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 "quakedef.h"
31
 
32
#include 
33
 
34
#include 
35
#include 
36
 
37
#include 
38
#include 
39
 
40
#define WARP_WIDTH              320
41
#define WARP_HEIGHT             200
42
 
43
static Display *dpy = NULL;
44
static int scrnum;
45
static Window win;
46
static GLXContext ctx = NULL;
47
 
48
#define KEY_MASK (KeyPressMask | KeyReleaseMask)
49
#define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | \
50
		    PointerMotionMask | ButtonMotionMask )
51
#define X_MASK (KEY_MASK | MOUSE_MASK | VisibilityChangeMask | StructureNotifyMask )
52
 
53
 
54
unsigned short	d_8to16table[256];
55
unsigned		d_8to24table[256];
56
unsigned char	d_15to8table[65536];
57
 
58
cvar_t	vid_mode = {"vid_mode","0",false};
59
 
60
static qboolean        mouse_avail;
61
static qboolean        mouse_active;
62
static int   mx, my;
63
static int	old_mouse_x, old_mouse_y;
64
 
65
static cvar_t in_mouse = {"in_mouse", "1", false};
66
static cvar_t in_dgamouse = {"in_dgamouse", "1", false};
67
static cvar_t m_filter = {"m_filter", "0"};
68
 
69
qboolean dgamouse = false;
70
qboolean vidmode_ext = false;
71
 
72
static int win_x, win_y;
73
 
74
static int scr_width, scr_height;
75
 
76
static XF86VidModeModeInfo **vidmodes;
77
static int default_dotclock_vidmode;
78
static int num_vidmodes;
79
static qboolean vidmode_active = false;
80
 
81
/*-----------------------------------------------------------------------*/
82
 
83
//int		texture_mode = GL_NEAREST;
84
//int		texture_mode = GL_NEAREST_MIPMAP_NEAREST;
85
//int		texture_mode = GL_NEAREST_MIPMAP_LINEAR;
86
int		texture_mode = GL_LINEAR;
87
//int		texture_mode = GL_LINEAR_MIPMAP_NEAREST;
88
//int		texture_mode = GL_LINEAR_MIPMAP_LINEAR;
89
 
90
int		texture_extension_number = 1;
91
 
92
float		gldepthmin, gldepthmax;
93
 
94
cvar_t	gl_ztrick = {"gl_ztrick","1"};
95
 
96
const char *gl_vendor;
97
const char *gl_renderer;
98
const char *gl_version;
99
const char *gl_extensions;
100
 
101
void (*qglColorTableEXT) (int, int, int, int, int, const void*);
102
void (*qgl3DfxSetPaletteEXT) (GLuint *);
103
 
104
static float vid_gamma = 1.0;
105
 
106
qboolean is8bit = false;
107
qboolean isPermedia = false;
108
qboolean gl_mtexable = false;
109
 
110
/*-----------------------------------------------------------------------*/
111
void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
112
{
113
}
114
 
115
void D_EndDirectRect (int x, int y, int width, int height)
116
{
117
}
118
 
