Original Post
I've just started learning dinput and I wrote a simple wrapper class for it. But it doesn't seem to work consistently.
Here are the files, broken down into 3 main modules: input,keyboard,mouse (cursor)
Input.h
I know I really shouldn't have posted all the code, and just told you what my specific problem is, but I can't seem to find the problem!
("Log" and "Bitmap" are two of my other classes, and the problem almost certainly isn't there, they've been tested many times).
I get all sorts of weird errors. Sometimes the program exits immediatly after I check for a key press, even though I haven't even pressed it at all!! (Maybe I should clean out the "keyboardState" somehow??)
Another time I will get an error (in my log file) saying I failed to create the dinput object..and some other weird things.
But the cursor class is the worst, when I call
Cursor::GetInput(), the program closes straight away. Why??
Please, what is wrong with this code??
Any suggestions also for the design of the wrapper??
Oh yeah, do you think it worth placing keyboard and mouse input in seperate classes instead of just one??
Any help would be great, and thanks for your time
[EDIT] AHHH!! My code DOES NOT look like that!!
Stupid source box
[EDIT]
[edited by - julienX on April 23, 2003 12:04:06 PM]
//Input.h -- Main directinput class
//Watch for multiple inclusions
#ifndef INPUT_H
#define INPUT_H
//Includes
#include "dinput.h"
#include "Error.h"
#include <objbase.h>
/////////////////////////////////////////////////////
//Class declaration
class Input
{
public:
Input();
Input(HINSTANCE hinstance,Log *oldLog);
virtual ~Input();
//Initialisation
bool Init(HINSTANCE hinstance,Log *oldLog);
//Accessor methods
LPDIRECTINPUT8 GetDIObject() { return lpdi; };
Log * GetLogObject() { return log; };
private:
LPDIRECTINPUT8 lpdi;
Log *log;
};
/////////////////////////////////////////////////////
#endif //End INPUT_H
//Input.cpp
//Input.cpp -- Main directInput class
#include "Input.h"
/////////////////////////////////////////////////////
//Default constructor
Input::Input()
{
//Set pointer members to NULL
lpdi = NULL;
log = NULL;
} //End constructor
/////////////////////////////////////////////////////
//Constructor
Input::Input(HINSTANCE hinstance,Log *oldLog)
{
//Initialise directinput
Input::Init(hinstance,oldLog);
} //End constructor
/////////////////////////////////////////////////////
//Destructor
Input::~Input()
{
//Release main dinput object
if (lpdi)
{
lpdi->Release();
lpdi = NULL;
}
} //End destructor
/////////////////////////////////////////////////////
//DirectInput initialisation
bool Input::Init(HINSTANCE hinstance,Log *oldLog)
{
//Check if already initialised
if (lpdi)
return true;
//Set log member to point to original log object
log = oldLog;
//Create main dinput object
if (FAILED(DirectInput8Create(hinstance,DIRECTINPUT_VERSION,
IID_IDirectInput8,(void**)&lpdi,NULL)))
{
*log <<"ERROR: Failed to create main dinput object\n";
return false;
}
} //End Init
/////////////////////////////////////////////////////
//Keyboard.h
//Keyboard.h -- Directinput keyboard class
//Watch for multiple inclusions
#ifndef KEYBOARD_H
#define KEYBOARD_H
//Includes
#include "Input.h"
#define KEYDOWN_MACRO(data,key) (data[key] & 0x80)
/////////////////////////////////////////////////////
//Class declaration
class Keyboard
{
public:
Keyboard();
Keyboard(HWND hwnd,Input *oldInput);
virtual ~Keyboard();
bool Init(HWND hwnd,Input *oldInput);
void GetInput();
int KeyDown(unsigned char key);
//Accessor methods
LPDIRECTINPUTDEVICE8 GetKeyboard() { return lpdiKeyboard; };
private:
LPDIRECTINPUTDEVICE8 lpdiKeyboard;
UCHAR keyboardState[256];
Input *input;
};
/////////////////////////////////////////////////////
#endif //End KEYBOARD_H
Keyboard.cpp
//Keyboard.cpp -- Directinput keyboard class
#include "Keyboard.h"
/////////////////////////////////////////////////////
//Default constructor
Keyboard::Keyboard()
{
//Set pointer members to NULL
lpdiKeyboard = NULL;
input = NULL;
} //End constructor
/////////////////////////////////////////////////////
//Constructor
Keyboard::Keyboard(HWND hwnd,Input *oldInput)
{
//Initialise object
Keyboard::Init(hwnd,oldInput);
} //End constructor
/////////////////////////////////////////////////////
//Destructor
Keyboard::~Keyboard()
{
//Unacquire and delete keyboard device
if (lpdiKeyboard)
{
lpdiKeyboard->Unacquire();
lpdiKeyboard->Release();
lpdiKeyboard = NULL;
}
} //End destructor
/////////////////////////////////////////////////////
//Initialisation
bool Keyboard::Init(HWND hwnd,Input *oldInput)
{
//Check if already initialised
if (lpdiKeyboard)
return true;
//Set input member to point to original input object
input = oldInput;
//Create keyboard device
if (FAILED(input->GetDIObject()->CreateDevice(GUID_SysKeyboard,
&lpdiKeyboard,NULL)))
{
*input->GetLogObject() <<"ERROR: Failed to create keyboard device\n";
return false;
}
//Set cooperation level
if (FAILED(lpdiKeyboard->SetCooperativeLevel(hwnd,DISCL_BACKGROUND |
DISCL_NONEXCLUSIVE)))
{
*input->GetLogObject() <<"ERROR: Failed to set keyboard ccoperative level\n";
return false;
}
//Set keyboard data format
if (FAILED(lpdiKeyboard->SetDataFormat(&c_dfDIKeyboard)))
{
*input->GetLogObject() <<"ERROR: Failed to set keyboard data format\n";
return false;
}
//Acquire the keyboard
if (FAILED(lpdiKeyboard->Acquire()))
{
*input->GetLogObject() <<"ERROR: Failed to acquire keyboard\n";
return false;
}
//Init successful
return true;
} //End Init
/////////////////////////////////////////////////////
//Read in keyboard input
void Keyboard::GetInput()
{
//Clear input buffer
for (int i=0; i<256; i++)
keyboardState[i] = 0;
//Update keyboard states
if (FAILED(lpdiKeyboard->GetDeviceState(sizeof(keyboardState),(LPVOID)keyboardState)))
*input->GetLogObject() <<"ERROR: Failed to get keyboard device state\n";
} //End GetInput
/////////////////////////////////////////////////////
//Checks if a key is pressed
int Keyboard::KeyDown(unsigned char key)
{
return (KEYDOWN_MACRO(keyboardState,key));
} //End KeyDown
/////////////////////////////////////////////////////
Cursor.h
#ifndef CURSOR_H
#define CURSOR_H
//Includes
#include "Bitmap.h"
#include "Input.h"
/////////////////////////////////////////////////////
//Class declaration
class Cursor : public Bitmap
{
public:
virtual ~Cursor();
bool Init(HWND hwnd,const char *fileName,Input *oldInput,Graphics *oldGraphics,Log *oldLog);
void GetInput();
void Draw();
int GetX() { return mouseX; };
int GetY() { return mouseY; };
private:
LPDIRECTINPUTDEVICE8 lpdiMouse;
DIMOUSESTATE mouseState;
int mouseX,mouseY;
Input *input;
};
/////////////////////////////////////////////////////
#endif //End CURSOR_H
//Cursor.cpp
#include "Cursor.h"
/////////////////////////////////////////////////////
bool Cursor::Init(HWND hwnd,const char *fileName,Input *oldInput,Graphics *oldGraphics,Log *oldLog)
{
//Check if already initialised
if (lpdiMouse)
return true;
input = oldInput;
//Create device
if (FAILED(input->GetDIObject()->CreateDevice(GUID_SysMouse, &lpdiMouse, NULL)))
{
*oldLog <<"ERROR: Create mouse device\n";
return false;
}
//Set cooperation level
if (FAILED(lpdiMouse->SetCooperativeLevel(hwnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND)))
{
*oldLog <<"ERROR: Set mouse coop\n";
return false;
}
//Set data format
if (FAILED(lpdiMouse->SetDataFormat(&c_dfDIMouse)))
{
*oldLog <<"ERROR: Set mouse data format\n";
return false;
}
// acquire the mouse
if (FAILED(lpdiMouse->Acquire()))
{
*oldLog <<"ERROR: Acquire mouse\n";
return false;
}
//Set initial cursor position
mouseX = graphics->GetWidth()/2;
mouseY = graphics->GetHeight()/2;
if (!Bitmap::Load(fileName,oldGraphics,oldLog))
{
*oldLog <<"ERROR: Load cursor\n";
return false;
}
//Success
return true;
} //End Init
/////////////////////////////////////////////////////
//Destructor
Cursor::~Cursor()
{
if (lpdiMouse)
{
lpdiMouse->Unacquire();
lpdiMouse->Release();
lpdiMouse = NULL;
}
} //End destructor
/////////////////////////////////////////////////////
void Cursor::GetInput()
{
// get the input from the mouse
lpdiMouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mouseState);
// move the mouse cursor
mouseX += (mouseState.lX);
mouseY += (mouseState.lY);
} //End GetInput
/////////////////////////////////////////////////////
//Draw the cursor
void Cursor::Draw()
{
Bitmap::Draw(mouseX-GetWidth()/2,mouseY-GetHeight()/2);
} //End Draw
/////////////////////////////////////////////////////