Direct Input: Avoiding Globals

Started by
3 comments, last by Muhammad Haggag 17 years, 11 months ago
Okay, aparently I am a bit lost. I cannot put my Enumdevices Callback inside a Class right? (If I can please explain how, it has not worked for me yet) but I want the organization of having all my directX pointers inside a class. I have done this with Direct 3D, but now I need input..... and I am trying to avoid using a global. I know that would work, so if there is no other option I will do it... Alright, here is my code, this is just me organizing stuff from a book, there is much room for improvement, but I will work on that once I get everything from DirectX into nice little classes. I am strange like that. Here is the code in question (only snippits):

class eInput
{
public:
	IDirectInput8 *iDI;             // DirectInput component
	IDirectInputDevice8 *iDIDJoysticks; // Enum Joystick device
	IDirectInputDevice8 *iDIJoy; // Joystick device
	IDirectInputDevice8 *iDIMouse;
	IDirectInputDevice8 *iDIKeyboard;

	HWND hwnd;
	eInput();
	~eInput();
	
bool InitKeyboard();
bool InitMouse();
bool InitJoystick();
bool KRead( void *DataBuffer, long BufferSize);
bool MRead( void *DataBuffer, long BufferSize);
bool JRead( void *DataBuffer, long BufferSize);
bool CALLBACK EnumJoysticks(LPCDIDEVICEINSTANCE pdInst, LPVOID pvRef);
	bool Init();
};

the code that calls this and it expantion:

bool eInput::InitJoystick()
{

	 iDI->EnumDevices(DI8DEVTYPE_JOYSTICK, EnumJoysticks, NULL, DIEDFL_ATTACHEDONLY);
  // Everything was a success
	 return true;
}


bool CALLBACK eInput::EnumJoysticks(LPCDIDEVICEINSTANCE pdInst, LPVOID pvRef)
{
  DIPROPRANGE dipr;
  DIPROPDWORD dipdw;
  
  iDIDJoysticks = NULL;

  // Create the device object using global DirectInput object
  if(FAILED(iDI->CreateDevice(pdInst->guidInstance,                    &iDIDJoysticks, NULL)))
    return DIENUM_CONTINUE;

  // Set the data format
  if(FAILED(iDIDJoysticks->SetDataFormat(&c_dfDIJoystick))) {
   iDIDJoysticks->Release();
    iDIDJoysticks = NULL;
	    return DIENUM_CONTINUE;
  }

  // Set the cooperative mode
  if(FAILED(iDIDJoysticks->SetCooperativeLevel(hwnd,  
            DISCL_FOREGROUND | DISCL_NONEXCLUSIVE))) {
    iDIDJoysticks->Release();
    iDIDJoysticks = NULL;
    return DIENUM_CONTINUE;
  }

  // Clear out the structure first
  ZeroMemory(&dipr, sizeof(DIPROPRANGE));
  dipr.diph.dwSize = sizeof(dipr);
  dipr.diph.dwHeaderSize = sizeof(dipr);

  dipr.diph.dwObj = DIJOFS_X;
  dipr.diph.dwHow = DIPH_BYOFFSET;  // offset into data format

  dipr.lMin = -1024;
  dipr.lMax = 1024;

   if(FAILED(iDIDJoysticks->SetProperty(DIPROP_RANGE,                                                &dipr.diph))) {
    iDIDJoysticks->Release();
    iDIDJoysticks = NULL;
    return DIENUM_CONTINUE;
  }

  dipr.diph.dwObj = DIJOFS_Y;
  if(FAILED(iDIDJoysticks->SetProperty(DIPROP_RANGE,                                                &dipr.diph))) {
    iDIDJoysticks->Release();
    iDIDJoysticks = NULL;
    return DIENUM_CONTINUE;
  }
    
  // Set X deadzone to 15%
  dipdw.diph.dwObj = DIJOFS_X;
  dipdw.dwData = 1500;
  if(FAILED(iDIJoy->SetProperty(DIPROP_DEADZONE, &dipdw.diph))) {
    iDIDJoysticks->Release();
    iDIDJoysticks = NULL;
    return DIENUM_CONTINUE;
  }

  // Set Y deadzone
  dipdw.diph.dwObj = DIJOFS_Y;
  if(FAILED(iDIJoy->SetProperty(DIPROP_DEADZONE, &dipdw.diph))) {
    iDIDJoysticks->Release();
    iDIDJoysticks = NULL;
    return DIENUM_CONTINUE;
  }

  // Acquire the device for use
  if(FAILED(iDIDJoysticks->Acquire())) {
    iDIDJoysticks->Release();
    iDIDJoysticks = NULL;
    return DIENUM_CONTINUE;
  }

  // Stop enumeration
  return DIENUM_STOP;
}

Thanks. I have been working with this particular code for a grand total of about 3 weeks now! DirectX may be the cause of head aches, but I think it will be worth the agrrivation!
___________________________________________________Optimists see the glass as Half FullPessimists See the glass as Half EmptyEngineers See the glass as Twice as big as it needs to be
Advertisement
If you look at the declaration of the function pointer signature that you are trying to implement, it doesn't have a class type. This means that you can't use class functions - they have to be C-style. However, this doesn't mean that they have to be global and be accessable to your whole application - if you keep it all contained in one source file, it should work out well.

What you can do is make a dummy C-style function, and then just pass through to your input class's function from there. I assume that you have some way to access the instantiated input class. For example:

bool EnumJoysticks( blah1, blah2 ){   return GetEngine()->GetInput()->EnumJoysticks( blah1, blah2 )}


This is a very light-weight way to get around the problem (I commonly do this with MsgProc's too).
Dustin Franklin ( circlesoft :: KBase :: Mystic GD :: ApolloNL )
Ummm, I don't think I have a way to acess it like that. I though that DirectX was based on COM, and that is a C++ thing isn't it? It uses function members. I honestly have no Idea what you are trying to tell me to do. I don't gave anykind of GetEngine function. Or get input. I can read the Joystick.... and any other kind of thing, but my engine isn't meant to track or query itself... I don't know how to do that. can I just add a bunch of fields to the function (or can you not do that with CALLBACKS?) Thanks!
___________________________________________________Optimists see the glass as Half FullPessimists See the glass as Half EmptyEngineers See the glass as Twice as big as it needs to be
Consider using static member functions - you can pass a static member function to the DirectInput enumeration function. However, you will probably have to make member data static as well. This would be annoying only if you will be making multiple instances of eInput. By the way, what does the e stand for in eInput?
I live in Palestine, but it's not in the country list, so I picked Zimbabwe.
bool eInput::InitJoystick(){ iDI->EnumDevices(DI8DEVTYPE_JOYSTICK, EnumJoysticks, this, DIEDFL_ATTACHEDONLY);  // Everything was a success return true;}bool eInput::EnumJoysticks(LPCDIDEVICEINSTANCE pdInst){    &#8230;}// Declare this as a static member functionbool eInput::StaticEnumJoysticks(LPDEIDEVICEINSTANCE pdInst, PVOID pvRef){    return static_cast<eInput*>(pvRef)->EnumJoysticks(pdInst);}

This topic is closed to new replies.

Advertisement