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 "quakedef.h"
29
30 #include <GL/glx.h>
31
32 #include <X11/keysym.h>
33 #include <X11/cursorfont.h>
34
35 #ifdef USE_DGA
36 #include <X11/extensions/xf86dga.h>
37 #endif
38
39
40 #define WARP_WIDTH 320
41 #define WARP_HEIGHT 200
42
43 static Display *dpy = NULL;
44 static Window win;
45 static GLXContext ctx = NULL;
46
47 static float old_windowed_mouse = 0;
48
49 #define KEY_MASK (KeyPressMask | KeyReleaseMask)
50 #define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | \
51 PointerMotionMask)
52
53 #define X_MASK (KEY_MASK | MOUSE_MASK | VisibilityChangeMask)
54
55 unsigned short d_8to16table[256];
56 unsigned d_8to24table[256];
57 unsigned char d_15to8table[65536];
58
59 cvar_t _windowed_mouse = {"_windowed_mouse","0", true};
60 cvar_t vid_mode = {"vid_mode","0",false};
61
62 static float mouse_x, mouse_y;
63 static float old_mouse_x, old_mouse_y;
64
65 cvar_t m_filter = {"m_filter", "0"};
66
67 static int scr_width, scr_height;
68
69 /*-----------------------------------------------------------------------*/
70
71 //int texture_mode = GL_NEAREST;
72 //int texture_mode = GL_NEAREST_MIPMAP_NEAREST;
73 //int texture_mode = GL_NEAREST_MIPMAP_LINEAR;
74 int texture_mode = GL_LINEAR;
75 //int texture_mode = GL_LINEAR_MIPMAP_NEAREST;
76 //int texture_mode = GL_LINEAR_MIPMAP_LINEAR;
77
78 int texture_extension_number = 1;
79
80 float gldepthmin, gldepthmax;
81
82 cvar_t gl_ztrick = {"gl_ztrick","1"};
83
84 const char *gl_vendor;
85 const char *gl_renderer;
86 const char *gl_version;
87 const char *gl_extensions;
88
89 qboolean is8bit = false;
90 qboolean isPermedia = false;
91 qboolean gl_mtexable = false;
92
93 /*-----------------------------------------------------------------------*/
D_BeginDirectRect(int x,int y,byte * pbitmap,int width,int height)94 void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
95 {
96 }
97
D_EndDirectRect(int x,int y,int width,int height)98 void D_EndDirectRect (int x, int y, int width, int height)
99 {
100 }
101
XLateKey(XKeyEvent * ev)102 static int XLateKey(XKeyEvent *ev)
103 {
104
105 int key;
106 char buf[64];
107 KeySym keysym;
108
109 key = 0;
110
111 XLookupString(ev, buf, sizeof buf, &keysym, 0);
112
113 switch(keysym)
114 {
115 case XK_KP_Page_Up:
116 case XK_Page_Up: key = K_PGUP; break;
117
118 case XK_KP_Page_Down:
119 case XK_Page_Down: key = K_PGDN; break;
120
121 case XK_KP_Home:
122 case XK_Home: key = K_HOME; break;
123
124 case XK_KP_End:
125 case XK_End: key = K_END; break;
126
127 case XK_KP_Left:
128 case XK_Left: key = K_LEFTARROW; break;
129
130 case XK_KP_Right:
131 case XK_Right: key = K_RIGHTARROW; break;
132
133 case XK_KP_Down:
134 case XK_Down: key = K_DOWNARROW; break;
135
136 case XK_KP_Up:
137 case XK_Up: key = K_UPARROW; break;
138
139 case XK_Escape: key = K_ESCAPE; break;
140
141 case XK_KP_Enter:
142 case XK_Return: key = K_ENTER; break;
143
144 case XK_Tab: key = K_TAB; break;
145
146 case XK_F1: key = K_F1; break;
147
148 case XK_F2: key = K_F2; break;
149
150 case XK_F3: key = K_F3; break;
151
152 case XK_F4: key = K_F4; break;
153
154 case XK_F5: key = K_F5; break;
155
156 case XK_F6: key = K_F6; break;
157
158 case XK_F7: key = K_F7; break;
159
160 case XK_F8: key = K_F8; break;
161
162 case XK_F9: key = K_F9; break;
163
164 case XK_F10: key = K_F10; break;
165
166 case XK_F11: key = K_F11; break;
167
168 case XK_F12: key = K_F12; break;
169
170 case XK_BackSpace: key = K_BACKSPACE; break;
171
172 case XK_KP_Delete:
173 case XK_Delete: key = K_DEL; break;
174
175 case XK_Pause: key = K_PAUSE; break;
176
177 case XK_Shift_L:
178 case XK_Shift_R: key = K_SHIFT; break;
179
180 case XK_Execute:
181 case XK_Control_L:
182 case XK_Control_R: key = K_CTRL; break;
183
184 case XK_Alt_L:
185 case XK_Meta_L:
186 case XK_Alt_R:
187 case XK_Meta_R: key = K_ALT; break;
188
189 case XK_KP_Begin: key = '5'; break;
190
191 case XK_KP_Insert:
192 case XK_Insert:key = K_INS; break;
193
194 case XK_KP_Multiply: key = '*'; break;
195 case XK_KP_Add: key = '+'; break;
196 case XK_KP_Subtract: key = '-'; break;
197 case XK_KP_Divide: key = '/'; break;
198
199 #if 0
200 case 0x021: key = '1';break;/* [!] */
201 case 0x040: key = '2';break;/* [@] */
202 case 0x023: key = '3';break;/* [#] */
203 case 0x024: key = '4';break;/* [$] */
204 case 0x025: key = '5';break;/* [%] */
205 case 0x05e: key = '6';break;/* [^] */
206 case 0x026: key = '7';break;/* [&] */
207 case 0x02a: key = '8';break;/* [*] */
208 case 0x028: key = '9';;break;/* [(] */
209 case 0x029: key = '0';break;/* [)] */
210 case 0x05f: key = '-';break;/* [_] */
211 case 0x02b: key = '=';break;/* [+] */
212 case 0x07c: key = '\'';break;/* [|] */
213 case 0x07d: key = '[';break;/* [}] */
214 case 0x07b: key = ']';break;/* [{] */
215 case 0x022: key = '\'';break;/* ["] */
216 case 0x03a: key = ';';break;/* [:] */
217 case 0x03f: key = '/';break;/* [?] */
218 case 0x03e: key = '.';break;/* [>] */
219 case 0x03c: key = ',';break;/* [<] */
220 #endif
221
222 default:
223 key = *(unsigned char*)buf;
224 if (key >= 'A' && key <= 'Z')
225 key = key - 'A' + 'a';
226 break;
227 }
228
229 return key;
230 }
231
install_grabs(void)232 static void install_grabs(void)
233 {
234 XGrabPointer(dpy, win,
235 True,
236 0,
237 GrabModeAsync, GrabModeAsync,
238 win,
239 None,
240 CurrentTime);
241
242 #ifdef USE_DGA
243 XF86DGADirectVideo(dpy, DefaultScreen(dpy), XF86DGADirectMouse);
244 dgamouse = 1;
245 #else
246 XWarpPointer(dpy, None, win,
247 0, 0, 0, 0,
248 vid.width / 2, vid.height / 2);
249 #endif
250
251 XGrabKeyboard(dpy, win,
252 False,
253 GrabModeAsync, GrabModeAsync,
254 CurrentTime);
255
256 // XSync(dpy, True);
257 }
258
uninstall_grabs(void)259 static void uninstall_grabs(void)
260 {
261 #ifdef USE_DGA
262 XF86DGADirectVideo(dpy, DefaultScreen(dpy), 0);
263 dgamouse = 0;
264 #endif
265
266 XUngrabPointer(dpy, CurrentTime);
267 XUngrabKeyboard(dpy, CurrentTime);
268
269 // XSync(dpy, True);
270 }
271
GetEvent(void)272 static void GetEvent(void)
273 {
274 XEvent event;
275 int b;
276
277 if (!dpy)
278 return;
279
280 XNextEvent(dpy, &event);
281
282 switch (event.type) {
283 case KeyPress:
284 case KeyRelease:
285 Key_Event(XLateKey(&event.xkey), event.type == KeyPress);
286 break;
287
288 case MotionNotify:
289 #ifdef USE_DGA
290 if (dgamouse && _windowed_mouse.value) {
291 mouse_x = event.xmotion.x_root;
292 mouse_y = event.xmotion.y_root;
293 } else
294 #endif
295 {
296 if (_windowed_mouse.value) {
297 mouse_x = (float) ((int)event.xmotion.x - (int)(vid.width/2));
298 mouse_y = (float) ((int)event.xmotion.y - (int)(vid.height/2));
299
300 /* move the mouse to the window center again */
301 XSelectInput(dpy, win, X_MASK & ~PointerMotionMask);
302 XWarpPointer(dpy, None, win, 0, 0, 0, 0,
303 (vid.width/2), (vid.height/2));
304 XSelectInput(dpy, win, X_MASK);
305 }
306 }
307 break;
308
309 case ButtonPress:
310 b=-1;
311 if (event.xbutton.button == 1)
312 b = 0;
313 else if (event.xbutton.button == 2)
314 b = 2;
315 else if (event.xbutton.button == 3)
316 b = 1;
317 if (b>=0)
318 Key_Event(K_MOUSE1 + b, true);
319 break;
320
321 case ButtonRelease:
322 b=-1;
323 if (event.xbutton.button == 1)
324 b = 0;
325 else if (event.xbutton.button == 2)
326 b = 2;
327 else if (event.xbutton.button == 3)
328 b = 1;
329 if (b>=0)
330 Key_Event(K_MOUSE1 + b, false);
331 break;
332 }
333
334 if (old_windowed_mouse != _windowed_mouse.value) {
335 old_windowed_mouse = _windowed_mouse.value;
336
337 if (!_windowed_mouse.value) {
338 /* ungrab the pointer */
339 uninstall_grabs();
340 } else {
341 /* grab the pointer */
342 install_grabs();
343 }
344 }
345 }
346
347
VID_Shutdown(void)348 void VID_Shutdown(void)
349 {
350 if (!ctx)
351 return;
352
353 glXDestroyContext(dpy, ctx);
354 }
355
signal_handler(int sig)356 void signal_handler(int sig)
357 {
358 printf("Received signal %d, exiting...\n", sig);
359 Sys_Quit();
360 exit(0);
361 }
362
InitSig(void)363 void InitSig(void)
364 {
365 signal(SIGHUP, signal_handler);
366 signal(SIGINT, signal_handler);
367 signal(SIGQUIT, signal_handler);
368 signal(SIGILL, signal_handler);
369 signal(SIGTRAP, signal_handler);
370 signal(SIGIOT, signal_handler);
371 signal(SIGBUS, signal_handler);
372 signal(SIGFPE, signal_handler);
373 signal(SIGSEGV, signal_handler);
374 signal(SIGTERM, signal_handler);
375 }
376
VID_ShiftPalette(unsigned char * p)377 void VID_ShiftPalette(unsigned char *p)
378 {
379 // VID_SetPalette(p);
380 }
381
VID_SetPalette(unsigned char * palette)382 void VID_SetPalette (unsigned char *palette)
383 {
384 byte *pal;
385 unsigned r,g,b;
386 unsigned v;
387 int r1,g1,b1;
388 int k;
389 unsigned short i;
390 unsigned *table;
391 FILE *f;
392 char s[255];
393 float dist, bestdist;
394 static qboolean palflag = false;
395
396 //
397 // 8 8 8 encoding
398 //
399 Con_Printf("Converting 8to24\n");
400
401 pal = palette;
402 table = d_8to24table;
403 for (i=0 ; i<256 ; i++)
404 {
405 r = pal[0];
406 g = pal[1];
407 b = pal[2];
408 pal += 3;
409
410 // v = (255<<24) + (r<<16) + (g<<8) + (b<<0);
411 // v = (255<<0) + (r<<8) + (g<<16) + (b<<24);
412 v = (255<<24) + (r<<0) + (g<<8) + (b<<16);
413 *table++ = v;
414 }
415 d_8to24table[255] &= 0xffffff; // 255 is transparent
416
417 // JACK: 3D distance calcs - k is last closest, l is the distance.
418 // FIXME: Precalculate this and cache to disk.
419 if (palflag)
420 return;
421 palflag = true;
422
423 COM_FOpenFile("glquake/15to8.pal", &f);
424 if (f) {
425 fread(d_15to8table, 1<<15, 1, f);
426 fclose(f);
427 } else {
428 for (i=0; i < (1<<15); i++) {
429 /* Maps
430 000000000000000
431 000000000011111 = Red = 0x1F
432 000001111100000 = Blue = 0x03E0
433 111110000000000 = Grn = 0x7C00
434 */
435 r = ((i & 0x1F) << 3)+4;
436 g = ((i & 0x03E0) >> 2)+4;
437 b = ((i & 0x7C00) >> 7)+4;
438 pal = (unsigned char *)d_8to24table;
439 for (v=0,k=0,bestdist=10000.0; v<256; v++,pal+=4) {
440 r1 = (int)r - (int)pal[0];
441 g1 = (int)g - (int)pal[1];
442 b1 = (int)b - (int)pal[2];
443 dist = sqrt(((r1*r1)+(g1*g1)+(b1*b1)));
444 if (dist < bestdist) {
445 k=v;
446 bestdist = dist;
447 }
448 }
449 d_15to8table[i]=k;
450 }
451 sprintf(s, "%s/glquake", com_gamedir);
452 Sys_mkdir (s);
453 sprintf(s, "%s/glquake/15to8.pal", com_gamedir);
454 if ((f = fopen(s, "wb")) != NULL) {
455 fwrite(d_15to8table, 1<<15, 1, f);
456 fclose(f);
457 }
458 }
459 }
460
461 /*
462 ===============
463 GL_Init
464 ===============
465 */
GL_Init(void)466 void GL_Init (void)
467 {
468 gl_vendor = glGetString (GL_VENDOR);
469 Con_Printf ("GL_VENDOR: %s\n", gl_vendor);
470 gl_renderer = glGetString (GL_RENDERER);
471 Con_Printf ("GL_RENDERER: %s\n", gl_renderer);
472
473 gl_version = glGetString (GL_VERSION);
474 Con_Printf ("GL_VERSION: %s\n", gl_version);
475 gl_extensions = glGetString (GL_EXTENSIONS);
476 Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions);
477
478 // Con_Printf ("%s %s\n", gl_renderer, gl_version);
479
480 glClearColor (1,0,0,0);
481 glCullFace(GL_FRONT);
482 glEnable(GL_TEXTURE_2D);
483
484 glEnable(GL_ALPHA_TEST);
485 glAlphaFunc(GL_GREATER, 0.666);
486
487 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
488 glShadeModel (GL_FLAT);
489
490 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
491 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
492 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
493 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
494
495 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
496
497 // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
498 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
499 }
500
501 /*
502 =================
503 GL_BeginRendering
504
505 =================
506 */
GL_BeginRendering(int * x,int * y,int * width,int * height)507 void GL_BeginRendering (int *x, int *y, int *width, int *height)
508 {
509 extern cvar_t gl_clear;
510
511 *x = *y = 0;
512 *width = scr_width;
513 *height = scr_height;
514
515 // if (!wglMakeCurrent( maindc, baseRC ))
516 // Sys_Error ("wglMakeCurrent failed");
517
518 // glViewport (*x, *y, *width, *height);
519 }
520
521
GL_EndRendering(void)522 void GL_EndRendering (void)
523 {
524 glFlush();
525 glXSwapBuffers(dpy, win);
526 }
527
VID_Is8bit(void)528 qboolean VID_Is8bit(void)
529 {
530 return is8bit;
531 }
532
533 #ifdef GL_EXT_SHARED
VID_Init8bitPalette()534 void VID_Init8bitPalette()
535 {
536 // Check for 8bit Extensions and initialize them.
537 int i;
538 char thePalette[256*3];
539 char *oldPalette, *newPalette;
540
541 if (strstr(gl_extensions, "GL_EXT_shared_texture_palette") == NULL)
542 return;
543
544 Con_SafePrintf("8-bit GL extensions enabled.\n");
545 glEnable( GL_SHARED_TEXTURE_PALETTE_EXT );
546 oldPalette = (char *) d_8to24table; //d_8to24table3dfx;
547 newPalette = thePalette;
548 for (i=0;i<256;i++) {
549 *newPalette++ = *oldPalette++;
550 *newPalette++ = *oldPalette++;
551 *newPalette++ = *oldPalette++;
552 oldPalette++;
553 }
554 glColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGB, 256, GL_RGB, GL_UNSIGNED_BYTE, (void *) thePalette);
555 is8bit = true;
556 }
557
558 #else
559 extern void gl3DfxSetPaletteEXT(GLuint *pal);
560
VID_Init8bitPalette(void)561 void VID_Init8bitPalette(void)
562 {
563 // Check for 8bit Extensions and initialize them.
564 int i;
565 GLubyte table[256][4];
566 char *oldpal;
567
568 if (strstr(gl_extensions, "3DFX_set_global_palette") == NULL)
569 return;
570
571 Con_SafePrintf("8-bit GL extensions enabled.\n");
572 glEnable( GL_SHARED_TEXTURE_PALETTE_EXT );
573 oldpal = (char *) d_8to24table; //d_8to24table3dfx;
574 for (i=0;i<256;i++) {
575 table[i][2] = *oldpal++;
576 table[i][1] = *oldpal++;
577 table[i][0] = *oldpal++;
578 table[i][3] = 255;
579 oldpal++;
580 }
581 gl3DfxSetPaletteEXT((GLuint *)table);
582 is8bit = true;
583 }
584 #endif
585
VID_Init(unsigned char * palette)586 void VID_Init(unsigned char *palette)
587 {
588 int i;
589 int attrib[] = {
590 GLX_RGBA,
591 GLX_RED_SIZE, 1,
592 GLX_GREEN_SIZE, 1,
593 GLX_BLUE_SIZE, 1,
594 GLX_DOUBLEBUFFER,
595 GLX_DEPTH_SIZE, 1,
596 None
597 };
598 char gldir[MAX_OSPATH];
599 int width = 640, height = 480;
600 int scrnum;
601 XSetWindowAttributes attr;
602 unsigned long mask;
603 Window root;
604 XVisualInfo *visinfo;
605
606 S_Init();
607
608 Cvar_RegisterVariable (&vid_mode);
609 Cvar_RegisterVariable (&gl_ztrick);
610 Cvar_RegisterVariable (&_windowed_mouse);
611
612 vid.maxwarpwidth = WARP_WIDTH;
613 vid.maxwarpheight = WARP_HEIGHT;
614 vid.colormap = host_colormap;
615 vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
616
617 // interpret command-line params
618
619 // set vid parameters
620 if ((i = COM_CheckParm("-width")) != 0)
621 width = atoi(com_argv[i+1]);
622 if ((i = COM_CheckParm("-height")) != 0)
623 height = atoi(com_argv[i+1]);
624
625 if ((i = COM_CheckParm("-conwidth")) != 0)
626 vid.conwidth = Q_atoi(com_argv[i+1]);
627 else
628 vid.conwidth = 640;
629
630 vid.conwidth &= 0xfff8; // make it a multiple of eight
631
632 if (vid.conwidth < 320)
633 vid.conwidth = 320;
634
635 // pick a conheight that matches with correct aspect
636 vid.conheight = vid.conwidth*3 / 4;
637
638 if ((i = COM_CheckParm("-conheight")) != 0)
639 vid.conheight = Q_atoi(com_argv[i+1]);
640 if (vid.conheight < 200)
641 vid.conheight = 200;
642
643 if (!(dpy = XOpenDisplay(NULL))) {
644 fprintf(stderr, "Error couldn't open the X display\n");
645 exit(1);
646 }
647
648 scrnum = DefaultScreen(dpy);
649 root = RootWindow(dpy, scrnum);
650
651 visinfo = glXChooseVisual(dpy, scrnum, attrib);
652 if (!visinfo) {
653 fprintf(stderr, "qkHack: Error couldn't get an RGB, Double-buffered, Depth visual\n");
654 exit(1);
655 }
656 /* window attributes */
657 attr.background_pixel = 0;
658 attr.border_pixel = 0;
659 attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
660 attr.event_mask = X_MASK;
661 mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
662
663 win = XCreateWindow(dpy, root, 0, 0, width, height,
664 0, visinfo->depth, InputOutput,
665 visinfo->visual, mask, &attr);
666 XMapWindow(dpy, win);
667
668 XMoveWindow(dpy, win, 0, 0);
669
670 XFlush(dpy);
671
672 ctx = glXCreateContext(dpy, visinfo, NULL, True);
673
674 glXMakeCurrent(dpy, win, ctx);
675
676 scr_width = width;
677 scr_height = height;
678
679 if (vid.conheight > height)
680 vid.conheight = height;
681 if (vid.conwidth > width)
682 vid.conwidth = width;
683 vid.width = vid.conwidth;
684 vid.height = vid.conheight;
685
686 vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0);
687 vid.numpages = 2;
688
689 InitSig(); // trap evil signals
690
691 GL_Init();
692
693 sprintf (gldir, "%s/glquake", com_gamedir);
694 Sys_mkdir (gldir);
695
696 VID_SetPalette(palette);
697
698 // Check for 3DFX Extensions and initialize them.
699 VID_Init8bitPalette();
700
701 Con_SafePrintf ("Video mode %dx%d initialized.\n", width, height);
702
703 vid.recalc_refdef = 1; // force a surface cache flush
704 }
705
Sys_SendKeyEvents(void)706 void Sys_SendKeyEvents(void)
707 {
708 if (dpy) {
709 while (XPending(dpy))
710 GetEvent();
711 }
712 }
713
Force_CenterView_f(void)714 void Force_CenterView_f (void)
715 {
716 cl.viewangles[PITCH] = 0;
717 }
718
IN_Init(void)719 void IN_Init(void)
720 {
721 }
722
IN_Shutdown(void)723 void IN_Shutdown(void)
724 {
725 }
726
727 /*
728 ===========
729 IN_Commands
730 ===========
731 */
IN_Commands(void)732 void IN_Commands (void)
733 {
734 }
735
736 /*
737 ===========
738 IN_Move
739 ===========
740 */
IN_MouseMove(usercmd_t * cmd)741 void IN_MouseMove (usercmd_t *cmd)
742 {
743 if (m_filter.value)
744 {
745 mouse_x = (mouse_x + old_mouse_x) * 0.5;
746 mouse_y = (mouse_y + old_mouse_y) * 0.5;
747 }
748 old_mouse_x = mouse_x;
749 old_mouse_y = mouse_y;
750
751 mouse_x *= sensitivity.value;
752 mouse_y *= sensitivity.value;
753
754 // add mouse X/Y movement to cmd
755 if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) ))
756 cmd->sidemove += m_side.value * mouse_x;
757 else
758 cl.viewangles[YAW] -= m_yaw.value * mouse_x;
759
760 if (in_mlook.state & 1)
761 V_StopPitchDrift ();
762
763 if ( (in_mlook.state & 1) && !(in_strafe.state & 1))
764 {
765 cl.viewangles[PITCH] += m_pitch.value * mouse_y;
766 if (cl.viewangles[PITCH] > 80)
767 cl.viewangles[PITCH] = 80;
768 if (cl.viewangles[PITCH] < -70)
769 cl.viewangles[PITCH] = -70;
770 }
771 else
772 {
773 if ((in_strafe.state & 1) && noclip_anglehack)
774 cmd->upmove -= m_forward.value * mouse_y;
775 else
776 cmd->forwardmove -= m_forward.value * mouse_y;
777 }
778 mouse_x = mouse_y = 0.0;
779 }
780
IN_Move(usercmd_t * cmd)781 void IN_Move (usercmd_t *cmd)
782 {
783 IN_MouseMove(cmd);
784 }
785
786
VID_UnlockBuffer()787 void VID_UnlockBuffer() {}
VID_LockBuffer()788 void VID_LockBuffer() {}
789
790