|
|
1.1 ! root 1: // vid_x.c -- general x video driver ! 2: ! 3: #include <sys/time.h> ! 4: #include <sys/types.h> ! 5: #include <unistd.h> ! 6: #include <fcntl.h> ! 7: #include <signal.h> ! 8: #include <stdlib.h> ! 9: #include <stdio.h> ! 10: #include <string.h> ! 11: #include <sys/ipc.h> ! 12: #include <sys/shm.h> ! 13: #include <X11/Xlib.h> ! 14: #include <X11/Xutil.h> ! 15: #include <X11/keysym.h> ! 16: #include <X11/Intrinsic.h> ! 17: #include <X11/Shell.h> ! 18: #include <X11/StringDefs.h> ! 19: #include <X11/Xatom.h> ! 20: #include <X11/Xmd.h> ! 21: #include <X11/extensions/xf86vmode.h> ! 22: #include <X11/extensions/xf86dga.h> ! 23: ! 24: #include "quakedef.h" ! 25: #include "d_local.h" ! 26: ! 27: cvar_t m_filter = {"m_filter","1"}; ! 28: ! 29: qboolean mouse_avail; ! 30: int mouse_buttons=3; ! 31: int mouse_oldbuttonstate; ! 32: int mouse_buttonstate; ! 33: float mouse_x, mouse_y; ! 34: float old_mouse_x, old_mouse_y; ! 35: ! 36: typedef struct ! 37: { ! 38: int input; ! 39: int output; ! 40: } keymap_t; ! 41: ! 42: viddef_t vid; // global video state ! 43: unsigned short d_8to16table[256]; ! 44: ! 45: int num_shades=32; ! 46: int d_con_indirect = 0; ! 47: int vid_buffersize; ! 48: int pixbytes; ! 49: ! 50: static Display *x_disp; ! 51: static Colormap x_cmap; ! 52: static Window x_win; ! 53: static GC x_gc; ! 54: static Visual *x_vis; ! 55: static XVisualInfo *x_visinfo; ! 56: //static XImage *x_image; ! 57: ! 58: static int vid_inited; ! 59: static int direct_video_inited; ! 60: ! 61: int work_buffer; ! 62: static int verbose=0; ! 63: ! 64: char *hw_fb_addr; ! 65: int hw_fb_width; ! 66: int hw_fb_banksize; ! 67: int hw_fb_ram; ! 68: int hw_fb_dotclock; ! 69: XF86VidModeModeLine hw_fb_modeline; ! 70: ! 71: static long X11_highhunkmark; ! 72: static long X11_buffersize; ! 73: int vid_surfcachesize; ! 74: void *vid_surfcache; ! 75: ! 76: static int flipy; ! 77: static char *flipaddr; ! 78: ! 79: void (*vid_menudrawfn)(void); ! 80: void (*vid_menukeyfn)(int key); ! 81: ! 82: ! 83: // ======================================================================== ! 84: // Tragic death handler ! 85: // ======================================================================== ! 86: ! 87: void TragicDeath(int signal_num) ! 88: { ! 89: VID_Shutdown(); ! 90: Sys_Error("This death brought to you by the number %d\n", signal_num); ! 91: } ! 92: ! 93: // Called at startup to set up translation tables, takes 256 8 bit RGB values ! 94: // the palette data will go away after the call, so it must be copied off if ! 95: // the video driver will need it again ! 96: ! 97: void VID_Init (unsigned char *palette) ! 98: { ! 99: ! 100: int devmem; ! 101: int i; ! 102: XVisualInfo template; ! 103: XSetWindowAttributes xswa; ! 104: int MajorVersion, MinorVersion; ! 105: int EventBase, ErrorBase; ! 106: int MINMINOR=4; ! 107: int MINMAJOR=0; ! 108: struct sigaction sa; ! 109: XGCValues xgcvalues; ! 110: int valuemask = GCGraphicsExposures; ! 111: char *dispname; ! 112: Status xrc; ! 113: XSizeHints *x_hints; ! 114: ! 115: vid_inited = 0; ! 116: direct_video_inited = 0; ! 117: ! 118: devmem=open("/dev/mem", O_RDWR); ! 119: if (devmem<0) ! 120: fprintf(stderr, "You must run this as root or \"chmod 666 /dev/mem\"\n"); ! 121: else ! 122: close(devmem); ! 123: ! 124: srandom(getpid()); ! 125: ! 126: verbose=COM_CheckParm("-verbose"); ! 127: ! 128: // open the display ! 129: dispname = getenv("DISPLAY"); ! 130: if (!dispname) dispname = ":0.0"; ! 131: x_disp = XOpenDisplay(dispname); ! 132: if (!x_disp) ! 133: { ! 134: if (getenv("DISPLAY")) ! 135: Sys_Error("VID: Could not open display [%s]\n", ! 136: getenv("DISPLAY")); ! 137: else ! 138: Sys_Error("VID: Could not open local display\n"); ! 139: } ! 140: XSynchronize(x_disp, True); ! 141: ! 142: // use the root window for everything ! 143: ! 144: // x_win = RootWindow(x_disp, DefaultScreen(x_disp)); ! 145: xswa.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ! 146: PointerMotionMask | ButtonPressMask | ButtonReleaseMask; ! 147: ! 148: x_win = XCreateWindow(x_disp, DefaultRootWindow(x_disp), 0, 0, ! 149: WidthOfScreen(ScreenOfDisplay(x_disp, 0)), ! 150: HeightOfScreen(ScreenOfDisplay(x_disp, 0)), 0, ! 151: CopyFromParent, InputOutput, CopyFromParent, ! 152: CWEventMask, &xswa); ! 153: XSetTransientForHint(x_disp, x_win, x_win); ! 154: x_hints = XAllocSizeHints(); ! 155: x_hints->flags = USPosition; ! 156: XSetWMNormalHints(x_disp, x_win, x_hints); ! 157: // X_Free(x_hints); ! 158: XMapWindow(x_disp, x_win); ! 159: XRaiseWindow(x_disp, x_win); ! 160: ! 161: // check that vidmode extension is avail ! 162: ! 163: if (!XF86VidModeQueryVersion(x_disp, &MajorVersion, &MinorVersion)) ! 164: Sys_Error("Unable to query VidMode version"); ! 165: if (!XF86VidModeQueryExtension(x_disp, &EventBase, &ErrorBase)) ! 166: Sys_Error("Unable to query VidMode extension"); ! 167: if (MajorVersion < MINMAJOR || MinorVersion < MINMINOR) ! 168: Sys_Error("Minimum required VidMode extension version is %d.%d\n", ! 169: MINMAJOR, MINMINOR); ! 170: ! 171: // catch signals so i can die well ! 172: ! 173: sigaction(SIGINT, 0, &sa); ! 174: sa.sa_handler = TragicDeath; ! 175: sigaction(SIGINT, &sa, 0); ! 176: sigaction(SIGTERM, &sa, 0); ! 177: ! 178: // set up the mode and get info on the fb ! 179: ! 180: xrc = XF86DGAGetVideo(x_disp, DefaultScreen(x_disp), &hw_fb_addr, ! 181: &hw_fb_width, &hw_fb_banksize, &hw_fb_ram); ! 182: xrc = XF86DGADirectVideo(x_disp, DefaultScreen(x_disp), ! 183: XF86DGADirectGraphics|XF86DGADirectMouse|XF86DGADirectKeyb); ! 184: if (xrc != True) ! 185: Sys_Error("DirectVideo could not be setup\n"); ! 186: direct_video_inited = 1; ! 187: setuid(getuid()); ! 188: xrc = XF86DGASetViewPort(x_disp, DefaultScreen(x_disp), 0, 0); ! 189: xrc = XF86DGASetVidPage(x_disp, DefaultScreen(x_disp), 0); ! 190: xrc = XF86VidModeGetModeLine(x_disp, DefaultScreen(x_disp), ! 191: &hw_fb_dotclock, &hw_fb_modeline); ! 192: ! 193: vid.width = hw_fb_modeline.hdisplay; ! 194: vid.height = hw_fb_modeline.vdisplay; ! 195: vid.maxwarpwidth = WARP_WIDTH; ! 196: vid.maxwarpheight = WARP_HEIGHT; ! 197: vid.aspect = 1.0; ! 198: vid.numpages = 2; ! 199: vid.colormap = host_colormap; ! 200: vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); ! 201: ! 202: // ritual for getting x_visinfo which basically just has the depth in it ! 203: ! 204: x_vis = DefaultVisual(x_disp, DefaultScreen(x_disp)); ! 205: template.visualid = XVisualIDFromVisual(x_vis); ! 206: x_visinfo = XGetVisualInfo(x_disp, VisualIDMask, &template, &i); ! 207: pixbytes = x_visinfo->depth/8; ! 208: ! 209: // now know everything we need to know about the buffer ! 210: ! 211: work_buffer = 1; ! 212: vid.rowbytes = hw_fb_width * pixbytes; ! 213: flipaddr = hw_fb_addr + vid.rowbytes * vid.height; ! 214: flipy = vid.height; ! 215: vid.buffer = flipaddr; ! 216: vid.direct = hw_fb_addr; ! 217: vid.conbuffer = flipaddr; ! 218: vid.conrowbytes = vid.rowbytes; ! 219: vid.conwidth = vid.width; ! 220: vid.conheight = vid.height; ! 221: ! 222: Sys_Printf("VID: bank size = %d bytes\n", hw_fb_banksize); ! 223: Sys_Printf("VID: ram = %dkb\n", hw_fb_ram); ! 224: ! 225: if (hw_fb_banksize < vid.rowbytes * vid.height * 2) ! 226: Sys_Error("Video card bank size (%d bytes) too small for this res.", hw_fb_banksize); ! 227: ! 228: if (vid.rowbytes * vid.height * 2 > hw_fb_ram * 1024) ! 229: Sys_Error("Not enough video memory for this res"); ! 230: ! 231: // create the GC ! 232: ! 233: xgcvalues.graphics_exposures = False; ! 234: x_gc = XCreateGC(x_disp, x_win, valuemask, &xgcvalues ); ! 235: ! 236: // make input rawer ! 237: ! 238: XAutoRepeatOff(x_disp); ! 239: XGrabKeyboard(x_disp, x_win, True, GrabModeAsync, ! 240: GrabModeAsync, CurrentTime); ! 241: XGrabPointer(x_disp, x_win, True, ! 242: ButtonPressMask | ButtonReleaseMask, GrabModeAsync, GrabModeAsync, ! 243: None, None, CurrentTime); ! 244: ! 245: // setup colormap if necessary ! 246: ! 247: if (x_visinfo->depth == 8) ! 248: { ! 249: ! 250: if (x_visinfo->class == PseudoColor) ! 251: { ! 252: x_cmap = XCreateColormap(x_disp, x_win, x_vis, AllocAll); ! 253: VID_SetPalette(palette); ! 254: XInstallColormap(x_disp, x_cmap); ! 255: XSetWindowColormap(x_disp, x_win, x_cmap); ! 256: XSetWMColormapWindows(x_disp, x_win, &x_win, 1); ! 257: } ! 258: ! 259: } ! 260: ! 261: X11_highhunkmark = Hunk_HighMark (); ! 262: X11_buffersize = vid.width * vid.height * sizeof (*d_pzbuffer); ! 263: vid_surfcachesize = D_SurfaceCacheForRes (vid.width, vid.height); ! 264: X11_buffersize += vid_surfcachesize; ! 265: d_pzbuffer = Hunk_HighAllocName (X11_buffersize, "video"); ! 266: if (d_pzbuffer == NULL) ! 267: Sys_Error ("Not enough memory for video mode\n"); ! 268: vid_surfcache = (byte *) d_pzbuffer ! 269: + vid.width * vid.height * sizeof (*d_pzbuffer); ! 270: D_InitCaches(vid_surfcache, vid_surfcachesize); ! 271: ! 272: signal(SIGFPE, SIG_IGN); ! 273: ! 274: vid_inited = 1; ! 275: ! 276: } ! 277: ! 278: void VID_ShiftPalette(unsigned char *p) ! 279: { ! 280: if (!vid_inited) return; ! 281: VID_SetPalette(p); ! 282: } ! 283: ! 284: void VID_SetPalette(unsigned char *palette) ! 285: { ! 286: ! 287: int i; ! 288: XColor colors[256]; ! 289: ! 290: if (!vid_inited) return; ! 291: if (x_visinfo->class == PseudoColor && x_visinfo->depth == 8) ! 292: { ! 293: for (i=0 ; i<256 ; i++) ! 294: { ! 295: colors[i].pixel = i; ! 296: colors[i].flags = DoRed|DoGreen|DoBlue; ! 297: colors[i].red = palette[i*3] * 257; ! 298: colors[i].green = palette[i*3+1] * 257; ! 299: colors[i].blue = palette[i*3+2] * 257; ! 300: } ! 301: XStoreColors(x_disp, x_cmap, colors, 256); ! 302: } ! 303: ! 304: } ! 305: ! 306: // Called at shutdown ! 307: ! 308: void VID_Shutdown (void) ! 309: { ! 310: Con_Printf("VID_Shutdown\n"); ! 311: if (x_disp) ! 312: { ! 313: XUngrabPointer(x_disp, CurrentTime); ! 314: XUngrabKeyboard(x_disp, CurrentTime); ! 315: XAutoRepeatOn(x_disp); ! 316: if (direct_video_inited) ! 317: XF86DGADirectVideo(x_disp, DefaultScreen(x_disp), 0); ! 318: direct_video_inited = 0; ! 319: XCloseDisplay(x_disp); ! 320: x_disp = 0; ! 321: } ! 322: vid_inited = 0; ! 323: } ! 324: ! 325: int XLateKey(XKeyEvent *ev) ! 326: { ! 327: ! 328: int key; ! 329: char buf[64]; ! 330: KeySym keysym; ! 331: ! 332: key = 0; ! 333: ! 334: XLookupString(ev, buf, sizeof buf, &keysym, 0); ! 335: ! 336: switch(keysym) ! 337: { ! 338: case XK_Page_Up: key = K_PGUP; break; ! 339: case XK_Page_Down: key = K_PGDN; break; ! 340: case XK_Home: key = K_HOME; break; ! 341: case XK_End: key = K_END; break; ! 342: case XK_Left: key = K_LEFTARROW; break; ! 343: case XK_Right: key = K_RIGHTARROW; break; ! 344: case XK_Down: key = K_DOWNARROW; break; ! 345: case XK_Up: key = K_UPARROW; break; ! 346: case XK_Escape: key = K_ESCAPE; break; ! 347: case XK_Return: key = K_ENTER; break; ! 348: case XK_Tab: key = K_TAB; break; ! 349: case XK_F1: key = K_F1; break; ! 350: case XK_F2: key = K_F2; break; ! 351: case XK_F3: key = K_F3; break; ! 352: case XK_F4: key = K_F4; break; ! 353: case XK_F5: key = K_F5; break; ! 354: case XK_F6: key = K_F6; break; ! 355: case XK_F7: key = K_F7; break; ! 356: case XK_F8: key = K_F8; break; ! 357: case XK_F9: key = K_F9; break; ! 358: case XK_F10: key = K_F10; break; ! 359: case XK_F11: key = K_F11; break; ! 360: case XK_F12: key = K_F12; break; ! 361: case XK_BackSpace: ! 362: case XK_Delete: key = K_BACKSPACE; break; ! 363: case XK_Pause: key = K_PAUSE; break; ! 364: case XK_Shift_L: ! 365: case XK_Shift_R: key = K_SHIFT; break; ! 366: case XK_Execute: ! 367: case XK_Control_L: ! 368: case XK_Control_R: key = K_CTRL; break; ! 369: case XK_Alt_L: ! 370: case XK_Meta_L: ! 371: case XK_Alt_R: ! 372: case XK_Meta_R: key = K_ALT; break; ! 373: ! 374: case 0x07e: key = '`';break;/* [~] */ ! 375: case 0x021: key = '1';break;/* [!] */ ! 376: case 0x040: key = '2';break;/* [@] */ ! 377: case 0x023: key = '3';break;/* [#] */ ! 378: case 0x024: key = '4';break;/* [$] */ ! 379: case 0x025: key = '5';break;/* [%] */ ! 380: case 0x05e: key = '6';break;/* [^] */ ! 381: case 0x026: key = '7';break;/* [&] */ ! 382: case 0x02a: key = '8';break;/* [*] */ ! 383: case 0x028: key = '9';;break;/* [(] */ ! 384: case 0x029: key = '0';break;/* [)] */ ! 385: case 0x05f: key = '-';break;/* [_] */ ! 386: case 0x02b: key = '=';break;/* [+] */ ! 387: case 0x07c: key = '\'';break;/* [|] */ ! 388: case 0x07d: key = '[';break;/* [}] */ ! 389: case 0x07b: key = ']';break;/* [{] */ ! 390: case 0x022: key = '\'';break;/* ["] */ ! 391: case 0x03a: key = ';';break;/* [:] */ ! 392: case 0x03f: key = '/';break;/* [?] */ ! 393: case 0x03e: key = '.';break;/* [>] */ ! 394: case 0x03c: key = ',';break;/* [<] */ ! 395: ! 396: default: ! 397: key = *(unsigned char*)buf; ! 398: if (key >= 'A' && key <= 'Z') ! 399: key = key - 'A' + 'a'; ! 400: // fprintf(stderr, "case 0x0%x: key = ___;break;/* [%c] */\n", keysym); ! 401: break; ! 402: } ! 403: ! 404: return key; ! 405: ! 406: } ! 407: ! 408: struct ! 409: { ! 410: int key; ! 411: int down; ! 412: } keyq[64]; ! 413: int keyq_head=0; ! 414: int keyq_tail=0; ! 415: ! 416: void GetEvent(void) ! 417: { ! 418: ! 419: XEvent x_event; ! 420: int b; ! 421: ! 422: XNextEvent(x_disp, &x_event); ! 423: switch(x_event.type) ! 424: { ! 425: case KeyPress: ! 426: keyq[keyq_head].key = XLateKey(&x_event.xkey); ! 427: keyq[keyq_head].down = true; ! 428: keyq_head = (keyq_head + 1) & 63; ! 429: break; ! 430: case KeyRelease: ! 431: keyq[keyq_head].key = XLateKey(&x_event.xkey); ! 432: keyq[keyq_head].down = false; ! 433: keyq_head = (keyq_head + 1) & 63; ! 434: break; ! 435: case MotionNotify: ! 436: mouse_x += (float) x_event.xmotion.x; ! 437: mouse_y += (float) x_event.xmotion.y; ! 438: break; ! 439: case ButtonPress: ! 440: b=-1; ! 441: if (x_event.xbutton.button == Button1) ! 442: b = 0; ! 443: else if (x_event.xbutton.button == Button2) ! 444: b = 2; ! 445: else if (x_event.xbutton.button == Button3) ! 446: b = 1; ! 447: if (b>=0) ! 448: mouse_buttonstate |= 1<<b; ! 449: break; ! 450: case ButtonRelease: ! 451: b=-1; ! 452: if (x_event.xbutton.button == Button1) ! 453: b = 0; ! 454: else if (x_event.xbutton.button == Button2) ! 455: b = 2; ! 456: else if (x_event.xbutton.button == Button3) ! 457: b = 1; ! 458: if (b>=0) ! 459: mouse_buttonstate &= ~(1<<b); ! 460: break; ! 461: } ! 462: ! 463: } ! 464: ! 465: // flushes the given rectangles from the view buffer to the screen ! 466: ! 467: void VID_Update (vrect_t *rects) ! 468: { ! 469: ! 470: if (!vid_inited) return; ! 471: ! 472: // flip pages ! 473: ! 474: XF86DGASetViewPort(x_disp, DefaultScreen(x_disp), 0, ! 475: flipy * work_buffer); ! 476: ! 477: work_buffer = !work_buffer; ! 478: if (work_buffer) ! 479: { ! 480: vid.buffer = flipaddr; ! 481: vid.conbuffer = flipaddr; ! 482: vid.direct = hw_fb_addr; ! 483: } ! 484: else ! 485: { ! 486: vid.buffer = hw_fb_addr; ! 487: vid.conbuffer = hw_fb_addr; ! 488: vid.direct = flipaddr; ! 489: } ! 490: ! 491: XSync(x_disp, False); ! 492: ! 493: } ! 494: ! 495: static int dither; ! 496: ! 497: void VID_DitherOn(void) ! 498: { ! 499: if (dither == 0) ! 500: { ! 501: vid.recalc_refdef = 1; ! 502: dither = 1; ! 503: } ! 504: } ! 505: ! 506: void VID_DitherOff(void) ! 507: { ! 508: if (dither) ! 509: { ! 510: vid.recalc_refdef = 1; ! 511: dither = 0; ! 512: } ! 513: } ! 514: ! 515: int Sys_OpenWindow(void) ! 516: { ! 517: return 0; ! 518: } ! 519: ! 520: void Sys_EraseWindow(int window) ! 521: { ! 522: } ! 523: ! 524: void Sys_DrawCircle(int window, int x, int y, int r) ! 525: { ! 526: } ! 527: ! 528: void Sys_DisplayWindow(int window) ! 529: { ! 530: } ! 531: ! 532: void Sys_SendKeyEvents(void) ! 533: { ! 534: if (!vid_inited) return; ! 535: // get events from x server ! 536: if (x_disp) ! 537: { ! 538: while (XPending(x_disp)) GetEvent(); ! 539: while (keyq_head != keyq_tail) ! 540: { ! 541: Key_Event(keyq[keyq_tail].key, keyq[keyq_tail].down); ! 542: keyq_tail = (keyq_tail + 1) & 63; ! 543: } ! 544: } ! 545: } ! 546: ! 547: char *Sys_ConsoleInput (void) ! 548: { ! 549: ! 550: static char text[256]; ! 551: int len; ! 552: fd_set readfds; ! 553: int ready; ! 554: struct timeval timeout; ! 555: ! 556: timeout.tv_sec = 0; ! 557: timeout.tv_usec = 0; ! 558: FD_ZERO(&readfds); ! 559: FD_SET(0, &readfds); ! 560: ready = select(1, &readfds, 0, 0, &timeout); ! 561: ! 562: if (ready>0) ! 563: { ! 564: len = read (0, text, sizeof(text)); ! 565: if (len >= 1) ! 566: { ! 567: text[len-1] = 0; // rip off the /n and terminate ! 568: return text; ! 569: } ! 570: } ! 571: ! 572: return 0; ! 573: ! 574: } ! 575: ! 576: ! 577: static byte backingbuf[48*24]; ! 578: ! 579: void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) ! 580: { ! 581: int i, j, reps, repshift; ! 582: ! 583: if (!vid_inited) return; ! 584: ! 585: if (vid.aspect > 1.5) ! 586: { ! 587: reps = 2; ! 588: repshift = 1; ! 589: } ! 590: else ! 591: { ! 592: reps = 1; ! 593: repshift = 0; ! 594: } ! 595: ! 596: for (i=0 ; i<(height << repshift) ; i += reps) ! 597: { ! 598: for (j=0 ; j<reps ; j++) ! 599: { ! 600: memcpy (&backingbuf[(i + j) * 24], ! 601: vid.direct + x + ((y << repshift) + i + j) * ! 602: vid.rowbytes, width); ! 603: memcpy (vid.direct + x + ((y << repshift) + i + j) * ! 604: vid.rowbytes, &pbitmap[(i >> repshift) * width], width); ! 605: } ! 606: } ! 607: ! 608: } ! 609: ! 610: void D_EndDirectRect (int x, int y, int width, int height) ! 611: { ! 612: int i, j, reps, repshift; ! 613: ! 614: if (!vid_inited) return; ! 615: ! 616: if (vid.aspect > 1.5) ! 617: { ! 618: reps = 2; ! 619: repshift = 1; ! 620: } ! 621: else ! 622: { ! 623: reps = 1; ! 624: repshift = 0; ! 625: } ! 626: ! 627: for (i=0 ; i<(height << repshift) ; i += reps) ! 628: { ! 629: for (j=0 ; j<reps ; j++) ! 630: { ! 631: memcpy (vid.direct + x + ((y << repshift) + i + j) * ! 632: vid.rowbytes, &backingbuf[(i + j) * 24], width); ! 633: } ! 634: } ! 635: ! 636: } ! 637: ! 638: /* ! 639: =========== ! 640: IN_Init ! 641: =========== ! 642: */ ! 643: void IN_Init (void) ! 644: { ! 645: Cvar_RegisterVariable (&m_filter); ! 646: if ( COM_CheckParm ("-nomouse") ) ! 647: return; ! 648: mouse_x = mouse_y = 0.0; ! 649: mouse_avail = 1; ! 650: } ! 651: ! 652: /* ! 653: =========== ! 654: IN_Shutdown ! 655: =========== ! 656: */ ! 657: void IN_Shutdown (void) ! 658: { ! 659: mouse_avail = 0; ! 660: } ! 661: ! 662: ! 663: /* ! 664: =========== ! 665: IN_Commands ! 666: =========== ! 667: */ ! 668: void IN_Commands (void) ! 669: { ! 670: int i; ! 671: ! 672: if (!vid_inited || !mouse_avail) return; ! 673: ! 674: // perform button actions ! 675: for (i=0 ; i<mouse_buttons ; i++) ! 676: { ! 677: if ( (mouse_buttonstate & (1<<i)) && ! 678: !(mouse_oldbuttonstate & (1<<i)) ) ! 679: { ! 680: Key_Event (K_MOUSE1 + i, true); ! 681: } ! 682: if ( !(mouse_buttonstate & (1<<i)) && ! 683: (mouse_oldbuttonstate & (1<<i)) ) ! 684: { ! 685: Key_Event (K_MOUSE1 + i, false); ! 686: } ! 687: } ! 688: ! 689: mouse_oldbuttonstate = mouse_buttonstate; ! 690: ! 691: } ! 692: ! 693: /* ! 694: =========== ! 695: IN_Move ! 696: =========== ! 697: */ ! 698: void IN_Move (usercmd_t *cmd) ! 699: { ! 700: ! 701: if (!vid_inited || !mouse_avail) ! 702: return; ! 703: ! 704: if (m_filter.value) ! 705: { ! 706: mouse_x = (mouse_x + old_mouse_x) * 0.5; ! 707: mouse_y = (mouse_y + old_mouse_y) * 0.5; ! 708: } ! 709: old_mouse_x = mouse_x; ! 710: old_mouse_y = mouse_y; ! 711: ! 712: mouse_x *= sensitivity.value; ! 713: mouse_y *= sensitivity.value; ! 714: ! 715: // add mouse X/Y movement to cmd ! 716: if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) )) ! 717: cmd->sidemove += m_side.value * mouse_x; ! 718: else ! 719: cl.viewangles[YAW] -= m_yaw.value * mouse_x; ! 720: ! 721: if (in_mlook.state & 1) ! 722: V_StopPitchDrift (); ! 723: ! 724: if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) ! 725: { ! 726: cl.viewangles[PITCH] += m_pitch.value * mouse_y; ! 727: if (cl.viewangles[PITCH] > 80) ! 728: cl.viewangles[PITCH] = 80; ! 729: if (cl.viewangles[PITCH] < -70) ! 730: cl.viewangles[PITCH] = -70; ! 731: } ! 732: else ! 733: { ! 734: if ((in_strafe.state & 1) && noclip_anglehack) ! 735: cmd->upmove -= m_forward.value * mouse_y; ! 736: else ! 737: cmd->forwardmove -= m_forward.value * mouse_y; ! 738: } ! 739: ! 740: mouse_x = mouse_y = 0.0; ! 741: ! 742: } ! 743:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.