|
|
//****************************************************************************
//
// File: joycal.c
// Content: Joystick calibration dialog
// History:
// Date By Reason
// ==== == ======
// 11-dec-94 craige split out of joycpl.c; some tweaks
// 15-dec-94 craige allow N joysticks
// 17-dec-94 craige new UI as requested by ChrisB
// 18-dec-94 craige process UV
// 05-jan-95 craige new centering confirmation messages
// 04-mar-95 craige bug 10761 - separate strings for pluralization
// bug 12036 - now works when "Back" clicked off of
// custom 4-axis with POV hat
//
// Copyright (c) Microsoft Corporation 1994-1995
//
//****************************************************************************
#pragma pack (8)
#include "stdafx.h"
#include "joycpl.h"
#include "resource.h"
#include "pov.h"
#include "assert.h"
#include "baseids.h"
#include "comstr.h"
#undef NewLoadString
#define NewLoadString(a, b, c, d) \
pszCommonString->LoadString(b); \ lstrcpy( c, (LPCTSTR)*pszCommonString )
// Context sensitive help stuff!
static void OnContextMenu(WPARAM wParam); static void OnHelp (LPARAM);
static const DWORD CalibrateHelpIDs[] = { IDC_JOYLIST1, IDC_JOYLIST1, IDC_JOYLIST2, IDC_JOYLIST2, IDC_JOYLIST3, IDC_JOYLIST3, IDC_JOYLIST4, IDC_JOYLIST4, 0, 0 };
/*
* This has the look and feel of a wizard, but isn't This leads to the * obvious... * * Q: Why isn't this a "real" wizard? * * A: - it doesn't have multiple pages, it has a single page. the user * sees different joystick items activate and de-activate on the dialog * as he/she calibrates each axis. fussing with multiple sheets for each * axis would be confusing and unnecessary. */
/*
* calibration states */ // %%% debug %%% alpha days
extern "C" { typedef enum { JCS_INIT=-1, JCS_XY_CENTER1, JCS_XY_MOVE, JCS_XY_CENTER2, JCS_Z_MOVE, JCS_Z_PLACEHOLDER, JCS_R_MOVE, JCS_R_PLACEHOLDER, JCS_U_MOVE, JCS_U_PLACEHOLDER, JCS_V_MOVE, JCS_V_PLACEHOLDER, JCS_POV_MOVEUP, JCS_POV_MOVERIGHT, JCS_POV_MOVEDOWN, JCS_POV_MOVELEFT, JCS_FINI } cal_states;
typedef enum { JC_XY=0, JC_Z, JC_POV_UP, JC_POV_RIGHT, JC_POV_DOWN, JC_POV_LEFT, JC_R, JC_U, JC_V, JC_FINI } cal_wins;
// variables used in calibration
typedef struct { LPGLOBALVARS pgv; cal_states cState; BOOL bHasTimer; BOOL bUseTimer; HINSTANCE hinst; JOYINFOEX ji; JOYRANGE jr; DWORD pov[JOY_POV_NUMDIRS]; int iAxisCount; BOOL bPOVdone; } CALVARS, *LPCALVARS;
extern "C" WINMMAPI MMRESULT WINAPI joyConfigChanged(DWORD);
#define JOY_CALIB_FLAGS JOY_RETURNX | JOY_RETURNY | JOY_RETURNZ | \
JOY_RETURNR | JOY_RETURNU | JOY_RETURNV | \ JOY_RETURNBUTTONS | JOY_RETURNRAWDATA
/*
* we use raw data during calibration; RAW_SHIFT allows us to convert to * a reasonable "real" value */ #define RAW_SHIFT 100
} // extern "C"
// setDefaultButton - make a button the default window
static void setDefaultButton( HWND hwnd, HWND hwdb ) { // Optimized New Method
SendMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)hwdb, (LPARAM)TRUE);
/* Optimized Old Method
DWORD style; HWND hCtrl; int idList[] = { IDC_JOYCALDONE, IDC_JOYCALNEXT, IDC_JOYCALBACK, IDC_JOYPICKPOV }; #define SIZEOF_LIST 4
// turn off the current default push button
for (short i=0; i < SIZEOF_LIST; i++ ) { hCtrl = GetDlgItem( hwnd, idList[i] );
if (hCtrl) { style = GetWindowLong( hCtrl, GWL_STYLE );
if ( style & BS_DEFPUSHBUTTON ) { style &= ~BS_DEFPUSHBUTTON; style |= BS_PUSHBUTTON; SetWindowLong( hCtrl, GWL_STYLE, style ); break; } } }
// make the specified button the default
style = GetWindowLong( hwdb, GWL_STYLE ); style &= ~(BS_PUSHBUTTON|BS_DEFPUSHBUTTON); style |= BS_DEFPUSHBUTTON; SetWindowLong( hwdb, GWL_STYLE, style ); */
} // setDefaultButton
/*
* setLabel * * set the label for an axis based on current calibration state */ static void setLabel( LPGLOBALVARS pgv, HWND hwnd, UINT id, LPJOYREGHWCONFIG pcfg, DWORD bit ) { char str[MAX_STR]; int type; HINSTANCE hinst; HWND hwtext;
hinst = GetResourceInstance( ); assert(hinst);
// get text for this axis label...
if( pcfg->dwUsageSettings & JOY_US_ISOEM ) { type = pcfg->dwType - JOY_HW_LASTENTRY; if( type < 0 || type >= pgv->pjd->oemCount ) { type = -1; } } else { type = -1; }
switch( id ) { case IDC_JOYLIST1_LABEL: if( (type == -1) || (pgv->pjd->oemList[type].xy_label[0] == 0) ) { NewLoadString( hinst, IDS_XYAXIS_LABEL, str, sizeof( str ) ); if( !lstrlen(str) ) return; } else lstrcpy( str, pgv->pjd->oemList[type].xy_label ); break;
case IDC_JOYLIST2_LABEL: if( (type == -1) || (pgv->pjd->oemList[type].z_label[0] == 0 ) ) { NewLoadString( hinst, IDS_ZAXIS_LABEL, str, sizeof( str ) ); if( !lstrlen(str) ) return; } else lstrcpy( str, pgv->pjd->oemList[type].z_label ); break;
case IDC_JOYLIST3_LABEL: if( (type == -1) || (pgv->pjd->oemList[type].r_label[0] == 0) ) { NewLoadString( hinst, IDS_RAXIS_LABEL, str, sizeof( str ) ); if( !lstrlen(str) ) return; } else lstrcpy( str, pgv->pjd->oemList[type].r_label ); break;
case IDC_JOYLIST4_LABEL: if( (type == -1) || (pgv->pjd->oemList[type].u_label[0] == 0) ) { NewLoadString( hinst, IDS_UAXIS_LABEL, str, sizeof( str ) ); if( !lstrlen(str) ) return; } else lstrcpy( str, pgv->pjd->oemList[type].u_label ); break;
case IDC_JOYLIST5_LABEL: if( (type == -1) || (pgv->pjd->oemList[type].v_label[0] == 0) ) { NewLoadString( hinst, IDS_VAXIS_LABEL, str, sizeof( str ) ); if( !lstrlen(str) ) return; } else lstrcpy( str, pgv->pjd->oemList[type].v_label ); break;
case IDC_JOYPOV_LABEL: if( (type == -1) || (pgv->pjd->oemList[type].pov_label[0] == 0) ) { NewLoadString( hinst, IDS_POVAXIS_LABEL, str, sizeof( str ) ); if( !lstrlen(str) ) return; } else lstrcpy( str, pgv->pjd->oemList[type].pov_label ); break; }
hwtext = GetDlgItem( hwnd, id ); ASSERT (::IsWindow(hwtext));
if( hwtext != NULL ) SetWindowText( hwtext, str );
} /* setLabel */
// enableCalWindows - enable or disable specific calibration windows
static void enableCalWindows( LPGLOBALVARS pgv, LPJOYREGHWCONFIG pcfg, HWND hwnd, cal_wins id ) { BOOL on; HWND hwlb; HWND hwb; int iid;
// set up the buttons
hwb = GetDlgItem( hwnd,IDC_JOYCALDONE ); ASSERT (hwb);
if( id == JC_FINI ) { hwlb = GetDlgItem( hwnd, IDC_JOYCALNEXT ); ASSERT (::IsWindow(hwlb)); ShowWindow(hwlb, SW_HIDE );
EnableWindow( hwb, TRUE ); ShowWindow( hwb, SW_NORMAL ); SetFocus( hwb ); setDefaultButton( hwnd, hwb ); } else { hwlb = GetDlgItem( hwnd, IDC_JOYCALNEXT ); ASSERT (::IsWindow(hwlb)); ShowWindow( hwlb, SW_NORMAL );
EnableWindow( hwb, FALSE ); ShowWindow( hwb, SW_HIDE ); }
setLabel( pgv, hwnd, IDC_JOYLIST1_LABEL, pcfg, JOY_ISCAL_XY );
// set up the XY window
on = FALSE;
if( id == JC_XY ) on = TRUE;
hwlb = GetDlgItem( hwnd, IDC_JOYLIST1 ); ASSERT (::IsWindow(hwlb));
if( !on ) InvalidateRect( hwlb, NULL, TRUE );
EnableWindow( hwlb, on ); EnableWindow( GetDlgItem( hwnd, IDC_JOYLIST1_LABEL ), on );
/*
* set up the Z window */ on = FALSE; if( id == JC_Z ) on = TRUE;
hwlb = GetDlgItem( hwnd, IDC_JOYLIST2 ); if( !on ) { InvalidateRect( hwlb, NULL, TRUE ); } EnableWindow( hwlb, on ); EnableWindow( GetDlgItem( hwnd, IDC_JOYLIST2_LABEL ), on );
/*
* set up the R window */ on = FALSE; if( id == JC_R ) { on = TRUE; } hwlb = GetDlgItem( hwnd, IDC_JOYLIST3 ); if( !on ) { InvalidateRect( hwlb, NULL, TRUE ); } EnableWindow( hwlb, on ); EnableWindow( GetDlgItem( hwnd, IDC_JOYLIST3_LABEL ), on );
/*
* set up the U window */ on = FALSE; if( id == JC_U ) { on = TRUE; } hwlb = GetDlgItem( hwnd, IDC_JOYLIST4 ); if( hwlb != NULL ) { if( !on ) { InvalidateRect( hwlb, NULL, TRUE ); } EnableWindow( hwlb, on ); EnableWindow( GetDlgItem( hwnd, IDC_JOYLIST4_LABEL ), on ); }
/*
* set up the V window */ on = FALSE; if( id == JC_V ) { on = TRUE; } hwlb = GetDlgItem( hwnd, IDC_JOYLIST5 ); if( hwlb != NULL ) { if( !on ) { InvalidateRect( hwlb, NULL, TRUE ); } EnableWindow( hwlb, on ); EnableWindow( GetDlgItem( hwnd, IDC_JOYLIST5_LABEL ), on ); }
/*
* set up the POV icon */ on = FALSE; if( id >= JC_POV_UP && id <= JC_POV_LEFT ) { on = TRUE; } EnableWindow( GetDlgItem( hwnd, IDC_JOYPOV_LABEL ), on ); hwb = GetDlgItem( hwnd, IDC_JOYPICKPOV ); EnableWindow( hwb, on ); if( on ) { ShowWindow( hwb, SW_NORMAL ); SetFocus( hwb ); setDefaultButton( hwnd, hwb ); switch( id ) { case JC_POV_UP: iid = IDI_JOYPOV_UP; break; case JC_POV_RIGHT: iid = IDI_JOYPOV_RIGHT; break; case JC_POV_LEFT: iid = IDI_JOYPOV_LEFT; break; case JC_POV_DOWN: iid = IDI_JOYPOV_DOWN; break; } } else { ShowWindow( hwb, SW_HIDE ); UpdateWindow( hwb ); iid = IDI_JOYPOV_GRAYED; } ChangeIcon( hwnd, iid, IDC_JOYPOV );
} /* enableCalWindows */
/*
* getJoyName - get the name of a joystick */ static int getJoyName( LPJOYREGHWCONFIG pcfg, BOOL plural ) { int str2id;
if( pcfg->hws.dwFlags & JOY_HWS_ISYOKE ) { str2id = ( plural ) ? IDS_JOYCAL_YOKES : IDS_JOYCAL_YOKE; } else if( pcfg->hws.dwFlags & JOY_HWS_ISCARCTRL ) { str2id = ( plural ) ? IDS_JOYCAL_CARS : IDS_JOYCAL_CAR; } else if( pcfg->hws.dwFlags & JOY_HWS_ISGAMEPAD ) { str2id = ( plural ) ? IDS_JOYCAL_GAMEPADS : IDS_JOYCAL_GAMEPAD; } else { str2id = ( plural ) ? IDS_JOY2S : IDS_JOY2; }
return(str2id);
} /* getJoyName */
/*
* joyCalStateChange - calibration state change */ static BOOL joyCalStateChange( LPCALVARS pcv, HWND hwnd, BOOL back ) { HINSTANCE hinst; HWND hwtext; int strid; int stridx = 0; // BUG FIX: CML 6/21/96 (FLASH RAID 270)
int str2id; int str3id; int str4id; char str[2*MAX_STR]; char buff[2*MAX_STR]; char str2[64]; char str3[64]; char str4[64]; BOOL done; LPJOYREGHWCONFIG pcfg; BOOL rc; int type; LPGLOBALVARS pgv; BOOL isdone;
assert(pcv); assert(hwnd);
/*
* move to the next state: get the appropriate string * to display, and enable the correct controls */ pgv = pcv->pgv; assert(pgv); rc = TRUE; done = FALSE; pcfg = &pgv->joyHWCurr; str2id = -1; str3id = -1; str4id = -1; (pcv->cState) = (cal_states) (pcv->cState + ((cal_states) 1)); EnableWindow( GetDlgItem( hwnd, IDC_JOYCALBACK ), back );
while( !done ) { done = TRUE;
switch( pcv->cState ) { case JCS_XY_CENTER1: /*
* init. range variables */ pcv->jr.jpMin.dwX = (DWORD) -1; pcv->jr.jpMin.dwY = (DWORD) -1; pcv->jr.jpMin.dwZ = (DWORD) -1; pcv->jr.jpMin.dwR = (DWORD) -1; pcv->jr.jpMin.dwU = (DWORD) -1; pcv->jr.jpMin.dwV = (DWORD) -1; pcv->jr.jpMax.dwX = 0; pcv->jr.jpMax.dwY = 0; pcv->jr.jpMax.dwZ = 0; pcv->jr.jpMax.dwR = 0; pcv->jr.jpMax.dwU = 0; pcv->jr.jpMax.dwV = 0;
// set strings to display
stridx = CALSTR1;
if( pcfg->hws.dwFlags & JOY_HWS_ISYOKE ) { strid = IDS_JOYCALXY_CENTERYOKE; } else if( pcfg->hws.dwFlags & JOY_HWS_ISCARCTRL ) { strid = IDS_JOYCALXY_CENTERCAR; } else if( pcfg->hws.dwFlags & JOY_HWS_ISGAMEPAD ) { strid = IDS_JOYCALXY_CENTERGAMEPAD; } else { strid = IDS_JOYCALXY_CENTER; }
enableCalWindows( pgv, pcfg, hwnd, JC_XY ); break;
case JCS_XY_MOVE: stridx = CALSTR2; if( pcfg->hws.dwFlags & JOY_HWS_ISYOKE ) { strid = IDS_JOYCALXY_MOVEYOKE; } else if( pcfg->hws.dwFlags & JOY_HWS_ISCARCTRL ) { strid = IDS_JOYCALXY_MOVECAR; } else if( pcfg->hws.dwFlags & JOY_HWS_ISGAMEPAD ) { strid = IDS_JOYCALXY_MOVEGAMEPAD; } else { strid = IDS_JOYCALXY_MOVE; } break;
case JCS_XY_CENTER2: stridx = CALSTR3; if( pcfg->hws.dwFlags & JOY_HWS_ISYOKE ) { strid = IDS_JOYCALXY_CENTERYOKE2; } else if( pcfg->hws.dwFlags & JOY_HWS_ISCARCTRL ) { strid = IDS_JOYCALXY_CENTERCAR2; } else if( pcfg->hws.dwFlags & JOY_HWS_ISGAMEPAD ) { strid = IDS_JOYCALXY_CENTERGAMEPAD2; } else { strid = IDS_JOYCALXY_CENTER2; } break;
case JCS_Z_MOVE: stridx = CALSTR4; if( !(pcfg->hws.dwFlags & JOY_HWS_HASZ) ) { pcv->cState = JCS_R_MOVE; done = FALSE; } else { enableCalWindows( pgv, pcfg, hwnd, JC_Z ); strid = IDS_JOYCALZ_MOVE; str2id = getJoyName( pcfg, TRUE ); } break;
case JCS_Z_PLACEHOLDER: pcv->cState = JCS_R_MOVE; done = FALSE; break;
case JCS_R_MOVE: stridx = CALSTR5; if( !(pcfg->hws.dwFlags & JOY_HWS_HASR) && !(pcfg->dwUsageSettings & JOY_US_HASRUDDER) ) { pcv->cState = JCS_U_MOVE; done = FALSE; } else { enableCalWindows( pgv, pcfg, hwnd, JC_R ); strid = IDS_JOYCALRUDDER_MOVE; str2id = getJoyName( pcfg, TRUE ); } break;
case JCS_R_PLACEHOLDER: pcv->cState = JCS_U_MOVE; done = FALSE; break;
case JCS_U_MOVE: stridx = CALSTR6; if( !(pcfg->hws.dwFlags & JOY_HWS_HASU) ) { pcv->cState = JCS_V_MOVE; done = FALSE; } else { enableCalWindows( pgv, pcfg, hwnd, JC_U ); strid = IDS_JOYCALU_MOVE; str2id = getJoyName( pcfg, TRUE ); } break;
case JCS_U_PLACEHOLDER: pcv->cState = JCS_V_MOVE; done = FALSE; break;
case JCS_V_MOVE: stridx = CALSTR7; if( !(pcfg->hws.dwFlags & JOY_HWS_HASV) ) { pcv->cState = JCS_POV_MOVEUP; done = FALSE; } else { enableCalWindows( pgv, pcfg, hwnd, JC_V ); strid = IDS_JOYCALV_MOVE; str2id = getJoyName( pcfg, TRUE ); } break;
case JCS_V_PLACEHOLDER: pcv->cState = JCS_POV_MOVEUP; done = FALSE; break;
case JCS_POV_MOVEUP: stridx = CALSTR8; if( !(pcfg->hws.dwFlags & JOY_HWS_HASPOV) ) { pcv->cState = JCS_FINI; done = FALSE; } else { enableCalWindows( pgv, pcfg, hwnd, JC_POV_UP ); strid = IDS_JOYCALPOV_MOVE; str2id = IDS_JOYCAL_UP; str3id = getJoyName( pcfg, TRUE ); str4id = IDS_JOYCAL_UP; } break;
case JCS_POV_MOVERIGHT: stridx = CALSTR9; enableCalWindows( pgv, pcfg, hwnd, JC_POV_RIGHT ); strid = IDS_JOYCALPOV_MOVE; str2id = IDS_JOYCAL_RIGHT; str3id = getJoyName( pcfg, TRUE ); str4id = IDS_JOYCAL_RIGHT; break;
case JCS_POV_MOVEDOWN: stridx = CALSTR10; enableCalWindows( pgv, pcfg, hwnd, JC_POV_DOWN ); strid = IDS_JOYCALPOV_MOVE; str2id = IDS_JOYCAL_DOWN; str3id = getJoyName( pcfg, TRUE ); str4id = IDS_JOYCAL_DOWN; break;
case JCS_POV_MOVELEFT: stridx = CALSTR11; enableCalWindows( pgv, pcfg, hwnd, JC_POV_LEFT ); strid = IDS_JOYCALPOV_MOVE; str2id = IDS_JOYCAL_LEFT; str3id = getJoyName( pcfg, TRUE ); str4id = IDS_JOYCAL_LEFT; break;
case JCS_FINI: /*
* see if everything that needs to be calibrated * was actually calibrated */ if( !(pcfg->hwv.dwCalFlags & JOY_ISCAL_XY) ) { isdone = FALSE; } else if( (pcfg->hws.dwFlags & JOY_HWS_HASZ) && !(pcfg->hwv.dwCalFlags & JOY_ISCAL_Z) ) { isdone = FALSE; } else if( ((pcfg->hws.dwFlags & JOY_HWS_HASR) || (pcfg->dwUsageSettings & JOY_US_HASRUDDER)) && !(pcfg->hwv.dwCalFlags & JOY_ISCAL_R) ) { isdone = FALSE; } else if( (pcfg->hws.dwFlags & JOY_HWS_HASPOV) && !(pcfg->hwv.dwCalFlags & JOY_ISCAL_POV) ) { isdone = FALSE; } else if( (pcfg->hws.dwFlags & JOY_HWS_HASU) && !(pcfg->hwv.dwCalFlags & JOY_ISCAL_U) ) { isdone = FALSE; } else if( (pcfg->hws.dwFlags & JOY_HWS_HASV) && !(pcfg->hwv.dwCalFlags & JOY_ISCAL_V) ) { isdone = FALSE; } else { isdone = TRUE; }
strid = ( isdone ) ? IDS_JOYCAL_DONE : IDS_JOYCAL_NOTDONE;
str2id = getJoyName( pcfg, FALSE ); str3id = getJoyName( pcfg, TRUE ); stridx = CALSTR12; enableCalWindows( pgv, pcfg, hwnd, JC_FINI ); rc = FALSE; break; } // END OF SWITCH
} // END OF WHILE
// see if there is any OEM text specified
hinst = GetResourceInstance( ); assert(hinst); hwtext = GetDlgItem( hwnd, IDC_JOYCALMSG );
if( pcfg->dwUsageSettings & JOY_US_ISOEM ) { LPJOYDATA pjd; pjd = pgv->pjd; assert(pjd); type = pcfg->dwType - JOY_HW_LASTENTRY; if( pjd->oemList[type].cal_strs[ stridx ][0] != 0 ) { SetWindowText( hwtext, pjd->oemList[type].cal_strs[ stridx] ); return(rc); } }
// no OEM text, use the defaults
LoadString( hinst, strid, str, sizeof(str));
if( lstrlen(str) ) { if( str2id != -1 ) { NewLoadString( hinst, str2id, str2, sizeof( str2 ) );
if( str2 ) { if( str3id != -1 ) { NewLoadString( hinst, str3id, str3, sizeof( str3 ) );
if( lstrlen(str3) ) { if( str4id != -1 ) { NewLoadString( hinst, str4id, str4, sizeof( str4 ) );
if( lstrlen(str4) ) { // wsprintf( buff, str, str2, str3, str4 );
assert(str2); assert(str3); assert(str4); LPSTR lpargs[] = {str2, str3, str4};
FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, (LPSTR) str, 0, 0, buff, sizeof(buff), lpargs);
SetWindowText( hwtext, buff ); } } else { wsprintf( buff, str, str2, str3 ); SetWindowText( hwtext, buff ); } } } else { wsprintf( buff, str, str2, str2 ); SetWindowText( hwtext, buff ); } } } else { SetWindowText( hwtext, str ); } }
return(rc);
} /* joyCalStateChange */
/*
* joyCalStateSkip - skip the current state, move to the next one */ static void joyCalStateSkip( LPCALVARS pcv, HWND hwnd ) {
assert(pcv); assert(hwnd);
#if 0
/*
* if we're calibrating XY, skip to Z */ if( pcv->cState <= JCS_XY_CENTER2 ) { pcv->cState = JCS_XY_CENTER2; /*
* if we're calibrating Z, skip to R */ } else if( pcv->cState < JCS_Z_PLACEHOLDER ) { pcv->cState = JCS_Z_PLACEHOLDER; /*
* if we're calibrating R, skip to U */ } else if( pcv->cState < JCS_R_PLACEHOLDER ) { pcv->cState = JCS_R_PLACEHOLDER; /*
* if we're calibrating U, skip to V */ } else if( pcv->cState < JCS_U_PLACEHOLDER ) { pcv->cState = JCS_U_PLACEHOLDER; /*
* if we're calibrating V, skip to POV */ } else if( pcv->cState < JCS_V_PLACEHOLDER ) { pcv->cState = JCS_V_PLACEHOLDER; /*
* we must be calibration POV, skip to the end */ } else { pcv->cState = JCS_POV_MOVELEFT; } #endif
/*
* state changed, reset to the new one */ CauseRedraw( &pcv->ji, FALSE ); joyCalStateChange( pcv, hwnd, TRUE );
} /* joyCalStateSkip */
/*
* resetCustomPOVFlags - set POV flags based on original values for custom joystick */ static void resetCustomPOVFlags( LPGLOBALVARS pgv, LPJOYREGHWCONFIG pcfg ) { assert(pgv); assert(pcfg);
if( pcfg->dwType == JOY_HW_CUSTOM ) { pcfg->hws.dwFlags &= ~(JOY_HWS_POVISPOLL|JOY_HWS_POVISBUTTONCOMBOS);
if( pgv->bOrigPOVIsPoll ) pcfg->hws.dwFlags |= JOY_HWS_POVISPOLL;
if( pgv->bOrigPOVIsButtonCombos ) pcfg->hws.dwFlags |= JOY_HWS_POVISBUTTONCOMBOS; }
} /* resetCustomPOVFlags */
/*
* joyCalStateBack - move back to start the previous state */ static void joyCalStateBack( LPCALVARS pcv, HWND hwnd ) { assert(pcv); assert(hwnd);
BOOL back; LPJOYREGHWCONFIG pcfg; LPGLOBALVARS pgv;
pgv = pcv->pgv; assert(pgv); back = TRUE; pcfg = &pgv->joyHWCurr; assert(pcfg); /*
* at the end, backup */ if( pcv->cState == JCS_FINI ) { // ADDED BY CML 6/21/96 TO FIX LOST FOCUS BUG (FLASH RAID 167)
SetFocus(GetDlgItem(hwnd, IDC_JOYCALBACK)); // END ADD
/*
* if there is POV, back up to it */ if( pcfg->hws.dwFlags & JOY_HWS_HASPOV ) { pcv->cState = JCS_V_PLACEHOLDER; resetCustomPOVFlags( pgv, pcfg ); /*
* if there is V, back up to it */ } else if( pcfg->hws.dwFlags & JOY_HWS_HASV ) { pcv->cState = JCS_U_PLACEHOLDER; /*
* if there is U, back up to it */ } else if( pcfg->hws.dwFlags & JOY_HWS_HASU ) { pcv->cState = JCS_R_PLACEHOLDER; /*
* if there is R, back up to it */ } else if( (pcfg->hws.dwFlags & JOY_HWS_HASR) || (pcfg->dwUsageSettings & JOY_US_HASRUDDER) ) { pcv->cState = JCS_Z_PLACEHOLDER; /*
* if there is Z, back up to it */ } else if( pcfg->hws.dwFlags & JOY_HWS_HASZ ) { pcv->cState = JCS_XY_CENTER2; /*
* no where else to go, back up to XY */ } else { // ADDED BY CML 6/21/96 TO FIX LOST FOCUS BUG (FLASH RAID 167)
SetFocus(GetDlgItem(hwnd, IDC_JOYCALNEXT)); // END ADD
// pcv->cState = JCS_INIT;
pcv->cState = JCS_XY_MOVE; // back = FALSE;
} /*
* doing POV, so restart it */ } else if( pcv->cState > JCS_POV_MOVEUP ) { pcv->cState = JCS_V_PLACEHOLDER; // pcfg->hws.dwFlags &= ~(JOY_HWS_POVISPOLL|JOY_HWS_POVISBUTTONCOMBOS);
resetCustomPOVFlags( pgv, pcfg ); /*
* just starting POV, back up */ } else if( pcv->cState == JCS_POV_MOVEUP ) {
// ADDED BY CML 6/21/96 TO FIX LOST FOCUS BUG (FLASH RAID 167)
SetFocus(GetDlgItem(hwnd, IDC_JOYCALBACK)); // END ADD
/*
* if there is V, back up to it */ if( pcfg->hws.dwFlags & JOY_HWS_HASV ) { pcv->cState = JCS_U_PLACEHOLDER; /*
* if there is U, back up to it */ } else if( pcfg->hws.dwFlags & JOY_HWS_HASU ) { pcv->cState = JCS_R_PLACEHOLDER; /*
* if there is R, back up to it */ } else if( (pcfg->hws.dwFlags & JOY_HWS_HASR) || (pcfg->dwUsageSettings & JOY_US_HASRUDDER) ) { pcv->cState = JCS_Z_PLACEHOLDER; /*
* if there is Z, back up to it */ } else if( pcfg->hws.dwFlags & JOY_HWS_HASZ ) { pcv->cState = JCS_XY_CENTER2; /*
* no where else to go, back up to XY */ } else { // ADDED BY CML 6/21/96 TO FIX LOST FOCUS BUG (FLASH RAID 167)
SetFocus(GetDlgItem(hwnd, IDC_JOYCALNEXT)); // END ADD
// pcv->cState = JCS_INIT;
pcv->cState = JCS_XY_MOVE; // back = FALSE;
} /*
* doing V, backup */ } else if( pcv->cState == JCS_V_MOVE ) { /*
* if there is U, back up to it */ if( pcfg->hws.dwFlags & JOY_HWS_HASU ) { pcv->cState = JCS_R_PLACEHOLDER; /*
* if there is R, back up to it */ } else if( (pcfg->hws.dwFlags & JOY_HWS_HASR) || (pcfg->dwUsageSettings & JOY_US_HASRUDDER) ) { pcv->cState = JCS_Z_PLACEHOLDER; /*
* if there is Z, back up to it */ } else if( pcfg->hws.dwFlags & JOY_HWS_HASZ ) { pcv->cState = JCS_XY_CENTER2; /*
* no where else to go, back up to XY */ } else { // ADDED BY CML 6/21/96 TO FIX LOST FOCUS BUG (FLASH RAID 167)
SetFocus(GetDlgItem(hwnd, IDC_JOYCALNEXT)); // END ADD
// pcv->cState = JCS_INIT;
pcv->cState = JCS_XY_MOVE; // back = FALSE;
} /*
* doing U, backup */ } else if( pcv->cState == JCS_U_MOVE ) { /*
* if there is R, back up to it */ if( (pcfg->hws.dwFlags & JOY_HWS_HASR) || (pcfg->dwUsageSettings & JOY_US_HASRUDDER) ) { pcv->cState = JCS_Z_PLACEHOLDER; /*
* if there is Z, back up to it */ } else if( pcfg->hws.dwFlags & JOY_HWS_HASZ ) { pcv->cState = JCS_XY_CENTER2; /*
* no where else to go, back up to XY */ } else { // pcv->cState = JCS_INIT;
pcv->cState = JCS_XY_MOVE; // back = FALSE;
} /*
* doing R, backup */ } else if( pcv->cState == JCS_R_MOVE ) { /*
* if there is Z, back up to it */ if( pcfg->hws.dwFlags & JOY_HWS_HASZ ) { pcv->cState = JCS_XY_CENTER2; /*
* no where else to go, back up to XY */ } else { // ADDED BY CML 6/21/96 TO FIX LOST FOCUS BUG (FLASH RAID 167)
SetFocus(GetDlgItem(hwnd, IDC_JOYCALNEXT)); // END ADD
// pcv->cState = JCS_INIT;
pcv->cState = JCS_XY_MOVE; // back = FALSE;
} /*
* if we're doing Z or in the middle of XY, backup to XY */ } else if( pcv->cState == JCS_XY_MOVE ) { SetFocus(GetDlgItem(hwnd, IDC_JOYCALNEXT)); pcv->cState = JCS_INIT; back = FALSE; } else { // ADDED BY CML 6/21/96 TO FIX LOST FOCUS BUG (FLASH RAID 167)
SetFocus(GetDlgItem(hwnd, IDC_JOYCALNEXT)); // END ADD
pcv->cState = (cal_states)(pcv->cState - 2); // pcv->cState = JCS_INIT;
// back = FALSE;
}
/*
* state changed, reset to the new one */ CauseRedraw( &pcv->ji, FALSE ); joyCalStateChange( pcv, hwnd, back );
} /* joyCalStateBack */
// macro to get new max/min data for an axis
#define NEWMINMAX( a ) \
if( pji->dw##a##pos > pcv->jr.jpMax.dw##a ) { \ pcv->jr.jpMax.dw##a = pji->dw##a##pos; \ } \ if( pji->dw##a##pos < pcv->jr.jpMin.dw##a ) { \ pcv->jr.jpMin.dw##a = pji->dw##a##pos; \ } \ pji->dw##a##pos *= RAW_SHIFT;
// joyCollectCalInfo - record calibration info
static BOOL joyCollectCalInfo( LPCALVARS pcv, HWND hwnd, LPJOYINFOEX pji ) { assert(pcv); assert(hwnd); assert(pji);
LPGLOBALVARS pgv; LPJOYREGHWCONFIG pcfg;
pgv = pcv->pgv; assert(pgv); switch( pcv->cState ) { // remember XY center
case JCS_XY_CENTER1: case JCS_XY_CENTER2: #ifdef _DEBUG
TRACE("%s: %d: dwXpos is %d dwYpos is %d\n", __FILE__, __LINE__, pji->dwXpos, pji->dwYpos); #endif // _DEBUG
if( !pcv->jr.jpCenter.dwY ) { pgv->joyRange.jpMax.dwY = pji->dwYpos << 1; pcv->jr.jpCenter.dwY = pji->dwYpos; }
if( !pcv->jr.jpCenter.dwX ) { pgv->joyRange.jpMax.dwX = pji->dwXpos << 1; pcv->jr.jpCenter.dwX = pji->dwXpos; }
pgv->joyRange.jpMin.dwX = 0; pgv->joyRange.jpMin.dwY = 0;
DoJoyMove( pgv, hwnd, pji, &pcv->ji, JOYMOVE_DRAWXY ); break;
// remember max/min XY values
case JCS_XY_MOVE: if( pji->dwXpos > pcv->jr.jpMax.dwX ) { pcv->jr.jpMax.dwX = pji->dwXpos; }
if( pji->dwXpos < pcv->jr.jpMin.dwX ) { pcv->jr.jpMin.dwX = pji->dwXpos; }
if( pji->dwYpos > pcv->jr.jpMax.dwY ) { pcv->jr.jpMax.dwY = pji->dwYpos; }
if( pji->dwYpos < pcv->jr.jpMin.dwY ) { pcv->jr.jpMin.dwY = pji->dwYpos; }
DoJoyMove( pgv, hwnd, pji, &pcv->ji, JOYMOVE_DRAWXY ); break;
// remember max/min Z value
case JCS_Z_MOVE: NEWMINMAX( Z ); DoJoyMove( pgv, hwnd, pji, &pcv->ji, JOYMOVE_DRAWZ ); break;
// remember max/min R value
case JCS_R_MOVE: NEWMINMAX( R ); DoJoyMove( pgv, hwnd, pji, &pcv->ji, JOYMOVE_DRAWR ); break;
// remember max/min U value
case JCS_U_MOVE: NEWMINMAX( U ); DoJoyMove( pgv, hwnd, pji, &pcv->ji, JOYMOVE_DRAWU ); break;
// remember max/min V value
case JCS_V_MOVE: NEWMINMAX( V ); DoJoyMove( pgv, hwnd, pji, &pcv->ji, JOYMOVE_DRAWV ); break; }
// if a button was pressed, move to the next state
if( ((pcv->ji.dwButtons & ALL_BUTTONS) != (pji->dwButtons & ALL_BUTTONS)) && ((pji->dwButtons & JOY_BUTTON1) || (pji->dwButtons & JOY_BUTTON2) || (pji->dwButtons & JOY_BUTTON3) || (pji->dwButtons & JOY_BUTTON4) || (pji->dwButtons & JOY_BUTTON5) || (pji->dwButtons & JOY_BUTTON6) || (pji->dwButtons & JOY_BUTTON7) || (pji->dwButtons & JOY_BUTTON8) || (pji->dwButtons & JOY_BUTTON9) || (pji->dwButtons & JOY_BUTTON10) || (pji->dwButtons & JOY_BUTTON11) || (pji->dwButtons & JOY_BUTTON12) || (pji->dwButtons & JOY_BUTTON13) || (pji->dwButtons & JOY_BUTTON14) || (pji->dwButtons & JOY_BUTTON15) || (pji->dwButtons & JOY_BUTTON16) || (pji->dwButtons & JOY_BUTTON17) || (pji->dwButtons & JOY_BUTTON18) || (pji->dwButtons & JOY_BUTTON19) || (pji->dwButtons & JOY_BUTTON20) || (pji->dwButtons & JOY_BUTTON21) || (pji->dwButtons & JOY_BUTTON22) || (pji->dwButtons & JOY_BUTTON23) || (pji->dwButtons & JOY_BUTTON24) || (pji->dwButtons & JOY_BUTTON25) || (pji->dwButtons & JOY_BUTTON26) || (pji->dwButtons & JOY_BUTTON27) || (pji->dwButtons & JOY_BUTTON28) || (pji->dwButtons & JOY_BUTTON29) || (pji->dwButtons & JOY_BUTTON30) || (pji->dwButtons & JOY_BUTTON31) || (pji->dwButtons & JOY_BUTTON32) ) ) { // check and see if we are leaving one calibration to the next;
// if yes, take time to stop and remember what the user just did
pcfg = &pgv->joyHWCurr; assert(pcfg);
switch( pcv->cState ) { case JCS_XY_CENTER1: pcv->jr.jpCenter.dwX = pji->dwXpos; pcv->jr.jpCenter.dwY = pji->dwYpos; DPF( "Center 1: %d,%d\r\n", pji->dwXpos, pji->dwYpos ); break;
case JCS_XY_CENTER2: DPF( "Center 2: %d,%d\r\n", pji->dwXpos, pji->dwYpos ); pcv->jr.jpCenter.dwX += pji->dwXpos; pcv->jr.jpCenter.dwY += pji->dwYpos; pcv->jr.jpCenter.dwX /= 2; pcv->jr.jpCenter.dwY /= 2; DPF( "Center Avg: %d,%d\r\n", pcv->jr.jpCenter.dwX, pcv->jr.jpCenter.dwY ); pcfg->hwv.jrvHardware.jpMin.dwX = pcv->jr.jpMin.dwX; pcfg->hwv.jrvHardware.jpMin.dwY = pcv->jr.jpMin.dwY; pcfg->hwv.jrvHardware.jpMax.dwX = pcv->jr.jpMax.dwX; pcfg->hwv.jrvHardware.jpMax.dwY = pcv->jr.jpMax.dwY; pcfg->hwv.jrvHardware.jpCenter.dwX = pcv->jr.jpCenter.dwX; pcfg->hwv.jrvHardware.jpCenter.dwY = pcv->jr.jpCenter.dwY; pcfg->hwv.dwCalFlags |= JOY_ISCAL_XY; break; case JCS_Z_MOVE: pcfg->hwv.jrvHardware.jpMin.dwZ = pcv->jr.jpMin.dwZ; pcfg->hwv.jrvHardware.jpMax.dwZ = pcv->jr.jpMax.dwZ; pcfg->hwv.dwCalFlags |= JOY_ISCAL_Z; break; case JCS_R_MOVE: pcfg->hwv.jrvHardware.jpMin.dwR = pcv->jr.jpMin.dwR; pcfg->hwv.jrvHardware.jpMax.dwR = pcv->jr.jpMax.dwR; pcfg->hwv.dwCalFlags |= JOY_ISCAL_R; break; case JCS_U_MOVE: pcfg->hwv.jrvHardware.jpMin.dwU = pcv->jr.jpMin.dwU; pcfg->hwv.jrvHardware.jpMax.dwU = pcv->jr.jpMax.dwU; pcfg->hwv.dwCalFlags |= JOY_ISCAL_U; break; case JCS_V_MOVE: pcfg->hwv.jrvHardware.jpMin.dwV = pcv->jr.jpMin.dwV; pcfg->hwv.jrvHardware.jpMax.dwV = pcv->jr.jpMax.dwV; pcfg->hwv.dwCalFlags |= JOY_ISCAL_V; break; }
pcv->ji.dwButtons = pji->dwButtons; return(joyCalStateChange( pcv, hwnd, TRUE )); } pcv->ji.dwButtons = pji->dwButtons; return(TRUE);
} /* joyCollectCalInfo */
/*
* joyCalibrateInitDialog - init the calibration dialog */ static BOOL joyCalibrateInitDialog( HWND hwnd, LPARAM lParam ) { LPJOYREGHWCONFIG pcfg; LPCALVARS pcv = NULL; LPGLOBALVARS pgv = NULL;
ASSERT (::IsWindow(hwnd));
// set up calibration variables
pcv = (CALVARS *) DoAlloc( sizeof( CALVARS ) ); ASSERT(pcv);
if( pcv == NULL ) return(FALSE);
SetWindowLong( hwnd, DWL_USER, (LONG) pcv ); assert(pcv);
pgv = (LPGLOBALVARS) lParam; assert(pgv);
pcv->pgv = pgv;
//
// set labels
//
LPSTR psz1 = new char[MAX_STR_LEN]; ASSERT (psz1);
LPSTR psz2 = new char[MAX_STR_LEN]; ASSERT (psz2);
if( !LoadString(GetResourceInstance(), IDS_JOYCALCAPN, psz1, MAX_STR_LEN) ) { TRACE( "%s: %s - LoadString Failure!\n", __FILE__, __LINE__); }
wsprintf(psz2, psz1, pgv->iJoyId+1); SetWindowText(hwnd, psz2);
if( psz1 ) delete[] (psz1);
if( psz2 ) delete[] (psz2);
// init state info
pcv->cState = JCS_INIT;
// set dialog text based on OEM strings
SetOEMText( pgv, hwnd, FALSE );
// customize dialog based on Z axis, R axis, and POV hat
pcfg = &pgv->joyHWCurr; assert(pcfg);
pcv->iAxisCount = 2;
if( pcfg->hws.dwFlags & JOY_HWS_HASZ ) pcv->iAxisCount++;
if( (pcfg->hws.dwFlags & JOY_HWS_HASR) || (pcfg->dwUsageSettings & JOY_US_HASRUDDER) ) pcv->iAxisCount++;
if( (pcfg->hws.dwFlags & JOY_HWS_HASPOV) && (pcfg->hws.dwFlags & JOY_HWS_POVISPOLL) ) pcv->iAxisCount++;
if( pcfg->hws.dwFlags & JOY_HWS_HASU ) pcv->iAxisCount++;
if( pcfg->hws.dwFlags & JOY_HWS_HASV ) pcv->iAxisCount++;
ShowControls( pcfg, hwnd );
HWND hCtrl = GetDlgItem( hwnd, IDC_JOYPOV_LABEL ); ASSERT (::IsWindow(hCtrl)); ShowWindow(hCtrl, pcfg->hws.dwFlags & JOY_HWS_HASPOV ? SW_SHOW : SW_HIDE);
// if all axes are used and we have POV then it MUST be buttons
if( pcfg->hws.dwFlags & JOY_HWS_HASPOV ) { if( pgv->dwMaxAxes == 4 && pcv->iAxisCount == 4 ) pcfg->hws.dwFlags |= JOY_HWS_POVISBUTTONCOMBOS; }
// other misc setup
pcv->bPOVdone = FALSE; pcv->bHasTimer = SetTimer( hwnd, TIMER_ID, JOYPOLLTIME, NULL ); pcv->bUseTimer = TRUE;
if( !pcv->bHasTimer ) { DPF( "No timer for joystick calibration!\r\n" ); return(FALSE); }
if( !joyCalStateChange( pcv, hwnd, FALSE ) ) { DPF( "Could not initialize joystick calibration\r\n" ); return(FALSE); }
return(TRUE);
} /* joyCalibrateInitDialog */
/*
* setJIFlagsForPOV - get joyinfo flags to allow a raw POV poll */ static void setJIFlagsForPOV( LPCALVARS pcv, LPJOYREGHWCONFIG pcfg, DWORD *pflags ) { /*
* for polled POV, we need to specifiy JOY_CAL_READ(3|4) to make * the driver give us position values back instead of trying to * give us a POV value back */ // if( pcfg->hws.dwFlags & JOY_HWS_HASPOV )
{ if( pcfg->hws.dwFlags & JOY_HWS_POVISPOLL ) { switch( pcv->iAxisCount ) { case 6: (*pflags) |= JOY_CAL_READ6; break; case 5: (*pflags) |= JOY_CAL_READ5; break;
case 4: (*pflags) |= JOY_CAL_READ4; break;
case 3: (*pflags) |= JOY_CAL_READ3; break; } // If we don't have a 3rd or 4th axis on this joystick, try reading
// another axis anyway to see if the POV hat is on it
} else if( !(pcfg->hws.dwFlags & (JOY_HWS_POVISPOLL|JOY_HWS_POVISBUTTONCOMBOS)) ) { switch( pcv->iAxisCount ) { case 5: (*pflags) |= JOY_CAL_READ6; break;
case 4: (*pflags) |= JOY_CAL_READ5; break;
case 3: (*pflags) |= JOY_CAL_READ4; break;
case 2: (*pflags) |= JOY_CAL_READ3; break; } } }
} /* setJIFlagsForPOV */
// tryPOV - try for a POV access
static BOOL tryPOV( LPCALVARS pcv, HWND hwnd ) { assert(pcv); assert(hwnd);
int rc; BOOL ispoll; BOOL isb; BOOL nowaypoll; JOYINFOEX ji; DWORD val; LPJOYREGHWCONFIG pcfg; LPGLOBALVARS pgv; int i;
pgv = pcv->pgv; assert(pgv);
// reject call if not in a POV state
if( !(pcv->cState == JCS_POV_MOVEUP || pcv->cState == JCS_POV_MOVEDOWN || pcv->cState == JCS_POV_MOVELEFT || pcv->cState == JCS_POV_MOVERIGHT) ) return(FALSE);
// take a snapshot of the current joystick state
pcfg = &pgv->joyHWCurr; assert(pcfg); nowaypoll = FALSE; ji.dwSize = sizeof( ji ); while( 1 ) { // get joystick info
ji.dwFlags = JOY_CALIB_FLAGS;
// if you have a POV, set the flags for it!
if( pcfg->hws.dwFlags & JOY_HWS_HASPOV ) setJIFlagsForPOV( pcv, pcfg, &ji.dwFlags );
rc = joyGetPosEx( pgv->iJoyId, &ji ); if( rc == JOYERR_NOERROR ) break;
if( !(pcfg->hws.dwFlags & JOY_HWS_POVISPOLL) && (ji.dwFlags & (JOY_CAL_READ3|JOY_CAL_READ4|JOY_CAL_READ5|JOY_CAL_READ6)) ) { // try again, but don't ask for extra axis
ji.dwFlags &= ~(JOY_CAL_READ6 | JOY_CAL_READ5 | JOY_CAL_READ4 | JOY_CAL_READ3); rc = joyGetPosEx( pgv->iJoyId, &ji ); if( rc == JOYERR_NOERROR ) { nowaypoll = TRUE; // pov can't possibly be polled
break; } else return(JoyError( hwnd )) ? TRUE : FALSE; // have to wait for next "Select POV" to retry
} else return(JoyError( hwnd )) ? TRUE : FALSE; // have to wait for next "Select POV" to retry
}
/*
* here is where we determine if POV is polled or is button combos. * * See if we already know the answer (bits in joyHWCurr): * if yes: * we're done. * if no: * We see if there are currently multiple buttons down. * if yes: * POV is assumed to be button combos. * if no: * POV is assumed to be done with polling */ ispoll = FALSE; isb = FALSE; if( pcfg->hws.dwFlags & JOY_HWS_POVISPOLL ) { ispoll = TRUE; } else if( pcfg->hws.dwFlags & JOY_HWS_POVISBUTTONCOMBOS ) { isb = TRUE; }
if( !isb && !ispoll ) { // the type is indeterminate, so we identify it
if( nowaypoll ||((ji.dwButtons != 0) && (ji.dwButtons != JOY_BUTTON1) && (ji.dwButtons != JOY_BUTTON2) && (ji.dwButtons != JOY_BUTTON3) && (ji.dwButtons != JOY_BUTTON4) && (ji.dwButtons != JOY_BUTTON5) && (ji.dwButtons != JOY_BUTTON6) && (ji.dwButtons != JOY_BUTTON7) && (ji.dwButtons != JOY_BUTTON8) && (ji.dwButtons != JOY_BUTTON9) && (ji.dwButtons != JOY_BUTTON10) && (ji.dwButtons != JOY_BUTTON11) && (ji.dwButtons != JOY_BUTTON12) && (ji.dwButtons != JOY_BUTTON13) && (ji.dwButtons != JOY_BUTTON14) && (ji.dwButtons != JOY_BUTTON15) && (ji.dwButtons != JOY_BUTTON16) && (ji.dwButtons != JOY_BUTTON17) && (ji.dwButtons != JOY_BUTTON18) && (ji.dwButtons != JOY_BUTTON19) && (ji.dwButtons != JOY_BUTTON20) && (ji.dwButtons != JOY_BUTTON21) && (ji.dwButtons != JOY_BUTTON22) && (ji.dwButtons != JOY_BUTTON23) && (ji.dwButtons != JOY_BUTTON24) && (ji.dwButtons != JOY_BUTTON25) && (ji.dwButtons != JOY_BUTTON26) && (ji.dwButtons != JOY_BUTTON27) && (ji.dwButtons != JOY_BUTTON28) && (ji.dwButtons != JOY_BUTTON29) && (ji.dwButtons != JOY_BUTTON30) && (ji.dwButtons != JOY_BUTTON31) && (ji.dwButtons != JOY_BUTTON32) ) ) { isb = TRUE; pcfg->hws.dwFlags |= JOY_HWS_POVISBUTTONCOMBOS; } else { // we always assume J2 Y for a polling POV if unspecified
ispoll = TRUE; pcfg->hws.dwFlags |= JOY_HWS_POVISPOLL; }
// the driver needs to notified that we've made this decision
RegSaveCurrentJoyHW( pgv ); RegistryUpdated( pgv ); }
// record the data value for this POV reading
if( isb ) val = ji.dwButtons; else val = (pcfg->hws.dwFlags & JOY_HWS_HASZ) ? ji.dwRpos : ji.dwZpos;
switch( pcv->cState ) { case JCS_POV_MOVEUP: pcv->pov[JOY_POVVAL_FORWARD] = val; break;
case JCS_POV_MOVERIGHT: pcv->pov[JOY_POVVAL_RIGHT] = val; break;
case JCS_POV_MOVEDOWN: pcv->pov[JOY_POVVAL_BACKWARD] = val; break;
case JCS_POV_MOVELEFT: pcv->pov[JOY_POVVAL_LEFT] = val;
// since this was the last POV thing to calibrate, we need to save the calibration info
for( i=0;i<JOY_POV_NUMDIRS;i++ ) pcfg->hwv.dwPOVValues[i] = pcv->pov[i];
pcfg->hwv.dwCalFlags |= JOY_ISCAL_POV; pcv->bPOVdone = TRUE; break; } return(joyCalStateChange( pcv, hwnd, TRUE ));
} /* tryPOV */
#ifdef DEAD_CODE
// FixCustomPOVType - fix custom POV type info if POV wasn't calibrated; called by test dlg to update config
void FixCustomPOVType( LPCALVARS pcv ) { assert(pcv);
if( !pcv->bPOVdone ) resetCustomPOVFlags( pcv->pgv, &pcv->pgv->joyHWCurr );
} /* FixCustomPOVType */ #endif // DEAD_CODE
// CalibrateProc - calibrate a joystick
BOOL CALLBACK CalibrateProc( HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam) { switch( umsg ) { case WM_CONTEXTMENU: OnContextMenu(wParam); return(1);
case WM_HELP: OnHelp(lParam); return(1);
case WM_TIMER: { LPCALVARS pcv = (LPCALVARS) GetWindowLong( hwnd, DWL_USER ); assert(pcv);
if( pcv->bUseTimer ) { JOYINFOEX *ji = new JOYINFOEX; ASSERT (ji);
MMRESULT rc; LPJOYREGHWCONFIG pcfg; LPGLOBALVARS pgv;
pgv = pcv->pgv; assert(pgv);
pcv->bUseTimer = FALSE; ji->dwSize = sizeof( JOYINFOEX );
while( 1 ) { // get current joystick info
ji->dwFlags = JOY_CALIB_FLAGS; pcfg = &pgv->joyHWCurr; ASSERT(pcfg);
// if there is a POV, set the flags for it!
if( pcfg->hws.dwFlags & JOY_HWS_HASPOV ) setJIFlagsForPOV( pcv, pcfg, &ji->dwFlags );
rc = joyGetPosEx( pgv->iJoyId, ji );
if( rc == JOYERR_NOERROR ) break;
// didn't work, try without extra POV axis
if( !(pcfg->hws.dwFlags & JOY_HWS_POVISPOLL) && (ji->dwFlags & (JOY_CAL_READ3|JOY_CAL_READ4|JOY_CAL_READ5|JOY_CAL_READ6)) ) { ji->dwFlags &= ~(JOY_CAL_READ6 | JOY_CAL_READ5 | JOY_CAL_READ4 | JOY_CAL_READ3);
rc = joyGetPosEx( pgv->iJoyId, ji );
if( rc == JOYERR_NOERROR ) break; }
if( !JoyError( hwnd ) ) { // return now if cancel selected; don't turn back on the timer
PostMessage(hwnd, WM_COMMAND, IDCANCEL, 0); // ADDED CML 7/05/96
return(FALSE); } continue; }
// how could you get here and rc != JOYERR_NOERROR?
if( rc == JOYERR_NOERROR ) joyCollectCalInfo( pcv, hwnd, ji );
if( ji ) delete (ji);
/*
* If we've started POV calibration, we need to look at the * keyboard and ignore joystick, so don't turn the timer * back on if we've started the POV calibration */ if( pcv->cState < JCS_POV_MOVEUP ) pcv->bUseTimer = TRUE; } break; }
case WM_DESTROY: { LPCALVARS pcv = (LPCALVARS) GetWindowLong( hwnd, DWL_USER ); assert(pcv); DoFree( pcv ); break; }
case WM_INITDIALOG: if( !joyCalibrateInitDialog( hwnd, lParam ) ) { LPCALVARS pcv = (LPCALVARS) GetWindowLong( hwnd, DWL_USER ); assert(pcv);
if( pcv != NULL && pcv->bHasTimer ) { KillTimer( hwnd, TIMER_ID ); pcv->bHasTimer = FALSE; }
EndDialog( hwnd, 0 ); } return(FALSE);
case WM_PAINT: { LPCALVARS pcv = (LPCALVARS) GetWindowLong( hwnd, DWL_USER ); assert(pcv); CauseRedraw( &pcv->ji, FALSE ); return(FALSE); }
case WM_COMMAND: { LPCALVARS pcv = (LPCALVARS) GetWindowLong( hwnd, DWL_USER ); assert(pcv); int id = GET_WM_COMMAND_ID(wParam, lParam);
switch( id ) { #ifdef DEAD_CODE
case IDC_JOYTEST: { BOOL timeon;
timeon = pcv->bUseTimer; pcv->bUseTimer = FALSE; DoTest( pcv->pgv, hwnd, (void (__cdecl *)(void *)) FixCustomPOVType, pcv ); pcv->bUseTimer = timeon; break; } #endif //DEAD_CODE
case IDCANCEL: // fall through
case IDC_JOYCALDONE: if( pcv->bHasTimer ) { KillTimer( hwnd, TIMER_ID ); pcv->bHasTimer = FALSE; }
// {
// LPJOYREGHWCONFIG pcfg = &pcv->pgv->joyHWCurr;
// assert(pcfg);
// }
EndDialog( hwnd, (id == IDC_JOYCALDONE) ); break;
case IDC_JOYPICKPOV: if( !tryPOV( pcv, hwnd ) ) { ASSERT (::IsWindow(hwnd)); HWND hwb = GetDlgItem( hwnd, IDC_JOYPICKPOV ); ASSERT (::IsWindow(hwb));
ShowWindow( hwb, SW_HIDE ); EnableWindow( hwb, FALSE ); } break;
case IDC_JOYCALNEXT: pcv->bUseTimer = TRUE; joyCalStateSkip( pcv, hwnd ); break;
case IDC_JOYCALBACK: pcv->bUseTimer = TRUE; joyCalStateBack( pcv, hwnd ); break;
default: break; } break; }
default: break; } return(FALSE);
} // CalibrateProc
// DoCalibrate - do the calibration dialog
void DoCalibrate( LPGLOBALVARS pgv, HWND hwnd ) { assert(pgv);
JOYREGHWCONFIG save_joycfg; int rc; int id;
// save the current config, and then add the rudder if it is present
save_joycfg = pgv->joyHWCurr;
// if this is a custom joystick, then don't assume anything
// about how the POV is set up
if( pgv->joyHWCurr.dwType == JOY_HW_CUSTOM ) { pgv->bOrigPOVIsPoll = (pgv->joyHWCurr.hws.dwFlags & JOY_HWS_POVISPOLL); pgv->bOrigPOVIsButtonCombos = (pgv->joyHWCurr.hws.dwFlags & JOY_HWS_POVISBUTTONCOMBOS); pgv->joyHWCurr.hws.dwFlags &= ~(JOY_HWS_POVISPOLL|JOY_HWS_POVISBUTTONCOMBOS); }
// update the registry with our new joystick info
RegSaveCurrentJoyHW( pgv ); RegistryUpdated( pgv );
// Fix for 8738, missing IDD_JOYCALIBRATE1 in resource table!
id = ( pgv->joyHWCurr.hws.dwFlags & (JOY_HWS_HASU|JOY_HWS_HASV)) ? IDD_JOYCALIBRATE1 : IDD_CAL;
rc = DialogBoxParam(GetResourceInstance(), MAKEINTRESOURCE( id ), hwnd, (int (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long)) CalibrateProc, (LONG) pgv );
// update the registry with the new info or the old info
if( rc ) PropSheet_Changed( GetParent(hwnd), hwnd ); else pgv->joyHWCurr = save_joycfg;
RegSaveCurrentJoyHW( pgv ); RegistryUpdated( pgv );
} /* DoCalibrate */
////////////////////////////////////////////////////////////////////////////////////////
// OnContextMenu(WPARAM wParam)
////////////////////////////////////////////////////////////////////////////////////////
void OnContextMenu(WPARAM wParam) { short nSize = STR_LEN_32;
// point to help file
char *pszHelpFileName = new char[nSize]; ASSERT (pszHelpFileName);
// returns help file name and size of string
GetHelpFileName(pszHelpFileName, &nSize);
WinHelp((HWND)wParam, pszHelpFileName, HELP_CONTEXTMENU, (DWORD)CalibrateHelpIDs);
if( pszHelpFileName ) delete[] (pszHelpFileName); }
////////////////////////////////////////////////////////////////////////////////////////
// OnHelp(LPARAM lParam)
////////////////////////////////////////////////////////////////////////////////////////
void OnHelp(LPARAM lParam) { short nSize = STR_LEN_32;
// point to help file
char *pszHelpFileName = new char[nSize]; ASSERT (pszHelpFileName);
// returns help file name and size of string
GetHelpFileName(pszHelpFileName, &nSize);
LPHELPINFO lphi = (LPHELPINFO)lParam; if( lphi->iContextType==HELPINFO_WINDOW ) WinHelp((HWND)lphi->hItemHandle, pszHelpFileName, HELP_WM_HELP, (DWORD)CalibrateHelpIDs);
if( pszHelpFileName ) delete[] (pszHelpFileName); }
|