home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume13 / x4war / part01 < prev    next >
Encoding:
Internet Message Format  |  1992-04-09  |  53.6 KB

  1. Path: uunet!zephyr.ens.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v13i077:  x4war - An X11 version of Chinese four-state war game, Part01/03
  5. Message-ID: <2649@master.CNA.TEK.COM>
  6. Date: 23 Mar 92 22:50:10 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 1978
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: Xiaobing Chen <xiaobing@cs.sfu.ca>
  12. Posting-number: Volume 13, Issue 77
  13. Archive-name: x4war/Part01
  14. Environment: X11, Xlib, Xt
  15.  
  16.  
  17.  
  18. #! /bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 1 (of 3)."
  25. # Contents:  README MANIFEST bitmaps bitmaps/war_logo.xbm x4war.c
  26. # Wrapped by billr@saab on Mon Mar 23 14:49:04 1992
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'README' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'README'\"
  30. else
  31. echo shar: Extracting \"'README'\" \(2607 characters\)
  32. sed "s/^X//" >'README' <<'END_OF_FILE'
  33. Xx4war - An X11 version of Chinese four-state war game.
  34. X
  35. X
  36. XWHAT IS IT?
  37. X
  38. XThis is a board game which implements the Chinese four-state war game in the
  39. XX Window environment. It allows four players to play the game on four displays,
  40. Xeach coordinating a complete army, players at the opposite position of the
  41. Xplaying board are allied. The goal of the game is to capture the COLOURS of
  42. Xthe enemy.
  43. X
  44. XI heard it's sort of like the American game 'stratego'.
  45. X
  46. X
  47. XCOMPILING
  48. X
  49. XThe program is implemented using Xlib and Xt. It should be compilable in
  50. Xmost of  X11/R4 environment. Presently the program is tested only under
  51. XSunOS 4.1.1 and IRIX 4.0.1 System V.
  52. X
  53. XA Makefile.simple is supplied. Just following the steps below:
  54. X
  55. X    %make -f Makefile.simple bgbitmap
  56. X        to get 'bgbitmap' for creating the background of the board.
  57. X
  58. X    %bgbitmap
  59. X        wait for a second and a background bitmap file called
  60. X        'war_background.xbm' will be created in the bitmaps
  61. X        subdirectory.
  62. X
  63. X    %make -f Makefile.simple
  64. X        this will get you the 'x4war' executable.
  65. X
  66. X
  67. XAn Imakefile is also included. If you use this file, you can type 'xmkmf' to
  68. Xget a Makefile, then use the above command with '-f Makefile.simple' omitted.
  69. X
  70. XThe file 'x4war' is enough for the game. Other files can be removed after you
  71. Xget the 'x4war' file.
  72. X
  73. X
  74. XUSAGE
  75. X
  76. XType 'x4war -usage' to get command options.
  77. X
  78. XFor the meaning of the nodes and rules of the game, please consult one who can
  79. Xread Chinese characters and knows the conventional rules. Also read x4war.man
  80. Xfor detail.
  81. X
  82. X
  83. XACKNOWLEDGEMENTS
  84. X
  85. XSpecial thanks to Zhongmin Guo, Bo Wang, Ju Wu, and Danpo Zhang, who created
  86. Xmost of the bitmaps and had given many valuable suggestions. And many thanks
  87. Xto my fellow students at School of Computing Science and Engineering Science,
  88. XSimon Fraser University, who had helped to test the program and given all
  89. Xkinds of support.
  90. X
  91. X
  92. XCOPYRIGHT
  93. X
  94. XCopyright 1992 by Xiaobing Chen
  95. X
  96. XPermission to use, copy, and distribute for non-commercial purposes,
  97. Xis hereby granted without fee, providing that the above copyright
  98. Xnotice appear in all copies and that both the copyright notice and this
  99. Xpermission notice appear in supporting documentation. 
  100. X
  101. XThe software may be modified for your own purposes, but modified versions
  102. Xmay not be distributed without prior consent of the the author.
  103. X
  104. XThis software is provided "as is" without any expressed or implied warranty.
  105. X
  106. XThe author may be contacted via:
  107. X    Address:   Xiaobing Chen
  108. X               School of Computing Science
  109. X               Simon Fraser University  
  110. X               Burnaby, B.C.,  V5A 1S6
  111. X           Canada
  112. X
  113. X    EMail:     xiaobing@cs.sfu.ca       
  114. X
  115. X
  116. END_OF_FILE
  117. if test 2607 -ne `wc -c <'README'`; then
  118.     echo shar: \"'README'\" unpacked with wrong size!
  119. fi
  120. # end of 'README'
  121. fi
  122. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  123.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  124. else
  125. echo shar: Extracting \"'MANIFEST'\" \(1106 characters\)
  126. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  127. X   File Name        Archive #    Description
  128. X-----------------------------------------------------------
  129. X Imakefile                  3    
  130. X MANIFEST                   1    This shipping list
  131. X Makefile.simple            2    
  132. X README                     1    
  133. X bgbitmap.c                 2    
  134. X bitmaps                    1    
  135. X bitmaps/back0.xbm          3    
  136. X bitmaps/back1.xbm          3    
  137. X bitmaps/back2.xbm          3    
  138. X bitmaps/back3.xbm          3    
  139. X bitmaps/bomb.xbm           3    
  140. X bitmaps/brigadier.xbm      3    
  141. X bitmaps/captain.xbm        3    
  142. X bitmaps/colonel.xbm        3    
  143. X bitmaps/colours.xbm        3    
  144. X bitmaps/cursor.xbm         3    
  145. X bitmaps/cursormask.xbm     3    
  146. X bitmaps/f_lieutenant.xbm   3    
  147. X bitmaps/general.xbm        3    
  148. X bitmaps/go.xbm             2    
  149. X bitmaps/m_general.xbm      3    
  150. X bitmaps/major.xbm          3    
  151. X bitmaps/marshal.xbm        3    
  152. X bitmaps/mine.xbm           3    
  153. X bitmaps/nodemask.xbm       3    
  154. X bitmaps/sapper.xbm         3    
  155. X bitmaps/stop.xbm           2    
  156. X bitmaps/war_logo.xbm       1    
  157. X war.c                      2    
  158. X war.h                      2    
  159. X x4war.c                    1    
  160. X x4war.man                  2    
  161. END_OF_FILE
  162. if test 1106 -ne `wc -c <'MANIFEST'`; then
  163.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  164. fi
  165. # end of 'MANIFEST'
  166. fi
  167. if test ! -d 'bitmaps' ; then
  168.     echo shar: Creating directory \"'bitmaps'\"
  169.     mkdir 'bitmaps'
  170. fi
  171. if test -f 'bitmaps/war_logo.xbm' -a "${1}" != "-c" ; then 
  172.   echo shar: Will not clobber existing file \"'bitmaps/war_logo.xbm'\"
  173. else
  174. echo shar: Extracting \"'bitmaps/war_logo.xbm'\" \(3289 characters\)
  175. sed "s/^X//" >'bitmaps/war_logo.xbm' <<'END_OF_FILE'
  176. X#define war_logo_width 64
  177. X#define war_logo_height 64
  178. Xstatic char war_logo_bits[] = {
  179. X   0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x06, 0x7f, 0x0f, 0x00, 0x00,
  180. X   0x00, 0x06, 0x00, 0x07, 0x66, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06,
  181. X   0x66, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06, 0x66, 0x04, 0x00, 0x00,
  182. X   0x00, 0x06, 0x00, 0x06, 0x6e, 0x04, 0x1f, 0xce, 0x01, 0x06, 0xf0, 0x06,
  183. X   0xee, 0x82, 0x38, 0x2c, 0x03, 0x06, 0x8c, 0x07, 0xcc, 0x42, 0x70, 0x1c,
  184. X   0x03, 0x06, 0x04, 0x07, 0xec, 0x62, 0x60, 0x0c, 0x00, 0x06, 0x06, 0x06,
  185. X   0xdc, 0x63, 0x60, 0x0c, 0x00, 0x06, 0x06, 0x06, 0xdc, 0x61, 0x60, 0x0c,
  186. X   0x00, 0x06, 0x06, 0x06, 0x98, 0x61, 0x60, 0x0c, 0x00, 0x06, 0x06, 0x06,
  187. X   0x98, 0xe1, 0x20, 0x0c, 0x00, 0x06, 0x0e, 0x07, 0x98, 0xc1, 0x11, 0x0c,
  188. X   0x00, 0x06, 0x9c, 0x06, 0x98, 0x81, 0x0f, 0x1e, 0x80, 0x1f, 0x78, 0x0e,
  189. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  190. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  191. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  192. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  193. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  194. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x7e, 0xf0, 0x03, 0x00, 0x00,
  195. X   0x00, 0x80, 0x73, 0xee, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x80, 0x73, 0xe0,
  196. X   0xe0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0xf8, 0xe0, 0x00, 0x00, 0x00,
  197. X   0x00, 0x80, 0x7f, 0xfc, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0xee,
  198. X   0xe1, 0x00, 0x00, 0x00, 0x00, 0x80, 0x7f, 0xee, 0xe1, 0x00, 0x00, 0x00,
  199. X   0x00, 0x80, 0x73, 0xfc, 0xf1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  200. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  201. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  202. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  203. X   0x00, 0x00, 0x1f, 0x7c, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x38,
  204. X   0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00,
  205. X   0x00, 0x00, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x38,
  206. X   0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00,
  207. X   0x00, 0x00, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x38,
  208. X   0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00,
  209. X   0x00, 0x00, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x7c,
  210. X   0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  211. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  212. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  213. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  214. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  215. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  216. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  217. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  218. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  219. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  220. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  221. X   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  222. X
  223. X
  224. END_OF_FILE
  225. if test 3289 -ne `wc -c <'bitmaps/war_logo.xbm'`; then
  226.     echo shar: \"'bitmaps/war_logo.xbm'\" unpacked with wrong size!
  227. fi
  228. # end of 'bitmaps/war_logo.xbm'
  229. fi
  230. if test -f 'x4war.c' -a "${1}" != "-c" ; then 
  231.   echo shar: Will not clobber existing file \"'x4war.c'\"
  232. else
  233. echo shar: Extracting \"'x4war.c'\" \(42982 characters\)
  234. sed "s/^X//" >'x4war.c' <<'END_OF_FILE'
  235. X#include <X11/Xlib.h>
  236. X#include <X11/Xutil.h>
  237. X#include <X11/X.h>
  238. X#include <X11/Xos.h>
  239. X#include <X11/Xatom.h>
  240. X#include <X11/Intrinsic.h>
  241. X#include <X11/keysym.h>
  242. X
  243. X#include <stdio.h>
  244. X#include "war.h"
  245. X
  246. X#include "bitmaps/war_background.xbm"
  247. X#include "bitmaps/war_logo.xbm"
  248. X#include "bitmaps/colours.xbm"
  249. X#include "bitmaps/marshal.xbm"
  250. X#include "bitmaps/general.xbm"
  251. X#include "bitmaps/m_general.xbm"
  252. X#include "bitmaps/brigadier.xbm"
  253. X#include "bitmaps/colonel.xbm"
  254. X#include "bitmaps/major.xbm"
  255. X#include "bitmaps/captain.xbm"
  256. X#include "bitmaps/f_lieutenant.xbm"
  257. X#include "bitmaps/sapper.xbm"
  258. X#include "bitmaps/mine.xbm"
  259. X#include "bitmaps/bomb.xbm"
  260. X
  261. X#include "bitmaps/back0.xbm"
  262. X#include "bitmaps/back1.xbm"
  263. X#include "bitmaps/back2.xbm"
  264. X#include "bitmaps/back3.xbm"
  265. X
  266. X#include "bitmaps/cursor.xbm"
  267. X#include "bitmaps/cursormask.xbm"
  268. X#include "bitmaps/nodemask.xbm"
  269. X
  270. X#include "bitmaps/go.xbm"
  271. X#include "bitmaps/stop.xbm"
  272. X
  273. X
  274. Xstruct Player {
  275. X    Display *dis;
  276. X    int scr;        /* screen number of display *dis */
  277. X    Window win, confirm;
  278. X    Pixmap node[16];    /* 0-11 for faces of nodes, 12-15 for back and cursor */
  279. X    Pixmap cursormask_pixmap,nodemask_pixmap,icon_pixmap,stop_pixmap,go_pixmap;
  280. X    unsigned long fg[4];   /* foreground of nodes */
  281. X    XColor fg_color, bg_color;
  282. X    GC gc;
  283. X    Cursor cursor, tmp_cursor;
  284. X
  285. X    char *display_name;
  286. X    char player_name[10];
  287. X    char color_name[20];
  288. X    int rip[5][5];
  289. X    int rip_index;
  290. X    int state;        /* 0--dead, 1--deploy, 2--play, 3--quit */
  291. X    int num_movable;
  292. X    int popup;        /* 0--no popup, 1--Peace Request, 2--Quit,
  293. X               3--continue message*/
  294. X            /* if confirm window is poped up, input is grabed */
  295. X
  296. X/* this structure tells if a node is picked up by pressing a button, it
  297. X   records the array and subscripts of the node.
  298. X*/
  299. X    struct {
  300. X    int arr;
  301. X    int x, y;
  302. X    int value;
  303. X    Boolean picked;
  304. X    } pick;
  305. X    Boolean marshal_dead;
  306. X    char talk_msg[3][30];
  307. X    int talk_col;
  308. X    int talk_x, talk_y;
  309. X};
  310. X
  311. XXtAppContext app_context;
  312. X
  313. XArr arr[4][6][5], mid[3][3];    /* array to remember the state of the
  314. X                   war */
  315. X
  316. Xstruct Player p[4];
  317. X
  318. XSapper_path sap[21];
  319. X
  320. Xunsigned int  global_argc;
  321. Xchar ** global_argv;
  322. Xchar *progname;
  323. X
  324. Xchar msg1[30], msg2[30];
  325. Xchar confirm_msg[30];
  326. X
  327. Xint mode;    /* game mode */
  328. X        /* 0 -- new game and deploy phase */
  329. X        /* 1 -- play phase    */
  330. X        /* 2 -- peace request phase */
  331. X        /* 3 -- one game finished */
  332. X        /* 4 -- during a move */
  333. X
  334. Xint num_player; /* when one is defeated, this var decrease by 1 */
  335. X
  336. Xint count;    /* to calculate the flashing when node moved */
  337. X        /* values and meanings
  338. X           8--clear source;
  339. X           7--show source;
  340. X           6--clear source;
  341. X           5--show source;
  342. X           4--clear source;
  343. X           3--show destination;
  344. X           2--clear destination;
  345. X           1--show destination;
  346. X           0--clear destination;
  347. X        */
  348. Xint turn;        /* 0-3, specifies who's turn to move */
  349. X
  350. Xint round;
  351. X
  352. Xint sf, si, sj, sw, sv, df, di, dj, dw, dv;    /* record one move */
  353. X
  354. XBoolean debug;
  355. X
  356. Xstatic void refresh_board();
  357. X
  358. X
  359. X/*******************************************************************
  360. X*
  361. X*   Synopsis
  362. X*    parse_arguments(argc, argv)
  363. X*        int argc;
  364. X*        char **argv;
  365. X*
  366. X*   Description
  367. X*    parses arguments in command line and set appropriate properties,
  368. X*    exit if illegal argument present.
  369. X*
  370. X********************************************************************/
  371. X
  372. Xstatic void
  373. Xparse_arguments(argc, argv)
  374. Xint argc;
  375. Xchar **argv;
  376. X{
  377. X    int i;
  378. X
  379. X    i = 1;
  380. X    while (i<argc) {
  381. X    if (!strcmp(argv[i], "-p0"))
  382. X        strncpy(p[0].player_name, argv[++i], 9);
  383. X    else if (!strcmp(argv[i], "-d0"))
  384. X        p[0].display_name = argv[++i];
  385. X    else if (!strcmp(argv[i], "-c0"))
  386. X        strncpy(p[0].color_name, argv[++i], 19);
  387. X    else if (!strcmp(argv[i], "-p1"))
  388. X        strncpy(p[1].player_name, argv[++i], 9);
  389. X    else if (!strcmp(argv[i], "-d1"))
  390. X        p[1].display_name = argv[++i];
  391. X    else if (!strcmp(argv[i], "-c1"))
  392. X        strncpy(p[1].color_name, argv[++i], 19);
  393. X    else if (!strcmp(argv[i], "-p2"))
  394. X        strncpy(p[2].player_name, argv[++i], 9);
  395. X    else if (!strcmp(argv[i], "-d2"))
  396. X        p[2].display_name = argv[++i];
  397. X    else if (!strcmp(argv[i], "-c2"))
  398. X        strncpy(p[2].color_name, argv[++i], 19);
  399. X    else if (!strcmp(argv[i], "-p3"))
  400. X        strncpy(p[3].player_name, argv[++i], 9);
  401. X    else if (!strcmp(argv[i], "-d3"))
  402. X        p[3].display_name = argv[++i];
  403. X    else if (!strcmp(argv[i], "-c3"))
  404. X        strncpy(p[3].color_name, argv[++i], 19);
  405. X    else if (!strcmp(argv[i], "-usage")) {
  406. X        syntax(argv[0]);
  407. X        exit(0);
  408. X    }
  409. X    else if (!strcmp(argv[i], "-debug"))
  410. X        debug = True;
  411. X
  412. X    else {
  413. X        syntax(argv[0]);
  414. X        exit(-1);
  415. X    }
  416. X    i++;
  417. X    }
  418. X}
  419. X
  420. X
  421. X
  422. X
  423. X/*****************************************************************************
  424. X *
  425. X *   Synopsis
  426. X *    Boolean LookUpColor(display, name, col, color_index)
  427. X *        Display *display;
  428. X *        char *name;
  429. X *        XColor *col;
  430. X *        unsigned long *color_index;    return
  431. X *
  432. X *   Arguments
  433. X *    display         specifies a connection to an X server;
  434. X *    name         a string for color;
  435. X *    col         returns XColor structure of the named color;
  436. X *    color_index  returns the pixel value representing the named color,
  437. X *             which is actually an index to the colormap;
  438. X *
  439. X *   Return values
  440. X *    True on success
  441. X *    False on failing to allocate the named color
  442. X *
  443. X ****************************************************************************/
  444. X
  445. XBoolean LookUpColor(display, name, col, color_index)
  446. XDisplay *display;
  447. Xchar *name;
  448. XXColor *col;
  449. Xunsigned long *color_index;
  450. X{
  451. X  XColor xcolor;
  452. X
  453. X  if(XAllocNamedColor(display, DefaultColormap(display, DefaultScreen(display)),
  454. X        name,  col, &xcolor) == 0) {
  455. X    printf("LookUpColor: could not allocate %s.\n", name);
  456. X    return(False);
  457. X  } 
  458. X  *color_index = col->pixel;
  459. X  return(True);
  460. X}
  461. X
  462. X
  463. X/*********************************************************************
  464. X*
  465. X*   Synopsis
  466. X*    connect_display()
  467. X*
  468. X*   Description
  469. X*    connect to displays and create windows.
  470. X*
  471. X**********************************************************************/
  472. X
  473. X
  474. Xstatic void
  475. Xconnect_display()
  476. X{
  477. X    Display *dpy;
  478. X    Pixmap background;
  479. X    int i, j;
  480. X    char err_msg[100];
  481. X    XSetWindowAttributes attr;
  482. X    unsigned long fg, bg;
  483. X    XSizeHints size_hints;
  484. X    char *win_name, *icon_name;
  485. X    XGCValues values;
  486. X    XColor color;
  487. X
  488. X    XtToolkitInitialize();
  489. X    app_context = XtCreateApplicationContext();
  490. X
  491. X    values.foreground = 0;
  492. X    values.background = 1;
  493. X
  494. X    win_name = (char *)malloc(40);
  495. X
  496. X    for (i=0; i<4; i++) {
  497. X    if (!(p[i].dis=XtOpenDisplay(app_context, p[i].display_name, "x4war",
  498. X        "x4war", 0, 0, &global_argc, global_argv))) {
  499. X        sprintf(err_msg, "can not open display %s",
  500. X            XDisplayName(p[i].display_name));
  501. X        fatal_error(err_msg);
  502. X    }
  503. X    dpy = p[i].dis;
  504. X    p[i].scr = DefaultScreen(dpy);
  505. X
  506. X    attr.border_pixel = BlackPixel(dpy, p[i].scr);
  507. X
  508. X    p[i].win = XCreateWindow(dpy, RootWindow(dpy,p[i].scr), 
  509. X            0, 0, DIMENSION, DIMENSION, 4, CopyFromParent, 
  510. X            InputOutput, CopyFromParent, CWBorderPixel, &attr);
  511. X
  512. X    if (!LookUpColor(dpy, DEFAULT_BOARD_BG, &color, &bg))
  513. X        bg = WhitePixel(dpy, p[i].scr);
  514. X    if (!LookUpColor(dpy, DEFAULT_BOARD_FG, &color, &fg))
  515. X        fg = BlackPixel(dpy, p[i].scr);
  516. X    background = XCreatePixmapFromBitmapData(dpy, p[i].win,
  517. X        war_background_bits, war_background_width,
  518. X        war_background_height, fg, bg,
  519. X        DefaultDepth(dpy, p[i].scr));
  520. X
  521. X    XSetWindowBackgroundPixmap(dpy, p[i].win, background);
  522. X
  523. X    XFreePixmap(dpy, background);
  524. X
  525. X    sprintf(win_name, "x4war  player %s", p[i].player_name);
  526. X    icon_name = p[i].player_name;
  527. X    p[i].icon_pixmap = XCreateBitmapFromData(dpy, p[i].win, war_logo_bits,
  528. X        war_logo_width, war_logo_height);
  529. X
  530. X    size_hints.flags = PPosition | PSize | PMinSize;
  531. X    size_hints.min_width = DIMENSION;
  532. X    size_hints.min_height = DIMENSION;
  533. X    {
  534. X    XWMHints wm_hints;
  535. X    XClassHint class_hints;
  536. X
  537. X    XTextProperty windowName, iconName;
  538. X
  539. X    if (XStringListToTextProperty(&win_name, 1, &windowName) == 0)
  540. X        fatal_error("structure allocation for windowName failed.");
  541. X    if (XStringListToTextProperty(&icon_name, 1, &iconName) == 0)
  542. X        fatal_error("structure allocation for iconName failed.");        
  543. X
  544. X    wm_hints.initial_state = NormalState;
  545. X    wm_hints.input = True;
  546. X    wm_hints.icon_pixmap = p[i].icon_pixmap;
  547. X    wm_hints.flags = StateHint | IconPixmapHint | InputHint;
  548. X
  549. X    class_hints.res_name = progname;
  550. X    class_hints.res_class = "X4war";
  551. X
  552. X    XSetWMProperties(dpy, p[i].win, &windowName, &iconName, 
  553. X            global_argv, global_argc, &size_hints, &wm_hints, 
  554. X            &class_hints);
  555. X    }
  556. X
  557. X    XSelectInput(dpy, p[i].win, ExposureMask | KeyPressMask | 
  558. X            ButtonPressMask | ButtonReleaseMask);
  559. X
  560. X    if (!LookUpColor(dpy, p[i].color_name, &(p[i].fg_color), &(p[i].fg[i])))
  561. X        p[i].fg[i] = BlackPixel(dpy, p[i].scr);
  562. X
  563. X    for (j=0; j<4; j++)
  564. X        if (j != i)
  565. X        if (!LookUpColor(dpy, p[j].color_name, &color, &(p[i].fg[j])))
  566. X            p[i].fg[j] = BlackPixel(dpy, p[i].scr);
  567. X
  568. X    p[i].gc = XCreateGC(dpy, p[i].win, 0, NULL);
  569. X    XSetBackground(dpy, p[i].gc, WhitePixel(dpy, p[i].scr));
  570. X    XSetFont(dpy, p[i].gc, XLoadFont(dpy, "9x15bold"));
  571. X    XSetLineAttributes(dpy, p[i].gc, 2, LineSolid, CapButt, JoinRound);
  572. X
  573. X    p[i].node[0] = XCreateBitmapFromData(dpy, p[i].win, colours_bits,
  574. X        colours_width, colours_height);
  575. X    p[i].node[1] = XCreateBitmapFromData(dpy, p[i].win, sapper_bits,
  576. X        sapper_width, sapper_height);
  577. X    p[i].node[2] = XCreateBitmapFromData(dpy, p[i].win, f_lieutenant_bits,
  578. X        f_lieutenant_width, f_lieutenant_height);
  579. X    p[i].node[3] = XCreateBitmapFromData(dpy, p[i].win, captain_bits,
  580. X        captain_width, captain_height);
  581. X    p[i].node[4] = XCreateBitmapFromData(dpy, p[i].win, major_bits,
  582. X        major_width, major_height);
  583. X    p[i].node[5] = XCreateBitmapFromData(dpy, p[i].win, colonel_bits,
  584. X        colonel_width, colonel_height);
  585. X    p[i].node[6] = XCreateBitmapFromData(dpy, p[i].win, brigadier_bits,
  586. X        brigadier_width, brigadier_height);
  587. X    p[i].node[7] = XCreateBitmapFromData(dpy, p[i].win, m_general_bits,
  588. X        m_general_width, m_general_height);
  589. X    p[i].node[8] = XCreateBitmapFromData(dpy, p[i].win, general_bits,
  590. X        general_width, general_height);
  591. X    p[i].node[9] = XCreateBitmapFromData(dpy, p[i].win, marshal_bits,
  592. X        marshal_width, marshal_height);
  593. X    p[i].node[10] = XCreateBitmapFromData(dpy, p[i].win, mine_bits,
  594. X        mine_width, mine_height);
  595. X    p[i].node[11] = XCreateBitmapFromData(dpy, p[i].win, bomb_bits,
  596. X        bomb_width, bomb_height);
  597. X
  598. X    if (i != 0)
  599. X        p[i].node[12] = XCreateBitmapFromData(dpy, p[i].win,
  600. X            back0_bits, back0_width, back0_height);
  601. X    if (i != 1)
  602. X        p[i].node[13] = XCreateBitmapFromData(dpy, p[i].win,
  603. X            back1_bits, back1_width, back1_height);
  604. X    if (i != 2)
  605. X        p[i].node[14] = XCreateBitmapFromData(dpy, p[i].win,
  606. X            back2_bits, back2_width, back2_height);
  607. X    if (i != 3)
  608. X        p[i].node[15] = XCreateBitmapFromData(dpy, p[i].win,
  609. X            back3_bits, back3_width, back3_height);
  610. X
  611. X    p[i].node[12+i] = XCreateBitmapFromData(dpy, p[i].win,
  612. X            cursor_bits, cursor_width, cursor_height);
  613. X    p[i].cursormask_pixmap = XCreateBitmapFromData(dpy, p[i].win,
  614. X            cursormask_bits, cursormask_width, cursormask_height);
  615. X    LookUpColor(dpy, "White", &(p[i].bg_color), &bg);
  616. X    p[i].cursor = XCreatePixmapCursor(dpy, p[i].node[i+12],
  617. X        p[i].cursormask_pixmap, &(p[i].fg_color), &(p[i].bg_color),
  618. X        cursor_x_hot, cursor_y_hot);
  619. X    XDefineCursor(dpy, p[i].win, p[i].cursor);
  620. X
  621. X    p[i].confirm = XCreateSimpleWindow(dpy, p[i].win, 400, 400, 300, 120, 4,
  622. X        BlackPixel(dpy, p[i].scr), WhitePixel(dpy, p[i].scr));
  623. X    XSelectInput(dpy, p[i].confirm, ExposureMask | ButtonPressMask);
  624. X
  625. X    p[i].nodemask_pixmap = XCreateBitmapFromData(dpy, p[i].win,
  626. X        nodemask_bits, nodemask_width, nodemask_height);
  627. X    p[i].stop_pixmap = XCreateBitmapFromData(dpy, p[i].win, stop_bits,
  628. X        stop_width, stop_height);
  629. X    p[i].go_pixmap = XCreateBitmapFromData(dpy, p[i].win, go_bits,
  630. X        go_width, go_height);
  631. X    }
  632. X}
  633. X
  634. X
  635. X/************************************************************************
  636. X*
  637. X*   Synopsis
  638. X*    initial_board()
  639. X*
  640. X*   Description
  641. X*    set for a new game
  642. X*
  643. X************************************************************************/
  644. Xstatic void
  645. Xinitial_board()
  646. X{
  647. X    int i, j, k;
  648. X
  649. X
  650. X    for (i=0; i<4; i++)
  651. X     for (j=0; j<6; j++)
  652. X      for (k=0; k<5; k++) {
  653. X    arr[i][j][k].value = EMPTY;
  654. X    arr[i][j][k].id = i;
  655. X    }
  656. X
  657. X    for (i=0; i<3; i++)
  658. X      for (j=0; j<3; j++)
  659. X    mid[i][j].value = EMPTY;
  660. X
  661. X
  662. X    for (i=0; i<4; i++) {
  663. X    p[i].rip_index = 0;
  664. X    p[i].state = 1;
  665. X    p[i].num_movable = 21;
  666. X    p[i].popup = 0;
  667. X    p[i].pick.picked = False;
  668. X    p[i].marshal_dead = False;
  669. X    p[i].talk_msg[0][0] = p[i].talk_msg[1][0] = p[i].talk_msg[2][0] = '\0';
  670. X    p[i].talk_col = 0;
  671. X
  672. X    if (debug) {
  673. X        arr[i][0][0].value = MARSHAL;
  674. X        arr[i][0][1].value = GENERAL;
  675. X        arr[i][0][2].value = M_GENERAL;
  676. X        arr[i][0][3].value = M_GENERAL;
  677. X        arr[i][0][4].value = BRIGADIER;
  678. X        arr[i][1][0].value = BRIGADIER;
  679. X        arr[i][1][2].value = COLONEL;
  680. X        arr[i][1][4].value = COLONEL;
  681. X        arr[i][2][0].value = MAJOR;
  682. X        arr[i][2][1].value = MAJOR;
  683. X        arr[i][2][3].value = CAPTAIN;
  684. X        arr[i][2][4].value = CAPTAIN;
  685. X        arr[i][3][0].value = CAPTAIN;
  686. X        arr[i][3][2].value = F_LIEUTENANT;
  687. X        arr[i][3][4].value = F_LIEUTENANT;
  688. X        arr[i][4][0].value = F_LIEUTENANT;
  689. X        arr[i][4][1].value = SAPPER;
  690. X        arr[i][4][2].value = SAPPER;
  691. X        arr[i][4][3].value = SAPPER;
  692. X        arr[i][4][4].value = BOMB;
  693. X        arr[i][5][0].value = BOMB;
  694. X        arr[i][5][1].value = COLOURS;
  695. X        arr[i][5][2].value = MINE;
  696. X        arr[i][5][3].value = MINE;
  697. X        arr[i][5][4].value = MINE;
  698. X
  699. X        for (j=0; j<5; j++)
  700. X          for (k=0; k<5; k++)
  701. X        p[i].rip[j][k] = EMPTY;
  702. X    }
  703. X
  704. X      else  {
  705. X    p[i].rip[0][0] = COLOURS;
  706. X    p[i].rip[0][1] = MARSHAL;
  707. X    p[i].rip[0][2] = GENERAL;
  708. X    p[i].rip[0][3] = M_GENERAL;
  709. X    p[i].rip[0][4] = M_GENERAL;
  710. X    p[i].rip[1][0] = BRIGADIER;
  711. X    p[i].rip[1][1] = BRIGADIER;
  712. X    p[i].rip[1][2] = COLONEL;
  713. X    p[i].rip[1][3] = COLONEL;
  714. X    p[i].rip[1][4] = MAJOR;
  715. X    p[i].rip[2][0] = MAJOR;
  716. X    p[i].rip[2][1] = CAPTAIN;
  717. X    p[i].rip[2][2] = CAPTAIN;
  718. X    p[i].rip[2][3] = CAPTAIN;
  719. X    p[i].rip[2][4] = F_LIEUTENANT;
  720. X    p[i].rip[3][0] = F_LIEUTENANT;
  721. X    p[i].rip[3][1] = F_LIEUTENANT;
  722. X    p[i].rip[3][2] = SAPPER;
  723. X    p[i].rip[3][3] = SAPPER;
  724. X    p[i].rip[3][4] = SAPPER;
  725. X    p[i].rip[4][0] = MINE;
  726. X    p[i].rip[4][1] = MINE;
  727. X    p[i].rip[4][2] = MINE;
  728. X    p[i].rip[4][3] = BOMB;
  729. X    p[i].rip[4][4] = BOMB;
  730. X      }
  731. X
  732. X    }
  733. X
  734. X    num_player = 4;
  735. X    mode = 0;
  736. X}
  737. X
  738. X
  739. X
  740. X
  741. X
  742. X
  743. X/*********************************************************************
  744. X*
  745. X*   Synopsis
  746. X*    int whichplayer(display)
  747. X*        Display *display;
  748. X*
  749. X*   Return values
  750. X*    0 - 4    according to whom the display belongs
  751. X*
  752. X**********************************************************************/
  753. X
  754. Xint whichplayer(display)
  755. XDisplay *display;
  756. X{
  757. X    int i;
  758. X
  759. X    for (i=0; i<4; i++)
  760. X    if (display == p[i].dis)  return(i);
  761. X}
  762. X
  763. X
  764. X
  765. X/**********************************************************************
  766. X*
  767. X*   Synopsis
  768. X*    put_msg(s1, s2)
  769. X*        char *s1, *s2;
  770. X*
  771. X*   Description
  772. X*    put the two strings into the global msg1 and msg2, and draw them
  773. X*    on the board.
  774. X*
  775. X***********************************************************************/
  776. X
  777. Xstatic void
  778. Xput_msg(s1, s2)
  779. Xchar *s1, *s2;
  780. X{
  781. X    int i;
  782. X
  783. X    strncpy(msg1, s1, MAX_MSG);
  784. X    strncpy(msg2, s2, MAX_MSG);
  785. X
  786. X    for (i=0; i<4; i++)
  787. X    if (p[i].state != 3) {
  788. X        XClearArea(p[i].dis, p[i].win, MSG_BOX_X, MSG_BOX_Y,
  789. X        MSG_WIDTH, MSG_HEIGHT, False);
  790. X        XSetForeground(p[i].dis, p[i].gc, p[i].fg[i]);
  791. X        XDrawString(p[i].dis, p[i].win, p[i].gc, MSG_X, MSG_Y,
  792. X        msg1, strlen(msg1));
  793. X        XDrawString(p[i].dis, p[i].win, p[i].gc, MSG_X, MSG_Y+25,
  794. X        msg2, strlen(msg2));
  795. X    }
  796. X}
  797. X
  798. X
  799. X
  800. X/*********************************************************************
  801. X*
  802. X*   Synopsis
  803. X*    send_expose_event()
  804. X*
  805. X*   Description
  806. X*    send an expose event to all active players
  807. X*
  808. X*********************************************************************/
  809. X
  810. Xstatic void
  811. Xsend_expose_event()
  812. X{
  813. X    XEvent event;
  814. X    int n;
  815. X
  816. X    event.xexpose.x = event.xexpose.y = 0;
  817. X    event.xexpose.width = event.xexpose.height = DIMENSION;
  818. X    for (n=0; n<4; n++)
  819. X    if (p[n].state != 3)
  820. X        refresh_board(n, &event);
  821. X}
  822. X
  823. X
  824. X
  825. X
  826. X/**********************************************************************
  827. X*
  828. X*   Synopsis
  829. X*    redraw_confirm(i)
  830. X*        int i;
  831. X*
  832. X*   Argument
  833. X*    i    specifies which player;
  834. X*
  835. X*   Description
  836. X*    redraws the confirmation window, with confirm_msg displayed.
  837. X*
  838. X***********************************************************************/
  839. X
  840. Xstatic void
  841. Xredraw_confirm(i)
  842. Xint i;
  843. X{
  844. X    XSetForeground(p[i].dis, p[i].gc, BlackPixel(p[i].dis, p[i].scr));
  845. X    XDrawRectangle(p[i].dis, p[i].confirm, p[i].gc, 3, 3, 293, 113);
  846. X    if (p[i].popup == 3)
  847. X    XDrawRectangle(p[i].dis, p[i].confirm, p[i].gc, 100, 75, 99, 19);
  848. X    else {
  849. X    XDrawRectangle(p[i].dis, p[i].confirm, p[i].gc, 80, 75, 39, 19);
  850. X    XDrawRectangle(p[i].dis, p[i].confirm, p[i].gc, 180, 75, 39, 19);
  851. X    }
  852. X
  853. X    XSetForeground(p[i].dis, p[i].gc, p[i].fg[i]);
  854. X    if (p[i].popup == 3)
  855. X    XDrawString(p[i].dis, p[i].confirm, p[i].gc, 110, 90, "CONTINUE", 8);
  856. X    else {
  857. X    XDrawString(p[i].dis, p[i].confirm, p[i].gc, 90, 90, "OK", 2);
  858. X    XDrawString(p[i].dis, p[i].confirm, p[i].gc, 190, 90, "NO", 2);
  859. X    }
  860. X    XDrawString(p[i].dis, p[i].confirm, p[i].gc, 30, 40, confirm_msg,
  861. X        strlen(confirm_msg));
  862. X}
  863. X
  864. X
  865. X
  866. X
  867. X/**********************************************************************
  868. X*
  869. X*   Synopsis
  870. X*    Boolean valid_deploy(i)
  871. X*        int i;
  872. X*
  873. X*   Description
  874. X*    check if player i's initial deploy is valid.
  875. X*
  876. X***********************************************************************/
  877. X
  878. XBoolean valid_deploy(i)
  879. Xint i;
  880. X{
  881. X    int m, n, k;
  882. X
  883. X    if (arr[i][5][1].value != COLOURS && arr[i][5][3].value != COLOURS)
  884. X    return(False);
  885. X    if (arr[i][1][1].value != EMPTY || arr[i][1][3].value != EMPTY ||
  886. X    arr[i][2][2].value != EMPTY || arr[i][3][1].value != EMPTY ||
  887. X    arr[i][3][3].value != EMPTY)
  888. X      return(False);
  889. X
  890. X    k = 0;
  891. X    for (m=4; m<6; m++)
  892. X      for (n=0; n<5; n++)
  893. X    if (arr[i][m][n].value == MINE) k++;
  894. X    if (k<3)  return(False);
  895. X
  896. X    for (m=0; m<5; m++)
  897. X      for (n=0; n<5; n++)
  898. X    if (p[i].rip[m][n] != EMPTY)  return(False);
  899. X
  900. X    if (arr[i][5][1].value != MINE && arr[i][5][3].value != MINE)
  901. X    p[i].num_movable--; 
  902. X    return(True);
  903. X}
  904. X
  905. X
  906. X
  907. X
  908. X
  909. X/***********************************************************************
  910. X*
  911. X*   Synopsis
  912. X*    peace_request(i)
  913. X*        int i;
  914. X*
  915. X*   Description
  916. X*    player i request for peace, this can only happen in play mode 1.
  917. X*
  918. X************************************************************************/
  919. X
  920. Xstatic void
  921. Xpeace_request(i)
  922. Xint i;
  923. X{
  924. X    int n;
  925. X
  926. X    mode = 2;
  927. X
  928. X    for (n=0; n<4; n++)
  929. X      if (n != i && p[n].state == 2) {
  930. X    p[n].popup = 1;
  931. X    sprintf(confirm_msg, "%s requesting peace", p[i].player_name);
  932. X    XMapWindow(p[n].dis, p[n].confirm);
  933. X      }
  934. X}
  935. X
  936. X
  937. X
  938. X/********************************************************************
  939. X*
  940. X*   Synopsis
  941. X*    lost_war(i)
  942. X*        int i;
  943. X*
  944. X*   Description
  945. X*    player i lost the war, if he/she's partner has lost too, change
  946. X*    mode to 3; else, just update the playing array and send an expose
  947. X*    event.
  948. X*
  949. X**********************************************************************/
  950. X
  951. Xstatic void
  952. Xlost_war(i)
  953. Xint i;
  954. X{
  955. X    int n, j, k;
  956. X
  957. X    p[i].state = 0;
  958. X    num_player--;
  959. X    if (p[(i+2)%4].state != 2) {
  960. X    put_msg(p[i].player_name, "and my ally lost!");
  961. X    sprintf(confirm_msg, "%s and %s lost!", p[i].player_name,
  962. X        p[(i+2)%4].player_name);
  963. X    for (n=0; n<4; n++)
  964. X        if (p[n].state != 3) {
  965. X        XBell(p[n].dis, 0);
  966. X        p[n].popup = 3;
  967. X        XMapWindow(p[n].dis, p[n].confirm);
  968. X        p[n].state = 0;
  969. X        }
  970. X    mode = 3;
  971. X    send_expose_event();
  972. X    }
  973. X    else {
  974. X    for (n=0; n<4; n++)
  975. X     for (j=0; j<6; j++)
  976. X      for (k=0; k<5; k++)
  977. X        if (arr[n][j][k].value != EMPTY  && arr[n][j][k].id == i) {
  978. X        p[i].rip[p[i].rip_index/5][p[i].rip_index%5] =
  979. X            arr[n][j][k].value;
  980. X        p[i].rip_index++;
  981. X        arr[n][j][k].value = EMPTY;
  982. X        }
  983. X    for (n=0; n<3; n++)
  984. X      for (j=0; j<3; j++)
  985. X        if (mid[n][j].value != EMPTY && mid[n][j].id == i) {
  986. X        p[i].rip[p[i].rip_index/5][p[i].rip_index%5] = mid[n][j].value;
  987. X        p[i].rip_index++;
  988. X        mid[n][j].value = EMPTY;
  989. X        }
  990. X    send_expose_event();
  991. X    }
  992. X}
  993. X
  994. X
  995. X
  996. X
  997. X
  998. X/***********************************************************************
  999. X*
  1000. X*   Synopsis
  1001. X*    new_game()
  1002. X*
  1003. X*   Description
  1004. X*    it clear the board and start a new game, or quit if someone has gone.
  1005. X*
  1006. X************************************************************************/
  1007. X
  1008. Xstatic void
  1009. Xnew_game()
  1010. X{
  1011. X    int i, j, k;
  1012. X
  1013. X    for (i=0; i<4; i++)
  1014. X    if (p[i].state == 3) {    /* someone has already quit */
  1015. X        for (k=0; k<4; k++) {
  1016. X        XFreeCursor(p[k].dis, p[k].cursor);
  1017. X        XFreeGC(p[k].dis, p[k].gc);
  1018. X        for (j=0; j<16; j++)
  1019. X            XFreePixmap(p[k].dis, p[k].node[j]);
  1020. X        XFreePixmap(p[k].dis, p[k].cursormask_pixmap);
  1021. X        XFreePixmap(p[k].dis, p[k].icon_pixmap);
  1022. X        XFreePixmap(p[k].dis, p[k].go_pixmap);
  1023. X        XFreePixmap(p[k].dis, p[k].stop_pixmap);
  1024. X        }
  1025. X        exit(0);
  1026. X    }
  1027. X
  1028. X    for (i=0; i<4; i++) {
  1029. X    if (p[i].popup != 0) {
  1030. X        p[i].popup = 0;
  1031. X        XUnmapWindow(p[i].dis, p[i].confirm);
  1032. X    }
  1033. X    XClearArea(p[i].dis, p[i].win, 0, 0, DIMENSION, DIMENSION, False);
  1034. X    }
  1035. X    initial_board();
  1036. X    put_msg("New War", "deploy first");
  1037. X    send_expose_event();
  1038. X}
  1039. X
  1040. X
  1041. X
  1042. X
  1043. X
  1044. X/************************************************************************
  1045. X*
  1046. X*   Synopsis
  1047. X*    putsign(i, flag)
  1048. X*        int i, flag;
  1049. X*
  1050. X*   Arguments
  1051. X*    i    specifies which player's board;
  1052. X*    flag    0 or 1,  0 to put stop sign, and 1 to put go ahead sign
  1053. X*
  1054. X*   Description
  1055. X*    it puts stop or go-ahead signs in the sign box.
  1056. X*
  1057. X*************************************************************************/
  1058. X
  1059. Xstatic void
  1060. Xputsign(i, flag)
  1061. Xint i, flag;
  1062. X{
  1063. X    XSetForeground(p[i].dis, p[i].gc, p[i].fg[i]);
  1064. X    if (flag)
  1065. X    XCopyPlane(p[i].dis, p[i].go_pixmap, p[i].win, p[i].gc, 0, 0,
  1066. X        SIGN_DIMENSION, SIGN_DIMENSION, P1+2, P1+2, 1);
  1067. X    else
  1068. X    XCopyPlane(p[i].dis, p[i].stop_pixmap, p[i].win, p[i].gc, 0, 0,
  1069. X        SIGN_DIMENSION, SIGN_DIMENSION, P1+2, P1+2, 1);
  1070. X}
  1071. X
  1072. X
  1073. X
  1074. X
  1075. X/***********************************************************************
  1076. X*
  1077. X*   Synopsis
  1078. X*    putnode(i, value, x, y)
  1079. X*        int i, value, x, y;
  1080. X*
  1081. X*   Arguments
  1082. X*    i    specifies player i's board;
  1083. X*    value    -1 -- 15, means clear or an index to the node image;
  1084. X*    x, y    coordinates of the center of the node on the board;
  1085. X*
  1086. X*   Description
  1087. X*    it draws the image indicated by value at position (x,y) on
  1088. X*    player i's board.
  1089. X*    if value is -1, it clear the positioned area.
  1090. X*    the foreground of the gc should be set before hand.
  1091. X*    the image is drawn at (x-20, y-20) with width and height of
  1092. X*    both 40.
  1093. X*
  1094. X************************************************************************/
  1095. X
  1096. Xstatic void
  1097. Xputnode(i, value, x, y)
  1098. Xint i, value, x, y;
  1099. X{
  1100. X    if (value == -1)
  1101. X    XClearArea(p[i].dis, p[i].win, x-20, y-20, 40, 40, False);
  1102. X    else
  1103. X    XCopyPlane(p[i].dis, p[i].node[value], p[i].win, p[i].gc, 0, 0,
  1104. X        40, 40, x-20, y-20, 1);
  1105. X}
  1106. X
  1107. X
  1108. X
  1109. X
  1110. X/************************************************************************
  1111. X*
  1112. X*   Synopsis
  1113. X*    putarea(i, x1, y1, x2, y2)
  1114. X*        int i, x1, y1, x2, y2)
  1115. X*
  1116. X*   Description
  1117. X*    redraw an area of (x1, y1), (x2, y2) on player i's board.
  1118. X*    the coordinates are for the board but within the area of F0-F3
  1119. X*    and MIDFIELD.
  1120. X*
  1121. X*************************************************************************/
  1122. X
  1123. Xputarea(i, x1, y1, x2, y2)
  1124. Xint i, x1, y1, x2, y2;
  1125. X{
  1126. X    int f, k, l, m, n, a1, b1, a2, b2, c, d;
  1127. X
  1128. X    boardtoarr(i, x1, y1, &a1, &b1);
  1129. X    f = boardtoarr(i, x2, y2, &a2, &b2);
  1130. X
  1131. X    if (a1 > a2) {
  1132. X    k = a1;  a1 = a2;  a2 = k;
  1133. X    }
  1134. X    if (b1 > b2) {
  1135. X    k = b1;  b1 = b2;  b2 = k;
  1136. X    }
  1137. X
  1138. X    for (m=a1; m<=a2; m++)
  1139. X      for (n=b1; n<=b2; n++) {
  1140. X    if (f == MIDFIELD) {
  1141. X        k = mid[m][n].value;
  1142. X        l = mid[m][n].id;
  1143. X    }
  1144. X    else {
  1145. X        k = arr[f][m][n].value;
  1146. X        l = arr[f][m][n].id;
  1147. X    }
  1148. X    XSetForeground(p[i].dis, p[i].gc, p[i].fg[l]);
  1149. X
  1150. X    if (k != EMPTY && l != i && p[i].state != 0 &&
  1151. X        !(k==COLOURS && p[f].marshal_dead) )  k = l + 12;
  1152. X    arrtoboard(i, f, m, n, &c, &d);
  1153. X    putnode(i, k, c, d);
  1154. X      }
  1155. X}
  1156. X
  1157. X
  1158. X
  1159. X
  1160. X/************************************************************************
  1161. X*
  1162. X*   Synopsis
  1163. X*    refresh_board(i, event)
  1164. X*        int i;
  1165. X*        XEvent *event;
  1166. X*
  1167. X*   Description
  1168. X*    refresh player i's board according to the expose event.
  1169. X*
  1170. X**************************************************************************/
  1171. X
  1172. Xstatic void
  1173. Xrefresh_board(i, event)
  1174. Xint i;
  1175. XXEvent *event;
  1176. X{
  1177. X    int x1, y1, x2, y2;
  1178. X    int a1, b1, a2, b2;
  1179. X    int c1, d1, c2, d2;
  1180. X    int flag, m, n;
  1181. X    char s[35];
  1182. X
  1183. X    x1 = event->xexpose.x;
  1184. X    y1 = event->xexpose.y;
  1185. X    x2 = x1 + event->xexpose.width;
  1186. X    y2 = y1 + event->xexpose.height;
  1187. X
  1188. X
  1189. X    flag = area_intersection(P1, P1, P2, P2, x1,y1, x2,y2, &a1, &b1, &a2, &b2);
  1190. X    if (flag) {
  1191. X    XSetForeground(p[i].dis, p[i].gc, p[i].fg[i]);
  1192. X    if (mode == 0 || mode == 3 || turn != i)
  1193. X        putsign(i, 0);
  1194. X    else putsign(i, 1);
  1195. X
  1196. X    XClearArea(p[i].dis, p[i].win, TALK_L_X, TALK_Y, TALK_WIDTH, 150,False);
  1197. X
  1198. X    XSetForeground(p[i].dis, p[i].gc, p[i].fg[0]);
  1199. X    sprintf(s, "PLAYER 0  (%s)", p[0].player_name);
  1200. X    XDrawString(p[i].dis, p[i].win,p[i].gc, TALK0_X, TALK_Y-5, s,strlen(s));
  1201. X    n = TALK0_Y;
  1202. X    for (m=0; m<3; m++) {
  1203. X        XDrawString(p[i].dis, p[i].win, p[i].gc, TALK0_X, n,
  1204. X            p[0].talk_msg[m], strlen(p[0].talk_msg[m]));
  1205. X        n += TALK_Y_INC;
  1206. X    }
  1207. X
  1208. X    XSetForeground(p[i].dis, p[i].gc, p[i].fg[2]);
  1209. X    sprintf(s, "PLAYER 2  (%s)", p[2].player_name);
  1210. X    XDrawString(p[i].dis, p[i].win,p[i].gc, TALK2_X,TALK_Y+85, s,strlen(s));
  1211. X    n = TALK2_Y;
  1212. X    for (m=0; m<3; m++) {
  1213. X        XDrawString(p[i].dis, p[i].win, p[i].gc, TALK2_X, n,
  1214. X            p[2].talk_msg[m], strlen(p[2].talk_msg[m]));
  1215. X        n += TALK_Y_INC;
  1216. X    }
  1217. X    }
  1218. X
  1219. X    flag = area_intersection(P5, P1, P6, P2, x1,y1, x2,y2, &a1, &b1, &a2, &b2);
  1220. X    if (flag) {
  1221. X    XSetForeground(p[i].dis, p[i].gc, p[i].fg[i]);
  1222. X    XClearArea(p[i].dis, p[i].win, MSG_BOX_X, MSG_BOX_Y,
  1223. X            MSG_WIDTH, MSG_HEIGHT, False);
  1224. X    XDrawString(p[i].dis, p[i].win, p[i].gc, MSG_X, MSG_Y,
  1225. X        msg1, strlen(msg1));
  1226. X    XDrawString(p[i].dis, p[i].win, p[i].gc, MSG_X, MSG_Y+25,
  1227. X        msg2, strlen(msg2));
  1228. X
  1229. X    XSetForeground(p[i].dis, p[i].gc, p[i].fg[1]);
  1230. X    sprintf(s, "PLAYER 1  (%s)", p[1].player_name);
  1231. X    XDrawString(p[i].dis, p[i].win,p[i].gc, TALK1_X, TALK_Y-5, s,strlen(s));
  1232. X    n = TALK1_Y;
  1233. X    for (m=0; m<3; m++) {
  1234. X        XDrawString(p[i].dis, p[i].win, p[i].gc, TALK1_X, n,
  1235. X            p[1].talk_msg[m], strlen(p[1].talk_msg[m]));
  1236. X        n += TALK_Y_INC;
  1237. X    }
  1238. X
  1239. X    XSetForeground(p[i].dis, p[i].gc, p[i].fg[3]);
  1240. X    sprintf(s, "PLAYER 3  (%s)", p[3].player_name);
  1241. X    XDrawString(p[i].dis, p[i].win,p[i].gc, TALK3_X,TALK_Y+85, s,strlen(s));
  1242. X    n = TALK3_Y;
  1243. X    for (m=0; m<3; m++) {
  1244. X        XDrawString(p[i].dis, p[i].win, p[i].gc, TALK3_X, n,
  1245. X            p[3].talk_msg[m], strlen(p[3].talk_msg[m]));
  1246. X        n += TALK_Y_INC;
  1247. X    }
  1248. X    }
  1249. X
  1250. X    flag = area_intersection(P1+5, RIP_Y+5, P1+RIP_DIMENSION-5,
  1251. X    RIP_Y+RIP_DIMENSION-5, x1, y1, x2, y2, &a1, &b1, &a2, &b2);
  1252. X    if (flag) {
  1253. X    boardtofield(a1, b1, &c1, &d1);
  1254. X    boardtofield(a2, b2, &c2, &d2);
  1255. X    XSetForeground(p[i].dis, p[i].gc, p[i].fg[i]);
  1256. X    for (m=c1; m<=c2; m++)
  1257. X      for (n=d1; n<=d2; n++) {
  1258. X        fieldtoboard(RIP, m, n, &a1, &b1);
  1259. X        putnode(i, p[i].rip[m][n], a1, b1);
  1260. X      }
  1261. X    }
  1262. X
  1263. X/* refresh field 0 */
  1264. X    flag = area_intersection(P3-20, P5-20, P4+20, P6+20,
  1265. X        x1, y1, x2, y2, &a1, &b1, &a2, &b2);
  1266. X    if (flag)
  1267. X    putarea(i, a1, b1, a2, b2);
  1268. X
  1269. X    if (mode > 0) {
  1270. X    flag = area_intersection(P5-20, P3-20, P6+20, P4+20,
  1271. X        x1, y1, x2, y2, &a1, &b1, &a2, &b2);
  1272. X    if (flag)
  1273. X        putarea(i, a1, b1, a2, b2);
  1274. X
  1275. X        flag = area_intersection(P3-20, P1-20, P4+20, P2+20,
  1276. X        x1, y1, x2, y2, &a1, &b1, &a2, &b2);
  1277. X    if (flag)
  1278. X        putarea(i, a1, b1, a2, b2);
  1279. X
  1280. X        flag = area_intersection(P1-20, P3-20, P2+20, P4+20,
  1281. X        x1, y1, x2, y2, &a1, &b1, &a2, &b2);
  1282. X    if (flag)
  1283. X        putarea(i, a1, b1, a2, b2);
  1284. X
  1285. X        flag = area_intersection(P3-20, P3-20, P4+20, P4+20,
  1286. X        x1, y1, x2, y2, &a1, &b1, &a2, &b2);
  1287. X    if (flag)
  1288. X        putarea(i, a1, b1, a2, b2);
  1289. X    }
  1290. X}
  1291. X
  1292. X
  1293. X
  1294. X
  1295. X/**********************************************************************
  1296. X*
  1297. X*   Synopsis
  1298. X*    talk(i, flag, k)
  1299. X*        int i, flag;
  1300. X*        char k;
  1301. X*
  1302. X*   Arguments
  1303. X*    i    player i pressed a key;
  1304. X*    flag    0 - a printable key; 1 - a backspace; 2 - a Return key;
  1305. X*    k    the char if printable;
  1306. X*
  1307. X*   Description
  1308. X*    player i has pressed a key 'k', this function draws the character
  1309. X*    in the corresponding talking box.
  1310. X*
  1311. X************************************************************************/
  1312. X
  1313. Xstatic void
  1314. Xtalk(i, flag, k)
  1315. Xint i, flag;
  1316. Xchar k;
  1317. X{
  1318. X    int m;
  1319. X    static char s[] = {' ', '\0'};
  1320. X
  1321. X
  1322. X    if (flag == 1) {
  1323. X    if (p[i].talk_col == 0)   return;
  1324. X    s[0] = ' ';
  1325. X    p[i].talk_msg[2][p[i].talk_col] = '\0';
  1326. X    p[i].talk_col--;
  1327. X    for (m=0; m<4; m++)
  1328. X        if (p[m].state != 3)
  1329. X        XDrawImageString(p[m].dis, p[m].win, p[m].gc,
  1330. X            p[i].talk_x+p[i].talk_col*TALK_X_INC, p[i].talk_y,
  1331. X            s, 1);
  1332. X    return;
  1333. X    }
  1334. X
  1335. X    for (m=0; m<4; m++)
  1336. X    if (p[m].state != 3)
  1337. X        XSetForeground(p[m].dis, p[m].gc, p[m].fg[i]);
  1338. X
  1339. X    if (flag == 2 || p[i].talk_col >= MAX_MSG) {
  1340. X    strcpy(p[i].talk_msg[0], p[i].talk_msg[1]);
  1341. X    strcpy(p[i].talk_msg[1], p[i].talk_msg[2]);
  1342. X    p[i].talk_msg[2][0] = '\0';
  1343. X    p[i].talk_col = 0;
  1344. X    for (m=0; m<4; m++)
  1345. X        if (p[m].state != 3) {
  1346. X        XClearArea(p[m].dis, p[m].win, p[i].talk_x-5,
  1347. X            p[i].talk_y-2*TALK_Y_INC-15, TALK_WIDTH, TALK_HEIGHT,
  1348. X            False);
  1349. X
  1350. X        XDrawImageString(p[m].dis, p[m].win, p[m].gc,
  1351. X            p[i].talk_x, p[i].talk_y-2*TALK_Y_INC,
  1352. X            p[i].talk_msg[0], strlen(p[i].talk_msg[0]));
  1353. X        XDrawImageString(p[m].dis, p[m].win, p[m].gc,
  1354. X            p[i].talk_x, p[i].talk_y-TALK_Y_INC,
  1355. X            p[i].talk_msg[1], strlen(p[i].talk_msg[1]));
  1356. X        }
  1357. X    }
  1358. X    if (flag == 0) {
  1359. X    s[0] = k;
  1360. X    for (m=0; m<4; m++)
  1361. X        if (p[m].state != 3)
  1362. X        XDrawImageString(p[m].dis, p[m].win, p[m].gc,
  1363. X            p[i].talk_x+TALK_X_INC*p[i].talk_col,
  1364. X            p[i].talk_y, s, 1);
  1365. X    p[i].talk_msg[2][p[i].talk_col++] = k;
  1366. X    p[i].talk_msg[2][p[i].talk_col] = '\0';
  1367. X    }
  1368. X}
  1369. X
  1370. X
  1371. X
  1372. X
  1373. X
  1374. X
  1375. X
  1376. X/**********************************************************************
  1377. X*
  1378. X*   Synopsis
  1379. X*    int move(i, f, x, y)
  1380. X*        int i, f, x, y;
  1381. X*
  1382. X*   Argument
  1383. X*    i    0-3, specifies a move from p[i].pick;
  1384. X*    f    F0 -- RIP, the destination array;
  1385. X*    x, y    subscripts in the destination array;
  1386. X*
  1387. X*   Return values
  1388. X*    0    invalid move;
  1389. X*    1    no fight, just a move;
  1390. X*    2    source loses;
  1391. X*    3    tie;
  1392. X*    4    source win;
  1393. X*
  1394. X***********************************************************************/
  1395. X
  1396. Xint move(i, f, x, y)
  1397. Xint i, f, x, y;
  1398. X{
  1399. X    int m;
  1400. X
  1401. X    if (f == RIP)  return(0);
  1402. X    if (f == MIDFIELD) {
  1403. X    m = mid[x][y].value;
  1404. X    if (m != EMPTY && (mid[x][y].id==i || mid[x][y].id==(i+2)%4))
  1405. X        return(0);
  1406. X    }
  1407. X    else {
  1408. X    m = arr[f][x][y].value;
  1409. X    if (m != EMPTY && (arr[f][x][y].id==i || arr[f][x][y].id==(i+2)%4))
  1410. X        return(0);
  1411. X    if (m != EMPTY && ((x==1 && y==1) || (x==1 && y==3) || (x==2 && y==2)
  1412. X            || (x==3 && y==1) || (x==3 && y==3)))
  1413. X        return(0);
  1414. X    }
  1415. X
  1416. X    if (!valid_move(p[i].pick.arr, p[i].pick.x, p[i].pick.y, f, x, y))
  1417. X    return(0);
  1418. X
  1419. X    if (x==5 && (y==1 || y==3))
  1420. X     return ((m==COLOURS) ? 3 : 2);
  1421. X    if (m == EMPTY)  return(1);
  1422. X    return(fight(p[i].pick.value, m));
  1423. X}
  1424. X
  1425. X
  1426. X
  1427. X
  1428. X/************************************************************************
  1429. X*
  1430. X*   Synopsis
  1431. X*    Boolean lose_check(i, v)
  1432. X*        int i, v;
  1433. X*
  1434. X*   Return values
  1435. X*    True    if defeated;
  1436. X*    False    otherwise;
  1437. X*
  1438. X*   Description
  1439. X*    player i has just lost a node valued v, this function checks if:
  1440. X*        it is the COLOURS, then declares defeated;
  1441. X*        it is the MARSHAL, then its COLOURS is showed face up on all
  1442. X*        boards;
  1443. X*        the player has no moving nodes avaliable, then declares defeated.
  1444. X*    the last case is not implemented.
  1445. X*
  1446. X***************************************************************************/
  1447. X
  1448. XBoolean lose_check(i, v)
  1449. Xint i, v;
  1450. X{
  1451. X    int m, k, b, c;
  1452. X
  1453. X    if (v == COLOURS)
  1454. X    return(True);
  1455. X    if (v == MARSHAL) {
  1456. X    p[i].marshal_dead = True;
  1457. X    m = (arr[i][5][1].value == COLOURS) ? 1 : 3;
  1458. X    for (k=0; k<4; k++)
  1459. X        if (p[k].state != 3) {
  1460. X        XSetForeground(p[k].dis, p[k].gc, p[k].fg[i]);
  1461. X        arrtoboard(k, i, 5, m, &b, &c);
  1462. X        putnode(k, COLOURS, b, c);
  1463. X        }
  1464. X    }
  1465. X    if ((--p[i].num_movable)==0)  return(True);
  1466. X    return(False);
  1467. X}
  1468. X
  1469. X
  1470. X
  1471. X
  1472. X
  1473. X/***********************************************************************
  1474. X*
  1475. X*   Synopsis
  1476. X*    return_rip(i, v)
  1477. X*        int i, v;
  1478. X*
  1479. X*   Description
  1480. X*    returns player i's node valued v to rip.
  1481. X*
  1482. X************************************************************************/
  1483. X
  1484. Xstatic void
  1485. Xreturn_rip(i, v)
  1486. Xint i, v;
  1487. X{
  1488. X    int m, n, x, y;
  1489. X
  1490. X    m = p[i].rip_index/5;
  1491. X    n = p[i].rip_index%5;
  1492. X    p[i].rip[m][n] = v;
  1493. X    p[i].rip_index++;
  1494. X    arrtoboard(i, RIP, m, n, &x, &y);
  1495. X    XSetForeground(p[i].dis, p[i].gc, p[i].fg[i]);
  1496. X    putnode(i, v, x, y);
  1497. X}
  1498. X
  1499. X
  1500. X
  1501. X
  1502. X/************************************************************************
  1503. X*
  1504. X*   Synopsis
  1505. X*    show_move(m)
  1506. X*        int m;
  1507. X*
  1508. X*   Argument
  1509. X*    m    the moving result from move();
  1510. X*
  1511. X*   Description
  1512. X*    it takes the values from the global arguments (sf,si,sj) and
  1513. X*    (df,di,dj) and show the move on the board.
  1514. X*    Then, it update the state to implement the move.
  1515. X*
  1516. X************************************************************************/
  1517. X
  1518. Xstatic void
  1519. Xshow_move(m)
  1520. Xint m;
  1521. X{
  1522. X    int a, b, c, v, w, x;
  1523. X    char s1[40], s2[40];
  1524. X
  1525. X    if (count >= 0) {
  1526. X    for (c=0; c<4; c++)
  1527. X        if (p[c].state != 3) {
  1528. X        if (count>3)
  1529. X            arrtoboard(c, sf, si, sj, &a, &b);
  1530. X        else
  1531. X            arrtoboard(c, df, di, dj, &a, &b);
  1532. X        if (count%2 == 0)
  1533. X            putnode(c, -1, a, b);
  1534. X        else {
  1535. X            XSetForeground(p[c].dis, p[c].gc, p[c].fg[sw]);
  1536. X            x = sv;
  1537. X            if (c!=sw && p[c].state!=0)
  1538. X            x = 12 + sw;
  1539. X            putnode(c, x, a, b);
  1540. X        }
  1541. X        }
  1542. X    count--;
  1543. X    XtAppAddTimeOut(app_context, 300, show_move, m);
  1544. X    }
  1545. X    else {
  1546. X    sprintf(s1, "%s (%d,%d,%d)=>(%d,%d,%d)", p[sw].player_name,
  1547. X        sf, si, sj, df, di, dj);
  1548. X    if (m == 2)
  1549. X        sprintf(s2, "%s lost to %s", p[sw].player_name, p[dw].player_name);
  1550. X    else if (m == 3)
  1551. X        sprintf(s2, "%s and %s tied", p[sw].player_name, p[dw].player_name);
  1552. X    else
  1553. X        sprintf(s2, "%s is marching on", p[sw].player_name);
  1554. X    put_msg(s1, s2);
  1555. X
  1556. X    if (m == 3)
  1557. X        if (df == MIDFIELD) mid[di][dj].value = EMPTY;
  1558. X        else arr[df][di][dj].value = EMPTY;
  1559. X    if (m == 4 || m == 1)
  1560. X        if (df == MIDFIELD) {
  1561. X        mid[di][dj].value = sv;
  1562. X        mid[di][dj].id = sw;
  1563. X        }
  1564. X        else {
  1565. X        arr[df][di][dj].value = sv;
  1566. X        arr[df][di][dj].id = sw;
  1567. X        }
  1568. X
  1569. X    if (df == MIDFIELD) {    
  1570. X        w = mid[di][dj].id;
  1571. X        v = mid[di][dj].value;
  1572. X    }
  1573. X    else {
  1574. X        w = arr[df][di][dj].id;
  1575. X        v = arr[df][di][dj].value;
  1576. X    }
  1577. X    for (c=0; c<4; c++)
  1578. X        if (p[c].state != 3) {
  1579. X        arrtoboard(c, df, di, dj, &a, &b);
  1580. X        XSetForeground(p[c].dis, p[c].gc, p[c].fg[w]);
  1581. X        x = v;
  1582. X        if (c!=w && p[c].state!=0 && v!=EMPTY)
  1583. X           x = 12 + w;
  1584. X        putnode(c, x, a, b);
  1585. X        }
  1586. X
  1587. X    mode = 1;    /* because lost_war could change mode if lost */
  1588. X    if (m == 3 || m == 4) {
  1589. X        return_rip(dw, dv);
  1590. X        if (lose_check(dw, dv)) lost_war(dw);
  1591. X    }
  1592. X    if ((mode==1) && (m==2 || m==3)) {
  1593. X        return_rip(sw, sv);
  1594. X        if (lose_check(sw, sv)) lost_war(sw);
  1595. X    }
  1596. X    if (mode == 1) {
  1597. X        do {
  1598. X        turn = (turn+1)%4;
  1599. X        } while (p[turn].state != 2);
  1600. X        putsign(sw, 0);
  1601. X        putsign(turn, 1);
  1602. X        XBell(p[turn].dis, 0);
  1603. X    }
  1604. X    }
  1605. X}
  1606. X
  1607. X
  1608. Xmain(argc, argv)
  1609. Xint argc;
  1610. Xchar **argv;
  1611. X{
  1612. X    int i, j, who, x, y, f, m, n;
  1613. X    int agree_to_peace;
  1614. X    XEvent event;
  1615. X    char buffer, s[40];
  1616. X    KeySym keysym;
  1617. X    XComposeStatus compose;
  1618. X
  1619. X    progname = argv[0];
  1620. X    global_argc = argc;
  1621. X    global_argv = argv;
  1622. X
  1623. X    for (i=0; i<4; i++) {
  1624. X    p[i].display_name = NULL;
  1625. X    sprintf(p[i].player_name, "PLAYER %d", i);
  1626. X    }
  1627. X    strcpy(p[0].color_name, PLAYER0_COLOR);
  1628. X    strcpy(p[1].color_name, PLAYER1_COLOR);
  1629. X    strcpy(p[2].color_name, PLAYER2_COLOR);
  1630. X    strcpy(p[3].color_name, PLAYER3_COLOR);
  1631. X    p[0].talk_x = p[2].talk_x = TALK0_X;
  1632. X    p[1].talk_x = p[3].talk_x = TALK1_X;
  1633. X    p[0].talk_y = p[1].talk_y = TALK0_Y+2*TALK_Y_INC;
  1634. X    p[2].talk_y = p[3].talk_y = TALK2_Y+2*TALK_Y_INC;
  1635. X
  1636. X    debug = False;
  1637. X
  1638. X    parse_arguments(argc, argv);
  1639. X
  1640. X    connect_display();
  1641. X    initial_sapper();
  1642. X    initial_board();
  1643. X    turn = 0;
  1644. X
  1645. X    for (i=0; i<4; i++)
  1646. X    XMapWindow(p[i].dis, p[i].win);
  1647. X
  1648. X    while (1) {
  1649. X    XtAppNextEvent(app_context, &event);
  1650. X    switch(event.type) {
  1651. X      case Expose:
  1652. X        who = whichplayer(event.xexpose.display);
  1653. X
  1654. X        if (p[who].confirm == event.xexpose.window)
  1655. X        redraw_confirm(who);
  1656. X        else refresh_board(who, &event);
  1657. X        break;
  1658. X
  1659. X      case ButtonPress:
  1660. X        who = whichplayer(event.xbutton.display);
  1661. X        if (p[who].popup) {
  1662. X        if (event.xbutton.window != p[who].confirm) {
  1663. X            XBell(p[who].dis, 0);
  1664. X            break;
  1665. X        }
  1666. X        x = event.xbutton.x;
  1667. X        y = event.xbutton.y;
  1668. X        if (p[who].popup != 3)
  1669. X            if (x>80 && x<120 && y>75 && y<95)  f = 1;
  1670. X            else if (x>180 && x<220 && y>75 && y<95)  f = 0;
  1671. X            else {
  1672. X            XBell(p[who].dis, 0);
  1673. X            break;
  1674. X            }
  1675. X
  1676. X        XUnmapWindow(p[who].dis, p[who].confirm);
  1677. X        if (p[who].popup == 3) {
  1678. X            p[who].popup = 0;
  1679. X            break;
  1680. X        }
  1681. X        if (p[who].popup == 2) {    /* QUIT popup */
  1682. X            if (f) {        /* yes to quit */
  1683. X            XUnmapWindow(p[who].dis, p[who].win);
  1684. X            if (p[who].state || mode==3) {
  1685. X                for (i=0; i<4; i++) {
  1686. X                XFreeCursor(p[i].dis, p[i].cursor);
  1687. X                XFreeGC(p[i].dis, p[i].gc);
  1688. X                for (j=0; j<16; j++)
  1689. X                    XFreePixmap(p[i].dis, p[i].node[j]);
  1690. X                XFreePixmap(p[i].dis, p[i].cursormask_pixmap);
  1691. X                XFreePixmap(p[i].dis, p[i].icon_pixmap);
  1692. X                XFreePixmap(p[i].dis, p[i].go_pixmap);
  1693. X                XFreePixmap(p[i].dis, p[i].stop_pixmap);
  1694. X                XFreePixmap(p[i].dis, p[i].nodemask_pixmap);
  1695. X                }
  1696. X                exit(0);
  1697. X            }
  1698. X            else p[who].state = 3;
  1699. X            }
  1700. X            p[who].popup = 0;
  1701. X        }
  1702. X        else    /* PEACE popup */
  1703. X            if (f) {
  1704. X            agree_to_peace++;
  1705. X            p[who].popup = 0;
  1706. X            if (agree_to_peace >= num_player) {
  1707. X                strcpy(confirm_msg, "peace arrived!");
  1708. X                for (i=0; i<4; i++)
  1709. X                if (p[i].state != 3) {
  1710. X                    p[i].popup = 3;
  1711. X                    XMapWindow(p[i].dis, p[i].confirm);
  1712. X                }
  1713. X                mode = 3;
  1714. X            }
  1715. X            }
  1716. X            else {
  1717. X            strcpy(confirm_msg, "Absolutely no peace!");
  1718. X            for (i=0; i<4; i++)
  1719. X                if (p[i].state != 3) {
  1720. X                if (p[i].popup)
  1721. X                    XUnmapWindow(p[i].dis, p[i].confirm);
  1722. X                p[i].popup = 3;
  1723. X                XMapWindow(p[i].dis, p[i].confirm);
  1724. X                }
  1725. X            mode = 1;
  1726. X            }
  1727. X
  1728. X        break;
  1729. X        }
  1730. X
  1731. X        f = boardtofield(event.xbutton.x, event.xbutton.y, &x, &y);
  1732. X        if (f == QUIT) {
  1733. X        if (mode!=1 || p[who].state!=2 || who==turn) {
  1734. X            strcpy(confirm_msg, "Confirm quit!");
  1735. X            p[who].popup = 2;
  1736. X            XMapWindow(p[who].dis, p[who].confirm);
  1737. X        }
  1738. X        else  XBell(p[who].dis, 0);
  1739. X        break;
  1740. X        }
  1741. X
  1742. X        if (f == SURRENDER) {
  1743. X        if (mode==1 && p[who].state==2 && turn==who) {
  1744. X            put_msg(p[who].player_name, "I surrender, spare me!");
  1745. X            do {
  1746. X            turn = (turn+1)%4;
  1747. X            } while (p[turn].state != 2);
  1748. X            XBell(p[turn].dis, 0);
  1749. X            lost_war(who);
  1750. X        }
  1751. X
  1752. X        else XBell(p[who].dis, 0);
  1753. X        break;
  1754. X        }
  1755. X
  1756. X        if (f == PEACE) {
  1757. X        if (mode == 1 && p[who].state == 2 && turn == who) {
  1758. X            for (i=0; i<4; i++)
  1759. X            if (p[i].popup != 0) break;
  1760. X            if (i == 4) {
  1761. X            agree_to_peace = 1;
  1762. X            peace_request(who);
  1763. X            break;
  1764. X            }
  1765. X        }
  1766. X        XBell(p[who].dis, 0);
  1767. X        break;
  1768. X        }
  1769. X
  1770. X        if (f == REDEPLOY) {
  1771. X        if (mode == 0)  p[who].state = 1;
  1772. X        else XBell(p[who].dis, 0);
  1773. X        break;
  1774. X        }
  1775. X
  1776. X        if (f == READY) {
  1777. X        if (mode == 0)
  1778. X            if (!valid_deploy(who)) {
  1779. X            strcpy(confirm_msg,"Invalid deploy");
  1780. X            p[who].popup = 3;
  1781. X            XMapWindow(p[who].dis, p[who].confirm);
  1782. X            XBell(p[who].dis, 0);
  1783. X            }
  1784. X            else {
  1785. X            p[who].state = 2;
  1786. X            for (i=0; i<4; i++)
  1787. X                if (p[i].state != 2) break;
  1788. X            if (i == 4) {
  1789. X                mode = 1;
  1790. X                sprintf(s, "%s moves first", p[turn].player_name);
  1791. X                put_msg("WAR started", s);
  1792. X                send_expose_event();
  1793. X                XBell(p[turn].dis, 0);
  1794. X            }
  1795. X            }
  1796. X        else XBell(p[who].dis, 0);
  1797. X        break;
  1798. X        }
  1799. X
  1800. X        if (f == NEW) {
  1801. X        if (mode == 3) new_game();
  1802. X        else XBell(p[who].dis, 0);
  1803. X        break;
  1804. X        }
  1805. X
  1806. X/*from now on the button event happened on the board for picking up a node */
  1807. X
  1808. X        if (p[who].state==0 || mode>1) {
  1809. X        XBell(p[who].dis, 0);
  1810. X        break;
  1811. X        }
  1812. X
  1813. X        f = boardtoarr(who, event.xbutton.x, event.xbutton.y, &x, &y);
  1814. X        if (f == -1) {
  1815. X        XBell(p[who].dis, 0);
  1816. X        break;
  1817. X        }
  1818. X        p[who].pick.arr = f;
  1819. X        p[who].pick.x = x;
  1820. X        p[who].pick.y = y;
  1821. X        if (mode == 0)
  1822. X        if (p[who].state == 1)
  1823. X            if (f == RIP && p[who].rip[x][y] != EMPTY)
  1824. X            p[who].pick.value = p[who].rip[x][y];
  1825. X            else if (f == who && arr[f][x][y].value != EMPTY)
  1826. X            p[who].pick.value = arr[f][x][y].value;
  1827. X            else {
  1828. X            XBell(p[who].dis, 0);
  1829. X            break;
  1830. X            }
  1831. X        else {
  1832. X            XBell(p[who].dis, 0);
  1833. X            break;
  1834. X        }
  1835. X        else {
  1836. X        if (turn != who) {
  1837. X            XBell(p[who].dis, 0);
  1838. X            break;
  1839. X        }
  1840. X        if (f==MIDFIELD && mid[x][y].id==who && mid[x][y].value!=EMPTY)
  1841. X            p[who].pick.value = mid[x][y].value;
  1842. X        else if (f>=F0 && f<=F3 && arr[f][x][y].id == who &&
  1843. X            arr[f][x][y].value!=EMPTY && arr[f][x][y].value!=MINE &&
  1844. X            (x!=5 || (y!=1 && y!=3)) )
  1845. X            p[who].pick.value = arr[f][x][y].value;
  1846. X        else {
  1847. X            XBell(p[who].dis, 0);
  1848. X            break;
  1849. X        }
  1850. X        }
  1851. X        p[who].pick.picked = True;
  1852. X        arrtoboard(who, f, x, y, &m, &n);
  1853. X        putnode(who, -1, m, n);
  1854. X
  1855. X        p[who].tmp_cursor = XCreatePixmapCursor(p[who].dis,
  1856. X        p[who].node[p[who].pick.value], p[who].nodemask_pixmap,
  1857. X        &(p[who].fg_color), &(p[who].bg_color),
  1858. X        nodemask_x_hot, nodemask_y_hot);
  1859. X        XDefineCursor(p[who].dis, p[who].win, p[who].tmp_cursor);
  1860. X        break;
  1861. X
  1862. X      case ButtonRelease:
  1863. X        who = whichplayer(event.xbutton.display);
  1864. X        if (p[who].pick.picked) {
  1865. X        XSetForeground(p[who].dis, p[who].gc, p[who].fg[who]);
  1866. X        p[who].pick.picked = False;
  1867. X        XFreeCursor(p[who].dis, p[who].tmp_cursor);
  1868. X        XDefineCursor(p[who].dis, p[who].win, p[who].cursor);
  1869. X        f = boardtoarr(who, event.xbutton.x, event.xbutton.y, &x, &y);
  1870. X        if (f != -1)
  1871. X            if (mode == 0) {
  1872. X            if (f == RIP && p[who].rip[x][y] == EMPTY)
  1873. X                p[who].rip[x][y] = p[who].pick.value;
  1874. X            else if (f == who && arr[f][x][y].value == EMPTY)
  1875. X                arr[f][x][y].value = p[who].pick.value;
  1876. X            else {
  1877. X                arrtoboard(who, p[who].pick.arr, p[who].pick.x,
  1878. X                p[who].pick.y, &m, &n);
  1879. X                putnode(who, p[who].pick.value, m, n);
  1880. X                XBell(p[who].dis, 0);
  1881. X                break;
  1882. X            }
  1883. X
  1884. X            m = p[who].pick.x;
  1885. X            n = p[who].pick.y;
  1886. X            if (p[who].pick.arr==RIP)
  1887. X                p[who].rip[m][n] = EMPTY;
  1888. X            else  arr[who][m][n].value = EMPTY;
  1889. X            arrtoboard(who, f, x, y, &m, &n);
  1890. X            putnode(who, p[who].pick.value, m, n);
  1891. X            }
  1892. X            else {
  1893. X            m = move(who, f, x, y);
  1894. X            if (m == 0) {    /* invalid move */
  1895. X                arrtoboard(who, p[who].pick.arr, p[who].pick.x,
  1896. X                p[who].pick.y, &m, &n);
  1897. X                putnode(who, p[who].pick.value, m, n);
  1898. X                XBell(p[who].dis, 0);
  1899. X            }
  1900. X            else {
  1901. X                mode = 4;
  1902. X                sf = p[who].pick.arr;
  1903. X                si = p[who].pick.x;
  1904. X                sj = p[who].pick.y;
  1905. X                df = f;
  1906. X                di = x;
  1907. X                dj = y;
  1908. X                if (sf == MIDFIELD) {
  1909. X                sw = mid[si][sj].id;
  1910. X                sv = mid[si][sj].value;
  1911. X                mid[si][sj].value = EMPTY;
  1912. X                }
  1913. X                else {
  1914. X                sw = arr[sf][si][sj].id;
  1915. X                sv = arr[sf][si][sj].value;
  1916. X                arr[sf][si][sj].value = EMPTY;
  1917. X                }
  1918. X                if (df == MIDFIELD) {
  1919. X                dw = mid[di][dj].id;
  1920. X                dv = mid[di][dj].value;
  1921. X                }
  1922. X                else {
  1923. X                dw = arr[df][di][dj].id;
  1924. X                dv = arr[df][di][dj].value;
  1925. X                }
  1926. X                count = 8;
  1927. X                show_move(m);
  1928. X            }
  1929. X            }
  1930. X        else {
  1931. X            arrtoboard(who, p[who].pick.arr, p[who].pick.x,
  1932. X                p[who].pick.y, &m, &n);
  1933. X            putnode(who, p[who].pick.value, m, n);
  1934. X            XBell(p[who].dis, 0);
  1935. X        }
  1936. X        } /* if (picked == True) */
  1937. X        break;
  1938. X
  1939. X      case KeyPress:
  1940. X        who = whichplayer(event.xkey.display);
  1941. X        f = XLookupString(&event, &buffer, 1, &keysym, &compose);
  1942. X        if (keysym==XK_Return || keysym==XK_Linefeed) {
  1943. X        talk(who, 2, '_');
  1944. X        break;
  1945. X        }
  1946. X        if (keysym==XK_BackSpace || keysym==XK_Delete) {
  1947. X        talk(who, 1, '_');
  1948. X        break;
  1949. X        }
  1950. X        if (keysym>=XK_space && keysym<=XK_asciitilde)
  1951. X        talk(who, 0, buffer);
  1952. X        break;
  1953. X
  1954. X      case MappingNotify:
  1955. X        XRefreshKeyboardMapping(&event);
  1956. X        break;
  1957. X
  1958. X      default:
  1959. X        break;
  1960. X    }  /* switch */
  1961. X    } /* while(1) */
  1962. X}
  1963. X
  1964. X
  1965. X
  1966. END_OF_FILE
  1967. if test 42982 -ne `wc -c <'x4war.c'`; then
  1968.     echo shar: \"'x4war.c'\" unpacked with wrong size!
  1969. fi
  1970. # end of 'x4war.c'
  1971. fi
  1972. echo shar: End of archive 1 \(of 3\).
  1973. cp /dev/null ark1isdone
  1974. MISSING=""
  1975. for I in 1 2 3 ; do
  1976.     if test ! -f ark${I}isdone ; then
  1977.     MISSING="${MISSING} ${I}"
  1978.     fi
  1979. done
  1980. if test "${MISSING}" = "" ; then
  1981.     echo You have unpacked all 3 archives.
  1982.     rm -f ark[1-9]isdone
  1983. else
  1984.     echo You still need to unpack the following archives:
  1985.     echo "        " ${MISSING}
  1986. fi
  1987. ##  End of shell archive.
  1988. exit 0
  1989.