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
#include 
21
#include 
22
#include 
23
#include 
24
#include 
25
#include 
26
#include 
27
 
28
#include 
29
 
30
#include "vga.h"
31
#include "vgakeyboard.h"
32
#include "vgamouse.h"
33
 
34
#include "quakedef.h"
35
#include "d_local.h"
36
 
37
#define stringify(m) { #m, m }
38
 
39
unsigned short       d_8to16table[256];
40
static byte		*vid_surfcache;
41
static int		VID_highhunkmark;
42
 
43
int num_modes;
44
vga_modeinfo *modes;
45
int current_mode;
46
 
47
int num_shades=32;
48
 
49
struct
50
{
51
	char *name;
52
	int num;
53
} mice[] =
54
{
55
	stringify(MOUSE_MICROSOFT),
56
	stringify(MOUSE_MOUSESYSTEMS),
57
	stringify(MOUSE_MMSERIES),
58
	stringify(MOUSE_LOGITECH),
59
	stringify(MOUSE_BUSMOUSE),
60
	stringify(MOUSE_PS2),
61
};
62
 
63
static unsigned char scantokey[128];
64
static byte vid_current_palette[768];
65
 
66
int num_mice = sizeof (mice) / sizeof(mice[0]);
67
 
68
int	d_con_indirect = 0;
69
 
70
int		svgalib_inited=0;
71
int		UseMouse = 1;
72
int		UseDisplay = 1;
73
int		UseKeyboard = 1;
74
 
75
int		mouserate = MOUSE_DEFAULTSAMPLERATE;
76
 
77
cvar_t		vid_mode = {"vid_mode","5",false};
78
cvar_t		vid_redrawfull = {"vid_redrawfull","0",false};
79
cvar_t		vid_waitforrefresh = {"vid_waitforrefresh","0",true};
80
 
81
char	*framebuffer_ptr;
82
 
83
cvar_t  mouse_button_commands[3] =
84
{
85
    {"mouse1","+attack"},
86
    {"mouse2","+strafe"},
87
    {"mouse3","+forward"},
88
};
89
 
90
int     mouse_buttons;
91
int     mouse_buttonstate;
92
int     mouse_oldbuttonstate;
93
float   mouse_x, mouse_y;
94
float	old_mouse_x, old_mouse_y;
95
int		mx, my;
96
 
97
cvar_t	m_filter = {"m_filter","0"};
98
 
99
static byte     backingbuf[48*24];
100
 
101
int		VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes, VGA_planar;
102
byte	*VGA_pagebase;
103
 
104
void VGA_UpdatePlanarScreen (void *srcbuffer);
105
 