119
static int XLateKey(XKeyEvent *ev)
120
{
121
 
122
	int key;
123
	char buf[64];
124
	KeySym keysym;
125
 
126
	key = 0;
127
 
128
	XLookupString(ev, buf, sizeof buf, &keysym, 0);
129
 
130
	switch(keysym)
131
	{
132
		case XK_KP_Page_Up:
133
		case XK_Page_Up:	 key = K_PGUP; break;
134
 
135
		case XK_KP_Page_Down:
136
		case XK_Page_Down:	 key = K_PGDN; break;
137
 
138
		case XK_KP_Home:
139
		case XK_Home:	 key = K_HOME; break;
140
 
141
		case XK_KP_End:
142
		case XK_End:	 key = K_END; break;
143
 
144
		case XK_KP_Left:
145
		case XK_Left:	 key = K_LEFTARROW; break;
146
 
147
		case XK_KP_Right:
148
		case XK_Right:	key = K_RIGHTARROW;		break;
149
 
150
		case XK_KP_Down:
151
		case XK_Down:	 key = K_DOWNARROW; break;
152
 
153
		case XK_KP_Up:
154
		case XK_Up:		 key = K_UPARROW;	 break;
155
 
156
		case XK_Escape: key = K_ESCAPE;		break;
157
 
158
		case XK_KP_Enter:
159
		case XK_Return: key = K_ENTER;		 break;
160
 
161
		case XK_Tab:		key = K_TAB;			 break;
162
 
163
		case XK_F1:		 key = K_F1;				break;
164
 
165
		case XK_F2:		 key = K_F2;				break;
166
 
167
		case XK_F3:		 key = K_F3;				break;
168
 
169
		case XK_F4:		 key = K_F4;				break;
170
 
171
		case XK_F5:		 key = K_F5;				break;
172
 
173
		case XK_F6:		 key = K_F6;				break;
174
 
175
		case XK_F7:		 key = K_F7;				break;
176
 
177
		case XK_F8:		 key = K_F8;				break;
178
 
179
		case XK_F9:		 key = K_F9;				break;
180
 
181
		case XK_F10:		key = K_F10;			 break;
182
 
183
		case XK_F11:		key = K_F11;			 break;
184
 
185
		case XK_F12:		key = K_F12;			 break;
186
 
187
		case XK_BackSpace: key = K_BACKSPACE; break;
188
 
189
		case XK_KP_Delete:
190
		case XK_Delete: key = K_DEL; break;
191
 
192
		case XK_Pause:	key = K_PAUSE;		 break;
193
 
194
		case XK_Shift_L:
195
		case XK_Shift_R:	key = K_SHIFT;		break;
196
 
197
		case XK_Execute:
198
		case XK_Control_L:
199
		case XK_Control_R:	key = K_CTRL;		 break;
200
 
201
		case XK_Alt_L:
202
		case XK_Meta_L:
203
		case XK_Alt_R:
204
		case XK_Meta_R: key = K_ALT;			break;
205
 
206
		case XK_KP_Begin: key = '5';	break;
207
 
208
		case XK_KP_Insert:
209
		case XK_Insert:key = K_INS; break;
210
 
211
		case XK_KP_Multiply: key = '*'; break;
212
		case XK_KP_Add:  key = '+'; break;
213
		case XK_KP_Subtract: key = '-'; break;
214
		case XK_KP_Divide: key = '/'; break;
215
 
216
#if 0
217
		case 0x021: key = '1';break;/* [!] */
218
		case 0x040: key = '2';break;/* [@] */
219
		case 0x023: key = '3';break;/* [#] */
220
		case 0x024: key = '4';break;/* [$] */
221
		case 0x025: key = '5';break;/* [%] */
222
		case 0x05e: key = '6';break;/* [^] */
223
		case 0x026: key = '7';break;/* [&] */
224
		case 0x02a: key = '8';break;/* [*] */
225
		case 0x028: key = '9';;break;/* [(] */
226
		case 0x029: key = '0';break;/* [)] */
227
		case 0x05f: key = '-';break;/* [_] */
228
		case 0x02b: key = '=';break;/* [+] */
229
		case 0x07c: key = '\'';break;/* [|] */
230
		case 0x07d: key = '[';break;/* [}] */
231
		case 0x07b: key = ']';break;/* [{] */
232
		case 0x022: key = '\'';break;/* ["] */
233
		case 0x03a: key = ';';break;/* [:] */
234
		case 0x03f: key = '/';break;/* [?] */
235
		case 0x03e: key = '.';break;/* [>] */
236
		case 0x03c: key = ',';break;/* [<] */
237
#endif
238
 
239
		default:
240
			key = *(unsigned char*)buf;
241
			if (key >= 'A' && key <= 'Z')
242
				key = key - 'A' + 'a';
243
			break;
244
	}
245
 
246
	return key;
247
}
248
 
