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