Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
  12.  
  13. See the GNU General Public License for more details.
  14.  
  15. You should have received a copy of the GNU General Public License
  16. along with this program; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  
  19. */
  20. // cl.input.c  -- builds an intended movement command to send to the server
  21.  
  22. // Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All
  23. // rights reserved.
  24.  
  25. #include "quakedef.h"
  26.  
  27. /*
  28. ===============================================================================
  29.  
  30. KEY BUTTONS
  31.  
  32. Continuous button event tracking is complicated by the fact that two different
  33. input sources (say, mouse button 1 and the control key) can both press the
  34. same button, but the button should only be released when both of the
  35. pressing key have been released.
  36.  
  37. When a key event issues a button command (+forward, +attack, etc), it appends
  38. its key number as a parameter to the command so it can be matched up with
  39. the release.
  40.  
  41. state bit 0 is the current state of the key
  42. state bit 1 is edge triggered on the up to down transition
  43. state bit 2 is edge triggered on the down to up transition
  44.  
  45. ===============================================================================
  46. */
  47.  
  48.  
  49. kbutton_t       in_mlook, in_klook;
  50. kbutton_t       in_left, in_right, in_forward, in_back;
  51. kbutton_t       in_lookup, in_lookdown, in_moveleft, in_moveright;
  52. kbutton_t       in_strafe, in_speed, in_use, in_jump, in_attack;
  53. kbutton_t       in_up, in_down;
  54.  
  55. int                     in_impulse;
  56.  
  57.  
  58. void KeyDown (kbutton_t *b)
  59. {
  60.         int             k;
  61.         char    *c;
  62.  
  63.         c = Cmd_Argv(1);
  64.         if (c[0])
  65.                 k = atoi(c);
  66.         else
  67.                 k = -1;         // typed manually at the console for continuous down
  68.  
  69.         if (k == b->down[0] || k == b->down[1])
  70.                 return;         // repeating key
  71.        
  72.         if (!b->down[0])
  73.                 b->down[0] = k;
  74.         else if (!b->down[1])
  75.                 b->down[1] = k;
  76.         else
  77.         {
  78.                 Con_Printf ("Three keys down for a button!\n");
  79.                 return;
  80.         }
  81.        
  82.         if (b->state & 1)
  83.                 return;         // still down
  84.         b->state |= 1 + 2;      // down + impulse down
  85. }
  86.  
  87. void KeyUp (kbutton_t *b)
  88. {
  89.         int             k;
  90.         char    *c;
  91.        
  92.         c = Cmd_Argv(1);
  93.         if (c[0])
  94.                 k = atoi(c);
  95.         else
  96.         { // typed manually at the console, assume for unsticking, so clear all
  97.                 b->down[0] = b->down[1] = 0;
  98.                 b->state = 4;   // impulse up
  99.                 return;
  100.         }
  101.  
  102.         if (b->down[0] == k)
  103.                 b->down[0] = 0;
  104.         else if (b->down[1] == k)
  105.                 b->down[1] = 0;
  106.         else
  107.                 return;         // key up without coresponding down (menu pass through)
  108.         if (b->down[0] || b->down[1])
  109.                 return;         // some other key is still holding it down
  110.  
  111.         if (!(b->state & 1))
  112.                 return;         // still up (this should not happen)
  113.         b->state &= ~1;         // now up
  114.         b->state |= 4;          // impulse up
  115. }
  116.  
  117. void IN_KLookDown (void) {KeyDown(&in_klook);}
  118. void IN_KLookUp (void) {KeyUp(&in_klook);}
  119. void IN_MLookDown (void) {KeyDown(&in_mlook);}
  120. void IN_MLookUp (void) {
  121. KeyUp(&in_mlook);
  122. if ( !(in_mlook.state&1) &&  lookspring.value)
  123.         V_StartPitchDrift();
  124. }
  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. void IN_JumpDown (void) {KeyDown(&in_jump);}
  157. void IN_JumpUp (void) {KeyUp(&in_jump);}
  158.  
  159. void IN_Impulse (void) {in_impulse=Q_atoi(Cmd_Argv(1));}
  160.  
  161. /*
  162. ===============
  163. CL_KeyState
  164.  
  165. Returns 0.25 if a key was pressed and released during the frame,
  166. 0.5 if it was pressed and held
  167. 0 if held then released, and
  168. 1.0 if held for the entire time
  169. ===============
  170. */
  171. float CL_KeyState (kbutton_t *key)
  172. {
  173.         float           val;
  174.         qboolean        impulsedown, impulseup, down;
  175.        
  176.         impulsedown = key->state & 2;
  177.         impulseup = key->state & 4;
  178.         down = key->state & 1;
  179.         val = 0;
  180.        
  181.         if (impulsedown && !impulseup)
  182.                 if (down)
  183.                         val = 0.5;      // pressed and held this frame
  184.                 else
  185.                         val = 0;        //      I_Error ();
  186.         if (impulseup && !impulsedown)
  187.                 if (down)
  188.                         val = 0;        //      I_Error ();
  189.                 else
  190.                         val = 0;        // released this frame
  191.         if (!impulsedown && !impulseup)
  192.                 if (down)
  193.                         val = 1.0;      // held the entire frame
  194.                 else
  195.                         val = 0;        // up the entire frame
  196.         if (impulsedown && impulseup)
  197.                 if (down)
  198.                         val = 0.75;     // released and re-pressed this frame
  199.                 else
  200.                         val = 0.25;     // pressed and released this frame
  201.  
  202.         key->state &= 1;                // clear impulses
  203.        
  204.         return val;
  205. }
  206.  
  207.  
  208.  
  209.  
  210. //==========================================================================
  211.  
  212. cvar_t  cl_upspeed = {"cl_upspeed","200"};
  213. cvar_t  cl_forwardspeed = {"cl_forwardspeed","200", true};
  214. cvar_t  cl_backspeed = {"cl_backspeed","200", true};
  215. cvar_t  cl_sidespeed = {"cl_sidespeed","350"};
  216.  
  217. cvar_t  cl_movespeedkey = {"cl_movespeedkey","2.0"};
  218.  
  219. cvar_t  cl_yawspeed = {"cl_yawspeed","140"};
  220. cvar_t  cl_pitchspeed = {"cl_pitchspeed","150"};
  221.  
  222. cvar_t  cl_anglespeedkey = {"cl_anglespeedkey","1.5"};
  223.  
  224.  
  225. /*
  226. ================
  227. CL_AdjustAngles
  228.  
  229. Moves the local angle positions
  230. ================
  231. */
  232. void CL_AdjustAngles (void)
  233. {
  234.         float   speed;
  235.         float   up, down;
  236.        
  237.         if (in_speed.state & 1)
  238.                 speed = host_frametime * cl_anglespeedkey.value;
  239.         else
  240.                 speed = host_frametime;
  241.  
  242.         if (!(in_strafe.state & 1))
  243.         {
  244.                 cl.viewangles[YAW] -= speed*cl_yawspeed.value*CL_KeyState (&in_right);
  245.                 cl.viewangles[YAW] += speed*cl_yawspeed.value*CL_KeyState (&in_left);
  246.                 cl.viewangles[YAW] = anglemod(cl.viewangles[YAW]);
  247.         }
  248.         if (in_klook.state & 1)
  249.         {
  250.                 V_StopPitchDrift ();
  251.                 cl.viewangles[PITCH] -= speed*cl_pitchspeed.value * CL_KeyState (&in_forward);
  252.                 cl.viewangles[PITCH] += speed*cl_pitchspeed.value * CL_KeyState (&in_back);
  253.         }
  254.        
  255.         up = CL_KeyState (&in_lookup);
  256.         down = CL_KeyState(&in_lookdown);
  257.        
  258.         cl.viewangles[PITCH] -= speed*cl_pitchspeed.value * up;
  259.         cl.viewangles[PITCH] += speed*cl_pitchspeed.value * down;
  260.  
  261.         if (up || down)
  262.                 V_StopPitchDrift ();
  263.                
  264.         if (cl.viewangles[PITCH] > 80)
  265.                 cl.viewangles[PITCH] = 80;
  266.         if (cl.viewangles[PITCH] < -70)
  267.                 cl.viewangles[PITCH] = -70;
  268.  
  269.         if (cl.viewangles[ROLL] > 50)
  270.                 cl.viewangles[ROLL] = 50;
  271.         if (cl.viewangles[ROLL] < -50)
  272.                 cl.viewangles[ROLL] = -50;
  273.                
  274. }
  275.  
  276. /*
  277. ================
  278. CL_BaseMove
  279.  
  280. Send the intended movement message to the server
  281. ================
  282. */
  283. void CL_BaseMove (usercmd_t *cmd)
  284. {      
  285.         if (cls.signon != SIGNONS)
  286.                 return;
  287.                        
  288.         CL_AdjustAngles ();
  289.        
  290.         Q_memset (cmd, 0, sizeof(*cmd));
  291.        
  292.         if (in_strafe.state & 1)
  293.         {
  294.                 cmd->sidemove += cl_sidespeed.value * CL_KeyState (&in_right);
  295.                 cmd->sidemove -= cl_sidespeed.value * CL_KeyState (&in_left);
  296.         }
  297.  
  298.         cmd->sidemove += cl_sidespeed.value * CL_KeyState (&in_moveright);
  299.         cmd->sidemove -= cl_sidespeed.value * CL_KeyState (&in_moveleft);
  300.  
  301.         cmd->upmove += cl_upspeed.value * CL_KeyState (&in_up);
  302.         cmd->upmove -= cl_upspeed.value * CL_KeyState (&in_down);
  303.  
  304.         if (! (in_klook.state & 1) )
  305.         {      
  306.                 cmd->forwardmove += cl_forwardspeed.value * CL_KeyState (&in_forward);
  307.                 cmd->forwardmove -= cl_backspeed.value * CL_KeyState (&in_back);
  308.         }      
  309.  
  310. //
  311. // adjust for speed key
  312. //
  313.         if (in_speed.state & 1)
  314.         {
  315.                 cmd->forwardmove *= cl_movespeedkey.value;
  316.                 cmd->sidemove *= cl_movespeedkey.value;
  317.                 cmd->upmove *= cl_movespeedkey.value;
  318.         }
  319.  
  320. #ifdef QUAKE2
  321.         cmd->lightlevel = cl.light_level;
  322. #endif
  323. }
  324.  
  325.  
  326.  
  327. /*
  328. ==============
  329. CL_SendMove
  330. ==============
  331. */
  332. void CL_SendMove (usercmd_t *cmd)
  333. {
  334.         int             i;
  335.         int             bits;
  336.         sizebuf_t       buf;
  337.         byte    data[128];
  338.        
  339.         buf.maxsize = 128;
  340.         buf.cursize = 0;
  341.         buf.data = data;
  342.        
  343.         cl.cmd = *cmd;
  344.  
  345. //
  346. // send the movement message
  347. //
  348.     MSG_WriteByte (&buf, clc_move);
  349.  
  350.         MSG_WriteFloat (&buf, cl.mtime[0]);     // so server can get ping times
  351.  
  352.         for (i=0 ; i<3 ; i++)
  353.                 MSG_WriteAngle (&buf, cl.viewangles[i]);
  354.        
  355.     MSG_WriteShort (&buf, cmd->forwardmove);
  356.     MSG_WriteShort (&buf, cmd->sidemove);
  357.     MSG_WriteShort (&buf, cmd->upmove);
  358.  
  359. //
  360. // send button bits
  361. //
  362.         bits = 0;
  363.        
  364.         if ( in_attack.state & 3 )
  365.                 bits |= 1;
  366.         in_attack.state &= ~2;
  367.        
  368.         if (in_jump.state & 3)
  369.                 bits |= 2;
  370.         in_jump.state &= ~2;
  371.        
  372.     MSG_WriteByte (&buf, bits);
  373.  
  374.     MSG_WriteByte (&buf, in_impulse);
  375.         in_impulse = 0;
  376.  
  377. #ifdef QUAKE2
  378. //
  379. // light level
  380. //
  381.         MSG_WriteByte (&buf, cmd->lightlevel);
  382. #endif
  383.  
  384. //
  385. // deliver the message
  386. //
  387.         if (cls.demoplayback)
  388.                 return;
  389.  
  390. //
  391. // allways dump the first two message, because it may contain leftover inputs
  392. // from the last level
  393. //
  394.         if (++cl.movemessages <= 2)
  395.                 return;
  396.        
  397.         if (NET_SendUnreliableMessage (cls.netcon, &buf) == -1)
  398.         {
  399.                 Con_Printf ("CL_SendMove: lost server connection\n");
  400.                 CL_Disconnect ();
  401.         }
  402. }
  403.  
  404. /*
  405. ============
  406. CL_InitInput
  407. ============
  408. */
  409. void CL_InitInput (void)
  410. {
  411.         Cmd_AddCommand ("+moveup",IN_UpDown);
  412.         Cmd_AddCommand ("-moveup",IN_UpUp);
  413.         Cmd_AddCommand ("+movedown",IN_DownDown);
  414.         Cmd_AddCommand ("-movedown",IN_DownUp);
  415.         Cmd_AddCommand ("+left",IN_LeftDown);
  416.         Cmd_AddCommand ("-left",IN_LeftUp);
  417.         Cmd_AddCommand ("+right",IN_RightDown);
  418.         Cmd_AddCommand ("-right",IN_RightUp);
  419.         Cmd_AddCommand ("+forward",IN_ForwardDown);
  420.         Cmd_AddCommand ("-forward",IN_ForwardUp);
  421.         Cmd_AddCommand ("+back",IN_BackDown);
  422.         Cmd_AddCommand ("-back",IN_BackUp);
  423.         Cmd_AddCommand ("+lookup", IN_LookupDown);
  424.         Cmd_AddCommand ("-lookup", IN_LookupUp);
  425.         Cmd_AddCommand ("+lookdown", IN_LookdownDown);
  426.         Cmd_AddCommand ("-lookdown", IN_LookdownUp);
  427.         Cmd_AddCommand ("+strafe", IN_StrafeDown);
  428.         Cmd_AddCommand ("-strafe", IN_StrafeUp);
  429.         Cmd_AddCommand ("+moveleft", IN_MoveleftDown);
  430.         Cmd_AddCommand ("-moveleft", IN_MoveleftUp);
  431.         Cmd_AddCommand ("+moveright", IN_MoverightDown);
  432.         Cmd_AddCommand ("-moveright", IN_MoverightUp);
  433.         Cmd_AddCommand ("+speed", IN_SpeedDown);
  434.         Cmd_AddCommand ("-speed", IN_SpeedUp);
  435.         Cmd_AddCommand ("+attack", IN_AttackDown);
  436.         Cmd_AddCommand ("-attack", IN_AttackUp);
  437.         Cmd_AddCommand ("+use", IN_UseDown);
  438.         Cmd_AddCommand ("-use", IN_UseUp);
  439.         Cmd_AddCommand ("+jump", IN_JumpDown);
  440.         Cmd_AddCommand ("-jump", IN_JumpUp);
  441.         Cmd_AddCommand ("impulse", IN_Impulse);
  442.         Cmd_AddCommand ("+klook", IN_KLookDown);
  443.         Cmd_AddCommand ("-klook", IN_KLookUp);
  444.         Cmd_AddCommand ("+mlook", IN_MLookDown);
  445.         Cmd_AddCommand ("-mlook", IN_MLookUp);
  446.  
  447. }
  448.  
  449.