]> icculus.org git repositories - divverent/darkplaces.git/blob - cl_input.c
get rid of the unused clearnotify and clearconsole variables
[divverent/darkplaces.git] / cl_input.c
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_jump, in_attack;
53 kbutton_t       in_up, in_down;
54 // LordHavoc: added 6 new buttons
55 kbutton_t       in_button3, in_button4, in_button5, in_button6, in_button7, in_button8;
56
57 int                     in_impulse;
58
59
60 void KeyDown (kbutton_t *b)
61 {
62         int k;
63         const char *c;
64
65         c = Cmd_Argv(1);
66         if (c[0])
67                 k = atoi(c);
68         else
69                 k = -1;         // typed manually at the console for continuous down
70
71         if (k == b->down[0] || k == b->down[1])
72                 return;         // repeating key
73
74         if (!b->down[0])
75                 b->down[0] = k;
76         else if (!b->down[1])
77                 b->down[1] = k;
78         else
79         {
80                 Con_Print("Three keys down for a button!\n");
81                 return;
82         }
83
84         if (b->state & 1)
85                 return;         // still down
86         b->state |= 1 + 2;      // down + impulse down
87 }
88
89 void KeyUp (kbutton_t *b)
90 {
91         int k;
92         const char *c;
93
94         c = Cmd_Argv(1);
95         if (c[0])
96                 k = atoi(c);
97         else
98         { // typed manually at the console, assume for unsticking, so clear all
99                 b->down[0] = b->down[1] = 0;
100                 b->state = 4;   // impulse up
101                 return;
102         }
103
104         if (b->down[0] == k)
105                 b->down[0] = 0;
106         else if (b->down[1] == k)
107                 b->down[1] = 0;
108         else
109                 return;         // key up without coresponding down (menu pass through)
110         if (b->down[0] || b->down[1])
111                 return;         // some other key is still holding it down
112
113         if (!(b->state & 1))
114                 return;         // still up (this should not happen)
115         b->state &= ~1;         // now up
116         b->state |= 4;          // impulse up
117 }
118
119 void IN_KLookDown (void) {KeyDown(&in_klook);}
120 void IN_KLookUp (void) {KeyUp(&in_klook);}
121 void IN_MLookDown (void) {KeyDown(&in_mlook);}
122 void IN_MLookUp (void)
123 {
124         KeyUp(&in_mlook);
125         if ( !(in_mlook.state&1) && lookspring.value)
126                 V_StartPitchDrift();
127 }
128 void IN_UpDown(void) {KeyDown(&in_up);}
129 void IN_UpUp(void) {KeyUp(&in_up);}
130 void IN_DownDown(void) {KeyDown(&in_down);}
131 void IN_DownUp(void) {KeyUp(&in_down);}
132 void IN_LeftDown(void) {KeyDown(&in_left);}
133 void IN_LeftUp(void) {KeyUp(&in_left);}
134 void IN_RightDown(void) {KeyDown(&in_right);}
135 void IN_RightUp(void) {KeyUp(&in_right);}
136 void IN_ForwardDown(void) {KeyDown(&in_forward);}
137 void IN_ForwardUp(void) {KeyUp(&in_forward);}
138 void IN_BackDown(void) {KeyDown(&in_back);}
139 void IN_BackUp(void) {KeyUp(&in_back);}
140 void IN_LookupDown(void) {KeyDown(&in_lookup);}
141 void IN_LookupUp(void) {KeyUp(&in_lookup);}
142 void IN_LookdownDown(void) {KeyDown(&in_lookdown);}
143 void IN_LookdownUp(void) {KeyUp(&in_lookdown);}
144 void IN_MoveleftDown(void) {KeyDown(&in_moveleft);}
145 void IN_MoveleftUp(void) {KeyUp(&in_moveleft);}
146 void IN_MoverightDown(void) {KeyDown(&in_moveright);}
147 void IN_MoverightUp(void) {KeyUp(&in_moveright);}
148
149 void IN_SpeedDown(void) {KeyDown(&in_speed);}
150 void IN_SpeedUp(void) {KeyUp(&in_speed);}
151 void IN_StrafeDown(void) {KeyDown(&in_strafe);}
152 void IN_StrafeUp(void) {KeyUp(&in_strafe);}
153
154 void IN_AttackDown(void) {KeyDown(&in_attack);}
155 void IN_AttackUp(void) {KeyUp(&in_attack);}
156
157 // LordHavoc: added 6 new buttons
158 void IN_Button3Down(void) {KeyDown(&in_button3);}
159 void IN_Button3Up(void) {KeyUp(&in_button3);}
160 void IN_Button4Down(void) {KeyDown(&in_button4);}
161 void IN_Button4Up(void) {KeyUp(&in_button4);}
162 void IN_Button5Down(void) {KeyDown(&in_button5);}
163 void IN_Button5Up(void) {KeyUp(&in_button5);}
164 void IN_Button6Down(void) {KeyDown(&in_button6);}
165 void IN_Button6Up(void) {KeyUp(&in_button6);}
166 void IN_Button7Down(void) {KeyDown(&in_button7);}
167 void IN_Button7Up(void) {KeyUp(&in_button7);}
168 void IN_Button8Down(void) {KeyDown(&in_button8);}
169 void IN_Button8Up(void) {KeyUp(&in_button8);}
170
171 void IN_JumpDown (void) {KeyDown(&in_jump);}
172 void IN_JumpUp (void) {KeyUp(&in_jump);}
173
174 void IN_Impulse (void) {in_impulse=atoi(Cmd_Argv(1));}
175
176 /*
177 ===============
178 CL_KeyState
179
180 Returns 0.25 if a key was pressed and released during the frame,
181 0.5 if it was pressed and held
182 0 if held then released, and
183 1.0 if held for the entire time
184 ===============
185 */
186 float CL_KeyState (kbutton_t *key)
187 {
188         float           val;
189         qboolean        impulsedown, impulseup, down;
190
191         impulsedown = key->state & 2;
192         impulseup = key->state & 4;
193         down = key->state & 1;
194         val = 0;
195
196         if (impulsedown && !impulseup)
197         {
198                 if (down)
199                         val = 0.5;      // pressed and held this frame
200                 else
201                         val = 0;        //      I_Error ();
202         }
203         if (impulseup && !impulsedown)
204         {
205                 if (down)
206                         val = 0;        //      I_Error ();
207                 else
208                         val = 0;        // released this frame
209         }
210         if (!impulsedown && !impulseup)
211         {
212                 if (down)
213                         val = 1.0;      // held the entire frame
214                 else
215                         val = 0;        // up the entire frame
216         }
217         if (impulsedown && impulseup)
218         {
219                 if (down)
220                         val = 0.75;     // released and re-pressed this frame
221                 else
222                         val = 0.25;     // pressed and released this frame
223         }
224
225         key->state &= 1;                // clear impulses
226
227         return val;
228 }
229
230
231
232
233 //==========================================================================
234
235 cvar_t cl_upspeed = {CVAR_SAVE, "cl_upspeed","400"};
236 cvar_t cl_forwardspeed = {CVAR_SAVE, "cl_forwardspeed","400"};
237 cvar_t cl_backspeed = {CVAR_SAVE, "cl_backspeed","400"};
238 cvar_t cl_sidespeed = {CVAR_SAVE, "cl_sidespeed","350"};
239
240 cvar_t cl_movespeedkey = {CVAR_SAVE, "cl_movespeedkey","2.0"};
241
242 cvar_t cl_yawspeed = {CVAR_SAVE, "cl_yawspeed","140"};
243 cvar_t cl_pitchspeed = {CVAR_SAVE, "cl_pitchspeed","150"};
244
245 cvar_t cl_anglespeedkey = {CVAR_SAVE, "cl_anglespeedkey","1.5"};
246
247 /*
248 ================
249 CL_AdjustAngles
250
251 Moves the local angle positions
252 ================
253 */
254 void CL_AdjustAngles (void)
255 {
256         float   speed;
257         float   up, down;
258
259         if (in_speed.state & 1)
260                 speed = host_realframetime * cl_anglespeedkey.value;
261         else
262                 speed = host_realframetime;
263
264         if (!(in_strafe.state & 1))
265         {
266                 cl.viewangles[YAW] -= speed*cl_yawspeed.value*CL_KeyState (&in_right);
267                 cl.viewangles[YAW] += speed*cl_yawspeed.value*CL_KeyState (&in_left);
268         }
269         if (in_klook.state & 1)
270         {
271                 V_StopPitchDrift ();
272                 cl.viewangles[PITCH] -= speed*cl_pitchspeed.value * CL_KeyState (&in_forward);
273                 cl.viewangles[PITCH] += speed*cl_pitchspeed.value * CL_KeyState (&in_back);
274         }
275
276         up = CL_KeyState (&in_lookup);
277         down = CL_KeyState(&in_lookdown);
278
279         cl.viewangles[PITCH] -= speed*cl_pitchspeed.value * up;
280         cl.viewangles[PITCH] += speed*cl_pitchspeed.value * down;
281
282         if (up || down)
283                 V_StopPitchDrift ();
284
285         cl.viewangles[YAW] = ANGLEMOD(cl.viewangles[YAW]);
286         cl.viewangles[PITCH] = ANGLEMOD(cl.viewangles[PITCH]);
287         cl.viewangles[ROLL] = ANGLEMOD(cl.viewangles[ROLL]);
288         if (cl.viewangles[YAW] >= 180)
289                 cl.viewangles[YAW] -= 360;
290         if (cl.viewangles[PITCH] >= 180)
291                 cl.viewangles[PITCH] -= 360;
292         if (cl.viewangles[ROLL] >= 180)
293                 cl.viewangles[ROLL] -= 360;
294
295         cl.viewangles[PITCH] = bound (in_pitch_min.value, cl.viewangles[PITCH], in_pitch_max.value);
296         cl.viewangles[ROLL] = bound(-50, cl.viewangles[ROLL], 50);
297 }
298
299 /*
300 ================
301 CL_BaseMove
302
303 Send the intended movement message to the server
304 ================
305 */
306 void CL_BaseMove (usercmd_t *cmd)
307 {
308         if (cls.signon != SIGNONS)
309                 return;
310
311         CL_AdjustAngles ();
312
313         memset (cmd, 0, sizeof(*cmd));
314
315         if (in_strafe.state & 1)
316         {
317                 cmd->sidemove += cl_sidespeed.value * CL_KeyState (&in_right);
318                 cmd->sidemove -= cl_sidespeed.value * CL_KeyState (&in_left);
319         }
320
321         cmd->sidemove += cl_sidespeed.value * CL_KeyState (&in_moveright);
322         cmd->sidemove -= cl_sidespeed.value * CL_KeyState (&in_moveleft);
323
324         cmd->upmove += cl_upspeed.value * CL_KeyState (&in_up);
325         cmd->upmove -= cl_upspeed.value * CL_KeyState (&in_down);
326
327         if (! (in_klook.state & 1) )
328         {
329                 cmd->forwardmove += cl_forwardspeed.value * CL_KeyState (&in_forward);
330                 cmd->forwardmove -= cl_backspeed.value * CL_KeyState (&in_back);
331         }
332
333 //
334 // adjust for speed key
335 //
336         if (in_speed.state & 1)
337         {
338                 cmd->forwardmove *= cl_movespeedkey.value;
339                 cmd->sidemove *= cl_movespeedkey.value;
340                 cmd->upmove *= cl_movespeedkey.value;
341         }
342 }
343
344
345
346 /*
347 ==============
348 CL_SendMove
349 ==============
350 */
351 void CL_SendMove(usercmd_t *cmd)
352 {
353         int i;
354         int bits;
355         sizebuf_t buf;
356         qbyte data[128];
357         static double lastmovetime;
358         static float forwardmove, sidemove, upmove, total; // accumulation
359
360         forwardmove += cmd->forwardmove;
361         sidemove += cmd->sidemove;
362         upmove += cmd->upmove;
363         total++;
364         // LordHavoc: cap outgoing movement messages to sys_ticrate
365         if (!cl.islocalgame && (realtime - lastmovetime < sys_ticrate.value))
366                 return;
367         lastmovetime = realtime;
368         // average what has happened during this time
369         total = 1.0f / total;
370         forwardmove *= total;
371         sidemove *= total;
372         upmove *= total;
373         total = 0;
374
375         buf.maxsize = 128;
376         buf.cursize = 0;
377         buf.data = data;
378
379         cl.cmd = *cmd;
380
381         // send the movement message
382         MSG_WriteByte (&buf, clc_move);
383
384         MSG_WriteFloat (&buf, cl.mtime[0]);     // so server can get ping times
385
386         if (cl.protocol == PROTOCOL_QUAKE)
387         {
388                 for (i = 0;i < 3;i++)
389                         MSG_WriteAngle8i (&buf, cl.viewangles[i]);
390         }
391         else if (cl.protocol == PROTOCOL_DARKPLACES2 || cl.protocol == PROTOCOL_DARKPLACES3)
392         {
393                 for (i = 0;i < 3;i++)
394                         MSG_WriteAngle32f (&buf, cl.viewangles[i]);
395         }
396         else if (cl.protocol == PROTOCOL_DARKPLACES1 || cl.protocol == PROTOCOL_DARKPLACES4 || cl.protocol == PROTOCOL_DARKPLACES5)
397         {
398                 for (i = 0;i < 3;i++)
399                         MSG_WriteAngle16i (&buf, cl.viewangles[i]);
400         }
401
402         MSG_WriteCoord16i (&buf, forwardmove);
403         MSG_WriteCoord16i (&buf, sidemove);
404         MSG_WriteCoord16i (&buf, upmove);
405
406         forwardmove = sidemove = upmove = 0;
407         // send button bits
408         bits = 0;
409
410         // LordHavoc: added 6 new buttons
411         if (in_attack.state  & 3) bits |=   1;in_attack.state  &= ~2;
412         if (in_jump.state    & 3) bits |=   2;in_jump.state    &= ~2;
413         if (in_button3.state & 3) bits |=   4;in_button3.state &= ~2;
414         if (in_button4.state & 3) bits |=   8;in_button4.state &= ~2;
415         if (in_button5.state & 3) bits |=  16;in_button5.state &= ~2;
416         if (in_button6.state & 3) bits |=  32;in_button6.state &= ~2;
417         if (in_button7.state & 3) bits |=  64;in_button7.state &= ~2;
418         if (in_button8.state & 3) bits |= 128;in_button8.state &= ~2;
419
420         MSG_WriteByte (&buf, bits);
421
422         MSG_WriteByte (&buf, in_impulse);
423         in_impulse = 0;
424
425         // FIXME: should ack latest 3 frames perhaps?
426         if (cl.latestframenum > 0)
427         {
428                 if (developer_networkentities.integer >= 1)
429                         Con_Printf("send clc_ackentities %i\n", cl.latestframenum);
430                 MSG_WriteByte(&buf, clc_ackentities);
431                 MSG_WriteLong(&buf, cl.latestframenum);
432         }
433
434         // deliver the message
435         if (cls.demoplayback)
436                 return;
437
438         // always dump the first two messages, because they may contain leftover inputs from the last level
439         if (++cl.movemessages <= 2)
440                 return;
441
442         if (NetConn_SendUnreliableMessage(cls.netcon, &buf) == -1)
443         {
444                 Con_Print("CL_SendMove: lost server connection\n");
445                 CL_Disconnect();
446                 Host_ShutdownServer(false);
447         }
448 }
449
450 /*
451 ============
452 CL_InitInput
453 ============
454 */
455 void CL_InitInput (void)
456 {
457         Cmd_AddCommand ("+moveup",IN_UpDown);
458         Cmd_AddCommand ("-moveup",IN_UpUp);
459         Cmd_AddCommand ("+movedown",IN_DownDown);
460         Cmd_AddCommand ("-movedown",IN_DownUp);
461         Cmd_AddCommand ("+left",IN_LeftDown);
462         Cmd_AddCommand ("-left",IN_LeftUp);
463         Cmd_AddCommand ("+right",IN_RightDown);
464         Cmd_AddCommand ("-right",IN_RightUp);
465         Cmd_AddCommand ("+forward",IN_ForwardDown);
466         Cmd_AddCommand ("-forward",IN_ForwardUp);
467         Cmd_AddCommand ("+back",IN_BackDown);
468         Cmd_AddCommand ("-back",IN_BackUp);
469         Cmd_AddCommand ("+lookup", IN_LookupDown);
470         Cmd_AddCommand ("-lookup", IN_LookupUp);
471         Cmd_AddCommand ("+lookdown", IN_LookdownDown);
472         Cmd_AddCommand ("-lookdown", IN_LookdownUp);
473         Cmd_AddCommand ("+strafe", IN_StrafeDown);
474         Cmd_AddCommand ("-strafe", IN_StrafeUp);
475         Cmd_AddCommand ("+moveleft", IN_MoveleftDown);
476         Cmd_AddCommand ("-moveleft", IN_MoveleftUp);
477         Cmd_AddCommand ("+moveright", IN_MoverightDown);
478         Cmd_AddCommand ("-moveright", IN_MoverightUp);
479         Cmd_AddCommand ("+speed", IN_SpeedDown);
480         Cmd_AddCommand ("-speed", IN_SpeedUp);
481         Cmd_AddCommand ("+attack", IN_AttackDown);
482         Cmd_AddCommand ("-attack", IN_AttackUp);
483         Cmd_AddCommand ("+jump", IN_JumpDown);
484         Cmd_AddCommand ("-jump", IN_JumpUp);
485         Cmd_AddCommand ("impulse", IN_Impulse);
486         Cmd_AddCommand ("+klook", IN_KLookDown);
487         Cmd_AddCommand ("-klook", IN_KLookUp);
488         Cmd_AddCommand ("+mlook", IN_MLookDown);
489         Cmd_AddCommand ("-mlook", IN_MLookUp);
490
491         // LordHavoc: added 6 new buttons
492         Cmd_AddCommand ("+button3", IN_Button3Down);
493         Cmd_AddCommand ("-button3", IN_Button3Up);
494         Cmd_AddCommand ("+button4", IN_Button4Down);
495         Cmd_AddCommand ("-button4", IN_Button4Up);
496         Cmd_AddCommand ("+button5", IN_Button5Down);
497         Cmd_AddCommand ("-button5", IN_Button5Up);
498         Cmd_AddCommand ("+button6", IN_Button6Down);
499         Cmd_AddCommand ("-button6", IN_Button6Up);
500         Cmd_AddCommand ("+button7", IN_Button7Down);
501         Cmd_AddCommand ("-button7", IN_Button7Up);
502         Cmd_AddCommand ("+button8", IN_Button8Down);
503         Cmd_AddCommand ("-button8", IN_Button8Up);
504 }
505