// ---------------------------------------------------------------------------- // SnikSnaks.c // ---------------------------------------------------------------------------- #include "SnikSnaks.h" static void subDrawSnikSnakFromAbove(int, int); static void subDrawSnikSnakFromBelow(int, int); static void subDrawSnikSnakFromLeft(int, int); static void subDrawSnikSnakFromRight(int, int); static void subDrawSnikSnakTurnLeft(int, int); static void subDrawSnikSnakTurnRight(int, int); static void subSnikSnakFromAbove(int, int); static void subSnikSnakFromBelow(int, int); static void subSnikSnakFromLeft(int, int); static void subSnikSnakFromRight(int, int); static void subSnikSnakTurnLeft(int, int); static void subSnikSnakTurnRight(int, int); // static char *VB_Name = "modSnikSnak"; // --- Option Explicit // ========================================================================== // SUBROUTINE // Animate/move Snik-Snaks // ========================================================================== void subAnimateSnikSnaks(int si) { int bx, Tmp; if (SnikSnaksElectronsFrozen == 1) return; #if 1 /* (not sure why this was removed -- this broke several level solutions) */ if (LowByte(PlayField16[si]) != fiSnikSnak) return; #endif // If LowByte(PlayField16(si)) <> fiSnikSnak Then Exit Function // Debug.Assert (LowByte(PlayField16[si]) == fiSnikSnak); bx = HighByte(PlayField16[si]); Tmp = bx / 8; switch (Tmp) { case 0: subSnikSnakTurnLeft(si, bx); // turning, bx=0 -> point N, bx = 1 -> point NW etc. break; case 1: subSnikSnakTurnRight(si, bx); // turn right break; case 2: subSnikSnakFromBelow(si, bx); // access si from below break; case 3: subSnikSnakFromRight(si, bx); // access si from right break; case 4: subSnikSnakFromAbove(si, bx); // access si from above break; case 5: subSnikSnakFromLeft(si, bx); // access si from left break; default: // Debug.Assert(False); break; } } void subDrawAnimatedSnikSnaks(int si) { int bx, Tmp; // If SnikSnaksElectronsFrozen = 1 Then Exit Function if (LowByte(PlayField16[si]) != fiSnikSnak) return; bx = HighByte(PlayField16[si]); Tmp = bx / 8; switch (Tmp) { case 0: subDrawSnikSnakTurnLeft(si, bx); // turning, bx=0 -> point N, bx = 1 -> point NW etc. break; case 1: subDrawSnikSnakTurnRight(si, bx); // turn right break; case 2: subDrawSnikSnakFromBelow(si, bx); // access si from below break; case 3: subDrawSnikSnakFromRight(si, bx); // access si from right break; case 4: subDrawSnikSnakFromAbove(si, bx); // access si from above break; case 5: subDrawSnikSnakFromLeft(si, bx); // access si from left break; } } static void subSnikSnakTurnLeft(int si, int bx) { int ax, ah, bl; ax = (TimerVar & 3); if (ax != 0) { if (ax == 3) goto loc_g_7622; return; } // loc_g_75E0: // +++++++++++++++++++++++++++++++++++++++++++++++++++++ subDrawSnikSnakTurnLeft(si, bx); // +++++++++++++++++++++++++++++++++++++++++++++++++++++ bx = (bx + 1) & 0x7; MovHighByte(&PlayField16[si], bx); return; locMayExplode760A: ah = HighByte(ax); if (ah == 0x1B) return; if (ah == 0x19) return; if (ah == 0x18) return; if (ah == 0x1A) return; ExplodeFieldSP(si); // Explode return; loc_g_7622: bl = HighByte(PlayField16[si]); if (bl == 0) goto loc_g_763B; if (bl == 2) goto loc_g_765E; if (bl == 4) goto loc_g_7681; if (bl == 6) goto loc_g_76A7; return; loc_g_763B: // pointing up ax = PlayField16[si - FieldWidth]; if (ax == 0) // above is empty -> go up goto loc_g_764E; if (LowByte(ax) == fiMurphy) // above is murphy -> explode goto locMayExplode760A; return; loc_g_764E: // above is empty -> go up PlayField16[si] = 0x1BB; si = si - FieldWidth; PlayField16[si] = 0x1011; return; loc_g_765E: // pointing left ax = PlayField16[si - 1]; if (ax == 0) // left is empty -> go there goto loc_g_7671; if (LowByte(ax) == fiMurphy) // left is murphy -> explode goto locMayExplode760A; return; loc_g_7671: // left is empty -> go there PlayField16[si] = 0x2BB; si = si - 1; PlayField16[si] = 0x1811; return; loc_g_7681: // pointing down ax = PlayField16[si + FieldWidth]; if (ax == 0) // below is empty -> go down goto loc_g_7697; if (LowByte(ax) == fiMurphy) // below is murphy -> explode goto locMayExplode760A; return; loc_g_7697: // below is empty -> go down PlayField16[si] = 0x3BB; si = si + FieldWidth; PlayField16[si] = 0x2011; return; loc_g_76A7: // pointing Right ax = PlayField16[si + 1]; if (ax == 0) // right is empty -> go there goto loc_g_76BD; if (LowByte(ax) == fiMurphy) // right is murphy -> explode goto locMayExplode760A; return; loc_g_76BD: // right is empty -> go there PlayField16[si] = 0x4BB; si = si + 1; PlayField16[si] = 0x2811; } static void subSnikSnakTurnRight(int si, int bx) { int ax, ah, bl; ax = (TimerVar & 3); if (ax != 0) { if (ax == 3) goto loc_g_771F; return; } // loc_g_76DB: // +++++++++++++++++++++++++++++++++++++++++++++++++++++ subDrawSnikSnakTurnRight(si, bx); // +++++++++++++++++++++++++++++++++++++++++++++++++++++ bx = ((bx + 1) & 0x7) | 8; MovHighByte(&PlayField16[si], bx); return; locMayExplode7707: ah = HighByte(ax); if (ah == 0x1B) return; if (ah == 0x19) return; if (ah == 0x18) return; if (ah == 0x1A) return; ExplodeFieldSP(si); // Explode return; loc_g_771F: bl = HighByte(PlayField16[si]); if (bl == 0x8) goto loc_g_7738; if (bl == 0xA) goto loc_g_77A4; if (bl == 0xC) goto loc_g_777E; if (bl == 0xE) goto loc_g_775B; return; loc_g_7738: // pointing up ax = PlayField16[si - FieldWidth]; if (ax == 0) // above is empty -> go up goto loc_g_774B; if (LowByte(ax) == fiMurphy) // above is murphy -> explode goto locMayExplode7707; return; loc_g_774B: // above is empty -> go up PlayField16[si] = 0x1BB; si = si - FieldWidth; PlayField16[si] = 0x1011; return; loc_g_775B: // pointing left ax = PlayField16[si - 1]; if (ax == 0) // left is empty -> go there goto loc_g_776E; if (LowByte(ax) == fiMurphy) // left is murphy -> explode goto locMayExplode7707; return; loc_g_776E: // left is empty -> go there PlayField16[si] = 0x2BB; si = si - 1; PlayField16[si] = 0x1811; return; loc_g_777E: // pointing down ax = PlayField16[si + FieldWidth]; if (ax == 0) // below is empty -> go down goto loc_g_7794; if (LowByte(ax) == fiMurphy) // below is murphy -> explode goto locMayExplode7707; return; loc_g_7794: // below is empty -> go down PlayField16[si] = 0x3BB; si = si + FieldWidth; PlayField16[si] = 0x2011; return; loc_g_77A4: // pointing Right ax = PlayField16[si + 1]; if (ax == 0) // right is empty -> go there goto loc_g_77BA; if (LowByte(ax) == fiMurphy) // right is murphy -> explode goto locMayExplode7707; return; loc_g_77BA: // right is empty -> go there PlayField16[si] = 0x4BB; si = si + 1; PlayField16[si] = 0x2811; } static void subSnikSnakFromBelow(int si, int bx) { int ax, bl; // +++++++++++++++++++++++++++++++++++++++++++++++++++++ subDrawSnikSnakFromBelow(si, bx); // +++++++++++++++++++++++++++++++++++++++++++++++++++++ bx = bx - 0xF; // get and increment sequence# bl = LowByte(bx); if (bl == 7 && LowByte(PlayField16[si + FieldWidth]) != fiExplosion) { PlayField16[si + FieldWidth] = 0; // sniknak left that field } if (bl < 8) // sniksnak still goes up { bl = bl + 0x10; MovHighByte(&PlayField16[si], bl); return; } // loc_g_7813 PlayField16[si] = 0x11; // sequence#=8 -> arrived at the new field ax = PlayField16[si - 1]; // check left field if (ax == 0 || LowByte(ax) == fiMurphy) // check for empty or murphy { MovHighByte(&PlayField16[si], 1); // start to turn left return; } // loc_g_7826: and 'loc_g_7833: ax = PlayField16[si - FieldWidth]; // cannot turn left -> check above if (ax == 0) // check if empty { PlayField16[si] = 0x1BB; // mark as "sniksnak leaving" si = si - FieldWidth; // go up! PlayField16[si] = 0x1011; return; } // loc_g_784A: if (LowByte(ax) == fiMurphy) // check for murphy above { ExplodeFieldSP(si); // Explode return; } // loc_g_7855: ax = PlayField16[si + 1]; // check right field if (ax == 0 || LowByte(ax) == fiMurphy) // check for empty or murphy { MovHighByte(&PlayField16[si], 9); // start to turn right return; } // loc_g_7862: and 'loc_g_786F: // else: no way to go, start turning around MovHighByte(&PlayField16[si], 1); } static void subSnikSnakFromRight(int si, int bx) { int ax, bl; // +++++++++++++++++++++++++++++++++++++++++++++++++++++ subDrawSnikSnakFromRight(si, bx); // +++++++++++++++++++++++++++++++++++++++++++++++++++++ bx = bx - 0x17; // get and increment sequence# bl = LowByte(bx); if (bl == 7 && LowByte(PlayField16[si + 1]) != fiExplosion) { PlayField16[si + 1] = 0; // sniknak left that field } // loc_g_78AC: if (bl < 8) // sniksnak still goes left { bl = bl + 0x18; MovHighByte(&PlayField16[si], bl); return; } // loc_g_78B9: PlayField16[si] = 0x11; // sequence#=8 -> arrived at the new field ax = PlayField16[si + FieldWidth]; // check below if (ax == 0 || LowByte(ax) == fiMurphy) // empty or murphy? { MovHighByte(&PlayField16[si], 3); // yes -> turn left down return; } // loc_g_78CC: and 'loc_g_78D9: ax = PlayField16[si - 1]; // check left, etc ... see the comments on subSnikSnakFromBelow() if (ax == 0) { PlayField16[si] = 0x2BB; si = si - 1; // 1 field left PlayField16[si] = 0x1811; return; } // loc_g_78F0: if (LowByte(ax) == fiMurphy) { ExplodeFieldSP(si); // Explode return; } // loc_g_78FB: ax = PlayField16[si - FieldWidth]; // check above if (ax == 0 || LowByte(ax) == fiMurphy) { MovHighByte(&PlayField16[si], 0xF); return; } // loc_g_7908:loc_g_7915: MovHighByte(&PlayField16[si], 3); } static void subSnikSnakFromAbove(int si, int bx) { int ax, bl; // +++++++++++++++++++++++++++++++++++++++++++++++++++++ subDrawSnikSnakFromAbove(si, bx); // +++++++++++++++++++++++++++++++++++++++++++++++++++++ bx = bx - 0x1F; // get and increment sequence# bl = LowByte(bx); if (bl == 7 && LowByte(PlayField16[si - FieldWidth]) != fiExplosion) { PlayField16[si - FieldWidth] = 0; // sniknak left that field } if (bl < 8) // sniksnak still goes down { bl = bl + 0x20; MovHighByte(&PlayField16[si], bl); return; } // loc_g_7813 PlayField16[si] = 0x11; // sequence#=8 -> arrived at the new field ax = PlayField16[si + 1]; // check right if (ax == 0 || LowByte(ax) == fiMurphy) { MovHighByte(&PlayField16[si], 5); return; } // loc_g_7986: ax = PlayField16[si + FieldWidth]; // check below if (ax == 0) { PlayField16[si] = 0x3BB; si = si + FieldWidth; // 1 field down PlayField16[si] = 0x2011; return; } // loc_g_799D: if (LowByte(ax) == fiMurphy) { ExplodeFieldSP(si); // Explode return; } // loc_g_79A8: ax = PlayField16[si - 1]; // check left if (ax == 0 || LowByte(ax) == fiMurphy) { MovHighByte(&PlayField16[si], 0xD); return; } // loc_g_79C2: MovHighByte(&PlayField16[si], 5); } static void subSnikSnakFromLeft(int si, int bx) { int ax, bl; // +++++++++++++++++++++++++++++++++++++++++++++++++++++ subDrawSnikSnakFromLeft(si, bx); // +++++++++++++++++++++++++++++++++++++++++++++++++++++ bx = bx - 0x27; // get and increment sequence# bl = LowByte(bx); if (bl == 7 && LowByte(PlayField16[si - 1]) != fiExplosion) { PlayField16[si - 1] = 0; // sniknak left that field } if (bl < 8) // sniksnak still goes right { bl = bl + 0x28; MovHighByte(&PlayField16[si], bl); return; } // loc_g_78B9: PlayField16[si] = 0x11; // sequence#=8 -> arrived at the new field ax = PlayField16[si - FieldWidth]; // check above if (ax == 0 || LowByte(ax) == fiMurphy) { MovHighByte(&PlayField16[si], 7); return; } // loc_g_7A2D: ax = PlayField16[si + 1]; // check right(straight on) if (ax == 0) { PlayField16[si] = 0x4BB; si = si + 1; // 1 field right PlayField16[si] = 0x2811; return; } // loc_g_7A44: if (LowByte(ax) == fiMurphy) { ExplodeFieldSP(si); // Explode return; } // loc_g_7A4F: ax = PlayField16[si + FieldWidth]; // check below if (ax == 0 || LowByte(ax) == fiMurphy) { MovHighByte(&PlayField16[si], 0xB); return; } // loc_g_7A69: MovHighByte(&PlayField16[si], 7); } static void subDrawSnikSnakTurnLeft(int si, int bx) { int pos = ((bx + 7) % 8) / 2; // +++++++++++++++++++++++++++++++++++++++++++++++++++++ GfxGraphic[GetX(si)][GetY(si)] = aniSnikSnakTurningLeft[pos]; // +++++++++++++++++++++++++++++++++++++++++++++++++++++ } static void subDrawSnikSnakTurnRight(int si, int bx) { int pos = ((bx - 1) % 8) / 2; // +++++++++++++++++++++++++++++++++++++++++++++++++++++ GfxGraphic[GetX(si)][GetY(si)] = aniSnikSnakTurningRight[pos]; // +++++++++++++++++++++++++++++++++++++++++++++++++++++ } static void subDrawSnikSnakFromBelow(int si, int bx) { int X, Y; bx = bx - 0xF; // get and anti-increment sequence# // +++++++++++++++++++++++++++++++++++++++++++++++++++++ X = GetStretchX(si); Y = GetStretchY(si + FieldWidth); DDSpriteBuffer_BltImg(X, Y, aniSpace, 0); DDSpriteBuffer_BltImg(X, Y - bx * TwoPixels, aniSnikSnakUp, bx); // +++++++++++++++++++++++++++++++++++++++++++++++++++++ } static void subDrawSnikSnakFromRight(int si, int bx) { int X, Y; bx = bx - 0x17; // get and increment sequence# // +++++++++++++++++++++++++++++++++++++++++++++++++++++ X = GetStretchX(si + 1); Y = GetStretchY(si); DDSpriteBuffer_BltImg(X, Y, aniSpace, 0); DDSpriteBuffer_BltImg(X - bx * TwoPixels, Y, aniSnikSnakLeft, bx); // +++++++++++++++++++++++++++++++++++++++++++++++++++++ } static void subDrawSnikSnakFromAbove(int si, int bx) { int X, Y; bx = bx - 0x1F; // get and increment sequence# // +++++++++++++++++++++++++++++++++++++++++++++++++++++ X = GetStretchX(si); Y = GetStretchY(si - FieldWidth); DDSpriteBuffer_BltImg(X, Y, aniSpace, 0); DDSpriteBuffer_BltImg(X, Y + bx * TwoPixels, aniSnikSnakDown, bx); // +++++++++++++++++++++++++++++++++++++++++++++++++++++ } static void subDrawSnikSnakFromLeft(int si, int bx) { int X, Y; bx = bx - 0x27; // get and increment sequence# // +++++++++++++++++++++++++++++++++++++++++++++++++++++ X = GetStretchX(si - 1); Y = GetStretchY(si); DDSpriteBuffer_BltImg(X, Y, aniSpace, 0); DDSpriteBuffer_BltImg(X + bx * TwoPixels, Y, aniSnikSnakRight, bx); // +++++++++++++++++++++++++++++++++++++++++++++++++++++ }