home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / x / volume18 / xmris / part04 < prev    next >
Encoding:
Text File  |  1992-07-15  |  50.1 KB  |  1,798 lines

  1. Path: uunet!usc!elroy.jpl.nasa.gov!swrinde!mips!msi!dcmartin
  2. From: nathan@inmos.co.uk (Nathan Sidwell)
  3. Newsgroups: comp.sources.x
  4. Subject: v18i025: Xmris - an X video game, Part04/09
  5. Message-ID: <1992Jul16.171738.1768@msi.com>
  6. Date: 16 Jul 92 17:17:38 GMT
  7. References: <csx-18i022-xmris@uunet.UU.NET>
  8. Sender: dcmartin@msi.com (David C. Martin - Moderator)
  9. Organization: Molecular Simulations, Inc.
  10. Lines: 1784
  11. Approved: dcmartin@msi.com
  12. Originator: dcmartin@fascet
  13.  
  14. Submitted-by: Nathan Sidwell <nathan@inmos.co.uk>
  15. Posting-number: Volume 18, Issue 25
  16. Archive-name: xmris/part04
  17.  
  18. # this is part.04 (part 4 of a multipart archive)
  19. # do not concatenate these parts, unpack them in order with /bin/sh
  20. # file draw.c continued
  21. #
  22. if test ! -r _shar_seq_.tmp; then
  23.     echo 'Please unpack part 1 first!'
  24.     exit 1
  25. fi
  26. (read Scheck
  27.  if test "$Scheck" != 4; then
  28.     echo Please unpack part "$Scheck" next!
  29.     exit 1
  30.  else
  31.     exit 0
  32.  fi
  33. ) < _shar_seq_.tmp || exit 1
  34. if test ! -f _shar_wnt_.tmp; then
  35.     echo 'x - still skipping draw.c'
  36. else
  37. echo 'x - continuing file draw.c'
  38. sed 's/^X//' << 'SHAR_EOF' >> 'draw.c' &&
  39. X    case 2: case 4:
  40. X    {
  41. X      COORD     offset;
  42. X      COORD     pixel;
  43. X      unsigned  bits;
  44. X    
  45. X      pixel.x = player.old_ball.pixel.x - BALL_WIDTH / 2;
  46. X      pixel.y = player.old_ball.pixel.y - BALL_HEIGHT / 2;
  47. X      if(player.old_ball.count)
  48. X    {
  49. X      offset.x = player.old_ball.count * BALL_EX;
  50. X      offset.y = player.old_ball.count * BALL_EY;
  51. X      bits = 0xFF;
  52. X      /*{{{  set clips*/
  53. X      {
  54. X        if(pixel.x < offset.x)
  55. X          bits &= 0xF8;
  56. X        if(pixel.y < offset.y)
  57. X          bits &= 0x3E;
  58. X        if(pixel.x + offset.x > BOARD_WIDTH)
  59. X          bits &= 0x8F;
  60. X        if(pixel.y + offset.y > BOARD_HEIGHT)
  61. X          bits &= 0xE3;
  62. X      }
  63. X      /*}}}*/
  64. X      /*{{{  do inner bits*/
  65. X      {
  66. X        if(bits & 0x01)
  67. X          XCopyArea(display.display, ball_xor, display.window, GCN(GC_BALL),
  68. X          0, 0, BALL_WIDTH, BALL_HEIGHT,
  69. X          pixel.x - offset.x, pixel.y - offset.y);
  70. X        if(bits & 0x02)
  71. X          XCopyArea(display.display, ball_xor, display.window, GCN(GC_BALL),
  72. X          0, 0, BALL_WIDTH, BALL_HEIGHT,
  73. X          pixel.x - offset.x, pixel.y);
  74. X        if(bits & 0x04)
  75. X          XCopyArea(display.display, ball_xor, display.window, GCN(GC_BALL),
  76. X          0, 0, BALL_WIDTH, BALL_HEIGHT,
  77. X          pixel.x - offset.x, pixel.y + offset.y);
  78. X        if(bits & 0x08)
  79. X          XCopyArea(display.display, ball_xor, display.window, GCN(GC_BALL),
  80. X          0, 0, BALL_WIDTH, BALL_HEIGHT,
  81. X          pixel.x, pixel.y + offset.y);
  82. X        if(bits & 0x10)
  83. X          XCopyArea(display.display, ball_xor, display.window, GCN(GC_BALL),
  84. X          0, 0, BALL_WIDTH, BALL_HEIGHT,
  85. X          pixel.x + offset.x, pixel.y + offset.y);
  86. X        if(bits & 0x20)
  87. X          XCopyArea(display.display, ball_xor, display.window, GCN(GC_BALL),
  88. X          0, 0, BALL_WIDTH, BALL_HEIGHT,
  89. X          pixel.x + offset.x, pixel.y);
  90. X        if(bits & 0x40)
  91. X          XCopyArea(display.display, ball_xor, display.window, GCN(GC_BALL),
  92. X          0, 0, BALL_WIDTH, BALL_HEIGHT,
  93. X          pixel.x + offset.x, pixel.y - offset.y);
  94. X        if(bits & 0x80)
  95. X          XCopyArea(display.display, ball_xor, display.window, GCN(GC_BALL),
  96. X          0, 0, BALL_WIDTH, BALL_HEIGHT,
  97. X          pixel.x, pixel.y - offset.y);
  98. X      }
  99. X      /*}}}*/
  100. X      offset.x *= 2;
  101. X      offset.y *= 2;
  102. X      /*{{{  set clips*/
  103. X      {
  104. X        if(pixel.x < offset.x)
  105. X          bits &= 0xF8;
  106. X        if(pixel.y < offset.y)
  107. X          bits &= 0x3E;
  108. X        if(pixel.x + offset.x > BOARD_WIDTH)
  109. X          bits &= 0x8F;
  110. X        if(pixel.y + offset.y > BOARD_HEIGHT)
  111. X          bits &= 0xE3;
  112. X      }
  113. X      /*}}}*/
  114. X      /*{{{  do outer bits*/
  115. X      {
  116. X        if(bits & 0x01)
  117. X          XCopyArea(display.display, ball_xor, display.window, GCN(GC_BALL),
  118. X          0, 0, BALL_WIDTH, BALL_HEIGHT,
  119. X          pixel.x - offset.x, pixel.y - offset.y);
  120. X        if(bits & 0x02)
  121. X          XCopyArea(display.display, ball_xor, display.window, GCN(GC_BALL),
  122. X          0, 0, BALL_WIDTH, BALL_HEIGHT,
  123. X          pixel.x - offset.x, pixel.y);
  124. X        if(bits & 0x04)
  125. X          XCopyArea(display.display, ball_xor, display.window, GCN(GC_BALL),
  126. X          0, 0, BALL_WIDTH, BALL_HEIGHT,
  127. X          pixel.x - offset.x, pixel.y + offset.y);
  128. X        if(bits & 0x08)
  129. X          XCopyArea(display.display, ball_xor, display.window, GCN(GC_BALL),
  130. X          0, 0, BALL_WIDTH, BALL_HEIGHT,
  131. X          pixel.x, pixel.y + offset.y);
  132. X        if(bits & 0x10)
  133. X          XCopyArea(display.display, ball_xor, display.window, GCN(GC_BALL),
  134. X          0, 0, BALL_WIDTH, BALL_HEIGHT,
  135. X          pixel.x + offset.x, pixel.y + offset.y);
  136. X        if(bits & 0x20)
  137. X          XCopyArea(display.display, ball_xor, display.window, GCN(GC_BALL),
  138. X          0, 0, BALL_WIDTH, BALL_HEIGHT,
  139. X          pixel.x + offset.x, pixel.y);
  140. X        if(bits & 0x40)
  141. X          XCopyArea(display.display, ball_xor, display.window, GCN(GC_BALL),
  142. X          0, 0, BALL_WIDTH, BALL_HEIGHT,
  143. X          pixel.x + offset.x, pixel.y - offset.y);
  144. X        if(bits & 0x80)
  145. X          XCopyArea(display.display, ball_xor, display.window, GCN(GC_BALL),
  146. X          0, 0, BALL_WIDTH, BALL_HEIGHT,
  147. X          pixel.x, pixel.y - offset.y);
  148. X      }
  149. X      /*}}}*/
  150. X    }
  151. X      else
  152. X    XCopyArea(display.display, ball_xor, display.window, GCN(GC_BALL),
  153. X        0, 0, BALL_WIDTH, BALL_HEIGHT, pixel.x, pixel.y);
  154. X      break;
  155. X    }
  156. X    /*}}}*/
  157. X    /*{{{  case 3:*/
  158. X    case 3:
  159. X      break;
  160. X    /*}}}*/
  161. X  }
  162. X  return;
  163. }
  164. /*}}}*/
  165. /*{{{  void zoom_board()*/
  166. extern void zoom_board FUNCARGVOID
  167. /* zooms out on the initial board */
  168. {
  169. X  unsigned  count;
  170. X    
  171. X  XFillRectangle(display.display, display.copy, GCN(GC_CLEAR),
  172. X      BORDER_LEFT + 1, BORDER_TOP + 1, BOARD_WIDTH - 2, BOARD_HEIGHT - 2);
  173. X  XCopyArea(display.display, display.copy, display.window, GCN(GC_COPY),
  174. X      0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0);
  175. X  XCopyArea(display.display, display.back, display.copy, GCN(GC_COPY),
  176. X      BORDER_LEFT + 1, BORDER_TOP + 1, BOARD_WIDTH - 2, BOARD_HEIGHT - 2,
  177. X      BORDER_LEFT + 1, BORDER_TOP + 1);
  178. X  /*{{{  do the apple sprites*/
  179. X  {
  180. X    int       i;
  181. X    APPLE     *aptr;
  182. X      
  183. X    for(aptr = apple.list, i = apple.apples; i--; aptr++)
  184. X      {
  185. X    SPRITE    *sptr;
  186. X      
  187. X    sptr = &sprites[SPRITE_APPLE];
  188. X    XCopyArea(display.display, sptr->mask, display.copy, GCN(GC_MASK),
  189. X        0, 0, CELL_WIDTH, CELL_HEIGHT, aptr->pixel.x, aptr->pixel.y);
  190. X    XCopyArea(display.display, sptr->image, display.copy, GCN(GC_OR),
  191. X        0, 0, CELL_WIDTH, CELL_HEIGHT, aptr->pixel.x, aptr->pixel.y);
  192. X      }
  193. X  }
  194. X  /*}}}*/
  195. X  timer_start(ZOOM_RATE);
  196. X  for(count = 0; count < BOARD_HEIGHT / (2 * ZOOM_Y); count += 1)
  197. X    {
  198. X      XCopyArea(display.display, display.copy, display.window, GCN(GC_COPY),
  199. X      BORDER_LEFT + BOARD_WIDTH / 2 - ZOOM_X - count * ZOOM_X,
  200. X      BORDER_TOP + BOARD_HEIGHT / 2 - ZOOM_Y- count * ZOOM_Y,
  201. X      ZOOM_X, count * 2 * ZOOM_Y + 2 * ZOOM_Y,
  202. X      BORDER_LEFT + BOARD_WIDTH / 2 - ZOOM_X - count * ZOOM_X,
  203. X      BORDER_TOP + BOARD_HEIGHT / 2 - ZOOM_Y - count * ZOOM_Y);
  204. X      XCopyArea(display.display, display.copy, display.window, GCN(GC_COPY),
  205. X      BORDER_LEFT + BOARD_WIDTH / 2 + count * ZOOM_X,
  206. X      BORDER_TOP + BOARD_HEIGHT / 2 - ZOOM_Y - count * ZOOM_Y,
  207. X      ZOOM_X, count * 2 * ZOOM_Y + 2 * ZOOM_Y,
  208. X      BORDER_LEFT + BOARD_WIDTH / 2 + count * ZOOM_X,
  209. X      BORDER_TOP + BOARD_HEIGHT / 2 - ZOOM_Y - count * ZOOM_Y);
  210. X      XCopyArea(display.display, display.copy, display.window, GCN(GC_COPY),
  211. X      BORDER_LEFT + BOARD_WIDTH / 2 - count * ZOOM_X,
  212. X      BORDER_TOP + BOARD_HEIGHT / 2 - ZOOM_Y - count * ZOOM_Y,
  213. X      count * 2 * ZOOM_X, ZOOM_Y,
  214. X      BORDER_LEFT + BOARD_WIDTH / 2 - count * ZOOM_X,
  215. X      BORDER_TOP + BOARD_HEIGHT / 2 - ZOOM_Y - count * ZOOM_Y);
  216. X      XCopyArea(display.display, display.copy, display.window, GCN(GC_COPY),
  217. X      BORDER_LEFT + BOARD_WIDTH / 2 - count * ZOOM_X,
  218. X      BORDER_TOP + BOARD_HEIGHT / 2 + count * ZOOM_Y,
  219. X      count * 2 * ZOOM_X, ZOOM_Y,
  220. X      BORDER_LEFT + BOARD_WIDTH / 2 - count * ZOOM_X,
  221. X      BORDER_TOP + BOARD_HEIGHT / 2 + count * ZOOM_Y);
  222. X      XSync(display.display, False);
  223. X      timer_wait();
  224. X    }
  225. X  timer_stop();
  226. X  return;
  227. }
  228. /*}}}*/
  229. SHAR_EOF
  230. echo 'File draw.c is complete' &&
  231. chmod 0644 draw.c ||
  232. echo 'restore of draw.c failed'
  233. Wc_c="`wc -c < 'draw.c'`"
  234. test 23961 -eq "$Wc_c" ||
  235.     echo 'draw.c: original size 23961, current size' "$Wc_c"
  236. rm -f _shar_wnt_.tmp
  237. fi
  238. # ============= monster.c ==============
  239. if test -f 'monster.c' -a X"$1" != X"-c"; then
  240.     echo 'x - skipping monster.c (File already exists)'
  241.     rm -f _shar_wnt_.tmp
  242. else
  243. > _shar_wnt_.tmp
  244. echo 'x - extracting monster.c (Text)'
  245. sed 's/^X//' << 'SHAR_EOF' > 'monster.c' &&
  246. /*{{{  (C) 1992 Nathan Sidwell*/
  247. /*****************************************************************************
  248. X            X M R I S V1.01
  249. X            ---------------
  250. X            (C) 1992 Nathan Sidwell
  251. X
  252. This program is copyright (C) 1992 Nathan Sidwell. This software and documentation
  253. is in the public domain. Permission is granted to distribute and compile
  254. verbatim copies of this software for non-commercial, non-profit use,
  255. without fee. The software may be modified, provided that both the above copyright
  256. notice and this permission notice appear.
  257. X
  258. No guarantee is given as to the robustness or suitability of this
  259. software for your computer.
  260. X
  261. Nathan Sidwell  INMOS UK |                 | nathan@inmos.co.uk       DoD#0390
  262. *****************************************************************************/
  263. /*}}}*/
  264. #include "xmris.h"
  265. /*{{{  prototypes*/
  266. static void extra_dies PROTOARGLIST((void));
  267. /*}}}*/
  268. /*{{{  MONSTER *extra_escape()*/
  269. extern MONSTER *extra_escape FUNCARGVOID
  270. /*
  271. X * remove the extra monster from the top, so it
  272. X * can run around
  273. X */
  274. {
  275. X  int       x;
  276. X  
  277. X  extra.escape = 1;
  278. X  x = XTRA_X + extra.select * XTRA_SPACING;
  279. X  XFillRectangle(display.display, display.back, GCN(GC_CLEAR),
  280. X      x, XTRA_Y, CELL_WIDTH, CELL_HEIGHT);
  281. X  add_background(x, XTRA_Y, CELL_WIDTH, CELL_HEIGHT);
  282. X  x -= BORDER_LEFT + GAP_WIDTH;
  283. X  assert(x % (CELL_WIDTH + GAP_WIDTH) % VEL_X == 0);
  284. X  return spawn_monster(2, 1, 1, x / (CELL_WIDTH + GAP_WIDTH), 0,
  285. X      x % (CELL_WIDTH + GAP_WIDTH), XTRA_Y - BORDER_TOP);
  286. }
  287. /*}}}*/
  288. /*{{{  void extra_dies()*/
  289. static void extra_dies FUNCARGVOID
  290. /*
  291. X * the extra monster has died,
  292. X * put it back at the top
  293. X * and maybe alter the state
  294. X */
  295. {
  296. X  unsigned  got;
  297. X  
  298. X  if(global.state == 2)
  299. X    {
  300. X      global.state = 3;
  301. X      monster.den = 0;
  302. X      monster.delay = 0;
  303. X    }
  304. X  got = extra.got & (1 << extra.select);
  305. X  extra.got |= 1 << extra.select;
  306. X  extra.escape = 0;
  307. X  if(!got)
  308. X    create_xtra_monster(extra.select);
  309. X  draw_extra();
  310. X  return;
  311. }
  312. /*}}}*/
  313. /*{{{  void fall_monsters()*/
  314. extern void fall_monsters FUNCARGVOID
  315. /*
  316. X * makes all the monsters fall
  317. X */
  318. {
  319. X  unsigned  i;
  320. X  MONSTER   *mptr;
  321. X
  322. X  for(mptr = monster.list, i = monster.monsters; i--; mptr++)
  323. X    if(mptr->apple)
  324. X      {
  325. X    /*{{{  just hit?*/
  326. X    if(mptr->face < 8)
  327. X      {
  328. X        if(BOARDCELL(mptr->cell.x, mptr->cell.y)->distance ==
  329. X          monster.nearest)
  330. X        global.difficulty++;
  331. X        new_face(mptr);
  332. X        if(mptr == &monster.list[0])
  333. X          mptr->shot = 1;
  334. X        else
  335. X          {
  336. X        mptr->chew = 0;
  337. X        if(mptr->type < 2)
  338. X          monster.normals--;
  339. X        else if(mptr->type == 2)
  340. X          extra_dies();
  341. X        else if(mptr->type == 3)
  342. X          monster.drones--;
  343. X          }
  344. X      }
  345. X    /*}}}*/
  346. X    mptr->pixel.y = mptr->apple->pixel.y + CELL_HEIGHT;
  347. X    if(mptr->apple && mptr->apple->state > 3)
  348. X      {
  349. X        if(mptr->type != 4)
  350. X          mptr->type = 5;
  351. X        else
  352. X          mptr->apple = NULL;
  353. X      }
  354. X      }
  355. X  return;
  356. }
  357. /*}}}*/
  358. /*{{{  void move_monsters()*/
  359. extern void move_monsters FUNCARGVOID
  360. /*
  361. X * moves all the monsters
  362. X */
  363. {
  364. X  MONSTER   *mptr;
  365. X  unsigned  i;
  366. X  unsigned  nearest;
  367. X  unsigned  farthest;
  368. X
  369. X  nearest = 255;
  370. X  farthest = 0;
  371. X  for(mptr = &monster.list[1], i = monster.monsters - 1; i--; mptr++)
  372. X    {
  373. X      if(mptr->shot || (mptr->type == 3 && global.state == 3))
  374. X    /*{{{  shot*/
  375. X    {
  376. X      if(BOARDCELL(mptr->cell.x, mptr->cell.y)->distance ==
  377. X          monster.nearest)
  378. X        global.difficulty++;
  379. X      if(mptr->type < 2)
  380. X        monster.normals--;
  381. X      else
  382. X        /*{{{  convert to apple*/
  383. X        {
  384. X          APPLE     *aptr;
  385. X          CELL      *cptr;
  386. X              
  387. X          if(mptr->type == 2)
  388. X        extra_dies();
  389. X          else if(mptr->type == 3)
  390. X        monster.drones--;
  391. X          if(mptr->offset.x > (CELL_WIDTH + GAP_WIDTH) / 2)
  392. X        {
  393. X          mptr->offset.x -= CELL_WIDTH + GAP_WIDTH;
  394. X          mptr->cell.x++;
  395. X        }
  396. X          else if(mptr->offset.x < -(CELL_WIDTH + GAP_WIDTH) / 2)
  397. X        {
  398. X          mptr->offset.x += CELL_WIDTH + GAP_WIDTH;
  399. X          mptr->cell.x--;
  400. X        }
  401. X          cptr = BOARDCELL(mptr->cell.x, mptr->cell.y);
  402. X          aptr = spawn_apple(mptr->cell.x, mptr->cell.y,
  403. X          mptr->offset.x, mptr->offset.y);
  404. X          if(mptr->cell.y == CELLS_DOWN - 1)
  405. X        aptr->state = 2;
  406. X          else if(mptr->offset.y < cptr->depths[1])
  407. X        aptr->state = 2;
  408. X          else if(!mptr->offset.y && cptr[CELL_STRIDE].visit)
  409. X        {
  410. X          aptr->state = 1;
  411. X          aptr->count = APPLE_ROCK_DELAY;
  412. X        }
  413. X        }
  414. X        /*}}}*/
  415. X      if(mptr->shot)
  416. X        add_score(500, mptr->pixel.x + CELL_WIDTH / 2,
  417. X        mptr->pixel.y + CELL_HEIGHT / 2);
  418. X      mptr->type = 5;
  419. X    }
  420. X    /*}}}*/
  421. X      else if(mptr->apple)
  422. X    /*EMPTY*/;
  423. X      else if(mptr->chew)
  424. X    /*{{{  chewing*/
  425. X    {
  426. X      if(mptr->chew == 1)
  427. X        {
  428. X          mptr->chew = 2;
  429. X          mptr->count = CHOMP_DELAY;
  430. X          mptr->image = 0;
  431. X          mptr->cycle = MONSTER_CYCLES - 1;
  432. X        }
  433. X      mptr->count--;
  434. X      if(!mptr->count)
  435. X        mptr->chew = 0;
  436. X      if(!mptr->cycle)
  437. X        {
  438. X          mptr->image = (mptr->image + 1) % MONSTER_IMAGES;
  439. X          mptr->cycle = MONSTER_CYCLES;
  440. X        }
  441. X      mptr->cycle--;
  442. X    }
  443. X    /*}}}*/
  444. X      else if(global.state != 4)
  445. X    {
  446. X      CELL      *cptr;
  447. X
  448. X      cptr = BOARDCELL(mptr->cell.x, mptr->cell.y);
  449. X      assert((cptr->distance || global.broken) && cptr->visit);
  450. X      if(!mptr->cycle)
  451. X        {
  452. X          mptr->cycle = MONSTER_CYCLES;
  453. X          mptr->image++;
  454. X          if(mptr->image == MONSTER_IMAGES)
  455. X        mptr->image = 0;
  456. X        }
  457. X      if((!mptr->count || mptr->type & 2) && !mptr->pause)
  458. X        mptr->cycle--;
  459. X      if(mptr->type & 2 || global.state != 2)
  460. X        {
  461. X          if(nearest > cptr->distance)
  462. X        nearest = cptr->distance;
  463. X          if(farthest < cptr->distance)
  464. X        farthest = cptr->distance;
  465. X        }
  466. X      switch(mptr->type)
  467. X      {
  468. X        /*{{{  case 0: case 1: (normal or muncher)*/
  469. X        case 0: case 1:
  470. X        {
  471. X          int     valid;
  472. X              
  473. X          valid = valid_directions(mptr, cptr);
  474. X          if(mptr->count)
  475. X        mptr->count--;
  476. X          if(!mptr->type && random() < CONT_TOGGLE_PROB)
  477. X        /*{{{  toggle the cont & maybe turn round*/
  478. X        {
  479. X          mptr->cont = !mptr->cont;
  480. X          if(mptr->pause || mptr->stop)
  481. X            {
  482. X              mptr->dir ^= 1;
  483. X              new_face(mptr);
  484. X            }
  485. X        }
  486. X        /*}}}*/
  487. X          if(mptr->push)
  488. X        /*{{{  disable left or right*/
  489. X        {
  490. X          if(mptr->push < 0)
  491. X            valid &= 0x77;
  492. X          else
  493. X            valid &= 0xBB;
  494. X        }
  495. X        /*}}}*/
  496. X          else if(mptr->count)
  497. X        valid = 0;
  498. X          else if(mptr->pause)
  499. X        {
  500. X          if(!mptr->type)
  501. X            {
  502. X              if(random() < GO_MUNCH_PROB * global.difficulty)
  503. X            mptr->gomunch = 1;
  504. X              valid = 0;
  505. X            }
  506. X          else if(mptr->stop || random() < PUSH_TURN_PROB)
  507. X            {
  508. X              mptr->dir ^= 1;
  509. X              new_face(mptr);
  510. X              valid = 0;
  511. X            }
  512. X          mptr->stop = 0;
  513. X          mptr->pause = 0;
  514. X        }
  515. X          else if(global.state == 2)
  516. X        valid = 0;
  517. X          else if(!mptr->offset.x && !mptr->offset.y)
  518. X        {
  519. X          mptr->fast = 0;
  520. X          if(!mptr->type && global.state == 3)
  521. X            mptr->fast = 1;
  522. X          if(mptr->gomunch)
  523. X            {
  524. X              mptr->gomunch = 0;
  525. X              mptr->type = 1;
  526. X              mptr->count = GO_MUNCH_DELAY;
  527. X            }
  528. X          else if(mptr->type)
  529. X            {
  530. X              int       temp;
  531. X            
  532. X              temp = valid & 0xF;
  533. X              if((temp & -temp) != temp)
  534. X            {
  535. X              APPLE     *aptr;
  536. X              unsigned  i;
  537. X              int       x;
  538. X                      
  539. X              mptr->type = 0;
  540. X              mptr->count = STOP_MUNCH_DELAY;
  541. X              valid = 0;
  542. X              x = mptr->pixel.x - CELL_WIDTH + GAP_WIDTH * 2;
  543. X              for(aptr = apple.list, i = apple.apples; i--; aptr++)
  544. X                {
  545. X                  if(!aptr->state && aptr->pixel.x - x >= 0 &&
  546. X                  aptr->pixel.x - x < CELL_WIDTH * 2 - GAP_WIDTH * 4 &&
  547. X                  aptr->cell.y == mptr->cell.y - 1)
  548. X                {
  549. X                  aptr->state = 1;
  550. X                  aptr->count = APPLE_ROCK_DELAY;
  551. X                }
  552. X                }
  553. X            }
  554. X            }
  555. X          else if(!mptr->type && random() <
  556. X              GO_MUNCH_PROB * global.difficulty)
  557. X            mptr->gomunch = 1;
  558. X        }
  559. X          if(!valid)
  560. X        /*EMPTY*/;
  561. X          else if(mptr->type)
  562. X        /*{{{  move the muncher*/
  563. X        {
  564. X          if(mptr->offset.x || mptr->offset.y)
  565. X            /*{{{  carry on*/
  566. X            {
  567. X              CELL      *nptr;
  568. X                      
  569. X              nptr = move_muncher(mptr);
  570. X              if(nptr)
  571. X            {
  572. X              cptr = nptr;
  573. X              if(nptr->sprite == SPRITE_CHERRY)
  574. X                {
  575. X                  global.cherries--;
  576. X                  nptr->sprite = 0;
  577. X                }
  578. X            }
  579. X            }
  580. X            /*}}}*/
  581. X          else
  582. X            /*{{{  pick new direction*/
  583. X            {
  584. X              int     temp;
  585. X                      
  586. X              temp = ~valid & 0xF;
  587. X              if(!mptr->cell.y)
  588. X            temp &= 0xE;
  589. X              else if(mptr->cell.y == CELLS_DOWN - 1)
  590. X            temp &= 0xD;
  591. X              if(!mptr->cell.x)
  592. X            temp &= 0xB;
  593. X              else if(mptr->cell.x == CELLS_ACROSS - 1)
  594. X            temp &= 0x7;
  595. X              if(!temp)
  596. X            temp = valid & 0xF;
  597. X              if(mptr->pixel.x < monster.list[0].pixel.x)
  598. X            valid = 0x8;
  599. X              else if(mptr->pixel.x > monster.list[0].pixel.x)
  600. X            valid = 0x4;
  601. X              else
  602. X            valid = 0;
  603. X              if(!(valid & temp))
  604. X            {
  605. X              if(mptr->pixel.y < monster.list[0].pixel.y)
  606. X                valid = 0x2;
  607. X              else if(mptr->pixel.y > monster.list[0].pixel.y)
  608. X                valid = 0x1;
  609. X              if(!(valid & temp))
  610. X                valid = temp;
  611. X            }
  612. X              assert(valid);
  613. X              for(temp = 0; !(valid & 1); temp++)
  614. X            valid >>= 1;
  615. X              if(temp != mptr->dir)
  616. X            {
  617. X              mptr->dir = temp;
  618. X              new_face(mptr);
  619. X            }
  620. X              move_muncher(mptr);
  621. X            }
  622. X            /*}}}*/
  623. X        }
  624. X        /*}}}*/
  625. X          else
  626. X        /*{{{  pick a direction*/
  627. X        {
  628. X          unsigned  temp;
  629. X                  
  630. X          if(mptr->cont)
  631. X            {
  632. X              valid &= 0xF;
  633. X              temp = valid & ~(1 << (mptr->dir ^ 1));
  634. X              if(temp)
  635. X            valid = temp;
  636. X            }
  637. X          else if(valid & 0xF0)
  638. X            valid = valid & valid >> 4;
  639. X          valid = choose_direction(valid);
  640. X          temp = mptr->dir;
  641. X          if(valid != mptr->dir)
  642. X            {
  643. X              mptr->dir = valid;
  644. X              if(mptr->push && (valid ^ temp) != 1)
  645. X            {
  646. X              mptr->push = 0;
  647. X              mptr->cont = 1;
  648. X            }
  649. X              new_face(mptr);
  650. X            }
  651. X          if(!apple_stop(mptr, cptr))
  652. X            cptr = move_movable(mptr, cptr);
  653. X          if(mptr->push)
  654. X            {
  655. X              mptr->dir = temp;
  656. X              mptr->push = 0;
  657. X            }
  658. X        }
  659. X        /*}}}*/
  660. X          break;
  661. X        }
  662. X        /*}}}*/
  663. X        /*{{{  case 2: case 3: (xtra or drone)*/
  664. X        case 2: case 3:
  665. X        {
  666. X          int     valid;
  667. X          int     temp;
  668. X              
  669. X          /*{{{  giving birth?*/
  670. X          if(monster.delay && mptr->type == 2 && global.state == 2)
  671. X        {
  672. X          monster.delay--;
  673. X          if(monster.delay)
  674. X            break;
  675. X          if(monster.den)
  676. X            {
  677. X              monster.delay = XTRA_BIRTH_DELAY;
  678. X              monster.den--;
  679. X              spawn_monster(3, mptr->dir, mptr->face,
  680. X              mptr->cell.x, mptr->cell.y,
  681. X              mptr->offset.x, mptr->offset.y);
  682. X              monster.drones++;
  683. X              i++;
  684. X            }
  685. X        }
  686. X          /*}}}*/
  687. X          valid = valid_directions(mptr, cptr);
  688. X          if(global.state == 3 && !mptr->offset.x && ! mptr->offset.y)
  689. X        mptr->fast = 1;
  690. X          /*{{{  pick a direction*/
  691. X          {
  692. X        if(valid & 0xF0 &&
  693. X            (mptr->type != 2 || player.ball.state ||
  694. X            (global.state == 2 ? mptr->count == monster.farthest :
  695. X             mptr->count != monster.nearest)))
  696. X          {
  697. X            mptr->cont = 0;
  698. X            valid >>= 4;
  699. X          }
  700. X        else
  701. X          {
  702. X            temp = valid & ((valid >> 4) ^ 0xF);
  703. X            if(temp)
  704. X              valid = temp;
  705. X            else
  706. X              valid &= 0xF;
  707. X          }
  708. X        valid = choose_direction(valid);
  709. X        if(valid != mptr->dir)
  710. X          {
  711. X            mptr->dir = valid;
  712. X            new_face(mptr);
  713. X          }
  714. X        mptr->count = cptr->distance;
  715. X        cptr = move_movable(mptr, cptr);
  716. X        /*{{{  walked into apple?*/
  717. X        {
  718. X          unsigned  i;
  719. X          APPLE     *aptr;
  720. X          int       x, y;
  721. X          int       width, height;
  722. X                  
  723. X          x = mptr->pixel.x;
  724. X          y = mptr->pixel.y;
  725. X          /*{{{  set offset*/
  726. X          if(mptr->dir & 2)
  727. X            {
  728. X              x -= CELL_WIDTH / 2;
  729. X              y -= CELL_HEIGHT / 4;
  730. X              width = CELL_WIDTH;
  731. X              height = CELL_HEIGHT / 2;
  732. X            }
  733. X          else
  734. X            {
  735. X              x -= CELL_WIDTH / 4;
  736. X              y -= CELL_HEIGHT / 2;
  737. X              width = CELL_WIDTH / 2;
  738. X              height = CELL_HEIGHT;
  739. X            }
  740. X          /*}}}*/
  741. X          for(aptr = apple.list, i = apple.apples; i--; aptr++)
  742. X            {
  743. X              if(aptr->state < 3 &&
  744. X              aptr->pixel.x - x >= 0 &&
  745. X              aptr->pixel.x - x < width &&
  746. X              aptr->pixel.y - y >= 0 &&
  747. X              aptr->pixel.y - y < height)
  748. X            {
  749. X              mptr->chew = 1;
  750. X              aptr->chewed = 1;
  751. X              break;
  752. X            }
  753. X            }
  754. X        }
  755. X        /*}}}*/
  756. X          }
  757. X          /*}}}*/
  758. X          break;
  759. X        }
  760. X        /*}}}*/
  761. X        /*{{{  default:*/
  762. X        default:
  763. X          assert(0);
  764. X          break;
  765. X        /*}}}*/
  766. X      }
  767. X    }
  768. X    }
  769. X  monster.nearest = nearest;
  770. X  monster.farthest = farthest;
  771. X  return;
  772. }
  773. /*}}}*/
  774. /*{{{  void new_xtra()*/
  775. extern void new_xtra FUNCARGVOID
  776. /*
  777. X * increments the extra monster, and draws it up
  778. X */
  779. {
  780. X  draw_extra_letter(extra.select);
  781. X  if(extra.select == 4)
  782. X    extra.select = 0;
  783. X  else
  784. X    extra.select++;
  785. X  create_xtra_monster(extra.select);
  786. X  draw_extra();
  787. X  return;
  788. }
  789. /*}}}*/
  790. /*{{{  MONSTER *spawn_monster(type, dir, face, cx, cy, ox, oy)*/
  791. extern MONSTER *spawn_monster FUNCARGLIST((type, dir, face, cx, cy, ox, oy))
  792. int       type  FUNCARGSEP  /* type of monster 0-4 */
  793. int       dir   FUNCARGSEP  /* direction 0-3 */
  794. int       face  FUNCARGSEP  /* face 0-5 */
  795. int       cx    FUNCARGSEP  /* cell x */
  796. int       cy    FUNCARGSEP  /* cell y */
  797. int       ox    FUNCARGSEP  /* offset x */
  798. int       oy    FUNCARGTERM /* offset y */
  799. /*
  800. X * creates a new monster onto the monster list
  801. X * returns a pointer to the new monster
  802. X */
  803. {
  804. X  MONSTER *mptr;
  805. X
  806. X  assert(monster.monsters != MONSTERS);
  807. X  assert(!(ox % VEL_X) && !(oy % VEL_Y));
  808. X  mptr = &monster.list[monster.monsters++];
  809. X  mptr->dir = dir;
  810. X  mptr->type = type;
  811. X  mptr->face = face;
  812. X  mptr->apple = NULL;
  813. X  mptr->push = 0;
  814. X  mptr->gomunch = mptr->cont = mptr->chew = mptr->pause = mptr->stop = 0;
  815. X  mptr->fast = mptr->pushing = 0;
  816. X  mptr->count = 0;
  817. X  mptr->cell.x = cx;
  818. X  mptr->cell.y = cy;
  819. X  mptr->offset.x = ox;
  820. X  mptr->offset.y = oy;
  821. X  mptr->pixel.x = PIXELX(cx, ox);
  822. X  mptr->pixel.y = PIXELY(cy, oy);
  823. X  mptr->image = random() % MONSTER_IMAGES;
  824. X  mptr->cycle = random() % MONSTER_CYCLES;
  825. X  mptr->shot = 0;
  826. X  mptr->old_sprite = 0;
  827. X  return mptr;
  828. }
  829. /*}}}*/
  830. SHAR_EOF
  831. chmod 0644 monster.c ||
  832. echo 'restore of monster.c failed'
  833. Wc_c="`wc -c < 'monster.c'`"
  834. test 13476 -eq "$Wc_c" ||
  835.     echo 'monster.c: original size 13476, current size' "$Wc_c"
  836. rm -f _shar_wnt_.tmp
  837. fi
  838. # ============= move.c ==============
  839. if test -f 'move.c' -a X"$1" != X"-c"; then
  840.     echo 'x - skipping move.c (File already exists)'
  841.     rm -f _shar_wnt_.tmp
  842. else
  843. > _shar_wnt_.tmp
  844. echo 'x - extracting move.c (Text)'
  845. sed 's/^X//' << 'SHAR_EOF' > 'move.c' &&
  846. /*{{{  (C) 1992 Nathan Sidwell*/
  847. /*****************************************************************************
  848. X            X M R I S V1.01
  849. X            ---------------
  850. X            (C) 1992 Nathan Sidwell
  851. X
  852. This program is copyright (C) 1992 Nathan Sidwell. This software and documentation
  853. is in the public domain. Permission is granted to distribute and compile
  854. verbatim copies of this software for non-commercial, non-profit use,
  855. without fee. The software may be modified, provided that both the above copyright
  856. notice and this permission notice appear.
  857. X
  858. No guarantee is given as to the robustness or suitability of this
  859. software for your computer.
  860. X
  861. Nathan Sidwell  INMOS UK |                 | nathan@inmos.co.uk       DoD#0390
  862. *****************************************************************************/
  863. /*}}}*/
  864. #include "xmris.h"
  865. /*{{{  prototypes*/
  866. static void munch_back PROTOARGLIST((int, int, int, int, int, int, SPRITE *));
  867. /*}}}*/
  868. /*{{{  unsigned choose_direction(valid)*/
  869. extern unsigned choose_direction FUNCARGLIST((valid))
  870. unsigned  valid FUNCARGTERM
  871. /* picks a direction at random from the valid ones */
  872. {
  873. X  unsigned  choices;
  874. X  unsigned  temp;
  875. X  unsigned  choice;
  876. X  
  877. X  assert(valid && !(valid & ~0xF));
  878. X  for(choices = 0, temp = valid; temp; choices++)
  879. X    temp ^= temp & -temp;
  880. X  if(choices == 1)
  881. X    choice = 0;
  882. X  else if(choices == 3)
  883. X    choice = random() % 3;
  884. X  else
  885. X    choice = random() & (choices - 1);
  886. X  do
  887. X    {
  888. X      temp = valid & -valid;
  889. X      valid ^= temp;
  890. X    }
  891. X  while(choice--);
  892. X  assert(temp);
  893. X  for(valid = 0; !(temp & 1); valid++)
  894. X    temp >>= 1;
  895. X  return valid;
  896. }
  897. /*}}}*/
  898. /*{{{  CELL *drop_apple(aptr, cptr)*/
  899. extern CELL *drop_apple FUNCARGLIST((aptr, cptr))
  900. APPLE   *aptr FUNCARGSEP
  901. CELL    *cptr FUNCARGTERM
  902. /*
  903. X * deals with apples which break through to the cell below
  904. X * the apple has already been moved to the new coordinate
  905. X * returns NULL if we stay in the same cell, or a pointer
  906. X * to the new cell
  907. X */
  908. {
  909. X  CELL      *new;
  910. X  COORD     pixel;
  911. X
  912. X  update.set = 0;
  913. X  pixel.x = aptr->pixel.x - aptr->offset.x;
  914. X  pixel.y = aptr->pixel.y - aptr->offset.y;
  915. X  if(aptr->offset.y <= cptr[0].depths[1])
  916. X    new = NULL;
  917. X  else if(cptr[CELL_STRIDE].visit)
  918. X    /*{{{  break through below*/
  919. X    {
  920. X      /*{{{  munch*/
  921. X      {
  922. X    SPRITE      *sptr;
  923. X              
  924. X    sptr = &sprites[SPRITE_EDGE_BASE + 1];
  925. X    /*{{{  munch the left half of the edge below*/
  926. X    {
  927. X      unsigned  type;
  928. X            
  929. X      type = 0;
  930. X      if(cptr[0].depths[2] < -VEL_X)
  931. X        type = GAP_HEIGHT;
  932. X      if(cptr[CELL_STRIDE].depths[2] < -VEL_X)
  933. X        type += 2 * GAP_HEIGHT;
  934. X      if(type == 3 * GAP_HEIGHT &&
  935. X          (cptr[-1].depths[1] > VEL_Y ||
  936. X          cptr[CELL_STRIDE-1].depths[0] < -VEL_Y))
  937. X        type = 4 * GAP_HEIGHT;
  938. X      munch_back(0, type,
  939. X          EDGE_WIDTH >> 1, GAP_HEIGHT,
  940. X          pixel.x + (CELL_WIDTH >> 1) - (EDGE_WIDTH >> 1),
  941. X          pixel.y + CELL_HEIGHT, sptr);
  942. X      if(!cptr[0].depths[2])
  943. X        munch_back(0, 0, EDGE_WIDTH >> 1, GAP_HEIGHT,
  944. X        pixel.x + (CELL_WIDTH >> 1) - (EDGE_WIDTH >> 1),
  945. X        pixel.y + CELL_HEIGHT - GAP_WIDTH, sptr);
  946. X      if(!cptr[CELL_STRIDE].depths[2])
  947. X        munch_back(0, 0, EDGE_WIDTH >> 1, GAP_HEIGHT,
  948. X        pixel.x + (CELL_WIDTH >> 1) - (EDGE_WIDTH >> 1),
  949. X        pixel.y + CELL_HEIGHT + GAP_HEIGHT, sptr);
  950. X    }
  951. X    /*}}}*/
  952. X    /*{{{  munch the right half of the edge below*/
  953. X    {
  954. X      unsigned  type;
  955. X            
  956. X      type = 0;
  957. X      if(cptr[0].depths[3] > VEL_X)
  958. X        type = GAP_HEIGHT;
  959. X      if(cptr[CELL_STRIDE].depths[3] > VEL_X)
  960. X        type += 2 * GAP_HEIGHT;
  961. X      if(type == 3 * GAP_HEIGHT &&
  962. X          (cptr[1].depths[1] > VEL_Y ||
  963. X          cptr[CELL_STRIDE+1].depths[0] < -VEL_Y))
  964. X        type = 4 * GAP_HEIGHT;
  965. X      munch_back(EDGE_WIDTH >> 1, type,
  966. X          EDGE_WIDTH >> 1, GAP_HEIGHT,
  967. X          pixel.x + (CELL_WIDTH >> 1),
  968. X          pixel.y + CELL_HEIGHT, sptr);
  969. X      if(!cptr[0].depths[3])
  970. X        munch_back(EDGE_WIDTH >> 1, 0,
  971. X        EDGE_WIDTH >> 1, GAP_HEIGHT,
  972. X        pixel.x + (CELL_WIDTH >> 1),
  973. X        pixel.y + CELL_HEIGHT - GAP_WIDTH, sptr);
  974. X      if(!cptr[CELL_STRIDE].depths[3])
  975. X        munch_back(EDGE_WIDTH >> 1, 0,
  976. X        EDGE_WIDTH >> 1, GAP_HEIGHT,
  977. X        pixel.x + (CELL_WIDTH >> 1),
  978. X        pixel.y + CELL_HEIGHT + GAP_HEIGHT, sptr);
  979. X    }
  980. X    /*}}}*/
  981. X      }
  982. X      /*}}}*/
  983. X      aptr->offset.y -= CELL_HEIGHT + GAP_HEIGHT;
  984. X      aptr->cell.y += 1;
  985. X      pixel.y += CELL_HEIGHT + GAP_HEIGHT;
  986. X      global.broken = 1;
  987. X      cptr[0].depths[1] = CELL_HEIGHT + GAP_HEIGHT;
  988. X      new = cptr + CELL_STRIDE;
  989. X      cptr[CELL_STRIDE].depths[0] = -(CELL_HEIGHT + GAP_HEIGHT);
  990. X    }
  991. X    /*}}}*/
  992. X  else if(aptr->offset.y - cptr[CELL_STRIDE * 2].depths[0] >=
  993. X      CELL_HEIGHT + GAP_HEIGHT)
  994. X    /*{{{  breakthrough 2 below*/
  995. X    {
  996. X      aptr->offset.y -= CELL_HEIGHT + GAP_HEIGHT;
  997. X      aptr->cell.y += 1;
  998. X      pixel.y += CELL_HEIGHT + GAP_HEIGHT;
  999. X      global.broken = 1;
  1000. X      cptr[CELL_STRIDE].visit = 1;
  1001. X      cptr[0].depths[1] = CELL_HEIGHT + GAP_HEIGHT;
  1002. X      cptr[CELL_STRIDE].depths[0] = -(CELL_HEIGHT + GAP_HEIGHT);
  1003. X      cptr[CELL_STRIDE].depths[1] = CELL_HEIGHT + GAP_HEIGHT;
  1004. X      cptr[CELL_STRIDE * 2].depths[0] = -(CELL_HEIGHT + GAP_HEIGHT);
  1005. X      if(cptr[CELL_STRIDE - 1].depths[3])
  1006. X    {
  1007. X      cptr[CELL_STRIDE].depths[2] = -(CELL_WIDTH + GAP_WIDTH);
  1008. X      cptr[CELL_STRIDE-1].depths[3] = CELL_WIDTH + GAP_WIDTH;
  1009. X    }
  1010. X      if(cptr[CELL_STRIDE+1].depths[2])
  1011. X    {
  1012. X      cptr[CELL_STRIDE].depths[3] = CELL_WIDTH + GAP_WIDTH;
  1013. X      cptr[CELL_STRIDE+1].depths[2] = -(CELL_WIDTH + GAP_WIDTH);
  1014. X    }
  1015. X      munch_hole(cptr + CELL_STRIDE, pixel.x, pixel.y);
  1016. X      new = cptr + CELL_STRIDE;
  1017. X    }
  1018. X    /*}}}*/
  1019. X  else
  1020. X    new = NULL;
  1021. X  /*{{{  redraw prize?*/
  1022. X  if(new && new->sprite)
  1023. X    {
  1024. X      SPRITE    *sptr;
  1025. X    
  1026. X      sptr = &sprites[new->sprite];
  1027. X      if(display.background != COLOUR_ZERO)
  1028. X    XCopyArea(display.display, sptr->mask, display.back, GCN(GC_MASK),
  1029. X        0, 0, CELL_WIDTH, CELL_HEIGHT,
  1030. X        pixel.x, pixel.y);
  1031. X      XCopyArea(display.display, sptr->image, display.back, GCN(GC_OR),
  1032. X      0, 0, CELL_WIDTH, CELL_HEIGHT,
  1033. X      pixel.x, pixel.y);
  1034. X    }
  1035. X  /*}}}*/
  1036. X  if(update.set)
  1037. X    add_background(update.tl.x, update.tl.y,
  1038. X    update.br.x - update.tl.x, update.br.y - update.tl.y);
  1039. X  return new;
  1040. }
  1041. /*}}}*/
  1042. /*{{{  CELL *move_movable(mptr, cptr)*/
  1043. extern CELL *move_movable FUNCARGLIST((mptr, cptr))
  1044. MONSTER   *mptr FUNCARGSEP
  1045. CELL      *cptr FUNCARGTERM
  1046. {
  1047. X  unsigned  delta;
  1048. X  
  1049. X  switch(mptr->dir)
  1050. X  {
  1051. X    /*{{{  case 0: (up)*/
  1052. X    case 0:
  1053. X      if(!mptr->fast)
  1054. X    delta = VEL_Y;
  1055. X      else if(mptr->offset.y > (CELL_HEIGHT + GAP_HEIGHT) - VEL_Y_FAST * FAST_STEPS)
  1056. X    delta = VEL_Y_FAST;
  1057. X      else if(mptr->offset.y > GAP_HEIGHT + VEL_Y_FAST * FAST_STEPS)
  1058. X    delta = VEL_Y;
  1059. X      else if(mptr->offset.y > GAP_HEIGHT)
  1060. X    delta = VEL_Y_FAST;
  1061. X      else if(mptr->offset.y > 0)
  1062. X    delta = VEL_Y;
  1063. X      else if(mptr->offset.y > - VEL_Y_FAST * FAST_STEPS)
  1064. X    delta = VEL_Y_FAST;
  1065. X      else if(mptr->offset.y > - CELL_HEIGHT + VEL_Y_FAST * FAST_STEPS)
  1066. X    delta = VEL_Y;
  1067. X      else if(mptr->offset.y > - CELL_HEIGHT)
  1068. X    delta = VEL_Y_FAST;
  1069. X      else
  1070. X    delta = VEL_Y;
  1071. X      mptr->pixel.y -= delta;
  1072. X      mptr->offset.y -= delta;
  1073. X      if(mptr->offset.y == -(CELL_HEIGHT + GAP_HEIGHT))
  1074. X    {
  1075. X      mptr->offset.y = 0;
  1076. X      mptr->cell.y -= 1;
  1077. X      cptr -= CELL_STRIDE;
  1078. X    }
  1079. X      assert(cptr->visit && !mptr->offset.x && mptr->cell.y >= 0);
  1080. X      break;
  1081. X    /*}}}*/
  1082. X    /*{{{  case 1: (down)*/
  1083. X    case 1:
  1084. X      if(!mptr->fast)
  1085. X    delta = VEL_Y;
  1086. X      else if(mptr->offset.y < -(CELL_HEIGHT + GAP_HEIGHT) + VEL_Y_FAST * FAST_STEPS)
  1087. X    delta = VEL_Y_FAST;
  1088. X      else if(mptr->offset.y < - GAP_HEIGHT - VEL_Y_FAST * FAST_STEPS)
  1089. X    delta = VEL_Y;
  1090. X      else if(mptr->offset.y < -GAP_HEIGHT)
  1091. X    delta = VEL_Y_FAST;
  1092. X      else if(mptr->offset.y < 0)
  1093. X    delta = VEL_Y;
  1094. X      else if(mptr->offset.y < VEL_Y_FAST * FAST_STEPS)
  1095. X    delta = VEL_Y_FAST;
  1096. X      else if(mptr->offset.y < CELL_HEIGHT - VEL_Y_FAST * FAST_STEPS)
  1097. X    delta = VEL_Y;
  1098. X      else if(mptr->offset.y < CELL_HEIGHT)
  1099. X    delta = VEL_Y_FAST;
  1100. X      else
  1101. X    delta = VEL_Y;
  1102. X      mptr->pixel.y += delta;
  1103. X      mptr->offset.y += delta;
  1104. X      if(mptr->offset.y == CELL_HEIGHT + GAP_HEIGHT)
  1105. X    {
  1106. X      mptr->offset.y = 0;
  1107. X      mptr->cell.y += 1;
  1108. X      cptr += CELL_STRIDE;
  1109. X    }
  1110. X      assert(cptr->visit && mptr->cell.y < CELLS_DOWN &&
  1111. X      (!mptr->offset.x || (!mptr->cell.y && mptr->offset.y <= 0)));
  1112. X      break;
  1113. X    /*}}}*/
  1114. X    /*{{{  case 2: (left)*/
  1115. X    case 2:
  1116. X      if(!mptr->fast)
  1117. X    delta = VEL_X;
  1118. X      else if(mptr->offset.x > (CELL_WIDTH + GAP_WIDTH) - VEL_X_FAST * FAST_STEPS)
  1119. X    delta = VEL_X_FAST;
  1120. X      else if(mptr->offset.x > GAP_WIDTH + VEL_X_FAST * FAST_STEPS)
  1121. X    delta = VEL_X;
  1122. X      else if(mptr->offset.x > GAP_WIDTH)
  1123. X    delta = VEL_X_FAST;
  1124. X      else if(mptr->offset.x > 0)
  1125. X    delta = VEL_X;
  1126. X      else if(mptr->offset.x > - VEL_X_FAST * FAST_STEPS)
  1127. X    delta = VEL_X_FAST;
  1128. X      else if(mptr->offset.x > - CELL_WIDTH + VEL_X_FAST * FAST_STEPS)
  1129. X    delta = VEL_X;
  1130. X      else if(mptr->offset.x > -CELL_WIDTH)
  1131. X    delta = VEL_X_FAST;
  1132. X      else
  1133. X    delta = VEL_X;
  1134. X      mptr->pixel.x -= delta;
  1135. X      mptr->offset.x -= delta;
  1136. X      if(mptr->offset.x == -(CELL_WIDTH + GAP_WIDTH))
  1137. X    {
  1138. X      mptr->offset.x = 0;
  1139. X      mptr->cell.x -= 1;
  1140. X      cptr -= 1;
  1141. X    }
  1142. X      assert(cptr->visit && !mptr->offset.y && mptr->cell.x >= 0);
  1143. X      break;
  1144. X    /*}}}*/
  1145. X    /*{{{  case 3: (right)*/
  1146. X    case 3:
  1147. X      if(!mptr->fast)
  1148. X    delta = VEL_X;
  1149. X      else if(mptr->offset.x < -(CELL_WIDTH + GAP_WIDTH) + VEL_X_FAST * FAST_STEPS)
  1150. X    delta = VEL_X_FAST;
  1151. X      else if(mptr->offset.x < - GAP_WIDTH - VEL_X_FAST * FAST_STEPS)
  1152. X    delta = VEL_X;
  1153. X      else if(mptr->offset.x < -GAP_WIDTH)
  1154. X    delta = VEL_X_FAST;
  1155. X      else if(mptr->offset.x < 0)
  1156. X    delta = VEL_X;
  1157. X      else if(mptr->offset.x < VEL_X_FAST * FAST_STEPS)
  1158. X    delta = VEL_X_FAST;
  1159. X      else if(mptr->offset.x < CELL_WIDTH - VEL_X_FAST * FAST_STEPS)
  1160. X    delta = VEL_X;
  1161. X      else if(mptr->offset.x < CELL_WIDTH)
  1162. X    delta = VEL_X_FAST;
  1163. X      else
  1164. X    delta = VEL_X;
  1165. X      mptr->pixel.x += delta;
  1166. X      mptr->offset.x += delta;
  1167. X      if(mptr->offset.x == CELL_WIDTH + GAP_WIDTH)
  1168. X    {
  1169. X      mptr->offset.x = 0;
  1170. X      mptr->cell.x += 1;
  1171. X      cptr += 1;
  1172. X    }
  1173. X      assert(cptr->visit && !mptr->offset.y && mptr->cell.x < CELLS_ACROSS);
  1174. X      break;
  1175. X    /*}}}*/
  1176. X  }
  1177. X  return cptr;
  1178. }
  1179. /*}}}*/
  1180. /*{{{  CELL *move_muncher(mptr)*/
  1181. extern CELL *move_muncher FUNCARGLIST((mptr))
  1182. MONSTER   *mptr FUNCARGTERM /* the object to move */
  1183. /*
  1184. X * moves and munches the board for an object which can munch
  1185. X * apple checking is performed here too
  1186. X * (ie the man, or a munch monster)
  1187. X * the board array is updated as required
  1188. X * returns a pointer to the new cell, if we have arrived elsewhere
  1189. X * or NULL if we stayed on the same cell
  1190. X */
  1191. {
  1192. X  unsigned  broke;
  1193. X  CELL      *nptr;
  1194. X  CELL      *cherry;
  1195. X  CELL      *cptr;
  1196. X  COORD     pixel;
  1197. X  COORD     cell;
  1198. X  SPRITE    *sptr;
  1199. X  int       knocked;
  1200. X
  1201. X  assert(!mptr->stop && !mptr->pause);
  1202. X  broke = 0;
  1203. X  nptr = NULL;
  1204. X  cherry = NULL;
  1205. X  update.set = 0;
  1206. X  cell.x = mptr->cell.x;
  1207. X  cell.y = mptr->cell.y;
  1208. X  cptr = BOARDCELL(cell.x, cell.y);
  1209. X  pixel.x = PIXELX(cell.x, 0);
  1210. X  pixel.y = PIXELY(cell.y, 0);
  1211. X  knocked = 0;
  1212. X  if(!apple_stop(mptr, cptr))
  1213. X    {
  1214. X      switch(mptr->dir)
  1215. X      {
  1216. X    /*{{{  case 0: (up)*/
  1217. X    case 0:
  1218. X      /*
  1219. X       * if the depth upwards is less than the future depth,
  1220. X       * then we have to do some munching
  1221. X       */
  1222. X      mptr->offset.y -= VEL_Y;
  1223. X      mptr->pixel.y = pixel.y + mptr->offset.y;
  1224. X      if(cptr[0].depths[0] > mptr->offset.y)
  1225. X        /*{{{  munch*/
  1226. X        {
  1227. X          cptr[0].depths[0] = mptr->offset.y;
  1228. X          sptr = &sprites[SPRITE_MUNCH_BASE + 0];
  1229. X          munch_back(0, 0, CELL_WIDTH, MUNCH_HEIGHT >> 1,
  1230. X          pixel.x, pixel.y + cptr->depths[0], sptr);
  1231. X          if(mptr->offset.y == -VEL_Y && cptr[-CELL_STRIDE].visit)
  1232. X        {
  1233. X          sptr = &sprites[SPRITE_EDGE_BASE + 1];
  1234. X          /*{{{  munch the left half of the edge above*/
  1235. X          {
  1236. X            unsigned  type;
  1237. X                            
  1238. X            type = 0;
  1239. X            if(cptr[0].depths[2] < -VEL_X)
  1240. X              type = 2 * GAP_HEIGHT;
  1241. X            if(cptr[-CELL_STRIDE].depths[2] < -VEL_X)
  1242. X              type += GAP_HEIGHT;
  1243. X            if(type == 3 * GAP_HEIGHT &&
  1244. X            (cptr[-1].depths[0] < -VEL_Y ||
  1245. X            cptr[-CELL_STRIDE-1].depths[1] > VEL_Y))
  1246. X              type = 4 * GAP_HEIGHT;
  1247. X            munch_back(0, type,
  1248. X            EDGE_WIDTH >> 1, GAP_HEIGHT,
  1249. X            pixel.x + (CELL_WIDTH >> 1) - (EDGE_WIDTH >> 1),
  1250. X            pixel.y - GAP_HEIGHT, sptr);
  1251. X            if(!cptr[-CELL_STRIDE].depths[2])
  1252. X              munch_back(0, 0, EDGE_WIDTH >> 1, GAP_HEIGHT,
  1253. X              pixel.x + (CELL_WIDTH >> 1) - (EDGE_WIDTH >> 1),
  1254. X              pixel.y - GAP_HEIGHT * 2, sptr);
  1255. X          }
  1256. X          /*}}}*/
  1257. X          /*{{{  munch the right half of the edge above*/
  1258. X          {
  1259. X            unsigned  type;
  1260. X                            
  1261. X            type = 0;
  1262. X            if(cptr[0].depths[3] > VEL_X)
  1263. X              type = 2 * GAP_HEIGHT;
  1264. X            if(cptr[-CELL_STRIDE].depths[3] > VEL_X)
  1265. X              type += GAP_HEIGHT;
  1266. X            if(type == 3 * GAP_HEIGHT &&
  1267. X            (cptr[1].depths[0] < -VEL_Y ||
  1268. X            cptr[-CELL_STRIDE+1].depths[1] > VEL_Y))
  1269. X              type = 4 * GAP_HEIGHT;
  1270. X            munch_back(EDGE_WIDTH >> 1, type,
  1271. X            EDGE_WIDTH >> 1, GAP_HEIGHT,
  1272. X            pixel.x + (CELL_WIDTH >> 1),
  1273. X            pixel.y - GAP_HEIGHT, sptr);
  1274. X            if(!cptr[-CELL_STRIDE].depths[3])
  1275. X              munch_back(EDGE_WIDTH >> 1, 0,
  1276. X              EDGE_WIDTH >> 1, GAP_HEIGHT,
  1277. X              pixel.x + (CELL_WIDTH >> 1),
  1278. X              pixel.y - GAP_HEIGHT * 2, sptr);
  1279. X          }
  1280. X          /*}}}*/
  1281. X          cptr[0].depths[0] = -(CELL_HEIGHT + GAP_HEIGHT);
  1282. X          cptr[-CELL_STRIDE].depths[1] = CELL_HEIGHT + GAP_HEIGHT;
  1283. X          broke = 1;
  1284. X        }
  1285. X          else
  1286. X        {
  1287. X          if(mptr->offset.y == -(VEL_Y * 2))
  1288. X            {
  1289. X              sptr = &sprites[SPRITE_EDGE_BASE + 1];
  1290. X              /*{{{  round top left corner?*/
  1291. X              if(cptr[0].depths[2] < -VEL_X)
  1292. X            munch_back(0, 2 * GAP_HEIGHT,
  1293. X                EDGE_WIDTH >> 1, GAP_HEIGHT,
  1294. X                pixel.x + (CELL_WIDTH >> 1) - (EDGE_WIDTH >> 1),
  1295. X                pixel.y - GAP_HEIGHT, sptr);
  1296. X              /*}}}*/
  1297. X              /*{{{  round top right corner?*/
  1298. X              if(cptr[0].depths[3] > VEL_X)
  1299. X            munch_back(EDGE_WIDTH >> 1, 2 * GAP_HEIGHT,
  1300. X                EDGE_WIDTH >> 1, GAP_HEIGHT,
  1301. X                pixel.x + (CELL_WIDTH >> 1),
  1302. X                pixel.y - GAP_HEIGHT, sptr);
  1303. X              /*}}}*/
  1304. X            }
  1305. X          /*{{{  knocked through?*/
  1306. X          /*
  1307. X           * have we bumped into any of the following ?
  1308. X           * path from 2 above me
  1309. X           * path from above left
  1310. X           * path from above right
  1311. X           */
  1312. X          if((cptr[-CELL_STRIDE*2].depths[1] - cptr[0].depths[0] >=
  1313. X              CELL_HEIGHT + GAP_HEIGHT * 2) ||
  1314. X              (cptr[-CELL_STRIDE-1].depths[3] &&
  1315. X            cptr[-CELL_STRIDE-1].depths[3] - cptr[0].depths[0] >=
  1316. X            KNOCK_THROUGH) ||
  1317. X              (cptr[-CELL_STRIDE+1].depths[2] &&
  1318. X            cptr[-CELL_STRIDE+1].depths[2] + cptr[0].depths[0] <=
  1319. X            -KNOCK_THROUGH))
  1320. X            {
  1321. X              knocked = -CELL_STRIDE;
  1322. X              pixel.y -= CELL_HEIGHT + GAP_HEIGHT;
  1323. X              cell.y -= 1;
  1324. X            }
  1325. X          else
  1326. X            {
  1327. X              if(cptr->depths[0] == -(CELL_HEIGHT + GAP_HEIGHT))
  1328. X            {
  1329. X              cptr[-CELL_STRIDE].visit = 1;
  1330. X              cptr[-CELL_STRIDE].depths[1] =
  1331. X                  CELL_HEIGHT + GAP_HEIGHT;
  1332. X            }
  1333. X              cherry = cptr - CELL_STRIDE;
  1334. X              pixel.y -= CELL_HEIGHT + GAP_HEIGHT;
  1335. X            }
  1336. X          /*}}}*/
  1337. X        }
  1338. X        }
  1339. X        /*}}}*/
  1340. X      else if(mptr->offset.y < -VEL_Y)
  1341. X        {
  1342. X          cherry = cptr - CELL_STRIDE;
  1343. X          pixel.y -= CELL_HEIGHT + GAP_HEIGHT;
  1344. X        }
  1345. X      if(mptr->offset.y == -(CELL_HEIGHT + GAP_HEIGHT))
  1346. X        {
  1347. X          mptr->offset.y = 0;
  1348. X          mptr->cell.y--;
  1349. X          nptr = cptr - CELL_STRIDE;
  1350. X        }
  1351. X      break;
  1352. X    /*}}}*/
  1353. X    /*{{{  case 1: (down)*/
  1354. X    case 1:
  1355. X    {
  1356. X      mptr->offset.y += VEL_Y;
  1357. X      mptr->pixel.y = pixel.y + mptr->offset.y;
  1358. X      if(cptr->depths[1] < mptr->offset.y)
  1359. X        /*{{{  munch*/
  1360. X        {
  1361. X          cptr->depths[1] = mptr->offset.y;
  1362. X          sptr = &sprites[SPRITE_MUNCH_BASE + 0];
  1363. X          munch_back(0, MUNCH_HEIGHT >> 1,
  1364. X          CELL_WIDTH, MUNCH_HEIGHT >> 1,
  1365. X          pixel.x, pixel.y + cptr[0].depths[1] +
  1366. X          CELL_HEIGHT - (MUNCH_HEIGHT >> 1), sptr);
  1367. X          if(mptr->offset.y == VEL_Y && cptr[CELL_STRIDE].visit)
  1368. X        {
  1369. X          sptr = &sprites[SPRITE_EDGE_BASE + 1];
  1370. X          /*{{{  munch the left half of the edge below*/
  1371. X          {
  1372. X            unsigned  type;
  1373. X                            
  1374. X            type = 0;
  1375. X            if(cptr[0].depths[2] < -VEL_X)
  1376. X              type = GAP_HEIGHT;
  1377. X            if(cptr[CELL_STRIDE].depths[2] < -VEL_X)
  1378. X              type += 2 * GAP_HEIGHT;
  1379. X            if(type == 3 * GAP_HEIGHT &&
  1380. X            (cptr[-1].depths[1] > VEL_Y ||
  1381. X            cptr[CELL_STRIDE-1].depths[0] < -VEL_Y))
  1382. X              type = 4 * GAP_HEIGHT;
  1383. X            munch_back(0, type,
  1384. X            EDGE_WIDTH >> 1, GAP_HEIGHT,
  1385. X            pixel.x + (CELL_WIDTH >> 1) - (EDGE_WIDTH >> 1),
  1386. X            pixel.y + CELL_HEIGHT, sptr);
  1387. X            if(!cptr[CELL_STRIDE].depths[2])
  1388. X              munch_back(0, 0, EDGE_WIDTH >> 1, GAP_HEIGHT,
  1389. X              pixel.x + (CELL_WIDTH >> 1) - (EDGE_WIDTH >> 1),
  1390. X              pixel.y + CELL_HEIGHT + GAP_HEIGHT, sptr);
  1391. X          }
  1392. X          /*}}}*/
  1393. X          /*{{{  munch the right half of the edge below*/
  1394. X          {
  1395. X            unsigned  type;
  1396. X                            
  1397. X            type = 0;
  1398. X            if(cptr[0].depths[3] > VEL_X)
  1399. X              type = GAP_HEIGHT;
  1400. X            if(cptr[CELL_STRIDE].depths[3] > VEL_X)
  1401. X              type += 2 * GAP_HEIGHT;
  1402. X            if(type == 3 * GAP_HEIGHT &&
  1403. X            (cptr[1].depths[1] > VEL_Y ||
  1404. X            cptr[CELL_STRIDE+1].depths[0] < -VEL_Y))
  1405. X              type = 4 * GAP_HEIGHT;
  1406. X            munch_back(EDGE_WIDTH >> 1, type,
  1407. X            EDGE_WIDTH >> 1, GAP_HEIGHT,
  1408. X            pixel.x + (CELL_WIDTH >> 1),
  1409. X            pixel.y + CELL_HEIGHT, sptr);
  1410. X            if(!cptr[CELL_STRIDE].depths[3])
  1411. X              munch_back(EDGE_WIDTH >> 1, 0,
  1412. X              EDGE_WIDTH >> 1, GAP_HEIGHT,
  1413. X              pixel.x + (CELL_WIDTH >> 1),
  1414. X              pixel.y + CELL_HEIGHT + GAP_HEIGHT, sptr);
  1415. X          }
  1416. X          /*}}}*/
  1417. X          cptr[0].depths[1] = CELL_HEIGHT + GAP_HEIGHT;
  1418. X          cptr[CELL_STRIDE].depths[0] = -(CELL_HEIGHT + GAP_HEIGHT);
  1419. X          broke = 1;
  1420. X        }
  1421. X          else
  1422. X        {
  1423. X          if(mptr->offset.y == (VEL_Y * 2))
  1424. X            {
  1425. X              sptr = &sprites[SPRITE_EDGE_BASE + 1];
  1426. X              /*{{{  round bottom left corner?*/
  1427. X              if(cptr[0].depths[2] < -VEL_X)
  1428. X            munch_back(0, GAP_HEIGHT,
  1429. X                EDGE_WIDTH >> 1, GAP_HEIGHT,
  1430. X                pixel.x + (CELL_WIDTH >> 1) - (EDGE_WIDTH >> 1),
  1431. X                pixel.y + CELL_HEIGHT, sptr);
  1432. X              /*}}}*/
  1433. X              /*{{{  round bottom right corner?*/
  1434. X              if(cptr[0].depths[3] > VEL_X)
  1435. X            munch_back(EDGE_WIDTH >> 1, GAP_HEIGHT,
  1436. X                EDGE_WIDTH >> 1, GAP_HEIGHT,
  1437. X                pixel.x + (CELL_WIDTH >> 1),
  1438. X                pixel.y + CELL_HEIGHT, sptr);
  1439. X              /*}}}*/
  1440. X            }
  1441. X          /*{{{  knocked through?*/
  1442. X          /*
  1443. X           * have we bumped into any of the following ?
  1444. X           * path from 2 below me
  1445. X           * path from below left
  1446. X           * path from below right
  1447. X           */
  1448. X          if((cptr[0].depths[1] - cptr[CELL_STRIDE*2].depths[0] >=
  1449. X              CELL_HEIGHT + GAP_HEIGHT * 2) ||
  1450. X              (cptr[CELL_STRIDE-1].depths[3] &&
  1451. X            cptr[CELL_STRIDE-1].depths[3] + cptr[0].depths[1] >=
  1452. X            KNOCK_THROUGH) ||
  1453. X              (cptr[CELL_STRIDE+1].depths[2] &&
  1454. X            cptr[0].depths[1] - cptr[CELL_STRIDE+1].depths[2] >=
  1455. X            KNOCK_THROUGH))
  1456. X            {
  1457. X              knocked = CELL_STRIDE;
  1458. X              pixel.y += CELL_HEIGHT + GAP_HEIGHT;
  1459. X              cell.y += 1;
  1460. X            }
  1461. X          else
  1462. X            {
  1463. X              if(cptr->depths[1] == (CELL_HEIGHT + GAP_HEIGHT))
  1464. X            {
  1465. X              cptr[CELL_STRIDE].visit = 1;
  1466. X              cptr[CELL_STRIDE].depths[0] =
  1467. X                  -(CELL_HEIGHT + GAP_HEIGHT);
  1468. X            }
  1469. X              cherry = cptr + CELL_STRIDE;
  1470. X              pixel.y += CELL_HEIGHT + GAP_HEIGHT;
  1471. X            }
  1472. X          /*}}}*/
  1473. X        }
  1474. X        }
  1475. X        /*}}}*/
  1476. X      else if(mptr->offset.y > VEL_Y)
  1477. X        {
  1478. X          cherry = cptr + CELL_STRIDE;
  1479. X          pixel.y += CELL_HEIGHT + GAP_HEIGHT;
  1480. X        }
  1481. X      if(mptr->offset.y == (CELL_HEIGHT + GAP_HEIGHT))
  1482. X        {
  1483. X          mptr->offset.y = 0;
  1484. X          mptr->cell.y++;
  1485. X          nptr = cptr + CELL_STRIDE;
  1486. X        }
  1487. X      break;
  1488. X    }
  1489. X    /*}}}*/
  1490. X    /*{{{  case 2: (left)*/
  1491. X    case 2:
  1492. X    {
  1493. X      mptr->offset.x -= VEL_X;
  1494. X      mptr->pixel.x = pixel.x + mptr->offset.x;
  1495. X      if(cptr[0].depths[2] > mptr->offset.x)
  1496. X        /*{{{  munch*/
  1497. X        {
  1498. X          cptr[0].depths[2] = mptr->offset.x;
  1499. X          sptr = &sprites[SPRITE_MUNCH_BASE + 1];
  1500. X          munch_back(0, 0, MUNCH_WIDTH >> 1, CELL_HEIGHT,
  1501. X          pixel.x + cptr[0].depths[2], pixel.y, sptr);
  1502. X          if(mptr->offset.x == -VEL_X && cptr[-1].visit)
  1503. X        {
  1504. X          sptr = &sprites[SPRITE_EDGE_BASE + 0];
  1505. X          /*{{{  munch the top half of the edge left*/
  1506. X          {
  1507. X            unsigned  type;
  1508. X                            
  1509. X            type = 0;
  1510. X            if(cptr[0].depths[0] < -VEL_Y)
  1511. X              type = 2 * GAP_WIDTH;
  1512. X            if(cptr[-1].depths[0] < -VEL_Y)
  1513. X              type += GAP_WIDTH;
  1514. X            if(type == 3 * GAP_WIDTH &&
  1515. X            (cptr[-CELL_STRIDE].depths[2] < -VEL_X ||
  1516. X            cptr[-CELL_STRIDE-1].depths[3] > VEL_X))
  1517. X              type = 4 * GAP_WIDTH;
  1518. X            munch_back(type, 0,
  1519. X            GAP_HEIGHT, EDGE_HEIGHT >> 1,
  1520. X            pixel.x - GAP_WIDTH,
  1521. X            pixel.y + (CELL_HEIGHT >> 1) - (EDGE_HEIGHT >> 1),
  1522. X            sptr);
  1523. X            if(!cptr[-1].depths[0])
  1524. X              munch_back(0, 0, GAP_WIDTH, EDGE_HEIGHT >> 1,
  1525. X              pixel.x - GAP_WIDTH * 2,
  1526. X              pixel.y + (CELL_HEIGHT >> 1) - (EDGE_HEIGHT >> 1),
  1527. X              sptr);
  1528. X          }
  1529. X          /*}}}*/
  1530. X          /*{{{  munch the bottom half of the edge left*/
  1531. X          {
  1532. X            unsigned  type;
  1533. X                            
  1534. X            type = 0;
  1535. X            if(cptr[0].depths[1] > VEL_Y)
  1536. X              type = 2 * GAP_WIDTH;
  1537. X            if(cptr[-1].depths[1] > VEL_Y)
  1538. X              type += GAP_WIDTH;
  1539. X            if(type == 3 * GAP_WIDTH &&
  1540. X            (cptr[CELL_STRIDE].depths[2] < -VEL_X ||
  1541. X            cptr[CELL_STRIDE-1].depths[3] > VEL_X))
  1542. X              type = 4 * GAP_WIDTH;
  1543. X            munch_back(type, EDGE_HEIGHT >> 1,
  1544. X            GAP_WIDTH, EDGE_HEIGHT >> 1,
  1545. X            pixel.x - GAP_WIDTH,
  1546. X            pixel.y + (CELL_HEIGHT >> 1), sptr);
  1547. X            if(!cptr[-1].depths[1])
  1548. X              munch_back(0, EDGE_HEIGHT >> 1,
  1549. X              GAP_WIDTH, EDGE_HEIGHT >> 1,
  1550. X              pixel.x - GAP_WIDTH * 2,
  1551. X              pixel.y + (CELL_HEIGHT >> 1), sptr);
  1552. X          }
  1553. X          /*}}}*/
  1554. X          cptr[0].depths[2] = -(CELL_WIDTH + GAP_WIDTH);
  1555. X          cptr[-1].depths[3] = CELL_WIDTH + GAP_WIDTH;
  1556. X          broke = 1;
  1557. X        }
  1558. X          else
  1559. X        {
  1560. X          if(mptr->offset.x == -(VEL_X * 2))
  1561. X            {
  1562. X              sptr = &sprites[SPRITE_EDGE_BASE + 0];
  1563. X              /*{{{  round left top corner?*/
  1564. X              if(cptr[0].depths[0] < -VEL_Y)
  1565. X            munch_back(2 * GAP_WIDTH, 0,
  1566. X                GAP_WIDTH, EDGE_HEIGHT >> 1,
  1567. X                pixel.x - GAP_WIDTH,
  1568. X                pixel.y + (CELL_HEIGHT >> 1) - (EDGE_HEIGHT >> 1),
  1569. X                sptr);
  1570. X              /*}}}*/
  1571. X              /*{{{  round left bottom corner?*/
  1572. X              if(cptr[0].depths[1] > VEL_Y)
  1573. X            munch_back(2 * GAP_HEIGHT, EDGE_HEIGHT >> 1,
  1574. X                GAP_WIDTH, EDGE_HEIGHT >> 1,
  1575. X                pixel.x - GAP_WIDTH,
  1576. X                pixel.y + (CELL_HEIGHT >> 1), sptr);
  1577. X              /*}}}*/
  1578. X            }
  1579. X          /*{{{  knocked through?*/
  1580. X          /*
  1581. X           * have we bumped into any of the following ?
  1582. X           * path from 2 left me
  1583. X           * path from left above
  1584. X           * path from left below
  1585. X           */
  1586. X          if((cptr[-2].depths[3] - cptr[0].depths[2] >=
  1587. X              CELL_WIDTH + GAP_WIDTH * 2) ||
  1588. X              (cptr[-CELL_STRIDE-1].depths[1] &&
  1589. X            cptr[-CELL_STRIDE-1].depths[1] - cptr[0].depths[2] >=
  1590. X            KNOCK_THROUGH) ||
  1591. X              (cptr[CELL_STRIDE-1].depths[0] &&
  1592. X            cptr[CELL_STRIDE-1].depths[0] + cptr[0].depths[2] <=
  1593. X            -KNOCK_THROUGH))
  1594. X            {
  1595. X              knocked = -1;
  1596. X              pixel.x -= CELL_WIDTH + GAP_WIDTH;
  1597. X              cell.x -= 1;
  1598. X            }
  1599. X          else
  1600. X            {
  1601. X              if(cptr->depths[2] == -(CELL_WIDTH + GAP_WIDTH))
  1602. X            {
  1603. X              cptr[-1].visit = 1;
  1604. X              cptr[-1].depths[3] = CELL_WIDTH + GAP_WIDTH;
  1605. X            }
  1606. X              cherry = cptr - 1;
  1607. X              pixel.x -= CELL_WIDTH + GAP_WIDTH;
  1608. X            }
  1609. X          /*}}}*/
  1610. X        }
  1611. X        }
  1612. X        /*}}}*/
  1613. X      else if(mptr->offset.x < -VEL_X)
  1614. X        {
  1615. X          cherry = cptr - 1;
  1616. X          pixel.x -= CELL_WIDTH + GAP_WIDTH;
  1617. X        }
  1618. X      if(mptr->offset.x == -(CELL_WIDTH + GAP_WIDTH))
  1619. X        {
  1620. X          mptr->offset.x = 0;
  1621. X          mptr->cell.x--;
  1622. X          nptr = cptr - 1;
  1623. X        }
  1624. X      break;
  1625. X    }
  1626. X    /*}}}*/
  1627. X    /*{{{  case 3: (right)*/
  1628. X    case 3:
  1629. X    {
  1630. X      mptr->offset.x += VEL_X;
  1631. X      mptr->pixel.x = pixel.x + mptr->offset.x;
  1632. X      if(cptr->depths[3] < mptr->offset.x)
  1633. X        /*{{{  munch*/
  1634. X        {
  1635. X          cptr->depths[3] = mptr->offset.x;
  1636. X          sptr = &sprites[SPRITE_MUNCH_BASE + 1];
  1637. X          munch_back(MUNCH_WIDTH >> 1, 0,
  1638. X          MUNCH_WIDTH >> 1, CELL_HEIGHT,
  1639. X          pixel.x + cptr->depths[3] +
  1640. X          CELL_HEIGHT - (MUNCH_WIDTH >> 1), pixel.y, sptr);
  1641. X          if(mptr->offset.x == VEL_X && cptr[1].visit)
  1642. X        {
  1643. X          sptr = &sprites[SPRITE_EDGE_BASE + 0];
  1644. X          /*{{{  munch the top half of the edge right*/
  1645. X          {
  1646. X            unsigned  type;
  1647. X                            
  1648. X            type = 0;
  1649. X            if(cptr[0].depths[0] < -VEL_Y)
  1650. X              type = GAP_WIDTH;
  1651. X            if(cptr[1].depths[0] < -VEL_Y)
  1652. X              type += 2 * GAP_WIDTH;
  1653. X            if(type == 3 * GAP_WIDTH &&
  1654. X              (cptr[-CELL_STRIDE].depths[3] > VEL_X ||
  1655. X            cptr[-CELL_STRIDE+1].depths[2] < -VEL_X))
  1656. X              type = 4 * GAP_WIDTH;
  1657. X            munch_back(type, 0,
  1658. X            GAP_WIDTH, EDGE_HEIGHT >> 1,
  1659. X            pixel.x + CELL_WIDTH, pixel.y +
  1660. X            (CELL_HEIGHT >> 1) - (EDGE_HEIGHT >> 1), sptr);
  1661. X            if(!cptr[1].depths[0])
  1662. X              munch_back(0, 0, GAP_WIDTH, EDGE_HEIGHT >> 1,
  1663. X              pixel.x + CELL_WIDTH + GAP_WIDTH, pixel.y +
  1664. X              (CELL_HEIGHT >> 1) - (EDGE_HEIGHT >> 1), sptr);
  1665. X          }
  1666. X          /*}}}*/
  1667. X          /*{{{  munch the bottom half of the edge right*/
  1668. X          {
  1669. X            unsigned  type;
  1670. X                            
  1671. X            type = 0;
  1672. X            if(cptr[0].depths[1] > VEL_Y)
  1673. X              type = GAP_WIDTH;
  1674. X            if(cptr[1].depths[1] > VEL_Y)
  1675. X              type += 2 * GAP_WIDTH;
  1676. X            if(type == 3 * GAP_WIDTH &&
  1677. X            (cptr[CELL_STRIDE].depths[3] > VEL_X ||
  1678. X            cptr[CELL_STRIDE+1].depths[2] < -VEL_X))
  1679. X              type = 4 * GAP_WIDTH;
  1680. X            munch_back(type, EDGE_HEIGHT >> 1,
  1681. X            GAP_WIDTH, EDGE_HEIGHT >> 1,
  1682. X            pixel.x + CELL_WIDTH,
  1683. X            pixel.y + (CELL_HEIGHT >> 1), sptr);
  1684. X            if(!cptr[1].depths[1])
  1685. X              munch_back(0, EDGE_HEIGHT >> 1,
  1686. X              GAP_WIDTH, EDGE_HEIGHT >> 1,
  1687. X              pixel.x + CELL_WIDTH + GAP_WIDTH,
  1688. X              pixel.y + (CELL_HEIGHT >> 1), sptr);
  1689. X          }
  1690. X          /*}}}*/
  1691. X          cptr[0].depths[3] = CELL_WIDTH + GAP_WIDTH;
  1692. X          cptr[1].depths[2] = -(CELL_WIDTH + GAP_WIDTH);
  1693. X          broke = 1;
  1694. X        }
  1695. X          else
  1696. X        {
  1697. X          if(mptr->offset.x == (VEL_X * 2))
  1698. X            {
  1699. X              sptr = &sprites[SPRITE_EDGE_BASE + 0];
  1700. X              /*{{{  round right top corner?*/
  1701. X              if(cptr[0].depths[0] < -VEL_Y)
  1702. X            munch_back(GAP_HEIGHT, 0,
  1703. X                GAP_WIDTH, EDGE_HEIGHT >> 1,
  1704. X                pixel.x + CELL_WIDTH, pixel.y +
  1705. X                (CELL_HEIGHT >> 1) - (EDGE_HEIGHT >> 1), sptr);
  1706. X              /*}}}*/
  1707. X              /*{{{  round right bottom corner?*/
  1708. X              if(cptr[0].depths[1] > VEL_Y)
  1709. X            munch_back(GAP_WIDTH, EDGE_HEIGHT >> 1,
  1710. X                GAP_WIDTH, EDGE_HEIGHT >> 1,
  1711. X                pixel.x + CELL_WIDTH, pixel.y +
  1712. X                (CELL_HEIGHT >> 1), sptr);
  1713. X              /*}}}*/
  1714. X            }
  1715. X          /*{{{  knocked through?*/
  1716. X          /*
  1717. X           * have we bumped into any of the following ?
  1718. X           * path from 2 right me
  1719. X           * path from right above
  1720. X           * path from right below
  1721. X           */
  1722. X          if((cptr[0].depths[3] - cptr[2].depths[2] >=
  1723. X              CELL_WIDTH + GAP_WIDTH * 2) ||
  1724. X              (cptr[-CELL_STRIDE+1].depths[1] &&
  1725. X            cptr[-CELL_STRIDE+1].depths[1] + cptr[0].depths[3] >=
  1726. X            KNOCK_THROUGH) ||
  1727. X              (cptr[CELL_STRIDE+1].depths[0] &&
  1728. X            cptr[0].depths[3] - cptr[CELL_STRIDE+1].depths[0] >=
  1729. X            KNOCK_THROUGH))
  1730. X            {
  1731. X              knocked = 1;
  1732. X              pixel.x += CELL_WIDTH + GAP_WIDTH;
  1733. X              cell.x += 1;
  1734. X            }
  1735. X          else
  1736. X            {
  1737. X              if(cptr->depths[3] == (CELL_WIDTH + GAP_WIDTH))
  1738. X            {
  1739. X              cptr[1].visit = 1;
  1740. X              cptr[1].depths[2] = -(CELL_WIDTH + GAP_WIDTH);
  1741. X            }
  1742. X              cherry = cptr + 1;
  1743. X              pixel.x += CELL_WIDTH + GAP_WIDTH;
  1744. X            }
  1745. X          /*}}}*/
  1746. X        }
  1747. X        }
  1748. X        /*}}}*/
  1749. X      else if(mptr->offset.x > VEL_X)
  1750. X        {
  1751. X          cherry = cptr + 1;
  1752. X          pixel.x += CELL_WIDTH + GAP_WIDTH;
  1753. X        }
  1754. X      if(mptr->offset.x == (CELL_WIDTH + GAP_WIDTH))
  1755. X        {
  1756. X          mptr->offset.x = 0;
  1757. X          mptr->cell.x++;
  1758. X          nptr = cptr + 1;
  1759. X        }
  1760. X      break;
  1761. X    }
  1762. X    /*}}}*/
  1763. X      }
  1764. X      apple_under(mptr, nptr ? nptr : cptr);
  1765. X    }
  1766. X  /*{{{  knocked through?*/
  1767. X  /*
  1768. X   * if we knocked through to an adjoining cell
  1769. X   * we clear out the specified cell and check all the corners
  1770. X   * note, cell has already been altered correctly
  1771. X   * we must also check to se if this launches an apple
  1772. X   */
  1773. X  if(knocked)
  1774. X    {
  1775. X      unsigned  i;
  1776. X      APPLE     *aptr;
  1777. X    
  1778. X      broke = 1;
  1779. X      cherry = cptr += knocked;
  1780. X      cptr[0].visit = 1;
  1781. X      /*{{{  alter the depths*/
  1782. X      {
  1783. X    if(cptr[-CELL_STRIDE].depths[1])
  1784. X      {
  1785. X        cptr[0].depths[0] = -(CELL_HEIGHT + GAP_HEIGHT);
  1786. SHAR_EOF
  1787. true || echo 'restore of move.c failed'
  1788. fi
  1789. echo 'End of  part 4'
  1790. echo 'File move.c is continued in part 5'
  1791. echo 5 > _shar_seq_.tmp
  1792. exit 0
  1793. -- 
  1794. ---
  1795. Senior Systems Scientist        mail: dcmartin@msi.com
  1796. Molecular Simulations, Inc.        uucp: uunet!dcmartin
  1797. 796 North Pastoria Avenue        at&t: 408/522-9236
  1798.