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