249
static Cursor CreateNullCursor(Display *display, Window root)
250
{
251
    Pixmap cursormask;
252
    XGCValues xgc;
253
    GC gc;
254
    XColor dummycolour;
255
    Cursor cursor;
256
 
257
    cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
258
    xgc.function = GXclear;
259
    gc =  XCreateGC(display, cursormask, GCFunction, &xgc);
260
    XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
261
    dummycolour.pixel = 0;
262
    dummycolour.red = 0;
263
    dummycolour.flags = 04;
264
    cursor = XCreatePixmapCursor(display, cursormask, cursormask,
265
          &dummycolour,&dummycolour, 0,0);
266
    XFreePixmap(display,cursormask);
267
    XFreeGC(display,gc);
268
    return cursor;
269
}
270
 
271
static void install_grabs(void)
272
{
273
 
274
// inviso cursor
275
	XDefineCursor(dpy, win, CreateNullCursor(dpy, win));
276
 
277
	XGrabPointer(dpy, win,
278
				 True,
279
				 0,
280
				 GrabModeAsync, GrabModeAsync,
281
				 win,
282
				 None,
283
				 CurrentTime);
284
 
285
	if (in_dgamouse.value) {
286
		int MajorVersion, MinorVersion;
287
 
288
		if (!XF86DGAQueryVersion(dpy, &MajorVersion, &MinorVersion)) {
289
			// unable to query, probalby not supported
290
			Con_Printf( "Failed to detect XF86DGA Mouse\n" );
291
			in_dgamouse.value = 0;
292
		} else {
293
			dgamouse = true;
294
			XF86DGADirectVideo(dpy, DefaultScreen(dpy), XF86DGADirectMouse);
295
			XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0);
296
		}
297
	} else {
298
		XWarpPointer(dpy, None, win,
299
					 0, 0, 0, 0,
300
					 vid.width / 2, vid.height / 2);
301
	}
302
 
303
	XGrabKeyboard(dpy, win,
304
				  False,
305
				  GrabModeAsync, GrabModeAsync,
306
				  CurrentTime);
307
 
308
	mouse_active = true;
309
 
310
//	XSync(dpy, True);
311
}
312
 
313
static void uninstall_grabs(void)
314
{
315
	if (!dpy || !win)
316
		return;
317
 
318
	if (dgamouse) {
319
		dgamouse = false;
320
		XF86DGADirectVideo(dpy, DefaultScreen(dpy), 0);
321
	}
322
 
323
	XUngrabPointer(dpy, CurrentTime);
324
	XUngrabKeyboard(dpy, CurrentTime);
325
 
326
// inviso cursor
327
	XUndefineCursor(dpy, win);
328
 
329
	mouse_active = false;
330
}
331
 
332
static void HandleEvents(void)
333
{
334
	XEvent event;
335
	KeySym ks;
336
	int b;
337
	qboolean dowarp = false;
338
	int mwx = vid.width/2;
339
	int mwy = vid.height/2;
340
 
341
	if (!dpy)
342
		return;
343
 
344
	while (XPending(dpy)) {
345
		XNextEvent(dpy, &event);
346
 
347
		switch (event.type) {
348
		case KeyPress:
349
		case KeyRelease:
350
			Key_Event(XLateKey(&event.xkey), event.type == KeyPress);
351
			break;
352
 
353
		case MotionNotify:
354
			if (mouse_active) {
355
				if (dgamouse) {
356
					mx += (event.xmotion.x + win_x) * 2;
357
					my += (event.xmotion.y + win_y) * 2;
358
				}
359
				else
360
				{
361
					mx += ((int)event.xmotion.x - mwx) * 2;
362
					my += ((int)event.xmotion.y - mwy) * 2;
363
					mwx = event.xmotion.x;
364
					mwy = event.xmotion.y;
365
 
366
					if (mx || my)
367
						dowarp = true;
368
				}
369
			}
370
			break;
371
 
372
			break;
373
 
374
		case ButtonPress:
375
			b=-1;
376
			if (event.xbutton.button == 1)
377
				b = 0;
378
			else if (event.xbutton.button == 2)
379
				b = 2;
380
			else if (event.xbutton.button == 3)
381
				b = 1;
382
			if (b>=0)
383
				Key_Event(K_MOUSE1 + b, true);
384
			break;
385
 
386
		case ButtonRelease:
387
			b=-1;
388
			if (event.xbutton.button == 1)
389
				b = 0;
390
			else if (event.xbutton.button == 2)
391
				b = 2;
392
			else if (event.xbutton.button == 3)
393
				b = 1;
394
			if (b>=0)
395
				Key_Event(K_MOUSE1 + b, false);
396
			break;
397
 
398
		case CreateNotify :
399
			win_x = event.xcreatewindow.x;
400
			win_y = event.xcreatewindow.y;
401
			break;
402
 
403
		case ConfigureNotify :
404
			win_x = event.xconfigure.x;
405
			win_y = event.xconfigure.y;
406
			break;
407
		}
408
	}
409
 
410
	if (dowarp) {
411
		/* move the mouse to the window center again */
412
		XWarpPointer(dpy, None, win, 0, 0, 0, 0, vid.width / 2, vid.height / 2);
413
	}
414
 
415
}
416
 
