home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume14 / xbattle / part07 < prev    next >
Encoding:
Internet Message Format  |  1993-01-26  |  47.4 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: v14i078:  xbattle - multi-player battle strategy game for X-Windows, Part07/07
  5. Message-ID: <3517@master.CNA.TEK.COM>
  6. Date: 7 Sep 92 21:23:46 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 1377
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: slehar@cns.bu.edu
  12. Posting-number: Volume 14, Issue 78
  13. Archive-name: xbattle/Part07
  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 7 (of 7)."
  25. # Contents:  tutorial1 utils.c
  26. # Wrapped by billr@saab on Mon Sep  7 14:18:51 1992
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'tutorial1' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'tutorial1'\"
  30. else
  31. echo shar: Extracting \"'tutorial1'\" \(17781 characters\)
  32. sed "s/^X//" >'tutorial1' <<'END_OF_FILE'
  33. X#! /bin/sh
  34. X
  35. Xecho "=================== XBATTLE TUTORIAL ========================" 
  36. Xecho "hit RETURN to continue"
  37. Xread p1
  38. Xclear
  39. Xecho "The xbattle  game  board is a grid  of  squares that can contain"
  40. Xecho "troops of different colors-  or shades  of  gray if  you  have a"
  41. Xecho "monochrome monitor.  Here is a small xbattle game board that was"
  42. Xecho "started with the command..."
  43. Xecho
  44. Xecho "> xbattle -black me -board 5 -square 64 -manpos -armies 1"
  45. X
  46. Xxbattle -black me -board 5 -square 64  -manpos -armies 1&
  47. X
  48. Xecho
  49. X
  50. Xecho "This means- run xbattle, my color is  black, the board size is 5"
  51. Xecho "x 5 game squares, and each game square is 64 x 64 pixels, use"
  52. Xecho "manual positioning of the window, and give me one army."
  53. X
  54. Xecho
  55. Xecho "hit RETURN to continue"
  56. Xread p1
  57. Xclear
  58. X
  59. Xecho "The square in the  middle  represents an army  of  black troops,"
  60. Xecho "which you can command by clicking with the mouse.  The direction"
  61. Xecho "in which the  troops march  depends on where  in the game square"
  62. Xecho "you click the  mouse- each  game square  is divided into regions"
  63. Xecho "like this..."
  64. X
  65. Xecho
  66. X
  67. Xecho "              GAME SQUARE"
  68. Xecho "       =============================="
  69. Xecho "       ||        |        |        ||"
  70. Xecho "       || up &   | march  | up &   ||"
  71. Xecho "       || left   |  up    | right  ||"
  72. Xecho "       ||        |        |        ||"
  73. Xecho "       ||--------|--------|--------||"
  74. Xecho "       ||        |        |        ||"
  75. Xecho "       || march  | stop   | march  ||"
  76. Xecho "       || left   |        | right  ||"
  77. Xecho "       ||        |        |        ||"
  78. Xecho "       ||--------|--------|--------||"
  79. Xecho "       ||        |        |        ||"
  80. Xecho "       || down & | march  | down & ||"
  81. Xecho "       ||  left  |  down  | right  ||"
  82. Xecho "       ||        |        |        ||"
  83. Xecho "       =============================="
  84. X
  85. Xecho
  86. X
  87. Xecho "so,  for instance, to march  to the right,   you click near  the"
  88. Xecho "right edge of the game square, and you will see a command vector"
  89. Xecho "appear, pointing right.   Your  troop  square  will now  rapidly"
  90. Xecho "shrink, and  the neighboring   square will  grow, as  the troops"
  91. Xecho "march from one square to the next.  If you click near the corner"
  92. Xecho "of  the game  square  the troops  will split   and  move in both"
  93. Xecho "directions  at the same   time.   March  your troops  around the"
  94. Xecho "little game board to get the feel of the commands."
  95. X
  96. Xecho
  97. X
  98. Xecho "Notice that the left mouse button toggles the command vectors on"
  99. Xecho "or  off, while  the  middle mouse  button  clears   all existing"
  100. Xecho "command vectors  and replaces them   with the new one.  Try  out"
  101. Xecho "both these command modes.  For most practical purposes  you will"
  102. Xecho "probably find the middle mouse to be more useful."
  103. X
  104. Xecho
  105. Xecho "hit RETURN to continue"
  106. Xread p1
  107. Xclear
  108. X
  109. Xecho "There is a text line under the game board. Commands issued while"
  110. Xecho "the mouse is in the text area will be interpreted differently to"
  111. Xecho "commands issued on the  game  board.  Position your mouse in the"
  112. Xecho "text area, and  type control-c, (i.e. hold  the control  key and"
  113. Xecho "type c) and  the game should quit.  Quit   the game  before  you"
  114. Xecho "continue."
  115. X
  116. Xecho
  117. Xecho "hit RETURN to continue"
  118. Xread p1
  119. Xclear
  120. X
  121. Xecho
  122. X
  123. Xecho "Now we will start a  game with two  opposing armies,  black  and"
  124. Xecho "white, and you can practice attacking the enemy.   The game will"
  125. Xecho "be started with the command line..."
  126. Xecho
  127. Xecho "> xbattle -black me -white me -board 6 -manpos -armies 4"
  128. Xecho
  129. X
  130. Xecho
  131. Xecho "This time,  the board  is  6 x  6,  and the square   size is the"
  132. Xecho "default size.  The argument '-armies 4' creates four  armies for"
  133. Xecho "each team and arranges them in opposing ranks.  You will have to"
  134. Xecho "position two windows this time, black and white, place them next"
  135. Xecho "to each other so that you can see them both.   You will  only be"
  136. Xecho "able to command the black  troops in the  black window, and  the"
  137. Xecho "white troops from the white  window,  although both windows will"
  138. Xecho "show the same game board.  Later on, you will be opening the two"
  139. Xecho "windows on separate displays to play against an opponent on that"
  140. Xecho "display; for now, you will be controlling both sides."
  141. Xecho
  142. Xecho "You  can   also   choose '-light' and    '-dark'  team colors on"
  143. Xecho "monochrome monitors, while  color monitors will  display '-red',"
  144. Xecho "'-green', '-blue',  '-cyan',   '-magenta', and  '-yellow'   team"
  145. Xecho "colors as well    as the monochrome ones.  If    you are playing"
  146. Xecho "between color  and monochrome  monitors, you  can   even  define"
  147. Xecho "hybrid colors such as '-redblack' (color name first), which will"
  148. Xecho "appear  red on the  color and black  on the monochrome monitors."
  149. Xecho "Pure colors like '-red' will appear  on monochrome monitors with"
  150. Xecho "a letter 'R' in each square."
  151. Xecho
  152. X
  153. Xecho
  154. Xecho "hit RETURN to continue"
  155. Xread p1
  156. Xclear
  157. X
  158. Xxbattle -black me -white me -board 6 -manpos -armies 4&
  159. X
  160. Xecho "You can see the two  battle lines drawn  up opposite each other."
  161. Xecho "Command one of the  black squares to  march into a white square."
  162. Xecho "You will see that with  equal  initial strength, the attacker is"
  163. Xecho "under  a disadvantage and  suffers  much more loss, although the"
  164. Xecho "white might suffer some loss from the attack."
  165. X
  166. Xecho
  167. X
  168. Xecho "Now try something  else- in  the white window, command the white"
  169. Xecho "troops  to  scatter all over   the  game board, splitting   into"
  170. Xecho "smaller sections by clicking  near the  corners.   Then form the"
  171. Xecho "remaining  black squares into a column,  and command the head of"
  172. Xecho "the column to attack the smallest white squares one by one.  You"
  173. Xecho "will see that  this has a  much greater effect.  During  battle,"
  174. Xecho "both sides can suffer damage,  but when the  opposing forces are"
  175. Xecho "unequal, the smaller force suffers  much greater  losses, so you"
  176. Xecho "should always   strive for local  superiority   to minimize your"
  177. Xecho "losses."
  178. X
  179. Xecho
  180. X
  181. Xecho "Try arranging flanking attacks by surrounding white squares from"
  182. Xecho "two or more sides, and  then attacking simultaneously.  You must"
  183. Xecho "click quickly to   assure  a  simultaneous attack in    order to"
  184. Xecho "achieve maximum effect.  Here is another rule of xbattle- that a"
  185. Xecho "simultaneous assault from two  or more directions  increases the"
  186. Xecho "effectiveness of the attack.  "
  187. X
  188. Xecho
  189. X
  190. Xecho "Notice that during an attack,  both colors are displayed  in the"
  191. Xecho "game  square in their  proper proportions, with a crossed-swords"
  192. Xecho "battle symbol as long as the battle continues."
  193. X
  194. Xecho
  195. Xecho "hit RETURN to continue"
  196. Xread p1
  197. Xclear
  198. X
  199. Xecho "Notice that the text  area now contains two  lines, one for each"
  200. Xecho "team.  Position your mouse in the text area and  type some keys-"
  201. Xecho "you will see the characters appearing on both windows.  When the"
  202. Xecho "opposing teams are  run from remote sites, the  text line can be"
  203. Xecho "used to communicate between the windows."
  204. X
  205. Xecho
  206. X
  207. Xecho "Now, type control-c in both windows and quit the game before you"
  208. Xecho "continue."
  209. X
  210. Xecho
  211. Xecho "hit RETURN to continue"
  212. Xread p1
  213. Xclear
  214. X
  215. Xecho "We will now experiment with resupply- in the next  game you will"
  216. Xecho "see circles   in some  of  the   game  squares.    These circles"
  217. Xecho "represent supply sources, and if you  capture one, it becomes an"
  218. Xecho "endless supply of  additional troops   of your color.  The  game"
  219. Xecho "board can soon be swamped by the excess troops if you  move them"
  220. Xecho "around."
  221. X
  222. Xecho 
  223. X
  224. Xecho "This game was started with the command..."
  225. X
  226. Xecho
  227. Xecho "> xbattle -red me -board 6 -manpos -armies 1 -towns 5"
  228. Xecho
  229. X
  230. Xecho "where  the argument  -towns 5  provided  for randomly positioned"
  231. Xecho "towns (the circles) with  randomly varying sizes with  a density"
  232. Xecho "of  5.  Almost all arguments in  xbattle range between 0 and 10,"
  233. Xecho "so that 5 is generally a mid value.  Notice  also that this time"
  234. Xecho "your color is given as red.  If you are  on a color monitor, you"
  235. Xecho "will  see  your troops as   red.  If  you   are  on a monochrome"
  236. Xecho "monitor, they  will  be black, with  a letter 'R'  in each troop"
  237. Xecho "square to denote the color."
  238. Xecho
  239. Xecho "Quit the  game  before you continue"
  240. Xecho
  241. X
  242. Xxbattle -red me -board 6 -manpos -armies 1 -towns 5&
  243. X
  244. Xecho
  245. Xecho "hit RETURN to continue"
  246. Xread p1
  247. Xclear
  248. X
  249. Xecho "In the next example we  will add  a certain decay to the troops,"
  250. Xecho "which means that the troops will consume their  provisions  at a"
  251. Xecho "rate proportional to  the number of  troops.  That  means that a"
  252. Xecho "single supply base can only  support a certain number of troops,"
  253. Xecho "so that the  number of troops  will only  grow until it  reaches"
  254. Xecho "that size.  Try to generate as many  troops as you  can from the"
  255. Xecho "single supply base.  This game was started with the command..."
  256. X
  257. Xecho
  258. Xecho "> xbattle -blueblack me -board 6 -manpos -rbases 1 -decay 10 -speed 10"
  259. Xecho
  260. X
  261. Xxbattle -blueblack me -board 6 -manpos -rbases 1 -decay 10 -speed 10&
  262. X
  263. Xecho 
  264. X
  265. Xecho "In this game we use the argument '-rbases 1' which will create 1"
  266. Xecho "full sized base for each team and position them randomly  on the"
  267. Xecho "game  board.   Notice  also  that this  time  we   use the color"
  268. Xecho "'blueblack', which means blue on a color monitor but black  on a"
  269. Xecho "monochrome monitor.  The color name must come first."
  270. X
  271. Xecho
  272. X
  273. Xecho "Notice that the shorter the supply line, the larger  the size of"
  274. Xecho "the army that can be maintained.   This is because of the losses"
  275. Xecho "along the supply line.  Also,  troops  cut  off from the  supply"
  276. Xecho "base will  wither   away   and  die.  In  this  example  we also"
  277. Xecho "increased the speed of  the simulation with  the argument -speed"
  278. Xecho "10, which  is  normally set to  the default -speed 5.   quit the"
  279. Xecho "game before you continue"
  280. X
  281. Xecho
  282. Xecho "hit RETURN to continue"
  283. Xread p1
  284. Xclear
  285. X
  286. Xecho "In the next example we will use another form of resupply, called"
  287. Xecho "farms.  Here, every square on the gameboard produces troops at a"
  288. Xecho "steady rate, controlled by the size of the argument, so that the"
  289. Xecho "larger  the area that you occupy,  the larger the  army that you"
  290. Xecho "can sustain.  This simulation was started with the command..."
  291. X
  292. Xecho
  293. Xecho "> xbattle -light me -board 6 -manpos -farms 9 -militia 9 -decay 5 -speed 10 -repeat"
  294. Xecho
  295. X
  296. Xecho "and in this case we make use  of another option, called militia,"
  297. Xecho "which creates  troops of random size in  random locations on the"
  298. Xecho "game board.  Again, try to  create  the largest  army you can by"
  299. Xecho "funneling the   production  of   all  the farms  into   a single"
  300. Xecho "location.  This simulates  the large  scale dynamics of   troops"
  301. Xecho "living  off  the fat  of    the land.  Also,   in  this game, we"
  302. Xecho "demonstrate the -repeat option- if you corner-click one  army to"
  303. Xecho "march north-east,  for  example,  then  rapidly click  in  other"
  304. Xecho "squares  using the  RIGHT mouse   button, the north-east command"
  305. Xecho "will be repeated in these squares.  For multiple repeated clicks"
  306. Xecho "the -repeat option can save you a lot of time aiming  the mouse."
  307. Xecho "Note also that we use the color 'light' which  means light gray."
  308. Xecho "There are four monochrome colors, black, white, light and dark."
  309. Xecho
  310. Xecho "Quit the game before you continue."
  311. X
  312. Xxbattle -light me -board 6 -square 48 -manpos -farms 9 -militia 9 -decay 5 -speed 10 -repeat&
  313. X
  314. Xecho
  315. Xecho "hit RETURN to continue"
  316. Xread p1
  317. Xclear
  318. X
  319. Xecho "In the next examples, we will demonstrate three types of terrain"
  320. Xecho "that can be used with xbattle-  seas,  hills, and forests.  Seas"
  321. Xecho "are simply regions that cannot be traversed by  land troops, and"
  322. Xecho "thus can  be  used  for  defensive strategy.   The  command line"
  323. Xecho "argument -seas  5 will create random  seas with  a density of 5."
  324. Xecho "We will also demonstrate the -hex  option, which creates a board"
  325. Xecho "of hexagons rather than squares,  but the commands work  in  the"
  326. Xecho "same way."
  327. Xecho
  328. Xecho "Quit the game before you continue."
  329. X
  330. Xecho
  331. Xecho "> xbattle -black me -farms 5 -militia 5 -decay 5 -sea 5 -hex"
  332. Xecho
  333. X
  334. Xecho
  335. Xecho "hit RETURN to start the game"
  336. Xread p1
  337. Xclear
  338. X
  339. Xxbattle -black me -farms 5 -militia 5 -decay 5 -sea 5 -hex&
  340. X
  341. Xecho
  342. Xecho "Quit the game before you continue."
  343. Xread p1
  344. Xclear
  345. X
  346. Xecho "Hills are represented  as various shades  of gray on monochrome"
  347. Xecho "monitors, or shades  of green on  color monitors.  Progress  up"
  348. Xecho "hills is much slower than on the level, but faster again on the"
  349. Xecho "way  down.  The  steepness of   the hills  is  controled by the"
  350. Xecho "argument."
  351. Xecho "Quit the game before you continue."
  352. X
  353. Xecho
  354. Xecho "> xbattle -black me -farms 5 -militia 5 -decay 5 -hills 9 -hex"
  355. Xecho
  356. X
  357. Xecho
  358. Xecho "hit RETURN to start the game"
  359. Xread p1
  360. Xclear
  361. X
  362. Xxbattle -black me -farms 5 -militia 5 -decay 5 -hills 9  -hex&
  363. X
  364. Xecho "wait... it takes a while to initialize the gray tones"
  365. Xecho
  366. Xecho "hit RETURN to continue"
  367. Xread p1
  368. Xclear
  369. X
  370. Xecho "You may have noticed that when you run xbattle, it always prints"
  371. Xecho "something like 'seed:  714326158'.   This is the  random  number"
  372. Xecho "seed that xbattle uses to initialize all the random  features in"
  373. Xecho "the game.    By default, xbattle  generates a new  seed every game."
  374. Xecho "but you can specify a particular  seed with the parameter '-seed"
  375. Xecho "<n>' in order to exactly recreate a particular game.  Be sure to"
  376. Xecho "use exactly the same parameters as the original  game as well as"
  377. Xecho "the same seed."
  378. Xecho
  379. Xecho
  380. X
  381. Xecho "Now,  we   will  demonstrate the  horizon  option  whereby enemy"
  382. Xecho "activity is only seen when they are within a specified number of"
  383. Xecho "game squares  from  the  nearest friendly  force,   the argument"
  384. Xecho "determines  the  range of visibility,  in  game  squares, with a"
  385. Xecho "default  of 2 if   no argument is supplied.   Send  out scouting"
  386. Xecho "parties from   the magentablack   bases to search  out the  four"
  387. Xecho "hidden  cyanwhite bases.  In   this   example we use  the  dummy"
  388. Xecho "argument 'you' to represent a non-existant cyanwhite display for"
  389. Xecho "the purpose of testing.  In actual play against an opponent, you"
  390. Xecho "will have to specify an actual x display."
  391. Xecho
  392. Xecho "> xbattle -magentablack me -cyanwhite you -rbases 4 -horizon -hex"
  393. Xecho
  394. Xecho "Quit the game before you continue."
  395. X
  396. Xecho
  397. Xecho "hit RETURN to start the game"
  398. Xread p1
  399. Xclear
  400. X
  401. Xxbattle -magentablack me -cyanwhite you -rbases 4 -horizon -hex&
  402. X
  403. Xecho
  404. Xecho "hit RETURN to continue"
  405. Xread p1
  406. Xclear
  407. X
  408. Xecho "You  can save   yourself the trouble  of typing  in a   bunch of"
  409. Xecho "command options  if you  create an  options file,  and call that"
  410. Xecho "file   when running xbattle.  A   couple   of  options files are"
  411. Xecho "supplied   with xbattle, and you   can  create  your  own.   For"
  412. Xecho "example, the file 'tribal.xbo' contains the options..."
  413. Xecho
  414. Xecho " -decay 2"
  415. Xecho " -sea 8"
  416. Xecho " -square 32"
  417. Xecho " -board 24"
  418. Xecho " -farms 7"
  419. Xecho " -militia 10"
  420. Xecho " -repeat"
  421. Xecho " -fill 4"
  422. Xecho " -dig 4"
  423. Xecho " -area"
  424. Xecho " -attack"
  425. Xecho
  426. Xecho "so you can call all these options with the command..."
  427. Xecho
  428. Xecho "> xbattle ... -options tribal.xbo ..."
  429. Xecho
  430. Xecho
  431. Xecho "The tribal options create an interesting scenario  starting with"
  432. Xecho "a mad rush to gain territory followed by  a plodding battle much"
  433. Xecho "like WW1 trench warfare.  It introduces two new options, -attack"
  434. Xecho "and -area.  The -attack  option  lets  you launch a simultaneous"
  435. Xecho "attack on  an enemy square from  all adjacent  squares by use of"
  436. Xecho "the 'a' key.  First surround the enemy,  then point at the enemy"
  437. Xecho "square and   press  'a'.    The   -area  option    changes   the"
  438. Xecho "representation of troop squares so that the number  of troops is"
  439. Xecho "proportional to the area of the  square, rather  than the length"
  440. Xecho "of the side, which is the default.   Practice occupying a corner"
  441. Xecho "of the game board and clearing out all stray  enemy troops.  Two"
  442. Xecho "more options, -dig  and -fill,   will  be discussed  in the next"
  443. Xecho "tutorial."
  444. Xecho
  445. Xecho "> xbattle -black me -white you -options tribal.xbo &"
  446. Xecho
  447. Xecho "hit RETURN to start the game"
  448. Xread p1
  449. Xclear
  450. X
  451. Xxbattle -black me -white you -options tribal.xbo &
  452. X
  453. Xecho
  454. Xecho "hit RETURN to continue"
  455. Xread p1
  456. Xclear
  457. X
  458. Xecho "In order to play  against a  real opponent, you must specify the"
  459. Xecho "display on which he will  be playing.  One  way to discover this"
  460. Xecho "is by use of the unix command 'who'.  On my machine this command"
  461. Xecho "produces a listing like this..."
  462. Xecho
  463. Xecho " slehar   ttyp0   Jan 10 10:19   (cnsxk.bu.edu:0.0)"
  464. Xecho " slehar   ttyp1   Jan 10 10:19   (cnsxk.bu.edu:0.0)"
  465. Xecho " lesher   ttyp2   Jan  7 10:05   (charles:0.0)"
  466. Xecho " slehar   ttyp5   Jan 10 16:47   (unix:0.0)"
  467. Xecho " slehar   ttyp6   Jan 10 16:47   (unix:0.0)"
  468. Xecho
  469. Xecho "which  tells   me    (slehar)  that   my   xdisplay  is   called"
  470. Xecho "cnsxk.bu.edu:0.0, or just cnsxk.  I could start  an xbattle with"
  471. Xecho "lesher using the command"
  472. Xecho
  473. Xecho "> xbattle -black me -white charles ..."
  474. Xecho 
  475. Xecho "supplying any command options I  might choose.  Alternatively, I"
  476. Xecho "could use  cnsxk instead of  'me'  for my  own display."
  477. X
  478. Xecho
  479. Xecho "hit RETURN to continue"
  480. Xread p1
  481. Xclear
  482. X
  483. Xecho "Play a few games with some real opponents before going on to the"
  484. Xecho "next tutorial.  If playing against more experienced players, set"
  485. Xecho "the  '-speed' parameter  very  low, like  1, or even  fractional"
  486. Xecho "values like 0.5, to generate  a game  of strategy and intellect,"
  487. Xecho "where the  manual skill of  rapid  clicking is  not the dominant"
  488. Xecho "factor in the game.  In the next tutorial  you will learn how to"
  489. Xecho "bias games, setting  game parameters differently for  individual"
  490. Xecho "players."
  491. Xecho
  492. Xecho "       Good luck, and happy xbattling!"
  493. Xecho
  494. Xecho
  495. Xecho
  496. Xecho "================= END OF XBATTLE TUTORIAL ==================="
  497. END_OF_FILE
  498. if test 17781 -ne `wc -c <'tutorial1'`; then
  499.     echo shar: \"'tutorial1'\" unpacked with wrong size!
  500. fi
  501. chmod +x 'tutorial1'
  502. # end of 'tutorial1'
  503. fi
  504. if test -f 'utils.c' -a "${1}" != "-c" ; then 
  505.   echo shar: Will not clobber existing file \"'utils.c'\"
  506. else
  507. echo shar: Extracting \"'utils.c'\" \(27365 characters\)
  508. sed "s/^X//" >'utils.c' <<'END_OF_FILE'
  509. X#include <stdio.h>
  510. X  
  511. X/**** x include files ****/
  512. X#include <X11/Xlib.h>
  513. X#include <X11/Xutil.h>
  514. X#include <X11/Xatom.h>
  515. X#include <X11/keysym.h>
  516. X#include <X11/keysymdef.h>
  517. X
  518. X#include "extern.h"
  519. X
  520. X/*************************************************************************/
  521. X/**    open_xwindow                            **/
  522. X/** arguments:                                **/
  523. X/**    struct xwindow_type *xwindow    xwindow structure        **/
  524. X/**    int xpos,ypos            window position- negative value    **/
  525. X/**                      means position with mouse    **/
  526. X/**    int xsize,ysize            window dimensions        **/
  527. X/**    char title[]            window and icon title        **/
  528. X/**    long eventmask            event mask e.g. ButtonPressMask    **/
  529. X/**                                            KeyPressMask    **/
  530. X/**                                            ExposureMask    **/
  531. X/**    Steve Lehar (slehar@park.bu.edu)                **/
  532. X/**    Greg Lesher (lesher@park.bu.edu)                **/
  533. X/*************************************************************************/
  534. Xopen_xwindow(xwindow,displayname,xpos,ypos,xsize,ysize,gtitle,htitle,eventmask,squaresize)
  535. X  xwindow_type *xwindow;
  536. X  char displayname[];
  537. X  int xpos,ypos,xsize,ysize;
  538. X  char gtitle[], htitle[];
  539. X  long eventmask;
  540. X  int squaresize;
  541. X{
  542. X  int i, j, k;
  543. X  GC create_gc();
  544. X
  545. X  /**** visuals variables ****/
  546. X  Visual *visual;        /* struct defining window properties     */
  547. X  unsigned long valuemask;    /* mask for attributes             */
  548. X  XSetWindowAttributes attrib;    /* window attributes             */
  549. X  XVisualInfo vinfo;
  550. X  XPoint hex_small_points[7];
  551. X  double fraction, temp;
  552. X
  553. X  GC gc_and,
  554. X     gc_all,
  555. X     gc_none,
  556. X     terrainhue[NHILLTONES];
  557. X  static Pixmap stipple[NGREYTONES+NHILLTONES];
  558. X  double ratio, value, increment;
  559. X  int limit;
  560. X
  561. X  /**** open display and screen ****/
  562. X  xwindow->display = XOpenDisplay(displayname);
  563. X  if(xwindow->display == NULL)
  564. X  {
  565. X    printf("ERROR open_xwindow: can't open display %s\n",displayname);
  566. X    exit(1);
  567. X  }
  568. X  xwindow->screen  = DefaultScreen(xwindow->display);
  569. X
  570. X  /**** set window position and size hints for window manager ****/
  571. X  xwindow->hint.x = xpos;
  572. X  xwindow->hint.y = ypos;
  573. X  xwindow->hint.width = xsize;
  574. X  xwindow->hint.height = ysize;
  575. X  if (xpos < 0 || ypos < 0)
  576. X    xwindow->hint.flags = ( PPosition | PSize);
  577. X  else
  578. X    xwindow->hint.flags = (USPosition | PSize);
  579. X
  580. X  /**** get a visual with required properties ****/
  581. X  xwindow->depth = DefaultDepth(xwindow->display, xwindow->screen);
  582. X
  583. X  visual = DefaultVisual(xwindow->display,xwindow->screen);
  584. X
  585. X  if(xwindow->depth != 8)
  586. X  {
  587. X    if (XMatchVisualInfo(xwindow->display, xwindow->screen, 8, PseudoColor, &vinfo))
  588. X    {
  589. X      visual = vinfo.visual;
  590. X      xwindow->depth = 8;
  591. X    }
  592. X  }
  593. X
  594. X  if (xwindow->depth != 8)
  595. X    xwindow->depth = 1;
  596. X
  597. X  if(xwindow->depth == 8)
  598. X  {
  599. X    /**** create color map using visual ****/
  600. X#if NEWCOLORMAP
  601. X    xwindow->cmap = XCreateColormap(xwindow->display,
  602. X                RootWindow(xwindow->display, xwindow->screen),
  603. X                visual, AllocAll);
  604. X#else
  605. X    xwindow->cmap = DefaultColormap (xwindow->display, xwindow->screen);
  606. X#endif
  607. X    
  608. X    /**** set attributes ****/
  609. X    valuemask = CWBackPixel | CWBorderPixel | CWBitGravity | CWColormap;
  610. X    attrib.background_pixel = BlackPixel(xwindow->display,xwindow->screen);
  611. X    attrib.border_pixel = BlackPixel(xwindow->display,xwindow->screen);
  612. X    attrib.bit_gravity = CenterGravity;
  613. X    attrib.colormap = xwindow->cmap;
  614. X
  615. X    /**** create the x window ****/
  616. X    xwindow->window = XCreateWindow(xwindow->display, 
  617. X              RootWindow(xwindow->display, xwindow->screen),
  618. X              xwindow->hint.x, xwindow->hint.y,
  619. X              xwindow->hint.width, xwindow->hint.height,
  620. X              BORDER, xwindow->depth, InputOutput, visual,
  621. X              valuemask, &attrib);
  622. X  }
  623. X  else
  624. X  {
  625. X    xwindow->window = XCreateSimpleWindow(xwindow->display,
  626. X                                 DefaultRootWindow(xwindow->display),
  627. X                                 xwindow->hint.x, xwindow->hint.y,
  628. X                                 xwindow->hint.width, xwindow->hint.height, BORDER,
  629. X                                 BlackPixel(xwindow->display,xwindow->screen),
  630. X                                 WhitePixel(xwindow->display,xwindow->screen));
  631. X  }
  632. X
  633. X  /**** get standard properties for window manager ****/
  634. X  if (xwindow->depth == 8)
  635. X    XSetStandardProperties(xwindow->display, xwindow->window, htitle, htitle,
  636. X              None, NULL, None, &xwindow->hint);
  637. X  else if (xwindow->depth == 1)
  638. X  {
  639. X    XSetStandardProperties(xwindow->display, xwindow->window, gtitle, gtitle, 
  640. X              None, NULL, None, &xwindow->hint);
  641. X  }
  642. X
  643. X  /**** set window manager hints ****/
  644. X  xwindow->xwmh.flags = (InputHint|StateHint);  
  645. X  xwindow->xwmh.input = TRUE;
  646. X  xwindow->xwmh.initial_state = NormalState;
  647. X  XSetWMHints(xwindow->display, xwindow->window, &(xwindow->xwmh));
  648. X
  649. X  /**** make window sensitive selected events ****/
  650. X  XSelectInput(xwindow->display, xwindow->window, eventmask);
  651. X
  652. X  /**** load color map ****/
  653. X  if(xwindow->depth == 8)
  654. X  {
  655. X    for (i=0 ; i<MAXCOLORS ; i++)
  656. X    {
  657. X      xwindow->xcolor[i].flags = 0;
  658. X      xwindow->xcolor[i].pixel = i;
  659. X      xwindow->xcolor[i].red = 0;
  660. X      xwindow->xcolor[i].green = 0;
  661. X      xwindow->xcolor[i].blue = 0;
  662. X    }
  663. X
  664. X    /**** set player colors ****/
  665. X    for (i=0; i<nsides; i++)
  666. X    {
  667. X      xwindow->xcolor[i].flags = DoRed | DoGreen | DoBlue;
  668. X      xwindow->xcolor[i].pixel = i;
  669. X      xwindow->xcolor[i].red =   palette[sidemap[i]][0]<<8;
  670. X      xwindow->xcolor[i].green = palette[sidemap[i]][1]<<8;
  671. X      xwindow->xcolor[i].blue =  palette[sidemap[i]][2]<<8;
  672. X    }
  673. X
  674. X    /**** background color ****/
  675. X    xwindow->xcolor[none].flags = DoRed | DoGreen | DoBlue;
  676. X    xwindow->xcolor[none].pixel = none;
  677. X    xwindow->xcolor[none].red =   palette[0][0]<<8;
  678. X    xwindow->xcolor[none].green = palette[0][1]<<8;
  679. X    xwindow->xcolor[none].blue =  palette[0][2]<<8;
  680. X
  681. X    /**** dark ****/
  682. X    xwindow->xcolor[dark].flags = DoRed | DoGreen | DoBlue;
  683. X    xwindow->xcolor[dark].pixel = dark;
  684. X    xwindow->xcolor[dark].red =   0<<8;
  685. X    xwindow->xcolor[dark].green = 0<<8;
  686. X    xwindow->xcolor[dark].blue =  0<<8;
  687. X
  688. X    /**** light ****/
  689. X    xwindow->xcolor[light].flags = DoRed | DoGreen | DoBlue;
  690. X    xwindow->xcolor[light].pixel = light;
  691. X    xwindow->xcolor[light].red =   255<<8;
  692. X    xwindow->xcolor[light].green = 255<<8;
  693. X    xwindow->xcolor[light].blue =  255<<8;
  694. X
  695. X    if (enable_terrain)
  696. X    {
  697. X      /**** set hill tones ****/
  698. X      if (enable_hills)
  699. X      {
  700. X        increment = 5.0/((double)(NHILLTONES-1));
  701. X        for (i=0; i<NHILLTONES; i++)
  702. X        {
  703. X          value = increment * i;
  704. X          xwindow->xcolor[light+1+i].flags = DoRed | DoGreen | DoBlue;
  705. X          xwindow->xcolor[light+1+i].pixel = light+1+i;
  706. X
  707. X          xwindow->xcolor[light+1+i].red =   ((int)(hillintersect[0] + hillslope[0]*value))<<8;
  708. X          xwindow->xcolor[light+1+i].green = ((int)(hillintersect[1] + hillslope[1]*value))<<8;
  709. X          xwindow->xcolor[light+1+i].blue =  ((int)(hillintersect[2] + hillslope[2]*value))<<8;
  710. X
  711. X/*** Simpler ratio method of hill determination ***/
  712. X/***
  713. X          ratio = ((1.25-0.75)/((double)(NHILLTONES-1)))*i + 0.75;
  714. X
  715. X          xwindow->xcolor[light+1+i].red =   ((int)(ratio*hillpalette[0]))<<8;
  716. X          xwindow->xcolor[light+1+i].green = ((int)(ratio*hillpalette[1]))<<8;
  717. X          xwindow->xcolor[light+1+i].blue =  ((int)(ratio*hillpalette[2]))<<8;
  718. X***/
  719. X        }
  720. X        if (enable_sea)
  721. X        {
  722. X          xwindow->xcolor[light+1].flags = DoRed | DoGreen | DoBlue;
  723. X          xwindow->xcolor[light+1].pixel = light+1;
  724. X          xwindow->xcolor[light+1].red =   (seapalette[0])<<8;
  725. X          xwindow->xcolor[light+1].green = (seapalette[1])<<8;
  726. X          xwindow->xcolor[light+1].blue =  (seapalette[2])<<8;
  727. X        }
  728. X      }
  729. X      /**** set forest tones ****/
  730. X      if (enable_forest)
  731. X      {
  732. X        for (i=0; i<NFORESTTONES; i++)
  733. X        {
  734. X          xwindow->xcolor[light+1+i].flags = DoRed | DoGreen | DoBlue;
  735. X          xwindow->xcolor[light+1+i].pixel = light+1+i;
  736. X
  737. X          ratio = ((1.25-0.75)/((double)(NFORESTTONES-1)))*(NFORESTTONES-1-i) + 0.75;
  738. X
  739. X          xwindow->xcolor[light+1+i].red =   ((int)(ratio*forestpalette[0]))<<8;
  740. X          xwindow->xcolor[light+1+i].green = ((int)(ratio*forestpalette[1]))<<8;
  741. X          xwindow->xcolor[light+1+i].blue =  ((int)(ratio*forestpalette[2]))<<8;
  742. X        }
  743. X        if (enable_sea)
  744. X        {
  745. X          xwindow->xcolor[light+1].flags = DoRed | DoGreen | DoBlue;
  746. X          xwindow->xcolor[light+1].pixel = light+1;
  747. X          xwindow->xcolor[light+1].red =   (seapalette[0])<<8;
  748. X          xwindow->xcolor[light+1].green = (seapalette[1])<<8;
  749. X          xwindow->xcolor[light+1].blue =  (seapalette[2])<<8;
  750. X        }
  751. X      }
  752. X      /**** set sea tone(s) ****/
  753. X      if (enable_sea && !enable_hills && !enable_forest)
  754. X      {
  755. X        xwindow->xcolor[light+1].flags = DoRed | DoGreen | DoBlue;
  756. X        xwindow->xcolor[light+1].pixel = light+1;
  757. X        xwindow->xcolor[light+1].red =   (seapalette[0])<<8;
  758. X        xwindow->xcolor[light+1].green = (seapalette[1])<<8;
  759. X        xwindow->xcolor[light+1].blue =  (seapalette[2])<<8;
  760. X
  761. X        xwindow->xcolor[light+2].flags = DoRed | DoGreen | DoBlue;
  762. X        xwindow->xcolor[light+2].pixel = light+2;
  763. X        xwindow->xcolor[light+2].red =   (palette[0][0])<<8;
  764. X        xwindow->xcolor[light+2].green = (palette[0][1])<<8;
  765. X        xwindow->xcolor[light+2].blue =  (palette[0][2])<<8;
  766. X
  767. X      }
  768. X    }
  769. X
  770. X#if NEWCOLORMAP
  771. X    XStoreColors(xwindow->display, xwindow->cmap, xwindow->xcolor, MAXCOLORS);
  772. X#else
  773. X    for (i=0; i<MAXCOLORS; i++)
  774. X      if (!XAllocColor(xwindow->display, xwindow->cmap, &xwindow->xcolor[i] ))
  775. X        printf ( "Warning: Couldn't allocate color cells\n");
  776. X#endif
  777. X
  778. X    for (i=0; i<nsides; i++)
  779. X      xwindow->drawletter[i] = FALSE;
  780. X  }
  781. X
  782. X  /**** window mapping ****/
  783. X  XMapRaised(xwindow->display, xwindow->window);
  784. X
  785. X  /**** create graphics contexts (drawing colors) ****/
  786. X  for (j=0; j<=nsides+2; j++)
  787. X    xwindow->hue[j] = XCreateGC(xwindow->display, xwindow->window, 0, 0);
  788. X  xwindow->flip  = XCreateGC(xwindow->display, xwindow->window, 0, 0);
  789. X
  790. X  xwindow->gc_clear  = XCreateGC(xwindow->display, xwindow->window, 0, 0);
  791. X  XSetFunction(xwindow->display, xwindow->gc_clear, GXandInverted);
  792. X
  793. X  xwindow->gc_or = XCreateGC(xwindow->display, xwindow->window, 0, 0);
  794. X  XSetFunction(xwindow->display, xwindow->gc_or, GXor);
  795. X
  796. X  if (enable_terrain)
  797. X  {
  798. X    if (enable_hills)
  799. X      limit = NHILLTONES;
  800. X    else if (enable_forest)
  801. X      limit = NFORESTTONES;
  802. X    if (enable_sea && !enable_hills && !enable_forest)
  803. X      limit = NSEATONES;
  804. X
  805. X    for (j=0; j<limit; j++)
  806. X    {
  807. X       terrainhue[j] = XCreateGC(xwindow->display, xwindow->window, 0, 0);
  808. X       XSetFunction(xwindow->display, terrainhue[j], GXcopy);
  809. X    }
  810. X  }
  811. X
  812. X  /**** set drawing functions ****/
  813. X  for (j=0; j<=nsides+2; j++)
  814. X    XSetFunction(xwindow->display, xwindow->hue[j], GXcopy);
  815. X  XSetFunction(xwindow->display, xwindow->flip,  GXinvert);
  816. X
  817. X  /**** set drawing colors ****/
  818. X  if (xwindow->depth == 1)
  819. X  { 
  820. X    for (j=0; j<nsides; j++) {
  821. X
  822. X      if (color2bw[sidemap[j]] == WHITE)
  823. X      {
  824. X        XSetForeground(xwindow->display, xwindow->hue[j],
  825. X                     WhitePixel(xwindow->display,xwindow->screen));
  826. X        XSetBackground(xwindow->display, xwindow->hue[j],
  827. X                     BlackPixel(xwindow->display,xwindow->screen));
  828. X      }
  829. X      else
  830. X      {
  831. X        XSetForeground(xwindow->display, xwindow->hue[j],
  832. X                     BlackPixel(xwindow->display,xwindow->screen));
  833. X        XSetBackground(xwindow->display, xwindow->hue[j],
  834. X                     WhitePixel(xwindow->display,xwindow->screen));
  835. X      }
  836. X    }
  837. X    XSetForeground(xwindow->display, xwindow->hue[none],
  838. X                     BlackPixel(xwindow->display,xwindow->screen));
  839. X    XSetBackground(xwindow->display, xwindow->hue[none],
  840. X                     WhitePixel(xwindow->display,xwindow->screen));
  841. X
  842. X    XSetForeground(xwindow->display, xwindow->hue[dark],
  843. X                     BlackPixel(xwindow->display,xwindow->screen));
  844. X    XSetBackground(xwindow->display, xwindow->hue[dark],
  845. X                     WhitePixel(xwindow->display,xwindow->screen));
  846. X
  847. X    XSetForeground(xwindow->display, xwindow->hue[light],
  848. X                     WhitePixel(xwindow->display,xwindow->screen));
  849. X    XSetBackground(xwindow->display, xwindow->hue[light],
  850. X                     BlackPixel(xwindow->display,xwindow->screen));
  851. X
  852. X/**
  853. X    XSetForeground(xwindow->display, xwindow->flip,
  854. X                 BlackPixel(xwindow->display,xwindow->screen));
  855. X    XSetBackground(xwindow->display, xwindow->flip,
  856. X                 WhitePixel(xwindow->display,xwindow->screen));
  857. X**/
  858. X  }
  859. X
  860. X  /**** set colors (link GC to color) ****/
  861. X  if (xwindow->depth == 8)
  862. X  {
  863. X#if NEWCOLORMAP
  864. X    for (j=0; j<nsides; j++)
  865. X    {
  866. X      XSetForeground (xwindow->display, xwindow->hue[j], j);
  867. X      XSetBackground (xwindow->display, xwindow->hue[j], nsides);
  868. X    }
  869. X    XSetForeground (xwindow->display, xwindow->hue[none], none);
  870. X    XSetForeground (xwindow->display, xwindow->hue[dark], dark);
  871. X    XSetForeground (xwindow->display, xwindow->hue[light], light);
  872. X#else
  873. X    for (j=0; j<nsides; j++)
  874. X    {
  875. X      XSetForeground (xwindow->display, xwindow->hue[j], xwindow->xcolor[j].pixel);
  876. X      XSetBackground (xwindow->display, xwindow->hue[j], xwindow->xcolor[nsides].pixel);
  877. X    }
  878. X    XSetForeground (xwindow->display, xwindow->hue[none], xwindow->xcolor[none].pixel);
  879. X    XSetForeground (xwindow->display, xwindow->hue[dark], xwindow->xcolor[dark].pixel);
  880. X    XSetForeground (xwindow->display, xwindow->hue[light], xwindow->xcolor[light].pixel);
  881. X#endif
  882. X
  883. X    if (enable_terrain)
  884. X    {
  885. X      for (j=0; j<limit; j++)
  886. X      {
  887. X#if NEWCOLORMAP
  888. X        XSetForeground (xwindow->display, terrainhue[j], light+1+j);
  889. X        XSetBackground (xwindow->display, terrainhue[j], none);
  890. X#else
  891. X        XSetForeground (xwindow->display, terrainhue[j], xwindow->xcolor[light+1+j].pixel);
  892. X        XSetBackground (xwindow->display, terrainhue[j], xwindow->xcolor[none].pixel);
  893. X#endif
  894. X      }
  895. X    }
  896. X  }
  897. X
  898. X  if (xwindow->depth == 1)
  899. X  {
  900. X    /**** set grey stipple color ****/
  901. X
  902. X    init_stipple (xwindow->display, xwindow->window, stipple);
  903. X
  904. X    for (j=0; j<nsides; j++)
  905. X    {
  906. X      if (color2bw[sidemap[j]] != WHITE && color2bw[sidemap[j]] != BLACK)
  907. X      {
  908. X        XSetStipple(  xwindow->display, xwindow->hue[j], stipple[color2bw[sidemap[j]]-BLACK-1]);
  909. X        XSetFillStyle(xwindow->display, xwindow->hue[j], FillOpaqueStippled);
  910. X      }
  911. X    }
  912. X
  913. X    XSetStipple(  xwindow->display, xwindow->hue[nsides], stipple[NGREYTONES/2]);
  914. X    XSetFillStyle(xwindow->display, xwindow->hue[nsides], FillOpaqueStippled);
  915. X  }
  916. X
  917. X  
  918. X  /**** create and initialize pixmaps for terrain ****/
  919. X  if (enable_terrain)
  920. X  {
  921. X    for (i=0; i<limit; i++)
  922. X    {
  923. X      if (enable_hex)
  924. X      {
  925. X        if (i == 0 && enable_sea)
  926. X          xwindow->terrain[i] = XCreatePixmap (xwindow->display, xwindow->window,
  927. X                                              2*fillnumber*hex_side, 6*hex_vert, xwindow->depth);
  928. X        else
  929. X          xwindow->terrain[i] = XCreatePixmap (xwindow->display, xwindow->window,
  930. X                                              2*hex_side, 6*hex_vert, xwindow->depth);
  931. X      }
  932. X      else
  933. X        xwindow->terrain[i] = XCreatePixmap (xwindow->display, xwindow->window,
  934. X                                              squaresize, squaresize, xwindow->depth);
  935. X    }
  936. X
  937. X    if (xwindow->depth == 8)
  938. X    {
  939. X      for (i=0; i<limit; i++)
  940. X      {
  941. X          if (enable_hex)
  942. X            XFillRectangle(xwindow->display,xwindow->terrain[i],
  943. X                          terrainhue[i], 0, 0, 2*hex_side, 2*hex_vert);
  944. X          else
  945. X            XFillRectangle(xwindow->display,xwindow->terrain[i],
  946. X                          terrainhue[i], 0, 0, squaresize, squaresize);
  947. X      }
  948. X    }
  949. X    else if (xwindow->depth == 1)
  950. X    {
  951. X      if (enable_hex)
  952. X        init_terrain_pixmaps (xwindow, limit, 2*hex_side);
  953. X      else
  954. X        init_terrain_pixmaps (xwindow, limit, squaresize);
  955. X   
  956. X      if (enable_sea && !enable_hills && !enable_forest)
  957. X      {
  958. X        if (enable_sea)
  959. X        {
  960. X          if (enable_hex)
  961. X            XFillRectangle(xwindow->display,xwindow->terrain[1],
  962. X                   xwindow->hue[none], 0, 0, 2*hex_side, 2*hex_vert);
  963. X          else
  964. X            XFillRectangle(xwindow->display,xwindow->terrain[1],
  965. X                   xwindow->hue[none], 0, 0, squaresize, squaresize);
  966. X        }
  967. X      }
  968. X    }
  969. X
  970. X    gc_and  = XCreateGC(xwindow->display, xwindow->window, 0, 0);
  971. X    XSetFunction(xwindow->display, gc_and, GXand);
  972. X
  973. X    gc_all  = XCreateGC(xwindow->display, xwindow->window, 0, 0);
  974. X    XSetFunction(xwindow->display, gc_all, GXset);
  975. X
  976. X    gc_none  = XCreateGC(xwindow->display, xwindow->window, 0, 0);
  977. X    XSetFunction(xwindow->display, gc_none, GXclear);
  978. X
  979. X    if (enable_hex)
  980. X    {
  981. X      for (i=0; i<limit; i++)
  982. X      {
  983. X        if (i==0 && enable_sea)
  984. X        {
  985. X          for (j=0; j<fillnumber; j++)
  986. X          {
  987. X            XCopyArea (xwindow->display, xwindow->terrain[0], xwindow->terrain[0],
  988. X                              xwindow->hue[light], 0, 0, 2*hex_side, 2*hex_vert, 2*j*hex_side, 0);
  989. X
  990. X            fraction = ((double)(fillnumber-j))/(fillnumber);
  991. X
  992. X            hex_small_points[0].x = 2*j*hex_side + hex_halfside +
  993. X                                               (int)((1.0-fraction)*hex_halfside + 0.5);
  994. X            hex_small_points[0].y = 2*hex_vert + (int)((1.0-fraction)*hex_vert + 0.5);
  995. X
  996. X            for (k=1; k<7; k++)
  997. X            {
  998. X              temp = fraction*hex_points[k].x;
  999. X              if (temp < 0)
  1000. X                hex_small_points[k].x = (int)(fraction * hex_points[k].x - 0.5);
  1001. X              else
  1002. X                hex_small_points[k].x = (int)(fraction * hex_points[k].x + 0.5);
  1003. X
  1004. X              temp = fraction*hex_points[k].y;
  1005. X              if (temp < 0)
  1006. X                hex_small_points[k].y = (int)(fraction * hex_points[k].y - 0.5);
  1007. X              else
  1008. X                hex_small_points[k].y = (int)(fraction * hex_points[k].y + 0.5);
  1009. X            }
  1010. X
  1011. X            XFillRectangle(xwindow->display,xwindow->terrain[0], gc_none,
  1012. X                                            2*j*hex_side, 2*hex_vert, 2*hex_side, 2*hex_vert);
  1013. X
  1014. X            XFillPolygon (xwindow->display, xwindow->terrain[0], gc_all,
  1015. X                                            hex_small_points, 6, Convex, CoordModePrevious);
  1016. X  
  1017. X            XCopyArea (xwindow->display, xwindow->terrain[0], xwindow->terrain[0],
  1018. X                       gc_and, 2*j*hex_side, 2*hex_vert, 2*hex_side, 2*hex_vert, 2*j*hex_side, 0);
  1019. X          }
  1020. X        }
  1021. X        else
  1022. X        {
  1023. X          hex_points[0].x = hex_halfside;
  1024. X          hex_points[0].y = 2*hex_vert;
  1025. X
  1026. X          XFillRectangle (xwindow->display,xwindow->terrain[i], gc_none,
  1027. X                                        0, 2*hex_vert, 2*hex_side, 2*hex_vert);
  1028. X
  1029. X          XFillPolygon (xwindow->display, xwindow->terrain[i], gc_all,
  1030. X                                            hex_points, 6, Convex, CoordModePrevious);
  1031. X          XCopyArea (xwindow->display, xwindow->terrain[i], xwindow->terrain[i],
  1032. X                   gc_and, 0, 2*hex_vert, 2*hex_side, 2*hex_vert, 0, 0);
  1033. X
  1034. X        }
  1035. X      }
  1036. X    }
  1037. X  }
  1038. X
  1039. X  /**** load font ****/
  1040. X  xwindow->font_struct = XLoadQueryFont(xwindow->display, FONT);
  1041. X  if(xwindow->font_struct == 0)
  1042. X  {
  1043. X    printf("font %s not found, using default\n",FONT);
  1044. X    xwindow->font_struct = XQueryFont(xwindow->display,XGContextFromGC(
  1045. X                    DefaultGC(xwindow->display,xwindow->screen)));
  1046. X  }
  1047. X  else
  1048. X  {
  1049. X    for (i=0; i<nsides; i++)
  1050. X      XSetFont(xwindow->display, xwindow->hue[i], xwindow->font_struct->fid);
  1051. X    XSetFont(xwindow->display, xwindow->flip,  xwindow->font_struct->fid);
  1052. X  }
  1053. X
  1054. X  if (xwindow->depth == 1)
  1055. X  {
  1056. X    for (i=0; i<nsides; i++)
  1057. X    {
  1058. X      if (lettermap[i][0])
  1059. X      {
  1060. X        xwindow->drawletter[i] = TRUE;
  1061. X        XGetFontProperty(xwindow->font_struct, XA_QUAD_WIDTH, &xwindow->charwidth);
  1062. X        XGetFontProperty(xwindow->font_struct, XA_CAP_HEIGHT, &xwindow->charheight);
  1063. X        strcpy (xwindow->letter[i], lettermap[i]);
  1064. X      }
  1065. X      else if (enable_reserve[i])
  1066. X      {
  1067. X        XGetFontProperty(xwindow->font_struct, XA_QUAD_WIDTH, &xwindow->charwidth);
  1068. X        XGetFontProperty(xwindow->font_struct, XA_CAP_HEIGHT, &xwindow->charheight);
  1069. X      }
  1070. X      else
  1071. X        xwindow->drawletter[i] = FALSE;
  1072. X    }
  1073. X  }
  1074. X  xwindow->drawletter[none] = FALSE;
  1075. X
  1076. X  /**** map window to make it visible ****/
  1077. X  if (xwindow->depth == 8)
  1078. X    XMapWindow(xwindow->display, xwindow->window);
  1079. X}
  1080. X
  1081. X
  1082. X/*************************************************************************/
  1083. X/**    close_xwindow                            **/
  1084. X/**  Close the x window                            **/
  1085. X/**    Steve Lehar (slehar@park.bu.edu)                **/
  1086. X/*************************************************************************/
  1087. Xclose_xwindow(xwindow)
  1088. X  xwindow_type *xwindow;
  1089. X{
  1090. X  XDestroyWindow(xwindow->display,xwindow->window);
  1091. X  XCloseDisplay(xwindow->display);
  1092. X}
  1093. X
  1094. X
  1095. X/*************************************************************************/
  1096. X/**     init_stipple                                                    **/
  1097. X/**  create stipple patterns for greytoning                **/
  1098. X/**     Greg Lesher (lesher@park.bu.edu)                                **/
  1099. X/*************************************************************************/
  1100. Xinit_stipple (display, window, stipple)
  1101. X
  1102. X  Display *display;
  1103. X  Window window;
  1104. X  Pixmap stipple[];
  1105. X
  1106. X{
  1107. X  int i;
  1108. X
  1109. X  static char grey[NGREYTONES+NHILLTONES][8] = {
  1110. X    {0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF, 0xAA, 0xFF},
  1111. X    {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55},
  1112. X    {0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00}};
  1113. X
  1114. X  for (i=0; i<NGREYTONES; i++)
  1115. X    stipple[i] = XCreateBitmapFromData(display,window,grey[i],8,8);
  1116. X}
  1117. X
  1118. X
  1119. X/*************************************************************************/
  1120. X/**     init_terrain                                                    **/
  1121. X/**  yse error diffusion to emulate grayscale terrain            **/
  1122. X/**     Greg Lesher (lesher@park.bu.edu)                                **/
  1123. X/*************************************************************************/
  1124. Xinit_terrain_pixmaps (xwindow, limit, squaresize)
  1125. X  xwindow_type *xwindow;
  1126. X  int limit,
  1127. X      squaresize;
  1128. X{
  1129. X  int i, x, y,
  1130. X      enable_quasi;
  1131. X
  1132. X  double value,
  1133. X         quasi,
  1134. X         target[2*MAXSQUARESIZE+20][2*MAXSQUARESIZE+20],
  1135. X         error,
  1136. X         drand48();
  1137. X
  1138. X  if (NHILLTONES > 5)
  1139. X    enable_quasi = TRUE;
  1140. X  else
  1141. X    enable_quasi = FALSE;
  1142. X
  1143. X  /**** for each level of greytone ****/
  1144. X  for (i=0; i<limit; i++)
  1145. X  {
  1146. X    /**** compute desired graylevel in [0,1] ****/
  1147. X   
  1148. X    if (enable_forest)
  1149. X      value = 0.75 - ((0.75-0.25)/((double)(limit-1)))*(limit-1-i);
  1150. X    else
  1151. X      value = 0.75 - ((0.75-0.25)/((double)(limit-1)))*i;
  1152. X
  1153. X    if (enable_sea && i == 0)
  1154. X    {
  1155. X      value = SEAVALUE;
  1156. X      enable_quasi = TRUE;
  1157. X    }
  1158. X    else if (NHILLTONES <= 5)
  1159. X      enable_quasi = FALSE;
  1160. X
  1161. X    for (x=0; x<squaresize+20; x++)
  1162. X      for (y=0; y<squaresize+20; y++)
  1163. X        target[x][y] = value;
  1164. X
  1165. X    /**** for each square threshold and diffuse error ****/
  1166. X    for (x=0; x<squaresize+20; x++)
  1167. X    {
  1168. X      for (y=0; y<squaresize+20; y++)
  1169. X      {
  1170. X        /**** threshold and set error ****/
  1171. X        if (target[x][y] > 0.5)
  1172. X        {
  1173. X          if (x>=10 && x<squaresize+10 && y>=10 && y<squaresize+10)
  1174. X            XDrawPoint (xwindow->display, xwindow->terrain[i], xwindow->hue[dark], x-10, y-10);
  1175. X          error = target[x][y] - 1.0;
  1176. X        }
  1177. X        else
  1178. X        {
  1179. X          if (x>=10 && x<squaresize+10 && y>=10 && y<squaresize+10)
  1180. X            XDrawPoint (xwindow->display, xwindow->terrain[i], xwindow->hue[light], x-10, y-10);
  1181. X          error = target[x][y];
  1182. X        }
  1183. X
  1184. X        /**** enable randomness if over 5 levels (removes artifacts and worms) ****/
  1185. X        if (enable_quasi)
  1186. X          quasi = drand48()/20.0;
  1187. X        else
  1188. X          quasi = 0;
  1189. X
  1190. X        /**** distribute error ****/
  1191. X        if (y == 0)
  1192. X        {
  1193. X          if (x == squaresize+20-1)
  1194. X          {
  1195. X            target[x][y+1] += 1.0*error;
  1196. X          }
  1197. X          else
  1198. X          {
  1199. X            target[x][y+1] += (0.4+quasi)*error;
  1200. X            target[x+1][y] += (0.4-quasi)*error;
  1201. X            target[x+1][y+1] += 0.2*error;
  1202. X          }
  1203. X        }
  1204. X        else if (y == squaresize+20-1)
  1205. X        {
  1206. X          if (x != squaresize+20-1)
  1207. X          {
  1208. X            target[x+1][y] += (0.7+quasi)*error;
  1209. X            target[x+1][y-1] += (0.3-quasi)*error;
  1210. X          }
  1211. X        }
  1212. X        else if (x == squaresize+20-1)
  1213. X        {
  1214. X          target[x][y+1] += 1.0*error;
  1215. X        }
  1216. X        else
  1217. X        {
  1218. X          target[x][y+1] += (0.3+quasi)*error;
  1219. X          target[x+1][y] += (0.3-quasi)*error;
  1220. X          target[x+1][y+1] += 0.2*error;
  1221. X          target[x+1][y-1] += 0.2*error;
  1222. X        }
  1223. X      }
  1224. X    }
  1225. X
  1226. X    if (enable_sea && !enable_hills && !enable_forest)
  1227. X      return;
  1228. X  }
  1229. X}
  1230. X
  1231. X
  1232. X/*****************************************************************/
  1233. X/**    intval                            **/
  1234. X/** returns the int value of the argument indexed by index+1    **/
  1235. X/**    Steve Lehar (slehar@park.bu.edu)            **/
  1236. X/*****************************************************************/
  1237. Xintval(str,argc,argv)
  1238. X  char str[];
  1239. X  int argc;
  1240. X  char *argv[];
  1241. X{
  1242. X  int i,
  1243. X      index=0;
  1244. X
  1245. X  for (i=1; i<argc; i++)
  1246. X  {
  1247. X    if (strcmp(argv[i],str)==0)
  1248. X      index=i;
  1249. X  }
  1250. X  if (index>0)
  1251. X    sscanf(argv[index+1],"%d",&i);
  1252. X  else
  1253. X    i=0;
  1254. X  return(i);
  1255. X}
  1256. X
  1257. X
  1258. X/*****************************************************************/
  1259. X/**    doubleval                        **/
  1260. X/** returns the double value of the argument indexed by index+1    **/
  1261. X/**    Steve Lehar (slehar@park.bu.edu)            **/
  1262. X/*****************************************************************/
  1263. Xdouble doubleval(str,argc,argv)
  1264. X  char str[];
  1265. X  int argc;
  1266. X  char *argv[];
  1267. X{
  1268. X  float f;
  1269. X  int i,
  1270. X      index=0;
  1271. X
  1272. X  for (i=1; i<argc; i++)
  1273. X  {
  1274. X    if (strcmp(argv[i],str)==0)
  1275. X      index=i;
  1276. X  }
  1277. X  if (index>0)
  1278. X    sscanf(argv[index+1],"%f",&f);
  1279. X  else
  1280. X    f = 0.0;
  1281. X  return((double)(f));
  1282. X}
  1283. X
  1284. X
  1285. X/*****************************************************************/
  1286. X/**    stringval                        **/
  1287. X/** sets string to the string argument indexed by index+1    **/
  1288. X/**    Greg Lesher (lesher@park.bu.edu)            **/
  1289. X/*****************************************************************/
  1290. Xint stringval(str,argc,argv,string)
  1291. X  char str[];
  1292. X  int argc;
  1293. X  char *argv[];
  1294. X  char string[];
  1295. X{
  1296. X  int i,
  1297. X      index=0;
  1298. X
  1299. X  for (i=1; i<argc; i++)
  1300. X  {
  1301. X    if (strcmp(argv[i],str)==0)
  1302. X      index=i;
  1303. X  }
  1304. X  if (index == (argc-1))
  1305. X    return (FALSE);
  1306. X  if (argv[index+1][0] == '-' || argv[index+1][0] == '}')
  1307. X    return (FALSE);
  1308. X  strcpy (string, argv[index+1]);
  1309. X  return(TRUE);
  1310. X}
  1311. X
  1312. X
  1313. X/*****************************************************************/
  1314. X/**    is_arg                            **/
  1315. X/** determines wether a command line argument exists in the    **/
  1316. X/** form of str.                        **/
  1317. X/**    Steve Lehar (slehar@park.bu.edu)            **/
  1318. X/*****************************************************************/
  1319. Xis_arg(str,argc,argv)
  1320. X  char str[];
  1321. X  int argc;
  1322. X  char *argv[];
  1323. X{
  1324. X  int i,
  1325. X      found=0;
  1326. X
  1327. X  for (i=1; i<argc; i++)
  1328. X  {
  1329. X    if (strcmp(argv[i],str)==0)
  1330. X      found=i;
  1331. X  }
  1332. X  return(found);
  1333. X}
  1334. X
  1335. X
  1336. X/*************************************************************************/
  1337. X/**     matchsstr                                                       **/
  1338. X/**  attempts to match first part of two input strings            **/
  1339. X/**     Greg Lesher (lesher@park.bu.edu)                                **/
  1340. X/*************************************************************************/
  1341. Xmatchstr (line, word)
  1342. X  char line[], word[];
  1343. X{
  1344. X  int i;
  1345. X
  1346. X  for (i=0; i<strlen(word); i++)
  1347. X    if (line[i] != word[i])
  1348. X      return (FALSE);
  1349. X  return (TRUE);
  1350. X}
  1351. X
  1352. X
  1353. X#if NODRAND48
  1354. Xdouble
  1355. Xdrand48()
  1356. X{
  1357. X  double temp;
  1358. X
  1359. X  temp = (double)(rand() & 0xFFFF)/((double)(0xFFFF));
  1360. X
  1361. X  return (temp);
  1362. X}
  1363. X#endif
  1364. END_OF_FILE
  1365. if test 27365 -ne `wc -c <'utils.c'`; then
  1366.     echo shar: \"'utils.c'\" unpacked with wrong size!
  1367. fi
  1368. # end of 'utils.c'
  1369. fi
  1370. echo shar: End of archive 7 \(of 7\).
  1371. cp /dev/null ark7isdone
  1372. MISSING=""
  1373. for I in 1 2 3 4 5 6 7 ; do
  1374.     if test ! -f ark${I}isdone ; then
  1375.     MISSING="${MISSING} ${I}"
  1376.     fi
  1377. done
  1378. if test "${MISSING}" = "" ; then
  1379.     echo You have unpacked all 7 archives.
  1380.     rm -f ark[1-9]isdone
  1381. else
  1382.     echo You still need to unpack the following archives:
  1383.     echo "        " ${MISSING}
  1384. fi
  1385. ##  End of shell archive.
  1386. exit 0
  1387.