home *** CD-ROM | disk | FTP | other *** search
/ Adventures in Heaven 2 / adventuresinheaven2powergamesfordosandwindows.iso / windows / arcade / cbzone / c_gpr.c < prev    next >
C/C++ Source or Header  |  1992-05-27  |  30KB  |  1,068 lines

  1. #include "c_includ.h"
  2. /*
  3.  * cbzone_gpr.c
  4.  *  -- Todd W Mummert, December 1990, CMU
  5.  *
  6.  * RCS info
  7.  *  $Header: c_gpr.c,v 1.1 91/01/12 02:03:32 mummert Locked $
  8.  *
  9.  * emulate gpr/ftn on top of X11.
  10.  *
  11.  * I don't know who originally wrote this emulation routine, but
  12.  * I've seriously changed it anyway.  Therefore, it should not
  13.  * be used with any expectation that it will do anything similiar
  14.  * to the original gpr routines.
  15.  * Almost all of the routines have had their arguments shortened.
  16.  * And why bother returning status when it's always the same.  Most
  17.  * importantly I removed the mallocs that were in polyline and
  18.  * multiline.
  19.  *
  20.  * Added support for window managers, iconification, color, etc...
  21.  * Now, it's basically a file full of one line functions...except
  22.  * for the event handling and initialization.
  23.  *
  24.  * let's define how we are going to use the GC's...
  25.  * Erase GC...both foreground and background the color of the game
  26.  *   background...
  27.  * Text GC...foreground is red...as all text is currently
  28.  * Draw GC...will be changed often...usually just the color
  29.  * BitBlt GC...it will handle the printing of the
  30.  *           lander/missile warning boxes after they are initially
  31.  *           placed.
  32.  */
  33.  
  34. #include "bitmaps\moon.bit"
  35. #include "bitmaps\joystick.bit"
  36. #include "bitmaps\hswitch.bit"
  37. #include "bitmaps\lswitch.bit"
  38. #include "bitmaps\tank.bit"
  39. #include "bitmaps\cursor.bit"
  40. #include "bitmaps\cshape.bit"
  41.  
  42. typedef struct {
  43.   char name[14];                /* the color will be stored as  */
  44. } Colorname;                    /*      #RRRRGGGGBBBB           */
  45.  
  46. typedef struct {
  47.   int width;
  48.   int height;
  49.   char* bits;
  50.   Pixmap p;
  51.   unsigned int color;
  52. } Bmap;
  53.  
  54. Display *d;
  55. Window w, root;
  56. GC BitBltGC, DrawGC, TextGC, EraseGC;
  57. XRectangle clipr;                     /* defines the main viewscreen       */
  58. Colormap cmap, dcmap;                 /* private & default colormaps       */
  59. int ufc, unfc;                        /* number of fading/nonfading colors */
  60. int cw, cr;                           /* number of colors wanted/received  */
  61. Screen* screen;
  62. Pixel* pixels = NULL;                 /* the actual pixel values we obtain */
  63. Colorname* bases = NULL;              /* names of the base colors          */
  64. Colorname* fcnames = NULL;            /* names of the fading colors        */
  65. int screen_num;
  66. Position_t mouse_posn;
  67. int wid, hei, depth;
  68.  
  69. #define NUMPIXMAPS 5
  70. Bmap bmaps[NUMPIXMAPS] = {
  71.   moon_width, moon_height, moon_bits, None, COLOR_MOON,
  72.   joystick_width, joystick_height, joystick_bits, None, COLOR_JOYSTICK,
  73.   hswitch_width, hswitch_height, hswitch_bits, None, COLOR_TEXT,
  74.   lswitch_width, lswitch_height, lswitch_bits, None, COLOR_TEXT,
  75.   tank_width, tank_height, tank_bits, None, COLOR_TEXT
  76.   };
  77.  
  78. void grabpointer()
  79. {
  80. #ifdef X11
  81.   while (XGrabPointer(d, w, False,
  82.                       ButtonPressMask|ButtonReleaseMask|PointerMotionMask,
  83.                       GrabModeAsync,
  84.                       GrabModeAsync,
  85.                       w,
  86.                       None,
  87.                       CurrentTime) != GrabSuccess);
  88. #endif //X11
  89. }
  90.  
  91. void ungrabpointer()
  92. {
  93. #ifdef X11
  94.   XUngrabPointer(d, CurrentTime);
  95. #endif //X11
  96. }
  97.  
  98. void setmonomap()
  99. {
  100.   int i;
  101.  
  102.   cmap = dcmap;
  103.   pixels = (Pixel*) malloc(2 * sizeof(Pixel));
  104.   opt->cpi[COLOR_BG] = 0;
  105.   pixels[0] = BlackPixelOfScreen(screen);
  106. #ifdef WIN32
  107.   hpen[0] = CreatePen( PS_SOLID, 0, pixels[0] );
  108.   hbrushBlack = CreateSolidBrush( 0x00000000 );
  109. #endif
  110.   opt->cpi[COLOR_FG] = 1;
  111.   pixels[1] = WhitePixelOfScreen(screen);
  112. #ifdef WIN32
  113.   hpen[1] = CreatePen( PS_SOLID, 0, WhitePixelOfScreen(screen) );
  114.   hbrushFill = CreateSolidBrush( 0x0000FF00 );
  115. #endif
  116.   opt->fading_colors = 1;
  117.   for (i=2; i<MAX_COLORS; i++)
  118.     opt->cpi[i] = 1;
  119.   cw = cr = 2;
  120. }
  121.  
  122. void createfadedcolors()
  123. {
  124. #ifdef X11
  125.   XColor color;
  126.   int i, j;
  127.   float factor;
  128.   int num = 0;
  129.  
  130.   if (fcnames != NULL)
  131.     free(fcnames);
  132.   fcnames =
  133.     (Colorname *) malloc(ufc*opt->fading_colors*sizeof(Colorname));
  134.   for (i=LF_COLOR; i>LN_COLOR; i--)
  135.     if (opt->cpi[i] == i) {
  136.       XParseColor(d, dcmap, bases[i].name, &color);
  137.       sprintf(fcnames[num++].name, "#%04x%04x%04x",
  138.               color.red, color.green, color.blue);
  139.       for (j=1; j<opt->fading_colors; j++) {
  140.         factor = 1.0 - 0.5*j/(opt->fading_colors-1);
  141.         sprintf(fcnames[num++].name, "#%04x%04x%04x",
  142.                 (int) (factor*color.red), (int) (factor*color.green),
  143.                 (int) (factor*color.blue));
  144.       }
  145.     }
  146. #endif //X11
  147. }
  148.  
  149. void setcoloroptvalues()
  150. {
  151.   int i;
  152.   int num = 0;
  153.  
  154.   for (i=L_COLOR; i>=0; i--)
  155.     if (opt->cpi[i] == i) {
  156.       opt->cpi[i] = num;
  157.       if (i>LN_COLOR)
  158.         num += opt->fading_colors;
  159.       else
  160.         num++;
  161.     }
  162.     else
  163.       opt->cpi[i] = opt->cpi[opt->cpi[i]];
  164. }
  165.  
  166. void standardizecolors(v)
  167.      Visual* v;
  168. {
  169. #ifdef X11
  170.   XColor color;
  171.   int i;
  172.   int num = 0;
  173.  
  174.   if (bases != NULL)
  175.     free(bases);
  176.   bases = (Colorname *) malloc(MAX_COLORS*sizeof(Colorname));
  177.   for (i=0; i<MAX_COLORS; i++) {
  178.     XParseColor(d, dcmap, opt->cname[i], &color);
  179.     if (v->class == StaticGray || v->class == GrayScale)
  180.       color.red = color.green = color.blue = color.red > color.green ?
  181.         (color.red > color.blue ? color.red : color.blue) :
  182.           (color.green > color.blue ? color.green : color.blue);
  183.     sprintf(bases[num++].name,
  184.             "#%04x%04x%04x", color.red, color.green, color.blue);
  185.   }
  186. #endif //X11
  187. }
  188.  
  189. int writecolormap(status)
  190.      Bool* status;
  191. {
  192. #ifdef X11
  193.   int i, j;
  194.   XColor color;
  195.   int ind = 0;
  196.   int num = 0;
  197.  
  198.   *status = True;
  199.   if (pixels != NULL)
  200.     free(pixels);
  201.   pixels = (Pixel*) calloc(cw, sizeof(Pixel));
  202.   for (i=L_COLOR; *status && i>=0; i--)
  203.     if (opt->cpi[i] == i)
  204.       if (opt->fading_colors < 2 || i<FF_COLOR) {
  205.         XParseColor(d, cmap, bases[i].name, &color);
  206.         if (XAllocColor(d, cmap, &color))
  207.           pixels[num++] = color.pixel;
  208.         else
  209.           *status = False;
  210.       }
  211.       else
  212.         for (j=0; *status && j<opt->fading_colors; j++) {
  213.           XParseColor(d, cmap, fcnames[ind++].name, &color);
  214.           if (XAllocColor(d, cmap, &color))
  215.             pixels[num++] = color.pixel;
  216.           else
  217.             *status = False;
  218.         }
  219.   return num;
  220. #endif //X11
  221. }
  222.  
  223. void countcolors()
  224. {
  225.   int i, j;
  226.  
  227.   ufc = unfc = 0;
  228.   if (opt->mono) {
  229.     cr = cw = unfc = 2;
  230.     return;
  231.   }
  232.   for (i=L_COLOR; i>=0; i--) {
  233.     for (j=L_COLOR; j>i && strcmp(bases[i].name,bases[j].name); j--);
  234.     opt->cpi[i] = j;
  235.     if (i == j)
  236.       if (opt->fading_colors==1 || i<FF_COLOR)
  237.         unfc++;
  238.       else
  239.         ufc++;
  240.   }
  241.   cw = unfc+ufc*opt->fading_colors;
  242. }
  243.  
  244. void reducecolors()
  245. {
  246.   int i, firstcolor, lastcolor;
  247.   static int attempt = 0;
  248.   static int groupings[][2] = {
  249.     F1_COLOR, L1_COLOR, F2_COLOR, L2_COLOR, F3_COLOR, L3_COLOR,
  250.     F4_COLOR, L4_COLOR, F5_COLOR, L5_COLOR, F6_COLOR, L6_COLOR,
  251.     F7_COLOR, L7_COLOR, F8_COLOR, L8_COLOR, F9_COLOR, L9_COLOR };
  252.  
  253.   while (cw > cr) {
  254.     switch(attempt++) {
  255.     case 0:                     /* reduce # of fading colors */
  256.       opt->fading_colors = (cr-unfc)/ufc;
  257.       if (opt->fading_colors < 1)
  258.         opt->fading_colors = 1;
  259.       break;
  260.     case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9:
  261.       /* now start combining color groups */
  262.       firstcolor = groupings[attempt-1][0];
  263.       lastcolor = groupings[attempt-1][1];
  264.       for (i=lastcolor; i>firstcolor; i--)
  265.         strcpy(bases[i].name, bases[firstcolor].name);
  266.       break;
  267.     case 10:
  268.       opt->mono = True;
  269.       break;
  270.     }
  271.     countcolors();
  272.   }
  273. }
  274.  
  275. void setcolormap()
  276. {
  277. #ifdef X11
  278.   int dallocated, pallocated;
  279.   Bool success = False;
  280.   Visual* visual;
  281.  
  282.   if (opt->mono || depth == 1) {        /* mono? */
  283.     setmonomap();
  284.     return;
  285.   }
  286.  
  287.   visual = DefaultVisual(d, screen_num);
  288.   standardizecolors(visual);
  289.  
  290.   if (opt->max_colors < 2)
  291.     if (depth<8)
  292.       cr = 1<<depth;
  293.     else
  294.       cr = 256;
  295.   else
  296.     cr = opt->max_colors;
  297.  
  298.   if (opt->fading_colors < 1)
  299.     opt->fading_colors = cr;
  300.  
  301.   do {
  302.     countcolors();
  303.     reducecolors();
  304.  
  305.     if (opt->mono) {
  306.       setmonomap();
  307.       return;
  308.     }
  309.  
  310.     if (opt->fading_colors > 1)
  311.       createfadedcolors();
  312.  
  313.     if (DisplayCells(d, screen_num) >= cw) {
  314.       cmap = dcmap;
  315.       dallocated = writecolormap(&success);
  316.     }
  317.     else
  318.       dallocated = DisplayCells(d, screen_num);
  319.  
  320.     pallocated = 0;
  321.     if (!success) {
  322.       XFreeColors(d, cmap, pixels, dallocated, 0);
  323.       if (!opt->defaultcolormap) {
  324.         cmap = XCreateColormap(d, root, visual, AllocNone);
  325.         pallocated = writecolormap(&success);
  326.         if (!success) {
  327.           XFreeColors(d, cmap, pixels, pallocated, 0);
  328.           XFreeColormap(d, cmap);
  329.         }
  330.       }
  331.     }
  332.  
  333.     cr = dallocated>pallocated ? dallocated : pallocated;
  334.   } while (!success);
  335.  
  336.   setcoloroptvalues();
  337. #endif //X11
  338. }
  339.  
  340. void gprinit ()
  341. {
  342. #ifdef X11
  343.   XEvent ev;
  344.  
  345.   XSelectInput(d, w, ExposureMask|PointerMotionMask|ButtonPressMask
  346.                |ButtonReleaseMask|KeyPressMask|StructureNotifyMask);
  347.   XMapRaised(d, w);
  348.   XWindowEvent(d, w, StructureNotifyMask, &ev);
  349.   grabpointer();
  350. #endif //X11
  351. }
  352.  
  353. void buildgcs()
  354. {
  355. #ifdef X11
  356.   XGCValues xgcv;
  357.   XColor BColor, FColor;
  358.   Font f;
  359.  
  360.   xgcv.foreground = pixels[opt->cpi[COLOR_FG]];
  361.   xgcv.background = pixels[opt->cpi[COLOR_BG]];
  362.   DrawGC = XCreateGC(d, w, GCForeground | GCBackground, &xgcv);
  363.   xgcv.foreground = pixels[opt->cpi[COLOR_TEXT]];
  364.   TextGC = XCreateGC(d, w, GCForeground | GCBackground, &xgcv);
  365.   xgcv.foreground = pixels[opt->cpi[COLOR_BG]];
  366.   EraseGC = XCreateGC(d, w, GCForeground | GCBackground, &xgcv);
  367.   xgcv.function = GXxor;
  368.   xgcv.foreground = pixels[opt->cpi[COLOR_TEXT]] ^ pixels[opt->cpi[COLOR_BG]];
  369.   BitBltGC = XCreateGC(d, w, GCFunction | GCForeground | GCBackground, &xgcv);
  370.   FColor.pixel = pixels[opt->cpi[COLOR_CURSOR]];
  371.   XQueryColor(d, cmap, &FColor);
  372.   BColor.pixel = pixels[opt->cpi[COLOR_BG]];
  373.   XQueryColor(d, cmap, &BColor);
  374.   if (opt->cursor)
  375.     XDefineCursor(d, w,
  376.                   XCreatePixmapCursor(d,
  377.                                       XCreateBitmapFromData(d, w, cursor_bits,
  378.                                                             16, 16),
  379.                                       XCreateBitmapFromData(d, w, cshape_bits,
  380.                                                             16, 16),
  381.                                       &FColor, &BColor, 8, 10 ));
  382.   else {
  383.     f = XLoadFont(d, "fixed");
  384.     XDefineCursor(d, w,
  385.                   XCreateGlyphCursor(d, f, f, ' ', ' ', &FColor, &BColor));
  386.   }
  387. #endif //X11
  388. }
  389.  
  390. void buildpixmaps()
  391. {
  392. #ifdef X11
  393.   int i;
  394.  
  395.   for (i=0; i<NUMPIXMAPS; i++)
  396.     bmaps[i].p =
  397.       XCreatePixmapFromBitmapData(d, w, bmaps[i].bit,
  398.                                   bmaps[i].width, bmaps[i].height,
  399.                                   pixels[opt->cpi[bmaps[i].color]],
  400.                                   pixels[opt->cpi[COLOR_BG]],
  401.                                   depth);
  402. #endif //X11
  403. }
  404.  
  405. #ifdef X11
  406. static XrmOptionDescRec CbzoneOptions[] = {
  407.   {"-delay", "*delay", XrmoptionSepArg, NULL},
  408.   {"-blocks", "*blocks", XrmoptionSepArg, NULL},
  409.   {"-landers", "*landers", XrmoptionSepArg, NULL},
  410.   {"-tanks", "*tanks", XrmoptionSepArg, NULL},
  411.   {"-missiles", "*missiles", XrmoptionSepArg, NULL},
  412.   {"-salvos", "*salvos", XrmoptionSepArg, NULL},
  413.   {"-coptersonly", "*coptersonly", XrmoptionNoArg, "True"},
  414.   {"-quiet", "*quiet", XrmoptionNoArg, "False"},
  415.   {"-scores", "*scores", XrmoptionNoArg,  "True"},
  416.   {"-original", "*original", XrmoptionNoArg, "True"},
  417.   {"-version", "*version", XrmoptionNoArg, "True"},
  418.   {"-help", "*help", XrmoptionNoArg, "True"},
  419.   {"-nooutput", "*output", XrmoptionNoArg, "False"},
  420.   {"-mono", "*mono", XrmoptionNoArg, "True"},
  421.   {"-cursor", "*cursor", XrmoptionNoArg, "True"},
  422.   {"-nofullscreen", "*fullscreen", XrmoptionNoArg, "False"},
  423.   {"-defaultcolormap", "*defaultcolormap", XrmoptionNoArg, "True"}
  424. };
  425.  
  426. static XtResource CbzoneResources[] = {
  427.   {"delay", "Delay", XtRInt, sizeof(int),
  428.      XtOffset(Optionp, delay), XtRImmediate, (caddr_t) DELAY},
  429.   {"blocks", "Blocks", XtRInt, sizeof(int),
  430.      XtOffset(Optionp, mblocks), XtRImmediate, (caddr_t) MBLOCKS},
  431.   {"landers", "Landers", XtRInt, sizeof(int),
  432.      XtOffset(Optionp, mlanders), XtRImmediate, (caddr_t) MLANDERS},
  433.   {"tanks", "Tanks", XtRInt, sizeof(int),
  434.      XtOffset(Optionp, mtanks), XtRImmediate, (caddr_t) MTANKS},
  435.   {"missiles", "Missiles", XtRInt, sizeof(int),
  436.      XtOffset(Optionp, mmissiles), XtRImmediate, (caddr_t) MMISSILES},
  437.   {"salvos", "Salvos", XtRInt, sizeof(int),
  438.      XtOffset(Optionp, msalvos), XtRImmediate, (caddr_t) MSALVOS},
  439.   {"coptersonly", "Coptersonly", XtRBoolean, sizeof(Boolean),
  440.      XtOffset(Optionp, copters), XtRString, "False"},
  441.   {"quiet", "Quiet", XtRBoolean, sizeof(Boolean),
  442.      XtOffset(Optionp, loud), XtRString, "True"},
  443.   {"scores", "Scores", XtRBoolean, sizeof(Boolean),
  444.      XtOffset(Optionp, scores), XtRString, "False"},
  445.   {"original", "Original", XtRBoolean, sizeof(Boolean),
  446.      XtOffset(Optionp, original), XtRString, "False"},
  447.   {"version", "Version", XtRBoolean, sizeof(Boolean),
  448.      XtOffset(Optionp, version), XtRString, "False"},
  449.   {"help", "Help", XtRBoolean, sizeof(Boolean),
  450.      XtOffset(Optionp, help), XtRString, "False"},
  451.   {"output", "Output", XtRBoolean, sizeof(Boolean),
  452.      XtOffset(Optionp, output), XtRString, "True"},
  453.   {"mono", "Mono", XtRBoolean, sizeof(Boolean),
  454.      XtOffset(Optionp, mono), XtRString, "False"},
  455.   {"bgcolor", "BgColor", XtRString, sizeof(String),
  456.      XtOffset(Optionp, cname[COLOR_BG]),
  457.      XtRString, "black"},
  458.   {"fgcolor", "FgColor", XtRString, sizeof(String),
  459.      XtOffset(Optionp, cname[COLOR_FG]),
  460.      XtRString, "skyblue"},
  461.   {"textcolor", "TextColor", XtRString, sizeof(String),
  462.      XtOffset(Optionp, cname[COLOR_TEXT]),
  463.      XtRString, "red"},
  464.   {"esalvocolor", "SalvoColor", XtRString, sizeof(String),
  465.      XtOffset(Optionp, cname[COLOR_ESALVO]),
  466.      XtRString, "red"},
  467.   {"psalvocolor", "SalvoColor", XtRString, sizeof(String),
  468.      XtOffset(Optionp, cname[COLOR_PSALVO]),
  469.      XtRString, "skyblue"},
  470.   {"joystickcolor", "JoystickColor", XtRString, sizeof(String),
  471.      XtOffset(Optionp, cname[COLOR_JOYSTICK]),
  472.      XtRString, "red"},
  473.   {"scannercolor", "ScannerColor", XtRString, sizeof(String),
  474.      XtOffset(Optionp, cname[COLOR_SCANNER]),
  475.      XtRString, "green"},
  476.   {"horizoncolor", "HorizonColor", XtRString, sizeof(String),
  477.      XtOffset(Optionp, cname[COLOR_HORIZON]),
  478.      XtRString, "gray50"},
  479.   {"mooncolor", "MoonColor", XtRString, sizeof(String),
  480.      XtOffset(Optionp, cname[COLOR_MOON]),
  481.      XtRString, "gray50"},
  482.   {"xhaircolor", "XHairColor", XtRString, sizeof(String),
  483.      XtOffset(Optionp, cname[COLOR_XHAIR]),
  484.      XtRString, "gray50"},
  485.   {"cursorcolor", "CursorColor", XtRString, sizeof(String),
  486.      XtOffset(Optionp, cname[COLOR_CURSOR]), XtRString, "skyblue"},
  487.   {"crackcolor", "CrackColor", XtRString, sizeof(String),
  488.      XtOffset(Optionp, cname[COLOR_CRACKS]),
  489.      XtRString, "skyblue"},
  490.   {"tankcolor", "EnemyColor", XtRString, sizeof(String),
  491.      XtOffset(Optionp, cname[COLOR_TANK]),
  492.      XtRString, "green"},
  493.   {"supercolor", "EnemyColor", XtRString, sizeof(String),
  494.      XtOffset(Optionp, cname[COLOR_SUPER]),
  495.      XtRString, "green"},
  496.   {"missilecolor", "EnemyColor", XtRString, sizeof(String),
  497.      XtOffset(Optionp, cname[COLOR_MISSILE]),
  498.      XtRString, "green"},
  499.   {"coptercolor", "EnemyColor", XtRString, sizeof(String),
  500.      XtOffset(Optionp, cname[COLOR_COPTER]),
  501.      XtRString, "green"},
  502.   {"landercolor", "LanderColor", XtRString, sizeof(String),
  503.      XtOffset(Optionp, cname[COLOR_LANDER]),
  504.      XtRString, "green"},
  505.   {"cubecolor", "BlockColor", XtRString, sizeof(String),
  506.      XtOffset(Optionp, cname[COLOR_CUBE]),
  507.      XtRString, "yellow"},
  508.   {"pyramidcolor", "BlockColor", XtRString, sizeof(String),
  509.      XtOffset(Optionp, cname[COLOR_PYRAMID]),
  510.      XtRString, "yellow"},
  511.   {"maxcolors", "MaxColors", XtRInt, sizeof(int),
  512.      XtOffset(Optionp, max_colors), XtRImmediate, (caddr_t) 0},
  513.   {"fadingcolors", "FadingColors", XtRInt, sizeof(int),
  514.      XtOffset(Optionp, fading_colors), XtRImmediate, (caddr_t) 0},
  515.   {"cursor", "Cursor", XtRBoolean, sizeof(Boolean),
  516.      XtOffset(Optionp, cursor), XtRString, "False"},
  517.   {"fullscreen", "Fullscreen", XtRBoolean, sizeof(Boolean),
  518.      XtOffset(Optionp, fullscreen), XtRString, "True"},
  519.   {"defaultcolormap", "DefaultColormap", XtRBoolean, sizeof(Boolean),
  520.      XtOffset(Optionp, defaultcolormap), XtRString, "False"}
  521. };
  522. #endif //X11
  523.  
  524. void gprinqconfig(argc, argv)
  525.      int* argc;
  526.      char* argv[];
  527. {
  528. #ifdef WIN32
  529.   parseopt(*argc, argv, True);
  530.   setmonomap(); // Eric Fogelin: Bypass setcolormap. Go right to mono.
  531. #else //X11
  532.   Widget cbzone;
  533.   XWMHints wmhints;
  534.   XSizeHints shints;
  535.   XtAppContext cbzonecontext;
  536.   int i;
  537.  
  538.   XtToolkitInitialize();
  539.   cbzonecontext = XtCreateApplicationContext();
  540.   if ((d = XtOpenDisplay(cbzonecontext, NULL,
  541.                          "cbzone", "Cbzone",
  542.                          CbzoneOptions, XtNumber(CbzoneOptions),
  543.                          argc, argv)) == NULL) {
  544.     parseopt(*argc, argv, False);
  545.     printf("can't open display! bye.\n");
  546.     exit(0);
  547.   }
  548.   cbzone = XtAppCreateShell("cbzone", "Cbzone",
  549.                             applicationShellWidgetClass, d, NULL, 0);
  550.   XtGetApplicationResources(cbzone, opt, CbzoneResources,
  551.                             XtNumber(CbzoneResources), NULL, 0);
  552.   parseopt(*argc, argv, True);
  553.  
  554.   screen = DefaultScreenOfDisplay(d);
  555.   depth = DisplayPlanes(d, screen_num);
  556.   screen_num = DefaultScreen(d);
  557.   dcmap = DefaultColormap(d, screen_num);
  558.   root = DefaultRootWindow(d);
  559.   setcolormap();
  560.  
  561.   if (opt->fullscreen) {
  562.     shints.width = wid = WidthOfScreen(screen)+10;
  563.     shints.height = hei = HeightOfScreen(screen)+10;
  564.     shints.x = shints.y = 0;
  565.     shints.flags = USPosition | USSize;
  566.   }
  567.   else {
  568.     wid = 1000;
  569.     hei = 710;
  570.     shints.flags = 0;
  571.   }
  572.  
  573.   w = XCreateSimpleWindow (d, root, 0, 0, wid, hei, 0,
  574.                            pixels[opt->cpi[COLOR_BG]],
  575.                            pixels[opt->cpi[COLOR_BG]]);
  576.   XSetWindowColormap(d, w, cmap);
  577.  
  578.   wmhints.input = True;
  579.   wmhints.flags = InputHint;
  580.   XSetWMHints(d, w, &wmhints);
  581.   XSetNormalHints(d, w, &shints);
  582.   XStoreName(d, w,"Cbzone");
  583.   XSetIconName(d, w, "Cbzone");
  584.  
  585.   gprinit();
  586.   buildgcs();
  587.   buildpixmaps();
  588. #endif //X11
  589. }
  590.  
  591. void gprsettextfont(font)
  592.      Font font;
  593. {
  594. #ifdef X11
  595.   XSetFont(d, TextGC, font);
  596. #endif //X11
  597. }
  598.  
  599. void printstring(x, y, string, nchars)
  600.      int x, y;
  601.      char* string;
  602.      int nchars;
  603. {
  604. #ifdef WIN32
  605.   TextOut (hdc, x, y, string, nchars);
  606. #else //X11
  607.   XDrawImageString (d, w, TextGC, x, y, string, nchars);
  608. #endif //X11
  609. }
  610.  
  611. void polyline(points, number)
  612.      XPoint *points;
  613.      int number;
  614. {
  615. #ifdef WIN32
  616.   int i;
  617.   POINT pt[100];
  618.   for (i=0; i<number; points++, i++) {
  619.     pt[i].x = points->x;
  620.     pt[i].y = points->y;
  621.   }
  622.   Polyline(hdc, pt, number);
  623. #else //X11
  624.   XDrawLines(d, w, DrawGC, points, number, CoordModeOrigin);
  625. #endif //X11
  626. }
  627.  
  628. void multiline(segments, number)
  629.      XSegment *segments;
  630.      int number;
  631. {
  632. #ifdef WIN32
  633. #ifndef WIN31
  634.   int i, j;
  635.   POINT pt[100];
  636.   DWORD polycnt[50];
  637.   for (i=0, j=0; i<number*2; segments++, i += 2, j++) {
  638.     pt[i].x = segments->x1;
  639.     pt[i].y = segments->y1;
  640.     pt[i+1].x = segments->x2;
  641.     pt[i+1].y = segments->y2;
  642.     polycnt[j] = 2;
  643.   }
  644.   PolyPolyline(hdc, pt, polycnt, number);
  645. #else
  646.   int i;
  647.   for (i=0; i<number; segments++, i++) {
  648.     MoveToEx( hdc, segments->x1, segments->y1, NULL );
  649.     LineTo( hdc, segments->x2, segments->y2 );
  650.   }
  651. #endif /WIN31
  652. #else //X11
  653.   XDrawSegments (d, w, DrawGC, segments, number);
  654. #endif //X11
  655. }
  656.  
  657. void drawrectangle(x, y, width, height)
  658.      int x, y, width, height;
  659. {
  660. #ifdef WIN32
  661.   // HOLLOW,
  662.   HBRUSH hbrushOld;
  663.  
  664.   hbrushOld = SelectObject( hdc, hbrushBlack );
  665.   Rectangle (hdc, x, y, x+width, y+height);
  666.   SelectObject( hdc, hbrushOld );
  667. #else //X11
  668.   XDrawRectangle (d, w, DrawGC, x, y, width, height);
  669. #endif //X11
  670. }
  671.  
  672. void bitblt(window)
  673.      Window_t *window;
  674. {
  675. #ifdef WIN32
  676.   RECT rect;
  677.   // Eric Fogelin: This is simply an InvertRect (see BitBltGC GXor above)?!?
  678.   rect.left = window->base.x;
  679.   rect.top = window->base.y;
  680.   rect.right = rect.left+window->size.x;
  681.   rect.bottom = rect.top+window->size.y;
  682.  
  683.   InvertRect(hdc, &rect );
  684. #else //X11
  685.   XFillRectangle(d, w, BitBltGC, window->base.x, window->base.y,
  686.                  window->size.x, window->size.y);
  687. #endif //X11
  688. }
  689.  
  690. void clearrectangle(window, dsto)
  691.      Window_t *window;
  692.      Position_t *dsto;
  693. {
  694. #ifdef WIN32
  695.   // Eric Fogelin: Fill rectangle with opaque background
  696.   HBRUSH hbrushOld;
  697.  
  698.   hbrushOld = SelectObject( hdc, hbrushBlack );
  699.   Rectangle (hdc, dsto->x, dsto->y, window->size.x+dsto->x, window->size.y+dsto->y);
  700.   SelectObject( hdc, hbrushOld );
  701. #else //X11
  702.   XFillRectangle(d,w,EraseGC,dsto->x, dsto->y,
  703.                  window->size.x, window->size.y);
  704. #endif //X11
  705. }
  706.  
  707. void gprsetclippingactive(flag)
  708.      Bool flag;
  709. {
  710.   HRGN hrgn; // WIN32 additions
  711.   if (flag) {
  712. #ifdef WIN32
  713.     IntersectClipRect( hdc, clipr.x+2, clipr.y, clipr.x+clipr.width-1, clipr.y+clipr.height-1 );
  714. //    hrgn = CreateRectRgn( clipr.x*2/3, clipr.y*2/3, clipr.x+clipr.width*2/3, clipr.y+clipr.height*2/3 );
  715. //    SelectClipRgn( hdc, hrgn );
  716. //    DeleteObject ( hrgn );
  717. #else // X11
  718.     XSetClipRectangles (d, DrawGC, 0, 0, &clipr, 1, YXBanded);
  719.     XSetClipRectangles (d, EraseGC, 0, 0, &clipr, 1, YXBanded);
  720. #endif
  721.   } else {
  722. #ifdef WIN32
  723.     hrgn = CreateRectRgn( 0, 0, 1000, 1000 );
  724.     SelectClipRgn( hdc, hrgn );
  725.     DeleteObject ( hrgn );
  726. #else // X11
  727.     XSetClipMask (d, DrawGC, None);
  728.     XSetClipMask (d, EraseGC, None);
  729. #endif //X11
  730.   }
  731. }
  732.  
  733. void tonetime()
  734. {
  735.   if (opt->loud)
  736. #ifdef WIN32
  737. ;
  738. //    MessageBeep();
  739. #else //X11
  740.     XBell(d, 0);
  741. #endif //X11
  742. }
  743.  
  744. void timeclock(tval)
  745.      struct timeval* tval;
  746. {
  747. // Eric Fogelin: Appears to flush X calls (graphics?) before calling time
  748. // Appears to make sure game is over (everything flushed) before showing time
  749. #ifdef X11
  750.   XSync(d, False);
  751. #endif //X11
  752.   gettimeofday(tval, 0);
  753. }
  754.  
  755. void gprinqcursor(posn)
  756.      Position_t *posn;
  757. {
  758.   *posn = mouse_posn;
  759. }
  760.  
  761. Bool paused = False;
  762. Bool gprcondeventwait(key, posn)
  763.      char* key;
  764.      Position_t *posn;
  765. {
  766. #ifdef WIN32
  767.   int i;
  768.   short state;
  769.   static POINT mouse_old;
  770.   POINT pt;
  771.   MSG msg;
  772.  
  773.   for (i=0; i<NUMVKEYS; i++) {
  774.     state = GetAsyncKeyState( vkey[i].vkey );
  775.     if ( (vkey[i].prevstate ^ state) & KEYDOWN ) {
  776.     vkey[i].prevstate = state;
  777.     if (state & KEYDOWN)
  778.         *key = vkey[i].vkeydown;
  779.     else
  780.         *key = vkey[i].vkeyup;
  781.     // Flush mouse message from input queue
  782.     do {
  783.     } while( PeekMessage( &msg, NULL, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE ));
  784.     return True;
  785.     }
  786.   }
  787.  
  788.   GetCursorPos( &pt );
  789.   ScreenToClient( GetFocus(), &pt );
  790.   DPtoLP( hdc, &pt, 1 );
  791.   if ((mouse_old.x != pt.x) || (mouse_old.y != pt.y)) {
  792.       mouse_old.x = mouse_posn.x = pt.x;
  793.       mouse_old.y = mouse_posn.y = pt.y;
  794.       *posn = mouse_posn;
  795.       return True;
  796.    }
  797.    return False;
  798.  
  799. #else // X11
  800.   static unsigned long flag[16]={0};
  801.   XEvent ev;
  802.   char keystr;
  803.   Bool return_val = False;
  804.   Bool motion = False;
  805.  
  806.   while (XPending(d) || paused) {
  807.     XNextEvent(d, &ev);
  808.     switch(ev.type) {
  809.     case Expose:
  810.       if (((XExposeEvent*) &ev)->count) break;
  811.       if (!paused)
  812.         grabpointer();
  813.       mouse_posn.x = ev.xexpose.x;
  814.       mouse_posn.y = ev.xexpose.y;
  815.       *key = 'R';
  816.       return_val = True;
  817.       break;
  818.     case UnmapNotify:
  819.       paused = True;
  820.       break;
  821.     case MapNotify:
  822.       paused = False;
  823.       break;
  824.     case KeyPress:
  825.       if (XLookupString(&ev.xkey,&keystr,1,(KeySym *) 0,
  826.                         (XComposeStatus *) 0) == 1)
  827.         switch (keystr) {
  828.         case 'p': case 'P':
  829.           ungrabpointer();
  830.           paused = True;
  831.           break;
  832.         case 'c': case 'C':
  833.           grabpointer();
  834.           paused = False;
  835.           break;
  836.         case 'i': case 'I': case ' ':
  837.           XIconifyWindow(d, w, screen_num);
  838.           break;
  839.         case 'r': case 'R':
  840.           *key = 'R';
  841.           return_val = True;
  842.           break;
  843.         case '\003': case 'q': case 'Q':
  844.           *key = 'Q';
  845.           return_val = True;
  846.           break;
  847.         }
  848.       if (return_val) {
  849.         mouse_posn.x = ev.xkey.x;
  850.         mouse_posn.y = ev.xkey.y;
  851.       }
  852.       break;
  853.     case MotionNotify:
  854.       motion = True;
  855.       mouse_posn.x = ev.xmotion.x;
  856.       mouse_posn.y = ev.xmotion.y;
  857.       break;
  858.     case ButtonPress:
  859.       mouse_posn.x = ev.xbutton.x;
  860.       mouse_posn.y = ev.xbutton.y;
  861.       *key = ev.xbutton.button + 'a' - 1;
  862.       flag[ev.xbutton.button]=1;
  863.       return_val = True;
  864.       break;
  865.     case ButtonRelease:
  866.       mouse_posn.x = ev.xbutton.x;
  867.       mouse_posn.y = ev.xbutton.y;
  868.       *key = ev.xbutton.button + 'A' - 1;
  869.       flag[ev.xbutton.button]=0;
  870.       return_val = True;
  871.       break;
  872.     }
  873.     if (return_val)
  874.       break;
  875.   }
  876.   if(flag[1]&&flag[3]) {
  877.     *key = 'Q';
  878.     return_val = True;
  879.   }
  880.   if (!paused) {
  881.     *posn = mouse_posn;
  882.   }
  883.   return return_val;
  884. #endif //X11
  885. }
  886.  
  887. void gprsetcursorposition(posn)
  888.      Position_t *posn;
  889. {
  890. #ifdef X11
  891.   XWarpPointer (d, None, w, 0, 0, 0, 0, posn->x, posn->y);
  892. #endif //X11
  893. }
  894.  
  895. Font gprloadfontfile(name)
  896.      char* name;
  897. {
  898. #ifdef WIN32
  899.   HFONT hfont;
  900.   hfont = CreateFont( 22, 0,
  901.             0, 0, FW_DONTCARE,
  902.             0, 0, 0,
  903.             ANSI_CHARSET, OUT_TT_PRECIS, 0, PROOF_QUALITY,
  904.             FIXED_PITCH, NULL );
  905.   SelectObject( hdc, hfont );
  906.  
  907. #else
  908.   XFontStruct *xfs;
  909.  
  910.   if ((xfs = XLoadQueryFont(d, name)) == NULL)
  911.     return XLoadFont(d, "fixed");
  912.   else
  913.     return xfs->fid;
  914. #endif //X11
  915. }
  916.  
  917. void gprsettextvalue(index)
  918.      int index;
  919. {
  920. #ifdef WIN32
  921.   SetTextColor( hdc, pixels[index]);
  922. #else //X11
  923.   XSetForeground(d, TextGC, pixels[index]);
  924. #endif //X11
  925. }
  926.  
  927. void gprsettextbackgroundvalue(index)
  928.      int index;
  929. {
  930. #ifdef WIN32
  931.   SetBkColor( hdc, pixels[index]);
  932. #else //X11
  933.   XSetBackground(d, TextGC, pixels[index]);
  934. #endif //X11
  935. }
  936.  
  937. void gprsetdrawvalue(index)
  938.      int index;
  939. {
  940. #ifdef WIN32
  941.   // Need to create pens??!?!
  942.   // SetColor( hdc, pixels[index]);
  943.   SelectObject( hdc, hpen[index] );
  944. #else //X11
  945.   XSetForeground(d, DrawGC, pixels[index]);
  946. #endif //X11
  947. }
  948.  
  949. void gprcircle(center, radius)
  950.      Position_t *center;
  951.      int radius;
  952. {
  953. #ifdef WIN32
  954.   // HOLLOW
  955.   HBRUSH hbrushOld;
  956.  
  957.   hbrushOld = SelectObject( hdc, hbrushBlack );
  958.   Ellipse( hdc, center->x - radius, center->y - radius, center->x + radius, center->y + radius );
  959.   SelectObject( hdc, hbrushOld );
  960. #else //X11
  961.   XDrawArc (d, w, DrawGC,
  962.             center->x - radius, center->y - radius,
  963.             radius+radius, radius+radius, 0, 360*64);
  964. #endif //X11
  965. }
  966.  
  967. void gprcirclefilled(center, radius)
  968.      Position_t *center;
  969.      int radius;
  970. {
  971. #ifdef WIN32
  972.   // FILL
  973.   Ellipse( hdc, center->x - radius, center->y - radius, center->x + radius, center->y + radius );
  974. #else //X11
  975.   XFillArc (d, w, DrawGC,
  976.             center->x - radius, center->y - radius,
  977.             radius+radius, radius+radius, 0, 360*64);
  978. #endif //X11
  979. }
  980.  
  981. void gprsetclipwindow(window)
  982.      Window_t *window;
  983. {
  984.   clipr.x = window->base.x;
  985.   clipr.y = window->base.y;
  986.   clipr.width = window->size.x;
  987.   clipr.height =  window->size.y;
  988. }
  989.  
  990. void clearentirescreen()
  991. {
  992. #ifdef X11
  993.   XClearWindow(d, w);
  994. #endif //X11
  995. }
  996.  
  997. void flushwindow()
  998. {
  999. #ifdef X11
  1000.   XFlush(d);
  1001. #endif //X11
  1002. }
  1003.  
  1004. void waitforkey(c)
  1005.      char c;
  1006. {
  1007. #ifdef X11
  1008.   char keystr;
  1009.   XEvent ev;
  1010.  
  1011.   XFlush(d);                    /* out with the old */
  1012.   while (XPending(d))
  1013.     XNextEvent(d, &ev);
  1014.                                 /* now wait for the new */
  1015.   while (1) {
  1016.     XWindowEvent(d, w, KeyPressMask|ButtonPressMask, &ev);
  1017.     switch(ev.type) {
  1018.     case KeyPress:
  1019.       if (!c || XLookupString(&ev.xkey,&keystr,1,(KeySym *) 0,
  1020.                         (XComposeStatus *) 0) == 1 &&
  1021.           keystr == c)
  1022.         return;
  1023.       break;
  1024.     case ButtonPress:
  1025.       if (!c)
  1026.         return;
  1027.       break;
  1028.     }
  1029.   }
  1030. #endif //X11
  1031. }
  1032.  
  1033. void putpixmap(i, p)
  1034.      int i;
  1035.      int* p;
  1036. {
  1037. #ifdef WIN32
  1038.   // Eric Fogelin: HACK.  Just fill rect where pixmap would go.
  1039.   // Change fill color to white?
  1040.   HBRUSH hbrushOld;
  1041.  
  1042.   hbrushOld = SelectObject( hdc, hbrushFill );
  1043.   Ellipse (hdc, p[0], p[1], p[0]+bmaps[i].width, p[1]+bmaps[i].height );
  1044.   SelectObject( hdc, hbrushOld );
  1045. #else //X11
  1046.   XCopyArea(d, bmaps[i].p, w, DrawGC, 0, 0,
  1047.             bmaps[i].width, bmaps[i].height, p[0], p[1]);
  1048. #endif //X11
  1049. }
  1050.  
  1051. void removepixmap(i, p)
  1052.      int i;
  1053.      int* p;
  1054. {
  1055. #ifdef WIN32
  1056.   // Eric Fogelin: HACK.  Just fill rect where pixmap would go.
  1057.   // Change fill color to black?
  1058.   HBRUSH hbrushOld;
  1059.  
  1060.   hbrushOld = SelectObject( hdc, hbrushBlack );
  1061.   Rectangle (hdc, p[0], p[1], p[0]+bmaps[i].width, p[1]+bmaps[i].height );
  1062.   SelectObject( hdc, hbrushOld );
  1063. #else //X11
  1064.   XFillRectangle(d, w, EraseGC, p[0], p[1],
  1065.                  bmaps[i].width, bmaps[i].height);
  1066. #endif //X11
  1067. }
  1068.