rnd-20090623-1-src
[rocksndiamonds.git] / src / game_sp / Explosions.c
diff --git a/src/game_sp/Explosions.c b/src/game_sp/Explosions.c
new file mode 100644 (file)
index 0000000..b6b6ca8
--- /dev/null
@@ -0,0 +1,337 @@
+// ----------------------------------------------------------------------------
+// Explosions.c
+// ----------------------------------------------------------------------------
+
+#include "Explosions.h"
+
+static void LetExplodeFieldSP(int tsi, int cx, int dh);
+static int subExplodeInfotron(int tsi, int cx);
+static int subExplodeZonk(int tsi, int cx);
+
+static char *VB_Name = "modExplosions";
+// --- Option Explicit
+
+// ==========================================================================
+//                              SUBROUTINE
+// Animate explosion
+// ==========================================================================
+int subAnimateExplosion(int si)
+{
+  int subAnimateExplosion;
+
+  int ax, bx, bl, X, Y;
+
+  if (LowByte(PlayField16[si]) != fiExplosion)
+    return subAnimateExplosion;
+
+  ax = (TimerVar & 3);
+  if (ax != 0)
+    return subAnimateExplosion;
+
+  bl = HighByte(PlayField16[si]);
+  if ((bl & 0x80) != 0) // infotron explosion!
+    goto loc_g_28D0;
+
+  bl = bl + 1;
+  MovHighByte(&PlayField16[si], bl);
+  // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  X = GetStretchX(si);
+  Y = GetStretchY(si);
+  StretchedSprites.BltEx(X, Y, aniExplosion[bl]);
+  // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  if (bl == 8)
+  {
+    PlayField16[si] = 0;
+    ExplosionShake = 0; // nothing explodes
+  } // loc_ret_g_28CF:
+
+  return subAnimateExplosion;
+
+loc_g_28D0: // explosion produces infotron
+  bl = bl + 1;
+  if (bl == 0x89)
+  {
+    PlayField16[si] = fiInfotron;
+    MovLowByte(&ExplosionShake, 0); // nothing explodes
+    return subAnimateExplosion;
+  } // loc_g_28E3:
+
+  MovHighByte(&PlayField16[si], bl);
+  // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  X = GetStretchX(si);
+  Y = GetStretchY(si);
+  StretchedSprites.BltEx(X, Y, aniExplosionInfo + bl - 0x80);
+  // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  return subAnimateExplosion;
+} // subAnimateExplosion
+
+// ==========================================================================
+//                              SUBROUTINE
+// Explode
+// ==========================================================================
+
+void ExplodeFieldSP(int si)
+{
+  int ax, al, cx, dl, dh;
+
+  ax = LowByte(PlayField16[si]);
+  if (ax == fiHardWare)
+    return;
+
+  ExplosionShake = 1; // something explodes
+  if (ax == fiMurphy)
+    KillMurphyFlag = 1;
+
+  if (ax == fiElectron)
+  {
+    cx = 0x801F; // produce infotrons
+    dl = 0xF3;
+  }
+  else // loc_g_2977:
+  {
+    cx = 0x1F; // normal explosion
+    dl = 0xD;
+  } // loc_g_297C:
+
+  LetExplodeFieldSP(si - FieldWidth - 1, cx, dl);
+  LetExplodeFieldSP(si - FieldWidth, cx, dl);
+  LetExplodeFieldSP(si - FieldWidth + 1, cx, dl);
+  LetExplodeFieldSP(si - 1, cx, dl);
+  PlayField16[si] = cx;
+  LetExplodeFieldSP(si + 1, cx, dl);
+  LetExplodeFieldSP(si + FieldWidth - 1, cx, dl);
+  LetExplodeFieldSP(si + FieldWidth, cx, dl);
+  LetExplodeFieldSP(si + FieldWidth + 1, cx, dl);
+
+loc_g_2C3B:
+  subSoundFXExplosion();
+} // ExplodeFieldSP
+
+static void LetExplodeFieldSP(int tsi, int cx, int dh)
+{
+  int al;
+
+  if (tsi < (-FieldWidth))
+    return;
+
+  al = LowByte(PlayField16[tsi]);
+  switch (al)
+  {
+    case fiHardWare:
+      return;
+
+      break;
+
+    case fiOrangeDisk:
+    case fiYellowDisk:
+    case fiSnikSnak:
+      PlayField8[tsi] = dh;
+      PlayField16[tsi] = cx;
+      break;
+
+    case fiZonk:
+      subExplodeZonk(tsi, cx);
+      break;
+
+    case fiInfotron:
+      subExplodeInfotron(tsi, cx);
+      break;
+
+    case fiElectron:
+      PlayField8[tsi] = (-dh) & 0xFF;
+      PlayField16[tsi] = 0x801F;
+      break;
+
+    case fiMurphy:
+      KillMurphyFlag = 1;
+      PlayField8[tsi] = dh;
+      PlayField16[tsi] = cx;
+      break;
+
+    default:
+      PlayField16[tsi] = cx;
+      break;
+  }
+}
+
+static int subExplodeZonk(int tsi, int cx)
+{
+  static int subExplodeZonk;
+
+  int ah;
+
+  ah = HighByte(PlayField16[tsi]) & 0xF0;
+  PlayField16[tsi] = cx;
+  switch (ah)
+  {
+    case 0x10:
+    case 0x70:
+      subClearFieldDueToExplosion(tsi - FieldWidth);
+      tsi = tsi + FieldWidth;
+      if (PlayField16[tsi] == 0x9999)
+        subClearFieldDueToExplosion(tsi);
+
+      break;
+
+    case 0x20:
+      subClearFieldDueToExplosion(tsi + 1);
+      subClearFieldDueToExplosion(tsi + FieldWidth);
+      break;
+
+    case 0x30:
+      subClearFieldDueToExplosion(tsi - 1);
+      subClearFieldDueToExplosion(tsi + FieldWidth);
+      break;
+
+    case 0x50:
+      subClearFieldDueToExplosion(tsi - 1);
+      break;
+
+    case 0x60:
+      subClearFieldDueToExplosion(tsi + 1);
+      break;
+
+    case 0xFF000070: // !!! 0x70; this will never be reached! ...??
+      subClearFieldDueToExplosion(tsi + FieldWidth);
+      break;
+  }
+
+  return subExplodeZonk;
+} // subExplodeZonk
+
+static int subExplodeInfotron(int tsi, int cx)
+{
+  static int subExplodeInfotron;
+
+  int ah;
+
+  ah = HighByte(PlayField16[tsi]) & 0xF0;
+  PlayField16[tsi] = cx;
+  switch (ah)
+  {
+    case 0x10:
+    case 0x70:
+      subClearFieldDueToExplosion(tsi - FieldWidth);
+      tsi = tsi + FieldWidth;
+      if (PlayField16[tsi] == 0x9999)
+        subClearFieldDueToExplosion(tsi);
+
+      break;
+
+    case 0x20:
+      subClearFieldDueToExplosion(tsi + 1);
+      tsi = tsi + FieldWidth; // differnt from zonk version
+      if (PlayField16[tsi] == 0x9999)
+        subClearFieldDueToExplosion(tsi);
+
+      break;
+
+    case 0x30:
+      subClearFieldDueToExplosion(tsi - 1);
+      tsi = tsi + FieldWidth; // differnt from zonk version
+      if (PlayField16[tsi] == 0x9999)
+        subClearFieldDueToExplosion(tsi);
+
+      break;
+
+    case 0x50:
+      subClearFieldDueToExplosion(tsi - 1);
+      break;
+
+    case 0x60:
+      subClearFieldDueToExplosion(tsi + 1);
+      break;
+
+    case 0xFF000070: // !!! 0x70; this will never be reached! ...??
+      subClearFieldDueToExplosion(tsi + FieldWidth);
+      break;
+  }
+
+  return subExplodeInfotron;
+} // subExplodeInfotron
+
+int subClearFieldDueToExplosion(int si)
+{
+  int subClearFieldDueToExplosion;
+
+  int X, Y;
+
+  if (LowByte(PlayField16[si]) == fiExplosion)
+    return subClearFieldDueToExplosion;
+
+  PlayField16[si] = 0;
+  // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  X = GetStretchX(si);
+  Y = GetStretchY(si);
+  StretchedSprites.BltEx(X, Y, fiSpace);
+  // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  return subClearFieldDueToExplosion;
+} // subClearFieldDueToExplosion
+
+int subRedDiskReleaseExplosion()
+{
+  int subRedDiskReleaseExplosion;
+
+  int al, X, Y, si;
+
+  al = RedDiskReleasePhase;            // Red disk release phase
+  if (al <= 1)
+    return subRedDiskReleaseExplosion;
+
+  si = RedDiskReleaseMurphyPos;
+  if (PlayField16[si] == 0) // Release red disk
+    PlayField16[si] = fiRedDisk;
+
+  // +++++++++++++++++++++++++++++++++++++++++
+  X = GetStretchX(si);
+  Y = GetStretchY(si);
+  StretchedSprites.BltEx(X, Y, fiRedDisk);
+  // +++++++++++++++++++++++++++++++++++++++++
+  RedDiskReleasePhase = RedDiskReleasePhase + 1;
+  if (RedDiskReleasePhase >= 0x28)
+  {
+    // si = RedDiskReleaseMurphyPos           ' Red disk was released here
+    ExplodeFieldSP(si);                 // Explode
+    RedDiskReleasePhase = 0;
+  }
+
+  return subRedDiskReleaseExplosion;
+}
+
+int subFollowUpExplosions()
+{
+  int subFollowUpExplosions;
+
+  int ax, si;
+
+locloop_g_2919:
+  for (si = 0; si <= LevelMax; si++)
+  {
+    ax = ByteToInt(PlayField8[si]);
+    if (ax != 0)
+    {
+      if (ax < 0)
+      {
+        ax = ax + 1;
+        PlayField8[si] = ax & 0xFF;
+        if (ax == 0)
+        {
+          PlayField16[si] = 0xFF18;
+          ExplodeFieldSP(si);                 // Explode
+        }
+
+      }
+      else
+      {
+        ax = ax - 1;
+        PlayField8[si] = ax;
+        if (ax == 0)
+          ExplodeFieldSP(si);
+      }
+    }
+  }
+
+  return subFollowUpExplosions;
+} // subFollowUpExplosions