00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "../client/client.h"
00026 #include "win_local.h"
00027
00028
00029 typedef struct {
00030 int oldButtonState;
00031
00032 qboolean mouseActive;
00033 qboolean mouseInitialized;
00034 qboolean mouseStartupDelayed;
00035 } WinMouseVars_t;
00036
00037 static WinMouseVars_t s_wmv;
00038
00039 static int window_center_x, window_center_y;
00040
00041
00042
00043
00044 static void IN_StartupMIDI( void );
00045 static void IN_ShutdownMIDI( void );
00046
00047 #define MAX_MIDIIN_DEVICES 8
00048
00049 typedef struct {
00050 int numDevices;
00051 MIDIINCAPS caps[MAX_MIDIIN_DEVICES];
00052
00053 HMIDIIN hMidiIn;
00054 } MidiInfo_t;
00055
00056 static MidiInfo_t s_midiInfo;
00057
00058
00059
00060
00061 #define JOY_MAX_AXES 6 // X, Y, Z, R, U, V
00062
00063 typedef struct {
00064 qboolean avail;
00065 int id;
00066 JOYCAPS jc;
00067
00068 int oldbuttonstate;
00069 int oldpovstate;
00070
00071 JOYINFOEX ji;
00072 } joystickInfo_t;
00073
00074 static joystickInfo_t joy;
00075
00076
00077
00078 cvar_t *in_midi;
00079 cvar_t *in_midiport;
00080 cvar_t *in_midichannel;
00081 cvar_t *in_mididevice;
00082
00083 cvar_t *in_mouse;
00084 cvar_t *in_logitechbug;
00085 cvar_t *in_joystick;
00086 cvar_t *in_joyBallScale;
00087 cvar_t *in_debugJoystick;
00088 cvar_t *joy_threshold;
00089
00090 qboolean in_appactive;
00091
00092
00093 void IN_StartupJoystick (void);
00094 void IN_JoyMove(void);
00095
00096 static void MidiInfo_f( void );
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 void IN_InitWin32Mouse( void )
00112 {
00113 }
00114
00115
00116
00117
00118
00119
00120 void IN_ShutdownWin32Mouse( void ) {
00121 }
00122
00123
00124
00125
00126
00127
00128 void IN_ActivateWin32Mouse( void ) {
00129 int width, height;
00130 RECT window_rect;
00131
00132 width = GetSystemMetrics (SM_CXSCREEN);
00133 height = GetSystemMetrics (SM_CYSCREEN);
00134
00135 GetWindowRect ( g_wv.hWnd, &window_rect);
00136 if (window_rect.left < 0)
00137 window_rect.left = 0;
00138 if (window_rect.top < 0)
00139 window_rect.top = 0;
00140 if (window_rect.right >= width)
00141 window_rect.right = width-1;
00142 if (window_rect.bottom >= height-1)
00143 window_rect.bottom = height-1;
00144 window_center_x = (window_rect.right + window_rect.left)/2;
00145 window_center_y = (window_rect.top + window_rect.bottom)/2;
00146
00147 SetCursorPos (window_center_x, window_center_y);
00148
00149 SetCapture ( g_wv.hWnd );
00150 ClipCursor (&window_rect);
00151 while (ShowCursor (FALSE) >= 0)
00152 ;
00153 }
00154
00155
00156
00157
00158
00159
00160 void IN_DeactivateWin32Mouse( void )
00161 {
00162 ClipCursor (NULL);
00163 ReleaseCapture ();
00164 while (ShowCursor (TRUE) < 0)
00165 ;
00166 }
00167
00168
00169
00170
00171
00172
00173 void IN_Win32Mouse( int *mx, int *my ) {
00174 POINT current_pos;
00175
00176
00177 GetCursorPos (¤t_pos);
00178
00179
00180 SetCursorPos (window_center_x, window_center_y);
00181
00182 *mx = current_pos.x - window_center_x;
00183 *my = current_pos.y - window_center_y;
00184 }
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 #undef DEFINE_GUID
00196
00197 #define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
00198 EXTERN_C const GUID name \
00199 = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
00200
00201 DEFINE_GUID(GUID_SysMouse, 0x6F1D2B60,0xD5A0,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
00202 DEFINE_GUID(GUID_XAxis, 0xA36D02E0,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
00203 DEFINE_GUID(GUID_YAxis, 0xA36D02E1,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
00204 DEFINE_GUID(GUID_ZAxis, 0xA36D02E2,0xC9F3,0x11CF,0xBF,0xC7,0x44,0x45,0x53,0x54,0x00,0x00);
00205
00206
00207 #define DINPUT_BUFFERSIZE 16
00208 #define iDirectInputCreate(a,b,c,d) pDirectInputCreate(a,b,c,d)
00209
00210 HRESULT (WINAPI *pDirectInputCreate)(HINSTANCE hinst, DWORD dwVersion,
00211 LPDIRECTINPUT * lplpDirectInput, LPUNKNOWN punkOuter);
00212
00213 static HINSTANCE hInstDI;
00214
00215 typedef struct MYDATA {
00216 LONG lX;
00217 LONG lY;
00218 LONG lZ;
00219 BYTE bButtonA;
00220 BYTE bButtonB;
00221 BYTE bButtonC;
00222 BYTE bButtonD;
00223 } MYDATA;
00224
00225 static DIOBJECTDATAFORMAT rgodf[] = {
00226 { &GUID_XAxis, FIELD_OFFSET(MYDATA, lX), DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,},
00227 { &GUID_YAxis, FIELD_OFFSET(MYDATA, lY), DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,},
00228 { &GUID_ZAxis, FIELD_OFFSET(MYDATA, lZ), 0x80000000 | DIDFT_AXIS | DIDFT_ANYINSTANCE, 0,},
00229 { 0, FIELD_OFFSET(MYDATA, bButtonA), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
00230 { 0, FIELD_OFFSET(MYDATA, bButtonB), DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
00231 { 0, FIELD_OFFSET(MYDATA, bButtonC), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
00232 { 0, FIELD_OFFSET(MYDATA, bButtonD), 0x80000000 | DIDFT_BUTTON | DIDFT_ANYINSTANCE, 0,},
00233 };
00234
00235 #define NUM_OBJECTS (sizeof(rgodf) / sizeof(rgodf[0]))
00236
00237
00238 static DIDATAFORMAT df = {
00239 sizeof(DIDATAFORMAT),
00240 sizeof(DIOBJECTDATAFORMAT),
00241 DIDF_RELAXIS,
00242 sizeof(MYDATA),
00243 NUM_OBJECTS,
00244 rgodf,
00245 };
00246
00247 static LPDIRECTINPUT g_pdi;
00248 static LPDIRECTINPUTDEVICE g_pMouse;
00249
00250 void IN_DIMouse( int *mx, int *my );
00251
00252
00253
00254
00255
00256
00257 qboolean IN_InitDIMouse( void ) {
00258 HRESULT hr;
00259 int x, y;
00260 DIPROPDWORD dipdw = {
00261 {
00262 sizeof(DIPROPDWORD),
00263 sizeof(DIPROPHEADER),
00264 0,
00265 DIPH_DEVICE,
00266 },
00267 DINPUT_BUFFERSIZE,
00268 };
00269
00270 Com_Printf( "Initializing DirectInput...\n");
00271
00272 if (!hInstDI) {
00273 hInstDI = LoadLibrary("dinput.dll");
00274
00275 if (hInstDI == NULL) {
00276 Com_Printf ("Couldn't load dinput.dll\n");
00277 return qfalse;
00278 }
00279 }
00280
00281 if (!pDirectInputCreate) {
00282 pDirectInputCreate = (long (__stdcall *)(void *,unsigned long ,struct IDirectInputA ** ,struct IUnknown *))
00283 GetProcAddress(hInstDI,"DirectInputCreateA");
00284
00285 if (!pDirectInputCreate) {
00286 Com_Printf ("Couldn't get DI proc addr\n");
00287 return qfalse;
00288 }
00289 }
00290
00291
00292 hr = iDirectInputCreate( g_wv.hInstance, DIRECTINPUT_VERSION, &g_pdi, NULL);
00293
00294 if (FAILED(hr)) {
00295 Com_Printf ("iDirectInputCreate failed\n");
00296 return qfalse;
00297 }
00298
00299
00300 hr = IDirectInput_CreateDevice(g_pdi, &GUID_SysMouse, &g_pMouse, NULL);
00301
00302 if (FAILED(hr)) {
00303 Com_Printf ("Couldn't open DI mouse device\n");
00304 return qfalse;
00305 }
00306
00307
00308 hr = IDirectInputDevice_SetDataFormat(g_pMouse, &df);
00309
00310 if (FAILED(hr)) {
00311 Com_Printf ("Couldn't set DI mouse format\n");
00312 return qfalse;
00313 }
00314
00315
00316 hr = IDirectInputDevice_SetCooperativeLevel(g_pMouse, g_wv.hWnd,
00317 DISCL_EXCLUSIVE | DISCL_FOREGROUND);
00318
00319
00320 if (FAILED(hr)) {
00321 Com_Printf ("Couldn't set DI coop level\n");
00322 return qfalse;
00323 }
00324
00325
00326
00327
00328 hr = IDirectInputDevice_SetProperty(g_pMouse, DIPROP_BUFFERSIZE, &dipdw.diph);
00329
00330 if (FAILED(hr)) {
00331 Com_Printf ("Couldn't set DI buffersize\n");
00332 return qfalse;
00333 }
00334
00335
00336 IN_DIMouse( &x, &y );
00337 IN_DIMouse( &x, &y );
00338
00339 Com_Printf( "DirectInput initialized.\n");
00340 return qtrue;
00341 }
00342
00343
00344
00345
00346
00347
00348 void IN_ShutdownDIMouse( void ) {
00349 if (g_pMouse) {
00350 IDirectInputDevice_Release(g_pMouse);
00351 g_pMouse = NULL;
00352 }
00353
00354 if (g_pdi) {
00355 IDirectInput_Release(g_pdi);
00356 g_pdi = NULL;
00357 }
00358 }
00359
00360
00361
00362
00363
00364
00365 void IN_ActivateDIMouse( void ) {
00366 HRESULT hr;
00367
00368 if (!g_pMouse) {
00369 return;
00370 }
00371
00372
00373 hr = IDirectInputDevice_Acquire( g_pMouse );
00374 if (FAILED(hr)) {
00375 if ( !IN_InitDIMouse() ) {
00376 Com_Printf ("Falling back to Win32 mouse support...\n");
00377 Cvar_Set( "in_mouse", "-1" );
00378 }
00379 }
00380 }
00381
00382
00383
00384
00385
00386
00387 void IN_DeactivateDIMouse( void ) {
00388 if (!g_pMouse) {
00389 return;
00390 }
00391 IDirectInputDevice_Unacquire( g_pMouse );
00392 }
00393
00394
00395
00396
00397
00398
00399
00400 void IN_DIMouse( int *mx, int *my ) {
00401 DIDEVICEOBJECTDATA od;
00402 DIMOUSESTATE state;
00403 DWORD dwElements;
00404 HRESULT hr;
00405 int value;
00406 static float oldSysTime;
00407
00408 if ( !g_pMouse ) {
00409 return;
00410 }
00411
00412
00413 for (;;)
00414 {
00415 dwElements = 1;
00416
00417 hr = IDirectInputDevice_GetDeviceData(g_pMouse,
00418 sizeof(DIDEVICEOBJECTDATA), &od, &dwElements, 0);
00419 if ((hr == DIERR_INPUTLOST) || (hr == DIERR_NOTACQUIRED)) {
00420 IDirectInputDevice_Acquire(g_pMouse);
00421 return;
00422 }
00423
00424
00425 if ( FAILED(hr) ) {
00426 break;
00427 }
00428
00429 if ( dwElements == 0 ) {
00430 break;
00431 }
00432
00433 switch (od.dwOfs) {
00434 case DIMOFS_BUTTON0:
00435 if (od.dwData & 0x80)
00436 Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MOUSE1, qtrue, 0, NULL );
00437 else
00438 Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MOUSE1, qfalse, 0, NULL );
00439 break;
00440
00441 case DIMOFS_BUTTON1:
00442 if (od.dwData & 0x80)
00443 Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MOUSE2, qtrue, 0, NULL );
00444 else
00445 Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MOUSE2, qfalse, 0, NULL );
00446 break;
00447
00448 case DIMOFS_BUTTON2:
00449 if (od.dwData & 0x80)
00450 Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MOUSE3, qtrue, 0, NULL );
00451 else
00452 Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MOUSE3, qfalse, 0, NULL );
00453 break;
00454
00455 case DIMOFS_BUTTON3:
00456 if (od.dwData & 0x80)
00457 Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MOUSE4, qtrue, 0, NULL );
00458 else
00459 Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MOUSE4, qfalse, 0, NULL );
00460 break;
00461
00462 case DIMOFS_Z:
00463 value = od.dwData;
00464 if (value == 0) {
00465
00466 } else if (value < 0) {
00467 Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MWHEELDOWN, qtrue, 0, NULL );
00468 Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MWHEELDOWN, qfalse, 0, NULL );
00469 } else {
00470 Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MWHEELUP, qtrue, 0, NULL );
00471 Sys_QueEvent( od.dwTimeStamp, SE_KEY, K_MWHEELUP, qfalse, 0, NULL );
00472 }
00473 break;
00474 }
00475 }
00476
00477
00478
00479 hr = IDirectInputDevice_GetDeviceState(g_pMouse,
00480 sizeof(DIDEVICEOBJECTDATA), &state);
00481 if ( FAILED(hr) ) {
00482 *mx = *my = 0;
00483 return;
00484 }
00485 *mx = state.lX;
00486 *my = state.lY;
00487 }
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 void IN_ActivateMouse( void )
00505 {
00506 if (!s_wmv.mouseInitialized ) {
00507 return;
00508 }
00509 if ( !in_mouse->integer )
00510 {
00511 s_wmv.mouseActive = qfalse;
00512 return;
00513 }
00514 if ( s_wmv.mouseActive )
00515 {
00516 return;
00517 }
00518
00519 s_wmv.mouseActive = qtrue;
00520
00521 if ( in_mouse->integer != -1 ) {
00522 IN_ActivateDIMouse();
00523 }
00524 IN_ActivateWin32Mouse();
00525 }
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535 void IN_DeactivateMouse( void ) {
00536 if (!s_wmv.mouseInitialized ) {
00537 return;
00538 }
00539 if (!s_wmv.mouseActive ) {
00540 return;
00541 }
00542 s_wmv.mouseActive = qfalse;
00543
00544 IN_DeactivateDIMouse();
00545 IN_DeactivateWin32Mouse();
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555 void IN_StartupMouse( void )
00556 {
00557 s_wmv.mouseInitialized = qfalse;
00558 s_wmv.mouseStartupDelayed = qfalse;
00559
00560 if ( in_mouse->integer == 0 ) {
00561 Com_Printf ("Mouse control not active.\n");
00562 return;
00563 }
00564
00565
00566 if ( ( g_wv.osversion.dwPlatformId == VER_PLATFORM_WIN32_NT ) &&
00567 ( g_wv.osversion.dwMajorVersion == 4 ) )
00568 {
00569 Com_Printf ("Disallowing DirectInput on NT 4.0\n");
00570 Cvar_Set( "in_mouse", "-1" );
00571 }
00572
00573 if ( in_mouse->integer == -1 ) {
00574 Com_Printf ("Skipping check for DirectInput\n");
00575 } else {
00576 if (!g_wv.hWnd)
00577 {
00578 Com_Printf ("No window for DirectInput mouse init, delaying\n");
00579 s_wmv.mouseStartupDelayed = qtrue;
00580 return;
00581 }
00582 if ( IN_InitDIMouse() ) {
00583 s_wmv.mouseInitialized = qtrue;
00584 return;
00585 }
00586 Com_Printf ("Falling back to Win32 mouse support...\n");
00587 }
00588 s_wmv.mouseInitialized = qtrue;
00589 IN_InitWin32Mouse();
00590 }
00591
00592
00593
00594
00595
00596
00597 void IN_MouseEvent (int mstate)
00598 {
00599 int i;
00600
00601 if ( !s_wmv.mouseInitialized )
00602 return;
00603
00604
00605 for (i = 0 ; i < 3 ; i++ )
00606 {
00607 if ( (mstate & (1<<i)) &&
00608 !(s_wmv.oldButtonState & (1<<i)) )
00609 {
00610 Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MOUSE1 + i, qtrue, 0, NULL );
00611 }
00612
00613 if ( !(mstate & (1<<i)) &&
00614 (s_wmv.oldButtonState & (1<<i)) )
00615 {
00616 Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_MOUSE1 + i, qfalse, 0, NULL );
00617 }
00618 }
00619
00620 s_wmv.oldButtonState = mstate;
00621 }
00622
00623
00624
00625
00626
00627
00628
00629 void IN_MouseMove ( void ) {
00630 int mx, my;
00631
00632 if ( g_pMouse ) {
00633 IN_DIMouse( &mx, &my );
00634 } else {
00635 IN_Win32Mouse( &mx, &my );
00636 }
00637
00638 if ( !mx && !my ) {
00639 return;
00640 }
00641
00642 Sys_QueEvent( 0, SE_MOUSE, mx, my, 0, NULL );
00643 }
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 void IN_Startup( void ) {
00658 Com_Printf ("\n------- Input Initialization -------\n");
00659 IN_StartupMouse ();
00660 IN_StartupJoystick ();
00661 IN_StartupMIDI();
00662 Com_Printf ("------------------------------------\n");
00663
00664 in_mouse->modified = qfalse;
00665 in_joystick->modified = qfalse;
00666 }
00667
00668
00669
00670
00671
00672
00673 void IN_Shutdown( void ) {
00674 IN_DeactivateMouse();
00675 IN_ShutdownDIMouse();
00676 IN_ShutdownMIDI();
00677 Cmd_RemoveCommand("midiinfo" );
00678 }
00679
00680
00681
00682
00683
00684
00685
00686 void IN_Init( void ) {
00687
00688 in_midi = Cvar_Get ("in_midi", "0", CVAR_ARCHIVE);
00689 in_midiport = Cvar_Get ("in_midiport", "1", CVAR_ARCHIVE);
00690 in_midichannel = Cvar_Get ("in_midichannel", "1", CVAR_ARCHIVE);
00691 in_mididevice = Cvar_Get ("in_mididevice", "0", CVAR_ARCHIVE);
00692
00693 Cmd_AddCommand( "midiinfo", MidiInfo_f );
00694
00695
00696 in_mouse = Cvar_Get ("in_mouse", "1", CVAR_ARCHIVE|CVAR_LATCH);
00697 in_logitechbug = Cvar_Get ("in_logitechbug", "0", CVAR_ARCHIVE);
00698
00699
00700 in_joystick = Cvar_Get ("in_joystick", "0", CVAR_ARCHIVE|CVAR_LATCH);
00701 in_joyBallScale = Cvar_Get ("in_joyBallScale", "0.02", CVAR_ARCHIVE);
00702 in_debugJoystick = Cvar_Get ("in_debugjoystick", "0", CVAR_TEMP);
00703
00704 joy_threshold = Cvar_Get ("joy_threshold", "0.15", CVAR_ARCHIVE);
00705
00706 IN_Startup();
00707 }
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719 void IN_Activate (qboolean active) {
00720 in_appactive = active;
00721
00722 if ( !active )
00723 {
00724 IN_DeactivateMouse();
00725 }
00726 }
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736 void IN_Frame (void) {
00737
00738 IN_JoyMove();
00739
00740 if ( !s_wmv.mouseInitialized ) {
00741 if (s_wmv.mouseStartupDelayed && g_wv.hWnd)
00742 {
00743 Com_Printf("Proceeding with delayed mouse init\n");
00744 IN_StartupMouse();
00745 s_wmv.mouseStartupDelayed = qfalse;
00746 }
00747 return;
00748 }
00749
00750 if ( cls.keyCatchers & KEYCATCH_CONSOLE ) {
00751
00752
00753
00754 if (Cvar_VariableValue ("r_fullscreen") == 0
00755 && strcmp( Cvar_VariableString("r_glDriver"), _3DFX_DRIVER_NAME) ) {
00756 IN_DeactivateMouse ();
00757 return;
00758 }
00759 }
00760
00761 if ( !in_appactive ) {
00762 IN_DeactivateMouse ();
00763 return;
00764 }
00765
00766 IN_ActivateMouse();
00767
00768
00769 IN_MouseMove();
00770
00771 }
00772
00773
00774
00775
00776
00777
00778
00779 void IN_ClearStates (void)
00780 {
00781 s_wmv.oldButtonState = 0;
00782 }
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798 void IN_StartupJoystick (void) {
00799 int numdevs;
00800 MMRESULT mmr;
00801
00802
00803 joy.avail = qfalse;
00804
00805 if (! in_joystick->integer ) {
00806 Com_Printf ("Joystick is not active.\n");
00807 return;
00808 }
00809
00810
00811 if ((numdevs = joyGetNumDevs ()) == 0)
00812 {
00813 Com_Printf ("joystick not found -- driver not present\n");
00814 return;
00815 }
00816
00817
00818 mmr = 0;
00819 for (joy.id=0 ; joy.id<numdevs ; joy.id++)
00820 {
00821 Com_Memset (&joy.ji, 0, sizeof(joy.ji));
00822 joy.ji.dwSize = sizeof(joy.ji);
00823 joy.ji.dwFlags = JOY_RETURNCENTERED;
00824
00825 if ((mmr = joyGetPosEx (joy.id, &joy.ji)) == JOYERR_NOERROR)
00826 break;
00827 }
00828
00829
00830 if (mmr != JOYERR_NOERROR)
00831 {
00832 Com_Printf ("joystick not found -- no valid joysticks (%x)\n", mmr);
00833 return;
00834 }
00835
00836
00837
00838 Com_Memset (&joy.jc, 0, sizeof(joy.jc));
00839 if ((mmr = joyGetDevCaps (joy.id, &joy.jc, sizeof(joy.jc))) != JOYERR_NOERROR)
00840 {
00841 Com_Printf ("joystick not found -- invalid joystick capabilities (%x)\n", mmr);
00842 return;
00843 }
00844
00845 Com_Printf( "Joystick found.\n" );
00846 Com_Printf( "Pname: %s\n", joy.jc.szPname );
00847 Com_Printf( "OemVxD: %s\n", joy.jc.szOEMVxD );
00848 Com_Printf( "RegKey: %s\n", joy.jc.szRegKey );
00849
00850 Com_Printf( "Numbuttons: %i / %i\n", joy.jc.wNumButtons, joy.jc.wMaxButtons );
00851 Com_Printf( "Axis: %i / %i\n", joy.jc.wNumAxes, joy.jc.wMaxAxes );
00852 Com_Printf( "Caps: 0x%x\n", joy.jc.wCaps );
00853 if ( joy.jc.wCaps & JOYCAPS_HASPOV ) {
00854 Com_Printf( "HASPOV\n" );
00855 } else {
00856 Com_Printf( "no POV\n" );
00857 }
00858
00859
00860 joy.oldbuttonstate = 0;
00861 joy.oldpovstate = 0;
00862
00863
00864 joy.avail = qtrue;
00865 }
00866
00867
00868
00869
00870
00871
00872 float JoyToF( int value ) {
00873 float fValue;
00874
00875
00876 value -= 32768;
00877
00878
00879 fValue = (float)value / 32768.0;
00880
00881 if ( fValue < -1 ) {
00882 fValue = -1;
00883 }
00884 if ( fValue > 1 ) {
00885 fValue = 1;
00886 }
00887 return fValue;
00888 }
00889
00890 int JoyToI( int value ) {
00891
00892 value -= 32768;
00893
00894 return value;
00895 }
00896
00897 int joyDirectionKeys[16] = {
00898 K_LEFTARROW, K_RIGHTARROW,
00899 K_UPARROW, K_DOWNARROW,
00900 K_JOY16, K_JOY17,
00901 K_JOY18, K_JOY19,
00902 K_JOY20, K_JOY21,
00903 K_JOY22, K_JOY23,
00904
00905 K_JOY24, K_JOY25,
00906 K_JOY26, K_JOY27
00907 };
00908
00909
00910
00911
00912
00913
00914 void IN_JoyMove( void ) {
00915 float fAxisValue;
00916 int i;
00917 DWORD buttonstate, povstate;
00918 int x, y;
00919
00920
00921 if ( !joy.avail ) {
00922 return;
00923 }
00924
00925
00926 Com_Memset (&joy.ji, 0, sizeof(joy.ji));
00927 joy.ji.dwSize = sizeof(joy.ji);
00928 joy.ji.dwFlags = JOY_RETURNALL;
00929
00930 if ( joyGetPosEx (joy.id, &joy.ji) != JOYERR_NOERROR ) {
00931
00932
00933
00934
00935
00936 return;
00937 }
00938
00939 if ( in_debugJoystick->integer ) {
00940 Com_Printf( "%8x %5i %5.2f %5.2f %5.2f %5.2f %6i %6i\n",
00941 joy.ji.dwButtons,
00942 joy.ji.dwPOV,
00943 JoyToF( joy.ji.dwXpos ), JoyToF( joy.ji.dwYpos ),
00944 JoyToF( joy.ji.dwZpos ), JoyToF( joy.ji.dwRpos ),
00945 JoyToI( joy.ji.dwUpos ), JoyToI( joy.ji.dwVpos ) );
00946 }
00947
00948
00949
00950 buttonstate = joy.ji.dwButtons;
00951 for ( i=0 ; i < joy.jc.wNumButtons ; i++ ) {
00952 if ( (buttonstate & (1<<i)) && !(joy.oldbuttonstate & (1<<i)) ) {
00953 Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_JOY1 + i, qtrue, 0, NULL );
00954 }
00955 if ( !(buttonstate & (1<<i)) && (joy.oldbuttonstate & (1<<i)) ) {
00956 Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, K_JOY1 + i, qfalse, 0, NULL );
00957 }
00958 }
00959 joy.oldbuttonstate = buttonstate;
00960
00961 povstate = 0;
00962
00963
00964 for (i = 0; i < joy.jc.wNumAxes && i < 4 ; i++) {
00965
00966 fAxisValue = JoyToF( (&joy.ji.dwXpos)[i] );
00967
00968 if ( fAxisValue < -joy_threshold->value ) {
00969 povstate |= (1<<(i*2));
00970 } else if ( fAxisValue > joy_threshold->value ) {
00971 povstate |= (1<<(i*2+1));
00972 }
00973 }
00974
00975
00976 if ( joy.jc.wCaps & JOYCAPS_HASPOV ) {
00977 if ( joy.ji.dwPOV != JOY_POVCENTERED ) {
00978 if (joy.ji.dwPOV == JOY_POVFORWARD)
00979 povstate |= 1<<12;
00980 if (joy.ji.dwPOV == JOY_POVBACKWARD)
00981 povstate |= 1<<13;
00982 if (joy.ji.dwPOV == JOY_POVRIGHT)
00983 povstate |= 1<<14;
00984 if (joy.ji.dwPOV == JOY_POVLEFT)
00985 povstate |= 1<<15;
00986 }
00987 }
00988
00989
00990 for (i=0 ; i < 16 ; i++) {
00991 if ( (povstate & (1<<i)) && !(joy.oldpovstate & (1<<i)) ) {
00992 Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, joyDirectionKeys[i], qtrue, 0, NULL );
00993 }
00994
00995 if ( !(povstate & (1<<i)) && (joy.oldpovstate & (1<<i)) ) {
00996 Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, joyDirectionKeys[i], qfalse, 0, NULL );
00997 }
00998 }
00999 joy.oldpovstate = povstate;
01000
01001
01002 if ( joy.jc.wNumAxes >= 6 ) {
01003 x = JoyToI( joy.ji.dwUpos ) * in_joyBallScale->value;
01004 y = JoyToI( joy.ji.dwVpos ) * in_joyBallScale->value;
01005 if ( x || y ) {
01006 Sys_QueEvent( g_wv.sysMsgTime, SE_MOUSE, x, y, 0, NULL );
01007 }
01008 }
01009 }
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019 static void MIDI_NoteOff( int note )
01020 {
01021 int qkey;
01022
01023 qkey = note - 60 + K_AUX1;
01024
01025 if ( qkey > 255 || qkey < K_AUX1 )
01026 return;
01027
01028 Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, qkey, qfalse, 0, NULL );
01029 }
01030
01031 static void MIDI_NoteOn( int note, int velocity )
01032 {
01033 int qkey;
01034
01035 if ( velocity == 0 )
01036 MIDI_NoteOff( note );
01037
01038 qkey = note - 60 + K_AUX1;
01039
01040 if ( qkey > 255 || qkey < K_AUX1 )
01041 return;
01042
01043 Sys_QueEvent( g_wv.sysMsgTime, SE_KEY, qkey, qtrue, 0, NULL );
01044 }
01045
01046 static void CALLBACK MidiInProc( HMIDIIN hMidiIn, UINT uMsg, DWORD dwInstance,
01047 DWORD dwParam1, DWORD dwParam2 )
01048 {
01049 int message;
01050
01051 switch ( uMsg )
01052 {
01053 case MIM_OPEN:
01054 break;
01055 case MIM_CLOSE:
01056 break;
01057 case MIM_DATA:
01058 message = dwParam1 & 0xff;
01059
01060
01061 if ( ( message & 0xf0 ) == 0x90 )
01062 {
01063 if ( ( ( message & 0x0f ) + 1 ) == in_midichannel->integer )
01064 MIDI_NoteOn( ( dwParam1 & 0xff00 ) >> 8, ( dwParam1 & 0xff0000 ) >> 16 );
01065 }
01066 else if ( ( message & 0xf0 ) == 0x80 )
01067 {
01068 if ( ( ( message & 0x0f ) + 1 ) == in_midichannel->integer )
01069 MIDI_NoteOff( ( dwParam1 & 0xff00 ) >> 8 );
01070 }
01071 break;
01072 case MIM_LONGDATA:
01073 break;
01074 case MIM_ERROR:
01075 break;
01076 case MIM_LONGERROR:
01077 break;
01078 }
01079
01080
01081 }
01082
01083 static void MidiInfo_f( void )
01084 {
01085 int i;
01086
01087 const char *enableStrings[] = { "disabled", "enabled" };
01088
01089 Com_Printf( "\nMIDI control: %s\n", enableStrings[in_midi->integer != 0] );
01090 Com_Printf( "port: %d\n", in_midiport->integer );
01091 Com_Printf( "channel: %d\n", in_midichannel->integer );
01092 Com_Printf( "current device: %d\n", in_mididevice->integer );
01093 Com_Printf( "number of devices: %d\n", s_midiInfo.numDevices );
01094 for ( i = 0; i < s_midiInfo.numDevices; i++ )
01095 {
01096 if ( i == Cvar_VariableValue( "in_mididevice" ) )
01097 Com_Printf( "***" );
01098 else
01099 Com_Printf( "..." );
01100 Com_Printf( "device %2d: %s\n", i, s_midiInfo.caps[i].szPname );
01101 Com_Printf( "...manufacturer ID: 0x%hx\n", s_midiInfo.caps[i].wMid );
01102 Com_Printf( "...product ID: 0x%hx\n", s_midiInfo.caps[i].wPid );
01103
01104 Com_Printf( "\n" );
01105 }
01106 }
01107
01108 static void IN_StartupMIDI( void )
01109 {
01110 int i;
01111
01112 if ( !Cvar_VariableValue( "in_midi" ) )
01113 return;
01114
01115
01116
01117
01118 s_midiInfo.numDevices = midiInGetNumDevs();
01119
01120 for ( i = 0; i < s_midiInfo.numDevices; i++ )
01121 {
01122 midiInGetDevCaps( i, &s_midiInfo.caps[i], sizeof( s_midiInfo.caps[i] ) );
01123 }
01124
01125
01126
01127
01128 if ( midiInOpen( &s_midiInfo.hMidiIn,
01129 in_mididevice->integer,
01130 ( unsigned long ) MidiInProc,
01131 ( unsigned long ) NULL,
01132 CALLBACK_FUNCTION ) != MMSYSERR_NOERROR )
01133 {
01134 Com_Printf( "WARNING: could not open MIDI device %d: '%s'\n", in_mididevice->integer , s_midiInfo.caps[( int ) in_mididevice->value] );
01135 return;
01136 }
01137
01138 midiInStart( s_midiInfo.hMidiIn );
01139 }
01140
01141 static void IN_ShutdownMIDI( void )
01142 {
01143 if ( s_midiInfo.hMidiIn )
01144 {
01145 midiInClose( s_midiInfo.hMidiIn );
01146 }
01147 Com_Memset( &s_midiInfo, 0, sizeof( s_midiInfo ) );
01148 }
01149