417
static void IN_DeactivateMouse( void )
418
{
419
	if (!mouse_avail || !dpy || !win)
420
		return;
421
 
422
	if (mouse_active) {
423
		uninstall_grabs();
424
		mouse_active = false;
425
	}
426
}
427
 
428
static void IN_ActivateMouse( void )
429
{
430
	if (!mouse_avail || !dpy || !win)
431
		return;
432
 
433
	if (!mouse_active) {
434
		mx = my = 0; // don't spazz
435
		install_grabs();
436
		mouse_active = true;
437
	}
438
}
439
 
440
 
441
void VID_Shutdown(void)
442
{
443
	if (!ctx || !dpy)
444
		return;
445
	IN_DeactivateMouse();
446
	if (dpy) {
447
		if (ctx)
448
			glXDestroyContext(dpy, ctx);
449
		if (win)
450
			XDestroyWindow(dpy, win);
451
		if (vidmode_active)
452
			XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[0]);
453
		XCloseDisplay(dpy);
454
	}
455
	vidmode_active = false;
456
	dpy = NULL;
457
	win = 0;
458
	ctx = NULL;
459
}
460
 
461
void signal_handler(int sig)
462
{
463
	printf("Received signal %d, exiting...\n", sig);
464
	Sys_Quit();
465
	exit(0);
466
}
467
 
468
void InitSig(void)
469
{
470
	signal(SIGHUP, signal_handler);
471
	signal(SIGINT, signal_handler);
472
	signal(SIGQUIT, signal_handler);
473
	signal(SIGILL, signal_handler);
474
	signal(SIGTRAP, signal_handler);
475
	signal(SIGIOT, signal_handler);
476
	signal(SIGBUS, signal_handler);
477
	signal(SIGFPE, signal_handler);
478
	signal(SIGSEGV, signal_handler);
479
	signal(SIGTERM, signal_handler);
480
}
481
 
482
void VID_ShiftPalette(unsigned char *p)
483
{
484
//	VID_SetPalette(p);
485
}
486
 
487
void	VID_SetPalette (unsigned char *palette)
488
{
489
	byte	*pal;
490
	unsigned r,g,b;
491
	unsigned v;
492
	int     r1,g1,b1;
493
	int		j,k,l,m;
494
	unsigned short i;
495
	unsigned	*table;
496
	FILE *f;
497
	char s[255];
498
	int dist, bestdist;
499
 
500
//
501
// 8 8 8 encoding
502
//
503
	pal = palette;
504
	table = d_8to24table;
505
	for (i=0 ; i<256 ; i++)
506
	{
507
		r = pal[0];
508
		g = pal[1];
509
		b = pal[2];
510
		pal += 3;
511
 
512
		v = (255<<24) + (r<<0) + (g<<8) + (b<<16);
513
		*table++ = v;
514
	}
515
	d_8to24table[255] &= 0xffffff;	// 255 is transparent
516
 
517
	for (i=0; i < (1<<15); i++) {
518
		/* Maps
519
		000000000000000
520
		000000000011111 = Red  = 0x1F
521
		000001111100000 = Blue = 0x03E0
522
		111110000000000 = Grn  = 0x7C00
523
		*/
524
		r = ((i & 0x1F) << 3)+4;
525
		g = ((i & 0x03E0) >> 2)+4;
526
		b = ((i & 0x7C00) >> 7)+4;
527
		pal = (unsigned char *)d_8to24table;
528
		for (v=0,k=0,bestdist=10000*10000; v<256; v++,pal+=4) {
529
			r1 = (int)r - (int)pal[0];
530
			g1 = (int)g - (int)pal[1];
531
			b1 = (int)b - (int)pal[2];
532
			dist = (r1*r1)+(g1*g1)+(b1*b1);
533
			if (dist < bestdist) {
534
				k=v;
535
				bestdist = dist;
536
			}
537
		}
538
		d_15to8table[i]=k;
539
	}
540
}
541
 
