Skip to content

Commit

Permalink
Win32|Refactor: Use DirectInput's C++ interface
Browse files Browse the repository at this point in the history
  • Loading branch information
danij-deng committed May 3, 2012
1 parent f196a26 commit 13aea05
Show file tree
Hide file tree
Showing 5 changed files with 374 additions and 95 deletions.
2 changes: 1 addition & 1 deletion doomsday/engine/engine.pro
Expand Up @@ -376,7 +376,7 @@ win32 {

SOURCES += \
win32/src/dd_winit.c \
win32/src/directinput.c \
win32/src/directinput.cpp \
win32/src/sys_console.c \
win32/src/sys_findfile.c \
win32/src/joystick_win32.cpp \
Expand Down
68 changes: 62 additions & 6 deletions doomsday/engine/win32/include/directinput.h
Expand Up @@ -21,16 +21,72 @@ void DirectInput_Shutdown(void);

LPDIRECTINPUT8 DirectInput_Instance();

void DirectInput_KillDevice(LPDIRECTINPUTDEVICE8 *dev);

HRESULT DirectInput_SetProperty(LPDIRECTINPUTDEVICE8 dev, REFGUID property, DWORD how, DWORD obj, DWORD data);

HRESULT DirectInput_SetRangeProperty(LPDIRECTINPUTDEVICE8 dev, REFGUID property, DWORD how, DWORD obj, int min, int max);
void DirectInput_KillDevice(LPDIRECTINPUTDEVICE8* dev);

const char* DirectInput_ErrorMsg(HRESULT hr);

#ifdef __cplusplus
}
} // extern "C"
#endif

#ifdef __cplusplus
/**
* A handy adaptor for manipulating a DIPROPDWORD structure.
*/
struct DIPropDWord : DIPROPDWORD
{
DIPropDWord(DWORD how=0, DWORD object=0, DWORD data=0)
{
initHeader();
setHow(how);
setObject(object);
setData(data);
}

operator DIPROPHEADER*() { return &diph; }
operator const DIPROPHEADER*() const { return &diph; }

inline DIPropDWord& setHow(DWORD how) { diph.dwHow = how; return *this; }
inline DIPropDWord& setObject(DWORD obj) { diph.dwObj = obj; return *this; }
inline DIPropDWord& setData(DWORD data) { dwData = data; return *this; }

private:
void initHeader()
{
diph.dwSize = sizeof(DIPROPDWORD);
diph.dwHeaderSize = sizeof(diph);
}
};

/**
* A handy adaptor for manipulating a DIPROPRANGE structure.
*/
struct DIPropRange : DIPROPRANGE
{
DIPropRange(DWORD how=0, DWORD object=0, int min=0, int max=0)
{
initHeader();
setHow(how);
setObject(object);
setMin(min);
setMax(max);
}

operator DIPROPHEADER*() { return &diph; }
operator const DIPROPHEADER*() const { return &diph; }

inline DIPropRange& setHow(DWORD how) { diph.dwHow = how; return *this; }
inline DIPropRange& setObject(DWORD obj) { diph.dwObj = obj; return *this; }
inline DIPropRange& setMin(int min) { lMin = min; return *this; }
inline DIPropRange& setMax(int max) { lMax = max; return *this; }

private:
void initHeader()
{
diph.dwSize = sizeof(DIPROPRANGE);
diph.dwHeaderSize = sizeof(diph);
}
};
#endif // __cplusplus

