home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / XAP / XGAMES / SPIDER.TAR / spider / gfx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-28  |  35.8 KB  |  1,440 lines

  1. /*
  2.  *    Spider
  3.  *
  4.  *    (c) Copyright 1989, Donald R. Woods and Sun Microsystems, Inc.
  5.  *    (c) Copyright 1990, David Lemke and Network Computing Devices Inc.
  6.  *
  7.  *    See copyright.h for the terms of the copyright.
  8.  *
  9.  *    @(#)gfx.c    2.3    90/05/30
  10.  *
  11.  */
  12.  
  13. /*
  14.  * Spider card drawing routines
  15.  */
  16. #include    "defs.h"
  17. #include    "globals.h"
  18.  
  19. #ifdef ROUND_CARDS
  20. #include    <X11/Xmu/Drawing.h>
  21.  
  22. #define    ROUND_W    7
  23. #define    ROUND_H    7
  24.  
  25. Bool    round_cards = True;
  26. #endif
  27.  
  28. static GC    cardgc;        /* gc in use when drawing cards */
  29.  
  30. #ifdef    KITLESS
  31. static int    message_y;
  32. static GC    textgc;
  33. #endif    /* KITLESS */
  34.  
  35.  
  36. /* substitue gray1 for Green on mono */
  37. #define gray1_width 16
  38. #define gray1_height 16
  39. static char gray1_bits[] = {
  40.    0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
  41.    0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
  42.    0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa};
  43.  
  44. /* logo for card backs */
  45. /* any size logo can be handled.  */
  46.  
  47. #define logo_width 64
  48. #define logo_height 64
  49. static char logo_bits[] = {
  50.  0x77,0xd5,0xd7,0xdd,0x77,0xd5,0xd7,0xdd,0xbb,0xea,0xae,0xbb,0xbb,0xea,0xae,
  51.  0xbb,0x5d,0x75,0x5d,0x77,0x5d,0x75,0x5d,0x77,0xee,0xba,0xba,0xee,0xae,0xba,
  52.  0xba,0xee,0x77,0x5d,0x75,0xdd,0x77,0x5d,0x75,0xdd,0xbb,0xae,0xea,0xba,0xbb,
  53.  0xae,0xea,0xba,0x5d,0x57,0xd5,0x75,0x5d,0x57,0xd5,0x75,0xae,0xab,0xaa,0xeb,
  54.  0xae,0xab,0xaa,0xeb,0xd7,0x55,0x55,0xd7,0xd7,0x51,0x55,0xd7,0xeb,0xae,0xaa,
  55.  0xae,0xeb,0xa2,0xaa,0xae,0x75,0x5d,0x55,0x5d,0x75,0x44,0x15,0x5d,0xba,0xbb,
  56.  0xea,0xba,0xba,0x88,0x8a,0xba,0x5d,0x77,0x75,0x75,0x1d,0x11,0x45,0x75,0xee,
  57.  0xee,0xba,0xea,0x2e,0x22,0xa2,0xea,0xd7,0xdd,0x5d,0xd5,0x57,0x44,0x10,0xd5,
  58.  0xab,0xbb,0xef,0xaa,0xab,0x88,0x88,0xaa,0x57,0x77,0x77,0xd5,0x57,0x11,0x45,
  59.  0xd5,0xae,0xee,0xba,0xea,0xae,0x22,0xa2,0xea,0x5d,0xdd,0x5d,0x75,0x5d,0x45,
  60.  0x10,0x75,0xba,0xba,0xef,0xba,0xba,0x8a,0x88,0xba,0x75,0x75,0x77,0x5d,0x75,
  61.  0x15,0x45,0x5d,0xea,0xea,0xba,0xae,0xea,0x2a,0xa2,0xae,0xdd,0xd5,0x5d,0x77,
  62.  0xdd,0x55,0x50,0x77,0xae,0xab,0xaf,0xeb,0xae,0xab,0xa8,0xeb,0xd7,0x55,0x57,
  63.  0xd7,0xd7,0x55,0x55,0xd7,0xeb,0xaa,0xaa,0xae,0xeb,0xaa,0xaa,0xae,0x75,0x57,
  64.  0x55,0x5d,0x75,0x57,0x55,0x5d,0xba,0xae,0xea,0xba,0xba,0xae,0xaa,0xba,0xdd,
  65.  0x5d,0x75,0x75,0xdd,0x5d,0x75,0x75,0xae,0xbb,0xba,0xea,0xae,0xbb,0xba,0xea,
  66.  0x77,0x77,0x5d,0xd5,0x77,0x77,0x5d,0xd5,0xeb,0xee,0xee,0xaa,0xeb,0xee,0xae,
  67.  0xaa,0xd7,0xdd,0x77,0xd5,0xd7,0xdd,0x77,0xd5,0xae,0xbb,0xbb,0xea,0xae,0xbb,
  68.  0xbb,0xea,0x5d,0x77,0x5d,0x75,0x5d,0x77,0x5d,0x75,0xba,0xee,0xee,0xba,0xba,
  69.  0xee,0xae,0xba,0x75,0xdd,0x77,0x5d,0x75,0xdd,0x77,0x5d,0xea,0xba,0xbb,0xae,
  70.  0xea,0xba,0xbb,0xae,0xd5,0x75,0x5d,0x57,0xd5,0x75,0x5d,0x57,0xaa,0xeb,0xae,
  71.  0xab,0xaa,0xeb,0xae,0xab,0x55,0xd7,0xd7,0x55,0x55,0xd7,0xd7,0x55,0xaa,0xae,
  72.  0xeb,0xae,0xaa,0xae,0xeb,0xae,0x55,0x5d,0x75,0x5d,0x55,0x5d,0x75,0x5d,0xea,
  73.  0xba,0xba,0xbb,0xea,0xba,0xba,0xbb,0x75,0x75,0x5d,0x77,0x75,0x75,0x5d,0x77,
  74.  0xba,0xea,0xee,0xee,0xba,0xea,0xee,0xee,0x5d,0xd5,0xd7,0xdd,0x5d,0xd5,0xd7,
  75.  0xdd,0xef,0xaa,0xab,0xbb,0xef,0xaa,0xab,0xbb,0x77,0xd5,0x57,0x77,0x77,0xd5,
  76.  0x57,0x77,0xba,0xea,0xae,0xee,0xba,0xea,0xae,0xee,0x5d,0x75,0x5d,0xdd,0x5d,
  77.  0x75,0x5d,0xdd,0xef,0xba,0xba,0xba,0xef,0xba,0xba,0xba,0x77,0x5d,0x75,0x75,
  78.  0x77,0x5d,0x75,0x75,0xba,0xae,0xea,0xea,0xba,0xae,0xea,0xea,0x5d,0x77,0xdd,
  79.  0xd5,0x5d,0x77,0xdd,0xd5,0xaf,0xeb,0xae,0xab,0xaf,0xeb,0xae,0xab,0x57,0xd7,
  80.  0xd7,0x55,0x57,0xd7,0xd7,0x55,0xaa,0xae,0xeb,0xaa,0xaa,0xae,0xeb,0xaa,0x55,
  81.  0x5d,0x75,0x57,0x55,0x5d,0x75,0x57,0xaa,0xba,0xba,0xae,0xaa,0xba,0xba,0xae,
  82.  0x75,0x75,0xdd,0x5d,0x55,0x75,0xdd,0x5d,0xba,0xea,0xae,0xbb,0xba,0xea,0xae,
  83.  0xbb,0x5d,0xd5,0x77,0x77,0x5d,0xd5,0x77,0x77,0xae,0xaa,0xeb,0xee,0xae,0xaa,
  84.  0xeb,0xee};
  85.  
  86. #ifndef SMALL_CARDS
  87. #include    "rank.bm"
  88. #include    "face.bm"
  89. #include    "suit.bm"
  90.  
  91. static Pixmap    rank_map[NUM_RANKS],    rank_r_map[NUM_RANKS];
  92. static Pixmap    rank_map_red[NUM_RANKS],    rank_r_map_red[NUM_RANKS];
  93. static Pixmap    suit_map[NUM_SUITS],    suit_r_map[NUM_SUITS];
  94. static Pixmap    suit_sm_map[NUM_SUITS],    suit_sm_r_map[NUM_SUITS];
  95. static Pixmap    suit_lg_map[NUM_SUITS];
  96. static Pixmap    jack_map[NUM_SUITS], queen_map[NUM_SUITS], king_map[NUM_SUITS];
  97.  
  98. #else    /* SMALL_CARDS */
  99. #include    "cards.bm"
  100.  
  101. static Pixmap    card_bitmaps[CARDS_PER_DECK];
  102. #endif /* !SMALL_CARDS */
  103.  
  104. /* clipping rectangles */
  105. static XRectangle    cliprects[1] = { 0, 0, CARD_WIDTH + 1, 0};
  106.  
  107. static GC    redgc;
  108. static GC    blackgc;
  109. static GC    whitegc;
  110. static GC    backgc;
  111.  
  112. static int    back_delta_x, back_delta_y; /* how much to modify the TS origin by */
  113.  
  114. #ifndef SMALL_CARDS
  115. static Bool    card_is_clipped;    /* optimizer for card drawing */
  116. #endif
  117.  
  118. gfx_init(d, scr)
  119. Display    *d;
  120. int    scr;
  121. {
  122. XGCValues    gcv;
  123. long        gcflags;
  124. XColor        color;
  125. Colormap    cmap;
  126. Pixmap        tmpmap;
  127. GC        logogc;
  128. unsigned long    redpixel;
  129.  
  130.     /* save these off */
  131.     dpy = d;
  132.     screen = scr;
  133.  
  134.     if (DisplayCells(dpy, screen) > 2)    {
  135.         is_color = True;
  136.     }    else    {
  137.         is_color = False;
  138.     }
  139.  
  140.     blackpixel = BlackPixel(dpy, screen);
  141.     whitepixel = WhitePixel(dpy, screen);
  142.  
  143.     /* make gc for white */
  144.     gcv.foreground = WhitePixel(dpy, screen);
  145.     gcv.background = BlackPixel(dpy, screen);
  146.     gcv.graphics_exposures = False;
  147.     gcflags = GCForeground | GCBackground | GCGraphicsExposures;
  148.  
  149.     whitegc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
  150.  
  151.     /* make gc for black */
  152.     gcv.foreground = BlackPixel(dpy, screen);
  153.     gcv.background = WhitePixel(dpy, screen);
  154.     gcflags = GCForeground | GCBackground | GCGraphicsExposures;
  155.  
  156.     blackgc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
  157.  
  158. #ifdef    KITLESS
  159.     /* add on to blackgc */
  160.     if ((message_font = XLoadQueryFont(dpy, MESSAGE_FONT)) == NULL)    {
  161.         (void) fprintf(stderr,"can't get font %s\n", MESSAGE_FONT);
  162.         exit(0);
  163.     }
  164.     message_y = message_font->ascent;
  165.     gcv.font = message_font->fid;
  166.     gcflags |= GCFont;
  167.  
  168.     textgc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
  169. #endif KITLESS
  170.  
  171.     tmpmap = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  172.         logo_bits, logo_width, logo_height);
  173.  
  174.     logomap = XCreatePixmap(dpy, RootWindow(dpy, screen), logo_width,
  175.         logo_height, DefaultDepth(dpy, screen));
  176.  
  177.     back_delta_x = (CARD_WIDTH - logo_width)/2;
  178.     back_delta_y = (CARD_HEIGHT - logo_height)/2;
  179.  
  180.     /* XXX -- workaround for X11R4 bug */
  181.     back_delta_x -= CARD_WIDTH;
  182.     back_delta_y -= CARD_HEIGHT;
  183.  
  184.     if (is_color)    {
  185.         cmap = DefaultColormap(dpy, screen);
  186.         XAllocNamedColor(dpy, cmap, "Sea Green", &color, &color);
  187.         gcv.foreground = color.pixel;
  188.         gcv.background = WhitePixel(dpy, screen);
  189.         gcflags = GCForeground | GCBackground;
  190.         logogc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
  191.         XCopyPlane(dpy, tmpmap, logomap, logogc, 0, 0, 
  192.             logo_width, logo_height, 0, 0, 1);
  193.         XFreeGC(dpy, logogc);
  194.     } else    {
  195.         XCopyPlane(dpy, tmpmap, logomap, whitegc, 0, 0, 
  196.             logo_width, logo_height, 0, 0, 1);
  197.     }
  198.     XFreePixmap(dpy, tmpmap);
  199.  
  200.     gcv.tile = logomap;
  201.     gcv.fill_style = FillTiled;
  202.     gcflags |= GCTile | GCFillStyle | GCGraphicsExposures;
  203.  
  204.     backgc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
  205.  
  206.     borderpixel = blackpixel;
  207.  
  208.     if (is_color)    {
  209.         cmap = DefaultColormap(dpy, screen);
  210.  
  211.         color.flags = DoRed | DoGreen | DoBlue;
  212.  
  213.         /*
  214.          * color levels are the NeWS RGB values
  215.          */
  216.         color.red = 13107;    /* 0.2 */
  217.         color.green = 52428;    /* 0.8 */
  218.         color.blue = 39321;    /* 0.6 */
  219.         XAllocColor(dpy, cmap, &color);
  220.         greenpixel = color.pixel;
  221.  
  222.         color.red = 52428;    /* 0.8 */
  223.         color.green = color.blue = 0;
  224.         XAllocColor(dpy, cmap, &color);
  225.         redpixel = color.pixel;
  226.  
  227.         gcv.foreground = redpixel;
  228.         gcv.background = WhitePixel(dpy, screen);
  229.         gcflags = GCForeground | GCBackground | GCGraphicsExposures;
  230.  
  231.         redgc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
  232.  
  233.     } else    {
  234.         greenmap = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  235.             gray1_bits, gray1_width, gray1_height);
  236.  
  237.         redmap = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  238.             gray1_bits, gray1_width, gray1_height);
  239.  
  240.         gcv.tile = redmap;
  241.         gcv.fill_style = FillTiled;
  242.  
  243.         gcv.foreground = BlackPixel(dpy, screen);
  244.         gcv.background = WhitePixel(dpy, screen);
  245.  
  246.         gcflags = GCTile | GCForeground | GCBackground |
  247.             GCFillStyle | GCGraphicsExposures;
  248.  
  249.         redgc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
  250.     }
  251.     make_card_maps();
  252. }
  253.  
  254. #ifndef SMALL_CARDS
  255. /*
  256.  * make a 'red' pixmap by setting the clipmask to the desired shape and 
  257.  * pushing 'red' through it
  258.  */
  259.  
  260. static Pixmap
  261. make_red_map(bits, width, height)
  262. char    *bits;
  263. int    width, height;
  264. {
  265. Pixmap    tmpmap, newmap;
  266. static GC    cleargc = (GC) 0;
  267. XGCValues    xgcv;
  268.  
  269.  
  270.     if (cleargc == (GC) 0)    {
  271.         xgcv.function = GXclear;
  272.         cleargc = XCreateGC(dpy, RootWindow(dpy, screen), GCFunction, 
  273.                                 &xgcv);
  274.     }
  275.  
  276.     tmpmap = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  277.         bits, width, height);
  278.  
  279.     newmap = XCreatePixmap(dpy, RootWindow(dpy, screen), width, height, 1);
  280.  
  281.     /* clear pixmap */
  282.     XFillRectangle(dpy, newmap, cleargc, 0, 0, width, height);
  283.  
  284.     XSetClipMask(dpy, redgc, tmpmap);
  285.     XFillRectangle(dpy, newmap, redgc, 0, 0, width, height);
  286.     XSetClipMask(dpy, redgc, None);
  287.     XFreePixmap(dpy, tmpmap);
  288.  
  289.     return (newmap);
  290. }
  291.  
  292. make_card_maps()
  293. {
  294. unsigned char    *new_bits;
  295. Rank    r;
  296. int    i;
  297.  
  298.     for (r = Ace; r <= King; r++)    {
  299.         rank_map[(int)r] = XCreateBitmapFromData(dpy, 
  300.             RootWindow(dpy, screen),
  301.             rank_bits[(int)r], rank_width, rank_height);
  302.  
  303.         new_bits = (unsigned char *) calloc(sizeof(rank_bits[(int)r]),
  304.                             1);
  305.         rot_180((unsigned char *)rank_bits[(int)r], new_bits, 
  306.             rank_width, rank_height);
  307.         rank_r_map[(int)r] = XCreateBitmapFromData(dpy, 
  308.             RootWindow(dpy, screen),
  309.             new_bits, rank_width, rank_height);
  310.         free((char *)new_bits);
  311.     }
  312.  
  313.     for (r = Ace; r <= King; r++)    {
  314.         new_bits = (unsigned char *) calloc(sizeof(rank_bits[(int)r]),
  315.                             1);
  316.         rot_180((unsigned char *)rank_bits[(int)r], new_bits, 
  317.                 rank_width, rank_height);
  318.         if (is_color)    {
  319.             rank_map_red[(int)r] = XCreateBitmapFromData(dpy, 
  320.                 RootWindow(dpy, screen),
  321.                 rank_bits[(int)r], rank_width, rank_height);
  322.  
  323.             rank_r_map_red[(int)r] = XCreateBitmapFromData(dpy, 
  324.                 RootWindow(dpy, screen),
  325.                 new_bits, rank_width, rank_height);
  326.         } else    {
  327.             rank_map_red[(int)r] = make_red_map(rank_bits[(int)r],
  328.                         rank_width, rank_height);
  329.  
  330.             rank_r_map_red[(int)r] = make_red_map((char *)new_bits, 
  331.                         rank_width, rank_height);
  332.         }
  333.         free((char *)new_bits);
  334.     }
  335.  
  336.     i = (int)Spade;
  337.     /* make all the card bitmaps */
  338.     suit_map[i] = XCreateBitmapFromData(dpy, 
  339.         RootWindow(dpy, screen),
  340.         spade_bits, spade_width, spade_height);
  341.  
  342.     new_bits = (unsigned char *) calloc(sizeof(spade_bits), 1);
  343.     flip_bits((unsigned char *)spade_bits, new_bits, spade_width, 
  344.                 spade_height);
  345.     suit_r_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  346.         new_bits, spade_width, spade_height);
  347.     free((char *)new_bits);
  348.  
  349.     suit_sm_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  350.         spade_sm_bits, spade_sm_width, spade_sm_height);
  351.  
  352.     new_bits = (unsigned char *) calloc(sizeof(spade_sm_bits), 1);
  353.     flip_bits((unsigned char *)spade_sm_bits, new_bits, spade_sm_width,
  354.             spade_sm_height);
  355.     suit_sm_r_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  356.         new_bits, spade_sm_width, spade_sm_height);
  357.     free((char *)new_bits);
  358.  
  359.     suit_lg_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  360.         spade_lg_bits, spade_lg_width, spade_lg_height);
  361.  
  362.     jack_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  363.         jack_s_bits, jack_s_width, jack_s_height);
  364.  
  365.     queen_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  366.         queen_s_bits, queen_s_width, queen_s_height);
  367.  
  368.     king_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  369.         king_s_bits, king_s_width, king_s_height);
  370.  
  371.     i = (int)Heart;
  372.     /* make all the card bitmaps */
  373.     new_bits = (unsigned char *) calloc(sizeof(heart_bits), 1);
  374.     flip_bits((unsigned char *)heart_bits, new_bits, heart_width, 
  375.                     heart_height);
  376.  
  377.     if (is_color)    {
  378.         suit_map[i] = XCreateBitmapFromData(dpy, 
  379.             RootWindow(dpy, screen),
  380.             heart_bits, heart_width, heart_height);
  381.         suit_r_map[i] = XCreateBitmapFromData(dpy, 
  382.             RootWindow(dpy, screen),
  383.             new_bits, heart_width, heart_height);
  384.     } else    {
  385.         suit_map[i] = make_red_map(heart_bits, heart_width, 
  386.                         heart_height);
  387.         suit_r_map[i] = make_red_map((char *)new_bits, heart_width, 
  388.                         heart_height);
  389.     }
  390.  
  391.     free((char *)new_bits);
  392.  
  393.     new_bits = (unsigned char *) calloc(sizeof(heart_sm_bits), 1);
  394.     flip_bits((unsigned char *)heart_sm_bits, new_bits, heart_sm_width, 
  395.         heart_sm_height);
  396.     suit_sm_r_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  397.         new_bits, heart_sm_width, heart_sm_height);
  398.  
  399.     if (is_color)    {
  400.         suit_sm_map[i] = XCreateBitmapFromData(dpy, 
  401.             RootWindow(dpy, screen),
  402.             heart_sm_bits, heart_sm_width, heart_sm_height);
  403.         suit_sm_r_map[i] = XCreateBitmapFromData(dpy, 
  404.             RootWindow(dpy, screen),
  405.             new_bits, heart_sm_width, heart_sm_height);
  406.     } else    {
  407.         suit_sm_map[i] = make_red_map(heart_sm_bits, heart_sm_width, 
  408.                         heart_height);
  409.         suit_sm_r_map[i] = make_red_map((char *)new_bits, 
  410.             heart_sm_width, heart_sm_height);
  411.     }
  412.     free((char *)new_bits);
  413.  
  414.     suit_lg_map[i] = suit_map[i];
  415.  
  416.     if (is_color)    {
  417.         jack_map[i] = XCreateBitmapFromData(dpy, 
  418.             RootWindow(dpy, screen),
  419.             jack_h_bits, jack_h_width, jack_h_height);
  420.  
  421.         queen_map[i] = XCreateBitmapFromData(dpy, 
  422.             RootWindow(dpy, screen),
  423.             queen_h_bits, queen_h_width, queen_h_height);
  424.  
  425.         king_map[i] = XCreateBitmapFromData(dpy, 
  426.             RootWindow(dpy, screen),
  427.             king_h_bits, king_h_width, king_h_height);
  428.     } else    {
  429.         jack_map[i] = make_red_map(jack_h_bits, jack_h_width, 
  430.                             jack_h_height);
  431.  
  432.         queen_map[i] = make_red_map(queen_h_bits, queen_h_width, 
  433.                             queen_h_height);
  434.  
  435.         king_map[i] = make_red_map(king_h_bits, king_h_width, 
  436.                             king_h_height);
  437.     }
  438.  
  439.  
  440.     i = (int)Diamond;
  441.     /* make all the card bitmaps */
  442.     new_bits = (unsigned char *) calloc(sizeof(diamond_bits), 1);
  443.     flip_bits((unsigned char *)diamond_bits, new_bits, diamond_width, 
  444.         diamond_height);
  445.  
  446.     if (is_color)    {
  447.         suit_map[i] = XCreateBitmapFromData(dpy, 
  448.             RootWindow(dpy, screen),
  449.             diamond_bits, diamond_width, diamond_height);
  450.         suit_r_map[i] = XCreateBitmapFromData(dpy, 
  451.             RootWindow(dpy, screen),
  452.             new_bits, diamond_width, diamond_height);
  453.     } else    {
  454.         suit_map[i] = make_red_map(diamond_bits, diamond_width, 
  455.                         diamond_height);
  456.         suit_r_map[i] = make_red_map((char *)new_bits, diamond_width, 
  457.                         diamond_height);
  458.     }
  459.  
  460.     free((char *)new_bits);
  461.  
  462.     new_bits = (unsigned char *) calloc(sizeof(diamond_sm_bits), 1);
  463.     flip_bits((unsigned char *)diamond_sm_bits, new_bits, 
  464.                 diamond_sm_width, diamond_sm_height);
  465.     suit_sm_r_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  466.         new_bits, diamond_sm_width, diamond_sm_height);
  467.  
  468.     if (is_color)    {
  469.         suit_sm_map[i] = XCreateBitmapFromData(dpy, 
  470.             RootWindow(dpy, screen),
  471.             diamond_sm_bits, diamond_sm_width, diamond_sm_height);
  472.         suit_sm_r_map[i] = XCreateBitmapFromData(dpy, 
  473.             RootWindow(dpy, screen),
  474.             new_bits, diamond_sm_width, diamond_sm_height);
  475.     } else    {
  476.         suit_sm_map[i] = make_red_map(diamond_sm_bits, diamond_sm_width, 
  477.                         diamond_height);
  478.         suit_sm_r_map[i] = make_red_map((char *)new_bits, 
  479.                 diamond_sm_width, diamond_sm_height);
  480.     }
  481.     free((char *)new_bits);
  482.  
  483.     suit_lg_map[i] = suit_map[i];
  484.  
  485.     if (is_color)    {
  486.         jack_map[i] = XCreateBitmapFromData(dpy, 
  487.             RootWindow(dpy, screen),
  488.             jack_d_bits, jack_d_width, jack_d_height);
  489.  
  490.         queen_map[i] = XCreateBitmapFromData(dpy, 
  491.             RootWindow(dpy, screen),
  492.             queen_d_bits, queen_d_width, queen_d_height);
  493.  
  494.         king_map[i] = XCreateBitmapFromData(dpy, 
  495.             RootWindow(dpy, screen),
  496.             king_d_bits, king_d_width, king_d_height);
  497.     } else    {
  498.         jack_map[i] = make_red_map(jack_d_bits, jack_d_width, 
  499.                             jack_d_height);
  500.  
  501.         queen_map[i] = make_red_map(queen_d_bits, queen_d_width, 
  502.                             queen_d_height);
  503.  
  504.         king_map[i] = make_red_map(king_d_bits, king_d_width, 
  505.                             king_d_height);
  506.     }
  507.  
  508.     i = (int)Club;
  509.     /* make all the card bitmaps */
  510.     suit_map[i] = XCreateBitmapFromData(dpy, 
  511.         RootWindow(dpy, screen),
  512.         club_bits, club_width, club_height);
  513.  
  514.     new_bits = (unsigned char *) calloc(sizeof(club_bits), 1);
  515.     flip_bits((unsigned char *)club_bits, new_bits, club_width, 
  516.         club_height);
  517.     suit_r_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  518.         new_bits, club_width, club_height);
  519.     free((char *)new_bits);
  520.  
  521.     suit_sm_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  522.         club_sm_bits, club_sm_width, club_sm_height);
  523.  
  524.     new_bits = (unsigned char *) calloc(sizeof(club_sm_bits), 1);
  525.     flip_bits((unsigned char *)club_sm_bits, new_bits, club_sm_width, 
  526.         club_sm_height);
  527.     suit_sm_r_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  528.         new_bits, club_sm_width, club_sm_height);
  529.     free((char *)new_bits);
  530.  
  531.     suit_lg_map[i] = suit_map[i];
  532.  
  533.  
  534.     jack_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  535.         jack_c_bits, jack_c_width, jack_c_height);
  536.  
  537.     queen_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  538.         queen_c_bits, queen_c_width, queen_c_height);
  539.  
  540.     king_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  541.         king_c_bits, king_c_width, king_c_height);
  542. }
  543.  
  544. #else
  545.  
  546. make_card_maps()
  547. {
  548. int    i;
  549.  
  550.     for (i = 0; i < CARDS_PER_DECK; i++)    {
  551.         card_bitmaps[i] = XCreateBitmapFromData(dpy, 
  552.             RootWindow(dpy, screen), card_bits[i], 
  553.             card_width, card_height);
  554.     }
  555. }
  556. #endif /* !SMALL_CARDS */
  557.  
  558. void
  559. force_redraw()
  560. {
  561.     XClearArea(dpy, table, 0, 0, 0, 0, True);
  562. }
  563.  
  564. /*
  565.  * only bother to show one card, since they're all stacked up
  566.  *
  567.  * REMIND -- spread the deck a bit to show that there's more
  568.  */
  569. redraw_deck(x, y, w, h)
  570. int    x, y, w, h;
  571. {
  572. CardPtr    tmp;
  573.  
  574.     /* trivial reject */
  575.     if ((y > (DECK_Y + CARD_HEIGHT)) || ((y + h) < (DECK_Y)) ||
  576.         (x > (DECK_X + CARD_WIDTH))  || ((x + w) < DECK_X))
  577.         return;
  578.  
  579.     if (deck->cards == CARDNULL)    {
  580.         XClearArea(dpy, table, deck->x, deck->y, CARD_WIDTH,
  581.             CARD_HEIGHT, False);
  582. #ifdef ROUND_CARDS
  583.         if (round_cards)    {
  584.             XmuDrawRoundedRectangle(dpy, table, blackgc, 
  585.                 deck->x, deck->y, CARD_WIDTH, CARD_HEIGHT,
  586.                 ROUND_W, ROUND_H);
  587.         } else
  588. #endif
  589.         XDrawRectangle(dpy, table, blackgc, deck->x, deck->y,
  590.             CARD_WIDTH, CARD_HEIGHT);
  591.     } else    {
  592.         /* only show topmost card */
  593.         tmp = last_card(deck);
  594.         if (tmp->draw_count != draw_count)    {
  595.             show_card(tmp);
  596.             tmp->draw_count = draw_count;
  597.         }
  598.     }
  599. }
  600.  
  601.  
  602. redraw_card_piles(x, y, w, h)
  603. int    x, y, w, h;
  604. {
  605. int    i;
  606. CardPtr    tmp;
  607.  
  608.     /* trivial reject */
  609.     if ((y > (PILE_LOC_Y + CARD_HEIGHT)) || (y + h) < (PILE_LOC_Y))
  610.         return;
  611.  
  612.     /* figure out which piles to show */
  613.     for (i = 0; i < NUM_PILES; i++)    {
  614.         if ((x <= (CARD_WIDTH + PILE_LOC_X(piles[i]->place))) && 
  615.             ((x + w) >= PILE_LOC_X(piles[i]->place)))    {
  616.             if (tmp = piles[i]->cards)    {
  617.                 /* display the last card */
  618.                 while (tmp->next)    {
  619.                     tmp = tmp->next;
  620.                 }
  621.                 if (tmp->draw_count != draw_count)    {
  622.                     show_card(tmp);
  623.                     tmp->draw_count = draw_count;
  624.                 }
  625.             } else    {
  626. #ifdef ROUND_CARDS
  627.                 if (round_cards)
  628.                     XmuDrawRoundedRectangle(dpy, table, blackgc,
  629.                     piles[i]->x, piles[i]->y,
  630.                     CARD_WIDTH, CARD_HEIGHT,
  631.                     ROUND_W, ROUND_H);
  632.                 else
  633. #endif
  634.                     XDrawRectangle(dpy, table, blackgc, 
  635.                     piles[i]->x, piles[i]->y,
  636.                     CARD_WIDTH, CARD_HEIGHT);
  637.             }
  638.             
  639.         }
  640.     }
  641. }
  642.  
  643.  
  644. redraw_card_stacks(x, y, w, h)
  645. int    x, y, w, h;
  646. {
  647. int    i;
  648. CardPtr    tmp;
  649.  
  650.     /* trivial reject */
  651.     if ((y + h) < (STACK_LOC_Y))
  652.         return;
  653.  
  654.     /* figure out which stacks to show */
  655.     for (i = 0; i < NUM_STACKS; i++)    {
  656.         if ((x <= (CARD_WIDTH + STACK_LOC_X(stack[i]->place))) && 
  657.             ((x + w) >= STACK_LOC_X(stack[i]->place))) {
  658.             if (tmp = stack[i]->cards)    {
  659.                 while (tmp)    {
  660.                     int    d;
  661.  
  662.                     if (tmp->next)
  663.                         d = tmp->list->card_delta;
  664.                     else
  665.                         d = CARD_HEIGHT;
  666.                     if ((y <= (tmp->y + d)) && 
  667.                         ((y + h) >= tmp->y)) {
  668. #ifdef ROUND_CARDS
  669. /* for round cards, we just paint the whole stack if any card is damaged.
  670.  * this avoids getting into trouble when unsorted exposure lists come back
  671.  * and we screw up overlaps
  672.  */
  673.                         if (round_cards)    {
  674.                             tmp = stack[i]->cards;
  675.                             /* skip if this stack's been
  676.                              * painted already */
  677.                             if (tmp->draw_count == draw_count)    {
  678.                             tmp = CARDNULL; /* so we pop out */
  679.                             continue;
  680.                             }
  681.                                                     while (tmp)     {
  682.                             show_card(tmp);
  683.                             tmp->draw_count = draw_count;
  684.                                                         tmp = tmp->next;
  685.                                                     }
  686.                             continue;
  687.                         } else
  688. #endif /* ROUND_CARDS */
  689.                         {
  690.                             if (tmp->draw_count != draw_count)    {
  691.                             show_card(tmp);
  692.                             tmp->draw_count = draw_count;
  693.                             }
  694.                         }
  695.                     }
  696.                     tmp = tmp->next;
  697.                 }
  698.             } else    {
  699. #ifdef ROUND_CARDS
  700.                 if (round_cards)
  701.                     XmuDrawRoundedRectangle(dpy, table, blackgc,
  702.                     stack[i]->x, stack[i]->y,
  703.                     CARD_WIDTH, CARD_HEIGHT,
  704.                     ROUND_W, ROUND_H);
  705.                 else
  706. #endif
  707.                     XDrawRectangle(dpy, table, blackgc, 
  708.                     stack[i]->x, stack[i]->y,
  709.                     CARD_WIDTH, CARD_HEIGHT);
  710.             }
  711.         }
  712.     }
  713. }
  714.  
  715. /*
  716.  * clears out and repaints list from card down
  717.  */
  718. show_list(list, card)
  719. CardList    list;
  720. CardPtr        card;
  721. {
  722. CardPtr    tmp;
  723. int    h;
  724.     
  725.     if (list->place >= STACK_1)    {
  726.         h = table_height - ((card) ? card->y : STACK_LOC_Y);
  727.     } else    {
  728.         h = CARD_HEIGHT;
  729.     }
  730.  
  731. #ifdef ROUND_CARDS
  732.     /* don't want to blast the card above us that we overwrite */
  733.     if (round_cards)
  734.         XClearArea(dpy, table, list->x, 
  735.         ((card) ? card->y + ROUND_H : list->y), 
  736.         CARD_WIDTH + 1, 
  737.         h - (IS_PILE(list) ? 0 : ROUND_H),
  738.         False);
  739.     else
  740. #endif
  741.         XClearArea(dpy, table, list->x, ((card) ? card->y : list->y), 
  742.         CARD_WIDTH + 1, h, False);
  743.  
  744.     tmp = card;
  745.     /* draw outline */
  746.     if (tmp == CARDNULL)    {
  747. #ifdef ROUND_CARDS
  748.         if (round_cards)
  749.             XmuDrawRoundedRectangle(dpy, table, blackgc, 
  750.             list->x, list->y,
  751.             CARD_WIDTH, CARD_HEIGHT, ROUND_W, ROUND_H);
  752.         else
  753. #endif
  754.             XDrawRectangle(dpy, table, blackgc, list->x, list->y,
  755.             CARD_WIDTH, CARD_HEIGHT);
  756.     }
  757.     while (tmp)    {
  758.         show_card(tmp);
  759.         tmp = tmp->next;
  760.     }
  761. }
  762.  
  763. /*
  764.  * paints individual card
  765.  */
  766. show_card(card)
  767. CardPtr    card;
  768. {
  769. int    delta    = 0;
  770.  
  771.     if (((card->next == CARDNULL) || ((card->list->card_delta != 0))) && 
  772.         (card->type == Faceup))    {
  773.         if (card->next)
  774.             delta = card->list->card_delta;
  775.         paint_card(card->x, card->y, card->rank, card->suit, delta);
  776.     }
  777.     if (card->type == Facedown)    {
  778.         /* paint all of back if end of stack */
  779.         if (card->next == CARDNULL)     {
  780.             paint_cardback(card->x, card->y, CARD_HEIGHT);
  781.         /* paint delta bits of it otherwise */
  782.         } else if (card->list->card_delta)    {
  783.             paint_cardback(card->x, card->y, 
  784.                 card->list->card_delta);
  785.         }
  786.     }
  787. }
  788.  
  789. paint_cardback(x, y, delta)
  790. int    x, y, delta;
  791. {
  792. #define    INSET    2
  793.     /* change the origin so cards will have the same back anywhere
  794.      * on the table
  795.      */
  796.     /*
  797.      * there should be a tile centered in the card, with the
  798.      * surrounding tiles being partial
  799.      */
  800. #ifdef ROUND_CARDS
  801.     if (round_cards)
  802.         XmuFillRoundedRectangle(dpy, table, blackgc, x, y, CARD_WIDTH, 
  803.         (delta == CARD_HEIGHT) ? delta : delta + ROUND_H * 2,
  804.         ROUND_W, ROUND_H);
  805.     else
  806. #endif
  807.         XFillRectangle(dpy, table, blackgc, x, y, CARD_WIDTH, delta);
  808.     XSetTSOrigin(dpy, backgc, x + back_delta_x, y + back_delta_y);
  809.  
  810. #ifdef ROUND_CARDS
  811.     if (round_cards)
  812.         XmuFillRoundedRectangle(dpy, table, backgc, x + INSET, y + INSET, 
  813.         CARD_WIDTH - 2*INSET,
  814.         (delta == CARD_HEIGHT) ? 
  815.             (CARD_HEIGHT - 2*INSET) : delta + ROUND_H * 2,
  816.         ROUND_W, ROUND_H);
  817.     else
  818. #endif
  819.         XFillRectangle(dpy, table, backgc, x + INSET, y + INSET, 
  820.         CARD_WIDTH - 2*INSET,
  821.         (delta == CARD_HEIGHT) ? 
  822.             (CARD_HEIGHT - 2*INSET) : delta);
  823. }
  824.  
  825. #ifndef SMALL_CARDS
  826. /*
  827.  * delta is 0 if the card is fully showing
  828.  */
  829. paint_card(x, y, rank, suit, delta)
  830. int    x,y;
  831. Rank    rank;
  832. Suit    suit;
  833. int    delta;
  834. {
  835.     if (suit == Spade || suit == Club)    {
  836.         cardgc = blackgc;
  837.     } else    {
  838.         cardgc = redgc;
  839.     }
  840.  
  841.     if (delta)    {
  842. #ifdef ROUND_CARDS
  843.         if (round_cards)
  844.             cliprects[0].height = delta + ROUND_H;
  845.         else
  846. #endif
  847.             cliprects[0].height = delta;
  848.         XSetClipRectangles(dpy, cardgc, x, y, cliprects, 1, Unsorted);
  849. #ifdef ROUND_CARDS
  850.         if (round_cards)    {
  851.             XSetClipRectangles(dpy, whitegc, x, y, cliprects, 1, 
  852.                         Unsorted);
  853.             if (cardgc != blackgc)
  854.             XSetClipRectangles(dpy, blackgc, x, y, cliprects, 1,
  855.                         Unsorted);
  856.  
  857.             /* add in ROUND_H to height so only the top is rounded */
  858.             /* fill the background */
  859.             XmuFillRoundedRectangle(dpy, table, whitegc, x, y, 
  860.             CARD_WIDTH, delta + ROUND_H, ROUND_W, ROUND_H);
  861.             /* draw border on card */
  862.             XmuDrawRoundedRectangle(dpy, table, blackgc, x, y, 
  863.             CARD_WIDTH, delta + ROUND_H, ROUND_W, ROUND_H);
  864.         } else    
  865. #endif
  866.         {
  867.             /* fill the background */
  868.             XFillRectangle(dpy, table, whitegc, x, y, 
  869.                     CARD_WIDTH, delta);
  870.             /* draw border on card */
  871.             XDrawRectangle(dpy, table, blackgc, x, y, 
  872.                     CARD_WIDTH, delta);
  873.         }
  874.         card_is_clipped = True;
  875.     } else    {    /* fill all the card */
  876. #ifdef ROUND_CARDS
  877.         if (round_cards)    {
  878.             /* fill the background */
  879.             XmuFillRoundedRectangle(dpy, table, whitegc, x, y, 
  880.             CARD_WIDTH, CARD_HEIGHT,
  881.             ROUND_W, ROUND_H);
  882.             /* draw border on card */
  883.             XmuDrawRoundedRectangle(dpy, table, blackgc, x, y, 
  884.             CARD_WIDTH, CARD_HEIGHT,
  885.             ROUND_W, ROUND_H);
  886.         } else
  887. #endif
  888.         {
  889.             /* fill the background */
  890.             XFillRectangle(dpy, table, whitegc, x, y, 
  891.             CARD_WIDTH, CARD_HEIGHT);
  892.             /* draw border on card */
  893.             XDrawRectangle(dpy, table, blackgc, x, y, 
  894.             CARD_WIDTH, CARD_HEIGHT);
  895.         }
  896.         card_is_clipped = False;
  897.     }
  898.  
  899.     switch (rank)    {
  900.     case    King:
  901.         draw_king(suit, x, y);
  902.         break;
  903.     case    Queen:
  904.         draw_queen(suit, x, y);
  905.         break;
  906.     case    Jack:
  907.         draw_jack(suit, x, y);
  908.         break;
  909.  
  910.     case    Ten:
  911.         draw_pip(suit, MID_CARD_X + x, CARD_TEN_Y1 + y);
  912.         draw_did(suit, MID_CARD_X + x, CARD_TEN_Y2 + y);
  913.         draw_eight_pips(suit, x, y);
  914.         break;
  915.  
  916.     case    Nine:
  917.         draw_pip(suit, x + MID_CARD_X, y + MID_CARD_Y);
  918.         draw_eight_pips(suit, x, y);
  919.         break;
  920.  
  921.     case    Eight:
  922.         draw_did(suit, x + MID_CARD_X, y + CARD_EIGHT_Y);
  923.         /* fall thru */
  924.     case    Seven:
  925.         draw_pip(suit, MID_CARD_X + x, CARD_SEVEN_Y + y);
  926.         /* fall thru */
  927.     case    Six:
  928.         draw_six_pips(suit, x, y);
  929.         break;
  930.  
  931.     case    Five:
  932.         draw_pip(suit, x + MID_CARD_X, y + MID_CARD_Y);
  933.         /* fall thru */
  934.     case    Four:
  935.         draw_four_pips(suit, x, y);
  936.         break;
  937.  
  938.     case    Three:
  939.         draw_pip(suit, x + MID_CARD_X, y + MID_CARD_Y);
  940.         /* fall thru */
  941.     case    Deuce:
  942.         draw_two_pips(suit, x, y);
  943.         break;
  944.     case    Ace:
  945.         draw_center_pip(suit, x + MID_CARD_X, y + MID_CARD_Y);
  946.         break;
  947.     default:
  948.         assert(0);
  949.     }
  950.  
  951.     draw_rank(x, y, rank, suit);
  952.  
  953.     /* clear the clip mask */
  954.     XSetClipMask(dpy, cardgc, None);
  955. #ifdef ROUND_CARDS
  956.     if (round_cards)    {
  957.         XSetClipMask(dpy, whitegc, None);
  958.         if (cardgc != blackgc)
  959.         XSetClipMask(dpy, blackgc, None);
  960.     }
  961. #endif
  962. }
  963.  
  964. /*
  965.  * NOTE -- for all the pip drawers except the one that actually plots the
  966.  * bits, the location is the card's location.  the drawer's take the
  967.  * pip's center as location.
  968.  */
  969.  
  970. /*
  971.  * draws right-side-up pip
  972.  *
  973.  * location is for center of pip
  974.  */
  975. draw_pip(suit, x, y)
  976. Suit    suit;
  977. int    x, y;
  978. {
  979. int    w, h;
  980.  
  981.     switch(suit)    {
  982.     case    Spade:
  983.         w = spade_width;
  984.         h = spade_height;
  985.         break;
  986.     case    Diamond:
  987.         x++;
  988.         w = diamond_width;
  989.         h = diamond_height;
  990.         break;
  991.     case    Heart:
  992.         y++;
  993.         w = heart_width;
  994.         h = heart_height;
  995.         break;
  996.     case    Club:
  997.         y++;
  998.         w = club_width;
  999.         h = club_height;
  1000.         break;
  1001.     default:
  1002.         assert(0);
  1003.     }
  1004.     XCopyPlane(dpy, suit_map[suit], table, cardgc, 
  1005.         0, 0, w, h,
  1006.         x - w/2, y - h/2, 1);
  1007. }
  1008.  
  1009. /*
  1010.  * draws upside-down pip
  1011.  *
  1012.  * location is for center of pip
  1013.  */
  1014. draw_did(suit, x, y)
  1015. Suit    suit;
  1016. int    x,y;
  1017. {
  1018. int    w, h;
  1019.  
  1020.     if (card_is_clipped)    /* a clipped card never shows any did's */
  1021.         return;
  1022.  
  1023.     switch(suit)    {
  1024.     case    Spade:
  1025.         w = spade_width;
  1026.         h = spade_height;
  1027.         break;
  1028.     case    Diamond:
  1029.         x++;
  1030.         w = diamond_width;
  1031.         h = diamond_height;
  1032.         break;
  1033.     case    Heart:
  1034.         y++;
  1035.         w = heart_width;
  1036.         h = heart_height;
  1037.         break;
  1038.     case    Club:
  1039.         y++;
  1040.         w = club_width;
  1041.         h = club_height;
  1042.         break;
  1043.     default:
  1044.         assert(0);
  1045.     }
  1046.     XCopyPlane(dpy, suit_r_map[suit], table, cardgc, 
  1047.         0, 0, w, h,
  1048.         x - w/2, y - h/2, 1);
  1049. }
  1050.  
  1051. /*
  1052.  * draws big center pip
  1053.  */
  1054. draw_center_pip(suit, x, y)
  1055. Suit    suit;
  1056. int    x,y;
  1057. {
  1058. int    w, h;
  1059.  
  1060.     if (card_is_clipped)
  1061.         return;
  1062.  
  1063.     switch(suit)    {
  1064.     case    Spade:
  1065.         w = spade_lg_width;
  1066.         h = spade_lg_height;
  1067.         break;
  1068.     case    Diamond:
  1069.         w = diamond_width;
  1070.         h = diamond_height;
  1071.         break;
  1072.     case    Heart:
  1073.         w = heart_width;
  1074.         h = heart_height;
  1075.         break;
  1076.     case    Club:
  1077.         w = club_width;
  1078.         h = club_height;
  1079.         break;
  1080.     default:
  1081.         assert(0);
  1082.     }
  1083.     XCopyPlane(dpy, suit_lg_map[suit], table, cardgc, 
  1084.         0, 0, w, h,
  1085.         x - w/2, y - h/2, 1);
  1086. }
  1087.  
  1088. /* 
  1089.  * draw_two_pips
  1090.  */
  1091. draw_two_pips(suit, x, y)
  1092. Suit    suit;
  1093. int    x,y;
  1094. {
  1095.     draw_pip(suit, x + MID_CARD_X, y + CARD_ROW1_Y);
  1096.     draw_did(suit, x + MID_CARD_X, y + CARD_ROW5_Y);
  1097. }
  1098.  
  1099. /*
  1100.  * draw_four_pips
  1101.  */
  1102. draw_four_pips(suit, x, y)
  1103. Suit    suit;
  1104. int    x,y;
  1105. {
  1106.     draw_pip(suit, x + CARD_COL1_X, y + CARD_ROW1_Y);
  1107.     draw_did(suit, x + CARD_COL1_X, y + CARD_ROW5_Y);
  1108.  
  1109.     draw_pip(suit, x + CARD_COL3_X, y + CARD_ROW1_Y);
  1110.     draw_did(suit, x + CARD_COL3_X, y + CARD_ROW5_Y);
  1111. }
  1112.  
  1113. draw_six_pips(suit, x, y)
  1114. Suit    suit;
  1115. int    x, y;
  1116. {
  1117.     draw_pip(suit, x + CARD_COL1_X, y + CARD_ROW1_Y);
  1118.  
  1119.     draw_pip(suit, x + CARD_COL3_X, y + CARD_ROW1_Y);
  1120.  
  1121.     if (card_is_clipped)
  1122.         return;
  1123.  
  1124.     /* these are only visible when its not clipped */
  1125.     draw_pip(suit, x + CARD_COL1_X, y + CARD_ROW3_Y);
  1126.     draw_did(suit, x + CARD_COL1_X, y + CARD_ROW5_Y);
  1127.  
  1128.     draw_pip(suit, x + CARD_COL3_X, y + CARD_ROW3_Y);
  1129.     draw_did(suit, x + CARD_COL3_X, y + CARD_ROW5_Y);
  1130. }
  1131.  
  1132. draw_eight_pips(suit, x, y)
  1133. Suit    suit;
  1134. int    x,y;
  1135. {
  1136.     draw_pip(suit, x + CARD_COL1_X, y + CARD_ROW1_Y);
  1137.  
  1138.     draw_pip(suit, x + CARD_COL3_X, y + CARD_ROW1_Y);
  1139.  
  1140.     if (card_is_clipped)
  1141.         return;
  1142.  
  1143.     /* these are only visible when its not clipped */
  1144.     draw_pip(suit, x + CARD_COL1_X, y + CARD_ROW2_Y);
  1145.     draw_did(suit, x + CARD_COL1_X, y + CARD_ROW4_Y);
  1146.     draw_did(suit, x + CARD_COL1_X, y + CARD_ROW5_Y);
  1147.  
  1148.     draw_pip(suit, x + CARD_COL3_X, y + CARD_ROW2_Y);
  1149.     draw_did(suit, x + CARD_COL3_X, y + CARD_ROW4_Y);
  1150.     draw_did(suit, x + CARD_COL3_X, y + CARD_ROW5_Y);
  1151. }
  1152.  
  1153. draw_jack(suit, x, y)
  1154. Suit    suit;
  1155. int    x,y;
  1156. {
  1157.     XCopyPlane(dpy, jack_map[suit], table, cardgc, 
  1158.         0, 0, FACECARD_WIDTH, FACECARD_HEIGHT,
  1159.         x + (CARD_WIDTH - FACECARD_WIDTH)/2, 
  1160.         y + (CARD_HEIGHT - FACECARD_HEIGHT)/2, 1);
  1161.  
  1162.     XDrawRectangle(dpy, table, cardgc,
  1163.         x + (CARD_WIDTH - FACECARD_WIDTH)/2, 
  1164.         y + (CARD_HEIGHT - FACECARD_HEIGHT)/2,
  1165.         FACECARD_WIDTH, FACECARD_HEIGHT);
  1166. }
  1167.  
  1168. draw_queen(suit, x, y)
  1169. Suit    suit;
  1170. int    x,y;
  1171. {
  1172.     XCopyPlane(dpy, queen_map[suit], table, cardgc,
  1173.         0, 0, FACECARD_WIDTH, FACECARD_HEIGHT,
  1174.         x + (CARD_WIDTH - FACECARD_WIDTH)/2, 
  1175.         y + (CARD_HEIGHT - FACECARD_HEIGHT)/2, 1);
  1176.  
  1177.     XDrawRectangle(dpy, table, cardgc,
  1178.         x + (CARD_WIDTH - FACECARD_WIDTH)/2, 
  1179.         y + (CARD_HEIGHT - FACECARD_HEIGHT)/2,
  1180.         FACECARD_WIDTH, FACECARD_HEIGHT);
  1181. }
  1182.  
  1183. draw_king(suit, x, y)
  1184. Suit    suit;
  1185. int    x,y;
  1186. {
  1187.     XCopyPlane(dpy, king_map[suit], table, cardgc,
  1188.         0, 0, FACECARD_WIDTH, FACECARD_HEIGHT,
  1189.         x + (CARD_WIDTH - FACECARD_WIDTH)/2, 
  1190.         y + (CARD_HEIGHT - FACECARD_HEIGHT)/2, 1);
  1191.  
  1192.     XDrawRectangle(dpy, table, cardgc,
  1193.         x + (CARD_WIDTH - FACECARD_WIDTH)/2, 
  1194.         y + (CARD_HEIGHT - FACECARD_HEIGHT)/2,
  1195.         FACECARD_WIDTH, FACECARD_HEIGHT);
  1196. }
  1197.  
  1198. draw_rank(x, y, rank, suit)
  1199. int    x, y;
  1200. Rank    rank;
  1201. Suit    suit;
  1202. {
  1203. int    w, h;
  1204.  
  1205.     if (suit == Heart || suit == Diamond)    {
  1206.         XCopyPlane(dpy, rank_map_red[rank], table, cardgc,
  1207.             0, 0, RANK_WIDTH, RANK_HEIGHT,
  1208.             x + RANK_LOC_X, y + RANK_LOC_Y, 1);
  1209.  
  1210.         if (!card_is_clipped)
  1211.             XCopyPlane(dpy, rank_r_map_red[rank], table, cardgc,
  1212.             0, 0, RANK_WIDTH, RANK_HEIGHT,
  1213.             x + (CARD_WIDTH - RANK_WIDTH - RANK_LOC_X), 
  1214.             y + (CARD_HEIGHT - RANK_HEIGHT - RANK_LOC_Y), 1);
  1215.     } else    {
  1216.         XCopyPlane(dpy, rank_map[rank], table, cardgc,
  1217.             0, 0, RANK_WIDTH, RANK_HEIGHT,
  1218.             x + RANK_LOC_X, y + RANK_LOC_Y, 1);
  1219.  
  1220.         if (!card_is_clipped)
  1221.             XCopyPlane(dpy, rank_r_map[rank], table, cardgc,
  1222.             0, 0, RANK_WIDTH, RANK_HEIGHT,
  1223.             x + (CARD_WIDTH - RANK_WIDTH - RANK_LOC_X), 
  1224.             y + (CARD_HEIGHT - RANK_HEIGHT - RANK_LOC_Y), 1);
  1225.     }
  1226.  
  1227.     switch (suit)    {
  1228.         case    Spade:
  1229.             w = spade_sm_width;
  1230.             h = spade_sm_height;
  1231.             break;
  1232.         case    Heart:
  1233.             w = heart_sm_width;
  1234.             h = heart_sm_height;
  1235.             break;
  1236.         case    Diamond:
  1237.             x++;    /* offset the smaller width */
  1238.             w = diamond_sm_width;
  1239.             h = diamond_sm_height;
  1240.             break;
  1241.         case    Club:
  1242.             w = club_sm_width;
  1243.             h = club_sm_height;
  1244.             break;
  1245.         default:
  1246.             assert(0);
  1247.     }
  1248.     XCopyPlane(dpy, suit_sm_map[suit], table, cardgc,
  1249.         0, 0, w, h,
  1250.         x + SMALL_LOC_X, y + SMALL_LOC_Y, 1);
  1251.  
  1252.     if (!card_is_clipped)
  1253.         XCopyPlane(dpy, suit_sm_r_map[suit], table, cardgc,
  1254.         0, 0, w, h,
  1255.         x + (CARD_WIDTH - w - SMALL_LOC_X), 
  1256.         y + (CARD_HEIGHT - h - SMALL_LOC_Y), 1);
  1257. }
  1258.  
  1259. #else    /* SMALL_CARDS */
  1260.  
  1261. paint_card(x, y, rank, suit, delta)
  1262. int    x, y;
  1263. Rank    rank;
  1264. Suit    suit;
  1265. int    delta;
  1266. {
  1267. int    card_number;
  1268.  
  1269.     if (suit == Spade || suit == Club)      {
  1270.         cardgc = is_color ? blackgc: whitegc;
  1271.     } else  {
  1272.         cardgc = redgc;
  1273.     }
  1274.  
  1275.     if (delta)    {
  1276.         cliprects[0].height = delta;
  1277.         XSetClipRectangles(dpy, cardgc, x, y, cliprects, 1, Unsorted);
  1278.     }
  1279.  
  1280.     /* this is messy cause these are just straight xsol cards */
  1281.     switch (suit)    {
  1282.         case    Spade:
  1283.             card_number = 3 * NUM_RANKS;
  1284.             break;
  1285.         case    Heart:
  1286.             card_number = 0;
  1287.             break;
  1288.         case    Club:
  1289.             card_number = 2 * NUM_RANKS;
  1290.             break;
  1291.         case    Diamond:
  1292.             card_number = NUM_RANKS;
  1293.             break;
  1294.     }
  1295.     card_number += rank;
  1296.  
  1297.     XCopyPlane(dpy, card_bitmaps[card_number], table, cardgc, 0, 0, 
  1298.         CARD_WIDTH, CARD_HEIGHT, x, y, 1);
  1299.  
  1300.     if (delta)
  1301.         XSetClipMask(dpy, cardgc, None);
  1302. }
  1303. #endif    /* SMALL_CARDS */
  1304.  
  1305.  
  1306. /*
  1307.  * message handling
  1308.  */
  1309.  
  1310. #ifdef KITLESS
  1311. void
  1312. show_message(str)
  1313. char    *str;
  1314. {
  1315. static    char last_message[512];
  1316.  
  1317.     if (str)    {
  1318.         (void)strcpy(last_message, str);
  1319.     }
  1320.     XClearWindow(dpy, message_win);
  1321.     XDrawImageString(dpy, message_win, textgc, MESSAGE_X, message_y,
  1322.         last_message, strlen(last_message));
  1323. }
  1324. #endif    KITLESS
  1325.  
  1326. void
  1327. card_message(str, card)
  1328. char    *str;
  1329. CardPtr    card;
  1330. {
  1331. char    buf[512];
  1332.  
  1333.     (void)sprintf(buf, "%s %s of %s", 
  1334.         str, rank_name(card->rank), suit_name(card->suit));
  1335.     show_message(buf);
  1336. }
  1337.  
  1338. void
  1339. card2_message(str1, card1, str2, card2)
  1340. char    *str1, *str2;
  1341. CardPtr    card1, card2;
  1342. {
  1343. char    buf[512];
  1344.  
  1345.     (void)sprintf(buf, "%s %s of %s %s %s of %s", 
  1346.         str1, rank_name(card1->rank), suit_name(card1->suit),
  1347.         str2, rank_name(card2->rank), suit_name(card2->suit));
  1348.     show_message(buf);
  1349. }
  1350.  
  1351. void
  1352. clear_message()
  1353. {
  1354.     show_message(" ");
  1355. }
  1356.  
  1357. #ifndef SMALL_CARDS
  1358. static unsigned char _reverse_byte[0x100] = {
  1359.     0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
  1360.     0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
  1361.     0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
  1362.     0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
  1363.     0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
  1364.     0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
  1365.     0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
  1366.     0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
  1367.     0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
  1368.     0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
  1369.     0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
  1370.     0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
  1371.     0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
  1372.     0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
  1373.     0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
  1374.     0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
  1375.     0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
  1376.     0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
  1377.     0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
  1378.     0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
  1379.     0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
  1380.     0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
  1381.     0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
  1382.     0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
  1383.     0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
  1384.     0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
  1385.     0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
  1386.     0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
  1387.     0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
  1388.     0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
  1389.     0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
  1390.     0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
  1391. };
  1392.  
  1393. #define S(x,y) src[(H-1-(y))*W+(x)]
  1394. #define D(x,y) dst[(H-1-(y))*W+(x)]
  1395.  
  1396. flip_bits(src, dst, W, H)
  1397. unsigned char    *src, *dst;
  1398. int    W, H;
  1399. {
  1400. int    x, y;
  1401.  
  1402.     W = (W + 7)/8;
  1403.     for (y = 0; y < H; y++)    {
  1404.         for (x = 0; x < W; x++)    {
  1405.             D (x, y) = S (x, H - 1 - y);
  1406.         }
  1407.     }
  1408. }
  1409.  
  1410. rot_180(src, dst, W, H)
  1411. unsigned char   *src, *dst;
  1412. int    W, H;
  1413. {
  1414. int     x, y;
  1415. int    width = W;
  1416. unsigned char    *new;
  1417. int    bit;
  1418.  
  1419.     W = (W + 7)/8;
  1420.     for (y = 0; y < H; y++) {
  1421.         for (x = 0; x < W; x++) {
  1422.             D (x, y) = _reverse_byte[S (W - 1 - x, H - 1 - y)];
  1423.         }
  1424.     }
  1425.  
  1426.     /* shift it over */
  1427.     new = (unsigned char *)calloc((unsigned)W*H, (unsigned)1);
  1428.     for (y = 0; y < H; y++)    {
  1429.         for (x = 0; x < W*8; x++)    {
  1430.             bit = (*(dst + (x + (W*8 - width))/8 + y * W)
  1431.                 & (1 << ((x + (W*8 - width)) % 8))) ? 1 : 0;
  1432.             *(new + x/8 + y*W) = (bit << (x%8)) | 
  1433.                 (*(new + x/8 + y*W) & ~(1 << (x%8)));
  1434.         }
  1435.     }
  1436.     bcopy((char *)new, (char *)dst, W*H);
  1437.     free((char *)new);
  1438. }
  1439. #endif    /* !SMALL_CARDS */
  1440.