542
void CheckMultiTextureExtensions(void)
543
{
544
	void *prjobj;
545
 
546
	if (strstr(gl_extensions, "GL_SGIS_multitexture ") && !COM_CheckParm("-nomtex")) {
547
		Con_Printf("Found GL_SGIS_multitexture...\n");
548
 
549
		if ((prjobj = dlopen(NULL, RTLD_LAZY)) == NULL) {
550
			Con_Printf("Unable to open symbol list for main program.\n");
551
			return;
552
		}
553
 
554
		qglMTexCoord2fSGIS = (void *) dlsym(prjobj, "glMTexCoord2fSGIS");
555
		qglSelectTextureSGIS = (void *) dlsym(prjobj, "glSelectTextureSGIS");
556
 
557
		if (qglMTexCoord2fSGIS && qglSelectTextureSGIS) {
558
			Con_Printf("Multitexture extensions found.\n");
559
			gl_mtexable = true;
560
		} else
561
			Con_Printf("Symbol not found, disabled.\n");
562
 
563
		dlclose(prjobj);
564
	}
565
}
566
 
567
/*
568
===============
569
GL_Init
570
===============
571
*/
572
void GL_Init (void)
573
{
574
	gl_vendor = glGetString (GL_VENDOR);
575
	Con_Printf ("GL_VENDOR: %s\n", gl_vendor);
576
	gl_renderer = glGetString (GL_RENDERER);
577
	Con_Printf ("GL_RENDERER: %s\n", gl_renderer);
578
 
579
	gl_version = glGetString (GL_VERSION);
580
	Con_Printf ("GL_VERSION: %s\n", gl_version);
581
	gl_extensions = glGetString (GL_EXTENSIONS);
582
	Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions);
583
 
584
//	Con_Printf ("%s %s\n", gl_renderer, gl_version);
585
 
586
	CheckMultiTextureExtensions ();
587
 
588
	glClearColor (1,0,0,0);
589
	glCullFace(GL_FRONT);
590
	glEnable(GL_TEXTURE_2D);
591
 
592
	glEnable(GL_ALPHA_TEST);
593
	glAlphaFunc(GL_GREATER, 0.666);
594
 
595
	glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
596
	glShadeModel (GL_FLAT);
597
 
598
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
599
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
600
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
601
	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
602
 
603
	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
604
 
605
//	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
606
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
607
}
608
 
609
/*
610
=================
611
GL_BeginRendering
612
 
613
=================
614
*/
615
void GL_BeginRendering (int *x, int *y, int *width, int *height)
616
{
617
	extern cvar_t gl_clear;
618
 
619
	*x = *y = 0;
620
	*width = scr_width;
621
	*height = scr_height;
622
 
623
//    if (!wglMakeCurrent( maindc, baseRC ))
624
//		Sys_Error ("wglMakeCurrent failed");
625
 
626
//	glViewport (*x, *y, *width, *height);
627
}
628
 
629
 
630
void GL_EndRendering (void)
631
{
632
	glFlush();
633
	glXSwapBuffers(dpy, win);
634
}
635
 
636
qboolean VID_Is8bit(void)
637
{
638
	return is8bit;
639
}
640
 
