--- /dev/null
+// ----------------------------------------------------------------------------
+// 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;
+}