106
void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
107
{
108
	int i, j, k, plane, reps, repshift, offset, vidpage, off;
109
 
110
	if (!svgalib_inited || !vid.direct || !vga_oktowrite()) return;
111
 
112
	if (vid.aspect > 1.5)
113
	{
114
		reps = 2;
115
		repshift = 1;
116
	} else {
117
		reps = 1;
118
		repshift = 0;
119
	}
120
 
121
	vidpage = 0;
122
	vga_setpage(0);
123
 
124
	if (VGA_planar)
125
	{
126
		for (plane=0 ; plane<4 ; plane++)
127
		{
128
		// select the correct plane for reading and writing
129
			outb(0x02, 0x3C4);
130
			outb(1 << plane, 0x3C5);
131
			outb(4, 0x3CE);
132
			outb(plane, 0x3CF);
133
 
134
			for (i=0 ; i<(height << repshift) ; i += reps)
135
			{
136
				for (k=0 ; k
137
				{
138
					for (j=0 ; j<(width >> 2) ; j++)
139
					{
140
						backingbuf[(i + k) * 24 + (j << 2) + plane] =
141
								vid.direct[(y + i + k) * VGA_rowbytes +
142
								(x >> 2) + j];
143
						vid.direct[(y + i + k) * VGA_rowbytes + (x>>2) + j] =
144
								pbitmap[(i >> repshift) * 24 +
145
								(j << 2) + plane];
146
					}
147
				}
148
			}
149
		}
150
	} else {
151
		for (i=0 ; i<(height << repshift) ; i += reps)
152
		{
153
			for (j=0 ; j
154
			{
155
				offset = x + ((y << repshift) + i + j) * vid.rowbytes;
156
				off = offset % 0x10000;
157
				if ((offset / 0x10000) != vidpage) {
158
					vidpage=offset / 0x10000;
159
					vga_setpage(vidpage);
160
				}
161
				memcpy (&backingbuf[(i + j) * 24],
162
						vid.direct + off, width);
163
				memcpy (vid.direct + off,
164
						&pbitmap[(i >> repshift)*width], width);
165
			}
166
		}
167
	}
168
}
169
 
170
void D_EndDirectRect (int x, int y, int width, int height)
171
{
172
	int i, j, k, plane, reps, repshift, offset, vidpage, off;
173
 
174
	if (!svgalib_inited || !vid.direct || !vga_oktowrite()) return;
175
 
176
	if (vid.aspect > 1.5)
177
	{
178
		reps = 2;
179
		repshift = 1;
180
	} else {
181
		reps = 1;
182
		repshift = 0;
183
	}
184
 
185
	vidpage = 0;
186
	vga_setpage(0);
187
 
188
	if (VGA_planar)
189
	{
190
		for (plane=0 ; plane<4 ; plane++)
191
		{
192
		// select the correct plane for writing
193
			outb(2, 0x3C4);
194
			outb(1 << plane, 0x3C5);
195
			outb(4, 0x3CE);
196
			outb(plane, 0x3CF);
197
 
198
			for (i=0 ; i<(height << repshift) ; i += reps)
199
			{
200
				for (k=0 ; k
201
				{
202
					for (j=0 ; j<(width >> 2) ; j++)
203
					{
204
						vid.direct[(y + i + k) * VGA_rowbytes + (x>>2) + j] =
205
								backingbuf[(i + k) * 24 + (j << 2) + plane];
206
					}
207
				}
208
			}
209
		}
210
	} else {
211
		for (i=0 ; i<(height << repshift) ; i += reps)
212
		{
213
			for (j=0 ; j
214
			{
215
				offset = x + ((y << repshift) + i + j) * vid.rowbytes;
216
				off = offset % 0x10000;
217
				if ((offset / 0x10000) != vidpage) {
218
					vidpage=offset / 0x10000;
219
					vga_setpage(vidpage);
220
				}
221
				memcpy (vid.direct + off,
222
						&backingbuf[(i +j)*24],
223
						width);
224
			}
225
		}
226
	}
227
}
228
 
229
/*
230
=================
231
VID_Gamma_f
232
 
233
Keybinding command
234
=================
235
*/
236
void VID_Gamma_f (void)
237
{
238
	float	gamma, f, inf;
239
	unsigned char	palette[768];
240
	int		i;
241
 
242
	if (Cmd_Argc () == 2)
243
	{
244
		gamma = Q_atof (Cmd_Argv(1));
245
 
246
		for (i=0 ; i<768 ; i++)
247
		{
248
			f = pow ( (host_basepal[i]+1)/256.0 , gamma );
249
			inf = f*255 + 0.5;
250
			if (inf < 0)
251
				inf = 0;
252
			if (inf > 255)
253
				inf = 255;
254
			palette[i] = inf;
255
		}
256
 
257
		VID_SetPalette (palette);
258
 
259
		vid.recalc_refdef = 1;				// force a surface cache flush
260
	}
261
}
262
 
263
void VID_DescribeMode_f (void)
264
{
265
	int modenum;
266
 
267
	modenum = Q_atoi (Cmd_Argv(1));
268
	if ((modenum >= num_modes) || (modenum < 0 ) || !modes[modenum].width)
269
		Con_Printf("Invalid video mode: %d!\n",modenum);
270
	Con_Printf("%d: %d x %d - ",modenum,modes[modenum].width,modes[modenum].height);
271
	if (modes[modenum].bytesperpixel == 0)
272
		Con_Printf("ModeX\n");
273
	else
274
		Con_Printf("%d bpp\n", modes[modenum].bytesperpixel<<3);
275
}
276
 
277
void VID_DescribeModes_f (void)
278
{
279
	int i;
280
 
281
	for (i=0;i
282
		if (modes[i].width) {
283
			Con_Printf("%d: %d x %d - ", i, modes[i].width,modes[i].height);
284
			if (modes[i].bytesperpixel == 0)
285
				Con_Printf("ModeX\n");
286
			else
287
				Con_Printf("%d bpp\n", modes[i].bytesperpixel<<3);
288
		}
289
}
290
 
291
/*
292
================
293
VID_NumModes
294
================
295
*/
296
int VID_NumModes ()
297
{
298
	int i,i1=0;
299
 
300
	for (i=0;i
301
		i1+=(modes[i].width?1:0);
302
	return (i1);
303
}
304
 
305
void VID_NumModes_f (void)
306
{
307
	Con_Printf("%d modes\n",VID_NumModes());
308
}
309
 
310
void VID_Debug_f (void)
311
{
312
	Con_Printf("mode: %d\n",current_mode);
313
	Con_Printf("height x width: %d x %d\n",vid.height,vid.width);
314
	Con_Printf("bpp: %d\n",modes[current_mode].bytesperpixel*8);
315
	Con_Printf("vid.aspect: %f\n",vid.aspect);
316
}
317
 
318
 
319
 
320
void VID_InitModes(void)
321
{
322
 
323
	int i;
324
 
325
// get complete information on all modes
326
 
327
	num_modes = vga_lastmodenumber()+1;
328
	modes = Z_Malloc(num_modes * sizeof(vga_modeinfo));
329
	for (i=0 ; i
330
	{
331
		if (vga_hasmode(i))
332
			Q_memcpy(&modes[i], vga_getmodeinfo(i), sizeof (vga_modeinfo));
333
		else
334
			modes[i].width = 0; // means not available
335
	}
336
 
337
// filter for modes i don't support
338
 
339
	for (i=0 ; i
340
	{
341
		if (modes[i].bytesperpixel != 1 && modes[i].colors != 256)
342
			modes[i].width = 0;
343
	}
344
 
345
}
346
 
347
int get_mode(char *name, int width, int height, int depth)
348
{
349
 
350
	int i;
351
	int ok, match;
352
 
353
	match = (!!width) + (!!height)*2 + (!!depth)*4;
354
 
355
	if (name)
356
	{
357
		i = vga_getmodenumber(name);
358
		if (!modes[i].width)
359
		{
360
			Sys_Printf("Mode [%s] not supported\n", name);
361
			i = G320x200x256;
362
		}
363
	}
364
	else
365
	{
366
		for (i=0 ; i
367
			if (modes[i].width)
368
			{
369
				ok = (modes[i].width == width)
370
					+ (modes[i].height == height)*2
371
					+ (modes[i].bytesperpixel == depth/8)*4;
372
				if ((ok & match) == ok)
373
					break;
374
			}
375
		if (i==num_modes)
376
		{
377
			Sys_Printf("Mode %dx%d (%d bits) not supported\n",
378
				width, height, depth);
379
			i = G320x200x256;
380
		}
381
	}
382
 
383
	return i;
384
 
385
}
386
 
387
int matchmouse(int mouse, char *name)
388
{
389
	int i;
390
	for (i=0 ; i
391
		if (!strcmp(mice[i].name, name))
392
			return i;
393
	return mouse;
394
}
395
 
396
#if 0
397
 
398
void vtswitch(int newconsole)
399
{
400
 
401
	int fd;
402
	struct vt_stat x;
403
 
404
// switch consoles and wait until reactivated
405
	fd = open("/dev/console", O_RDONLY);
406
	ioctl(fd, VT_GETSTATE, &x);
407
	ioctl(fd, VT_ACTIVATE, newconsole);
408
	ioctl(fd, VT_WAITACTIVE, x.v_active);
409
	close(fd);
410
 
411
}
412
 
413
#endif
414
 
415
void keyhandler(int scancode, int state)
416
{
417
 
418
	int sc;
419
 
420
	sc = scancode & 0x7f;
421
//	Con_Printf("scancode=%x (%d%s)\n", scancode, sc, scancode&0x80?"+128":"");
422
	Key_Event(scantokey[sc], state == KEY_EVENTPRESS);
423
 
424
}
425
 
426
void VID_Shutdown(void)
427
{
428
 
429
	if (!svgalib_inited) return;
430
 
431
//	printf("shutdown graphics called\n");
432
	if (UseKeyboard)
433
		keyboard_close();
434
	if (UseDisplay)
435
		vga_setmode(TEXT);
436
//	printf("shutdown graphics finished\n");
437
 
438
	svgalib_inited = 0;
439
 
440
}
441
 
442
void VID_ShiftPalette(unsigned char *p)
443
{
444
	VID_SetPalette(p);
445
}
446
 
447
void VID_SetPalette(byte *palette)
448
{
449
 
450
	static int tmppal[256*3];
451
	int *tp;
452
	int i;
453
 
454
	if (!svgalib_inited)
455
		return;
456
 
457
	memcpy(vid_current_palette, palette, sizeof(vid_current_palette));
458
 
459
	if (vga_getcolors() == 256)
460
	{
461
 
462
		tp = tmppal;
463
		for (i=256*3 ; i ; i--)
464
			*(tp++) = *(palette++) >> 2;
465
 
466
		if (UseDisplay && vga_oktowrite())
467
			vga_setpalvec(0, 256, tmppal);
468
 
469
	}
470
}
471
 
472
int VID_SetMode (int modenum, unsigned char *palette)
473
{
474
	int bsize, zsize, tsize;
475
 
476
	if ((modenum >= num_modes) || (modenum < 0) || !modes[modenum].width)
477
	{
478
		Cvar_SetValue ("vid_mode", (float)current_mode);
479
 
480
		Con_Printf("No such video mode: %d\n",modenum);
481
 
482
		return 0;
483
	}
484
 
485
	Cvar_SetValue ("vid_mode", (float)modenum);
486
 
487
	current_mode=modenum;
488
 
489
	vid.width = modes[current_mode].width;
490
	vid.height = modes[current_mode].height;
491
 
492
	VGA_width = modes[current_mode].width;
493
	VGA_height = modes[current_mode].height;
494
	VGA_planar = modes[current_mode].bytesperpixel == 0;
495
	VGA_rowbytes = modes[current_mode].linewidth;
496
	vid.rowbytes = modes[current_mode].linewidth;
497
	if (VGA_planar) {
498
		VGA_bufferrowbytes = modes[current_mode].linewidth * 4;
499
		vid.rowbytes = modes[current_mode].linewidth*4;
500
	}
501
 
502
	vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0);
503
	vid.colormap = (pixel_t *) host_colormap;
504
	vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
505
	vid.conrowbytes = vid.rowbytes;
506
	vid.conwidth = vid.width;
507
	vid.conheight = vid.height;
508
	vid.numpages = 1;
509
 
510
	vid.maxwarpwidth = WARP_WIDTH;
511
	vid.maxwarpheight = WARP_HEIGHT;
512
 
513
	// alloc zbuffer and surface cache
514
	if (d_pzbuffer) {
515
		D_FlushCaches();
516
		Hunk_FreeToHighMark (VID_highhunkmark);
517
		d_pzbuffer = NULL;
518
		vid_surfcache = NULL;
519
	}
520
 
521
	bsize = vid.rowbytes * vid.height;
522
	tsize = D_SurfaceCacheForRes (vid.width, vid.height);
523
	zsize = vid.width * vid.height * sizeof(*d_pzbuffer);
524
 
525
	VID_highhunkmark = Hunk_HighMark ();
526
 
527
	d_pzbuffer = Hunk_HighAllocName (bsize+tsize+zsize, "video");
528
 
529
	vid_surfcache = ((byte *)d_pzbuffer) + zsize;
530
 
531
	vid.conbuffer = vid.buffer = (pixel_t *)(((byte *)d_pzbuffer) + zsize + tsize);
532
 
533
	D_InitCaches (vid_surfcache, tsize);
534
 
535
// get goin'
536
 
537
	vga_setmode(current_mode);
538
	VID_SetPalette(palette);
539
 
540
	VGA_pagebase = vid.direct = framebuffer_ptr = (char *) vga_getgraphmem();
541
//		if (vga_setlinearaddressing()>0)
542
//			framebuffer_ptr = (char *) vga_getgraphmem();
543
	if (!framebuffer_ptr)
544
		Sys_Error("This mode isn't hapnin'\n");
545
 
546
	vga_setpage(0);
547
 
548
	svgalib_inited=1;
549
 
550
	vid.recalc_refdef = 1;				// force a surface cache flush
551
 
552
	return 0;
553
}
554
 
555
void VID_Init(unsigned char *palette)
556
{
557
 
558
	int i;
559
	int w, h, d;
560
 
561
	if (svgalib_inited)
562
		return;
563
 
564
//	Cmd_AddCommand ("gamma", VID_Gamma_f);
565
 
566
	if (UseDisplay)
567
	{
568
		vga_init();
569
 
570
		VID_InitModes();
571
 
572
		Cvar_RegisterVariable (&vid_mode);
573
		Cvar_RegisterVariable (&vid_redrawfull);
574
		Cvar_RegisterVariable (&vid_waitforrefresh);
575
 
576
		Cmd_AddCommand("vid_nummodes", VID_NumModes_f);
577
		Cmd_AddCommand("vid_describemode", VID_DescribeMode_f);
578
		Cmd_AddCommand("vid_describemodes", VID_DescribeModes_f);
579
		Cmd_AddCommand("vid_debug", VID_Debug_f);
580
 
581
	// interpret command-line params
582
 
583
		w = h = d = 0;
584
		if (getenv("GSVGAMODE"))
585
			current_mode = get_mode(getenv("GSVGAMODE"), w, h, d);
586
		else if (COM_CheckParm("-mode"))
587
			current_mode = get_mode(com_argv[COM_CheckParm("-mode")+1], w, h, d);
588
		else if (COM_CheckParm("-w") || COM_CheckParm("-h")
589
			|| COM_CheckParm("-d"))
590
		{
591
			if (COM_CheckParm("-w"))
592
				w = Q_atoi(com_argv[COM_CheckParm("-w")+1]);
593
			if (COM_CheckParm("-h"))
594
				h = Q_atoi(com_argv[COM_CheckParm("-h")+1]);
595
			if (COM_CheckParm("-d"))
596
				d = Q_atoi(com_argv[COM_CheckParm("-d")+1]);
597
			current_mode = get_mode(0, w, h, d);
598
		}
599
		else
600
			current_mode = G320x200x256;
601
 
602
	// set vid parameters
603
		VID_SetMode(current_mode, palette);
604
 
605
		VID_SetPalette(palette);
606
 
607
		// we do want to run in the background when switched away
608
		vga_runinbackground(1);
609
	}
610
 
611
	if (COM_CheckParm("-nokbd")) UseKeyboard = 0;
612
 
613
	if (UseKeyboard)
614
	{
615
		for (i=0 ; i<128 ; i++)
616
			scantokey[i] = ' ';
617
 
618
		scantokey[42] = K_SHIFT;
619
		scantokey[54] = K_SHIFT;
620
		scantokey[72] = K_UPARROW;
621
		scantokey[103] = K_UPARROW;
622
		scantokey[80] = K_DOWNARROW;
623
		scantokey[108] = K_DOWNARROW;
624
		scantokey[75] = K_LEFTARROW;
625
		scantokey[105] = K_LEFTARROW;
626
		scantokey[77] = K_RIGHTARROW;
627
		scantokey[106] = K_RIGHTARROW;
628
		scantokey[29] = K_CTRL;
629
		scantokey[97] = K_CTRL;
630
		scantokey[56] = K_ALT;
631
		scantokey[100] = K_ALT;
632
//		scantokey[58] = JK_CAPS;
633
//		scantokey[69] = JK_NUM_LOCK;
634
		scantokey[71] = K_HOME;
635
		scantokey[73] = K_PGUP;
636
		scantokey[79] = K_END;
637
		scantokey[81] = K_PGDN;
638
		scantokey[82] = K_INS;
639
		scantokey[83] = K_DEL;
640
		scantokey[1 ] = K_ESCAPE;
641
		scantokey[28] = K_ENTER;
642
		scantokey[15] = K_TAB;
643
		scantokey[14] = K_BACKSPACE;
644
		scantokey[119] = K_PAUSE;
645
    	scantokey[57] = ' ';
646
 
647
		scantokey[102] = K_HOME;
648
		scantokey[104] = K_PGUP;
649
		scantokey[107] = K_END;
650
		scantokey[109] = K_PGDN;
651
		scantokey[110] = K_INS;
652
		scantokey[111] = K_DEL;
653
 
654
		scantokey[2] = '1';
655
		scantokey[3] = '2';
656
		scantokey[4] = '3';
657
		scantokey[5] = '4';
658
		scantokey[6] = '5';
659
		scantokey[7] = '6';
660
		scantokey[8] = '7';
661
		scantokey[9] = '8';
662
		scantokey[10] = '9';
663
		scantokey[11] = '0';
664
		scantokey[12] = '-';
665
		scantokey[13] = '=';
666
		scantokey[41] = '`';
667
		scantokey[26] = '[';
668
		scantokey[27] = ']';
669
		scantokey[39] = ';';
670
		scantokey[40] = '\'';
671
		scantokey[51] = ',';
672
		scantokey[52] = '.';
673
		scantokey[53] = '/';
674
		scantokey[43] = '\\';
675
 
676
		scantokey[59] = K_F1;
677
		scantokey[60] = K_F2;
678
		scantokey[61] = K_F3;
679
		scantokey[62] = K_F4;
680
		scantokey[63] = K_F5;
681
		scantokey[64] = K_F6;
682
		scantokey[65] = K_F7;
683
		scantokey[66] = K_F8;
684
		scantokey[67] = K_F9;
685
		scantokey[68] = K_F10;
686
		scantokey[87] = K_F11;
687
		scantokey[88] = K_F12;
688
		scantokey[30] = 'a';
689
		scantokey[48] = 'b';
690
		scantokey[46] = 'c';
691
        scantokey[32] = 'd';
692
        scantokey[18] = 'e';
693
        scantokey[33] = 'f';
694
        scantokey[34] = 'g';
695
        scantokey[35] = 'h';
696
        scantokey[23] = 'i';
697
        scantokey[36] = 'j';
698
        scantokey[37] = 'k';
699
        scantokey[38] = 'l';
700
        scantokey[50] = 'm';
701
        scantokey[49] = 'n';
702
        scantokey[24] = 'o';
703
        scantokey[25] = 'p';
704
        scantokey[16] = 'q';
705
        scantokey[19] = 'r';
706
        scantokey[31] = 's';
707
        scantokey[20] = 't';
708
        scantokey[22] = 'u';
709
        scantokey[47] = 'v';
710
        scantokey[17] = 'w';
711
        scantokey[45] = 'x';
712
        scantokey[21] = 'y';
713
        scantokey[44] = 'z';
714
 
715
		if (keyboard_init())
716
			Sys_Error("keyboard_init() failed");
717
		keyboard_seteventhandler(keyhandler);
718
	}
719
 
720
}
721
 
722
void VID_Update(vrect_t *rects)
723
{
724
	if (!svgalib_inited)
725
		return;
726
 
727
	if (!vga_oktowrite())
728
		return; // can't update screen if it's not active
729
 
730
	if (vid_waitforrefresh.value)
731
		vga_waitretrace();
732
 
733
	if (VGA_planar)
734
		VGA_UpdatePlanarScreen (vid.buffer);
735
 
736
	else if (vid_redrawfull.value) {
737
		int total = vid.rowbytes * vid.height;
738
		int offset;
739
 
740
		for (offset=0;offset
741
			vga_setpage(offset/0x10000);
742
			memcpy(framebuffer_ptr,
743
					vid.buffer + offset,
744
					((total-offset>0x10000)?0x10000:(total-offset)));
745
		}
746
	} else {
747
		int ycount;
748
		int offset;
749
		int vidpage=0;
750
 
751
		vga_setpage(0);
752
 
753
		while (rects)
754
		{
755
			ycount = rects->height;
756
			offset = rects->y * vid.rowbytes + rects->x;
757
			while (ycount--)
758
			{
759
				register int i = offset % 0x10000;
760
 
761
				if ((offset / 0x10000) != vidpage) {
762
					vidpage=offset / 0x10000;
763
					vga_setpage(vidpage);
764
				}
765
				if (rects->width + i > 0x10000) {
766
					memcpy(framebuffer_ptr + i,
767
							vid.buffer + offset,
768
							0x10000 - i);
769
					vga_setpage(++vidpage);
770
					memcpy(framebuffer_ptr,
771
							vid.buffer + offset + 0x10000 - i,
772
							rects->width - 0x10000 + i);
773
				} else
774
					memcpy(framebuffer_ptr + i,
775
							vid.buffer + offset,
776
							rects->width);
777
				offset += vid.rowbytes;
778
			}
779
 
780
			rects = rects->pnext;
781
		}
782
	}
783
 
784
	if (vid_mode.value != current_mode)
785
		VID_SetMode ((int)vid_mode.value, vid_current_palette);
786
}
787
 
788
static int dither;
789
 
790
void VID_DitherOn(void)
791
{
792
    if (dither == 0)
793
    {
794
//		R_ViewChanged (&vrect, sb_lines, vid.aspect);
795
        dither = 1;
796
    }
797
}
798
 
799
void VID_DitherOff(void)
800
{
801
    if (dither)
802
    {
803
//		R_ViewChanged (&vrect, sb_lines, vid.aspect);
804
        dither = 0;
805
    }
806
}
807
 
808
void Sys_SendKeyEvents(void)
809
{
810
	if (!svgalib_inited)
811
		return;
812
 
813
	if (UseKeyboard)
814
		while (keyboard_update());
815
}
816
 
817
void Force_CenterView_f (void)
818
{
819
	cl.viewangles[PITCH] = 0;
820
}
821
 
822
 
823
void mousehandler(int buttonstate, int dx, int dy)
824
{
825
	mouse_buttonstate = buttonstate;
826
	mx += dx;
827
	my += dy;
828
}
829
 
830
void IN_Init(void)
831
{
832
 
833
	int mtype;
834
	char *mousedev;
835
	int mouserate;
836
 
837
	if (UseMouse)
838
	{
839
 
840
		Cvar_RegisterVariable (&mouse_button_commands[0]);
841
		Cvar_RegisterVariable (&mouse_button_commands[1]);
842
		Cvar_RegisterVariable (&mouse_button_commands[2]);
843
		Cvar_RegisterVariable (&m_filter);
844
		Cmd_AddCommand ("force_centerview", Force_CenterView_f);
845
 
846
		mouse_buttons = 3;
847
 
848
		mtype = vga_getmousetype();
849
 
850
		mousedev = "/dev/mouse";
851
		if (getenv("MOUSEDEV")) mousedev = getenv("MOUSEDEV");
852
		if (COM_CheckParm("-mdev"))
853
			mousedev = com_argv[COM_CheckParm("-mdev")+1];
854
 
855
		mouserate = 1200;
856
		if (getenv("MOUSERATE")) mouserate = atoi(getenv("MOUSERATE"));
857
		if (COM_CheckParm("-mrate"))
858
			mouserate = atoi(com_argv[COM_CheckParm("-mrate")+1]);
859
 
860
//		printf("Mouse: dev=%s,type=%s,speed=%d\n",
861
//			mousedev, mice[mtype].name, mouserate);
862
		if (mouse_init(mousedev, mtype, mouserate))
863
		{
864
			Con_Printf("No mouse found\n");
865
			UseMouse = 0;
866
		}
867
		else
868
			mouse_seteventhandler(mousehandler);
869
 
870
	}
871
 
872
}
873
 
874
void IN_Shutdown(void)
875
{
876
	if (UseMouse)
877
		mouse_close();
878
}
879
 
880
/*
881
===========
882
IN_Commands
883
===========
884
*/
885
void IN_Commands (void)
886
{
887
	if (UseMouse && cls.state != ca_dedicated)
888
	{
889
		// poll mouse values
890
		while (mouse_update())
891
			;
892
 
893
		// perform button actions
894
		if ((mouse_buttonstate & MOUSE_LEFTBUTTON) &&
895
			!(mouse_oldbuttonstate & MOUSE_LEFTBUTTON))
896
			Key_Event (K_MOUSE1, true);
897
		else if (!(mouse_buttonstate & MOUSE_LEFTBUTTON) &&
898
			(mouse_oldbuttonstate & MOUSE_LEFTBUTTON))
899
			Key_Event (K_MOUSE1, false);
900
 
901
		if ((mouse_buttonstate & MOUSE_RIGHTBUTTON) &&
902
			!(mouse_oldbuttonstate & MOUSE_RIGHTBUTTON))
903
			Key_Event (K_MOUSE2, true);
904
		else if (!(mouse_buttonstate & MOUSE_RIGHTBUTTON) &&
905
			(mouse_oldbuttonstate & MOUSE_RIGHTBUTTON))
906
			Key_Event (K_MOUSE2, false);
907
 
908
		if ((mouse_buttonstate & MOUSE_MIDDLEBUTTON) &&
909
			!(mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON))
910
			Key_Event (K_MOUSE3, true);
911
		else if (!(mouse_buttonstate & MOUSE_MIDDLEBUTTON) &&
912
			(mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON))
913
			Key_Event (K_MOUSE3, false);
914
 
915
		mouse_oldbuttonstate = mouse_buttonstate;
916
	}
917
}
918
 
919
/*
920
===========
921
IN_Move
922
===========
923
*/
924
void IN_MouseMove (usercmd_t *cmd)
925
{
926
	if (!UseMouse)
927
		return;
928
 
929
	// poll mouse values
930
	while (mouse_update())
931
		;
932
 
933
	if (m_filter.value)
934
	{
935
		mouse_x = (mx + old_mouse_x) * 0.5;
936
		mouse_y = (my + old_mouse_y) * 0.5;
937
	}
938
	else
939
	{
940
		mouse_x = mx;
941
		mouse_y = my;
942
	}
943
	old_mouse_x = mx;
944
	old_mouse_y = my;
945
	mx = my = 0; // clear for next update
946
 
947
	mouse_x *= sensitivity.value;
948
	mouse_y *= sensitivity.value;
949
 
950
// add mouse X/Y movement to cmd
951
	if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) ))
952
		cmd->sidemove += m_side.value * mouse_x;
953
	else
954
		cl.viewangles[YAW] -= m_yaw.value * mouse_x;
955
 
956
	if (in_mlook.state & 1)
957
		V_StopPitchDrift ();
958
 
959
	if ( (in_mlook.state & 1) && !(in_strafe.state & 1))
960
	{
961
		cl.viewangles[PITCH] += m_pitch.value * mouse_y;
962
		if (cl.viewangles[PITCH] > 80)
963
			cl.viewangles[PITCH] = 80;
964
		if (cl.viewangles[PITCH] < -70)
965
			cl.viewangles[PITCH] = -70;
966
	}
967
	else
968
	{
969
		if ((in_strafe.state & 1) && noclip_anglehack)
970
			cmd->upmove -= m_forward.value * mouse_y;
971
		else
972
			cmd->forwardmove -= m_forward.value * mouse_y;
973
	}
974
}
975
 
976
void IN_Move (usercmd_t *cmd)
977
{
978
	IN_MouseMove(cmd);
979
}
980
 
981
 
982
/*
983
================
984
VID_ModeInfo
985
================
986
*/
987
char *VID_ModeInfo (int modenum)
988
{
989
	static char	*badmodestr = "Bad mode number";
990
	static char modestr[40];
991
 
992
	if (modenum == 0)
993
	{
994
		sprintf (modestr, "%d x %d, %d bpp",
995
				 vid.width, vid.height, modes[current_mode].bytesperpixel*8);
996
		return (modestr);
997
	}
998
	else
999
	{
1000
		return (badmodestr);
1001
	}
1002
}
1003