Annotation of quake2/win32/in_win.c, revision 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.