home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume14 / xbattle / part02 < prev    next >
Encoding:
Internet Message Format  |  1993-01-26  |  51.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: v14i073:  xbattle - multi-player battle strategy game for X-Windows, Part02/07
  5. Message-ID: <3512@master.CNA.TEK.COM>
  6. Date: 7 Sep 92 21:22:52 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 1658
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: slehar@cns.bu.edu
  12. Posting-number: Volume 14, Issue 73
  13. Archive-name: xbattle/Part02
  14. Environment: Xlib
  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 2 (of 7)."
  25. # Contents:  main.c patchlevel.h tribal.xbo
  26. # Wrapped by billr@saab on Mon Sep  7 14:18:49 1992
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'main.c' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'main.c'\"
  30. else
  31. echo shar: Extracting \"'main.c'\" \(48734 characters\)
  32. sed "s/^X//" >'main.c' <<'END_OF_FILE'
  33. X#include <stdio.h>
  34. X  
  35. X/**** x include files ****/
  36. X#include <X11/Xlib.h>
  37. X#include <X11/Xutil.h>
  38. X#include <X11/Xatom.h>
  39. X#include <X11/keysym.h>
  40. X#include <X11/keysymdef.h>
  41. X
  42. X#include "global.h"
  43. X
  44. X#if UNIX
  45. X#include <sys/types.h>
  46. X#include <sys/time.h>
  47. X#endif
  48. X
  49. X/*************************************************************************/
  50. X/**    xbattle                                **/
  51. X/**                                    **/
  52. X/**    Steve Lehar (slehar@park.bu.edu)                **/
  53. X/**     Greg Lesher (lesher@park.bu.edu)                **/
  54. X/** with horizon and sea contribution from                **/
  55. X/**     Mark Lauer (elric@cs.su.oz.au)                                  **/
  56. X/**                                    **/
  57. X/*************************************************************************/
  58. X
  59. Xmain(argc,argv)
  60. X  int argc;
  61. X  char *argv[];
  62. X{ 
  63. X  int i,j,t,p,
  64. X      winxsize[MAXSIDES],
  65. X      winysize[MAXSIDES];
  66. X
  67. X  long eventmask;
  68. X  XEvent event;
  69. X  char displayname[MAXPLAYERS][80],
  70. X       gtitle[20], htitle[20];
  71. X  square_type *board;
  72. X#if UNIX
  73. X  int fd, maxfd;
  74. X  int selectback;
  75. X  unsigned long newtime, oldtime, targettime;
  76. X  fd_set rfds, disp_fds;
  77. X  struct timeval tval;
  78. X  struct timeval tp_old;
  79. X  struct timezone tzp;
  80. X#endif
  81. X  
  82. X  /**** getarg functions ****/
  83. X  int intval(),is_arg();
  84. X  double doubleval();
  85. X  int stringval();
  86. X
  87. X  /**** parse the command line ****/
  88. X
  89. X  init_defaults();
  90. X  checkoptions(argc,argv);
  91. X  get_displaynames(displayname,colorarray,rcolorarray,argc,argv);
  92. X  init_options(displayname,argc,argv);
  93. X  clean_options (displayname);
  94. X
  95. X  if (enable_hex)
  96. X  {
  97. X    init_hex (squaresize[0]);
  98. X
  99. X    for (i=0; i<nsides; i++)
  100. X    {
  101. X      for (j=0; j<nsides; j++)
  102. X#if MULTITEXT
  103. X      textyh[i][j]=boardsizey*2*hex_vert + hex_vert + 12 + 16*j,
  104. X#else
  105. X      textyh[i][j]=boardsizey*2*hex_vert + hex_vert + 12,
  106. X      textyl[i][j]=boardsizey*2*hex_vert + hex_vert + 28;
  107. X#endif
  108. X
  109. X      winxsize[i] = (boardsizex-1)*3*(hex_halfside) + 2*hex_side;
  110. X
  111. X#if MULTITEXT
  112. X      winysize[i] = boardsizey*2*hex_vert + hex_vert + nsides*TEXTSIZE;
  113. X#else
  114. X      winysize[i] = boardsizey*2*hex_vert + hex_vert + 2*TEXTSIZE;
  115. X#endif
  116. X    }
  117. X  }
  118. X  else
  119. X  { 
  120. X    for (i=0; i<nsides; i++)
  121. X    {
  122. X      for (j=0; j<nsides; j++)
  123. X#if MULTITEXT
  124. X      textyh[i][j]=boardsizey*squaresize[i]+12+16*j,
  125. X#else
  126. X      textyh[i][j]=boardsizey*squaresize[i]+12,
  127. X      textyl[i][j]=boardsizey*squaresize[i]+28;
  128. X#endif
  129. X
  130. X      winxsize[i] = boardsizex*squaresize[i];
  131. X#if MULTITEXT
  132. X      winysize[i] = boardsizey*squaresize[i] + nsides*TEXTSIZE;
  133. X#else
  134. X      winysize[i] = boardsizey*squaresize[i] + 2*TEXTSIZE;
  135. X#endif
  136. X    }
  137. X  } 
  138. X
  139. X  /**** allocate the boards ****/
  140. X  board  = (square_type *)(malloc(boardsizex*boardsizey*sizeof(square_type)));
  141. X
  142. X  init_board (board);
  143. X  
  144. X  /**** open x windows ****/
  145. X#if UNIX
  146. X  maxfd = 0;
  147. X  FD_ZERO(&disp_fds);
  148. X#endif
  149. X
  150. X  if (enable_bound)
  151. X    eventmask = ButtonPressMask|ButtonReleaseMask|ButtonMotionMask|KeyPressMask|ExposureMask;
  152. X  else
  153. X    eventmask = ButtonPressMask|ButtonMotionMask|KeyPressMask|ExposureMask;
  154. X
  155. X  for (p=0; p<nplayers; p++)
  156. X  {
  157. X    xwindow[p]  = (xwindow_type*)malloc(sizeof(xwindow_type));
  158. X
  159. X    strcpy (gtitle, graytitle[color2bw[sidemap[colorarray[p]]]]);
  160. X    strcpy (htitle, huetitle[sidemap[colorarray[p]]]);
  161. X
  162. X    if (lettermap[colorarray[p]][0])
  163. X      strcpy (gtitle, htitle);
  164. X
  165. X    if (enable_manpos[colorarray[p]])
  166. X      open_xwindow(xwindow[p],displayname[p],-1,-1,
  167. X                  winxsize[colorarray[p]],winysize[colorarray[p]],
  168. X                          gtitle, htitle, eventmask,squaresize[colorarray[p]]);
  169. X    else
  170. X      open_xwindow(xwindow[p],displayname[p],XPOS,YPOS,
  171. X                  winxsize[colorarray[p]],winysize[colorarray[p]],
  172. X                          gtitle, htitle, eventmask,squaresize[colorarray[p]]);
  173. X
  174. X#if UNIX
  175. X    if ((fd = ConnectionNumber (xwindow[p]->display)) > maxfd)
  176. X      maxfd = fd;
  177. X    FD_SET (fd, &disp_fds); 
  178. X#endif
  179. X  }  
  180. X
  181. X  if (enable_edit)
  182. X    edit_board(board);
  183. X
  184. X  /**** replay game ****/
  185. X  if (enable_replay)
  186. X    replaygame(squaresize[0], board);
  187. X  
  188. X  /************* main event loop *************/
  189. X#if UNIX
  190. X  XSetIOErrorHandler(1);
  191. X  gettimeofday (&tp_old, &tzp);
  192. X  oldtime = (tp_old.tv_sec%10000)*1000000 + tp_old.tv_usec;
  193. X  targettime = oldtime + (delay/10000)*1000000 + (delay%10000)*100;
  194. X
  195. X  while (TRUE)
  196. X  {
  197. X    /**** check for events ****/
  198. X    rfds = disp_fds;
  199. X
  200. X    tval.tv_sec = (targettime-oldtime)/1000000;
  201. X    tval.tv_usec = (targettime-oldtime)%1000000;
  202. X
  203. X    selectback = select (maxfd+1, &rfds, NULL, NULL, &tval);
  204. X
  205. X    gettimeofday (&tp_old, &tzp);
  206. X    newtime = (tp_old.tv_sec%10000)*1000000 + tp_old.tv_usec;
  207. X
  208. X    if (newtime < oldtime)
  209. X      targettime = newtime - 1;
  210. X
  211. X    switch (selectback)
  212. X    {
  213. X      case -1:
  214. X        perror("select()");
  215. X        exit (1);
  216. X        break;
  217. X
  218. X      case 0:
  219. X        for (i=0; i<nplayers; i++)
  220. X        {
  221. X          if (winopen[i])
  222. X          {
  223. X            XFlush(xwindow[i]->display);
  224. X            while (XEventsQueued(xwindow[i]->display, QueuedAfterReading) > 0)
  225. X            {
  226. X          XNextEvent(xwindow[i]->display, &event);
  227. X          process_event(event,board,colorarray,i);
  228. X            }
  229. X
  230. X#if MULTIFLUSH
  231. X            XFlush(xwindow[i]->display);
  232. X#endif
  233. X          }
  234. X        }
  235. X        break;
  236. X
  237. X      default:
  238. X        for (i=0; i<nplayers; i++)
  239. X        {
  240. X          if (winopen[i])
  241. X          {
  242. X            if (FD_SET(fd = ConnectionNumber(xwindow[i]->display), &rfds))
  243. X            {
  244. X              while (winopen[i] &&
  245. X                    XEventsQueued(xwindow[i]->display, QueuedAfterReading) > 0)
  246. X         
  247. X              {
  248. X            XNextEvent(xwindow[i]->display, &event);
  249. X            process_event(event,board,colorarray,i);
  250. X              }
  251. X
  252. X#if MULTIFLUSH
  253. X              XFlush(xwindow[i]->display);
  254. X#endif
  255. X
  256. X              if (!winopen[i])
  257. X                FD_CLR (fd, &disp_fds);
  258. X            }
  259. X          }
  260. X        }
  261. X        break;
  262. X    }
  263. X
  264. X    if (newtime > targettime)
  265. X    {
  266. X      if (enable_march)
  267. X        march(board);
  268. X      update_board(board);
  269. X      targettime = newtime + (delay/10000)*1000000 + (delay%10000)*100;
  270. X    }
  271. X    oldtime = newtime;  
  272. X  }
  273. X#else
  274. X  t = 0;
  275. X  while (TRUE)
  276. X  {
  277. X    /**** check for events ****/
  278. X    for (i=0; i<nplayers; i++)
  279. X    {
  280. X      if (!winopen[i])
  281. X        continue;
  282. X      if (XEventsQueued(xwindow[i]->display, QueuedAfterReading) > 0)
  283. X      {
  284. X    XNextEvent(xwindow[i]->display, &event);
  285. X    process_event(event,board,colorarray,i);
  286. X      }
  287. X      else
  288. X        XFlush(xwindow[i]->display);
  289. X    }
  290. X    
  291. X    /**** update the game board ****/
  292. X    if (t++>delay)
  293. X    {
  294. X      t = 0;
  295. X      if (enable_march)
  296. X        march(board);
  297. X      update_board(board);
  298. X    }
  299. X  }
  300. X#endif
  301. X}
  302. X
  303. X
  304. X/*************************************************************************/
  305. X/**    process_event                            **/
  306. X/** Process the x event from the xwindow of 'player'            **/
  307. X/**    Steve Lehar (slehar@park.bu.edu)                **/
  308. X/**    Greg Lesher (lesher@park.bu.edu)                **/
  309. X/*************************************************************************/
  310. Xprocess_event(event,board,colorarray,player)
  311. X  XEvent event;
  312. X  square_type *board;
  313. X  int colorarray[MAXPLAYERS], player;
  314. X{
  315. X  int i, j, k, x, y,
  316. X      xpos, ypos,
  317. X      textcount,
  318. X      limit,
  319. X      tdir[DIRS],
  320. X      xlow, xhigh, ylow, yhigh,
  321. X      status,
  322. X      color,
  323. X      control,
  324. X      shift;
  325. X  char text[10],
  326. X       line[10];
  327. X  double val;
  328. X  KeySym key;
  329. X  char keyvector[32];
  330. X  unsigned int bitindex,
  331. X               byteindex;
  332. X  KeyCode code;
  333. X  square_type *square2;
  334. X  
  335. X  /**** Process events ****/
  336. X  switch (event.type)
  337. X  {
  338. X    /**** process expose event ****/
  339. X    case Expose:
  340. X      drawboard(board, player, FALSE);
  341. X      break;
  342. X    
  343. X    /**** process button presses ****/
  344. X    case ButtonPress:
  345. X
  346. X      if (winwatch[player])
  347. X        break;
  348. X
  349. X#if PAUSE
  350. X      if (paused)
  351. X        break;
  352. X#endif
  353. X      
  354. X      /**** left button ****/
  355. X      switch (event.xbutton.button)
  356. X      {
  357. X        case Button1:
  358. X        case Button2:
  359. X          shift = event.xbutton.state & ShiftMask;
  360. X
  361. X          if (enable_personalmarch[colorarray[player]] && shift)
  362. X          {
  363. X            oldx[player] = -1;
  364. X            oldy[player] = -1;
  365. X
  366. X            getsquare(event.xbutton.x,event.xbutton.y,&x,&y,tdir,squaresize[colorarray[player]],board,shift);
  367. X               
  368. X            color = colorarray[player];
  369. X
  370. X            if (enable_sea && SQUARE(board,x,y)->color==none && SQUARE(board,x,y)->value[none]<=0)
  371. X              break;
  372. X            else if (SQUARE(board,x,y)->color == color &&
  373. X                                     SQUARE(board,x,y)->value[color] > 0) 
  374. X            {
  375. X              SQUARE(board,x,y)->anymarch = ACTIVE;
  376. X              SQUARE(board,x,y)->marchcolor = color;
  377. X              SQUARE(board,x,y)->marchcount = 0;
  378. X            }
  379. X            else
  380. X            {
  381. X              SQUARE(board,x,y)->march[color] = PASSIVE;
  382. X            }
  383. X
  384. X            for (i=0; i<directions; i++)
  385. X              SQUARE(board,x,y)->marchdir[color][i] = 0;
  386. X
  387. X            if (event.xbutton.button == Button1)
  388. X              SQUARE(board,x,y)->marchtype[color] = SET;
  389. X            else
  390. X              SQUARE(board,x,y)->marchtype[color] = FORCE;
  391. X
  392. X            for (i=0; i<directions; i++)
  393. X              if (tdir[i])
  394. X              {
  395. X                SQUARE(board,x,y)->marchdir[color][i] = 1;
  396. X                i = 5;
  397. X              }
  398. X            if (SQUARE(board,x,y)->march[color] == PASSIVE)
  399. X              outdated[x][y] = ALL;
  400. X            break;
  401. X          }
  402. X
  403. X          getsquare(event.xbutton.x,event.xbutton.y,&x,&y,dir[player],squaresize[colorarray[player]],
  404. X                                                              board,shift);
  405. X
  406. X          if (enable_personalbound[colorarray[player]])
  407. X          {
  408. X            oldx[player] = x;
  409. X            oldy[player] = y;
  410. X            break;
  411. X          }
  412. X        
  413. X          /**** move ****/
  414. X          if (SQUARE(board,x,y)->color == colorarray[player] ||
  415. X               (!enable_disrupt[colorarray[player]] && SQUARE(board,x,y)->color==FIGHT &&
  416. X                                SQUARE(board,x,y)->oldcolor == colorarray[player]))
  417. X          {
  418. X#if VARMOUSE
  419. X            if (event.xbutton.button == Button1)
  420. X            {
  421. X          moveon(SQUARE(board, x,y),dir[player]);
  422. X              dirtype[player] = SET;
  423. X            }
  424. X            else
  425. X            {
  426. X          moveoff(SQUARE(board, x,y),dir[player]);
  427. X              dirtype[player] = FORCE;
  428. X            }
  429. X#else
  430. X            if (event.xbutton.button == Button1)
  431. X            {
  432. X          setmove(SQUARE(board, x,y),dir[player]);
  433. X              dirtype[player] = SET;
  434. X            }
  435. X            else
  436. X            {
  437. X          forcemove(SQUARE(board, x,y),dir[player]);
  438. X              dirtype[player] = FORCE;
  439. X            }
  440. X#endif
  441. X
  442. X            dumpsquare (board, SQUARE(board,x,y));
  443. X          }
  444. X
  445. X          if (enable_personalmarch[colorarray[player]])
  446. X            if (SQUARE(board,x,y)->march[colorarray[player]] || SQUARE(board,x,y)->anymarch)
  447. X            {
  448. X              if (SQUARE(board,x,y)->anymarch == ACTIVE &&
  449. X                             SQUARE(board,x,y)->marchcolor == colorarray[player])
  450. X              {
  451. X                SQUARE(board,x,y)->anymarch = FALSE;
  452. X                SQUARE(board,x,y)->march[colorarray[player]] = FALSE;
  453. X              }
  454. X              else
  455. X              {
  456. X                SQUARE(board,x,y)->march[colorarray[player]] = FALSE;
  457. X                outdated[x][y] = ALL;
  458. X                dumpsquare (board, SQUARE(board,x,y));
  459. X              }
  460. X            }
  461. X
  462. X          break;
  463. X  
  464. X        case Button3:
  465. X  
  466. X          if (enable_artillery[colorarray[player]] || enable_paratroops[colorarray[player]] ||
  467. X                                              enable_repeat[colorarray[player]])
  468. X          {
  469. X            getsquare(event.xbutton.x,event.xbutton.y,&x,&y,tdir,squaresize[colorarray[player]], board,shift);
  470. X
  471. X            if (SQUARE(board,x,y)->color == colorarray[player])
  472. X            {
  473. X              shift = event.xbutton.state & ShiftMask;
  474. X              control = event.xbutton.state & ControlMask;
  475. X
  476. X              if (shift && enable_paratroops[colorarray[player]])
  477. X                para (board, event.xbutton.x, event.xbutton.y, x, y, colorarray);
  478. X              else if (control && enable_artillery[colorarray[player]])
  479. X                fire (board, event.xbutton.x, event.xbutton.y, x, y, colorarray);
  480. X              else if (enable_repeat[colorarray[player]]) 
  481. X              {
  482. X#if VARMOUSE
  483. X                if (dirtype[player] == SET)
  484. X              moveon(SQUARE(board, x,y),dir[player]);
  485. X                else
  486. X              moveoff(SQUARE(board, x,y),dir[player]);
  487. X#else
  488. X                if (dirtype[player] == SET)
  489. X              setmove(SQUARE(board, x,y),dir[player]);
  490. X                else
  491. X              forcemove(SQUARE(board, x,y),dir[player]);
  492. X#endif
  493. X              dumpsquare (board, SQUARE(board,x,y));
  494. X              }
  495. X            }
  496. X          }
  497. X          break;
  498. X      }
  499. X      break;
  500. X
  501. X    case ButtonRelease:
  502. X      if (!enable_personalbound[colorarray[player]])
  503. X        break;
  504. X
  505. X      if ((oldx[player] == -1) && (oldy[player] == -1))
  506. X        break;
  507. X
  508. X      getsquare(event.xbutton.x,event.xbutton.y,&x,&y,tdir,squaresize[colorarray[player]], board,shift);
  509. X
  510. X      if (y >= boardsizey)
  511. X        y = boardsizey-1;
  512. X      if (x >= boardsizex)
  513. X        x = boardsizex-1;
  514. X
  515. X      if (oldx[player] < x)
  516. X      {
  517. X        xlow = oldx[player]; 
  518. X        xhigh = x;
  519. X      }
  520. X      else
  521. X      {
  522. X        xlow = x;
  523. X        xhigh = oldx[player]; 
  524. X      }
  525. X
  526. X      if (oldy[player] < y)
  527. X      {
  528. X        ylow = oldy[player]; 
  529. X        yhigh = y;
  530. X      }
  531. X      else
  532. X      {
  533. X        ylow = y;
  534. X        yhigh = oldy[player]; 
  535. X      }
  536. X
  537. X      switch (event.xbutton.button)
  538. X      {
  539. X        case Button1:
  540. X        case Button2:
  541. X
  542. X          for (i=xlow; i<=xhigh; i++)
  543. X          {
  544. X            for (j=ylow; j<=yhigh; j++)
  545. X            {
  546. X              if (SQUARE(board,i,j)->color == colorarray[player] ||
  547. X                     (!enable_disrupt[colorarray[player]] && SQUARE(board,i,j)->color==FIGHT &&
  548. X                     SQUARE(board,i,j)->oldcolor == colorarray[player]))
  549. X              {
  550. X#if VARMOUSE
  551. X                if (event.xbutton.button == Button1)
  552. X              moveon(SQUARE(board, i,j),dir[player]);
  553. X                else
  554. X              moveoff(SQUARE(board, i,j),dir[player]);
  555. X#else
  556. X                if (event.xbutton.button == Button1)
  557. X              setmove(SQUARE(board, i,j),dir[player]);
  558. X                else
  559. X              forcemove(SQUARE(board, i,j),dir[player]);
  560. X#endif
  561. X
  562. X                dumpsquare (board, SQUARE(board,i,j));
  563. X
  564. X              }
  565. X            }
  566. X          }
  567. X
  568. X          break;
  569. X
  570. X        case Button3:
  571. X          break;
  572. X      }
  573. X      break;
  574. X  
  575. X      /**** process key press events ****/
  576. X    case KeyPress:
  577. X      textcount = XLookupString(&event, text, 10, &key, NULL);
  578. X      if (textcount != 0)
  579. X      {
  580. X        if ((enable_hex && (event.xbutton.y < boardsizey*2*hex_vert + hex_vert)) ||
  581. X               (!enable_hex && (event.xbutton.y < boardsizey*squaresize[colorarray[player]])))
  582. X        {
  583. X          getsquare(event.xbutton.x,event.xbutton.y,&x,&y,dir[player],
  584. X                                     squaresize[colorarray[player]], board,shift);
  585. X          if (winwatch[player])
  586. X            break;
  587. X          switch (text[0])
  588. X          {
  589. X#if PAUSE
  590. X            case CTRLS:
  591. X              paused = TRUE;
  592. X              break;
  593. X            case CTRLQ:
  594. X              paused = FALSE;
  595. X              break;
  596. X#endif
  597. X            case 'a':
  598. X            case 'A':
  599. X              color = colorarray[player];
  600. X
  601. X              if (!enable_attack[color])
  602. X                break;
  603. X
  604. X              if (SQUARE(board,x,y)->color == none || SQUARE(board,x,y)->color == color)
  605. X                break;
  606. X
  607. X              for (i=0; i<directions; i++)
  608. X                tdir[i] = 0;
  609. X
  610. X              for (i=0; i<directions; i++)
  611. X              {
  612. X                square2 = SQUARE(board,x,y)->connect[i];
  613. X
  614. X                if (square2 != SQUARE(board,x,y) && square2->color == color)
  615. X                {
  616. X                  tdir[(i+directions/2)%directions] = 1;
  617. X                  forcemove (square2, tdir);
  618. X                  tdir[(i+directions/2)%directions] = 0;
  619. X                }
  620. X              }
  621. X
  622. X              break;
  623. X
  624. X            case 'z':
  625. X            case 'Z':
  626. X              color = colorarray[player];
  627. X              if (SQUARE(board,x,y)->color == color)
  628. X              {
  629. X                for (i=0; i<directions; i++)
  630. X                  tdir[i] = 0;
  631. X                forcemove (SQUARE(board,x,y), tdir);
  632. X              }
  633. X              break;
  634. X
  635. X            case 'p':
  636. X            case 'P':
  637. X              if (!enable_paratroops[colorarray[player]])
  638. X                break;
  639. X
  640. X              getsquare(event.xbutton.x,event.xbutton.y,&x,&y,tdir,squaresize[colorarray[player]], board,shift);
  641. X              if (SQUARE(board,x,y)->color == colorarray[player])
  642. X                para (board, event.xbutton.x, event.xbutton.y, x, y, colorarray);
  643. X              break;
  644. X
  645. X            case 'g':
  646. X            case 'G':
  647. X              if (!enable_artillery[colorarray[player]])
  648. X                break;
  649. X
  650. X              getsquare(event.xbutton.x,event.xbutton.y,&x,&y,tdir,squaresize[colorarray[player]], board,shift);
  651. X              if (SQUARE(board,x,y)->color == colorarray[player])
  652. X                fire (board, event.xbutton.x, event.xbutton.y, x, y, colorarray);
  653. X              break;
  654. X
  655. X            case 'd':
  656. X            case 'D':
  657. X              if (!enable_dig[colorarray[player]])
  658. X                break;
  659. X
  660. X              if (SQUARE(board,x,y)->color == colorarray[player])
  661. X              {
  662. X                if (SQUARE(board,x,y)->value[SQUARE(board,x,y)->color] > digcost &&
  663. X                          SQUARE(board,x,y)->growth < 60 )
  664. X                {
  665. X                  if (SQUARE(board,x,y)->move == 0)
  666. X                  {
  667. X                    SQUARE(board,x,y)->value[none] -= 1; 
  668. X
  669. X                    if (enable_sea)
  670. X                      SQUARE(board,x,y)->value[none] = 1 - fillnumber; 
  671. X                    else if (SQUARE(board,x,y)->value[none] < 0) 
  672. X                      SQUARE(board,x,y)->value[none] = 0; 
  673. X
  674. X                    SQUARE(board,x,y)->angle = 0;
  675. X                    SQUARE(board,x,y)->value[SQUARE(board,x,y)->color] = 0; 
  676. X                    SQUARE(board,x,y)->move = 0;
  677. X                    for (k=0; k<directions; k++)
  678. X                      SQUARE(board,x,y)->dir[k] = 0;
  679. X                    SQUARE(board,x,y)->lowbound = 0;
  680. X                    outdatehorizon (board, x, y, SQUARE(board,x,y)->color);
  681. X                    SQUARE(board,x,y)->color = none; 
  682. X                    outdated[x][y] = ALL;
  683. X                  }
  684. X                  else if (SQUARE(board,x,y)->move == 1)  /** dig partially filled square **/
  685. X                  {
  686. X                    for (i=0; i<directions; i++)
  687. X                    {
  688. X                      if (SQUARE(board,x,y)->dir[i])
  689. X                        square2 = SQUARE(board,x,y)->connect[i];
  690. X                    }
  691. X
  692. X                    if (square2->color == none && square2->value[none] < 0)
  693. X                    {
  694. X                      square2->value[none] += 1;
  695. X
  696. X                      SQUARE(board,x,y)->move = 0;
  697. X                      SQUARE(board,x,y)->value[SQUARE(board,x,y)->color] = 0;
  698. X                      for (k=0; k<8; k++)
  699. X                        SQUARE(board,x,y)->dir[k] = 0;
  700. X                      SQUARE(board,x,y)->lowbound = 0;
  701. X                      outdatehorizon (board, square2->x, square2->x, ALL);
  702. X                      outdated[x][y] = ALL;
  703. X                      outdated[square2->x][square2->y] = ALL;
  704. X                    }
  705. X                  }
  706. X                }
  707. X              }
  708. X              break;
  709. X  
  710. X            case 'f':
  711. X            case 'F':
  712. X              if (!enable_fill[colorarray[player]])
  713. X                break;
  714. X              if (SQUARE(board,x,y)->color == colorarray[player])
  715. X              {
  716. X                if (SQUARE(board,x,y)->value[SQUARE(board,x,y)->color] > fillcost &&
  717. X                          SQUARE(board,x,y)->move <= 1)
  718. X                {
  719. X                  if (SQUARE(board,x,y)->move == 1)
  720. X                  {
  721. X                    for (i=0; i<directions; i++)
  722. X                    {
  723. X                      if (SQUARE(board,x,y)->dir[i])
  724. X                        square2 = SQUARE(board,x,y)->connect[i];
  725. X                    }
  726. X
  727. X                    if (square2->color == none && square2->value[none] <= 0)
  728. X                    {
  729. X                      square2->value[none] -= 1;
  730. X
  731. X                      if (square2->value[none] <= (-fillnumber))
  732. X                        square2->value[none] = 1;
  733. X
  734. X                      SQUARE(board,x,y)->move = 0;
  735. X                      SQUARE(board,x,y)->value[SQUARE(board,x,y)->color] = 0;
  736. X                      for (k=0; k<directions; k++)
  737. X                        SQUARE(board,x,y)->dir[k] = 0;
  738. X                      SQUARE(board,x,y)->lowbound = 0;
  739. X                      outdatehorizon (board, square2->x, square2->y, ALL);
  740. X                      outdated[x][y] = ALL;
  741. X                      outdated[square2->y][square2->y] = ALL;
  742. X                    }
  743. X                  }
  744. X                  else if (enable_hills || enable_forest)
  745. X                  {
  746. X                    if (enable_hills)
  747. X                      limit = NHILLTONES-1;
  748. X                    else if (enable_forest)
  749. X                      limit = NHILLTONES-1;
  750. X                    else if (enable_sea)
  751. X                      break;
  752. X
  753. X                    if (SQUARE(board,x,y)->value[none] < limit)
  754. X                    {
  755. X                      SQUARE(board,x,y)->value[none] += 1;
  756. X
  757. X                      SQUARE(board,x,y)->move = 0;
  758. X                      SQUARE(board,x,y)->value[SQUARE(board,x,y)->color] = 0;
  759. X                      for (k=0; k<8; k++)
  760. X                        SQUARE(board,x,y)->dir[k] = 0;
  761. X                      SQUARE(board,x,y)->lowbound = 0;
  762. X                      outdatehorizon (board, x, y, ALL);
  763. X                      outdated[x][y] = ALL;
  764. X                    }
  765. X                  }
  766. X                }
  767. X              }
  768. X              break;
  769. X
  770. X            case 's':
  771. X            case 'S':
  772. X              if (!enable_scuttle[colorarray[player]])
  773. X                break;
  774. X              if (SQUARE(board,x,y)->color == colorarray[player])
  775. X              {
  776. X                if (SQUARE(board,x,y)->growth >= 60 && !enable_build[colorarray[player]])
  777. X                {
  778. X                  val = SQUARE(board,x,y)->value[SQUARE(board,x,y)->color];
  779. X                 
  780. X                  SQUARE(board,x,y)->growth -= val; 
  781. X                  SQUARE(board,x,y)->oldgrowth = SQUARE(board,x,y)->growth;
  782. X
  783. X                  if (SQUARE(board,x,y)->growth < 60)
  784. X                  {
  785. X                    SQUARE(board,x,y)->growth = 0;
  786. X                    SQUARE(board,x,y)->oldgrowth = 0;
  787. X                    SQUARE(board,x,y)->angle = 0;
  788. X                  }
  789. X
  790. X                  SQUARE(board,x,y)->value[SQUARE(board,x,y)->color] -= val/2;
  791. X
  792. X                  outdatehorizon (board, x, y, SQUARE(board,x,y)->color);
  793. X                  outdated[x][y] = ALL;
  794. X                }
  795. X                else if (enable_build[colorarray[player]] && SQUARE(board,x,y)-> angle > 0 &&
  796. X                  SQUARE(board,x,y)->value[SQUARE(board,x,y)->color] >= scuttlerate[colorarray[player]])
  797. X                {
  798. X                  SQUARE(board,x,y)->angle -= buildrate[colorarray[player]];
  799. X                  SQUARE(board,x,y)->growth = 0;
  800. X                  if (SQUARE(board,x,y)->angle < 40)
  801. X                  {
  802. X                    SQUARE(board,x,y)->angle = 0; 
  803. X                    SQUARE(board,x,y)->growth = 0; 
  804. X                    SQUARE(board,x,y)->oldgrowth = 0; 
  805. X                  }
  806. X    
  807. X                  SQUARE(board,x,y)->value[SQUARE(board,x,y)->color] -= scuttlerate[colorarray[player]]; 
  808. X                  if (SQUARE(board,x,y)->value[SQUARE(board,x,y)->color] <= 0)
  809. X                  {
  810. X                      SQUARE(board,x,y)->move = 0;
  811. X                      SQUARE(board,x,y)->value[SQUARE(board,x,y)->color] = 0; 
  812. X                      for (k=0; k<directions; k++)
  813. X                        SQUARE(board,x,y)->dir[k] = 0;
  814. X                      SQUARE(board,x,y)->lowbound = 0;
  815. X                  }
  816. X
  817. X                  outdatehorizon (board, x, y, SQUARE(board,x,y)->color);
  818. X                  outdated[x][y] = ALL;
  819. X                }
  820. X              }
  821. X              break;
  822. X  
  823. X            case 'b':
  824. X            case 'B':
  825. X              if (!enable_build[colorarray[player]])
  826. X                break;
  827. X              if (SQUARE(board,x,y)->color == colorarray[player])
  828. X              {
  829. X                if (SQUARE(board,x,y)->value[SQUARE(board,x,y)->color] > (MAXVAL-2) &&
  830. X                      SQUARE(board,x,y)->angle < 23040)
  831. X                {
  832. X                  if (SQUARE(board,x,y)->oldgrowth < 55)
  833. X                    SQUARE(board,x,y)->oldgrowth = 100;
  834. X                  SQUARE(board,x,y)->angle += buildrate[colorarray[player]];
  835. X                  if (SQUARE(board,x,y)->angle >= 23000)
  836. X                  {
  837. X                    SQUARE(board,x,y)->angle = 23040; 
  838. X                    SQUARE(board,x,y)->growth = SQUARE(board,x,y)->oldgrowth;
  839. X                  }
  840. X  
  841. X                  SQUARE(board,x,y)->value[SQUARE(board,x,y)->color] = 0; 
  842. X                  SQUARE(board,x,y)->lowbound = 0;
  843. X                  outdatehorizon (board, x, y, SQUARE(board,x,y)->color);
  844. X                  outdated[x][y] = ALL;
  845. X                }
  846. X              }
  847. X              break;
  848. X
  849. X            case '0':
  850. X            case '1':
  851. X            case '2':
  852. X            case '3':
  853. X            case '4':
  854. X            case '5':
  855. X            case '6':
  856. X            case '7':
  857. X            case '8':
  858. X            case '9':
  859. X              if (!enable_reserve[colorarray[player]])
  860. X                break;
  861. X              if (SQUARE(board,x,y)->color == colorarray[player])
  862. X              {
  863. X                val = (double)(text[0] - '0')*MAXVAL/10.0;
  864. X                SQUARE(board,x,y)->lowbound = (int)(val);
  865. X
  866. X                status = xwindow[player]->drawletter[player];
  867. X                strcpy (line, xwindow[player]->letter[player]);
  868. X
  869. X                xwindow[player]->drawletter[player] = TRUE;
  870. X
  871. X                text[1] = '\0';
  872. X                strcpy (xwindow[player]->letter[player], text);
  873. X
  874. X                drawsquare(xwindow[player],SQUARE(board,x,y),colorarray[player],
  875. X                                                       squaresize[colorarray[player]]);
  876. X
  877. X                strcpy (xwindow[player]->letter[player], line);
  878. X                xwindow[player]->drawletter[player] = status;
  879. X              }
  880. X              break;
  881. X  
  882. X            default:
  883. X              break;
  884. X          }
  885. X        }
  886. X        else
  887. X          print_message(text,textcount,colorarray[player],player,board);
  888. X      }
  889. X      break;
  890. X  }
  891. X}
  892. X
  893. X
  894. X/*************************************************************************/
  895. X/**    dumpsquare                            **/
  896. X/** oft used routine for drawing updated square to all screens        **/
  897. X/**    Greg Lesher (lesher@park.bu.edu)                **/
  898. X/*************************************************************************/
  899. X
  900. Xdumpsquare (board, square)
  901. X  square_type *board,
  902. X              *square;
  903. X{
  904. X  int i;
  905. X
  906. X  for (i=0; i<nplayers; i++)
  907. X  {
  908. X    if (!winopen[i])
  909. X      continue;
  910. X    /**** draw if visible to player i ****/
  911. X    if (visible(board,colorarray[i],square->x,square->y))
  912. X    {
  913. X      if (enable_hidden[colorarray[i]])
  914. X      {
  915. X        if (square->color == colorarray[i])
  916. X          drawsquare(xwindow[i],square,colorarray[i],squaresize[colorarray[i]]);
  917. X      }
  918. X      else
  919. X        drawsquare(xwindow[i],square,colorarray[i],squaresize[colorarray[i]]);
  920. X    }
  921. X  }
  922. X  /**** store if necessary ****/
  923. X  if (enable_storage)
  924. X    storedrawsquare(square,squaresize[0]);
  925. X}
  926. X
  927. X
  928. X/*************************************************************************/
  929. X/**    getsquare                            **/
  930. X/** gets the board square corresponding to the window position        **/
  931. X/** and the direction from center within that square.  CSIZE is the     **/
  932. X/** minimum distance from the center of the square for the move to be    **/
  933. X/** encoded.                                **/
  934. X/**    Steve Lehar (slehar@park.bu.edu)                **/
  935. X/*************************************************************************/
  936. Xgetsquare(winx,winy,boardx,boardy,dir,squaresize, board, shift)
  937. X  int winx,winy,
  938. X      *boardx,*boardy,
  939. X      dir[DIRS],
  940. X      squaresize,
  941. X      shift;
  942. X  square_type *board;
  943. X{
  944. X  int i, j,
  945. X      done,
  946. X      dx, dy,
  947. X      row_even, col_even,
  948. X      modx, mody,
  949. X      xdiff, ydiff,
  950. X      xoff, yoff,
  951. X      xpos, ypos,
  952. X      col1, col2, row1, row2,
  953. X      min, minpos_i, minpos_j;
  954. X
  955. X  double temp;
  956. X
  957. X  if (enable_hex)
  958. X  {
  959. X    modx = (winx + hex_halfside)/(hex_side + hex_halfside);
  960. X    mody = (winy)/(hex_vert);
  961. X
  962. X    if (mody%2 == 0)
  963. X      row_even = TRUE;
  964. X    else
  965. X      row_even = FALSE;
  966. X
  967. X    if (modx%2 == 0)
  968. X      col_even = TRUE;
  969. X    else
  970. X      col_even = FALSE;
  971. X
  972. X    col1 = modx - 1;
  973. X    col2 = modx;
  974. X
  975. X    if (!row_even)
  976. X    {
  977. X      row1 = mody/2;
  978. X      row2 = row1;
  979. X    }
  980. X    else
  981. X    {
  982. X      if (col_even)
  983. X      {
  984. X        row1 = mody/2 - 1;
  985. X        row2 = mody/2;
  986. X      }
  987. X      else
  988. X      {
  989. X        row1 = mody/2;
  990. X        row2 = mody/2 - 1;
  991. X      }
  992. X    }
  993. X
  994. X    xpos = modx*(hex_side + hex_halfside) + hex_quarterside;
  995. X    ypos = mody*hex_vert + hex_halfvert;
  996. X
  997. X    xoff = winx - xpos;
  998. X    yoff = ypos - winy;
  999. X
  1000. X    temp = xoff * hex_slope;  
  1001. X
  1002. X    if ((!col_even && !row_even) || (col_even && row_even))
  1003. X    {
  1004. X      if (yoff > temp)
  1005. X      {
  1006. X        *boardx = col1;
  1007. X        *boardy = row1;
  1008. X      }
  1009. X      else
  1010. X      {
  1011. X        *boardx = col2;
  1012. X        *boardy = row2;
  1013. X      }
  1014. X    }
  1015. X    else
  1016. X    {
  1017. X      temp = -temp;
  1018. X
  1019. X      if (yoff > temp)
  1020. X      {
  1021. X        *boardx = col2;
  1022. X        *boardy = row2;
  1023. X      }
  1024. X      else
  1025. X      {
  1026. X        *boardx = col1;
  1027. X        *boardy = row1;
  1028. X      }
  1029. X    }
  1030. X
  1031. X    for (i=0; i<directions; i++)
  1032. X      dir[i] = 0;
  1033. X
  1034. X    done = FALSE;
  1035. X    if (*boardx < 0)
  1036. X    {
  1037. X      *boardx = 0;
  1038. X      done = TRUE;
  1039. X    }
  1040. X    else if (*boardx > boardsizex-1)
  1041. X    {
  1042. X      *boardx = boardsizex-1;
  1043. X      done = TRUE;
  1044. X    }
  1045. X
  1046. X    if (*boardy < 0)
  1047. X    {
  1048. X      *boardy = 0;
  1049. X      done = TRUE;
  1050. X    }
  1051. X    else if (*boardy > boardsizey-1)
  1052. X    {
  1053. X      *boardy = boardsizey-1;
  1054. X      done = TRUE;
  1055. X    }
  1056. X  
  1057. X    if (done)
  1058. X      return;
  1059. X
  1060. X    xoff = winx - SQUARE(board, *boardx, *boardy)->xpos + hex_side;
  1061. X    yoff = SQUARE(board, *boardx, *boardy)->ypos - winy + hex_vert;
  1062. X
  1063. X    if (hex_chart[xoff][yoff][0] >= 0)
  1064. X    {
  1065. X      dir[hex_chart[xoff][yoff][0]] = 1;
  1066. X      if (shift && hex_chart[xoff][yoff][1] >= 0)
  1067. X        dir[hex_chart[xoff][yoff][1]] = 1;
  1068. X    }
  1069. X  }
  1070. X  else
  1071. X  {
  1072. X    /**** compute board position & relative position ****/
  1073. X    *boardx = winx/squaresize;
  1074. X    *boardy = (winy)/squaresize;
  1075. X    dx = winx%squaresize - (squaresize/2);
  1076. X    dy = (winy)%squaresize - (squaresize/2);
  1077. X  
  1078. X    /**** encode relative position as dir ****/
  1079. X    if (dy<(-CSIZE)) dir[UP   ] = 1; else dir[UP   ] = 0;
  1080. X    if (dy > CSIZE)  dir[DOWN ] = 1; else dir[DOWN ] = 0;
  1081. X    if (dx > CSIZE)  dir[RIGHT] = 1; else dir[RIGHT] = 0;
  1082. X    if (dx<(-CSIZE)) dir[LEFT ] = 1; else dir[LEFT ] = 0;
  1083. X
  1084. X    if (abs(dx) < CSIZE && abs(dy) < CSIZE)
  1085. X      for (i=0; i<directions; i++)
  1086. X        dir[i] = 0;
  1087. X  }
  1088. X}
  1089. X
  1090. X
  1091. X/*************************************************************************/
  1092. X/**    removeplayer (player)                        **/
  1093. X/**  Remove player from the game.  If all players have been removed     **/
  1094. X/**  then quit the game.                        **/
  1095. X/**    Greg Lesher (lesher@park.bu.edu)                **/
  1096. X/*************************************************************************/
  1097. Xremoveplayer (player, board)
  1098. X  int player;
  1099. X  square_type *board;
  1100. X{
  1101. X  int i, j,
  1102. X      done,
  1103. X      limit;
  1104. X
  1105. X  char line[512];
  1106. X
  1107. X  winopen[player] = FALSE;
  1108. X  done = TRUE;
  1109. X  for (i=0; i<nplayers; i++)
  1110. X    if (winopen[i] && !winwatch[i])
  1111. X      done = FALSE;
  1112. X  
  1113. X  /**** free up all constructs ****/
  1114. X  for (j=0; j<nsides; j++)
  1115. X    XFreeGC(xwindow[player]->display, xwindow[player]->hue[j]);
  1116. X  XFreeGC(xwindow[player]->display, xwindow[player]->hue[none]);
  1117. X  XFreeGC(xwindow[player]->display, xwindow[player]->hue[dark]);
  1118. X  XFreeGC(xwindow[player]->display, xwindow[player]->hue[light]);
  1119. X
  1120. X  if (enable_terrain)
  1121. X  {
  1122. X    if (enable_hills)
  1123. X      limit = NHILLTONES;
  1124. X    else if (enable_forest)
  1125. X     limit = NFORESTTONES;
  1126. X    else if (enable_sea)
  1127. X      limit = NSEATONES;
  1128. X
  1129. X    for (j=0; j<limit; j++)
  1130. X      XFreePixmap(xwindow[player]->display, xwindow[player]->terrain[j]);
  1131. X  }
  1132. X
  1133. X  /**** remove player from game ****/
  1134. X  close_xwindow(xwindow[player]);
  1135. X
  1136. X  if (done)
  1137. X  {
  1138. X    for (i=0; i<nplayers; i++)
  1139. X    {
  1140. X      if (winopen[i])
  1141. X      {
  1142. X        removeplayer (i, board);
  1143. X      }
  1144. X    }
  1145. X
  1146. X    if (enable_storage || enable_replay)
  1147. X    {
  1148. X      if (enable_storage)
  1149. X        fprintf (fpout, "Q00");
  1150. X      fclose (fpout);
  1151. X    }
  1152. X    exit (0);
  1153. X  }
  1154. X  else
  1155. X  {
  1156. X    sprintf (line, "%s has quit the game", huename[sidemap[colorarray[player]]]);
  1157. X/**
  1158. X    sprintf (line, "%s (%s) has quit the game", huename[sidemap[colorarray[player]]],
  1159. X               grayname[color2bw[sidemap[colorarray[player]]]]); 
  1160. X**/
  1161. X
  1162. X    print_message(line,strlen(line),colorarray[player],player,board);
  1163. X
  1164. X    for (i=0; i<nplayers; i++)
  1165. X      if (winopen[i])
  1166. X        XBell(xwindow[i]->display,100);
  1167. X  }
  1168. X}
  1169. X
  1170. X
  1171. Xgamestats (board)
  1172. X  square_type *board;
  1173. X{
  1174. X  int i, j,
  1175. X      color,
  1176. X      force[MAXSIDES],
  1177. X      area[MAXSIDES];
  1178. X
  1179. X  for (i=0; i<nsides; i++)
  1180. X  {
  1181. X    force[i] = 0;
  1182. X    area[i] = 0;
  1183. X  }
  1184. X
  1185. X  for (i=0; i<boardsizex; i++)
  1186. X    for (j=0; j<boardsizey; j++)
  1187. X    {
  1188. X      color = SQUARE(board,i,j)->color;
  1189. X      if (color != FIGHT && color != none)
  1190. X      {
  1191. X        force[color] += SQUARE(board,i,j)->value[color];
  1192. X        area[color]++;
  1193. X      }
  1194. X    }
  1195. X
  1196. X  for (i=0; i<nsides; i++)
  1197. X    printf ("%s:  %3d squares   %5d force\n", huename[sidemap[i]], area[i], force[i]);
  1198. X  printf ("\n");
  1199. X}
  1200. X
  1201. X
  1202. X/*************************************************************************/
  1203. X/**    replaygame                            **/
  1204. X/**     replay game from file (non-functionally)            **/    
  1205. X/**    Greg Lesher (lesher@park.bu.edu)                **/
  1206. X/*************************************************************************/
  1207. Xreplaygame(squaresize,board)
  1208. X  int squaresize;
  1209. X  square_type *board;
  1210. X{
  1211. X  int i, j, k, l,
  1212. X      ipos, jpos,
  1213. X      count, done,
  1214. X      arg1, arg2, arg3, arg4,
  1215. X      hafpsize, hafc,
  1216. X      hafsquare,
  1217. X      offset, terrain_type;
  1218. X
  1219. X  static int xrand, yrand;
  1220. X
  1221. X  char type;
  1222. X
  1223. X  square_type *square;
  1224. X
  1225. X  hafsquare = squaresize/2;
  1226. X  done = FALSE;
  1227. X
  1228. X  for (count=0; !done; count++)
  1229. X  {
  1230. X    /**** This is the hack to get REPLAY message to work.  Note that the ****/
  1231. X    /**** number of loops to drawtime (500 below) appears to have an     ****/
  1232. X    /**** allowable minimum of 2 or 3 hundred.  We're confounded.        ****/
  1233. X
  1234. X    if (count == 500)
  1235. X    {
  1236. X      for (k=0; k<nplayers; k++)
  1237. X      {
  1238. X#if MULTITEXT
  1239. X        for (l=0; l<nsides; l++)
  1240. X          XDrawImageString(xwindow[k]->display,xwindow[k]->window,
  1241. X                          xwindow[k]->hue[light],
  1242. X               TEXTX,textyh[l],
  1243. X               messagestr,strlen(messagestr));
  1244. X#else
  1245. X        XDrawImageString(xwindow[k]->display,xwindow[k]->window,
  1246. X                          xwindow[k]->hue[light],
  1247. X               TEXTX,textyh[0],
  1248. X               messagestr,strlen(messagestr));
  1249. X        XDrawImageString(xwindow[k]->display,xwindow[k]->window,
  1250. X               xwindow[k]->hue[light],
  1251. X               TEXTX,textyl[0],
  1252. X               messagestr,strlen(messagestr));
  1253. X#endif
  1254. X        XSync (xwindow[k]->display, 0);
  1255. X        XFlush(xwindow[k]->display);
  1256. X      }
  1257. X    }
  1258. X
  1259. X    /**** load command and arguments ****/
  1260. X    type = fgetc (fpout); 
  1261. X    i = fgetc (fpout);
  1262. X    j = fgetc (fpout);
  1263. X    square = SQUARE(board,i,j);
  1264. X    if (enable_hex)
  1265. X    {
  1266. X      ipos = square->xpos;
  1267. X      jpos = square->ypos;
  1268. X    }
  1269. X    else
  1270. X    {
  1271. X      ipos = i*squaresize;
  1272. X      jpos = j*squaresize;
  1273. X    }
  1274. X
  1275. X    if (type == 'A' || type == 'a' || type == 'D' || type == 'E' || type == 'F' || type == 'G' ||
  1276. X        type == 'H' || type == 'I')
  1277. X    {
  1278. X      arg1 = fgetc (fpout);
  1279. X
  1280. X      if (type == 'D' || type == 'E' || type == 'G' || type == 'H' || type == 'I' || type == 'F')
  1281. X        arg2 = fgetc (fpout);
  1282. X
  1283. X      if (type == 'E')
  1284. X      {
  1285. X        arg3 = fgetc (fpout);
  1286. X        arg4 = fgetc (fpout);
  1287. X      }
  1288. X    }
  1289. X
  1290. X    /**** for each window ****/
  1291. X    for (k=0; k<nplayers; k++)
  1292. X    {
  1293. X      switch (type)
  1294. X      {
  1295. X        case 'A':
  1296. X          terrain_type = arg1; 
  1297. X          if (terrain_type > 128)
  1298. X            terrain_type = terrain_type - 256;
  1299. X
  1300. X          if (enable_hex)
  1301. X          {
  1302. X            offset = -2 * terrain_type;
  1303. X
  1304. X            if (terrain_type < 0)
  1305. X            {
  1306. X              double_copy (xwindow[k], square, colorarray[k], squaresize, terrain_type, 0);
  1307. X              terrain_type = 0;
  1308. X            }
  1309. X            else
  1310. X              offset = 0;
  1311. X
  1312. X            if (terrain_type == 1 && !enable_hills && !enable_forest)
  1313. X              XFillArc (xwindow[k]->display,xwindow[k]->window, xwindow[k]->hue[none],
  1314. X                     ipos-(hex_vert-1), jpos-(hex_vert-1), 2*(hex_vert-1), 2*(hex_vert-1), 0, 23040);
  1315. X            else
  1316. X              double_copy (xwindow[k], square, colorarray[k], squaresize, terrain_type, offset);
  1317. X          }
  1318. X          else
  1319. X          {
  1320. X            offset = ((double)(-terrain_type) * squaresize)/(2*fillnumber);
  1321. X
  1322. X            if (terrain_type < 0)
  1323. X              terrain_type = 0;
  1324. X            else
  1325. X              offset = 0;
  1326. X
  1327. X            if (offset != 0)
  1328. X              XCopyArea (xwindow[k]->display, xwindow[k]->terrain[1], xwindow[k]->window,
  1329. X                  xwindow[k]->hue[dark], 0, 0, squaresize, squaresize, ipos, jpos);
  1330. X
  1331. X            XCopyArea (xwindow[k]->display, xwindow[k]->terrain[terrain_type], xwindow[k]->window,
  1332. X                          xwindow[k]->hue[dark], 0, 0, squaresize-2*offset, squaresize-2*offset,
  1333. X                          ipos+offset, jpos+offset);
  1334. X          }
  1335. X          break;
  1336. X
  1337. X        case 'B':
  1338. X          if (enable_hex)
  1339. X          {
  1340. X            XFillArc (xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[none],
  1341. X                 ipos-(hex_vert-1), jpos-(hex_vert-1), 2*(hex_vert-1), 2*(hex_vert-1), 0, 23040);
  1342. X          }
  1343. X          else
  1344. X            XFillRectangle(xwindow[k]->display,xwindow[k]->window, xwindow[k]->hue[none],
  1345. X                     ipos, jpos, squaresize, squaresize);
  1346. X          break;
  1347. X
  1348. X        case 'b':
  1349. X          if (enable_hex)
  1350. X            blanksquare(xwindow[k], square, colorarray[k], squaresize, TRUE);
  1351. X          XSync (xwindow[k]->display, 0);
  1352. X          break;
  1353. X  
  1354. X        case 'C':
  1355. X          XDrawRectangle(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[dark],
  1356. X                     ipos+hafsquare-CSIZE, jpos+hafsquare-CSIZE, 2*CSIZE, 2*CSIZE);
  1357. X          break;
  1358. X  
  1359. X        case 'D':
  1360. X          hafpsize = arg1/2;
  1361. X          if (enable_hex)
  1362. X          {
  1363. X            XFillArc (xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg2],
  1364. X                            ipos-hafpsize, jpos-hafpsize, arg1, arg1, 0, 23040);
  1365. X
  1366. X          }
  1367. X          else
  1368. X          {
  1369. X            XDrawRectangle(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[dark],
  1370. X                       ipos+hafsquare-CSIZE, jpos+hafsquare-CSIZE, 2*CSIZE, 2*CSIZE);
  1371. X
  1372. X            XFillRectangle(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[arg2],
  1373. X                       ipos+hafsquare-hafpsize, jpos+hafsquare-hafpsize, arg1, arg1);
  1374. X          }
  1375. X          break;
  1376. X  
  1377. X        case 'E':
  1378. X
  1379. X          if (enable_hex)
  1380. X          {
  1381. X            hafpsize = arg1/2;
  1382. X            XFillArc (xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg2],
  1383. X                      ipos-hafpsize, jpos-hafpsize, arg1, arg1, 0, 23040);
  1384. X            hafpsize = arg3/2;
  1385. X            XFillArc (xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg4],
  1386. X                      ipos-hafpsize, jpos-hafpsize, arg3, arg3, 0, 23040);
  1387. X          }
  1388. X          else
  1389. X          {
  1390. X            hafpsize = arg1/2;
  1391. X            XFillRectangle(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[arg2],
  1392. X                       ipos+hafsquare-hafpsize,
  1393. X                       jpos+hafsquare-hafpsize, arg1, arg1);
  1394. X            hafpsize = arg3/2;
  1395. X            XFillRectangle(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[arg4],
  1396. X                       ipos+hafsquare-hafpsize,
  1397. X                       jpos+hafsquare-hafpsize, arg3, arg3);
  1398. X          }
  1399. X          break;
  1400. X  
  1401. X        case 'F':
  1402. X  
  1403. X          if (enable_hex)
  1404. X          {
  1405. X            hafc = arg1/2;
  1406. X
  1407. X            XDrawArc(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[dark],
  1408. X                     ipos-hafc, jpos-hafc, arg1, arg1, 0, (arg2*23040)/255);
  1409. X
  1410. X            XDrawArc(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[dark],
  1411. X                     ipos-hafc + 1, jpos-hafc + 1, arg1 - 2, arg1 - 2, 0, (arg2*23040)/255);
  1412. X          }
  1413. X          else
  1414. X          {
  1415. X            hafc = (squaresize-arg1)/2;
  1416. X            XDrawArc(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[dark],
  1417. X                       ipos+hafc, jpos+hafc,
  1418. X                       arg1, arg1, 0, (arg2*23040)/255);
  1419. X  
  1420. X            XDrawArc(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[dark],
  1421. X                       ipos+hafc + 1, jpos+hafc + 1,
  1422. X                       arg1 - 2, arg1 - 2, 0, (arg2*23040)/255);
  1423. X          }
  1424. X  
  1425. X          break;
  1426. X  
  1427. X        case 'G':
  1428. X          if (enable_hex)
  1429. X          {
  1430. X            if (arg2 == 'u')
  1431. X            {
  1432. X              XDrawLine(xwindow[k]->display,xwindow[k]->window, xwindow[k]->hue[arg1],
  1433. X                                     ipos, jpos, ipos, jpos - hex_vert + 2);
  1434. X              XDrawLine(xwindow[k]->display,xwindow[k]->window, xwindow[k]->hue[arg1],
  1435. X                                     ipos+1, jpos, ipos+1, jpos - hex_vert + 2);
  1436. X              XDrawLine(xwindow[k]->display,xwindow[k]->window, xwindow[k]->hue[arg1],
  1437. X                                     ipos-1, jpos, ipos-1, jpos - hex_vert + 2);
  1438. X            }
  1439. X            if (arg2 == 'd')
  1440. X            {
  1441. X              XDrawLine(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg1],
  1442. X                                     ipos, jpos, ipos, jpos + hex_vert - 2);
  1443. X              XDrawLine(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg1],
  1444. X                                     ipos+1, jpos, ipos+1, jpos + hex_vert - 2);
  1445. X              XDrawLine(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg1],
  1446. X                                     ipos-1, jpos, ipos-1, jpos + hex_vert - 2);
  1447. X
  1448. X            }
  1449. X            if (arg2 == 'R')
  1450. X            {
  1451. X              XDrawLine(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg1],
  1452. X                           ipos, jpos, ipos + hex_3quarterside - 1, jpos - hex_halfvert + 1);
  1453. X              XDrawLine(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg1],
  1454. X                           ipos+1, jpos, ipos+1 + hex_3quarterside - 1, jpos - hex_halfvert + 1);
  1455. X              XDrawLine(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg1],
  1456. X                           ipos, jpos-1, ipos+1 + hex_3quarterside - 1, jpos-1 - hex_halfvert + 1);
  1457. X            }
  1458. X            if (arg2 == 'r')
  1459. X            {
  1460. X              XDrawLine(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg1],
  1461. X                           ipos, jpos, ipos + hex_3quarterside - 1, jpos + hex_halfvert - 1);
  1462. X              XDrawLine(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg1],
  1463. X                           ipos+1, jpos, ipos+1 + hex_3quarterside - 1, jpos + hex_halfvert - 1);
  1464. X              XDrawLine(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg1],
  1465. X                           ipos, jpos+1, ipos + hex_3quarterside - 1, jpos+1 + hex_halfvert - 1);
  1466. X            }
  1467. X            if (arg2 == 'L')
  1468. X            {
  1469. X              XDrawLine(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg1],
  1470. X                           ipos, jpos, ipos - hex_3quarterside + 1, jpos - hex_halfvert + 1);
  1471. X              XDrawLine(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg1],
  1472. X                           ipos-1, jpos, ipos-1 - hex_3quarterside + 1, jpos - hex_halfvert + 1);
  1473. X              XDrawLine(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg1],
  1474. X                           ipos, jpos-1, ipos - hex_3quarterside + 1, jpos-1 - hex_halfvert + 1);
  1475. X            }
  1476. X            if (arg2 == 'l')
  1477. X            {
  1478. X              XDrawLine(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg1],
  1479. X                           ipos, jpos, ipos - hex_3quarterside + 1, jpos + hex_halfvert - 1);
  1480. X              XDrawLine(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg1],
  1481. X                           ipos-1, jpos, ipos-1 - hex_3quarterside + 1, jpos + hex_halfvert - 1);
  1482. X              XDrawLine(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg1],
  1483. X                           ipos, jpos+1, ipos - hex_3quarterside + 1, jpos+1 + hex_halfvert - 1);
  1484. X
  1485. X            }
  1486. X          }
  1487. X          else
  1488. X          {
  1489. X            ipos = ipos+hafsquare;
  1490. X            jpos = jpos+hafsquare;
  1491. X            if (arg2 == 'u')
  1492. X            {
  1493. X              XDrawLine(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[arg1],
  1494. X                       ipos-1, jpos, ipos-1, jpos-hafsquare);
  1495. X              XDrawLine(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[arg1],
  1496. X                       ipos, jpos, ipos, jpos-hafsquare);
  1497. X              XDrawLine(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[arg1],
  1498. X                       ipos+1, jpos, ipos+1, jpos-hafsquare);
  1499. X            }
  1500. X            else if (arg2 == 'd')
  1501. X            {
  1502. X              XDrawLine(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[arg1],
  1503. X                       ipos-1, jpos, ipos-1, jpos+hafsquare-1);
  1504. X              XDrawLine(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[arg1],
  1505. X                       ipos, jpos, ipos, jpos+hafsquare-1);
  1506. X              XDrawLine(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[arg1],
  1507. X                       ipos+1, jpos, ipos+1, jpos+hafsquare-1);
  1508. X  
  1509. X            }
  1510. X            else if (arg2 == 'r')
  1511. X            {
  1512. X              XDrawLine(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[arg1],
  1513. X                       ipos, jpos-1, ipos+hafsquare-1, jpos-1);
  1514. X              XDrawLine(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[arg1],
  1515. X                       ipos, jpos, ipos+hafsquare-1, jpos);
  1516. X              XDrawLine(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[arg1],
  1517. X                       ipos, jpos+1, ipos+hafsquare-1, jpos+1);
  1518. X            }
  1519. X            else if (arg2 == 'l')
  1520. X            {
  1521. X              XDrawLine(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[arg1],
  1522. X                       ipos, jpos-1, ipos-hafsquare, jpos-1);
  1523. X              XDrawLine(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[arg1],
  1524. X                       ipos, jpos, ipos-hafsquare, jpos);
  1525. X              XDrawLine(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[arg1],
  1526. X                       ipos, jpos+1, ipos-hafsquare, jpos+1);
  1527. X            }
  1528. X          }
  1529. X          break;
  1530. X  
  1531. X        case 'H':
  1532. X          if (enable_hex)
  1533. X          {
  1534. X            xrand = (xrand+2938345)%hex_side;
  1535. X            yrand = (yrand+2398321)%hex_side;
  1536. X
  1537. X            hafc = arg1/2;
  1538. X
  1539. X            XFillArc(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg2],
  1540. X                     ipos - hafc + xrand - hex_halfside,
  1541. X                     jpos - hafc + yrand - hex_halfside,
  1542. X                     arg1, arg1, 0, 23040);
  1543. X          }
  1544. X          else
  1545. X          {
  1546. X            xrand = (xrand+2938345)%(squaresize/2);
  1547. X            yrand = (yrand+2398321)%(squaresize/2);
  1548. X  
  1549. X            hafc = (squaresize-arg1)/2; 
  1550. X  
  1551. X            XFillArc(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[arg2],
  1552. X                     ipos+hafc+xrand-squaresize/4, jpos+hafc+yrand-squaresize/4,
  1553. X                     arg1, arg1, 0, 23040);
  1554. X          }
  1555. X          break;
  1556. X  
  1557. X        case 'I':
  1558. X          if (enable_hex)
  1559. X          {
  1560. X            xrand = (xrand+2938345)%hex_side;
  1561. X            yrand = (yrand+2398321)%hex_side;
  1562. X
  1563. X            hafc = arg1/2;
  1564. X
  1565. X            XFillArc(xwindow[k]->display, xwindow[k]->window, xwindow[k]->hue[arg2],
  1566. X                     ipos - hafc + xrand - hex_halfside, jpos - hafc + yrand - hex_halfside,
  1567. X                     arg1, arg1, 0, 11520);
  1568. X          }
  1569. X          else
  1570. X          {
  1571. X            xrand = (xrand+2938345)%(squaresize/2);
  1572. X            yrand = (yrand+2398321)%(squaresize/2);
  1573. X  
  1574. X            hafc = (squaresize-arg1)/2; 
  1575. X  
  1576. X            XFillArc(xwindow[k]->display,xwindow[k]->window,xwindow[k]->hue[arg2],
  1577. X                     ipos+hafc+xrand-squaresize/4,
  1578. X                     jpos+hafc+yrand-squaresize/4,
  1579. X                     arg1, arg1, 0, 11520);
  1580. X          }
  1581. X          break;
  1582. X
  1583. X        case 'J':
  1584. X          XSync (xwindow[k]->display, 0);
  1585. X          break;
  1586. X  
  1587. X        case 'Q':
  1588. X          XSync (xwindow[k]->display, 0);
  1589. X          done = TRUE;
  1590. X          break;
  1591. X  
  1592. X        default:
  1593. X          /**** try to recover from bad input ****/
  1594. X          printf ("%c %d %d %d %d\n", type, i, j, arg1, arg2);
  1595. X          while (type < 'A' || type > 'J' && type != 'Q')
  1596. X            type = fgetc(fpout);
  1597. X          ungetc (type, fpout);
  1598. X          printf ("TROUBLE\n");
  1599. X          exit (0);
  1600. X          break;
  1601. X      }
  1602. X      /**** make sure window is flushed regularly ****/
  1603. X      if ((count % 15) == 0)
  1604. X        XSync (xwindow[k]->display, 0);
  1605. X    }
  1606. X  }
  1607. X
  1608. X  while (TRUE);
  1609. X}
  1610. X
  1611. END_OF_FILE
  1612. if test 48734 -ne `wc -c <'main.c'`; then
  1613.     echo shar: \"'main.c'\" unpacked with wrong size!
  1614. fi
  1615. # end of 'main.c'
  1616. fi
  1617. if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  1618.   echo shar: Will not clobber existing file \"'patchlevel.h'\"
  1619. else
  1620. echo shar: Extracting \"'patchlevel.h'\" \(4 characters\)
  1621. sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
  1622. X4.0
  1623. END_OF_FILE
  1624. if test 4 -ne `wc -c <'patchlevel.h'`; then
  1625.     echo shar: \"'patchlevel.h'\" unpacked with wrong size!
  1626. fi
  1627. # end of 'patchlevel.h'
  1628. fi
  1629. if test -f 'tribal.xbo' -a "${1}" != "-c" ; then 
  1630.   echo shar: Will not clobber existing file \"'tribal.xbo'\"
  1631. else
  1632. echo shar: Extracting \"'tribal.xbo'\" \(95 characters\)
  1633. sed "s/^X//" >'tribal.xbo' <<'END_OF_FILE'
  1634. X-decay 2
  1635. X-sea 8
  1636. X-square 32
  1637. X-board 24
  1638. X-farms 7
  1639. X-militia 10
  1640. X-repeat
  1641. X-fill 4
  1642. X-dig 4
  1643. X-area
  1644. X-attack
  1645. END_OF_FILE
  1646. if test 95 -ne `wc -c <'tribal.xbo'`; then
  1647.     echo shar: \"'tribal.xbo'\" unpacked with wrong size!
  1648. fi
  1649. # end of 'tribal.xbo'
  1650. fi
  1651. echo shar: End of archive 2 \(of 7\).
  1652. cp /dev/null ark2isdone
  1653. MISSING=""
  1654. for I in 1 2 3 4 5 6 7 ; do
  1655.     if test ! -f ark${I}isdone ; then
  1656.     MISSING="${MISSING} ${I}"
  1657.     fi
  1658. done
  1659. if test "${MISSING}" = "" ; then
  1660.     echo You have unpacked all 7 archives.
  1661.     rm -f ark[1-9]isdone
  1662. else
  1663.     echo You still need to unpack the following archives:
  1664.     echo "        " ${MISSING}
  1665. fi
  1666. ##  End of shell archive.
  1667. exit 0
  1668.