i_video.c
上传用户:xuyinpeng
上传日期:2021-05-12
资源大小:455k
文件大小:23k
源码类别:

射击游戏

开发平台:

Visual C++

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