home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume15 / xhearts / part04 < prev    next >
Text File  |  1992-02-03  |  56KB  |  2,016 lines

  1. Newsgroups: comp.sources.x
  2. Path: uunet!usc!elroy.jpl.nasa.gov!ames!pasteur!nntp
  3. From: mikey@sgi.com (Mike Yang)
  4. Subject: v15i171: xhearts (w/ patch #1), Part04/06
  5. Message-ID: <1992Feb4.141941.9390@pasteur.Berkeley.EDU>
  6. Sender: dcmartin@msi.com (David C. Martin - Moderator)
  7. Nntp-Posting-Host: postgres.berkeley.edu
  8. Organization: University of California, at Berkeley
  9. References: <csx-15i168-xhearts@uunet.UU.NET>
  10. Date: Tue, 4 Feb 1992 14:19:41 GMT
  11. Approved: dcmartin@msi.com
  12.  
  13. Submitted-by: mikey@sgi.com (Mike Yang)
  14. Posting-number: Volume 15, Issue 171
  15. Archive-name: xhearts/part04
  16.  
  17. # This is a shell archive.  Remove anything before this line, then feed it
  18. # into a shell via "sh file" or similar.  To overwrite existing files,
  19. # type "sh file -c".
  20. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  21. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  22. # If this archive is complete, you will see the following message at the end:
  23. #        "End of archive 4 (of 6)."
  24. # Contents:  gfx.c hearts.c hearts_dist.c rank.bm
  25. # Wrapped by dcmartin@fascet on Wed Jan 15 06:30:34 1992
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'gfx.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'gfx.c'\"
  29. else
  30. echo shar: Extracting \"'gfx.c'\" \(32347 characters\)
  31. sed "s/^X//" >'gfx.c' <<'END_OF_FILE'
  32. X/*
  33. X *    Spider card bitmap drawing routines, modified for external use
  34. X *      by Mike Yang, Silicon Graphics, mikey@sgi.com.
  35. X *
  36. X */
  37. X
  38. X/*
  39. X * Copyright 1990 Heather Rose and Sun Microsystems, Inc.
  40. X *
  41. X * Permission to use, copy, modify, distribute, and sell this software and its
  42. X * documentation for any purpose is hereby granted without fee, provided that
  43. X * the above copyright notice appear in all copies and that both that copyright
  44. X * notice and this permission notice appear in supporting documentation, and
  45. X * that the names of Donald Woods and Sun Microsystems not be used in
  46. X * advertising or publicity pertaining to distribution of the software without
  47. X * specific, written prior permission.  Heather Rose and Sun Microsystems not be used in
  48. X * advertising or publicity pertaining to distribution of the software without
  49. X * specific, written prior permission.  Heather Rose and Sun Microsystems make
  50. X * no representations about the suitability of this software for any purpose.
  51. X * It is provided "as is" without express or implied warranty.
  52. X *
  53. X * THE ABOVE-NAMED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  54. X * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT
  55. X * SHALL HEATHER ROSE OR SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  56. X * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  57. X * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  58. X * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  59. X * OF THIS SOFTWARE.
  60. X *
  61. X * Author:
  62. X *        Heather Rose
  63. X *        hrose@sun.com
  64. X *
  65. X *        Sun Microsystems, Inc.
  66. X *        2550 Garcia Avenue
  67. X *        Mountain View, CA  94043
  68. X */
  69. X
  70. X/*
  71. X * Copyright 1990 David Lemke and Network Computing Devices
  72. X *
  73. X * Permission to use, copy, modify, distribute, and sell this software and its
  74. X * documentation for any purpose is hereby granted without fee, provided that
  75. X * the above copyright notice appear in all copies and that both that
  76. X * copyright notice and this permission notice appear in supporting
  77. X * documentation, and that the name of Network Computing Devices not be 
  78. X * used in advertising or publicity pertaining to distribution of the 
  79. X * software without specific, written prior permission.  Network Computing 
  80. X * Devices makes no representations about the suitability of this software 
  81. X * for any purpose.  It is provided "as is" without express or implied 
  82. X * warranty.
  83. X *
  84. X * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS 
  85. X * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  86. X * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL,
  87. X * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 
  88. X * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 
  89. X * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE 
  90. X * OR PERFORMANCE OF THIS SOFTWARE.
  91. X *
  92. X * Author:      
  93. X *        Dave Lemke
  94. X *        lemke@ncd.com
  95. X *
  96. X *        Network Computing Devices, Inc
  97. X *        350 North Bernardo Ave
  98. X *        Mountain View, CA 94043
  99. X *
  100. X *    @(#)copyright.h    2.2    90/04/27
  101. X *
  102. X */
  103. X
  104. X/*
  105. X% Copyright (c) 1989, Donald R. Woods and Sun Microsystems, Inc.
  106. X%
  107. X% Permission to use, copy, modify, distribute, and sell this software and its
  108. X% documentation for any purpose is hereby granted without fee, provided that
  109. X% the above copyright notice appear in all copies and that both that copyright
  110. X% notice and this permission notice appear in supporting documentation, and
  111. X% that the names of Donald Woods and Sun Microsystems not be used in
  112. X% advertising or publicity pertaining to distribution of the software without
  113. X% specific, written prior permission.  Donald Woods and Sun Microsystems make
  114. X% no representations about the suitability of this software for any purpose.
  115. X% It is provided "as is" without express or implied warranty.
  116. X%
  117. X% THE ABOVE-NAMED DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  118. X% INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT
  119. X% SHALL DONALD WOODS OR SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  120. X% CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  121. X% DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  122. X% TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  123. X% OF THIS SOFTWARE.
  124. X%
  125. X% History: Spider is a solitaire card game that can be found in various books
  126. X% of same; the rules are presumed to be in the public domain.  The author's
  127. X% first computer implementation was on the Stanford Artificial Intelligence Lab
  128. X% system (SAIL).  It was later ported to the Xerox Development Environment.
  129. X% The card images are loosely based on scanned-in images but were largely
  130. X% redrawn by the author with help from Larry Rosenberg.
  131. X%
  132. X% This program is written entirely in NeWS and runs on OPEN WINDOWS 1.0.
  133. X% It could be made to run much faster if parts of it were written in C, using
  134. X% NeWS mainly for its display and input capabilities, but that is left as an
  135. X% exercise for the reader.  Spider may also run with little or no modification
  136. X% on subsequent releases of OPEN WINDOWS, but no guarantee is made on this
  137. X% point (nor any other; see above!).  To run Spider, feed this file to 'psh'.
  138. X%
  139. X% Author:    Don Woods
  140. X%        woods@sun.com
  141. X%
  142. X%        Sun Microsystems, Inc.
  143. X%        2550 Garcia Avenue
  144. X%        Mountain View, CA  94043
  145. X*/
  146. X
  147. X/*
  148. X * Spider card drawing routines
  149. X */
  150. X#include    "gfx.h"
  151. X#include    <X11/Xutil.h>
  152. X#include    <stdio.h>
  153. X#include    <assert.h>
  154. X
  155. X/*
  156. X * spider global variables
  157. X */
  158. XDisplay    *dpy;
  159. Xint    screen;
  160. XPixmap    greenmap;
  161. XPixmap    redmap;
  162. XPixmap    logomap;
  163. Xunsigned long    blackpixel;
  164. Xunsigned long    whitepixel;
  165. Xunsigned long    borderpixel;
  166. Xunsigned long    greenpixel;
  167. XBool    is_color;
  168. X
  169. Xstatic GC    cardgc;        /* gc in use when drawing cards */
  170. X
  171. X/* substitue gray1 for Green on mono */
  172. X#define gray1_width 16
  173. X#define gray1_height 16
  174. Xstatic char gray1_bits[] = {
  175. X   0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
  176. X   0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa,
  177. X   0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa};
  178. X
  179. X/* logo for card backs */
  180. X/* any size logo can be handled.  */
  181. X
  182. X#define logo_width 64
  183. X#define logo_height 64
  184. Xstatic char logo_bits[] = {
  185. X 0x77,0xd5,0xd7,0xdd,0x77,0xd5,0xd7,0xdd,0xbb,0xea,0xae,0xbb,0xbb,0xea,0xae,
  186. X 0xbb,0x5d,0x75,0x5d,0x77,0x5d,0x75,0x5d,0x77,0xee,0xba,0xba,0xee,0xae,0xba,
  187. X 0xba,0xee,0x77,0x5d,0x75,0xdd,0x77,0x5d,0x75,0xdd,0xbb,0xae,0xea,0xba,0xbb,
  188. X 0xae,0xea,0xba,0x5d,0x57,0xd5,0x75,0x5d,0x57,0xd5,0x75,0xae,0xab,0xaa,0xeb,
  189. X 0xae,0xab,0xaa,0xeb,0xd7,0x55,0x55,0xd7,0xd7,0x51,0x55,0xd7,0xeb,0xae,0xaa,
  190. X 0xae,0xeb,0xa2,0xaa,0xae,0x75,0x5d,0x55,0x5d,0x75,0x44,0x15,0x5d,0xba,0xbb,
  191. X 0xea,0xba,0xba,0x88,0x8a,0xba,0x5d,0x77,0x75,0x75,0x1d,0x11,0x45,0x75,0xee,
  192. X 0xee,0xba,0xea,0x2e,0x22,0xa2,0xea,0xd7,0xdd,0x5d,0xd5,0x57,0x44,0x10,0xd5,
  193. X 0xab,0xbb,0xef,0xaa,0xab,0x88,0x88,0xaa,0x57,0x77,0x77,0xd5,0x57,0x11,0x45,
  194. X 0xd5,0xae,0xee,0xba,0xea,0xae,0x22,0xa2,0xea,0x5d,0xdd,0x5d,0x75,0x5d,0x45,
  195. X 0x10,0x75,0xba,0xba,0xef,0xba,0xba,0x8a,0x88,0xba,0x75,0x75,0x77,0x5d,0x75,
  196. X 0x15,0x45,0x5d,0xea,0xea,0xba,0xae,0xea,0x2a,0xa2,0xae,0xdd,0xd5,0x5d,0x77,
  197. X 0xdd,0x55,0x50,0x77,0xae,0xab,0xaf,0xeb,0xae,0xab,0xa8,0xeb,0xd7,0x55,0x57,
  198. X 0xd7,0xd7,0x55,0x55,0xd7,0xeb,0xaa,0xaa,0xae,0xeb,0xaa,0xaa,0xae,0x75,0x57,
  199. X 0x55,0x5d,0x75,0x57,0x55,0x5d,0xba,0xae,0xea,0xba,0xba,0xae,0xaa,0xba,0xdd,
  200. X 0x5d,0x75,0x75,0xdd,0x5d,0x75,0x75,0xae,0xbb,0xba,0xea,0xae,0xbb,0xba,0xea,
  201. X 0x77,0x77,0x5d,0xd5,0x77,0x77,0x5d,0xd5,0xeb,0xee,0xee,0xaa,0xeb,0xee,0xae,
  202. X 0xaa,0xd7,0xdd,0x77,0xd5,0xd7,0xdd,0x77,0xd5,0xae,0xbb,0xbb,0xea,0xae,0xbb,
  203. X 0xbb,0xea,0x5d,0x77,0x5d,0x75,0x5d,0x77,0x5d,0x75,0xba,0xee,0xee,0xba,0xba,
  204. X 0xee,0xae,0xba,0x75,0xdd,0x77,0x5d,0x75,0xdd,0x77,0x5d,0xea,0xba,0xbb,0xae,
  205. X 0xea,0xba,0xbb,0xae,0xd5,0x75,0x5d,0x57,0xd5,0x75,0x5d,0x57,0xaa,0xeb,0xae,
  206. X 0xab,0xaa,0xeb,0xae,0xab,0x55,0xd7,0xd7,0x55,0x55,0xd7,0xd7,0x55,0xaa,0xae,
  207. X 0xeb,0xae,0xaa,0xae,0xeb,0xae,0x55,0x5d,0x75,0x5d,0x55,0x5d,0x75,0x5d,0xea,
  208. X 0xba,0xba,0xbb,0xea,0xba,0xba,0xbb,0x75,0x75,0x5d,0x77,0x75,0x75,0x5d,0x77,
  209. X 0xba,0xea,0xee,0xee,0xba,0xea,0xee,0xee,0x5d,0xd5,0xd7,0xdd,0x5d,0xd5,0xd7,
  210. X 0xdd,0xef,0xaa,0xab,0xbb,0xef,0xaa,0xab,0xbb,0x77,0xd5,0x57,0x77,0x77,0xd5,
  211. X 0x57,0x77,0xba,0xea,0xae,0xee,0xba,0xea,0xae,0xee,0x5d,0x75,0x5d,0xdd,0x5d,
  212. X 0x75,0x5d,0xdd,0xef,0xba,0xba,0xba,0xef,0xba,0xba,0xba,0x77,0x5d,0x75,0x75,
  213. X 0x77,0x5d,0x75,0x75,0xba,0xae,0xea,0xea,0xba,0xae,0xea,0xea,0x5d,0x77,0xdd,
  214. X 0xd5,0x5d,0x77,0xdd,0xd5,0xaf,0xeb,0xae,0xab,0xaf,0xeb,0xae,0xab,0x57,0xd7,
  215. X 0xd7,0x55,0x57,0xd7,0xd7,0x55,0xaa,0xae,0xeb,0xaa,0xaa,0xae,0xeb,0xaa,0x55,
  216. X 0x5d,0x75,0x57,0x55,0x5d,0x75,0x57,0xaa,0xba,0xba,0xae,0xaa,0xba,0xba,0xae,
  217. X 0x75,0x75,0xdd,0x5d,0x55,0x75,0xdd,0x5d,0xba,0xea,0xae,0xbb,0xba,0xea,0xae,
  218. X 0xbb,0x5d,0xd5,0x77,0x77,0x5d,0xd5,0x77,0x77,0xae,0xaa,0xeb,0xee,0xae,0xaa,
  219. X 0xeb,0xee};
  220. X
  221. X#include    "rank.bm"
  222. X#include    "face.bm"
  223. X#include    "suit.bm"
  224. X
  225. Xstatic Pixmap    rank_map[NUM_RANKS],    rank_r_map[NUM_RANKS];
  226. Xstatic Pixmap    rank_map_red[NUM_RANKS],    rank_r_map_red[NUM_RANKS];
  227. Xstatic Pixmap    suit_map[NUM_SUITS],    suit_r_map[NUM_SUITS];
  228. Xstatic Pixmap    suit_sm_map[NUM_SUITS],    suit_sm_r_map[NUM_SUITS];
  229. Xstatic Pixmap    suit_lg_map[NUM_SUITS];
  230. Xstatic Pixmap    jack_map[NUM_SUITS], queen_map[NUM_SUITS], king_map[NUM_SUITS];
  231. X
  232. X/* clipping rectangles */
  233. Xstatic XRectangle    cliprects[1] = { 0, 0, CARD_WIDTH + 1, 0};
  234. X
  235. Xstatic GC    redgc;
  236. Xstatic GC    blackgc;
  237. Xstatic GC    whitegc;
  238. Xstatic GC    backgc;
  239. X
  240. Xstatic int    back_delta_x, back_delta_y; /* how much to modify the TS origin by */
  241. X
  242. Xstatic Bool    card_is_clipped;    /* optimizer for card drawing */
  243. X
  244. Xgfx_init(d, scr)
  245. XDisplay    *d;
  246. Xint    scr;
  247. X{
  248. XXGCValues    gcv;
  249. Xlong        gcflags;
  250. XXColor        color;
  251. XColormap    cmap;
  252. XPixmap        tmpmap;
  253. XGC        logogc;
  254. Xunsigned long    redpixel;
  255. X
  256. X    /* save these off */
  257. X    dpy = d;
  258. X    screen = scr;
  259. X
  260. X    if (DisplayCells(dpy, screen) > 2)    {
  261. X        is_color = True;
  262. X    }    else    {
  263. X        is_color = False;
  264. X    }
  265. X
  266. X    blackpixel = BlackPixel(dpy, screen);
  267. X    whitepixel = WhitePixel(dpy, screen);
  268. X
  269. X    /* make gc for white */
  270. X    gcv.foreground = WhitePixel(dpy, screen);
  271. X    gcv.background = BlackPixel(dpy, screen);
  272. X    gcv.graphics_exposures = False;
  273. X    gcflags = GCForeground | GCBackground | GCGraphicsExposures;
  274. X
  275. X    whitegc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
  276. X
  277. X    /* make gc for black */
  278. X    gcv.foreground = BlackPixel(dpy, screen);
  279. X    gcv.background = WhitePixel(dpy, screen);
  280. X    gcflags = GCForeground | GCBackground | GCGraphicsExposures;
  281. X
  282. X    blackgc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
  283. X
  284. X    tmpmap = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  285. X        logo_bits, logo_width, logo_height);
  286. X
  287. X    logomap = XCreatePixmap(dpy, RootWindow(dpy, screen), logo_width,
  288. X        logo_height, DefaultDepth(dpy, screen));
  289. X
  290. X    back_delta_x = (CARD_WIDTH - logo_width)/2;
  291. X    back_delta_y = (CARD_HEIGHT - logo_height)/2;
  292. X
  293. X    if (is_color)    {
  294. X        cmap = DefaultColormap(dpy, screen);
  295. X        XAllocNamedColor(dpy, cmap, "Sea Green", &color, &color);
  296. X        gcv.foreground = color.pixel;
  297. X        gcv.background = WhitePixel(dpy, screen);
  298. X        gcflags = GCForeground | GCBackground;
  299. X        logogc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
  300. X        XCopyPlane(dpy, tmpmap, logomap, logogc, 0, 0, 
  301. X            logo_width, logo_height, 0, 0, 1);
  302. X        XFreeGC(dpy, logogc);
  303. X    } else    {
  304. X        XCopyPlane(dpy, tmpmap, logomap, whitegc, 0, 0, 
  305. X            logo_width, logo_height, 0, 0, 1);
  306. X    }
  307. X    XFreePixmap(dpy, tmpmap);
  308. X
  309. X    gcv.tile = logomap;
  310. X    gcv.fill_style = FillTiled;
  311. X    gcflags |= GCTile | GCFillStyle | GCGraphicsExposures;
  312. X
  313. X    backgc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
  314. X
  315. X    borderpixel = blackpixel;
  316. X
  317. X    if (is_color)    {
  318. X        cmap = DefaultColormap(dpy, screen);
  319. X
  320. X        color.flags = DoRed | DoGreen | DoBlue;
  321. X
  322. X        /*
  323. X         * color levels are the NeWS RGB values
  324. X         */
  325. X        color.red = 13107;    /* 0.2 */
  326. X        color.green = 52428;    /* 0.8 */
  327. X        color.blue = 39321;    /* 0.6 */
  328. X        XAllocColor(dpy, cmap, &color);
  329. X        greenpixel = color.pixel;
  330. X
  331. X        color.red = 52428;    /* 0.8 */
  332. X        color.green = color.blue = 0;
  333. X        XAllocColor(dpy, cmap, &color);
  334. X        redpixel = color.pixel;
  335. X
  336. X        gcv.foreground = redpixel;
  337. X        gcv.background = WhitePixel(dpy, screen);
  338. X        gcflags = GCForeground | GCBackground | GCGraphicsExposures;
  339. X
  340. X        redgc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
  341. X
  342. X    } else    {
  343. X        greenmap = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  344. X            gray1_bits, gray1_width, gray1_height);
  345. X
  346. X        redmap = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  347. X            gray1_bits, gray1_width, gray1_height);
  348. X
  349. X        gcv.tile = redmap;
  350. X        gcv.fill_style = FillTiled;
  351. X
  352. X        gcv.foreground = BlackPixel(dpy, screen);
  353. X        gcv.background = WhitePixel(dpy, screen);
  354. X
  355. X        gcflags = GCTile | GCForeground | GCBackground |
  356. X            GCFillStyle | GCGraphicsExposures;
  357. X
  358. X        redgc = XCreateGC(dpy, RootWindow(dpy, screen), gcflags, &gcv);
  359. X    }
  360. X    make_card_maps();
  361. X}
  362. X
  363. X/*
  364. X * make a 'red' pixmap by setting the clipmask to the desired shape and 
  365. X * pushing 'red' through it
  366. X */
  367. X
  368. Xstatic Pixmap
  369. Xmake_red_map(bits, width, height)
  370. Xchar    *bits;
  371. Xint    width, height;
  372. X{
  373. XPixmap    tmpmap, newmap;
  374. Xstatic GC    cleargc = (GC) 0;
  375. XXGCValues    xgcv;
  376. X
  377. X
  378. X    if (cleargc == (GC) 0)    {
  379. X        xgcv.function = GXclear;
  380. X        cleargc = XCreateGC(dpy, RootWindow(dpy, screen), GCFunction, 
  381. X                                &xgcv);
  382. X    }
  383. X
  384. X    tmpmap = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  385. X        bits, width, height);
  386. X
  387. X    newmap = XCreatePixmap(dpy, RootWindow(dpy, screen), width, height, 1);
  388. X
  389. X    /* clear pixmap */
  390. X    XFillRectangle(dpy, newmap, cleargc, 0, 0, width, height);
  391. X
  392. X    XSetClipMask(dpy, redgc, tmpmap);
  393. X    XFillRectangle(dpy, newmap, redgc, 0, 0, width, height);
  394. X    XSetClipMask(dpy, redgc, None);
  395. X    XFreePixmap(dpy, tmpmap);
  396. X
  397. X    return (newmap);
  398. X}
  399. X
  400. Xmake_card_maps()
  401. X{
  402. Xunsigned char    *new_bits;
  403. XRank    r;
  404. Xint    i;
  405. X
  406. X    for (r = Ace; r <= King; r++)    {
  407. X        rank_map[(int)r] = XCreateBitmapFromData(dpy, 
  408. X            RootWindow(dpy, screen),
  409. X            rank_bits[(int)r], rank_width, rank_height);
  410. X
  411. X        new_bits = (unsigned char *) calloc(sizeof(rank_bits[(int)r]),
  412. X                            1);
  413. X        rot_180((unsigned char *)rank_bits[(int)r], new_bits, 
  414. X            rank_width, rank_height);
  415. X        rank_r_map[(int)r] = XCreateBitmapFromData(dpy, 
  416. X            RootWindow(dpy, screen),
  417. X            new_bits, rank_width, rank_height);
  418. X        free((char *)new_bits);
  419. X    }
  420. X
  421. X    for (r = Ace; r <= King; r++)    {
  422. X        new_bits = (unsigned char *) calloc(sizeof(rank_bits[(int)r]),
  423. X                            1);
  424. X        rot_180((unsigned char *)rank_bits[(int)r], new_bits, 
  425. X                rank_width, rank_height);
  426. X        if (is_color)    {
  427. X            rank_map_red[(int)r] = XCreateBitmapFromData(dpy, 
  428. X                RootWindow(dpy, screen),
  429. X                rank_bits[(int)r], rank_width, rank_height);
  430. X
  431. X            rank_r_map_red[(int)r] = XCreateBitmapFromData(dpy, 
  432. X                RootWindow(dpy, screen),
  433. X                new_bits, rank_width, rank_height);
  434. X        } else    {
  435. X            rank_map_red[(int)r] = make_red_map(rank_bits[(int)r],
  436. X                        rank_width, rank_height);
  437. X
  438. X            rank_r_map_red[(int)r] = make_red_map((char *)new_bits, 
  439. X                        rank_width, rank_height);
  440. X        }
  441. X        free((char *)new_bits);
  442. X    }
  443. X
  444. X    i = (int)Spade;
  445. X    /* make all the card bitmaps */
  446. X    suit_map[i] = XCreateBitmapFromData(dpy, 
  447. X        RootWindow(dpy, screen),
  448. X        spade_bits, spade_width, spade_height);
  449. X
  450. X    new_bits = (unsigned char *) calloc(sizeof(spade_bits), 1);
  451. X    flip_bits((unsigned char *)spade_bits, new_bits, spade_width, 
  452. X                spade_height);
  453. X    suit_r_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  454. X        new_bits, spade_width, spade_height);
  455. X    free((char *)new_bits);
  456. X
  457. X    suit_sm_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  458. X        spade_sm_bits, spade_sm_width, spade_sm_height);
  459. X
  460. X    new_bits = (unsigned char *) calloc(sizeof(spade_sm_bits), 1);
  461. X    flip_bits((unsigned char *)spade_sm_bits, new_bits, spade_sm_width,
  462. X            spade_sm_height);
  463. X    suit_sm_r_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  464. X        new_bits, spade_sm_width, spade_sm_height);
  465. X    free((char *)new_bits);
  466. X
  467. X    suit_lg_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  468. X        spade_lg_bits, spade_lg_width, spade_lg_height);
  469. X
  470. X    jack_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  471. X        jack_s_bits, jack_s_width, jack_s_height);
  472. X
  473. X    queen_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  474. X        queen_s_bits, queen_s_width, queen_s_height);
  475. X
  476. X    king_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  477. X        king_s_bits, king_s_width, king_s_height);
  478. X
  479. X    i = (int)Heart;
  480. X    /* make all the card bitmaps */
  481. X    new_bits = (unsigned char *) calloc(sizeof(heart_bits), 1);
  482. X    flip_bits((unsigned char *)heart_bits, new_bits, heart_width, 
  483. X                    heart_height);
  484. X
  485. X    if (is_color)    {
  486. X        suit_map[i] = XCreateBitmapFromData(dpy, 
  487. X            RootWindow(dpy, screen),
  488. X            heart_bits, heart_width, heart_height);
  489. X        suit_r_map[i] = XCreateBitmapFromData(dpy, 
  490. X            RootWindow(dpy, screen),
  491. X            new_bits, heart_width, heart_height);
  492. X    } else    {
  493. X        suit_map[i] = make_red_map(heart_bits, heart_width, 
  494. X                        heart_height);
  495. X        suit_r_map[i] = make_red_map((char *)new_bits, heart_width, 
  496. X                        heart_height);
  497. X    }
  498. X
  499. X    free((char *)new_bits);
  500. X
  501. X    new_bits = (unsigned char *) calloc(sizeof(heart_sm_bits), 1);
  502. X    flip_bits((unsigned char *)heart_sm_bits, new_bits, heart_sm_width, 
  503. X        heart_sm_height);
  504. X    suit_sm_r_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  505. X        new_bits, heart_sm_width, heart_sm_height);
  506. X
  507. X    if (is_color)    {
  508. X        suit_sm_map[i] = XCreateBitmapFromData(dpy, 
  509. X            RootWindow(dpy, screen),
  510. X            heart_sm_bits, heart_sm_width, heart_sm_height);
  511. X        suit_sm_r_map[i] = XCreateBitmapFromData(dpy, 
  512. X            RootWindow(dpy, screen),
  513. X            new_bits, heart_sm_width, heart_sm_height);
  514. X    } else    {
  515. X        suit_sm_map[i] = make_red_map(heart_sm_bits, heart_sm_width, 
  516. X                        heart_height);
  517. X        suit_sm_r_map[i] = make_red_map((char *)new_bits, 
  518. X            heart_sm_width, heart_sm_height);
  519. X    }
  520. X    free((char *)new_bits);
  521. X
  522. X    suit_lg_map[i] = suit_map[i];
  523. X
  524. X    if (is_color)    {
  525. X        jack_map[i] = XCreateBitmapFromData(dpy, 
  526. X            RootWindow(dpy, screen),
  527. X            jack_h_bits, jack_h_width, jack_h_height);
  528. X
  529. X        queen_map[i] = XCreateBitmapFromData(dpy, 
  530. X            RootWindow(dpy, screen),
  531. X            queen_h_bits, queen_h_width, queen_h_height);
  532. X
  533. X        king_map[i] = XCreateBitmapFromData(dpy, 
  534. X            RootWindow(dpy, screen),
  535. X            king_h_bits, king_h_width, king_h_height);
  536. X    } else    {
  537. X        jack_map[i] = make_red_map(jack_h_bits, jack_h_width, 
  538. X                            jack_h_height);
  539. X
  540. X        queen_map[i] = make_red_map(queen_h_bits, queen_h_width, 
  541. X                            queen_h_height);
  542. X
  543. X        king_map[i] = make_red_map(king_h_bits, king_h_width, 
  544. X                            king_h_height);
  545. X    }
  546. X
  547. X
  548. X    i = (int)Diamond;
  549. X    /* make all the card bitmaps */
  550. X    new_bits = (unsigned char *) calloc(sizeof(diamond_bits), 1);
  551. X    flip_bits((unsigned char *)diamond_bits, new_bits, diamond_width, 
  552. X        diamond_height);
  553. X
  554. X    if (is_color)    {
  555. X        suit_map[i] = XCreateBitmapFromData(dpy, 
  556. X            RootWindow(dpy, screen),
  557. X            diamond_bits, diamond_width, diamond_height);
  558. X        suit_r_map[i] = XCreateBitmapFromData(dpy, 
  559. X            RootWindow(dpy, screen),
  560. X            new_bits, diamond_width, diamond_height);
  561. X    } else    {
  562. X        suit_map[i] = make_red_map(diamond_bits, diamond_width, 
  563. X                        diamond_height);
  564. X        suit_r_map[i] = make_red_map((char *)new_bits, diamond_width, 
  565. X                        diamond_height);
  566. X    }
  567. X
  568. X    free((char *)new_bits);
  569. X
  570. X    new_bits = (unsigned char *) calloc(sizeof(diamond_sm_bits), 1);
  571. X    flip_bits((unsigned char *)diamond_sm_bits, new_bits, 
  572. X                diamond_sm_width, diamond_sm_height);
  573. X    suit_sm_r_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  574. X        new_bits, diamond_sm_width, diamond_sm_height);
  575. X
  576. X    if (is_color)    {
  577. X        suit_sm_map[i] = XCreateBitmapFromData(dpy, 
  578. X            RootWindow(dpy, screen),
  579. X            diamond_sm_bits, diamond_sm_width, diamond_sm_height);
  580. X        suit_sm_r_map[i] = XCreateBitmapFromData(dpy, 
  581. X            RootWindow(dpy, screen),
  582. X            new_bits, diamond_sm_width, diamond_sm_height);
  583. X    } else    {
  584. X        suit_sm_map[i] = make_red_map(diamond_sm_bits, diamond_sm_width, 
  585. X                        diamond_height);
  586. X        suit_sm_r_map[i] = make_red_map((char *)new_bits, 
  587. X                diamond_sm_width, diamond_sm_height);
  588. X    }
  589. X    free((char *)new_bits);
  590. X
  591. X    suit_lg_map[i] = suit_map[i];
  592. X
  593. X    if (is_color)    {
  594. X        jack_map[i] = XCreateBitmapFromData(dpy, 
  595. X            RootWindow(dpy, screen),
  596. X            jack_d_bits, jack_d_width, jack_d_height);
  597. X
  598. X        queen_map[i] = XCreateBitmapFromData(dpy, 
  599. X            RootWindow(dpy, screen),
  600. X            queen_d_bits, queen_d_width, queen_d_height);
  601. X
  602. X        king_map[i] = XCreateBitmapFromData(dpy, 
  603. X            RootWindow(dpy, screen),
  604. X            king_d_bits, king_d_width, king_d_height);
  605. X    } else    {
  606. X        jack_map[i] = make_red_map(jack_d_bits, jack_d_width, 
  607. X                            jack_d_height);
  608. X
  609. X        queen_map[i] = make_red_map(queen_d_bits, queen_d_width, 
  610. X                            queen_d_height);
  611. X
  612. X        king_map[i] = make_red_map(king_d_bits, king_d_width, 
  613. X                            king_d_height);
  614. X    }
  615. X
  616. X    i = (int)Club;
  617. X    /* make all the card bitmaps */
  618. X    suit_map[i] = XCreateBitmapFromData(dpy, 
  619. X        RootWindow(dpy, screen),
  620. X        club_bits, club_width, club_height);
  621. X
  622. X    new_bits = (unsigned char *) calloc(sizeof(club_bits), 1);
  623. X    flip_bits((unsigned char *)club_bits, new_bits, club_width, 
  624. X        club_height);
  625. X    suit_r_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  626. X        new_bits, club_width, club_height);
  627. X    free((char *)new_bits);
  628. X
  629. X    suit_sm_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  630. X        club_sm_bits, club_sm_width, club_sm_height);
  631. X
  632. X    new_bits = (unsigned char *) calloc(sizeof(club_sm_bits), 1);
  633. X    flip_bits((unsigned char *)club_sm_bits, new_bits, club_sm_width, 
  634. X        club_sm_height);
  635. X    suit_sm_r_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  636. X        new_bits, club_sm_width, club_sm_height);
  637. X    free((char *)new_bits);
  638. X
  639. X    suit_lg_map[i] = suit_map[i];
  640. X
  641. X
  642. X    jack_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  643. X        jack_c_bits, jack_c_width, jack_c_height);
  644. X
  645. X    queen_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  646. X        queen_c_bits, queen_c_width, queen_c_height);
  647. X
  648. X    king_map[i] = XCreateBitmapFromData(dpy, RootWindow(dpy, screen),
  649. X        king_c_bits, king_c_width, king_c_height);
  650. X}
  651. X
  652. Xstatic unsigned char _reverse_byte[0x100] = {
  653. X    0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
  654. X    0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
  655. X    0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
  656. X    0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
  657. X    0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
  658. X    0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
  659. X    0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
  660. X    0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
  661. X    0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
  662. X    0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
  663. X    0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
  664. X    0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
  665. X    0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
  666. X    0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
  667. X    0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
  668. X    0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
  669. X    0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
  670. X    0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
  671. X    0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
  672. X    0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
  673. X    0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
  674. X    0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
  675. X    0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
  676. X    0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
  677. X    0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
  678. X    0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
  679. X    0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
  680. X    0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
  681. X    0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
  682. X    0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
  683. X    0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
  684. X    0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
  685. X};
  686. X
  687. X#define S(x,y) src[(H-1-(y))*W+(x)]
  688. X#define D(x,y) dst[(H-1-(y))*W+(x)]
  689. X
  690. Xflip_bits(src, dst, W, H)
  691. Xunsigned char    *src, *dst;
  692. Xint    W, H;
  693. X{
  694. Xint    x, y;
  695. X
  696. X    W = (W + 7)/8;
  697. X    for (y = 0; y < H; y++)    {
  698. X        for (x = 0; x < W; x++)    {
  699. X            D (x, y) = S (x, H - 1 - y);
  700. X        }
  701. X    }
  702. X}
  703. X
  704. Xrot_180(src, dst, W, H)
  705. Xunsigned char   *src, *dst;
  706. Xint    W, H;
  707. X{
  708. Xint     x, y;
  709. Xint    width = W;
  710. Xunsigned char    *new;
  711. Xint    bit;
  712. X
  713. X    W = (W + 7)/8;
  714. X    for (y = 0; y < H; y++) {
  715. X        for (x = 0; x < W; x++) {
  716. X            D (x, y) = _reverse_byte[S (W - 1 - x, H - 1 - y)];
  717. X        }
  718. X    }
  719. X
  720. X    /* shift it over */
  721. X    new = (unsigned char *)calloc((unsigned)W*H, (unsigned)1);
  722. X    for (y = 0; y < H; y++)    {
  723. X        for (x = 0; x < W*8; x++)    {
  724. X            bit = (*(dst + (x + (W*8 - width))/8 + y * W)
  725. X                & (1 << ((x + (W*8 - width)) % 8))) ? 1 : 0;
  726. X            *(new + x/8 + y*W) = (bit << (x%8)) | 
  727. X                (*(new + x/8 + y*W) & ~(1 << (x%8)));
  728. X        }
  729. X    }
  730. X    bcopy((char *)new, (char *)dst, W*H);
  731. X    free((char *)new);
  732. X}
  733. X
  734. X/*
  735. X * delta is 0 if the card is fully showing
  736. X */
  737. Xpaint_card(table, x, y, rank, suit, delta)
  738. XWindow    table;
  739. Xint    x,y;
  740. XRank    rank;
  741. XSuit    suit;
  742. Xint    delta;
  743. X{
  744. X    if (suit == Spade || suit == Club)    {
  745. X        cardgc = blackgc;
  746. X    } else    {
  747. X        cardgc = redgc;
  748. X    }
  749. X
  750. X    if (delta)    {
  751. X            cliprects[0].height = delta;
  752. X        XSetClipRectangles(dpy, cardgc, x, y, cliprects, 1, Unsorted);
  753. X        {
  754. X            /* fill the background */
  755. X            XFillRectangle(dpy, table, whitegc, x, y, 
  756. X                    CARD_WIDTH, delta);
  757. X            /* draw border on card */
  758. X            XDrawRectangle(dpy, table, blackgc, x, y, 
  759. X                    CARD_WIDTH, delta);
  760. X        }
  761. X        card_is_clipped = True;
  762. X    } else    {    /* fill all the card */
  763. X        {
  764. X            /* fill the background */
  765. X            XFillRectangle(dpy, table, whitegc, x, y, 
  766. X            CARD_WIDTH, CARD_HEIGHT);
  767. X            /* draw border on card */
  768. X            XDrawRectangle(dpy, table, blackgc, x, y, 
  769. X            CARD_WIDTH, CARD_HEIGHT);
  770. X        }
  771. X        card_is_clipped = False;
  772. X    }
  773. X
  774. X    switch (rank)    {
  775. X    case    King:
  776. X        draw_king(table, suit, x, y);
  777. X        break;
  778. X    case    Queen:
  779. X        draw_queen(table, suit, x, y);
  780. X        break;
  781. X    case    Jack:
  782. X        draw_jack(table, suit, x, y);
  783. X        break;
  784. X
  785. X    case    Ten:
  786. X        draw_pip(table, suit, MID_CARD_X + x, CARD_TEN_Y1 + y);
  787. X        draw_did(table, suit, MID_CARD_X + x, CARD_TEN_Y2 + y);
  788. X        draw_eight_pips(table, suit, x, y);
  789. X        break;
  790. X
  791. X    case    Nine:
  792. X        draw_pip(table, suit, x + MID_CARD_X, y + MID_CARD_Y);
  793. X        draw_eight_pips(table, suit, x, y);
  794. X        break;
  795. X
  796. X    case    Eight:
  797. X        draw_did(table, suit, x + MID_CARD_X, y + CARD_EIGHT_Y);
  798. X        /* fall thru */
  799. X    case    Seven:
  800. X        draw_pip(table, suit, MID_CARD_X + x, CARD_SEVEN_Y + y);
  801. X        /* fall thru */
  802. X    case    Six:
  803. X        draw_six_pips(table, suit, x, y);
  804. X        break;
  805. X
  806. X    case    Five:
  807. X        draw_pip(table, suit, x + MID_CARD_X, y + MID_CARD_Y);
  808. X        /* fall thru */
  809. X    case    Four:
  810. X        draw_four_pips(table, suit, x, y);
  811. X        break;
  812. X
  813. X    case    Three:
  814. X        draw_pip(table, suit, x + MID_CARD_X, y + MID_CARD_Y);
  815. X        /* fall thru */
  816. X    case    Deuce:
  817. X        draw_two_pips(table, suit, x, y);
  818. X        break;
  819. X    case    Ace:
  820. X        draw_center_pip(table, suit, x + MID_CARD_X, y + MID_CARD_Y);
  821. X        break;
  822. X    default:
  823. X        assert(0);
  824. X    }
  825. X
  826. X    draw_rank(table, x, y, rank, suit);
  827. X
  828. X    /* clear the clip mask */
  829. X    XSetClipMask(dpy, cardgc, None);
  830. X}
  831. X
  832. X/*
  833. X * NOTE -- for all the pip drawers except the one that actually plots the
  834. X * bits, the location is the card's location.  the drawer's take the
  835. X * pip's center as location.
  836. X */
  837. X
  838. X/*
  839. X * draws right-side-up pip
  840. X *
  841. X * location is for center of pip
  842. X */
  843. Xdraw_pip(table, suit, x, y)
  844. XWindow    table;
  845. XSuit    suit;
  846. Xint    x, y;
  847. X{
  848. Xint    w, h;
  849. X
  850. X    switch(suit)    {
  851. X    case    Spade:
  852. X        w = spade_width;
  853. X        h = spade_height;
  854. X        break;
  855. X    case    Diamond:
  856. X        x++;
  857. X        w = diamond_width;
  858. X        h = diamond_height;
  859. X        break;
  860. X    case    Heart:
  861. X        y++;
  862. X        w = heart_width;
  863. X        h = heart_height;
  864. X        break;
  865. X    case    Club:
  866. X        y++;
  867. X        w = club_width;
  868. X        h = club_height;
  869. X        break;
  870. X    default:
  871. X        assert(0);
  872. X    }
  873. X    XCopyPlane(dpy, suit_map[suit], table, cardgc, 
  874. X        0, 0, w, h,
  875. X        x - w/2, y - h/2, 1);
  876. X}
  877. X
  878. X/*
  879. X * draws upside-down pip
  880. X *
  881. X * location is for center of pip
  882. X */
  883. Xdraw_did(table, suit, x, y)
  884. XWindow    table;
  885. XSuit    suit;
  886. Xint    x,y;
  887. X{
  888. Xint    w, h;
  889. X
  890. X    if (card_is_clipped)    /* a clipped card never shows any did's */
  891. X        return;
  892. X
  893. X    switch(suit)    {
  894. X    case    Spade:
  895. X        w = spade_width;
  896. X        h = spade_height;
  897. X        break;
  898. X    case    Diamond:
  899. X        x++;
  900. X        w = diamond_width;
  901. X        h = diamond_height;
  902. X        break;
  903. X    case    Heart:
  904. X        y++;
  905. X        w = heart_width;
  906. X        h = heart_height;
  907. X        break;
  908. X    case    Club:
  909. X        y++;
  910. X        w = club_width;
  911. X        h = club_height;
  912. X        break;
  913. X    default:
  914. X        assert(0);
  915. X    }
  916. X    XCopyPlane(dpy, suit_r_map[suit], table, cardgc, 
  917. X        0, 0, w, h,
  918. X        x - w/2, y - h/2, 1);
  919. X}
  920. X
  921. X/*
  922. X * draws big center pip
  923. X */
  924. Xdraw_center_pip(table, suit, x, y)
  925. XWindow    table;
  926. XSuit    suit;
  927. Xint    x,y;
  928. X{
  929. Xint    w, h;
  930. X
  931. X    if (card_is_clipped)
  932. X        return;
  933. X
  934. X    switch(suit)    {
  935. X    case    Spade:
  936. X        w = spade_lg_width;
  937. X        h = spade_lg_height;
  938. X        break;
  939. X    case    Diamond:
  940. X        w = diamond_width;
  941. X        h = diamond_height;
  942. X        break;
  943. X    case    Heart:
  944. X        w = heart_width;
  945. X        h = heart_height;
  946. X        break;
  947. X    case    Club:
  948. X        w = club_width;
  949. X        h = club_height;
  950. X        break;
  951. X    default:
  952. X        assert(0);
  953. X    }
  954. X    XCopyPlane(dpy, suit_lg_map[suit], table, cardgc, 
  955. X        0, 0, w, h,
  956. X        x - w/2, y - h/2, 1);
  957. X}
  958. X
  959. X/* 
  960. X * draw_two_pips
  961. X */
  962. Xdraw_two_pips(table, suit, x, y)
  963. XWindow    table;
  964. XSuit    suit;
  965. Xint    x,y;
  966. X{
  967. X    draw_pip(table, suit, x + MID_CARD_X, y + CARD_ROW1_Y);
  968. X    draw_did(table, suit, x + MID_CARD_X, y + CARD_ROW5_Y);
  969. X}
  970. X
  971. X/*
  972. X * draw_four_pips
  973. X */
  974. Xdraw_four_pips(table, suit, x, y)
  975. XWindow    table;
  976. XSuit    suit;
  977. Xint    x,y;
  978. X{
  979. X    draw_pip(table, suit, x + CARD_COL1_X, y + CARD_ROW1_Y);
  980. X    draw_did(table, suit, x + CARD_COL1_X, y + CARD_ROW5_Y);
  981. X
  982. X    draw_pip(table, suit, x + CARD_COL3_X, y + CARD_ROW1_Y);
  983. X    draw_did(table, suit, x + CARD_COL3_X, y + CARD_ROW5_Y);
  984. X}
  985. X
  986. Xdraw_six_pips(table, suit, x, y)
  987. XWindow    table;
  988. XSuit    suit;
  989. Xint    x, y;
  990. X{
  991. X    draw_pip(table, suit, x + CARD_COL1_X, y + CARD_ROW1_Y);
  992. X
  993. X    draw_pip(table, suit, x + CARD_COL3_X, y + CARD_ROW1_Y);
  994. X
  995. X    if (card_is_clipped)
  996. X        return;
  997. X
  998. X    /* these are only visible when its not clipped */
  999. X    draw_pip(table, suit, x + CARD_COL1_X, y + CARD_ROW3_Y);
  1000. X    draw_did(table, suit, x + CARD_COL1_X, y + CARD_ROW5_Y);
  1001. X
  1002. X    draw_pip(table, suit, x + CARD_COL3_X, y + CARD_ROW3_Y);
  1003. X    draw_did(table, suit, x + CARD_COL3_X, y + CARD_ROW5_Y);
  1004. X}
  1005. X
  1006. Xdraw_eight_pips(table, suit, x, y)
  1007. XWindow    table;
  1008. XSuit    suit;
  1009. Xint    x,y;
  1010. X{
  1011. X    draw_pip(table, suit, x + CARD_COL1_X, y + CARD_ROW1_Y);
  1012. X
  1013. X    draw_pip(table, suit, x + CARD_COL3_X, y + CARD_ROW1_Y);
  1014. X
  1015. X    if (card_is_clipped)
  1016. X        return;
  1017. X
  1018. X    /* these are only visible when its not clipped */
  1019. X    draw_pip(table, suit, x + CARD_COL1_X, y + CARD_ROW2_Y);
  1020. X    draw_did(table, suit, x + CARD_COL1_X, y + CARD_ROW4_Y);
  1021. X    draw_did(table, suit, x + CARD_COL1_X, y + CARD_ROW5_Y);
  1022. X
  1023. X    draw_pip(table, suit, x + CARD_COL3_X, y + CARD_ROW2_Y);
  1024. X    draw_did(table, suit, x + CARD_COL3_X, y + CARD_ROW4_Y);
  1025. X    draw_did(table, suit, x + CARD_COL3_X, y + CARD_ROW5_Y);
  1026. X}
  1027. X
  1028. Xdraw_jack(table, suit, x, y)
  1029. XWindow    table;
  1030. XSuit    suit;
  1031. Xint    x,y;
  1032. X{
  1033. X    XCopyPlane(dpy, jack_map[suit], table, cardgc, 
  1034. X        0, 0, FACECARD_WIDTH, FACECARD_HEIGHT,
  1035. X        x + (CARD_WIDTH - FACECARD_WIDTH)/2, 
  1036. X        y + (CARD_HEIGHT - FACECARD_HEIGHT)/2, 1);
  1037. X
  1038. X    XDrawRectangle(dpy, table, cardgc,
  1039. X        x + (CARD_WIDTH - FACECARD_WIDTH)/2, 
  1040. X        y + (CARD_HEIGHT - FACECARD_HEIGHT)/2,
  1041. X        FACECARD_WIDTH, FACECARD_HEIGHT);
  1042. X}
  1043. X
  1044. Xdraw_queen(table, suit, x, y)
  1045. XWindow    table;
  1046. XSuit    suit;
  1047. Xint    x,y;
  1048. X{
  1049. X    XCopyPlane(dpy, queen_map[suit], table, cardgc,
  1050. X        0, 0, FACECARD_WIDTH, FACECARD_HEIGHT,
  1051. X        x + (CARD_WIDTH - FACECARD_WIDTH)/2, 
  1052. X        y + (CARD_HEIGHT - FACECARD_HEIGHT)/2, 1);
  1053. X
  1054. X    XDrawRectangle(dpy, table, cardgc,
  1055. X        x + (CARD_WIDTH - FACECARD_WIDTH)/2, 
  1056. X        y + (CARD_HEIGHT - FACECARD_HEIGHT)/2,
  1057. X        FACECARD_WIDTH, FACECARD_HEIGHT);
  1058. X}
  1059. X
  1060. Xdraw_king(table, suit, x, y)
  1061. XWindow    table;
  1062. XSuit    suit;
  1063. Xint    x,y;
  1064. X{
  1065. X    XCopyPlane(dpy, king_map[suit], table, cardgc,
  1066. X        0, 0, FACECARD_WIDTH, FACECARD_HEIGHT,
  1067. X        x + (CARD_WIDTH - FACECARD_WIDTH)/2, 
  1068. X        y + (CARD_HEIGHT - FACECARD_HEIGHT)/2, 1);
  1069. X
  1070. X    XDrawRectangle(dpy, table, cardgc,
  1071. X        x + (CARD_WIDTH - FACECARD_WIDTH)/2, 
  1072. X        y + (CARD_HEIGHT - FACECARD_HEIGHT)/2,
  1073. X        FACECARD_WIDTH, FACECARD_HEIGHT);
  1074. X}
  1075. X
  1076. Xdraw_rank(table, x, y, rank, suit)
  1077. XWindow    table;
  1078. Xint    x, y;
  1079. XRank    rank;
  1080. XSuit    suit;
  1081. X{
  1082. Xint    w, h;
  1083. X
  1084. X    if (suit == Heart || suit == Diamond)    {
  1085. X        XCopyPlane(dpy, rank_map_red[rank], table, cardgc,
  1086. X            0, 0, RANK_WIDTH, RANK_HEIGHT,
  1087. X            x + RANK_LOC_X, y + RANK_LOC_Y, 1);
  1088. X
  1089. X        if (!card_is_clipped)
  1090. X            XCopyPlane(dpy, rank_r_map_red[rank], table, cardgc,
  1091. X            0, 0, RANK_WIDTH, RANK_HEIGHT,
  1092. X            x + (CARD_WIDTH - RANK_WIDTH - RANK_LOC_X), 
  1093. X            y + (CARD_HEIGHT - RANK_HEIGHT - RANK_LOC_Y), 1);
  1094. X    } else    {
  1095. X        XCopyPlane(dpy, rank_map[rank], table, cardgc,
  1096. X            0, 0, RANK_WIDTH, RANK_HEIGHT,
  1097. X            x + RANK_LOC_X, y + RANK_LOC_Y, 1);
  1098. X
  1099. X        if (!card_is_clipped)
  1100. X            XCopyPlane(dpy, rank_r_map[rank], table, cardgc,
  1101. X            0, 0, RANK_WIDTH, RANK_HEIGHT,
  1102. X            x + (CARD_WIDTH - RANK_WIDTH - RANK_LOC_X), 
  1103. X            y + (CARD_HEIGHT - RANK_HEIGHT - RANK_LOC_Y), 1);
  1104. X    }
  1105. X
  1106. X    switch (suit)    {
  1107. X        case    Spade:
  1108. X            w = spade_sm_width;
  1109. X            h = spade_sm_height;
  1110. X            break;
  1111. X        case    Heart:
  1112. X            w = heart_sm_width;
  1113. X            h = heart_sm_height;
  1114. X            break;
  1115. X        case    Diamond:
  1116. X            x++;    /* offset the smaller width */
  1117. X            w = diamond_sm_width;
  1118. X            h = diamond_sm_height;
  1119. X            break;
  1120. X        case    Club:
  1121. X            w = club_sm_width;
  1122. X            h = club_sm_height;
  1123. X            break;
  1124. X        default:
  1125. X            assert(0);
  1126. X    }
  1127. X    XCopyPlane(dpy, suit_sm_map[suit], table, cardgc,
  1128. X        0, 0, w, h,
  1129. X        x + SMALL_LOC_X, y + SMALL_LOC_Y, 1);
  1130. X
  1131. X    if (!card_is_clipped)
  1132. X        XCopyPlane(dpy, suit_sm_r_map[suit], table, cardgc,
  1133. X        0, 0, w, h,
  1134. X        x + (CARD_WIDTH - w - SMALL_LOC_X), 
  1135. X        y + (CARD_HEIGHT - h - SMALL_LOC_Y), 1);
  1136. X}
  1137. END_OF_FILE
  1138. if test 32347 -ne `wc -c <'gfx.c'`; then
  1139.     echo shar: \"'gfx.c'\" unpacked with wrong size!
  1140. fi
  1141. # end of 'gfx.c'
  1142. fi
  1143. if test -f 'hearts.c' -a "${1}" != "-c" ; then 
  1144.   echo shar: Will not clobber existing file \"'hearts.c'\"
  1145. else
  1146. echo shar: Extracting \"'hearts.c'\" \(6065 characters\)
  1147. sed "s/^X//" >'hearts.c' <<'END_OF_FILE'
  1148. X/*
  1149. X * hearts - human interface to hearts program
  1150. X *
  1151. X * All smarts are in heartsd, which is invoked by initial caller of hearts.
  1152. X *
  1153. X * Private messages, last-play, auto-play added by:
  1154. X *    Mike Yang of UC Berkeley (mikey@ernie.berkeley.edu)
  1155. X *
  1156. X * By Bob Ankeney or Generic Computer Products
  1157. X * Bug reports to:
  1158. X * ...!tektronix!reed!bob
  1159. X *
  1160. X *
  1161. X * Commands to hearts client (r = rank, s = suit):
  1162. X *
  1163. X * Ars        Add card to hand.
  1164. X * Rrs        Remove card from hand.
  1165. X * En        Erase window n.
  1166. X * G        Get a card.
  1167. X * Pnrs<name>    Play card from player n, whose name is <name>.
  1168. X * Snpptt<name>    Score points (pp) and total points (tt) for player n.
  1169. X * Mn<text>    Message <text> is placed in window n.
  1170. X * X        Go away.
  1171. X * Z        Game over, socket closing.
  1172. X *
  1173. X * Messages from client:
  1174. X *
  1175. X * Prs        Pass/Play card from hand.
  1176. X * M<text>        Send message <text> to all players.
  1177. X *
  1178. X */
  1179. X
  1180. X#include <sys/errno.h>
  1181. X#include "misc.h"
  1182. X#include "defs.h"
  1183. X#include "local.h"
  1184. X#include "client.h"
  1185. X#ifdef SYSV
  1186. X#include <sys/termio.h>
  1187. X#endif
  1188. X
  1189. Xint    dist_socket, dealer_socket;
  1190. Xchar    game_over, first_game;
  1191. Xchar    host[256];
  1192. X
  1193. Xchar    *snames[] = {
  1194. X        "",
  1195. X        "clubs",
  1196. X        "diamonds",
  1197. X        "hearts",
  1198. X        "spades"
  1199. X    },
  1200. X    rnames[] = " 23456789TJQKA";
  1201. X
  1202. Xget_going()
  1203. X{
  1204. X    int    dealer_port;
  1205. X    char    *name, *getenv();
  1206. X    /*
  1207. X     * Connect to distributor.  If not available, start it.
  1208. X     */
  1209. X    if ((dist_socket = connect_to(host, PORT)) == 0) {
  1210. X        start_distributor();
  1211. X        if ((dist_socket = connect_to(host, PORT)) == 0)
  1212. X            death("Can't invoke distributor!");
  1213. X    }
  1214. X    /*
  1215. X     * Get dealer port and connect to it.
  1216. X     * If port returned == 0, restart game with old dealer.
  1217. X     */
  1218. X    if (dealer_port = select_game()) {
  1219. X        if (!first_game) {
  1220. X                (void) close(dealer_socket);
  1221. X            close_socket(dealer_socket);
  1222. X        }
  1223. X        if ((dealer_socket = connect_to(host, dealer_port)) == 0)
  1224. X            death("Can't connect to dealer!\n");
  1225. X        if ((name = getenv("HEARTS")) == NULL)    /* get user name */
  1226. X            if ((name = getenv("NAME")) == NULL)
  1227. X                name = getenv("USER");
  1228. X        init_socket();
  1229. X        write_socket(dealer_socket, name);    /* tell dealer */
  1230. X    }
  1231. X    start_game();
  1232. X}
  1233. X
  1234. Xdo_command(buf)
  1235. Xchar    *buf;
  1236. X{
  1237. X    char    rch, sch;
  1238. X    int    player, suit, pts, total_pts, window_num;
  1239. X
  1240. X    switch (buf[0]) {
  1241. X    case 'A' :        /* Add card to hand */
  1242. X            enter_card(get_rank(buf[1]), get_suit(buf[2]));
  1243. X        break;
  1244. X
  1245. X    case 'R' :        /* Remove card from hand */
  1246. X            remove_card(get_rank(buf[1]), get_suit(buf[2]));
  1247. X        break;
  1248. X
  1249. X    case 'E' :        /* Erase window */
  1250. X            erase_window(buf[1] - '0');
  1251. X        break;
  1252. X
  1253. X    case 'G' :        /* Get card */
  1254. X        read_card();
  1255. X        break;
  1256. X
  1257. X    case 'P' :        /* Play card from player */
  1258. X        (void) sscanf(buf+1, "%1d %c %c", &player, &rch, &sch);
  1259. X        play_card(player, rch, sch, buf+4);
  1260. X        break;
  1261. X
  1262. X    case 'S' :        /* Score points for player */
  1263. X        (void) sscanf(buf+1, "%1d %3d %3d", &player, &pts, &total_pts);
  1264. X        score_points(player, pts, total_pts, buf+8);
  1265. X        break;
  1266. X
  1267. X    case 'M' :        /* Print message in window */
  1268. X            display_message(buf[1] - '0', buf+2);
  1269. X        break;
  1270. X
  1271. X    case 'X' :        /* Game over */
  1272. X            game_is_over();
  1273. X        game_over = TRUE;
  1274. X        first_game = FALSE;
  1275. X        break;
  1276. X
  1277. X    case 'Z' :        /* Game over, socket closing */
  1278. X            game_is_over();
  1279. X        game_over = TRUE;
  1280. X            first_game = TRUE;
  1281. X        (void) close(dealer_socket);
  1282. X        close_socket(dealer_socket);
  1283. X    }
  1284. X}
  1285. X
  1286. X/*
  1287. X * Filter out nasties from message in buffer
  1288. X */
  1289. X
  1290. Xmikey_strcmp(s,t)
  1291. Xchar s[], t[];
  1292. X{
  1293. X  int i;
  1294. X
  1295. X  i = 0;
  1296. X  while ((s[i] == t[i]) || (s[i] >= 'A' && s[i] <= 'Z' &&
  1297. X                (s[i] - 'A' + 'a') == t[i]))
  1298. X    if (t[i++] == '\0')
  1299. X      return(TRUE);
  1300. X  return((t[i] == '\0'));
  1301. X}
  1302. X
  1303. Xblock(buf, what)
  1304. Xchar *buf, *what;
  1305. X{
  1306. X  int i;
  1307. X
  1308. X  for (i=0;i<=strlen(what);i++)
  1309. X    *buf++ = *what++;
  1310. X}
  1311. X
  1312. Xmikey_filter(buf)
  1313. Xchar *buf;
  1314. X{
  1315. X  int i;
  1316. X
  1317. X  for (i=1;i<strlen(buf);i++) {
  1318. X    if (mikey_strcmp(buf+i,"asshole"))
  1319. X      block(buf+i,"a--hole");
  1320. X    if (mikey_strcmp(buf+i,"tit"))
  1321. X      block(buf+i,"t-t");
  1322. X    if (mikey_strcmp(buf+i,"shit"))
  1323. X      block(buf+i,"s--t");
  1324. X    if (mikey_strcmp(buf+i,"damn"))
  1325. X      block(buf+i,"d--n");
  1326. X    if (mikey_strcmp(buf+i,"fuck"))
  1327. X      block(buf+i,"f--k");
  1328. X  }
  1329. X}
  1330. X
  1331. X/**********************************************************************/
  1332. X
  1333. Xdo_socket()
  1334. X{
  1335. X  char buf[64];
  1336. X
  1337. X  if (!read_socket(dealer_socket, buf))
  1338. X    death("Dealer died!!");
  1339. X  do_command(buf);
  1340. X}
  1341. X
  1342. Xsend_message(msg)
  1343. Xchar *msg;
  1344. X{
  1345. X  char buf[64];
  1346. X
  1347. X  sprintf(buf, "M%s", msg);
  1348. X  mikey_filter(buf);
  1349. X  write_socket(dealer_socket, buf);
  1350. X}
  1351. X
  1352. Xsend_private_message(who, msg)
  1353. Xint who;
  1354. Xchar *msg;
  1355. X{
  1356. X  char buf[64];
  1357. X
  1358. X  sprintf(buf, ";%d%s", who, msg);
  1359. X  mikey_filter(buf);
  1360. X  write_socket(dealer_socket, buf);
  1361. X}
  1362. X
  1363. Xtoggle_private_messages()
  1364. X{
  1365. X  char buf[2];
  1366. X
  1367. X  buf[0] = '~';
  1368. X  buf[1] = '\0';
  1369. X  write_socket(dealer_socket, buf);
  1370. X}
  1371. X
  1372. Xsend_card(rank, suit)
  1373. Xint rank, suit;
  1374. X{
  1375. X  char buf[64];
  1376. X
  1377. X  sprintf(buf, "P%c%c", rank, suit);
  1378. X  write_socket(dealer_socket, buf);
  1379. X}
  1380. X
  1381. Xsend_auto()
  1382. X{
  1383. X  char buf[64];
  1384. X
  1385. X  sprintf(buf, "P?%c", HEARTS);
  1386. X  write_socket(dealer_socket, buf);
  1387. X}
  1388. X
  1389. Xclose_windows()
  1390. X{
  1391. X    (void) signal(SIGINT, SIG_IGN);
  1392. X    terminate();
  1393. X}
  1394. X
  1395. Xdeath(buf)
  1396. Xchar    *buf;
  1397. X{
  1398. X    close_windows();
  1399. X    printf("%s\n", buf);
  1400. X    exit(1);
  1401. X}
  1402. X
  1403. Xwimp_out()
  1404. X{
  1405. X    close_windows();
  1406. X    exit(0);
  1407. X}
  1408. X
  1409. Xget_rank(rch)
  1410. Xint rch;
  1411. X{
  1412. X    int    i;
  1413. X
  1414. X    for (i = 1; i <= MAX_RANK; i++)
  1415. X        if (rch == rnames[i])
  1416. X            return(i);
  1417. X    return(0);
  1418. X}
  1419. X
  1420. Xget_suit(sch)
  1421. Xint sch;
  1422. X{
  1423. X    int    i;
  1424. X
  1425. X    for (i = 1; i <= MAX_SUIT; i++)
  1426. X        if (sch == *snames[i])
  1427. X            return(i);
  1428. X    return(0);
  1429. X}
  1430. X
  1431. Xstart_new_game()
  1432. X{
  1433. X  write_socket(dist_socket, "n");
  1434. X}
  1435. X
  1436. Xjoin_game(i)
  1437. Xint i;
  1438. X{
  1439. X  char buf[64];
  1440. X
  1441. X  (void) sprintf(buf, "j%d", i);
  1442. X  write_socket(dist_socket, buf);
  1443. X}
  1444. X
  1445. Xdo_dist()
  1446. X{
  1447. X  int i;
  1448. X  char buf[64];
  1449. X
  1450. X  if (read_socket(dist_socket, buf) == 0)
  1451. X    dist_died(3);
  1452. X  i = update_table(buf);
  1453. X  show_tables(cur_screen_table);
  1454. X}
  1455. X
  1456. Xmain(argc, argv)
  1457. Xint    argc;
  1458. Xchar    **argv;
  1459. X{
  1460. X/* Call init first, in case the client wants to parse arguments */
  1461. X    init(&argc, argv);
  1462. X
  1463. X    if (argc > 2) {
  1464. X        fprintf(stderr, "usage: %s [hostname]\n", *argv);
  1465. X        exit(1);
  1466. X    }
  1467. X    if (argc == 2)
  1468. X        (void) strcpy (host, *++argv);
  1469. X    else
  1470. X        (void) gethostname(host, sizeof(host));    /* host is this machine */
  1471. X
  1472. X    first_game = TRUE;
  1473. X
  1474. X    (void) signal(SIGINT, wimp_out);
  1475. X
  1476. X    for (;;) {
  1477. X        game_over = FALSE;
  1478. X        get_going();
  1479. X        do {
  1480. X            scan();
  1481. X        }
  1482. X        while (!game_over);
  1483. X    }
  1484. X}
  1485. X
  1486. END_OF_FILE
  1487. if test 6065 -ne `wc -c <'hearts.c'`; then
  1488.     echo shar: \"'hearts.c'\" unpacked with wrong size!
  1489. fi
  1490. # end of 'hearts.c'
  1491. fi
  1492. if test -f 'hearts_dist.c' -a "${1}" != "-c" ; then 
  1493.   echo shar: Will not clobber existing file \"'hearts_dist.c'\"
  1494. else
  1495. echo shar: Extracting \"'hearts_dist.c'\" \(10208 characters\)
  1496. sed "s/^X//" >'hearts_dist.c' <<'END_OF_FILE'
  1497. X/*
  1498. X * hearts_dist - distributor for hearts
  1499. X *
  1500. X * Keeps track of games in progress and allows new players to select which
  1501. X * game to join or start a new game.
  1502. X *
  1503. X *
  1504. X *    Commands to hearts player:
  1505. X *  tn        Following info regards table n (n is unique identifier).
  1506. X *  hn        Now playing hand n.
  1507. X *  rn        Now playing round n.
  1508. X *  pn<name>    Player n is <name>.
  1509. X *
  1510. X *  xn        Table n has exited (game over).
  1511. X *  g        Get table number to join.
  1512. X *  cn        Connect to dealer on port n.
  1513. X *
  1514. X *    Commands from hearts player:
  1515. X *  jn        Join table n.
  1516. X *  n        Start new game.
  1517. X *
  1518. X *    Commands to dealer:
  1519. X * none yet?!?
  1520. X *
  1521. X *    Commands from dealer:
  1522. X *  hn        Now playing hand n.
  1523. X *  rn        Now playing round n.
  1524. X *  pn<name>    Player n is <name>.
  1525. X *
  1526. X */
  1527. X
  1528. X#include "misc.h"
  1529. X#include "defs.h"
  1530. X#include "local.h"
  1531. X#include <string.h>
  1532. X#include <malloc.h>
  1533. X
  1534. Xtypedef struct table *table_ptr;
  1535. X
  1536. Xstruct table {
  1537. X    table_ptr    next_table;        /* Points to next table entry */
  1538. X    int        table_id;        /* Unique identifier */
  1539. X    char        player_name[4][9];    /* Name of players at table */
  1540. X    int        hand;            /* Current dealer hand (1..4) */
  1541. X    int        round;            /* Current round (1..13) */
  1542. X    int        port_num;        /* Port # assigned */
  1543. X    int        socket;            /* File descriptor for dealer */
  1544. X    int        pid;            /* Process id for dealer */
  1545. X};
  1546. X
  1547. Xtypedef struct empty_table *empty_ptr;
  1548. X
  1549. Xstruct empty_table {
  1550. X    empty_ptr    next_empty;
  1551. X    int        port_num;        /* Available port # */
  1552. X};
  1553. X
  1554. Xtypedef struct new_comer *new_ptr;
  1555. X
  1556. Xstruct new_comer {
  1557. X    new_ptr        next_new_comer;
  1558. X    int        socket;            /* File descriptor */
  1559. X};
  1560. X
  1561. Xtable_ptr    first_table;
  1562. Xempty_ptr    first_empty;
  1563. Xnew_ptr        first_new_comer;
  1564. X
  1565. Xint    main_sock,
  1566. X    next_port,                /* Next port to assign */
  1567. X    unique_id;
  1568. X
  1569. X/*
  1570. X * clear_table - dealer went away; drop that table.
  1571. X */
  1572. Xclear_table(tbl_ptr)
  1573. Xtable_ptr    tbl_ptr;
  1574. X{
  1575. X    table_ptr    prev_ptr = NULL;
  1576. X    table_ptr    cur_ptr;
  1577. X    empty_ptr    temp_empty, cur_empty;
  1578. X    new_ptr        cur_new_comer;
  1579. X    char        buf[16];
  1580. X
  1581. X    while (wait(0) != tbl_ptr->pid)        /* Wait for process to die */
  1582. X        ;
  1583. X    (void) close(tbl_ptr->socket);
  1584. X    /*
  1585. X     * Inform new-comers
  1586. X     */
  1587. X    (void) sprintf(buf, "x%d", tbl_ptr->table_id);
  1588. X    for (cur_new_comer = first_new_comer; cur_new_comer;
  1589. X            cur_new_comer = cur_new_comer->next_new_comer)
  1590. X        write_socket(cur_new_comer->socket, buf);
  1591. X    for (cur_ptr = first_table; cur_ptr != tbl_ptr;
  1592. X                    cur_ptr = cur_ptr->next_table)
  1593. X        prev_ptr = cur_ptr;
  1594. X    if (prev_ptr)
  1595. X        prev_ptr->next_table = tbl_ptr->next_table;
  1596. X    else
  1597. X        if ((first_table = tbl_ptr->next_table) == NULL &&
  1598. X            first_new_comer == NULL)
  1599. X            exit(0);    /* No more dealers */
  1600. X            ;
  1601. X     if (first_table) {
  1602. X    temp_empty = (empty_ptr) malloc(sizeof(struct empty_table));
  1603. X    temp_empty->next_empty = NULL;
  1604. X    temp_empty->port_num = tbl_ptr->port_num;
  1605. X    free((char *) tbl_ptr);
  1606. X    if (first_empty) {
  1607. X        for (cur_empty = first_empty; cur_empty->next_empty;
  1608. X                    cur_empty = cur_empty->next_empty) ;
  1609. X        cur_empty->next_empty = temp_empty;
  1610. X    }
  1611. X    else
  1612. X        first_empty = temp_empty;
  1613. X      }
  1614. X}
  1615. X
  1616. X/*
  1617. X * drop_new_comer - New comer exited
  1618. X */
  1619. Xdrop_new_comer(dead_new_comer)
  1620. Xnew_ptr    dead_new_comer;
  1621. X{
  1622. X    new_ptr    cur_new_comer,
  1623. X        prev_new_comer = NULL;
  1624. X
  1625. X    (void) close(dead_new_comer->socket);
  1626. X    for (cur_new_comer = first_new_comer; cur_new_comer != dead_new_comer;
  1627. X            cur_new_comer = cur_new_comer->next_new_comer)
  1628. X        prev_new_comer = cur_new_comer;
  1629. X    if (prev_new_comer)
  1630. X        prev_new_comer->next_new_comer = dead_new_comer->next_new_comer;
  1631. X    else
  1632. X        first_new_comer = dead_new_comer->next_new_comer;
  1633. X    free((char *) dead_new_comer);
  1634. X    if ((first_table == NULL) && (first_new_comer == NULL))
  1635. X        exit(0);        /* Nobody connected */
  1636. X}
  1637. X
  1638. X/*
  1639. X * new_player - New player has connected.  Inform of games in progress and
  1640. X *        request game to be joined.
  1641. X */
  1642. Xnew_player()
  1643. X{
  1644. X    int    new_socket;        /* new file descriptor */
  1645. X    char    buf[64];
  1646. X    struct    sockaddr_in sockad;
  1647. X    int    ssize;            /* makes accept happy */
  1648. X    int    i;
  1649. X    new_ptr        cur_new_comer, temp_new_comer;
  1650. X    table_ptr    cur_ptr;
  1651. X
  1652. X    /*
  1653. X     * add whoever's waiting
  1654. X     */
  1655. X    ssize = sizeof (sockad);
  1656. X    if ((new_socket = accept(main_sock, &sockad, &ssize)) == -1) {
  1657. X        perror("accept");
  1658. X        exit(-1);
  1659. X    }
  1660. X    /*
  1661. X     * add to list of new_comers
  1662. X     */
  1663. X    temp_new_comer = (new_ptr) malloc(sizeof(struct new_comer));
  1664. X    temp_new_comer->next_new_comer = NULL;
  1665. X    temp_new_comer->socket = new_socket;
  1666. X    if (first_new_comer) {
  1667. X        for (cur_new_comer = first_new_comer;
  1668. X            cur_new_comer->next_new_comer;
  1669. X            cur_new_comer = cur_new_comer->next_new_comer) ;
  1670. X        cur_new_comer->next_new_comer = temp_new_comer;
  1671. X    }
  1672. X    else {
  1673. X        first_new_comer = temp_new_comer;
  1674. X        first_new_comer->next_new_comer = NULL;
  1675. X    }
  1676. X    /*
  1677. X     * send info on games in progress
  1678. X     */
  1679. X    for (cur_ptr = first_table; cur_ptr; cur_ptr = cur_ptr->next_table) {
  1680. X        (void) sprintf(buf, "t%d", cur_ptr->table_id);
  1681. X        write_socket(new_socket, buf);
  1682. X        (void) sprintf(buf, "h%d", cur_ptr->hand);
  1683. X        write_socket(new_socket, buf);
  1684. X        (void) sprintf(buf, "r%d", cur_ptr->round);
  1685. X        write_socket(new_socket, buf);
  1686. X        for (i = 0; i < 4; i++) {
  1687. X            (void) sprintf(buf, "p%d%s", i, cur_ptr->player_name[i]);
  1688. X            write_socket(new_socket, buf);
  1689. X        }
  1690. X    }
  1691. X    write_socket(new_socket, "g");
  1692. X}
  1693. X
  1694. Xtell_new_comers(buf)
  1695. Xchar    *buf;
  1696. X{
  1697. X    new_ptr    cur_new;
  1698. X
  1699. X    for (cur_new = first_new_comer; cur_new;
  1700. X            cur_new = cur_new->next_new_comer)
  1701. X        write_socket(cur_new->socket, buf);
  1702. X}
  1703. X
  1704. X/*
  1705. X * join - join an existing table.  table_num is unique identifier for table.
  1706. X */
  1707. Xjoin(table_num, socket)
  1708. Xint    table_num, socket;
  1709. X{
  1710. X    table_ptr    cur_ptr;
  1711. X    char    buf[16];
  1712. X
  1713. X    for (cur_ptr = first_table; cur_ptr && cur_ptr->table_id != table_num;
  1714. X                    cur_ptr = cur_ptr->next_table) ;
  1715. X    if (cur_ptr) {
  1716. X        (void) sprintf(buf, "c%d", cur_ptr->port_num);
  1717. X        write_socket(socket, buf);
  1718. X    }
  1719. X    else
  1720. X        write_socket(socket, "g");    /* Table doesn't exist?!? */
  1721. X}
  1722. X
  1723. X/*
  1724. X * new_table - start new hearts game.
  1725. X */
  1726. Xnew_table(cur_new_comer)
  1727. Xnew_ptr    cur_new_comer;
  1728. X{
  1729. X    table_ptr    cur_table, new_tbl_ptr;
  1730. X    empty_ptr    tmp_empty;
  1731. X    int        i, socks[2];
  1732. X    int        dealer_port, dealer_socket, retry = 0;
  1733. X    char    buf[16], filename[1024];
  1734. X
  1735. X    new_tbl_ptr = (table_ptr) malloc(sizeof(struct table));
  1736. X    new_tbl_ptr->next_table = NULL;
  1737. X    new_tbl_ptr->table_id = ++unique_id;
  1738. X    for (i = 0; i < 4; i++)
  1739. X        (void) strcpy(new_tbl_ptr->player_name[i], "<empty>");
  1740. X    /*
  1741. X     * Assign a port.  Reassign a used port if available.
  1742. X     */
  1743. X    do {
  1744. X        if (first_empty) {
  1745. X            dealer_port = first_empty->port_num;
  1746. X            tmp_empty = first_empty;
  1747. X            first_empty = first_empty->next_empty;
  1748. X            free((char *) tmp_empty);
  1749. X        }
  1750. X        else
  1751. X            dealer_port = next_port++;
  1752. X        /*
  1753. X         * Make sure port is ok before assigning.
  1754. X         */
  1755. X        if ((dealer_socket = open_socket(dealer_port)) == 0)
  1756. X            if (++ retry == 20) {
  1757. X                fputs("Can't open a dealer port!\n", stderr);
  1758. X                exit(1);
  1759. X            }
  1760. X    }
  1761. X    while (dealer_socket == 0);
  1762. X    new_tbl_ptr->port_num = dealer_port;
  1763. X    /*
  1764. X     * Open a socket pair to talk to dealer on.
  1765. X     */
  1766. X    if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks) == -1) {
  1767. X        perror("socketpair");
  1768. X        exit(1);
  1769. X    }
  1770. X    switch (new_tbl_ptr->pid = fork()) {
  1771. X    case 0:
  1772. X        (void) setpgrp (0, getpid());
  1773. X        (void) close(socks[0]);
  1774. X        if (socks[1] != 3)
  1775. X            (void) dup2(socks[1], 3);    /* Remap to fd 3 */
  1776. X        if (dealer_socket != 4)
  1777. X            (void) dup2(dealer_socket, 4);    /* Remap to fd 4 */
  1778. X        sprintf(filename, "%s/%s", HEARTSLIB, HEARTSD);
  1779. X        execl (filename, "heartsd", 0);
  1780. X        exit(1);
  1781. X    case -1:
  1782. X        perror("fork");
  1783. X        exit(1);
  1784. X    }
  1785. X    (void) close(socks[1]);
  1786. X    (void) close(dealer_socket);
  1787. X
  1788. X    new_tbl_ptr->socket = socks[0];
  1789. X    if (first_table) {
  1790. X        for (cur_table = first_table; cur_table->next_table;
  1791. X            cur_table = cur_table->next_table)
  1792. X            ;
  1793. X        cur_table->next_table = new_tbl_ptr;
  1794. X    }
  1795. X    else
  1796. X        first_table = new_tbl_ptr;
  1797. X    /*
  1798. X     * Inform hearts player of port # to connect on.
  1799. X     */
  1800. X    (void) sprintf(buf, "c%d", dealer_port);
  1801. X    write_socket(cur_new_comer->socket, buf);
  1802. X}
  1803. X
  1804. Xmain(argc, argv)
  1805. Xchar **argv;
  1806. X{
  1807. X    fd_type        read_fd;
  1808. X    table_ptr    cur_table;
  1809. X    new_ptr        cur_new_comer;
  1810. X    char        buf[64], tmp_buf[64];
  1811. X    int        ret;
  1812. X    int        table_num;
  1813. X    char        debug;
  1814. X
  1815. X    while (*++argv) {
  1816. X        if (**argv == '-') {
  1817. X            while (*++*argv) {
  1818. X                switch (**argv) {
  1819. X                case 'd':
  1820. X                    debug = TRUE;
  1821. X                    break;
  1822. X
  1823. X                default:
  1824. X                    fprintf (stderr, "usage: hearts_dist [-d]\n");
  1825. X                    exit (1);
  1826. X                    break;
  1827. X                }
  1828. X            }
  1829. X        }
  1830. X    }
  1831. X
  1832. X    first_table = NULL;
  1833. X    first_empty = NULL;
  1834. X    first_new_comer = NULL;
  1835. X    next_port = DIST_PORT;
  1836. X    unique_id = 0;
  1837. X
  1838. X    if ((main_sock = open_socket(PORT)) == 0) {
  1839. X        fputs("Distributor port in use!\n", stderr);
  1840. X        exit(1);
  1841. X    }
  1842. X    if (!debug) {
  1843. X        /*
  1844. X         * Fork off and die.  Thus hearts invoker wait() returns.
  1845. X         * This signals ready to connect.
  1846. X         */
  1847. X        if (fork())
  1848. X            exit (0);
  1849. X    }
  1850. X
  1851. X    for (;;) {
  1852. X        fd_init(main_sock, &read_fd);
  1853. X        /*
  1854. X         * Build mask for dealers
  1855. X         */
  1856. X        for (cur_table = first_table; cur_table;
  1857. X                cur_table = cur_table->next_table)
  1858. X            fd_set(cur_table->socket, &read_fd);
  1859. X        /*
  1860. X         * Build mask for new_comers
  1861. X         */
  1862. X        for (cur_new_comer = first_new_comer; cur_new_comer;
  1863. X                cur_new_comer = cur_new_comer->next_new_comer)
  1864. X            fd_set(cur_new_comer->socket, &read_fd);
  1865. X
  1866. X        /*
  1867. X         * Wait for something to happen
  1868. X         */
  1869. X        if (select(WIDTH, &read_fd, (fd_type *) 0, (fd_type *) 0,
  1870. X                (struct timeval *) 0)) {
  1871. X            if (fd_isset(main_sock, read_fd))
  1872. X                new_player();
  1873. X            for (cur_table = first_table; cur_table;
  1874. X                    cur_table = cur_table->next_table)
  1875. X                if (fd_isset(cur_table->socket, read_fd)) {
  1876. X                    /*
  1877. X                     * Message from dealer
  1878. X                     */
  1879. X                    ret = read_socket(cur_table->socket, buf);
  1880. X                    if (!ret) {
  1881. X                        clear_table(cur_table);
  1882. X                        break;
  1883. X                    } else {
  1884. X                        switch (buf[0]) {
  1885. X                        case 'h' :
  1886. X                            (void) sscanf(buf + 1, "%d", &cur_table->hand);
  1887. X                            break;
  1888. X                        case 'r' :
  1889. X                            (void) sscanf(buf + 1, "%d", &cur_table->round);
  1890. X                            break;
  1891. X                        case 'p' :
  1892. X                            (void) strcpy(cur_table->player_name[buf[1] - '0'], buf + 2);
  1893. X                        }
  1894. X                        (void) sprintf(tmp_buf, "t%d", cur_table->table_id);
  1895. X                        tell_new_comers(tmp_buf);
  1896. X                        tell_new_comers(buf);
  1897. X                    }
  1898. X                }
  1899. X            for (cur_new_comer = first_new_comer; cur_new_comer;
  1900. X                cur_new_comer = cur_new_comer->next_new_comer)
  1901. X                if (fd_isset(cur_new_comer->socket, read_fd)) {
  1902. X                    /*
  1903. X                     * Message from newcomer
  1904. X                     */
  1905. X                    ret = read_socket(cur_new_comer->socket, buf);
  1906. X                    if (ret)
  1907. X                        switch (buf[0]) {
  1908. X                        case 'j' :
  1909. X                            (void) sscanf(buf + 1, "%d", &table_num);
  1910. X                            join(table_num, cur_new_comer->socket);
  1911. X                            break;
  1912. X
  1913. X                        case 'n' :
  1914. X                            new_table(cur_new_comer);
  1915. X                        }
  1916. X                    else {
  1917. X                        drop_new_comer(cur_new_comer);
  1918. X                        break;
  1919. X                         }
  1920. X                }
  1921. X        }
  1922. X    }
  1923. X}
  1924. X
  1925. END_OF_FILE
  1926. if test 10208 -ne `wc -c <'hearts_dist.c'`; then
  1927.     echo shar: \"'hearts_dist.c'\" unpacked with wrong size!
  1928. fi
  1929. # end of 'hearts_dist.c'
  1930. fi
  1931. if test -f 'rank.bm' -a "${1}" != "-c" ; then 
  1932.   echo shar: Will not clobber existing file \"'rank.bm'\"
  1933. else
  1934. echo shar: Extracting \"'rank.bm'\" \(2624 characters\)
  1935. sed "s/^X//" >'rank.bm' <<'END_OF_FILE'
  1936. X/*
  1937. X *    Spider
  1938. X *
  1939. X *    (c) Copyright 1989, Donald R. Woods and Sun Microsystems, Inc.
  1940. X *    (c) Copyright 1990, David Lemke and Network Computing Devices Inc.
  1941. X *
  1942. X *    See copyright.h for the terms of the copyright.
  1943. X *
  1944. X *    @(#)rank.bm    2.1    90/04/25
  1945. X *
  1946. X */
  1947. X#define rank_width 9
  1948. X#define rank_height 14
  1949. Xstatic char rank_bits[13][28] = {
  1950. X   0x38, 0x00, 0x38, 0x00, 0x38, 0x00, 0x6c, 0x00, 0x6c, 0x00, 0x6c, 0x00,
  1951. X   0x6c, 0x00, 0xc6, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xc6, 0x00, 0x83, 0x01,
  1952. X   0x83, 0x01, 0x83, 0x01,
  1953. X   0x7c, 0x00, 0xfe, 0x00, 0xc7, 0x01, 0x83, 0x01, 0x80, 0x01, 0xc0, 0x01,
  1954. X   0xe0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1c, 0x00, 0x0e, 0x00, 0x87, 0x01,
  1955. X   0xff, 0x01, 0xff, 0x01,
  1956. X   0xff, 0x01, 0xff, 0x01, 0xc3, 0x01, 0xe0, 0x00, 0x70, 0x00, 0x78, 0x00,
  1957. X   0xfc, 0x00, 0xc8, 0x01, 0x80, 0x01, 0x80, 0x01, 0x82, 0x01, 0xc7, 0x01,
  1958. X   0xfe, 0x00, 0x7c, 0x00,
  1959. X   0xe0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd8, 0x00, 0xd8, 0x00, 0xcc, 0x00,
  1960. X   0xcc, 0x00, 0xc6, 0x00, 0xc6, 0x00, 0xff, 0x01, 0xff, 0x01, 0xc0, 0x00,
  1961. X   0xe0, 0x01, 0xe0, 0x01,
  1962. X   0xff, 0x00, 0xff, 0x00, 0x03, 0x00, 0x03, 0x00, 0x7b, 0x00, 0xff, 0x00,
  1963. X   0xc7, 0x01, 0x82, 0x01, 0x80, 0x01, 0x80, 0x01, 0x82, 0x01, 0xc7, 0x01,
  1964. X   0xfe, 0x00, 0x7c, 0x00,
  1965. X   0x7c, 0x00, 0xfe, 0x00, 0xc7, 0x01, 0x83, 0x00, 0x03, 0x00, 0x7b, 0x00,
  1966. X   0xff, 0x00, 0xc7, 0x01, 0x83, 0x01, 0x83, 0x01, 0x83, 0x01, 0xc7, 0x01,
  1967. X   0xfe, 0x00, 0x7c, 0x00,
  1968. X   0xff, 0x01, 0xff, 0x01, 0x83, 0x01, 0xc0, 0x00, 0xc0, 0x00, 0x60, 0x00,
  1969. X   0x60, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x18, 0x00, 0x18, 0x00,
  1970. X   0x18, 0x00, 0x18, 0x00,
  1971. X   0x7c, 0x00, 0xfe, 0x00, 0xc7, 0x01, 0x83, 0x01, 0xc7, 0x01, 0xfe, 0x00,
  1972. X   0x7c, 0x00, 0xfe, 0x00, 0xc7, 0x01, 0x83, 0x01, 0x83, 0x01, 0xc7, 0x01,
  1973. X   0xfe, 0x00, 0x7c, 0x00,
  1974. X   0x7c, 0x00, 0xfe, 0x00, 0xc7, 0x01, 0x83, 0x01, 0x83, 0x01, 0x83, 0x01,
  1975. X   0xc7, 0x01, 0xfe, 0x01, 0xbc, 0x01, 0x80, 0x01, 0x82, 0x01, 0xc7, 0x01,
  1976. X   0xfe, 0x00, 0x7c, 0x00,
  1977. X   0xf3, 0x00, 0xfb, 0x01, 0x9b, 0x01, 0x9b, 0x01, 0x9b, 0x01, 0x9b, 0x01,
  1978. X   0x9b, 0x01, 0x9b, 0x01, 0x9b, 0x01, 0x9b, 0x01, 0x9b, 0x01, 0x9b, 0x01,
  1979. X   0xfb, 0x01, 0xf3, 0x00,
  1980. X   0xe0, 0x01, 0xe0, 0x01, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00,
  1981. X   0xc0, 0x00, 0xc0, 0x00, 0xc0, 0x00, 0xc3, 0x00, 0xc3, 0x00, 0xe7, 0x00,
  1982. X   0x7e, 0x00, 0x3c, 0x00,
  1983. X   0x38, 0x00, 0x7c, 0x00, 0xee, 0x00, 0xc6, 0x00, 0xc6, 0x00, 0xc6, 0x00,
  1984. X   0xc6, 0x00, 0xc6, 0x00, 0xdf, 0x00, 0xff, 0x00, 0xf6, 0x00, 0xee, 0x00,
  1985. X   0xfc, 0x01, 0xb8, 0x00,
  1986. X   0xef, 0x01, 0xef, 0x01, 0xe6, 0x00, 0x76, 0x00, 0x3e, 0x00, 0x1e, 0x00,
  1987. X   0x1e, 0x00, 0x3e, 0x00, 0x36, 0x00, 0x76, 0x00, 0x66, 0x00, 0xe6, 0x00,
  1988. X   0xef, 0x01, 0xef, 0x01};
  1989. END_OF_FILE
  1990. if test 2624 -ne `wc -c <'rank.bm'`; then
  1991.     echo shar: \"'rank.bm'\" unpacked with wrong size!
  1992. fi
  1993. # end of 'rank.bm'
  1994. fi
  1995. echo shar: End of archive 4 \(of 6\).
  1996. cp /dev/null ark4isdone
  1997. MISSING=""
  1998. for I in 1 2 3 4 5 6 ; do
  1999.     if test ! -f ark${I}isdone ; then
  2000.     MISSING="${MISSING} ${I}"
  2001.     fi
  2002. done
  2003. if test "${MISSING}" = "" ; then
  2004.     echo You have unpacked all 6 archives.
  2005.     rm -f ark[1-9]isdone
  2006. else
  2007.     echo You still need to unpack the following archives:
  2008.     echo "        " ${MISSING}
  2009. fi
  2010. ##  End of shell archive.
  2011. exit 0
  2012. --
  2013. Molecular Simulations, Inc.             mail: dcmartin@postgres.berkeley.edu
  2014. 796 N. Pastoria Avenue                  uucp: uwvax!ucbvax!dcmartin
  2015. Sunnyvale, California 94086             at&t: 408/522-9236
  2016.