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