1 // ----------------------------------------------------------------------------
2 // SnikSnaks.c
3 // ----------------------------------------------------------------------------
4
5 #include "SnikSnaks.h"
6
7
8 static void subDrawSnikSnakFromAbove(int, int);
9 static void subDrawSnikSnakFromBelow(int, int);
10 static void subDrawSnikSnakFromLeft(int, int);
11 static void subDrawSnikSnakFromRight(int, int);
12 static void subDrawSnikSnakTurnLeft(int, int);
13 static void subDrawSnikSnakTurnRight(int, int);
14 static void subSnikSnakFromAbove(int, int);
15 static void subSnikSnakFromBelow(int, int);
16 static void subSnikSnakFromLeft(int, int);
17 static void subSnikSnakFromRight(int, int);
18 static void subSnikSnakTurnLeft(int, int);
19 static void subSnikSnakTurnRight(int, int);
20
21 // static char *VB_Name = "modSnikSnak";
22
23 // --- Option Explicit
24 // ==========================================================================
25 // SUBROUTINE
26 // Animate/move Snik-Snaks
27 // ==========================================================================
28
subAnimateSnikSnaks(int si)29 void subAnimateSnikSnaks(int si)
30 {
31 int bx, Tmp;
32
33 if (SnikSnaksElectronsFrozen == 1)
34 return;
35
36 #if 1
37 /* (not sure why this was removed -- this broke several level solutions) */
38 if (LowByte(PlayField16[si]) != fiSnikSnak)
39 return;
40 #endif
41
42 // If LowByte(PlayField16(si)) <> fiSnikSnak Then Exit Function
43 // Debug.Assert (LowByte(PlayField16[si]) == fiSnikSnak);
44
45 bx = HighByte(PlayField16[si]);
46 Tmp = bx / 8;
47 switch (Tmp)
48 {
49 case 0:
50 subSnikSnakTurnLeft(si, bx); // turning, bx=0 -> point N, bx = 1 -> point NW etc.
51 break;
52
53 case 1:
54 subSnikSnakTurnRight(si, bx); // turn right
55 break;
56
57 case 2:
58 subSnikSnakFromBelow(si, bx); // access si from below
59 break;
60
61 case 3:
62 subSnikSnakFromRight(si, bx); // access si from right
63 break;
64
65 case 4:
66 subSnikSnakFromAbove(si, bx); // access si from above
67 break;
68
69 case 5:
70 subSnikSnakFromLeft(si, bx); // access si from left
71 break;
72
73 default:
74 // Debug.Assert(False);
75 break;
76 }
77 }
78
subDrawAnimatedSnikSnaks(int si)79 void subDrawAnimatedSnikSnaks(int si)
80 {
81 int bx, Tmp;
82
83 // If SnikSnaksElectronsFrozen = 1 Then Exit Function
84
85 if (LowByte(PlayField16[si]) != fiSnikSnak)
86 return;
87
88 bx = HighByte(PlayField16[si]);
89 Tmp = bx / 8;
90 switch (Tmp)
91 {
92 case 0:
93 subDrawSnikSnakTurnLeft(si, bx); // turning, bx=0 -> point N, bx = 1 -> point NW etc.
94 break;
95
96 case 1:
97 subDrawSnikSnakTurnRight(si, bx); // turn right
98 break;
99
100 case 2:
101 subDrawSnikSnakFromBelow(si, bx); // access si from below
102 break;
103
104 case 3:
105 subDrawSnikSnakFromRight(si, bx); // access si from right
106 break;
107
108 case 4:
109 subDrawSnikSnakFromAbove(si, bx); // access si from above
110 break;
111
112 case 5:
113 subDrawSnikSnakFromLeft(si, bx); // access si from left
114 break;
115 }
116 }
117
subSnikSnakTurnLeft(int si,int bx)118 static void subSnikSnakTurnLeft(int si, int bx)
119 {
120 int ax, ah, bl;
121
122 ax = (TimerVar & 3);
123 if (ax != 0)
124 {
125 if (ax == 3)
126 goto loc_g_7622;
127
128 return;
129 } // loc_g_75E0:
130
131 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
132 subDrawSnikSnakTurnLeft(si, bx);
133 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
134
135 bx = (bx + 1) & 0x7;
136 MovHighByte(&PlayField16[si], bx);
137
138 return;
139
140 locMayExplode760A:
141 ah = HighByte(ax);
142 if (ah == 0x1B)
143 return;
144
145 if (ah == 0x19)
146 return;
147
148 if (ah == 0x18)
149 return;
150
151 if (ah == 0x1A)
152 return;
153
154 ExplodeFieldSP(si); // Explode
155
156 return;
157
158 loc_g_7622:
159 bl = HighByte(PlayField16[si]);
160 if (bl == 0)
161 goto loc_g_763B;
162
163 if (bl == 2)
164 goto loc_g_765E;
165
166 if (bl == 4)
167 goto loc_g_7681;
168
169 if (bl == 6)
170 goto loc_g_76A7;
171
172 return;
173
174 loc_g_763B: // pointing up
175 ax = PlayField16[si - FieldWidth];
176 if (ax == 0) // above is empty -> go up
177 goto loc_g_764E;
178
179 if (LowByte(ax) == fiMurphy) // above is murphy -> explode
180 goto locMayExplode760A;
181
182 return;
183
184 loc_g_764E: // above is empty -> go up
185 PlayField16[si] = 0x1BB;
186 si = si - FieldWidth;
187 PlayField16[si] = 0x1011;
188
189 return;
190
191 loc_g_765E: // pointing left
192 ax = PlayField16[si - 1];
193 if (ax == 0) // left is empty -> go there
194 goto loc_g_7671;
195
196 if (LowByte(ax) == fiMurphy) // left is murphy -> explode
197 goto locMayExplode760A;
198
199 return;
200
201 loc_g_7671: // left is empty -> go there
202 PlayField16[si] = 0x2BB;
203 si = si - 1;
204 PlayField16[si] = 0x1811;
205
206 return;
207
208 loc_g_7681: // pointing down
209 ax = PlayField16[si + FieldWidth];
210 if (ax == 0) // below is empty -> go down
211 goto loc_g_7697;
212
213 if (LowByte(ax) == fiMurphy) // below is murphy -> explode
214 goto locMayExplode760A;
215
216 return;
217
218 loc_g_7697: // below is empty -> go down
219 PlayField16[si] = 0x3BB;
220 si = si + FieldWidth;
221 PlayField16[si] = 0x2011;
222
223 return;
224
225 loc_g_76A7: // pointing Right
226 ax = PlayField16[si + 1];
227 if (ax == 0) // right is empty -> go there
228 goto loc_g_76BD;
229
230 if (LowByte(ax) == fiMurphy) // right is murphy -> explode
231 goto locMayExplode760A;
232
233 return;
234
235 loc_g_76BD: // right is empty -> go there
236 PlayField16[si] = 0x4BB;
237 si = si + 1;
238 PlayField16[si] = 0x2811;
239 }
240
subSnikSnakTurnRight(int si,int bx)241 static void subSnikSnakTurnRight(int si, int bx)
242 {
243 int ax, ah, bl;
244
245 ax = (TimerVar & 3);
246 if (ax != 0)
247 {
248 if (ax == 3)
249 goto loc_g_771F;
250
251 return;
252 } // loc_g_76DB:
253
254 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
255 subDrawSnikSnakTurnRight(si, bx);
256 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
257
258 bx = ((bx + 1) & 0x7) | 8;
259 MovHighByte(&PlayField16[si], bx);
260
261 return;
262
263 locMayExplode7707:
264 ah = HighByte(ax);
265 if (ah == 0x1B)
266 return;
267
268 if (ah == 0x19)
269 return;
270
271 if (ah == 0x18)
272 return;
273
274 if (ah == 0x1A)
275 return;
276
277 ExplodeFieldSP(si); // Explode
278
279 return;
280
281 loc_g_771F:
282 bl = HighByte(PlayField16[si]);
283 if (bl == 0x8)
284 goto loc_g_7738;
285
286 if (bl == 0xA)
287 goto loc_g_77A4;
288
289 if (bl == 0xC)
290 goto loc_g_777E;
291
292 if (bl == 0xE)
293 goto loc_g_775B;
294
295 return;
296
297 loc_g_7738: // pointing up
298 ax = PlayField16[si - FieldWidth];
299 if (ax == 0) // above is empty -> go up
300 goto loc_g_774B;
301
302 if (LowByte(ax) == fiMurphy) // above is murphy -> explode
303 goto locMayExplode7707;
304
305 return;
306
307 loc_g_774B: // above is empty -> go up
308 PlayField16[si] = 0x1BB;
309 si = si - FieldWidth;
310 PlayField16[si] = 0x1011;
311
312 return;
313
314 loc_g_775B: // pointing left
315 ax = PlayField16[si - 1];
316 if (ax == 0) // left is empty -> go there
317 goto loc_g_776E;
318
319 if (LowByte(ax) == fiMurphy) // left is murphy -> explode
320 goto locMayExplode7707;
321
322 return;
323
324 loc_g_776E: // left is empty -> go there
325 PlayField16[si] = 0x2BB;
326 si = si - 1;
327 PlayField16[si] = 0x1811;
328
329 return;
330
331 loc_g_777E: // pointing down
332 ax = PlayField16[si + FieldWidth];
333 if (ax == 0) // below is empty -> go down
334 goto loc_g_7794;
335
336 if (LowByte(ax) == fiMurphy) // below is murphy -> explode
337 goto locMayExplode7707;
338
339 return;
340
341 loc_g_7794: // below is empty -> go down
342 PlayField16[si] = 0x3BB;
343 si = si + FieldWidth;
344 PlayField16[si] = 0x2011;
345
346 return;
347
348 loc_g_77A4: // pointing Right
349 ax = PlayField16[si + 1];
350 if (ax == 0) // right is empty -> go there
351 goto loc_g_77BA;
352
353 if (LowByte(ax) == fiMurphy) // right is murphy -> explode
354 goto locMayExplode7707;
355
356 return;
357
358 loc_g_77BA: // right is empty -> go there
359 PlayField16[si] = 0x4BB;
360 si = si + 1;
361 PlayField16[si] = 0x2811;
362 }
363
subSnikSnakFromBelow(int si,int bx)364 static void subSnikSnakFromBelow(int si, int bx)
365 {
366 int ax, bl;
367
368 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
369 subDrawSnikSnakFromBelow(si, bx);
370 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
371 bx = bx - 0xF; // get and increment sequence#
372
373 bl = LowByte(bx);
374 if (bl == 7 && LowByte(PlayField16[si + FieldWidth]) != fiExplosion)
375 {
376 PlayField16[si + FieldWidth] = 0; // sniknak left that field
377 }
378
379 if (bl < 8) // sniksnak still goes up
380 {
381 bl = bl + 0x10;
382 MovHighByte(&PlayField16[si], bl);
383
384 return;
385 } // loc_g_7813
386
387 PlayField16[si] = 0x11; // sequence#=8 -> arrived at the new field
388 ax = PlayField16[si - 1]; // check left field
389 if (ax == 0 || LowByte(ax) == fiMurphy) // check for empty or murphy
390 {
391 MovHighByte(&PlayField16[si], 1); // start to turn left
392
393 return;
394 } // loc_g_7826: and 'loc_g_7833:
395
396 ax = PlayField16[si - FieldWidth]; // cannot turn left -> check above
397 if (ax == 0) // check if empty
398 {
399 PlayField16[si] = 0x1BB; // mark as "sniksnak leaving"
400 si = si - FieldWidth; // go up!
401 PlayField16[si] = 0x1011;
402
403 return;
404 } // loc_g_784A:
405
406 if (LowByte(ax) == fiMurphy) // check for murphy above
407 {
408 ExplodeFieldSP(si); // Explode
409
410 return;
411 } // loc_g_7855:
412
413 ax = PlayField16[si + 1]; // check right field
414 if (ax == 0 || LowByte(ax) == fiMurphy) // check for empty or murphy
415 {
416 MovHighByte(&PlayField16[si], 9); // start to turn right
417
418 return;
419 } // loc_g_7862: and 'loc_g_786F:
420
421 // else: no way to go, start turning around
422 MovHighByte(&PlayField16[si], 1);
423 }
424
subSnikSnakFromRight(int si,int bx)425 static void subSnikSnakFromRight(int si, int bx)
426 {
427 int ax, bl;
428
429 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
430 subDrawSnikSnakFromRight(si, bx);
431 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
432 bx = bx - 0x17; // get and increment sequence#
433
434 bl = LowByte(bx);
435 if (bl == 7 && LowByte(PlayField16[si + 1]) != fiExplosion)
436 {
437 PlayField16[si + 1] = 0; // sniknak left that field
438 } // loc_g_78AC:
439
440 if (bl < 8) // sniksnak still goes left
441 {
442 bl = bl + 0x18;
443 MovHighByte(&PlayField16[si], bl);
444
445 return;
446 } // loc_g_78B9:
447
448 PlayField16[si] = 0x11; // sequence#=8 -> arrived at the new field
449 ax = PlayField16[si + FieldWidth]; // check below
450 if (ax == 0 || LowByte(ax) == fiMurphy) // empty or murphy?
451 {
452 MovHighByte(&PlayField16[si], 3); // yes -> turn left down
453
454 return;
455 } // loc_g_78CC: and 'loc_g_78D9:
456
457 ax = PlayField16[si - 1]; // check left, etc ... see the comments on subSnikSnakFromBelow()
458 if (ax == 0)
459 {
460 PlayField16[si] = 0x2BB;
461 si = si - 1; // 1 field left
462 PlayField16[si] = 0x1811;
463
464 return;
465 } // loc_g_78F0:
466
467 if (LowByte(ax) == fiMurphy)
468 {
469 ExplodeFieldSP(si); // Explode
470
471 return;
472 } // loc_g_78FB:
473
474 ax = PlayField16[si - FieldWidth]; // check above
475 if (ax == 0 || LowByte(ax) == fiMurphy)
476 {
477 MovHighByte(&PlayField16[si], 0xF);
478
479 return;
480 } // loc_g_7908:loc_g_7915:
481
482 MovHighByte(&PlayField16[si], 3);
483 }
484
subSnikSnakFromAbove(int si,int bx)485 static void subSnikSnakFromAbove(int si, int bx)
486 {
487 int ax, bl;
488
489 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
490 subDrawSnikSnakFromAbove(si, bx);
491 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
492 bx = bx - 0x1F; // get and increment sequence#
493
494 bl = LowByte(bx);
495 if (bl == 7 && LowByte(PlayField16[si - FieldWidth]) != fiExplosion)
496 {
497 PlayField16[si - FieldWidth] = 0; // sniknak left that field
498 }
499
500 if (bl < 8) // sniksnak still goes down
501 {
502 bl = bl + 0x20;
503 MovHighByte(&PlayField16[si], bl);
504
505 return;
506 } // loc_g_7813
507
508 PlayField16[si] = 0x11; // sequence#=8 -> arrived at the new field
509 ax = PlayField16[si + 1]; // check right
510 if (ax == 0 || LowByte(ax) == fiMurphy)
511 {
512 MovHighByte(&PlayField16[si], 5);
513
514 return;
515 } // loc_g_7986:
516
517 ax = PlayField16[si + FieldWidth]; // check below
518 if (ax == 0)
519 {
520 PlayField16[si] = 0x3BB;
521 si = si + FieldWidth; // 1 field down
522 PlayField16[si] = 0x2011;
523
524 return;
525 } // loc_g_799D:
526
527 if (LowByte(ax) == fiMurphy)
528 {
529 ExplodeFieldSP(si); // Explode
530
531 return;
532 } // loc_g_79A8:
533
534 ax = PlayField16[si - 1]; // check left
535 if (ax == 0 || LowByte(ax) == fiMurphy)
536 {
537 MovHighByte(&PlayField16[si], 0xD);
538
539 return;
540 } // loc_g_79C2:
541
542 MovHighByte(&PlayField16[si], 5);
543 }
544
subSnikSnakFromLeft(int si,int bx)545 static void subSnikSnakFromLeft(int si, int bx)
546 {
547 int ax, bl;
548
549 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
550 subDrawSnikSnakFromLeft(si, bx);
551 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
552 bx = bx - 0x27; // get and increment sequence#
553
554 bl = LowByte(bx);
555 if (bl == 7 && LowByte(PlayField16[si - 1]) != fiExplosion)
556 {
557 PlayField16[si - 1] = 0; // sniknak left that field
558 }
559
560 if (bl < 8) // sniksnak still goes right
561 {
562 bl = bl + 0x28;
563 MovHighByte(&PlayField16[si], bl);
564
565 return;
566 } // loc_g_78B9:
567
568 PlayField16[si] = 0x11; // sequence#=8 -> arrived at the new field
569 ax = PlayField16[si - FieldWidth]; // check above
570 if (ax == 0 || LowByte(ax) == fiMurphy)
571 {
572 MovHighByte(&PlayField16[si], 7);
573
574 return;
575 } // loc_g_7A2D:
576
577 ax = PlayField16[si + 1]; // check right(straight on)
578 if (ax == 0)
579 {
580 PlayField16[si] = 0x4BB;
581 si = si + 1; // 1 field right
582 PlayField16[si] = 0x2811;
583
584 return;
585 } // loc_g_7A44:
586
587 if (LowByte(ax) == fiMurphy)
588 {
589 ExplodeFieldSP(si); // Explode
590
591 return;
592 } // loc_g_7A4F:
593
594 ax = PlayField16[si + FieldWidth]; // check below
595 if (ax == 0 || LowByte(ax) == fiMurphy)
596 {
597 MovHighByte(&PlayField16[si], 0xB);
598
599 return;
600 } // loc_g_7A69:
601
602 MovHighByte(&PlayField16[si], 7);
603 }
604
subDrawSnikSnakTurnLeft(int si,int bx)605 static void subDrawSnikSnakTurnLeft(int si, int bx)
606 {
607 int pos = ((bx + 7) % 8) / 2;
608
609 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
610 GfxGraphic[GetX(si)][GetY(si)] = aniSnikSnakTurningLeft[pos];
611 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
612 }
613
subDrawSnikSnakTurnRight(int si,int bx)614 static void subDrawSnikSnakTurnRight(int si, int bx)
615 {
616 int pos = ((bx - 1) % 8) / 2;
617
618 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
619 GfxGraphic[GetX(si)][GetY(si)] = aniSnikSnakTurningRight[pos];
620 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
621 }
622
subDrawSnikSnakFromBelow(int si,int bx)623 static void subDrawSnikSnakFromBelow(int si, int bx)
624 {
625 int X, Y;
626
627 bx = bx - 0xF; // get and anti-increment sequence#
628
629 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
630 X = GetStretchX(si);
631 Y = GetStretchY(si + FieldWidth);
632 DDSpriteBuffer_BltImg(X, Y, aniSpace, 0);
633 DDSpriteBuffer_BltImg(X, Y - bx * TwoPixels, aniSnikSnakUp, bx);
634 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
635 }
636
subDrawSnikSnakFromRight(int si,int bx)637 static void subDrawSnikSnakFromRight(int si, int bx)
638 {
639 int X, Y;
640
641 bx = bx - 0x17; // get and increment sequence#
642
643 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
644 X = GetStretchX(si + 1);
645 Y = GetStretchY(si);
646 DDSpriteBuffer_BltImg(X, Y, aniSpace, 0);
647 DDSpriteBuffer_BltImg(X - bx * TwoPixels, Y, aniSnikSnakLeft, bx);
648 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
649 }
650
subDrawSnikSnakFromAbove(int si,int bx)651 static void subDrawSnikSnakFromAbove(int si, int bx)
652 {
653 int X, Y;
654
655 bx = bx - 0x1F; // get and increment sequence#
656
657 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
658 X = GetStretchX(si);
659 Y = GetStretchY(si - FieldWidth);
660 DDSpriteBuffer_BltImg(X, Y, aniSpace, 0);
661 DDSpriteBuffer_BltImg(X, Y + bx * TwoPixels, aniSnikSnakDown, bx);
662 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
663 }
664
subDrawSnikSnakFromLeft(int si,int bx)665 static void subDrawSnikSnakFromLeft(int si, int bx)
666 {
667 int X, Y;
668
669 bx = bx - 0x27; // get and increment sequence#
670
671 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
672 X = GetStretchX(si - 1);
673 Y = GetStretchY(si);
674 DDSpriteBuffer_BltImg(X, Y, aniSpace, 0);
675 DDSpriteBuffer_BltImg(X + bx * TwoPixels, Y, aniSnikSnakRight, bx);
676 // +++++++++++++++++++++++++++++++++++++++++++++++++++++
677 }
678