2003-04-15 08:08:53 +00:00
// ******************************************************************
// *
// * .,-::::: .,:: .::::::::. .,:: .:
// * ,;;;'````' `;;;, .,;; ;;;'';;' `;;;, .,;;
// * [[[ '[[,,[[' [[[__[[\. '[[,,[['
// * $$$ Y$$$P $$""""Y$$ Y$$$P
// * `88bo,__,o, oP"``"Yo, _88o,,od8P oP"``"Yo,
// * "YUMMMMMP",m" "Mm,""YUMMMP" ,m" "Mm,
// *
// * Cxbx->Win32->XBController.cpp
// *
// * This file is part of the Cxbx project.
// *
// * Cxbx and Cxbe are free software; you can redistribute them
// * and/or modify them under the terms of the GNU General Public
// * License as published by the Free Software Foundation; either
// * version 2 of the license, or (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have recieved a copy of the GNU General Public License
// * along with this program; see the file COPYING.
// * If not, write to the Free Software Foundation, Inc.,
// * 59 Temple Place - Suite 330, Bostom, MA 02111-1307, USA.
// *
// * (c) 2002-2003 Aaron Robinson <caustik@caustik.com>
// *
// * All rights reserved
// *
// ******************************************************************
# include "XBController.h"
# include <stdio.h>
// ******************************************************************
// * func: XBController::XBController
// ******************************************************************
XBController : : XBController ( )
{
2003-04-16 19:06:20 +00:00
m_CurrentState = XBCTRL_STATE_NONE ;
2003-04-15 08:08:53 +00:00
int v = 0 ;
for ( v = 0 ; v < XBCTRL_MAX_DEVICES ; v + + )
2003-04-16 19:06:20 +00:00
{
2003-04-15 08:08:53 +00:00
m_DeviceName [ v ] [ 0 ] = ' \0 ' ;
2003-04-16 19:06:20 +00:00
m_InputDevice [ v ] . m_Device = NULL ;
m_InputDevice [ v ] . m_Flags = 0 ;
}
2003-04-15 08:08:53 +00:00
for ( v = 0 ; v < XBCTRL_OBJECT_COUNT ; v + + )
{
m_ObjectConfig [ v ] . dwDevice = - 1 ;
m_ObjectConfig [ v ] . dwInfo = - 1 ;
m_ObjectConfig [ v ] . dwFlags = 0 ;
}
2003-04-16 19:06:20 +00:00
m_pDirectInput8 = NULL ;
m_dwInputDeviceCount = 0 ;
}
// ******************************************************************
// * func: XBController::~XBController
// ******************************************************************
XBController : : ~ XBController ( )
{
if ( m_CurrentState = = XBCTRL_STATE_CONFIG )
ConfigEnd ( ) ;
else if ( m_CurrentState = = XBCTRL_STATE_LISTEN )
ListenEnd ( ) ;
2003-04-15 08:08:53 +00:00
}
// ******************************************************************
// * func: XBController::Load
// ******************************************************************
void XBController : : Load ( const char * szRegistryKey )
{
2003-04-16 19:06:20 +00:00
if ( m_CurrentState ! = XBCTRL_STATE_NONE )
{
SetError ( " Invalid State " , false ) ;
return ;
}
2003-04-15 08:08:53 +00:00
// ******************************************************************
// * Load Configuration from Registry
// ******************************************************************
{
DWORD dwDisposition , dwType , dwSize ;
HKEY hKey ;
if ( RegCreateKeyEx ( HKEY_CURRENT_USER , szRegistryKey , 0 , NULL , REG_OPTION_NON_VOLATILE , KEY_QUERY_VALUE , NULL , & hKey , & dwDisposition ) = = ERROR_SUCCESS )
{
int v = 0 ;
// ******************************************************************
// * Load Device Names
// ******************************************************************
{
char szValueName [ 64 ] ;
for ( v = 0 ; v < XBCTRL_MAX_DEVICES ; v + + )
{
// default is a null string
m_DeviceName [ v ] [ 0 ] = ' \0 ' ;
sprintf ( szValueName , " DeviceName 0x%.02X " , v ) ;
dwType = REG_SZ ; dwSize = 260 ;
RegQueryValueEx ( hKey , szValueName , NULL , & dwType , ( PBYTE ) m_DeviceName [ v ] , & dwSize ) ;
}
}
// ******************************************************************
// * Load Object Configuration
// ******************************************************************
{
char szValueName [ 64 ] ;
for ( v = 0 ; v < XBCTRL_OBJECT_COUNT ; v + + )
{
// default object configuration
m_ObjectConfig [ v ] . dwDevice = - 1 ;
m_ObjectConfig [ v ] . dwInfo = - 1 ;
m_ObjectConfig [ v ] . dwFlags = 0 ;
sprintf ( szValueName , " Object : \" %s \" " , m_DeviceNameLookup [ v ] ) ;
dwType = REG_BINARY ; dwSize = sizeof ( XBCtrlObjectCfg ) ;
RegQueryValueEx ( hKey , szValueName , NULL , & dwType , ( PBYTE ) & m_ObjectConfig [ v ] , & dwSize ) ;
}
}
RegCloseKey ( hKey ) ;
}
}
}
// ******************************************************************
// * func: XBController::Save
// ******************************************************************
void XBController : : Save ( const char * szRegistryKey )
{
2003-04-16 19:06:20 +00:00
if ( m_CurrentState ! = XBCTRL_STATE_NONE )
{
SetError ( " Invalid State " , false ) ;
return ;
}
2003-04-15 08:08:53 +00:00
// ******************************************************************
// * Save Configuration to Registry
// ******************************************************************
{
DWORD dwDisposition , dwType , dwSize ;
HKEY hKey ;
if ( RegCreateKeyEx ( HKEY_CURRENT_USER , szRegistryKey , 0 , NULL , REG_OPTION_NON_VOLATILE , KEY_SET_VALUE , NULL , & hKey , & dwDisposition ) = = ERROR_SUCCESS )
{
int v = 0 ;
// ******************************************************************
// * Save Device Names
// ******************************************************************
{
char szValueName [ 64 ] ;
for ( v = 0 ; v < XBCTRL_MAX_DEVICES ; v + + )
{
sprintf ( szValueName , " DeviceName 0x%.02X " , v ) ;
dwType = REG_SZ ; dwSize = 260 ;
2003-04-16 19:06:20 +00:00
if ( m_DeviceName [ v ] [ 0 ] = = ' \0 ' )
RegDeleteValue ( hKey , szValueName ) ;
else
2003-04-15 08:08:53 +00:00
RegSetValueEx ( hKey , szValueName , NULL , dwType , ( PBYTE ) m_DeviceName [ v ] , dwSize ) ;
}
}
// ******************************************************************
// * Save Object Configuration
// ******************************************************************
{
char szValueName [ 64 ] ;
for ( v = 0 ; v < XBCTRL_OBJECT_COUNT ; v + + )
{
sprintf ( szValueName , " Object : \" %s \" " , m_DeviceNameLookup [ v ] ) ;
dwType = REG_BINARY ; dwSize = sizeof ( XBCtrlObjectCfg ) ;
if ( m_ObjectConfig [ v ] . dwDevice ! = - 1 )
RegSetValueEx ( hKey , szValueName , NULL , dwType , ( PBYTE ) & m_ObjectConfig [ v ] , dwSize ) ;
}
}
RegCloseKey ( hKey ) ;
}
}
}
// ******************************************************************
// * func: XBController::ConfigBegin
// ******************************************************************
void XBController : : ConfigBegin ( HWND hwnd , XBCtrlObject object )
{
2003-04-16 19:06:20 +00:00
if ( m_CurrentState ! = XBCTRL_STATE_NONE )
2003-04-15 08:08:53 +00:00
{
2003-04-16 19:06:20 +00:00
SetError ( " Invalid State " , false ) ;
return ;
2003-04-15 08:08:53 +00:00
}
2003-04-16 19:06:20 +00:00
m_CurrentState = XBCTRL_STATE_CONFIG ;
2003-04-15 08:08:53 +00:00
2003-04-16 19:06:20 +00:00
DInputInit ( hwnd ) ;
2003-04-15 08:08:53 +00:00
2003-04-16 19:06:20 +00:00
if ( GetError ( ) ! = 0 )
return ;
2003-04-15 08:08:53 +00:00
2003-04-16 19:06:20 +00:00
lPrevMouseX = - 1 ;
lPrevMouseY = - 1 ;
lPrevMouseZ = - 1 ;
2003-04-15 08:08:53 +00:00
CurConfigObject = object ;
return ;
}
// ******************************************************************
// * func: XBController::ConfigPoll
// ******************************************************************
bool XBController : : ConfigPoll ( char * szStatus )
{
2003-04-16 19:06:20 +00:00
if ( m_CurrentState ! = XBCTRL_STATE_CONFIG )
{
SetError ( " Invalid State " , false ) ;
return false ;
}
2003-04-15 08:08:53 +00:00
DIDEVICEINSTANCE DeviceInstance ;
DIDEVICEOBJECTINSTANCE ObjectInstance ;
DeviceInstance . dwSize = sizeof ( DIDEVICEINSTANCE ) ;
ObjectInstance . dwSize = sizeof ( DIDEVICEOBJECTINSTANCE ) ;
// ******************************************************************
// * Monitor for significant device state changes
// ******************************************************************
for ( int v = m_dwInputDeviceCount - 1 ; v > = 0 ; v - - )
{
// ******************************************************************
// * Poll the current device
// ******************************************************************
{
HRESULT hRet = m_InputDevice [ v ] . m_Device - > Poll ( ) ;
if ( FAILED ( hRet ) )
{
hRet = m_InputDevice [ v ] . m_Device - > Acquire ( ) ;
while ( hRet = = DIERR_INPUTLOST )
hRet = m_InputDevice [ v ] . m_Device - > Acquire ( ) ;
}
}
DWORD dwHow = - 1 , dwFlags = m_InputDevice [ v ] . m_Flags ;
// ******************************************************************
// * Detect Joystick Input
// ******************************************************************
if ( m_InputDevice [ v ] . m_Flags & DEVICE_FLAG_JOYSTICK )
{
DIJOYSTATE JoyState ;
// ******************************************************************
// * Get Joystick State
// ******************************************************************
{
HRESULT hRet = m_InputDevice [ v ] . m_Device - > GetDeviceState ( sizeof ( DIJOYSTATE ) , & JoyState ) ;
if ( FAILED ( hRet ) )
continue ;
}
dwFlags = DEVICE_FLAG_JOYSTICK ;
if ( abs ( JoyState . lX ) > DETECT_SENSITIVITY_JOYSTICK )
{
dwHow = FIELD_OFFSET ( DIJOYSTATE , lX ) ;
dwFlags | = ( JoyState . lX > 0 ) ? ( DEVICE_FLAG_AXIS | DEVICE_FLAG_POSITIVE ) : ( DEVICE_FLAG_AXIS | DEVICE_FLAG_NEGATIVE ) ;
}
else if ( abs ( JoyState . lY ) > DETECT_SENSITIVITY_JOYSTICK )
{
dwHow = FIELD_OFFSET ( DIJOYSTATE , lY ) ;
dwFlags | = ( JoyState . lY > 0 ) ? ( DEVICE_FLAG_AXIS | DEVICE_FLAG_POSITIVE ) : ( DEVICE_FLAG_AXIS | DEVICE_FLAG_NEGATIVE ) ;
}
else if ( abs ( JoyState . lZ ) > DETECT_SENSITIVITY_JOYSTICK )
{
dwHow = FIELD_OFFSET ( DIJOYSTATE , lZ ) ;
dwFlags | = ( JoyState . lZ > 0 ) ? ( DEVICE_FLAG_AXIS | DEVICE_FLAG_POSITIVE ) : ( DEVICE_FLAG_AXIS | DEVICE_FLAG_NEGATIVE ) ;
}
else if ( abs ( JoyState . lRx ) > DETECT_SENSITIVITY_JOYSTICK )
{
dwHow = FIELD_OFFSET ( DIJOYSTATE , lRx ) ;
dwFlags | = ( JoyState . lRx > 0 ) ? ( DEVICE_FLAG_AXIS | DEVICE_FLAG_POSITIVE ) : ( DEVICE_FLAG_AXIS | DEVICE_FLAG_NEGATIVE ) ;
}
else if ( abs ( JoyState . lRy ) > DETECT_SENSITIVITY_JOYSTICK )
{
dwHow = FIELD_OFFSET ( DIJOYSTATE , lRy ) ;
dwFlags | = ( JoyState . lRy > 0 ) ? ( DEVICE_FLAG_AXIS | DEVICE_FLAG_POSITIVE ) : ( DEVICE_FLAG_AXIS | DEVICE_FLAG_NEGATIVE ) ;
}
else if ( abs ( JoyState . lRz ) > DETECT_SENSITIVITY_JOYSTICK )
{
dwHow = FIELD_OFFSET ( DIJOYSTATE , lRz ) ;
dwFlags | = ( JoyState . lRz > 0 ) ? ( DEVICE_FLAG_AXIS | DEVICE_FLAG_POSITIVE ) : ( DEVICE_FLAG_AXIS | DEVICE_FLAG_NEGATIVE ) ;
}
else
for ( int b = 0 ; b < 2 ; b + + )
if ( abs ( JoyState . rglSlider [ b ] ) > DETECT_SENSITIVITY_JOYSTICK )
dwHow = FIELD_OFFSET ( DIJOYSTATE , rglSlider [ b ] ) ;
else
for ( int b = 0 ; b < 4 ; b + + )
if ( abs ( JoyState . rgdwPOV [ b ] ) > DETECT_SENSITIVITY_POV )
dwHow = FIELD_OFFSET ( DIJOYSTATE , rgdwPOV [ b ] ) ;
else
for ( int b = 0 ; b < 32 ; b + + )
if ( JoyState . rgbButtons [ b ] > DETECT_SENSITIVITY_BUTTON )
dwHow = FIELD_OFFSET ( DIJOYSTATE , rgbButtons [ b ] ) ;
// ******************************************************************
// * Retrieve Object Info
// ******************************************************************
if ( dwHow ! = - 1 )
{
char * szDirection = ( dwFlags & DEVICE_FLAG_AXIS ) ? ( dwFlags & DEVICE_FLAG_POSITIVE ) ? " Positive " : " Negative " : " " ;
m_InputDevice [ v ] . m_Device - > GetDeviceInfo ( & DeviceInstance ) ;
m_InputDevice [ v ] . m_Device - > GetObjectInfo ( & ObjectInstance , dwHow , DIPH_BYOFFSET ) ;
Map ( CurConfigObject , DeviceInstance . tszInstanceName , dwHow , dwFlags ) ;
printf ( " Cxbx: Detected %s %s on %s \n " , szDirection , ObjectInstance . tszName , DeviceInstance . tszInstanceName , ObjectInstance . dwType ) ;
sprintf ( szStatus , " Success: %s Mapped to '%s%s' on '%s'! " , m_DeviceNameLookup [ CurConfigObject ] , szDirection , ObjectInstance . tszName , DeviceInstance . tszInstanceName ) ;
return true ;
}
2003-04-16 19:06:20 +00:00
}
// ******************************************************************
// * Detect Keyboard Input
// ******************************************************************
else if ( m_InputDevice [ v ] . m_Flags & DEVICE_FLAG_KEYBOARD )
{
BYTE KeyState [ 256 ] ;
m_InputDevice [ v ] . m_Device - > GetDeviceState ( 256 , KeyState ) ;
dwFlags = DEVICE_FLAG_KEYBOARD ;
2003-04-15 08:08:53 +00:00
2003-04-16 19:06:20 +00:00
// ******************************************************************
// * Check for Mouse Key State Change
// ******************************************************************
for ( int r = 0 ; r < 256 ; r + + )
{
if ( KeyState [ r ] ! = 0 )
{
dwHow = r ;
break ;
}
}
// ******************************************************************
// * Check for Success
// ******************************************************************
if ( dwHow ! = - 1 )
{
Map ( CurConfigObject , " SysKeyboard " , dwHow , dwFlags ) ;
printf ( " Cxbx: Detected Key %d on SysKeyboard \n " , dwHow ) ;
sprintf ( szStatus , " Success: %s Mapped to Key %d on SysKeyboard " , m_DeviceNameLookup [ CurConfigObject ] , dwHow ) ;
return true ;
}
}
// ******************************************************************
// * Detect Mouse Input
// ******************************************************************
else if ( m_InputDevice [ v ] . m_Flags & DEVICE_FLAG_MOUSE )
{
DIMOUSESTATE2 MouseState ;
m_InputDevice [ v ] . m_Device - > GetDeviceState ( sizeof ( MouseState ) , & MouseState ) ;
dwFlags = DEVICE_FLAG_MOUSE ;
// ******************************************************************
// * Detect Button State Change
// ******************************************************************
for ( int r = 0 ; r < 8 ; r + + )
{
// 0x80 is the mask for button push
if ( MouseState . rgbButtons [ r ] & 0x80 )
{
dwHow = r ;
dwFlags | = DEVICE_FLAG_MOUSE_CLICK ;
break ;
}
}
// ******************************************************************
// * Check for Success
// ******************************************************************
if ( dwHow ! = - 1 )
{
Map ( CurConfigObject , " SysMouse " , dwHow , dwFlags ) ;
printf ( " Cxbx: Detected Button %d on SysMouse \n " , dwHow ) ;
sprintf ( szStatus , " Success: %s Mapped to Button %d on SysMouse " , m_DeviceNameLookup [ CurConfigObject ] , dwHow ) ;
return true ;
}
// ******************************************************************
// * Check for Mouse Movement
// ******************************************************************
else
{
LONG lAbsDeltaX = 0 , lAbsDeltaY = 0 , lAbsDeltaZ = 0 ;
LONG lDeltaX = 0 , lDeltaY = 0 , lDeltaZ = 0 ;
if ( lPrevMouseX = = - 1 | | lPrevMouseY = = - 1 | | lPrevMouseZ = = - 1 )
lDeltaX = lDeltaY = lDeltaZ = 0 ;
else
{
lDeltaX = MouseState . lX - lPrevMouseX ;
lDeltaY = MouseState . lY - lPrevMouseY ;
lDeltaZ = MouseState . lZ - lPrevMouseZ ;
lAbsDeltaX = abs ( lDeltaX ) ;
lAbsDeltaY = abs ( lDeltaY ) ;
lAbsDeltaZ = abs ( lDeltaZ ) ;
}
LONG lMax = ( lAbsDeltaX > lAbsDeltaY ) ? lAbsDeltaX : lAbsDeltaY ;
if ( lAbsDeltaZ > lMax )
lMax = lAbsDeltaZ ;
lPrevMouseX = MouseState . lX ;
lPrevMouseY = MouseState . lY ;
lPrevMouseZ = MouseState . lZ ;
if ( lMax > DETECT_SENSITIVITY_MOUSE )
{
dwFlags | = DEVICE_FLAG_AXIS ;
if ( lMax = = lAbsDeltaX )
{
dwHow = DIMOFS_X ;
dwFlags | = ( lDeltaX > 0 ) ? DEVICE_FLAG_POSITIVE : DEVICE_FLAG_NEGATIVE ;
}
else if ( lMax = = lAbsDeltaY )
{
dwHow = DIMOFS_Y ;
dwFlags | = ( lDeltaY > 0 ) ? DEVICE_FLAG_POSITIVE : DEVICE_FLAG_NEGATIVE ;
}
else if ( lMax = = lAbsDeltaZ )
{
dwHow = DIMOFS_Z ;
dwFlags | = ( lDeltaZ > 0 ) ? DEVICE_FLAG_POSITIVE : DEVICE_FLAG_NEGATIVE ;
}
}
// ******************************************************************
// * Check for Success
// ******************************************************************
if ( dwHow ! = - 1 )
{
char * szDirection = ( dwFlags & DEVICE_FLAG_POSITIVE ) ? " Positive " : " Negative " ;
char * szObjName = " Unknown " ;
ObjectInstance . dwSize = sizeof ( ObjectInstance ) ;
if ( m_InputDevice [ v ] . m_Device - > GetObjectInfo ( & ObjectInstance , dwHow , DIPH_BYOFFSET ) = = DI_OK )
szObjName = ObjectInstance . tszName ;
Map ( CurConfigObject , " SysMouse " , dwHow , dwFlags ) ;
printf ( " Cxbx: Detected Movement on the %s %s on SysMouse \n " , szDirection , szObjName ) ;
sprintf ( szStatus , " Success: %s Mapped to %s %s on SysMouse " , m_DeviceNameLookup [ CurConfigObject ] , szDirection , szObjName ) ;
return true ;
}
}
2003-04-15 08:08:53 +00:00
}
}
return false ;
}
// ******************************************************************
// * func: XBController::ConfigEnd
// ******************************************************************
void XBController : : ConfigEnd ( )
2003-04-16 19:06:20 +00:00
{
if ( m_CurrentState ! = XBCTRL_STATE_CONFIG )
{
SetError ( " Invalid State " , false ) ;
return ;
}
DInputCleanup ( ) ;
m_CurrentState = XBCTRL_STATE_NONE ;
return ;
}
// ******************************************************************
// * func: XBController::ListenBegin
// ******************************************************************
void XBController : : ListenBegin ( HWND hwnd )
{
if ( m_CurrentState ! = XBCTRL_STATE_NONE )
{
SetError ( " Invalid State " , false ) ;
return ;
}
m_CurrentState = XBCTRL_STATE_LISTEN ;
DInputInit ( hwnd ) ;
return ;
}
// ******************************************************************
// * func: XBController::ListenPoll
// ******************************************************************
void XBController : : ListenPoll ( xapi : : XINPUT_STATE * Controller )
{
// TODO: For each device with a configured input device, update changes
static int step = 500 ;
Controller - > Gamepad . sThumbLX + = step ;
if ( Controller - > Gamepad . sThumbLX < 0 - 32768 - 2 * step | |
Controller - > Gamepad . sThumbLX > 0 + 32767 - 2 * step )
{
step = - step ;
Controller - > Gamepad . sThumbLX + = step ;
}
return ;
}
// ******************************************************************
// * func: XBController::ListenEnd
// ******************************************************************
void XBController : : ListenEnd ( )
{
if ( m_CurrentState ! = XBCTRL_STATE_LISTEN )
{
SetError ( " Invalid State " , false ) ;
return ;
}
DInputCleanup ( ) ;
m_CurrentState = XBCTRL_STATE_NONE ;
return ;
}
// ******************************************************************
// * func: XBController::DeviceIsUsed
// ******************************************************************
bool XBController : : DeviceIsUsed ( const char * szDeviceName )
{
for ( int v = 0 ; v < XBCTRL_MAX_DEVICES ; v + + )
{
if ( m_DeviceName [ v ] [ 0 ] ! = ' \0 ' )
{
if ( strncmp ( m_DeviceName [ v ] , szDeviceName , 255 ) = = 0 )
return true ;
}
}
return false ;
}
// ******************************************************************
// * func: XBController::DInputInit
// ******************************************************************
void XBController : : DInputInit ( HWND hwnd )
2003-04-15 08:08:53 +00:00
{
// ******************************************************************
2003-04-16 19:06:20 +00:00
// * Create DirectInput Object
2003-04-15 08:08:53 +00:00
// ******************************************************************
{
2003-04-16 19:06:20 +00:00
HRESULT hRet = DirectInput8Create
(
GetModuleHandle ( NULL ) ,
DIRECTINPUT_VERSION ,
IID_IDirectInput8 ,
( void * * ) & m_pDirectInput8 ,
NULL
) ;
if ( FAILED ( hRet ) )
{
SetError ( " Could not initialized DirectInput8 " , true ) ;
return ;
}
}
// ******************************************************************
// * Create all the devices available (well...most of them)
// ******************************************************************
if ( m_pDirectInput8 ! = 0 )
{
HRESULT hRet = m_pDirectInput8 - > EnumDevices
(
DI8DEVCLASS_GAMECTRL ,
WrapEnumGameCtrlCallback ,
this ,
DIEDFL_ATTACHEDONLY
) ;
if ( m_CurrentState = = XBCTRL_STATE_CONFIG | | DeviceIsUsed ( " SysKeyboard " ) )
2003-04-15 08:08:53 +00:00
{
2003-04-16 19:06:20 +00:00
hRet = m_pDirectInput8 - > CreateDevice ( GUID_SysKeyboard , & m_InputDevice [ m_dwInputDeviceCount ] . m_Device , NULL ) ;
if ( ! FAILED ( hRet ) )
{
m_InputDevice [ m_dwInputDeviceCount ] . m_Flags = DEVICE_FLAG_KEYBOARD ;
m_InputDevice [ m_dwInputDeviceCount + + ] . m_Device - > SetDataFormat ( & c_dfDIKeyboard ) ;
}
2003-04-15 08:08:53 +00:00
}
2003-04-16 19:06:20 +00:00
if ( m_CurrentState = = XBCTRL_STATE_CONFIG | | DeviceIsUsed ( " SysMouse " ) )
{
hRet = m_pDirectInput8 - > CreateDevice ( GUID_SysMouse , & m_InputDevice [ m_dwInputDeviceCount ] . m_Device , NULL ) ;
if ( ! FAILED ( hRet ) )
{
m_InputDevice [ m_dwInputDeviceCount ] . m_Flags = DEVICE_FLAG_MOUSE ;
m_InputDevice [ m_dwInputDeviceCount + + ] . m_Device - > SetDataFormat ( & c_dfDIMouse2 ) ;
}
}
}
2003-04-15 08:08:53 +00:00
2003-04-16 19:06:20 +00:00
// ******************************************************************
// * Set cooperative level and acquire
// ******************************************************************
{
for ( int v = m_dwInputDeviceCount - 1 ; v > = 0 ; v - - )
2003-04-15 08:08:53 +00:00
{
2003-04-16 19:06:20 +00:00
m_InputDevice [ v ] . m_Device - > SetCooperativeLevel ( hwnd , DISCL_NONEXCLUSIVE | DISCL_FOREGROUND ) ;
m_InputDevice [ v ] . m_Device - > Acquire ( ) ;
HRESULT hRet = m_InputDevice [ v ] . m_Device - > Poll ( ) ;
if ( FAILED ( hRet ) )
{
hRet = m_InputDevice [ v ] . m_Device - > Acquire ( ) ;
while ( hRet = = DIERR_INPUTLOST )
hRet = m_InputDevice [ v ] . m_Device - > Acquire ( ) ;
if ( hRet ! = DIERR_INPUTLOST )
break ;
}
2003-04-15 08:08:53 +00:00
}
}
2003-04-16 19:06:20 +00:00
// ******************************************************************
// * Enumerate Controller objects
// ******************************************************************
for ( m_dwCurObject = 0 ; m_dwCurObject < m_dwInputDeviceCount ; m_dwCurObject + + )
m_InputDevice [ m_dwCurObject ] . m_Device - > EnumObjects ( WrapEnumObjectsCallback , this , DIDFT_ALL ) ;
}
// ******************************************************************
// * func: XBController::DInputCleanup
// ******************************************************************
void XBController : : DInputCleanup ( )
{
for ( int v = m_dwInputDeviceCount - 1 ; v > = 0 ; v - - )
{
m_InputDevice [ v ] . m_Device - > Unacquire ( ) ;
m_InputDevice [ v ] . m_Device - > Release ( ) ;
m_InputDevice [ v ] . m_Device = 0 ;
}
m_dwInputDeviceCount = 0 ;
if ( m_pDirectInput8 ! = 0 )
{
m_pDirectInput8 - > Release ( ) ;
m_pDirectInput8 = 0 ;
}
2003-04-15 08:08:53 +00:00
return ;
}
// ******************************************************************
// * func: XBController::Map
// ******************************************************************
void XBController : : Map ( XBCtrlObject object , const char * szDeviceName , int dwInfo , int dwFlags )
{
// Initialize InputMapping instance
m_ObjectConfig [ object ] . dwDevice = Insert ( szDeviceName ) ;
m_ObjectConfig [ object ] . dwInfo = dwInfo ;
m_ObjectConfig [ object ] . dwFlags = dwFlags ;
// Purse unused device slots
for ( int v = 0 ; v < XBCTRL_MAX_DEVICES ; v + + )
{
bool inuse = false ;
for ( int r = 0 ; r < XBCTRL_OBJECT_COUNT ; r + + )
2003-04-16 19:06:20 +00:00
{
2003-04-15 08:08:53 +00:00
if ( m_ObjectConfig [ r ] . dwDevice = = v )
inuse = true ;
2003-04-16 19:06:20 +00:00
}
2003-04-15 08:08:53 +00:00
if ( ! inuse )
m_DeviceName [ v ] [ 0 ] = ' \0 ' ;
}
}
// ******************************************************************
// * func: XBController::Insert
// ******************************************************************
int XBController : : Insert ( const char * szDeviceName )
{
int v = 0 ;
for ( v = 0 ; v < XBCTRL_MAX_DEVICES ; v + + )
2003-04-16 19:06:20 +00:00
{
2003-04-15 08:08:53 +00:00
if ( strcmp ( m_DeviceName [ v ] , szDeviceName ) = = 0 )
return v ;
2003-04-16 19:06:20 +00:00
}
2003-04-15 08:08:53 +00:00
for ( v = 0 ; v < XBCTRL_MAX_DEVICES ; v + + )
{
if ( m_DeviceName [ v ] [ 0 ] = = ' \0 ' )
{
strncpy ( m_DeviceName [ v ] , szDeviceName , 255 ) ;
return v ;
}
}
MessageBox ( NULL , " Unexpected Circumstance (Too Many Controller Devices)! Please contact caustik! " , " Cxbx " , MB_OK | MB_ICONEXCLAMATION ) ;
ExitProcess ( 1 ) ;
return 0 ;
}
// ******************************************************************
// * func: XBController::EnumGameCtrlCallback
// ******************************************************************
BOOL XBController : : EnumGameCtrlCallback ( LPCDIDEVICEINSTANCE lpddi )
{
2003-04-16 19:06:20 +00:00
if ( m_CurrentState = = XBCTRL_STATE_LISTEN & & DeviceIsUsed ( lpddi - > tszInstanceName ) )
return DIENUM_CONTINUE ;
2003-04-15 08:08:53 +00:00
HRESULT hRet = m_pDirectInput8 - > CreateDevice ( lpddi - > guidInstance , & m_InputDevice [ m_dwInputDeviceCount ] . m_Device , NULL ) ;
if ( ! FAILED ( hRet ) )
{
m_InputDevice [ m_dwInputDeviceCount ] . m_Flags = DEVICE_FLAG_JOYSTICK ;
m_InputDevice [ m_dwInputDeviceCount + + ] . m_Device - > SetDataFormat ( & c_dfDIJoystick ) ;
}
2003-04-16 19:06:20 +00:00
printf ( " Emu: Monitoring Device %s \n " , lpddi - > tszInstanceName ) ;
2003-04-15 08:08:53 +00:00
return DIENUM_CONTINUE ;
}
// ******************************************************************
// * func: XBController::EnumObjectsCallback
// ******************************************************************
BOOL XBController : : EnumObjectsCallback ( LPCDIDEVICEOBJECTINSTANCE lpddoi )
{
if ( lpddoi - > dwType & DIDFT_AXIS )
{
DIPROPRANGE diprg ;
diprg . diph . dwSize = sizeof ( DIPROPRANGE ) ;
diprg . diph . dwHeaderSize = sizeof ( DIPROPHEADER ) ;
diprg . diph . dwHow = DIPH_BYID ;
diprg . diph . dwObj = lpddoi - > dwType ;
diprg . lMin = 0 - 32768 ;
diprg . lMax = 0 + 32767 ;
HRESULT hRet = m_InputDevice [ m_dwCurObject ] . m_Device - > SetProperty ( DIPROP_RANGE , & diprg . diph ) ;
if ( FAILED ( hRet ) )
return DIENUM_STOP ;
}
return DIENUM_CONTINUE ;
}
// ******************************************************************
// * func: WrapEnumGameCtrlCallback
// ******************************************************************
BOOL CALLBACK WrapEnumGameCtrlCallback ( LPCDIDEVICEINSTANCE lpddi , LPVOID pvRef )
{
XBController * context = ( XBController * ) pvRef ;
return context - > EnumGameCtrlCallback ( lpddi ) ;
}
// ******************************************************************
// * func: WrapEnumObjectsCallback
// ******************************************************************
BOOL CALLBACK WrapEnumObjectsCallback ( LPCDIDEVICEOBJECTINSTANCE lpddoi , LPVOID pvRef )
{
XBController * context = ( XBController * ) pvRef ;
return context - > EnumObjectsCallback ( lpddoi ) ;
}
// ******************************************************************
// * Input Device Name Lookup Table
// ******************************************************************
const char * XBController : : m_DeviceNameLookup [ XBCTRL_OBJECT_COUNT ] =
{
// ******************************************************************
// * Analog Axis
// ******************************************************************
" LThumbPosX " , " LThumbNegX " , " LThumbPosY " , " LThumbNegY " ,
" RThumbPosX " , " RThumbNegX " , " RThumbPosY " , " RThumbNegY " ,
// ******************************************************************
// * Analog Buttons
// ******************************************************************
" X " , " Y " , " A " , " B " , " White " , " Black " , " LTrigger " , " RTrigger " ,
// ******************************************************************
// * Digital Buttons
// ******************************************************************
" DPadUp " , " DPadDown " , " DPadLeft " , " DPadRight " ,
" Back " , " Start " , " LThumb " , " RThumb " ,
} ;