641
void VID_Init8bitPalette(void)
642
{
643
	// Check for 8bit Extensions and initialize them.
644
	int i;
645
	void *prjobj;
646
 
647
	if ((prjobj = dlopen(NULL, RTLD_LAZY)) == NULL) {
648
		Con_Printf("Unable to open symbol list for main program.\n");
649
		return;
650
	}
651
 
652
	if (strstr(gl_extensions, "3DFX_set_global_palette") &&
653
		(qgl3DfxSetPaletteEXT = dlsym(prjobj, "gl3DfxSetPaletteEXT")) != NULL) {
654
		GLubyte table[256][4];
655
		char *oldpal;
656
 
657
		Con_SafePrintf("8-bit GL extensions enabled.\n");
658
		glEnable( GL_SHARED_TEXTURE_PALETTE_EXT );
659
		oldpal = (char *) d_8to24table; //d_8to24table3dfx;
660
		for (i=0;i<256;i++) {
661
			table[i][2] = *oldpal++;
662
			table[i][1] = *oldpal++;
663
			table[i][0] = *oldpal++;
664
			table[i][3] = 255;
665
			oldpal++;
666
		}
667
		qgl3DfxSetPaletteEXT((GLuint *)table);
668
		is8bit = true;
669
 
670
	} else if (strstr(gl_extensions, "GL_EXT_shared_texture_palette") &&
671
		(qglColorTableEXT = dlsym(prjobj, "glColorTableEXT")) != NULL) {
672
		char thePalette[256*3];
673
		char *oldPalette, *newPalette;
674
 
675
		Con_SafePrintf("8-bit GL extensions enabled.\n");
676
		glEnable( GL_SHARED_TEXTURE_PALETTE_EXT );
677
		oldPalette = (char *) d_8to24table; //d_8to24table3dfx;
678
		newPalette = thePalette;
679
		for (i=0;i<256;i++) {
680
			*newPalette++ = *oldPalette++;
681
			*newPalette++ = *oldPalette++;
682
			*newPalette++ = *oldPalette++;
683
			oldPalette++;
684
		}
685
		qglColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGB, 256, GL_RGB, GL_UNSIGNED_BYTE, (void *) thePalette);
686
		is8bit = true;
687
	}
688
 
689
	dlclose(prjobj);
690
}
691
 
692
static void Check_Gamma (unsigned char *pal)
693
{
694
	float	f, inf;
695
	unsigned char	palette[768];
696
	int		i;
697
 
698
	if ((i = COM_CheckParm("-gamma")) == 0) {
699
		if ((gl_renderer && strstr(gl_renderer, "Voodoo")) ||
700
			(gl_vendor && strstr(gl_vendor, "3Dfx")))
701
			vid_gamma = 1;
702
		else
703
			vid_gamma = 0.7; // default to 0.7 on non-3dfx hardware
704
	} else
705
		vid_gamma = Q_atof(com_argv[i+1]);
706
 
707
	for (i=0 ; i<768 ; i++)
708
	{
709
		f = pow ( (pal[i]+1)/256.0 , vid_gamma );
710
		inf = f*255 + 0.5;
711
		if (inf < 0)
712
			inf = 0;
713
		if (inf > 255)
714
			inf = 255;
715
		palette[i] = inf;
716
	}
717
 
718
	memcpy (pal, palette, sizeof(palette));
719
}
720
 
