reman3/Rayman_X/cpa/tempgrp/INO/Specif/InitDI.c

447 lines
15 KiB
C

/***************************************************************************/
/* Description: InitDI.c, part of CPA INO library */
/* Direct Input device low level init implementation */
/* */
/* Author: F. Jentey */
/* Creation date: 21/04/97 */
/* Last Update: 30/07/97 Direct input initialisation */
/***************************************************************************/
/*======== Direct Input header ========*/
#ifndef INITGUID
#define INITGUID
#include "DInput.h"
#undef INITGUID
#else
#include "DInput.h"
#endif
/*=======================================*/
#include "INO\errINO.h"
#include "INOInit.h"
#include "InitDI.h"
#include "INOJoy.h"
#include "INOKeyb.h"
#include "INOMouse.h"
#include "Joystick.h"
#define M_DInput() INO_g_p_stDInputInterface->lpVtbl
LPDIRECTINPUT INO_g_p_stDInputInterface = NULL;
HINSTANCE INO_g_hAppInstance;
HWND INO_g_hAppMainWindow;
unsigned long m_ulDITargetVersion = DIRECTINPUT_VERSION; /* Version of Direct Input the module was build for*/
unsigned long m_ulDIInstalledVersion; /* Version of Direct Input installed on the machine*/
DIDEVCAPS g_stDIDevCaps;
DIDEVCAPS_DX3 g_stDIDevCaps3;
INO_tdstDIDevice INO_g_a_stDIDevice[INO_C_wNbMaxDevice];
short INO_g_wNbDevices = 0;
/*********************************************************************************/
/* Joystick enumeration callback */
/* Device instance are stored in INO_g_a_stJoystickInstance */
/*********************************************************************************/
BOOL CALLBACK fn_bEnumDeviceCallback(LPCDIDEVICEINSTANCE p_stDeviceInstance, LPVOID p_vRef)
{
LPDIRECTINPUTDEVICE p_stDevice;
LPDIRECTINPUTDEVICE2 p_stDevice2;
LPCDIDATAFORMAT p_stDataFormat;
DWORD ulCooperativeLevel;
HRESULT DInputErr;
/* Create the DirectInput joystick device */
DInputErr = M_DInput()->CreateDevice(
INO_g_p_stDInputInterface,
&p_stDeviceInstance->guidInstance,
&p_stDevice,
NULL
);
if (DInputErr != DI_OK) return FALSE;
switch (GET_DIDEVICE_TYPE(p_stDeviceInstance->dwDevType))
{
case DIDEVTYPE_MOUSE:
p_stDataFormat = &c_dfDIMouse;
/* All these settings have been tried in NT 4 with Service Pack 3 installed*/
/* This is the option selected...*/
ulCooperativeLevel = DISCL_NONEXCLUSIVE | DISCL_FOREGROUND;
/* This one freezes the mouse...*/
/*ulCooperativeLevel = DISCL_EXCLUSIVE | DISCL_FOREGROUND;*/
/* Works similarly to DISCL_NONEXCLUSIVE | DISCL_FOREGROUND*/
/*ulCooperativeLevel = DISCL_NONEXCLUSIVE | DISCL_BACKGROUND;*/
/* This one causes unhandled exceptions...*/
/*ulCooperativeLevel = DISCL_EXCLUSIVE | DISCL_BACKGROUND;*/
break;
case DIDEVTYPE_KEYBOARD:
p_stDataFormat = &c_dfDIKeyboard;
ulCooperativeLevel = DISCL_NONEXCLUSIVE | DISCL_FOREGROUND;
/*ulCooperativeLevel = DISCL_EXCLUSIVE | DISCL_FOREGROUND;*/
break;
case DIDEVTYPE_JOYSTICK:
p_stDataFormat = &c_dfDIJoystick;
ulCooperativeLevel = DISCL_NONEXCLUSIVE | DISCL_FOREGROUND;
break;
default:
return FALSE;
}
/* Make sure the device is not acquired before calling setDataFormat */
/* and SetCooperativeLevel. */
DInputErr = p_stDevice->lpVtbl->Unacquire(p_stDevice);
/* Set joystick data format */
DInputErr = p_stDevice->lpVtbl->SetDataFormat(p_stDevice, p_stDataFormat);
if (DInputErr != DI_OK)
{
p_stDevice->lpVtbl->Release(p_stDevice);
return FALSE;
}
/* Set the cooperative level */
DInputErr = p_stDevice->lpVtbl->SetCooperativeLevel(
p_stDevice,
INO_g_hAppMainWindow,
ulCooperativeLevel
);
if (DInputErr != DI_OK)
{
p_stDevice->lpVtbl->Release(p_stDevice);
return FALSE;
}
/* Everything is OK, keep this joystick */
memcpy(
&INO_g_a_stDIDevice[INO_g_wNbDevices].m_stDevInstance,
p_stDeviceInstance,
sizeof(DIDEVICEINSTANCE)
);
INO_g_a_stDIDevice[INO_g_wNbDevices].m_p_stDevInterface = p_stDevice;
/* Find the IDirectInput2 interface, for using Poll method */
if (GET_DIDEVICE_TYPE(p_stDeviceInstance->dwDevType) == DIDEVTYPE_JOYSTICK)
{
DInputErr = p_stDevice->lpVtbl->QueryInterface(
p_stDevice,
&IID_IDirectInputDevice2,
(LPVOID*)&p_stDevice2
);
if (DInputErr == S_OK)
{
INO_g_a_stDIDevice[INO_g_wNbDevices].m_p_stDevInterface2 = p_stDevice2;
INO_g_a_stDIDevice[INO_g_wNbDevices].m_wExtendedInterfaceAvailable = 1;
}
else
{
INO_g_a_stDIDevice[INO_g_wNbDevices].m_p_stDevInterface2 = NULL;
INO_g_a_stDIDevice[INO_g_wNbDevices].m_wExtendedInterfaceAvailable = 0;
}
}
else
{
INO_g_a_stDIDevice[INO_g_wNbDevices].m_p_stDevInterface2 = NULL;
INO_g_a_stDIDevice[INO_g_wNbDevices].m_wExtendedInterfaceAvailable = 0;
}
INO_g_wNbDevices++;
return DIENUM_CONTINUE;
}
/***********************************/
/* Init Direct Input */
/* Return 1 if OK, else 0 */
/***********************************/
short INO_fn_wInitAllDevices(HINSTANCE hInstance, HWND hWindow)
{
HRESULT DInputErr;
if (INO_g_p_stDInputInterface)
return(1);
INO_g_wNbDevices = 0;
DInputErr = DirectInputCreate(hInstance,DIRECTINPUT_VERSION,&INO_g_p_stDInputInterface,NULL);
if (DInputErr==DIERR_OLDDIRECTINPUTVERSION)
{
/* If compiled with Direct Input 5, and Direct Input 3 is installed */
DInputErr = DirectInputCreate(hInstance,DIRECTINPUT_VERSION_3,&INO_g_p_stDInputInterface,NULL);
if (DInputErr == DI_OK)
m_ulDIInstalledVersion = DIRECTINPUT_VERSION_3;
}
else
m_ulDIInstalledVersion = DIRECTINPUT_VERSION;
switch (DInputErr)
{
case DI_OK:
INO_g_hAppInstance = hInstance;
INO_g_hAppMainWindow = hWindow;
break;
case DIERR_INVALIDPARAM:
case DIERR_OUTOFMEMORY:
case DIERR_OLDDIRECTINPUTVERSION:
case DIERR_BETADIRECTINPUTVERSION:
default:
INO_g_p_stDInputInterface = NULL;
m_ulDIInstalledVersion = 0;
INO_fn_vUpdateLastError(E_uwINO_FatalDirectInpuNotFound);
return (0);
}
memset(INO_g_a_stDIDevice,0,sizeof(INO_tdstDIDevice)*INO_C_wNbMaxDevice);
DInputErr = M_DInput()->EnumDevices(
INO_g_p_stDInputInterface,
0,
fn_bEnumDeviceCallback,
NULL,
DIEDFL_ALLDEVICES
);
if( DInputErr == DI_OK )
{
return ( 1 );
}
return( 0 );
}
/***********************************/
/* Init one device */
/***********************************/
short INO_fn_wInitDevice(INO_tdhDevice hDev)
{
HRESULT DInputErr;
short i, wResult;
for (i=0; i<INO_C_wNbMaxDevice; i++)
{
if (!INO_g_a_stDIDevice[i].m_hDevice &&
(1 << GET_DIDEVICE_TYPE(INO_g_a_stDIDevice[i].m_stDevInstance.dwDevType) == INO_M_uwType(hDev))
)
{
INO_g_a_stDIDevice[i].m_hDevice = hDev;
switch (INO_M_uwType(hDev))
{
case INO_C_uwJoystick:
hDev->m_pfnRead = INO_fn_wReadJoystick;
wResult = INO_fn_wInitJoystickCaps(hDev);
break;
case INO_C_uwKeyboard:
hDev->m_pfnRead = INO_fn_wReadKeyboard;
wResult = INO_fn_wInitKeyboardCaps(hDev);
break;
case INO_C_uwMouse:
/* Initialize the mouse only if the application uses it*/
hDev->m_pfnRead = INO_fn_wReadMouse;
wResult = INO_fn_wInitMouseCaps(hDev);
break;
}
if (!wResult)
{
INO_fn_vUpdateLastError(E_uwINO_DeviceInitFailed);
return (-1);
}
DInputErr = M_DIAcquire(i);
switch (DInputErr)
{
case DI_OK:
case S_FALSE:
hDev->m_p_stState->m_ucStatus |= INO_C_ucAcquired;
break;
case DIERR_INPUTLOST:
hDev->m_p_stState->m_ucStatus &= ~INO_C_ucAcquired;
break;
case DIERR_INVALIDPARAM:
hDev->m_p_stState->m_ucStatus &= ~INO_C_ucAcquired;
INO_fn_vUpdateLastError(E_uwINO_DirectInputError);
return (-1);
default:
break;
}
return (i);
}
}
return (-1);
}
/***********************************/
/* Release one device */
/***********************************/
short INO_fn_wDestroyDevice(INO_tdhDevice hDev)
{
long i;
for (i=0; i<INO_C_wNbMaxDevice; i++)
{
if (INO_g_a_stDIDevice[i].m_hDevice == hDev)
{
M_DIUnacquire(i);
/* M_DIRelease(i);*/
memset(&INO_g_a_stDIDevice[i],0,sizeof(INO_tdstDIDevice));
return (1);
}
}
return (0);
}
/***********************************/
/* Release Direct Input */
/***********************************/
void INO_fn_vReleaseAllDevices()
{
long i;
if (!INO_g_p_stDInputInterface) return;
for (i=0; i<INO_C_wNbMaxDevice; i++)
if (INO_g_a_stDIDevice[i].m_hDevice)
{
M_DIRelease(i);
INO_fn_wDestroyDevice(INO_g_a_stDIDevice[i].m_hDevice);
}
M_DInput()->Release(INO_g_p_stDInputInterface);
INO_g_p_stDInputInterface = NULL;
}
/****************************************/
/* Free All */
/****************************************/
short INO_fn_wGetNbDevices(unsigned short uwType)
{
short i, lNb = 0;
if (!INO_g_p_stDInputInterface) return (0);
for (i=0; i<INO_C_wNbMaxDevice; i++)
if ((1 << GET_DIDEVICE_TYPE(INO_g_a_stDIDevice[i].m_stDevInstance.dwDevType)) == uwType) lNb++;
/*if (INO_g_a_stDIDevice[i].m_hDevice)*/
/* if (GET_DIDEVICE_TYPE(INO_g_a_stDIDevice[i].m_stDevInstance.dwDevType) == uwType) lNb++;*/
return (lNb);
}
/******************************************/
/* init the device capabilities */
/* and return the DInput sub-type */
/******************************************/
short INO_fn_wFillDeviceCaps(INO_tdhDevice hDev)
{
HRESULT DInputErr;
short wDev;
INO_tdstDevCaps *p_stCaps = (INO_tdstDevCaps*)(hDev->m_p_stCaps);
for (wDev=0; wDev<INO_C_wNbMaxDevice; wDev++)
if (INO_g_a_stDIDevice[wDev].m_hDevice == hDev) break;
if (wDev == INO_C_wNbMaxDevice) return (0);
M_DIAcquire(wDev);
if (m_ulDIInstalledVersion == DIRECTINPUT_VERSION_3)
{
memset(&g_stDIDevCaps3,0,sizeof(DIDEVCAPS_DX3));
g_stDIDevCaps3.dwSize = sizeof(DIDEVCAPS_DX3);
DInputErr = M_DIGetCaps(wDev,(DIDEVCAPS*)&g_stDIDevCaps3);
}
else
{
memset(&g_stDIDevCaps,0,sizeof(DIDEVCAPS));
g_stDIDevCaps.dwSize = sizeof(DIDEVCAPS);
DInputErr = M_DIGetCaps(wDev,&g_stDIDevCaps);
}
if (DInputErr == DI_OK)
{
if (m_ulDIInstalledVersion == DIRECTINPUT_VERSION_3)
{
if (g_stDIDevCaps3.dwFlags & DIDC_ATTACHED)
hDev->m_p_stState->m_ucStatus |= INO_C_ucConnected;
p_stCaps->m_ucNbButtons = (unsigned char)g_stDIDevCaps3.dwButtons;
switch (INO_M_uwType(hDev))
{
case INO_C_uwJoystick:
((INO_tdstJoystickCaps*)p_stCaps)->m_ucNbPOVs = (unsigned char)g_stDIDevCaps3.dwPOVs;
case INO_C_uwMouse:
((INO_tdstJoystickCaps*)p_stCaps)->m_ucNbAxes = (unsigned char)g_stDIDevCaps3.dwAxes;
break;
}
return (GET_DIDEVICE_SUBTYPE(g_stDIDevCaps3.dwDevType));
}
else
{
if (g_stDIDevCaps.dwFlags & DIDC_ATTACHED)
hDev->m_p_stState->m_ucStatus |= INO_C_ucConnected;
p_stCaps->m_ucNbButtons = (unsigned char)g_stDIDevCaps.dwButtons;
switch (INO_M_uwType(hDev))
{
case INO_C_uwJoystick:
((INO_tdstJoystickCaps*)p_stCaps)->m_ucNbAxes = (unsigned char)g_stDIDevCaps.dwAxes;
((INO_tdstJoystickCaps*)p_stCaps)->m_ucNbPOVs = (unsigned char)g_stDIDevCaps.dwPOVs;
break;
}
return (GET_DIDEVICE_SUBTYPE(g_stDIDevCaps.dwDevType));
}
}
else
{
hDev->m_p_stState->m_ucStatus &= ~INO_C_ucConnected;
hDev->m_p_stState->m_ucStatus &= ~INO_C_ucAcquired;
INO_fn_vUpdateLastError(E_uwINO_DeviceInitFailed);
return (0);
}
}
short INO_fn_wIsConnected(INO_tdhDevice hDev)
{
HRESULT DInputErr;
short wDev;
/* JFP: what is this used for? Is it necessary?*/
for (wDev=0; wDev<INO_C_wNbMaxDevice; wDev++)
if (INO_g_a_stDIDevice[wDev].m_hDevice == hDev)
break;
if (wDev == INO_C_wNbMaxDevice)
return (0);
/* Use DI 3 structure to go faster */
memset(&g_stDIDevCaps3,0,sizeof(DIDEVCAPS_DX3));
g_stDIDevCaps3.dwSize = sizeof(DIDEVCAPS_DX3);
DInputErr = M_DIGetCaps(wDev,(DIDEVCAPS*)&g_stDIDevCaps3);
if (DInputErr == DI_OK)
{
if (g_stDIDevCaps3.dwFlags & DIDC_ATTACHED)
{
hDev->m_p_stState->m_ucStatus |= INO_C_ucConnected;
return (1);
}
else
hDev->m_p_stState->m_ucStatus &= ~INO_C_ucConnected;
}
return (0);
}