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
// in_mouse.c -- dos mouse code
21
 
22
#include "quakedef.h"
23
#include "dosisms.h"
24
 
25
#define AUX_FLAG_FREELOOK	0x00000001
26
 
27
typedef struct
28
{
29
	long    interruptVector;
30
	char    deviceName[16];
31
	long    numAxes;
32
	long	numButtons;
33
	long	flags;
34
 
35
	vec3_t  viewangles;
36
 
37
// intended velocities
38
	float   forwardmove;
39
	float   sidemove;
40
	float   upmove;
41
 
42
	long	buttons;
43
} externControl_t;
44
 
45
/*
46
#define AUX_FLAG_FORCEFREELOOK	0x00000001	// r/o
47
#define AUX_FLAG_EXTENDED		0x00000002	// r/o
48
#define AUX_FLAG_RUN			0x00000004	// w/o
49
#define AUX_FLAG_STRAFE			0x00000008	// w/o
50
#define AUX_FLAG_FREELOOK		0x00000010	// w/o
51
 
52
#define AUX_MAP_UNDEFINED	0
53
#define AUX_MAP_PITCH		1
54
#define AUX_MAP_YAW			2
55
#define AUX_MAP_ROLL		3
56
#define AUX_MAP_FORWARD		4
57
#define AUX_MAP_SIDE		5
58
#define AUX_MAP_UP			6
59
 
60
typedef struct
61
{
62
	long    interruptVector;
63
	// r/o
64
	char    deviceName[16];
65
	// r/o
66
	long    numAxes;
67
			// r/o	1-6
68
	long	numButtons;			// r/o	0-32
69
	long	flags;				// see above
70
	byte	axisMapping[6];		// w/o	default = p,y,r,f,s,u
71
	float	axisValue[6];		// r/w
72
	float	sensitivity[6];		// w/o	default = 1.0
73
	long	buttons;			// r/o
74
	float	last_frame_time;	// w/o
75
} externControl_t;
76
*/
77
 
78
cvar_t	m_filter = {"m_filter","1"};
79
 
80
qboolean	mouse_avail;
81
int		mouse_buttons;
82
int		mouse_oldbuttonstate;
83
int		mouse_buttonstate;
84
float	mouse_x, mouse_y;
85
float	old_mouse_x, old_mouse_y;
86
 
87
 
88
cvar_t	in_joystick = {"joystick","1"};
89
cvar_t	joy_numbuttons = {"joybuttons","4", true};
90
 
91
qboolean	joy_avail;
92
int		joy_oldbuttonstate;
93
int		joy_buttonstate;
94
 
95
int     joyxl, joyxh, joyyl, joyyh;
96
int		joystickx, joysticky;
97
 
98
qboolean		need_center;
99
 
100
qboolean		extern_avail;
101
int				extern_buttons;
102
int				extern_oldbuttonstate;
103
int				extern_buttonstate;
104
cvar_t	aux_look = {"auxlook","1", true};
105
externControl_t	*extern_control;
106
void IN_StartupExternal (void);
107
void IN_ExternalMove (usercmd_t *cmd);
108
 
109
void IN_StartupJoystick (void);
110
qboolean IN_ReadJoystick (void);
111
 
112
 
113
void Toggle_AuxLook_f (void)
114
{
115
	if (aux_look.value)
116
		Cvar_Set ("auxlook","0");
117
	else
118
		Cvar_Set ("auxlook","1");
119
}
120
 
121
 
122
void Force_CenterView_f (void)
123
{
124
	cl.viewangles[PITCH] = 0;
125
}
126
 
127
 
128
/*
129
===========
130
IN_StartupMouse
131
===========
132
*/
133
void IN_StartupMouse (void)
134
{
135
	if ( COM_CheckParm ("-nomouse") )
136
		return;
137
 
138
// check for mouse
139
	regs.x.ax = 0;
140
	dos_int86(0x33);
141
	mouse_avail = regs.x.ax;
142
	if (!mouse_avail)
143
	{
144
		Con_Printf ("No mouse found\n");
145
		return;
146
	}
147
 
148
	mouse_buttons = regs.x.bx;
149
	if (mouse_buttons > 3)
150
		mouse_buttons = 3;
151
	Con_Printf("%d-button mouse available\n", mouse_buttons);
152
}
153
 