721
void VID_Init(unsigned char *palette)
722
{
723
	int i;
724
	int attrib[] = {
725
		GLX_RGBA,
726
		GLX_RED_SIZE, 1,
727
		GLX_GREEN_SIZE, 1,
728
		GLX_BLUE_SIZE, 1,
729
		GLX_DOUBLEBUFFER,
730
		GLX_DEPTH_SIZE, 1,
731
		None
732
	};
733
	char	gldir[MAX_OSPATH];
734
	int width = 640, height = 480;
735
	XSetWindowAttributes attr;
736
	unsigned long mask;
737
	Window root;
738
	XVisualInfo *visinfo;
739
	qboolean fullscreen = true;
740
	int MajorVersion, MinorVersion;
741
	int actualWidth, actualHeight;
742
 
743
	Cvar_RegisterVariable (&vid_mode);
744
	Cvar_RegisterVariable (&in_mouse);
745
	Cvar_RegisterVariable (&in_dgamouse);
746
	Cvar_RegisterVariable (&m_filter);
747
	Cvar_RegisterVariable (&gl_ztrick);
748
 
749
	vid.maxwarpwidth = WARP_WIDTH;
750
	vid.maxwarpheight = WARP_HEIGHT;
751
	vid.colormap = host_colormap;
752
	vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
753
 
754
// interpret command-line params
755
 
756
// set vid parameters
757
	if ((i = COM_CheckParm("-window")) != 0)
758
		fullscreen = false;
759
 
760
	if ((i = COM_CheckParm("-width")) != 0)
761
		width = atoi(com_argv[i+1]);
762
 
763
	if ((i = COM_CheckParm("-height")) != 0)
764
		height = atoi(com_argv[i+1]);
765
 
766
	if ((i = COM_CheckParm("-conwidth")) != 0)
767
		vid.conwidth = Q_atoi(com_argv[i+1]);
768
	else
769
		vid.conwidth = 640;
770
 
771
	vid.conwidth &= 0xfff8; // make it a multiple of eight
772
 
773
	if (vid.conwidth < 320)
774
		vid.conwidth = 320;
775
 
776
	// pick a conheight that matches with correct aspect
777
	vid.conheight = vid.conwidth*3 / 4;
778
 
779
	if ((i = COM_CheckParm("-conheight")) != 0)
780
		vid.conheight = Q_atoi(com_argv[i+1]);
781
	if (vid.conheight < 200)
782
		vid.conheight = 200;
783
 
784
	if (!(dpy = XOpenDisplay(NULL))) {
785
		fprintf(stderr, "Error couldn't open the X display\n");
786
		exit(1);
787
	}
788
 
789
	scrnum = DefaultScreen(dpy);
790
	root = RootWindow(dpy, scrnum);
791
 
792
	// Get video mode list
793
	MajorVersion = MinorVersion = 0;
794
	if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion)) {
795
		vidmode_ext = false;
796
	} else {
797
		Con_Printf("Using XFree86-VidModeExtension Version %d.%d\n", MajorVersion, MinorVersion);
798
		vidmode_ext = true;
799
	}
800
 
801
	visinfo = glXChooseVisual(dpy, scrnum, attrib);
802
	if (!visinfo) {
803
		fprintf(stderr, "qkHack: Error couldn't get an RGB, Double-buffered, Depth visual\n");
804
		exit(1);
805
	}
806
 
807
	if (vidmode_ext) {
808
		int best_fit, best_dist, dist, x, y;
809
 
810
		XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes);
811
 
812
		// Are we going fullscreen?  If so, let's change video mode
813
		if (fullscreen) {
814
			best_dist = 9999999;
815
			best_fit = -1;
816
 
817
			for (i = 0; i < num_vidmodes; i++) {
818
				if (width > vidmodes[i]->hdisplay ||
819
					height > vidmodes[i]->vdisplay)
820
					continue;
821
 
822
				x = width - vidmodes[i]->hdisplay;
823
				y = height - vidmodes[i]->vdisplay;
824
				dist = (x * x) + (y * y);
825
				if (dist < best_dist) {
826
					best_dist = dist;
827
					best_fit = i;
828
				}
829
			}
830
 
831
			if (best_fit != -1) {
832
				actualWidth = vidmodes[best_fit]->hdisplay;
833
				actualHeight = vidmodes[best_fit]->vdisplay;
834
 
835
				// change to the mode
836
				XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]);
837
				vidmode_active = true;
838
 
839
				// Move the viewport to top left
840
				XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
841
			} else
842
				fullscreen = 0;
843
		}
844
	}
845
 
846
	/* window attributes */
847
	attr.background_pixel = 0;
848
	attr.border_pixel = 0;
849
	attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
850
	attr.event_mask = X_MASK;
851
	if (vidmode_active) {
852
		mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
853
			CWEventMask | CWOverrideRedirect;
854
		attr.override_redirect = True;
855
		attr.backing_store = NotUseful;
856
		attr.save_under = False;
857
	} else
