rnd-20040814-1-src
authorHolger Schemel <info@artsoft.org>
Sat, 14 Aug 2004 20:58:59 +0000 (22:58 +0200)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:47:38 +0000 (10:47 +0200)
26 files changed:
Makefile
src/Makefile
src/conftime.h
src/editor.c
src/libem/Makefile [new file with mode: 0644]
src/libem/cave.c [new file with mode: 0644]
src/libem/convert.c [new file with mode: 0644]
src/libem/display.h [new file with mode: 0644]
src/libem/file.h [new file with mode: 0644]
src/libem/global.h [new file with mode: 0644]
src/libem/graphics.c [new file with mode: 0644]
src/libem/init.c [new file with mode: 0644]
src/libem/input.c [new file with mode: 0644]
src/libem/level.h [new file with mode: 0644]
src/libem/main.c [new file with mode: 0644]
src/libem/sample.h [new file with mode: 0644]
src/libem/sound.c [new file with mode: 0644]
src/libem/synchro_1.c [new file with mode: 0644]
src/libem/synchro_2.c [new file with mode: 0644]
src/libem/synchro_3.c [new file with mode: 0644]
src/libem/tab_generate.c [new file with mode: 0644]
src/libem/tile.h [new file with mode: 0644]
src/libem/ulaw_generate.c [new file with mode: 0644]
src/libgame/platform.h
src/main.c
src/main.h

index 9f1e23217da1495a982230cd6eeef1709feea2a5..85f0afe46fbe09ddf79b14a41cac418b09c0e6c5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -50,8 +50,8 @@ CROSS_PATH_WIN32=/usr/local/cross-tools/i386-mingw32msvc
 SRC_DIR = src
 MAKE_CMD = $(MAKE) -C $(SRC_DIR)
 
-DEFAULT_TARGET = x11
-DEFAULT_TARGET = sdl
+DEFAULT_TARGET = x11
+DEFAULT_TARGET = sdl
 
 
 # -----------------------------------------------------------------------------
index fed7f7ce6eb8ff60fb81a37ba5a6260747905f2e..5caa60517aa142ab82cb304ed88903d4f7a39e2c 100644 (file)
@@ -22,7 +22,9 @@ ifdef X11_PATH                        # path to X11 specified by top level Makefile
 XINC_PATH = $(X11_PATH)/include
 XLIB_PATH = $(X11_PATH)/lib
 X11_INCL = -I$(XINC_PATH)
-X11_LIBS = -L$(XLIB_PATH) -lX11
+# X11_LIBS = -L$(XLIB_PATH) -lX11
+# !!! remove Xpm dependency !!!
+X11_LIBS = -L$(XLIB_PATH) -lX11 -lXpm
 endif
 
 AR = ar
@@ -194,8 +196,13 @@ CNFS_CMD = ../Scripts/create_element_defs.pl
 
 TIMESTAMP_FILE = conftime.h
 
-LIBDIR = libgame
-LIBGAME = $(LIBDIR)/libgame.a
+LIBGAMEDIR = libgame
+LIBGAME = $(LIBGAMEDIR)/libgame.a
+
+LIBEMDIR = libem
+LIBEM = $(LIBEMDIR)/libem.a
+
+RNDLIBS = $(LIBGAME) $(LIBEM)
 
 ICONBASE = windows_icon
 ifeq ($(PLATFORM),cross-win32)
@@ -208,15 +215,20 @@ endif
 # build targets
 # -----------------------------------------------------------------------------
 
-all: libgame_dir $(PROGNAME)
+all: libgame_dir libem_dir $(PROGNAME)
 
-$(PROGNAME): $(LIBGAME) $(TIMESTAMP_FILE) $(OBJS) $(ICON)
-       $(CC) $(PROFILING) $(OBJS) $(ICON) $(LIBGAME) $(LDFLAGS) -o $(PROGNAME)
+$(PROGNAME): $(RNDLIBS) $(TIMESTAMP_FILE) $(OBJS) $(ICON)
+       $(CC) $(PROFILING) $(OBJS) $(ICON) $(RNDLIBS) $(LDFLAGS) -o $(PROGNAME)
 
 libgame_dir:
-       @$(MAKE) -C $(LIBDIR)
+       @$(MAKE) -C $(LIBGAMEDIR)
 $(LIBGAME):
-       @$(MAKE) -C $(LIBDIR)
+       @$(MAKE) -C $(LIBGAMEDIR)
+
+libem_dir:
+       @$(MAKE) -C $(LIBEMDIR)
+$(LIBEM):
+       @$(MAKE) -C $(LIBEMDIR)
 
 auto-conf:
        @for i in $(CNFS); do                   \
@@ -233,7 +245,7 @@ conf_snd.h: conf_snd.c
 conf_mus.h: conf_mus.c
        @$(MAKE) auto-conf
 
-$(TIMESTAMP_FILE): $(SRCS) $(LIBGAME)
+$(TIMESTAMP_FILE): $(SRCS) $(LIBGAME) $(LIBEM)
        @date '+"[%Y-%m-%d %H:%M]"' \
        | sed -e 's/^/#define COMPILE_DATE_STRING /' \
        > $(TIMESTAMP_FILE)
@@ -246,9 +258,11 @@ $(ICON):
        $(CC) $(PROFILING) $(CFLAGS) -c $*.c
 
 clean-obj:
-       $(MAKE) -C $(LIBDIR) clean
+       $(MAKE) -C $(LIBGAMEDIR) clean
+       $(MAKE) -C $(LIBEMDIR) clean
        $(RM) $(OBJS)
        $(RM) $(LIBGAME)
+       $(RM) $(LIBEM)
 
 clean-ico:
        $(RM) $(ICONBASE).ico
@@ -268,7 +282,8 @@ clean: clean-obj clean-ico clean-bin
 dist-clean: clean-obj
 
 depend:
-       $(MAKE) -C $(LIBDIR) depend
+       $(MAKE) -C $(LIBGAMEDIR) depend
+       $(MAKE) -C $(LIBEMDIR) depend
        for i in $(SRCS); do $(CPP) $(CFLAGS) -M $$i; done > .depend
 
 ifeq (.depend,$(wildcard .depend))
index 0515c7cc599b4d9be877c2146d5c8ba3005a3bfb..d8ec00d9ee61798ebef33fd2a6909b491d437116 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2004-08-07 15:46]"
+#define COMPILE_DATE_STRING "[2004-08-14 22:53]"
index de334bb5241a7d9966b7deb138afdd1f8a24c4a5..5856c35a9dcdbc49197780ff426022dd7a8d4762 100644 (file)
@@ -1358,9 +1358,11 @@ static struct ValueTextInfo options_change_direct_action[] =
 #else
   { CE_HITTING_SOMETHING,      "collision"                     },
 #endif
-#if 1
+
+#if 0
   { CE_BLOCKED,                        "blocked"                       },
 #endif
+
   { CE_IMPACT,                 "impact (on something)"         },
   { CE_SMASHED,                        "smashed (from above)"          },
 
diff --git a/src/libem/Makefile b/src/libem/Makefile
new file mode 100644 (file)
index 0000000..489737a
--- /dev/null
@@ -0,0 +1,69 @@
+# =============================================================================
+# Rocks'n'Diamonds Makefile (libem)
+# -----------------------------------------------------------------------------
+# (c) 1995-2004 Holger Schemel <info@artsoft.org>
+# -----------------------------------------------------------------------------
+# Emerald Mine for X11 © 2000,2001 David Tritscher
+# =============================================================================
+
+# -----------------------------------------------------------------------------
+# configuration
+# -----------------------------------------------------------------------------
+
+SRCS = cave.c          \
+       convert.c       \
+       graphics.c      \
+       init.c          \
+       input.c         \
+       main.c          \
+       sound.c         \
+       synchro_1.c     \
+       synchro_2.c     \
+       synchro_3.c     \
+       tab_generate.c  \
+       ulaw_generate.c
+
+OBJS = cave.o          \
+       convert.o       \
+       graphics.o      \
+       init.o          \
+       input.o         \
+       main.o          \
+       sound.o         \
+       synchro_1.o     \
+       synchro_2.o     \
+       synchro_3.o     \
+       tab_generate.o  \
+       ulaw_generate.o
+
+LIBEM = libem.a
+
+
+# -----------------------------------------------------------------------------
+# build targets
+# -----------------------------------------------------------------------------
+
+all: $(LIBEM)
+
+$(LIBEM): $(OBJS)
+       $(AR) cru $(LIBEM) $(OBJS)
+       $(RANLIB) $(LIBEM)
+
+.c.o:
+       $(CC) $(PROFILING) $(CFLAGS) -c $*.c
+
+clean:
+       $(RM) $(OBJS)
+       $(RM) $(LIBEM)
+
+
+# -----------------------------------------------------------------------------
+# development only
+# -----------------------------------------------------------------------------
+
+depend:
+       for i in $(SRCS); do $(CPP) $(CFLAGS) -M $$i; done > .depend
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/src/libem/cave.c b/src/libem/cave.c
new file mode 100644 (file)
index 0000000..25de9a5
--- /dev/null
@@ -0,0 +1,149 @@
+/* 2000-08-10T16:43:50Z
+ *
+ * cave data structures
+ */
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "global.h"
+#include "tile.h"
+#include "level.h"
+#include "file.h"
+
+struct cave_node *cave_list;
+
+static void clear(void);
+
+/* attempt load a cave
+ * 
+ * completely initializes the level structure, ready for a game
+ */
+int cave_convert(char *filename)
+{
+       int result;
+       FILE *file;
+       int actual;
+       unsigned long length;
+       unsigned char buffer[16384];
+
+       clear();
+
+       file = fopen(filename, "rb");
+       if(file == 0) {
+               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, filename, "open error", strerror(errno));
+               result = 1;
+               goto fail;
+       }
+       actual = fread(buffer, 1, 16384, file);
+       if(actual == -1) {
+               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, filename, "read error", strerror(errno));
+               result = 1;
+               goto fail;
+       }
+       length = actual;
+       fclose(file);
+       file = 0;
+
+       if(clean_emerald(buffer, &length)) {
+               fprintf(stderr, "%s: \"%s\": %s\n", progname, filename, "unrecognized format");
+               result = 1; goto fail;
+       }
+       convert_emerald(buffer);
+
+       result = 0;
+fail:
+       if(file) fclose(file);
+       return(result);
+}
+
+static void clear(void)
+{
+       lev.home = 1; /* number of players */
+       lev.width = 0;
+       lev.height = 0;
+       lev.time = 0;
+       lev.required = 0;
+       lev.score = 0;
+
+       ply1.num = 0;
+       ply1.alive = (lev.home >= 1);
+       ply1.dynamite = 0;
+       ply1.dynamite_cnt = 0;
+       ply1.keys = 0;
+       ply1.anim = 0;
+       ply1.oldx = ply1.x = 0;
+       ply1.oldy = ply1.y = 0;
+       ply1.joy_n = ply1.joy_e = ply1.joy_s = ply1.joy_w = ply1.joy_fire = ply1.joy_stick = ply1.joy_spin = 0;
+       ply2.num = 1;
+       ply2.alive = (lev.home >= 2);
+       ply2.dynamite = 0;
+       ply2.dynamite_cnt = 0;
+       ply2.keys = 0;
+       ply2.anim = 0;
+       ply2.oldx = ply2.x = 0;
+       ply2.oldy = ply2.y = 0;
+       ply2.joy_n = ply2.joy_e = ply2.joy_s = ply2.joy_w = ply2.joy_fire = ply2.joy_stick = ply2.joy_spin = 0;
+}
+
+void read_cave_list(void)
+{
+       char name[MAXNAME+2];
+       struct cave_node *node, **prev;
+       DIR *dir;
+       struct dirent *entry;
+       char *cut;
+       int len;
+
+       free_cave_list(); /* delete old list if i forgot to before */
+
+       name[MAXNAME] = 0;
+       if(arg_basedir) {
+               snprintf(name, MAXNAME+2, "%s/%s", arg_basedir, EM_LVL_DIR);
+       } else {
+               snprintf(name, MAXNAME+2, "%s", EM_LVL_DIR);
+       }
+       if(name[MAXNAME]) snprintf_overflow("read cave/ directory");
+
+       dir = opendir(name);
+       if(dir) {
+               prev = &cave_list;
+               while((entry = readdir(dir))) {
+                       if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
+
+                       node = malloc(sizeof(*node)); if(node == 0) break;
+                       *prev = node; prev = &node->next;
+
+                       node->path[MAXNAME] = 0;
+                       snprintf(node->path, MAXNAME+2, "%s/%s", name, entry->d_name);
+                       if(node->path[MAXNAME]) snprintf_overflow("read cave/ directory");
+
+                       cut = strrchr(node->path, '/'); cut = cut ? cut + 1 : node->path;
+                       len = strlen(cut);
+                       if(len <= 32) {
+                               strncpy(node->name, cut, 32);
+                       } else {
+                               snprintf(node->name, 32, "%.8s..%s", cut, cut + len - 16);
+                       }
+               }
+               *prev = 0;
+               closedir(dir);
+       } else {
+               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, name, "failed to open directory", strerror(errno));
+       }
+}
+
+void free_cave_list(void)
+{
+       struct cave_node *node, *next;
+
+       for(node = cave_list; node; node = next) {
+               next = node->next;
+               free(node);
+       }
+       cave_list = 0;
+}
diff --git a/src/libem/convert.c b/src/libem/convert.c
new file mode 100644 (file)
index 0000000..fdd5853
--- /dev/null
@@ -0,0 +1,393 @@
+/* 2000-08-20T09:41:18Z
+ *
+ * identify all emerald mine caves and turn them into v6 format.
+ * fixes illegal tiles, acid, wheel, limits times, cleans flags.
+ *
+ * these tables weed out bad tiles for older caves (eg. wheel on -> wheel off)
+ * and clean up v6 caves (acid, number limits) which should(!) be inconsequential,
+ * but no doubt it will break some caves.
+ */
+static unsigned char remap_v6[256] = { /* filter crap for v6 */
+       0,0,2,2,4,4,118,118,8,9,10,11,12,13,14,15,16,16,18,18,20,21,22,23,24,25,26,27,28,
+       28,118,28,0,16,2,18,36,37,37,37,40,41,42,43,44,45,128,128,128,148,148,148,45,45,45,
+       148,0,57,58,59,60,61,62,63,64,65,66,67,68,69,69,69,69,73,74,75,118,75,75,75,75,75,
+       75,75,75,153,153,153,153,153,153,153,153,153,153,153,153,153,153,99,100,68,68,68,
+       68,68,68,68,68,118,118,118,118,118,114,115,131,118,118,119,120,121,122,118,118,118,
+       118,118,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,
+       147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,165,118,
+       168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,
+       189,68,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,
+       210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,
+       231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,153,153,153,153,153,153,
+       153,153,153,153
+};
+static unsigned char remap_v5[256] = { /* filter crap for v5 */
+       0,0,2,2,4,4,118,118,8,9,10,11,12,13,14,15,16,16,18,18,20,21,22,23,24,25,26,27,28,
+       28,118,28,0,16,2,18,36,37,37,37,147,41,42,43,44,45,128,128,128,148,148,148,45,45,
+       45,148,0,57,58,59,60,61,62,63,64,65,66,67,68,153,153,153,153,153,153,153,153,153,
+       153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+       153,153,68,68,68,68,68,68,68,68,118,118,118,118,118,114,115,131,118,118,119,120,121,
+       122,118,118,118,118,118,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,
+       143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,153,153,153,
+       153,153,153,118,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,
+       185,186,187,188,189,68,153,153,153,153,153,153,153,153,153,200,201,202,203,204,205,
+       206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,
+       227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,153,153,153,153,153,153,
+       153,153,153,153,153,153,153,153
+};
+static unsigned char remap_v4[256] = { /* filter crap for v4 */
+       0,0,2,2,4,4,118,118,8,9,10,11,12,13,14,15,16,16,18,18,20,21,22,23,24,25,26,27,28,
+       28,118,28,0,16,2,18,36,37,37,37,147,41,42,43,44,45,128,128,128,148,148,148,45,45,
+       45,148,0,153,153,59,60,61,62,63,64,65,66,153,153,153,153,153,153,153,153,153,153,
+       153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,
+       153,153,153,153,153,153,153,153,153,153,153,153,153,153,153,118,114,115,131,118,118,
+       119,120,121,122,118,118,118,118,118,128,129,130,131,132,133,134,135,136,137,138,139,
+       140,141,142,143,144,145,146,147,148,149,150,151,152,68,154,155,156,157,158,160,160,
+       160,160,160,160,160,160,160,160,160,160,160,160,160,160,175,153,153,153,153,153,153,
+       153,153,153,153,153,153,153,153,68,153,153,153,153,153,153,153,153,153,200,201,202,
+       203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
+       224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,153,153,153,
+       153,153,153,153,153,153,153,153,153,153,153
+};
+static unsigned char remap_v4eater[28] = { /* filter crap for v4 */
+       128,18,2,0,4,8,16,20,28,37,41,45,130,129,131,132,133,134,135,136,146,147,175,65,66,
+       64,2,18
+};
+
+int clean_emerald(unsigned char *src, unsigned long *length)
+{
+       unsigned int i;
+       if(*length >= 2172 && src[2106] == 255 && src[2107] == 54 && src[2108] == 48 && src[2109] == 48) {
+               for(i = 0; i < 2048; i++) src[i] = remap_v6[src[i]];
+               for(i = 2048; i < 2084; i++) src[i] = remap_v6[src[i]];
+               for(i = 2112; i < 2148; i++) src[i] = remap_v6[src[i]];
+               goto v6;
+       }
+       if(*length >= 2110 && src[2106] == 255 && src[2107] == 53 && src[2108] == 48 && src[2109] == 48) {
+               for(i = 0; i < 2048; i++) src[i] = remap_v5[src[i]];
+               for(i = 2048; i < 2084; i++) src[i] = remap_v5[src[i]];
+               for(i = 2112; i < 2148; i++) src[i] = src[i - 64];
+               goto v5;
+       }
+       if(*length >= 2106 && src[1983] == 116) {
+               for(i = 0; i < 2048; i++) src[i] = remap_v4[src[i]];
+               for(i = 2048; i < 2084; i++) src[i] = remap_v4eater[src[i] >= 28 ? 0 : src[i]];
+               for(i = 2112; i < 2148; i++) src[i] = src[i - 64];
+               goto v4;
+       }
+       if(*length >= 2106 && src[0] == 241 && src[1983] == 27) {
+               unsigned char j = 94;
+               for(i = 0; i < 2106; i++) src[i] = (src[i] ^ (j += 7)) - 0x11;
+               src[1] = 131;
+               for(i = 0; i < 2048; i++) src[i] = remap_v4[src[i]];
+               for(i = 2048; i < 2084; i++) src[i] = remap_v4eater[src[i] >= 28 ? 0 : src[i]];
+               for(i = 2112; i < 2148; i++) src[i] = src[i - 64];
+               goto v3;
+       }
+       return(1); /* unrecognized cave */
+v3:
+v4:
+v5:
+       src[2106] = 255; src[2107] = 54; src[2108] = 48; src[2109] = 48; /* id */
+       i = src[2094] * 10; src[2110] = i >> 8; src[2111] = i; /* time */
+       for(i = 2148; i < 2172; i++) src[i] = 0;
+       src[2159] = 128; /* ball data */
+v6:
+       for(i = 0; i < 2048; i++) if(src[i] == 40) break; /* fix wheel */
+       for(i++; i < 2048; i++) if(src[i] == 40) src[i] = 147;
+       for(i = 64; i < 2048; i++) if(src[i] == 63) src[i - 64] = 101; /* fix acid */
+       for(i = 2051; i < 2057; i++) if(src[i] == 63) src[i - 3] = 101; /* fix acid in eater 1 */
+       for(i = 2060; i < 2066; i++) if(src[i] == 63) src[i - 3] = 101; /* fix acid in eater 2 */
+       for(i = 2069; i < 2075; i++) if(src[i] == 63) src[i - 3] = 101; /* fix acid in eater 3 */
+       for(i = 2078; i < 2084; i++) if(src[i] == 63) src[i - 3] = 101; /* fix acid in eater 4 */
+       for(i = 2115; i < 2121; i++) if(src[i] == 63) src[i - 3] = 101; /* fix acid in eater 5 */
+       for(i = 2124; i < 2130; i++) if(src[i] == 63) src[i - 3] = 101; /* fix acid in eater 6 */
+       for(i = 2133; i < 2139; i++) if(src[i] == 63) src[i - 3] = 101; /* fix acid in eater 7 */
+       for(i = 2142; i < 2148; i++) if(src[i] == 63) src[i - 3] = 101; /* fix acid in eater 8 */
+       src[2094] = 0; /* old style time */
+       src[2096] &= 7; src[src[2096] << 8 | src[2097]] = 128; /* player 1 pos */
+       src[2098] &= 7; src[src[2098] << 8 | src[2099]] = 128; /* player 2 pos */
+       if((src[2100] << 8 | src[2101]) > 9999) { src[2100] = 39; src[2101] = 15; } /* ameuba speed */
+       if((src[2102] << 8 | src[2103]) > 9999) { src[2102] = 39; src[2103] = 15; } /* time wonderwall */
+       if((src[2110] << 8 | src[2111]) > 9999) { src[2110] = 39; src[2111] = 15; } /* time */
+       i = src[2149]; i &= 15; i &= -i; src[2149] = i; /* wind direction */
+       if((src[2154] << 8 | src[2155]) > 9999) { src[2154] = 39; src[2155] = 15; } /* time lenses */
+       if((src[2156] << 8 | src[2157]) > 9999) { src[2156] = 39; src[2157] = 15; } /* time magnify */
+       src[2158] = 0; src[2159] = remap_v6[src[2159]]; /* ball object */
+       if((src[2160] << 8 | src[2161]) > 9999) { src[2160] = 39; src[2161] = 15; } /* ball pause */
+       src[2162] &= 129; if(src[2162] & 1) src[2163] = 0; /* ball data */
+       if((src[2164] << 8 | src[2165]) > 9999) { src[2164] = 39; src[2165] = 15; } /* android move pause */
+       if((src[2166] << 8 | src[2167]) > 9999) { src[2166] = 39; src[2167] = 15; } /* android clone pause */
+       src[2168] &= 31; /* android data */
+
+       *length = 2172; /* size of v6 cave */
+       return(0);
+}
+
+/* 2000-07-30T00:26:00Z
+ *
+ * Read emerald mine caves version 6
+ * 
+ * v4 and v5 emerald mine caves are converted to v6 (which completely supports older versions)
+ * 
+ * converting to the internal format loses /significant/ information which can breaks lots of caves.
+ * 
+ * major incompatibilities:
+ * borderless caves behave completely differently, the player no longer "warps" to the other side.
+ * a compile time option for spring can make it behave differently when it rolls.
+ * a compile time option for rolling objects (stone, nut, spring, bomb) only in eater.
+ * acid is always deadly even with no base beneath it.
+ *
+ * so far all below have not broken any caves:
+ *
+ * active wheel inside an eater will not function, eater explosions will not change settings.
+ * initial collect objects (emerald, diamond, dynamite) dont exist.
+ * initial rolling objects will be moved manually and made into sitting objects.
+ * drips always appear from dots.
+ * more than one thing can fall into acid at the same time.
+ * acid explodes when the player walks into it, rather than splashing.
+ * simultaneous explosions may be in a slightly different order.
+ * quicksand states have been reduced.
+ * acid base is effectively an indestructable wall now which can affect eater explosions.
+ * android can clone forever with a clone pause of 0 (emeralds, diamonds, nuts, stones, bombs, springs).
+ *
+ * 2001-03-12T02:46:55Z
+ *   rolling stuff is now allowed in the cave, i didn't like making this decision.
+ *   if BAD_ROLL is not defined, initial rolling objects are moved by hand.
+ *   initial collect objects break some cave in elvis mine 5.
+ *   different timing for wonderwall break some cave in exception mine 2.
+ *   i think i'm pretty locked into always using the bad roll. *sigh*
+ *   rolling spring is now turned into regular spring. it appears the emc editor only uses
+ *   the force code for initially moving spring. i will follow this in my editor.
+ */
+
+#include "tile.h"
+#include "level.h"
+
+static unsigned short remap_emerald[256] = {
+       Xstone, Xstone, Xdiamond, Xdiamond, Xalien, Xalien, Xblank, Xblank,
+       Xtank_n, Xtank_e, Xtank_s, Xtank_w, Xtank_gon, Xtank_goe, Xtank_gos, Xtank_gow,
+       Xbomb, Xbomb, Xemerald, Xemerald, Xbug_n, Xbug_e, Xbug_s, Xbug_w,
+       Xbug_gon, Xbug_goe, Xbug_gos, Xbug_gow, Xdrip_eat, Xdrip_eat, Xdrip_eat, Xdrip_eat,
+       Xstone, Xbomb, Xdiamond, Xemerald, Xwonderwall, Xnut, Xnut, Xnut,
+       Xwheel, Xeater_n, Xeater_s, Xeater_w, Xeater_e, Xsand_stone, Xblank, Xblank,
+       Xblank, Xsand, Xsand, Xsand, Xsand_stone, Xsand_stone, Xsand_stone, Xsand,
+       Xstone, Xgrow_ew, Xgrow_ns, Xdynamite_1, Xdynamite_2, Xdynamite_3, Xdynamite_4, Xacid_s,
+       Xexit_1, Xexit_2, Xexit_3, Xballoon, Xplant, Xspring, Xspring, Xspring,
+       Xspring, Xball_1, Xball_2, Xandroid, Xblank, Xandroid, Xandroid, Xandroid,
+       Xandroid, Xandroid, Xandroid, Xandroid, Xandroid, Xblank, Xblank, Xblank,
+       Xblank, Xblank, Xblank, Xblank, Xblank, Xblank, Xblank, Xblank,
+#ifdef BAD_ROLL
+       Xblank, Xblank, Xblank, Xspring_force_w, Xspring_force_e, Xacid_1, Xacid_2, Xacid_3,
+       Xacid_4, Xacid_5, Xacid_6, Xacid_7, Xacid_8, Xblank, Xblank, Xblank,
+       Xblank, Xblank, Xnut_force_w, Xnut_force_e, Xsteel_1, Xblank, Xblank, Xbomb_force_w,
+       Xbomb_force_e, Xstone_force_w, Xstone_force_e, Xblank, Xblank, Xblank, Xblank, Xblank,
+#else
+       Xblank, Xblank, Xblank, Xspring, Xspring, Xacid_1, Xacid_2, Xacid_3,
+       Xacid_4, Xacid_5, Xacid_6, Xacid_7, Xacid_8, Xblank, Xblank, Xblank,
+       Xblank, Xblank, Xnut, Xnut, Xsteel_1, Xblank, Xblank, Xbomb,
+       Xbomb, Xstone, Xstone, Xblank, Xblank, Xblank, Xblank, Xblank,
+#endif
+       Xblank, Xround_wall_1, Xgrass, Xsteel_1, Xwall_1, Xkey_1, Xkey_2, Xkey_3,
+       Xkey_4, Xdoor_1, Xdoor_2, Xdoor_3, Xdoor_4, Xdripper, Xfake_door_1, Xfake_door_2,
+       Xfake_door_3, Xfake_door_4, Xwonderwall, Xwheel, Xsand, Xacid_nw, Xacid_ne, Xacid_sw,
+       Xacid_se, Xfake_blank, Xameuba_1, Xameuba_2, Xameuba_3, Xameuba_4, Xexit, Xalpha_arrow_w,
+       Xfake_grass, Xlenses, Xmagnify, Xfake_blank, Xfake_grass, Xswitch, Xswitch, Xblank,
+       Xdecor_8, Xdecor_9, Xdecor_10, Xdecor_5, Xalpha_comma, Xalpha_quote, Xalpha_minus, Xdynamite,
+       Xsteel_3, Xdecor_6, Xdecor_7, Xsteel_2, Xround_wall_2, Xdecor_2, Xdecor_4, Xdecor_3,
+       Xwind_nesw, Xwind_e, Xwind_s, Xwind_w, Xwind_n, Xdirt, Xplant, Xkey_5,
+       Xkey_6, Xkey_7, Xkey_8, Xdoor_5, Xdoor_6, Xdoor_7, Xdoor_8, Xbumper,
+       Xalpha_a, Xalpha_b, Xalpha_c, Xalpha_d, Xalpha_e, Xalpha_f, Xalpha_g, Xalpha_h,
+       Xalpha_i, Xalpha_j, Xalpha_k, Xalpha_l, Xalpha_m, Xalpha_n, Xalpha_o, Xalpha_p,
+       Xalpha_q, Xalpha_r, Xalpha_s, Xalpha_t, Xalpha_u, Xalpha_v, Xalpha_w, Xalpha_x,
+       Xalpha_y, Xalpha_z, Xalpha_0, Xalpha_1, Xalpha_2, Xalpha_3, Xalpha_4, Xalpha_5,
+       Xalpha_6, Xalpha_7, Xalpha_8, Xalpha_9, Xalpha_perio, Xalpha_excla, Xalpha_colon, Xalpha_quest,
+       Xalpha_arrow_e, Xdecor_1, Xfake_door_5, Xfake_door_6, Xfake_door_7, Xfake_door_8, Xblank, Xblank,
+       Xblank, Xblank, Xblank, Xblank, Xblank, Xblank, Xblank, Xblank,
+};
+
+void convert_emerald(unsigned char *src)
+{
+       unsigned int x, y, temp;
+
+       lev.width = 64;
+       lev.height = 32;
+       temp = ((src[0x83E] << 8 | src[0x83F]) * 25 + 3) / 4; if(temp == 0 || temp > 9999) temp = 9999;
+       lev.time = temp;
+       lev.required = src[0x82F];
+
+       temp = src[0x830] << 8 | src[0x831];
+       ply1.oldx = ply1.x = (temp & 63) + 1;
+       ply1.oldy = ply1.y = (temp >> 6 & 31) + 1;
+       temp = src[0x832] << 8 | src[0x833];
+       ply2.oldx = ply2.x = (temp & 63) + 1;
+       ply2.oldy = ply2.y = (temp >> 6 & 31) + 1;
+
+       lev.alien_score = src[0x826];
+       temp = (src[0x834] << 8 | src[0x835]) * 28; if(temp > 9999) temp = 9999;
+       lev.ameuba_time = temp;
+       lev.android_move_cnt = lev.android_move_time = src[0x874] << 8 | src[0x875];
+       lev.android_clone_cnt = lev.android_clone_time = src[0x876] << 8 | src[0x877];
+       lev.ball_pos = 0;
+       lev.ball_random = src[0x872] & 1 ? 1 : 0;
+       lev.ball_state = src[0x872] & 128 ? 1 : 0;
+       lev.ball_cnt = lev.ball_time = src[0x870] << 8 | src[0x871];
+       lev.bug_score = src[0x828];
+       lev.diamond_score = src[0x825];
+       lev.dynamite_score = src[0x82B];
+       lev.eater_pos = 0;
+       lev.eater_score = src[0x829];
+       lev.emerald_score = src[0x824];
+       lev.exit_score = src[0x82D] * 8 / 5;
+       lev.key_score = src[0x82C];
+       lev.lenses_cnt = 0;
+       lev.lenses_score = src[0x867];
+       lev.lenses_time = src[0x86A] << 8 | src[0x86B];
+       lev.magnify_cnt = 0;
+       lev.magnify_score = src[0x868];
+       lev.magnify_time = src[0x86C] << 8 | src[0x86D];
+       lev.nut_score = src[0x82A];
+       lev.shine_cnt = 0;
+       lev.slurp_score = src[0x869];
+       lev.tank_score = src[0x827];
+       lev.wheel_cnt = 0;
+       lev.wheel_x = 1;
+       lev.wheel_y = 1;
+       lev.wheel_time = src[0x838] << 8 | src[0x839];
+       lev.wind_cnt = src[0x865] & 15 ? 9999 : 0;
+       temp = src[0x865];
+       lev.wind_direction = temp & 8 ? 0 : temp & 1 ? 1 : temp & 2 ? 2 : temp & 4 ? 3 : 0;
+       lev.wind_time = 9999;
+       lev.wonderwall_state = 0;
+       lev.wonderwall_time = src[0x836] << 8 | src[0x837];
+
+       for(x = 0; x < 9; x++) lev.eater_array[0][x] = remap_emerald[src[0x800 + x]];
+       for(x = 0; x < 9; x++) lev.eater_array[1][x] = remap_emerald[src[0x809 + x]];
+       for(x = 0; x < 9; x++) lev.eater_array[2][x] = remap_emerald[src[0x812 + x]];
+       for(x = 0; x < 9; x++) lev.eater_array[3][x] = remap_emerald[src[0x81B + x]];
+       for(x = 0; x < 9; x++) lev.eater_array[4][x] = remap_emerald[src[0x840 + x]];
+       for(x = 0; x < 9; x++) lev.eater_array[5][x] = remap_emerald[src[0x849 + x]];
+       for(x = 0; x < 9; x++) lev.eater_array[6][x] = remap_emerald[src[0x852 + x]];
+       for(x = 0; x < 9; x++) lev.eater_array[7][x] = remap_emerald[src[0x85B + x]];
+       temp = remap_emerald[src[0x86F]];
+       for(y = 0; y < 8; y++) {
+               if(src[0x872] & 1) {
+                       for(x = 0; x < 8; x++) lev.ball_array[y][x] = temp;
+               } else {
+                       lev.ball_array[y][1] = (src[0x873] & 1) ? temp : Xblank; /* north */
+                       lev.ball_array[y][6] = (src[0x873] & 2) ? temp : Xblank; /* south */
+                       lev.ball_array[y][3] = (src[0x873] & 4) ? temp : Xblank; /* west */
+                       lev.ball_array[y][4] = (src[0x873] & 8) ? temp : Xblank; /* east */
+                       lev.ball_array[y][7] = (src[0x873] & 16) ? temp : Xblank; /* south east */
+                       lev.ball_array[y][5] = (src[0x873] & 32) ? temp : Xblank; /* south west */
+                       lev.ball_array[y][2] = (src[0x873] & 64) ? temp : Xblank; /* north east */
+                       lev.ball_array[y][0] = (src[0x873] & 128) ? temp : Xblank; /* north west */
+               }
+       }
+       for(temp = 0; temp < TILE_MAX; temp++) lev.android_array[temp] = Xblank;
+       temp = src[0x878] << 8 | src[0x879];
+       if(temp & 1) {
+               lev.android_array[Xemerald] = lev.android_array[Xemerald_pause] =
+               lev.android_array[Xemerald_fall] = lev.android_array[Yemerald_sB] =
+               lev.android_array[Yemerald_eB] = lev.android_array[Yemerald_wB] = Xemerald;
+       }
+       if(temp & 2) {
+               lev.android_array[Xdiamond] = lev.android_array[Xdiamond_pause] =
+               lev.android_array[Xdiamond_fall] = lev.android_array[Ydiamond_sB] =
+               lev.android_array[Ydiamond_eB] = lev.android_array[Ydiamond_wB] = Xdiamond;
+       }
+       if(temp & 4) {
+               lev.android_array[Xstone] = lev.android_array[Xstone_pause] =
+               lev.android_array[Xstone_fall] = lev.android_array[Ystone_sB] =
+               lev.android_array[Ystone_eB] = lev.android_array[Ystone_wB] = Xstone;
+       }
+       if(temp & 8) {
+               lev.android_array[Xbomb] = lev.android_array[Xbomb_pause] =
+               lev.android_array[Xbomb_fall] = lev.android_array[Ybomb_sB] =
+               lev.android_array[Ybomb_eB] = lev.android_array[Ybomb_wB] = Xbomb;
+       }
+       if(temp & 16) {
+               lev.android_array[Xnut] = lev.android_array[Xnut_pause] =
+               lev.android_array[Xnut_fall] = lev.android_array[Ynut_sB] =
+               lev.android_array[Ynut_eB] = lev.android_array[Ynut_wB] = Xnut;
+       }
+       if(temp & 32) {
+               lev.android_array[Xtank_n] = lev.android_array[Xtank_gon] = lev.android_array[Ytank_nB] =
+               lev.android_array[Ytank_n_e] = lev.android_array[Ytank_n_w] = Xtank_n;
+               lev.android_array[Xtank_e] = lev.android_array[Xtank_goe] = lev.android_array[Ytank_eB] =
+               lev.android_array[Ytank_e_s] = lev.android_array[Ytank_e_n] = Xtank_e;
+               lev.android_array[Xtank_s] = lev.android_array[Xtank_gos] = lev.android_array[Ytank_sB] =
+               lev.android_array[Ytank_s_w] = lev.android_array[Ytank_s_e] = Xtank_s;
+               lev.android_array[Xtank_w] = lev.android_array[Xtank_gow] = lev.android_array[Ytank_wB] =
+               lev.android_array[Ytank_w_n] = lev.android_array[Ytank_w_s] = Xtank_w;
+       }
+       if(temp & 64) {
+               lev.android_array[Xeater_n] = lev.android_array[Yeater_nB] = Xeater_n;
+               lev.android_array[Xeater_e] = lev.android_array[Yeater_eB] = Xeater_e;
+               lev.android_array[Xeater_s] = lev.android_array[Yeater_sB] = Xeater_s;
+               lev.android_array[Xeater_w] = lev.android_array[Yeater_wB] = Xeater_w;
+       }
+       if(temp & 128) {
+               lev.android_array[Xbug_n] = lev.android_array[Xbug_gon] = lev.android_array[Ybug_nB] =
+               lev.android_array[Ybug_n_e] = lev.android_array[Ybug_n_w] = Xbug_gon;
+               lev.android_array[Xbug_e] = lev.android_array[Xbug_goe] = lev.android_array[Ybug_eB] =
+               lev.android_array[Ybug_e_s] = lev.android_array[Ybug_e_n] = Xbug_goe;
+               lev.android_array[Xbug_s] = lev.android_array[Xbug_gos] = lev.android_array[Ybug_sB] =
+               lev.android_array[Ybug_s_w] = lev.android_array[Ybug_s_e] = Xbug_gos;
+               lev.android_array[Xbug_w] = lev.android_array[Xbug_gow] = lev.android_array[Ybug_wB] =
+               lev.android_array[Ybug_w_n] = lev.android_array[Ybug_w_s] = Xbug_gow;
+       }
+       if(temp & 256) {
+               lev.android_array[Xalien] = lev.android_array[Xalien_pause] =
+               lev.android_array[Yalien_nB] = lev.android_array[Yalien_eB] =
+               lev.android_array[Yalien_sB] = lev.android_array[Yalien_wB] = Xalien;
+       }
+       if(temp & 512) {
+               lev.android_array[Xspring] = lev.android_array[Xspring_pause] =
+               lev.android_array[Xspring_e] = lev.android_array[Yspring_eB] = lev.android_array[Yspring_kill_eB] =
+               lev.android_array[Xspring_w] = lev.android_array[Yspring_wB] = lev.android_array[Yspring_kill_wB] =
+               lev.android_array[Xspring_fall] = lev.android_array[Yspring_sB] = Xspring;
+       }
+       if(temp & 1024) {
+               lev.android_array[Yballoon_nB] = lev.android_array[Yballoon_eB] =
+               lev.android_array[Yballoon_sB] = lev.android_array[Yballoon_wB] =
+               lev.android_array[Xballoon] = Xballoon;
+       }
+       if(temp & 2048) {
+               lev.android_array[Xdripper] = lev.android_array[XdripperB] =
+               lev.android_array[Xameuba_1] = lev.android_array[Xameuba_2] =
+               lev.android_array[Xameuba_3] = lev.android_array[Xameuba_4] =
+               lev.android_array[Xameuba_5] = lev.android_array[Xameuba_6] =
+               lev.android_array[Xameuba_7] = lev.android_array[Xameuba_8] = Xdrip_eat;
+       }
+       if(temp & 4096) {
+               lev.android_array[Xdynamite] = Xdynamite;
+       }
+
+       for(temp = 1; temp < 2047; temp++) {
+               switch(src[temp]) {
+               case 0x24: lev.wonderwall_state = 1; lev.wonderwall_time = 9999; break; /* wonderwall */
+               case 0x28: lev.wheel_x = temp & 63; lev.wheel_y = temp >> 6; lev.wheel_cnt = lev.wheel_time; break; /* wheel */
+#ifndef BAD_ROLL
+               case 0x63: src[temp - 1] = 0x45; src[temp] = 0x80; break; /* spring roll left */
+               case 0x64: src[temp + 1] = 0x45; src[temp] = 0x80; break; /* spring roll right */
+               case 0x72: src[temp - 1] = 0x25; src[temp] = 0x80; break; /* nut roll left */
+               case 0x73: src[temp + 1] = 0x25; src[temp] = 0x80; break; /* nut roll right */
+               case 0x77: src[temp - 1] = 0x10; src[temp] = 0x80; break; /* bomb roll left */
+               case 0x78: src[temp + 1] = 0x10; src[temp] = 0x80; break; /* bomb roll right */
+               case 0x79: src[temp - 1] = 0x00; src[temp] = 0x80; break; /* stone roll left */
+               case 0x7A: src[temp + 1] = 0x00; src[temp] = 0x80; break; /* stone roll right */
+#endif
+               case 0xA3: lev.lenses_cnt = 9999; break; /* fake blank */
+               case 0xA4: lev.magnify_cnt = 9999; break; /* fake grass */
+               }
+       }
+       for(y = 0; y < HEIGHT; y++) for(x = 0; x < WIDTH; x++) Cave[y][x] = ZBORDER;
+       temp = 0; for(y = 0; y < lev.height; y++) for(x = 0; x < lev.width; x++) {
+               Cave[y+1][x+1] = remap_emerald[src[temp++]];
+       }
+       if(ply1.alive) Cave[ply1.y][ply1.x] = Zplayer;
+       if(ply2.alive) Cave[ply2.y][ply2.x] = Zplayer;
+       for(y = 0; y < HEIGHT; y++) for(x = 0; x < WIDTH; x++) Next[y][x] = Cave[y][x];
+       for(y = 0; y < HEIGHT; y++) for(x = 0; x < WIDTH; x++) Draw[y][x] = Cave[y][x];
+}
diff --git a/src/libem/display.h b/src/libem/display.h
new file mode 100644 (file)
index 0000000..a13d3a7
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef DISPLAY_H
+#define DISPLAY_H
+
+#define TILEX 16
+#define TILEY 16
+#define SCOREX 8
+#define SCOREY 9
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+
+extern Display *display;
+extern Window window;
+#if 0
+extern Window xwindow;
+#else
+#define xwindow window
+#endif
+
+extern Pixmap screenPixmap;
+extern Pixmap scorePixmap;
+extern Pixmap spriteBitmap;
+
+extern Pixmap objPixmap;
+extern Pixmap objmaskBitmap;
+extern Pixmap sprPixmap;
+extern Pixmap sprmaskBitmap;
+extern Pixmap ttlPixmap;
+extern Pixmap ttlmaskBitmap;
+extern Pixmap botPixmap;
+extern Pixmap botmaskBitmap;
+
+extern GC screenGC;
+extern GC scoreGC;
+extern GC spriteGC;
+extern GC antsGC;
+
+extern Atom deleteAtom;
+
+extern KeySym lastKeySym;
+
+extern KeyCode northKeyCode[];
+extern KeyCode eastKeyCode[];
+extern KeyCode southKeyCode[];
+extern KeyCode westKeyCode[];
+extern KeyCode fireKeyCode[];
+extern KeyCode escKeyCode[];
+
+#endif
diff --git a/src/libem/file.h b/src/libem/file.h
new file mode 100644 (file)
index 0000000..678bbb4
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef FILE_H
+#define FILE_H
+
+/* 2000-09-28T09:07:50Z
+ */
+
+#include "global.h"
+
+struct cave_node {
+       struct cave_node *next;
+       char path[MAXNAME+2];
+       char name[32];
+};
+
+extern struct cave_node *cave_list;
+
+#endif
diff --git a/src/libem/global.h b/src/libem/global.h
new file mode 100644 (file)
index 0000000..8179206
--- /dev/null
@@ -0,0 +1,60 @@
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#define EM_GFX_DIR     "graphics.EM"
+#define EM_SND_DIR     "sounds.EM"
+#define EM_LVL_DIR     "levels.EM"
+
+#define MAXNAME 1024 /* arbitrary maximum length of filenames (cos i am lazy) */
+extern void snprintf_overflow(char *);
+
+extern int debug;
+extern char *progname;
+extern char *arg_basedir;
+extern char *arg_display;
+extern char *arg_geometry;
+extern int arg_install;
+extern int arg_silence;
+
+extern unsigned int frame;
+
+extern short ulaw_to_linear[256];
+extern unsigned char linear_to_ulaw[65536];
+
+/* all global function prototypes */
+
+int open_all(void);
+void close_all(void);
+
+void readjoy(void);
+void input_eventloop(void);
+
+void blitscreen(void);
+void game_initscreen(void);
+void game_blitscore(void);
+void game_animscreen(void);
+void title_initscreen(void);
+void title_blitscore(void);
+void title_animscreen(void);
+void title_blitants(unsigned int y);
+void title_string(unsigned int y, unsigned int left, unsigned int right, char *string);
+
+void sound_play(void);
+
+int cave_convert(char *filename);
+
+int game_start(void);
+void synchro_1(void);
+void synchro_2(void);
+void synchro_3(void);
+
+int clean_emerald(unsigned char *src, unsigned long *length);
+void convert_emerald(unsigned char *src);
+
+int sound_thread(void);
+int read_sample(char *name, short **data, long *length);
+
+void read_cave_list(void);
+void free_cave_list(void);
+
+#endif
diff --git a/src/libem/graphics.c b/src/libem/graphics.c
new file mode 100644 (file)
index 0000000..0951468
--- /dev/null
@@ -0,0 +1,366 @@
+/* 2000-08-13T14:36:17Z
+ *
+ * graphics manipulation crap
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include "global.h"
+#include "display.h"
+#include "level.h"
+
+#include <stdio.h>
+
+unsigned int frame; /* current frame */
+unsigned int screen_x; /* current scroll position */
+unsigned int screen_y;
+
+static unsigned short screen[14][22]; /* tiles currently on screen */
+
+static unsigned int colours[8];
+static unsigned int colour_anim;
+
+void xdebug(char *msg)
+{
+#if 0
+  XSync(display, False);
+  printf("EM DEBUG: %s\n", msg);
+#endif
+}
+
+static void colour_shuffle(void)
+{
+       unsigned int i, j, k;
+       for(i = 0; i < 8; i++) colours[i] = i;
+       for(i = 0; i < 8; i++) {
+               Random = Random * 129 + 1;
+               j = (Random >> 10) & 7;
+               k = colours[i];
+               colours[i] = colours[j];
+               colours[j] = k;
+       }
+}
+
+/* copy the entire screen to the window at the scroll position
+ *
+ * perhaps use mit-shm to speed this up
+ */
+void blitscreen(void)
+{
+       unsigned int x = screen_x % (22 * TILEX);
+       unsigned int y = screen_y % (14 * TILEY);
+
+       xdebug("blitscreen");
+
+#if 0
+       printf("::: %d, %d [%d, %d]\n", x, y, TILEX, TILEY);
+#endif
+
+       if(x < 2 * TILEX && y < 2 * TILEY) {
+
+#if 0
+         printf("!!! %ld, %ld, %ld, %ld\n",
+                display, screenPixmap, xwindow, screenGC);
+#endif
+
+               XCopyArea(display, screenPixmap, xwindow, screenGC, x, y, 20 * TILEX, 12 * TILEY, 0, 0);
+       } else if(x < 2 * TILEX && y >= 2 * TILEY) {
+               XCopyArea(display, screenPixmap, xwindow, screenGC, x, y, 20 * TILEX, 14 * TILEY - y, 0, 0);
+               XCopyArea(display, screenPixmap, xwindow, screenGC, x, 0, 20 * TILEX, y - 2 * TILEY, 0, 14 * TILEY - y);
+       } else if(x >= 2 * TILEX && y < 2 * TILEY) {
+               XCopyArea(display, screenPixmap, xwindow, screenGC, x, y, 22 * TILEX - x, 12 * TILEY, 0, 0);
+               XCopyArea(display, screenPixmap, xwindow, screenGC, 0, y, x - 2 * TILEX, 12 * TILEY, 22 * TILEX - x, 0);
+       } else {
+               XCopyArea(display, screenPixmap, xwindow, screenGC, x, y, 22 * TILEX - x, 14 * TILEY - y, 0, 0);
+               XCopyArea(display, screenPixmap, xwindow, screenGC, 0, y, x - 2 * TILEX, 14 * TILEY - y, 22 * TILEX - x, 0);
+               XCopyArea(display, screenPixmap, xwindow, screenGC, x, 0, 22 * TILEX - x, y - 2 * TILEY, 0, 14 * TILEY - y);
+               XCopyArea(display, screenPixmap, xwindow, screenGC, 0, 0, x - 2 * TILEX, y - 2 * TILEY, 22 * TILEX - x, 14 * TILEY - y);
+       }
+
+       XCopyArea(display, scorePixmap, xwindow, scoreGC, 0, 0, 20 * TILEX, SCOREY, 0, 12 * TILEY);
+       XFlush(display);
+
+       xdebug("blitscreen - done");
+}
+
+/* draw differences between game tiles and screen tiles
+ *
+ * implicitly handles scrolling and restoring background under the sprites
+ *
+ * perhaps use mit-shm to speed this up
+ */
+static void animscreen(void)
+{
+       unsigned int x, y, dx, dy;
+       unsigned short obj;
+       unsigned int left = screen_x / TILEX;
+       unsigned int top = screen_y / TILEY;
+
+       xdebug("animscreen");
+
+       for(y = top; y < top + 14; y++) {
+               dy = y % 14;
+               for(x = left; x < left + 22; x++) {
+                       dx = x % 22;
+                       obj = map_obj[frame][Draw[y][x]];
+                       if(screen[dy][dx] != obj) {
+                               screen[dy][dx] = obj;
+                               XCopyArea(display, objPixmap, screenPixmap, screenGC, (obj / 512) * TILEX, (obj % 512) * TILEY / 16, TILEX, TILEY, dx * TILEX, dy * TILEY);
+                       }
+               }
+       }
+}
+
+/* blit players to the screen
+ *
+ * handles transparency and movement
+ */
+static void blitplayer(struct PLAYER *ply) {
+       unsigned int x, y, dx, dy;
+       unsigned short obj, spr;
+
+       xdebug("blitplayer");
+
+       if(ply->alive) {
+               x = (frame * ply->oldx + (8 - frame) * ply->x) * TILEX / 8; dx = x + TILEX - 1;
+               y = (frame * ply->oldy + (8 - frame) * ply->y) * TILEY / 8; dy = y + TILEY - 1;
+               if((unsigned int)(dx - screen_x) < (21 * TILEX - 1) && (unsigned int)(dy - screen_y) < (13 * TILEY - 1)) {
+                       spr = map_spr[ply->num][frame][ply->anim];
+                       x %= 22 * TILEX; dx %= 22 * TILEX;
+                       y %= 14 * TILEY; dy %= 14 * TILEY;
+                       if(objmaskBitmap) {
+                               obj = screen[y / TILEY][x / TILEX];
+                               XCopyArea(display, objmaskBitmap, spriteBitmap, spriteGC, (obj / 512) * TILEX, (obj % 512) * TILEY / 16, TILEX, TILEY, -(x % TILEX), -(y % TILEY));
+                               obj = screen[dy / TILEY][dx / TILEX];
+                               XCopyArea(display, objmaskBitmap, spriteBitmap, spriteGC, (obj / 512) * TILEX, (obj % 512) * TILEY / 16, TILEX, TILEY, (22 * TILEX - x) % TILEX, (14 * TILEY - y) % TILEY);
+                       } else if(sprmaskBitmap) {
+                               XCopyArea(display, sprmaskBitmap, spriteBitmap, spriteGC, (spr / 8) * TILEX, (spr % 8) * TILEY, TILEX, TILEY, 0, 0);
+                       } else {
+                               XFillRectangle(display, spriteBitmap, spriteGC, 0, 0, TILEX, TILEY);
+                       }
+                       screen[y / TILEY][x / TILEX] = -1; /* mark screen as dirty */
+                       screen[dy / TILEY][dx / TILEX] = -1;
+                       XSetClipMask(display, screenGC, spriteBitmap);
+                       XSetClipOrigin(display, screenGC, x, y);
+                       XCopyArea(display, sprPixmap, screenPixmap, screenGC, (spr / 8) * TILEX, (spr % 8) * TILEY, TILEX, TILEY, x, y);
+                       XSetClipOrigin(display, screenGC, x - 22 * TILEX, y);
+                       XCopyArea(display, sprPixmap, screenPixmap, screenGC, (spr / 8) * TILEX, (spr % 8) * TILEY, TILEX, TILEY, x - 22 * TILEX, y);
+                       XSetClipOrigin(display, screenGC, x, y - 14 * TILEY);
+                       XCopyArea(display, sprPixmap, screenPixmap, screenGC, (spr / 8) * TILEX, (spr % 8) * TILEY, TILEX, TILEY, x, y - 14 * TILEY);
+                       XSetClipMask(display, screenGC, None);
+               }
+       }
+}
+
+void game_initscreen(void)
+{
+       unsigned int x,y;
+
+       xdebug("game_initscreen");
+
+#if 0
+       printf("--> M5.1: xwindow == %ld\n", xwindow);
+#endif
+
+       frame = 6;
+       screen_x = 0;
+       screen_y = 0;
+
+#if 0
+       printf("--> M5.2: &window == %ld\n", &window);
+       printf("--> M5.2: xwindow == %ld\n", xwindow);
+       printf("--> M5.2: &xwindow == %ld\n", &xwindow);
+       printf("--> M5.2: screen == %ld\n", screen);
+       printf("--> M5.2: &screen[0][0] == %ld\n", &screen[0][0]);
+#endif
+
+       for(y = 0; y < 14; y++) {
+               for(x = 0; x < 22; x++) {
+#if 0
+                 printf("--> M5.2.A: xwindow == %ld [%d,%d]\n", xwindow, x,y);
+#endif
+                       screen[y][x] = -1;
+#if 0
+                 printf("--> M5.2.B: xwindow == %ld [%d,%d]\n", xwindow, x,y);
+#endif
+               }
+       }
+
+#if 0
+       printf("--> M5.3: xwindow == %ld\n", xwindow);
+#endif
+
+       colour_shuffle();
+       colours[0] += 16;
+       colours[1] += 16;
+       colours[2] += 16;
+       colour_anim = 0;
+
+#if 0
+       printf("--> M5.4: xwindow == %ld\n", xwindow);
+#endif
+
+       XFillRectangle(display, scorePixmap, scoreGC, 0, 0, 20 * TILEX, SCOREY);
+       XCopyArea(display, botPixmap, scorePixmap, scoreGC, 11 * SCOREX, colours[0] * SCOREY, 3 * SCOREX, SCOREY, 1 * SCOREX, 0); /* 0-63 time */
+       XCopyArea(display, botPixmap, scorePixmap, scoreGC, 18 * SCOREX, colours[0] * SCOREY, 6 * SCOREX, SCOREY, 15 * SCOREX, 0); /* 112-207 diamonds */
+       XCopyArea(display, botPixmap, scorePixmap, scoreGC, 14 * SCOREX, colours[0] * SCOREY, 4 * SCOREX, SCOREY, 32 * SCOREX, 0); /* 256-319 score */
+
+#if 0
+       printf("--> M5.X: xwindow == %ld\n", xwindow);
+#endif
+}
+
+void game_blitscore(void)
+{
+       unsigned int i;
+
+       xdebug("game_blitscore");
+
+       i = (lev.time + 4) / 5;
+       XCopyArea(display, botPixmap, scorePixmap, scoreGC, (i % 10) * SCOREX, colours[1] * SCOREY, SCOREX, SCOREY, 7 * SCOREX, 0); i /= 10;
+       XCopyArea(display, botPixmap, scorePixmap, scoreGC, (i % 10) * SCOREX, colours[1] * SCOREY, SCOREX, SCOREY, 6 * SCOREX, 0); i /= 10;
+       XCopyArea(display, botPixmap, scorePixmap, scoreGC, (i % 10) * SCOREX, colours[1] * SCOREY, SCOREX, SCOREY, 5 * SCOREX, 0); i /= 10;
+       XCopyArea(display, botPixmap, scorePixmap, scoreGC, (i % 10) * SCOREX, colours[1] * SCOREY, SCOREX, SCOREY, 4 * SCOREX, 0);
+       i = lev.score;
+       XCopyArea(display, botPixmap, scorePixmap, scoreGC, (i % 10) * SCOREX, colours[1] * SCOREY, SCOREX, SCOREY, 39 * SCOREX, 0); i /= 10;
+       XCopyArea(display, botPixmap, scorePixmap, scoreGC, (i % 10) * SCOREX, colours[1] * SCOREY, SCOREX, SCOREY, 38 * SCOREX, 0); i /= 10;
+       XCopyArea(display, botPixmap, scorePixmap, scoreGC, (i % 10) * SCOREX, colours[1] * SCOREY, SCOREX, SCOREY, 37 * SCOREX, 0); i /= 10;
+       XCopyArea(display, botPixmap, scorePixmap, scoreGC, (i % 10) * SCOREX, colours[1] * SCOREY, SCOREX, SCOREY, 36 * SCOREX, 0);
+       if(lev.home == 0) {
+               XCopyArea(display, botPixmap, scorePixmap, scoreGC, 12 * SCOREX, 24 * SCOREY, 12 * SCOREX, SCOREY, 14 * SCOREX, 0); /* relax */
+               goto done;
+       }
+       if(ply1.alive + ply2.alive >= lev.home && lev.required == 0) {
+               XCopyArea(display, botPixmap, scorePixmap, scoreGC, 24 * SCOREX, colours[2] * SCOREY, 12 * SCOREX, SCOREY, 14 * SCOREX, 0); /* find the exit */
+               goto done;
+       }
+       if(ply1.alive + ply2.alive < lev.home) {
+               if(++colour_anim > 11) colour_anim = 0;
+               if(colour_anim < 6) {
+                       XCopyArea(display, botPixmap, scorePixmap, scoreGC, 0, 24 * SCOREY, 12 * SCOREX, SCOREY, 14 * SCOREX, 0); /* forget it */
+                       goto done;
+               }
+               XCopyArea(display, botPixmap, scorePixmap, scoreGC, 18 * SCOREX, colours[0] * SCOREY, 6 * SCOREX, SCOREY, 15 * SCOREX, 0); /* diamonds */
+       }
+       i = lev.required;
+       XCopyArea(display, botPixmap, scorePixmap, scoreGC, (i % 10) * SCOREX, colours[1] * SCOREY, SCOREX, SCOREY, 24 * SCOREX, 0); i /= 10;
+       XCopyArea(display, botPixmap, scorePixmap, scoreGC, (i % 10) * SCOREX, colours[1] * SCOREY, SCOREX, SCOREY, 23 * SCOREX, 0); i /= 10;
+       XCopyArea(display, botPixmap, scorePixmap, scoreGC, (i % 10) * SCOREX, colours[1] * SCOREY, SCOREX, SCOREY, 22 * SCOREX, 0); i /= 10;
+       XCopyArea(display, botPixmap, scorePixmap, scoreGC, (i % 10) * SCOREX, colours[1] * SCOREY, SCOREX, SCOREY, 21 * SCOREX, 0);
+done:
+}
+
+void game_animscreen(void)
+{
+       unsigned int x,y;
+
+       xdebug("game_animscreen");
+
+       x = (frame * ply1.oldx + (8 - frame) * ply1.x) * TILEX / 8 + (19 * TILEX) / 2;
+       y = (frame * ply1.oldy + (8 - frame) * ply1.y) * TILEY / 8 + (11 * TILEY) / 2;
+       if(x > lev.width * TILEX) x = lev.width * TILEX;
+       if(y > lev.height * TILEY) y = lev.height * TILEY;
+       if(x < 20 * TILEX) x = 20 * TILEY;
+       if(y < 12 * TILEY) y = 12 * TILEY;
+       screen_x = x - 19 * TILEX;
+       screen_y = y - 11 * TILEY;
+
+       animscreen();
+       blitplayer(&ply1);
+       blitplayer(&ply2);
+       blitscreen();
+       XFlush(display);
+
+       Random = Random * 129 + 1;
+}
+
+void title_initscreen(void)
+{
+       xdebug("title_initscreen");
+
+       screen_x = 0;
+       screen_y = 0;
+
+       colour_shuffle();
+       colours[1] += 8;
+       colour_anim = 0;
+
+       XCopyArea(display, ttlPixmap, screenPixmap, screenGC, 0, 0, 20 * TILEX, 12 * TILEY, 0, 0);
+       if(botmaskBitmap) {
+               XCopyArea(display, botPixmap, scorePixmap, scoreGC, 0, colours[1] * SCOREY, 20 * TILEX, SCOREY, 0, 0);
+               XSetClipMask(display, scoreGC, botmaskBitmap);
+               XSetClipOrigin(display, scoreGC, 0, 0 - colours[0] * SCOREY);
+       }
+       XCopyArea(display, botPixmap, scorePixmap, scoreGC, 0, colours[0] * SCOREY, 20 * TILEX, SCOREY, 0, 0);
+       if(botmaskBitmap) {
+               XSetClipMask(display, scoreGC, None);
+       }
+}
+
+void title_blitscore(void)
+{
+       unsigned int x, y, i;
+
+       xdebug("title_blitscore");
+
+       if(++colour_anim > 30) colour_anim = 0;
+       i = colour_anim >= 16 ? 31 - colour_anim : colour_anim;
+       x = (i / 8 + 18) * 2 * SCOREX;
+       y = (i % 8 + 16) * SCOREY;
+
+       if(botmaskBitmap) {
+               XCopyArea(display, botPixmap, scorePixmap, scoreGC, 32 * SCOREX, colours[1] * SCOREY, 2 * SCOREX, SCOREY, 32 * SCOREX, 0);
+               XSetClipMask(display, scoreGC, botmaskBitmap);
+               XSetClipOrigin(display, scoreGC, 32 * SCOREX - x, 0 - y);
+       }
+       XCopyArea(display, botPixmap, scorePixmap, scoreGC, x, y, 2 * SCOREX, SCOREY, 32 * SCOREX, 0);
+       if(botmaskBitmap) {
+               XSetClipMask(display, scoreGC, None);
+       }
+}
+
+void title_blitants(unsigned int y)
+{
+       static const char ants_dashes[2] = { 8, 7 };
+
+       xdebug("title_blitants");
+
+       XSetDashes(display, antsGC, colour_anim, ants_dashes, 2);
+       XDrawRectangle(display, screenPixmap, antsGC, 0, y * TILEY, 20 * TILEX - 1, TILEY - 1);
+}
+
+void title_animscreen(void)
+{
+       blitscreen();
+       XFlush(display);
+
+       Random = Random * 129 + 1;
+}
+
+void title_string(unsigned int y, unsigned int left, unsigned int right, char *string)
+{
+       int i;
+       unsigned int x;
+
+       xdebug("title_string");
+
+       y *= TILEY; left *= SCOREX; right *= SCOREX;
+       x = (left + right - strlen(string) * 12) / 2;
+       if(x < left || x >= right) x = left;
+
+       XCopyArea(display, ttlPixmap, screenPixmap, screenGC, left, y, right - left, TILEY, left, y);
+       if(ttlmaskBitmap) XSetClipMask(display, screenGC, ttlmaskBitmap);
+       for(i = 0; string[i] && x < right; i++) {
+               unsigned short ch_pos, ch_x, ch_y;
+               ch_pos = map_ttl[string[i] & 127];
+               if(ch_pos < 640) {
+                       ch_x = (ch_pos % 320);
+                       ch_y = (ch_pos / 320 + 12) * TILEY;
+                       if(ttlmaskBitmap) XSetClipOrigin(display, screenGC, x - ch_x, y - ch_y);
+                       XCopyArea(display, ttlPixmap, screenPixmap, screenGC, ch_x, ch_y, 12, TILEY, x, y);
+               }
+               x += 12;
+       }
+       XSetClipMask(display, screenGC, None);
+}
diff --git a/src/libem/init.c b/src/libem/init.c
new file mode 100644 (file)
index 0000000..59a688d
--- /dev/null
@@ -0,0 +1,493 @@
+/* 2000-08-10T18:03:54Z
+ *
+ * open X11 display and sound
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+#include <X11/cursorfont.h>
+#include <X11/xpm.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+#include <string.h>
+#include <errno.h>
+
+#include "../libgame/platform.h"
+
+#include "global.h"
+#include "display.h"
+#include "sample.h"
+
+Display *display;
+Window xwindow;
+
+Pixmap screenPixmap;
+Pixmap scorePixmap;
+Pixmap spriteBitmap;
+
+Pixmap objPixmap;
+Pixmap objmaskBitmap;
+Pixmap botPixmap;
+Pixmap botmaskBitmap;
+Pixmap sprPixmap;
+Pixmap sprmaskBitmap;
+Pixmap ttlPixmap;
+Pixmap ttlmaskBitmap;
+
+GC screenGC;
+GC scoreGC;
+GC spriteGC;
+GC antsGC;
+
+Atom deleteAtom;
+
+KeySym lastKeySym;
+
+KeyCode northKeyCode[3];
+KeyCode eastKeyCode[3];
+KeyCode southKeyCode[3];
+KeyCode westKeyCode[3];
+KeyCode fireKeyCode[3];
+KeyCode escKeyCode[1];
+
+char play[SAMPLE_MAX];
+
+static int sound_pid = -1;
+int sound_pipe[2] = { -1, -1 }; /* for communication */
+short *sound_data[SAMPLE_MAX]; /* pointer to sound data */
+long sound_length[SAMPLE_MAX]; /* length of sound data */
+
+static Screen *defaultScreen;
+static Visual *defaultVisual;
+static Colormap defaultColourmap;
+static Window defaultRootWindow;
+static unsigned int screenDepth;
+static unsigned int screenWidth;
+static unsigned int screenHeight;
+static unsigned long screenBlackPixel;
+static unsigned long screenWhitePixel;
+
+static XSizeHints sizeHints;
+static XSetWindowAttributes setWindowAttributes;
+static XWMHints wmHints;
+static XVisualInfo visualInfo;
+static XGCValues gcValues;
+
+static Colormap privateColourmap;
+static Cursor cursor;
+static XColor *privateColours;
+static unsigned char *privateFlags;
+static int privateNumColours;
+
+static XColor redColour;
+static XColor whiteColour;
+static int gotRed;
+static int gotWhite;
+
+static Pixmap xpmPixmaps[4];
+static Pixmap xpmBitmaps[4];
+static XpmAttributes xpmAttributes[4];
+static int xpmGot[4];
+
+static int xpmAllocColourFunc(Display *, Colormap, char *, XColor *, void *);
+static int xpmFreeColoursFunc(Display *, Colormap, unsigned long *, int, void *);
+
+static KeyCode keycodes[16];
+
+static const char *xpmNames[4] = { "object.xpm", "score.xpm", "sprite.xpm", "title.xpm" };
+static const int xpmCloseness[4] = { 10000, 10000, 40000, 50000 };
+static const KeySym keysyms[16] = {
+       XK_Up, XK_KP_Up, XK_r, /* north */
+       XK_Right, XK_KP_Right, XK_g, /* east */
+       XK_Down, XK_KP_Down, XK_f, /* south */
+       XK_Left, XK_KP_Left, XK_d, /* west */
+       XK_Shift_L, XK_Control_R, XK_space, /* fire */
+       XK_Escape /* escape */
+};
+static const char *sound_names[SAMPLE_MAX] = {
+       "00.blank.au","01.roll.au","02.stone.au","03.nut.au","04.crack.au",
+       "05.bug.au","06.tank.au","07.android.au","08.spring.au","09.slurp.au",
+       "10.eater.au","11.alien.au","12.collect.au","13.diamond.au","14.squash.au",
+       "15.drip.au","16.push.au","17.dirt.au","18.acid.au","19.ball.au",
+       "20.grow.au","21.wonder.au","22.door.au","23.exit.au","24.dynamite.au",
+       "25.tick.au","26.press.au","27.wheel.au","28.boom.au","29.time.au",
+       "30.die.au"
+};
+static const int sound_volume[SAMPLE_MAX] = {
+       20,100,100,100,100,20,20,100,100,100,
+       50,100,100,100,100,100,100,100,100,100,
+       100,20,100,100,100,100,100,20,100,100,
+       100
+};
+
+int open_all(void)
+{
+       char name[MAXNAME+2];
+       void *dummyptr;
+       int dummyint;
+       int i;
+
+       display = XOpenDisplay(arg_display);
+       if(display == 0) {
+               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to open display", strerror(errno));
+               return(1);
+       }
+
+       defaultScreen = DefaultScreenOfDisplay(display);
+       defaultVisual = DefaultVisualOfScreen(defaultScreen);
+       defaultColourmap = DefaultColormapOfScreen(defaultScreen);
+       defaultRootWindow = RootWindowOfScreen(defaultScreen);
+       screenDepth = DefaultDepthOfScreen(defaultScreen);
+       screenWidth = WidthOfScreen(defaultScreen);
+       screenHeight = HeightOfScreen(defaultScreen);
+       screenBlackPixel = BlackPixelOfScreen(defaultScreen);
+       screenWhitePixel = WhitePixelOfScreen(defaultScreen);
+
+       if(arg_install) {
+               visualInfo.visualid = XVisualIDFromVisual(defaultVisual);
+               dummyptr = XGetVisualInfo(display, VisualIDMask, &visualInfo, &dummyint);
+               if(dummyptr == 0) {
+                       fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to get visual info", strerror(errno));
+                       return(1);
+               }
+               memcpy(&visualInfo, dummyptr, sizeof(visualInfo));
+               XFree(dummyptr);
+
+               if(visualInfo.class != PseudoColor) {
+                       fprintf(stderr, "%s: \"%s\": %s\n", progname, XDisplayName(arg_display), "private colourmap only supported for pseudocolour display");
+                       return(1);
+               }
+
+               privateColourmap = XCreateColormap(display, defaultRootWindow, defaultVisual, AllocAll);
+               if(privateColourmap == 0) {
+                       fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to create colourmap", strerror(errno));
+                       return(1);
+               }
+
+               privateNumColours = visualInfo.colormap_size;
+
+               privateColours = malloc(privateNumColours * sizeof(XColor));
+               if(privateColours == 0) {
+                       fprintf(stderr, "%s: %s (%d): %s\n", progname, "malloc failed", privateNumColours * sizeof(XColor), strerror(errno));
+                       return(1);
+               }
+               for(dummyint = 0; dummyint < privateNumColours; dummyint++) privateColours[dummyint].pixel = dummyint;
+               XQueryColors(display, defaultColourmap, privateColours, privateNumColours);
+               XStoreColors(display, privateColourmap, privateColours, privateNumColours);
+
+               privateFlags = malloc(privateNumColours);
+               if(privateFlags == 0) {
+                       fprintf(stderr, "%s: %s (%d): %s\n", progname, "malloc failed", privateNumColours, strerror(errno));
+                       return(1);
+               }
+               memset(privateFlags, 0, privateNumColours);
+               privateFlags[0] = 1; /* first two entries (black and white) are already allocated */
+               privateFlags[1] = 1;
+       }
+
+       sizeHints.flags = PSize | PMinSize | PMaxSize;
+       sizeHints.width = 20 * TILEX;
+       sizeHints.height = 12 * TILEY + SCOREY;
+       sizeHints.min_width = sizeHints.max_width = sizeHints.width;
+       sizeHints.min_height = sizeHints.max_height = sizeHints.height;
+       if(arg_geometry) {
+               dummyint = XWMGeometry(display, XScreenNumberOfScreen(defaultScreen), arg_geometry, 0, 2, &sizeHints, &sizeHints.x, &sizeHints.y, &dummyint, &dummyint, &sizeHints.win_gravity);
+               if(dummyint & (XValue | YValue)) sizeHints.flags |= USPosition | PWinGravity;
+       }
+
+       xwindow = XCreateWindow(display, defaultRootWindow, sizeHints.x, sizeHints.y, sizeHints.width, sizeHints.height, 2, screenDepth, InputOutput, CopyFromParent, 0, 0);
+       if(xwindow == 0) {
+               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to open window", strerror(errno));
+               return(1);
+       }
+
+       setWindowAttributes.background_pixel = screenBlackPixel;
+       setWindowAttributes.border_pixel = screenWhitePixel;
+       setWindowAttributes.backing_store = NotUseful;
+       setWindowAttributes.override_redirect = False;
+       setWindowAttributes.event_mask = KeyPressMask | EnterWindowMask | LeaveWindowMask | ExposureMask;
+       setWindowAttributes.colormap = privateColourmap ? privateColourmap : defaultColourmap;
+       XChangeWindowAttributes(display, xwindow, CWBackPixel | CWBorderPixel | CWBackingStore | CWOverrideRedirect | CWEventMask | CWColormap, &setWindowAttributes);
+
+       XStoreName(display, xwindow, "Emerald Mine");
+
+       wmHints.flags = InputHint | StateHint;
+       wmHints.input = True;
+       wmHints.initial_state = NormalState;
+       XSetWMHints(display, xwindow, &wmHints);
+
+       XSetWMNormalHints(display, xwindow, &sizeHints);
+
+       deleteAtom = XInternAtom(display, "WM_DELETE_WINDOW", False);
+       XSetWMProtocols(display, xwindow, &deleteAtom, 1);
+
+       cursor = XCreateFontCursor(display, XC_trek);
+       if(cursor) XDefineCursor(display, xwindow, cursor);
+
+       XMapWindow(display, xwindow);
+
+       for(i = 0; i < 4; i++) {
+               name[MAXNAME] = 0;
+               if(arg_basedir) {
+                       snprintf(name, MAXNAME+2, "%s/%s/%s", arg_basedir, EM_GFX_DIR, xpmNames[i]);
+               } else {
+                       snprintf(name, MAXNAME+2, "%s/%s", EM_GFX_DIR, xpmNames[i]);
+               }
+               if(name[MAXNAME]) snprintf_overflow("read graphics/ files");
+
+               xpmAttributes[i].valuemask = XpmColormap | XpmReturnAllocPixels | XpmExactColors | XpmCloseness | XpmAllocColor | XpmFreeColors;
+               xpmAttributes[i].colormap = privateColourmap ? privateColourmap : defaultColourmap;
+               xpmAttributes[i].exactColors = False;
+               xpmAttributes[i].closeness = xpmCloseness[i];
+               xpmAttributes[i].alloc_color = xpmAllocColourFunc;
+               xpmAttributes[i].free_colors = xpmFreeColoursFunc;
+               dummyint = XpmReadFileToPixmap(display, xwindow, name, &xpmPixmaps[i], &xpmBitmaps[i], &xpmAttributes[i]);
+               if(dummyint) {
+                       fprintf(stderr, "%s: \"%s\": \"%s\": %s: %s: %s\n", progname, XDisplayName(arg_display), name, "failed to read xpm", XpmGetErrorString(dummyint), strerror(errno));
+                       return(1);
+               }
+               xpmGot[i] = 1;
+       }
+
+       objPixmap = xpmPixmaps[0];
+       botPixmap = xpmPixmaps[1];
+       sprPixmap = xpmPixmaps[2];
+       ttlPixmap = xpmPixmaps[3];
+       objmaskBitmap = xpmBitmaps[0];
+       botmaskBitmap = xpmBitmaps[1];
+       sprmaskBitmap = xpmBitmaps[2];
+       ttlmaskBitmap = xpmBitmaps[3];
+
+       screenPixmap = XCreatePixmap(display, xwindow, 22 * TILEX, 14 * TILEY, screenDepth);
+       if(screenPixmap == 0) {
+               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to create pixmap", strerror(errno));
+               return(1);
+       }
+
+       scorePixmap = XCreatePixmap(display, xwindow, 20 * TILEX, SCOREY, screenDepth);
+       if(scorePixmap == 0) {
+               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to create pixmap", strerror(errno));
+               return(1);
+       }
+
+       spriteBitmap = XCreatePixmap(display, xwindow, TILEX, TILEY, 1);
+       if(spriteBitmap == 0) {
+               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to create pixmap", strerror(errno));
+               return(1);
+       }
+
+       redColour.pixel = screenWhitePixel;
+       whiteColour.pixel = screenBlackPixel;
+       gotRed = (xpmAllocColourFunc(display, privateColourmap ? privateColourmap : defaultColourmap, "red", &redColour, 0) > 0);
+       gotWhite = (xpmAllocColourFunc(display, privateColourmap ? privateColourmap : defaultColourmap, "white", &whiteColour, 0) > 0);
+
+       gcValues.graphics_exposures = False;
+       screenGC = XCreateGC(display, screenPixmap, GCGraphicsExposures, &gcValues);
+       if(screenGC == 0) {
+               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to create graphics context", strerror(errno));
+               return(1);
+       }
+
+       gcValues.graphics_exposures = False;
+       scoreGC = XCreateGC(display, scorePixmap, GCGraphicsExposures, &gcValues);
+       if(scoreGC == 0) {
+               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to create graphics context", strerror(errno));
+               return(1);
+       }
+
+       gcValues.function = objmaskBitmap ? GXcopyInverted : sprmaskBitmap ? GXcopy : GXset;
+       gcValues.graphics_exposures = False;
+       spriteGC = XCreateGC(display, spriteBitmap, GCFunction | GCGraphicsExposures, &gcValues);
+       if(spriteGC == 0) {
+               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to create graphics context", strerror(errno));
+               return(1);
+       }
+
+       gcValues.foreground = redColour.pixel;
+       gcValues.background = whiteColour.pixel;
+       gcValues.line_style = LineDoubleDash;
+       gcValues.graphics_exposures = False;
+       antsGC = XCreateGC(display, screenPixmap, GCForeground | GCBackground | GCLineStyle | GCGraphicsExposures, &gcValues);
+       if(antsGC == 0) {
+               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, XDisplayName(arg_display), "failed to create graphics context", strerror(errno));
+               return(1);
+       }
+
+       for(i = 0; i < 16; i++) {
+               keycodes[i] = XKeysymToKeycode(display, keysyms[i]);
+       }
+       for(i = 0; i < 3; i++) northKeyCode[i] = keycodes[i + 0];
+       for(i = 0; i < 3; i++) eastKeyCode[i] = keycodes[i + 3];
+       for(i = 0; i < 3; i++) southKeyCode[i] = keycodes[i + 6];
+       for(i = 0; i < 3; i++) westKeyCode[i] = keycodes[i + 9];
+       for(i = 0; i < 3; i++) fireKeyCode[i] = keycodes[i + 12];
+       for(i = 0; i < 1; i++) escKeyCode[i] = keycodes[i + 15];
+
+#if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD)
+       if(arg_silence == 0) {
+               for(i = 0; i < SAMPLE_MAX; i++) {
+                       name[MAXNAME] = 0;
+                       if(arg_basedir) {
+                               snprintf(name, MAXNAME+2, "%s/%s/%s", arg_basedir, EM_SND_DIR, sound_names[i]);
+                       } else {
+                               snprintf(name, MAXNAME+2, "%s/%s", EM_SND_DIR, sound_names[i]);
+                       }
+                       if(name[MAXNAME]) snprintf_overflow("read sounds/ directory");
+
+                       if(read_sample(name, &sound_data[i], &sound_length[i])) return(1);
+
+                       {
+                               short *ptr, *stop;
+                               int mult = sound_volume[i] * 65536 / (100 * MIXER_MAX);
+                               stop = sound_data[i] + sound_length[i];
+                               for(ptr = sound_data[i]; ptr < stop; ptr++) *ptr = (*ptr * mult) / 65536;
+                       }
+               }
+
+               if(pipe(sound_pipe) == -1) {
+                       fprintf(stderr, "%s: %s: %s\n", progname, "unable to create sound pipe", strerror(errno));
+                       return(1);
+               }
+               sound_pid = fork();
+               if(sound_pid == -1) {
+                       fprintf(stderr, "%s: %s: %s\n", progname, "unable to fork sound thread", strerror(errno));
+                       return(1);
+               }
+               close(sound_pipe[sound_pid == 0]); sound_pipe[sound_pid == 0] = -1;
+               if(sound_pid == 0) _exit(sound_thread());
+               signal(SIGPIPE, SIG_IGN); /* dont crash if sound process dies */
+       }
+#endif /* defined(PLATFORM_LINUX) || defined(PLATFORM_BSD) */
+
+       return(0);
+}
+
+void close_all(void)
+{
+       int i;
+
+       if(sound_pid != -1) {
+               kill(sound_pid, SIGTERM);
+               waitpid(sound_pid, 0, 0);
+       }
+       if(sound_pipe[0] != -1) close(sound_pipe[0]);
+       if(sound_pipe[1] != -1) close(sound_pipe[1]);
+       for(i = 0; i < SAMPLE_MAX; i++) if(sound_data[i]) free(sound_data[i]);
+
+       for(i = 0; i < 4; i++) if(xpmPixmaps[i]) XFreePixmap(display, xpmPixmaps[i]);
+       for(i = 0; i < 4; i++) if(xpmBitmaps[i]) XFreePixmap(display, xpmBitmaps[i]);
+       for(i = 0; i < 4; i++) if(xpmGot[i]) {
+               xpmFreeColoursFunc(display, xpmAttributes[i].colormap, xpmAttributes[i].alloc_pixels, xpmAttributes[i].nalloc_pixels, 0);
+               XpmFreeAttributes(&xpmAttributes[i]);
+       }
+       if(gotRed) xpmFreeColoursFunc(display, privateColourmap ? privateColourmap : defaultColourmap, &redColour.pixel, 1, 0);
+       if(gotWhite) xpmFreeColoursFunc(display, privateColourmap ? privateColourmap : defaultColourmap, &whiteColour.pixel, 1, 0);
+       if(screenGC) XFreeGC(display, screenGC);
+       if(scoreGC) XFreeGC(display, scoreGC);
+       if(spriteGC) XFreeGC(display, spriteGC);
+       if(antsGC) XFreeGC(display, antsGC);
+       if(screenPixmap) XFreePixmap(display, screenPixmap);
+       if(scorePixmap) XFreePixmap(display, scorePixmap);
+       if(spriteBitmap) XFreePixmap(display, spriteBitmap);
+       if(xwindow) XDestroyWindow(display, xwindow);
+       if(cursor) XFreeCursor(display, cursor);
+       if(privateColourmap) XFreeColormap(display, privateColourmap);
+       if(privateColours) free(privateColours);
+       if(privateFlags) free(privateFlags);
+       if(display) XCloseDisplay(display);
+}
+
+/* ---------------------------------------------------------------------- */
+
+void sound_play(void)
+{
+       if(sound_pipe[1] != -1) {
+               if(write(sound_pipe[1], &play, sizeof(play)) == -1) {
+                       fprintf(stderr, "%s: %s: %s\n", progname, "write sound", strerror(errno));
+                       if(sound_pipe[0] != -1) { close(sound_pipe[0]); sound_pipe[0] = -1; }
+                       if(sound_pipe[1] != -1) { close(sound_pipe[1]); sound_pipe[1] = -1; }
+               }
+       }
+       memset(play, 0, sizeof(play));
+}
+
+/* ---------------------------------------------------------------------- */
+
+static int xpmAllocColourFunc(Display *display, Colormap colourmap, char *colourname, XColor *xcolour, void *closure)
+{
+       int i, match;
+       int r,g,b;
+       long best, sum;
+
+       if(colourname) if(XParseColor(display, colourmap, colourname, xcolour) == 0) return(-1); /* invalid name */
+       if(colourmap != privateColourmap) return(XAllocColor(display, colourmap, xcolour) != 0);
+
+/* first try to find an exact match */
+       match = -1;
+       for(i = 0; i < privateNumColours; i++) {
+               if(privateColours[i].red == xcolour->red && privateColours[i].green == xcolour->green && privateColours[i].blue == xcolour->blue) match = i;
+       }
+       if(match != -1) {
+               privateFlags[match] = 1;
+               xcolour->pixel = privateColours[match].pixel;
+               return(1);
+       }
+
+/* then find an unallocated colour that is close to what we want */
+       match = -1;
+       best = 1000000;
+       for(i = 0; i < privateNumColours; i++) {
+               if(privateFlags[i]) continue; /* skip if it is already allocated */
+               r = (privateColours[i].red - xcolour->red) / 256;
+               g = (privateColours[i].green - xcolour->green) / 256;
+               b = (privateColours[i].blue - xcolour->blue) / 256;
+               sum = r * r + g * g + b * b;
+               if(sum < best) {
+                       best = sum;
+                       match = i;
+               }
+       }
+       if(match != -1) {
+               privateFlags[match] = 1;
+               privateColours[match].red = xcolour->red;
+               privateColours[match].green = xcolour->green;
+               privateColours[match].blue = xcolour->blue;
+               XStoreColor(display, colourmap, &privateColours[match]);
+               xcolour->pixel = privateColours[match].pixel;
+               return(1); /* found a close match */
+       }
+
+/* if all else fails, just find the closest colour and return it */
+       match = -1;
+       best = 1000000;
+       for(i = 0; i < privateNumColours; i++) {
+               r = (privateColours[i].red - xcolour->red) / 256;
+               g = (privateColours[i].green - xcolour->green) / 256;
+               b = (privateColours[i].blue - xcolour->blue) / 256;
+               sum = r * r + g * g + b * b;
+               if(sum < best) {
+                       best = sum;
+                       match = i;
+               }
+       }
+       if(match != -1) {
+               xcolour->red = privateColours[match].red;
+               xcolour->green = privateColours[match].green;
+               xcolour->blue = privateColours[match].blue;
+               xcolour->pixel = privateColours[match].pixel;
+               return(1); /* best we could do */
+       }
+       return(0); /* still didnt find one, give up */
+}
+
+static int xpmFreeColoursFunc(Display *display, Colormap colourmap, unsigned long *pixels, int npixels, void *closure)
+{
+       if(colourmap != privateColourmap) XFreeColors(display, colourmap, pixels, npixels, 0);
+       return(1); /* non-zero for success */
+}
diff --git a/src/libem/input.c b/src/libem/input.c
new file mode 100644 (file)
index 0000000..7c6437c
--- /dev/null
@@ -0,0 +1,320 @@
+/* 2000-08-13T15:29:40Z
+ *
+ * handle input from x11 and keyboard and joystick
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "global.h"
+#include "display.h"
+#include "level.h"
+
+unsigned long Random;
+
+struct PLAYER ply1;
+struct PLAYER ply2;
+struct LEVEL lev;
+
+unsigned short **Boom;
+unsigned short **Cave;
+unsigned short **Next;
+unsigned short **Draw;
+
+static unsigned short *Index[4][HEIGHT];
+static unsigned short Array[4][HEIGHT][WIDTH];
+
+static int input_die;
+static int input_pause;
+static int input_refresh;
+static int input_esc;
+
+static struct timeval tv1;
+static struct timeval tv2;
+
+static unsigned char keymatrix[32];
+
+static int player_mode;
+static char player_name[32];
+static int player_level;
+
+static void drawmenu(int pos)
+{
+       char buffer[256];
+       switch(pos) {
+       case 0:
+               switch(player_mode) {
+               case 0: strcpy(buffer, "quit emerald mine"); break;
+               case 1: strcpy(buffer, "single player"); break;
+               case 2: strcpy(buffer, "teamwork"); break;
+               }
+               title_string(4, 0, 40, buffer);
+               break;
+       case 1:
+               sprintf(buffer, "name: %s", player_name);
+               title_string(5, 0, 40, buffer);
+               break;
+       case 2:
+               sprintf(buffer, "level: %d", player_level);
+               title_string(6, 0, 40, buffer);
+               break;
+       case 3:
+               title_string(7, 0, 40, "highscores");
+               break;
+       case 4:
+               title_string(8, 0, 40, "start");
+               break;
+       case 5:
+               title_string(10, 1, 13, "played");
+               title_string(10, 14, 26, "score");
+               title_string(10, 27, 39, "won");
+               break;
+       case 6:
+               sprintf(buffer, "%d", 0);
+               title_string(11, 1, 13, buffer);
+               sprintf(buffer, "%d", 0);
+               title_string(11, 14, 26, buffer);
+               sprintf(buffer, "%d", 0);
+               title_string(11, 27, 39, buffer);
+               break;
+       }
+}
+
+/* bring it all together */
+int game_start(void)
+{
+       int x,y;
+       char name[MAXNAME+2];
+       int temp;
+       int pos;
+
+       Random = 1684108901;
+
+       for(y = 0; y < HEIGHT; y++) for(x = 0; x < WIDTH; x++) Array[0][y][x] = ZBORDER;
+       for(y = 0; y < HEIGHT; y++) for(x = 0; x < WIDTH; x++) Array[1][y][x] = ZBORDER;
+       for(y = 0; y < HEIGHT; y++) for(x = 0; x < WIDTH; x++) Array[2][y][x] = ZBORDER;
+       for(y = 0; y < HEIGHT; y++) for(x = 0; x < WIDTH; x++) Array[3][y][x] = Xblank;
+
+       for(y = 0; y < HEIGHT; y++) Index[0][y] = Array[0][y];
+       for(y = 0; y < HEIGHT; y++) Index[1][y] = Array[1][y];
+       for(y = 0; y < HEIGHT; y++) Index[2][y] = Array[2][y];
+       for(y = 0; y < HEIGHT; y++) Index[3][y] = Array[3][y];
+
+       Cave = Index[0];
+       Next = Index[1];
+       Draw = Index[2];
+       Boom = Index[3];
+
+       player_mode = 1; /* start off as single player */
+       strcpy(player_name, "dave");
+       player_level = 0;
+
+       input_pause = 1;
+
+       for(;;) {
+
+               pos = 4;
+
+               title_initscreen();
+
+               for(temp = 0; temp < 7; temp++) drawmenu(temp); /* display all lines */
+               title_blitants(4 + pos);
+
+               title_blitscore();
+               title_animscreen();
+
+#if 0
+               printf("--> M1: xwindow == %ld\n", xwindow);
+#endif
+
+               temp = 1;
+               for(;;) {
+                       input_eventloop();
+                       if(input_die) return(0);
+                       if(input_refresh) blitscreen();
+
+#if 0
+                       printf("--> M2: xwindow == %ld\n", xwindow);
+#endif
+
+                       if(!input_pause) {
+                               title_blitants(4 + pos);
+                               title_blitscore();
+                               title_animscreen();
+
+#if 0
+                               printf("--> M3: xwindow == %ld\n", xwindow);
+#endif
+
+                               ply1.joy_n = ply1.joy_e = ply1.joy_s = ply1.joy_w = 0;
+
+                               readjoy();
+
+                               if(temp == 0) {
+                                       if(ply1.joy_fire) break;
+
+                                       if(ply1.joy_e && player_level < 99) {
+                                               player_level++;
+                                               drawmenu(2);
+                                       }
+                                       if(ply1.joy_w && player_level > 0) {
+                                               player_level--;
+                                               drawmenu(2);
+                                       }
+                                       if(ply1.joy_n && pos > 0) {
+                                               drawmenu(pos);
+                                               pos--;
+                                               title_blitants(4 + pos);
+                                       }
+                                       if(ply1.joy_s && pos < 4) {
+                                               drawmenu(pos);
+                                               pos++;
+                                               title_blitants(4 + pos);
+                                       }
+                               }
+                               temp = (ply1.joy_n || ply1.joy_e || ply1.joy_s || ply1.joy_w || ply1.joy_fire);
+                       }
+               }
+
+#if 0
+               printf("--> M4: xwindow == %ld\n", xwindow);
+#endif
+
+               name[MAXNAME] = 0;
+               snprintf(name, MAXNAME+2, "%s/lev%02d", EM_LVL_DIR, player_level);
+               if(name[MAXNAME]) snprintf_overflow("read a level in cave/");
+
+               if(cave_convert(name)) continue;
+
+#if 0
+               printf("--> M5: xwindow == %ld\n", xwindow);
+#endif
+
+               game_initscreen();
+#if 0
+               printf("--> M6: xwindow == %ld\n", xwindow);
+#endif
+               game_blitscore();
+#if 0
+               printf("--> M7: xwindow == %ld\n", xwindow);
+#endif
+               game_animscreen();
+
+#if 0
+               printf("--> M8: xwindow == %ld\n", xwindow);
+#endif
+
+               for(;;) {
+                       input_eventloop();
+                       if(input_die || input_esc) break;
+                       if(input_refresh) blitscreen();
+
+                       if(!input_pause) {
+                               game_animscreen();
+
+                               frame = (frame - 1) & 7;
+
+                               readjoy();
+
+                               if(frame == 7) {
+                                       synchro_1();
+                                       synchro_2();
+                               }
+                               if(frame == 6) {
+                                       synchro_3();
+                                       sound_play();
+                                       game_blitscore();
+                               }
+                       }
+               }
+       }
+}
+
+/* read input device for players
+ */
+void readjoy(void)
+{
+       unsigned int i;
+       unsigned int north = 0, east = 0, south = 0, west = 0, fire = 0;
+
+       for(i = 0; i < 3; i++) if(keymatrix[northKeyCode[i] >> 3] & 1 << (northKeyCode[i] & 7)) north = 1;
+       for(i = 0; i < 3; i++) if(keymatrix[eastKeyCode[i] >> 3] & 1 << (eastKeyCode[i] & 7)) east = 1;
+       for(i = 0; i < 3; i++) if(keymatrix[southKeyCode[i] >> 3] & 1 << (southKeyCode[i] & 7)) south = 1;
+       for(i = 0; i < 3; i++) if(keymatrix[westKeyCode[i] >> 3] & 1 << (westKeyCode[i] & 7)) west = 1;
+       for(i = 0; i < 3; i++) if(keymatrix[fireKeyCode[i] >> 3] & 1 << (fireKeyCode[i] & 7)) fire = 1;
+
+       ply1.joy_fire = fire;
+       if(ply1.joy_stick || (north | east | south | west)) {
+               ply1.joy_n = north;
+               ply1.joy_e = east;
+               ply1.joy_s = south;
+               ply1.joy_w = west;
+       }
+}
+
+/* handle events from x windows and block until the next frame
+ */
+void input_eventloop(void)
+{
+       XEvent event;
+       unsigned int i;
+       unsigned long count;
+
+       if(input_pause) {
+               XPeekEvent(display, &event); /* block until an event arrives */
+
+               if(gettimeofday(&tv1, 0) == -1) tv1.tv_usec = 0;
+       } else {
+               XSync(display, False); /* block until all graphics are drawn */
+
+               if(gettimeofday(&tv2, 0) == -1) tv2.tv_usec = 0;
+               count = tv2.tv_usec + 1000000 - tv1.tv_usec; if(count >= 1000000) count -= 1000000;
+               tv1.tv_usec = tv2.tv_usec;
+               if(count < 25000) {
+                       tv2.tv_sec = 0;
+                       tv2.tv_usec = 25000 - count;
+#if 1
+                       select(0, 0, 0, 0, &tv2); /* sleep a bit */
+#else
+                       usleep(tv2.tv_usec);
+#endif
+               }
+       }
+
+       input_die = 0;
+       input_refresh = 0;
+       lastKeySym = NoSymbol;
+       while(XPending(display)) { /* drain the event queue */
+               XNextEvent(display, &event);
+               switch(event.xany.type) {
+               case KeyPress:
+                       XLookupString(&event.xkey, (char *)&count, 1, &lastKeySym, 0);
+                       break;
+               case Expose:
+                       if(event.xexpose.window == xwindow && event.xexpose.count == 0) input_refresh = 1;
+                       break;
+               case ClientMessage:
+                       if(event.xclient.window == xwindow && (Atom)event.xclient.data.l[0] == deleteAtom) input_die = 1;
+                       break;
+               case EnterNotify:
+                       if(event.xcrossing.window == xwindow) input_pause = 0;
+                       break;
+               case LeaveNotify:
+                       if(event.xcrossing.window == xwindow) input_pause = 1;
+                       break;
+               }
+       }
+       XQueryKeymap(display, keymatrix); /* read the keyboard */
+
+       input_esc = 0;
+       for(i = 0; i < 1; i++) if(keymatrix[escKeyCode[i] >> 3] & 1 << (escKeyCode[i] & 7)) input_esc = 1;
+}
diff --git a/src/libem/level.h b/src/libem/level.h
new file mode 100644 (file)
index 0000000..d7ca5a5
--- /dev/null
@@ -0,0 +1,91 @@
+#ifndef LEVEL_H
+#define LEVEL_H
+
+#include "tile.h"
+
+#define WIDTH 102
+#define HEIGHT 102
+
+struct LEVEL {
+       unsigned int home;     /* number of players that have to go home 0=all players home */
+       unsigned int width;    /* world width */
+       unsigned int height;   /* world height */
+       unsigned int time;     /* time remaining */
+       unsigned int required; /* emeralds needed */
+       unsigned int score;    /* score */
+
+/* fill in all below /every/ time you read a level */
+       unsigned int alien_score;           /* alien popped by stone/spring score */
+       unsigned int ameuba_time;           /* ameuba speed */
+       unsigned int android_move_cnt;      /* android move time counter */
+       unsigned int android_move_time;     /* android move reset time */
+       unsigned int android_clone_cnt;     /* android clone time counter */
+       unsigned int android_clone_time;    /* android clone reset time */
+       unsigned int ball_cnt;              /* ball time counter */
+       unsigned int ball_pos;              /* ball array pos counter */
+       unsigned int ball_random;           /* ball is random flag */
+       unsigned int ball_state;            /* ball currently on flag */
+       unsigned int ball_time;             /* ball reset time */
+       unsigned int bug_score;             /* bug popped by stone/spring score */
+       unsigned int diamond_score;         /* diamond collect score */
+       unsigned int dynamite_score;        /* dynamite collect scoer*/
+       unsigned int eater_pos;             /* eater array pos */
+       unsigned int eater_score;           /* eater popped by stone/spring score */
+       unsigned int emerald_score;         /* emerald collect score */
+       unsigned int exit_score;            /* exit score */
+       unsigned int key_score;             /* key collect score */
+       unsigned int lenses_cnt;            /* lenses time counter */
+       unsigned int lenses_score;          /* lenses collect score */
+       unsigned int lenses_time;           /* lenses reset time */
+       unsigned int magnify_cnt;           /* magnify time counter */
+       unsigned int magnify_score;         /* magnify collect score */
+       unsigned int magnify_time;          /* magnify reset time */
+       unsigned int nut_score;             /* nut crack score */
+       unsigned int shine_cnt;             /* shine counter for emerald/diamond */
+       unsigned int slurp_score;           /* slurp alien score */
+       unsigned int tank_score;            /* tank popped by stone/spring */
+       unsigned int wheel_cnt;             /* wheel time counter */
+       unsigned int wheel_x;               /* wheel x pos */
+       unsigned int wheel_y;               /* wheel y pos */
+       unsigned int wheel_time;            /* wheel reset time */
+       unsigned int wind_cnt;              /* wind time counter */
+       unsigned int wind_direction;        /* wind direction */
+       unsigned int wind_time;             /* wind reset time */
+       unsigned int wonderwall_state;      /* wonderwall currently on flag */
+       unsigned int wonderwall_time;       /* wonderwall time */
+       unsigned short eater_array[8][9];   /* eater data */
+       unsigned short ball_array[8][8];    /* ball data */
+       unsigned short android_array[TILE_MAX]; /* android clone table */
+};
+
+struct PLAYER {
+       unsigned int num;
+       unsigned int alive;
+       unsigned int dynamite;
+       unsigned int dynamite_cnt;
+       unsigned int keys;
+       unsigned int anim;
+       unsigned int x;
+       unsigned int y;
+       unsigned int oldx;
+       unsigned int oldy;
+       unsigned joy_n:1;
+       unsigned joy_e:1;
+       unsigned joy_s:1;
+       unsigned joy_w:1;
+       unsigned joy_fire:1;
+       unsigned joy_stick:1;
+       unsigned joy_spin:1;
+};
+
+extern unsigned long Random;
+
+extern struct PLAYER ply1;
+extern struct PLAYER ply2;
+extern struct LEVEL lev;
+extern unsigned short **Boom;
+extern unsigned short **Cave;
+extern unsigned short **Next;
+extern unsigned short **Draw;
+
+#endif
diff --git a/src/libem/main.c b/src/libem/main.c
new file mode 100644 (file)
index 0000000..308bfa2
--- /dev/null
@@ -0,0 +1,77 @@
+/* Emerald Mine
+ * 
+ * David Tritscher
+ * 
+ * v0.0 2000-01-06T06:43:39Z
+ *
+ * set everything up and close everything down
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "global.h"
+
+char *progname;
+char *arg_basedir;
+char *arg_display;
+char *arg_geometry;
+int arg_install;
+int arg_silence;
+
+extern void tab_generate();
+extern void ulaw_generate();
+
+int em_main(int argc, char **argv)
+{
+       int result;
+       int option;
+       extern char *optarg;
+
+       /* pre-calculate some data */
+       tab_generate();
+       ulaw_generate();
+
+       progname = strrchr(argv[0], '/'); progname = progname ? progname + 1 : argv[0];
+
+       while((option = getopt(argc, argv, "b:d:g:in")) != -1) {
+               switch(option) {
+               case 'b': arg_basedir = optarg; break;
+               case 'd': arg_display = optarg; break;
+               case 'g': arg_geometry = optarg; break;
+               case 'i': arg_install = 1; break;
+               case 'n': arg_silence = 1; break;
+               default:
+                       printf("Emerald Mine for X11 © 2000,2001 David Tritscher\n\n");
+                       printf("usage: %s [options]\n", progname);
+                       printf("\t-b    set base directory\n");
+                       printf("\t-d    server to contact\n");
+                       printf("\t-g    geometry\n");
+                       printf("\t-i    install colourmap\n");
+                       printf("\t-n    no sounds\n");
+                       exit(option == 'h' ? 0 : 1);
+               }
+       }
+       if(arg_basedir == 0) arg_basedir = getenv("EMERALD_BASE");
+
+       result = open_all(); if(result) goto fail;
+       result = game_start(); if(result) goto fail;
+       result = 0;
+fail:
+       close_all();
+       return(result);
+}
+
+/* massive kludge for buffer overflows
+ * i cant think of an elegant way to handle this situation.
+ * oh wait yes i can. dynamically allocate each string. oh well
+ */
+void snprintf_overflow(char *description)
+{
+       fprintf(stderr, "%s: %s\n", progname, "buffer overflow; check EMERALD_BASE environment variable");
+       fprintf(stderr, "%s %s\n", "Fault occured while attempting to", description);
+       abort();
+}
diff --git a/src/libem/sample.h b/src/libem/sample.h
new file mode 100644 (file)
index 0000000..680aff0
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef SAMPLE_H
+#define SAMPLE_H
+
+enum {
+       SAMPLE_blank = 0, /* player walks on blank */
+       SAMPLE_roll, /* player pushes stone/bomb/nut */
+       SAMPLE_stone, /* stone hits ground */
+       SAMPLE_nut, /* nut hits ground */
+       SAMPLE_crack, /* stone hits nut */
+       SAMPLE_bug, /* bug moves */
+       SAMPLE_tank, /* tank moves */
+       SAMPLE_android, /* android places something */
+       SAMPLE_spring, /* spring hits ground/wall/bumper, stone hits spring */
+       SAMPLE_slurp, /* spring kills alien */
+       SAMPLE_eater, /* eater sits/eats diamond */
+       SAMPLE_alien, /* alien moves */
+       SAMPLE_collect, /* player collects diamond/emerald/dynamite/key/lenses/magnify */
+       SAMPLE_diamond, /* diamond/emerald hits ground */
+       SAMPLE_squash, /* stone squashes diamond, stone/emerald/diamond thru wonderwall */
+       SAMPLE_drip, /* drip hits ground */
+       SAMPLE_push, /* player pushes spring/balloon/android */
+       SAMPLE_dirt, /* player walks on dirt */
+       SAMPLE_acid, /* acid splashes */
+       SAMPLE_ball, /* ball places something */
+       SAMPLE_grow, /* growing wall grows */
+       SAMPLE_wonder, /* wonderwall moves */
+       SAMPLE_door, /* player goes thru door */
+       SAMPLE_exit, /* player goes in exit */
+       SAMPLE_dynamite, /* player places dynamite */
+       SAMPLE_tick, /* dynamite ticks */
+       SAMPLE_press, /* player presses wheel/wind/switch */
+       SAMPLE_wheel, /* wheel moves */
+       SAMPLE_boom, /* explosion */
+       SAMPLE_time, /* time runs out */
+       SAMPLE_die, /* player dies */
+       SAMPLE_MAX
+};
+
+extern char play[SAMPLE_MAX];
+extern int sound_pipe[2];
+extern short *sound_data[SAMPLE_MAX];
+extern long sound_length[SAMPLE_MAX];
+
+#define MIXER_MAX 4 /* maximum number of samples we can play at once */
+
+enum { AUDIO_ULAW = 0, AUDIO_U8 };
+
+#endif
diff --git a/src/libem/sound.c b/src/libem/sound.c
new file mode 100644 (file)
index 0000000..57fec5a
--- /dev/null
@@ -0,0 +1,337 @@
+/* 2000-08-10T17:39:15Z
+ *
+ * handle sounds in emerald mine
+ */
+
+#include "../libgame/platform.h"
+
+#if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD)
+
+#ifdef PLATFORM_LINUX
+#include <sys/soundcard.h>
+#endif
+
+#ifdef PLATFORM_BSD
+#include <soundcard.h>
+#endif
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "global.h"
+#include "sample.h"
+
+static char audioname[] = "/dev/audio";
+
+static const int sound_priority[SAMPLE_MAX] = {
+       SAMPLE_exit, SAMPLE_die, SAMPLE_time, SAMPLE_boom, SAMPLE_tick,
+       SAMPLE_collect, SAMPLE_roll, SAMPLE_push, SAMPLE_dynamite, SAMPLE_press,
+       SAMPLE_door, SAMPLE_dirt, SAMPLE_blank, SAMPLE_android, SAMPLE_ball,
+       SAMPLE_grow, SAMPLE_squash, SAMPLE_crack, SAMPLE_slurp, SAMPLE_drip,
+       SAMPLE_wonder, SAMPLE_wheel, SAMPLE_stone, SAMPLE_spring, SAMPLE_diamond,
+       SAMPLE_nut, SAMPLE_bug, SAMPLE_tank, SAMPLE_eater, SAMPLE_alien,
+       SAMPLE_acid
+};
+
+int sound_thread(void)
+{
+       int audio_fd; /* file descriptor of /dev/audio or -1 if not open */
+       int audio_format;
+       int sample_rate;
+       int fragment_size;
+       unsigned char *audio_buffer; /* actual buffer pumped to /dev/audio */
+       short *mix_buffer;
+
+       char sound_play[SAMPLE_MAX]; /* if set, we should be playing these sounds */
+       long sound_pos[SAMPLE_MAX]; /* position in the sound */
+       int mix_play[MIXER_MAX]; /* which sounds we have chosen to mix (calculated each time) */
+       int mix_count;
+
+       int i;
+
+loop:
+       audio_fd = -1;
+       audio_format = AUDIO_ULAW; /* defaults for non-OSS /dev/audio */
+       sample_rate = 8000;
+       fragment_size = 256;
+       audio_buffer = 0;
+       mix_buffer = 0;
+       mix_count = 0;
+
+       memset(sound_play, 0, sizeof(sound_play)); /* not playing any sounds */
+
+       for(;;) {
+               for(;;) {
+
+/* pick sounds to play, if any */
+                       if(sound_play[SAMPLE_exit] || sound_play[SAMPLE_die]) sound_play[SAMPLE_boom] = 0; /* no explosions if player goes home */
+                       mix_count = 0;
+                       for(i = 0; i < SAMPLE_MAX; i++) {
+                               if(sound_play[sound_priority[i]]) {
+                                       mix_play[mix_count++] = sound_priority[i];
+                                       if(mix_count == MIXER_MAX) break; /* cant mix too many sounds at once */
+                               }
+                       }
+
+/* check for incoming messages */
+                       if(mix_count || audio_fd != -1) { /* dont block if we are playing sounds */
+                               fd_set rfds;
+                               struct timeval tv;
+                               FD_ZERO(&rfds);
+                               FD_SET(sound_pipe[0], &rfds);
+                               tv.tv_sec = 0;
+                               tv.tv_usec = 0; /* (900000 * fragment_size / sample_rate) */
+                               i = select(sound_pipe[0] + 1, &rfds, 0, 0, &tv); /* dont block */
+                               if(i == -1) {
+                                       fprintf(stderr, "%s: %s: %s\n", progname, "select failed", strerror(errno));
+                                       goto fail;
+                               }
+                               if(i == 0) break; /* no messages */
+                       }
+
+/* get a message and start a sound */
+                       i = read(sound_pipe[0], &play, sizeof(play));
+                       if(i == -1) {
+                               fprintf(stderr, "%s: %s: %s\n", progname, "read failed", strerror(errno));
+                               goto fail;
+                       }
+                       if(i == 0) {
+                               fprintf(stderr, "%s: %s: %s\n", progname, "read sound", "Broken pipe");
+                               goto fail;
+                       }
+                       if(i != sizeof(play)) {
+                               fprintf(stderr, "%s: %s\n", progname, "bad message length");
+                               goto fail;
+                       }
+                       for(i = 0; i < SAMPLE_MAX; i++) {
+                               if(play[i]) {
+                                       sound_play[i] = 1; /* play this sound */
+                                       sound_pos[i] = 0; /* start it from the start */
+                               }
+                       }
+               }
+
+/* open the audio device if there are sounds to play */
+               if(mix_count && audio_fd == -1) {
+                       audio_fd = open(audioname, O_WRONLY);
+                       if(audio_fd == -1) goto reset;
+#ifdef OPEN_SOUND_SYSTEM
+                       i = 0x00020008;
+                       if(ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &i) == -1) {
+                               fprintf(stderr, "%s: \"%s\": %s (%d): %s\n", progname, audioname, "unable to set fragment size", 512, strerror(errno));
+                               goto reset;
+                       }
+                       if(ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &i) == -1) {
+                               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, audioname, "unable to query audio format", strerror(errno));
+                               goto reset;
+                       }
+                       audio_format = (i & AFMT_U8) ? AFMT_U8 : AFMT_MU_LAW; /* prefer 8 bit unsigned and fall back on mu-law */
+                       i = audio_format;
+                       if(ioctl(audio_fd, SNDCTL_DSP_SETFMT, &i) == -1) {
+                               fprintf(stderr, "%s: \"%s\": %s (%d): %s\n", progname, audioname, "unable to set audio format", audio_format, strerror(errno));
+                               goto reset;
+                       }
+                       if(i == AFMT_MU_LAW) {
+                               audio_format = AUDIO_ULAW;
+                       } else if(i == AFMT_U8) {
+                               audio_format = AUDIO_U8;
+                       } else {
+                               fprintf(stderr, "%s: \"%s\": %s (%d)\n", progname, audioname, "audio format required by device not supported", i);
+                               goto reset;
+                       }
+                       i = 1;
+                       if(ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &i) == -1) {
+                               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, audioname, "unable to set channels to mono", strerror(errno));
+                               goto reset;
+                       }
+                       if(i != 1) {
+                               fprintf(stderr, "%s: \"%s\": %s (%d)\n", progname, audioname, "channels required by device not supported", i);
+                               goto reset;
+                       }
+                       i = 8000;
+                       if(ioctl(audio_fd, SNDCTL_DSP_SPEED, &i) == -1) {
+                               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, audioname, "unable to set sampling rate", strerror(errno));
+                               goto reset;
+                       }
+                       sample_rate = i;
+                       if(ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &i) == -1) {
+                               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, audioname, "unable to get block size", strerror(errno));
+                               goto reset;
+                       }
+                       fragment_size = i;
+#else
+                       if(fcntl(audio_fd, F_SETFL, O_NONBLOCK) == -1) {
+                               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, audioname, "unable to make audio non blocking", strerror(errno));
+                               goto reset;
+                       }
+#endif /* OPEN_SOUND_SYSTEM */
+                       audio_buffer = malloc(fragment_size * sizeof(*audio_buffer));
+                       if(audio_buffer == 0) {
+                               fprintf(stderr, "%s: %s (%d): %s\n", progname, "unable to malloc audio buffer", fragment_size * sizeof(*audio_buffer), strerror(errno));
+                               goto fail;
+                       }
+                       mix_buffer = malloc(fragment_size * sizeof(*mix_buffer));
+                       if(mix_buffer == 0) {
+                               fprintf(stderr, "%s: %s (%d): %s\n", progname, "unable to malloc mixing buffer", fragment_size * sizeof(*mix_buffer), strerror(errno));
+                               goto fail;
+                       }
+               }
+
+/* close the audio device if no sounds are playing */
+               if(mix_count == 0 && audio_fd != -1) {
+                       close(audio_fd);
+                       free(audio_buffer);
+                       free(mix_buffer);
+                       audio_fd = -1;
+                       audio_buffer = 0;
+                       mix_buffer = 0;
+               }
+
+/* if we are playing sounds and the audio device is open, mix them */
+               if(mix_count && audio_fd != -1) {
+
+                       memset(mix_buffer, 0, fragment_size * sizeof(*mix_buffer)); /* prepare mix buffer */
+
+                       for(i = 0; i < mix_count; i++) {
+                               register short *mix_ptr = mix_buffer;
+                               register short *sound_ptr = sound_data[mix_play[i]] + sound_pos[mix_play[i]];
+                               register long count = sound_length[mix_play[i]] - sound_pos[mix_play[i]];
+                               if(count > fragment_size) count = fragment_size;
+                               while(count--) *mix_ptr++ += *sound_ptr++; /* mix the sounds in */
+                       }
+                       switch(audio_format) {
+                       case AUDIO_ULAW:
+                               for(i = 0; i < fragment_size; i++) audio_buffer[i] = linear_to_ulaw[mix_buffer[i] + 32768];
+                               break;
+                       case AUDIO_U8:
+                               for(i = 0; i < fragment_size; i++) audio_buffer[i] = (mix_buffer[i] + 32768) >> 8;
+                               break;
+                       }
+
+/* advance sound pointers */
+                       for(i = 0; i < SAMPLE_MAX; i++) {
+                               if(sound_play[i]) {
+                                       if(sound_pos[i] + fragment_size < sound_length[i]) {
+                                               sound_pos[i] += fragment_size;
+                                       } else {
+                                               sound_play[i] = 0;
+                                       }
+                               }
+                       }
+
+/* send the data to the audio device */
+                       i = write(audio_fd, audio_buffer, fragment_size);
+                       if(i == -1) {
+                               fprintf(stderr, "%s: %s: %s\n", progname, "write error", strerror(errno));
+                               goto reset;
+                       }
+                       if(i != fragment_size) {
+                               fprintf(stderr, "%s: %s\n", progname, "bad write length");
+                               goto reset;
+                       }
+               }
+       } /* for */
+
+reset:
+       if(audio_fd != -1) close(audio_fd);
+       if(audio_buffer) free(audio_buffer);
+       if(mix_buffer) free(mix_buffer);
+       goto loop; /* back to top */
+
+fail:
+       if(audio_fd != -1) close(audio_fd);
+       if(audio_buffer) free(audio_buffer);
+       if(mix_buffer) free(mix_buffer);
+       return(0);
+}
+
+int read_sample(char *name, short **data, long *length)
+{
+       int result;
+       FILE *file = 0;
+       short *dataptr = 0;
+       long datalength;
+
+       int i, actual, ch;
+       unsigned char buffer[24];
+       unsigned long temp;
+
+       file = fopen(name, "rb");
+       if(file == 0) {
+               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, name, "open error", strerror(errno));
+               result = 1; goto fail;
+       }
+       actual = fread(buffer, 1, 24, file);
+       if(actual == -1) {
+               fprintf(stderr, "%s: \"%s\": %s: %s\n", progname, name, "read error", strerror(errno));
+               result = 1; goto fail;
+       }
+       if(actual < 24) {
+               fprintf(stderr, "%s: \"%s\": %s\n", progname, name, "premature eof");
+               result = 1; goto fail;
+       }
+       temp = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; /* magic */
+       if(temp != 0x2e736e64) {
+               fprintf(stderr, "%s: \"%s\": %s\n", progname, name, "unrecognized file format");
+               result = 1; goto fail;
+       }
+       temp = buffer[4] << 24 | buffer[5] << 16 | buffer[6] << 8 | buffer[7]; /* header length */
+       if(temp < 24) {
+               fprintf(stderr, "%s: \"%s\": %s\n", progname, name, "bad header length");
+               result = 1; goto fail;
+       }
+       actual = temp;
+       for(i = 24; i < actual; i++) { /* skip the rest of the header */
+               ch = fgetc(file);
+               if(ch == EOF) break;
+       }
+
+       temp = buffer[8] << 24 | buffer[9] << 16 | buffer[10] << 8 | buffer[11]; /* data length */
+       datalength = temp;
+       temp = buffer[12] << 24 | buffer[13] << 16 | buffer[14] << 8 | buffer[15]; /* encoding */
+       if(temp != 1) {
+               fprintf(stderr, "%s: \"%s\": %s (%ld != 1)\n", progname, name, "bad encoding type", temp);
+               result = 1; goto fail;
+       }
+       temp = buffer[16] << 24 | buffer[17] << 16 | buffer[18] << 8 | buffer[19]; /* sample rate */
+       if(temp != 8000) {
+               fprintf(stderr, "%s: \"%s\": %s (%ld != 8000)\n", progname, name, "bad sample rate", temp);
+               result = 1; goto fail;
+       }
+       temp = buffer[20] << 24 | buffer[21] << 16 | buffer[22] << 8 | buffer[23]; /* channels */
+       if(temp != 1) {
+               fprintf(stderr, "%s: \"%s\": %s (%ld != 1)\n", progname, name, "unsupported channels", temp);
+               result = 1; goto fail;
+       }
+
+       dataptr = malloc(datalength * sizeof(*dataptr));
+       if(dataptr == 0) {
+               fprintf(stderr, "%s: \"%s\": %s (%ld): %s\n", progname, name, "unable to malloc buffer", datalength * sizeof(*dataptr), strerror(errno));
+               result = 1; goto fail;
+       }
+
+       for(i = 0; i < datalength; i++) {
+               ch = fgetc(file);
+               if(ch == EOF) break;
+               dataptr[i] = ulaw_to_linear[ch];
+       }
+       fclose(file);
+       file = 0;
+
+       *data = dataptr;
+       *length = datalength;
+       result = 0;
+fail:
+       if(file) fclose(file);
+       return(result);
+}
+
+#endif /* defined(PLATFORM_LINUX) || defined(PLATFORM_BSD) */
diff --git a/src/libem/synchro_1.c b/src/libem/synchro_1.c
new file mode 100644 (file)
index 0000000..8b2f47f
--- /dev/null
@@ -0,0 +1,794 @@
+
+/* first part of synchro.
+ *
+ * game logic for players.
+ *
+ * large switch statement for tiles the player interacts with.
+ */
+
+#include "tile.h"
+#include "level.h"
+#include "sample.h"
+
+static void player(struct PLAYER *);
+static int test(struct PLAYER *);
+static void die(struct PLAYER *);
+
+void synchro_1(void)
+{
+       char ply1_kill = test(&ply1); /* must test for death and actually kill separately */
+       char ply2_kill = test(&ply2);
+       if(ply1.alive && ply1_kill) die(&ply1);
+       if(ply2.alive && ply2_kill) die(&ply2);
+
+#if 0
+       ply1.alive = 1; /* debugging */
+#endif
+
+       ply1.oldx = ply1.x;
+       ply1.oldy = ply1.y;
+       ply1.anim = SPR_still;
+       ply2.oldx = ply2.x;
+       ply2.oldy = ply2.y;
+       ply2.anim = SPR_still;
+
+       if(Random & 256) {
+               if(ply1.alive) player(&ply1);
+               if(ply2.alive) player(&ply2);
+       } else {
+               if(ply2.alive) player(&ply2);
+               if(ply1.alive) player(&ply1);
+       }
+       if(ply1.alive) {
+               if(Cave[ply1.oldy][ply1.oldx] == Zplayer) {
+                       Cave[ply1.oldy][ply1.oldx] = Xblank;
+                       Next[ply1.oldy][ply1.oldx] = Xblank;
+               }
+               if(Cave[ply1.y][ply1.x] == Xblank) {
+                       Cave[ply1.y][ply1.x] = Zplayer;
+                       Next[ply1.y][ply1.x] = Zplayer;
+               }
+       }
+       if(ply2.alive) {
+               if(Cave[ply2.oldy][ply2.oldx] == Zplayer) {
+                       Cave[ply2.oldy][ply2.oldx] = Xblank;
+                       Next[ply2.oldy][ply2.oldx] = Xblank;
+               }
+               if(Cave[ply2.y][ply2.x] == Xblank) {
+                       Cave[ply2.y][ply2.x] = Zplayer;
+                       Next[ply2.y][ply2.x] = Zplayer;
+               }
+       }
+}
+
+static int test(struct PLAYER *ply)
+{
+       register unsigned int x = ply->x;
+       register unsigned int y = ply->y;
+
+       if(lev.time == 0) return(1);
+
+       switch(Cave[y-1][x]) {
+       case Xbug_n:
+       case Xbug_e:
+       case Xbug_s:
+       case Xbug_w:
+       case Xbug_gon:
+       case Xbug_goe:
+       case Xbug_gos:
+       case Xbug_gow:
+       case Xtank_n:
+       case Xtank_e:
+       case Xtank_s:
+       case Xtank_w:
+       case Xtank_gon:
+       case Xtank_goe:
+       case Xtank_gos:
+       case Xtank_gow:
+               return(1);
+       }
+       switch(Cave[y][x+1]) {
+       case Xbug_n:
+       case Xbug_e:
+       case Xbug_s:
+       case Xbug_w:
+       case Xbug_gon:
+       case Xbug_goe:
+       case Xbug_gos:
+       case Xbug_gow:
+       case Xtank_n:
+       case Xtank_e:
+       case Xtank_s:
+       case Xtank_w:
+       case Xtank_gon:
+       case Xtank_goe:
+       case Xtank_gos:
+       case Xtank_gow:
+               return(1);
+       }
+       switch(Cave[y+1][x]) {
+       case Xbug_n:
+       case Xbug_e:
+       case Xbug_s:
+       case Xbug_w:
+       case Xbug_gon:
+       case Xbug_goe:
+       case Xbug_gos:
+       case Xbug_gow:
+       case Xtank_n:
+       case Xtank_e:
+       case Xtank_s:
+       case Xtank_w:
+       case Xtank_gon:
+       case Xtank_goe:
+       case Xtank_gos:
+       case Xtank_gow:
+               return(1);
+       }
+       switch(Cave[y][x-1]) {
+       case Xbug_n:
+       case Xbug_e:
+       case Xbug_s:
+       case Xbug_w:
+       case Xbug_gon:
+       case Xbug_goe:
+       case Xbug_gos:
+       case Xbug_gow:
+       case Xtank_n:
+       case Xtank_e:
+       case Xtank_s:
+       case Xtank_w:
+       case Xtank_gon:
+       case Xtank_goe:
+       case Xtank_gos:
+       case Xtank_gow:
+               return(1);
+       }
+       switch(Cave[y][x]) {
+       case Xblank:
+       case Yacid_splash_eB:
+       case Yacid_splash_wB:
+       case Zplayer:
+       case Xdynamite_1:
+       case Xdynamite_2:
+       case Xdynamite_3:
+       case Xdynamite_4:
+               return(0);
+       }
+       return(1);
+}
+
+static void die(struct PLAYER *ply)
+{
+       register unsigned int x = ply->x;
+       register unsigned int y = ply->y;
+
+       ply->alive = 0;
+
+       switch(Cave[y-1][x]) {
+       case Xbug_n:
+       case Xbug_e:
+       case Xbug_s:
+       case Xbug_w:
+       case Xbug_gon:
+       case Xbug_goe:
+       case Xbug_gos:
+       case Xbug_gow:
+               Cave[y-1][x] = Xboom_bug; break;
+       case Xtank_n:
+       case Xtank_e:
+       case Xtank_s:
+       case Xtank_w:
+       case Xtank_gon:
+       case Xtank_goe:
+       case Xtank_gos:
+       case Xtank_gow:
+               Cave[y-1][x] = Xboom_bomb; break;
+       }
+       switch(Cave[y][x+1]) {
+       case Xbug_n:
+       case Xbug_e:
+       case Xbug_s:
+       case Xbug_w:
+       case Xbug_gon:
+       case Xbug_goe:
+       case Xbug_gos:
+       case Xbug_gow:
+               Cave[y][x+1] = Xboom_bug; break;
+       case Xtank_n:
+       case Xtank_e:
+       case Xtank_s:
+       case Xtank_w:
+       case Xtank_gon:
+       case Xtank_goe:
+       case Xtank_gos:
+       case Xtank_gow:
+               Cave[y][x+1] = Xboom_bomb; break;
+       }
+       switch(Cave[y+1][x]) {
+       case Xbug_n:
+       case Xbug_e:
+       case Xbug_s:
+       case Xbug_w:
+       case Xbug_gon:
+       case Xbug_goe:
+       case Xbug_gos:
+       case Xbug_gow:
+               Cave[y+1][x] = Xboom_bug; break;
+       case Xtank_n:
+       case Xtank_e:
+       case Xtank_s:
+       case Xtank_w:
+       case Xtank_gon:
+       case Xtank_goe:
+       case Xtank_gos:
+       case Xtank_gow:
+               Cave[y+1][x] = Xboom_bomb; break;
+       }
+       switch(Cave[y][x-1]) {
+       case Xbug_n:
+       case Xbug_e:
+       case Xbug_s:
+       case Xbug_w:
+       case Xbug_gon:
+       case Xbug_goe:
+       case Xbug_gos:
+       case Xbug_gow:
+               Cave[y][x-1] = Xboom_bug; break;
+       case Xtank_n:
+       case Xtank_e:
+       case Xtank_s:
+       case Xtank_w:
+       case Xtank_gon:
+       case Xtank_goe:
+       case Xtank_gos:
+       case Xtank_gow:
+               Cave[y][x-1] = Xboom_bomb; break;
+       }
+       switch(Cave[y][x]) {
+       case Xexit_1:
+       case Xexit_2:
+       case Xexit_3:
+               play[SAMPLE_exit] = 1; break;
+       default:
+               play[SAMPLE_die] = 1; break;
+       }
+       Cave[y][x] = Xboom_1;
+       Boom[y][x] = Xblank;
+}
+
+static void player(struct PLAYER *ply)
+{
+       register unsigned int x = ply->x;
+       register unsigned int y = ply->y;
+       unsigned int anim = 0;  /* initialized to make compilers happy */
+       int dx = 0, dy = 0;
+
+       if((ply->joy_spin = !ply->joy_spin)) {
+               if(ply->joy_n) {
+                       y--; dy = -1; anim = 0; /* north */
+               } else if(ply->joy_e) {
+                       x++; dx = 1; anim = 1; /* east */
+               } else if(ply->joy_s) {
+                       y++; dy = 1; anim = 2; /* south */
+               } else if(ply->joy_w) {
+                       x--; dx = -1; anim = 3; /* west */
+               }
+       } else {
+               if(ply->joy_w) {
+                       x--; dx = -1; anim = 3; /* west */
+               } else if(ply->joy_s) {
+                       y++; dy = 1; anim = 2; /* south */
+               } else if(ply->joy_e) {
+                       x++; dx = 1; anim = 1; /* east */
+               } else if(ply->joy_n) {
+                       y--; dy = -1; anim = 0; /* north */
+               }
+       }
+       if(dx == 0 && dy == 0) {
+               ply->joy_stick = 0;
+               if(ply->joy_fire) {
+                       if(++ply->dynamite_cnt == 5 && ply->dynamite) {
+                               Cave[y][x] = Xdynamite_1;
+                               play[SAMPLE_dynamite] = 1;
+                               ply->dynamite--;
+                       }
+               } else {
+                       ply->dynamite_cnt = 0;
+               }
+               Random += 7; /* bit more random if we dont move */
+               return;
+       }
+       ply->joy_stick = 1;
+       ply->joy_n = ply->joy_e = ply->joy_s = ply->joy_w = 0;
+       ply->dynamite_cnt = 0; /* reset dynamite timer if we move */
+
+       if(ply->joy_fire == 0) {
+               switch(Cave[y][x]) { /* fire is released */
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Zplayer;
+                       Next[y][x] = Zplayer;
+                       play[SAMPLE_blank] = 1;
+                       ply->anim = SPR_walk + anim;
+                       ply->x = x;
+                       ply->y = y;
+                       break;
+               case Xboom_android:
+               case Xboom_1:
+               case Xbug_n:
+               case Xbug_e:
+               case Xbug_s:
+               case Xbug_w:
+               case Xbug_gon:
+               case Xbug_goe:
+               case Xbug_gos:
+               case Xbug_gow:
+               case Xtank_n:
+               case Xtank_e:
+               case Xtank_s:
+               case Xtank_w:
+               case Xtank_gon:
+               case Xtank_goe:
+               case Xtank_gos:
+               case Xtank_gow:
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       ply->anim = SPR_walk + anim;
+                       ply->x = x;
+                       ply->y = y;
+                       break;
+               case Xgrass:
+                       Cave[y][x] = dy ? (dy < 0 ? Ygrass_nB : Ygrass_sB) : (dx > 0 ? Ygrass_eB : Ygrass_wB);
+                       Next[y][x] = Zplayer;
+                       play[SAMPLE_dirt] = 1;
+                       ply->anim = SPR_walk + anim;
+                       ply->x = x;
+                       ply->y = y;
+                       break;
+               case Xdirt:
+                       Cave[y][x] = dy ? (dy < 0 ? Ydirt_nB : Ydirt_sB) : (dx > 0 ? Ydirt_eB : Ydirt_wB);
+                       Next[y][x] = Zplayer;
+                       play[SAMPLE_dirt] = 1;
+                       ply->anim = SPR_walk + anim;
+                       ply->x = x;
+                       ply->y = y;
+                       break;
+               case Xdiamond:
+               case Xdiamond_pause:
+                       Cave[y][x] = Ydiamond_eat;
+                       Next[y][x] = Zplayer;
+                       play[SAMPLE_collect] = 1;
+                       lev.score += lev.diamond_score;
+                       lev.required = lev.required < 3 ? 0 : lev.required - 3;
+                       ply->anim = SPR_walk + anim;
+                       ply->x = x;
+                       ply->y = y;
+                       break;
+               case Xemerald:
+               case Xemerald_pause:
+                       Cave[y][x] = Yemerald_eat;
+                       Next[y][x] = Zplayer;
+                       play[SAMPLE_collect] = 1;
+                       lev.score += lev.emerald_score;
+                       lev.required = lev.required < 1 ? 0 : lev.required - 1;
+                       ply->anim = SPR_walk + anim;
+                       ply->x = x;
+                       ply->y = y;
+                       break;
+               case Xdynamite:
+                       Cave[y][x] = Ydynamite_eat;
+                       Next[y][x] = Zplayer;
+                       play[SAMPLE_collect] = 1;
+                       lev.score += lev.dynamite_score;
+                       ply->dynamite = ply->dynamite > 9998 ? 9999 : ply->dynamite + 1;
+                       ply->anim = SPR_walk + anim;
+                       ply->x = x;
+                       ply->y = y;
+                       break;
+               case Xkey_1:
+                       ply->keys |= 0x01; goto key_walk;
+               case Xkey_2:
+                       ply->keys |= 0x02; goto key_walk;
+               case Xkey_3:
+                       ply->keys |= 0x04; goto key_walk;
+               case Xkey_4:
+                       ply->keys |= 0x08; goto key_walk;
+               case Xkey_5:
+                       ply->keys |= 0x10; goto key_walk;
+               case Xkey_6:
+                       ply->keys |= 0x20; goto key_walk;
+               case Xkey_7:
+                       ply->keys |= 0x40; goto key_walk;
+               case Xkey_8:
+                       ply->keys |= 0x80; goto key_walk;
+               key_walk:
+                       Cave[y][x] = Yball_eat;
+                       Next[y][x] = Zplayer;
+                       play[SAMPLE_collect] = 1;
+                       lev.score += lev.key_score;
+                       ply->anim = SPR_walk + anim;
+                       ply->x = x;
+                       ply->y = y;
+                       break;
+               case Xlenses:
+                       Cave[y][x] = Yball_eat;
+                       Next[y][x] = Zplayer;
+                       play[SAMPLE_collect] = 1;
+                       lev.score += lev.lenses_score;
+                       lev.lenses_cnt = lev.lenses_time;
+                       ply->anim = SPR_walk + anim;
+                       ply->x = x;
+                       ply->y = y;
+                       break;
+               case Xmagnify:
+                       Cave[y][x] = Yball_eat;
+                       Next[y][x] = Zplayer;
+                       play[SAMPLE_collect] = 1;
+                       lev.score += lev.magnify_score;
+                       lev.magnify_cnt = lev.magnify_time;
+                       ply->anim = SPR_walk + anim;
+                       ply->x = x;
+                       ply->y = y;
+                       break;
+               case Xstone:
+                       if(dy) break;
+                       switch(Cave[y][x+dx]) {
+                       case Xacid_1:
+                       case Xacid_2:
+                       case Xacid_3:
+                       case Xacid_4:
+                       case Xacid_5:
+                       case Xacid_6:
+                       case Xacid_7:
+                       case Xacid_8:
+                               if(Cave[y-1][x+dx+1] == Xblank) Cave[y-1][x+dx+1] = Yacid_splash_eB;
+                               if(Cave[y-1][x+dx-1] == Xblank) Cave[y-1][x+dx-1] = Yacid_splash_wB;
+                               play[SAMPLE_acid] = 1;
+                               goto stone_walk;
+                       case Xblank:
+                       case Yacid_splash_eB:
+                       case Yacid_splash_wB:
+                               Cave[y][x+dx] = dx > 0 ? Ystone_e : Ystone_w;
+                               Next[y][x+dx] = Xstone_pause;
+                       stone_walk:
+                               Cave[y][x] = dx > 0 ? Ystone_eB : Ystone_wB;
+                               Next[y][x] = Zplayer;
+                               play[SAMPLE_roll] = 1;
+                               ply->x = x;
+                       }
+                       ply->anim = SPR_push + anim;
+                       break;
+               case Xbomb:
+                       if(dy) break;
+                       switch(Cave[y][x+dx]) {
+                       case Xacid_1:
+                       case Xacid_2:
+                       case Xacid_3:
+                       case Xacid_4:
+                       case Xacid_5:
+                       case Xacid_6:
+                       case Xacid_7:
+                       case Xacid_8:
+                               if(Cave[y-1][x+dx+1] == Xblank) Cave[y-1][x+dx+1] = Yacid_splash_eB;
+                               if(Cave[y-1][x+dx-1] == Xblank) Cave[y-1][x+dx-1] = Yacid_splash_wB;
+                               play[SAMPLE_acid] = 1;
+                               goto bomb_walk;
+                       case Xblank:
+                       case Yacid_splash_eB:
+                       case Yacid_splash_wB:
+                               Cave[y][x+dx] = dx > 0 ? Ybomb_e : Ybomb_w;
+                               Next[y][x+dx] = Xbomb_pause;
+                       bomb_walk:
+                               Cave[y][x] = dx > 0 ? Ybomb_eB : Ybomb_wB;
+                               Next[y][x] = Zplayer;
+                               play[SAMPLE_roll] = 1;
+                               ply->x = x;
+                       }
+                       ply->anim = SPR_push + anim;
+                       break;
+               case Xnut:
+                       if(dy) break;
+                       switch(Cave[y][x+dx]) {
+                       case Xacid_1:
+                       case Xacid_2:
+                       case Xacid_3:
+                       case Xacid_4:
+                       case Xacid_5:
+                       case Xacid_6:
+                       case Xacid_7:
+                       case Xacid_8:
+                               if(Cave[y-1][x+dx+1] == Xblank) Cave[y-1][x+dx+1] = Yacid_splash_eB;
+                               if(Cave[y-1][x+dx-1] == Xblank) Cave[y-1][x+dx-1] = Yacid_splash_wB;
+                               play[SAMPLE_acid] = 1;
+                               goto nut_walk;
+                       case Xblank:
+                       case Yacid_splash_eB:
+                       case Yacid_splash_wB:
+                               Cave[y][x+dx] = dx > 0 ? Ynut_e : Ynut_w;
+                               Next[y][x+dx] = Xnut_pause;
+                       nut_walk:
+                               Cave[y][x] = dx > 0 ? Ynut_eB : Ynut_wB;
+                               Next[y][x] = Zplayer;
+                               play[SAMPLE_roll] = 1;
+                               ply->x = x;
+                       }
+                       ply->anim = SPR_push + anim;
+                       break;
+               case Xspring:
+                       if(dy) break;
+                       switch(Cave[y][x+dx]) {
+                       case Xalien:
+                       case Xalien_pause:
+                               Cave[y][x] = dx > 0 ? Yspring_kill_eB : Yspring_kill_wB;
+                               Cave[y][x+dx] = dx > 0 ? Yspring_kill_e : Yspring_kill_w;
+                               Next[y][x] = Zplayer;
+                               Next[y][x+dx] = dx > 0 ? Xspring_e : Xspring_w;
+                               play[SAMPLE_slurp] = 1;
+                               lev.score += lev.slurp_score;
+                               ply->x = x;
+                               break;
+                       case Xacid_1:
+                       case Xacid_2:
+                       case Xacid_3:
+                       case Xacid_4:
+                       case Xacid_5:
+                       case Xacid_6:
+                       case Xacid_7:
+                       case Xacid_8:
+                               if(Cave[y-1][x+dx+1] == Xblank) Cave[y-1][x+dx+1] = Yacid_splash_eB;
+                               if(Cave[y-1][x+dx-1] == Xblank) Cave[y-1][x+dx-1] = Yacid_splash_wB;
+                               play[SAMPLE_acid] = 1;
+                               goto spring_walk;
+                       case Xblank:
+                       case Yacid_splash_eB:
+                       case Yacid_splash_wB:
+                               Cave[y][x+dx] = dx > 0 ? Yspring_e : Yspring_w;
+                               Next[y][x+dx] = dx > 0 ? Xspring_e : Xspring_w;
+                       spring_walk:
+                               Cave[y][x] = dx > 0 ? Yspring_eB : Yspring_wB;
+                               Next[y][x] = Zplayer;
+                               play[SAMPLE_roll] = 1;
+                               ply->x = x;
+                       }
+                       ply->anim = SPR_push + anim;
+                       break;
+               case Xspring_pause:
+               case Xstone_pause:
+               case Xbomb_pause:
+               case Xnut_pause:
+               case Xsand_stonein_1:
+               case Xsand_stonein_2:
+               case Xsand_stonein_3:
+               case Xsand_stonein_4:
+                       if(dy) break;
+                       ply->anim = SPR_push + anim;
+                       break;
+               case Xballoon:
+                       switch(Cave[y+dy][x+dx]) {
+                       case Xacid_1:
+                       case Xacid_2:
+                       case Xacid_3:
+                       case Xacid_4:
+                       case Xacid_5:
+                       case Xacid_6:
+                       case Xacid_7:
+                       case Xacid_8:
+                               if(Cave[y+dy-1][x+dx+1] == Xblank) Cave[y+dy-1][x+dx+1] = Yacid_splash_eB;
+                               if(Cave[y+dy-1][x+dx-1] == Xblank) Cave[y+dy-1][x+dx-1] = Yacid_splash_wB;
+                               play[SAMPLE_acid] = 1;
+                               goto balloon_walk;
+                       case Xblank:
+                       case Yacid_splash_eB:
+                       case Yacid_splash_wB:
+                               Cave[y+dy][x+dx] = dy ? (dy < 0 ? Yballoon_n : Yballoon_s) : (dx > 0 ? Yballoon_e : Yballoon_w);
+                               Next[y+dy][x+dx] = Xballoon;
+                       balloon_walk:
+                               Cave[y][x] = dy ? (dy < 0 ? Yballoon_nB : Yballoon_sB) : (dx > 0 ? Yballoon_eB : Yballoon_wB);
+                               Next[y][x] = Zplayer;
+                               play[SAMPLE_push] = 1;
+                               ply->x = x;
+                               ply->y = y;
+                       }
+                       ply->anim = SPR_push + anim;
+                       break;
+               case Xandroid:
+               case Xandroid_1_n:
+               case Xandroid_2_n:
+               case Xandroid_1_e:
+               case Xandroid_2_e:
+               case Xandroid_1_s:
+               case Xandroid_2_s:
+               case Xandroid_1_w:
+               case Xandroid_2_w:
+                       switch(Cave[y+dy][x+dx]) {
+                       case Xacid_1:
+                       case Xacid_2:
+                       case Xacid_3:
+                       case Xacid_4:
+                       case Xacid_5:
+                       case Xacid_6:
+                       case Xacid_7:
+                       case Xacid_8:
+                               if(Cave[y+dy-1][x+dx+1] == Xblank) Cave[y+dy-1][x+dx+1] = Yacid_splash_eB;
+                               if(Cave[y+dy-1][x+dx-1] == Xblank) Cave[y+dy-1][x+dx-1] = Yacid_splash_wB;
+                               play[SAMPLE_acid] = 1;
+                               goto android_walk;
+                       case Xblank:
+                       case Yacid_splash_eB:
+                       case Yacid_splash_wB:
+                               Cave[y+dy][x+dx] = dy ? (dy < 0 ? Yandroid_n : Yandroid_s) : (dx > 0 ? Yandroid_e : Yandroid_w);
+                               Next[y+dy][x+dx] = dy ? (dy < 0 ? Xandroid_2_n : Xandroid_2_s) : (dx > 0 ? Xandroid_2_e : Xandroid_2_w);
+                       android_walk:
+                               Cave[y][x] = dy ? (dy < 0 ? Yandroid_nB : Yandroid_sB) : (dx > 0 ? Yandroid_eB : Yandroid_wB);
+                               Next[y][x] = Zplayer;
+                               play[SAMPLE_push] = 1;
+                               ply->x = x;
+                               ply->y = y;
+                       }
+                       ply->anim = SPR_push + anim;
+                       break;
+               case Xdoor_1:
+               case Xfake_door_1:
+                       if(ply->keys & 0x01) goto door_walk; else break;
+               case Xdoor_2:
+               case Xfake_door_2:
+                       if(ply->keys & 0x02) goto door_walk; else break;
+               case Xdoor_3:
+               case Xfake_door_3:
+                       if(ply->keys & 0x04) goto door_walk; else break;
+               case Xdoor_4:
+               case Xfake_door_4:
+                       if(ply->keys & 0x08) goto door_walk; else break;
+               case Xdoor_5:
+               case Xfake_door_5:
+                       if(ply->keys & 0x10) goto door_walk; else break;
+               case Xdoor_6:
+               case Xfake_door_6:
+                       if(ply->keys & 0x20) goto door_walk; else break;
+               case Xdoor_7:
+               case Xfake_door_7:
+                       if(ply->keys & 0x40) goto door_walk; else break;
+               case Xdoor_8:
+               case Xfake_door_8:
+                       if(ply->keys & 0x80) goto door_walk; else break;
+               door_walk:
+                       if(!tab_blank[Cave[y+dy][x+dx]]) break;
+                       Cave[y+dy][x+dx] = Zplayer;
+                       Next[y+dy][x+dx] = Zplayer;
+                       play[SAMPLE_door] = 1;
+                       ply->anim = SPR_walk + anim;
+                       ply->x = x + dx;
+                       ply->y = y + dy;
+                       break;
+               case Xwheel:
+                       play[SAMPLE_press] = 1;
+                       lev.wheel_cnt = lev.wheel_time;
+                       lev.wheel_x = x;
+                       lev.wheel_y = y;
+                       break;
+               case Xwind_n:
+                       lev.wind_direction = 0; goto wind_walk;
+               case Xwind_e:
+                       lev.wind_direction = 1; goto wind_walk;
+               case Xwind_s:
+                       lev.wind_direction = 2; goto wind_walk;
+               case Xwind_w:
+                       lev.wind_direction = 3; goto wind_walk;
+               case Xwind_nesw:
+                       lev.wind_direction = dy ? (dy < 0 ? 0 : 2) : (dx > 0 ? 1 : 3); goto wind_walk;
+               wind_walk:
+                       play[SAMPLE_press] = 1;
+                       lev.wind_cnt = lev.wind_time;
+                       break;
+               case Xwind_stop:
+                       play[SAMPLE_press] = 1;
+                       lev.wind_cnt = 0;
+                       break;
+               case Xswitch:
+                       play[SAMPLE_press] = 1;
+                       lev.ball_cnt = lev.ball_time;
+                       lev.ball_state = !lev.ball_state;
+                       break;
+               case Xplant:
+                       Cave[y][x] = Yplant;
+                       Next[y][x] = Xplant;
+                       play[SAMPLE_blank] = 1;
+                       ply->anim = SPR_walk + anim;
+                       ply->x = x;
+                       ply->y = y;
+                       break;
+               case Xexit_1:
+               case Xexit_2:
+               case Xexit_3:
+                       play[SAMPLE_exit] = 1;
+                       if(--lev.home == 0) lev.score += lev.time * lev.exit_score / 100;
+                       ply->anim = SPR_walk + anim;
+                       ply->x = x;
+                       ply->y = y;
+                       break;
+               }
+       } else {
+               switch(Cave[y][x]) { /* fire is pressed */
+               case Xgrass:
+               case Xdirt:
+                       Cave[y][x] = Yball_eat;
+                       Next[y][x] = Xblank;
+                       play[SAMPLE_dirt] = 1;
+                       ply->anim = SPR_spray + anim;
+                       break;
+               case Xdiamond:
+               case Xdiamond_pause:
+                       Cave[y][x] = Ydiamond_eat;
+                       Next[y][x] = Xblank;
+                       play[SAMPLE_collect] = 1;
+                       lev.score += lev.diamond_score;
+                       lev.required = lev.required < 3 ? 0 : lev.required - 3;
+                       ply->anim = SPR_walk + anim;
+                       break;
+               case Xemerald:
+               case Xemerald_pause:
+                       Cave[y][x] = Yemerald_eat;
+                       Next[y][x] = Xblank;
+                       play[SAMPLE_collect] = 1;
+                       lev.score += lev.emerald_score;
+                       lev.required = lev.required < 1 ? 0 : lev.required - 1;
+                       ply->anim = SPR_walk + anim;
+                       break;
+               case Xdynamite:
+                       Cave[y][x] = Ydynamite_eat;
+                       Next[y][x] = Xblank;
+                       play[SAMPLE_collect] = 1;
+                       lev.score += lev.dynamite_score;
+                       ply->dynamite = ply->dynamite > 9998 ? 9999 : ply->dynamite + 1;
+                       ply->anim = SPR_walk + anim;
+                       break;
+               case Xkey_1:
+                       ply->keys |= 0x01; goto key_shoot;
+               case Xkey_2:
+                       ply->keys |= 0x02; goto key_shoot;
+               case Xkey_3:
+                       ply->keys |= 0x04; goto key_shoot;
+               case Xkey_4:
+                       ply->keys |= 0x08; goto key_shoot;
+               case Xkey_5:
+                       ply->keys |= 0x10; goto key_shoot;
+               case Xkey_6:
+                       ply->keys |= 0x20; goto key_shoot;
+               case Xkey_7:
+                       ply->keys |= 0x40; goto key_shoot;
+               case Xkey_8:
+                       ply->keys |= 0x80; goto key_shoot;
+               key_shoot:
+                       Cave[y][x] = Yball_eat;
+                       Next[y][x] = Xblank;
+                       play[SAMPLE_collect] = 1;
+                       lev.score += lev.key_score;
+                       ply->anim = SPR_walk + anim;
+                       break;
+               case Xlenses:
+                       Cave[y][x] = Yball_eat;
+                       Next[y][x] = Xblank;
+                       play[SAMPLE_collect] = 1;
+                       lev.score += lev.lenses_score;
+                       lev.lenses_cnt = lev.lenses_time;
+                       ply->anim = SPR_walk + anim;
+                       break;
+               case Xmagnify:
+                       Cave[y][x] = Yball_eat;
+                       Next[y][x] = Xblank;
+                       play[SAMPLE_collect] = 1;
+                       lev.score += lev.magnify_score;
+                       lev.magnify_cnt = lev.magnify_time;
+                       ply->anim = SPR_walk + anim;
+                       break;
+               }
+       }
+}
diff --git a/src/libem/synchro_2.c b/src/libem/synchro_2.c
new file mode 100644 (file)
index 0000000..731e9fa
--- /dev/null
@@ -0,0 +1,3813 @@
+
+/* second part of synchro.
+ *
+ * game logic for monsters.
+ *
+ * one giant switch statement to process everything.
+ *
+ * this whole thing is a major bottleneck. the compiler must use registers. compilers suck.
+ */
+
+#include "display.h"
+#include "tile.h"
+#include "level.h"
+#include "sample.h"
+
+extern unsigned int screen_x;
+extern unsigned int screen_y;
+
+void synchro_2(void)
+{
+       register unsigned int x = 0;
+       register unsigned int y = 1;
+       register unsigned long random = Random;
+       register unsigned short *cave_cache = Cave[y]; /* might be a win */
+       unsigned long score = 0;
+
+       unsigned int temp = 0;  /* initialized to make compilers happy */
+       unsigned int left = screen_x / TILEX; /* only needed for sounds */
+       unsigned int top = screen_y / TILEY;
+       unsigned int dx; /* only needed to find closest player */
+       unsigned int dy;
+
+#define RANDOM (random = random << 31 | random >> 1)
+#define PLAY(sample) { if((unsigned int)(y - top) <= 12 && (unsigned int)(x - left) <= 20) play[sample] = 1; }
+
+loop:
+       switch(cave_cache[++x]) {
+       default:
+               goto loop;
+/* ---------------------------------------------------------------------- */
+#ifdef BAD_ROLL
+       case Xstone_force_e:
+               switch(Cave[y][x+1]) {
+               case ZBORDER:
+               case Znormal:
+               case Zdynamite:
+               case Xboom_bug:
+               case Xboom_bomb:
+               case Xboom_android:
+               case Xboom_1:
+               case Zplayer:
+                       Cave[y][x] = Xstone;
+                       Next[y][x] = Xstone;
+                       goto loop;
+               default:
+                       Cave[y][x] = Ystone_eB;
+                       Cave[y][x+1] = Ystone_e;
+                       Next[y][x] = Xblank;
+                       Next[y][x+1] = Xstone_pause;
+                       goto loop;
+               }
+       case Xstone_force_w:
+               switch(Cave[y][x-1]) {
+               case ZBORDER:
+               case Znormal:
+               case Zdynamite:
+               case Xboom_bug:
+               case Xboom_bomb:
+               case Xboom_android:
+               case Xboom_1:
+               case Zplayer:
+                       Cave[y][x] = Xstone;
+                       Next[y][x] = Xstone;
+                       goto loop;
+               default:
+                       Cave[y][x] = Ystone_wB;
+                       Cave[y][x-1] = Ystone_w;
+                       Next[y][x] = Xblank;
+                       Next[y][x-1] = Xstone_pause;
+                       goto loop;
+               }
+       case Xnut_force_e:
+               switch(Cave[y][x+1]) {
+               case ZBORDER:
+               case Znormal:
+               case Zdynamite:
+               case Xboom_bug:
+               case Xboom_bomb:
+               case Xboom_android:
+               case Xboom_1:
+               case Zplayer:
+                       Cave[y][x] = Xnut;
+                       Next[y][x] = Xnut;
+                       goto loop;
+               default:
+                       Cave[y][x] = Ynut_eB;
+                       Cave[y][x+1] = Ynut_e;
+                       Next[y][x] = Xblank;
+                       Next[y][x+1] = Xnut_pause;
+                       goto loop;
+               }
+       case Xnut_force_w:
+               switch(Cave[y][x-1]) {
+               case ZBORDER:
+               case Znormal:
+               case Zdynamite:
+               case Xboom_bug:
+               case Xboom_bomb:
+               case Xboom_android:
+               case Xboom_1:
+               case Zplayer:
+                       Cave[y][x] = Xnut;
+                       Next[y][x] = Xnut;
+                       goto loop;
+               default:
+                       Cave[y][x] = Ynut_wB;
+                       Cave[y][x-1] = Ynut_w;
+                       Next[y][x] = Xblank;
+                       Next[y][x-1] = Xnut_pause;
+                       goto loop;
+               }
+       case Xspring_force_e:
+               switch(Cave[y][x+1]) {
+               case ZBORDER:
+               case Znormal:
+               case Zdynamite:
+               case Xboom_bug:
+               case Xboom_bomb:
+               case Xboom_android:
+               case Xboom_1:
+               case Zplayer:
+                       Cave[y][x] = Xspring;
+                       Next[y][x] = Xspring;
+                       goto loop;
+               default:
+                       Cave[y][x] = Yspring_eB;
+                       Cave[y][x+1] = Yspring_e;
+                       Next[y][x] = Xblank;
+#ifdef BAD_SPRING
+                       Next[y][x+1] = Xspring_e;
+#else
+                       Next[y][x+1] = Xspring_pause;
+#endif
+                       goto loop;
+               }
+       case Xspring_force_w:
+               switch(Cave[y][x-1]) {
+               case ZBORDER:
+               case Znormal:
+               case Zdynamite:
+               case Xboom_bug:
+               case Xboom_bomb:
+               case Xboom_android:
+               case Xboom_1:
+               case Zplayer:
+                       Cave[y][x] = Xspring;
+                       Next[y][x] = Xspring;
+                       goto loop;
+               default:
+                       Cave[y][x] = Yspring_wB;
+                       Cave[y][x-1] = Yspring_w;
+                       Next[y][x] = Xblank;
+#ifdef BAD_SPRING
+                       Next[y][x-1] = Xspring_w;
+#else
+                       Next[y][x-1] = Xspring_pause;
+#endif
+                       goto loop;
+               }
+       case Xemerald_force_e:
+               switch(Cave[y][x+1]) {
+               case ZBORDER:
+               case Znormal:
+               case Zdynamite:
+               case Xboom_bug:
+               case Xboom_bomb:
+               case Xboom_android:
+               case Xboom_1:
+               case Zplayer:
+                       Cave[y][x] = Xemerald;
+                       Next[y][x] = Xemerald;
+                       goto loop;
+               default:
+                       Cave[y][x] = Yemerald_eB;
+                       Cave[y][x+1] = Yemerald_e;
+                       Next[y][x] = Xblank;
+                       Next[y][x+1] = Xemerald_pause;
+                       goto loop;
+               }
+       case Xemerald_force_w:
+               switch(Cave[y][x-1]) {
+               case ZBORDER:
+               case Znormal:
+               case Zdynamite:
+               case Xboom_bug:
+               case Xboom_bomb:
+               case Xboom_android:
+               case Xboom_1:
+               case Zplayer:
+                       Cave[y][x] = Xemerald;
+                       Next[y][x] = Xemerald;
+                       goto loop;
+               default:
+                       Cave[y][x] = Yemerald_wB;
+                       Cave[y][x-1] = Yemerald_w;
+                       Next[y][x] = Xblank;
+                       Next[y][x-1] = Xemerald_pause;
+                       goto loop;
+               }
+       case Xdiamond_force_e:
+               switch(Cave[y][x+1]) {
+               case ZBORDER:
+               case Znormal:
+               case Zdynamite:
+               case Xboom_bug:
+               case Xboom_bomb:
+               case Xboom_android:
+               case Xboom_1:
+               case Zplayer:
+                       Cave[y][x] = Xdiamond;
+                       Next[y][x] = Xdiamond;
+                       goto loop;
+               default:
+                       Cave[y][x] = Ydiamond_eB;
+                       Cave[y][x+1] = Ydiamond_e;
+                       Next[y][x] = Xblank;
+                       Next[y][x+1] = Xdiamond_pause;
+                       goto loop;
+               }
+       case Xdiamond_force_w:
+               switch(Cave[y][x-1]) {
+               case ZBORDER:
+               case Znormal:
+               case Zdynamite:
+               case Xboom_bug:
+               case Xboom_bomb:
+               case Xboom_android:
+               case Xboom_1:
+               case Zplayer:
+                       Cave[y][x] = Xdiamond;
+                       Next[y][x] = Xdiamond;
+                       goto loop;
+               default:
+                       Cave[y][x] = Ydiamond_wB;
+                       Cave[y][x-1] = Ydiamond_w;
+                       Next[y][x] = Xblank;
+                       Next[y][x-1] = Xdiamond_pause;
+                       goto loop;
+               }
+       case Xbomb_force_e:
+               switch(Cave[y][x+1]) {
+               case ZBORDER:
+               case Znormal:
+               case Zdynamite:
+               case Xboom_bug:
+               case Xboom_bomb:
+               case Xboom_android:
+               case Xboom_1:
+               case Zplayer:
+                       Cave[y][x] = Xbomb;
+                       Next[y][x] = Xbomb;
+                       goto loop;
+               default:
+                       Cave[y][x] = Ybomb_eB;
+                       Cave[y][x+1] = Ybomb_e;
+                       Next[y][x] = Xblank;
+                       Next[y][x+1] = Xbomb_pause;
+                       goto loop;
+               }
+       case Xbomb_force_w:
+               switch(Cave[y][x-1]) {
+               case ZBORDER:
+               case Znormal:
+               case Zdynamite:
+               case Xboom_bug:
+               case Xboom_bomb:
+               case Xboom_android:
+               case Xboom_1:
+               case Zplayer:
+                       Cave[y][x] = Xbomb;
+                       Next[y][x] = Xbomb;
+                       goto loop;
+               default:
+                       Cave[y][x] = Ybomb_wB;
+                       Cave[y][x-1] = Ybomb_w;
+                       Next[y][x] = Xblank;
+                       Next[y][x-1] = Xbomb_pause;
+                       goto loop;
+               }
+#endif
+/* ---------------------------------------------------------------------- */
+       case Xstone:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ystone_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+                       Cave[y][x] = Ystone_sB;
+                       Cave[y+1][x] = Ystone_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xstone_fall;
+                       goto loop;
+               case Xsand:
+                       Cave[y][x] = Xsand_stonein_1;
+                       Cave[y+1][x] = Xsand_sandstone_1;
+                       Next[y][x] = Xsand_stonein_2;
+                       Next[y+1][x] = Xsand_sandstone_2;
+                       goto loop;
+               case Xspring:
+               case Xspring_pause:
+               case Xspring_e:
+               case Xspring_w:
+               case Xandroid:
+               case Xandroid_1_n:
+               case Xandroid_2_n:
+               case Xandroid_1_e:
+               case Xandroid_2_e:
+               case Xandroid_1_s:
+               case Xandroid_2_s:
+               case Xandroid_1_w:
+               case Xandroid_2_w:
+               case Xstone:
+               case Xstone_pause:
+               case Xemerald:
+               case Xemerald_pause:
+               case Xdiamond:
+               case Xdiamond_pause:
+               case Xbomb:
+               case Xbomb_pause:
+               case Xballoon:
+               case Xacid_ne:
+               case Xacid_nw:
+               case Xball_1:
+               case Xball_2:
+               case Xnut:
+               case Xnut_pause:
+               case Xgrow_ns:
+               case Xgrow_ew:
+               case Xkey_1:
+               case Xkey_2:
+               case Xkey_3:
+               case Xkey_4:
+               case Xkey_5:
+               case Xkey_6:
+               case Xkey_7:
+               case Xkey_8:
+               case Xbumper:
+               case Xswitch:
+               case Xlenses:
+               case Xmagnify:
+               case Xround_wall_1:
+               case Xround_wall_2:
+               case Xround_wall_3:
+               case Xround_wall_4:
+                       if(RANDOM & 1) {
+                               if(tab_blank[Cave[y][x+1]] && tab_acid[Cave[y+1][x+1]]) {
+                                       Cave[y][x] = Ystone_eB;
+                                       Cave[y][x+1] = Ystone_e;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x+1] = Xstone_pause;
+                                       goto loop;
+                               }
+                               if(tab_blank[Cave[y][x-1]] && tab_acid[Cave[y+1][x-1]]) {
+                                       Cave[y][x] = Ystone_wB;
+                                       Cave[y][x-1] = Ystone_w;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x-1] = Xstone_pause;
+                                       goto loop;
+                               }
+                       } else {
+                               if(tab_blank[Cave[y][x-1]] && tab_acid[Cave[y+1][x-1]]) {
+                                       Cave[y][x] = Ystone_wB;
+                                       Cave[y][x-1] = Ystone_w;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x-1] = Xstone_pause;
+                                       goto loop;
+                               }
+                               if(tab_blank[Cave[y][x+1]] && tab_acid[Cave[y+1][x+1]]) {
+                                       Cave[y][x] = Ystone_eB;
+                                       Cave[y][x+1] = Ystone_e;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x+1] = Xstone_pause;
+                                       goto loop;
+                               }
+                       }
+               default:
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xstone_pause:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ystone_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Ystone_sB;
+                       Cave[y+1][x] = Ystone_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xstone_fall;
+                       goto loop;
+               default:
+                       Cave[y][x] = Xstone;
+                       Next[y][x] = Xstone;
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xstone_fall:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ystone_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Zplayer:
+                       Cave[y][x] = Ystone_sB;
+                       Cave[y+1][x] = Ystone_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xstone_fall;
+                       goto loop;
+               case Xnut:
+               case Xnut_pause:
+                       Cave[y+1][x] = Yemerald_stone;
+                       Next[y][x] = Xstone;
+                       Next[y+1][x] = Xemerald;
+                       play[SAMPLE_crack] = 1;
+                       score += lev.nut_score;
+                       goto loop;
+               case Xbug_n:
+               case Xbug_e:
+               case Xbug_s:
+               case Xbug_w:
+               case Xbug_gon:
+               case Xbug_goe:
+               case Xbug_gos:
+               case Xbug_gow:
+                       Cave[y][x] = Ystone_sB;
+                       Cave[y+1][x] = Ybug_stone;
+                       Next[y+1][x] = Znormal;
+                       Boom[y][x-1] = Xemerald;
+                       Boom[y][x] = Xemerald;
+                       Boom[y][x+1] = Xemerald;
+                       Boom[y+1][x-1] = Xemerald;
+                       Boom[y+1][x] = Xdiamond;
+                       Boom[y+1][x+1] = Xemerald;
+                       Boom[y+2][x-1] = Xemerald;
+                       Boom[y+2][x] = Xemerald;
+                       Boom[y+2][x+1] = Xemerald;
+                       score += lev.bug_score;
+                       goto loop;
+               case Xtank_n:
+               case Xtank_e:
+               case Xtank_s:
+               case Xtank_w:
+               case Xtank_gon:
+               case Xtank_goe:
+               case Xtank_gos:
+               case Xtank_gow:
+                       Cave[y][x] = Ystone_sB;
+                       Cave[y+1][x] = Ytank_stone;
+                       Next[y+1][x] = Znormal;
+                       Boom[y][x-1] = Xblank;
+                       Boom[y][x] = Xblank;
+                       Boom[y][x+1] = Xblank;
+                       Boom[y+1][x-1] = Xblank;
+                       Boom[y+1][x] = Xblank;
+                       Boom[y+1][x+1] = Xblank;
+                       Boom[y+2][x-1] = Xblank;
+                       Boom[y+2][x] = Xblank;
+                       Boom[y+2][x+1] = Xblank;
+                       score += lev.tank_score;
+                       goto loop;
+               case Xspring:
+                       if(RANDOM & 1) {
+                               switch(Cave[y+1][x+1]) {
+                               case Xblank:
+                               case Yacid_splash_eB:
+                               case Yacid_splash_wB:
+                               case Xalien:
+                               case Xalien_pause:
+                                       Cave[y+1][x] = Xspring_e; break;
+                               default:
+                                       Cave[y+1][x] = Xspring_w; break;
+                               }
+                       } else {
+                               switch(Cave[y+1][x-1]) {
+                               case Xblank:
+                               case Yacid_splash_eB:
+                               case Yacid_splash_wB:
+                               case Xalien:
+                               case Xalien_pause:
+                                       Cave[y+1][x] = Xspring_w; break;
+                               default:
+                                       Cave[y+1][x] = Xspring_e; break;
+                               }
+                       }
+                       Next[y][x] = Xstone;
+                       goto loop;
+               case Xeater_n:
+               case Xeater_e:
+               case Xeater_s:
+               case Xeater_w:
+                       Cave[y][x] = Ystone_sB;
+                       Cave[y+1][x] = Yeater_stone;
+                       Next[y+1][x] = Znormal;
+                       Boom[y][x-1] = lev.eater_array[lev.eater_pos][0];
+                       Boom[y][x] = lev.eater_array[lev.eater_pos][1];
+                       Boom[y][x+1] = lev.eater_array[lev.eater_pos][2];
+                       Boom[y+1][x-1] = lev.eater_array[lev.eater_pos][3];
+                       Boom[y+1][x] = lev.eater_array[lev.eater_pos][4];
+                       Boom[y+1][x+1] = lev.eater_array[lev.eater_pos][5];
+                       Boom[y+2][x-1] = lev.eater_array[lev.eater_pos][6];
+                       Boom[y+2][x] = lev.eater_array[lev.eater_pos][7];
+                       Boom[y+2][x+1] = lev.eater_array[lev.eater_pos][8];
+                       lev.eater_pos = (lev.eater_pos + 1) & 7;
+                       score += lev.eater_score;
+                       goto loop;
+               case Xalien:
+               case Xalien_pause:
+                       Cave[y][x] = Ystone_sB;
+                       Cave[y+1][x] = Yalien_stone;
+                       Next[y+1][x] = Znormal;
+                       Boom[y][x-1] = Xblank;
+                       Boom[y][x] = Xblank;
+                       Boom[y][x+1] = Xblank;
+                       Boom[y+1][x-1] = Xblank;
+                       Boom[y+1][x] = Xblank;
+                       Boom[y+1][x+1] = Xblank;
+                       Boom[y+2][x-1] = Xblank;
+                       Boom[y+2][x] = Xblank;
+                       Boom[y+2][x+1] = Xblank;
+                       score += lev.alien_score;
+                       goto loop;
+               case Xdiamond:
+               case Xdiamond_pause:
+                       switch(Cave[y+2][x]) {
+                       case Xblank:
+                       case Yacid_splash_eB:
+                       case Yacid_splash_wB:
+                       case Zplayer:
+                       case Xbug_n:
+                       case Xbug_e:
+                       case Xbug_s:
+                       case Xbug_w:
+                       case Xbug_gon:
+                       case Xbug_goe:
+                       case Xbug_gos:
+                       case Xbug_gow:
+                       case Xtank_n:
+                       case Xtank_e:
+                       case Xtank_s:
+                       case Xtank_w:
+                       case Xtank_gon:
+                       case Xtank_goe:
+                       case Xtank_gos:
+                       case Xtank_gow:
+                       case Xspring_fall:
+                       case Xandroid:
+                       case Xandroid_1_n:
+                       case Xandroid_2_n:
+                       case Xandroid_1_e:
+                       case Xandroid_2_e:
+                       case Xandroid_1_s:
+                       case Xandroid_2_s:
+                       case Xandroid_1_w:
+                       case Xandroid_2_w:
+                       case Xstone_fall:
+                       case Xemerald_fall:
+                       case Xdiamond_fall:
+                       case Xbomb_fall:
+                       case Xacid_s:
+                       case Xacid_1:
+                       case Xacid_2:
+                       case Xacid_3:
+                       case Xacid_4:
+                       case Xacid_5:
+                       case Xacid_6:
+                       case Xacid_7:
+                       case Xacid_8:
+                       case Xnut_fall:
+                       case Xplant:
+                       case Yplant:
+                               Next[y][x] = Xstone;
+                               PLAY(SAMPLE_stone);
+                               goto loop;
+                       }
+                       Cave[y][x] = Ystone_sB;
+                       Cave[y+1][x] = Ydiamond_stone;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xstone_pause;
+                       play[SAMPLE_squash] = 1;
+                       goto loop;
+               case Xbomb:
+               case Xbomb_pause:
+                       Cave[y+1][x] = Ybomb_eat;
+                       Next[y+1][x] = Znormal;
+                       Boom[y][x-1] = Xblank;
+                       Boom[y][x] = Xblank;
+                       Boom[y][x+1] = Xblank;
+                       Boom[y+1][x-1] = Xblank;
+                       Boom[y+1][x] = Xblank;
+                       Boom[y+1][x+1] = Xblank;
+                       Boom[y+2][x-1] = Xblank;
+                       Boom[y+2][x] = Xblank;
+                       Boom[y+2][x+1] = Xblank;
+                       goto loop;
+               case Xwonderwall:
+                       if(lev.wonderwall_time) {
+                               lev.wonderwall_state = 1;
+                               Cave[y][x] = Ystone_sB;
+                               if(tab_blank[Cave[y+2][x]]) {
+                                       Cave[y+2][x] = Yemerald_s;
+                                       Next[y+2][x] = Xemerald_fall;
+                               }
+                               Next[y][x] = Xblank;
+                               play[SAMPLE_squash] = 1;
+                               goto loop;
+                       }
+               default:
+                       Cave[y][x] = Xstone;
+                       Next[y][x] = Xstone;
+                       PLAY(SAMPLE_stone);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xnut:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ynut_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Ynut_sB;
+                       Cave[y+1][x] = Ynut_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xnut_fall;
+                       goto loop;
+               case Xspring:
+               case Xspring_pause:
+               case Xspring_e:
+               case Xspring_w:
+               case Xandroid:
+               case Xandroid_1_n:
+               case Xandroid_2_n:
+               case Xandroid_1_e:
+               case Xandroid_2_e:
+               case Xandroid_1_s:
+               case Xandroid_2_s:
+               case Xandroid_1_w:
+               case Xandroid_2_w:
+               case Xstone:
+               case Xstone_pause:
+               case Xemerald:
+               case Xemerald_pause:
+               case Xdiamond:
+               case Xdiamond_pause:
+               case Xbomb:
+               case Xbomb_pause:
+               case Xballoon:
+               case Xacid_ne:
+               case Xacid_nw:
+               case Xball_1:
+               case Xball_2:
+               case Xnut:
+               case Xnut_pause:
+               case Xgrow_ns:
+               case Xgrow_ew:
+               case Xkey_1:
+               case Xkey_2:
+               case Xkey_3:
+               case Xkey_4:
+               case Xkey_5:
+               case Xkey_6:
+               case Xkey_7:
+               case Xkey_8:
+               case Xbumper:
+               case Xswitch:
+               case Xround_wall_1:
+               case Xround_wall_2:
+               case Xround_wall_3:
+               case Xround_wall_4:
+                       if(RANDOM & 1) {
+                               if(tab_blank[Cave[y][x+1]] && tab_acid[Cave[y+1][x+1]]) {
+                                       Cave[y][x] = Ynut_eB;
+                                       Cave[y][x+1] = Ynut_e;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x+1] = Xnut_pause;
+                                       goto loop;
+                               }
+                               if(tab_blank[Cave[y][x-1]] && tab_acid[Cave[y+1][x-1]]) {
+                                       Cave[y][x] = Ynut_wB;
+                                       Cave[y][x-1] = Ynut_w;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x-1] = Xnut_pause;
+                                       goto loop;
+                               }
+                       } else {
+                               if(tab_blank[Cave[y][x-1]] && tab_acid[Cave[y+1][x-1]]) {
+                                       Cave[y][x] = Ynut_wB;
+                                       Cave[y][x-1] = Ynut_w;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x-1] = Xnut_pause;
+                                       goto loop;
+                               }
+                               if(tab_blank[Cave[y][x+1]] && tab_acid[Cave[y+1][x+1]]) {
+                                       Cave[y][x] = Ynut_eB;
+                                       Cave[y][x+1] = Ynut_e;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x+1] = Xnut_pause;
+                                       goto loop;
+                               }
+                       }
+               default:
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xnut_pause:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ynut_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Ynut_sB;
+                       Cave[y+1][x] = Ynut_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xnut_fall;
+                       goto loop;
+               default:
+                       Cave[y][x] = Xnut;
+                       Next[y][x] = Xnut;
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xnut_fall:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ynut_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Zplayer:
+                       Cave[y][x] = Ynut_sB;
+                       Cave[y+1][x] = Ynut_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xnut_fall;
+                       goto loop;
+               default:
+                       Cave[y][x] = Xnut;
+                       Next[y][x] = Xnut;
+                       PLAY(SAMPLE_nut);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xbug_n:
+               if(tab_ameuba[Cave[y-1][x]] || tab_ameuba[Cave[y][x+1]] || tab_ameuba[Cave[y+1][x]] || tab_ameuba[Cave[y][x-1]]) goto bug_boom;
+               switch(Cave[y][x+1]) {
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+               case Zplayer:
+                       Cave[y][x] = Ybug_n_e;
+                       Next[y][x] = Xbug_goe;
+                       PLAY(SAMPLE_bug);
+                       goto loop;
+               default:
+                       goto bug_gon;
+               }
+       case Xbug_gon:
+               if(tab_ameuba[Cave[y-1][x]] || tab_ameuba[Cave[y][x+1]] || tab_ameuba[Cave[y+1][x]] || tab_ameuba[Cave[y][x-1]]) goto bug_boom;
+       bug_gon:
+               switch(Cave[y-1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ybug_nB;
+                       if(Cave[y-2][x+1] == Xblank) Cave[y-2][x+1] = Yacid_splash_eB;
+                       if(Cave[y-2][x-1] == Xblank) Cave[y-2][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Zplayer:
+                       Cave[y][x] = Ybug_nB;
+                       Cave[y-1][x] = Ybug_n;
+                       Next[y][x] = Xblank;
+                       Next[y-1][x] = Xbug_n;
+                       PLAY(SAMPLE_bug);
+                       goto loop;
+               default:
+                       Cave[y][x] = Ybug_n_w;
+                       Next[y][x] = Xbug_gow;
+                       PLAY(SAMPLE_bug);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xbug_e:
+               if(tab_ameuba[Cave[y-1][x]] || tab_ameuba[Cave[y][x+1]] || tab_ameuba[Cave[y+1][x]] || tab_ameuba[Cave[y][x-1]]) goto bug_boom;
+               switch(Cave[y+1][x]) {
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+               case Zplayer:
+                       Cave[y][x] = Ybug_e_s;
+                       Next[y][x] = Xbug_gos;
+                       PLAY(SAMPLE_bug);
+                       goto loop;
+               default:
+                       goto bug_goe;
+               }
+       case Xbug_goe:
+               if(tab_ameuba[Cave[y-1][x]] || tab_ameuba[Cave[y][x+1]] || tab_ameuba[Cave[y+1][x]] || tab_ameuba[Cave[y][x-1]]) goto bug_boom;
+       bug_goe:
+               switch(Cave[y][x+1]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ybug_eB;
+                       if(Cave[y-1][x+2] == Xblank) Cave[y-1][x+2] = Yacid_splash_eB;
+                       if(Cave[y-1][x] == Xblank) Cave[y-1][x] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Zplayer:
+                       Cave[y][x] = Ybug_eB;
+                       Cave[y][x+1] = Ybug_e;
+                       Next[y][x] = Xblank;
+                       Next[y][x+1] = Xbug_e;
+                       PLAY(SAMPLE_bug);
+                       goto loop;
+               default:
+                       Cave[y][x] = Ybug_e_n;
+                       Next[y][x] = Xbug_gon;
+                       PLAY(SAMPLE_bug);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xbug_s:
+               if(tab_ameuba[Cave[y-1][x]] || tab_ameuba[Cave[y][x+1]] || tab_ameuba[Cave[y+1][x]] || tab_ameuba[Cave[y][x-1]]) goto bug_boom;
+               switch(Cave[y][x-1]) {
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+               case Zplayer:
+                       Cave[y][x] = Ybug_s_w;
+                       Next[y][x] = Xbug_gow;
+                       PLAY(SAMPLE_bug);
+                       goto loop;
+               default:
+                       goto bug_gos;
+               }
+       case Xbug_gos:
+               if(tab_ameuba[Cave[y-1][x]] || tab_ameuba[Cave[y][x+1]] || tab_ameuba[Cave[y+1][x]] || tab_ameuba[Cave[y][x-1]]) goto bug_boom;
+       bug_gos:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ybug_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Zplayer:
+                       Cave[y][x] = Ybug_sB;
+                       Cave[y+1][x] = Ybug_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xbug_s;
+                       PLAY(SAMPLE_bug);
+                       goto loop;
+               default:
+                       Cave[y][x] = Ybug_s_e;
+                       Next[y][x] = Xbug_goe;
+                       PLAY(SAMPLE_bug);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xbug_w:
+               if(tab_ameuba[Cave[y-1][x]] || tab_ameuba[Cave[y][x+1]] || tab_ameuba[Cave[y+1][x]] || tab_ameuba[Cave[y][x-1]]) goto bug_boom;
+               switch(Cave[y-1][x]) {
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+               case Zplayer:
+                       Cave[y][x] = Ybug_w_n;
+                       Next[y][x] = Xbug_gon;
+                       PLAY(SAMPLE_bug);
+                       goto loop;
+               default:
+                       goto bug_gow;
+               }
+       case Xbug_gow:
+               if(tab_ameuba[Cave[y-1][x]] || tab_ameuba[Cave[y][x+1]] || tab_ameuba[Cave[y+1][x]] || tab_ameuba[Cave[y][x-1]]) goto bug_boom;
+       bug_gow:
+               switch(Cave[y][x-1]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ybug_wB;
+                       if(Cave[y-1][x] == Xblank) Cave[y-1][x] = Yacid_splash_eB;
+                       if(Cave[y-1][x-2] == Xblank) Cave[y-1][x-2] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Zplayer:
+                       Cave[y][x] = Ybug_wB;
+                       Cave[y][x-1] = Ybug_w;
+                       Next[y][x] = Xblank;
+                       Next[y][x-1] = Xbug_w;
+                       PLAY(SAMPLE_bug);
+                       goto loop;
+               default:
+                       Cave[y][x] = Ybug_w_s;
+                       Next[y][x] = Xbug_gos;
+                       PLAY(SAMPLE_bug);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xtank_n:
+               if(tab_ameuba[Cave[y-1][x]] || tab_ameuba[Cave[y][x+1]] || tab_ameuba[Cave[y+1][x]] || tab_ameuba[Cave[y][x-1]]) goto tank_boom;
+               switch(Cave[y][x-1]) {
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+               case Zplayer:
+                       Cave[y][x] = Ytank_n_w;
+                       Next[y][x] = Xtank_gow;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               default:
+                       goto tank_gon;
+               }
+       case Xtank_gon:
+               if(tab_ameuba[Cave[y-1][x]] || tab_ameuba[Cave[y][x+1]] || tab_ameuba[Cave[y+1][x]] || tab_ameuba[Cave[y][x-1]]) goto tank_boom;
+       tank_gon:
+               switch(Cave[y-1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ytank_nB;
+                       if(Cave[y-2][x+1] == Xblank) Cave[y-2][x+1] = Yacid_splash_eB;
+                       if(Cave[y-2][x-1] == Xblank) Cave[y-2][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Zplayer:
+                       Cave[y][x] = Ytank_nB;
+                       Cave[y-1][x] = Ytank_n;
+                       Next[y][x] = Xblank;
+                       Next[y-1][x] = Xtank_n;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               default:
+                       Cave[y][x] = Ytank_n_e;
+                       Next[y][x] = Xtank_goe;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xtank_e:
+               if(tab_ameuba[Cave[y-1][x]] || tab_ameuba[Cave[y][x+1]] || tab_ameuba[Cave[y+1][x]] || tab_ameuba[Cave[y][x-1]]) goto tank_boom;
+               switch(Cave[y-1][x]) {
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+               case Zplayer:
+                       Cave[y][x] = Ytank_e_n;
+                       Next[y][x] = Xtank_gon;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               default:
+                       goto tank_goe;
+               }
+       case Xtank_goe:
+               if(tab_ameuba[Cave[y-1][x]] || tab_ameuba[Cave[y][x+1]] || tab_ameuba[Cave[y+1][x]] || tab_ameuba[Cave[y][x-1]]) goto tank_boom;
+       tank_goe:
+               switch(Cave[y][x+1]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ytank_eB;
+                       if(Cave[y-1][x+2] == Xblank) Cave[y-1][x+2] = Yacid_splash_eB;
+                       if(Cave[y-1][x] == Xblank) Cave[y-1][x] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Zplayer:
+                       Cave[y][x] = Ytank_eB;
+                       Cave[y][x+1] = Ytank_e;
+                       Next[y][x] = Xblank;
+                       Next[y][x+1] = Xtank_e;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               default:
+                       Cave[y][x] = Ytank_e_s;
+                       Next[y][x] = Xtank_gos;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xtank_s:
+               if(tab_ameuba[Cave[y-1][x]] || tab_ameuba[Cave[y][x+1]] || tab_ameuba[Cave[y+1][x]] || tab_ameuba[Cave[y][x-1]]) goto tank_boom;
+               switch(Cave[y][x+1]) {
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+               case Zplayer:
+                       Cave[y][x] = Ytank_s_e;
+                       Next[y][x] = Xtank_goe;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               default:
+                       goto tank_gos;
+               }
+       case Xtank_gos:
+               if(tab_ameuba[Cave[y-1][x]] || tab_ameuba[Cave[y][x+1]] || tab_ameuba[Cave[y+1][x]] || tab_ameuba[Cave[y][x-1]]) goto tank_boom;
+       tank_gos:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ytank_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Zplayer:
+                       Cave[y][x] = Ytank_sB;
+                       Cave[y+1][x] = Ytank_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xtank_s;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               default:
+                       Cave[y][x] = Ytank_s_w;
+                       Next[y][x] = Xtank_gow;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xtank_w:
+               if(tab_ameuba[Cave[y-1][x]] || tab_ameuba[Cave[y][x+1]] || tab_ameuba[Cave[y+1][x]] || tab_ameuba[Cave[y][x-1]]) goto tank_boom;
+               switch(Cave[y+1][x]) {
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+               case Zplayer:
+                       Cave[y][x] = Ytank_w_s;
+                       Next[y][x] = Xtank_gos;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               default:
+                       goto tank_gow;
+               }
+       case Xtank_gow:
+               if(tab_ameuba[Cave[y-1][x]] || tab_ameuba[Cave[y][x+1]] || tab_ameuba[Cave[y+1][x]] || tab_ameuba[Cave[y][x-1]]) goto tank_boom;
+       tank_gow:
+               switch(Cave[y][x-1]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ytank_wB;
+                       if(Cave[y-1][x] == Xblank) Cave[y-1][x] = Yacid_splash_eB;
+                       if(Cave[y-1][x-2] == Xblank) Cave[y-1][x-2] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Zplayer:
+                       Cave[y][x] = Ytank_wB;
+                       Cave[y][x-1] = Ytank_w;
+                       Next[y][x] = Xblank;
+                       Next[y][x-1] = Xtank_w;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               default:
+                       Cave[y][x] = Ytank_w_n;
+                       Next[y][x] = Xtank_gon;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xandroid:
+       android:
+               if(lev.android_clone_cnt == 0) {
+                       if(Cave[y-1][x-1] != Xblank && Cave[y-1][x] != Xblank &&
+                          Cave[y-1][x+1] != Xblank && Cave[y][x-1] != Xblank &&
+                          Cave[y][x+1] != Xblank && Cave[y+1][x-1] != Xblank &&
+                          Cave[y+1][x] != Xblank && Cave[y+1][x+1] != Xblank) goto android_move;
+
+                       switch(RANDOM & 7) { /* randomly find an object to clone */
+                       case 0: /* S,NE,W,NW,SE,E,SW,N */
+                               temp = lev.android_array[Cave[y+1][x]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x]]; if(temp != Xblank) break;
+                               goto android_move;
+                       case 1: /* NW,SE,N,S,NE,SW,E,W */
+                               temp = lev.android_array[Cave[y-1][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y][x-1]]; if(temp != Xblank) break;
+                               goto android_move;
+                       case 2: /* SW,E,S,W,N,NW,SE,NE */
+                               temp = lev.android_array[Cave[y+1][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x+1]]; if(temp != Xblank) break;
+                               goto android_move;
+                       case 3: /* N,SE,NE,E,W,S,NW,SW */
+                               temp = lev.android_array[Cave[y-1][x]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x-1]]; if(temp != Xblank) break;
+                               goto android_move;
+                       case 4: /* SE,NW,E,NE,SW,W,N,S */
+                               temp = lev.android_array[Cave[y+1][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x]]; if(temp != Xblank) break;
+                               goto android_move;
+                       case 5: /* NE,W,SE,SW,S,N,E,NW */
+                               temp = lev.android_array[Cave[y-1][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x-1]]; if(temp != Xblank) break;
+                               goto android_move;
+                       case 6: /* E,N,SW,S,NW,NE,SE,W */
+                               temp = lev.android_array[Cave[y][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y][x-1]]; if(temp != Xblank) break;
+                               goto android_move;
+                       case 7: /* W,SW,NW,N,E,SE,NE,S */
+                               temp = lev.android_array[Cave[y][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x-1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y-1][x+1]]; if(temp != Xblank) break;
+                               temp = lev.android_array[Cave[y+1][x]]; if(temp != Xblank) break;
+                               goto android_move;
+                       }
+                       Next[y][x] = temp; /* the item we chose to clone */
+                       play[SAMPLE_android] = 1;
+                       switch(RANDOM & 7) { /* randomly find a direction to move */
+                       case 0: /* S,NE,W,NW,SE,E,SW,N */
+                               if(Cave[y+1][x] == Xblank) goto android_s;
+                               if(Cave[y-1][x+1] == Xblank) goto android_ne;
+                               if(Cave[y][x-1] == Xblank) goto android_w;
+                               if(Cave[y-1][x-1] == Xblank) goto android_nw;
+                               if(Cave[y+1][x+1] == Xblank) goto android_se;
+                               if(Cave[y][x+1] == Xblank) goto android_e;
+                               if(Cave[y+1][x-1] == Xblank) goto android_sw;
+                               if(Cave[y-1][x] == Xblank) goto android_n;
+                               goto android_move;
+                       case 1: /* NW,SE,N,S,NE,SW,E,W */
+                               if(Cave[y-1][x-1] == Xblank) goto android_nw;
+                               if(Cave[y+1][x+1] == Xblank) goto android_se;
+                               if(Cave[y-1][x] == Xblank) goto android_n;
+                               if(Cave[y+1][x] == Xblank) goto android_s;
+                               if(Cave[y-1][x+1] == Xblank) goto android_ne;
+                               if(Cave[y+1][x-1] == Xblank) goto android_sw;
+                               if(Cave[y][x+1] == Xblank) goto android_e;
+                               if(Cave[y][x-1] == Xblank) goto android_w;
+                               goto android_move;
+                       case 2: /* SW,E,S,W,N,NW,SE,NE */
+                               if(Cave[y+1][x-1] == Xblank) goto android_sw;
+                               if(Cave[y][x+1] == Xblank) goto android_e;
+                               if(Cave[y+1][x] == Xblank) goto android_s;
+                               if(Cave[y][x-1] == Xblank) goto android_w;
+                               if(Cave[y-1][x] == Xblank) goto android_n;
+                               if(Cave[y-1][x-1] == Xblank) goto android_nw;
+                               if(Cave[y+1][x+1] == Xblank) goto android_se;
+                               if(Cave[y-1][x+1] == Xblank) goto android_ne;
+                               goto android_move;
+                       case 3: /* N,SE,NE,E,W,S,NW,SW */
+                               if(Cave[y-1][x] == Xblank) goto android_n;
+                               if(Cave[y+1][x+1] == Xblank) goto android_se;
+                               if(Cave[y-1][x+1] == Xblank) goto android_ne;
+                               if(Cave[y][x+1] == Xblank) goto android_e;
+                               if(Cave[y][x-1] == Xblank) goto android_w;
+                               if(Cave[y+1][x] == Xblank) goto android_s;
+                               if(Cave[y-1][x-1] == Xblank) goto android_nw;
+                               if(Cave[y+1][x-1] == Xblank) goto android_sw;
+                               goto android_move;
+                       case 4: /* SE,NW,E,NE,SW,W,N,S */
+                               if(Cave[y+1][x+1] == Xblank) goto android_se;
+                               if(Cave[y-1][x-1] == Xblank) goto android_nw;
+                               if(Cave[y][x+1] == Xblank) goto android_e;
+                               if(Cave[y-1][x+1] == Xblank) goto android_ne;
+                               if(Cave[y+1][x-1] == Xblank) goto android_sw;
+                               if(Cave[y][x-1] == Xblank) goto android_w;
+                               if(Cave[y-1][x] == Xblank) goto android_n;
+                               if(Cave[y+1][x] == Xblank) goto android_s;
+                               goto android_move;
+                       case 5: /* NE,W,SE,SW,S,N,E,NW */
+                               if(Cave[y-1][x+1] == Xblank) goto android_ne;
+                               if(Cave[y][x-1] == Xblank) goto android_w;
+                               if(Cave[y+1][x+1] == Xblank) goto android_se;
+                               if(Cave[y+1][x-1] == Xblank) goto android_sw;
+                               if(Cave[y+1][x] == Xblank) goto android_s;
+                               if(Cave[y-1][x] == Xblank) goto android_n;
+                               if(Cave[y][x+1] == Xblank) goto android_e;
+                               if(Cave[y-1][x-1] == Xblank) goto android_nw;
+                               goto android_move;
+                       case 6: /* E,N,SW,S,NW,NE,SE,W */
+                               if(Cave[y][x+1] == Xblank) goto android_e;
+                               if(Cave[y-1][x] == Xblank) goto android_n;
+                               if(Cave[y+1][x-1] == Xblank) goto android_sw;
+                               if(Cave[y+1][x] == Xblank) goto android_s;
+                               if(Cave[y-1][x-1] == Xblank) goto android_nw;
+                               if(Cave[y-1][x+1] == Xblank) goto android_ne;
+                               if(Cave[y+1][x+1] == Xblank) goto android_se;
+                               if(Cave[y][x-1] == Xblank) goto android_w;
+                               goto android_move;
+                       case 7: /* W,SW,NW,N,E,SE,NE,S */
+                               if(Cave[y][x-1] == Xblank) goto android_w;
+                               if(Cave[y+1][x-1] == Xblank) goto android_sw;
+                               if(Cave[y-1][x-1] == Xblank) goto android_nw;
+                               if(Cave[y-1][x] == Xblank) goto android_n;
+                               if(Cave[y][x+1] == Xblank) goto android_e;
+                               if(Cave[y+1][x+1] == Xblank) goto android_se;
+                               if(Cave[y-1][x+1] == Xblank) goto android_ne;
+                               if(Cave[y+1][x] == Xblank) goto android_s;
+                               goto android_move;
+                       }
+               }
+       android_move:
+               if(lev.android_move_cnt == 0) {
+                       if(Cave[y-1][x-1] == Zplayer || Cave[y-1][x] == Zplayer ||
+                          Cave[y-1][x+1] == Zplayer || Cave[y][x-1] == Zplayer ||
+                          Cave[y][x+1] == Zplayer || Cave[y+1][x-1] == Zplayer ||
+                          Cave[y+1][x] == Zplayer || Cave[y+1][x+1] == Zplayer) goto android_still;
+
+                       if(ply1.alive && ply2.alive) {
+                               if( (ply1.x > x ? ply1.x - x : x - ply1.x) + (ply1.y > y ? ply1.y - y : y - ply1.y) < (ply2.x > x ? ply2.x - x : x - ply2.x) + (ply2.y > y ? ply2.y - y : y - ply2.y) ) {
+                                       dx = ply1.x;
+                                       dy = ply1.y;
+                               } else {
+                                       dx = ply2.x;
+                                       dy = ply2.y;
+                               }
+                       } else if(ply1.alive) {
+                               dx = ply1.x;
+                               dy = ply1.y;
+                       } else if(ply2.alive) {
+                               dx = ply2.x;
+                               dy = ply2.y;
+                       } else {
+                               dx = 0;
+                               dy = 0;
+                       }
+                       Next[y][x] = Xblank; /* assume we will move */
+                       temp = ((x < dx) + 1 - (x > dx)) + ((y < dy) + 1 - (y > dy)) * 3;
+                       if(RANDOM & 1) {
+                               switch(temp) { /* attempt clockwise move first if direct path is blocked */
+                               case 0: /* north west */
+                                       if(tab_android_move[Cave[y-1][x-1]]) goto android_nw;
+                                       if(tab_android_move[Cave[y-1][x]]) goto android_n;
+                                       if(tab_android_move[Cave[y][x-1]]) goto android_w;
+                                       break;
+                               case 1: /* north */
+                                       if(tab_android_move[Cave[y-1][x]]) goto android_n;
+                                       if(tab_android_move[Cave[y-1][x+1]]) goto android_ne;
+                                       if(tab_android_move[Cave[y-1][x-1]]) goto android_nw;
+                                       break;
+                               case 2: /* north east */
+                                       if(tab_android_move[Cave[y-1][x+1]]) goto android_ne;
+                                       if(tab_android_move[Cave[y][x+1]]) goto android_e;
+                                       if(tab_android_move[Cave[y-1][x]]) goto android_n;
+                                       break;
+                               case 3: /* west */
+                                       if(tab_android_move[Cave[y][x-1]]) goto android_w;
+                                       if(tab_android_move[Cave[y-1][x-1]]) goto android_nw;
+                                       if(tab_android_move[Cave[y+1][x-1]]) goto android_sw;
+                                       break;
+                               case 4: /* nowhere */
+                                       break;
+                               case 5: /* east */
+                                       if(tab_android_move[Cave[y][x+1]]) goto android_e;
+                                       if(tab_android_move[Cave[y+1][x+1]]) goto android_se;
+                                       if(tab_android_move[Cave[y-1][x+1]]) goto android_ne;
+                                       break;
+                               case 6: /* south west */
+                                       if(tab_android_move[Cave[y+1][x-1]]) goto android_sw;
+                                       if(tab_android_move[Cave[y][x-1]]) goto android_w;
+                                       if(tab_android_move[Cave[y+1][x]]) goto android_s;
+                                       break;
+                               case 7: /* south */
+                                       if(tab_android_move[Cave[y+1][x]]) goto android_s;
+                                       if(tab_android_move[Cave[y+1][x-1]]) goto android_sw;
+                                       if(tab_android_move[Cave[y+1][x+1]]) goto android_se;
+                                       break;
+                               case 8: /* south east */
+                                       if(tab_android_move[Cave[y+1][x+1]]) goto android_se;
+                                       if(tab_android_move[Cave[y+1][x]]) goto android_s;
+                                       if(tab_android_move[Cave[y][x+1]]) goto android_e;
+                                       break;
+                               }
+                       } else {
+                               switch(temp) { /* attempt counter clockwise move first if direct path is blocked */
+                               case 0: /* north west */
+                                       if(tab_android_move[Cave[y-1][x-1]]) goto android_nw;
+                                       if(tab_android_move[Cave[y][x-1]]) goto android_w;
+                                       if(tab_android_move[Cave[y-1][x]]) goto android_n;
+                                       break;
+                               case 1: /* north */
+                                       if(tab_android_move[Cave[y-1][x]]) goto android_n;
+                                       if(tab_android_move[Cave[y-1][x-1]]) goto android_nw;
+                                       if(tab_android_move[Cave[y-1][x+1]]) goto android_ne;
+                                       break;
+                               case 2: /* north east */
+                                       if(tab_android_move[Cave[y-1][x+1]]) goto android_ne;
+                                       if(tab_android_move[Cave[y-1][x]]) goto android_n;
+                                       if(tab_android_move[Cave[y][x+1]]) goto android_e;
+                                       break;
+                               case 3: /* west */
+                                       if(tab_android_move[Cave[y][x-1]]) goto android_w;
+                                       if(tab_android_move[Cave[y+1][x-1]]) goto android_sw;
+                                       if(tab_android_move[Cave[y-1][x-1]]) goto android_nw;
+                                       break;
+                               case 4: /* nowhere */
+                                       break;
+                               case 5: /* east */
+                                       if(tab_android_move[Cave[y][x+1]]) goto android_e;
+                                       if(tab_android_move[Cave[y-1][x+1]]) goto android_ne;
+                                       if(tab_android_move[Cave[y+1][x+1]]) goto android_se;
+                                       break;
+                               case 6: /* south west */
+                                       if(tab_android_move[Cave[y+1][x-1]]) goto android_sw;
+                                       if(tab_android_move[Cave[y+1][x]]) goto android_s;
+                                       if(tab_android_move[Cave[y][x-1]]) goto android_w;
+                                       break;
+                               case 7: /* south */
+                                       if(tab_android_move[Cave[y+1][x]]) goto android_s;
+                                       if(tab_android_move[Cave[y+1][x+1]]) goto android_se;
+                                       if(tab_android_move[Cave[y+1][x-1]]) goto android_sw;
+                                       break;
+                               case 8: /* south east */
+                                       if(tab_android_move[Cave[y+1][x+1]]) goto android_se;
+                                       if(tab_android_move[Cave[y][x+1]]) goto android_e;
+                                       if(tab_android_move[Cave[y+1][x]]) goto android_s;
+                                       break;
+                               }
+                       }
+               }
+       android_still:
+               Next[y][x] = Xandroid;
+               goto loop;
+       android_n:
+               Cave[y][x] = Yandroid_nB;
+               Cave[y-1][x] = Yandroid_n;
+               Next[y-1][x] = Xandroid;
+               PLAY(SAMPLE_tank);
+               goto loop;
+       android_ne:
+               Cave[y][x] = Yandroid_neB;
+               Cave[y-1][x+1] = Yandroid_ne;
+               Next[y-1][x+1] = Xandroid;
+               PLAY(SAMPLE_tank);
+               goto loop;
+       android_e:
+               Cave[y][x] = Yandroid_eB;
+               Cave[y][x+1] = Yandroid_e;
+               Next[y][x+1] = Xandroid;
+               PLAY(SAMPLE_tank);
+               goto loop;
+       android_se:
+               Cave[y][x] = Yandroid_seB;
+               Cave[y+1][x+1] = Yandroid_se;
+               Next[y+1][x+1] = Xandroid;
+               PLAY(SAMPLE_tank);
+               goto loop;
+       android_s:
+               Cave[y][x] = Yandroid_sB;
+               Cave[y+1][x] = Yandroid_s;
+               Next[y+1][x] = Xandroid;
+               PLAY(SAMPLE_tank);
+               goto loop;
+       android_sw:
+               Cave[y][x] = Yandroid_swB;
+               Cave[y+1][x-1] = Yandroid_sw;
+               Next[y+1][x-1] = Xandroid;
+               PLAY(SAMPLE_tank);
+               goto loop;
+       android_w:
+               Cave[y][x] = Yandroid_wB;
+               Cave[y][x-1] = Yandroid_w;
+               Next[y][x-1] = Xandroid;
+               PLAY(SAMPLE_tank);
+               goto loop;
+       android_nw:
+               Cave[y][x] = Yandroid_nwB;
+               Cave[y-1][x-1] = Yandroid_nw;
+               Next[y-1][x-1] = Xandroid;
+               PLAY(SAMPLE_tank);
+               goto loop;
+/* ---------------------------------------------------------------------- */
+       case Xandroid_1_n:
+               switch(Cave[y-1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yandroid_nB;
+                       if(Cave[y-2][x+1] == Xblank) Cave[y-2][x+1] = Yacid_splash_eB;
+                       if(Cave[y-2][x-1] == Xblank) Cave[y-2][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Yandroid_nB;
+                       Cave[y-1][x] = Yandroid_n;
+                       Next[y][x] = Xblank;
+                       Next[y-1][x] = Xandroid;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               default:
+                       goto android;
+               }
+       case Xandroid_2_n:
+               switch(Cave[y-1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yandroid_nB;
+                       if(Cave[y-2][x+1] == Xblank) Cave[y-2][x+1] = Yacid_splash_eB;
+                       if(Cave[y-2][x-1] == Xblank) Cave[y-2][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Yandroid_nB;
+                       Cave[y-1][x] = Yandroid_n;
+                       Next[y][x] = Xblank;
+                       Next[y-1][x] = Xandroid_1_n;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               default:
+                       goto android;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xandroid_1_e:
+               switch(Cave[y][x+1]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yandroid_eB;
+                       if(Cave[y-1][x+2] == Xblank) Cave[y-1][x+2] = Yacid_splash_eB;
+                       if(Cave[y-1][x] == Xblank) Cave[y-1][x] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Yandroid_eB;
+                       Cave[y][x+1] = Yandroid_e;
+                       Next[y][x] = Xblank;
+                       Next[y][x+1] = Xandroid;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               default:
+                       goto android;
+               }
+       case Xandroid_2_e:
+               switch(Cave[y][x+1]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yandroid_eB;
+                       if(Cave[y-1][x+2] == Xblank) Cave[y-1][x+2] = Yacid_splash_eB;
+                       if(Cave[y-1][x] == Xblank) Cave[y-1][x] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Yandroid_eB;
+                       Cave[y][x+1] = Yandroid_e;
+                       Next[y][x] = Xblank;
+                       Next[y][x+1] = Xandroid_1_e;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               default:
+                       goto android;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xandroid_1_s:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yandroid_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Yandroid_sB;
+                       Cave[y+1][x] = Yandroid_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xandroid;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               default:
+                       goto android;
+               }
+       case Xandroid_2_s:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yandroid_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Yandroid_sB;
+                       Cave[y+1][x] = Yandroid_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xandroid_1_s;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               default:
+                       goto android;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xandroid_1_w:
+               switch(Cave[y][x-1]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yandroid_wB;
+                       if(Cave[y-1][x] == Xblank) Cave[y-1][x] = Yacid_splash_eB;
+                       if(Cave[y-1][x-2] == Xblank) Cave[y-1][x-2] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Yandroid_wB;
+                       Cave[y][x-1] = Yandroid_w;
+                       Next[y][x] = Xblank;
+                       Next[y][x-1] = Xandroid;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               default:
+                       goto android;
+               }
+       case Xandroid_2_w:
+               switch(Cave[y][x-1]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yandroid_wB;
+                       if(Cave[y-1][x] == Xblank) Cave[y-1][x] = Yacid_splash_eB;
+                       if(Cave[y-1][x-2] == Xblank) Cave[y-1][x-2] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Yandroid_wB;
+                       Cave[y][x-1] = Yandroid_w;
+                       Next[y][x] = Xblank;
+                       Next[y][x-1] = Xandroid_1_w;
+                       PLAY(SAMPLE_tank);
+                       goto loop;
+               default:
+                       goto android;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xspring:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yspring_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+                       Cave[y][x] = Yspring_sB;
+                       Cave[y+1][x] = Yspring_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xspring_fall;
+                       goto loop;
+               case Xspring:
+               case Xspring_pause:
+               case Xspring_e:
+               case Xspring_w:
+               case Xandroid:
+               case Xandroid_1_n:
+               case Xandroid_2_n:
+               case Xandroid_1_e:
+               case Xandroid_2_e:
+               case Xandroid_1_s:
+               case Xandroid_2_s:
+               case Xandroid_1_w:
+               case Xandroid_2_w:
+               case Xstone:
+               case Xstone_pause:
+               case Xemerald:
+               case Xemerald_pause:
+               case Xdiamond:
+               case Xdiamond_pause:
+               case Xbomb:
+               case Xbomb_pause:
+               case Xballoon:
+               case Xacid_ne:
+               case Xacid_nw:
+               case Xball_1:
+               case Xball_2:
+               case Xnut:
+               case Xnut_pause:
+               case Xgrow_ns:
+               case Xgrow_ew:
+               case Xkey_1:
+               case Xkey_2:
+               case Xkey_3:
+               case Xkey_4:
+               case Xkey_5:
+               case Xkey_6:
+               case Xkey_7:
+               case Xkey_8:
+               case Xbumper:
+               case Xswitch:
+               case Xround_wall_1:
+               case Xround_wall_2:
+               case Xround_wall_3:
+               case Xround_wall_4:
+                       if(RANDOM & 1) {
+                               if(tab_blank[Cave[y][x+1]] && tab_acid[Cave[y+1][x+1]]) {
+                                       Cave[y][x] = Yspring_eB;
+                                       Cave[y][x+1] = Yspring_e;
+                                       if(Cave[y+1][x] == Xbumper) Cave[y+1][x] = XbumperB;
+                                       Next[y][x] = Xblank;
+#ifdef BAD_SPRING
+                                       Next[y][x+1] = Xspring_e;
+#else
+                                       Next[y][x+1] = Xspring_pause;
+#endif
+                                       goto loop;
+                               }
+                               if(tab_blank[Cave[y][x-1]] && tab_acid[Cave[y+1][x-1]]) {
+                                       Cave[y][x] = Yspring_wB;
+                                       Cave[y][x-1] = Yspring_w;
+                                       if(Cave[y+1][x] == Xbumper) Cave[y+1][x] = XbumperB;
+                                       Next[y][x] = Xblank;
+#ifdef BAD_SPRING
+                                       Next[y][x-1] = Xspring_w;
+#else
+                                       Next[y][x-1] = Xspring_pause;
+#endif
+                                       goto loop;
+                               }
+                       } else {
+                               if(tab_blank[Cave[y][x-1]] && tab_acid[Cave[y+1][x-1]]) {
+                                       Cave[y][x] = Yspring_wB;
+                                       Cave[y][x-1] = Yspring_w;
+                                       if(Cave[y+1][x] == Xbumper) Cave[y+1][x] = XbumperB;
+                                       Next[y][x] = Xblank;
+#ifdef BAD_SPRING
+                                       Next[y][x-1] = Xspring_w;
+#else
+                                       Next[y][x-1] = Xspring_pause;
+#endif
+                                       goto loop;
+                               }
+                               if(tab_blank[Cave[y][x+1]] && tab_acid[Cave[y+1][x+1]]) {
+                                       Cave[y][x] = Yspring_eB;
+                                       Cave[y][x+1] = Yspring_e;
+                                       if(Cave[y+1][x] == Xbumper) Cave[y+1][x] = XbumperB;
+                                       Next[y][x] = Xblank;
+#ifdef BAD_SPRING
+                                       Next[y][x+1] = Xspring_e;
+#else
+                                       Next[y][x+1] = Xspring_pause;
+#endif
+                                       goto loop;
+                               }
+                       }
+               default:
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xspring_pause:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yspring_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Yspring_sB;
+                       Cave[y+1][x] = Yspring_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xspring_fall;
+                       goto loop;
+               default:
+                       Cave[y][x] = Xspring;
+                       Next[y][x] = Xspring;
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xspring_e:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yspring_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Yspring_sB;
+                       Cave[y+1][x] = Yspring_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xspring_fall;
+                       goto loop;
+               case Xbumper:
+                       Cave[y+1][x] = XbumperB;
+               }
+               switch(Cave[y][x+1]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yspring_eB;
+                       if(Cave[y-1][x+2] == Xblank) Cave[y-1][x+2] = Yacid_splash_eB;
+                       if(Cave[y-1][x] == Xblank) Cave[y-1][x] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Yalien_nB:
+               case Yalien_eB:
+               case Yalien_sB:
+               case Yalien_wB:
+                       Cave[y][x] = Yspring_eB;
+                       Cave[y][x+1] = Yspring_e;
+                       Next[y][x] = Xblank;
+                       Next[y][x+1] = Xspring_e;
+                       goto loop;
+               case Xalien:
+               case Xalien_pause:
+               case Yalien_n:
+               case Yalien_e:
+               case Yalien_s:
+               case Yalien_w:
+                       Cave[y][x] = Yspring_kill_eB;
+                       Cave[y][x+1] = Yspring_kill_e;
+                       Next[y][x] = Xblank;
+                       Next[y][x+1] = Xspring_e;
+                       play[SAMPLE_slurp] = 1;
+                       score += lev.slurp_score;
+                       goto loop;
+               case Xbumper:
+               case XbumperB:
+                       Cave[y][x+1] = XbumperB;
+                       Next[y][x] = Xspring_w;
+                       PLAY(SAMPLE_spring);
+                       goto loop;
+               default:
+                       Cave[y][x] = Xspring;
+                       Next[y][x] = Xspring;
+                       PLAY(SAMPLE_spring);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xspring_w:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yspring_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Yspring_sB;
+                       Cave[y+1][x] = Yspring_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xspring_fall;
+                       goto loop;
+               case Xbumper:
+                       Cave[y+1][x] = XbumperB;
+               }
+               switch(Cave[y][x-1]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yspring_wB;
+                       if(Cave[y-1][x] == Xblank) Cave[y-1][x] = Yacid_splash_eB;
+                       if(Cave[y-1][x-2] == Xblank) Cave[y-1][x-2] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Yalien_nB:
+               case Yalien_eB:
+               case Yalien_sB:
+               case Yalien_wB:
+                       Cave[y][x] = Yspring_wB;
+                       Cave[y][x-1] = Yspring_w;
+                       Next[y][x] = Xblank;
+                       Next[y][x-1] = Xspring_w;
+                       goto loop;
+               case Xalien:
+               case Xalien_pause:
+               case Yalien_n:
+               case Yalien_e:
+               case Yalien_s:
+               case Yalien_w:
+                       Cave[y][x] = Yspring_kill_wB;
+                       Cave[y][x-1] = Yspring_kill_w;
+                       Next[y][x] = Xblank;
+                       Next[y][x-1] = Xspring_w;
+                       play[SAMPLE_slurp] = 1;
+                       score += lev.slurp_score;
+                       goto loop;
+               case Xbumper:
+               case XbumperB:
+                       Cave[y][x-1] = XbumperB;
+                       Next[y][x] = Xspring_e;
+                       PLAY(SAMPLE_spring);
+                       goto loop;
+               default:
+                       Cave[y][x] = Xspring;
+                       Next[y][x] = Xspring;
+                       PLAY(SAMPLE_spring);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xspring_fall:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yspring_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Zplayer:
+                       Cave[y][x] = Yspring_sB;
+                       Cave[y+1][x] = Yspring_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xspring_fall;
+                       goto loop;
+               case Xbomb:
+               case Xbomb_pause:
+                       Cave[y+1][x] = Ybomb_eat;
+                       Next[y+1][x] = Znormal;
+                       Boom[y][x-1] = Xblank;
+                       Boom[y][x] = Xblank;
+                       Boom[y][x+1] = Xblank;
+                       Boom[y+1][x-1] = Xblank;
+                       Boom[y+1][x] = Xblank;
+                       Boom[y+1][x+1] = Xblank;
+                       Boom[y+2][x-1] = Xblank;
+                       Boom[y+2][x] = Xblank;
+                       Boom[y+2][x+1] = Xblank;
+                       goto loop;
+               case Xbug_n:
+               case Xbug_e:
+               case Xbug_s:
+               case Xbug_w:
+               case Xbug_gon:
+               case Xbug_goe:
+               case Xbug_gos:
+               case Xbug_gow:
+                       Cave[y][x] = Yspring_sB;
+                       Cave[y+1][x] = Ybug_spring;
+                       Next[y+1][x] = Znormal;
+                       Boom[y][x-1] = Xemerald;
+                       Boom[y][x] = Xemerald;
+                       Boom[y][x+1] = Xemerald;
+                       Boom[y+1][x-1] = Xemerald;
+                       Boom[y+1][x] = Xdiamond;
+                       Boom[y+1][x+1] = Xemerald;
+                       Boom[y+2][x-1] = Xemerald;
+                       Boom[y+2][x] = Xemerald;
+                       Boom[y+2][x+1] = Xemerald;
+                       score += lev.bug_score;
+                       goto loop;
+               case Xtank_n:
+               case Xtank_e:
+               case Xtank_s:
+               case Xtank_w:
+               case Xtank_gon:
+               case Xtank_goe:
+               case Xtank_gos:
+               case Xtank_gow:
+                       Cave[y][x] = Yspring_sB;
+                       Cave[y+1][x] = Ytank_spring;
+                       Next[y+1][x] = Znormal;
+                       Boom[y][x-1] = Xblank;
+                       Boom[y][x] = Xblank;
+                       Boom[y][x+1] = Xblank;
+                       Boom[y+1][x-1] = Xblank;
+                       Boom[y+1][x] = Xblank;
+                       Boom[y+1][x+1] = Xblank;
+                       Boom[y+2][x-1] = Xblank;
+                       Boom[y+2][x] = Xblank;
+                       Boom[y+2][x+1] = Xblank;
+                       score += lev.tank_score;
+                       goto loop;
+               case Xeater_n:
+               case Xeater_e:
+               case Xeater_s:
+               case Xeater_w:
+                       Cave[y][x] = Yspring_sB;
+                       Cave[y+1][x] = Yeater_spring;
+                       Next[y+1][x] = Znormal;
+                       Boom[y][x-1] = lev.eater_array[lev.eater_pos][0];
+                       Boom[y][x] = lev.eater_array[lev.eater_pos][1];
+                       Boom[y][x+1] = lev.eater_array[lev.eater_pos][2];
+                       Boom[y+1][x-1] = lev.eater_array[lev.eater_pos][3];
+                       Boom[y+1][x] = lev.eater_array[lev.eater_pos][4];
+                       Boom[y+1][x+1] = lev.eater_array[lev.eater_pos][5];
+                       Boom[y+2][x-1] = lev.eater_array[lev.eater_pos][6];
+                       Boom[y+2][x] = lev.eater_array[lev.eater_pos][7];
+                       Boom[y+2][x+1] = lev.eater_array[lev.eater_pos][8];
+                       lev.eater_pos = (lev.eater_pos + 1) & 7;
+                       score += lev.eater_score;
+                       goto loop;
+               case Xalien:
+               case Xalien_pause:
+                       Cave[y][x] = Yspring_sB;
+                       Cave[y+1][x] = Yalien_spring;
+                       Next[y+1][x] = Znormal;
+                       Boom[y][x-1] = Xblank;
+                       Boom[y][x] = Xblank;
+                       Boom[y][x+1] = Xblank;
+                       Boom[y+1][x-1] = Xblank;
+                       Boom[y+1][x] = Xblank;
+                       Boom[y+1][x+1] = Xblank;
+                       Boom[y+2][x-1] = Xblank;
+                       Boom[y+2][x] = Xblank;
+                       Boom[y+2][x+1] = Xblank;
+                       score += lev.alien_score;
+                       goto loop;
+               default:
+                       Cave[y][x] = Xspring;
+                       Next[y][x] = Xspring;
+                       PLAY(SAMPLE_spring);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xeater_n:
+               if(Cave[y][x+1] == Xdiamond) {
+                       Cave[y][x+1] = Ydiamond_eat;
+                       Next[y][x+1] = Xblank;
+                       play[SAMPLE_eater] = 1;
+                       goto loop;
+               }
+               if(Cave[y+1][x] == Xdiamond) {
+                       Cave[y+1][x] = Ydiamond_eat;
+                       Next[y+1][x] = Xblank;
+                       play[SAMPLE_eater] = 1;
+                       goto loop;
+               }
+               if(Cave[y][x-1] == Xdiamond) {
+                       Cave[y][x-1] = Ydiamond_eat;
+                       Next[y][x-1] = Xblank;
+                       play[SAMPLE_eater] = 1;
+                       goto loop;
+               }
+               if(Cave[y-1][x] == Xdiamond) {
+                       Cave[y-1][x] = Ydiamond_eat;
+                       Next[y-1][x] = Xblank;
+                       play[SAMPLE_eater] = 1;
+                       goto loop;
+               }
+               switch(Cave[y-1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yeater_nB;
+                       if(Cave[y-2][x+1] == Xblank) Cave[y-2][x+1] = Yacid_splash_eB;
+                       if(Cave[y-2][x-1] == Xblank) Cave[y-2][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Zplayer:
+                       Cave[y][x] = Yeater_nB;
+                       Cave[y-1][x] = Yeater_n;
+                       Next[y][x] = Xblank;
+                       Next[y-1][x] = Xeater_n;
+                       goto loop;
+               default:
+                       Next[y][x] = RANDOM & 1 ? Xeater_e : Xeater_w;
+                       PLAY(SAMPLE_eater);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xeater_e:
+               if(Cave[y+1][x] == Xdiamond) {
+                       Cave[y+1][x] = Ydiamond_eat;
+                       Next[y+1][x] = Xblank;
+                       play[SAMPLE_eater] = 1;
+                       goto loop;
+               }
+               if(Cave[y][x-1] == Xdiamond) {
+                       Cave[y][x-1] = Ydiamond_eat;
+                       Next[y][x-1] = Xblank;
+                       play[SAMPLE_eater] = 1;
+                       goto loop;
+               }
+               if(Cave[y-1][x] == Xdiamond) {
+                       Cave[y-1][x] = Ydiamond_eat;
+                       Next[y-1][x] = Xblank;
+                       play[SAMPLE_eater] = 1;
+                       goto loop;
+               }
+               if(Cave[y][x+1] == Xdiamond) {
+                       Cave[y][x+1] = Ydiamond_eat;
+                       Next[y][x+1] = Xblank;
+                       play[SAMPLE_eater] = 1;
+                       goto loop;
+               }
+               switch(Cave[y][x+1]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yeater_eB;
+                       if(Cave[y-1][x+2] == Xblank) Cave[y-1][x+2] = Yacid_splash_eB;
+                       if(Cave[y-1][x] == Xblank) Cave[y-1][x] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Zplayer:
+                       Cave[y][x] = Yeater_eB;
+                       Cave[y][x+1] = Yeater_e;
+                       Next[y][x] = Xblank;
+                       Next[y][x+1] = Xeater_e;
+                       goto loop;
+               default:
+                       Next[y][x] = RANDOM & 1 ? Xeater_n : Xeater_s;
+                       PLAY(SAMPLE_eater);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xeater_s:
+               if(Cave[y][x-1] == Xdiamond) {
+                       Cave[y][x-1] = Ydiamond_eat;
+                       Next[y][x-1] = Xblank;
+                       play[SAMPLE_eater] = 1;
+                       goto loop;
+               }
+               if(Cave[y-1][x] == Xdiamond) {
+                       Cave[y-1][x] = Ydiamond_eat;
+                       Next[y-1][x] = Xblank;
+                       play[SAMPLE_eater] = 1;
+                       goto loop;
+               }
+               if(Cave[y][x+1] == Xdiamond) {
+                       Cave[y][x+1] = Ydiamond_eat;
+                       Next[y][x+1] = Xblank;
+                       play[SAMPLE_eater] = 1;
+                       goto loop;
+               }
+               if(Cave[y+1][x] == Xdiamond) {
+                       Cave[y+1][x] = Ydiamond_eat;
+                       Next[y+1][x] = Xblank;
+                       play[SAMPLE_eater] = 1;
+                       goto loop;
+               }
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yeater_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Zplayer:
+                       Cave[y][x] = Yeater_sB;
+                       Cave[y+1][x] = Yeater_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xeater_s;
+                       goto loop;
+               default:
+                       Next[y][x] = RANDOM & 1 ? Xeater_e : Xeater_w;
+                       PLAY(SAMPLE_eater);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xeater_w:
+               if(Cave[y-1][x] == Xdiamond) {
+                       Cave[y-1][x] = Ydiamond_eat;
+                       Next[y-1][x] = Xblank;
+                       play[SAMPLE_eater] = 1;
+                       goto loop;
+               }
+               if(Cave[y][x+1] == Xdiamond) {
+                       Cave[y][x+1] = Ydiamond_eat;
+                       Next[y][x+1] = Xblank;
+                       play[SAMPLE_eater] = 1;
+                       goto loop;
+               }
+               if(Cave[y+1][x] == Xdiamond) {
+                       Cave[y+1][x] = Ydiamond_eat;
+                       Next[y+1][x] = Xblank;
+                       play[SAMPLE_eater] = 1;
+                       goto loop;
+               }
+               if(Cave[y][x-1] == Xdiamond) {
+                       Cave[y][x-1] = Ydiamond_eat;
+                       Next[y][x-1] = Xblank;
+                       play[SAMPLE_eater] = 1;
+                       goto loop;
+               }
+               switch(Cave[y][x-1]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yeater_wB;
+                       if(Cave[y-1][x] == Xblank) Cave[y-1][x] = Yacid_splash_eB;
+                       if(Cave[y-1][x-2] == Xblank) Cave[y-1][x-2] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Zplayer:
+                       Cave[y][x] = Yeater_wB;
+                       Cave[y][x-1] = Yeater_w;
+                       Next[y][x] = Xblank;
+                       Next[y][x-1] = Xeater_w;
+                       goto loop;
+               default:
+                       Next[y][x] = RANDOM & 1 ? Xeater_n : Xeater_s;
+                       PLAY(SAMPLE_eater);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xalien:
+               if(lev.wheel_cnt) {
+                       dx = lev.wheel_x;
+                       dy = lev.wheel_y;
+               } else if(ply1.alive && ply2.alive) {
+                       if( (ply1.x > x ? ply1.x - x : x - ply1.x) + (ply1.y > y ? ply1.y - y : y - ply1.y) < (ply2.x > x ? ply2.x - x : x - ply2.x) + (ply2.y > y ? ply2.y - y : y - ply2.y) ) {
+                               dx = ply1.x;
+                               dy = ply1.y;
+                       } else {
+                               dx = ply2.x;
+                               dy = ply2.y;
+                       }
+               } else if(ply1.alive) {
+                       dx = ply1.x;
+                       dy = ply1.y;
+               } else if(ply2.alive) {
+                       dx = ply2.x;
+                       dy = ply2.y;
+               } else {
+                       dx = 0;
+                       dy = 0;
+               }
+               if(RANDOM & 1) {
+                       if(y > dy) {
+                               switch(Cave[y-1][x]) {
+                               case Xacid_1:
+                               case Xacid_2:
+                               case Xacid_3:
+                               case Xacid_4:
+                               case Xacid_5:
+                               case Xacid_6:
+                               case Xacid_7:
+                               case Xacid_8:
+                                       Cave[y][x] = Yalien_nB;
+                                       if(Cave[y-2][x+1] == Xblank) Cave[y-2][x+1] = Yacid_splash_eB;
+                                       if(Cave[y-2][x-1] == Xblank) Cave[y-2][x-1] = Yacid_splash_wB;
+                                       Next[y][x] = Xblank;
+                                       PLAY(SAMPLE_acid);
+                                       goto loop;
+                               case Xblank:
+                               case Yacid_splash_eB:
+                               case Yacid_splash_wB:
+                               case Xplant:
+                               case Yplant:
+                               case Zplayer:
+                                       Cave[y][x] = Yalien_nB;
+                                       Cave[y-1][x] = Yalien_n;
+                                       Next[y][x] = Xblank;
+                                       Next[y-1][x] = Xalien_pause;
+                                       PLAY(SAMPLE_alien);
+                                       goto loop;
+                               }
+                       } else if(y < dy) {
+                               switch(Cave[y+1][x]) {
+                               case Xacid_1:
+                               case Xacid_2:
+                               case Xacid_3:
+                               case Xacid_4:
+                               case Xacid_5:
+                               case Xacid_6:
+                               case Xacid_7:
+                               case Xacid_8:
+                                       Cave[y][x] = Yalien_sB;
+                                       Next[y][x] = Xblank;
+                                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                                       PLAY(SAMPLE_acid);
+                                       goto loop;
+                               case Xblank:
+                               case Yacid_splash_eB:
+                               case Yacid_splash_wB:
+                               case Xplant:
+                               case Yplant:
+                               case Zplayer:
+                                       Cave[y][x] = Yalien_sB;
+                                       Cave[y+1][x] = Yalien_s;
+                                       Next[y][x] = Xblank;
+                                       Next[y+1][x] = Xalien_pause;
+                                       PLAY(SAMPLE_alien);
+                                       goto loop;
+                               }
+                       }
+               } else {
+                       if(x < dx) {
+                               switch(Cave[y][x+1]) {
+                               case Xacid_1:
+                               case Xacid_2:
+                               case Xacid_3:
+                               case Xacid_4:
+                               case Xacid_5:
+                               case Xacid_6:
+                               case Xacid_7:
+                               case Xacid_8:
+                                       Cave[y][x] = Yalien_eB;
+                                       if(Cave[y-1][x+2] == Xblank) Cave[y-1][x+2] = Yacid_splash_eB;
+                                       if(Cave[y-1][x] == Xblank) Cave[y-1][x] = Yacid_splash_wB;
+                                       Next[y][x] = Xblank;
+                                       PLAY(SAMPLE_acid);
+                                       goto loop;
+                               case Xblank:
+                               case Yacid_splash_eB:
+                               case Yacid_splash_wB:
+                               case Xplant:
+                               case Yplant:
+                               case Zplayer:
+                                       Cave[y][x] = Yalien_eB;
+                                       Cave[y][x+1] = Yalien_e;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x+1] = Xalien_pause;
+                                       PLAY(SAMPLE_alien);
+                                       goto loop;
+                               }
+                       } else if(x > dx) {
+                               switch(Cave[y][x-1]) {
+                               case Xacid_1:
+                               case Xacid_2:
+                               case Xacid_3:
+                               case Xacid_4:
+                               case Xacid_5:
+                               case Xacid_6:
+                               case Xacid_7:
+                               case Xacid_8:
+                                       Cave[y][x] = Yalien_wB;
+                                       if(Cave[y-1][x] == Xblank) Cave[y-1][x] = Yacid_splash_eB;
+                                       if(Cave[y-1][x-2] == Xblank) Cave[y-1][x-2] = Yacid_splash_wB;
+                                       Next[y][x] = Xblank;
+                                       PLAY(SAMPLE_acid);
+                                       goto loop;
+                               case Xblank:
+                               case Yacid_splash_eB:
+                               case Yacid_splash_wB:
+                               case Xplant:
+                               case Yplant:
+                               case Zplayer:
+                                       Cave[y][x] = Yalien_wB;
+                                       Cave[y][x-1] = Yalien_w;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x-1] = Xalien_pause;
+                                       PLAY(SAMPLE_alien);
+                                       goto loop;
+                               }
+                       }
+               }
+               goto loop;
+       case Xalien_pause:
+               Next[y][x] = Xalien;
+               goto loop;
+/* ---------------------------------------------------------------------- */
+       case Xemerald:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yemerald_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Yemerald_sB;
+                       Cave[y+1][x] = Yemerald_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xemerald_fall;
+                       goto loop;
+               case Xspring:
+               case Xspring_pause:
+               case Xspring_e:
+               case Xspring_w:
+               case Xandroid:
+               case Xandroid_1_n:
+               case Xandroid_2_n:
+               case Xandroid_1_e:
+               case Xandroid_2_e:
+               case Xandroid_1_s:
+               case Xandroid_2_s:
+               case Xandroid_1_w:
+               case Xandroid_2_w:
+               case Xstone:
+               case Xstone_pause:
+               case Xemerald:
+               case Xemerald_pause:
+               case Xdiamond:
+               case Xdiamond_pause:
+               case Xbomb:
+               case Xbomb_pause:
+               case Xballoon:
+               case Xacid_ne:
+               case Xacid_nw:
+               case Xball_1:
+               case Xball_2:
+               case Xnut:
+               case Xnut_pause:
+               case Xgrow_ns:
+               case Xgrow_ew:
+               case Xwonderwall:
+               case Xkey_1:
+               case Xkey_2:
+               case Xkey_3:
+               case Xkey_4:
+               case Xkey_5:
+               case Xkey_6:
+               case Xkey_7:
+               case Xkey_8:
+               case Xbumper:
+               case Xswitch:
+               case Xsteel_1:
+               case Xsteel_2:
+               case Xsteel_3:
+               case Xsteel_4:
+               case Xwall_1:
+               case Xwall_2:
+               case Xwall_3:
+               case Xwall_4:
+               case Xround_wall_1:
+               case Xround_wall_2:
+               case Xround_wall_3:
+               case Xround_wall_4:
+                       if(RANDOM & 1) {
+                               if(tab_blank[Cave[y][x+1]] && tab_acid[Cave[y+1][x+1]]) {
+                                       Cave[y][x] = Yemerald_eB;
+                                       Cave[y][x+1] = Yemerald_e;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x+1] = Xemerald_pause;
+                                       goto loop;
+                               }
+                               if(tab_blank[Cave[y][x-1]] && tab_acid[Cave[y+1][x-1]]) {
+                                       Cave[y][x] = Yemerald_wB;
+                                       Cave[y][x-1] = Yemerald_w;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x-1] = Xemerald_pause;
+                                       goto loop;
+                               }
+                       } else {
+                               if(tab_blank[Cave[y][x-1]] && tab_acid[Cave[y+1][x-1]]) {
+                                       Cave[y][x] = Yemerald_wB;
+                                       Cave[y][x-1] = Yemerald_w;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x-1] = Xemerald_pause;
+                                       goto loop;
+                               }
+                               if(tab_blank[Cave[y][x+1]] && tab_acid[Cave[y+1][x+1]]) {
+                                       Cave[y][x] = Yemerald_eB;
+                                       Cave[y][x+1] = Yemerald_e;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x+1] = Xemerald_pause;
+                                       goto loop;
+                               }
+                       }
+               default:
+                       if(++lev.shine_cnt > 50) {
+                               lev.shine_cnt = RANDOM & 7;
+                               Cave[y][x] = Xemerald_shine;
+                       }
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xemerald_pause:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yemerald_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Yemerald_sB;
+                       Cave[y+1][x] = Yemerald_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xemerald_fall;
+                       goto loop;
+               default:
+                       Cave[y][x] = Xemerald;
+                       Next[y][x] = Xemerald;
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xemerald_fall:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Yemerald_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Zplayer:
+                       Cave[y][x] = Yemerald_sB;
+                       Cave[y+1][x] = Yemerald_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xemerald_fall;
+                       goto loop;
+               case Xwonderwall:
+                       if(lev.wonderwall_time) {
+                               lev.wonderwall_state = 1;
+                               Cave[y][x] = Yemerald_sB;
+                               if(tab_blank[Cave[y+2][x]]) {
+                                       Cave[y+2][x] = Ydiamond_s;
+                                       Next[y+2][x] = Xdiamond_fall;
+                               }
+                               Next[y][x] = Xblank;
+                               play[SAMPLE_squash] = 1;
+                               goto loop;
+                       }
+               default:
+                       Cave[y][x] = Xemerald;
+                       Next[y][x] = Xemerald;
+                       PLAY(SAMPLE_diamond);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xdiamond:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ydiamond_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Ydiamond_sB;
+                       Cave[y+1][x] = Ydiamond_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xdiamond_fall;
+                       goto loop;
+               case Xspring:
+               case Xspring_pause:
+               case Xspring_e:
+               case Xspring_w:
+               case Xandroid:
+               case Xandroid_1_n:
+               case Xandroid_2_n:
+               case Xandroid_1_e:
+               case Xandroid_2_e:
+               case Xandroid_1_s:
+               case Xandroid_2_s:
+               case Xandroid_1_w:
+               case Xandroid_2_w:
+               case Xstone:
+               case Xstone_pause:
+               case Xemerald:
+               case Xemerald_pause:
+               case Xdiamond:
+               case Xdiamond_pause:
+               case Xbomb:
+               case Xbomb_pause:
+               case Xballoon:
+               case Xacid_ne:
+               case Xacid_nw:
+               case Xball_1:
+               case Xball_2:
+               case Xnut:
+               case Xnut_pause:
+               case Xgrow_ns:
+               case Xgrow_ew:
+               case Xwonderwall:
+               case Xkey_1:
+               case Xkey_2:
+               case Xkey_3:
+               case Xkey_4:
+               case Xkey_5:
+               case Xkey_6:
+               case Xkey_7:
+               case Xkey_8:
+               case Xbumper:
+               case Xswitch:
+               case Xsteel_1:
+               case Xsteel_2:
+               case Xsteel_3:
+               case Xsteel_4:
+               case Xwall_1:
+               case Xwall_2:
+               case Xwall_3:
+               case Xwall_4:
+               case Xround_wall_1:
+               case Xround_wall_2:
+               case Xround_wall_3:
+               case Xround_wall_4:
+                       if(RANDOM & 1) {
+                               if(tab_blank[Cave[y][x+1]] && tab_acid[Cave[y+1][x+1]]) {
+                                       Cave[y][x] = Ydiamond_eB;
+                                       Cave[y][x+1] = Ydiamond_e;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x+1] = Xdiamond_pause;
+                                       goto loop;
+                               }
+                               if(tab_blank[Cave[y][x-1]] && tab_acid[Cave[y+1][x-1]]) {
+                                       Cave[y][x] = Ydiamond_wB;
+                                       Cave[y][x-1] = Ydiamond_w;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x-1] = Xdiamond_pause;
+                                       goto loop;
+                               }
+                       } else {
+                               if(tab_blank[Cave[y][x-1]] && tab_acid[Cave[y+1][x-1]]) {
+                                       Cave[y][x] = Ydiamond_wB;
+                                       Cave[y][x-1] = Ydiamond_w;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x-1] = Xdiamond_pause;
+                                       goto loop;
+                               }
+                               if(tab_blank[Cave[y][x+1]] && tab_acid[Cave[y+1][x+1]]) {
+                                       Cave[y][x] = Ydiamond_eB;
+                                       Cave[y][x+1] = Ydiamond_e;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x+1] = Xdiamond_pause;
+                                       goto loop;
+                               }
+                       }
+               default:
+                       if(++lev.shine_cnt > 50) {
+                               lev.shine_cnt = RANDOM & 7;
+                               Cave[y][x] = Xdiamond_shine;
+                       }
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xdiamond_pause:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ydiamond_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Ydiamond_sB;
+                       Cave[y+1][x] = Ydiamond_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xdiamond_fall;
+                       goto loop;
+               default:
+                       Cave[y][x] = Xdiamond;
+                       Next[y][x] = Xdiamond;
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xdiamond_fall:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ydiamond_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Zplayer:
+                       Cave[y][x] = Ydiamond_sB;
+                       Cave[y+1][x] = Ydiamond_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xdiamond_fall;
+                       goto loop;
+               case Xwonderwall:
+                       if(lev.wonderwall_time) {
+                               lev.wonderwall_state = 1;
+                               Cave[y][x] = Ydiamond_sB;
+                               if(tab_blank[Cave[y+2][x]]) {
+                                       Cave[y+2][x] = Ystone_s;
+                                       Next[y+2][x] = Xstone_fall;
+                               }
+                               Next[y][x] = Xblank;
+                               play[SAMPLE_squash] = 1;
+                               goto loop;
+                       }
+               default:
+                       Cave[y][x] = Xdiamond;
+                       Next[y][x] = Xdiamond;
+                       PLAY(SAMPLE_diamond);
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xdrip_fall:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ydrip_s1B;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xdrip_stretchB;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xplant:
+               case Yplant:
+               case Zplayer:
+                       Cave[y][x] = Ydrip_s1B;
+                       Cave[y+1][x] = Ydrip_s1;
+                       Next[y][x] = Xdrip_stretchB;
+                       Next[y+1][x] = Xdrip_stretch;
+                       goto loop;
+               default:
+                       switch(RANDOM & 7) {
+                       case 0: temp = Xameuba_1; break;
+                       case 1: temp = Xameuba_2; break;
+                       case 2: temp = Xameuba_3; break;
+                       case 3: temp = Xameuba_4; break;
+                       case 4: temp = Xameuba_5; break;
+                       case 5: temp = Xameuba_6; break;
+                       case 6: temp = Xameuba_7; break;
+                       case 7: temp = Xameuba_8; break;
+                       }
+                       Cave[y][x] = temp;
+                       Next[y][x] = temp;
+                       play[SAMPLE_drip] = 1;
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xdrip_stretch:
+               Cave[y][x] = Ydrip_s2;
+               Next[y][x] = Xdrip_fall;
+               goto loop;
+       case Xdrip_stretchB:
+               Cave[y][x] = Ydrip_s2B;
+               Next[y][x] = Xblank;
+               goto loop;
+       case Xdrip_eat:
+               Next[y][x] = Xdrip_fall;
+               goto loop;
+/* ---------------------------------------------------------------------- */
+       case Xbomb:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ybomb_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Ybomb_sB;
+                       Cave[y+1][x] = Ybomb_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xbomb_fall;
+                       goto loop;
+               case Xspring:
+               case Xspring_pause:
+               case Xspring_e:
+               case Xspring_w:
+               case Xandroid:
+               case Xandroid_1_n:
+               case Xandroid_2_n:
+               case Xandroid_1_e:
+               case Xandroid_2_e:
+               case Xandroid_1_s:
+               case Xandroid_2_s:
+               case Xandroid_1_w:
+               case Xandroid_2_w:
+               case Xstone:
+               case Xstone_pause:
+               case Xemerald:
+               case Xemerald_pause:
+               case Xdiamond:
+               case Xdiamond_pause:
+               case Xbomb:
+               case Xbomb_pause:
+               case Xballoon:
+               case Xacid_ne:
+               case Xacid_nw:
+               case Xball_1:
+               case Xball_2:
+               case Xnut:
+               case Xnut_pause:
+               case Xgrow_ns:
+               case Xgrow_ew:
+               case Xkey_1:
+               case Xkey_2:
+               case Xkey_3:
+               case Xkey_4:
+               case Xkey_5:
+               case Xkey_6:
+               case Xkey_7:
+               case Xkey_8:
+               case Xbumper:
+               case Xswitch:
+               case Xround_wall_1:
+               case Xround_wall_2:
+               case Xround_wall_3:
+               case Xround_wall_4:
+                       if(RANDOM & 1) {
+                               if(tab_blank[Cave[y][x+1]] && tab_acid[Cave[y+1][x+1]]) {
+                                       Cave[y][x] = Ybomb_eB;
+                                       Cave[y][x+1] = Ybomb_e;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x+1] = Xbomb_pause;
+                                       goto loop;
+                               }
+                               if(tab_blank[Cave[y][x-1]] && tab_acid[Cave[y+1][x-1]]) {
+                                       Cave[y][x] = Ybomb_wB;
+                                       Cave[y][x-1] = Ybomb_w;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x-1] = Xbomb_pause;
+                                       goto loop;
+                               }
+                       } else {
+                               if(tab_blank[Cave[y][x-1]] && tab_acid[Cave[y+1][x-1]]) {
+                                       Cave[y][x] = Ybomb_wB;
+                                       Cave[y][x-1] = Ybomb_w;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x-1] = Xbomb_pause;
+                                       goto loop;
+                               }
+                               if(tab_blank[Cave[y][x+1]] && tab_acid[Cave[y+1][x+1]]) {
+                                       Cave[y][x] = Ybomb_eB;
+                                       Cave[y][x+1] = Ybomb_e;
+                                       Next[y][x] = Xblank;
+                                       Next[y][x+1] = Xbomb_pause;
+                                       goto loop;
+                               }
+                       }
+               default:
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xbomb_pause:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ybomb_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Ybomb_sB;
+                       Cave[y+1][x] = Ybomb_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xbomb_fall;
+                       goto loop;
+               default:
+                       Cave[y][x] = Xbomb;
+                       Next[y][x] = Xbomb;
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xbomb_fall:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Ybomb_sB;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xblank;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Ybomb_sB;
+                       Cave[y+1][x] = Ybomb_s;
+                       Next[y][x] = Xblank;
+                       Next[y+1][x] = Xbomb_fall;
+                       goto loop;
+               default:
+                       Cave[y][x] = Ybomb_eat;
+                       Next[y][x] = Znormal;
+                       Boom[y-1][x-1] = Xblank;
+                       Boom[y-1][x] = Xblank;
+                       Boom[y-1][x+1] = Xblank;
+                       Boom[y][x-1] = Xblank;
+                       Boom[y][x] = Xblank;
+                       Boom[y][x+1] = Xblank;
+                       Boom[y+1][x-1] = Xblank;
+                       Boom[y+1][x] = Xblank;
+                       Boom[y+1][x+1] = Xblank;
+                       goto loop;
+               }
+/* ---------------------------------------------------------------------- */
+       case Xballoon:
+               if(lev.wind_cnt == 0) goto loop;
+               switch(lev.wind_direction) {
+               case 0: /* north */
+                       switch(Cave[y-1][x]) {
+                       case Xacid_1:
+                       case Xacid_2:
+                       case Xacid_3:
+                       case Xacid_4:
+                       case Xacid_5:
+                       case Xacid_6:
+                       case Xacid_7:
+                       case Xacid_8:
+                               Cave[y][x] = Yballoon_nB;
+                               if(Cave[y-2][x+1] == Xblank) Cave[y-2][x+1] = Yacid_splash_eB;
+                               if(Cave[y-2][x-1] == Xblank) Cave[y-2][x-1] = Yacid_splash_wB;
+                               Next[y][x] = Xblank;
+                               PLAY(SAMPLE_acid);
+                               goto loop;
+                       case Xblank:
+                       case Yacid_splash_eB:
+                       case Yacid_splash_wB:
+                               Cave[y][x] = Yballoon_nB;
+                               Cave[y-1][x] = Yballoon_n;
+                               Next[y][x] = Xblank;
+                               Next[y-1][x] = Xballoon;
+                               goto loop;
+                       default:
+                               goto loop;
+                       }
+               case 1: /* east */
+                       switch(Cave[y][x+1]) {
+                       case Xacid_1:
+                       case Xacid_2:
+                       case Xacid_3:
+                       case Xacid_4:
+                       case Xacid_5:
+                       case Xacid_6:
+                       case Xacid_7:
+                       case Xacid_8:
+                               Cave[y][x] = Yballoon_eB;
+                               if(Cave[y-1][x+2] == Xblank) Cave[y-1][x+2] = Yacid_splash_eB;
+                               if(Cave[y-1][x] == Xblank) Cave[y-1][x] = Yacid_splash_wB;
+                               Next[y][x] = Xblank;
+                               PLAY(SAMPLE_acid);
+                               goto loop;
+                       case Xblank:
+                       case Yacid_splash_eB:
+                       case Yacid_splash_wB:
+                               Cave[y][x] = Yballoon_eB;
+                               Cave[y][x+1] = Yballoon_e;
+                               Next[y][x] = Xblank;
+                               Next[y][x+1] = Xballoon;
+                               goto loop;
+                       default:
+                               goto loop;
+                       }
+               case 2: /* south */
+                       switch(Cave[y+1][x]) {
+                       case Xacid_1:
+                       case Xacid_2:
+                       case Xacid_3:
+                       case Xacid_4:
+                       case Xacid_5:
+                       case Xacid_6:
+                       case Xacid_7:
+                       case Xacid_8:
+                               Cave[y][x] = Yballoon_sB;
+                               if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                               if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                               Next[y][x] = Xblank;
+                               PLAY(SAMPLE_acid);
+                               goto loop;
+                       case Xblank:
+                       case Yacid_splash_eB:
+                       case Yacid_splash_wB:
+                               Cave[y][x] = Yballoon_sB;
+                               Cave[y+1][x] = Yballoon_s;
+                               Next[y][x] = Xblank;
+                               Next[y+1][x] = Xballoon;
+                               goto loop;
+                       default:
+                               goto loop;
+                       }
+               case 3: /* west */
+                       switch(Cave[y][x-1]) {
+                       case Xacid_1:
+                       case Xacid_2:
+                       case Xacid_3:
+                       case Xacid_4:
+                       case Xacid_5:
+                       case Xacid_6:
+                       case Xacid_7:
+                       case Xacid_8:
+                               Cave[y][x] = Yballoon_wB;
+                               if(Cave[y-1][x] == Xblank) Cave[y-1][x] = Yacid_splash_eB;
+                               if(Cave[y-1][x-2] == Xblank) Cave[y-1][x-2] = Yacid_splash_wB;
+                               Next[y][x] = Xblank;
+                               PLAY(SAMPLE_acid);
+                               goto loop;
+                       case Xblank:
+                       case Yacid_splash_eB:
+                       case Yacid_splash_wB:
+                               Cave[y][x] = Yballoon_wB;
+                               Cave[y][x-1] = Yballoon_w;
+                               Next[y][x] = Xblank;
+                               Next[y][x-1] = Xballoon;
+                               goto loop;
+                       default:
+                               goto loop;
+                       }
+               }
+/* ---------------------------------------------------------------------- */
+       case Xacid_1:
+               Next[y][x] = Xacid_2;
+               goto loop;
+       case Xacid_2:
+               Next[y][x] = Xacid_3;
+               goto loop;
+       case Xacid_3:
+               Next[y][x] = Xacid_4;
+               goto loop;
+       case Xacid_4:
+               Next[y][x] = Xacid_5;
+               goto loop;
+       case Xacid_5:
+               Next[y][x] = Xacid_6;
+               goto loop;
+       case Xacid_6:
+               Next[y][x] = Xacid_7;
+               goto loop;
+       case Xacid_7:
+               Next[y][x] = Xacid_8;
+               goto loop;
+       case Xacid_8:
+               Next[y][x] = Xacid_1;
+               goto loop;
+/* ---------------------------------------------------------------------- */
+       case Xball_1:
+               if(lev.ball_state == 0) goto loop;
+               Cave[y][x] = Xball_1B;
+               Next[y][x] = Xball_2;
+               if(lev.ball_cnt) goto loop;
+               goto ball_common;
+       case Xball_2:
+               if(lev.ball_state == 0) goto loop;
+               Cave[y][x] = Xball_2B;
+               Next[y][x] = Xball_1;
+               if(lev.ball_cnt) goto loop;
+               goto ball_common;
+       ball_common:
+               play[SAMPLE_ball] = 1;
+               if(lev.ball_random) {
+                       switch(RANDOM & 7) {
+                       case 0:
+                               if(lev.ball_array[lev.ball_pos][0] != Xblank && tab_blank[Cave[y-1][x-1]]) {
+                                       Cave[y-1][x-1] = Yball_eat;
+                                       Next[y-1][x-1] = lev.ball_array[lev.ball_pos][0];
+                               }
+                               break;
+                       case 1:
+                               if(lev.ball_array[lev.ball_pos][1] != Xblank && tab_blank[Cave[y-1][x]]) {
+                                       Cave[y-1][x] = Yball_eat;
+                                       Next[y-1][x] = lev.ball_array[lev.ball_pos][1];
+                               }
+                               break;
+                       case 2:
+                               if(lev.ball_array[lev.ball_pos][2] != Xblank && tab_blank[Cave[y-1][x+1]]) {
+                                       Cave[y-1][x+1] = Yball_eat;
+                                       Next[y-1][x+1] = lev.ball_array[lev.ball_pos][2];
+                               }
+                               break;
+                       case 3:
+                               if(lev.ball_array[lev.ball_pos][3] != Xblank && tab_blank[Cave[y][x-1]]) {
+                                       Cave[y][x-1] = Yball_eat;
+                                       Next[y][x-1] = lev.ball_array[lev.ball_pos][3];
+                               }
+                               break;
+                       case 4:
+                               if(lev.ball_array[lev.ball_pos][4] != Xblank && tab_blank[Cave[y][x+1]]) {
+                                       Cave[y][x+1] = Yball_eat;
+                                       Next[y][x+1] = lev.ball_array[lev.ball_pos][4];
+                               }
+                               break;
+                       case 5:
+                               if(lev.ball_array[lev.ball_pos][5] != Xblank && tab_blank[Cave[y+1][x-1]]) {
+                                       Cave[y+1][x-1] = Yball_eat;
+                                       Next[y+1][x-1] = lev.ball_array[lev.ball_pos][5];
+                               }
+                               break;
+                       case 6:
+                               if(lev.ball_array[lev.ball_pos][6] != Xblank && tab_blank[Cave[y+1][x]]) {
+                                       Cave[y+1][x] = Yball_eat;
+                                       Next[y+1][x] = lev.ball_array[lev.ball_pos][6];
+                               }
+                               break;
+                       case 7:
+                               if(lev.ball_array[lev.ball_pos][7] != Xblank && tab_blank[Cave[y+1][x+1]]) {
+                                       Cave[y+1][x+1] = Yball_eat;
+                                       Next[y+1][x+1] = lev.ball_array[lev.ball_pos][7];
+                               }
+                               break;
+                       }
+               } else {
+                       if(lev.ball_array[lev.ball_pos][0] != Xblank && tab_blank[Cave[y-1][x-1]]) {
+                               Cave[y-1][x-1] = Yball_eat;
+                               Next[y-1][x-1] = lev.ball_array[lev.ball_pos][0];
+                       }
+                       if(lev.ball_array[lev.ball_pos][1] != Xblank && tab_blank[Cave[y-1][x]]) {
+                               Cave[y-1][x] = Yball_eat;
+                               Next[y-1][x] = lev.ball_array[lev.ball_pos][1];
+                       }
+                       if(lev.ball_array[lev.ball_pos][2] != Xblank && tab_blank[Cave[y-1][x+1]]) {
+                               Cave[y-1][x+1] = Yball_eat;
+                               Next[y-1][x+1] = lev.ball_array[lev.ball_pos][2];
+                       }
+                       if(lev.ball_array[lev.ball_pos][3] != Xblank && tab_blank[Cave[y][x-1]]) {
+                               Cave[y][x-1] = Yball_eat;
+                               Next[y][x-1] = lev.ball_array[lev.ball_pos][3];
+                       }
+                       if(lev.ball_array[lev.ball_pos][4] != Xblank && tab_blank[Cave[y][x+1]]) {
+                               Cave[y][x+1] = Yball_eat;
+                               Next[y][x+1] = lev.ball_array[lev.ball_pos][4];
+                       }
+                       if(lev.ball_array[lev.ball_pos][5] != Xblank && tab_blank[Cave[y+1][x-1]]) {
+                               Cave[y+1][x-1] = Yball_eat;
+                               Next[y+1][x-1] = lev.ball_array[lev.ball_pos][5];
+                       }
+                       if(lev.ball_array[lev.ball_pos][6] != Xblank && tab_blank[Cave[y+1][x]]) {
+                               Cave[y+1][x] = Yball_eat;
+                               Next[y+1][x] = lev.ball_array[lev.ball_pos][6];
+                       }
+                       if(lev.ball_array[lev.ball_pos][7] != Xblank && tab_blank[Cave[y+1][x+1]]) {
+                               Cave[y+1][x+1] = Yball_eat;
+                               Next[y+1][x+1] = lev.ball_array[lev.ball_pos][7];
+                       }
+               }
+               lev.ball_pos = (lev.ball_pos + 1) & 7;
+               goto loop;
+/* ---------------------------------------------------------------------- */
+       case Xgrow_ns:
+               if(tab_blank[Cave[y-1][x]]) {
+                       Cave[y-1][x] = Ygrow_ns_eat;
+                       Next[y-1][x] = Xgrow_ns;
+                       play[SAMPLE_grow] = 1;
+               }
+               if(tab_blank[Cave[y+1][x]]) {
+                       Cave[y+1][x] = Ygrow_ns_eat;
+                       Next[y+1][x] = Xgrow_ns;
+                       play[SAMPLE_grow] = 1;
+               }
+               goto loop;
+       case Xgrow_ew:
+               if(tab_blank[Cave[y][x+1]]) {
+                       Cave[y][x+1] = Ygrow_ew_eat;
+                       Next[y][x+1] = Xgrow_ew;
+                       play[SAMPLE_grow] = 1;
+               }
+               if(tab_blank[Cave[y][x-1]]) {
+                       Cave[y][x-1] = Ygrow_ew_eat;
+                       Next[y][x-1] = Xgrow_ew;
+                       play[SAMPLE_grow] = 1;
+               }
+               goto loop;
+/* ---------------------------------------------------------------------- */
+       case Xwonderwall:
+               if(lev.wonderwall_time && lev.wonderwall_state) {
+                       Cave[y][x] = XwonderwallB;
+                       play[SAMPLE_wonder] = 1;
+               }
+               goto loop;
+/* ---------------------------------------------------------------------- */
+       case Xexit:
+               if(lev.required > 0) goto loop;
+               temp = RANDOM & 63;
+               if(temp < 21) {
+                       Cave[y][x] = Xexit_1;
+                       Next[y][x] = Xexit_2;
+               } else if(temp < 42) {
+                       Cave[y][x] = Xexit_2;
+                       Next[y][x] = Xexit_3;
+               } else {
+                       Cave[y][x] = Xexit_3;
+                       Next[y][x] = Xexit_1;
+               }
+               goto loop;
+       case Xexit_1:
+               Next[y][x] = Xexit_2;
+               goto loop;
+       case Xexit_2:
+               Next[y][x] = Xexit_3;
+               goto loop;
+       case Xexit_3:
+               Next[y][x] = Xexit_1;
+               goto loop;
+/* ---------------------------------------------------------------------- */
+       case Xdynamite_1:
+               play[SAMPLE_tick] = 1;
+               Next[y][x] = Xdynamite_2;
+               goto loop;
+       case Xdynamite_2:
+               play[SAMPLE_tick] = 1;
+               Next[y][x] = Xdynamite_3;
+               goto loop;
+       case Xdynamite_3:
+               play[SAMPLE_tick] = 1;
+               Next[y][x] = Xdynamite_4;
+               goto loop;
+       case Xdynamite_4:
+               play[SAMPLE_tick] = 1;
+               Next[y][x] = Zdynamite;
+               Boom[y-1][x-1] = Xblank;
+               Boom[y-1][x] = Xblank;
+               Boom[y-1][x+1] = Xblank;
+               Boom[y][x-1] = Xblank;
+               Boom[y][x] = Xblank;
+               Boom[y][x+1] = Xblank;
+               Boom[y+1][x-1] = Xblank;
+               Boom[y+1][x] = Xblank;
+               Boom[y+1][x+1] = Xblank;
+               goto loop;
+/* ---------------------------------------------------------------------- */
+       case Xwheel:
+               if(lev.wheel_cnt && x == lev.wheel_x && y == lev.wheel_y) Cave[y][x] = XwheelB;
+               goto loop;
+/* ---------------------------------------------------------------------- */
+       case Xswitch:
+               if(lev.ball_state) Cave[y][x] = XswitchB;
+               goto loop;
+/* ---------------------------------------------------------------------- */
+       case Xsand_stone:
+               switch(Cave[y+1][x]) {
+               case Xacid_1:
+               case Xacid_2:
+               case Xacid_3:
+               case Xacid_4:
+               case Xacid_5:
+               case Xacid_6:
+               case Xacid_7:
+               case Xacid_8:
+                       Cave[y][x] = Xsand_stonesand_3;
+                       if(Cave[y][x+1] == Xblank) Cave[y][x+1] = Yacid_splash_eB;
+                       if(Cave[y][x-1] == Xblank) Cave[y][x-1] = Yacid_splash_wB;
+                       Next[y][x] = Xsand_stonesand_4;
+                       PLAY(SAMPLE_acid);
+                       goto loop;
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+                       Cave[y][x] = Xsand_stonesand_3;
+                       Cave[y+1][x] = Xsand_stoneout_1;
+                       Next[y][x] = Xsand_stonesand_4;
+                       Next[y+1][x] = Xsand_stoneout_2;
+                       goto loop;
+               case Xsand:
+                       Cave[y][x] = Xsand_stonesand_1;
+                       Cave[y+1][x] = Xsand_sandstone_1;
+                       Next[y][x] = Xsand_stonesand_2;
+                       Next[y+1][x] = Xsand_sandstone_2;
+                       goto loop;
+               default:
+                       goto loop;
+               }
+       case Xsand_stonein_1:
+               Next[y][x] = Xsand_stonein_2;
+               goto loop;
+       case Xsand_stonein_2:
+               Next[y][x] = Xsand_stonein_3;
+               goto loop;
+       case Xsand_stonein_3:
+               Next[y][x] = Xsand_stonein_4;
+               goto loop;
+       case Xsand_stonein_4:
+               Next[y][x] = Xblank;
+               goto loop;
+       case Xsand_stonesand_1:
+               Next[y][x] = Xsand_stonesand_2;
+               goto loop;
+       case Xsand_stonesand_2:
+               Next[y][x] = Xsand_stonesand_3;
+               goto loop;
+       case Xsand_stonesand_3:
+               Next[y][x] = Xsand_stonesand_4;
+               goto loop;
+       case Xsand_stonesand_4:
+               Next[y][x] = Xsand;
+               goto loop;
+       case Xsand_stoneout_1:
+               Next[y][x] = Xsand_stoneout_2;
+               goto loop;
+       case Xsand_stoneout_2:
+               Next[y][x] = Xstone_fall;
+               goto loop;
+       case Xsand_sandstone_1:
+               Next[y][x] = Xsand_sandstone_2;
+               goto loop;
+       case Xsand_sandstone_2:
+               Next[y][x] = Xsand_sandstone_3;
+               goto loop;
+       case Xsand_sandstone_3:
+               Next[y][x] = Xsand_sandstone_4;
+               goto loop;
+       case Xsand_sandstone_4:
+               Next[y][x] = Xsand_stone;
+               goto loop;
+/* ---------------------------------------------------------------------- */
+       case Xdripper:
+               if(lev.lenses_cnt) Cave[y][x] = XdripperB;
+               goto loop;
+/* ---------------------------------------------------------------------- */
+       case Xfake_blank:
+               if(lev.lenses_cnt) Cave[y][x] = Xfake_blankB;
+               goto loop;
+/* ---------------------------------------------------------------------- */
+       case Xfake_grass:
+               if(lev.magnify_cnt) Cave[y][x] = Xfake_grassB;
+               goto loop;
+/* ---------------------------------------------------------------------- */
+       case Xfake_door_1:
+               if(lev.magnify_cnt) Cave[y][x] = Xdoor_1;
+               goto loop;
+       case Xfake_door_2:
+               if(lev.magnify_cnt) Cave[y][x] = Xdoor_2;
+               goto loop;
+       case Xfake_door_3:
+               if(lev.magnify_cnt) Cave[y][x] = Xdoor_3;
+               goto loop;
+       case Xfake_door_4:
+               if(lev.magnify_cnt) Cave[y][x] = Xdoor_4;
+               goto loop;
+       case Xfake_door_5:
+               if(lev.magnify_cnt) Cave[y][x] = Xdoor_5;
+               goto loop;
+       case Xfake_door_6:
+               if(lev.magnify_cnt) Cave[y][x] = Xdoor_6;
+               goto loop;
+       case Xfake_door_7:
+               if(lev.magnify_cnt) Cave[y][x] = Xdoor_7;
+               goto loop;
+       case Xfake_door_8:
+               if(lev.magnify_cnt) Cave[y][x] = Xdoor_8;
+               goto loop;
+/* ---------------------------------------------------------------------- */
+       case Xboom_bug:
+       bug_boom:
+               Next[y][x] = Znormal;
+               Boom[y-1][x-1] = Xemerald;
+               Boom[y-1][x] = Xemerald;
+               Boom[y-1][x+1] = Xemerald;
+               Boom[y][x-1] = Xemerald;
+               Boom[y][x] = Xdiamond;
+               Boom[y][x+1] = Xemerald;
+               Boom[y+1][x-1] = Xemerald;
+               Boom[y+1][x] = Xemerald;
+               Boom[y+1][x+1] = Xemerald;
+               goto loop;
+       case Xboom_bomb:
+       tank_boom:
+               Next[y][x] = Znormal;
+               Boom[y-1][x-1] = Xblank;
+               Boom[y-1][x] = Xblank;
+               Boom[y-1][x+1] = Xblank;
+               Boom[y][x-1] = Xblank;
+               Boom[y][x] = Xblank;
+               Boom[y][x+1] = Xblank;
+               Boom[y+1][x-1] = Xblank;
+               Boom[y+1][x] = Xblank;
+               Boom[y+1][x+1] = Xblank;
+               goto loop;
+       case Xboom_android:
+       case Xboom_1:
+               Next[y][x] = Xboom_2;
+               play[SAMPLE_boom] = 1;
+               goto loop;
+       case Xboom_2:
+               Next[y][x] = Boom[y][x];
+               goto loop;
+/* ---------------------------------------------------------------------- */
+       case ZBORDER:
+               if(++y < HEIGHT - 1) {
+                       x = 0;
+                       cave_cache = Cave[y];
+                       goto loop;
+               }
+               goto done;
+       }
+
+#undef RANDOM
+#undef PLAY
+#undef PLAY_FORCE
+
+done:
+       if(ply1.alive || ply2.alive) lev.score += score; /* only get a score if someone is alive */
+       Random = random;
+       {
+               void *temp = Cave; Cave = Next; Next = Draw; Draw = temp; /* triple buffering */
+       }
+}
diff --git a/src/libem/synchro_3.c b/src/libem/synchro_3.c
new file mode 100644 (file)
index 0000000..1d85e6b
--- /dev/null
@@ -0,0 +1,88 @@
+
+/* third part of synchro.
+ *
+ * handle global elements.
+ *
+ * this should be spread over the frames for reduced cpu load.
+ */
+
+#include "tile.h"
+#include "level.h"
+#include "sample.h"
+
+void synchro_3(void)
+{
+       register unsigned int x;
+       register unsigned int y;
+       register unsigned int count;
+       register unsigned long random;
+
+/* update variables */
+       if(lev.score > 9999) lev.score = 9999;
+
+       if(lev.time) lev.time--;
+       if(lev.android_move_cnt-- == 0) lev.android_move_cnt = lev.android_move_time;
+       if(lev.android_clone_cnt-- == 0) lev.android_clone_cnt = lev.android_clone_time;
+       if(lev.ball_state) if(lev.ball_cnt-- == 0) lev.ball_cnt = lev.ball_time;
+       if(lev.lenses_cnt) lev.lenses_cnt--;
+       if(lev.magnify_cnt) lev.magnify_cnt--;
+       if(lev.wheel_cnt) lev.wheel_cnt--;
+       if(lev.wind_cnt) lev.wind_cnt--;
+       if(lev.wonderwall_time && lev.wonderwall_state) lev.wonderwall_time--;
+
+       if(lev.time > 0 && lev.time <= 50 && lev.time % 5 == 0) play[SAMPLE_time] = 1;
+       if(lev.wheel_cnt) play[SAMPLE_wheel] = 1;
+
+/* grow ameuba */
+       random = Random;
+       for(count = lev.ameuba_time; count--;) {
+               x = (random >> 10) % (WIDTH - 2);
+               y = (random >> 20) % (HEIGHT - 2);
+               switch(Cave[y][x]) {
+               case Xblank:
+               case Yacid_splash_eB:
+               case Yacid_splash_wB:
+               case Xgrass:
+               case Xdirt:
+               case Xsand:
+               case Xplant:
+               case Yplant:
+                       if(tab_ameuba[Cave[y-1][x]] || tab_ameuba[Cave[y][x+1]] || tab_ameuba[Cave[y+1][x]] || tab_ameuba[Cave[y][x-1]]) Cave[y][x] = Xdrip_eat;
+               }
+               random = random * 129 + 1;
+       }
+       Random = random;
+
+/* handle explosions */
+       for(y = 1; y < HEIGHT - 1; y++) for(x = 1; x < WIDTH - 1; x++) {
+               switch(Cave[y][x]) {
+               case Znormal:
+                       Cave[y][x] = Xboom_1;
+                       Cave[y-1][x] = tab_explode_normal[Cave[y-1][x]];
+                       Cave[y][x-1] = tab_explode_normal[Cave[y][x-1]];
+                       Cave[y][x+1] = tab_explode_normal[Cave[y][x+1]];
+                       Cave[y+1][x] = tab_explode_normal[Cave[y+1][x]];
+                       Cave[y-1][x-1] = tab_explode_normal[Cave[y-1][x-1]];
+                       Cave[y-1][x+1] = tab_explode_normal[Cave[y-1][x+1]];
+                       Cave[y+1][x-1] = tab_explode_normal[Cave[y+1][x-1]];
+                       Cave[y+1][x+1] = tab_explode_normal[Cave[y+1][x+1]];
+                       break;
+               case Zdynamite:
+                       Cave[y][x] = Xboom_1;
+                       Cave[y-1][x] = tab_explode_dynamite[Cave[y-1][x]];
+                       Cave[y][x-1] = tab_explode_dynamite[Cave[y][x-1]];
+                       Cave[y][x+1] = tab_explode_dynamite[Cave[y][x+1]];
+                       Cave[y+1][x] = tab_explode_dynamite[Cave[y+1][x]];
+                       Cave[y-1][x-1] = tab_explode_dynamite[Cave[y-1][x-1]];
+                       Cave[y-1][x+1] = tab_explode_dynamite[Cave[y-1][x+1]];
+                       Cave[y+1][x-1] = tab_explode_dynamite[Cave[y+1][x-1]];
+                       Cave[y+1][x+1] = tab_explode_dynamite[Cave[y+1][x+1]];
+                       break;
+               }
+       }
+
+/* triple buffering */
+       for(y = 0; y < HEIGHT; y++) for(x = 0; x < WIDTH; x++) {
+               Next[y][x] = Cave[y][x];
+       }
+}
diff --git a/src/libem/tab_generate.c b/src/libem/tab_generate.c
new file mode 100644 (file)
index 0000000..d11cc77
--- /dev/null
@@ -0,0 +1,4680 @@
+/* 2000-04-19T13:26:05Z
+ *
+ * construct some tables to be included directly in emerald mine source.
+ * i made this because dynamically building the tables every time sucks and i
+ * need to be able to easily modify tile.h.
+ *
+ * this is key data which almost everything depends on.
+ *
+ * this is supposed to be fairly easy to read and modify. the tab values
+ * are still hard coded constants but that should be less of a problem to
+ * modify.
+ */
+
+#include <stdio.h>
+#include "tile.h"
+
+/* ---------------------------------------------------------------------- */
+
+/* 0=stop 1=blank */
+int tile_blank[] = {
+       Xblank, 1,
+       Yacid_splash_eB, 1,
+       Yacid_splash_wB, 1,
+       TILE_MAX
+};
+/* 0=stop 1=acid */
+int tile_acid[] = {
+       Xblank, 1,
+       Yacid_splash_eB, 1,
+       Yacid_splash_wB, 1,
+       Xacid_1, 1,
+       Xacid_2, 1,
+       Xacid_3, 1,
+       Xacid_4, 1,
+       Xacid_5, 1,
+       Xacid_6, 1,
+       Xacid_7, 1,
+       Xacid_8, 1,
+       TILE_MAX
+};
+/* 0=stop 1=ameuba */
+int tile_ameuba[] = {
+       Xdripper, 1,
+       XdripperB, 1,
+       Xameuba_1, 1,
+       Xameuba_2, 1,
+       Xameuba_3, 1,
+       Xameuba_4, 1,
+       Xameuba_5, 1,
+       Xameuba_6, 1,
+       Xameuba_7, 1,
+       Xameuba_8, 1,
+       TILE_MAX
+};
+/* 0=stop 1=move */
+int tile_android_move[] = {
+       Xblank, 1,
+       Yacid_splash_eB, 1,
+       Yacid_splash_wB, 1,
+       Xplant, 1,
+       TILE_MAX
+};
+
+/* ---------------------------------------------------------------------- */
+
+/* explosions: special format */
+/* everything is initially filled with Xboom_1 */
+int tile_explode[] = {
+       ZBORDER,
+       Znormal,
+       Zdynamite,
+       Xboom_bug,
+       Xboom_bomb,
+       Xboom_android,
+       Xandroid,
+       Xandroid_1_n,
+       Xandroid_2_n,
+       Xandroid_1_e,
+       Xandroid_2_e,
+       Xandroid_1_s,
+       Xandroid_2_s,
+       Xandroid_1_w,
+       Xandroid_2_w,
+       Xacid_ne,
+       Xacid_nw,
+       Xacid_s,
+       Xacid_se,
+       Xacid_sw,
+       Xacid_1,
+       Xacid_2,
+       Xacid_3,
+       Xacid_4,
+       Xacid_5,
+       Xacid_6,
+       Xacid_7,
+       Xacid_8,
+       Xdoor_1,
+       Xdoor_2,
+       Xdoor_3,
+       Xdoor_4,
+       Xdoor_5,
+       Xdoor_6,
+       Xdoor_7,
+       Xdoor_8,
+       Xplant,
+       Yplant,
+       Xfake_door_1,
+       Xfake_door_2,
+       Xfake_door_3,
+       Xfake_door_4,
+       Xfake_door_5,
+       Xfake_door_6,
+       Xfake_door_7,
+       Xfake_door_8,
+       Xsteel_1,
+       Xsteel_2,
+       Xsteel_3,
+       Xsteel_4,
+       TILE_MAX, /* up till here are indestructable */
+       Xbug_n, Xboom_bug,
+       Xbug_e, Xboom_bug,
+       Xbug_s, Xboom_bug,
+       Xbug_w, Xboom_bug,
+       Xbug_gon, Xboom_bug,
+       Xbug_goe, Xboom_bug,
+       Xbug_gos, Xboom_bug,
+       Xbug_gow, Xboom_bug,
+       Xbomb, Xboom_bomb,
+       Xbomb_pause, Xboom_bomb,
+       Xbomb_fall, Xboom_bomb,
+       TILE_MAX, /* up till here are special explosions */
+       Xandroid, Xboom_android,
+       Xandroid_1_n, Xboom_android,
+       Xandroid_2_n, Xboom_android,
+       Xandroid_1_e, Xboom_android,
+       Xandroid_2_e, Xboom_android,
+       Xandroid_1_s, Xboom_android,
+       Xandroid_2_s, Xboom_android,
+       Xandroid_1_w, Xboom_android,
+       Xandroid_2_w, Xboom_android,
+       TILE_MAX /* up until here are dynamite explosions */
+};
+
+/* ---------------------------------------------------------------------- */
+
+/* map the graphics file to internal tiles and animations
+ *
+ * one graphics icon maps to many tiles and animations
+ */
+
+int obj_map[] = {
+
+/* special */
+
+Ystone_sB,7 ,
+Xsand_stonein_4,7 ,
+-1,
+Xsand_stonein_4,5 ,
+Xsand_stonein_4,6 ,
+-1,
+Ystone_sB,6 ,
+Xsand_stonein_4,3 ,
+Xsand_stonein_4,4 ,
+-1,
+Xsand_stonein_4,1 ,
+Xsand_stonein_4,2 ,
+-1,
+Ystone_sB,5 ,
+Xsand_stonein_3,7 ,
+Xsand_stonein_4,0 ,
+-1,
+Xsand_stonein_3,5 ,
+Xsand_stonein_3,6 ,
+-1,
+Ystone_sB,4 ,
+Xsand_stonein_3,3 ,
+Xsand_stonein_3,4 ,
+-1,
+Xsand_stonein_3,1 ,
+Xsand_stonein_3,2 ,
+-1,
+Ystone_sB,3 ,
+Xsand_stonein_2,7 ,
+Xsand_stonein_3,0 ,
+-1,
+Xsand_stonein_2,5 ,
+Xsand_stonein_2,6 ,
+-1,
+Ystone_sB,2 ,
+Xsand_stonein_2,3 ,
+Xsand_stonein_2,4 ,
+-1,
+Xsand_stonein_2,1 ,
+Xsand_stonein_2,2 ,
+-1,
+Ystone_sB,1 ,
+Xsand_stonein_1,7 ,
+Xsand_stonein_2,0 ,
+-1,
+Xsand_stonein_1,5 ,
+Xsand_stonein_1,6 ,
+-1,
+Ystone_sB,0 ,
+Xsand_stonein_1,3 ,
+Xsand_stonein_1,4 ,
+-1,
+Xsand_stonein_1,1 ,
+Xsand_stonein_1,2 ,
+-1,
+Xstone,0 ,
+Xstone,1 ,
+Xstone,2 ,
+Xstone,3 ,
+Xstone,4 ,
+Xstone,5 ,
+Xstone,6 ,
+Xstone,7 ,
+Xstone_pause,0 ,
+Xstone_pause,1 ,
+Xstone_pause,2 ,
+Xstone_pause,3 ,
+Xstone_pause,4 ,
+Xstone_pause,5 ,
+Xstone_pause,6 ,
+Xstone_pause,7 ,
+Xstone_fall,0 ,
+Xstone_fall,1 ,
+Xstone_fall,2 ,
+Xstone_fall,3 ,
+Xstone_fall,4 ,
+Xstone_fall,5 ,
+Xstone_fall,6 ,
+Xstone_fall,7 ,
+#ifdef BAD_ROLL
+Xstone_force_e,0 ,
+Xstone_force_e,1 ,
+Xstone_force_e,2 ,
+Xstone_force_e,3 ,
+Xstone_force_e,4 ,
+Xstone_force_e,5 ,
+Xstone_force_e,6 ,
+Xstone_force_e,7 ,
+Xstone_force_w,0 ,
+Xstone_force_w,1 ,
+Xstone_force_w,2 ,
+Xstone_force_w,3 ,
+Xstone_force_w,4 ,
+Xstone_force_w,5 ,
+Xstone_force_w,6 ,
+Xstone_force_w,7 ,
+#endif
+Ystone_s,7 ,
+Xsand_stoneout_2,7 ,
+Xsand_stonein_1,0 ,
+Ystone_e,7 ,
+Ystone_w,7 ,
+Ydiamond_stone,7 ,
+-1,
+-1,
+Ystone_s,6 ,
+Xsand_stoneout_2,6 ,
+-1,
+-1,
+Ystone_s,5 ,
+Xsand_stoneout_2,5 ,
+-1,
+-1,
+Ystone_s,4 ,
+Xsand_stoneout_2,4 ,
+-1,
+Xsand_stoneout_2,3 ,
+-1,
+Ystone_s,3 ,
+Xsand_stoneout_2,2 ,
+-1,
+Xsand_stoneout_2,1 ,
+-1,
+Ystone_s,2 ,
+Xsand_stoneout_2,0 ,
+-1,
+Xsand_stoneout_1,7 ,
+Xsand_stoneout_1,6 ,
+-1,
+Ystone_s,1 ,
+Xsand_stoneout_1,5 ,
+-1,
+Xsand_stoneout_1,4 ,
+Xsand_stoneout_1,3 ,
+-1,
+Ystone_s,0 ,
+Xsand_stoneout_1,2 ,
+-1,
+Xsand_stoneout_1,1 ,
+Xsand_stoneout_1,0 ,
+-1,
+Ynut_sB,7 ,
+-1,
+-1,
+Ynut_sB,6 ,
+-1,
+-1,
+Ynut_sB,5 ,
+-1,
+-1,
+Ynut_sB,4 ,
+-1,
+-1,
+Ynut_sB,3 ,
+-1,
+-1,
+Ynut_sB,2 ,
+-1,
+-1,
+Ynut_sB,1 ,
+-1,
+-1,
+Ynut_sB,0 ,
+-1,
+-1,
+Ynut_s,7 ,
+Ynut_e,7 ,
+Ynut_w,7 ,
+Xnut,0 ,
+Xnut,1 ,
+Xnut,2 ,
+Xnut,3 ,
+Xnut,4 ,
+Xnut,5 ,
+Xnut,6 ,
+Xnut,7 ,
+Xnut_pause,0 ,
+Xnut_pause,1 ,
+Xnut_pause,2 ,
+Xnut_pause,3 ,
+Xnut_pause,4 ,
+Xnut_pause,5 ,
+Xnut_pause,6 ,
+Xnut_pause,7 ,
+Xnut_fall,0 ,
+Xnut_fall,1 ,
+Xnut_fall,2 ,
+Xnut_fall,3 ,
+Xnut_fall,4 ,
+Xnut_fall,5 ,
+Xnut_fall,6 ,
+Xnut_fall,7 ,
+#ifdef BAD_ROLL
+Xnut_force_e,0 ,
+Xnut_force_e,1 ,
+Xnut_force_e,2 ,
+Xnut_force_e,3 ,
+Xnut_force_e,4 ,
+Xnut_force_e,5 ,
+Xnut_force_e,6 ,
+Xnut_force_e,7 ,
+Xnut_force_w,0 ,
+Xnut_force_w,1 ,
+Xnut_force_w,2 ,
+Xnut_force_w,3 ,
+Xnut_force_w,4 ,
+Xnut_force_w,5 ,
+Xnut_force_w,6 ,
+Xnut_force_w,7 ,
+#endif
+-1,
+-1,
+Ynut_s,6 ,
+-1,
+-1,
+Ynut_s,5 ,
+-1,
+-1,
+Ynut_s,4 ,
+-1,
+-1,
+Ynut_s,3 ,
+-1,
+-1,
+Ynut_s,2 ,
+-1,
+-1,
+Ynut_s,1 ,
+-1,
+-1,
+Ynut_s,0 ,
+-1,
+-1,
+
+/* normal */
+
+Xblank,0 ,
+Xblank,1 ,
+Xblank,2 ,
+Xblank,3 ,
+Xblank,4 ,
+Xblank,5 ,
+Xblank,6 ,
+Xblank,7 ,
+Xfake_blank,0 ,
+Xfake_blank,1 ,
+Xfake_blank,2 ,
+Xfake_blank,3 ,
+Xfake_blank,4 ,
+Xfake_blank,5 ,
+Xfake_blank,6 ,
+Xfake_blank,7 ,
+Xdripper,0 ,
+Xdripper,1 ,
+Xdripper,2 ,
+Xdripper,3 ,
+Xdripper,4 ,
+Xdripper,5 ,
+Xdripper,6 ,
+Xdripper,7 ,
+Zplayer,0 ,
+Zplayer,1 ,
+Zplayer,2 ,
+Zplayer,3 ,
+Zplayer,4 ,
+Zplayer,5 ,
+Zplayer,6 ,
+Zplayer,7 ,
+Ydynamite_eat,3 ,
+Ydynamite_eat,4 ,
+Ydynamite_eat,5 ,
+Ydynamite_eat,6 ,
+Ydynamite_eat,7 ,
+-1,
+-1,
+-1,
+-1,
+-1,
+
+Ystone_eB,6 ,
+Ystone_w,0 ,
+-1,
+Ystone_e,6 ,
+Ystone_wB,0 ,
+-1,
+Ystone_eB,5 ,
+Ystone_w,1 ,
+-1,
+Ystone_e,5 ,
+Ystone_wB,1 ,
+-1,
+Ystone_eB,4 ,
+Ystone_w,2 ,
+-1,
+Ystone_e,4 ,
+Ystone_wB,2 ,
+-1,
+Ystone_eB,3 ,
+Ystone_w,3 ,
+-1,
+Ystone_e,3 ,
+Ystone_wB,3 ,
+-1,
+Ystone_eB,2 ,
+Ystone_w,4 ,
+-1,
+Ystone_e,2 ,
+Ystone_wB,4 ,
+-1,
+Ystone_eB,1 ,
+Ystone_w,5 ,
+-1,
+Ystone_e,1 ,
+Ystone_wB,5 ,
+-1,
+Ystone_eB,0 ,
+Ystone_w,6 ,
+-1,
+Ystone_e,0 ,
+Ystone_wB,6 ,
+-1,
+
+Ynut_eB,6 ,
+Ynut_w,0 ,
+-1,
+Ynut_e,6 ,
+Ynut_wB,0 ,
+-1,
+Ynut_eB,5 ,
+Ynut_w,1 ,
+-1,
+Ynut_e,5 ,
+Ynut_wB,1 ,
+-1,
+Ynut_eB,4 ,
+Ynut_w,2 ,
+-1,
+Ynut_e,4 ,
+Ynut_wB,2 ,
+-1,
+Ynut_eB,3 ,
+Ynut_w,3 ,
+-1,
+Ynut_e,3 ,
+Ynut_wB,3 ,
+-1,
+Ynut_eB,2 ,
+Ynut_w,4 ,
+-1,
+Ynut_e,2 ,
+Ynut_wB,4 ,
+-1,
+Ynut_eB,1 ,
+Ynut_w,5 ,
+-1,
+Ynut_e,1 ,
+Ynut_wB,5 ,
+-1,
+Ynut_eB,0 ,
+Ynut_w,6 ,
+-1,
+Ynut_e,0 ,
+Ynut_wB,6 ,
+-1,
+
+Ybug_w_n,7 ,
+Ybug_e_n,7 ,
+Ybug_n,7 ,
+Xbug_n,0 ,
+Xbug_n,1 ,
+Xbug_n,2 ,
+Xbug_n,3 ,
+Xbug_n,4 ,
+Xbug_n,5 ,
+Xbug_n,6 ,
+Xbug_n,7 ,
+Xbug_gon,0 ,
+Xbug_gon,1 ,
+Xbug_gon,2 ,
+Xbug_gon,3 ,
+Xbug_gon,4 ,
+Xbug_gon,5 ,
+Xbug_gon,6 ,
+Xbug_gon,7 ,
+-1,
+Ybug_n_e,7 ,
+Ybug_s_e,7 ,
+Ybug_e,7 ,
+Xbug_e,0 ,
+Xbug_e,1 ,
+Xbug_e,2 ,
+Xbug_e,3 ,
+Xbug_e,4 ,
+Xbug_e,5 ,
+Xbug_e,6 ,
+Xbug_e,7 ,
+Xbug_goe,0 ,
+Xbug_goe,1 ,
+Xbug_goe,2 ,
+Xbug_goe,3 ,
+Xbug_goe,4 ,
+Xbug_goe,5 ,
+Xbug_goe,6 ,
+Xbug_goe,7 ,
+-1,
+Ybug_e_s,7 ,
+Ybug_w_s,7 ,
+Ybug_s,7 ,
+Xbug_s,0 ,
+Xbug_s,1 ,
+Xbug_s,2 ,
+Xbug_s,3 ,
+Xbug_s,4 ,
+Xbug_s,5 ,
+Xbug_s,6 ,
+Xbug_s,7 ,
+Xbug_gos,0 ,
+Xbug_gos,1 ,
+Xbug_gos,2 ,
+Xbug_gos,3 ,
+Xbug_gos,4 ,
+Xbug_gos,5 ,
+Xbug_gos,6 ,
+Xbug_gos,7 ,
+-1,
+Ybug_n_w,7 ,
+Ybug_s_w,7 ,
+Ybug_w,7 ,
+Xbug_w,0 ,
+Xbug_w,1 ,
+Xbug_w,2 ,
+Xbug_w,3 ,
+Xbug_w,4 ,
+Xbug_w,5 ,
+Xbug_w,6 ,
+Xbug_w,7 ,
+Xbug_gow,0 ,
+Xbug_gow,1 ,
+Xbug_gow,2 ,
+Xbug_gow,3 ,
+Xbug_gow,4 ,
+Xbug_gow,5 ,
+Xbug_gow,6 ,
+Xbug_gow,7 ,
+-1,
+Ybug_n,0 ,
+-1,
+Ybug_nB,0 ,
+-1,
+Ybug_n,1 ,
+-1,
+Ybug_nB,1 ,
+-1,
+Ybug_n,2 ,
+-1,
+Ybug_nB,2 ,
+-1,
+Ybug_n,3 ,
+-1,
+Ybug_nB,3 ,
+-1,
+Ybug_n,4 ,
+-1,
+Ybug_nB,4 ,
+-1,
+Ybug_n,5 ,
+-1,
+Ybug_nB,5 ,
+-1,
+Ybug_n,6 ,
+-1,
+Ybug_nB,6 ,
+-1,
+Ybug_eB,6 ,
+-1,
+Ybug_e,6 ,
+-1,
+Ybug_eB,5 ,
+-1,
+Ybug_e,5 ,
+-1,
+Ybug_eB,4 ,
+-1,
+Ybug_e,4 ,
+-1,
+Ybug_eB,3 ,
+-1,
+Ybug_e,3 ,
+-1,
+Ybug_eB,2 ,
+-1,
+Ybug_e,2 ,
+-1,
+Ybug_eB,1 ,
+-1,
+Ybug_e,1 ,
+-1,
+Ybug_eB,0 ,
+-1,
+Ybug_e,0 ,
+-1,
+Ybug_sB,6 ,
+-1,
+Ybug_s,6 ,
+-1,
+Ybug_sB,5 ,
+-1,
+Ybug_s,5 ,
+-1,
+Ybug_sB,4 ,
+-1,
+Ybug_s,4 ,
+-1,
+Ybug_sB,3 ,
+-1,
+Ybug_s,3 ,
+-1,
+Ybug_sB,2 ,
+-1,
+Ybug_s,2 ,
+-1,
+Ybug_sB,1 ,
+-1,
+Ybug_s,1 ,
+-1,
+Ybug_sB,0 ,
+-1,
+Ybug_s,0 ,
+-1,
+Ybug_w,0 ,
+-1,
+Ybug_wB,0 ,
+-1,
+Ybug_w,1 ,
+-1,
+Ybug_wB,1 ,
+-1,
+Ybug_w,2 ,
+-1,
+Ybug_wB,2 ,
+-1,
+Ybug_w,3 ,
+-1,
+Ybug_wB,3 ,
+-1,
+Ybug_w,4 ,
+-1,
+Ybug_wB,4 ,
+-1,
+Ybug_w,5 ,
+-1,
+Ybug_wB,5 ,
+-1,
+Ybug_w,6 ,
+-1,
+Ybug_wB,6 ,
+-1,
+Ybug_n_e,0 ,
+Ybug_e_n,6 ,
+-1,
+Ybug_n_e,1 ,
+Ybug_e_n,5 ,
+-1,
+Ybug_n_e,2 ,
+Ybug_e_n,4 ,
+-1,
+Ybug_n_e,3 ,
+Ybug_e_n,3 ,
+-1,
+Ybug_n_e,4 ,
+Ybug_e_n,2 ,
+-1,
+Ybug_n_e,5 ,
+Ybug_e_n,1 ,
+-1,
+Ybug_n_e,6 ,
+Ybug_e_n,0 ,
+-1,
+Ybug_e_s,0 ,
+Ybug_s_e,6 ,
+-1,
+Ybug_e_s,1 ,
+Ybug_s_e,5 ,
+-1,
+Ybug_e_s,2 ,
+Ybug_s_e,4 ,
+-1,
+Ybug_e_s,3 ,
+Ybug_s_e,3 ,
+-1,
+Ybug_e_s,4 ,
+Ybug_s_e,2 ,
+-1,
+Ybug_e_s,5 ,
+Ybug_s_e,1 ,
+-1,
+Ybug_e_s,6 ,
+Ybug_s_e,0 ,
+-1,
+Ybug_s_w,0 ,
+Ybug_w_s,6 ,
+-1,
+Ybug_s_w,1 ,
+Ybug_w_s,5 ,
+-1,
+Ybug_s_w,2 ,
+Ybug_w_s,4 ,
+-1,
+Ybug_s_w,3 ,
+Ybug_w_s,3 ,
+-1,
+Ybug_s_w,4 ,
+Ybug_w_s,2 ,
+-1,
+Ybug_s_w,5 ,
+Ybug_w_s,1 ,
+-1,
+Ybug_s_w,6 ,
+Ybug_w_s,0 ,
+-1,
+Ybug_n_w,6 ,
+Ybug_w_n,0 ,
+-1,
+Ybug_n_w,5 ,
+Ybug_w_n,1 ,
+-1,
+Ybug_n_w,4 ,
+Ybug_w_n,2 ,
+-1,
+Ybug_n_w,3 ,
+Ybug_w_n,3 ,
+-1,
+Ybug_n_w,2 ,
+Ybug_w_n,4 ,
+-1,
+Ybug_n_w,1 ,
+Ybug_w_n,5 ,
+-1,
+Ybug_n_w,0 ,
+Ybug_w_n,6 ,
+-1,
+Ybug_stone,0 ,
+-1,
+Ybug_stone,1 ,
+-1,
+Ybug_stone,2 ,
+-1,
+Ybug_stone,3 ,
+-1,
+Ybug_stone,4 ,
+-1,
+Ybug_stone,5 ,
+-1,
+Ybug_stone,6 ,
+-1,
+Ybug_spring,0 ,
+-1,
+Ybug_spring,1 ,
+-1,
+Ybug_spring,2 ,
+-1,
+Ybug_spring,3 ,
+-1,
+Ybug_spring,4 ,
+-1,
+Ybug_spring,5 ,
+-1,
+Ybug_spring,6 ,
+-1,
+
+Ytank_w_n,7 ,
+Ytank_e_n,7 ,
+Ytank_n,7 ,
+Xtank_n,0 ,
+Xtank_n,1 ,
+Xtank_n,2 ,
+Xtank_n,3 ,
+Xtank_n,4 ,
+Xtank_n,5 ,
+Xtank_n,6 ,
+Xtank_n,7 ,
+Xtank_gon,0 ,
+Xtank_gon,1 ,
+Xtank_gon,2 ,
+Xtank_gon,3 ,
+Xtank_gon,4 ,
+Xtank_gon,5 ,
+Xtank_gon,6 ,
+Xtank_gon,7 ,
+-1,
+Ytank_n_e,7 ,
+Ytank_s_e,7 ,
+Ytank_e,7 ,
+Xtank_e,0 ,
+Xtank_e,1 ,
+Xtank_e,2 ,
+Xtank_e,3 ,
+Xtank_e,4 ,
+Xtank_e,5 ,
+Xtank_e,6 ,
+Xtank_e,7 ,
+Xtank_goe,0 ,
+Xtank_goe,1 ,
+Xtank_goe,2 ,
+Xtank_goe,3 ,
+Xtank_goe,4 ,
+Xtank_goe,5 ,
+Xtank_goe,6 ,
+Xtank_goe,7 ,
+-1,
+Ytank_e_s,7 ,
+Ytank_w_s,7 ,
+Ytank_s,7 ,
+Xtank_s,0 ,
+Xtank_s,1 ,
+Xtank_s,2 ,
+Xtank_s,3 ,
+Xtank_s,4 ,
+Xtank_s,5 ,
+Xtank_s,6 ,
+Xtank_s,7 ,
+Xtank_gos,0 ,
+Xtank_gos,1 ,
+Xtank_gos,2 ,
+Xtank_gos,3 ,
+Xtank_gos,4 ,
+Xtank_gos,5 ,
+Xtank_gos,6 ,
+Xtank_gos,7 ,
+-1,
+Ytank_n_w,7 ,
+Ytank_s_w,7 ,
+Ytank_w,7 ,
+Xtank_w,0 ,
+Xtank_w,1 ,
+Xtank_w,2 ,
+Xtank_w,3 ,
+Xtank_w,4 ,
+Xtank_w,5 ,
+Xtank_w,6 ,
+Xtank_w,7 ,
+Xtank_gow,0 ,
+Xtank_gow,1 ,
+Xtank_gow,2 ,
+Xtank_gow,3 ,
+Xtank_gow,4 ,
+Xtank_gow,5 ,
+Xtank_gow,6 ,
+Xtank_gow,7 ,
+-1,
+Ytank_n,0 ,
+-1,
+Ytank_nB,0 ,
+-1,
+Ytank_n,1 ,
+-1,
+Ytank_nB,1 ,
+-1,
+Ytank_n,2 ,
+-1,
+Ytank_nB,2 ,
+-1,
+Ytank_n,3 ,
+-1,
+Ytank_nB,3 ,
+-1,
+Ytank_n,4 ,
+-1,
+Ytank_nB,4 ,
+-1,
+Ytank_n,5 ,
+-1,
+Ytank_nB,5 ,
+-1,
+Ytank_n,6 ,
+-1,
+Ytank_nB,6 ,
+-1,
+Ytank_eB,6 ,
+-1,
+Ytank_e,6 ,
+-1,
+Ytank_eB,5 ,
+-1,
+Ytank_e,5 ,
+-1,
+Ytank_eB,4 ,
+-1,
+Ytank_e,4 ,
+-1,
+Ytank_eB,3 ,
+-1,
+Ytank_e,3 ,
+-1,
+Ytank_eB,2 ,
+-1,
+Ytank_e,2 ,
+-1,
+Ytank_eB,1 ,
+-1,
+Ytank_e,1 ,
+-1,
+Ytank_eB,0 ,
+-1,
+Ytank_e,0 ,
+-1,
+Ytank_sB,6 ,
+-1,
+Ytank_s,6 ,
+-1,
+Ytank_sB,5 ,
+-1,
+Ytank_s,5 ,
+-1,
+Ytank_sB,4 ,
+-1,
+Ytank_s,4 ,
+-1,
+Ytank_sB,3 ,
+-1,
+Ytank_s,3 ,
+-1,
+Ytank_sB,2 ,
+-1,
+Ytank_s,2 ,
+-1,
+Ytank_sB,1 ,
+-1,
+Ytank_s,1 ,
+-1,
+Ytank_sB,0 ,
+-1,
+Ytank_s,0 ,
+-1,
+Ytank_w,0 ,
+-1,
+Ytank_wB,0 ,
+-1,
+Ytank_w,1 ,
+-1,
+Ytank_wB,1 ,
+-1,
+Ytank_w,2 ,
+-1,
+Ytank_wB,2 ,
+-1,
+Ytank_w,3 ,
+-1,
+Ytank_wB,3 ,
+-1,
+Ytank_w,4 ,
+-1,
+Ytank_wB,4 ,
+-1,
+Ytank_w,5 ,
+-1,
+Ytank_wB,5 ,
+-1,
+Ytank_w,6 ,
+-1,
+Ytank_wB,6 ,
+-1,
+Ytank_n_e,0 ,
+Ytank_e_n,6 ,
+-1,
+Ytank_n_e,1 ,
+Ytank_e_n,5 ,
+-1,
+Ytank_n_e,2 ,
+Ytank_e_n,4 ,
+-1,
+Ytank_n_e,3 ,
+Ytank_e_n,3 ,
+-1,
+Ytank_n_e,4 ,
+Ytank_e_n,2 ,
+-1,
+Ytank_n_e,5 ,
+Ytank_e_n,1 ,
+-1,
+Ytank_n_e,6 ,
+Ytank_e_n,0 ,
+-1,
+Ytank_e_s,0 ,
+Ytank_s_e,6 ,
+-1,
+Ytank_e_s,1 ,
+Ytank_s_e,5 ,
+-1,
+Ytank_e_s,2 ,
+Ytank_s_e,4 ,
+-1,
+Ytank_e_s,3 ,
+Ytank_s_e,3 ,
+-1,
+Ytank_e_s,4 ,
+Ytank_s_e,2 ,
+-1,
+Ytank_e_s,5 ,
+Ytank_s_e,1 ,
+-1,
+Ytank_e_s,6 ,
+Ytank_s_e,0 ,
+-1,
+Ytank_s_w,0 ,
+Ytank_w_s,6 ,
+-1,
+Ytank_s_w,1 ,
+Ytank_w_s,5 ,
+-1,
+Ytank_s_w,2 ,
+Ytank_w_s,4 ,
+-1,
+Ytank_s_w,3 ,
+Ytank_w_s,3 ,
+-1,
+Ytank_s_w,4 ,
+Ytank_w_s,2 ,
+-1,
+Ytank_s_w,5 ,
+Ytank_w_s,1 ,
+-1,
+Ytank_s_w,6 ,
+Ytank_w_s,0 ,
+-1,
+Ytank_n_w,6 ,
+Ytank_w_n,0 ,
+-1,
+Ytank_n_w,5 ,
+Ytank_w_n,1 ,
+-1,
+Ytank_n_w,4 ,
+Ytank_w_n,2 ,
+-1,
+Ytank_n_w,3 ,
+Ytank_w_n,3 ,
+-1,
+Ytank_n_w,2 ,
+Ytank_w_n,4 ,
+-1,
+Ytank_n_w,1 ,
+Ytank_w_n,5 ,
+-1,
+Ytank_n_w,0 ,
+Ytank_w_n,6 ,
+-1,
+Ytank_stone,0 ,
+-1,
+Ytank_stone,1 ,
+-1,
+Ytank_stone,2 ,
+-1,
+Ytank_stone,3 ,
+-1,
+Ytank_stone,4 ,
+-1,
+Ytank_stone,5 ,
+-1,
+Ytank_stone,6 ,
+-1,
+Ytank_spring,0 ,
+-1,
+Ytank_spring,1 ,
+-1,
+Ytank_spring,2 ,
+-1,
+Ytank_spring,3 ,
+-1,
+Ytank_spring,4 ,
+-1,
+Ytank_spring,5 ,
+-1,
+Ytank_spring,6 ,
+-1,
+
+Yandroid_n,7 ,
+Yandroid_ne,7 ,
+Yandroid_e,7 ,
+Yandroid_se,7 ,
+Yandroid_s,7 ,
+Yandroid_sw,7 ,
+Yandroid_w,7 ,
+Yandroid_nw,7 ,
+Xandroid,7 ,
+Xandroid_1_n,7 ,
+Xandroid_2_n,7 ,
+Xandroid_1_e,7 ,
+Xandroid_2_e,7 ,
+Xandroid_1_w,7 ,
+Xandroid_2_w,7 ,
+Xandroid_1_s,7 ,
+Xandroid_2_s,7 ,
+-1,
+Xandroid,0 ,
+Xandroid_1_n,0 ,
+Xandroid_2_n,0 ,
+Xandroid_1_e,0 ,
+Xandroid_2_e,0 ,
+Xandroid_1_w,0 ,
+Xandroid_2_w,0 ,
+Xandroid_1_s,0 ,
+Xandroid_2_s,0 ,
+-1,
+Xandroid,1 ,
+Xandroid_1_n,1 ,
+Xandroid_2_n,1 ,
+Xandroid_1_e,1 ,
+Xandroid_2_e,1 ,
+Xandroid_1_w,1 ,
+Xandroid_2_w,1 ,
+Xandroid_1_s,1 ,
+Xandroid_2_s,1 ,
+-1,
+Xandroid,2 ,
+Xandroid_1_n,2 ,
+Xandroid_2_n,2 ,
+Xandroid_1_e,2 ,
+Xandroid_2_e,2 ,
+Xandroid_1_w,2 ,
+Xandroid_2_w,2 ,
+Xandroid_1_s,2 ,
+Xandroid_2_s,2 ,
+-1,
+Xandroid,3 ,
+Xandroid_1_n,3 ,
+Xandroid_2_n,3 ,
+Xandroid_1_e,3 ,
+Xandroid_2_e,3 ,
+Xandroid_1_w,3 ,
+Xandroid_2_w,3 ,
+Xandroid_1_s,3 ,
+Xandroid_2_s,3 ,
+-1,
+Xandroid,4 ,
+Xandroid_1_n,4 ,
+Xandroid_2_n,4 ,
+Xandroid_1_e,4 ,
+Xandroid_2_e,4 ,
+Xandroid_1_w,4 ,
+Xandroid_2_w,4 ,
+Xandroid_1_s,4 ,
+Xandroid_2_s,4 ,
+-1,
+Xandroid,5 ,
+Xandroid_1_n,5 ,
+Xandroid_2_n,5 ,
+Xandroid_1_e,5 ,
+Xandroid_2_e,5 ,
+Xandroid_1_w,5 ,
+Xandroid_2_w,5 ,
+Xandroid_1_s,5 ,
+Xandroid_2_s,5 ,
+-1,
+Xandroid,6 ,
+Xandroid_1_n,6 ,
+Xandroid_2_n,6 ,
+Xandroid_1_e,6 ,
+Xandroid_2_e,6 ,
+Xandroid_1_w,6 ,
+Xandroid_2_w,6 ,
+Xandroid_1_s,6 ,
+Xandroid_2_s,6 ,
+-1,
+Yandroid_n,0 ,
+Yandroid_sB,6 ,
+-1,
+Yandroid_nB,0 ,
+Yandroid_s,6 ,
+-1,
+Yandroid_n,1 ,
+Yandroid_sB,5 ,
+-1,
+Yandroid_nB,1 ,
+Yandroid_s,5 ,
+-1,
+Yandroid_n,2 ,
+Yandroid_sB,4 ,
+Xboom_android,0 ,
+-1,
+Yandroid_nB,2 ,
+Yandroid_s,4 ,
+Xboom_android,1 ,
+-1,
+Yandroid_n,3 ,
+Yandroid_sB,3 ,
+Xboom_android,2 ,
+-1,
+Yandroid_nB,3 ,
+Yandroid_s,3 ,
+Xboom_android,3 ,
+-1,
+Yandroid_n,4 ,
+Yandroid_sB,2 ,
+Xboom_android,4 ,
+-1,
+Yandroid_nB,4 ,
+Yandroid_s,2 ,
+Xboom_android,5 ,
+-1,
+Yandroid_n,5 ,
+Yandroid_sB,1 ,
+Xboom_android,6 ,
+-1,
+Yandroid_nB,5 ,
+Yandroid_s,1 ,
+-1,
+Yandroid_n,6 ,
+Yandroid_sB,0 ,
+-1,
+Yandroid_nB,6 ,
+Yandroid_s,0 ,
+-1,
+Yandroid_eB,6 ,
+Yandroid_w,0 ,
+-1,
+Yandroid_e,6 ,
+Yandroid_wB,0 ,
+-1,
+Yandroid_eB,5 ,
+Yandroid_w,1 ,
+-1,
+Yandroid_e,5 ,
+Yandroid_wB,1 ,
+-1,
+Yandroid_eB,4 ,
+Yandroid_w,2 ,
+-1,
+Yandroid_e,4 ,
+Yandroid_wB,2 ,
+-1,
+Yandroid_eB,3 ,
+Yandroid_w,3 ,
+-1,
+Yandroid_e,3 ,
+Yandroid_wB,3 ,
+-1,
+Yandroid_eB,2 ,
+Yandroid_w,4 ,
+-1,
+Yandroid_e,2 ,
+Yandroid_wB,4 ,
+-1,
+Yandroid_eB,1 ,
+Yandroid_w,5 ,
+-1,
+Yandroid_e,1 ,
+Yandroid_wB,5 ,
+-1,
+Yandroid_eB,0 ,
+Yandroid_w,6 ,
+-1,
+Yandroid_e,0 ,
+Yandroid_wB,6 ,
+-1,
+Yandroid_neB,6 ,
+Yandroid_sw,0 ,
+-1,
+Yandroid_ne,6 ,
+Yandroid_swB,0 ,
+-1,
+Yandroid_neB,5 ,
+Yandroid_sw,1 ,
+-1,
+Yandroid_ne,5 ,
+Yandroid_swB,1 ,
+-1,
+Yandroid_neB,4 ,
+Yandroid_sw,2 ,
+-1,
+Yandroid_ne,4 ,
+Yandroid_swB,2 ,
+-1,
+Yandroid_neB,3 ,
+Yandroid_sw,3 ,
+-1,
+Yandroid_ne,3 ,
+Yandroid_swB,3 ,
+-1,
+Yandroid_neB,2 ,
+Yandroid_sw,4 ,
+-1,
+Yandroid_ne,2 ,
+Yandroid_swB,4 ,
+-1,
+Yandroid_neB,1 ,
+Yandroid_sw,5 ,
+-1,
+Yandroid_ne,1 ,
+Yandroid_swB,5 ,
+-1,
+Yandroid_neB,0 ,
+Yandroid_sw,6 ,
+-1,
+Yandroid_ne,0 ,
+Yandroid_swB,6 ,
+-1,
+Yandroid_nw,0 ,
+Yandroid_seB,6 ,
+-1,
+Yandroid_nwB,0 ,
+Yandroid_se,6 ,
+-1,
+Yandroid_nw,1 ,
+Yandroid_seB,5 ,
+-1,
+Yandroid_nwB,1 ,
+Yandroid_se,5 ,
+-1,
+Yandroid_nw,2 ,
+Yandroid_seB,4 ,
+-1,
+Yandroid_nwB,2 ,
+Yandroid_se,4 ,
+-1,
+Yandroid_nw,3 ,
+Yandroid_seB,3 ,
+-1,
+Yandroid_nwB,3 ,
+Yandroid_se,3 ,
+-1,
+Yandroid_nw,4 ,
+Yandroid_seB,2 ,
+-1,
+Yandroid_nwB,4 ,
+Yandroid_se,2 ,
+-1,
+Yandroid_nw,5 ,
+Yandroid_seB,1 ,
+-1,
+Yandroid_nwB,5 ,
+Yandroid_se,1 ,
+-1,
+Yandroid_nw,6 ,
+Yandroid_seB,0 ,
+-1,
+Yandroid_nwB,6 ,
+Yandroid_se,0 ,
+-1,
+
+Yspring_e,7 ,
+Yspring_w,7 ,
+Yspring_kill_e,7 ,
+Yspring_kill_w,7 ,
+Yspring_s,7 ,
+Xspring,0 ,
+Xspring,1 ,
+Xspring,2 ,
+Xspring,3 ,
+Xspring,4 ,
+Xspring,5 ,
+Xspring,6 ,
+Xspring,7 ,
+Xspring_pause,0 ,
+Xspring_pause,1 ,
+Xspring_pause,2 ,
+Xspring_pause,3 ,
+Xspring_pause,4 ,
+Xspring_pause,5 ,
+Xspring_pause,6 ,
+Xspring_pause,7 ,
+Xspring_e,0 ,
+Xspring_e,1 ,
+Xspring_e,2 ,
+Xspring_e,3 ,
+Xspring_e,4 ,
+Xspring_e,5 ,
+Xspring_e,6 ,
+Xspring_e,7 ,
+Xspring_w,0 ,
+Xspring_w,1 ,
+Xspring_w,2 ,
+Xspring_w,3 ,
+Xspring_w,4 ,
+Xspring_w,5 ,
+Xspring_w,6 ,
+Xspring_w,7 ,
+Xspring_fall,0 ,
+Xspring_fall,1 ,
+Xspring_fall,2 ,
+Xspring_fall,3 ,
+Xspring_fall,4 ,
+Xspring_fall,5 ,
+Xspring_fall,6 ,
+Xspring_fall,7 ,
+#ifdef BAD_ROLL
+Xspring_force_e,0 ,
+Xspring_force_e,1 ,
+Xspring_force_e,2 ,
+Xspring_force_e,3 ,
+Xspring_force_e,4 ,
+Xspring_force_e,5 ,
+Xspring_force_e,6 ,
+Xspring_force_e,7 ,
+Xspring_force_w,0 ,
+Xspring_force_w,1 ,
+Xspring_force_w,2 ,
+Xspring_force_w,3 ,
+Xspring_force_w,4 ,
+Xspring_force_w,5 ,
+Xspring_force_w,6 ,
+Xspring_force_w,7 ,
+#endif
+-1,
+Yspring_sB,6 ,
+-1,
+Yspring_s,6 ,
+-1,
+Yspring_sB,5 ,
+-1,
+Yspring_s,5 ,
+-1,
+Yspring_sB,4 ,
+-1,
+Yspring_s,4 ,
+-1,
+Yspring_sB,3 ,
+-1,
+Yspring_s,3 ,
+-1,
+Yspring_sB,2 ,
+-1,
+Yspring_s,2 ,
+-1,
+Yspring_sB,1 ,
+-1,
+Yspring_s,1 ,
+-1,
+Yspring_sB,0 ,
+-1,
+Yspring_s,0 ,
+-1,
+Yspring_eB,6 ,
+Yspring_w,0 ,
+-1,
+Yspring_e,6 ,
+Yspring_wB,0 ,
+-1,
+Yspring_eB,5 ,
+Yspring_w,1 ,
+-1,
+Yspring_e,5 ,
+Yspring_wB,1 ,
+-1,
+Yspring_eB,4 ,
+Yspring_w,2 ,
+-1,
+Yspring_e,4 ,
+Yspring_wB,2 ,
+-1,
+Yspring_eB,3 ,
+Yspring_w,3 ,
+-1,
+Yspring_e,3 ,
+Yspring_wB,3 ,
+-1,
+Yspring_eB,2 ,
+Yspring_w,4 ,
+-1,
+Yspring_e,2 ,
+Yspring_wB,4 ,
+-1,
+Yspring_eB,1 ,
+Yspring_w,5 ,
+-1,
+Yspring_e,1 ,
+Yspring_wB,5 ,
+-1,
+Yspring_eB,0 ,
+Yspring_w,6 ,
+-1,
+Yspring_e,0 ,
+Yspring_wB,6 ,
+-1,
+Yspring_kill_eB,6 ,
+-1,
+Yspring_kill_e,6 ,
+-1,
+Yspring_kill_eB,5 ,
+-1,
+Yspring_kill_e,5 ,
+-1,
+Yspring_kill_eB,4 ,
+-1,
+Yspring_kill_e,4 ,
+-1,
+Yspring_kill_eB,3 ,
+-1,
+Yspring_kill_e,3 ,
+-1,
+Yspring_kill_eB,2 ,
+-1,
+Yspring_kill_e,2 ,
+-1,
+Yspring_kill_eB,1 ,
+-1,
+Yspring_kill_e,1 ,
+-1,
+Yspring_kill_eB,0 ,
+-1,
+Yspring_kill_e,0 ,
+-1,
+Yspring_kill_w,0 ,
+-1,
+Yspring_kill_wB,0 ,
+-1,
+Yspring_kill_w,1 ,
+-1,
+Yspring_kill_wB,1 ,
+-1,
+Yspring_kill_w,2 ,
+-1,
+Yspring_kill_wB,2 ,
+-1,
+Yspring_kill_w,3 ,
+-1,
+Yspring_kill_wB,3 ,
+-1,
+Yspring_kill_w,4 ,
+-1,
+Yspring_kill_wB,4 ,
+-1,
+Yspring_kill_w,5 ,
+-1,
+Yspring_kill_wB,5 ,
+-1,
+Yspring_kill_w,6 ,
+-1,
+Yspring_kill_wB,6 ,
+-1,
+
+Xeater_n,0 ,
+Xeater_e,0 ,
+Xeater_w,0 ,
+Xeater_s,0 ,
+Xeater_n,7 ,
+Xeater_e,7 ,
+Xeater_s,7 ,
+Xeater_w,7 ,
+Yeater_n,7 ,
+Yeater_e,7 ,
+Yeater_s,7 ,
+Yeater_w,7 ,
+-1,
+Xeater_n,1 ,
+Xeater_e,1 ,
+Xeater_w,1 ,
+Xeater_s,1 ,
+Xeater_n,6 ,
+Xeater_e,6 ,
+Xeater_w,6 ,
+Xeater_s,6 ,
+-1,
+Xeater_n,2 ,
+Xeater_e,2 ,
+Xeater_w,2 ,
+Xeater_s,2 ,
+Xeater_n,5 ,
+Xeater_e,5 ,
+Xeater_w,5 ,
+Xeater_s,5 ,
+-1,
+Xeater_n,3 ,
+Xeater_e,3 ,
+Xeater_w,3 ,
+Xeater_s,3 ,
+Xeater_n,4 ,
+Xeater_e,4 ,
+Xeater_w,4 ,
+Xeater_s,4 ,
+-1,
+Yeater_n,0 ,
+Yeater_sB,6 ,
+-1,
+Yeater_nB,0 ,
+Yeater_s,6 ,
+-1,
+Yeater_n,1 ,
+Yeater_sB,5 ,
+-1,
+Yeater_nB,1 ,
+Yeater_s,5 ,
+-1,
+Yeater_n,2 ,
+Yeater_sB,4 ,
+-1,
+Yeater_nB,2 ,
+Yeater_s,4 ,
+-1,
+Yeater_n,3 ,
+Yeater_sB,3 ,
+-1,
+Yeater_nB,3 ,
+Yeater_s,3 ,
+-1,
+Yeater_n,4 ,
+Yeater_sB,2,
+-1,
+Yeater_nB,4 ,
+Yeater_s,2 ,
+-1,
+Yeater_n,5 ,
+Yeater_sB,1 ,
+-1,
+Yeater_nB,5 ,
+Yeater_s,1 ,
+-1,
+Yeater_n,6 ,
+Yeater_sB,0 ,
+-1,
+Yeater_nB,6 ,
+Yeater_s,0 ,
+-1,
+Yeater_eB,6 ,
+Yeater_w,0 ,
+-1,
+Yeater_e,6 ,
+Yeater_wB,0 ,
+-1,
+Yeater_eB,5 ,
+Yeater_w,1 ,
+-1,
+Yeater_e,5 ,
+Yeater_wB,1 ,
+-1,
+Yeater_eB,4 ,
+Yeater_w,2 ,
+-1,
+Yeater_e,4 ,
+Yeater_wB,2 ,
+-1,
+Yeater_eB,3 ,
+Yeater_w,3 ,
+-1,
+Yeater_e,3 ,
+Yeater_wB,3 ,
+-1,
+Yeater_eB,2 ,
+Yeater_w,4 ,
+-1,
+Yeater_e,2 ,
+Yeater_wB,4 ,
+-1,
+Yeater_eB,1 ,
+Yeater_w,5 ,
+-1,
+Yeater_e,1 ,
+Yeater_wB,5 ,
+-1,
+Yeater_eB,0 ,
+Yeater_w,6 ,
+-1,
+Yeater_e,0 ,
+Yeater_wB,6 ,
+-1,
+Yeater_stone,0 ,
+-1,
+Yeater_stone,1 ,
+-1,
+Yeater_stone,2 ,
+-1,
+Yeater_stone,3 ,
+-1,
+Yeater_stone,4 ,
+-1,
+Yeater_stone,5 ,
+-1,
+Yeater_stone,6 ,
+-1,
+Yeater_spring,0 ,
+-1,
+Yeater_spring,1 ,
+-1,
+Yeater_spring,2 ,
+-1,
+Yeater_spring,3 ,
+-1,
+Yeater_spring,4 ,
+-1,
+Yeater_spring,5 ,
+-1,
+Yeater_spring,6 ,
+-1,
+
+Xalien,0 ,
+Xalien_pause,0 ,
+Xalien,7 ,
+Xalien_pause,7 ,
+Yalien_n,7 ,
+Yalien_e,7 ,
+Yalien_s,7 ,
+Yalien_w,7 ,
+-1,
+Xalien,1 ,
+Xalien_pause,1 ,
+Xalien,6 ,
+Xalien_pause,6 ,
+-1,
+Xalien,2 ,
+Xalien_pause,2 ,
+Xalien,5 ,
+Xalien_pause,5 ,
+-1,
+Xalien,3 ,
+Xalien_pause,3 ,
+Xalien,4 ,
+Xalien_pause,4 ,
+-1,
+Yalien_n,0 ,
+Yalien_sB,6 ,
+-1,
+Yalien_nB,0 ,
+Yalien_s,6 ,
+-1,
+Yalien_n,1 ,
+Yalien_sB,5 ,
+-1,
+Yalien_nB,1 ,
+Yalien_s,5 ,
+-1,
+Yalien_n,2 ,
+Yalien_sB,4 ,
+-1,
+Yalien_nB,2 ,
+Yalien_s,4 ,
+-1,
+Yalien_n,3 ,
+Yalien_sB,3 ,
+-1,
+Yalien_nB,3 ,
+Yalien_s,3 ,
+-1,
+Yalien_n,4 ,
+Yalien_sB,2 ,
+-1,
+Yalien_nB,4 ,
+Yalien_s,2 ,
+-1,
+Yalien_n,5 ,
+Yalien_sB,1 ,
+-1,
+Yalien_nB,5 ,
+Yalien_s,1 ,
+-1,
+Yalien_n,6 ,
+Yalien_sB,0 ,
+-1,
+Yalien_nB,6 ,
+Yalien_s,0 ,
+-1,
+Yalien_eB,6 ,
+Yalien_w,0 ,
+-1,
+Yalien_e,6 ,
+Yalien_wB,0 ,
+-1,
+Yalien_eB,5 ,
+Yalien_w,1 ,
+-1,
+Yalien_e,5 ,
+Yalien_wB,1 ,
+-1,
+Yalien_eB,4 ,
+Yalien_w,2 ,
+-1,
+Yalien_e,4 ,
+Yalien_wB,2 ,
+-1,
+Yalien_eB,3 ,
+Yalien_w,3 ,
+-1,
+Yalien_e,3 ,
+Yalien_wB,3 ,
+-1,
+Yalien_eB,2 ,
+Yalien_w,4 ,
+-1,
+Yalien_e,2 ,
+Yalien_wB,4 ,
+-1,
+Yalien_eB,1 ,
+Yalien_w,5 ,
+-1,
+Yalien_e,1 ,
+Yalien_wB,5 ,
+-1,
+Yalien_eB,0 ,
+Yalien_w,6 ,
+-1,
+Yalien_e,0 ,
+Yalien_wB,6 ,
+-1,
+Yalien_stone,0 ,
+-1,
+Yalien_stone,1 ,
+-1,
+Yalien_stone,2 ,
+-1,
+Yalien_stone,3 ,
+-1,
+Yalien_stone,4 ,
+-1,
+Yalien_stone,5 ,
+-1,
+Yalien_stone,6 ,
+-1,
+Yalien_spring,0 ,
+-1,
+Yalien_spring,1 ,
+-1,
+Yalien_spring,2 ,
+-1,
+Yalien_spring,3 ,
+-1,
+Yalien_spring,4 ,
+-1,
+Yalien_spring,5 ,
+-1,
+Yalien_spring,6 ,
+-1,
+
+Xemerald,0 ,
+Xemerald,1 ,
+Xemerald,2 ,
+Xemerald,3 ,
+Xemerald,4 ,
+Xemerald,5 ,
+Xemerald,6 ,
+Xemerald,7 ,
+Xemerald_pause,0 ,
+Xemerald_pause,1 ,
+Xemerald_pause,2 ,
+Xemerald_pause,3 ,
+Xemerald_pause,4 ,
+Xemerald_pause,5 ,
+Xemerald_pause,6 ,
+Xemerald_pause,7 ,
+Xemerald_fall,0 ,
+Xemerald_fall,1 ,
+Xemerald_fall,2 ,
+Xemerald_fall,3 ,
+Xemerald_fall,4 ,
+Xemerald_fall,5 ,
+Xemerald_fall,6 ,
+Xemerald_fall,7 ,
+#ifdef BAD_ROLL
+Xemerald_force_e,0 ,
+Xemerald_force_e,1 ,
+Xemerald_force_e,2 ,
+Xemerald_force_e,3 ,
+Xemerald_force_e,4 ,
+Xemerald_force_e,5 ,
+Xemerald_force_e,6 ,
+Xemerald_force_e,7 ,
+Xemerald_force_w,0 ,
+Xemerald_force_w,1 ,
+Xemerald_force_w,2 ,
+Xemerald_force_w,3 ,
+Xemerald_force_w,4 ,
+Xemerald_force_w,5 ,
+Xemerald_force_w,6 ,
+Xemerald_force_w,7 ,
+#endif
+Xemerald_shine,0 ,
+Xemerald_shine,7 ,
+Yemerald_stone,7 ,
+Yemerald_s,7 ,
+Yemerald_e,7 ,
+Yemerald_w,7 ,
+-1,
+Xemerald_shine,1 ,
+Xemerald_shine,6 ,
+-1,
+Xemerald_shine,2 ,
+Xemerald_shine,5 ,
+-1,
+Xemerald_shine,3 ,
+Xemerald_shine,4 ,
+-1,
+Yemerald_sB,6 ,
+-1,
+Yemerald_s,6 ,
+-1,
+Yemerald_sB,5 ,
+-1,
+Yemerald_s,5 ,
+-1,
+Yemerald_sB,4 ,
+-1,
+Yemerald_s,4 ,
+-1,
+Yemerald_sB,3 ,
+-1,
+Yemerald_s,3 ,
+-1,
+Yemerald_sB,2 ,
+-1,
+Yemerald_s,2 ,
+-1,
+Yemerald_sB,1 ,
+-1,
+Yemerald_s,1 ,
+-1,
+Yemerald_sB,0 ,
+-1,
+Yemerald_s,0 ,
+-1,
+Yemerald_eB,6 ,
+Yemerald_w,0 ,
+-1,
+Yemerald_e,6 ,
+Yemerald_wB,0 ,
+-1,
+Yemerald_eB,5 ,
+Yemerald_w,1 ,
+-1,
+Yemerald_e,5 ,
+Yemerald_wB,1 ,
+-1,
+Yemerald_eB,4 ,
+Yemerald_w,2 ,
+-1,
+Yemerald_e,4 ,
+Yemerald_wB,2 ,
+-1,
+Yemerald_eB,3 ,
+Yemerald_w,3 ,
+-1,
+Yemerald_e,3 ,
+Yemerald_wB,3 ,
+-1,
+Yemerald_eB,2 ,
+Yemerald_w,4 ,
+-1,
+Yemerald_e,2 ,
+Yemerald_wB,4 ,
+-1,
+Yemerald_eB,1 ,
+Yemerald_w,5 ,
+-1,
+Yemerald_e,1 ,
+Yemerald_wB,5 ,
+-1,
+Yemerald_eB,0 ,
+Yemerald_w,6 ,
+-1,
+Yemerald_e,0 ,
+Yemerald_wB,6 ,
+-1,
+Yemerald_eat,6 ,
+-1,
+Yemerald_eat,5 ,
+-1,
+Yemerald_eat,4 ,
+-1,
+Yemerald_eat,3 ,
+-1,
+Yemerald_eat,2 ,
+-1,
+Yemerald_eat,1 ,
+-1,
+Yemerald_eat,0 ,
+-1,
+Yemerald_stone,0 ,
+-1,
+Yemerald_stone,1 ,
+-1,
+Yemerald_stone,2 ,
+-1,
+Yemerald_stone,3 ,
+-1,
+Yemerald_stone,4 ,
+-1,
+Yemerald_stone,5 ,
+-1,
+Yemerald_stone,6 ,
+-1,
+
+Xdiamond,0 ,
+Xdiamond,1 ,
+Xdiamond,2 ,
+Xdiamond,3 ,
+Xdiamond,4 ,
+Xdiamond,5 ,
+Xdiamond,6 ,
+Xdiamond,7 ,
+Xdiamond_pause,0 ,
+Xdiamond_pause,1 ,
+Xdiamond_pause,2 ,
+Xdiamond_pause,3 ,
+Xdiamond_pause,4 ,
+Xdiamond_pause,5 ,
+Xdiamond_pause,6 ,
+Xdiamond_pause,7 ,
+Xdiamond_fall,0 ,
+Xdiamond_fall,1 ,
+Xdiamond_fall,2 ,
+Xdiamond_fall,3 ,
+Xdiamond_fall,4 ,
+Xdiamond_fall,5 ,
+Xdiamond_fall,6 ,
+Xdiamond_fall,7 ,
+#ifdef BAD_ROLL
+Xdiamond_force_e,0 ,
+Xdiamond_force_e,1 ,
+Xdiamond_force_e,2 ,
+Xdiamond_force_e,3 ,
+Xdiamond_force_e,4 ,
+Xdiamond_force_e,5 ,
+Xdiamond_force_e,6 ,
+Xdiamond_force_e,7 ,
+Xdiamond_force_w,0 ,
+Xdiamond_force_w,1 ,
+Xdiamond_force_w,2 ,
+Xdiamond_force_w,3 ,
+Xdiamond_force_w,4 ,
+Xdiamond_force_w,5 ,
+Xdiamond_force_w,6 ,
+Xdiamond_force_w,7 ,
+#endif
+Xdiamond_shine,0 ,
+Xdiamond_shine,7 ,
+Ydiamond_s,7 ,
+Ydiamond_e,7 ,
+Ydiamond_w,7 ,
+-1,
+Xdiamond_shine,1 ,
+Xdiamond_shine,6 ,
+-1,
+Xdiamond_shine,2 ,
+Xdiamond_shine,5 ,
+-1,
+Xdiamond_shine,3 ,
+Xdiamond_shine,4 ,
+-1,
+Ydiamond_sB,6 ,
+-1,
+Ydiamond_s,6 ,
+-1,
+Ydiamond_sB,5 ,
+-1,
+Ydiamond_s,5 ,
+-1,
+Ydiamond_sB,4 ,
+-1,
+Ydiamond_s,4 ,
+-1,
+Ydiamond_sB,3 ,
+-1,
+Ydiamond_s,3 ,
+-1,
+Ydiamond_sB,2 ,
+-1,
+Ydiamond_s,2 ,
+-1,
+Ydiamond_sB,1 ,
+-1,
+Ydiamond_s,1 ,
+-1,
+Ydiamond_sB,0 ,
+-1,
+Ydiamond_s,0 ,
+-1,
+Ydiamond_eB,6 ,
+Ydiamond_w,0 ,
+-1,
+Ydiamond_e,6 ,
+Ydiamond_wB,0 ,
+-1,
+Ydiamond_eB,5 ,
+Ydiamond_w,1 ,
+-1,
+Ydiamond_e,5 ,
+Ydiamond_wB,1 ,
+-1,
+Ydiamond_eB,4 ,
+Ydiamond_w,2 ,
+-1,
+Ydiamond_e,4 ,
+Ydiamond_wB,2 ,
+-1,
+Ydiamond_eB,3 ,
+Ydiamond_w,3 ,
+-1,
+Ydiamond_e,3 ,
+Ydiamond_wB,3 ,
+-1,
+Ydiamond_eB,2 ,
+Ydiamond_w,4 ,
+-1,
+Ydiamond_e,2 ,
+Ydiamond_wB,4 ,
+-1,
+Ydiamond_eB,1 ,
+Ydiamond_w,5 ,
+-1,
+Ydiamond_e,1 ,
+Ydiamond_wB,5 ,
+-1,
+Ydiamond_eB,0 ,
+Ydiamond_w,6 ,
+-1,
+Ydiamond_e,0 ,
+Ydiamond_wB,6 ,
+-1,
+Ydiamond_eat,6 ,
+-1,
+Ydiamond_eat,5 ,
+-1,
+Ydiamond_eat,4 ,
+-1,
+Ydiamond_eat,3 ,
+-1,
+Ydiamond_eat,2 ,
+-1,
+Ydiamond_eat,1 ,
+-1,
+Ydiamond_eat,0 ,
+-1,
+Ydiamond_stone,0 ,
+-1,
+Ydiamond_stone,1 ,
+-1,
+Ydiamond_stone,2 ,
+-1,
+Ydiamond_stone,3 ,
+-1,
+Ydiamond_stone,4 ,
+-1,
+Ydiamond_stone,5 ,
+-1,
+Ydiamond_stone,6 ,
+-1,
+
+Xdrip_fall,0 ,
+Xdrip_fall,1 ,
+Xdrip_fall,2 ,
+Xdrip_fall,3 ,
+Xdrip_fall,4 ,
+Xdrip_fall,5 ,
+Xdrip_fall,6 ,
+Xdrip_fall,7 ,
+Xdrip_eat,7 ,
+Ydrip_s2,7 ,
+-1,
+Ydrip_s2B,6 ,
+-1,
+Ydrip_s2,6 ,
+-1,
+Ydrip_s2B,5 ,
+-1,
+Ydrip_s2,5 ,
+-1,
+Ydrip_s2B,4 ,
+-1,
+Ydrip_s2,4 ,
+-1,
+Ydrip_s2B,3 ,
+-1,
+Ydrip_s2,3 ,
+-1,
+Ydrip_s2B,2 ,
+-1,
+Ydrip_s2,2 ,
+-1,
+Ydrip_s2B,1 ,
+-1,
+Ydrip_s2,1 ,
+-1,
+Ydrip_s2B,0 ,
+-1,
+Ydrip_s2,0 ,
+-1,
+Xdrip_stretchB,0 ,
+Xdrip_stretchB,1 ,
+Xdrip_stretchB,2 ,
+Xdrip_stretchB,3 ,
+Xdrip_stretchB,4 ,
+Xdrip_stretchB,5 ,
+Xdrip_stretchB,6 ,
+Xdrip_stretchB,7 ,
+Ydrip_s1B,7 ,
+-1,
+Xdrip_stretch,0 ,
+Xdrip_stretch,1 ,
+Xdrip_stretch,2 ,
+Xdrip_stretch,3 ,
+Xdrip_stretch,4 ,
+Xdrip_stretch,5 ,
+Xdrip_stretch,6 ,
+Xdrip_stretch,7 ,
+Ydrip_s1,7 ,
+-1,
+Ydrip_s1B,6 ,
+-1,
+Ydrip_s1,6 ,
+-1,
+Ydrip_s1B,5 ,
+-1,
+Ydrip_s1,5 ,
+-1,
+Ydrip_s1B,4 ,
+-1,
+Ydrip_s1,4 ,
+-1,
+Ydrip_s1B,3 ,
+-1,
+Ydrip_s1,3 ,
+-1,
+Ydrip_s1B,2 ,
+-1,
+Ydrip_s1,2 ,
+-1,
+Ydrip_s1B,1 ,
+-1,
+Ydrip_s1,1 ,
+-1,
+Ydrip_s1B,0 ,
+-1,
+Ydrip_s1,0 ,
+-1,
+Xdrip_eat,0 ,
+-1,
+Xdrip_eat,1 ,
+-1,
+Xdrip_eat,2 ,
+-1,
+Xdrip_eat,3 ,
+-1,
+Xdrip_eat,4 ,
+-1,
+Xdrip_eat,5 ,
+-1,
+Xdrip_eat,6 ,
+-1,
+
+Xbomb,0 ,
+Xbomb,1 ,
+Xbomb,2 ,
+Xbomb,3 ,
+Xbomb,4 ,
+Xbomb,5 ,
+Xbomb,6 ,
+Xbomb,7 ,
+Xbomb_pause,0 ,
+Xbomb_pause,1 ,
+Xbomb_pause,2 ,
+Xbomb_pause,3 ,
+Xbomb_pause,4 ,
+Xbomb_pause,5 ,
+Xbomb_pause,6 ,
+Xbomb_pause,7 ,
+Xbomb_fall,0 ,
+Xbomb_fall,1 ,
+Xbomb_fall,2 ,
+Xbomb_fall,3 ,
+Xbomb_fall,4 ,
+Xbomb_fall,5 ,
+Xbomb_fall,6 ,
+Xbomb_fall,7 ,
+#ifdef BAD_ROLL
+Xbomb_force_e,0 ,
+Xbomb_force_e,1 ,
+Xbomb_force_e,2 ,
+Xbomb_force_e,3 ,
+Xbomb_force_e,4 ,
+Xbomb_force_e,5 ,
+Xbomb_force_e,6 ,
+Xbomb_force_e,7 ,
+Xbomb_force_w,0 ,
+Xbomb_force_w,1 ,
+Xbomb_force_w,2 ,
+Xbomb_force_w,3 ,
+Xbomb_force_w,4 ,
+Xbomb_force_w,5 ,
+Xbomb_force_w,6 ,
+Xbomb_force_w,7 ,
+#endif
+Ybomb_s,7 ,
+Ybomb_e,7 ,
+Ybomb_w,7 ,
+-1,
+Ybomb_sB,6 ,
+-1,
+Ybomb_s,6 ,
+-1,
+Ybomb_sB,5 ,
+-1,
+Ybomb_s,5 ,
+-1,
+Ybomb_sB,4 ,
+-1,
+Ybomb_s,4 ,
+-1,
+Ybomb_sB,3 ,
+-1,
+Ybomb_s,3 ,
+-1,
+Ybomb_sB,2 ,
+-1,
+Ybomb_s,2 ,
+-1,
+Ybomb_sB,1 ,
+-1,
+Ybomb_s,1 ,
+-1,
+Ybomb_sB,0 ,
+-1,
+Ybomb_s,0 ,
+-1,
+Ybomb_eB,6 ,
+Ybomb_w,0 ,
+-1,
+Ybomb_e,6 ,
+Ybomb_wB,0 ,
+-1,
+Ybomb_eB,5 ,
+Ybomb_w,1 ,
+-1,
+Ybomb_e,5 ,
+Ybomb_wB,1 ,
+-1,
+Ybomb_eB,4 ,
+Ybomb_w,2 ,
+-1,
+Ybomb_e,4 ,
+Ybomb_wB,2 ,
+-1,
+Ybomb_eB,3 ,
+Ybomb_w,3 ,
+-1,
+Ybomb_e,3 ,
+Ybomb_wB,3 ,
+-1,
+Ybomb_eB,2 ,
+Ybomb_w,4 ,
+-1,
+Ybomb_e,2 ,
+Ybomb_wB,4 ,
+-1,
+Ybomb_eB,1 ,
+Ybomb_w,5 ,
+-1,
+Ybomb_e,1 ,
+Ybomb_wB,5 ,
+-1,
+Ybomb_eB,0 ,
+Ybomb_w,6 ,
+-1,
+Ybomb_e,0 ,
+Ybomb_wB,6 ,
+-1,
+Ybomb_eat,6 ,
+-1,
+Ybomb_eat,5 ,
+-1,
+Ybomb_eat,4 ,
+-1,
+Ybomb_eat,3 ,
+-1,
+Ybomb_eat,2 ,
+-1,
+Ybomb_eat,1 ,
+-1,
+Ybomb_eat,0 ,
+-1,
+
+Yballoon_n,7 ,
+Yballoon_e,7 ,
+Yballoon_s,7 ,
+Yballoon_w,7 ,
+Xballoon,0 ,
+Xballoon,1 ,
+Xballoon,2 ,
+Xballoon,3 ,
+Xballoon,4 ,
+Xballoon,5 ,
+Xballoon,6 ,
+Xballoon,7 ,
+-1,
+Yballoon_n,0 ,
+Yballoon_sB,6 ,
+-1,
+Yballoon_nB,0 ,
+Yballoon_s,6 ,
+-1,
+Yballoon_n,1 ,
+Yballoon_sB,5 ,
+-1,
+Yballoon_nB,1 ,
+Yballoon_s,5 ,
+-1,
+Yballoon_n,2 ,
+Yballoon_sB,4 ,
+-1,
+Yballoon_nB,2 ,
+Yballoon_s,4 ,
+-1,
+Yballoon_n,3 ,
+Yballoon_sB,3 ,
+-1,
+Yballoon_nB,3 ,
+Yballoon_s,3 ,
+-1,
+Yballoon_n,4 ,
+Yballoon_sB,2 ,
+-1,
+Yballoon_nB,4 ,
+Yballoon_s,2 ,
+-1,
+Yballoon_n,5 ,
+Yballoon_sB,1 ,
+-1,
+Yballoon_nB,5 ,
+Yballoon_s,1 ,
+-1,
+Yballoon_n,6 ,
+Yballoon_sB,0 ,
+-1,
+Yballoon_nB,6 ,
+Yballoon_s,0 ,
+-1,
+Yballoon_eB,6 ,
+Yballoon_w,0 ,
+-1,
+Yballoon_e,6 ,
+Yballoon_wB,0 ,
+-1,
+Yballoon_eB,5 ,
+Yballoon_w,1 ,
+-1,
+Yballoon_e,5 ,
+Yballoon_wB,1 ,
+-1,
+Yballoon_eB,4 ,
+Yballoon_w,2 ,
+-1,
+Yballoon_e,4 ,
+Yballoon_wB,2 ,
+-1,
+Yballoon_eB,3 ,
+Yballoon_w,3 ,
+-1,
+Yballoon_e,3 ,
+Yballoon_wB,3 ,
+-1,
+Yballoon_eB,2 ,
+Yballoon_w,4 ,
+-1,
+Yballoon_e,2 ,
+Yballoon_wB,4 ,
+-1,
+Yballoon_eB,1 ,
+Yballoon_w,5 ,
+-1,
+Yballoon_e,1 ,
+Yballoon_wB,5 ,
+-1,
+Yballoon_eB,0 ,
+Yballoon_w,6 ,
+-1,
+Yballoon_e,0 ,
+Yballoon_wB,6 ,
+-1,
+
+Xgrass,0 ,
+Xgrass,1 ,
+Xgrass,2 ,
+Xgrass,3 ,
+Xgrass,4 ,
+Xgrass,5 ,
+Xgrass,6 ,
+Xgrass,7 ,
+Xfake_grass,0 ,
+Xfake_grass,1 ,
+Xfake_grass,2 ,
+Xfake_grass,3 ,
+Xfake_grass,4 ,
+Xfake_grass,5 ,
+Xfake_grass,6 ,
+Xfake_grass,7 ,
+-1,
+Ygrass_nB,6 ,
+-1,
+Ygrass_nB,5 ,
+-1,
+Ygrass_nB,4 ,
+-1,
+Ygrass_nB,3 ,
+-1,
+Ygrass_nB,2 ,
+-1,
+Ygrass_nB,1 ,
+-1,
+Ygrass_nB,0 ,
+-1,
+Ygrass_eB,6 ,
+-1,
+Ygrass_eB,5 ,
+-1,
+Ygrass_eB,4 ,
+-1,
+Ygrass_eB,3 ,
+-1,
+Ygrass_eB,2 ,
+-1,
+Ygrass_eB,1 ,
+-1,
+Ygrass_eB,0 ,
+-1,
+Ygrass_sB,6 ,
+-1,
+Ygrass_sB,5 ,
+-1,
+Ygrass_sB,4 ,
+-1,
+Ygrass_sB,3 ,
+-1,
+Ygrass_sB,2 ,
+-1,
+Ygrass_sB,1 ,
+-1,
+Ygrass_sB,0 ,
+-1,
+Ygrass_wB,6 ,
+-1,
+Ygrass_wB,5 ,
+-1,
+Ygrass_wB,4 ,
+-1,
+Ygrass_wB,3 ,
+-1,
+Ygrass_wB,2 ,
+-1,
+Ygrass_wB,1 ,
+-1,
+Ygrass_wB,0 ,
+-1,
+
+Xdirt,0 ,
+Xdirt,1 ,
+Xdirt,2 ,
+Xdirt,3 ,
+Xdirt,4 ,
+Xdirt,5 ,
+Xdirt,6 ,
+Xdirt,7 ,
+-1,
+Ydirt_nB,6 ,
+-1,
+Ydirt_nB,5 ,
+-1,
+Ydirt_nB,4 ,
+-1,
+Ydirt_nB,3 ,
+-1,
+Ydirt_nB,2 ,
+-1,
+Ydirt_nB,1 ,
+-1,
+Ydirt_nB,0 ,
+-1,
+Ydirt_eB,6 ,
+-1,
+Ydirt_eB,5 ,
+-1,
+Ydirt_eB,4 ,
+-1,
+Ydirt_eB,3 ,
+-1,
+Ydirt_eB,2 ,
+-1,
+Ydirt_eB,1 ,
+-1,
+Ydirt_eB,0 ,
+-1,
+Ydirt_sB,6 ,
+-1,
+Ydirt_sB,5 ,
+-1,
+Ydirt_sB,4 ,
+-1,
+Ydirt_sB,3 ,
+-1,
+Ydirt_sB,2 ,
+-1,
+Ydirt_sB,1 ,
+-1,
+Ydirt_sB,0 ,
+-1,
+Ydirt_wB,6 ,
+-1,
+Ydirt_wB,5 ,
+-1,
+Ydirt_wB,4 ,
+-1,
+Ydirt_wB,3 ,
+-1,
+Ydirt_wB,2 ,
+-1,
+Ydirt_wB,1 ,
+-1,
+Ydirt_wB,0 ,
+-1,
+
+Xacid_nw,0 ,
+Xacid_nw,1 ,
+Xacid_nw,2 ,
+Xacid_nw,3 ,
+Xacid_nw,4 ,
+Xacid_nw,5 ,
+Xacid_nw,6 ,
+Xacid_nw,7 ,
+-1,
+Xacid_ne,0 ,
+Xacid_ne,1 ,
+Xacid_ne,2 ,
+Xacid_ne,3 ,
+Xacid_ne,4 ,
+Xacid_ne,5 ,
+Xacid_ne,6 ,
+Xacid_ne,7 ,
+-1,
+Xacid_sw,0 ,
+Xacid_sw,1 ,
+Xacid_sw,2 ,
+Xacid_sw,3 ,
+Xacid_sw,4 ,
+Xacid_sw,5 ,
+Xacid_sw,6 ,
+Xacid_sw,7 ,
+-1,
+Xacid_s,0 ,
+Xacid_s,1 ,
+Xacid_s,2 ,
+Xacid_s,3 ,
+Xacid_s,4 ,
+Xacid_s,5 ,
+Xacid_s,6 ,
+Xacid_s,7 ,
+-1,
+Xacid_se,0 ,
+Xacid_se,1 ,
+Xacid_se,2 ,
+Xacid_se,3 ,
+Xacid_se,4 ,
+Xacid_se,5 ,
+Xacid_se,6 ,
+Xacid_se,7 ,
+-1,
+Xacid_1,0 ,
+Xacid_1,1 ,
+Xacid_1,2 ,
+Xacid_1,3 ,
+Xacid_1,4 ,
+Xacid_1,5 ,
+Xacid_1,6 ,
+Xacid_1,7 ,
+-1,
+Xacid_2,0 ,
+Xacid_2,1 ,
+Xacid_2,2 ,
+Xacid_2,3 ,
+Xacid_2,4 ,
+Xacid_2,5 ,
+Xacid_2,6 ,
+Xacid_2,7 ,
+-1,
+Xacid_3,0 ,
+Xacid_3,1 ,
+Xacid_3,2 ,
+Xacid_3,3 ,
+Xacid_3,4 ,
+Xacid_3,5 ,
+Xacid_3,6 ,
+Xacid_3,7 ,
+-1,
+Xacid_4,0 ,
+Xacid_4,1 ,
+Xacid_4,2 ,
+Xacid_4,3 ,
+Xacid_4,4 ,
+Xacid_4,5 ,
+Xacid_4,6 ,
+Xacid_4,7 ,
+-1,
+Xacid_5,0 ,
+Xacid_5,1 ,
+Xacid_5,2 ,
+Xacid_5,3 ,
+Xacid_5,4 ,
+Xacid_5,5 ,
+Xacid_5,6 ,
+Xacid_5,7 ,
+-1,
+Xacid_6,0 ,
+Xacid_6,1 ,
+Xacid_6,2 ,
+Xacid_6,3 ,
+Xacid_6,4 ,
+Xacid_6,5 ,
+Xacid_6,6 ,
+Xacid_6,7 ,
+-1,
+Xacid_7,0 ,
+Xacid_7,1 ,
+Xacid_7,2 ,
+Xacid_7,3 ,
+Xacid_7,4 ,
+Xacid_7,5 ,
+Xacid_7,6 ,
+Xacid_7,7 ,
+-1,
+Xacid_8,0 ,
+Xacid_8,1 ,
+Xacid_8,2 ,
+Xacid_8,3 ,
+Xacid_8,4 ,
+Xacid_8,5 ,
+Xacid_8,6 ,
+Xacid_8,7 ,
+-1,
+Yacid_splash_wB,4 ,
+Yacid_splash_wB,5 ,
+-1,
+Yacid_splash_wB,2 ,
+Yacid_splash_wB,3 ,
+-1,
+Yacid_splash_wB,0 ,
+Yacid_splash_wB,1 ,
+-1,
+Yacid_splash_eB,4 ,
+Yacid_splash_eB,5 ,
+-1,
+Yacid_splash_eB,2 ,
+Yacid_splash_eB,3 ,
+-1,
+Yacid_splash_eB,0 ,
+Yacid_splash_eB,1 ,
+-1,
+
+Xball_2B,7 ,
+Xball_1,0 ,
+Xball_1,1 ,
+Xball_1,2 ,
+Xball_1,3 ,
+Xball_1,4 ,
+Xball_1,5 ,
+Xball_1,6 ,
+Xball_1,7 ,
+-1,
+Xball_1B,0 ,
+-1,
+Xball_1B,1 ,
+-1,
+Xball_1B,2 ,
+-1,
+Xball_1B,3 ,
+-1,
+Xball_1B,4 ,
+-1,
+Xball_1B,5 ,
+-1,
+Xball_1B,6 ,
+-1,
+Xball_1B,7 ,
+Xball_2,0 ,
+Xball_2,1 ,
+Xball_2,2 ,
+Xball_2,3 ,
+Xball_2,4 ,
+Xball_2,5 ,
+Xball_2,6 ,
+Xball_2,7 ,
+-1,
+Xball_2B,0 ,
+-1,
+Xball_2B,1 ,
+-1,
+Xball_2B,2 ,
+-1,
+Xball_2B,3 ,
+-1,
+Xball_2B,4 ,
+-1,
+Xball_2B,5 ,
+-1,
+Xball_2B,6 ,
+-1,
+
+Ygrow_ew_eat,7 ,
+Xgrow_ew,0 ,
+Xgrow_ew,1 ,
+Xgrow_ew,2 ,
+Xgrow_ew,3 ,
+Xgrow_ew,4 ,
+Xgrow_ew,5 ,
+Xgrow_ew,6 ,
+Xgrow_ew,7 ,
+-1,
+Ygrow_ew_eat,0 ,
+-1,
+Ygrow_ew_eat,1 ,
+-1,
+Ygrow_ew_eat,2 ,
+-1,
+Ygrow_ew_eat,3 ,
+-1,
+Ygrow_ew_eat,4 ,
+-1,
+Ygrow_ew_eat,5 ,
+-1,
+Ygrow_ew_eat,6 ,
+-1,
+Ygrow_ns_eat,7 ,
+Xgrow_ns,0 ,
+Xgrow_ns,1 ,
+Xgrow_ns,2 ,
+Xgrow_ns,3 ,
+Xgrow_ns,4 ,
+Xgrow_ns,5 ,
+Xgrow_ns,6 ,
+Xgrow_ns,7 ,
+-1,
+Ygrow_ns_eat,0 ,
+-1,
+Ygrow_ns_eat,1 ,
+-1,
+Ygrow_ns_eat,2 ,
+-1,
+Ygrow_ns_eat,3 ,
+-1,
+Ygrow_ns_eat,4 ,
+-1,
+Ygrow_ns_eat,5 ,
+-1,
+Ygrow_ns_eat,6 ,
+-1,
+
+XwonderwallB,7 ,
+Xwonderwall,0 ,
+Xwonderwall,1 ,
+Xwonderwall,2 ,
+Xwonderwall,3 ,
+Xwonderwall,4 ,
+Xwonderwall,5 ,
+Xwonderwall,6 ,
+Xwonderwall,7 ,
+-1,
+XwonderwallB,0 ,
+-1,
+XwonderwallB,1 ,
+-1,
+XwonderwallB,2 ,
+-1,
+XwonderwallB,3 ,
+-1,
+XwonderwallB,4 ,
+-1,
+XwonderwallB,5 ,
+-1,
+XwonderwallB,6 ,
+-1,
+
+Xameuba_1,0 ,
+Xameuba_1,1 ,
+Xameuba_1,2 ,
+Xameuba_1,3 ,
+Xameuba_1,4 ,
+Xameuba_1,5 ,
+Xameuba_1,6 ,
+Xameuba_1,7 ,
+-1,
+Xameuba_2,0 ,
+Xameuba_2,1 ,
+Xameuba_2,2 ,
+Xameuba_2,3 ,
+Xameuba_2,4 ,
+Xameuba_2,5 ,
+Xameuba_2,6 ,
+Xameuba_2,7 ,
+-1,
+Xameuba_3,0 ,
+Xameuba_3,1 ,
+Xameuba_3,2 ,
+Xameuba_3,3 ,
+Xameuba_3,4 ,
+Xameuba_3,5 ,
+Xameuba_3,6 ,
+Xameuba_3,7 ,
+-1,
+Xameuba_4,0 ,
+Xameuba_4,1 ,
+Xameuba_4,2 ,
+Xameuba_4,3 ,
+Xameuba_4,4 ,
+Xameuba_4,5 ,
+Xameuba_4,6 ,
+Xameuba_4,7 ,
+-1,
+Xameuba_5,0 ,
+Xameuba_5,1 ,
+Xameuba_5,2 ,
+Xameuba_5,3 ,
+Xameuba_5,4 ,
+Xameuba_5,5 ,
+Xameuba_5,6 ,
+Xameuba_5,7 ,
+-1,
+Xameuba_6,0 ,
+Xameuba_6,1 ,
+Xameuba_6,2 ,
+Xameuba_6,3 ,
+Xameuba_6,4 ,
+Xameuba_6,5 ,
+Xameuba_6,6 ,
+Xameuba_6,7 ,
+-1,
+Xameuba_7,0 ,
+Xameuba_7,1 ,
+Xameuba_7,2 ,
+Xameuba_7,3 ,
+Xameuba_7,4 ,
+Xameuba_7,5 ,
+Xameuba_7,6 ,
+Xameuba_7,7 ,
+-1,
+Xameuba_8,0 ,
+Xameuba_8,1 ,
+Xameuba_8,2 ,
+Xameuba_8,3 ,
+Xameuba_8,4 ,
+Xameuba_8,5 ,
+Xameuba_8,6 ,
+Xameuba_8,7 ,
+-1,
+
+Xdoor_1,0 ,
+Xdoor_1,1 ,
+Xdoor_1,2 ,
+Xdoor_1,3 ,
+Xdoor_1,4 ,
+Xdoor_1,5 ,
+Xdoor_1,6 ,
+Xdoor_1,7 ,
+-1,
+Xdoor_2,0 ,
+Xdoor_2,1 ,
+Xdoor_2,2 ,
+Xdoor_2,3 ,
+Xdoor_2,4 ,
+Xdoor_2,5 ,
+Xdoor_2,6 ,
+Xdoor_2,7 ,
+-1,
+Xdoor_3,0 ,
+Xdoor_3,1 ,
+Xdoor_3,2 ,
+Xdoor_3,3 ,
+Xdoor_3,4 ,
+Xdoor_3,5 ,
+Xdoor_3,6 ,
+Xdoor_3,7 ,
+-1,
+Xdoor_4,0 ,
+Xdoor_4,1 ,
+Xdoor_4,2 ,
+Xdoor_4,3 ,
+Xdoor_4,4 ,
+Xdoor_4,5 ,
+Xdoor_4,6 ,
+Xdoor_4,7 ,
+-1,
+Xdoor_5,0 ,
+Xdoor_5,1 ,
+Xdoor_5,2 ,
+Xdoor_5,3 ,
+Xdoor_5,4 ,
+Xdoor_5,5 ,
+Xdoor_5,6 ,
+Xdoor_5,7 ,
+-1,
+Xdoor_6,0 ,
+Xdoor_6,1 ,
+Xdoor_6,2 ,
+Xdoor_6,3 ,
+Xdoor_6,4 ,
+Xdoor_6,5 ,
+Xdoor_6,6 ,
+Xdoor_6,7 ,
+-1,
+Xdoor_7,0 ,
+Xdoor_7,1 ,
+Xdoor_7,2 ,
+Xdoor_7,3 ,
+Xdoor_7,4 ,
+Xdoor_7,5 ,
+Xdoor_7,6 ,
+Xdoor_7,7 ,
+-1,
+Xdoor_8,0 ,
+Xdoor_8,1 ,
+Xdoor_8,2 ,
+Xdoor_8,3 ,
+Xdoor_8,4 ,
+Xdoor_8,5 ,
+Xdoor_8,6 ,
+Xdoor_8,7 ,
+-1,
+Xkey_1,0 ,
+Xkey_1,1 ,
+Xkey_1,2 ,
+Xkey_1,3 ,
+Xkey_1,4 ,
+Xkey_1,5 ,
+Xkey_1,6 ,
+Xkey_1,7 ,
+-1,
+Xkey_2,0 ,
+Xkey_2,1 ,
+Xkey_2,2 ,
+Xkey_2,3 ,
+Xkey_2,4 ,
+Xkey_2,5 ,
+Xkey_2,6 ,
+Xkey_2,7 ,
+-1,
+Xkey_3,0 ,
+Xkey_3,1 ,
+Xkey_3,2 ,
+Xkey_3,3 ,
+Xkey_3,4 ,
+Xkey_3,5 ,
+Xkey_3,6 ,
+Xkey_3,7 ,
+-1,
+Xkey_4,0 ,
+Xkey_4,1 ,
+Xkey_4,2 ,
+Xkey_4,3 ,
+Xkey_4,4 ,
+Xkey_4,5 ,
+Xkey_4,6 ,
+Xkey_4,7 ,
+-1,
+Xkey_5,0 ,
+Xkey_5,1 ,
+Xkey_5,2 ,
+Xkey_5,3 ,
+Xkey_5,4 ,
+Xkey_5,5 ,
+Xkey_5,6 ,
+Xkey_5,7 ,
+-1,
+Xkey_6,0 ,
+Xkey_6,1 ,
+Xkey_6,2 ,
+Xkey_6,3 ,
+Xkey_6,4 ,
+Xkey_6,5 ,
+Xkey_6,6 ,
+Xkey_6,7 ,
+-1,
+Xkey_7,0 ,
+Xkey_7,1 ,
+Xkey_7,2 ,
+Xkey_7,3 ,
+Xkey_7,4 ,
+Xkey_7,5 ,
+Xkey_7,6 ,
+Xkey_7,7 ,
+-1,
+Xkey_8,0 ,
+Xkey_8,1 ,
+Xkey_8,2 ,
+Xkey_8,3 ,
+Xkey_8,4 ,
+Xkey_8,5 ,
+Xkey_8,6 ,
+Xkey_8,7 ,
+-1,
+
+Xwind_n,0 ,
+Xwind_n,1 ,
+Xwind_n,2 ,
+Xwind_n,3 ,
+Xwind_n,4 ,
+Xwind_n,5 ,
+Xwind_n,6 ,
+Xwind_n,7 ,
+-1,
+Xwind_e,0 ,
+Xwind_e,1 ,
+Xwind_e,2 ,
+Xwind_e,3 ,
+Xwind_e,4 ,
+Xwind_e,5 ,
+Xwind_e,6 ,
+Xwind_e,7 ,
+-1,
+Xwind_s,0 ,
+Xwind_s,1 ,
+Xwind_s,2 ,
+Xwind_s,3 ,
+Xwind_s,4 ,
+Xwind_s,5 ,
+Xwind_s,6 ,
+Xwind_s,7 ,
+-1,
+Xwind_w,0 ,
+Xwind_w,1 ,
+Xwind_w,2 ,
+Xwind_w,3 ,
+Xwind_w,4 ,
+Xwind_w,5 ,
+Xwind_w,6 ,
+Xwind_w,7 ,
+-1,
+Xwind_nesw,0 ,
+Xwind_nesw,1 ,
+Xwind_nesw,2 ,
+Xwind_nesw,3 ,
+Xwind_nesw,4 ,
+Xwind_nesw,5 ,
+Xwind_nesw,6 ,
+Xwind_nesw,7 ,
+-1,
+Xwind_stop,0 ,
+Xwind_stop,1 ,
+Xwind_stop,2 ,
+Xwind_stop,3 ,
+Xwind_stop,4 ,
+Xwind_stop,5 ,
+Xwind_stop,6 ,
+Xwind_stop,7 ,
+-1,
+
+Xexit,0 ,
+Xexit,1 ,
+Xexit,2 ,
+Xexit,3 ,
+Xexit,4 ,
+Xexit,5 ,
+Xexit,6 ,
+Xexit,7 ,
+-1,
+Xexit_1,0 ,
+Xexit_1,1 ,
+Xexit_1,2 ,
+-1,
+Xexit_1,3 ,
+Xexit_1,4 ,
+Xexit_1,5 ,
+Xexit_3,7 ,
+Xexit_3,6 ,
+Xexit_3,5 ,
+-1,
+Xexit_1,6 ,
+Xexit_1,7 ,
+Xexit_2,0 ,
+Xexit_3,4 ,
+Xexit_3,3 ,
+Xexit_3,2 ,
+-1,
+Xexit_2,1 ,
+Xexit_2,2 ,
+Xexit_2,3 ,
+Xexit_3,1 ,
+Xexit_3,0 ,
+Xexit_2,7 ,
+-1,
+Xexit_2,4 ,
+Xexit_2,5 ,
+Xexit_2,6 ,
+-1,
+
+Ydynamite_eat,0 ,
+Ydynamite_eat,1 ,
+Ydynamite_eat,2 ,
+Xdynamite,0 ,
+Xdynamite,1 ,
+Xdynamite,2 ,
+Xdynamite,3 ,
+Xdynamite,4 ,
+Xdynamite,5 ,
+Xdynamite,6 ,
+Xdynamite,7 ,
+-1,
+Xdynamite_4,0 ,
+Xdynamite_4,1 ,
+Xdynamite_4,2 ,
+Xdynamite_4,3 ,
+Xdynamite_4,4 ,
+Xdynamite_4,5 ,
+Xdynamite_4,6 ,
+Xdynamite_4,7 ,
+-1,
+Xdynamite_3,0 ,
+Xdynamite_3,1 ,
+Xdynamite_3,2 ,
+Xdynamite_3,3 ,
+Xdynamite_3,4 ,
+Xdynamite_3,5 ,
+Xdynamite_3,6 ,
+Xdynamite_3,7 ,
+-1,
+Xdynamite_2,0 ,
+Xdynamite_2,1 ,
+Xdynamite_2,2 ,
+Xdynamite_2,3 ,
+Xdynamite_2,4 ,
+Xdynamite_2,5 ,
+Xdynamite_2,6 ,
+Xdynamite_2,7 ,
+-1,
+Xdynamite_1,0 ,
+Xdynamite_1,1 ,
+Xdynamite_1,2 ,
+Xdynamite_1,3 ,
+Xdynamite_1,4 ,
+Xdynamite_1,5 ,
+Xdynamite_1,6 ,
+Xdynamite_1,7 ,
+-1,
+
+Xbumper,0 ,
+Xbumper,1 ,
+Xbumper,2 ,
+Xbumper,3 ,
+Xbumper,4 ,
+Xbumper,5 ,
+Xbumper,6 ,
+Xbumper,7 ,
+XbumperB,0 ,
+XbumperB,7 ,
+-1,
+XbumperB,1 ,
+XbumperB,6 ,
+-1,
+XbumperB,2 ,
+XbumperB,5 ,
+-1,
+XbumperB,3 ,
+XbumperB,4 ,
+-1,
+
+Xwheel,0 ,
+Xwheel,1 ,
+Xwheel,2 ,
+Xwheel,3 ,
+Xwheel,4 ,
+Xwheel,5 ,
+Xwheel,6 ,
+Xwheel,7 ,
+XwheelB,7 ,
+XwheelB,6 ,
+XwheelB,5 ,
+XwheelB,4 ,
+-1,
+XwheelB,3 ,
+XwheelB,2 ,
+XwheelB,1 ,
+XwheelB,0 ,
+-1,
+
+XswitchB,0 ,
+XswitchB,1 ,
+XswitchB,2 ,
+XswitchB,3 ,
+XswitchB,4 ,
+XswitchB,5 ,
+XswitchB,6 ,
+XswitchB,7 ,
+-1,
+Xswitch,0 ,
+Xswitch,1 ,
+Xswitch,2 ,
+Xswitch,3 ,
+Xswitch,4 ,
+Xswitch,5 ,
+Xswitch,6 ,
+Xswitch,7 ,
+-1,
+
+Xsand,0 ,
+Xsand,1 ,
+Xsand,2 ,
+Xsand,3 ,
+Xsand,4 ,
+Xsand,5 ,
+Xsand,6 ,
+Xsand,7 ,
+Xsand_stone,0 ,
+Xsand_stone,1 ,
+Xsand_stone,2 ,
+Xsand_stone,3 ,
+Xsand_stone,4 ,
+Xsand_stone,5 ,
+Xsand_stone,6 ,
+Xsand_stone,7 ,
+Xsand_stonesand_1,0 ,
+Xsand_stonesand_1,1 ,
+Xsand_stonesand_1,2 ,
+Xsand_stonesand_1,3 ,
+Xsand_stonesand_1,4 ,
+Xsand_stonesand_1,5 ,
+Xsand_stonesand_1,6 ,
+Xsand_stonesand_1,7 ,
+Xsand_stonesand_2,0 ,
+Xsand_stonesand_2,1 ,
+Xsand_stonesand_2,2 ,
+Xsand_stonesand_2,3 ,
+Xsand_stonesand_2,4 ,
+Xsand_stonesand_2,5 ,
+Xsand_stonesand_2,6 ,
+Xsand_stonesand_2,7 ,
+Xsand_stonesand_3,0 ,
+Xsand_stonesand_3,1 ,
+Xsand_stonesand_3,2 ,
+Xsand_stonesand_3,3 ,
+Xsand_stonesand_3,4 ,
+Xsand_stonesand_3,5 ,
+Xsand_stonesand_3,6 ,
+Xsand_stonesand_3,7 ,
+Xsand_stonesand_4,0 ,
+Xsand_stonesand_4,1 ,
+Xsand_stonesand_4,2 ,
+Xsand_stonesand_4,3 ,
+Xsand_stonesand_4,4 ,
+Xsand_stonesand_4,5 ,
+Xsand_stonesand_4,6 ,
+Xsand_stonesand_4,7 ,
+Xsand_sandstone_1,0 ,
+Xsand_sandstone_1,1 ,
+Xsand_sandstone_1,2 ,
+Xsand_sandstone_1,3 ,
+Xsand_sandstone_1,4 ,
+Xsand_sandstone_1,5 ,
+Xsand_sandstone_1,6 ,
+Xsand_sandstone_1,7 ,
+Xsand_sandstone_2,0 ,
+Xsand_sandstone_2,1 ,
+Xsand_sandstone_2,2 ,
+Xsand_sandstone_2,3 ,
+Xsand_sandstone_2,4 ,
+Xsand_sandstone_2,5 ,
+Xsand_sandstone_2,6 ,
+Xsand_sandstone_2,7 ,
+Xsand_sandstone_3,0 ,
+Xsand_sandstone_3,1 ,
+Xsand_sandstone_3,2 ,
+Xsand_sandstone_3,3 ,
+Xsand_sandstone_3,4 ,
+Xsand_sandstone_3,5 ,
+Xsand_sandstone_3,6 ,
+Xsand_sandstone_3,7 ,
+Xsand_sandstone_4,0 ,
+Xsand_sandstone_4,1 ,
+Xsand_sandstone_4,2 ,
+Xsand_sandstone_4,3 ,
+Xsand_sandstone_4,4 ,
+Xsand_sandstone_4,5 ,
+Xsand_sandstone_4,6 ,
+Xsand_sandstone_4,7 ,
+-1,
+
+Xplant,0 ,
+Xplant,1 ,
+Xplant,2 ,
+Xplant,3 ,
+Xplant,4 ,
+Xplant,5 ,
+Xplant,6 ,
+Xplant,7 ,
+Yplant,0 ,
+Yplant,1 ,
+Yplant,2 ,
+Yplant,3 ,
+Yplant,4 ,
+Yplant,5 ,
+Yplant,6 ,
+Yplant,7 ,
+-1,
+
+Xlenses,0 ,
+Xlenses,1 ,
+Xlenses,2 ,
+Xlenses,3 ,
+Xlenses,4 ,
+Xlenses,5 ,
+Xlenses,6 ,
+Xlenses,7 ,
+-1,
+
+Xmagnify,0 ,
+Xmagnify,1 ,
+Xmagnify,2 ,
+Xmagnify,3 ,
+Xmagnify,4 ,
+Xmagnify,5 ,
+Xmagnify,6 ,
+Xmagnify,7 ,
+-1,
+
+XdripperB,0 ,
+XdripperB,1 ,
+XdripperB,2 ,
+XdripperB,3 ,
+XdripperB,4 ,
+XdripperB,5 ,
+XdripperB,6 ,
+XdripperB,7 ,
+-1,
+
+Xfake_blankB,0 ,
+Xfake_blankB,1 ,
+Xfake_blankB,2 ,
+Xfake_blankB,3 ,
+Xfake_blankB,4 ,
+Xfake_blankB,5 ,
+Xfake_blankB,6 ,
+Xfake_blankB,7 ,
+-1,
+
+Xfake_grassB,0 ,
+Xfake_grassB,1 ,
+Xfake_grassB,2 ,
+Xfake_grassB,3 ,
+Xfake_grassB,4 ,
+Xfake_grassB,5 ,
+Xfake_grassB,6 ,
+Xfake_grassB,7 ,
+-1,
+
+Xfake_door_1,0 ,
+Xfake_door_1,1 ,
+Xfake_door_1,2 ,
+Xfake_door_1,3 ,
+Xfake_door_1,4 ,
+Xfake_door_1,5 ,
+Xfake_door_1,6 ,
+Xfake_door_1,7 ,
+Xfake_door_2,0 ,
+Xfake_door_2,1 ,
+Xfake_door_2,2 ,
+Xfake_door_2,3 ,
+Xfake_door_2,4 ,
+Xfake_door_2,5 ,
+Xfake_door_2,6 ,
+Xfake_door_2,7 ,
+Xfake_door_3,0 ,
+Xfake_door_3,1 ,
+Xfake_door_3,2 ,
+Xfake_door_3,3 ,
+Xfake_door_3,4 ,
+Xfake_door_3,5 ,
+Xfake_door_3,6 ,
+Xfake_door_3,7 ,
+Xfake_door_4,0 ,
+Xfake_door_4,1 ,
+Xfake_door_4,2 ,
+Xfake_door_4,3 ,
+Xfake_door_4,4 ,
+Xfake_door_4,5 ,
+Xfake_door_4,6 ,
+Xfake_door_4,7 ,
+Xfake_door_5,0 ,
+Xfake_door_5,1 ,
+Xfake_door_5,2 ,
+Xfake_door_5,3 ,
+Xfake_door_5,4 ,
+Xfake_door_5,5 ,
+Xfake_door_5,6 ,
+Xfake_door_5,7 ,
+Xfake_door_6,0 ,
+Xfake_door_6,1 ,
+Xfake_door_6,2 ,
+Xfake_door_6,3 ,
+Xfake_door_6,4 ,
+Xfake_door_6,5 ,
+Xfake_door_6,6 ,
+Xfake_door_6,7 ,
+Xfake_door_7,0 ,
+Xfake_door_7,1 ,
+Xfake_door_7,2 ,
+Xfake_door_7,3 ,
+Xfake_door_7,4 ,
+Xfake_door_7,5 ,
+Xfake_door_7,6 ,
+Xfake_door_7,7 ,
+Xfake_door_8,0 ,
+Xfake_door_8,1 ,
+Xfake_door_8,2 ,
+Xfake_door_8,3 ,
+Xfake_door_8,4 ,
+Xfake_door_8,5 ,
+Xfake_door_8,6 ,
+Xfake_door_8,7 ,
+-1,
+
+Xsteel_1,0 ,
+Xsteel_1,1 ,
+Xsteel_1,2 ,
+Xsteel_1,3 ,
+Xsteel_1,4 ,
+Xsteel_1,5 ,
+Xsteel_1,6 ,
+Xsteel_1,7 ,
+-1,
+Xsteel_2,0 ,
+Xsteel_2,1 ,
+Xsteel_2,2 ,
+Xsteel_2,3 ,
+Xsteel_2,4 ,
+Xsteel_2,5 ,
+Xsteel_2,6 ,
+Xsteel_2,7 ,
+-1,
+Xsteel_3,0 ,
+Xsteel_3,1 ,
+Xsteel_3,2 ,
+Xsteel_3,3 ,
+Xsteel_3,4 ,
+Xsteel_3,5 ,
+Xsteel_3,6 ,
+Xsteel_3,7 ,
+-1,
+Xsteel_4,0 ,
+Xsteel_4,1 ,
+Xsteel_4,2 ,
+Xsteel_4,3 ,
+Xsteel_4,4 ,
+Xsteel_4,5 ,
+Xsteel_4,6 ,
+Xsteel_4,7 ,
+-1,
+Xwall_1,0 ,
+Xwall_1,1 ,
+Xwall_1,2 ,
+Xwall_1,3 ,
+Xwall_1,4 ,
+Xwall_1,5 ,
+Xwall_1,6 ,
+Xwall_1,7 ,
+-1,
+Xwall_2,0 ,
+Xwall_2,1 ,
+Xwall_2,2 ,
+Xwall_2,3 ,
+Xwall_2,4 ,
+Xwall_2,5 ,
+Xwall_2,6 ,
+Xwall_2,7 ,
+-1,
+Xwall_3,0 ,
+Xwall_3,1 ,
+Xwall_3,2 ,
+Xwall_3,3 ,
+Xwall_3,4 ,
+Xwall_3,5 ,
+Xwall_3,6 ,
+Xwall_3,7 ,
+-1,
+Xwall_4,0 ,
+Xwall_4,1 ,
+Xwall_4,2 ,
+Xwall_4,3 ,
+Xwall_4,4 ,
+Xwall_4,5 ,
+Xwall_4,6 ,
+Xwall_4,7 ,
+-1,
+Xround_wall_1,0 ,
+Xround_wall_1,1 ,
+Xround_wall_1,2 ,
+Xround_wall_1,3 ,
+Xround_wall_1,4 ,
+Xround_wall_1,5 ,
+Xround_wall_1,6 ,
+Xround_wall_1,7 ,
+-1,
+Xround_wall_2,0 ,
+Xround_wall_2,1 ,
+Xround_wall_2,2 ,
+Xround_wall_2,3 ,
+Xround_wall_2,4 ,
+Xround_wall_2,5 ,
+Xround_wall_2,6 ,
+Xround_wall_2,7 ,
+-1,
+Xround_wall_3,0 ,
+Xround_wall_3,1 ,
+Xround_wall_3,2 ,
+Xround_wall_3,3 ,
+Xround_wall_3,4 ,
+Xround_wall_3,5 ,
+Xround_wall_3,6 ,
+Xround_wall_3,7 ,
+-1,
+Xround_wall_4,0 ,
+Xround_wall_4,1 ,
+Xround_wall_4,2 ,
+Xround_wall_4,3 ,
+Xround_wall_4,4 ,
+Xround_wall_4,5 ,
+Xround_wall_4,6 ,
+Xround_wall_4,7 ,
+-1,
+Xdecor_1,0 ,
+Xdecor_1,1 ,
+Xdecor_1,2 ,
+Xdecor_1,3 ,
+Xdecor_1,4 ,
+Xdecor_1,5 ,
+Xdecor_1,6 ,
+Xdecor_1,7 ,
+-1,
+Xdecor_2,0 ,
+Xdecor_2,1 ,
+Xdecor_2,2 ,
+Xdecor_2,3 ,
+Xdecor_2,4 ,
+Xdecor_2,5 ,
+Xdecor_2,6 ,
+Xdecor_2,7 ,
+-1,
+Xdecor_3,0 ,
+Xdecor_3,1 ,
+Xdecor_3,2 ,
+Xdecor_3,3 ,
+Xdecor_3,4 ,
+Xdecor_3,5 ,
+Xdecor_3,6 ,
+Xdecor_3,7 ,
+-1,
+Xdecor_4,0 ,
+Xdecor_4,1 ,
+Xdecor_4,2 ,
+Xdecor_4,3 ,
+Xdecor_4,4 ,
+Xdecor_4,5 ,
+Xdecor_4,6 ,
+Xdecor_4,7 ,
+-1,
+Xdecor_5,0 ,
+Xdecor_5,1 ,
+Xdecor_5,2 ,
+Xdecor_5,3 ,
+Xdecor_5,4 ,
+Xdecor_5,5 ,
+Xdecor_5,6 ,
+Xdecor_5,7 ,
+-1,
+Xdecor_6,0 ,
+Xdecor_6,1 ,
+Xdecor_6,2 ,
+Xdecor_6,3 ,
+Xdecor_6,4 ,
+Xdecor_6,5 ,
+Xdecor_6,6 ,
+Xdecor_6,7 ,
+-1,
+Xdecor_7,0 ,
+Xdecor_7,1 ,
+Xdecor_7,2 ,
+Xdecor_7,3 ,
+Xdecor_7,4 ,
+Xdecor_7,5 ,
+Xdecor_7,6 ,
+Xdecor_7,7 ,
+-1,
+Xdecor_8,0 ,
+Xdecor_8,1 ,
+Xdecor_8,2 ,
+Xdecor_8,3 ,
+Xdecor_8,4 ,
+Xdecor_8,5 ,
+Xdecor_8,6 ,
+Xdecor_8,7 ,
+-1,
+Xdecor_9,0 ,
+Xdecor_9,1 ,
+Xdecor_9,2 ,
+Xdecor_9,3 ,
+Xdecor_9,4 ,
+Xdecor_9,5 ,
+Xdecor_9,6 ,
+Xdecor_9,7 ,
+-1,
+Xdecor_10,0 ,
+Xdecor_10,1 ,
+Xdecor_10,2 ,
+Xdecor_10,3 ,
+Xdecor_10,4 ,
+Xdecor_10,5 ,
+Xdecor_10,6 ,
+Xdecor_10,7 ,
+-1,
+Xdecor_11,0 ,
+Xdecor_11,1 ,
+Xdecor_11,2 ,
+Xdecor_11,3 ,
+Xdecor_11,4 ,
+Xdecor_11,5 ,
+Xdecor_11,6 ,
+Xdecor_11,7 ,
+-1,
+Xdecor_12,0 ,
+Xdecor_12,1 ,
+Xdecor_12,2 ,
+Xdecor_12,3 ,
+Xdecor_12,4 ,
+Xdecor_12,5 ,
+Xdecor_12,6 ,
+Xdecor_12,7 ,
+-1,
+Xalpha_excla,0 ,
+Xalpha_excla,1 ,
+Xalpha_excla,2 ,
+Xalpha_excla,3 ,
+Xalpha_excla,4 ,
+Xalpha_excla,5 ,
+Xalpha_excla,6 ,
+Xalpha_excla,7 ,
+-1,
+Xalpha_quote,0 ,
+Xalpha_quote,1 ,
+Xalpha_quote,2 ,
+Xalpha_quote,3 ,
+Xalpha_quote,4 ,
+Xalpha_quote,5 ,
+Xalpha_quote,6 ,
+Xalpha_quote,7 ,
+-1,
+Xalpha_comma,0 ,
+Xalpha_comma,1 ,
+Xalpha_comma,2 ,
+Xalpha_comma,3 ,
+Xalpha_comma,4 ,
+Xalpha_comma,5 ,
+Xalpha_comma,6 ,
+Xalpha_comma,7 ,
+-1,
+Xalpha_minus,0 ,
+Xalpha_minus,1 ,
+Xalpha_minus,2 ,
+Xalpha_minus,3 ,
+Xalpha_minus,4 ,
+Xalpha_minus,5 ,
+Xalpha_minus,6 ,
+Xalpha_minus,7 ,
+-1,
+Xalpha_perio,0 ,
+Xalpha_perio,1 ,
+Xalpha_perio,2 ,
+Xalpha_perio,3 ,
+Xalpha_perio,4 ,
+Xalpha_perio,5 ,
+Xalpha_perio,6 ,
+Xalpha_perio,7 ,
+-1,
+Xalpha_0,0 ,
+Xalpha_0,1 ,
+Xalpha_0,2 ,
+Xalpha_0,3 ,
+Xalpha_0,4 ,
+Xalpha_0,5 ,
+Xalpha_0,6 ,
+Xalpha_0,7 ,
+-1,
+Xalpha_1,0 ,
+Xalpha_1,1 ,
+Xalpha_1,2 ,
+Xalpha_1,3 ,
+Xalpha_1,4 ,
+Xalpha_1,5 ,
+Xalpha_1,6 ,
+Xalpha_1,7 ,
+-1,
+Xalpha_2,0 ,
+Xalpha_2,1 ,
+Xalpha_2,2 ,
+Xalpha_2,3 ,
+Xalpha_2,4 ,
+Xalpha_2,5 ,
+Xalpha_2,6 ,
+Xalpha_2,7 ,
+-1,
+Xalpha_3,0 ,
+Xalpha_3,1 ,
+Xalpha_3,2 ,
+Xalpha_3,3 ,
+Xalpha_3,4 ,
+Xalpha_3,5 ,
+Xalpha_3,6 ,
+Xalpha_3,7 ,
+-1,
+Xalpha_4,0 ,
+Xalpha_4,1 ,
+Xalpha_4,2 ,
+Xalpha_4,3 ,
+Xalpha_4,4 ,
+Xalpha_4,5 ,
+Xalpha_4,6 ,
+Xalpha_4,7 ,
+-1,
+Xalpha_5,0 ,
+Xalpha_5,1 ,
+Xalpha_5,2 ,
+Xalpha_5,3 ,
+Xalpha_5,4 ,
+Xalpha_5,5 ,
+Xalpha_5,6 ,
+Xalpha_5,7 ,
+-1,
+Xalpha_6,0 ,
+Xalpha_6,1 ,
+Xalpha_6,2 ,
+Xalpha_6,3 ,
+Xalpha_6,4 ,
+Xalpha_6,5 ,
+Xalpha_6,6 ,
+Xalpha_6,7 ,
+-1,
+Xalpha_7,0 ,
+Xalpha_7,1 ,
+Xalpha_7,2 ,
+Xalpha_7,3 ,
+Xalpha_7,4 ,
+Xalpha_7,5 ,
+Xalpha_7,6 ,
+Xalpha_7,7 ,
+-1,
+Xalpha_8,0 ,
+Xalpha_8,1 ,
+Xalpha_8,2 ,
+Xalpha_8,3 ,
+Xalpha_8,4 ,
+Xalpha_8,5 ,
+Xalpha_8,6 ,
+Xalpha_8,7 ,
+-1,
+Xalpha_9,0 ,
+Xalpha_9,1 ,
+Xalpha_9,2 ,
+Xalpha_9,3 ,
+Xalpha_9,4 ,
+Xalpha_9,5 ,
+Xalpha_9,6 ,
+Xalpha_9,7 ,
+-1,
+Xalpha_colon,0 ,
+Xalpha_colon,1 ,
+Xalpha_colon,2 ,
+Xalpha_colon,3 ,
+Xalpha_colon,4 ,
+Xalpha_colon,5 ,
+Xalpha_colon,6 ,
+Xalpha_colon,7 ,
+-1,
+Xalpha_arrow_w,0 ,
+Xalpha_arrow_w,1 ,
+Xalpha_arrow_w,2 ,
+Xalpha_arrow_w,3 ,
+Xalpha_arrow_w,4 ,
+Xalpha_arrow_w,5 ,
+Xalpha_arrow_w,6 ,
+Xalpha_arrow_w,7 ,
+-1,
+Xalpha_arrow_e,0 ,
+Xalpha_arrow_e,1 ,
+Xalpha_arrow_e,2 ,
+Xalpha_arrow_e,3 ,
+Xalpha_arrow_e,4 ,
+Xalpha_arrow_e,5 ,
+Xalpha_arrow_e,6 ,
+Xalpha_arrow_e,7 ,
+-1,
+Xalpha_quest,0 ,
+Xalpha_quest,1 ,
+Xalpha_quest,2 ,
+Xalpha_quest,3 ,
+Xalpha_quest,4 ,
+Xalpha_quest,5 ,
+Xalpha_quest,6 ,
+Xalpha_quest,7 ,
+-1,
+Xalpha_a,0 ,
+Xalpha_a,1 ,
+Xalpha_a,2 ,
+Xalpha_a,3 ,
+Xalpha_a,4 ,
+Xalpha_a,5 ,
+Xalpha_a,6 ,
+Xalpha_a,7 ,
+-1,
+Xalpha_b,0 ,
+Xalpha_b,1 ,
+Xalpha_b,2 ,
+Xalpha_b,3 ,
+Xalpha_b,4 ,
+Xalpha_b,5 ,
+Xalpha_b,6 ,
+Xalpha_b,7 ,
+-1,
+Xalpha_c,0 ,
+Xalpha_c,1 ,
+Xalpha_c,2 ,
+Xalpha_c,3 ,
+Xalpha_c,4 ,
+Xalpha_c,5 ,
+Xalpha_c,6 ,
+Xalpha_c,7 ,
+-1,
+Xalpha_d,0 ,
+Xalpha_d,1 ,
+Xalpha_d,2 ,
+Xalpha_d,3 ,
+Xalpha_d,4 ,
+Xalpha_d,5 ,
+Xalpha_d,6 ,
+Xalpha_d,7 ,
+-1,
+Xalpha_e,0 ,
+Xalpha_e,1 ,
+Xalpha_e,2 ,
+Xalpha_e,3 ,
+Xalpha_e,4 ,
+Xalpha_e,5 ,
+Xalpha_e,6 ,
+Xalpha_e,7 ,
+-1,
+Xalpha_f,0 ,
+Xalpha_f,1 ,
+Xalpha_f,2 ,
+Xalpha_f,3 ,
+Xalpha_f,4 ,
+Xalpha_f,5 ,
+Xalpha_f,6 ,
+Xalpha_f,7 ,
+-1,
+Xalpha_g,0 ,
+Xalpha_g,1 ,
+Xalpha_g,2 ,
+Xalpha_g,3 ,
+Xalpha_g,4 ,
+Xalpha_g,5 ,
+Xalpha_g,6 ,
+Xalpha_g,7 ,
+-1,
+Xalpha_h,0 ,
+Xalpha_h,1 ,
+Xalpha_h,2 ,
+Xalpha_h,3 ,
+Xalpha_h,4 ,
+Xalpha_h,5 ,
+Xalpha_h,6 ,
+Xalpha_h,7 ,
+-1,
+Xalpha_i,0 ,
+Xalpha_i,1 ,
+Xalpha_i,2 ,
+Xalpha_i,3 ,
+Xalpha_i,4 ,
+Xalpha_i,5 ,
+Xalpha_i,6 ,
+Xalpha_i,7 ,
+-1,
+Xalpha_j,0 ,
+Xalpha_j,1 ,
+Xalpha_j,2 ,
+Xalpha_j,3 ,
+Xalpha_j,4 ,
+Xalpha_j,5 ,
+Xalpha_j,6 ,
+Xalpha_j,7 ,
+-1,
+Xalpha_k,0 ,
+Xalpha_k,1 ,
+Xalpha_k,2 ,
+Xalpha_k,3 ,
+Xalpha_k,4 ,
+Xalpha_k,5 ,
+Xalpha_k,6 ,
+Xalpha_k,7 ,
+-1,
+Xalpha_l,0 ,
+Xalpha_l,1 ,
+Xalpha_l,2 ,
+Xalpha_l,3 ,
+Xalpha_l,4 ,
+Xalpha_l,5 ,
+Xalpha_l,6 ,
+Xalpha_l,7 ,
+-1,
+Xalpha_m,0 ,
+Xalpha_m,1 ,
+Xalpha_m,2 ,
+Xalpha_m,3 ,
+Xalpha_m,4 ,
+Xalpha_m,5 ,
+Xalpha_m,6 ,
+Xalpha_m,7 ,
+-1,
+Xalpha_n,0 ,
+Xalpha_n,1 ,
+Xalpha_n,2 ,
+Xalpha_n,3 ,
+Xalpha_n,4 ,
+Xalpha_n,5 ,
+Xalpha_n,6 ,
+Xalpha_n,7 ,
+-1,
+Xalpha_o,0 ,
+Xalpha_o,1 ,
+Xalpha_o,2 ,
+Xalpha_o,3 ,
+Xalpha_o,4 ,
+Xalpha_o,5 ,
+Xalpha_o,6 ,
+Xalpha_o,7 ,
+-1,
+Xalpha_p,0 ,
+Xalpha_p,1 ,
+Xalpha_p,2 ,
+Xalpha_p,3 ,
+Xalpha_p,4 ,
+Xalpha_p,5 ,
+Xalpha_p,6 ,
+Xalpha_p,7 ,
+-1,
+Xalpha_q,0 ,
+Xalpha_q,1 ,
+Xalpha_q,2 ,
+Xalpha_q,3 ,
+Xalpha_q,4 ,
+Xalpha_q,5 ,
+Xalpha_q,6 ,
+Xalpha_q,7 ,
+-1,
+Xalpha_r,0 ,
+Xalpha_r,1 ,
+Xalpha_r,2 ,
+Xalpha_r,3 ,
+Xalpha_r,4 ,
+Xalpha_r,5 ,
+Xalpha_r,6 ,
+Xalpha_r,7 ,
+-1,
+Xalpha_s,0 ,
+Xalpha_s,1 ,
+Xalpha_s,2 ,
+Xalpha_s,3 ,
+Xalpha_s,4 ,
+Xalpha_s,5 ,
+Xalpha_s,6 ,
+Xalpha_s,7 ,
+-1,
+Xalpha_t,0 ,
+Xalpha_t,1 ,
+Xalpha_t,2 ,
+Xalpha_t,3 ,
+Xalpha_t,4 ,
+Xalpha_t,5 ,
+Xalpha_t,6 ,
+Xalpha_t,7 ,
+-1,
+Xalpha_u,0 ,
+Xalpha_u,1 ,
+Xalpha_u,2 ,
+Xalpha_u,3 ,
+Xalpha_u,4 ,
+Xalpha_u,5 ,
+Xalpha_u,6 ,
+Xalpha_u,7 ,
+-1,
+Xalpha_v,0 ,
+Xalpha_v,1 ,
+Xalpha_v,2 ,
+Xalpha_v,3 ,
+Xalpha_v,4 ,
+Xalpha_v,5 ,
+Xalpha_v,6 ,
+Xalpha_v,7 ,
+-1,
+Xalpha_w,0 ,
+Xalpha_w,1 ,
+Xalpha_w,2 ,
+Xalpha_w,3 ,
+Xalpha_w,4 ,
+Xalpha_w,5 ,
+Xalpha_w,6 ,
+Xalpha_w,7 ,
+-1,
+Xalpha_x,0 ,
+Xalpha_x,1 ,
+Xalpha_x,2 ,
+Xalpha_x,3 ,
+Xalpha_x,4 ,
+Xalpha_x,5 ,
+Xalpha_x,6 ,
+Xalpha_x,7 ,
+-1,
+Xalpha_y,0 ,
+Xalpha_y,1 ,
+Xalpha_y,2 ,
+Xalpha_y,3 ,
+Xalpha_y,4 ,
+Xalpha_y,5 ,
+Xalpha_y,6 ,
+Xalpha_y,7 ,
+-1,
+Xalpha_z,0 ,
+Xalpha_z,1 ,
+Xalpha_z,2 ,
+Xalpha_z,3 ,
+Xalpha_z,4 ,
+Xalpha_z,5 ,
+Xalpha_z,6 ,
+Xalpha_z,7 ,
+-1,
+Xalpha_copyr,0 ,
+Xalpha_copyr,1 ,
+Xalpha_copyr,2 ,
+Xalpha_copyr,3 ,
+Xalpha_copyr,4 ,
+Xalpha_copyr,5 ,
+Xalpha_copyr,6 ,
+Xalpha_copyr,7 ,
+-1,
+
+Yball_eat,7 ,
+Yball_eat,6 ,
+Yball_eat,5 ,
+Xboom_2,7 ,
+Xboom_2,6 ,
+Xboom_2,5 ,
+-1,
+Yball_eat,4 ,
+Yball_eat,3 ,
+Yball_eat,2 ,
+Xboom_2,4 ,
+Xboom_2,3 ,
+Xboom_2,2 ,
+-1,
+Yball_eat,1 ,
+Yball_eat,0 ,
+Xboom_2,1 ,
+Xboom_2,0 ,
+Xboom_1,7 ,
+-1,
+Xboom_1,6 ,
+Xboom_1,5 ,
+Xboom_android,7 ,
+-1,
+Xboom_1,4 ,
+Xboom_1,3 ,
+Xboom_bug,4 ,
+Xboom_bomb,4 ,
+Xboom_bug,3 ,
+Xboom_bomb,3 ,
+-1,
+Xboom_1,2 ,
+Xboom_1,1 ,
+Xboom_bug,6 ,
+Xboom_bomb,6 ,
+Xboom_bug,5 ,
+Xboom_bomb,5 ,
+Xboom_bug,2 ,
+Xboom_bomb,2 ,
+Xboom_bug,1 ,
+Xboom_bomb,1 ,
+-1,
+Xboom_bug,0 ,
+Xboom_bug,7 ,
+Xboom_bomb,0 ,
+Xboom_bomb,7 ,
+Xboom_1,0 ,
+Ybug_stone,7 ,
+Ybug_spring,7 ,
+Ytank_stone,7 ,
+Ytank_spring,7 ,
+Yeater_stone,7 ,
+Yeater_spring,7 ,
+Yalien_stone,7 ,
+Yalien_spring,7 ,
+Ybomb_eat,7 ,
+-1
+};
+
+int spr_map[] = {
+SPR_walk+0,0, 0,1,2,3,4,5,6,7,
+SPR_walk+1,0, 8,9,10,11,12,13,14,15,
+SPR_walk+2,0, 16,17,18,19,20,21,22,23,
+SPR_walk+3,0, 24,25,26,27,28,29,30,31,
+SPR_push+0,0, 32,33,34,35,36,35,34,33,
+SPR_push+1,0, 37,38,39,40,41,40,39,38,
+SPR_push+2,0, 42,43,44,45,46,45,44,43,
+SPR_push+3,0, 47,48,49,50,51,50,49,48,
+SPR_spray+0,0, 52,52,52,52,52,52,52,52,
+SPR_spray+1,0, 53,53,53,53,53,53,53,53,
+SPR_spray+2,0, 54,54,54,54,54,54,54,54,
+SPR_spray+3,0, 55,55,55,55,55,55,55,55,
+SPR_walk+0,1, 56,57,58,59,60,61,62,63,
+SPR_walk+1,1, 64,65,66,67,68,69,70,71,
+SPR_walk+2,1, 72,73,74,75,76,77,78,79,
+SPR_walk+3,1, 80,81,82,83,84,85,86,87,
+SPR_push+0,1, 88,89,90,91,92,91,90,89,
+SPR_push+1,1, 93,94,95,96,97,96,95,94,
+SPR_push+2,1, 98,99,100,101,102,101,100,99,
+SPR_push+3,1, 103,104,105,106,107,106,105,104,
+SPR_spray+0,1, 108,108,108,108,108,108,108,108,
+SPR_spray+1,1, 109,109,109,109,109,109,109,109,
+SPR_spray+2,1, 110,110,110,110,110,110,110,110,
+SPR_spray+3,1, 111,111,111,111,111,111,111,111,
+SPR_still,0, 112,112,112,112,112,112,112,112,
+SPR_still,1, 113,113,113,113,113,113,113,113,
+SPR_MAX
+};
+
+int ttl_map[] = {
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
+-1,0,-1,-1,-1,-1,-1,1,-1,-1,-1,-1,2,3,4,-1,      /* !',-. */
+5,6,7,8,9,10,11,12,13,14,15,-1,-1,-1,-1,16,      /* 0123456789:? */
+-1,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, /* ABCDEFGHIJKLMNO */
+32,33,34,35,36,37,38,39,40,41,42,-1,-1,-1,-1,-1, /* PQRSTUVWXYZ */
+-1,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, /* abcdefghijklmno */
+32,33,34,35,36,37,38,39,40,41,42,-1,-1,-1,-1,-1  /* pqrstuvwxyz */
+};
+
+/* ---------------------------------------------------------------------- */
+
+#if 0
+
+/* quick and dirty code to format the data semi nicely */
+
+void print_buffer(int *buffer, int count)
+{
+       int i,j;
+       j = 0;
+       for(i = 0; i < count;) {
+               if(j > 80) { j=0; printf("\n"); }
+               if(j == 0) printf("\t");
+               j += printf("%d", buffer[i]);
+               j += printf("%s", ++i == count ? "" : ",");
+       }
+       if(j) printf("\n");
+}
+void print_tab(int *invert, char *varname, char *comment)
+{
+       int i;
+       int buffer[TILE_MAX];
+
+       for(i = 0; i < TILE_MAX; i++) buffer[i] = 0;
+       for(;invert[0] < TILE_MAX; invert += 2) buffer[invert[0]] = invert[1];
+
+       printf("/* %s */\n", comment);
+       printf("const unsigned char %s[%d] = {\n", varname, TILE_MAX);
+       print_buffer(buffer, TILE_MAX);
+       printf("};\n");
+}
+void print_explode(void)
+{
+       int i;
+       int *tile = tile_explode;
+       int buffer[TILE_MAX];
+
+       for(i = 0; i < TILE_MAX; i++) buffer[i] = Xboom_1;
+       while((i = *tile++) < TILE_MAX) buffer[i] = i; /* these tiles are indestructable */
+       while((i = *tile++) < TILE_MAX) buffer[i] = *tile++; /* these tiles are special */
+
+       printf("/* normal explosion */\n");
+       printf("const unsigned short tab_explode_normal[%d] = {\n", TILE_MAX);
+       print_buffer(buffer, TILE_MAX);
+       printf("};\n");
+
+       while((i = *tile++) < TILE_MAX) buffer[i] = *tile++; /* these tiles for dynamite */
+
+       printf("/* dynamite explosion */\n");
+       printf("const unsigned short tab_explode_dynamite[%d] = {\n", TILE_MAX);
+       print_buffer(buffer, TILE_MAX);
+       printf("};\n");
+}
+void print_obj(void)
+{
+       int i,j;
+       int *map = obj_map;
+       int buffer[8][TILE_MAX];
+
+#if 0
+       int debug=0;
+       for(i = 0; i < 8; i++) for(j = 0; j < TILE_MAX; j++) buffer[i][j] = 0;
+       for(i = 0; i < 64; i++) {
+               for(;*map != -1; map += 2) {
+                       if(map[0] < 0 || map[0] >= TILE_MAX || map[1] < 0 || map[1] >= 8) { fprintf(stderr, "obj_map: bad tile (%d,%d) @ %d+%d\n", map[0], map[1], i / 16, i % 16); debug = 1; continue; }
+                       buffer[map[1]][map[0]]++;
+               }
+               map++;
+       }
+       for(i = 0; i < 896; i++) {
+               for(;*map != -1; map += 2) {
+                       if(map[0] < 0 || map[0] >= TILE_MAX || map[1] < 0 || map[1] >= 8) { fprintf(stderr, "obj_map: bad tile (%d,%d) @ %d\n", map[0], map[1], i); debug = 1; continue; }
+                       buffer[map[1]][map[0]]++;
+               }
+               map++;
+       }
+       for(i = 0; i < TILE_MAX; i++) for(j = 0; j < 8; j++) {
+               switch(buffer[j][i]) {
+               case 0: fprintf(stderr, "obj_map: uninitialized (%d,%d)\n", i, j); debug = 1; break;
+               case 1: break; /* good */
+               default: fprintf(stderr, "obj_map: duplicate (%d,%d)\n", i, j); debug = 1; break;
+               }
+       }
+       if(sizeof(obj_map) / sizeof(*obj_map) != map - obj_map) { fprintf(stderr, "obj_map: bad end (%d != %d)\n", sizeof(obj_map) / sizeof(*obj_map), map - obj_map); debug = 1; }
+       if(debug == 0) fprintf(stderr, "obj_map: looks good, now disable debug code\n");
+       abort();
+#else
+
+       for(i = 0; i < 8; i++) for(j = 0; j < TILE_MAX; j++) buffer[i][j] = Xblank;
+
+/* special case for first 64 entries */
+       for(i = 0; i < 64; i++) {
+               for(;*map != -1; map += 2) buffer[map[1]][map[0]] = i;
+               map++;
+       }
+
+/* now regular entries */
+       for(i = 0; i < 896 * 16; i += 16) {
+               for(;*map != -1; map += 2) buffer[map[1]][map[0]] = i;
+               map++;
+       }
+
+       printf("/* map tiles to coords */\n");
+       printf("const unsigned short map_obj[8][%d] = {\n", TILE_MAX);
+       for(i = 0; i < 8;) {
+               printf("{\n");
+               print_buffer(buffer[7 - i], TILE_MAX);
+               printf("}%s", ++i == 8 ? "\n" : ",");
+       }
+       printf("};\n");
+#endif
+}
+void print_spr(void)
+{
+       int i,j,k;
+       int *map = spr_map;
+       int buffer[2][8][SPR_MAX];
+
+       while(*map < SPR_MAX) {
+               i = *map++;
+               j = *map++;
+               for(k = 0; k < 8; k++) buffer[j][k][i] = *map++;
+       }
+
+       printf("/* map sprites to coords */\n");
+       printf("const unsigned short map_spr[2][8][%d] = {\n", SPR_MAX);
+       for(i = 0; i < 2;) {
+               printf("{\n");
+               for(j = 0; j < 8;) {
+                       printf("\t{ ");
+                       for(k = 0; k < SPR_MAX;) {
+                               printf("%d", buffer[i][7 - j][k]);
+                               printf("%s", ++k == SPR_MAX ? "" : ",");
+                       }
+                       printf(" }%s\n", ++j == 8 ? "" : ",");
+               }
+               printf("}%s", ++i == 2 ? "\n" : ",");
+       }
+       printf("};\n");
+}
+void print_ttl(void)
+{
+       int i,j,k;
+       int buffer[128];
+
+       for(i = 0; i < 128; i++) {
+               if(ttl_map[i] == -1) {
+                       buffer[i] = -1;
+               } else {
+                       j = (ttl_map[i] % 22) * 14;
+                       k = (ttl_map[i] / 22);
+                       buffer[i] = k * 320 + j;
+               }
+       }
+       printf("/* map ascii to coords */\n");
+       printf("const unsigned short map_ttl[128] = {\n");
+       print_buffer(buffer, 128);
+       printf("};\n");
+}
+int main_OLD(void)
+{
+       printf("/* THIS FILE AUTOMATICALLY GENERATED */\n\n");
+       print_tab(tile_blank, "tab_blank", "0=stop 1=blank");
+       print_tab(tile_acid, "tab_acid", "0=stop 1=acid");
+       print_tab(tile_ameuba, "tab_ameuba", "0=stop 1=ameuba");
+       print_tab(tile_android_move, "tab_android_move", "0=stop 1=move");
+       print_explode();
+       print_obj();
+       print_spr();
+       print_ttl();
+       return(0);
+}
+
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+/* 0=stop 1=blank */
+unsigned char tab_blank[TILE_MAX];
+
+/* 0=stop 1=acid */
+unsigned char tab_acid[TILE_MAX];
+
+/* 0=stop 1=ameuba */
+unsigned char tab_ameuba[TILE_MAX];
+
+/* 0=stop 1=move */
+unsigned char tab_android_move[TILE_MAX];
+
+/* normal explosion */
+unsigned short tab_explode_normal[TILE_MAX];
+
+/* dynamite explosion */
+unsigned short tab_explode_dynamite[TILE_MAX];
+
+/* map tiles to coords */
+unsigned short map_obj[8][TILE_MAX];
+
+/* map sprites to coords */
+unsigned short map_spr[2][8][13];
+
+/* map ascii to coords */
+unsigned short map_ttl[128];
+
+void create_tab(int *invert, unsigned char *array)
+{
+  int i;
+  int buffer[TILE_MAX];
+
+  for(i = 0; i < TILE_MAX; i++)
+    buffer[i] = 0;
+
+  for(;invert[0] < TILE_MAX; invert += 2)
+    buffer[invert[0]] = invert[1];
+
+  for(i = 0; i < TILE_MAX; i++)
+    array[i] = buffer[i];
+}
+
+void create_explode()
+{
+  int i;
+  int *tile = tile_explode;
+  int buffer[TILE_MAX];
+
+  for(i = 0; i < TILE_MAX; i++)
+    buffer[i] = Xboom_1;
+  while((i = *tile++) < TILE_MAX)
+    buffer[i] = i;                     /* these tiles are indestructable */
+  while((i = *tile++) < TILE_MAX)
+    buffer[i] = *tile++;               /* these tiles are special */
+
+  for(i = 0; i < TILE_MAX; i++)
+    tab_explode_normal[i] = buffer[i];
+
+  while((i = *tile++) < TILE_MAX)
+    buffer[i] = *tile++;               /* these tiles for dynamite */
+
+  for(i = 0; i < TILE_MAX; i++)
+    tab_explode_dynamite[i] = buffer[i];
+}
+
+void create_obj()
+{
+  int i, j;
+  int *map = obj_map;
+  int buffer[8][TILE_MAX];
+
+#if 0
+
+  int debug = 0;
+  for(i = 0; i < 8; i++)
+    for(j = 0; j < TILE_MAX; j++)
+      buffer[i][j] = 0;
+  for(i = 0; i < 64; i++)
+  {
+    for(;*map != -1; map += 2)
+    {
+      if (map[0] < 0 || map[0] >= TILE_MAX || map[1] < 0 || map[1] >= 8)
+      {
+       fprintf(stderr, "obj_map: bad tile (%d,%d) @ %d+%d\n",
+               map[0], map[1], i / 16, i % 16);
+       debug = 1;
+       continue;
+      }
+      buffer[map[1]][map[0]]++;
+    }
+    map++;
+  }
+  for(i = 0; i < 896; i++)
+  {
+    for(;*map != -1; map += 2)
+    {
+      if (map[0] < 0 || map[0] >= TILE_MAX || map[1] < 0 || map[1] >= 8)
+      {
+       fprintf(stderr, "obj_map: bad tile (%d,%d) @ %d\n", map[0], map[1], i);
+       debug = 1;
+       continue;
+      }
+      buffer[map[1]][map[0]]++;
+    }
+    map++;
+  }
+  for(i = 0; i < TILE_MAX; i++)
+  {
+    for(j = 0; j < 8; j++)
+    {
+      switch(buffer[j][i])
+      {
+        case 0:
+         fprintf(stderr, "obj_map: uninitialized (%d,%d)\n", i, j);
+         debug = 1;
+         break;
+        case 1:
+         break; /* good */
+        default:
+         fprintf(stderr, "obj_map: duplicate (%d,%d)\n", i, j);
+         debug = 1;
+         break;
+      }
+    }
+  }
+
+  if(sizeof(obj_map) / sizeof(*obj_map) != map - obj_map)
+  {
+    fprintf(stderr, "obj_map: bad end (%d != %d)\n",
+           sizeof(obj_map) / sizeof(*obj_map), map - obj_map);
+    debug = 1;
+  }
+  if(debug == 0)
+    fprintf(stderr, "obj_map: looks good, now disable debug code\n");
+  abort();
+
+#else
+
+  for(i = 0; i < 8; i++)
+    for(j = 0; j < TILE_MAX; j++)
+      buffer[i][j] = Xblank;
+
+  /* special case for first 64 entries */
+  for(i = 0; i < 64; i++)
+  {
+    for(;*map != -1; map += 2)
+      buffer[map[1]][map[0]] = i;
+    map++;
+  }
+
+  /* now regular entries */
+  for(i = 0; i < 896 * 16; i += 16)
+  {
+    for(;*map != -1; map += 2)
+      buffer[map[1]][map[0]] = i;
+    map++;
+  }
+
+  for(i = 0; i < 8; i++)
+    for(j = 0; j < TILE_MAX; j++)
+      map_obj[i][j] = buffer[7 - i][j];
+
+#endif
+}
+
+void create_spr()
+{
+  int i, j, k;
+  int *map = spr_map;
+  int buffer[2][8][SPR_MAX];
+
+  while(*map < SPR_MAX)
+  {
+    i = *map++;
+    j = *map++;
+    for(k = 0; k < 8; k++)
+      buffer[j][k][i] = *map++;
+  }
+
+  for(i = 0; i < 2; i++)
+    for(j = 0; j < 8; j++)
+      for(k = 0; k < SPR_MAX; k++)
+       map_spr[i][j][k] = buffer[i][7 - j][k];
+}
+
+void create_ttl()
+{
+  int i, j, k;
+  int buffer[128];
+
+  for(i = 0; i < 128; i++)
+  {
+    if(ttl_map[i] == -1)
+    {
+      buffer[i] = -1;
+    }
+    else
+    {
+      j = (ttl_map[i] % 22) * 14;
+      k = (ttl_map[i] / 22);
+      buffer[i] = k * 320 + j;
+    }
+  }
+
+  for (i = 0; i < 128; i++)
+    map_ttl[i] = buffer[i];
+}
+
+void tab_generate()
+{
+  create_tab(tile_blank, tab_blank);
+  create_tab(tile_acid, tab_acid);
+  create_tab(tile_ameuba, tab_ameuba);
+  create_tab(tile_android_move, tab_android_move);
+  create_explode();
+  create_obj();
+  create_spr();
+  create_ttl();
+}
diff --git a/src/libem/tile.h b/src/libem/tile.h
new file mode 100644 (file)
index 0000000..5f0f086
--- /dev/null
@@ -0,0 +1,436 @@
+#ifndef TILE_H
+#define TILE_H
+
+/* 2000-07-30T11:06:03Z
+ */
+
+/* define these for backwards compatibility */
+#define BAD_ROLL
+#define BAD_SPRING
+
+enum {
+       Xblank = 0, /* still */
+       Yacid_splash_eB, /* hmm */
+       Yacid_splash_wB, /* hmm */
+
+#ifdef BAD_ROLL
+       Xstone_force_e, /* only use these in eater */
+       Xstone_force_w,
+       Xnut_force_e,
+       Xnut_force_w,
+       Xspring_force_e,
+       Xspring_force_w,
+       Xemerald_force_e,
+       Xemerald_force_w,
+       Xdiamond_force_e,
+       Xdiamond_force_w,
+       Xbomb_force_e,
+       Xbomb_force_w,
+#endif
+
+       Xstone,
+       Xstone_pause,
+       Xstone_fall,
+       Ystone_s,
+       Ystone_sB,
+       Ystone_e,
+       Ystone_eB,
+       Ystone_w,
+       Ystone_wB,
+       Xnut,
+       Xnut_pause,
+       Xnut_fall,
+       Ynut_s,
+       Ynut_sB,
+       Ynut_e,
+       Ynut_eB,
+       Ynut_w,
+       Ynut_wB,
+       Xbug_n,
+       Xbug_e,
+       Xbug_s,
+       Xbug_w,
+       Xbug_gon,
+       Xbug_goe,
+       Xbug_gos,
+       Xbug_gow,
+       Ybug_n,
+       Ybug_nB,
+       Ybug_e,
+       Ybug_eB,
+       Ybug_s,
+       Ybug_sB,
+       Ybug_w,
+       Ybug_wB,
+       Ybug_w_n,
+       Ybug_n_e,
+       Ybug_e_s,
+       Ybug_s_w,
+       Ybug_e_n,
+       Ybug_s_e,
+       Ybug_w_s,
+       Ybug_n_w,
+       Ybug_stone,
+       Ybug_spring,
+       Xtank_n,
+       Xtank_e,
+       Xtank_s,
+       Xtank_w,
+       Xtank_gon,
+       Xtank_goe,
+       Xtank_gos,
+       Xtank_gow,
+       Ytank_n,
+       Ytank_nB,
+       Ytank_e,
+       Ytank_eB,
+       Ytank_s,
+       Ytank_sB,
+       Ytank_w,
+       Ytank_wB,
+       Ytank_w_n,
+       Ytank_n_e,
+       Ytank_e_s,
+       Ytank_s_w,
+       Ytank_e_n,
+       Ytank_s_e,
+       Ytank_w_s,
+       Ytank_n_w,
+       Ytank_stone,
+       Ytank_spring,
+       Xandroid,
+       Xandroid_1_n,
+       Xandroid_2_n,
+       Xandroid_1_e,
+       Xandroid_2_e,
+       Xandroid_1_w,
+       Xandroid_2_w,
+       Xandroid_1_s,
+       Xandroid_2_s,
+       Yandroid_n,
+       Yandroid_nB,
+       Yandroid_ne,
+       Yandroid_neB,
+       Yandroid_e,
+       Yandroid_eB,
+       Yandroid_se,
+       Yandroid_seB,
+       Yandroid_s,
+       Yandroid_sB,
+       Yandroid_sw,
+       Yandroid_swB,
+       Yandroid_w,
+       Yandroid_wB,
+       Yandroid_nw,
+       Yandroid_nwB,
+       Xspring,
+       Xspring_pause,
+       Xspring_e,
+       Xspring_w,
+       Xspring_fall,
+       Yspring_s,
+       Yspring_sB,
+       Yspring_e,
+       Yspring_eB,
+       Yspring_w,
+       Yspring_wB,
+       Yspring_kill_e,
+       Yspring_kill_eB,
+       Yspring_kill_w,
+       Yspring_kill_wB,
+       Xeater_n,
+       Xeater_e,
+       Xeater_w,
+       Xeater_s,
+       Yeater_n,
+       Yeater_nB,
+       Yeater_e,
+       Yeater_eB,
+       Yeater_s,
+       Yeater_sB,
+       Yeater_w,
+       Yeater_wB,
+       Yeater_stone,
+       Yeater_spring,
+       Xalien,
+       Xalien_pause,
+       Yalien_n,
+       Yalien_nB,
+       Yalien_e,
+       Yalien_eB,
+       Yalien_s,
+       Yalien_sB,
+       Yalien_w,
+       Yalien_wB,
+       Yalien_stone,
+       Yalien_spring,
+       Xemerald,
+       Xemerald_pause,
+       Xemerald_fall,
+       Xemerald_shine,
+       Yemerald_s,
+       Yemerald_sB,
+       Yemerald_e,
+       Yemerald_eB,
+       Yemerald_w,
+       Yemerald_wB,
+       Yemerald_eat,
+       Yemerald_stone,
+       Xdiamond,
+       Xdiamond_pause,
+       Xdiamond_fall,
+       Xdiamond_shine,
+       Ydiamond_s,
+       Ydiamond_sB,
+       Ydiamond_e,
+       Ydiamond_eB,
+       Ydiamond_w,
+       Ydiamond_wB,
+       Ydiamond_eat,
+       Ydiamond_stone,
+       Xdrip_fall,
+       Xdrip_stretch,
+       Xdrip_stretchB,
+       Xdrip_eat,
+       Ydrip_s1,
+       Ydrip_s1B,
+       Ydrip_s2,
+       Ydrip_s2B,
+       Xbomb,
+       Xbomb_pause,
+       Xbomb_fall,
+       Ybomb_s,
+       Ybomb_sB,
+       Ybomb_e,
+       Ybomb_eB,
+       Ybomb_w,
+       Ybomb_wB,
+       Ybomb_eat,
+       Xballoon,
+       Yballoon_n,
+       Yballoon_nB,
+       Yballoon_e,
+       Yballoon_eB,
+       Yballoon_s,
+       Yballoon_sB,
+       Yballoon_w,
+       Yballoon_wB,
+       Xgrass,
+       Ygrass_nB,
+       Ygrass_eB,
+       Ygrass_sB,
+       Ygrass_wB,
+       Xdirt,
+       Ydirt_nB,
+       Ydirt_eB,
+       Ydirt_sB,
+       Ydirt_wB,
+       Xacid_ne,
+       Xacid_se,
+       Xacid_s,
+       Xacid_sw,
+       Xacid_nw,
+       Xacid_1,
+       Xacid_2,
+       Xacid_3,
+       Xacid_4,
+       Xacid_5,
+       Xacid_6,
+       Xacid_7,
+       Xacid_8,
+       Xball_1,
+       Xball_1B,
+       Xball_2,
+       Xball_2B,
+       Yball_eat,
+       Xgrow_ns,
+       Ygrow_ns_eat,
+       Xgrow_ew,
+       Ygrow_ew_eat,
+       Xwonderwall,
+       XwonderwallB,
+       Xameuba_1,
+       Xameuba_2,
+       Xameuba_3,
+       Xameuba_4,
+       Xameuba_5,
+       Xameuba_6,
+       Xameuba_7,
+       Xameuba_8,
+       Xdoor_1,
+       Xdoor_2,
+       Xdoor_3,
+       Xdoor_4,
+       Xdoor_5,
+       Xdoor_6,
+       Xdoor_7,
+       Xdoor_8,
+       Xkey_1,
+       Xkey_2,
+       Xkey_3,
+       Xkey_4,
+       Xkey_5,
+       Xkey_6,
+       Xkey_7,
+       Xkey_8,
+       Xwind_n,
+       Xwind_e,
+       Xwind_s,
+       Xwind_w,
+       Xwind_nesw,
+       Xwind_stop,
+       Xexit,
+       Xexit_1,
+       Xexit_2,
+       Xexit_3,
+       Xdynamite,
+       Ydynamite_eat,
+       Xdynamite_1,
+       Xdynamite_2,
+       Xdynamite_3,
+       Xdynamite_4,
+       Xbumper,
+       XbumperB,
+       Xwheel,
+       XwheelB,
+       Xswitch,
+       XswitchB,
+       Xsand,
+       Xsand_stone,
+       Xsand_stonein_1,
+       Xsand_stonein_2,
+       Xsand_stonein_3,
+       Xsand_stonein_4,
+       Xsand_stonesand_1,
+       Xsand_stonesand_2,
+       Xsand_stonesand_3,
+       Xsand_stonesand_4,
+       Xsand_stoneout_1,
+       Xsand_stoneout_2,
+       Xsand_sandstone_1,
+       Xsand_sandstone_2,
+       Xsand_sandstone_3,
+       Xsand_sandstone_4,
+       Xplant,
+       Yplant,
+       Xlenses,
+       Xmagnify,
+       Xdripper,
+       XdripperB,
+       Xfake_blank,
+       Xfake_blankB,
+       Xfake_grass,
+       Xfake_grassB,
+       Xfake_door_1,
+       Xfake_door_2,
+       Xfake_door_3,
+       Xfake_door_4,
+       Xfake_door_5,
+       Xfake_door_6,
+       Xfake_door_7,
+       Xfake_door_8,
+       Xsteel_1,
+       Xsteel_2,
+       Xsteel_3,
+       Xsteel_4,
+       Xwall_1,
+       Xwall_2,
+       Xwall_3,
+       Xwall_4,
+       Xround_wall_1,
+       Xround_wall_2,
+       Xround_wall_3,
+       Xround_wall_4,
+       Xdecor_1,
+       Xdecor_2,
+       Xdecor_3,
+       Xdecor_4,
+       Xdecor_5,
+       Xdecor_6,
+       Xdecor_7,
+       Xdecor_8,
+       Xdecor_9,
+       Xdecor_10,
+       Xdecor_11,
+       Xdecor_12,
+       Xalpha_0,
+       Xalpha_1,
+       Xalpha_2,
+       Xalpha_3,
+       Xalpha_4,
+       Xalpha_5,
+       Xalpha_6,
+       Xalpha_7,
+       Xalpha_8,
+       Xalpha_9,
+       Xalpha_excla,
+       Xalpha_quote,
+       Xalpha_comma,
+       Xalpha_minus,
+       Xalpha_perio,
+       Xalpha_colon,
+       Xalpha_quest,
+       Xalpha_a,
+       Xalpha_b,
+       Xalpha_c,
+       Xalpha_d,
+       Xalpha_e,
+       Xalpha_f,
+       Xalpha_g,
+       Xalpha_h,
+       Xalpha_i,
+       Xalpha_j,
+       Xalpha_k,
+       Xalpha_l,
+       Xalpha_m,
+       Xalpha_n,
+       Xalpha_o,
+       Xalpha_p,
+       Xalpha_q,
+       Xalpha_r,
+       Xalpha_s,
+       Xalpha_t,
+       Xalpha_u,
+       Xalpha_v,
+       Xalpha_w,
+       Xalpha_x,
+       Xalpha_y,
+       Xalpha_z,
+       Xalpha_arrow_e,
+       Xalpha_arrow_w,
+       Xalpha_copyr,
+
+       Xboom_bug, /* passed from explode to synchro (linked explosion); transition to explode_normal */
+       Xboom_bomb, /* passed from explode to synchro (linked explosion); transition to explode_normal */
+       Xboom_android, /* passed from explode to synchro; transition to boom_2 */
+       Xboom_1, /* passed from explode to synchro; transition to boom_2 */
+       Xboom_2, /* transition to boom[] */
+
+       Znormal, /* no picture */ /* this tile is passed from synchro to explode, only in next[] */
+       Zdynamite, /* no picture */ /* this tile is passed from synchro to explode, only in next[] */
+       Zplayer, /* no picture */ /* special code to indicate player */
+       ZBORDER, /* no picture */ /* special code to indicate border */
+
+       TILE_MAX
+};
+
+enum {
+       SPR_still = 0,
+       SPR_walk = 1,
+       SPR_push = 5,
+       SPR_spray = 9,
+       SPR_MAX = 13
+};
+
+extern unsigned char tab_blank[TILE_MAX];
+extern unsigned char tab_acid[TILE_MAX];
+extern unsigned char tab_ameuba[TILE_MAX];
+extern unsigned char tab_android_move[TILE_MAX];
+extern unsigned short tab_explode_normal[TILE_MAX];
+extern unsigned short tab_explode_dynamite[TILE_MAX];
+
+extern unsigned short map_obj[8][TILE_MAX];
+extern unsigned short map_spr[2][8][SPR_MAX];
+extern unsigned short map_ttl[128];
+
+#endif
diff --git a/src/libem/ulaw_generate.c b/src/libem/ulaw_generate.c
new file mode 100644 (file)
index 0000000..b877b76
--- /dev/null
@@ -0,0 +1,176 @@
+/* 2000-08-10T04:29:10Z
+ *
+ * generate ulaw<->linear conversion tables to be included
+ * directly in emerald mine source
+ */
+
+#include "../libgame/platform.h"
+
+#if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD)
+
+#include <stdio.h>
+
+int calc_ulaw_to_linear(unsigned char);
+unsigned char calc_linear_to_ulaw(int);
+
+int buffer[65536];
+
+#if 0
+
+void print_buffer(int *buffer, int count)
+{
+       int i,j;
+       j = 0;
+       for(i = 0; i < count;) {
+               if(j > 80) { j=0; printf("\n"); }
+               if(j == 0) printf("\t");
+               j += printf("%d", buffer[i]);
+               j += printf("%s", ++i == count ? "" : ",");
+       }
+       if(j) printf("\n");
+}
+int main_OLD(void)
+{
+       int i;
+       printf("/* THIS FILE AUTOMATICALLY GENERATED */\n");
+       printf("\n#if defined(LINUX) || defined(BSD)\n");
+       printf("\n/* convert from 8 bit ulaw to signed 16 bit linear */\n");
+       printf("const short ulaw_to_linear[256] = {\n");
+       for(i = 0; i < 256; i++) {
+               buffer[i] = calc_ulaw_to_linear(i);
+       }
+       print_buffer(buffer, 256);
+       printf("};\n");
+       printf("\n/* convert from signed 16 bit linear to 8 bit ulaw */\n");
+       printf("const unsigned char linear_to_ulaw[65536] = {\n");
+       for(i = -32768; i < 32768; i++) {
+               buffer[i + 32768] = calc_linear_to_ulaw(i);
+       }
+       print_buffer(buffer, 65536);
+       printf("};\n");
+       printf("\n#endif /* defined(LINUX) || defined(BSD) */\n");
+       return(0);
+}
+
+#endif
+
+/* convert from 8 bit ulaw to signed 16 bit linear */
+short ulaw_to_linear[256];
+
+/* convert from signed 16 bit linear to 8 bit ulaw */
+unsigned char linear_to_ulaw[65536];
+
+void ulaw_generate()
+{
+  int i;
+
+  for(i = 0; i < 256; i++)
+    ulaw_to_linear[i] = calc_ulaw_to_linear(i);
+
+  for(i = -32768; i < 32768; i++)
+    linear_to_ulaw[i + 32768] = calc_linear_to_ulaw(i);
+}
+
+/*
+** This routine converts from ulaw to 16 bit linear.
+**
+** Craig Reese: IDA/Supercomputing Research Center
+** 29 September 1989
+**
+** References:
+** 1) CCITT Recommendation G.711  (very difficult to follow)
+** 2) MIL-STD-188-113,"Interoperability and Performance Standards
+**     for Analog-to_Digital Conversion Techniques,"
+**     17 February 1987
+**
+** Input: 8 bit ulaw sample
+** Output: signed 16 bit linear sample
+*/
+
+int calc_ulaw_to_linear(unsigned char ulawbyte)
+{
+       static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
+       int sign, exponent, mantissa, sample;
+
+       ulawbyte = ~ ulawbyte;
+       sign = ( ulawbyte & 0x80 );
+       exponent = ( ulawbyte >> 4 ) & 0x07;
+       mantissa = ulawbyte & 0x0F;
+       sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
+       if (sign != 0)
+               sample = -sample;
+
+       return(sample);
+}
+
+/*
+** This routine converts from linear to ulaw.
+**
+** Craig Reese: IDA/Supercomputing Research Center
+** Joe Campbell: Department of Defense
+** 29 September 1989
+**
+** References:
+** 1) CCITT Recommendation G.711  (very difficult to follow)
+** 2) "A New Digital Technique for Implementation of Any
+**     Continuous PCM Companding Law," Villeret, Michel,
+**     et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
+**     1973, pg. 11.12-11.17
+** 3) MIL-STD-188-113,"Interoperability and Performance Standards
+**     for Analog-to_Digital Conversion Techniques,"
+**     17 February 1987
+**
+** Input: Signed 16 bit linear sample
+** Output: 8 bit ulaw sample
+*/
+
+#define ZEROTRAP    /* turn on the trap as per the MIL-STD */
+#define BIAS 0x84   /* define the add-in bias for 16 bit samples */
+#define CLIP 32635
+
+unsigned char calc_linear_to_ulaw(int sample)
+{
+       static int exp_lut[256] =
+       {
+               0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
+               4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+               5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+               5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+               6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+               6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+               6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+               6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+               7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
+       };
+
+       int sign, exponent, mantissa;
+       unsigned char ulawbyte;
+
+/* Get the sample into sign-magnitude. */
+       sign = (sample >> 8) & 0x80; /* set aside the sign */
+       if (sign != 0)
+               sample = -sample; /* get magnitude */
+       if (sample > CLIP)
+               sample = CLIP; /* clip the magnitude */
+
+/* Convert from 16 bit linear to ulaw. */
+       sample = sample + BIAS;
+       exponent = exp_lut[( sample >> 7 ) & 0xFF];
+       mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
+       ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
+#ifdef ZEROTRAP
+       if (ulawbyte == 0)
+               ulawbyte = 0x02; /* optional CCITT trap */
+#endif
+
+       return(ulawbyte);
+}
+
+#endif /* defined(PLATFORM_LINUX) || defined(PLATFORM_BSD) */
index 5e1683619d8053a003a5273eabf58e15d2c3a165..baabd7e102080c53bae2efeb6eb7f610bd205bce 100644 (file)
 
 #if defined(__FreeBSD__)
 #define PLATFORM_FREEBSD
+#define PLATFORM_BSD
 #endif
 
 #if defined(__NetBSD__)
 #define PLATFORM_NETBSD
+#define PLATFORM_BSD
 #endif
 
 #if defined(__bsdi__)
 #define PLATFORM_BSDI
+#define PLATFORM_BSD
 #endif
 
 #if defined(sparc) && defined(sun)
index 596f996ab70e174e27f4c08c93d5753c67289f1a..2d823ea20e41720f76bb24e5b55c7bdf5a18e13f 100644 (file)
@@ -4173,6 +4173,9 @@ static void print_usage()
 
 int main(int argc, char *argv[])
 {
+  em_main(argc, argv);
+  return 0;
+
   InitProgramInfo(argv[0], USERDATA_DIRECTORY,
                  PROGRAM_TITLE_STRING, getWindowTitleString(),
                  ICON_TITLE_STRING, X11_ICON_FILENAME, X11_ICONMASK_FILENAME,
index 0ee2ca27a570731d1acd6e503409b5a9505e8c44..170a1fe53166293f95da3e79c30dbf5ca4450771 100644 (file)
@@ -23,6 +23,7 @@
 #include <fcntl.h>
 
 #include "libgame/libgame.h"
+#include "libem/libem.h"
 
 #include "conf_gfx.h"  /* include auto-generated data structure definitions */
 #include "conf_snd.h"  /* include auto-generated data structure definitions */