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 <asm/io.h> 29#include <dlfcn.h> 30 31/*#include "vga.h" */ 32#include "vgakeyboard.h" 33#include "vgamouse.h" 34 35#include "quakedef.h" 36#include "GL/fxmesa.h" 37 38#define WARP_WIDTH 320 39#define WARP_HEIGHT 200 40 41static fxMesaContext fc = NULL; 42#define stringify(m) { #m, m } 43 44unsigned short d_8to16table[256]; 45unsigned d_8to24table[256]; 46unsigned char d_15to8table[65536]; 47 48int num_shades=32; 49 50struct 51{ 52 char *name; 53 int num; 54} mice[] = 55{ 56 stringify(MOUSE_MICROSOFT), 57 stringify(MOUSE_MOUSESYSTEMS), 58 stringify(MOUSE_MMSERIES), 59 stringify(MOUSE_LOGITECH), 60 stringify(MOUSE_BUSMOUSE), 61 stringify(MOUSE_PS2), 62}; 63 64static unsigned char scantokey[128]; 65 66int num_mice = sizeof (mice) / sizeof(mice[0]); 67 68int d_con_indirect = 0; 69 70int svgalib_inited=0; 71int UseMouse = 1; 72int UseKeyboard = 1; 73 74int mouserate = MOUSE_DEFAULTSAMPLERATE; 75 76cvar_t vid_mode = {"vid_mode","5",false}; 77cvar_t vid_redrawfull = {"vid_redrawfull","0",false}; 78cvar_t vid_waitforrefresh = {"vid_waitforrefresh","0",true}; 79 80char *framebuffer_ptr; 81 82cvar_t mouse_button_commands[3] = 83{ 84 {"mouse1","+attack"}, 85 {"mouse2","+strafe"}, 86 {"mouse3","+forward"}, 87}; 88 89int mouse_buttons; 90int mouse_buttonstate; 91int mouse_oldbuttonstate; 92float mouse_x, mouse_y; 93float old_mouse_x, old_mouse_y; 94int mx, my; 95 96cvar_t m_filter = {"m_filter","1"}; 97 98int scr_width, scr_height; 99 100/*-----------------------------------------------------------------------*/ 101 102//int texture_mode = GL_NEAREST; 103//int texture_mode = GL_NEAREST_MIPMAP_NEAREST; 104//int texture_mode = GL_NEAREST_MIPMAP_LINEAR; 105int texture_mode = GL_LINEAR; 106//int texture_mode = GL_LINEAR_MIPMAP_NEAREST; 107//int texture_mode = GL_LINEAR_MIPMAP_LINEAR; 108 109int texture_extension_number = 1; 110 111float gldepthmin, gldepthmax; 112 113cvar_t gl_ztrick = {"gl_ztrick","1"}; 114 115const char *gl_vendor; 116const char *gl_renderer; 117const char *gl_version; 118const char *gl_extensions; 119 120void (*qgl3DfxSetPaletteEXT) (GLuint *); 121void (*qglColorTableEXT) (int, int, int, int, int, const void *); 122 123static float vid_gamma = 1.0; 124 125qboolean is8bit = false; 126qboolean isPermedia = false; 127qboolean gl_mtexable = false; 128 129/*-----------------------------------------------------------------------*/ 130void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) 131{ 132} 133 134void D_EndDirectRect (int x, int y, int width, int height) 135{ 136} 137 138int matchmouse(int mouse, char *name) 139{ 140 int i; 141 for (i=0 ; i<num_mice ; i++) 142 if (!strcmp(mice[i].name, name)) 143 return i; 144 return mouse; 145} 146 147#if 0 148 149void vtswitch(int newconsole) 150{ 151 152 int fd; 153 struct vt_stat x; 154 155// switch consoles and wait until reactivated 156 fd = open("/dev/console", O_RDONLY); 157 ioctl(fd, VT_GETSTATE, &x); 158 ioctl(fd, VT_ACTIVATE, newconsole); 159 ioctl(fd, VT_WAITACTIVE, x.v_active); 160 close(fd); 161 162} 163 164#endif 165 166void keyhandler(int scancode, int state) 167{ 168 169 int sc; 170 171 sc = scancode & 0x7f; 172 173 Key_Event(scantokey[sc], state == KEY_EVENTPRESS); 174 175} 176 177void VID_Shutdown(void) 178{ 179 if (!fc) 180 return; 181 182 fxMesaDestroyContext(fc); 183 184 if (UseKeyboard) 185 keyboard_close(); 186} 187 188void signal_handler(int sig) 189{ 190 printf("Received signal %d, exiting...\n", sig); 191 Sys_Quit(); 192 exit(0); 193} 194 195void InitSig(void) 196{ 197 signal(SIGHUP, signal_handler); 198 signal(SIGINT, signal_handler); 199 signal(SIGQUIT, signal_handler); 200 signal(SIGILL, signal_handler); 201 signal(SIGTRAP, signal_handler); 202 signal(SIGIOT, signal_handler); 203 signal(SIGBUS, signal_handler); 204 signal(SIGFPE, signal_handler); 205 signal(SIGSEGV, signal_handler); 206 signal(SIGTERM, signal_handler); 207} 208 209void VID_ShiftPalette(unsigned char *p) 210{ 211// VID_SetPalette(p); 212} 213 214void VID_SetPalette (unsigned char *palette) 215{ 216 byte *pal; 217 unsigned r,g,b; 218 unsigned v; 219 int r1,g1,b1; 220 int j,k,l,m; 221 unsigned short i; 222 unsigned *table; 223 FILE *f; 224 char s[255]; 225 int dist, bestdist; 226 static qboolean palflag = false; 227 228// 229// 8 8 8 encoding 230// 231 pal = palette; 232 table = d_8to24table; 233 for (i=0 ; i<256 ; i++) 234 { 235 r = pal[0]; 236 g = pal[1]; 237 b = pal[2]; 238 pal += 3; 239 240 v = (255<<24) + (r<<0) + (g<<8) + (b<<16); 241 *table++ = v; 242 } 243 d_8to24table[255] &= 0xffffff; // 255 is transparent 244 245 // JACK: 3D distance calcs - k is last closest, l is the distance. 246 for (i=0; i < (1<<15); i++) { 247 /* Maps 248 000000000000000 249 000000000011111 = Red = 0x1F 250 000001111100000 = Blue = 0x03E0 251 111110000000000 = Grn = 0x7C00 252 */ 253 r = ((i & 0x1F) << 3)+4; 254 g = ((i & 0x03E0) >> 2)+4; 255 b = ((i & 0x7C00) >> 7)+4; 256 pal = (unsigned char *)d_8to24table; 257 for (v=0,k=0,bestdist=10000*10000; v<256; v++,pal+=4) { 258 r1 = (int)r - (int)pal[0]; 259 g1 = (int)g - (int)pal[1]; 260 b1 = (int)b - (int)pal[2]; 261 dist = (r1*r1)+(g1*g1)+(b1*b1); 262 if (dist < bestdist) { 263 k=v; 264 bestdist = dist; 265 } 266 } 267 d_15to8table[i]=k; 268 } 269} 270 271void CheckMultiTextureExtensions(void) 272{ 273 void *prjobj; 274 275 if (strstr(gl_extensions, "GL_SGIS_multitexture ") && !COM_CheckParm("-nomtex")) { 276 Con_Printf("Found GL_SGIS_multitexture...\n"); 277 278 if ((prjobj = dlopen(NULL, RTLD_LAZY)) == NULL) { 279 Con_Printf("Unable to open symbol list for main program.\n"); 280 return; 281 } 282 283 qglMTexCoord2fSGIS = (void *) dlsym(prjobj, "glMTexCoord2fSGIS"); 284 qglSelectTextureSGIS = (void *) dlsym(prjobj, "glSelectTextureSGIS"); 285 286 if (qglMTexCoord2fSGIS && qglSelectTextureSGIS) { 287 Con_Printf("Multitexture extensions found.\n"); 288 gl_mtexable = true; 289 } else 290 Con_Printf("Symbol not found, disabled.\n"); 291 292 dlclose(prjobj); 293 } 294} 295 296/* 297=============== 298GL_Init 299=============== 300*/ 301void GL_Init (void) 302{ 303 gl_vendor = glGetString (GL_VENDOR); 304 Con_Printf ("GL_VENDOR: %s\n", gl_vendor); 305 gl_renderer = glGetString (GL_RENDERER); 306 Con_Printf ("GL_RENDERER: %s\n", gl_renderer); 307 308 gl_version = glGetString (GL_VERSION); 309 Con_Printf ("GL_VERSION: %s\n", gl_version); 310 gl_extensions = glGetString (GL_EXTENSIONS); 311 Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions); 312 313// Con_Printf ("%s %s\n", gl_renderer, gl_version); 314 315 CheckMultiTextureExtensions (); 316 317 glClearColor (1,0,0,0); 318 glCullFace(GL_FRONT); 319 glEnable(GL_TEXTURE_2D); 320 321 glEnable(GL_ALPHA_TEST); 322 glAlphaFunc(GL_GREATER, 0.666); 323 324 glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); 325 glShadeModel (GL_FLAT); 326 327 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 328 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 329 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 330 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 331 332 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 333 334// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 335 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 336} 337 338/* 339================= 340GL_BeginRendering 341 342================= 343*/ 344void GL_BeginRendering (int *x, int *y, int *width, int *height) 345{ 346 extern cvar_t gl_clear; 347 348 *x = *y = 0; 349 *width = scr_width; 350 *height = scr_height; 351 352// if (!wglMakeCurrent( maindc, baseRC )) 353// Sys_Error ("wglMakeCurrent failed"); 354 355// glViewport (*x, *y, *width, *height); 356} 357 358 359void GL_EndRendering (void) 360{ 361 glFlush(); 362 fxMesaSwapBuffers(); 363} 364 365void Init_KBD(void) 366{ 367 int i; 368 369 if (COM_CheckParm("-nokbd")) UseKeyboard = 0; 370 371 if (UseKeyboard) 372 { 373 for (i=0 ; i<128 ; i++) 374 scantokey[i] = ' '; 375 376 scantokey[42] = K_SHIFT; 377 scantokey[54] = K_SHIFT; 378 scantokey[72] = K_UPARROW; 379 scantokey[103] = K_UPARROW; 380 scantokey[80] = K_DOWNARROW; 381 scantokey[108] = K_DOWNARROW; 382 scantokey[75] = K_LEFTARROW; 383 scantokey[105] = K_LEFTARROW; 384 scantokey[77] = K_RIGHTARROW; 385 scantokey[106] = K_RIGHTARROW; 386 scantokey[29] = K_CTRL; 387 scantokey[97] = K_CTRL; 388 scantokey[56] = K_ALT; 389 scantokey[100] = K_ALT; 390// scantokey[58] = JK_CAPS; 391// scantokey[69] = JK_NUM_LOCK; 392 scantokey[71] = K_HOME; 393 scantokey[73] = K_PGUP; 394 scantokey[79] = K_END; 395 scantokey[81] = K_PGDN; 396 scantokey[82] = K_INS; 397 scantokey[83] = K_DEL; 398 scantokey[1 ] = K_ESCAPE; 399 scantokey[28] = K_ENTER; 400 scantokey[15] = K_TAB; 401 scantokey[14] = K_BACKSPACE; 402 scantokey[119] = K_PAUSE; 403 scantokey[57] = ' '; 404 405 scantokey[102] = K_HOME; 406 scantokey[104] = K_PGUP; 407 scantokey[107] = K_END; 408 scantokey[109] = K_PGDN; 409 scantokey[110] = K_INS; 410 scantokey[111] = K_DEL; 411 412 scantokey[2] = '1'; 413 scantokey[3] = '2'; 414 scantokey[4] = '3'; 415 scantokey[5] = '4'; 416 scantokey[6] = '5'; 417 scantokey[7] = '6'; 418 scantokey[8] = '7'; 419 scantokey[9] = '8'; 420 scantokey[10] = '9'; 421 scantokey[11] = '0'; 422 scantokey[12] = '-'; 423 scantokey[13] = '='; 424 scantokey[41] = '`'; 425 scantokey[26] = '['; 426 scantokey[27] = ']'; 427 scantokey[39] = ';'; 428 scantokey[40] = '\''; 429 scantokey[51] = ','; 430 scantokey[52] = '.'; 431 scantokey[53] = '/'; 432 scantokey[43] = '\\'; 433 434 scantokey[59] = K_F1; 435 scantokey[60] = K_F2; 436 scantokey[61] = K_F3; 437 scantokey[62] = K_F4; 438 scantokey[63] = K_F5; 439 scantokey[64] = K_F6; 440 scantokey[65] = K_F7; 441 scantokey[66] = K_F8; 442 scantokey[67] = K_F9; 443 scantokey[68] = K_F10; 444 scantokey[87] = K_F11; 445 scantokey[88] = K_F12; 446 scantokey[30] = 'a'; 447 scantokey[48] = 'b'; 448 scantokey[46] = 'c'; 449 scantokey[32] = 'd'; 450 scantokey[18] = 'e'; 451 scantokey[33] = 'f'; 452 scantokey[34] = 'g'; 453 scantokey[35] = 'h'; 454 scantokey[23] = 'i'; 455 scantokey[36] = 'j'; 456 scantokey[37] = 'k'; 457 scantokey[38] = 'l'; 458 scantokey[50] = 'm'; 459 scantokey[49] = 'n'; 460 scantokey[24] = 'o'; 461 scantokey[25] = 'p'; 462 scantokey[16] = 'q'; 463 scantokey[19] = 'r'; 464 scantokey[31] = 's'; 465 scantokey[20] = 't'; 466 scantokey[22] = 'u'; 467 scantokey[47] = 'v'; 468 scantokey[17] = 'w'; 469 scantokey[45] = 'x'; 470 scantokey[21] = 'y'; 471 scantokey[44] = 'z'; 472 473 scantokey[78] = '+'; 474 scantokey[74] = '-'; 475 476 if (keyboard_init()) 477 Sys_Error("keyboard_init() failed"); 478 keyboard_seteventhandler(keyhandler); 479 } 480} 481 482#define NUM_RESOLUTIONS 16 483 484static int resolutions[NUM_RESOLUTIONS][3]={ 485 320,200, GR_RESOLUTION_320x200, 486 320,240, GR_RESOLUTION_320x240, 487 400,256, GR_RESOLUTION_400x256, 488 400,300, GR_RESOLUTION_400x300, 489 512,384, GR_RESOLUTION_512x384, 490 640,200, GR_RESOLUTION_640x200, 491 640,350, GR_RESOLUTION_640x350, 492 640,400, GR_RESOLUTION_640x400, 493 640,480, GR_RESOLUTION_640x480, 494 800,600, GR_RESOLUTION_800x600, 495 960,720, GR_RESOLUTION_960x720, 496 856,480, GR_RESOLUTION_856x480, 497 512,256, GR_RESOLUTION_512x256, 498 1024,768, GR_RESOLUTION_1024x768, 499 1280,1024,GR_RESOLUTION_1280x1024, 500 1600,1200,GR_RESOLUTION_1600x1200 501}; 502 503int findres(int *width, int *height) 504{ 505 int i; 506 507 for(i=0;i<NUM_RESOLUTIONS;i++) 508 if((*width<=resolutions[i][0]) && (*height<=resolutions[i][1])) { 509 *width = resolutions[i][0]; 510 *height = resolutions[i][1]; 511 return resolutions[i][2]; 512 } 513 514 *width = 640; 515 *height = 480; 516 return GR_RESOLUTION_640x480; 517} 518 519qboolean VID_Is8bit(void) 520{ 521 return is8bit; 522} 523 524void VID_Init8bitPalette(void) 525{ 526 // Check for 8bit Extensions and initialize them. 527 int i; 528 void *prjobj; 529 530 if (COM_CheckParm("-no8bit")) 531 return; 532 533 if ((prjobj = dlopen(NULL, RTLD_LAZY)) == NULL) { 534 Con_Printf("Unable to open symbol list for main program.\n"); 535 return; 536 } 537 538 if (strstr(gl_extensions, "3DFX_set_global_palette") && 539 (qgl3DfxSetPaletteEXT = dlsym(prjobj, "gl3DfxSetPaletteEXT")) != NULL) { 540 GLubyte table[256][4]; 541 char *oldpal; 542 543 Con_SafePrintf("... Using 3DFX_set_global_palette\n"); 544 glEnable( GL_SHARED_TEXTURE_PALETTE_EXT ); 545 oldpal = (char *) d_8to24table; //d_8to24table3dfx; 546 for (i=0;i<256;i++) { 547 table[i][2] = *oldpal++; 548 table[i][1] = *oldpal++; 549 table[i][0] = *oldpal++; 550 table[i][3] = 255; 551 oldpal++; 552 } 553 qgl3DfxSetPaletteEXT((GLuint *)table); 554 is8bit = true; 555 556 } else if (strstr(gl_extensions, "GL_EXT_shared_texture_palette") && 557 (qglColorTableEXT = dlsym(prjobj, "glColorTableEXT")) != NULL) { 558 char thePalette[256*3]; 559 char *oldPalette, *newPalette; 560 561 Con_SafePrintf("... Using GL_EXT_shared_texture_palette\n"); 562 glEnable( GL_SHARED_TEXTURE_PALETTE_EXT ); 563 oldPalette = (char *) d_8to24table; //d_8to24table3dfx; 564 newPalette = thePalette; 565 for (i=0;i<256;i++) { 566 *newPalette++ = *oldPalette++; 567 *newPalette++ = *oldPalette++; 568 *newPalette++ = *oldPalette++; 569 oldPalette++; 570 } 571 qglColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGB, 256, GL_RGB, GL_UNSIGNED_BYTE, (void *) thePalette); 572 is8bit = true; 573 574 } 575 576 dlclose(prjobj); 577} 578 579static void Check_Gamma (unsigned char *pal) 580{ 581 float f, inf; 582 unsigned char palette[768]; 583 int i; 584 585 if ((i = COM_CheckParm("-gamma")) == 0) { 586 if ((gl_renderer && strstr(gl_renderer, "Voodoo")) || 587 (gl_vendor && strstr(gl_vendor, "3Dfx"))) 588 vid_gamma = 1; 589 else 590 vid_gamma = 0.7; // default to 0.7 on non-3dfx hardware 591 } else 592 vid_gamma = Q_atof(com_argv[i+1]); 593 594 for (i=0 ; i<768 ; i++) 595 { 596 f = pow ( (pal[i]+1)/256.0 , vid_gamma ); 597 inf = f*255 + 0.5; 598 if (inf < 0) 599 inf = 0; 600 if (inf > 255) 601 inf = 255; 602 palette[i] = inf; 603 } 604 605 memcpy (pal, palette, sizeof(palette)); 606} 607 608void VID_Init(unsigned char *palette) 609{ 610 int i; 611 GLint attribs[32]; 612 char gldir[MAX_OSPATH]; 613 int width = 640, height = 480; 614 615 Init_KBD(); 616 617 Cvar_RegisterVariable (&vid_mode); 618 Cvar_RegisterVariable (&vid_redrawfull); 619 Cvar_RegisterVariable (&vid_waitforrefresh); 620 Cvar_RegisterVariable (&gl_ztrick); 621 622 vid.maxwarpwidth = WARP_WIDTH; 623 vid.maxwarpheight = WARP_HEIGHT; 624 vid.colormap = host_colormap; 625 vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); 626 627// interpret command-line params 628 629// set vid parameters 630 attribs[0] = FXMESA_DOUBLEBUFFER; 631 attribs[1] = FXMESA_ALPHA_SIZE; 632 attribs[2] = 1; 633 attribs[3] = FXMESA_DEPTH_SIZE; 634 attribs[4] = 1; 635 attribs[5] = FXMESA_NONE; 636 637 if ((i = COM_CheckParm("-width")) != 0) 638 width = atoi(com_argv[i+1]); 639 if ((i = COM_CheckParm("-height")) != 0) 640 height = atoi(com_argv[i+1]); 641 642 if ((i = COM_CheckParm("-conwidth")) != 0) 643 vid.conwidth = Q_atoi(com_argv[i+1]); 644 else 645 vid.conwidth = 640; 646 647 vid.conwidth &= 0xfff8; // make it a multiple of eight 648 649 if (vid.conwidth < 320) 650 vid.conwidth = 320; 651 652 // pick a conheight that matches with correct aspect 653 vid.conheight = vid.conwidth*3 / 4; 654 655 if ((i = COM_CheckParm("-conheight")) != 0) 656 vid.conheight = Q_atoi(com_argv[i+1]); 657 if (vid.conheight < 200) 658 vid.conheight = 200; 659 660 fc = fxMesaCreateContext(0, findres(&width, &height), GR_REFRESH_75Hz, 661 attribs); 662 if (!fc) 663 Sys_Error("Unable to create 3DFX context.\n"); 664 665 InitSig(); // trap evil signals 666 667 scr_width = width; 668 scr_height = height; 669 670 fxMesaMakeCurrent(fc); 671 672 if (vid.conheight > height) 673 vid.conheight = height; 674 if (vid.conwidth > width) 675 vid.conwidth = width; 676 vid.width = vid.conwidth; 677 vid.height = vid.conheight; 678 679 vid.aspect = ((float)vid.height / (float)vid.width) * 680 (320.0 / 240.0); 681 vid.numpages = 2; 682 683 GL_Init(); 684 685 sprintf (gldir, "%s/glquake", com_gamedir); 686 Sys_mkdir (gldir); 687 688 Check_Gamma(palette); 689 VID_SetPalette(palette); 690 691 // Check for 3DFX Extensions and initialize them. 692 VID_Init8bitPalette(); 693 694 Con_SafePrintf ("Video mode %dx%d initialized.\n", width, height); 695 696 vid.recalc_refdef = 1; // force a surface cache flush 697} 698 699void Sys_SendKeyEvents(void) 700{ 701 if (UseKeyboard) 702 while (keyboard_update()); 703} 704 705void Force_CenterView_f (void) 706{ 707 cl.viewangles[PITCH] = 0; 708} 709 710 711void mousehandler(int buttonstate, int dx, int dy) 712{ 713 mouse_buttonstate = buttonstate; 714 mx += dx; 715 my += dy; 716} 717 718void IN_Init(void) 719{ 720 721 int mtype; 722 char *mousedev; 723 int mouserate; 724 725 if (UseMouse) 726 { 727 728 Cvar_RegisterVariable (&mouse_button_commands[0]); 729 Cvar_RegisterVariable (&mouse_button_commands[1]); 730 Cvar_RegisterVariable (&mouse_button_commands[2]); 731 Cmd_AddCommand ("force_centerview", Force_CenterView_f); 732 733 mouse_buttons = 3; 734 735 mtype = vga_getmousetype(); 736 737 mousedev = "/dev/mouse"; 738 if (getenv("MOUSEDEV")) mousedev = getenv("MOUSEDEV"); 739 if (COM_CheckParm("-mdev")) 740 mousedev = com_argv[COM_CheckParm("-mdev")+1]; 741 742 mouserate = 1200; 743 if (getenv("MOUSERATE")) mouserate = atoi(getenv("MOUSERATE")); 744 if (COM_CheckParm("-mrate")) 745 mouserate = atoi(com_argv[COM_CheckParm("-mrate")+1]); 746 747 if (mouse_init(mousedev, mtype, mouserate)) 748 { 749 Con_Printf("No mouse found\n"); 750 UseMouse = 0; 751 } 752 else 753 mouse_seteventhandler(mousehandler); 754 755 } 756 757} 758 759void IN_Shutdown(void) 760{ 761 if (UseMouse) 762 mouse_close(); 763} 764 765/* 766=========== 767IN_Commands 768=========== 769*/ 770void IN_Commands (void) 771{ 772 if (UseMouse && cls.state != ca_dedicated) 773 { 774 // poll mouse values 775 while (mouse_update()) 776 ; 777 778 // perform button actions 779 if ((mouse_buttonstate & MOUSE_LEFTBUTTON) && 780 !(mouse_oldbuttonstate & MOUSE_LEFTBUTTON)) 781 Key_Event (K_MOUSE1, true); 782 else if (!(mouse_buttonstate & MOUSE_LEFTBUTTON) && 783 (mouse_oldbuttonstate & MOUSE_LEFTBUTTON)) 784 Key_Event (K_MOUSE1, false); 785 786 if ((mouse_buttonstate & MOUSE_RIGHTBUTTON) && 787 !(mouse_oldbuttonstate & MOUSE_RIGHTBUTTON)) 788 Key_Event (K_MOUSE2, true); 789 else if (!(mouse_buttonstate & MOUSE_RIGHTBUTTON) && 790 (mouse_oldbuttonstate & MOUSE_RIGHTBUTTON)) 791 Key_Event (K_MOUSE2, false); 792 793 if ((mouse_buttonstate & MOUSE_MIDDLEBUTTON) && 794 !(mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON)) 795 Key_Event (K_MOUSE3, true); 796 else if (!(mouse_buttonstate & MOUSE_MIDDLEBUTTON) && 797 (mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON)) 798 Key_Event (K_MOUSE3, false); 799 800 mouse_oldbuttonstate = mouse_buttonstate; 801 } 802} 803 804/* 805=========== 806IN_Move 807=========== 808*/ 809void IN_MouseMove (usercmd_t *cmd) 810{ 811 if (!UseMouse) 812 return; 813 814 // poll mouse values 815 while (mouse_update()) 816 ; 817 818 if (m_filter.value) 819 { 820 mouse_x = (mx + old_mouse_x) * 0.5; 821 mouse_y = (my + old_mouse_y) * 0.5; 822 } 823 else 824 { 825 mouse_x = mx; 826 mouse_y = my; 827 } 828 old_mouse_x = mx; 829 old_mouse_y = my; 830 mx = my = 0; // clear for next update 831 832 mouse_x *= sensitivity.value; 833 mouse_y *= sensitivity.value; 834 835// add mouse X/Y movement to cmd 836 if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) )) 837 cmd->sidemove += m_side.value * mouse_x; 838 else 839 cl.viewangles[YAW] -= m_yaw.value * mouse_x; 840 841 if (in_mlook.state & 1) 842 V_StopPitchDrift (); 843 844 if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) 845 { 846 cl.viewangles[PITCH] += m_pitch.value * mouse_y; 847 if (cl.viewangles[PITCH] > 80) 848 cl.viewangles[PITCH] = 80; 849 if (cl.viewangles[PITCH] < -70) 850 cl.viewangles[PITCH] = -70; 851 } 852 else 853 { 854 if ((in_strafe.state & 1) && noclip_anglehack) 855 cmd->upmove -= m_forward.value * mouse_y; 856 else 857 cmd->forwardmove -= m_forward.value * mouse_y; 858 } 859} 860 861void IN_Move (usercmd_t *cmd) 862{ 863 IN_MouseMove(cmd); 864} 865 866 867