Annotation of quake2/client/cl_input.c, revision 1.1.1.2

1.1       root        1: // cl.input.c  -- builds an intended movement command to send to the server
                      2: 
                      3: #include "client.h"
                      4: 
                      5: cvar_t *cl_nodelta;
                      6: 
                      7: extern unsigned        sys_frame_time;
                      8: unsigned       frame_msec;
                      9: unsigned       old_sys_frame_time;
                     10: 
                     11: /*
                     12: ===============================================================================
                     13: 
                     14: KEY BUTTONS
                     15: 
                     16: Continuous button event tracking is complicated by the fact that two different
                     17: input sources (say, mouse button 1 and the control key) can both press the
                     18: same button, but the button should only be released when both of the
                     19: pressing key have been released.
                     20: 
                     21: When a key event issues a button command (+forward, +attack, etc), it appends
                     22: its key number as a parameter to the command so it can be matched up with
                     23: the release.
                     24: 
                     25: state bit 0 is the current state of the key
                     26: state bit 1 is edge triggered on the up to down transition
                     27: state bit 2 is edge triggered on the down to up transition
                     28: 
                     29: 
                     30: Key_Event (int key, qboolean down, unsigned time);
                     31: 
                     32:   +mlook src time
                     33: 
                     34: ===============================================================================
                     35: */
                     36: 
                     37: 
                     38: kbutton_t      in_klook;
                     39: kbutton_t      in_left, in_right, in_forward, in_back;
                     40: kbutton_t      in_lookup, in_lookdown, in_moveleft, in_moveright;
                     41: kbutton_t      in_strafe, in_speed, in_use, in_attack;
                     42: kbutton_t      in_up, in_down;
                     43: 
                     44: int                    in_impulse;
                     45: 
                     46: 
                     47: void KeyDown (kbutton_t *b)
                     48: {
                     49:        int             k;
                     50:        char    *c;
                     51:        
                     52:        c = Cmd_Argv(1);
                     53:        if (c[0])
                     54:                k = atoi(c);
                     55:        else
                     56:                k = -1;         // typed manually at the console for continuous down
                     57: 
                     58:        if (k == b->down[0] || k == b->down[1])
                     59:                return;         // repeating key
                     60:        
                     61:        if (!b->down[0])
                     62:                b->down[0] = k;
                     63:        else if (!b->down[1])
                     64:                b->down[1] = k;
                     65:        else
                     66:        {
                     67:                Com_Printf ("Three keys down for a button!\n");
                     68:                return;
                     69:        }
                     70:        
                     71:        if (b->state & 1)
                     72:                return;         // still down
                     73: 
                     74:        // save timestamp
                     75:        c = Cmd_Argv(2);
                     76:        b->downtime = atoi(c);
                     77:        if (!b->downtime)
                     78:                b->downtime = sys_frame_time - 100;
                     79: 
                     80:        b->state |= 1 + 2;      // down + impulse down
                     81: }
                     82: 
                     83: void KeyUp (kbutton_t *b)
                     84: {
                     85:        int             k;
                     86:        char    *c;
                     87:        unsigned        uptime;
                     88: 
                     89:        c = Cmd_Argv(1);
                     90:        if (c[0])
                     91:                k = atoi(c);
                     92:        else
                     93:        { // typed manually at the console, assume for unsticking, so clear all
                     94:                b->down[0] = b->down[1] = 0;
                     95:                b->state = 4;   // impulse up
                     96:                return;
                     97:        }
                     98: 
                     99:        if (b->down[0] == k)
                    100:                b->down[0] = 0;
                    101:        else if (b->down[1] == k)
                    102:                b->down[1] = 0;
                    103:        else
                    104:                return;         // key up without coresponding down (menu pass through)
                    105:        if (b->down[0] || b->down[1])
                    106:                return;         // some other key is still holding it down
                    107: 
                    108:        if (!(b->state & 1))
                    109:                return;         // still up (this should not happen)
                    110: 
                    111:        // save timestamp
                    112:        c = Cmd_Argv(2);
                    113:        uptime = atoi(c);
                    114:        if (uptime)
                    115:                b->msec += uptime - b->downtime;
                    116:        else
                    117:                b->msec += 10;
                    118: 
                    119:        b->state &= ~1;         // now up
                    120:        b->state |= 4;          // impulse up
                    121: }
                    122: 
                    123: void IN_KLookDown (void) {KeyDown(&in_klook);}
                    124: void IN_KLookUp (void) {KeyUp(&in_klook);}
                    125: void IN_UpDown(void) {KeyDown(&in_up);}
                    126: void IN_UpUp(void) {KeyUp(&in_up);}
                    127: void IN_DownDown(void) {KeyDown(&in_down);}
                    128: void IN_DownUp(void) {KeyUp(&in_down);}
                    129: void IN_LeftDown(void) {KeyDown(&in_left);}
                    130: void IN_LeftUp(void) {KeyUp(&in_left);}
                    131: void IN_RightDown(void) {KeyDown(&in_right);}
                    132: void IN_RightUp(void) {KeyUp(&in_right);}
                    133: void IN_ForwardDown(void) {KeyDown(&in_forward);}
                    134: void IN_ForwardUp(void) {KeyUp(&in_forward);}
                    135: void IN_BackDown(void) {KeyDown(&in_back);}
                    136: void IN_BackUp(void) {KeyUp(&in_back);}
                    137: void IN_LookupDown(void) {KeyDown(&in_lookup);}
                    138: void IN_LookupUp(void) {KeyUp(&in_lookup);}
                    139: void IN_LookdownDown(void) {KeyDown(&in_lookdown);}
                    140: void IN_LookdownUp(void) {KeyUp(&in_lookdown);}
                    141: void IN_MoveleftDown(void) {KeyDown(&in_moveleft);}
                    142: void IN_MoveleftUp(void) {KeyUp(&in_moveleft);}
                    143: void IN_MoverightDown(void) {KeyDown(&in_moveright);}
                    144: void IN_MoverightUp(void) {KeyUp(&in_moveright);}
                    145: 
                    146: void IN_SpeedDown(void) {KeyDown(&in_speed);}
                    147: void IN_SpeedUp(void) {KeyUp(&in_speed);}
                    148: void IN_StrafeDown(void) {KeyDown(&in_strafe);}
                    149: void IN_StrafeUp(void) {KeyUp(&in_strafe);}
                    150: 
                    151: void IN_AttackDown(void) {KeyDown(&in_attack);}
                    152: void IN_AttackUp(void) {KeyUp(&in_attack);}
                    153: 
                    154: void IN_UseDown (void) {KeyDown(&in_use);}
                    155: void IN_UseUp (void) {KeyUp(&in_use);}
                    156: 
                    157: void IN_Impulse (void) {in_impulse=atoi(Cmd_Argv(1));}
                    158: 
                    159: /*
                    160: ===============
                    161: CL_KeyState
                    162: 
                    163: Returns the fraction of the frame that the key was down
                    164: ===============
                    165: */
                    166: float CL_KeyState (kbutton_t *key)
                    167: {
                    168:        float           val;
                    169:        int                     msec;
                    170: 
                    171:        key->state &= 1;                // clear impulses
                    172: 
                    173:        msec = key->msec;
                    174:        key->msec = 0;
                    175: 
                    176:        if (key->state)
                    177:        {       // still down
                    178:                msec += sys_frame_time - key->downtime;
                    179:                key->downtime = sys_frame_time;
                    180:        }
                    181: 
                    182: #if 0
                    183:        if (msec)
                    184:        {
                    185:                Com_Printf ("%i ", msec);
                    186:        }
                    187: #endif
                    188: 
                    189:        val = (float)msec / frame_msec;
                    190:        if (val < 0)
                    191:                val = 0;
                    192:        if (val > 1)
                    193:                val = 1;
                    194: 
                    195:        return val;
                    196: }
                    197: 
                    198: 
                    199: 
                    200: 
                    201: //==========================================================================
                    202: 
                    203: cvar_t *cl_upspeed;
                    204: cvar_t *cl_forwardspeed;
                    205: cvar_t *cl_sidespeed;
                    206: 
                    207: cvar_t *cl_yawspeed;
                    208: cvar_t *cl_pitchspeed;
                    209: 
                    210: cvar_t *cl_run;
                    211: 
                    212: cvar_t *cl_anglespeedkey;
                    213: 
                    214: 
                    215: /*
                    216: ================
                    217: CL_AdjustAngles
                    218: 
                    219: Moves the local angle positions
                    220: ================
                    221: */
                    222: void CL_AdjustAngles (void)
                    223: {
                    224:        float   speed;
                    225:        float   up, down;
                    226:        
                    227:        if (in_speed.state & 1)
                    228:                speed = cls.frametime * cl_anglespeedkey->value;
                    229:        else
                    230:                speed = cls.frametime;
                    231: 
                    232:        if (!(in_strafe.state & 1))
                    233:        {
                    234:                cl.viewangles[YAW] -= speed*cl_yawspeed->value*CL_KeyState (&in_right);
                    235:                cl.viewangles[YAW] += speed*cl_yawspeed->value*CL_KeyState (&in_left);
                    236:        }
                    237:        if (in_klook.state & 1)
                    238:        {
                    239:                cl.viewangles[PITCH] -= speed*cl_pitchspeed->value * CL_KeyState (&in_forward);
                    240:                cl.viewangles[PITCH] += speed*cl_pitchspeed->value * CL_KeyState (&in_back);
                    241:        }
                    242:        
                    243:        up = CL_KeyState (&in_lookup);
                    244:        down = CL_KeyState(&in_lookdown);
                    245:        
                    246:        cl.viewangles[PITCH] -= speed*cl_pitchspeed->value * up;
                    247:        cl.viewangles[PITCH] += speed*cl_pitchspeed->value * down;
                    248: }
                    249: 
                    250: /*
                    251: ================
                    252: CL_BaseMove
                    253: 
                    254: Send the intended movement message to the server
                    255: ================
                    256: */
                    257: void CL_BaseMove (usercmd_t *cmd)
                    258: {      
                    259:        CL_AdjustAngles ();
                    260:        
                    261:        memset (cmd, 0, sizeof(*cmd));
                    262:        
                    263:        VectorCopy (cl.viewangles, cmd->angles);
                    264:        if (in_strafe.state & 1)
                    265:        {
                    266:                cmd->sidemove += cl_sidespeed->value * CL_KeyState (&in_right);
                    267:                cmd->sidemove -= cl_sidespeed->value * CL_KeyState (&in_left);
                    268:        }
                    269: 
                    270:        cmd->sidemove += cl_sidespeed->value * CL_KeyState (&in_moveright);
                    271:        cmd->sidemove -= cl_sidespeed->value * CL_KeyState (&in_moveleft);
                    272: 
                    273:        cmd->upmove += cl_upspeed->value * CL_KeyState (&in_up);
                    274:        cmd->upmove -= cl_upspeed->value * CL_KeyState (&in_down);
                    275: 
                    276:        if (! (in_klook.state & 1) )
                    277:        {       
                    278:                cmd->forwardmove += cl_forwardspeed->value * CL_KeyState (&in_forward);
                    279:                cmd->forwardmove -= cl_forwardspeed->value * CL_KeyState (&in_back);
                    280:        }       
                    281: 
                    282: //
                    283: // adjust for speed key / running
                    284: //
                    285:        if ( (in_speed.state & 1) ^ (int)(cl_run->value) )
                    286:        {
                    287:                cmd->forwardmove *= 2;
                    288:                cmd->sidemove *= 2;
                    289:                cmd->upmove *= 2;
                    290:        }       
                    291: }
                    292: 
                    293: void CL_ClampPitch (void)
                    294: {
                    295:        float   pitch;
                    296: 
                    297:        pitch = SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[PITCH]);
                    298:        if (pitch > 180)
                    299:                pitch -= 360;
                    300:        if (cl.viewangles[PITCH] + pitch > 89)
                    301:                cl.viewangles[PITCH] = 89 - pitch;
                    302:        if (cl.viewangles[PITCH] + pitch < -89)
                    303:                cl.viewangles[PITCH] = -89 - pitch;
                    304: }
                    305: 
                    306: /*
                    307: ==============
                    308: CL_FinishMove
                    309: ==============
                    310: */
                    311: void CL_FinishMove (usercmd_t *cmd)
                    312: {
                    313:        int             ms;
                    314:        int             i;
                    315: 
                    316: //
                    317: // figure button bits
                    318: //     
                    319:        if ( in_attack.state & 3 )
                    320:                cmd->buttons |= BUTTON_ATTACK;
                    321:        in_attack.state &= ~2;
                    322:        
                    323:        if (in_use.state & 3)
                    324:                cmd->buttons |= BUTTON_USE;
                    325:        in_use.state &= ~2;
                    326: 
                    327:        if (anykeydown && cls.key_dest == key_game)
                    328:                cmd->buttons |= BUTTON_ANY;
                    329: 
                    330:        // send milliseconds of time to apply the move
                    331:        ms = cls.frametime * 1000;
                    332:        if (ms > 250)
                    333:                ms = 100;               // time was unreasonable
                    334:        cmd->msec = ms;
                    335: 
                    336:        CL_ClampPitch ();
                    337:        for (i=0 ; i<3 ; i++)
                    338:                cmd->angles[i] = ANGLE2SHORT(cl.viewangles[i]);
                    339: 
                    340:        cmd->impulse = in_impulse;
                    341:        in_impulse = 0;
                    342: 
                    343: // send the ambient light level at the player's current position
                    344:        cmd->lightlevel = (byte)cl_lightlevel->value;
                    345: }
                    346: 
                    347: /*
                    348: =================
                    349: CL_CreateCmd
                    350: =================
                    351: */
                    352: usercmd_t CL_CreateCmd (void)
                    353: {
                    354:        usercmd_t       cmd;
                    355: 
                    356:        frame_msec = sys_frame_time - old_sys_frame_time;
                    357:        if (frame_msec < 1)
                    358:                frame_msec = 1;
                    359:        if (frame_msec > 200)
                    360:                frame_msec = 200;
                    361:        
                    362:        // get basic movement from keyboard
                    363:        CL_BaseMove (&cmd);
                    364: 
                    365:        // allow mice or other external controllers to add to the move
                    366:        IN_Move (&cmd);
                    367: 
                    368:        CL_FinishMove (&cmd);
                    369: 
                    370:        old_sys_frame_time = sys_frame_time;
                    371: 
                    372: //cmd.impulse = cls.framecount;
                    373: 
                    374:        return cmd;
                    375: }
                    376: 
                    377: 
                    378: void IN_CenterView (void)
                    379: {
                    380:        cl.viewangles[PITCH] = -SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[PITCH]);
                    381: }
                    382: 
                    383: /*
                    384: ============
                    385: CL_InitInput
                    386: ============
                    387: */
                    388: void CL_InitInput (void)
                    389: {
                    390:        Cmd_AddCommand ("centerview",IN_CenterView);
                    391: 
                    392:        Cmd_AddCommand ("+moveup",IN_UpDown);
                    393:        Cmd_AddCommand ("-moveup",IN_UpUp);
                    394:        Cmd_AddCommand ("+movedown",IN_DownDown);
                    395:        Cmd_AddCommand ("-movedown",IN_DownUp);
                    396:        Cmd_AddCommand ("+left",IN_LeftDown);
                    397:        Cmd_AddCommand ("-left",IN_LeftUp);
                    398:        Cmd_AddCommand ("+right",IN_RightDown);
                    399:        Cmd_AddCommand ("-right",IN_RightUp);
                    400:        Cmd_AddCommand ("+forward",IN_ForwardDown);
                    401:        Cmd_AddCommand ("-forward",IN_ForwardUp);
                    402:        Cmd_AddCommand ("+back",IN_BackDown);
                    403:        Cmd_AddCommand ("-back",IN_BackUp);
                    404:        Cmd_AddCommand ("+lookup", IN_LookupDown);
                    405:        Cmd_AddCommand ("-lookup", IN_LookupUp);
                    406:        Cmd_AddCommand ("+lookdown", IN_LookdownDown);
                    407:        Cmd_AddCommand ("-lookdown", IN_LookdownUp);
                    408:        Cmd_AddCommand ("+strafe", IN_StrafeDown);
                    409:        Cmd_AddCommand ("-strafe", IN_StrafeUp);
                    410:        Cmd_AddCommand ("+moveleft", IN_MoveleftDown);
                    411:        Cmd_AddCommand ("-moveleft", IN_MoveleftUp);
                    412:        Cmd_AddCommand ("+moveright", IN_MoverightDown);
                    413:        Cmd_AddCommand ("-moveright", IN_MoverightUp);
                    414:        Cmd_AddCommand ("+speed", IN_SpeedDown);
                    415:        Cmd_AddCommand ("-speed", IN_SpeedUp);
                    416:        Cmd_AddCommand ("+attack", IN_AttackDown);
                    417:        Cmd_AddCommand ("-attack", IN_AttackUp);
                    418:        Cmd_AddCommand ("+use", IN_UseDown);
                    419:        Cmd_AddCommand ("-use", IN_UseUp);
                    420:        Cmd_AddCommand ("impulse", IN_Impulse);
                    421:        Cmd_AddCommand ("+klook", IN_KLookDown);
                    422:        Cmd_AddCommand ("-klook", IN_KLookUp);
                    423: 
                    424:        cl_nodelta = Cvar_Get ("cl_nodelta", "0", 0);
                    425: }
                    426: 
                    427: 
                    428: 
                    429: /*
                    430: =================
                    431: CL_SendCmd
                    432: =================
                    433: */
                    434: void CL_SendCmd (void)
                    435: {
                    436:        sizebuf_t       buf;
                    437:        byte            data[128];
                    438:        int                     i;
                    439:        usercmd_t       *cmd, *oldcmd;
                    440:        usercmd_t       nullcmd;
                    441:        int                     checksumIndex;
                    442: 
                    443:        // build a command even if not connected
                    444: 
                    445:        // save this command off for prediction
                    446:        i = cls.netchan.outgoing_sequence & (CMD_BACKUP-1);
                    447:        cmd = &cl.cmds[i];
                    448:        cl.cmd_time[i] = cls.realtime;  // for netgraph ping calculation
                    449: 
                    450:        *cmd = CL_CreateCmd ();
                    451: 
                    452:        cl.cmd = *cmd;
                    453: 
                    454:        if (cls.state == ca_disconnected || cls.state == ca_connecting)
                    455:                return;
                    456: 
                    457:        if ( cls.state == ca_connected)
                    458:        {
                    459:                if (cls.netchan.message.cursize || curtime - cls.netchan.last_sent > 1000 )
                    460:                        Netchan_Transmit (&cls.netchan, 0, buf.data);   
                    461:                return;
                    462:        }
                    463: 
                    464:        // send a userinfo update if needed
                    465:        if (userinfo_modified)
                    466:        {
1.1.1.2 ! root      467:                CL_FixUpGender();
1.1       root      468:                userinfo_modified = false;
                    469:                MSG_WriteByte (&cls.netchan.message, clc_userinfo);
                    470:                MSG_WriteString (&cls.netchan.message, Cvar_Userinfo() );
                    471:        }
                    472: 
                    473:        SZ_Init (&buf, data, sizeof(data));
                    474: 
                    475:        if (cmd->buttons && cl.cinematictime > 0 && !cl.attractloop 
                    476:                && cls.realtime - cl.cinematictime > 1000)
                    477:        {       // skip the rest of the cinematic
                    478:                SCR_FinishCinematic ();
                    479:        }
                    480: 
                    481:        // begin a client move command
                    482:        MSG_WriteByte (&buf, clc_move);
                    483: 
                    484:        // save the position for a checksum byte
                    485:        checksumIndex = buf.cursize;
                    486:        MSG_WriteByte (&buf, 0);
                    487: 
                    488:        // let the server know what the last frame we
                    489:        // got was, so the next message can be delta compressed
                    490:        if (cl_nodelta->value || !cl.frame.valid || cls.demowaiting)
                    491:                MSG_WriteLong (&buf, -1);       // no compression
                    492:        else
                    493:                MSG_WriteLong (&buf, cl.frame.serverframe);
                    494: 
                    495:        // send this and the previous cmds in the message, so
                    496:        // if the last packet was dropped, it can be recovered
                    497:        i = (cls.netchan.outgoing_sequence-2) & (CMD_BACKUP-1);
                    498:        cmd = &cl.cmds[i];
                    499:        memset (&nullcmd, 0, sizeof(nullcmd));
                    500:        MSG_WriteDeltaUsercmd (&buf, &nullcmd, cmd);
                    501:        oldcmd = cmd;
                    502: 
                    503:        i = (cls.netchan.outgoing_sequence-1) & (CMD_BACKUP-1);
                    504:        cmd = &cl.cmds[i];
                    505:        MSG_WriteDeltaUsercmd (&buf, oldcmd, cmd);
                    506:        oldcmd = cmd;
                    507: 
                    508:        i = (cls.netchan.outgoing_sequence) & (CMD_BACKUP-1);
                    509:        cmd = &cl.cmds[i];
                    510:        MSG_WriteDeltaUsercmd (&buf, oldcmd, cmd);
                    511: 
                    512:        // calculate a checksum over the move commands
1.1.1.2 ! root      513:        buf.data[checksumIndex] = COM_BlockSequenceCRCByte(
1.1       root      514:                buf.data + checksumIndex + 1, buf.cursize - checksumIndex - 1,
                    515:                cls.netchan.outgoing_sequence);
                    516: 
                    517:        //
                    518:        // deliver the message
                    519:        //
                    520:        Netchan_Transmit (&cls.netchan, buf.cursize, buf.data); 
                    521: }
                    522: 
                    523: 

unix.superglobalmegacorp.com

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