• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <termios.h>
21 #include <sys/ioctl.h>
22 #include <sys/stat.h>
23 #include <sys/vt.h>
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <signal.h>
27 
28 #include <asm/io.h>
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 
D_BeginDirectRect(int x,int y,byte * pbitmap,int width,int height)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<reps ; 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<reps ; 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 
D_EndDirectRect(int x,int y,int width,int height)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<reps ; 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<reps ; 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 */
VID_Gamma_f(void)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 
VID_DescribeMode_f(void)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 
VID_DescribeModes_f(void)277 void VID_DescribeModes_f (void)
278 {
279 	int i;
280 
281 	for (i=0;i<num_modes;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 */
VID_NumModes()296 int VID_NumModes ()
297 {
298 	int i,i1=0;
299 
300 	for (i=0;i<num_modes;i++)
301 		i1+=(modes[i].width?1:0);
302 	return (i1);
303 }
304 
VID_NumModes_f(void)305 void VID_NumModes_f (void)
306 {
307 	Con_Printf("%d modes\n",VID_NumModes());
308 }
309 
VID_Debug_f(void)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 
VID_InitModes(void)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<num_modes ; 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<num_modes ; i++)
340 	{
341 		if (modes[i].bytesperpixel != 1 && modes[i].colors != 256)
342 			modes[i].width = 0;
343 	}
344 
345 }
346 
get_mode(char * name,int width,int height,int depth)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<num_modes ; 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 
matchmouse(int mouse,char * name)387 int matchmouse(int mouse, char *name)
388 {
389 	int i;
390 	for (i=0 ; i<num_mice ; 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 
keyhandler(int scancode,int state)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 
VID_Shutdown(void)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 
VID_ShiftPalette(unsigned char * p)442 void VID_ShiftPalette(unsigned char *p)
443 {
444 	VID_SetPalette(p);
445 }
446 
VID_SetPalette(byte * palette)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 
VID_SetMode(int modenum,unsigned char * palette)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 
VID_Init(unsigned char * palette)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 
VID_Update(vrect_t * rects)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<total;offset+=0x10000) {
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 
VID_DitherOn(void)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 
VID_DitherOff(void)799 void VID_DitherOff(void)
800 {
801     if (dither)
802     {
803 //		R_ViewChanged (&vrect, sb_lines, vid.aspect);
804         dither = 0;
805     }
806 }
807 
Sys_SendKeyEvents(void)808 void Sys_SendKeyEvents(void)
809 {
810 	if (!svgalib_inited)
811 		return;
812 
813 	if (UseKeyboard)
814 		while (keyboard_update());
815 }
816 
Force_CenterView_f(void)817 void Force_CenterView_f (void)
818 {
819 	cl.viewangles[PITCH] = 0;
820 }
821 
822 
mousehandler(int buttonstate,int dx,int dy)823 void mousehandler(int buttonstate, int dx, int dy)
824 {
825 	mouse_buttonstate = buttonstate;
826 	mx += dx;
827 	my += dy;
828 }
829 
IN_Init(void)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 
IN_Shutdown(void)874 void IN_Shutdown(void)
875 {
876 	if (UseMouse)
877 		mouse_close();
878 }
879 
880 /*
881 ===========
882 IN_Commands
883 ===========
884 */
IN_Commands(void)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 */
IN_MouseMove(usercmd_t * cmd)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 
IN_Move(usercmd_t * cmd)976 void IN_Move (usercmd_t *cmd)
977 {
978 	IN_MouseMove(cmd);
979 }
980 
981 
982 /*
983 ================
984 VID_ModeInfo
985 ================
986 */
VID_ModeInfo(int modenum)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 
1004