858
		mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
859
 
860
	win = XCreateWindow(dpy, root, 0, 0, width, height,
861
						0, visinfo->depth, InputOutput,
862
						visinfo->visual, mask, &attr);
863
	XMapWindow(dpy, win);
864
 
865
	if (vidmode_active) {
866
		XMoveWindow(dpy, win, 0, 0);
867
		XRaiseWindow(dpy, win);
868
		XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0);
869
		XFlush(dpy);
870
		// Move the viewport to top left
871
		XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
872
	}
873
 
874
	XFlush(dpy);
875
 
876
	ctx = glXCreateContext(dpy, visinfo, NULL, True);
877
 
878
	glXMakeCurrent(dpy, win, ctx);
879
 
880
	scr_width = width;
881
	scr_height = height;
882
 
883
	if (vid.conheight > height)
884
		vid.conheight = height;
885
	if (vid.conwidth > width)
886
		vid.conwidth = width;
887
	vid.width = vid.conwidth;
888
	vid.height = vid.conheight;
889
 
890
	vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0);
891
	vid.numpages = 2;
892
 
893
	InitSig(); // trap evil signals
894
 
895
	GL_Init();
896
 
897
	sprintf (gldir, "%s/glquake", com_gamedir);
898
	Sys_mkdir (gldir);
899
 
900
	VID_SetPalette(palette);
901
 
902
	// Check for 3DFX Extensions and initialize them.
903
	VID_Init8bitPalette();
904
 
905
	Con_SafePrintf ("Video mode %dx%d initialized.\n", width, height);
906
 
907
	vid.recalc_refdef = 1;				// force a surface cache flush
908
}
909
 
910
void Sys_SendKeyEvents(void)
911
{
912
	HandleEvents();
913
}
914
 
915
void Force_CenterView_f (void)
916
{
917
	cl.viewangles[PITCH] = 0;
918
}
919
 
920
void IN_Init(void)
921
{
922
}
923
 
924
void IN_Shutdown(void)
925
{
926
}
927
 
928
/*
929
===========
930
IN_Commands
931
===========
932
*/
933
void IN_Commands (void)
934
{
935
	if (!dpy || !win)
936
		return;
937
 
938
	if (vidmode_active || key_dest == key_game)
939
		IN_ActivateMouse();
940
	else
941
		IN_DeactivateMouse ();
942
}
943
 
944
/*
945
===========
946
IN_Move
947
===========
948
*/
949
void IN_MouseMove (usercmd_t *cmd)
950
{
951
	if (!mouse_avail)
952
		return;
953
 
954
	if (m_filter.value)
955
	{
956
		mx = (mx + old_mouse_x) * 0.5;
957
		my = (my + old_mouse_y) * 0.5;
958
	}
959
	old_mouse_x = mx;
960
	old_mouse_y = my;
961
 
962
	mx *= sensitivity.value;
963
	my *= sensitivity.value;
964
 
965
// add mouse X/Y movement to cmd
966
	if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) ))
967
		cmd->sidemove += m_side.value * mx;
968
	else
969
		cl.viewangles[YAW] -= m_yaw.value * mx;
970
 
971
	if (in_mlook.state & 1)
972
		V_StopPitchDrift ();
973
 
974
	if ( (in_mlook.state & 1) && !(in_strafe.state & 1))
975
	{
976
		cl.viewangles[PITCH] += m_pitch.value * my;
977
		if (cl.viewangles[PITCH] > 80)
978
			cl.viewangles[PITCH] = 80;
979
		if (cl.viewangles[PITCH] < -70)
980
			cl.viewangles[PITCH] = -70;
981
	}
982
	else
983
	{
984
		if ((in_strafe.state & 1) && noclip_anglehack)
985
			cmd->upmove -= m_forward.value * my;
986
		else
987
			cmd->forwardmove -= m_forward.value * my;
988
	}
989
	mx = my = 0;
990
}
991
 
992
void IN_Move (usercmd_t *cmd)
993
{
994
	IN_MouseMove(cmd);
995
}
996
 
997