rnd-20090623-1-src
[rocksndiamonds.git] / src / game_sp / Electrons.c
diff --git a/src/game_sp/Electrons.c b/src/game_sp/Electrons.c
new file mode 100644 (file)
index 0000000..709583c
--- /dev/null
@@ -0,0 +1,653 @@
+// ----------------------------------------------------------------------------
+// Electrons.c
+// ----------------------------------------------------------------------------
+
+#include "Electrons.h"
+
+static char *VB_Name = "modElectron";
+// --- Option Explicit
+// ==========================================================================
+//                              SUBROUTINE
+// Animate/move Electrons
+// ==========================================================================
+
+int subAnimateElectrons(int si)
+{
+  int subAnimateElectrons;
+
+  int bx, Tmp;
+
+  if (SnikSnaksElectronsFrozen == 1)
+    return subAnimateElectrons;
+
+  if (LowByte(PlayField16[si]) != fiElectron)
+    return subAnimateElectrons;
+
+  bx = HighByte(PlayField16[si]);
+  Tmp = bx / 8;
+  switch (Tmp)
+  {
+    case 0:
+      subElectronTurnLeft(si, bx); // turning, bx=0 -> point N, bx = 1 -> point NW etc.
+      break;
+
+    case 1:
+      subElectronTurnRight(si, bx); // turn right
+      break;
+
+    case 2:
+      subElectronFromBelow(si, bx); // access si from below
+      break;
+
+    case 3:
+      subElectronFromRight(si, bx); // access si from right
+      break;
+
+    case 4:
+      subElectronFromAbove(si, bx); // access si from above
+      break;
+
+    case 5:
+      subElectronFromLeft(si, bx); // access si from left
+      break;
+  }
+
+  return subAnimateElectrons;
+} // subAnimateElectrons
+
+int subDrawAnimatedElectrons(int si)
+{
+  int subDrawAnimatedElectrons;
+
+  int bx, Tmp;
+
+  // If SnikSnaksElectronsFrozen = 1 Then Exit Function
+  if (LowByte(PlayField16[si]) != fiElectron)
+    return subDrawAnimatedElectrons;
+
+  bx = HighByte(PlayField16[si]);
+  Tmp = bx / 8;
+  switch (Tmp)
+  {
+    case 0:
+      subDrawElectronTurnLeft(si, bx); // turning, bx=0 -> point N, bx = 1 -> point NW etc.
+      break;
+
+    case 1:
+      subDrawElectronTurnRight(si, bx); // turn right
+      break;
+
+    case 2:
+      subDrawElectronFromBelow(si, bx); // access si from below
+      break;
+
+    case 3:
+      subDrawElectronFromRight(si, bx); // access si from right
+      break;
+
+    case 4:
+      subDrawElectronFromAbove(si, bx); // access si from above
+      break;
+
+    case 5:
+      subDrawElectronFromLeft(si, bx); // access si from left
+      break;
+  }
+
+  return subDrawAnimatedElectrons;
+} // subDrawAnimatedElectrons
+
+int subElectronTurnLeft(int si, int bx)
+{
+  int subElectronTurnLeft;
+
+  int ax, ah, bl, dx, X, Y;
+
+  ax = (TimerVar & 3);
+  if (ax != 0)
+  {
+    if (ax == 3)
+      goto loc_g_7ACD;
+
+    return subElectronTurnLeft;
+  } // loc_g_7A9F:
+
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  X = GetStretchX(si);
+  Y = GetStretchY(si);
+  StretchedSprites.BltEx(X, Y, aniElectron[bx]);
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  bx = (bx + 1) & 0x7;
+  MovHighByte(&PlayField16[si], bx);
+  return subElectronTurnLeft;
+
+loc_g_7ACD:
+  bl = HighByte(PlayField16[si]);
+  if (bl == 0)
+    goto loc_g_7AE6;
+
+  if (bl == 2)
+    goto loc_g_7B05;
+
+  if (bl == 4)
+    goto loc_g_7B24;
+
+  if (bl == 6)
+    goto loc_g_7B43;
+
+  return subElectronTurnLeft;
+
+loc_g_7AE6: // pointing up
+  ax = PlayField16[si - FieldWidth];
+  if (ax == 0) // above is empty -> go up
+    goto loc_g_7AF5;
+
+  if (LowByte(ax) == fiMurphy) // above is murphy -> explode
+    ExplodeFieldSP(si);
+
+  return subElectronTurnLeft;
+
+loc_g_7AF5: // above is empty -> go up
+  PlayField16[si] = 0x1BB;
+  si = si - FieldWidth; // 1 field up
+  PlayField16[si] = 0x1018;
+  return subElectronTurnLeft;
+
+loc_g_7B05: // pointing left
+  ax = PlayField16[si - 1];
+  if (ax == 0) // left is empty -> go there
+    goto loc_g_7B14;
+
+  if (LowByte(ax) == fiMurphy) // left is murphy -> explode
+    ExplodeFieldSP(si);
+
+  return subElectronTurnLeft;
+
+loc_g_7B14: // left is empty -> go there
+  PlayField16[si] = 0x2BB;
+  si = si - 1; // 1 field left
+  PlayField16[si] = 0x1818;
+  return subElectronTurnLeft;
+
+loc_g_7B24: // pointing down
+  ax = PlayField16[si + FieldWidth];
+  if (ax == 0) // below is empty -> go down
+    goto loc_g_7B33;
+
+  if (LowByte(ax) == fiMurphy) // below is murphy -> explode
+    ExplodeFieldSP(si);
+
+  return subElectronTurnLeft;
+
+loc_g_7B33: // below is empty -> go down
+  PlayField16[si] = 0x3BB;
+  si = si + FieldWidth; // 1 field down
+  PlayField16[si] = 0x2018;
+  return subElectronTurnLeft;
+
+loc_g_7B43: // pointing Right
+  ax = PlayField16[si + 1];
+  if (ax == 0) // right is empty -> go there
+    goto loc_g_7B55;
+
+  if (LowByte(ax) == fiMurphy) // right is murphy -> explode
+    ExplodeFieldSP(si);
+
+  return subElectronTurnLeft;
+
+loc_g_7B55: // right is empty -> go there
+  PlayField16[si] = 0x4BB;
+  si = si + 1; // 1 field right
+  PlayField16[si] = 0x2818;
+
+  return subElectronTurnLeft;
+} // subElectronTurnLeft
+
+int subElectronTurnRight(int si, int bx)
+{
+  int subElectronTurnRight;
+
+  int ax, ah, bl, dx, X, Y;
+
+  ax = (TimerVar & 3);
+  if (ax != 0)
+  {
+    if (ax == 3)
+      goto loc_g_7BA3;
+
+    return subElectronTurnRight;
+  } // loc_g_7B73:
+
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  X = GetStretchX(si);
+  Y = GetStretchY(si);
+  StretchedSprites.BltEx(X, Y, aniElectron[0x10 - bx]);
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  bx = ((bx + 1) & 0x7) | 8;
+  MovHighByte(&PlayField16[si], bx);
+  return subElectronTurnRight;
+
+loc_g_7BA3:
+  bl = HighByte(PlayField16[si]);
+  if (bl == 0x8)
+    goto loc_g_7BBC;
+
+  if (bl == 0xA)
+    goto loc_g_7C19;
+
+  if (bl == 0xC)
+    goto loc_g_7BFA;
+
+  if (bl == 0xE)
+    goto loc_g_7BDB;
+
+  return subElectronTurnRight;
+
+loc_g_7BBC: // pointing up
+  ax = PlayField16[si - FieldWidth];
+  if (ax == 0) // above is empty -> go up
+    goto loc_g_7BCB;
+
+  if (LowByte(ax) == fiMurphy) // above is murphy -> explode
+    ExplodeFieldSP(si);
+
+  return subElectronTurnRight;
+
+loc_g_7BCB: // above is empty -> go up
+  PlayField16[si] = 0x1BB;
+  si = si - FieldWidth; // 1 field up
+  PlayField16[si] = 0x1018;
+  return subElectronTurnRight;
+
+loc_g_7BDB: // pointing left
+  ax = PlayField16[si - 1];
+  if (ax == 0) // left is empty -> go there
+    goto loc_g_7BEA;
+
+  if (LowByte(ax) == fiMurphy) // left is murphy -> explode
+    ExplodeFieldSP(si);
+
+  return subElectronTurnRight;
+
+loc_g_7BEA: // left is empty -> go there
+  PlayField16[si] = 0x2BB;
+  si = si - 1; // 1 field left
+  PlayField16[si] = 0x1818;
+  return subElectronTurnRight;
+
+loc_g_7BFA: // pointing down
+  ax = PlayField16[si + FieldWidth];
+  if (ax == 0) // below is empty -> go down
+    goto loc_g_7C09;
+
+  if (LowByte(ax) == fiMurphy) // below is murphy -> explode
+    ExplodeFieldSP(si);
+
+  return subElectronTurnRight;
+
+loc_g_7C09: // below is empty -> go down
+  PlayField16[si] = 0x3BB;
+  si = si + FieldWidth; // 1 field down
+  PlayField16[si] = 0x2018;
+  return subElectronTurnRight;
+
+loc_g_7C19: // pointing Right
+  ax = PlayField16[si + 1];
+  if (ax == 0) // right is empty -> go there
+    goto loc_g_7C2B;
+
+  if (LowByte(ax) == fiMurphy) // right is murphy -> explode
+    ExplodeFieldSP(si);
+
+  return subElectronTurnRight;
+
+loc_g_7C2B: // right is empty -> go there
+  PlayField16[si] = 0x4BB;
+  si = si + 1; // 1 field right
+  PlayField16[si] = 0x2818;
+
+  return subElectronTurnRight;
+} // subElectronTurnRight
+
+int subElectronFromBelow(int si, int bx)
+{
+  int subElectronFromBelow;
+
+  int ax, ah, bl, dx, X, Y;
+
+  bx = bx - 0xF;  // get and increment sequence#
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  X = GetStretchX(si);
+  Y = GetStretchY(si + FieldWidth);
+  StretchedSprites.BltEx(X, Y, 0);
+  StretchedSprites.BltEx(X, Y - bx * TwoPixels, aniElectron[bx]);
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  bl = LowByte(bx);
+  if (bl == 7 && LowByte(PlayField16[si + FieldWidth]) != fiExplosion)
+  {
+    PlayField16[si + FieldWidth] = 0; // electron left that field
+  }
+
+  if (bl < 8) // electron still goes up
+  {
+    bl = bl + 0x10;
+    MovHighByte(&PlayField16[si], bl);
+    return subElectronFromBelow;
+  } // loc_g_7C84
+
+  PlayField16[si] = 0x18; // 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 subElectronFromBelow;
+  } // loc_g_7CA4:
+
+  ax = PlayField16[si - FieldWidth]; // cannot turn left -> check above
+  if (ax == 0) // check if empty
+  {
+    PlayField16[si] = 0x1BB; // mark as "electron leaving"
+    si = si - FieldWidth; // go up!
+    PlayField16[si] = 0x1018;
+    return subElectronFromBelow;
+  }
+
+  if (LowByte(ax) == fiMurphy) // check for murphy above
+  {
+    ExplodeFieldSP(si); // Explode
+    return subElectronFromBelow;
+  } // loc_g_7CC6:
+
+  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 subElectronFromBelow;
+  } // loc_g_7CE0:
+
+  // else: no way to go, start turning around
+  MovHighByte(&PlayField16[si], 1);
+
+  return subElectronFromBelow;
+} // subElectronFromBelow
+
+int subElectronFromRight(int si, int bx)
+{
+  int subElectronFromRight;
+
+  int ax, ah, bl, dx, X, Y;
+
+  bx = bx - 0x17;  // get and increment sequence#
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  X = GetStretchX(si + 1);
+  Y = GetStretchY(si);
+  StretchedSprites.BltEx(X, Y, 0);
+  StretchedSprites.BltEx(X - bx * TwoPixels, Y, aniElectron[bx]);
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  bl = LowByte(bx);
+  if (bl == 7 && LowByte(PlayField16[si + 1]) != fiExplosion)
+  {
+    PlayField16[si + 1] = 0; // electron left that field
+  } // loc_g_7D1D:
+
+  if (bl < 8) // sniksnak still goes left
+  {
+    bl = bl + 0x18;
+    MovHighByte(&PlayField16[si], bl);
+    return subElectronFromRight;
+  } // loc_g_7D2A:
+
+  PlayField16[si] = 0x18; // 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 subElectronFromRight;
+  } // loc_g_7D4A:
+
+  ax = PlayField16[si - 1]; // check left, etc ... see the comments on subElectronFromBelow()
+  if (ax == 0)
+  {
+    PlayField16[si] = 0x2BB;
+    si = si - 1;                // 1 field left
+    PlayField16[si] = 0x1818;
+    return subElectronFromRight;
+  } // loc_g_7D61:
+
+  if (LowByte(ax) == fiMurphy)
+  {
+    ExplodeFieldSP(si);      // Explode
+    return subElectronFromRight;
+  } // loc_g_7D6C:
+
+  ax = PlayField16[si - FieldWidth]; // check above
+  if (ax == 0 || LowByte(ax) == fiMurphy)
+  {
+    MovHighByte(&PlayField16[si], 0xF);
+    return subElectronFromRight;
+  } // loc_g_7D86:
+
+  MovHighByte(&PlayField16[si], 3);
+
+  return subElectronFromRight;
+} // subElectronFromRight
+
+int subElectronFromAbove(int si, int bx)
+{
+  int subElectronFromAbove;
+
+  int ax, ah, bl, dx, X, Y;
+
+  bx = bx - 0x1F;  // get and increment sequence#
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  X = GetStretchX(si);
+  Y = GetStretchY(si - FieldWidth);
+  StretchedSprites.BltEx(X, Y, 0);
+  StretchedSprites.BltEx(X, Y + bx * TwoPixels, aniElectron[bx]);
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  bl = LowByte(bx);
+  if (bl == 7 && LowByte(PlayField16[si - FieldWidth]) != fiExplosion)
+  {
+    PlayField16[si - FieldWidth] = 0; // electron left that field
+  }
+
+  if (bl < 8) // electron still goes down
+  {
+    bl = bl + 0x20;
+    MovHighByte(&PlayField16[si], bl);
+    return subElectronFromAbove;
+  } // loc_g_7DD7
+
+  PlayField16[si] = 0x18; // sequence#=8 -> arrived at the new field
+  ax = PlayField16[si + 1]; // check right
+  if (ax == 0 || LowByte(ax) == fiMurphy)
+  {
+    MovHighByte(&PlayField16[si], 5);
+    return subElectronFromAbove;
+  } // loc_g_7DF7:
+
+  ax = PlayField16[si + FieldWidth]; // check below
+  if (ax == 0)
+  {
+    PlayField16[si] = 0x3BB;
+    si = si + FieldWidth;                 // 1 field down
+    PlayField16[si] = 0x2018;
+    return subElectronFromAbove;
+  } // loc_g_7E0E:
+
+  if (LowByte(ax) == fiMurphy)
+  {
+    ExplodeFieldSP(si);        // Explode
+    return subElectronFromAbove;
+  } // loc_g_7E19:
+
+  ax = PlayField16[si - 1]; // check left
+  if (ax == 0 || LowByte(ax) == fiMurphy)
+  {
+    MovHighByte(&PlayField16[si], 0xD);
+    return subElectronFromAbove;
+  } // loc_g_7E33:
+
+  MovHighByte(&PlayField16[si], 5);
+
+  return subElectronFromAbove;
+} // subElectronFromAbove
+
+int subElectronFromLeft(int si, int bx)
+{
+  int subElectronFromLeft;
+
+  int ax, ah, bl, dx, X, Y;
+
+  bx = bx - 0x27;  // get and increment sequence#
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  X = GetStretchX(si - 1);
+  Y = GetStretchY(si);
+  StretchedSprites.BltEx(X, Y, 0);
+  StretchedSprites.BltEx(X + bx * TwoPixels, Y, aniElectron[bx]);
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  bl = LowByte(bx);
+  if (bl == 7 && LowByte(PlayField16[si - 1]) != fiExplosion)
+  {
+    PlayField16[si - 1] = 0; // electron left that field
+  }
+
+  if (bl < 8) // electron still goes right
+  {
+    bl = bl + 0x28;
+    MovHighByte(&PlayField16[si], bl);
+    return subElectronFromLeft;
+  } // loc_g_7E7E:
+
+  PlayField16[si] = 0x18; // sequence#=8 -> arrived at the new field
+  ax = PlayField16[si - FieldWidth]; // check above
+  if (ax == 0 || LowByte(ax) == fiMurphy)
+  {
+    MovHighByte(&PlayField16[si], 7);
+    return subElectronFromLeft;
+  } // loc_g_7E9E:
+
+  ax = PlayField16[si + 1]; // check right(straight on)
+  if (ax == 0)
+  {
+    PlayField16[si] = 0x4BB;
+    si = si + 1;                   // 1 field right
+    PlayField16[si] = 0x2818;
+    return subElectronFromLeft;
+  } // loc_g_7EB5:
+
+  if (LowByte(ax) == fiMurphy)
+  {
+    ExplodeFieldSP(si);    // Explode
+    return subElectronFromLeft;
+  } // loc_g_7EC0:
+
+  ax = PlayField16[si + FieldWidth]; // check below
+  if (ax == 0 || LowByte(ax) == fiMurphy)
+  {
+    MovHighByte(&PlayField16[si], 0xB);
+    return subElectronFromLeft;
+  } // loc_g_7A69:
+
+  MovHighByte(&PlayField16[si], 7);
+
+  return subElectronFromLeft;
+} // subElectronFromLeft
+
+int subDrawElectronTurnLeft(int si, int bx)
+{
+  int subDrawElectronTurnLeft;
+
+  int X, Y;
+
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  X = GetStretchX(si);
+  Y = GetStretchY(si);
+  StretchedSprites.BltEx(X, Y, aniElectron[bx]);
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  return subDrawElectronTurnLeft;
+}
+
+int subDrawElectronTurnRight(int si, int bx)
+{
+  int subDrawElectronTurnRight;
+
+  int X, Y;
+
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  X = GetStretchX(si);
+  Y = GetStretchY(si);
+  StretchedSprites.BltEx(X, Y, aniElectron[0x10 - bx]);
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  return subDrawElectronTurnRight;
+}
+
+int subDrawElectronFromBelow(int si, int bx)
+{
+  int subDrawElectronFromBelow;
+
+  int X, Y;
+
+  bx = bx - 0xF;  // get and increment sequence#
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  X = GetStretchX(si);
+  Y = GetStretchY(si + FieldWidth);
+  StretchedSprites.BltEx(X, Y, 0);
+  StretchedSprites.BltEx(X, Y - bx * TwoPixels, aniElectron[bx]);
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  return subDrawElectronFromBelow;
+}
+
+int subDrawElectronFromRight(int si, int bx)
+{
+  int subDrawElectronFromRight;
+
+  int X, Y;
+
+  bx = bx - 0x17;  // get and increment sequence#
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  X = GetStretchX(si + 1);
+  Y = GetStretchY(si);
+  StretchedSprites.BltEx(X, Y, 0);
+  StretchedSprites.BltEx(X - bx * TwoPixels, Y, aniElectron[bx]);
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  return subDrawElectronFromRight;
+}
+
+int subDrawElectronFromAbove(int si, int bx)
+{
+  int subDrawElectronFromAbove;
+
+  int X, Y;
+
+  bx = bx - 0x1F;  // get and increment sequence#
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  X = GetStretchX(si);
+  Y = GetStretchY(si - FieldWidth);
+  StretchedSprites.BltEx(X, Y, 0);
+  StretchedSprites.BltEx(X, Y + bx * TwoPixels, aniElectron[bx]);
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  return subDrawElectronFromAbove;
+}
+
+int subDrawElectronFromLeft(int si, int bx)
+{
+  int subDrawElectronFromLeft;
+
+  int X, Y;
+
+  bx = bx - 0x27;  // get and increment sequence#
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+  X = GetStretchX(si - 1);
+  Y = GetStretchY(si);
+  StretchedSprites.BltEx(X, Y, 0);
+  StretchedSprites.BltEx(X + bx * TwoPixels, Y, aniElectron[bx]);
+  // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  return subDrawElectronFromLeft;
+}