Skip to main content
gamedev.net
🔒 Locked

DInput wrapper advice

Started by julienX Apr 23, 2003 at 11:01 AM 0 replies 2.2k views
Original Post
julienX
julienX
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
    

//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


/////////////////////////////////////////////////////


    
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]
chacha
RhoneRanger
RhoneRanger
First of all, if your function is within your class, you shouldnt put the syntax like

input::init(blah)

init(blah) will do!

Same with the keyboard interface, and the mouse.

The function
int Keyboard::KeyDown(unsigned char key){ return (KEYDOWN_MACRO(keyboardState,key)); } //End KeyDown

is kind of redundant, when this in a game loop

if(KEYDOWN_MACRO(keyboardState,DIK_ESCAPE))
//do something

is good enough, why waste time on a function?? Besides that, your code looks really solid. Good Job!!!

I have a dinput tutorial that may help you

http://www.myran.com/enilno/index.php?page=showtut.htm&tut=4&menu=0&color=g
TechleadEnilno, the Ultima 2 projectwww.dr-code.org/enilno

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.