summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/quake/cl_input.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2018-02-11 15:34:30 -0500
committerFranklin Wei <git@fwei.tk>2019-07-19 22:37:40 -0400
commit5d05b9d3e920a6aa5fcb553758e98ed0da8c91e4 (patch)
tree84406e21639529a185556a33e5de7f43cffc277b /apps/plugins/sdl/progs/quake/cl_input.c
parentb70fecf21ddc21877ec1ae7888d9c18a979e37ad (diff)
downloadrockbox-5d05b9d3e920a6aa5fcb553758e98ed0da8c91e4.tar.gz
rockbox-5d05b9d3e920a6aa5fcb553758e98ed0da8c91e4.zip
Quake!
This ports id Software's Quake to run on the SDL plugin runtime. The source code originated from id under the GPLv2 license. I used https://github.com/ahefner/sdlquake as the base of my port. Performance is, unsurprisingly, not on par with what you're probably used to on PC. I average about 10FPS on ipod6g, but it's still playable. Sound works well enough, but in-game music is not supported. I've written ARM assembly routines for the inner sound loop. Make sure you turn the "brightness" all the way down, or colors will look funky. To run, extract Quake's data files to /.rockbox/quake. Have fun! Change-Id: I4285036e967d7f0722802d43cf2096c808ca5799
Diffstat (limited to 'apps/plugins/sdl/progs/quake/cl_input.c')
-rw-r--r--apps/plugins/sdl/progs/quake/cl_input.c448
1 files changed, 448 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/quake/cl_input.c b/apps/plugins/sdl/progs/quake/cl_input.c
new file mode 100644
index 0000000000..5327b7363e
--- /dev/null
+++ b/apps/plugins/sdl/progs/quake/cl_input.c
@@ -0,0 +1,448 @@
1/*
2Copyright (C) 1996-1997 Id Software, Inc.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, 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
30KEY BUTTONS
31
32Continuous button event tracking is complicated by the fact that two different
33input sources (say, mouse button 1 and the control key) can both press the
34same button, but the button should only be released when both of the
35pressing key have been released.
36
37When a key event issues a button command (+forward, +attack, etc), it appends
38its key number as a parameter to the command so it can be matched up with
39the release.
40
41state bit 0 is the current state of the key
42state bit 1 is edge triggered on the up to down transition
43state bit 2 is edge triggered on the down to up transition
44
45===============================================================================
46*/
47
48
49kbutton_t in_mlook, in_klook;
50kbutton_t in_left, in_right, in_forward, in_back;
51kbutton_t in_lookup, in_lookdown, in_moveleft, in_moveright;
52kbutton_t in_strafe, in_speed, in_use, in_jump, in_attack;
53kbutton_t in_up, in_down;
54
55int in_impulse;
56
57
58void 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
87void 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
117void IN_KLookDown (void) {KeyDown(&in_klook);}
118void IN_KLookUp (void) {KeyUp(&in_klook);}
119void IN_MLookDown (void) {KeyDown(&in_mlook);}
120void IN_MLookUp (void) {
121KeyUp(&in_mlook);
122if ( !(in_mlook.state&1) && lookspring.value)
123 V_StartPitchDrift();
124}
125void IN_UpDown(void) {KeyDown(&in_up);}
126void IN_UpUp(void) {KeyUp(&in_up);}
127void IN_DownDown(void) {KeyDown(&in_down);}
128void IN_DownUp(void) {KeyUp(&in_down);}
129void IN_LeftDown(void) {KeyDown(&in_left);}
130void IN_LeftUp(void) {KeyUp(&in_left);}
131void IN_RightDown(void) {KeyDown(&in_right);}
132void IN_RightUp(void) {KeyUp(&in_right);}
133void IN_ForwardDown(void) {KeyDown(&in_forward);}
134void IN_ForwardUp(void) {KeyUp(&in_forward);}
135void IN_BackDown(void) {KeyDown(&in_back);}
136void IN_BackUp(void) {KeyUp(&in_back);}
137void IN_LookupDown(void) {KeyDown(&in_lookup);}
138void IN_LookupUp(void) {KeyUp(&in_lookup);}
139void IN_LookdownDown(void) {KeyDown(&in_lookdown);}
140void IN_LookdownUp(void) {KeyUp(&in_lookdown);}
141void IN_MoveleftDown(void) {KeyDown(&in_moveleft);}
142void IN_MoveleftUp(void) {KeyUp(&in_moveleft);}
143void IN_MoverightDown(void) {KeyDown(&in_moveright);}
144void IN_MoverightUp(void) {KeyUp(&in_moveright);}
145
146void IN_SpeedDown(void) {KeyDown(&in_speed);}
147void IN_SpeedUp(void) {KeyUp(&in_speed);}
148void IN_StrafeDown(void) {KeyDown(&in_strafe);}
149void IN_StrafeUp(void) {KeyUp(&in_strafe);}
150
151void IN_AttackDown(void) {KeyDown(&in_attack);}
152void IN_AttackUp(void) {KeyUp(&in_attack);}
153
154void IN_UseDown (void) {KeyDown(&in_use);}
155void IN_UseUp (void) {KeyUp(&in_use);}
156void IN_JumpDown (void) {KeyDown(&in_jump);}
157void IN_JumpUp (void) {KeyUp(&in_jump);}
158
159void IN_Impulse (void) {in_impulse=Q_atoi(Cmd_Argv(1));}
160
161/*
162===============
163CL_KeyState
164
165Returns 0.25 if a key was pressed and released during the frame,
1660.5 if it was pressed and held
1670 if held then released, and
1681.0 if held for the entire time
169===============
170*/
171float 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
212cvar_t cl_upspeed = {"cl_upspeed","200"};
213cvar_t cl_forwardspeed = {"cl_forwardspeed","200", true};
214cvar_t cl_backspeed = {"cl_backspeed","200", true};
215cvar_t cl_sidespeed = {"cl_sidespeed","350"};
216
217cvar_t cl_movespeedkey = {"cl_movespeedkey","2.0"};
218
219cvar_t cl_yawspeed = {"cl_yawspeed","140"};
220cvar_t cl_pitchspeed = {"cl_pitchspeed","150"};
221
222cvar_t cl_anglespeedkey = {"cl_anglespeedkey","1.5"};
223
224
225/*
226================
227CL_AdjustAngles
228
229Moves the local angle positions
230================
231*/
232void 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================
278CL_BaseMove
279
280Send the intended movement message to the server
281================
282*/
283void 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==============
329CL_SendMove
330==============
331*/
332void 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============
406CL_InitInput
407============
408*/
409void 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