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