726 lines
21 KiB
C
726 lines
21 KiB
C
|
/******************************************************************************
|
||
|
|
||
|
Copyright (C) Microsoft Corporation 1985-1990. All rights reserved.
|
||
|
|
||
|
Title: joy.c - MMSYSTEM Joystick interface code
|
||
|
|
||
|
Version: 1.00
|
||
|
|
||
|
Date: 10-Jun-1990
|
||
|
|
||
|
Author: GLENNS ROBWI
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
|
||
|
Change log:
|
||
|
|
||
|
DATE REV DESCRIPTION
|
||
|
-------- ----- -----------------------------------------------------------
|
||
|
2/7/90 Changes to avoid a bug in Windows which won't allow
|
||
|
FreeLibrary to be called during WEP.
|
||
|
|
||
|
10/11/90 .61 Use windows timer + general cleanup
|
||
|
|
||
|
*****************************************************************************/
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include "mmsystem.h"
|
||
|
#include "mmddk.h"
|
||
|
#include "mmsysi.h"
|
||
|
#include "thunks.h"
|
||
|
|
||
|
// Put init and terminate code in correct segment.
|
||
|
|
||
|
static void NEAR PASCAL joyGetCalibration(void);
|
||
|
|
||
|
#pragma alloc_text( INIT, JoyInit )
|
||
|
#pragma alloc_text( INIT, joyGetCalibration)
|
||
|
|
||
|
/* -------------------------------------------------------------------------
|
||
|
** Thunking stuff
|
||
|
** -------------------------------------------------------------------------
|
||
|
*/
|
||
|
extern JOYMESSAGEPROC PASCAL joy32Message;
|
||
|
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
|
||
|
strings
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
extern char far szNull[]; // in INIT.C
|
||
|
extern char far szSystemIni[];
|
||
|
extern char far szJoystick[];
|
||
|
extern char far szJoystickDrv[];
|
||
|
extern char far szDrivers[];
|
||
|
|
||
|
char szJoyKey[] = "JoyCal ";
|
||
|
|
||
|
/****************************************************************************
|
||
|
|
||
|
Joystick Capture Internal Structure
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
typedef struct joycapture_tag {
|
||
|
HWND hWnd;
|
||
|
UINT wPeriod;
|
||
|
BOOL bChanged;
|
||
|
UINT wThreshold;
|
||
|
UINT wIDEvent;
|
||
|
} JOYCAPTURE;
|
||
|
|
||
|
#define iJoyMax 2
|
||
|
#define JOY_UNINITIALIZED 0xFFFF
|
||
|
|
||
|
// !!! Code assumes these constants equal 0 and 1
|
||
|
|
||
|
#if JOYSTICKID1 != 0
|
||
|
ERROR IN ASSUMMED CONSTANT
|
||
|
#endif
|
||
|
#if JOYSTICKID2 != 1
|
||
|
ERROR IN ASSUMMED CONSTANT
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
|
||
|
Local data
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
static JOYCAPTURE JoyCapture[iJoyMax];
|
||
|
static HDRVR hDrvJoy[iJoyMax];
|
||
|
static UINT wNumDevs = JOY_UNINITIALIZED;
|
||
|
|
||
|
void CALLBACK joyPollCallback(HWND hWnd, UINT wMsg, UINT wIDEvent, DWORD dwTime);
|
||
|
|
||
|
/****************************************************************************
|
||
|
|
||
|
@doc INTERNAL
|
||
|
|
||
|
@api void | joyGetCalibration | Retrieve and set calibration from
|
||
|
[joystick.drv] section of system.ini file.
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
// !!! need to do clean up of strings in all of mmsystem
|
||
|
|
||
|
static void NEAR PASCAL joyGetCalibration(void)
|
||
|
{
|
||
|
char szKeyName[sizeof(szJoyKey)];
|
||
|
|
||
|
#define hexval(h) (int)(h>='a'?h-'a'+10:h-'0')
|
||
|
|
||
|
UINT val[6];
|
||
|
UINT wDev,wVal;
|
||
|
int hv;
|
||
|
char c,sz[80],far *psz;
|
||
|
|
||
|
lstrcpy(szKeyName, szJoyKey);
|
||
|
for (wDev=0; wDev < wNumDevs; wDev++)
|
||
|
{
|
||
|
szKeyName[sizeof(szKeyName)-2] = (char)(wDev + '0');
|
||
|
|
||
|
if (GetPrivateProfileString(szJoystickDrv,
|
||
|
szKeyName,szNull,sz,sizeof(sz),szSystemIni))
|
||
|
{
|
||
|
AnsiLower(sz);
|
||
|
for (psz=sz,wVal=0; c = *psz, wVal < 6; psz++)
|
||
|
{
|
||
|
if (c != ' ')
|
||
|
{
|
||
|
hv=0;
|
||
|
|
||
|
do {
|
||
|
hv = (hv << 4) + hexval(c);
|
||
|
} while ((c=*++psz) && (c!=' '));
|
||
|
|
||
|
val[wVal++] = hv;
|
||
|
}
|
||
|
}
|
||
|
joySetCalibration (wDev,val+0,val+1,val+2,val+3,val+4,val+5);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/****************************************************************************
|
||
|
|
||
|
@doc INTERNAL
|
||
|
|
||
|
@api BOOL | JoyInit | This function initializes the joystick services.
|
||
|
|
||
|
@rdesc The return value is TRUE if the services are initialised, FALSE
|
||
|
if an error occurs
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
BOOL FAR PASCAL JoyInit(void)
|
||
|
{
|
||
|
// Only attempt initialization once.
|
||
|
if (wNumDevs != JOY_UNINITIALIZED) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
else {
|
||
|
wNumDevs = 0;
|
||
|
}
|
||
|
|
||
|
wNumDevs = joyMessage( (HDRVR)1, JDD_GETNUMDEVS, 0L, 0L );
|
||
|
|
||
|
// Make sure driver was installed.
|
||
|
if (joy32Message == NULL) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
switch ( wNumDevs ) {
|
||
|
|
||
|
case 2:
|
||
|
hDrvJoy[1] = (HDRVR)2;
|
||
|
/* fall thru */
|
||
|
|
||
|
case 1:
|
||
|
hDrvJoy[0] = (HDRVR)1;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
// Initialize joycapture...
|
||
|
|
||
|
// Code relies on hWnd being NULL or an invalid window handle
|
||
|
// if joystick is not captured.
|
||
|
|
||
|
JoyCapture[0].hWnd = NULL;
|
||
|
JoyCapture[1].hWnd = NULL;
|
||
|
|
||
|
// Code relies on joystick threshold being initialized to a rational
|
||
|
// value. 0 essentially turns threshold off - any change in joystick
|
||
|
// position will be reported.
|
||
|
|
||
|
JoyCapture[0].wThreshold= 0;
|
||
|
JoyCapture[1].wThreshold= 0;
|
||
|
|
||
|
JoyCapture[0].wIDEvent= 0;
|
||
|
JoyCapture[1].wIDEvent= 0;
|
||
|
|
||
|
// bChanged, and wPeriod do not need initializing.
|
||
|
|
||
|
joyGetCalibration ();
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* MMSYSTEM JOYSTICK API'S
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
/****************************************************************************
|
||
|
|
||
|
@doc EXTERNAL
|
||
|
|
||
|
@api UINT | joyGetDevCaps | This function queries a joystick device to
|
||
|
determine its capabilities.
|
||
|
|
||
|
@parm UINT | wId | Identifies the device to be queried. This value
|
||
|
is either JOYSTICKID1 or JOYSTICKID2.
|
||
|
|
||
|
@parm LPJOYCAPS | lpCaps | Specifies a far pointer to a <t JOYCAPS>
|
||
|
data structure. This structure is filled with information about the
|
||
|
capabilities of the joystick device.
|
||
|
|
||
|
@parm UINT | wSize | Specifies the size of the <t JOYCAPS> structure.
|
||
|
|
||
|
@rdesc Returns JOYERR_NOERROR if successful. Otherwise, returns one of the
|
||
|
following error codes:
|
||
|
|
||
|
@flag MMSYSERR_NODRIVER | The joystick driver is not present.
|
||
|
|
||
|
@flag JOYERR_PARMS | The specified joystick device ID <p wId> is invalid.
|
||
|
|
||
|
@comm Use <f joyGetNumDevs> to determine the number of
|
||
|
joystick devices supported by the driver.
|
||
|
|
||
|
@xref joyGetNumDevs
|
||
|
****************************************************************************/
|
||
|
|
||
|
UINT WINAPI joyGetDevCaps(UINT wId, LPJOYCAPS lpCaps, UINT wSize)
|
||
|
{
|
||
|
V_WPOINTER(lpCaps, wSize, MMSYSERR_INVALPARAM);
|
||
|
|
||
|
if ((!hDrvJoy[0] && !JoyInit()) || (wId >= iJoyMax))
|
||
|
return MMSYSERR_NODRIVER;
|
||
|
|
||
|
if (wId >= wNumDevs)
|
||
|
return JOYERR_PARMS;
|
||
|
|
||
|
return joyMessage( hDrvJoy[wId], JDD_GETDEVCAPS,
|
||
|
(DWORD)lpCaps, (DWORD)wSize );
|
||
|
}
|
||
|
|
||
|
/****************************************************************************
|
||
|
|
||
|
@doc EXTERNAL
|
||
|
|
||
|
@api UINT | joyGetNumDevs | This function returns the number of joystick
|
||
|
devices supported by the system.
|
||
|
|
||
|
@rdesc Returns the number of joystick devices supported by the joystick
|
||
|
driver. If no driver is present, the function returns zero.
|
||
|
|
||
|
@comm Use <f joyGetPos> to determine whether a given
|
||
|
joystick is actually attached to the system. The <f joyGetPos> function returns
|
||
|
a JOYERR_UNPLUGGED error code if the specified joystick is not connected.
|
||
|
|
||
|
@xref joyGetDevCaps joyGetPos
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
UINT WINAPI joyGetNumDevs(void)
|
||
|
{
|
||
|
// Return 0 on error (Can't return JOYERR_NODRIVER
|
||
|
// since no way to distinguish error code from valid count.)
|
||
|
|
||
|
if (!hDrvJoy[0] && !JoyInit())
|
||
|
return 0;
|
||
|
|
||
|
return wNumDevs;
|
||
|
}
|
||
|
|
||
|
/****************************************************************************
|
||
|
|
||
|
@doc EXTERNAL
|
||
|
|
||
|
@api UINT | joyGetPos | This function queries for the position and button
|
||
|
activity of a joystick device.
|
||
|
|
||
|
@parm UINT | wId | Identifies the joystick device to be queried.
|
||
|
This value is either JOYSTICKID1 or JOYSTICKID2.
|
||
|
|
||
|
@parm LPJOYINFO | lpInfo | Specifies a far pointer to a <t JOYINFO>
|
||
|
data structure. This structure is filled with information about the
|
||
|
position and button activity of the joystick device.
|
||
|
|
||
|
@rdesc Returns JOYERR_NOERROR if successful. Otherwise, returns one of the
|
||
|
following error codes:
|
||
|
|
||
|
@flag MMSYSERR_NODRIVER | The joystick driver is not present.
|
||
|
|
||
|
@flag JOYERR_PARMS | The specified joystick device ID <p wId> is invalid.
|
||
|
|
||
|
@flag JOYERR_UNPLUGGED | The specified joystick is not connected to the
|
||
|
system.
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
UINT WINAPI joyGetPos(UINT wId, LPJOYINFO lpInfo)
|
||
|
{
|
||
|
V_WPOINTER(lpInfo, sizeof(JOYINFO), MMSYSERR_INVALPARAM);
|
||
|
|
||
|
if ((!hDrvJoy[0] && !JoyInit()) || (wId >= iJoyMax))
|
||
|
return MMSYSERR_NODRIVER;
|
||
|
|
||
|
if (wId >= wNumDevs)
|
||
|
return JOYERR_PARMS;
|
||
|
|
||
|
return joyMessage( hDrvJoy[wId], JDD_GETPOS, (DWORD)lpInfo, 0L );
|
||
|
}
|
||
|
|
||
|
/****************************************************************************
|
||
|
|
||
|
@doc EXTERNAL
|
||
|
|
||
|
@api UINT | joyGetThreshold | This function queries the current
|
||
|
movement threshold of a joystick device.
|
||
|
|
||
|
@parm UINT | wId | Identifies the joystick device to be queried.
|
||
|
This value is either JOYSTICKID1 or JOYSTICKID2.
|
||
|
|
||
|
@parm UINT FAR* | lpwThreshold | Specifies a far pointer to a UINT variable
|
||
|
that is filled with the movement threshold value.
|
||
|
|
||
|
@rdesc Returns JOYERR_NOERROR if successful. Otherwise, returns one of the
|
||
|
following error codes:
|
||
|
|
||
|
@flag MMSYSERR_NODRIVER | The joystick driver is not present.
|
||
|
|
||
|
@flag JOYERR_PARMS | The specified joystick device ID <p wId> is invalid.
|
||
|
|
||
|
@comm The movement threshold is the distance the joystick must be
|
||
|
moved before a WM_JOYMOVE message is sent to a window that has
|
||
|
captured the device. The threshold is initially zero.
|
||
|
|
||
|
@xref joySetThreshold
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
UINT WINAPI joyGetThreshold(UINT wId, UINT FAR* lpwThreshold)
|
||
|
{
|
||
|
V_WPOINTER(lpwThreshold, sizeof(UINT), MMSYSERR_INVALPARAM);
|
||
|
|
||
|
if (!hDrvJoy[0] && !JoyInit())
|
||
|
return MMSYSERR_NODRIVER;
|
||
|
|
||
|
if (wId >= iJoyMax)
|
||
|
return MMSYSERR_INVALPARAM;
|
||
|
|
||
|
if (wId >= wNumDevs)
|
||
|
return JOYERR_PARMS;
|
||
|
|
||
|
*lpwThreshold = (JoyCapture[wId].wThreshold);
|
||
|
|
||
|
return JOYERR_NOERROR;
|
||
|
}
|
||
|
|
||
|
/****************************************************************************
|
||
|
|
||
|
@doc EXTERNAL
|
||
|
|
||
|
@api UINT | joyReleaseCapture | This function releases the capture
|
||
|
set by <f joySetCapture> on the specified joystick device.
|
||
|
|
||
|
@parm UINT | wId | Identifies the joystick device to be released.
|
||
|
This value is either JOYSTICKID1 or JOYSTICK2.
|
||
|
|
||
|
@rdesc Returns JOYERR_NOERROR if successful. Otherwise, returns one of the
|
||
|
following error codes:
|
||
|
|
||
|
@flag MMSYSERR_NODRIVER | The joystick driver is not present.
|
||
|
|
||
|
@flag JOYERR_PARMS | The specified joystick device ID <p wId> is invalid.
|
||
|
|
||
|
@xref joySetCapture
|
||
|
****************************************************************************/
|
||
|
|
||
|
UINT WINAPI joyReleaseCapture(UINT wId)
|
||
|
{
|
||
|
if (!hDrvJoy[0] && !JoyInit())
|
||
|
return MMSYSERR_NODRIVER;
|
||
|
|
||
|
if (wId >= iJoyMax)
|
||
|
return MMSYSERR_INVALPARAM;
|
||
|
|
||
|
if (wId >= wNumDevs)
|
||
|
return JOYERR_PARMS;
|
||
|
|
||
|
if (JoyCapture[wId].hWnd == NULL)
|
||
|
return JOYERR_NOERROR;
|
||
|
|
||
|
KillTimer (NULL, JoyCapture[wId].wIDEvent);
|
||
|
JoyCapture[wId].wIDEvent = 0;
|
||
|
JoyCapture[wId].hWnd = NULL;
|
||
|
|
||
|
return JOYERR_NOERROR;
|
||
|
}
|
||
|
|
||
|
/****************************************************************************
|
||
|
|
||
|
@doc EXTERNAL
|
||
|
|
||
|
@api UINT | joySetCapture | This function causes joystick messages to
|
||
|
be sent to the specified window.
|
||
|
|
||
|
@parm HWND | hWnd | Specifies a handle to the window to which messages
|
||
|
are to be sent.
|
||
|
|
||
|
@parm UINT | wId | Identifies the joystick device to be captured.
|
||
|
This value is either JOYSTICKID1 or JOYSTICKID2.
|
||
|
|
||
|
@parm UINT | wPeriod | Specifies the polling rate, in milliseconds.
|
||
|
|
||
|
@parm BOOL | bChanged | If this parameter is set to TRUE, then messages
|
||
|
are sent only when the position changes by a value greater than the
|
||
|
joystick movement threshold.
|
||
|
|
||
|
@rdesc Returns JOYERR_NOERROR if successful. Otherwise, returns one of the
|
||
|
following error codes:
|
||
|
|
||
|
@flag MMSYSERR_NODRIVER | The joystick driver is not present.
|
||
|
|
||
|
@flag JOYERR_PARMS | The specified window handle <p hWnd>
|
||
|
or joystick device ID <p wId> is invalid.
|
||
|
|
||
|
@flag JOYERR_NOCANDO | Cannot capture joystick input because some
|
||
|
required service (for example, a Windows timer) is unavailable.
|
||
|
|
||
|
@flag JOYERR_UNPLUGGED | The specified joystick is not connected to the
|
||
|
system.
|
||
|
|
||
|
@comm This function fails if the specified joystick device is
|
||
|
currently captured. You should call the <f joyReleaseCapture> function when
|
||
|
the joystick capture is no longer needed. If the window is destroyed,
|
||
|
the joystick will be released automatically.
|
||
|
|
||
|
@xref joyReleaseCapture joySetThreshold joyGetThreshold
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
UINT WINAPI joySetCapture(HWND hwnd, UINT wId, UINT wPeriod, BOOL bChanged )
|
||
|
{
|
||
|
JOYINFO joyinfo;
|
||
|
LPJOYINFO lpinfo = &joyinfo;
|
||
|
UINT w;
|
||
|
JOYCAPS JoyCaps;
|
||
|
|
||
|
if (!hwnd || !IsWindow(hwnd))
|
||
|
return JOYERR_PARMS;
|
||
|
|
||
|
if (!hDrvJoy[0] && !JoyInit())
|
||
|
return MMSYSERR_NODRIVER;
|
||
|
|
||
|
if (wId >= iJoyMax)
|
||
|
return MMSYSERR_INVALPARAM;
|
||
|
|
||
|
if (wId >= wNumDevs)
|
||
|
return JOYERR_PARMS;
|
||
|
|
||
|
if (JoyCapture[wId].hWnd)
|
||
|
if (IsWindow(JoyCapture[wId].hWnd))
|
||
|
return JOYERR_NOCANDO;
|
||
|
else
|
||
|
joyReleaseCapture(wId);
|
||
|
|
||
|
if (joyGetDevCaps (wId, &JoyCaps, sizeof(JOYCAPS)) == 0)
|
||
|
wPeriod = min(JoyCaps.wPeriodMax,max(JoyCaps.wPeriodMin,wPeriod));
|
||
|
else
|
||
|
return JOYERR_NOCANDO;
|
||
|
|
||
|
// ensure that position info. is ok.
|
||
|
|
||
|
if (w = joyGetPos(wId, lpinfo))
|
||
|
return (w);
|
||
|
|
||
|
JoyCapture[wId].wPeriod = wPeriod;
|
||
|
JoyCapture[wId].bChanged = bChanged;
|
||
|
|
||
|
if (!(JoyCapture[wId].wIDEvent = SetTimer(NULL, 0, wPeriod, (TIMERPROC)joyPollCallback)))
|
||
|
{
|
||
|
DOUT("MMSYSTEM: Couldn't allocate timer in joy.c\r\n");
|
||
|
return JOYERR_NOCANDO;
|
||
|
}
|
||
|
|
||
|
JoyCapture[wId].hWnd = hwnd;
|
||
|
return JOYERR_NOERROR;
|
||
|
}
|
||
|
|
||
|
/****************************************************************************
|
||
|
|
||
|
@doc EXTERNAL
|
||
|
|
||
|
@api UINT | joySetThreshold | This function sets the movement threshold
|
||
|
of a joystick device.
|
||
|
|
||
|
@parm UINT | wId | Identifies the joystick device. This value is either
|
||
|
JOYSTICKID1 or JOYSTICKID2.
|
||
|
|
||
|
@parm UINT | wThreshold | Specifies the new movement threshold.
|
||
|
|
||
|
@rdesc Returns JOYERR_NOERROR if successful. Otherwise, returns one of the
|
||
|
following error codes:
|
||
|
|
||
|
@flag MMSYSERR_NODRIVER | The joystick driver is not present.
|
||
|
|
||
|
@flag JOYERR_PARMS | The specified joystick device ID <p wId> is invalid.
|
||
|
|
||
|
@comm The movement threshold is the distance the joystick must be
|
||
|
moved before a MM_JOYMOVE message is sent to a window that has
|
||
|
captured the device.
|
||
|
|
||
|
@xref joyGetThreshold joySetCapture
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
UINT WINAPI joySetThreshold(UINT wId, UINT wThreshold)
|
||
|
{
|
||
|
if (!hDrvJoy[0] && !JoyInit())
|
||
|
return MMSYSERR_NODRIVER;
|
||
|
|
||
|
if (wId >= iJoyMax)
|
||
|
return MMSYSERR_INVALPARAM;
|
||
|
|
||
|
if (wId >= wNumDevs)
|
||
|
return JOYERR_PARMS;
|
||
|
|
||
|
JoyCapture[wId].wThreshold = wThreshold;
|
||
|
return JOYERR_NOERROR;
|
||
|
}
|
||
|
|
||
|
/****************************************************************************
|
||
|
|
||
|
@doc INTERNAL
|
||
|
|
||
|
@api UINT | joySetCalibration | This function sets the values used to
|
||
|
convert the values returned by the joystick drivers GetPos function
|
||
|
to the range specified in GetDevCaps.
|
||
|
|
||
|
@parm UINT | wId | Identifies the joystick device
|
||
|
|
||
|
@parm UINT FAR* | pwXbase | Specifies the base value for the X pot. The
|
||
|
previous value will be copied back to the variable pointed to here.
|
||
|
|
||
|
@parm UINT FAR* | pwXdelta | Specifies the delta value for the X pot. The
|
||
|
previous value will be copied back to the variable pointed to here.
|
||
|
|
||
|
@parm UINT FAR* | pwYbase | Specifies the base value for the Y pot. The
|
||
|
previous value will be copied back to the variable pointed to here.
|
||
|
|
||
|
@parm UINT FAR* | pwYdelta | Specifies the delta value for the Y pot. The
|
||
|
previous value will be copied back to the variable pointed to here.
|
||
|
|
||
|
@parm UINT FAR* | pwZbase | Specifies the base value for the Z pot. The
|
||
|
previous value will be copied back to the variable pointed to here.
|
||
|
|
||
|
@parm UINT FAR* | pwZdelta | Specifies the delta value for the Z pot. The
|
||
|
previous value will be copied back to the variable pointed to here.
|
||
|
|
||
|
@rdesc The return value is zero if the function was successful, otherwise
|
||
|
it is an error number.
|
||
|
|
||
|
@comm The base represents the lowest value the joystick driver returns,
|
||
|
whereas the delta represents the multiplier to use to convert
|
||
|
the actual value returned by the driver to the valid range
|
||
|
for the joystick API's.
|
||
|
i.e. If the driver returns a range of 43-345 for the X pot, and
|
||
|
the valid mmsystem API range is 0-65535, the base value will be
|
||
|
43, and the delta will be 65535/(345-43)=217. Thus the base,
|
||
|
and delta convert 43-345 to a range of 0-65535 with the formula:
|
||
|
((wXvalue-43)*217) , where wXvalue was given by the joystick driver.
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
UINT WINAPI joySetCalibration( UINT wId,
|
||
|
UINT FAR* pwXbase,
|
||
|
UINT FAR* pwXdelta,
|
||
|
UINT FAR* pwYbase,
|
||
|
UINT FAR* pwYdelta,
|
||
|
UINT FAR* pwZbase,
|
||
|
UINT FAR* pwZdelta )
|
||
|
{
|
||
|
JOYCALIBRATE oldCal,newCal;
|
||
|
UINT w;
|
||
|
|
||
|
if (!hDrvJoy[0] && !JoyInit())
|
||
|
return MMSYSERR_NODRIVER;
|
||
|
|
||
|
if (wId >= wNumDevs)
|
||
|
return JOYERR_PARMS;
|
||
|
|
||
|
newCal.wXbase = *pwXbase;
|
||
|
newCal.wXdelta = *pwXdelta;
|
||
|
|
||
|
newCal.wYbase = *pwYbase;
|
||
|
newCal.wYdelta = *pwYdelta;
|
||
|
|
||
|
newCal.wZbase = *pwZbase;
|
||
|
newCal.wZdelta = *pwZdelta;
|
||
|
|
||
|
w = joyMessage( hDrvJoy[wId], JDD_SETCALIBRATION, (DWORD)(LPSTR)&newCal,
|
||
|
(DWORD)(LPSTR)&oldCal );
|
||
|
|
||
|
*pwXbase = oldCal.wXbase;
|
||
|
*pwXdelta = oldCal.wXdelta;
|
||
|
|
||
|
*pwYbase = oldCal.wYbase;
|
||
|
*pwYdelta = oldCal.wYdelta;
|
||
|
|
||
|
*pwZbase = oldCal.wZbase;
|
||
|
*pwZdelta = oldCal.wZdelta;
|
||
|
|
||
|
return w;
|
||
|
}
|
||
|
|
||
|
/****************************************************************************
|
||
|
|
||
|
@doc INTERNAL
|
||
|
|
||
|
@api void | joyPollCallback | Function called for joystick
|
||
|
timer polling scheme initiated from SetCapture call.
|
||
|
|
||
|
@parm HWND | hWnd | Identifies the window associated with the timer
|
||
|
event.
|
||
|
|
||
|
@parm UINT | wMsg | Specifies the WM_TIMER message.
|
||
|
|
||
|
@parm UINT | wIDEvent | Specifies the timer's ID.
|
||
|
|
||
|
@parm DWORD | dwTime | Specifies the current system time.
|
||
|
|
||
|
|
||
|
****************************************************************************/
|
||
|
|
||
|
void CALLBACK joyPollCallback(HWND hWnd, UINT wMsg, UINT wIDEvent, DWORD dwTime)
|
||
|
{
|
||
|
#define diff(w1,w2) (UINT)(w1 > w2 ? w1-w2 : w2-w1)
|
||
|
|
||
|
static JOYINFO oldInfo[2] = {{ 0, 0, 0, 0 },{ 0, 0, 0, 0 }};
|
||
|
JOYINFO Info;
|
||
|
|
||
|
UINT w ,fBtnMask;
|
||
|
|
||
|
if (wIDEvent == JoyCapture[0].wIDEvent)
|
||
|
wIDEvent = 0;
|
||
|
else if (wIDEvent == JoyCapture[1].wIDEvent)
|
||
|
wIDEvent = 1;
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
else
|
||
|
{
|
||
|
DOUT("MMSYSTEM: Invalid timer handle in joy.c\r\n");
|
||
|
KillTimer (NULL, wIDEvent);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
if (!JoyCapture[wIDEvent].hWnd || !IsWindow(JoyCapture[wIDEvent].hWnd))
|
||
|
joyReleaseCapture(wIDEvent);
|
||
|
|
||
|
if (!joyMessage( hDrvJoy[wIDEvent], JDD_GETPOS,
|
||
|
(DWORD)(LPJOYINFO)&Info, 0L ))
|
||
|
{
|
||
|
|
||
|
for (w=0,fBtnMask=1; w < 4; w++,fBtnMask <<=1)
|
||
|
{
|
||
|
if ((Info.wButtons ^ oldInfo[wIDEvent].wButtons) & fBtnMask)
|
||
|
{
|
||
|
PostMessage(
|
||
|
JoyCapture[wIDEvent].hWnd,
|
||
|
wIDEvent + ((Info.wButtons & fBtnMask) ?
|
||
|
MM_JOY1BUTTONDOWN : MM_JOY1BUTTONUP ),
|
||
|
(WPARAM)(Info.wButtons | fBtnMask << 8),
|
||
|
MAKELPARAM(Info.wXpos,Info.wYpos));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!JoyCapture[wIDEvent].bChanged ||
|
||
|
diff(Info.wXpos,oldInfo[wIDEvent].wXpos)>JoyCapture[wIDEvent].wThreshold ||
|
||
|
diff(Info.wYpos,oldInfo[wIDEvent].wYpos)>JoyCapture[wIDEvent].wThreshold)
|
||
|
{
|
||
|
PostMessage(
|
||
|
JoyCapture[wIDEvent].hWnd,
|
||
|
MM_JOY1MOVE+wIDEvent,
|
||
|
(WPARAM)(Info.wButtons),
|
||
|
MAKELPARAM(Info.wXpos,Info.wYpos));
|
||
|
|
||
|
}
|
||
|
|
||
|
else if (!JoyCapture[wIDEvent].bChanged ||
|
||
|
diff(Info.wZpos,oldInfo[wIDEvent].wZpos)>JoyCapture[wIDEvent].wThreshold)
|
||
|
{
|
||
|
PostMessage(
|
||
|
JoyCapture[wIDEvent].hWnd,
|
||
|
MM_JOY1ZMOVE+wIDEvent,
|
||
|
(WPARAM)Info.wButtons,
|
||
|
MAKELPARAM(Info.wZpos,0));
|
||
|
}
|
||
|
|
||
|
oldInfo[wIDEvent] = Info;
|
||
|
}
|
||
|
#undef diff
|
||
|
}
|