|
|
1.1.1.3 ! root 1: /* ! 2: Copyright (C) 1997-2001 Id Software, Inc. ! 3: ! 4: This program is free software; you can redistribute it and/or ! 5: modify it under the terms of the GNU General Public License ! 6: as published by the Free Software Foundation; either version 2 ! 7: of the License, or (at your option) any later version. ! 8: ! 9: This program is distributed in the hope that it will be useful, ! 10: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 11: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ! 12: ! 13: See the GNU General Public License for more details. ! 14: ! 15: You should have received a copy of the GNU General Public License ! 16: along with this program; if not, write to the Free Software ! 17: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ! 18: ! 19: */ 1.1 root 20: // in_win.c -- windows 95 mouse and joystick code 21: // 02/21/97 JCB Added extended DirectInput code to support external controllers. 1.1.1.2 root 22: 1.1 root 23: #include "../client/client.h" 24: #include "winquake.h" 25: 26: extern unsigned sys_msg_time; 1.1.1.2 root 27: 1.1 root 28: // joystick defines and variables 29: // where should defines be moved? 30: #define JOY_ABSOLUTE_AXIS 0x00000000 // control like a joystick 31: #define JOY_RELATIVE_AXIS 0x00000010 // control like a mouse, spinner, trackball 32: #define JOY_MAX_AXES 6 // X, Y, Z, R, U, V 33: #define JOY_AXIS_X 0 34: #define JOY_AXIS_Y 1 35: #define JOY_AXIS_Z 2 36: #define JOY_AXIS_R 3 37: #define JOY_AXIS_U 4 38: #define JOY_AXIS_V 5 1.1.1.2 root 39: 1.1 root 40: enum _ControlList 41: { 42: AxisNada = 0, AxisForward, AxisLook, AxisSide, AxisTurn, AxisUp 43: }; 1.1.1.2 root 44: 1.1 root 45: DWORD dwAxisFlags[JOY_MAX_AXES] = 46: { 47: JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ, JOY_RETURNR, JOY_RETURNU, JOY_RETURNV 48: }; 1.1.1.2 root 49: 1.1 root 50: DWORD dwAxisMap[JOY_MAX_AXES]; 51: DWORD dwControlMap[JOY_MAX_AXES]; 52: PDWORD pdwRawValue[JOY_MAX_AXES]; 1.1.1.2 root 53: 1.1 root 54: cvar_t *in_mouse; 55: cvar_t *in_joystick; 1.1.1.2 root 56: 57: 1.1 root 58: // none of these cvars are saved over a session 59: // this means that advanced controller configuration needs to be executed 60: // each time. this avoids any problems with getting back to a default usage 61: // or when changing from one controller to another. this way at least something 62: // works. 63: cvar_t *joy_name; 64: cvar_t *joy_advanced; 65: cvar_t *joy_advaxisx; 66: cvar_t *joy_advaxisy; 67: cvar_t *joy_advaxisz; 68: cvar_t *joy_advaxisr; 69: cvar_t *joy_advaxisu; 70: cvar_t *joy_advaxisv; 71: cvar_t *joy_forwardthreshold; 72: cvar_t *joy_sidethreshold; 73: cvar_t *joy_pitchthreshold; 74: cvar_t *joy_yawthreshold; 75: cvar_t *joy_forwardsensitivity; 76: cvar_t *joy_sidesensitivity; 77: cvar_t *joy_pitchsensitivity; 78: cvar_t *joy_yawsensitivity; 79: cvar_t *joy_upthreshold; 80: cvar_t *joy_upsensitivity; 1.1.1.2 root 81: 1.1 root 82: qboolean joy_avail, joy_advancedinit, joy_haspov; 83: DWORD joy_oldbuttonstate, joy_oldpovstate; 1.1.1.2 root 84: 1.1 root 85: int joy_id; 86: DWORD joy_flags; 87: DWORD joy_numbuttons; 1.1.1.2 root 88: 1.1 root 89: static JOYINFOEX ji; 1.1.1.2 root 90: 1.1 root 91: qboolean in_appactive; 1.1.1.2 root 92: 1.1 root 93: // forward-referenced functions 94: void IN_StartupJoystick (void); 95: void Joy_AdvancedUpdate_f (void); 96: void IN_JoyMove (usercmd_t *cmd); 1.1.1.2 root 97: 1.1 root 98: /* 99: ============================================================ 1.1.1.2 root 100: 1.1 root 101: MOUSE CONTROL 1.1.1.2 root 102: 1.1 root 103: ============================================================ 104: */ 1.1.1.2 root 105: 1.1 root 106: // mouse variables 107: cvar_t *m_filter; 1.1.1.2 root 108: 1.1 root 109: qboolean mlooking; 1.1.1.2 root 110: 1.1 root 111: void IN_MLookDown (void) { mlooking = true; } 112: void IN_MLookUp (void) { 113: mlooking = false; 114: if (!freelook->value && lookspring->value) 115: IN_CenterView (); 116: } 1.1.1.2 root 117: 1.1 root 118: int mouse_buttons; 119: int mouse_oldbuttonstate; 120: POINT current_pos; 121: int mouse_x, mouse_y, old_mouse_x, old_mouse_y, mx_accum, my_accum; 1.1.1.2 root 122: 1.1 root 123: int old_x, old_y; 1.1.1.2 root 124: 1.1 root 125: qboolean mouseactive; // false when not focus app 1.1.1.2 root 126: 1.1 root 127: qboolean restore_spi; 128: qboolean mouseinitialized; 129: int originalmouseparms[3], newmouseparms[3] = {0, 0, 1}; 130: qboolean mouseparmsvalid; 1.1.1.2 root 131: 1.1 root 132: int window_center_x, window_center_y; 133: RECT window_rect; 1.1.1.2 root 134: 135: 1.1 root 136: /* 137: =========== 138: IN_ActivateMouse 1.1.1.2 root 139: 1.1 root 140: Called when the window gains focus or changes in some way 141: =========== 142: */ 143: void IN_ActivateMouse (void) 144: { 145: int width, height; 1.1.1.2 root 146: 1.1 root 147: if (!mouseinitialized) 148: return; 149: if (!in_mouse->value) 150: { 151: mouseactive = false; 152: return; 153: } 154: if (mouseactive) 155: return; 1.1.1.2 root 156: 1.1 root 157: mouseactive = true; 158: 159: if (mouseparmsvalid) 160: restore_spi = SystemParametersInfo (SPI_SETMOUSE, 0, newmouseparms, 0); 161: 162: width = GetSystemMetrics (SM_CXSCREEN); 163: height = GetSystemMetrics (SM_CYSCREEN); 1.1.1.2 root 164: 1.1 root 165: GetWindowRect ( cl_hwnd, &window_rect); 166: if (window_rect.left < 0) 167: window_rect.left = 0; 168: if (window_rect.top < 0) 169: window_rect.top = 0; 170: if (window_rect.right >= width) 171: window_rect.right = width-1; 172: if (window_rect.bottom >= height-1) 173: window_rect.bottom = height-1; 174: 175: window_center_x = (window_rect.right + window_rect.left)/2; 176: window_center_y = (window_rect.top + window_rect.bottom)/2; 177: 178: SetCursorPos (window_center_x, window_center_y); 179: 180: old_x = window_center_x; 181: old_y = window_center_y; 1.1.1.2 root 182: 1.1 root 183: SetCapture ( cl_hwnd ); 184: ClipCursor (&window_rect); 185: while (ShowCursor (FALSE) >= 0) 186: ; 187: } 1.1.1.2 root 188: 189: 1.1 root 190: /* 191: =========== 192: IN_DeactivateMouse 1.1.1.2 root 193: 1.1 root 194: Called when the window loses focus 195: =========== 196: */ 197: void IN_DeactivateMouse (void) 198: { 199: if (!mouseinitialized) 200: return; 201: if (!mouseactive) 202: return; 1.1.1.2 root 203: 1.1 root 204: if (restore_spi) 205: SystemParametersInfo (SPI_SETMOUSE, 0, originalmouseparms, 0); 1.1.1.2 root 206: 1.1 root 207: mouseactive = false; 1.1.1.2 root 208: 1.1 root 209: ClipCursor (NULL); 210: ReleaseCapture (); 211: while (ShowCursor (TRUE) < 0) 212: ; 213: } 1.1.1.2 root 214: 215: 216: 1.1 root 217: /* 218: =========== 219: IN_StartupMouse 220: =========== 221: */ 222: void IN_StartupMouse (void) 223: { 224: cvar_t *cv; 1.1.1.2 root 225: 1.1 root 226: cv = Cvar_Get ("in_initmouse", "1", CVAR_NOSET); 227: if ( !cv->value ) 228: return; 1.1.1.2 root 229: 1.1 root 230: mouseinitialized = true; 231: mouseparmsvalid = SystemParametersInfo (SPI_GETMOUSE, 0, originalmouseparms, 0); 232: mouse_buttons = 3; 233: } 1.1.1.2 root 234: 1.1 root 235: /* 236: =========== 237: IN_MouseEvent 238: =========== 239: */ 240: void IN_MouseEvent (int mstate) 241: { 242: int i; 1.1.1.2 root 243: 1.1 root 244: if (!mouseinitialized) 245: return; 246: 247: // perform button actions 248: for (i=0 ; i<mouse_buttons ; i++) 249: { 250: if ( (mstate & (1<<i)) && 251: !(mouse_oldbuttonstate & (1<<i)) ) 252: { 253: Key_Event (K_MOUSE1 + i, true, sys_msg_time); 254: } 1.1.1.2 root 255: 1.1 root 256: if ( !(mstate & (1<<i)) && 257: (mouse_oldbuttonstate & (1<<i)) ) 258: { 259: Key_Event (K_MOUSE1 + i, false, sys_msg_time); 260: } 261: } 262: 263: mouse_oldbuttonstate = mstate; 264: } 265: 1.1.1.2 root 266: 1.1 root 267: /* 268: =========== 269: IN_MouseMove 270: =========== 271: */ 272: void IN_MouseMove (usercmd_t *cmd) 273: { 274: int mx, my; 275: 276: if (!mouseactive) 277: return; 278: 279: // find mouse movement 1.1.1.2 root 280: if (!GetCursorPos (¤t_pos)) 281: return; 1.1 root 282: 283: mx = current_pos.x - window_center_x; 284: my = current_pos.y - window_center_y; 285: 1.1.1.2 root 286: #if 0 1.1 root 287: if (!mx && !my) 288: return; 1.1.1.2 root 289: #endif 1.1 root 290: 291: if (m_filter->value) 292: { 293: mouse_x = (mx + old_mouse_x) * 0.5; 294: mouse_y = (my + old_mouse_y) * 0.5; 295: } 296: else 297: { 298: mouse_x = mx; 299: mouse_y = my; 300: } 301: 302: old_mouse_x = mx; 303: old_mouse_y = my; 304: 305: mouse_x *= sensitivity->value; 306: mouse_y *= sensitivity->value; 307: 308: // add mouse X/Y movement to cmd 309: if ( (in_strafe.state & 1) || (lookstrafe->value && mlooking )) 310: cmd->sidemove += m_side->value * mouse_x; 311: else 312: cl.viewangles[YAW] -= m_yaw->value * mouse_x; 313: 314: if ( (mlooking || freelook->value) && !(in_strafe.state & 1)) 315: { 316: cl.viewangles[PITCH] += m_pitch->value * mouse_y; 317: } 318: else 319: { 320: cmd->forwardmove -= m_forward->value * mouse_y; 321: } 322: 323: // force the mouse to the center, so there's room to move 1.1.1.2 root 324: if (mx || my) 325: SetCursorPos (window_center_x, window_center_y); 1.1 root 326: } 327: 1.1.1.2 root 328: 1.1 root 329: /* 330: ========================================================================= 1.1.1.2 root 331: 1.1 root 332: VIEW CENTERING 1.1.1.2 root 333: 1.1 root 334: ========================================================================= 335: */ 1.1.1.2 root 336: 1.1 root 337: cvar_t *v_centermove; 338: cvar_t *v_centerspeed; 1.1.1.2 root 339: 340: 1.1 root 341: /* 342: =========== 343: IN_Init 344: =========== 345: */ 346: void IN_Init (void) 347: { 348: // mouse variables 349: m_filter = Cvar_Get ("m_filter", "0", 0); 350: in_mouse = Cvar_Get ("in_mouse", "1", CVAR_ARCHIVE); 1.1.1.2 root 351: 1.1 root 352: // joystick variables 353: in_joystick = Cvar_Get ("in_joystick", "0", CVAR_ARCHIVE); 354: joy_name = Cvar_Get ("joy_name", "joystick", 0); 355: joy_advanced = Cvar_Get ("joy_advanced", "0", 0); 356: joy_advaxisx = Cvar_Get ("joy_advaxisx", "0", 0); 357: joy_advaxisy = Cvar_Get ("joy_advaxisy", "0", 0); 358: joy_advaxisz = Cvar_Get ("joy_advaxisz", "0", 0); 359: joy_advaxisr = Cvar_Get ("joy_advaxisr", "0", 0); 360: joy_advaxisu = Cvar_Get ("joy_advaxisu", "0", 0); 361: joy_advaxisv = Cvar_Get ("joy_advaxisv", "0", 0); 362: joy_forwardthreshold = Cvar_Get ("joy_forwardthreshold", "0.15", 0); 363: joy_sidethreshold = Cvar_Get ("joy_sidethreshold", "0.15", 0); 364: joy_upthreshold = Cvar_Get ("joy_upthreshold", "0.15", 0); 365: joy_pitchthreshold = Cvar_Get ("joy_pitchthreshold", "0.15", 0); 366: joy_yawthreshold = Cvar_Get ("joy_yawthreshold", "0.15", 0); 367: joy_forwardsensitivity = Cvar_Get ("joy_forwardsensitivity", "-1", 0); 368: joy_sidesensitivity = Cvar_Get ("joy_sidesensitivity", "-1", 0); 369: joy_upsensitivity = Cvar_Get ("joy_upsensitivity", "-1", 0); 370: joy_pitchsensitivity = Cvar_Get ("joy_pitchsensitivity", "1", 0); 371: joy_yawsensitivity = Cvar_Get ("joy_yawsensitivity", "-1", 0); 1.1.1.2 root 372: 1.1 root 373: // centering 374: v_centermove = Cvar_Get ("v_centermove", "0.15", 0); 375: v_centerspeed = Cvar_Get ("v_centerspeed", "500", 0); 1.1.1.2 root 376: 1.1 root 377: Cmd_AddCommand ("+mlook", IN_MLookDown); 378: Cmd_AddCommand ("-mlook", IN_MLookUp); 1.1.1.2 root 379: 1.1 root 380: Cmd_AddCommand ("joy_advancedupdate", Joy_AdvancedUpdate_f); 1.1.1.2 root 381: 1.1 root 382: IN_StartupMouse (); 383: IN_StartupJoystick (); 384: } 1.1.1.2 root 385: 1.1 root 386: /* 387: =========== 388: IN_Shutdown 389: =========== 390: */ 391: void IN_Shutdown (void) 392: { 393: IN_DeactivateMouse (); 394: } 1.1.1.2 root 395: 396: 1.1 root 397: /* 398: =========== 399: IN_Activate 1.1.1.2 root 400: 1.1 root 401: Called when the main window gains or loses focus. 402: The window may have been destroyed and recreated 403: between a deactivate and an activate. 404: =========== 405: */ 406: void IN_Activate (qboolean active) 407: { 408: in_appactive = active; 409: mouseactive = !active; // force a new window check or turn off 410: } 1.1.1.2 root 411: 412: 1.1 root 413: /* 414: ================== 415: IN_Frame 1.1.1.2 root 416: 1.1 root 417: Called every frame, even if not generating commands 418: ================== 419: */ 420: void IN_Frame (void) 421: { 422: if (!mouseinitialized) 423: return; 1.1.1.2 root 424: 1.1 root 425: if (!in_mouse || !in_appactive) 426: { 427: IN_DeactivateMouse (); 428: return; 429: } 1.1.1.2 root 430: 1.1 root 431: if ( !cl.refresh_prepped 432: || cls.key_dest == key_console 433: || cls.key_dest == key_menu) 434: { 435: // temporarily deactivate if in fullscreen 436: if (Cvar_VariableValue ("vid_fullscreen") == 0) 437: { 438: IN_DeactivateMouse (); 439: return; 440: } 441: } 1.1.1.2 root 442: 1.1 root 443: IN_ActivateMouse (); 444: } 1.1.1.2 root 445: 1.1 root 446: /* 447: =========== 448: IN_Move 449: =========== 450: */ 451: void IN_Move (usercmd_t *cmd) 452: { 453: IN_MouseMove (cmd); 1.1.1.2 root 454: 1.1 root 455: if (ActiveApp) 456: IN_JoyMove (cmd); 457: } 1.1.1.2 root 458: 459: 1.1 root 460: /* 461: =================== 462: IN_ClearStates 463: =================== 464: */ 465: void IN_ClearStates (void) 466: { 467: mx_accum = 0; 468: my_accum = 0; 469: mouse_oldbuttonstate = 0; 470: } 1.1.1.2 root 471: 472: 1.1 root 473: /* 474: ========================================================================= 1.1.1.2 root 475: 1.1 root 476: JOYSTICK 1.1.1.2 root 477: 1.1 root 478: ========================================================================= 479: */ 1.1.1.2 root 480: 1.1 root 481: /* 482: =============== 483: IN_StartupJoystick 484: =============== 485: */ 486: void IN_StartupJoystick (void) 487: { 488: int numdevs; 489: JOYCAPS jc; 490: MMRESULT mmr; 491: cvar_t *cv; 1.1.1.2 root 492: 1.1 root 493: // assume no joystick 494: joy_avail = false; 1.1.1.2 root 495: 1.1 root 496: // abort startup if user requests no joystick 497: cv = Cvar_Get ("in_initjoy", "1", CVAR_NOSET); 498: if ( !cv->value ) 499: return; 500: 501: // verify joystick driver is present 502: if ((numdevs = joyGetNumDevs ()) == 0) 503: { 504: // Com_Printf ("\njoystick not found -- driver not present\n\n"); 505: return; 506: } 1.1.1.2 root 507: 1.1 root 508: // cycle through the joystick ids for the first valid one 509: for (joy_id=0 ; joy_id<numdevs ; joy_id++) 510: { 511: memset (&ji, 0, sizeof(ji)); 512: ji.dwSize = sizeof(ji); 513: ji.dwFlags = JOY_RETURNCENTERED; 1.1.1.2 root 514: 1.1 root 515: if ((mmr = joyGetPosEx (joy_id, &ji)) == JOYERR_NOERROR) 516: break; 517: } 1.1.1.2 root 518: 1.1 root 519: // abort startup if we didn't find a valid joystick 520: if (mmr != JOYERR_NOERROR) 521: { 522: Com_Printf ("\njoystick not found -- no valid joysticks (%x)\n\n", mmr); 523: return; 524: } 1.1.1.2 root 525: 1.1 root 526: // get the capabilities of the selected joystick 527: // abort startup if command fails 528: memset (&jc, 0, sizeof(jc)); 529: if ((mmr = joyGetDevCaps (joy_id, &jc, sizeof(jc))) != JOYERR_NOERROR) 530: { 531: Com_Printf ("\njoystick not found -- invalid joystick capabilities (%x)\n\n", mmr); 532: return; 533: } 1.1.1.2 root 534: 1.1 root 535: // save the joystick's number of buttons and POV status 536: joy_numbuttons = jc.wNumButtons; 537: joy_haspov = jc.wCaps & JOYCAPS_HASPOV; 1.1.1.2 root 538: 1.1 root 539: // old button and POV states default to no buttons pressed 540: joy_oldbuttonstate = joy_oldpovstate = 0; 1.1.1.2 root 541: 1.1 root 542: // mark the joystick as available and advanced initialization not completed 543: // this is needed as cvars are not available during initialization 1.1.1.2 root 544: 1.1 root 545: joy_avail = true; 546: joy_advancedinit = false; 1.1.1.2 root 547: 1.1 root 548: Com_Printf ("\njoystick detected\n\n"); 549: } 1.1.1.2 root 550: 551: 1.1 root 552: /* 553: =========== 554: RawValuePointer 555: =========== 556: */ 557: PDWORD RawValuePointer (int axis) 558: { 559: switch (axis) 560: { 561: case JOY_AXIS_X: 562: return &ji.dwXpos; 563: case JOY_AXIS_Y: 564: return &ji.dwYpos; 565: case JOY_AXIS_Z: 566: return &ji.dwZpos; 567: case JOY_AXIS_R: 568: return &ji.dwRpos; 569: case JOY_AXIS_U: 570: return &ji.dwUpos; 571: case JOY_AXIS_V: 572: return &ji.dwVpos; 573: } 574: } 1.1.1.2 root 575: 576: 1.1 root 577: /* 578: =========== 579: Joy_AdvancedUpdate_f 580: =========== 581: */ 582: void Joy_AdvancedUpdate_f (void) 583: { 1.1.1.2 root 584: 1.1 root 585: // called once by IN_ReadJoystick and by user whenever an update is needed 586: // cvars are now available 587: int i; 588: DWORD dwTemp; 1.1.1.2 root 589: 1.1 root 590: // initialize all the maps 591: for (i = 0; i < JOY_MAX_AXES; i++) 592: { 593: dwAxisMap[i] = AxisNada; 594: dwControlMap[i] = JOY_ABSOLUTE_AXIS; 595: pdwRawValue[i] = RawValuePointer(i); 596: } 1.1.1.2 root 597: 1.1 root 598: if( joy_advanced->value == 0.0) 599: { 600: // default joystick initialization 601: // 2 axes only with joystick control 602: dwAxisMap[JOY_AXIS_X] = AxisTurn; 603: // dwControlMap[JOY_AXIS_X] = JOY_ABSOLUTE_AXIS; 604: dwAxisMap[JOY_AXIS_Y] = AxisForward; 605: // dwControlMap[JOY_AXIS_Y] = JOY_ABSOLUTE_AXIS; 606: } 607: else 608: { 609: if (strcmp (joy_name->string, "joystick") != 0) 610: { 611: // notify user of advanced controller 612: Com_Printf ("\n%s configured\n\n", joy_name->string); 613: } 1.1.1.2 root 614: 1.1 root 615: // advanced initialization here 616: // data supplied by user via joy_axisn cvars 617: dwTemp = (DWORD) joy_advaxisx->value; 618: dwAxisMap[JOY_AXIS_X] = dwTemp & 0x0000000f; 619: dwControlMap[JOY_AXIS_X] = dwTemp & JOY_RELATIVE_AXIS; 620: dwTemp = (DWORD) joy_advaxisy->value; 621: dwAxisMap[JOY_AXIS_Y] = dwTemp & 0x0000000f; 622: dwControlMap[JOY_AXIS_Y] = dwTemp & JOY_RELATIVE_AXIS; 623: dwTemp = (DWORD) joy_advaxisz->value; 624: dwAxisMap[JOY_AXIS_Z] = dwTemp & 0x0000000f; 625: dwControlMap[JOY_AXIS_Z] = dwTemp & JOY_RELATIVE_AXIS; 626: dwTemp = (DWORD) joy_advaxisr->value; 627: dwAxisMap[JOY_AXIS_R] = dwTemp & 0x0000000f; 628: dwControlMap[JOY_AXIS_R] = dwTemp & JOY_RELATIVE_AXIS; 629: dwTemp = (DWORD) joy_advaxisu->value; 630: dwAxisMap[JOY_AXIS_U] = dwTemp & 0x0000000f; 631: dwControlMap[JOY_AXIS_U] = dwTemp & JOY_RELATIVE_AXIS; 632: dwTemp = (DWORD) joy_advaxisv->value; 633: dwAxisMap[JOY_AXIS_V] = dwTemp & 0x0000000f; 634: dwControlMap[JOY_AXIS_V] = dwTemp & JOY_RELATIVE_AXIS; 635: } 1.1.1.2 root 636: 1.1 root 637: // compute the axes to collect from DirectInput 638: joy_flags = JOY_RETURNCENTERED | JOY_RETURNBUTTONS | JOY_RETURNPOV; 639: for (i = 0; i < JOY_MAX_AXES; i++) 640: { 641: if (dwAxisMap[i] != AxisNada) 642: { 643: joy_flags |= dwAxisFlags[i]; 644: } 645: } 646: } 1.1.1.2 root 647: 648: 1.1 root 649: /* 650: =========== 651: IN_Commands 652: =========== 653: */ 654: void IN_Commands (void) 655: { 656: int i, key_index; 657: DWORD buttonstate, povstate; 1.1.1.2 root 658: 1.1 root 659: if (!joy_avail) 660: { 661: return; 662: } 1.1.1.2 root 663: 1.1 root 664: 665: // loop through the joystick buttons 666: // key a joystick event or auxillary event for higher number buttons for each state change 667: buttonstate = ji.dwButtons; 668: for (i=0 ; i < joy_numbuttons ; i++) 669: { 670: if ( (buttonstate & (1<<i)) && !(joy_oldbuttonstate & (1<<i)) ) 671: { 672: key_index = (i < 4) ? K_JOY1 : K_AUX1; 673: Key_Event (key_index + i, true, 0); 674: } 1.1.1.2 root 675: 1.1 root 676: if ( !(buttonstate & (1<<i)) && (joy_oldbuttonstate & (1<<i)) ) 677: { 678: key_index = (i < 4) ? K_JOY1 : K_AUX1; 679: Key_Event (key_index + i, false, 0); 680: } 681: } 682: joy_oldbuttonstate = buttonstate; 1.1.1.2 root 683: 1.1 root 684: if (joy_haspov) 685: { 686: // convert POV information into 4 bits of state information 687: // this avoids any potential problems related to moving from one 688: // direction to another without going through the center position 689: povstate = 0; 690: if(ji.dwPOV != JOY_POVCENTERED) 691: { 692: if (ji.dwPOV == JOY_POVFORWARD) 693: povstate |= 0x01; 694: if (ji.dwPOV == JOY_POVRIGHT) 695: povstate |= 0x02; 696: if (ji.dwPOV == JOY_POVBACKWARD) 697: povstate |= 0x04; 698: if (ji.dwPOV == JOY_POVLEFT) 699: povstate |= 0x08; 700: } 701: // determine which bits have changed and key an auxillary event for each change 702: for (i=0 ; i < 4 ; i++) 703: { 704: if ( (povstate & (1<<i)) && !(joy_oldpovstate & (1<<i)) ) 705: { 706: Key_Event (K_AUX29 + i, true, 0); 707: } 1.1.1.2 root 708: 1.1 root 709: if ( !(povstate & (1<<i)) && (joy_oldpovstate & (1<<i)) ) 710: { 711: Key_Event (K_AUX29 + i, false, 0); 712: } 713: } 714: joy_oldpovstate = povstate; 715: } 716: } 1.1.1.2 root 717: 718: 1.1 root 719: /* 720: =============== 721: IN_ReadJoystick 722: =============== 723: */ 724: qboolean IN_ReadJoystick (void) 725: { 1.1.1.2 root 726: 1.1 root 727: memset (&ji, 0, sizeof(ji)); 728: ji.dwSize = sizeof(ji); 729: ji.dwFlags = joy_flags; 1.1.1.2 root 730: 1.1 root 731: if (joyGetPosEx (joy_id, &ji) == JOYERR_NOERROR) 732: { 733: return true; 734: } 735: else 736: { 737: // read error occurred 738: // turning off the joystick seems too harsh for 1 read error,\ 739: // but what should be done? 740: // Com_Printf ("IN_ReadJoystick: no response\n"); 741: // joy_avail = false; 742: return false; 743: } 744: } 1.1.1.2 root 745: 746: 1.1 root 747: /* 748: =========== 749: IN_JoyMove 750: =========== 751: */ 752: void IN_JoyMove (usercmd_t *cmd) 753: { 754: float speed, aspeed; 755: float fAxisValue; 756: int i; 1.1.1.2 root 757: 1.1 root 758: // complete initialization if first time in 759: // this is needed as cvars are not available at initialization time 760: if( joy_advancedinit != true ) 761: { 762: Joy_AdvancedUpdate_f(); 763: joy_advancedinit = true; 764: } 1.1.1.2 root 765: 1.1 root 766: // verify joystick is available and that the user wants to use it 767: if (!joy_avail || !in_joystick->value) 768: { 769: return; 770: } 771: 772: // collect the joystick data, if possible 773: if (IN_ReadJoystick () != true) 774: { 775: return; 776: } 1.1.1.2 root 777: 1.1 root 778: if ( (in_speed.state & 1) ^ (int)cl_run->value) 779: speed = 2; 780: else 781: speed = 1; 782: aspeed = speed * cls.frametime; 1.1.1.2 root 783: 1.1 root 784: // loop through the axes 785: for (i = 0; i < JOY_MAX_AXES; i++) 786: { 787: // get the floating point zero-centered, potentially-inverted data for the current axis 788: fAxisValue = (float) *pdwRawValue[i]; 789: // move centerpoint to zero 790: fAxisValue -= 32768.0; 1.1.1.2 root 791: 1.1 root 792: // convert range from -32768..32767 to -1..1 793: fAxisValue /= 32768.0; 1.1.1.2 root 794: 1.1 root 795: switch (dwAxisMap[i]) 796: { 797: case AxisForward: 798: if ((joy_advanced->value == 0.0) && mlooking) 799: { 800: // user wants forward control to become look control 801: if (fabs(fAxisValue) > joy_pitchthreshold->value) 802: { 803: // if mouse invert is on, invert the joystick pitch value 804: // only absolute control support here (joy_advanced is false) 805: if (m_pitch->value < 0.0) 806: { 807: cl.viewangles[PITCH] -= (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; 808: } 809: else 810: { 811: cl.viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; 812: } 813: } 814: } 815: else 816: { 817: // user wants forward control to be forward control 818: if (fabs(fAxisValue) > joy_forwardthreshold->value) 819: { 820: cmd->forwardmove += (fAxisValue * joy_forwardsensitivity->value) * speed * cl_forwardspeed->value; 821: } 822: } 823: break; 1.1.1.2 root 824: 1.1 root 825: case AxisSide: 826: if (fabs(fAxisValue) > joy_sidethreshold->value) 827: { 828: cmd->sidemove += (fAxisValue * joy_sidesensitivity->value) * speed * cl_sidespeed->value; 829: } 830: break; 831: 832: case AxisUp: 833: if (fabs(fAxisValue) > joy_upthreshold->value) 834: { 835: cmd->upmove += (fAxisValue * joy_upsensitivity->value) * speed * cl_upspeed->value; 836: } 837: break; 1.1.1.2 root 838: 1.1 root 839: case AxisTurn: 840: if ((in_strafe.state & 1) || (lookstrafe->value && mlooking)) 841: { 842: // user wants turn control to become side control 843: if (fabs(fAxisValue) > joy_sidethreshold->value) 844: { 845: cmd->sidemove -= (fAxisValue * joy_sidesensitivity->value) * speed * cl_sidespeed->value; 846: } 847: } 848: else 849: { 850: // user wants turn control to be turn control 851: if (fabs(fAxisValue) > joy_yawthreshold->value) 852: { 853: if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) 854: { 855: cl.viewangles[YAW] += (fAxisValue * joy_yawsensitivity->value) * aspeed * cl_yawspeed->value; 856: } 857: else 858: { 859: cl.viewangles[YAW] += (fAxisValue * joy_yawsensitivity->value) * speed * 180.0; 860: } 1.1.1.2 root 861: 1.1 root 862: } 863: } 864: break; 1.1.1.2 root 865: 1.1 root 866: case AxisLook: 867: if (mlooking) 868: { 869: if (fabs(fAxisValue) > joy_pitchthreshold->value) 870: { 871: // pitch movement detected and pitch movement desired by user 872: if(dwControlMap[i] == JOY_ABSOLUTE_AXIS) 873: { 874: cl.viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * aspeed * cl_pitchspeed->value; 875: } 876: else 877: { 878: cl.viewangles[PITCH] += (fAxisValue * joy_pitchsensitivity->value) * speed * 180.0; 879: } 880: } 881: } 882: break; 1.1.1.2 root 883: 1.1 root 884: default: 885: break; 886: } 887: } 888: } 1.1.1.2 root 889:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.