Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5131 clevermous 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
 
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