Annotation of quake2/win32/in_win.c, revision 1.1.1.1

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 (&current_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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.