new window code

This commit is contained in:
David Rose 2003-01-09 22:33:37 +00:00
parent 0de392dc87
commit 629c2322f4
2 changed files with 321 additions and 0 deletions

View File

@ -0,0 +1,276 @@
// Filename: dxInput8.cxx
// Created by: angelina jolie (07Oct99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#include "config_wdxdisplay8.h"
#include <dxInput8.h>
#define AXIS_RESOLUTION 2000 // use this many levels of resolution by default (could be more if needed and device supported it)
#define AXIS_RANGE_CENTERED // if defined, axis range is centered on 0, instead of starting on 0
BOOL CALLBACK EnumGameCtrlsCallback( const DIDEVICEINSTANCE* pdidInstance,
VOID* pContext ) {
DI_DeviceInfos *pDevInfos = (DI_DeviceInfos *)pContext;
(*pDevInfos).push_back(*pdidInstance);
if(wdxdisplay_cat.is_debug())
wdxdisplay_cat.debug() << "Found DevType 0x" << (void*)pdidInstance->dwDevType << ": " << pdidInstance->tszInstanceName << ": " << pdidInstance->tszProductName <<endl;
return DIENUM_CONTINUE;
}
extern BOOL CALLBACK EnumObjectsCallbackJoystick(const DIDEVICEOBJECTINSTANCE* pdidoi,VOID* pContext);
DInput8Info::DInput8Info() {
_pDInput8 = NULL;
_hDInputDLL = NULL;
_JoystickPollTimer = NULL;
}
DInput8Info::~DInput8Info() {
for(UINT i=0;i<_DeviceList.size();i++) {
_DeviceList[i]->Unacquire();
SAFE_RELEASE(_DeviceList[i]);
}
// bugbug: need to handle this
// if(_JoystickPollTimer!=NULL)
// KillTimer(...)
SAFE_RELEASE(_pDInput8);
if(_hDInputDLL) {
FreeLibrary(_hDInputDLL);
_hDInputDLL=NULL;
}
}
bool DInput8Info::InitDirectInput(void) {
HRESULT hr;
// assumes dx8 exists
// use dynamic load so non-dinput programs dont have to load dinput
#define DLLNAME "dinput8.dll"
#define DINPUTCREATE "DirectInput8Create"
HINSTANCE _hDInputDLL = LoadLibrary(DLLNAME);
if(_hDInputDLL == 0) {
wdxdisplay_cat.fatal() << "LoadLibrary(" << DLLNAME <<") failed!, error=" << GetLastError() << endl;
exit(1);
}
typedef HRESULT (WINAPI * LPDIRECTINPUT8CREATE)(HINSTANCE hinst, DWORD dwVersion, REFIID riidltf, LPVOID *ppvOut, LPUNKNOWN punkOuter);
LPDIRECTINPUT8CREATE pDInputCreate8;
pDInputCreate8 = (LPDIRECTINPUT8CREATE) GetProcAddress(_hDInputDLL,DINPUTCREATE);
if(pDInputCreate8 == NULL) {
wdxdisplay_cat.fatal() << "GetProcAddr failed for " << DINPUTCREATE << endl;
exit(1);
}
// Register with the DirectInput subsystem and get a pointer
// to a IDirectInput interface we can use.
// Create a DInput object
if( FAILED( hr = (*pDInputCreate8)(GetModuleHandle(NULL), DIRECTINPUT_VERSION,
IID_IDirectInput8, (VOID**)&_pDInput8, NULL ) ) ) {
wdxdisplay_cat.error() << DINPUTCREATE << "failed" << D3DERRORSTRING(hr);
return false;
}
// enum all the joysticks,etc (but not keybd/mouse)
if( FAILED( hr = _pDInput8->EnumDevices(DI8DEVCLASS_GAMECTRL,
EnumGameCtrlsCallback,
(LPVOID)&_DevInfos, DIEDFL_ATTACHEDONLY ) ) ) {
wdxdisplay_cat.error() << "EnumDevices failed" << D3DERRORSTRING(hr);
return false;
}
return true;
}
bool DInput8Info::CreateJoystickOrPad(HWND hWnd) {
bool bFoundDev = false;
UINT devnum=0;
char *errstr=NULL;
// look through the list for the first joystick or gamepad
for(;devnum<_DevInfos.size();devnum++) {
DWORD devType = GET_DIDEVICE_TYPE(_DevInfos[devnum].dwDevType);
if((devType==DI8DEVTYPE_GAMEPAD) ||(devType==DI8DEVTYPE_JOYSTICK)) {
bFoundDev=true;
break;
}
}
if(!bFoundDev) {
wdxdisplay_cat.error() << "Cant find an attached Joystick or GamePad!\n";
return false;
}
LPDIRECTINPUTDEVICE8 pJoyDevice;
// Obtain an interface to the enumerated joystick.
HRESULT hr = _pDInput8->CreateDevice(_DevInfos[devnum].guidInstance, &pJoyDevice, NULL );
if(FAILED(hr)) {
errstr="CreateDevice";
goto handle_error;
}
assert(pJoyDevice!=NULL);
_DeviceList.push_back(pJoyDevice);
// Set the data format to "simple joystick" - a predefined data format
//
// A data format specifies which controls on a device we are interested in,
// and how they should be reported. This tells DInput that we will be
// passing a DIJOYSTATE2 structure to IDirectInputDevice::GetDeviceState().
hr = pJoyDevice->SetDataFormat(&c_dfDIJoystick2);
if(FAILED(hr)) {
errstr="SetDataFormat";
goto handle_error;
}
// must be called AFTER SetDataFormat to get all the proper flags
DX_DECLARE_CLEAN(DIDEVCAPS, DIDevCaps);
hr = pJoyDevice->GetCapabilities(&DIDevCaps);
assert(SUCCEEDED(hr));
_DevCaps.push_back(DIDevCaps);
if(wdxdisplay_cat.is_debug())
wdxdisplay_cat.debug() << "Joy/Pad has " << DIDevCaps.dwAxes << " Axes, " << DIDevCaps.dwButtons << " Buttons, " << DIDevCaps.dwPOVs << " POVs" << endl;
// Set the cooperative level to let DInput know how this device should
// interact with the system and with other DInput applications.
hr = pJoyDevice->SetCooperativeLevel( hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
if(FAILED(hr)) {
errstr="SetCooperativeLevel";
goto handle_error;
}
// set the min/max values property for discovered axes.
hr = pJoyDevice->EnumObjects(EnumObjectsCallbackJoystick, (LPVOID)pJoyDevice, DIDFT_AXIS);
if(FAILED(hr)) {
errstr="EnumObjects";
goto handle_error;
}
return true;
handle_error:
wdxdisplay_cat.error() << errstr << " failed for (" << _DevInfos[devnum].tszInstanceName << ":" << _DevInfos[devnum].tszProductName << ")" << D3DERRORSTRING(hr);
return false;
}
//-----------------------------------------------------------------------------
// Name: EnumObjectsCallback()
// Desc: Callback function for enumerating objects (axes, buttons, POVs) on a
// joystick. This function enables user interface elements for objects
// that are found to exist, and scales axes min/max values.
//-----------------------------------------------------------------------------
BOOL CALLBACK EnumObjectsCallbackJoystick( const DIDEVICEOBJECTINSTANCE* pdidoi,
VOID* pContext ) {
LPDIRECTINPUTDEVICE8 pJoyDevice = (LPDIRECTINPUTDEVICE8) pContext;
HRESULT hr;
// For axes that are returned, set the DIPROP_RANGE property for the
// enumerated axis in order to scale min/max values.
if( pdidoi->dwType & DIDFT_AXIS ) {
DIPROPRANGE diprg;
diprg.diph.dwSize = sizeof(DIPROPRANGE);
diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
diprg.diph.dwHow = DIPH_BYID;
diprg.diph.dwObj = pdidoi->dwType; // Specify the enumerated axis
#ifdef AXIS_RANGE_CENTERED
diprg.lMin = -AXIS_RESOLUTION/2;
diprg.lMax = +AXIS_RESOLUTION/2;
#else
diprg.lMin = 0;
diprg.lMax = +AXIS_RESOLUTION;
#endif
// Set the range for the axis
hr = pJoyDevice->SetProperty( DIPROP_RANGE, &diprg.diph);
if(FAILED(hr)) {
wdxdisplay_cat.error() << "SetProperty on axis failed" << D3DERRORSTRING(hr);
return DIENUM_STOP;
}
}
return DIENUM_CONTINUE;
}
bool DInput8Info::ReadJoystick(int devnum, DIJOYSTATE2 &js) {
LPDIRECTINPUTDEVICE8 pJoystick = _DeviceList[devnum];
assert(pJoystick!=NULL);
HRESULT hr;
char *errstr;
// Poll the device to read the current state
hr = pJoystick->Poll();
if( FAILED(hr) ) {
// DInput is telling us that the input stream has been
// interrupted. We aren't tracking any state between polls, so
// we don't have any special reset that needs to be done. We
// just re-acquire and try again.
if((hr==DIERR_NOTACQUIRED)||(hr == DIERR_INPUTLOST)) {
hr = pJoystick->Acquire();
if(FAILED(hr)) {
if(wdxdisplay_cat.is_spam())
wdxdisplay_cat.spam() << "Acquire failed" << D3DERRORSTRING(hr);
// hr may be DIERR_OTHERAPPHASPRIO or other errors. This
// may occur when the app is minimized or in the process of
// switching, so just try again later
return false;
}
hr = pJoystick->Poll();
if(FAILED(hr)) {
// should never happen!
errstr = "Poll after successful Acquire failed";
goto handle_error;
}
} else {
errstr = "Unknown Poll failure";
goto handle_error;
}
}
// should we make a vector of devstate dataformats to generalize this fn for all device types?
// Get the input's device state
hr = pJoystick->GetDeviceState( sizeof(DIJOYSTATE2), &js);
if(FAILED(hr)) {
errstr = "GetDeviceState failed";
goto handle_error;
}
return true;
handle_error:
wdxdisplay_cat.fatal() << errstr << D3DERRORSTRING(hr);
return false;
}

View File

@ -0,0 +1,45 @@
// Filename: dxInput8.h
// Created by: blllyjo (07Oct99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://www.panda3d.org/license.txt .
//
// To contact the maintainers of this program write to
// panda3d@yahoogroups.com .
//
////////////////////////////////////////////////////////////////////
#ifndef DXINPUT8_H
#define DXINPUT8_H
#define DIRECTINPUT_VERSION 0x800
#include <dinput.h>
typedef vector<DIDEVICEINSTANCE> DI_DeviceInfos;
typedef vector<DIDEVICEOBJECTINSTANCE> DI_DeviceObjInfos;
class DInput8Info {
public:
DInput8Info(void);
~DInput8Info(void);
bool InitDirectInput(void);
bool CreateJoystickOrPad(HWND hWnd);
bool ReadJoystick(int devnum, DIJOYSTATE2 &js);
HINSTANCE _hDInputDLL;
UINT_PTR _JoystickPollTimer;
LPDIRECTINPUT8 _pDInput8;
DI_DeviceInfos _DevInfos;
// arrays for all created devices. Should probably put these together in a struct,
// along with the data fmt info
vector<LPDIRECTINPUTDEVICE8> _DeviceList;
vector<DIDEVCAPS> _DevCaps;
};
#endif