|
|
1.1 ! root 1: // Emacs style mode select -*- C++ -*- ! 2: //----------------------------------------------------------------------------- ! 3: // ! 4: // $Id:$ ! 5: // ! 6: // Copyright (C) 1993-1996 by id Software, Inc. ! 7: // ! 8: // This program is free software; you can redistribute it and/or ! 9: // modify it under the terms of the GNU General Public License ! 10: // as published by the Free Software Foundation; either version 2 ! 11: // of the License, or (at your option) any later version. ! 12: // ! 13: // This program is distributed in the hope that it will be useful, ! 14: // but WITHOUT ANY WARRANTY; without even the implied warranty of ! 15: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 16: // GNU General Public License for more details. ! 17: // ! 18: // $Log:$ ! 19: // ! 20: // DESCRIPTION: ! 21: // DOOM graphics stuff for X11, UNIX. ! 22: // ! 23: //----------------------------------------------------------------------------- ! 24: ! 25: static const char ! 26: rcsid[] = "$Id: i_x.c,v 1.6 1997/02/03 22:45:10 b1 Exp $"; ! 27: ! 28: #include <stdlib.h> ! 29: #include <unistd.h> ! 30: #include <sys/ipc.h> ! 31: #include <sys/shm.h> ! 32: ! 33: #include <X11/Xlib.h> ! 34: #include <X11/Xutil.h> ! 35: #include <X11/keysym.h> ! 36: ! 37: #include <X11/extensions/XShm.h> ! 38: // Had to dig up XShm.c for this one. ! 39: // It is in the libXext, but not in the XFree86 headers. ! 40: #ifdef LINUX ! 41: int XShmGetEventBase( Display* dpy ); // problems with g++? ! 42: #endif ! 43: ! 44: #include <stdarg.h> ! 45: #include <sys/time.h> ! 46: #include <sys/types.h> ! 47: #include <sys/socket.h> ! 48: ! 49: #include <netinet/in.h> ! 50: #include <errnos.h> ! 51: #include <signal.h> ! 52: ! 53: #include "doomstat.h" ! 54: #include "i_system.h" ! 55: #include "v_video.h" ! 56: #include "m_argv.h" ! 57: #include "d_main.h" ! 58: ! 59: #include "doomdef.h" ! 60: ! 61: #define POINTER_WARP_COUNTDOWN 1 ! 62: ! 63: Display* X_display=0; ! 64: Window X_mainWindow; ! 65: Colormap X_cmap; ! 66: Visual* X_visual; ! 67: GC X_gc; ! 68: XEvent X_event; ! 69: int X_screen; ! 70: XVisualInfo X_visualinfo; ! 71: XImage* image; ! 72: int X_width; ! 73: int X_height; ! 74: ! 75: // MIT SHared Memory extension. ! 76: boolean doShm; ! 77: ! 78: XShmSegmentInfo X_shminfo; ! 79: int X_shmeventtype; ! 80: ! 81: // Fake mouse handling. ! 82: // This cannot work properly w/o DGA. ! 83: // Needs an invisible mouse cursor at least. ! 84: boolean grabMouse; ! 85: int doPointerWarp = POINTER_WARP_COUNTDOWN; ! 86: ! 87: // Blocky mode, ! 88: // replace each 320x200 pixel with multiply*multiply pixels. ! 89: // According to Dave Taylor, it still is a bonehead thing ! 90: // to use .... ! 91: static int multiply=1; ! 92: ! 93: ! 94: // ! 95: // Translates the key currently in X_event ! 96: // ! 97: ! 98: int xlatekey(void) ! 99: { ! 100: ! 101: int rc; ! 102: ! 103: switch(rc = XKeycodeToKeysym(X_display, X_event.xkey.keycode, 0)) ! 104: { ! 105: case XK_Left: rc = KEY_LEFTARROW; break; ! 106: case XK_Right: rc = KEY_RIGHTARROW; break; ! 107: case XK_Down: rc = KEY_DOWNARROW; break; ! 108: case XK_Up: rc = KEY_UPARROW; break; ! 109: case XK_Escape: rc = KEY_ESCAPE; break; ! 110: case XK_Return: rc = KEY_ENTER; break; ! 111: case XK_Tab: rc = KEY_TAB; break; ! 112: case XK_F1: rc = KEY_F1; break; ! 113: case XK_F2: rc = KEY_F2; break; ! 114: case XK_F3: rc = KEY_F3; break; ! 115: case XK_F4: rc = KEY_F4; break; ! 116: case XK_F5: rc = KEY_F5; break; ! 117: case XK_F6: rc = KEY_F6; break; ! 118: case XK_F7: rc = KEY_F7; break; ! 119: case XK_F8: rc = KEY_F8; break; ! 120: case XK_F9: rc = KEY_F9; break; ! 121: case XK_F10: rc = KEY_F10; break; ! 122: case XK_F11: rc = KEY_F11; break; ! 123: case XK_F12: rc = KEY_F12; break; ! 124: ! 125: case XK_BackSpace: ! 126: case XK_Delete: rc = KEY_BACKSPACE; break; ! 127: ! 128: case XK_Pause: rc = KEY_PAUSE; break; ! 129: ! 130: case XK_KP_Equal: ! 131: case XK_equal: rc = KEY_EQUALS; break; ! 132: ! 133: case XK_KP_Subtract: ! 134: case XK_minus: rc = KEY_MINUS; break; ! 135: ! 136: case XK_Shift_L: ! 137: case XK_Shift_R: ! 138: rc = KEY_RSHIFT; ! 139: break; ! 140: ! 141: case XK_Control_L: ! 142: case XK_Control_R: ! 143: rc = KEY_RCTRL; ! 144: break; ! 145: ! 146: case XK_Alt_L: ! 147: case XK_Meta_L: ! 148: case XK_Alt_R: ! 149: case XK_Meta_R: ! 150: rc = KEY_RALT; ! 151: break; ! 152: ! 153: default: ! 154: if (rc >= XK_space && rc <= XK_asciitilde) ! 155: rc = rc - XK_space + ' '; ! 156: if (rc >= 'A' && rc <= 'Z') ! 157: rc = rc - 'A' + 'a'; ! 158: break; ! 159: } ! 160: ! 161: return rc; ! 162: ! 163: } ! 164: ! 165: void I_ShutdownGraphics(void) ! 166: { ! 167: // Detach from X server ! 168: if (!XShmDetach(X_display, &X_shminfo)) ! 169: I_Error("XShmDetach() failed in I_ShutdownGraphics()"); ! 170: ! 171: // Release shared memory. ! 172: shmdt(X_shminfo.shmaddr); ! 173: shmctl(X_shminfo.shmid, IPC_RMID, 0); ! 174: ! 175: // Paranoia. ! 176: image->data = NULL; ! 177: } ! 178: ! 179: ! 180: ! 181: // ! 182: // I_StartFrame ! 183: // ! 184: void I_StartFrame (void) ! 185: { ! 186: // er? ! 187: ! 188: } ! 189: ! 190: static int lastmousex = 0; ! 191: static int lastmousey = 0; ! 192: boolean mousemoved = false; ! 193: boolean shmFinished; ! 194: ! 195: void I_GetEvent(void) ! 196: { ! 197: ! 198: event_t event; ! 199: ! 200: // put event-grabbing stuff in here ! 201: XNextEvent(X_display, &X_event); ! 202: switch (X_event.type) ! 203: { ! 204: case KeyPress: ! 205: event.type = ev_keydown; ! 206: event.data1 = xlatekey(); ! 207: D_PostEvent(&event); ! 208: // fprintf(stderr, "k"); ! 209: break; ! 210: case KeyRelease: ! 211: event.type = ev_keyup; ! 212: event.data1 = xlatekey(); ! 213: D_PostEvent(&event); ! 214: // fprintf(stderr, "ku"); ! 215: break; ! 216: case ButtonPress: ! 217: event.type = ev_mouse; ! 218: event.data1 = ! 219: (X_event.xbutton.state & Button1Mask) ! 220: | (X_event.xbutton.state & Button2Mask ? 2 : 0) ! 221: | (X_event.xbutton.state & Button3Mask ? 4 : 0) ! 222: | (X_event.xbutton.button == Button1) ! 223: | (X_event.xbutton.button == Button2 ? 2 : 0) ! 224: | (X_event.xbutton.button == Button3 ? 4 : 0); ! 225: event.data2 = event.data3 = 0; ! 226: D_PostEvent(&event); ! 227: // fprintf(stderr, "b"); ! 228: break; ! 229: case ButtonRelease: ! 230: event.type = ev_mouse; ! 231: event.data1 = ! 232: (X_event.xbutton.state & Button1Mask) ! 233: | (X_event.xbutton.state & Button2Mask ? 2 : 0) ! 234: | (X_event.xbutton.state & Button3Mask ? 4 : 0); ! 235: // suggest parentheses around arithmetic in operand of | ! 236: event.data1 = ! 237: event.data1 ! 238: ^ (X_event.xbutton.button == Button1 ? 1 : 0) ! 239: ^ (X_event.xbutton.button == Button2 ? 2 : 0) ! 240: ^ (X_event.xbutton.button == Button3 ? 4 : 0); ! 241: event.data2 = event.data3 = 0; ! 242: D_PostEvent(&event); ! 243: // fprintf(stderr, "bu"); ! 244: break; ! 245: case MotionNotify: ! 246: event.type = ev_mouse; ! 247: event.data1 = ! 248: (X_event.xmotion.state & Button1Mask) ! 249: | (X_event.xmotion.state & Button2Mask ? 2 : 0) ! 250: | (X_event.xmotion.state & Button3Mask ? 4 : 0); ! 251: event.data2 = (X_event.xmotion.x - lastmousex) << 2; ! 252: event.data3 = (lastmousey - X_event.xmotion.y) << 2; ! 253: ! 254: if (event.data2 || event.data3) ! 255: { ! 256: lastmousex = X_event.xmotion.x; ! 257: lastmousey = X_event.xmotion.y; ! 258: if (X_event.xmotion.x != X_width/2 && ! 259: X_event.xmotion.y != X_height/2) ! 260: { ! 261: D_PostEvent(&event); ! 262: // fprintf(stderr, "m"); ! 263: mousemoved = false; ! 264: } else ! 265: { ! 266: mousemoved = true; ! 267: } ! 268: } ! 269: break; ! 270: ! 271: case Expose: ! 272: case ConfigureNotify: ! 273: break; ! 274: ! 275: default: ! 276: if (doShm && X_event.type == X_shmeventtype) shmFinished = true; ! 277: break; ! 278: } ! 279: ! 280: } ! 281: ! 282: Cursor ! 283: createnullcursor ! 284: ( Display* display, ! 285: Window root ) ! 286: { ! 287: Pixmap cursormask; ! 288: XGCValues xgc; ! 289: GC gc; ! 290: XColor dummycolour; ! 291: Cursor cursor; ! 292: ! 293: cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/); ! 294: xgc.function = GXclear; ! 295: gc = XCreateGC(display, cursormask, GCFunction, &xgc); ! 296: XFillRectangle(display, cursormask, gc, 0, 0, 1, 1); ! 297: dummycolour.pixel = 0; ! 298: dummycolour.red = 0; ! 299: dummycolour.flags = 04; ! 300: cursor = XCreatePixmapCursor(display, cursormask, cursormask, ! 301: &dummycolour,&dummycolour, 0,0); ! 302: XFreePixmap(display,cursormask); ! 303: XFreeGC(display,gc); ! 304: return cursor; ! 305: } ! 306: ! 307: // ! 308: // I_StartTic ! 309: // ! 310: void I_StartTic (void) ! 311: { ! 312: ! 313: if (!X_display) ! 314: return; ! 315: ! 316: while (XPending(X_display)) ! 317: I_GetEvent(); ! 318: ! 319: // Warp the pointer back to the middle of the window ! 320: // or it will wander off - that is, the game will ! 321: // loose input focus within X11. ! 322: if (grabMouse) ! 323: { ! 324: if (!--doPointerWarp) ! 325: { ! 326: XWarpPointer( X_display, ! 327: None, ! 328: X_mainWindow, ! 329: 0, 0, ! 330: 0, 0, ! 331: X_width/2, X_height/2); ! 332: ! 333: doPointerWarp = POINTER_WARP_COUNTDOWN; ! 334: } ! 335: } ! 336: ! 337: mousemoved = false; ! 338: ! 339: } ! 340: ! 341: ! 342: // ! 343: // I_UpdateNoBlit ! 344: // ! 345: void I_UpdateNoBlit (void) ! 346: { ! 347: // what is this? ! 348: } ! 349: ! 350: // ! 351: // I_FinishUpdate ! 352: // ! 353: void I_FinishUpdate (void) ! 354: { ! 355: ! 356: static int lasttic; ! 357: int tics; ! 358: int i; ! 359: // UNUSED static unsigned char *bigscreen=0; ! 360: ! 361: // draws little dots on the bottom of the screen ! 362: if (devparm) ! 363: { ! 364: ! 365: i = I_GetTime(); ! 366: tics = i - lasttic; ! 367: lasttic = i; ! 368: if (tics > 20) tics = 20; ! 369: ! 370: for (i=0 ; i<tics*2 ; i+=2) ! 371: screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0xff; ! 372: for ( ; i<20*2 ; i+=2) ! 373: screens[0][ (SCREENHEIGHT-1)*SCREENWIDTH + i] = 0x0; ! 374: ! 375: } ! 376: ! 377: // scales the screen size before blitting it ! 378: if (multiply == 2) ! 379: { ! 380: unsigned int *olineptrs[2]; ! 381: unsigned int *ilineptr; ! 382: int x, y, i; ! 383: unsigned int twoopixels; ! 384: unsigned int twomoreopixels; ! 385: unsigned int fouripixels; ! 386: ! 387: ilineptr = (unsigned int *) (screens[0]); ! 388: for (i=0 ; i<2 ; i++) ! 389: olineptrs[i] = (unsigned int *) &image->data[i*X_width]; ! 390: ! 391: y = SCREENHEIGHT; ! 392: while (y--) ! 393: { ! 394: x = SCREENWIDTH; ! 395: do ! 396: { ! 397: fouripixels = *ilineptr++; ! 398: twoopixels = (fouripixels & 0xff000000) ! 399: | ((fouripixels>>8) & 0xffff00) ! 400: | ((fouripixels>>16) & 0xff); ! 401: twomoreopixels = ((fouripixels<<16) & 0xff000000) ! 402: | ((fouripixels<<8) & 0xffff00) ! 403: | (fouripixels & 0xff); ! 404: #ifdef __BIG_ENDIAN__ ! 405: *olineptrs[0]++ = twoopixels; ! 406: *olineptrs[1]++ = twoopixels; ! 407: *olineptrs[0]++ = twomoreopixels; ! 408: *olineptrs[1]++ = twomoreopixels; ! 409: #else ! 410: *olineptrs[0]++ = twomoreopixels; ! 411: *olineptrs[1]++ = twomoreopixels; ! 412: *olineptrs[0]++ = twoopixels; ! 413: *olineptrs[1]++ = twoopixels; ! 414: #endif ! 415: } while (x-=4); ! 416: olineptrs[0] += X_width/4; ! 417: olineptrs[1] += X_width/4; ! 418: } ! 419: ! 420: } ! 421: else if (multiply == 3) ! 422: { ! 423: unsigned int *olineptrs[3]; ! 424: unsigned int *ilineptr; ! 425: int x, y, i; ! 426: unsigned int fouropixels[3]; ! 427: unsigned int fouripixels; ! 428: ! 429: ilineptr = (unsigned int *) (screens[0]); ! 430: for (i=0 ; i<3 ; i++) ! 431: olineptrs[i] = (unsigned int *) &image->data[i*X_width]; ! 432: ! 433: y = SCREENHEIGHT; ! 434: while (y--) ! 435: { ! 436: x = SCREENWIDTH; ! 437: do ! 438: { ! 439: fouripixels = *ilineptr++; ! 440: fouropixels[0] = (fouripixels & 0xff000000) ! 441: | ((fouripixels>>8) & 0xff0000) ! 442: | ((fouripixels>>16) & 0xffff); ! 443: fouropixels[1] = ((fouripixels<<8) & 0xff000000) ! 444: | (fouripixels & 0xffff00) ! 445: | ((fouripixels>>8) & 0xff); ! 446: fouropixels[2] = ((fouripixels<<16) & 0xffff0000) ! 447: | ((fouripixels<<8) & 0xff00) ! 448: | (fouripixels & 0xff); ! 449: #ifdef __BIG_ENDIAN__ ! 450: *olineptrs[0]++ = fouropixels[0]; ! 451: *olineptrs[1]++ = fouropixels[0]; ! 452: *olineptrs[2]++ = fouropixels[0]; ! 453: *olineptrs[0]++ = fouropixels[1]; ! 454: *olineptrs[1]++ = fouropixels[1]; ! 455: *olineptrs[2]++ = fouropixels[1]; ! 456: *olineptrs[0]++ = fouropixels[2]; ! 457: *olineptrs[1]++ = fouropixels[2]; ! 458: *olineptrs[2]++ = fouropixels[2]; ! 459: #else ! 460: *olineptrs[0]++ = fouropixels[2]; ! 461: *olineptrs[1]++ = fouropixels[2]; ! 462: *olineptrs[2]++ = fouropixels[2]; ! 463: *olineptrs[0]++ = fouropixels[1]; ! 464: *olineptrs[1]++ = fouropixels[1]; ! 465: *olineptrs[2]++ = fouropixels[1]; ! 466: *olineptrs[0]++ = fouropixels[0]; ! 467: *olineptrs[1]++ = fouropixels[0]; ! 468: *olineptrs[2]++ = fouropixels[0]; ! 469: #endif ! 470: } while (x-=4); ! 471: olineptrs[0] += 2*X_width/4; ! 472: olineptrs[1] += 2*X_width/4; ! 473: olineptrs[2] += 2*X_width/4; ! 474: } ! 475: ! 476: } ! 477: else if (multiply == 4) ! 478: { ! 479: // Broken. Gotta fix this some day. ! 480: void Expand4(unsigned *, double *); ! 481: Expand4 ((unsigned *)(screens[0]), (double *) (image->data)); ! 482: } ! 483: ! 484: if (doShm) ! 485: { ! 486: ! 487: if (!XShmPutImage( X_display, ! 488: X_mainWindow, ! 489: X_gc, ! 490: image, ! 491: 0, 0, ! 492: 0, 0, ! 493: X_width, X_height, ! 494: True )) ! 495: I_Error("XShmPutImage() failed\n"); ! 496: ! 497: // wait for it to finish and processes all input events ! 498: shmFinished = false; ! 499: do ! 500: { ! 501: I_GetEvent(); ! 502: } while (!shmFinished); ! 503: ! 504: } ! 505: else ! 506: { ! 507: ! 508: // draw the image ! 509: XPutImage( X_display, ! 510: X_mainWindow, ! 511: X_gc, ! 512: image, ! 513: 0, 0, ! 514: 0, 0, ! 515: X_width, X_height ); ! 516: ! 517: // sync up with server ! 518: XSync(X_display, False); ! 519: ! 520: } ! 521: ! 522: } ! 523: ! 524: ! 525: // ! 526: // I_ReadScreen ! 527: // ! 528: void I_ReadScreen (byte* scr) ! 529: { ! 530: memcpy (scr, screens[0], SCREENWIDTH*SCREENHEIGHT); ! 531: } ! 532: ! 533: ! 534: // ! 535: // Palette stuff. ! 536: // ! 537: static XColor colors[256]; ! 538: ! 539: void UploadNewPalette(Colormap cmap, byte *palette) ! 540: { ! 541: ! 542: register int i; ! 543: register int c; ! 544: static boolean firstcall = true; ! 545: ! 546: #ifdef __cplusplus ! 547: if (X_visualinfo.c_class == PseudoColor && X_visualinfo.depth == 8) ! 548: #else ! 549: if (X_visualinfo.class == PseudoColor && X_visualinfo.depth == 8) ! 550: #endif ! 551: { ! 552: // initialize the colormap ! 553: if (firstcall) ! 554: { ! 555: firstcall = false; ! 556: for (i=0 ; i<256 ; i++) ! 557: { ! 558: colors[i].pixel = i; ! 559: colors[i].flags = DoRed|DoGreen|DoBlue; ! 560: } ! 561: } ! 562: ! 563: // set the X colormap entries ! 564: for (i=0 ; i<256 ; i++) ! 565: { ! 566: c = gammatable[usegamma][*palette++]; ! 567: colors[i].red = (c<<8) + c; ! 568: c = gammatable[usegamma][*palette++]; ! 569: colors[i].green = (c<<8) + c; ! 570: c = gammatable[usegamma][*palette++]; ! 571: colors[i].blue = (c<<8) + c; ! 572: } ! 573: ! 574: // store the colors to the current colormap ! 575: XStoreColors(X_display, cmap, colors, 256); ! 576: ! 577: } ! 578: } ! 579: ! 580: // ! 581: // I_SetPalette ! 582: // ! 583: void I_SetPalette (byte* palette) ! 584: { ! 585: UploadNewPalette(X_cmap, palette); ! 586: } ! 587: ! 588: ! 589: // ! 590: // This function is probably redundant, ! 591: // if XShmDetach works properly. ! 592: // ddt never detached the XShm memory, ! 593: // thus there might have been stale ! 594: // handles accumulating. ! 595: // ! 596: void grabsharedmemory(int size) ! 597: { ! 598: ! 599: int key = ('d'<<24) | ('o'<<16) | ('o'<<8) | 'm'; ! 600: struct shmid_ds shminfo; ! 601: int minsize = 320*200; ! 602: int id; ! 603: int rc; ! 604: // UNUSED int done=0; ! 605: int pollution=5; ! 606: ! 607: // try to use what was here before ! 608: do ! 609: { ! 610: id = shmget((key_t) key, minsize, 0777); // just get the id ! 611: if (id != -1) ! 612: { ! 613: rc=shmctl(id, IPC_STAT, &shminfo); // get stats on it ! 614: if (!rc) ! 615: { ! 616: if (shminfo.shm_nattch) ! 617: { ! 618: fprintf(stderr, "User %d appears to be running " ! 619: "DOOM. Is that wise?\n", shminfo.shm_cpid); ! 620: key++; ! 621: } ! 622: else ! 623: { ! 624: if (getuid() == shminfo.shm_perm.cuid) ! 625: { ! 626: rc = shmctl(id, IPC_RMID, 0); ! 627: if (!rc) ! 628: fprintf(stderr, ! 629: "Was able to kill my old shared memory\n"); ! 630: else ! 631: I_Error("Was NOT able to kill my old shared memory"); ! 632: ! 633: id = shmget((key_t)key, size, IPC_CREAT|0777); ! 634: if (id==-1) ! 635: I_Error("Could not get shared memory"); ! 636: ! 637: rc=shmctl(id, IPC_STAT, &shminfo); ! 638: ! 639: break; ! 640: ! 641: } ! 642: if (size >= shminfo.shm_segsz) ! 643: { ! 644: fprintf(stderr, ! 645: "will use %d's stale shared memory\n", ! 646: shminfo.shm_cpid); ! 647: break; ! 648: } ! 649: else ! 650: { ! 651: fprintf(stderr, ! 652: "warning: can't use stale " ! 653: "shared memory belonging to id %d, " ! 654: "key=0x%x\n", ! 655: shminfo.shm_cpid, key); ! 656: key++; ! 657: } ! 658: } ! 659: } ! 660: else ! 661: { ! 662: I_Error("could not get stats on key=%d", key); ! 663: } ! 664: } ! 665: else ! 666: { ! 667: id = shmget((key_t)key, size, IPC_CREAT|0777); ! 668: if (id==-1) ! 669: { ! 670: extern int errno; ! 671: fprintf(stderr, "errno=%d\n", errno); ! 672: I_Error("Could not get any shared memory"); ! 673: } ! 674: break; ! 675: } ! 676: } while (--pollution); ! 677: ! 678: if (!pollution) ! 679: { ! 680: I_Error("Sorry, system too polluted with stale " ! 681: "shared memory segments.\n"); ! 682: } ! 683: ! 684: X_shminfo.shmid = id; ! 685: ! 686: // attach to the shared memory segment ! 687: image->data = X_shminfo.shmaddr = shmat(id, 0, 0); ! 688: ! 689: fprintf(stderr, "shared memory id=%d, addr=0x%x\n", id, ! 690: (int) (image->data)); ! 691: } ! 692: ! 693: void I_InitGraphics(void) ! 694: { ! 695: ! 696: char* displayname; ! 697: char* d; ! 698: int n; ! 699: int pnum; ! 700: int x=0; ! 701: int y=0; ! 702: ! 703: // warning: char format, different type arg ! 704: char xsign=' '; ! 705: char ysign=' '; ! 706: ! 707: int oktodraw; ! 708: unsigned long attribmask; ! 709: XSetWindowAttributes attribs; ! 710: XGCValues xgcvalues; ! 711: int valuemask; ! 712: static int firsttime=1; ! 713: ! 714: if (!firsttime) ! 715: return; ! 716: firsttime = 0; ! 717: ! 718: signal(SIGINT, (void (*)(int)) I_Quit); ! 719: ! 720: if (M_CheckParm("-2")) ! 721: multiply = 2; ! 722: ! 723: if (M_CheckParm("-3")) ! 724: multiply = 3; ! 725: ! 726: if (M_CheckParm("-4")) ! 727: multiply = 4; ! 728: ! 729: X_width = SCREENWIDTH * multiply; ! 730: X_height = SCREENHEIGHT * multiply; ! 731: ! 732: // check for command-line display name ! 733: if ( (pnum=M_CheckParm("-disp")) ) // suggest parentheses around assignment ! 734: displayname = myargv[pnum+1]; ! 735: else ! 736: displayname = 0; ! 737: ! 738: // check if the user wants to grab the mouse (quite unnice) ! 739: grabMouse = !!M_CheckParm("-grabmouse"); ! 740: ! 741: // check for command-line geometry ! 742: if ( (pnum=M_CheckParm("-geom")) ) // suggest parentheses around assignment ! 743: { ! 744: // warning: char format, different type arg 3,5 ! 745: n = sscanf(myargv[pnum+1], "%c%d%c%d", &xsign, &x, &ysign, &y); ! 746: ! 747: if (n==2) ! 748: x = y = 0; ! 749: else if (n==6) ! 750: { ! 751: if (xsign == '-') ! 752: x = -x; ! 753: if (ysign == '-') ! 754: y = -y; ! 755: } ! 756: else ! 757: I_Error("bad -geom parameter"); ! 758: } ! 759: ! 760: // open the display ! 761: X_display = XOpenDisplay(displayname); ! 762: if (!X_display) ! 763: { ! 764: if (displayname) ! 765: I_Error("Could not open display [%s]", displayname); ! 766: else ! 767: I_Error("Could not open display (DISPLAY=[%s])", getenv("DISPLAY")); ! 768: } ! 769: ! 770: // use the default visual ! 771: X_screen = DefaultScreen(X_display); ! 772: if (!XMatchVisualInfo(X_display, X_screen, 8, PseudoColor, &X_visualinfo)) ! 773: I_Error("xdoom currently only supports 256-color PseudoColor screens"); ! 774: X_visual = X_visualinfo.visual; ! 775: ! 776: // check for the MITSHM extension ! 777: doShm = XShmQueryExtension(X_display); ! 778: ! 779: // even if it's available, make sure it's a local connection ! 780: if (doShm) ! 781: { ! 782: if (!displayname) displayname = (char *) getenv("DISPLAY"); ! 783: if (displayname) ! 784: { ! 785: d = displayname; ! 786: while (*d && (*d != ':')) d++; ! 787: if (*d) *d = 0; ! 788: if (!(!strcasecmp(displayname, "unix") || !*displayname)) doShm = false; ! 789: } ! 790: } ! 791: ! 792: fprintf(stderr, "Using MITSHM extension\n"); ! 793: ! 794: // create the colormap ! 795: X_cmap = XCreateColormap(X_display, RootWindow(X_display, ! 796: X_screen), X_visual, AllocAll); ! 797: ! 798: // setup attributes for main window ! 799: attribmask = CWEventMask | CWColormap | CWBorderPixel; ! 800: attribs.event_mask = ! 801: KeyPressMask ! 802: | KeyReleaseMask ! 803: // | PointerMotionMask | ButtonPressMask | ButtonReleaseMask ! 804: | ExposureMask; ! 805: ! 806: attribs.colormap = X_cmap; ! 807: attribs.border_pixel = 0; ! 808: ! 809: // create the main window ! 810: X_mainWindow = XCreateWindow( X_display, ! 811: RootWindow(X_display, X_screen), ! 812: x, y, ! 813: X_width, X_height, ! 814: 0, // borderwidth ! 815: 8, // depth ! 816: InputOutput, ! 817: X_visual, ! 818: attribmask, ! 819: &attribs ); ! 820: ! 821: XDefineCursor(X_display, X_mainWindow, ! 822: createnullcursor( X_display, X_mainWindow ) ); ! 823: ! 824: // create the GC ! 825: valuemask = GCGraphicsExposures; ! 826: xgcvalues.graphics_exposures = False; ! 827: X_gc = XCreateGC( X_display, ! 828: X_mainWindow, ! 829: valuemask, ! 830: &xgcvalues ); ! 831: ! 832: // map the window ! 833: XMapWindow(X_display, X_mainWindow); ! 834: ! 835: // wait until it is OK to draw ! 836: oktodraw = 0; ! 837: while (!oktodraw) ! 838: { ! 839: XNextEvent(X_display, &X_event); ! 840: if (X_event.type == Expose ! 841: && !X_event.xexpose.count) ! 842: { ! 843: oktodraw = 1; ! 844: } ! 845: } ! 846: ! 847: // grabs the pointer so it is restricted to this window ! 848: if (grabMouse) ! 849: XGrabPointer(X_display, X_mainWindow, True, ! 850: ButtonPressMask|ButtonReleaseMask|PointerMotionMask, ! 851: GrabModeAsync, GrabModeAsync, ! 852: X_mainWindow, None, CurrentTime); ! 853: ! 854: if (doShm) ! 855: { ! 856: ! 857: X_shmeventtype = XShmGetEventBase(X_display) + ShmCompletion; ! 858: ! 859: // create the image ! 860: image = XShmCreateImage( X_display, ! 861: X_visual, ! 862: 8, ! 863: ZPixmap, ! 864: 0, ! 865: &X_shminfo, ! 866: X_width, ! 867: X_height ); ! 868: ! 869: grabsharedmemory(image->bytes_per_line * image->height); ! 870: ! 871: ! 872: // UNUSED ! 873: // create the shared memory segment ! 874: // X_shminfo.shmid = shmget (IPC_PRIVATE, ! 875: // image->bytes_per_line * image->height, IPC_CREAT | 0777); ! 876: // if (X_shminfo.shmid < 0) ! 877: // { ! 878: // perror(""); ! 879: // I_Error("shmget() failed in InitGraphics()"); ! 880: // } ! 881: // fprintf(stderr, "shared memory id=%d\n", X_shminfo.shmid); ! 882: // attach to the shared memory segment ! 883: // image->data = X_shminfo.shmaddr = shmat(X_shminfo.shmid, 0, 0); ! 884: ! 885: ! 886: if (!image->data) ! 887: { ! 888: perror(""); ! 889: I_Error("shmat() failed in InitGraphics()"); ! 890: } ! 891: ! 892: // get the X server to attach to it ! 893: if (!XShmAttach(X_display, &X_shminfo)) ! 894: I_Error("XShmAttach() failed in InitGraphics()"); ! 895: ! 896: } ! 897: else ! 898: { ! 899: image = XCreateImage( X_display, ! 900: X_visual, ! 901: 8, ! 902: ZPixmap, ! 903: 0, ! 904: (char*)malloc(X_width * X_height), ! 905: X_width, X_height, ! 906: 8, ! 907: X_width ); ! 908: ! 909: } ! 910: ! 911: if (multiply == 1) ! 912: screens[0] = (unsigned char *) (image->data); ! 913: else ! 914: screens[0] = (unsigned char *) malloc (SCREENWIDTH * SCREENHEIGHT); ! 915: ! 916: } ! 917: ! 918: ! 919: unsigned exptable[256]; ! 920: ! 921: void InitExpand (void) ! 922: { ! 923: int i; ! 924: ! 925: for (i=0 ; i<256 ; i++) ! 926: exptable[i] = i | (i<<8) | (i<<16) | (i<<24); ! 927: } ! 928: ! 929: double exptable2[256*256]; ! 930: ! 931: void InitExpand2 (void) ! 932: { ! 933: int i; ! 934: int j; ! 935: // UNUSED unsigned iexp, jexp; ! 936: double* exp; ! 937: union ! 938: { ! 939: double d; ! 940: unsigned u[2]; ! 941: } pixel; ! 942: ! 943: printf ("building exptable2...\n"); ! 944: exp = exptable2; ! 945: for (i=0 ; i<256 ; i++) ! 946: { ! 947: pixel.u[0] = i | (i<<8) | (i<<16) | (i<<24); ! 948: for (j=0 ; j<256 ; j++) ! 949: { ! 950: pixel.u[1] = j | (j<<8) | (j<<16) | (j<<24); ! 951: *exp++ = pixel.d; ! 952: } ! 953: } ! 954: printf ("done.\n"); ! 955: } ! 956: ! 957: int inited; ! 958: ! 959: void ! 960: Expand4 ! 961: ( unsigned* lineptr, ! 962: double* xline ) ! 963: { ! 964: double dpixel; ! 965: unsigned x; ! 966: unsigned y; ! 967: unsigned fourpixels; ! 968: unsigned step; ! 969: double* exp; ! 970: ! 971: exp = exptable2; ! 972: if (!inited) ! 973: { ! 974: inited = 1; ! 975: InitExpand2 (); ! 976: } ! 977: ! 978: ! 979: step = 3*SCREENWIDTH/2; ! 980: ! 981: y = SCREENHEIGHT-1; ! 982: do ! 983: { ! 984: x = SCREENWIDTH; ! 985: ! 986: do ! 987: { ! 988: fourpixels = lineptr[0]; ! 989: ! 990: dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) ); ! 991: xline[0] = dpixel; ! 992: xline[160] = dpixel; ! 993: xline[320] = dpixel; ! 994: xline[480] = dpixel; ! 995: ! 996: dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) ); ! 997: xline[1] = dpixel; ! 998: xline[161] = dpixel; ! 999: xline[321] = dpixel; ! 1000: xline[481] = dpixel; ! 1001: ! 1002: fourpixels = lineptr[1]; ! 1003: ! 1004: dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) ); ! 1005: xline[2] = dpixel; ! 1006: xline[162] = dpixel; ! 1007: xline[322] = dpixel; ! 1008: xline[482] = dpixel; ! 1009: ! 1010: dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) ); ! 1011: xline[3] = dpixel; ! 1012: xline[163] = dpixel; ! 1013: xline[323] = dpixel; ! 1014: xline[483] = dpixel; ! 1015: ! 1016: fourpixels = lineptr[2]; ! 1017: ! 1018: dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) ); ! 1019: xline[4] = dpixel; ! 1020: xline[164] = dpixel; ! 1021: xline[324] = dpixel; ! 1022: xline[484] = dpixel; ! 1023: ! 1024: dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) ); ! 1025: xline[5] = dpixel; ! 1026: xline[165] = dpixel; ! 1027: xline[325] = dpixel; ! 1028: xline[485] = dpixel; ! 1029: ! 1030: fourpixels = lineptr[3]; ! 1031: ! 1032: dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff0000)>>13) ); ! 1033: xline[6] = dpixel; ! 1034: xline[166] = dpixel; ! 1035: xline[326] = dpixel; ! 1036: xline[486] = dpixel; ! 1037: ! 1038: dpixel = *(double *)( (int)exp + ( (fourpixels&0xffff)<<3 ) ); ! 1039: xline[7] = dpixel; ! 1040: xline[167] = dpixel; ! 1041: xline[327] = dpixel; ! 1042: xline[487] = dpixel; ! 1043: ! 1044: lineptr+=4; ! 1045: xline+=8; ! 1046: } while (x-=16); ! 1047: xline += step; ! 1048: } while (y--); ! 1049: } ! 1050: ! 1051:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.