summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/quake/gl_vidlinuxglx.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/sdl/progs/quake/gl_vidlinuxglx.c')
-rw-r--r--apps/plugins/sdl/progs/quake/gl_vidlinuxglx.c997
1 files changed, 997 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/quake/gl_vidlinuxglx.c b/apps/plugins/sdl/progs/quake/gl_vidlinuxglx.c
new file mode 100644
index 0000000000..400adb4678
--- /dev/null
+++ b/apps/plugins/sdl/progs/quake/gl_vidlinuxglx.c
@@ -0,0 +1,997 @@
1/*
2Copyright (C) 1996-1997 Id Software, Inc.
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, 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 <dlfcn.h>
29
30#include "quakedef.h"
31
32#include <GL/glx.h>
33
34#include <X11/keysym.h>
35#include <X11/cursorfont.h>
36
37#include <X11/extensions/xf86dga.h>
38#include <X11/extensions/xf86vmode.h>
39
40#define WARP_WIDTH 320
41#define WARP_HEIGHT 200
42
43static Display *dpy = NULL;
44static int scrnum;
45static Window win;
46static 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
54unsigned short d_8to16table[256];
55unsigned d_8to24table[256];
56unsigned char d_15to8table[65536];
57
58cvar_t vid_mode = {"vid_mode","0",false};
59
60static qboolean mouse_avail;
61static qboolean mouse_active;
62static int mx, my;
63static int old_mouse_x, old_mouse_y;
64
65static cvar_t in_mouse = {"in_mouse", "1", false};
66static cvar_t in_dgamouse = {"in_dgamouse", "1", false};
67static cvar_t m_filter = {"m_filter", "0"};
68
69qboolean dgamouse = false;
70qboolean vidmode_ext = false;
71
72static int win_x, win_y;
73
74static int scr_width, scr_height;
75
76static XF86VidModeModeInfo **vidmodes;
77static int default_dotclock_vidmode;
78static int num_vidmodes;
79static 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;
86int texture_mode = GL_LINEAR;
87//int texture_mode = GL_LINEAR_MIPMAP_NEAREST;
88//int texture_mode = GL_LINEAR_MIPMAP_LINEAR;
89
90int texture_extension_number = 1;
91
92float gldepthmin, gldepthmax;
93
94cvar_t gl_ztrick = {"gl_ztrick","1"};
95
96const char *gl_vendor;
97const char *gl_renderer;
98const char *gl_version;
99const char *gl_extensions;
100
101void (*qglColorTableEXT) (int, int, int, int, int, const void*);
102void (*qgl3DfxSetPaletteEXT) (GLuint *);
103
104static float vid_gamma = 1.0;
105
106qboolean is8bit = false;
107qboolean isPermedia = false;
108qboolean gl_mtexable = false;
109
110/*-----------------------------------------------------------------------*/
111void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
112{
113}
114
115void D_EndDirectRect (int x, int y, int width, int height)
116{
117}
118
119static 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
249static 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
271static 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
313static 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
332static 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
417static 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
428static 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
441void 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
461void signal_handler(int sig)
462{
463 printf("Received signal %d, exiting...\n", sig);
464 Sys_Quit();
465 exit(0);
466}
467
468void 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
482void VID_ShiftPalette(unsigned char *p)
483{
484// VID_SetPalette(p);
485}
486
487void 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
542void 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===============
569GL_Init
570===============
571*/
572void 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=================
611GL_BeginRendering
612
613=================
614*/
615void 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
630void GL_EndRendering (void)
631{
632 glFlush();
633 glXSwapBuffers(dpy, win);
634}
635
636qboolean VID_Is8bit(void)
637{
638 return is8bit;
639}
640
641void 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
692static 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
721void 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
910void Sys_SendKeyEvents(void)
911{
912 HandleEvents();
913}
914
915void Force_CenterView_f (void)
916{
917 cl.viewangles[PITCH] = 0;
918}
919
920void IN_Init(void)
921{
922}
923
924void IN_Shutdown(void)
925{
926}
927
928/*
929===========
930IN_Commands
931===========
932*/
933void 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===========
946IN_Move
947===========
948*/
949void 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
992void IN_Move (usercmd_t *cmd)
993{
994 IN_MouseMove(cmd);
995}
996
997