+2009-06-20
+ * started with integration of native Supaplex engine, using source code
+ of Megaplex from Frank Schindler, based on original Supaplex engine
+
+2009-06-16
+ * version number set to 3.2.6.2
+
2009-06-15
* version 3.2.6.1 released
CONFIG_GAME = $(CONFIG_GAME_DIR) $(CONFIG_SCORE_ENTRIES) $(CONFIG_SPECIAL)
CONFIG = $(CONFIG_GAME) $(JOYSTICK)
-# DEBUG = -DDEBUG -g
+DEBUG = -DDEBUG -g
# PROFILING = $(PROFILING_FLAGS)
# OPTIONS = $(DEBUG) -Wall # only for debugging purposes
GAME_EM_DIR = game_em
GAME_EM = $(GAME_EM_DIR)/game_em.a
-RNDLIBS = $(LIBGAME) $(GAME_EM)
+GAME_SP_DIR = game_sp
+GAME_SP = $(GAME_SP_DIR)/game_sp.a
+
+RNDLIBS = $(LIBGAME) $(GAME_EM) $(GAME_SP)
ICONBASE = windows_icon
ifeq ($(PLATFORM),cross-win32)
# build targets
# -----------------------------------------------------------------------------
-all: libgame_dir game_em_dir $(PROGNAME)
+all: libgame_dir game_em_dir game_sp_dir $(PROGNAME)
$(PROGNAME): $(RNDLIBS) $(TIMESTAMP_FILE) $(OBJS) $(ICON)
$(CC) $(PROFILING) $(OBJS) $(ICON) $(RNDLIBS) $(LDFLAGS) -o $(PROGNAME)
$(GAME_EM):
@$(MAKE) -C $(GAME_EM_DIR)
+game_sp_dir:
+ @$(MAKE) -C $(GAME_SP_DIR)
+$(GAME_SP):
+ @$(MAKE) -C $(GAME_SP_DIR)
+
auto-conf:
@for i in $(CNFS); do \
echo "$(CNFS_CMD) $$i > $$i"; \
conf_mus.h: conf_mus.c
@$(MAKE) auto-conf
-$(TIMESTAMP_FILE): $(SRCS) $(LIBGAME) $(GAME_EM)
+$(TIMESTAMP_FILE): $(SRCS) $(LIBGAME) $(GAME_EM) $(GAME_SP)
@date '+"%Y-%m-%d %H:%M"' \
| sed -e 's/^/#define COMPILE_DATE_STRING /' \
> $(TIMESTAMP_FILE)
clean-obj:
$(MAKE) -C $(LIBGAME_DIR) clean
$(MAKE) -C $(GAME_EM_DIR) clean
+ $(MAKE) -C $(GAME_SP_DIR) clean
$(RM) $(OBJS)
$(RM) $(LIBGAME)
$(RM) $(GAME_EM)
+ $(RM) $(GAME_SP)
clean-ico:
$(RM) $(ICONBASE).ico
dist-clean: clean-obj
tags:
- $(ETAGS) *.[ch] $(LIBGAME_DIR)/*.[ch] $(GAME_EM_DIR)/*.[ch]
+ $(ETAGS) *.[ch] $(LIBGAME_DIR)/*.[ch] $(GAME_EM_DIR)/*.[ch] $(GAME_SP_DIR)/*.[ch]
depend:
$(MAKE) -C $(LIBGAME_DIR) depend
$(MAKE) -C $(GAME_EM_DIR) depend
+ $(MAKE) -C $(GAME_SP_DIR) depend
for i in $(SRCS); do $(CPP) $(CFLAGS) -M $$i; done > .depend
ifeq (.depend,$(wildcard .depend))
-#define COMPILE_DATE_STRING "2009-06-15 22:46"
+#define COMPILE_DATE_STRING "2009-06-23 02:12"
#include "libgame/libgame.h"
#include "game_em/export.h"
+#include "game_sp/export.h"
/* ========================================================================= */
case LEVEL_FILE_TYPE_SP:
LoadLevelFromFileInfo_SP(level, level_file_info);
+#if 1
+ level->game_engine_type = GAME_ENGINE_TYPE_SP;
+#endif
break;
case LEVEL_FILE_TYPE_DC:
/* blit playfield from scroll buffer to normal back buffer for fading in */
BlitScreenToBitmap_EM(backbuffer);
}
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
+ {
+ InitGameEngine_SP();
+
+ /* blit playfield from scroll buffer to normal back buffer for fading in */
+ BlitScreenToBitmap_SP(backbuffer);
+ }
else
{
DrawLevel();
{
GameActions_EM_Main();
}
+ else if (level.game_engine_type == GAME_ENGINE_TYPE_SP)
+ {
+ GameActions_SP_Main();
+ }
else
{
GameActions_RND();
AdvanceFrameAndPlayerCounters(-1); /* advance counters for all players */
}
+void GameActions_SP_Main()
+{
+ byte effective_action[MAX_PLAYERS];
+ boolean warp_mode = (tape.playing && tape.warp_forward && !tape.pausing);
+ int i;
+
+ for (i = 0; i < MAX_PLAYERS; i++)
+ effective_action[i] = stored_player[i].effective_action;
+
+ GameActions_SP(effective_action, warp_mode);
+
+ CheckLevelTime();
+
+ AdvanceFrameAndPlayerCounters(-1); /* advance counters for all players */
+}
+
void GameActions_RND()
{
int magic_wall_x = 0, magic_wall_y = 0;
void GameActions(void);
void GameActions_EM_Main();
+void GameActions_SP_Main();
void GameActions_RND();
void ScrollLevel(int, int);
# =============================================================================
# Rocks'n'Diamonds Makefile (game_em)
# -----------------------------------------------------------------------------
-# (c) 1995-2005 Holger Schemel <info@artsoft.org>
+# (c) 1995-2006 Holger Schemel <info@artsoft.org>
# -----------------------------------------------------------------------------
# Emerald Mine for X11 © 2000,2001 David Tritscher
# =============================================================================
-#ifndef EXPORT_H
-#define EXPORT_H
+#ifndef GAME_SP_EXPORT_H
+#define GAME_SP_EXPORT_H
/* ========================================================================= */
/* functions and definitions exported from game_em to main program */
extern void LoadEngineSnapshotValues_EM();
extern void SaveEngineSnapshotValues_EM();
-#endif /* EXPORT_H */
+#endif /* GAME_SP_EXPORT_H */
/* often used screen positions */
#define ORIG_MENU_SX ((ORIG_SCR_MENUX - SCR_MENUX) * TILEX / 2)
#define ORIG_MENU_SY 0
-#define SY 8
#define SX 8
#define SY 8
#define SXSIZE (SCR_FIELDX * TILEX)
--- /dev/null
+// ----------------------------------------------------------------------------
+// ASM.c
+// ----------------------------------------------------------------------------
+
+#include "ASM.h"
+
+static char *VB_Name = "modASM";
+// --- Option Explicit
+
+// PseudoRegisters:
+// Public ax%, bx%
+// --- const int ByteMask = 0xFF;
+int cmpFlag;
+
+void Neg(int *Val)
+{
+ *Val = -*Val;
+}
+
+void Mov(int *Var, int Val)
+{
+ *Var = Val;
+}
+
+void MovLowByte(int *Var, int Val)
+{
+ *Var = (*Var & 0xFF00) | (Val & 0xFF);
+}
+
+void MovHighByte(int *Var, int Val)
+{
+ int Tmp;
+
+ Tmp = Val & 0x7F;
+ Tmp = 0x100 * Tmp;
+ if ((Val & 0x80) != 0)
+ Tmp = Tmp | 0x8000;
+
+ *Var = (*Var & 0xFF) | Tmp;
+}
+
+int LowByte(int Var)
+{
+ int LowByte;
+
+ // Dim Tmp As Byte
+ LowByte = (Var & 0xFF);
+ // LowByte = ByteToInt(Tmp)
+
+ return LowByte;
+}
+
+int HighByte(int Var)
+{
+ int HighByte;
+
+ if (Var & 0x8000)
+ {
+ HighByte = ((Var & 0x7FFF) / 0x100) | 0x80;
+ }
+ else
+ {
+ HighByte = Var / 0x100;
+ }
+
+ return HighByte;
+}
+
+int SgnHighByte(int Var) // extends the signum to 16 bit
+{
+ int SgnHighByte;
+
+ if (Var & 0x8000)
+ {
+ SgnHighByte = ((Var & 0x7FFF) / 0x100) | 0xFF80;
+ }
+ else
+ {
+ SgnHighByte = Var / 0x100;
+ }
+
+ return SgnHighByte;
+}
+
+boolean Less()
+{
+ boolean Less;
+
+ Less = (cmpFlag < 0);
+
+ return Less;
+}
+
+boolean GreaterOrEqual()
+{
+ boolean GreaterOrEqual;
+
+ GreaterOrEqual = (0 <= cmpFlag);
+
+ return GreaterOrEqual;
+}
+
+boolean Equal()
+{
+ boolean Equal;
+
+ Equal = (0 == cmpFlag);
+
+ return Equal;
+}
+
+void CMP(int A, int B)
+{
+ cmpFlag = A - B;
+}
+
+void Add(int *A, int B)
+{
+ *A = *A + B;
+}
+
+void MySub(int *A, int B)
+{
+ *A = *A - B;
+}
+
+int SHR(int Var, int Count)
+{
+ int SHR;
+
+ int i;
+
+ if (Var & 0x8000)
+ {
+ Var = ((Var & 0x7FFF) / 2) | 0x4000;
+ }
+ else
+ {
+ Var = Var / 2;
+ }
+
+ for (i = 2; i <= Count; i++)
+ {
+ Var = Var / 2;
+ }
+
+ return SHR;
+}
+
+int SHL(int Var, int Count)
+{
+ int SHL;
+
+ int i;
+
+ for (i = 1; i <= Count; i++)
+ {
+ Var = Var & 0x7FFF;
+ if ((Var & 0x4000) != 0)
+ {
+ Var = (2 * (Var & 0x3FFF)) | 0x8000;
+ }
+ else
+ {
+ Var = 2 * Var;
+ }
+ }
+
+ return SHL;
+}
+
+int ByteToInt(byte B)
+{
+ int ByteToInt;
+
+ if ((B & 0x80) == 0x80)
+ {
+ ByteToInt = -(0xFF - B + 1);
+ }
+ else
+ {
+ ByteToInt = B;
+ }
+
+ return ByteToInt;
+}
+
+byte IntToByte(int i)
+{
+ byte IntToByte;
+
+ // IntToByte = CByte(i & 0xFF);
+ IntToByte = (byte)(i & 0xFF);
+
+ return IntToByte;
+}
+
+void XCHG(int A, int B)
+{
+ int Tmp;
+
+ Tmp = B;
+ B = A;
+ A = Tmp;
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// ASM.h
+// ----------------------------------------------------------------------------
+
+#ifndef ASM_H
+#define ASM_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+#define ByteMask (0xFF)
+
+extern void Add(int *A, int B);
+extern int ByteToInt(byte B);
+extern void CMP(int A, int B);
+extern boolean Equal();
+extern boolean GreaterOrEqual();
+extern int HighByte(int Var);
+extern byte IntToByte(int i);
+extern boolean Less();
+extern int LowByte(int Var);
+extern void Mov(int *Var, int Val);
+extern void MovHighByte(int *Var, int Val);
+extern void MovLowByte(int *Var, int Val);
+extern void MySub(int *A, int B);
+extern void Neg(int *Val);
+extern int SHL(int Var, int Count);
+extern int SHR(int Var, int Count);
+extern int SgnHighByte(int Var);
+extern void XCHG(int A, int B);
+
+extern int cmpFlag;
+
+#endif /* ASM_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// BitMapObject.c
+// ----------------------------------------------------------------------------
+
+#include "BitMapObject.h"
+
+static void ConvertToVBPalette();
+static long Get_ByteWidth();
+static long Get_LineLength();
+static void ReDimArrays();
+
+// --- VERSION 1.0 CLASS
+// --- BEGIN
+// --- MultiUse = -1 'True // True
+// --- Persistable = 0 'NotPersistable // NotPersistable
+// --- DataBindingBehavior = 0 'vbNone // vbNone
+// --- DataSourceBehavior = 0 'vbNone // vbNone
+// --- MTSTransactionMode = 0 'NotAnMTSObject // NotAnMTSObject
+// --- END
+
+static char *VB_Name = "BitMapObject";
+static boolean VB_GlobalNameSpace = False;
+static boolean VB_Creatable = True;
+static boolean VB_PredeclaredId = False;
+static boolean VB_Exposed = False;
+// --- Option Explicit
+
+// info von http://web.usxchange.net/elmo/bmp.htm
+
+// A BMP file consists of the four following parts:
+//
+// 1.BITMAPFILEHEADER
+// 2.BITMAPINFOHEADER
+// 3.A color table of RGBQUAD structures (1, 4 & 8 bit only)
+// 4.An array of bytes for the actual image data
+
+// 1.BITMAPFILEHEADER
+// 1.bfType
+// Declared an unsigned integer. But, this is just to reserve space for 2 bytes.
+// The 2 bytes must be the 2 characters BM to indicate a BitMap file.
+// 2.bfSize
+// Total size of file in bytes.
+// 3.bfReserved1
+// Always zero (ignore).
+// 4.bfReserved2
+// Always zero (ignore).
+// 5.bfOffBits
+// Specifies the byte offset from the BITMAPFILEHEADER structure to the actual bitmap data in the file.
+// ::: #ifndef HAS_BitmapFileHeaderType
+// ::: typedef struct // { /* bmfh */
+// ::: {
+// ::: byte bfTypeB;
+// ::: byte bfTypeM;
+// ::: long bfSize;
+// ::: int bfReserved1;
+// ::: int bfReserved2;
+// ::: long bfOffBits;
+// ::: } BitmapFileHeaderType;
+// ::: #define HAS_BitmapFileHeaderType
+// ::: #endif
+
+// 2.BITMAPINFOHEADER
+// 1.biSize
+// Size of BITMAPINFOHEADER structure (should always be 40).
+// 2.biWidth
+// Width of image in pixels.
+// 3.biHeight
+// Height of image in pixels.
+// 4.biPlanes
+// Always one (ignore).
+// 5.biBitCount
+// Specifies the number of bits per pixel. This value must be 1, 4, 8, or 24.
+// 6.biCompression
+// Specifies the type of compression.
+// 1.BI_RGB No compression.
+// 2.BI_RLE8 8 bit RLE
+// 3.BI_RLE4 4 bit RLE
+// 7.biSizeImage
+// Specifies the size, in bytes, of the image data. May be zero if the bitmap is in the BI_RGB format.
+// 8.biXPelsPerMeter
+// Ignore.
+// 9.biYPelsPerMeter
+// Ignore.
+// 10.biClrUsed
+// Specifies the number of color indices in the color table. Zero indicaes the bitmap uses the maximum number of colors corresponding to the value of the
+// biBitCount member e.g. 8 bit -> 256 colors.
+//
+// The maximum number of colors = 2N. Where N = biBitCount. 2N is the same as 1 << N. The same as you can get powers of 10 by shifting the decimal point
+// in a decimal number, only it is binary.
+// 11.biClrImportant
+// Ignore.
+// ::: #ifndef HAS_BitmapInfoHeaderType
+// ::: typedef struct // { /* bmih */
+// ::: {
+// ::: long biSize;
+// ::: long biWidth;
+// ::: long biHeight;
+// ::: int biPlanes;
+// ::: int biBitCount;
+// ::: long biCompression;
+// ::: long biSizeImage;
+// ::: long biXPelsPerMeter;
+// ::: long biYPelsPerMeter;
+// ::: long biClrUsed;
+// ::: long biClrImportant;
+// ::: } BitmapInfoHeaderType;
+// ::: #define HAS_BitmapInfoHeaderType
+// ::: #endif
+
+// 3.A color table of RGBQUAD structures (1, 4 & 8 bit only)
+// RGBQUAD structure is self explanatory.
+// ::: #ifndef HAS_RGBQUADType
+// ::: typedef struct // { /* rgbq */
+// ::: {
+// ::: byte rgbBlue;
+// ::: byte rgbGreen;
+// ::: byte rgbRed;
+// ::: byte rgbReserved;
+// ::: } RGBQUADType;
+// ::: #define HAS_RGBQUADType
+// ::: #endif
+
+RGBQUADType *ColorTable;
+long *VBPalette;
+
+// 4.An array of bytes for the actual image data
+// Bits per pixel & compression determined by biBitCount & biCompression.
+
+byte *ImageDataBytes;
+
+// ######################################################################################################
+
+BitmapFileHeaderType BMFH;
+BitmapInfoHeaderType BMIH;
+
+static long Get_LineLength()
+{
+ static long LineLength;
+
+ LineLength = 4 * (((Get_ByteWidth() - 1) / 4) + 1);
+
+ return LineLength;
+}
+
+static long Get_ByteWidth()
+{
+ static long ByteWidth;
+
+ ByteWidth = BMIH.biWidth * BMIH.biBitCount / 8;
+
+ return ByteWidth;
+}
+
+void BitMapObject_CreateAtSize(long XPixels, long YPixels, long BitsPerPixel)
+{
+ {
+ BMIH.biWidth = XPixels;
+ BMIH.biHeight = YPixels;
+ BMIH.biSize = 40;
+ BMIH.biBitCount = BitsPerPixel;
+ BMIH.biClrUsed = (1 << BMIH.biBitCount);
+ BMIH.biPlanes = 1;
+ BMIH.biClrImportant = BMIH.biClrUsed;
+ BMIH.biCompression = 0;
+ }
+ {
+ BMFH.bfTypeB = 0x42; // B'
+ BMFH.bfTypeM = 0x4D; // M'
+ }
+ ReDimArrays();
+}
+
+void BitMapObject_CreateFromFile(char *Path)
+{
+ long FNum;
+
+ FNum = FreeFile();
+ if (! FileExists(Path))
+ return;
+
+ if (FileLen(Path) < (Len(BMFH) + Len(BMIH)))
+ return;
+
+ FNum = fopen(Path, "rb");
+ FILE_GET(FNum, -1, &BMFH, sizeof(BMFH));
+ FILE_GET(FNum, -1, &BMIH, sizeof(BMIH));
+ ReDimArrays();
+ {
+ if (BMIH.biCompression != 0)
+ {
+ Err.Raise(600, "BitMapObject", "Cannot read compressed BMP files");
+ fclose(FNum);
+ return;
+ }
+
+ if (BMIH.biBitCount < 9)
+ {
+ FILE_GET(FNum, -1, &ColorTable, sizeof(ColorTable));
+ }
+
+ }
+ FILE_GET(FNum, 1 + BMFH.bfOffBits, &ImageDataBytes, sizeof(ImageDataBytes));
+ fclose(FNum);
+ if (BMIH.biBitCount < 9)
+ ConvertToVBPalette();
+}
+
+void BitMapObject_SaveToFile(char *Path)
+{
+ long FNum;
+
+ BMFH.bfOffBits = Len(BMFH) + Len(BMIH);
+ if (BMIH.biBitCount < 9)
+ BMFH.bfOffBits = BMFH.bfOffBits + ((1 << BMIH.biBitCount)) * Len(ColorTable[0]);
+
+ BMIH.biSizeImage = Get_LineLength() * BMIH.biHeight;
+ BMFH.bfSize = BMFH.bfOffBits + BMIH.biSizeImage;
+ FNum = FreeFile();
+ FNum = fopen(Path, "wb");
+ FILE_PUT(FNum, -1, &BMFH, sizeof(BMFH));
+ FILE_PUT(FNum, -1, &BMIH, sizeof(BMIH));
+ if (BMIH.biBitCount < 9)
+ {
+ FILE_PUT(FNum, -1, &ColorTable, sizeof(ColorTable));
+ }
+
+ FILE_PUT(FNum, -1, &ImageDataBytes, sizeof(ImageDataBytes));
+ fclose(FNum);
+}
+
+static void ConvertToVBPalette()
+{
+ long ColMax, i;
+
+ ColMax = UBound(ColorTable);
+ for (i = 0; i <= ColMax; i++)
+ {
+ {
+ VBPalette[i] = RGB(ColorTable[i].rgbRed, ColorTable[i].rgbGreen, ColorTable[i].rgbBlue);
+ }
+ }
+}
+
+static void ReDimArrays()
+{
+ {
+ if (BMIH.biBitCount < 9)
+ {
+ BMIH.biClrUsed = (1 << BMIH.biBitCount);
+ ColorTable = REDIM_1D(sizeof(RGBQUADType), 0, BMIH.biClrUsed - 1);
+ VBPalette = REDIM_1D(sizeof(long), 0, BMIH.biClrUsed - 1);
+ }
+
+ if (0 < Get_LineLength() && 0 < BMIH.biHeight)
+ {
+ ImageDataBytes = REDIM_2D(sizeof(byte), 0, Get_LineLength() - 1, 0, BMIH.biHeight - 1);
+ }
+
+ }
+}
+
+long BitMapObject_Get_Palette(long Index)
+{
+ long Palette;
+
+ Palette = VBPalette[Index];
+
+ return Palette;
+}
+
+void BitMapObject_Let_Palette(long Index, long NewVal)
+{
+ VBPalette[Index] = NewVal & 0xFFFFFF;
+ {
+ ColorTable[Index].rgbRed = (NewVal & 0xFF) / 0x1;
+ ColorTable[Index].rgbGreen = (NewVal & 0xFF00) / 0x100;
+ ColorTable[Index].rgbBlue = (NewVal & 0xFF0000) / 0x10000;
+ }
+}
+
+long BitMapObject_Get_ColorsUsed()
+{
+ long ColorsUsed;
+
+ if (BMIH.biBitCount < 9)
+ {
+ ColorsUsed = (1 << BMIH.biBitCount);
+ }
+ else
+ {
+ ColorsUsed = 0;
+ }
+
+ return ColorsUsed;
+}
+
+long BitMapObject_Get_ColorIndex(long X, long Y)
+{
+ long ColorIndex;
+
+ long ColIndex, NewX, BitPos, nY;
+
+ if (8 < BMIH.biBitCount)
+ {
+ Err.Raise(600, "BitmapObject", "I have ! Palette in this ColorDepthMode");
+ ColorIndex = -1;
+ return ColorIndex;
+ }
+
+ nY = BMIH.biHeight - 1 - Y;
+ switch (BMIH.biBitCount)
+ {
+ case 1:
+ ColIndex = ImageDataBytes[X / 8, nY];
+ BitPos = 7 - (X % 8);
+ NewX = (1 << BitPos);
+ if ((NewX && ColIndex) == 0)
+ {
+ ColorIndex = 0;
+ }
+ else
+ {
+ ColorIndex = 1;
+ }
+
+ break;
+
+ case 4:
+ ColIndex = ImageDataBytes[X / 2, nY];
+ if ((X % 2) == 0)
+ {
+ ColorIndex = (ColIndex & 0xF0) / 0x10;
+ }
+ else
+ {
+ ColorIndex = (ColIndex & 0xF);
+ }
+
+ break;
+
+ case 8:
+ ColorIndex = ImageDataBytes[X, nY];
+ break;
+
+ default:
+ Err.Raise(600, "BitmapObject", "Invalid bpx value");
+ break;
+ }
+
+ return ColorIndex;
+}
+
+void BitMapObject_Let_ColorIndex(long X, long Y, long ColorIndex)
+{
+ long ColIndex, ByteVal, NewX, BitPos, nY;
+
+ if (8 < BMIH.biBitCount)
+ {
+ Err.Raise(600, "BitmapObject", "I have ! Palette in this ColorDepthMode");
+ return;
+ }
+
+ nY = BMIH.biHeight - 1 - Y;
+ switch (BMIH.biBitCount)
+ {
+ case 1:
+ ByteVal = ImageDataBytes[X / 8, nY];
+ BitPos = 7 - (X % 8);
+ NewX = (1 << BitPos);
+ ColIndex = ColorIndex * NewX;
+ if (ColIndex == 0)
+ {
+ ByteVal = (ByteVal & (! NewX));
+ }
+ else
+ {
+ ByteVal = (ByteVal | NewX);
+ }
+
+ ImageDataBytes[X / 8, nY] = ByteVal;
+ break;
+
+ case 4:
+ ByteVal = ImageDataBytes[X / 2, nY];
+ if ((X % 2) == 0)
+ {
+ ByteVal = (ByteVal & 0xF) + ColorIndex * 0x10;
+ }
+ else
+ {
+ ByteVal = (ByteVal & 0xF0) + ColorIndex;
+ }
+
+ ImageDataBytes[X / 2, nY] = ByteVal;
+ break;
+
+ case 8:
+ ImageDataBytes[X, nY] = ColorIndex;
+ break;
+
+ case 24:
+ Err.Raise(600, "BitmapObject", "Invalid bpx value");
+ break;
+ }
+}
+
+long BitMapObject_Get_Point(long X, long Y)
+{
+ long Point;
+
+ long ColIndex, NewX, BitPos, nY;
+
+ nY = BMIH.biHeight - 1 - Y;
+ switch (BMIH.biBitCount)
+ {
+ case 1:
+ ColIndex = ImageDataBytes[X / 8, nY];
+ BitPos = 7 - (X % 8);
+ NewX = (1 << BitPos);
+ if ((NewX && ColIndex) == 0)
+ {
+ ColIndex = 0;
+ }
+ else
+ {
+ ColIndex = 1;
+ }
+
+ Point = VBPalette[ColIndex];
+ break;
+
+ case 4:
+ ColIndex = ImageDataBytes[X / 2, nY];
+ if ((X % 2) == 0)
+ {
+ ColIndex = (ColIndex & 0xF0) / 0x10;
+ }
+ else
+ {
+ ColIndex = (ColIndex & 0xF);
+ }
+
+ Point = VBPalette[ColIndex];
+ break;
+
+ case 8:
+ ColIndex = ImageDataBytes[X, nY];
+ Point = VBPalette[ColIndex];
+ break;
+
+ case 24:
+ NewX = 3 * X;
+ Point = ImageDataBytes[NewX, nY] * 0x10000;
+ Point = Point + ImageDataBytes[NewX + 1, nY] * 0x100;
+ Point = Point + ImageDataBytes[NewX + 2, nY];
+ break;
+
+ default:
+ Err.Raise(600, "BitmapObject", "Invalid bpx value");
+ break;
+ }
+
+ return Point;
+}
+
+void BitMapObject_Let_Point(long X, long Y, long NewColor)
+{
+ long ColIndex, ByteVal, NewX, BitPos, nY;
+
+ nY = BMIH.biHeight - 1 - Y;
+ switch (BMIH.biBitCount)
+ {
+ case 1:
+ ColIndex = GetPaletteIndex(NewColor);
+ ByteVal = ImageDataBytes[X / 8, nY];
+ BitPos = 7 - (X % 8);
+ NewX = (1 << BitPos);
+ ColIndex = ColIndex * NewX;
+ if (ColIndex == 0)
+ {
+ ByteVal = (ByteVal & (! NewX));
+ }
+ else
+ {
+ ByteVal = (ByteVal | NewX);
+ }
+
+ ImageDataBytes[X / 8, nY] = ByteVal;
+ break;
+
+ case 4:
+ ColIndex = GetPaletteIndex(NewColor);
+ ByteVal = ImageDataBytes[X / 2, nY];
+ if ((X % 2) == 0)
+ {
+ ByteVal = (ByteVal & 0xF) + ColIndex * 0x10;
+ }
+ else
+ {
+ ByteVal = (ByteVal & 0xF0) + ColIndex;
+ }
+
+ ImageDataBytes[X / 2, nY] = ByteVal;
+ break;
+
+ case 8:
+ ImageDataBytes[X, nY] = GetPaletteIndex(NewColor);
+ break;
+
+ case 24:
+ NewX = 3 * X;
+ ImageDataBytes[NewX, nY] = (NewColor & 0xFF0000) / 0x10000; // B
+ ImageDataBytes[NewX + 1, nY] = (NewColor & 0xFF00) / 0x100; // G
+ ImageDataBytes[NewX + 2, nY] = (NewColor & 0xFF); // R
+ break;
+
+ default:
+ Err.Raise(600, "BitmapObject", "Invalid bpx value");
+ break;
+ }
+}
+
+int BitMapObject_GetPaletteIndex(long Color)
+{
+ int GetPaletteIndex;
+
+ long i, ColMax;
+
+ ColMax = UBound(VBPalette);
+ for (i = 0; i <= ColMax; i++)
+ {
+ if (VBPalette[i] == Color)
+ break;
+ }
+
+ if (ColMax < i) // Error - Color not in Palette!
+ i = -1;
+
+ GetPaletteIndex = i;
+
+ return GetPaletteIndex;
+}
+
+long BitMapObject_Get_Width()
+{
+ long Width;
+
+ Width = BMIH.biWidth;
+
+ return Width;
+}
+
+long BitMapObject_Get_Height()
+{
+ long Height;
+
+ Height = BMIH.biHeight;
+
+ return Height;
+}
+
+BitMapObject BitMapObject_GetStretchCopy(float StretchVal)
+{
+ BitMapObject GetStretchCopy;
+
+ long nWidth, nHeight, iX, iY;
+
+ // GetStretchCopy = New BitMapObject; // (handle this later, if needed)
+ nWidth = StretchVal * BMIH.biWidth;
+ nHeight = StretchVal * BMIH.biHeight;
+ GetStretchCopy.CreateAtSize(nWidth, nHeight, CLng(BMIH.biBitCount));
+ nWidth = nWidth - 1;
+ nHeight = nHeight - 1;
+ for (iX = 0; iX <= BMIH.biClrUsed - 1; iX++)
+ {
+ GetStretchCopy.Let_Palette(iX, Palette(iX));
+ }
+
+ for (iY = 0; iY <= nHeight; iY++)
+ {
+ for (iX = 0; iX <= nWidth; iX++)
+ {
+ GetStretchCopy.Let_ColorIndex(iX, iY, ColorIndex(Int(iX / StretchVal), Int(iY / StretchVal)));
+ }
+ }
+
+ return GetStretchCopy;
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// BitMapObject.h
+// ----------------------------------------------------------------------------
+
+#ifndef BITMAPOBJECT_H
+#define BITMAPOBJECT_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+#ifndef HAS_BitmapFileHeaderType
+typedef struct // { /* bmfh */
+{
+ byte bfTypeB;
+ byte bfTypeM;
+ long bfSize;
+ int bfReserved1;
+ int bfReserved2;
+ long bfOffBits;
+} BitmapFileHeaderType;
+#define HAS_BitmapFileHeaderType
+#endif
+
+#ifndef HAS_BitmapInfoHeaderType
+typedef struct // { /* bmih */
+{
+ long biSize;
+ long biWidth;
+ long biHeight;
+ int biPlanes;
+ int biBitCount;
+ long biCompression;
+ long biSizeImage;
+ long biXPelsPerMeter;
+ long biYPelsPerMeter;
+ long biClrUsed;
+ long biClrImportant;
+} BitmapInfoHeaderType;
+#define HAS_BitmapInfoHeaderType
+#endif
+
+#ifndef HAS_RGBQUADType
+typedef struct // { /* rgbq */
+{
+ byte rgbBlue;
+ byte rgbGreen;
+ byte rgbRed;
+ byte rgbReserved;
+} RGBQUADType;
+#define HAS_RGBQUADType
+#endif
+
+extern void BitMapObject_CreateAtSize(long XPixels, long YPixels, long BitsPerPixel);
+extern void BitMapObject_CreateFromFile(char *Path);
+extern int BitMapObject_GetPaletteIndex(long Color);
+extern BitMapObject BitMapObject_GetStretchCopy(float StretchVal);
+extern long BitMapObject_Get_ColorIndex(long X, long Y);
+extern long BitMapObject_Get_ColorsUsed();
+extern long BitMapObject_Get_Height();
+extern long BitMapObject_Get_Palette(long Index);
+extern long BitMapObject_Get_Point(long X, long Y);
+extern long BitMapObject_Get_Width();
+extern void BitMapObject_Let_ColorIndex(long X, long Y, long ColorIndex);
+extern void BitMapObject_Let_Palette(long Index, long NewVal);
+extern void BitMapObject_Let_Point(long X, long Y, long NewColor);
+extern void BitMapObject_SaveToFile(char *Path);
+
+#endif /* BITMAPOBJECT_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// BugsTerminals.c
+// ----------------------------------------------------------------------------
+
+#include "BugsTerminals.h"
+
+static char *VB_Name = "modBugTerminal";
+// --- Option Explicit
+
+long GetTickCount();
+
+byte *TerminalState;
+int TerminalMaxCycles;
+#define aniTerminal (0x80)
+
+// ==========================================================================
+// SUBROUTINE
+// Animate bugs
+// ==========================================================================
+
+int subAnimateBugs(int si)
+{
+ int subAnimateBugs;
+
+ int ax, bx, cx, dx, di;
+ int ah, bh, ch, dh, al, bl, cl, dl;
+
+ if (fiBug != LowByte(PlayField16[si]))
+ return subAnimateBugs;
+
+ if (0 != (TimerVar & 3))
+ return subAnimateBugs;
+
+ bl = SgnHighByte(PlayField16[si]); // get and increment sequence#
+ bl = bl + 1;
+ if (bl >= 0xE)
+ {
+ bl = subGetRandomNumber(); // generate new random number
+ bl = -((bl & 0x3F) + 0x20);
+ }
+
+ MovHighByte(&PlayField16[si], bl); // save sequence#
+ if (bl < 0) // bug sleeps / is inactive
+ return subAnimateBugs;
+
+ // now the bug is active! Beware Murphy!
+ if ((ByteMask && PlayField16[si - FieldWidth - 1]) == fiMurphy)
+ goto markPlaySound;
+
+ if ((ByteMask && PlayField16[si - FieldWidth]) == fiMurphy)
+ goto markPlaySound;
+
+ if ((ByteMask && PlayField16[si - FieldWidth + 1]) == fiMurphy)
+ goto markPlaySound;
+
+ if ((ByteMask && PlayField16[si - 1]) == fiMurphy)
+ goto markPlaySound;
+
+ if ((ByteMask && PlayField16[si + 1]) == fiMurphy)
+ goto markPlaySound;
+
+ if ((ByteMask && PlayField16[si + FieldWidth - 1]) == fiMurphy)
+ goto markPlaySound;
+
+ if ((ByteMask && PlayField16[si + FieldWidth]) == fiMurphy)
+ goto markPlaySound;
+
+ if ((ByteMask && PlayField16[si + FieldWidth + 1]) == fiMurphy)
+ goto markPlaySound;
+
+ goto markDisplay;
+
+markPlaySound:
+ subSoundFXBug(); // play dangerous sound
+
+markDisplay:
+ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ cx = aniBug[bl];
+ StretchedSprites.BltEx(GetStretchX(si), GetStretchY(si), cx);
+ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ return subAnimateBugs;
+} // subAnimateBugs
+
+// ==========================================================================
+// SUBROUTINE
+// Animate terminals
+// ==========================================================================
+int subAnimateTerminals(int si)
+{
+ int subAnimateTerminals;
+
+ int bl, ax, al, X, Y;
+
+ if (LowByte(PlayField16[si]) != fiTerminal)
+ return subAnimateTerminals;
+
+ bl = HighByte(PlayField16[si]);
+ if ((bl & 0x80) == 0x80)
+ bl = (bl | 0xFF00);
+
+ bl = bl + 1;
+ if (bl <= 0)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ return subAnimateTerminals;
+ }
+
+ bl = -(subGetRandomNumber() & TerminalMaxCycles); // generate new random number
+ MovHighByte(&PlayField16[si], bl); // save new sequence#
+ bl = TerminalState[si] + 1;
+ if (bl == 8)
+ {
+ bl = 0;
+ }
+ else if (15 < bl)
+ {
+ bl = 8;
+ }
+
+ TerminalState[si] = bl;
+ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ al = aniTerminal + bl;
+ X = GetStretchX(si);
+ Y = GetStretchY(si);
+ StretchedSprites.BltEx(X, Y, al);
+ // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ return subAnimateTerminals;
+} // subAnimateElectrons
+
+// ==========================================================================
+// SUBROUTINE
+// Randomize random number generator
+// ==========================================================================
+
+int subRandomize()
+{
+ int subRandomize;
+
+ long Tick, Tmp;
+
+ Tick = GetTickCount();
+ Tmp = ((Tick ^ (long)(Tick / (1 << 16))) & 0xFFFF);
+ RandomSeed = 0x7FFF & Tmp;
+ if ((Tmp & 0x8000) != 0)
+ RandomSeed = RandomSeed | 0x8000;
+
+ return subRandomize;
+} // subRandomize
+
+
+// ==========================================================================
+// SUBROUTINE
+// Generate new random number, first method (see also sub_g_8580)
+// ==========================================================================
+
+int subGetRandomNumber()
+{
+ int subGetRandomNumber;
+
+ long Tmp, RSeed;
+
+ RSeed = (long)(0x7FFF & RandomSeed);
+ if (0x8000 == (RandomSeed & 0x8000))
+ RSeed = RSeed | 0x8000;
+
+ Tmp = 0xFFFF & (((0x5E5 * RandomSeed) & 0xFFFF) + 0x31);
+ RandomSeed = 0x7FFF & Tmp;
+ if ((Tmp & 0x8000) != 0)
+ RandomSeed = RandomSeed | 0x8000;
+
+ subGetRandomNumber = Tmp / 2;
+ // Mov ax, randomseed
+ // Mov bx, &H5E5
+ // mul bx ' dx:ax = reg * ax
+ // Add ax, &H31
+ // Mov randomseed, ax
+ // shr ax,1
+
+ return subGetRandomNumber;
+} // subGetRandomNumber
+
--- /dev/null
+// ----------------------------------------------------------------------------
+// BugsTerminals.h
+// ----------------------------------------------------------------------------
+
+#ifndef BUGSTERMINALS_H
+#define BUGSTERMINALS_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern int subAnimateBugs(int si);
+extern int subAnimateTerminals(int si);
+extern int subGetRandomNumber();
+extern int subRandomize();
+
+extern byte *TerminalState;
+extern int TerminalMaxCycles;
+
+#endif /* BUGSTERMINALS_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// Capture.c
+// ----------------------------------------------------------------------------
+
+#include "Capture.h"
+
+static char *VB_Name = "CaptureModule";
+// --------------------------------------------------------------------
+// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+//
+// Visual Basic 4.0 16/32 Capture Routines
+//
+// This module contains several routines for capturing windows into a
+// picture. All the routines work on both 16 and 32 bit Windows
+// platforms.
+// The routines also have palette support.
+//
+// CreateBitmapPicture - Creates a picture object from a bitmap and
+// palette.
+// CaptureWindow - Captures any window given a window handle.
+// CaptureActiveWindow - Captures the active window on the desktop.
+// CaptureForm - Captures the entire form.
+// CaptureClient - Captures the client area of a form.
+// CaptureScreen - Captures the entire screen.
+// PrintPictureToFitPage - prints any picture as big as possible on
+// the page.
+//
+// NOTES
+// - No error trapping is included in these routines.
+// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+//
+// --- Option Explicit
+// --- Option Base 0
+
+// ::: #ifndef HAS_PALETTEENTRY
+// ::: typedef struct
+// ::: {
+// ::: byte peRed;
+// ::: byte peGreen;
+// ::: byte peBlue;
+// ::: byte peFlags;
+// ::: } PALETTEENTRY;
+// ::: #define HAS_PALETTEENTRY
+// ::: #endif
+
+// ::: #ifndef HAS_LOGPALETTE
+// ::: typedef struct
+// ::: {
+// ::: int palVersion;
+// ::: int palNumEntries;
+// ::: PALETTEENTRY palPalEntry[255]; // Enough for 256 colors.
+// ::: } LOGPALETTE;
+// ::: #define HAS_LOGPALETTE
+// ::: #endif
+
+// ::: #ifndef HAS_GUID
+// ::: typedef struct
+// ::: {
+// ::: long Data1;
+// ::: int Data2;
+// ::: int Data3;
+// ::: byte Data4[7];
+// ::: } GUID;
+// ::: #define HAS_GUID
+// ::: #endif
+
+#if Win32
+
+#define RASTERCAPS (38)
+#define RC_PALETTE (0x100)
+#define SIZEPALETTE (104)
+
+// ::: #ifndef HAS_RECT
+// ::: typedef struct
+// ::: {
+// ::: long left;
+// ::: long top;
+// ::: long right;
+// ::: long bottom;
+// ::: } RECT;
+// ::: #define HAS_RECT
+// ::: #endif
+
+long CreateCompatibleDC(long hDC);
+long CreateCompatibleBitmap(long hDC, long nWidth, long nHeight);
+long GetDeviceCaps(long hDC, long iCapabilitiy);
+long GetSystemPaletteEntries(long hDC, long wStartIndex, long wNumEntries, PALETTEENTRY lpPaletteEntries);
+long CreatePalette(LOGPALETTE lpLogPalette);
+long SelectObject(long hDC, long hObject);
+long BitBlt(long hDCDest, long XDest, long YDest, long nWidth, long nHeight, long hDCSrc, long XSrc, long YSrc, long dwRop);
+long DeleteDC(long hDC);
+long GetForegroundWindow();
+long SelectPalette(long hDC, long hPalette, long bForceBackground);
+long RealizePalette(long hDC);
+long GetWindowDC(long hWnd);
+long GetDC(long hWnd);
+long GetWindowRect(long hWnd, RECT lpRect);
+long ReleaseDC(long hWnd, long hDC);
+long GetDesktopWindow();
+
+// ::: #ifndef HAS_PicBmp
+// ::: typedef struct
+// ::: {
+// ::: long Size;
+// ::: long Type;
+// ::: long hBmp;
+// ::: long hPal;
+// ::: long Reserved;
+// ::: } PicBmp;
+// ::: #define HAS_PicBmp
+// ::: #endif
+
+long OleCreatePictureIndirect(PicBmp PicDesc, GUID RefIID, long fPictureOwnsHandle, IPicture IPic);
+
+#elif Win16
+
+#define RASTERCAPS (38)
+#define RC_PALETTE (0x100)
+#define SIZEPALETTE (104)
+
+// ::: #ifndef HAS_RECT
+// ::: typedef struct
+// ::: {
+// ::: int left;
+// ::: int top;
+// ::: int right;
+// ::: int bottom;
+// ::: } RECT;
+// ::: #define HAS_RECT
+// ::: #endif
+
+int CreateCompatibleDC(int hDC);
+int CreateCompatibleBitmap(int hDC, int nWidth, int nHeight);
+int GetDeviceCaps(int hDC, int iCapabilitiy);
+int GetSystemPaletteEntries(int hDC, int wStartIndex, int wNumEntries, PALETTEENTRY lpPaletteEntries);
+int CreatePalette(LOGPALETTE lpLogPalette);
+int SelectObject(int hDC, int hObject);
+int BitBlt(int hDCDest, int XDest, int YDest, int nWidth, int nHeight, int hDCSrc, int XSrc, int YSrc, long dwRop);
+int DeleteDC(int hDC);
+int GetForegroundWindow();
+int SelectPalette(int hDC, int hPalette, int bForceBackground);
+int RealizePalette(int hDC);
+int GetWindowDC(int hWnd);
+int GetDC(int hWnd);
+int GetWindowRect(int hWnd, RECT lpRect);
+int ReleaseDC(int hWnd, int hDC);
+int GetDesktopWindow();
+
+// ::: #ifndef HAS_PicBmp
+// ::: typedef struct
+// ::: {
+// ::: int Size;
+// ::: int Type;
+// ::: int hBmp;
+// ::: int hPal;
+// ::: int Reserved;
+// ::: } PicBmp;
+// ::: #define HAS_PicBmp
+// ::: #endif
+
+int OleCreatePictureIndirect(PicBmp PictDesc, GUID RefIID, int fPictureOwnsHandle, IPicture IPic);
+
+#endif
+
+// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+//
+// CreateBitmapPicture
+// - Creates a bitmap type Picture object from a bitmap and
+// palette.
+//
+// hBmp
+// - Handle to a bitmap.
+//
+// hPal
+// - Handle to a Palette.
+// - Can be null if the bitmap doesn't use a palette.
+//
+// Returns
+// - Returns a Picture object containing the bitmap.
+// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+//
+#if Win32
+Picture CreateBitmapPicture(long hBmp, long hPal)
+{
+ Picture CreateBitmapPicture;
+
+ long r;
+
+#elif Win16
+Picture CreateBitmapPicture(int hBmp, int hPal)
+{
+ Picture CreateBitmapPicture;
+
+ int r;
+
+#endif
+ PicBmp pic;
+
+ // IPicture requires a reference to "Standard OLE Types."
+ IPicture IPic;
+ GUID IID_IDispatch;
+
+ // Fill in with IDispatch Interface ID.
+ {
+ IID_IDispatch.Data1 = 0x20400;
+ IID_IDispatch.Data4[0] = 0xC0;
+ IID_IDispatch.Data4[7] = 0x46;
+ }
+
+ // Fill Pic with necessary parts.
+ {
+ pic.Size = Len(pic); // Length of structure.
+ pic.Type = vbPicTypeBitmap; // Type of Picture (bitmap).
+ pic.hBmp = hBmp; // Handle to bitmap.
+ pic.hPal = hPal; // Handle to palette (may be null).
+ }
+
+ // Create Picture object.
+ r = OleCreatePictureIndirect(pic, IID_IDispatch, 1, IPic);
+
+ // Return the new Picture object.
+ CreateBitmapPicture = IPic;
+
+ return CreateBitmapPicture;
+}
+
+// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+//
+// CaptureWindow
+// - Captures any portion of a window.
+//
+// hWndSrc
+// - Handle to the window to be captured.
+//
+// Client
+// - If True CaptureWindow captures from the client area of the
+// window.
+// - If False CaptureWindow captures from the entire window.
+//
+// LeftSrc, TopSrc, WidthSrc, HeightSrc
+// - Specify the portion of the window to capture.
+// - Dimensions need to be specified in pixels.
+//
+// Returns
+// - Returns a Picture object containing a bitmap of the specified
+// portion of the window that was captured.
+// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+// '''''
+//
+#if Win32
+Picture CaptureWindow(long hWndSrc, boolean Client, long LeftSrc, long TopSrc, long WidthSrc, long HeightSrc)
+{
+ Picture CaptureWindow;
+
+ long hDCMemory;
+ long hBmp;
+ long hBmpPrev;
+ long r;
+ long hDCSrc;
+ long hPal;
+ long hPalPrev;
+ long RasterCapsScrn;
+ long HasPaletteScrn;
+ long PaletteSizeScrn;
+
+#elif Win16
+Picture CaptureWindow(int hWndSrc, boolean Client, int LeftSrc, int TopSrc, long WidthSrc, long HeightSrc)
+{
+ Picture CaptureWindow;
+
+ int hDCMemory;
+ int hBmp;
+ int hBmpPrev;
+ int r;
+ int hDCSrc;
+ int hPal;
+ int hPalPrev;
+ int RasterCapsScrn;
+ int HasPaletteScrn;
+ int PaletteSizeScrn;
+
+#endif
+ LOGPALETTE LogPal;
+
+ // Depending on the value of Client get the proper device context.
+ if (Client)
+ {
+ hDCSrc = GetDC(hWndSrc); // Get device context for client area.
+ }
+ else
+ {
+ hDCSrc = GetWindowDC(hWndSrc); // Get device context for entire
+ // window.
+ }
+
+ // Create a memory device context for the copy process.
+ hDCMemory = CreateCompatibleDC(hDCSrc);
+ // Create a bitmap and place it in the memory DC.
+ hBmp = CreateCompatibleBitmap(hDCSrc, WidthSrc, HeightSrc);
+ hBmpPrev = SelectObject(hDCMemory, hBmp);
+
+ // Get screen properties.
+ RasterCapsScrn = GetDeviceCaps(hDCSrc, RASTERCAPS); // Raster
+ // capabilities.
+ HasPaletteScrn = RasterCapsScrn & RC_PALETTE; // Palette
+ // support.
+ PaletteSizeScrn = GetDeviceCaps(hDCSrc, SIZEPALETTE); // Size of
+ // palette.
+
+ // If the screen has a palette make a copy and realize it.
+ if (HasPaletteScrn && (PaletteSizeScrn == 256))
+ {
+ // Create a copy of the system palette.
+ LogPal.palVersion = 0x300;
+ LogPal.palNumEntries = 256;
+ r = GetSystemPaletteEntries(hDCSrc, 0, 256, LogPal.palPalEntry[0]);
+ hPal = CreatePalette(LogPal);
+ // Select the new palette into the memory DC and realize it.
+ hPalPrev = SelectPalette(hDCMemory, hPal, 0);
+ r = RealizePalette(hDCMemory);
+ }
+
+ // Copy the on-screen image into the memory DC.
+ r = BitBlt(hDCMemory, 0, 0, WidthSrc, HeightSrc, hDCSrc, LeftSrc, TopSrc, vbSrcCopy);
+
+ // Remove the new copy of the on-screen image.
+ hBmp = SelectObject(hDCMemory, hBmpPrev);
+
+ // If the screen has a palette get back the palette that was
+ // selected in previously.
+ if (HasPaletteScrn && (PaletteSizeScrn == 256))
+ {
+ hPal = SelectPalette(hDCMemory, hPalPrev, 0);
+ }
+
+ // Release the device context resources back to the system.
+ r = DeleteDC(hDCMemory);
+ r = ReleaseDC(hWndSrc, hDCSrc);
+
+ // Call CreateBitmapPicture to create a picture object from the
+ // bitmap and palette handles. Then return the resulting picture
+ // object.
+
+ CaptureWindow = CreateBitmapPicture(hBmp, hPal);
+
+ return CaptureWindow;
+}
+
+// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+//
+// CaptureScreen
+// - Captures the entire screen.
+//
+// Returns
+// - Returns a Picture object containing a bitmap of the screen.
+// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+//
+Picture CaptureScreen()
+{
+ Picture CaptureScreen;
+
+#if Win32
+ long hWndScreen;
+
+#elif Win16
+ int hWndScreen;
+
+#endif
+
+ // Get a handle to the desktop window.
+ hWndScreen = GetDesktopWindow();
+
+ // Call CaptureWindow to capture the entire desktop give the handle
+ // and return the resulting Picture object.
+
+ CaptureScreen = CaptureWindow(hWndScreen, False, 0, 0, Screen.Width / Screen.TwipsPerPixelX, Screen.Height / Screen.TwipsPerPixelY);
+
+ return CaptureScreen;
+}
+
+// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+//
+// CaptureForm
+// - Captures an entire form including title bar and border.
+//
+// frmSrc
+// - The Form object to capture.
+//
+// Returns
+// - Returns a Picture object containing a bitmap of the entire
+// form.
+// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+//
+Picture CaptureForm(Form frmSrc)
+{
+ Picture CaptureForm;
+
+ // Call CaptureWindow to capture the entire form given its window
+ // handle and then return the resulting Picture object.
+ CaptureForm = CaptureWindow(frmSrc.hWnd, False, 0, 0, frmSrc.ScaleX(frmSrc.Width, vbTwips, vbPixels), frmSrc.ScaleY(frmSrc.Height, vbTwips, vbPixels));
+
+ return CaptureForm;
+}
+
+// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+//
+// CaptureClient
+// - Captures the client area of a form.
+//
+// frmSrc
+// - The Form object to capture.
+//
+// Returns
+// - Returns a Picture object containing a bitmap of the form's
+// client area.
+// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+//
+Picture CaptureClient(Form frmSrc)
+{
+ Picture CaptureClient;
+
+ // Call CaptureWindow to capture the client area of the form given
+ // its window handle and return the resulting Picture object.
+ CaptureClient = CaptureWindow(frmSrc.hWnd, True, 0, 0, frmSrc.ScaleX(frmSrc.ScaleWidth, frmSrc.ScaleMode, vbPixels), frmSrc.ScaleY(frmSrc.ScaleHeight, frmSrc.ScaleMode, vbPixels));
+
+ return CaptureClient;
+}
+
+// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+//
+// CaptureActiveWindow
+// - Captures the currently active window on the screen.
+//
+// Returns
+// - Returns a Picture object containing a bitmap of the active
+// window.
+// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+//
+Picture CaptureActiveWindow()
+{
+ Picture CaptureActiveWindow;
+
+#if Win32
+ long hWndActive;
+ long r;
+
+#elif Win16
+ int hWndActive;
+ int r;
+
+#endif
+ RECT RectActive;
+
+ // Get a handle to the active/foreground window.
+ hWndActive = GetForegroundWindow();
+
+ // Get the dimensions of the window.
+ r = GetWindowRect(hWndActive, RectActive);
+
+ // Call CaptureWindow to capture the active window given its
+ // handle and return the Resulting Picture object.
+ CaptureActiveWindow = CaptureWindow(hWndActive, False, 0, 0, RectActive.right - RectActive.left, RectActive.bottom - RectActive.top);
+
+ return CaptureActiveWindow;
+}
+
+// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+//
+// PrintPictureToFitPage
+// - Prints a Picture object as big as possible.
+//
+// Prn
+// - Destination Printer object.
+//
+// Pic
+// - Source Picture object.
+// ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+//
+void PrintPictureToFitPage(Printer Prn, Picture pic)
+{
+ #define vbHiMetric (8)
+ double PicRatio;
+ double PrnWidth;
+ double PrnHeight;
+ double PrnRatio;
+ double PrnPicWidth;
+ double PrnPicHeight;
+
+ // Determine if picture should be printed in landscape or portrait
+ // and set the orientation.
+ if (pic.Height >= pic.Width)
+ {
+ Prn.Orientation = vbPRORPortrait; // Taller than wide.
+ }
+ else
+ {
+ Prn.Orientation = vbPRORLandscape; // Wider than tall.
+ }
+
+ // Calculate device independent Width-to-Height ratio for picture.
+ PicRatio = pic.Width / pic.Height;
+
+ // Calculate the dimentions of the printable area in HiMetric.
+ PrnWidth = Prn.ScaleX(Prn.ScaleWidth, Prn.ScaleMode, vbHiMetric);
+ PrnHeight = Prn.ScaleY(Prn.ScaleHeight, Prn.ScaleMode, vbHiMetric);
+ // Calculate device independent Width to Height ratio for printer.
+ PrnRatio = PrnWidth / PrnHeight;
+
+ // Scale the output to the printable area.
+ if (PicRatio >= PrnRatio)
+ {
+ // Scale picture to fit full width of printable area.
+ PrnPicWidth = Prn.ScaleX(PrnWidth, vbHiMetric, Prn.ScaleMode);
+ PrnPicHeight = Prn.ScaleY(PrnWidth / PicRatio, vbHiMetric, Prn.ScaleMode);
+ }
+ else
+ {
+ // Scale picture to fit full height of printable area.
+ PrnPicHeight = Prn.ScaleY(PrnHeight, vbHiMetric, Prn.ScaleMode);
+ PrnPicWidth = Prn.ScaleX(PrnHeight * PicRatio, vbHiMetric, Prn.ScaleMode);
+ }
+
+ // Print the picture using the PaintPicture method.
+ Prn_PaintPicture(pic, 0, 0, PrnPicWidth, PrnPicHeight);
+}
+
+// --------------------------------------------------------------------
+
--- /dev/null
+// ----------------------------------------------------------------------------
+// Capture.h
+// ----------------------------------------------------------------------------
+
+#ifndef CAPTURE_H
+#define CAPTURE_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+#ifndef HAS_PALETTEENTRY
+typedef struct
+{
+ byte peRed;
+ byte peGreen;
+ byte peBlue;
+ byte peFlags;
+} PALETTEENTRY;
+#define HAS_PALETTEENTRY
+#endif
+
+#ifndef HAS_LOGPALETTE
+typedef struct
+{
+ int palVersion;
+ int palNumEntries;
+ PALETTEENTRY palPalEntry[255]; // Enough for 256 colors.
+} LOGPALETTE;
+#define HAS_LOGPALETTE
+#endif
+
+#ifndef HAS_GUID
+typedef struct
+{
+ long Data1;
+ int Data2;
+ int Data3;
+ byte Data4[7];
+} GUID;
+#define HAS_GUID
+#endif
+
+#if Win32
+
+#ifndef HAS_RECT
+typedef struct
+{
+ long left;
+ long top;
+ long right;
+ long bottom;
+} RECT;
+#define HAS_RECT
+#endif
+
+#ifndef HAS_PicBmp
+typedef struct
+{
+ long Size;
+ long Type;
+ long hBmp;
+ long hPal;
+ long Reserved;
+} PicBmp;
+#define HAS_PicBmp
+#endif
+
+#elif Win16
+
+#ifndef HAS_RECT
+typedef struct
+{
+ int left;
+ int top;
+ int right;
+ int bottom;
+} RECT;
+#define HAS_RECT
+#endif
+
+#ifndef HAS_PicBmp
+typedef struct
+{
+ int Size;
+ int Type;
+ int hBmp;
+ int hPal;
+ int Reserved;
+} PicBmp;
+#define HAS_PicBmp
+#endif
+
+#endif
+
+#if Win32
+
+
+
+#elif Win16
+
+
+
+#endif
+
+#if Win32
+
+
+
+#elif Win16
+
+
+
+#endif
+
+#if Win32
+
+
+
+#elif Win16
+
+
+
+#endif
+
+#if Win32
+
+
+
+#elif Win16
+
+
+
+#endif
+
+extern Picture CaptureActiveWindow();
+extern Picture CaptureClient(Form frmSrc);
+extern Picture CaptureForm(Form frmSrc);
+extern Picture CaptureScreen();
+extern Picture CaptureWindow(int hWndSrc, boolean Client, int LeftSrc, int TopSrc, long WidthSrc, long HeightSrc);
+extern Picture CreateBitmapPicture(int hBmp, int hPal);
+extern void PrintPictureToFitPage(Printer Prn, Picture pic);
+
+#endif /* CAPTURE_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// DDScrollBuffer.c
+// ----------------------------------------------------------------------------
+
+#include "DDScrollBuffer.h"
+
+#include <math.h>
+
+
+// --- VERSION 1.0 CLASS
+// --- BEGIN
+// --- MultiUse = -1 'True // True
+// --- Persistable = 0 'NotPersistable // NotPersistable
+// --- DataBindingBehavior = 0 'vbNone // vbNone
+// --- DataSourceBehavior = 0 'vbNone // vbNone
+// --- MTSTransactionMode = 0 'NotAnMTSObject // NotAnMTSObject
+// --- END
+
+static char *VB_Name = "DDScrollBuffer";
+static boolean VB_GlobalNameSpace = False;
+static boolean VB_Creatable = True;
+static boolean VB_PredeclaredId = False;
+static boolean VB_Exposed = False;
+// --- Option Explicit
+
+// needs reference to: DirectX7 for Visual Basic Type Library
+
+DirectDrawSurface7 Buffer;
+DirectDrawSurface7 mPrimary;
+long mWidth, mHeight;
+long mhWnd;
+long mScrollX, mScrollY;
+long mDestXOff, mDestYOff;
+
+void DDScrollBuffer_Let_DestXOff(long NewVal)
+{
+ mDestXOff = NewVal;
+}
+
+long DDScrollBuffer_Get_DestXOff()
+{
+ long DestXOff;
+
+ DestXOff = mDestXOff;
+
+ return DestXOff;
+}
+
+void DDScrollBuffer_Let_DestYOff(long NewVal)
+{
+ mDestYOff = NewVal;
+}
+
+long DDScrollBuffer_Get_DestYOff()
+{
+ long DestYOff;
+
+ DestYOff = mDestYOff;
+
+ return DestYOff;
+}
+
+DirectDrawSurface7 DDScrollBuffer_Get_Surface()
+{
+ DirectDrawSurface7 Surface;
+
+ Surface = Buffer;
+
+ return Surface;
+}
+
+long DDScrollBuffer_Get_Width()
+{
+ long Width;
+
+ Width = mWidth;
+
+ return Width;
+}
+
+int DDScrollBuffer_Get_Height()
+{
+ int Height;
+
+ Height = mHeight;
+
+ return Height;
+}
+
+long DDScrollBuffer_CreateAtSize(long Width, long Height, long hWndViewPort)
+{
+ long CreateAtSize;
+
+ DDSURFACEDESC2 SD;
+
+ CreateAtSize = 0;
+ mhWnd = hWndViewPort;
+ // Create ScrollBuffer:
+ {
+ SD.lFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ SD.ddsCaps.lCaps = DDSCAPS_VIDEOMEMORY;
+ // SD.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
+ SD.LWidth = Width;
+ SD.LHeight = Height;
+ }
+
+ // --- On Error Resume Next
+ Buffer = DDraw.CreateSurface(SD);
+ if (Err.Number != 0)
+ return CreateAtSize;
+
+ // --- On Error GoTo 0
+
+ mWidth = Width;
+ mHeight = Height;
+ mScrollX = 0;
+ mScrollY = 0;
+ CreateAtSize = -1;
+
+ return CreateAtSize;
+}
+
+void DDScrollBuffer_Cls(int BackColor)
+{
+ RECT EmptyRect;
+
+ if (NoDisplayFlag)
+ return;
+
+ Buffer.BltColorFill(EmptyRect, BackColor);
+}
+
+void DDScrollBuffer_Blt()
+{
+ RECT DR, SR;
+ long tX, tY, L;
+ // RECT ERect;
+ // long Restore;
+
+ if (NoDisplayFlag)
+ return;
+
+
+ // --- On Error GoTo BltEH
+ DirectX.GetWindowRect(mhWnd, DR);
+ // --- On Error GoTo 0
+
+ {
+ tX = (DR.right - DR.left) / Stretch;
+ tY = (DR.bottom - DR.top) / Stretch;
+ }
+ {
+ SR.left = mScrollX + mDestXOff;
+ SR.top = mScrollY + mDestYOff;
+ SR.right = SR.left + tX;
+ SR.bottom = SR.top + tY;
+ // If mWidth < SR.right Then
+ // SR.right = mWidth
+ // DR.right = DR.left + Stretch * (SR.right - SR.left)
+ // End If
+ // If mHeight < SR.bottom Then
+ // SR.bottom = mHeight
+ // DR.bottom = DR.top + Stretch * (SR.bottom - SR.top)
+ // End If
+ // If (mScrollX + mDestXOff) < 0 Then
+ // SR.left = 0
+ // DR.left = DR.left - Stretch * (mScrollX + mDestXOff)
+ // End If
+ // If (mScrollY + mDestYOff) < 0 Then
+ // SR.top = 0
+ // DR.top = DR.top - Stretch * (mScrollY + mDestYOff)
+ // End If
+ }
+ // DDraw.WaitForVerticalBlank DDWAITVB_BLOCKBEGIN, 0
+ if (IS_NOTHING(&Buffer, sizeof(Buffer)))
+ return;
+
+ if (IS_NOTHING(&PrimarySurface, sizeof(PrimarySurface)))
+ return;
+
+ L = PrimarySurface_Blt(DR, Buffer, SR, DDBLT_WAIT);
+ if (L != DD_OK)
+ {
+ switch (L)
+ {
+ case DDERR_GENERIC:
+ Debug.Assert(False);
+ break;
+
+ case DDERR_INVALIDCLIPLIST:
+ Debug.Assert(False);
+ break;
+
+ case DDERR_INVALIDOBJECT:
+ Debug.Assert(False);
+ break;
+
+ case DDERR_INVALIDPARAMS:
+ Debug.Assert(False);
+ break;
+
+ case DDERR_INVALIDRECT:
+ Debug.Assert(False);
+ break;
+
+ case DDERR_NOALPHAHW:
+ Debug.Assert(False);
+ break;
+
+ case DDERR_NOBLTHW:
+ Debug.Assert(False);
+ break;
+
+ case DDERR_NOCLIPLIST:
+ Debug.Assert(False);
+ break;
+
+ case DDERR_NODDROPSHW:
+ Debug.Assert(False);
+ break;
+
+ case DDERR_NOMIRRORHW:
+ Debug.Assert(False);
+ break;
+
+ case DDERR_NORASTEROPHW:
+ Debug.Assert(False);
+ break;
+
+ case DDERR_NOROTATIONHW:
+ Debug.Assert(False);
+ break;
+
+ case DDERR_NOSTRETCHHW:
+ Debug.Assert(False);
+ break;
+
+ case DDERR_NOZBUFFERHW:
+ Debug.Assert(False);
+ break;
+
+ case DDERR_SURFACEBUSY:
+ Debug.Assert(False);
+ break;
+
+ case DDERR_SURFACELOST:
+ DDraw.RestoreAllSurfaces();
+ if (! PrimarySurface.isLost())
+ {
+ subDisplayLevel();
+ // Blt();
+ }
+
+ // RestorePrimarySurface
+ // ClipToWindow 0
+ break;
+
+ case DDERR_UNSUPPORTED:
+ Debug.Assert(False);
+ break;
+
+ case DDERR_WASSTILLDRAWING:
+ Debug.Assert(False);
+ break;
+
+ default:
+ Debug.Assert(False);
+ break;
+ }
+ }
+
+#if 0
+ // Buffer.UpdateOverlay SR, PrimarySurface, DR, DDOVER_SHOW
+ if (EditFlag)
+ FMark.RefreshMarker();
+#endif
+
+ // BltEH:
+}
+
+void DDScrollBuffer_ScrollTo(int X, int Y)
+{
+ if (NoDisplayFlag)
+ return;
+
+ X = X / Stretch;
+ Y = Y / Stretch;
+ mScrollX = X;
+ mScrollY = Y;
+ ScrollX = mScrollX;
+ ScrollY = mScrollY;
+}
+
+void DDScrollBuffer_ScrollTowards(int X, int Y, double Step)
+{
+ double dx, dY, r;
+
+ if (NoDisplayFlag)
+ return;
+
+ X = X / Stretch;
+ Y = Y / Stretch;
+ dx = X - mScrollX;
+ dY = Y - mScrollY;
+ r = Sqr(dx * dx + dY * dY);
+ if (r == 0) // we are there already
+ return;
+
+ if (Step < r)
+ r = Step / r;
+ else
+ r = 1;
+
+ mScrollX = mScrollX + dx * r;
+ mScrollY = mScrollY + dY * r;
+ ScrollX = mScrollX;
+ ScrollY = mScrollY;
+}
+
+void DDScrollBuffer_SoftScrollTo(int X, int Y, long TimeMS, int FPS)
+{
+ double dx, dY;
+ TickCountObject Tick;
+ long dT, StepCount;
+ double T, tStep;
+ long oldX, oldY, maxD;
+ boolean AlreadyRunning;
+
+ if (NoDisplayFlag)
+ return;
+
+ if (AlreadyRunning)
+ {
+ return;
+ }
+
+ AlreadyRunning = True;
+ X = X / Stretch;
+ Y = Y / Stretch;
+ dx = X - mScrollX;
+ dY = Y - mScrollY;
+ maxD = (Abs(dx) < Abs(dY) ? Abs(dY) : Abs(dY));
+ StepCount = FPS * (TimeMS / (double)1000);
+ if (StepCount > maxD)
+ StepCount = maxD;
+
+ if (StepCount == 0)
+ StepCount = 1;
+
+ dT = 1000 / FPS;
+ tStep = (double)1 / StepCount;
+ oldX = mScrollX;
+ oldY = mScrollY;
+ // R = Sqr(dX * dX + dY * dY)
+ // If R = 0 Then Exit Sub 'we are there already
+ for (T = (double)tStep; T <= (double)1; T += tStep)
+ {
+ if (UserDragFlag)
+ goto SoftScrollEH;
+
+ // If Claim Then Exit For
+ Tick.DelayMS(dT, False);
+ mScrollX = oldX + T * dx;
+ mScrollY = oldY + T * dY;
+ ScrollX = mScrollX;
+ ScrollY = mScrollY;
+ // Blt();
+ }
+
+ if (UserDragFlag)
+ goto SoftScrollEH;
+
+ Tick.DelayMS(dT, False);
+ mScrollX = X;
+ mScrollY = Y;
+ ScrollX = mScrollX;
+ ScrollY = mScrollY;
+ // Blt();
+
+SoftScrollEH:
+ AlreadyRunning = False;
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// DDScrollBuffer.h
+// ----------------------------------------------------------------------------
+
+#ifndef DDSCROLLBUFFER_H
+#define DDSCROLLBUFFER_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern void DDScrollBuffer_Blt();
+extern void DDScrollBuffer_Cls(int BackColor);
+extern long DDScrollBuffer_CreateAtSize(long Width, long Height, long hWndViewPort);
+extern long DDScrollBuffer_Get_DestXOff();
+extern long DDScrollBuffer_Get_DestYOff();
+extern int DDScrollBuffer_Get_Height();
+extern DirectDrawSurface7 DDScrollBuffer_Get_Surface();
+extern long DDScrollBuffer_Get_Width();
+extern void DDScrollBuffer_Let_DestXOff(long NewVal);
+extern void DDScrollBuffer_Let_DestYOff(long NewVal);
+extern void DDScrollBuffer_ScrollTo(int X, int Y);
+extern void DDScrollBuffer_ScrollTowards(int X, int Y, double Step);
+extern void DDScrollBuffer_SoftScrollTo(int X, int Y, long TimeMS, int FPS);
+
+#endif /* DDSCROLLBUFFER_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// DDSpriteBuffer.c
+// ----------------------------------------------------------------------------
+
+#include "DDSpriteBuffer.h"
+
+static void Blt(int pX, int pY, int SpriteX, int SpriteY);
+
+// --- VERSION 1.0 CLASS
+// --- BEGIN
+// --- MultiUse = -1 'True // True
+// --- Persistable = 0 'NotPersistable // NotPersistable
+// --- DataBindingBehavior = 0 'vbNone // vbNone
+// --- DataSourceBehavior = 0 'vbNone // vbNone
+// --- MTSTransactionMode = 0 'NotAnMTSObject // NotAnMTSObject
+// --- END
+
+static char *VB_Name = "DDSpriteBuffer";
+static boolean VB_GlobalNameSpace = False;
+static boolean VB_Creatable = True;
+static boolean VB_PredeclaredId = False;
+static boolean VB_Exposed = False;
+// --- Option Explicit
+
+// needs reference to: DirectX7 for Visual Basic Type Library
+
+DirectDrawSurface7 Buffer;
+DirectDrawSurface7 mDest;
+long mXSpriteCount, mYSpriteCount;
+long mSpriteWidth, mSpriteHeight;
+long mDestXOff, mDestYOff;
+
+void DDSpriteBuffer_Let_DestXOff(long NewVal)
+{
+ mDestXOff = NewVal;
+}
+
+long DDSpriteBuffer_Get_DestXOff()
+{
+ long DestXOff;
+
+ DestXOff = mDestXOff;
+
+ return DestXOff;
+}
+
+void DDSpriteBuffer_Let_DestYOff(long NewVal)
+{
+ mDestYOff = NewVal;
+}
+
+long DDSpriteBuffer_Get_DestYOff()
+{
+ long DestYOff;
+
+ DestYOff = mDestYOff;
+
+ return DestYOff;
+}
+
+int DDSpriteBuffer_Set_DestinationSurface(DirectDrawSurface7 DSurface)
+{
+ int DestinationSurface;
+
+ mDest = DSurface;
+
+ return DestinationSurface;
+}
+
+DirectDrawSurface7 DDSpriteBuffer_Get_Surface()
+{
+ DirectDrawSurface7 Surface;
+
+ Surface = Buffer;
+
+ return Surface;
+}
+
+long DDSpriteBuffer_Get_Width()
+{
+ long Width;
+
+ Width = mSpriteWidth * mXSpriteCount;
+
+ return Width;
+}
+
+int DDSpriteBuffer_Get_Height()
+{
+ int Height;
+
+ Height = mSpriteHeight * mYSpriteCount;
+
+ return Height;
+}
+
+boolean DDSpriteBuffer_CreateFromFile(char *Path, long xSprites, long ySprites)
+{
+ boolean CreateFromFile;
+
+ DDSURFACEDESC2 SD;
+
+ {
+ SD.lFlags = DDSD_CAPS; // Or DDSD_WIDTH Or DDSD_HEIGHT
+ SD.ddsCaps.lCaps = DDSCAPS_VIDEOMEMORY; // DDSCAPS_SYSTEMMEMORY 'DDSCAPS_OFFSCREENPLAIN
+ }
+
+ // --- On Error GoTo CreateFromFileEH
+ Buffer = DDraw.CreateSurfaceFromFile(Path, SD);
+ // --- On Error GoTo 0
+
+ Buffer.GetSurfaceDesc(SD);
+ mSpriteWidth = SD.LWidth / xSprites;
+ mSpriteHeight = SD.LHeight / ySprites;
+ mXSpriteCount = xSprites;
+ mYSpriteCount = ySprites;
+ CreateFromFile = True;
+ return CreateFromFile;
+
+CreateFromFileEH:
+ CreateFromFile = False;
+
+ return CreateFromFile;
+}
+
+boolean DDSpriteBuffer_CreateAtSize(long Width, long Height, long xSprites, long ySprites)
+{
+ boolean CreateAtSize;
+
+ DDSURFACEDESC2 SD;
+
+ {
+ SD.lFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
+ SD.ddsCaps.lCaps = DDSCAPS_VIDEOMEMORY;
+ // SD.ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
+ SD.LWidth = Width;
+ SD.LHeight = Height;
+ }
+
+ // --- On Error GoTo CreateAtSizeEH
+ Buffer = DDraw.CreateSurface(SD);
+ // --- On Error GoTo 0
+
+ mSpriteWidth = Width / xSprites;
+ mSpriteHeight = Height / ySprites;
+ mXSpriteCount = xSprites;
+ mYSpriteCount = ySprites;
+ CreateAtSize = True;
+ return CreateAtSize;
+
+CreateAtSizeEH:
+ CreateAtSize = False;
+
+ return CreateAtSize;
+}
+
+void DDSpriteBuffer_Cls(int BackColor)
+{
+ RECT EmptyRect;
+
+ Buffer.BltColorFill(EmptyRect, BackColor);
+}
+
+static void Blt(int pX, int pY, int SpriteX, int SpriteY)
+{
+ RECT DR, SR;
+ long Tmp;
+
+ if (NoDisplayFlag)
+ return;
+
+ {
+ DR.left = pX + mDestXOff;
+ DR.top = pY + mDestYOff;
+ DR.right = pX + mSpriteWidth + mDestXOff;
+ DR.bottom = pY + mSpriteHeight + mDestYOff;
+ }
+ {
+ SR.left = mSpriteWidth * (SpriteX - 1);
+ SR.top = mSpriteHeight * (SpriteY - 1);
+ SR.right = SR.left + mSpriteWidth;
+ SR.bottom = SR.top + mSpriteHeight;
+ }
+ Tmp = mDest_Blt(DR, Buffer, SR, DDBLT_WAIT);
+}
+
+void DDSpriteBuffer_BltEx(int pX, int pY, int SpritePos)
+{
+ int XPos, YPos;
+
+ if (NoDisplayFlag)
+ return;
+
+ XPos = (SpritePos % mXSpriteCount) + 1;
+ YPos = (SpritePos / mXSpriteCount) + 1;
+ Blt(pX, pY, XPos, YPos);
+}
+
+// Public Function GetStretchCopy(Stretch!) As DDSpriteBuffer
+// Dim SR As RECT, DR As RECT, Y%, X%, pX%, pY%, Tmp&
+// // Set GetStretchCopy = New DDSpriteBuffer // (handle this later, if needed)
+// If Not GetStretchCopy.CreateAtSize(Stretch * Width, Stretch * Height, mXSpriteCount, mYSpriteCount) Then
+// Set GetStretchCopy = Nothing
+// Else
+// For Y = 0 To mYSpriteCount - 1
+// pY = Y * Stretch * mSpriteHeight
+// For X = 0 To mXSpriteCount - 1
+// pX = X * Stretch * mSpriteWidth
+// With DR
+// .left = pX
+// .top = pY
+// .right = pX + mSpriteWidth * Stretch
+// .bottom = pY + mSpriteHeight * Stretch
+// End With
+// With SR
+// .left = mSpriteWidth * X
+// .top = mSpriteHeight * Y
+// .right = .left + mSpriteWidth
+// .bottom = .top + mSpriteHeight
+// End With
+// Tmp = GetStretchCopy.Surface.Blt(DR, Buffer, SR, DDBLT_WAIT)
+// Next X
+// Next Y
+// 'GetStretchCopy.Surface.Blt DR, Buffer, DR, DDBLT_WAIT
+// End If
+// End Function
+
+static void Class_Initialize()
+{
+ mDestXOff = 0;
+ mDestYOff = 0;
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// DDSpriteBuffer.h
+// ----------------------------------------------------------------------------
+
+#ifndef DDSPRITEBUFFER_H
+#define DDSPRITEBUFFER_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern void DDSpriteBuffer_BltEx(int pX, int pY, int SpritePos);
+extern void DDSpriteBuffer_Cls(int BackColor);
+extern boolean DDSpriteBuffer_CreateAtSize(long Width, long Height, long xSprites, long ySprites);
+extern boolean DDSpriteBuffer_CreateFromFile(char *Path, long xSprites, long ySprites);
+extern long DDSpriteBuffer_Get_DestXOff();
+extern long DDSpriteBuffer_Get_DestYOff();
+extern int DDSpriteBuffer_Get_Height();
+extern DirectDrawSurface7 DDSpriteBuffer_Get_Surface();
+extern long DDSpriteBuffer_Get_Width();
+extern void DDSpriteBuffer_Let_DestXOff(long NewVal);
+extern void DDSpriteBuffer_Let_DestYOff(long NewVal);
+extern int DDSpriteBuffer_Set_DestinationSurface(DirectDrawSurface7 DSurface);
+
+#endif /* DDSPRITEBUFFER_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// Demo.c
+// ----------------------------------------------------------------------------
+
+#include "Demo.h"
+
+static char *VB_Name = "modDemo";
+// --- Option Explicit
+//
+// Public Function subCloseDemoRecordingFile()
+//
+// End Function
+int RecDemoRandomSeed;
+byte FirstDemoByte;
+char *MySignature;
+
+void subGetNextDemoKey()
+{
+ int ax;
+
+ if (0 < DemoKeyRepeatCounter)
+ {
+ DemoKeyRepeatCounter = DemoKeyRepeatCounter - 1;
+ }
+ else
+ {
+ DemoOffset = DemoOffset + 1;
+ if (DemoOffset <= FileMax)
+ {
+ ax = PlayField8[DemoOffset];
+ if (ax == 0xFF)
+ {
+ demo_stopped = 1;
+ ExitToMenuFlag = 1;
+ }
+ else
+ {
+ DemoKeyCode = ax & 0xF;
+ DemoKeyRepeatCounter = (ax & 0xF0) / 0x10;
+ }
+
+ }
+ else
+ {
+ ExitToMenuFlag = 1;
+ }
+ }
+}
+
+currency GetTotalFramesOfDemo()
+{
+ currency GetTotalFramesOfDemo;
+
+ long i;
+ currency nFrames;
+ byte db;
+
+ GetTotalFramesOfDemo = 0;
+ if (! DemoAvailable)
+ return GetTotalFramesOfDemo;
+
+ nFrames = 1;
+ i = DemoPointer + 1;
+
+ // --- On Error GoTo GetTotalFramesOfDemoEH
+ db = PlayField8[i];
+ while (db != 0xFF)
+ {
+ nFrames = nFrames + (db & 0xF0) / 0x10 + 1;
+ i = i + 1;
+ db = PlayField8[i];
+ }
+
+ GetTotalFramesOfDemo = nFrames;
+ return GetTotalFramesOfDemo;
+
+GetTotalFramesOfDemoEH:
+ // ReportError "GetTotalFramesOfDemo()", "invalid data detected in file " & OrigPath
+ GetTotalFramesOfDemo = 0;
+ DemoAvailable = False;
+
+ return GetTotalFramesOfDemo;
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// Demo.h
+// ----------------------------------------------------------------------------
+
+#ifndef DEMO_H
+#define DEMO_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern currency GetTotalFramesOfDemo();
+extern void subGetNextDemoKey();
+
+extern byte FirstDemoByte;
+extern char *MySignature;
+extern int RecDemoRandomSeed;
+
+#endif /* DEMO_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// DemoBufferObject.c
+// ----------------------------------------------------------------------------
+
+#include "DemoBufferObject.h"
+
+static void Class_Terminate();
+static int RemoveLastDemoKey();
+
+// --- VERSION 1.0 CLASS
+// --- BEGIN
+// --- MultiUse = -1 'True // True
+// --- Persistable = 0 'NotPersistable // NotPersistable
+// --- DataBindingBehavior = 0 'vbNone // vbNone
+// --- DataSourceBehavior = 0 'vbNone // vbNone
+// --- MTSTransactionMode = 0 'NotAnMTSObject // NotAnMTSObject
+// --- END
+
+static char *VB_Name = "DemoBufferObject";
+static boolean VB_GlobalNameSpace = False;
+static boolean VB_Creatable = True;
+static boolean VB_PredeclaredId = False;
+static boolean VB_Exposed = False;
+// --- Option Explicit
+
+#define MaxPos ((long)1024)
+
+// Private Const MaxPos& = 20& 'debug only
+byte DemoByte[MaxPos + 1];
+DemoBufferObject SubBuffer;
+
+byte nFirstByte;
+
+char *mSignature;
+boolean bSignatureAvailable;
+
+long WritePos;
+int LastKey;
+int CheckSum;
+long nSize;
+
+static void Class_Initialize()
+{
+ int lSize;
+
+ Trace("DemoBufferObject", "Construction");
+ DemoBufferObject_Reset();
+ if (! IS_NOTHING(&DemoBuffer, sizeof(DemoBuffer)))
+ {
+ lSize = DemoBuffer_Size();
+ Trace("DemoBufferObject", "Size == ...");
+ Trace("DemoBufferObject", "BufferCount == ...");
+ Trace("DemoBufferObject", "TimerVar == ...");
+ }
+}
+
+static void Class_Terminate()
+{
+ SET_TO_NOTHING(&SubBuffer, sizeof(SubBuffer));
+}
+
+void DemoBufferObject_Reset()
+{
+ nSize = 0;
+ nFirstByte = 0x81;
+ WritePos = 0;
+ LastKey = -1;
+ CheckSum = 0;
+ bSignatureAvailable = False;
+ mSignature = "";
+ SET_TO_NOTHING(&SubBuffer, sizeof(SubBuffer));
+}
+
+long DemoBufferObject_Get_Size()
+{
+ long Size;
+
+ Size = (nSize < 1 ? 0 : 0);
+ if (! IS_NOTHING(&SubBuffer, sizeof(SubBuffer)))
+ Size = Size + SubBuffer_Size();
+
+ return Size;
+}
+
+byte DemoBufferObject_Get_CheckSumByte()
+{
+ byte CheckSumByte;
+
+ CheckSumByte = CheckSum & 0xFF;
+
+ return CheckSumByte;
+}
+
+byte DemoBufferObject_Get_FirstByte()
+{
+ byte FirstByte;
+
+ FirstByte = nFirstByte;
+
+ return FirstByte;
+}
+
+void DemoBufferObject_Let_FirstByte(byte NewVal)
+{
+ nFirstByte = NewVal;
+}
+
+//
+// Public Property Get DemoAvailable() As Boolean
+// DemoAvailable = (0 < nSize)
+// End Property
+//
+// Public Property Get Signature() As String
+// If SubBuffer Is Nothing Then
+// Signature = mSignature
+// Else
+// Signature = SubBuffer.Signature
+// End If
+// End Property
+
+// Public Property Let Signature(NewSig$)
+// If SubBuffer Is Nothing Then
+// Signature = NewSig
+// Else
+// SubBuffer.Signature = NewSig
+// End If
+// End Property
+//
+// Public Property Get SignatureAvailable() As Boolean
+// If SubBuffer Is Nothing Then
+// SignatureAvailable = (mSignature <> "")
+// Else
+// SignatureAvailable = SubBuffer
+// End If
+// End Property
+
+boolean DemoBufferObject_Serialize(int FNum)
+{
+ boolean Serialize;
+
+ int i; // , LKey%
+
+ Serialize = True;
+ if (! IS_NOTHING(&SubBuffer, sizeof(SubBuffer)))
+ Serialize = SubBuffer_Serialize(FNum);
+
+ if (nSize == 0)
+ return Serialize;
+
+ // LKey = RemoveLastDemoKey()
+ if (! nSize < MaxPos) // this buffer is full
+ {
+
+ // --- On Error GoTo SerializeEH
+ FILE_PUT(FNum, -1, &DemoByte, sizeof(DemoByte));
+ // --- On Error GoTo 0
+
+ }
+ else // this is the last buffer in the recursive chain
+ {
+
+ // --- On Error GoTo SerializeEH
+ for (i = 1; i <= WritePos; i++)
+ {
+ FILE_PUT(FNum, -1, &DemoByte[i], sizeof(DemoByte[i]));
+ }
+
+ // --- On Error GoTo 0
+
+ }
+
+ // AddDemoKey LKey
+ return Serialize;
+
+SerializeEH:
+ Serialize = False;
+
+ return Serialize;
+}
+
+void DemoBufferObject_AddDemoKey(int KeyCode)
+{
+ CheckSum = (CheckSum + 1) & 0xFF; // increment checksum
+ // If Not SubBuffer Is Nothing Then 'delegate
+ // Debug.Assert False
+ // 'SubBuffer.AddDemoKey KeyCode
+ // Exit Sub
+ // End If
+ if (LastKey == KeyCode)
+ {
+ DemoByte[WritePos] = DemoByte[WritePos] + 0x10;
+ if (0xEF < DemoByte[WritePos])
+ LastKey = -1;
+
+ }
+ else // LastKey <> KeyCode
+ {
+ WritePos = WritePos + 1;
+
+ if (MaxPos < WritePos) // if overflow then create new buffer, hang myself in list
+ {
+ DemoBufferObject Tmp;
+
+ // Tmp = New DemoBufferObject; // (handle this later, if needed)
+ Tmp.SetSubBuffer(&VB_OBJECT_SELF);
+ Tmp.AddDemoKey(KeyCode); // and delegate
+ DemoBuffer = Tmp;
+ }
+ else
+ {
+ nSize = nSize + 1; // increment size
+ DemoByte[WritePos] = KeyCode;
+ LastKey = KeyCode;
+ }
+ }
+}
+
+void DemoBufferObject_SetSubBuffer(DemoBufferObject SBuf)
+{
+ SubBuffer = SBuf;
+}
+
+static int RemoveLastDemoKey()
+{
+ static int RemoveLastDemoKey;
+
+ RemoveLastDemoKey = (DemoByte[WritePos] & 0xF);
+ if (DemoByte[WritePos] < 0x10)
+ {
+ WritePos = WritePos - 1;
+ nSize = nSize - 1;
+ LastKey = -1;
+ }
+ else
+ {
+ DemoByte[WritePos] = DemoByte[WritePos] - 0x10;
+ }
+
+ return RemoveLastDemoKey;
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// DemoBufferObject.h
+// ----------------------------------------------------------------------------
+
+#ifndef DEMOBUFFEROBJECT_H
+#define DEMOBUFFEROBJECT_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern void DemoBufferObject_AddDemoKey(int KeyCode);
+extern byte DemoBufferObject_Get_CheckSumByte();
+extern byte DemoBufferObject_Get_FirstByte();
+extern long DemoBufferObject_Get_Size();
+extern void DemoBufferObject_Let_FirstByte(byte NewVal);
+extern void DemoBufferObject_Reset();
+extern boolean DemoBufferObject_Serialize(int FNum);
+extern void DemoBufferObject_SetSubBuffer(DemoBufferObject SBuf);
+
+#endif /* DEMOBUFFEROBJECT_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// DirectDrawGlobals.c
+// ----------------------------------------------------------------------------
+
+#include "DirectDrawGlobals.h"
+
+static char *VB_Name = "DirectDrawGlobals";
+// --- Option Explicit
+
+DirectX7 DirectX;
+DirectDraw7 DirectDraw;
+DirectDrawSurface7 PrimarySurface;
+
+void InitDirectDraw(long hWndClip)
+{
+ DDSURFACEDESC2 SD;
+
+ // DirectX = New DirectX7; // (handle this later, if needed)
+ DirectDraw = DirectX.DirectDrawCreate("");
+ DirectDraw.SetCooperativeLevel(0, DDSCL_NORMAL);
+ // Create PrimarySurface:
+ {
+ SD.lFlags = DDSD_CAPS;
+ SD.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE;
+ }
+ PrimarySurface = DirectDraw.CreateSurface(SD);
+ if (hWndClip != 0)
+ ClipToWindow(hWndClip);
+}
+
+void ReleaseDirectDraw()
+{
+ SET_TO_NOTHING(&PrimarySurface, sizeof(PrimarySurface));
+ SET_TO_NOTHING(&DirectDraw, sizeof(DirectDraw));
+ SET_TO_NOTHING(&DirectX, sizeof(DirectX));
+}
+
+void ClipToWindow(long hWnd)
+{
+ DirectDrawClipper Clipper;
+
+ // create clipper
+ Clipper = DirectDraw.CreateClipper(0);
+ Clipper.SetHWnd(hWnd);
+ PrimarySurface.SetClipper(Clipper);
+ SET_TO_NOTHING(&Clipper, sizeof(Clipper));
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// DirectDrawGlobals.h
+// ----------------------------------------------------------------------------
+
+#ifndef DIRECTDRAWGLOBALS_H
+#define DIRECTDRAWGLOBALS_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern void ClipToWindow(long hWnd);
+extern void InitDirectDraw(long hWndClip);
+extern void ReleaseDirectDraw();
+
+extern DirectDraw7 DirectDraw;
+extern DirectDrawSurface7 PrimarySurface;
+extern DirectX7 DirectX;
+
+#endif /* DIRECTDRAWGLOBALS_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// DirectXGlobals.c
+// ----------------------------------------------------------------------------
+
+#include "DirectXGlobals.h"
+
+static char *VB_Name = "DirectXGlobals";
+// --- Option Explicit
+
+DirectX7 DirectX;
+DirectX7 DirectXS;
+DirectDraw7 DDraw;
+DirectSound DSound;
+
+// Public DInput As DirectInput
+// Public DKeyboard As DirectInputDevice
+DirectDrawSurface7 PrimarySurface;
+
+void InitDirectX(long hWndForm, long hWndClip)
+{
+ // DirectX = New DirectX7; // (handle this later, if needed)
+ // DirectXS = New DirectX7; // (handle this later, if needed)
+
+ // DirectSound:
+
+ // --- On Error Resume Next
+ DSound = DirectXS.DirectSoundCreate("");
+ if (Err.Number != 0)
+ {
+ ReportError("InitDirectX()", "Unable to start DirectSound.");
+ }
+ else
+ {
+ DSound.SetCooperativeLevel(hWndForm, DSSCL_PRIORITY);
+ LoadSoundFX();
+ }
+
+ // DirectDraw:
+ DDraw = DirectX.DirectDrawCreate("");
+ DDraw.SetCooperativeLevel(0, DDSCL_NORMAL);
+ RestorePrimarySurface();
+ if (hWndClip != 0)
+ ClipToWindow(hWndClip);
+
+ // 'DirectInput:
+ // Set DInput = DirectX.DirectInputCreate()
+ // Set DKeyboard = DInput.CreateDevice("GUID_SysKeyboard")
+ // Call DKeyboard.SetCommonDataFormat(DIFORMAT_KEYBOARD)
+ // Call DKeyboard.SetCooperativeLevel(hWndForm, DISCL_NONEXCLUSIVE Or DISCL_BACKGROUND)
+ // Call DKeyboard.Acquire
+}
+
+void RestorePrimarySurface()
+{
+ DDSURFACEDESC2 SD;
+
+ // Create PrimarySurface:
+ {
+ SD.lFlags = DDSD_CAPS;
+ SD.ddsCaps.lCaps = DDSCAPS_PRIMARYSURFACE;
+ }
+
+ // --- On Error Resume Next
+ SET_TO_NOTHING(&PrimarySurface, sizeof(PrimarySurface));
+ PrimarySurface = DDraw.CreateSurface(SD);
+}
+
+void ReleaseDirectDraw()
+{
+ SET_TO_NOTHING(&PrimarySurface, sizeof(PrimarySurface));
+ SET_TO_NOTHING(&DDraw, sizeof(DDraw));
+ SET_TO_NOTHING(&DirectX, sizeof(DirectX));
+}
+
+void ClipToWindow(long hWnd)
+{
+ DirectDrawClipper Clipper;
+ long shWnd;
+
+ if (hWnd != 0)
+ shWnd = hWnd;
+
+ // create clipper
+ Clipper = DDraw.CreateClipper(0);
+ Clipper.SetHWnd(shWnd);
+ PrimarySurface.SetClipper(Clipper);
+ SET_TO_NOTHING(&Clipper, sizeof(Clipper));
+}
+
+// Public Sub DimPrimary(Brightness&)
+// Dim Pal As DirectDrawPalette
+// Set Pal = PrimarySurface.GetPalette()
+// End Sub
+
--- /dev/null
+// ----------------------------------------------------------------------------
+// DirectXGlobals.h
+// ----------------------------------------------------------------------------
+
+#ifndef DIRECTXGLOBALS_H
+#define DIRECTXGLOBALS_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern void ClipToWindow(long hWnd);
+extern void InitDirectX(long hWndForm, long hWndClip);
+extern void ReleaseDirectDraw();
+extern void RestorePrimarySurface();
+
+extern DirectDraw7 DDraw;
+extern DirectDrawSurface7 PrimarySurface;
+extern DirectSound DSound;
+extern DirectX7 DirectX;
+extern DirectX7 DirectXS;
+
+#endif /* DIRECTXGLOBALS_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// Display.c
+// ----------------------------------------------------------------------------
+
+#include "Display.h"
+
+static char *VB_Name = "modDisplay";
+// --- Option Explicit
+
+int ScreenScrollXPos, ScreenScrollYPos;
+int ScreenPosition, data_h_Xtmp, data_h_Ytmp;
+
+int ShowRedDiskCounter, ShowPanel;
+int ExplosionShake;
+boolean NoDisplayFlag;
+
+long DisplayMinX, DisplayMaxX, DisplayWidth;
+long DisplayMinY, DisplayMaxY, DisplayHeight;
+
+
+int subDisplayInfotronsNeeded()
+{
+ int subDisplayInfotronsNeeded;
+
+ if (NoDisplayFlag)
+ return subDisplayInfotronsNeeded;
+
+ {
+#if 0
+ MainForm.lblInfoCount.Caption = InfotronsNeeded;
+ MainForm.lblInfoCount.Refresh;
+#endif
+ }
+
+ return subDisplayInfotronsNeeded;
+}
+
+int subDisplayPlayingTime()
+{
+ int subDisplayPlayingTime;
+
+
+ return subDisplayPlayingTime;
+}
+
+int subDisplayLevel()
+{
+ int subDisplayLevel;
+
+ if (NoDisplayFlag || ! LevelLoaded)
+ return subDisplayLevel;
+
+#if 0
+ MainForm.DisplayLevel();
+#endif
+
+ return subDisplayLevel;
+}
+
+void subDisplayPanel()
+{
+}
+
+int subCheckRestoreRedDiskCountDisplay()
+{
+ int subCheckRestoreRedDiskCountDisplay;
+
+ if (NoDisplayFlag)
+ return subCheckRestoreRedDiskCountDisplay;
+
+ if (ShowRedDiskCounter == 0)
+ return subCheckRestoreRedDiskCountDisplay;
+
+ ShowRedDiskCounter = ShowRedDiskCounter - 1;
+ if (ShowRedDiskCounter == 0)
+ {
+ {
+#if 0
+ MainForm.lblRedDiskCount.Caption = 0;
+ MainForm.lblRedDiskCount.Refresh;
+#endif
+ }
+ }
+
+ return subCheckRestoreRedDiskCountDisplay;
+}
+
+void subDisplayRedDiskCount()
+{
+ if (NoDisplayFlag)
+ return;
+
+ {
+#if 0
+ MainForm.lblRedDiskCount.Caption = RedDiskCount;
+ MainForm.lblRedDiskCount.Refresh;
+#endif
+ }
+ ShowRedDiskCounter = 0x46;
+}
+
+void ScrollTo(int X, int Y)
+{
+ long oldX, oldY;
+
+ if (NoDisplayFlag)
+ return;
+
+ oldX = ScrollX;
+ oldY = ScrollY;
+ X = ScrollDelta * (X / ScrollDelta);
+ X = Max(X, ScrollMinX);
+ X = Min(X, ScrollMaxX);
+ Y = ScrollDelta * (Y / ScrollDelta);
+ Y = Max(Y, ScrollMinY);
+ Y = Min(Y, ScrollMaxY);
+ // ScrollX = X
+ // ScrollY = Y
+ Stage.ScrollTo(X, Y);
+}
+
+void ScrollTowards(int X, int Y)
+{
+ long oldX, oldY;
+
+ if (NoDisplayFlag)
+ return;
+
+ oldX = ScrollX;
+ oldY = ScrollY;
+ X = ScrollDelta * (X / ScrollDelta);
+ X = Max(X, ScrollMinX);
+ X = Min(X, ScrollMaxX);
+ Y = ScrollDelta * (Y / ScrollDelta);
+ Y = Max(Y, ScrollMinY);
+ Y = Min(Y, ScrollMaxY);
+ // ScrollX = X
+ // ScrollY = Y
+ Stage.ScrollTowards(X, Y, 2 * Stretch);
+}
+
+void SoftScrollTo(int X, int Y, long TimeMS, int FPS)
+{
+ long oldX, oldY;
+
+ if (NoDisplayFlag)
+ return;
+
+ oldX = ScrollX;
+ oldY = ScrollY;
+ X = ScrollDelta * (X / ScrollDelta);
+ X = Max(X, ScrollMinX);
+ X = Min(X, ScrollMaxX);
+ Y = ScrollDelta * (Y / ScrollDelta);
+ Y = Max(Y, ScrollMinY);
+ Y = Min(Y, ScrollMaxY);
+ // ScrollX = X
+ // ScrollY = Y
+ Stage.SoftScrollTo(X, Y, TimeMS, FPS);
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// Display.h
+// ----------------------------------------------------------------------------
+
+#ifndef DISPLAY_H
+#define DISPLAY_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern void ScrollTo(int X, int Y);
+extern void ScrollTowards(int X, int Y);
+extern void SoftScrollTo(int X, int Y, long TimeMS, int FPS);
+extern int subCheckRestoreRedDiskCountDisplay();
+extern int subDisplayInfotronsNeeded();
+extern int subDisplayLevel();
+extern void subDisplayPanel();
+extern int subDisplayPlayingTime();
+extern void subDisplayRedDiskCount();
+
+extern boolean NoDisplayFlag;
+extern int ExplosionShake;
+extern int ScreenPosition, data_h_Xtmp, data_h_Ytmp;
+extern int ScreenScrollXPos, ScreenScrollYPos;
+extern int ShowRedDiskCounter, ShowPanel;
+extern long DisplayMinX, DisplayMaxX, DisplayWidth;
+extern long DisplayMinY, DisplayMaxY, DisplayHeight;
+
+#endif /* DISPLAY_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// DoGameStuff.c
+// ----------------------------------------------------------------------------
+
+#include "DoGameStuff.h"
+
+static void CallAnimation(int si, byte bl);
+static boolean IsToBeAnimated(int bl);
+
+static char *VB_Name = "modDoGameStuff";
+// --- Option Explicit
+
+int *AnimationPosTable;
+byte *AnimationSubTable;
+
+// ==========================================================================
+// SUBROUTINE
+// Do game stuff
+// ==========================================================================
+
+int subDoGameStuff()
+{
+ int subDoGameStuff;
+
+ int si, cx, dx, bl;
+
+ subAnimateMurphy(MurphyPosIndex); // move Murphy in any direction
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ // Build a database of locations and subs-to-call of animatable fields only:
+ // Make a snapshot from the field before the animation cycle starts.
+ // first and last line are not animated.
+ si = FieldWidth + 1;
+ cx = LevelMax - 2 * FieldWidth - 1;
+ dx = 0;
+ do // locloop_g_2282:
+ {
+ bl = LowByte(PlayField16[si]);
+ if (((bl & 0xD) != 0) && (bl < 0x20)) // all animatables have 1's in &H0D' above &H1F? (&H1F=explosion!)
+ {
+ if (IsToBeAnimated(bl))
+ {
+ AnimationPosTable[dx] = si;
+ AnimationSubTable[dx] = bl;
+ dx = dx + 1; // count database entries
+ }
+ }
+
+ si = si + 1; // next field
+ cx = cx - 1;
+ }
+ while (0 < cx); // locloop_g_2282' until all lines scanned(not top- and bottom edge)
+
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ // Now use the database to animate all animatables the fastest way.
+ // All the other fields are not checked anymore: those have no database entry.
+ // The field from before animation is frozen in the database in order not to
+ // do follow-up animations in the same loop.
+ if (dx != 0) // any database entries?
+ {
+ dx = dx - 1;
+ for (cx = 0; cx <= dx; cx++)
+ {
+ CallAnimation(AnimationPosTable[cx], AnimationSubTable[cx]);
+ } // loop locloop_g_22B8 ' until all animatables done
+ }
+
+ // All animations are done now
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ if (KillMurphyFlag == 1 || MurphyMoveCounter == 0)
+ {
+ if (LeadOutCounter == 0)
+ {
+ KillMurphyFlag = 0; // no more "kill Murphy"
+ ExplodeFieldSP(MurphyExplodePos); // Explode
+ LeadOutCounter = 0x40; // quit: start lead-out
+ }
+ } // loc_g_22FB:
+
+
+ return subDoGameStuff;
+} // subDoGameStuff
+
+static boolean IsToBeAnimated(int bl)
+{
+ static boolean IsToBeAnimated;
+
+ switch (bl)
+ {
+ case fiZonk:
+ case fiInfotron:
+ case fiOrangeDisk:
+ case fiSnikSnak:
+ case fiTerminal:
+ case fiElectron:
+ case fiBug:
+ case fiExplosion:
+ IsToBeAnimated = True;
+ break;
+
+ default:
+ IsToBeAnimated = False;
+ break;
+ }
+
+ return IsToBeAnimated;
+}
+
+static void CallAnimation(int si, byte bl)
+{
+ switch (bl)
+ {
+ case fiZonk:
+ subAnimateZonks(si);
+ break;
+
+ case fiInfotron:
+ subAnimateInfotrons(si);
+ break;
+
+ case fiOrangeDisk:
+ subAnimateOrangeDisks(si);
+ break;
+
+ case fiSnikSnak:
+ subAnimateSnikSnaks(si);
+ break;
+
+ case fiTerminal:
+ subAnimateTerminals(si);
+ break;
+
+ case fiElectron:
+ subAnimateElectrons(si);
+ break;
+
+ case fiBug:
+ subAnimateBugs(si);
+ break;
+
+ case fiExplosion:
+ subAnimateExplosion(si);
+ break;
+
+ default:
+ // Debug.Assert(False);
+ break;
+ }
+}
+
--- /dev/null
+// ----------------------------------------------------------------------------
+// DoGameStuff.h
+// ----------------------------------------------------------------------------
+
+#ifndef DOGAMESTUFF_H
+#define DOGAMESTUFF_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern int subDoGameStuff();
+
+extern byte *AnimationSubTable;
+extern int *AnimationPosTable;
+
+#endif /* DOGAMESTUFF_H */
--- /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;
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// Electrons.h
+// ----------------------------------------------------------------------------
+
+#ifndef ELECTRONS_H
+#define ELECTRONS_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern int subAnimateElectrons(int si);
+extern int subDrawAnimatedElectrons(int si);
+extern int subDrawElectronFromAbove(int si, int bx);
+extern int subDrawElectronFromBelow(int si, int bx);
+extern int subDrawElectronFromLeft(int si, int bx);
+extern int subDrawElectronFromRight(int si, int bx);
+extern int subDrawElectronTurnLeft(int si, int bx);
+extern int subDrawElectronTurnRight(int si, int bx);
+extern int subElectronFromAbove(int si, int bx);
+extern int subElectronFromBelow(int si, int bx);
+extern int subElectronFromLeft(int si, int bx);
+extern int subElectronFromRight(int si, int bx);
+extern int subElectronTurnLeft(int si, int bx);
+extern int subElectronTurnRight(int si, int bx);
+
+#endif /* ELECTRONS_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// ErrorReporting.c
+// ----------------------------------------------------------------------------
+
+#include "ErrorReporting.h"
+
+static char * GetErrLogPath();
+static char * GetTraceLogPath();
+
+static char *VB_Name = "modErrorReporting";
+// --- Option Explicit
+
+static char *GetErrLogPath()
+{
+ static char *GetErrLogPath;
+
+ // GetErrLogPath = GET_PATH(WithSlash(App.Path), "Error.log");
+ GetErrLogPath = "Error.log";
+
+ return GetErrLogPath;
+}
+
+static char *GetTraceLogPath()
+{
+ static char *GetTraceLogPath;
+
+ // GetTraceLogPath = GET_PATH(WithSlash(App.Path), "Trace.log");
+ GetTraceLogPath = "Trace.log";
+
+ return GetTraceLogPath;
+}
+
+void Trace(char *Source, char *Message)
+{
+ // Dim Path$, FNum%, bIsOpen As Boolean
+ // Path = GetTraceLogPath()
+ // FNum = FreeFile
+ // bIsOpen = False
+ // On Error GoTo TraceEH
+ // Open Path For Append Access Write As FNum
+ // bIsOpen = True
+ // ' --- Print #FNum, Now & " " & Source & " : " & Message
+ // On Error GoTo 0
+ // TraceEH:
+ // If bIsOpen Then Close FNum
+}
+
+void ReportError(char *Source, char *Message)
+{
+ char *Path;
+ int FNum;
+ boolean bIsOpen;
+
+ Path = GetErrLogPath();
+ // FNum = FreeFile();
+ bIsOpen = False;
+
+ // --- On Error GoTo ReportErrorEH
+ FNum = fopen(Path, "ab");
+ bIsOpen = True;
+ // --- Print #FNum, Now & " SOURCE = " & Source & " ErrMessage = " & Message
+ // --- On Error GoTo 0
+
+
+ReportErrorEH:
+ if (bIsOpen)
+ fclose(FNum);
+}
+
+void InitErrorReporting()
+{
+ char *Path;
+
+ Path = GetErrLogPath();
+ MayKill(Path);
+ Path = GetTraceLogPath();
+ MayKill(Path);
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// ErrorReporting.h
+// ----------------------------------------------------------------------------
+
+#ifndef ERRORREPORTING_H
+#define ERRORREPORTING_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern void InitErrorReporting();
+extern void ReportError(char *Source, char *Message);
+extern void Trace(char *Source, char *Message);
+
+#endif /* ERRORREPORTING_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// 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
--- /dev/null
+// ----------------------------------------------------------------------------
+// Explosions.h
+// ----------------------------------------------------------------------------
+
+#ifndef EXPLOSIONS_H
+#define EXPLOSIONS_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern void ExplodeFieldSP(int si);
+extern int subAnimateExplosion(int si);
+extern int subClearFieldDueToExplosion(int si);
+extern int subFollowUpExplosions();
+extern int subRedDiskReleaseExplosion();
+
+#endif /* EXPLOSIONS_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// FakeDeclares.c
+// ----------------------------------------------------------------------------
+
+#include "FakeDeclares.h"
+
+static void subUpdateHallOfFame();
+
+static char *VB_Name = "FakeDeclares";
+// --- Option Explicit
+// --- Option Compare Binary
+
+int MurphyPosIndex, MurphyXPos, MurphyYPos;
+int MurphyScreenXPos, MurphyScreenYPos;
+int MurphyExplodePos, SplitMoveFlag, RedDiskReleaseMurphyPos;
+int KillMurphyFlag, MurphyMoveCounter;
+long YawnSleepCounter;
+int MurphyVar0DAC;
+int MurphyVar0DAE;
+int MurphyVarFaceLeft;
+int ScratchGravity, GravityFlag;
+int RedDiskReleaseFlag, MovingPictureSequencePhase;
+int data_h_DemoDone, LevelStatus;
+
+int data_h_0DA7;
+int data_h_0DA8;
+int data_h_0DA9;
+int data_h_0D9E;
+int data_h_0D9F;
+int data_h_0DA0;
+int data_h_0DA1;
+int data_h_0DA2;
+int data_h_0DA4;
+int data_h_0DA5;
+int data_h_0DA6;
+
+int data_h_165A;
+int YellowDisksExploded;
+int AllowRedDiskCheat, AllowEatRightRedDiskBug;
+
+int GameBusyFlag;
+int InfotronsNeeded, TotalInfotronsNeeded;
+int RedDiskCount;
+int SnikSnaksElectronsFrozen;
+
+boolean EditFlag;
+int EditMode;
+// --- const int edDraw = 1;
+int edSelect = 2;
+int edMove = 3;
+
+int DemoFlag, data_scr_demo, demo_stopped;
+int WasDemoFlag;
+int EP_GameDemoVar0DAA;
+int RecordDemoFlag; // , DemoRecordingFlag%
+int DemoKeyCode, DemoPointer;
+long DemoOffset;
+int DemoKeyRepeatCounter;
+
+int RedDiskReleasePhase;
+int UpdatedFlag;
+
+int DebugVersionFlag, D_ModeFlag;
+int Data_SubRest, Data_SubRstFlg;
+int keyEnter;
+
+int data_SPtorunavail; // ???????
+
+int UpdateTimeFlag;
+
+// boolean bModified;
+boolean ModifiedFlag;
+
+static void subUpdateHallOfFame()
+{
+}
+
+boolean Get_ModifiedFlag()
+{
+ // boolean ModifiedFlag;
+
+ // Let_ModifiedFlag(bModified);
+ Let_ModifiedFlag(ModifiedFlag);
+
+ return ModifiedFlag;
+}
+
+void Let_ModifiedFlag(boolean NewVal)
+{
+ // If bModified = NewVal Then Exit Property
+ char *Cap;
+
+ // bModified = NewVal;
+ ModifiedFlag = NewVal;
+ if (! LevelLoaded)
+ return;
+
+ if (NewVal)
+ {
+ Cap = ""; // !!! Cap = "MegaPlex - " & StripFileName(OrigPath) & "*"
+ gSignature = "";
+ bSignatureAvailable = False;
+ }
+ else
+ {
+ Cap = ""; // !!! Cap = "MegaPlex - " & StripFileName(OrigPath)
+ }
+
+#if 0
+ if (MainForm.Caption != Cap)
+ MainForm.Caption = Cap;
+#endif
+}
+
--- /dev/null
+// ----------------------------------------------------------------------------
+// FakeDeclares.h
+// ----------------------------------------------------------------------------
+
+#ifndef FAKEDECLARES_H
+#define FAKEDECLARES_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+#define edDraw (1)
+
+extern boolean ModifiedFlag;
+extern boolean Get_ModifiedFlag();
+extern void Let_ModifiedFlag(boolean NewVal);
+
+extern boolean EditFlag;
+extern int AllowRedDiskCheat, AllowEatRightRedDiskBug;
+extern int Data_SubRest, Data_SubRstFlg;
+extern int DebugVersionFlag, D_ModeFlag;
+extern int DemoFlag, data_scr_demo, demo_stopped;
+extern int DemoKeyCode, DemoPointer;
+extern int DemoKeyRepeatCounter;
+extern int EP_GameDemoVar0DAA;
+extern int EditMode;
+extern int GameBusyFlag;
+extern int InfotronsNeeded, TotalInfotronsNeeded;
+extern int KillMurphyFlag, MurphyMoveCounter;
+extern int MurphyExplodePos, SplitMoveFlag, RedDiskReleaseMurphyPos;
+extern int MurphyPosIndex, MurphyXPos, MurphyYPos;
+extern int MurphyScreenXPos, MurphyScreenYPos;
+extern int MurphyVar0DAC;
+extern int MurphyVar0DAE;
+extern int MurphyVarFaceLeft;
+extern int RecordDemoFlag;
+extern int RedDiskCount;
+extern int RedDiskReleaseFlag, MovingPictureSequencePhase;
+extern int RedDiskReleasePhase;
+extern int ScratchGravity, GravityFlag;
+extern int SnikSnaksElectronsFrozen;
+extern int UpdateTimeFlag;
+extern int UpdatedFlag;
+extern int WasDemoFlag;
+extern int YellowDisksExploded;
+extern int data_SPtorunavail;
+extern int data_h_0D9E;
+extern int data_h_0D9F;
+extern int data_h_0DA0;
+extern int data_h_0DA1;
+extern int data_h_0DA2;
+extern int data_h_0DA4;
+extern int data_h_0DA5;
+extern int data_h_0DA6;
+extern int data_h_0DA7;
+extern int data_h_0DA8;
+extern int data_h_0DA9;
+extern int data_h_165A;
+extern int data_h_DemoDone, LevelStatus;
+extern int edMove;
+extern int edSelect;
+extern int keyEnter;
+extern long DemoOffset;
+extern long YawnSleepCounter;
+
+#endif /* FAKEDECLARES_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// FancyRestore.c
+// ----------------------------------------------------------------------------
+
+#include "FancyRestore.h"
+
+static char *VB_Name = "modFancy";
+// --- Option Explicit
+
+// ==========================================================================
+// SUBROUTINE
+// Restore fancy stuff from sparelevel (and destroy registers ...)
+// ==========================================================================
+
+
+int subRestoreFancy()
+{
+ int subRestoreFancy;
+
+
+ return subRestoreFancy;
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// FancyRestore.h
+// ----------------------------------------------------------------------------
+
+#ifndef FANCYRESTORE_H
+#define FANCYRESTORE_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern int subRestoreFancy();
+
+#endif /* FANCYRESTORE_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// GeneralTricks.c
+// ----------------------------------------------------------------------------
+
+#include "GeneralTricks.h"
+
+static char *VB_Name = "GeneralTricks_Module";
+// --- Option Explicit
+// --- Option Compare Text
+
+double ValEx(char *TS)
+{
+ double ValEx;
+
+ // Extends the Val() function for
+ // german-style number-representing strings
+ int i;
+ char *LS, *RS;
+
+ i = InStr(1, TS, ",");
+ if (i != 0)
+ {
+ LS = Left(TS, i - 1);
+ RS = Right(TS, Len(TS) - i);
+ ValEx = Val(CAT(LS, ".", RS));
+ }
+ else
+ {
+ ValEx = Val(TS);
+ }
+
+ return ValEx;
+}
+
+void INC(int *VAR, int Delta)
+{
+ *VAR = *VAR + Delta;
+}
+
+void DEC(int *VAR, int Delta)
+{
+ *VAR = *VAR - Delta;
+}
+
+char *MySplit(char *TS, char *Sep, long SCount)
+{
+ char *MySplit;
+
+ char *T;
+ long i, J, k, q, L, SL;
+ char *RA;
+
+ T = TS;
+ L = Len(TS);
+ SL = Len(Sep);
+ J = SCount;
+ if (J < 1)
+ {
+ J = 0;
+ i = 1;
+ while (i <= L)
+ {
+ k = InStr(i, T, Sep);
+ if (k < i)
+ break;
+
+ if (i < k)
+ J = J + 1;
+
+ i = k + SL;
+ }
+
+ if (i <= L)
+ J = J + 1;
+ }
+
+ if (0 < J)
+ RA = REDIM_1D(sizeof(char), 0, J + 1 - 1);
+ else
+ return MySplit;
+
+ i = 1;
+ q = 0;
+ while (i <= L)
+ {
+ k = InStr(i, T, Sep);
+ if (k < i)
+ break;
+
+ if (i < k)
+ {
+ if (J <= q + 1)
+ break;
+
+ q = q + 1;
+ RA[q] = Mid(T, i, k - i);
+ }
+
+ i = k + SL;
+ }
+
+ if (i <= L)
+ {
+ q = q + 1;
+ T = Right(T, L - i + 1);
+ do
+ {
+ if (Len(T) <= SL)
+ break;
+
+ if (Right(T, SL) == Sep)
+ {
+ T = Left(T, Len(T) - SL);
+ }
+ else
+ {
+ break;
+ }
+ }
+ while (1);
+
+ strcpy(&RA[q], T); // RA(q) = T
+ }
+
+ MySplit = RA;
+
+ return MySplit;
+}
+
+void MyReplace(char *TS, char *Pat1, char *Pat2)
+{
+ long k, SL1, SL2, TL;
+
+ TL = Len(TS);
+ SL1 = Len(Pat1);
+ SL2 = Len(Pat2);
+ k = InStr(1, TS, Pat1);
+ if (k == 0)
+ return;
+
+ do
+ {
+ TS = CAT(Left(TS, k - 1), Pat2, Right(TS, TL - k - SL1 + 1));
+ TL = TL + SL2 - SL1;
+ k = InStr(k + SL2, TS, Pat1);
+ }
+ while (!(k == 0));
+}
+
--- /dev/null
+// ----------------------------------------------------------------------------
+// GeneralTricks.h
+// ----------------------------------------------------------------------------
+
+#ifndef GENERALTRICKS_H
+#define GENERALTRICKS_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern void DEC(int *VAR, int Delta);
+extern void INC(int *VAR, int Delta);
+extern void MyReplace(char *TS, char *Pat1, char *Pat2);
+extern char *MySplit(char *TS, char *Sep, long SCount);
+extern double ValEx(char *TS);
+
+#endif /* GENERALTRICKS_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// Globals.c
+// ----------------------------------------------------------------------------
+
+#include "Globals.h"
+
+static void ReadDemo();
+void ReadLevel();
+
+static char *VB_Name = "modGlobals";
+// --- Option Explicit
+// --- Option Compare Text
+// --- Option Base 0
+
+// --- const long StretchWidth = 16;
+// --- const long StretchWidth2 = StretchWidth / 2;
+// --- const long BaseWidth = 16;
+// --- const int TwoPixels = 2;
+
+boolean Original;
+boolean Cracked;
+boolean Level_Arg;
+boolean EGA_Arg;
+boolean Record_Fix;
+boolean SpeedKeys;
+boolean Level_Fix;
+boolean Dead_Code;
+boolean Redundant;
+boolean Alignments;
+boolean Ctrl_Alt_Fix;
+boolean Protection;
+boolean EP_ENHANCE;
+boolean EP_DEMO;
+boolean EP_DEBUG;
+boolean EXTRASPEED;
+boolean TIMINGFIX;
+boolean SafeRecord;
+boolean Norm_Time;
+boolean EP_OLD8;
+boolean SAVEGAME;
+boolean HP_DEMO;
+boolean ScreenFix;
+boolean DemoRecordFix;
+boolean DebugSwitch;
+boolean Ver62;
+boolean Ver62test;
+boolean Ver63;
+boolean Ver64;
+
+int LevelNumber;
+char *CurPath, *OrigPath, *TmpPath;
+boolean LevelLoaded;
+long SignatureDelay;
+
+boolean bCapturePane;
+
+int FieldWidth; // = 60
+int FieldHeight; // = 24
+int HeaderSize; // = 96
+int FieldMax, LevelMax;
+long FileMax;
+int *PlayField16;
+byte *PlayField8;
+byte *DisPlayField;
+
+// Public DisplayMin%, DisplayMax%, DisplayWidth%, DisplayHeight%
+
+int TimerVar, RandomSeed;
+currency DeltaT; // Interval between two frames (in ms)
+long DeltaTPlay, DeltaTDemo;
+boolean BlockingSpeed;
+
+// --- const int posFrameCorner = 55;
+// --- const int posFrameVertical = 110;
+// --- const int posFrameHorizontal = 111;
+
+int FreezeZonks;
+
+// constants for Fixed Fields:
+// --- const int fiSpace = 0; // &H00 space(28 = wall space ...)
+// --- const int fiZonk = 1; // &H01 zonk
+// --- const int fiBase = 2; // &H02 base
+// --- const int fiMurphy = 3; // &H03 Murphy
+// --- const int fiInfotron = 4; // &H04 infotron
+// --- const int fiRAM = 5; // &H05 small RAM chip
+// --- const int fiHardWare = 6; // &H06 hardware (square, standard pyramid shape)
+// --- const int fiExit = 7; // &H07 exit
+// --- const int fiOrangeDisk = 8; // &H08 brown/orange utility disk
+// --- const int fiPortRight = 9; // &H09 port 1 left to right
+// --- const int fiPortDown = 10; // &H0A port 1 up to down
+// --- const int fiPortLeft = 11; // &H0B port 1 right to left
+// --- const int fiPortUp = 12; // &H0C port 1 down to up
+// --- const int fiSpPortRight = 13; // &H0D port 2 left to right (gravity change)
+// --- const int fiSpPortDown = 14; // &H0E port 2 up to down (gravity change)
+// --- const int fiSpPortLeft = 15; // &H0F port 2 right to left (gravity change)
+// --- const int fiSpPortUp = 16; // &H10 port 2 down to up (gravity change)
+// --- const int fiSnikSnak = 17; // &H11 snik snak
+// --- const int fiYellowDisk = 18; // &H12 yellow utility disk
+// --- const int fiTerminal = 19; // &H13 terminal
+// --- const int fiRedDisk = 20; // &H14 red utility disk
+// --- const int fiPortUpAndDown = 21; // &H15 vertical port
+// --- const int fiPortLeftAndRight = 22; // &H16 horizontal port
+// --- const int fiPortAllDirections = 23; // &H17 horizontal + vertical port
+// --- const int fiElectron = 24; // &H18 electron
+// --- const int fiBug = 25; // &H19 bug
+// --- const int fiRAMLeft = 26; // &H1A horizontal RAM chip, left (pin 1)
+// --- const int fiRAMRight = 27; // &H1B horizontal RAM chip, right
+// --- const int fiHWFirst = 28; // &H1C hardware (radial blue circular cap + coloured shapes)
+
+// Public Const fiHW1% = 29 ' 29 = 1D hardware (green signal lamp)
+// Public Const fiHW2% = 30 ' 30 = 1E hardware (blue signal lamp)
+// Public Const fiHW3% = 31 ' 31 = 1F hardware (red signal lamp)
+// Public Const fiHW4% = 32 ' 32 = 20 hardware (yellow/black diagonal stripes)
+// Public Const fiHW5% = 33 ' 33 = 21 hardware (yellow resistor + blue + red shapes)
+// Public Const fiHW6% = 34 ' 34 = 22 hardware (horizontal red capacitor + smd shape)
+// Public Const fiHW7% = 35 ' 35 = 23 hardware (red + yellow + blue horizontal resistors)
+// Public Const fiHW8% = 36 ' 36 = 24 hardware (3 red vertical resistors)
+// --- const int fiHWLast = 37; // 37 = 25 hardware (3 yellow horizontal resistors)
+// --- const int fiRAMTop = 38; // 38 = 26 vertical RAM chip, top (pin 1)
+// --- const int fiRAMBottom = 39; // 39 = 27 vertical RAM chip, bottom
+
+// Specials to experiment with ...
+// --- const int fiWallSpace = 40; // 40 = 28 invisible wall (can explode, zonks don't roll off)
+// --- const int fiHWTrash1 = 41; // 41 = 29 hardware trash
+// --- const int fiHWTrash2 = 42; // 42 = 2A hardware trash
+// --- const int fiHWMurphy = 43; // 43 = 2B hardware inverted Murphy ... (maybe nice for use?)
+
+// --- const int fiExplosion = 0x1F;
+
+// --- const int keyNone = 0;
+// --- const int keyUp = 1;
+// --- const int keyLeft = 2;
+// --- const int keyDown = 3;
+// --- const int keyRight = 4;
+// --- const int keySpaceUp = 5;
+// --- const int keySpaceLeft = 6;
+// --- const int keySpaceDown = 7;
+// --- const int keySpaceRight = 8;
+// --- const int keySpace = 9;
+
+int *aniBug, *aniZonkRollRight, *aniZonkRollLeft;
+int *aniInfotronRollRight, *aniInfotronRollLeft;
+int *aniSnikSnak, *aniElectron, *aniExplosion;
+int *aniTouchBase, *aniTouchInfotron, *aniTouchRedDisk;
+// --- const int aniExplosionInfo = 111;
+// --- const int aniSnikSnakUp = 159;
+// --- const int aniSnikSnakDown = 167;
+// --- const int aniSnikSnakLeft = 239;
+// --- const int aniSnikSnakRight = 247;
+// --- const int aniMurphyYawn = 56;
+// --- const int aniMurphySleepLeft = 71;
+// --- const int aniMurphySleepRight = 68;
+int *aniMurphyExit; // , aniMurphyFaceLeft%, aniMurphyFaceRight%
+int *aniMurphyEatLeft, *aniMurphyEatRight; // , aniMurphyEatRightRedDisk
+int *aniMurphyEatUpLeft, *aniMurphyEatUpRight, *aniSplitUpDown;
+int *aniYellowDisk, *aniOrangeDisk, *aniRedDisk;
+// --- const int aniMurphyTouchUp = 46;
+// --- const int aniMurphyTouchLeft = 95;
+// --- const int aniMurphyTouchDown = 47;
+// --- const int aniMurphyTouchRight = 94;
+int *aniEatInfotronLeft, *aniEatInfotronRight;
+// --- const int aniPushLeft = 45;
+// --- const int aniPushRight = 44;
+// --- const int aniPushUpDown = 79;
+
+void InitGlobals()
+{
+ aniBug = Array(74, 75, 76, 77, 78, 77, 76, 77, 78, 77, 76, 75, 74, 25);
+ aniZonkRollRight = Array(198, 197, 196, 195, 194, 193, 192, 1, -1);
+ aniZonkRollLeft = Array(192, 193, 194, 195, 196, 197, 198, 1, -1);
+ aniInfotronRollRight = Array(206, 205, 204, 203, 202, 201, 200, 4);
+ aniInfotronRollLeft = Array(200, 201, 202, 203, 204, 205, 206, 4);
+ aniSnikSnak = Array(121, 122, 123, 124, 125, 126, 127, 120, 121);
+ aniElectron = Array(144, 145, 146, 147, 148, 149, 150, 151, 144);
+ aniExplosion = Array(3, 103, 104, 105, 106, 107, 108, 109, 0);
+ aniTouchBase = Array(80, 81, 82, 83, 84, 85, 86, 0, -1);
+ aniTouchInfotron = Array(87, 88, 89, 91, 92, 93, 0, -1); // Only seven frames!!!!
+ aniTouchRedDisk = Array(96, 97, 98, 99, 100, 101, 102, 0, -1);
+ aniMurphyExit = Array(46, 46, 46, 46, 47, 47, 47, 47, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 0, 0, 0, 0, -1);
+ aniMurphyEatLeft = Array(176, 177, 178, 179, 180, 181, 182, 183, -1);
+ aniMurphyEatRight = Array(184, 185, 186, 187, 188, 189, 190, 191, -1);
+ aniMurphyEatUpLeft = Array(183, 182, 181, 180, 179, 178, 177, 176, -1);
+ aniMurphyEatUpRight = Array(191, 190, 189, 188, 187, 186, 185, 184, -1);
+ // aniMurphyEatRightRedDisk = Array(184, 184, 185, 186, 187, 188, 189, 190, 191, -1) '9 frames!
+ aniEatInfotronLeft = Array(209, 211, 213, 215, 217, 219, 221, 223, -1);
+ aniEatInfotronRight = Array(224, 226, 228, 230, 232, 234, 236, 238, -1);
+ aniSplitUpDown = Array(3, 3, 3, 3, 3, 3, 3, 3, -1);
+ aniYellowDisk = Array(18, 18, 18, 18, 18, 18, 18, 18, -1);
+ aniOrangeDisk = Array(8, 8, 8, 8, 8, 8, 8, 8, -1);
+ aniRedDisk = Array(20, -1);
+ InitPseudoCompileFlags();
+ UserDragFlag = False;
+ AutoScrollFlag = True;
+ FreezeZonks = 0;
+ BlockingSpeed = False;
+ LevelLoaded = False;
+ FieldWidth = 60;
+ FieldHeight = 24;
+ HeaderSize = 96;
+ FieldMax = (FieldWidth * FieldHeight) + HeaderSize - 1;
+ LevelMax = (FieldWidth * FieldHeight) - 1;
+ Let_ModifiedFlag(False);
+ bPlaying = False;
+ gSignature = "";
+ bSignatureAvailable = False;
+ FirstDemoByte = 0x81;
+ MySignature = "";
+ InitErrorReporting();
+}
+
+void InitPseudoCompileFlags()
+{
+ Cracked = 1; // If protection Then crack it
+ Level_Arg = 1; // :number is cmd line option
+ // Level_Arg = 0 ' Remove Level cmd line option
+ EGA_Arg = 1; // EGA is command line option
+ Record_Fix = 1; // Assemble with fixed Demo rec
+ SpeedKeys = 0; // Remove Speed Keys fix
+ Level_Fix = 1; // Assemble with Level Fix
+ Dead_Code = 0; // Remove dead code
+ Redundant = 0; // Remove redundant code
+ Alignments = 1; // Assemble with alignments
+ Ctrl_Alt_Fix = 1; // Assemble with Ctrl/Alt fix
+ Protection = 0; // Remove protection code,do HP
+ // EP added by EP for version 5.
+ EP_ENHANCE = 1; // Some more nice things (EP)
+ EP_DEMO = 1; // Use .SP files for demos (EP)
+ // Including record demo!
+ EP_DEBUG = 0; // little cmdline debugging
+ EXTRASPEED = 1; // '@' option, superfast!
+ TIMINGFIX = 1; // "Fixed" the timing problem..
+ // Inactive If DemoRecordFix Then1
+ SafeRecord = 1; // skip debug keys in recording
+ Norm_Time = 1; // force automatic speed test,
+ // save result and then do as
+ // requested from cmd line.
+ EP_OLD8 = 1; // call old int8 from current.
+ SAVEGAME = 1; // Allow saving to SUPAPLEX.SAV
+ HP_DEMO = 1; // Use fixed demo routines 5.5
+ ScreenFix = 1; // No menu-write to gamy field
+ DemoRecordFix = 1; // Demo record timing fix on
+ DebugSwitch = 1; // Allow Ctrl/Alt-ScrollLock
+ Ver62 = 1; // Version 6.2 stuff
+ Ver62test = 0; // Version 6.2 test stuff
+ Ver63 = 1; // Version 6.3 stuff
+ Ver64 = 1; // Version 6.4 stuff
+
+}
+
+int GetSI(int X, int Y)
+{
+ int GetSI;
+
+ GetSI = Y * FieldWidth + X;
+
+ return GetSI;
+}
+
+int GetX(int si)
+{
+ int GetX;
+
+ GetX = si % FieldWidth;
+
+ return GetX;
+}
+
+int GetY(int si)
+{
+ int GetY;
+
+ GetY = si / FieldWidth;
+
+ return GetY;
+}
+
+int GetStretchX(int si)
+{
+ int GetStretchX;
+
+ GetStretchX = StretchWidth * (si % FieldWidth);
+
+ return GetStretchX;
+}
+
+int GetStretchY(int si)
+{
+ int GetStretchY;
+
+ GetStretchY = StretchWidth * (si / FieldWidth);
+
+ return GetStretchY;
+}
+
+void ReadLevel()
+{
+ // int FNum;
+ FILE *FNum;
+ long i;
+ // byte T;
+
+ DemoAvailable = False;
+ if (STRING_IS_LIKE(CurPath, "*.mpx"))
+ {
+ ReadMPX();
+ return;
+ }
+
+ if (STRING_IS_LIKE(CurPath, "*.sp"))
+ {
+ ReadDemo();
+ return;
+ }
+
+ if (DemoFlag != 0)
+ {
+ ReadDemo();
+ return;
+ }
+
+ FileMax = 0;
+ FieldWidth = 60;
+ FieldHeight = 24;
+ HeaderSize = 96;
+ FieldMax = (FieldWidth * FieldHeight) + HeaderSize - 1;
+ LevelMax = (FieldWidth * FieldHeight) - 1;
+ PlayField8 = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1);
+ DisPlayField = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1);
+ // FNum = FreeFile();
+
+ // --- On Error GoTo ReadLevelEH
+ FNum = fopen(CurPath, "rb");
+ i = (LevelNumber - 1) * ((long)(FieldMax) + 1) + 1;
+ FILE_GET(FNum, i, &PlayField8, sizeof(PlayField8));
+ i = (LevelNumber) * ((long)(FieldMax) + 1) + 1 - HeaderSize;
+ FILE_GET(FNum, i, &LInfo, sizeof(LInfo)); // store level info in an extra structure
+ fclose(FNum);
+ // --- On Error GoTo 0
+
+ if (FieldMax < FileMax)
+ DemoAvailable = True;
+
+ ReadSignature();
+ PlayField16 = REDIM_1D(sizeof(int), -FieldWidth, FieldMax);
+ for (i = 0; i <= FieldMax; i++)
+ {
+ PlayField16[i] = PlayField8[i];
+ DisPlayField[i] = PlayField8[i];
+ PlayField8[i] = 0;
+ }
+
+ AnimationPosTable = REDIM_1D(sizeof(int), 0, LevelMax - 2 *FieldWidth);
+ AnimationSubTable = REDIM_1D(sizeof(byte), 0, LevelMax - 2 *FieldWidth);
+ TerminalState = REDIM_1D(sizeof(byte), FieldWidth, LevelMax - FieldWidth);
+ GravityFlag = LInfo.InitialGravity;
+ FreezeZonks = LInfo.InitialFreezeZonks;
+ subRandomize();
+ LevelLoaded = True;
+ return;
+
+#if 0
+ReadLevelEH:
+ Close();
+#endif
+}
+
+static void ReadDemo()
+{
+ // int FNum, i;
+ FILE *FNum;
+ int i;
+ // byte T;
+
+ FieldWidth = 60;
+ FieldHeight = 24;
+ HeaderSize = 96;
+ FieldMax = (FieldWidth * FieldHeight) + HeaderSize - 1;
+ LevelMax = (FieldWidth * FieldHeight) - 1;
+
+ // --- On Error GoTo ReadDemoEH
+ FileMax = FileLen(CurPath) - 1;
+ PlayField8 = REDIM_1D(sizeof(byte), 0, FileMax + 1 - 1);
+ DisPlayField = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1);
+ // FNum = FreeFile();
+ FNum = fopen(CurPath, "rb");
+ i = (LevelNumber - 1) * ((long)(FieldMax) + 1) + 1;
+ FILE_GET(FNum, i, &PlayField8, sizeof(PlayField8));
+ i = (LevelNumber) * ((long)(FieldMax) + 1) + 1 - HeaderSize;
+ FILE_GET(FNum, i, &LInfo, sizeof(LInfo)); // store level info in an extra structure
+ fclose(FNum);
+ // --- On Error GoTo 0
+
+ if (FieldMax < FileMax)
+ DemoAvailable = True;
+
+ ReadSignature();
+ PlayField16 = REDIM_1D(sizeof(int), -FieldWidth, FieldMax);
+ for (i = 0; i <= FieldMax; i++)
+ {
+ PlayField16[i] = PlayField8[i];
+ DisPlayField[i] = PlayField8[i];
+ PlayField8[i] = 0;
+ }
+
+ AnimationPosTable = REDIM_1D(sizeof(int), 0, LevelMax - 2 *FieldWidth);
+ AnimationSubTable = REDIM_1D(sizeof(byte), 0, LevelMax - 2 *FieldWidth);
+ TerminalState = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1);
+ DemoPointer = FieldMax + 1;
+ DemoOffset = DemoPointer;
+ DemoKeyRepeatCounter = 0;
+ // DemoFlag = 1
+ // DemoAvailable = True
+ GravityFlag = LInfo.InitialGravity;
+ FreezeZonks = LInfo.InitialFreezeZonks;
+ RandomSeed = LInfo.DemoRandomSeed;
+ LevelLoaded = True;
+ return;
+
+#if 0
+ReadDemoEH:
+ Close();
+#endif
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// Globals.h
+// ----------------------------------------------------------------------------
+
+#ifndef GLOBALS_H
+#define GLOBALS_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+#define BaseWidth (16)
+#define StretchWidth (16)
+#define StretchWidth2 (StretchWidth / 2)
+#define TwoPixels (2)
+#define aniExplosionInfo (111)
+#define aniMurphySleepLeft (71)
+#define aniMurphySleepRight (68)
+#define aniMurphyTouchDown (47)
+#define aniMurphyTouchLeft (95)
+#define aniMurphyTouchRight (94)
+#define aniMurphyTouchUp (46)
+#define aniMurphyYawn (56)
+#define aniPushLeft (45)
+#define aniPushRight (44)
+#define aniPushUpDown (79)
+#define aniSnikSnakDown (167)
+#define aniSnikSnakLeft (239)
+#define aniSnikSnakRight (247)
+#define aniSnikSnakUp (159)
+#define fiBase (2)
+#define fiBug (25)
+#define fiElectron (24)
+#define fiExit (7)
+#define fiExplosion (0x1F)
+#define fiHWFirst (28)
+#define fiHWLast (37)
+#define fiHWMurphy (43)
+#define fiHWTrash1 (41)
+#define fiHWTrash2 (42)
+#define fiHardWare (6)
+#define fiInfotron (4)
+#define fiMurphy (3)
+#define fiOrangeDisk (8)
+#define fiPortAllDirections (23)
+#define fiPortDown (10)
+#define fiPortLeft (11)
+#define fiPortLeftAndRight (22)
+#define fiPortRight (9)
+#define fiPortUp (12)
+#define fiPortUpAndDown (21)
+#define fiRAM (5)
+#define fiRAMBottom (39)
+#define fiRAMLeft (26)
+#define fiRAMRight (27)
+#define fiRAMTop (38)
+#define fiRedDisk (20)
+#define fiSnikSnak (17)
+#define fiSpPortDown (14)
+#define fiSpPortLeft (15)
+#define fiSpPortRight (13)
+#define fiSpPortUp (16)
+#define fiSpace (0)
+#define fiTerminal (19)
+#define fiWallSpace (40)
+#define fiYellowDisk (18)
+#define fiZonk (1)
+#define keyDown (3)
+#define keyLeft (2)
+#define keyNone (0)
+#define keyRight (4)
+#define keySpace (9)
+#define keySpaceDown (7)
+#define keySpaceLeft (6)
+#define keySpaceRight (8)
+#define keySpaceUp (5)
+#define keyUp (1)
+#define posFrameCorner (55)
+#define posFrameHorizontal (111)
+#define posFrameVertical (110)
+
+extern int GetSI(int X, int Y);
+extern int GetStretchX(int si);
+extern int GetStretchY(int si);
+extern int GetX(int si);
+extern int GetY(int si);
+extern void InitGlobals();
+extern void InitPseudoCompileFlags();
+
+extern void ReadLevel();
+
+extern boolean Alignments;
+extern boolean BlockingSpeed;
+extern boolean Cracked;
+extern boolean Ctrl_Alt_Fix;
+extern boolean Dead_Code;
+extern boolean DebugSwitch;
+extern boolean DemoRecordFix;
+extern boolean EGA_Arg;
+extern boolean EP_DEBUG;
+extern boolean EP_DEMO;
+extern boolean EP_ENHANCE;
+extern boolean EP_OLD8;
+extern boolean EXTRASPEED;
+extern boolean HP_DEMO;
+extern boolean LevelLoaded;
+extern boolean Level_Arg;
+extern boolean Level_Fix;
+extern boolean Norm_Time;
+extern boolean Original;
+extern boolean Protection;
+extern boolean Record_Fix;
+extern boolean Redundant;
+extern boolean SAVEGAME;
+extern boolean SafeRecord;
+extern boolean ScreenFix;
+extern boolean SpeedKeys;
+extern boolean TIMINGFIX;
+extern boolean Ver62;
+extern boolean Ver62test;
+extern boolean Ver63;
+extern boolean Ver64;
+extern boolean bCapturePane;
+extern byte *DisPlayField;
+extern byte *PlayField8;
+extern char *CurPath, *OrigPath, *TmpPath;
+extern currency DeltaT;
+extern int *PlayField16;
+extern int *aniBug, *aniZonkRollRight, *aniZonkRollLeft;
+extern int *aniEatInfotronLeft, *aniEatInfotronRight;
+extern int *aniInfotronRollRight, *aniInfotronRollLeft;
+extern int *aniMurphyEatLeft, *aniMurphyEatRight;
+extern int *aniMurphyEatUpLeft, *aniMurphyEatUpRight, *aniSplitUpDown;
+extern int *aniMurphyExit;
+extern int *aniSnikSnak, *aniElectron, *aniExplosion;
+extern int *aniTouchBase, *aniTouchInfotron, *aniTouchRedDisk;
+extern int *aniYellowDisk, *aniOrangeDisk, *aniRedDisk;
+extern int FieldHeight;
+extern int FieldMax, LevelMax;
+extern int FieldWidth;
+extern int FreezeZonks;
+extern int HeaderSize;
+extern int LevelNumber;
+extern int TimerVar, RandomSeed;
+extern long DeltaTPlay, DeltaTDemo;
+extern long FileMax;
+extern long SignatureDelay;
+
+#endif /* GLOBALS_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// Infotrons.c
+// ----------------------------------------------------------------------------
+
+#include "Infotrons.h"
+
+static char *VB_Name = "modInfotron";
+// --- Option Explicit
+
+// ==========================================================================
+// SUBROUTINE
+// Animate Infotrons (falling)
+// ==========================================================================
+
+int subAnimateInfotrons(int si)
+{
+ int subAnimateInfotrons;
+
+ int tFld;
+
+ // PseudoRegisters:
+ int ax, bx, cx, dx, di, X, Y;
+ int ah, bh, ch, dh, al, bl, cl, dl;
+
+ tFld = PlayField16[si];
+ if ((tFld & 0xFF) != fiInfotron)
+ return subAnimateInfotrons;
+
+ if (tFld == fiInfotron)
+ {
+ ax = PlayField16[si + FieldWidth]; // select case playfield16(si+60)
+ if (ax == 0)
+ goto loc_g_11D5;
+
+ if (ax == fiZonk)
+ goto loc_g_11A6;
+
+ if (ax == fiInfotron)
+ goto loc_g_11A6;
+
+ if (ax == fiRAM)
+ goto loc_g_11A6;
+
+ return subAnimateInfotrons;
+
+loc_g_11A6: // Case fiZonk, fiInfotron, fiRAM
+ ax = PlayField16[si + FieldWidth - 1];
+ if (ax == 0 || ax == 0x8888 || ax == 0xAAAA)
+ goto loc_g_11DC;
+
+loc_g_11BD:
+ ax = PlayField16[si + FieldWidth + 1];
+ if (ax == 0 || ax == 0x8888 || ax == 0xAAAA)
+ goto loc_g_11F2;
+
+ return subAnimateInfotrons;
+
+loc_g_11D5: // Case fiSpace
+ MovHighByte(&PlayField16[si], 0x40);
+ goto loc_g_1207;
+
+loc_g_11DC: // roll left?
+ if (PlayField16[si - 1] == 0)
+ goto loc_g_11E5;
+
+ goto loc_g_11BD;
+
+loc_g_11E5:
+ MovHighByte(&PlayField16[si], 0x50);
+ PlayField16[si - 1] = 0x8888;
+ goto loc_g_1207;
+
+loc_g_11F2: // roll right?
+ if (PlayField16[si + 1] == 0)
+ goto loc_g_11FA;
+
+ return subAnimateInfotrons;
+
+loc_g_11FA:
+ MovHighByte(&PlayField16[si], 0x60);
+ PlayField16[si + 1] = 0x8888;
+ } // tFld = fiInfotron
+
+loc_g_1207:
+ // from now on the infotron is definitely moving,
+ // maybe the sequence is in an advanced frame
+ // or just beeing initialized due to the code above
+ bl = HighByte(PlayField16[si]);
+ bx = 0;
+ MovLowByte(&bx, bl);
+ al = bl & 0xF0;
+ if (al == 0x10) // infotron comes falling from above
+ goto loc_g_1242;
+
+ if (al == 0x20) // infotron comes rolling from right to left
+ goto loc_g_138D;
+
+ if (al == 0x30) // infotron comes rolling from left to right
+ goto loc_g_13E9;
+
+ if (al == 0x40) // infotron falls straight down
+ goto loc_g_1444;
+
+ if (al == 0x50) // infotron rolls left
+ goto loc_g_1472;
+
+ if (al == 0x60) // infotron rolls right
+ goto loc_g_14E0;
+
+ if (al == 0x70) // intermediate state
+ goto loc_g_154E;
+
+ return subAnimateInfotrons;
+
+loc_g_1242: // infotron comes falling from above
+ // To Do: draw infotron falling from above
+ // according to position in (bl And &H07)
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ X = GetStretchX(si);
+ Y = GetStretchY(si - FieldWidth);
+ dx = bl & 0x7;
+ StretchedSprites.BltEx(X, Y, 0);
+ StretchedSprites.BltEx(X, Y + TwoPixels * (dx + 1), fiInfotron);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ bl = HighByte(PlayField16[si]) + 1;
+ if (bl == 0x16)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ subCleanUpForInfotronsAbove(si - FieldWidth);
+ return subAnimateInfotrons;
+ } // loc_g_1285:
+
+ if (bl < 0x18)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ return subAnimateInfotrons;
+ } // loc_g_128F:
+
+ MovHighByte(&PlayField16[si], 0); // infotron arrived at the field
+
+ // now check if the zonk may go on falling somehow
+ ax = PlayField16[si + FieldWidth];
+ if (ax == 0) // below is empty!-> go on falling
+ goto loc_g_132D;
+
+ if (ax == 0x9999) // below is only temporarily used
+ goto loc_g_132D;
+
+ if ((ax & 0xFF) == fiMurphy) // Murphy dies
+ goto loc_g_1364;
+
+ if (ax == fiRedDisk) // red disk hit
+ goto loc_g_1386;
+
+ if ((ax & 0xFF) == fiSnikSnak) // SnikSnak dies
+ goto loc_g_1386;
+
+
+ if ((ax & 0xFF) == fiElectron) // Electron cracked!
+ goto loc_g_1386;
+
+ if (ax == fiYellowDisk) // yellow disk hit
+ goto loc_g_1386;
+
+ if (ax == fiOrangeDisk) // orange disk hit
+ goto loc_g_1386;
+
+ subSoundFXZonk(); // play the zonk sound,'cause zonk hits something "hard"
+
+ if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM))
+ return subAnimateInfotrons;
+
+ // infotron rolls somewhere
+ ax = PlayField16[si + FieldWidth - 1];
+ if (ax == 0 || ax == 0x8888 || ax == 0xAAAA) // may roll left
+ goto loc_g_133A;
+
+ ax = PlayField16[si + FieldWidth + 1];
+ if (ax == 0 || ax == 0x8888 || ax == 0xAAAA) // may roll right
+ goto loc_g_1350;
+
+ return subAnimateInfotrons;
+
+loc_g_132D: // go on falling down?
+ PlayField16[si] = 0x7004; // go into intermediate waitstate
+ PlayField16[si + FieldWidth] = 0x9999; // mark as "zonk waiting to access"
+ return subAnimateInfotrons;
+
+loc_g_133A: // test if infotron may roll left
+ // This if(if true) jumps up far above
+ // to the according rountine for fixed infotrons!
+ if (PlayField16[si - 1] != 0) // Remarkable!!! ' loc_g_0EF4:
+ goto loc_g_11BD;
+
+ MovHighByte(&PlayField16[si], 0x50); // infotron rolls left
+ Mov(&PlayField16[si - 1], 0x8888);
+ return subAnimateInfotrons;
+
+loc_g_1350: // test if infotron may roll right
+ if (PlayField16[si + 1] != 0)
+ return subAnimateInfotrons;
+
+ MovHighByte(&PlayField16[si], 0x60); // infotron rolls right
+ Mov(&PlayField16[si + 1], 0x8888);
+ return subAnimateInfotrons;
+
+loc_g_1364: // Murphy dies, but not in any case
+ bl = HighByte(PlayField16[si + FieldWidth]);
+ if (bl == 0xE || bl == 0xF || bl == 0x28)
+ return subAnimateInfotrons;
+
+ if (bl == 0x29 || bl == 0x25 || bl == 0x26)
+ return subAnimateInfotrons;
+
+
+
+
+
+
+
+
+
+
+
+loc_g_1386: // someone dies/explodes immediately
+ si = si + FieldWidth; // 1 field down
+ ExplodeFieldSP(si); // Explode
+ return subAnimateInfotrons;
+
+
+
+
+
+loc_g_138D: // infotron comes rolling from right to left
+ // To Do: draw infotron rolling from right
+ // according to position in (bl And &H07)
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ X = GetStretchX(si + 1);
+ Y = GetStretchY(si);
+ dx = (bl & 0x7) + 1;
+ StretchedSprites.BltEx(X, Y, 0);
+ StretchedSprites.BltEx(X - (TwoPixels * dx), Y, aniInfotronRollLeft[dx - 1]);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ bl = HighByte(PlayField16[si]) + 1; // get and increment sequence#
+ if (bl == 0x24)
+ PlayField16[si + 1] = 0xAAAA;
+
+ if (bl == 0x26)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ subCleanUpForInfotronsAbove(si + 1);
+ }
+ else if (bl < 0x28)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ }
+ else
+ {
+ PlayField16[si] = 0x7004; // go into intermediate state
+ }
+
+ return subAnimateInfotrons;
+
+loc_g_13E9: // infotron comes rolling from left to right
+ // To Do: draw infotron rolling from left
+ // according to position in (bl And &H07)
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ X = GetStretchX(si - 1);
+ Y = GetStretchY(si);
+ dx = (bl & 0x7) + 1;
+ StretchedSprites.BltEx(X, Y, 0);
+ StretchedSprites.BltEx(X + (TwoPixels * dx), Y, aniInfotronRollRight[dx - 1]);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ bl = HighByte(PlayField16[si]) + 1;
+ if (bl == 0x34)
+ PlayField16[si - 1] = 0xAAAA;
+
+ if (bl == 0x36)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ subCleanUpForInfotronsAbove(si - 1);
+ }
+ else if (bl < 0x38)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ }
+ else
+ {
+ PlayField16[si] = 0x7004; // go into intermediate state
+ }
+
+ return subAnimateInfotrons;
+
+loc_g_1444: // infotron falls straight down
+ bl = bl + 1;
+ if (bl < 0x42)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ }
+ else if (PlayField16[si + FieldWidth] != 0)
+ {
+ bl = bl - 1; // stay waiting
+ MovHighByte(&PlayField16[si], bl);
+ }
+ else
+ {
+ PlayField16[si] = 0xFFFF;
+ si = si + FieldWidth; // 1 field down
+ PlayField16[si] = 0x1004; // go falling
+ }
+
+ return subAnimateInfotrons;
+
+loc_g_1472: // infotron rolls left
+ // To Do: draw infotron rolling to left
+ // according to position in (bl And &H0F)
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ X = GetStretchX(si);
+ Y = GetStretchY(si);
+ dx = (bl & 0xF) + 1;
+ StretchedSprites.BltEx(X, Y, 0);
+ StretchedSprites.BltEx(X - (TwoPixels * dx), Y, aniInfotronRollLeft[dx - 1]);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ bl = HighByte(PlayField16[si]) + 1; // retrieve and increment sequence#
+ if (bl < 0x52)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ return subAnimateInfotrons;
+ }
+
+ if (PlayField16[si + FieldWidth - 1] != 0)
+ goto loc_g_14D9;
+
+ if (PlayField16[si - 1] != 0)
+ {
+ if (PlayField16[si - 1] != 0x8888)
+ goto loc_g_14D9;
+ }
+
+ PlayField16[si] = 0xFFFF;
+ si = si - 1; // 1 field left
+ PlayField16[si] = 0x2204;
+ PlayField16[si + FieldWidth] = 0x9999;
+ return subAnimateInfotrons;
+
+loc_g_14D9: // stay waiting
+ bl = bl - 1;
+ MovHighByte(&PlayField16[si], bl);
+ return subAnimateInfotrons;
+
+loc_g_14E0: // infotron rolls right
+ // To Do: draw infotron rolling to right
+ // according to position in (bl And &H07)
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ X = GetStretchX(si);
+ Y = GetStretchY(si);
+ dx = (bl & 0x7) + 1;
+ StretchedSprites.BltEx(X, Y, 0);
+ StretchedSprites.BltEx(X + (TwoPixels * dx), Y, aniInfotronRollRight[dx - 1]);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ bl = HighByte(PlayField16[si]) + 1;
+ if (bl < 0x62)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ return subAnimateInfotrons;
+ }
+
+ if (PlayField16[si + FieldWidth + 1] != 0)
+ goto loc_g_1547;
+
+ if (PlayField16[si + 1] != 0)
+ {
+ if (PlayField16[si + 1] != 0x8888)
+ goto loc_g_1547;
+ }
+
+ PlayField16[si] = 0xFFFF;
+ si = si + 1;
+ PlayField16[si] = 0x3204;
+ PlayField16[si + FieldWidth] = 0x9999;
+ return subAnimateInfotrons;
+
+loc_g_1547: // stay waiting
+ bl = bl - 1;
+ MovHighByte(&PlayField16[si], bl);
+ return subAnimateInfotrons;
+
+loc_g_154E: // intermediate state
+ ax = PlayField16[si + FieldWidth];
+ if (ax == 0 || ax == 0x9999)
+ {
+ PlayField16[si] = 0xFFFF;
+ si = si + FieldWidth; // 1 field down
+ PlayField16[si] = 0x1004; // start falling down
+ goto loc_g_1242;
+ }
+
+ return subAnimateInfotrons;
+} // subAnimateInfotrons
+
+int subCleanUpForInfotronsAbove(int si)
+{
+ int subCleanUpForInfotronsAbove;
+
+ int ax;
+
+ if (LowByte(PlayField16[si]) != fiExplosion)
+ PlayField16[si] = 0;
+
+ if (PlayField16[si - FieldWidth] != 0)
+ {
+ if (PlayField16[si - FieldWidth] != 0x9999)
+ return subCleanUpForInfotronsAbove;
+
+ if (LowByte(PlayField16[si - 2 * FieldWidth]) != fiZonk)
+ return subCleanUpForInfotronsAbove;
+ }
+
+ if (PlayField16[si - FieldWidth - 1] == fiInfotron)
+ goto loc_g_16FE;
+
+loc_g_16F6:
+ if (PlayField16[si - FieldWidth + 1] == fiInfotron)
+ goto loc_g_1722;
+
+ return subCleanUpForInfotronsAbove;
+
+loc_g_16FE:
+ ax = PlayField16[si - 1];
+ if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
+ {
+ PlayField16[si - FieldWidth - 1] = 0x6004;
+ PlayField16[si - FieldWidth] = 0x8888;
+ return subCleanUpForInfotronsAbove;
+ }
+
+ goto loc_g_16F6;
+
+loc_g_1722:
+ ax = PlayField16[si + 1];
+ if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
+ {
+ PlayField16[si - FieldWidth + 1] = 0x5004;
+ PlayField16[si - FieldWidth] = 0x8888;
+ }
+
+ return subCleanUpForInfotronsAbove;
+} // subCleanUpForInfotronsAbove
+
--- /dev/null
+// ----------------------------------------------------------------------------
+// Infotrons.h
+// ----------------------------------------------------------------------------
+
+#ifndef INFOTRONS_H
+#define INFOTRONS_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern int subAnimateInfotrons(int si);
+extern int subCleanUpForInfotronsAbove(int si);
+
+#endif /* INFOTRONS_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// InitGameConditions.c
+// ----------------------------------------------------------------------------
+
+#include "InitGameConditions.h"
+
+static char *VB_Name = "modInitGameConditions";
+// --- Option Explicit
+
+// ==========================================================================
+// SUBROUTINE
+// Init game conditions (variables)
+// ==========================================================================
+
+int subInitGameConditions()
+{
+ int subInitGameConditions;
+
+ bCapturePane = False;
+
+ MurphyVar0DAC = MurphyYPos;
+ MurphyVar0DAE = MurphyXPos;
+ MurphyVarFaceLeft = 0;
+ KillMurphyFlag = 0; // no "kill Murphy"
+ ExitToMenuFlag = 0;
+ LeadOutCounter = 0; // quit flag: lead-out counter
+ RedDiskCount = 0; // Red disk counter
+ ShowRedDiskCounter = 0; // show-red-disk time-out
+
+ YawnSleepCounter = 0; // Wake up sleeping Murphy
+
+ data_h_0DA7 = 0xFF;
+ data_h_0DA8 = 0xFF;
+ data_h_0DA9 = 0xFF;
+ data_h_0D9E = 1;
+ data_h_0D9F = 0;
+ data_h_0DA0 = 0;
+ data_h_0DA1 = 0;
+ data_h_0DA2 = 0;
+ data_h_0DA4 = 0;
+ data_h_0DA5 = 0;
+ data_h_0DA6 = 0;
+
+ ExplosionShake = 0; // Force explosion flag off
+
+ TerminalMaxCycles = 0x7F;
+ YellowDisksExploded = 0;
+
+ TimerVar = 0;
+ // ShowPanel = 1 ' Force Panel on
+ // MainForm.PanelVisible = True;
+ EnterRepeatCounter = 0; // restart Enter repeat counter
+ SnikSnaksElectronsFrozen = 0; // Snik-Snaks and Electr. move!
+
+ SplitMoveFlag = 0; // Reset Split-through-ports
+ RedDiskReleasePhase = 0; // (re-)enable red disk release
+ RedDiskReleaseMurphyPos = 0; // Red disk was released here
+
+
+ return subInitGameConditions;
+} // subInitGameConditions
+
+
+// ==========================================================================
+// SUBROUTINE
+// Locate Murphy and init location.
+// ==========================================================================
+
+int InitMurphyPos()
+{
+ int InitMurphyPos;
+
+ int si;
+
+ for (si = 0; si <= LevelMax - 1; si++)
+ {
+ if (PlayField16[si] == fiMurphy)
+ break;
+ }
+
+ InitMurphyPosB(si);
+ MurphyPosIndex = si;
+
+ return InitMurphyPos;
+} // InitMurphyPos
+
+int InitMurphyPosB(int si)
+{
+ int InitMurphyPosB;
+
+ MurphyYPos = GetStretchY(si) / Stretch;
+ MurphyXPos = GetStretchX(si) / Stretch;
+
+ MurphyScreenXPos = GetStretchX(si); // Murphy's screen x-position
+ MurphyScreenYPos = GetStretchY(si); // Murphy's screen y-position
+
+ // To Do: draw Murphy in location ax
+ StretchedSprites.BltEx(MurphyScreenXPos, MurphyScreenYPos, fiMurphy);
+
+ MurphyScreenXPos = MurphyScreenXPos / Stretch;
+ MurphyScreenYPos = MurphyScreenYPos / Stretch;
+
+ subCalculateScreenScrollPos(); // calculate screen start addrs
+ if (AutoScrollFlag)
+ {
+ if (bPlaying)
+ {
+ SoftScrollTo(ScreenScrollXPos, ScreenScrollYPos, 1000, 25);
+ }
+ else
+ {
+ ScrollTo(ScreenScrollXPos, ScreenScrollYPos);
+ }
+ }
+
+ return InitMurphyPosB;
+} // InitMurphyPosB
+
+// ==========================================================================
+// SUBROUTINE
+// Convert to easy symbols and reset Infotron count If not ThenVer62
+// ==========================================================================
+
+int subConvertToEasySymbols()
+{
+ int subConvertToEasySymbols;
+
+ int ax, bx, cx, dx, di, X, Y, i;
+ int ah, bh, ch, dh, al, bl, cl, dl, ZF;
+
+ bx = 0;
+ dx = 0;
+ cx = LevelMax + 1;
+ i = 0;
+
+loc_g_26C9:
+ ax = PlayField16[i];
+ al = LowByte(ax);
+ if (al == 0xF1) // converted explosion?
+ {
+ MovLowByte(&PlayField16[i], 0x1F); // restore explosions
+ goto loc_g_2778;
+ }
+
+ if (LowByte(GameBusyFlag) != 1) // free screen write?
+ {
+ if (ax == fiInfotron) // Infotron? -> yes--count!
+ goto loc_g_2704;
+
+ if (ax == fiSnikSnak) // Snik Snak? -> yes--rearrange
+ goto loc_g_2713;
+
+ if (ax == fiElectron) // Electron? -> yes--rearrange
+ goto loc_g_2741;
+ }
+
+ // test for fancy RAM Chips:
+ if (ax == fiRAMLeft || ax == fiRAMRight)
+ goto loc_g_2707;
+
+ if (ax == fiRAMTop || ax == fiRAMBottom)
+ goto loc_g_2707;
+
+ if (ax < fiHWFirst) // All but deco hardware?
+ goto loc_g_26F8;
+
+ if (ax < fiRAMTop) // Decorative hardware?
+ goto loc_g_270D;
+
+loc_g_26F8:
+ if (ax < fiSpPortRight) // Gravity change ports only?
+ goto loc_g_2778;
+
+ if (ax < fiSnikSnak) // Gravity change port! 'loc_g_2702:
+ goto loc_g_276F;
+
+ goto loc_g_2778;
+
+loc_g_2704: // INFOTRON
+ dx = dx + 1; // Count Infotrons
+ goto loc_g_2778;
+
+loc_g_2707: // DECO RAM CHIPS
+ PlayField16[i] = fiRAM; // Convert to standard RAM chip
+ goto loc_g_2778;
+
+loc_g_270D: // DECO HARDWARE
+ PlayField16[i] = fiHardWare; // Convert to standard hardware
+ goto loc_g_2778;
+
+loc_g_2713: // SNIK-SNAK
+ if (PlayField16[i - 1] != 0) // 1 field left empty? -> no--try up
+ goto loc_g_271F;
+
+ MovHighByte(&PlayField16[i], 1); // turn left, step = NorthWest
+ goto loc_g_2778;
+
+loc_g_271F:
+ if (PlayField16[i - FieldWidth] != 0) // 1 field up empty? -> no--try right
+ goto loc_g_2730;
+
+ PlayField16[i - FieldWidth] = 0x1011; // SnikSnak accessing from below, step = 0
+ PlayField16[i] = 0xFFFF;
+ goto loc_g_2778;
+
+loc_g_2730:
+ if (PlayField16[i + 1] != 0) // 1 field right empty? -> point up
+ goto loc_g_2778;
+
+ PlayField16[i + 1] = 0x2811; // SnikSnak accessing from left, step = 0
+ PlayField16[i] = 0xFFFF;
+ goto loc_g_2778;
+
+loc_g_2741: // ELECTRON
+ if (PlayField16[i - 1] != 0) // 1 field left empty? -> no--try up
+ goto loc_g_274D;
+
+ MovHighByte(&PlayField16[i], 1);
+ goto loc_g_2778;
+
+loc_g_274D:
+ if (PlayField16[i - FieldWidth] != 0) // 1 field up empty? -> no--try right
+ goto loc_g_275E;
+
+ PlayField16[i - FieldWidth] = 0x1018; // 1 field up
+ PlayField16[i] = 0xFFFF;
+ goto loc_g_2778;
+
+loc_g_275E:
+ if (PlayField16[i + 1] != 0) // 1 field right empty? -> no--point down
+ goto loc_g_2778;
+
+ PlayField16[i + 1] = 0x2818;
+ PlayField16[i] = 0xFFFF;
+ goto loc_g_2778;
+
+loc_g_276F: // GRAVITY CHANGING PORTS
+ PlayField16[i] = (ax - 4) | 0x100; // Convert to standard ports
+ goto loc_g_2778;
+
+loc_g_2778:
+ i = i + 1; // Next field
+ bx = bx + 1;
+ cx = cx - 1;
+ if (0 < cx) // Until all done 'loc_g_2782:
+ goto loc_g_26C9;
+
+ subConvertToEasySymbols = dx; // return InfotronCount
+
+ return subConvertToEasySymbols;
+} // subConvertToEasySymbols
+
+// ==========================================================================
+// SUBROUTINE
+// Reset Infotron count. Call immediately after subConvertToEasySymbols
+// ==========================================================================
+
+int ResetInfotronsNeeded(int dx)
+{
+ int ResetInfotronsNeeded;
+
+ if (LInfo.InfotronsNeeded != 0) // Jump If equal (autodetect)
+ {
+ dx = LInfo.InfotronsNeeded;
+ } // loc_g_278D:
+
+ InfotronsNeeded = LowByte(dx); // Remaining Infotrons needed
+ TotalInfotronsNeeded = InfotronsNeeded; // Number of Infotrons needed
+ subDisplayInfotronsNeeded();
+
+ return ResetInfotronsNeeded;
+} // ResetInfotronsNeeded
+
+
+// ==========================================================================
+// SUBROUTINE
+// Fetch and initialize a level
+// ==========================================================================
+
+int subFetchAndInitLevelB()
+{
+ int subFetchAndInitLevelB;
+
+ boolean UpdatePlayTime;
+
+ MovLowByte(&data_SPtorunavail, 0); // no SP file
+ data_scr_demo = 0;
+ UpdatePlayTime = (0 == demo_stopped ? True : True);
+ demo_stopped = 0;
+ subFetchAndInitLevelA(UpdatePlayTime);
+
+ return subFetchAndInitLevelB;
+} // subFetchAndInitLevelb
+
+int subFetchAndInitLevelA(boolean UpdatePlayTime)
+{
+ int subFetchAndInitLevelA;
+
+ if (UpdatePlayTime && (0 == demo_stopped))
+ {
+ subUpdatePlayingTime(); // update playing time
+ }
+
+ D_ModeFlag = 0; // 1=debug D pressed (CPU use)
+ if (0 != demo_stopped) // 1=demo, 0=game
+ DemoFlag = 1;
+
+ GameBusyFlag = 0; // restore scissors too
+ subFetchAndInitLevel(); // Fetch and initialize a level
+ GameBusyFlag = 1; // no free screen write
+ if (1 <= demo_stopped)
+ {
+ if (1 == demo_stopped)
+ {
+ DemoFlag = 0; // 1=demo, 0=game
+ demo_stopped = demo_stopped + 1;
+ }
+ else
+ {
+ DemoFlag = 0; // 1=demo, 0=game
+ }
+ }
+
+ DemoKeyCode = 0; // delete last demo key!
+ if (DemoFlag != 0) // don't allow during game! only in Demo
+ {
+ DemoOffset = DemoPointer; // init demo pointer
+ DemoKeyRepeatCounter = 1;
+ subGetNextDemoKey(); // get next demo byte
+ }
+
+ return subFetchAndInitLevelA;
+} // subFetchAndInitLevela
+
+int subFetchAndInitLevel()
+{
+ int subFetchAndInitLevel;
+
+ int InfoCountInLevel;
+
+ Trace("modInitGameConditions", "--> subFetchAndInitLevel");
+ Trace("modInitGameConditions", "Call ReadLevel");
+ ReadLevel(); // Read LEVELS.DAT
+ Trace("modInitGameConditions", "ReadLevel return subFetchAndInitLeveled");
+
+ if (RecordDemoFlag == 1)
+ {
+ RecDemoRandomSeed = RandomSeed;
+ // Debug.Print "FetchRec: " & Hex(RandomSeed)
+ }
+
+ // If DemoFlag = 1 Then
+ // Debug.Print "FetchPlay: " & Hex(RandomSeed)
+ // End If
+ GameBusyFlag = -GameBusyFlag; // make <>1
+ Trace("modInitGameConditions", "subConvertToEasySymbols");
+ InfoCountInLevel = subConvertToEasySymbols(); // Convert to easy symbols
+ GameBusyFlag = -GameBusyFlag; // restore
+ Trace("modInitGameConditions", "subDisplayLevel");
+ subDisplayLevel(); // Paint (Init) game field
+ subDisplayPanel(); // Paint (Init) Panel
+ ResetInfotronsNeeded(InfoCountInLevel); // and reset Infotron count
+ Data_SubRstFlg = 1;
+ Trace("modInitGameConditions", "subInitGameConditions");
+ subInitGameConditions(); // Init game conditions (vars)
+ InitMurphyPos(); // Locate Murphy + screen pos
+ Trace("modInitGameConditions", "<-- subFetchAndInitLevel");
+
+ return subFetchAndInitLevel;
+} // subFetchAndInitLevel
--- /dev/null
+// ----------------------------------------------------------------------------
+// InitGameConditions.h
+// ----------------------------------------------------------------------------
+
+#ifndef INITGAMECONDITIONS_H
+#define INITGAMECONDITIONS_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern int InitMurphyPos();
+extern int InitMurphyPosB(int si);
+extern int ResetInfotronsNeeded(int dx);
+extern int subConvertToEasySymbols();
+extern int subFetchAndInitLevel();
+extern int subFetchAndInitLevelA(boolean UpdatePlayTime);
+extern int subFetchAndInitLevelB();
+extern int subInitGameConditions();
+
+#endif /* INITGAMECONDITIONS_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// Input.c
+// ----------------------------------------------------------------------------
+
+#include "Input.h"
+
+static char *VB_Name = "modInput";
+// --- Option Explicit
+
+boolean KeyState[255 + 1];
+DemoBufferObject DemoBuffer;
+
+//
+// Public KeyFlagSpace As Boolean
+// Public KeyFlagUp As Boolean
+// Public KeyFlagLeft As Boolean
+// Public KeyFlagDown As Boolean
+// Public KeyFlagRight As Boolean
+// Public KeyFlagEnter As Boolean
+// Public KeyFlagESC As Boolean
+// Public KeyFlagR As Boolean
+// Public KeyFlagRShift As Boolean
+
+int KeyScanCode7;
+
+void subCheckJoystick()
+{
+}
+
+int subCheckRightMouseButton()
+{
+ int subCheckRightMouseButton;
+
+ // return button state
+
+ return subCheckRightMouseButton;
+}
+
+int subProcessKeyboardInput()
+{
+ int subProcessKeyboardInput;
+
+ int LastKey;
+
+ // On Error GoTo NoKeyboardAccessEH
+ // Call DKeyboard.Acquire
+ // On Error GoTo 0
+ // Call DKeyboard.GetDeviceStateKeyboard(KeyState)
+ // With KeyState
+ if (DemoFlag != 0)
+ {
+ subGetNextDemoKey();
+ if (ExitToMenuFlag != 0)
+ return subProcessKeyboardInput;
+
+ }
+ else
+ {
+ if (KeyState[vbKeySpace])
+ {
+ if (KeyState[vbKeyUp])
+ {
+ DemoKeyCode = keySpaceUp;
+ }
+ else if (KeyState[vbKeyLeft])
+ {
+ DemoKeyCode = keySpaceLeft;
+ }
+ else if (KeyState[vbKeyDown])
+ {
+ DemoKeyCode = keySpaceDown;
+ }
+ else if (KeyState[vbKeyRight])
+ {
+ DemoKeyCode = keySpaceRight;
+ }
+ else
+ {
+ DemoKeyCode = keySpace;
+ }
+
+ }
+ else
+ {
+ if (KeyState[vbKeyUp])
+ {
+ DemoKeyCode = keyUp;
+ }
+ else if (KeyState[vbKeyLeft])
+ {
+ DemoKeyCode = keyLeft;
+ }
+ else if (KeyState[vbKeyDown])
+ {
+ DemoKeyCode = keyDown;
+ }
+ else if (KeyState[vbKeyRight])
+ {
+ DemoKeyCode = keyRight;
+ }
+ else
+ {
+ DemoKeyCode = keyNone;
+ }
+ }
+ }
+
+ // demo recording
+ if (RecordDemoFlag == 1)
+ DemoBuffer.AddDemoKey(DemoKeyCode);
+
+ if (DemoKeyCode != LastKey && ! NoDisplayFlag)
+ {
+#if 0
+ MainForm.ShowKey(DemoKeyCode);
+#endif
+ LastKey = DemoKeyCode;
+ }
+
+ if (KeyState[vbKeyEscape])
+ {
+ if (BlockingSpeed)
+ {
+ // Call MainForm.menSpeed_Click(4)
+ }
+ else
+ {
+ KillMurphyFlag = 1;
+ // ExplodeFieldSP MurphyPosIndex
+ // LeadOutCounter = &H20
+ }
+ }
+
+ if (KeyState[vbKeyR])
+ {
+ subFetchAndInitLevelB();
+ }
+
+ if (KeyState[vbKeyShift])
+ subDisplayRedDiskCount();
+
+#if 0
+ if (KeyState[vbKeyReturn])
+ MainForm.PanelVisible = (ShowPanel == 0);
+#endif
+
+ // End With
+ // Call DKeyboard.Unacquire
+ return subProcessKeyboardInput;
+
+NoKeyboardAccessEH:
+ Debug.Print("! Keyboard access");
+
+ return subProcessKeyboardInput;
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// Input.h
+// ----------------------------------------------------------------------------
+
+#ifndef INPUT_H
+#define INPUT_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern void subCheckJoystick();
+extern int subCheckRightMouseButton();
+extern int subProcessKeyboardInput();
+
+extern DemoBufferObject DemoBuffer;
+extern boolean KeyState[255 + 1];
+extern int KeyScanCode7;
+
+#endif /* INPUT_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// LevelSetPreviewForm.c
+// ----------------------------------------------------------------------------
+
+#include "LevelSetPreviewForm.h"
+
+// --- VERSION 5.00
+// --- Begin VB.Form LevelSetPreviewForm
+// --- BorderStyle = 4 'Fixed ToolWindow // Fixed ToolWindow
+// --- Caption = "Level Set Preview"
+// --- ClientHeight = 10860
+// --- ClientLeft = 4890
+// --- ClientTop = 2760
+// --- ClientWidth = 6585
+// --- LinkTopic = "Form1"
+// --- MaxButton = 0 'False // False
+// --- MinButton = 0 'False // False
+// --- ScaleHeight = 724
+// --- ScaleMode = 3 'Pixel // Pixel
+// --- ScaleWidth = 439
+// --- ShowInTaskbar = 0 'False // False
+// --- Begin VB.PictureBox pic
+// --- BackColor = &H00000000&
+// --- Height = 2475
+// --- Left = 480
+// --- ScaleHeight = 161
+// --- ScaleMode = 3 'Pixel // Pixel
+// --- ScaleWidth = 349
+// --- TabIndex = 0
+// --- Top = 360
+// --- Width = 5295
+// --- End
+// --- End
+
+static char *VB_Name = "LevelSetPreviewForm";
+static boolean VB_GlobalNameSpace = False;
+static boolean VB_Creatable = False;
+static boolean VB_PredeclaredId = True;
+static boolean VB_Exposed = False;
+// --- Option Explicit
+
--- /dev/null
+// ----------------------------------------------------------------------------
+// LevelSetPreviewForm.h
+// ----------------------------------------------------------------------------
+
+#ifndef LEVELSETPREVIEWFORM_H
+#define LEVELSETPREVIEWFORM_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+#endif /* LEVELSETPREVIEWFORM_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// MainForm.c
+// ----------------------------------------------------------------------------
+
+#include "MainForm.h"
+
+#if 1
+
+static void DrawFrame(int Delta);
+
+#else
+
+static void CleanTempDir(char *TmpDir);
+static void CountDown(long HalfSeconds, int bDisplayBar);
+static void DrawFrame(int Delta);
+static void DrawPauseLayer(long Layer);
+static void FillFileList(char *Path);
+static void FillLevelList(char *Path, int LevelIndex);
+static void FocusTim_Timer();
+static void Form_KeyDown(int KeyCode, int Shift);
+static void Form_KeyUp(int KeyCode, int Shift);
+static void Form_Paint();
+static int GetFileNameToSave();
+static long GetHwndFromTempFileName(char *TmpFile);
+static char * GetMyTempFileName();
+static void GetSettings();
+static char * GetSpeedDescriptionFPS(currency FrameDelayUS);
+static int GetSpeedIndex(long DelayUS);
+static char * GetValidTempPath();
+static long Get_LastOpenFilter();
+static long Get_LastSaveFilter();
+static int InitSpeeds();
+static boolean InstanceStillRunning(char *TmpFile);
+static void Let_LastOpenFilter(long NewVal);
+static void Let_LastSaveFilter(long NewVal);
+static void LoadKeyIndicators();
+static void LoadMenus();
+static void PanelTim_Timer();
+static void ReStretch(float NewStretch);
+static void RestoreFrame();
+static boolean SaveAs();
+static void SaveSettings();
+static void SetScrollEdges();
+static void UpdateDeltaT();
+static void cmbFile_Click();
+static void cmbFile_KeyDown(int KeyCode, int Shift);
+static void cmbFile_KeyUp(int KeyCode, int Shift);
+static void cmbLevel_Click();
+static void cmbLevel_KeyUp(int KeyCode, int Shift);
+static void cmblevel_KeyDown(int KeyCode, int Shift);
+static void cmdPause_Click();
+static void cmdPause_MouseUp(int Button, int Shift, float X, float Y);
+static void cmdPlayAll_Click();
+static void cmdPlayAll_MouseUp(int Button, int Shift, float X, float Y);
+static void cmdPlayDemo_Click();
+static void cmdPlayDemo_MouseUp(int Button, int Shift, float X, float Y);
+static void cmdPlay_Click();
+static void cmdPlay_MouseUp(int Button, int Shift, float X, float Y);
+static void cmdRecordDemo_Click();
+static void cmdRecordDemo_MouseUp(int Button, int Shift, float X, float Y);
+static void cmdStop_Click();
+static void cmdStop_MouseUp(int Button, int Shift, float X, float Y);
+static void fpsTim_Timer();
+static void menAbout_Click();
+static void menAutoScroll_Click();
+static void menBorder_Click();
+static void menCopy_Click();
+static void menEnOff_Click();
+static void menEnOn_Click();
+static void menExit_Click();
+static void menFaster_Click();
+static void menGravOff_Click();
+static void menGravOn_Click();
+static void menNewStd_Click();
+static void menNew_Click();
+static void menOpen_Click();
+static void menOptions_Click();
+static void menPanel_Click();
+static void menPaste_Click();
+static void menPause_Click();
+static void menPlayAll_Click();
+static void menPlayDemo_Click();
+static void menPlay_Click();
+static void menReRecordDemo_Click();
+static void menRec_Click();
+static void menRemSP_Click();
+static void menRestoreBorder_Click();
+static void menSaveAs_Click();
+static void menSave_Click();
+static void menSelectAll_Click();
+static void menShowLInfo_Click();
+static void menSlower_Click();
+static void menSoundFX_Click();
+static void menStretch_Click(int Index);
+static void menToolTips_Click();
+static void menTrim_Click();
+static void menZonkOff_Click();
+static void menZonkOn_Click();
+static void picKeys_MouseUp(int Button, int Shift, float X, float Y);
+static void picMenu_Click();
+static void picPane_KeyDown(int KeyCode, int Shift);
+static void picPane_KeyUp(int KeyCode, int Shift);
+static void picPane_MouseDown(int Button, int Shift, float X, float Y);
+static void picPane_MouseMove(int Button, int Shift, float X, float Y);
+static void picPane_MouseUp(int Button, int Shift, float X, float Y);
+static void picPane_Paint();
+static void picViewPort_MouseUp(int Button, int Shift, float X, float Y);
+static void picViewPort_Paint();
+static void picViewPort_Resize();
+
+#endif
+
+void DrawField(int X, int Y);
+void DrawFieldAnimated(int X, int Y);
+void DrawFieldNoAnimated(int X, int Y);
+
+// --- VERSION 5.00
+// --- Object = "{F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.2#0"; "COMDLG32.OCX"
+// --- Begin VB.Form MainForm
+// --- AutoRedraw = -1 'True // True
+// --- Caption = "MegaPlex"
+// --- ClientHeight = 5850
+// --- ClientLeft = 2580
+// --- ClientTop = 2205
+// --- ClientWidth = 9285
+// --- Icon = "MainForm.frx":0000
+// --- LinkTopic = "Form1"
+// --- ScaleHeight = 390
+// --- ScaleMode = 3 'Pixel // Pixel
+// --- ScaleWidth = 619
+// --- Begin VB.Timer fpsTim
+// --- Enabled = 0 'False // False
+// --- Interval = 200
+// --- Left = 1380
+// --- Top = 2940
+// --- End
+// --- Begin VB.Timer FocusTim
+// --- Interval = 50
+// --- Left = 1920
+// --- Top = 2940
+// --- End
+// --- Begin MSComDlg.CommonDialog cmDlg
+// --- Left = 240
+// --- Top = 2880
+// --- _ExtentX = 847
+// --- _ExtentY = 847
+// --- _Version = 393216
+// --- CancelError = -1 'True // True
+// --- End
+// --- Begin VB.Timer PanelTim
+// --- Enabled = 0 'False // False
+// --- Interval = 5
+// --- Left = 840
+// --- Top = 2940
+// --- End
+// --- Begin VB.Frame Panel
+// --- Height = 1140
+// --- Left = 180
+// --- TabIndex = 2
+// --- Top = 3540
+// --- Width = 9015
+// --- Begin VB.CommandButton cmdPlay
+// --- DisabledPicture = "MainForm.frx":0442
+// --- DownPicture = "MainForm.frx":058C
+// --- Height = 345
+// --- Left = 5820
+// --- Picture = "MainForm.frx":06D6
+// --- Style = 1 'Graphical // Graphical
+// --- TabIndex = 16
+// --- TabStop = 0 'False // False
+// --- Top = 240
+// --- Width = 495
+// --- End
+// --- Begin VB.CommandButton cmdStop
+// --- DisabledPicture = "MainForm.frx":0820
+// --- DownPicture = "MainForm.frx":096A
+// --- Enabled = 0 'False // False
+// --- Height = 345
+// --- Left = 7020
+// --- Picture = "MainForm.frx":0AB4
+// --- Style = 1 'Graphical // Graphical
+// --- TabIndex = 15
+// --- TabStop = 0 'False // False
+// --- Top = 240
+// --- Width = 495
+// --- End
+// --- Begin VB.CommandButton cmdPlayDemo
+// --- DisabledPicture = "MainForm.frx":0BFE
+// --- DownPicture = "MainForm.frx":0D48
+// --- Enabled = 0 'False // False
+// --- Height = 345
+// --- Left = 7740
+// --- Picture = "MainForm.frx":0E92
+// --- Style = 1 'Graphical // Graphical
+// --- TabIndex = 14
+// --- TabStop = 0 'False // False
+// --- Top = 240
+// --- Width = 495
+// --- End
+// --- Begin VB.CommandButton cmdPause
+// --- DisabledPicture = "MainForm.frx":0FDC
+// --- DownPicture = "MainForm.frx":1126
+// --- Enabled = 0 'False // False
+// --- Height = 345
+// --- Left = 6420
+// --- Picture = "MainForm.frx":1270
+// --- Style = 1 'Graphical // Graphical
+// --- TabIndex = 13
+// --- TabStop = 0 'False // False
+// --- Top = 240
+// --- Width = 495
+// --- End
+// --- Begin VB.CommandButton cmdRecordDemo
+// --- DisabledPicture = "MainForm.frx":13BA
+// --- DownPicture = "MainForm.frx":1504
+// --- Height = 345
+// --- Left = 8340
+// --- Picture = "MainForm.frx":164E
+// --- Style = 1 'Graphical // Graphical
+// --- TabIndex = 12
+// --- TabStop = 0 'False // False
+// --- Top = 240
+// --- Width = 495
+// --- End
+// --- Begin VB.ComboBox cmbFile
+// --- BackColor = &H00000000&
+// --- BeginProperty Font
+// --- Name = "Fixedsys"
+// --- Size = 9
+// --- Charset = 0
+// --- Weight = 400
+// --- Underline = 0 'False // False
+// --- Italic = 0 'False // False
+// --- Strikethrough = 0 'False // False
+// --- EndProperty
+// --- ForeColor = &H00FF8080&
+// --- Height = 345
+// --- Left = 120
+// --- Sorted = -1 'True // True
+// --- Style = 2 'Dropdown List // Dropdown List
+// --- TabIndex = 9
+// --- Top = 240
+// --- Width = 3015
+// --- End
+// --- Begin VB.ComboBox cmbLevel
+// --- BackColor = &H00000000&
+// --- BeginProperty Font
+// --- Name = "Fixedsys"
+// --- Size = 9
+// --- Charset = 0
+// --- Weight = 400
+// --- Underline = 0 'False // False
+// --- Italic = 0 'False // False
+// --- Strikethrough = 0 'False // False
+// --- EndProperty
+// --- ForeColor = &H00FF8080&
+// --- Height = 345
+// --- Left = 840
+// --- Sorted = -1 'True // True
+// --- Style = 2 'Dropdown List // Dropdown List
+// --- TabIndex = 5
+// --- Top = 660
+// --- Width = 4035
+// --- End
+// --- Begin VB.PictureBox picKeys
+// --- BackColor = &H00008080&
+// --- BorderStyle = 0 'None // None
+// --- Height = 330
+// --- Left = 5400
+// --- ScaleHeight = 22
+// --- ScaleMode = 3 'Pixel // Pixel
+// --- ScaleWidth = 22
+// --- TabIndex = 4
+// --- TabStop = 0 'False // False
+// --- Top = 240
+// --- Width = 330
+// --- Begin VB.Shape shpKey
+// --- FillColor = &H00008000&
+// --- FillStyle = 0 'Solid // Solid
+// --- Height = 120
+// --- Index = 1
+// --- Left = 0
+// --- Shape = 5 'Rounded Square // Rounded Square
+// --- Top = 0
+// --- Width = 120
+// --- End
+// --- End
+// --- Begin VB.CommandButton cmdPlayAll
+// --- Caption = "Play All Demos"
+// --- Enabled = 0 'False // False
+// --- Height = 345
+// --- Left = 7380
+// --- TabIndex = 3
+// --- TabStop = 0 'False // False
+// --- Top = 960
+// --- Visible = 0 'False // False
+// --- Width = 1395
+// --- End
+// --- Begin VB.Shape shpProgress
+// --- BackColor = &H00800000&
+// --- BackStyle = 1 'Opaque // Opaque
+// --- Height = 75
+// --- Left = 120
+// --- Top = 1020
+// --- Visible = 0 'False // False
+// --- Width = 7515
+// --- End
+// --- Begin VB.Label lblStatus
+// --- Alignment = 2 'Center // Center
+// --- BorderStyle = 1 'Fixed Single // Fixed Single
+// --- Caption = "MegaPlex"
+// --- BeginProperty Font
+// --- Name = "Fixedsys"
+// --- Size = 9
+// --- Charset = 0
+// --- Weight = 400
+// --- Underline = 0 'False // False
+// --- Italic = 0 'False // False
+// --- Strikethrough = 0 'False // False
+// --- EndProperty
+// --- Height = 345
+// --- Left = 3240
+// --- TabIndex = 11
+// --- Top = 240
+// --- Width = 2055
+// --- End
+// --- Begin VB.Image Image2
+// --- Height = 240
+// --- Left = 6780
+// --- Picture = "MainForm.frx":1BD8
+// --- Top = 720
+// --- Width = 240
+// --- End
+// --- Begin VB.Image Image1
+// --- Height = 240
+// --- Left = 5880
+// --- Picture = "MainForm.frx":1D22
+// --- Top = 720
+// --- Width = 240
+// --- End
+// --- Begin VB.Label lblFps
+// --- Alignment = 2 'Center // Center
+// --- BackColor = &H00000000&
+// --- BorderStyle = 1 'Fixed Single // Fixed Single
+// --- BeginProperty Font
+// --- Name = "Fixedsys"
+// --- Size = 9
+// --- Charset = 0
+// --- Weight = 400
+// --- Underline = 0 'False // False
+// --- Italic = 0 'False // False
+// --- Strikethrough = 0 'False // False
+// --- EndProperty
+// --- ForeColor = &H0000C0C0&
+// --- Height = 345
+// --- Left = 120
+// --- TabIndex = 10
+// --- Top = 660
+// --- Width = 615
+// --- End
+// --- Begin VB.Label lblInfoCount
+// --- Alignment = 2 'Center // Center
+// --- BackColor = &H00000000&
+// --- BorderStyle = 1 'Fixed Single // Fixed Single
+// --- BeginProperty Font
+// --- Name = "Fixedsys"
+// --- Size = 9
+// --- Charset = 0
+// --- Weight = 400
+// --- Underline = 0 'False // False
+// --- Italic = 0 'False // False
+// --- Strikethrough = 0 'False // False
+// --- EndProperty
+// --- ForeColor = &H00FF8080&
+// --- Height = 345
+// --- Left = 5040
+// --- TabIndex = 8
+// --- Top = 660
+// --- Width = 795
+// --- End
+// --- Begin VB.Label lblRedDiskCount
+// --- Alignment = 2 'Center // Center
+// --- BackColor = &H00000000&
+// --- BorderStyle = 1 'Fixed Single // Fixed Single
+// --- BeginProperty Font
+// --- Name = "Fixedsys"
+// --- Size = 9
+// --- Charset = 0
+// --- Weight = 400
+// --- Underline = 0 'False // False
+// --- Italic = 0 'False // False
+// --- Strikethrough = 0 'False // False
+// --- EndProperty
+// --- ForeColor = &H000000FF&
+// --- Height = 345
+// --- Left = 6240
+// --- TabIndex = 7
+// --- Top = 660
+// --- Width = 495
+// --- End
+// --- Begin VB.Label lblFrameCount
+// --- Alignment = 2 'Center // Center
+// --- BorderStyle = 1 'Fixed Single // Fixed Single
+// --- Caption = "0"
+// --- BeginProperty Font
+// --- Name = "Fixedsys"
+// --- Size = 9
+// --- Charset = 0
+// --- Weight = 400
+// --- Underline = 0 'False // False
+// --- Italic = 0 'False // False
+// --- Strikethrough = 0 'False // False
+// --- EndProperty
+// --- Height = 345
+// --- Left = 7200
+// --- TabIndex = 6
+// --- Top = 660
+// --- Width = 1635
+// --- End
+// --- End
+// --- Begin VB.PictureBox picViewPort
+// --- BorderStyle = 0 'None // None
+// --- Height = 2535
+// --- Left = 180
+// --- ScaleHeight = 169
+// --- ScaleMode = 3 'Pixel // Pixel
+// --- ScaleWidth = 265
+// --- TabIndex = 0
+// --- TabStop = 0 'False // False
+// --- Top = 180
+// --- Width = 3975
+// --- Begin VB.PictureBox picPane
+// --- AutoSize = -1 'True // True
+// --- BackColor = &H00000000&
+// --- BorderStyle = 0 'None // None
+// --- DrawWidth = 3
+// --- Height = 1635
+// --- Left = 240
+// --- ScaleHeight = 109
+// --- ScaleMode = 3 'Pixel // Pixel
+// --- ScaleWidth = 129
+// --- TabIndex = 1
+// --- Top = 180
+// --- Width = 1935
+// --- End
+// --- Begin VB.PictureBox picFrame
+// --- Height = 915
+// --- Left = 1320
+// --- ScaleHeight = 57
+// --- ScaleMode = 3 'Pixel // Pixel
+// --- ScaleWidth = 81
+// --- TabIndex = 17
+// --- TabStop = 0 'False // False
+// --- Top = 1200
+// --- Width = 1275
+// --- End
+// --- End
+// --- Begin VB.Menu menFile
+// --- Caption = "&File"
+// --- Begin VB.Menu menNewStd
+// --- Caption = "New S&tandard Level"
+// --- End
+// --- Begin VB.Menu menNew
+// --- Caption = "&New Level"
+// --- End
+// --- Begin VB.Menu menDash5
+// --- Caption = "-"
+// --- End
+// --- Begin VB.Menu menOpen
+// --- Caption = "&Open"
+// --- End
+// --- Begin VB.Menu menSave
+// --- Caption = "&Save"
+// --- Shortcut = ^S
+// --- End
+// --- Begin VB.Menu menSaveAs
+// --- Caption = "Save &As ..."
+// --- End
+// --- Begin VB.Menu menDash4
+// --- Caption = "-"
+// --- End
+// --- Begin VB.Menu menExit
+// --- Caption = "E&xit"
+// --- Shortcut = ^Q
+// --- End
+// --- End
+// --- Begin VB.Menu menEditMain
+// --- Caption = "&Edit"
+// --- Begin VB.Menu menEdit
+// --- Caption = "&Edit Level"
+// --- End
+// --- Begin VB.Menu menDash3
+// --- Caption = "-"
+// --- End
+// --- Begin VB.Menu menCopy
+// --- Caption = "&Copy"
+// --- Shortcut = ^C
+// --- End
+// --- Begin VB.Menu menPaste
+// --- Caption = "&Paste"
+// --- Shortcut = ^V
+// --- End
+// --- Begin VB.Menu menTrim
+// --- Caption = "&Trim"
+// --- Shortcut = ^T
+// --- End
+// --- Begin VB.Menu menDash8
+// --- Caption = "-"
+// --- Index = 1
+// --- End
+// --- Begin VB.Menu menSelectAll
+// --- Caption = "Select &All"
+// --- Shortcut = ^A
+// --- End
+// --- Begin VB.Menu menDash6
+// --- Caption = "-"
+// --- End
+// --- Begin VB.Menu menRestoreBorder
+// --- Caption = "Restore &border"
+// --- Shortcut = ^B
+// --- End
+// --- Begin VB.Menu menSp
+// --- Caption = "Special Port"
+// --- Begin VB.Menu menGravOn
+// --- Caption = "&Gravity On"
+// --- End
+// --- Begin VB.Menu menZonkOn
+// --- Caption = "Freeze &Zonks On"
+// --- End
+// --- Begin VB.Menu menEnOn
+// --- Caption = "Freeze &Enemies On"
+// --- End
+// --- Begin VB.Menu menDash7
+// --- Caption = "-"
+// --- End
+// --- Begin VB.Menu menGravOff
+// --- Caption = "Gravity &Off"
+// --- End
+// --- Begin VB.Menu menZonkOff
+// --- Caption = "Freeze Zon&ks Off"
+// --- End
+// --- Begin VB.Menu menEnOff
+// --- Caption = "Freeze E&nemies Off"
+// --- End
+// --- Begin VB.Menu menDash10
+// --- Caption = "-"
+// --- End
+// --- Begin VB.Menu menRemSP
+// --- Caption = "&Remove (Make Normal Port)"
+// --- End
+// --- End
+// --- End
+// --- Begin VB.Menu menView
+// --- Caption = "&View"
+// --- Begin VB.Menu menZoom
+// --- Caption = "&Zoom"
+// --- Begin VB.Menu menStretch
+// --- Caption = "0.25 : 1"
+// --- Index = 1
+// --- End
+// --- End
+// --- Begin VB.Menu menBorder
+// --- Caption = "Show &Border"
+// --- Checked = -1 'True // True
+// --- End
+// --- Begin VB.Menu menPanel
+// --- Caption = "Show &Panel"
+// --- Checked = -1 'True // True
+// --- End
+// --- Begin VB.Menu menAutoScroll
+// --- Caption = "&Autoscroll"
+// --- Checked = -1 'True // True
+// --- End
+// --- Begin VB.Menu menDash9
+// --- Caption = "-"
+// --- End
+// --- Begin VB.Menu menShowLInfo
+// --- Caption = "Show Level &Info"
+// --- End
+// --- End
+// --- Begin VB.Menu menSound
+// --- Caption = "&Sound"
+// --- Begin VB.Menu menSoundFX
+// --- Caption = "&FX"
+// --- End
+// --- Begin VB.Menu menMusic
+// --- Caption = "&Music"
+// --- Enabled = 0 'False // False
+// --- End
+// --- End
+// --- Begin VB.Menu menSpeed
+// --- Caption = "Speed"
+// --- Begin VB.Menu menSpeedPlay
+// --- Caption = "Game play"
+// --- Index = 11
+// --- Begin VB.Menu menPlaySpeed
+// --- Caption = "1"
+// --- Index = 1
+// --- End
+// --- End
+// --- Begin VB.Menu menSpeedDemo
+// --- Caption = "Demo playback"
+// --- Begin VB.Menu menDemoSpeed
+// --- Caption = "1"
+// --- Index = 1
+// --- End
+// --- End
+// --- Begin VB.Menu menSpeedDash
+// --- Caption = "-"
+// --- End
+// --- Begin VB.Menu menFaster
+// --- Caption = "Faster (Pg Up)"
+// --- End
+// --- Begin VB.Menu menSlower
+// --- Caption = "Slower (Pg Down)"
+// --- End
+// --- End
+// --- Begin VB.Menu menRun
+// --- Caption = "&Play"
+// --- Begin VB.Menu menPlay
+// --- Caption = "P&lay Game (Space)"
+// --- End
+// --- Begin VB.Menu menPause
+// --- Caption = "&Pause (P)"
+// --- Enabled = 0 'False // False
+// --- End
+// --- Begin VB.Menu menStop
+// --- Caption = "&Stop (Q)"
+// --- Enabled = 0 'False // False
+// --- End
+// --- Begin VB.Menu menDash0
+// --- Caption = "-"
+// --- End
+// --- Begin VB.Menu menRec
+// --- Caption = "&Record Demo (Ctrl+R)"
+// --- End
+// --- Begin VB.Menu menPlayDemo
+// --- Caption = "Play &Demo (Ctrl+Space)"
+// --- End
+// --- Begin VB.Menu menPlayAll
+// --- Caption = "Play &All Demos"
+// --- End
+// --- End
+// --- Begin VB.Menu menOptionsMain
+// --- Caption = "&Options"
+// --- Begin VB.Menu menOptions
+// --- Caption = "&Options ..."
+// --- End
+// --- End
+// --- Begin VB.Menu menHelp
+// --- Caption = "Help"
+// --- Begin VB.Menu menToolTips
+// --- Caption = "Show &ToolTips"
+// --- End
+// --- Begin VB.Menu menDash1
+// --- Caption = "-"
+// --- End
+// --- Begin VB.Menu menAbout
+// --- Caption = "&About MegaPlex"
+// --- End
+// --- End
+// --- End
+
+static char *VB_Name = "MainForm";
+static boolean VB_GlobalNameSpace = False;
+static boolean VB_Creatable = False;
+static boolean VB_PredeclaredId = True;
+static boolean VB_Exposed = False;
+// --- Option Explicit
+// --- Option Compare Text
+
+long SetParent(long hWndChild, long hWndNewParent);
+long SetWindowLong(long hWnd, long nIndex, long dwNewLong);
+long GetWindowLong(long hWnd, long nIndex);
+long GetTempPath(long nBufferLength, char *lpBuffer);
+long GetWindowText(long hWnd, char *lpString, long cch);
+
+#define GWL_STYLE ((-16))
+#define WS_CHILD (0x40000000)
+#define WS_POPUP (0x80000000)
+
+// [UNCOMMENTED] Dim StretchWidth2&
+
+char *MpxBmp;
+int OldPointer;
+long OSX, OSY, MDX, MDY;
+int MouseButton;
+
+int PanelSeq;
+
+boolean Loaded, DemosAvailable;
+
+#define nSpeedCount (17)
+int SpeedsByDelayUS[nSpeedCount + 1];
+#define DefaultSpeedIndex (12)
+
+currency LastTick, LastFrame;
+TickCountObject T;
+
+const char *AppTitle = "MegaPlex";
+
+static char *GetSpeedDescriptionFPS(currency FrameDelayUS)
+{
+ static char *GetSpeedDescriptionFPS;
+
+ long FPS;
+
+ if (FrameDelayUS == 0)
+ {
+ GetSpeedDescriptionFPS = "Fastest possible";
+ return GetSpeedDescriptionFPS;
+ }
+
+ if (FrameDelayUS < 0)
+ {
+ GetSpeedDescriptionFPS = "! display (even faster)";
+ return GetSpeedDescriptionFPS;
+ }
+
+ FPS = 1000000 / FrameDelayUS;
+ GetSpeedDescriptionFPS = CAT(INT_TO_STR(FPS), " fps");
+ if (35 == FPS)
+ GetSpeedDescriptionFPS = CAT(GetSpeedDescriptionFPS, "(Default)");
+
+ return GetSpeedDescriptionFPS;
+}
+
+static int InitSpeeds()
+{
+ static int InitSpeeds;
+
+ SpeedsByDelayUS[1] = -1; // no display
+ SpeedsByDelayUS[2] = 0; // fastest possible
+ SpeedsByDelayUS[3] = 1000000 / 700; // 700 fps
+ SpeedsByDelayUS[4] = 1000000 / 500; // 500 fps
+ SpeedsByDelayUS[5] = 1000000 / 350; // 350 fps
+ SpeedsByDelayUS[6] = 1000000 / 250; // 250 fps
+ SpeedsByDelayUS[7] = 1000000 / 200; // etc.
+ SpeedsByDelayUS[8] = 1000000 / 150;
+ SpeedsByDelayUS[9] = 1000000 / 100;
+ SpeedsByDelayUS[10] = 1000000 / 70;
+ SpeedsByDelayUS[11] = 1000000 / 50;
+ SpeedsByDelayUS[12] = 1000000 / 35; // default
+ SpeedsByDelayUS[13] = 1000000 / 25;
+ SpeedsByDelayUS[14] = 1000000 / 20;
+ SpeedsByDelayUS[15] = 1000000 / 10;
+ SpeedsByDelayUS[16] = 1000000 / 5;
+ SpeedsByDelayUS[17] = 1000000 / 1;
+
+ return InitSpeeds;
+}
+
+static int GetSpeedIndex(long DelayUS)
+{
+ static int GetSpeedIndex;
+
+ int i;
+ long Diff, MinDiff;
+ int MinIdx;
+
+ MinIdx = DefaultSpeedIndex;
+ MinDiff = 1000000;
+ for (i = 1; i <= nSpeedCount; i++)
+ {
+ Diff = Abs(DelayUS - SpeedsByDelayUS[i]);
+ if (Diff < MinDiff)
+ {
+ MinDiff = Diff;
+ MinIdx = i;
+ }
+ }
+
+ GetSpeedIndex = MinIdx;
+
+ return GetSpeedIndex;
+}
+
+#if 0
+
+static long Get_LastOpenFilter()
+{
+ static long LastOpenFilter;
+
+ SettingsObject s;
+
+ LastOpenFilter = s.Read("LastOpenFilter", 1);
+
+ return LastOpenFilter;
+}
+
+static void Let_LastOpenFilter(long NewVal)
+{
+ SettingsObject s;
+
+ SettingsObject_Save("LastOpenFilter", NewVal);
+}
+
+static long Get_LastSaveFilter()
+{
+ static long LastSaveFilter;
+
+ SettingsObject s;
+
+ LastSaveFilter = s.Read("LastSaveFilter", 1);
+
+ return LastSaveFilter;
+}
+
+static void Let_LastSaveFilter(long NewVal)
+{
+ SettingsObject s;
+
+ SettingsObject_Save("LastSaveFilter", NewVal);
+}
+
+#endif
+
+static void CountDown(long HalfSeconds, int bDisplayBar)
+{
+ long i;
+ int k;
+ long dT, Delta;
+ long LeftPos, TopPos, RightPos, MaxWidth; // , MaxHeight&
+
+ dT = HalfSeconds * 500;
+ Delta = dT / 200;
+ LeftPos = cmbFile.left;
+ TopPos = cmbFile.top - shpProgress.Height - cmbFile.top / 8;
+ RightPos = lblFrameCount.left + lblFrameCount.Width;
+ MaxWidth = RightPos - LeftPos;
+ // MaxHeight = lblFrameCount.Top - TopPos + lblFrameCount.Height + 4
+ if (bDisplayBar)
+ {
+ shpProgress.Move(LeftPos, TopPos, 0); // , MaxHeight
+ shpProgress.Visible = True;
+ }
+
+ for (i = 1; i <= 200; i++)
+ {
+ // lblFrameCount = i
+ if (bDisplayBar)
+ {
+ if (i < 101)
+ {
+ shpProgress.Width = MaxWidth * i / 100;
+ }
+ else
+ {
+ k = MaxWidth * (i - 100) / 100;
+ shpProgress.Move(k, TopPos, RightPos - k);
+ }
+ }
+
+ T.DelayMS(Delta, False);
+ }
+
+ shpProgress.Visible = False;
+ // lblFrameCount = 0
+}
+
+static char *GetValidTempPath()
+{
+ static char *GetValidTempPath;
+
+ char *TP;
+ long nSize, L;
+
+ GetValidTempPath = "";
+ nSize = 255;
+ TP = String(nSize, Chr(32));
+ L = GetTempPath(nSize, TP);
+ if (nSize < L)
+ {
+ // buffer was too small, retry with a properly sized buffer:
+ nSize = L;
+ TP = String(nSize, Chr(32));
+ L = GetTempPath(nSize, TP);
+ }
+
+ TP = SlashLess(left(TP, L));
+ if ((0 == L) || (! IsDir(TP)))
+ {
+ // no valid temp path can be retrieved from the system --> create our own
+ TP = CAT(WithSlash(App.Path), "Temp");
+ if (! IsDir(TP))
+ {
+
+ // --- On Error Resume Next
+ MkDir(TP);
+ if (! IS_NOTHING(&Err, sizeof(Err)))
+ {
+ MESSAGE_BOX("an error occured"); // MsgBox "cannot create directory for temporary files " & TP, vbCritical, "MegaPlex - Error";
+ return GetValidTempPath;
+ }
+
+ // --- On Error GoTo 0
+
+ }
+ }
+
+ if (IsDir(TP))
+ GetValidTempPath = TP;
+
+ return GetValidTempPath;
+}
+
+#if 0
+
+static char *GetMyTempFileName()
+{
+ static char *GetMyTempFileName;
+
+ char *T;
+
+ (char *)T = Hex(hWnd);
+ while (Len(T) < 8)
+ {
+ T = CAT("0", T);
+ }
+
+ GetMyTempFileName = CAT("tmp0x", CAT((char *)T, ".mpx"));
+
+ return GetMyTempFileName;
+}
+
+static long GetHwndFromTempFileName(char *TmpFile)
+{
+ static long GetHwndFromTempFileName;
+
+ char *FN;
+ long LP;
+ int L;
+ char *NumString;
+
+ GetHwndFromTempFileName = 0;
+ FN = StripFileName(TmpFile);
+ LP = Len("tmp0x");
+ L = Len(TmpFile);
+ if (LP < L)
+ return GetHwndFromTempFileName;
+
+ L = L - LP;
+ NumString = right(FN, L - LP);
+ if (8 < L)
+ NumString = left(NumString, 8);
+
+ NumString = CAT("&H", NumString);
+ GetHwndFromTempFileName = Val(NumString);
+
+ return GetHwndFromTempFileName;
+}
+
+static void CleanTempDir(char *TmpDir)
+{
+ char *FN, *MFN;
+
+ MFN = GetMyTempFileName();
+ MayKill(CAT(WithSlash(TmpDir), MFN));
+ FN = Dir(CAT(WithSlash(TmpDir), "tmp0x*.mpx"));
+ while (FN != "")
+ {
+ if (STRING_IS_LIKE(FN, "tmp0x*.mpx"))
+ {
+ if (! InstanceStillRunning(FN))
+ MayKill(CAT(WithSlash(TmpDir), FN));
+ }
+
+ FN = Dir_Without_Args();
+ }
+}
+
+static boolean InstanceStillRunning(char *TmpFile)
+{
+ static boolean InstanceStillRunning;
+
+ long OtherHwnd, nSize, L;
+ char *Cap;
+
+ InstanceStillRunning = False;
+ OtherHwnd = GetHwndFromTempFileName(TmpFile);
+ nSize = 255;
+ Cap = String(nSize, Chr(32));
+ L = GetWindowText(OtherHwnd, Cap, nSize);
+ if ((L == 0) || (nSize < L))
+ return InstanceStillRunning;
+
+ if (STRING_IS_LIKE(Cap, CAT(AppTitle, "*")))
+ InstanceStillRunning = True;
+
+ return InstanceStillRunning;
+}
+
+#endif
+
+void DisplayLevel()
+{
+ int X, Y;
+
+ if (! Loaded)
+ return;
+
+ if (! LevelLoaded)
+ return;
+
+#if 0
+ SetDisplayRegion();
+#endif
+
+ DrawFrame(0);
+
+#if 0
+ if (! menBorder.Checked)
+ DrawFrame(1);
+#endif
+
+ if (bPlaying)
+ {
+ for (Y = DisplayMinY; Y <= DisplayMaxY; Y++)
+ {
+ for (X = DisplayMinX; X <= DisplayMaxX; X++)
+ {
+ DrawFieldNoAnimated(X, Y);
+ }
+ }
+
+ for (Y = DisplayMinY; Y <= DisplayMaxY; Y++)
+ {
+ for (X = DisplayMinX; X <= DisplayMaxX; X++)
+ {
+ DrawFieldAnimated(X, Y);
+ }
+ }
+
+ }
+ else
+ {
+ for (Y = DisplayMinY; Y <= DisplayMaxY; Y++)
+ {
+ for (X = DisplayMinX; X <= DisplayMaxX; X++)
+ {
+ DrawField(X, Y);
+ }
+ }
+ }
+}
+
+#if 0
+
+static void cmbFile_Click()
+{
+ CurPath = CAT(StripDir(OrigPath), CAT("/", cmbFile.List(cmbFile.ListIndex)));
+ OrigPath = CurPath;
+ FillLevelList(CurPath, LevelNumber);
+ if (STRING_IS_LIKE(OrigPath, "*.mpx") || STRING_IS_LIKE(OrigPath, "*.sp"))
+ {
+ menSave.Enabled = True;
+ }
+ else
+ {
+ menSave.Enabled = False;
+ }
+}
+
+static void cmbFile_KeyDown(int KeyCode, int Shift)
+{
+ picPane_KeyDown(KeyCode, Shift);
+}
+
+static void cmbFile_KeyUp(int KeyCode, int Shift)
+{
+ picPane_KeyUp(KeyCode, Shift);
+}
+
+static int GetFileNameToSave()
+{
+ static int GetFileNameToSave;
+
+ char *T;
+
+ (char *)T = StripFileName(OrigPath);
+ if (STRING_IS_LIKE(T, "*.dat") || STRING_IS_LIKE(T, "*.d##"))
+ {
+ T = "Level" & Format(LevelNumber, "#000");
+ }
+
+ GetFileNameToSave = T;
+
+ return GetFileNameToSave;
+}
+
+static void cmbLevel_Click()
+{
+ long InfoCount;
+ boolean Oldflag;
+ int Msg;
+ long LastIndex;
+ boolean bBlock;
+
+ if (bBlock)
+ return;
+
+ // //////////////////////////////////////////////////////////////////
+ if (ModifiedFlag)
+ {
+ VbMsgBoxResult Res;
+
+ Msg = "Save changes to " & GetFileNameToSave() & " ?";
+ Res = MsgBox(Msg, vbYesNoCancel, AppTitle & " - close level");
+ if (Res == vbCancel) // fallback
+ {
+ bBlock = True;
+
+ // --- On Error Resume Next
+ cmbLevel.ListIndex = LastIndex;
+ // --- On Error GoTo 0
+
+ bBlock = False;
+ Debug.Assert cmbLevel.ListIndex = LastIndex;
+ return;
+ }
+
+ if (Res == vbYes)
+ {
+ // Dim oldCurPath$
+ // oldCurPath = CurPath
+ if (FileExists(OrigPath) && menSave.Enabled)
+ {
+ menSave_Click();
+ }
+ else
+ {
+ if (! SaveAs()) // fallback
+ {
+ bBlock = True;
+
+ // --- On Error Resume Next
+ cmbLevel.ListIndex = LastIndex;
+ // --- On Error GoTo 0
+
+ bBlock = False;
+ Debug.Assert cmbLevel.ListIndex = LastIndex;
+ return;
+ }
+ }
+
+ // CurPath = oldCurPath
+ }
+
+ Let_ModifiedFlag(False);
+ CurPath = OrigPath;
+ }
+
+ // //////////////////////////////////////////////////////////////////
+ {
+ LevelNumber = cmbLevel.ListIndex + 1;
+ DemoFlag = False;
+ if (Loaded)
+ {
+ Oldflag = NoDisplayFlag;
+ NoDisplayFlag = False;
+ subFetchAndInitLevel();
+ if ((0 < SignatureDelay) && ! (WindowState == vbMinimized))
+ {
+ Msg = LInfo.LevelTitle & vbNewLine & "(" & FieldWidth & " x " & FieldHeight & ")";
+ if (DemoAvailable && bSignatureAvailable)
+ Msg = Msg & vbNewLine & vbNewLine & gSignature;
+
+ SignatureForm.Signature = Msg;
+ SignatureForm.DelayMS = SignatureDelay;
+ int X, Y;
+
+ X = left + (Width - SignatureForm.Width) / 2;
+ Y = top + (Height - SignatureForm.Height) / 2;
+ SignatureForm.Move X, Y;
+ SignatureForm.Show vbModeless, Me;
+ Me.SetFocus;
+ }
+
+ lblStatus = "MegaPlex";
+ lblFrameCount = GetTotalFramesOfDemo();
+ if (EditFlag)
+ EdAll();
+
+ ReStretch(Stretch);
+ // picPane_Paint
+ Stage.Blt();
+ NoDisplayFlag = Oldflag;
+ LastIndex = cmbLevel.ListIndex;
+ }
+
+ }
+ menPlayDemo.Enabled = DemoAvailable;
+ cmdPlayDemo.Enabled = DemoAvailable;
+}
+
+static void cmblevel_KeyDown(int KeyCode, int Shift)
+{
+ if (GameLoopRunning != 0)
+ return;
+
+ switch (KeyCode)
+ {
+ case vbKeySpace:
+ if (menPlay.Enabled == True)
+ menPlay_Click();
+
+ break;
+
+ default:
+ picPane_KeyDown(KeyCode, Shift);
+ break;
+ }
+}
+
+static void cmbLevel_KeyUp(int KeyCode, int Shift)
+{
+ picPane_KeyUp(KeyCode, Shift);
+}
+
+static void cmdPause_Click()
+{
+ menPause_Click();
+}
+
+static void cmdPause_MouseUp(int Button, int Shift, float X, float Y)
+{
+ FocusTim.Enabled = True;
+}
+
+static void cmdPlay_Click()
+{
+ if (menPlay.Enabled)
+ menPlay_Click();
+}
+
+static void cmdPlay_MouseUp(int Button, int Shift, float X, float Y)
+{
+ FocusTim.Enabled = True;
+}
+
+static void cmdPlayAll_Click()
+{
+ menPlayAll_Click();
+}
+
+static void cmdPlayAll_MouseUp(int Button, int Shift, float X, float Y)
+{
+ FocusTim.Enabled = True;
+}
+
+static void cmdPlayDemo_Click()
+{
+ menPlayDemo_Click();
+}
+
+static void cmdPlayDemo_MouseUp(int Button, int Shift, float X, float Y)
+{
+ FocusTim.Enabled = True;
+}
+
+static void cmdRecordDemo_Click()
+{
+ if (menRec.Enabled)
+ menRec_Click();
+}
+
+static void cmdRecordDemo_MouseUp(int Button, int Shift, float X, float Y)
+{
+ FocusTim.Enabled = True;
+}
+
+static void cmdStop_Click()
+{
+ if (menStop.Enabled)
+ menStop_Click();
+}
+
+static void cmdStop_MouseUp(int Button, int Shift, float X, float Y)
+{
+ FocusTim.Enabled = True;
+}
+
+static void FocusTim_Timer()
+{
+ FocusTim.Enabled = False;
+
+ // --- On Error Resume Next
+ picPane.SetFocus;
+}
+
+static void Form_KeyDown(int KeyCode, int Shift)
+{
+ picPane_KeyDown(KeyCode, Shift);
+}
+
+static void Form_KeyUp(int KeyCode, int Shift)
+{
+ picPane_KeyUp(KeyCode, Shift);
+}
+
+#endif
+
+static void Form_Load()
+{
+#if 0
+
+ long i;
+ SettingsObject s;
+
+#endif
+
+ Loaded = False;
+ DemoFlag = 0;
+ PanelSeq = 0;
+ EditFlag = False;
+ EditMode = edMove;
+ // FMark = New MarkerObject; // (handle this later, if needed)
+ InitGlobals();
+
+#if 0
+
+ LoadMenus();
+
+ TmpPath = GetValidTempPath();
+ if (TmpPath == "")
+ exit(-1);
+
+ CleanTempDir(TmpPath);
+ TmpPath = CAT(WithSlash(TmpPath), GetMyTempFileName());
+ GetSettings();
+ ShowPanel = 1;
+
+ InitDirectX(hWnd, picPane.hWnd);
+
+ // AllowRedDiskCheat = 1
+ MpxBmp = CAT(App.Path, "/mpx.bmp");
+ // // Set NormalSprites = New DDSpriteBuffer // (handle this later, if needed)
+ // NormalSprites.CreateFromFile MPXBMP, 16, 16
+
+ Field = REDIM_2D(sizeof(int), 0, 2 + 1 - 1, 0, 2 + 1 - 1);
+
+ picViewPort.ScaleMode = vbPixels;
+
+ PauseMode = 0;
+ // BaseWidth = 16
+ menBorder_Click();
+ Loaded = True;
+ ReStretch(Stretch);
+ LoadKeyIndicators();
+
+ Show;
+
+ FillFileList(CurPath);
+ if (s.Read("ShowSplash", True))
+ {
+ // frmSplash.EnableTimer
+ frmSplash.Show vbModal, Me;
+ }
+
+#endif
+}
+
+#if 0
+
+static void FillLevelList(char *Path, int LevelIndex)
+{
+ long FNum, LevLen, i, iMax;
+ char *TFile;
+
+ cmbLevel.Clear;
+ if (! FileExists(Path))
+ return;
+
+ if ((STRING_IS_LIKE(Path, "*.D??")) || (STRING_IS_LIKE(Path, "*.sp")))
+ {
+ FNum = FreeFile();
+ LevLen = 1536;
+ FNum = fopen(Path, "rb");
+ {
+ i = 0;
+ FILE_GET(FNum, (long)1441 + i * LevLen, &LInfo, sizeof(LInfo));
+ cmbLevel.AddItem Format(i + 1, "#000") & " " & LInfo.LevelTitle, i;
+ if (STRING_IS_LIKE(Path, "*.D??"))
+ {
+ while (!(EOF(FNum)))
+ {
+ i = i + 1;
+ FILE_GET(FNum, (long)1441 + i * LevLen, &LInfo, sizeof(LInfo));
+ if (EOF(FNum))
+ break;
+
+ cmbLevel.AddItem Format(i + 1, "#000") & " " & LInfo.LevelTitle, i;
+ }
+ }
+
+ if (LevelIndex <= i && 0 < LevelIndex)
+ i = LevelIndex - 1;
+ else
+ i = 0;
+
+ cmbLevel.ListIndex = i;
+ }
+ fclose(FNum);
+ }
+ else if (STRING_IS_LIKE(Path, "*.mpx"))
+ {
+ FNum = FreeFile();
+ LevLen = 1536;
+ FNum = fopen(Path, "rb");
+ {
+ i = 0;
+ if (MpxOpen(Path))
+ {
+ for (i = 1; i <= LevelCount; i++)
+ {
+ if (! MpxLoadLInfo(CInt(i)))
+ break;
+
+ cmbLevel.AddItem Format(i, "#000") & " " & LInfo.LevelTitle, i - 1;
+ }
+
+ MpxClose();
+ }
+
+ if (LevelIndex < i && 0 < LevelIndex)
+ i = LevelIndex - 1;
+ else
+ i = 0;
+
+ if (i < cmbLevel.ListCount)
+ cmbLevel.ListIndex = i;
+
+ }
+ fclose(FNum);
+ }
+}
+
+static void FillFileList(char *Path)
+{
+ long FNum, LevLen, i;
+ int nDemoCount;
+ char *TFile, *TPath, *OFile;
+
+ cmbFile.Clear;
+ i = 0;
+ nDemoCount = 0;
+ TPath = WithSlash(StripDir(Path));
+ OFile = StripFileName(Path);
+ TFile = Dir(TPath & "*.D??");
+ while (TFile != "")
+ {
+ if (FileLen(TPath & TFile) == 170496)
+ {
+ cmbFile.AddItem TFile;
+ }
+
+ TFile = Dir;
+ }
+
+ TFile = Dir(TPath & "*.SP");
+ while (TFile != "")
+ {
+ nDemoCount = nDemoCount + 1;
+ cmbFile.AddItem TFile;
+ TFile = Dir;
+ }
+
+ TFile = Dir(TPath & "*.mpx");
+ while (TFile != "")
+ {
+ nDemoCount = nDemoCount + 1;
+ cmbFile.AddItem TFile;
+ TFile = Dir;
+ }
+
+ i = cmbFile.ListCount - 1;
+ if (0 < cmbFile.ListCount)
+ {
+ do
+ {
+ if ((cmbFile.List(i) Like OFile) || i == 0)
+ break;
+
+ i = i - 1;
+ }
+ while (!(i < 1));
+
+ cmbFile.ListIndex = i;
+ }
+
+ DemosAvailable = (1 < nDemoCount);
+ menPlayAll.Enabled = DemosAvailable;
+ cmdPlayAll.Enabled = DemosAvailable;
+}
+
+static void LoadMenus()
+{
+ long i;
+
+ // speeds
+ menFaster.Enabled = False;
+ menSlower.Enabled = False;
+ InitSpeeds();
+ for (i = 1; i <= nSpeedCount; i++)
+ {
+ if (1 < i)
+ {
+ Load menPlaySpeed(i);
+ Load menDemoSpeed(i);
+ }
+
+ menPlaySpeed(i).Caption = GetSpeedDescriptionFPS(SpeedsByDelayUS[i]);
+ menDemoSpeed(i).Caption = GetSpeedDescriptionFPS(SpeedsByDelayUS[i]);
+ }
+
+ // zoom
+ menStretch(1).Caption = Format(0.25, "#0.00") & ";
+ 1";
+ if (Stretch == 0.25)
+ menStretch(1).Checked = True;
+
+ for (i = 2; i <= 20; i++)
+ {
+ Load menStretch(i);
+ menStretch(i).Caption = Format(0.25 * i, "#0.00") & ";
+ 1";
+ menStretch(i).Checked = ((i * 0.25) == Stretch);
+ }
+
+ menSp.Enabled = False;
+}
+
+//
+// Function DisplayShift&()
+// Dim X&, Y&, A&, B&, iX&, iiX&, LD&
+// Dim Sprite&
+// DisplayShift = 0
+// For A = 0 To picPane.ScaleWidth
+// For Y = DisplayMinY To DisplayMaxY
+// For X = DisplayMinX To DisplayMaxX
+// iX = StretchWidth * X + A
+// Sprite = Field(X, Y).SpritePos
+// If picPane.ScaleWidth < (iX + 1) Then
+// iX = iX - picPane.ScaleWidth
+// Else
+// If picPane.ScaleWidth < (iX + 1 + BaseWidth) Then
+// iiX = iX - picPane.ScaleWidth
+// Sprites.BitBltSprite picPane.hdc, iiX, StretchWidth * Y, Sprite
+// End If
+// End If
+// Sprites.BitBltSprite picPane.hdc, iX, StretchWidth * Y, Sprite
+// Next X
+// Next Y
+// DisplayShift = DisplayShift + 1
+// 'DoEvents
+// Next A
+// End Function
+
+static void Form_Paint()
+{
+ // Debug.Print "Form_Paint()"
+}
+
+static void Form_Resize()
+{
+ long Space, NW, NH;
+ int Tmp;
+
+ if (WindowState == vbMinimized || ! Loaded)
+ return;
+
+ Space = Panel.left;
+ // NW = ScaleWidth - 2 * Space: If NW < 0 Then NW = 0
+ // NH = ScaleHeight - 3 * Space - cmbLevel.Height: If NH < 0 Then NH = 0
+ // picViewPort.Move Space, Space, NW, NH
+ Tmp = (ShowPanel != 0 ? ScaleHeight - Panel.Height : ScaleHeight - Panel.Height);
+ if (Tmp < 0)
+ Tmp = 0;
+
+ picViewPort.Move 0, 0, ScaleWidth, Tmp;
+ // Tmp = 2 * Space + picViewPort.Height
+ Panel.top = Tmp;
+ Panel.left = (ScaleWidth - Panel.Width) / 2;
+ // 'cmdNormal.Top = 2 * Space + picViewPort.Height
+ // cmbLevel.Top = Tmp
+ // lblRedDiskCount.Top = Tmp
+ // lblInfoCount.Top = Tmp
+ // picKeys.Top = Tmp
+ // lblFrameCount.Top = Tmp
+ // cmdPlayAll.Top = Tmp
+}
+
+#endif
+
+static void DrawFrame(int Delta)
+{
+ int i, LX, tY, RX, BY;
+
+ LX = -1 + Delta;
+ tY = -1 + Delta;
+ RX = FieldWidth - Delta;
+ BY = FieldHeight - Delta;
+ DrawSprite(LX, tY, posFrameCorner);
+ DrawSprite(LX, BY, posFrameCorner);
+ DrawSprite(RX, tY, posFrameCorner);
+ DrawSprite(RX, BY, posFrameCorner);
+ for (i = LX + 1; i <= RX - 1; i++)
+ {
+ DrawSprite(i, tY, posFrameHorizontal);
+ DrawSprite(i, BY, posFrameHorizontal);
+ }
+
+ for (i = tY + 1; i <= BY - 1; i++)
+ {
+ DrawSprite(LX, i, posFrameVertical);
+ DrawSprite(RX, i, posFrameVertical);
+ }
+}
+
+static void RestoreFrame()
+{
+ int i, LX, tY, RX, BY;
+
+ LX = 0;
+ tY = 0;
+ RX = FieldWidth - 1;
+ BY = FieldHeight - 1;
+ for (i = LX; i <= RX; i++)
+ {
+ DrawField(i, tY);
+ DrawField(i, BY);
+ }
+
+ for (i = tY + 1; i <= BY - 1; i++)
+ {
+ DrawField(LX, i);
+ DrawField(RX, i);
+ }
+}
+
+#if 0
+
+static void Form_Unload(int Cancel)
+{
+ EndFlag = True;
+ ExitToMenuFlag = 1;
+ if (cmdPlayAll.STRING_IS_LIKE(Caption, "Quit*"))
+ {
+ cmdPlayAll_Click();
+ }
+
+ if (menEdit.Checked)
+ menEdit_Click();
+
+ if (ModifiedFlag)
+ {
+ char *Msg;
+ VbMsgBoxResult Res;
+
+ Msg = "Save changes to " & GetFileNameToSave() & " ?";
+ Res = MsgBox(Msg, vbYesNoCancel, AppTitle & " - closing");
+ if (Res == vbCancel)
+ {
+ Cancel = -1;
+ return;
+ }
+
+ if (Res == vbYes)
+ {
+ if (FileExists(OrigPath) && menSave.Enabled)
+ {
+ menSave_Click();
+ }
+ else
+ {
+ menSaveAs_Click();
+ }
+ }
+ }
+
+ if (FileExists(TmpPath) || ModifiedFlag)
+ {
+ MayKill(TmpPath);
+ CurPath = OrigPath;
+ }
+
+ ReleaseDirectDraw();
+ SaveSettings();
+ End;
+}
+
+static void fpsTim_Timer()
+{
+ currency TickDiff;
+ int count5;
+
+ count5 = count5 + 1;
+ if (4 < count5)
+ {
+ TickDiff = T.TickDiffUS(LastTick);
+ lblFps.Caption = CLng(Round((1000000 * (TimerVar - LastFrame)) / (TickDiff), 0));
+ LastFrame = TimerVar;
+ LastTick = T.TickNow();
+ count5 = 0;
+ }
+
+ // If NoDisplayFlag Then lblFrameCount = TimerVar
+ lblFrameCount = TimerVar;
+}
+
+static void menAbout_Click()
+{
+ frmSplash.Show vbModal, Me;
+}
+
+static void menAutoScroll_Click()
+{
+ {
+ menAutoScroll.Checked = ! menAutoScroll.Checked;
+ AutoScrollFlag = menAutoScroll.Checked;
+ }
+}
+
+static void menBorder_Click()
+{
+ if (menBorder.Checked)
+ {
+ menBorder.Checked = False;
+ DisplayMinX = 1;
+ DisplayMaxX = FieldWidth - 2;
+ DisplayWidth = FieldWidth;
+ DisplayMinY = 1;
+ DisplayMaxY = FieldHeight - 2;
+ DisplayHeight = FieldHeight;
+ if (Loaded && LevelLoaded)
+ DrawFrame(1);
+
+ }
+ else
+ {
+ menBorder.Checked = True;
+ DisplayMinX = 0;
+ DisplayMaxX = FieldWidth - 1;
+ DisplayWidth = FieldWidth + 2;
+ DisplayMinY = 0;
+ DisplayMaxY = FieldHeight - 1;
+ DisplayHeight = FieldHeight + 2;
+ if (Loaded && LevelLoaded)
+ RestoreFrame();
+ }
+
+ ReStretch(Stretch);
+ // DisplayLevel True
+}
+
+void SetDisplayRegion()
+{
+ if (! menBorder.Checked)
+ {
+ DisplayMinX = 1;
+ DisplayMaxX = FieldWidth - 2;
+ DisplayWidth = FieldWidth;
+ DisplayMinY = 1;
+ DisplayMaxY = FieldHeight - 2;
+ DisplayHeight = FieldHeight;
+ if (LevelLoaded)
+ DrawFrame(1);
+
+ }
+ else
+ {
+ DisplayMinX = 0;
+ DisplayMaxX = FieldWidth - 1;
+ DisplayWidth = FieldWidth + 2;
+ DisplayMinY = 0;
+ DisplayMaxY = FieldHeight - 1;
+ DisplayHeight = FieldHeight + 2;
+ if (LevelLoaded)
+ RestoreFrame();
+ }
+}
+
+static void menCopy_Click()
+{
+ FMark.Copy;
+}
+
+void menEdit_Click()
+{
+ long L;
+
+ if (menEdit.Checked)
+ {
+ menEdit.Checked = False;
+ // leave edit mode
+ if (EditFlag)
+ Unload ToolBox;
+
+ EditFlag = False;
+ UnEdAll();
+ FMark.ShowMarker False;
+ picViewPort.MousePointer = 0;
+ if (ModifiedFlag)
+ {
+ if (! STRING_IS_LIKE(CurPath, TmpPath))
+ {
+ OrigPath = CurPath;
+ CurPath = TmpPath;
+ }
+
+ SaveMPX(TmpPath);
+ }
+
+ DisplayLevel();
+ Stage.Blt();
+ }
+ else
+ {
+ if (! LevelLoaded)
+ {
+ Beep();
+ return;
+ }
+
+ if (ModifiedFlag)
+ {
+ if (! STRING_IS_LIKE(CurPath, TmpPath))
+ {
+ OrigPath = CurPath;
+ CurPath = TmpPath;
+ }
+
+ SaveMPX(TmpPath);
+ }
+
+ subFetchAndInitLevel();
+ menEdit.Checked = True;
+ // enter edit mode
+ EditFlag = True;
+ // ScaleMode = vbTwips
+ ToolBox.Move (Width - ToolBox.Width) / 2, Height - ToolBox.Height;
+ // ScaleMode = vbPixels
+ // L = GetWindowLong(ToolBox.hWnd, GWL_STYLE)
+ // L = L And (Not WS_POPUP)
+ // L = L Or WS_CHILD
+ // SetWindowLong ToolBox.hWnd, GWL_STYLE, L
+ // SetParent ToolBox.hWnd, hWnd
+ ToolBox.Show vbModeless, Me;
+ EdAll();
+ DisplayLevel();
+ Stage.Blt();
+ FMark.ShowMarker True;
+ }
+}
+
+static void menEnOff_Click()
+{
+ menEnOn.Checked = False;
+ menEnOff.Checked = True;
+ SpSaveMenu();
+ SpLoadMenu();
+}
+
+static void menEnOn_Click()
+{
+ menEnOn.Checked = True;
+ menEnOff.Checked = False;
+ SpSaveMenu();
+ SpLoadMenu();
+}
+
+static void menExit_Click()
+{
+ Unload Me;
+}
+
+static void menFaster_Click()
+{
+ int i;
+
+ if (! bPlaying)
+ {
+ Debug.Assert(False);
+ return;
+ }
+
+ if (DemoFlag != 0) // demoplayback
+ {
+ i = GetSpeedIndex(DeltaTDemo);
+ i = i - 1;
+ If i < 2 Then i = 2;
+ menDemoSpeed_Click (i);
+ }
+ else
+ {
+ i = GetSpeedIndex(DeltaTPlay);
+ i = i - 1;
+ If i < 2 Then i = 2;
+ menPlaySpeed_Click (i);
+ }
+}
+
+static void menSlower_Click()
+{
+ int i;
+
+ if (! bPlaying)
+ {
+ Debug.Assert(False);
+ return;
+ }
+
+ if (DemoFlag != 0) // demoplayback
+ {
+ i = GetSpeedIndex(DeltaTDemo);
+ i = i + 1;
+ If nSpeedCount < i Then i = nSpeedCount;
+ menDemoSpeed_Click (i);
+ }
+ else
+ {
+ i = GetSpeedIndex(DeltaTPlay);
+ i = i + 1;
+ If nSpeedCount < i Then i = nSpeedCount;
+ menPlaySpeed_Click (i);
+ }
+}
+
+void menPlaySpeed_Click(int Index)
+{
+ int i;
+
+ // If NoDisplayFlag And (GameLoopRunning <> 0) Then
+ // NoDisplayFlag = False
+ // DisplayLevel
+ // End If
+ // NoDisplayFlag = False
+ for (i = menPlaySpeed.LBound; i <= menPlaySpeed.UBound; i++)
+ {
+ {
+ menPlaySpeed(i).Checked = (Index == i);
+ }
+ }
+
+ BlockingSpeed = False;
+ DeltaTPlay = SpeedsByDelayUS[Index];
+ UpdateDeltaT();
+ // If DeltaTPlay < 0 Then
+ // Stage.Blt
+ // DeltaT = 0
+ // NoDisplayFlag = True
+ // End If
+}
+
+void menDemoSpeed_Click(int Index)
+{
+ int i;
+
+ // If NoDisplayFlag And (GameLoopRunning <> 0) Then
+ // NoDisplayFlag = False
+ // DisplayLevel
+ // End If
+ NoDisplayFlag = False;
+ for (i = menDemoSpeed.LBound; i <= menDemoSpeed.UBound; i++)
+ {
+ {
+ menDemoSpeed(i).Checked = (Index == i);
+ }
+ }
+
+ BlockingSpeed = False;
+ DeltaTDemo = SpeedsByDelayUS[Index];
+ UpdateDeltaT();
+ // If DeltaTPlay < 0 Then
+ // Stage.Blt
+ // DeltaT = 0
+ // NoDisplayFlag = True
+ // End If
+}
+
+static void UpdateDeltaT()
+{
+ if (! bPlaying)
+ return;
+
+ DeltaT = (DemoFlag != 0 ? DeltaTDemo : DeltaTDemo);
+ if (DeltaT < 0)
+ {
+ Stage.Blt();
+ DeltaT = 0;
+ NoDisplayFlag = True;
+ }
+ else
+ {
+ if (NoDisplayFlag && GameLoopRunning != 0)
+ {
+ NoDisplayFlag = False;
+ DisplayLevel();
+ }
+ else
+ {
+ NoDisplayFlag = False;
+ }
+ }
+}
+
+static void menGravOff_Click()
+{
+ menGravOn.Checked = False;
+ menGravOff.Checked = True;
+ SpSaveMenu();
+ SpLoadMenu();
+}
+
+static void menGravOn_Click()
+{
+ menGravOn.Checked = True;
+ menGravOff.Checked = False;
+ SpSaveMenu();
+ SpLoadMenu();
+}
+
+static void menNew_Click()
+{
+ NewForm.Show vbModal, Me;
+ CreateLevel(FieldWidth, FieldHeight);
+ ReStretch(Stretch);
+}
+
+static void menNewStd_Click()
+{
+ CreateLevel(60, 24);
+ ReStretch(Stretch);
+}
+
+static void menOpen_Click()
+{
+ long LFilt;
+
+ {
+ // cmDlg.DefaultExt = "sp"
+
+ /*
+
+ (prevent compiler warning here due to suspected use of trigraph)
+
+ cmDlg.Filter = "All Levels (*.DAT;*.D??;*.sp;*.mpx)|*.DAT;*.D??;*.sp;*.mpx|MegaPlex Levels (*.mpx)|*.mpx" & "|Supaplex Level Sets (*.DAT;*.D??)|*.DAT;*.D??|SpeedFix Demos (*.sp)|*.sp";
+ */
+
+ LFilt = LastOpenFilter;
+ cmDlg.FilterIndex = (0 < LFilt & LFilt < 5 ? LFilt : LFilt);
+ if (FileExists(CurPath))
+ cmDlg.InitDir = WithSlash(StripDir(CurPath));
+
+ cmDlg.flags = cdlOFNHideReadOnly | cdlOFNLongNames;
+ }
+
+ // --- On Error GoTo menOpenEH
+ cmDlg.ShowOpen;
+ // --- On Error GoTo 0
+
+ LFilt = cmDlg.FilterIndex;
+ LastOpenFilter = LFilt;
+ CurPath = cmDlg.FileName;
+ OrigPath = CurPath;
+ FillFileList (CurPath);
+
+menOpenEH:
+}
+
+static void menOptions_Click()
+{
+ OptionsForm oFrm;
+
+ oFrm.Show vbModal, Me;
+ SaveSettings();
+ picViewPort_Resize();
+}
+
+static void menPanel_Click()
+{
+ {
+ PanelVisible = ! menPanel.Checked;
+ }
+}
+
+void Let_PanelVisible(boolean NewVal)
+{
+ boolean HidePanel;
+
+ if (HidePanel != NewVal)
+ return;
+
+ HidePanel = ! NewVal;
+ PanelTim.Enabled = True;
+}
+
+static void DrawPauseLayer(long Layer)
+{
+ DirectDrawPalette Pal;
+ PALETTEENTRY *Val;
+ long i;
+
+ // Dim X&, Y&
+ // For Y = 0 To bmpStage.Height Step BaseWidth
+ // For X = 0 To bmpStage.Width Step BaseWidth
+ // Pause.TransparentDraw bmpStageHDC, X, Y, Layer
+ // Next X
+ // Next Y
+ // With Stage.Surface
+ // Set Pal = .GetPalette
+ // for i=1 to pal.GetEntries(
+ // Stage.Surface.SetPalette
+}
+
+static void menPaste_Click()
+{
+ FMark.Paste;
+ DisplayLevel();
+ Stage.Blt();
+}
+
+static void menPause_Click()
+{
+ StdPicture OldPic;
+ char *OldText;
+
+ PauseMode = (PauseMode != 0 ? 0 : 0);
+ if (PauseMode != 0)
+ {
+ if (IS_NOTHING(&OldPic, sizeof(OldPic)))
+ OldPic = cmdPause.Picture;
+
+ cmdPause.Picture = cmdPause.DownPicture;
+ OldText = lblStatus.Caption;
+ lblStatus = "Paused ...";
+ }
+ else
+ {
+ cmdPause.Picture = OldPic;
+ lblStatus.Caption = OldText;
+ }
+}
+
+static void menPlayAll_Click()
+{
+ long iMin, iMax, i;
+ int FNum;
+ char *LogPath, *OutStr, *ReRecPath, *SPPath;
+ boolean bEqual;
+ boolean QuitFlag;
+
+ if (cmdPlayAll.STRING_IS_LIKE(Caption, "Play) All Demos")
+ {
+ cmdPlayAll.Caption = "Quit All";
+ menPlayAll.Caption = "Quit All";
+ FocusTim.Enabled = True;
+ QuitFlag = False;
+ iMin = 0;
+ iMax = cmbFile.ListCount - 1;
+ LogPath = StripDir(CurPath) & "/Error.Log";
+ if (Dir(LogPath) != "")
+ Kill(LogPath);
+
+ for (i = iMin; i <= iMax; i++)
+ {
+ cmbFile.ListIndex = i;
+ // If CurPath Like "*.sp" Or CurPath Like "*.mpx" Then
+ if (DemoAvailable)
+ {
+ SPPath = CurPath;
+ ReRecPath = SPPath & ".ReRec";
+ menPlayDemo_Click();
+ // SaveSP ReRecPath
+ // bEqual = FilesEqual(ReRecPath, SPPath)
+ // If bEqual Then MayKill ReRecPath
+ bEqual = True;
+ OutStr = cmbFile.List(i) & " -> ";
+ //
+ if (Val(lblFrameCount) != GetTotalFramesOfDemo())
+ {
+ OutStr = OutStr & "Error in GetTotalFramesOfDemo()! ";
+ Debug.Assert(False);
+ }
+
+ //
+ if ((LevelStatus == 1) && bEqual)
+ {
+ OutStr = OutStr & "Success";
+ }
+ else if (QuitFlag)
+ {
+ OutStr = OutStr & "All Demos (float)Canceled";
+ }
+ else
+ {
+ if (LevelStatus != 1)
+ {
+ OutStr = OutStr & "### Level Failed ### (TimerVar == " & TimerVar & ")";
+ }
+
+ if (! bEqual)
+ {
+ OutStr = OutStr & "### ReRecording is binary different ###";
+ }
+ }
+
+ FNum = FreeFile();
+ FNum = fopen(LogPath, "ab");
+ Print #FNum, OutStr;
+ fclose(FNum);
+ if (QuitFlag)
+ break;
+ }
+ }
+
+ cmdPlayAll.Caption = "Play All Demos";
+ menPlayAll.Caption = "Play All Demos";
+ SettingsObject Settings;
+
+ MySignature = Settings.Read("MySignature", "");
+ FirstDemoByte = 0x81;
+ }
+ else
+ {
+ QuitFlag = True;
+ if (menStop.Enabled)
+ menStop_Click();
+ }
+}
+
+static void menRemSP_Click()
+{
+ RemoveSP();
+ SpLoadMenu();
+}
+
+static void menRestoreBorder_Click()
+{
+ RestoreBorder();
+}
+
+static void menSave_Click()
+{
+ if (! ModifiedFlag)
+ return;
+
+ if (STRING_IS_LIKE(CurPath, TmpPath))
+ CurPath = OrigPath;
+
+ if (STRING_IS_LIKE(CurPath, "") || STRING_IS_LIKE(CurPath, "*.dat"))
+ {
+ menSaveAs_Click();
+ return;
+ }
+
+ if (STRING_IS_LIKE(CurPath, "*.sp"))
+ {
+ menSaveAs_Click();
+ return;
+ }
+
+ if (! FileExists(CurPath) || STRING_IS_LIKE(CurPath, "Untitled"))
+ {
+ menSaveAs_Click();
+ return;
+ }
+
+ SaveMPX(CurPath);
+ Let_ModifiedFlag(False);
+}
+
+static void menSaveAs_Click()
+{
+ if (SaveAs())
+ FillFileList (CurPath);
+}
+
+static boolean SaveAs()
+{
+ static boolean SaveAs;
+
+ char *FN;
+ SettingsObject s;
+
+ SaveAs = False;
+ {
+ // cmDlg.DefaultExt = "sp"
+ cmDlg.Filter = "MegaPlex Level (*.mpx)|*.mpx|SpeedFix Demo (*.sp)|*.sp";
+ cmDlg.FilterIndex = LastSaveFilter;
+ // If OrigPath Like "*.sp" Then cmDlg.FilterIndex = 1 Else cmDlg.FilterIndex = 0
+ if (FileExists(OrigPath))
+ {
+ cmDlg.InitDir = WithSlash(StripDir(OrigPath));
+ cmDlg.InitDir = s.Read("LastSaveDir", cmDlg.InitDir);
+ cmDlg.FileName = StripExtensionlessFileName(GetFileNameToSave());
+ }
+
+ cmDlg.flags = cdlOFNHideReadOnly | cdlOFNLongNames;
+ }
+
+ // --- On Error GoTo SaveAsEH
+ cmDlg.ShowSave;
+ // --- On Error GoTo 0
+
+ LastSaveFilter = cmDlg.FilterIndex;
+ FN = cmDlg.FileName;
+ SettingsObject_Save("LastSaveDir", WithSlash(StripDir(FN)));
+ if (STRING_IS_LIKE(FN, "*.sp"))
+ {
+ SaveSP(FN);
+ }
+ else if (STRING_IS_LIKE(FN, "*.mpx"))
+ {
+ SaveMPX(FN);
+ }
+
+ Let_ModifiedFlag(False);
+ SaveAs = True;
+
+SaveAsEH:
+
+ return SaveAs;
+}
+
+static void menSelectAll_Click()
+{
+ FMark.SetPoint1 0, 0;
+ FMark.SetPoint2 FieldWidth - 1, FieldHeight - 1;
+}
+
+static void menShowLInfo_Click()
+{
+ char *Msg;
+
+ Msg = LInfo.LevelTitle & vbNewLine & "(" & FieldWidth & " x " & FieldHeight & ")";
+ if (DemoAvailable && bSignatureAvailable)
+ Msg = Msg & vbNewLine & vbNewLine & gSignature;
+
+ SignatureForm.Signature = Msg;
+ SignatureForm.DelayMS = 5000;
+ int X, Y;
+
+ X = left + (Width - SignatureForm.Width) / 2;
+ Y = top + (Height - SignatureForm.Height) / 2;
+ SignatureForm.Move X, Y;
+ SignatureForm.Show vbModeless, Me;
+ Me.SetFocus;
+}
+
+static void menSoundFX_Click()
+{
+ {
+ menSoundFX.Checked = ! menSoundFX.Checked;
+ FXOnFlag = (menSoundFX.Checked ? -1 : -1);
+ }
+}
+
+#endif
+
+// static void menPlay_Click()
+void menPlay_Click()
+{
+
+#if 0
+
+ boolean OldEditFlag;
+
+ // Trace "MainForm", "--> menPlay_Click()"
+ if (! LevelLoaded)
+ {
+ Beep();
+ return;
+ }
+
+ SignatureForm.DelayMS = 1;
+ menPlay.Enabled = False;
+ menPause.Enabled = True;
+ menStop.Enabled = True;
+ cmdPlay.Enabled = False;
+ cmdPause.Enabled = True;
+ cmdStop.Enabled = True;
+ cmdPlayDemo.Enabled = False;
+ menPlayDemo.Enabled = False;
+ cmdRecordDemo.Enabled = False;
+ menRec.Enabled = False;
+ menFaster.Enabled = True;
+ menSlower.Enabled = True;
+ if (cmdPlayAll.STRING_IS_LIKE(Caption, "Play*"))
+ {
+ cmdPlayAll.Enabled = False;
+ menPlayAll.Enabled = False;
+ }
+
+ cmbFile.Enabled = False;
+ cmbLevel.Enabled = False;
+ OldEditFlag = EditFlag;
+ if (EditFlag)
+ menEdit_Click();
+
+ menEditMain.Enabled = False;
+ if (DemoFlag == 0 && RecordDemoFlag == 0)
+ lblStatus = "Playing";
+
+ lblFrameCount = 0;
+
+#endif
+
+ LastFrame = 0;
+ LastTick = T.TickNow;
+
+#if 0
+
+ fpsTim.Enabled = True;
+
+#endif
+
+ // DimPrimary 100
+ bPlaying = True;
+
+#if 0
+
+ UpdateDeltaT();
+
+#endif
+
+ subFetchAndInitLevelB();
+ // Trace "MainForm", "CountDown 1"
+ CountDown(2, (0 == DemoFlag));
+ // Trace "MainForm", "Call GoPlay"
+ GoPlay();
+ // Trace "MainForm", "GoPlay returned"
+
+#if 0
+
+ if (LevelStatus == 1)
+ {
+ lblStatus = "(float)Success";
+ }
+ else
+ {
+ lblStatus = "Try (float)again";
+ }
+
+#endif
+
+ // Trace "MainForm", "CountDown 1"
+ CountDown(1, False);
+ RecordDemoFlag = 0;
+
+#if 0
+ ShowKey(0);
+#endif
+
+ bPlaying = False;
+ // Trace "MainForm", "Call subFetchAndInitLevel"
+ subFetchAndInitLevel();
+ // Trace "MainForm", "subFetchAndInitLevel returned"
+ Stage.Blt();
+
+#if 0
+
+ menEditMain.Enabled = True;
+ if (OldEditFlag)
+ menEdit_Click();
+
+ // Trace "MainForm", "<-- menPlay_Click()"
+
+#endif
+
+}
+
+#if 0
+
+static void menPlayDemo_Click()
+{
+ DemoFlag = 1;
+ RecordDemoFlag = 0;
+ lblStatus = "Demo Playback";
+ menPlay_Click();
+ if (LevelStatus != 1)
+ lblStatus = "Demo Failed";
+
+ DemoFlag = 0;
+}
+
+static void menRec_Click()
+{
+ Trace("MainForm", "--> menRec_Click()");
+ if (! LevelLoaded)
+ {
+ Beep();
+ return;
+ }
+
+ RecordDemoFlag = 1;
+ DemoFlag = 0;
+ lblStatus.ForeColor = vbRed;
+ lblStatus = "Recording Demo";
+ // DemoBuffer = New DemoBufferObject; // (handle this later, if needed)
+ Debug.Assert(! IS_NOTHING(&DemoBuffer, sizeof(DemoBuffer)));
+ Trace("MainForm", "Call menPlayClick");
+ menPlay_Click();
+ Trace("MainForm", "menPlayClick returned");
+
+ lblStatus.ForeColor = vbButtonText;
+ RecordDemoFlag = 0;
+ Let_ModifiedFlag(True);
+ if (! STRING_IS_LIKE(CurPath, TmpPath))
+ {
+ OrigPath = CurPath;
+ CurPath = TmpPath;
+ }
+
+ LInfo.DemoRandomSeed = RecDemoRandomSeed;
+ Trace("MainForm", "Call SaveMPX(TmpPath)");
+ SaveMPX(TmpPath);
+ Trace("MainForm", "Set DemoBuffer == Nothing");
+ SET_TO_NOTHING(&DemoBuffer, sizeof(DemoBuffer));
+ Trace("MainForm", "Call subFetchAndInitLevel");
+ subFetchAndInitLevel();
+ cmdPlayDemo.Enabled = DemoAvailable;
+ Trace("MainForm", "<-- menRec_Click()");
+}
+
+static void menReRecordDemo_Click()
+{
+ if (! LevelLoaded)
+ {
+ Beep();
+ return;
+ }
+
+ RecordDemoFlag = 1;
+ DemoFlag = 1;
+ lblStatus.ForeColor = vbRed;
+ lblStatus = "ReRecording Demo";
+ // DemoBuffer = New DemoBufferObject; // (handle this later, if needed)
+ Debug.Assert(! IS_NOTHING(&DemoBuffer, sizeof(DemoBuffer)));
+ menPlay_Click();
+ lblStatus.ForeColor = vbButtonText;
+ RecordDemoFlag = 0;
+ Let_ModifiedFlag(True);
+ if (! STRING_IS_LIKE(CurPath, TmpPath))
+ {
+ OrigPath = CurPath;
+ CurPath = TmpPath;
+ }
+
+ LInfo.DemoRandomSeed = RecDemoRandomSeed;
+ SaveMPX(TmpPath);
+ SET_TO_NOTHING(&DemoBuffer, sizeof(DemoBuffer));
+ subFetchAndInitLevel();
+}
+
+void menStop_Click()
+{
+ EndFlag = True;
+ LeadOutCounter = 1;
+ if (PauseMode != 0)
+ menPause_Click();
+
+ fpsTim.Enabled = False;
+ fpsTim_Timer();
+ lblFps.Caption = "";
+ menRec.Enabled = True;
+ menPlay.Enabled = True;
+ menPause.Enabled = False;
+ menStop.Enabled = False;
+ cmdPlay.Enabled = True;
+ cmdPause.Enabled = False;
+ cmdStop.Enabled = False;
+ cmdRecordDemo.Enabled = True;
+ cmdPlayDemo.Enabled = DemoAvailable;
+ cmdPlayAll.Enabled = DemosAvailable;
+ menPlayDemo.Enabled = DemoAvailable;
+ menPlayAll.Enabled = DemosAvailable;
+ menFaster.Enabled = False;
+ menSlower.Enabled = False;
+ cmbFile.Enabled = True;
+ cmbLevel.Enabled = True;
+}
+
+static void menStretch_Click(int Index)
+{
+ ReStretch(0.25 * Index);
+ // DisplayLevel True
+}
+
+static void menToolTips_Click()
+{
+ {
+ menToolTips.Checked = ! menToolTips.Checked;
+ if (menToolTips.Checked)
+ {
+ cmdPlay.ToolTipText = "Play Game (Space)";
+ cmdPause.ToolTipText = "Pause (P)";
+ cmdStop.ToolTipText = "Stop (Q)";
+ cmdPlayDemo.ToolTipText = "Play demo (Ctrl+Space)";
+ cmdRecordDemo.ToolTipText = "Record demo (Ctrl+R)";
+ lblInfoCount.ToolTipText = "Number of infotrons needed";
+ lblRedDiskCount.ToolTipText = "Number of red disks";
+ cmbLevel.ToolTipText = "List of all levels in the file";
+ cmbFile.ToolTipText = "List of files in current directory";
+ lblFps.ToolTipText = "Animation speed in fps";
+ lblFrameCount.ToolTipText = "Game time in frames";
+ }
+ else
+ {
+ cmdPlay.ToolTipText = "";
+ cmdPause.ToolTipText = "";
+ cmdStop.ToolTipText = "";
+ cmdPlayDemo.ToolTipText = "";
+ cmdRecordDemo.ToolTipText = "";
+ lblInfoCount.ToolTipText = "";
+ lblRedDiskCount.ToolTipText = "";
+ cmbLevel.ToolTipText = "";
+ cmbFile.ToolTipText = "";
+ lblFps.ToolTipText = "";
+ lblFrameCount.ToolTipText = "";
+ }
+
+ }
+}
+
+static void menTrim_Click()
+{
+ LevelInfoType Tmp;
+ char *OldOPath;
+
+ OldOPath = OrigPath;
+ Tmp = LInfo;
+ Tmp.SpecialPortCount = 0; // hack: all special ports are deleted
+ menCopy_Click();
+ CreateLevel(FMark.Width, FMark.Height);
+ LInfo = Tmp;
+ OrigPath = OldOPath;
+ CurPath = OldOPath;
+ menSelectAll_Click();
+ menPaste_Click();
+ picViewPort_Resize();
+}
+
+static void menZonkOff_Click()
+{
+ menZonkOn.Checked = False;
+ menZonkOff.Checked = True;
+ SpSaveMenu();
+ SpLoadMenu();
+}
+
+static void menZonkOn_Click()
+{
+ menZonkOn.Checked = True;
+ menZonkOff.Checked = False;
+ SpSaveMenu();
+ SpLoadMenu();
+}
+
+static void PanelTim_Timer()
+{
+ int Tmp;
+
+ Tmp = Panel.Height;
+ if (PanelSeq < Panel.Height && -1 < PanelSeq)
+ {
+ PanelSeq = (ShowPanel != 0 ? PanelSeq + 2 : PanelSeq + 2);
+ Tmp = ScaleHeight - Tmp + PanelSeq;
+ Panel.top = Tmp;
+ picViewPort.Height = Tmp;
+ }
+ else
+ {
+ PanelTim.Enabled = False;
+ PanelSeq = (PanelSeq < 0 ? 0 : 0);
+ ShowPanel = (ShowPanel == 0 ? 1 : 1);
+ menPanel.Checked = (ShowPanel != 0);
+ }
+}
+
+static void picKeys_MouseUp(int Button, int Shift, float X, float Y)
+{
+ FocusTim.Enabled = True;
+}
+
+static void picMenu_Click()
+{
+}
+
+static void picPane_KeyDown(int KeyCode, int Shift)
+{
+ if (KeyCode < 0 || 255 < KeyCode)
+ return;
+
+ KeyState[KeyCode] = True;
+ switch (KeyCode)
+ {
+ case vbKeyControl:
+ if (MouseButton == 0 && EditFlag)
+ picPane.MousePointer = 15;
+
+ break;
+
+ case vbKeyUp:
+ case vbKeyLeft:
+ case vbKeyDown:
+ case vbKeyRight:
+ case vbKeySpace:
+ if (DemoFlag != 0)
+ {
+ DemoFlag = 0;
+ UpdateDeltaT();
+ }
+
+ break;
+
+ case vbKeyF12:
+ if (DemoFlag != 0 && 2 == Shift)
+ {
+ DemoFlag = 0;
+ UpdateDeltaT();
+ }
+
+ break;
+
+ case vbKeyF11:
+ bCapturePane = ! bCapturePane;
+ break;
+ }
+}
+
+static void picPane_KeyUp(int KeyCode, int Shift)
+{
+ if (KeyCode < 0 || 255 < KeyCode)
+ return;
+
+ KeyState[KeyCode] = False;
+ switch (KeyCode)
+ {
+ case vbKeyPageUp:
+ if (menFaster.Enabled)
+ menFaster_Click();
+
+ break;
+
+ case vbKeyPageDown:
+ if (menSlower.Enabled)
+ menSlower_Click();
+
+ break;
+
+ case vbKeySpace:
+ if (2 == Shift) // ctrl+space
+ {
+ if (menPlayDemo.Enabled)
+ menPlayDemo_Click();
+
+ }
+ else
+ {
+ if (menPlay.Enabled)
+ menPlay_Click();
+ }
+
+ break;
+
+ case vbKeyQ:
+ if (menStop.Enabled)
+ menStop_Click();
+
+ break;
+
+ case vbKeyR:
+ if (menRec.Enabled)
+ menRec_Click();
+
+ break;
+
+ case vbKeyP:
+ case vbKeyPause:
+ if (menPause.Enabled && (Shift == 0))
+ menPause_Click();
+
+ break;
+
+ case vbKeyControl:
+ if (MouseButton == 0 && EditFlag)
+ picPane.MousePointer = 0;
+ break;
+ }
+}
+
+static void picPane_MouseDown(int Button, int Shift, float X, float Y)
+{
+ int OldEdMode;
+
+ MouseButton = Button;
+ OldEdMode = EditMode;
+ if (Button != 1)
+ {
+ if (Button == 2 && Shift != 2)
+ {
+ EditMode = edSelect;
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ if (Shift == 2)
+ EditMode = edMove;
+
+ OSX = ScrollX;
+ OSY = ScrollY;
+ MDX = X;
+ MDY = Y;
+ switch (EditMode)
+ {
+ case edMove:
+ picPane.MousePointer = 5; // size
+ UserDragFlag = True;
+ break;
+
+ case edDraw:
+ SetField(X, Y, ToolBox.ASpriteIndex);
+ break;
+
+ case edSelect:
+ FMark.SetPoint1 EdGetX(X), EdGetY(Y);
+ FMark.MoveMarker;
+ break;
+ }
+
+ EditMode = OldEdMode;
+}
+
+static void picPane_MouseMove(int Button, int Shift, float X, float Y)
+{
+ boolean Oldflag;
+ int OldEdMode;
+
+ OldEdMode = EditMode;
+ if (Button != 1)
+ {
+ if (EditFlag && Button == 2 && Shift != 2)
+ {
+ EditMode = edSelect;
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ if (Shift == 2)
+ EditMode = edMove;
+
+ switch (EditMode)
+ {
+ case edMove:
+ Oldflag = NoDisplayFlag;
+ NoDisplayFlag = False;
+ ScrollTo(OSX - X + MDX, OSY - Y + MDY);
+ Stage.Blt();
+ NoDisplayFlag = Oldflag;
+ break;
+
+ case edDraw:
+ SetField(X, Y, ToolBox.ASpriteIndex);
+ break;
+
+ case edSelect:
+ FMark.SetPoint2 EdGetX(X), EdGetY(Y);
+ FMark.MoveMarker;
+ break;
+ }
+
+ EditMode = OldEdMode;
+}
+
+static void picPane_MouseUp(int Button, int Shift, float X, float Y)
+{
+ MouseButton = MouseButton ^ Button;
+ picPane.MousePointer = 0;
+ UserDragFlag = False;
+ if (menEditMain.Enabled && Button == 2)
+ {
+ if (MDX == X && MDY == Y)
+ PopupMenu menEditMain;
+ }
+}
+
+static void picPane_Paint()
+{
+ boolean Oldflag;
+
+ Oldflag = NoDisplayFlag;
+ NoDisplayFlag = False;
+ Stage.Blt();
+ NoDisplayFlag = Oldflag;
+}
+
+static void ReStretch(float NewStretch)
+{
+ long BW2, LW, LH, i;
+
+ if (! Loaded)
+ {
+ Stretch = NewStretch;
+ return;
+ }
+
+ MousePointer = 11;
+ SET_TO_NOTHING(&Stage, sizeof(Stage));
+ SET_TO_NOTHING(&StretchedSprites, sizeof(StretchedSprites));
+ menStretch(Stretch / 0.25).Checked = False;
+ Stretch = NewStretch;
+ menStretch(Stretch / 0.25).Checked = True;
+ // StretchWidth = BaseWidth ' * NewStretch
+ // StretchWidth2 = StretchWidth \ 2
+ // TwoPixels = 2 '* Stretch
+ // StretchLoad Sprites, imgMpx.Picture, 16, 16
+ BW2 = StretchWidth / 2;
+ LW = (FieldWidth + 2) * BaseWidth; // StretchWidth
+ LH = (FieldHeight + 2) * BaseWidth; // StretchWidth
+ // i = bmpStage.CreateAtSize(LW, LH)
+ // Stage = New DDScrollBuffer; // (handle this later, if needed)
+ i = Stage.CreateAtSize(LW, LH, picPane.hWnd);
+ // Set StretchedSprites = NormalSprites.GetStretchCopy(Stretch)
+ ReLoadStretchSprites();
+ if (i == 0 || IS_NOTHING(&StretchedSprites, sizeof(StretchedSprites)))
+ {
+ // menStretch(Stretch / 0.5).Enabled = False
+ if (0.5 <= Stretch)
+ ReStretch(Stretch - 0.25);
+
+ }
+ else
+ {
+ StretchedSprites.DestXOff = 1 * BaseWidth; // StretchWidth
+ StretchedSprites.DestYOff = 1 * BaseWidth; // StretchWidth
+ Stage.DestXOff = 1 * StretchWidth;
+ Stage.DestYOff = 1 * StretchWidth;
+ StretchedSprites.DestinationSurface = Stage.Surface;
+ Stage.Cls;
+ if (Loaded && LevelLoaded)
+ {
+ SetDisplayRegion();
+ picViewPort_Resize();
+ DisplayLevel();
+ }
+
+ subCalculateScreenScrollPos();
+ ScrollTo(ScreenScrollXPos, ScreenScrollYPos);
+ Stage.Blt();
+ picPane_Paint();
+ }
+
+ MousePointer = 0;
+}
+
+static void SetScrollEdges()
+{
+ ScrollMinX = (DisplayMinX - 0.5) * Stretch * BaseWidth;
+ ScrollMinY = (DisplayMinY - 0.5) * Stretch * BaseWidth;
+ ScrollMaxX = (DisplayMaxX + 1.5) * Stretch * BaseWidth - picPane.Width;
+ ScrollMaxY = (DisplayMaxY + 1.5) * Stretch * BaseWidth - picPane.Height;
+}
+
+#endif
+
+void DrawField(int X, int Y)
+{
+ int Tmp, tsi;
+
+ tsi = GetSI(X, Y);
+ Tmp = LowByte(PlayField16[tsi]);
+ if (40 < Tmp)
+ Tmp = 0;
+
+ if (Tmp == fiRAM || Tmp == fiHardWare)
+ Tmp = DisPlayField[tsi];
+
+ if (Tmp == fiBug || Tmp == 40)
+ Tmp = DisPlayField[tsi];
+
+ if (EditFlag)
+ {
+ if (fiOrangeDisk < Tmp && Tmp < fiSnikSnak)
+ Tmp = DisPlayField[tsi];
+ }
+
+ StretchedSprites.BltEx(StretchWidth * X, StretchWidth * Y, Tmp);
+}
+
+void DrawFieldAnimated(int X, int Y)
+{
+ int Tmp, tsi;
+
+ tsi = GetSI(X, Y);
+ Tmp = LowByte(PlayField16[tsi]);
+ switch (Tmp)
+ {
+ case fiSnikSnak:
+ subDrawAnimatedSnikSnaks(tsi);
+ break;
+
+ case fiElectron:
+ subDrawAnimatedElectrons(tsi);
+ break;
+
+ default:
+ // If 40 < Tmp Then Tmp = 0
+ // If Tmp = fiRAM Or Tmp = fiHardWare Then Tmp = DisPlayField(tsi)
+ // If Tmp = fiBug Or Tmp = 40 Then Tmp = DisPlayField(tsi)
+ // If EditFlag Then
+ // If fiOrangeDisk < Tmp And Tmp < fiSnikSnak Then Tmp = DisPlayField(tsi)
+ // End If
+ // StretchedSprites.BltEx StretchWidth * X, StretchWidth * Y, Tmp
+ break;
+ }
+}
+
+void DrawFieldNoAnimated(int X, int Y)
+{
+ int Tmp, tsi;
+
+ tsi = GetSI(X, Y);
+ Tmp = LowByte(PlayField16[tsi]);
+ switch (Tmp)
+ {
+ case fiSnikSnak:
+ StretchedSprites.BltEx(StretchWidth * X, StretchWidth * Y, fiSpace);
+ break;
+
+ case fiElectron:
+ StretchedSprites.BltEx(StretchWidth * X, StretchWidth * Y, fiSpace);
+ break;
+
+ default:
+ if (40 < Tmp)
+ Tmp = 0;
+
+ if (Tmp == fiRAM || Tmp == fiHardWare)
+ Tmp = DisPlayField[tsi];
+
+ if (Tmp == fiBug || Tmp == 40)
+ Tmp = DisPlayField[tsi];
+
+ if (EditFlag)
+ {
+ if (fiOrangeDisk < Tmp && Tmp < fiSnikSnak)
+ Tmp = DisPlayField[tsi];
+ }
+
+ StretchedSprites.BltEx(StretchWidth * X, StretchWidth * Y, Tmp);
+ break;
+ }
+}
+
+void DrawSprite(int X, int Y, int SpritePos)
+{
+ StretchedSprites.BltEx(StretchWidth * X, StretchWidth * Y, SpritePos);
+}
+
+#if 0
+
+void InvalidateRect(long XMin, long YMin, long XMax, long YMax)
+{
+ long X, Y;
+
+ // For Y = YMin To YMax
+ // For X = XMin To XMax
+ // Field(X, Y).GraphicsValid = 0
+ // Next X
+ // Next Y
+}
+
+static void picViewPort_MouseUp(int Button, int Shift, float X, float Y)
+{
+ FocusTim.Enabled = True;
+}
+
+static void picViewPort_Paint()
+{
+ // Debug.Print "picViewPort_Paint()"
+}
+
+static void picViewPort_Resize()
+{
+ long bdX, bdY, PanelVisibility;
+ long X, Y, dx, dY;
+ SettingsObject s;
+ boolean B;
+
+ bdX = picFrame.Width - picFrame.ScaleWidth;
+ bdY = picFrame.Height - picFrame.ScaleHeight;
+ dx = Min(picViewPort.ScaleWidth - bdX, (DisplayWidth - 1) * Stretch * BaseWidth);
+ dx = Max(dx, 0);
+ dY = Min(picViewPort.ScaleHeight - bdX, (DisplayHeight - 1) * Stretch * BaseWidth);
+ dY = Max(dY, 0);
+ B = s.Read("LimitToOriginalFieldSize", False);
+ PanelVisibility = 24 * (Panel.Height - PanelSeq - (float)1) / Panel.Height;
+ if (B)
+ {
+ dx = Min(320 * Stretch, dx);
+ dY = Min((200 - PanelVisibility) * Stretch, dY);
+ }
+
+ X = Max((picViewPort.ScaleWidth - dx) / 2, 0);
+ Y = Max((picViewPort.ScaleHeight - dY) / 2, 0);
+ picPane.Move X, Y, dx, dY;
+ picFrame.Move X - bdX / 2, Y - bdY / 2, dx + bdX, dY + bdY;
+ SetScrollEdges();
+ ScrollTo(ScrollX, ScrollY);
+ // SizeTim.Interval = 1
+}
+
+//
+// Private Sub SizeTim_Timer()
+// Dim wdX&, wdY&
+// SizeTim.Interval = 0
+// wdX = Max(0, picViewPort.ScaleWidth - picPane.Width) * Screen.TwipsPerPixelX
+// wdY = Max(0, picViewPort.ScaleHeight - picPane.Height) * Screen.TwipsPerPixelY
+// If (0 < wdX) Or (0 < wdY) Then
+// Move Left, Top, Width - wdX, Height - wdY
+// End If
+// End Sub
+
+static void LoadKeyIndicators()
+{
+ int i;
+
+ picKeys.BackColor = vbButtonFace;
+ for (i = 2; i <= 5; i++)
+ {
+ Load shpKey(i);
+ }
+
+ for (i = 1; i <= 5; i++)
+ {
+ shpKey(i).FillColor = vbButtonFace;
+ shpKey(i).Visible = True;
+ }
+
+ shpKey(1).Move 7, 0;
+ shpKey(2).Move 0, 7;
+ shpKey(3).Move 7, 14;
+ shpKey(4).Move 14, 7;
+ shpKey(5).Move 7, 7;
+}
+
+void ShowKey(int KeyVar)
+{
+ boolean State[5 + 1];
+ int i;
+ boolean Tmp;
+ long Col;
+ boolean LastState[5 + 1];
+
+ // For i = 1 To 5
+ // State(i) = False
+ // Next i
+ switch (KeyVar)
+ {
+ case 0:
+ // do nothing
+ break;
+
+ case Is < 5:
+ State[KeyVar] = True;
+ break;
+
+ default:
+ State[5] = True;
+ if (KeyVar < 9)
+ State[KeyVar - 4] = True;
+ break;
+ }
+
+ for (i = 1; i <= 5; i++)
+ {
+ Tmp = State[i];
+ if (Tmp ^ LastState[i])
+ {
+ Col = (i == 5 ? vbRed : vbRed);
+ shpKey(i).FillColor = (Tmp ? Col : Col);
+ shpKey(i).Refresh;
+ LastState[i] = Tmp;
+ }
+ }
+}
+
+static void GetSettings()
+{
+ SettingsObject s;
+ char *APath;
+ long X, Y;
+ int i;
+ boolean Flag;
+
+ {
+ // last file info
+ APath = WithSlash(App.Path);
+ CurPath = s.Read("LastPath", APath);
+ OrigPath = CurPath;
+ // window width and height
+ X = s.Read("Width", Width);
+ Y = s.Read("Height", Height);
+ if (X < 0 Then X == 0: If Y < 0)
+ Y = 0;
+
+ if (Screen.Width < X)
+ X = Screen.Width;
+
+ if (Screen.Height < Y)
+ Y = Screen.Height;
+
+ Width = X;
+ Height = Y;
+ // window position and state
+ X = s.Read("Left", left);
+ Y = s.Read("Top", top);
+ if (X < 0 Then X == 0: If Y < 0)
+ Y = 0;
+
+ if (Screen.Width < (X + Width))
+ X = Screen.Width - Width;
+
+ if (Screen.Height < (Y + Height))
+ Y = Screen.Height - Height;
+
+ left = X;
+ top = Y;
+ WindowState = s.Read("WinState", vbNormal);
+ // flags/options
+ Flag = s.Read("ShowToolTips", True);
+ if (Flag)
+ menToolTips_Click();
+
+ menBorder.Checked = ! CBool(s.Read("ShowBorder", False));
+ Flag = CBool(s.Read("AutoScroll", True));
+ if (! Flag)
+ {
+ AutoScrollFlag = False;
+ menAutoScroll.Checked = False;
+ }
+
+ Flag = CBool(s.Read("SoundFX", True));
+ FXOnFlag = (Flag ? -1 : -1);
+ menSoundFX.Checked = Flag;
+ SignatureDelay = CLng(s.Read("SignatureDelay", 3000));
+ AllowRedDiskCheat = CInt(s.Read("AllowRedDiskCheat", 1));
+ AllowEatRightRedDiskBug = CInt(s.Read("AllowEatRightRedDiskBug", 1));
+ MySignature = s.Read("MySignature", "");
+ // speed
+ X = s.Read("FrameDelayPlay", 1000000 / 35);
+ i = GetSpeedIndex(X);
+ menPlaySpeed_Click(i);
+ X = s.Read("FrameDelayDemo", 1000000 / 35);
+ i = GetSpeedIndex(X);
+ menDemoSpeed_Click(i);
+ // Zoom
+ i = s.Read("Stretch", 4);
+ if (i < menStretch.LBound || menStretch.UBound < i)
+ i = 4;
+
+ menStretch_Click (i);
+ }
+}
+
+static void SaveSettings()
+{
+ SettingsObject s;
+ int i;
+
+ {
+ s.Save "LastPath", (ModifiedFlag ? OrigPath : OrigPath);
+ if (WindowState != vbMinimized)
+ {
+ s.Save "Width", Width;
+ s.Save "Height", Height;
+ s.Save "Left", left;
+ s.Save "Top", top;
+ s.Save "WinState", WindowState;
+ }
+
+ s.Save "ShowToolTips", menToolTips.Checked;
+ s.Save "ShowBorder", menBorder.Checked;
+ s.Save "AutoScroll", menAutoScroll.Checked;
+ s.Save "SoundFX", menSoundFX.Checked;
+ s.Save "SignatureDelay", SignatureDelay;
+ s.Save "AllowRedDiskCheat", AllowRedDiskCheat;
+ s.Save "AllowEatRightRedDiskBug", AllowEatRightRedDiskBug;
+ s.Save "MySignature", MySignature;
+ // speeds
+ s.Save "FrameDelayPlay", DeltaTPlay;
+ s.Save "FrameDelayDemo", DeltaTDemo;
+ // zoom
+ for (i = menStretch.LBound; i <= menStretch.UBound; i++)
+ {
+ if (menStretch(i).Checked)
+ break;
+ }
+
+ s.Save "Stretch", i;
+ // s.Save "",
+ }
+}
+
+void ReLoadStretchSprites()
+{
+ long Tmp;
+ BitMapObject NBMP, SBMP;
+ char *tmpMpxBmp;
+
+ // If Stretch = 1 Then
+ MpxBmp = App.Path & "/Mpx.bmp";
+ // Else
+ // MpxBmp = App.Path & "\Mpx" & Stretch & ".bmp"
+ // tmpMpxBmp = App.Path & "\Mpx.bmp"
+ // If FileExists(MpxBmp) And FileExists(tmpMpxBmp) Then
+ // If FileDateTime(MpxBmp) < FileDateTime(tmpMpxBmp) Then
+ // MayKill MpxBmp
+ // End If
+ // End If
+ // If Not FileExists(MpxBmp) Then
+ // MousePointer = 11
+ // // Set NBMP = New BitMapObject // (handle this later, if needed)
+ // tmpMpxBmp = App.Path & "\Mpx.bmp"
+ // If Not FileExists(tmpMpxBmp) Then
+ // ReportError "ReLoadStretchSprites", "File not found: " & tmpMpxBmp
+ // MESSAGE_BOX("an error occured"); // MsgBox "File not found: " & tmpMpxBmp, vbCritical, "MegaPlex - Error"
+ // End
+ // End If
+ // NBMP.CreateFromFile tmpMpxBmp
+ // Set SBMP = NBMP.GetStretchCopy(Stretch)
+ // SBMP.SaveToFile MpxBmp
+ // Set NBMP = Nothing
+ // Set SBMP = Nothing
+ // MousePointer = 0
+ // End If
+ // End If
+ // StretchedSprites = New DDSpriteBuffer; // (handle this later, if needed)
+ if (! StretchedSprites.CreateFromFile(MpxBmp, 16, 16))
+ SET_TO_NOTHING(&StretchedSprites, sizeof(StretchedSprites));
+}
+
+void SaveSnapshot(currency Number)
+{
+ char *Path;
+
+ Path = CAT(WithSlash(App.Path), "Capture");
+ if (! IsDir(Path))
+ MkDir(Path);
+
+ Path = Path & "\" & Format(Number, "00000000") & ".bmp";
+ SavePicture CaptureWindow(picPane.hWnd, True, 0, 0, picPane.ScaleWidth, picPane.ScaleHeight), Path;
+}
+
+#endif
--- /dev/null
+// ----------------------------------------------------------------------------
+// MainForm.h
+// ----------------------------------------------------------------------------
+
+#ifndef MAINFORM_H
+#define MAINFORM_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern void DisplayLevel();
+extern void DrawField(int X, int Y);
+extern void DrawFieldAnimated(int X, int Y);
+extern void DrawFieldNoAnimated(int X, int Y);
+extern void DrawSprite(int X, int Y, int SpritePos);
+extern void InvalidateRect(long XMin, long YMin, long XMax, long YMax);
+extern void Let_PanelVisible(boolean NewVal);
+extern void ReLoadStretchSprites();
+extern void SaveSnapshot(currency Number);
+extern void SetDisplayRegion();
+extern void ShowKey(int KeyVar);
+extern void menDemoSpeed_Click(int Index);
+extern void menEdit_Click();
+extern void menPlaySpeed_Click(int Index);
+extern void menStop_Click();
+
+#endif /* MAINFORM_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// MainGameLoop.c
+// ----------------------------------------------------------------------------
+
+#include "MainGameLoop.h"
+
+static char *VB_Name = "modMainGameLoop";
+// --- Option Explicit
+
+int GameLoopRunning;
+boolean bPlaying;
+int LeadOutCounter, EnterRepeatCounter;
+int ForcedExitFlag;
+int ExitToMenuFlag;
+int SavedGameFlag;
+boolean UserDragFlag;
+boolean AutoScrollFlag;
+
+// ==========================================================================
+// SUBROUTINE
+// Play a game/demo
+// ==========================================================================
+
+int subMainGameLoop()
+{
+ int subMainGameLoop;
+
+ int al, bx;
+ TickCountObject Clock;
+ currency LastFrame;
+
+ if (DemoFlag != 0)
+ {
+ // EP set level success byte: demo, not game
+ WasDemoFlag = 1;
+ EP_GameDemoVar0DAA = 0; // demo
+ }
+ else // loc_g_1836:
+ {
+ // EP set level success byte: game, not demo
+ WasDemoFlag = 0;
+ EP_GameDemoVar0DAA = 1; // game
+ }
+
+ // RestartGameLoop:
+ // If RecordDemoFlag = 1 Then
+ // RecordDemoFlag = 0 ' clear Demo Recording flag
+ // Call subDisplayPlayingTime ' playing time on screen
+ // ' Record key still pressed?' >= (Ctrl-)F1 and <= (Ctrl-)F10
+ // While &H3B <= KeyScanCode7 And KeyScanCode7 <= &H44
+ // ' yes -> wait until released
+ // ' should we DoEvents here???? ... depends on how ... but yes!
+ // ' ...or we can rather poll the keyboardstate inside this loop???
+ // Wend
+ // Call subInitGameConditions ' Init game conditions (vars)
+ // If MusicOnFlag = 0 Then Call subMusicInit
+ // WasDemoFlag = 0 ' no demo anymore
+ // EP_GameDemoVar0DAA = 1 ' force game
+ // End If
+
+ // This was a bug in the original Supaplex: sometimes red disks could not
+ // be released. This happened If Murphy was killed DURING a red disk release
+ // and the next try started.
+ RedDiskReleasePhase = 0; // (re-)enable red disk release
+ UpdatedFlag = 0;
+ GameLoopRunning = 1;
+ LevelStatus = 0;
+ // ----------------------------------------------------------------------------
+ // --------------------- START OF GAME-BUSY LOOP ------------------------------
+ // ----------------------------------------------------------------------------
+
+locRepeatMainGameLoop: // start repeating game loop
+
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ // FS synchronization
+ while (PauseMode != 0)
+ {
+ DoEvents();
+ }
+
+ do
+ {
+ DoEvents(); // user may klick on menus or move the window here ...
+ }
+ while (Clock.TickDiffUS(LastFrame) < DeltaT); // wait till its time for the next frame
+
+ // never any additional code between here!
+ LastFrame = Clock.TickNow; // store the frame time
+ // never any additional code between here!
+ if (! NoDisplayFlag) // copy the BackBuffer(=Stage) to visible screen
+ Stage.Blt();
+
+ // FS end of synchronization
+ // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ if (EndFlag)
+ goto locExitMainGameLoop;
+
+ // If DemoFlag = 0 Then Call subCheckJoystick ' check joystick
+ // bx = subCheckRightMouseButton() ' check (right) mouse button
+ // If bx = 2 And LeadOutCounter < 1 Then KillMurphyFlag = 1 ' lead-out busy after quit? -> kill Murphy!
+
+ // If DebugVersionFlag <> 0 Then ' debug mode on?
+ // If Data_SubRest <> 0 Then Data_SubRest = Data_SubRest - 1
+ // If keyEnter <> 0 Then GoTo loc_g_186F ' Was it the Enter key? -> yes--skip! No mouse!
+ // ' fixes ENTER bug If no mouse driver!
+ // If bx <> 1 Then GoTo loc_g_186F ' Left button=Init game field
+ // ' Also Enter If no mouse!
+ // If Data_SubRest <> 0 Then GoTo loc_g_186F
+ // Data_SubRest = 10
+ // Call subRestoreFancy
+ // Call subDisplayLevel ' Paint (Init) game field
+ // Call subConvertToEasySymbols ' Convert to easy symbols
+ // End If
+
+loc_g_186F:
+ subProcessKeyboardInput(); // Check keyboard, act on keys
+ // 'HACK:
+ // TimerVar = TimerVar + 1
+ // DoEvents
+ // GoTo loc_g_186F
+ // 'END HACK
+ // If RecordDemoFlag = 1 Then GoTo RestartGameLoop
+
+ // ----------------------------------------------------------------------------
+ //
+ subDoGameStuff(); // do all game stuff
+ //
+ // ----------------------------------------------------------------------------
+
+ // Call subDisplayPlayingTime ' playing time on screen
+ subCheckRestoreRedDiskCountDisplay(); // Restore panel: red-disk hole
+
+ subRedDiskReleaseExplosion(); // Red Disk release and explode
+ subFollowUpExplosions(); // every explosion may cause up to 8 following explosions
+
+ bx = subCalculateScreenScrollPos(); // calculate screen start addrs
+ ScreenPosition = bx;
+ // Now new X and new Y are calculated, and bx = screen position = ScreenPosition
+ data_h_Ytmp = ScreenScrollYPos; // copy Y for next soft scroll
+ data_h_Xtmp = ScreenScrollXPos; // copy X for next soft scroll
+ if ((! UserDragFlag) && AutoScrollFlag)
+ ScrollTowards(ScreenScrollXPos, ScreenScrollYPos);
+
+ if (ForcedExitFlag != 0) // Forced Exit?' yes--exit!
+ goto locExitMainGameLoop;
+
+ TimerVar = TimerVar + 1;
+
+#if 0
+ if (bCapturePane)
+ MainForm.SaveSnapshot(TimerVar);
+#endif
+
+ // If Not NoDisplayFlag Then
+ // With MainForm.lblFrameCount
+ // .Caption = TimerVar
+ // .Refresh
+ // End With
+ // End If
+ if (ExitToMenuFlag == 1)
+ goto locExitMainGameLoop;
+
+ if (LeadOutCounter == 0) // no lead-out: game busy
+ goto locRepeatMainGameLoop;
+
+ // ----------------------------------------------------------------------------
+ // ---------------------- END OF GAME-BUSY LOOP -------------------------------
+ // ----------------------------------------------------------------------------
+ LeadOutCounter = LeadOutCounter - 1; // do more lead-out after quit
+ if (LeadOutCounter != 0) // lead-out not ready: more
+ goto locRepeatMainGameLoop;
+
+ // lead-out done: exit now
+ // ---------------------- END OF GAME-BUSY LOOP (including lead-out) ----------
+
+locExitMainGameLoop:
+ do
+ {
+ DoEvents(); // user may klick on menus or move the window here ...
+ }
+ while (Clock.TickDiffUS(LastFrame) < DeltaT); // wait till its time for the next frame
+
+ Stage.Blt(); // blit the last frame
+ GameLoopRunning = 0;
+
+#if 0
+ MainForm.menStop_Click();
+ MainForm.PanelVisible = True;
+#endif
+
+ // If DemoRecordingFlag <> 0 Then Call subCloseDemoRecordingFile ' Demo recording on? -> close opened demo file (w)
+ if (SavedGameFlag != 0) // after savegame: no update!
+ {
+ SavedGameFlag = 0;
+ return subMainGameLoop;
+ }
+
+ SavedGameFlag = 0;
+ if (UpdateTimeFlag == 0) // update time?
+ return subMainGameLoop;
+
+ if (UpdatedFlag == 0) // update playing time
+ subUpdatePlayingTime();
+
+
+ return subMainGameLoop;
+} // subMainGameLoop
+
+void subUpdatePlayingTime()
+{
+}
+
+int subCalculateScreenScrollPos()
+{
+ int subCalculateScreenScrollPos;
+
+ int ax, Ay;
+
+ if (ExplosionShake != 0)
+ {
+ subGetRandomNumber();
+ }
+
+ {
+ ax = MainForm.picPane.Width / 2;
+ Ay = MainForm.picPane.Height / 2;
+ }
+ ScreenScrollXPos = Stretch * (MurphyScreenXPos + 8) - ax;
+ ScreenScrollYPos = Stretch * (MurphyScreenYPos + 8) - Ay;
+
+ return subCalculateScreenScrollPos;
+}
+
--- /dev/null
+// ----------------------------------------------------------------------------
+// MainGameLoop.h
+// ----------------------------------------------------------------------------
+
+#ifndef MAINGAMELOOP_H
+#define MAINGAMELOOP_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern int subCalculateScreenScrollPos();
+extern int subMainGameLoop();
+extern void subUpdatePlayingTime();
+
+extern boolean AutoScrollFlag;
+extern boolean UserDragFlag;
+extern boolean bPlaying;
+extern int ExitToMenuFlag;
+extern int ForcedExitFlag;
+extern int GameLoopRunning;
+extern int LeadOutCounter, EnterRepeatCounter;
+extern int SavedGameFlag;
+
+#endif /* MAINGAMELOOP_H */
--- /dev/null
+# =============================================================================
+# Rocks'n'Diamonds Makefile (game_sp)
+# -----------------------------------------------------------------------------
+# (c) 1995-2009 Holger Schemel <info@artsoft.org>
+# -----------------------------------------------------------------------------
+# MegaPlex version 0.5 beta release xmas 2001 by Frank Schindler,
+# based on the Speed Fix 6.3+ by Herman Perk,
+# based on original Supaplex by Michael Stopp & Philip Jespersen.
+# =============================================================================
+
+# -----------------------------------------------------------------------------
+# configuration
+# -----------------------------------------------------------------------------
+
+SRCS = main.c \
+ vb_lib.c \
+ vb_vars.c \
+ \
+ ASM.c \
+ BitMapObject.c \
+ BugsTerminals.c \
+ Capture.c \
+ DDScrollBuffer.c \
+ DDSpriteBuffer.c \
+ Demo.c \
+ DemoBufferObject.c \
+ DirectDrawGlobals.c \
+ DirectXGlobals.c \
+ Display.c \
+ DoGameStuff.c \
+ Electrons.c \
+ ErrorReporting.c \
+ Explosions.c \
+ FakeDeclares.c \
+ FancyRestore.c \
+ GeneralTricks.c \
+ Globals.c \
+ Infotrons.c \
+ InitGameConditions.c \
+ Input.c \
+ LevelSetPreviewForm.c \
+ MainForm.c \
+ MainGameLoop.c \
+ Marker.c \
+ Murphy.c \
+ OrangeDisk.c \
+ PathTools.c \
+ SettingsObject.c \
+ SnikSnaks.c \
+ Sound.c \
+ TickCountObject.c \
+ TopMost.c \
+ Zonk.c \
+ modAnimations.c \
+ modGeneralTricks.c \
+ modMPX.c
+
+OBJS = main.o \
+ vb_lib.o \
+ vb_vars.o \
+ \
+ ASM.o \
+ BitMapObject.o \
+ BugsTerminals.o \
+ Capture.o \
+ DDScrollBuffer.o \
+ DDSpriteBuffer.o \
+ Demo.o \
+ DemoBufferObject.o \
+ DirectDrawGlobals.o \
+ DirectXGlobals.o \
+ Display.o \
+ DoGameStuff.o \
+ Electrons.o \
+ ErrorReporting.o \
+ Explosions.o \
+ FakeDeclares.o \
+ FancyRestore.o \
+ GeneralTricks.o \
+ Globals.o \
+ Infotrons.o \
+ InitGameConditions.o \
+ Input.o \
+ LevelSetPreviewForm.o \
+ MainForm.o \
+ MainGameLoop.o \
+ Marker.o \
+ Murphy.o \
+ OrangeDisk.o \
+ PathTools.o \
+ SettingsObject.o \
+ SnikSnaks.o \
+ Sound.o \
+ TickCountObject.o \
+ TopMost.o \
+ Zonk.o \
+ modAnimations.o \
+ modGeneralTricks.o \
+ modMPX.o
+
+GAME_SP = game_sp.a
+
+
+# -----------------------------------------------------------------------------
+# build targets
+# -----------------------------------------------------------------------------
+
+all: $(GAME_SP)
+
+$(GAME_SP): $(OBJS)
+ $(AR) cru $(GAME_SP) $(OBJS)
+ $(RANLIB) $(GAME_SP)
+
+.c.o:
+ $(CC) $(PROFILING) $(CFLAGS) -c $*.c
+
+clean:
+ $(RM) $(OBJS)
+ $(RM) $(GAME_SP)
+
+
+# -----------------------------------------------------------------------------
+# development only
+# -----------------------------------------------------------------------------
+
+depend:
+ for i in $(SRCS); do $(CPP) $(CFLAGS) -M $$i; done > .depend
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
--- /dev/null
+// ----------------------------------------------------------------------------
+// Marker.c
+// ----------------------------------------------------------------------------
+
+#include "Marker.h"
+
+static boolean IsPort(long i);
+static void LimitXY(int *X, int *Y);
+static void SortData();
+
+// --- VERSION 1.0 CLASS
+// --- BEGIN
+// --- MultiUse = -1 'True // True
+// --- Persistable = 0 'NotPersistable // NotPersistable
+// --- DataBindingBehavior = 0 'vbNone // vbNone
+// --- DataSourceBehavior = 0 'vbNone // vbNone
+// --- MTSTransactionMode = 0 'NotAnMTSObject // NotAnMTSObject
+// --- END
+
+static char *VB_Name = "MarkerObject";
+static boolean VB_GlobalNameSpace = False;
+static boolean VB_Creatable = True;
+static boolean VB_PredeclaredId = False;
+static boolean VB_Exposed = False;
+// --- Option Explicit
+
+long mIndex1, mIndex2;
+int X1, X2, Y1, Y2;
+int XMin, YMin;
+boolean mVisible;
+
+byte *SelectionData;
+
+int Marker_Get_Width()
+{
+ int Width;
+
+ Width = Abs(X2 - X1) + 1;
+
+ return Width;
+}
+
+int Marker_Get_Height()
+{
+ int Height;
+
+ Height = Abs(Y2 - Y1) + 1;
+
+ return Height;
+}
+
+int Marker_Get_Left()
+{
+ int Left;
+
+ SortData();
+ Left = XMin;
+
+ return Left;
+}
+
+int Marker_Get_Top()
+{
+ int Top;
+
+ SortData();
+ Top = YMin;
+
+ return Top;
+}
+
+static void LimitXY(int *X, int *Y)
+{
+ if (*X < DisplayMinX)
+ *X = DisplayMinX;
+
+ if (DisplayMaxX < *X)
+ *X = DisplayMaxX;
+
+ if (*Y < DisplayMinY)
+ *Y = DisplayMinY;
+
+ if (DisplayMaxY < *Y)
+ *Y = DisplayMaxY;
+}
+
+void Marker_SetPoint1(int X, int Y)
+{
+ LimitXY(&X, &Y);
+ X1 = X;
+ Y1 = Y;
+ X2 = X;
+ Y2 = Y;
+}
+
+void Marker_SetPoint2(int X, int Y)
+{
+ char *T;
+
+ LimitXY(&X, &Y);
+ X2 = X;
+ Y2 = Y;
+ T = CAT("(", Marker_Get_Width(), " x ", Marker_Get_Height(), ")");
+ MainForm.lblFrameCount = T;
+}
+
+static void SortData()
+{
+ int Tmp;
+
+ XMin = (X2 < X1 ? X2 : X2);
+ YMin = (Y2 < Y1 ? Y2 : Y2);
+}
+
+void Marker_ShowMarker(boolean ShowFlag)
+{
+ mVisible = ShowFlag;
+ Marker_MoveMarker();
+}
+
+void Marker_RefreshMarker()
+{
+ int L, T, R, B;
+ long Tmp;
+
+ if (! mVisible)
+ return;
+
+ LimitXY(&X1, &Y1);
+ LimitXY(&X2, &Y2);
+ SortData();
+ L = DigitXPos(XMin) - 1;
+ T = DigitYPos(YMin) - 1;
+ R = L + StretchWidth * Marker_Get_Width() + 1;
+ B = T + StretchWidth * Marker_Get_Height() + 1;
+ MainForm.picPane.Line(L, T, R, B, 0xFFFFFF, B);
+}
+
+void Marker_MoveMarker()
+{
+ int L, T, R, B;
+ long Tmp;
+
+ if (! mVisible)
+ return;
+
+ LimitXY(&X1, &Y1);
+ LimitXY(&X2, &Y2);
+ SortData();
+ Stage.Blt();
+ Tmp = GetSI(XMin, YMin);
+ if (Marker_Get_Width() == 1 && Marker_Get_Height() == 1 && IsPort(Tmp))
+ {
+ SpLoadMenu();
+ MainForm.menSP.Enabled = True;
+ }
+ else
+ {
+ MainForm.menSP.Enabled = False;
+ }
+}
+
+static boolean IsPort(long i)
+{
+ static boolean IsPort;
+
+ int ax;
+
+ IsPort = False;
+ ax = DisPlayField[i];
+ if (fiOrangeDisk < ax && ax < fiSnikSnak)
+ IsPort = True;
+
+ return IsPort;
+}
+
+void Marker_Copy()
+{
+ int X, Y, MaxX, MaxY;
+ long Tmp;
+ char *TPath;
+ int FNum;
+
+ SortData();
+ MaxX = Marker_Get_Width() - 1;
+ MaxY = Marker_Get_Height() - 1;
+ SelectionData = REDIM_2D(sizeof(byte), 0, MaxX + 1 - 1, 0, MaxY + 1 - 1);
+ for (Y = 0; Y <= MaxY; Y++)
+ {
+ for (X = 0; X <= MaxX; X++)
+ {
+ Tmp = FieldWidth * (YMin + Y) + XMin + X;
+
+ // --- On Error GoTo CopyEH
+ SelectionData[X, Y] = DisPlayField[Tmp];
+ // --- On Error GoTo 0
+
+ }
+ }
+
+ TPath = CAT(App.Path, "/Mpx.clp");
+ if (FileExists(TPath))
+ MayKill(TPath);
+
+ FNum = FreeFile();
+
+ // --- On Error GoTo CopyEH
+ FNum = fopen(TPath, "wb");
+ FILE_PUT(FNum, -1, &MaxX, sizeof(MaxX));
+ FILE_PUT(FNum, -1, &MaxY, sizeof(MaxY));
+ FILE_PUT(FNum, -1, &SelectionData, sizeof(SelectionData));
+ fclose(FNum);
+ SelectionData = REDIM_1D(sizeof(byte), 0, 1 - 1);
+ return;
+
+CopyEH:
+ Beep();
+}
+
+void Marker_Paste()
+{
+ int X, Y, MaxX, MaxY;
+ long Tmp;
+ char *TPath;
+ int FNum;
+
+ TPath = CAT(App.Path, "/Mpx.clp");
+ if (! FileExists(TPath))
+ {
+ Beep();
+ return;
+ }
+
+ FNum = FreeFile();
+
+ // --- On Error GoTo PasteEH
+ FNum = fopen(TPath, "rb");
+ FILE_GET(FNum, -1, &MaxX, sizeof(MaxX));
+ FILE_GET(FNum, -1, &MaxY, sizeof(MaxY));
+ SelectionData = REDIM_2D(sizeof(byte), 0, MaxX + 1 - 1, 0, MaxY + 1 - 1);
+ FILE_GET(FNum, -1, &SelectionData, sizeof(SelectionData));
+ fclose(FNum);
+ // --- On Error GoTo 0
+
+ SortData();
+ if (Marker_Get_Width() <= MaxX)
+ MaxX = Marker_Get_Width() - 1;
+
+ if (Marker_Get_Height() <= MaxY)
+ MaxY = Marker_Get_Height() - 1;
+
+ for (Y = 0; Y <= MaxY; Y++)
+ {
+ for (X = 0; X <= MaxX; X++)
+ {
+ Tmp = FieldWidth * (YMin + Y) + XMin + X;
+
+ // --- On Error GoTo PasteEH
+ DisPlayField[Tmp] = SelectionData[X, Y];
+ PlayField16[Tmp] = UnEdSprite(SelectionData[X, Y]);
+ // --- On Error GoTo 0
+
+ }
+ }
+
+ Let_ModifiedFlag(True);
+PasteEH:
+ Beep();
+}
+
+static void Class_Initialize()
+{
+ mVisible = False;
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// Marker.h
+// ----------------------------------------------------------------------------
+
+#ifndef MARKER_H
+#define MARKER_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern void Marker_Copy();
+extern int Marker_Get_Height();
+extern int Marker_Get_Left();
+extern int Marker_Get_Top();
+extern int Marker_Get_Width();
+extern void Marker_MoveMarker();
+extern void Marker_Paste();
+extern void Marker_RefreshMarker();
+extern void Marker_SetPoint1(int X, int Y);
+extern void Marker_SetPoint2(int X, int Y);
+extern void Marker_ShowMarker(boolean ShowFlag);
+
+#endif /* MARKER_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// Murphy.c
+// ----------------------------------------------------------------------------
+
+#include "Murphy.h"
+
+static void subEatRedDisk(int si);
+static boolean subMoveKillsMurphy(int si, int ax, int bl);
+
+static char *VB_Name = "modMurphy";
+// --- Option Explicit
+
+#define LocalStretch (1)
+
+// ==========================================================================
+// SUBROUTINE
+// Move Murphy in any direction
+// ==========================================================================
+
+int subAnimateMurphy(int si)
+{
+ int subAnimateMurphy;
+
+ int ax, al, ah, bx, bl, i, X, Y;
+ int tX, tY, tDeltaX, tDeltaY, tPos, Tmp;
+
+ // Variables that hold information about the animation sequence
+ int *dx; // an array of image positions in moving.mpx, finalized with -1
+ int dx2; // an additional image position of a second sprite, for instance: yellow disk if pushed
+ int MurphyDX, MurphyDY; // murphys move steps
+ int SeqPos; // index into dx()
+ int ClearPos; // Position to clear before blitting sprites, none=-1
+ int dxPos; // field-position to draw dx(SeqPos)
+ int dx2Step; // position of dx2 relative to dx-position
+
+ ax = PlayField16[si];
+ al = LowByte(ax);
+ if (al != fiMurphy)
+ {
+ MurphyMoveCounter = 0; // We have no Murphy! Exit!
+ return subAnimateMurphy;
+ }
+
+ MurphyMoveCounter = 1; // We have a Murphy!
+ MurphyExplodePos = si;
+ if (ax != 3) // yes--go proceed moving murphy?
+ goto locProceedMovingMurphy;
+
+ // FS: reset moving sequence variables
+ MurphyDX = 0;
+ MurphyDY = 0;
+ ClearPos = si;
+ dxPos = si;
+ dx2 = -1;
+ SeqPos = 0;
+ // end of FS
+ ScratchGravity = 0; // scratch gravity off
+ if (GravityFlag != 0) // Gravity? (1=gravity on)
+ {
+ bl = LowByte(PlayField16[si - FieldWidth]); // check above
+ if (! (bl == fiPortUp || bl == fiPortUpAndDown || bl == fiPortAllDirections))
+ {
+ if (PlayField16[si + FieldWidth] == 0) // gravity on and space below!
+ ScratchGravity = 1;
+ }
+ } // loc_g_5E8B:
+
+ bl = DemoKeyCode;
+ if (bl != 0) // a key was pressed!
+ goto locKeyPressed5FCF;
+
+ RedDiskReleaseFlag = 1;
+ if (ScratchGravity != 0) // gravity pulls & space below?'-> force Space up to down
+ {
+ MurphyDY = 2;
+ goto loc_g_6364;
+ }
+
+ ax = (TimerVar & 3);
+ if (ax != 0)
+ return subAnimateMurphy;
+
+ // ------------------------------------------------------------------
+ // Murphy's YAWN & SLEEP sequence, counted down by YawnSleepCounter:
+ YawnSleepCounter = YawnSleepCounter + 1;
+ if (YawnSleepCounter == 4)
+ {
+ subCopyFieldToScreen(si, fiMurphy); // normal grin
+ return subAnimateMurphy;
+ } // loc_g_5ECE:
+
+ if (YawnSleepCounter <= 500) // loc_g_5ED7:
+ return subAnimateMurphy;
+
+ if (YawnSleepCounter <= 522)
+ {
+ bx = (YawnSleepCounter - 500) / 2;
+ subCopyFieldToScreen(si, aniMurphyYawn + bx); // yawn! and look depressed afterwards...
+ return subAnimateMurphy;
+ } // loc_g_5F00:
+
+ if (YawnSleepCounter <= 1000)
+ return subAnimateMurphy;
+
+ if (YawnSleepCounter <= 1022)
+ {
+ bx = (YawnSleepCounter - 1000) / 2;
+ subCopyFieldToScreen(si, aniMurphyYawn + bx); // yawn again!
+ return subAnimateMurphy;
+ } // loc_g_5F32:
+
+ if (YawnSleepCounter <= 1600) // loc_g_5F3B:
+ return subAnimateMurphy;
+
+ if (YawnSleepCounter <= 1622)
+ {
+ bx = (YawnSleepCounter - 1600) / 2;
+ subCopyFieldToScreen(si, aniMurphyYawn + bx); // yawn again! - third time
+ return subAnimateMurphy;
+ } // loc_g_5F64:
+
+ if (YawnSleepCounter > 1654)
+ return subAnimateMurphy;
+
+ if (PlayField16[si - 1] == 0)
+ {
+ if (PlayField16[si + 1] == 0)
+ {
+ YawnSleepCounter = 36;
+ return subAnimateMurphy;
+
+ }
+ else
+ {
+ bx = (YawnSleepCounter - 1622) / 16;
+ subCopyFieldToScreen(si, aniMurphySleepRight + bx); // go to sleep
+ return subAnimateMurphy;
+ }
+ } // loc_g_5F81:
+
+ bx = (YawnSleepCounter - 1622) / 16;
+ subCopyFieldToScreen(si, aniMurphySleepLeft + bx); // go to sleep
+ return subAnimateMurphy;
+
+ // end of YAWN-SLEEP-Sequence
+ // ------------------------------------------------------------------
+ // ==========================================================================
+ // (Direct Jump) a key was pressed
+ // ==========================================================================
+
+locKeyPressed5FCF:
+ if (ScratchGravity == 0)
+ goto loc_g_6003;
+
+ if (PlayField16[si + FieldWidth] != 0)
+ goto loc_g_6003;
+
+ if (bl == keyUp)
+ {
+ if (PlayField16[si - FieldWidth] == fiBase)
+ goto loc_g_6003;
+
+ }
+ else if (bl == keyLeft)
+ {
+ if (PlayField16[si - 1] == fiBase)
+ goto loc_g_6003;
+
+ }
+ else if (bl == keyRight)
+ {
+ if (PlayField16[si + 1] == fiBase)
+ goto loc_g_6003;
+ } // loc_g_6001:
+
+ bl = keyDown; // force moving down!
+loc_g_6003:
+ switch (bl)
+ {
+ case keyUp: // 1
+ RedDiskReleaseFlag = 0; // moving down to up ...
+ goto loc_g_6078;
+
+ break;
+
+ case keyLeft: // 2
+ RedDiskReleaseFlag = 0; // moving right to left ...
+ goto loc_g_60DA;
+
+ break;
+
+ case keyDown: // 3
+ RedDiskReleaseFlag = 0; // moving up to down ...
+ goto loc_g_6154;
+
+ break;
+
+ case keyRight: // 4
+ RedDiskReleaseFlag = 0; // moving left to right ...
+ goto loc_g_61B6;
+
+ break;
+
+ case keySpaceUp: // 5
+ RedDiskReleaseFlag = 0; // touching down to up ...
+ goto loc_g_622E;
+
+ break;
+
+ case keySpaceLeft: // 6
+ RedDiskReleaseFlag = 0; // touching right to left ...
+ goto loc_g_6258;
+
+ break;
+
+ case keySpaceDown: // 7
+ RedDiskReleaseFlag = 0; // touching up to down ...
+ goto loc_g_6288;
+
+ break;
+
+ case keySpaceRight: // 8
+ RedDiskReleaseFlag = 0; // touching left to right ...
+ goto loc_g_62B2;
+
+ break;
+
+ case keySpace: // 9
+ goto loc_g_62E2; // no move ...
+
+ break;
+
+ default:
+ RedDiskReleaseFlag = 0;
+ return subAnimateMurphy;
+ break;
+ }
+
+ // ==========================================================================
+ // moving down to up ...
+ // ==========================================================================
+
+loc_g_6078:
+ // FS:
+ MurphyDY = -2;
+ // end of FS
+ ax = PlayField16[si - FieldWidth];
+ al = LowByte(ax);
+ if (ax == fiSpace)
+ goto loc_g_6312;
+
+ if (ax == fiBase)
+ goto loc_g_63D3;
+
+ if (al == fiBug)
+ goto loc_g_63C2;
+
+ if (ax == fiInfotron)
+ goto loc_g_65C6;
+
+ if (ax == fiExit)
+ goto loc_g_6756;
+
+ if (al == fiTerminal)
+ goto loc_g_6817;
+
+ if (al == fiPortUp || al == fiPortUpAndDown || al == fiPortAllDirections)
+ goto loc_g_6916;
+
+ if (al == fiRedDisk)
+ goto loc_g_69A6;
+
+ if (al == fiYellowDisk)
+ goto loc_g_6AB8;
+
+ if (! subMoveKillsMurphy(si - FieldWidth, ax, bl))
+ goto loc_g_6078;
+
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // moving right to left ...
+ // ==========================================================================
+
+loc_g_60DA:
+ // FS:
+ MurphyDX = -2;
+ // end of FS
+ MurphyVarFaceLeft = 1;
+ ax = PlayField16[si - 1];
+ al = LowByte(ax);
+ if (ax == fiSpace)
+ goto loc_g_6341;
+
+ if (ax == fiBase)
+ goto loc_g_641C;
+
+ if (al == fiBug)
+ goto loc_g_640B;
+
+ if (ax == fiInfotron)
+ goto loc_g_65FE;
+
+ if (ax == fiExit)
+ goto loc_g_6756;
+
+ if (ax == fiZonk)
+ goto loc_g_679B;
+
+ if (al == fiTerminal)
+ goto loc_g_684E;
+
+ if (al == fiPortLeft || al == fiPortLeftAndRight || al == fiPortAllDirections)
+ goto loc_g_693A;
+
+ if (ax == fiRedDisk)
+ goto loc_g_69CE;
+
+ if (ax == fiYellowDisk)
+ goto loc_g_6AF1;
+
+ if (ax == fiOrangeDisk)
+ goto loc_g_6B9B;
+
+ if (! subMoveKillsMurphy(si - 1, ax, bl))
+ goto loc_g_60DA;
+
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // moving up to down ...
+ // ==========================================================================
+
+loc_g_6154:
+ // FS:
+ MurphyDY = 2;
+ // end of FS
+ ax = PlayField16[si + FieldWidth];
+ al = LowByte(ax);
+ if (ax == fiSpace)
+ goto loc_g_6364;
+
+ if (ax == fiBase)
+ goto loc_g_6459;
+
+ if (al == fiBug)
+ goto loc_g_6448;
+
+ if (ax == fiInfotron)
+ goto loc_g_662A;
+
+ if (ax == fiExit)
+ goto loc_g_6756;
+
+ if (al == fiTerminal)
+ goto loc_g_6884;
+
+ if (al == fiPortDown || al == fiPortUpAndDown || al == fiPortAllDirections)
+ goto loc_g_695E;
+
+ if (al == fiRedDisk)
+ goto loc_g_69F7;
+
+ if (al == fiYellowDisk)
+ goto loc_g_6B2A;
+
+ if (! subMoveKillsMurphy(si + FieldWidth, ax, bl))
+ goto loc_g_6154;
+
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // moving left to right ...
+ // ==========================================================================
+
+loc_g_61B6:
+ // FS:
+ MurphyDX = 2;
+ // end of FS
+ MurphyVarFaceLeft = 0;
+ ax = PlayField16[si + 1];
+ al = LowByte(ax);
+ if (ax == fiSpace)
+ goto loc_g_6399;
+
+ if (ax == fiBase)
+ goto loc_g_64A2;
+
+ if (al == fiBug)
+ goto loc_g_6491;
+
+ if (ax == fiInfotron)
+ goto loc_g_6662;
+
+ if (ax == fiExit)
+ goto loc_g_6756;
+
+ if (ax == fiZonk)
+ goto loc_g_67D4;
+
+ if (al == fiTerminal)
+ goto loc_g_68BA;
+
+ if (al == fiPortRight || al == fiPortLeftAndRight || al == fiPortAllDirections)
+ goto loc_g_6982;
+
+ if (al == fiRedDisk)
+ goto loc_g_6A1F;
+
+ if (al == fiYellowDisk)
+ goto loc_g_6B63;
+
+ if (ax == fiOrangeDisk)
+ goto loc_g_6BD3;
+
+ if (! subMoveKillsMurphy(si + 1, ax, bl))
+ goto loc_g_61B6;
+
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // touching down to up ...
+ // ==========================================================================
+
+loc_g_622E:
+ // FS:
+ ClearPos = -1;
+ dxPos = si - FieldWidth;
+ // end of FS
+ ax = PlayField16[si - FieldWidth];
+ al = LowByte(ax);
+ al = LowByte(ax);
+ if (ax == fiBase)
+ goto loc_g_64DF;
+
+ if (al == fiBug)
+ goto loc_g_64CE;
+
+ if (ax == fiInfotron)
+ goto loc_g_668E;
+
+ if (al == fiTerminal)
+ goto loc_g_6817;
+
+ if (al == fiRedDisk)
+ goto loc_g_6A48;
+
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // touching right to left ...
+ // ==========================================================================
+
+loc_g_6258:
+ // FS:
+ ClearPos = -1;
+ dxPos = si - 1;
+ // end of FS
+ MurphyVarFaceLeft = 1;
+ ax = PlayField16[si - 1];
+ al = LowByte(ax);
+ if (ax == fiBase)
+ goto loc_g_651D;
+
+ if (al == fiBug)
+ goto loc_g_650C;
+
+ if (ax == fiInfotron)
+ goto loc_g_66C0;
+
+ if (al == fiTerminal)
+ goto loc_g_684E;
+
+ if (al == fiRedDisk)
+ goto loc_g_6A64;
+
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // touching up to down ...
+ // ==========================================================================
+
+loc_g_6288:
+ // FS:
+ ClearPos = -1;
+ dxPos = si + FieldWidth;
+ // end of FS
+ ax = PlayField16[si + FieldWidth];
+ al = LowByte(ax);
+ if (ax == fiBase)
+ goto loc_g_655B;
+
+ if (al == fiBug)
+ goto loc_g_654A;
+
+ if (ax == fiInfotron)
+ goto loc_g_66F2;
+
+ if (al == fiTerminal)
+ goto loc_g_6884;
+
+ if (al == fiRedDisk)
+ goto loc_g_6A80;
+
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // touching left to right ...
+ // ==========================================================================
+
+loc_g_62B2:
+ // FS:
+ ClearPos = -1;
+ dxPos = si + 1;
+ // end of FS
+ MurphyVarFaceLeft = 0;
+ ax = PlayField16[si + 1];
+ al = LowByte(ax);
+ if (ax == fiBase)
+ goto loc_g_6599;
+
+ if (al == fiBug)
+ goto loc_g_6588;
+
+ if (ax == fiInfotron)
+ goto loc_g_6724;
+
+ if (al == fiTerminal)
+ goto loc_g_68BA;
+
+ if (al == fiRedDisk)
+ goto loc_g_6A9C;
+
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Release Red disk: no move ...
+ // ==========================================================================
+
+loc_g_62E2:
+ // FS:
+ ClearPos = -1;
+ // end of FS
+ if (LowByte(RedDiskCount) == 0)
+ return subAnimateMurphy;
+
+ if (LowByte(RedDiskReleasePhase) != 0)
+ return subAnimateMurphy;
+
+ if (LowByte(RedDiskReleaseFlag) != 1)
+ return subAnimateMurphy;
+
+ MovHighByte(&PlayField16[si], 0x2A);
+ MovingPictureSequencePhase = 0x40; // init picture move sequence
+ dx = aniRedDisk;
+ MovLowByte(&RedDiskReleasePhase, 1);
+ Mov(&RedDiskReleaseMurphyPos, si); // remember Murphy's location
+ goto loc_Split;
+
+ // ==========================================================================
+ // SPACE moving down to up
+ // ==========================================================================
+
+loc_g_6312:
+ dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
+ PlayField16[si - FieldWidth] = 0x103;
+ PlayField16[si] = 0x300;
+ si = si - FieldWidth;
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // SPACE moving right to left
+ // ==========================================================================
+
+loc_g_6341:
+ dx = aniMurphyEatLeft;
+ PlayField16[si - 1] = 0x203;
+ PlayField16[si] = 0x300;
+ si = si - 1;
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // SPACE moving up to down, and when gravity is pulling!
+ // ==========================================================================
+
+loc_g_6364:
+ dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
+ PlayField16[si + FieldWidth] = 0x303;
+ PlayField16[si] = 0x300;
+ si = si + FieldWidth;
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // SPACE moving left to right
+ // ==========================================================================
+
+loc_g_6399:
+ dx = aniMurphyEatRight;
+ PlayField16[si + 1] = 0x403;
+ PlayField16[si] = 0x300;
+ si = si + 1;
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // BUG moving down to up
+ // ==========================================================================
+
+loc_g_63C2:
+ if (SgnHighByte(PlayField16[si - FieldWidth]) >= 0)
+ {
+ ExplodeFieldSP(si); // Explode
+ return subAnimateMurphy;
+ }
+
+ PlayField16[si - FieldWidth] = fiBase;
+ // ==========================================================================
+ // BASE moving down to up
+ // ==========================================================================
+
+loc_g_63D3:
+ subSoundFXBase();
+ dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
+ PlayField16[si - FieldWidth] = 0x503;
+ PlayField16[si] = 0x300;
+ si = si - FieldWidth;
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // BUG moving right to left
+ // ==========================================================================
+
+loc_g_640B:
+ if (SgnHighByte(PlayField16[si - 1]) >= 0)
+ {
+ ExplodeFieldSP(si); // Explode
+ return subAnimateMurphy;
+ }
+
+ PlayField16[si - 1] = fiBase;
+ // ==========================================================================
+ // BASE moving right to left
+ // ==========================================================================
+
+loc_g_641C:
+ subSoundFXBase();
+ dx = aniMurphyEatLeft;
+ PlayField16[si - 1] = 0x203;
+ PlayField16[si] = 0x300;
+ si = si - 1;
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // BUG moving up to down
+ // ==========================================================================
+
+loc_g_6448:
+ if (SgnHighByte(PlayField16[si + FieldWidth]) >= 0)
+ {
+ ExplodeFieldSP(si); // Explode
+ return subAnimateMurphy;
+ }
+
+ PlayField16[si + FieldWidth] = fiBase;
+ // ==========================================================================
+ // BASE moving up to down
+ // ==========================================================================
+
+loc_g_6459:
+ subSoundFXBase();
+ dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
+ PlayField16[si + FieldWidth] = 0x703;
+ PlayField16[si] = 0x300;
+ si = si + FieldWidth;
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // BUG moving left to right
+ // ==========================================================================
+
+loc_g_6491:
+ if (SgnHighByte(PlayField16[si + 1]) >= 0)
+ {
+ ExplodeFieldSP(si); // Explode
+ return subAnimateMurphy;
+ }
+
+ PlayField16[si + 1] = fiBase;
+ // ==========================================================================
+ // BASE moving left to right
+ // ==========================================================================
+
+loc_g_64A2:
+ subSoundFXBase();
+ dx = aniMurphyEatRight;
+ PlayField16[si + 1] = 0x803;
+ PlayField16[si] = 0x300;
+ si = si + 1;
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // BUG touching down to up
+ // ==========================================================================
+
+loc_g_64CE:
+ if (SgnHighByte(PlayField16[si - FieldWidth]) >= 0)
+ {
+ ExplodeFieldSP(si); // Explode
+ return subAnimateMurphy;
+ }
+
+ PlayField16[si - FieldWidth] = fiBase;
+ // ==========================================================================
+ // BASE touching down to up
+ // ==========================================================================
+
+loc_g_64DF:
+ subCopyFieldToScreen(si, aniMurphyTouchUp);
+ subSoundFXBase();
+ dx = aniTouchBase;
+ dxPos = si - FieldWidth;
+ MovHighByte(&PlayField16[si], 0x10);
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // BUG touching right to left
+ // ==========================================================================
+
+loc_g_650C:
+ if (SgnHighByte(PlayField16[si - 1]) >= 0)
+ {
+ ExplodeFieldSP(si); // Explode
+ return subAnimateMurphy;
+ }
+
+ PlayField16[si - 1] = fiBase;
+ // ==========================================================================
+ // BASE touching right to left
+ // ==========================================================================
+
+loc_g_651D:
+ subCopyFieldToScreen(si, aniMurphyTouchLeft);
+ subSoundFXBase();
+ dx = aniTouchBase;
+ dxPos = si - 1;
+ MovHighByte(&PlayField16[si], 0x11);
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // BUG touching up to down
+ // ==========================================================================
+
+loc_g_654A:
+ if (SgnHighByte(PlayField16[si + FieldWidth]) >= 0)
+ {
+ ExplodeFieldSP(si); // Explode
+ return subAnimateMurphy;
+ }
+
+ PlayField16[si + FieldWidth] = fiBase;
+ // ==========================================================================
+ // BASE touching up to down
+ // ==========================================================================
+
+loc_g_655B:
+ subCopyFieldToScreen(si, aniMurphyTouchDown);
+ subSoundFXBase();
+ dx = aniTouchBase;
+ dxPos = si + FieldWidth;
+ MovHighByte(&PlayField16[si], 0x12);
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // BUG touching left to right
+ // ==========================================================================
+
+loc_g_6588:
+ if (SgnHighByte(PlayField16[si + 1]) >= 0)
+ {
+ ExplodeFieldSP(si); // Explode
+ return subAnimateMurphy;
+ }
+
+ PlayField16[si + 1] = fiBase;
+ // ==========================================================================
+ // BASE touching left to right
+ // ==========================================================================
+
+loc_g_6599:
+ subCopyFieldToScreen(si, aniMurphyTouchRight);
+ subSoundFXBase();
+ dx = aniTouchBase;
+ dxPos = si + 1;
+ MovHighByte(&PlayField16[si], 0x13);
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // INFOTRON moving down to up
+ // ==========================================================================
+
+loc_g_65C6:
+ subSoundFXInfotron();
+ dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
+ PlayField16[si - FieldWidth] = 0x903;
+ PlayField16[si] = 0x300;
+ si = si - FieldWidth;
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // INFOTRON moving right to left
+ // ==========================================================================
+
+loc_g_65FE:
+ subSoundFXInfotron();
+ dx = aniEatInfotronLeft;
+ dx2 = fiInfotron;
+ dx2Step = -1;
+ ClearPos = -1;
+ PlayField16[si - 1] = 0xA03;
+ PlayField16[si] = 0x300;
+ si = si - 1;
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // INFOTRON moving up to down
+ // ==========================================================================
+
+loc_g_662A:
+ subSoundFXInfotron();
+ dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
+ PlayField16[si + FieldWidth] = 0xB03;
+ PlayField16[si] = 0x300;
+ si = si + FieldWidth;
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // INFOTRON moving left to right
+ // ==========================================================================
+
+loc_g_6662:
+ subSoundFXInfotron();
+ dx = aniEatInfotronRight;
+ dx2 = fiInfotron;
+ dx2Step = 1;
+ ClearPos = -1;
+ PlayField16[si + 1] = 0xC03;
+ PlayField16[si] = 0x300;
+ si = si + 1;
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // INFOTRON touching down to up
+ // ==========================================================================
+
+loc_g_668E:
+ subCopyFieldToScreen(si, aniMurphyTouchUp);
+ subSoundFXInfotron();
+ dx = aniTouchInfotron;
+ MovHighByte(&PlayField16[si], 0x14);
+ MovHighByte(&PlayField16[si - FieldWidth], 0xFF);
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // INFOTRON touching right to left
+ // ==========================================================================
+
+loc_g_66C0:
+ subCopyFieldToScreen(si, aniMurphyTouchLeft);
+ subSoundFXInfotron();
+ dx = aniTouchInfotron;
+ MovHighByte(&PlayField16[si], 0x15);
+ MovHighByte(&PlayField16[si - 1], 0xFF);
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // INFOTRON touching up to down
+ // ==========================================================================
+
+loc_g_66F2:
+ subCopyFieldToScreen(si, aniMurphyTouchDown);
+ subSoundFXInfotron();
+ dx = aniTouchInfotron;
+ MovHighByte(&PlayField16[si], 0x16);
+ MovHighByte(&PlayField16[si + FieldWidth], 0xFF);
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // INFOTRON touching left to right
+ // ==========================================================================
+
+loc_g_6724:
+ subCopyFieldToScreen(si, aniMurphyTouchRight);
+ subSoundFXInfotron();
+ dx = aniTouchInfotron;
+ MovHighByte(&PlayField16[si], 0x17);
+ MovHighByte(&PlayField16[si + 1], 0xFF);
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // EXIT pressed from any direction
+ // ==========================================================================
+
+loc_g_6756:
+ // FS
+ ClearPos = -1;
+ MurphyDX = 0;
+ MurphyDY = 0;
+ // end of FS
+ if (LowByte(InfotronsNeeded) != 0)
+ return subAnimateMurphy;
+
+ subSoundFXExit();
+ data_h_DemoDone = 1; // EP set level success bytes
+ LevelStatus = 1; // set Level Status DONE
+ EP_GameDemoVar0DAA = 0; // force demo for lead-out
+ if (SavedGameFlag == 0) // saved game running?
+ {
+ if (UpdateTimeFlag != 0) // update time?
+ {
+ UpdatedFlag = 1; // prevent double update
+ subUpdatePlayingTime(); // update playing time
+ }
+ }
+
+#if 0
+ subUpdateHallOfFame(); // update time + Hall-Of-Fame
+#endif
+
+ LeadOutCounter = 0x40; // quit: start lead-out
+ dx = aniMurphyExit;
+ MovHighByte(&PlayField16[si], 0xD);
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // ZONK moving right to left
+ // ==========================================================================
+
+loc_g_679B:
+ ax = PlayField16[si - 2];
+ if (ax != 0)
+ return subAnimateMurphy;
+
+ MovHighByte(&PlayField16[si - 2], 1);
+ subCopyFieldToScreen(si, aniPushLeft); // draw pushing murphy
+ dx = aniZonkRollLeft;
+ dxPos = si - 1;
+ dx2 = aniPushLeft;
+ dx2Step = 1;
+ MovHighByte(&PlayField16[si], 0xE);
+ goto loc_MoveNoSplit;
+
+ // ==========================================================================
+ // ZONK moving left to right
+ // ==========================================================================
+
+loc_g_67D4:
+ ax = PlayField16[si + 2];
+ if (ax != 0)
+ return subAnimateMurphy;
+
+ ax = PlayField16[si + FieldWidth + 1];
+ if (ax == 0) // zonk falls
+ return subAnimateMurphy;
+
+ MovHighByte(&PlayField16[si + 2], 1);
+ subCopyFieldToScreen(si, aniPushRight); // draw pushing murphy
+ dx = aniZonkRollRight;
+ dxPos = si + 1;
+ dx2 = aniPushRight;
+ dx2Step = -1;
+ MovHighByte(&PlayField16[si], 0xF);
+ goto loc_MoveNoSplit;
+
+ // ==========================================================================
+ // TERMINAL moving/touching down to up
+ // ==========================================================================
+
+loc_g_6817:
+ subCopyFieldToScreen(si, aniMurphyTouchUp);
+ if (YellowDisksExploded != 0)
+ {
+ YawnSleepCounter = 10; // stay hypnotized
+ return subAnimateMurphy;
+ } // loc_g_6838:
+
+ subCopyFieldToScreen(si - FieldWidth, 0x88); // draw new terminal type
+ TerminalState[si - FieldWidth] = 8;
+ goto loc_g_68F0;
+
+ // ==========================================================================
+ // TERMINAL moving/touching right to left
+ // ==========================================================================
+
+loc_g_684E:
+ subCopyFieldToScreen(si, aniMurphyTouchLeft);
+ if (YellowDisksExploded != 0)
+ {
+ YawnSleepCounter = 10; // stay hypnotized
+ return subAnimateMurphy;
+ } // loc_g_6838:
+
+ subCopyFieldToScreen(si - 1, 0x88); // draw new terminal type
+ TerminalState[si - 1] = 8;
+ goto loc_g_68F0;
+
+ // ==========================================================================
+ // TERMINAL moving/touching up to down
+ // ==========================================================================
+
+loc_g_6884:
+ subCopyFieldToScreen(si, aniMurphyTouchDown);
+ if (YellowDisksExploded != 0)
+ {
+ YawnSleepCounter = 10; // stay hypnotized
+ return subAnimateMurphy;
+ } // loc_g_6838:
+
+ subCopyFieldToScreen(si + FieldWidth, 0x88); // draw new terminal type
+ TerminalState[si + FieldWidth] = 8;
+ goto loc_g_68F0;
+
+ // ==========================================================================
+ // TERMINAL moving/touching left to right
+ // ==========================================================================
+
+loc_g_68BA:
+ subCopyFieldToScreen(si, aniMurphyTouchRight);
+ if (YellowDisksExploded != 0)
+ {
+ YawnSleepCounter = 10; // stay hypnotized
+ return subAnimateMurphy;
+ } // loc_g_6838:
+
+ subCopyFieldToScreen(si + 1, 0x88); // draw new terminal type
+ TerminalState[si + 1] = 8;
+ // ==========================================================================
+ // common TERMINAL stuff moving/touching from all directions
+ // ==========================================================================
+
+loc_g_68F0:
+ TerminalMaxCycles = 7;
+ YellowDisksExploded = 1;
+ for (i = 0; i <= LevelMax; i++)
+ {
+ if (PlayField16[i] == fiYellowDisk)
+ ExplodeFieldSP (i);
+ }
+
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // PORT down to up, VERTICAL PORT, CROSS PORT all moving down to up
+ // ==========================================================================
+
+loc_g_6916:
+ if (PlayField16[si - 2 * FieldWidth] != 0)
+ return subAnimateMurphy;
+
+ dx = aniSplitUpDown;
+ dx2Step = -FieldWidth;
+ PlayField16[si] = 0x1803;
+ PlayField16[si - 2 * FieldWidth] = 0x300;
+ goto loc_StopSplit;
+
+ // ==========================================================================
+ // PORT right to left, HORIZONTAL PORT, CROSS PORT all moving right to left
+ // ==========================================================================
+
+loc_g_693A:
+ if (PlayField16[si - 2] != 0)
+ return subAnimateMurphy;
+
+ dx = aniMurphyEatLeft;
+ dx2Step = -1;
+ PlayField16[si] = 0x1903;
+ PlayField16[si - 2] = 0x300;
+ goto loc_StopSplit;
+
+ // ==========================================================================
+ // PORT up to down, VERTICAL PORT, CROSS PORT all moving up to down
+ // ==========================================================================
+
+loc_g_695E:
+ if (PlayField16[si + 2 * FieldWidth] != 0)
+ return subAnimateMurphy;
+
+ dx = aniSplitUpDown;
+ dx2Step = FieldWidth;
+ PlayField16[si] = 0x1A03;
+ PlayField16[si + 2 * FieldWidth] = 0x300;
+ goto loc_StopSplit;
+
+ // ==========================================================================
+ // PORT left to right, HORIZONTAL PORT, CROSS PORT all moving left to right
+ // ==========================================================================
+
+loc_g_6982:
+ if (PlayField16[si + 2] != 0)
+ return subAnimateMurphy;
+
+ dx = aniMurphyEatRight;
+ dx2Step = 1;
+ PlayField16[si] = 0x1B03;
+ PlayField16[si + 2] = 0x300;
+
+loc_StopSplit:
+ MovingPictureSequencePhase = 0; // stop picture move sequence
+ SplitMoveFlag = 1; // port: split movement
+ goto loc_Split;
+
+ // ==========================================================================
+ // RED DISK moving down to up
+ // ==========================================================================
+
+loc_g_69A6:
+ dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
+ PlayField16[si] = 0x1C03;
+ PlayField16[si - FieldWidth] = 0x300;
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // RED DISK moving right to left
+ // ==========================================================================
+
+loc_g_69CE:
+ dx = aniMurphyEatLeft;
+ PlayField16[si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
+ PlayField16[si - 1] = 0x1D03;
+ si = si - 1;
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // RED DISK moving up to down
+ // ==========================================================================
+
+loc_g_69F7:
+ dx = (MurphyVarFaceLeft == 0 ? aniMurphyEatUpRight : aniMurphyEatUpRight);
+ PlayField16[si] = 0x1E03;
+ PlayField16[si + FieldWidth] = 0x300;
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // RED DISK moving left to right
+ // ==========================================================================
+
+loc_g_6A1F:
+ // dx = aniMurphyEatRightRedDisk 'this sequence is 9 steps long!
+ dx = aniMurphyEatRight;
+ // --------------------------------------------------------------------------
+ // BugFix
+ // Table data_h_145A, pointed to by table data_h_105E, has a severe bug:
+ // The Red Disk sequence is 8 pictures long, but 9 are displayed, because it
+ // has 1 extra entry, which causes Murphy to end slightly shifted to the left!
+ // We may not fix the table, because then the timing of the game changes
+ // and several existing demo's do not run properly anymore.
+ // We only correct Murphies x-location here, when the sequence starts.
+ // Remember that this is not the real bug-fix, but we must live with
+ // this existing bug and correct for the consequences of it.
+ if (0 == AllowEatRightRedDiskBug) // Murphy's screen x-position
+ MurphyScreenXPos = MurphyScreenXPos - 2;
+
+ SeqPos = -1;
+ // FS: for me this means to blit the first animation frame twice
+ // end of BugFix
+ // --------------------------------------------------------------------------
+ PlayField16[si] = 0x300; // !!!!!! this time we move murphy at sequence-start!
+ PlayField16[si + 1] = 0x1F03;
+ si = si + 1;
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // RED DISK touching down to up
+ // ==========================================================================
+
+loc_g_6A48:
+ dx = aniTouchRedDisk;
+ MovHighByte(&PlayField16[si], 0x20);
+ MovHighByte(&PlayField16[si - FieldWidth], 3);
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // RED DISK touching right to left
+ // ==========================================================================
+
+loc_g_6A64:
+ dx = aniTouchRedDisk;
+ MovHighByte(&PlayField16[si], 0x21);
+ MovHighByte(&PlayField16[si - 1], 3);
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // RED DISK touching up to down
+ // ==========================================================================
+
+loc_g_6A80:
+ dx = aniTouchRedDisk;
+ MovHighByte(&PlayField16[si], 0x22);
+ MovHighByte(&PlayField16[si + FieldWidth], 3);
+ goto loc_StopNoSplit;
+
+ // ==========================================================================
+ // RED DISK touching left to right
+ // ==========================================================================
+
+loc_g_6A9C:
+ dx = aniTouchRedDisk;
+ MovHighByte(&PlayField16[si], 0x23);
+ MovHighByte(&PlayField16[si + 1], 3);
+
+loc_StopNoSplit:
+ MovingPictureSequencePhase = 0; // stop picture move sequence
+ goto loc_NoSplit;
+
+ // ==========================================================================
+ // YELLOW DISK moving down to up
+ // ==========================================================================
+
+loc_g_6AB8:
+ if (PlayField16[si - 2 * FieldWidth] != 0)
+ return subAnimateMurphy;
+
+ PlayField16[si - 2 * FieldWidth] = 0x1200;
+ subCopyFieldToScreen(si, aniPushRight);
+ dx = aniYellowDisk;
+ dxPos = si - FieldWidth;
+ dx2 = aniPushUpDown;
+ dx2Step = FieldWidth;
+ PlayField16[si] = 0x2403;
+ goto loc_MoveNoSplit;
+
+ // ==========================================================================
+ // YELLOW DISK moving right to left
+ // ==========================================================================
+
+loc_g_6AF1:
+ if (PlayField16[si - 2] != 0)
+ return subAnimateMurphy;
+
+ PlayField16[si - 2] = 0x1200;
+ subCopyFieldToScreen(si, aniPushLeft);
+ dx = aniYellowDisk;
+ dxPos = si - 1;
+ dx2 = aniPushLeft;
+ dx2Step = 1;
+ PlayField16[si] = 0x2503;
+ goto loc_MoveNoSplit;
+
+ // ==========================================================================
+ // YELLOW DISK moving up to down
+ // ==========================================================================
+
+loc_g_6B2A:
+ if (PlayField16[si + 2 * FieldWidth] != 0)
+ return subAnimateMurphy;
+
+ PlayField16[si + 2 * FieldWidth] = 0x1200;
+ subCopyFieldToScreen(si, aniPushRight);
+ dx = aniYellowDisk;
+ dxPos = si + FieldWidth;
+ dx2 = aniPushUpDown;
+ dx2Step = -FieldWidth;
+ PlayField16[si] = 0x2703;
+ goto loc_MoveNoSplit;
+
+ // ==========================================================================
+ // YELLOW DISK moving left to right
+ // ==========================================================================
+
+loc_g_6B63:
+ if (PlayField16[si + 2] != 0)
+ return subAnimateMurphy;
+
+ PlayField16[si + 2] = 0x1200;
+ subCopyFieldToScreen(si, aniPushRight);
+ dx = aniYellowDisk;
+ dxPos = si + 1;
+ dx2 = aniPushRight;
+ dx2Step = -1;
+ PlayField16[si] = 0x2603;
+ goto loc_MoveNoSplit;
+
+ // ==========================================================================
+ // ORANGE DISK moving right to left
+ // ==========================================================================
+
+loc_g_6B9B:
+ if (PlayField16[si - 2] != 0)
+ return subAnimateMurphy;
+
+ PlayField16[si - 2] = 0x800;
+ subCopyFieldToScreen(si, aniPushLeft);
+ dx = aniOrangeDisk;
+ dxPos = si - 1;
+ dx2 = aniPushLeft;
+ dx2Step = 1;
+ PlayField16[si] = 0x2803;
+ goto loc_MoveNoSplit;
+
+ // ==========================================================================
+ // ORANGE DISK moving left to right
+ // ==========================================================================
+
+loc_g_6BD3:
+ if (PlayField16[si + 2] != 0)
+ return subAnimateMurphy;
+
+ if (PlayField16[si + FieldWidth + 1] == 0) // falling goes before pushing
+ return subAnimateMurphy;
+
+ PlayField16[si + 2] = 0x100;
+ subCopyFieldToScreen(si, aniPushRight);
+ dx = aniOrangeDisk;
+ dxPos = si + 1;
+ dx2 = aniPushRight;
+ dx2Step = -1;
+ PlayField16[si] = 0x2903;
+ // ==========================================================================
+ // Copy screen animation action table to action work space
+ // (To paint sequence: Push Zonk/Disk / release red disk / Port passing)
+ // ==========================================================================
+
+loc_MoveNoSplit:
+ MovingPictureSequencePhase = 8; // init picture move sequence
+
+loc_NoSplit:
+ SplitMoveFlag = 0; // no port: no split movement
+
+loc_Split:
+ // copy/store global move sequence info????????????????????????????????????
+ // ... dont think so ...(FS)
+ // ==========================================================================
+ // Proceed with all movements
+ // ==========================================================================
+
+locProceedMovingMurphy: // proceed moving murphy
+ YawnSleepCounter = 0; // Wake up sleeping Murphy
+ ax = MovingPictureSequencePhase; // sequence busy?
+ if (ax == 0) // no -- start sequence!
+ goto loc_g_6C8F;
+
+ ax = ax - 1; // next picture of sequence
+ MovingPictureSequencePhase = ax; // store for later
+ if (ax == 0) // Sound effects
+ subSoundFXPush();
+
+ bl = HighByte(PlayField16[si]);
+ if (bl == 0xE) // Push Zonk to left
+ goto loc_g_6F7E;
+
+ if (bl == 0xF) // Push Zonk to right
+ goto loc_g_6FBC;
+
+ if (bl == 0x28) // Push orange disk to left
+ goto loc_g_6FFA;
+
+ if (bl == 0x29) // Push orange disk to right
+ goto loc_g_7038;
+
+ if (bl == 0x24) // Push yellow disk up
+ goto loc_g_7076;
+
+ if (bl == 0x25) // Push yellow disk to left
+ goto loc_g_70B4;
+
+ if (bl == 0x27) // Push yellow disk down
+ goto loc_g_70F2;
+
+ if (bl == 0x26) // Push yellow disk to right
+ goto loc_g_7130;
+
+ if (bl == 0x2A) // Red disk release timer
+ goto loc_g_716E;
+
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Paint frame of MOVING.DAT sequence
+ // ==========================================================================
+
+loc_g_6C8F:
+ if (SplitMoveFlag == 0)
+ {
+ // ++++++++++++++++++++++++++
+ // Begin of normal movement
+ MurphyScreenXPos = MurphyScreenXPos + MurphyDX;
+ MurphyScreenYPos = MurphyScreenYPos + MurphyDY;
+ if (! ClearPos < 0) // clear field that murphy is leaving
+ subCopyFieldToScreen(ClearPos, 0);
+
+ if (dx2 == fiInfotron) // special case of infotron moving left or right
+ {
+ tDeltaX = 0;
+ tDeltaY = 0;
+ }
+ else
+ {
+ tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
+ tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
+ }
+
+ X = GetStretchX(dxPos) + tDeltaX;
+ Y = GetStretchY(dxPos) + tDeltaY;
+ Tmp = (SeqPos < 0 ? 0 : 0); // 9StepBugFix!(red disk move right)
+ StretchedSprites.BltEx(X, Y, dx[Tmp]);
+ if (! dx2 < 0)
+ {
+ tPos = dxPos + dx2Step;
+ X = GetStretchX(tPos);
+ Y = GetStretchY(tPos);
+ if (dx2 == fiInfotron) // special case of infotron moving left or right
+ {
+ StretchedSprites.BltEx(X, Y, dx[SeqPos] + dx2Step);
+ }
+ else // pushing something
+ {
+ StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx2);
+ }
+ }
+
+ // End of normal movement
+ // ------------------------
+ }
+ else
+ {
+ // ++++++++++++++++++++++++++++++++
+ // Begin of split movement (port)
+ MurphyScreenXPos = MurphyScreenXPos + 2 * MurphyDX;
+ MurphyScreenYPos = MurphyScreenYPos + 2 * MurphyDY;
+ subCopyFieldToScreen(ClearPos, 0); // clear the field that murphy leaves
+ tDeltaX = MurphyDX * LocalStretch * (SeqPos + 1);
+ tDeltaY = MurphyDY * LocalStretch * (SeqPos + 1);
+ X = GetStretchX(dxPos) + tDeltaX;
+ Y = GetStretchY(dxPos) + tDeltaY;
+ StretchedSprites.BltEx(X, Y, dx[SeqPos]); // plot first murphy
+ tPos = dxPos + dx2Step;
+ X = GetStretchX(tPos);
+ Y = GetStretchY(tPos);
+ StretchedSprites.BltEx(X + tDeltaX, Y + tDeltaY, dx[SeqPos]); // plot second murphy
+ StretchedSprites.BltEx(X, Y, LowByte(PlayField16[tPos])); // replot the port on top
+ // End of split movement (port)
+ // ------------------------------
+ } // loc_g_6D1E:'loc_g_6D28:
+
+ SeqPos = SeqPos + 1;
+ if (dx[SeqPos] > -1)
+ return subAnimateMurphy;
+
+ // Follow-up after movement completed 'loc_g_6D35:
+ MurphyXPos = MurphyXPos + MurphyDX;
+ MurphyYPos = MurphyYPos + MurphyDY;
+ bl = HighByte(PlayField16[si]); // animation phase
+ MovHighByte(&PlayField16[si], 0);
+
+ if (bl == 0x1) // space, moving up
+ goto loc_g_6EC8;
+
+ if (bl == 0x2) // space, moving left
+ goto loc_g_6EE6;
+
+ if (bl == 0x3) // space, moving down
+ goto loc_g_6F04;
+
+ if (bl == 0x4) // space, moving right
+ goto loc_g_71C4;
+
+ if (bl == 0x5) // base , moving up
+ goto loc_g_6EC8;
+
+ if (bl == 0x6) // base , moving left -> 6 is not used, value is set to 2 instead of 6!
+ goto loc_g_6EE6;
+
+ if (bl == 0x7) // base , moving down
+ goto loc_g_6F04;
+
+ if (bl == 0x8) // base , moving right
+ goto loc_g_71C4;
+
+ if (bl == 0x9) // infotron, moving up
+ goto loc_g_6EBA;
+
+ if (bl == 0xA) // infotron, moving left
+ goto loc_g_6ED8;
+
+ if (bl == 0xB) // infotron, moving down
+ goto loc_g_6EF6;
+
+ if (bl == 0xC) // infotron, moving right
+ goto loc_g_71B6;
+
+ if (bl == 0xD) // exit
+ goto loc_g_6F77;
+
+ if (bl == 0xE) // zonk, pushing left
+ goto loc_g_6F18;
+
+ if (bl == 0xF) // zonk, pushing right
+ goto loc_g_6F3B;
+
+ if (bl == 0x10) // base , touching up
+ goto loc_g_71E2;
+
+ if (bl == 0x11) // base , touching left
+ goto loc_g_71FE;
+
+ if (bl == 0x12) // base , touching down
+ goto loc_g_721A;
+
+ if (bl == 0x13) // base , touching right
+ goto loc_g_7236;
+
+ if (bl == 0x14) // infotron touching up
+ goto loc_g_71D4;
+
+ if (bl == 0x15) // infotron touching left
+ goto loc_g_71F0;
+
+ if (bl == 0x16) // infotron touching down
+ goto loc_g_720C;
+
+ if (bl == 0x17) // infotron touching right
+ goto loc_g_7228;
+
+ if (bl == 0x18) // port up
+ goto loc_g_7244;
+
+ if (bl == 0x19) // port left
+ goto loc_g_7272;
+
+ if (bl == 0x1A) // port down
+ goto loc_g_729F;
+
+ if (bl == 0x1B) // port right
+ goto loc_g_72CD;
+
+ if (bl == 0x1C) // red disk, moving up
+ goto loc_g_72FA;
+
+ if (bl == 0x1D) // red disk, moving left
+ goto loc_g_7318;
+
+ if (bl == 0x1E) // red disk, moving down
+ goto loc_g_7333;
+
+ if (bl == 0x1F) // red disk, moving right -> 9-Step-Bug!
+ goto loc_g_7351;
+
+ if (bl == 0x20) // red disk, touching up
+ goto loc_g_736C;
+
+ if (bl == 0x21) // red disk, touching left
+ goto loc_g_7381;
+
+ if (bl == 0x22) // red disk, touching down
+ goto loc_g_7396;
+
+ if (bl == 0x23) // red disk, touching right
+ goto loc_g_73AB;
+
+ if (bl == 0x24) // yellow disk, pushing up
+ goto loc_g_73C0;
+
+ if (bl == 0x25) // yellow disk, pushing left
+ goto loc_g_73DD;
+
+ if (bl == 0x26) // yellow disk, pushing right -> order of "down" exchanged with "right"!
+ goto loc_g_7417;
+
+ if (bl == 0x27) // yellow disk, pushing down -> order of "down" exchanged with "right"!
+ goto loc_g_73FA;
+
+ if (bl == 0x28) // orange disk, pushing left
+ goto loc_g_7434;
+
+ if (bl == 0x29) // orange disk, pushing right
+ goto loc_g_7451;
+
+ if (bl == 0x2A) // red disk, release
+ goto loc_g_747F;
+
+ ExitToMenuFlag = 1;
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // infotron, moving up
+ // ==========================================================================
+
+loc_g_6EBA:
+ if (0 < LowByte(InfotronsNeeded))
+ InfotronsNeeded = InfotronsNeeded - 1;
+
+ subDisplayInfotronsNeeded();
+loc_g_6EC8: // space, base
+ PlayField16[si] = fiMurphy;
+ subAdjustZonksInfotronsAboveMurphy(si + FieldWidth);
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // infotron, moving left
+ // ==========================================================================
+
+loc_g_6ED8:
+ if (0 < LowByte(InfotronsNeeded))
+ InfotronsNeeded = InfotronsNeeded - 1;
+
+ subDisplayInfotronsNeeded();
+loc_g_6EE6: // space, base
+ PlayField16[si] = fiMurphy;
+ subAdjustZonksInfotronsAboveMurphy(si + 1);
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // infotron, moving down
+ // ==========================================================================
+
+loc_g_6EF6:
+ if (0 < LowByte(InfotronsNeeded))
+ InfotronsNeeded = InfotronsNeeded - 1;
+
+ subDisplayInfotronsNeeded();
+loc_g_6F04: // space, base
+ if (LowByte(PlayField16[si - FieldWidth]) != fiExplosion)
+ PlayField16[si - FieldWidth] = 0;
+
+ PlayField16[si] = fiMurphy;
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // infotron, moving right
+ // ==========================================================================
+
+loc_g_71B6:
+ if (0 < LowByte(InfotronsNeeded))
+ InfotronsNeeded = InfotronsNeeded - 1;
+
+ subDisplayInfotronsNeeded();
+loc_g_71C4: // space, base
+ subAdjustZonksInfotronsAboveMurphy(si - 1);
+ PlayField16[si] = fiMurphy;
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // infotron, touching up
+ // ==========================================================================
+
+loc_g_71D4:
+ if (0 < LowByte(InfotronsNeeded))
+ InfotronsNeeded = InfotronsNeeded - 1;
+
+ subDisplayInfotronsNeeded();
+loc_g_71E2: // base
+ if (LowByte(PlayField16[si - FieldWidth]) != fiExplosion)
+ PlayField16[si - FieldWidth] = 0;
+
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // infotron, touching left
+ // ==========================================================================
+
+loc_g_71F0:
+ if (0 < LowByte(InfotronsNeeded))
+ InfotronsNeeded = InfotronsNeeded - 1;
+
+ subDisplayInfotronsNeeded();
+loc_g_71FE: // base
+ if (LowByte(PlayField16[si - 1]) != fiExplosion)
+ PlayField16[si - 1] = 0;
+
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // infotron, touching down
+ // ==========================================================================
+
+loc_g_720C:
+ if (0 < LowByte(InfotronsNeeded))
+ InfotronsNeeded = InfotronsNeeded - 1;
+
+ subDisplayInfotronsNeeded();
+loc_g_721A: // base
+ if (LowByte(PlayField16[si + FieldWidth]) != fiExplosion)
+ PlayField16[si + FieldWidth] = 0;
+
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // infotron, touching right
+ // ==========================================================================
+
+loc_g_7228:
+ if (0 < LowByte(InfotronsNeeded))
+ InfotronsNeeded = InfotronsNeeded - 1;
+
+ subDisplayInfotronsNeeded();
+loc_g_7236: // base
+ if (LowByte(PlayField16[si + 1]) != fiExplosion)
+ PlayField16[si + 1] = 0;
+
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // zonk, pushing left
+ // ==========================================================================
+
+loc_g_6F18:
+ if (LowByte(PlayField16[si]) != fiExplosion)
+ PlayField16[si] = 0;
+
+ PlayField16[si - 1] = fiMurphy;
+ PlayField16[si - 2] = fiZonk;
+ subExplodeSnikSnaksBelow(si - 2);
+ si = si - 1;
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // zonk, pushing right
+ // ==========================================================================
+
+loc_g_6F3B:
+ if (LowByte(PlayField16[si]) != fiExplosion)
+ PlayField16[si] = 0;
+
+ PlayField16[si + 1] = fiMurphy;
+ PlayField16[si + 2] = fiZonk;
+ subExplodeSnikSnaksBelow(si + 2);
+ si = si + 1;
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // exit
+ // ==========================================================================
+
+loc_g_6F77:
+ ExitToMenuFlag = 1;
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Push Zonk from right to left
+ // ==========================================================================
+
+loc_g_6F7E:
+ if (DemoKeyCode == keyLeft && PlayField16[si - 1] == fiZonk)
+ return subAnimateMurphy;
+
+ PlayField16[si] = fiMurphy; // else restore - no more zonk pushing!
+ PlayField16[si - 1] = fiZonk;
+ if (LowByte(PlayField16[si - 2]) != fiExplosion)
+ PlayField16[si - 2] = 0;
+
+ subCopyFieldToScreen(si, fiMurphy);
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Push Zonk from left to right
+ // ==========================================================================
+
+loc_g_6FBC:
+ if (DemoKeyCode == keyRight && PlayField16[si + 1] == fiZonk)
+ return subAnimateMurphy;
+
+ PlayField16[si] = fiMurphy; // else restore - no more zonk pushing!
+ PlayField16[si + 1] = fiZonk;
+ if (LowByte(PlayField16[si + 2]) != fiExplosion)
+ PlayField16[si + 2] = 0;
+
+ subCopyFieldToScreen(si, fiMurphy);
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Push orange disk from right to left
+ // ==========================================================================
+
+loc_g_6FFA:
+ if (DemoKeyCode == keyLeft && PlayField16[si - 1] == fiOrangeDisk)
+ return subAnimateMurphy;
+
+ PlayField16[si] = fiMurphy; // else restore - no more pushing!
+ PlayField16[si - 1] = fiOrangeDisk;
+ if (LowByte(PlayField16[si - 2]) != fiExplosion)
+ PlayField16[si - 2] = 0;
+
+ subCopyFieldToScreen(si, fiMurphy);
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Push orange disk from left to right
+ // ==========================================================================
+
+loc_g_7038:
+ if (DemoKeyCode == keyRight && PlayField16[si + 1] == fiOrangeDisk)
+ return subAnimateMurphy;
+
+ PlayField16[si] = fiMurphy; // else restore - no more pushing!
+ PlayField16[si + 1] = fiOrangeDisk;
+ if (LowByte(PlayField16[si + 2]) != fiExplosion)
+ PlayField16[si + 2] = 0;
+
+ subCopyFieldToScreen(si, fiMurphy);
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Push yellow disk from down to up
+ // ==========================================================================
+
+loc_g_7076:
+ if (DemoKeyCode == keyUp && PlayField16[si - FieldWidth] == fiYellowDisk)
+ return subAnimateMurphy;
+
+ PlayField16[si] = fiMurphy; // else restore - no more pushing!
+ PlayField16[si - FieldWidth] = fiYellowDisk;
+ if (LowByte(PlayField16[si - 2 * FieldWidth]) != fiExplosion)
+ PlayField16[si - 2 * FieldWidth] = 0;
+
+ subCopyFieldToScreen(si, fiMurphy);
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Push yellow disk from right to left
+ // ==========================================================================
+
+loc_g_70B4:
+ if (DemoKeyCode == keyLeft && PlayField16[si - 1] == fiYellowDisk)
+ return subAnimateMurphy;
+
+ PlayField16[si] = fiMurphy; // else restore - no more pushing!
+ PlayField16[si - 1] = fiYellowDisk;
+ if (LowByte(PlayField16[si - 2]) != fiExplosion)
+ PlayField16[si - 2] = 0;
+
+ subCopyFieldToScreen(si, fiMurphy);
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Push yellow disk from up to down
+ // ==========================================================================
+
+loc_g_70F2:
+ if (DemoKeyCode == keyDown && PlayField16[si + FieldWidth] == fiYellowDisk)
+ return subAnimateMurphy;
+
+ PlayField16[si] = fiMurphy; // else restore - no more pushing!
+ PlayField16[si + FieldWidth] = fiYellowDisk;
+ if (LowByte(PlayField16[si + 2 * FieldWidth]) != fiExplosion)
+ PlayField16[si + 2 * FieldWidth] = 0;
+
+ subCopyFieldToScreen(si, fiMurphy);
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Push yellow disk from left to right
+ // ==========================================================================
+
+loc_g_7130:
+ if (DemoKeyCode == keyRight && PlayField16[si + 1] == fiYellowDisk)
+ return subAnimateMurphy;
+
+ PlayField16[si] = fiMurphy; // else restore - no more pushing!
+ PlayField16[si + 1] = fiYellowDisk;
+ if (LowByte(PlayField16[si + 2]) != fiExplosion)
+ PlayField16[si + 2] = 0;
+
+ subCopyFieldToScreen(si, fiMurphy);
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // time red disk release (space)
+ // ==========================================================================
+
+loc_g_716E:
+ if (DemoKeyCode != keySpace)
+ {
+ PlayField16[si] = fiMurphy;
+ subCopyFieldToScreen(si, fiMurphy);
+ RedDiskReleasePhase = 0;
+ }
+ else if (MovingPictureSequencePhase == 0x20)
+ {
+ subCopyFieldToScreen(si, 43); // anxious murphy
+ RedDiskReleasePhase = 1;
+ }
+
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Special port down to up
+ // ==========================================================================
+
+loc_g_7244:
+ if (LowByte(PlayField16[si]) != fiExplosion)
+ PlayField16[si] = 0;
+
+ PlayField16[si - 2 * FieldWidth] = fiMurphy;
+ SplitMoveFlag = 0;
+ si = si - FieldWidth;
+ if (HighByte(PlayField16[si]) == 1)
+ subSpPortTest(si);
+
+ si = si - FieldWidth;
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Special port right to left
+ // ==========================================================================
+
+loc_g_7272:
+ if (LowByte(PlayField16[si]) != fiExplosion)
+ PlayField16[si] = 0;
+
+ PlayField16[si - 2] = fiMurphy;
+ SplitMoveFlag = 0;
+ si = si - 1;
+ if (HighByte(PlayField16[si]) == 1)
+ subSpPortTest(si);
+
+ si = si - 1;
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Special port up to down
+ // ==========================================================================
+
+loc_g_729F:
+ if (LowByte(PlayField16[si]) != fiExplosion)
+ PlayField16[si] = 0;
+
+ PlayField16[si + 2 * FieldWidth] = fiMurphy;
+ SplitMoveFlag = 0;
+ si = si + FieldWidth;
+ if (HighByte(PlayField16[si]) == 1)
+ subSpPortTest(si);
+
+ si = si + FieldWidth;
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Special port left to right
+ // ==========================================================================
+
+loc_g_72CD:
+ if (LowByte(PlayField16[si]) != fiExplosion)
+ PlayField16[si] = 0;
+
+ PlayField16[si + 2] = fiMurphy;
+ SplitMoveFlag = 0;
+ si = si + 1;
+ if (HighByte(PlayField16[si]) == 1)
+ subSpPortTest(si);
+
+ si = si + 1;
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Move Red Disk up
+ // ==========================================================================
+
+loc_g_72FA:
+ if (LowByte(PlayField16[si]) != fiExplosion)
+ PlayField16[si] = 0;
+
+ si = si - FieldWidth;
+ PlayField16[si] = fiMurphy;
+ subEatRedDisk(si); // inc+show Murphy's red disks
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Move Red Disk left
+ // ==========================================================================
+
+loc_g_7318:
+ if (LowByte(PlayField16[si + 1]) != fiExplosion)
+ PlayField16[si + 1] = 0;
+
+ PlayField16[si] = fiMurphy;
+ subEatRedDisk(si); // inc+show Murphy's red disks
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Move Red Disk down
+ // ==========================================================================
+
+loc_g_7333:
+ if (LowByte(PlayField16[si]) != fiExplosion)
+ PlayField16[si] = 0;
+
+ si = si + FieldWidth;
+ PlayField16[si] = fiMurphy;
+ subEatRedDisk(si); // inc+show Murphy's red disks
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Move Red Disk right
+ // ==========================================================================
+
+loc_g_7351:
+ if (LowByte(PlayField16[si - 1]) != fiExplosion)
+ PlayField16[si - 1] = 0;
+
+ PlayField16[si] = fiMurphy;
+ subEatRedDisk(si); // inc+show Murphy's red disks
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Eat Red Disk up
+ // ==========================================================================
+
+loc_g_736C:
+ if (LowByte(PlayField16[si - FieldWidth]) != fiExplosion)
+ PlayField16[si - FieldWidth] = 0;
+
+ subEatRedDisk(si - FieldWidth); // inc+show Murphy's red disks
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Eat Red Disk left
+ // ==========================================================================
+
+loc_g_7381:
+ if (LowByte(PlayField16[si - 1]) != fiExplosion)
+ PlayField16[si - 1] = 0;
+
+ subEatRedDisk(si - 1); // inc+show Murphy's red disks
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Eat Red Disk down
+ // ==========================================================================
+
+loc_g_7396:
+ if (LowByte(PlayField16[si + FieldWidth]) != fiExplosion)
+ PlayField16[si + FieldWidth] = 0;
+
+ subEatRedDisk(si + FieldWidth); // inc+show Murphy's red disks
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Eat Red Disk right
+ // ==========================================================================
+
+loc_g_73AB:
+ if (LowByte(PlayField16[si + 1]) != fiExplosion)
+ PlayField16[si + 1] = 0;
+
+ subEatRedDisk(si + 1); // inc+show Murphy's red disks
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // yellow disk, pushing up
+ // ==========================================================================
+
+loc_g_73C0:
+ if (LowByte(PlayField16[si]) != fiExplosion)
+ PlayField16[si] = 0;
+
+ si = si - FieldWidth;
+ PlayField16[si] = fiMurphy;
+ PlayField16[si - FieldWidth] = fiYellowDisk;
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // yellow disk, pushing left
+ // ==========================================================================
+
+loc_g_73DD:
+ if (LowByte(PlayField16[si]) != fiExplosion)
+ PlayField16[si] = 0;
+
+ si = si - 1;
+ PlayField16[si] = fiMurphy;
+ PlayField16[si - 1] = fiYellowDisk;
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // yellow disk, pushing down
+ // ==========================================================================
+
+loc_g_73FA:
+ if (LowByte(PlayField16[si]) != fiExplosion)
+ PlayField16[si] = 0;
+
+ si = si + FieldWidth;
+ PlayField16[si] = fiMurphy;
+ PlayField16[si + FieldWidth] = fiYellowDisk;
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // yellow disk pushing right
+ // ==========================================================================
+
+loc_g_7417:
+ if (LowByte(PlayField16[si]) != fiExplosion)
+ PlayField16[si] = 0;
+
+ si = si + 1;
+ PlayField16[si] = fiMurphy;
+ PlayField16[si + 1] = fiYellowDisk;
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // orange disk, pushing left
+ // ==========================================================================
+
+loc_g_7434:
+ if (LowByte(PlayField16[si]) != fiExplosion)
+ PlayField16[si] = 0;
+
+ si = si - 1;
+ PlayField16[si] = fiMurphy;
+ PlayField16[si - 1] = fiOrangeDisk;
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // orange disk, pushing right
+ // ==========================================================================
+
+loc_g_7451:
+ if (LowByte(PlayField16[si]) != fiExplosion)
+ PlayField16[si] = 0;
+
+ si = si + 1;
+ PlayField16[si] = fiMurphy;
+ PlayField16[si + 1] = fiOrangeDisk;
+ if (PlayField16[si + FieldWidth + 1] == 0) // make it fall down if below is empty
+ {
+ MovHighByte(&PlayField16[si + 1], 0x20);
+ MovHighByte(&PlayField16[si + FieldWidth + 1], fiOrangeDisk);
+ }
+
+ return subAnimateMurphy;
+
+ // ==========================================================================
+ // Release a red disk
+ // ==========================================================================
+
+loc_g_747F:
+ PlayField16[si] = fiMurphy;
+ RedDiskReleasePhase = 2;
+ RedDiskCount = RedDiskCount - 1;
+ subDisplayRedDiskCount();
+ subSoundFXPush(); // Sound effects
+
+ return subAnimateMurphy;
+} // subAnimateMurphy
+
+// ==========================================================================
+// SUBROUTINE
+// ==========================================================================
+int subExplodeSnikSnaksBelow(int si)
+{
+ int subExplodeSnikSnaksBelow;
+
+ int ax;
+
+ ax = LowByte(PlayField16[si + FieldWidth]);
+ if (ax == 0x11 || ax == 0xBB)
+ ExplodeFieldSP(si + FieldWidth);
+
+ return subExplodeSnikSnaksBelow;
+} // subExplodeSnikSnaksBelow
+
+// ==========================================================================
+// SUBROUTINE
+// Does pushing against an object kill Murphy?
+// ==========================================================================
+static boolean subMoveKillsMurphy(int si, int ax, int bl)
+{
+ static boolean subMoveKillsMurphy;
+
+ int al, ah;
+
+ al = LowByte(ax);
+ ah = HighByte(ax);
+ if (ax == 0xFFFF || ax == 0xAAAA || ah == 0)
+ goto loc_g_752E;
+
+ if (al == fiZonk)
+ goto loc_g_74E7;
+
+ if (al == fiExplosion)
+ goto loc_g_7530;
+
+ if (fiOrangeDisk <= al && al <= fiPortUp)
+ goto loc_g_752E;
+
+ ExplodeFieldSP(si); // Explode
+ subMoveKillsMurphy = True;
+ return subMoveKillsMurphy;
+
+loc_g_74E7: // zonk
+ if (bl == keyLeft)
+ goto loc_g_74F6;
+
+ if (bl == keyRight)
+ goto loc_g_7512;
+
+ ExplodeFieldSP(si); // Explode
+ subMoveKillsMurphy = True;
+ return subMoveKillsMurphy;
+
+loc_g_74F6: // zonk left
+ ah = ah & 0xF0;
+ if (! (ah == 0x20 || ah == 0x40 || ah == 0x50 || ah == 0x70))
+ ExplodeFieldSP(si);
+
+ subMoveKillsMurphy = True; // Set carry flag
+ return subMoveKillsMurphy;
+
+loc_g_7512: // zonk right
+ ah = ah & 0xF0;
+ if (! (ah == 0x30 || ah == 0x40 || ah == 0x60 || ah == 0x70))
+ ExplodeFieldSP(si);
+
+loc_g_752E: // Marked fields and Ports
+ subMoveKillsMurphy = True; // Set carry flag
+ return subMoveKillsMurphy;
+
+loc_g_7530: // explosion
+ if ((ah & 0x80) != 0)
+ goto loc_g_753A;
+
+ if (ah >= 4)
+ goto loc_g_753F;
+
+loc_g_753A:
+ ExplodeFieldSP(si); // Explode
+ subMoveKillsMurphy = True; // Set carry flag
+ return subMoveKillsMurphy;
+
+loc_g_753F:
+ PlayField16[si] = 0;
+ subMoveKillsMurphy = False;
+
+ return subMoveKillsMurphy;
+} // subMoveKillsMurphy
+
+// ==========================================================================
+// SUBROUTINE
+// Test If si 's a special (grav) port and If so Then fetch new values (see below)
+// change conditions to port specs
+// The 10-port data base is at data_h_0D28, 10 entries of 6 bytes each:
+// (hi),(lo),(gravity),(freeze zonks),(freeze enemies),(unused)
+// ==========================================================================
+int subSpPortTest(int si)
+{
+ int subSpPortTest;
+
+ int i, cx, bx;
+
+ cx = LInfo.SpecialPortCount; // number of special ports
+ for (i = 1; i <= cx; i++)
+ {
+ {
+ bx = HighByte(LInfo.SpecialPort[i].PortLocation);
+ MovHighByte(&bx, LowByte(LInfo.SpecialPort[i].PortLocation));
+ if (bx / 2 == si)
+ {
+ GravityFlag = LInfo.SpecialPort[i].Gravity;
+ FreezeZonks = LInfo.SpecialPort[i].FreezeZonks;
+ SnikSnaksElectronsFrozen = LInfo.SpecialPort[i].FreezeEnemies;
+ // RandomTime = RandomTime Xor RandomSeed 'is RandomTime used at all? no!
+ i = cx + 1;
+ }
+
+ }
+ }
+
+ return subSpPortTest;
+} // subSpPortTest
+
+void subCopyFieldToScreen(int si, int fi)
+{
+ int X, Y;
+
+ // +++++++++++++++++++++++++++++++++++++++++
+ X = GetStretchX(si);
+ Y = GetStretchY(si);
+ StretchedSprites.BltEx(X, Y, fi);
+ // +++++++++++++++++++++++++++++++++++++++++
+}
+
+static void subEatRedDisk(int si)
+{
+ if (AllowRedDiskCheat == 0)
+ {
+ if (RedDiskReleasePhase != 0)
+ {
+ if (RedDiskReleaseMurphyPos == si)
+ return;
+ }
+ }
+
+ RedDiskCount = (RedDiskCount + 1) % 256;
+ subDisplayRedDiskCount();
+}
+
+int subAdjustZonksInfotronsAboveMurphy(int si)
+{
+ int subAdjustZonksInfotronsAboveMurphy;
+
+ int ax;
+
+ if (LowByte(PlayField16[si]) != fiExplosion)
+ PlayField16[si] = 0;
+
+ ax = PlayField16[si - FieldWidth];
+ if (ax == 0 || ax == 0x9999)
+ goto loc_g_15A8;
+
+ if (ax == fiZonk || ax == fiInfotron)
+ {
+ MovHighByte(&PlayField16[si - FieldWidth], 0x40); // make falling straigt down
+ }
+
+ return subAdjustZonksInfotronsAboveMurphy;
+
+loc_g_15A8: // empty above
+ ax = PlayField16[si - FieldWidth - 1];
+ if (ax == fiZonk || ax == fiInfotron)
+ goto loc_g_15C5;
+
+loc_g_15B6:
+ ax = PlayField16[si - FieldWidth + 1];
+ if (ax == fiZonk || ax == fiInfotron)
+ goto loc_g_15E8;
+
+ return subAdjustZonksInfotronsAboveMurphy;
+
+loc_g_15C5: // zonk/infotron above left
+ ax = PlayField16[si - 1];
+ if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM)) // continue testing right above
+ goto loc_g_15B6;
+
+ MovHighByte(&PlayField16[si - FieldWidth - 1], 0x60); // make roll right
+ PlayField16[si - FieldWidth] = 0x8888;
+ return subAdjustZonksInfotronsAboveMurphy;
+
+loc_g_15E8: // zonk/infotron above right
+ ax = PlayField16[si + 1];
+ if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
+ {
+ MovHighByte(&PlayField16[si - FieldWidth + 1], 0x50); // make roll left
+ PlayField16[si - FieldWidth] = 0x8888;
+ }
+
+ return subAdjustZonksInfotronsAboveMurphy;
+} // subAdjustZonksInfotronsAboveMurphy
--- /dev/null
+// ----------------------------------------------------------------------------
+// Murphy.h
+// ----------------------------------------------------------------------------
+
+#ifndef MURPHY_H
+#define MURPHY_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern int subAdjustZonksInfotronsAboveMurphy(int si);
+extern int subAnimateMurphy(int si);
+extern void subCopyFieldToScreen(int si, int fi);
+extern int subExplodeSnikSnaksBelow(int si);
+extern int subSpPortTest(int si);
+
+#endif /* MURPHY_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// OrangeDisk.c
+// ----------------------------------------------------------------------------
+
+#include "OrangeDisk.h"
+
+static char *VB_Name = "modOrangeDisk";
+// --- Option Explicit
+// ==========================================================================
+// SUBROUTINE
+// Animate/move orange disks (falling)
+// ==========================================================================
+
+int subAnimateOrangeDisks(int si)
+{
+ int subAnimateOrangeDisks;
+
+ int ax, bl, dx, X, Y;
+
+ ax = PlayField16[si];
+ if (LowByte(ax) != fiOrangeDisk)
+ return subAnimateOrangeDisks;
+
+ if (ax >= 0x3008) // disk is falling
+ goto loc_g_2804;
+
+ if (ax >= 0x2008) // disk is in wait state before falling
+ goto loc_g_27DA;
+
+ if (PlayField16[si + FieldWidth] == 0)
+ goto loc_g_27CF;
+
+ return subAnimateOrangeDisks;
+
+loc_g_27CF: // below is empty -> disk may start to fall
+ MovHighByte(&PlayField16[si], 0x20);
+ MovHighByte(&PlayField16[si + FieldWidth], fiOrangeDisk);
+ return subAnimateOrangeDisks;
+
+loc_g_27DA:
+ if (PlayField16[si + FieldWidth] == 0)
+ {
+ PlayField16[si] = fiOrangeDisk;
+ return subAnimateOrangeDisks;
+ } // loc_g_27E8:
+
+ bl = HighByte(PlayField16[si]) + 1;
+ if (bl == 0x22) // wait phase is finished
+ bl = 0x30;
+
+ MovHighByte(&PlayField16[si], bl);
+ return subAnimateOrangeDisks;
+
+loc_g_2804: // disk is falling
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ dx = HighByte(PlayField16[si]) & 0x7;
+ X = GetStretchX(si);
+ Y = GetStretchY(si);
+ StretchedSprites.BltEx(X, Y, 0);
+ StretchedSprites.BltEx(X, Y + TwoPixels * (dx + 1), fiOrangeDisk);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ bl = HighByte(PlayField16[si]) + 1;
+ if ((bl & 0x7) != 0)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ return subAnimateOrangeDisks;
+ }
+
+ PlayField16[si] = 0;
+ PlayField16[si + FieldWidth] = fiOrangeDisk;
+ si = si + FieldWidth;
+ if (PlayField16[si + FieldWidth] == 0)
+ {
+ MovHighByte(&PlayField16[si], 0x30); // go on falling down
+ MovHighByte(&PlayField16[si + FieldWidth], fiOrangeDisk);
+ return subAnimateOrangeDisks;
+ } // loc_g_2867:
+
+ if (LowByte(PlayField16[si + FieldWidth]) == fiExplosion)
+ return subAnimateOrangeDisks;
+
+ ExplodeFieldSP(si); // Explode
+
+ return subAnimateOrangeDisks;
+} // subAnimateOrangeDisks
+
--- /dev/null
+// ----------------------------------------------------------------------------
+// OrangeDisk.h
+// ----------------------------------------------------------------------------
+
+#ifndef ORANGEDISK_H
+#define ORANGEDISK_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern int subAnimateOrangeDisks(int si);
+
+#endif /* ORANGEDISK_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// PathTools.c
+// ----------------------------------------------------------------------------
+
+#include "PathTools.h"
+
+static char *VB_Name = "PathTools_Module";
+// --- Option Explicit
+// --- Option Compare Text
+
+// ########### Quote & UnQuote ##################################################
+
+void UnQuote(char *ST)
+{
+ long L;
+
+ L = strlen(ST);
+ while (STRING_IS_LIKE(ST, "\"*"))
+ {
+ ST = Right(ST, L - 1);
+ L = L - 1;
+ }
+
+ while (STRING_IS_LIKE(ST, "*\""))
+ {
+ ST = Left(ST, L - 1);
+ }
+}
+
+void Quote(char *ST)
+{
+ if (! STRING_IS_LIKE(ST, "\"*"))
+ ST = CAT("\"", ST);
+
+ if (! STRING_IS_LIKE(ST, "*\""))
+ ST = CAT(ST, "\"");
+}
+
+char *UnQuoted(char *STRG)
+{
+ char *UnQuoted;
+
+ long L;
+ char *ST;
+
+ ST = STRG;
+ L = strlen(ST);
+ while (STRING_IS_LIKE(ST, "\"*"))
+ {
+ ST = Right(ST, L - 1);
+ L = L - 1;
+ }
+
+ while (STRING_IS_LIKE(ST, "*\""))
+ {
+ ST = Left(ST, L - 1);
+ }
+
+ UnQuoted = ST;
+
+ return UnQuoted;
+}
+
+char *Quoted(char *STRG)
+{
+ char *Quoted;
+
+ char *ST;
+
+ ST = STRG;
+ if (! STRING_IS_LIKE(ST, "\"*"))
+ ST = CAT("\"", ST);
+
+ if (! STRING_IS_LIKE(ST, "*\""))
+ ST = CAT(ST, "\"");
+
+ Quoted = ST;
+
+ return Quoted;
+}
+
+// ############ Path-/FileName-Extraction and concatanation ######################
+
+char *StripDir(char *Path)
+{
+ char *StripDir;
+
+ char *T;
+ long i;
+
+ T = StrReverse(Path);
+ i = InStr(1, T, "/");
+ if (i == 0)
+ StripDir = "";
+ else
+ StripDir = StrReverse(Right(T, strlen(T) - i));
+
+ return StripDir;
+}
+
+char *StripFileName(char *Path)
+{
+ char *StripFileName;
+
+ char *T;
+ long i;
+
+ T = StrReverse(Path);
+ if (STRING_IS_LIKE(T, "/*"))
+ T = Right(T, strlen(T) - 1);
+
+ i = InStr(1, T, "/");
+ if (i == 0)
+ i = strlen(T) + 1;
+
+ if (i < 2)
+ StripFileName = "";
+ else
+ StripFileName = StrReverse(Left(T, i - 1));
+
+ return StripFileName;
+}
+
+char *StripExtension(char *Path)
+{
+ char *StripExtension;
+
+ char *T;
+ long i, iSlash;
+
+ T = StrReverse(Path);
+ iSlash = InStr(1, T, "/");
+ i = InStr(1, T, ".");
+ if ((i < 2) || (iSlash < i))
+ StripExtension = "";
+ else
+ StripExtension = StrReverse(Left(T, i - 1));
+
+ return StripExtension;
+}
+
+char *NewExtension(char *Path, char *NewExt)
+{
+ char *NewExtension;
+
+ // NewExtension("C:\MyPath\MyFile.Old","New") returns "C:\MyPath\MyFile.New"
+ // NewExtension("C:\MyPath.dir\MyFile","New") returns "C:\MyPath\MyFile.New"
+ char *T;
+ long i, iSlash, ELen;
+
+ T = StrReverse(Path);
+ iSlash = InStr(1, T, "/");
+ i = InStr(1, T, ".");
+ if ((i < 1) || (iSlash < i))
+ ELen = 0;
+ else
+ ELen = i;
+
+ NewExtension = CAT(Left(StrReverse(T), strlen(T) - i), ".", NewExt);
+
+ return NewExtension;
+}
+
+char *StripExtensionlessFileName(char *Path)
+{
+ char *StripExtensionlessFileName;
+
+ char *T, *T2;
+ long i, iSlash;
+
+ T = StripFileName(Path);
+ T2 = StripExtension(Path);
+ StripExtensionlessFileName = Left(T, strlen(T) - strlen(T2) - (0 < strlen(T2) ? 1 : 1));
+
+ return StripExtensionlessFileName;
+}
+
+char *WithSlash(char *Path)
+{
+ char *WithSlash;
+
+ if (STRING_IS_LIKE(Path, "*/"))
+ {
+ WithSlash = Path;
+ }
+ else
+ {
+ WithSlash = CAT(Path, "/");
+ }
+
+ return WithSlash;
+}
+
+char *SlashLess(char *Path)
+{
+ char *SlashLess;
+
+ SlashLess = Path;
+ while (STRING_IS_LIKE(SlashLess, "*/"))
+ {
+ SlashLess = Left(Path, strlen(Path) - 1);
+ }
+
+ return SlashLess;
+}
+
+// ############ File-/Diresctory-Operations ######################################
+
+boolean FileExists(char *Path)
+{
+ boolean FileExists;
+
+ if ((STRING_IS_LIKE(Dir(Path), "")) || (STRING_IS_LIKE(Path, "")))
+ FileExists = False;
+ else
+ FileExists = True;
+
+ return FileExists;
+}
+
+void MayKill(char *Path)
+{
+
+ // --- On Error GoTo MayKillEH
+ Kill(Path);
+ // MayKillEH:
+}
+
+boolean IsDir(char *Path)
+{
+ boolean IsDir;
+
+
+ // --- On Error Resume Next
+ IsDir = (vbDirectory == (GetAttr(Path) & vbDirectory));
+ if (Err.Number != 0)
+ IsDir = False;
+
+ return IsDir;
+}
+
+// ######### binary comparison of files ##########################################
+
+boolean FilesEqual(char *Path1, char *Path2)
+{
+ boolean FilesEqual;
+
+ int FNum1, FNum2;
+ long nSize, i;
+ boolean b1Open, b2Open;
+ byte *bin1, *bin2;
+
+ FilesEqual = False;
+ // Debug.Assert(FileExists(Path1));
+ // Debug.Assert(FileExists(Path2));
+ if (! (FileExists(Path1) && FileExists(Path2)))
+ return FilesEqual;
+
+ nSize = FileLen(Path1);
+ if (nSize != FileLen(Path2))
+ return FilesEqual;
+
+ bin1 = REDIM_1D(sizeof(byte), 0, nSize + 1 - 1);
+ bin2 = REDIM_1D(sizeof(byte), 0, nSize + 1 - 1);
+ b1Open = False;
+ b2Open = False;
+
+ // --- On Error GoTo FilesEqualEH
+ // FNum1 = FreeFile();
+ FNum1 = fopen(Path1, "rb");
+ b1Open = True;
+ FILE_GET(FNum1, -1, &bin1, sizeof(bin1));
+ fclose(FNum1);
+ b1Open = False;
+ // FNum2 = FreeFile();
+ FNum2 = fopen(Path2, "rb");
+ b2Open = True;
+ FILE_GET(FNum2, -1, &bin2, sizeof(bin2));
+ fclose(FNum2);
+ b2Open = False;
+ // --- On Error GoTo 0
+
+ for (i = 1; i <= nSize; i++)
+ {
+ if (bin1[i] != bin2[i]) // return false
+ return FilesEqual;
+ }
+
+ FilesEqual = True;
+ return FilesEqual;
+
+FilesEqualEH:
+ if (b1Open)
+ Close(FNum1);
+
+ if (b2Open)
+ Close(FNum2);
+
+ return FilesEqual;
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// PathTools.h
+// ----------------------------------------------------------------------------
+
+#ifndef PATHTOOLS_H
+#define PATHTOOLS_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern boolean FileExists(char *Path);
+extern boolean FilesEqual(char *Path1, char *Path2);
+extern boolean IsDir(char *Path);
+extern void MayKill(char *Path);
+extern char *NewExtension(char *Path, char *NewExt);
+extern void Quote(char *ST);
+extern char *Quoted(char *STRG);
+extern char *SlashLess(char *Path);
+extern char *StripDir(char *Path);
+extern char *StripExtension(char *Path);
+extern char *StripExtensionlessFileName(char *Path);
+extern char *StripFileName(char *Path);
+extern void UnQuote(char *ST);
+extern char *UnQuoted(char *STRG);
+extern char *WithSlash(char *Path);
+
+#endif /* PATHTOOLS_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// SettingsObject.c
+// ----------------------------------------------------------------------------
+
+#include "SettingsObject.h"
+
+// --- VERSION 1.0 CLASS
+// --- BEGIN
+// --- MultiUse = -1 'True // True
+// --- Persistable = 0 'NotPersistable // NotPersistable
+// --- DataBindingBehavior = 0 'vbNone // vbNone
+// --- DataSourceBehavior = 0 'vbNone // vbNone
+// --- MTSTransactionMode = 0 'NotAnMTSObject // NotAnMTSObject
+// --- END
+
+static char *VB_Name = "SettingsObject";
+static boolean VB_GlobalNameSpace = False;
+static boolean VB_Creatable = True;
+static boolean VB_PredeclaredId = False;
+static boolean VB_Exposed = False;
+// --- Option Explicit
+// --- Option Compare Text
+
+const char *AppName = "MegaPlex";
+const char *Config = "Config";
+
+void SettingsObject_Save(char *ValName, int Val)
+{
+ SaveSetting(AppName, Config, ValName, Val);
+}
+
+int SettingsObject_Read(char *ValName, int Default)
+{
+ int Read;
+
+ Read = GetSetting(AppName, Config, ValName, Default);
+
+ return Read;
+}
+
--- /dev/null
+// ----------------------------------------------------------------------------
+// SettingsObject.h
+// ----------------------------------------------------------------------------
+
+#ifndef SETTINGSOBJECT_H
+#define SETTINGSOBJECT_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern int SettingsObject_Read(char *ValName, int Default);
+extern void SettingsObject_Save(char *ValName, int Val);
+
+#endif /* SETTINGSOBJECT_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// SnikSnaks.c
+// ----------------------------------------------------------------------------
+
+#include "SnikSnaks.h"
+
+static int subDrawSnikSnakFromAbove(int si, int bx);
+static int subDrawSnikSnakFromBelow(int si, int bx);
+static int subDrawSnikSnakFromLeft(int si, int bx);
+static int subDrawSnikSnakFromRight(int si, int bx);
+static int subDrawSnikSnakTurnLeft(int si, int bx);
+static int subDrawSnikSnakTurnRight(int si, int bx);
+static int subSnikSnakFromAbove(int si, int bx);
+static int subSnikSnakFromBelow(int si, int bx);
+static int subSnikSnakFromLeft(int si, int bx);
+static int subSnikSnakFromRight(int si, int bx);
+static int subSnikSnakTurnLeft(int si, int bx);
+static int subSnikSnakTurnRight(int si, int bx);
+
+static char *VB_Name = "modSnikSnak";
+// --- Option Explicit
+// ==========================================================================
+// SUBROUTINE
+// Animate/move Snik-Snaks
+// ==========================================================================
+
+int subAnimateSnikSnaks(int si)
+{
+ int subAnimateSnikSnaks;
+
+ int bx, Tmp;
+
+ if (SnikSnaksElectronsFrozen == 1)
+ return subAnimateSnikSnaks;
+
+ // 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;
+ }
+
+ return subAnimateSnikSnaks;
+} // subAnimateSnikSnaks
+
+int subDrawAnimatedSnikSnaks(int si)
+{
+ int subDrawAnimatedSnikSnaks;
+
+ int bx, Tmp;
+
+ // If SnikSnaksElectronsFrozen = 1 Then Exit Function
+ if (LowByte(PlayField16[si]) != fiSnikSnak)
+ return subDrawAnimatedSnikSnaks;
+
+ 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;
+ }
+
+ return subDrawAnimatedSnikSnaks;
+} // subAnimateSnikSnaks
+
+static int subSnikSnakTurnLeft(int si, int bx)
+{
+ static int subSnikSnakTurnLeft;
+
+ int ax, ah, bl, dx, X, Y;
+
+ ax = (TimerVar & 3);
+ if (ax != 0)
+ {
+ if (ax == 3)
+ goto loc_g_7622;
+
+ return subSnikSnakTurnLeft;
+ } // loc_g_75E0:
+
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ X = GetStretchX(si);
+ Y = GetStretchY(si);
+ StretchedSprites.BltEx(X, Y, aniSnikSnak[bx]);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ bx = (bx + 1) & 0x7;
+ MovHighByte(&PlayField16[si], bx);
+ return subSnikSnakTurnLeft;
+
+locMayExplode760A:
+ ah = HighByte(ax);
+ if (ah == 0x1B)
+ return subSnikSnakTurnLeft;
+
+ if (ah == 0x19)
+ return subSnikSnakTurnLeft;
+
+ if (ah == 0x18)
+ return subSnikSnakTurnLeft;
+
+ if (ah == 0x1A)
+ return subSnikSnakTurnLeft;
+
+ ExplodeFieldSP(si); // Explode
+ return subSnikSnakTurnLeft;
+
+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 subSnikSnakTurnLeft;
+
+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 subSnikSnakTurnLeft;
+
+loc_g_764E: // above is empty -> go up
+ PlayField16[si] = 0x1BB;
+ si = si - FieldWidth;
+ PlayField16[si] = 0x1011;
+ return subSnikSnakTurnLeft;
+
+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 subSnikSnakTurnLeft;
+
+loc_g_7671: // left is empty -> go there
+ PlayField16[si] = 0x2BB;
+ si = si - 1;
+ PlayField16[si] = 0x1811;
+ return subSnikSnakTurnLeft;
+
+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 subSnikSnakTurnLeft;
+
+loc_g_7697: // below is empty -> go down
+ PlayField16[si] = 0x3BB;
+ si = si + FieldWidth;
+ PlayField16[si] = 0x2011;
+ return subSnikSnakTurnLeft;
+
+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 subSnikSnakTurnLeft;
+
+loc_g_76BD: // right is empty -> go there
+ PlayField16[si] = 0x4BB;
+ si = si + 1;
+ PlayField16[si] = 0x2811;
+
+ return subSnikSnakTurnLeft;
+} // subSnikSnakTurnLeft
+
+static int subSnikSnakTurnRight(int si, int bx)
+{
+ static int subSnikSnakTurnRight;
+
+ int ax, ah, bl, dx, X, Y;
+
+ ax = (TimerVar & 3);
+ if (ax != 0)
+ {
+ if (ax == 3)
+ goto loc_g_771F;
+
+ return subSnikSnakTurnRight;
+ } // loc_g_76DB:
+
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ X = GetStretchX(si);
+ Y = GetStretchY(si);
+ StretchedSprites.BltEx(X, Y, aniSnikSnak[0x10 - bx]);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ bx = ((bx + 1) & 0x7) | 8;
+ MovHighByte(&PlayField16[si], bx);
+ return subSnikSnakTurnRight;
+
+locMayExplode7707:
+ ah = HighByte(ax);
+ if (ah == 0x1B)
+ return subSnikSnakTurnRight;
+
+ if (ah == 0x19)
+ return subSnikSnakTurnRight;
+
+ if (ah == 0x18)
+ return subSnikSnakTurnRight;
+
+ if (ah == 0x1A)
+ return subSnikSnakTurnRight;
+
+ ExplodeFieldSP(si); // Explode
+ return subSnikSnakTurnRight;
+
+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 subSnikSnakTurnRight;
+
+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 subSnikSnakTurnRight;
+
+loc_g_774B: // above is empty -> go up
+ PlayField16[si] = 0x1BB;
+ si = si - FieldWidth;
+ PlayField16[si] = 0x1011;
+ return subSnikSnakTurnRight;
+
+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 subSnikSnakTurnRight;
+
+loc_g_776E: // left is empty -> go there
+ PlayField16[si] = 0x2BB;
+ si = si - 1;
+ PlayField16[si] = 0x1811;
+ return subSnikSnakTurnRight;
+
+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 subSnikSnakTurnRight;
+
+loc_g_7794: // below is empty -> go down
+ PlayField16[si] = 0x3BB;
+ si = si + FieldWidth;
+ PlayField16[si] = 0x2011;
+ return subSnikSnakTurnRight;
+
+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 subSnikSnakTurnRight;
+
+loc_g_77BA: // right is empty -> go there
+ PlayField16[si] = 0x4BB;
+ si = si + 1;
+ PlayField16[si] = 0x2811;
+
+ return subSnikSnakTurnRight;
+} // subSnikSnakTurnRight
+
+static int subSnikSnakFromBelow(int si, int bx)
+{
+ static int subSnikSnakFromBelow;
+
+ 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, aniSnikSnakUp + bx);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 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 subSnikSnakFromBelow;
+ } // 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 subSnikSnakFromBelow;
+ } // 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 subSnikSnakFromBelow;
+ } // loc_g_784A:
+
+ if (LowByte(ax) == fiMurphy) // check for murphy above
+ {
+ ExplodeFieldSP(si); // Explode
+ return subSnikSnakFromBelow;
+ } // 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 subSnikSnakFromBelow;
+ } // loc_g_7862: and 'loc_g_786F:
+
+ // else: no way to go, start turning around
+ MovHighByte(&PlayField16[si], 1);
+
+ return subSnikSnakFromBelow;
+} // subSnikSnakFromBelow
+
+static int subSnikSnakFromRight(int si, int bx)
+{
+ static int subSnikSnakFromRight;
+
+ 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, aniSnikSnakLeft + bx);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 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 subSnikSnakFromRight;
+ } // 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 subSnikSnakFromRight;
+ } // 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 subSnikSnakFromRight;
+ } // loc_g_78F0:
+
+ if (LowByte(ax) == fiMurphy)
+ {
+ ExplodeFieldSP(si); // Explode
+ return subSnikSnakFromRight;
+ } // loc_g_78FB:
+
+ ax = PlayField16[si - FieldWidth]; // check above
+ if (ax == 0 || LowByte(ax) == fiMurphy)
+ {
+ MovHighByte(&PlayField16[si], 0xF);
+ return subSnikSnakFromRight;
+ } // loc_g_7908:loc_g_7915:
+
+ MovHighByte(&PlayField16[si], 3);
+
+ return subSnikSnakFromRight;
+} // subSnikSnakFromRight
+
+static int subSnikSnakFromAbove(int si, int bx)
+{
+ static int subSnikSnakFromAbove;
+
+ 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, aniSnikSnakDown + bx);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 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 subSnikSnakFromAbove;
+ } // 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 subSnikSnakFromAbove;
+ } // 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 subSnikSnakFromAbove;
+ } // loc_g_799D:
+
+ if (LowByte(ax) == fiMurphy)
+ {
+ ExplodeFieldSP(si); // Explode
+ return subSnikSnakFromAbove;
+ } // loc_g_79A8:
+
+ ax = PlayField16[si - 1]; // check left
+ if (ax == 0 || LowByte(ax) == fiMurphy)
+ {
+ MovHighByte(&PlayField16[si], 0xD);
+ return subSnikSnakFromAbove;
+ } // loc_g_79C2:
+
+ MovHighByte(&PlayField16[si], 5);
+
+ return subSnikSnakFromAbove;
+} // subSnikSnakFromAbove
+
+static int subSnikSnakFromLeft(int si, int bx)
+{
+ static int subSnikSnakFromLeft;
+
+ 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, aniSnikSnakRight + bx);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 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 subSnikSnakFromLeft;
+ } // 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 subSnikSnakFromLeft;
+ } // 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 subSnikSnakFromLeft;
+ } // loc_g_7A44:
+
+ if (LowByte(ax) == fiMurphy)
+ {
+ ExplodeFieldSP(si); // Explode
+ return subSnikSnakFromLeft;
+ } // loc_g_7A4F:
+
+ ax = PlayField16[si + FieldWidth]; // check below
+ if (ax == 0 || LowByte(ax) == fiMurphy)
+ {
+ MovHighByte(&PlayField16[si], 0xB);
+ return subSnikSnakFromLeft;
+ } // loc_g_7A69:
+
+ MovHighByte(&PlayField16[si], 7);
+
+ return subSnikSnakFromLeft;
+} // subSnikSnakFromLeft
+
+static int subDrawSnikSnakTurnLeft(int si, int bx)
+{
+ static int subDrawSnikSnakTurnLeft;
+
+ int X, Y;
+
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ X = GetStretchX(si);
+ Y = GetStretchY(si);
+ StretchedSprites.BltEx(X, Y, aniSnikSnak[bx]);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ return subDrawSnikSnakTurnLeft;
+}
+
+static int subDrawSnikSnakTurnRight(int si, int bx)
+{
+ static int subDrawSnikSnakTurnRight;
+
+ int X, Y;
+
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ X = GetStretchX(si);
+ Y = GetStretchY(si);
+ StretchedSprites.BltEx(X, Y, aniSnikSnak[0x10 - bx]);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ return subDrawSnikSnakTurnRight;
+}
+
+static int subDrawSnikSnakFromBelow(int si, int bx)
+{
+ static int subDrawSnikSnakFromBelow;
+
+ int X, Y;
+
+ bx = bx - 0xF; // get and anti-increment sequence#
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ X = GetStretchX(si);
+ Y = GetStretchY(si + FieldWidth);
+ StretchedSprites.BltEx(X, Y, 0);
+ StretchedSprites.BltEx(X, Y - bx * TwoPixels, aniSnikSnakUp + bx);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ return subDrawSnikSnakFromBelow;
+}
+
+static int subDrawSnikSnakFromRight(int si, int bx)
+{
+ static int subDrawSnikSnakFromRight;
+
+ 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, aniSnikSnakLeft + bx);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ return subDrawSnikSnakFromRight;
+}
+
+static int subDrawSnikSnakFromAbove(int si, int bx)
+{
+ static int subDrawSnikSnakFromAbove;
+
+ 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, aniSnikSnakDown + bx);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ return subDrawSnikSnakFromAbove;
+}
+
+static int subDrawSnikSnakFromLeft(int si, int bx)
+{
+ static int subDrawSnikSnakFromLeft;
+
+ 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, aniSnikSnakRight + bx);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+ return subDrawSnikSnakFromLeft;
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// SnikSnaks.h
+// ----------------------------------------------------------------------------
+
+#ifndef SNIKSNAKS_H
+#define SNIKSNAKS_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern int subAnimateSnikSnaks(int si);
+extern int subDrawAnimatedSnikSnaks(int si);
+
+#endif /* SNIKSNAKS_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// Sound.c
+// ----------------------------------------------------------------------------
+
+#include "Sound.h"
+
+static char *VB_Name = "modSound";
+// --- Option Explicit
+
+int MusicOnFlag;
+int FXOnFlag;
+
+DirectSoundBuffer ZonkFX[1 + 1];
+DirectSoundBuffer InfotronFX[1 + 1];
+DirectSoundBuffer BugFX[1 + 1];
+DirectSoundBuffer ExplosionFX[1 + 1];
+DirectSoundBuffer PushFX;
+DirectSoundBuffer ExitFX;
+DirectSoundBuffer BaseFX;
+
+#if 0
+
+void LoadSoundFX()
+{
+ DSBUFFERDESC bufferDesc;
+ WAVEFORMATEX waveFormat;
+ char *FName;
+ int i;
+
+ bufferDesc.lFlags = DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_STATIC;
+ waveFormat.nFormatTag = WAVE_FORMAT_PCM;
+ waveFormat.nChannels = 1;
+ waveFormat.lSamplesPerSec = 8000;
+ waveFormat.nBitsPerSample = 8;
+ waveFormat.nBlockAlign = waveFormat.nBitsPerSample / 8 * waveFormat.nChannels;
+ waveFormat.lAvgBytesPerSec = waveFormat.lSamplesPerSec * waveFormat.nBlockAlign;
+ FName = CAT(App.Path, "/Sound/");
+ for (i = 0; i <= 1; i++)
+ {
+ ZonkFX[i] = DSound.CreateSoundBufferFromFile(CAT(FName, "Zonk.wav"), bufferDesc, waveFormat);
+ InfotronFX[i] = DSound.CreateSoundBufferFromFile(CAT(FName, "Infotron.wav"), bufferDesc, waveFormat);
+ BugFX[i] = DSound.CreateSoundBufferFromFile(CAT(FName, "Bug.wav"), bufferDesc, waveFormat);
+ ExplosionFX[i] = DSound.CreateSoundBufferFromFile(CAT(FName, "Explosion.wav"), bufferDesc, waveFormat);
+ }
+
+ BaseFX = DSound.CreateSoundBufferFromFile(CAT(FName, "Base.wav"), bufferDesc, waveFormat);
+ ExitFX = DSound.CreateSoundBufferFromFile(CAT(FName, "Exit.wav"), bufferDesc, waveFormat);
+ PushFX = DSound.CreateSoundBufferFromFile(CAT(FName, "Push.wav"), bufferDesc, waveFormat);
+ // FXOnFlag = 0
+}
+
+#endif
+
+void subSoundFXZonk()
+{
+ int i;
+
+ if (FXOnFlag == 0)
+ return;
+
+ for (i = 0; i <= 1; i++)
+ {
+ if (! IS_NOTHING(&ZonkFX[i], sizeof(ZonkFX[i])))
+ {
+ if (ZonkFX[i].GetStatus() != DSBSTATUS_PLAYING)
+ {
+ ZonkFX[i].Play DSBPLAY_DEFAULT;
+ break;
+ }
+ }
+ }
+}
+
+void subSoundFXBug()
+{
+ int i;
+
+ if (FXOnFlag == 0)
+ return;
+
+ for (i = 0; i <= 1; i++)
+ {
+ if (! IS_NOTHING(&BugFX[i], sizeof(BugFX[i])))
+ {
+ if (BugFX[i].GetStatus() != DSBSTATUS_PLAYING)
+ {
+ BugFX[i].Play DSBPLAY_DEFAULT;
+ break;
+ }
+ }
+ }
+}
+
+void subSoundFXInfotron()
+{
+ int i;
+
+ if (FXOnFlag == 0)
+ return;
+
+ for (i = 0; i <= 1; i++)
+ {
+ if (! IS_NOTHING(&InfotronFX[i], sizeof(InfotronFX[i])))
+ {
+ if (InfotronFX[i].GetStatus() != DSBSTATUS_PLAYING)
+ {
+ InfotronFX[i].Play DSBPLAY_DEFAULT;
+ break;
+ }
+ }
+ }
+}
+
+void subSoundFXExplosion()
+{
+ int i;
+
+ if (FXOnFlag == 0)
+ return;
+
+ for (i = 0; i <= 1; i++)
+ {
+ if (! IS_NOTHING(&ExplosionFX[i], sizeof(ExplosionFX[i])))
+ {
+ if (ExplosionFX[i].GetStatus() != DSBSTATUS_PLAYING)
+ {
+ ExplosionFX[i].Play DSBPLAY_DEFAULT;
+ break;
+ }
+ }
+ }
+}
+
+void subSoundFXBase()
+{
+ if (FXOnFlag == 0)
+ return;
+
+ if (IS_NOTHING(&BaseFX, sizeof(BaseFX)))
+ return;
+
+ if (BaseFX.GetStatus() != DSBSTATUS_PLAYING)
+ {
+ BaseFX.Play DSBPLAY_DEFAULT;
+ }
+}
+
+void subSoundFXPush()
+{
+ if (FXOnFlag == 0)
+ return;
+
+ if (IS_NOTHING(&PushFX, sizeof(PushFX)))
+ return;
+
+ if (PushFX.GetStatus() != DSBSTATUS_PLAYING)
+ {
+ PushFX.Play DSBPLAY_DEFAULT;
+ }
+}
+
+void subSoundFXExit()
+{
+ if (FXOnFlag == 0)
+ return;
+
+ if (IS_NOTHING(&ExitFX, sizeof(ExitFX)))
+ return;
+
+ if (ExitFX.GetStatus() != DSBSTATUS_PLAYING)
+ {
+ ExitFX.Play DSBPLAY_DEFAULT;
+ }
+}
+
+void subMusicInit()
+{
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// Sound.h
+// ----------------------------------------------------------------------------
+
+#ifndef SOUND_H
+#define SOUND_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern void LoadSoundFX();
+extern void subMusicInit();
+extern void subSoundFXBase();
+extern void subSoundFXBug();
+extern void subSoundFXExit();
+extern void subSoundFXExplosion();
+extern void subSoundFXInfotron();
+extern void subSoundFXPush();
+extern void subSoundFXZonk();
+
+extern int FXOnFlag;
+extern int MusicOnFlag;
+
+#endif /* SOUND_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// TickCountObject.c
+// ----------------------------------------------------------------------------
+
+#include "TickCountObject.h"
+
+// --- VERSION 1.0 CLASS
+// --- BEGIN
+// --- MultiUse = -1 'True // True
+// --- Persistable = 0 'NotPersistable // NotPersistable
+// --- DataBindingBehavior = 0 'vbNone // vbNone
+// --- DataSourceBehavior = 0 'vbNone // vbNone
+// --- MTSTransactionMode = 0 'NotAnMTSObject // NotAnMTSObject
+// --- END
+
+// static char *VB_Name = "TickCountObject";
+// static boolean VB_GlobalNameSpace = False;
+// static boolean VB_Creatable = True;
+// static boolean VB_PredeclaredId = False;
+// static boolean VB_Exposed = False;
+// --- Option Explicit
+
+#define LongMin (-(double)2147483648) // the "#" sign is a bug of the VB environment AutoFormat function but causes no real problems; don't worry 'bout it!
+#define LongMax (2147483647)
+
+long GetTickCount();
+long QueryPerformanceCounter(currency lpPerformanceCount);
+long QueryPerformanceFrequency(currency lpFrequency);
+
+boolean DelayLoopActive;
+
+boolean MPause, bHighPerf;
+currency PFreq; // LARGE_INTEGER
+double sFactor, msFactor, usFactor;
+
+boolean TickCountObject_Get_Active()
+{
+ boolean Active;
+
+ Active = DelayLoopActive;
+
+ return Active;
+}
+
+boolean TickCountObject_Get_Pause()
+{
+ boolean Pause;
+
+ Pause = MPause;
+
+ return Pause;
+}
+
+void TickCountObject_Let_Pause(boolean NewVal)
+{
+ MPause = NewVal;
+}
+
+void TickCountObject_DelayMS(long MSInterval, boolean DoEventsFlag) // in ms
+{
+ currency Start;
+
+ Start = TickNow();
+ DelayLoopActive = True;
+ do
+ {
+ if (DoEventsFlag)
+ DoEvents();
+
+ if (MSInterval <= TickDiffMS(Start) && ! MPause)
+ break;
+ }
+ while (1);
+
+ DelayLoopActive = False;
+}
+
+// for compatibility with old code:
+void TickCountObject_DelayS(long SInterval, boolean DoEventsFlag) // in s
+{
+ // check if SInterval is less than 25 days ...
+ if ((int)(LongMax / 1000) <= SInterval)
+ {
+ Err.Raise(513, "Delay()", "Value Overflow");
+ }
+ else
+ {
+ TickCountObject_DelayMS((long)1000 * SInterval, DoEventsFlag);
+ }
+}
+
+currency TickCountObject_Get_TickNow()
+{
+ currency TickNow;
+
+ if (bHighPerf)
+ {
+ QueryPerformanceCounter(TickNow);
+ }
+ else
+ {
+ TickNow = GetTickCount();
+ }
+
+ return TickNow;
+}
+
+long TickCountObject_TickDiffS(currency TickStart)
+{
+ long TickDiffS;
+
+ currency NewTick, TD;
+
+ if (bHighPerf)
+ {
+ QueryPerformanceCounter(NewTick);
+ TD = (NewTick - TickStart);
+ TickDiffS = sFactor * TD;
+ }
+ else
+ {
+ NewTick = GetTickCount();
+ if (NewTick < TickStart)
+ {
+ // Overflow occured and needs to be handled
+ TickDiffS = (LongMax - TickStart) + (NewTick - LongMin) + 1;
+ }
+ else
+ {
+ TickDiffS = NewTick - TickStart;
+ }
+
+ TickDiffS = Int(TickDiffS / 1000);
+ }
+
+ return TickDiffS;
+}
+
+long TickCountObject_TickDiffMS(currency TickStart)
+{
+ long TickDiffMS;
+
+ currency NewTick, TD;
+
+ if (bHighPerf)
+ {
+ QueryPerformanceCounter(NewTick);
+ TD = (NewTick - TickStart);
+ TickDiffMS = msFactor * TD;
+ }
+ else
+ {
+ NewTick = GetTickCount();
+ if (NewTick < TickStart)
+ {
+ // Overflow occured and needs to be handled
+ TickDiffMS = (LongMax - TickStart) + (NewTick - LongMin) + 1;
+ }
+ else
+ {
+ TickDiffMS = NewTick - TickStart;
+ }
+ }
+
+ return TickDiffMS;
+}
+
+currency TickCountObject_TickDiffUS(currency TickStart)
+{
+ currency TickDiffUS;
+
+ currency NewTick, TD;
+
+ if (bHighPerf)
+ {
+ QueryPerformanceCounter(NewTick);
+ TD = (NewTick - TickStart);
+ TickDiffUS = usFactor * TD;
+ }
+ else
+ {
+ NewTick = GetTickCount();
+ if (NewTick < TickStart)
+ {
+ // Overflow occured and needs to be handled
+ TickDiffUS = ((LongMax - TickStart) + (NewTick - LongMin) + 1) * (currency)1000;
+ }
+ else
+ {
+ TickDiffUS = (NewTick - TickStart) * (currency)1000;
+ }
+ }
+
+ return TickDiffUS;
+}
+
+#if 0
+
+static void Class_Initialize()
+{
+ long L;
+
+ bHighPerf = (0 != QueryPerformanceFrequency(PFreq));
+ if (bHighPerf)
+ {
+ sFactor = (double)1 / PFreq;
+ msFactor = (double)1000 / PFreq;
+ usFactor = (double)1000000 / PFreq;
+ }
+
+ DelayLoopActive = False;
+ TickCountObject_Let_Pause(False);
+}
+
+#endif
--- /dev/null
+// ----------------------------------------------------------------------------
+// TickCountObject.h
+// ----------------------------------------------------------------------------
+
+#ifndef TICKCOUNTOBJECT_H
+#define TICKCOUNTOBJECT_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern void TickCountObject_DelayMS(long MSInterval, boolean DoEventsFlag);
+extern void TickCountObject_DelayS(long SInterval, boolean DoEventsFlag);
+extern boolean TickCountObject_Get_Active();
+extern boolean TickCountObject_Get_Pause();
+extern currency TickCountObject_Get_TickNow();
+extern void TickCountObject_Let_Pause(boolean NewVal);
+extern long TickCountObject_TickDiffMS(currency TickStart);
+extern long TickCountObject_TickDiffS(currency TickStart);
+extern currency TickCountObject_TickDiffUS(currency TickStart);
+
+#endif /* TICKCOUNTOBJECT_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// TopMost.c
+// ----------------------------------------------------------------------------
+
+#include "TopMost.h"
+
+// static char *VB_Name = "TopMost_Module";
+// --- Option Explicit
+// --- const int SWP_FRAMECHANGED = 0x20;
+// --- const int SWP_HIDEWINDOW = 0x80;
+// --- const int SWP_NOACTIVATE = 0x10;
+// --- const int SWP_NOCOPYBITS = 0x100;
+// --- const int SWP_NOMOVE = 0x2;
+// --- const int SWP_NOOWNERZORDER = 0x200;
+// --- const int SWP_NOREDRAW = 0x8;
+// --- const int SWP_NOSIZE = 0x1;
+// --- const int SWP_NOZORDER = 0x4;
+// --- const int SWP_SHOWWINDOW = 0x40;
+// --- const int SWP_DRAWFRAME = SWP_FRAMECHANGED;
+// --- const int SWP_NOREPOSITION = SWP_NOOWNERZORDER;
+
+// --- const int HWND_BOTTOM = 1;
+// --- const int HWND_BROADCAST = 0xFFFF;
+// --- const int HWND_DESKTOP = 0;
+// --- const int HWND_NOTOPMOST = - 2;
+// --- const int HWND_TOP = 0;
+// --- const int HWND_TOPMOST = - 1;
+
+int SetWindowPos(long h, long hb, int X, int Y, int cx, int cy, int f);
+
+void TopMost(Object obj)
+{
+ int i;
+
+ i = SetWindowPos(obj.hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE + SWP_NOMOVE);
+}
+
+void UnTopMost(Object obj)
+{
+ int i;
+
+ i = SetWindowPos(obj.hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE + SWP_NOMOVE);
+}
+
+void HideWindow(long hWnd)
+{
+ int i;
+
+ i = SetWindowPos(hWnd, HWND_BOTTOM, 100, 100, 200, 200, SWP_HIDEWINDOW);
+}
+
--- /dev/null
+// ----------------------------------------------------------------------------
+// TopMost.h
+// ----------------------------------------------------------------------------
+
+#ifndef TOPMOST_H
+#define TOPMOST_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+#define HWND_BOTTOM (1)
+#define HWND_BROADCAST (0xFFFF)
+#define HWND_DESKTOP (0)
+#define HWND_NOTOPMOST (- 2)
+#define HWND_TOP (0)
+#define HWND_TOPMOST (- 1)
+#define SWP_DRAWFRAME (SWP_FRAMECHANGED)
+#define SWP_FRAMECHANGED (0x20)
+#define SWP_HIDEWINDOW (0x80)
+#define SWP_NOACTIVATE (0x10)
+#define SWP_NOCOPYBITS (0x100)
+#define SWP_NOMOVE (0x2)
+#define SWP_NOOWNERZORDER (0x200)
+#define SWP_NOREDRAW (0x8)
+#define SWP_NOREPOSITION (SWP_NOOWNERZORDER)
+#define SWP_NOSIZE (0x1)
+#define SWP_NOZORDER (0x4)
+#define SWP_SHOWWINDOW (0x40)
+
+extern void HideWindow(long hWnd);
+extern void TopMost(Object obj);
+extern void UnTopMost(Object obj);
+
+#endif /* TOPMOST_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// Zonk.c
+// ----------------------------------------------------------------------------
+
+#include "Zonk.h"
+
+// static char *VB_Name = "modZonk";
+// --- Option Explicit
+
+// ==========================================================================
+// SUBROUTINE
+// Animate Zonks (falling)
+// ==========================================================================
+
+int subAnimateZonks(int si)
+{
+ int subAnimateZonks;
+
+ int tFld;
+
+ // PseudoRegisters:
+ // int ax, bx, cx, dx, di, X, Y;
+ int ax, bx, dx, X, Y;
+ // int ah, bh, ch, dh, al, bl, cl, dl;
+ int al, bl;
+
+ tFld = PlayField16[si];
+ if ((tFld & 0xFF) != fiZonk)
+ return subAnimateZonks;
+
+ if (tFld == fiZonk)
+ {
+ if (FreezeZonks == 2) // Do Zonks fall? (debug)
+ return subAnimateZonks;
+
+ ax = PlayField16[si + FieldWidth]; // select case playfield16(si+60)
+ if (ax == 0)
+ goto loc_g_0D64;
+
+ if (ax == fiZonk)
+ goto loc_g_0D35;
+
+ if (ax == fiInfotron)
+ goto loc_g_0D35;
+
+ if (ax == fiRAM)
+ goto loc_g_0D35;
+
+ return subAnimateZonks;
+
+loc_g_0D35: // Case fiZonk, fiInfotron, fiRAM
+ ax = PlayField16[si + FieldWidth - 1];
+ if (ax == 0 || ax == 0x8888 || ax == 0xAAAA)
+ goto loc_g_0D6B;
+
+loc_g_0D4C:
+ ax = PlayField16[si + FieldWidth + 1];
+ if (ax == 0 || ax == 0x8888 || ax == 0xAAAA)
+ goto loc_g_0D81;
+
+ return subAnimateZonks;
+
+loc_g_0D64: // Case fiSpace
+ MovHighByte(&PlayField16[si], 0x40);
+ goto loc_g_0DA5;
+
+loc_g_0D6B: // roll left?
+ if (PlayField16[si - 1] == 0)
+ goto loc_g_0D74;
+
+ goto loc_g_0D4C;
+
+loc_g_0D74:
+ MovHighByte(&PlayField16[si], 0x50);
+ PlayField16[si - 1] = 0x8888;
+ goto loc_g_0DA5;
+
+loc_g_0D81: // roll right?
+ if (PlayField16[si + 1] == 0)
+ goto loc_g_0D98;
+
+ if (PlayField16[si + 1] != 0x9999) // wow right is different from left!
+ return subAnimateZonks;
+
+ if (LowByte(PlayField16[si - FieldWidth + 1]) != 1)
+ return subAnimateZonks;
+
+loc_g_0D98:
+ MovHighByte(&PlayField16[si], 0x60);
+ PlayField16[si + 1] = 0x8888;
+ } // tFld = fiZonk
+
+loc_g_0DA5:
+ // from now on the zonk is definitely moving,
+ // maybe the sequence is in an advanced frame
+ // or just beeing initialized due to the code above
+ bl = HighByte(PlayField16[si]);
+ bx = 0;
+ MovLowByte(&bx, bl);
+ al = bl & 0xF0;
+ if (al == 0x10) // zonk comes falling from above
+ goto loc_g_0DE8;
+
+ if (al == 0x20) // zonk comes rolling from right to left
+ goto loc_g_0F83;
+
+ if (al == 0x30) // zonk comes rolling from left to right
+ goto loc_g_0FE8;
+
+ if (FreezeZonks == 2)
+ return subAnimateZonks;
+
+ if (al == 0x40) // zonk falls straight down
+ goto loc_g_104D;
+
+ if (al == 0x50) // zonk rolls left
+ goto loc_g_107B;
+
+ if (al == 0x60) // zonk rolls right
+ goto loc_g_10E9;
+
+ if (al == 0x70) // intermediate state
+ goto loc_g_1157;
+
+ return subAnimateZonks;
+
+loc_g_0DE8: // zonk comes falling from above
+ // To Do: draw zonk falling from above
+ // according to position in (bl And &H07)
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ X = GetStretchX(si);
+ Y = GetStretchY(si - FieldWidth);
+ dx = bl & 0x7;
+ StretchedSprites.BltEx(X, Y, 0);
+ StretchedSprites.BltEx(X, Y + TwoPixels * (dx + 1), fiZonk);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ bl = HighByte(PlayField16[si]) + 1;
+ if (bl == 0x16)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ subCleanUpForZonksAbove(si - FieldWidth);
+ return subAnimateZonks;
+ } // loc_g_0E2B:
+
+ if (bl < 0x18)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ return subAnimateZonks;
+ } // loc_g_0E35:
+
+ MovHighByte(&PlayField16[si], 0); // zonk arrived at the field
+ if ((FreezeZonks & 0xFF) == 2)
+ return subAnimateZonks;
+
+ // loc_g_0E42: // now check if the zonk may go on falling somehow
+ ax = PlayField16[si + FieldWidth];
+ if (ax == 0) // below is empty!-> go on falling 'loc_g_0E4C:
+ goto loc_g_0EDD;
+
+ if (ax == 0x9999) // below is only temporarily used ' loc_g_0E57:
+ goto loc_g_0EDD;
+
+ if ((ax & 0xFF) == fiMurphy) // Murphy dies 'loc_g_0E61:
+ goto loc_g_0F14;
+
+ if ((ax & 0xFF) == fiSnikSnak) // SnikSnak dies 'loc_g_0E6B:
+ goto loc_g_0F6E;
+
+ if (ax == 0x2BB) // loc_g_0E76:
+ goto loc_g_0F36;
+
+ if (ax == 0x4BB) // loc_g_0E81:
+ goto loc_g_0F52;
+
+ if ((ax & 0xFF) == fiElectron) // Electron cracked! 'loc_g_0E8B:
+ goto loc_g_0F6E;
+
+ if (ax == fiOrangeDisk) // OrangeDisk explodes 'loc_g_0E95:
+ goto loc_g_0F75;
+
+ subSoundFXZonk(); // play the zonk sound,'cause zonk hits something "hard"
+
+ if (! (ax == fiZonk || ax == fiInfotron || ax == fiRAM))
+ return subAnimateZonks;
+
+ // loc_g_0EAE: ' Zonk rolls somewhere
+ ax = PlayField16[si + FieldWidth - 1];
+ if (ax == 0 || ax == 0x8888 || ax == 0xAAAA) // may roll left
+ goto loc_g_0EEA;
+
+ ax = PlayField16[si + FieldWidth + 1];
+ if (ax == 0 || ax == 0x8888 || ax == 0xAAAA) // may roll right
+ goto loc_g_0F00;
+
+ return subAnimateZonks;
+
+loc_g_0EDD: // go on falling down?
+ PlayField16[si] = 0x7001; // go into intermediate waitstate
+ PlayField16[si + FieldWidth] = 0x9999; // mark as "zonk waiting to access"
+ return subAnimateZonks;
+
+loc_g_0EEA: // test if zonk may roll left
+ // This if(if true) jumps up far above
+ // to the according rountine for fixed zonks!
+ if (PlayField16[si - 1] != 0) // Remarkable!!! ' loc_g_0EF4:
+ goto loc_g_0D4C;
+
+ MovHighByte(&PlayField16[si], 0x50); // zonk rolls left
+ Mov(&PlayField16[si - 1], 0x8888); // mark as zonk accessing?
+ return subAnimateZonks;
+
+loc_g_0F00: // test if zonk may roll right
+ if (PlayField16[si + 1] != 0) // loc_g_0F08:
+ return subAnimateZonks;
+
+ MovHighByte(&PlayField16[si], 0x60); // zonk rolls right
+ Mov(&PlayField16[si + 1], 0x8888); // mark as zonk accessing?
+ return subAnimateZonks;
+
+loc_g_0F14: // Murphy dies, but not in any case
+ bl = HighByte(PlayField16[si + FieldWidth]);
+ if (bl == 0xE || bl == 0xF || bl == 0x28)
+ return subAnimateZonks;
+
+ if (bl == 0x29 || bl == 0x25 || bl == 0x26)
+ return subAnimateZonks;
+
+loc_g_0F36: // ??
+ ax = LowByte(PlayField16[si + FieldWidth - 1]);
+ if (ax == fiElectron) // loc_g_0F43:
+ PlayField16[si + FieldWidth] = fiElectron;
+
+ if (ax != 0x1F)
+ PlayField16[si + FieldWidth - 1] = 0;
+
+ goto loc_g_0F6E;
+
+loc_g_0F52: // ??
+ ax = LowByte(PlayField16[si + FieldWidth + 1]);
+ if (ax == fiElectron) // loc_g_0F5F:
+ PlayField16[si + FieldWidth] = fiElectron;
+
+ if (ax != 0x1F)
+ PlayField16[si + FieldWidth + 1] = 0;
+
+ goto loc_g_0F6E;
+
+loc_g_0F6E: // someone dies/explodes
+ si = si + FieldWidth; // 1 field down
+ ExplodeFieldSP(si); // Explode
+ return subAnimateZonks;
+
+loc_g_0F75: // OrangeDisk explodes next cycle
+ si = si + FieldWidth; // 1 field down
+ PlayField8[si] = fiHardWare;
+ return subAnimateZonks;
+
+loc_g_0F83: // zonk comes rolling from right to left
+ // To Do: draw zonk rolling from right
+ // according to position in (bl And &H07)
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ X = GetStretchX(si + 1);
+ Y = GetStretchY(si);
+ dx = (bl & 0x7) + 1;
+ StretchedSprites.BltEx(X, Y, 0);
+ StretchedSprites.BltEx(X - (TwoPixels * dx), Y, aniZonkRollLeft[dx - 1]);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ bl = HighByte(PlayField16[si]) + 1; // get and increment sequence#
+ if (bl == 0x24)
+ PlayField16[si + 1] = 0xAAAA;
+
+ if (bl == 0x26)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ subCleanUpForZonksAbove(si + 1);
+ }
+ else if (bl < 0x28)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ }
+ else
+ {
+ PlayField16[si] = 0xFFFF;
+ si = si + FieldWidth; // 1 field down
+ PlayField16[si] = 0x1001; // convert rolling zonk to a falling zonk
+ }
+
+ return subAnimateZonks;
+
+loc_g_0FE8: // zonk comes rolling from left to right
+ // To Do: draw zonk rolling from left
+ // according to position in (bl And &H07)
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ X = GetStretchX(si - 1);
+ Y = GetStretchY(si);
+ dx = (bl & 0x7) + 1;
+ StretchedSprites.BltEx(X, Y, 0);
+ StretchedSprites.BltEx(X + (TwoPixels * dx), Y, aniZonkRollRight[dx - 1]);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ bl = HighByte(PlayField16[si]) + 1;
+ if (bl == 0x34)
+ PlayField16[si - 1] = 0xAAAA;
+
+ if (bl == 0x36)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ subCleanUpForZonksAbove(si - 1);
+ }
+ else if (bl < 0x38)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ }
+ else
+ {
+ PlayField16[si] = 0xFFFF;
+ si = si + FieldWidth; // 1 field down
+ PlayField16[si] = 0x1001; // convert rolling zonk to a falling zonk
+ }
+
+ return subAnimateZonks;
+
+loc_g_104D: // zonk falls straight down
+ bl = bl + 1;
+ if (bl < 0x42)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ }
+ else if (PlayField16[si + FieldWidth] != 0)
+ {
+ bl = bl - 1; // stay waiting
+ MovHighByte(&PlayField16[si], bl);
+ }
+ else
+ {
+ PlayField16[si] = 0xFFFF; // mark as "zonk leaving"
+ si = si + FieldWidth; // 1 field down
+ PlayField16[si] = 0x1001; // go falling
+ }
+
+ return subAnimateZonks;
+
+loc_g_107B: // zonk rolls left
+ // To Do: draw zonk rolling to left
+ // according to position in (bl And &H0F)
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ X = GetStretchX(si);
+ Y = GetStretchY(si);
+ dx = (bl & 0xF) + 1;
+ StretchedSprites.BltEx(X, Y, 0);
+ StretchedSprites.BltEx(X - (TwoPixels * dx), Y, aniZonkRollLeft[dx - 1]);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ bl = HighByte(PlayField16[si]) + 1; // retrieve and increment sequence#
+ if (bl < 0x52)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ return subAnimateZonks;
+ }
+
+ if (PlayField16[si + FieldWidth - 1] != 0)
+ goto loc_g_10E2;
+
+ if (PlayField16[si - 1] != 0)
+ {
+ if (PlayField16[si - 1] != 0x8888)
+ goto loc_g_10E2;
+ } // loc_g_10C8:
+
+ PlayField16[si] = 0xFFFF;
+ si = si - 1; // 1 field left
+ PlayField16[si] = 0x2201;
+ PlayField16[si + FieldWidth] = 0xFFFF;
+ return subAnimateZonks;
+
+loc_g_10E2: // stay waiting
+ bl = bl - 1;
+ MovHighByte(&PlayField16[si], bl);
+ return subAnimateZonks;
+
+loc_g_10E9: // zonk rolls right
+ // To Do: draw zonk rolling to right
+ // according to position in (bl And &H07)
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ X = GetStretchX(si);
+ Y = GetStretchY(si);
+ dx = (bl & 0x7) + 1;
+ StretchedSprites.BltEx(X, Y, 0);
+ StretchedSprites.BltEx(X + (TwoPixels * dx), Y, aniZonkRollRight[dx - 1]);
+ // +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ bl = HighByte(PlayField16[si]) + 1;
+ if (bl < 0x62)
+ {
+ MovHighByte(&PlayField16[si], bl);
+ return subAnimateZonks;
+ }
+
+ if (PlayField16[si + FieldWidth + 1] != 0)
+ goto loc_g_1150;
+
+ if (PlayField16[si + 1] != 0)
+ {
+ if (PlayField16[si + 1] != 0x8888)
+ goto loc_g_1150;
+ }
+
+ PlayField16[si] = 0xFFFF;
+ si = si + 1;
+ PlayField16[si] = 0x3201;
+ PlayField16[si + FieldWidth] = 0xFFFF;
+ return subAnimateZonks;
+
+loc_g_1150: // stay waiting
+ bl = bl - 1;
+ MovHighByte(&PlayField16[si], bl);
+ return subAnimateZonks;
+
+loc_g_1157: // intermediate state
+ ax = PlayField16[si + FieldWidth];
+ if (ax == 0 || ax == 0x9999)
+ {
+ PlayField16[si] = 0xFFFF;
+ si = si + FieldWidth; // 1 field down
+ PlayField16[si] = 0x1001; // start falling down
+ goto loc_g_0DE8;
+ }
+
+ return subAnimateZonks;
+} // subAnimateZonks endp
+
+int subCleanUpForZonksAbove(int si)
+{
+ int subCleanUpForZonksAbove;
+
+ int ax;
+
+ if (LowByte(PlayField16[si]) != fiExplosion)
+ PlayField16[si] = 0;
+
+ if (PlayField16[si - FieldWidth] != 0)
+ {
+ if (PlayField16[si - FieldWidth] != 0x9999)
+ return subCleanUpForZonksAbove;
+
+ if (LowByte(PlayField16[si - 2 * FieldWidth]) != fiInfotron)
+ return subCleanUpForZonksAbove;
+ } // loc_g_1674:
+
+ if (PlayField16[si - FieldWidth - 1] != fiZonk)
+ {
+ if (PlayField16[si - FieldWidth + 1] != fiZonk)
+ return subCleanUpForZonksAbove;
+
+ goto loc_g_16A7;
+ }
+
+ ax = PlayField16[si - 1];
+ if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
+ {
+ PlayField16[si - FieldWidth - 1] = 0x6001;
+ PlayField16[si - FieldWidth] = 0x8888;
+ return subCleanUpForZonksAbove;
+ }
+
+ if (PlayField16[si - FieldWidth + 1] != fiZonk)
+ return subCleanUpForZonksAbove;
+
+loc_g_16A7:
+ ax = PlayField16[si + 1];
+ if (ax == fiZonk || ax == fiInfotron || ax == fiRAM)
+ {
+ PlayField16[si - FieldWidth + 1] = 0x5001;
+ PlayField16[si - FieldWidth] = 0x8888;
+ }
+
+ return subCleanUpForZonksAbove;
+} // subCleanUpForZonksAbove
+
--- /dev/null
+// ----------------------------------------------------------------------------
+// Zonk.h
+// ----------------------------------------------------------------------------
+
+#ifndef ZONK_H
+#define ZONK_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern int subAnimateZonks(int si);
+extern int subCleanUpForZonksAbove(int si);
+
+#endif /* ZONK_H */
--- /dev/null
+#ifndef EXPORT_H
+#define EXPORT_H
+
+/* ========================================================================= */
+/* functions and definitions exported from game_sp to main program */
+/* ========================================================================= */
+
+/* ------------------------------------------------------------------------- */
+/* constant definitions */
+/* ------------------------------------------------------------------------- */
+
+
+/* ------------------------------------------------------------------------- */
+/* data structure definitions */
+/* ------------------------------------------------------------------------- */
+
+struct GlobalInfo_SP
+{
+};
+
+struct GameInfo_SP
+{
+};
+
+struct LevelInfo_SP
+{
+ int file_version;
+};
+
+struct GraphicInfo_SP
+{
+ Bitmap *bitmap;
+ int src_x, src_y;
+ int src_offset_x, src_offset_y;
+ int dst_offset_x, dst_offset_y;
+ int width, height;
+
+ Bitmap *crumbled_bitmap;
+ int crumbled_src_x, crumbled_src_y;
+ int crumbled_border_size;
+
+ boolean has_crumbled_graphics;
+ boolean preserve_background;
+
+ int unique_identifier; /* used to identify needed screen updates */
+};
+
+struct EngineSnapshotInfo_SP
+{
+ struct GameInfo_SP game_sp;
+};
+
+
+/* ------------------------------------------------------------------------- */
+/* exported functions */
+/* ------------------------------------------------------------------------- */
+
+extern struct GlobalInfo_SP global_sp_info;
+extern struct LevelInfo_SP native_sp_level;
+extern struct GraphicInfo_SP graphic_info_sp_object[TILE_MAX][8];
+extern struct GraphicInfo_SP graphic_info_sp_player[MAX_PLAYERS][SPR_MAX][8];
+extern struct EngineSnapshotInfo_SP engine_snapshot_sp;
+
+extern void InitGameEngine_SP();
+extern void GameActions_SP(byte *, boolean);
+
+extern unsigned int InitEngineRandom_SP(long);
+
+extern void setLevelInfoToDefaults_SP();
+extern boolean LoadNativeLevel_SP(char *);
+
+extern void BackToFront_SP(void);
+extern void BlitScreenToBitmap_SP(Bitmap *);
+extern void RedrawPlayfield_SP(boolean);
+extern void DrawGameDoorValues_SP();
+
+extern void LoadEngineSnapshotValues_SP();
+extern void SaveEngineSnapshotValues_SP();
+
+#endif /* EXPORT_H */
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2006 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* game_sp.h *
+***********************************************************/
+
+#ifndef GAME_SP_H
+#define GAME_SP_H
+
+#define GAME_SP_VERSION_1_0_0
+
+#include "export.h"
+
+#endif /* GAME_SP_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// global.h
+// ----------------------------------------------------------------------------
+
+#ifndef GAME_SP_GLOBAL_H
+#define GAME_SP_GLOBAL_H
+
+#include "ASM.h"
+#include "BitMapObject.h"
+#include "BugsTerminals.h"
+#include "Capture.h"
+#include "DDScrollBuffer.h"
+#include "DDSpriteBuffer.h"
+#include "Demo.h"
+#include "DemoBufferObject.h"
+#include "DirectDrawGlobals.h"
+#include "DirectXGlobals.h"
+#include "Display.h"
+#include "DoGameStuff.h"
+#include "Electrons.h"
+#include "ErrorReporting.h"
+#include "Explosions.h"
+#include "FakeDeclares.h"
+#include "FancyRestore.h"
+#include "GeneralTricks.h"
+#include "Globals.h"
+#include "Infotrons.h"
+#include "InitGameConditions.h"
+#include "Input.h"
+#include "LevelSetPreviewForm.h"
+#include "MainForm.h"
+#include "MainGameLoop.h"
+#include "Marker.h"
+#include "Murphy.h"
+#include "OrangeDisk.h"
+#include "PathTools.h"
+#include "SettingsObject.h"
+#include "SnikSnaks.h"
+#include "Sound.h"
+#include "TickCountObject.h"
+#include "TopMost.h"
+#include "Zonk.h"
+#include "modAnimations.h"
+#include "modGeneralTricks.h"
+#include "modMPX.h"
+
+#endif /* GAME_SP_GLOBAL_H */
--- /dev/null
+
+#include "main_sp.h"
+#include "global.h"
+
+
+void InitGameEngine_SP()
+{
+ menPlay_Click();
+}
+
+void BlitScreenToBitmap_SP(Bitmap *target_bitmap)
+{
+}
+
+void GameActions_SP(byte action[MAX_PLAYERS], boolean warp_mode)
+{
+}
--- /dev/null
+#ifndef MAIN_SP_H
+#define MAIN_SP_H
+
+/* ========================================================================= */
+/* external functions and definitions imported from main program to game_sp */
+/* ========================================================================= */
+
+#include "../engines.h"
+
+
+/* ========================================================================= */
+/* functions and definitions that are exported from game_sp to main program */
+/* ========================================================================= */
+
+#include "export.h"
+
+
+/* ========================================================================= */
+/* internal functions and definitions that are not exported to main program */
+/* ========================================================================= */
+
+
+/* ------------------------------------------------------------------------- */
+/* constant definitions */
+/* ------------------------------------------------------------------------- */
+
+/* screen sizes and positions for SP engine */
+
+#define ORIG_TILEX 16
+#define ORIG_TILEY 16
+
+#define ZOOM_FACTOR 2
+
+#define TILEX (ORIG_TILEX * ZOOM_FACTOR)
+#define TILEY (ORIG_TILEY * ZOOM_FACTOR)
+
+#define SCR_FIELDX 17
+#define SCR_FIELDY 17
+
+/* often used screen positions */
+#define SX 8
+#define SY 8
+#define SXSIZE (SCR_FIELDX * TILEX)
+#define SYSIZE (SCR_FIELDY * TILEY)
+
+
+/* ------------------------------------------------------------------------- */
+/* data structure definitions */
+/* ------------------------------------------------------------------------- */
+
+/* ------------------------------------------------------------------------- */
+/* exported variables */
+/* ------------------------------------------------------------------------- */
+
+extern struct LevelInfo_SP native_sp_level;
+
+extern struct GameInfo_SP game_sp;
+
+
+/* ------------------------------------------------------------------------- */
+/* exported functions */
+/* ------------------------------------------------------------------------- */
+
+#endif /* MAIN_SP_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// modAnimations.c
+// ----------------------------------------------------------------------------
+
+#include "modAnimations.h"
+
+// static char *VB_Name = "modAnimations";
+// --- Option Explicit
+
+// ::: #ifndef HAS_SpecialPortType
+// ::: typedef struct
+// ::: {
+// ::: int PortLocation; // = 2*(x+(y*60))
+// ::: byte Gravity; // 1 = turn on, anything else (0) = turn off
+// ::: byte FreezeZonks; // 2 = turn on, anything else (0) = turn off (1=off!)
+// ::: byte FreezeEnemies; // 1 = turn on, anything else (0) = turn off
+// ::: byte UnUsed;
+// ::: } SpecialPortType;
+// ::: #define HAS_SpecialPortType
+// ::: #endif
+
+// ::: #ifndef HAS_LevelInfoType
+// ::: typedef struct
+// ::: {
+// ::: byte UnUsed[4 + 1];
+// ::: byte InitialGravity; // 1=on, anything else (0) = off
+// ::: byte Version; // SpeedFixVersion XOR &H20
+// ::: char LevelTitle[23];
+// ::: byte InitialFreezeZonks; // 2=on, anything else (0) = off. (1=off too!)
+// ::: byte InfotronsNeeded;
+
+// ::: // Number of Infotrons needed. 0 means that Supaplex will count the total
+// ::: // amount of Infotrons in the level, and use the low byte of that number.
+// ::: // (A multiple of 256 Infotrons will then result in 0-to-eat, etc.!)
+// ::: byte SpecialPortCount; // Maximum 10 allowed!
+// ::: SpecialPortType SpecialPort[10 + 1];
+// ::: byte SpeedByte; // = Speed XOR Highbyte(RandomSeed)
+// ::: byte CheckSumByte; // = CheckSum XOR SpeedByte
+// ::: int DemoRandomSeed;
+// ::: } LevelInfoType;
+// ::: #define HAS_LevelInfoType
+// ::: #endif
+
+DDSpriteBuffer NormalSprites;
+DDSpriteBuffer StretchedSprites;
+DDScrollBuffer Stage;
+
+byte LData[59 + 1][23 + 1];
+LevelInfoType LInfo;
+
+float Stretch; // , StretchWidth%, TwoPixels!
+
+int ScrollMinX, ScrollMaxX, ScrollMinY, ScrollMaxY;
+int ScrollX, ScrollY;
+// --- const long ScrollDelta = 1&;
+
+// Public FieldWidth&, FieldHeight&
+boolean EndFlag;
+long PauseMode;
+
+TickCountObject Clock;
+long MurphyX, MurphyY;
+
+void GoPlay()
+{
+ // Call subFetchAndInitLevelB
+ EndFlag = False;
+ subMainGameLoop();
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// modAnimations.h
+// ----------------------------------------------------------------------------
+
+#ifndef MODANIMATIONS_H
+#define MODANIMATIONS_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+#ifndef HAS_SpecialPortType
+typedef struct
+{
+ int PortLocation; // = 2*(x+(y*60))
+ byte Gravity; // 1 = turn on, anything else (0) = turn off
+ byte FreezeZonks; // 2 = turn on, anything else (0) = turn off (1=off!)
+ byte FreezeEnemies; // 1 = turn on, anything else (0) = turn off
+ byte UnUsed;
+} SpecialPortType;
+#define HAS_SpecialPortType
+#endif
+
+#ifndef HAS_LevelInfoType
+typedef struct
+{
+ byte UnUsed[4 + 1];
+ byte InitialGravity; // 1=on, anything else (0) = off
+ byte Version; // SpeedFixVersion XOR &H20
+ char LevelTitle[23];
+ byte InitialFreezeZonks; // 2=on, anything else (0) = off. (1=off too!)
+ byte InfotronsNeeded;
+
+ // Number of Infotrons needed. 0 means that Supaplex will count the total
+ // amount of Infotrons in the level, and use the low byte of that number.
+ // (A multiple of 256 Infotrons will then result in 0-to-eat, etc.!)
+ byte SpecialPortCount; // Maximum 10 allowed!
+ SpecialPortType SpecialPort[10 + 1];
+ byte SpeedByte; // = Speed XOR Highbyte(RandomSeed)
+ byte CheckSumByte; // = CheckSum XOR SpeedByte
+ int DemoRandomSeed;
+} LevelInfoType;
+#define HAS_LevelInfoType
+#endif
+
+#define ScrollDelta ((long)1)
+
+extern void GoPlay();
+
+extern DDScrollBuffer Stage;
+extern DDSpriteBuffer NormalSprites;
+extern DDSpriteBuffer StretchedSprites;
+extern LevelInfoType LInfo;
+extern boolean EndFlag;
+extern byte LData[59 + 1][23 + 1];
+extern float Stretch;
+extern int ScrollMinX, ScrollMaxX, ScrollMinY, ScrollMaxY;
+extern int ScrollX, ScrollY;
+extern long PauseMode;
+
+#endif /* MODANIMATIONS_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// modGeneralTricks.c
+// ----------------------------------------------------------------------------
+
+#include "modGeneralTricks.h"
+
+// static char *VB_Name = "modGeneralTricks";
+// --- Option Explicit
+
+void Inc(int *i)
+{
+ *i = *i + 1;
+}
+
+void Dec(int *i)
+{
+ *i = *i - 1;
+}
+
+/*
+double ValEx(char *TS)
+{
+ double ValEx;
+
+ // Extends the Val() function for
+ // german-style number-representing strings
+ int i;
+ char *LS, *RS;
+
+ i = InStr(1, TS, ",");
+ if (i != 0)
+ {
+ LS = Left(TS, i - 1);
+ RS = Right(TS, Len(TS) - i);
+ ValEx = ValCAT(LS, ".", RS);
+ }
+ else
+ {
+ ValEx = Val(TS);
+ }
+
+ return ValEx;
+}
+*/
+
+int Min(int A, int B)
+{
+ int Min;
+
+ if (A < B)
+ Min = A;
+ else
+ Min = B;
+
+ return Min;
+}
+
+int Max(int A, int B)
+{
+ int Max;
+
+ if (A < B)
+ Max = B;
+ else
+ Max = A;
+
+ return Max;
+}
+
--- /dev/null
+// ----------------------------------------------------------------------------
+// modGeneralTricks.h
+// ----------------------------------------------------------------------------
+
+#ifndef MODGENERALTRICKS_H
+#define MODGENERALTRICKS_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+extern void Dec(int *i);
+extern void Inc(int *i);
+extern int Max(int A, int B);
+extern int Min(int A, int B);
+extern double ValEx(char *TS);
+
+#endif /* MODGENERALTRICKS_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// modMPX.c
+// ----------------------------------------------------------------------------
+
+#include "modMPX.h"
+
+void ReadMPX();
+#if 0
+static void SaveMPX(char *Path);
+static void SaveSP(char *Path);
+#endif
+
+// static char *VB_Name = "modMPX";
+// --- Option Explicit
+
+char *gSignature;
+boolean bSignatureAvailable;
+
+const char MPX_ID[4] = "MPX ";
+
+// ::: #ifndef HAS_LevelDescriptor
+// ::: typedef struct
+// ::: {
+// ::: int Width;
+// ::: int Height;
+// ::: long OffSet;
+// ::: long Size;
+// ::: } LevelDescriptor;
+// ::: #define HAS_LevelDescriptor
+// ::: #endif
+
+int MPXVersion;
+int LevelCount;
+boolean DemoAvailable;
+LevelDescriptor *LDesc;
+// int OFile;
+FILE *OFile;
+
+boolean MpxOpen(char *Path)
+{
+ boolean MpxOpen;
+
+ // int i;
+ // byte T;
+ char readID[4];
+
+ MpxOpen = False;
+
+ // --- On Error GoTo OpenMPXEH
+ // OFile = FreeFile();
+ OFile = fopen(CurPath, "rb");
+ FILE_GET(OFile, -1, &readID, sizeof(readID));
+ if (readID != MPX_ID)
+ goto OpenMPXEH;
+
+ FILE_GET(OFile, -1, &MPXVersion, sizeof(MPXVersion));
+ FILE_GET(OFile, -1, &LevelCount, sizeof(LevelCount));
+ LDesc = REDIM_1D(sizeof(LevelDescriptor), 0, LevelCount + 1 - 1);
+ FILE_GET(OFile, -1, &LDesc, sizeof(LDesc));
+ MpxOpen = True;
+ return MpxOpen;
+
+OpenMPXEH:
+ fclose(OFile);
+ OFile = 0;
+
+ return MpxOpen;
+}
+
+boolean MpxLoadLInfo(int i)
+{
+ boolean MpxLoadLInfo;
+
+ long Off;
+
+ MpxLoadLInfo = False;
+ // if (OFile < 1)
+ if (OFile == 0)
+ return MpxLoadLInfo;
+
+ Off = LDesc[i].OffSet;
+ Off = Off + LDesc[i].Width * LDesc[i].Height;
+
+ // --- On Error GoTo MpxLoadLInfoEH
+ FILE_GET(OFile, Off, &LInfo, sizeof(LInfo));
+ MpxLoadLInfo = True;
+ return MpxLoadLInfo;
+
+ // MpxLoadLInfoEH:
+ fclose(OFile);
+ OFile = 0;
+
+ return MpxLoadLInfo;
+}
+
+void MpxClose()
+{
+ if (0 < OFile)
+ {
+ fclose(OFile);
+ OFile = 0;
+ }
+}
+
+void ReadMPX()
+{
+ // int FNum, i;
+ FILE *FNum;
+ int i;
+ // byte T;
+ char readID[4];
+
+ Trace("modMPX", "--> ReadMPX");
+
+ // --- On Error GoTo ReadMPXEH
+ // FNum = FreeFile();
+ Trace("modMPX", "open file");
+ FNum = fopen(CurPath, "rb");
+ FILE_GET(FNum, -1, &readID, sizeof(readID));
+ if (readID != MPX_ID)
+ goto ReadMPXEH;
+
+ FILE_GET(FNum, -1, &MPXVersion, sizeof(MPXVersion));
+ if (MPXVersion != 1)
+ goto ReadMPXEH;
+
+ FILE_GET(FNum, -1, &LevelCount, sizeof(LevelCount));
+ if (LevelCount < 1)
+ goto ReadMPXEH;
+
+ LDesc = REDIM_1D(sizeof(LevelDescriptor), 0, LevelCount + 1 - 1);
+ Trace("modMPX", "--> read LevelDescriptor");
+ FILE_GET(FNum, -1, &LDesc, sizeof(LDesc));
+ FieldWidth = LDesc[LevelNumber].Width;
+ FieldHeight = LDesc[LevelNumber].Height;
+ HeaderSize = 96;
+ FieldMax = (FieldWidth * FieldHeight) + HeaderSize - 1;
+ LevelMax = (FieldWidth * FieldHeight) - 1;
+ FileMax = LDesc[LevelNumber].Size - 1;
+ if (FileMax < FieldMax)
+ FileMax = FieldMax;
+
+ Trace("modMPX", "ReDim PlayField8");
+ PlayField8 = REDIM_1D(sizeof(byte), 0, FileMax + 1 - 1);
+ DisPlayField = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1);
+ i = LDesc[LevelNumber].OffSet;
+ FILE_GET(FNum, i, &PlayField8, sizeof(PlayField8));
+ i = i + LevelMax + 1;
+ FILE_GET(FNum, i, &LInfo, sizeof(LInfo)); // store level info in an extra structure
+ fclose(FNum);
+ // --- On Error GoTo 0
+
+ Trace("modMPX", "file closed");
+ if (FieldMax < FileMax)
+ DemoAvailable = True;
+
+ Trace("modMPX", "read signature");
+ ReadSignature();
+ Trace("modMPX", "ReDim PlayField16");
+ PlayField16 = REDIM_1D(sizeof(int), -FieldWidth, FieldMax);
+ for (i = 0; i <= FieldMax; i++)
+ {
+ PlayField16[i] = PlayField8[i];
+ DisPlayField[i] = PlayField8[i];
+ PlayField8[i] = 0;
+ }
+
+ AnimationPosTable = REDIM_1D(sizeof(int), 0, LevelMax - 2 *FieldWidth);
+ AnimationSubTable = REDIM_1D(sizeof(byte), 0, LevelMax - 2 *FieldWidth);
+ TerminalState = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1);
+ GravityFlag = LInfo.InitialGravity;
+ FreezeZonks = LInfo.InitialFreezeZonks;
+ DemoPointer = FieldMax + 1;
+ DemoOffset = DemoPointer;
+ DemoKeyRepeatCounter = 0;
+ if (DemoFlag != 0)
+ {
+ // Debug.Print "ReadMPX: " & Hex(LInfo.DemoRandomSeed)
+ RandomSeed = LInfo.DemoRandomSeed;
+ DemoFlag = 1;
+ }
+ else
+ {
+ subRandomize();
+ }
+
+ MainForm.SetDisplayRegion();
+ LevelLoaded = True;
+ if (CurPath != TmpPath)
+ Let_ModifiedFlag(False);
+
+ Trace("modMPX", "--> ReadMPX");
+ return;
+
+ReadMPXEH:
+ // Close();
+ fclose(FNum);
+ ReportError("modMPX", CAT("Error reading MPX file ", CurPath));
+ Trace("modMPX", "Error reading MPX file");
+ Trace("modMPX", "--> ReadMPX");
+}
+
+#if 0
+
+static void SaveMPX(char *Path)
+{
+ // int FNum, i;
+ FILE *FNum;
+ int i;
+ // byte T;
+ byte FF;
+
+ FF = 0xFF;
+ LevelNumber = 1;
+ LevelCount = 1;
+ MPXVersion = 1;
+ if ((FileMax < FieldMax) || ! IS_NOTHING(&DemoBuffer, sizeof(DemoBuffer)))
+ FileMax = FieldMax;
+
+ LDesc = REDIM_1D(sizeof(LevelDescriptor), 0, LevelCount + 1 - 1);
+ {
+ LDesc[LevelNumber].Width = FieldWidth;
+ LDesc[LevelNumber].Height = FieldHeight;
+ LDesc[LevelNumber].OffSet = 4 + 2 * strlen(INT_TO_STR(LevelCount)) +
+ LevelCount * sizeof(LDesc[1]) + 1;
+ LDesc[LevelNumber].Size = FileMax + 1;
+ if (! IS_NOTHING(&DemoBuffer, sizeof(DemoBuffer)))
+ {
+ LDesc[LevelNumber].Size = LDesc[LevelNumber].Size + DemoBuffer.Size + 2;
+ if (0 < strlen(MySignature))
+ LDesc[LevelNumber].Size = LDesc[LevelNumber].Size + strlen(MySignature) + 1;
+ }
+
+ }
+
+ // UnEdAll();
+
+ // --- On Error GoTo SaveMPXEH
+ // FNum = FreeFile();
+ if (FileExists(Path))
+ MayKill(Path);
+
+ FNum = fopen(Path, "wb");
+ FILE_PUT(FNum, -1, &MPX_ID, sizeof(MPX_ID));
+ FILE_PUT(FNum, -1, &MPXVersion, sizeof(MPXVersion));
+ FILE_PUT(FNum, -1, &LevelCount, sizeof(LevelCount));
+ FILE_PUT(FNum, -1, &LDesc, sizeof(LDesc));
+ i = LDesc[LevelNumber].OffSet;
+ FILE_PUT(FNum, i, &PlayField8, sizeof(PlayField8));
+ FILE_PUT(FNum, i, &DisPlayField, sizeof(DisPlayField));
+ i = i + LevelMax + 1;
+ FILE_PUT(FNum, i, &LInfo, sizeof(LInfo)); // store level info
+ if (! IS_NOTHING(&DemoBuffer, sizeof(DemoBuffer))) // demo was recorded
+ {
+ // Debug.Print "SaveMPX: " & Hex(LInfo.DemoRandomSeed)
+ FILE_PUT(FNum, -1, &FirstDemoByte, sizeof(FirstDemoByte));
+ if (! DemoBuffer.Serialize(FNum))
+ goto SaveMPXEH;
+
+ FILE_PUT(FNum, -1, &FF, sizeof(FF));
+ if (0 < strlen(MySignature))
+ {
+ FILE_PUT(FNum, -1, &MySignature, sizeof(MySignature));
+ FILE_PUT(FNum, -1, &FF, sizeof(FF));
+ }
+ }
+
+ fclose(FNum);
+ // --- On Error GoTo 0
+
+ CurPath = Path;
+
+ // EdAll();
+
+ if (Path != TmpPath)
+ Let_ModifiedFlag(False);
+
+ return;
+
+SaveMPXEH:
+ // Close();
+ fclose(FNum);
+}
+
+#endif
+
+#if 0
+
+static void SaveSP(char *Path)
+{
+ // int FNum, i;
+ FILE *FNum;
+ int i;
+ // byte T;
+
+ LevelNumber = 1;
+ LevelCount = 1;
+ if (! IS_NOTHING(&DemoBuffer, sizeof(DemoBuffer)))
+ LInfo.CheckSumByte = DemoBuffer.CheckSumByte;
+
+ if ((FileMax < FieldMax) || ! IS_NOTHING(&DemoBuffer, sizeof(DemoBuffer)))
+ FileMax = FieldMax;
+
+ // UnEdAll();
+
+ // --- On Error GoTo SaveSPEH
+ // FNum = FreeFile();
+ FNum = fopen(Path, "wb");
+ FILE_PUT(FNum, 1, &PlayField8, sizeof(PlayField8));
+ FILE_PUT(FNum, 1, &DisPlayField, sizeof(DisPlayField));
+ i = LevelMax + 2;
+ FILE_PUT(FNum, i, &LInfo, sizeof(LInfo)); // store level info
+ if (! IS_NOTHING(&DemoBuffer, sizeof(DemoBuffer))) // demo was recorded
+ {
+ // Debug.Print "SaveMPX: " & Hex(LInfo.DemoRandomSeed)
+ // If Not DemoBuffer.Serialize(FNum) Then GoTo SaveSPEH
+
+ // Debug.Assert(False);
+ }
+
+ fclose(FNum);
+ // --- On Error GoTo 0
+
+ CurPath = Path;
+
+ // EdAll();
+
+ if (Path != TmpPath)
+ Let_ModifiedFlag(False);
+
+ return;
+
+ // SaveSPEH:
+ // Close();
+}
+
+#endif
+
+void CreateLevel(int LWidth, int LHeight)
+{
+ long Tmp, i;
+ // byte T;
+
+ CurPath = "Untitled";
+ OrigPath = CurPath;
+ LevelNumber = 1;
+ FieldWidth = LWidth;
+ FieldHeight = LHeight;
+ HeaderSize = 96;
+ FieldMax = (FieldWidth * FieldHeight) + HeaderSize - 1;
+ LevelMax = (FieldWidth * FieldHeight) - 1;
+ FileMax = FieldMax;
+ PlayField8 = REDIM_1D(sizeof(byte), 0, FileMax + 1 - 1);
+ DisPlayField = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1);
+ Tmp = FieldWidth * (FieldHeight - 1);
+ for (i = 0; i <= FieldWidth - 1; i++)
+ {
+ PlayField8[i] = fiHardWare;
+ PlayField8[Tmp + i] = fiHardWare;
+ }
+
+ Tmp = Tmp;
+ for (i = FieldWidth; i <= Tmp; i += FieldWidth)
+ {
+ PlayField8[i] = fiHardWare;
+ PlayField8[i - 1] = fiHardWare;
+ }
+
+ {
+ LInfo.DemoRandomSeed = 0;
+ LInfo.InfotronsNeeded = 0;
+ LInfo.InitialFreezeZonks = 0;
+ LInfo.InitialGravity = 0;
+ strcpy(LInfo.LevelTitle, "------ New Level ------");;
+ LInfo.SpecialPortCount = 0;
+ LInfo.Version = 0x74; // immitate speedfix version 5.4
+ }
+ PlayField16 = REDIM_1D(sizeof(int), -FieldWidth, FieldMax);
+ for (i = 0; i <= FieldMax; i++)
+ {
+ PlayField16[i] = PlayField8[i];
+ DisPlayField[i] = PlayField8[i];
+ PlayField8[i] = 0;
+ }
+
+ AnimationPosTable = REDIM_1D(sizeof(int), 0, LevelMax - 2 *FieldWidth);
+ AnimationSubTable = REDIM_1D(sizeof(byte), 0, LevelMax - 2 *FieldWidth);
+ TerminalState = REDIM_1D(sizeof(byte), 0, FieldMax + 1 - 1);
+ GravityFlag = LInfo.InitialGravity;
+ FreezeZonks = LInfo.InitialFreezeZonks;
+ RandomSeed = LInfo.DemoRandomSeed;
+ DemoAvailable = False;
+ SET_TO_NOTHING(&DemoBuffer, sizeof(DemoBuffer));
+ LevelLoaded = True;
+ Let_ModifiedFlag(True);
+}
+
+void ReadSignature()
+{
+ long i, iMin, iMax;
+
+ Trace("modMPX", "--> ReadSignature");
+ bSignatureAvailable = False;
+ gSignature = "";
+
+ // ##################################################### ReRecording-Test
+ if ((DemoFlag == 1) && (RecordDemoFlag == 1))
+ {
+ FirstDemoByte = PlayField8[DemoPointer];
+ MySignature = gSignature;
+ }
+
+ // ##################################################### ReRecording-Test
+
+ // gSignature = String(511, "A"): bSignatureAvailable = False: Exit Sub 'test
+ if (! (FieldMax < FileMax))
+ return;
+
+ // !!! Debug.Assert PlayField8(FileMax) = &HFF
+ Trace("modMPX", "settin iMin/Max");
+ iMin = FileMax - 512;
+ if (iMin < (FieldMax + 2))
+ iMin = FieldMax + 2;
+
+ iMax = FileMax - 1;
+ Trace("modMPX", " For i == iMax To iMin Step -1");
+ for (i = iMax; i <= iMin; i += -1)
+ {
+ if (PlayField8[i] == 0xFF)
+ break;
+ }
+
+ if (i < iMin)
+ return;
+
+ for (i = i + 1; i <= iMax; i++)
+ {
+ gSignature = CAT(gSignature, (char)(PlayField8[i]));
+ }
+
+ // ##################################################### ReRecording-Test
+ if ((DemoFlag == 1) && (RecordDemoFlag == 1))
+ MySignature = gSignature;
+
+ // ##################################################### ReRecording-Test
+
+ if (iMin <= iMax)
+ bSignatureAvailable = True;
+
+ Trace("modMPX", "<-- ReadSignature");
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// modMPX.h
+// ----------------------------------------------------------------------------
+
+#ifndef MODMPX_H
+#define MODMPX_H
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+#include "global.h"
+
+#ifndef HAS_LevelDescriptor
+typedef struct
+{
+ int Width;
+ int Height;
+ long OffSet;
+ long Size;
+} LevelDescriptor;
+#define HAS_LevelDescriptor
+#endif
+
+extern void CreateLevel(int LWidth, int LHeight);
+extern void MpxClose();
+extern boolean MpxLoadLInfo(int i);
+extern boolean MpxOpen(char *Path);
+extern void ReadSignature();
+
+extern void ReadMPX();
+
+extern LevelDescriptor *LDesc;
+extern boolean DemoAvailable;
+extern boolean bSignatureAvailable;
+extern char *gSignature;
+extern int LevelCount;
+
+#endif /* MODMPX_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// vb_defs.h
+// ----------------------------------------------------------------------------
+
+#ifndef VB_DEFS_H
+#define VB_DEFS_H
+
+#define Win16 1
+
+#ifndef False
+#define False 0
+#define True (!False)
+#endif
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+/* these are just dummy values to prevent the compiler from complaining */
+#define VALUE_START_VB 100
+#define VALUE_START_VB_KEY 200
+#define VALUE_START_DD 300
+#define VALUE_START_DD_ERR 400
+#define VALUE_START_DS 500
+
+#define vbPicTypeBitmap (VALUE_START_VB + 1)
+#define vbSrcCopy (VALUE_START_VB + 2)
+#define vbTwips (VALUE_START_VB + 3)
+#define vbPixels (VALUE_START_VB + 4)
+#define vbPRORPortrait (VALUE_START_VB + 5)
+#define vbPRORLandscape (VALUE_START_VB + 6)
+#define vbDirectory (VALUE_START_VB + 7)
+
+#define vbKeySpace (VALUE_START_VB_KEY + 1)
+#define vbKeyLeft (VALUE_START_VB_KEY + 2)
+#define vbKeyRight (VALUE_START_VB_KEY + 3)
+#define vbKeyUp (VALUE_START_VB_KEY + 4)
+#define vbKeyDown (VALUE_START_VB_KEY + 5)
+#define vbKeyEscape (VALUE_START_VB_KEY + 6)
+#define vbKeyR (VALUE_START_VB_KEY + 7)
+#define vbKeyReturn (VALUE_START_VB_KEY + 8)
+#define vbKeyShift (VALUE_START_VB_KEY + 9)
+
+#define DD_OK (VALUE_START_DD + 0)
+
+#define DDSD_CAPS (VALUE_START_DD + 1)
+#define DDSD_WIDTH (VALUE_START_DD + 2)
+#define DDSD_HEIGHT (VALUE_START_DD + 3)
+#define DDSCL_NORMAL (VALUE_START_DD + 4)
+#define DDBLT_WAIT (VALUE_START_DD + 5)
+#define DDSCAPS_VIDEOMEMORY (VALUE_START_DD + 6)
+#define DDSCAPS_OFFSCREENPLAIN (VALUE_START_DD + 7)
+#define DDSCAPS_PRIMARYSURFACE (VALUE_START_DD + 8)
+
+#define DDERR_GENERIC (VALUE_START_DD_ERR + 1)
+#define DDERR_INVALIDCLIPLIST (VALUE_START_DD_ERR + 2)
+#define DDERR_INVALIDOBJECT (VALUE_START_DD_ERR + 3)
+#define DDERR_INVALIDPARAMS (VALUE_START_DD_ERR + 4)
+#define DDERR_INVALIDRECT (VALUE_START_DD_ERR + 5)
+#define DDERR_NOALPHAHW (VALUE_START_DD_ERR + 6)
+#define DDERR_NOBLTHW (VALUE_START_DD_ERR + 7)
+#define DDERR_NOCLIPLIST (VALUE_START_DD_ERR + 8)
+#define DDERR_NODDROPSHW (VALUE_START_DD_ERR + 9)
+#define DDERR_NOMIRRORHW (VALUE_START_DD_ERR + 10)
+#define DDERR_NORASTEROPHW (VALUE_START_DD_ERR + 11)
+#define DDERR_NOROTATIONHW (VALUE_START_DD_ERR + 12)
+#define DDERR_NOSTRETCHHW (VALUE_START_DD_ERR + 13)
+#define DDERR_NOZBUFFERHW (VALUE_START_DD_ERR + 14)
+#define DDERR_SURFACEBUSY (VALUE_START_DD_ERR + 15)
+#define DDERR_SURFACELOST (VALUE_START_DD_ERR + 16)
+#define DDERR_UNSUPPORTED (VALUE_START_DD_ERR + 17)
+#define DDERR_WASSTILLDRAWING (VALUE_START_DD_ERR + 18)
+
+#define DSSCL_PRIORITY (VALUE_START_DS + 1)
+#define DSBCAPS_CTRLFREQUENCY (VALUE_START_DS + 2)
+#define DSBCAPS_CTRLPAN (VALUE_START_DS + 3)
+#define DSBCAPS_CTRLVOLUME (VALUE_START_DS + 4)
+#define DSBCAPS_STATIC (VALUE_START_DS + 5)
+#define WAVE_FORMAT_PCM (VALUE_START_DS + 6)
+#define DSBSTATUS_PLAYING (VALUE_START_DS + 7)
+#define DSBPLAY_DEFAULT (VALUE_START_DS + 8)
+
+#endif /* VB_DEFS_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// vb_lib.c
+// ----------------------------------------------------------------------------
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+
+/* helper functions for constructs not supported by C */
+void *REDIM_1D(int a, int b, int c)
+{
+}
+
+void *REDIM_2D(int a, int b, int c, int d, int e)
+{
+}
+
+boolean IS_NOTHING(void *a, int b)
+{
+}
+
+void SET_TO_NOTHING(void *a, int b)
+{
+}
+
+void MESSAGE_BOX(char *a)
+{
+}
+
+
+char *CAT(const char *a, ...)
+{
+}
+
+char *GET_PATH(char *a, ...)
+{
+}
+
+char *INT_TO_STR(int a)
+{
+}
+
+
+boolean STRING_IS_LIKE(char *a, char *b)
+{
+}
+
+
+int FILE_GET(FILE *a, int b, void *c, int d)
+{
+}
+
+int FILE_PUT(FILE *a, int b, void *c, int d)
+{
+}
+
+
+/* this is just a workaround -- handle array definitions later */
+void *Array(int a, ...)
+{
+}
+
+
+/* VB functions that do not return "int" (and would cause compiler errors) */
+double Val(char *a)
+{
+}
+
+char *Left(char *a, int b)
+{
+}
+
+char *left(char *a, int b)
+{
+}
+
+char *Right(char *a, int b)
+{
+}
+
+char *right(char *a, int b)
+{
+}
+
+char *StrReverse(char *a)
+{
+}
+
+int InStr(int a, char *b, char *c)
+{
+}
+
+char *Dir(char *a)
+{
+}
+
+char *Dir_Without_Args()
+{
+}
+
+void Kill(char *a)
+{
+}
+
+char *Chr(int a)
+{
+}
+
+char *String(int a, char *b)
+{
+}
+
+void MkDir(char *a)
+{
+}
+
+char *Hex(int a)
+{
+}
+
+
+int FileLen(char *a)
+{
+}
+
+long GetTickCount()
+{
+}
+
+int GetAttr(char *a)
+{
+}
+
+void DoEvents()
+{
+}
+
+void SaveSetting(const char * a, const char *b, char *c, int d)
+{
+}
+
+long GetTempPath(long a, char *b)
+{
+}
--- /dev/null
+// ----------------------------------------------------------------------------
+// vb_lib.h
+// ----------------------------------------------------------------------------
+
+#ifndef VB_LIB_H
+#define VB_LIB_H
+
+#define Abs(x) ABS(x)
+#define Sqr(x) sqrt(x)
+
+
+/* helper functions for constructs not supported by C */
+extern void *REDIM_1D(int, int, int);
+extern void *REDIM_2D(int, int, int, int, int);
+
+extern boolean IS_NOTHING(void *, int);
+
+extern void SET_TO_NOTHING(void *, int);
+
+extern void MESSAGE_BOX(char *);
+
+extern char *CAT(const char *, ...);
+extern char *GET_PATH(char *, ...);
+extern char *INT_TO_STR(int);
+
+extern boolean STRING_IS_LIKE(char *, char *);
+
+extern int FILE_GET(FILE *, int, void *, int);
+extern int FILE_PUT(FILE *, int, void *, int);
+
+/* this is just a workaround -- handle array definitions later */
+extern void *Array(int, ...);
+
+/* VB functions that do not return "int" (and would cause compiler errors) */
+extern double Val(char *);
+extern char *Left(char *, int);
+extern char *left(char *, int);
+extern char *Right(char *, int);
+extern char *right(char *, int);
+extern char *StrReverse(char *);
+extern int InStr(int, char *, char *);
+extern char *Dir(char *);
+extern char *Dir_Without_Args();
+extern void Kill(char *);
+extern char *Chr(int);
+extern char *String(int, char *);
+extern void MkDir(char *);
+extern char *SlashLess(char *);
+extern char *Hex(int);
+
+extern int FileLen(char *);
+
+extern long GetTickCount();
+
+extern int GetAttr(char *);
+
+extern void DoEvents();
+
+extern void SaveSetting(const char *, const char *, char *, int);
+
+extern long GetTempPath(long, char *);
+
+#endif /* VB_LIB_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// vb_types.h
+// ----------------------------------------------------------------------------
+
+#ifndef VB_TYPES_H
+#define VB_TYPES_H
+
+#include "../libgame/types.h"
+
+
+#if 0
+typedef unsigned char boolean;
+#endif
+
+typedef double currency;
+
+#if 0
+#if !defined(PLATFORM_WIN32)
+typedef unsigned char byte;
+#endif
+#endif
+
+typedef int Variant;
+
+typedef struct
+{
+ int hWnd;
+} Object;
+
+#ifndef HAS_RECT
+typedef struct
+{
+ int left;
+ int top;
+ int right;
+ int bottom;
+} RECT;
+#define HAS_RECT
+#endif
+
+typedef struct
+{
+ char *Path;
+} vb_App;
+
+typedef struct
+{
+ void (*Assert)(boolean);
+ void (*Print)(char *);
+} vb_Debug;
+
+typedef struct
+{
+ int Number;
+ void (*Raise)(int, char *, char *);
+} vb_Err;
+
+typedef struct
+{
+ int Width;
+ int Height;
+
+ int ScaleWidth;
+ int ScaleHeight;
+ int ScaleMode;
+
+ int Orientation;
+
+ int TwipsPerPixelX;
+ int TwipsPerPixelY;
+
+ int hWnd;
+
+ int (*ScaleX)(int, int, int);
+ int (*ScaleY)(int, int, int);
+} vb_Generic_Device;
+
+typedef vb_Generic_Device vb_Screen;
+
+typedef vb_Generic_Device Form;
+typedef vb_Generic_Device Picture;
+typedef vb_Generic_Device IPicture;
+typedef vb_Generic_Device Printer;
+
+typedef struct
+{
+ int lCaps;
+} vb_Caps;
+
+typedef struct
+{
+ int LWidth;
+ int LHeight;
+ int lFlags;
+ vb_Caps ddsCaps;
+} DDSURFACEDESC2;
+
+typedef struct
+{
+ void (*SetHWnd)(long);
+} DirectDrawClipper;
+
+typedef struct
+{
+ boolean (*isLost)(void);
+ void (*GetSurfaceDesc)(DDSURFACEDESC2);
+ void (*SetClipper)(DirectDrawClipper);
+ // long (*Blt)(RECT, DirectDrawSurface7, RECT, int);
+ void (*BltColorFill)(RECT, int);
+} DirectDrawSurface7;
+
+typedef struct
+{
+ DirectDrawSurface7 (*CreateSurface)(DDSURFACEDESC2);
+ DirectDrawSurface7 (*CreateSurfaceFromFile)(char *, DDSURFACEDESC2);
+ void (*SetCooperativeLevel)(int, int);
+ DirectDrawClipper (*CreateClipper)(int);
+ void (*RestoreAllSurfaces)(void);
+} DirectDraw7;
+
+typedef struct
+{
+ int lFlags;
+} DSBUFFERDESC;
+
+typedef struct
+{
+ int nFormatTag;
+ int nChannels;
+ int lSamplesPerSec;
+ int nBitsPerSample;
+ int nBlockAlign;
+ int lAvgBytesPerSec;
+} WAVEFORMATEX;
+
+typedef struct
+{
+ int (*GetStatus)(void);
+ void (*Play)(int);
+} DirectSoundBuffer;
+
+typedef struct
+{
+ void (*SetCooperativeLevel)(long, int);
+ DirectSoundBuffer (*CreateSoundBufferFromFile)(char *, DSBUFFERDESC, WAVEFORMATEX);
+} DirectSound;
+
+typedef struct
+{
+ DirectDraw7 (*DirectDrawCreate)(char *);
+ DirectSound (*DirectSoundCreate)(char *);
+ void (*GetWindowRect)(long, RECT);
+} DirectX7;
+
+typedef struct
+{
+ int Left;
+ int Top;
+ void (*RefreshMarker)(void);
+} MarkerObject;
+
+typedef struct
+{
+ void (*DelayMS)(long, boolean);
+ double (*TickDiffUS)(double);
+ double TickNow;
+} TickCountObject;
+
+typedef struct
+{
+ int Caption;
+ void (*Refresh)(void);
+} MainForm_lblCount;
+
+typedef struct
+{
+ boolean Checked;
+ boolean Enabled;
+} MainForm_men;
+
+typedef struct
+{
+ int Width;
+ int Height;
+ void (*Line)(int, int, int, int, int, int);
+} MainForm_picPane;
+
+typedef struct
+{
+ MainForm_lblCount lblInfoCount;
+ MainForm_lblCount lblRedDiskCount;
+ void (*DisplayLevel)(void);
+ void (*DrawField)(int, int);
+ MainForm_men menGravOn;
+ MainForm_men menZonkOn;
+ MainForm_men menEnOn;
+ MainForm_men menGravOff;
+ MainForm_men menZonkOff;
+ MainForm_men menEnOff;
+ MainForm_men menRemSP;
+ MainForm_men menSP;
+ char *Caption;
+ boolean PanelVisible;
+ void (*ShowKey)(int);
+ void (*SaveSnapshot)(int);
+ void (*menStop_Click)(void);
+ MainForm_picPane picPane;
+ char *lblFrameCount;
+ void (*SetDisplayRegion)(void);
+} MainFormObject;
+
+typedef struct
+{
+ int DestXOff;
+ int DestYOff;
+
+ void (*Blt)();
+ void (*ScrollTo)(int, int);
+ void (*ScrollTowards)(int, int, double);
+ void (*SoftScrollTo)(int, int, long, int);
+
+} DDScrollBuffer;
+
+typedef struct
+{
+ void (*BltEx)(int, int, int);
+} DDSpriteBuffer;
+
+typedef struct
+{
+ void (*CreateAtSize)(long, long, long);
+ void (*Let_Palette)(long, long);
+ void (*Let_ColorIndex)(long, long, long);
+} BitMapObject;
+
+struct DemoBufferObject
+{
+ int Size;
+ byte CheckSumByte;
+ void (*SetSubBuffer)(struct DemoBufferObject *);
+ void (*AddDemoKey)(int);
+ boolean (*Serialize)(FILE *);
+};
+typedef struct DemoBufferObject DemoBufferObject;
+
+typedef struct
+{
+ int (*Read)(char *ValName, int Default);
+ void (*Save)(char *ValName, int Val);
+} SettingsObject;
+
+typedef struct
+{
+ int left;
+ int top;
+ int ListIndex;
+ char (*List)(int);
+} cmbFileObject;
+
+typedef struct
+{
+ int Width;
+ int Height;
+ boolean Visible;
+ void (*Move)(int, int, int);
+} shpProgressObject;
+
+typedef struct
+{
+ int left;
+ int Top;
+ int Width;
+ int Height;
+} lblFrameCountObject;
+
+typedef struct
+{
+ boolean Checked;
+} menBorderObject;
+
+#endif /* VB_TYPES_H */
--- /dev/null
+// ----------------------------------------------------------------------------
+// vb_vars.c
+// ----------------------------------------------------------------------------
+
+#include "vb_types.h"
+#include "vb_defs.h"
+#include "vb_vars.h"
+#include "vb_lib.h"
+
+vb_App App;
+vb_Err Err;
+MainFormObject MainForm;
+lblFrameCountObject lblFrameCount;
+cmbFileObject cmbFile;
+shpProgressObject shpProgress;
--- /dev/null
+// ----------------------------------------------------------------------------
+// vb_vars.h
+// ----------------------------------------------------------------------------
+
+#ifndef VB_VARS_H
+#define VB_VARS_H
+
+extern vb_Screen Screen;
+extern vb_Debug Debug;
+extern vb_Err Err;
+extern vb_App App;
+
+extern DemoBufferObject VB_OBJECT_SELF;
+
+extern MainFormObject MainForm;
+extern cmbFileObject cmbFile;
+extern shpProgressObject shpProgress;
+extern lblFrameCountObject lblFrameCount;
+extern menBorderObject menBorder;
+
+extern int hWnd;
+
+#endif /* VB_VARS_H */
#include "libgame/libgame.h"
#include "game_em/game_em.h"
+#include "game_sp/game_sp.h"
#include "conf_gfx.h" /* include auto-generated data structure definitions */
#include "conf_snd.h" /* include auto-generated data structure definitions */
#define PROGRAM_VERSION_MAJOR 3
#define PROGRAM_VERSION_MINOR 2
#define PROGRAM_VERSION_PATCH 6
-#define PROGRAM_VERSION_BUILD 1
+#define PROGRAM_VERSION_BUILD 2
#define PROGRAM_TITLE_STRING "Rocks'n'Diamonds"
#define PROGRAM_AUTHOR_STRING "Holger Schemel"
-#define PROGRAM_COPYRIGHT_STRING "Copyright ©1995-2008 by Holger Schemel"
+#define PROGRAM_COPYRIGHT_STRING "Copyright ©1995-2009 by Holger Schemel"
#define PROGRAM_EMAIL_STRING "info@artsoft.org"
#define PROGRAM_WEBSITE_STRING "http://www.artsoft.org/"
#define PROGRAM_GAME_BY_STRING "A Game by Artsoft Entertainment"
#define GAME_ENGINE_TYPE_UNKNOWN LEVEL_FILE_TYPE_UNKNOWN
#define GAME_ENGINE_TYPE_RND LEVEL_FILE_TYPE_RND
#define GAME_ENGINE_TYPE_EM LEVEL_FILE_TYPE_EM
+#define GAME_ENGINE_TYPE_SP LEVEL_FILE_TYPE_SP
-#define NUM_ENGINE_TYPES 3
+#define NUM_ENGINE_TYPES 4
struct BorderInfo