#endif // LIBDENG_DIRECTINPUT_H
@@ -1,5 +1,5 @@
/**
* @file directinput.c
* @file directinput.cpp
* DirectInput for Windows. @ingroup input
*
* @authors Copyright © 2003-2012 Jaakko Keränen <jaakko.keranen@iki.fi>
Expand All @@ -25,6 +25,7 @@
#include "con_main.h"

static LPDIRECTINPUT8 dInput;
static LPDIRECTINPUT dInput3;

const char* DirectInput_ErrorMsg(HRESULT hr)
{
Expand All @@ -40,28 +41,29 @@ int DirectInput_Init(void)
{
HRESULT hr;

if(dInput) return true;
if(dInput || dInput3) return true;

// We'll create the DirectInput object. The only required input device
// is the keyboard. The others are optional.
if(FAILED(hr = CoCreateInstance(&CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER,
&IID_IDirectInput8, &dInput)) ||
FAILED(hr = IDirectInput8_Initialize(dInput, app.hInstance, DIRECTINPUT_VERSION)))
// We'll create the DirectInput object.
if(FAILED(hr = CoCreateInstance(CLSID_DirectInput8, NULL, CLSCTX_INPROC_SERVER,
IID_IDirectInput8, (LPVOID*)&dInput)) ||
FAILED(hr = dInput->Initialize(app.hInstance, DIRECTINPUT_VERSION)))
{
Con_Message("DirectInput 8 init failed (0x%x).\n", hr);

// Try DInput3 instead.
// I'm not sure if this works correctly.
if(FAILED(hr = CoCreateInstance(&CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER,
&IID_IDirectInput2W, &dInput)) ||
FAILED(hr = IDirectInput2_Initialize(dInput, app.hInstance, 0x0300)))
if(FAILED(hr = CoCreateInstance(CLSID_DirectInput, NULL, CLSCTX_INPROC_SERVER,
IID_IDirectInput2W, (LPVOID*)&dInput3)) ||
FAILED(hr = dInput3->Initialize(app.hInstance, 0x0300)))
{
Con_Message("Failed to create DirectInput 3 object (0x%x).\n", hr);
return false;
}

Con_Message("Using DirectInput 3.\n");
}

if(!dInput)
if(!dInput && !dInput3)
{
Con_Message(" DirectInput init failed.\n");
return false;
Expand All @@ -72,45 +74,28 @@ int DirectInput_Init(void)

void DirectInput_Shutdown(void)
{
if(!dInput) return;
if(!dInput && !dInput3) return;

// Release DirectInput.
IDirectInput_Release(dInput);
dInput = 0;
if(dInput)
{
IDirectInput_Release(dInput);
dInput = 0;
}
if(dInput3)
{
IDirectInput_Release(dInput3);
dInput3 = 0;
}
}

LPDIRECTINPUT8 DirectInput_Instance()
{
assert(dInput != 0);
return dInput;
}

HRESULT DirectInput_SetProperty(LPDIRECTINPUTDEVICE8 dev, REFGUID property, DWORD how, DWORD obj, DWORD data)
{
DIPROPDWORD dipdw;

dipdw.diph.dwSize = sizeof(dipdw);
dipdw.diph.dwHeaderSize = sizeof(dipdw.diph);
dipdw.diph.dwObj = obj;
dipdw.diph.dwHow = how;
dipdw.dwData = data;
return IDirectInputDevice8_SetProperty(dev, property, &dipdw.diph);
}

HRESULT DirectInput_SetRangeProperty(LPDIRECTINPUTDEVICE8 dev, REFGUID property, DWORD how, DWORD obj, int min, int max)
{
DIPROPRANGE dipr;

dipr.diph.dwSize = sizeof(dipr);
dipr.diph.dwHeaderSize = sizeof(dipr.diph);
dipr.diph.dwObj = obj;
dipr.diph.dwHow = how;
dipr.lMin = min;
dipr.lMax = max;
return IDirectInputDevice8_SetProperty(dev, property, &dipr.diph);
assert(dInput != 0 || dInput3 != 0);
return dInput? dInput : (LPDIRECTINPUT8)dInput3;
}

void DirectInput_KillDevice(LPDIRECTINPUTDEVICE8 *dev)
void DirectInput_KillDevice(LPDIRECTINPUTDEVICE8* dev)
{
if(*dev) IDirectInputDevice8_Unacquire(*dev);
I_SAFE_RELEASE(*dev);
Expand Down

0 comments on commit 13aea05

Please sign in to comment.