154
/*
155
===========
156
IN_Init
157
===========
158
*/
159
void IN_Init (void)
160
{
161
	int i;
162
 
163
	Cvar_RegisterVariable (&m_filter);
164
	Cvar_RegisterVariable (&in_joystick);
165
	Cvar_RegisterVariable (&joy_numbuttons);
166
	Cvar_RegisterVariable (&aux_look);
167
	Cmd_AddCommand ("toggle_auxlook", Toggle_AuxLook_f);
168
	Cmd_AddCommand ("force_centerview", Force_CenterView_f);
169
 
170
	IN_StartupMouse ();
171
	IN_StartupJoystick ();
172
 
173
	i = COM_CheckParm ("-control");
174
	if (i)
175
	{
176
		extern_control = real2ptr(Q_atoi (com_argv[i+1]));
177
		IN_StartupExternal ();
178
	}
179
}
180
 
181
/*
182
===========
183
IN_Shutdown
184
===========
185
*/
186
void IN_Shutdown (void)
187
{
188
 
189
}
190
 
191
 
192
/*
193
===========
194
IN_Commands
195
===========
196
*/
197
void IN_Commands (void)
198
{
199
	int		i;
200
 
201
	if (mouse_avail)
202
	{
203
		regs.x.ax = 3;		// read buttons
204
		dos_int86(0x33);
205
		mouse_buttonstate = regs.x.bx;
206
 
207
	// perform button actions
208
		for (i=0 ; i
209
		{
210
			if ( (mouse_buttonstate & (1<
211
			!(mouse_oldbuttonstate & (1<
212
			{
213
				Key_Event (K_MOUSE1 + i, true);
214
			}
215
			if ( !(mouse_buttonstate & (1<
216
			(mouse_oldbuttonstate & (1<
217
			{
218
				Key_Event (K_MOUSE1 + i, false);
219
			}
220
		}
221
 
222
		mouse_oldbuttonstate = mouse_buttonstate;
223
	}
224
 
225
	if (joy_avail)
226
	{
227
		joy_buttonstate = ((dos_inportb(0x201) >> 4)&15)^15;
228
	// perform button actions
229
		for (i=0 ; i
230
		{
231
			if ( (joy_buttonstate & (1<
232
			!(joy_oldbuttonstate & (1<
233
			{
234
				Key_Event (K_JOY1 + i, true);
235
			}
236
			if ( !(joy_buttonstate & (1<
237
			(joy_oldbuttonstate & (1<
238
			{
239
				Key_Event (K_JOY1 + i, false);
240
			}
241
		}
242
 
243
		joy_oldbuttonstate = joy_buttonstate;
244
	}
245
 
246
	if (extern_avail)
247
	{
248
		extern_buttonstate = extern_control->buttons;
249
 
250
	// perform button actions
251
		for (i=0 ; i
252
		{
253
			if ( (extern_buttonstate & (1<
254
			!(extern_oldbuttonstate & (1<
255
			{
256
				Key_Event (K_AUX1 + i, true);
257
			}
258
			if ( !(extern_buttonstate & (1<
259
			(extern_oldbuttonstate & (1<
260
			{
261
				Key_Event (K_AUX1 + i, false);
262
			}
263
		}
264
 
265
		extern_oldbuttonstate = extern_buttonstate;
266
	}
267
 
268
}
269
 
270
 
271
/*
272
===========
273
IN_Move
274
===========
275
*/
276
void IN_MouseMove (usercmd_t *cmd)
277
{
278
	int		mx, my;
279
 
280
	if (!mouse_avail)
281
		return;
282
 
283
	regs.x.ax = 11;		// read move
284
	dos_int86(0x33);
285
	mx = (short)regs.x.cx;
286
	my = (short)regs.x.dx;
287
 
288
	if (m_filter.value)
289
	{
290
		mouse_x = (mx + old_mouse_x) * 0.5;
291
		mouse_y = (my + old_mouse_y) * 0.5;
292
	}
293
	else
294
	{
295
		mouse_x = mx;
296
		mouse_y = my;
297
	}
298
	old_mouse_x = mx;
299
	old_mouse_y = my;
300
 
301
	mouse_x *= sensitivity.value;
302
	mouse_y *= sensitivity.value;
303
 
304
// add mouse X/Y movement to cmd
305
	if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) ))
306
		cmd->sidemove += m_side.value * mouse_x;
307
	else
308
		cl.viewangles[YAW] -= m_yaw.value * mouse_x;
309
 
310
	if (in_mlook.state & 1)
311
		V_StopPitchDrift ();
312
 
313
	if ( (in_mlook.state & 1) && !(in_strafe.state & 1))
314
	{
315
		cl.viewangles[PITCH] += m_pitch.value * mouse_y;
316
		if (cl.viewangles[PITCH] > 80)
317
			cl.viewangles[PITCH] = 80;
318
		if (cl.viewangles[PITCH] < -70)
319
			cl.viewangles[PITCH] = -70;
320
	}
321
	else
322
	{
323
		if ((in_strafe.state & 1) && noclip_anglehack)
324
			cmd->upmove -= m_forward.value * mouse_y;
325
		else
326
			cmd->forwardmove -= m_forward.value * mouse_y;
327
	}
328
}
329
 
330
/*
331
===========
332
IN_JoyMove
333
===========
334
*/
335
void IN_JoyMove (usercmd_t *cmd)
336
{
337
	float	speed, aspeed;
338
 
339
	if (!joy_avail || !in_joystick.value)
340
		return;
341
 
342
	IN_ReadJoystick ();
343
	if (joysticky > joyyh*2 || joystickx > joyxh*2)
344
		return;		// assume something jumped in and messed up the joystick
345
					// reading time (win 95)
346
 
347
	if (in_speed.state & 1)
348
		speed = cl_movespeedkey.value;
349
	else
350
		speed = 1;
351
	aspeed = speed*host_frametime;
352
 
353
	if (in_strafe.state & 1)
354
	{
355
		if (joystickx < joyxl)
356
			cmd->sidemove -= speed*cl_sidespeed.value;
357
		else if (joystickx > joyxh)
358
			cmd->sidemove += speed*cl_sidespeed.value;
359
	}
360
	else
361
	{
362
		if (joystickx < joyxl)
363
			cl.viewangles[YAW] += aspeed*cl_yawspeed.value;
364
		else if (joystickx > joyxh)
365
			cl.viewangles[YAW] -= aspeed*cl_yawspeed.value;
366
		cl.viewangles[YAW] = anglemod(cl.viewangles[YAW]);
367
	}
368
 
369
	if (in_mlook.state & 1)
370
	{
371
		if (m_pitch.value < 0)
372
			speed *= -1;
373
 
374
		if (joysticky < joyyl)
375
			cl.viewangles[PITCH] += aspeed*cl_pitchspeed.value;
376
		else if (joysticky > joyyh)
377
			cl.viewangles[PITCH] -= aspeed*cl_pitchspeed.value;
378
	}
379
	else
380
	{
381
		if (joysticky < joyyl)
382
			cmd->forwardmove += speed*cl_forwardspeed.value;
383
		else if (joysticky > joyyh)
384
			cmd->forwardmove -= speed*cl_backspeed.value;
385
	}
386
}
387
 
388
/*
389
===========
390
IN_Move
391
===========
392
*/
393
void IN_Move (usercmd_t *cmd)
394
{
395
	IN_MouseMove (cmd);
396
	IN_JoyMove (cmd);
397
	IN_ExternalMove (cmd);
398
}
399
 
400
/*
401
============================================================================
402
 
403
					JOYSTICK
404
 
405
============================================================================
406
*/
407
 
408
 
409
 
410
qboolean IN_ReadJoystick (void)
411
{
412
	int		b;
413
	int		count;
414
 
415
	joystickx = 0;
416
	joysticky = 0;
417
 
418
	count = 0;
419
 
420
	b = dos_inportb(0x201);
421
	dos_outportb(0x201, b);
422
 
423
// clear counters
424
	while (++count < 10000)
425
	{
426
		b = dos_inportb(0x201);
427
 
428
		joystickx += b&1;
429
		joysticky += (b&2)>>1;
430
		if ( !(b&3) )
431
			return true;
432
	}
433
 
434
	Con_Printf ("IN_ReadJoystick: no response\n");
435
	joy_avail = false;
436
	return false;
437
}
438
 
439
/*
440
=============
441
WaitJoyButton
442
=============
443
*/
444
qboolean WaitJoyButton (void)
445
{
446
	int             oldbuttons, buttons;
447
 
448
	oldbuttons = 0;
449
	do
450
	{
451
		key_count = -1;
452
		Sys_SendKeyEvents ();
453
		key_count = 0;
454
		if (key_lastpress == K_ESCAPE)
455
		{
456
			Con_Printf ("aborted.\n");
457
			return false;
458
		}
459
		key_lastpress = 0;
460
		SCR_UpdateScreen ();
461
		buttons =  ((dos_inportb(0x201) >> 4)&1)^1;
462
		if (buttons != oldbuttons)
463
		{
464
			oldbuttons = buttons;
465
			continue;
466
		}
467
	} while ( !buttons);
468
 
469
	do
470
	{
471
		key_count = -1;
472
		Sys_SendKeyEvents ();
473
		key_count = 0;
474
		if (key_lastpress == K_ESCAPE)
475
		{
476
			Con_Printf ("aborted.\n");
477
			return false;
478
		}
479
		key_lastpress = 0;
480
		SCR_UpdateScreen ();
481
		buttons =  ((dos_inportb(0x201) >> 4)&1)^1;
482
		if (buttons != oldbuttons)
483
		{
484
			oldbuttons = buttons;
485
			continue;
486
		}
487
	} while ( buttons);
488
 
489
	return true;
490
}
491
 
492
 
493
 
494
/*
495
===============
496
IN_StartupJoystick
497
===============
498
*/
499
void IN_StartupJoystick (void)
500
{
501
	int     centerx, centery;
502
 
503
 	Con_Printf ("\n");
504
 
505
	joy_avail = false;
506
	if ( COM_CheckParm ("-nojoy") )
507
		return;
508
 
509
	if (!IN_ReadJoystick ())
510
	{
511
		joy_avail = false;
512
		Con_Printf ("joystick not found\n");
513
		return;
514
	}
515
 
516
	Con_Printf ("joystick found\n");
517
 
518
	Con_Printf ("CENTER the joystick\nand press button 1 (ESC to skip):\n");
519
	if (!WaitJoyButton ())
520
		return;
521
	IN_ReadJoystick ();
522
	centerx = joystickx;
523
	centery = joysticky;
524
 
525
	Con_Printf ("Push the joystick to the UPPER LEFT\nand press button 1 (ESC to skip):\n");
526
	if (!WaitJoyButton ())
527
		return;
528
	IN_ReadJoystick ();
529
	joyxl = (centerx + joystickx)/2;
530
	joyyl = (centerx + joysticky)/2;
531
 
532
	Con_Printf ("Push the joystick to the LOWER RIGHT\nand press button 1 (ESC to skip):\n");
533
	if (!WaitJoyButton ())
534
		return;
535
	IN_ReadJoystick ();
536
	joyxh = (centerx + joystickx)/2;
537
	joyyh = (centery + joysticky)/2;
538
 
539
	joy_avail = true;
540
	Con_Printf ("joystick configured.\n");
541
 
542
 	Con_Printf ("\n");
543
}
544
 
545
 
546
/*
547
============================================================================
548
 
549
					EXTERNAL
550
 
551
============================================================================
552
*/
553
 
554
 
555
/*
556
===============
557
IN_StartupExternal
558
===============
559
*/
560
void IN_StartupExternal (void)
561
{
562
	if (extern_control->numButtons > 32)
563
		extern_control->numButtons = 32;
564
 
565
	Con_Printf("%s Initialized\n", extern_control->deviceName);
566
	Con_Printf("  %u axes  %u buttons\n", extern_control->numAxes, extern_control->numButtons);
567
 
568
	extern_avail = true;
569
	extern_buttons = extern_control->numButtons;
570
}
571
 
572
 
573
/*
574
===========
575
IN_ExternalMove
576
===========
577
*/
578
void IN_ExternalMove (usercmd_t *cmd)
579
{
580
	qboolean freelook;
581
 
582
	if (! extern_avail)
583
		return;
584
 
585
	extern_control->viewangles[YAW] = cl.viewangles[YAW];
586
	extern_control->viewangles[PITCH] = cl.viewangles[PITCH];
587
	extern_control->viewangles[ROLL] = cl.viewangles[ROLL];
588
	extern_control->forwardmove = cmd->forwardmove;
589
	extern_control->sidemove = cmd->sidemove;
590
	extern_control->upmove = cmd->upmove;
591
 
592
Con_DPrintf("IN:  y:%f p:%f r:%f f:%f s:%f u:%f\n", extern_control->viewangles[YAW], extern_control->viewangles[PITCH], extern_control->viewangles[ROLL], extern_control->forwardmove, extern_control->sidemove, extern_control->upmove);
593
 
594
	dos_int86(extern_control->interruptVector);
595
 
596
Con_DPrintf("OUT: y:%f p:%f r:%f f:%f s:%f u:%f\n", extern_control->viewangles[YAW], extern_control->viewangles[PITCH], extern_control->viewangles[ROLL], extern_control->forwardmove, extern_control->sidemove, extern_control->upmove);
597
 
598
	cl.viewangles[YAW] = extern_control->viewangles[YAW];
599
	cl.viewangles[PITCH] = extern_control->viewangles[PITCH];
600
	cl.viewangles[ROLL] = extern_control->viewangles[ROLL];
601
	cmd->forwardmove = extern_control->forwardmove;
602
	cmd->sidemove = extern_control->sidemove;
603
	cmd->upmove = extern_control->upmove;
604
 
605
	if (cl.viewangles[PITCH] > 80)
606
		cl.viewangles[PITCH] = 80;
607
	if (cl.viewangles[PITCH] < -70)
608
		cl.viewangles[PITCH] = -70;
609
 
610
	freelook = (extern_control->flags & AUX_FLAG_FREELOOK || aux_look.value || in_mlook.state & 1);
611
 
612
	if (freelook)
613
		V_StopPitchDrift ();
614
}
615