+Release Version 3.1.1 [16 AUG 2005]
+-----------------------------------
+ - added tutorial level set created by Aaron Davidson
+ - added editor element descriptions written by Aaron Davidson
+ - added native game engine for Emerald Mine (Club) levels
+ - added level skipping functionality to main menu
+ - added support for dumping small-sized level sketches from editor
+ - added use of "editorsetup.conf" for different level sets
+ - lots of bugfixes and internal engine changes (see ChangeLog)
+
Release Version 3.1.0 [07 JUN 2004]
-----------------------------------
- fixed obvious bug with wrong "Murphy" graphics (when digging etc.)
+2005-08-15
+ * fixed bug on Mac OS X (use of reserved name "Random") in EM engine
+
+2005-08-07
+ * version number temporarily set to 3.1.1 (intermediate bugfix release)
+ * version 3.1.1 released
+
+2005-08-07
+ * changed some va_arg() arguments from 'long' to 'int', fixing problems
+ on 64-bit architecture systems with LP64 data model
+
+2005-08-06
+ * fixed bug with bombs not exploding when hitting the last level line
+ (introduced after the release of 3.1.0)
+
+2005-08-06
+ * added support for dumping small-sized level sketches from editor
+
+2005-07-24
+ * added recognition of "trigger element" for "change digged element to"
+ (this is not really what the "trigger element" was made for, but its
+ use may seem obvious for leaving back digged elements unchanged)
+
+2005-07-23
+ * fixed multiple warnings about failed joystick device initialization
+
+2005-06-27
+ * fixed bug with dynamite dropped on top of just dropped custom element
+ (collect dynamite, collect CE, drop CE => dynamite was also dropped);
+ dynamite can still be dropped, but drop key must be released before
+
+2005-06-27
+ * fixed bug with wrong start directory when started from file browser
+ (due to this bug, R'n'D could not be started from KDE's Konqueror)
+
+2005-06-26
+ * fixed bug causing "change when impact" on player not working
+ * fixed wrong priority of "hitting something" over "hitting <element>"
+ * fixed wrong priority of "hit by something" over "hit by <element>"
+
+2005-06-14
+ * fixed graphical bug which caused the player (being Murphy) to show
+ collecting animations although the element was collected by penguin
+
+2005-06-08
+ * fixed two bugs causing wrong door background graphics in system.c
+ (in functions "SetBackgroundBitmap()" and "DrawingOnBackground()")
+
+2005-06-06
+ * fixed graphic bug with exploding bomb and R'n'D graphics in EM engine
+ * added "no direction" to "walkable/passable from" selectbox options
+
+2005-06-05
+ * enhanced tape autoplay to accept "autoplay <set> [<nr> ...]" format
+ * in tape autoplay, not only report broken, but also missing tapes
+
+2005-05-31
+ * uploaded pre-release (test) version 3.2.0-2 binary and source code
+
+2005-05-27
+ * fixed small bug with "linear" animation not working for active lamp
+
+2005-05-24
+ * fixed bug with moving up despite gravity due to "block last field"
+ * fixed small bug with wrong draw offset when typing name in main menu
+ * when reading user names from "passwd", ignore data after first comma
+ * when creating new "levelinfo.conf", only write some selected entries
+
+2005-04-28
+ * fixed displaying "imported from/by" on preview with empty string
+ * fixed ignoring draw offset for fonts used for level preview texts
+
+2005-04-24
+ * fixed a delay problem with SDL and too many mouse motion events
+ * added setup option "skip levels" and level skipping functionality
+
+2005-03-19
+ * added move speed "not moving" for non-moving CEs, but with direction
+
+2005-03-06
+ * fixed mapping of obsolete element token names in "editorsetup.conf"
+ * fixed bug with sound "acid.splashing" treated as a loop sound
+ * fixed some little sound bugs in native EM engine
+
+2005-02-20
+ * fixed small bug when dragging scrollbars to end positions
+
+2005-02-14
+ * added editor element descriptions written by Aaron Davidson
+
+2005-02-02
+ * improved fallback handling when configured artwork is not available
+ (now using default artwork instead of exiting when files not found)
+
+2005-02-01
+ * fixed bug on level selection screen when dragging scrollbar
+
+2005-01-19
+ * fixed bug which caused broken tapes when appending to EM engine tapes
+
+2005-01-17
+ * uploaded pre-release (test) version 3.2.0-1 binary and source code
+
+2005-01-17
+ * added code to replace changed artwork config tokens with other tokens
+ (needed for backwards compatibility, so that older tokens still work)
+
+2005-01-16
+ * added native R'n'D graphics for some new EMC elements in EM engine
+
+2005-01-15
+ * fixed some bugs in the EM engine integration code
+ * changed EM engine code to allow diagonal movement
+ * changed EM engine code to allow use of separate snap and drop keys
+
+2005-01-03
+ * fixed some redraw bugs when using EM engine
+
+2005-01-02
+ * fixed bug with not converting RND levels which are set to use native
+ engine to native level structure when loading
+
+2005-01-01
+ * uploaded pre-release (test) version 3.2.0-0 binary and source code
+
+2005-01-01
+ * version number set to 3.2.0
+
+2004-12-30
+ * level data now reset to defaults after attempt to load invalid file
+
+2004-11-13
+ * added use of "editorsetup.conf" for different level sets
+
+2004-10-26
+ * added auto-detection for various types of Emerald Mine level files
+
+2004-10-17
+ * fixed bug with scrollbars getting too small when list is very large
+
+2004-10-09
+ * fixed bug with 3+3 (cross) sized explosion not making explosion sound
+
+2004-10-04
+ * added most level editor configuration gadgets for new EMC elements
+
+2004-10-01
+ * added more element and graphic definitions for new EMC elements
+
+2004-09-27
+ * modified native EM engine to use integrated R'n'D sound system
+
+2004-09-21
+ * added SDL support to graphics functions in native EM engine
+ (by always using generic libgame interface functions)
+
+2004-09-20
+ * fixed bug in frame synchronization in native EM engine
+
+2004-09-18
+ * added code to convert levels between R'n'D and native EM engine
+
+2004-08-23
+ * new Emerald Mine engine can now play levels selected in main menu
+
+2004-08-16
+ * fixed big memory leak in function "CreateBitmapWithSmallBitmaps()"
+ (which creates scaled down graphics for level editor and preview);
+ there's still a memory leak somewhere in the artwork handling code
+ * added "scale image up" functionality to X11 version of zoom function
+
+2004-08-14
+ * first attempts to integrate new, native Emerald Mine Club engine
+
+2004-08-07
+ * fixed bug in gadget code which caused reset of CEs in level editor
+ (example: pressing 'b' [grab brush] on CE config page erased values)
+ (solution: check if gadgets in ClickOnGadget() are really mapped)
+ * improved level change detection in editor (settings now also checked)
+ * fixed bug with "can move into acid" and "don't collide with" state
+
+2004-07-29
+ * fixed maze runner style CEs to use the configured move delay value
+
+2004-06-27
+ * added Aaron Davidson's tutorial level set to the "Tutorials" section
+
+2004-06-20
+ * fixed engine change that broke 3.0.8 levels like "Walpurgis Gardens"
+ * fixed the above fix because it broke level set "machine" (*sigh*)
+ * fixed random element placement in level editor to work as expected
+ * fixed undefined graphic of runtime element "EL_AMOEBA_TO_DIAMOND"
+
+2004-06-15
+ * re-recorded tape for BD2K3, level 010 (broken due to bugfix)
+
+2004-06-13
+ * fixed bug (missing array boundary check) which caused broken tapes
+ * fixed bug (when loading level template) which caused broken levels
+ * fixed bug with new block last field code when using non-yellow player
+
+2004-06-12
+ * fixed bug when pressing "stop, pause, stop, play" on tape recorder
+ * internal change of how the player blocks the last field when moving
+ * fixed blocking delay of last field for EM and SP style block delay
+ * fixed bug where the player had to wait for the usual move delay after
+ unsuccessfully trying to move, when he directly could move after that
+ * the last two changes should make original Supaplex level 93 solvable
+ * improved use of random number generator to make it less predictable
+ * fixed behaviour of slippery SP elements to let slip left, then right
+
+2004-06-11
+ * fixed bug with wrong door state after trying to quickload empty tape
+ * fixed waste of static memory usage of the binary, making it smaller
+ * fixed very little graphical bug in Supaplex explosion
+
+2004-06-07
+ * version number set to 3.1.1
+
+2004-06-07
+ * version 3.1.0 released
+
2004-06-07
* fixed bug with crash when writing user levelinfo.conf the first time
# =============================================================================
# Rocks'n'Diamonds Makefile
# -----------------------------------------------------------------------------
-# (c) 1995-2003 Holger Schemel <info@artsoft.org>
+# (c) 1995-2005 Holger Schemel <info@artsoft.org>
# =============================================================================
# -----------------------------------------------------------------------------
mac:
@$(MAKE_CMD) PLATFORM=macosx
+mac-static:
+ @$(MAKE_CMD) PLATFORM=macosx TARGET=sdl-static
+
msdos:
@$(MAKE_CMD) PLATFORM=msdos
@./rocksndiamonds --verbose
gdb: all
- @gdb ./rocksndiamonds
+ @gdb -batch -x GDB_COMMANDS ./rocksndiamonds
valgrind: all
@valgrind -v --leak-check=yes ./rocksndiamonds 2> valgrind.out
$(MAKE) clean
$(MAKE) dist-build-unix ; $(MAKE) dist-clean
$(MAKE) dist-build-win32 ; $(MAKE) dist-clean
- $(MAKE) dist-build-msdos ; $(MAKE) dist-clean
+# $(MAKE) dist-build-msdos ; $(MAKE) dist-clean
+
+# dist-all: dist-build-all dist-unix dist-msdos dist-win32 dist-macosx
+dist-all: dist-build-all dist-unix dist-win32 dist-macosx
-dist-all: dist-build-all dist-unix dist-msdos dist-win32 dist-macosx
+# upload-all: upload-unix upload-msdos upload-win32 upload-macosx
+upload-all: upload-unix upload-win32 upload-macosx
-upload-all: upload-unix upload-msdos upload-win32 upload-macosx
+tags:
+ $(MAKE_CMD) tags
depend dep:
$(MAKE_CMD) depend
# =============================================================================
# Rocks'n'Diamonds Makefile (src)
# -----------------------------------------------------------------------------
-# (c) 1995-2003 Holger Schemel <info@artsoft.org>
+# (c) 1995-2005 Holger Schemel <info@artsoft.org>
# =============================================================================
# -----------------------------------------------------------------------------
AR = ar
RANLIB = ranlib
+ETAGS = etags
BMP2ICO = bmp2ico
WINDRES = windres
SYS_LDFLAGS = $(SDL_LIBS) $(shell sdl-config --libs)
endif
+ifeq ($(TARGET),sdl-static)
+SYS_CFLAGS = -DTARGET_SDL $(shell sdl-config --cflags)
+SDL_LIBS = -lSDL_image -lSDL_mixer -lSDL_net -lsmpeg
+SYS_LDFLAGS = $(SDL_LIBS) $(shell sdl-config --static-libs)
+endif
+
ifeq ($(TARGET),allegro)
SYS_CFLAGS = -DTARGET_ALLEGRO -I$(CROSS_PATH_MSDOS)/include
SYS_LDFLAGS = -lalleg
TIMESTAMP_FILE = conftime.h
-LIBDIR = libgame
-LIBGAME = $(LIBDIR)/libgame.a
+LIBGAME_DIR = libgame
+LIBGAME = $(LIBGAME_DIR)/libgame.a
+
+GAME_EM_DIR = game_em
+GAME_EM = $(GAME_EM_DIR)/game_em.a
+
+RNDLIBS = $(LIBGAME) $(GAME_EM)
ICONBASE = windows_icon
ifeq ($(PLATFORM),cross-win32)
# build targets
# -----------------------------------------------------------------------------
-all: libgame_dir $(PROGNAME)
+all: libgame_dir game_em_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 $(LIBGAME_DIR)
$(LIBGAME):
- @$(MAKE) -C $(LIBDIR)
+ @$(MAKE) -C $(LIBGAME_DIR)
+
+game_em_dir:
+ @$(MAKE) -C $(GAME_EM_DIR)
+$(GAME_EM):
+ @$(MAKE) -C $(GAME_EM_DIR)
auto-conf:
@for i in $(CNFS); do \
conf_mus.h: conf_mus.c
@$(MAKE) auto-conf
-$(TIMESTAMP_FILE): $(SRCS) $(LIBGAME)
+$(TIMESTAMP_FILE): $(SRCS) $(LIBGAME) $(GAME_EM)
@date '+"[%Y-%m-%d %H:%M]"' \
| sed -e 's/^/#define COMPILE_DATE_STRING /' \
> $(TIMESTAMP_FILE)
$(CC) $(PROFILING) $(CFLAGS) -c $*.c
clean-obj:
- $(MAKE) -C $(LIBDIR) clean
+ $(MAKE) -C $(LIBGAME_DIR) clean
+ $(MAKE) -C $(GAME_EM_DIR) clean
$(RM) $(OBJS)
$(RM) $(LIBGAME)
+ $(RM) $(GAME_EM)
clean-ico:
$(RM) $(ICONBASE).ico
dist-clean: clean-obj
+tags:
+ $(ETAGS) *.[ch] $(LIBGAME_DIR)/*.[ch] $(GAME_EM_DIR)/*.[ch]
+
depend:
- $(MAKE) -C $(LIBDIR) depend
+ $(MAKE) -C $(LIBGAME_DIR) depend
+ $(MAKE) -C $(GAME_EM_DIR) depend
for i in $(SRCS); do $(CPP) $(CFLAGS) -M $$i; done > .depend
ifeq (.depend,$(wildcard .depend))
static void PrepareBackbuffer()
{
- /* Fill empty backbuffer for animation functions */
+ if (game_status == GAME_MODE_PLAYING &&
+ level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ {
+ BlitScreenToBitmap_EM(backbuffer);
+
+ return;
+ }
+
+ /* fill empty backbuffer for animation functions */
if (setup.direct_draw && game_status == GAME_MODE_PLAYING)
{
int xx, yy;
for (i=0; i < num_toons; i++)
{
int graphic = IMG_TOON_1 + i;
- struct FileInfo *image = getImageListEntry(graphic);
+ struct FileInfo *image = getImageListEntryFromImageID(graphic);
toons[i].bitmap = graphic_info[graphic].bitmap;
{ "char_dollar.ypos", "0" },
{ "char_dollar.frames", "1" },
- { "char_procent", "RocksFontEM.pcx" },
- { "char_procent.xpos", "5" },
- { "char_procent.ypos", "0" },
- { "char_procent.frames", "1" },
+ { "char_percent", "RocksFontEM.pcx" },
+ { "char_percent.xpos", "5" },
+ { "char_percent.ypos", "0" },
+ { "char_percent.frames", "1" },
{ "char_ampersand", "RocksFontEM.pcx" },
{ "char_ampersand.xpos", "6" },
#define EL_CHAR_QUOTEDBL (EL_CHAR_ASCII0 + 34)
#define EL_CHAR_NUMBERSIGN (EL_CHAR_ASCII0 + 35)
#define EL_CHAR_DOLLAR (EL_CHAR_ASCII0 + 36)
-#define EL_CHAR_PROCENT (EL_CHAR_ASCII0 + 37)
+#define EL_CHAR_PERCENT (EL_CHAR_ASCII0 + 37)
#define EL_CHAR_AMPERSAND (EL_CHAR_ASCII0 + 38)
#define EL_CHAR_APOSTROPHE (EL_CHAR_ASCII0 + 39)
#define EL_CHAR_PARENLEFT (EL_CHAR_ASCII0 + 40)
EL_BD_BUTTERFLY, -1, -1, FALSE,
IMG_BD_BUTTERFLY
},
+ {
+ EL_BD_BUTTERFLY_RIGHT, -1, -1, FALSE,
+ IMG_BD_BUTTERFLY_RIGHT
+ },
+ {
+ EL_BD_BUTTERFLY, -1, MV_BIT_RIGHT, FALSE,
+ IMG_BD_BUTTERFLY_RIGHT
+ },
+ {
+ EL_BD_BUTTERFLY_UP, -1, -1, FALSE,
+ IMG_BD_BUTTERFLY_UP
+ },
+ {
+ EL_BD_BUTTERFLY, -1, MV_BIT_UP, FALSE,
+ IMG_BD_BUTTERFLY_UP
+ },
+ {
+ EL_BD_BUTTERFLY_LEFT, -1, -1, FALSE,
+ IMG_BD_BUTTERFLY_LEFT
+ },
+ {
+ EL_BD_BUTTERFLY, -1, MV_BIT_LEFT, FALSE,
+ IMG_BD_BUTTERFLY_LEFT
+ },
+ {
+ EL_BD_BUTTERFLY_DOWN, -1, -1, FALSE,
+ IMG_BD_BUTTERFLY_DOWN
+ },
+ {
+ EL_BD_BUTTERFLY, -1, MV_BIT_DOWN, FALSE,
+ IMG_BD_BUTTERFLY_DOWN
+ },
{
EL_BD_FIREFLY, -1, -1, FALSE,
IMG_BD_FIREFLY
},
+ {
+ EL_BD_FIREFLY_RIGHT, -1, -1, FALSE,
+ IMG_BD_FIREFLY_RIGHT
+ },
+ {
+ EL_BD_FIREFLY, -1, MV_BIT_RIGHT, FALSE,
+ IMG_BD_FIREFLY_RIGHT
+ },
+ {
+ EL_BD_FIREFLY_UP, -1, -1, FALSE,
+ IMG_BD_FIREFLY_UP
+ },
+ {
+ EL_BD_FIREFLY, -1, MV_BIT_UP, FALSE,
+ IMG_BD_FIREFLY_UP
+ },
+ {
+ EL_BD_FIREFLY_LEFT, -1, -1, FALSE,
+ IMG_BD_FIREFLY_LEFT
+ },
+ {
+ EL_BD_FIREFLY, -1, MV_BIT_LEFT, FALSE,
+ IMG_BD_FIREFLY_LEFT
+ },
+ {
+ EL_BD_FIREFLY_DOWN, -1, -1, FALSE,
+ IMG_BD_FIREFLY_DOWN
+ },
+ {
+ EL_BD_FIREFLY, -1, MV_BIT_DOWN, FALSE,
+ IMG_BD_FIREFLY_DOWN
+ },
{
EL_SP_DEFAULT, ACTION_EXPLODING, -1, FALSE,
IMG_SP_DEFAULT_EXPLODING
EL_BALLOON_SWITCH_ANY, -1, -1, FALSE,
IMG_BALLOON_SWITCH_ANY
},
+ {
+ EL_BALLOON_SWITCH_NONE, -1, -1, FALSE,
+ IMG_BALLOON_SWITCH_NONE
+ },
{
EL_SPRING, -1, -1, FALSE,
IMG_SPRING
EL_INVISIBLE_SAND, ACTION_ACTIVE, -1, FALSE,
IMG_INVISIBLE_SAND_ACTIVE
},
+ {
+ EL_INVISIBLE_SAND, ACTION_ACTIVE, -1, TRUE,
+ IMG_INVISIBLE_SAND_ACTIVE_CRUMBLED
+ },
+ {
+ EL_INVISIBLE_SAND_ACTIVE, -1, -1, TRUE,
+ IMG_INVISIBLE_SAND_ACTIVE_CRUMBLED
+ },
+ {
+ EL_INVISIBLE_SAND_ACTIVE, ACTION_DIGGING, MV_BIT_LEFT, FALSE,
+ IMG_INVISIBLE_SAND_ACTIVE_DIGGING_LEFT
+ },
+ {
+ EL_INVISIBLE_SAND_ACTIVE, ACTION_DIGGING, MV_BIT_RIGHT, FALSE,
+ IMG_INVISIBLE_SAND_ACTIVE_DIGGING_RIGHT
+ },
+ {
+ EL_INVISIBLE_SAND_ACTIVE, ACTION_DIGGING, MV_BIT_UP, FALSE,
+ IMG_INVISIBLE_SAND_ACTIVE_DIGGING_UP
+ },
+ {
+ EL_INVISIBLE_SAND_ACTIVE, ACTION_DIGGING, MV_BIT_DOWN, FALSE,
+ IMG_INVISIBLE_SAND_ACTIVE_DIGGING_DOWN
+ },
+ {
+ EL_INVISIBLE_SAND_ACTIVE, ACTION_DIGGING, MV_BIT_LEFT, TRUE,
+ IMG_INVISIBLE_SAND_ACTIVE_DIGGING_LEFT_CRUMBLED
+ },
+ {
+ EL_INVISIBLE_SAND_ACTIVE, ACTION_DIGGING, MV_BIT_RIGHT, TRUE,
+ IMG_INVISIBLE_SAND_ACTIVE_DIGGING_RIGHT_CRUMBLED
+ },
+ {
+ EL_INVISIBLE_SAND_ACTIVE, ACTION_DIGGING, MV_BIT_UP, TRUE,
+ IMG_INVISIBLE_SAND_ACTIVE_DIGGING_UP_CRUMBLED
+ },
+ {
+ EL_INVISIBLE_SAND_ACTIVE, ACTION_DIGGING, MV_BIT_DOWN, TRUE,
+ IMG_INVISIBLE_SAND_ACTIVE_DIGGING_DOWN_CRUMBLED
+ },
{
EL_CONVEYOR_BELT_1_MIDDLE, -1, -1, FALSE,
IMG_CONVEYOR_BELT_1_MIDDLE
EL_TRIGGER_PLAYER, -1, -1, FALSE,
IMG_TRIGGER_PLAYER
},
+ {
+ EL_EMC_KEY_5, -1, -1, FALSE,
+ IMG_EMC_KEY_5
+ },
+ {
+ EL_EMC_KEY_6, -1, -1, FALSE,
+ IMG_EMC_KEY_6
+ },
+ {
+ EL_EMC_KEY_7, -1, -1, FALSE,
+ IMG_EMC_KEY_7
+ },
+ {
+ EL_EMC_KEY_8, -1, -1, FALSE,
+ IMG_EMC_KEY_8
+ },
+ {
+ EL_EMC_GATE_5, -1, -1, FALSE,
+ IMG_EMC_GATE_5
+ },
+ {
+ EL_EMC_GATE_5_GRAY, -1, -1, FALSE,
+ IMG_EMC_GATE_5_GRAY
+ },
+ {
+ EL_EMC_GATE_6, -1, -1, FALSE,
+ IMG_EMC_GATE_6
+ },
+ {
+ EL_EMC_GATE_6_GRAY, -1, -1, FALSE,
+ IMG_EMC_GATE_6_GRAY
+ },
+ {
+ EL_EMC_GATE_7, -1, -1, FALSE,
+ IMG_EMC_GATE_7
+ },
+ {
+ EL_EMC_GATE_7_GRAY, -1, -1, FALSE,
+ IMG_EMC_GATE_7_GRAY
+ },
+ {
+ EL_EMC_GATE_8, -1, -1, FALSE,
+ IMG_EMC_GATE_8
+ },
+ {
+ EL_EMC_GATE_8_GRAY, -1, -1, FALSE,
+ IMG_EMC_GATE_8_GRAY
+ },
+ {
+ EL_EMC_ANDROID, -1, -1, FALSE,
+ IMG_EMC_ANDROID
+ },
+ {
+ EL_EMC_GRASS, -1, -1, FALSE,
+ IMG_EMC_GRASS
+ },
+ {
+ EL_EMC_GRASS, -1, -1, TRUE,
+ IMG_EMC_GRASS_CRUMBLED
+ },
+ {
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_LEFT, FALSE,
+ IMG_EMC_GRASS_DIGGING_LEFT
+ },
+ {
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_RIGHT, FALSE,
+ IMG_EMC_GRASS_DIGGING_RIGHT
+ },
+ {
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_UP, FALSE,
+ IMG_EMC_GRASS_DIGGING_UP
+ },
+ {
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_DOWN, FALSE,
+ IMG_EMC_GRASS_DIGGING_DOWN
+ },
+ {
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_LEFT, TRUE,
+ IMG_EMC_GRASS_DIGGING_LEFT_CRUMBLED
+ },
+ {
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_RIGHT, TRUE,
+ IMG_EMC_GRASS_DIGGING_RIGHT_CRUMBLED
+ },
+ {
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_UP, TRUE,
+ IMG_EMC_GRASS_DIGGING_UP_CRUMBLED
+ },
+ {
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_DOWN, TRUE,
+ IMG_EMC_GRASS_DIGGING_DOWN_CRUMBLED
+ },
+ {
+ EL_EMC_MAGIC_BALL, -1, -1, FALSE,
+ IMG_EMC_MAGIC_BALL
+ },
+ {
+ EL_EMC_MAGIC_BALL_ACTIVE, -1, -1, FALSE,
+ IMG_EMC_MAGIC_BALL_ACTIVE
+ },
+ {
+ EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1, FALSE,
+ IMG_EMC_MAGIC_BALL_ACTIVE
+ },
+ {
+ EL_EMC_MAGIC_BALL_SWITCH, -1, -1, FALSE,
+ IMG_EMC_MAGIC_BALL_SWITCH
+ },
+ {
+ EL_EMC_MAGIC_BALL_SWITCH_ACTIVE, -1, -1, FALSE,
+ IMG_EMC_MAGIC_BALL_SWITCH_ACTIVE
+ },
+ {
+ EL_EMC_MAGIC_BALL_SWITCH, ACTION_ACTIVE, -1, FALSE,
+ IMG_EMC_MAGIC_BALL_SWITCH_ACTIVE
+ },
+ {
+ EL_EMC_SPRING_BUMPER, -1, -1, FALSE,
+ IMG_EMC_SPRING_BUMPER
+ },
+ {
+ EL_EMC_SPRING_BUMPER, ACTION_ACTIVE, -1, FALSE,
+ IMG_EMC_SPRING_BUMPER_ACTIVE
+ },
+ {
+ EL_EMC_PLANT, -1, -1, FALSE,
+ IMG_EMC_PLANT
+ },
+ {
+ EL_EMC_PLANT, -1, -1, TRUE,
+ IMG_EMC_PLANT_CRUMBLED
+ },
+ {
+ EL_EMC_LENSES, -1, -1, FALSE,
+ IMG_EMC_LENSES
+ },
+ {
+ EL_EMC_MAGNIFIER, -1, -1, FALSE,
+ IMG_EMC_MAGNIFIER
+ },
+ {
+ EL_EMC_WALL_9, -1, -1, FALSE,
+ IMG_EMC_WALL_9
+ },
+ {
+ EL_EMC_WALL_10, -1, -1, FALSE,
+ IMG_EMC_WALL_10
+ },
+ {
+ EL_EMC_WALL_11, -1, -1, FALSE,
+ IMG_EMC_WALL_11
+ },
+ {
+ EL_EMC_WALL_12, -1, -1, FALSE,
+ IMG_EMC_WALL_12
+ },
+ {
+ EL_EMC_WALL_13, -1, -1, FALSE,
+ IMG_EMC_WALL_13
+ },
+ {
+ EL_EMC_WALL_14, -1, -1, FALSE,
+ IMG_EMC_WALL_14
+ },
+ {
+ EL_EMC_WALL_15, -1, -1, FALSE,
+ IMG_EMC_WALL_15
+ },
+ {
+ EL_EMC_WALL_16, -1, -1, FALSE,
+ IMG_EMC_WALL_16
+ },
+ {
+ EL_EMC_WALL_SLIPPERY_1, -1, -1, FALSE,
+ IMG_EMC_WALL_SLIPPERY_1
+ },
+ {
+ EL_EMC_WALL_SLIPPERY_2, -1, -1, FALSE,
+ IMG_EMC_WALL_SLIPPERY_2
+ },
+ {
+ EL_EMC_WALL_SLIPPERY_3, -1, -1, FALSE,
+ IMG_EMC_WALL_SLIPPERY_3
+ },
+ {
+ EL_EMC_WALL_SLIPPERY_4, -1, -1, FALSE,
+ IMG_EMC_WALL_SLIPPERY_4
+ },
+ {
+ EL_EMC_FAKE_GRASS, -1, -1, FALSE,
+ IMG_EMC_FAKE_GRASS
+ },
+ {
+ EL_EMC_FAKE_GRASS, -1, -1, TRUE,
+ IMG_EMC_FAKE_GRASS_CRUMBLED
+ },
+ {
+ EL_EMC_FAKE_GRASS, ACTION_ACTIVE, -1, FALSE,
+ IMG_EMC_FAKE_GRASS_ACTIVE
+ },
+ {
+ EL_EMC_FAKE_GRASS, ACTION_ACTIVE, -1, TRUE,
+ IMG_EMC_FAKE_GRASS_ACTIVE_CRUMBLED
+ },
+ {
+ EL_EMC_FAKE_ACID, -1, -1, FALSE,
+ IMG_EMC_FAKE_ACID
+ },
+ {
+ EL_EMC_DRIPPER, -1, -1, FALSE,
+ IMG_EMC_DRIPPER
+ },
+ {
+ EL_EMC_DRIPPER, ACTION_ACTIVE, -1, FALSE,
+ IMG_EMC_DRIPPER_ACTIVE
+ },
{
EL_BD_BUTTERFLY_DOWN, -1, -1, FALSE,
IMG_BD_BUTTERFLY
IMG_CHAR_DOLLAR
},
{
- EL_CHAR_PROCENT, -1, -1, FALSE,
- IMG_CHAR_PROCENT
+ EL_CHAR_PERCENT, -1, -1, FALSE,
+ IMG_CHAR_PERCENT
},
{
EL_CHAR_AMPERSAND, -1, -1, FALSE,
EL_AMOEBA_DEAD, TRUE, ACTION_DROPPING,
SND_CLASS_AMOEBA_DROPPING
},
+ {
+ EL_ACID, FALSE, ACTION_SPLASHING,
+ SND_ACID_SPLASHING
+ },
{
EL_QUICKSAND_EMPTY, TRUE, ACTION_FILLING,
SND_CLASS_QUICKSAND_FILLING
EL_WALL, TRUE, ACTION_GROWING,
SND_CLASS_WALL_GROWING
},
+ {
+ EL_EMC_ANDROID, FALSE, ACTION_PUSHING,
+ SND_EMC_ANDROID_PUSHING
+ },
+ {
+ EL_EMC_ANDROID, FALSE, ACTION_MOVING,
+ SND_EMC_ANDROID_MOVING
+ },
+ {
+ EL_EMC_ANDROID, FALSE, ACTION_DROPPING,
+ SND_EMC_ANDROID_DROPPING
+ },
+ {
+ EL_EMC_MAGIC_BALL, FALSE, ACTION_DROPPING,
+ SND_EMC_MAGIC_BALL_DROPPING
+ },
{
EL_PEARL, FALSE, ACTION_COLLECTING,
SND_PEARL_COLLECTING
EL_INVISIBLE_SAND, FALSE, ACTION_DIGGING,
SND_INVISIBLE_SAND_DIGGING
},
+ {
+ EL_INVISIBLE_SAND_ACTIVE, FALSE, ACTION_DIGGING,
+ SND_INVISIBLE_SAND_ACTIVE_DIGGING
+ },
{
EL_SHIELD_NORMAL, FALSE, ACTION_COLLECTING,
SND_SHIELD_NORMAL_COLLECTING
EL_INVISIBLE_STEELWALL_VERTICAL, GFX_SPECIAL_ARG_EDITOR,
IMG_INVISIBLE_STEELWALL_VERTICAL_EDITOR
},
+ {
+ EL_EMC_GATE_5_GRAY, GFX_SPECIAL_ARG_EDITOR,
+ IMG_EMC_GATE_5_GRAY_EDITOR
+ },
+ {
+ EL_EMC_GATE_6_GRAY, GFX_SPECIAL_ARG_EDITOR,
+ IMG_EMC_GATE_6_GRAY_EDITOR
+ },
+ {
+ EL_EMC_GATE_7_GRAY, GFX_SPECIAL_ARG_EDITOR,
+ IMG_EMC_GATE_7_GRAY_EDITOR
+ },
+ {
+ EL_EMC_GATE_8_GRAY, GFX_SPECIAL_ARG_EDITOR,
+ IMG_EMC_GATE_8_GRAY_EDITOR
+ },
+ {
+ EL_EMC_DRIPPER, GFX_SPECIAL_ARG_EDITOR,
+ IMG_EMC_DRIPPER_EDITOR
+ },
{
EL_CUSTOM_1, GFX_SPECIAL_ARG_EDITOR,
IMG_CUSTOM_1_EDITOR
reliable default values. If that value is GFX_ARG_UNDEFINED, it will
be dynamically determined, using some of the other list values. */
-struct ConfigInfo image_config_suffix[] =
+struct ConfigTypeInfo image_config_suffix[] =
{
{ ".x", ARG_UNDEFINED, TYPE_INTEGER },
{ ".y", ARG_UNDEFINED, TYPE_INTEGER },
{ ".ypos", ARG_UNDEFINED, TYPE_INTEGER },
{ ".width", ARG_UNDEFINED, TYPE_INTEGER },
{ ".height", ARG_UNDEFINED, TYPE_INTEGER },
- { ".offset", ARG_UNDEFINED, TYPE_INTEGER },
{ ".vertical", "false", TYPE_BOOLEAN },
+ { ".offset", ARG_UNDEFINED, TYPE_INTEGER },
{ ".xoffset", ARG_UNDEFINED, TYPE_INTEGER },
{ ".yoffset", ARG_UNDEFINED, TYPE_INTEGER },
+ { ".2nd_movement_tile", "false", TYPE_BOOLEAN },
+ { ".2nd_vertical", ARG_UNDEFINED, TYPE_BOOLEAN },
+ { ".2nd_offset", ARG_UNDEFINED, TYPE_INTEGER },
+ { ".2nd_xoffset", ARG_UNDEFINED, TYPE_INTEGER },
+ { ".2nd_yoffset", ARG_UNDEFINED, TYPE_INTEGER },
+ { ".2nd_swap_tiles", ARG_UNDEFINED, TYPE_BOOLEAN },
{ ".frames", ARG_UNDEFINED, TYPE_INTEGER },
{ ".frames_per_line", ARG_UNDEFINED, TYPE_INTEGER },
{ ".start_frame", ARG_UNDEFINED, TYPE_INTEGER },
{ ".post_delay_fixed", ARG_UNDEFINED, TYPE_INTEGER },
{ ".post_delay_random", ARG_UNDEFINED, TYPE_INTEGER },
{ ".name", ARG_UNDEFINED, TYPE_STRING },
+ { ".scale_up_factor", ARG_UNDEFINED, TYPE_INTEGER },
{ NULL, NULL, 0 }
};
{ "bd_butterfly.anim_mode", "pingpong" },
{ "bd_butterfly.delay", "4" },
{ "bd_butterfly.global_sync", "true" },
+ { "bd_butterfly.right", "RocksElements.pcx" },
+ { "bd_butterfly.right.xpos", "4" },
+ { "bd_butterfly.right.ypos", "12" },
+ { "bd_butterfly.right.frames", "2" },
+ { "bd_butterfly.right.anim_mode", "pingpong" },
+ { "bd_butterfly.right.delay", "4" },
+ { "bd_butterfly.right.global_sync", "true" },
{ "bd_butterfly.right.EDITOR", "RocksElements.pcx" },
{ "bd_butterfly.right.EDITOR.xpos", "8" },
{ "bd_butterfly.right.EDITOR.ypos", "12" },
+ { "bd_butterfly.up", "RocksElements.pcx" },
+ { "bd_butterfly.up.xpos", "4" },
+ { "bd_butterfly.up.ypos", "12" },
+ { "bd_butterfly.up.frames", "2" },
+ { "bd_butterfly.up.anim_mode", "pingpong" },
+ { "bd_butterfly.up.delay", "4" },
+ { "bd_butterfly.up.global_sync", "true" },
{ "bd_butterfly.up.EDITOR", "RocksElements.pcx" },
{ "bd_butterfly.up.EDITOR.xpos", "9" },
{ "bd_butterfly.up.EDITOR.ypos", "12" },
+ { "bd_butterfly.left", "RocksElements.pcx" },
+ { "bd_butterfly.left.xpos", "4" },
+ { "bd_butterfly.left.ypos", "12" },
+ { "bd_butterfly.left.frames", "2" },
+ { "bd_butterfly.left.anim_mode", "pingpong" },
+ { "bd_butterfly.left.delay", "4" },
+ { "bd_butterfly.left.global_sync", "true" },
{ "bd_butterfly.left.EDITOR", "RocksElements.pcx" },
{ "bd_butterfly.left.EDITOR.xpos", "10" },
{ "bd_butterfly.left.EDITOR.ypos", "12" },
+ { "bd_butterfly.down", "RocksElements.pcx" },
+ { "bd_butterfly.down.xpos", "4" },
+ { "bd_butterfly.down.ypos", "12" },
+ { "bd_butterfly.down.frames", "2" },
+ { "bd_butterfly.down.anim_mode", "pingpong" },
+ { "bd_butterfly.down.delay", "4" },
+ { "bd_butterfly.down.global_sync", "true" },
{ "bd_butterfly.down.EDITOR", "RocksElements.pcx" },
{ "bd_butterfly.down.EDITOR.xpos", "11" },
{ "bd_butterfly.down.EDITOR.ypos", "12" },
{ "bd_firefly.anim_mode", "pingpong" },
{ "bd_firefly.delay", "4" },
{ "bd_firefly.global_sync", "true" },
+ { "bd_firefly.right", "RocksElements.pcx" },
+ { "bd_firefly.right.xpos", "6" },
+ { "bd_firefly.right.ypos", "12" },
+ { "bd_firefly.right.frames", "2" },
+ { "bd_firefly.right.anim_mode", "pingpong" },
+ { "bd_firefly.right.delay", "4" },
+ { "bd_firefly.right.global_sync", "true" },
{ "bd_firefly.right.EDITOR", "RocksElements.pcx" },
{ "bd_firefly.right.EDITOR.xpos", "12" },
{ "bd_firefly.right.EDITOR.ypos", "12" },
+ { "bd_firefly.up", "RocksElements.pcx" },
+ { "bd_firefly.up.xpos", "6" },
+ { "bd_firefly.up.ypos", "12" },
+ { "bd_firefly.up.frames", "2" },
+ { "bd_firefly.up.anim_mode", "pingpong" },
+ { "bd_firefly.up.delay", "4" },
+ { "bd_firefly.up.global_sync", "true" },
{ "bd_firefly.up.EDITOR", "RocksElements.pcx" },
{ "bd_firefly.up.EDITOR.xpos", "13" },
{ "bd_firefly.up.EDITOR.ypos", "12" },
+ { "bd_firefly.left", "RocksElements.pcx" },
+ { "bd_firefly.left.xpos", "6" },
+ { "bd_firefly.left.ypos", "12" },
+ { "bd_firefly.left.frames", "2" },
+ { "bd_firefly.left.anim_mode", "pingpong" },
+ { "bd_firefly.left.delay", "4" },
+ { "bd_firefly.left.global_sync", "true" },
{ "bd_firefly.left.EDITOR", "RocksElements.pcx" },
{ "bd_firefly.left.EDITOR.xpos", "14" },
{ "bd_firefly.left.EDITOR.ypos", "12" },
+ { "bd_firefly.down", "RocksElements.pcx" },
+ { "bd_firefly.down.xpos", "6" },
+ { "bd_firefly.down.ypos", "12" },
+ { "bd_firefly.down.frames", "2" },
+ { "bd_firefly.down.anim_mode", "pingpong" },
+ { "bd_firefly.down.delay", "4" },
+ { "bd_firefly.down.global_sync", "true" },
{ "bd_firefly.down.EDITOR", "RocksElements.pcx" },
{ "bd_firefly.down.EDITOR.xpos", "15" },
{ "bd_firefly.down.EDITOR.ypos", "12" },
{ "balloon_switch_any.xpos", "15" },
{ "balloon_switch_any.ypos", "0" },
{ "balloon_switch_any.frames", "1" },
+ { "balloon_switch_none", "RocksDC.pcx" },
+ { "balloon_switch_none.xpos", "13" },
+ { "balloon_switch_none.ypos", "5" },
+ { "balloon_switch_none.frames", "1" },
{ "spring", "RocksDC.pcx" },
{ "spring.xpos", "8" },
{ "emc_steelwall_1.xpos", "14" },
{ "emc_steelwall_1.ypos", "0" },
{ "emc_steelwall_1.frames", "1" },
- { "emc_steelwall_2", "RocksDC.pcx" },
- { "emc_steelwall_2.xpos", "14" },
- { "emc_steelwall_2.ypos", "0" },
+ { "emc_steelwall_2", "RocksEMC.pcx" },
+ { "emc_steelwall_2.xpos", "9" },
+ { "emc_steelwall_2.ypos", "8" },
{ "emc_steelwall_2.frames", "1" },
- { "emc_steelwall_3", "RocksDC.pcx" },
- { "emc_steelwall_3.xpos", "14" },
- { "emc_steelwall_3.ypos", "0" },
+ { "emc_steelwall_3", "RocksEMC.pcx" },
+ { "emc_steelwall_3.xpos", "9" },
+ { "emc_steelwall_3.ypos", "9" },
{ "emc_steelwall_3.frames", "1" },
- { "emc_steelwall_4", "RocksDC.pcx" },
- { "emc_steelwall_4.xpos", "14" },
- { "emc_steelwall_4.ypos", "0" },
+ { "emc_steelwall_4", "RocksEMC.pcx" },
+ { "emc_steelwall_4.xpos", "9" },
+ { "emc_steelwall_4.ypos", "10" },
{ "emc_steelwall_4.frames", "1" },
{ "emc_wall_1", "RocksDC.pcx" },
{ "emc_wall_7.xpos", "15" },
{ "emc_wall_7.ypos", "2" },
{ "emc_wall_7.frames", "1" },
- { "emc_wall_8", "RocksDC.pcx" },
- { "emc_wall_8.xpos", "14" },
- { "emc_wall_8.ypos", "1" },
+ { "emc_wall_8", "RocksEMC.pcx" },
+ { "emc_wall_8.xpos", "8" },
+ { "emc_wall_8.ypos", "7" },
{ "emc_wall_8.frames", "1" },
/* images for Diamond Caves style elements and actions */
{ "invisible_wall.active.frames", "1" },
{ "invisible_sand", "RocksSP.pcx" },
- { "invisible_sand.xpos", "6" },
- { "invisible_sand.ypos", "5" },
+ { "invisible_sand.xpos", "0" },
+ { "invisible_sand.ypos", "0" },
{ "invisible_sand.frames", "1" },
- { "invisible_sand.EDITOR", "RocksSP.pcx" },
+ { "invisible_sand.EDITOR", "RocksEMC.pcx" },
{ "invisible_sand.EDITOR.xpos", "2" },
- { "invisible_sand.EDITOR.ypos", "5" },
- { "invisible_sand.active", "RocksSP.pcx" },
+ { "invisible_sand.EDITOR.ypos", "4" },
+ { "invisible_sand.active", "RocksEMC.pcx" },
{ "invisible_sand.active.xpos", "2" },
- { "invisible_sand.active.ypos", "5" },
+ { "invisible_sand.active.ypos", "4" },
{ "invisible_sand.active.frames", "1" },
+ { "invisible_sand.active.CRUMBLED", "RocksEMC.pcx" },
+ { "invisible_sand.active.CRUMBLED.xpos", "3" },
+ { "invisible_sand.active.CRUMBLED.ypos", "4" },
+ { "invisible_sand.active.CRUMBLED.frames", "1" },
+ { "invisible_sand.active.digging.left", "RocksEMC.pcx" },
+ { "invisible_sand.active.digging.left.xpos", "6" },
+ { "invisible_sand.active.digging.left.ypos", "2" },
+ { "invisible_sand.active.digging.left.frames","3" },
+ { "invisible_sand.active.digging.left.delay", "2" },
+ { "invisible_sand.active.digging.left.anim_mode","linear" },
+ { "invisible_sand.active.digging.right", "RocksEMC.pcx" },
+ { "invisible_sand.active.digging.right.xpos", "9" },
+ { "invisible_sand.active.digging.right.ypos", "2" },
+ { "invisible_sand.active.digging.right.frames","3" },
+ { "invisible_sand.active.digging.right.delay","2" },
+ { "invisible_sand.active.digging.right.anim_mode","linear" },
+ { "invisible_sand.active.digging.up", "RocksEMC.pcx" },
+ { "invisible_sand.active.digging.up.xpos", "0" },
+ { "invisible_sand.active.digging.up.ypos", "2" },
+ { "invisible_sand.active.digging.up.frames", "3" },
+ { "invisible_sand.active.digging.up.delay", "2" },
+ { "invisible_sand.active.digging.up.anim_mode","linear" },
+ { "invisible_sand.active.digging.down", "RocksEMC.pcx" },
+ { "invisible_sand.active.digging.down.xpos", "3" },
+ { "invisible_sand.active.digging.down.ypos", "2" },
+ { "invisible_sand.active.digging.down.frames","3" },
+ { "invisible_sand.active.digging.down.delay", "2" },
+ { "invisible_sand.active.digging.down.anim_mode","linear" },
+ { "invisible_sand.active.digging.left.CRUMBLED", "RocksEMC.pcx" },
+ { "invisible_sand.active.digging.left.CRUMBLED.xpos", "6" },
+ { "invisible_sand.active.digging.left.CRUMBLED.ypos", "3" },
+ { "invisible_sand.active.digging.left.CRUMBLED.frames","3" },
+ { "invisible_sand.active.digging.left.CRUMBLED.delay","2" },
+ { "invisible_sand.active.digging.left.CRUMBLED.anim_mode","linear" },
+ { "invisible_sand.active.digging.right.CRUMBLED", "RocksEMC.pcx" },
+ { "invisible_sand.active.digging.right.CRUMBLED.xpos","9" },
+ { "invisible_sand.active.digging.right.CRUMBLED.ypos","3" },
+ { "invisible_sand.active.digging.right.CRUMBLED.frames","3" },
+ { "invisible_sand.active.digging.right.CRUMBLED.delay","2" },
+ { "invisible_sand.active.digging.right.CRUMBLED.anim_mode","linear" },
+ { "invisible_sand.active.digging.up.CRUMBLED", "RocksEMC.pcx" },
+ { "invisible_sand.active.digging.up.CRUMBLED.xpos", "0" },
+ { "invisible_sand.active.digging.up.CRUMBLED.ypos", "3" },
+ { "invisible_sand.active.digging.up.CRUMBLED.frames", "3" },
+ { "invisible_sand.active.digging.up.CRUMBLED.delay", "2" },
+ { "invisible_sand.active.digging.up.CRUMBLED.anim_mode","linear" },
+ { "invisible_sand.active.digging.down.CRUMBLED", "RocksEMC.pcx" },
+ { "invisible_sand.active.digging.down.CRUMBLED.xpos", "3" },
+ { "invisible_sand.active.digging.down.CRUMBLED.ypos", "3" },
+ { "invisible_sand.active.digging.down.CRUMBLED.frames","3" },
+ { "invisible_sand.active.digging.down.CRUMBLED.delay","2" },
+ { "invisible_sand.active.digging.down.CRUMBLED.anim_mode","linear" },
{ "conveyor_belt_1_middle", "RocksDC.pcx" },
{ "conveyor_belt_1_middle.xpos", "0" },
{ "trigger_player.ypos", "13" },
{ "trigger_player.frames", "1" },
+ { "emc_key_5", "RocksEMC.pcx" },
+ { "emc_key_5.xpos", "0" },
+ { "emc_key_5.ypos", "5" },
+ { "emc_key_5.frames", "1" },
+ { "emc_key_6", "RocksEMC.pcx" },
+ { "emc_key_6.xpos", "1" },
+ { "emc_key_6.ypos", "5" },
+ { "emc_key_6.frames", "1" },
+ { "emc_key_7", "RocksEMC.pcx" },
+ { "emc_key_7.xpos", "2" },
+ { "emc_key_7.ypos", "5" },
+ { "emc_key_7.frames", "1" },
+ { "emc_key_8", "RocksEMC.pcx" },
+ { "emc_key_8.xpos", "3" },
+ { "emc_key_8.ypos", "5" },
+ { "emc_key_8.frames", "1" },
+
+ { "emc_gate_5", "RocksEMC.pcx" },
+ { "emc_gate_5.xpos", "0" },
+ { "emc_gate_5.ypos", "6" },
+ { "emc_gate_5.frames", "1" },
+ { "emc_gate_5_gray", "RocksEMC.pcx" },
+ { "emc_gate_5_gray.xpos", "4" },
+ { "emc_gate_5_gray.ypos", "7" },
+ { "emc_gate_5_gray.frames", "1" },
+ { "emc_gate_5_gray.EDITOR", "RocksEMC.pcx" },
+ { "emc_gate_5_gray.EDITOR.xpos", "0" },
+ { "emc_gate_5_gray.EDITOR.ypos", "7" },
+ { "emc_gate_6", "RocksEMC.pcx" },
+ { "emc_gate_6.xpos", "1" },
+ { "emc_gate_6.ypos", "6" },
+ { "emc_gate_6.frames", "1" },
+ { "emc_gate_6_gray", "RocksEMC.pcx" },
+ { "emc_gate_6_gray.xpos", "4" },
+ { "emc_gate_6_gray.ypos", "7" },
+ { "emc_gate_6_gray.frames", "1" },
+ { "emc_gate_6_gray.EDITOR", "RocksEMC.pcx" },
+ { "emc_gate_6_gray.EDITOR.xpos", "1" },
+ { "emc_gate_6_gray.EDITOR.ypos", "7" },
+ { "emc_gate_7", "RocksEMC.pcx" },
+ { "emc_gate_7.xpos", "2" },
+ { "emc_gate_7.ypos", "6" },
+ { "emc_gate_7.frames", "1" },
+ { "emc_gate_7_gray", "RocksEMC.pcx" },
+ { "emc_gate_7_gray.xpos", "4" },
+ { "emc_gate_7_gray.ypos", "7" },
+ { "emc_gate_7_gray.frames", "1" },
+ { "emc_gate_7_gray.EDITOR", "RocksEMC.pcx" },
+ { "emc_gate_7_gray.EDITOR.xpos", "2" },
+ { "emc_gate_7_gray.EDITOR.ypos", "7" },
+ { "emc_gate_8", "RocksEMC.pcx" },
+ { "emc_gate_8.xpos", "3" },
+ { "emc_gate_8.ypos", "6" },
+ { "emc_gate_8.frames", "1" },
+ { "emc_gate_8_gray", "RocksEMC.pcx" },
+ { "emc_gate_8_gray.xpos", "4" },
+ { "emc_gate_8_gray.ypos", "7" },
+ { "emc_gate_8_gray.frames", "1" },
+ { "emc_gate_8_gray.EDITOR", "RocksEMC.pcx" },
+ { "emc_gate_8_gray.EDITOR.xpos", "3" },
+ { "emc_gate_8_gray.EDITOR.ypos", "7" },
+
+ { "emc_android", "RocksEMC.pcx" },
+ { "emc_android.xpos", "0" },
+ { "emc_android.ypos", "8" },
+ { "emc_android.frames", "8" },
+
+ { "emc_grass", "RocksEMC.pcx" },
+ { "emc_grass.xpos", "0" },
+ { "emc_grass.ypos", "4" },
+ { "emc_grass.frames", "1" },
+ { "emc_grass.CRUMBLED", "RocksEMC.pcx" },
+ { "emc_grass.CRUMBLED.xpos", "1" },
+ { "emc_grass.CRUMBLED.ypos", "4" },
+ { "emc_grass.CRUMBLED.frames", "1" },
+ { "emc_grass.digging.left", "RocksEMC.pcx" },
+ { "emc_grass.digging.left.xpos", "6" },
+ { "emc_grass.digging.left.ypos", "0" },
+ { "emc_grass.digging.left.frames", "3" },
+ { "emc_grass.digging.left.delay", "2" },
+ { "emc_grass.digging.left.anim_mode", "linear" },
+ { "emc_grass.digging.right", "RocksEMC.pcx" },
+ { "emc_grass.digging.right.xpos", "9" },
+ { "emc_grass.digging.right.ypos", "0" },
+ { "emc_grass.digging.right.frames", "3" },
+ { "emc_grass.digging.right.delay", "2" },
+ { "emc_grass.digging.right.anim_mode", "linear" },
+ { "emc_grass.digging.up", "RocksEMC.pcx" },
+ { "emc_grass.digging.up.xpos", "0" },
+ { "emc_grass.digging.up.ypos", "0" },
+ { "emc_grass.digging.up.frames", "3" },
+ { "emc_grass.digging.up.delay", "2" },
+ { "emc_grass.digging.up.anim_mode", "linear" },
+ { "emc_grass.digging.down", "RocksEMC.pcx" },
+ { "emc_grass.digging.down.xpos", "3" },
+ { "emc_grass.digging.down.ypos", "0" },
+ { "emc_grass.digging.down.frames", "3" },
+ { "emc_grass.digging.down.delay", "2" },
+ { "emc_grass.digging.down.anim_mode", "linear" },
+ { "emc_grass.digging.left.CRUMBLED", "RocksEMC.pcx" },
+ { "emc_grass.digging.left.CRUMBLED.xpos", "6" },
+ { "emc_grass.digging.left.CRUMBLED.ypos", "1" },
+ { "emc_grass.digging.left.CRUMBLED.frames", "3" },
+ { "emc_grass.digging.left.CRUMBLED.delay", "2" },
+ { "emc_grass.digging.left.CRUMBLED.anim_mode","linear" },
+ { "emc_grass.digging.right.CRUMBLED", "RocksEMC.pcx" },
+ { "emc_grass.digging.right.CRUMBLED.xpos", "9" },
+ { "emc_grass.digging.right.CRUMBLED.ypos", "1" },
+ { "emc_grass.digging.right.CRUMBLED.frames", "3" },
+ { "emc_grass.digging.right.CRUMBLED.delay", "2" },
+ { "emc_grass.digging.right.CRUMBLED.anim_mode","linear" },
+ { "emc_grass.digging.up.CRUMBLED", "RocksEMC.pcx" },
+ { "emc_grass.digging.up.CRUMBLED.xpos", "0" },
+ { "emc_grass.digging.up.CRUMBLED.ypos", "1" },
+ { "emc_grass.digging.up.CRUMBLED.frames", "3" },
+ { "emc_grass.digging.up.CRUMBLED.delay", "2" },
+ { "emc_grass.digging.up.CRUMBLED.anim_mode", "linear" },
+ { "emc_grass.digging.down.CRUMBLED", "RocksEMC.pcx" },
+ { "emc_grass.digging.down.CRUMBLED.xpos", "3" },
+ { "emc_grass.digging.down.CRUMBLED.ypos", "1" },
+ { "emc_grass.digging.down.CRUMBLED.frames", "3" },
+ { "emc_grass.digging.down.CRUMBLED.delay", "2" },
+ { "emc_grass.digging.down.CRUMBLED.anim_mode","linear" },
+
+ { "emc_magic_ball", "RocksEMC.pcx" },
+ { "emc_magic_ball.xpos", "0" },
+ { "emc_magic_ball.ypos", "9" },
+ { "emc_magic_ball.frames", "1" },
+
+ { "emc_magic_ball.active", "RocksEMC.pcx" },
+ { "emc_magic_ball.active.xpos", "0" },
+ { "emc_magic_ball.active.ypos", "9" },
+ { "emc_magic_ball.active.frames", "16" },
+ { "emc_magic_ball.active.frames_per_line", "8" },
+
+ { "emc_magic_ball_switch", "RocksEMC.pcx" },
+ { "emc_magic_ball_switch.xpos", "8" },
+ { "emc_magic_ball_switch.ypos", "10" },
+ { "emc_magic_ball_switch.frames", "1" },
+
+ { "emc_magic_ball_switch.active", "RocksEMC.pcx" },
+ { "emc_magic_ball_switch.active.xpos", "8" },
+ { "emc_magic_ball_switch.active.ypos", "9" },
+ { "emc_magic_ball_switch.active.frames", "1" },
+
+ { "emc_spring_bumper", "RocksEMC.pcx" },
+ { "emc_spring_bumper.xpos", "8" },
+ { "emc_spring_bumper.ypos", "4" },
+ { "emc_spring_bumper.frames", "1" },
+
+ { "emc_spring_bumper.active", "RocksEMC.pcx" },
+ { "emc_spring_bumper.active.xpos", "8" },
+ { "emc_spring_bumper.active.ypos", "4" },
+ { "emc_spring_bumper.active.frames", "4" },
+ { "emc_spring_bumper.active.anim_mode", "pingpong2" },
+
+ { "emc_plant", "RocksEMC.pcx" },
+ { "emc_plant.xpos", "4" },
+ { "emc_plant.ypos", "4" },
+ { "emc_plant.frames", "1" },
+ { "emc_plant.CRUMBLED", "RocksEMC.pcx" },
+ { "emc_plant.CRUMBLED.xpos", "5" },
+ { "emc_plant.CRUMBLED.ypos", "4" },
+ { "emc_plant.CRUMBLED.frames", "1" },
+
+ { "emc_lenses", "RocksEMC.pcx" },
+ { "emc_lenses.xpos", "6" },
+ { "emc_lenses.ypos", "4" },
+ { "emc_lenses.frames", "1" },
+
+ { "emc_magnifier", "RocksEMC.pcx" },
+ { "emc_magnifier.xpos", "7" },
+ { "emc_magnifier.ypos", "4" },
+ { "emc_magnifier.frames", "1" },
+
+ { "emc_wall_9", "RocksEMC.pcx" },
+ { "emc_wall_9.xpos", "10" },
+ { "emc_wall_9.ypos", "5" },
+ { "emc_wall_9.frames", "1" },
+ { "emc_wall_10", "RocksEMC.pcx" },
+ { "emc_wall_10.xpos", "10" },
+ { "emc_wall_10.ypos", "6" },
+ { "emc_wall_10.frames", "1" },
+ { "emc_wall_11", "RocksEMC.pcx" },
+ { "emc_wall_11.xpos", "11" },
+ { "emc_wall_11.ypos", "5" },
+ { "emc_wall_11.frames", "1" },
+ { "emc_wall_12", "RocksEMC.pcx" },
+ { "emc_wall_12.xpos", "11" },
+ { "emc_wall_12.ypos", "6" },
+ { "emc_wall_12.frames", "1" },
+ { "emc_wall_13", "RocksEMC.pcx" },
+ { "emc_wall_13.xpos", "10" },
+ { "emc_wall_13.ypos", "7" },
+ { "emc_wall_13.frames", "1" },
+ { "emc_wall_14", "RocksEMC.pcx" },
+ { "emc_wall_14.xpos", "10" },
+ { "emc_wall_14.ypos", "8" },
+ { "emc_wall_14.frames", "1" },
+ { "emc_wall_15", "RocksEMC.pcx" },
+ { "emc_wall_15.xpos", "10" },
+ { "emc_wall_15.ypos", "9" },
+ { "emc_wall_15.frames", "1" },
+ { "emc_wall_16", "RocksEMC.pcx" },
+ { "emc_wall_16.xpos", "10" },
+ { "emc_wall_16.ypos", "10" },
+ { "emc_wall_16.frames", "1" },
+
+ { "emc_wall_slippery_1", "RocksEMC.pcx" },
+ { "emc_wall_slippery_1.xpos", "11" },
+ { "emc_wall_slippery_1.ypos", "7" },
+ { "emc_wall_slippery_1.frames", "1" },
+ { "emc_wall_slippery_2", "RocksEMC.pcx" },
+ { "emc_wall_slippery_2.xpos", "11" },
+ { "emc_wall_slippery_2.ypos", "8" },
+ { "emc_wall_slippery_2.frames", "1" },
+ { "emc_wall_slippery_3", "RocksEMC.pcx" },
+ { "emc_wall_slippery_3.xpos", "11" },
+ { "emc_wall_slippery_3.ypos", "9" },
+ { "emc_wall_slippery_3.frames", "1" },
+ { "emc_wall_slippery_4", "RocksEMC.pcx" },
+ { "emc_wall_slippery_4.xpos", "11" },
+ { "emc_wall_slippery_4.ypos", "10" },
+ { "emc_wall_slippery_4.frames", "1" },
+
+ { "emc_fake_grass", "RocksEMC.pcx" },
+ { "emc_fake_grass.xpos", "0" },
+ { "emc_fake_grass.ypos", "4" },
+ { "emc_fake_grass.frames", "1" },
+ { "emc_fake_grass.CRUMBLED", "RocksEMC.pcx" },
+ { "emc_fake_grass.CRUMBLED.xpos", "1" },
+ { "emc_fake_grass.CRUMBLED.ypos", "4" },
+ { "emc_fake_grass.CRUMBLED.frames", "1" },
+ { "emc_fake_grass.active", "RocksEMC.pcx" },
+ { "emc_fake_grass.active.xpos", "2" },
+ { "emc_fake_grass.active.ypos", "4" },
+ { "emc_fake_grass.active.frames", "1" },
+ { "emc_fake_grass.active.CRUMBLED", "RocksEMC.pcx" },
+ { "emc_fake_grass.active.CRUMBLED.xpos", "3" },
+ { "emc_fake_grass.active.CRUMBLED.ypos", "4" },
+ { "emc_fake_grass.active.CRUMBLED.frames", "1" },
+
+ { "emc_fake_acid", "RocksElements.pcx" },
+ { "emc_fake_acid.xpos", "12" },
+ { "emc_fake_acid.ypos", "7" },
+ { "emc_fake_acid.frames", "4" },
+ { "emc_fake_acid.delay", "10" },
+ { "emc_fake_acid.global_sync", "true" },
+
+ { "emc_dripper", "RocksSP.pcx" },
+ { "emc_dripper.xpos", "0" },
+ { "emc_dripper.ypos", "0" },
+ { "emc_dripper.frames", "1" },
+ { "emc_dripper.EDITOR", "RocksEMC.pcx" },
+ { "emc_dripper.EDITOR.xpos", "8" },
+ { "emc_dripper.EDITOR.ypos", "8" },
+ { "emc_dripper.active", "RocksEMC.pcx" },
+ { "emc_dripper.active.xpos", "8" },
+ { "emc_dripper.active.ypos", "8" },
+ { "emc_dripper.active.frames", "1" },
+
#include "conf_chr.c" /* include auto-generated data structure definitions */
#include "conf_cus.c" /* include auto-generated data structure definitions */
#include "conf_grp.c" /* include auto-generated data structure definitions */
/* images not associated to game elements (used for menu screens etc.) */
/* keyword to stop parser: "NO_MORE_ELEMENT_IMAGES" <-- do not change! */
+#if 1
+ /* !!! TEMPORARILY STORED HERE -- PROBABLY TO BE CHANGED !!! */
+
+ /* (for testing, change filename back to "emc_object dot pcx") */
+ { "emc_object", "RocksEMC.pcx" },
+#if 0
+ { "emc_object.scale_up_factor", "2" },
+#endif
+
+ /* (for testing, change filename back to "emc_sprite dot pcx") */
+ { "emc_sprite", "RocksEMC.pcx" },
+#if 0
+ { "emc_sprite.scale_up_factor", "2" },
+#endif
+#endif
+
{ "toon_1", "RocksToons.pcx" },
{ "toon_1.x", "2" },
{ "toon_1.y", "72" },
#define IMG_BD_AMOEBA 17
#define IMG_BD_AMOEBA_EDITOR 18
#define IMG_BD_BUTTERFLY 19
-#define IMG_BD_BUTTERFLY_RIGHT_EDITOR 20
-#define IMG_BD_BUTTERFLY_UP_EDITOR 21
-#define IMG_BD_BUTTERFLY_LEFT_EDITOR 22
-#define IMG_BD_BUTTERFLY_DOWN_EDITOR 23
-#define IMG_BD_FIREFLY 24
-#define IMG_BD_FIREFLY_RIGHT_EDITOR 25
-#define IMG_BD_FIREFLY_UP_EDITOR 26
-#define IMG_BD_FIREFLY_LEFT_EDITOR 27
-#define IMG_BD_FIREFLY_DOWN_EDITOR 28
-#define IMG_SP_DEFAULT_EXPLODING 29
-#define IMG_SP_ZONK 30
-#define IMG_SP_ZONK_MOVING_LEFT 31
-#define IMG_SP_ZONK_MOVING_RIGHT 32
-#define IMG_SP_ZONK_PUSHING_LEFT 33
-#define IMG_SP_ZONK_PUSHING_RIGHT 34
-#define IMG_SP_BASE 35
-#define IMG_SP_MURPHY 36
-#define IMG_SP_MURPHY_MOVING_LEFT 37
-#define IMG_SP_MURPHY_MOVING_RIGHT 38
-#define IMG_SP_MURPHY_DIGGING_LEFT 39
-#define IMG_SP_MURPHY_DIGGING_RIGHT 40
-#define IMG_SP_MURPHY_COLLECTING_LEFT 41
-#define IMG_SP_MURPHY_COLLECTING_RIGHT 42
-#define IMG_SP_MURPHY_PUSHING_LEFT 43
-#define IMG_SP_MURPHY_PUSHING_RIGHT 44
-#define IMG_SP_MURPHY_SNAPPING_LEFT 45
-#define IMG_SP_MURPHY_SNAPPING_RIGHT 46
-#define IMG_SP_MURPHY_SNAPPING_UP 47
-#define IMG_SP_MURPHY_SNAPPING_DOWN 48
-#define IMG_SP_MURPHY_CLONE 49
-#define IMG_SP_INFOTRON 50
-#define IMG_SP_INFOTRON_EDITOR 51
-#define IMG_SP_CHIP_SINGLE 52
-#define IMG_SP_CHIP_LEFT 53
-#define IMG_SP_CHIP_RIGHT 54
-#define IMG_SP_CHIP_TOP 55
-#define IMG_SP_CHIP_BOTTOM 56
-#define IMG_SP_HARDWARE_GRAY 57
-#define IMG_SP_HARDWARE_GREEN 58
-#define IMG_SP_HARDWARE_BLUE 59
-#define IMG_SP_HARDWARE_RED 60
-#define IMG_SP_HARDWARE_YELLOW 61
-#define IMG_SP_EXIT_CLOSED 62
-#define IMG_SP_EXIT_OPENING 63
-#define IMG_SP_EXIT_OPEN 64
-#define IMG_SP_EXIT_CLOSING 65
-#define IMG_SP_DISK_ORANGE 66
-#define IMG_SP_DISK_YELLOW 67
-#define IMG_SP_DISK_RED 68
-#define IMG_SP_DISK_RED_COLLECTING 69
-#define IMG_SP_DISK_RED_ACTIVE 70
-#define IMG_SP_PORT_RIGHT 71
-#define IMG_SP_PORT_DOWN 72
-#define IMG_SP_PORT_LEFT 73
-#define IMG_SP_PORT_UP 74
-#define IMG_SP_PORT_HORIZONTAL 75
-#define IMG_SP_PORT_VERTICAL 76
-#define IMG_SP_PORT_ANY 77
-#define IMG_SP_GRAVITY_PORT_RIGHT 78
-#define IMG_SP_GRAVITY_PORT_RIGHT_EDITOR 79
-#define IMG_SP_GRAVITY_PORT_DOWN 80
-#define IMG_SP_GRAVITY_PORT_DOWN_EDITOR 81
-#define IMG_SP_GRAVITY_PORT_LEFT 82
-#define IMG_SP_GRAVITY_PORT_LEFT_EDITOR 83
-#define IMG_SP_GRAVITY_PORT_UP 84
-#define IMG_SP_GRAVITY_PORT_UP_EDITOR 85
-#define IMG_SP_GRAVITY_ON_PORT_RIGHT 86
-#define IMG_SP_GRAVITY_ON_PORT_RIGHT_EDITOR 87
-#define IMG_SP_GRAVITY_ON_PORT_DOWN 88
-#define IMG_SP_GRAVITY_ON_PORT_DOWN_EDITOR 89
-#define IMG_SP_GRAVITY_ON_PORT_LEFT 90
-#define IMG_SP_GRAVITY_ON_PORT_LEFT_EDITOR 91
-#define IMG_SP_GRAVITY_ON_PORT_UP 92
-#define IMG_SP_GRAVITY_ON_PORT_UP_EDITOR 93
-#define IMG_SP_GRAVITY_OFF_PORT_RIGHT 94
-#define IMG_SP_GRAVITY_OFF_PORT_RIGHT_EDITOR 95
-#define IMG_SP_GRAVITY_OFF_PORT_DOWN 96
-#define IMG_SP_GRAVITY_OFF_PORT_DOWN_EDITOR 97
-#define IMG_SP_GRAVITY_OFF_PORT_LEFT 98
-#define IMG_SP_GRAVITY_OFF_PORT_LEFT_EDITOR 99
-#define IMG_SP_GRAVITY_OFF_PORT_UP 100
-#define IMG_SP_GRAVITY_OFF_PORT_UP_EDITOR 101
-#define IMG_SP_SNIKSNAK 102
-#define IMG_SP_SNIKSNAK_LEFT 103
-#define IMG_SP_SNIKSNAK_RIGHT 104
-#define IMG_SP_SNIKSNAK_UP 105
-#define IMG_SP_SNIKSNAK_DOWN 106
-#define IMG_SP_SNIKSNAK_TURNING_FROM_LEFT_UP 107
-#define IMG_SP_SNIKSNAK_TURNING_FROM_LEFT_DOWN 108
-#define IMG_SP_SNIKSNAK_TURNING_FROM_RIGHT_UP 109
-#define IMG_SP_SNIKSNAK_TURNING_FROM_RIGHT_DOWN 110
-#define IMG_SP_SNIKSNAK_TURNING_FROM_UP_LEFT 111
-#define IMG_SP_SNIKSNAK_TURNING_FROM_UP_RIGHT 112
-#define IMG_SP_SNIKSNAK_TURNING_FROM_DOWN_LEFT 113
-#define IMG_SP_SNIKSNAK_TURNING_FROM_DOWN_RIGHT 114
-#define IMG_SP_ELECTRON 115
-#define IMG_SP_ELECTRON_EDITOR 116
-#define IMG_SP_ELECTRON_EXPLODING 117
-#define IMG_SP_TERMINAL 118
-#define IMG_SP_TERMINAL_EDITOR 119
-#define IMG_SP_TERMINAL_ACTIVE 120
-#define IMG_SP_BUGGY_BASE 121
-#define IMG_SP_BUGGY_BASE_EDITOR 122
-#define IMG_SP_BUGGY_BASE_ACTIVATING 123
-#define IMG_SP_BUGGY_BASE_ACTIVE 124
-#define IMG_SP_HARDWARE_BASE_1 125
-#define IMG_SP_HARDWARE_BASE_2 126
-#define IMG_SP_HARDWARE_BASE_3 127
-#define IMG_SP_HARDWARE_BASE_4 128
-#define IMG_SP_HARDWARE_BASE_5 129
-#define IMG_SP_HARDWARE_BASE_6 130
-#define IMG_SOKOBAN_OBJECT 131
-#define IMG_SOKOBAN_OBJECT_EDITOR 132
-#define IMG_SOKOBAN_FIELD_EMPTY 133
-#define IMG_SOKOBAN_FIELD_FULL 134
-#define IMG_SOKOBAN_FIELD_PLAYER 135
-#define IMG_SOKOBAN_FIELD_PLAYER_EDITOR 136
-#define IMG_EMPTY_SPACE 137
-#define IMG_SAND 138
-#define IMG_SAND_CRUMBLED 139
-#define IMG_SAND_DIGGING_LEFT 140
-#define IMG_SAND_DIGGING_RIGHT 141
-#define IMG_SAND_DIGGING_UP 142
-#define IMG_SAND_DIGGING_DOWN 143
-#define IMG_SAND_DIGGING_LEFT_CRUMBLED 144
-#define IMG_SAND_DIGGING_RIGHT_CRUMBLED 145
-#define IMG_SAND_DIGGING_UP_CRUMBLED 146
-#define IMG_SAND_DIGGING_DOWN_CRUMBLED 147
-#define IMG_WALL 148
-#define IMG_WALL_SLIPPERY 149
-#define IMG_STEELWALL 150
-#define IMG_ROCK 151
-#define IMG_ROCK_MOVING_LEFT 152
-#define IMG_ROCK_MOVING_RIGHT 153
-#define IMG_ROCK_PUSHING_LEFT 154
-#define IMG_ROCK_PUSHING_RIGHT 155
-#define IMG_EMERALD 156
-#define IMG_EMERALD_MOVING 157
-#define IMG_EMERALD_FALLING 158
-#define IMG_EMERALD_COLLECTING 159
-#define IMG_DIAMOND 160
-#define IMG_DIAMOND_MOVING 161
-#define IMG_DIAMOND_FALLING 162
-#define IMG_DIAMOND_COLLECTING 163
-#define IMG_BOMB 164
-#define IMG_NUT 165
-#define IMG_NUT_BREAKING 166
-#define IMG_DYNAMITE 167
-#define IMG_DYNAMITE_EDITOR 168
-#define IMG_DYNAMITE_ACTIVE 169
-#define IMG_DYNAMITE_ACTIVE_EDITOR 170
-#define IMG_WALL_EMERALD 171
-#define IMG_WALL_DIAMOND 172
-#define IMG_BUG 173
-#define IMG_BUG_RIGHT 174
-#define IMG_BUG_UP 175
-#define IMG_BUG_LEFT 176
-#define IMG_BUG_DOWN 177
-#define IMG_BUG_MOVING_RIGHT 178
-#define IMG_BUG_MOVING_UP 179
-#define IMG_BUG_MOVING_LEFT 180
-#define IMG_BUG_MOVING_DOWN 181
-#define IMG_BUG_TURNING_FROM_RIGHT_UP 182
-#define IMG_BUG_TURNING_FROM_UP_LEFT 183
-#define IMG_BUG_TURNING_FROM_LEFT_DOWN 184
-#define IMG_BUG_TURNING_FROM_DOWN_RIGHT 185
-#define IMG_BUG_TURNING_FROM_RIGHT_DOWN 186
-#define IMG_BUG_TURNING_FROM_UP_RIGHT 187
-#define IMG_BUG_TURNING_FROM_LEFT_UP 188
-#define IMG_BUG_TURNING_FROM_DOWN_LEFT 189
-#define IMG_SPACESHIP 190
-#define IMG_SPACESHIP_RIGHT 191
-#define IMG_SPACESHIP_UP 192
-#define IMG_SPACESHIP_LEFT 193
-#define IMG_SPACESHIP_DOWN 194
-#define IMG_SPACESHIP_MOVING_RIGHT 195
-#define IMG_SPACESHIP_MOVING_UP 196
-#define IMG_SPACESHIP_MOVING_LEFT 197
-#define IMG_SPACESHIP_MOVING_DOWN 198
-#define IMG_SPACESHIP_TURNING_FROM_RIGHT_UP 199
-#define IMG_SPACESHIP_TURNING_FROM_UP_LEFT 200
-#define IMG_SPACESHIP_TURNING_FROM_LEFT_DOWN 201
-#define IMG_SPACESHIP_TURNING_FROM_DOWN_RIGHT 202
-#define IMG_SPACESHIP_TURNING_FROM_RIGHT_DOWN 203
-#define IMG_SPACESHIP_TURNING_FROM_UP_RIGHT 204
-#define IMG_SPACESHIP_TURNING_FROM_LEFT_UP 205
-#define IMG_SPACESHIP_TURNING_FROM_DOWN_LEFT 206
-#define IMG_YAMYAM 207
-#define IMG_YAMYAM_MOVING 208
-#define IMG_ROBOT 209
-#define IMG_ROBOT_MOVING 210
-#define IMG_ROBOT_WHEEL 211
-#define IMG_ROBOT_WHEEL_ACTIVE 212
-#define IMG_MAGIC_WALL 213
-#define IMG_MAGIC_WALL_ACTIVE 214
-#define IMG_MAGIC_WALL_FILLING 215
-#define IMG_MAGIC_WALL_FULL 216
-#define IMG_MAGIC_WALL_EMPTYING 217
-#define IMG_MAGIC_WALL_DEAD 218
-#define IMG_QUICKSAND_EMPTY 219
-#define IMG_QUICKSAND_FILLING 220
-#define IMG_QUICKSAND_FULL 221
-#define IMG_QUICKSAND_FULL_EDITOR 222
-#define IMG_QUICKSAND_EMPTYING 223
-#define IMG_ACID_POOL_TOPLEFT 224
-#define IMG_ACID_POOL_TOPRIGHT 225
-#define IMG_ACID_POOL_BOTTOMLEFT 226
-#define IMG_ACID_POOL_BOTTOM 227
-#define IMG_ACID_POOL_BOTTOMRIGHT 228
-#define IMG_ACID 229
-#define IMG_ACID_SPLASH_LEFT 230
-#define IMG_ACID_SPLASH_RIGHT 231
-#define IMG_AMOEBA_DROP 232
-#define IMG_AMOEBA_GROWING 233
-#define IMG_AMOEBA_SHRINKING 234
-#define IMG_AMOEBA_WET 235
-#define IMG_AMOEBA_WET_EDITOR 236
-#define IMG_AMOEBA_DROPPING 237
-#define IMG_AMOEBA_DRY 238
-#define IMG_AMOEBA_FULL 239
-#define IMG_AMOEBA_FULL_EDITOR 240
-#define IMG_AMOEBA_DEAD 241
-#define IMG_AMOEBA_DEAD_EDITOR 242
-#define IMG_EM_KEY_1 243
-#define IMG_EM_KEY_2 244
-#define IMG_EM_KEY_3 245
-#define IMG_EM_KEY_4 246
-#define IMG_EM_GATE_1 247
-#define IMG_EM_GATE_2 248
-#define IMG_EM_GATE_3 249
-#define IMG_EM_GATE_4 250
-#define IMG_EM_GATE_1_GRAY 251
-#define IMG_EM_GATE_1_GRAY_EDITOR 252
-#define IMG_EM_GATE_2_GRAY 253
-#define IMG_EM_GATE_2_GRAY_EDITOR 254
-#define IMG_EM_GATE_3_GRAY 255
-#define IMG_EM_GATE_3_GRAY_EDITOR 256
-#define IMG_EM_GATE_4_GRAY 257
-#define IMG_EM_GATE_4_GRAY_EDITOR 258
-#define IMG_EXIT_CLOSED 259
-#define IMG_EXIT_OPENING 260
-#define IMG_EXIT_OPEN 261
-#define IMG_EXIT_CLOSING 262
-#define IMG_BALLOON 263
-#define IMG_BALLOON_MOVING 264
-#define IMG_BALLOON_PUSHING 265
-#define IMG_BALLOON_SWITCH_LEFT 266
-#define IMG_BALLOON_SWITCH_RIGHT 267
-#define IMG_BALLOON_SWITCH_UP 268
-#define IMG_BALLOON_SWITCH_DOWN 269
-#define IMG_BALLOON_SWITCH_ANY 270
-#define IMG_SPRING 271
-#define IMG_EMC_STEELWALL_1 272
-#define IMG_EMC_STEELWALL_2 273
-#define IMG_EMC_STEELWALL_3 274
-#define IMG_EMC_STEELWALL_4 275
-#define IMG_EMC_WALL_1 276
-#define IMG_EMC_WALL_2 277
-#define IMG_EMC_WALL_3 278
-#define IMG_EMC_WALL_4 279
-#define IMG_EMC_WALL_5 280
-#define IMG_EMC_WALL_6 281
-#define IMG_EMC_WALL_7 282
-#define IMG_EMC_WALL_8 283
-#define IMG_INVISIBLE_STEELWALL 284
-#define IMG_INVISIBLE_STEELWALL_EDITOR 285
-#define IMG_INVISIBLE_STEELWALL_ACTIVE 286
-#define IMG_INVISIBLE_WALL 287
-#define IMG_INVISIBLE_WALL_EDITOR 288
-#define IMG_INVISIBLE_WALL_ACTIVE 289
-#define IMG_INVISIBLE_SAND 290
-#define IMG_INVISIBLE_SAND_EDITOR 291
-#define IMG_INVISIBLE_SAND_ACTIVE 292
-#define IMG_CONVEYOR_BELT_1_MIDDLE 293
-#define IMG_CONVEYOR_BELT_1_MIDDLE_ACTIVE 294
-#define IMG_CONVEYOR_BELT_1_LEFT 295
-#define IMG_CONVEYOR_BELT_1_LEFT_ACTIVE 296
-#define IMG_CONVEYOR_BELT_1_RIGHT 297
-#define IMG_CONVEYOR_BELT_1_RIGHT_ACTIVE 298
-#define IMG_CONVEYOR_BELT_1_SWITCH_LEFT 299
-#define IMG_CONVEYOR_BELT_1_SWITCH_MIDDLE 300
-#define IMG_CONVEYOR_BELT_1_SWITCH_RIGHT 301
-#define IMG_CONVEYOR_BELT_2_MIDDLE 302
-#define IMG_CONVEYOR_BELT_2_MIDDLE_ACTIVE 303
-#define IMG_CONVEYOR_BELT_2_LEFT 304
-#define IMG_CONVEYOR_BELT_2_LEFT_ACTIVE 305
-#define IMG_CONVEYOR_BELT_2_RIGHT 306
-#define IMG_CONVEYOR_BELT_2_RIGHT_ACTIVE 307
-#define IMG_CONVEYOR_BELT_2_SWITCH_LEFT 308
-#define IMG_CONVEYOR_BELT_2_SWITCH_MIDDLE 309
-#define IMG_CONVEYOR_BELT_2_SWITCH_RIGHT 310
-#define IMG_CONVEYOR_BELT_3_MIDDLE 311
-#define IMG_CONVEYOR_BELT_3_MIDDLE_ACTIVE 312
-#define IMG_CONVEYOR_BELT_3_LEFT 313
-#define IMG_CONVEYOR_BELT_3_LEFT_ACTIVE 314
-#define IMG_CONVEYOR_BELT_3_RIGHT 315
-#define IMG_CONVEYOR_BELT_3_RIGHT_ACTIVE 316
-#define IMG_CONVEYOR_BELT_3_SWITCH_LEFT 317
-#define IMG_CONVEYOR_BELT_3_SWITCH_MIDDLE 318
-#define IMG_CONVEYOR_BELT_3_SWITCH_RIGHT 319
-#define IMG_CONVEYOR_BELT_4_MIDDLE 320
-#define IMG_CONVEYOR_BELT_4_MIDDLE_ACTIVE 321
-#define IMG_CONVEYOR_BELT_4_LEFT 322
-#define IMG_CONVEYOR_BELT_4_LEFT_ACTIVE 323
-#define IMG_CONVEYOR_BELT_4_RIGHT 324
-#define IMG_CONVEYOR_BELT_4_RIGHT_ACTIVE 325
-#define IMG_CONVEYOR_BELT_4_SWITCH_LEFT 326
-#define IMG_CONVEYOR_BELT_4_SWITCH_MIDDLE 327
-#define IMG_CONVEYOR_BELT_4_SWITCH_RIGHT 328
-#define IMG_SWITCHGATE_SWITCH_UP 329
-#define IMG_SWITCHGATE_SWITCH_DOWN 330
-#define IMG_LIGHT_SWITCH 331
-#define IMG_LIGHT_SWITCH_ACTIVE 332
-#define IMG_TIMEGATE_SWITCH 333
-#define IMG_TIMEGATE_SWITCH_ACTIVE 334
-#define IMG_ENVELOPE_1 335
-#define IMG_ENVELOPE_1_COLLECTING 336
-#define IMG_ENVELOPE_2 337
-#define IMG_ENVELOPE_2_COLLECTING 338
-#define IMG_ENVELOPE_3 339
-#define IMG_ENVELOPE_3_COLLECTING 340
-#define IMG_ENVELOPE_4 341
-#define IMG_ENVELOPE_4_COLLECTING 342
-#define IMG_SIGN_EXCLAMATION 343
-#define IMG_SIGN_STOP 344
-#define IMG_LANDMINE 345
-#define IMG_STEELWALL_SLIPPERY 346
-#define IMG_EXTRA_TIME 347
-#define IMG_SHIELD_NORMAL 348
-#define IMG_SHIELD_NORMAL_ACTIVE 349
-#define IMG_SHIELD_DEADLY 350
-#define IMG_SHIELD_DEADLY_ACTIVE 351
-#define IMG_SWITCHGATE_CLOSED 352
-#define IMG_SWITCHGATE_OPENING 353
-#define IMG_SWITCHGATE_OPEN 354
-#define IMG_SWITCHGATE_CLOSING 355
-#define IMG_TIMEGATE_CLOSED 356
-#define IMG_TIMEGATE_OPENING 357
-#define IMG_TIMEGATE_OPEN 358
-#define IMG_TIMEGATE_CLOSING 359
-#define IMG_PEARL 360
-#define IMG_PEARL_BREAKING 361
-#define IMG_CRYSTAL 362
-#define IMG_WALL_PEARL 363
-#define IMG_WALL_CRYSTAL 364
-#define IMG_TUBE_RIGHT_DOWN 365
-#define IMG_TUBE_HORIZONTAL_DOWN 366
-#define IMG_TUBE_LEFT_DOWN 367
-#define IMG_TUBE_HORIZONTAL 368
-#define IMG_TUBE_VERTICAL_RIGHT 369
-#define IMG_TUBE_ANY 370
-#define IMG_TUBE_VERTICAL_LEFT 371
-#define IMG_TUBE_VERTICAL 372
-#define IMG_TUBE_RIGHT_UP 373
-#define IMG_TUBE_HORIZONTAL_UP 374
-#define IMG_TUBE_LEFT_UP 375
-#define IMG_TRAP 376
-#define IMG_TRAP_ACTIVE 377
-#define IMG_DX_SUPABOMB 378
-#define IMG_KEY_1 379
-#define IMG_KEY_1_EDITOR 380
-#define IMG_KEY_2 381
-#define IMG_KEY_2_EDITOR 382
-#define IMG_KEY_3 383
-#define IMG_KEY_3_EDITOR 384
-#define IMG_KEY_4 385
-#define IMG_KEY_4_EDITOR 386
-#define IMG_GATE_1 387
-#define IMG_GATE_2 388
-#define IMG_GATE_3 389
-#define IMG_GATE_4 390
-#define IMG_GATE_1_GRAY 391
-#define IMG_GATE_1_GRAY_EDITOR 392
-#define IMG_GATE_2_GRAY 393
-#define IMG_GATE_2_GRAY_EDITOR 394
-#define IMG_GATE_3_GRAY 395
-#define IMG_GATE_3_GRAY_EDITOR 396
-#define IMG_GATE_4_GRAY 397
-#define IMG_GATE_4_GRAY_EDITOR 398
-#define IMG_GAME_OF_LIFE 399
-#define IMG_BIOMAZE 400
-#define IMG_PACMAN 401
-#define IMG_PACMAN_RIGHT 402
-#define IMG_PACMAN_UP 403
-#define IMG_PACMAN_LEFT 404
-#define IMG_PACMAN_DOWN 405
-#define IMG_PACMAN_TURNING_FROM_RIGHT 406
-#define IMG_PACMAN_TURNING_FROM_UP 407
-#define IMG_PACMAN_TURNING_FROM_LEFT 408
-#define IMG_PACMAN_TURNING_FROM_DOWN 409
-#define IMG_LAMP 410
-#define IMG_LAMP_EDITOR 411
-#define IMG_LAMP_ACTIVE 412
-#define IMG_TIME_ORB_FULL 413
-#define IMG_TIME_ORB_EMPTY 414
-#define IMG_EMERALD_YELLOW 415
-#define IMG_EMERALD_YELLOW_MOVING 416
-#define IMG_EMERALD_YELLOW_FALLING 417
-#define IMG_EMERALD_RED 418
-#define IMG_EMERALD_RED_MOVING 419
-#define IMG_EMERALD_RED_FALLING 420
-#define IMG_EMERALD_PURPLE 421
-#define IMG_EMERALD_PURPLE_MOVING 422
-#define IMG_EMERALD_PURPLE_FALLING 423
-#define IMG_WALL_EMERALD_YELLOW 424
-#define IMG_WALL_EMERALD_RED 425
-#define IMG_WALL_EMERALD_PURPLE 426
-#define IMG_WALL_BD_DIAMOND 427
-#define IMG_EXPANDABLE_WALL 428
-#define IMG_EXPANDABLE_WALL_HORIZONTAL 429
-#define IMG_EXPANDABLE_WALL_HORIZONTAL_EDITOR 430
-#define IMG_EXPANDABLE_WALL_VERTICAL 431
-#define IMG_EXPANDABLE_WALL_VERTICAL_EDITOR 432
-#define IMG_EXPANDABLE_WALL_ANY 433
-#define IMG_EXPANDABLE_WALL_ANY_EDITOR 434
-#define IMG_EXPANDABLE_WALL_GROWING_LEFT 435
-#define IMG_EXPANDABLE_WALL_GROWING_RIGHT 436
-#define IMG_EXPANDABLE_WALL_GROWING_UP 437
-#define IMG_EXPANDABLE_WALL_GROWING_DOWN 438
-#define IMG_BLACK_ORB 439
-#define IMG_SPEED_PILL 440
-#define IMG_DARK_YAMYAM 441
-#define IMG_DYNABOMB 442
-#define IMG_DYNABOMB_ACTIVE 443
-#define IMG_DYNABOMB_PLAYER_1 444
-#define IMG_DYNABOMB_PLAYER_1_ACTIVE 445
-#define IMG_DYNABOMB_PLAYER_2 446
-#define IMG_DYNABOMB_PLAYER_2_ACTIVE 447
-#define IMG_DYNABOMB_PLAYER_3 448
-#define IMG_DYNABOMB_PLAYER_3_ACTIVE 449
-#define IMG_DYNABOMB_PLAYER_4 450
-#define IMG_DYNABOMB_PLAYER_4_ACTIVE 451
-#define IMG_DYNABOMB_INCREASE_NUMBER 452
-#define IMG_DYNABOMB_INCREASE_SIZE 453
-#define IMG_DYNABOMB_INCREASE_POWER 454
-#define IMG_PIG 455
-#define IMG_PIG_DOWN 456
-#define IMG_PIG_UP 457
-#define IMG_PIG_LEFT 458
-#define IMG_PIG_RIGHT 459
-#define IMG_PIG_MOVING_DOWN 460
-#define IMG_PIG_MOVING_UP 461
-#define IMG_PIG_MOVING_LEFT 462
-#define IMG_PIG_MOVING_RIGHT 463
-#define IMG_PIG_DIGGING_DOWN 464
-#define IMG_PIG_DIGGING_UP 465
-#define IMG_PIG_DIGGING_LEFT 466
-#define IMG_PIG_DIGGING_RIGHT 467
-#define IMG_DRAGON 468
-#define IMG_DRAGON_DOWN 469
-#define IMG_DRAGON_UP 470
-#define IMG_DRAGON_LEFT 471
-#define IMG_DRAGON_RIGHT 472
-#define IMG_DRAGON_MOVING_DOWN 473
-#define IMG_DRAGON_MOVING_UP 474
-#define IMG_DRAGON_MOVING_LEFT 475
-#define IMG_DRAGON_MOVING_RIGHT 476
-#define IMG_DRAGON_ATTACKING_DOWN 477
-#define IMG_DRAGON_ATTACKING_UP 478
-#define IMG_DRAGON_ATTACKING_LEFT 479
-#define IMG_DRAGON_ATTACKING_RIGHT 480
-#define IMG_MOLE 481
-#define IMG_MOLE_DOWN 482
-#define IMG_MOLE_UP 483
-#define IMG_MOLE_LEFT 484
-#define IMG_MOLE_RIGHT 485
-#define IMG_MOLE_MOVING_DOWN 486
-#define IMG_MOLE_MOVING_UP 487
-#define IMG_MOLE_MOVING_LEFT 488
-#define IMG_MOLE_MOVING_RIGHT 489
-#define IMG_MOLE_DIGGING_DOWN 490
-#define IMG_MOLE_DIGGING_UP 491
-#define IMG_MOLE_DIGGING_LEFT 492
-#define IMG_MOLE_DIGGING_RIGHT 493
-#define IMG_PENGUIN 494
-#define IMG_PENGUIN_EDITOR 495
-#define IMG_PENGUIN_DOWN 496
-#define IMG_PENGUIN_UP 497
-#define IMG_PENGUIN_LEFT 498
-#define IMG_PENGUIN_RIGHT 499
-#define IMG_PENGUIN_MOVING_DOWN 500
-#define IMG_PENGUIN_MOVING_UP 501
-#define IMG_PENGUIN_MOVING_LEFT 502
-#define IMG_PENGUIN_MOVING_RIGHT 503
-#define IMG_SATELLITE 504
-#define IMG_FLAMES_1_LEFT 505
-#define IMG_FLAMES_2_LEFT 506
-#define IMG_FLAMES_3_LEFT 507
-#define IMG_FLAMES_1_RIGHT 508
-#define IMG_FLAMES_2_RIGHT 509
-#define IMG_FLAMES_3_RIGHT 510
-#define IMG_FLAMES_1_UP 511
-#define IMG_FLAMES_2_UP 512
-#define IMG_FLAMES_3_UP 513
-#define IMG_FLAMES_1_DOWN 514
-#define IMG_FLAMES_2_DOWN 515
-#define IMG_FLAMES_3_DOWN 516
-#define IMG_STONEBLOCK 517
-#define IMG_PLAYER_1 518
-#define IMG_PLAYER_1_EDITOR 519
-#define IMG_PLAYER_1_DOWN 520
-#define IMG_PLAYER_1_UP 521
-#define IMG_PLAYER_1_LEFT 522
-#define IMG_PLAYER_1_RIGHT 523
-#define IMG_PLAYER_1_MOVING_DOWN 524
-#define IMG_PLAYER_1_MOVING_UP 525
-#define IMG_PLAYER_1_MOVING_LEFT 526
-#define IMG_PLAYER_1_MOVING_RIGHT 527
-#define IMG_PLAYER_1_DIGGING_DOWN 528
-#define IMG_PLAYER_1_DIGGING_UP 529
-#define IMG_PLAYER_1_DIGGING_LEFT 530
-#define IMG_PLAYER_1_DIGGING_RIGHT 531
-#define IMG_PLAYER_1_COLLECTING_DOWN 532
-#define IMG_PLAYER_1_COLLECTING_UP 533
-#define IMG_PLAYER_1_COLLECTING_LEFT 534
-#define IMG_PLAYER_1_COLLECTING_RIGHT 535
-#define IMG_PLAYER_1_PUSHING_DOWN 536
-#define IMG_PLAYER_1_PUSHING_UP 537
-#define IMG_PLAYER_1_PUSHING_LEFT 538
-#define IMG_PLAYER_1_PUSHING_RIGHT 539
-#define IMG_PLAYER_1_SNAPPING_DOWN 540
-#define IMG_PLAYER_1_SNAPPING_UP 541
-#define IMG_PLAYER_1_SNAPPING_LEFT 542
-#define IMG_PLAYER_1_SNAPPING_RIGHT 543
-#define IMG_PLAYER_2 544
-#define IMG_PLAYER_2_EDITOR 545
-#define IMG_PLAYER_2_DOWN 546
-#define IMG_PLAYER_2_UP 547
-#define IMG_PLAYER_2_LEFT 548
-#define IMG_PLAYER_2_RIGHT 549
-#define IMG_PLAYER_2_MOVING_DOWN 550
-#define IMG_PLAYER_2_MOVING_UP 551
-#define IMG_PLAYER_2_MOVING_LEFT 552
-#define IMG_PLAYER_2_MOVING_RIGHT 553
-#define IMG_PLAYER_2_DIGGING_DOWN 554
-#define IMG_PLAYER_2_DIGGING_UP 555
-#define IMG_PLAYER_2_DIGGING_LEFT 556
-#define IMG_PLAYER_2_DIGGING_RIGHT 557
-#define IMG_PLAYER_2_COLLECTING_DOWN 558
-#define IMG_PLAYER_2_COLLECTING_UP 559
-#define IMG_PLAYER_2_COLLECTING_LEFT 560
-#define IMG_PLAYER_2_COLLECTING_RIGHT 561
-#define IMG_PLAYER_2_PUSHING_DOWN 562
-#define IMG_PLAYER_2_PUSHING_UP 563
-#define IMG_PLAYER_2_PUSHING_LEFT 564
-#define IMG_PLAYER_2_PUSHING_RIGHT 565
-#define IMG_PLAYER_2_SNAPPING_DOWN 566
-#define IMG_PLAYER_2_SNAPPING_UP 567
-#define IMG_PLAYER_2_SNAPPING_LEFT 568
-#define IMG_PLAYER_2_SNAPPING_RIGHT 569
-#define IMG_PLAYER_3 570
-#define IMG_PLAYER_3_EDITOR 571
-#define IMG_PLAYER_3_DOWN 572
-#define IMG_PLAYER_3_UP 573
-#define IMG_PLAYER_3_LEFT 574
-#define IMG_PLAYER_3_RIGHT 575
-#define IMG_PLAYER_3_MOVING_DOWN 576
-#define IMG_PLAYER_3_MOVING_UP 577
-#define IMG_PLAYER_3_MOVING_LEFT 578
-#define IMG_PLAYER_3_MOVING_RIGHT 579
-#define IMG_PLAYER_3_DIGGING_DOWN 580
-#define IMG_PLAYER_3_DIGGING_UP 581
-#define IMG_PLAYER_3_DIGGING_LEFT 582
-#define IMG_PLAYER_3_DIGGING_RIGHT 583
-#define IMG_PLAYER_3_COLLECTING_DOWN 584
-#define IMG_PLAYER_3_COLLECTING_UP 585
-#define IMG_PLAYER_3_COLLECTING_LEFT 586
-#define IMG_PLAYER_3_COLLECTING_RIGHT 587
-#define IMG_PLAYER_3_PUSHING_DOWN 588
-#define IMG_PLAYER_3_PUSHING_UP 589
-#define IMG_PLAYER_3_PUSHING_LEFT 590
-#define IMG_PLAYER_3_PUSHING_RIGHT 591
-#define IMG_PLAYER_3_SNAPPING_DOWN 592
-#define IMG_PLAYER_3_SNAPPING_UP 593
-#define IMG_PLAYER_3_SNAPPING_LEFT 594
-#define IMG_PLAYER_3_SNAPPING_RIGHT 595
-#define IMG_PLAYER_4 596
-#define IMG_PLAYER_4_EDITOR 597
-#define IMG_PLAYER_4_DOWN 598
-#define IMG_PLAYER_4_UP 599
-#define IMG_PLAYER_4_LEFT 600
-#define IMG_PLAYER_4_RIGHT 601
-#define IMG_PLAYER_4_MOVING_DOWN 602
-#define IMG_PLAYER_4_MOVING_UP 603
-#define IMG_PLAYER_4_MOVING_LEFT 604
-#define IMG_PLAYER_4_MOVING_RIGHT 605
-#define IMG_PLAYER_4_DIGGING_DOWN 606
-#define IMG_PLAYER_4_DIGGING_UP 607
-#define IMG_PLAYER_4_DIGGING_LEFT 608
-#define IMG_PLAYER_4_DIGGING_RIGHT 609
-#define IMG_PLAYER_4_COLLECTING_DOWN 610
-#define IMG_PLAYER_4_COLLECTING_UP 611
-#define IMG_PLAYER_4_COLLECTING_LEFT 612
-#define IMG_PLAYER_4_COLLECTING_RIGHT 613
-#define IMG_PLAYER_4_PUSHING_DOWN 614
-#define IMG_PLAYER_4_PUSHING_UP 615
-#define IMG_PLAYER_4_PUSHING_LEFT 616
-#define IMG_PLAYER_4_PUSHING_RIGHT 617
-#define IMG_PLAYER_4_SNAPPING_DOWN 618
-#define IMG_PLAYER_4_SNAPPING_UP 619
-#define IMG_PLAYER_4_SNAPPING_LEFT 620
-#define IMG_PLAYER_4_SNAPPING_RIGHT 621
-#define IMG_DEFAULT_EXPLODING 622
-#define IMG_TWINKLE_BLUE 623
-#define IMG_TWINKLE_WHITE 624
-#define IMG_STEELWALL_TOPLEFT 625
-#define IMG_STEELWALL_TOPRIGHT 626
-#define IMG_STEELWALL_BOTTOMLEFT 627
-#define IMG_STEELWALL_BOTTOMRIGHT 628
-#define IMG_STEELWALL_HORIZONTAL 629
-#define IMG_STEELWALL_VERTICAL 630
-#define IMG_STEELWALL_TOPLEFT_EDITOR 631
-#define IMG_STEELWALL_TOPRIGHT_EDITOR 632
-#define IMG_STEELWALL_BOTTOMLEFT_EDITOR 633
-#define IMG_STEELWALL_BOTTOMRIGHT_EDITOR 634
-#define IMG_STEELWALL_HORIZONTAL_EDITOR 635
-#define IMG_STEELWALL_VERTICAL_EDITOR 636
-#define IMG_INVISIBLE_STEELWALL_TOPLEFT 637
-#define IMG_INVISIBLE_STEELWALL_TOPRIGHT 638
-#define IMG_INVISIBLE_STEELWALL_BOTTOMLEFT 639
-#define IMG_INVISIBLE_STEELWALL_BOTTOMRIGHT 640
-#define IMG_INVISIBLE_STEELWALL_HORIZONTAL 641
-#define IMG_INVISIBLE_STEELWALL_VERTICAL 642
-#define IMG_INVISIBLE_STEELWALL_TOPLEFT_EDITOR 643
-#define IMG_INVISIBLE_STEELWALL_TOPRIGHT_EDITOR 644
-#define IMG_INVISIBLE_STEELWALL_BOTTOMLEFT_EDITOR 645
-#define IMG_INVISIBLE_STEELWALL_BOTTOMRIGHT_EDITOR 646
-#define IMG_INVISIBLE_STEELWALL_HORIZONTAL_EDITOR 647
-#define IMG_INVISIBLE_STEELWALL_VERTICAL_EDITOR 648
-#define IMG_ARROW_LEFT 649
-#define IMG_ARROW_RIGHT 650
-#define IMG_ARROW_UP 651
-#define IMG_ARROW_DOWN 652
-#define IMG_UNKNOWN 653
-#define IMG_TRIGGER_ELEMENT 654
-#define IMG_TRIGGER_PLAYER 655
-#define IMG_CHAR_SPACE 656
-#define IMG_CHAR_EXCLAM 657
-#define IMG_CHAR_QUOTEDBL 658
-#define IMG_CHAR_NUMBERSIGN 659
-#define IMG_CHAR_DOLLAR 660
-#define IMG_CHAR_PROCENT 661
-#define IMG_CHAR_AMPERSAND 662
-#define IMG_CHAR_APOSTROPHE 663
-#define IMG_CHAR_PARENLEFT 664
-#define IMG_CHAR_PARENRIGHT 665
-#define IMG_CHAR_ASTERISK 666
-#define IMG_CHAR_PLUS 667
-#define IMG_CHAR_COMMA 668
-#define IMG_CHAR_MINUS 669
-#define IMG_CHAR_PERIOD 670
-#define IMG_CHAR_SLASH 671
-#define IMG_CHAR_0 672
-#define IMG_CHAR_1 673
-#define IMG_CHAR_2 674
-#define IMG_CHAR_3 675
-#define IMG_CHAR_4 676
-#define IMG_CHAR_5 677
-#define IMG_CHAR_6 678
-#define IMG_CHAR_7 679
-#define IMG_CHAR_8 680
-#define IMG_CHAR_9 681
-#define IMG_CHAR_COLON 682
-#define IMG_CHAR_SEMICOLON 683
-#define IMG_CHAR_LESS 684
-#define IMG_CHAR_EQUAL 685
-#define IMG_CHAR_GREATER 686
-#define IMG_CHAR_QUESTION 687
-#define IMG_CHAR_AT 688
-#define IMG_CHAR_A 689
-#define IMG_CHAR_B 690
-#define IMG_CHAR_C 691
-#define IMG_CHAR_D 692
-#define IMG_CHAR_E 693
-#define IMG_CHAR_F 694
-#define IMG_CHAR_G 695
-#define IMG_CHAR_H 696
-#define IMG_CHAR_I 697
-#define IMG_CHAR_J 698
-#define IMG_CHAR_K 699
-#define IMG_CHAR_L 700
-#define IMG_CHAR_M 701
-#define IMG_CHAR_N 702
-#define IMG_CHAR_O 703
-#define IMG_CHAR_P 704
-#define IMG_CHAR_Q 705
-#define IMG_CHAR_R 706
-#define IMG_CHAR_S 707
-#define IMG_CHAR_T 708
-#define IMG_CHAR_U 709
-#define IMG_CHAR_V 710
-#define IMG_CHAR_W 711
-#define IMG_CHAR_X 712
-#define IMG_CHAR_Y 713
-#define IMG_CHAR_Z 714
-#define IMG_CHAR_BRACKETLEFT 715
-#define IMG_CHAR_BACKSLASH 716
-#define IMG_CHAR_BRACKETRIGHT 717
-#define IMG_CHAR_ASCIICIRCUM 718
-#define IMG_CHAR_UNDERSCORE 719
-#define IMG_CHAR_COPYRIGHT 720
-#define IMG_CHAR_AUMLAUT 721
-#define IMG_CHAR_OUMLAUT 722
-#define IMG_CHAR_UUMLAUT 723
-#define IMG_CHAR_DEGREE 724
-#define IMG_CHAR_TRADEMARK 725
-#define IMG_CHAR_CURSOR 726
-#define IMG_CUSTOM_1 727
-#define IMG_CUSTOM_1_EDITOR 728
-#define IMG_CUSTOM_2 729
-#define IMG_CUSTOM_2_EDITOR 730
-#define IMG_CUSTOM_3 731
-#define IMG_CUSTOM_3_EDITOR 732
-#define IMG_CUSTOM_4 733
-#define IMG_CUSTOM_4_EDITOR 734
-#define IMG_CUSTOM_5 735
-#define IMG_CUSTOM_5_EDITOR 736
-#define IMG_CUSTOM_6 737
-#define IMG_CUSTOM_6_EDITOR 738
-#define IMG_CUSTOM_7 739
-#define IMG_CUSTOM_7_EDITOR 740
-#define IMG_CUSTOM_8 741
-#define IMG_CUSTOM_8_EDITOR 742
-#define IMG_CUSTOM_9 743
-#define IMG_CUSTOM_9_EDITOR 744
-#define IMG_CUSTOM_10 745
-#define IMG_CUSTOM_10_EDITOR 746
-#define IMG_CUSTOM_11 747
-#define IMG_CUSTOM_11_EDITOR 748
-#define IMG_CUSTOM_12 749
-#define IMG_CUSTOM_12_EDITOR 750
-#define IMG_CUSTOM_13 751
-#define IMG_CUSTOM_13_EDITOR 752
-#define IMG_CUSTOM_14 753
-#define IMG_CUSTOM_14_EDITOR 754
-#define IMG_CUSTOM_15 755
-#define IMG_CUSTOM_15_EDITOR 756
-#define IMG_CUSTOM_16 757
-#define IMG_CUSTOM_16_EDITOR 758
-#define IMG_CUSTOM_17 759
-#define IMG_CUSTOM_17_EDITOR 760
-#define IMG_CUSTOM_18 761
-#define IMG_CUSTOM_18_EDITOR 762
-#define IMG_CUSTOM_19 763
-#define IMG_CUSTOM_19_EDITOR 764
-#define IMG_CUSTOM_20 765
-#define IMG_CUSTOM_20_EDITOR 766
-#define IMG_CUSTOM_21 767
-#define IMG_CUSTOM_21_EDITOR 768
-#define IMG_CUSTOM_22 769
-#define IMG_CUSTOM_22_EDITOR 770
-#define IMG_CUSTOM_23 771
-#define IMG_CUSTOM_23_EDITOR 772
-#define IMG_CUSTOM_24 773
-#define IMG_CUSTOM_24_EDITOR 774
-#define IMG_CUSTOM_25 775
-#define IMG_CUSTOM_25_EDITOR 776
-#define IMG_CUSTOM_26 777
-#define IMG_CUSTOM_26_EDITOR 778
-#define IMG_CUSTOM_27 779
-#define IMG_CUSTOM_27_EDITOR 780
-#define IMG_CUSTOM_28 781
-#define IMG_CUSTOM_28_EDITOR 782
-#define IMG_CUSTOM_29 783
-#define IMG_CUSTOM_29_EDITOR 784
-#define IMG_CUSTOM_30 785
-#define IMG_CUSTOM_30_EDITOR 786
-#define IMG_CUSTOM_31 787
-#define IMG_CUSTOM_31_EDITOR 788
-#define IMG_CUSTOM_32 789
-#define IMG_CUSTOM_32_EDITOR 790
-#define IMG_CUSTOM_33 791
-#define IMG_CUSTOM_33_EDITOR 792
-#define IMG_CUSTOM_34 793
-#define IMG_CUSTOM_34_EDITOR 794
-#define IMG_CUSTOM_35 795
-#define IMG_CUSTOM_35_EDITOR 796
-#define IMG_CUSTOM_36 797
-#define IMG_CUSTOM_36_EDITOR 798
-#define IMG_CUSTOM_37 799
-#define IMG_CUSTOM_37_EDITOR 800
-#define IMG_CUSTOM_38 801
-#define IMG_CUSTOM_38_EDITOR 802
-#define IMG_CUSTOM_39 803
-#define IMG_CUSTOM_39_EDITOR 804
-#define IMG_CUSTOM_40 805
-#define IMG_CUSTOM_40_EDITOR 806
-#define IMG_CUSTOM_41 807
-#define IMG_CUSTOM_41_EDITOR 808
-#define IMG_CUSTOM_42 809
-#define IMG_CUSTOM_42_EDITOR 810
-#define IMG_CUSTOM_43 811
-#define IMG_CUSTOM_43_EDITOR 812
-#define IMG_CUSTOM_44 813
-#define IMG_CUSTOM_44_EDITOR 814
-#define IMG_CUSTOM_45 815
-#define IMG_CUSTOM_45_EDITOR 816
-#define IMG_CUSTOM_46 817
-#define IMG_CUSTOM_46_EDITOR 818
-#define IMG_CUSTOM_47 819
-#define IMG_CUSTOM_47_EDITOR 820
-#define IMG_CUSTOM_48 821
-#define IMG_CUSTOM_48_EDITOR 822
-#define IMG_CUSTOM_49 823
-#define IMG_CUSTOM_49_EDITOR 824
-#define IMG_CUSTOM_50 825
-#define IMG_CUSTOM_50_EDITOR 826
-#define IMG_CUSTOM_51 827
-#define IMG_CUSTOM_51_EDITOR 828
-#define IMG_CUSTOM_52 829
-#define IMG_CUSTOM_52_EDITOR 830
-#define IMG_CUSTOM_53 831
-#define IMG_CUSTOM_53_EDITOR 832
-#define IMG_CUSTOM_54 833
-#define IMG_CUSTOM_54_EDITOR 834
-#define IMG_CUSTOM_55 835
-#define IMG_CUSTOM_55_EDITOR 836
-#define IMG_CUSTOM_56 837
-#define IMG_CUSTOM_56_EDITOR 838
-#define IMG_CUSTOM_57 839
-#define IMG_CUSTOM_57_EDITOR 840
-#define IMG_CUSTOM_58 841
-#define IMG_CUSTOM_58_EDITOR 842
-#define IMG_CUSTOM_59 843
-#define IMG_CUSTOM_59_EDITOR 844
-#define IMG_CUSTOM_60 845
-#define IMG_CUSTOM_60_EDITOR 846
-#define IMG_CUSTOM_61 847
-#define IMG_CUSTOM_61_EDITOR 848
-#define IMG_CUSTOM_62 849
-#define IMG_CUSTOM_62_EDITOR 850
-#define IMG_CUSTOM_63 851
-#define IMG_CUSTOM_63_EDITOR 852
-#define IMG_CUSTOM_64 853
-#define IMG_CUSTOM_64_EDITOR 854
-#define IMG_CUSTOM_65 855
-#define IMG_CUSTOM_65_EDITOR 856
-#define IMG_CUSTOM_66 857
-#define IMG_CUSTOM_66_EDITOR 858
-#define IMG_CUSTOM_67 859
-#define IMG_CUSTOM_67_EDITOR 860
-#define IMG_CUSTOM_68 861
-#define IMG_CUSTOM_68_EDITOR 862
-#define IMG_CUSTOM_69 863
-#define IMG_CUSTOM_69_EDITOR 864
-#define IMG_CUSTOM_70 865
-#define IMG_CUSTOM_70_EDITOR 866
-#define IMG_CUSTOM_71 867
-#define IMG_CUSTOM_71_EDITOR 868
-#define IMG_CUSTOM_72 869
-#define IMG_CUSTOM_72_EDITOR 870
-#define IMG_CUSTOM_73 871
-#define IMG_CUSTOM_73_EDITOR 872
-#define IMG_CUSTOM_74 873
-#define IMG_CUSTOM_74_EDITOR 874
-#define IMG_CUSTOM_75 875
-#define IMG_CUSTOM_75_EDITOR 876
-#define IMG_CUSTOM_76 877
-#define IMG_CUSTOM_76_EDITOR 878
-#define IMG_CUSTOM_77 879
-#define IMG_CUSTOM_77_EDITOR 880
-#define IMG_CUSTOM_78 881
-#define IMG_CUSTOM_78_EDITOR 882
-#define IMG_CUSTOM_79 883
-#define IMG_CUSTOM_79_EDITOR 884
-#define IMG_CUSTOM_80 885
-#define IMG_CUSTOM_80_EDITOR 886
-#define IMG_CUSTOM_81 887
-#define IMG_CUSTOM_81_EDITOR 888
-#define IMG_CUSTOM_82 889
-#define IMG_CUSTOM_82_EDITOR 890
-#define IMG_CUSTOM_83 891
-#define IMG_CUSTOM_83_EDITOR 892
-#define IMG_CUSTOM_84 893
-#define IMG_CUSTOM_84_EDITOR 894
-#define IMG_CUSTOM_85 895
-#define IMG_CUSTOM_85_EDITOR 896
-#define IMG_CUSTOM_86 897
-#define IMG_CUSTOM_86_EDITOR 898
-#define IMG_CUSTOM_87 899
-#define IMG_CUSTOM_87_EDITOR 900
-#define IMG_CUSTOM_88 901
-#define IMG_CUSTOM_88_EDITOR 902
-#define IMG_CUSTOM_89 903
-#define IMG_CUSTOM_89_EDITOR 904
-#define IMG_CUSTOM_90 905
-#define IMG_CUSTOM_90_EDITOR 906
-#define IMG_CUSTOM_91 907
-#define IMG_CUSTOM_91_EDITOR 908
-#define IMG_CUSTOM_92 909
-#define IMG_CUSTOM_92_EDITOR 910
-#define IMG_CUSTOM_93 911
-#define IMG_CUSTOM_93_EDITOR 912
-#define IMG_CUSTOM_94 913
-#define IMG_CUSTOM_94_EDITOR 914
-#define IMG_CUSTOM_95 915
-#define IMG_CUSTOM_95_EDITOR 916
-#define IMG_CUSTOM_96 917
-#define IMG_CUSTOM_96_EDITOR 918
-#define IMG_CUSTOM_97 919
-#define IMG_CUSTOM_97_EDITOR 920
-#define IMG_CUSTOM_98 921
-#define IMG_CUSTOM_98_EDITOR 922
-#define IMG_CUSTOM_99 923
-#define IMG_CUSTOM_99_EDITOR 924
-#define IMG_CUSTOM_100 925
-#define IMG_CUSTOM_100_EDITOR 926
-#define IMG_CUSTOM_101 927
-#define IMG_CUSTOM_101_EDITOR 928
-#define IMG_CUSTOM_102 929
-#define IMG_CUSTOM_102_EDITOR 930
-#define IMG_CUSTOM_103 931
-#define IMG_CUSTOM_103_EDITOR 932
-#define IMG_CUSTOM_104 933
-#define IMG_CUSTOM_104_EDITOR 934
-#define IMG_CUSTOM_105 935
-#define IMG_CUSTOM_105_EDITOR 936
-#define IMG_CUSTOM_106 937
-#define IMG_CUSTOM_106_EDITOR 938
-#define IMG_CUSTOM_107 939
-#define IMG_CUSTOM_107_EDITOR 940
-#define IMG_CUSTOM_108 941
-#define IMG_CUSTOM_108_EDITOR 942
-#define IMG_CUSTOM_109 943
-#define IMG_CUSTOM_109_EDITOR 944
-#define IMG_CUSTOM_110 945
-#define IMG_CUSTOM_110_EDITOR 946
-#define IMG_CUSTOM_111 947
-#define IMG_CUSTOM_111_EDITOR 948
-#define IMG_CUSTOM_112 949
-#define IMG_CUSTOM_112_EDITOR 950
-#define IMG_CUSTOM_113 951
-#define IMG_CUSTOM_113_EDITOR 952
-#define IMG_CUSTOM_114 953
-#define IMG_CUSTOM_114_EDITOR 954
-#define IMG_CUSTOM_115 955
-#define IMG_CUSTOM_115_EDITOR 956
-#define IMG_CUSTOM_116 957
-#define IMG_CUSTOM_116_EDITOR 958
-#define IMG_CUSTOM_117 959
-#define IMG_CUSTOM_117_EDITOR 960
-#define IMG_CUSTOM_118 961
-#define IMG_CUSTOM_118_EDITOR 962
-#define IMG_CUSTOM_119 963
-#define IMG_CUSTOM_119_EDITOR 964
-#define IMG_CUSTOM_120 965
-#define IMG_CUSTOM_120_EDITOR 966
-#define IMG_CUSTOM_121 967
-#define IMG_CUSTOM_121_EDITOR 968
-#define IMG_CUSTOM_122 969
-#define IMG_CUSTOM_122_EDITOR 970
-#define IMG_CUSTOM_123 971
-#define IMG_CUSTOM_123_EDITOR 972
-#define IMG_CUSTOM_124 973
-#define IMG_CUSTOM_124_EDITOR 974
-#define IMG_CUSTOM_125 975
-#define IMG_CUSTOM_125_EDITOR 976
-#define IMG_CUSTOM_126 977
-#define IMG_CUSTOM_126_EDITOR 978
-#define IMG_CUSTOM_127 979
-#define IMG_CUSTOM_127_EDITOR 980
-#define IMG_CUSTOM_128 981
-#define IMG_CUSTOM_128_EDITOR 982
-#define IMG_CUSTOM_129 983
-#define IMG_CUSTOM_129_EDITOR 984
-#define IMG_CUSTOM_130 985
-#define IMG_CUSTOM_130_EDITOR 986
-#define IMG_CUSTOM_131 987
-#define IMG_CUSTOM_131_EDITOR 988
-#define IMG_CUSTOM_132 989
-#define IMG_CUSTOM_132_EDITOR 990
-#define IMG_CUSTOM_133 991
-#define IMG_CUSTOM_133_EDITOR 992
-#define IMG_CUSTOM_134 993
-#define IMG_CUSTOM_134_EDITOR 994
-#define IMG_CUSTOM_135 995
-#define IMG_CUSTOM_135_EDITOR 996
-#define IMG_CUSTOM_136 997
-#define IMG_CUSTOM_136_EDITOR 998
-#define IMG_CUSTOM_137 999
-#define IMG_CUSTOM_137_EDITOR 1000
-#define IMG_CUSTOM_138 1001
-#define IMG_CUSTOM_138_EDITOR 1002
-#define IMG_CUSTOM_139 1003
-#define IMG_CUSTOM_139_EDITOR 1004
-#define IMG_CUSTOM_140 1005
-#define IMG_CUSTOM_140_EDITOR 1006
-#define IMG_CUSTOM_141 1007
-#define IMG_CUSTOM_141_EDITOR 1008
-#define IMG_CUSTOM_142 1009
-#define IMG_CUSTOM_142_EDITOR 1010
-#define IMG_CUSTOM_143 1011
-#define IMG_CUSTOM_143_EDITOR 1012
-#define IMG_CUSTOM_144 1013
-#define IMG_CUSTOM_144_EDITOR 1014
-#define IMG_CUSTOM_145 1015
-#define IMG_CUSTOM_145_EDITOR 1016
-#define IMG_CUSTOM_146 1017
-#define IMG_CUSTOM_146_EDITOR 1018
-#define IMG_CUSTOM_147 1019
-#define IMG_CUSTOM_147_EDITOR 1020
-#define IMG_CUSTOM_148 1021
-#define IMG_CUSTOM_148_EDITOR 1022
-#define IMG_CUSTOM_149 1023
-#define IMG_CUSTOM_149_EDITOR 1024
-#define IMG_CUSTOM_150 1025
-#define IMG_CUSTOM_150_EDITOR 1026
-#define IMG_CUSTOM_151 1027
-#define IMG_CUSTOM_151_EDITOR 1028
-#define IMG_CUSTOM_152 1029
-#define IMG_CUSTOM_152_EDITOR 1030
-#define IMG_CUSTOM_153 1031
-#define IMG_CUSTOM_153_EDITOR 1032
-#define IMG_CUSTOM_154 1033
-#define IMG_CUSTOM_154_EDITOR 1034
-#define IMG_CUSTOM_155 1035
-#define IMG_CUSTOM_155_EDITOR 1036
-#define IMG_CUSTOM_156 1037
-#define IMG_CUSTOM_156_EDITOR 1038
-#define IMG_CUSTOM_157 1039
-#define IMG_CUSTOM_157_EDITOR 1040
-#define IMG_CUSTOM_158 1041
-#define IMG_CUSTOM_158_EDITOR 1042
-#define IMG_CUSTOM_159 1043
-#define IMG_CUSTOM_159_EDITOR 1044
-#define IMG_CUSTOM_160 1045
-#define IMG_CUSTOM_160_EDITOR 1046
-#define IMG_CUSTOM_161 1047
-#define IMG_CUSTOM_161_EDITOR 1048
-#define IMG_CUSTOM_162 1049
-#define IMG_CUSTOM_162_EDITOR 1050
-#define IMG_CUSTOM_163 1051
-#define IMG_CUSTOM_163_EDITOR 1052
-#define IMG_CUSTOM_164 1053
-#define IMG_CUSTOM_164_EDITOR 1054
-#define IMG_CUSTOM_165 1055
-#define IMG_CUSTOM_165_EDITOR 1056
-#define IMG_CUSTOM_166 1057
-#define IMG_CUSTOM_166_EDITOR 1058
-#define IMG_CUSTOM_167 1059
-#define IMG_CUSTOM_167_EDITOR 1060
-#define IMG_CUSTOM_168 1061
-#define IMG_CUSTOM_168_EDITOR 1062
-#define IMG_CUSTOM_169 1063
-#define IMG_CUSTOM_169_EDITOR 1064
-#define IMG_CUSTOM_170 1065
-#define IMG_CUSTOM_170_EDITOR 1066
-#define IMG_CUSTOM_171 1067
-#define IMG_CUSTOM_171_EDITOR 1068
-#define IMG_CUSTOM_172 1069
-#define IMG_CUSTOM_172_EDITOR 1070
-#define IMG_CUSTOM_173 1071
-#define IMG_CUSTOM_173_EDITOR 1072
-#define IMG_CUSTOM_174 1073
-#define IMG_CUSTOM_174_EDITOR 1074
-#define IMG_CUSTOM_175 1075
-#define IMG_CUSTOM_175_EDITOR 1076
-#define IMG_CUSTOM_176 1077
-#define IMG_CUSTOM_176_EDITOR 1078
-#define IMG_CUSTOM_177 1079
-#define IMG_CUSTOM_177_EDITOR 1080
-#define IMG_CUSTOM_178 1081
-#define IMG_CUSTOM_178_EDITOR 1082
-#define IMG_CUSTOM_179 1083
-#define IMG_CUSTOM_179_EDITOR 1084
-#define IMG_CUSTOM_180 1085
-#define IMG_CUSTOM_180_EDITOR 1086
-#define IMG_CUSTOM_181 1087
-#define IMG_CUSTOM_181_EDITOR 1088
-#define IMG_CUSTOM_182 1089
-#define IMG_CUSTOM_182_EDITOR 1090
-#define IMG_CUSTOM_183 1091
-#define IMG_CUSTOM_183_EDITOR 1092
-#define IMG_CUSTOM_184 1093
-#define IMG_CUSTOM_184_EDITOR 1094
-#define IMG_CUSTOM_185 1095
-#define IMG_CUSTOM_185_EDITOR 1096
-#define IMG_CUSTOM_186 1097
-#define IMG_CUSTOM_186_EDITOR 1098
-#define IMG_CUSTOM_187 1099
-#define IMG_CUSTOM_187_EDITOR 1100
-#define IMG_CUSTOM_188 1101
-#define IMG_CUSTOM_188_EDITOR 1102
-#define IMG_CUSTOM_189 1103
-#define IMG_CUSTOM_189_EDITOR 1104
-#define IMG_CUSTOM_190 1105
-#define IMG_CUSTOM_190_EDITOR 1106
-#define IMG_CUSTOM_191 1107
-#define IMG_CUSTOM_191_EDITOR 1108
-#define IMG_CUSTOM_192 1109
-#define IMG_CUSTOM_192_EDITOR 1110
-#define IMG_CUSTOM_193 1111
-#define IMG_CUSTOM_193_EDITOR 1112
-#define IMG_CUSTOM_194 1113
-#define IMG_CUSTOM_194_EDITOR 1114
-#define IMG_CUSTOM_195 1115
-#define IMG_CUSTOM_195_EDITOR 1116
-#define IMG_CUSTOM_196 1117
-#define IMG_CUSTOM_196_EDITOR 1118
-#define IMG_CUSTOM_197 1119
-#define IMG_CUSTOM_197_EDITOR 1120
-#define IMG_CUSTOM_198 1121
-#define IMG_CUSTOM_198_EDITOR 1122
-#define IMG_CUSTOM_199 1123
-#define IMG_CUSTOM_199_EDITOR 1124
-#define IMG_CUSTOM_200 1125
-#define IMG_CUSTOM_200_EDITOR 1126
-#define IMG_CUSTOM_201 1127
-#define IMG_CUSTOM_201_EDITOR 1128
-#define IMG_CUSTOM_202 1129
-#define IMG_CUSTOM_202_EDITOR 1130
-#define IMG_CUSTOM_203 1131
-#define IMG_CUSTOM_203_EDITOR 1132
-#define IMG_CUSTOM_204 1133
-#define IMG_CUSTOM_204_EDITOR 1134
-#define IMG_CUSTOM_205 1135
-#define IMG_CUSTOM_205_EDITOR 1136
-#define IMG_CUSTOM_206 1137
-#define IMG_CUSTOM_206_EDITOR 1138
-#define IMG_CUSTOM_207 1139
-#define IMG_CUSTOM_207_EDITOR 1140
-#define IMG_CUSTOM_208 1141
-#define IMG_CUSTOM_208_EDITOR 1142
-#define IMG_CUSTOM_209 1143
-#define IMG_CUSTOM_209_EDITOR 1144
-#define IMG_CUSTOM_210 1145
-#define IMG_CUSTOM_210_EDITOR 1146
-#define IMG_CUSTOM_211 1147
-#define IMG_CUSTOM_211_EDITOR 1148
-#define IMG_CUSTOM_212 1149
-#define IMG_CUSTOM_212_EDITOR 1150
-#define IMG_CUSTOM_213 1151
-#define IMG_CUSTOM_213_EDITOR 1152
-#define IMG_CUSTOM_214 1153
-#define IMG_CUSTOM_214_EDITOR 1154
-#define IMG_CUSTOM_215 1155
-#define IMG_CUSTOM_215_EDITOR 1156
-#define IMG_CUSTOM_216 1157
-#define IMG_CUSTOM_216_EDITOR 1158
-#define IMG_CUSTOM_217 1159
-#define IMG_CUSTOM_217_EDITOR 1160
-#define IMG_CUSTOM_218 1161
-#define IMG_CUSTOM_218_EDITOR 1162
-#define IMG_CUSTOM_219 1163
-#define IMG_CUSTOM_219_EDITOR 1164
-#define IMG_CUSTOM_220 1165
-#define IMG_CUSTOM_220_EDITOR 1166
-#define IMG_CUSTOM_221 1167
-#define IMG_CUSTOM_221_EDITOR 1168
-#define IMG_CUSTOM_222 1169
-#define IMG_CUSTOM_222_EDITOR 1170
-#define IMG_CUSTOM_223 1171
-#define IMG_CUSTOM_223_EDITOR 1172
-#define IMG_CUSTOM_224 1173
-#define IMG_CUSTOM_224_EDITOR 1174
-#define IMG_CUSTOM_225 1175
-#define IMG_CUSTOM_225_EDITOR 1176
-#define IMG_CUSTOM_226 1177
-#define IMG_CUSTOM_226_EDITOR 1178
-#define IMG_CUSTOM_227 1179
-#define IMG_CUSTOM_227_EDITOR 1180
-#define IMG_CUSTOM_228 1181
-#define IMG_CUSTOM_228_EDITOR 1182
-#define IMG_CUSTOM_229 1183
-#define IMG_CUSTOM_229_EDITOR 1184
-#define IMG_CUSTOM_230 1185
-#define IMG_CUSTOM_230_EDITOR 1186
-#define IMG_CUSTOM_231 1187
-#define IMG_CUSTOM_231_EDITOR 1188
-#define IMG_CUSTOM_232 1189
-#define IMG_CUSTOM_232_EDITOR 1190
-#define IMG_CUSTOM_233 1191
-#define IMG_CUSTOM_233_EDITOR 1192
-#define IMG_CUSTOM_234 1193
-#define IMG_CUSTOM_234_EDITOR 1194
-#define IMG_CUSTOM_235 1195
-#define IMG_CUSTOM_235_EDITOR 1196
-#define IMG_CUSTOM_236 1197
-#define IMG_CUSTOM_236_EDITOR 1198
-#define IMG_CUSTOM_237 1199
-#define IMG_CUSTOM_237_EDITOR 1200
-#define IMG_CUSTOM_238 1201
-#define IMG_CUSTOM_238_EDITOR 1202
-#define IMG_CUSTOM_239 1203
-#define IMG_CUSTOM_239_EDITOR 1204
-#define IMG_CUSTOM_240 1205
-#define IMG_CUSTOM_240_EDITOR 1206
-#define IMG_CUSTOM_241 1207
-#define IMG_CUSTOM_241_EDITOR 1208
-#define IMG_CUSTOM_242 1209
-#define IMG_CUSTOM_242_EDITOR 1210
-#define IMG_CUSTOM_243 1211
-#define IMG_CUSTOM_243_EDITOR 1212
-#define IMG_CUSTOM_244 1213
-#define IMG_CUSTOM_244_EDITOR 1214
-#define IMG_CUSTOM_245 1215
-#define IMG_CUSTOM_245_EDITOR 1216
-#define IMG_CUSTOM_246 1217
-#define IMG_CUSTOM_246_EDITOR 1218
-#define IMG_CUSTOM_247 1219
-#define IMG_CUSTOM_247_EDITOR 1220
-#define IMG_CUSTOM_248 1221
-#define IMG_CUSTOM_248_EDITOR 1222
-#define IMG_CUSTOM_249 1223
-#define IMG_CUSTOM_249_EDITOR 1224
-#define IMG_CUSTOM_250 1225
-#define IMG_CUSTOM_250_EDITOR 1226
-#define IMG_CUSTOM_251 1227
-#define IMG_CUSTOM_251_EDITOR 1228
-#define IMG_CUSTOM_252 1229
-#define IMG_CUSTOM_252_EDITOR 1230
-#define IMG_CUSTOM_253 1231
-#define IMG_CUSTOM_253_EDITOR 1232
-#define IMG_CUSTOM_254 1233
-#define IMG_CUSTOM_254_EDITOR 1234
-#define IMG_CUSTOM_255 1235
-#define IMG_CUSTOM_255_EDITOR 1236
-#define IMG_CUSTOM_256 1237
-#define IMG_CUSTOM_256_EDITOR 1238
-#define IMG_GROUP_1 1239
-#define IMG_GROUP_1_EDITOR 1240
-#define IMG_GROUP_2 1241
-#define IMG_GROUP_2_EDITOR 1242
-#define IMG_GROUP_3 1243
-#define IMG_GROUP_3_EDITOR 1244
-#define IMG_GROUP_4 1245
-#define IMG_GROUP_4_EDITOR 1246
-#define IMG_GROUP_5 1247
-#define IMG_GROUP_5_EDITOR 1248
-#define IMG_GROUP_6 1249
-#define IMG_GROUP_6_EDITOR 1250
-#define IMG_GROUP_7 1251
-#define IMG_GROUP_7_EDITOR 1252
-#define IMG_GROUP_8 1253
-#define IMG_GROUP_8_EDITOR 1254
-#define IMG_GROUP_9 1255
-#define IMG_GROUP_9_EDITOR 1256
-#define IMG_GROUP_10 1257
-#define IMG_GROUP_10_EDITOR 1258
-#define IMG_GROUP_11 1259
-#define IMG_GROUP_11_EDITOR 1260
-#define IMG_GROUP_12 1261
-#define IMG_GROUP_12_EDITOR 1262
-#define IMG_GROUP_13 1263
-#define IMG_GROUP_13_EDITOR 1264
-#define IMG_GROUP_14 1265
-#define IMG_GROUP_14_EDITOR 1266
-#define IMG_GROUP_15 1267
-#define IMG_GROUP_15_EDITOR 1268
-#define IMG_GROUP_16 1269
-#define IMG_GROUP_16_EDITOR 1270
-#define IMG_GROUP_17 1271
-#define IMG_GROUP_17_EDITOR 1272
-#define IMG_GROUP_18 1273
-#define IMG_GROUP_18_EDITOR 1274
-#define IMG_GROUP_19 1275
-#define IMG_GROUP_19_EDITOR 1276
-#define IMG_GROUP_20 1277
-#define IMG_GROUP_20_EDITOR 1278
-#define IMG_GROUP_21 1279
-#define IMG_GROUP_21_EDITOR 1280
-#define IMG_GROUP_22 1281
-#define IMG_GROUP_22_EDITOR 1282
-#define IMG_GROUP_23 1283
-#define IMG_GROUP_23_EDITOR 1284
-#define IMG_GROUP_24 1285
-#define IMG_GROUP_24_EDITOR 1286
-#define IMG_GROUP_25 1287
-#define IMG_GROUP_25_EDITOR 1288
-#define IMG_GROUP_26 1289
-#define IMG_GROUP_26_EDITOR 1290
-#define IMG_GROUP_27 1291
-#define IMG_GROUP_27_EDITOR 1292
-#define IMG_GROUP_28 1293
-#define IMG_GROUP_28_EDITOR 1294
-#define IMG_GROUP_29 1295
-#define IMG_GROUP_29_EDITOR 1296
-#define IMG_GROUP_30 1297
-#define IMG_GROUP_30_EDITOR 1298
-#define IMG_GROUP_31 1299
-#define IMG_GROUP_31_EDITOR 1300
-#define IMG_GROUP_32 1301
-#define IMG_GROUP_32_EDITOR 1302
-#define IMG_TOON_1 1303
-#define IMG_TOON_2 1304
-#define IMG_TOON_3 1305
-#define IMG_TOON_4 1306
-#define IMG_TOON_5 1307
-#define IMG_TOON_6 1308
-#define IMG_TOON_7 1309
-#define IMG_TOON_8 1310
-#define IMG_TOON_9 1311
-#define IMG_TOON_10 1312
-#define IMG_TOON_11 1313
-#define IMG_TOON_12 1314
-#define IMG_TOON_13 1315
-#define IMG_TOON_14 1316
-#define IMG_TOON_15 1317
-#define IMG_TOON_16 1318
-#define IMG_TOON_17 1319
-#define IMG_TOON_18 1320
-#define IMG_TOON_19 1321
-#define IMG_TOON_20 1322
-#define IMG_MENU_CALIBRATE_RED 1323
-#define IMG_MENU_CALIBRATE_BLUE 1324
-#define IMG_MENU_CALIBRATE_YELLOW 1325
-#define IMG_MENU_BUTTON 1326
-#define IMG_MENU_BUTTON_ACTIVE 1327
-#define IMG_MENU_BUTTON_LEFT 1328
-#define IMG_MENU_BUTTON_RIGHT 1329
-#define IMG_MENU_BUTTON_UP 1330
-#define IMG_MENU_BUTTON_DOWN 1331
-#define IMG_MENU_BUTTON_LEFT_ACTIVE 1332
-#define IMG_MENU_BUTTON_RIGHT_ACTIVE 1333
-#define IMG_MENU_BUTTON_UP_ACTIVE 1334
-#define IMG_MENU_BUTTON_DOWN_ACTIVE 1335
-#define IMG_MENU_SCROLLBAR 1336
-#define IMG_MENU_SCROLLBAR_ACTIVE 1337
-#define IMG_FONT_INITIAL_1 1338
-#define IMG_FONT_INITIAL_2 1339
-#define IMG_FONT_INITIAL_3 1340
-#define IMG_FONT_INITIAL_4 1341
-#define IMG_FONT_TITLE_1 1342
-#define IMG_FONT_TITLE_1_LEVELS 1343
-#define IMG_FONT_TITLE_2 1344
-#define IMG_FONT_MENU_1 1345
-#define IMG_FONT_MENU_2 1346
-#define IMG_FONT_TEXT_1 1347
-#define IMG_FONT_TEXT_1_LEVELS 1348
-#define IMG_FONT_TEXT_1_PREVIEW 1349
-#define IMG_FONT_TEXT_1_SCORES 1350
-#define IMG_FONT_TEXT_1_ACTIVE_SCORES 1351
-#define IMG_FONT_TEXT_2 1352
-#define IMG_FONT_TEXT_2_LEVELS 1353
-#define IMG_FONT_TEXT_2_PREVIEW 1354
-#define IMG_FONT_TEXT_2_SCORES 1355
-#define IMG_FONT_TEXT_2_ACTIVE_SCORES 1356
-#define IMG_FONT_TEXT_3 1357
-#define IMG_FONT_TEXT_3_LEVELS 1358
-#define IMG_FONT_TEXT_3_PREVIEW 1359
-#define IMG_FONT_TEXT_3_SCORES 1360
-#define IMG_FONT_TEXT_3_ACTIVE_SCORES 1361
-#define IMG_FONT_TEXT_4 1362
-#define IMG_FONT_TEXT_4_LEVELS 1363
-#define IMG_FONT_TEXT_4_SCORES 1364
-#define IMG_FONT_TEXT_4_ACTIVE_SCORES 1365
-#define IMG_FONT_ENVELOPE_1 1366
-#define IMG_FONT_ENVELOPE_2 1367
-#define IMG_FONT_ENVELOPE_3 1368
-#define IMG_FONT_ENVELOPE_4 1369
-#define IMG_FONT_INPUT_1 1370
-#define IMG_FONT_INPUT_1_MAIN 1371
-#define IMG_FONT_INPUT_1_ACTIVE 1372
-#define IMG_FONT_INPUT_1_ACTIVE_MAIN 1373
-#define IMG_FONT_INPUT_1_ACTIVE_SETUP 1374
-#define IMG_FONT_INPUT_2 1375
-#define IMG_FONT_INPUT_2_ACTIVE 1376
-#define IMG_FONT_OPTION_OFF 1377
-#define IMG_FONT_OPTION_ON 1378
-#define IMG_FONT_VALUE_1 1379
-#define IMG_FONT_VALUE_2 1380
-#define IMG_FONT_VALUE_OLD 1381
-#define IMG_FONT_LEVEL_NUMBER 1382
-#define IMG_FONT_TAPE_RECORDER 1383
-#define IMG_FONT_GAME_INFO 1384
-#define IMG_GLOBAL_BORDER 1385
-#define IMG_GLOBAL_DOOR 1386
-#define IMG_EDITOR_ELEMENT_BORDER 1387
-#define IMG_EDITOR_ELEMENT_BORDER_INPUT 1388
-#define IMG_BACKGROUND_ENVELOPE_1 1389
-#define IMG_BACKGROUND_ENVELOPE_2 1390
-#define IMG_BACKGROUND_ENVELOPE_3 1391
-#define IMG_BACKGROUND_ENVELOPE_4 1392
-#define IMG_BACKGROUND 1393
-#define IMG_BACKGROUND_MAIN 1394
-#define IMG_BACKGROUND_LEVELS 1395
-#define IMG_BACKGROUND_SCORES 1396
-#define IMG_BACKGROUND_EDITOR 1397
-#define IMG_BACKGROUND_INFO 1398
-#define IMG_BACKGROUND_INFO_ELEMENTS 1399
-#define IMG_BACKGROUND_SETUP 1400
-#define IMG_BACKGROUND_DOOR 1401
+#define IMG_BD_BUTTERFLY_RIGHT 20
+#define IMG_BD_BUTTERFLY_RIGHT_EDITOR 21
+#define IMG_BD_BUTTERFLY_UP 22
+#define IMG_BD_BUTTERFLY_UP_EDITOR 23
+#define IMG_BD_BUTTERFLY_LEFT 24
+#define IMG_BD_BUTTERFLY_LEFT_EDITOR 25
+#define IMG_BD_BUTTERFLY_DOWN 26
+#define IMG_BD_BUTTERFLY_DOWN_EDITOR 27
+#define IMG_BD_FIREFLY 28
+#define IMG_BD_FIREFLY_RIGHT 29
+#define IMG_BD_FIREFLY_RIGHT_EDITOR 30
+#define IMG_BD_FIREFLY_UP 31
+#define IMG_BD_FIREFLY_UP_EDITOR 32
+#define IMG_BD_FIREFLY_LEFT 33
+#define IMG_BD_FIREFLY_LEFT_EDITOR 34
+#define IMG_BD_FIREFLY_DOWN 35
+#define IMG_BD_FIREFLY_DOWN_EDITOR 36
+#define IMG_SP_DEFAULT_EXPLODING 37
+#define IMG_SP_ZONK 38
+#define IMG_SP_ZONK_MOVING_LEFT 39
+#define IMG_SP_ZONK_MOVING_RIGHT 40
+#define IMG_SP_ZONK_PUSHING_LEFT 41
+#define IMG_SP_ZONK_PUSHING_RIGHT 42
+#define IMG_SP_BASE 43
+#define IMG_SP_MURPHY 44
+#define IMG_SP_MURPHY_MOVING_LEFT 45
+#define IMG_SP_MURPHY_MOVING_RIGHT 46
+#define IMG_SP_MURPHY_DIGGING_LEFT 47
+#define IMG_SP_MURPHY_DIGGING_RIGHT 48
+#define IMG_SP_MURPHY_COLLECTING_LEFT 49
+#define IMG_SP_MURPHY_COLLECTING_RIGHT 50
+#define IMG_SP_MURPHY_PUSHING_LEFT 51
+#define IMG_SP_MURPHY_PUSHING_RIGHT 52
+#define IMG_SP_MURPHY_SNAPPING_LEFT 53
+#define IMG_SP_MURPHY_SNAPPING_RIGHT 54
+#define IMG_SP_MURPHY_SNAPPING_UP 55
+#define IMG_SP_MURPHY_SNAPPING_DOWN 56
+#define IMG_SP_MURPHY_CLONE 57
+#define IMG_SP_INFOTRON 58
+#define IMG_SP_INFOTRON_EDITOR 59
+#define IMG_SP_CHIP_SINGLE 60
+#define IMG_SP_CHIP_LEFT 61
+#define IMG_SP_CHIP_RIGHT 62
+#define IMG_SP_CHIP_TOP 63
+#define IMG_SP_CHIP_BOTTOM 64
+#define IMG_SP_HARDWARE_GRAY 65
+#define IMG_SP_HARDWARE_GREEN 66
+#define IMG_SP_HARDWARE_BLUE 67
+#define IMG_SP_HARDWARE_RED 68
+#define IMG_SP_HARDWARE_YELLOW 69
+#define IMG_SP_EXIT_CLOSED 70
+#define IMG_SP_EXIT_OPENING 71
+#define IMG_SP_EXIT_OPEN 72
+#define IMG_SP_EXIT_CLOSING 73
+#define IMG_SP_DISK_ORANGE 74
+#define IMG_SP_DISK_YELLOW 75
+#define IMG_SP_DISK_RED 76
+#define IMG_SP_DISK_RED_COLLECTING 77
+#define IMG_SP_DISK_RED_ACTIVE 78
+#define IMG_SP_PORT_RIGHT 79
+#define IMG_SP_PORT_DOWN 80
+#define IMG_SP_PORT_LEFT 81
+#define IMG_SP_PORT_UP 82
+#define IMG_SP_PORT_HORIZONTAL 83
+#define IMG_SP_PORT_VERTICAL 84
+#define IMG_SP_PORT_ANY 85
+#define IMG_SP_GRAVITY_PORT_RIGHT 86
+#define IMG_SP_GRAVITY_PORT_RIGHT_EDITOR 87
+#define IMG_SP_GRAVITY_PORT_DOWN 88
+#define IMG_SP_GRAVITY_PORT_DOWN_EDITOR 89
+#define IMG_SP_GRAVITY_PORT_LEFT 90
+#define IMG_SP_GRAVITY_PORT_LEFT_EDITOR 91
+#define IMG_SP_GRAVITY_PORT_UP 92
+#define IMG_SP_GRAVITY_PORT_UP_EDITOR 93
+#define IMG_SP_GRAVITY_ON_PORT_RIGHT 94
+#define IMG_SP_GRAVITY_ON_PORT_RIGHT_EDITOR 95
+#define IMG_SP_GRAVITY_ON_PORT_DOWN 96
+#define IMG_SP_GRAVITY_ON_PORT_DOWN_EDITOR 97
+#define IMG_SP_GRAVITY_ON_PORT_LEFT 98
+#define IMG_SP_GRAVITY_ON_PORT_LEFT_EDITOR 99
+#define IMG_SP_GRAVITY_ON_PORT_UP 100
+#define IMG_SP_GRAVITY_ON_PORT_UP_EDITOR 101
+#define IMG_SP_GRAVITY_OFF_PORT_RIGHT 102
+#define IMG_SP_GRAVITY_OFF_PORT_RIGHT_EDITOR 103
+#define IMG_SP_GRAVITY_OFF_PORT_DOWN 104
+#define IMG_SP_GRAVITY_OFF_PORT_DOWN_EDITOR 105
+#define IMG_SP_GRAVITY_OFF_PORT_LEFT 106
+#define IMG_SP_GRAVITY_OFF_PORT_LEFT_EDITOR 107
+#define IMG_SP_GRAVITY_OFF_PORT_UP 108
+#define IMG_SP_GRAVITY_OFF_PORT_UP_EDITOR 109
+#define IMG_SP_SNIKSNAK 110
+#define IMG_SP_SNIKSNAK_LEFT 111
+#define IMG_SP_SNIKSNAK_RIGHT 112
+#define IMG_SP_SNIKSNAK_UP 113
+#define IMG_SP_SNIKSNAK_DOWN 114
+#define IMG_SP_SNIKSNAK_TURNING_FROM_LEFT_UP 115
+#define IMG_SP_SNIKSNAK_TURNING_FROM_LEFT_DOWN 116
+#define IMG_SP_SNIKSNAK_TURNING_FROM_RIGHT_UP 117
+#define IMG_SP_SNIKSNAK_TURNING_FROM_RIGHT_DOWN 118
+#define IMG_SP_SNIKSNAK_TURNING_FROM_UP_LEFT 119
+#define IMG_SP_SNIKSNAK_TURNING_FROM_UP_RIGHT 120
+#define IMG_SP_SNIKSNAK_TURNING_FROM_DOWN_LEFT 121
+#define IMG_SP_SNIKSNAK_TURNING_FROM_DOWN_RIGHT 122
+#define IMG_SP_ELECTRON 123
+#define IMG_SP_ELECTRON_EDITOR 124
+#define IMG_SP_ELECTRON_EXPLODING 125
+#define IMG_SP_TERMINAL 126
+#define IMG_SP_TERMINAL_EDITOR 127
+#define IMG_SP_TERMINAL_ACTIVE 128
+#define IMG_SP_BUGGY_BASE 129
+#define IMG_SP_BUGGY_BASE_EDITOR 130
+#define IMG_SP_BUGGY_BASE_ACTIVATING 131
+#define IMG_SP_BUGGY_BASE_ACTIVE 132
+#define IMG_SP_HARDWARE_BASE_1 133
+#define IMG_SP_HARDWARE_BASE_2 134
+#define IMG_SP_HARDWARE_BASE_3 135
+#define IMG_SP_HARDWARE_BASE_4 136
+#define IMG_SP_HARDWARE_BASE_5 137
+#define IMG_SP_HARDWARE_BASE_6 138
+#define IMG_SOKOBAN_OBJECT 139
+#define IMG_SOKOBAN_OBJECT_EDITOR 140
+#define IMG_SOKOBAN_FIELD_EMPTY 141
+#define IMG_SOKOBAN_FIELD_FULL 142
+#define IMG_SOKOBAN_FIELD_PLAYER 143
+#define IMG_SOKOBAN_FIELD_PLAYER_EDITOR 144
+#define IMG_EMPTY_SPACE 145
+#define IMG_SAND 146
+#define IMG_SAND_CRUMBLED 147
+#define IMG_SAND_DIGGING_LEFT 148
+#define IMG_SAND_DIGGING_RIGHT 149
+#define IMG_SAND_DIGGING_UP 150
+#define IMG_SAND_DIGGING_DOWN 151
+#define IMG_SAND_DIGGING_LEFT_CRUMBLED 152
+#define IMG_SAND_DIGGING_RIGHT_CRUMBLED 153
+#define IMG_SAND_DIGGING_UP_CRUMBLED 154
+#define IMG_SAND_DIGGING_DOWN_CRUMBLED 155
+#define IMG_WALL 156
+#define IMG_WALL_SLIPPERY 157
+#define IMG_STEELWALL 158
+#define IMG_ROCK 159
+#define IMG_ROCK_MOVING_LEFT 160
+#define IMG_ROCK_MOVING_RIGHT 161
+#define IMG_ROCK_PUSHING_LEFT 162
+#define IMG_ROCK_PUSHING_RIGHT 163
+#define IMG_EMERALD 164
+#define IMG_EMERALD_MOVING 165
+#define IMG_EMERALD_FALLING 166
+#define IMG_EMERALD_COLLECTING 167
+#define IMG_DIAMOND 168
+#define IMG_DIAMOND_MOVING 169
+#define IMG_DIAMOND_FALLING 170
+#define IMG_DIAMOND_COLLECTING 171
+#define IMG_BOMB 172
+#define IMG_NUT 173
+#define IMG_NUT_BREAKING 174
+#define IMG_DYNAMITE 175
+#define IMG_DYNAMITE_EDITOR 176
+#define IMG_DYNAMITE_ACTIVE 177
+#define IMG_DYNAMITE_ACTIVE_EDITOR 178
+#define IMG_WALL_EMERALD 179
+#define IMG_WALL_DIAMOND 180
+#define IMG_BUG 181
+#define IMG_BUG_RIGHT 182
+#define IMG_BUG_UP 183
+#define IMG_BUG_LEFT 184
+#define IMG_BUG_DOWN 185
+#define IMG_BUG_MOVING_RIGHT 186
+#define IMG_BUG_MOVING_UP 187
+#define IMG_BUG_MOVING_LEFT 188
+#define IMG_BUG_MOVING_DOWN 189
+#define IMG_BUG_TURNING_FROM_RIGHT_UP 190
+#define IMG_BUG_TURNING_FROM_UP_LEFT 191
+#define IMG_BUG_TURNING_FROM_LEFT_DOWN 192
+#define IMG_BUG_TURNING_FROM_DOWN_RIGHT 193
+#define IMG_BUG_TURNING_FROM_RIGHT_DOWN 194
+#define IMG_BUG_TURNING_FROM_UP_RIGHT 195
+#define IMG_BUG_TURNING_FROM_LEFT_UP 196
+#define IMG_BUG_TURNING_FROM_DOWN_LEFT 197
+#define IMG_SPACESHIP 198
+#define IMG_SPACESHIP_RIGHT 199
+#define IMG_SPACESHIP_UP 200
+#define IMG_SPACESHIP_LEFT 201
+#define IMG_SPACESHIP_DOWN 202
+#define IMG_SPACESHIP_MOVING_RIGHT 203
+#define IMG_SPACESHIP_MOVING_UP 204
+#define IMG_SPACESHIP_MOVING_LEFT 205
+#define IMG_SPACESHIP_MOVING_DOWN 206
+#define IMG_SPACESHIP_TURNING_FROM_RIGHT_UP 207
+#define IMG_SPACESHIP_TURNING_FROM_UP_LEFT 208
+#define IMG_SPACESHIP_TURNING_FROM_LEFT_DOWN 209
+#define IMG_SPACESHIP_TURNING_FROM_DOWN_RIGHT 210
+#define IMG_SPACESHIP_TURNING_FROM_RIGHT_DOWN 211
+#define IMG_SPACESHIP_TURNING_FROM_UP_RIGHT 212
+#define IMG_SPACESHIP_TURNING_FROM_LEFT_UP 213
+#define IMG_SPACESHIP_TURNING_FROM_DOWN_LEFT 214
+#define IMG_YAMYAM 215
+#define IMG_YAMYAM_MOVING 216
+#define IMG_ROBOT 217
+#define IMG_ROBOT_MOVING 218
+#define IMG_ROBOT_WHEEL 219
+#define IMG_ROBOT_WHEEL_ACTIVE 220
+#define IMG_MAGIC_WALL 221
+#define IMG_MAGIC_WALL_ACTIVE 222
+#define IMG_MAGIC_WALL_FILLING 223
+#define IMG_MAGIC_WALL_FULL 224
+#define IMG_MAGIC_WALL_EMPTYING 225
+#define IMG_MAGIC_WALL_DEAD 226
+#define IMG_QUICKSAND_EMPTY 227
+#define IMG_QUICKSAND_FILLING 228
+#define IMG_QUICKSAND_FULL 229
+#define IMG_QUICKSAND_FULL_EDITOR 230
+#define IMG_QUICKSAND_EMPTYING 231
+#define IMG_ACID_POOL_TOPLEFT 232
+#define IMG_ACID_POOL_TOPRIGHT 233
+#define IMG_ACID_POOL_BOTTOMLEFT 234
+#define IMG_ACID_POOL_BOTTOM 235
+#define IMG_ACID_POOL_BOTTOMRIGHT 236
+#define IMG_ACID 237
+#define IMG_ACID_SPLASH_LEFT 238
+#define IMG_ACID_SPLASH_RIGHT 239
+#define IMG_AMOEBA_DROP 240
+#define IMG_AMOEBA_GROWING 241
+#define IMG_AMOEBA_SHRINKING 242
+#define IMG_AMOEBA_WET 243
+#define IMG_AMOEBA_WET_EDITOR 244
+#define IMG_AMOEBA_DROPPING 245
+#define IMG_AMOEBA_DRY 246
+#define IMG_AMOEBA_FULL 247
+#define IMG_AMOEBA_FULL_EDITOR 248
+#define IMG_AMOEBA_DEAD 249
+#define IMG_AMOEBA_DEAD_EDITOR 250
+#define IMG_EM_KEY_1 251
+#define IMG_EM_KEY_2 252
+#define IMG_EM_KEY_3 253
+#define IMG_EM_KEY_4 254
+#define IMG_EM_GATE_1 255
+#define IMG_EM_GATE_2 256
+#define IMG_EM_GATE_3 257
+#define IMG_EM_GATE_4 258
+#define IMG_EM_GATE_1_GRAY 259
+#define IMG_EM_GATE_1_GRAY_EDITOR 260
+#define IMG_EM_GATE_2_GRAY 261
+#define IMG_EM_GATE_2_GRAY_EDITOR 262
+#define IMG_EM_GATE_3_GRAY 263
+#define IMG_EM_GATE_3_GRAY_EDITOR 264
+#define IMG_EM_GATE_4_GRAY 265
+#define IMG_EM_GATE_4_GRAY_EDITOR 266
+#define IMG_EXIT_CLOSED 267
+#define IMG_EXIT_OPENING 268
+#define IMG_EXIT_OPEN 269
+#define IMG_EXIT_CLOSING 270
+#define IMG_BALLOON 271
+#define IMG_BALLOON_MOVING 272
+#define IMG_BALLOON_PUSHING 273
+#define IMG_BALLOON_SWITCH_LEFT 274
+#define IMG_BALLOON_SWITCH_RIGHT 275
+#define IMG_BALLOON_SWITCH_UP 276
+#define IMG_BALLOON_SWITCH_DOWN 277
+#define IMG_BALLOON_SWITCH_ANY 278
+#define IMG_BALLOON_SWITCH_NONE 279
+#define IMG_SPRING 280
+#define IMG_EMC_STEELWALL_1 281
+#define IMG_EMC_STEELWALL_2 282
+#define IMG_EMC_STEELWALL_3 283
+#define IMG_EMC_STEELWALL_4 284
+#define IMG_EMC_WALL_1 285
+#define IMG_EMC_WALL_2 286
+#define IMG_EMC_WALL_3 287
+#define IMG_EMC_WALL_4 288
+#define IMG_EMC_WALL_5 289
+#define IMG_EMC_WALL_6 290
+#define IMG_EMC_WALL_7 291
+#define IMG_EMC_WALL_8 292
+#define IMG_INVISIBLE_STEELWALL 293
+#define IMG_INVISIBLE_STEELWALL_EDITOR 294
+#define IMG_INVISIBLE_STEELWALL_ACTIVE 295
+#define IMG_INVISIBLE_WALL 296
+#define IMG_INVISIBLE_WALL_EDITOR 297
+#define IMG_INVISIBLE_WALL_ACTIVE 298
+#define IMG_INVISIBLE_SAND 299
+#define IMG_INVISIBLE_SAND_EDITOR 300
+#define IMG_INVISIBLE_SAND_ACTIVE 301
+#define IMG_INVISIBLE_SAND_ACTIVE_CRUMBLED 302
+#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_LEFT 303
+#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_RIGHT 304
+#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_UP 305
+#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_DOWN 306
+#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_LEFT_CRUMBLED 307
+#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_RIGHT_CRUMBLED 308
+#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_UP_CRUMBLED 309
+#define IMG_INVISIBLE_SAND_ACTIVE_DIGGING_DOWN_CRUMBLED 310
+#define IMG_CONVEYOR_BELT_1_MIDDLE 311
+#define IMG_CONVEYOR_BELT_1_MIDDLE_ACTIVE 312
+#define IMG_CONVEYOR_BELT_1_LEFT 313
+#define IMG_CONVEYOR_BELT_1_LEFT_ACTIVE 314
+#define IMG_CONVEYOR_BELT_1_RIGHT 315
+#define IMG_CONVEYOR_BELT_1_RIGHT_ACTIVE 316
+#define IMG_CONVEYOR_BELT_1_SWITCH_LEFT 317
+#define IMG_CONVEYOR_BELT_1_SWITCH_MIDDLE 318
+#define IMG_CONVEYOR_BELT_1_SWITCH_RIGHT 319
+#define IMG_CONVEYOR_BELT_2_MIDDLE 320
+#define IMG_CONVEYOR_BELT_2_MIDDLE_ACTIVE 321
+#define IMG_CONVEYOR_BELT_2_LEFT 322
+#define IMG_CONVEYOR_BELT_2_LEFT_ACTIVE 323
+#define IMG_CONVEYOR_BELT_2_RIGHT 324
+#define IMG_CONVEYOR_BELT_2_RIGHT_ACTIVE 325
+#define IMG_CONVEYOR_BELT_2_SWITCH_LEFT 326
+#define IMG_CONVEYOR_BELT_2_SWITCH_MIDDLE 327
+#define IMG_CONVEYOR_BELT_2_SWITCH_RIGHT 328
+#define IMG_CONVEYOR_BELT_3_MIDDLE 329
+#define IMG_CONVEYOR_BELT_3_MIDDLE_ACTIVE 330
+#define IMG_CONVEYOR_BELT_3_LEFT 331
+#define IMG_CONVEYOR_BELT_3_LEFT_ACTIVE 332
+#define IMG_CONVEYOR_BELT_3_RIGHT 333
+#define IMG_CONVEYOR_BELT_3_RIGHT_ACTIVE 334
+#define IMG_CONVEYOR_BELT_3_SWITCH_LEFT 335
+#define IMG_CONVEYOR_BELT_3_SWITCH_MIDDLE 336
+#define IMG_CONVEYOR_BELT_3_SWITCH_RIGHT 337
+#define IMG_CONVEYOR_BELT_4_MIDDLE 338
+#define IMG_CONVEYOR_BELT_4_MIDDLE_ACTIVE 339
+#define IMG_CONVEYOR_BELT_4_LEFT 340
+#define IMG_CONVEYOR_BELT_4_LEFT_ACTIVE 341
+#define IMG_CONVEYOR_BELT_4_RIGHT 342
+#define IMG_CONVEYOR_BELT_4_RIGHT_ACTIVE 343
+#define IMG_CONVEYOR_BELT_4_SWITCH_LEFT 344
+#define IMG_CONVEYOR_BELT_4_SWITCH_MIDDLE 345
+#define IMG_CONVEYOR_BELT_4_SWITCH_RIGHT 346
+#define IMG_SWITCHGATE_SWITCH_UP 347
+#define IMG_SWITCHGATE_SWITCH_DOWN 348
+#define IMG_LIGHT_SWITCH 349
+#define IMG_LIGHT_SWITCH_ACTIVE 350
+#define IMG_TIMEGATE_SWITCH 351
+#define IMG_TIMEGATE_SWITCH_ACTIVE 352
+#define IMG_ENVELOPE_1 353
+#define IMG_ENVELOPE_1_COLLECTING 354
+#define IMG_ENVELOPE_2 355
+#define IMG_ENVELOPE_2_COLLECTING 356
+#define IMG_ENVELOPE_3 357
+#define IMG_ENVELOPE_3_COLLECTING 358
+#define IMG_ENVELOPE_4 359
+#define IMG_ENVELOPE_4_COLLECTING 360
+#define IMG_SIGN_EXCLAMATION 361
+#define IMG_SIGN_STOP 362
+#define IMG_LANDMINE 363
+#define IMG_STEELWALL_SLIPPERY 364
+#define IMG_EXTRA_TIME 365
+#define IMG_SHIELD_NORMAL 366
+#define IMG_SHIELD_NORMAL_ACTIVE 367
+#define IMG_SHIELD_DEADLY 368
+#define IMG_SHIELD_DEADLY_ACTIVE 369
+#define IMG_SWITCHGATE_CLOSED 370
+#define IMG_SWITCHGATE_OPENING 371
+#define IMG_SWITCHGATE_OPEN 372
+#define IMG_SWITCHGATE_CLOSING 373
+#define IMG_TIMEGATE_CLOSED 374
+#define IMG_TIMEGATE_OPENING 375
+#define IMG_TIMEGATE_OPEN 376
+#define IMG_TIMEGATE_CLOSING 377
+#define IMG_PEARL 378
+#define IMG_PEARL_BREAKING 379
+#define IMG_CRYSTAL 380
+#define IMG_WALL_PEARL 381
+#define IMG_WALL_CRYSTAL 382
+#define IMG_TUBE_RIGHT_DOWN 383
+#define IMG_TUBE_HORIZONTAL_DOWN 384
+#define IMG_TUBE_LEFT_DOWN 385
+#define IMG_TUBE_HORIZONTAL 386
+#define IMG_TUBE_VERTICAL_RIGHT 387
+#define IMG_TUBE_ANY 388
+#define IMG_TUBE_VERTICAL_LEFT 389
+#define IMG_TUBE_VERTICAL 390
+#define IMG_TUBE_RIGHT_UP 391
+#define IMG_TUBE_HORIZONTAL_UP 392
+#define IMG_TUBE_LEFT_UP 393
+#define IMG_TRAP 394
+#define IMG_TRAP_ACTIVE 395
+#define IMG_DX_SUPABOMB 396
+#define IMG_KEY_1 397
+#define IMG_KEY_1_EDITOR 398
+#define IMG_KEY_2 399
+#define IMG_KEY_2_EDITOR 400
+#define IMG_KEY_3 401
+#define IMG_KEY_3_EDITOR 402
+#define IMG_KEY_4 403
+#define IMG_KEY_4_EDITOR 404
+#define IMG_GATE_1 405
+#define IMG_GATE_2 406
+#define IMG_GATE_3 407
+#define IMG_GATE_4 408
+#define IMG_GATE_1_GRAY 409
+#define IMG_GATE_1_GRAY_EDITOR 410
+#define IMG_GATE_2_GRAY 411
+#define IMG_GATE_2_GRAY_EDITOR 412
+#define IMG_GATE_3_GRAY 413
+#define IMG_GATE_3_GRAY_EDITOR 414
+#define IMG_GATE_4_GRAY 415
+#define IMG_GATE_4_GRAY_EDITOR 416
+#define IMG_GAME_OF_LIFE 417
+#define IMG_BIOMAZE 418
+#define IMG_PACMAN 419
+#define IMG_PACMAN_RIGHT 420
+#define IMG_PACMAN_UP 421
+#define IMG_PACMAN_LEFT 422
+#define IMG_PACMAN_DOWN 423
+#define IMG_PACMAN_TURNING_FROM_RIGHT 424
+#define IMG_PACMAN_TURNING_FROM_UP 425
+#define IMG_PACMAN_TURNING_FROM_LEFT 426
+#define IMG_PACMAN_TURNING_FROM_DOWN 427
+#define IMG_LAMP 428
+#define IMG_LAMP_EDITOR 429
+#define IMG_LAMP_ACTIVE 430
+#define IMG_TIME_ORB_FULL 431
+#define IMG_TIME_ORB_EMPTY 432
+#define IMG_EMERALD_YELLOW 433
+#define IMG_EMERALD_YELLOW_MOVING 434
+#define IMG_EMERALD_YELLOW_FALLING 435
+#define IMG_EMERALD_RED 436
+#define IMG_EMERALD_RED_MOVING 437
+#define IMG_EMERALD_RED_FALLING 438
+#define IMG_EMERALD_PURPLE 439
+#define IMG_EMERALD_PURPLE_MOVING 440
+#define IMG_EMERALD_PURPLE_FALLING 441
+#define IMG_WALL_EMERALD_YELLOW 442
+#define IMG_WALL_EMERALD_RED 443
+#define IMG_WALL_EMERALD_PURPLE 444
+#define IMG_WALL_BD_DIAMOND 445
+#define IMG_EXPANDABLE_WALL 446
+#define IMG_EXPANDABLE_WALL_HORIZONTAL 447
+#define IMG_EXPANDABLE_WALL_HORIZONTAL_EDITOR 448
+#define IMG_EXPANDABLE_WALL_VERTICAL 449
+#define IMG_EXPANDABLE_WALL_VERTICAL_EDITOR 450
+#define IMG_EXPANDABLE_WALL_ANY 451
+#define IMG_EXPANDABLE_WALL_ANY_EDITOR 452
+#define IMG_EXPANDABLE_WALL_GROWING_LEFT 453
+#define IMG_EXPANDABLE_WALL_GROWING_RIGHT 454
+#define IMG_EXPANDABLE_WALL_GROWING_UP 455
+#define IMG_EXPANDABLE_WALL_GROWING_DOWN 456
+#define IMG_BLACK_ORB 457
+#define IMG_SPEED_PILL 458
+#define IMG_DARK_YAMYAM 459
+#define IMG_DYNABOMB 460
+#define IMG_DYNABOMB_ACTIVE 461
+#define IMG_DYNABOMB_PLAYER_1 462
+#define IMG_DYNABOMB_PLAYER_1_ACTIVE 463
+#define IMG_DYNABOMB_PLAYER_2 464
+#define IMG_DYNABOMB_PLAYER_2_ACTIVE 465
+#define IMG_DYNABOMB_PLAYER_3 466
+#define IMG_DYNABOMB_PLAYER_3_ACTIVE 467
+#define IMG_DYNABOMB_PLAYER_4 468
+#define IMG_DYNABOMB_PLAYER_4_ACTIVE 469
+#define IMG_DYNABOMB_INCREASE_NUMBER 470
+#define IMG_DYNABOMB_INCREASE_SIZE 471
+#define IMG_DYNABOMB_INCREASE_POWER 472
+#define IMG_PIG 473
+#define IMG_PIG_DOWN 474
+#define IMG_PIG_UP 475
+#define IMG_PIG_LEFT 476
+#define IMG_PIG_RIGHT 477
+#define IMG_PIG_MOVING_DOWN 478
+#define IMG_PIG_MOVING_UP 479
+#define IMG_PIG_MOVING_LEFT 480
+#define IMG_PIG_MOVING_RIGHT 481
+#define IMG_PIG_DIGGING_DOWN 482
+#define IMG_PIG_DIGGING_UP 483
+#define IMG_PIG_DIGGING_LEFT 484
+#define IMG_PIG_DIGGING_RIGHT 485
+#define IMG_DRAGON 486
+#define IMG_DRAGON_DOWN 487
+#define IMG_DRAGON_UP 488
+#define IMG_DRAGON_LEFT 489
+#define IMG_DRAGON_RIGHT 490
+#define IMG_DRAGON_MOVING_DOWN 491
+#define IMG_DRAGON_MOVING_UP 492
+#define IMG_DRAGON_MOVING_LEFT 493
+#define IMG_DRAGON_MOVING_RIGHT 494
+#define IMG_DRAGON_ATTACKING_DOWN 495
+#define IMG_DRAGON_ATTACKING_UP 496
+#define IMG_DRAGON_ATTACKING_LEFT 497
+#define IMG_DRAGON_ATTACKING_RIGHT 498
+#define IMG_MOLE 499
+#define IMG_MOLE_DOWN 500
+#define IMG_MOLE_UP 501
+#define IMG_MOLE_LEFT 502
+#define IMG_MOLE_RIGHT 503
+#define IMG_MOLE_MOVING_DOWN 504
+#define IMG_MOLE_MOVING_UP 505
+#define IMG_MOLE_MOVING_LEFT 506
+#define IMG_MOLE_MOVING_RIGHT 507
+#define IMG_MOLE_DIGGING_DOWN 508
+#define IMG_MOLE_DIGGING_UP 509
+#define IMG_MOLE_DIGGING_LEFT 510
+#define IMG_MOLE_DIGGING_RIGHT 511
+#define IMG_PENGUIN 512
+#define IMG_PENGUIN_EDITOR 513
+#define IMG_PENGUIN_DOWN 514
+#define IMG_PENGUIN_UP 515
+#define IMG_PENGUIN_LEFT 516
+#define IMG_PENGUIN_RIGHT 517
+#define IMG_PENGUIN_MOVING_DOWN 518
+#define IMG_PENGUIN_MOVING_UP 519
+#define IMG_PENGUIN_MOVING_LEFT 520
+#define IMG_PENGUIN_MOVING_RIGHT 521
+#define IMG_SATELLITE 522
+#define IMG_FLAMES_1_LEFT 523
+#define IMG_FLAMES_2_LEFT 524
+#define IMG_FLAMES_3_LEFT 525
+#define IMG_FLAMES_1_RIGHT 526
+#define IMG_FLAMES_2_RIGHT 527
+#define IMG_FLAMES_3_RIGHT 528
+#define IMG_FLAMES_1_UP 529
+#define IMG_FLAMES_2_UP 530
+#define IMG_FLAMES_3_UP 531
+#define IMG_FLAMES_1_DOWN 532
+#define IMG_FLAMES_2_DOWN 533
+#define IMG_FLAMES_3_DOWN 534
+#define IMG_STONEBLOCK 535
+#define IMG_PLAYER_1 536
+#define IMG_PLAYER_1_EDITOR 537
+#define IMG_PLAYER_1_DOWN 538
+#define IMG_PLAYER_1_UP 539
+#define IMG_PLAYER_1_LEFT 540
+#define IMG_PLAYER_1_RIGHT 541
+#define IMG_PLAYER_1_MOVING_DOWN 542
+#define IMG_PLAYER_1_MOVING_UP 543
+#define IMG_PLAYER_1_MOVING_LEFT 544
+#define IMG_PLAYER_1_MOVING_RIGHT 545
+#define IMG_PLAYER_1_DIGGING_DOWN 546
+#define IMG_PLAYER_1_DIGGING_UP 547
+#define IMG_PLAYER_1_DIGGING_LEFT 548
+#define IMG_PLAYER_1_DIGGING_RIGHT 549
+#define IMG_PLAYER_1_COLLECTING_DOWN 550
+#define IMG_PLAYER_1_COLLECTING_UP 551
+#define IMG_PLAYER_1_COLLECTING_LEFT 552
+#define IMG_PLAYER_1_COLLECTING_RIGHT 553
+#define IMG_PLAYER_1_PUSHING_DOWN 554
+#define IMG_PLAYER_1_PUSHING_UP 555
+#define IMG_PLAYER_1_PUSHING_LEFT 556
+#define IMG_PLAYER_1_PUSHING_RIGHT 557
+#define IMG_PLAYER_1_SNAPPING_DOWN 558
+#define IMG_PLAYER_1_SNAPPING_UP 559
+#define IMG_PLAYER_1_SNAPPING_LEFT 560
+#define IMG_PLAYER_1_SNAPPING_RIGHT 561
+#define IMG_PLAYER_2 562
+#define IMG_PLAYER_2_EDITOR 563
+#define IMG_PLAYER_2_DOWN 564
+#define IMG_PLAYER_2_UP 565
+#define IMG_PLAYER_2_LEFT 566
+#define IMG_PLAYER_2_RIGHT 567
+#define IMG_PLAYER_2_MOVING_DOWN 568
+#define IMG_PLAYER_2_MOVING_UP 569
+#define IMG_PLAYER_2_MOVING_LEFT 570
+#define IMG_PLAYER_2_MOVING_RIGHT 571
+#define IMG_PLAYER_2_DIGGING_DOWN 572
+#define IMG_PLAYER_2_DIGGING_UP 573
+#define IMG_PLAYER_2_DIGGING_LEFT 574
+#define IMG_PLAYER_2_DIGGING_RIGHT 575
+#define IMG_PLAYER_2_COLLECTING_DOWN 576
+#define IMG_PLAYER_2_COLLECTING_UP 577
+#define IMG_PLAYER_2_COLLECTING_LEFT 578
+#define IMG_PLAYER_2_COLLECTING_RIGHT 579
+#define IMG_PLAYER_2_PUSHING_DOWN 580
+#define IMG_PLAYER_2_PUSHING_UP 581
+#define IMG_PLAYER_2_PUSHING_LEFT 582
+#define IMG_PLAYER_2_PUSHING_RIGHT 583
+#define IMG_PLAYER_2_SNAPPING_DOWN 584
+#define IMG_PLAYER_2_SNAPPING_UP 585
+#define IMG_PLAYER_2_SNAPPING_LEFT 586
+#define IMG_PLAYER_2_SNAPPING_RIGHT 587
+#define IMG_PLAYER_3 588
+#define IMG_PLAYER_3_EDITOR 589
+#define IMG_PLAYER_3_DOWN 590
+#define IMG_PLAYER_3_UP 591
+#define IMG_PLAYER_3_LEFT 592
+#define IMG_PLAYER_3_RIGHT 593
+#define IMG_PLAYER_3_MOVING_DOWN 594
+#define IMG_PLAYER_3_MOVING_UP 595
+#define IMG_PLAYER_3_MOVING_LEFT 596
+#define IMG_PLAYER_3_MOVING_RIGHT 597
+#define IMG_PLAYER_3_DIGGING_DOWN 598
+#define IMG_PLAYER_3_DIGGING_UP 599
+#define IMG_PLAYER_3_DIGGING_LEFT 600
+#define IMG_PLAYER_3_DIGGING_RIGHT 601
+#define IMG_PLAYER_3_COLLECTING_DOWN 602
+#define IMG_PLAYER_3_COLLECTING_UP 603
+#define IMG_PLAYER_3_COLLECTING_LEFT 604
+#define IMG_PLAYER_3_COLLECTING_RIGHT 605
+#define IMG_PLAYER_3_PUSHING_DOWN 606
+#define IMG_PLAYER_3_PUSHING_UP 607
+#define IMG_PLAYER_3_PUSHING_LEFT 608
+#define IMG_PLAYER_3_PUSHING_RIGHT 609
+#define IMG_PLAYER_3_SNAPPING_DOWN 610
+#define IMG_PLAYER_3_SNAPPING_UP 611
+#define IMG_PLAYER_3_SNAPPING_LEFT 612
+#define IMG_PLAYER_3_SNAPPING_RIGHT 613
+#define IMG_PLAYER_4 614
+#define IMG_PLAYER_4_EDITOR 615
+#define IMG_PLAYER_4_DOWN 616
+#define IMG_PLAYER_4_UP 617
+#define IMG_PLAYER_4_LEFT 618
+#define IMG_PLAYER_4_RIGHT 619
+#define IMG_PLAYER_4_MOVING_DOWN 620
+#define IMG_PLAYER_4_MOVING_UP 621
+#define IMG_PLAYER_4_MOVING_LEFT 622
+#define IMG_PLAYER_4_MOVING_RIGHT 623
+#define IMG_PLAYER_4_DIGGING_DOWN 624
+#define IMG_PLAYER_4_DIGGING_UP 625
+#define IMG_PLAYER_4_DIGGING_LEFT 626
+#define IMG_PLAYER_4_DIGGING_RIGHT 627
+#define IMG_PLAYER_4_COLLECTING_DOWN 628
+#define IMG_PLAYER_4_COLLECTING_UP 629
+#define IMG_PLAYER_4_COLLECTING_LEFT 630
+#define IMG_PLAYER_4_COLLECTING_RIGHT 631
+#define IMG_PLAYER_4_PUSHING_DOWN 632
+#define IMG_PLAYER_4_PUSHING_UP 633
+#define IMG_PLAYER_4_PUSHING_LEFT 634
+#define IMG_PLAYER_4_PUSHING_RIGHT 635
+#define IMG_PLAYER_4_SNAPPING_DOWN 636
+#define IMG_PLAYER_4_SNAPPING_UP 637
+#define IMG_PLAYER_4_SNAPPING_LEFT 638
+#define IMG_PLAYER_4_SNAPPING_RIGHT 639
+#define IMG_DEFAULT_EXPLODING 640
+#define IMG_TWINKLE_BLUE 641
+#define IMG_TWINKLE_WHITE 642
+#define IMG_STEELWALL_TOPLEFT 643
+#define IMG_STEELWALL_TOPRIGHT 644
+#define IMG_STEELWALL_BOTTOMLEFT 645
+#define IMG_STEELWALL_BOTTOMRIGHT 646
+#define IMG_STEELWALL_HORIZONTAL 647
+#define IMG_STEELWALL_VERTICAL 648
+#define IMG_STEELWALL_TOPLEFT_EDITOR 649
+#define IMG_STEELWALL_TOPRIGHT_EDITOR 650
+#define IMG_STEELWALL_BOTTOMLEFT_EDITOR 651
+#define IMG_STEELWALL_BOTTOMRIGHT_EDITOR 652
+#define IMG_STEELWALL_HORIZONTAL_EDITOR 653
+#define IMG_STEELWALL_VERTICAL_EDITOR 654
+#define IMG_INVISIBLE_STEELWALL_TOPLEFT 655
+#define IMG_INVISIBLE_STEELWALL_TOPRIGHT 656
+#define IMG_INVISIBLE_STEELWALL_BOTTOMLEFT 657
+#define IMG_INVISIBLE_STEELWALL_BOTTOMRIGHT 658
+#define IMG_INVISIBLE_STEELWALL_HORIZONTAL 659
+#define IMG_INVISIBLE_STEELWALL_VERTICAL 660
+#define IMG_INVISIBLE_STEELWALL_TOPLEFT_EDITOR 661
+#define IMG_INVISIBLE_STEELWALL_TOPRIGHT_EDITOR 662
+#define IMG_INVISIBLE_STEELWALL_BOTTOMLEFT_EDITOR 663
+#define IMG_INVISIBLE_STEELWALL_BOTTOMRIGHT_EDITOR 664
+#define IMG_INVISIBLE_STEELWALL_HORIZONTAL_EDITOR 665
+#define IMG_INVISIBLE_STEELWALL_VERTICAL_EDITOR 666
+#define IMG_ARROW_LEFT 667
+#define IMG_ARROW_RIGHT 668
+#define IMG_ARROW_UP 669
+#define IMG_ARROW_DOWN 670
+#define IMG_UNKNOWN 671
+#define IMG_TRIGGER_ELEMENT 672
+#define IMG_TRIGGER_PLAYER 673
+#define IMG_EMC_KEY_5 674
+#define IMG_EMC_KEY_6 675
+#define IMG_EMC_KEY_7 676
+#define IMG_EMC_KEY_8 677
+#define IMG_EMC_GATE_5 678
+#define IMG_EMC_GATE_5_GRAY 679
+#define IMG_EMC_GATE_5_GRAY_EDITOR 680
+#define IMG_EMC_GATE_6 681
+#define IMG_EMC_GATE_6_GRAY 682
+#define IMG_EMC_GATE_6_GRAY_EDITOR 683
+#define IMG_EMC_GATE_7 684
+#define IMG_EMC_GATE_7_GRAY 685
+#define IMG_EMC_GATE_7_GRAY_EDITOR 686
+#define IMG_EMC_GATE_8 687
+#define IMG_EMC_GATE_8_GRAY 688
+#define IMG_EMC_GATE_8_GRAY_EDITOR 689
+#define IMG_EMC_ANDROID 690
+#define IMG_EMC_GRASS 691
+#define IMG_EMC_GRASS_CRUMBLED 692
+#define IMG_EMC_GRASS_DIGGING_LEFT 693
+#define IMG_EMC_GRASS_DIGGING_RIGHT 694
+#define IMG_EMC_GRASS_DIGGING_UP 695
+#define IMG_EMC_GRASS_DIGGING_DOWN 696
+#define IMG_EMC_GRASS_DIGGING_LEFT_CRUMBLED 697
+#define IMG_EMC_GRASS_DIGGING_RIGHT_CRUMBLED 698
+#define IMG_EMC_GRASS_DIGGING_UP_CRUMBLED 699
+#define IMG_EMC_GRASS_DIGGING_DOWN_CRUMBLED 700
+#define IMG_EMC_MAGIC_BALL 701
+#define IMG_EMC_MAGIC_BALL_ACTIVE 702
+#define IMG_EMC_MAGIC_BALL_SWITCH 703
+#define IMG_EMC_MAGIC_BALL_SWITCH_ACTIVE 704
+#define IMG_EMC_SPRING_BUMPER 705
+#define IMG_EMC_SPRING_BUMPER_ACTIVE 706
+#define IMG_EMC_PLANT 707
+#define IMG_EMC_PLANT_CRUMBLED 708
+#define IMG_EMC_LENSES 709
+#define IMG_EMC_MAGNIFIER 710
+#define IMG_EMC_WALL_9 711
+#define IMG_EMC_WALL_10 712
+#define IMG_EMC_WALL_11 713
+#define IMG_EMC_WALL_12 714
+#define IMG_EMC_WALL_13 715
+#define IMG_EMC_WALL_14 716
+#define IMG_EMC_WALL_15 717
+#define IMG_EMC_WALL_16 718
+#define IMG_EMC_WALL_SLIPPERY_1 719
+#define IMG_EMC_WALL_SLIPPERY_2 720
+#define IMG_EMC_WALL_SLIPPERY_3 721
+#define IMG_EMC_WALL_SLIPPERY_4 722
+#define IMG_EMC_FAKE_GRASS 723
+#define IMG_EMC_FAKE_GRASS_CRUMBLED 724
+#define IMG_EMC_FAKE_GRASS_ACTIVE 725
+#define IMG_EMC_FAKE_GRASS_ACTIVE_CRUMBLED 726
+#define IMG_EMC_FAKE_ACID 727
+#define IMG_EMC_DRIPPER 728
+#define IMG_EMC_DRIPPER_EDITOR 729
+#define IMG_EMC_DRIPPER_ACTIVE 730
+#define IMG_CHAR_SPACE 731
+#define IMG_CHAR_EXCLAM 732
+#define IMG_CHAR_QUOTEDBL 733
+#define IMG_CHAR_NUMBERSIGN 734
+#define IMG_CHAR_DOLLAR 735
+#define IMG_CHAR_PERCENT 736
+#define IMG_CHAR_AMPERSAND 737
+#define IMG_CHAR_APOSTROPHE 738
+#define IMG_CHAR_PARENLEFT 739
+#define IMG_CHAR_PARENRIGHT 740
+#define IMG_CHAR_ASTERISK 741
+#define IMG_CHAR_PLUS 742
+#define IMG_CHAR_COMMA 743
+#define IMG_CHAR_MINUS 744
+#define IMG_CHAR_PERIOD 745
+#define IMG_CHAR_SLASH 746
+#define IMG_CHAR_0 747
+#define IMG_CHAR_1 748
+#define IMG_CHAR_2 749
+#define IMG_CHAR_3 750
+#define IMG_CHAR_4 751
+#define IMG_CHAR_5 752
+#define IMG_CHAR_6 753
+#define IMG_CHAR_7 754
+#define IMG_CHAR_8 755
+#define IMG_CHAR_9 756
+#define IMG_CHAR_COLON 757
+#define IMG_CHAR_SEMICOLON 758
+#define IMG_CHAR_LESS 759
+#define IMG_CHAR_EQUAL 760
+#define IMG_CHAR_GREATER 761
+#define IMG_CHAR_QUESTION 762
+#define IMG_CHAR_AT 763
+#define IMG_CHAR_A 764
+#define IMG_CHAR_B 765
+#define IMG_CHAR_C 766
+#define IMG_CHAR_D 767
+#define IMG_CHAR_E 768
+#define IMG_CHAR_F 769
+#define IMG_CHAR_G 770
+#define IMG_CHAR_H 771
+#define IMG_CHAR_I 772
+#define IMG_CHAR_J 773
+#define IMG_CHAR_K 774
+#define IMG_CHAR_L 775
+#define IMG_CHAR_M 776
+#define IMG_CHAR_N 777
+#define IMG_CHAR_O 778
+#define IMG_CHAR_P 779
+#define IMG_CHAR_Q 780
+#define IMG_CHAR_R 781
+#define IMG_CHAR_S 782
+#define IMG_CHAR_T 783
+#define IMG_CHAR_U 784
+#define IMG_CHAR_V 785
+#define IMG_CHAR_W 786
+#define IMG_CHAR_X 787
+#define IMG_CHAR_Y 788
+#define IMG_CHAR_Z 789
+#define IMG_CHAR_BRACKETLEFT 790
+#define IMG_CHAR_BACKSLASH 791
+#define IMG_CHAR_BRACKETRIGHT 792
+#define IMG_CHAR_ASCIICIRCUM 793
+#define IMG_CHAR_UNDERSCORE 794
+#define IMG_CHAR_COPYRIGHT 795
+#define IMG_CHAR_AUMLAUT 796
+#define IMG_CHAR_OUMLAUT 797
+#define IMG_CHAR_UUMLAUT 798
+#define IMG_CHAR_DEGREE 799
+#define IMG_CHAR_TRADEMARK 800
+#define IMG_CHAR_CURSOR 801
+#define IMG_CUSTOM_1 802
+#define IMG_CUSTOM_1_EDITOR 803
+#define IMG_CUSTOM_2 804
+#define IMG_CUSTOM_2_EDITOR 805
+#define IMG_CUSTOM_3 806
+#define IMG_CUSTOM_3_EDITOR 807
+#define IMG_CUSTOM_4 808
+#define IMG_CUSTOM_4_EDITOR 809
+#define IMG_CUSTOM_5 810
+#define IMG_CUSTOM_5_EDITOR 811
+#define IMG_CUSTOM_6 812
+#define IMG_CUSTOM_6_EDITOR 813
+#define IMG_CUSTOM_7 814
+#define IMG_CUSTOM_7_EDITOR 815
+#define IMG_CUSTOM_8 816
+#define IMG_CUSTOM_8_EDITOR 817
+#define IMG_CUSTOM_9 818
+#define IMG_CUSTOM_9_EDITOR 819
+#define IMG_CUSTOM_10 820
+#define IMG_CUSTOM_10_EDITOR 821
+#define IMG_CUSTOM_11 822
+#define IMG_CUSTOM_11_EDITOR 823
+#define IMG_CUSTOM_12 824
+#define IMG_CUSTOM_12_EDITOR 825
+#define IMG_CUSTOM_13 826
+#define IMG_CUSTOM_13_EDITOR 827
+#define IMG_CUSTOM_14 828
+#define IMG_CUSTOM_14_EDITOR 829
+#define IMG_CUSTOM_15 830
+#define IMG_CUSTOM_15_EDITOR 831
+#define IMG_CUSTOM_16 832
+#define IMG_CUSTOM_16_EDITOR 833
+#define IMG_CUSTOM_17 834
+#define IMG_CUSTOM_17_EDITOR 835
+#define IMG_CUSTOM_18 836
+#define IMG_CUSTOM_18_EDITOR 837
+#define IMG_CUSTOM_19 838
+#define IMG_CUSTOM_19_EDITOR 839
+#define IMG_CUSTOM_20 840
+#define IMG_CUSTOM_20_EDITOR 841
+#define IMG_CUSTOM_21 842
+#define IMG_CUSTOM_21_EDITOR 843
+#define IMG_CUSTOM_22 844
+#define IMG_CUSTOM_22_EDITOR 845
+#define IMG_CUSTOM_23 846
+#define IMG_CUSTOM_23_EDITOR 847
+#define IMG_CUSTOM_24 848
+#define IMG_CUSTOM_24_EDITOR 849
+#define IMG_CUSTOM_25 850
+#define IMG_CUSTOM_25_EDITOR 851
+#define IMG_CUSTOM_26 852
+#define IMG_CUSTOM_26_EDITOR 853
+#define IMG_CUSTOM_27 854
+#define IMG_CUSTOM_27_EDITOR 855
+#define IMG_CUSTOM_28 856
+#define IMG_CUSTOM_28_EDITOR 857
+#define IMG_CUSTOM_29 858
+#define IMG_CUSTOM_29_EDITOR 859
+#define IMG_CUSTOM_30 860
+#define IMG_CUSTOM_30_EDITOR 861
+#define IMG_CUSTOM_31 862
+#define IMG_CUSTOM_31_EDITOR 863
+#define IMG_CUSTOM_32 864
+#define IMG_CUSTOM_32_EDITOR 865
+#define IMG_CUSTOM_33 866
+#define IMG_CUSTOM_33_EDITOR 867
+#define IMG_CUSTOM_34 868
+#define IMG_CUSTOM_34_EDITOR 869
+#define IMG_CUSTOM_35 870
+#define IMG_CUSTOM_35_EDITOR 871
+#define IMG_CUSTOM_36 872
+#define IMG_CUSTOM_36_EDITOR 873
+#define IMG_CUSTOM_37 874
+#define IMG_CUSTOM_37_EDITOR 875
+#define IMG_CUSTOM_38 876
+#define IMG_CUSTOM_38_EDITOR 877
+#define IMG_CUSTOM_39 878
+#define IMG_CUSTOM_39_EDITOR 879
+#define IMG_CUSTOM_40 880
+#define IMG_CUSTOM_40_EDITOR 881
+#define IMG_CUSTOM_41 882
+#define IMG_CUSTOM_41_EDITOR 883
+#define IMG_CUSTOM_42 884
+#define IMG_CUSTOM_42_EDITOR 885
+#define IMG_CUSTOM_43 886
+#define IMG_CUSTOM_43_EDITOR 887
+#define IMG_CUSTOM_44 888
+#define IMG_CUSTOM_44_EDITOR 889
+#define IMG_CUSTOM_45 890
+#define IMG_CUSTOM_45_EDITOR 891
+#define IMG_CUSTOM_46 892
+#define IMG_CUSTOM_46_EDITOR 893
+#define IMG_CUSTOM_47 894
+#define IMG_CUSTOM_47_EDITOR 895
+#define IMG_CUSTOM_48 896
+#define IMG_CUSTOM_48_EDITOR 897
+#define IMG_CUSTOM_49 898
+#define IMG_CUSTOM_49_EDITOR 899
+#define IMG_CUSTOM_50 900
+#define IMG_CUSTOM_50_EDITOR 901
+#define IMG_CUSTOM_51 902
+#define IMG_CUSTOM_51_EDITOR 903
+#define IMG_CUSTOM_52 904
+#define IMG_CUSTOM_52_EDITOR 905
+#define IMG_CUSTOM_53 906
+#define IMG_CUSTOM_53_EDITOR 907
+#define IMG_CUSTOM_54 908
+#define IMG_CUSTOM_54_EDITOR 909
+#define IMG_CUSTOM_55 910
+#define IMG_CUSTOM_55_EDITOR 911
+#define IMG_CUSTOM_56 912
+#define IMG_CUSTOM_56_EDITOR 913
+#define IMG_CUSTOM_57 914
+#define IMG_CUSTOM_57_EDITOR 915
+#define IMG_CUSTOM_58 916
+#define IMG_CUSTOM_58_EDITOR 917
+#define IMG_CUSTOM_59 918
+#define IMG_CUSTOM_59_EDITOR 919
+#define IMG_CUSTOM_60 920
+#define IMG_CUSTOM_60_EDITOR 921
+#define IMG_CUSTOM_61 922
+#define IMG_CUSTOM_61_EDITOR 923
+#define IMG_CUSTOM_62 924
+#define IMG_CUSTOM_62_EDITOR 925
+#define IMG_CUSTOM_63 926
+#define IMG_CUSTOM_63_EDITOR 927
+#define IMG_CUSTOM_64 928
+#define IMG_CUSTOM_64_EDITOR 929
+#define IMG_CUSTOM_65 930
+#define IMG_CUSTOM_65_EDITOR 931
+#define IMG_CUSTOM_66 932
+#define IMG_CUSTOM_66_EDITOR 933
+#define IMG_CUSTOM_67 934
+#define IMG_CUSTOM_67_EDITOR 935
+#define IMG_CUSTOM_68 936
+#define IMG_CUSTOM_68_EDITOR 937
+#define IMG_CUSTOM_69 938
+#define IMG_CUSTOM_69_EDITOR 939
+#define IMG_CUSTOM_70 940
+#define IMG_CUSTOM_70_EDITOR 941
+#define IMG_CUSTOM_71 942
+#define IMG_CUSTOM_71_EDITOR 943
+#define IMG_CUSTOM_72 944
+#define IMG_CUSTOM_72_EDITOR 945
+#define IMG_CUSTOM_73 946
+#define IMG_CUSTOM_73_EDITOR 947
+#define IMG_CUSTOM_74 948
+#define IMG_CUSTOM_74_EDITOR 949
+#define IMG_CUSTOM_75 950
+#define IMG_CUSTOM_75_EDITOR 951
+#define IMG_CUSTOM_76 952
+#define IMG_CUSTOM_76_EDITOR 953
+#define IMG_CUSTOM_77 954
+#define IMG_CUSTOM_77_EDITOR 955
+#define IMG_CUSTOM_78 956
+#define IMG_CUSTOM_78_EDITOR 957
+#define IMG_CUSTOM_79 958
+#define IMG_CUSTOM_79_EDITOR 959
+#define IMG_CUSTOM_80 960
+#define IMG_CUSTOM_80_EDITOR 961
+#define IMG_CUSTOM_81 962
+#define IMG_CUSTOM_81_EDITOR 963
+#define IMG_CUSTOM_82 964
+#define IMG_CUSTOM_82_EDITOR 965
+#define IMG_CUSTOM_83 966
+#define IMG_CUSTOM_83_EDITOR 967
+#define IMG_CUSTOM_84 968
+#define IMG_CUSTOM_84_EDITOR 969
+#define IMG_CUSTOM_85 970
+#define IMG_CUSTOM_85_EDITOR 971
+#define IMG_CUSTOM_86 972
+#define IMG_CUSTOM_86_EDITOR 973
+#define IMG_CUSTOM_87 974
+#define IMG_CUSTOM_87_EDITOR 975
+#define IMG_CUSTOM_88 976
+#define IMG_CUSTOM_88_EDITOR 977
+#define IMG_CUSTOM_89 978
+#define IMG_CUSTOM_89_EDITOR 979
+#define IMG_CUSTOM_90 980
+#define IMG_CUSTOM_90_EDITOR 981
+#define IMG_CUSTOM_91 982
+#define IMG_CUSTOM_91_EDITOR 983
+#define IMG_CUSTOM_92 984
+#define IMG_CUSTOM_92_EDITOR 985
+#define IMG_CUSTOM_93 986
+#define IMG_CUSTOM_93_EDITOR 987
+#define IMG_CUSTOM_94 988
+#define IMG_CUSTOM_94_EDITOR 989
+#define IMG_CUSTOM_95 990
+#define IMG_CUSTOM_95_EDITOR 991
+#define IMG_CUSTOM_96 992
+#define IMG_CUSTOM_96_EDITOR 993
+#define IMG_CUSTOM_97 994
+#define IMG_CUSTOM_97_EDITOR 995
+#define IMG_CUSTOM_98 996
+#define IMG_CUSTOM_98_EDITOR 997
+#define IMG_CUSTOM_99 998
+#define IMG_CUSTOM_99_EDITOR 999
+#define IMG_CUSTOM_100 1000
+#define IMG_CUSTOM_100_EDITOR 1001
+#define IMG_CUSTOM_101 1002
+#define IMG_CUSTOM_101_EDITOR 1003
+#define IMG_CUSTOM_102 1004
+#define IMG_CUSTOM_102_EDITOR 1005
+#define IMG_CUSTOM_103 1006
+#define IMG_CUSTOM_103_EDITOR 1007
+#define IMG_CUSTOM_104 1008
+#define IMG_CUSTOM_104_EDITOR 1009
+#define IMG_CUSTOM_105 1010
+#define IMG_CUSTOM_105_EDITOR 1011
+#define IMG_CUSTOM_106 1012
+#define IMG_CUSTOM_106_EDITOR 1013
+#define IMG_CUSTOM_107 1014
+#define IMG_CUSTOM_107_EDITOR 1015
+#define IMG_CUSTOM_108 1016
+#define IMG_CUSTOM_108_EDITOR 1017
+#define IMG_CUSTOM_109 1018
+#define IMG_CUSTOM_109_EDITOR 1019
+#define IMG_CUSTOM_110 1020
+#define IMG_CUSTOM_110_EDITOR 1021
+#define IMG_CUSTOM_111 1022
+#define IMG_CUSTOM_111_EDITOR 1023
+#define IMG_CUSTOM_112 1024
+#define IMG_CUSTOM_112_EDITOR 1025
+#define IMG_CUSTOM_113 1026
+#define IMG_CUSTOM_113_EDITOR 1027
+#define IMG_CUSTOM_114 1028
+#define IMG_CUSTOM_114_EDITOR 1029
+#define IMG_CUSTOM_115 1030
+#define IMG_CUSTOM_115_EDITOR 1031
+#define IMG_CUSTOM_116 1032
+#define IMG_CUSTOM_116_EDITOR 1033
+#define IMG_CUSTOM_117 1034
+#define IMG_CUSTOM_117_EDITOR 1035
+#define IMG_CUSTOM_118 1036
+#define IMG_CUSTOM_118_EDITOR 1037
+#define IMG_CUSTOM_119 1038
+#define IMG_CUSTOM_119_EDITOR 1039
+#define IMG_CUSTOM_120 1040
+#define IMG_CUSTOM_120_EDITOR 1041
+#define IMG_CUSTOM_121 1042
+#define IMG_CUSTOM_121_EDITOR 1043
+#define IMG_CUSTOM_122 1044
+#define IMG_CUSTOM_122_EDITOR 1045
+#define IMG_CUSTOM_123 1046
+#define IMG_CUSTOM_123_EDITOR 1047
+#define IMG_CUSTOM_124 1048
+#define IMG_CUSTOM_124_EDITOR 1049
+#define IMG_CUSTOM_125 1050
+#define IMG_CUSTOM_125_EDITOR 1051
+#define IMG_CUSTOM_126 1052
+#define IMG_CUSTOM_126_EDITOR 1053
+#define IMG_CUSTOM_127 1054
+#define IMG_CUSTOM_127_EDITOR 1055
+#define IMG_CUSTOM_128 1056
+#define IMG_CUSTOM_128_EDITOR 1057
+#define IMG_CUSTOM_129 1058
+#define IMG_CUSTOM_129_EDITOR 1059
+#define IMG_CUSTOM_130 1060
+#define IMG_CUSTOM_130_EDITOR 1061
+#define IMG_CUSTOM_131 1062
+#define IMG_CUSTOM_131_EDITOR 1063
+#define IMG_CUSTOM_132 1064
+#define IMG_CUSTOM_132_EDITOR 1065
+#define IMG_CUSTOM_133 1066
+#define IMG_CUSTOM_133_EDITOR 1067
+#define IMG_CUSTOM_134 1068
+#define IMG_CUSTOM_134_EDITOR 1069
+#define IMG_CUSTOM_135 1070
+#define IMG_CUSTOM_135_EDITOR 1071
+#define IMG_CUSTOM_136 1072
+#define IMG_CUSTOM_136_EDITOR 1073
+#define IMG_CUSTOM_137 1074
+#define IMG_CUSTOM_137_EDITOR 1075
+#define IMG_CUSTOM_138 1076
+#define IMG_CUSTOM_138_EDITOR 1077
+#define IMG_CUSTOM_139 1078
+#define IMG_CUSTOM_139_EDITOR 1079
+#define IMG_CUSTOM_140 1080
+#define IMG_CUSTOM_140_EDITOR 1081
+#define IMG_CUSTOM_141 1082
+#define IMG_CUSTOM_141_EDITOR 1083
+#define IMG_CUSTOM_142 1084
+#define IMG_CUSTOM_142_EDITOR 1085
+#define IMG_CUSTOM_143 1086
+#define IMG_CUSTOM_143_EDITOR 1087
+#define IMG_CUSTOM_144 1088
+#define IMG_CUSTOM_144_EDITOR 1089
+#define IMG_CUSTOM_145 1090
+#define IMG_CUSTOM_145_EDITOR 1091
+#define IMG_CUSTOM_146 1092
+#define IMG_CUSTOM_146_EDITOR 1093
+#define IMG_CUSTOM_147 1094
+#define IMG_CUSTOM_147_EDITOR 1095
+#define IMG_CUSTOM_148 1096
+#define IMG_CUSTOM_148_EDITOR 1097
+#define IMG_CUSTOM_149 1098
+#define IMG_CUSTOM_149_EDITOR 1099
+#define IMG_CUSTOM_150 1100
+#define IMG_CUSTOM_150_EDITOR 1101
+#define IMG_CUSTOM_151 1102
+#define IMG_CUSTOM_151_EDITOR 1103
+#define IMG_CUSTOM_152 1104
+#define IMG_CUSTOM_152_EDITOR 1105
+#define IMG_CUSTOM_153 1106
+#define IMG_CUSTOM_153_EDITOR 1107
+#define IMG_CUSTOM_154 1108
+#define IMG_CUSTOM_154_EDITOR 1109
+#define IMG_CUSTOM_155 1110
+#define IMG_CUSTOM_155_EDITOR 1111
+#define IMG_CUSTOM_156 1112
+#define IMG_CUSTOM_156_EDITOR 1113
+#define IMG_CUSTOM_157 1114
+#define IMG_CUSTOM_157_EDITOR 1115
+#define IMG_CUSTOM_158 1116
+#define IMG_CUSTOM_158_EDITOR 1117
+#define IMG_CUSTOM_159 1118
+#define IMG_CUSTOM_159_EDITOR 1119
+#define IMG_CUSTOM_160 1120
+#define IMG_CUSTOM_160_EDITOR 1121
+#define IMG_CUSTOM_161 1122
+#define IMG_CUSTOM_161_EDITOR 1123
+#define IMG_CUSTOM_162 1124
+#define IMG_CUSTOM_162_EDITOR 1125
+#define IMG_CUSTOM_163 1126
+#define IMG_CUSTOM_163_EDITOR 1127
+#define IMG_CUSTOM_164 1128
+#define IMG_CUSTOM_164_EDITOR 1129
+#define IMG_CUSTOM_165 1130
+#define IMG_CUSTOM_165_EDITOR 1131
+#define IMG_CUSTOM_166 1132
+#define IMG_CUSTOM_166_EDITOR 1133
+#define IMG_CUSTOM_167 1134
+#define IMG_CUSTOM_167_EDITOR 1135
+#define IMG_CUSTOM_168 1136
+#define IMG_CUSTOM_168_EDITOR 1137
+#define IMG_CUSTOM_169 1138
+#define IMG_CUSTOM_169_EDITOR 1139
+#define IMG_CUSTOM_170 1140
+#define IMG_CUSTOM_170_EDITOR 1141
+#define IMG_CUSTOM_171 1142
+#define IMG_CUSTOM_171_EDITOR 1143
+#define IMG_CUSTOM_172 1144
+#define IMG_CUSTOM_172_EDITOR 1145
+#define IMG_CUSTOM_173 1146
+#define IMG_CUSTOM_173_EDITOR 1147
+#define IMG_CUSTOM_174 1148
+#define IMG_CUSTOM_174_EDITOR 1149
+#define IMG_CUSTOM_175 1150
+#define IMG_CUSTOM_175_EDITOR 1151
+#define IMG_CUSTOM_176 1152
+#define IMG_CUSTOM_176_EDITOR 1153
+#define IMG_CUSTOM_177 1154
+#define IMG_CUSTOM_177_EDITOR 1155
+#define IMG_CUSTOM_178 1156
+#define IMG_CUSTOM_178_EDITOR 1157
+#define IMG_CUSTOM_179 1158
+#define IMG_CUSTOM_179_EDITOR 1159
+#define IMG_CUSTOM_180 1160
+#define IMG_CUSTOM_180_EDITOR 1161
+#define IMG_CUSTOM_181 1162
+#define IMG_CUSTOM_181_EDITOR 1163
+#define IMG_CUSTOM_182 1164
+#define IMG_CUSTOM_182_EDITOR 1165
+#define IMG_CUSTOM_183 1166
+#define IMG_CUSTOM_183_EDITOR 1167
+#define IMG_CUSTOM_184 1168
+#define IMG_CUSTOM_184_EDITOR 1169
+#define IMG_CUSTOM_185 1170
+#define IMG_CUSTOM_185_EDITOR 1171
+#define IMG_CUSTOM_186 1172
+#define IMG_CUSTOM_186_EDITOR 1173
+#define IMG_CUSTOM_187 1174
+#define IMG_CUSTOM_187_EDITOR 1175
+#define IMG_CUSTOM_188 1176
+#define IMG_CUSTOM_188_EDITOR 1177
+#define IMG_CUSTOM_189 1178
+#define IMG_CUSTOM_189_EDITOR 1179
+#define IMG_CUSTOM_190 1180
+#define IMG_CUSTOM_190_EDITOR 1181
+#define IMG_CUSTOM_191 1182
+#define IMG_CUSTOM_191_EDITOR 1183
+#define IMG_CUSTOM_192 1184
+#define IMG_CUSTOM_192_EDITOR 1185
+#define IMG_CUSTOM_193 1186
+#define IMG_CUSTOM_193_EDITOR 1187
+#define IMG_CUSTOM_194 1188
+#define IMG_CUSTOM_194_EDITOR 1189
+#define IMG_CUSTOM_195 1190
+#define IMG_CUSTOM_195_EDITOR 1191
+#define IMG_CUSTOM_196 1192
+#define IMG_CUSTOM_196_EDITOR 1193
+#define IMG_CUSTOM_197 1194
+#define IMG_CUSTOM_197_EDITOR 1195
+#define IMG_CUSTOM_198 1196
+#define IMG_CUSTOM_198_EDITOR 1197
+#define IMG_CUSTOM_199 1198
+#define IMG_CUSTOM_199_EDITOR 1199
+#define IMG_CUSTOM_200 1200
+#define IMG_CUSTOM_200_EDITOR 1201
+#define IMG_CUSTOM_201 1202
+#define IMG_CUSTOM_201_EDITOR 1203
+#define IMG_CUSTOM_202 1204
+#define IMG_CUSTOM_202_EDITOR 1205
+#define IMG_CUSTOM_203 1206
+#define IMG_CUSTOM_203_EDITOR 1207
+#define IMG_CUSTOM_204 1208
+#define IMG_CUSTOM_204_EDITOR 1209
+#define IMG_CUSTOM_205 1210
+#define IMG_CUSTOM_205_EDITOR 1211
+#define IMG_CUSTOM_206 1212
+#define IMG_CUSTOM_206_EDITOR 1213
+#define IMG_CUSTOM_207 1214
+#define IMG_CUSTOM_207_EDITOR 1215
+#define IMG_CUSTOM_208 1216
+#define IMG_CUSTOM_208_EDITOR 1217
+#define IMG_CUSTOM_209 1218
+#define IMG_CUSTOM_209_EDITOR 1219
+#define IMG_CUSTOM_210 1220
+#define IMG_CUSTOM_210_EDITOR 1221
+#define IMG_CUSTOM_211 1222
+#define IMG_CUSTOM_211_EDITOR 1223
+#define IMG_CUSTOM_212 1224
+#define IMG_CUSTOM_212_EDITOR 1225
+#define IMG_CUSTOM_213 1226
+#define IMG_CUSTOM_213_EDITOR 1227
+#define IMG_CUSTOM_214 1228
+#define IMG_CUSTOM_214_EDITOR 1229
+#define IMG_CUSTOM_215 1230
+#define IMG_CUSTOM_215_EDITOR 1231
+#define IMG_CUSTOM_216 1232
+#define IMG_CUSTOM_216_EDITOR 1233
+#define IMG_CUSTOM_217 1234
+#define IMG_CUSTOM_217_EDITOR 1235
+#define IMG_CUSTOM_218 1236
+#define IMG_CUSTOM_218_EDITOR 1237
+#define IMG_CUSTOM_219 1238
+#define IMG_CUSTOM_219_EDITOR 1239
+#define IMG_CUSTOM_220 1240
+#define IMG_CUSTOM_220_EDITOR 1241
+#define IMG_CUSTOM_221 1242
+#define IMG_CUSTOM_221_EDITOR 1243
+#define IMG_CUSTOM_222 1244
+#define IMG_CUSTOM_222_EDITOR 1245
+#define IMG_CUSTOM_223 1246
+#define IMG_CUSTOM_223_EDITOR 1247
+#define IMG_CUSTOM_224 1248
+#define IMG_CUSTOM_224_EDITOR 1249
+#define IMG_CUSTOM_225 1250
+#define IMG_CUSTOM_225_EDITOR 1251
+#define IMG_CUSTOM_226 1252
+#define IMG_CUSTOM_226_EDITOR 1253
+#define IMG_CUSTOM_227 1254
+#define IMG_CUSTOM_227_EDITOR 1255
+#define IMG_CUSTOM_228 1256
+#define IMG_CUSTOM_228_EDITOR 1257
+#define IMG_CUSTOM_229 1258
+#define IMG_CUSTOM_229_EDITOR 1259
+#define IMG_CUSTOM_230 1260
+#define IMG_CUSTOM_230_EDITOR 1261
+#define IMG_CUSTOM_231 1262
+#define IMG_CUSTOM_231_EDITOR 1263
+#define IMG_CUSTOM_232 1264
+#define IMG_CUSTOM_232_EDITOR 1265
+#define IMG_CUSTOM_233 1266
+#define IMG_CUSTOM_233_EDITOR 1267
+#define IMG_CUSTOM_234 1268
+#define IMG_CUSTOM_234_EDITOR 1269
+#define IMG_CUSTOM_235 1270
+#define IMG_CUSTOM_235_EDITOR 1271
+#define IMG_CUSTOM_236 1272
+#define IMG_CUSTOM_236_EDITOR 1273
+#define IMG_CUSTOM_237 1274
+#define IMG_CUSTOM_237_EDITOR 1275
+#define IMG_CUSTOM_238 1276
+#define IMG_CUSTOM_238_EDITOR 1277
+#define IMG_CUSTOM_239 1278
+#define IMG_CUSTOM_239_EDITOR 1279
+#define IMG_CUSTOM_240 1280
+#define IMG_CUSTOM_240_EDITOR 1281
+#define IMG_CUSTOM_241 1282
+#define IMG_CUSTOM_241_EDITOR 1283
+#define IMG_CUSTOM_242 1284
+#define IMG_CUSTOM_242_EDITOR 1285
+#define IMG_CUSTOM_243 1286
+#define IMG_CUSTOM_243_EDITOR 1287
+#define IMG_CUSTOM_244 1288
+#define IMG_CUSTOM_244_EDITOR 1289
+#define IMG_CUSTOM_245 1290
+#define IMG_CUSTOM_245_EDITOR 1291
+#define IMG_CUSTOM_246 1292
+#define IMG_CUSTOM_246_EDITOR 1293
+#define IMG_CUSTOM_247 1294
+#define IMG_CUSTOM_247_EDITOR 1295
+#define IMG_CUSTOM_248 1296
+#define IMG_CUSTOM_248_EDITOR 1297
+#define IMG_CUSTOM_249 1298
+#define IMG_CUSTOM_249_EDITOR 1299
+#define IMG_CUSTOM_250 1300
+#define IMG_CUSTOM_250_EDITOR 1301
+#define IMG_CUSTOM_251 1302
+#define IMG_CUSTOM_251_EDITOR 1303
+#define IMG_CUSTOM_252 1304
+#define IMG_CUSTOM_252_EDITOR 1305
+#define IMG_CUSTOM_253 1306
+#define IMG_CUSTOM_253_EDITOR 1307
+#define IMG_CUSTOM_254 1308
+#define IMG_CUSTOM_254_EDITOR 1309
+#define IMG_CUSTOM_255 1310
+#define IMG_CUSTOM_255_EDITOR 1311
+#define IMG_CUSTOM_256 1312
+#define IMG_CUSTOM_256_EDITOR 1313
+#define IMG_GROUP_1 1314
+#define IMG_GROUP_1_EDITOR 1315
+#define IMG_GROUP_2 1316
+#define IMG_GROUP_2_EDITOR 1317
+#define IMG_GROUP_3 1318
+#define IMG_GROUP_3_EDITOR 1319
+#define IMG_GROUP_4 1320
+#define IMG_GROUP_4_EDITOR 1321
+#define IMG_GROUP_5 1322
+#define IMG_GROUP_5_EDITOR 1323
+#define IMG_GROUP_6 1324
+#define IMG_GROUP_6_EDITOR 1325
+#define IMG_GROUP_7 1326
+#define IMG_GROUP_7_EDITOR 1327
+#define IMG_GROUP_8 1328
+#define IMG_GROUP_8_EDITOR 1329
+#define IMG_GROUP_9 1330
+#define IMG_GROUP_9_EDITOR 1331
+#define IMG_GROUP_10 1332
+#define IMG_GROUP_10_EDITOR 1333
+#define IMG_GROUP_11 1334
+#define IMG_GROUP_11_EDITOR 1335
+#define IMG_GROUP_12 1336
+#define IMG_GROUP_12_EDITOR 1337
+#define IMG_GROUP_13 1338
+#define IMG_GROUP_13_EDITOR 1339
+#define IMG_GROUP_14 1340
+#define IMG_GROUP_14_EDITOR 1341
+#define IMG_GROUP_15 1342
+#define IMG_GROUP_15_EDITOR 1343
+#define IMG_GROUP_16 1344
+#define IMG_GROUP_16_EDITOR 1345
+#define IMG_GROUP_17 1346
+#define IMG_GROUP_17_EDITOR 1347
+#define IMG_GROUP_18 1348
+#define IMG_GROUP_18_EDITOR 1349
+#define IMG_GROUP_19 1350
+#define IMG_GROUP_19_EDITOR 1351
+#define IMG_GROUP_20 1352
+#define IMG_GROUP_20_EDITOR 1353
+#define IMG_GROUP_21 1354
+#define IMG_GROUP_21_EDITOR 1355
+#define IMG_GROUP_22 1356
+#define IMG_GROUP_22_EDITOR 1357
+#define IMG_GROUP_23 1358
+#define IMG_GROUP_23_EDITOR 1359
+#define IMG_GROUP_24 1360
+#define IMG_GROUP_24_EDITOR 1361
+#define IMG_GROUP_25 1362
+#define IMG_GROUP_25_EDITOR 1363
+#define IMG_GROUP_26 1364
+#define IMG_GROUP_26_EDITOR 1365
+#define IMG_GROUP_27 1366
+#define IMG_GROUP_27_EDITOR 1367
+#define IMG_GROUP_28 1368
+#define IMG_GROUP_28_EDITOR 1369
+#define IMG_GROUP_29 1370
+#define IMG_GROUP_29_EDITOR 1371
+#define IMG_GROUP_30 1372
+#define IMG_GROUP_30_EDITOR 1373
+#define IMG_GROUP_31 1374
+#define IMG_GROUP_31_EDITOR 1375
+#define IMG_GROUP_32 1376
+#define IMG_GROUP_32_EDITOR 1377
+#define IMG_EMC_OBJECT 1378
+#define IMG_EMC_SPRITE 1379
+#define IMG_TOON_1 1380
+#define IMG_TOON_2 1381
+#define IMG_TOON_3 1382
+#define IMG_TOON_4 1383
+#define IMG_TOON_5 1384
+#define IMG_TOON_6 1385
+#define IMG_TOON_7 1386
+#define IMG_TOON_8 1387
+#define IMG_TOON_9 1388
+#define IMG_TOON_10 1389
+#define IMG_TOON_11 1390
+#define IMG_TOON_12 1391
+#define IMG_TOON_13 1392
+#define IMG_TOON_14 1393
+#define IMG_TOON_15 1394
+#define IMG_TOON_16 1395
+#define IMG_TOON_17 1396
+#define IMG_TOON_18 1397
+#define IMG_TOON_19 1398
+#define IMG_TOON_20 1399
+#define IMG_MENU_CALIBRATE_RED 1400
+#define IMG_MENU_CALIBRATE_BLUE 1401
+#define IMG_MENU_CALIBRATE_YELLOW 1402
+#define IMG_MENU_BUTTON 1403
+#define IMG_MENU_BUTTON_ACTIVE 1404
+#define IMG_MENU_BUTTON_LEFT 1405
+#define IMG_MENU_BUTTON_RIGHT 1406
+#define IMG_MENU_BUTTON_UP 1407
+#define IMG_MENU_BUTTON_DOWN 1408
+#define IMG_MENU_BUTTON_LEFT_ACTIVE 1409
+#define IMG_MENU_BUTTON_RIGHT_ACTIVE 1410
+#define IMG_MENU_BUTTON_UP_ACTIVE 1411
+#define IMG_MENU_BUTTON_DOWN_ACTIVE 1412
+#define IMG_MENU_SCROLLBAR 1413
+#define IMG_MENU_SCROLLBAR_ACTIVE 1414
+#define IMG_FONT_INITIAL_1 1415
+#define IMG_FONT_INITIAL_2 1416
+#define IMG_FONT_INITIAL_3 1417
+#define IMG_FONT_INITIAL_4 1418
+#define IMG_FONT_TITLE_1 1419
+#define IMG_FONT_TITLE_1_LEVELS 1420
+#define IMG_FONT_TITLE_2 1421
+#define IMG_FONT_MENU_1 1422
+#define IMG_FONT_MENU_2 1423
+#define IMG_FONT_TEXT_1 1424
+#define IMG_FONT_TEXT_1_LEVELS 1425
+#define IMG_FONT_TEXT_1_PREVIEW 1426
+#define IMG_FONT_TEXT_1_SCORES 1427
+#define IMG_FONT_TEXT_1_ACTIVE_SCORES 1428
+#define IMG_FONT_TEXT_2 1429
+#define IMG_FONT_TEXT_2_LEVELS 1430
+#define IMG_FONT_TEXT_2_PREVIEW 1431
+#define IMG_FONT_TEXT_2_SCORES 1432
+#define IMG_FONT_TEXT_2_ACTIVE_SCORES 1433
+#define IMG_FONT_TEXT_3 1434
+#define IMG_FONT_TEXT_3_LEVELS 1435
+#define IMG_FONT_TEXT_3_PREVIEW 1436
+#define IMG_FONT_TEXT_3_SCORES 1437
+#define IMG_FONT_TEXT_3_ACTIVE_SCORES 1438
+#define IMG_FONT_TEXT_4 1439
+#define IMG_FONT_TEXT_4_LEVELS 1440
+#define IMG_FONT_TEXT_4_SCORES 1441
+#define IMG_FONT_TEXT_4_ACTIVE_SCORES 1442
+#define IMG_FONT_ENVELOPE_1 1443
+#define IMG_FONT_ENVELOPE_2 1444
+#define IMG_FONT_ENVELOPE_3 1445
+#define IMG_FONT_ENVELOPE_4 1446
+#define IMG_FONT_INPUT_1 1447
+#define IMG_FONT_INPUT_1_MAIN 1448
+#define IMG_FONT_INPUT_1_ACTIVE 1449
+#define IMG_FONT_INPUT_1_ACTIVE_MAIN 1450
+#define IMG_FONT_INPUT_1_ACTIVE_SETUP 1451
+#define IMG_FONT_INPUT_2 1452
+#define IMG_FONT_INPUT_2_ACTIVE 1453
+#define IMG_FONT_OPTION_OFF 1454
+#define IMG_FONT_OPTION_ON 1455
+#define IMG_FONT_VALUE_1 1456
+#define IMG_FONT_VALUE_2 1457
+#define IMG_FONT_VALUE_OLD 1458
+#define IMG_FONT_LEVEL_NUMBER 1459
+#define IMG_FONT_TAPE_RECORDER 1460
+#define IMG_FONT_GAME_INFO 1461
+#define IMG_GLOBAL_BORDER 1462
+#define IMG_GLOBAL_DOOR 1463
+#define IMG_EDITOR_ELEMENT_BORDER 1464
+#define IMG_EDITOR_ELEMENT_BORDER_INPUT 1465
+#define IMG_BACKGROUND_ENVELOPE_1 1466
+#define IMG_BACKGROUND_ENVELOPE_2 1467
+#define IMG_BACKGROUND_ENVELOPE_3 1468
+#define IMG_BACKGROUND_ENVELOPE_4 1469
+#define IMG_BACKGROUND 1470
+#define IMG_BACKGROUND_MAIN 1471
+#define IMG_BACKGROUND_LEVELS 1472
+#define IMG_BACKGROUND_SCORES 1473
+#define IMG_BACKGROUND_EDITOR 1474
+#define IMG_BACKGROUND_INFO 1475
+#define IMG_BACKGROUND_INFO_ELEMENTS 1476
+#define IMG_BACKGROUND_SETUP 1477
+#define IMG_BACKGROUND_DOOR 1478
-#define NUM_IMAGE_FILES 1402
+#define NUM_IMAGE_FILES 1479
#endif /* CONF_GFX_H */
{ "char_quotedbl", "10" },
{ "char_numbersign", "10" },
{ "char_dollar", "10" },
- { "char_procent", "10" },
+ { "char_percent", "10" },
{ "char_ampersand", "10" },
{ "char_apostrophe", "10" },
{ "char_parenleft", "10" },
reliable default values. If that value is MUS_ARG_UNDEFINED, it will
be dynamically determined, using some of the other list values. */
-struct ConfigInfo music_config_suffix[] =
+struct ConfigTypeInfo music_config_suffix[] =
{
{ ".mode_loop", ARG_UNDEFINED, TYPE_BOOLEAN },
reliable default values. If that value is SND_ARG_UNDEFINED, it will
be dynamically determined, using some of the other list values. */
-struct ConfigInfo sound_config_suffix[] =
+struct ConfigTypeInfo sound_config_suffix[] =
{
{ ".mode_loop", ARG_UNDEFINED, TYPE_BOOLEAN },
+ { ".volume", "100", TYPE_INTEGER },
+ { ".priority", "0", TYPE_INTEGER },
{ NULL, NULL, 0 }
};
{ "spaceship.waiting", "roehr.wav" },
{ "yamyam.moving", UNDEFINED_FILENAME },
{ "yamyam.waiting", "njam.wav" },
- { "yamyam.digging", UNDEFINED_FILENAME },
+ { "yamyam.digging", "njam.wav" },
{ "robot.moving", "schlurf.wav" },
{ "robot.moving.mode_loop", "false" },
{ "robot.waiting", UNDEFINED_FILENAME },
{ "spring.pushing", "pusch.wav" },
{ "spring.impact", "klopf.wav" },
{ "[wall].growing", UNDEFINED_FILENAME },
+ { "emc_android.pushing", "pusch.wav" },
+ { "emc_android.moving", "roehr.wav" },
+ { "emc_android.moving.mode_loop", "false" },
+ { "emc_android.dropping", "deng.wav" },
+ { "emc_magic_ball.dropping", "deng.wav" },
/* sounds for Diamond Caves style elements and actions */
{ "pearl.collecting", "pong.wav" },
{ "[envelope].opening", UNDEFINED_FILENAME },
{ "[envelope].closing", UNDEFINED_FILENAME },
{ "invisible_sand.digging", "schlurf.wav" },
+ { "invisible_sand.active.digging", "schlurf.wav" },
{ "shield_normal.collecting", "pong.wav" },
{ "shield_normal.active", UNDEFINED_FILENAME },
{ "shield_deadly.collecting", "pong.wav" },
#define SND_SPRING_PUSHING 95
#define SND_SPRING_IMPACT 96
#define SND_CLASS_WALL_GROWING 97
-#define SND_PEARL_COLLECTING 98
-#define SND_PEARL_BREAKING 99
-#define SND_PEARL_IMPACT 100
-#define SND_CRYSTAL_COLLECTING 101
-#define SND_CRYSTAL_IMPACT 102
-#define SND_CLASS_ENVELOPE_COLLECTING 103
-#define SND_CLASS_ENVELOPE_OPENING 104
-#define SND_CLASS_ENVELOPE_CLOSING 105
-#define SND_INVISIBLE_SAND_DIGGING 106
-#define SND_SHIELD_NORMAL_COLLECTING 107
-#define SND_SHIELD_NORMAL_ACTIVE 108
-#define SND_SHIELD_DEADLY_COLLECTING 109
-#define SND_SHIELD_DEADLY_ACTIVE 110
-#define SND_EXTRA_TIME_COLLECTING 111
-#define SND_MOLE_MOVING 112
-#define SND_MOLE_WAITING 113
-#define SND_MOLE_DIGGING 114
-#define SND_CLASS_SWITCHGATE_SWITCH_ACTIVATING 115
-#define SND_CLASS_SWITCHGATE_OPENING 116
-#define SND_CLASS_SWITCHGATE_CLOSING 117
-#define SND_CLASS_SWITCHGATE_PASSING 118
-#define SND_TIMEGATE_SWITCH_ACTIVATING 119
-#define SND_TIMEGATE_SWITCH_ACTIVE 120
-#define SND_TIMEGATE_SWITCH_DEACTIVATING 121
-#define SND_TIMEGATE_OPENING 122
-#define SND_CLASS_TIMEGATE_CLOSING 123
-#define SND_CLASS_TIMEGATE_PASSING 124
-#define SND_CLASS_CONVEYOR_BELT_SWITCH_ACTIVATING 125
-#define SND_CLASS_CONVEYOR_BELT_ACTIVE 126
-#define SND_CLASS_CONVEYOR_BELT_SWITCH_DEACTIVATING 127
-#define SND_LIGHT_SWITCH_ACTIVATING 128
-#define SND_LIGHT_SWITCH_DEACTIVATING 129
-#define SND_DX_SUPABOMB_PUSHING 130
-#define SND_TRAP_DIGGING 131
-#define SND_TRAP_ACTIVATING 132
-#define SND_CLASS_TUBE_WALKING 133
-#define SND_AMOEBA_TURNING_TO_GEM 134
-#define SND_AMOEBA_TURNING_TO_ROCK 135
-#define SND_SPEED_PILL_COLLECTING 136
-#define SND_DYNABOMB_INCREASE_NUMBER_COLLECTING 137
-#define SND_DYNABOMB_INCREASE_SIZE_COLLECTING 138
-#define SND_DYNABOMB_INCREASE_POWER_COLLECTING 139
-#define SND_CLASS_DYNABOMB_DROPPING 140
-#define SND_CLASS_DYNABOMB_ACTIVE 141
-#define SND_SATELLITE_MOVING 142
-#define SND_SATELLITE_WAITING 143
-#define SND_SATELLITE_PUSHING 144
-#define SND_LAMP_ACTIVATING 145
-#define SND_LAMP_DEACTIVATING 146
-#define SND_TIME_ORB_FULL_COLLECTING 147
-#define SND_TIME_ORB_FULL_IMPACT 148
-#define SND_TIME_ORB_EMPTY_PUSHING 149
-#define SND_TIME_ORB_EMPTY_IMPACT 150
-#define SND_GAME_OF_LIFE_WAITING 151
-#define SND_GAME_OF_LIFE_GROWING 152
-#define SND_BIOMAZE_WAITING 153
-#define SND_BIOMAZE_GROWING 154
-#define SND_PACMAN_MOVING 155
-#define SND_PACMAN_WAITING 156
-#define SND_PACMAN_DIGGING 157
-#define SND_DARK_YAMYAM_MOVING 158
-#define SND_DARK_YAMYAM_WAITING 159
-#define SND_DARK_YAMYAM_DIGGING 160
-#define SND_PENGUIN_MOVING 161
-#define SND_PENGUIN_WAITING 162
-#define SND_PIG_MOVING 163
-#define SND_PIG_WAITING 164
-#define SND_PIG_DIGGING 165
-#define SND_DRAGON_MOVING 166
-#define SND_DRAGON_WAITING 167
-#define SND_DRAGON_ATTACKING 168
-#define SND_GAME_STARTING 169
-#define SND_GAME_RUNNING_OUT_OF_TIME 170
-#define SND_GAME_LEVELTIME_BONUS 171
-#define SND_GAME_LOSING 172
-#define SND_GAME_WINNING 173
-#define SND_GAME_SOKOBAN_SOLVING 174
-#define SND_DOOR_OPENING 175
-#define SND_DOOR_CLOSING 176
-#define SND_BACKGROUND_MAIN 177
-#define SND_BACKGROUND_LEVELS 178
-#define SND_BACKGROUND_SCORES 179
-#define SND_BACKGROUND_EDITOR 180
-#define SND_BACKGROUND_INFO 181
-#define SND_BACKGROUND_SETUP 182
+#define SND_EMC_ANDROID_PUSHING 98
+#define SND_EMC_ANDROID_MOVING 99
+#define SND_EMC_ANDROID_DROPPING 100
+#define SND_EMC_MAGIC_BALL_DROPPING 101
+#define SND_PEARL_COLLECTING 102
+#define SND_PEARL_BREAKING 103
+#define SND_PEARL_IMPACT 104
+#define SND_CRYSTAL_COLLECTING 105
+#define SND_CRYSTAL_IMPACT 106
+#define SND_CLASS_ENVELOPE_COLLECTING 107
+#define SND_CLASS_ENVELOPE_OPENING 108
+#define SND_CLASS_ENVELOPE_CLOSING 109
+#define SND_INVISIBLE_SAND_DIGGING 110
+#define SND_INVISIBLE_SAND_ACTIVE_DIGGING 111
+#define SND_SHIELD_NORMAL_COLLECTING 112
+#define SND_SHIELD_NORMAL_ACTIVE 113
+#define SND_SHIELD_DEADLY_COLLECTING 114
+#define SND_SHIELD_DEADLY_ACTIVE 115
+#define SND_EXTRA_TIME_COLLECTING 116
+#define SND_MOLE_MOVING 117
+#define SND_MOLE_WAITING 118
+#define SND_MOLE_DIGGING 119
+#define SND_CLASS_SWITCHGATE_SWITCH_ACTIVATING 120
+#define SND_CLASS_SWITCHGATE_OPENING 121
+#define SND_CLASS_SWITCHGATE_CLOSING 122
+#define SND_CLASS_SWITCHGATE_PASSING 123
+#define SND_TIMEGATE_SWITCH_ACTIVATING 124
+#define SND_TIMEGATE_SWITCH_ACTIVE 125
+#define SND_TIMEGATE_SWITCH_DEACTIVATING 126
+#define SND_TIMEGATE_OPENING 127
+#define SND_CLASS_TIMEGATE_CLOSING 128
+#define SND_CLASS_TIMEGATE_PASSING 129
+#define SND_CLASS_CONVEYOR_BELT_SWITCH_ACTIVATING 130
+#define SND_CLASS_CONVEYOR_BELT_ACTIVE 131
+#define SND_CLASS_CONVEYOR_BELT_SWITCH_DEACTIVATING 132
+#define SND_LIGHT_SWITCH_ACTIVATING 133
+#define SND_LIGHT_SWITCH_DEACTIVATING 134
+#define SND_DX_SUPABOMB_PUSHING 135
+#define SND_TRAP_DIGGING 136
+#define SND_TRAP_ACTIVATING 137
+#define SND_CLASS_TUBE_WALKING 138
+#define SND_AMOEBA_TURNING_TO_GEM 139
+#define SND_AMOEBA_TURNING_TO_ROCK 140
+#define SND_SPEED_PILL_COLLECTING 141
+#define SND_DYNABOMB_INCREASE_NUMBER_COLLECTING 142
+#define SND_DYNABOMB_INCREASE_SIZE_COLLECTING 143
+#define SND_DYNABOMB_INCREASE_POWER_COLLECTING 144
+#define SND_CLASS_DYNABOMB_DROPPING 145
+#define SND_CLASS_DYNABOMB_ACTIVE 146
+#define SND_SATELLITE_MOVING 147
+#define SND_SATELLITE_WAITING 148
+#define SND_SATELLITE_PUSHING 149
+#define SND_LAMP_ACTIVATING 150
+#define SND_LAMP_DEACTIVATING 151
+#define SND_TIME_ORB_FULL_COLLECTING 152
+#define SND_TIME_ORB_FULL_IMPACT 153
+#define SND_TIME_ORB_EMPTY_PUSHING 154
+#define SND_TIME_ORB_EMPTY_IMPACT 155
+#define SND_GAME_OF_LIFE_WAITING 156
+#define SND_GAME_OF_LIFE_GROWING 157
+#define SND_BIOMAZE_WAITING 158
+#define SND_BIOMAZE_GROWING 159
+#define SND_PACMAN_MOVING 160
+#define SND_PACMAN_WAITING 161
+#define SND_PACMAN_DIGGING 162
+#define SND_DARK_YAMYAM_MOVING 163
+#define SND_DARK_YAMYAM_WAITING 164
+#define SND_DARK_YAMYAM_DIGGING 165
+#define SND_PENGUIN_MOVING 166
+#define SND_PENGUIN_WAITING 167
+#define SND_PIG_MOVING 168
+#define SND_PIG_WAITING 169
+#define SND_PIG_DIGGING 170
+#define SND_DRAGON_MOVING 171
+#define SND_DRAGON_WAITING 172
+#define SND_DRAGON_ATTACKING 173
+#define SND_GAME_STARTING 174
+#define SND_GAME_RUNNING_OUT_OF_TIME 175
+#define SND_GAME_LEVELTIME_BONUS 176
+#define SND_GAME_LOSING 177
+#define SND_GAME_WINNING 178
+#define SND_GAME_SOKOBAN_SOLVING 179
+#define SND_DOOR_OPENING 180
+#define SND_DOOR_CLOSING 181
+#define SND_BACKGROUND_MAIN 182
+#define SND_BACKGROUND_LEVELS 183
+#define SND_BACKGROUND_SCORES 184
+#define SND_BACKGROUND_EDITOR 185
+#define SND_BACKGROUND_INFO 186
+#define SND_BACKGROUND_SETUP 187
-#define NUM_SOUND_FILES 183
+#define NUM_SOUND_FILES 188
#endif /* CONF_SND_H */
-#define COMPILE_DATE_STRING "[2004-06-07 01:56]"
+#define COMPILE_DATE_STRING "[2005-08-16 00:08]"
MINI_TILEX / 2)
/* values for the settings windows */
-#define ED_SETTINGS_XSTART (3 * MINI_TILEX / 2)
-#define ED_SETTINGS_YSTART (MINI_TILEY * 10)
+#define ED_LEVEL_SETTINGS_XSTART (3 * MINI_TILEX / 2)
+#define ED_LEVEL_SETTINGS_YSTART (5 * MINI_TILEY)
+
+#define ED_ELEMENT_SETTINGS_XSTART (3 * MINI_TILEX / 2)
+#define ED_ELEMENT_SETTINGS_YSTART (10 * MINI_TILEY)
#define ED_XOFFSET_CHECKBOX (ED_CHECKBUTTON_XSIZE + \
2 * ED_GADGET_DISTANCE)
#define ED_SETTINGS_XOFFSET ED_XOFFSET_CHECKBOX
#define ED_SETTINGS_YOFFSET (3 * MINI_TILEY / 2)
-#define ED_SETTINGS_XPOS(n) (ED_SETTINGS_XSTART + \
+#define ED_LEVEL_SETTINGS_XPOS(n) (ED_LEVEL_SETTINGS_XSTART + \
(n) * ED_SETTINGS_XOFFSET)
-#define ED_SETTINGS_YPOS(n) (ED_SETTINGS_YSTART + \
+#define ED_LEVEL_SETTINGS_YPOS(n) (ED_LEVEL_SETTINGS_YSTART + \
+ (n) * ED_SETTINGS_YOFFSET)
+
+#define ED_ELEMENT_SETTINGS_XPOS(n) (ED_ELEMENT_SETTINGS_XSTART + \
+ (n) * ED_SETTINGS_XOFFSET)
+#define ED_ELEMENT_SETTINGS_YPOS(n) (ED_ELEMENT_SETTINGS_YSTART + \
(n) * ED_SETTINGS_YOFFSET)
#define ED_SETTINGS1_YPOS MINI_TILEY
(n) * ED_COUNTER_YDISTANCE - 2)
/* values for element content drawing areas */
-#define ED_AREA_1X1_SETTINGS_XPOS(n) (ED_SETTINGS_XPOS(n))
-#define ED_AREA_1X1_SETTINGS_YPOS(n) (ED_SETTINGS_YPOS(n) + \
+#define ED_AREA_1X1_SETTINGS_XPOS(n) (ED_ELEMENT_SETTINGS_XPOS(n))
+#define ED_AREA_1X1_SETTINGS_YPOS(n) (ED_ELEMENT_SETTINGS_YPOS(n) + \
ED_GADGET_DISTANCE)
-#define ED_AREA_3X3_SETTINGS_XPOS(n) (ED_SETTINGS_XPOS(n))
-#define ED_AREA_3X3_SETTINGS_YPOS(n) (ED_SETTINGS_YPOS(n) + \
+#define ED_AREA_3X3_SETTINGS_XPOS(n) (ED_ELEMENT_SETTINGS_XPOS(n))
+#define ED_AREA_3X3_SETTINGS_YPOS(n) (ED_ELEMENT_SETTINGS_YPOS(n) + \
ED_GADGET_DISTANCE - MINI_TILEY)
/* yamyam content */
#define ED_AREA_YAMYAM_CONTENT_YPOS(n) (17 * MINI_TILEY + \
6 * ((n) / 4) * MINI_TILEY)
+/* magic ball content */
+#define ED_AREA_MAGIC_BALL_CONTENT_XPOS(n) (2 * MINI_TILEX + \
+ 5 * ((n) % 4) * MINI_TILEX)
+#define ED_AREA_MAGIC_BALL_CONTENT_YPOS(n) (17 * MINI_TILEY + \
+ 6 * ((n) / 4) * MINI_TILEY)
+
/* values for scrolling gadgets for drawing area */
#define ED_SCROLLBUTTON_XPOS 24
#define ED_SCROLLBUTTON_YPOS 0
#define GADGET_ID_LEVEL_TIMESCORE_DOWN (GADGET_ID_COUNTER_FIRST + 18)
#define GADGET_ID_LEVEL_TIMESCORE_TEXT (GADGET_ID_COUNTER_FIRST + 19)
#define GADGET_ID_LEVEL_TIMESCORE_UP (GADGET_ID_COUNTER_FIRST + 20)
-#define GADGET_ID_ELEMENT_SCORE_DOWN (GADGET_ID_COUNTER_FIRST + 21)
-#define GADGET_ID_ELEMENT_SCORE_TEXT (GADGET_ID_COUNTER_FIRST + 22)
-#define GADGET_ID_ELEMENT_SCORE_UP (GADGET_ID_COUNTER_FIRST + 23)
-#define GADGET_ID_ELEMENT_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 24)
-#define GADGET_ID_ELEMENT_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 25)
-#define GADGET_ID_ELEMENT_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 26)
-#define GADGET_ID_ENVELOPE_XSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 27)
-#define GADGET_ID_ENVELOPE_XSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 28)
-#define GADGET_ID_ENVELOPE_XSIZE_UP (GADGET_ID_COUNTER_FIRST + 29)
-#define GADGET_ID_ENVELOPE_YSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 30)
-#define GADGET_ID_ENVELOPE_YSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 31)
-#define GADGET_ID_ENVELOPE_YSIZE_UP (GADGET_ID_COUNTER_FIRST + 32)
-#define GADGET_ID_CUSTOM_SCORE_DOWN (GADGET_ID_COUNTER_FIRST + 33)
-#define GADGET_ID_CUSTOM_SCORE_TEXT (GADGET_ID_COUNTER_FIRST + 34)
-#define GADGET_ID_CUSTOM_SCORE_UP (GADGET_ID_COUNTER_FIRST + 35)
-#define GADGET_ID_CUSTOM_GEMCOUNT_DOWN (GADGET_ID_COUNTER_FIRST + 36)
-#define GADGET_ID_CUSTOM_GEMCOUNT_TEXT (GADGET_ID_COUNTER_FIRST + 37)
-#define GADGET_ID_CUSTOM_GEMCOUNT_UP (GADGET_ID_COUNTER_FIRST + 38)
-#define GADGET_ID_PUSH_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 39)
-#define GADGET_ID_PUSH_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 40)
-#define GADGET_ID_PUSH_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 41)
-#define GADGET_ID_PUSH_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 42)
-#define GADGET_ID_PUSH_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 43)
-#define GADGET_ID_PUSH_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 44)
-#define GADGET_ID_DROP_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 45)
-#define GADGET_ID_DROP_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 46)
-#define GADGET_ID_DROP_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 47)
-#define GADGET_ID_DROP_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 48)
-#define GADGET_ID_DROP_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 49)
-#define GADGET_ID_DROP_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 50)
-#define GADGET_ID_MOVE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 51)
-#define GADGET_ID_MOVE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 52)
-#define GADGET_ID_MOVE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 53)
-#define GADGET_ID_MOVE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 54)
-#define GADGET_ID_MOVE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 55)
-#define GADGET_ID_MOVE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 56)
-#define GADGET_ID_EXPLOSION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 57)
-#define GADGET_ID_EXPLOSION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 58)
-#define GADGET_ID_EXPLOSION_DELAY_UP (GADGET_ID_COUNTER_FIRST + 59)
-#define GADGET_ID_IGNITION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 60)
-#define GADGET_ID_IGNITION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 61)
-#define GADGET_ID_IGNITION_DELAY_UP (GADGET_ID_COUNTER_FIRST + 62)
-#define GADGET_ID_CHANGE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 63)
-#define GADGET_ID_CHANGE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 64)
-#define GADGET_ID_CHANGE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 65)
-#define GADGET_ID_CHANGE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 66)
-#define GADGET_ID_CHANGE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 67)
-#define GADGET_ID_CHANGE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 68)
-#define GADGET_ID_CHANGE_CONT_RND_DOWN (GADGET_ID_COUNTER_FIRST + 69)
-#define GADGET_ID_CHANGE_CONT_RND_TEXT (GADGET_ID_COUNTER_FIRST + 70)
-#define GADGET_ID_CHANGE_CONT_RND_UP (GADGET_ID_COUNTER_FIRST + 71)
-#define GADGET_ID_GROUP_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 72)
-#define GADGET_ID_GROUP_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 73)
-#define GADGET_ID_GROUP_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 74)
+#define GADGET_ID_ELEMENT_VALUE1_DOWN (GADGET_ID_COUNTER_FIRST + 21)
+#define GADGET_ID_ELEMENT_VALUE1_TEXT (GADGET_ID_COUNTER_FIRST + 22)
+#define GADGET_ID_ELEMENT_VALUE1_UP (GADGET_ID_COUNTER_FIRST + 23)
+#define GADGET_ID_ELEMENT_VALUE2_DOWN (GADGET_ID_COUNTER_FIRST + 24)
+#define GADGET_ID_ELEMENT_VALUE2_TEXT (GADGET_ID_COUNTER_FIRST + 25)
+#define GADGET_ID_ELEMENT_VALUE2_UP (GADGET_ID_COUNTER_FIRST + 26)
+#define GADGET_ID_YAMYAM_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 27)
+#define GADGET_ID_YAMYAM_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 28)
+#define GADGET_ID_YAMYAM_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 29)
+#define GADGET_ID_ENVELOPE_XSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 30)
+#define GADGET_ID_ENVELOPE_XSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 31)
+#define GADGET_ID_ENVELOPE_XSIZE_UP (GADGET_ID_COUNTER_FIRST + 32)
+#define GADGET_ID_ENVELOPE_YSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 33)
+#define GADGET_ID_ENVELOPE_YSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 34)
+#define GADGET_ID_ENVELOPE_YSIZE_UP (GADGET_ID_COUNTER_FIRST + 35)
+#define GADGET_ID_CUSTOM_SCORE_DOWN (GADGET_ID_COUNTER_FIRST + 36)
+#define GADGET_ID_CUSTOM_SCORE_TEXT (GADGET_ID_COUNTER_FIRST + 37)
+#define GADGET_ID_CUSTOM_SCORE_UP (GADGET_ID_COUNTER_FIRST + 38)
+#define GADGET_ID_CUSTOM_GEMCOUNT_DOWN (GADGET_ID_COUNTER_FIRST + 39)
+#define GADGET_ID_CUSTOM_GEMCOUNT_TEXT (GADGET_ID_COUNTER_FIRST + 40)
+#define GADGET_ID_CUSTOM_GEMCOUNT_UP (GADGET_ID_COUNTER_FIRST + 41)
+#define GADGET_ID_PUSH_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 42)
+#define GADGET_ID_PUSH_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 43)
+#define GADGET_ID_PUSH_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 44)
+#define GADGET_ID_PUSH_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 45)
+#define GADGET_ID_PUSH_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 46)
+#define GADGET_ID_PUSH_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 47)
+#define GADGET_ID_DROP_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 48)
+#define GADGET_ID_DROP_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 49)
+#define GADGET_ID_DROP_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 50)
+#define GADGET_ID_DROP_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 51)
+#define GADGET_ID_DROP_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 52)
+#define GADGET_ID_DROP_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 53)
+#define GADGET_ID_MOVE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 54)
+#define GADGET_ID_MOVE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 55)
+#define GADGET_ID_MOVE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 56)
+#define GADGET_ID_MOVE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 57)
+#define GADGET_ID_MOVE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 58)
+#define GADGET_ID_MOVE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 59)
+#define GADGET_ID_EXPLOSION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 60)
+#define GADGET_ID_EXPLOSION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 61)
+#define GADGET_ID_EXPLOSION_DELAY_UP (GADGET_ID_COUNTER_FIRST + 62)
+#define GADGET_ID_IGNITION_DELAY_DOWN (GADGET_ID_COUNTER_FIRST + 63)
+#define GADGET_ID_IGNITION_DELAY_TEXT (GADGET_ID_COUNTER_FIRST + 64)
+#define GADGET_ID_IGNITION_DELAY_UP (GADGET_ID_COUNTER_FIRST + 65)
+#define GADGET_ID_CHANGE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 66)
+#define GADGET_ID_CHANGE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 67)
+#define GADGET_ID_CHANGE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 68)
+#define GADGET_ID_CHANGE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 69)
+#define GADGET_ID_CHANGE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 70)
+#define GADGET_ID_CHANGE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 71)
+#define GADGET_ID_CHANGE_CONT_RND_DOWN (GADGET_ID_COUNTER_FIRST + 72)
+#define GADGET_ID_CHANGE_CONT_RND_TEXT (GADGET_ID_COUNTER_FIRST + 73)
+#define GADGET_ID_CHANGE_CONT_RND_UP (GADGET_ID_COUNTER_FIRST + 74)
+#define GADGET_ID_GROUP_CONTENT_DOWN (GADGET_ID_COUNTER_FIRST + 75)
+#define GADGET_ID_GROUP_CONTENT_TEXT (GADGET_ID_COUNTER_FIRST + 76)
+#define GADGET_ID_GROUP_CONTENT_UP (GADGET_ID_COUNTER_FIRST + 77)
/* drawing area identifiers */
-#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 75)
+#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 78)
#define GADGET_ID_DRAWING_LEVEL (GADGET_ID_DRAWING_AREA_FIRST + 0)
-#define GADGET_ID_ELEMENT_CONTENT_0 (GADGET_ID_DRAWING_AREA_FIRST + 1)
-#define GADGET_ID_ELEMENT_CONTENT_1 (GADGET_ID_DRAWING_AREA_FIRST + 2)
-#define GADGET_ID_ELEMENT_CONTENT_2 (GADGET_ID_DRAWING_AREA_FIRST + 3)
-#define GADGET_ID_ELEMENT_CONTENT_3 (GADGET_ID_DRAWING_AREA_FIRST + 4)
-#define GADGET_ID_ELEMENT_CONTENT_4 (GADGET_ID_DRAWING_AREA_FIRST + 5)
-#define GADGET_ID_ELEMENT_CONTENT_5 (GADGET_ID_DRAWING_AREA_FIRST + 6)
-#define GADGET_ID_ELEMENT_CONTENT_6 (GADGET_ID_DRAWING_AREA_FIRST + 7)
-#define GADGET_ID_ELEMENT_CONTENT_7 (GADGET_ID_DRAWING_AREA_FIRST + 8)
-#define GADGET_ID_AMOEBA_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 9)
-#define GADGET_ID_CUSTOM_GRAPHIC (GADGET_ID_DRAWING_AREA_FIRST + 10)
-#define GADGET_ID_CUSTOM_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 11)
-#define GADGET_ID_CUSTOM_MOVE_ENTER (GADGET_ID_DRAWING_AREA_FIRST + 12)
-#define GADGET_ID_CUSTOM_MOVE_LEAVE (GADGET_ID_DRAWING_AREA_FIRST + 13)
-#define GADGET_ID_CUSTOM_CHANGE_TARGET (GADGET_ID_DRAWING_AREA_FIRST + 14)
-#define GADGET_ID_CUSTOM_CHANGE_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 15)
-#define GADGET_ID_CUSTOM_CHANGE_TRIGGER (GADGET_ID_DRAWING_AREA_FIRST + 16)
-#define GADGET_ID_GROUP_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 17)
-#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 18)
+#define GADGET_ID_YAMYAM_CONTENT_0 (GADGET_ID_DRAWING_AREA_FIRST + 1)
+#define GADGET_ID_YAMYAM_CONTENT_1 (GADGET_ID_DRAWING_AREA_FIRST + 2)
+#define GADGET_ID_YAMYAM_CONTENT_2 (GADGET_ID_DRAWING_AREA_FIRST + 3)
+#define GADGET_ID_YAMYAM_CONTENT_3 (GADGET_ID_DRAWING_AREA_FIRST + 4)
+#define GADGET_ID_YAMYAM_CONTENT_4 (GADGET_ID_DRAWING_AREA_FIRST + 5)
+#define GADGET_ID_YAMYAM_CONTENT_5 (GADGET_ID_DRAWING_AREA_FIRST + 6)
+#define GADGET_ID_YAMYAM_CONTENT_6 (GADGET_ID_DRAWING_AREA_FIRST + 7)
+#define GADGET_ID_YAMYAM_CONTENT_7 (GADGET_ID_DRAWING_AREA_FIRST + 8)
+#define GADGET_ID_MAGIC_BALL_CONTENT_0 (GADGET_ID_DRAWING_AREA_FIRST + 9)
+#define GADGET_ID_MAGIC_BALL_CONTENT_1 (GADGET_ID_DRAWING_AREA_FIRST + 10)
+#define GADGET_ID_MAGIC_BALL_CONTENT_2 (GADGET_ID_DRAWING_AREA_FIRST + 11)
+#define GADGET_ID_MAGIC_BALL_CONTENT_3 (GADGET_ID_DRAWING_AREA_FIRST + 12)
+#define GADGET_ID_MAGIC_BALL_CONTENT_4 (GADGET_ID_DRAWING_AREA_FIRST + 13)
+#define GADGET_ID_MAGIC_BALL_CONTENT_5 (GADGET_ID_DRAWING_AREA_FIRST + 14)
+#define GADGET_ID_MAGIC_BALL_CONTENT_6 (GADGET_ID_DRAWING_AREA_FIRST + 15)
+#define GADGET_ID_MAGIC_BALL_CONTENT_7 (GADGET_ID_DRAWING_AREA_FIRST + 16)
+#define GADGET_ID_AMOEBA_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 17)
+#define GADGET_ID_CUSTOM_GRAPHIC (GADGET_ID_DRAWING_AREA_FIRST + 18)
+#define GADGET_ID_CUSTOM_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 19)
+#define GADGET_ID_CUSTOM_MOVE_ENTER (GADGET_ID_DRAWING_AREA_FIRST + 20)
+#define GADGET_ID_CUSTOM_MOVE_LEAVE (GADGET_ID_DRAWING_AREA_FIRST + 21)
+#define GADGET_ID_CUSTOM_CHANGE_TARGET (GADGET_ID_DRAWING_AREA_FIRST + 22)
+#define GADGET_ID_CUSTOM_CHANGE_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 23)
+#define GADGET_ID_CUSTOM_CHANGE_TRIGGER (GADGET_ID_DRAWING_AREA_FIRST + 24)
+#define GADGET_ID_GROUP_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 25)
+#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 26)
/* text input identifiers */
-#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 19)
+#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 27)
#define GADGET_ID_LEVEL_NAME (GADGET_ID_TEXT_INPUT_FIRST + 0)
#define GADGET_ID_LEVEL_AUTHOR (GADGET_ID_TEXT_INPUT_FIRST + 1)
#define GADGET_ID_SELECTBOX_FIRST (GADGET_ID_TEXT_AREA_FIRST + 1)
#define GADGET_ID_TIME_OR_STEPS (GADGET_ID_SELECTBOX_FIRST + 0)
-#define GADGET_ID_CUSTOM_WALK_TO_ACTION (GADGET_ID_SELECTBOX_FIRST + 1)
-#define GADGET_ID_CUSTOM_EXPLOSION_TYPE (GADGET_ID_SELECTBOX_FIRST + 2)
-#define GADGET_ID_CUSTOM_DEADLINESS (GADGET_ID_SELECTBOX_FIRST + 3)
-#define GADGET_ID_CUSTOM_MOVE_PATTERN (GADGET_ID_SELECTBOX_FIRST + 4)
-#define GADGET_ID_CUSTOM_MOVE_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 5)
-#define GADGET_ID_CUSTOM_MOVE_STEPSIZE (GADGET_ID_SELECTBOX_FIRST + 6)
-#define GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE (GADGET_ID_SELECTBOX_FIRST + 7)
-#define GADGET_ID_CUSTOM_SMASH_TARGETS (GADGET_ID_SELECTBOX_FIRST + 8)
-#define GADGET_ID_CUSTOM_SLIPPERY_TYPE (GADGET_ID_SELECTBOX_FIRST + 9)
-#define GADGET_ID_CUSTOM_ACCESS_TYPE (GADGET_ID_SELECTBOX_FIRST + 10)
-#define GADGET_ID_CUSTOM_ACCESS_LAYER (GADGET_ID_SELECTBOX_FIRST + 11)
-#define GADGET_ID_CUSTOM_ACCESS_PROTECTED (GADGET_ID_SELECTBOX_FIRST + 12)
-#define GADGET_ID_CUSTOM_ACCESS_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 13)
-#define GADGET_ID_CHANGE_TIME_UNITS (GADGET_ID_SELECTBOX_FIRST + 14)
-#define GADGET_ID_CHANGE_DIRECT_ACTION (GADGET_ID_SELECTBOX_FIRST + 15)
-#define GADGET_ID_CHANGE_OTHER_ACTION (GADGET_ID_SELECTBOX_FIRST + 16)
-#define GADGET_ID_CHANGE_SIDE (GADGET_ID_SELECTBOX_FIRST + 17)
-#define GADGET_ID_CHANGE_PLAYER (GADGET_ID_SELECTBOX_FIRST + 18)
-#define GADGET_ID_CHANGE_PAGE (GADGET_ID_SELECTBOX_FIRST + 19)
-#define GADGET_ID_CHANGE_REPLACE_WHEN (GADGET_ID_SELECTBOX_FIRST + 20)
-#define GADGET_ID_SELECT_CHANGE_PAGE (GADGET_ID_SELECTBOX_FIRST + 21)
-#define GADGET_ID_GROUP_CHOICE_MODE (GADGET_ID_SELECTBOX_FIRST + 22)
+#define GADGET_ID_GAME_ENGINE_TYPE (GADGET_ID_SELECTBOX_FIRST + 1)
+#define GADGET_ID_CUSTOM_WALK_TO_ACTION (GADGET_ID_SELECTBOX_FIRST + 2)
+#define GADGET_ID_CUSTOM_EXPLOSION_TYPE (GADGET_ID_SELECTBOX_FIRST + 3)
+#define GADGET_ID_CUSTOM_DEADLINESS (GADGET_ID_SELECTBOX_FIRST + 4)
+#define GADGET_ID_CUSTOM_MOVE_PATTERN (GADGET_ID_SELECTBOX_FIRST + 5)
+#define GADGET_ID_CUSTOM_MOVE_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 6)
+#define GADGET_ID_CUSTOM_MOVE_STEPSIZE (GADGET_ID_SELECTBOX_FIRST + 7)
+#define GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE (GADGET_ID_SELECTBOX_FIRST + 8)
+#define GADGET_ID_CUSTOM_SMASH_TARGETS (GADGET_ID_SELECTBOX_FIRST + 9)
+#define GADGET_ID_CUSTOM_SLIPPERY_TYPE (GADGET_ID_SELECTBOX_FIRST + 10)
+#define GADGET_ID_CUSTOM_ACCESS_TYPE (GADGET_ID_SELECTBOX_FIRST + 11)
+#define GADGET_ID_CUSTOM_ACCESS_LAYER (GADGET_ID_SELECTBOX_FIRST + 12)
+#define GADGET_ID_CUSTOM_ACCESS_PROTECTED (GADGET_ID_SELECTBOX_FIRST + 13)
+#define GADGET_ID_CUSTOM_ACCESS_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 14)
+#define GADGET_ID_CHANGE_TIME_UNITS (GADGET_ID_SELECTBOX_FIRST + 15)
+#define GADGET_ID_CHANGE_DIRECT_ACTION (GADGET_ID_SELECTBOX_FIRST + 16)
+#define GADGET_ID_CHANGE_OTHER_ACTION (GADGET_ID_SELECTBOX_FIRST + 17)
+#define GADGET_ID_CHANGE_SIDE (GADGET_ID_SELECTBOX_FIRST + 18)
+#define GADGET_ID_CHANGE_PLAYER (GADGET_ID_SELECTBOX_FIRST + 19)
+#define GADGET_ID_CHANGE_PAGE (GADGET_ID_SELECTBOX_FIRST + 20)
+#define GADGET_ID_CHANGE_REPLACE_WHEN (GADGET_ID_SELECTBOX_FIRST + 21)
+#define GADGET_ID_SELECT_CHANGE_PAGE (GADGET_ID_SELECTBOX_FIRST + 22)
+#define GADGET_ID_GROUP_CHOICE_MODE (GADGET_ID_SELECTBOX_FIRST + 23)
/* textbutton identifiers */
-#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 23)
+#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 24)
#define GADGET_ID_PROPERTIES_INFO (GADGET_ID_TEXTBUTTON_FIRST + 0)
#define GADGET_ID_PROPERTIES_CONFIG (GADGET_ID_TEXTBUTTON_FIRST + 1)
#define GADGET_ID_RANDOM_PERCENTAGE (GADGET_ID_CHECKBUTTON_FIRST + 0)
#define GADGET_ID_RANDOM_QUANTITY (GADGET_ID_CHECKBUTTON_FIRST + 1)
#define GADGET_ID_RANDOM_RESTRICTED (GADGET_ID_CHECKBUTTON_FIRST + 2)
-#define GADGET_ID_DOUBLE_SPEED (GADGET_ID_CHECKBUTTON_FIRST + 3)
-#define GADGET_ID_GRAVITY (GADGET_ID_CHECKBUTTON_FIRST + 4)
-#define GADGET_ID_STICK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 5)
-#define GADGET_ID_EM_SLIPPERY_GEMS (GADGET_ID_CHECKBUTTON_FIRST + 6)
-#define GADGET_ID_USE_SPRING_BUG (GADGET_ID_CHECKBUTTON_FIRST + 7)
-#define GADGET_ID_GROW_INTO_DIGGABLE (GADGET_ID_CHECKBUTTON_FIRST + 8)
+#define GADGET_ID_INITIAL_GRAVITY (GADGET_ID_CHECKBUTTON_FIRST + 3)
+#define GADGET_ID_STICK_ELEMENT (GADGET_ID_CHECKBUTTON_FIRST + 4)
+#define GADGET_ID_EM_SLIPPERY_GEMS (GADGET_ID_CHECKBUTTON_FIRST + 5)
+#define GADGET_ID_USE_SPRING_BUG (GADGET_ID_CHECKBUTTON_FIRST + 6)
+#define GADGET_ID_GROW_INTO_DIGGABLE (GADGET_ID_CHECKBUTTON_FIRST + 7)
+#define GADGET_ID_DOUBLE_SPEED (GADGET_ID_CHECKBUTTON_FIRST + 8)
#define GADGET_ID_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 9)
#define GADGET_ID_SP_BLOCK_LAST_FIELD (GADGET_ID_CHECKBUTTON_FIRST + 10)
#define GADGET_ID_INSTANT_RELOCATION (GADGET_ID_CHECKBUTTON_FIRST + 11)
#define ED_COUNTER_ID_LEVEL_TIMELIMIT 4
#define ED_COUNTER_ID_LEVEL_TIMESCORE 5
#define ED_COUNTER_ID_LEVEL_RANDOM 6
-#define ED_COUNTER_ID_ELEMENT_SCORE 7
-#define ED_COUNTER_ID_ELEMENT_CONTENT 8
-#define ED_COUNTER_ID_ENVELOPE_XSIZE 9
-#define ED_COUNTER_ID_ENVELOPE_YSIZE 10
-#define ED_COUNTER_ID_CUSTOM_SCORE 11
-#define ED_COUNTER_ID_CUSTOM_GEMCOUNT 12
-#define ED_COUNTER_ID_PUSH_DELAY_FIX 13
-#define ED_COUNTER_ID_PUSH_DELAY_RND 14
-#define ED_COUNTER_ID_DROP_DELAY_FIX 15
-#define ED_COUNTER_ID_DROP_DELAY_RND 16
-#define ED_COUNTER_ID_MOVE_DELAY_FIX 17
-#define ED_COUNTER_ID_MOVE_DELAY_RND 18
-#define ED_COUNTER_ID_EXPLOSION_DELAY 19
-#define ED_COUNTER_ID_IGNITION_DELAY 20
-#define ED_COUNTER_ID_GROUP_CONTENT 21
-#define ED_COUNTER_ID_CHANGE_DELAY_FIX 22
-#define ED_COUNTER_ID_CHANGE_DELAY_RND 23
-#define ED_COUNTER_ID_CHANGE_CONT_RND 24
-
-#define ED_NUM_COUNTERBUTTONS 25
+#define ED_COUNTER_ID_ELEMENT_VALUE1 7
+#define ED_COUNTER_ID_ELEMENT_VALUE2 8
+#define ED_COUNTER_ID_YAMYAM_CONTENT 9
+#define ED_COUNTER_ID_ENVELOPE_XSIZE 10
+#define ED_COUNTER_ID_ENVELOPE_YSIZE 11
+#define ED_COUNTER_ID_CUSTOM_SCORE 12
+#define ED_COUNTER_ID_CUSTOM_GEMCOUNT 13
+#define ED_COUNTER_ID_PUSH_DELAY_FIX 14
+#define ED_COUNTER_ID_PUSH_DELAY_RND 15
+#define ED_COUNTER_ID_DROP_DELAY_FIX 16
+#define ED_COUNTER_ID_DROP_DELAY_RND 17
+#define ED_COUNTER_ID_MOVE_DELAY_FIX 18
+#define ED_COUNTER_ID_MOVE_DELAY_RND 19
+#define ED_COUNTER_ID_EXPLOSION_DELAY 20
+#define ED_COUNTER_ID_IGNITION_DELAY 21
+#define ED_COUNTER_ID_GROUP_CONTENT 22
+#define ED_COUNTER_ID_CHANGE_DELAY_FIX 23
+#define ED_COUNTER_ID_CHANGE_DELAY_RND 24
+#define ED_COUNTER_ID_CHANGE_CONT_RND 25
+
+#define ED_NUM_COUNTERBUTTONS 26
#define ED_COUNTER_ID_LEVEL_FIRST ED_COUNTER_ID_LEVEL_XSIZE
#define ED_COUNTER_ID_LEVEL_LAST ED_COUNTER_ID_LEVEL_RANDOM
/* values for selectbox gadgets */
#define ED_SELECTBOX_ID_TIME_OR_STEPS 0
-#define ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE 1
-#define ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER 2
-#define ED_SELECTBOX_ID_CUSTOM_ACCESS_PROTECTED 3
-#define ED_SELECTBOX_ID_CUSTOM_ACCESS_DIRECTION 4
-#define ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION 5
-#define ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN 6
-#define ED_SELECTBOX_ID_CUSTOM_MOVE_DIRECTION 7
-#define ED_SELECTBOX_ID_CUSTOM_MOVE_STEPSIZE 8
-#define ED_SELECTBOX_ID_CUSTOM_MOVE_LEAVE_TYPE 9
-#define ED_SELECTBOX_ID_CUSTOM_SMASH_TARGETS 10
-#define ED_SELECTBOX_ID_CUSTOM_SLIPPERY_TYPE 11
-#define ED_SELECTBOX_ID_CUSTOM_DEADLINESS 12
-#define ED_SELECTBOX_ID_CUSTOM_EXPLOSION_TYPE 13
-#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS 14
-#define ED_SELECTBOX_ID_CHANGE_DIRECT_ACTION 15
-#define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION 16
-#define ED_SELECTBOX_ID_CHANGE_SIDE 17
-#define ED_SELECTBOX_ID_CHANGE_PLAYER 18
-#define ED_SELECTBOX_ID_CHANGE_PAGE 19
-#define ED_SELECTBOX_ID_CHANGE_REPLACE_WHEN 20
-#define ED_SELECTBOX_ID_SELECT_CHANGE_PAGE 21
-#define ED_SELECTBOX_ID_GROUP_CHOICE_MODE 22
-
-#define ED_NUM_SELECTBOX 23
+#define ED_SELECTBOX_ID_GAME_ENGINE_TYPE 1
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE 2
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER 3
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_PROTECTED 4
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_DIRECTION 5
+#define ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION 6
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN 7
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_DIRECTION 8
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_STEPSIZE 9
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_LEAVE_TYPE 10
+#define ED_SELECTBOX_ID_CUSTOM_SMASH_TARGETS 11
+#define ED_SELECTBOX_ID_CUSTOM_SLIPPERY_TYPE 12
+#define ED_SELECTBOX_ID_CUSTOM_DEADLINESS 13
+#define ED_SELECTBOX_ID_CUSTOM_EXPLOSION_TYPE 14
+#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS 15
+#define ED_SELECTBOX_ID_CHANGE_DIRECT_ACTION 16
+#define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION 17
+#define ED_SELECTBOX_ID_CHANGE_SIDE 18
+#define ED_SELECTBOX_ID_CHANGE_PLAYER 19
+#define ED_SELECTBOX_ID_CHANGE_PAGE 20
+#define ED_SELECTBOX_ID_CHANGE_REPLACE_WHEN 21
+#define ED_SELECTBOX_ID_SELECT_CHANGE_PAGE 22
+#define ED_SELECTBOX_ID_GROUP_CHOICE_MODE 23
+
+#define ED_NUM_SELECTBOX 24
#define ED_SELECTBOX_ID_LEVEL_FIRST ED_SELECTBOX_ID_TIME_OR_STEPS
-#define ED_SELECTBOX_ID_LEVEL_LAST ED_SELECTBOX_ID_TIME_OR_STEPS
+#define ED_SELECTBOX_ID_LEVEL_LAST ED_SELECTBOX_ID_GAME_ENGINE_TYPE
#define ED_SELECTBOX_ID_CUSTOM1_FIRST ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE
#define ED_SELECTBOX_ID_CUSTOM1_LAST ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION
#define ED_GRAPHICBUTTON_ID_CHANGE_LAST ED_GRAPHICBUTTON_ID_PASTE_CHANGE_PAGE
/* values for checkbutton gadgets */
-#define ED_CHECKBUTTON_ID_DOUBLE_SPEED 0
-#define ED_CHECKBUTTON_ID_GRAVITY 1
-#define ED_CHECKBUTTON_ID_RANDOM_RESTRICTED 2
-#define ED_CHECKBUTTON_ID_STICK_ELEMENT 3
-#define ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS 4
-#define ED_CHECKBUTTON_ID_USE_SPRING_BUG 5
-#define ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE 6
+#define ED_CHECKBUTTON_ID_INITIAL_GRAVITY 0
+#define ED_CHECKBUTTON_ID_RANDOM_RESTRICTED 1
+#define ED_CHECKBUTTON_ID_STICK_ELEMENT 2
+#define ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS 3
+#define ED_CHECKBUTTON_ID_USE_SPRING_BUG 4
+#define ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE 5
+#define ED_CHECKBUTTON_ID_DOUBLE_SPEED 6
#define ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD 7
#define ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD 8
#define ED_CHECKBUTTON_ID_INSTANT_RELOCATION 9
#define ED_NUM_CHECKBUTTONS 37
-#define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_DOUBLE_SPEED
+#define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_INITIAL_GRAVITY
#define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED
#define ED_CHECKBUTTON_ID_CUSTOM1_FIRST ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC
/* values for drawing area gadgets */
#define ED_DRAWING_ID_DRAWING_LEVEL 0
-#define ED_DRAWING_ID_ELEMENT_CONTENT_0 1
-#define ED_DRAWING_ID_ELEMENT_CONTENT_1 2
-#define ED_DRAWING_ID_ELEMENT_CONTENT_2 3
-#define ED_DRAWING_ID_ELEMENT_CONTENT_3 4
-#define ED_DRAWING_ID_ELEMENT_CONTENT_4 5
-#define ED_DRAWING_ID_ELEMENT_CONTENT_5 6
-#define ED_DRAWING_ID_ELEMENT_CONTENT_6 7
-#define ED_DRAWING_ID_ELEMENT_CONTENT_7 8
-#define ED_DRAWING_ID_AMOEBA_CONTENT 9
-#define ED_DRAWING_ID_CUSTOM_GRAPHIC 10
-#define ED_DRAWING_ID_CUSTOM_CONTENT 11
-#define ED_DRAWING_ID_CUSTOM_MOVE_ENTER 12
-#define ED_DRAWING_ID_CUSTOM_MOVE_LEAVE 13
-#define ED_DRAWING_ID_CUSTOM_CHANGE_TARGET 14
-#define ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT 15
-#define ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER 16
-#define ED_DRAWING_ID_GROUP_CONTENT 17
-#define ED_DRAWING_ID_RANDOM_BACKGROUND 18
-
-#define ED_NUM_DRAWING_AREAS 19
+#define ED_DRAWING_ID_YAMYAM_CONTENT_0 1
+#define ED_DRAWING_ID_YAMYAM_CONTENT_1 2
+#define ED_DRAWING_ID_YAMYAM_CONTENT_2 3
+#define ED_DRAWING_ID_YAMYAM_CONTENT_3 4
+#define ED_DRAWING_ID_YAMYAM_CONTENT_4 5
+#define ED_DRAWING_ID_YAMYAM_CONTENT_5 6
+#define ED_DRAWING_ID_YAMYAM_CONTENT_6 7
+#define ED_DRAWING_ID_YAMYAM_CONTENT_7 8
+#define ED_DRAWING_ID_MAGIC_BALL_CONTENT_0 9
+#define ED_DRAWING_ID_MAGIC_BALL_CONTENT_1 10
+#define ED_DRAWING_ID_MAGIC_BALL_CONTENT_2 11
+#define ED_DRAWING_ID_MAGIC_BALL_CONTENT_3 12
+#define ED_DRAWING_ID_MAGIC_BALL_CONTENT_4 13
+#define ED_DRAWING_ID_MAGIC_BALL_CONTENT_5 14
+#define ED_DRAWING_ID_MAGIC_BALL_CONTENT_6 15
+#define ED_DRAWING_ID_MAGIC_BALL_CONTENT_7 16
+#define ED_DRAWING_ID_AMOEBA_CONTENT 17
+#define ED_DRAWING_ID_CUSTOM_GRAPHIC 18
+#define ED_DRAWING_ID_CUSTOM_CONTENT 19
+#define ED_DRAWING_ID_CUSTOM_MOVE_ENTER 20
+#define ED_DRAWING_ID_CUSTOM_MOVE_LEAVE 21
+#define ED_DRAWING_ID_CUSTOM_CHANGE_TARGET 22
+#define ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT 23
+#define ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER 24
+#define ED_DRAWING_ID_GROUP_CONTENT 25
+#define ED_DRAWING_ID_RANDOM_BACKGROUND 26
+
+#define ED_NUM_DRAWING_AREAS 27
/*
char *text;
} control_info[ED_NUM_CTRL_BUTTONS] =
{
+ /* note: some additional characters are already reserved for "cheat mode"
+ shortcuts (":XYZ" style) -- for details, see "events.c" */
+
{ 's', "draw single items" },
{ 'd', "draw connected items" },
{ 'l', "draw lines" },
char *text_above, *text_left, *text_right;
} counterbutton_info[ED_NUM_COUNTERBUTTONS] =
{
- /* ---------- level and editor settings ---------------------------------- */
+ /* ---------- current level number --------------------------------------- */
{
DX + 5 - SX, DY + 3 - SY,
&level_nr,
NULL, NULL, NULL
},
+
+ /* ---------- level and editor settings ---------------------------------- */
+
{
- ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(2),
+ ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(4),
MIN_LEV_FIELDX, MAX_LEV_FIELDX,
GADGET_ID_LEVEL_XSIZE_DOWN, GADGET_ID_LEVEL_XSIZE_UP,
GADGET_ID_LEVEL_XSIZE_TEXT, GADGET_ID_NONE,
"playfield size:", NULL, "width",
},
{
- -1, ED_COUNTER_YPOS(2),
+ -1, ED_LEVEL_SETTINGS_YPOS(4),
MIN_LEV_FIELDY, MAX_LEV_FIELDY,
GADGET_ID_LEVEL_YSIZE_DOWN, GADGET_ID_LEVEL_YSIZE_UP,
GADGET_ID_LEVEL_YSIZE_TEXT, GADGET_ID_LEVEL_XSIZE_UP,
NULL, " ", "height",
},
{
- ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(3),
+ ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(6),
0, 999,
GADGET_ID_LEVEL_GEMSLIMIT_DOWN, GADGET_ID_LEVEL_GEMSLIMIT_UP,
GADGET_ID_LEVEL_GEMSLIMIT_TEXT, GADGET_ID_NONE,
&level.gems_needed,
- "number of gems to collect:", NULL, NULL
+ NULL, "number of gems to collect:", NULL
},
{
- ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(4),
+ ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(8),
0, 9999,
GADGET_ID_LEVEL_TIMELIMIT_DOWN, GADGET_ID_LEVEL_TIMELIMIT_UP,
GADGET_ID_LEVEL_TIMELIMIT_TEXT, GADGET_ID_NONE,
"time or step limit to solve level:", NULL, NULL
},
{
- ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(5),
+ ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(10),
0, 255,
GADGET_ID_LEVEL_TIMESCORE_DOWN, GADGET_ID_LEVEL_TIMESCORE_UP,
GADGET_ID_LEVEL_TIMESCORE_TEXT, GADGET_ID_NONE,
"score for each 10 sec/steps left:", NULL, NULL
},
{
- ED_SETTINGS_XPOS(0), ED_COUNTER2_YPOS(8),
+ ED_LEVEL_SETTINGS_XPOS(0), ED_COUNTER2_YPOS(8),
1, 100,
GADGET_ID_LEVEL_RANDOM_DOWN, GADGET_ID_LEVEL_RANDOM_UP,
GADGET_ID_LEVEL_RANDOM_TEXT, GADGET_ID_NONE,
/* ---------- element settings: configure (various elements) ------------- */
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(0),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0),
+ MIN_SCORE, MAX_SCORE,
+ GADGET_ID_ELEMENT_VALUE1_DOWN, GADGET_ID_ELEMENT_VALUE1_UP,
+ GADGET_ID_ELEMENT_VALUE1_TEXT, GADGET_ID_NONE,
+ NULL, /* will be set when used */
+ NULL, NULL, NULL
+ },
+ {
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
MIN_SCORE, MAX_SCORE,
- GADGET_ID_ELEMENT_SCORE_DOWN, GADGET_ID_ELEMENT_SCORE_UP,
- GADGET_ID_ELEMENT_SCORE_TEXT, GADGET_ID_NONE,
+ GADGET_ID_ELEMENT_VALUE2_DOWN, GADGET_ID_ELEMENT_VALUE2_UP,
+ GADGET_ID_ELEMENT_VALUE2_TEXT, GADGET_ID_NONE,
NULL, /* will be set when used */
NULL, NULL, NULL
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(3),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3),
MIN_ELEMENT_CONTENTS, MAX_ELEMENT_CONTENTS,
- GADGET_ID_ELEMENT_CONTENT_DOWN, GADGET_ID_ELEMENT_CONTENT_UP,
- GADGET_ID_ELEMENT_CONTENT_TEXT, GADGET_ID_NONE,
+ GADGET_ID_YAMYAM_CONTENT_DOWN, GADGET_ID_YAMYAM_CONTENT_UP,
+ GADGET_ID_YAMYAM_CONTENT_TEXT, GADGET_ID_NONE,
&level.num_yamyam_contents,
NULL, NULL, "number of content areas"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(0),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0),
MIN_ENVELOPE_XSIZE, MAX_ENVELOPE_XSIZE,
GADGET_ID_ENVELOPE_XSIZE_DOWN, GADGET_ID_ENVELOPE_XSIZE_UP,
GADGET_ID_ENVELOPE_XSIZE_TEXT, GADGET_ID_NONE,
NULL, NULL, "width",
},
{
- -1, ED_SETTINGS_YPOS(0),
+ -1, ED_ELEMENT_SETTINGS_YPOS(0),
MIN_ENVELOPE_YSIZE, MAX_ENVELOPE_YSIZE,
GADGET_ID_ENVELOPE_YSIZE_DOWN, GADGET_ID_ENVELOPE_YSIZE_UP,
GADGET_ID_ENVELOPE_YSIZE_TEXT, GADGET_ID_ENVELOPE_XSIZE_UP,
/* ---------- element settings: configure 1 (custom elements) ------------ */
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(6),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(6),
MIN_SCORE, MAX_SCORE,
GADGET_ID_CUSTOM_SCORE_DOWN, GADGET_ID_CUSTOM_SCORE_UP,
GADGET_ID_CUSTOM_SCORE_TEXT, GADGET_ID_NONE,
NULL, "score", " "
},
{
- -1, ED_SETTINGS_YPOS(6),
+ -1, ED_ELEMENT_SETTINGS_YPOS(6),
MIN_COLLECT_COUNT, MAX_COLLECT_COUNT,
GADGET_ID_CUSTOM_GEMCOUNT_DOWN, GADGET_ID_CUSTOM_GEMCOUNT_UP,
GADGET_ID_CUSTOM_GEMCOUNT_TEXT, GADGET_ID_CUSTOM_SCORE_UP,
NULL, "count", NULL
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(7),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(7),
0, 255,
GADGET_ID_PUSH_DELAY_FIX_DOWN, GADGET_ID_PUSH_DELAY_FIX_UP,
GADGET_ID_PUSH_DELAY_FIX_TEXT, GADGET_ID_NONE,
NULL, "push delay", NULL
},
{
- -1, ED_SETTINGS_YPOS(7),
+ -1, ED_ELEMENT_SETTINGS_YPOS(7),
0, 255,
GADGET_ID_PUSH_DELAY_RND_DOWN, GADGET_ID_PUSH_DELAY_RND_UP,
GADGET_ID_PUSH_DELAY_RND_TEXT, GADGET_ID_PUSH_DELAY_FIX_UP,
NULL, "+random", NULL
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(8),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(8),
0, 255,
GADGET_ID_DROP_DELAY_FIX_DOWN, GADGET_ID_DROP_DELAY_FIX_UP,
GADGET_ID_DROP_DELAY_FIX_TEXT, GADGET_ID_NONE,
NULL, "drop delay", NULL
},
{
- -1, ED_SETTINGS_YPOS(8),
+ -1, ED_ELEMENT_SETTINGS_YPOS(8),
0, 255,
GADGET_ID_DROP_DELAY_RND_DOWN, GADGET_ID_DROP_DELAY_RND_UP,
GADGET_ID_DROP_DELAY_RND_TEXT, GADGET_ID_DROP_DELAY_FIX_UP,
/* ---------- element settings: configure 2 (custom elements) ------------ */
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(5),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(5),
0, 999,
GADGET_ID_MOVE_DELAY_FIX_DOWN, GADGET_ID_MOVE_DELAY_FIX_UP,
GADGET_ID_MOVE_DELAY_FIX_TEXT, GADGET_ID_NONE,
NULL, "move delay", NULL
},
{
- -1, ED_SETTINGS_YPOS(5),
+ -1, ED_ELEMENT_SETTINGS_YPOS(5),
0, 999,
GADGET_ID_MOVE_DELAY_RND_DOWN, GADGET_ID_MOVE_DELAY_RND_UP,
GADGET_ID_MOVE_DELAY_RND_TEXT, GADGET_ID_MOVE_DELAY_FIX_UP,
NULL, "+random", NULL
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(12),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(12),
0, 255,
GADGET_ID_EXPLOSION_DELAY_DOWN, GADGET_ID_EXPLOSION_DELAY_UP,
GADGET_ID_EXPLOSION_DELAY_TEXT, GADGET_ID_NONE,
NULL, "explosion delay", NULL
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(13),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(13),
0, 255,
GADGET_ID_IGNITION_DELAY_DOWN, GADGET_ID_IGNITION_DELAY_UP,
GADGET_ID_IGNITION_DELAY_TEXT, GADGET_ID_NONE,
/* ---------- element settings: configure (group elements) --------------- */
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(5),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5),
MIN_ELEMENTS_IN_GROUP, MAX_ELEMENTS_IN_GROUP,
GADGET_ID_GROUP_CONTENT_DOWN, GADGET_ID_GROUP_CONTENT_UP,
GADGET_ID_GROUP_CONTENT_TEXT, GADGET_ID_NONE,
/* ---------- element settings: advanced (custom elements) --------------- */
{
- ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(2),
+ ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(2),
0, 999,
GADGET_ID_CHANGE_DELAY_FIX_DOWN, GADGET_ID_CHANGE_DELAY_FIX_UP,
GADGET_ID_CHANGE_DELAY_FIX_TEXT, GADGET_ID_NONE,
NULL, "delay", NULL,
},
{
- -1, ED_SETTINGS_YPOS(2),
+ -1, ED_ELEMENT_SETTINGS_YPOS(2),
0, 999,
GADGET_ID_CHANGE_DELAY_RND_DOWN, GADGET_ID_CHANGE_DELAY_RND_UP,
GADGET_ID_CHANGE_DELAY_RND_TEXT, GADGET_ID_CHANGE_DELAY_FIX_UP,
NULL, "+random", NULL
},
{
- ED_SETTINGS_XPOS(3), ED_SETTINGS_YPOS(12),
+ ED_ELEMENT_SETTINGS_XPOS(3), ED_ELEMENT_SETTINGS_YPOS(12),
0, 100,
GADGET_ID_CHANGE_CONT_RND_DOWN, GADGET_ID_CHANGE_CONT_RND_UP,
GADGET_ID_CHANGE_CONT_RND_TEXT, GADGET_ID_NONE,
} textinput_info[ED_NUM_TEXTINPUT] =
{
{
- ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(0),
+ ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(0),
GADGET_ID_LEVEL_NAME,
MAX_LEVEL_NAME_LEN,
level.name,
"Title:", "Title"
},
{
- ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(1),
+ ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(2),
GADGET_ID_LEVEL_AUTHOR,
MAX_LEVEL_AUTHOR_LEN,
level.author,
} textarea_info[ED_NUM_TEXTAREAS] =
{
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(2),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2),
GADGET_ID_ENVELOPE_INFO,
MAX_ENVELOPE_XSIZE, MAX_ENVELOPE_YSIZE,
NULL,
{ -1, NULL }
};
+static struct ValueTextInfo options_game_engine_type[] =
+{
+ { GAME_ENGINE_TYPE_RND, "Rocks'n'Diamonds" },
+ { GAME_ENGINE_TYPE_EM, "Emerald Mine" },
+
+ { -1, NULL }
+};
+
static struct ValueTextInfo options_access_type[] =
{
{ EP_WALKABLE, "walkable" },
static struct ValueTextInfo options_access_direction[] =
{
+ { MV_NO_DIRECTIONS, "no direction" },
{ MV_LEFT, "left" },
{ MV_RIGHT, "right" },
{ MV_UP, "up" },
static struct ValueTextInfo options_move_stepsize[] =
{
+ { 0, "not moving" },
{ 1, "very slow" },
{ 2, "slow" },
{ 4, "normal" },
#else
{ CE_HITTING_SOMETHING, "collision" },
#endif
-#if 1
+
+#if 0
{ CE_BLOCKED, "blocked" },
#endif
+
{ CE_IMPACT, "impact (on something)" },
{ CE_SMASHED, "smashed (from above)" },
static struct ValueTextInfo options_change_other_action[] =
{
- { CE_OTHER_GETS_TOUCHED, "player touches" },
- { CE_OTHER_GETS_PRESSED, "player presses" },
- { CE_OTHER_GETS_PUSHED, "player pushes" },
- { CE_OTHER_GETS_ENTERED, "player enters" },
- { CE_OTHER_GETS_LEFT, "player leaves" },
- { CE_OTHER_GETS_DIGGED, "player digs" },
- { CE_OTHER_GETS_COLLECTED, "player collects" },
- { CE_OTHER_GETS_DROPPED, "player drops/throws" },
- { CE_OTHER_IS_TOUCHING, "touching" },
+ { CE_PLAYER_TOUCHES_X, "player touches" },
+ { CE_PLAYER_PRESSES_X, "player presses" },
+ { CE_PLAYER_PUSHES_X, "player pushes" },
+ { CE_PLAYER_ENTERS_X, "player enters" },
+ { CE_PLAYER_LEAVES_X, "player leaves" },
+ { CE_PLAYER_DIGS_X, "player digs" },
+ { CE_PLAYER_COLLECTS_X, "player collects" },
+ { CE_PLAYER_DROPS_X, "player drops/throws" },
+ { CE_TOUCHING_X, "touching" },
#if 1
- { CE_OTHER_IS_HITTING, "hitting" },
- { CE_OTHER_GETS_HIT, "hit by" },
+ { CE_HITTING_X, "hitting" },
+ { CE_HIT_BY_X, "hit by" },
#endif
- { CE_OTHER_IS_SWITCHING, "switch of" },
- { CE_OTHER_IS_CHANGING, "change by page of" },
- { CE_OTHER_IS_EXPLODING, "explosion of" },
+ { CE_SWITCH_OF_X, "switch of" },
+ { CE_CHANGE_OF_X, "change by page of" },
+ { CE_EXPLOSION_OF_X, "explosion of" },
{ -1, NULL }
};
/* ---------- level and editor settings ---------------------------------- */
{
- -1, ED_COUNTER_YPOS(4),
+ -1, ED_LEVEL_SETTINGS_YPOS(8),
GADGET_ID_TIME_OR_STEPS, GADGET_ID_LEVEL_TIMELIMIT_UP,
-1,
options_time_or_steps,
&level.use_step_counter,
NULL, "(0 => no limit)", "time or step limit"
},
+ {
+ ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(5),
+ GADGET_ID_GAME_ENGINE_TYPE, GADGET_ID_NONE,
+ -1,
+ options_game_engine_type,
+ &level.game_engine_type,
+ "game engine:", NULL, "game engine"
+ },
/* ---------- element settings: configure 1 (custom elements) ----------- */
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(3),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(3),
GADGET_ID_CUSTOM_ACCESS_TYPE, GADGET_ID_NONE,
-1,
options_access_type,
NULL, NULL, "type of access to this field"
},
{
- -1, ED_SETTINGS_YPOS(3),
+ -1, ED_ELEMENT_SETTINGS_YPOS(3),
GADGET_ID_CUSTOM_ACCESS_LAYER, GADGET_ID_CUSTOM_ACCESS_TYPE,
-1,
options_access_layer,
NULL, NULL, "layer of access for this field"
},
{
- -1, ED_SETTINGS_YPOS(3),
+ -1, ED_ELEMENT_SETTINGS_YPOS(3),
GADGET_ID_CUSTOM_ACCESS_PROTECTED, GADGET_ID_CUSTOM_ACCESS_LAYER,
-1,
options_access_protected,
NULL, NULL, "protected access for this field"
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(4),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(4),
GADGET_ID_CUSTOM_ACCESS_DIRECTION, GADGET_ID_NONE,
-1,
options_access_direction,
"from", NULL, "access direction for this field"
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(5),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(5),
GADGET_ID_CUSTOM_WALK_TO_ACTION, GADGET_ID_NONE,
-1,
options_walk_to_action,
/* ---------- element settings: configure 2 (custom elements) ----------- */
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(1),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_CUSTOM_MOVE_PATTERN, GADGET_ID_NONE,
-1,
options_move_pattern,
"can move", NULL, "element move pattern"
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(2),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(2),
GADGET_ID_CUSTOM_MOVE_DIRECTION, GADGET_ID_NONE,
-1,
options_move_direction,
"starts moving", NULL, "initial element move direction"
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(4),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(4),
GADGET_ID_CUSTOM_MOVE_STEPSIZE, GADGET_ID_NONE,
-1,
options_move_stepsize,
"move/fall speed", NULL, "speed of element movement"
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(3),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(3),
GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE, GADGET_ID_NONE,
-1,
options_move_leave_type,
"can dig: can", ":", "leave behind or change element"
},
{
- -1, ED_SETTINGS_YPOS(7),
+ -1, ED_ELEMENT_SETTINGS_YPOS(7),
GADGET_ID_CUSTOM_SMASH_TARGETS, GADGET_ID_CUSTOM_CAN_SMASH,
-1,
options_smash_targets,
"can smash", NULL, "elements that can be smashed"
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(8),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(8),
GADGET_ID_CUSTOM_SLIPPERY_TYPE, GADGET_ID_NONE,
-1,
options_slippery_type,
"slippery", NULL, "where other elements fall down"
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(9),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(9),
GADGET_ID_CUSTOM_DEADLINESS, GADGET_ID_NONE,
-1,
options_deadliness,
"deadly when", NULL, "deadliness of element"
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(10),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(10),
GADGET_ID_CUSTOM_EXPLOSION_TYPE, GADGET_ID_NONE,
-1,
options_explosion_type,
/* ---------- element settings: advanced (custom elements) --------------- */
{
- ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(3),
+ ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(3),
GADGET_ID_CHANGE_TIME_UNITS, GADGET_ID_NONE,
-1,
options_time_units,
"delay time given in", NULL, "delay time units for change"
},
{
- ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(4),
+ ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(4),
GADGET_ID_CHANGE_DIRECT_ACTION, GADGET_ID_NONE,
-1,
options_change_direct_action,
NULL, NULL, "type of direct action"
},
{
- ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(5),
+ ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(5),
GADGET_ID_CHANGE_OTHER_ACTION, GADGET_ID_NONE,
-1,
options_change_other_action,
NULL, "element:", "type of other element action"
},
{
- ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(6),
+ ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(6),
GADGET_ID_CHANGE_SIDE, GADGET_ID_NONE,
-1,
options_change_trigger_side,
"at", "side", "element side that causes change"
},
{
- ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(7),
+ ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(7),
GADGET_ID_CHANGE_PLAYER, GADGET_ID_NONE,
-1,
options_change_trigger_player,
"player:", " ", "player that causes change"
},
{
- ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(7),
+ ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(7),
GADGET_ID_CHANGE_PAGE, GADGET_ID_CHANGE_PLAYER,
-1,
options_change_trigger_page,
"page:", NULL, "change page that causes change"
},
{
- ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(10),
+ ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(10),
GADGET_ID_CHANGE_REPLACE_WHEN, GADGET_ID_NONE,
-1,
options_change_replace_when,
"replace when", NULL, "which elements can be replaced"
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(14),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(14),
GADGET_ID_SELECT_CHANGE_PAGE, GADGET_ID_NONE,
3,
options_change_page,
/* ---------- element settings: configure (group elements) --------------- */
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(6),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6),
GADGET_ID_GROUP_CHOICE_MODE, GADGET_ID_NONE,
-1,
options_group_choice_mode,
{
#if 1
{
- ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(1),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_COUNTER_YPOS(1),
GADGET_ID_PROPERTIES_INFO, GADGET_ID_NONE,
8, "Info",
NULL, NULL, "Show information about element"
},
{
- ED_SETTINGS_XPOS(0) + 124, ED_COUNTER_YPOS(1),
+ ED_ELEMENT_SETTINGS_XPOS(0) + 124, ED_COUNTER_YPOS(1),
GADGET_ID_PROPERTIES_CONFIG, GADGET_ID_NONE,
8, "Config",
NULL, NULL, "Configure element properties"
},
{
- ED_SETTINGS_XPOS(0) + 124, ED_COUNTER_YPOS(1),
+ ED_ELEMENT_SETTINGS_XPOS(0) + 124, ED_COUNTER_YPOS(1),
GADGET_ID_PROPERTIES_CONFIG_1, GADGET_ID_NONE,
8, "Config 1",
NULL, NULL, "Configure custom element properties"
},
{
- ED_SETTINGS_XPOS(0) + 248, ED_COUNTER_YPOS(1),
+ ED_ELEMENT_SETTINGS_XPOS(0) + 248, ED_COUNTER_YPOS(1),
GADGET_ID_PROPERTIES_CONFIG_2, GADGET_ID_NONE,
8, "Config 2",
NULL, NULL, "Configure custom element properties"
},
{
- ED_SETTINGS_XPOS(0) + 372, ED_COUNTER_YPOS(1),
+ ED_ELEMENT_SETTINGS_XPOS(0) + 372, ED_COUNTER_YPOS(1),
GADGET_ID_PROPERTIES_CHANGE, GADGET_ID_NONE,
8, "Change",
NULL, NULL, "Custom element change configuration"
},
#else
{
- ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(1),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_COUNTER_YPOS(1),
GADGET_ID_PROPERTIES_INFO, GADGET_ID_NONE,
11, "Information",
NULL, NULL, "Show information about element"
},
{
- ED_SETTINGS_XPOS(0) + 166, ED_COUNTER_YPOS(1),
+ ED_ELEMENT_SETTINGS_XPOS(0) + 166, ED_COUNTER_YPOS(1),
GADGET_ID_PROPERTIES_CONFIG, GADGET_ID_NONE,
11, "Configure",
NULL, NULL, "Configure element properties"
},
{
- ED_SETTINGS_XPOS(0) + 332, ED_COUNTER_YPOS(1),
+ ED_ELEMENT_SETTINGS_XPOS(0) + 332, ED_COUNTER_YPOS(1),
GADGET_ID_PROPERTIES_CHANGE, GADGET_ID_NONE,
11, "Advanced",
NULL, NULL, "Advanced element configuration"
},
#endif
{
- -1, ED_SETTINGS_YPOS(2),
+ -1, ED_ELEMENT_SETTINGS_YPOS(2),
GADGET_ID_SAVE_AS_TEMPLATE, GADGET_ID_CUSTOM_USE_TEMPLATE,
-1, "Save",
" ", "As Template", "Save current settings as new template"
},
{
- -1, ED_SETTINGS_YPOS(14),
+ -1, ED_ELEMENT_SETTINGS_YPOS(14),
GADGET_ID_ADD_CHANGE_PAGE, GADGET_ID_PASTE_CHANGE_PAGE,
-1, "New",
NULL, NULL, "Add new change page"
},
{
- -1, ED_SETTINGS_YPOS(14),
+ -1, ED_ELEMENT_SETTINGS_YPOS(14),
GADGET_ID_DEL_CHANGE_PAGE, GADGET_ID_ADD_CHANGE_PAGE,
-1, "Delete",
NULL, NULL, "Delete current change page"
{
{
ED_BUTTON_MINUS_XPOS, ED_BUTTON_COUNT_YPOS,
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(14),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(14),
ED_BUTTON_COUNT_XSIZE, ED_BUTTON_COUNT_YSIZE,
GADGET_ID_PREV_CHANGE_PAGE, GADGET_ID_NONE,
NULL, NULL, "select previous change page"
},
{
ED_BUTTON_PLUS_XPOS, ED_BUTTON_COUNT_YPOS,
- -1, ED_SETTINGS_YPOS(14),
+ -1, ED_ELEMENT_SETTINGS_YPOS(14),
ED_BUTTON_COUNT_XSIZE, ED_BUTTON_COUNT_YSIZE,
GADGET_ID_NEXT_CHANGE_PAGE, GADGET_ID_SELECT_CHANGE_PAGE,
NULL, "change page", "select next change page"
},
{
ED_COPY_CHANGE_PAGE_XPOS, ED_COPY_CHANGE_PAGE_YPOS,
- -1, ED_SETTINGS_YPOS(14),
+ -1, ED_ELEMENT_SETTINGS_YPOS(14),
ED_BUTTON_COUNT_XSIZE, ED_BUTTON_COUNT_YSIZE,
GADGET_ID_COPY_CHANGE_PAGE, GADGET_ID_NEXT_CHANGE_PAGE,
" ", NULL, "copy settings from this change page"
},
{
ED_PASTE_CHANGE_PAGE_XPOS, ED_PASTE_CHANGE_PAGE_YPOS,
- -1, ED_SETTINGS_YPOS(14),
+ -1, ED_ELEMENT_SETTINGS_YPOS(14),
ED_BUTTON_COUNT_XSIZE, ED_BUTTON_COUNT_YSIZE,
GADGET_ID_PASTE_CHANGE_PAGE, GADGET_ID_COPY_CHANGE_PAGE,
NULL, NULL, "paste settings to this change page"
/* ---------- level and editor settings ---------------------------------- */
{
- ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(6) - MINI_TILEY,
- GADGET_ID_DOUBLE_SPEED, GADGET_ID_NONE,
- &level.double_speed,
- NULL, "double speed movement", "set movement speed of player"
- },
- {
- -1, ED_COUNTER_YPOS(6) - MINI_TILEY,
- GADGET_ID_GRAVITY, GADGET_ID_DOUBLE_SPEED,
+ ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(11),
+ GADGET_ID_INITIAL_GRAVITY, GADGET_ID_NONE,
&level.initial_gravity,
- " ", "gravity", "set level gravity"
+ NULL,
+ "initial gravity", "set initial level gravity"
},
{
- ED_SETTINGS_XPOS(0), ED_COUNTER2_YPOS(9) - MINI_TILEY,
+ ED_LEVEL_SETTINGS_XPOS(0), ED_COUNTER2_YPOS(9) - MINI_TILEY,
GADGET_ID_RANDOM_RESTRICTED, GADGET_ID_NONE,
&random_placement_background_restricted,
NULL,
/* ---------- element settings: configure (various elements) ------------- */
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(0),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0),
GADGET_ID_STICK_ELEMENT, GADGET_ID_NONE,
&stick_element_properties_window,
NULL,
"stick this screen to edit content","stick this screen to edit content"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(1),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_EM_SLIPPERY_GEMS, GADGET_ID_NONE,
&level.em_slippery_gems,
NULL,
"slip down from certain flat walls","use EM style slipping behaviour"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(1),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_USE_SPRING_BUG, GADGET_ID_NONE,
&level.use_spring_bug,
NULL,
"use spring pushing bug", "use odd spring pushing behaviour"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(0),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0),
GADGET_ID_GROW_INTO_DIGGABLE, GADGET_ID_NONE,
&level.grow_into_diggable,
NULL,
"can grow into anything diggable", "grow into more than just sand"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(1),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4),
+ GADGET_ID_DOUBLE_SPEED, GADGET_ID_NONE,
+ &level.double_speed,
+ NULL,
+ "double speed movement", "set initial movement speed of player"
+ },
+ {
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_BLOCK_LAST_FIELD, GADGET_ID_NONE,
&level.block_last_field,
NULL,
"block last field when moving", "player blocks last field when moving"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(1),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_SP_BLOCK_LAST_FIELD, GADGET_ID_NONE,
&level.sp_block_last_field,
NULL,
"block last field when moving", "player blocks last field when moving"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(2),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2),
GADGET_ID_INSTANT_RELOCATION, GADGET_ID_NONE,
&level.instant_relocation,
NULL,
"no scrolling when relocating", "player gets relocated without delay"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(3),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3),
GADGET_ID_CAN_PASS_TO_WALKABLE, GADGET_ID_NONE,
&level.can_pass_to_walkable,
NULL,
"can pass to walkable element", "player can pass to empty or walkable"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(0),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0),
GADGET_ID_CAN_FALL_INTO_ACID, GADGET_ID_NONE,
&custom_element_properties[EP_CAN_MOVE_INTO_ACID],
NULL,
"can fall into acid (with gravity)","player can fall into acid pool"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(0),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0),
GADGET_ID_CAN_MOVE_INTO_ACID, GADGET_ID_NONE,
&custom_element_properties[EP_CAN_MOVE_INTO_ACID],
NULL,
"can move into acid", "element can move into acid pool"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(1),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_DONT_COLLIDE_WITH, GADGET_ID_NONE,
&custom_element_properties[EP_DONT_COLLIDE_WITH],
NULL,
/* ---------- element settings: configure 1 (custom elements) ----------- */
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(1),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_CUSTOM_USE_GRAPHIC, GADGET_ID_NONE,
&custom_element.use_gfx_element,
+
+ /* !!! add separate "use existing element sound" !!! */
#if 0
NULL, "use graphic/sound of element:", "use existing graphic and sound"
#else
#endif
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(2),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2),
GADGET_ID_CUSTOM_USE_TEMPLATE, GADGET_ID_NONE,
&level.use_custom_template,
NULL, "use template", "use template for custom properties"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(3),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3),
GADGET_ID_CUSTOM_ACCESSIBLE, GADGET_ID_NONE,
&custom_element_properties[EP_ACCESSIBLE],
NULL, NULL, "player can walk to or pass this field"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(10),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10),
GADGET_ID_CUSTOM_GRAV_REACHABLE, GADGET_ID_NONE,
&custom_element_properties[EP_GRAVITY_REACHABLE],
NULL, "reachable despite gravity", "player can walk/dig despite gravity"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(5),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5),
GADGET_ID_CUSTOM_WALK_TO_OBJECT, GADGET_ID_NONE,
&custom_element_properties[EP_WALK_TO_OBJECT],
NULL, NULL, "player can dig/collect/push element"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(9),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9),
GADGET_ID_CUSTOM_INDESTRUCTIBLE, GADGET_ID_NONE,
&custom_element_properties[EP_INDESTRUCTIBLE],
NULL, "indestructible", "element is indestructible"
/* ---------- element settings: configure 2 (custom elements) ----------- */
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(1),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_CUSTOM_CAN_MOVE, GADGET_ID_NONE,
&custom_element_properties[EP_CAN_MOVE],
NULL, NULL, "element can move with some pattern"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(7),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7),
GADGET_ID_CUSTOM_CAN_FALL, GADGET_ID_NONE,
&custom_element_properties[EP_CAN_FALL],
NULL, "can fall", "element can fall down"
},
{
- -1, ED_SETTINGS_YPOS(7),
+ -1, ED_ELEMENT_SETTINGS_YPOS(7),
GADGET_ID_CUSTOM_CAN_SMASH, GADGET_ID_CUSTOM_CAN_FALL,
&custom_element_properties[EP_CAN_SMASH],
" ", NULL, "element can smash other elements"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(8),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8),
GADGET_ID_CUSTOM_SLIPPERY, GADGET_ID_NONE,
&custom_element_properties[EP_SLIPPERY],
NULL, NULL, "other elements can fall down from it"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(9),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9),
GADGET_ID_CUSTOM_DEADLY, GADGET_ID_NONE,
&custom_element_properties[EP_DEADLY],
NULL, NULL, "element can kill the player"
},
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(10),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10),
GADGET_ID_CUSTOM_CAN_EXPLODE, GADGET_ID_NONE,
&custom_element_properties[EP_CAN_EXPLODE],
NULL, NULL, "element can explode"
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(11),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(11),
GADGET_ID_CUSTOM_EXPLODE_FIRE, GADGET_ID_NONE,
&custom_element_properties[EP_EXPLODES_BY_FIRE],
NULL, "by fire", "element can explode by fire/explosion"
},
{
- -1, ED_SETTINGS_YPOS(11),
+ -1, ED_ELEMENT_SETTINGS_YPOS(11),
GADGET_ID_CUSTOM_EXPLODE_SMASH, GADGET_ID_CUSTOM_EXPLODE_FIRE,
&custom_element_properties[EP_EXPLODES_SMASHED],
" ", "smashed", "element can explode when smashed"
},
{
- -1, ED_SETTINGS_YPOS(11),
+ -1, ED_ELEMENT_SETTINGS_YPOS(11),
GADGET_ID_CUSTOM_EXPLODE_IMPACT, GADGET_ID_CUSTOM_EXPLODE_SMASH,
&custom_element_properties[EP_EXPLODES_IMPACT],
" ", "impact", "element can explode on impact"
/* ---------- element settings: advanced (custom elements) --------------- */
{
- ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(1),
+ ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1),
GADGET_ID_CUSTOM_CAN_CHANGE, GADGET_ID_NONE,
&custom_element_change.can_change,
NULL, "element changes to:", "element can change to other element"
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(2),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(2),
GADGET_ID_CHANGE_DELAY, GADGET_ID_NONE,
&custom_element_change_events[CE_DELAY],
NULL, NULL, "element changes after delay"
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(4),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(4),
GADGET_ID_CHANGE_BY_DIRECT_ACT, GADGET_ID_NONE,
&custom_element_change_events[CE_BY_DIRECT_ACTION],
NULL, NULL, "element changes by direct action"
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(5),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(5),
GADGET_ID_CHANGE_BY_OTHER_ACT, GADGET_ID_NONE,
&custom_element_change_events[CE_BY_OTHER_ACTION],
NULL, NULL, "element changes by other element"
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(8),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(8),
GADGET_ID_CHANGE_USE_EXPLOSION, GADGET_ID_NONE,
&custom_element_change.explode,
NULL, "explode instead of change", "element explodes instead of change"
},
{
- ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(9),
+ ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(9),
GADGET_ID_CHANGE_USE_CONTENT, GADGET_ID_NONE,
&custom_element_change.use_target_content,
NULL, "use extended change target:","element changes to more elements"
},
{
- ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(11),
+ ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(11),
GADGET_ID_CHANGE_ONLY_COMPLETE, GADGET_ID_NONE,
&custom_element_change.only_if_complete,
NULL, "replace all or nothing", "only replace when all can be changed"
},
{
- ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(12),
+ ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(12),
GADGET_ID_CHANGE_USE_RANDOM, GADGET_ID_NONE,
&custom_element_change.use_random_replace,
NULL, NULL, "use percentage for random replace"
{
ED_AREA_YAMYAM_CONTENT_XPOS(0), ED_AREA_YAMYAM_CONTENT_YPOS(0),
3, 3,
- GADGET_ID_ELEMENT_CONTENT_0, GADGET_ID_NONE,
+ GADGET_ID_YAMYAM_CONTENT_0, GADGET_ID_NONE,
NULL, NULL, "1"
},
{
ED_AREA_YAMYAM_CONTENT_XPOS(1), ED_AREA_YAMYAM_CONTENT_YPOS(1),
3, 3,
- GADGET_ID_ELEMENT_CONTENT_1, GADGET_ID_NONE,
+ GADGET_ID_YAMYAM_CONTENT_1, GADGET_ID_NONE,
NULL, NULL, "2"
},
{
ED_AREA_YAMYAM_CONTENT_XPOS(2), ED_AREA_YAMYAM_CONTENT_YPOS(2),
3, 3,
- GADGET_ID_ELEMENT_CONTENT_2, GADGET_ID_NONE,
+ GADGET_ID_YAMYAM_CONTENT_2, GADGET_ID_NONE,
NULL, NULL, "3"
},
{
ED_AREA_YAMYAM_CONTENT_XPOS(3), ED_AREA_YAMYAM_CONTENT_YPOS(3),
3, 3,
- GADGET_ID_ELEMENT_CONTENT_3, GADGET_ID_NONE,
+ GADGET_ID_YAMYAM_CONTENT_3, GADGET_ID_NONE,
NULL, NULL, "4"
},
{
ED_AREA_YAMYAM_CONTENT_XPOS(4), ED_AREA_YAMYAM_CONTENT_YPOS(4),
3, 3,
- GADGET_ID_ELEMENT_CONTENT_4, GADGET_ID_NONE,
+ GADGET_ID_YAMYAM_CONTENT_4, GADGET_ID_NONE,
NULL, NULL, "5"
},
{
ED_AREA_YAMYAM_CONTENT_XPOS(5), ED_AREA_YAMYAM_CONTENT_YPOS(5),
3, 3,
- GADGET_ID_ELEMENT_CONTENT_5, GADGET_ID_NONE,
+ GADGET_ID_YAMYAM_CONTENT_5, GADGET_ID_NONE,
NULL, NULL, "6"
},
{
ED_AREA_YAMYAM_CONTENT_XPOS(6), ED_AREA_YAMYAM_CONTENT_YPOS(6),
3, 3,
- GADGET_ID_ELEMENT_CONTENT_6, GADGET_ID_NONE,
+ GADGET_ID_YAMYAM_CONTENT_6, GADGET_ID_NONE,
NULL, NULL, "7"
},
{
ED_AREA_YAMYAM_CONTENT_XPOS(7), ED_AREA_YAMYAM_CONTENT_YPOS(7),
3, 3,
- GADGET_ID_ELEMENT_CONTENT_7, GADGET_ID_NONE,
+ GADGET_ID_YAMYAM_CONTENT_7, GADGET_ID_NONE,
+ NULL, NULL, "8"
+ },
+
+ /* ---------- magic ball content ----------------------------------------- */
+
+ {
+ ED_AREA_MAGIC_BALL_CONTENT_XPOS(0), ED_AREA_MAGIC_BALL_CONTENT_YPOS(0),
+ 3, 3,
+ GADGET_ID_MAGIC_BALL_CONTENT_0, GADGET_ID_NONE,
+ NULL, NULL, "1"
+ },
+ {
+ ED_AREA_MAGIC_BALL_CONTENT_XPOS(1), ED_AREA_MAGIC_BALL_CONTENT_YPOS(1),
+ 3, 3,
+ GADGET_ID_MAGIC_BALL_CONTENT_1, GADGET_ID_NONE,
+ NULL, NULL, "2"
+ },
+ {
+ ED_AREA_MAGIC_BALL_CONTENT_XPOS(2), ED_AREA_MAGIC_BALL_CONTENT_YPOS(2),
+ 3, 3,
+ GADGET_ID_MAGIC_BALL_CONTENT_2, GADGET_ID_NONE,
+ NULL, NULL, "3"
+ },
+ {
+ ED_AREA_MAGIC_BALL_CONTENT_XPOS(3), ED_AREA_MAGIC_BALL_CONTENT_YPOS(3),
+ 3, 3,
+ GADGET_ID_MAGIC_BALL_CONTENT_3, GADGET_ID_NONE,
+ NULL, NULL, "4"
+ },
+ {
+ ED_AREA_MAGIC_BALL_CONTENT_XPOS(4), ED_AREA_MAGIC_BALL_CONTENT_YPOS(4),
+ 3, 3,
+ GADGET_ID_MAGIC_BALL_CONTENT_4, GADGET_ID_NONE,
+ NULL, NULL, "5"
+ },
+ {
+ ED_AREA_MAGIC_BALL_CONTENT_XPOS(5), ED_AREA_MAGIC_BALL_CONTENT_YPOS(5),
+ 3, 3,
+ GADGET_ID_MAGIC_BALL_CONTENT_5, GADGET_ID_NONE,
+ NULL, NULL, "6"
+ },
+ {
+ ED_AREA_MAGIC_BALL_CONTENT_XPOS(6), ED_AREA_MAGIC_BALL_CONTENT_YPOS(6),
+ 3, 3,
+ GADGET_ID_MAGIC_BALL_CONTENT_6, GADGET_ID_NONE,
+ NULL, NULL, "7"
+ },
+ {
+ ED_AREA_MAGIC_BALL_CONTENT_XPOS(7), ED_AREA_MAGIC_BALL_CONTENT_YPOS(7),
+ 3, 3,
+ GADGET_ID_MAGIC_BALL_CONTENT_7, GADGET_ID_NONE,
NULL, NULL, "8"
},
/* ---------- random background (for random painting) -------------------- */
{
- -1, ED_SETTINGS_YPOS(14),
+ -1, ED_ELEMENT_SETTINGS_YPOS(14),
1, 1,
GADGET_ID_RANDOM_BACKGROUND, GADGET_ID_RANDOM_RESTRICTED,
NULL, NULL, NULL
static int num_editor_hl_emerald_mine=SIZEOF_ARRAY_INT(editor_hl_emerald_mine);
static int num_editor_el_emerald_mine=SIZEOF_ARRAY_INT(editor_el_emerald_mine);
+static int editor_hl_emerald_mine_club[] =
+{
+ EL_CHAR('E'),
+ EL_CHAR('M'),
+ EL_CHAR('E'),
+ EL_CHAR('-'),
+
+ EL_CHAR('R'),
+ EL_CHAR('A'),
+ EL_CHAR('L'),
+ EL_CHAR('D'),
+
+ EL_CHAR('M'),
+ EL_CHAR('I'),
+ EL_CHAR('N'),
+ EL_CHAR('E'),
+
+ EL_CHAR('C'),
+ EL_CHAR('L'),
+ EL_CHAR('U'),
+ EL_CHAR('B'),
+};
+
+static int editor_el_emerald_mine_club[] =
+{
+ EL_EMC_KEY_5,
+ EL_EMC_KEY_6,
+ EL_EMC_KEY_7,
+ EL_EMC_KEY_8,
+
+ EL_EMC_GATE_5,
+ EL_EMC_GATE_6,
+ EL_EMC_GATE_7,
+ EL_EMC_GATE_8,
+
+ EL_EMC_GATE_5_GRAY,
+ EL_EMC_GATE_6_GRAY,
+ EL_EMC_GATE_7_GRAY,
+ EL_EMC_GATE_8_GRAY,
+
+ EL_EMC_STEELWALL_1,
+ EL_EMC_STEELWALL_2,
+ EL_EMC_STEELWALL_3,
+ EL_EMC_STEELWALL_4,
+
+ EL_EMC_WALL_13,
+ EL_EMC_WALL_14,
+ EL_EMC_WALL_15,
+ EL_EMC_WALL_16,
+
+ EL_EMC_WALL_SLIPPERY_1,
+ EL_EMC_WALL_SLIPPERY_2,
+ EL_EMC_WALL_SLIPPERY_3,
+ EL_EMC_WALL_SLIPPERY_4,
+
+ EL_EMC_WALL_1,
+ EL_EMC_WALL_2,
+ EL_EMC_WALL_3,
+ EL_EMC_WALL_4,
+
+ EL_EMC_WALL_5,
+ EL_EMC_WALL_6,
+ EL_EMC_WALL_7,
+ EL_EMC_WALL_8,
+
+ EL_EMC_WALL_9,
+ EL_EMC_WALL_10,
+ EL_EMC_WALL_11,
+ EL_EMC_WALL_12,
+
+#if RELEASE_311
+ EL_EMPTY,
+#else
+ EL_EMC_ANDROID,
+#endif
+ EL_BALLOON,
+ EL_BALLOON_SWITCH_ANY,
+#if RELEASE_311
+ EL_EMPTY,
+#else
+ EL_BALLOON_SWITCH_NONE,
+#endif
+
+ EL_BALLOON_SWITCH_LEFT,
+ EL_BALLOON_SWITCH_RIGHT,
+ EL_BALLOON_SWITCH_UP,
+ EL_BALLOON_SWITCH_DOWN,
+
+ EL_EMC_GRASS,
+ EL_EMC_PLANT,
+#if RELEASE_311
+ EL_EMPTY,
+ EL_EMPTY,
+#else
+ EL_EMC_LENSES,
+ EL_EMC_MAGNIFIER,
+#endif
+
+#if RELEASE_311
+ EL_EMPTY,
+ EL_EMPTY,
+#else
+ EL_EMC_MAGIC_BALL,
+ EL_EMC_MAGIC_BALL_SWITCH,
+#endif
+ EL_SPRING,
+#if RELEASE_311
+ EL_EMPTY,
+#else
+ EL_EMC_SPRING_BUMPER,
+#endif
+
+#if RELEASE_311
+ EL_EMPTY,
+#else
+ EL_EMC_DRIPPER,
+#endif
+ EL_EMC_FAKE_GRASS,
+ EL_EMPTY,
+ EL_EMPTY,
+};
+static int *editor_hl_emerald_mine_club_ptr = editor_hl_emerald_mine_club;
+static int *editor_el_emerald_mine_club_ptr = editor_el_emerald_mine_club;
+static int num_editor_hl_emerald_mine_club=SIZEOF_ARRAY_INT(editor_hl_emerald_mine_club);
+static int num_editor_el_emerald_mine_club=SIZEOF_ARRAY_INT(editor_el_emerald_mine_club);
+
static int editor_hl_more[] =
{
EL_CHAR('M'),
EL_SPACESHIP,
EL_MOLE_DOWN,
- EL_BALLOON,
- EL_BALLOON_SWITCH_ANY,
-
- EL_BALLOON_SWITCH_LEFT,
- EL_BALLOON_SWITCH_RIGHT,
- EL_BALLOON_SWITCH_UP,
- EL_BALLOON_SWITCH_DOWN,
+ EL_EMPTY,
+ EL_EMPTY,
EL_SATELLITE,
EL_EXPANDABLE_WALL_HORIZONTAL,
EL_INVISIBLE_WALL,
EL_SPEED_PILL,
EL_BLACK_ORB,
-
- EL_EMC_STEELWALL_1,
- EL_EMC_WALL_1,
- EL_EMC_WALL_2,
- EL_EMC_WALL_3,
-
- EL_EMC_WALL_4,
- EL_EMC_WALL_5,
- EL_EMC_WALL_6,
- EL_EMC_WALL_7,
};
static int *editor_hl_more_ptr = editor_hl_more;
static int *editor_el_more_ptr = editor_el_more;
static int editor_el_dx_boulderdash[] =
{
- EL_SPRING,
+ EL_EMPTY,
EL_TUBE_RIGHT_DOWN,
EL_TUBE_HORIZONTAL_DOWN,
EL_TUBE_LEFT_DOWN,
&editor_hl_emerald_mine_ptr, &num_editor_hl_emerald_mine,
&editor_el_emerald_mine_ptr, &num_editor_el_emerald_mine
},
+ {
+ &setup.editor.el_emerald_mine_club,
+ &editor_hl_emerald_mine_club_ptr, &num_editor_hl_emerald_mine_club,
+ &editor_el_emerald_mine_club_ptr, &num_editor_el_emerald_mine_club
+ },
{
&setup.editor.el_more,
&editor_hl_more_ptr, &num_editor_hl_more,
checked_free(editor_elements);
+#if 0
if (!initialized)
+#else
+ /* reload user defined element list for each invocation of level editor */
+#endif
{
/* initialize optional user defined element list */
LoadUserDefinedEditorElementList(&editor_el_user_defined_ptr,
for (x = 0; x < group_element_info.num_elements; x++)
DrawMiniGraphicExt(drawto, gi->x + x * MINI_TILEX, gi->y,
el2edimg(group_element_info.element[x]));
- else if (id >= ED_DRAWING_ID_ELEMENT_CONTENT_0 &&
- id <= ED_DRAWING_ID_ELEMENT_CONTENT_7)
+ else if (id >= ED_DRAWING_ID_YAMYAM_CONTENT_0 &&
+ id <= ED_DRAWING_ID_YAMYAM_CONTENT_7)
{
- int nr = id - ED_DRAWING_ID_ELEMENT_CONTENT_0;
+ int nr = id - ED_DRAWING_ID_YAMYAM_CONTENT_0;
for (y = 0; y < 3; y++)
for (x = 0; x < 3; x++)
gi->x + x * MINI_TILEX, gi->y + y * MINI_TILEY,
el2edimg(level.yamyam_content[nr][x][y]));
}
+ else if (id >= ED_DRAWING_ID_MAGIC_BALL_CONTENT_0 &&
+ id <= ED_DRAWING_ID_MAGIC_BALL_CONTENT_7)
+ {
+ int nr = id - ED_DRAWING_ID_MAGIC_BALL_CONTENT_0;
+
+ for (y = 0; y < 3; y++)
+ for (x = 0; x < 3; x++)
+ DrawMiniGraphicExt(drawto,
+ gi->x + x * MINI_TILEX, gi->y + y * MINI_TILEY,
+ el2edimg(level.ball_content[nr][x][y]));
+ }
}
static void ScrollMiniLevel(int from_x, int from_y, int scroll)
int y; /* set after gadget position was modified */
#endif
- /* set position for "score" counter gadget */
- if (id == ED_COUNTER_ID_ELEMENT_SCORE)
+ /* set position for "value1/value2" counter gadgets (score in most cases) */
+ if (id == ED_COUNTER_ID_ELEMENT_VALUE1 ||
+ id == ED_COUNTER_ID_ELEMENT_VALUE2)
{
ModifyGadget(gi_down, GDI_Y, SY + counterbutton_info[id].y, GDI_END);
ModifyGadget(gi_text, GDI_Y, SY + counterbutton_info[id].y, GDI_END);
undo_buffer_position = -1;
undo_buffer_steps = -1;
CopyLevelToUndoBuffer(UNDO_IMMEDIATE);
+
+ level.changed = FALSE;
}
static void DrawEditModeWindow()
static boolean LevelChanged()
{
- boolean level_changed = FALSE;
+ boolean field_changed = FALSE;
int x, y;
+ if (leveldir_current->readonly)
+ return FALSE;
+
for (y = 0; y < lev_fieldy; y++)
for (x = 0; x < lev_fieldx; x++)
if (Feld[x][y] != level.field[x][y])
- level_changed = TRUE;
+ field_changed = TRUE;
- return level_changed;
+ return (level.changed || field_changed);
}
static boolean LevelContainsPlayer()
boolean player_found = FALSE;
int x, y;
+ return TRUE; /* !!! CURRENTLY DEACTIVATED !!! */
+
for (y = 0; y < lev_fieldy; y++)
for (x = 0; x < lev_fieldx; x++)
if (Feld[x][y] == EL_PLAYER_1 ||
element_old = (IS_CUSTOM_ELEMENT(element_new) ?
EL_INTERNAL_CLIPBOARD_CUSTOM : EL_INTERNAL_CLIPBOARD_GROUP);
copy_mode = GADGET_ID_CUSTOM_COPY_TO;
+
+ level.changed = TRUE;
}
else if (IS_CUSTOM_ELEMENT(element_old) && !IS_CUSTOM_ELEMENT(element_new))
{
return FALSE;
}
+ else
+ {
+ level.changed = TRUE;
+ }
if (copy_mode == GADGET_ID_CUSTOM_COPY_FROM)
{
/* set "change by other element action" selectbox help value */
custom_element_change.other_action =
- (HAS_CHANGE_EVENT(element, CE_OTHER_GETS_TOUCHED) ? CE_OTHER_GETS_TOUCHED :
- HAS_CHANGE_EVENT(element, CE_OTHER_GETS_PRESSED) ? CE_OTHER_GETS_PRESSED :
- HAS_CHANGE_EVENT(element, CE_OTHER_GETS_PUSHED) ? CE_OTHER_GETS_PUSHED :
- HAS_CHANGE_EVENT(element, CE_OTHER_GETS_ENTERED) ? CE_OTHER_GETS_ENTERED :
- HAS_CHANGE_EVENT(element, CE_OTHER_GETS_LEFT) ? CE_OTHER_GETS_LEFT :
- HAS_CHANGE_EVENT(element, CE_OTHER_GETS_DIGGED) ? CE_OTHER_GETS_DIGGED :
- HAS_CHANGE_EVENT(element, CE_OTHER_GETS_COLLECTED) ? CE_OTHER_GETS_COLLECTED :
- HAS_CHANGE_EVENT(element, CE_OTHER_GETS_DROPPED) ? CE_OTHER_GETS_DROPPED :
- HAS_CHANGE_EVENT(element, CE_OTHER_IS_TOUCHING) ? CE_OTHER_IS_TOUCHING :
- HAS_CHANGE_EVENT(element, CE_OTHER_IS_HITTING) ? CE_OTHER_IS_HITTING :
- HAS_CHANGE_EVENT(element, CE_OTHER_GETS_HIT) ? CE_OTHER_GETS_HIT :
- HAS_CHANGE_EVENT(element, CE_OTHER_IS_SWITCHING) ? CE_OTHER_IS_SWITCHING :
- HAS_CHANGE_EVENT(element, CE_OTHER_IS_CHANGING) ? CE_OTHER_IS_CHANGING :
- HAS_CHANGE_EVENT(element, CE_OTHER_IS_EXPLODING) ? CE_OTHER_IS_EXPLODING :
+ (HAS_CHANGE_EVENT(element, CE_PLAYER_TOUCHES_X) ? CE_PLAYER_TOUCHES_X :
+ HAS_CHANGE_EVENT(element, CE_PLAYER_PRESSES_X) ? CE_PLAYER_PRESSES_X :
+ HAS_CHANGE_EVENT(element, CE_PLAYER_PUSHES_X) ? CE_PLAYER_PUSHES_X :
+ HAS_CHANGE_EVENT(element, CE_PLAYER_ENTERS_X) ? CE_PLAYER_ENTERS_X :
+ HAS_CHANGE_EVENT(element, CE_PLAYER_LEAVES_X) ? CE_PLAYER_LEAVES_X :
+ HAS_CHANGE_EVENT(element, CE_PLAYER_DIGS_X) ? CE_PLAYER_DIGS_X :
+ HAS_CHANGE_EVENT(element, CE_PLAYER_COLLECTS_X) ? CE_PLAYER_COLLECTS_X :
+ HAS_CHANGE_EVENT(element, CE_PLAYER_DROPS_X) ? CE_PLAYER_DROPS_X :
+ HAS_CHANGE_EVENT(element, CE_TOUCHING_X) ? CE_TOUCHING_X :
+ HAS_CHANGE_EVENT(element, CE_HITTING_X) ? CE_HITTING_X :
+ HAS_CHANGE_EVENT(element, CE_HIT_BY_X) ? CE_HIT_BY_X :
+ HAS_CHANGE_EVENT(element, CE_SWITCH_OF_X) ? CE_SWITCH_OF_X :
+ HAS_CHANGE_EVENT(element, CE_CHANGE_OF_X) ? CE_CHANGE_OF_X :
+ HAS_CHANGE_EVENT(element, CE_EXPLOSION_OF_X) ? CE_EXPLOSION_OF_X :
custom_element_change.other_action);
}
/* mark that this custom element has been modified */
custom_element.modified_settings = TRUE;
+ level.changed = TRUE;
if (level.use_custom_template)
{
custom_element_change_events[CE_BY_DIRECT_ACTION];
/* set other element action change event from checkbox and selectbox */
- custom_element_change_events[CE_OTHER_GETS_TOUCHED] = FALSE;
- custom_element_change_events[CE_OTHER_GETS_PRESSED] = FALSE;
- custom_element_change_events[CE_OTHER_GETS_PUSHED] = FALSE;
- custom_element_change_events[CE_OTHER_GETS_ENTERED] = FALSE;
- custom_element_change_events[CE_OTHER_GETS_LEFT] = FALSE;
- custom_element_change_events[CE_OTHER_GETS_DIGGED] = FALSE;
- custom_element_change_events[CE_OTHER_GETS_COLLECTED] = FALSE;
- custom_element_change_events[CE_OTHER_GETS_DROPPED] = FALSE;
- custom_element_change_events[CE_OTHER_IS_TOUCHING] = FALSE;
- custom_element_change_events[CE_OTHER_IS_HITTING] = FALSE;
- custom_element_change_events[CE_OTHER_GETS_HIT] = FALSE;
- custom_element_change_events[CE_OTHER_IS_SWITCHING] = FALSE;
- custom_element_change_events[CE_OTHER_IS_CHANGING] = FALSE;
- custom_element_change_events[CE_OTHER_IS_EXPLODING] = FALSE;
+ custom_element_change_events[CE_PLAYER_TOUCHES_X] = FALSE;
+ custom_element_change_events[CE_PLAYER_PRESSES_X] = FALSE;
+ custom_element_change_events[CE_PLAYER_PUSHES_X] = FALSE;
+ custom_element_change_events[CE_PLAYER_ENTERS_X] = FALSE;
+ custom_element_change_events[CE_PLAYER_LEAVES_X] = FALSE;
+ custom_element_change_events[CE_PLAYER_DIGS_X] = FALSE;
+ custom_element_change_events[CE_PLAYER_COLLECTS_X] = FALSE;
+ custom_element_change_events[CE_PLAYER_DROPS_X] = FALSE;
+ custom_element_change_events[CE_TOUCHING_X] = FALSE;
+ custom_element_change_events[CE_HITTING_X] = FALSE;
+ custom_element_change_events[CE_HIT_BY_X] = FALSE;
+ custom_element_change_events[CE_SWITCH_OF_X] = FALSE;
+ custom_element_change_events[CE_CHANGE_OF_X] = FALSE;
+ custom_element_change_events[CE_EXPLOSION_OF_X] = FALSE;
custom_element_change_events[custom_element_change.other_action] =
custom_element_change_events[CE_BY_OTHER_ACTION];
/* mark that this group element has been modified */
element_info[element].modified_settings = TRUE;
+ level.changed = TRUE;
}
static void CopyClassicElementPropertiesToGame(int element)
MapDrawingArea(id);
}
-static void DrawElementContentAreas()
+static void DrawYamYamContentAreas()
{
int x = SX + ED_AREA_YAMYAM_CONTENT_XPOS(3) + 4 * MINI_TILEX;
int y = SY + ED_AREA_YAMYAM_CONTENT_YPOS(0) + ED_BORDER_AREA_YSIZE;
int i;
/* display counter to choose number of element content areas */
- MapCounterButtons(ED_COUNTER_ID_ELEMENT_CONTENT);
+ MapCounterButtons(ED_COUNTER_ID_YAMYAM_CONTENT);
for (i = 0; i < MAX_ELEMENT_CONTENTS; i++)
{
- int id = ED_DRAWING_ID_ELEMENT_CONTENT_0 + i;
- int font_height = getFontHeight(FONT_TEXT_1);
+ int id = ED_DRAWING_ID_YAMYAM_CONTENT_0 + i;
if (i < level.num_yamyam_contents)
+ {
MapDrawingArea(id);
+ }
else
{
+ int font_height = getFontHeight(FONT_TEXT_1);
+
UnmapDrawingArea(id);
/* delete content areas in case of reducing number of them */
DrawText(x, y + 2 * MINI_TILEY, "smashed", FONT_TEXT_1);
}
+static void DrawMagicBallContentAreas()
+{
+ int x = SX + ED_AREA_MAGIC_BALL_CONTENT_XPOS(3) + 4 * MINI_TILEX;
+ int y = SY + ED_AREA_MAGIC_BALL_CONTENT_YPOS(0) + ED_BORDER_AREA_YSIZE;
+ int i;
+
+ for (i = 0; i < NUM_MAGIC_BALL_CONTENTS; i++)
+ MapDrawingArea(ED_DRAWING_ID_MAGIC_BALL_CONTENT_0 + i);
+
+ DrawText(x, y + 0 * MINI_TILEY, "generated", FONT_TEXT_1);
+ DrawText(x, y + 1 * MINI_TILEY, "when", FONT_TEXT_1);
+ DrawText(x, y + 2 * MINI_TILEY, "active", FONT_TEXT_1);
+}
+
static void DrawGroupElementArea(int element)
{
int num_elements = group_element_info.num_elements;
static boolean PrintInfoText(char *text, int font_nr, int start_line)
{
int font_height = getFontHeight(font_nr);
- int pad_x = ED_SETTINGS_XPOS(0);
- int pad_y = ED_SETTINGS_YPOS(0) + ED_BORDER_SIZE;
+ int pad_x = ED_ELEMENT_SETTINGS_XPOS(0);
+ int pad_y = ED_ELEMENT_SETTINGS_YPOS(0) + ED_BORDER_SIZE;
int sx = SX + pad_x;
int sy = SY + pad_y;
int max_lines_per_screen = (SYSIZE - pad_y) / font_height - 1;
int font_nr = FONT_TEXT_2;
int font_width = getFontWidth(font_nr);
int font_height = getFontHeight(font_nr);
- int pad_x = ED_SETTINGS_XPOS(0);
- int pad_y = ED_SETTINGS_YPOS(0) + ED_BORDER_SIZE;
+ int pad_x = ED_ELEMENT_SETTINGS_XPOS(0);
+ int pad_y = ED_ELEMENT_SETTINGS_YPOS(0) + ED_BORDER_SIZE;
int sx = SX + pad_x;
int sy = SY + pad_y + start_line * font_height;
int max_chars_per_line = (SXSIZE - 2 * pad_x) / font_width;
int font_nr = FONT_TEXT_2;
int font_width = getFontWidth(font_nr);
int font_height = getFontHeight(font_nr);
- int pad_x = ED_SETTINGS_XPOS(0);
- int pad_y = ED_SETTINGS_YPOS(0) + ED_BORDER_SIZE;
+ int pad_x = ED_ELEMENT_SETTINGS_XPOS(0);
+ int pad_y = ED_ELEMENT_SETTINGS_YPOS(0) + ED_BORDER_SIZE;
int sx = SX + pad_x;
int sy = SY + pad_y;
int max_chars_per_line = (SXSIZE - 2 * pad_x) / font_width;
int font2_nr = FONT_TEXT_2;
int font1_width = getFontWidth(font1_nr);
int font2_height = getFontHeight(font2_nr);
- int pad_x = ED_SETTINGS_XPOS(0);
- int pad_y = ED_SETTINGS_YPOS(0) + ED_BORDER_SIZE;
+ int pad_x = ED_ELEMENT_SETTINGS_XPOS(0);
+ int pad_y = ED_ELEMENT_SETTINGS_YPOS(0) + ED_BORDER_SIZE;
int screen_line = 0;
int i, x, y;
#define TEXT_COLLECTING "Score for collecting"
#define TEXT_SMASHING "Score for smashing"
+#define TEXT_SLURPING "Score for slurping"
#define TEXT_CRACKING "Score for cracking"
-#define TEXT_SPEED "Speed of amoeba growth"
+#define TEXT_AMOEBA_SPEED "Speed of amoeba growth"
#define TEXT_DURATION "Duration when activated"
+#define TEXT_BALL_DELAY "Element generation delay"
+#define TEXT_MOVE_SPEED "Speed of android moving"
+#define TEXT_CLONE_SPEED "Speed of android cloning"
static struct
{
{ EL_EM_KEY_3_FILE, &level.score[SC_KEY], TEXT_COLLECTING },
{ EL_EM_KEY_4_FILE, &level.score[SC_KEY], TEXT_COLLECTING },
#endif
- { EL_AMOEBA_WET, &level.amoeba_speed, TEXT_SPEED },
- { EL_AMOEBA_DRY, &level.amoeba_speed, TEXT_SPEED },
- { EL_AMOEBA_FULL, &level.amoeba_speed, TEXT_SPEED },
- { EL_BD_AMOEBA, &level.amoeba_speed, TEXT_SPEED },
+ { EL_EMC_KEY_5, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_EMC_KEY_6, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_EMC_KEY_7, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_EMC_KEY_8, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_AMOEBA_WET, &level.amoeba_speed, TEXT_AMOEBA_SPEED },
+ { EL_AMOEBA_DRY, &level.amoeba_speed, TEXT_AMOEBA_SPEED },
+ { EL_AMOEBA_FULL, &level.amoeba_speed, TEXT_AMOEBA_SPEED },
+ { EL_BD_AMOEBA, &level.amoeba_speed, TEXT_AMOEBA_SPEED },
{ EL_MAGIC_WALL, &level.time_magic_wall, TEXT_DURATION },
{ EL_ROBOT_WHEEL, &level.time_wheel, TEXT_DURATION },
+
+#if 1
+ { EL_EMC_ANDROID, &level.android_move_time, TEXT_MOVE_SPEED },
+ { EL_EMC_ANDROID, &level.android_clone_time, TEXT_CLONE_SPEED },
+ { EL_EMC_MAGIC_BALL, &level.ball_time, TEXT_BALL_DELAY },
+ { EL_EMC_LENSES, &level.lenses_score, TEXT_COLLECTING },
+ { EL_EMC_MAGNIFIER, &level.magnify_score, TEXT_COLLECTING },
+ { EL_ROBOT, &level.slurp_score, TEXT_SLURPING },
+ { EL_EMC_LENSES, &level.lenses_time, TEXT_DURATION },
+ { EL_EMC_MAGNIFIER, &level.magnify_time, TEXT_DURATION },
+#endif
+
{ -1, NULL, NULL }
};
static void DrawPropertiesConfig()
{
+ int max_num_element_counters = 2;
+ int num_element_counters = 0;
int i;
if (!checkPropertiesConfig(properties_element))
return;
}
- /* check if there are elements where a score can be chosen for */
+ /* check if there are elements where a value can be chosen for */
for (i = 0; elements_with_counter[i].element != -1; i++)
{
if (elements_with_counter[i].element == properties_element)
{
- int counter_id = ED_COUNTER_ID_ELEMENT_SCORE;
+ int counter_id = ED_COUNTER_ID_ELEMENT_VALUE1 + num_element_counters;
counterbutton_info[counter_id].y =
- ED_SETTINGS_YPOS((HAS_CONTENT(properties_element) ? 1 : 0) +
+ ED_ELEMENT_SETTINGS_YPOS((HAS_CONTENT(properties_element) ? 1 : 0) +
(CAN_GROW(properties_element) ? 1 : 0) +
(COULD_MOVE_INTO_ACID(properties_element) ? 1 : 0) +
- (MAYBE_DONT_COLLIDE_WITH(properties_element) ? 1 :0));
+ (MAYBE_DONT_COLLIDE_WITH(properties_element) ? 1 : 0)+
+ num_element_counters);
counterbutton_info[counter_id].value = elements_with_counter[i].value;
counterbutton_info[counter_id].text_right= elements_with_counter[i].text;
+ /* !!! CHANGE THIS FOR CERTAIN ELEMENTS !!! */
+ counterbutton_info[counter_id].min_value = MIN_SCORE;
+ counterbutton_info[counter_id].max_value = MAX_SCORE;
+
MapCounterButtons(counter_id);
- break;
+ num_element_counters++;
+ if (num_element_counters >= max_num_element_counters)
+ break;
}
}
if (IS_AMOEBOID(properties_element))
MapDrawingArea(ED_DRAWING_ID_AMOEBA_CONTENT);
- else
- DrawElementContentAreas();
+ else if (properties_element == EL_YAMYAM)
+ DrawYamYamContentAreas();
}
+ if (properties_element == EL_EMC_MAGIC_BALL)
+ DrawMagicBallContentAreas();
+
if (ELEM_IS_PLAYER(properties_element))
{
MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID);
ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD);
MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INSTANT_RELOCATION);
MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE);
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_DOUBLE_SPEED);
}
if (IS_GEM(properties_element))
{
/* set position for checkbutton for "can move into acid" */
checkbutton_info[ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID].x =
- ED_SETTINGS_XPOS(IS_CUSTOM_ELEMENT(properties_element) ? 1 : 0);
+ ED_ELEMENT_SETTINGS_XPOS(IS_CUSTOM_ELEMENT(properties_element) ? 1 : 0);
checkbutton_info[ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID].y =
- ED_SETTINGS_YPOS(IS_CUSTOM_ELEMENT(properties_element) ? 6 :
+ ED_ELEMENT_SETTINGS_YPOS(IS_CUSTOM_ELEMENT(properties_element) ? 6 :
HAS_CONTENT(properties_element) ? 1 : 0);
MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID);
if (CAN_GROW(properties_element))
{
checkbutton_info[ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE].y =
- ED_SETTINGS_YPOS(HAS_CONTENT(properties_element) ? 1 : 0);
+ ED_ELEMENT_SETTINGS_YPOS(HAS_CONTENT(properties_element) ? 1 : 0);
MapCheckbuttonGadget(ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE);
}
int font_nr = FONT_TEXT_1;
int font_width = getFontWidth(font_nr);
int font_height = getFontHeight(font_nr);
- int max_text_width = SXSIZE - x - ED_SETTINGS_XPOS(0);
+ int max_text_width = SXSIZE - x - ED_ELEMENT_SETTINGS_XPOS(0);
int max_chars_per_line = max_text_width / font_width;
char buffer[max_chars_per_line + 1];
#define CB_BRUSH_TO_LEVEL 2
#define CB_DELETE_OLD_CURSOR 3
#define CB_DUMP_BRUSH 4
+#define CB_DUMP_BRUSH_SMALL 5
static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y,
int button, int mode)
int new_element = BUTTON_ELEMENT(button);
int x, y;
- if (mode == CB_DUMP_BRUSH)
+ if (mode == CB_DUMP_BRUSH ||
+ mode == CB_DUMP_BRUSH_SMALL)
{
if (!draw_with_brush)
{
if (IS_CUSTOM_ELEMENT(element))
element_mapped = EL_CUSTOM_START;
- else if (element > EL_ENVELOPE_4)
- element_mapped = EL_CHAR_QUESTION; /* change to EL_UNKNOWN ... */
+ else if (IS_GROUP_ELEMENT(element))
+ element_mapped = EL_GROUP_START;
+ else if (element >= NUM_FILE_ELEMENTS)
+ element_mapped = EL_UNKNOWN;
- printf("`%03d", element_mapped);
+ printf("%c%03d", (mode == CB_DUMP_BRUSH ? '`' : '¸'), element_mapped);
#endif
}
CopyBrushExt(0, 0, 0, 0, 0, CB_DUMP_BRUSH);
}
+void DumpBrush_Small()
+{
+ CopyBrushExt(0, 0, 0, 0, 0, CB_DUMP_BRUSH_SMALL);
+}
+
static void FloodFill(int from_x, int from_y, int fill_element)
{
int i,x,y;
DrawLevelText(start_sx, sy + 1, 0, TEXT_SETCURSOR);
else
DrawLevelText(0, 0, 0, TEXT_END);
+
+ level.changed = TRUE;
}
break;
SetBorderElement();
if (BorderElement != last_border_element)
DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+
+ level.changed = TRUE;
}
static void RandomPlacement(int new_element)
{
static boolean free_position[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
- int num_free_positions;
- int num_percentage;
- int num_elements;
+ int num_free_positions = 0;
+ int num_percentage, num_elements;
int x, y;
- /* determine number of free positions for the new elements */
- /* (maybe this statement should be formatted a bit more readable...) */
- num_free_positions = 0;
- for (x = 0; x < lev_fieldx; x++)
- for (y = 0; y < lev_fieldy; y++)
- if ((free_position[x][y] =
- ((random_placement_background_restricted &&
- Feld[x][y] == random_placement_background_element) ||
- (!random_placement_background_restricted &&
- Feld[x][y] != new_element))) == TRUE)
- num_free_positions++;
+ /* determine number of free positions for randomly placing the new element */
+ for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++)
+ {
+ free_position[x][y] =
+ (random_placement_background_restricted ?
+ Feld[x][y] == random_placement_background_element :
+ Feld[x][y] != new_element);
+
+ if (free_position[x][y])
+ num_free_positions++;
+ }
/* determine number of new elements to place there */
num_percentage = num_free_positions * random_placement_value / 100;
num_elements = (random_placement_method == RANDOM_USE_PERCENTAGE ?
num_percentage : random_placement_value);
- /* if not more free positions than elements to place, fill whole level */
- if (num_elements >= num_free_positions)
+ /* if less free positions than elements to place, fill all these positions */
+ if (num_free_positions < num_elements)
{
for (x = 0; x < lev_fieldx; x++)
for (y = 0; y < lev_fieldy; y++)
- Feld[x][y] = new_element;
-
- DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
- CopyLevelToUndoBuffer(UNDO_IMMEDIATE);
- return;
+ if (free_position[x][y])
+ Feld[x][y] = new_element;
}
-
- while (num_elements > 0)
+ else
{
- x = RND(lev_fieldx);
- y = RND(lev_fieldy);
-
- /* don't place element at the same position twice */
- if (free_position[x][y])
+ while (num_elements > 0)
{
- free_position[x][y] = FALSE;
- Feld[x][y] = new_element;
- num_elements--;
+ x = RND(lev_fieldx);
+ y = RND(lev_fieldy);
+
+ /* don't place element at the same position twice */
+ if (free_position[x][y])
+ {
+ free_position[x][y] = FALSE;
+ Feld[x][y] = new_element;
+ num_elements--;
+ }
}
}
}
else if (id == GADGET_ID_RANDOM_BACKGROUND)
random_placement_background_element = new_element;
- else if (id >= GADGET_ID_ELEMENT_CONTENT_0 &&
- id <= GADGET_ID_ELEMENT_CONTENT_7)
- level.yamyam_content[id - GADGET_ID_ELEMENT_CONTENT_0][sx][sy] =
+ else if (id >= GADGET_ID_YAMYAM_CONTENT_0 &&
+ id <= GADGET_ID_YAMYAM_CONTENT_7)
+ level.yamyam_content[id - GADGET_ID_YAMYAM_CONTENT_0][sx][sy] =
+ new_element;
+ else if (id >= GADGET_ID_MAGIC_BALL_CONTENT_0 &&
+ id <= GADGET_ID_MAGIC_BALL_CONTENT_7)
+ level.ball_content[id - GADGET_ID_MAGIC_BALL_CONTENT_0][sx][sy] =
new_element;
}
break;
PickDrawingElement(button, group_element_info.element[sx]);
else if (id == GADGET_ID_RANDOM_BACKGROUND)
PickDrawingElement(button, random_placement_background_element);
- else if (id >= GADGET_ID_ELEMENT_CONTENT_0 &&
- id <= GADGET_ID_ELEMENT_CONTENT_7)
+ else if (id >= GADGET_ID_YAMYAM_CONTENT_0 &&
+ id <= GADGET_ID_YAMYAM_CONTENT_7)
{
- int i = id - GADGET_ID_ELEMENT_CONTENT_0;
+ int i = id - GADGET_ID_YAMYAM_CONTENT_0;
PickDrawingElement(button, level.yamyam_content[i][sx][sy]);
}
+ else if (id >= GADGET_ID_MAGIC_BALL_CONTENT_0 &&
+ id <= GADGET_ID_MAGIC_BALL_CONTENT_7)
+ {
+ int i = id - GADGET_ID_MAGIC_BALL_CONTENT_0;
+
+ PickDrawingElement(button, level.ball_content[i][sx][sy]);
+ }
break;
if ((level_changed && pressed) || (!level_changed && released))
return;
- if (level_changed && !Request("Level has changed! Discard changes ?",
+ if (level_changed && !Request("Level has changed ! Discard changes ?",
REQ_ASK))
{
if (gadget_id == counterbutton_info[counter_id].gadget_id_text)
ModifyEditorCounter(counter_id, *counter_value);
+
return;
}
}
else
ModifyEditorCounter(counter_id, *counter_value + step);
+ if (counter_id == ED_COUNTER_ID_SELECT_LEVEL)
+ {
+ LoadLevel(level_nr);
+ TapeErase();
+ ResetUndoBuffer();
+ DrawEditModeWindow();
+
+ return;
+ }
+
switch (counter_id)
{
- case ED_COUNTER_ID_ELEMENT_CONTENT:
- DrawElementContentAreas();
+ case ED_COUNTER_ID_YAMYAM_CONTENT:
+ DrawYamYamContentAreas();
break;
case ED_COUNTER_ID_GROUP_CONTENT:
lev_fieldy = level.fieldy;
break;
- case ED_COUNTER_ID_SELECT_LEVEL:
- LoadLevel(level_nr);
- TapeErase();
- ResetUndoBuffer();
- DrawEditModeWindow();
- break;
-
default:
break;
}
(counter_id >= ED_COUNTER_ID_CHANGE_FIRST &&
counter_id <= ED_COUNTER_ID_CHANGE_LAST))
CopyElementPropertiesToGame(properties_element);
+
+ level.changed = TRUE;
}
static void HandleTextInputGadgets(struct GadgetInfo *gi)
ModifyEditorElementList(); /* update changed button info text */
}
+
+ level.changed = TRUE;
}
static void HandleTextAreaGadgets(struct GadgetInfo *gi)
int type_id = gi->custom_type_id;
strcpy(textarea_info[type_id].value, gi->textarea.value);
+
+ level.changed = TRUE;
}
static void HandleSelectboxGadgets(struct GadgetInfo *gi)
(type_id >= ED_SELECTBOX_ID_CHANGE_FIRST &&
type_id <= ED_SELECTBOX_ID_CHANGE_LAST) ||
(type_id == ED_SELECTBOX_ID_GROUP_CHOICE_MODE))
+ {
CopyElementPropertiesToGame(properties_element);
+
+ level.changed = TRUE;
+ }
}
static void HandleTextbuttonGadgets(struct GadgetInfo *gi)
setElementChangeInfoToDefaults(ei->change);
DrawPropertiesWindow();
+
+ level.changed = TRUE;
}
else if (type_id == ED_TEXTBUTTON_ID_DEL_CHANGE_PAGE &&
custom_element.num_change_pages > MIN_CHANGE_PAGES)
setElementChangePages(ei, ei->num_change_pages - 1);
DrawPropertiesWindow();
+
+ level.changed = TRUE;
}
}
element_info[EL_INTERNAL_CLIPBOARD_CHANGE].change_page[0] =
ei->change_page[current_change_page];
else if (type_id == ED_GRAPHICBUTTON_ID_PASTE_CHANGE_PAGE)
+ {
ei->change_page[current_change_page] =
element_info[EL_INTERNAL_CLIPBOARD_CHANGE].change_page[0];
+ level.changed = TRUE;
+ }
+
DrawPropertiesWindow();
}
}
{
*radiobutton_info[gi->custom_type_id].value =
radiobutton_info[gi->custom_type_id].checked_value;
+
+ level.changed = TRUE;
}
static void HandleCheckbuttons(struct GadgetInfo *gi)
DrawEditModeWindow();
}
+
+ level.changed = TRUE;
}
static void HandleControlButtons(struct GadgetInfo *gi)
for (x = 0; x < MAX_LEV_FIELDX; x++)
for (y = 0; y < MAX_LEV_FIELDY; y++)
Feld[x][y] = (button == 1 ? EL_EMPTY : new_element);
+
CopyLevelToUndoBuffer(GADGET_ID_CLEAR);
DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
break;
}
- if (!LevelContainsPlayer)
+ if (!LevelContainsPlayer())
Request("No Level without Gregor Mc Duffin please !", REQ_CONFIRM);
else
{
if (new_level)
Request("Level saved !", REQ_CONFIRM);
+
+ level.changed = FALSE;
}
break;
case GADGET_ID_TEST:
- if (!LevelContainsPlayer)
+ if (!LevelContainsPlayer())
Request("No Level without Gregor Mc Duffin please !", REQ_CONFIRM);
else
{
CopyPlayfield(level.field, FieldBackup);
CopyPlayfield(Feld, level.field);
+ CopyNativeLevel_RND_to_Native(&level);
+
UnmapLevelEditorGadgets();
UndrawSpecialEditorDoor();
element = group_element_info.element[sx];
else if (id == GADGET_ID_RANDOM_BACKGROUND)
element = random_placement_background_element;
- else if (id >= GADGET_ID_ELEMENT_CONTENT_0 &&
- id <= GADGET_ID_ELEMENT_CONTENT_7)
- element = level.yamyam_content[id - GADGET_ID_ELEMENT_CONTENT_0][sx][sy];
+ else if (id >= GADGET_ID_YAMYAM_CONTENT_0 &&
+ id <= GADGET_ID_YAMYAM_CONTENT_7)
+ element = level.yamyam_content[id - GADGET_ID_YAMYAM_CONTENT_0][sx][sy];
+ else if (id >= GADGET_ID_MAGIC_BALL_CONTENT_0 &&
+ id <= GADGET_ID_MAGIC_BALL_CONTENT_7)
+ element = level.ball_content[id -GADGET_ID_MAGIC_BALL_CONTENT_0][sx][sy];
strncpy(infotext, getElementInfoText(element), max_infotext_len);
}
sprintf(infotext, "Group element position: %d", sx + 1);
else if (id == GADGET_ID_RANDOM_BACKGROUND)
strcpy(infotext, "Random placement background");
- else if (id >= GADGET_ID_ELEMENT_CONTENT_0 &&
- id <= GADGET_ID_ELEMENT_CONTENT_7)
+ else if (id >= GADGET_ID_YAMYAM_CONTENT_0 &&
+ id <= GADGET_ID_YAMYAM_CONTENT_7)
+ sprintf(infotext, "Content area %d position: %d, %d",
+ id - GADGET_ID_YAMYAM_CONTENT_0 + 1, sx, sy);
+ else if (id >= GADGET_ID_MAGIC_BALL_CONTENT_0 &&
+ id <= GADGET_ID_MAGIC_BALL_CONTENT_7)
sprintf(infotext, "Content area %d position: %d, %d",
- id - GADGET_ID_ELEMENT_CONTENT_0 + 1, sx, sy);
+ id - GADGET_ID_MAGIC_BALL_CONTENT_0 + 1, sx, sy);
}
infotext[max_infotext_len] = '\0';
{
if (!ask_if_level_has_changed ||
!LevelChanged() ||
- Request("Level has changed! Exit without saving ?",
+ Request("Level has changed ! Exit without saving ?",
REQ_ASK | REQ_STAY_OPEN))
{
#if 1
else
{
CloseDoor(DOOR_CLOSE_1);
- BlitBitmap(bitmap_db_door, bitmap_db_door,
- DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE,DYSIZE,
- DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
- OpenDoor(DOOR_OPEN_1);
+ OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
}
}
#define MAX_ELEM_X 4
#define MAX_ELEM_Y 10
-extern int element_shift;
-extern int editor_element[];
-extern int elements_in_list;
-
void CreateLevelEditorGadgets();
void FreeLevelEditorGadgets();
void UnmapLevelEditorGadgets();
void PrintEditorElementList();
void DumpBrush();
+void DumpBrush_Small();
#endif
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2004 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* engines.h *
+***********************************************************/
+
+#ifndef ENGINES_H
+#define ENGINES_H
+
+#include "libgame/libgame.h"
+
+
+/* ========================================================================= */
+/* functions and definitions exported from main program to game_em */
+/* ========================================================================= */
+
+extern void SetBitmaps_EM(Bitmap **);
+extern void UpdateEngineValues(int, int);
+extern void DrawAllGameValues(int, int, int, int, int);
+extern int getGameFrameDelay_EM(int);
+extern void PlayLevelSound_EM(int, int, int, int);
+extern void InitGraphicInfo_EM(void);
+
+#endif /* ENGINES_H */
}
/* skip mouse motion events without pressed button outside level editor */
- if (button_status == MB_RELEASED && game_status != GAME_MODE_EDITOR &&
- game_status != GAME_MODE_PLAYING)
+ if (button_status == MB_RELEASED &&
+ game_status != GAME_MODE_EDITOR && game_status != GAME_MODE_PLAYING)
return 0;
else
return 1;
}
+/* to prevent delay problems, skip mouse motion events if the very next
+ event is also a mouse motion event (and therefore effectively only
+ handling the last of a row of mouse motion events in the event queue) */
+
+boolean SkipPressedMouseMotionEvent(const Event *event)
+{
+ /* nothing to do if the current event is not a mouse motion event */
+ if (event->type != EVENT_MOTIONNOTIFY)
+ return FALSE;
+
+ /* only skip motion events with pressed button outside level editor */
+ if (button_status == MB_RELEASED ||
+ game_status == GAME_MODE_EDITOR || game_status == GAME_MODE_PLAYING)
+ return FALSE;
+
+ if (PendingEvent())
+ {
+ Event next_event;
+
+ PeekEvent(&next_event);
+
+ /* if next event is also a mouse motion event, skip the current one */
+ if (next_event.type == EVENT_MOTIONNOTIFY)
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
/* this is only really needed for non-SDL targets to filter unwanted events;
when using SDL with properly installed event filter, this function can be
replaced with a simple "NextEvent()" call, but it doesn't hurt either */
{
while (PendingEvent())
{
+ boolean handle_this_event = FALSE;
+
NextEvent(event);
if (FilterMouseMotionEvents(event))
+ handle_this_event = TRUE;
+
+#if 1
+ if (SkipPressedMouseMotionEvent(event))
+ handle_this_event = FALSE;
+#endif
+
+ if (handle_this_event)
return TRUE;
}
else
button_status = MB_RELEASED;
+#if 0
+ printf("::: button %s\n", event->type == EVENT_BUTTONPRESS ?
+ "pressed" : "released");
+#endif
+
HandleButton(event->x, event->y, button_status);
}
motion_status = TRUE;
+#if 0
+ printf("::: %d, %d\n", event->x, event->y);
+#endif
+
HandleButton(event->x, event->y, button_status);
}
Delay(100);
KeyboardAutoRepeatOffUnlessAutoplay();
}
+
if (old_joystick_status != -1)
joystick.status = old_joystick_status;
}
{
DumpBrush();
}
+ else if (is_string_suffix(cheat_input, ":DDB"))
+ {
+ DumpBrush_Small();
+ }
}
}
printf("ScrollStepSize == %d (1/1)\n", ScrollStepSize);
break;
+ case KSYM_v:
+ printf("::: currently using game engine version %d\n",
+ game.engine_version);
+ break;
+
#if 0
case KSYM_z:
#define CHUNK_SIZE_NONE -1 /* do not write chunk size */
#define FILE_VERS_CHUNK_SIZE 8 /* size of file version chunk */
#define LEVEL_HEADER_SIZE 80 /* size of level file header */
-#define LEVEL_HEADER_UNUSED 1 /* unused level header bytes */
+#define LEVEL_HEADER_UNUSED 0 /* unused level header bytes */
#define LEVEL_CHUNK_CNT2_SIZE 160 /* size of level CNT2 chunk */
#define LEVEL_CHUNK_CNT2_UNUSED 11 /* unused CNT2 chunk bytes */
#define LEVEL_CHUNK_CNT3_HEADER 16 /* size of level CNT3 header */
#define TAPE_COOKIE_TMPL "ROCKSNDIAMONDS_TAPE_FILE_VERSION_x.x"
#define SCORE_COOKIE "ROCKSNDIAMONDS_SCORE_FILE_VERSION_1.2"
-/* values for level file type identifier */
-#define LEVEL_FILE_TYPE_UNKNOWN 0
-#define LEVEL_FILE_TYPE_RND 1
-#define LEVEL_FILE_TYPE_BD 2
-#define LEVEL_FILE_TYPE_EM 3
-#define LEVEL_FILE_TYPE_SP 4
-#define LEVEL_FILE_TYPE_DX 5
-#define LEVEL_FILE_TYPE_SB 6
-#define LEVEL_FILE_TYPE_DC 7
-
-#define LEVEL_FILE_TYPE_RND_PACKED (10 + LEVEL_FILE_TYPE_RND)
-#define LEVEL_FILE_TYPE_EM_PACKED (10 + LEVEL_FILE_TYPE_EM)
-
-#define IS_SINGLE_LEVEL_FILE(x) (x < 10)
-#define IS_PACKED_LEVEL_FILE(x) (x > 10)
+static struct
+{
+ int filetype;
+ char *id;
+}
+filetype_id_list[] =
+{
+ { LEVEL_FILE_TYPE_RND, "RND" },
+ { LEVEL_FILE_TYPE_BD, "BD" },
+ { LEVEL_FILE_TYPE_EM, "EM" },
+ { LEVEL_FILE_TYPE_SP, "SP" },
+ { LEVEL_FILE_TYPE_DX, "DX" },
+ { LEVEL_FILE_TYPE_SB, "SB" },
+ { LEVEL_FILE_TYPE_DC, "DC" },
+ { -1, NULL },
+};
/* ========================================================================= */
void setElementChangeInfoToDefaults(struct ElementChangeInfo *change)
{
- int x, y;
+ int i, x, y;
change->can_change = FALSE;
- change->events = CE_BITMASK_DEFAULT;
+ for (i = 0; i < NUM_CHANGE_EVENTS; i++)
+ change->has_event[i] = FALSE;
change->trigger_player = CH_PLAYER_ANY;
change->trigger_side = CH_SIDE_ANY;
static void setLevelInfoToDefaults(struct LevelInfo *level)
{
static boolean clipboard_elements_initialized = FALSE;
-
int i, j, x, y;
+ setLevelInfoToDefaults_EM();
+
+ level->native_em_level = &native_em_level;
+
+ level->game_engine_type = GAME_ENGINE_TYPE_RND;
+
level->file_version = FILE_VERSION_ACTUAL;
level->game_version = GAME_VERSION_ACTUAL;
level->double_speed = FALSE;
level->initial_gravity = FALSE;
level->em_slippery_gems = FALSE;
- level->block_last_field = FALSE;
- level->sp_block_last_field = TRUE;
level->instant_relocation = FALSE;
level->can_pass_to_walkable = FALSE;
level->grow_into_diggable = TRUE;
+ level->block_last_field = FALSE; /* EM does not block by default */
+ level->sp_block_last_field = TRUE; /* SP blocks the last field */
+
+#if 0 /* !!! THIS IS NOT A LEVEL SETTING => LOGIC MOVED TO "game.c" !!! */
+ level->block_delay = 8; /* when blocking, block 8 frames */
+ level->sp_block_delay = 9; /* SP indeed blocks 9 frames, not 8 */
+#endif
+
level->can_move_into_acid_bits = ~0; /* everything can move into acid */
- level->dont_collide_with_bits = ~0; /* always deadly when colliding */
+ level->dont_collide_with_bits = ~0; /* always deadly when colliding */
level->use_spring_bug = FALSE;
level->use_step_counter = FALSE;
+ /* values for the new EMC elements */
+ level->android_move_time = 10;
+ level->android_clone_time = 10;
+ level->ball_random = FALSE;
+ level->ball_state_initial = FALSE;
+ level->ball_time = 10;
+ level->lenses_score = 10;
+ level->magnify_score = 10;
+ level->slurp_score = 10;
+ level->lenses_time = 10;
+ level->magnify_time = 10;
+ level->wind_direction_initial = MV_NO_MOVING;
+ for (i = 0; i < NUM_MAGIC_BALL_CONTENTS; i++)
+ for (x = 0; x < 3; x++)
+ for (y = 0; y < 3; y++)
+ level->ball_content[i][x][y] = EL_EMPTY;
+ for (i = 0; i < 16; i++)
+ level->android_array[i] = FALSE;
+
level->use_custom_template = FALSE;
for (i = 0; i < MAX_LEVEL_NAME_LEN; i++)
level->no_valid_file = FALSE;
+ level->changed = FALSE;
+
if (leveldir_current == NULL) /* only when dumping level */
return;
return LEVEL_FILE_TYPE_UNKNOWN;
}
-static char *getSingleLevelBasename(int nr, int type)
+static char *getSingleLevelBasename(int nr)
{
static char basename[MAX_FILENAME_LEN];
- char *level_filename = getStringCopy(leveldir_current->level_filename);
-
- if (level_filename == NULL)
- level_filename = getStringCat2("%03d.", LEVELFILE_EXTENSION);
- switch (type)
- {
- case LEVEL_FILE_TYPE_RND:
- if (nr < 0)
- sprintf(basename, "template.%s", LEVELFILE_EXTENSION);
- else
- sprintf(basename, "%03d.%s", nr, LEVELFILE_EXTENSION);
- break;
-
- case LEVEL_FILE_TYPE_EM:
- sprintf(basename, "%d", nr);
- break;
-
- case LEVEL_FILE_TYPE_UNKNOWN:
- default:
- sprintf(basename, level_filename, nr);
- break;
- }
-
- free(level_filename);
+ if (nr < 0)
+ sprintf(basename, "template.%s", LEVELFILE_EXTENSION);
+ else
+ sprintf(basename, "%03d.%s", nr, LEVELFILE_EXTENSION);
return basename;
}
return basename;
}
-static char *getSingleLevelFilename(int nr, int type)
+static char *getSingleLevelFilename(int nr)
{
- return getLevelFilenameFromBasename(getSingleLevelBasename(nr, type));
+ return getLevelFilenameFromBasename(getSingleLevelBasename(nr));
}
#if 0
char *getDefaultLevelFilename(int nr)
{
- return getSingleLevelFilename(nr, LEVEL_FILE_TYPE_RND);
+ return getSingleLevelFilename(nr);
}
+#if 0
static void setLevelFileInfo_SingleLevelFilename(struct LevelFileInfo *lfi,
int type)
{
lfi->basename = getSingleLevelBasename(lfi->nr, lfi->type);
lfi->filename = getLevelFilenameFromBasename(lfi->basename);
}
+#endif
+
+static void setLevelFileInfo_FormatLevelFilename(struct LevelFileInfo *lfi,
+ int type, char *format, ...)
+{
+ static char basename[MAX_FILENAME_LEN];
+ va_list ap;
+
+ va_start(ap, format);
+ vsprintf(basename, format, ap);
+ va_end(ap);
+
+ lfi->type = type;
+ lfi->packed = FALSE;
+ lfi->basename = basename;
+ lfi->filename = getLevelFilenameFromBasename(lfi->basename);
+}
static void setLevelFileInfo_PackedLevelFilename(struct LevelFileInfo *lfi,
int type)
lfi->filename = getLevelFilenameFromBasename(lfi->basename);
}
-static void determineLevelFileInfo_Filename(struct LevelFileInfo *lfi)
+static int getFiletypeFromID(char *filetype_id)
+{
+ char *filetype_id_lower;
+ int filetype = LEVEL_FILE_TYPE_UNKNOWN;
+ int i;
+
+ if (filetype_id == NULL)
+ return LEVEL_FILE_TYPE_UNKNOWN;
+
+ filetype_id_lower = getStringToLower(filetype_id);
+
+ for (i = 0; filetype_id_list[i].id != NULL; i++)
+ {
+ char *id_lower = getStringToLower(filetype_id_list[i].id);
+
+ if (strcmp(filetype_id_lower, id_lower) == 0)
+ filetype = filetype_id_list[i].filetype;
+
+ free(id_lower);
+
+ if (filetype != LEVEL_FILE_TYPE_UNKNOWN)
+ break;
+ }
+
+ free(filetype_id_lower);
+
+ return filetype;
+}
+
+#if 0
+static void OLD_determineLevelFileInfo_Filename(struct LevelFileInfo *lfi)
{
/* special case: level number is negative => check for level template file */
if (lfi->nr < 0)
if (leveldir_current->level_filename != NULL)
{
+ int filetype = getFiletypeFromID(leveldir_current->level_filetype);
+
/* check for file name/pattern specified in "levelinfo.conf" */
- setLevelFileInfo_SingleLevelFilename(lfi, LEVEL_FILE_TYPE_UNKNOWN);
+ setLevelFileInfo_SingleLevelFilename(lfi, filetype);
+
if (fileExists(lfi->filename))
return;
}
/* no known level file found -- try to use default values */
setLevelFileInfo_SingleLevelFilename(lfi, LEVEL_FILE_TYPE_UNKNOWN);
}
+#endif
+
+static void determineLevelFileInfo_Filename(struct LevelFileInfo *lfi)
+{
+ int nr = lfi->nr;
+
+ /* special case: level number is negative => check for level template file */
+ if (nr < 0)
+ {
+ setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_RND,
+ "template.%s", LEVELFILE_EXTENSION);
+
+ /* no fallback if template file not existing */
+ return;
+ }
+
+ /* special case: check for file name/pattern specified in "levelinfo.conf" */
+ if (leveldir_current->level_filename != NULL)
+ {
+ int filetype = getFiletypeFromID(leveldir_current->level_filetype);
+
+ setLevelFileInfo_FormatLevelFilename(lfi, filetype,
+ leveldir_current->level_filename, nr);
+ if (fileExists(lfi->filename))
+ return;
+ }
+
+ /* check for native Rocks'n'Diamonds level file */
+ setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_RND,
+ "%03d.%s", nr, LEVELFILE_EXTENSION);
+ if (fileExists(lfi->filename))
+ return;
+
+ /* check for Emerald Mine level file (V1) */
+ setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "a%c%c",
+ 'a' + (nr / 10) % 26, '0' + nr % 10);
+ if (fileExists(lfi->filename))
+ return;
+ setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "A%c%c",
+ 'A' + (nr / 10) % 26, '0' + nr % 10);
+ if (fileExists(lfi->filename))
+ return;
+
+ /* check for Emerald Mine level file (V2 to V5) */
+ setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "%d", nr);
+ if (fileExists(lfi->filename))
+ return;
+
+ /* check for Emerald Mine level file (V6 / single mode) */
+ setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "%02ds", nr);
+ if (fileExists(lfi->filename))
+ return;
+ setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "%02dS", nr);
+ if (fileExists(lfi->filename))
+ return;
+
+ /* check for Emerald Mine level file (V6 / teamwork mode) */
+ setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "%02dt", nr);
+ if (fileExists(lfi->filename))
+ return;
+ setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_EM, "%02dT", nr);
+ if (fileExists(lfi->filename))
+ return;
+
+ /* check for various packed level file formats */
+ setLevelFileInfo_PackedLevelFilename(lfi, LEVEL_FILE_TYPE_UNKNOWN);
+ if (fileExists(lfi->filename))
+ return;
+
+ /* no known level file found -- use default values (and fail later) */
+ setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_RND,
+ "%03d.%s", nr, LEVELFILE_EXTENSION);
+}
static void determineLevelFileInfo_Filetype(struct LevelFileInfo *lfi)
{
lfi->type = getFileTypeFromBasename(lfi->basename);
}
+#if 1
+static void setLevelFileInfo(struct LevelFileInfo *level_file_info, int nr)
+{
+ /* always start with reliable default values */
+ setFileInfoToDefaults(level_file_info);
+
+ level_file_info->nr = nr; /* set requested level number */
+
+ determineLevelFileInfo_Filename(level_file_info);
+ determineLevelFileInfo_Filetype(level_file_info);
+}
+
+#else
+
static struct LevelFileInfo *getLevelFileInfo(int nr)
{
static struct LevelFileInfo level_file_info;
return &level_file_info;
}
-
+#endif
/* ------------------------------------------------------------------------- */
/* functions for loading R'n'D level */
level->can_pass_to_walkable = (getFile8Bit(file) == 1 ? TRUE : FALSE);
level->grow_into_diggable = (getFile8Bit(file) == 1 ? TRUE : FALSE);
+ level->game_engine_type = getFile8Bit(file);
+
ReadUnusedBytesFromFile(file, LEVEL_HEADER_UNUSED);
return chunk_size;
for (i = 0; i < num_changed_custom_elements; i++)
{
int element = getFile16BitBE(file);
+ unsigned long event_bits;
if (!IS_CUSTOM_ELEMENT(element))
{
element_info[element].content[x][y] =
getMappedElement(getFile16BitBE(file));
- element_info[element].change->events = getFile32BitBE(file);
+ event_bits = getFile32BitBE(file);
+ for (j = 0; j < NUM_CHANGE_EVENTS; j++)
+ if (event_bits & (1 << j))
+ element_info[element].change->has_event[j] = TRUE;
element_info[element].change->target_element =
getMappedElement(getFile16BitBE(file));
struct ElementInfo *ei;
int chunk_size_expected;
int element;
- int i, x, y;
+ int i, j, x, y;
element = getFile16BitBE(file);
for (i = 0; i < ei->num_change_pages; i++)
{
struct ElementChangeInfo *change = &ei->change_page[i];
+ unsigned long event_bits;
/* always start with reliable default values */
setElementChangeInfoToDefaults(change);
- change->events = getFile32BitBE(file);
+ event_bits = getFile32BitBE(file);
+ for (j = 0; j < NUM_CHANGE_EVENTS; j++)
+ if (event_bits & (1 << j))
+ change->has_event[j] = TRUE;
change->target_element = getMappedElement(getFile16BitBE(file));
/* functions for loading EM level */
/* ------------------------------------------------------------------------- */
+#if 0
+
static int map_em_element_yam(int element)
{
switch (element)
#define EM_LEVEL_XSIZE 64
#define EM_LEVEL_YSIZE 32
-static void LoadLevelFromFileInfo_EM(struct LevelInfo *level,
- struct LevelFileInfo *level_file_info)
+static void OLD_LoadLevelFromFileInfo_EM(struct LevelInfo *level,
+ struct LevelFileInfo *level_file_info)
{
char *filename = level_file_info->filename;
FILE *file;
unsigned char leveldata[EM_LEVEL_SIZE];
unsigned char *header = &leveldata[EM_LEVEL_XSIZE * EM_LEVEL_YSIZE];
- unsigned char code0 = 0x65;
- unsigned char code1 = 0x11;
- boolean level_is_crypted = FALSE;
int nr = level_file_info->nr;
int i, x, y;
return;
}
- for(i = 0; i < EM_LEVEL_SIZE; i++)
+ for (i = 0; i < EM_LEVEL_SIZE; i++)
leveldata[i] = fgetc(file);
fclose(file);
if ((leveldata[0] == 0xf1 ||
leveldata[0] == 0xf5) && leveldata[2] == 0xe7 && leveldata[3] == 0xee)
{
- level_is_crypted = TRUE;
+ unsigned char code0 = 0x65;
+ unsigned char code1 = 0x11;
if (leveldata[0] == 0xf5) /* error in crypted Emerald Mine 2 levels */
leveldata[0] = 0xf1;
- }
- if (level_is_crypted) /* decode crypted level data */
- {
- for(i = 0; i < EM_LEVEL_SIZE; i++)
+ /* decode crypted level data */
+
+ for (i = 0; i < EM_LEVEL_SIZE; i++)
{
leveldata[i] ^= code0;
leveldata[i] -= code1;
- code0 = (code0 + 7) & 0xff;
+ code0 = (code0 + 7) & 0xff;
}
}
level->num_yamyam_contents = 4;
- for(i = 0; i < level->num_yamyam_contents; i++)
- for(y = 0; y < 3; y++)
- for(x = 0; x < 3; x++)
+ for (i = 0; i < level->num_yamyam_contents; i++)
+ for (y = 0; y < 3; y++)
+ for (x = 0; x < 3; x++)
level->yamyam_content[i][x][y] =
map_em_element_yam(header[i * 9 + y * 3 + x]);
level->field[x][y] = EL_PLAYER_2;
}
+#else
+
+void CopyNativeLevel_RND_to_EM(struct LevelInfo *level)
+{
+ static int ball_xy[8][2] =
+ {
+ { 0, 0 },
+ { 1, 0 },
+ { 2, 0 },
+ { 0, 1 },
+ { 2, 1 },
+ { 0, 2 },
+ { 1, 2 },
+ { 2, 2 },
+ };
+ struct LevelInfo_EM *level_em = level->native_em_level;
+ struct LEVEL *lev = level_em->lev;
+ struct PLAYER *ply1 = level_em->ply1;
+ struct PLAYER *ply2 = level_em->ply2;
+ int i, j, x, y;
+
+ lev->width = MIN(level->fieldx, EM_MAX_CAVE_WIDTH);
+ lev->height = MIN(level->fieldy, EM_MAX_CAVE_HEIGHT);
+
+ lev->time_seconds = level->time;
+ lev->required_initial = level->gems_needed;
+
+ lev->emerald_score = level->score[SC_EMERALD];
+ lev->diamond_score = level->score[SC_DIAMOND];
+ lev->alien_score = level->score[SC_ROBOT];
+ lev->tank_score = level->score[SC_SPACESHIP];
+ lev->bug_score = level->score[SC_BUG];
+ lev->eater_score = level->score[SC_YAMYAM];
+ lev->nut_score = level->score[SC_NUT];
+ lev->dynamite_score = level->score[SC_DYNAMITE];
+ lev->key_score = level->score[SC_KEY];
+ lev->exit_score = level->score[SC_TIME_BONUS];
+
+ for (i = 0; i < MAX_ELEMENT_CONTENTS; i++)
+ for (y = 0; y < 3; y++)
+ for (x = 0; x < 3; x++)
+ lev->eater_array[i][y * 3 + x] =
+ map_element_RND_to_EM(level->yamyam_content[i][x][y]);
+
+ lev->amoeba_time = level->amoeba_speed;
+ lev->wonderwall_time_initial = level->time_magic_wall;
+ lev->wheel_time = level->time_wheel;
+
+ lev->android_move_time = level->android_move_time;
+ lev->android_clone_time = level->android_clone_time;
+ lev->ball_random = level->ball_random;
+ lev->ball_state_initial = level->ball_state_initial;
+ lev->ball_time = level->ball_time;
+
+ lev->lenses_score = level->lenses_score;
+ lev->magnify_score = level->magnify_score;
+ lev->slurp_score = level->slurp_score;
+
+ lev->lenses_time = level->lenses_time;
+ lev->magnify_time = level->magnify_time;
+ lev->wind_direction_initial = level->wind_direction_initial;
+
+ for (i = 0; i < NUM_MAGIC_BALL_CONTENTS; i++)
+ for (j = 0; j < 8; j++)
+ lev->ball_array[i][j] =
+ map_element_RND_to_EM(level->
+ ball_content[i][ball_xy[j][0]][ball_xy[j][1]]);
+
+ for (i = 0; i < 16; i++)
+ lev->android_array[i] = FALSE; /* !!! YET TO COME !!! */
+
+ /* first fill the complete playfield with the default border element */
+ for (y = 0; y < EM_MAX_CAVE_HEIGHT; y++)
+ for (x = 0; x < EM_MAX_CAVE_WIDTH; x++)
+ level_em->cave[x][y] = ZBORDER;
+
+ /* then copy the real level contents from level file into the playfield */
+ for (y = 0; y < lev->height; y++) for (x = 0; x < lev->width; x++)
+ {
+ int new_element = map_element_RND_to_EM(level->field[x][y]);
+
+ if (level->field[x][y] == EL_AMOEBA_DEAD)
+ new_element = map_element_RND_to_EM(EL_AMOEBA_WET);
+
+ level_em->cave[x + 1][y + 1] = new_element;
+ }
+
+ ply1->x_initial = 0;
+ ply1->y_initial = 0;
+
+ ply2->x_initial = 0;
+ ply2->y_initial = 0;
+
+ /* initialize player positions and delete players from the playfield */
+ for (y = 0; y < lev->height; y++) for (x = 0; x < lev->width; x++)
+ {
+ if (level->field[x][y] == EL_PLAYER_1)
+ {
+ ply1->x_initial = x + 1;
+ ply1->y_initial = y + 1;
+ level_em->cave[x + 1][y + 1] = map_element_RND_to_EM(EL_EMPTY);
+ }
+ else if (level->field[x][y] == EL_PLAYER_2)
+ {
+ ply2->x_initial = x + 1;
+ ply2->y_initial = y + 1;
+ level_em->cave[x + 1][y + 1] = map_element_RND_to_EM(EL_EMPTY);
+ }
+ }
+}
+
+void CopyNativeLevel_EM_to_RND(struct LevelInfo *level)
+{
+ static int ball_xy[8][2] =
+ {
+ { 0, 0 },
+ { 1, 0 },
+ { 2, 0 },
+ { 0, 1 },
+ { 2, 1 },
+ { 0, 2 },
+ { 1, 2 },
+ { 2, 2 },
+ };
+ struct LevelInfo_EM *level_em = level->native_em_level;
+ struct LEVEL *lev = level_em->lev;
+ struct PLAYER *ply1 = level_em->ply1;
+ struct PLAYER *ply2 = level_em->ply2;
+ int i, j, x, y;
+
+ level->fieldx = MIN(lev->width, MAX_LEV_FIELDX);
+ level->fieldy = MIN(lev->height, MAX_LEV_FIELDY);
+
+ level->time = lev->time_seconds;
+ level->gems_needed = lev->required_initial;
+
+ sprintf(level->name, "Level %d", level->file_info.nr);
+
+ level->score[SC_EMERALD] = lev->emerald_score;
+ level->score[SC_DIAMOND] = lev->diamond_score;
+ level->score[SC_ROBOT] = lev->alien_score;
+ level->score[SC_SPACESHIP] = lev->tank_score;
+ level->score[SC_BUG] = lev->bug_score;
+ level->score[SC_YAMYAM] = lev->eater_score;
+ level->score[SC_NUT] = lev->nut_score;
+ level->score[SC_DYNAMITE] = lev->dynamite_score;
+ level->score[SC_KEY] = lev->key_score;
+ level->score[SC_TIME_BONUS] = lev->exit_score;
+
+ level->num_yamyam_contents = MAX_ELEMENT_CONTENTS;
+
+ for (i = 0; i < level->num_yamyam_contents; i++)
+ for (y = 0; y < 3; y++)
+ for (x = 0; x < 3; x++)
+ level->yamyam_content[i][x][y] =
+ map_element_EM_to_RND(lev->eater_array[i][y * 3 + x]);
+
+ level->amoeba_speed = lev->amoeba_time;
+ level->time_magic_wall = lev->wonderwall_time_initial;
+ level->time_wheel = lev->wheel_time;
+
+ level->android_move_time = lev->android_move_time;
+ level->android_clone_time = lev->android_clone_time;
+ level->ball_random = lev->ball_random;
+ level->ball_state_initial = lev->ball_state_initial;
+ level->ball_time = lev->ball_time;
+
+ level->lenses_score = lev->lenses_score;
+ level->magnify_score = lev->magnify_score;
+ level->slurp_score = lev->slurp_score;
+
+ level->lenses_time = lev->lenses_time;
+ level->magnify_time = lev->magnify_time;
+ level->wind_direction_initial = lev->wind_direction_initial;
+
+ for (i = 0; i < NUM_MAGIC_BALL_CONTENTS; i++)
+ for (j = 0; j < 8; j++)
+ level->ball_content[i][ball_xy[j][0]][ball_xy[j][1]] =
+ map_element_EM_to_RND(lev->ball_array[i][j]);
+
+ for (i = 0; i < 16; i++)
+ level->android_array[i] = FALSE; /* !!! YET TO COME !!! */
+
+ /* convert the playfield (some elements need special treatment) */
+ for (y = 0; y < level->fieldy; y++) for (x = 0; x < level->fieldx; x++)
+ {
+ int new_element = map_element_EM_to_RND(level_em->cave[x + 1][y + 1]);
+
+ if (new_element == EL_AMOEBA_WET && level->amoeba_speed == 0)
+ new_element = EL_AMOEBA_DEAD;
+
+ level->field[x][y] = new_element;
+ }
+
+ /* in case of both players set to the same field, use the first player */
+ level->field[ply2->x_initial - 1][ply2->y_initial - 1] = EL_PLAYER_2;
+ level->field[ply1->x_initial - 1][ply1->y_initial - 1] = EL_PLAYER_1;
+
+#if 0
+ printf("::: native Emerald Mine file version: %d\n", level_em->file_version);
+#endif
+}
+
+static void LoadLevelFromFileInfo_EM(struct LevelInfo *level,
+ struct LevelFileInfo *level_file_info)
+{
+ if (!LoadNativeLevel_EM(level_file_info->filename))
+ level->no_valid_file = TRUE;
+}
+
+#endif
+
+void CopyNativeLevel_RND_to_Native(struct LevelInfo *level)
+{
+ if (level->game_engine_type == GAME_ENGINE_TYPE_EM)
+ CopyNativeLevel_RND_to_EM(level);
+}
+
+void CopyNativeLevel_Native_to_RND(struct LevelInfo *level)
+{
+ if (level->game_engine_type == GAME_ENGINE_TYPE_EM)
+ CopyNativeLevel_EM_to_RND(level);
+}
+
+
/* ------------------------------------------------------------------------- */
/* functions for loading SP level */
/* ------------------------------------------------------------------------- */
level->time_wheel = 0;
level->amoeba_content = EL_EMPTY;
- for(i = 0; i < LEVEL_SCORE_ELEMENTS; i++)
+ for (i = 0; i < LEVEL_SCORE_ELEMENTS; i++)
level->score[i] = 0; /* !!! CORRECT THIS !!! */
/* there are no yamyams in supaplex levels */
- for(i = 0; i < level->num_yamyam_contents; i++)
- for(y = 0; y < 3; y++)
- for(x = 0; x < 3; x++)
+ for (i = 0; i < level->num_yamyam_contents; i++)
+ for (y = 0; y < 3; y++)
+ for (x = 0; x < 3; x++)
level->yamyam_content[i][x][y] = EL_EMPTY;
}
case LEVEL_FILE_TYPE_EM:
LoadLevelFromFileInfo_EM(level, level_file_info);
+ level->game_engine_type = GAME_ENGINE_TYPE_EM;
break;
case LEVEL_FILE_TYPE_SP:
LoadLevelFromFileInfo_RND(level, level_file_info);
break;
}
+
+ /* if level file is invalid, restore level structure to default values */
+ if (level->no_valid_file)
+ setLevelInfoToDefaults(level);
+
+ if (level->game_engine_type == GAME_ENGINE_TYPE_UNKNOWN)
+ level->game_engine_type = GAME_ENGINE_TYPE_RND;
+
+ if (level_file_info->type == LEVEL_FILE_TYPE_RND)
+ CopyNativeLevel_RND_to_Native(level);
+ else
+ CopyNativeLevel_Native_to_RND(level);
}
void LoadLevelFromFilename(struct LevelInfo *level, char *filename)
if (level->game_version == VERSION_IDENT(2,0,1,0))
level->em_slippery_gems = TRUE;
+ /* springs could be pushed over pits before (pre-release version) 2.2.0 */
if (level->game_version < VERSION_IDENT(2,2,0,0))
level->use_spring_bug = TRUE;
+ /* only few elements were able to actively move into acid before 3.1.0 */
+ /* trigger settings did not exist before 3.1.0; set to default "any" */
if (level->game_version < VERSION_IDENT(3,1,0,0))
{
int i, j;
+ /* correct "can move into acid" settings (all zero in old levels) */
+
level->can_move_into_acid_bits = 0; /* nothing can move into acid */
level->dont_collide_with_bits = 0; /* nothing is deadly when colliding */
for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
SET_PROPERTY(EL_CUSTOM_START + i, EP_CAN_MOVE_INTO_ACID, TRUE);
+ /* correct trigger settings (stored as zero == "none" in old levels) */
+
for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
{
int element = EL_CUSTOM_START + i;
}
}
}
+
+#if 0 /* !!! MOVED TO "game.c", BECAUSE CAN CHANGE INSIDE LEVEL EDITOR !!! */
+#if 1 /* USE_NEW_BLOCK_STYLE */
+ /* blocking the last field when moving was corrected in version 3.1.1 */
+ if (level->game_version < VERSION_IDENT(3,1,1,0))
+ {
+#if 0
+ printf("::: %d\n", level->block_last_field);
+#endif
+
+ /* even "not blocking" was blocking the last field for one frame */
+ level->block_delay = (level->block_last_field ? 7 : 1);
+ level->sp_block_delay = (level->sp_block_last_field ? 7 : 1);
+
+ level->block_last_field = TRUE;
+ level->sp_block_last_field = TRUE;
+ }
+#endif
+#endif
+
}
- else
+ else /* always use the latest game engine version */
{
#if 0
printf("\n::: ALWAYS USE LATEST ENGINE FOR THIS LEVEL: [%d] '%s'\n",
}
/* order of checking and copying events to be mapped is important */
- for (j = CE_OTHER_GETS_COLLECTED; j >= CE_HITTING_SOMETHING; j--)
+ for (j = CE_PLAYER_COLLECTS_X; j >= CE_HITTING_SOMETHING; j--)
{
if (HAS_CHANGE_EVENT(element, j - 1))
{
}
/* initialize "can_explode" field for old levels which did not store this */
+ /* !!! CHECK THIS -- "<= 3,1,0,0" IS PROBABLY WRONG !!! */
if (level->game_version <= VERSION_IDENT(3,1,0,0))
{
for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
}
}
+ /* correct previously hard-coded move delay values for maze runner style */
+ if (level->game_version < VERSION_IDENT(3,1,1,0))
+ {
+ for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
+ {
+ int element = EL_CUSTOM_START + i;
+
+ if (element_info[element].move_pattern & MV_MAZE_RUNNER_STYLE)
+ {
+ /* previously hard-coded and therefore ignored */
+ element_info[element].move_delay_fixed = 9;
+ element_info[element].move_delay_random = 0;
+ }
+ }
+ }
+
#if 0
/* set default push delay values (corrected since version 3.0.7-1) */
if (level->game_version < VERSION_IDENT(3,0,7,1))
void LoadLevelTemplate(int nr)
{
+#if 1
+ char *filename;
+
+ setLevelFileInfo(&level_template.file_info, nr);
+ filename = level_template.file_info.filename;
+
+ LoadLevelFromFileInfo(&level_template, &level_template.file_info);
+
+#else
+
#if 1
struct LevelFileInfo *level_file_info = getLevelFileInfo(nr);
char *filename = level_file_info->filename;
LoadLevelFromFilename_RND(&level_template, filename);
#endif
+#endif
+#if 1
+ LoadLevel_InitVersion(&level_template, filename);
+ LoadLevel_InitElements(&level_template, filename);
+#else
LoadLevel_InitVersion(&level, filename);
LoadLevel_InitElements(&level, filename);
+#endif
ActivateLevelTemplate();
}
void LoadLevel(int nr)
{
+#if 1
+ char *filename;
+
+ setLevelFileInfo(&level.file_info, nr);
+ filename = level.file_info.filename;
+
+ LoadLevelFromFileInfo(&level, &level.file_info);
+
+#else
+
#if 1
struct LevelFileInfo *level_file_info = getLevelFileInfo(nr);
char *filename = level_file_info->filename;
char *filename = getLevelFilename(nr);
LoadLevelFromFilename_RND(&level, filename);
+#endif
#endif
if (level.use_custom_template)
putFile8Bit(file, (level->can_pass_to_walkable ? 1 : 0));
putFile8Bit(file, (level->grow_into_diggable ? 1 : 0));
+ putFile8Bit(file, level->game_engine_type);
+
WriteUnusedBytesToFile(file, LEVEL_HEADER_UNUSED);
}
static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
{
struct ElementInfo *ei = &element_info[element];
- int i, x, y;
+ int i, j, x, y;
putFile16BitBE(file, element);
for (i = 0; i < ei->num_change_pages; i++)
{
struct ElementChangeInfo *change = &ei->change_page[i];
+ unsigned long event_bits = 0;
- putFile32BitBE(file, change->events);
+ for (j = 0; j < NUM_CHANGE_EVENTS; j++)
+ if (change->has_event[j])
+ event_bits |= (1 << j);
+
+ putFile32BitBE(file, event_bits);
putFile16BitBE(file, change->target_element);
for (i = 0; i < tape->length; i++)
{
- if (i >= MAX_TAPELEN)
+ if (i >= MAX_TAPE_LEN)
break;
for (j = 0; j < MAX_PLAYERS; j++)
InitTapeDirectory(leveldir_current->subdir);
/* if a tape still exists, ask to overwrite it */
- if (access(filename, F_OK) == 0)
+ if (fileExists(filename))
{
new_tape = FALSE;
if (!Request("Replace old tape ?", REQ_ASK))
tape.changed = FALSE;
if (new_tape)
- Request("tape saved !", REQ_CONFIRM);
+ Request("Tape saved !", REQ_CONFIRM);
}
void DumpTape(struct TapeInfo *tape)
printf_line("-", 79);
printf("Tape of Level %03d (file version %08d, game version %08d)\n",
tape->level_nr, tape->file_version, tape->game_version);
+ printf(" (effective engine version %08d)\n",
+ tape->engine_version);
printf("Level series identifier: '%s'\n", tape->level_identifier);
printf_line("-", 79);
for (i = 0; i < tape->length; i++)
{
- if (i >= MAX_TAPELEN)
+ if (i >= MAX_TAPE_LEN)
break;
printf("%03d: ", i);
#define SETUP_TOKEN_QUICK_DOORS 10
#define SETUP_TOKEN_TEAM_MODE 11
#define SETUP_TOKEN_HANDICAP 12
-#define SETUP_TOKEN_TIME_LIMIT 13
-#define SETUP_TOKEN_FULLSCREEN 14
-#define SETUP_TOKEN_ASK_ON_ESCAPE 15
-#define SETUP_TOKEN_GRAPHICS_SET 16
-#define SETUP_TOKEN_SOUNDS_SET 17
-#define SETUP_TOKEN_MUSIC_SET 18
-#define SETUP_TOKEN_OVERRIDE_LEVEL_GRAPHICS 19
-#define SETUP_TOKEN_OVERRIDE_LEVEL_SOUNDS 20
-#define SETUP_TOKEN_OVERRIDE_LEVEL_MUSIC 21
-
-#define NUM_GLOBAL_SETUP_TOKENS 22
+#define SETUP_TOKEN_SKIP_LEVELS 13
+#define SETUP_TOKEN_TIME_LIMIT 14
+#define SETUP_TOKEN_FULLSCREEN 15
+#define SETUP_TOKEN_ASK_ON_ESCAPE 16
+#define SETUP_TOKEN_GRAPHICS_SET 17
+#define SETUP_TOKEN_SOUNDS_SET 18
+#define SETUP_TOKEN_MUSIC_SET 19
+#define SETUP_TOKEN_OVERRIDE_LEVEL_GRAPHICS 20
+#define SETUP_TOKEN_OVERRIDE_LEVEL_SOUNDS 21
+#define SETUP_TOKEN_OVERRIDE_LEVEL_MUSIC 22
+
+#define NUM_GLOBAL_SETUP_TOKENS 23
/* editor setup */
#define SETUP_TOKEN_EDITOR_EL_BOULDERDASH 0
#define SETUP_TOKEN_EDITOR_EL_EMERALD_MINE 1
-#define SETUP_TOKEN_EDITOR_EL_MORE 2
-#define SETUP_TOKEN_EDITOR_EL_SOKOBAN 3
-#define SETUP_TOKEN_EDITOR_EL_SUPAPLEX 4
-#define SETUP_TOKEN_EDITOR_EL_DIAMOND_CAVES 5
-#define SETUP_TOKEN_EDITOR_EL_DX_BOULDERDASH 6
-#define SETUP_TOKEN_EDITOR_EL_CHARS 7
-#define SETUP_TOKEN_EDITOR_EL_CUSTOM 8
-#define SETUP_TOKEN_EDITOR_EL_CUSTOM_MORE 9
-#define SETUP_TOKEN_EDITOR_EL_HEADLINES 10
-#define SETUP_TOKEN_EDITOR_EL_USER_DEFINED 11
-
-#define NUM_EDITOR_SETUP_TOKENS 12
+#define SETUP_TOKEN_EDITOR_EL_EMERALD_MINE_CLUB 2
+#define SETUP_TOKEN_EDITOR_EL_MORE 3
+#define SETUP_TOKEN_EDITOR_EL_SOKOBAN 4
+#define SETUP_TOKEN_EDITOR_EL_SUPAPLEX 5
+#define SETUP_TOKEN_EDITOR_EL_DIAMOND_CAVES 6
+#define SETUP_TOKEN_EDITOR_EL_DX_BOULDERDASH 7
+#define SETUP_TOKEN_EDITOR_EL_CHARS 8
+#define SETUP_TOKEN_EDITOR_EL_CUSTOM 9
+#define SETUP_TOKEN_EDITOR_EL_CUSTOM_MORE 10
+#define SETUP_TOKEN_EDITOR_EL_HEADLINES 11
+#define SETUP_TOKEN_EDITOR_EL_USER_DEFINED 12
+
+#define NUM_EDITOR_SETUP_TOKENS 13
/* shortcut setup */
#define SETUP_TOKEN_SHORTCUT_SAVE_GAME 0
{ TYPE_SWITCH, &si.quick_doors, "quick_doors" },
{ TYPE_SWITCH, &si.team_mode, "team_mode" },
{ TYPE_SWITCH, &si.handicap, "handicap" },
+ { TYPE_SWITCH, &si.skip_levels, "skip_levels" },
{ TYPE_SWITCH, &si.time_limit, "time_limit" },
{ TYPE_SWITCH, &si.fullscreen, "fullscreen" },
{ TYPE_SWITCH, &si.ask_on_escape, "ask_on_escape" },
{
{ TYPE_SWITCH, &sei.el_boulderdash, "editor.el_boulderdash" },
{ TYPE_SWITCH, &sei.el_emerald_mine, "editor.el_emerald_mine" },
+ { TYPE_SWITCH, &sei.el_emerald_mine_club,"editor.el_emerald_mine_club"},
{ TYPE_SWITCH, &sei.el_more, "editor.el_more" },
{ TYPE_SWITCH, &sei.el_sokoban, "editor.el_sokoban" },
{ TYPE_SWITCH, &sei.el_supaplex, "editor.el_supaplex" },
si->quick_doors = FALSE;
si->team_mode = FALSE;
si->handicap = TRUE;
+ si->skip_levels = TRUE;
si->time_limit = TRUE;
si->fullscreen = FALSE;
si->ask_on_escape = TRUE;
si->override_level_sounds = FALSE;
si->override_level_music = FALSE;
- si->editor.el_boulderdash = TRUE;
- si->editor.el_emerald_mine = TRUE;
- si->editor.el_more = TRUE;
- si->editor.el_sokoban = TRUE;
- si->editor.el_supaplex = TRUE;
- si->editor.el_diamond_caves = TRUE;
- si->editor.el_dx_boulderdash = TRUE;
- si->editor.el_chars = TRUE;
- si->editor.el_custom = TRUE;
- si->editor.el_custom_more = FALSE;
+ si->editor.el_boulderdash = TRUE;
+ si->editor.el_emerald_mine = TRUE;
+ si->editor.el_emerald_mine_club = TRUE;
+ si->editor.el_more = TRUE;
+ si->editor.el_sokoban = TRUE;
+ si->editor.el_supaplex = TRUE;
+ si->editor.el_diamond_caves = TRUE;
+ si->editor.el_dx_boulderdash = TRUE;
+ si->editor.el_chars = TRUE;
+ si->editor.el_custom = TRUE;
+ si->editor.el_custom_more = FALSE;
si->editor.el_headlines = TRUE;
si->editor.el_user_defined = FALSE;
{
char *value = getHashEntry(element_hash, list->token);
- if (value)
+ if (value == NULL) /* try to find obsolete token mapping */
+ {
+ char *mapped_token = get_mapped_token(list->token);
+
+ if (mapped_token != NULL)
+ {
+ value = getHashEntry(element_hash, mapped_token);
+
+ free(mapped_token);
+ }
+ }
+
+ if (value != NULL)
{
(*elements)[(*num_elements)++] = atoi(value);
}
#include "main.h"
+
+#define LEVEL_PACKED_START 100
+#define PACKED_LEVELS(x) (LEVEL_PACKED_START + x)
+
+#define LEVEL_FILE_TYPE_RND_PACKED PACKED_LEVELS(LEVEL_FILE_TYPE_RND)
+#define LEVEL_FILE_TYPE_EM_PACKED PACKED_LEVELS(LEVEL_FILE_TYPE_EM)
+
+#define IS_SINGLE_LEVEL_FILE(x) (x < LEVEL_PACKED_START)
+#define IS_PACKED_LEVEL_FILE(x) (x > LEVEL_PACKED_START)
+
+
void setElementChangePages(struct ElementInfo *, int);
void setElementChangeInfoToDefaults(struct ElementChangeInfo *);
void SaveLevelTemplate();
void DumpLevel(struct LevelInfo *);
+void CopyNativeLevel_RND_to_Native(struct LevelInfo *);
+void CopyNativeLevel_Native_to_RND(struct LevelInfo *);
+
void LoadTapeFromFilename(char *);
void LoadTape(int);
void LoadSolutionTape(int);
/* EXPERIMENTAL STUFF */
#define USE_NEW_AMOEBA_CODE FALSE
+/* EXPERIMENTAL STUFF */
+#define USE_NEW_STUFF (TRUE * 1)
+
+#define USE_NEW_MOVE_STYLE (TRUE * USE_NEW_STUFF * 1)
+#define USE_NEW_MOVE_DELAY (TRUE * USE_NEW_STUFF * 1)
+#define USE_NEW_PUSH_DELAY (TRUE * USE_NEW_STUFF * 1)
+#define USE_NEW_BLOCK_STYLE (TRUE * USE_NEW_STUFF * 1)
+#define USE_NEW_SP_SLIPPERY (TRUE * USE_NEW_STUFF * 1)
+#define USE_NEW_RANDOMIZE (TRUE * USE_NEW_STUFF * 1)
+
+#define USE_CAN_MOVE_NOT_MOVING (TRUE * USE_NEW_STUFF * 1)
+#define USE_PREVIOUS_MOVE_DIR (TRUE * USE_NEW_STUFF * 1)
+
+#define USE_PUSH_BUGFIX (TRUE * USE_NEW_STUFF * 1)
+#if 0
+#define USE_BLOCK_DELAY_BUGFIX (TRUE * USE_NEW_STUFF * 1)
+#endif
+#define USE_GRAVITY_BUGFIX_NEW (TRUE * USE_NEW_STUFF * 1)
+#define USE_GRAVITY_BUGFIX_OLD (TRUE * USE_NEW_STUFF * 0)
+
+#define USE_PENGUIN_COLLECT_BUGFIX (TRUE * USE_NEW_STUFF * 1)
+
+#define USE_IMPACT_BUGFIX (TRUE * USE_NEW_STUFF * 1)
+
+#define USE_HITTING_SOMETHING_BUGFIX (TRUE * USE_NEW_STUFF * 1)
+#define USE_HIT_BY_SOMETHING_BUGFIX (TRUE * USE_NEW_STUFF * 1)
+
+#define USE_DROP_BUGFIX (TRUE * USE_NEW_STUFF * 1)
+
+#define USE_CHANGE_TO_TRIGGERED (TRUE * USE_NEW_STUFF * 1)
+
+
/* for DigField() */
#define DF_NO_PUSH 0
#define DF_DIG 1
/* forward declaration for internal use */
+static void AdvanceFrameAndPlayerCounters(int);
+
static boolean MovePlayerOneStep(struct PlayerInfo *, int, int, int, int);
static boolean MovePlayer(struct PlayerInfo *, int, int);
static void ScrollPlayer(struct PlayerInfo *, int);
{ EL_UNDEFINED, MV_NO_MOVING }
};
-static unsigned long trigger_events[MAX_NUM_ELEMENTS];
+static boolean trigger_events[MAX_NUM_ELEMENTS][NUM_CHANGE_EVENTS];
-#define IS_AUTO_CHANGING(e) (element_info[e].change_events & \
- CH_EVENT_BIT(CE_DELAY))
+#define IS_AUTO_CHANGING(e) (element_info[e].has_change_event[CE_DELAY])
#define IS_JUST_CHANGING(x, y) (ChangeDelay[x][y] != 0)
#define IS_CHANGING(x, y) (IS_AUTO_CHANGING(Feld[x][y]) || \
IS_JUST_CHANGING(x, y))
level.sp_block_last_field :
level.block_last_field);
+#if USE_NEW_BLOCK_STYLE
+#if 1
+
+ /* ---------- initialize player's last field block delay --------------- */
+
+ /* always start with reliable default value (no adjustment needed) */
+ player->block_delay_adjustment = 0;
+
+ /* special case 1: in Supaplex, Murphy blocks last field one more frame */
+ if (player->block_last_field && element == EL_SP_MURPHY)
+ player->block_delay_adjustment = 1;
+
+ /* special case 2: in game engines before 3.1.1, blocking was different */
+ if (game.use_block_last_field_bug)
+ player->block_delay_adjustment = (player->block_last_field ? -1 : 1);
+
+#if 0
+ /* blocking the last field when moving was corrected in version 3.1.1 */
+ if (game.use_block_last_field_bug)
+ {
+ /* even "not blocking" was blocking the last field for one frame */
+ level.block_delay = (level.block_last_field ? 7 : 1);
+ level.sp_block_delay = (level.sp_block_last_field ? 7 : 1);
+
+ level.block_last_field = TRUE;
+ level.sp_block_last_field = TRUE;
+ }
+#endif
+
+#if 0 /* !!! THIS IS NOT A LEVEL SETTING => REMOVED !!! */
+ level.block_delay = 8; /* when blocking, block 8 frames */
+ level.sp_block_delay = 9; /* SP indeed blocks 9 frames, not 8 */
+#endif
+
+#if 0
+ printf("::: %d, %d\n", level.block_delay, level.sp_block_delay);
+#endif
+
+#else
+
+#if 1
+ player->block_delay = (player->block_last_field ?
+ (element == EL_SP_MURPHY ?
+ level.sp_block_delay :
+ level.block_delay) : 0);
+#else
+ player->block_delay = (element == EL_SP_MURPHY ?
+ (player->block_last_field ? 7 : 1) :
+ (player->block_last_field ? 7 : 1));
+#endif
+
+#endif
+
+#if 0
+ printf("::: block_last_field == %d, block_delay = %d\n",
+ player->block_last_field, player->block_delay);
+#endif
+#endif
+
if (!options.network || player->connected)
{
player->active = TRUE;
DrawText(DX_DYNAMITE, DY_DYNAMITE, int2str(value, 3), FONT_TEXT_2);
}
-inline void DrawGameValue_Keys(struct PlayerInfo *player)
+inline void DrawGameValue_Keys(int key[MAX_NUM_KEYS])
{
int i;
- for (i = 0; i < MAX_KEYS; i++)
- if (player->key[i])
+ /* currently only 4 of 8 possible keys are displayed */
+ for (i = 0; i < STD_NUM_KEYS; i++)
+ if (key[i])
DrawMiniGraphicExt(drawto, DX_KEYS + i * MINI_TILEX, DY_KEYS,
el2edimg(EL_KEY_1 + i));
}
}
}
-void DrawGameDoorValues()
+void DrawAllGameValues(int emeralds, int dynamite, int score, int time,
+ int key_bits)
{
+ int key[MAX_NUM_KEYS];
int i;
+ for (i = 0; i < MAX_NUM_KEYS; i++)
+ key[i] = key_bits & (1 << i);
+
DrawGameValue_Level(level_nr);
- for (i = 0; i < MAX_PLAYERS; i++)
- DrawGameValue_Keys(&stored_player[i]);
+ DrawGameValue_Emeralds(emeralds);
+ DrawGameValue_Dynamite(dynamite);
+ DrawGameValue_Score(score);
+ DrawGameValue_Time(time);
+
+ DrawGameValue_Keys(key);
+}
+
+void DrawGameDoorValues()
+{
+ int i;
+
+ if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ {
+ DrawGameDoorValues_EM();
+
+ return;
+ }
+
+ DrawGameValue_Level(level_nr);
DrawGameValue_Emeralds(local_player->gems_still_needed);
DrawGameValue_Dynamite(local_player->inventory_size);
DrawGameValue_Score(local_player->score);
DrawGameValue_Time(TimeLeft);
+
+ for (i = 0; i < MAX_PLAYERS; i++)
+ DrawGameValue_Keys(stored_player[i].key);
}
static void resolve_group_element(int group_element, int recursion_depth)
static void InitGameEngine()
{
- int i, j, k;
+ int i, j, k, l;
/* set game engine from tape file when re-playing, else from level file */
game.engine_version = (tape.playing ? tape.engine_version :
level.game_version);
+ /* ---------------------------------------------------------------------- */
+ /* set flags for bugs and changes according to active game engine version */
+ /* ---------------------------------------------------------------------- */
+
+ /*
+ Summary of bugfix/change:
+ Fixed handling for custom elements that change when pushed by the player.
+
+ Fixed/changed in version:
+ 3.1.0
+
+ Description:
+ Before 3.1.0, custom elements that "change when pushing" changed directly
+ after the player started pushing them (until then handled in "DigField()").
+ Since 3.1.0, these custom elements are not changed until the "pushing"
+ move of the element is finished (now handled in "ContinueMoving()").
+
+ Affected levels/tapes:
+ The first condition is generally needed for all levels/tapes before version
+ 3.1.0, which might use the old behaviour before it was changed; known tapes
+ that are affected are some tapes from the level set "Walpurgis Gardens" by
+ Jamie Cullen.
+ The second condition is an exception from the above case and is needed for
+ the special case of tapes recorded with game (not engine!) version 3.1.0 or
+ above (including some development versions of 3.1.0), but before it was
+ known that this change would break tapes like the above and was fixed in
+ 3.1.1, so that the changed behaviour was active although the engine version
+ while recording maybe was before 3.1.0. There is at least one tape that is
+ affected by this exception, which is the tape for the one-level set "Bug
+ Machine" by Juergen Bonhagen.
+ */
+
+ game.use_change_when_pushing_bug =
+ (game.engine_version < VERSION_IDENT(3,1,0,0) &&
+ !(tape.playing &&
+ tape.game_version >= VERSION_IDENT(3,1,0,0) &&
+ tape.game_version < VERSION_IDENT(3,1,1,0)));
+
+ /*
+ Summary of bugfix/change:
+ Fixed handling for blocking the field the player leaves when moving.
+
+ Fixed/changed in version:
+ 3.1.1
+
+ Description:
+ Before 3.1.1, when "block last field when moving" was enabled, the field
+ the player is leaving when moving was blocked for the time of the move,
+ and was directly unblocked afterwards. This resulted in the last field
+ being blocked for exactly one less than the number of frames of one player
+ move. Additionally, even when blocking was disabled, the last field was
+ blocked for exactly one frame.
+ Since 3.1.1, due to changes in player movement handling, the last field
+ is not blocked at all when blocking is disabled. When blocking is enabled,
+ the last field is blocked for exactly the number of frames of one player
+ move. Additionally, if the player is Murphy, the hero of Supaplex, the
+ last field is blocked for exactly one more than the number of frames of
+ one player move.
+
+ Affected levels/tapes:
+ (!!! yet to be determined -- probably many !!!)
+ */
+
+ game.use_block_last_field_bug =
+ (game.engine_version < VERSION_IDENT(3,1,1,0));
+
+ /* ---------------------------------------------------------------------- */
+
/* dynamically adjust element properties according to game engine version */
InitElementPropertiesEngine(game.engine_version);
/* ---------- initialize player's initial move delay --------------------- */
+#if USE_NEW_MOVE_DELAY
+ /* dynamically adjust player properties according to level information */
+ game.initial_move_delay_value =
+ (level.double_speed ? MOVE_DELAY_HIGH_SPEED : MOVE_DELAY_NORMAL_SPEED);
+
+ /* dynamically adjust player properties according to game engine version */
+ game.initial_move_delay = (game.engine_version <= VERSION_IDENT(2,0,1,0) ?
+ game.initial_move_delay_value : 0);
+#else
/* dynamically adjust player properties according to game engine version */
game.initial_move_delay =
(game.engine_version <= VERSION_IDENT(2,0,1,0) ? INITIAL_MOVE_DELAY_ON :
/* dynamically adjust player properties according to level information */
game.initial_move_delay_value =
(level.double_speed ? MOVE_DELAY_HIGH_SPEED : MOVE_DELAY_NORMAL_SPEED);
+#endif
/* ---------- initialize player's initial push delay --------------------- */
ei->change->delay_frames = 1;
}
- ei->change_events = CE_BITMASK_DEFAULT;
for (j = 0; j < NUM_CHANGE_EVENTS; j++)
{
+ ei->has_change_event[j] = FALSE;
+
ei->event_page_nr[j] = 0;
ei->event_page[j] = &ei->change_page[0];
}
ei->change->change_function = ch_delay->change_function;
ei->change->post_change_function = ch_delay->post_change_function;
- ei->change_events |= CH_EVENT_BIT(CE_DELAY);
+ ei->has_change_event[CE_DELAY] = TRUE;
#if 1
SET_PROPERTY(ch_delay->element, EP_CAN_CHANGE, TRUE);
for (k = 0; k < NUM_CHANGE_EVENTS; k++)
{
/* only add event page for the first page found with this event */
- if (ei->change_page[j].events & CH_EVENT_BIT(k) &&
- !(ei->change_events & CH_EVENT_BIT(k)))
+ if (ei->change_page[j].has_event[k] && !(ei->has_change_event[k]))
{
- ei->change_events |= CH_EVENT_BIT(k);
+ ei->has_change_event[k] = TRUE;
+
ei->event_page_nr[k] = j;
ei->event_page[k] = &ei->change_page[j];
}
/* only add custom elements that change after fixed/random frame delay */
if (CAN_CHANGE(element) && HAS_CHANGE_EVENT(element, CE_DELAY))
- element_info[element].change_events |= CH_EVENT_BIT(CE_DELAY);
+ element_info[element].has_change_event[CE_DELAY] = TRUE;
}
#endif
/* initialize trigger events information */
for (i = 0; i < MAX_NUM_ELEMENTS; i++)
- trigger_events[i] = EP_BITMASK_DEFAULT;
+ for (j = 0; j < NUM_CHANGE_EVENTS; j++)
+ trigger_events[i][j] = FALSE;
#if 1
/* add trigger events from element change event properties */
if (!ei->change_page[j].can_change)
continue;
- if (ei->change_page[j].events & CH_EVENT_BIT(CE_BY_OTHER_ACTION))
+ if (ei->change_page[j].has_event[CE_BY_OTHER_ACTION])
{
int trigger_element = ei->change_page[j].trigger_element;
- if (IS_GROUP_ELEMENT(trigger_element))
+ for (k = 0; k < NUM_CHANGE_EVENTS; k++)
{
- struct ElementGroupInfo *group = element_info[trigger_element].group;
+ if (ei->change_page[j].has_event[k])
+ {
+ if (IS_GROUP_ELEMENT(trigger_element))
+ {
+ struct ElementGroupInfo *group =
+ element_info[trigger_element].group;
- for (k = 0; k < group->num_elements_resolved; k++)
- trigger_events[group->element_resolved[k]]
- |= ei->change_page[j].events;
+ for (l = 0; l < group->num_elements_resolved; l++)
+ trigger_events[group->element_resolved[l]][k] = TRUE;
+ }
+ else
+ trigger_events[trigger_element][k] = TRUE;
+ }
}
- else
- trigger_events[trigger_element] |= ei->change_page[j].events;
}
}
}
/* add trigger events from element change event properties */
for (i = 0; i < MAX_NUM_ELEMENTS; i++)
if (HAS_CHANGE_EVENT(i, CE_BY_OTHER_ACTION))
- trigger_events[element_info[i].change->trigger_element] |=
- element_info[i].change->events;
+ for (j = 0; j < NUM_CHANGE_EVENTS; j++)
+ if (element_info[i].change->has_event[j])
+ trigger_events[element_info[i].change->trigger_element][j] = TRUE;
#endif
/* ---------- initialize push delay -------------------------------------- */
{
if (IS_SP_ELEMENT(i))
{
+#if USE_NEW_MOVE_STYLE
+ /* set SP push delay to just enough to push under a falling zonk */
+ int delay = (game.engine_version >= VERSION_IDENT(3,1,1,0) ? 8 : 6);
+
+ element_info[i].push_delay_fixed = delay;
+ element_info[i].push_delay_random = 0;
+#else
element_info[i].push_delay_fixed = 6; /* just enough to escape ... */
element_info[i].push_delay_random = 0; /* ... from falling zonk */
+#endif
}
}
}
player->lights_still_needed = 0;
player->friends_still_needed = 0;
- for (j = 0; j < MAX_KEYS; j++)
+ for (j = 0; j < MAX_NUM_KEYS; j++)
player->key[j] = FALSE;
player->dynabomb_count = 0;
player->use_murphy_graphic = FALSE;
- player->block_last_field = FALSE;
+ player->block_last_field = FALSE; /* initialized in InitPlayerField() */
+ player->block_delay_adjustment = 0; /* initialized in InitPlayerField() */
+
player->can_fall_into_acid = CAN_MOVE_INTO_ACID(player->element_nr);
player->actual_frame_counter = 0;
player->switch_x = -1;
player->switch_y = -1;
+#if USE_DROP_BUGFIX
+ player->drop_x = -1;
+ player->drop_y = -1;
+#endif
+
player->show_envelope = 0;
player->move_delay = game.initial_move_delay;
player->move_delay_reset_counter = 0;
- player->push_delay = 0;
+#if USE_NEW_PUSH_DELAY
+ player->push_delay = -1; /* initialized when pushing starts */
+ player->push_delay_value = game.initial_push_delay_value;
+#else
+ player->push_delay = 0;
player->push_delay_value = game.initial_push_delay_value;
+#endif
player->drop_delay = 0;
#endif
ZX = ZY = -1;
+ ExitX = ExitY = -1;
FrameCounter = 0;
TimeFrames = 0;
Stop[x][y] = FALSE;
Pushed[x][y] = FALSE;
- Changed[x][y] = CE_BITMASK_DEFAULT;
- ChangeEvent[x][y] = CE_BITMASK_DEFAULT;
+ Changed[x][y] = FALSE;
+ ChangeEvent[x][y] = -1;
ExplodePhase[x][y] = 0;
ExplodeDelay[x][y] = 0;
player->element_nr = some_player->element_nr;
#endif
+#if USE_NEW_BLOCK_STYLE
+ player->block_last_field = some_player->block_last_field;
+ player->block_delay_adjustment = some_player->block_delay_adjustment;
+#endif
+
StorePlayer[jx][jy] = player->element_nr;
player->jx = player->last_jx = jx;
player->jy = player->last_jy = jy;
CloseDoor(DOOR_CLOSE_1);
- DrawLevel();
- DrawAllPlayers();
+ /* !!! FIX THIS (START) !!! */
+ if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ {
+ InitGameEngine_EM();
+ }
+ else
+ {
+ DrawLevel();
+ DrawAllPlayers();
- /* after drawing the level, correct some elements */
- if (game.timegate_time_left == 0)
- CloseAllOpenTimegates();
+ /* after drawing the level, correct some elements */
+ if (game.timegate_time_left == 0)
+ CloseAllOpenTimegates();
- if (setup.soft_scrolling)
- BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY);
+ if (setup.soft_scrolling)
+ BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY);
- redraw_mask |= REDRAW_FROM_BACKBUFFER;
- FadeToFront();
+ redraw_mask |= REDRAW_FROM_BACKBUFFER;
+ FadeToFront();
+ }
+ /* !!! FIX THIS (END) !!! */
/* copy default game door content to main double buffer */
BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
#endif
}
+void UpdateEngineValues(int actual_scroll_x, int actual_scroll_y)
+{
+ /* this is used for non-R'n'D game engines to update certain engine values */
+
+ /* needed to determine if sounds are played within the visible screen area */
+ scroll_x = actual_scroll_x;
+ scroll_y = actual_scroll_y;
+}
+
void InitMovDir(int x, int y)
{
int i, element = Feld[x][y];
}
/* close exit door after last player */
- if ((Feld[ExitX][ExitY] == EL_EXIT_OPEN ||
- Feld[ExitX][ExitY] == EL_SP_EXIT_OPEN) && AllPlayersGone)
+ if (AllPlayersGone && ExitX >= 0 && ExitY >= 0 &&
+ (Feld[ExitX][ExitY] == EL_EXIT_OPEN ||
+ Feld[ExitX][ExitY] == EL_SP_EXIT_OPEN))
{
int element = Feld[ExitX][ExitY];
}
/* Hero disappears */
- DrawLevelField(ExitX, ExitY);
+ if (ExitX >= 0 && ExitY >= 0)
+ DrawLevelField(ExitX, ExitY);
+
BackToFront();
if (tape.playing)
return position;
}
+inline static int getElementMoveStepsize(int x, int y)
+{
+ int element = Feld[x][y];
+ int direction = MovDir[x][y];
+ int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0);
+ int dy = (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0);
+ int horiz_move = (dx != 0);
+ int sign = (horiz_move ? dx : dy);
+ int step = sign * element_info[element].move_stepsize;
+
+ /* special values for move stepsize for spring and things on conveyor belt */
+ if (horiz_move)
+ {
+#if 0
+ if (element == EL_SPRING)
+ step = sign * MOVE_STEPSIZE_NORMAL * 2;
+ else if (CAN_FALL(element) && !CAN_MOVE(element) &&
+ y < lev_fieldy - 1 && IS_BELT_ACTIVE(Feld[x][y + 1]))
+ step = sign * MOVE_STEPSIZE_NORMAL / 2;
+#else
+ if (CAN_FALL(element) &&
+ y < lev_fieldy - 1 && IS_BELT_ACTIVE(Feld[x][y + 1]))
+ step = sign * MOVE_STEPSIZE_NORMAL / 2;
+ else if (element == EL_SPRING)
+ step = sign * MOVE_STEPSIZE_NORMAL * 2;
+#endif
+ }
+
+ return step;
+}
+
void InitPlayerGfxAnimation(struct PlayerInfo *player, int action, int dir)
{
if (player->GfxAction != action || player->GfxDir != dir)
if (!WasJustMoving[x][y] || direction != MovDir[x][y])
ResetGfxAnimation(x, y);
+#if USE_CAN_MOVE_NOT_MOVING
+
+ MovDir[x][y] = direction;
+ GfxDir[x][y] = direction;
+ GfxAction[x][y] = (direction == MV_DOWN && CAN_FALL(element) ?
+ ACTION_FALLING : ACTION_MOVING);
+
+ if (getElementMoveStepsize(x, y) != 0) /* moving or being moved */
+ {
+ if (Feld[newx][newy] == EL_EMPTY)
+ Feld[newx][newy] = EL_BLOCKED;
+
+ MovDir[newx][newy] = MovDir[x][y];
+ GfxFrame[newx][newy] = GfxFrame[x][y];
+ GfxRandom[newx][newy] = GfxRandom[x][y];
+ GfxAction[newx][newy] = GfxAction[x][y];
+ GfxDir[newx][newy] = GfxDir[x][y];
+ }
+
+#else
+
MovDir[newx][newy] = MovDir[x][y] = direction;
GfxDir[x][y] = direction;
GfxRandom[newx][newy] = GfxRandom[x][y];
GfxAction[newx][newy] = GfxAction[x][y];
GfxDir[newx][newy] = GfxDir[x][y];
+#endif
}
void Moving2Blocked(int x, int y, int *goes_to_x, int *goes_to_y)
{
ScrollPlayer(player, SCROLL_GO_ON);
ScrollScreen(NULL, SCROLL_GO_ON);
+
+#if USE_NEW_MOVE_DELAY
+ AdvanceFrameAndPlayerCounters(player->index_nr);
+#else
FrameCounter++;
+#endif
DrawPlayer(player);
player->index_bit, leave_side);
CheckTriggeredElementChangeByPlayer(old_jx, old_jy, old_element,
- CE_OTHER_GETS_LEFT,
+ CE_PLAYER_LEAVES_X,
player->index_bit, leave_side);
#endif
player->index_bit, enter_side);
CheckTriggeredElementChangeByPlayer(jx, jy, element,
- CE_OTHER_GETS_ENTERED,
+ CE_PLAYER_ENTERS_X,
player->index_bit, enter_side);
#endif
}
return;
#endif
+#if 1
+ if (mode == EX_TYPE_NORMAL ||
+ mode == EX_TYPE_CENTER ||
+ mode == EX_TYPE_CROSS)
+ PlayLevelSoundAction(ex, ey, ACTION_EXPLODING);
+#else
if (mode == EX_TYPE_NORMAL || mode == EX_TYPE_CENTER)
PlayLevelSoundAction(ex, ey, ACTION_EXPLODING);
+#endif
/* remove things displayed in background while burning dynamite */
if (Back[ex][ey] != EL_EMPTY && !IS_INDESTRUCTIBLE(Back[ex][ey]))
continue;
#endif
-#if 1
+ /* no idea why this was changed from 3.0.8 to 3.1.0 -- this causes buggy
+ behaviour, for example when touching a yamyam that explodes to rocks
+ with active deadly shield, a rock is created under the player !!! */
+ /* (case 1 (surely buggy): >= 3.1.0, case 2 (maybe buggy): <= 3.0.8) */
+#if 0
if (IS_PLAYER(x, y) && SHIELD_ON(PLAYERINFO(x, y)) &&
(game.engine_version < VERSION_IDENT(3,1,0,0) ||
(x == ex && y == ey && mode != EX_TYPE_BORDER)))
break;
}
- CheckTriggeredElementChange(x, y, element, CE_OTHER_IS_EXPLODING);
+ CheckTriggeredElementChange(x, y, element, CE_EXPLOSION_OF_X);
}
void SplashAcid(int x, int y)
Feld[x][y] = getInvisibleActiveFromInvisibleElement(element);
DrawLevelField(x, y);
+
+ /* uncrumble neighbour fields, if needed */
+ if (element == EL_INVISIBLE_SAND)
+ DrawLevelFieldCrumbledSandNeighbours(x, y);
}
else if (element == EL_INVISIBLE_STEELWALL_ACTIVE ||
element == EL_INVISIBLE_WALL_ACTIVE ||
Feld[x][y] = getInvisibleFromInvisibleActiveElement(element);
DrawLevelField(x, y);
+
+ /* re-crumble neighbour fields, if needed */
+ if (element == EL_INVISIBLE_SAND)
+ DrawLevelFieldCrumbledSandNeighbours(x, y);
}
}
}
Feld[x][y] = EL_TIMEGATE_SWITCH_ACTIVE;
}
-inline static int getElementMoveStepsize(int x, int y)
-{
- int element = Feld[x][y];
- int direction = MovDir[x][y];
- int dx = (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0);
- int dy = (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0);
- int horiz_move = (dx != 0);
- int sign = (horiz_move ? dx : dy);
- int step = sign * element_info[element].move_stepsize;
-
- /* special values for move stepsize for spring and things on conveyor belt */
- if (horiz_move)
- {
-#if 0
- if (element == EL_SPRING)
- step = sign * MOVE_STEPSIZE_NORMAL * 2;
- else if (CAN_FALL(element) && !CAN_MOVE(element) &&
- y < lev_fieldy - 1 && IS_BELT_ACTIVE(Feld[x][y + 1]))
- step = sign * MOVE_STEPSIZE_NORMAL / 2;
-#else
- if (CAN_FALL(element) &&
- y < lev_fieldy - 1 && IS_BELT_ACTIVE(Feld[x][y + 1]))
- step = sign * MOVE_STEPSIZE_NORMAL / 2;
- else if (element == EL_SPRING)
- step = sign * MOVE_STEPSIZE_NORMAL * 2;
-#endif
- }
-
- return step;
-}
-
void Impact(int x, int y)
{
- boolean lastline = (y == lev_fieldy-1);
+ boolean last_line = (y == lev_fieldy - 1);
boolean object_hit = FALSE;
- boolean impact = (lastline || object_hit);
+ boolean impact = (last_line || object_hit);
int element = Feld[x][y];
int smashed = EL_STEELWALL;
- if (!lastline) /* check if element below was hit */
+#if 0
+ printf("IMPACT!\n");
+#endif
+
+ if (!last_line) /* check if element below was hit */
{
if (Feld[x][y + 1] == EL_PLAYER_IS_LEAVING)
return;
if (object_hit)
smashed = MovingOrBlocked2Element(x, y + 1);
- impact = (lastline || object_hit);
+ impact = (last_line || object_hit);
}
- if (!lastline && smashed == EL_ACID) /* element falls into acid */
+ if (!last_line && smashed == EL_ACID) /* element falls into acid */
{
SplashAcid(x, y + 1);
return;
CheckElementChangeBySide(x, y + 1, smashed, element,
CE_SWITCHED, CH_SIDE_TOP);
CheckTriggeredElementChangeBySide(x, y + 1, smashed,
- CE_OTHER_IS_SWITCHING,CH_SIDE_TOP);
+ CE_SWITCH_OF_X, CH_SIDE_TOP);
#else
CheckTriggeredElementChangeBySide(x, y + 1, smashed,
- CE_OTHER_IS_SWITCHING,CH_SIDE_TOP);
+ CE_SWITCH_OF_X, CH_SIDE_TOP);
CheckElementChangeBySide(x, y + 1, smashed, element,
CE_SWITCHED, CH_SIDE_TOP);
#endif
}
/* play sound of magic wall / mill */
- if (!lastline &&
+ if (!last_line &&
(Feld[x][y + 1] == EL_MAGIC_WALL_ACTIVE ||
Feld[x][y + 1] == EL_BD_MAGIC_WALL_ACTIVE))
{
}
/* play sound of object that hits the ground */
- if (lastline || object_hit)
+ if (last_line || object_hit)
PlayLevelSoundElementAction(x, y, element, ACTION_IMPACT);
}
xx = x + move_xy[MovDir[x][y]].x;
yy = y + move_xy[MovDir[x][y]].y;
+#if 1
+ /* !!! this bugfix breaks at least BD2K3, level 010 !!! [re-recorded] */
+ if (!IN_LEV_FIELD(xx, yy) ||
+ (!IS_FREE(xx, yy) && !IS_FOOD_PIG(Feld[xx][yy])))
+ MovDir[x][y] = old_move_dir;
+#else
if (!IS_FREE(xx, yy) && !IS_FOOD_PIG(Feld[xx][yy]))
MovDir[x][y] = old_move_dir;
+#endif
MovDelay[x][y] = 0;
}
boolean can_turn_right =
CUSTOM_ELEMENT_CAN_ENTER_FIELD(element, right_x,right_y);
+#if USE_CAN_MOVE_NOT_MOVING
+ if (element_info[element].move_stepsize == 0) /* not moving */
+ return;
+#endif
+
if (move_pattern == MV_TURNING_LEFT)
MovDir[x][y] = left_dir;
else if (move_pattern == MV_TURNING_RIGHT)
boolean first_horiz = RND(2);
int new_move_dir = MovDir[x][y];
+#if USE_CAN_MOVE_NOT_MOVING
+ if (element_info[element].move_stepsize == 0) /* not moving */
+ {
+ first_horiz = (ABS(attr_x - x) >= ABS(attr_y - y));
+ MovDir[x][y] &= (first_horiz ? MV_HORIZONTAL : MV_VERTICAL);
+
+ return;
+ }
+#endif
+
MovDir[x][y] =
new_move_dir & (first_horiz ? MV_HORIZONTAL : MV_VERTICAL);
Moving2Blocked(x, y, &newx, &newy);
MovDir[x][y] = new_move_dir;
if (old_move_dir != new_move_dir)
+ {
+#if 1
+ MovDelay[x][y] = GET_NEW_MOVE_DELAY(element);
+#else
MovDelay[x][y] = 9;
+#endif
+ }
}
}
else if ((game.engine_version >= VERSION_IDENT(3,1,0,0) &&
CheckCollision[x][y] && !IS_FREE(x, y + 1)) ||
+#if USE_IMPACT_BUGFIX
+ (game.engine_version >= VERSION_IDENT(3,0,7,0) &&
+ CAN_FALL(element) && WasJustFalling[x][y] &&
+ (Feld[x][y + 1] == EL_BLOCKED || IS_PLAYER(x, y + 1))) ||
+
+ (game.engine_version < VERSION_IDENT(2,2,0,7) &&
+ CAN_FALL(element) && WasJustMoving[x][y] && !Pushed[x][y + 1] &&
+ (Feld[x][y + 1] == EL_BLOCKED)))
+#else
(game.engine_version >= VERSION_IDENT(3,0,7,0) &&
CAN_SMASH(element) && WasJustFalling[x][y] &&
(Feld[x][y + 1] == EL_BLOCKED || IS_PLAYER(x, y + 1))) ||
(game.engine_version < VERSION_IDENT(2,2,0,7) &&
CAN_SMASH(element) && WasJustMoving[x][y] && !Pushed[x][y + 1] &&
(Feld[x][y + 1] == EL_BLOCKED)))
+#endif
#else
#if 1
CheckCollision[x][y] = 0;
+#if 0
+ if (IS_PLAYER(x, y + 1))
+ printf("::: we ARE now killing the player [%d]\n", FrameCounter);
+#endif
+
Impact(x, y);
}
else if (IS_FREE(x, y + 1) && element == EL_SPRING && level.use_spring_bug)
can_fall_both = (can_fall_left && can_fall_right);
}
+#if USE_NEW_SP_SLIPPERY
+ /* !!! better use the same properties as for custom elements here !!! */
+ else if (game.engine_version >= VERSION_IDENT(3,1,1,0) &&
+ can_fall_both && IS_SP_ELEMENT(Feld[x][y + 1]))
+ {
+ can_fall_right = FALSE; /* slip down on left side */
+ can_fall_both = FALSE;
+ }
+#endif
+
+#if 1
+ if (can_fall_both)
+ {
+ if (game.emulation == EMU_BOULDERDASH ||
+ element == EL_BD_ROCK || element == EL_BD_DIAMOND)
+ can_fall_right = FALSE; /* slip down on left side */
+ else
+ can_fall_left = !(can_fall_right = RND(2));
+
+ can_fall_both = FALSE;
+ }
+#endif
+
if (can_fall_any)
{
+#if 0
if (can_fall_both &&
(game.emulation != EMU_BOULDERDASH &&
element != EL_BD_ROCK && element != EL_BD_DIAMOND))
can_fall_left = !(can_fall_right = RND(2));
+#endif
+ /* if not determined otherwise, prefer left side for slipping down */
InitMovingField(x, y, can_fall_left ? MV_LEFT : MV_RIGHT);
started_moving = TRUE;
}
WasJustMoving[x][y],
HAS_ANY_CHANGE_EVENT(element, CE_HITTING_SOMETHING),
HAS_ANY_CHANGE_EVENT(element, CE_HIT_BY_SOMETHING),
- HAS_ANY_CHANGE_EVENT(element, CE_OTHER_IS_HITTING),
- HAS_ANY_CHANGE_EVENT(element, CE_OTHER_GETS_HIT));
+ HAS_ANY_CHANGE_EVENT(element, CE_HITTING_X),
+ HAS_ANY_CHANGE_EVENT(element, CE_HIT_BY_X));
#endif
#if 1
#if 1
Store[newx][newy] = EL_EMPTY;
if (IS_EQUAL_OR_IN_GROUP(new_element, MOVE_ENTER_EL(element)))
+ {
+#if USE_CHANGE_TO_TRIGGERED
+ int move_leave_element = element_info[element].move_leave_element;
+
+ Store[newx][newy] = (move_leave_element == EL_TRIGGER_ELEMENT ?
+ new_element : move_leave_element);
+#else
Store[newx][newy] = element_info[element].move_leave_element;
+#endif
+ }
#else
Store[newx][newy] = EL_EMPTY;
if (IS_EQUAL_OR_IN_GROUP(new_element, MOVE_ENTER_EL(element)) ||
ContinueMoving(x, y);
}
+void dummy()
+{
+}
+
void ContinueMoving(int x, int y)
{
int element = Feld[x][y];
#else
boolean pushed_by_player = Pushed[x][y];
#endif
+ boolean last_line = (newy == lev_fieldy - 1);
MovPos[x][y] += getElementMoveStepsize(x, y);
#endif
Store[x][y] = EL_EMPTY;
- MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0;
+ MovPos[x][y] = 0;
+ MovDir[x][y] = 0;
+ MovDelay[x][y] = 0;
MovDelay[newx][newy] = 0;
if (CAN_CHANGE(element))
ChangeDelay[x][y] = 0;
ChangePage[x][y] = -1;
- Changed[x][y] = CE_BITMASK_DEFAULT;
- ChangeEvent[x][y] = CE_BITMASK_DEFAULT;
+ Changed[x][y] = FALSE;
+ ChangeEvent[x][y] = -1;
/* copy animation control values to new field */
GfxFrame[newx][newy] = GfxFrame[x][y];
Pushed[x][y] = Pushed[newx][newy] = FALSE;
+#if 0
+ /* do this after checking for left-behind element */
ResetGfxAnimation(x, y); /* reset animation values for old field */
+#endif
#if 1
/* some elements can leave other elements behind after moving */
{
int move_leave_element = ei->move_leave_element;
+#if USE_CHANGE_TO_TRIGGERED
+ if (ei->move_leave_type == LEAVE_TYPE_LIMITED &&
+ ei->move_leave_element == EL_TRIGGER_ELEMENT)
+ move_leave_element = stored;
+#endif
+
Feld[x][y] = move_leave_element;
- InitField(x, y, FALSE);
+
+#if USE_PREVIOUS_MOVE_DIR
+ if (element_info[Feld[x][y]].move_direction_initial == MV_START_PREVIOUS)
+ MovDir[x][y] = direction;
+#endif
+
+ InitField(x, y, FALSE);
if (GFX_CRUMBLED(Feld[x][y]))
DrawLevelFieldCrumbledSandNeighbours(x, y);
ei->can_leave_element = FALSE;
#endif
+#if 1
+ /* do this after checking for left-behind element */
+ ResetGfxAnimation(x, y); /* reset animation values for old field */
+#endif
+
#if 0
/* 2.1.1 (does not work correctly for spring) */
if (!CAN_MOVE(element))
else if (element == EL_PENGUIN)
TestIfFriendTouchesBadThing(newx, newy);
+#if USE_NEW_MOVE_STYLE
+#if 0
if (CAN_FALL(element) && direction == MV_DOWN &&
- (newy == lev_fieldy - 1 || !IS_FREE(x, newy + 1)))
+ !last_line && IS_PLAYER(x, newy + 1))
+ printf("::: we would now kill the player [%d]\n", FrameCounter);
+#endif
+
+ /* give the player one last chance (one more frame) to move away */
+ if (CAN_FALL(element) && direction == MV_DOWN &&
+ (last_line || (!IS_FREE(x, newy + 1) &&
+ (!IS_PLAYER(x, newy + 1) ||
+ game.engine_version < VERSION_IDENT(3,1,1,0)))))
Impact(x, newy);
+#else
+ if (CAN_FALL(element) && direction == MV_DOWN &&
+ (last_line || !IS_FREE(x, newy + 1)))
+ Impact(x, newy);
+#endif
+
+#if 1
+#if USE_PUSH_BUGFIX
#if 1
+ if (pushed_by_player && !game.use_change_when_pushing_bug)
+#else
+ if (pushed_by_player && game.engine_version >= VERSION_IDENT(3,1,0,0))
+#endif
+#else
if (pushed_by_player)
+#endif
+
{
#if 1
int dig_side = MV_DIR_OPPOSITE(direction);
CheckElementChangeByPlayer(newx, newy, element, CE_PUSHED_BY_PLAYER,
player->index_bit, dig_side);
- CheckTriggeredElementChangeByPlayer(newx,newy,element,CE_OTHER_GETS_PUSHED,
+ CheckTriggeredElementChangeByPlayer(newx,newy, element, CE_PLAYER_PUSHES_X,
player->index_bit, dig_side);
}
#endif
CE_HIT_BY_SOMETHING, opposite_direction);
if (IS_CUSTOM_ELEMENT(hitting_element) &&
- HAS_ANY_CHANGE_EVENT(hitting_element, CE_OTHER_IS_HITTING))
+ HAS_ANY_CHANGE_EVENT(hitting_element, CE_HITTING_X))
{
for (i = 0; i < element_info[hitting_element].num_change_pages; i++)
{
&element_info[hitting_element].change_page[i];
if (change->can_change &&
- change->events & CH_EVENT_BIT(CE_OTHER_IS_HITTING) &&
+ change->has_event[CE_HITTING_X] &&
change->trigger_side & touched_side &&
change->trigger_element == touched_element)
{
CheckElementChangeByPage(newx, newy, hitting_element,
- touched_element, CE_OTHER_IS_HITTING,i);
+ touched_element, CE_HITTING_X, i);
break;
}
}
}
if (IS_CUSTOM_ELEMENT(touched_element) &&
- HAS_ANY_CHANGE_EVENT(touched_element, CE_OTHER_GETS_HIT))
+ HAS_ANY_CHANGE_EVENT(touched_element, CE_HIT_BY_X))
{
for (i = 0; i < element_info[touched_element].num_change_pages; i++)
{
&element_info[touched_element].change_page[i];
if (change->can_change &&
- change->events & CH_EVENT_BIT(CE_OTHER_GETS_HIT) &&
+ change->has_event[CE_HIT_BY_X] &&
change->trigger_side & hitting_side &&
change->trigger_element == hitting_element)
{
CheckElementChangeByPage(nextx, nexty, touched_element,
- hitting_element, CE_OTHER_GETS_HIT, i);
+ hitting_element, CE_HIT_BY_X,i);
break;
}
}
RelocatePlayer(x, y, target_element);
#if 1
+ Changed[x][y] = TRUE; /* ignore all further changes in this frame */
+#else
Changed[x][y] |= ChangeEvent[x][y]; /* ignore same changes in this frame */
#endif
int old_element = Feld[x][y];
/* always use default change event to prevent running into a loop */
- if (ChangeEvent[x][y] == CE_BITMASK_DEFAULT)
- ChangeEvent[x][y] = CH_EVENT_BIT(CE_DELAY);
+ if (ChangeEvent[x][y] == -1)
+ ChangeEvent[x][y] = CE_DELAY;
- if (ChangeEvent[x][y] == CH_EVENT_BIT(CE_DELAY))
+ if (ChangeEvent[x][y] == CE_DELAY)
{
/* reset actual trigger element and player */
change->actual_trigger_element = EL_EMPTY;
change->actual_trigger_player = EL_PLAYER_1;
}
- /* do not change already changed elements with same change event */
-#if 0
- if (Changed[x][y] & ChangeEvent[x][y])
+#if 1
+ /* do not change any elements that have already changed in this frame */
+ if (Changed[x][y])
return FALSE;
#else
- if (Changed[x][y])
+ /* do not change already changed elements with same change event */
+ if (Changed[x][y] & ChangeEvent[x][y])
return FALSE;
#endif
+#if 1
+ Changed[x][y] = TRUE; /* ignore all further changes in this frame */
+#else
Changed[x][y] |= ChangeEvent[x][y]; /* ignore same changes in this frame */
+#endif
#if 0
/* !!! indirect change before direct change !!! */
- CheckTriggeredElementChangeByPage(x,y,Feld[x][y], CE_OTHER_IS_CHANGING,page);
+ CheckTriggeredElementChangeByPage(x, y, Feld[x][y], CE_CHANGE_OF_X, page);
#endif
if (change->explode)
#if 1
/* this uses direct change before indirect change */
- CheckTriggeredElementChangeByPage(x,y,old_element,CE_OTHER_IS_CHANGING,page);
+ CheckTriggeredElementChangeByPage(x, y, old_element, CE_CHANGE_OF_X, page);
#endif
return TRUE;
int i, j, x, y;
int trigger_page_bits = (trigger_page < 0 ? CH_PAGE_ANY : 1 << trigger_page);
- if (!(trigger_events[trigger_element] & CH_EVENT_BIT(trigger_event)))
+ if (!(trigger_events[trigger_element][trigger_event]))
return FALSE;
for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
struct ElementChangeInfo *change = &element_info[element].change_page[j];
if (change->can_change &&
- change->events & CH_EVENT_BIT(trigger_event) &&
+ change->has_event[trigger_event] &&
change->trigger_side & trigger_side &&
change->trigger_player & trigger_player &&
change->trigger_page & trigger_page_bits &&
IS_EQUAL_OR_IN_GROUP(trigger_element, change->trigger_element))
{
#if 0
- if (!(change->events & CH_EVENT_BIT(trigger_event)))
+ if (!(change->has_event[trigger_event]))
printf("::: !!! %d triggers %d: using wrong page %d [event %d]\n",
trigger_element-EL_CUSTOM_START+1, i+1, j, trigger_event);
#endif
if (Feld[x][y] == element)
{
ChangeDelay[x][y] = 1;
- ChangeEvent[x][y] = CH_EVENT_BIT(trigger_event);
+ ChangeEvent[x][y] = trigger_event;
ChangeElement(x, y, page);
}
}
struct ElementChangeInfo *change = &element_info[element].change_page[i];
if (change->can_change &&
- change->events & CH_EVENT_BIT(trigger_event) &&
+ change->has_event[trigger_event] &&
change->trigger_side & trigger_side &&
change->trigger_player & trigger_player)
{
#endif
ChangeDelay[x][y] = 1;
- ChangeEvent[x][y] = CH_EVENT_BIT(trigger_event);
+ ChangeEvent[x][y] = trigger_event;
ChangeElement(x, y, trigger_page);
return TRUE;
}
#endif
+void AdvanceFrameAndPlayerCounters(int player_nr)
+{
+ int i;
+
+ /* advance frame counters (global frame counter and time frame counter) */
+ FrameCounter++;
+ TimeFrames++;
+
+ /* advance player counters (counters for move delay, move animation etc.) */
+ for (i = 0; i < MAX_PLAYERS; i++)
+ {
+ boolean advance_player_counters = (player_nr == -1 || player_nr == i);
+ int move_frames =
+ MOVE_DELAY_NORMAL_SPEED / stored_player[i].move_delay_value;
+
+ if (!advance_player_counters) /* not all players may be affected */
+ continue;
+
+ stored_player[i].Frame += move_frames;
+
+ if (stored_player[i].MovPos != 0)
+ stored_player[i].StepFrame += move_frames;
+
+#if USE_NEW_MOVE_DELAY
+ if (stored_player[i].move_delay > 0)
+ stored_player[i].move_delay--;
+#endif
+
+#if USE_NEW_PUSH_DELAY
+ /* due to bugs in previous versions, counter must count up, not down */
+ if (stored_player[i].push_delay != -1)
+ stored_player[i].push_delay++;
+#endif
+
+ if (stored_player[i].drop_delay > 0)
+ stored_player[i].drop_delay--;
+ }
+}
+
void GameActions()
{
- static unsigned long action_delay = 0;
- unsigned long action_delay_value;
+ static unsigned long game_frame_delay = 0;
+ unsigned long game_frame_delay_value;
int magic_wall_x = 0, magic_wall_y = 0;
int i, x, y, element, graphic;
byte *recorded_player_action;
if (game_status != GAME_MODE_PLAYING)
return;
- action_delay_value =
+ game_frame_delay_value =
(tape.playing && tape.fast_forward ? FfwdFrameDelay : GameFrameDelay);
if (tape.playing && tape.warp_forward && !tape.pausing)
- action_delay_value = 0;
+ game_frame_delay_value = 0;
/* ---------- main game synchronization point ---------- */
- WaitUntilDelayReached(&action_delay, action_delay_value);
+ WaitUntilDelayReached(&game_frame_delay, game_frame_delay_value);
if (network_playing && !network_player_action_received)
{
recorded_player_action = (tape.playing ? TapePlayAction() : NULL);
#if 1
+ /* !!! CHECK THIS (tape.pausing is always FALSE here!) !!! */
if (recorded_player_action == NULL && tape.pausing)
return;
#endif
#endif
#if 1
- /* for downwards compatibility, the following code emulates a fixed bug that
+ /* for backwards compatibility, the following code emulates a fixed bug that
occured when pushing elements (causing elements that just made their last
pushing step to already (if possible) make their first falling step in the
same game frame, which is bad); this code is also needed to use the famous
for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++)
{
- Changed[x][y] = CE_BITMASK_DEFAULT;
- ChangeEvent[x][y] = CE_BITMASK_DEFAULT;
+ Changed[x][y] = FALSE;
+ ChangeEvent[x][y] = -1;
+
+#if USE_NEW_BLOCK_STYLE
+ /* this must be handled before main playfield loop */
+ if (Feld[x][y] == EL_PLAYER_IS_LEAVING)
+ {
+ MovDelay[x][y]--;
+ if (MovDelay[x][y] <= 0)
+ RemoveField(x, y);
+ }
+#endif
#if DEBUG
if (ChangePage[x][y] != -1 && ChangeDelay[x][y] != 1)
stored_player[0].StepFrame);
#endif
-#if 1
+#if USE_NEW_MOVE_DELAY
+ AdvanceFrameAndPlayerCounters(-1); /* advance counters for all players */
+#else
FrameCounter++;
TimeFrames++;
if (stored_player[i].MovPos != 0)
stored_player[i].StepFrame += move_frames;
+#if USE_NEW_MOVE_DELAY
+ if (stored_player[i].move_delay > 0)
+ stored_player[i].move_delay--;
+#endif
+
if (stored_player[i].drop_delay > 0)
stored_player[i].drop_delay--;
}
local_player->show_envelope = 0;
}
#endif
+
+#if USE_NEW_RANDOMIZE
+ /* use random number generator in every frame to make it less predictable */
+ if (game.engine_version >= VERSION_IDENT(3,1,1,0))
+ RND(1);
+#endif
}
static boolean AllPlayersInSight(struct PlayerInfo *player, int x, int y)
return (IN_LEV_FIELD(jx, jy + 1) &&
(IS_FREE(jx, jy + 1) ||
+#if USE_NEW_BLOCK_STYLE
+#if USE_GRAVITY_BUGFIX_OLD
+ Feld[jx][jy + 1] == EL_PLAYER_IS_LEAVING ||
+#endif
+#endif
(Feld[jx][jy + 1] == EL_ACID && player->can_fall_into_acid)) &&
IS_WALKABLE_FROM(Feld[jx][jy], MV_DOWN) &&
!IS_WALKABLE_INSIDE(Feld[jx][jy]));
/* check if DigField() has caused relocation of the player */
if (player->jx != jx || player->jy != jy)
- return MF_NO_ACTION;
+ return MF_NO_ACTION; /* <-- !!! CHECK THIS [-> MF_ACTION ?] !!! */
StorePlayer[jx][jy] = 0;
player->last_jx = jx;
#if 0
if (IS_CUSTOM_ELEMENT(Feld[jx][jy]))
{
- CheckTriggeredElementChangeBySide(jx, jy, Feld[jx][jy], CE_OTHER_GETS_LEFT,
+ CheckTriggeredElementChangeBySide(jx, jy, Feld[jx][jy], CE_PLAYER_LEAVES_X,
leave_side);
CheckElementChangeBySide(jx,jy, Feld[jx][jy],CE_LEFT_BY_PLAYER,leave_side);
}
if (IS_CUSTOM_ELEMENT(Feld[new_jx][new_jy]))
{
CheckTriggeredElementChangeBySide(new_jx, new_jy, Feld[new_jx][new_jy],
- CE_OTHER_GETS_ENTERED, enter_side);
+ CE_PLAYER_ENTERS_X, enter_side);
CheckElementChangeBySide(new_jx, new_jy, Feld[new_jx][new_jy],
CE_ENTERED_BY_PLAYER, enter_side);
}
#else
#if 1
+
+#if 0
+ printf("::: %d <= %d < %d ?\n", player->move_delay, FrameCounter,
+ player->move_delay + player->move_delay_value);
+#endif
+
+#if USE_NEW_MOVE_DELAY
+ if (player->move_delay > 0)
+#else
if (!FrameReached(&player->move_delay, player->move_delay_value))
+#endif
+ {
+#if 0
+ printf("::: can NOT move\n");
+#endif
+
return FALSE;
+ }
#else
if (!FrameReached(&player->move_delay, player->move_delay_value) &&
!(tape.playing && tape.file_version < FILE_VERSION_2_0))
return FALSE;
#endif
+#endif
+
+#if 0
+ printf("::: COULD move now\n");
+#endif
+
+#if USE_NEW_MOVE_DELAY
+ player->move_delay = -1; /* set to "uninitialized" value */
#endif
/* store if player is automatically moved to next field */
{
ScrollPlayer(player, SCROLL_GO_ON);
ScrollScreen(NULL, SCROLL_GO_ON);
+
+#if USE_NEW_MOVE_DELAY
+ AdvanceFrameAndPlayerCounters(player->index_nr);
+#else
FrameCounter++;
+#endif
+
DrawAllPlayers();
BackToFront();
}
if (moved & MF_MOVING)
{
+#if 0
+ printf("::: REALLY moves now\n");
+#endif
+
if (old_jx != jx && old_jy == jy)
player->MovDir = (old_jx < jx ? MV_RIGHT : MV_LEFT);
else if (old_jx == jx && old_jy != jy)
player->index_bit, leave_side);
CheckTriggeredElementChangeByPlayer(old_jx, old_jy, old_element,
- CE_OTHER_GETS_LEFT,
+ CE_PLAYER_LEAVES_X,
player->index_bit, leave_side);
if (IS_CUSTOM_ELEMENT(new_element))
player->index_bit, enter_side);
CheckTriggeredElementChangeByPlayer(jx, jy, new_element,
- CE_OTHER_GETS_ENTERED,
+ CE_PLAYER_ENTERS_X,
player->index_bit, enter_side);
#endif
player->last_move_dir = MV_NO_MOVING;
*/
player->is_moving = FALSE;
+
+#if USE_NEW_MOVE_STYLE
+ /* player is ALLOWED to move, but CANNOT move (something blocks his way) */
+ /* ensure that the player is also allowed to move in the next frame */
+ /* (currently, the player is forced to wait eight frames before he can try
+ again!!!) */
+
+ if (game.engine_version >= VERSION_IDENT(3,1,1,0))
+ player->move_delay = 0; /* allow direct movement in the next frame */
+#endif
}
+#if USE_NEW_MOVE_DELAY
+ if (player->move_delay == -1) /* not yet initialized by DigField() */
+ player->move_delay = player->move_delay_value;
+#endif
+
if (game.engine_version < VERSION_IDENT(3,0,7,0))
{
TestIfHeroTouchesBadThing(jx, jy);
player->actual_frame_counter = FrameCounter;
player->GfxPos = move_stepsize * (player->MovPos / move_stepsize);
+#if 0
+ printf("::: %06d: %d,%d: %d (%d) [%d]\n",
+ FrameCounter,
+ last_jx, last_jy, Feld[last_jx][last_jy], EL_EXPLOSION,
+ player->block_delay);
+#endif
+
+#if USE_NEW_BLOCK_STYLE
+
+#if 0
+ if (player->block_delay <= 0)
+ printf("::: ALERT! block_delay == %d\n", player->block_delay);
+#endif
+
+ if ((player->block_last_field || player->block_delay_adjustment > 0) &&
+ Feld[last_jx][last_jy] == EL_EMPTY)
+ {
+ int last_field_block_delay = 0; /* start with no blocking at all */
+ int block_delay_adjustment = player->block_delay_adjustment;
+
+ /* if player blocks last field, add delay for exactly one move */
+ if (player->block_last_field)
+ {
+ last_field_block_delay += player->move_delay_value;
+
+#if USE_GRAVITY_BUGFIX_NEW
+ /* when blocking enabled, prevent moving up despite gravity */
+ if (game.gravity && player->MovDir == MV_UP)
+ block_delay_adjustment = -1;
+#endif
+ }
+
+ /* add block delay adjustment (also possible when not blocking) */
+ last_field_block_delay += block_delay_adjustment;
+
+#if 0
+#if USE_BLOCK_DELAY_BUGFIX
+ /* when blocking enabled, correct block delay for fast movement */
+ if (player->block_last_field &&
+ player->move_delay_value < MOVE_DELAY_NORMAL_SPEED)
+ last_field_block_delay =
+ player->move_delay_value + player->block_delay_adjustment;
+#endif
+#endif
+
+#if 0
+#if USE_GRAVITY_BUGFIX_NEW
+ /* when blocking enabled, correct block delay for gravity movement */
+ if (player->block_last_field &&
+ game.gravity && player->MovDir == MV_UP)
+ last_field_block_delay = player->move_delay_value - 1;
+#endif
+#endif
+
+ Feld[last_jx][last_jy] = EL_PLAYER_IS_LEAVING;
+ MovDelay[last_jx][last_jy] = last_field_block_delay + 1;
+ }
+#else
+#if USE_NEW_MOVE_STYLE
+ if ((game.engine_version < VERSION_IDENT(3,1,1,0) ||
+ player->block_last_field) &&
+ Feld[last_jx][last_jy] == EL_EMPTY)
+ Feld[last_jx][last_jy] = EL_PLAYER_IS_LEAVING;
+#else
if (Feld[last_jx][last_jy] == EL_EMPTY)
Feld[last_jx][last_jy] = EL_PLAYER_IS_LEAVING;
+#endif
+#endif
#if 0
DrawPlayer(player);
player->MovPos += (player->MovPos > 0 ? -1 : 1) * move_stepsize;
player->GfxPos = move_stepsize * (player->MovPos / move_stepsize);
+#if USE_NEW_BLOCK_STYLE
+#else
if (!player->block_last_field &&
Feld[last_jx][last_jy] == EL_PLAYER_IS_LEAVING)
+#if 1
+ RemoveField(last_jx, last_jy);
+#else
Feld[last_jx][last_jy] = EL_EMPTY;
+#endif
+#endif
/* before DrawPlayer() to draw correct player graphic for this case */
if (player->MovPos == 0)
}
#endif
+#if USE_NEW_BLOCK_STYLE
+#else
if (player->block_last_field &&
Feld[last_jx][last_jy] == EL_PLAYER_IS_LEAVING)
+#if 1
+ RemoveField(last_jx, last_jy);
+#else
Feld[last_jx][last_jy] = EL_EMPTY;
+#endif
+#endif
player->last_jx = jx;
player->last_jy = jy;
player->index_bit, leave_side);
CheckTriggeredElementChangeByPlayer(old_jx, old_jy, old_element,
- CE_OTHER_GETS_LEFT,
+ CE_PLAYER_LEAVES_X,
player->index_bit, leave_side);
if (IS_CUSTOM_ELEMENT(new_element))
player->index_bit, enter_side);
CheckTriggeredElementChangeByPlayer(jx, jy, new_element,
- CE_OTHER_GETS_ENTERED,
+ CE_PLAYER_ENTERS_X,
player->index_bit, enter_side);
#endif
CheckElementChangeByPlayer(xx, yy, border_element, CE_TOUCHED_BY_PLAYER,
player->index_bit, border_side);
CheckTriggeredElementChangeByPlayer(xx, yy, border_element,
- CE_OTHER_GETS_TOUCHED,
+ CE_PLAYER_TOUCHES_X,
player->index_bit, border_side);
#else
CheckTriggeredElementChangeByPlayer(xx, yy, border_element,
- CE_OTHER_GETS_TOUCHED,
+ CE_PLAYER_TOUCHES_X,
player->index_bit, border_side);
CheckElementChangeByPlayer(xx, yy, border_element, CE_TOUCHED_BY_PLAYER,
player->index_bit, border_side);
CheckElementChangeByPlayer(x, y, center_element, CE_TOUCHED_BY_PLAYER,
player->index_bit, center_side);
CheckTriggeredElementChangeByPlayer(x, y, center_element,
- CE_OTHER_GETS_TOUCHED,
+ CE_PLAYER_TOUCHES_X,
player->index_bit, center_side);
#else
CheckTriggeredElementChangeByPlayer(x, y, center_element,
- CE_OTHER_GETS_TOUCHED,
+ CE_PLAYER_TOUCHES_X,
player->index_bit, center_side);
CheckElementChangeByPlayer(x, y, center_element, CE_TOUCHED_BY_PLAYER,
player->index_bit, center_side);
/* check for change of center element (but change it only once) */
if (IS_CUSTOM_ELEMENT(center_element) &&
- HAS_ANY_CHANGE_EVENT(center_element, CE_OTHER_IS_TOUCHING) &&
+ HAS_ANY_CHANGE_EVENT(center_element, CE_TOUCHING_X) &&
!change_center_element)
{
for (j = 0; j < element_info[center_element].num_change_pages; j++)
&element_info[center_element].change_page[j];
if (change->can_change &&
- change->events & CH_EVENT_BIT(CE_OTHER_IS_TOUCHING) &&
+ change->has_event[CE_TOUCHING_X] &&
change->trigger_side & border_side &&
#if 1
IS_EQUAL_OR_IN_GROUP(border_element, change->trigger_element)
/* check for change of border element */
if (IS_CUSTOM_ELEMENT(border_element) &&
- HAS_ANY_CHANGE_EVENT(border_element, CE_OTHER_IS_TOUCHING))
+ HAS_ANY_CHANGE_EVENT(border_element, CE_TOUCHING_X))
{
for (j = 0; j < element_info[border_element].num_change_pages; j++)
{
&element_info[border_element].change_page[j];
if (change->can_change &&
- change->events & CH_EVENT_BIT(CE_OTHER_IS_TOUCHING) &&
+ change->has_event[CE_TOUCHING_X] &&
change->trigger_side & center_side &&
#if 1
IS_EQUAL_OR_IN_GROUP(center_element, change->trigger_element)
#endif
CheckElementChangeByPage(xx, yy, border_element, center_element,
- CE_OTHER_IS_TOUCHING, j);
+ CE_TOUCHING_X, j);
break;
}
}
#endif
CheckElementChangeByPage(x, y, center_element, border_trigger_element,
- CE_OTHER_IS_TOUCHING, center_element_change_page);
+ CE_TOUCHING_X, center_element_change_page);
}
}
touched_element = (IN_LEV_FIELD(hitx, hity) ?
MovingOrBlocked2Element(hitx, hity) : EL_STEELWALL);
+#if !USE_HITTING_SOMETHING_BUGFIX
+ /* "hitting something" is also true when hitting the playfield border */
CheckElementChangeBySide(x, y, hitting_element, touched_element,
CE_HITTING_SOMETHING, direction);
+#endif
if (IN_LEV_FIELD(hitx, hity))
{
{
int i;
+#if !USE_HIT_BY_SOMETHING_BUGFIX
CheckElementChangeBySide(hitx, hity, touched_element, hitting_element,
CE_HIT_BY_SOMETHING, opposite_direction);
+#endif
if (IS_CUSTOM_ELEMENT(hitting_element) &&
- HAS_ANY_CHANGE_EVENT(hitting_element, CE_OTHER_IS_HITTING))
+ HAS_ANY_CHANGE_EVENT(hitting_element, CE_HITTING_X))
{
for (i = 0; i < element_info[hitting_element].num_change_pages; i++)
{
&element_info[hitting_element].change_page[i];
if (change->can_change &&
- change->events & CH_EVENT_BIT(CE_OTHER_IS_HITTING) &&
+ change->has_event[CE_HITTING_X] &&
change->trigger_side & touched_side &&
#if 1
)
{
CheckElementChangeByPage(x, y, hitting_element, touched_element,
- CE_OTHER_IS_HITTING, i);
+ CE_HITTING_X, i);
break;
}
}
}
if (IS_CUSTOM_ELEMENT(touched_element) &&
- HAS_ANY_CHANGE_EVENT(touched_element, CE_OTHER_GETS_HIT))
+ HAS_ANY_CHANGE_EVENT(touched_element, CE_HIT_BY_X))
{
for (i = 0; i < element_info[touched_element].num_change_pages; i++)
{
&element_info[touched_element].change_page[i];
if (change->can_change &&
- change->events & CH_EVENT_BIT(CE_OTHER_GETS_HIT) &&
+ change->has_event[CE_HIT_BY_X] &&
change->trigger_side & hitting_side &&
#if 1
IS_EQUAL_OR_IN_GROUP(hitting_element, change->trigger_element)
)
{
CheckElementChangeByPage(hitx, hity, touched_element,
- hitting_element, CE_OTHER_GETS_HIT, i);
+ hitting_element, CE_HIT_BY_X, i);
break;
}
}
}
+
+#if USE_HIT_BY_SOMETHING_BUGFIX
+ CheckElementChangeBySide(hitx, hity, touched_element, hitting_element,
+ CE_HIT_BY_SOMETHING, opposite_direction);
+#endif
}
}
+
+#if USE_HITTING_SOMETHING_BUGFIX
+ /* "hitting something" is also true when hitting the playfield border */
+ CheckElementChangeBySide(x, y, hitting_element, touched_element,
+ CE_HITTING_SOMETHING, direction);
+#endif
}
#if 0
&element_info[hitting_element].change_page[i];
if (change->can_change &&
- change->events & CH_EVENT_BIT(CE_OTHER_IS_SMASHING) &&
+ change->has_event[CE_OTHER_IS_SMASHING] &&
change->trigger_side & touched_side &&
#if 1
&element_info[touched_element].change_page[i];
if (change->can_change &&
- change->events & CH_EVENT_BIT(CE_OTHER_GETS_SMASHED) &&
+ change->has_event[CE_OTHER_GETS_SMASHED] &&
change->trigger_side & hitting_side &&
#if 1
IS_EQUAL_OR_IN_GROUP(hitting_element, change->trigger_element)
if (mode == DF_NO_PUSH) /* player just stopped pushing */
{
player->is_switching = FALSE;
+#if USE_NEW_PUSH_DELAY
+ player->push_delay = -1;
+#else
player->push_delay = 0;
+#endif
return MF_NO_ACTION;
}
return MF_NO_ACTION; /* player cannot walk here due to gravity */
#endif
- if (IS_GATE(element))
+ if (IS_RND_GATE(element))
{
- if (!player->key[element - EL_GATE_1])
+ if (!player->key[RND_GATE_NR(element)])
return MF_NO_ACTION;
}
- else if (IS_GATE_GRAY(element))
+ else if (IS_RND_GATE_GRAY(element))
{
- if (!player->key[element - EL_GATE_1_GRAY])
+ if (!player->key[RND_GATE_GRAY_NR(element)])
return MF_NO_ACTION;
}
else if (element == EL_EXIT_OPEN ||
if (IS_EM_GATE(element))
{
- if (!player->key[element - EL_EM_GATE_1])
+ if (!player->key[EM_GATE_NR(element)])
return MF_NO_ACTION;
}
else if (IS_EM_GATE_GRAY(element))
{
- if (!player->key[element - EL_EM_GATE_1_GRAY])
+ if (!player->key[EM_GATE_GRAY_NR(element)])
return MF_NO_ACTION;
}
else if (IS_SP_PORT(element))
PlayLevelSoundElementAction(x, y, element, ACTION_DIGGING);
- CheckTriggeredElementChangeByPlayer(x, y, element,CE_OTHER_GETS_DIGGED,
+ CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_DIGS_X,
player->index_bit, dig_side);
#if 1
{
player->dynabomb_xl = TRUE;
}
- else if ((element >= EL_KEY_1 && element <= EL_KEY_4) ||
- (element >= EL_EM_KEY_1 && element <= EL_EM_KEY_4))
+ else if (IS_KEY(element))
{
- int key_nr = (element >= EL_KEY_1 && element <= EL_KEY_4 ?
- element - EL_KEY_1 : element - EL_EM_KEY_1);
-
- player->key[key_nr] = TRUE;
+ player->key[KEY_NR(element)] = TRUE;
- DrawGameValue_Keys(player);
+ DrawGameValue_Keys(player->key);
redraw_mask |= REDRAW_DOOR_1;
}
if (is_player)
CheckTriggeredElementChangeByPlayer(x, y, element,
- CE_OTHER_GETS_COLLECTED,
+ CE_PLAYER_COLLECTS_X,
player->index_bit, dig_side);
#if 1
if (!checkDiagonalPushing(player, x, y, real_dx, real_dy))
return MF_NO_ACTION;
+#if USE_NEW_PUSH_DELAY
+
+#if 0
+ if ( (player->push_delay == -1) != (player->push_delay2 == 0) )
+ printf("::: ALERT: %d, %d [%d / %d]\n",
+ player->push_delay, player->push_delay2,
+ FrameCounter, FrameCounter / 50);
+#endif
+
+ if (player->push_delay == -1) /* new pushing; restart delay */
+ player->push_delay = 0;
+#else
if (player->push_delay == 0) /* new pushing; restart delay */
player->push_delay = FrameCounter;
+#endif
+
+#if USE_NEW_PUSH_DELAY
+#if 0
+ if ( (player->push_delay > 0) != (!xxx_fr) )
+ printf("::: PUSH BUG! %d, (%d -> %d) %d [%d / %d]\n",
+ player->push_delay,
+ xxx_pdv2, player->push_delay2, player->push_delay_value,
+ FrameCounter, FrameCounter / 50);
+#endif
+
+#if 0
+ if (player->push_delay > 0 &&
+ !(tape.playing && tape.file_version < FILE_VERSION_2_0) &&
+ element != EL_SPRING && element != EL_BALLOON)
+#else
+ /* !!! */
+ if (player->push_delay < player->push_delay_value &&
+ !(tape.playing && tape.file_version < FILE_VERSION_2_0) &&
+ element != EL_SPRING && element != EL_BALLOON)
+#endif
+#else
if (!FrameReached(&player->push_delay, player->push_delay_value) &&
!(tape.playing && tape.file_version < FILE_VERSION_2_0) &&
element != EL_SPRING && element != EL_BALLOON)
+#endif
{
/* make sure that there is no move delay before next try to push */
+#if USE_NEW_MOVE_DELAY
+ if (game.engine_version >= VERSION_IDENT(3,0,7,1))
+ player->move_delay = 0;
+#else
if (game.engine_version >= VERSION_IDENT(3,0,7,1))
player->move_delay = INITIAL_MOVE_DELAY_OFF;
+#endif
return MF_NO_ACTION;
}
else
player->push_delay_value = -1; /* get new value later */
+#if USE_PUSH_BUGFIX
+ /* now: check for element change _after_ element has been pushed! */
+#if 1
+ if (game.use_change_when_pushing_bug)
+#else
+ if (game.engine_version < VERSION_IDENT(3,1,0,0))
+#endif
+ {
+ CheckElementChangeByPlayer(x, y, element, CE_PUSHED_BY_PLAYER,
+ player->index_bit, dig_side);
+ CheckTriggeredElementChangeByPlayer(x,y, element, CE_PLAYER_PUSHES_X,
+ player->index_bit, dig_side);
+ }
+
+#else
+
#if 1
/* check for element change _after_ element has been pushed! */
#else
#if 1
- /* !!! TEST ONLY !!! */
+ /* !!! TEST ONLY !!! */
CheckElementChangeByPlayer(x, y, element, CE_PUSHED_BY_PLAYER,
player->index_bit, dig_side);
- CheckTriggeredElementChangeByPlayer(x, y, element,CE_OTHER_GETS_PUSHED,
+ CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PUSHES_X,
player->index_bit, dig_side);
#else
- CheckTriggeredElementChangeByPlayer(x, y, element,CE_OTHER_GETS_PUSHED,
+ CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PUSHES_X,
player->index_bit, dig_side);
CheckElementChangeByPlayer(x, y, element, CE_PUSHED_BY_PLAYER,
player->index_bit, dig_side);
#endif
+#endif
+
#endif
break;
if (PLAYER_SWITCHING(player, x, y))
{
CheckTriggeredElementChangeByPlayer(x,y, element,
- CE_OTHER_GETS_PRESSED,
+ CE_PLAYER_PRESSES_X,
player->index_bit, dig_side);
return MF_ACTION;
Feld[x][y] = EL_LAMP_ACTIVE;
local_player->lights_still_needed--;
+ ResetGfxAnimation(x, y);
DrawLevelField(x, y);
}
else if (element == EL_TIME_ORB_FULL)
TimeLeft += 10;
DrawGameValue_Time(TimeLeft);
+ ResetGfxAnimation(x, y);
DrawLevelField(x, y);
#if 0
}
CheckTriggeredElementChangeByPlayer(x, y, element,
- CE_OTHER_IS_SWITCHING,
+ CE_SWITCH_OF_X,
player->index_bit, dig_side);
- CheckTriggeredElementChangeByPlayer(x,y, element,CE_OTHER_GETS_PRESSED,
+ CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PRESSES_X,
player->index_bit, dig_side);
return MF_ACTION;
CheckElementChangeByPlayer(x, y, element, CE_SWITCHED,
player->index_bit, dig_side);
CheckTriggeredElementChangeByPlayer(x, y, element,
- CE_OTHER_IS_SWITCHING,
+ CE_SWITCH_OF_X,
player->index_bit, dig_side);
#else
CheckTriggeredElementChangeByPlayer(x, y, element,
- CE_OTHER_IS_SWITCHING,
+ CE_SWITCH_OF_X,
player->index_bit, dig_side);
CheckElementChangeByPlayer(x, y, element, CE_SWITCHED,
player->index_bit, dig_side);
/* !!! TEST ONLY !!! (this breaks "machine", level 000) */
CheckElementChangeByPlayer(x, y, element, CE_PRESSED_BY_PLAYER,
player->index_bit, dig_side);
- CheckTriggeredElementChangeByPlayer(x,y, element,CE_OTHER_GETS_PRESSED,
+ CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PRESSES_X,
player->index_bit, dig_side);
#else
- CheckTriggeredElementChangeByPlayer(x,y, element,CE_OTHER_GETS_PRESSED,
+ CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_PRESSES_X,
player->index_bit, dig_side);
CheckElementChangeByPlayer(x, y, element, CE_PRESSED_BY_PLAYER,
player->index_bit, dig_side);
return MF_NO_ACTION;
}
+#if USE_NEW_PUSH_DELAY
+ player->push_delay = -1;
+#else
player->push_delay = 0;
+#endif
- if (Feld[x][y] != element) /* really digged/collected something */
- player->is_collecting = !player->is_digging;
+#if USE_PENGUIN_COLLECT_BUGFIX
+ if (is_player) /* function can also be called by EL_PENGUIN */
+#endif
+ {
+ if (Feld[x][y] != element) /* really digged/collected something */
+ player->is_collecting = !player->is_digging;
+ }
return MF_MOVING;
}
EL_DYNABOMB_PLAYER_1_ACTIVE + player->index_nr :
EL_UNDEFINED);
+#if USE_DROP_BUGFIX
+ /* do not drop an element on top of another element; when holding drop key
+ pressed without moving, dropped element must move away before the next
+ element can be dropped (this is especially important if the next element
+ is dynamite, which can be placed on background for historical reasons) */
+ if (PLAYER_DROPPING(player, dropx, dropy) && Feld[dropx][dropy] != EL_EMPTY)
+ return MF_ACTION;
+#endif
+
if (IS_THROWABLE(drop_element))
{
dropx += GET_DX_FROM_DIR(drop_direction);
#if 1
/* needed if previous element just changed to "empty" in the last frame */
- Changed[dropx][dropy] = 0; /* allow another change */
+ Changed[dropx][dropy] = FALSE; /* allow another change */
#endif
#if 1
CheckElementChangeByPlayer(dropx, dropy, new_element, CE_DROPPED_BY_PLAYER,
player->index_bit, drop_side);
CheckTriggeredElementChangeByPlayer(dropx, dropy, new_element,
- CE_OTHER_GETS_DROPPED,
+ CE_PLAYER_DROPS_X,
player->index_bit, drop_side);
#else
CheckTriggeredElementChangeByPlayer(dropx, dropy, new_element,
- CE_OTHER_GETS_DROPPED,
+ CE_PLAYER_DROPS_X,
player->index_bit, drop_side);
CheckElementChangeByPlayer(dropx, dropy, new_element, CE_DROPPED_BY_PLAYER,
player->index_bit, drop_side);
nexty = dropy + GET_DY_FROM_DIR(move_direction);
#if 1
- Changed[dropx][dropy] = 0; /* allow another change */
+ Changed[dropx][dropy] = FALSE; /* allow another change */
CheckCollision[dropx][dropy] = 2;
#else
/* !!! commented out from 3.1.0-4 to 3.1.0-5 !!! */
else
{
- Changed[dropx][dropy] = 0; /* allow another change */
+ Changed[dropx][dropy] = FALSE; /* allow another change */
#if 1
TestIfElementHitsCustomElement(dropx, dropy, move_direction);
player->is_dropping = TRUE;
+#if USE_DROP_BUGFIX
+ player->drop_x = dropx;
+ player->drop_y = dropy;
+#endif
return TRUE;
}
PlayMusic(MAP_NOCONF_MUSIC(level_nr)); /* from music dir */
}
+void PlayLevelSound_EM(int x, int y, int element_em, int sample)
+{
+ int element = (element_em > -1 ? map_element_EM_to_RND(element_em) : 0);
+
+#if 0
+ if (sample == SAMPLE_bug)
+ printf("::: PlayLevelSound_EM: %d, %d: %d\n", x, y, sample);
+#endif
+
+ switch (sample)
+ {
+ case SAMPLE_blank:
+ PlayLevelSoundElementAction(x, y, element, ACTION_WALKING);
+ break;
+
+ case SAMPLE_roll:
+ PlayLevelSoundElementAction(x, y, element, ACTION_PUSHING);
+ break;
+
+ case SAMPLE_stone:
+ PlayLevelSoundElementAction(x, y, element, ACTION_IMPACT);
+ break;
+
+ case SAMPLE_nut:
+ PlayLevelSoundElementAction(x, y, element, ACTION_IMPACT);
+ break;
+
+ case SAMPLE_crack:
+ PlayLevelSoundElementAction(x, y, element, ACTION_BREAKING);
+ break;
+
+ case SAMPLE_bug:
+ PlayLevelSoundElementAction(x, y, element, ACTION_MOVING);
+ break;
+
+ case SAMPLE_tank:
+ PlayLevelSoundElementAction(x, y, element, ACTION_MOVING);
+ break;
+
+ case SAMPLE_android_clone:
+ PlayLevelSoundElementAction(x, y, element, ACTION_DROPPING);
+ break;
+
+ case SAMPLE_android_move:
+ PlayLevelSoundElementAction(x, y, element, ACTION_MOVING);
+ break;
+
+ case SAMPLE_spring:
+ PlayLevelSoundElementAction(x, y, element, ACTION_IMPACT);
+ break;
+
+ case SAMPLE_slurp:
+ PlayLevelSoundElementAction(x, y, element, ACTION_SLURPED_BY_SPRING);
+ break;
+
+ case SAMPLE_eater:
+ PlayLevelSoundElementAction(x, y, element, ACTION_WAITING);
+ break;
+
+ case SAMPLE_eater_eat:
+ PlayLevelSoundElementAction(x, y, element, ACTION_DIGGING);
+ break;
+
+ case SAMPLE_alien:
+ PlayLevelSoundElementAction(x, y, element, ACTION_MOVING);
+ break;
+
+ case SAMPLE_collect:
+ PlayLevelSoundElementAction(x, y, element, ACTION_COLLECTING);
+ break;
+
+ case SAMPLE_diamond:
+ PlayLevelSoundElementAction(x, y, element, ACTION_IMPACT);
+ break;
+
+ case SAMPLE_squash:
+ /* !!! CHECK THIS !!! */
+#if 1
+ PlayLevelSoundElementAction(x, y, element, ACTION_BREAKING);
+#else
+ PlayLevelSoundElementAction(x, y, element, ACTION_SMASHED_BY_ROCK);
+#endif
+ break;
+
+ case SAMPLE_wonderfall:
+ PlayLevelSoundElementAction(x, y, element, ACTION_FILLING);
+ break;
+
+ case SAMPLE_drip:
+ PlayLevelSoundElementAction(x, y, element, ACTION_IMPACT);
+ break;
+
+ case SAMPLE_push:
+ PlayLevelSoundElementAction(x, y, element, ACTION_PUSHING);
+ break;
+
+ case SAMPLE_dirt:
+ PlayLevelSoundElementAction(x, y, element, ACTION_DIGGING);
+ break;
+
+ case SAMPLE_acid:
+ PlayLevelSoundElementAction(x, y, element, ACTION_SPLASHING);
+ break;
+
+ case SAMPLE_ball:
+ PlayLevelSoundElementAction(x, y, element, ACTION_DROPPING);
+ break;
+
+ case SAMPLE_grow:
+ PlayLevelSoundElementAction(x, y, element, ACTION_GROWING);
+ break;
+
+ case SAMPLE_wonder:
+ PlayLevelSoundElementAction(x, y, element, ACTION_ACTIVE);
+ break;
+
+ case SAMPLE_door:
+ PlayLevelSoundElementAction(x, y, element, ACTION_PASSING);
+ break;
+
+ case SAMPLE_exit_open:
+ PlayLevelSoundElementAction(x, y, element, ACTION_OPENING);
+ break;
+
+ case SAMPLE_exit_leave:
+ PlayLevelSoundElementAction(x, y, element, ACTION_PASSING);
+ break;
+
+ case SAMPLE_dynamite:
+ PlayLevelSoundElementAction(x, y, element, ACTION_DROPPING);
+ break;
+
+ case SAMPLE_tick:
+ PlayLevelSoundElementAction(x, y, element, ACTION_ACTIVE);
+ break;
+
+ case SAMPLE_press:
+ PlayLevelSoundElementAction(x, y, element, ACTION_ACTIVATING);
+ break;
+
+ case SAMPLE_wheel:
+ PlayLevelSoundElementAction(x, y, element, ACTION_ACTIVE);
+ break;
+
+ case SAMPLE_boom:
+ PlayLevelSoundElementAction(x, y, element, ACTION_EXPLODING);
+ break;
+
+ case SAMPLE_die:
+ PlayLevelSoundElementAction(x, y, element, ACTION_DYING);
+ break;
+
+ case SAMPLE_time:
+ PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MIDDLE);
+ break;
+
+ default:
+ PlayLevelSoundElementAction(x, y, element, ACTION_DEFAULT);
+ break;
+ }
+}
+
void RaiseScore(int value)
{
local_player->score += value;
case EL_KEY_2:
case EL_KEY_3:
case EL_KEY_4:
+ case EL_EM_KEY_1:
+ case EL_EM_KEY_2:
+ case EL_EM_KEY_3:
+ case EL_EM_KEY_4:
+ case EL_EMC_KEY_5:
+ case EL_EMC_KEY_6:
+ case EL_EMC_KEY_7:
+ case EL_EMC_KEY_8:
RaiseScore(level.score[SC_KEY]);
break;
default:
#include "main.h"
void GetPlayerConfig(void);
+
+void DrawGameValue_Time(int);
void DrawGameDoorValues(void);
+
void InitGameSound();
void InitGame(void);
+
+void UpdateEngineValues(int, int);
+
void InitMovDir(int, int);
void InitAmoebaNr(int, int);
void GameWon(void);
boolean DropElement(struct PlayerInfo *);
void InitPlayLevelSound();
+void PlayLevelSound_EM(int, int, int, int);
void RaiseScore(int);
void RaiseScoreElement(int);
--- /dev/null
+# =============================================================================
+# Rocks'n'Diamonds Makefile (game_em)
+# -----------------------------------------------------------------------------
+# (c) 1995-2005 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
+
+GAME_EM = game_em.a
+
+
+# -----------------------------------------------------------------------------
+# build targets
+# -----------------------------------------------------------------------------
+
+all: $(GAME_EM)
+
+$(GAME_EM): $(OBJS)
+ $(AR) cru $(GAME_EM) $(OBJS)
+ $(RANLIB) $(GAME_EM)
+
+.c.o:
+ $(CC) $(PROFILING) $(CFLAGS) -c $*.c
+
+clean:
+ $(RM) $(OBJS)
+ $(RM) $(GAME_EM)
+
+
+# -----------------------------------------------------------------------------
+# development only
+# -----------------------------------------------------------------------------
+
+depend:
+ for i in $(SRCS); do $(CPP) $(CFLAGS) -M $$i; done > .depend
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
--- /dev/null
+/* 2000-08-10T16:43:50Z
+ *
+ * cave data structures
+ */
+
+#include "global.h"
+#include "tile.h"
+#include "level.h"
+
+
+struct LevelInfo_EM native_em_level;
+
+void setLevelInfoToDefaults_EM(void)
+{
+ int i;
+
+ native_em_level.file_version = FILE_VERSION_EM_ACTUAL;
+
+ native_em_level.lev = &lev;
+ native_em_level.ply1 = &ply1;
+ native_em_level.ply2 = &ply2;
+
+ lev.width = 64;
+ lev.height = 32;
+
+ ply1.x_initial = 0;
+ ply1.y_initial = 0;
+
+ ply2.x_initial = 0;
+ ply2.y_initial = 0;
+
+ lev.lenses_cnt_initial = 0;
+ lev.magnify_cnt_initial = 0;
+
+ lev.wheel_cnt_initial = 0;
+ lev.wheel_x_initial = 1;
+ lev.wheel_y_initial = 1;
+
+ lev.wind_time = 9999;
+ lev.wind_cnt_initial = 0;
+
+ lev.wonderwall_state_initial = 0;
+ lev.wonderwall_time_initial = 0;
+
+ for (i = 0; i < TILE_MAX; i++)
+ lev.android_array[i] = Xblank;
+
+ lev.home_initial = 1; /* initial number of players in this level */
+
+ ply1.alive_initial = (lev.home_initial >= 1);
+ ply2.alive_initial = (lev.home_initial >= 2);
+}
+
+
+/* load cave
+ *
+ * completely initializes the level structure, ready for a game
+ */
+
+#define MAX_EM_LEVEL_SIZE 16384
+
+boolean LoadNativeLevel_EM(char *filename)
+{
+ unsigned char raw_leveldata[MAX_EM_LEVEL_SIZE];
+ int raw_leveldata_length;
+ int file_version;
+ FILE *file;
+
+ /* always start with reliable default values */
+ setLevelInfoToDefaults_EM();
+
+ if (!(file = fopen(filename, MODE_READ)))
+ {
+ Error(ERR_WARN, "cannot open level '%s' -- using empty level", filename);
+
+ return FALSE;
+ }
+
+ raw_leveldata_length = fread(raw_leveldata, 1, MAX_EM_LEVEL_SIZE, file);
+
+ fclose(file);
+
+ if (raw_leveldata_length <= 0)
+ {
+ Error(ERR_WARN, "cannot read level '%s' -- using empty level", filename);
+
+ return FALSE;
+ }
+
+ if (!(file_version = cleanup_em_level(raw_leveldata, raw_leveldata_length)))
+ {
+ Error(ERR_WARN, "unknown EM level '%s' -- using empty level", filename);
+
+ return FALSE;
+ }
+
+ convert_em_level(raw_leveldata, file_version);
+ prepare_em_level();
+
+ return TRUE;
+}
--- /dev/null
+/* 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.
+ */
+
+#include "global.h"
+#include "tile.h"
+#include "level.h"
+
+
+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 cleanup_em_level(unsigned char *src, int length)
+{
+ int file_version = 0;
+ int i;
+
+ if (length >= 2172 &&
+ src[2106] == 255 &&
+ src[2107] == 54 &&
+ src[2108] == 48 &&
+ src[2109] == 48)
+ {
+ /* ---------- this cave has V6 file format ---------- */
+ file_version = FILE_VERSION_EM_V6;
+
+ 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]];
+ }
+ else if (length >= 2110 &&
+ src[2106] == 255 &&
+ src[2107] == 53 &&
+ src[2108] == 48 &&
+ src[2109] == 48)
+ {
+ /* ---------- this cave has V5 file format ---------- */
+ file_version = FILE_VERSION_EM_V5;
+
+ 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];
+ }
+#if 0
+ else if (length >= 2106) /* !!! TEST ONLY: SHOW BROKEN LEVELS !!! */
+#else
+ else if (length >= 2106 &&
+ src[1983] == 116)
+#endif
+ {
+ /* ---------- this cave has V4 file format ---------- */
+ file_version = FILE_VERSION_EM_V4;
+
+ 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];
+ }
+ else if (length >= 2106 &&
+ src[0] == 241 &&
+ src[1983] == 27)
+ {
+ unsigned char j = 94;
+
+ /* ---------- this cave has V3 file format ---------- */
+ file_version = FILE_VERSION_EM_V3;
+
+ 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];
+ }
+#if 1
+ else if (length >= 2106 &&
+ src[0] == 245 &&
+ src[1983] == 27)
+ {
+ unsigned char j = 94;
+
+ /* ---------- this cave has V3 file format ---------- */
+ file_version = FILE_VERSION_EM_V3;
+
+ 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];
+ }
+#endif
+ else
+ {
+ /* ---------- this cave has unknown file format ---------- */
+
+#if 1
+ printf("::: %d, %d\n", src[0], src[1983]);
+#endif
+
+ return 0;
+ }
+
+ if (file_version < FILE_VERSION_EM_V6)
+ {
+ /* id */
+ src[2106] = 255;
+ src[2107] = 54;
+ src[2108] = 48;
+ src[2109] = 48;
+
+ /* time */
+ i = src[2094] * 10;
+ src[2110] = i >> 8;
+ src[2111] = i;
+
+ for (i = 2148; i < 2172; i++)
+ src[i] = 0;
+
+ /* ball data */
+ src[2159] = 128;
+ }
+
+ /* ---------- at this stage, the cave data always has V6 format ---------- */
+
+ /* fix wheel */
+ for (i = 0; i < 2048; i++)
+ if (src[i] == 40)
+ break;
+ for (i++; i < 2048; i++)
+ if (src[i] == 40)
+ src[i] = 147;
+
+#if 0
+ /* fix acid */
+ for (i = 64; i < 2048; i++)
+ if (src[i] == 63) /* replace element above 'Xacid_s' ... */
+ src[i - 64] = 101; /* ... with 'Xacid_1' */
+
+#else
+
+ /* fix acid */
+ for (i = 64; i < 2048; i++)
+ {
+ if (src[i] == 63) /* 'Xacid_s' (acid pool, bottom middle) */
+ {
+ if (file_version == FILE_VERSION_EM_V4 &&
+ i < 2048 - 64 && src[i + 64] == 63)
+ src[i - 64] = 255; /* replace element above with 'Xfake_acid_1' */
+ else
+ src[i - 64] = 101; /* replace element above with 'Xacid_1' */
+ }
+ }
+#endif
+
+ /* fix acid in eater 1 */
+ for (i = 2051; i < 2057; i++)
+ if (src[i] == 63)
+ src[i - 3] = 101;
+
+ /* fix acid in eater 2 */
+ for (i = 2060; i < 2066; i++)
+ if (src[i] == 63)
+ src[i - 3] = 101;
+
+ /* fix acid in eater 3 */
+ for (i = 2069; i < 2075; i++)
+ if (src[i] == 63)
+ src[i - 3] = 101;
+
+ /* fix acid in eater 4 */
+ for (i = 2078; i < 2084; i++)
+ if (src[i] == 63)
+ src[i - 3] = 101;
+
+ /* fix acid in eater 5 */
+ for (i = 2115; i < 2121; i++)
+ if (src[i] == 63)
+ src[i - 3] = 101;
+
+ /* fix acid in eater 6 */
+ for (i = 2124; i < 2130; i++)
+ if (src[i] == 63)
+ src[i - 3] = 101;
+
+ /* fix acid in eater 7 */
+ for (i = 2133; i < 2139; i++)
+ if (src[i] == 63)
+ src[i - 3] = 101;
+
+ /* fix acid in eater 8 */
+ for (i = 2142; i < 2148; i++)
+ if (src[i] == 63)
+ src[i - 3] = 101;
+
+ /* old style time */
+ src[2094] = 0;
+
+ /* player 1 pos */
+ src[2096] &= 7;
+ src[src[2096] << 8 | src[2097]] = 128;
+
+ /* player 2 pos */
+ src[2098] &= 7;
+ src[src[2098] << 8 | src[2099]] = 128;
+
+ /* amoeba speed */
+ if ((src[2100] << 8 | src[2101]) > 9999)
+ {
+ src[2100] = 39;
+ src[2101] = 15;
+ }
+
+ /* time wonderwall */
+ if ((src[2102] << 8 | src[2103]) > 9999)
+ {
+ src[2102] = 39;
+ src[2103] = 15;
+ }
+
+ /* time */
+ if ((src[2110] << 8 | src[2111]) > 9999)
+ {
+ src[2110] = 39;
+ src[2111] = 15;
+ }
+
+ /* wind direction */
+ i = src[2149];
+ i &= 15;
+ i &= -i;
+ src[2149] = i;
+
+ /* time lenses */
+ if ((src[2154] << 8 | src[2155]) > 9999)
+ {
+ src[2154] = 39;
+ src[2155] = 15;
+ }
+
+ /* time magnify */
+ if ((src[2156] << 8 | src[2157]) > 9999)
+ {
+ src[2156] = 39;
+ src[2157] = 15;
+ }
+
+ /* ball object */
+ src[2158] = 0;
+ src[2159] = remap_v6[src[2159]];
+
+ /* ball pause */
+ if ((src[2160] << 8 | src[2161]) > 9999)
+ {
+ src[2160] = 39;
+ src[2161] = 15;
+ }
+
+ /* ball data */
+ src[2162] &= 129;
+ if (src[2162] & 1)
+ src[2163] = 0;
+
+ /* android move pause */
+ if ((src[2164] << 8 | src[2165]) > 9999)
+ {
+ src[2164] = 39;
+ src[2165] = 15;
+ }
+
+ /* android clone pause */
+ if ((src[2166] << 8 | src[2167]) > 9999)
+ {
+ src[2166] = 39;
+ src[2167] = 15;
+ }
+
+ /* android data */
+ src[2168] &= 31;
+
+ /* size of v6 cave */
+ length = 2172;
+
+#if 1
+ if (options.debug)
+ printf("::: EM level file version: %d\n", file_version);
+#endif
+
+ return file_version;
+}
+
+/* 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
+ * break 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 (this breaks cave 0 in
+ * downunder mine 16)
+ *
+ * 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) don't 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.
+ */
+
+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, Xamoeba_1, Xamoeba_2,
+ Xamoeba_3, Xamoeba_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,
+#if 0
+ Xblank, Xblank, Xblank, Xblank,
+#else
+ /* special elements added to solve compatibility problems */
+ Xblank, Xblank, Xblank, Xfake_acid_1
+#endif
+};
+
+void convert_em_level(unsigned char *src, int file_version)
+{
+ static int eater_offset[8] =
+ {
+ 0x800, 0x809, 0x812, 0x81B, 0x840, 0x849, 0x852, 0x85B
+ };
+ unsigned int i, x, y, temp;
+
+#if 1
+ lev.time_seconds = src[0x83E] << 8 | src[0x83F];
+ if (lev.time_seconds > 9999)
+ lev.time_seconds = 9999;
+#else
+ temp = ((src[0x83E] << 8 | src[0x83F]) * 25 + 3) / 4;
+ if (temp == 0 || temp > 9999)
+ temp = 9999;
+ lev.time_initial = temp;
+#endif
+
+ lev.required_initial = src[0x82F];
+
+ temp = src[0x830] << 8 | src[0x831];
+ ply1.x_initial = (temp & 63) + 1;
+ ply1.y_initial = (temp >> 6 & 31) + 1;
+ temp = src[0x832] << 8 | src[0x833];
+ ply2.x_initial = (temp & 63) + 1;
+ ply2.y_initial = (temp >> 6 & 31) + 1;
+
+ temp = (src[0x834] << 8 | src[0x835]) * 28;
+ if (temp > 9999)
+ temp = 9999;
+ lev.amoeba_time = temp;
+
+ lev.android_move_time = src[0x874] << 8 | src[0x875];
+ lev.android_clone_time = src[0x876] << 8 | src[0x877];
+
+ lev.ball_random = src[0x872] & 1 ? 1 : 0;
+ lev.ball_state_initial = src[0x872] & 128 ? 1 : 0;
+ lev.ball_time = src[0x870] << 8 | src[0x871];
+
+ lev.emerald_score = src[0x824];
+ lev.diamond_score = src[0x825];
+ lev.alien_score = src[0x826];
+ lev.tank_score = src[0x827];
+ lev.bug_score = src[0x828];
+ lev.eater_score = src[0x829];
+ lev.nut_score = src[0x82A];
+ lev.dynamite_score = src[0x82B];
+ lev.key_score = src[0x82C];
+ lev.exit_score = src[0x82D] * 8 / 5;
+ lev.lenses_score = src[0x867];
+ lev.magnify_score = src[0x868];
+ lev.slurp_score = src[0x869];
+
+ lev.lenses_time = src[0x86A] << 8 | src[0x86B];
+ lev.magnify_time = src[0x86C] << 8 | src[0x86D];
+ lev.wheel_time = src[0x838] << 8 | src[0x839];
+
+ lev.wind_cnt_initial = src[0x865] & 15 ? lev.wind_time : 0;
+ temp = src[0x865];
+ lev.wind_direction_initial = (temp & 8 ? 0 :
+ temp & 1 ? 1 :
+ temp & 2 ? 2 :
+ temp & 4 ? 3 : 0);
+
+ lev.wonderwall_time_initial = src[0x836] << 8 | src[0x837];
+
+ for (i = 0; i < 8; i++)
+ for (x = 0; x < 9; x++)
+ lev.eater_array[i][x] = remap_emerald[src[eater_offset[i] + 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; /* southeast */
+ lev.ball_array[y][5] = (src[0x873] & 32) ? temp : Xblank; /* southwest */
+ lev.ball_array[y][2] = (src[0x873] & 64) ? temp : Xblank; /* northeast */
+ lev.ball_array[y][0] = (src[0x873] & 128)? temp : Xblank; /* northwest */
+ }
+ }
+
+ 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[Xamoeba_1] =
+ lev.android_array[Xamoeba_2] =
+ lev.android_array[Xamoeba_3] =
+ lev.android_array[Xamoeba_4] =
+ lev.android_array[Xamoeba_5] =
+ lev.android_array[Xamoeba_6] =
+ lev.android_array[Xamoeba_7] =
+ lev.android_array[Xamoeba_8] = Xdrip_eat;
+ }
+
+ if (temp & 4096)
+ {
+ lev.android_array[Xdynamite] = Xdynamite;
+ }
+
+ for (temp = 1; temp < 2047; temp++)
+ {
+ switch (src[temp])
+ {
+ case 0x24: /* wonderwall */
+ lev.wonderwall_state_initial = 1;
+ lev.wonderwall_time_initial = 9999;
+ break;
+
+ case 0x28: /* wheel */
+ lev.wheel_x_initial = temp & 63;
+ lev.wheel_y_initial = temp >> 6;
+ lev.wheel_cnt_initial = lev.wheel_time;
+ break;
+
+#ifndef BAD_ROLL
+ case 0x63: /* spring roll left */
+ src[temp - 1] = 0x45;
+ src[temp] = 0x80;
+ break;
+
+ case 0x64: /* spring roll right */
+ src[temp + 1] = 0x45;
+ src[temp] = 0x80;
+ break;
+
+ case 0x72: /* nut roll left */
+ src[temp - 1] = 0x25;
+ src[temp] = 0x80;
+ break;
+
+ case 0x73: /* nut roll right */
+ src[temp + 1] = 0x25;
+ src[temp] = 0x80;
+ break;
+
+ case 0x77: /* bomb roll left */
+ src[temp - 1] = 0x10;
+ src[temp] = 0x80;
+ break;
+
+ case 0x78: /* bomb roll right */
+ src[temp + 1] = 0x10;
+ src[temp] = 0x80;
+ break;
+
+ case 0x79: /* stone roll left */
+ src[temp - 1] = 0x00;
+ src[temp] = 0x80;
+ break;
+
+ case 0x7A: /* stone roll right */
+ src[temp + 1] = 0x00;
+ src[temp] = 0x80;
+ break;
+#endif
+
+ case 0xA3: /* fake blank */
+ lev.lenses_cnt_initial = 9999;
+ break;
+
+ case 0xA4: /* fake grass */
+ lev.magnify_cnt_initial = 9999;
+ break;
+ }
+ }
+
+ /* first fill the complete playfield with the default border element */
+ for (y = 0; y < HEIGHT; y++)
+ for (x = 0; x < WIDTH; x++)
+ native_em_level.cave[x][y] = ZBORDER;
+
+ /* then copy the real level contents from level file into the playfield */
+ temp = 0;
+ for (y = 0; y < lev.height; y++)
+ for (x = 0; x < lev.width; x++)
+ native_em_level.cave[x + 1][y + 1] = remap_emerald[src[temp++]];
+
+ /* at last, set the two players at their positions in the playfield */
+ if (ply1.alive_initial)
+ native_em_level.cave[ply1.x_initial][ply1.y_initial] = Zplayer;
+ if (ply2.alive_initial)
+ native_em_level.cave[ply2.x_initial][ply2.y_initial] = Zplayer;
+
+ native_em_level.file_version = file_version;
+}
+
+void prepare_em_level(void)
+{
+ unsigned int x, y;
+
+ /* reset all runtime variables to their initial values */
+
+ for (y = 0; y < HEIGHT; y++)
+ for (x = 0; x < WIDTH; x++)
+ Cave[y][x] = native_em_level.cave[x][y];
+
+ 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];
+
+#if 1
+ lev.time_initial = lev.time_seconds;
+#else
+ lev.time_initial = (lev.time_seconds * 50 + 7) / 8;
+#endif
+ lev.time = lev.time_initial;
+
+ lev.required = lev.required_initial;
+ lev.score = 0;
+
+ lev.android_move_cnt = lev.android_move_time;
+ lev.android_clone_cnt = lev.android_clone_time;
+
+ lev.ball_pos = 0;
+ lev.ball_state = lev.ball_state_initial;
+ lev.ball_cnt = lev.ball_time;
+
+ lev.eater_pos = 0;
+ lev.shine_cnt = 0;
+
+ lev.lenses_cnt = lev.lenses_cnt_initial;
+ lev.magnify_cnt = lev.magnify_cnt_initial;
+
+ lev.wheel_cnt = lev.wheel_cnt_initial;
+ lev.wheel_x = lev.wheel_x_initial;
+ lev.wheel_y = lev.wheel_y_initial;
+
+ lev.wind_cnt = lev.wind_cnt_initial;
+ lev.wind_direction = lev.wind_direction_initial;
+
+ lev.wonderwall_state = lev.wonderwall_state_initial;
+ lev.wonderwall_time = lev.wonderwall_time_initial;
+
+ lev.home = lev.home_initial;
+
+ lev.killed_out_of_time = FALSE;
+
+ ply1.num = 0;
+ ply1.alive = ply1.alive_initial;
+ ply1.dynamite = 0;
+ ply1.dynamite_cnt = 0;
+ ply1.keys = 0;
+ ply1.anim = 0;
+ ply1.oldx = ply1.x = ply1.x_initial;
+ ply1.oldy = ply1.y = ply1.y_initial;
+ ply1.last_move_dir = MV_NO_MOVING;
+ ply1.joy_n = ply1.joy_e = ply1.joy_s = ply1.joy_w = 0;
+ ply1.joy_snap = ply1.joy_drop = 0;
+ ply1.joy_stick = ply1.joy_spin = 0;
+
+ ply2.num = 1;
+ ply2.alive = ply2.alive_initial;
+ ply2.dynamite = 0;
+ ply2.dynamite_cnt = 0;
+ ply2.keys = 0;
+ ply2.anim = 0;
+ ply2.oldx = ply2.x = ply2.x_initial;
+ ply2.oldy = ply2.y = ply2.y_initial;
+ ply2.last_move_dir = MV_NO_MOVING;
+ ply2.joy_n = ply2.joy_e = ply2.joy_s = ply2.joy_w = 0;
+ ply2.joy_snap = ply1.joy_drop = 0;
+ ply2.joy_stick = ply2.joy_spin = 0;
+}
--- /dev/null
+#ifndef DISPLAY_H
+#define DISPLAY_H
+
+#include "main_em.h"
+
+#define ORIG_TILEX 16
+#define ORIG_TILEY 16
+#define ORIG_SCOREX 8
+#define ORIG_SCOREY 9
+#define ORIG_GFXMENUFONTX 14
+#define ORIG_GFXMENUFONTY 16
+#define ORIG_MENUFONTX 12
+#define ORIG_MENUFONTY 16
+
+#define ZOOM_FACTOR 2
+
+#define TILEX (ORIG_TILEX * ZOOM_FACTOR)
+#define TILEY (ORIG_TILEY * ZOOM_FACTOR)
+#define SCOREX (ORIG_SCOREX * ZOOM_FACTOR)
+#define SCOREY (ORIG_SCOREY * ZOOM_FACTOR)
+#define GFXMENUFONTX (ORIG_GFXMENUFONTX * ZOOM_FACTOR)
+#define GFXMENUFONTY (ORIG_GFXMENUFONTY * ZOOM_FACTOR)
+#define MENUFONTX (ORIG_MENUFONTX * ZOOM_FACTOR)
+#define MENUFONTY (ORIG_MENUFONTY * ZOOM_FACTOR)
+
+#define ORIG_SCR_MENUX 20
+#define ORIG_SCR_MENUY 12
+#define SCR_MENUX 17
+#define SCR_MENUY 12
+#define SCR_FIELDX 17
+#define SCR_FIELDY 17
+#define MAX_BUF_XSIZE (SCR_FIELDX + 2)
+#define MAX_BUF_YSIZE (SCR_FIELDY + 2)
+
+/* often used screen positions */
+#define ORIG_MENU_SX ((ORIG_SCR_MENUX - SCR_MENUX) * TILEX / 2)
+#define ORIG_MENU_SY 0
+#define SY 8
+#define SX 8
+#define SY 8
+#define SXSIZE (SCR_FIELDX * TILEX)
+#define SYSIZE (SCR_FIELDY * TILEY)
+
+#if 1
+#define FRAMES_PER_SECOND 50
+
+#define ROUNDED_DIVIDE(x, y) (((x) + (y) - 1) / (y))
+
+#define SECONDS_TO_FRAMES(x) ((x) * FRAMES_PER_SECOND)
+#define FRAMES_TO_SECONDS(x) ((x) / FRAMES_PER_SECOND)
+
+#define SECONDS_TO_CYCLES(x) ROUNDED_DIVIDE((x) * FRAMES_PER_SECOND, 8)
+#define CYCLES_TO_SECONDS(x) ROUNDED_DIVIDE((x) * 8, FRAMES_PER_SECOND)
+
+#define DISPLAY_TIME(x) ROUNDED_DIVIDE(x, FRAMES_PER_SECOND)
+
+#else
+
+#define DISPLAY_TIME(x) (((x) * 8 + 49) / 50)
+#endif
+
+extern Bitmap *screenBitmap;
+extern Bitmap *scoreBitmap;
+
+extern Bitmap *objBitmap;
+extern Bitmap *sprBitmap;
+extern Bitmap *ttlBitmap;
+extern Bitmap *botBitmap;
+
+extern Pixmap screenPixmap;
+extern Pixmap scorePixmap;
+extern Pixmap spriteBitmap;
+
+extern Pixmap objmaskBitmap;
+extern Pixmap sprmaskBitmap;
+
+extern GC spriteGC;
+
+#endif
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2002 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* game_em.h *
+***********************************************************/
+
+#ifndef GAME_EM_H
+#define GAME_EM_H
+
+#define GAME_EM_VERSION_1_0_0
+
+
+/* ========================================================================= */
+/* functions and definitions exported from game_em to main program */
+/* ========================================================================= */
+
+#include "main_em.h"
+
+extern struct GlobalInfo_EM global_em_info;
+extern struct LevelInfo_EM native_em_level;
+extern struct GraphicInfo_EM graphic_info_em_object[TILE_MAX][8];
+extern struct GraphicInfo_EM graphic_info_em_player[2][SPR_MAX][8];
+
+extern void em_open_all();
+extern void em_close_all();
+
+extern void InitGameEngine_EM();
+extern void GameActions_EM(byte);
+
+extern unsigned int InitEngineRND_EM(long);
+
+extern void setLevelInfoToDefaults_EM();
+extern boolean LoadNativeLevel_EM(char *);
+
+extern void BlitScreenToBitmap_EM(Bitmap *);
+extern void RedrawPlayfield_EM();
+extern void DrawGameDoorValues_EM();
+
+#endif /* GAME_EM_H */
--- /dev/null
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#include "main_em.h"
+
+#define EM_GFX_DIR "graphics.EM"
+#define EM_SND_DIR "sounds.EM"
+#define EM_LVL_DIR "levels.EM"
+
+/* arbitrary maximum length of filenames (cos i am lazy) */
+#define MAXNAME 1024
+
+extern int debug;
+extern char *progname;
+extern char *arg_basedir;
+
+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(byte);
+void input_eventloop(void);
+
+void blitscreen(void);
+void game_initscreen(void);
+void game_animscreen(void);
+
+void DrawGameDoorValues_EM();
+
+void play_sound(int, int, int);
+void sound_play(void);
+
+int cave_convert(char *);
+boolean LoadNativeLevel_EM(char *);
+
+void game_init_vars(void);
+void game_play_init(int, char *);
+void game_loop(byte);
+
+void synchro_1(void);
+void synchro_2(void);
+void synchro_3(void);
+
+int cleanup_em_level(unsigned char *, int);
+void convert_em_level(unsigned char *, int);
+void prepare_em_level(void);
+
+int sound_thread(void);
+int read_sample(char *, short **, long *);
+
+void read_cave_list(void);
+void free_cave_list(void);
+
+#endif
--- /dev/null
+/* 2000-08-13T14:36:17Z
+ *
+ * graphics manipulation crap
+ */
+
+#include "global.h"
+#include "display.h"
+#include "level.h"
+
+
+unsigned int frame; /* current screen frame */
+unsigned int screen_x; /* current scroll position */
+unsigned int screen_y;
+
+/* tiles currently on screen */
+static unsigned int screentiles[MAX_BUF_YSIZE][MAX_BUF_XSIZE];
+static unsigned int crumbled_state[MAX_BUF_YSIZE][MAX_BUF_XSIZE];
+
+
+/* copy the entire screen to the window at the scroll position
+ *
+ * perhaps use mit-shm to speed this up
+ */
+
+void BlitScreenToBitmap_EM(Bitmap *target_bitmap)
+{
+ unsigned int x = screen_x % (MAX_BUF_XSIZE * TILEX);
+ unsigned int y = screen_y % (MAX_BUF_YSIZE * TILEY);
+
+ if (x < 2 * TILEX && y < 2 * TILEY)
+ {
+ BlitBitmap(screenBitmap, target_bitmap, x, y,
+ SCR_FIELDX * TILEX, SCR_FIELDY * TILEY, SX, SY);
+ }
+ else if (x < 2 * TILEX && y >= 2 * TILEY)
+ {
+ BlitBitmap(screenBitmap, target_bitmap, x, y,
+ SCR_FIELDX * TILEX, MAX_BUF_YSIZE * TILEY - y,
+ SX, SY);
+ BlitBitmap(screenBitmap, target_bitmap, x, 0,
+ SCR_FIELDX * TILEX, y - 2 * TILEY,
+ SX, SY + MAX_BUF_YSIZE * TILEY - y);
+ }
+ else if (x >= 2 * TILEX && y < 2 * TILEY)
+ {
+ BlitBitmap(screenBitmap, target_bitmap, x, y,
+ MAX_BUF_XSIZE * TILEX - x, SCR_FIELDY * TILEY,
+ SX, SY);
+ BlitBitmap(screenBitmap, target_bitmap, 0, y,
+ x - 2 * TILEX, SCR_FIELDY * TILEY,
+ SX + MAX_BUF_XSIZE * TILEX - x, SY);
+ }
+ else
+ {
+ BlitBitmap(screenBitmap, target_bitmap, x, y,
+ MAX_BUF_XSIZE * TILEX - x, MAX_BUF_YSIZE * TILEY - y,
+ SX, SY);
+ BlitBitmap(screenBitmap, target_bitmap, 0, y,
+ x - 2 * TILEX, MAX_BUF_YSIZE * TILEY - y,
+ SX + MAX_BUF_XSIZE * TILEX - x, SY);
+ BlitBitmap(screenBitmap, target_bitmap, x, 0,
+ MAX_BUF_XSIZE * TILEX - x, y - 2 * TILEY,
+ SX, SY + MAX_BUF_YSIZE * TILEY - y);
+ BlitBitmap(screenBitmap, target_bitmap, 0, 0,
+ x - 2 * TILEX, y - 2 * TILEY,
+ SX + MAX_BUF_XSIZE * TILEX - x, SY + MAX_BUF_YSIZE * TILEY - y);
+ }
+}
+
+void blitscreen(void)
+{
+ BlitScreenToBitmap_EM(window);
+}
+
+static void DrawLevelField_EM(int x, int y, int sx, int sy,
+ boolean draw_masked)
+{
+ int tile = Draw[y][x];
+ struct GraphicInfo_EM *g = &graphic_info_em_object[tile][frame];
+ int src_x = g->src_x + g->src_offset_x;
+ int src_y = g->src_y + g->src_offset_y;
+ int dst_x = sx * TILEX + g->dst_offset_x;
+ int dst_y = sy * TILEY + g->dst_offset_y;
+ int width = g->width;
+ int height = g->height;
+
+ if (draw_masked)
+ {
+ if (width > 0 && height > 0)
+ {
+ SetClipOrigin(g->bitmap, g->bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(g->bitmap, screenBitmap,
+ src_x, src_y, width, height, dst_x, dst_y);
+ }
+ }
+ else
+ {
+ if ((width != TILEX || height != TILEY) && !g->preserve_background)
+ ClearRectangle(screenBitmap, sx * TILEX, sy * TILEY, TILEX, TILEY);
+
+ if (width > 0 && height > 0)
+ BlitBitmap(g->bitmap, screenBitmap,
+ src_x, src_y, width, height, dst_x, dst_y);
+ }
+}
+
+static void DrawLevelFieldCrumbled_EM(int x, int y, int sx, int sy,
+ int crm, boolean draw_masked)
+{
+ int tile = Draw[y][x];
+ struct GraphicInfo_EM *g = &graphic_info_em_object[tile][frame];
+ unsigned int i;
+
+ if (crm == 0) /* no crumbled edges for this tile */
+ return;
+
+ for (i = 0; i < 4; i++)
+ {
+ if (crm & (1 << i))
+ {
+ int width, height, cx, cy;
+
+ if (i == 1 || i == 2)
+ {
+ width = g->crumbled_border_size;
+ height = TILEY;
+ cx = (i == 2 ? TILEX - g->crumbled_border_size : 0);
+ cy = 0;
+ }
+ else
+ {
+ width = TILEX;
+ height = g->crumbled_border_size;
+ cx = 0;
+ cy = (i == 3 ? TILEY - g->crumbled_border_size : 0);
+ }
+
+ if (width > 0 && height > 0)
+ {
+ int src_x = g->crumbled_src_x + cx;
+ int src_y = g->crumbled_src_y + cy;
+ int dst_x = sx * TILEX + cx;
+ int dst_y = sy * TILEY + cy;
+
+ if (draw_masked)
+ {
+ SetClipOrigin(g->crumbled_bitmap, g->crumbled_bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(g->crumbled_bitmap, screenBitmap,
+ src_x, src_y, width, height, dst_x, dst_y);
+ }
+ else
+ BlitBitmap(g->crumbled_bitmap, screenBitmap,
+ src_x, src_y, width, height, dst_x, dst_y);
+ }
+ }
+ }
+}
+
+static void DrawLevelPlayer_EM(int x1, int y1, int player_nr, int anim,
+ boolean draw_masked)
+{
+ struct GraphicInfo_EM *g = &graphic_info_em_player[player_nr][anim][frame];
+
+ int src_x = g->src_x, src_y = g->src_y;
+ int dst_x, dst_y;
+
+ if (draw_masked)
+ {
+ /* draw the player to current location */
+ dst_x = x1;
+ dst_y = y1;
+ SetClipOrigin(g->bitmap, g->bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(g->bitmap, screenBitmap,
+ src_x, src_y, TILEX, TILEY, dst_x, dst_y);
+
+ /* draw the player to opposite wrap-around column */
+ dst_x = x1 - MAX_BUF_XSIZE * TILEX;
+ dst_y = y1;
+ SetClipOrigin(g->bitmap, g->bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(g->bitmap, screenBitmap,
+ g->src_x, g->src_y, TILEX, TILEY, dst_x, dst_y);
+
+ /* draw the player to opposite wrap-around row */
+ dst_x = x1;
+ dst_y = y1 - MAX_BUF_YSIZE * TILEY;
+ SetClipOrigin(g->bitmap, g->bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(g->bitmap, screenBitmap,
+ g->src_x, g->src_y, TILEX, TILEY, dst_x, dst_y);
+ }
+ else
+ {
+ /* draw the player to current location */
+ dst_x = x1;
+ dst_y = y1;
+ BlitBitmap(g->bitmap, screenBitmap,
+ g->src_x, g->src_y, TILEX, TILEY, dst_x, dst_y);
+
+ /* draw the player to opposite wrap-around column */
+ dst_x = x1 - MAX_BUF_XSIZE * TILEX;
+ dst_y = y1;
+ BlitBitmap(g->bitmap, screenBitmap,
+ g->src_x, g->src_y, TILEX, TILEY, dst_x, dst_y);
+
+ /* draw the player to opposite wrap-around row */
+ dst_x = x1;
+ dst_y = y1 - MAX_BUF_YSIZE * TILEY;
+ BlitBitmap(g->bitmap, screenBitmap,
+ g->src_x, g->src_y, TILEX, TILEY, dst_x, dst_y);
+ }
+}
+
+/* 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, i;
+ unsigned int left = screen_x / TILEX;
+ unsigned int top = screen_y / TILEY;
+ static int xy[4][2] =
+ {
+ { 0, -1 },
+ { -1, 0 },
+ { +1, 0 },
+ { 0, +1 }
+ };
+
+ for (y = top; y < top + MAX_BUF_YSIZE; y++)
+ {
+ for (x = left; x < left + MAX_BUF_XSIZE; x++)
+ {
+ int sx = x % MAX_BUF_XSIZE;
+ int sy = y % MAX_BUF_YSIZE;
+ int tile = Draw[y][x];
+ struct GraphicInfo_EM *g = &graphic_info_em_object[tile][frame];
+ unsigned int obj = g->unique_identifier;
+ unsigned int crm = 0;
+
+ /* re-calculate crumbled state of this tile */
+ if (g->has_crumbled_graphics)
+ {
+ for (i = 0; i < 4; i++)
+ {
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
+ int tile_next;
+
+ if (xx < 0 || xx >= EM_MAX_CAVE_WIDTH ||
+ yy < 0 || yy >= EM_MAX_CAVE_HEIGHT)
+ continue;
+
+ tile_next = Draw[yy][xx];
+
+ if (!graphic_info_em_object[tile_next][frame].has_crumbled_graphics)
+ crm |= (1 << i);
+ }
+ }
+
+ /* only redraw screen tiles if they (or their crumbled state) changed */
+ if (screentiles[sy][sx] != obj || crumbled_state[sy][sx] != crm)
+ {
+ DrawLevelField_EM(x, y, sx, sy, FALSE);
+ DrawLevelFieldCrumbled_EM(x, y, sx, sy, crm, FALSE);
+
+ screentiles[sy][sx] = obj;
+ crumbled_state[sy][sx] = crm;
+ }
+ }
+ }
+}
+
+
+/* blit players to the screen
+ *
+ * handles transparency and movement
+ */
+
+static void blitplayer(struct PLAYER *ply)
+{
+ unsigned int x1, y1, x2, y2;
+
+ if (!ply->alive)
+ return;
+
+ /* x1/y1 are left/top and x2/y2 are right/down part of the player movement */
+ x1 = (frame * ply->oldx + (8 - frame) * ply->x) * TILEX / 8;
+ y1 = (frame * ply->oldy + (8 - frame) * ply->y) * TILEY / 8;
+ x2 = x1 + TILEX - 1;
+ y2 = y1 + TILEY - 1;
+
+ if ((unsigned int)(x2 - screen_x) < ((MAX_BUF_XSIZE - 1) * TILEX - 1) &&
+ (unsigned int)(y2 - screen_y) < ((MAX_BUF_YSIZE - 1) * TILEY - 1))
+ {
+ /* some casts to "int" are needed because of negative calculation values */
+ int dx = (int)ply->x - (int)ply->oldx;
+ int dy = (int)ply->y - (int)ply->oldy;
+ int old_x = (int)ply->oldx + (7 - (int)frame) * dx / 8;
+ int old_y = (int)ply->oldy + (7 - (int)frame) * dy / 8;
+ int new_x = old_x + SIGN(dx);
+ int new_y = old_y + SIGN(dy);
+ int old_sx = old_x % MAX_BUF_XSIZE;
+ int old_sy = old_y % MAX_BUF_XSIZE;
+ int new_sx = new_x % MAX_BUF_XSIZE;
+ int new_sy = new_y % MAX_BUF_XSIZE;
+#if 0
+ int old_crm = crumbled_state[old_sy][old_sx];
+#endif
+ int new_crm = crumbled_state[new_sy][new_sx];
+
+ /* only diggable elements can be crumbled in the classic EM engine */
+ boolean player_is_digging = (new_crm != 0);
+
+ x1 %= MAX_BUF_XSIZE * TILEX;
+ y1 %= MAX_BUF_YSIZE * TILEY;
+ x2 %= MAX_BUF_XSIZE * TILEX;
+ y2 %= MAX_BUF_YSIZE * TILEY;
+
+ if (player_is_digging)
+ {
+#if 0
+ /* draw the field the player is moving from (under the player) */
+ DrawLevelField_EM(old_x, old_y, old_sx, old_sy, FALSE);
+ DrawLevelFieldCrumbled_EM(old_x, old_y, old_sx, old_sy, old_crm, FALSE);
+#endif
+
+ /* draw the field the player is moving to (under the player) */
+ DrawLevelField_EM(new_x, new_y, new_sx, new_sy, FALSE);
+ DrawLevelFieldCrumbled_EM(new_x, new_y, new_sx, new_sy, new_crm, FALSE);
+
+ /* draw the player (masked) over the element he is just digging away */
+ DrawLevelPlayer_EM(x1, y1, ply->num, ply->anim, TRUE);
+
+#if 1
+ /* draw the field the player is moving from (masked over the player) */
+ DrawLevelField_EM(old_x, old_y, old_sx, old_sy, TRUE);
+#endif
+ }
+ else
+ {
+ /* draw the player under the element which is on the same field */
+ DrawLevelPlayer_EM(x1, y1, ply->num, ply->anim, FALSE);
+
+ /* draw the field the player is moving from (masked over the player) */
+ DrawLevelField_EM(old_x, old_y, old_sx, old_sy, TRUE);
+
+ /* draw the field the player is moving to (masked over the player) */
+ DrawLevelField_EM(new_x, new_y, new_sx, new_sy, TRUE);
+ }
+
+ /* mark screen tiles as dirty */
+ screentiles[old_sy][old_sx] = -1;
+ screentiles[new_sy][new_sx] = -1;
+ }
+}
+
+void game_initscreen(void)
+{
+ unsigned int x,y;
+
+ frame = 6;
+ screen_x = 0;
+ screen_y = 0;
+
+ for (y = 0; y < MAX_BUF_YSIZE; y++)
+ {
+ for (x = 0; x < MAX_BUF_XSIZE; x++)
+ {
+ screentiles[y][x] = -1;
+ crumbled_state[y][x] = 0;
+ }
+ }
+
+#if 1
+ DrawAllGameValues(lev.required, ply1.dynamite, lev.score,
+ lev.time, ply1.keys | ply2.keys);
+#else
+ DrawAllGameValues(lev.required, ply1.dynamite, lev.score,
+ DISPLAY_TIME(lev.time + 4), ply1.keys | ply2.keys);
+#endif
+}
+
+void RedrawPlayfield_EM()
+{
+ unsigned int x,y;
+
+ x = (frame * ply1.oldx + (8 - frame) * ply1.x) * TILEX / 8
+ + ((SCR_FIELDX - 1) * TILEX) / 2;
+ y = (frame * ply1.oldy + (8 - frame) * ply1.y) * TILEY / 8
+ + ((SCR_FIELDY - 1) * TILEY) / 2;
+
+ if (x > lev.width * TILEX)
+ x = lev.width * TILEX;
+ if (y > lev.height * TILEY)
+ y = lev.height * TILEY;
+
+ if (x < SCR_FIELDX * TILEX)
+ x = SCR_FIELDX * TILEY;
+ if (y < SCR_FIELDY * TILEY)
+ y = SCR_FIELDY * TILEY;
+
+ screen_x = x - (SCR_FIELDX - 1) * TILEX;
+ screen_y = y - (SCR_FIELDY - 1) * TILEY;
+
+ animscreen();
+ blitplayer(&ply1);
+ blitplayer(&ply2);
+ blitscreen();
+
+ FlushDisplay();
+}
+
+void game_animscreen(void)
+{
+ RedrawPlayfield_EM();
+}
+
+void DrawGameDoorValues_EM()
+{
+#if 1
+ DrawAllGameValues(lev.required, ply1.dynamite, lev.score,
+ lev.time, ply1.keys | ply2.keys);
+#else
+ DrawAllGameValues(lev.required, ply1.dynamite, lev.score,
+ DISPLAY_TIME(lev.time), ply1.keys | ply2.keys);
+#endif
+}
--- /dev/null
+/* 2000-08-10T18:03:54Z
+ *
+ * open X11 display and sound
+ */
+
+#include <signal.h>
+
+#if !defined(TARGET_SDL)
+#include <sys/wait.h>
+#endif
+
+#include "main_em.h"
+
+#include "global.h"
+#include "display.h"
+#include "sample.h"
+#include "level.h"
+
+
+Bitmap *objBitmap;
+Bitmap *sprBitmap;
+
+Bitmap *screenBitmap;
+
+#if 0
+Pixmap spriteBitmap;
+#endif
+
+Pixmap objPixmap;
+Pixmap sprPixmap;
+
+#if 0
+Pixmap objmaskBitmap;
+Pixmap sprmaskBitmap;
+
+GC spriteGC;
+#endif
+
+char play[SAMPLE_MAX];
+int play_x[SAMPLE_MAX];
+int play_y[SAMPLE_MAX];
+int play_element[SAMPLE_MAX];
+
+static boolean use_native_em_sound = 0;
+
+struct GlobalInfo_EM global_em_info;
+
+#if defined(AUDIO_UNIX_NATIVE)
+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 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",
+ "06.tank.au", /* android moving */
+ "08.spring.au",
+ "09.slurp.au",
+ "10.eater.au",
+ "10.eater.au", /* eater eating */
+ "11.alien.au",
+ "12.collect.au",
+ "13.diamond.au",
+ "14.squash.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",
+ "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,
+ 20,
+ 100,
+ 100,
+ 50,
+ 50,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 20,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 100,
+ 20,
+ 100,
+ 100,
+ 100
+};
+#endif
+
+char *progname;
+char *arg_basedir;
+
+extern void tab_generate();
+extern void tab_generate_graphics_info_em();
+extern void ulaw_generate();
+
+int open_all(void)
+{
+ Bitmap *emc_bitmaps[2];
+#if 0
+ XGCValues gcValues;
+#endif
+
+#if 1
+ SetBitmaps_EM(emc_bitmaps);
+
+ objBitmap = emc_bitmaps[0];
+ sprBitmap = emc_bitmaps[1];
+
+#if 0
+ objPixmap = emc_bitmaps[0]->drawable;
+ sprPixmap = emc_bitmaps[1]->drawable;
+
+ objmaskBitmap = emc_bitmaps[0]->clip_mask;
+ sprmaskBitmap = emc_bitmaps[1]->clip_mask;
+#endif
+
+ screenBitmap = CreateBitmap(MAX_BUF_XSIZE * TILEX, MAX_BUF_YSIZE * TILEY,
+ DEFAULT_DEPTH);
+
+ global_em_info.screenbuffer = screenBitmap;
+
+#endif
+
+#if 0
+ spriteBitmap = XCreatePixmap(display, window->drawable, TILEX, TILEY, 1);
+ if (spriteBitmap == 0)
+ Error(ERR_EXIT, "failed to create sprite pixmap for EM engine");
+
+ gcValues.function =
+ objmaskBitmap ? GXcopyInverted : sprmaskBitmap ? GXcopy : GXset;
+ gcValues.graphics_exposures = False;
+ spriteGC = XCreateGC(display, spriteBitmap, GCFunction | GCGraphicsExposures,
+ &gcValues);
+ if (spriteGC == 0)
+ Error(ERR_EXIT, "failed to create sprite GC for EM engine");
+#endif
+
+ /* ----------------------------------------------------------------- */
+
+#if defined(AUDIO_UNIX_NATIVE)
+
+#if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD)
+
+ if (use_native_em_sound)
+ {
+ char name[MAXNAME+2];
+ int i;
+
+ 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])
+ Error(ERR_EXIT, "buffer overflow when reading 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)
+ {
+ Error(ERR_WARN, "unable to create sound pipe for EM engine -- no sound");
+
+ return(1);
+ }
+
+ sound_pid = fork();
+ if (sound_pid == -1)
+ {
+ Error(ERR_WARN, "unable to fork sound thread for EM engine -- no sound");
+
+ 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) */
+
+#endif /* AUDIO_UNIX_NATIVE */
+
+ return(0);
+}
+
+void em_open_all()
+{
+ /* pre-calculate some data */
+ tab_generate();
+#if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD)
+ ulaw_generate();
+#endif
+
+ progname = "emerald mine";
+
+ if (open_all() != 0)
+ Error(ERR_EXIT, "em_open_all(): open_all() failed");
+
+ /* after "open_all()", because we need the graphic bitmaps to be defined */
+ tab_generate_graphics_info_em();
+
+ game_init_vars();
+}
+
+void em_close_all(void)
+{
+#if defined(AUDIO_UNIX_NATIVE)
+ 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]);
+#endif
+
+#if 0
+ if (spriteGC)
+ XFreeGC(display, spriteGC);
+
+ if (spriteBitmap)
+ XFreePixmap(display, spriteBitmap);
+#endif
+}
+
+/* ---------------------------------------------------------------------- */
+
+extern unsigned int screen_x;
+extern unsigned int screen_y;
+
+void play_element_sound(int x, int y, int sample, int element)
+{
+#if 0
+ unsigned int left = screen_x / TILEX;
+ unsigned int top = screen_y / TILEY;
+
+ if ((x == -1 && y == -1) || /* play sound in the middle of the screen */
+ ((unsigned int)(y - top) <= SCR_FIELDY &&
+ (unsigned int)(x - left) <= SCR_FIELDX))
+#endif
+ {
+#if 1
+ PlayLevelSound_EM(x, y, element, sample);
+#else
+ play[sample] = 1;
+ play_x[sample] = x;
+ play_y[sample] = y;
+ play_element[sample] = element;
+#endif
+ }
+}
+
+void play_sound(int x, int y, int sample)
+{
+ play_element_sound(x, y, sample, -1);
+}
+
+void sound_play(void)
+{
+ if (!use_native_em_sound)
+ {
+ int i;
+
+#if 0
+ UpdateEngineValues(screen_x / TILEX, screen_y / TILEY);
+#endif
+
+ return;
+
+ for (i = 0; i < SAMPLE_MAX; i++)
+ if (play[i])
+ PlayLevelSound_EM(play_x[i], play_y[i], play_element[i], i);
+ }
+
+#if defined(AUDIO_UNIX_NATIVE)
+ if (use_native_em_sound && sound_pipe[1] != -1)
+ {
+ if (write(sound_pipe[1], &play, sizeof(play)) == -1)
+ {
+ Error(ERR_WARN, "cannot write into pipe to child process -- no sounds");
+
+ 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;
+ }
+ }
+ }
+
+#endif
+
+ memset(play, 0, sizeof(play));
+}
+
+unsigned int InitEngineRND_EM(long seed)
+{
+ if (seed == NEW_RANDOMIZE)
+ {
+ int simple_rnd = SimpleRND(1000);
+ int i;
+
+ for (i = 0; i < simple_rnd || RandomEM == NEW_RANDOMIZE; i++)
+ RandomEM = RandomEM * 129 + 1;
+
+ seed = RandomEM;
+ }
+
+ RandomEM = seed;
+
+ return (unsigned int) seed;
+}
--- /dev/null
+/* 2000-08-13T15:29:40Z
+ *
+ * handle input from x11 and keyboard and joystick
+ */
+
+#include "global.h"
+#include "display.h"
+#include "level.h"
+
+
+unsigned long RandomEM;
+
+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];
+
+extern unsigned int screen_x;
+extern unsigned int screen_y;
+
+void game_init_vars(void)
+{
+ int x, y;
+
+ RandomEM = 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];
+}
+
+void InitGameEngine_EM()
+{
+ prepare_em_level();
+
+ game_initscreen();
+ game_animscreen();
+}
+
+void GameActions_EM(byte action)
+{
+ static unsigned long game_frame_delay = 0;
+#if 1
+ unsigned long game_frame_delay_value = getGameFrameDelay_EM(20);
+#else
+ unsigned long game_frame_delay_value = getGameFrameDelay_EM(25);
+#endif
+
+#if 0
+ /* this is done in screens.c/HandleGameActions() by calling BackToFront() */
+ XSync(display, False); /* block until all graphics are drawn */
+#endif
+
+ WaitUntilDelayReached(&game_frame_delay, game_frame_delay_value);
+
+ game_animscreen();
+
+ RandomEM = RandomEM * 129 + 1;
+
+ frame = (frame - 1) & 7;
+
+ readjoy(action);
+
+ UpdateEngineValues(screen_x / TILEX, screen_y / TILEY);
+
+ if (frame == 7)
+ {
+ synchro_1();
+ synchro_2();
+ }
+
+ if (frame == 6)
+ {
+ synchro_3();
+ sound_play();
+
+ if (game_frame_delay_value > 0) /* do not redraw values in warp mode */
+ DrawGameDoorValues_EM();
+ }
+
+#if 0
+ if (lev.time_initial == 0)
+ lev.time++;
+ else if (lev.time > 0)
+ lev.time--;
+#endif
+
+#if 0
+ if (lev.time_initial > 0 &&
+ lev.time > 0 && lev.time <= 50 && lev.time % 5 == 0 && setup.time_limit)
+ play_sound(-1, -1, SAMPLE_time);
+#endif
+}
+
+
+/* read input device for players */
+
+void readjoy(byte action)
+{
+ unsigned int north = 0, east = 0, south = 0, west = 0;
+ unsigned int snap = 0, drop = 0;
+
+ if (action & JOY_LEFT)
+ west = 1;
+
+ if (action & JOY_RIGHT)
+ east = 1;
+
+ if (action & JOY_UP)
+ north = 1;
+
+ if (action & JOY_DOWN)
+ south = 1;
+
+ if (action & JOY_BUTTON_1)
+ snap = 1;
+
+ if (action & JOY_BUTTON_2)
+ drop = 1;
+
+#if 1
+ ply1.joy_snap = snap;
+ ply1.joy_drop = drop;
+ if (ply1.joy_stick || (north | east | south | west))
+ {
+ ply1.joy_n = north;
+ ply1.joy_e = east;
+ ply1.joy_s = south;
+ ply1.joy_w = west;
+ }
+
+#else
+
+ ply2.joy_snap = snap;
+ ply2.joy_drop = drop;
+ if (ply2.joy_stick || (north | east | south | west))
+ {
+ ply2.joy_n = north;
+ ply2.joy_e = east;
+ ply2.joy_s = south;
+ ply2.joy_w = west;
+ }
+#endif
+}
--- /dev/null
+#ifndef LEVEL_H
+#define LEVEL_H
+
+#include "main_em.h"
+#include "tile.h"
+
+#define WIDTH EM_MAX_CAVE_WIDTH
+#define HEIGHT EM_MAX_CAVE_HEIGHT
+
+#if 0
+
+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 amoeba_time; /* amoeba 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_snap:1;
+ unsigned joy_drop:1;
+ unsigned joy_stick:1;
+ unsigned joy_spin:1;
+};
+
+#endif
+
+extern unsigned long RandomEM;
+
+extern struct PLAYER ply1;
+extern struct PLAYER ply2;
+extern struct LEVEL lev;
+
+extern struct LevelInfo_EM native_em_level;
+extern struct GraphicInfo_EM graphic_info_em_object[TILE_MAX][8];
+extern struct GraphicInfo_EM graphic_info_em_player[2][SPR_MAX][8];
+
+extern unsigned short **Boom;
+extern unsigned short **Cave;
+extern unsigned short **Next;
+extern unsigned short **Draw;
+
+#endif
--- /dev/null
+/* Emerald Mine
+ *
+ * David Tritscher
+ *
+ * v0.0 2000-01-06T06:43:39Z
+ *
+ * set everything up and close everything down
+ */
--- /dev/null
+#ifndef MAIN_EM_H
+#define MAIN_EM_H
+
+#include "../engines.h"
+
+
+/* 2000-07-30T11:06:03Z ---------------------------------------------------- */
+
+#define EM_MAX_CAVE_WIDTH 102
+#define EM_MAX_CAVE_HEIGHT 102
+
+/* define these for backwards compatibility */
+#define EM_ENGINE_BAD_ROLL
+#define EM_ENGINE_BAD_SPRING
+
+
+/*
+ -----------------------------------------------------------------------------
+ definition of elements used in the Emerald Mine Club engine;
+ the element names have the following properties:
+ - elements that start with an 'X' can be stored in a level file;
+ - elements that start with an 'Y' indicate moving elements;
+ - elements that end with a 'B' are the "backside" of a moving element.
+ -----------------------------------------------------------------------------
+*/
+
+enum
+{
+ Xblank = 0, /* still */
+ Yacid_splash_eB, /* hmm */
+ Yacid_splash_wB, /* hmm */
+
+#ifdef EM_ENGINE_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,
+
+#if 1
+ Ykey_1_eat,
+ Ykey_2_eat,
+ Ykey_3_eat,
+ Ykey_4_eat,
+ Ykey_5_eat,
+ Ykey_6_eat,
+ Ykey_7_eat,
+ Ykey_8_eat,
+ Ylenses_eat,
+ Ymagnify_eat,
+ Ygrass_eat,
+ Ydirt_eat,
+#endif
+
+ Xgrow_ns,
+ Ygrow_ns_eat,
+ Xgrow_ew,
+ Ygrow_ew_eat,
+ Xwonderwall,
+ XwonderwallB,
+ Xamoeba_1,
+ Xamoeba_2,
+ Xamoeba_3,
+ Xamoeba_4,
+ Xamoeba_5,
+ Xamoeba_6,
+ Xamoeba_7,
+ Xamoeba_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,
+
+#if 1
+ Xfake_acid_1,
+ Xfake_acid_2,
+ Xfake_acid_3,
+ Xfake_acid_4,
+ Xfake_acid_5,
+ Xfake_acid_6,
+ Xfake_acid_7,
+ Xfake_acid_8,
+#endif
+
+ 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, /* passed from synchro to explode, only in next[];
+ no picture */
+ Zdynamite, /* passed from synchro to explode, only in next[];
+ no picture */
+ Zplayer, /* special code to indicate player;
+ no picture */
+ ZBORDER, /* special code to indicate border;
+ no picture */
+
+ TILE_MAX
+};
+
+enum
+{
+ SPR_still = 0,
+ SPR_walk = 1,
+ SPR_push = 5,
+ SPR_spray = 9,
+
+ SPR_MAX = 13
+};
+
+enum
+{
+ SAMPLE_blank = 0, /* player walks on blank */
+ SAMPLE_roll, /* player pushes stone/bomb/nut/spring */
+ 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_clone, /* android places something */
+ SAMPLE_android_move, /* android moves */
+ SAMPLE_spring, /* spring hits ground/wall/bumper, stone hits spring */
+ SAMPLE_slurp, /* spring kills alien */
+ SAMPLE_eater, /* eater sits */
+ SAMPLE_eater_eat, /* eater eats diamond */
+ SAMPLE_alien, /* alien moves */
+ SAMPLE_collect, /* player collects object */
+ SAMPLE_diamond, /* diamond/emerald hits ground */
+ SAMPLE_squash, /* stone squashes diamond */
+ SAMPLE_wonderfall, /* object falls thru wonderwall */
+ SAMPLE_drip, /* drip hits ground */
+ SAMPLE_push, /* player pushes 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 is active */
+ SAMPLE_door, /* player goes thru door (gate) */
+ SAMPLE_exit_open, /* exit opens */
+ SAMPLE_exit_leave, /* player goes into 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
+};
+
+struct LEVEL
+{
+ unsigned int home_initial; /* number of players (initial) */
+ unsigned int home; /* number of players not yet at home */
+ /* 0 == all players at home */
+
+ unsigned int width; /* playfield width */
+ unsigned int height; /* playfield height */
+
+ unsigned int time_seconds; /* available time (seconds) */
+ unsigned int time_initial; /* available time (initial) */
+ unsigned int time; /* time remaining (runtime) */
+
+ boolean killed_out_of_time; /* kill player due to time out */
+
+ unsigned int required_initial; /* emeralds needed (initial) */
+ unsigned int required; /* emeralds needed (runtime) */
+
+ unsigned int score; /* score */
+
+ /* all below entries must be filled every time a level is read */
+
+ unsigned int alien_score; /* score for killing alien */
+ unsigned int amoeba_time; /* amoeba speed */
+ unsigned int android_move_cnt_initial;/* android move counter (initial) */
+ unsigned int android_move_cnt; /* android move counter */
+ unsigned int android_move_time; /* android move reset time */
+ unsigned int android_clone_cnt_initial;/* android clone counter (initial) */
+ unsigned int android_clone_cnt; /* android clone counter */
+ unsigned int android_clone_time; /* android clone reset time */
+ unsigned int ball_cnt; /* ball counter */
+ unsigned int ball_pos; /* ball array pos counter */
+ unsigned int ball_random; /* ball is random flag */
+ unsigned int ball_state_initial; /* ball active flag (initial) */
+ unsigned int ball_state; /* ball active flag */
+ unsigned int ball_time; /* ball reset time */
+ unsigned int bug_score; /* score for killing bug */
+ unsigned int diamond_score; /* score for collecting diamond */
+ unsigned int dynamite_score; /* score for collecting dynamite */
+ unsigned int eater_pos; /* eater array pos */
+ unsigned int eater_score; /* score for killing eater */
+ unsigned int emerald_score; /* score for collecting emerald */
+ unsigned int exit_score; /* score for entering exit */
+ unsigned int key_score; /* score for colleting key */
+ unsigned int lenses_cnt_initial; /* lenses counter (initial) */
+ unsigned int lenses_cnt; /* lenses counter */
+ unsigned int lenses_score; /* score for collecting lenses */
+ unsigned int lenses_time; /* lenses reset time */
+ unsigned int magnify_cnt_initial; /* magnify counter (initial) */
+ unsigned int magnify_cnt; /* magnify counter */
+ unsigned int magnify_score; /* score for collecting magnifier */
+ unsigned int magnify_time; /* magnify reset time */
+ unsigned int nut_score; /* score for cracking nut */
+ unsigned int shine_cnt; /* shine counter for emerald/diamond */
+ unsigned int slurp_score; /* score for slurping alien */
+ unsigned int tank_score; /* score for killing tank */
+ unsigned int wheel_cnt_initial; /* wheel counter (initial) */
+ unsigned int wheel_cnt; /* wheel counter */
+ unsigned int wheel_x_initial; /* wheel x pos (initial) */
+ unsigned int wheel_x; /* wheel x pos */
+ unsigned int wheel_y_initial; /* wheel y pos (initial) */
+ unsigned int wheel_y; /* wheel y pos */
+ unsigned int wheel_time; /* wheel reset time */
+ unsigned int wind_cnt_initial; /* wind counter (initial) */
+ unsigned int wind_cnt; /* wind time counter */
+ unsigned int wind_direction_initial; /* wind direction (initial) */
+ unsigned int wind_direction; /* wind direction */
+ unsigned int wind_time; /* wind reset time */
+ unsigned int wonderwall_state_initial;/* wonderwall active flag (initial) */
+ unsigned int wonderwall_state; /* wonderwall active flag */
+ unsigned int wonderwall_time_initial; /* wonderwall time (initial) */
+ 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_initial;
+ unsigned int alive;
+
+ unsigned int dynamite;
+ unsigned int dynamite_cnt;
+ unsigned int keys;
+ unsigned int anim;
+
+ unsigned int x_initial;
+ unsigned int y_initial;
+ unsigned int x;
+ unsigned int y;
+ unsigned int oldx;
+ unsigned int oldy;
+
+ unsigned int last_move_dir;
+
+ unsigned joy_n:1;
+ unsigned joy_e:1;
+ unsigned joy_s:1;
+ unsigned joy_w:1;
+ unsigned joy_snap:1;
+ unsigned joy_drop:1;
+ unsigned joy_stick:1;
+ unsigned joy_spin:1;
+};
+
+
+/* ------------------------------------------------------------------------- */
+/* definitions and structures for use by the main game functions */
+/* ------------------------------------------------------------------------- */
+
+/* values for native Emerald Mine game version */
+#define FILE_VERSION_EM_V3 3
+#define FILE_VERSION_EM_V4 4
+#define FILE_VERSION_EM_V5 5
+#define FILE_VERSION_EM_V6 6
+
+#define FILE_VERSION_EM_ACTUAL FILE_VERSION_EM_V6
+
+struct GlobalInfo_EM
+{
+ Bitmap *screenbuffer;
+};
+
+struct LevelInfo_EM
+{
+ int file_version;
+
+ unsigned short cave[EM_MAX_CAVE_WIDTH][EM_MAX_CAVE_HEIGHT];
+
+ struct LEVEL *lev;
+ struct PLAYER *ply1, *ply2;
+};
+
+struct GraphicInfo_EM
+{
+ Bitmap *bitmap;
+ int src_x, src_y;
+ int src_offset_x, src_offset_y;
+ int dst_offset_x, dst_offset_y;
+ int width, height;
+
+ Bitmap *crumbled_bitmap;
+ int crumbled_src_x, crumbled_src_y;
+ int crumbled_border_size;
+
+ boolean has_crumbled_graphics;
+ boolean preserve_background;
+
+ int unique_identifier; /* used to identify needed screen updates */
+};
+
+#endif /* MAIN_EM_H */
--- /dev/null
+#ifndef SAMPLE_H
+#define SAMPLE_H
+
+#include "main_em.h"
+
+
+#if 0
+
+enum
+{
+ SAMPLE_blank = 0, /* player walks on blank */
+ SAMPLE_roll, /* player pushes stone/bomb/nut/spring */
+ 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_clone, /* android places something */
+ SAMPLE_android_move, /* android moves */
+ SAMPLE_spring, /* spring hits ground/wall/bumper, stone hits spring */
+ SAMPLE_slurp, /* spring kills alien */
+ SAMPLE_eater, /* eater sits */
+ SAMPLE_eater_eat, /* eater eats diamond */
+ SAMPLE_alien, /* alien moves */
+ SAMPLE_collect, /* player collects object */
+ SAMPLE_diamond, /* diamond/emerald hits ground */
+ SAMPLE_squash, /* stone squashes diamond */
+ SAMPLE_wonderfall, /* object falls thru wonderwall */
+ SAMPLE_drip, /* drip hits ground */
+ SAMPLE_push, /* player pushes 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 (is active) */
+ SAMPLE_door, /* player goes thru door */
+ SAMPLE_exit_open, /* exit opens */
+ SAMPLE_exit_leave, /* player goes into 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
+};
+
+#endif
+
+extern void play_sound(int, int, int);
+extern void play_element_sound(int, int, int, int);
+
+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 */
+
+#if defined(AUDIO_UNIX_NATIVE)
+
+enum
+{
+ AUDIO_ULAW = 0,
+ AUDIO_U8
+};
+
+#endif /* AUDIO_UNIX_NATIVE */
+
+#endif /* SAMPLE_H */
--- /dev/null
+/* 2000-08-10T17:39:15Z
+ *
+ * handle sounds in emerald mine
+ */
+
+#include "main_em.h"
+
+
+#if defined(AUDIO_UNIX_NATIVE)
+
+#if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD)
+
+#ifdef PLATFORM_LINUX
+#include <sys/ioctl.h>
+#include <sys/soundcard.h>
+#endif
+
+#ifdef PLATFORM_BSD
+#include <ioctl.h>
+#include <soundcard.h>
+#endif
+
+#include "global.h"
+#include "sample.h"
+
+static char audioname[] = "/dev/audio";
+
+static const int sound_priority[SAMPLE_MAX] =
+{
+ SAMPLE_exit_open,
+ SAMPLE_exit_leave,
+ 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_clone,
+ SAMPLE_android_move,
+ SAMPLE_ball,
+ SAMPLE_grow,
+ SAMPLE_squash,
+ SAMPLE_wonderfall,
+ 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_eater_eat,
+ 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_open] ||
+ sound_play[SAMPLE_exit_leave] ||
+ 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)
+ {
+ Error(ERR_WARN, "select() failed in sound thread");
+
+ 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)
+ {
+ Error(ERR_WARN, "read() failed in sound thread");
+
+ goto fail;
+ }
+
+ if (i == 0)
+ {
+ Error(ERR_WARN, "reading sound failed in sound thread");
+
+ goto fail;
+ }
+
+ if (i != sizeof(play))
+ {
+ Error(ERR_WARN, "bad message length in sound thread");
+
+ 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)
+ {
+ Error(ERR_WARN, "unable to set fragment size in sound thread");
+
+ goto reset;
+ }
+
+ if (ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &i) == -1)
+ {
+ Error(ERR_WARN, "unable to query audio format in sound thread");
+
+ goto reset;
+ }
+
+ /* prefer 8 bit unsigned and fall back on mu-law */
+ audio_format = (i & AFMT_U8) ? AFMT_U8 : AFMT_MU_LAW;
+
+ i = audio_format;
+ if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &i) == -1)
+ {
+ Error(ERR_WARN, "unable to set audio format in sound thread");
+
+ goto reset;
+ }
+
+ if (i == AFMT_MU_LAW)
+ {
+ audio_format = AUDIO_ULAW;
+ }
+ else if (i == AFMT_U8)
+ {
+ audio_format = AUDIO_U8;
+ }
+ else
+ {
+ Error(ERR_WARN, "audio format required by device not supported");
+
+ goto reset;
+ }
+
+ i = 1;
+ if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &i) == -1)
+ {
+ Error(ERR_WARN, "unable to set channels to mono in sound thread");
+
+ goto reset;
+ }
+
+ if (i != 1)
+ {
+ Error(ERR_WARN, "channels required by device not supported");
+
+ goto reset;
+ }
+
+ i = 8000;
+ if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &i) == -1)
+ {
+ Error(ERR_WARN, "unable to set sampling rate in sound thread");
+
+ goto reset;
+ }
+
+ sample_rate = i;
+ if (ioctl(audio_fd, SNDCTL_DSP_GETBLKSIZE, &i) == -1)
+ {
+ Error(ERR_WARN, "unable to get block size in sound thread");
+
+ goto reset;
+ }
+
+ fragment_size = i;
+
+#else
+ if (fcntl(audio_fd, F_SETFL, O_NONBLOCK) == -1)
+ {
+ Error(ERR_WARN, "unable to make audio non blocking in sound thread");
+
+ goto reset;
+ }
+
+#endif /* OPEN_SOUND_SYSTEM */
+
+ audio_buffer = malloc(fragment_size * sizeof(*audio_buffer));
+ if (audio_buffer == 0)
+ {
+ Error(ERR_WARN, "unable to malloc audio buffer in sound thread");
+
+ goto fail;
+ }
+
+ mix_buffer = malloc(fragment_size * sizeof(*mix_buffer));
+ if (mix_buffer == 0)
+ {
+ Error(ERR_WARN, "unable to malloc mixing buffer in sound thread");
+
+ 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)
+ {
+ /* prepare mix buffer */
+ memset(mix_buffer, 0, fragment_size * sizeof(*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)
+ {
+ Error(ERR_WARN, "cannot write to audio device in sound thread");
+
+ goto reset;
+ }
+
+ if (i != fragment_size)
+ {
+ Error(ERR_WARN, "bad write length to audio device in sound thread");
+
+ 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)
+ {
+ Error(ERR_WARN, "cannot open file '%s' in sound thread", name);
+
+ result = 1;
+ goto fail;
+ }
+
+ actual = fread(buffer, 1, 24, file);
+ if (actual == -1)
+ {
+ Error(ERR_WARN, "cannot read file '%s' in sound thread", name);
+
+ result = 1;
+ goto fail;
+ }
+
+ if (actual < 24)
+ {
+ Error(ERR_WARN, "premature eof of file '%s' in sound thread", name);
+
+ result = 1;
+ goto fail;
+ }
+
+ /* magic */
+ temp = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
+ if (temp != 0x2e736e64)
+ {
+ Error(ERR_WARN, "unrecognized format of file '%s' in sound thread", name);
+
+ result = 1;
+ goto fail;
+ }
+
+ /* header length */
+ temp = buffer[4] << 24 | buffer[5] << 16 | buffer[6] << 8 | buffer[7];
+ if (temp < 24)
+ {
+ Error(ERR_WARN, "bad header length of file '%s' in sound thread", name);
+
+ 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;
+ }
+
+ /* data length */
+ temp = buffer[8] << 24 | buffer[9] << 16 | buffer[10] << 8 | buffer[11];
+ datalength = temp;
+
+ /* encoding */
+ temp = buffer[12] << 24 | buffer[13] << 16 | buffer[14] << 8 | buffer[15];
+ if (temp != 1)
+ {
+ fprintf(stderr, "%s: \"%s\": %s (%ld != 1)\n", progname, name,
+ "bad encoding type", temp);
+ result = 1;
+ goto fail;
+ }
+
+ /* sample rate */
+ temp = buffer[16] << 24 | buffer[17] << 16 | buffer[18] << 8 | buffer[19];
+ if (temp != 8000)
+ {
+ fprintf(stderr, "%s: \"%s\": %s (%ld != 8000)\n", progname, name,
+ "bad sample rate", temp);
+ result = 1;
+ goto fail;
+ }
+
+ /* channels */
+ temp = buffer[20] << 24 | buffer[21] << 16 | buffer[22] << 8 | buffer[23];
+ 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)
+ {
+ Error(ERR_WARN, "unable to malloc buffer for file '%s' in sound thread",
+ name);
+
+ 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) */
+
+#endif /* AUDIO_UNIX_NATIVE */
--- /dev/null
+/* 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"
+#include "display.h"
+
+
+static void check_player(struct PLAYER *);
+static void kill_player(struct PLAYER *);
+static boolean player_digfield(struct PLAYER *, int, int);
+static boolean player_killed(struct PLAYER *);
+
+void synchro_1(void)
+{
+ /* must test for death and actually kill separately */
+ boolean ply1_kill = player_killed(&ply1);
+ boolean ply2_kill = player_killed(&ply2);
+
+ if (ply1.alive && ply1_kill)
+ kill_player(&ply1);
+ if (ply2.alive && ply2_kill)
+ kill_player(&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 (RandomEM & 256)
+ {
+ if (ply1.alive) check_player(&ply1);
+ if (ply2.alive) check_player(&ply2);
+ }
+ else
+ {
+ if (ply2.alive) check_player(&ply2);
+ if (ply1.alive) check_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 boolean player_killed(struct PLAYER *ply)
+{
+ register unsigned int x = ply->x;
+ register unsigned int y = ply->y;
+
+ if (!ply->alive)
+ return FALSE;
+
+#if 1
+ if (lev.killed_out_of_time && setup.time_limit)
+ return TRUE;
+#else
+ if (lev.time_initial > 0 && lev.time == 0 && setup.time_limit)
+ return TRUE;
+#endif
+
+ 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 TRUE;
+ }
+
+ 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 TRUE;
+ }
+
+ 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 TRUE;
+ }
+
+ 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 TRUE;
+ }
+
+ 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:
+#if 1
+ case Xfake_acid_1:
+ case Xfake_acid_2:
+ case Xfake_acid_3:
+ case Xfake_acid_4:
+ case Xfake_acid_5:
+ case Xfake_acid_6:
+ case Xfake_acid_7:
+ case Xfake_acid_8:
+#endif
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void kill_player(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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, Zplayer);
+#endif
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, Zplayer);
+#endif
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, Zplayer);
+#endif
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, Zplayer);
+#endif
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, Zplayer);
+#endif
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, Zplayer);
+#endif
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, Zplayer);
+#endif
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, Zplayer);
+#endif
+ break;
+ }
+
+ switch(Cave[y][x])
+ {
+ case Xexit_1:
+ case Xexit_2:
+ case Xexit_3:
+ play_element_sound(x, y, SAMPLE_exit_leave, Xexit_1);
+ break;
+
+ default:
+ play_element_sound(x, y, SAMPLE_die, Zplayer);
+ break;
+ }
+
+ switch(Cave[y][x])
+ {
+#if 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:
+ break;
+#endif
+
+ default:
+ Cave[y][x] = Xboom_1;
+ Boom[y][x] = Xblank;
+ break;
+ }
+}
+
+static void check_player(struct PLAYER *ply)
+{
+ unsigned int oldx = ply->x;
+ unsigned int oldy = ply->y;
+ register unsigned int x = oldx;
+ register unsigned int y = oldy;
+ unsigned int anim = 0;
+ int dx = 0, dy = 0;
+
+#if 0
+ printf("::: up == %d, down == %d, left == %d, right == %d, fire == %d [spin == %d, stick == %d]\n",
+ ply->joy_n, ply->joy_s, ply->joy_w, ply->joy_e, ply->joy_fire,
+ ply->joy_spin, ply->joy_stick);
+#endif
+
+#if 1
+ if (ply->joy_w) /* west */
+ {
+ x--;
+ dx = -1;
+ anim = 3;
+ }
+ else if (ply->joy_e) /* east */
+ {
+ x++;
+ dx = 1;
+ anim = 1;
+ }
+
+ if (ply->joy_n) /* north */
+ {
+ y--;
+ dy = -1;
+ anim = 0;
+ }
+ else if (ply->joy_s) /* south */
+ {
+ y++;
+ dy = 1;
+ anim = 2;
+ }
+
+#else
+
+ if ((ply->joy_spin = !ply->joy_spin))
+ {
+ if (ply->joy_n) /* north */
+ {
+ y--;
+ dy = -1;
+ anim = 0;
+ }
+ else if (ply->joy_e) /* east */
+ {
+ x++;
+ dx = 1;
+ anim = 1;
+ }
+ else if (ply->joy_s) /* south */
+ {
+ y++;
+ dy = 1;
+ anim = 2;
+ }
+ else if (ply->joy_w) /* west */
+ {
+ x--;
+ dx = -1;
+ anim = 3;
+ }
+ }
+ else
+ {
+ if (ply->joy_w) /* west */
+ {
+ x--;
+ dx = -1;
+ anim = 3;
+ }
+ else if (ply->joy_s) /* south */
+ {
+ y++;
+ dy = 1;
+ anim = 2;
+ }
+ else if (ply->joy_e) /* east */
+ {
+ x++;
+ dx = 1;
+ anim = 1;
+ }
+ else if (ply->joy_n) /* north */
+ {
+ y--;
+ dy = -1;
+ anim = 0;
+ }
+ }
+#endif
+
+ if (dx == 0 && dy == 0)
+ {
+ ply->joy_stick = 0;
+
+ if (ply->joy_drop)
+ {
+ if (++ply->dynamite_cnt == 5 && ply->dynamite)
+ {
+ Cave[y][x] = Xdynamite_1;
+ play_element_sound(x, y, SAMPLE_dynamite, Xdynamite_1);
+ ply->dynamite--;
+ }
+ }
+ else
+ {
+ ply->dynamite_cnt = 0;
+ }
+
+ RandomEM += 7; /* be a bit more random if the player doesn't 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 */
+ ply->joy_spin = !ply->joy_spin;
+
+ if (ply->joy_snap == 0) /* player wants to move */
+ {
+ boolean moved = FALSE;
+
+ if (ply->last_move_dir & MV_HORIZONTAL)
+ {
+ if (!(moved = player_digfield(ply, 0, dy)))
+ moved = player_digfield(ply, dx, 0);
+ }
+ else
+ {
+ if (!(moved = player_digfield(ply, dx, 0)))
+ moved = player_digfield(ply, 0, dy);
+ }
+
+ if (moved)
+ {
+ if (oldx != ply->x)
+ ply->last_move_dir = (dx < 0 ? MV_LEFT : MV_RIGHT);
+ else if (oldy != ply->y)
+ ply->last_move_dir = (dy < 0 ? MV_UP : MV_DOWN);
+ }
+ }
+ else /* player wants to snap */
+ {
+ player_digfield(ply, dx, dy);
+ }
+}
+
+static boolean player_digfield(struct PLAYER *ply, int dx, int dy)
+{
+ int anim = (dx < 0 ? 3 : dx > 0 ? 1 : dy < 0 ? 0 : dy > 0 ? 2 : 2);
+ unsigned int oldx = ply->x;
+ unsigned int oldy = ply->y;
+ register unsigned int x = oldx + dx;
+ register unsigned int y = oldy + dy;
+ boolean result = TRUE;
+
+ if (!dx && !dy) /* no direction specified */
+ return FALSE;
+
+ if (dx && dy && ply->joy_snap) /* more than one direction specified */
+ return FALSE;
+
+ if (ply->joy_snap == 0) /* player wants to move */
+ {
+ int element = Cave[y][x];
+
+ 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;
+#if 1
+ case Xfake_acid_1:
+ case Xfake_acid_2:
+ case Xfake_acid_3:
+ case Xfake_acid_4:
+ case Xfake_acid_5:
+ case Xfake_acid_6:
+ case Xfake_acid_7:
+ case Xfake_acid_8:
+#endif
+ play_element_sound(x, y, SAMPLE_blank, Xblank);
+ ply->anim = SPR_walk + anim;
+ ply->x = x;
+ ply->y = y;
+ break;
+
+#if 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:
+#endif
+ if (Cave[y-1][x+1] == Xblank)
+ Cave[y-1][x+1] = Yacid_splash_eB;
+ if (Cave[y-1][x-1] == Xblank)
+ Cave[y-1][x-1] = Yacid_splash_wB;
+ play_element_sound(x, y, SAMPLE_acid, Xacid_1);
+
+ 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:
+#if 0
+ case Xacid_1:
+ case Xacid_2:
+ case Xacid_3:
+ case Xacid_4:
+ case Xacid_5:
+ case Xacid_6:
+ case Xacid_7:
+ case Xacid_8:
+#endif
+ 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_element_sound(x, y, SAMPLE_dirt, Xgrass);
+ 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_element_sound(x, y, SAMPLE_dirt, Xdirt);
+ 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_element_sound(x, y, SAMPLE_collect, element);
+ 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_element_sound(x, y, SAMPLE_collect, element);
+ 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_element_sound(x, y, SAMPLE_collect, element);
+ 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;
+ Cave[y][x] = Ykey_1_eat;
+ goto key_walk;
+
+ case Xkey_2:
+ ply->keys |= 0x02;
+ Cave[y][x] = Ykey_2_eat;
+ goto key_walk;
+
+ case Xkey_3:
+ ply->keys |= 0x04;
+ Cave[y][x] = Ykey_3_eat;
+ goto key_walk;
+
+ case Xkey_4:
+ ply->keys |= 0x08;
+ Cave[y][x] = Ykey_4_eat;
+ goto key_walk;
+
+ case Xkey_5:
+ ply->keys |= 0x10;
+ Cave[y][x] = Ykey_5_eat;
+ goto key_walk;
+
+ case Xkey_6:
+ ply->keys |= 0x20;
+ Cave[y][x] = Ykey_6_eat;
+ goto key_walk;
+
+ case Xkey_7:
+ ply->keys |= 0x40;
+ Cave[y][x] = Ykey_7_eat;
+ goto key_walk;
+
+ case Xkey_8:
+ ply->keys |= 0x80;
+ Cave[y][x] = Ykey_8_eat;
+ goto key_walk;
+
+ key_walk:
+
+ Next[y][x] = Zplayer;
+ play_element_sound(x, y, SAMPLE_collect, element);
+ lev.score += lev.key_score;
+ ply->anim = SPR_walk + anim;
+ ply->x = x;
+ ply->y = y;
+ break;
+
+ case Xlenses:
+ Cave[y][x] = Ylenses_eat;
+ Next[y][x] = Zplayer;
+ play_element_sound(x, y, SAMPLE_collect, element);
+ 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] = Ymagnify_eat;
+ Next[y][x] = Zplayer;
+ play_element_sound(x, y, SAMPLE_collect, element);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_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_element_sound(x, y, SAMPLE_roll, Xstone);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_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_element_sound(x, y, SAMPLE_roll, Xbomb);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_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_element_sound(x, y, SAMPLE_roll, Xnut);
+ 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_element_sound(x, y, SAMPLE_slurp, Xalien);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_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_element_sound(x, y, SAMPLE_roll, Xspring);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_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_element_sound(x, y, SAMPLE_push, Xballoon);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_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_element_sound(x, y, SAMPLE_push, Xandroid);
+ 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_element_sound(x, y, SAMPLE_door, element);
+ ply->anim = SPR_walk + anim;
+ ply->x = x + dx;
+ ply->y = y + dy;
+ break;
+
+ case Xwheel:
+ play_element_sound(x, y, SAMPLE_press, element);
+ 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_element_sound(x, y, SAMPLE_press, element);
+ lev.wind_cnt = lev.wind_time;
+ break;
+
+ case Xwind_stop:
+ play_element_sound(x, y, SAMPLE_press, element);
+ lev.wind_cnt = 0;
+ break;
+
+ case Xswitch:
+ play_element_sound(x, y, SAMPLE_press, element);
+ lev.ball_cnt = lev.ball_time;
+ lev.ball_state = !lev.ball_state;
+ break;
+
+ case Xplant:
+ Cave[y][x] = Yplant;
+ Next[y][x] = Xplant;
+ play_element_sound(x, y, SAMPLE_blank, Xplant);
+ ply->anim = SPR_walk + anim;
+ ply->x = x;
+ ply->y = y;
+ break;
+
+ case Xexit_1:
+ case Xexit_2:
+ case Xexit_3:
+ play_element_sound(x, y, SAMPLE_exit_leave, Xexit_1);
+
+ lev.home--;
+
+#if 0
+ /* !!! CHECK SCORE CALCULATION !!! */
+ if (lev.home == 0 && lev.time_initial > 0) /* game won */
+ lev.score += lev.time * lev.exit_score / 100;
+#endif
+
+ ply->anim = SPR_walk + anim;
+ ply->x = x;
+ ply->y = y;
+
+ break;
+ }
+
+ if (ply->x == oldx && ply->y == oldy) /* no movement */
+ result = FALSE;
+ }
+ else /* player wants to snap */
+ {
+ int element = Cave[y][x];
+
+ switch(Cave[y][x])
+ {
+ /* fire is pressed */
+
+ case Xgrass:
+ Cave[y][x] = Ygrass_eat;
+ Next[y][x] = Xblank;
+ play_element_sound(x, y, SAMPLE_dirt, element);
+ ply->anim = SPR_spray + anim;
+ break;
+
+ case Xdirt:
+ Cave[y][x] = Ydirt_eat;
+ Next[y][x] = Xblank;
+ play_element_sound(x, y, SAMPLE_dirt, element);
+ ply->anim = SPR_spray + anim;
+ break;
+
+ case Xdiamond:
+ case Xdiamond_pause:
+ Cave[y][x] = Ydiamond_eat;
+ Next[y][x] = Xblank;
+ play_element_sound(x, y, SAMPLE_collect, element);
+ 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_element_sound(x, y, SAMPLE_collect, element);
+ 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_element_sound(x, y, SAMPLE_collect, element);
+ 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;
+ Cave[y][x] = Ykey_1_eat;
+ goto key_shoot;
+
+ case Xkey_2:
+ ply->keys |= 0x02;
+ Cave[y][x] = Ykey_2_eat;
+ goto key_shoot;
+
+ case Xkey_3:
+ ply->keys |= 0x04;
+ Cave[y][x] = Ykey_3_eat;
+ goto key_shoot;
+
+ case Xkey_4:
+ ply->keys |= 0x08;
+ Cave[y][x] = Ykey_4_eat;
+ goto key_shoot;
+
+ case Xkey_5:
+ ply->keys |= 0x10;
+ Cave[y][x] = Ykey_5_eat;
+ goto key_shoot;
+
+ case Xkey_6:
+ ply->keys |= 0x20;
+ Cave[y][x] = Ykey_6_eat;
+ goto key_shoot;
+
+ case Xkey_7:
+ ply->keys |= 0x40;
+ Cave[y][x] = Ykey_7_eat;
+ goto key_shoot;
+
+ case Xkey_8:
+ ply->keys |= 0x80;
+ Cave[y][x] = Ykey_8_eat;
+ goto key_shoot;
+
+ key_shoot:
+ Next[y][x] = Xblank;
+ play_element_sound(x, y, SAMPLE_collect, element);
+ lev.score += lev.key_score;
+ ply->anim = SPR_walk + anim;
+ break;
+
+ case Xlenses:
+ Cave[y][x] = Ylenses_eat;
+ Next[y][x] = Xblank;
+ play_element_sound(x, y, SAMPLE_collect, element);
+ lev.score += lev.lenses_score;
+ lev.lenses_cnt = lev.lenses_time;
+ ply->anim = SPR_walk + anim;
+ break;
+
+ case Xmagnify:
+ Cave[y][x] = Ymagnify_eat;
+ Next[y][x] = Xblank;
+ play_element_sound(x, y, SAMPLE_collect, element);
+ lev.score += lev.magnify_score;
+ lev.magnify_cnt = lev.magnify_time;
+ ply->anim = SPR_walk + anim;
+ break;
+
+ default:
+ result = FALSE;
+ }
+ }
+
+ return result;
+}
--- /dev/null
+/* 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"
+
+
+#define RANDOM (random = random << 31 | random >> 1)
+
+void synchro_2(void)
+{
+ register unsigned int x = 0;
+ register unsigned int y = 1;
+ register unsigned long random = RandomEM;
+ 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 dx; /* only needed to find closest player */
+ unsigned int dy;
+ int element;
+
+ loop:
+
+ element = cave_cache[++x];
+
+ switch (element)
+ {
+ 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 /* BAD_ROLL */
+
+ /* --------------------------------------------------------------------- */
+
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ goto loop;
+
+ case Xblank:
+ case Yacid_splash_eB:
+ case Yacid_splash_wB:
+ case Xplant:
+ case Yplant:
+#if 1
+ case Xfake_acid_1:
+ case Xfake_acid_2:
+ case Xfake_acid_3:
+ case Xfake_acid_4:
+ case Xfake_acid_5:
+ case Xfake_acid_6:
+ case Xfake_acid_7:
+ case Xfake_acid_8:
+#endif
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ goto loop;
+
+ case Xblank:
+ case Yacid_splash_eB:
+ case Yacid_splash_wB:
+#if 1
+ case Xfake_acid_1:
+ case Xfake_acid_2:
+ case Xfake_acid_3:
+ case Xfake_acid_4:
+ case Xfake_acid_5:
+ case Xfake_acid_6:
+ case Xfake_acid_7:
+ case Xfake_acid_8:
+#endif
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ goto loop;
+
+ case Xblank:
+ case Yacid_splash_eB:
+ case Yacid_splash_wB:
+ case Zplayer:
+#if 1
+ case Xfake_acid_1:
+ case Xfake_acid_2:
+ case Xfake_acid_3:
+ case Xfake_acid_4:
+ case Xfake_acid_5:
+ case Xfake_acid_6:
+ case Xfake_acid_7:
+ case Xfake_acid_8:
+#endif
+ 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_element_sound(x, y, SAMPLE_crack, Xnut);
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, element);
+#endif
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, element);
+#endif
+ 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];
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, element);
+#endif
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, element);
+#endif
+ 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_element_sound(x, y, SAMPLE_stone, Xstone);
+ goto loop;
+ }
+
+ Cave[y][x] = Ystone_sB;
+ Cave[y+1][x] = Ydiamond_stone;
+ Next[y][x] = Xblank;
+ Next[y+1][x] = Xstone_pause;
+ play_element_sound(x, y, SAMPLE_squash, Xdiamond);
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, element);
+#endif
+ 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_element_sound(x, y, SAMPLE_wonderfall, Xwonderwall);
+ goto loop;
+ }
+
+ default:
+ Cave[y][x] = Xstone;
+ Next[y][x] = Xstone;
+ play_element_sound(x, y, SAMPLE_stone, Xstone);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_nut, Xnut);
+ goto loop;
+ }
+
+ /* --------------------------------------------------------------------- */
+
+ case Xbug_n:
+ if (tab_amoeba[Cave[y-1][x]] ||
+ tab_amoeba[Cave[y][x+1]] ||
+ tab_amoeba[Cave[y+1][x]] ||
+ tab_amoeba[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_element_sound(x, y, SAMPLE_bug, element);
+ goto loop;
+
+ default:
+ goto bug_gon;
+ }
+
+ case Xbug_gon:
+ if (tab_amoeba[Cave[y-1][x]] ||
+ tab_amoeba[Cave[y][x+1]] ||
+ tab_amoeba[Cave[y+1][x]] ||
+ tab_amoeba[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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_bug, element);
+ goto loop;
+
+ default:
+ Cave[y][x] = Ybug_n_w;
+ Next[y][x] = Xbug_gow;
+ play_element_sound(x, y, SAMPLE_bug, element);
+ goto loop;
+ }
+
+ /* --------------------------------------------------------------------- */
+
+ case Xbug_e:
+ if (tab_amoeba[Cave[y-1][x]] ||
+ tab_amoeba[Cave[y][x+1]] ||
+ tab_amoeba[Cave[y+1][x]] ||
+ tab_amoeba[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_element_sound(x, y, SAMPLE_bug, element);
+ goto loop;
+
+ default:
+ goto bug_goe;
+ }
+
+ case Xbug_goe:
+ if (tab_amoeba[Cave[y-1][x]] ||
+ tab_amoeba[Cave[y][x+1]] ||
+ tab_amoeba[Cave[y+1][x]] ||
+ tab_amoeba[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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_bug, element);
+ goto loop;
+
+ default:
+ Cave[y][x] = Ybug_e_n;
+ Next[y][x] = Xbug_gon;
+ play_element_sound(x, y, SAMPLE_bug, element);
+ goto loop;
+ }
+
+ /* --------------------------------------------------------------------- */
+
+ case Xbug_s:
+ if (tab_amoeba[Cave[y-1][x]] ||
+ tab_amoeba[Cave[y][x+1]] ||
+ tab_amoeba[Cave[y+1][x]] ||
+ tab_amoeba[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_element_sound(x, y, SAMPLE_bug, element);
+ goto loop;
+
+ default:
+ goto bug_gos;
+ }
+
+ case Xbug_gos:
+ if (tab_amoeba[Cave[y-1][x]] ||
+ tab_amoeba[Cave[y][x+1]] ||
+ tab_amoeba[Cave[y+1][x]] ||
+ tab_amoeba[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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_bug, element);
+ goto loop;
+
+ default:
+ Cave[y][x] = Ybug_s_e;
+ Next[y][x] = Xbug_goe;
+ play_element_sound(x, y, SAMPLE_bug, element);
+ goto loop;
+ }
+
+ /* --------------------------------------------------------------------- */
+
+ case Xbug_w:
+ if (tab_amoeba[Cave[y-1][x]] ||
+ tab_amoeba[Cave[y][x+1]] ||
+ tab_amoeba[Cave[y+1][x]] ||
+ tab_amoeba[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_element_sound(x, y, SAMPLE_bug, element);
+ goto loop;
+
+ default:
+ goto bug_gow;
+ }
+
+ case Xbug_gow:
+ if (tab_amoeba[Cave[y-1][x]] ||
+ tab_amoeba[Cave[y][x+1]] ||
+ tab_amoeba[Cave[y+1][x]] ||
+ tab_amoeba[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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_bug, element);
+ goto loop;
+
+ default:
+ Cave[y][x] = Ybug_w_s;
+ Next[y][x] = Xbug_gos;
+ play_element_sound(x, y, SAMPLE_bug, element);
+ goto loop;
+ }
+
+ /* --------------------------------------------------------------------- */
+
+ case Xtank_n:
+ if (tab_amoeba[Cave[y-1][x]] ||
+ tab_amoeba[Cave[y][x+1]] ||
+ tab_amoeba[Cave[y+1][x]] ||
+ tab_amoeba[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_element_sound(x, y, SAMPLE_tank, element);
+ goto loop;
+
+ default:
+ goto tank_gon;
+ }
+
+ case Xtank_gon:
+ if (tab_amoeba[Cave[y-1][x]] ||
+ tab_amoeba[Cave[y][x+1]] ||
+ tab_amoeba[Cave[y+1][x]] ||
+ tab_amoeba[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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_tank, element);
+ goto loop;
+
+ default:
+ Cave[y][x] = Ytank_n_e;
+ Next[y][x] = Xtank_goe;
+ play_element_sound(x, y, SAMPLE_tank, element);
+ goto loop;
+ }
+
+ /* --------------------------------------------------------------------- */
+
+ case Xtank_e:
+ if (tab_amoeba[Cave[y-1][x]] ||
+ tab_amoeba[Cave[y][x+1]] ||
+ tab_amoeba[Cave[y+1][x]] ||
+ tab_amoeba[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_element_sound(x, y, SAMPLE_tank, element);
+ goto loop;
+
+ default:
+ goto tank_goe;
+ }
+
+ case Xtank_goe:
+ if (tab_amoeba[Cave[y-1][x]] ||
+ tab_amoeba[Cave[y][x+1]] ||
+ tab_amoeba[Cave[y+1][x]] ||
+ tab_amoeba[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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_tank, element);
+ goto loop;
+
+ default:
+ Cave[y][x] = Ytank_e_s;
+ Next[y][x] = Xtank_gos;
+ play_element_sound(x, y, SAMPLE_tank, element);
+ goto loop;
+ }
+
+ /* --------------------------------------------------------------------- */
+
+ case Xtank_s:
+ if (tab_amoeba[Cave[y-1][x]] ||
+ tab_amoeba[Cave[y][x+1]] ||
+ tab_amoeba[Cave[y+1][x]] ||
+ tab_amoeba[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_element_sound(x, y, SAMPLE_tank, element);
+ goto loop;
+
+ default:
+ goto tank_gos;
+ }
+
+ case Xtank_gos:
+ if (tab_amoeba[Cave[y-1][x]] ||
+ tab_amoeba[Cave[y][x+1]] ||
+ tab_amoeba[Cave[y+1][x]] ||
+ tab_amoeba[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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_tank, element);
+ goto loop;
+
+ default:
+ Cave[y][x] = Ytank_s_w;
+ Next[y][x] = Xtank_gow;
+ play_element_sound(x, y, SAMPLE_tank, element);
+ goto loop;
+ }
+
+ /* --------------------------------------------------------------------- */
+
+ case Xtank_w:
+ if (tab_amoeba[Cave[y-1][x]] ||
+ tab_amoeba[Cave[y][x+1]] ||
+ tab_amoeba[Cave[y+1][x]] ||
+ tab_amoeba[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_element_sound(x, y, SAMPLE_tank, element);
+ goto loop;
+
+ default:
+ goto tank_gow;
+ }
+
+ case Xtank_gow:
+ if (tab_amoeba[Cave[y-1][x]] ||
+ tab_amoeba[Cave[y][x+1]] ||
+ tab_amoeba[Cave[y+1][x]] ||
+ tab_amoeba[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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_tank, element);
+ goto loop;
+
+ default:
+ Cave[y][x] = Ytank_w_n;
+ Next[y][x] = Xtank_gon;
+ play_element_sound(x, y, SAMPLE_tank, element);
+ 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_element_sound(x, y, SAMPLE_android_clone, temp);
+
+ 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 counterclockwise 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_element_sound(x, y, SAMPLE_android_move, element);
+ goto loop;
+
+ android_ne:
+
+ Cave[y][x] = Yandroid_neB;
+ Cave[y-1][x+1] = Yandroid_ne;
+ Next[y-1][x+1] = Xandroid;
+ play_element_sound(x, y, SAMPLE_android_move, element);
+ goto loop;
+
+ android_e:
+
+ Cave[y][x] = Yandroid_eB;
+ Cave[y][x+1] = Yandroid_e;
+ Next[y][x+1] = Xandroid;
+ play_element_sound(x, y, SAMPLE_android_move, element);
+ goto loop;
+
+ android_se:
+
+ Cave[y][x] = Yandroid_seB;
+ Cave[y+1][x+1] = Yandroid_se;
+ Next[y+1][x+1] = Xandroid;
+ play_element_sound(x, y, SAMPLE_android_move, element);
+ goto loop;
+
+ android_s:
+
+ Cave[y][x] = Yandroid_sB;
+ Cave[y+1][x] = Yandroid_s;
+ Next[y+1][x] = Xandroid;
+ play_element_sound(x, y, SAMPLE_android_move, element);
+ goto loop;
+
+ android_sw:
+
+ Cave[y][x] = Yandroid_swB;
+ Cave[y+1][x-1] = Yandroid_sw;
+ Next[y+1][x-1] = Xandroid;
+ play_element_sound(x, y, SAMPLE_android_move, element);
+ goto loop;
+
+ android_w:
+
+ Cave[y][x] = Yandroid_wB;
+ Cave[y][x-1] = Yandroid_w;
+ Next[y][x-1] = Xandroid;
+ play_element_sound(x, y, SAMPLE_android_move, element);
+ goto loop;
+
+ android_nw:
+
+ Cave[y][x] = Yandroid_nwB;
+ Cave[y-1][x-1] = Yandroid_nw;
+ Next[y-1][x-1] = Xandroid;
+ play_element_sound(x, y, SAMPLE_android_move, element);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_android_move, element);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_android_move, element);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_android_move, element);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_android_move, element);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_android_move, element);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_android_move, element);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_android_move, element);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_android_move, element);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_slurp, Xalien);
+ score += lev.slurp_score;
+ goto loop;
+
+ case Xbumper:
+ case XbumperB:
+ Cave[y][x+1] = XbumperB;
+ Next[y][x] = Xspring_w;
+ play_element_sound(x, y, SAMPLE_spring, Xspring);
+ goto loop;
+
+ default:
+ Cave[y][x] = Xspring;
+ Next[y][x] = Xspring;
+ play_element_sound(x, y, SAMPLE_spring, Xspring);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_slurp, Xalien);
+ score += lev.slurp_score;
+ goto loop;
+
+ case Xbumper:
+ case XbumperB:
+ Cave[y][x-1] = XbumperB;
+ Next[y][x] = Xspring_e;
+ play_element_sound(x, y, SAMPLE_spring, Xspring);
+ goto loop;
+
+ default:
+ Cave[y][x] = Xspring;
+ Next[y][x] = Xspring;
+ play_element_sound(x, y, SAMPLE_spring, Xspring);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, element);
+#endif
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, element);
+#endif
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, element);
+#endif
+ 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];
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, element);
+#endif
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, element);
+#endif
+ score += lev.alien_score;
+ goto loop;
+
+ default:
+ Cave[y][x] = Xspring;
+ Next[y][x] = Xspring;
+ play_element_sound(x, y, SAMPLE_spring, Xspring);
+ goto loop;
+ }
+
+ /* --------------------------------------------------------------------- */
+
+ case Xeater_n:
+ if (Cave[y][x+1] == Xdiamond)
+ {
+ Cave[y][x+1] = Ydiamond_eat;
+ Next[y][x+1] = Xblank;
+ play_element_sound(x, y, SAMPLE_eater_eat, element);
+ goto loop;
+ }
+
+ if (Cave[y+1][x] == Xdiamond)
+ {
+ Cave[y+1][x] = Ydiamond_eat;
+ Next[y+1][x] = Xblank;
+ play_element_sound(x, y, SAMPLE_eater_eat, element);
+ goto loop;
+ }
+
+ if (Cave[y][x-1] == Xdiamond)
+ {
+ Cave[y][x-1] = Ydiamond_eat;
+ Next[y][x-1] = Xblank;
+ play_element_sound(x, y, SAMPLE_eater_eat, element);
+ goto loop;
+ }
+
+ if (Cave[y-1][x] == Xdiamond)
+ {
+ Cave[y-1][x] = Ydiamond_eat;
+ Next[y-1][x] = Xblank;
+ play_element_sound(x, y, SAMPLE_eater_eat, element);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_eater, element);
+ goto loop;
+ }
+
+ /* --------------------------------------------------------------------- */
+
+ case Xeater_e:
+ if (Cave[y+1][x] == Xdiamond)
+ {
+ Cave[y+1][x] = Ydiamond_eat;
+ Next[y+1][x] = Xblank;
+ play_element_sound(x, y, SAMPLE_eater_eat, element);
+ goto loop;
+ }
+
+ if (Cave[y][x-1] == Xdiamond)
+ {
+ Cave[y][x-1] = Ydiamond_eat;
+ Next[y][x-1] = Xblank;
+ play_element_sound(x, y, SAMPLE_eater_eat, element);
+ goto loop;
+ }
+
+ if (Cave[y-1][x] == Xdiamond)
+ {
+ Cave[y-1][x] = Ydiamond_eat;
+ Next[y-1][x] = Xblank;
+ play_element_sound(x, y, SAMPLE_eater_eat, element);
+ goto loop;
+ }
+
+ if (Cave[y][x+1] == Xdiamond)
+ {
+ Cave[y][x+1] = Ydiamond_eat;
+ Next[y][x+1] = Xblank;
+ play_element_sound(x, y, SAMPLE_eater_eat, element);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_eater, element);
+ goto loop;
+ }
+
+ /* --------------------------------------------------------------------- */
+
+ case Xeater_s:
+ if (Cave[y][x-1] == Xdiamond)
+ {
+ Cave[y][x-1] = Ydiamond_eat;
+ Next[y][x-1] = Xblank;
+ play_element_sound(x, y, SAMPLE_eater_eat, element);
+ goto loop;
+ }
+
+ if (Cave[y-1][x] == Xdiamond)
+ {
+ Cave[y-1][x] = Ydiamond_eat;
+ Next[y-1][x] = Xblank;
+ play_element_sound(x, y, SAMPLE_eater_eat, element);
+ goto loop;
+ }
+
+ if (Cave[y][x+1] == Xdiamond)
+ {
+ Cave[y][x+1] = Ydiamond_eat;
+ Next[y][x+1] = Xblank;
+ play_element_sound(x, y, SAMPLE_eater_eat, element);
+ goto loop;
+ }
+
+ if (Cave[y+1][x] == Xdiamond)
+ {
+ Cave[y+1][x] = Ydiamond_eat;
+ Next[y+1][x] = Xblank;
+ play_element_sound(x, y, SAMPLE_eater_eat, element);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_eater, element);
+ goto loop;
+ }
+
+ /* --------------------------------------------------------------------- */
+
+ case Xeater_w:
+ if (Cave[y-1][x] == Xdiamond)
+ {
+ Cave[y-1][x] = Ydiamond_eat;
+ Next[y-1][x] = Xblank;
+ play_element_sound(x, y, SAMPLE_eater_eat, element);
+ goto loop;
+ }
+
+ if (Cave[y][x+1] == Xdiamond)
+ {
+ Cave[y][x+1] = Ydiamond_eat;
+ Next[y][x+1] = Xblank;
+ play_element_sound(x, y, SAMPLE_eater_eat, element);
+ goto loop;
+ }
+
+ if (Cave[y+1][x] == Xdiamond)
+ {
+ Cave[y+1][x] = Ydiamond_eat;
+ Next[y+1][x] = Xblank;
+ play_element_sound(x, y, SAMPLE_eater_eat, element);
+ goto loop;
+ }
+
+ if (Cave[y][x-1] == Xdiamond)
+ {
+ Cave[y][x-1] = Ydiamond_eat;
+ Next[y][x-1] = Xblank;
+ play_element_sound(x, y, SAMPLE_eater_eat, element);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_eater, element);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_alien, Xalien);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_alien, Xalien);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_alien, Xalien);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_alien, Xalien);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_wonderfall, Xwonderwall);
+ goto loop;
+ }
+
+ default:
+ Cave[y][x] = Xemerald;
+ Next[y][x] = Xemerald;
+ play_element_sound(x, y, SAMPLE_diamond, Xemerald);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_wonderfall, Xwonderwall);
+ goto loop;
+ }
+
+ default:
+ Cave[y][x] = Xdiamond;
+ Next[y][x] = Xdiamond;
+ play_element_sound(x, y, SAMPLE_diamond, Xdiamond);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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 = Xamoeba_1;
+ break;
+
+ case 1:
+ temp = Xamoeba_2;
+ break;
+
+ case 2:
+ temp = Xamoeba_3;
+ break;
+
+ case 3:
+ temp = Xamoeba_4;
+ break;
+
+ case 4:
+ temp = Xamoeba_5;
+ break;
+
+ case 5:
+ temp = Xamoeba_6;
+ break;
+
+ case 6:
+ temp = Xamoeba_7;
+ break;
+
+ case 7:
+ temp = Xamoeba_8;
+ break;
+ }
+
+ Cave[y][x] = temp;
+ Next[y][x] = temp;
+ play_element_sound(x, y, SAMPLE_drip, Xdrip_fall);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, element);
+#endif
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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 Xfake_acid_1:
+ Next[y][x] = Xfake_acid_2;
+ goto loop;
+
+ case Xfake_acid_2:
+ Next[y][x] = Xfake_acid_3;
+ goto loop;
+
+ case Xfake_acid_3:
+ Next[y][x] = Xfake_acid_4;
+ goto loop;
+
+ case Xfake_acid_4:
+ Next[y][x] = Xfake_acid_5;
+ goto loop;
+
+ case Xfake_acid_5:
+ Next[y][x] = Xfake_acid_6;
+ goto loop;
+
+ case Xfake_acid_6:
+ Next[y][x] = Xfake_acid_7;
+ goto loop;
+
+ case Xfake_acid_7:
+ Next[y][x] = Xfake_acid_8;
+ goto loop;
+
+ case Xfake_acid_8:
+ Next[y][x] = Xfake_acid_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_element_sound(x, y, SAMPLE_ball, element);
+ 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_element_sound(x, y, SAMPLE_grow, Xgrow_ns);
+ }
+
+ if (tab_blank[Cave[y+1][x]])
+ {
+ Cave[y+1][x] = Ygrow_ns_eat;
+ Next[y+1][x] = Xgrow_ns;
+ play_element_sound(x, y, SAMPLE_grow, Xgrow_ns);
+ }
+
+ 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_element_sound(x, y, SAMPLE_grow, Xgrow_ew);
+ }
+
+ if (tab_blank[Cave[y][x-1]])
+ {
+ Cave[y][x-1] = Ygrow_ew_eat;
+ Next[y][x-1] = Xgrow_ew;
+ play_element_sound(x, y, SAMPLE_grow, Xgrow_ew);
+ }
+
+ goto loop;
+
+ /* --------------------------------------------------------------------- */
+
+ case Xwonderwall:
+ if (lev.wonderwall_time && lev.wonderwall_state)
+ {
+ Cave[y][x] = XwonderwallB;
+ play_element_sound(x, y, SAMPLE_wonder, Xwonderwall);
+ }
+
+ 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;
+ }
+
+ play_element_sound(x, y, SAMPLE_exit_open, Xexit);
+
+ 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_element_sound(x, y, SAMPLE_tick, Xdynamite_1);
+ Next[y][x] = Xdynamite_2;
+ goto loop;
+
+ case Xdynamite_2:
+ play_element_sound(x, y, SAMPLE_tick, Xdynamite_2);
+ Next[y][x] = Xdynamite_3;
+ goto loop;
+
+ case Xdynamite_3:
+ play_element_sound(x, y, SAMPLE_tick, Xdynamite_3);
+ Next[y][x] = Xdynamite_4;
+ goto loop;
+
+ case Xdynamite_4:
+ play_element_sound(x, y, SAMPLE_tick, Xdynamite_4);
+ 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_element_sound(x, y, SAMPLE_acid, Xacid_1);
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, element);
+#endif
+ 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;
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, element);
+#endif
+ goto loop;
+
+ case Xboom_android:
+#if 0
+ play_element_sound(x, y, SAMPLE_boom, Xandroid);
+#endif
+ case Xboom_1:
+ Next[y][x] = Xboom_2;
+#if 1
+ play_sound(x, y, SAMPLE_boom);
+#endif
+ 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 */
+
+ RandomEM = random;
+
+ {
+ void *temp = Cave;
+
+ /* triple buffering */
+ Cave = Next;
+ Next = Draw;
+ Draw = temp;
+ }
+}
--- /dev/null
+/* 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 0
+#if 1
+ if (lev.time_initial == 0)
+ lev.time++;
+ else if (lev.time > 0)
+ lev.time--;
+#else
+ if (lev.time)
+ lev.time--;
+#endif
+#endif
+
+ 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 0
+ if (lev.time_initial > 0 &&
+ lev.time > 0 && lev.time <= 50 && lev.time % 5 == 0 && setup.time_limit)
+ play_sound(-1, -1, SAMPLE_time);
+#endif
+
+ if (lev.wheel_cnt)
+ play_element_sound(lev.wheel_x, lev.wheel_y, SAMPLE_wheel, Xwheel);
+
+ /* grow amoeba */
+
+ random = RandomEM;
+
+ for (count = lev.amoeba_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_amoeba[Cave[y-1][x]] ||
+ tab_amoeba[Cave[y][x+1]] ||
+ tab_amoeba[Cave[y+1][x]] ||
+ tab_amoeba[Cave[y][x-1]])
+ Cave[y][x] = Xdrip_eat;
+ }
+
+ random = random * 129 + 1;
+ }
+
+ RandomEM = 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];
+}
--- /dev/null
+/* 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 "tile.h"
+#include "display.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=amoeba */
+int tile_amoeba[] =
+{
+ Xdripper, 1,
+ XdripperB, 1,
+ Xamoeba_1, 1,
+ Xamoeba_2, 1,
+ Xamoeba_3, 1,
+ Xamoeba_4, 1,
+ Xamoeba_5, 1,
+ Xamoeba_6, 1,
+ Xamoeba_7, 1,
+ Xamoeba_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,
+
+#if 0
+ /* use normal "Xblank" instead of explicit x==0, y==2 empty space graphic */
+ Ynut_sB, 7,
+#endif
+
+ -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,
+
+ Xamoeba_1, 0,
+ Xamoeba_1, 1,
+ Xamoeba_1, 2,
+ Xamoeba_1, 3,
+ Xamoeba_1, 4,
+ Xamoeba_1, 5,
+ Xamoeba_1, 6,
+ Xamoeba_1, 7,
+ -1,
+ Xamoeba_2, 0,
+ Xamoeba_2, 1,
+ Xamoeba_2, 2,
+ Xamoeba_2, 3,
+ Xamoeba_2, 4,
+ Xamoeba_2, 5,
+ Xamoeba_2, 6,
+ Xamoeba_2, 7,
+ -1,
+ Xamoeba_3, 0,
+ Xamoeba_3, 1,
+ Xamoeba_3, 2,
+ Xamoeba_3, 3,
+ Xamoeba_3, 4,
+ Xamoeba_3, 5,
+ Xamoeba_3, 6,
+ Xamoeba_3, 7,
+ -1,
+ Xamoeba_4, 0,
+ Xamoeba_4, 1,
+ Xamoeba_4, 2,
+ Xamoeba_4, 3,
+ Xamoeba_4, 4,
+ Xamoeba_4, 5,
+ Xamoeba_4, 6,
+ Xamoeba_4, 7,
+ -1,
+ Xamoeba_5, 0,
+ Xamoeba_5, 1,
+ Xamoeba_5, 2,
+ Xamoeba_5, 3,
+ Xamoeba_5, 4,
+ Xamoeba_5, 5,
+ Xamoeba_5, 6,
+ Xamoeba_5, 7,
+ -1,
+ Xamoeba_6, 0,
+ Xamoeba_6, 1,
+ Xamoeba_6, 2,
+ Xamoeba_6, 3,
+ Xamoeba_6, 4,
+ Xamoeba_6, 5,
+ Xamoeba_6, 6,
+ Xamoeba_6, 7,
+ -1,
+ Xamoeba_7, 0,
+ Xamoeba_7, 1,
+ Xamoeba_7, 2,
+ Xamoeba_7, 3,
+ Xamoeba_7, 4,
+ Xamoeba_7, 5,
+ Xamoeba_7, 6,
+ Xamoeba_7, 7,
+ -1,
+ Xamoeba_8, 0,
+ Xamoeba_8, 1,
+ Xamoeba_8, 2,
+ Xamoeba_8, 3,
+ Xamoeba_8, 4,
+ Xamoeba_8, 5,
+ Xamoeba_8, 6,
+ Xamoeba_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,
+ Ykey_1_eat, 7,
+ Ykey_1_eat, 6,
+ Ykey_1_eat, 5,
+ Ykey_2_eat, 7,
+ Ykey_2_eat, 6,
+ Ykey_2_eat, 5,
+ Ykey_3_eat, 7,
+ Ykey_3_eat, 6,
+ Ykey_3_eat, 5,
+ Ykey_4_eat, 7,
+ Ykey_4_eat, 6,
+ Ykey_4_eat, 5,
+ Ykey_5_eat, 7,
+ Ykey_5_eat, 6,
+ Ykey_5_eat, 5,
+ Ykey_6_eat, 7,
+ Ykey_6_eat, 6,
+ Ykey_6_eat, 5,
+ Ykey_7_eat, 7,
+ Ykey_7_eat, 6,
+ Ykey_7_eat, 5,
+ Ykey_8_eat, 7,
+ Ykey_8_eat, 6,
+ Ykey_8_eat, 5,
+ Ylenses_eat, 7,
+ Ylenses_eat, 6,
+ Ylenses_eat, 5,
+ Ymagnify_eat, 7,
+ Ymagnify_eat, 6,
+ Ymagnify_eat, 5,
+ Ygrass_eat, 7,
+ Ygrass_eat, 6,
+ Ygrass_eat, 5,
+ Ydirt_eat, 7,
+ Ydirt_eat, 6,
+ Ydirt_eat, 5,
+ Xboom_2, 7,
+ Xboom_2, 6,
+ Xboom_2, 5,
+ -1,
+ Yball_eat, 4,
+ Yball_eat, 3,
+ Yball_eat, 2,
+ Ykey_1_eat, 4,
+ Ykey_1_eat, 3,
+ Ykey_1_eat, 2,
+ Ykey_2_eat, 4,
+ Ykey_2_eat, 3,
+ Ykey_2_eat, 2,
+ Ykey_3_eat, 4,
+ Ykey_3_eat, 3,
+ Ykey_3_eat, 2,
+ Ykey_4_eat, 4,
+ Ykey_4_eat, 3,
+ Ykey_4_eat, 2,
+ Ykey_5_eat, 4,
+ Ykey_5_eat, 3,
+ Ykey_5_eat, 2,
+ Ykey_6_eat, 4,
+ Ykey_6_eat, 3,
+ Ykey_6_eat, 2,
+ Ykey_7_eat, 4,
+ Ykey_7_eat, 3,
+ Ykey_7_eat, 2,
+ Ykey_8_eat, 4,
+ Ykey_8_eat, 3,
+ Ykey_8_eat, 2,
+ Ylenses_eat, 4,
+ Ylenses_eat, 3,
+ Ylenses_eat, 2,
+ Ymagnify_eat, 4,
+ Ymagnify_eat, 3,
+ Ymagnify_eat, 2,
+ Ygrass_eat, 4,
+ Ygrass_eat, 3,
+ Ygrass_eat, 2,
+ Ydirt_eat, 4,
+ Ydirt_eat, 3,
+ Ydirt_eat, 2,
+ Xboom_2, 4,
+ Xboom_2, 3,
+ Xboom_2, 2,
+ -1,
+ Yball_eat, 1,
+ Yball_eat, 0,
+ Ykey_1_eat, 1,
+ Ykey_1_eat, 0,
+ Ykey_2_eat, 1,
+ Ykey_2_eat, 0,
+ Ykey_3_eat, 1,
+ Ykey_3_eat, 0,
+ Ykey_4_eat, 1,
+ Ykey_4_eat, 0,
+ Ykey_5_eat, 1,
+ Ykey_5_eat, 0,
+ Ykey_6_eat, 1,
+ Ykey_6_eat, 0,
+ Ykey_7_eat, 1,
+ Ykey_7_eat, 0,
+ Ykey_8_eat, 1,
+ Ykey_8_eat, 0,
+ Ylenses_eat, 1,
+ Ylenses_eat, 0,
+ Ymagnify_eat, 1,
+ Ymagnify_eat, 0,
+ Ygrass_eat, 1,
+ Ygrass_eat, 0,
+ Ydirt_eat, 1,
+ Ydirt_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
+};
+
+
+/* 0=stop 1=blank */
+unsigned char tab_blank[TILE_MAX];
+
+/* 0=stop 1=acid */
+unsigned char tab_acid[TILE_MAX];
+
+/* 0=stop 1=amoeba */
+unsigned char tab_amoeba[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];
+
+/* map tiles and frames to graphic info */
+struct GraphicInfo_EM graphic_info_em_object[TILE_MAX][8];
+
+/* map player number, frames and action to graphic info */
+struct GraphicInfo_EM graphic_info_em_player[2][SPR_MAX][8];
+
+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_obj_graphics_info_em()
+{
+ int i, j;
+
+ for (i = 0; i < TILE_MAX; i++)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ struct GraphicInfo_EM *g = &graphic_info_em_object[i][j];
+ int obj = map_obj[j][i];
+
+ g->bitmap = objBitmap;
+ g->src_x = (obj / 512) * TILEX;
+ g->src_y = (obj % 512) * TILEY / 16;
+ g->src_offset_x = 0;
+ g->src_offset_y = 0;
+ g->dst_offset_x = 0;
+ g->dst_offset_y = 0;
+ g->width = TILEX;
+ g->height = TILEY;
+
+ g->crumbled_bitmap = NULL;
+ g->crumbled_src_x = 0;
+ g->crumbled_src_y = 0;
+ g->crumbled_border_size = 0;
+
+ g->has_crumbled_graphics = FALSE;
+ g->preserve_background = FALSE;
+
+ /* create unique graphic identifier to decide if tile must be redrawn */
+ g->unique_identifier = obj;
+ }
+ }
+}
+
+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_spr_graphics_info_em()
+{
+ int i, j, k;
+
+ for (i = 0; i < 2; i++)
+ {
+ for (j = 0; j < SPR_MAX; j++)
+ {
+ for (k = 0; k < 8; k++)
+ {
+ struct GraphicInfo_EM *g = &graphic_info_em_player[i][j][k];
+ int spr = map_spr[i][k][j];
+
+ g->bitmap = sprBitmap;
+ g->src_x = (spr / 8) * TILEX;
+ g->src_y = (spr % 8) * TILEY;
+ g->src_offset_x = 0;
+ g->src_offset_y = 0;
+ g->dst_offset_x = 0;
+ g->dst_offset_y = 0;
+ g->width = TILEX;
+ g->height = TILEY;
+
+ g->has_crumbled_graphics = FALSE;
+ g->crumbled_bitmap = NULL;
+ g->crumbled_src_x = 0;
+ g->crumbled_src_y = 0;
+ g->crumbled_border_size = 0;
+
+ g->unique_identifier = 0;
+ }
+ }
+ }
+}
+
+void tab_generate()
+{
+ create_tab(tile_blank, tab_blank);
+ create_tab(tile_acid, tab_acid);
+ create_tab(tile_amoeba, tab_amoeba);
+ create_tab(tile_android_move, tab_android_move);
+ create_explode();
+ create_obj();
+ create_spr();
+}
+
+void tab_generate_graphics_info_em()
+{
+ create_obj_graphics_info_em();
+ create_spr_graphics_info_em();
+
+ InitGraphicInfo_EM();
+}
--- /dev/null
+#ifndef TILE_H
+#define TILE_H
+
+#include "main_em.h"
+
+#ifdef EM_ENGINE_BAD_ROLL
+#define BAD_ROLL
+#endif
+
+#ifdef EM_ENGINE_BAD_SPRING
+#define BAD_SPRING
+#endif
+
+
+#if 0
+
+/* 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,
+ Xamoeba_1,
+ Xamoeba_2,
+ Xamoeba_3,
+ Xamoeba_4,
+ Xamoeba_5,
+ Xamoeba_6,
+ Xamoeba_7,
+ Xamoeba_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
+};
+
+#endif
+
+extern unsigned char tab_blank[TILE_MAX];
+extern unsigned char tab_acid[TILE_MAX];
+extern unsigned char tab_amoeba[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
--- /dev/null
+/* 2000-08-10T04:29:10Z
+ *
+ * generate ulaw<->linear conversion tables to be included
+ * directly in emerald mine source
+ */
+
+#include "main_em.h"
+
+
+#if defined(PLATFORM_LINUX) || defined(PLATFORM_BSD)
+
+int calc_ulaw_to_linear(unsigned char);
+unsigned char calc_linear_to_ulaw(int);
+
+int buffer[65536];
+
+/* 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) */
#define CONFIG_TOKEN_FONT_INITIAL "font.initial"
-struct FontBitmapInfo font_initial[NUM_INITIAL_FONTS];
+static struct FontBitmapInfo font_initial[NUM_INITIAL_FONTS];
+static int copy_properties[][5] =
+{
+ {
+ EL_BUG,
+ EL_BUG_LEFT, EL_BUG_RIGHT,
+ EL_BUG_UP, EL_BUG_DOWN
+ },
+ {
+ EL_SPACESHIP,
+ EL_SPACESHIP_LEFT, EL_SPACESHIP_RIGHT,
+ EL_SPACESHIP_UP, EL_SPACESHIP_DOWN
+ },
+ {
+ EL_BD_BUTTERFLY,
+ EL_BD_BUTTERFLY_LEFT, EL_BD_BUTTERFLY_RIGHT,
+ EL_BD_BUTTERFLY_UP, EL_BD_BUTTERFLY_DOWN
+ },
+ {
+ EL_BD_FIREFLY,
+ EL_BD_FIREFLY_LEFT, EL_BD_FIREFLY_RIGHT,
+ EL_BD_FIREFLY_UP, EL_BD_FIREFLY_DOWN
+ },
+ {
+ EL_PACMAN,
+ EL_PACMAN_LEFT, EL_PACMAN_RIGHT,
+ EL_PACMAN_UP, EL_PACMAN_DOWN
+ },
+ {
+ EL_MOLE,
+ EL_MOLE_LEFT, EL_MOLE_RIGHT,
+ EL_MOLE_UP, EL_MOLE_DOWN
+ },
+ {
+ -1,
+ -1, -1, -1, -1
+ }
+};
static void InitTileClipmasks()
{
gadgets_initialized = TRUE;
}
+inline void InitElementSmallImagesScaledUp(int graphic)
+{
+ CreateImageWithSmallImages(graphic, graphic_info[graphic].scale_up_factor);
+}
+
void InitElementSmallImages()
{
struct PropertyMapping *property_mapping = getImageListPropertyMapping();
/* initialize normal images from static configuration */
for (i = 0; element_to_graphic[i].element > -1; i++)
- CreateImageWithSmallImages(element_to_graphic[i].graphic);
+ InitElementSmallImagesScaledUp(element_to_graphic[i].graphic);
/* initialize special images from static configuration */
for (i = 0; element_to_special_graphic[i].element > -1; i++)
- CreateImageWithSmallImages(element_to_special_graphic[i].graphic);
+ InitElementSmallImagesScaledUp(element_to_special_graphic[i].graphic);
- /* initialize images from dynamic configuration */
+ /* initialize images from dynamic configuration (may be elements or other) */
+#if 1
+ for (i = 0; i < num_property_mappings; i++)
+ InitElementSmallImagesScaledUp(property_mapping[i].artwork_index);
+#else
+ /* !!! THIS DOES NOT WORK -- "artwork_index" is graphic, not element !!! */
+ /* !!! ALSO, non-element graphics might need scaling-up !!! */
for (i = 0; i < num_property_mappings; i++)
if (property_mapping[i].artwork_index < MAX_NUM_ELEMENTS)
- CreateImageWithSmallImages(property_mapping[i].artwork_index);
+ InitElementSmallImagesScaledUp(property_mapping[i].artwork_index);
+#endif
+
+#if 0
+ /* !!! FIX THIS (CHANGE TO USING NORMAL ELEMENT GRAPHIC DEFINITIONS) !!! */
+ for (i = IMG_EMC_OBJECT; i <= IMG_EMC_SPRITE; i++)
+ InitElementSmallImagesScaledUp(i);
+#endif
}
+#if 1
+/* !!! FIX THIS (CHANGE TO USING NORMAL ELEMENT GRAPHIC DEFINITIONS) !!! */
+void SetBitmaps_EM(Bitmap **em_bitmap)
+{
+ em_bitmap[0] = graphic_info[IMG_EMC_OBJECT].bitmap;
+ em_bitmap[1] = graphic_info[IMG_EMC_SPRITE].bitmap;
+}
+#endif
+
static int getFontBitmapID(int font_nr)
{
int special = -1;
if ((action > -1 || direction > -1 || crumbled == TRUE) &&
base_graphic != -1)
{
- boolean base_redefined = getImageListEntry(base_graphic)->redefined;
- boolean act_dir_redefined = getImageListEntry(graphic)->redefined;
+ boolean base_redefined =
+ getImageListEntryFromImageID(base_graphic)->redefined;
+ boolean act_dir_redefined =
+ getImageListEntryFromImageID(graphic)->redefined;
/* if the base graphic ("emerald", for example) has been redefined,
but not the action graphic ("emerald.falling", for example), do not
}
}
+#if 1
+ /* set hardcoded definitions for some runtime elements without graphic */
+ element_info[EL_AMOEBA_TO_DIAMOND].graphic[ACTION_DEFAULT] = IMG_AMOEBA_DEAD;
+#endif
+
#if 1
/* now set all undefined/invalid graphics to -1 to set to default after it */
for (i = 0; i < MAX_NUM_ELEMENTS; i++)
}
#endif
+#if 1
+ /* adjust graphics with 2nd tile for movement according to direction
+ (do this before correcting '-1' values to minimize calculations) */
+ for (i = 0; i < MAX_NUM_ELEMENTS; i++)
+ {
+ for (act = 0; act < NUM_ACTIONS; act++)
+ {
+ for (dir = 0; dir < NUM_DIRECTIONS; dir++)
+ {
+ int graphic = element_info[i].direction_graphic[act][dir];
+ int move_dir = (act == ACTION_FALLING ? MV_BIT_DOWN : dir);
+
+ if (act == ACTION_FALLING) /* special case */
+ graphic = element_info[i].graphic[act];
+
+ if (graphic != -1 &&
+ graphic_info[graphic].double_movement &&
+ graphic_info[graphic].swap_double_tiles != 0)
+ {
+ struct GraphicInfo *g = &graphic_info[graphic];
+ int src_x_front = g->src_x;
+ int src_y_front = g->src_y;
+ int src_x_back = g->src_x + g->offset2_x;
+ int src_y_back = g->src_y + g->offset2_y;
+ boolean frames_are_ordered_diagonally = (g->offset_x != 0 &&
+ g->offset_y != 0);
+ boolean front_is_left_or_upper = (src_x_front < src_x_back ||
+ src_y_front < src_y_back);
+#if 0
+ boolean second_tile_is_back =
+ ((move_dir == MV_BIT_LEFT && front_is_left_or_upper) ||
+ (move_dir == MV_BIT_UP && front_is_left_or_upper));
+ boolean second_tile_is_front =
+ ((move_dir == MV_BIT_RIGHT && front_is_left_or_upper) ||
+ (move_dir == MV_BIT_DOWN && front_is_left_or_upper));
+ boolean second_tile_should_be_front =
+ (g->second_tile_is_start == 0);
+ boolean second_tile_should_be_back =
+ (g->second_tile_is_start == 1);
+#endif
+ boolean swap_movement_tiles_always = (g->swap_double_tiles == 1);
+ boolean swap_movement_tiles_autodetected =
+ (!frames_are_ordered_diagonally &&
+ ((move_dir == MV_BIT_LEFT && !front_is_left_or_upper) ||
+ (move_dir == MV_BIT_UP && !front_is_left_or_upper) ||
+ (move_dir == MV_BIT_RIGHT && front_is_left_or_upper) ||
+ (move_dir == MV_BIT_DOWN && front_is_left_or_upper)));
+ Bitmap *dummy;
+
+#if 0
+ printf("::: CHECKING element %d ('%s'), '%s', dir %d [(%d -> %d, %d), %d => %d]\n",
+ i, element_info[i].token_name,
+ element_action_info[act].suffix, move_dir,
+ g->swap_double_tiles,
+ swap_movement_tiles_never,
+ swap_movement_tiles_always,
+ swap_movement_tiles_autodetected,
+ swap_movement_tiles);
+#endif
+
+ /* swap frontside and backside graphic tile coordinates, if needed */
+ if (swap_movement_tiles_always || swap_movement_tiles_autodetected)
+ {
+ /* get current (wrong) backside tile coordinates */
+ getGraphicSourceExt(graphic, 0, &dummy, &src_x_back, &src_y_back,
+ TRUE);
+
+ /* set frontside tile coordinates to backside tile coordinates */
+ g->src_x = src_x_back;
+ g->src_y = src_y_back;
+
+ /* invert tile offset to point to new backside tile coordinates */
+ g->offset2_x *= -1;
+ g->offset2_y *= -1;
+
+ /* do not swap front and backside tiles again after correction */
+ g->swap_double_tiles = 0;
+
+#if 0
+ printf(" CORRECTED\n");
+#endif
+ }
+ }
+ }
+ }
+ }
+#endif
+
/* now set all '-1' values to element specific default values */
for (i = 0; i < MAX_NUM_ELEMENTS; i++)
{
if (default_graphic == -1)
default_graphic = IMG_UNKNOWN;
+#if 1
+ if (default_crumbled == -1)
+ default_crumbled = default_graphic;
+#else
+ /* !!! THIS LOOKS CRAPPY FOR SAND ETC. WITHOUT CRUMBLED GRAPHICS !!! */
if (default_crumbled == -1)
default_crumbled = IMG_EMPTY;
+#endif
for (dir = 0; dir < NUM_DIRECTIONS; dir++)
{
if (default_direction_graphic[dir] == -1)
default_direction_graphic[dir] = default_graphic;
+#if 1
+ if (default_direction_crumbled[dir] == -1)
+ default_direction_crumbled[dir] = default_direction_graphic[dir];
+#else
+ /* !!! THIS LOOKS CRAPPY FOR SAND ETC. WITHOUT CRUMBLED GRAPHICS !!! */
if (default_direction_crumbled[dir] == -1)
default_direction_crumbled[dir] = default_crumbled;
+#endif
}
for (act = 0; act < NUM_ACTIONS; act++)
/* generic default action graphic (defined by "[default]" directive) */
int default_action_graphic = element_info[EL_DEFAULT].graphic[act];
int default_action_crumbled = element_info[EL_DEFAULT].crumbled[act];
+ int default_remove_graphic = IMG_EMPTY;
+
+ if (act_remove && default_action_graphic != -1)
+ default_remove_graphic = default_action_graphic;
/* look for special default action graphic (classic game specific) */
if (IS_BD_ELEMENT(i) && element_info[EL_BD_DEFAULT].graphic[act] != -1)
default_action_crumbled = element_info[EL_SB_DEFAULT].crumbled[act];
#if 1
+ /* !!! needed because EL_EMPTY_SPACE treated as IS_SP_ELEMENT !!! */
/* !!! make this better !!! */
if (i == EL_EMPTY_SPACE)
{
if (default_action_graphic == -1)
default_action_graphic = default_graphic;
+#if 1
+ if (default_action_crumbled == -1)
+ default_action_crumbled = default_action_graphic;
+#else
+ /* !!! THIS LOOKS CRAPPY FOR SAND ETC. WITHOUT CRUMBLED GRAPHICS !!! */
if (default_action_crumbled == -1)
default_action_crumbled = default_crumbled;
+#endif
for (dir = 0; dir < NUM_DIRECTIONS; dir++)
{
+ /* use action graphic as the default direction graphic, if undefined */
int default_action_direction_graphic = element_info[i].graphic[act];
int default_action_direction_crumbled = element_info[i].crumbled[act];
/* no graphic for current action -- use default direction graphic */
if (default_action_direction_graphic == -1)
default_action_direction_graphic =
- (act_remove ? IMG_EMPTY :
+ (act_remove ? default_remove_graphic :
act_turning ?
element_info[i].direction_graphic[ACTION_TURNING][dir] :
+ default_action_graphic != default_graphic ?
+ default_action_graphic :
default_direction_graphic[dir]);
+
+ if (element_info[i].direction_graphic[act][dir] == -1)
+ element_info[i].direction_graphic[act][dir] =
+ default_action_direction_graphic;
+
+#if 1
+ if (default_action_direction_crumbled == -1)
+ default_action_direction_crumbled =
+ element_info[i].direction_graphic[act][dir];
+#else
if (default_action_direction_crumbled == -1)
default_action_direction_crumbled =
- (act_remove ? IMG_EMPTY :
+ (act_remove ? default_remove_graphic :
act_turning ?
element_info[i].direction_crumbled[ACTION_TURNING][dir] :
+ default_action_crumbled != default_crumbled ?
+ default_action_crumbled :
default_direction_crumbled[dir]);
+#endif
- if (element_info[i].direction_graphic[act][dir] == -1)
- element_info[i].direction_graphic[act][dir] =
- default_action_direction_graphic;
if (element_info[i].direction_crumbled[act][dir] == -1)
element_info[i].direction_crumbled[act][dir] =
default_action_direction_crumbled;
+
+#if 0
+ if (i == EL_EMC_GRASS &&
+ act == ACTION_DIGGING &&
+ dir == MV_BIT_DOWN)
+ printf("::: direction_crumbled == %d, %d, %d\n",
+ element_info[i].direction_crumbled[act][dir],
+ default_action_direction_crumbled,
+ element_info[i].crumbled[act]);
+#endif
}
/* no graphic for this specific action -- use default action graphic */
if (element_info[i].graphic[act] == -1)
element_info[i].graphic[act] =
- (act_remove ? IMG_EMPTY :
+ (act_remove ? default_remove_graphic :
act_turning ? element_info[i].graphic[ACTION_TURNING] :
default_action_graphic);
+#if 1
+ if (element_info[i].crumbled[act] == -1)
+ element_info[i].crumbled[act] = element_info[i].graphic[act];
+#else
if (element_info[i].crumbled[act] == -1)
element_info[i].crumbled[act] =
- (act_remove ? IMG_EMPTY :
+ (act_remove ? default_remove_graphic :
act_turning ? element_info[i].crumbled[ACTION_TURNING] :
default_action_crumbled);
+#endif
}
}
int special = element_to_special_graphic[i].special;
int graphic = element_to_special_graphic[i].graphic;
int base_graphic = el2baseimg(element);
- boolean base_redefined = getImageListEntry(base_graphic)->redefined;
- boolean special_redefined = getImageListEntry(graphic)->redefined;
+ boolean base_redefined =
+ getImageListEntryFromImageID(base_graphic)->redefined;
+ boolean special_redefined =
+ getImageListEntryFromImageID(graphic)->redefined;
/* if the base graphic ("emerald", for example) has been redefined,
but not the special graphic ("emerald.EDITOR", for example), do not
return -1;
}
-static void set_graphic_parameters(int graphic, char **parameter_raw)
+static int get_scaled_graphic_width(int graphic)
{
- Bitmap *src_bitmap = getBitmapFromImageID(graphic);
+ int original_width = getOriginalImageWidthFromImageID(graphic);
+ int scale_up_factor = graphic_info[graphic].scale_up_factor;
+
+ return original_width * scale_up_factor;
+}
+
+static int get_scaled_graphic_height(int graphic)
+{
+ int original_height = getOriginalImageHeightFromImageID(graphic);
+ int scale_up_factor = graphic_info[graphic].scale_up_factor;
+
+ return original_height * scale_up_factor;
+}
+
+static void set_graphic_parameters(int graphic, int graphic_copy_from)
+{
+ struct FileInfo *image = getImageListEntryFromImageID(graphic_copy_from);
+ char **parameter_raw = image->parameter;
+ Bitmap *src_bitmap = getBitmapFromImageID(graphic_copy_from);
int parameter[NUM_GFX_ARGS];
int anim_frames_per_row = 1, anim_frames_per_col = 1;
int anim_frames_per_line = 1;
int i;
+#if 1
+#if 1
+
+ /* !!! NEW ARTWORK FALLBACK CODE !!! NEARLY UNTESTED !!! */
+ /* if fallback to default artwork is done, also use the default parameters */
+ if (image->fallback_to_default)
+ {
+#if 0
+ printf("::: FALLBACK for %d\n", graphic_copy_from);
+#endif
+
+ parameter_raw = image->default_parameter;
+ }
+
+#else
+
+ /* !!! ARTWORK FALLBACK CODE !!! NEARLY UNTESTED !!! */
+ /* (better try to set a "fallback -> use default parameters" flag) */
+ if (src_bitmap)
+ {
+ int len_source_filename = strlen(src_bitmap->source_filename);
+ int len_default_filename = strlen(image->default_filename);
+ int pos_basename = len_source_filename - len_default_filename;
+ char *source_basename = &src_bitmap->source_filename[pos_basename];
+
+#if 0
+ printf("::: src_bitmap->source_filename -> '%s'\n",
+ src_bitmap->source_filename);
+ printf("::: image->default_filename -> '%s'\n",
+ image->default_filename);
+ printf("::: image->filename -> '%s'\n",
+ image->filename);
+#endif
+
+ /* check if there was a fallback to the default artwork file */
+ if (strcmp(image->filename, image->default_filename) != 0 &&
+ pos_basename >= 0 &&
+ strcmp(source_basename, image->default_filename) == 0)
+ parameter_raw = image->default_parameter;
+ }
+#endif
+#endif
+
/* get integer values from string parameters */
for (i = 0; i < NUM_GFX_ARGS; i++)
{
graphic_info[graphic].height = TILEY;
graphic_info[graphic].offset_x = 0; /* one or both of these values ... */
graphic_info[graphic].offset_y = 0; /* ... will be corrected later */
+ graphic_info[graphic].offset2_x = 0; /* one or both of these values ... */
+ graphic_info[graphic].offset2_y = 0; /* ... will be corrected later */
+ graphic_info[graphic].swap_double_tiles = -1; /* auto-detect tile swapping */
graphic_info[graphic].crumbled_like = -1; /* do not use clone element */
graphic_info[graphic].diggable_like = -1; /* do not use clone element */
graphic_info[graphic].border_size = TILEX / 8; /* "CRUMBLED" border size */
+ graphic_info[graphic].scale_up_factor = 1; /* default: no scaling up */
graphic_info[graphic].anim_delay_fixed = 0;
graphic_info[graphic].anim_delay_random = 0;
graphic_info[graphic].post_delay_fixed = 0;
if (parameter[GFX_ARG_HEIGHT] != ARG_UNDEFINED_VALUE)
graphic_info[graphic].height = parameter[GFX_ARG_HEIGHT];
+ /* optional zoom factor for scaling up the image to a larger size */
+ if (parameter[GFX_ARG_SCALE_UP_FACTOR] != ARG_UNDEFINED_VALUE)
+ graphic_info[graphic].scale_up_factor = parameter[GFX_ARG_SCALE_UP_FACTOR];
+ if (graphic_info[graphic].scale_up_factor < 1)
+ graphic_info[graphic].scale_up_factor = 1; /* no scaling */
+
if (src_bitmap)
{
- anim_frames_per_row = src_bitmap->width / graphic_info[graphic].width;
- anim_frames_per_col = src_bitmap->height / graphic_info[graphic].height;
+ /* get final bitmap size (with scaling, but without small images) */
+ int src_bitmap_width = get_scaled_graphic_width(graphic);
+ int src_bitmap_height = get_scaled_graphic_height(graphic);
+
+ anim_frames_per_row = src_bitmap_width / graphic_info[graphic].width;
+ anim_frames_per_col = src_bitmap_height / graphic_info[graphic].height;
}
/* correct x or y offset dependent of vertical or horizontal frame order */
if (parameter[GFX_ARG_YOFFSET] != ARG_UNDEFINED_VALUE)
graphic_info[graphic].offset_y = parameter[GFX_ARG_YOFFSET];
+ /* optionally, moving animations may have separate start and end graphics */
+ graphic_info[graphic].double_movement = parameter[GFX_ARG_2ND_MOVEMENT_TILE];
+
+ if (parameter[GFX_ARG_2ND_VERTICAL] == ARG_UNDEFINED_VALUE)
+ parameter[GFX_ARG_2ND_VERTICAL] = !parameter[GFX_ARG_VERTICAL];
+
+ /* correct x or y offset2 dependent of vertical or horizontal frame order */
+ if (parameter[GFX_ARG_2ND_VERTICAL]) /* frames are ordered vertically */
+ graphic_info[graphic].offset2_y =
+ (parameter[GFX_ARG_2ND_OFFSET] != ARG_UNDEFINED_VALUE ?
+ parameter[GFX_ARG_2ND_OFFSET] : graphic_info[graphic].height);
+ else /* frames are ordered horizontally */
+ graphic_info[graphic].offset2_x =
+ (parameter[GFX_ARG_2ND_OFFSET] != ARG_UNDEFINED_VALUE ?
+ parameter[GFX_ARG_2ND_OFFSET] : graphic_info[graphic].width);
+
+ /* optionally, the x and y offset of 2nd graphic can be specified directly */
+ if (parameter[GFX_ARG_2ND_XOFFSET] != ARG_UNDEFINED_VALUE)
+ graphic_info[graphic].offset2_x = parameter[GFX_ARG_2ND_XOFFSET];
+ if (parameter[GFX_ARG_2ND_YOFFSET] != ARG_UNDEFINED_VALUE)
+ graphic_info[graphic].offset2_y = parameter[GFX_ARG_2ND_YOFFSET];
+
+ /* optionally, the second movement tile can be specified as start tile */
+ if (parameter[GFX_ARG_2ND_SWAP_TILES] != ARG_UNDEFINED_VALUE)
+ graphic_info[graphic].swap_double_tiles= parameter[GFX_ARG_2ND_SWAP_TILES];
+
/* automatically determine correct number of frames, if not defined */
if (parameter[GFX_ARG_FRAMES] != ARG_UNDEFINED_VALUE)
graphic_info[graphic].anim_frames = parameter[GFX_ARG_FRAMES];
static void InitGraphicInfo()
{
int fallback_graphic = IMG_CHAR_EXCLAM;
- struct FileInfo *fallback_image = getImageListEntry(fallback_graphic);
- Bitmap *fallback_bitmap = getBitmapFromImageID(fallback_graphic);
int num_images = getImageListSize();
int i;
for (i = 0; i < num_images; i++)
{
- struct FileInfo *image = getImageListEntry(i);
Bitmap *src_bitmap;
int src_x, src_y;
int first_frame, last_frame;
+ int src_bitmap_width, src_bitmap_height;
#if 0
printf("::: image: '%s' [%d]\n", image->token, i);
getTokenFromImageID(i));
#endif
- set_graphic_parameters(i, image->parameter);
+ set_graphic_parameters(i, i);
/* now check if no animation frames are outside of the loaded image */
if (graphic_info[i].bitmap == NULL)
continue; /* skip check for optional images that are undefined */
+ /* get final bitmap size (with scaling, but without small images) */
+ src_bitmap_width = get_scaled_graphic_width(i);
+ src_bitmap_height = get_scaled_graphic_height(i);
+
first_frame = 0;
getGraphicSource(i, first_frame, &src_bitmap, &src_x, &src_y);
if (src_x < 0 || src_y < 0 ||
- src_x + TILEX > src_bitmap->width ||
- src_y + TILEY > src_bitmap->height)
+ src_x + TILEX > src_bitmap_width ||
+ src_y + TILEY > src_bitmap_height)
{
Error(ERR_RETURN_LINE, "-");
Error(ERR_RETURN, "warning: error found in config file:");
src_x, src_y);
Error(ERR_RETURN, "custom graphic rejected for this element/action");
+#if 0
+ Error(ERR_RETURN, "scale_up_factor == %d", scale_up_factor);
+#endif
+
if (i == fallback_graphic)
Error(ERR_EXIT, "fatal error: no fallback graphic available");
Error(ERR_RETURN, "fallback done to 'char_exclam' for this graphic");
Error(ERR_RETURN_LINE, "-");
- set_graphic_parameters(i, fallback_image->default_parameter);
- graphic_info[i].bitmap = fallback_bitmap;
+ set_graphic_parameters(i, fallback_graphic);
}
last_frame = graphic_info[i].anim_frames - 1;
getGraphicSource(i, last_frame, &src_bitmap, &src_x, &src_y);
if (src_x < 0 || src_y < 0 ||
- src_x + TILEX > src_bitmap->width ||
- src_y + TILEY > src_bitmap->height)
+ src_x + TILEX > src_bitmap_width ||
+ src_y + TILEY > src_bitmap_height)
{
Error(ERR_RETURN_LINE, "-");
Error(ERR_RETURN, "warning: error found in config file:");
Error(ERR_RETURN, "fallback done to 'char_exclam' for this graphic");
Error(ERR_RETURN_LINE, "-");
- set_graphic_parameters(i, fallback_image->default_parameter);
- graphic_info[i].bitmap = fallback_bitmap;
+ set_graphic_parameters(i, fallback_graphic);
}
#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
- /* currently we need only a tile clip mask from the first frame */
+ /* currently we only need a tile clip mask from the first frame */
getGraphicSource(i, first_frame, &src_bitmap, &src_x, &src_y);
if (copy_clipmask_gc == None)
default_action_sound = element_info[i].sound[ACTION_DEFAULT];
#endif
+#if 1
+ /* !!! needed because EL_EMPTY_SPACE treated as IS_SP_ELEMENT !!! */
+ /* !!! make this better !!! */
+ if (i == EL_EMPTY_SPACE)
+ default_action_sound = element_info[EL_DEFAULT].sound[act];
+#endif
+
/* no sound for this specific action -- use default action sound */
if (element_info[i].sound[act] == -1)
element_info[i].sound[act] = default_action_sound;
}
}
+
+#if 1
+ /* copy sound settings to some elements that are only stored in level file
+ in native R'n'D levels, but are used by game engine in native EM levels */
+ for (i = 0; copy_properties[i][0] != -1; i++)
+ for (j = 1; j <= 4; j++)
+ for (act = 0; act < NUM_ACTIONS; act++)
+ element_info[copy_properties[i][j]].sound[act] =
+ element_info[copy_properties[i][0]].sound[act];
+#endif
}
static void InitGameModeSoundInfo()
/* explicit loop mode setting in configuration overrides default value */
if (parameter[SND_ARG_MODE_LOOP] != ARG_UNDEFINED_VALUE)
sound_info[sound].loop = parameter[SND_ARG_MODE_LOOP];
+
+ /* sound volume to change the original volume when loading the sound file */
+ sound_info[sound].volume = parameter[SND_ARG_VOLUME];
+
+ /* sound priority to give certain sounds a higher or lower priority */
+ sound_info[sound].volume = parameter[SND_ARG_VOLUME];
}
static void InitSoundInfo()
free(sound_effect_properties);
+#if 0
+ /* !!! MOVED TO "InitElementSoundInfo()" !!! */
+ /* !!! everything defined here gets overwritten there !!! */
+
+ /* copy sound settings to some elements that are only stored in level file
+ in native R'n'D levels, but are used by game engine in native EM levels */
+ for (i = 0; i < NUM_ACTIONS; i++)
+ for (j = 0; copy_properties[j][0] != -1; j++)
+ for (k = 1; k <= 4; k++)
+ element_info[copy_properties[j][k]].sound[i] =
+ element_info[copy_properties[j][0]].sound[i];
+
+ printf("::: bug -> %d\n", element_info[EL_BUG].sound[ACTION_MOVING]);
+ printf("::: bug_r -> %d\n", element_info[EL_BUG_RIGHT].sound[ACTION_MOVING]);
+#endif
+
#if 0
/* !!! now handled in InitElementSoundInfo() !!! */
/* initialize element/sound mapping from dynamic configuration */
InitElementGraphicInfo(); /* element game graphic mapping */
InitElementSpecialGraphicInfo(); /* element special graphic mapping */
- InitElementSmallImages(); /* create editor and preview images */
+ InitElementSmallImages(); /* scale images to all needed sizes */
InitFontGraphicInfo(); /* initialize text drawing functions */
+ InitGraphicInfo_EM(); /* graphic mapping for EM engine */
+
SetMainBackgroundImage(IMG_BACKGROUND);
SetDoorBackgroundImage(IMG_BACKGROUND_DOOR);
EL_TRAP,
EL_INVISIBLE_SAND,
EL_INVISIBLE_SAND_ACTIVE,
+ EL_EMC_GRASS,
/* !!! currently not diggable, but handled by 'ep_dont_run_into' !!! */
/* (if amoeba can grow into anything diggable, maybe keep these out) */
EL_LANDMINE,
EL_TRAP_ACTIVE,
EL_SP_BUGGY_BASE_ACTIVE,
+ EL_EMC_PLANT,
#endif
-1
};
EL_EM_KEY_2,
EL_EM_KEY_3,
EL_EM_KEY_4,
+ EL_EMC_KEY_5,
+ EL_EMC_KEY_6,
+ EL_EMC_KEY_7,
+ EL_EMC_KEY_8,
EL_DYNAMITE,
EL_DYNABOMB_INCREASE_NUMBER,
EL_DYNABOMB_INCREASE_SIZE,
EL_ENVELOPE_3,
EL_ENVELOPE_4,
EL_SPEED_PILL,
+ EL_EMC_LENSES,
+ EL_EMC_MAGNIFIER,
-1
};
EL_LANDMINE,
EL_TRAP_ACTIVE,
EL_SP_BUGGY_BASE_ACTIVE,
+ EL_EMC_PLANT,
#endif
-1
};
EL_EM_GATE_2_GRAY,
EL_EM_GATE_3_GRAY,
EL_EM_GATE_4_GRAY,
+ EL_EMC_GATE_5,
+ EL_EMC_GATE_6,
+ EL_EMC_GATE_7,
+ EL_EMC_GATE_8,
+ EL_EMC_GATE_5_GRAY,
+ EL_EMC_GATE_6_GRAY,
+ EL_EMC_GATE_7_GRAY,
+ EL_EMC_GATE_8_GRAY,
EL_SWITCHGATE_OPEN,
EL_SWITCHGATE_OPENING,
EL_SWITCHGATE_CLOSED,
EL_STEELWALL_SLIPPERY,
EL_PEARL,
EL_CRYSTAL,
+ EL_EMC_WALL_SLIPPERY_1,
+ EL_EMC_WALL_SLIPPERY_2,
+ EL_EMC_WALL_SLIPPERY_3,
+ EL_EMC_WALL_SLIPPERY_4,
-1
};
EL_SP_ELECTRON,
EL_BALLOON,
EL_SPRING,
+ EL_EMC_ANDROID,
-1
};
EL_PENGUIN,
EL_PIG,
EL_DRAGON,
+
+#if 0 /* USE_GRAVITY_BUGFIX_OLD */
+ EL_PLAYER_IS_LEAVING, /* needed for gravity + "block last field" */
+#endif
+
-1
};
EL_EM_GATE_2_GRAY,
EL_EM_GATE_3_GRAY,
EL_EM_GATE_4_GRAY,
+ EL_EMC_GATE_5,
+ EL_EMC_GATE_6,
+ EL_EMC_GATE_7,
+ EL_EMC_GATE_8,
+ EL_EMC_GATE_5_GRAY,
+ EL_EMC_GATE_6_GRAY,
+ EL_EMC_GATE_7_GRAY,
+ EL_EMC_GATE_8_GRAY,
EL_SWITCHGATE_OPEN,
EL_TIMEGATE_OPEN,
-1
EL_SATELLITE,
EL_SP_DISK_YELLOW,
EL_BALLOON,
+ EL_EMC_ANDROID,
-1
};
EL_EM_GATE_2_GRAY,
EL_EM_GATE_3_GRAY,
EL_EM_GATE_4_GRAY,
+ EL_EMC_GATE_5,
+ EL_EMC_GATE_6,
+ EL_EMC_GATE_7,
+ EL_EMC_GATE_8,
+ EL_EMC_GATE_5_GRAY,
+ EL_EMC_GATE_6_GRAY,
+ EL_EMC_GATE_7_GRAY,
+ EL_EMC_GATE_8_GRAY,
EL_SWITCHGATE_OPEN,
EL_TIMEGATE_OPEN,
EL_SP_GRAVITY_OFF_PORT_RIGHT,
EL_SP_GRAVITY_OFF_PORT_UP,
EL_SP_GRAVITY_OFF_PORT_DOWN,
+ EL_EMC_GRASS,
-1
};
EL_BALLOON_SWITCH_ANY,
EL_LAMP,
EL_TIME_ORB_FULL,
+ EL_EMC_MAGIC_BALL_SWITCH,
-1
};
EL_EM_GATE_2_GRAY,
EL_EM_GATE_3_GRAY,
EL_EM_GATE_4_GRAY,
+ EL_EMC_GATE_5,
+ EL_EMC_GATE_6,
+ EL_EMC_GATE_7,
+ EL_EMC_GATE_8,
+ EL_EMC_GATE_5_GRAY,
+ EL_EMC_GATE_6_GRAY,
+ EL_EMC_GATE_7_GRAY,
+ EL_EMC_GATE_8_GRAY,
-1
};
EL_EM_KEY_2,
EL_EM_KEY_3,
EL_EM_KEY_4,
+ EL_EMC_KEY_5,
+ EL_EMC_KEY_6,
+ EL_EMC_KEY_7,
+ EL_EMC_KEY_8,
EL_GATE_1,
EL_GATE_2,
EL_GATE_3,
EL_EM_GATE_2_GRAY,
EL_EM_GATE_3_GRAY,
EL_EM_GATE_4_GRAY,
+ EL_EMC_GATE_5,
+ EL_EMC_GATE_6,
+ EL_EMC_GATE_7,
+ EL_EMC_GATE_8,
+ EL_EMC_GATE_5_GRAY,
+ EL_EMC_GATE_6_GRAY,
+ EL_EMC_GATE_7_GRAY,
+ EL_EMC_GATE_8_GRAY,
EL_DYNAMITE,
EL_INVISIBLE_STEELWALL,
EL_INVISIBLE_WALL,
EL_EMC_STEELWALL_2,
EL_EMC_STEELWALL_3,
EL_EMC_STEELWALL_4,
+ EL_EMC_WALL_SLIPPERY_1,
+ EL_EMC_WALL_SLIPPERY_2,
+ EL_EMC_WALL_SLIPPERY_3,
+ EL_EMC_WALL_SLIPPERY_4,
EL_EMC_WALL_1,
EL_EMC_WALL_2,
EL_EMC_WALL_3,
EL_EMC_WALL_6,
EL_EMC_WALL_7,
EL_EMC_WALL_8,
+ EL_EMC_WALL_9,
+ EL_EMC_WALL_10,
+ EL_EMC_WALL_11,
+ EL_EMC_WALL_12,
+ EL_EMC_WALL_13,
+ EL_EMC_WALL_14,
+ EL_EMC_WALL_15,
+ EL_EMC_WALL_16,
-1
};
{ NULL, -1 }
};
- static int copy_properties[][5] =
- {
- {
- EL_BUG,
- EL_BUG_LEFT, EL_BUG_RIGHT,
- EL_BUG_UP, EL_BUG_DOWN
- },
- {
- EL_SPACESHIP,
- EL_SPACESHIP_LEFT, EL_SPACESHIP_RIGHT,
- EL_SPACESHIP_UP, EL_SPACESHIP_DOWN
- },
- {
- EL_BD_BUTTERFLY,
- EL_BD_BUTTERFLY_LEFT, EL_BD_BUTTERFLY_RIGHT,
- EL_BD_BUTTERFLY_UP, EL_BD_BUTTERFLY_DOWN
- },
- {
- EL_BD_FIREFLY,
- EL_BD_FIREFLY_LEFT, EL_BD_FIREFLY_RIGHT,
- EL_BD_FIREFLY_UP, EL_BD_FIREFLY_DOWN
- },
- {
- EL_PACMAN,
- EL_PACMAN_LEFT, EL_PACMAN_RIGHT,
- EL_PACMAN_UP, EL_PACMAN_DOWN
- },
- {
- EL_MOLE,
- EL_MOLE_LEFT, EL_MOLE_RIGHT,
- EL_MOLE_UP, EL_MOLE_DOWN
- },
- {
- -1,
- -1, -1, -1, -1
- }
- };
-
int i, j, k;
/* always start with reliable default values (element has no properties) */
SET_PROPERTY(i, EP_CAN_CHANGE, TRUE);
/* ---------- GFX_CRUMBLED --------------------------------------------- */
+#if 1
+ SET_PROPERTY(i, EP_GFX_CRUMBLED,
+ element_info[i].crumbled[ACTION_DEFAULT] !=
+ element_info[i].graphic[ACTION_DEFAULT]);
+#else
+ /* !!! THIS LOOKS CRAPPY FOR SAND ETC. WITHOUT CRUMBLED GRAPHICS !!! */
SET_PROPERTY(i, EP_GFX_CRUMBLED,
element_info[i].crumbled[ACTION_DEFAULT] != IMG_EMPTY);
+#endif
}
#if 0
static void InitGlobal()
{
+ int i;
+
+ for (i = 0; i < MAX_NUM_ELEMENTS + 1; i++)
+ {
+ /* check if element_name_info entry defined for each element in "main.h" */
+ if (i < MAX_NUM_ELEMENTS && element_name_info[i].token_name == NULL)
+ Error(ERR_EXIT, "undefined 'element_name_info' entry for element %d", i);
+
+ element_info[i].token_name = element_name_info[i].token_name;
+ element_info[i].class_name = element_name_info[i].class_name;
+ element_info[i].editor_description=element_name_info[i].editor_description;
+ }
+
global.autoplay_leveldir = NULL;
global.convert_leveldir = NULL;
{
char *filename = &command[11];
- if (access(filename, F_OK) != 0)
+ if (!fileExists(filename))
Error(ERR_EXIT, "cannot open file '%s'", filename);
LoadLevelFromFilename(&level, filename);
{
char *filename = &command[10];
- if (access(filename, F_OK) != 0)
+ if (!fileExists(filename))
Error(ERR_EXIT, "cannot open file '%s'", filename);
LoadTapeFromFilename(filename);
}
else if (strncmp(command, "autoplay ", 9) == 0)
{
- char *str_copy = getStringCopy(&command[9]);
- char *str_ptr = strchr(str_copy, ' ');
+ char *str_ptr = getStringCopy(&command[9]); /* read command parameters */
+
+ while (*str_ptr != '\0') /* continue parsing string */
+ {
+ /* cut leading whitespace from string, replace it by string terminator */
+ while (*str_ptr == ' ' || *str_ptr == '\t')
+ *str_ptr++ = '\0';
+
+ if (*str_ptr == '\0') /* end of string reached */
+ break;
+
+ if (global.autoplay_leveldir == NULL) /* read level set string */
+ {
+ global.autoplay_leveldir = str_ptr;
+ global.autoplay_all = TRUE; /* default: play all tapes */
+
+ for (i = 0; i < MAX_TAPES_PER_SET; i++)
+ global.autoplay_level[i] = FALSE;
+ }
+ else /* read level number string */
+ {
+ int level_nr = atoi(str_ptr); /* get level_nr value */
- global.autoplay_leveldir = str_copy;
- global.autoplay_level_nr = -1;
+ if (level_nr >= 0 && level_nr < MAX_TAPES_PER_SET)
+ global.autoplay_level[level_nr] = TRUE;
- if (str_ptr != NULL)
+ global.autoplay_all = FALSE;
+ }
+
+ /* advance string pointer to the next whitespace (or end of string) */
+ while (*str_ptr != ' ' && *str_ptr != '\t' && *str_ptr != '\0')
+ str_ptr++;
+ }
+
+#if 0
+ printf("level set == '%s'\n", global.autoplay_leveldir);
+
+ if (global.autoplay_all)
+ printf("play all levels\n");
+ else
{
- *str_ptr++ = '\0'; /* terminate leveldir string */
- global.autoplay_level_nr = atoi(str_ptr); /* get level_nr value */
+ printf("play the following levels:");
+
+ for (i = 0; i < MAX_TAPES_PER_SET; i++)
+ if (global.autoplay_level[i])
+ printf(" %03d", i);
+
+ printf("\n");
}
+#endif
+
}
else if (strncmp(command, "convert ", 8) == 0)
{
global.convert_leveldir = str_copy;
global.convert_level_nr = -1;
- if (str_ptr != NULL)
+ if (str_ptr != NULL) /* level number follows */
{
*str_ptr++ = '\0'; /* terminate leveldir string */
global.convert_level_nr = atoi(str_ptr); /* get level_nr value */
artwork_current_identifier) != 0)
artwork_new_identifier = artwork_current_identifier;
+#if 1
+ *(ARTWORK_CURRENT_IDENTIFIER_PTR(artwork, type))= artwork_current_identifier;
+#else
+ /* newer versions of gcc do not like this anymore :-/ */
*(&(ARTWORK_CURRENT_IDENTIFIER(artwork, type))) = artwork_current_identifier;
+#endif
#if 0
if (type == ARTWORK_TYPE_GRAPHICS)
void OpenAll()
{
- InitGlobal(); /* initialize some global variables */
+ InitGlobal(); /* initialize some global variables */
if (options.execute_command)
Execute_Command(options.execute_command);
#else
Error(ERR_WARN, "networking only supported in Unix version");
#endif
- exit(0); /* never reached */
+
+ exit(0); /* never reached, server loops forever */
}
InitSetup();
game_status = GAME_MODE_MAIN;
+#if 1
+ em_open_all();
+#endif
+
DrawMainMenu();
InitNetworkServer();
FreeAllMusic();
CloseAudio(); /* called after freeing sounds (needed for SDL) */
+#if 1
+ em_close_all();
+#endif
+
FreeAllImages();
FreeTileClipmasks();
#include "main.h"
#if 1
-#define setMoveIntoAcidProperty(l, e, v) \
+#define setMoveIntoAcidProperty(l, e, v) \
(setBitfieldProperty(&(l)->can_move_into_acid_bits, \
EP_CAN_MOVE_INTO_ACID, e, v))
-#define getMoveIntoAcidProperty(l, e) \
+#define getMoveIntoAcidProperty(l, e) \
(getBitfieldProperty(&(l)->can_move_into_acid_bits, \
EP_CAN_MOVE_INTO_ACID, e))
-#define setDontCollideWithProperty(l, e, v) \
- (setBitfieldProperty(&(l)->can_move_into_acid_bits, \
+#define setDontCollideWithProperty(l, e, v) \
+ (setBitfieldProperty(&(l)->dont_collide_with_bits, \
EP_DONT_COLLIDE_WITH, e, v))
-#define getDontCollideWithProperty(l, e) \
- (getBitfieldProperty(&(l)->can_move_into_acid_bits, \
+#define getDontCollideWithProperty(l, e) \
+ (getBitfieldProperty(&(l)->dont_collide_with_bits, \
EP_DONT_COLLIDE_WITH, e))
void setBitfieldProperty(int *, int, int, boolean);
# =============================================================================
# Rocks'n'Diamonds Makefile (libgame)
# -----------------------------------------------------------------------------
-# (c) 1995-2003 Holger Schemel <info@artsoft.org>
+# (c) 1995-2005 Holger Schemel <info@artsoft.org>
# =============================================================================
# -----------------------------------------------------------------------------
break;
case GDI_TYPE:
- gi->type = va_arg(ap, unsigned long);
+ gi->type = va_arg(ap, unsigned int);
break;
case GDI_STATE:
- gi->state = va_arg(ap, unsigned long);
+ gi->state = va_arg(ap, unsigned int);
break;
case GDI_ACTIVE:
break;
case GDI_RADIO_NR:
- gi->radio_nr = va_arg(ap, unsigned long);
+ gi->radio_nr = va_arg(ap, unsigned int);
break;
case GDI_NUMBER_VALUE:
- gi->textinput.number_value = va_arg(ap, long);
+ gi->textinput.number_value = va_arg(ap, int);
sprintf(gi->textinput.value, "%d", gi->textinput.number_value);
+ strcpy(gi->textinput.last_value, gi->textinput.value);
gi->textinput.cursor_position = strlen(gi->textinput.value);
break;
case GDI_NUMBER_MIN:
- gi->textinput.number_min = va_arg(ap, long);
+ gi->textinput.number_min = va_arg(ap, int);
if (gi->textinput.number_value < gi->textinput.number_min)
{
gi->textinput.number_value = gi->textinput.number_min;
sprintf(gi->textinput.value, "%d", gi->textinput.number_value);
+ strcpy(gi->textinput.last_value, gi->textinput.value);
}
break;
case GDI_NUMBER_MAX:
- gi->textinput.number_max = va_arg(ap, long);
+ gi->textinput.number_max = va_arg(ap, int);
if (gi->textinput.number_value > gi->textinput.number_max)
{
gi->textinput.number_value = gi->textinput.number_max;
sprintf(gi->textinput.value, "%d", gi->textinput.number_value);
+ strcpy(gi->textinput.last_value, gi->textinput.value);
}
break;
max_textsize = MIN(gi->textinput.size, MAX_GADGET_TEXTSIZE - 1);
strncpy(gi->textinput.value, va_arg(ap, char *), max_textsize);
+ strcpy(gi->textinput.last_value, gi->textinput.value);
+
gi->textinput.value[max_textsize] = '\0';
gi->textinput.cursor_position = strlen(gi->textinput.value);
/* same tag also used for other gadget definitions */
strcpy(gi->textbutton.value, gi->textinput.value);
strcpy(gi->textarea.value, gi->textinput.value);
+ strcpy(gi->textarea.last_value, gi->textinput.value);
}
break;
gi->textinput.size = max_textsize;
gi->textinput.value[max_textsize] = '\0';
+ strcpy(gi->textinput.last_value, gi->textinput.value);
/* same tag also used for other gadget definitions */
- strcpy(gi->textbutton.value, gi->textinput.value);
- gi->textbutton.size = gi->textinput.size;
+
+ gi->textarea.size = max_textsize;
+ gi->textarea.value[max_textsize] = '\0';
+ strcpy(gi->textarea.last_value, gi->textinput.value);
+
+ gi->textbutton.size = max_textsize;
+ gi->textbutton.value[max_textsize] = '\0';
+
gi->selectbox.size = gi->textinput.size;
}
break;
break;
case GDI_EVENT_MASK:
- gi->event_mask = va_arg(ap, unsigned long);
+ gi->event_mask = va_arg(ap, unsigned int);
break;
case GDI_AREA_SIZE:
getFontCharSource(font_nr, FONT_ASCII_CURSOR, &src_bitmap, &src_x, &src_y);
src_x += font_width / 2;
src_y += font_height / 2;
- gi->selectbox.inverse_color = GetPixel(src_bitmap, src_x, src_y);
+
+ /* there may be esoteric cases with missing or too small font bitmap */
+ if (src_bitmap != NULL &&
+ src_x < src_bitmap->width && src_y < src_bitmap->height)
+ gi->selectbox.inverse_color = GetPixel(src_bitmap, src_x, src_y);
/* always start with closed selectbox */
gi->selectbox.open = FALSE;
if (gi->type & GD_TYPE_SCROLLBAR)
{
struct GadgetScrollbar *gs = &gi->scrollbar;
+ int scrollbar_size_cmp;
if (gi->width == 0 || gi->height == 0 ||
gs->items_max == 0 || gs->items_visible == 0)
Error(ERR_EXIT, "scrollbar gadget incomplete (missing tags)");
/* calculate internal scrollbar values */
+ gs->size_min = (gi->type == GD_TYPE_SCROLLBAR_VERTICAL ?
+ gi->width : gi->height);
gs->size_max = (gi->type == GD_TYPE_SCROLLBAR_VERTICAL ?
gi->height : gi->width);
- gs->size = gs->size_max * gs->items_visible / gs->items_max;
- gs->position = gs->size_max * gs->item_position / gs->items_max;
+
+ scrollbar_size_cmp = gs->size_max * gs->items_visible / gs->items_max;
+ gs->size = MAX(scrollbar_size_cmp, gs->size_min);
+ gs->size_max_cmp = (gs->size_max - (gs->size - scrollbar_size_cmp));
+
+ gs->position = gs->size_max_cmp * gs->item_position / gs->items_max;
gs->position_max = gs->size_max - gs->size;
gs->correction = gs->size_max / gs->items_max / 2;
MultiMapGadgets(MULTIMAP_ALL | MULTIMAP_REMAP);
}
-static boolean anyTextInputGadgetActive()
+boolean anyTextInputGadgetActive()
{
return (last_gi && (last_gi->type & GD_TYPE_TEXT_INPUT) && last_gi->mapped);
}
-static boolean anyTextAreaGadgetActive()
+boolean anyTextAreaGadgetActive()
{
return (last_gi && (last_gi->type & GD_TYPE_TEXT_AREA) && last_gi->mapped);
}
-static boolean anySelectboxGadgetActive()
+boolean anySelectboxGadgetActive()
{
return (last_gi && (last_gi->type & GD_TYPE_SELECTBOX) && last_gi->mapped);
}
+boolean anyScrollbarGadgetActive()
+{
+ return (last_gi && (last_gi->type & GD_TYPE_SCROLLBAR) && last_gi->mapped);
+}
+
+boolean anyTextGadgetActive()
+{
+ return (anyTextInputGadgetActive() ||
+ anyTextAreaGadgetActive() ||
+ anySelectboxGadgetActive());
+}
+
static boolean insideSelectboxLine(struct GadgetInfo *gi, int mx, int my)
{
return(gi != NULL &&
my >= gi->selectbox.y && my < gi->selectbox.y + gi->selectbox.height);
}
-boolean anyTextGadgetActive()
-{
- return (anyTextInputGadgetActive() ||
- anyTextAreaGadgetActive() ||
- anySelectboxGadgetActive());
-}
-
void ClickOnGadget(struct GadgetInfo *gi, int button)
{
+ if (!gi->mapped)
+ return;
+
/* simulate releasing mouse button over last gadget, if still pressed */
if (button_status)
HandleGadgets(-1, -1, 0);
button != 0 && !motion_status && new_gi != last_gi)
#endif
{
- CheckRangeOfNumericInputGadget(last_gi); /* in case of numeric gadget */
+ struct GadgetInfo *gi = last_gi;
+ boolean gadget_changed = (gi->event_mask & GD_EVENT_TEXT_LEAVING);
- DrawGadget(last_gi, DG_UNPRESSED, last_gi->direct_draw);
+ /* check if text gadget has changed its value */
+ if (gi->type & GD_TYPE_TEXT_INPUT)
+ {
+ CheckRangeOfNumericInputGadget(gi);
- last_gi->event.type = GD_EVENT_TEXT_LEAVING;
+ if (strcmp(gi->textinput.value, gi->textinput.last_value) != 0)
+ strcpy(gi->textinput.last_value, gi->textinput.value);
+ else
+ gadget_changed = FALSE;
+ }
- if (last_gi->event_mask & GD_EVENT_TEXT_LEAVING)
- last_gi->callback_action(last_gi);
+ /* selectbox does not change its value when closed by clicking outside */
+ if (gi->type & GD_TYPE_SELECTBOX)
+ gadget_changed = FALSE;
+
+ DrawGadget(gi, DG_UNPRESSED, gi->direct_draw);
+
+ gi->event.type = GD_EVENT_TEXT_LEAVING;
+
+#if 1
+ if (gadget_changed && !(gi->type & GD_TYPE_SELECTBOX))
+ gi->callback_action(gi);
+#else
+ if (gi->event_mask & GD_EVENT_TEXT_LEAVING)
+ gi->callback_action(gi);
+#endif
last_gi = NULL;
if (gs->item_position < 0)
gs->item_position = 0;
- if (gs->item_position > gs->items_max - gs->items_visible)
+ else if (gs->item_position > gs->items_max - gs->items_visible)
gs->item_position = gs->items_max - gs->items_visible;
if (old_item_position != gs->item_position)
gs->position = scrollbar_mouse_pos - gs->drag_position;
- if (gs->position < 0)
+ /* make sure to always precisely reach end positions when dragging */
+ if (gs->position <= 0)
+ {
gs->position = 0;
- if (gs->position > gs->position_max)
+ gs->item_position = 0;
+ }
+ else if (gs->position >= gs->position_max)
+ {
gs->position = gs->position_max;
-
- gs->item_position =
- gs->items_max * (gs->position + gs->correction) / gs->size_max;
+ gs->item_position = gs->items_max - gs->items_visible;
+ }
+ else
+ {
+ gs->item_position =
+ gs->items_max * (gs->position + gs->correction) / gs->size_max_cmp;
+ }
if (gs->item_position < 0)
gs->item_position = 0;
if (gadget_released_inside)
{
boolean deactivate_gadget = TRUE;
+ boolean gadget_changed = TRUE;
if (gi->type & GD_TYPE_SELECTBOX)
{
#if 1
if (mouse_released_where_pressed ||
!gadget_released_inside_select_area) /* selectbox stays open */
+ {
deactivate_gadget = FALSE;
+ gadget_changed = FALSE;
+ }
#else
if (gadget_released_inside_select_line ||
gadget_released_off_borders) /* selectbox stays open */
+ {
deactivate_gadget = FALSE;
+ gadget_changed = FALSE;
+ }
#endif
- else
+ else if (gi->selectbox.index != gi->selectbox.current_index)
gi->selectbox.index = gi->selectbox.current_index;
+ else
+ gadget_changed = FALSE;
}
if (deactivate_gadget &&
gi->state = GD_BUTTON_UNPRESSED;
gi->event.type = GD_EVENT_RELEASED;
+#if 1
+ if ((gi->event_mask & GD_EVENT_RELEASED) && gadget_changed)
+ {
+ gi->callback_action(gi);
+ }
+#else
if ((gi->event_mask & GD_EVENT_RELEASED) && deactivate_gadget)
gi->callback_action(gi);
+#endif
}
if (gadget_released_off_borders)
if (key == KSYM_Return) /* valid for both text input and selectbox */
{
+ boolean gadget_changed = (gi->event_mask & GD_EVENT_TEXT_RETURN);
+
if (gi->type & GD_TYPE_TEXT_INPUT)
+ {
CheckRangeOfNumericInputGadget(gi);
+
+ if (strcmp(gi->textinput.value, gi->textinput.last_value) != 0)
+ strcpy(gi->textinput.last_value, gi->textinput.value);
+ else
+ gadget_changed = FALSE;
+ }
else if (gi->type & GD_TYPE_SELECTBOX)
- gi->selectbox.index = gi->selectbox.current_index;
+ {
+ if (gi->selectbox.index != gi->selectbox.current_index)
+ gi->selectbox.index = gi->selectbox.current_index;
+ else
+ gadget_changed = FALSE;
+ }
if (gi->type & GD_TYPE_TEXT_AREA)
{
last_gi = NULL;
}
+#if 1
+ if (gadget_changed)
+ gi->callback_action(gi);
+#else
if (gi->event_mask & GD_EVENT_TEXT_RETURN)
gi->callback_action(gi);
+#endif
}
else if (gi->type & GD_TYPE_TEXT_INPUT) /* only valid for text input */
{
struct GadgetTextInput
{
char value[MAX_GADGET_TEXTSIZE]; /* text string in input field */
+ char last_value[MAX_GADGET_TEXTSIZE]; /* last text string in input field */
int cursor_position; /* actual text cursor position */
int number_value; /* integer value, if numeric */
int number_min; /* minimal allowed numeric value */
struct GadgetTextArea
{
char value[MAX_GADGET_TEXTSIZE]; /* text string in input field */
+ char last_value[MAX_GADGET_TEXTSIZE]; /* last text string in input field */
int cursor_position; /* actual text cursor position */
int cursor_x; /* actual x cursor position */
int cursor_y; /* actual y cursor position */
int items_max; /* number of items to access */
int items_visible; /* number of visible items */
int item_position; /* actual item position */
+ int size_min; /* minimal scrollbar size */
int size_max; /* this is either width or height */
+ int size_max_cmp; /* needed for minimal scrollbar size */
int size; /* scrollbar size on screen */
int position; /* scrollbar position on screen */
int position_max; /* bottom/right scrollbar position */
char info_text[MAX_INFO_TEXTSIZE]; /* short popup info text */
int x, y; /* gadget position */
int width, height; /* gadget size */
- unsigned long type; /* type (button, text input, ...) */
- unsigned long state; /* state (pressed, released, ...) */
+ unsigned int type; /* type (button, text input, ...) */
+ unsigned int state; /* state (pressed, released, ...) */
boolean checked; /* check/radio button state */
int radio_nr; /* number of radio button series */
boolean mapped; /* gadget is mapped on the screen */
struct GadgetDesign design[2]; /* 0: normal; 1: pressed */
struct GadgetDesign alt_design[2]; /* alternative design */
struct GadgetDecoration deco; /* decoration on top of gadget */
- unsigned long event_mask; /* possible events for this gadget */
+ unsigned int event_mask; /* possible events for this gadget */
struct GadgetEvent event; /* actual gadget event */
gadget_function callback_info; /* function for pop-up info text */
gadget_function callback_action; /* function for gadget action */
void UnmapAllGadgets();
void RemapAllGadgets();
+boolean anyTextInputGadgetActive();
+boolean anyTextAreaGadgetActive();
+boolean anySelectboxGadgetActive();
+boolean anyScrollbarGadgetActive();
boolean anyTextGadgetActive();
+
void ClickOnGadget(struct GadgetInfo *, int);
boolean HandleGadgets(int, int, int);
dst_ptr += bytes_per_row; /* continue with leftmost byte of next row */
}
- mask_pixmap = XCreateBitmapFromData(display, window, (char *)mask_data,
- image->width, image->height);
+ if ((mask_pixmap = XCreateBitmapFromData(display, window, (char *)mask_data,
+ image->width, image->height))
+ == None)
+ Error(ERR_EXIT, "Image_to_Mask(): XCreateBitmapFromData() failed");
+
+ free(mask_data);
+
+ return mask_pixmap;
+}
+
+Pixmap Pixmap_to_Mask(Pixmap src_pixmap, int src_width, int src_height)
+{
+ XImage *src_ximage;
+ byte *src_ptr, *dst_ptr, *dst_ptr2;
+ int bits_per_pixel;
+ int bytes_per_pixel;
+ unsigned int bytes_per_row;
+ unsigned int x, y, i;
+ byte bitmask;
+ byte *mask_data;
+ Pixmap mask_pixmap;
+
+ /* copy source pixmap to temporary image */
+ if ((src_ximage = XGetImage(display, src_pixmap, 0, 0, src_width, src_height,
+ AllPlanes, ZPixmap)) == NULL)
+ Error(ERR_EXIT, "Pixmap_to_Mask(): XGetImage() failed");
+
+ bits_per_pixel = src_ximage->bits_per_pixel;
+ bytes_per_pixel = (bits_per_pixel + 7) / 8;
+
+ bytes_per_row = (src_width + 7) / 8;
+ mask_data = checked_calloc(bytes_per_row * src_height);
+
+ src_ptr = (byte *)src_ximage->data;
+ dst_ptr = mask_data;
+
+ /* create bitmap data which can be used by 'XCreateBitmapFromData()'
+ * directly to create a pixmap of depth 1 for use as a clip mask for
+ * the corresponding image pixmap
+ */
+
+ for (y = 0; y < src_height; y++)
+ {
+ bitmask = 0x01; /* start with leftmost bit in the byte */
+ dst_ptr2 = dst_ptr; /* start with leftmost byte in the row */
+
+ for (x = 0; x < src_width; x++)
+ {
+ for (i = 0; i < bytes_per_pixel; i++)
+ if (*src_ptr++) /* source pixel solid? (pixel index != 0) */
+ *dst_ptr2 |= bitmask; /* then write a bit into the image mask */
+
+ if ((bitmask <<= 1) == 0) /* bit at rightmost byte position reached? */
+ {
+ bitmask = 0x01; /* start again with leftmost bit position */
+ dst_ptr2++; /* continue with next byte in image mask */
+ }
+ }
+
+ dst_ptr += bytes_per_row; /* continue with leftmost byte of next row */
+ }
+
+ if ((mask_pixmap = XCreateBitmapFromData(display, window->drawable,
+ (char *)mask_data,
+ src_width, src_height)) == None)
+ Error(ERR_EXIT, "Pixmap_to_Mask(): XCreateBitmapFromData() failed");
+
free(mask_data);
return mask_pixmap;
-----------------------------------------------------------------------------
ZoomPixmap
- Important note: The scaling code currently only supports scaling down the
- image by a power of 2 -- scaling up is currently not supported at all!
+ Important note: The scaling code currently only supports scaling of the image
+ up or down by a power of 2 -- other scaling factors currently not supported!
+ Also not supported is scaling of pixmap masks (with depth 1); to scale them,
+ better use Pixmap_to_Mask() for now.
-----------------------------------------------------------------------------
*/
byte *src_ptr, *dst_ptr;
int bits_per_pixel;
int bytes_per_pixel;
- int x, y, i;
- int zoom_factor = src_width / dst_width; /* currently very limited! */
+ int x, y, xx, yy, i;
int row_skip, col_skip;
+ int zoom_factor;
+ boolean scale_down = (src_width > dst_width);
+
+ if (scale_down)
+ {
+ zoom_factor = src_width / dst_width;
+
+ /* adjust source image size to integer multiple of destination size */
+ src_width = dst_width * zoom_factor;
+ src_height = dst_height * zoom_factor;
+ }
+ else
+ {
+ zoom_factor = dst_width / src_width;
- /* adjust source image size to integer multiple of destination image size */
- src_width = dst_width * zoom_factor;
- src_height = dst_height * zoom_factor;
+ /* no adjustment needed when scaling up (some pixels may be left blank) */
+ }
/* copy source pixmap to temporary image */
- src_ximage = XGetImage(display, src_pixmap, 0, 0, src_width, src_height,
- AllPlanes, ZPixmap);
+ if ((src_ximage = XGetImage(display, src_pixmap, 0, 0, src_width, src_height,
+ AllPlanes, ZPixmap)) == NULL)
+ Error(ERR_EXIT, "ZoomPixmap(): XGetImage() failed");
bits_per_pixel = src_ximage->bits_per_pixel;
bytes_per_pixel = (bits_per_pixel + 7) / 8;
- dst_ximage = XCreateImage(display, visual, src_ximage->depth, ZPixmap,
- 0, NULL, dst_width, dst_height,
- 8, dst_width * bytes_per_pixel);
+ if ((dst_ximage = XCreateImage(display, visual, src_ximage->depth, ZPixmap,
+ 0, NULL, dst_width, dst_height,
+ 8, dst_width * bytes_per_pixel)) == NULL)
+ Error(ERR_EXIT, "ZoomPixmap(): XCreateImage() failed");
+
dst_ximage->data =
checked_malloc(dst_width * dst_height * bytes_per_pixel);
dst_ximage->byte_order = src_ximage->byte_order;
src_ptr = (byte *)src_ximage->data;
dst_ptr = (byte *)dst_ximage->data;
- col_skip = (zoom_factor - 1) * bytes_per_pixel;
- row_skip = col_skip * src_width;
+ if (scale_down)
+ {
+ col_skip = (zoom_factor - 1) * bytes_per_pixel;
+ row_skip = col_skip * src_width;
+
+ /* scale image down by scaling factor 'zoom_factor' */
+ for (y = 0; y < src_height; y += zoom_factor, src_ptr += row_skip)
+ for (x = 0; x < src_width; x += zoom_factor, src_ptr += col_skip)
+ for (i = 0; i < bytes_per_pixel; i++)
+ *dst_ptr++ = *src_ptr++;
+ }
+ else
+ {
+ row_skip = src_width * bytes_per_pixel;
- /* scale image down by scaling factor 'zoom_factor' */
- for (y = 0; y < src_height; y += zoom_factor, src_ptr += row_skip)
- for (x = 0; x < src_width; x += zoom_factor, src_ptr += col_skip)
- for (i = 0; i < bytes_per_pixel; i++)
- *dst_ptr++ = *src_ptr++;
+ /* scale image up by scaling factor 'zoom_factor' */
+ for (y = 0; y < src_height; y++)
+ {
+ for (yy = 0; yy < zoom_factor; yy++)
+ {
+ if (yy > 0)
+ src_ptr -= row_skip;
+
+ for (x = 0; x < src_width; x++)
+ {
+ for (xx = 0; xx < zoom_factor; xx++)
+ for (i = 0; i < bytes_per_pixel; i++)
+ *dst_ptr++ = *(src_ptr + i);
+
+ src_ptr += bytes_per_pixel;
+ }
+ }
+ }
+ }
/* copy scaled image to destination pixmap */
XPutImage(display, dst_pixmap, gc, dst_ximage, 0, 0, 0, 0,
int num_references;
Bitmap *bitmap;
- boolean contains_small_images;
+
+ int original_width; /* original image file width */
+ int original_height; /* original image file height */
+
+ boolean contains_small_images; /* set after adding small images */
+ boolean scaled_up; /* set after scaling up */
};
typedef struct ImageInfo ImageInfo;
img_info->source_filename = getStringCopy(filename);
+ img_info->original_width = img_info->bitmap->width;
+ img_info->original_height = img_info->bitmap->height;
+
img_info->contains_small_images = FALSE;
+ img_info->scaled_up = FALSE;
return img_info;
}
image_info->num_dynamic_file_list_entries);
}
-struct FileInfo *getImageListEntry(int pos)
+struct FileInfo *getImageListEntryFromImageID(int pos)
{
int num_list_entries = image_info->num_file_list_entries;
int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
Bitmap *getBitmapFromImageID(int pos)
{
-#if 0
- int num_list_entries = image_info->num_file_list_entries;
- int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
- ImageInfo **img_info =
- (ImageInfo **)(pos < num_list_entries ? image_info->artwork_list :
- image_info->dynamic_artwork_list);
-
- return (img_info[list_pos] != NULL ? img_info[list_pos]->bitmap : NULL);
-#else
ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
return (img_info != NULL ? img_info->bitmap : NULL);
-#endif
}
-char *getTokenFromImageID(int graphic)
+int getOriginalImageWidthFromImageID(int pos)
{
-#if 0
- /* !!! this does not work for dynamic artwork (crash!) !!! */
- struct FileInfo *file_list = (struct FileInfo *)image_info->file_list;
+ ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
+
+ return (img_info != NULL ? img_info->original_width : 0);
+}
+
+int getOriginalImageHeightFromImageID(int pos)
+{
+ ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
+
+ return (img_info != NULL ? img_info->original_height : 0);
+}
- return file_list[graphic].token;
-#else
- struct FileInfo *file_list = getImageListEntry(graphic);
+char *getTokenFromImageID(int graphic)
+{
+ struct FileInfo *file_list = getImageListEntryFromImageID(graphic);
return (file_list != NULL ? file_list->token : NULL);
-#endif
}
int getImageIDFromToken(char *token)
}
void InitImageList(struct ConfigInfo *config_list, int num_file_list_entries,
- struct ConfigInfo *config_suffix_list,
+ struct ConfigTypeInfo *config_suffix_list,
char **base_prefixes, char **ext1_suffixes,
char **ext2_suffixes, char **ext3_suffixes,
char **ignore_tokens)
ReloadCustomArtworkList(image_info);
}
-void CreateImageWithSmallImages(int pos)
+void CreateImageWithSmallImages(int pos, int zoom_factor)
{
ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
if (img_info == NULL || img_info->contains_small_images)
return;
- CreateBitmapWithSmallBitmaps(img_info->bitmap);
+ CreateBitmapWithSmallBitmaps(img_info->bitmap, zoom_factor);
img_info->contains_small_images = TRUE;
+ img_info->scaled_up = TRUE;
+
+#if 0
+ if (zoom_factor)
+ printf("CreateImageWithSmallImages: '%s' zoomed by factor %d\n",
+ img_info->source_filename, zoom_factor);
+#endif
#if 0
printf("CreateImageWithSmallImages: '%s' done\n", img_info->source_filename);
void freeImage(Image *);
void freeXImage(Image *, XImageInfo *);
+Pixmap Pixmap_to_Mask(Pixmap, int, int);
+
void ZoomPixmap(Display *, GC, Pixmap, Pixmap, int, int, int, int);
int Read_PCX_to_Pixmap(Display *, Window, GC, char *, Pixmap *, Pixmap *);
#endif /* TARGET_X11 */
int getImageListSize();
-struct FileInfo *getImageListEntry(int);
+struct FileInfo *getImageListEntryFromImageID(int);
Bitmap *getBitmapFromImageID(int);
+int getOriginalImageWidthFromImageID(int);
+int getOriginalImageHeightFromImageID(int);
char *getTokenFromImageID(int);
int getImageIDFromToken(char *);
char *getImageConfigFilename();
int getImageListPropertyMappingSize();
struct PropertyMapping *getImageListPropertyMapping();
-void InitImageList(struct ConfigInfo *, int, struct ConfigInfo *,
+void InitImageList(struct ConfigInfo *, int, struct ConfigTypeInfo *,
char **, char **, char **, char **, char **);
void ReloadCustomImages();
-void CreateImageWithSmallImages(int);
+void CreateImageWithSmallImages(int, int);
void FreeAllImages();
#if defined(PLATFORM_UNIX) && !defined(TARGET_SDL)
void UnixInitJoysticks()
{
+ static boolean unix_joystick_subsystem_initialized = FALSE;
+ boolean print_warning = !unix_joystick_subsystem_initialized;
int i;
for (i = 0; i < MAX_PLAYERS; i++)
if (access(device_name, R_OK) != 0)
{
- Error(ERR_WARN, "cannot access joystick device '%s'", device_name);
+ if (print_warning)
+ Error(ERR_WARN, "cannot access joystick device '%s'", device_name);
+
continue;
}
if ((joystick.fd[i] = open(device_name, O_RDONLY)) < 0)
{
- Error(ERR_WARN, "cannot open joystick device '%s'", device_name);
+ if (print_warning)
+ Error(ERR_WARN, "cannot open joystick device '%s'", device_name);
+
continue;
}
joystick.status = JOYSTICK_ACTIVATED;
}
+
+ unix_joystick_subsystem_initialized = TRUE;
}
boolean UnixReadJoystick(int fd, int *x, int *y, boolean *b1, boolean *b2)
char *from_ptr = real_name;
char *to_ptr = real_name_new;
- if (strchr(real_name, 'ß') == NULL) /* name does not contain 'ß' */
- {
- strncpy(real_name_new, real_name, MAX_USERNAME_LEN);
- real_name_new[MAX_USERNAME_LEN] = '\0';
-
- return real_name_new;
- }
-
- /* the user's real name may contain a 'ß' character (german sharp s),
- which has no equivalent in upper case letters (which our fonts use) */
+ /* copy the name string, but not more than MAX_USERNAME_LEN characters */
while (*from_ptr && (long)(to_ptr - real_name_new) < MAX_USERNAME_LEN - 1)
{
- if (*from_ptr != 'ß')
- *to_ptr++ = *from_ptr++;
- else
+ /* the name field read from "passwd" file may also contain additional
+ user information, separated by commas, which will be removed here */
+ if (*from_ptr == ',')
+ break;
+
+ /* the user's real name may contain 'ß' characters (german sharp s),
+ which have no equivalent in upper case letters (used by our fonts) */
+ if (*from_ptr == 'ß')
{
from_ptr++;
*to_ptr++ = 's';
*to_ptr++ = 's';
}
+ else
+ *to_ptr++ = *from_ptr++;
}
*to_ptr = '\0';
}
+/* ------------------------------------------------------------------------- */
+/* path manipulation functions */
+/* ------------------------------------------------------------------------- */
+
+static char *getLastPathSeparatorPtr(char *filename)
+{
+ char *last_separator = strrchr(filename, '/');
+
+#if !defined(PLATFORM_UNIX)
+ if (last_separator == NULL) /* also try DOS/Windows variant */
+ last_separator = strrchr(filename, '\\');
+#endif
+
+ return last_separator;
+}
+
+static char *getBaseNamePtr(char *filename)
+{
+ char *last_separator = getLastPathSeparatorPtr(filename);
+
+ if (last_separator != NULL)
+ return last_separator + 1; /* separator found: strip base path */
+ else
+ return filename; /* no separator found: filename has no path */
+}
+
+char *getBaseName(char *filename)
+{
+ return getStringCopy(getBaseNamePtr(filename));
+}
+
+char *getBasePath(char *filename)
+{
+ char *basepath = getStringCopy(filename);
+ char *last_separator = getLastPathSeparatorPtr(basepath);
+
+ if (last_separator != NULL)
+ *last_separator = '\0'; /* separator found: strip basename */
+ else
+ basepath = "."; /* no separator found: use current path */
+
+ return basepath;
+}
+
+
/* ------------------------------------------------------------------------- */
/* various string functions */
/* ------------------------------------------------------------------------- */
void GetOptions(char *argv[], void (*print_usage_function)(void))
{
+ char *ro_base_path = RO_BASE_PATH;
+ char *rw_base_path = RW_BASE_PATH;
char **options_left = &argv[1];
+#if !defined(PLATFORM_MACOSX)
+ /* if the program is configured to start from current directory (default),
+ determine program package directory (KDE/Konqueror does not do this by
+ itself and fails otherwise); on Mac OS X, the program binary is stored
+ in an application package directory -- do not try to use this directory
+ as the program data directory (Mac OS X handles this correctly anyway) */
+
+ if (strcmp(ro_base_path, ".") == 0)
+ ro_base_path = program.command_basepath;
+ if (strcmp(rw_base_path, ".") == 0)
+ rw_base_path = program.command_basepath;
+#endif
+
/* initialize global program options */
options.display_name = NULL;
options.server_host = NULL;
options.server_port = 0;
- options.ro_base_directory = RO_BASE_PATH;
- options.rw_base_directory = RW_BASE_PATH;
- options.level_directory = RO_BASE_PATH "/" LEVELS_DIRECTORY;
- options.graphics_directory = RO_BASE_PATH "/" GRAPHICS_DIRECTORY;
- options.sounds_directory = RO_BASE_PATH "/" SOUNDS_DIRECTORY;
- options.music_directory = RO_BASE_PATH "/" MUSIC_DIRECTORY;
- options.docs_directory = RO_BASE_PATH "/" DOCS_DIRECTORY;
+ options.ro_base_directory = ro_base_path;
+ options.rw_base_directory = rw_base_path;
+ options.level_directory = getPath2(ro_base_path, LEVELS_DIRECTORY);
+ options.graphics_directory = getPath2(ro_base_path, GRAPHICS_DIRECTORY);
+ options.sounds_directory = getPath2(ro_base_path, SOUNDS_DIRECTORY);
+ options.music_directory = getPath2(ro_base_path, MUSIC_DIRECTORY);
+ options.docs_directory = getPath2(ro_base_path, DOCS_DIRECTORY);
options.execute_command = NULL;
options.serveronly = FALSE;
options.network = FALSE;
Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str);
/* this should be extended to separate options for ro and rw data */
- options.ro_base_directory = option_arg;
- options.rw_base_directory = option_arg;
+ options.ro_base_directory = ro_base_path = option_arg;
+ options.rw_base_directory = rw_base_path = option_arg;
if (option_arg == next_option)
options_left++;
/* adjust paths for sub-directories in base directory accordingly */
- options.level_directory =
- getPath2(options.ro_base_directory, LEVELS_DIRECTORY);
- options.graphics_directory =
- getPath2(options.ro_base_directory, GRAPHICS_DIRECTORY);
- options.sounds_directory =
- getPath2(options.ro_base_directory, SOUNDS_DIRECTORY);
- options.music_directory =
- getPath2(options.ro_base_directory, MUSIC_DIRECTORY);
- options.docs_directory =
- getPath2(options.ro_base_directory, DOCS_DIRECTORY);
+ options.level_directory = getPath2(ro_base_path, LEVELS_DIRECTORY);
+ options.graphics_directory = getPath2(ro_base_path, GRAPHICS_DIRECTORY);
+ options.sounds_directory = getPath2(ro_base_path, SOUNDS_DIRECTORY);
+ options.music_directory = getPath2(ro_base_path, MUSIC_DIRECTORY);
+ options.docs_directory = getPath2(ro_base_path, DOCS_DIRECTORY);
}
else if (strncmp(option, "-levels", option_len) == 0)
{
boolean fileExists(char *filename)
{
+ if (filename == NULL)
+ return FALSE;
+
#if 0
printf("checking file '%s'\n", filename);
#endif
boolean FileIsGraphic(char *filename)
{
- char *basename = strrchr(filename, '/');
-
- basename = (basename != NULL ? basename + 1 : filename);
+ char *basename = getBaseNamePtr(filename);
return fileHasSuffix(basename, "pcx");
}
boolean FileIsSound(char *filename)
{
- char *basename = strrchr(filename, '/');
-
- basename = (basename != NULL ? basename + 1 : filename);
+ char *basename = getBaseNamePtr(filename);
return fileHasSuffix(basename, "wav");
}
boolean FileIsMusic(char *filename)
{
- char *basename = strrchr(filename, '/');
-
- basename = (basename != NULL ? basename + 1 : filename);
+ char *basename = getBaseNamePtr(filename);
if (FileIsSound(basename))
return TRUE;
/* functions for loading artwork configuration information */
/* ------------------------------------------------------------------------- */
+char *get_mapped_token(char *token)
+{
+ /* !!! make this dynamically configurable (init.c:InitArtworkConfig) !!! */
+ static char *map_token_prefix[][2] =
+ {
+ { "char_procent", "char_percent" },
+ { NULL, }
+ };
+ int i;
+
+ for (i = 0; map_token_prefix[i][0] != NULL; i++)
+ {
+ int len_token_prefix = strlen(map_token_prefix[i][0]);
+
+ if (strncmp(token, map_token_prefix[i][0], len_token_prefix) == 0)
+ return getStringCat2(map_token_prefix[i][1], &token[len_token_prefix]);
+ }
+
+ return NULL;
+}
+
/* This function checks if a string <s> of the format "string1, string2, ..."
exactly contains a string <s_contained>. */
struct ListNodeInfo ***, int *);
struct FileInfo *getFileListFromConfigList(struct ConfigInfo *config_list,
- struct ConfigInfo *suffix_list,
+ struct ConfigTypeInfo *suffix_list,
char **ignore_tokens,
int num_file_list_entries)
{
setString(&file_list[i].default_parameter[j], suffix_list[j].value);
setString(&file_list[i].parameter[j], suffix_list[j].value);
}
+
+ file_list[i].redefined = FALSE;
+ file_list[i].fallback_to_default = FALSE;
}
}
#define KNOWN_TOKEN_VALUE "[KNOWN_TOKEN_VALUE]"
static void read_token_parameters(SetupFileHash *setup_file_hash,
- struct ConfigInfo *suffix_list,
+ struct ConfigTypeInfo *suffix_list,
struct FileInfo *file_list_entry)
{
/* check for config token that is the base token without any suffixes */
static void add_dynamic_file_list_entry(struct FileInfo **list,
int *num_list_entries,
SetupFileHash *extra_file_hash,
- struct ConfigInfo *suffix_list,
+ struct ConfigTypeInfo *suffix_list,
int num_suffix_list_entries,
char *token)
{
new_list_entry->filename = NULL;
new_list_entry->parameter = checked_calloc(parameter_array_size);
+ new_list_entry->redefined = FALSE;
+ new_list_entry->fallback_to_default = FALSE;
+
read_token_parameters(extra_file_hash, suffix_list, new_list_entry);
}
char *filename)
{
struct FileInfo *file_list = artwork_info->file_list;
- struct ConfigInfo *suffix_list = artwork_info->suffix_list;
+ struct ConfigTypeInfo *suffix_list = artwork_info->suffix_list;
char **base_prefixes = artwork_info->base_prefixes;
char **ext1_suffixes = artwork_info->ext1_suffixes;
char **ext2_suffixes = artwork_info->ext2_suffixes;
/* at this point, we do not need the setup file hash anymore -- free it */
freeSetupFileHash(setup_file_hash);
+#if 1
+ /* map deprecated to current tokens (using prefix match and replace) */
+ BEGIN_HASH_ITERATION(valid_file_hash, itr)
+ {
+ char *token = HASH_ITERATION_TOKEN(itr);
+ char *mapped_token = get_mapped_token(token);
+
+ if (mapped_token != NULL)
+ {
+ char *value = HASH_ITERATION_VALUE(itr);
+
+ /* add mapped token */
+ setHashEntry(valid_file_hash, mapped_token, value);
+
+ /* ignore old token (by setting it to "known" keyword) */
+ setHashEntry(valid_file_hash, token, known_token_value);
+
+ free(mapped_token);
+ }
+ }
+ END_HASH_ITERATION(valid_file_hash, itr)
+#endif
+
/* read parameters for all known config file tokens */
for (i = 0; i < num_file_list_entries; i++)
read_token_parameters(valid_file_hash, suffix_list, &file_list[i]);
boolean base_prefix_found = FALSE;
boolean parameter_suffix_found = FALSE;
+#if 0
+ printf("::: examining '%s' -> '%s'\n", token, HASH_ITERATION_VALUE(itr));
+#endif
+
/* skip all parameter definitions (handled by read_token_parameters()) */
for (i = 0; i < num_suffix_list_entries && !parameter_suffix_found; i++)
{
setString(&file_list[i].parameter[j], file_list[i].default_parameter[j]);
file_list[i].redefined = FALSE;
+ file_list[i].fallback_to_default = FALSE;
}
/* free previous dynamic artwork file array */
}
}
+#if 1
+static void replaceArtworkListEntry(struct ArtworkListInfo *artwork_info,
+ struct ListNodeInfo **listnode,
+ struct FileInfo *file_list_entry)
+{
+ char *init_text[] =
+ {
+ "Loading graphics:",
+ "Loading sounds:",
+ "Loading music:"
+ };
+
+ ListNode *node;
+ char *basename = file_list_entry->filename;
+ char *filename = getCustomArtworkFilename(basename, artwork_info->type);
+
+#if 0
+ if (strcmp(file_list_entry->token, "background.DOOR") == 0)
+ printf("::: replaceArtworkListEntry: '%s' => '%s'\n",
+ basename, filename);
+#endif
+
+ if (filename == NULL)
+ {
+ Error(ERR_WARN, "cannot find artwork file '%s'", basename);
+
+ basename = file_list_entry->default_filename;
+
+ /* dynamic artwork has no default filename / skip empty default artwork */
+ if (basename == NULL || strcmp(basename, UNDEFINED_FILENAME) == 0)
+ return;
+
+ file_list_entry->fallback_to_default = TRUE;
+
+ Error(ERR_WARN, "trying default artwork file '%s'", basename);
+
+ filename = getCustomArtworkFilename(basename, artwork_info->type);
+
+ if (filename == NULL)
+ {
+ int error_mode = ERR_WARN;
+
+ /* we can get away without sounds and music, but not without graphics */
+ if (*listnode == NULL && artwork_info->type == ARTWORK_TYPE_GRAPHICS)
+ error_mode = ERR_EXIT;
+
+ Error(error_mode, "cannot find default artwork file '%s'", basename);
+
+ return;
+ }
+ }
+
+ /* check if the old and the new artwork file are the same */
+ if (*listnode && strcmp((*listnode)->source_filename, filename) == 0)
+ {
+ /* The old and new artwork are the same (have the same filename and path).
+ This usually means that this artwork does not exist in this artwork set
+ and a fallback to the existing artwork is done. */
+
+#if 0
+ printf("[artwork '%s' already exists (same list entry)]\n", filename);
+#endif
+
+ return;
+ }
+
+ /* delete existing artwork file entry */
+ deleteArtworkListEntry(artwork_info, listnode);
+
+ /* check if the new artwork file already exists in the list of artworks */
+ if ((node = getNodeFromKey(artwork_info->content_list, filename)) != NULL)
+ {
+#if 0
+ printf("[artwork '%s' already exists (other list entry)]\n", filename);
+#endif
+
+ *listnode = (struct ListNodeInfo *)node->content;
+ (*listnode)->num_references++;
+
+ return;
+ }
+
+#if 0
+ if (strcmp(file_list_entry->token, "background.DOOR") == 0)
+ printf("::: replaceArtworkListEntry: LOAD IT'\n");
+#endif
+
+#if 0
+ printf("::: %s: '%s'\n", init_text[artwork_info->type], basename);
+#endif
+
+ DrawInitText(init_text[artwork_info->type], 120, FC_GREEN);
+ DrawInitText(basename, 150, FC_YELLOW);
+
+ if ((*listnode = artwork_info->load_artwork(filename)) != NULL)
+ {
+#if 0
+ printf("[adding new artwork '%s']\n", filename);
+#endif
+
+ (*listnode)->num_references = 1;
+ addNodeToList(&artwork_info->content_list, (*listnode)->source_filename,
+ *listnode);
+ }
+ else
+ {
+ int error_mode = ERR_WARN;
+
+#if 1
+ /* we can get away without sounds and music, but not without graphics */
+ if (artwork_info->type == ARTWORK_TYPE_GRAPHICS)
+ error_mode = ERR_EXIT;
+#endif
+
+ Error(error_mode, "cannot load artwork file '%s'", basename);
+ return;
+ }
+}
+
+#else
+
static void replaceArtworkListEntry(struct ArtworkListInfo *artwork_info,
struct ListNodeInfo **listnode,
char *basename)
int error_mode = ERR_WARN;
#if 1
+ /* !!! NEW ARTWORK FALLBACK CODE !!! NEARLY UNTESTED !!! */
+ /* before failing, try fallback to default artwork */
+#else
/* we can get away without sounds and music, but not without graphics */
if (*listnode == NULL && artwork_info->type == ARTWORK_TYPE_GRAPHICS)
error_mode = ERR_EXIT;
return;
}
}
+#endif
+
+#if 1
+static void LoadCustomArtwork(struct ArtworkListInfo *artwork_info,
+ struct ListNodeInfo **listnode,
+ struct FileInfo *file_list_entry)
+{
+#if 0
+ printf("GOT CUSTOM ARTWORK FILE '%s'\n", filename);
+#endif
+
+#if 0
+ if (strcmp(file_list_entry->token, "background.DOOR") == 0)
+ printf("::: -> '%s' -> '%s'\n",
+ file_list_entry->token, file_list_entry->filename);
+#endif
+
+ if (strcmp(file_list_entry->filename, UNDEFINED_FILENAME) == 0)
+ {
+ deleteArtworkListEntry(artwork_info, listnode);
+ return;
+ }
+
+ replaceArtworkListEntry(artwork_info, listnode, file_list_entry);
+}
+
+#else
static void LoadCustomArtwork(struct ArtworkListInfo *artwork_info,
struct ListNodeInfo **listnode,
replaceArtworkListEntry(artwork_info, listnode, basename);
}
+#endif
+
+#if 1
+static void LoadArtworkToList(struct ArtworkListInfo *artwork_info,
+ struct ListNodeInfo **listnode,
+ struct FileInfo *file_list_entry)
+{
+#if 0
+ if (artwork_info->artwork_list == NULL ||
+ list_pos >= artwork_info->num_file_list_entries)
+ return;
+#endif
+
+#if 0
+ printf("loading artwork '%s' ... [%d]\n",
+ file_list_entry->filename, getNumNodes(artwork_info->content_list));
+#endif
+
+#if 1
+ LoadCustomArtwork(artwork_info, listnode, file_list_entry);
+#else
+ LoadCustomArtwork(artwork_info, &artwork_info->artwork_list[list_pos],
+ basename);
+#endif
+
+#if 0
+ printf("loading artwork '%s' done [%d]\n",
+ basename, getNumNodes(artwork_info->content_list));
+#endif
+}
+
+#else
static void LoadArtworkToList(struct ArtworkListInfo *artwork_info,
struct ListNodeInfo **listnode,
basename, getNumNodes(artwork_info->content_list));
#endif
}
+#endif
void ReloadCustomArtworkList(struct ArtworkListInfo *artwork_info)
{
for (i = 0; i < num_file_list_entries; i++)
{
#if 0
- if (strcmp(file_list[i].token, "background") == 0)
+ if (strcmp(file_list[i].token, "background.DOOR") == 0)
printf("::: '%s' -> '%s'\n", file_list[i].token, file_list[i].filename);
#endif
+#if 1
+ LoadArtworkToList(artwork_info, &artwork_info->artwork_list[i],
+ &file_list[i]);
+#else
LoadArtworkToList(artwork_info, &artwork_info->artwork_list[i],
file_list[i].filename, i);
+#endif
+
+#if 0
+ if (strcmp(file_list[i].token, "background.DOOR") == 0)
+ {
+ Bitmap *bitmap = getBitmapFromImageID(i);
+
+ printf("::: BITMAP: %08lx\n", bitmap);
+
+#if 0
+ BlitBitmap(bitmap, window, 0, 0, 100, 280, 0, 0);
+#endif
+ }
+#endif
#if 0
+ /* !!! NEW ARTWORK FALLBACK CODE !!! NEARLY UNTESTED !!! */
if (artwork_info->artwork_list[i] == NULL &&
- strcmp(file_list[i].default_filename, file_list[i].filename) != 0)
+ strcmp(file_list[i].filename, UNDEFINED_FILENAME) != 0 &&
+ strcmp(file_list[i].default_filename, file_list[i].filename) != 0 &&
+ strcmp(file_list[i].default_filename, UNDEFINED_FILENAME) != 0)
{
Error(ERR_WARN, "trying default artwork file '%s'",
file_list[i].default_filename);
LoadArtworkToList(artwork_info, &artwork_info->artwork_list[i],
file_list[i].default_filename, i);
+
+ /* even the fallback to default artwork was not successful -- fail now */
+ if (artwork_info->artwork_list[i] == NULL &&
+ artwork_info->type == ARTWORK_TYPE_GRAPHICS)
+ Error(ERR_EXIT, "cannot find artwork file '%s' or default file '%s'",
+ file_list[i].filename, file_list[i].default_filename);
+
+ file_list[i].fallback_to_default = TRUE;
}
#endif
}
for (i = 0; i < num_dynamic_file_list_entries; i++)
{
+#if 1
+ LoadArtworkToList(artwork_info, &artwork_info->dynamic_artwork_list[i],
+ &dynamic_file_list[i]);
+#else
LoadArtworkToList(artwork_info, &artwork_info->dynamic_artwork_list[i],
dynamic_file_list[i].filename, i);
+#endif
#if 0
printf("::: '%s', '0x%08x'\n",
dynamic_file_list[i].filename,
dynamic_file_list[i].default_filename);
#endif
+
+ /* dynamic artwork does not have default filename! */
}
#if 0
/* values for InitRND() */
#define NEW_RANDOMIZE -1
-#define InitRND(seed) init_random_number(0, seed)
+#define InitEngineRND(seed) init_random_number(0, seed)
#define InitSimpleRND(seed) init_random_number(1, seed)
#define RND(max) get_random_number(0, max)
#define SimpleRND(max) get_random_number(1, max)
char *getRealName(void);
char *getHomeDir(void);
+char *getBasePath(char *);
+char *getBaseName(char *);
+
char *getPath2(char *, char *);
char *getPath3(char *, char *, char*);
char *getStringCat2(char *, char *);
boolean FileIsMusic(char *);
boolean FileIsArtworkType(char *, int);
+char *get_mapped_token(char *);
+
int get_parameter_value(char *, char *, int);
int get_auto_parameter_value(char *, char *);
struct FileInfo *getFileListFromConfigList(struct ConfigInfo *,
- struct ConfigInfo *, char **, int);
+ struct ConfigTypeInfo *,
+ char **, int);
void LoadArtworkConfig(struct ArtworkListInfo *);
void ReloadCustomArtworkList(struct ArtworkListInfo *);
void FreeCustomArtworkLists(struct ArtworkListInfo *);
#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)
-----------------------------------------------------------------------------
zoomSurface()
- Zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface.
+ Zooms a 32bit or 8bit 'src' surface to newly created 'dst' surface.
'zoomx' and 'zoomy' are scaling factors for width and height.
- If 'smooth' is 1 then the destination 32bit surface is anti-aliased.
If the surface is not 8bit or 32bit RGBA/ABGR it will be converted
into a 32bit RGBA format on the fly.
-----------------------------------------------------------------------------
void SDLInitJoysticks()
{
static boolean sdl_joystick_subsystem_initialized = FALSE;
+ boolean print_warning = !sdl_joystick_subsystem_initialized;
int i;
if (!sdl_joystick_subsystem_initialized)
int joystick_nr = getJoystickNrFromDeviceName(device_name);
if (joystick_nr >= SDL_NumJoysticks())
+ {
+ if (setup.input[i].use_joystick && print_warning)
+ Error(ERR_WARN, "cannot find joystick %d", joystick_nr);
+
joystick_nr = -1;
+ }
/* misuse joystick file descriptor variable to store joystick number */
joystick.fd[i] = joystick_nr;
+ if (joystick_nr == -1)
+ continue;
+
/* this allows subsequent calls to 'InitJoysticks' for re-initialization */
if (SDLCheckJoystickOpened(joystick_nr))
SDLCloseJoystick(joystick_nr);
if (!SDLOpenJoystick(joystick_nr))
{
- Error(ERR_WARN, "cannot open joystick %d", joystick_nr);
+ if (print_warning)
+ Error(ERR_WARN, "cannot open joystick %d", joystick_nr);
+
continue;
}
#define LEVELCOLOR(n) (IS_LEVELCLASS_TUTORIAL(n) ? FC_BLUE : \
IS_LEVELCLASS_CLASSICS(n) ? FC_RED : \
- IS_LEVELCLASS_BD(n) ? FC_GREEN : \
+ IS_LEVELCLASS_BD(n) ? FC_YELLOW : \
IS_LEVELCLASS_EM(n) ? FC_YELLOW : \
- IS_LEVELCLASS_SP(n) ? FC_GREEN : \
+ IS_LEVELCLASS_SP(n) ? FC_YELLOW : \
IS_LEVELCLASS_DX(n) ? FC_YELLOW : \
+ IS_LEVELCLASS_SB(n) ? FC_YELLOW : \
IS_LEVELCLASS_CONTRIB(n) ? FC_GREEN : \
IS_LEVELCLASS_PRIVATE(n) ? FC_RED : \
FC_BLUE)
IS_LEVELCLASS_EM(n) ? 3 : \
IS_LEVELCLASS_SP(n) ? 4 : \
IS_LEVELCLASS_DX(n) ? 5 : \
- IS_LEVELCLASS_CONTRIB(n) ? 6 : \
- IS_LEVELCLASS_PRIVATE(n) ? 7 : \
+ IS_LEVELCLASS_SB(n) ? 6 : \
+ IS_LEVELCLASS_CONTRIB(n) ? 7 : \
+ IS_LEVELCLASS_PRIVATE(n) ? 8 : \
9)
#define ARTWORKCOLOR(n) (IS_ARTWORKCLASS_CLASSICS(n) ? FC_RED : \
- IS_ARTWORKCLASS_CONTRIB(n) ? FC_YELLOW : \
+ IS_ARTWORKCLASS_CONTRIB(n) ? FC_GREEN : \
IS_ARTWORKCLASS_PRIVATE(n) ? FC_RED : \
- IS_ARTWORKCLASS_LEVEL(n) ? FC_GREEN : \
+ IS_ARTWORKCLASS_LEVEL(n) ? FC_YELLOW : \
FC_BLUE)
#define ARTWORKSORTING(n) (IS_ARTWORKCLASS_CLASSICS(n) ? 0 : \
IS_ARTWORKCLASS_PRIVATE(n) ? 3 : \
9)
-#define TOKEN_VALUE_POSITION 40
-#define TOKEN_COMMENT_POSITION 60
+#define TOKEN_VALUE_POSITION_SHORT 32
+#define TOKEN_VALUE_POSITION_DEFAULT 40
+#define TOKEN_COMMENT_POSITION_DEFAULT 60
-#define MAX_COOKIE_LEN 256
+#define MAX_COOKIE_LEN 256
+
+static int token_value_position = TOKEN_VALUE_POSITION_DEFAULT;
+static int token_comment_position = TOKEN_COMMENT_POSITION_DEFAULT;
/* ------------------------------------------------------------------------- */
checked_free(level_dir);
- level_dir = getPath2((node->user_defined ? getUserLevelDir(NULL) :
+ level_dir = getPath2((node->in_user_dir ? getUserLevelDir(NULL) :
options.level_directory), node->fullpath);
return level_dir;
if (ti == NULL || leveldir_current == NULL)
return NULL;
- artwork_path_ptr = &(LEVELDIR_ARTWORK_PATH(leveldir_current, ti->type));
- artwork_set_ptr = &(LEVELDIR_ARTWORK_SET( leveldir_current, ti->type));
+ artwork_path_ptr = LEVELDIR_ARTWORK_PATH_PTR(leveldir_current, ti->type);
+ artwork_set_ptr = LEVELDIR_ARTWORK_SET_PTR( leveldir_current, ti->type);
checked_free(*artwork_path_ptr);
static char *filename = NULL;
checked_free(filename);
+ filename = getPath2(getCurrentLevelDir(), EDITORSETUP_FILENAME);
+
+ if (fileExists(filename))
+ return filename;
+ checked_free(filename);
filename = getPath2(getSetupDir(), EDITORSETUP_FILENAME);
return filename;
char *basenames[] =
{
"README",
- "README.txt",
"README.TXT",
+ "README.txt",
"Readme",
"Readme.txt",
"readme",
for (i = 0; basenames[i] != NULL; i++)
{
checked_free(filename);
-
filename = getPath2(getCurrentLevelDir(), basenames[i]);
+
if (fileExists(filename))
return filename;
}
void InitUserLevelDirectory(char *level_subdir)
{
- if (access(getUserLevelDir(level_subdir), F_OK) != 0)
+ if (!fileExists(getUserLevelDir(level_subdir)))
{
createDirectory(getUserDataDir(), "user data", PERMS_PRIVATE);
createDirectory(getUserLevelDir(NULL), "main user level", PERMS_PRIVATE);
#if 1
printf("subdir == '%s' ['%s', '%s'] [%d])\n",
- node->subdir, node->fullpath, node->basepath, node->user_defined);
+ node->subdir, node->fullpath, node->basepath, node->in_user_dir);
#else
printf("subdir == '%s' (%s) [%s] (%d)\n",
node->subdir, node->name, node->identifier, node->sort_priority);
mode_t group_umask = ~(dir_mode & S_IRWXG);
posix_umask(normal_umask & group_umask);
- if (access(dir, F_OK) != 0)
+ if (!fileExists(dir))
if (posix_mkdir(dir, dir_mode) != 0)
Error(ERR_WARN, "cannot create %s directory '%s'", text, dir);
/* start with the token and some spaces to format output line */
sprintf(entry, "%s:", token);
- for (i = strlen(entry); i < TOKEN_VALUE_POSITION; i++)
+ for (i = strlen(entry); i < token_value_position; i++)
strcat(entry, " ");
/* continue with the token's value */
boolean read_continued_line = FALSE;
FILE *file;
- if (use_hash)
- setup_file_data = newSetupFileHash();
- else
- insert_ptr = setup_file_data = newSetupFileList("", "");
-
if (!(file = fopen(filename, MODE_READ)))
{
Error(ERR_WARN, "cannot open configuration file '%s'", filename);
+
return NULL;
}
+ if (use_hash)
+ setup_file_data = newSetupFileHash();
+ else
+ insert_ptr = setup_file_data = newSetupFileList("", "");
+
while (!feof(file))
{
/* read next line of input file */
#define LEVELINFO_TOKEN_NAME_SORTING 2
#define LEVELINFO_TOKEN_AUTHOR 3
#define LEVELINFO_TOKEN_IMPORTED_FROM 4
-#define LEVELINFO_TOKEN_LEVELS 5
-#define LEVELINFO_TOKEN_FIRST_LEVEL 6
-#define LEVELINFO_TOKEN_SORT_PRIORITY 7
-#define LEVELINFO_TOKEN_LATEST_ENGINE 8
-#define LEVELINFO_TOKEN_LEVEL_GROUP 9
-#define LEVELINFO_TOKEN_READONLY 10
-#define LEVELINFO_TOKEN_GRAPHICS_SET 11
-#define LEVELINFO_TOKEN_SOUNDS_SET 12
-#define LEVELINFO_TOKEN_MUSIC_SET 13
-#define LEVELINFO_TOKEN_FILENAME 14
-#define LEVELINFO_TOKEN_FILETYPE 15
-#define LEVELINFO_TOKEN_HANDICAP 16
-
-#define NUM_LEVELINFO_TOKENS 17
+#define LEVELINFO_TOKEN_IMPORTED_BY 5
+#define LEVELINFO_TOKEN_LEVELS 6
+#define LEVELINFO_TOKEN_FIRST_LEVEL 7
+#define LEVELINFO_TOKEN_SORT_PRIORITY 8
+#define LEVELINFO_TOKEN_LATEST_ENGINE 9
+#define LEVELINFO_TOKEN_LEVEL_GROUP 10
+#define LEVELINFO_TOKEN_READONLY 11
+#define LEVELINFO_TOKEN_GRAPHICS_SET 12
+#define LEVELINFO_TOKEN_SOUNDS_SET 13
+#define LEVELINFO_TOKEN_MUSIC_SET 14
+#define LEVELINFO_TOKEN_FILENAME 15
+#define LEVELINFO_TOKEN_FILETYPE 16
+#define LEVELINFO_TOKEN_HANDICAP 17
+#define LEVELINFO_TOKEN_SKIP_LEVELS 18
+
+#define NUM_LEVELINFO_TOKENS 19
static LevelDirTree ldi;
{ TYPE_STRING, &ldi.name_sorting, "name_sorting" },
{ TYPE_STRING, &ldi.author, "author" },
{ TYPE_STRING, &ldi.imported_from, "imported_from" },
+ { TYPE_STRING, &ldi.imported_by, "imported_by" },
{ TYPE_INTEGER, &ldi.levels, "levels" },
{ TYPE_INTEGER, &ldi.first_level, "first_level" },
{ TYPE_INTEGER, &ldi.sort_priority, "sort_priority" },
{ TYPE_STRING, &ldi.music_set, "music_set" },
{ TYPE_STRING, &ldi.level_filename, "filename" },
{ TYPE_STRING, &ldi.level_filetype, "filetype" },
- { TYPE_BOOLEAN, &ldi.handicap, "handicap" }
+ { TYPE_BOOLEAN, &ldi.handicap, "handicap" },
+ { TYPE_BOOLEAN, &ldi.skip_levels, "skip_levels" }
};
static void setTreeInfoToDefaults(TreeInfo *ldi, int type)
ldi->sort_priority = LEVELCLASS_UNDEFINED; /* default: least priority */
ldi->latest_engine = FALSE; /* default: get from level */
ldi->parent_link = FALSE;
+ ldi->in_user_dir = FALSE;
ldi->user_defined = FALSE;
ldi->color = 0;
ldi->class_desc = NULL;
if (ldi->type == TREE_TYPE_LEVEL_DIR)
{
ldi->imported_from = NULL;
+ ldi->imported_by = NULL;
ldi->graphics_set = NULL;
ldi->sounds_set = NULL;
ldi->handicap_level = 0;
ldi->readonly = TRUE;
ldi->handicap = TRUE;
+ ldi->skip_levels = FALSE;
}
}
ldi->sort_priority = parent->sort_priority;
ldi->latest_engine = parent->latest_engine;
ldi->parent_link = FALSE;
+ ldi->in_user_dir = parent->in_user_dir;
ldi->user_defined = parent->user_defined;
ldi->color = parent->color;
ldi->class_desc = getStringCopy(parent->class_desc);
if (ldi->type == TREE_TYPE_LEVEL_DIR)
{
ldi->imported_from = getStringCopy(parent->imported_from);
+ ldi->imported_by = getStringCopy(parent->imported_by);
ldi->graphics_set = NULL;
ldi->sounds_set = NULL;
ldi->handicap_level = 0;
ldi->readonly = TRUE;
ldi->handicap = TRUE;
+ ldi->skip_levels = FALSE;
}
#else
ldi->author = getStringCopy(parent->author);
ldi->imported_from = getStringCopy(parent->imported_from);
+ ldi->imported_by = getStringCopy(parent->imported_by);
ldi->class_desc = getStringCopy(parent->class_desc);
ldi->graphics_set = NULL;
if (ldi->type == TREE_TYPE_LEVEL_DIR)
{
checked_free(ldi->imported_from);
+ checked_free(ldi->imported_by);
checked_free(ldi->graphics_set);
checked_free(ldi->sounds_set);
{
char *directory_path = getPath2(level_directory, directory_name);
char *filename = getPath2(directory_path, LEVELINFO_FILENAME);
- SetupFileHash *setup_file_hash = loadSetupFileHash(filename);
+ SetupFileHash *setup_file_hash;
LevelDirTree *leveldir_new = NULL;
int i;
+ /* unless debugging, silently ignore directories without "levelinfo.conf" */
+ if (!options.debug && !fileExists(filename))
+ {
+ free(directory_path);
+ free(filename);
+
+ return FALSE;
+ }
+
+ setup_file_hash = loadSetupFileHash(filename);
+
if (setup_file_hash == NULL)
{
Error(ERR_WARN, "ignoring level directory '%s'", directory_path);
leveldir_new->first_level + leveldir_new->levels - 1;
#if 1
- leveldir_new->user_defined =
+ leveldir_new->in_user_dir =
(strcmp(leveldir_new->basepath, options.level_directory) != 0);
#else
- leveldir_new->user_defined =
+ leveldir_new->in_user_dir =
(leveldir_new->basepath == options.level_directory ? FALSE : TRUE);
#endif
+#if 1
+ /* adjust sort priority if user's private level directory was detected */
+ if (leveldir_new->sort_priority == LEVELCLASS_UNDEFINED &&
+ leveldir_new->in_user_dir &&
+ strcmp(leveldir_new->subdir, getLoginName()) == 0)
+ leveldir_new->sort_priority = LEVELCLASS_PRIVATE_START;
+#endif
+
+ leveldir_new->user_defined =
+ (leveldir_new->in_user_dir && IS_LEVELCLASS_PRIVATE(leveldir_new));
+
leveldir_new->color = LEVELCOLOR(leveldir_new);
#if 1
setString(&leveldir_new->class_desc, getLevelClassDescription(leveldir_new));
TreeInfo *artwork_new = NULL;
int i;
- if (access(filename, F_OK) == 0) /* file exists */
+ if (fileExists(filename))
setup_file_hash = loadSetupFileHash(filename);
if (setup_file_hash == NULL) /* no config file -- look for artwork files */
}
#if 1
- artwork_new->user_defined =
+ artwork_new->in_user_dir =
(strcmp(artwork_new->basepath, OPTIONS_ARTWORK_DIRECTORY(type)) != 0);
#else
- artwork_new->user_defined =
+ artwork_new->in_user_dir =
(artwork_new->basepath == OPTIONS_ARTWORK_DIRECTORY(type) ? FALSE : TRUE);
#endif
setString(&level_info->author, getRealName());
level_info->levels = 100;
level_info->first_level = 1;
+#if 0
level_info->sort_priority = LEVELCLASS_PRIVATE_START;
level_info->readonly = FALSE;
setString(&level_info->graphics_set, GFX_CLASSIC_SUBDIR);
setString(&level_info->sounds_set, SND_CLASSIC_SUBDIR);
setString(&level_info->music_set, MUS_CLASSIC_SUBDIR);
+#endif
#else
ldi.name = getStringCopy(getLoginName());
ldi.author = getStringCopy(getRealName());
ldi.music_set = getStringCopy(MUS_CLASSIC_SUBDIR);
#endif
+ token_value_position = TOKEN_VALUE_POSITION_SHORT;
+
fprintf(file, "%s\n\n", getFormattedSetupEntry(TOKEN_STR_FILE_IDENTIFIER,
getCookie("LEVELINFO")));
ldi = *level_info;
for (i = 0; i < NUM_LEVELINFO_TOKENS; i++)
+ {
+#if 1
+ if (i == LEVELINFO_TOKEN_NAME ||
+ i == LEVELINFO_TOKEN_AUTHOR ||
+ i == LEVELINFO_TOKEN_LEVELS ||
+ i == LEVELINFO_TOKEN_FIRST_LEVEL)
+ fprintf(file, "%s\n", getSetupLine(levelinfo_tokens, "", i));
+
+ /* just to make things nicer :) */
+ if (i == LEVELINFO_TOKEN_AUTHOR)
+ fprintf(file, "\n");
+#else
if (i != LEVELINFO_TOKEN_IDENTIFIER &&
i != LEVELINFO_TOKEN_NAME_SORTING &&
i != LEVELINFO_TOKEN_IMPORTED_FROM &&
+ i != LEVELINFO_TOKEN_IMPORTED_BY &&
i != LEVELINFO_TOKEN_FILENAME &&
i != LEVELINFO_TOKEN_FILETYPE)
fprintf(file, "%s\n", getSetupLine(levelinfo_tokens, "", i));
+#endif
+ }
+
+ token_value_position = TOKEN_VALUE_POSITION_DEFAULT;
fclose(file);
{
/* add at least one whitespace */
strcat(line, " ");
- for (i = strlen(line); i < TOKEN_COMMENT_POSITION; i++)
+ for (i = strlen(line); i < token_comment_position; i++)
strcat(line, " ");
strcat(line, "# ");
/* check for more levels besides the 'levels' field of 'levelinfo.conf' */
- level_directory = getPath2((leveldir_current->user_defined ?
+ level_directory = getPath2((leveldir_current->in_user_dir ?
getUserLevelDir(NULL) :
options.level_directory),
leveldir_current->fullpath);
#define LEVELCLASS_SP_END 699
#define LEVELCLASS_DX_START 700
#define LEVELCLASS_DX_END 799
+#define LEVELCLASS_SB_START 800
+#define LEVELCLASS_SB_END 899
#define LEVELCLASS_PREDEFINED_START LEVELCLASS_TUTORIAL_START
-#define LEVELCLASS_PREDEFINED_END LEVELCLASS_DX_END
+#define LEVELCLASS_PREDEFINED_END LEVELCLASS_SB_END
#define LEVELCLASS_TUTORIAL LEVELCLASS_TUTORIAL_START
#define LEVELCLASS_CLASSICS LEVELCLASS_CLASSICS_START
#define LEVELCLASS_EM LEVELCLASS_EM_START
#define LEVELCLASS_SP LEVELCLASS_SP_START
#define LEVELCLASS_DX LEVELCLASS_DX_START
+#define LEVELCLASS_SB LEVELCLASS_SB_START
#define LEVELCLASS_UNDEFINED 999
#define IS_LEVELCLASS_DX(p) \
((p)->sort_priority >= LEVELCLASS_DX_START && \
(p)->sort_priority <= LEVELCLASS_DX_END)
+#define IS_LEVELCLASS_SB(p) \
+ ((p)->sort_priority >= LEVELCLASS_SB_START && \
+ (p)->sort_priority <= LEVELCLASS_SB_END)
#define IS_LEVELCLASS_UNDEFINED(p) \
((p)->sort_priority < LEVELCLASS_PREDEFINED_START || \
(p)->sort_priority > LEVELCLASS_PREDEFINED_END)
IS_LEVELCLASS_EM(n) ? LEVELCLASS_EM : \
IS_LEVELCLASS_SP(n) ? LEVELCLASS_SP : \
IS_LEVELCLASS_DX(n) ? LEVELCLASS_DX : \
+ IS_LEVELCLASS_SB(n) ? LEVELCLASS_SB : \
LEVELCLASS_UNDEFINED)
/* sort priorities of artwork */
}
void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries,
- struct ConfigInfo *config_suffix_list,
+ struct ConfigTypeInfo *config_suffix_list,
char **base_prefixes, char **ext1_suffixes,
char **ext2_suffixes, char **ext3_suffixes,
char **ignore_tokens)
}
void InitMusicList(struct ConfigInfo *config_list, int num_file_list_entries,
- struct ConfigInfo *config_suffix_list,
+ struct ConfigTypeInfo *config_suffix_list,
char **base_prefixes, char **ext1_suffixes,
char **ext2_suffixes, char **ext3_suffixes,
char **ignore_tokens)
int getMusicListPropertyMappingSize();
struct PropertyMapping *getSoundListPropertyMapping();
struct PropertyMapping *getMusicListPropertyMapping();
-void InitSoundList(struct ConfigInfo *, int, struct ConfigInfo *,
+void InitSoundList(struct ConfigInfo *, int, struct ConfigTypeInfo *,
char **, char **, char **, char **, char **);
-void InitMusicList(struct ConfigInfo *, int, struct ConfigInfo *,
+void InitMusicList(struct ConfigInfo *, int, struct ConfigTypeInfo *,
char **, char **, char **, char **, char **);
void InitReloadCustomSounds(char *);
void InitReloadCustomMusic(char *);
#endif
#include "system.h"
+#include "image.h"
#include "sound.h"
#include "setup.h"
#include "joystick.h"
char *cookie_prefix, char *filename_prefix,
int program_version)
{
- program.command_basename =
- (strrchr(argv0, '/') ? strrchr(argv0, '/') + 1 : argv0);
+ program.command_basepath = getBasePath(argv0);
+ program.command_basename = getBaseName(argv0);
program.userdata_directory = userdata_directory;
program.program_title = program_title;
void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask)
{
+ /* !!! THIS DOES NOT WORK !!! REPLACED BITMAPS MAY HAVE SAME ADDRESS !!! */
+#if 0
static Bitmap *main_bitmap_tile = NULL;
static Bitmap *door_bitmap_tile = NULL;
else if (mask == REDRAW_DOOR_1)
{
if (background_bitmap_tile == door_bitmap_tile)
- return; /* main background tile has not changed */
+ return; /* main background tile has not changed */
door_bitmap_tile = background_bitmap_tile;
}
- else /* should not happen */
+ else /* should not happen */
return;
+#endif
- if (background_bitmap_tile)
+ if (background_bitmap_tile != NULL)
gfx.background_bitmap_mask |= mask;
else
gfx.background_bitmap_mask &= ~mask;
DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile,
gfx.real_sx, gfx.real_sy,
gfx.full_sxsize, gfx.full_sysize);
- else
+ else if (mask == REDRAW_DOOR_1)
+ {
DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile,
gfx.dx, gfx.dy,
gfx.dxsize, gfx.dysize);
+ }
}
void SetMainBackgroundBitmap(Bitmap *background_bitmap_tile)
inline boolean DrawingOnBackground(int x, int y)
{
+#if 1
+ return (CheckDrawingArea(x, y, 1, 1, gfx.background_bitmap_mask) &&
+ CheckDrawingArea(x, y, 1, 1, gfx.draw_background_mask));
+#else
return ((gfx.draw_background_mask & gfx.background_bitmap_mask) &&
CheckDrawingArea(x, y, 1, 1, gfx.draw_background_mask));
+#endif
}
inline void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap,
return dst_bitmap;
}
-void CreateBitmapWithSmallBitmaps(Bitmap *src_bitmap)
+void CreateBitmapWithSmallBitmaps(Bitmap *old_bitmap, int zoom_factor)
{
- Bitmap *tmp_bitmap, *tmp_bitmap_2, *tmp_bitmap_8;
- int src_width, src_height;
- int tmp_width, tmp_height;
+ Bitmap swap_bitmap;
+ Bitmap *new_bitmap, *tmp_bitmap_1, *tmp_bitmap_2, *tmp_bitmap_8;
+ int width_1, height_1, width_2, height_2, width_8, height_8;
+ int new_width, new_height;
+
+ width_1 = old_bitmap->width * zoom_factor;
+ height_1 = old_bitmap->height * zoom_factor;
+ width_2 = width_1 / 2;
+ height_2 = height_1 / 2;
+ width_8 = width_1 / 8;
+ height_8 = height_1 / 8;
+
+ /* get image with normal size (this might require scaling up) */
+ if (zoom_factor != 1)
+ tmp_bitmap_1 = ZoomBitmap(old_bitmap, width_1, height_1);
+ else
+ tmp_bitmap_1 = old_bitmap;
+
+ /* get image with 1/2 of normal size (for use in the level editor) */
+ if (zoom_factor != 2)
+ tmp_bitmap_2 = ZoomBitmap(tmp_bitmap_1, width_1 / 2, height_1 / 2);
+ else
+ tmp_bitmap_2 = old_bitmap;
+
+ /* get image with 1/8 of normal size (for use on the preview screen) */
+ if (zoom_factor != 8)
+ tmp_bitmap_8 = ZoomBitmap(tmp_bitmap_1, width_1 / 8, height_1 / 8);
+ else
+ tmp_bitmap_8 = old_bitmap;
+
+ /* if image was scaled up, create new clipmask for normal size image */
+ if (zoom_factor != 1)
+ {
+#if defined(TARGET_X11)
+ if (old_bitmap->clip_mask)
+ XFreePixmap(display, old_bitmap->clip_mask);
+
+ old_bitmap->clip_mask =
+ Pixmap_to_Mask(tmp_bitmap_1->drawable, width_1, height_1);
- src_width = src_bitmap->width;
- src_height = src_bitmap->height;
+ XSetClipMask(display, old_bitmap->stored_clip_gc, old_bitmap->clip_mask);
+#else
+ SDL_Surface *tmp_surface_1 = tmp_bitmap_1->surface;
+
+ if (old_bitmap->surface_masked)
+ SDL_FreeSurface(old_bitmap->surface_masked);
+
+ SDL_SetColorKey(tmp_surface_1, SDL_SRCCOLORKEY,
+ SDL_MapRGB(tmp_surface_1->format, 0x00, 0x00, 0x00));
+ if ((old_bitmap->surface_masked = SDL_DisplayFormat(tmp_surface_1)) ==NULL)
+ Error(ERR_EXIT, "SDL_DisplayFormat() failed");
+ SDL_SetColorKey(tmp_surface_1, 0, 0); /* reset transparent pixel */
+#endif
+ }
+
+ new_width = width_1;
+ new_height = height_1 + (height_1 + 1) / 2; /* prevent odd height */
- tmp_width = src_width;
- tmp_height = src_height + (src_height + 1) / 2; /* prevent odd height */
+ new_bitmap = CreateBitmap(new_width, new_height, DEFAULT_DEPTH);
- tmp_bitmap = CreateBitmap(tmp_width, tmp_height, DEFAULT_DEPTH);
+ BlitBitmap(tmp_bitmap_1, new_bitmap, 0, 0, width_1, height_1, 0, 0);
+ BlitBitmap(tmp_bitmap_2, new_bitmap, 0, 0, width_1 / 2, height_1 / 2,
+ 0, height_1);
+ BlitBitmap(tmp_bitmap_8, new_bitmap, 0, 0, width_1 / 8, height_1 / 8,
+ 3 * width_1 / 4, height_1);
- tmp_bitmap_2 = ZoomBitmap(src_bitmap, src_width / 2, src_height / 2);
- tmp_bitmap_8 = ZoomBitmap(src_bitmap, src_width / 8, src_height / 8);
+ if (zoom_factor != 1)
+ FreeBitmap(tmp_bitmap_1);
- BlitBitmap(src_bitmap, tmp_bitmap, 0, 0, src_width, src_height, 0, 0);
- BlitBitmap(tmp_bitmap_2, tmp_bitmap, 0, 0, src_width / 2, src_height / 2,
- 0, src_height);
- BlitBitmap(tmp_bitmap_8, tmp_bitmap, 0, 0, src_width / 8, src_height / 8,
- 3 * src_width / 4, src_height);
+ if (zoom_factor != 2)
+ FreeBitmap(tmp_bitmap_2);
- FreeBitmap(tmp_bitmap_2);
- FreeBitmap(tmp_bitmap_8);
+ if (zoom_factor != 8)
+ FreeBitmap(tmp_bitmap_8);
+
+#if 0
#if defined(TARGET_SDL)
- /* !!! what about the old src_bitmap->surface ??? FIX ME !!! */
- src_bitmap->surface = tmp_bitmap->surface;
- tmp_bitmap->surface = NULL;
+ /* !!! what about the old old_bitmap->surface ??? FIX ME !!! */
+ old_bitmap->surface = new_bitmap->surface;
+ new_bitmap->surface = NULL;
#else
/* !!! see above !!! */
- src_bitmap->drawable = tmp_bitmap->drawable;
- tmp_bitmap->drawable = None;
+ old_bitmap->drawable = new_bitmap->drawable;
+ new_bitmap->drawable = None;
+#endif
+
+#else
+
+ /* replace image with extended image (containing normal, 1/2 and 1/8 size) */
+#if defined(TARGET_SDL)
+ swap_bitmap.surface = old_bitmap->surface;
+ old_bitmap->surface = new_bitmap->surface;
+ new_bitmap->surface = swap_bitmap.surface;
+#else
+ swap_bitmap.drawable = old_bitmap->drawable;
+ old_bitmap->drawable = new_bitmap->drawable;
+ new_bitmap->drawable = swap_bitmap.drawable;
#endif
- src_bitmap->height = tmp_bitmap->height;
+#endif
+
+ old_bitmap->width = new_bitmap->width;
+ old_bitmap->height = new_bitmap->height;
- FreeBitmap(tmp_bitmap);
+ FreeBitmap(new_bitmap);
}
#endif
}
+inline void PeekEvent(Event *event)
+{
+#if defined(TARGET_SDL)
+ SDL_PeepEvents(event, 1, SDL_PEEKEVENT, SDL_ALLEVENTS);
+#else
+ XPeekEvent(display, event);
+#endif
+}
+
inline Key GetEventKey(KeyEvent *event, boolean with_modifiers)
{
#if defined(TARGET_SDL)
#define BUTTON_1 4
#define BUTTON_2 5
-/* values for move direction and special "button" key bitmasks */
+/* values for move directions and special "button" key bitmasks */
#define MV_NO_MOVING 0
#define MV_LEFT (1 << MV_BIT_LEFT)
#define MV_RIGHT (1 << MV_BIT_RIGHT)
#define MV_UP (1 << MV_BIT_UP)
#define MV_DOWN (1 << MV_BIT_DOWN)
+#define MV_HORIZONTAL (MV_LEFT | MV_RIGHT)
+#define MV_VERTICAL (MV_UP | MV_DOWN)
+#define MV_ALL_DIRECTIONS (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)
+#define MV_ANY_DIRECTION (MV_ALL_DIRECTIONS)
+#define MV_NO_DIRECTIONS (MV_NO_MOVING)
+
#define KEY_BUTTON_1 (1 << BUTTON_1)
#define KEY_BUTTON_2 (1 << BUTTON_2)
#define KEY_MOTION (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)
/* values for artwork handling */
+#define LEVELDIR_ARTWORK_SET_PTR(leveldir, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ &(leveldir)->graphics_set : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ &(leveldir)->sounds_set : \
+ &(leveldir)->music_set)
+
#define LEVELDIR_ARTWORK_SET(leveldir, type) \
((type) == ARTWORK_TYPE_GRAPHICS ? \
(leveldir)->graphics_set : \
(leveldir)->sounds_set : \
(leveldir)->music_set)
+#define LEVELDIR_ARTWORK_PATH_PTR(leveldir, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ &(leveldir)->graphics_path : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ &(leveldir)->sounds_path : \
+ &(leveldir)->music_path)
+
#define LEVELDIR_ARTWORK_PATH(leveldir, type) \
((type) == ARTWORK_TYPE_GRAPHICS ? \
(leveldir)->graphics_path : \
(artwork).snd_first : \
(artwork).mus_first)
+#define ARTWORK_CURRENT_IDENTIFIER_PTR(artwork, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ &(artwork).gfx_current_identifier : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ &(artwork).snd_current_identifier : \
+ &(artwork).mus_current_identifier)
+
#define ARTWORK_CURRENT_IDENTIFIER(artwork, type) \
((type) == ARTWORK_TYPE_GRAPHICS ? \
(artwork).gfx_current_identifier : \
struct ProgramInfo
{
- char *command_basename;
- char *userdata_directory;
+ char *command_basepath; /* directory that contains the program */
+ char *command_basename; /* base filename of the program binary */
+ char *userdata_directory; /* personal user data directory */
char *program_title;
char *window_title;
{
boolean el_boulderdash;
boolean el_emerald_mine;
+ boolean el_emerald_mine_club;
boolean el_more;
boolean el_sokoban;
boolean el_supaplex;
boolean quick_doors;
boolean team_mode;
boolean handicap;
+ boolean skip_levels;
boolean time_limit;
boolean fullscreen;
boolean ask_on_escape;
char *name_sorting; /* optional sorting name for correct name sorting */
char *author; /* level or artwork author name */
char *imported_from; /* optional comment for imported levels or artwork */
+ char *imported_by; /* optional comment for imported levels or artwork */
char *graphics_set; /* optional custom graphics set (level tree only) */
char *sounds_set; /* optional custom sounds set (level tree only) */
boolean level_group; /* directory contains more level series directories */
boolean parent_link; /* entry links back to parent directory */
- boolean user_defined; /* user defined levels are stored in home directory */
+ boolean in_user_dir; /* user defined levels are stored in home directory */
+ boolean user_defined; /* levels in user directory and marked as "private" */
boolean readonly; /* readonly levels can not be changed with editor */
boolean handicap; /* level set has no handicap when set to "false" */
+ boolean skip_levels; /* levels can be skipped when set to "true" */
int color; /* color to use on selection screen for this level */
char *class_desc; /* description of level series class */
};
struct ConfigInfo
+{
+ char *token;
+ char *value;
+};
+
+struct ConfigTypeInfo
{
char *token;
char *value;
char **parameter; /* array of file parameters */
boolean redefined;
+ boolean fallback_to_default;
};
struct SetupFileList
struct FileInfo *dynamic_file_list; /* dynamic artwrk file array */
int num_suffix_list_entries;
- struct ConfigInfo *suffix_list; /* parameter suffixes array */
+ struct ConfigTypeInfo *suffix_list; /* parameter suffixes array */
int num_base_prefixes;
int num_ext1_suffixes;
void ReloadCustomImage(Bitmap *, char *);
Bitmap *ZoomBitmap(Bitmap *, int, int);
-void CreateBitmapWithSmallBitmaps(Bitmap *);
+void CreateBitmapWithSmallBitmaps(Bitmap *, int);
void SetMouseCursor(int);
inline void InitEventFilter(EventFilter);
inline boolean PendingEvent(void);
inline void NextEvent(Event *event);
+inline void PeekEvent(Event *event);
inline Key GetEventKey(KeyEvent *, boolean);
inline KeyMod HandleKeyModState(Key, int);
inline KeyMod GetKeyModState();
#endif
#ifndef SIGN
-#define SIGN(a) ((a) < 0 ? -1 : ((a)>0 ? 1 : 0))
+#define SIGN(a) ((a) < 0 ? -1 : ((a) > 0 ? 1 : 0))
#endif
#define SIZEOF_ARRAY(array, type) (sizeof(array) / sizeof(type))
#endif
int screen_width, screen_height;
int win_xpos, win_ypos;
- unsigned long pen_fg = WhitePixel(display,screen);
- unsigned long pen_bg = BlackPixel(display,screen);
+ unsigned long pen_fg = WhitePixel(display, screen);
+ unsigned long pen_bg = BlackPixel(display, screen);
const int width = video.width, height = video.height;
int i;
short Back[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
boolean Pushed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-unsigned long Changed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-unsigned long ChangeEvent[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+boolean Changed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short ChangeEvent[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
short WasJustMoving[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
short WasJustFalling[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
short CheckCollision[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
/* element definitions */
/* ------------------------------------------------------------------------- */
-struct ElementInfo element_info[MAX_NUM_ELEMENTS + 1] =
+struct ElementInfo element_info[MAX_NUM_ELEMENTS + 1];
+
+/* this contains predefined structure elements to initialize "element_info" */
+struct ElementNameInfo element_name_info[MAX_NUM_ELEMENTS + 1] =
{
/* keyword to start parser: "ELEMENT_INFO_START" <-- do not change! */
"letter '$'"
},
{
- "char_procent",
+ "char_percent",
"char",
"letter '%'"
},
{
"balloon_switch_any",
"balloon_switch",
- "send balloon in any direction"
+ "send balloon in pressed direction"
},
{
"emc_steelwall_1",
"sp_port",
"gravity off port (leading up)"
},
+ {
+ "balloon_switch_none",
+ "balloon_switch",
+ "stop moving balloon"
+ },
+ {
+ "emc_gate_5",
+ "gate",
+ "door 5 (EMC style)",
+ },
+ {
+ "emc_gate_6",
+ "gate",
+ "door 6 (EMC style)",
+ },
+ {
+ "emc_gate_7",
+ "gate",
+ "door 7 (EMC style)",
+ },
+ {
+ "emc_gate_8",
+ "gate",
+ "door 8 (EMC style)",
+ },
+ {
+ "emc_gate_5_gray",
+ "gate",
+ "gray door (EMC style, key 5)",
+ },
+ {
+ "emc_gate_6_gray",
+ "gate",
+ "gray door (EMC style, key 6)",
+ },
+ {
+ "emc_gate_7_gray",
+ "gate",
+ "gray door (EMC style, key 7)",
+ },
+ {
+ "emc_gate_8_gray",
+ "gate",
+ "gray door (EMC style, key 8)",
+ },
+ {
+ "emc_key_5",
+ "key",
+ "key 5 (EMC style)",
+ },
+ {
+ "emc_key_6",
+ "key",
+ "key 6 (EMC style)",
+ },
+ {
+ "emc_key_7",
+ "key",
+ "key 7 (EMC style)",
+ },
+ {
+ "emc_key_8",
+ "key",
+ "key 8 (EMC style)",
+ },
+ {
+ "emc_android",
+ "emc_android",
+ "android",
+ },
+ {
+ "emc_grass",
+ "emc_grass",
+ "grass",
+ },
+ {
+ "emc_magic_ball",
+ "emc_magic_ball",
+ "magic ball",
+ },
+ {
+ "emc_magic_ball.active",
+ "emc_magic_ball",
+ "magic ball (activated)",
+ },
+ {
+ "emc_magic_ball_switch",
+ "emc_magic_ball_switch",
+ "magic ball switch (off)",
+ },
+ {
+ "emc_magic_ball_switch.active",
+ "emc_magic_ball_switch",
+ "magic ball switch (on)",
+ },
+ {
+ "emc_spring_bumper",
+ "emc_spring_bumper",
+ "spring bumper",
+ },
+ {
+ "emc_plant",
+ "emc_plant",
+ "plant",
+ },
+ {
+ "emc_lenses",
+ "emc_lenses",
+ "lenses",
+ },
+ {
+ "emc_magnifier",
+ "emc_magnifier",
+ "magnifier",
+ },
+ {
+ "emc_wall_9",
+ "wall",
+ "normal wall"
+ },
+ {
+ "emc_wall_10",
+ "wall",
+ "normal wall"
+ },
+ {
+ "emc_wall_11",
+ "wall",
+ "normal wall"
+ },
+ {
+ "emc_wall_12",
+ "wall",
+ "normal wall"
+ },
+ {
+ "emc_wall_13",
+ "wall",
+ "normal wall"
+ },
+ {
+ "emc_wall_14",
+ "wall",
+ "normal wall"
+ },
+ {
+ "emc_wall_15",
+ "wall",
+ "normal wall"
+ },
+ {
+ "emc_wall_16",
+ "wall",
+ "normal wall"
+ },
+ {
+ "emc_wall_slippery_1",
+ "wall",
+ "slippery wall"
+ },
+ {
+ "emc_wall_slippery_2",
+ "wall",
+ "slippery wall"
+ },
+ {
+ "emc_wall_slippery_3",
+ "wall",
+ "slippery wall"
+ },
+ {
+ "emc_wall_slippery_4",
+ "wall",
+ "slippery wall"
+ },
+ {
+ "emc_fake_grass",
+ "fake grass",
+ "fake grass"
+ },
+ {
+ "emc_fake_acid",
+ "fake acid",
+ "fake acid"
+ },
+ {
+ "emc_dripper",
+ "dripper",
+ "dripper"
+ },
/* ----------------------------------------------------------------------- */
/* "real" (and therefore drawable) runtime elements */
{ ".turning_from_right", ACTION_TURNING_FROM_RIGHT, FALSE },
{ ".turning_from_up", ACTION_TURNING_FROM_UP, FALSE },
{ ".turning_from_down", ACTION_TURNING_FROM_DOWN, FALSE },
+ { ".smashed_by_rock", ACTION_SMASHED_BY_ROCK, FALSE },
+ { ".smashed_by_spring", ACTION_SMASHED_BY_SPRING, FALSE },
+ { ".slurped_by_spring", ACTION_SLURPED_BY_SPRING, FALSE },
+ { ".twinkling", ACTION_TWINKLING, FALSE },
+ { ".splashing", ACTION_SPLASHING, FALSE },
{ ".other", ACTION_OTHER, FALSE },
/* empty suffix always matches -- check as last entry in InitSoundInfo() */
{
{ "global.num_toons", &global.num_toons },
- { "menu.draw_xoffset", &menu.draw_xoffset_default },
- { "menu.draw_yoffset", &menu.draw_yoffset_default },
+ { "menu.draw_xoffset", &menu.draw_xoffset[GFX_SPECIAL_ARG_DEFAULT]},
+ { "menu.draw_yoffset", &menu.draw_yoffset[GFX_SPECIAL_ARG_DEFAULT]},
{ "menu.draw_xoffset.MAIN", &menu.draw_xoffset[GFX_SPECIAL_ARG_MAIN] },
{ "menu.draw_yoffset.MAIN", &menu.draw_yoffset[GFX_SPECIAL_ARG_MAIN] },
{ "menu.draw_xoffset.LEVELS", &menu.draw_xoffset[GFX_SPECIAL_ARG_LEVELS] },
{ "menu.scrollbar_xoffset", &menu.scrollbar_xoffset },
- { "menu.list_size", &menu.list_size_default },
+ { "menu.list_size", &menu.list_size[GFX_SPECIAL_ARG_DEFAULT] },
{ "menu.list_size.LEVELS", &menu.list_size[GFX_SPECIAL_ARG_LEVELS] },
{ "menu.list_size.SCORES", &menu.list_size[GFX_SPECIAL_ARG_SCORES] },
{ "menu.list_size.INFO", &menu.list_size[GFX_SPECIAL_ARG_INFO] },
" \"print helptext.conf\" print default helptext config\n"
" \"dump level FILE\" dump level data from FILE\n"
" \"dump tape FILE\" dump tape data from FILE\n"
- " \"autoplay LEVELDIR [NR]\" play level tapes for LEVELDIR\n"
+ " \"autoplay LEVELDIR [NR ...]\" play level tapes for LEVELDIR\n"
" \"convert LEVELDIR [NR]\" convert levels in LEVELDIR\n"
"\n",
program.command_basename);
#include <fcntl.h>
#include "libgame/libgame.h"
+#include "game_em/game_em.h"
#include "conf_gfx.h" /* include auto-generated data structure definitions */
#include "conf_snd.h" /* include auto-generated data structure definitions */
#define CE_HITTING_SOMETHING 5
#define CE_IMPACT 6
#define CE_SMASHED 7
-#define CE_OTHER_IS_TOUCHING 8
-#define CE_OTHER_IS_CHANGING 9
-#define CE_OTHER_IS_EXPLODING 10
-#define CE_OTHER_GETS_TOUCHED 11
-#define CE_OTHER_GETS_PRESSED 12
-#define CE_OTHER_GETS_PUSHED 13
-#define CE_OTHER_GETS_COLLECTED 14
-#define CE_OTHER_GETS_DROPPED 15
+#define CE_TOUCHING_X 8
+#define CE_CHANGE_OF_X 9
+#define CE_EXPLOSION_OF_X 10
+#define CE_PLAYER_TOUCHES_X 11
+#define CE_PLAYER_PRESSES_X 12
+#define CE_PLAYER_PUSHES_X 13
+#define CE_PLAYER_COLLECTS_X 14
+#define CE_PLAYER_DROPS_X 15
#define CE_BY_PLAYER_OBSOLETE 16 /* obsolete; now CE_BY_DIRECT_ACTION */
#define CE_BY_COLLISION_OBSOLETE 17 /* obsolete; now CE_BY_DIRECT_ACTION */
#define CE_BY_OTHER_ACTION 18 /* activates other element events */
#define CE_BY_DIRECT_ACTION 19 /* activates direct element events */
-#define CE_OTHER_GETS_DIGGED 20
+#define CE_PLAYER_DIGS_X 20
#define CE_ENTERED_BY_PLAYER 21
#define CE_LEFT_BY_PLAYER 22
-#define CE_OTHER_GETS_ENTERED 23
-#define CE_OTHER_GETS_LEFT 24
+#define CE_PLAYER_ENTERS_X 23
+#define CE_PLAYER_LEAVES_X 24
#define CE_SWITCHED 25
-#define CE_OTHER_IS_SWITCHING 26
+#define CE_SWITCH_OF_X 26
#define CE_HIT_BY_SOMETHING 27
-#define CE_OTHER_IS_HITTING 28
-#define CE_OTHER_GETS_HIT 29
+#define CE_HITTING_X 28
+#define CE_HIT_BY_X 29
#define CE_BLOCKED 30
#define NUM_CHANGE_EVENTS 31
#define CE_BITMASK_DEFAULT 0
+#if 1
+
+#define CH_EVENT_VAR(e,c) (element_info[e].change->has_event[c])
+#define CH_ANY_EVENT_VAR(e,c) (element_info[e].has_change_event[c])
+
+#define PAGE_HAS_CHANGE_EVENT(p,c) ((p)->has_event[c])
+#define HAS_CHANGE_EVENT(e,c) (IS_CUSTOM_ELEMENT(e) && \
+ CH_EVENT_VAR(e,c))
+#define HAS_ANY_CHANGE_EVENT(e,c) (IS_CUSTOM_ELEMENT(e) && \
+ CH_ANY_EVENT_VAR(e,c))
+
+#define SET_CHANGE_EVENT(e,c,v) (IS_CUSTOM_ELEMENT(e) ? \
+ CH_EVENT_VAR(e,c) = (v) : 0)
+#define SET_ANY_CHANGE_EVENT(e,c,v) (IS_CUSTOM_ELEMENT(e) ? \
+ CH_ANY_EVENT_VAR(e,c) = (v) : 0)
+
+#else
+
#define CH_EVENT_BIT(c) (1 << (c))
#define CH_EVENT_VAR(e) (element_info[e].change->events)
#define CH_ANY_EVENT_VAR(e) (element_info[e].change_events)
((v) ? \
(CH_EVENT_VAR(e) |= CH_EVENT_BIT(c)) : \
(CH_EVENT_VAR(e) &= ~CH_EVENT_BIT(c))) : 0)
+#define SET_ANY_CHANGE_EVENT(e,c,v) (IS_CUSTOM_ELEMENT(e) ? \
+ ((v) ? \
+ (CH_ANY_EVENT_VAR(e) |= CH_EVENT_BIT(c)) : \
+ (CH_ANY_EVENT_VAR(e) &= ~CH_EVENT_BIT(c))) : 0)
+#endif
/* values for change side for custom elements */
#define CH_SIDE_NONE MV_NO_MOVING
#define MV_BIT_TURNING_RANDOM 16
/* values for custom move patterns */
-#define MV_HORIZONTAL (MV_LEFT | MV_RIGHT)
-#define MV_VERTICAL (MV_UP | MV_DOWN)
-#define MV_ALL_DIRECTIONS (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)
-#define MV_ANY_DIRECTION (MV_ALL_DIRECTIONS)
#define MV_TOWARDS_PLAYER (1 << MV_BIT_TOWARDS_PLAYER)
#define MV_AWAY_FROM_PLAYER (1 << MV_BIT_AWAY_FROM_PLAYER)
#define MV_ALONG_LEFT_SIDE (1 << MV_BIT_ALONG_LEFT_SIDE)
#define IS_ENVELOPE(e) ((e) >= EL_ENVELOPE_1 && \
(e) <= EL_ENVELOPE_4)
-#define IS_GATE(e) ((e) >= EL_GATE_1 && \
+#define IS_RND_KEY(e) ((e) >= EL_KEY_1 && \
+ (e) <= EL_KEY_4)
+#define IS_EM_KEY(e) ((e) >= EL_EM_KEY_1 && \
+ (e) <= EL_EM_KEY_4)
+#define IS_EMC_KEY(e) ((e) >= EL_EMC_KEY_5 && \
+ (e) <= EL_EMC_KEY_8)
+#define IS_KEY(e) (IS_RND_KEY(e) || \
+ IS_EM_KEY(e) || \
+ IS_EMC_KEY(e))
+#define RND_KEY_NR(e) ((e) - EL_KEY_1)
+#define EM_KEY_NR(e) ((e) - EL_EM_KEY_1)
+#define EMC_KEY_NR(e) ((e) - EL_EMC_KEY_5 + 4)
+#define KEY_NR(e) (IS_RND_KEY(e) ? RND_KEY_NR(e) : \
+ IS_EM_KEY(e) ? EM_KEY_NR(e) : \
+ IS_EMC_KEY(e) ? EMC_KEY_NR(e) : 0)
+
+#define IS_RND_GATE(e) ((e) >= EL_GATE_1 && \
(e) <= EL_GATE_4)
-
-#define IS_GATE_GRAY(e) ((e) >= EL_GATE_1_GRAY && \
- (e) <= EL_GATE_4_GRAY)
-
#define IS_EM_GATE(e) ((e) >= EL_EM_GATE_1 && \
(e) <= EL_EM_GATE_4)
-
+#define IS_EMC_GATE(e) ((e) >= EL_EMC_GATE_5 && \
+ (e) <= EL_EMC_GATE_8)
+#define IS_GATE(e) (IS_RND_GATE(e) || \
+ IS_EM_GATE(e) || \
+ IS_EMC_GATE(e))
+#define RND_GATE_NR(e) ((e) - EL_GATE_1)
+#define EM_GATE_NR(e) ((e) - EL_EM_GATE_1)
+#define EMC_GATE_NR(e) ((e) - EL_EMC_GATE_5 + 4)
+#define GATE_NR(e) (IS_RND_GATE(e) ? RND_GATE_NR(e) : \
+ IS_EM_GATE(e) ? EM_GATE_NR(e) : \
+ IS_EMC_GATE(e) ? EMC_GATE_NR(e) : 0)
+
+#define IS_RND_GATE_GRAY(e) ((e) >= EL_GATE_1_GRAY && \
+ (e) <= EL_GATE_4_GRAY)
#define IS_EM_GATE_GRAY(e) ((e) >= EL_EM_GATE_1_GRAY && \
(e) <= EL_EM_GATE_4_GRAY)
+#define IS_EMC_GATE_GRAY(e) ((e) >= EL_EMC_GATE_5_GRAY && \
+ (e) <= EL_EMC_GATE_8_GRAY)
+#define IS_GATE_GRAY(e) (IS_RND_GATE_GRAY(e) || \
+ IS_EM_GATE_GRAY(e) || \
+ IS_EMC_GATE_GRAY(e))
+#define RND_GATE_GRAY_NR(e) ((e) - EL_GATE_1_GRAY)
+#define EM_GATE_GRAY_NR(e) ((e) - EL_EM_GATE_1_GRAY)
+#define EMC_GATE_GRAY_NR(e) ((e) - EL_EMC_GATE_5_GRAY + 4)
+#define GATE_GRAY_NR(e) (IS_RND_GATE_GRAY(e) ? RND_GATE_GRAY_NR(e) : \
+ IS_EM_GATE_GRAY(e) ? EM_GATE_GRAY_NR(e) : \
+ IS_EMC_GATE_GRAY(e) ? EMC_GATE_GRAY_NR(e) : 0)
#define GFX_ELEMENT(e) (element_info[e].use_gfx_element ? \
element_info[e].gfx_element : e)
#define PLAYER_SWITCHING(p,x,y) ((p)->is_switching && \
(p)->switch_x == (x) && (p)->switch_y == (y))
+#define PLAYER_DROPPING(p,x,y) ((p)->is_dropping && \
+ (p)->drop_x == (x) && (p)->drop_y == (y))
+
#define PLAYER_NR_GFX(g,i) ((g) + i * (IMG_PLAYER_2 - IMG_PLAYER_1))
#define ANIM_FRAMES(g) (graphic_info[g].anim_frames)
#define MAX_LEVEL_NAME_LEN 32
#define MAX_LEVEL_AUTHOR_LEN 32
#define MAX_ELEMENT_NAME_LEN 32
-#define MAX_TAPELEN (1000 * FRAMES_PER_SECOND) /* max.time x fps */
+#define MAX_TAPE_LEN (1000 * FRAMES_PER_SECOND) /* max.time x fps */
+#define MAX_TAPES_PER_SET 1024
#define MAX_SCORE_ENTRIES 100
#define MAX_NUM_AMOEBA 100
#define MAX_INVENTORY_SIZE 1000
-#define MAX_KEYS 4
+#define STD_NUM_KEYS 4
+#define MAX_NUM_KEYS 8
#define NUM_BELTS 4
#define NUM_BELT_PARTS 3
#define MIN_ENVELOPE_XSIZE 1
#define MIN_ELEMENT_CONTENTS 1
#define STD_ELEMENT_CONTENTS 4
#define MAX_ELEMENT_CONTENTS 8
+#define NUM_MAGIC_BALL_CONTENTS 8
#define LEVEL_SCORE_ELEMENTS 16 /* level elements with score */
#define VY 400
#define EX DX
#define EY (VY - 44)
-#define TILEX 32
-#define TILEY 32
-#define MINI_TILEX (TILEX / 2)
-#define MINI_TILEY (TILEY / 2)
-#define MICRO_TILEX (TILEX / 8)
-#define MICRO_TILEY (TILEY / 8)
+#define TILESIZE 32
+#define TILEX TILESIZE
+#define TILEY TILESIZE
+#define MINI_TILESIZE (TILESIZE / 2)
+#define MINI_TILEX MINI_TILESIZE
+#define MINI_TILEY MINI_TILESIZE
+#define MICRO_TILESIZE (TILESIZE / 8)
+#define MICRO_TILEX MICRO_TILESIZE
+#define MICRO_TILEY MICRO_TILESIZE
#define MIDPOSX (SCR_FIELDX / 2)
#define MIDPOSY (SCR_FIELDY / 2)
#define SXSIZE (SCR_FIELDX * TILEX)
#define EYSIZE (VYSIZE + 44)
#define FULL_SXSIZE (2 + SXSIZE + 2)
#define FULL_SYSIZE (2 + SYSIZE + 2)
-#define MICROLEV_XSIZE ((STD_LEV_FIELDX + 2) * MICRO_TILEX)
-#define MICROLEV_YSIZE ((STD_LEV_FIELDY + 2) * MICRO_TILEY)
-#define MICROLEV_XPOS (SX + (SXSIZE - MICROLEV_XSIZE) / 2)
-#define MICROLEV_YPOS (SX + 12 * TILEY - MICRO_TILEY)
-#define MICROLABEL_YPOS (MICROLEV_YPOS + MICROLEV_YSIZE + 7)
+#define MICROLEVEL_XSIZE ((STD_LEV_FIELDX + 2) * MICRO_TILEX)
+#define MICROLEVEL_YSIZE ((STD_LEV_FIELDY + 2) * MICRO_TILEY)
+#define MICROLEVEL_XPOS (SX + (SXSIZE - MICROLEVEL_XSIZE) / 2)
+#define MICROLEVEL_YPOS (SX + 12 * TILEY - MICRO_TILEY)
+#define MICROLABEL1_YPOS (MICROLEVEL_YPOS - 36)
+#define MICROLABEL2_YPOS (MICROLEVEL_YPOS + MICROLEVEL_YSIZE + 7)
/* score for elements */
#define EL_SP_GRAVITY_OFF_PORT_LEFT 665
#define EL_SP_GRAVITY_OFF_PORT_UP 666
-#define NUM_FILE_ELEMENTS 667
+
+/* the following EMC style elements are currently not implemented in R'n'D */
+#define EL_BALLOON_SWITCH_NONE 667
+#define EL_EMC_GATE_5 668
+#define EL_EMC_GATE_6 669
+#define EL_EMC_GATE_7 670
+#define EL_EMC_GATE_8 671
+#define EL_EMC_GATE_5_GRAY 672
+#define EL_EMC_GATE_6_GRAY 673
+#define EL_EMC_GATE_7_GRAY 674
+#define EL_EMC_GATE_8_GRAY 675
+#define EL_EMC_KEY_5 676
+#define EL_EMC_KEY_6 677
+#define EL_EMC_KEY_7 678
+#define EL_EMC_KEY_8 679
+#define EL_EMC_ANDROID 680
+#define EL_EMC_GRASS 681
+#define EL_EMC_MAGIC_BALL 682
+#define EL_EMC_MAGIC_BALL_ACTIVE 683
+#define EL_EMC_MAGIC_BALL_SWITCH 684
+#define EL_EMC_MAGIC_BALL_SWITCH_ACTIVE 685
+#define EL_EMC_SPRING_BUMPER 686
+#define EL_EMC_PLANT 687
+#define EL_EMC_LENSES 688
+#define EL_EMC_MAGNIFIER 689
+#define EL_EMC_WALL_9 690
+#define EL_EMC_WALL_10 691
+#define EL_EMC_WALL_11 692
+#define EL_EMC_WALL_12 693
+#define EL_EMC_WALL_13 694
+#define EL_EMC_WALL_14 695
+#define EL_EMC_WALL_15 696
+#define EL_EMC_WALL_16 697
+#define EL_EMC_WALL_SLIPPERY_1 698
+#define EL_EMC_WALL_SLIPPERY_2 699
+#define EL_EMC_WALL_SLIPPERY_3 700
+#define EL_EMC_WALL_SLIPPERY_4 701
+#define EL_EMC_FAKE_GRASS 702
+#define EL_EMC_FAKE_ACID 703
+#define EL_EMC_DRIPPER 704
+
+#define NUM_FILE_ELEMENTS 705
/* "real" (and therefore drawable) runtime elements */
/* dummy elements (never used as game elements, only used as graphics) */
#define EL_FIRST_DUMMY (EL_FIRST_RUNTIME_UNREAL + 18)
-#define EL_STEELWALL_TOPLEFT (EL_FIRST_DUMMY + 0)
-#define EL_STEELWALL_TOPRIGHT (EL_FIRST_DUMMY + 1)
-#define EL_STEELWALL_BOTTOMLEFT (EL_FIRST_DUMMY + 2)
-#define EL_STEELWALL_BOTTOMRIGHT (EL_FIRST_DUMMY + 3)
-#define EL_STEELWALL_HORIZONTAL (EL_FIRST_DUMMY + 4)
-#define EL_STEELWALL_VERTICAL (EL_FIRST_DUMMY + 5)
-#define EL_INVISIBLE_STEELWALL_TOPLEFT (EL_FIRST_DUMMY + 6)
-#define EL_INVISIBLE_STEELWALL_TOPRIGHT (EL_FIRST_DUMMY + 7)
-#define EL_INVISIBLE_STEELWALL_BOTTOMLEFT (EL_FIRST_DUMMY + 8)
-#define EL_INVISIBLE_STEELWALL_BOTTOMRIGHT (EL_FIRST_DUMMY + 9)
-#define EL_INVISIBLE_STEELWALL_HORIZONTAL (EL_FIRST_DUMMY + 10)
-#define EL_INVISIBLE_STEELWALL_VERTICAL (EL_FIRST_DUMMY + 11)
-#define EL_DYNABOMB (EL_FIRST_DUMMY + 12)
-#define EL_DYNABOMB_ACTIVE (EL_FIRST_DUMMY + 13)
-#define EL_DYNABOMB_PLAYER_1 (EL_FIRST_DUMMY + 14)
-#define EL_DYNABOMB_PLAYER_2 (EL_FIRST_DUMMY + 15)
-#define EL_DYNABOMB_PLAYER_3 (EL_FIRST_DUMMY + 16)
-#define EL_DYNABOMB_PLAYER_4 (EL_FIRST_DUMMY + 17)
-#define EL_SHIELD_NORMAL_ACTIVE (EL_FIRST_DUMMY + 18)
-#define EL_SHIELD_DEADLY_ACTIVE (EL_FIRST_DUMMY + 19)
-#define EL_AMOEBA (EL_FIRST_DUMMY + 20)
-#define EL_DEFAULT (EL_FIRST_DUMMY + 21)
-#define EL_BD_DEFAULT (EL_FIRST_DUMMY + 22)
-#define EL_SP_DEFAULT (EL_FIRST_DUMMY + 23)
-#define EL_SB_DEFAULT (EL_FIRST_DUMMY + 24)
+#define EL_STEELWALL_TOPLEFT (EL_FIRST_DUMMY + 0)
+#define EL_STEELWALL_TOPRIGHT (EL_FIRST_DUMMY + 1)
+#define EL_STEELWALL_BOTTOMLEFT (EL_FIRST_DUMMY + 2)
+#define EL_STEELWALL_BOTTOMRIGHT (EL_FIRST_DUMMY + 3)
+#define EL_STEELWALL_HORIZONTAL (EL_FIRST_DUMMY + 4)
+#define EL_STEELWALL_VERTICAL (EL_FIRST_DUMMY + 5)
+#define EL_INVISIBLE_STEELWALL_TOPLEFT (EL_FIRST_DUMMY + 6)
+#define EL_INVISIBLE_STEELWALL_TOPRIGHT (EL_FIRST_DUMMY + 7)
+#define EL_INVISIBLE_STEELWALL_BOTTOMLEFT (EL_FIRST_DUMMY + 8)
+#define EL_INVISIBLE_STEELWALL_BOTTOMRIGHT (EL_FIRST_DUMMY + 9)
+#define EL_INVISIBLE_STEELWALL_HORIZONTAL (EL_FIRST_DUMMY + 10)
+#define EL_INVISIBLE_STEELWALL_VERTICAL (EL_FIRST_DUMMY + 11)
+#define EL_DYNABOMB (EL_FIRST_DUMMY + 12)
+#define EL_DYNABOMB_ACTIVE (EL_FIRST_DUMMY + 13)
+#define EL_DYNABOMB_PLAYER_1 (EL_FIRST_DUMMY + 14)
+#define EL_DYNABOMB_PLAYER_2 (EL_FIRST_DUMMY + 15)
+#define EL_DYNABOMB_PLAYER_3 (EL_FIRST_DUMMY + 16)
+#define EL_DYNABOMB_PLAYER_4 (EL_FIRST_DUMMY + 17)
+#define EL_SHIELD_NORMAL_ACTIVE (EL_FIRST_DUMMY + 18)
+#define EL_SHIELD_DEADLY_ACTIVE (EL_FIRST_DUMMY + 19)
+#define EL_AMOEBA (EL_FIRST_DUMMY + 20)
+#define EL_DEFAULT (EL_FIRST_DUMMY + 21)
+#define EL_BD_DEFAULT (EL_FIRST_DUMMY + 22)
+#define EL_SP_DEFAULT (EL_FIRST_DUMMY + 23)
+#define EL_SB_DEFAULT (EL_FIRST_DUMMY + 24)
/* internal elements (only used for internal purposes like copying) */
-#define EL_FIRST_INTERNAL (EL_FIRST_DUMMY + 25)
+#define EL_FIRST_INTERNAL (EL_FIRST_DUMMY + 25)
-#define EL_INTERNAL_CLIPBOARD_CUSTOM (EL_FIRST_INTERNAL + 0)
-#define EL_INTERNAL_CLIPBOARD_CHANGE (EL_FIRST_INTERNAL + 1)
-#define EL_INTERNAL_CLIPBOARD_GROUP (EL_FIRST_INTERNAL + 2)
-#define EL_INTERNAL_DUMMY (EL_FIRST_INTERNAL + 3)
+#define EL_INTERNAL_CLIPBOARD_CUSTOM (EL_FIRST_INTERNAL + 0)
+#define EL_INTERNAL_CLIPBOARD_CHANGE (EL_FIRST_INTERNAL + 1)
+#define EL_INTERNAL_CLIPBOARD_GROUP (EL_FIRST_INTERNAL + 2)
+#define EL_INTERNAL_DUMMY (EL_FIRST_INTERNAL + 3)
-#define EL_INTERNAL_CLIPBOARD_START (EL_FIRST_INTERNAL + 0)
-#define EL_INTERNAL_CLIPBOARD_END (EL_FIRST_INTERNAL + 2)
-#define EL_INTERNAL_START (EL_FIRST_INTERNAL + 0)
-#define EL_INTERNAL_END (EL_FIRST_INTERNAL + 3)
+#define EL_INTERNAL_CLIPBOARD_START (EL_FIRST_INTERNAL + 0)
+#define EL_INTERNAL_CLIPBOARD_END (EL_FIRST_INTERNAL + 2)
+#define EL_INTERNAL_START (EL_FIRST_INTERNAL + 0)
+#define EL_INTERNAL_END (EL_FIRST_INTERNAL + 3)
-#define MAX_NUM_ELEMENTS (EL_FIRST_INTERNAL + 4)
+#define MAX_NUM_ELEMENTS (EL_FIRST_INTERNAL + 4)
/* values for graphics/sounds action types */
-#define ACTION_DEFAULT 0
-#define ACTION_WAITING 1
-#define ACTION_FALLING 2
-#define ACTION_MOVING 3
-#define ACTION_DIGGING 4
-#define ACTION_SNAPPING 5
-#define ACTION_COLLECTING 6
-#define ACTION_DROPPING 7
-#define ACTION_PUSHING 8
-#define ACTION_WALKING 9
-#define ACTION_PASSING 10
-#define ACTION_IMPACT 11
-#define ACTION_BREAKING 12
-#define ACTION_ACTIVATING 13
-#define ACTION_DEACTIVATING 14
-#define ACTION_OPENING 15
-#define ACTION_CLOSING 16
-#define ACTION_ATTACKING 17
-#define ACTION_GROWING 18
-#define ACTION_SHRINKING 19
-#define ACTION_ACTIVE 20
-#define ACTION_FILLING 21
-#define ACTION_EMPTYING 22
-#define ACTION_CHANGING 23
-#define ACTION_EXPLODING 24
-#define ACTION_BORING 25
-#define ACTION_BORING_1 26
-#define ACTION_BORING_2 27
-#define ACTION_BORING_3 28
-#define ACTION_BORING_4 29
-#define ACTION_BORING_5 30
-#define ACTION_BORING_6 31
-#define ACTION_BORING_7 32
-#define ACTION_BORING_8 33
-#define ACTION_BORING_9 34
-#define ACTION_BORING_10 35
-#define ACTION_SLEEPING 36
-#define ACTION_SLEEPING_1 37
-#define ACTION_SLEEPING_2 38
-#define ACTION_SLEEPING_3 39
-#define ACTION_AWAKENING 40
-#define ACTION_DYING 41
-#define ACTION_TURNING 42
-#define ACTION_TURNING_FROM_LEFT 43
-#define ACTION_TURNING_FROM_RIGHT 44
-#define ACTION_TURNING_FROM_UP 45
-#define ACTION_TURNING_FROM_DOWN 46
-#define ACTION_OTHER 47
-
-#define NUM_ACTIONS 48
-
-#define ACTION_BORING_LAST ACTION_BORING_10
-#define ACTION_SLEEPING_LAST ACTION_SLEEPING_3
+#define ACTION_DEFAULT 0
+#define ACTION_WAITING 1
+#define ACTION_FALLING 2
+#define ACTION_MOVING 3
+#define ACTION_DIGGING 4
+#define ACTION_SNAPPING 5
+#define ACTION_COLLECTING 6
+#define ACTION_DROPPING 7
+#define ACTION_PUSHING 8
+#define ACTION_WALKING 9
+#define ACTION_PASSING 10
+#define ACTION_IMPACT 11
+#define ACTION_BREAKING 12
+#define ACTION_ACTIVATING 13
+#define ACTION_DEACTIVATING 14
+#define ACTION_OPENING 15
+#define ACTION_CLOSING 16
+#define ACTION_ATTACKING 17
+#define ACTION_GROWING 18
+#define ACTION_SHRINKING 19
+#define ACTION_ACTIVE 20
+#define ACTION_FILLING 21
+#define ACTION_EMPTYING 22
+#define ACTION_CHANGING 23
+#define ACTION_EXPLODING 24
+#define ACTION_BORING 25
+#define ACTION_BORING_1 26
+#define ACTION_BORING_2 27
+#define ACTION_BORING_3 28
+#define ACTION_BORING_4 29
+#define ACTION_BORING_5 30
+#define ACTION_BORING_6 31
+#define ACTION_BORING_7 32
+#define ACTION_BORING_8 33
+#define ACTION_BORING_9 34
+#define ACTION_BORING_10 35
+#define ACTION_SLEEPING 36
+#define ACTION_SLEEPING_1 37
+#define ACTION_SLEEPING_2 38
+#define ACTION_SLEEPING_3 39
+#define ACTION_AWAKENING 40
+#define ACTION_DYING 41
+#define ACTION_TURNING 42
+#define ACTION_TURNING_FROM_LEFT 43
+#define ACTION_TURNING_FROM_RIGHT 44
+#define ACTION_TURNING_FROM_UP 45
+#define ACTION_TURNING_FROM_DOWN 46
+#define ACTION_SMASHED_BY_ROCK 47
+#define ACTION_SMASHED_BY_SPRING 48
+#define ACTION_SLURPED_BY_SPRING 49
+#define ACTION_TWINKLING 50
+#define ACTION_SPLASHING 51
+#define ACTION_OTHER 52
+
+#define NUM_ACTIONS 53
+
+#define ACTION_BORING_LAST ACTION_BORING_10
+#define ACTION_SLEEPING_LAST ACTION_SLEEPING_3
/* values for special image configuration suffixes (must match game mode) */
-#define GFX_SPECIAL_ARG_DEFAULT 0
-#define GFX_SPECIAL_ARG_MAIN 1
-#define GFX_SPECIAL_ARG_LEVELS 2
-#define GFX_SPECIAL_ARG_SCORES 3
-#define GFX_SPECIAL_ARG_EDITOR 4
-#define GFX_SPECIAL_ARG_INFO 5
-#define GFX_SPECIAL_ARG_SETUP 6
-#define GFX_SPECIAL_ARG_PLAYING 7
-#define GFX_SPECIAL_ARG_DOOR 8
-#define GFX_SPECIAL_ARG_PREVIEW 9
-#define GFX_SPECIAL_ARG_CRUMBLED 10
+#define GFX_SPECIAL_ARG_DEFAULT 0
+#define GFX_SPECIAL_ARG_MAIN 1
+#define GFX_SPECIAL_ARG_LEVELS 2
+#define GFX_SPECIAL_ARG_SCORES 3
+#define GFX_SPECIAL_ARG_EDITOR 4
+#define GFX_SPECIAL_ARG_INFO 5
+#define GFX_SPECIAL_ARG_SETUP 6
+#define GFX_SPECIAL_ARG_PLAYING 7
+#define GFX_SPECIAL_ARG_DOOR 8
+#define GFX_SPECIAL_ARG_PREVIEW 9
+#define GFX_SPECIAL_ARG_CRUMBLED 10
-#define NUM_SPECIAL_GFX_ARGS 11
+#define NUM_SPECIAL_GFX_ARGS 11
/* values for image configuration suffixes */
-#define GFX_ARG_X 0
-#define GFX_ARG_Y 1
-#define GFX_ARG_XPOS 2
-#define GFX_ARG_YPOS 3
-#define GFX_ARG_WIDTH 4
-#define GFX_ARG_HEIGHT 5
-#define GFX_ARG_OFFSET 6
-#define GFX_ARG_VERTICAL 7
-#define GFX_ARG_XOFFSET 8
-#define GFX_ARG_YOFFSET 9
-#define GFX_ARG_FRAMES 10
-#define GFX_ARG_FRAMES_PER_LINE 11
-#define GFX_ARG_START_FRAME 12
-#define GFX_ARG_DELAY 13
-#define GFX_ARG_ANIM_MODE 14
-#define GFX_ARG_GLOBAL_SYNC 15
-#define GFX_ARG_CRUMBLED_LIKE 16
-#define GFX_ARG_DIGGABLE_LIKE 17
-#define GFX_ARG_BORDER_SIZE 18
-#define GFX_ARG_STEP_OFFSET 19
-#define GFX_ARG_STEP_DELAY 20
-#define GFX_ARG_DIRECTION 21
-#define GFX_ARG_POSITION 22
-#define GFX_ARG_DRAW_XOFFSET 23
-#define GFX_ARG_DRAW_YOFFSET 24
-#define GFX_ARG_DRAW_MASKED 25
-#define GFX_ARG_ANIM_DELAY_FIXED 26
-#define GFX_ARG_ANIM_DELAY_RANDOM 27
-#define GFX_ARG_POST_DELAY_FIXED 28
-#define GFX_ARG_POST_DELAY_RANDOM 29
-#define GFX_ARG_NAME 30
-
-#define NUM_GFX_ARGS 31
+#define GFX_ARG_X 0
+#define GFX_ARG_Y 1
+#define GFX_ARG_XPOS 2
+#define GFX_ARG_YPOS 3
+#define GFX_ARG_WIDTH 4
+#define GFX_ARG_HEIGHT 5
+#define GFX_ARG_VERTICAL 6
+#define GFX_ARG_OFFSET 7
+#define GFX_ARG_XOFFSET 8
+#define GFX_ARG_YOFFSET 9
+#define GFX_ARG_2ND_MOVEMENT_TILE 10
+#define GFX_ARG_2ND_VERTICAL 11
+#define GFX_ARG_2ND_OFFSET 12
+#define GFX_ARG_2ND_XOFFSET 13
+#define GFX_ARG_2ND_YOFFSET 14
+#define GFX_ARG_2ND_SWAP_TILES 15
+#define GFX_ARG_FRAMES 16
+#define GFX_ARG_FRAMES_PER_LINE 17
+#define GFX_ARG_START_FRAME 18
+#define GFX_ARG_DELAY 19
+#define GFX_ARG_ANIM_MODE 20
+#define GFX_ARG_GLOBAL_SYNC 21
+#define GFX_ARG_CRUMBLED_LIKE 22
+#define GFX_ARG_DIGGABLE_LIKE 23
+#define GFX_ARG_BORDER_SIZE 24
+#define GFX_ARG_STEP_OFFSET 25
+#define GFX_ARG_STEP_DELAY 26
+#define GFX_ARG_DIRECTION 27
+#define GFX_ARG_POSITION 28
+#define GFX_ARG_DRAW_XOFFSET 29
+#define GFX_ARG_DRAW_YOFFSET 30
+#define GFX_ARG_DRAW_MASKED 31
+#define GFX_ARG_ANIM_DELAY_FIXED 32
+#define GFX_ARG_ANIM_DELAY_RANDOM 33
+#define GFX_ARG_POST_DELAY_FIXED 34
+#define GFX_ARG_POST_DELAY_RANDOM 35
+#define GFX_ARG_NAME 36
+#define GFX_ARG_SCALE_UP_FACTOR 37
+
+#define NUM_GFX_ARGS 38
/* values for sound configuration suffixes */
-#define SND_ARG_MODE_LOOP 0
+#define SND_ARG_MODE_LOOP 0
+#define SND_ARG_VOLUME 1
+#define SND_ARG_PRIORITY 2
-#define NUM_SND_ARGS 1
+#define NUM_SND_ARGS 3
/* values for music configuration suffixes */
-#define MUS_ARG_MODE_LOOP 0
+#define MUS_ARG_MODE_LOOP 0
-#define NUM_MUS_ARGS 1
+#define NUM_MUS_ARGS 1
/* values for font configuration */
-#define FONT_INITIAL_1 0
-#define FONT_INITIAL_2 1
-#define FONT_INITIAL_3 2
-#define FONT_INITIAL_4 3
-#define FONT_TITLE_1 4
-#define FONT_TITLE_2 5
-#define FONT_MENU_1 6
-#define FONT_MENU_2 7
-#define FONT_TEXT_1_ACTIVE 8
-#define FONT_TEXT_2_ACTIVE 9
-#define FONT_TEXT_3_ACTIVE 10
-#define FONT_TEXT_4_ACTIVE 11
-#define FONT_TEXT_1 12
-#define FONT_TEXT_2 13
-#define FONT_TEXT_3 14
-#define FONT_TEXT_4 15
-#define FONT_ENVELOPE_1 16
-#define FONT_ENVELOPE_2 17
-#define FONT_ENVELOPE_3 18
-#define FONT_ENVELOPE_4 19
-#define FONT_INPUT_1_ACTIVE 20
-#define FONT_INPUT_2_ACTIVE 21
-#define FONT_INPUT_1 22
-#define FONT_INPUT_2 23
-#define FONT_OPTION_OFF 24
-#define FONT_OPTION_ON 25
-#define FONT_VALUE_1 26
-#define FONT_VALUE_2 27
-#define FONT_VALUE_OLD 28
-#define FONT_LEVEL_NUMBER 29
-#define FONT_TAPE_RECORDER 30
-#define FONT_GAME_INFO 31
-
-#define NUM_FONTS 32
-#define NUM_INITIAL_FONTS 4
+#define FONT_INITIAL_1 0
+#define FONT_INITIAL_2 1
+#define FONT_INITIAL_3 2
+#define FONT_INITIAL_4 3
+#define FONT_TITLE_1 4
+#define FONT_TITLE_2 5
+#define FONT_MENU_1 6
+#define FONT_MENU_2 7
+#define FONT_TEXT_1_ACTIVE 8
+#define FONT_TEXT_2_ACTIVE 9
+#define FONT_TEXT_3_ACTIVE 10
+#define FONT_TEXT_4_ACTIVE 11
+#define FONT_TEXT_1 12
+#define FONT_TEXT_2 13
+#define FONT_TEXT_3 14
+#define FONT_TEXT_4 15
+#define FONT_ENVELOPE_1 16
+#define FONT_ENVELOPE_2 17
+#define FONT_ENVELOPE_3 18
+#define FONT_ENVELOPE_4 19
+#define FONT_INPUT_1_ACTIVE 20
+#define FONT_INPUT_2_ACTIVE 21
+#define FONT_INPUT_1 22
+#define FONT_INPUT_2 23
+#define FONT_OPTION_OFF 24
+#define FONT_OPTION_ON 25
+#define FONT_VALUE_1 26
+#define FONT_VALUE_2 27
+#define FONT_VALUE_OLD 28
+#define FONT_LEVEL_NUMBER 29
+#define FONT_TAPE_RECORDER 30
+#define FONT_GAME_INFO 31
+
+#define NUM_FONTS 32
+#define NUM_INITIAL_FONTS 4
/* values for game_status (must match special image configuration suffixes) */
-#define GAME_MODE_DEFAULT 0
-#define GAME_MODE_MAIN 1
-#define GAME_MODE_LEVELS 2
-#define GAME_MODE_SCORES 3
-#define GAME_MODE_EDITOR 4
-#define GAME_MODE_INFO 5
-#define GAME_MODE_SETUP 6
-#define GAME_MODE_PLAYING 7
-#define GAME_MODE_PSEUDO_DOOR 8
-#define GAME_MODE_PSEUDO_PREVIEW 9
-#define GAME_MODE_PSEUDO_CRUMBLED 10
+#define GAME_MODE_DEFAULT 0
+#define GAME_MODE_MAIN 1
+#define GAME_MODE_LEVELS 2
+#define GAME_MODE_SCORES 3
+#define GAME_MODE_EDITOR 4
+#define GAME_MODE_INFO 5
+#define GAME_MODE_SETUP 6
+#define GAME_MODE_PLAYING 7
+#define GAME_MODE_PSEUDO_DOOR 8
+#define GAME_MODE_PSEUDO_PREVIEW 9
+#define GAME_MODE_PSEUDO_CRUMBLED 10
/* there are no special config file suffixes for these modes */
-#define GAME_MODE_PSEUDO_TYPENAME 11
-#define GAME_MODE_QUIT 12
+#define GAME_MODE_PSEUDO_TYPENAME 11
+#define GAME_MODE_QUIT 12
/* special definitions currently only used for custom artwork configuration */
-#define MUSIC_PREFIX_BACKGROUND 0
-#define NUM_MUSIC_PREFIXES 1
-#define MAX_LEVELS 1000
+#define MUSIC_PREFIX_BACKGROUND 0
+#define NUM_MUSIC_PREFIXES 1
+#define MAX_LEVELS 1000
/* definitions for demo animation lists */
-#define HELPANIM_LIST_NEXT -1
-#define HELPANIM_LIST_END -999
+#define HELPANIM_LIST_NEXT -1
+#define HELPANIM_LIST_END -999
/* program information and versioning definitions */
-#define PROGRAM_VERSION_MAJOR 3
-#define PROGRAM_VERSION_MINOR 1
-#define PROGRAM_VERSION_PATCH 0
-#define PROGRAM_VERSION_BUILD 5
+#define RELEASE_311 TRUE
+
+#if RELEASE_311
+#define PROGRAM_VERSION_MAJOR 3
+#define PROGRAM_VERSION_MINOR 1
+#define PROGRAM_VERSION_PATCH 1
+#define PROGRAM_VERSION_BUILD 0
+#else
+/* !!! make sure that packaging script can find unique version number !!! */
+#define X_PROGRAM_VERSION_MAJOR 3
+#define X_PROGRAM_VERSION_MINOR 2
+#define X_PROGRAM_VERSION_PATCH 0
+#define X_PROGRAM_VERSION_BUILD 3
+#endif
-#define PROGRAM_TITLE_STRING "Rocks'n'Diamonds"
-#define PROGRAM_AUTHOR_STRING "Holger Schemel"
-#define PROGRAM_COPYRIGHT_STRING "Copyright ©1995-2004 by Holger Schemel"
+#define PROGRAM_TITLE_STRING "Rocks'n'Diamonds"
+#define PROGRAM_AUTHOR_STRING "Holger Schemel"
+#define PROGRAM_COPYRIGHT_STRING "Copyright ©1995-2005 by Holger Schemel"
-#define ICON_TITLE_STRING PROGRAM_TITLE_STRING
-#define COOKIE_PREFIX "ROCKSNDIAMONDS"
-#define FILENAME_PREFIX "Rocks"
+#define ICON_TITLE_STRING PROGRAM_TITLE_STRING
+#define COOKIE_PREFIX "ROCKSNDIAMONDS"
+#define FILENAME_PREFIX "Rocks"
#if defined(PLATFORM_UNIX)
-#define USERDATA_DIRECTORY ".rocksndiamonds"
+#define USERDATA_DIRECTORY ".rocksndiamonds"
#elif defined(PLATFORM_WIN32)
-#define USERDATA_DIRECTORY PROGRAM_TITLE_STRING
+#define USERDATA_DIRECTORY PROGRAM_TITLE_STRING
#else
-#define USERDATA_DIRECTORY "userdata"
+#define USERDATA_DIRECTORY "userdata"
#endif
-#define X11_ICON_FILENAME "rocks_icon.xbm"
-#define X11_ICONMASK_FILENAME "rocks_iconmask.xbm"
-#define MSDOS_POINTER_FILENAME "mouse.pcx"
+#define X11_ICON_FILENAME "rocks_icon.xbm"
+#define X11_ICONMASK_FILENAME "rocks_iconmask.xbm"
+#define MSDOS_POINTER_FILENAME "mouse.pcx"
/* file version numbers for resource files (levels, tapes, score, setup, etc.)
** currently supported/known file version numbers:
** 1.4 (still in use)
** 2.0 (actual)
*/
-#define FILE_VERSION_1_0 VERSION_IDENT(1,0,0,0)
-#define FILE_VERSION_1_2 VERSION_IDENT(1,2,0,0)
-#define FILE_VERSION_1_4 VERSION_IDENT(1,4,0,0)
-#define FILE_VERSION_2_0 VERSION_IDENT(2,0,0,0)
+#define FILE_VERSION_1_0 VERSION_IDENT(1,0,0,0)
+#define FILE_VERSION_1_2 VERSION_IDENT(1,2,0,0)
+#define FILE_VERSION_1_4 VERSION_IDENT(1,4,0,0)
+#define FILE_VERSION_2_0 VERSION_IDENT(2,0,0,0)
/* file version does not change for every program version, but is changed
when new features are introduced that are incompatible with older file
versions, so that they can be treated accordingly */
-#define FILE_VERSION_ACTUAL FILE_VERSION_2_0
+#define FILE_VERSION_ACTUAL FILE_VERSION_2_0
-#define GAME_VERSION_1_0 FILE_VERSION_1_0
-#define GAME_VERSION_1_2 FILE_VERSION_1_2
-#define GAME_VERSION_1_4 FILE_VERSION_1_4
-#define GAME_VERSION_2_0 FILE_VERSION_2_0
+#define GAME_VERSION_1_0 FILE_VERSION_1_0
+#define GAME_VERSION_1_2 FILE_VERSION_1_2
+#define GAME_VERSION_1_4 FILE_VERSION_1_4
+#define GAME_VERSION_2_0 FILE_VERSION_2_0
-#define GAME_VERSION_ACTUAL VERSION_IDENT(PROGRAM_VERSION_MAJOR, \
- PROGRAM_VERSION_MINOR, \
- PROGRAM_VERSION_PATCH, \
- PROGRAM_VERSION_BUILD)
+#define GAME_VERSION_ACTUAL VERSION_IDENT(PROGRAM_VERSION_MAJOR, \
+ PROGRAM_VERSION_MINOR, \
+ PROGRAM_VERSION_PATCH, \
+ PROGRAM_VERSION_BUILD)
/* values for game_emulation */
-#define EMU_NONE 0
-#define EMU_BOULDERDASH 1
-#define EMU_SOKOBAN 2
-#define EMU_SUPAPLEX 3
+#define EMU_NONE 0
+#define EMU_BOULDERDASH 1
+#define EMU_SOKOBAN 2
+#define EMU_SUPAPLEX 3
+
+/* values for level file type identifier */
+#define LEVEL_FILE_TYPE_UNKNOWN 0
+#define LEVEL_FILE_TYPE_RND 1
+#define LEVEL_FILE_TYPE_BD 2
+#define LEVEL_FILE_TYPE_EM 3
+#define LEVEL_FILE_TYPE_SP 4
+#define LEVEL_FILE_TYPE_DX 5
+#define LEVEL_FILE_TYPE_SB 6
+#define LEVEL_FILE_TYPE_DC 7
+
+#define NUM_LEVEL_FILE_TYPES 8
+
+/* values for game engine type identifier */
+#define GAME_ENGINE_TYPE_UNKNOWN LEVEL_FILE_TYPE_UNKNOWN
+#define GAME_ENGINE_TYPE_RND LEVEL_FILE_TYPE_RND
+#define GAME_ENGINE_TYPE_EM LEVEL_FILE_TYPE_EM
+
+#define NUM_ENGINE_TYPES 3
+
struct MenuInfo
{
- int draw_xoffset_default;
- int draw_yoffset_default;
int draw_xoffset[NUM_SPECIAL_GFX_ARGS];
int draw_yoffset[NUM_SPECIAL_GFX_ARGS];
int scrollbar_xoffset;
- int list_size_default;
int list_size[NUM_SPECIAL_GFX_ARGS];
int sound[NUM_SPECIAL_GFX_ARGS];
boolean use_murphy_graphic;
boolean block_last_field;
+ int block_delay_adjustment; /* needed for different engine versions */
+
boolean can_fall_into_acid;
boolean LevelSolved, GameOver;
int num_special_action_sleeping;
int switch_x, switch_y;
+ int drop_x, drop_y;
int show_envelope;
+#if 1 /* USE_NEW_MOVE_DELAY */
+ int move_delay;
+ int move_delay_value;
+#else
unsigned long move_delay;
int move_delay_value;
+#endif
int move_delay_reset_counter;
+#if 1 /* USE_NEW_PUSH_DELAY */
+ int push_delay;
+ int push_delay_value;
+#else
unsigned long push_delay;
unsigned long push_delay_value;
+#endif
unsigned long actual_frame_counter;
int sokobanfields_still_needed;
int lights_still_needed;
int friends_still_needed;
- int key[4];
+ int key[MAX_NUM_KEYS];
int dynabomb_count, dynabomb_size, dynabombs_left, dynabomb_xl;
int shield_normal_time_left;
int shield_deadly_time_left;
struct LevelInfo
{
+ struct LevelFileInfo file_info;
+
+ int game_engine_type;
+
+ /* level stored in native format for the alternative native game engines */
+ struct LevelInfo_EM *native_em_level;
+
int file_version; /* file format version the level is stored with */
int game_version; /* game release version the level was created with */
int fieldx, fieldy;
- int time;
+ int time; /* available time (seconds) */
int gems_needed;
char name[MAX_LEVEL_NAME_LEN + 1];
int time_light;
int time_timegate;
+ /* values for the new EMC elements */
+ int android_move_time;
+ int android_clone_time;
+ boolean ball_random;
+ boolean ball_state_initial;
+ int ball_time;
+ int lenses_score;
+ int magnify_score;
+ int slurp_score;
+ int lenses_time;
+ int magnify_time;
+ int wind_direction_initial;
+ int ball_content[NUM_MAGIC_BALL_CONTENTS][3][3];
+ boolean android_array[16];
+
int can_move_into_acid_bits; /* bitfield to store property for elements */
int dont_collide_with_bits; /* bitfield to store property for elements */
boolean double_speed;
boolean initial_gravity;
boolean em_slippery_gems; /* EM style "gems slip from wall" behaviour */
- boolean block_last_field; /* player blocks previous field while moving */
- boolean sp_block_last_field; /* player blocks previous field while moving */
boolean use_spring_bug; /* for compatibility with old levels */
boolean instant_relocation; /* no visual delay when relocating player */
boolean can_pass_to_walkable; /* player can pass to empty or walkable tile */
boolean grow_into_diggable; /* amoeba can grow into anything diggable */
+ boolean block_last_field; /* player blocks previous field while moving */
+ boolean sp_block_last_field; /* player blocks previous field while moving */
+
+#if 0 /* !!! THIS IS NOT A LEVEL SETTING => LOGIC MOVED TO "game.c" !!! */
+ int block_delay; /* delay for blocking previous field */
+ int sp_block_delay; /* delay for blocking previous field */
+#endif
+
/* ('int' instead of 'boolean' because used as selectbox value in editor) */
int use_step_counter; /* count steps instead of seconds for level */
boolean use_custom_template; /* use custom properties from template file */
boolean no_valid_file; /* set when level file missing or invalid */
+
+ boolean changed; /* set when level was changed in the editor */
};
struct TapeInfo
{
byte action[MAX_PLAYERS];
byte delay;
- } pos[MAX_TAPELEN];
+ } pos[MAX_TAPE_LEN];
boolean no_valid_file; /* set when tape file missing or invalid */
};
int initial_move_delay_value;
int initial_push_delay_value;
+ /* flags to handle bugs in and changes between different engine versions */
+ /* (for the latest engine version, these flags should always be "FALSE") */
+ boolean use_change_when_pushing_bug;
+ boolean use_block_last_field_bug;
+
/* variable within running game */
int yamyam_content_nr;
boolean magic_wall_active;
struct GlobalInfo
{
char *autoplay_leveldir;
- int autoplay_level_nr;
+ int autoplay_level[MAX_TAPES_PER_SET];
+ boolean autoplay_all;
char *convert_leveldir;
int convert_level_nr;
{
boolean can_change; /* use or ignore this change info */
+#if 1
+ boolean has_event[NUM_CHANGE_EVENTS]; /* change events */
+#else
unsigned long events; /* change events */
+#endif
int trigger_player; /* player triggering change */
int trigger_side; /* side triggering change */
int choice_pos; /* current element choice position */
};
+struct ElementNameInfo
+{
+ /* ---------- token and description strings ---------- */
+
+ char *token_name; /* element token used in config files */
+ char *class_name; /* element class used in config files */
+ char *editor_description; /* pre-defined description for level editor */
+};
+
struct ElementInfo
{
/* ---------- token and description strings ---------- */
/* ---------- internal values used at runtime when playing ---------- */
+#if 1
+ boolean has_change_event[NUM_CHANGE_EVENTS];
+#else
unsigned long change_events; /* bitfield for combined change events */
+#endif
int event_page_nr[NUM_CHANGE_EVENTS]; /* page number for each event */
struct ElementChangeInfo *event_page[NUM_CHANGE_EVENTS]; /* page for event */
int src_x, src_y; /* start position of animation frames */
int width, height; /* width/height of each animation frame */
int offset_x, offset_y; /* x/y offset to next animation frame */
+ int offset2_x, offset2_y; /* x/y offset to second movement tile */
+ boolean double_movement; /* animation has second movement tile */
+ int swap_double_tiles; /* explicitely force or forbid tile swapping */
int anim_frames;
int anim_frames_per_line;
int anim_start_frame;
int crumbled_like; /* element for cloning crumble graphics */
int diggable_like; /* element for cloning digging graphics */
int border_size; /* border size for "crumbled" graphics */
+ int scale_up_factor; /* optional factor for scaling image up */
int anim_delay_fixed; /* optional delay values for bored and */
int anim_delay_random; /* sleeping player animations (animation */
struct SoundInfo
{
boolean loop;
+ int volume;
+ int priority;
};
struct MusicInfo
extern short Back[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern boolean Pushed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern unsigned long Changed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern unsigned long ChangeEvent[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern boolean Changed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short ChangeEvent[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern short WasJustMoving[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern short WasJustFalling[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern short CheckCollision[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern struct MenuInfo menu;
extern struct DoorInfo door_1, door_2;
extern struct ElementInfo element_info[];
+extern struct ElementNameInfo element_name_info[];
extern struct ElementActionInfo element_action_info[];
extern struct ElementDirectionInfo element_direction_info[];
extern struct SpecialSuffixInfo special_suffix_info[];
extern struct MusicFileInfo *music_file_info;
extern struct HelpAnimInfo *helpanim_info;
extern SetupFileHash *helptext_info;
+extern struct ConfigTypeInfo image_config_suffix[];
+extern struct ConfigTypeInfo sound_config_suffix[];
+extern struct ConfigTypeInfo music_config_suffix[];
extern struct ConfigInfo image_config[];
extern struct ConfigInfo sound_config[];
extern struct ConfigInfo music_config[];
-extern struct ConfigInfo image_config_suffix[];
-extern struct ConfigInfo sound_config_suffix[];
-extern struct ConfigInfo music_config_suffix[];
extern struct ConfigInfo helpanim_config[];
extern struct ConfigInfo helptext_config[];
static int setup_mode = SETUP_MODE_MAIN;
static int info_mode = INFO_MODE_MAIN;
-#define mSX (SX + (game_status >= GAME_MODE_MAIN && \
- game_status <= GAME_MODE_SETUP ? \
- menu.draw_xoffset[game_status] : menu.draw_xoffset_default))
-#define mSY (SY + (game_status >= GAME_MODE_MAIN && \
- game_status <= GAME_MODE_SETUP ? \
- menu.draw_yoffset[game_status] : menu.draw_yoffset_default))
+#define DRAW_OFFSET_MODE(x) (x >= GAME_MODE_MAIN && \
+ x <= GAME_MODE_SETUP ? x : \
+ x == GAME_MODE_PSEUDO_TYPENAME ? \
+ GAME_MODE_MAIN : GAME_MODE_DEFAULT)
+
+#define mSX (SX + menu.draw_xoffset[DRAW_OFFSET_MODE(game_status)])
+#define mSY (SY + menu.draw_yoffset[DRAW_OFFSET_MODE(game_status)])
#define NUM_MENU_ENTRIES_ON_SCREEN (menu.list_size[game_status] > 2 ? \
menu.list_size[game_status] : \
DrawText(mSX + level_width + 5 * 32, mSY + 3*32, int2str(level_nr,3),
FONT_VALUE_1);
- DrawMicroLevel(MICROLEV_XPOS, MICROLEV_YPOS, TRUE);
+ DrawMicroLevel(MICROLEVEL_XPOS, MICROLEVEL_YPOS, TRUE);
DrawTextF(mSX + 32 + level_width - 2, mSY + 3*32 + 1, FONT_TEXT_3, "%d-%d",
leveldir_current->first_level, leveldir_current->last_level);
OpenDoor(DOOR_CLOSE_1 | DOOR_OPEN_2);
}
+#if 0
static void gotoTopLevelDir()
{
/* move upwards to top level directory */
leveldir_current = leveldir_current->node_parent;
}
}
+#endif
void HandleMainMenu(int mx, int my, int dx, int dy, int button)
{
+ static unsigned long level_delay = 0;
static int choice = 5;
int x = 0;
int y = choice;
if (y == 1 && ((x == 10 && level_nr > leveldir_current->first_level) ||
(x == 14 && level_nr < leveldir_current->last_level)) &&
- button)
+ button && DelayReached(&level_delay, GADGET_FRAME_DELAY))
{
- static unsigned long level_delay = 0;
int step = (button == 1 ? 1 : button == 2 ? 5 : 10);
int old_level_nr = level_nr;
int new_level_nr;
if (new_level_nr > leveldir_current->last_level)
new_level_nr = leveldir_current->last_level;
+#if 1
if (setup.handicap && new_level_nr > leveldir_current->handicap_level)
+ {
+ /* skipping levels is only allowed when trying to skip single level */
+ if (setup.skip_levels && step == 1 &&
+ Request("Level still unsolved ! Skip despite handicap ?", REQ_ASK))
+ {
+ leveldir_current->handicap_level++;
+ SaveLevelSetup_SeriesInfo();
+ }
+
new_level_nr = leveldir_current->handicap_level;
+ }
+#else
+ if (setup.handicap && new_level_nr > leveldir_current->handicap_level)
+ new_level_nr = leveldir_current->handicap_level;
+#endif
- if (new_level_nr != old_level_nr &&
- DelayReached(&level_delay, GADGET_FRAME_DELAY))
+ if (new_level_nr != old_level_nr)
{
level_nr = new_level_nr;
FONT_VALUE_1);
LoadLevel(level_nr);
- DrawMicroLevel(MICROLEV_XPOS, MICROLEV_YPOS, TRUE);
+ DrawMicroLevel(MICROLEVEL_XPOS, MICROLEVEL_YPOS, TRUE);
TapeErase();
LoadTape(level_nr);
SaveLevelSetup_LastSeries();
SaveLevelSetup_SeriesInfo();
+#if 0
gotoTopLevelDir();
+#endif
DrawChooseLevel();
}
if (game_status == GAME_MODE_MAIN)
{
- DrawMicroLevel(MICROLEV_XPOS, MICROLEV_YPOS, FALSE);
+ DrawMicroLevel(MICROLEVEL_XPOS, MICROLEVEL_YPOS, FALSE);
DoAnimation();
}
}
int num_entries = numTreeInfoInGroup(ti);
int num_page_entries;
int last_game_status = game_status; /* save current game status */
+ boolean position_set_by_scrollbar = (dx == 999);
/* force LEVELS draw offset on choose level and artwork setup screen */
game_status = GAME_MODE_LEVELS;
ti->cl_cursor = entry_pos - ti->cl_first;
}
- if (dx == 999) /* first entry is set by scrollbar position */
+ if (position_set_by_scrollbar)
ti->cl_first = dy;
else
AdjustChooseTreeScrollbar(SCREEN_CTRL_ID_SCROLL_VERTICAL,
return;
}
- if (IN_VIS_FIELD(x, y) &&
+ if (!anyScrollbarGadgetActive() &&
+ IN_VIS_FIELD(x, y) &&
mx < screen_gadget[SCREEN_CTRL_ID_SCROLL_VERTICAL]->x &&
y >= 0 && y < num_page_entries)
{
{
{ TYPE_SWITCH, &setup.team_mode, "Team-Mode:" },
{ TYPE_SWITCH, &setup.handicap, "Handicap:" },
+ { TYPE_SWITCH, &setup.skip_levels, "Skip Levels:" },
{ TYPE_SWITCH, &setup.time_limit, "Timelimit:" },
{ TYPE_SWITCH, &setup.autorecord, "Auto-Record:" },
{ TYPE_EMPTY, NULL, "" },
#endif
{ TYPE_SWITCH, &setup.editor.el_boulderdash, "BoulderDash:" },
{ TYPE_SWITCH, &setup.editor.el_emerald_mine, "Emerald Mine:" },
+ { TYPE_SWITCH, &setup.editor.el_emerald_mine_club,"E.M. Club:" },
{ TYPE_SWITCH, &setup.editor.el_more, "More:" },
{ TYPE_SWITCH, &setup.editor.el_sokoban, "Sokoban:" },
{ TYPE_SWITCH, &setup.editor.el_supaplex, "Supaplex:" },
if (game_status != GAME_MODE_PLAYING)
return;
- if (local_player->LevelSolved)
- GameWon();
+ /* !!! FIX THIS (START) !!! */
+ if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ {
+ byte *recorded_player_action;
+ byte summarized_player_action = 0;
+ byte tape_action[MAX_PLAYERS];
+ int i;
- if (AllPlayersGone && !TAPE_IS_STOPPED(tape))
- TapeStop();
+ if (level.native_em_level->lev->home == 0) /* all players at home */
+ {
+ GameWon();
- GameActions();
- BackToFront();
+ if (!TAPE_IS_STOPPED(tape))
+ TapeStop();
+
+ if (game_status != GAME_MODE_PLAYING)
+ return;
+ }
+
+ if (level.native_em_level->ply1->alive == 0 &&
+ level.native_em_level->ply2->alive == 0) /* all dead */
+ AllPlayersGone = TRUE;
+
+ if (AllPlayersGone && !TAPE_IS_STOPPED(tape))
+ TapeStop();
+
+ /* --- game actions --- */
+
+ if (tape.pausing)
+ {
+ /* don't use 100% CPU while in pause mode -- this should better be solved
+ like in the R'n'D game engine! */
+
+ Delay(10);
+
+ return;
+ }
+
+ recorded_player_action = (tape.playing ? TapePlayAction() : NULL);
+
+#if 1
+ /* !!! CHECK THIS (tape.pausing is always FALSE here!) !!! */
+ if (recorded_player_action == NULL && tape.pausing)
+ return;
+#endif
- if (tape.auto_play && !tape.playing)
- AutoPlayTape(); /* continue automatically playing next tape */
+ for (i = 0; i < MAX_PLAYERS; i++)
+ {
+ summarized_player_action |= stored_player[i].action;
+
+ if (!network_playing)
+ stored_player[i].effective_action = stored_player[i].action;
+ }
+
+ if (!options.network && !setup.team_mode)
+ local_player->effective_action = summarized_player_action;
+
+ if (recorded_player_action != NULL)
+ for (i = 0; i < MAX_PLAYERS; i++)
+ stored_player[i].effective_action = recorded_player_action[i];
+
+ for (i = 0; i < MAX_PLAYERS; i++)
+ {
+ tape_action[i] = stored_player[i].effective_action;
+
+ /* !!! (this does not happen in the EM engine) !!! */
+ if (tape.recording && tape_action[i] && !tape.player_participates[i])
+ tape.player_participates[i] = TRUE; /* player just appeared from CE */
+ }
+
+ /* only save actions from input devices, but not programmed actions */
+ if (tape.recording)
+ TapeRecordAction(tape_action);
+
+ GameActions_EM(local_player->effective_action);
+
+ if (TimeFrames >= FRAMES_PER_SECOND)
+ {
+ TimeFrames = 0;
+ TapeTime++;
+
+ if (!level.use_step_counter)
+ {
+ TimePlayed++;
+
+ if (TimeLeft > 0)
+ {
+ TimeLeft--;
+
+ if (TimeLeft <= 10 && setup.time_limit)
+ PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MIDDLE);
+
+ DrawGameValue_Time(TimeLeft);
+
+ if (!TimeLeft && setup.time_limit)
+ level.native_em_level->lev->killed_out_of_time = TRUE;
+ }
+ else if (level.time == 0 && level.native_em_level->lev->home > 0)
+ DrawGameValue_Time(TimePlayed);
+
+ level.native_em_level->lev->time =
+ (level.time == 0 ? TimePlayed : TimeLeft);
+ }
+
+ if (tape.recording || tape.playing)
+ DrawVideoDisplay(VIDEO_STATE_TIME_ON, TapeTime);
+ }
+
+ FrameCounter++;
+ TimeFrames++;
+
+ BackToFront();
+ }
+ else
+ {
+ if (local_player->LevelSolved)
+ GameWon();
+
+ if (AllPlayersGone && !TAPE_IS_STOPPED(tape))
+ TapeStop();
+
+ GameActions();
+ BackToFront();
+
+ if (tape.auto_play && !tape.playing)
+ AutoPlayTape(); /* continue automatically playing next tape */
+ }
}
/* ---------- new screen button stuff -------------------------------------- */
void TapeStopRecording()
{
+#if 0
if (!tape.recording)
return;
+#endif
TapeHaltRecording();
return;
#endif
- if (tape.counter >= MAX_TAPELEN - 1)
+ if (tape.counter >= MAX_TAPE_LEN - 1)
{
TapeStopRecording();
return;
void TapeStopPlaying()
{
+#if 0
if (!tape.playing)
return;
+#endif
tape.playing = FALSE;
tape.pausing = FALSE;
if (!tape.playing || tape.pausing)
return NULL;
- if (tape.pause_before_death) /* STOP 10s BEFORE PLAYER GETS KILLED... */
+ if (tape.pause_before_death) /* stop 10 seconds before player gets killed */
{
if (!(FrameCounter % 20))
{
if (TapeTime > tape.length_seconds - TAPE_PAUSE_SECONDS_BEFORE_DEATH)
{
TapeTogglePause(TAPE_TOGGLE_MANUAL);
+
return NULL;
}
}
DrawVideoDisplay(VIDEO_STATE_WARP2_ON, VIDEO_DISPLAY_SYMBOL_ONLY);
}
}
+
#if 0
/* !!! this makes things much slower !!! */
else if (tape.warp_forward)
void TapeQuickLoad()
{
+ char *filename = getTapeFilename(level_nr);
+
+ if (!fileExists(filename))
+ {
+ Request("No tape for this level !", REQ_CONFIRM);
+
+ return;
+ }
+
if (tape.recording && !Request("Stop recording and load tape ?",
REQ_ASK | REQ_STAY_CLOSED))
{
- BlitBitmap(bitmap_db_door, bitmap_db_door,
- DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
- DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
- OpenDoor(DOOR_OPEN_1);
+ OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
return;
}
tape.quick_resume = TRUE;
}
- else
- Request("No tape for this level !", REQ_CONFIRM);
+ else /* this should not happen (basically checked above) */
+ {
+ int reopen_door = (game_status == GAME_MODE_PLAYING ? REQ_REOPEN : 0);
+
+ Request("No tape for this level !", REQ_CONFIRM | reopen_door);
+ }
}
}
* tape autoplay functions
* ------------------------------------------------------------------------- */
-#define MAX_NUM_AUTOPLAY_LEVELS 1000
-
void AutoPlayTape()
{
static LevelDirTree *autoplay_leveldir = NULL;
static int autoplay_level_nr = -1;
static int num_levels_played = 0;
static int num_levels_solved = 0;
- static boolean levels_failed[MAX_NUM_AUTOPLAY_LEVELS];
+ static int num_tape_missing = 0;
+ static boolean level_failed[MAX_TAPES_PER_SET];
+ static boolean tape_missing[MAX_TAPES_PER_SET];
int i;
if (autoplay_initialized)
printf("%s.\n", tape.auto_play_level_solved ? "solved" : "NOT SOLVED");
num_levels_played++;
+
if (tape.auto_play_level_solved)
num_levels_solved++;
- else if (level_nr >= 0 && level_nr < MAX_NUM_AUTOPLAY_LEVELS)
- levels_failed[level_nr] = TRUE;
+ else if (level_nr >= 0 && level_nr < MAX_TAPES_PER_SET)
+ level_failed[level_nr] = TRUE;
}
else
{
leveldir_current = autoplay_leveldir;
- if (global.autoplay_level_nr != -1)
- {
- autoplay_leveldir->first_level = global.autoplay_level_nr;
- autoplay_leveldir->last_level = global.autoplay_level_nr;
- }
+ if (autoplay_leveldir->first_level < 0)
+ autoplay_leveldir->first_level = 0;
+ if (autoplay_leveldir->last_level >= MAX_TAPES_PER_SET)
+ autoplay_leveldir->last_level = MAX_TAPES_PER_SET - 1;
autoplay_level_nr = autoplay_leveldir->first_level;
printf_line("=", 79);
printf("\n");
- for (i = 0; i < MAX_NUM_AUTOPLAY_LEVELS; i++)
- levels_failed[i] = FALSE;
+ for (i = 0; i < MAX_TAPES_PER_SET; i++)
+ {
+ level_failed[i] = FALSE;
+ tape_missing[i] = FALSE;
+ }
autoplay_initialized = TRUE;
}
{
level_nr = autoplay_level_nr++;
+ if (!global.autoplay_all && !global.autoplay_level[level_nr])
+ continue;
+
TapeErase();
printf("Level %03d: ", level_nr);
if (TAPE_IS_EMPTY(tape))
#endif
{
+ num_tape_missing++;
+ if (level_nr >= 0 && level_nr < MAX_TAPES_PER_SET)
+ tape_missing[level_nr] = TRUE;
+
printf("(no tape)\n");
continue;
}
if (num_levels_played != num_levels_solved)
{
printf(", FAILED:");
- for (i = 0; i < MAX_NUM_AUTOPLAY_LEVELS; i++)
- if (levels_failed[i])
+ for (i = 0; i < MAX_TAPES_PER_SET; i++)
+ if (level_failed[i])
printf(" %03d", i);
}
+#if 0
+ if (num_tape_missing > 0)
+ {
+ printf(", NO TAPE:");
+ for (i = 0; i < MAX_TAPES_PER_SET; i++)
+ if (tape_missing[i])
+ printf(" %03d", i);
+ }
+#endif
+
printf("\n");
printf_line("=", 79);
void RedrawPlayfield(boolean force_redraw, int x, int y, int width, int height)
{
- if (game_status == GAME_MODE_PLAYING && !game.envelope_active)
+ if (game_status == GAME_MODE_PLAYING &&
+ level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ {
+ BlitScreenToBitmap_EM(backbuffer);
+ }
+ else if (game_status == GAME_MODE_PLAYING && !game.envelope_active)
{
if (force_redraw)
{
graphic_info[IMG_BACKGROUND].bitmap);
}
-void DrawBackground(int dest_x, int dest_y, int width, int height)
+void DrawBackground(int dst_x, int dst_y, int width, int height)
{
- ClearRectangleOnBackground(backbuffer, dest_x, dest_y, width, height);
+ ClearRectangleOnBackground(backbuffer, dst_x, dst_y, width, height);
redraw_mask |= REDRAW_FIELD;
}
sync_frame);
}
-inline void DrawGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y,
- int graphic, int sync_frame, int mask_mode)
+inline void getGraphicSourceExt(int graphic, int frame, Bitmap **bitmap,
+ int *x, int *y, boolean get_backside)
{
- int frame = getGraphicAnimationFrame(graphic, sync_frame);
+ struct GraphicInfo *g = &graphic_info[graphic];
+ int src_x = g->src_x + (get_backside ? g->offset2_x : 0);
+ int src_y = g->src_y + (get_backside ? g->offset2_y : 0);
- if (mask_mode == USE_MASKING)
- DrawGraphicThruMaskExt(dst_bitmap, x, y, graphic, frame);
- else
- DrawGraphicExt(dst_bitmap, x, y, graphic, frame);
+ *bitmap = g->bitmap;
+
+ if (g->offset_y == 0) /* frames are ordered horizontally */
+ {
+ int max_width = g->anim_frames_per_line * g->width;
+#if 1
+ int pos = (src_y / g->height) * max_width + src_x + frame * g->offset_x;
+
+ *x = pos % max_width;
+ *y = src_y % g->height + pos / max_width * g->height;
+#else
+ *x = (src_x + frame * g->offset_x) % max_width;
+ *y = src_y + (src_x + frame * g->offset_x) / max_width * g->height;
+#endif
+ }
+ else if (g->offset_x == 0) /* frames are ordered vertically */
+ {
+ int max_height = g->anim_frames_per_line * g->height;
+#if 1
+ int pos = (src_x / g->width) * max_height + src_y + frame * g->offset_y;
+
+ *x = src_x % g->width + pos / max_height * g->width;
+ *y = pos % max_height;
+#else
+ *x = src_x + (src_y + frame * g->offset_y) / max_height * g->width;
+ *y = (src_y + frame * g->offset_y) % max_height;
+#endif
+ }
+ else /* frames are ordered diagonally */
+ {
+ *x = src_x + frame * g->offset_x;
+ *y = src_y + frame * g->offset_y;
+ }
}
-inline void DrawGraphicAnimation(int x, int y, int graphic)
+void getGraphicSource(int graphic, int frame, Bitmap **bitmap, int *x, int *y)
{
- int lx = LEVELX(x), ly = LEVELY(y);
+ getGraphicSourceExt(graphic, frame, bitmap, x, y, FALSE);
+}
+void DrawGraphic(int x, int y, int graphic, int frame)
+{
+#if DEBUG
if (!IN_SCR_FIELD(x, y))
+ {
+ printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n", x, y, graphic);
+ printf("DrawGraphic(): This should never happen!\n");
return;
+ }
+#endif
- DrawGraphicAnimationExt(drawto_field, FX + x * TILEX, FY + y * TILEY,
- graphic, GfxFrame[lx][ly], NO_MASKING);
+ DrawGraphicExt(drawto_field, FX + x * TILEX, FY + y * TILEY, graphic, frame);
MarkTileDirty(x, y);
}
-void DrawLevelGraphicAnimation(int x, int y, int graphic)
+void DrawGraphicExt(DrawBuffer *dst_bitmap, int x, int y, int graphic,
+ int frame)
{
- DrawGraphicAnimation(SCREENX(x), SCREENY(y), graphic);
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+
+ getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
+ BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, TILEX, TILEY, x, y);
}
-void DrawLevelElementAnimation(int x, int y, int element)
+void DrawGraphicThruMask(int x, int y, int graphic, int frame)
{
-#if 1
- int graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]);
-
- DrawGraphicAnimation(SCREENX(x), SCREENY(y), graphic);
-#else
- DrawGraphicAnimation(SCREENX(x), SCREENY(y), el2img(element));
+#if DEBUG
+ if (!IN_SCR_FIELD(x, y))
+ {
+ printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
+ printf("DrawGraphicThruMask(): This should never happen!\n");
+ return;
+ }
#endif
+
+ DrawGraphicThruMaskExt(drawto_field, FX + x * TILEX, FY + y *TILEY, graphic,
+ frame);
+ MarkTileDirty(x, y);
}
-inline void DrawLevelGraphicAnimationIfNeeded(int x, int y, int graphic)
+void DrawGraphicThruMaskExt(DrawBuffer *d, int dst_x, int dst_y, int graphic,
+ int frame)
{
- int sx = SCREENX(x), sy = SCREENY(y);
+ Bitmap *src_bitmap;
+ int src_x, src_y;
- if (!IN_LEV_FIELD(x, y) || !IN_SCR_FIELD(sx, sy))
- return;
+ getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
- if (!IS_NEW_FRAME(GfxFrame[x][y], graphic))
- return;
+ SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(src_bitmap, d, src_x, src_y, TILEX, TILEY, dst_x, dst_y);
+}
- DrawGraphicAnimation(sx, sy, graphic);
+void DrawMiniGraphic(int x, int y, int graphic)
+{
+ DrawMiniGraphicExt(drawto, SX + x * MINI_TILEX,SY + y * MINI_TILEY, graphic);
+ MarkTileDirty(x / 2, y / 2);
+}
- if (GFX_CRUMBLED(Feld[x][y]))
- DrawLevelFieldCrumbledSand(x, y);
+void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
+{
+ struct GraphicInfo *g = &graphic_info[graphic];
+ int mini_startx = 0;
+ int mini_starty = g->bitmap->height * 2 / 3;
+
+ *bitmap = g->bitmap;
+ *x = mini_startx + g->src_x / 2;
+ *y = mini_starty + g->src_y / 2;
}
-void DrawLevelElementAnimationIfNeeded(int x, int y, int element)
+void DrawMiniGraphicExt(DrawBuffer *d, int x, int y, int graphic)
{
- int sx = SCREENX(x), sy = SCREENY(y);
- int graphic;
+ Bitmap *src_bitmap;
+ int src_x, src_y;
- if (!IN_LEV_FIELD(x, y) || !IN_SCR_FIELD(sx, sy))
- return;
+ getMiniGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
+ BlitBitmap(src_bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
+}
- graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]);
+inline static void DrawGraphicShiftedNormal(int x, int y, int dx, int dy,
+ int graphic, int frame,
+ int cut_mode, int mask_mode)
+{
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int dst_x, dst_y;
+ int width = TILEX, height = TILEY;
+ int cx = 0, cy = 0;
- if (!IS_NEW_FRAME(GfxFrame[x][y], graphic))
+ if (dx || dy) /* shifted graphic */
+ {
+ if (x < BX1) /* object enters playfield from the left */
+ {
+ x = BX1;
+ width = dx;
+ cx = TILEX - dx;
+ dx = 0;
+ }
+ else if (x > BX2) /* object enters playfield from the right */
+ {
+ x = BX2;
+ width = -dx;
+ dx = TILEX + dx;
+ }
+ else if (x==BX1 && dx < 0) /* object leaves playfield to the left */
+ {
+ width += dx;
+ cx = -dx;
+ dx = 0;
+ }
+ else if (x==BX2 && dx > 0) /* object leaves playfield to the right */
+ width -= dx;
+ else if (dx) /* general horizontal movement */
+ MarkTileDirty(x + SIGN(dx), y);
+
+ if (y < BY1) /* object enters playfield from the top */
+ {
+ if (cut_mode==CUT_BELOW) /* object completely above top border */
+ return;
+
+ y = BY1;
+ height = dy;
+ cy = TILEY - dy;
+ dy = 0;
+ }
+ else if (y > BY2) /* object enters playfield from the bottom */
+ {
+ y = BY2;
+ height = -dy;
+ dy = TILEY + dy;
+ }
+ else if (y==BY1 && dy < 0) /* object leaves playfield to the top */
+ {
+ height += dy;
+ cy = -dy;
+ dy = 0;
+ }
+ else if (dy > 0 && cut_mode == CUT_ABOVE)
+ {
+ if (y == BY2) /* object completely above bottom border */
+ return;
+
+ height = dy;
+ cy = TILEY - dy;
+ dy = TILEY;
+ MarkTileDirty(x, y + 1);
+ } /* object leaves playfield to the bottom */
+ else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
+ height -= dy;
+ else if (dy) /* general vertical movement */
+ MarkTileDirty(x, y + SIGN(dy));
+ }
+
+#if DEBUG
+ if (!IN_SCR_FIELD(x, y))
+ {
+ printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
+ printf("DrawGraphicShifted(): This should never happen!\n");
return;
+ }
+#endif
- DrawGraphicAnimation(sx, sy, graphic);
+ if (width > 0 && height > 0)
+ {
+ getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
- if (GFX_CRUMBLED(element))
- DrawLevelFieldCrumbledSand(x, y);
+ src_x += cx;
+ src_y += cy;
+
+ dst_x = FX + x * TILEX + dx;
+ dst_y = FY + y * TILEY + dy;
+
+ if (mask_mode == USE_MASKING)
+ {
+ SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(src_bitmap, drawto_field, src_x, src_y, width, height,
+ dst_x, dst_y);
+ }
+ else
+ BlitBitmap(src_bitmap, drawto_field, src_x, src_y, width, height,
+ dst_x, dst_y);
+
+ MarkTileDirty(x, y);
+ }
}
-static int getPlayerGraphic(struct PlayerInfo *player, int move_dir)
+inline static void DrawGraphicShiftedDouble(int x, int y, int dx, int dy,
+ int graphic, int frame,
+ int cut_mode, int mask_mode)
{
- if (player->use_murphy_graphic)
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int dst_x, dst_y;
+ int width = TILEX, height = TILEY;
+ int x1 = x;
+ int y1 = y;
+ int x2 = x + SIGN(dx);
+ int y2 = y + SIGN(dy);
+ int anim_frames = graphic_info[graphic].anim_frames;
+ int sync_frame = (dx ? ABS(dx) : ABS(dy)) * anim_frames / TILESIZE;
+
+ /* re-calculate animation frame for two-tile movement animation */
+ frame = getGraphicAnimationFrame(graphic, sync_frame);
+
+ if (IN_SCR_FIELD(x1, y1)) /* movement start graphic inside screen area */
{
- /* this works only because currently only one player can be "murphy" ... */
- static int last_horizontal_dir = MV_LEFT;
- int graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, move_dir);
+ getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y, TRUE);
- if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
- last_horizontal_dir = move_dir;
+ dst_x = FX + x1 * TILEX;
+ dst_y = FY + y1 * TILEY;
- if (graphic == IMG_SP_MURPHY) /* undefined => use special graphic */
+ if (mask_mode == USE_MASKING)
{
- int direction = (player->is_snapping ? move_dir : last_horizontal_dir);
+ SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(src_bitmap, drawto_field, src_x, src_y, width, height,
+ dst_x, dst_y);
+ }
+ else
+ BlitBitmap(src_bitmap, drawto_field, src_x, src_y, width, height,
+ dst_x, dst_y);
- graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, direction);
+ MarkTileDirty(x1, y1);
+ }
+
+ if (IN_SCR_FIELD(x2, y2)) /* movement end graphic inside screen area */
+ {
+ getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y, FALSE);
+
+ dst_x = FX + x2 * TILEX;
+ dst_y = FY + y2 * TILEY;
+
+ if (mask_mode == USE_MASKING)
+ {
+ SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(src_bitmap, drawto_field, src_x, src_y, width, height,
+ dst_x, dst_y);
}
+ else
+ BlitBitmap(src_bitmap, drawto_field, src_x, src_y, width, height,
+ dst_x, dst_y);
- return graphic;
+ MarkTileDirty(x2, y2);
}
- else
- return el_act_dir2img(player->element_nr, player->GfxAction, move_dir);
+
+#if 0
+ printf("::: DONE DrawGraphicShiftedDouble");
+ BackToFront();
+ Delay(1000);
+#endif
}
-static boolean equalGraphics(int graphic1, int graphic2)
+static void DrawGraphicShifted(int x, int y, int dx, int dy,
+ int graphic, int frame,
+ int cut_mode, int mask_mode)
{
- struct GraphicInfo *g1 = &graphic_info[graphic1];
- struct GraphicInfo *g2 = &graphic_info[graphic2];
+ if (graphic < 0)
+ {
+ DrawGraphic(x, y, graphic, frame);
- return (g1->bitmap == g2->bitmap &&
- g1->src_x == g2->src_x &&
- g1->src_y == g2->src_y &&
- g1->anim_frames == g2->anim_frames &&
- g1->anim_delay == g2->anim_delay &&
- g1->anim_mode == g2->anim_mode);
+ return;
+ }
+
+ if (graphic_info[graphic].double_movement) /* EM style movement images */
+ DrawGraphicShiftedDouble(x, y, dx, dy, graphic, frame, cut_mode,mask_mode);
+ else
+ DrawGraphicShiftedNormal(x, y, dx, dy, graphic, frame, cut_mode,mask_mode);
}
-void DrawAllPlayers()
+void DrawGraphicShiftedThruMask(int x, int y, int dx, int dy, int graphic,
+ int frame, int cut_mode)
{
- int i;
+ DrawGraphicShifted(x, y, dx, dy, graphic, frame, cut_mode, USE_MASKING);
+}
- for (i = 0; i < MAX_PLAYERS; i++)
- if (stored_player[i].active)
- DrawPlayer(&stored_player[i]);
-}
-
-void DrawPlayerField(int x, int y)
-{
- if (!IS_PLAYER(x, y))
- return;
-
- DrawPlayer(PLAYERINFO(x, y));
-}
-
-void DrawPlayer(struct PlayerInfo *player)
+void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
+ int cut_mode, int mask_mode)
{
- int jx = player->jx;
- int jy = player->jy;
- int move_dir = player->MovDir;
-#if 0
- int last_jx = player->last_jx;
- int last_jy = player->last_jy;
- int next_jx = jx + (jx - last_jx);
- int next_jy = jy + (jy - last_jy);
- boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
-#else
- int dx = (move_dir == MV_LEFT ? -1 : move_dir == MV_RIGHT ? +1 : 0);
- int dy = (move_dir == MV_UP ? -1 : move_dir == MV_DOWN ? +1 : 0);
- int last_jx = (player->is_moving ? jx - dx : jx);
- int last_jy = (player->is_moving ? jy - dy : jy);
- int next_jx = jx + dx;
- int next_jy = jy + dy;
- boolean player_is_moving = (player->MovPos ? TRUE : FALSE);
-#endif
- int sx = SCREENX(jx), sy = SCREENY(jy);
- int sxx = 0, syy = 0;
- int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
+ int lx = LEVELX(x), ly = LEVELY(y);
int graphic;
- int action = ACTION_DEFAULT;
- int last_player_graphic = getPlayerGraphic(player, move_dir);
- int last_player_frame = player->Frame;
- int frame = 0;
-
- if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
- return;
+ int frame;
-#if DEBUG
- if (!IN_LEV_FIELD(jx, jy))
+ if (IN_LEV_FIELD(lx, ly))
{
- printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
- printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
- printf("DrawPlayerField(): This should never happen!\n");
- return;
- }
-#endif
-
- if (element == EL_EXPLOSION)
- return;
-
- action = (player->is_pushing ? ACTION_PUSHING :
- player->is_digging ? ACTION_DIGGING :
- player->is_collecting ? ACTION_COLLECTING :
- player->is_moving ? ACTION_MOVING :
- player->is_snapping ? ACTION_SNAPPING :
- player->is_dropping ? ACTION_DROPPING :
- player->is_waiting ? player->action_waiting : ACTION_DEFAULT);
-
- InitPlayerGfxAnimation(player, action, move_dir);
+ SetRandomAnimationValue(lx, ly);
- /* ----------------------------------------------------------------------- */
- /* draw things in the field the player is leaving, if needed */
- /* ----------------------------------------------------------------------- */
+ graphic = el_act_dir2img(element, GfxAction[lx][ly], GfxDir[lx][ly]);
+ frame = getGraphicAnimationFrame(graphic, GfxFrame[lx][ly]);
-#if 1
- if (player->is_moving)
-#else
- if (player_is_moving)
-#endif
- {
- if (Back[last_jx][last_jy] && IS_DRAWABLE(last_element))
+ /* do not use double (EM style) movement graphic when not moving */
+ if (graphic_info[graphic].double_movement && !dx && !dy)
{
- DrawLevelElement(last_jx, last_jy, Back[last_jx][last_jy]);
-
- if (last_element == EL_DYNAMITE_ACTIVE ||
- last_element == EL_SP_DISK_RED_ACTIVE)
- DrawDynamite(last_jx, last_jy);
- else
- DrawLevelFieldThruMask(last_jx, last_jy);
+ graphic = el_act_dir2img(element, ACTION_DEFAULT, GfxDir[lx][ly]);
+ frame = getGraphicAnimationFrame(graphic, GfxFrame[lx][ly]);
}
- else if (last_element == EL_DYNAMITE_ACTIVE ||
- last_element == EL_SP_DISK_RED_ACTIVE)
- DrawDynamite(last_jx, last_jy);
- else
- DrawLevelField(last_jx, last_jy);
-
- if (player->is_pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
- DrawLevelElement(next_jx, next_jy, EL_EMPTY);
+ }
+ else /* border element */
+ {
+ graphic = el2img(element);
+ frame = getGraphicAnimationFrame(graphic, -1);
}
- if (!IN_SCR_FIELD(sx, sy))
- return;
-
- if (setup.direct_draw)
- SetDrawtoField(DRAW_BUFFERED);
+ if (element == EL_EXPANDABLE_WALL)
+ {
+ boolean left_stopped = FALSE, right_stopped = FALSE;
- /* ----------------------------------------------------------------------- */
- /* draw things behind the player, if needed */
- /* ----------------------------------------------------------------------- */
+ if (!IN_LEV_FIELD(lx - 1, ly) || IS_WALL(Feld[lx - 1][ly]))
+ left_stopped = TRUE;
+ if (!IN_LEV_FIELD(lx + 1, ly) || IS_WALL(Feld[lx + 1][ly]))
+ right_stopped = TRUE;
- if (Back[jx][jy])
- DrawLevelElement(jx, jy, Back[jx][jy]);
- else if (IS_ACTIVE_BOMB(element))
- DrawLevelElement(jx, jy, EL_EMPTY);
- else
- {
- if (player_is_moving && GfxElement[jx][jy] != EL_UNDEFINED)
+ if (left_stopped && right_stopped)
+ graphic = IMG_WALL;
+ else if (left_stopped)
{
- if (GFX_CRUMBLED(GfxElement[jx][jy]))
- DrawLevelFieldCrumbledSandDigging(jx, jy, move_dir, player->StepFrame);
- else
- {
- int old_element = GfxElement[jx][jy];
- int old_graphic = el_act_dir2img(old_element, action, move_dir);
- int frame = getGraphicAnimationFrame(old_graphic, player->StepFrame);
-
- DrawGraphic(sx, sy, old_graphic, frame);
- }
+ graphic = IMG_EXPANDABLE_WALL_GROWING_RIGHT;
+ frame = graphic_info[graphic].anim_frames - 1;
}
- else
+ else if (right_stopped)
{
- GfxElement[jx][jy] = EL_UNDEFINED;
-
- DrawLevelField(jx, jy);
+ graphic = IMG_EXPANDABLE_WALL_GROWING_LEFT;
+ frame = graphic_info[graphic].anim_frames - 1;
}
}
- /* ----------------------------------------------------------------------- */
- /* draw player himself */
- /* ----------------------------------------------------------------------- */
-
-#if 1
-
- graphic = getPlayerGraphic(player, move_dir);
-
- /* in the case of changed player action or direction, prevent the current
- animation frame from being restarted for identical animations */
- if (player->Frame == 0 && equalGraphics(graphic, last_player_graphic))
- player->Frame = last_player_frame;
+ if (dx || dy)
+ DrawGraphicShifted(x, y, dx, dy, graphic, frame, cut_mode, mask_mode);
+ else if (mask_mode == USE_MASKING)
+ DrawGraphicThruMask(x, y, graphic, frame);
+ else
+ DrawGraphic(x, y, graphic, frame);
+}
-#else
+void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
+ int cut_mode, int mask_mode)
+{
+ if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+ DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
+ cut_mode, mask_mode);
+}
- if (player->use_murphy_graphic)
- {
- static int last_horizontal_dir = MV_LEFT;
+void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
+ int cut_mode)
+{
+ DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
+}
- if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
- last_horizontal_dir = move_dir;
+void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
+ int cut_mode)
+{
+ DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
+}
- graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, move_dir);
+void DrawLevelElementThruMask(int x, int y, int element)
+{
+ DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
+}
- if (graphic == IMG_SP_MURPHY) /* undefined => use special graphic */
- {
- int direction = (player->is_snapping ? move_dir : last_horizontal_dir);
+void DrawLevelFieldThruMask(int x, int y)
+{
+ DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
+}
- graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, direction);
- }
- }
- else
- graphic = el_act_dir2img(player->element_nr, player->GfxAction, move_dir);
+#define TILE_GFX_ELEMENT(x, y) \
+ (GfxElement[x][y] != EL_UNDEFINED && Feld[x][y] != EL_EXPLOSION ? \
+ GfxElement[x][y] : Feld[x][y])
+static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame)
+{
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int sx = SCREENX(x), sy = SCREENY(y);
+ int element;
+ int width, height, cx, cy, i;
+#if 1
+ int crumbled_border_size = graphic_info[graphic].border_size;
+#else
+ int snip = TILEX / 8; /* number of border pixels from "crumbled graphic" */
#endif
-
- frame = getGraphicAnimationFrame(graphic, player->Frame);
-
- if (player->GfxPos)
+ static int xy[4][2] =
{
- if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
- sxx = player->GfxPos;
- else
- syy = player->GfxPos;
- }
+ { 0, -1 },
+ { -1, 0 },
+ { +1, 0 },
+ { 0, +1 }
+ };
- if (!setup.soft_scrolling && ScreenMovPos)
- sxx = syy = 0;
+#if 0
+ if (x == 0 && y == 7)
+ printf("::: %d, %d [%d]\n", GfxElement[x][y], Feld[x][y],
+ crumbled_border_size);
+#endif
- DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING);
+ if (!IN_LEV_FIELD(x, y))
+ return;
- if (SHIELD_ON(player))
+ element = TILE_GFX_ELEMENT(x, y);
+
+ /* crumble field itself */
+ if (GFX_CRUMBLED(element) && !IS_MOVING(x, y))
{
- int graphic = (player->shield_deadly_time_left ? IMG_SHIELD_DEADLY_ACTIVE :
- IMG_SHIELD_NORMAL_ACTIVE);
- int frame = getGraphicAnimationFrame(graphic, -1);
+ if (!IN_SCR_FIELD(sx, sy))
+ return;
- DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING);
- }
+ getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
- /* ----------------------------------------------------------------------- */
- /* draw things the player is pushing, if needed */
- /* ----------------------------------------------------------------------- */
-
-#if 0
- printf("::: %d, %d [%d, %d] [%d]\n",
- player->is_pushing, player_is_moving, player->GfxAction,
- player->is_moving, player_is_moving);
-#endif
+ for (i = 0; i < 4; i++)
+ {
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
#if 1
- if (player->is_pushing && player->is_moving)
+ element = (IN_LEV_FIELD(xx, yy) ? TILE_GFX_ELEMENT(xx, yy) :
+ BorderElement);
#else
- if (player->is_pushing && player_is_moving)
+ element = (IN_LEV_FIELD(xx, yy) ? Feld[xx][yy] : BorderElement);
#endif
- {
- int px = SCREENX(next_jx), py = SCREENY(next_jy);
- if (Back[next_jx][next_jy])
- DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]);
+ /* check if neighbour field is of same type */
+ if (GFX_CRUMBLED(element) && !IS_MOVING(xx, yy))
+ continue;
- if ((sxx || syy) && element == EL_SOKOBAN_OBJECT)
- DrawGraphicShiftedThruMask(px, py, sxx, syy, IMG_SOKOBAN_OBJECT, 0,
- NO_CUTTING);
- else
- {
- int element = MovingOrBlocked2Element(next_jx, next_jy);
- int graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir);
-#if 1
- int frame = getGraphicAnimationFrame(graphic, player->StepFrame);
-#else
- int frame = getGraphicAnimationFrame(graphic, player->Frame);
+#if 0
+ if (Feld[x][y] == EL_CUSTOM_START + 123)
+ printf("::: crumble [%d] THE CHAOS ENGINE (%d, %d): %d, %d\n",
+ i, Feld[x][y], element,
+ GFX_CRUMBLED(element), IS_MOVING(x, y));
#endif
- DrawGraphicShifted(px, py, sxx, syy, graphic, frame,
- NO_CUTTING, NO_MASKING);
- }
- }
-
- /* ----------------------------------------------------------------------- */
- /* draw things in front of player (active dynamite or dynabombs) */
- /* ----------------------------------------------------------------------- */
+ if (i == 1 || i == 2)
+ {
+ width = crumbled_border_size;
+ height = TILEY;
+ cx = (i == 2 ? TILEX - crumbled_border_size : 0);
+ cy = 0;
+ }
+ else
+ {
+ width = TILEX;
+ height = crumbled_border_size;
+ cx = 0;
+ cy = (i == 3 ? TILEY - crumbled_border_size : 0);
+ }
- if (IS_ACTIVE_BOMB(element))
- {
- graphic = el2img(element);
- frame = getGraphicAnimationFrame(graphic, GfxFrame[jx][jy]);
+ BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
+ width, height, FX + sx * TILEX + cx, FY + sy * TILEY + cy);
+ }
- if (game.emulation == EMU_SUPAPLEX)
- DrawGraphic(sx, sy, IMG_SP_DISK_RED, frame);
- else
- DrawGraphicThruMask(sx, sy, graphic, frame);
+ MarkTileDirty(sx, sy);
}
-
- if (player_is_moving && last_element == EL_EXPLOSION)
+ else /* crumble neighbour fields */
{
- int graphic = el_act2img(GfxElement[last_jx][last_jy], ACTION_EXPLODING);
- int delay = (game.emulation == EMU_SUPAPLEX ? 3 : 2);
- int phase = ExplodePhase[last_jx][last_jy] - 1;
- int frame = getGraphicAnimationFrame(graphic, phase - delay);
-
- if (phase >= delay)
- DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy), graphic, frame);
- }
-
- /* ----------------------------------------------------------------------- */
- /* draw elements the player is just walking/passing through/under */
- /* ----------------------------------------------------------------------- */
+#if 0
+ getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
+#endif
- if (player_is_moving)
- {
- /* handle the field the player is leaving ... */
- if (IS_ACCESSIBLE_INSIDE(last_element))
- DrawLevelField(last_jx, last_jy);
- else if (IS_ACCESSIBLE_UNDER(last_element))
- DrawLevelFieldThruMask(last_jx, last_jy);
- }
+ for (i = 0; i < 4; i++)
+ {
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
+ int sxx = sx + xy[i][0];
+ int syy = sy + xy[i][1];
#if 1
- /* do not redraw accessible elements if the player is just pushing them */
- if (!player_is_moving || !player->is_pushing)
- {
- /* ... and the field the player is entering */
- if (IS_ACCESSIBLE_INSIDE(element))
- DrawLevelField(jx, jy);
- else if (IS_ACCESSIBLE_UNDER(element))
- DrawLevelFieldThruMask(jx, jy);
- }
+ if (!IN_LEV_FIELD(xx, yy) ||
+ !IN_SCR_FIELD(sxx, syy) ||
+ IS_MOVING(xx, yy))
+ continue;
-#else
+ element = TILE_GFX_ELEMENT(xx, yy);
-#if 0
- /* !!! I have forgotton what this should be good for !!! */
- /* !!! causes player being visible when pushing from within tubes !!! */
- if (!player->is_pushing)
-#endif
- {
- /* ... and the field the player is entering */
- if (IS_ACCESSIBLE_INSIDE(element))
- DrawLevelField(jx, jy);
- else if (IS_ACCESSIBLE_UNDER(element))
- DrawLevelFieldThruMask(jx, jy);
- }
+ if (!GFX_CRUMBLED(element))
+ continue;
+#else
+ if (!IN_LEV_FIELD(xx, yy) ||
+ !IN_SCR_FIELD(sxx, syy) ||
+ !GFX_CRUMBLED(Feld[xx][yy]) ||
+ IS_MOVING(xx, yy))
+ continue;
#endif
- if (setup.direct_draw)
- {
- int dest_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
- int dest_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
- int x_size = TILEX * (1 + ABS(jx - last_jx));
- int y_size = TILEY * (1 + ABS(jy - last_jy));
-
- BlitBitmap(drawto_field, window,
- dest_x, dest_y, x_size, y_size, dest_x, dest_y);
- SetDrawtoField(DRAW_DIRECT);
- }
-
- MarkTileDirty(sx, sy);
-}
-
-void getGraphicSource(int graphic, int frame, Bitmap **bitmap, int *x, int *y)
-{
- struct GraphicInfo *g = &graphic_info[graphic];
+#if 1
+ graphic = el_act2crm(Feld[xx][yy], ACTION_DEFAULT);
+ crumbled_border_size = graphic_info[graphic].border_size;
- *bitmap = g->bitmap;
+ getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
+#endif
- if (g->offset_y == 0) /* frames are ordered horizontally */
- {
- int max_width = g->anim_frames_per_line * g->width;
+ if (i == 1 || i == 2)
+ {
+ width = crumbled_border_size;
+ height = TILEY;
+ cx = (i == 1 ? TILEX - crumbled_border_size : 0);
+ cy = 0;
+ }
+ else
+ {
+ width = TILEX;
+ height = crumbled_border_size;
+ cx = 0;
+ cy = (i == 0 ? TILEY - crumbled_border_size : 0);
+ }
- *x = (g->src_x + frame * g->offset_x) % max_width;
- *y = g->src_y + (g->src_x + frame * g->offset_x) / max_width * g->height;
- }
- else if (g->offset_x == 0) /* frames are ordered vertically */
- {
- int max_height = g->anim_frames_per_line * g->height;
+ BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
+ width, height, FX + sxx * TILEX + cx, FY + syy * TILEY + cy);
- *x = g->src_x + (g->src_y + frame * g->offset_y) / max_height * g->width;
- *y = (g->src_y + frame * g->offset_y) % max_height;
- }
- else /* frames are ordered diagonally */
- {
- *x = g->src_x + frame * g->offset_x;
- *y = g->src_y + frame * g->offset_y;
+ MarkTileDirty(sxx, syy);
+ }
}
}
-void DrawGraphic(int x, int y, int graphic, int frame)
+void DrawLevelFieldCrumbledSand(int x, int y)
{
-#if DEBUG
- if (!IN_SCR_FIELD(x, y))
- {
- printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n", x, y, graphic);
- printf("DrawGraphic(): This should never happen!\n");
- return;
- }
-#endif
-
- DrawGraphicExt(drawto_field, FX + x * TILEX, FY + y * TILEY, graphic, frame);
- MarkTileDirty(x, y);
-}
+#if 1
+ int graphic;
-void DrawGraphicExt(DrawBuffer *dst_bitmap, int x, int y, int graphic,
- int frame)
-{
- Bitmap *src_bitmap;
- int src_x, src_y;
+ if (!IN_LEV_FIELD(x, y))
+ return;
- getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
- BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, TILEX, TILEY, x, y);
-}
+ graphic = el_act2crm(Feld[x][y], ACTION_DEFAULT);
-void DrawGraphicThruMask(int x, int y, int graphic, int frame)
-{
-#if DEBUG
- if (!IN_SCR_FIELD(x, y))
- {
- printf("DrawGraphicThruMask(): x = %d,y = %d, graphic = %d\n",x,y,graphic);
- printf("DrawGraphicThruMask(): This should never happen!\n");
- return;
- }
+ DrawLevelFieldCrumbledSandExt(x, y, graphic, 0);
+#else
+ DrawLevelFieldCrumbledSandExt(x, y, IMG_SAND_CRUMBLED, 0);
#endif
-
- DrawGraphicThruMaskExt(drawto_field, FX + x * TILEX, FY + y *TILEY, graphic,
- frame);
- MarkTileDirty(x, y);
}
-void DrawGraphicThruMaskExt(DrawBuffer *d, int dest_x, int dest_y, int graphic,
- int frame)
+void DrawLevelFieldCrumbledSandDigging(int x, int y, int direction,
+ int step_frame)
{
#if 1
- Bitmap *src_bitmap;
- int src_x, src_y;
- GC drawing_gc;
-
- getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
- drawing_gc = src_bitmap->stored_clip_gc;
+ int graphic1 = el_act_dir2img(GfxElement[x][y], ACTION_DIGGING, direction);
+ int graphic2 = el_act_dir2crm(GfxElement[x][y], ACTION_DIGGING, direction);
#else
- GC drawing_gc = src_bitmap->stored_clip_gc;
- Bitmap *src_bitmap = graphic_info[graphic].bitmap;
- int src_x = graphic_info[graphic].src_x;
- int src_y = graphic_info[graphic].src_y;
- int offset_x = graphic_info[graphic].offset_x;
- int offset_y = graphic_info[graphic].offset_y;
-
- src_x += frame * offset_x;
- src_y += frame * offset_y;
-
+ int graphic1 = el_act_dir2img(EL_SAND, ACTION_DIGGING, direction);
+ int graphic2 = el_act_dir2img(EL_SAND_CRUMBLED, ACTION_DIGGING, direction);
#endif
+ int frame1 = getGraphicAnimationFrame(graphic1, step_frame);
+ int frame2 = getGraphicAnimationFrame(graphic2, step_frame);
+ int sx = SCREENX(x), sy = SCREENY(y);
- SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
- BlitBitmapMasked(src_bitmap, d, src_x, src_y, TILEX, TILEY, dest_x, dest_y);
+ DrawGraphic(sx, sy, graphic1, frame1);
+ DrawLevelFieldCrumbledSandExt(x, y, graphic2, frame2);
}
-void DrawMiniGraphic(int x, int y, int graphic)
+void DrawLevelFieldCrumbledSandNeighbours(int x, int y)
{
- DrawMiniGraphicExt(drawto, SX + x * MINI_TILEX,SY + y * MINI_TILEY, graphic);
- MarkTileDirty(x / 2, y / 2);
-}
-
-void getMiniGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
+ int sx = SCREENX(x), sy = SCREENY(y);
+ static int xy[4][2] =
+ {
+ { 0, -1 },
+ { -1, 0 },
+ { +1, 0 },
+ { 0, +1 }
+ };
+ int i;
+
+ for (i = 0; i < 4; i++)
+ {
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
+ int sxx = sx + xy[i][0];
+ int syy = sy + xy[i][1];
+
+ if (!IN_LEV_FIELD(xx, yy) ||
+ !IN_SCR_FIELD(sxx, syy) ||
+ !GFX_CRUMBLED(Feld[xx][yy]) ||
+ IS_MOVING(xx, yy))
+ continue;
+
+ DrawLevelField(xx, yy);
+ }
+}
+
+static int getBorderElement(int x, int y)
{
- struct GraphicInfo *g = &graphic_info[graphic];
- int mini_startx = 0;
- int mini_starty = g->bitmap->height * 2 / 3;
+ int border[7][2] =
+ {
+ { EL_STEELWALL_TOPLEFT, EL_INVISIBLE_STEELWALL_TOPLEFT },
+ { EL_STEELWALL_TOPRIGHT, EL_INVISIBLE_STEELWALL_TOPRIGHT },
+ { EL_STEELWALL_BOTTOMLEFT, EL_INVISIBLE_STEELWALL_BOTTOMLEFT },
+ { EL_STEELWALL_BOTTOMRIGHT, EL_INVISIBLE_STEELWALL_BOTTOMRIGHT },
+ { EL_STEELWALL_VERTICAL, EL_INVISIBLE_STEELWALL_VERTICAL },
+ { EL_STEELWALL_HORIZONTAL, EL_INVISIBLE_STEELWALL_HORIZONTAL },
+ { EL_STEELWALL, EL_INVISIBLE_STEELWALL }
+ };
+ int steel_type = (BorderElement == EL_STEELWALL ? 0 : 1);
+ int steel_position = (x == -1 && y == -1 ? 0 :
+ x == lev_fieldx && y == -1 ? 1 :
+ x == -1 && y == lev_fieldy ? 2 :
+ x == lev_fieldx && y == lev_fieldy ? 3 :
+ x == -1 || x == lev_fieldx ? 4 :
+ y == -1 || y == lev_fieldy ? 5 : 6);
- *bitmap = g->bitmap;
- *x = mini_startx + g->src_x / 2;
- *y = mini_starty + g->src_y / 2;
+ return border[steel_position][steel_type];
}
-void DrawMiniGraphicExt(DrawBuffer *d, int x, int y, int graphic)
+void DrawScreenElement(int x, int y, int element)
{
- Bitmap *src_bitmap;
- int src_x, src_y;
+ DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
+ DrawLevelFieldCrumbledSand(LEVELX(x), LEVELY(y));
+}
- getMiniGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
- BlitBitmap(src_bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
+void DrawLevelElement(int x, int y, int element)
+{
+ if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+ DrawScreenElement(SCREENX(x), SCREENY(y), element);
}
-void DrawGraphicShifted(int x, int y, int dx, int dy, int graphic, int frame,
- int cut_mode, int mask_mode)
+void DrawScreenField(int x, int y)
{
- Bitmap *src_bitmap;
- GC drawing_gc;
- int src_x, src_y;
- int width = TILEX, height = TILEY;
- int cx = 0, cy = 0;
- int dest_x, dest_y;
+ int lx = LEVELX(x), ly = LEVELY(y);
+ int element, content;
- if (graphic < 0)
+ if (!IN_LEV_FIELD(lx, ly))
{
- DrawGraphic(x, y, graphic, frame);
+ if (lx < -1 || lx > lev_fieldx || ly < -1 || ly > lev_fieldy)
+ element = EL_EMPTY;
+ else
+ element = getBorderElement(lx, ly);
+
+ DrawScreenElement(x, y, element);
return;
}
- if (dx || dy) /* shifted graphic */
+ element = Feld[lx][ly];
+ content = Store[lx][ly];
+
+ if (IS_MOVING(lx, ly))
{
- if (x < BX1) /* object enters playfield from the left */
- {
- x = BX1;
- width = dx;
- cx = TILEX - dx;
- dx = 0;
- }
- else if (x > BX2) /* object enters playfield from the right */
- {
- x = BX2;
- width = -dx;
- dx = TILEX + dx;
- }
- else if (x==BX1 && dx < 0) /* object leaves playfield to the left */
- {
- width += dx;
- cx = -dx;
- dx = 0;
- }
- else if (x==BX2 && dx > 0) /* object leaves playfield to the right */
- width -= dx;
- else if (dx) /* general horizontal movement */
- MarkTileDirty(x + SIGN(dx), y);
+ int horiz_move = (MovDir[lx][ly] == MV_LEFT || MovDir[lx][ly] == MV_RIGHT);
+ boolean cut_mode = NO_CUTTING;
- if (y < BY1) /* object enters playfield from the top */
- {
- if (cut_mode==CUT_BELOW) /* object completely above top border */
- return;
+ if (element == EL_QUICKSAND_EMPTYING ||
+ element == EL_MAGIC_WALL_EMPTYING ||
+ element == EL_BD_MAGIC_WALL_EMPTYING ||
+ element == EL_AMOEBA_DROPPING)
+ cut_mode = CUT_ABOVE;
+ else if (element == EL_QUICKSAND_FILLING ||
+ element == EL_MAGIC_WALL_FILLING ||
+ element == EL_BD_MAGIC_WALL_FILLING)
+ cut_mode = CUT_BELOW;
- y = BY1;
- height = dy;
- cy = TILEY - dy;
- dy = 0;
- }
- else if (y > BY2) /* object enters playfield from the bottom */
- {
- y = BY2;
- height = -dy;
- dy = TILEY + dy;
- }
- else if (y==BY1 && dy < 0) /* object leaves playfield to the top */
- {
- height += dy;
- cy = -dy;
- dy = 0;
- }
- else if (dy > 0 && cut_mode == CUT_ABOVE)
+ if (cut_mode == CUT_ABOVE)
+ DrawScreenElementShifted(x, y, 0, 0, element, NO_CUTTING);
+ else
+ DrawScreenElement(x, y, EL_EMPTY);
+
+ if (horiz_move)
+ DrawScreenElementShifted(x, y, MovPos[lx][ly], 0, element, NO_CUTTING);
+ else if (cut_mode == NO_CUTTING)
+ DrawScreenElementShifted(x, y, 0, MovPos[lx][ly], element, cut_mode);
+ else
+ DrawScreenElementShifted(x, y, 0, MovPos[lx][ly], content, cut_mode);
+
+ if (content == EL_ACID)
{
- if (y == BY2) /* object completely above bottom border */
- return;
+ int dir = MovDir[lx][ly];
+ int newlx = lx + (dir == MV_LEFT ? -1 : dir == MV_RIGHT ? +1 : 0);
+ int newly = ly + (dir == MV_UP ? -1 : dir == MV_DOWN ? +1 : 0);
- height = dy;
- cy = TILEY - dy;
- dy = TILEY;
- MarkTileDirty(x, y + 1);
- } /* object leaves playfield to the bottom */
- else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
- height -= dy;
- else if (dy) /* general vertical movement */
- MarkTileDirty(x, y + SIGN(dy));
+ DrawLevelElementThruMask(newlx, newly, EL_ACID);
+ }
}
+ else if (IS_BLOCKED(lx, ly))
+ {
+ int oldx, oldy;
+ int sx, sy;
+ int horiz_move;
+ boolean cut_mode = NO_CUTTING;
+ int element_old, content_old;
-#if 1
- getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
-#else
- src_bitmap = graphic_info[graphic].bitmap;
- src_x = graphic_info[graphic].src_x;
- src_y = graphic_info[graphic].src_y;
- offset_x = graphic_info[graphic].offset_x;
- offset_y = graphic_info[graphic].offset_y;
-
- src_x += frame * offset_x;
- src_y += frame * offset_y;
-#endif
+ Blocked2Moving(lx, ly, &oldx, &oldy);
+ sx = SCREENX(oldx);
+ sy = SCREENY(oldy);
+ horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
+ MovDir[oldx][oldy] == MV_RIGHT);
- drawing_gc = src_bitmap->stored_clip_gc;
+ element_old = Feld[oldx][oldy];
+ content_old = Store[oldx][oldy];
- src_x += cx;
- src_y += cy;
+ if (element_old == EL_QUICKSAND_EMPTYING ||
+ element_old == EL_MAGIC_WALL_EMPTYING ||
+ element_old == EL_BD_MAGIC_WALL_EMPTYING ||
+ element_old == EL_AMOEBA_DROPPING)
+ cut_mode = CUT_ABOVE;
- dest_x = FX + x * TILEX + dx;
- dest_y = FY + y * TILEY + dy;
+ DrawScreenElement(x, y, EL_EMPTY);
-#if DEBUG
- if (!IN_SCR_FIELD(x,y))
- {
- printf("DrawGraphicShifted(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
- printf("DrawGraphicShifted(): This should never happen!\n");
- return;
+ if (horiz_move)
+ DrawScreenElementShifted(sx, sy, MovPos[oldx][oldy], 0, element_old,
+ NO_CUTTING);
+ else if (cut_mode == NO_CUTTING)
+ DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], element_old,
+ cut_mode);
+ else
+ DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], content_old,
+ cut_mode);
}
-#endif
+ else if (IS_DRAWABLE(element))
+ DrawScreenElement(x, y, element);
+ else
+ DrawScreenElement(x, y, EL_EMPTY);
+}
- if (mask_mode == USE_MASKING)
+void DrawLevelField(int x, int y)
+{
+ if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+ DrawScreenField(SCREENX(x), SCREENY(y));
+ else if (IS_MOVING(x, y))
{
- SetClipOrigin(src_bitmap, drawing_gc, dest_x - src_x, dest_y - src_y);
- BlitBitmapMasked(src_bitmap, drawto_field, src_x, src_y, width, height,
- dest_x, dest_y);
+ int newx,newy;
+
+ Moving2Blocked(x, y, &newx, &newy);
+ if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
+ DrawScreenField(SCREENX(newx), SCREENY(newy));
}
- else
- BlitBitmap(src_bitmap, drawto_field, src_x, src_y, width, height,
- dest_x, dest_y);
+ else if (IS_BLOCKED(x, y))
+ {
+ int oldx, oldy;
- MarkTileDirty(x, y);
+ Blocked2Moving(x, y, &oldx, &oldy);
+ if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
+ DrawScreenField(SCREENX(oldx), SCREENY(oldy));
+ }
}
-void DrawGraphicShiftedThruMask(int x, int y, int dx, int dy, int graphic,
- int frame, int cut_mode)
+void DrawMiniElement(int x, int y, int element)
{
- DrawGraphicShifted(x, y, dx, dy, graphic, frame, cut_mode, USE_MASKING);
+ int graphic;
+
+ graphic = el2edimg(element);
+ DrawMiniGraphic(x, y, graphic);
}
-void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
- int cut_mode, int mask_mode)
+void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
{
- int lx = LEVELX(x), ly = LEVELY(y);
- int graphic;
- int frame;
-
- if (IN_LEV_FIELD(lx, ly))
- {
- SetRandomAnimationValue(lx, ly);
+ int x = sx + scroll_x, y = sy + scroll_y;
- graphic = el_act_dir2img(element, GfxAction[lx][ly], GfxDir[lx][ly]);
- frame = getGraphicAnimationFrame(graphic, GfxFrame[lx][ly]);
- }
- else /* border element */
- {
- graphic = el2img(element);
- frame = getGraphicAnimationFrame(graphic, -1);
- }
-
- if (element == EL_EXPANDABLE_WALL)
- {
- boolean left_stopped = FALSE, right_stopped = FALSE;
-
- if (!IN_LEV_FIELD(lx - 1, ly) || IS_WALL(Feld[lx - 1][ly]))
- left_stopped = TRUE;
- if (!IN_LEV_FIELD(lx + 1, ly) || IS_WALL(Feld[lx + 1][ly]))
- right_stopped = TRUE;
-
- if (left_stopped && right_stopped)
- graphic = IMG_WALL;
- else if (left_stopped)
- {
- graphic = IMG_EXPANDABLE_WALL_GROWING_RIGHT;
- frame = graphic_info[graphic].anim_frames - 1;
- }
- else if (right_stopped)
- {
- graphic = IMG_EXPANDABLE_WALL_GROWING_LEFT;
- frame = graphic_info[graphic].anim_frames - 1;
- }
- }
-
- if (dx || dy)
- DrawGraphicShifted(x, y, dx, dy, graphic, frame, cut_mode, mask_mode);
- else if (mask_mode == USE_MASKING)
- DrawGraphicThruMask(x, y, graphic, frame);
+ if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
+ DrawMiniElement(sx, sy, EL_EMPTY);
+ else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
+ DrawMiniElement(sx, sy, Feld[x][y]);
else
- DrawGraphic(x, y, graphic, frame);
+ DrawMiniGraphic(sx, sy, el2edimg(getBorderElement(x, y)));
}
-void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
- int cut_mode, int mask_mode)
+void DrawEnvelopeBackground(int envelope_nr, int startx, int starty,
+ int x, int y, int xsize, int ysize, int font_nr)
{
- if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawScreenElementExt(SCREENX(x), SCREENY(y), dx, dy, element,
- cut_mode, mask_mode);
-}
+ int font_width = getFontWidth(font_nr);
+ int font_height = getFontHeight(font_nr);
+ int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr;
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int dst_x = SX + startx + x * font_width;
+ int dst_y = SY + starty + y * font_height;
+ int width = graphic_info[graphic].width;
+ int height = graphic_info[graphic].height;
+ int inner_width = MAX(width - 2 * font_width, font_width);
+ int inner_height = MAX(height - 2 * font_height, font_height);
+ int inner_sx = (width >= 3 * font_width ? font_width : 0);
+ int inner_sy = (height >= 3 * font_height ? font_height : 0);
+ boolean draw_masked = graphic_info[graphic].draw_masked;
-void DrawScreenElementShifted(int x, int y, int dx, int dy, int element,
- int cut_mode)
-{
- DrawScreenElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
-}
+ getGraphicSource(graphic, 0, &src_bitmap, &src_x, &src_y);
-void DrawLevelElementShifted(int x, int y, int dx, int dy, int element,
- int cut_mode)
-{
- DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
-}
+ if (src_bitmap == NULL || width < font_width || height < font_height)
+ {
+ ClearRectangle(drawto, dst_x, dst_y, font_width, font_height);
+ return;
+ }
-void DrawLevelElementThruMask(int x, int y, int element)
-{
- DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
-}
+ src_x += (x == 0 ? 0 : x == xsize - 1 ? width - font_width :
+ inner_sx + (x - 1) * font_width % inner_width);
+ src_y += (y == 0 ? 0 : y == ysize - 1 ? height - font_height :
+ inner_sy + (y - 1) * font_height % inner_height);
-void DrawLevelFieldThruMask(int x, int y)
-{
- DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
+ if (draw_masked)
+ {
+ SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(src_bitmap, drawto, src_x, src_y, font_width, font_height,
+ dst_x, dst_y);
+ }
+ else
+ BlitBitmap(src_bitmap, drawto, src_x, src_y, font_width, font_height,
+ dst_x, dst_y);
}
-#define TILE_GFX_ELEMENT(x, y) \
- (GfxElement[x][y] != EL_UNDEFINED && Feld[x][y] != EL_EXPLOSION ? \
- GfxElement[x][y] : Feld[x][y])
-
-static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame)
+void AnimateEnvelope(int envelope_nr, int anim_mode, int action)
{
- Bitmap *src_bitmap;
- int src_x, src_y;
- int sx = SCREENX(x), sy = SCREENY(y);
- int element;
- int width, height, cx, cy, i;
+ int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr;
#if 1
- int crumbled_border_size = graphic_info[graphic].border_size;
+ Bitmap *src_bitmap = graphic_info[graphic].bitmap;
+ int mask_mode = (src_bitmap != NULL ? BLIT_MASKED : BLIT_ON_BACKGROUND);
#else
- int snip = TILEX / 8; /* number of border pixels from "crumbled graphic" */
+ boolean draw_masked = graphic_info[graphic].draw_masked;
+ int mask_mode = (draw_masked ? BLIT_MASKED : BLIT_ON_BACKGROUND);
#endif
- static int xy[4][2] =
+ boolean ffwd_delay = (tape.playing && tape.fast_forward);
+ boolean no_delay = (tape.warp_forward);
+ unsigned long anim_delay = 0;
+ int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay);
+ int anim_delay_value = (no_delay ? 0 : frame_delay_value);
+ int font_nr = FONT_ENVELOPE_1 + envelope_nr;
+ int font_width = getFontWidth(font_nr);
+ int font_height = getFontHeight(font_nr);
+ int max_xsize = level.envelope_xsize[envelope_nr];
+ int max_ysize = level.envelope_ysize[envelope_nr];
+ int xstart = (anim_mode & ANIM_VERTICAL ? max_xsize : 0);
+ int ystart = (anim_mode & ANIM_HORIZONTAL ? max_ysize : 0);
+ int xend = max_xsize;
+ int yend = (anim_mode != ANIM_DEFAULT ? max_ysize : 0);
+ int xstep = (xstart < xend ? 1 : 0);
+ int ystep = (ystart < yend || xstep == 0 ? 1 : 0);
+ int x, y;
+
+ for (x = xstart, y = ystart; x <= xend && y <= yend; x += xstep, y += ystep)
{
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ int xsize = (action == ACTION_CLOSING ? xend - (x - xstart) : x) + 2;
+ int ysize = (action == ACTION_CLOSING ? yend - (y - ystart) : y) + 2;
+ int sx = (SXSIZE - xsize * font_width) / 2;
+ int sy = (SYSIZE - ysize * font_height) / 2;
+ int xx, yy;
-#if 0
- if (x == 0 && y == 7)
- printf("::: %d, %d [%d]\n", GfxElement[x][y], Feld[x][y],
- crumbled_border_size);
-#endif
+ SetDrawtoField(DRAW_BUFFERED);
- if (!IN_LEV_FIELD(x, y))
- return;
+ BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY);
- element = TILE_GFX_ELEMENT(x, y);
+ SetDrawtoField(DRAW_BACKBUFFER);
- /* crumble field itself */
- if (GFX_CRUMBLED(element) && !IS_MOVING(x, y))
- {
- if (!IN_SCR_FIELD(sx, sy))
- return;
+ for (yy = 0; yy < ysize; yy++) for (xx = 0; xx < xsize; xx++)
+ DrawEnvelopeBackground(envelope_nr, sx,sy, xx,yy, xsize, ysize, font_nr);
- getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
+ DrawTextToTextArea(SX + sx + font_width, SY + sy + font_height,
+ level.envelope_text[envelope_nr], font_nr, max_xsize,
+ xsize - 2, ysize - 2, mask_mode);
- for (i = 0; i < 4; i++)
- {
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
+ redraw_mask |= REDRAW_FIELD | REDRAW_FROM_BACKBUFFER;
+ BackToFront();
-#if 1
- element = (IN_LEV_FIELD(xx, yy) ? TILE_GFX_ELEMENT(xx, yy) :
- BorderElement);
-#else
- element = (IN_LEV_FIELD(xx, yy) ? Feld[xx][yy] : BorderElement);
-#endif
+ WaitUntilDelayReached(&anim_delay, anim_delay_value / 2);
+ }
+}
- /* check if neighbour field is of same type */
- if (GFX_CRUMBLED(element) && !IS_MOVING(xx, yy))
- continue;
+void ShowEnvelope(int envelope_nr)
+{
+ int element = EL_ENVELOPE_1 + envelope_nr;
+ int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr;
+ int sound_opening = element_info[element].sound[ACTION_OPENING];
+ int sound_closing = element_info[element].sound[ACTION_CLOSING];
+ boolean ffwd_delay = (tape.playing && tape.fast_forward);
+ boolean no_delay = (tape.warp_forward);
+ int normal_delay_value = ONE_SECOND_DELAY / (ffwd_delay ? 2 : 1);
+ int wait_delay_value = (no_delay ? 0 : normal_delay_value);
+ int anim_mode = graphic_info[graphic].anim_mode;
+ int main_anim_mode = (anim_mode == ANIM_NONE ? ANIM_VERTICAL|ANIM_HORIZONTAL:
+ anim_mode == ANIM_DEFAULT ? ANIM_VERTICAL : anim_mode);
-#if 0
- if (Feld[x][y] == EL_CUSTOM_START + 123)
- printf("::: crumble [%d] THE CHAOS ENGINE (%d, %d): %d, %d\n",
- i, Feld[x][y], element,
- GFX_CRUMBLED(element), IS_MOVING(x, y));
-#endif
+ game.envelope_active = TRUE; /* needed for RedrawPlayfield() events */
- if (i == 1 || i == 2)
- {
- width = crumbled_border_size;
- height = TILEY;
- cx = (i == 2 ? TILEX - crumbled_border_size : 0);
- cy = 0;
- }
- else
- {
- width = TILEX;
- height = crumbled_border_size;
- cx = 0;
- cy = (i == 3 ? TILEY - crumbled_border_size : 0);
- }
+ PlaySoundStereo(sound_opening, SOUND_MIDDLE);
- BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
- width, height, FX + sx * TILEX + cx, FY + sy * TILEY + cy);
- }
+ if (anim_mode == ANIM_DEFAULT)
+ AnimateEnvelope(envelope_nr, ANIM_DEFAULT, ACTION_OPENING);
- MarkTileDirty(sx, sy);
- }
- else /* crumble neighbour fields */
- {
-#if 0
- getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
-#endif
+ AnimateEnvelope(envelope_nr, main_anim_mode, ACTION_OPENING);
- for (i = 0; i < 4; i++)
- {
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
- int sxx = sx + xy[i][0];
- int syy = sy + xy[i][1];
+ if (tape.playing)
+ Delay(wait_delay_value);
+ else
+ WaitForEventToContinue();
-#if 1
- if (!IN_LEV_FIELD(xx, yy) ||
- !IN_SCR_FIELD(sxx, syy) ||
- IS_MOVING(xx, yy))
- continue;
+ PlaySoundStereo(sound_closing, SOUND_MIDDLE);
- element = TILE_GFX_ELEMENT(xx, yy);
+ if (anim_mode != ANIM_NONE)
+ AnimateEnvelope(envelope_nr, main_anim_mode, ACTION_CLOSING);
- if (!GFX_CRUMBLED(element))
- continue;
-#else
- if (!IN_LEV_FIELD(xx, yy) ||
- !IN_SCR_FIELD(sxx, syy) ||
- !GFX_CRUMBLED(Feld[xx][yy]) ||
- IS_MOVING(xx, yy))
- continue;
-#endif
-
-#if 1
- graphic = el_act2crm(Feld[xx][yy], ACTION_DEFAULT);
- crumbled_border_size = graphic_info[graphic].border_size;
-
- getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
-#endif
+ if (anim_mode == ANIM_DEFAULT)
+ AnimateEnvelope(envelope_nr, ANIM_DEFAULT, ACTION_CLOSING);
- if (i == 1 || i == 2)
- {
- width = crumbled_border_size;
- height = TILEY;
- cx = (i == 1 ? TILEX - crumbled_border_size : 0);
- cy = 0;
- }
- else
- {
- width = TILEX;
- height = crumbled_border_size;
- cx = 0;
- cy = (i == 0 ? TILEY - crumbled_border_size : 0);
- }
+ game.envelope_active = FALSE;
- BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
- width, height, FX + sxx * TILEX + cx, FY + syy * TILEY + cy);
+ SetDrawtoField(DRAW_BUFFERED);
- MarkTileDirty(sxx, syy);
- }
- }
+ redraw_mask |= REDRAW_FIELD;
+ BackToFront();
}
-void DrawLevelFieldCrumbledSand(int x, int y)
+void getMicroGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
{
-#if 1
- int graphic;
-
- if (!IN_LEV_FIELD(x, y))
- return;
-
- graphic = el_act2crm(Feld[x][y], ACTION_DEFAULT);
+ Bitmap *src_bitmap = graphic_info[graphic].bitmap;
+ int mini_startx = src_bitmap->width * 3 / 4;
+ int mini_starty = src_bitmap->height * 2 / 3;
+ int src_x = mini_startx + graphic_info[graphic].src_x / 8;
+ int src_y = mini_starty + graphic_info[graphic].src_y / 8;
- DrawLevelFieldCrumbledSandExt(x, y, graphic, 0);
-#else
- DrawLevelFieldCrumbledSandExt(x, y, IMG_SAND_CRUMBLED, 0);
-#endif
+ *bitmap = src_bitmap;
+ *x = src_x;
+ *y = src_y;
}
-void DrawLevelFieldCrumbledSandDigging(int x, int y, int direction,
- int step_frame)
+void DrawMicroElement(int xpos, int ypos, int element)
{
-#if 1
- int graphic1 = el_act_dir2img(GfxElement[x][y], ACTION_DIGGING, direction);
- int graphic2 = el_act_dir2crm(GfxElement[x][y], ACTION_DIGGING, direction);
-#else
- int graphic1 = el_act_dir2img(EL_SAND, ACTION_DIGGING, direction);
- int graphic2 = el_act_dir2img(EL_SAND_CRUMBLED, ACTION_DIGGING, direction);
-#endif
- int frame1 = getGraphicAnimationFrame(graphic1, step_frame);
- int frame2 = getGraphicAnimationFrame(graphic2, step_frame);
- int sx = SCREENX(x), sy = SCREENY(y);
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int graphic = el2preimg(element);
- DrawGraphic(sx, sy, graphic1, frame1);
- DrawLevelFieldCrumbledSandExt(x, y, graphic2, frame2);
+ getMicroGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
+ BlitBitmap(src_bitmap, drawto, src_x, src_y, MICRO_TILEX, MICRO_TILEY,
+ xpos, ypos);
}
-void DrawLevelFieldCrumbledSandNeighbours(int x, int y)
+void DrawLevel()
{
- int sx = SCREENX(x), sy = SCREENY(y);
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
- int i;
+ int x,y;
- for (i = 0; i < 4; i++)
- {
- int xx = x + xy[i][0];
- int yy = y + xy[i][1];
- int sxx = sx + xy[i][0];
- int syy = sy + xy[i][1];
+ SetDrawBackgroundMask(REDRAW_NONE);
+ ClearWindow();
- if (!IN_LEV_FIELD(xx, yy) ||
- !IN_SCR_FIELD(sxx, syy) ||
- !GFX_CRUMBLED(Feld[xx][yy]) ||
- IS_MOVING(xx, yy))
- continue;
+ for (x = BX1; x <= BX2; x++)
+ for (y = BY1; y <= BY2; y++)
+ DrawScreenField(x, y);
- DrawLevelField(xx, yy);
- }
+ redraw_mask |= REDRAW_FIELD;
}
-static int getBorderElement(int x, int y)
+void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
{
- int border[7][2] =
- {
- { EL_STEELWALL_TOPLEFT, EL_INVISIBLE_STEELWALL_TOPLEFT },
- { EL_STEELWALL_TOPRIGHT, EL_INVISIBLE_STEELWALL_TOPRIGHT },
- { EL_STEELWALL_BOTTOMLEFT, EL_INVISIBLE_STEELWALL_BOTTOMLEFT },
- { EL_STEELWALL_BOTTOMRIGHT, EL_INVISIBLE_STEELWALL_BOTTOMRIGHT },
- { EL_STEELWALL_VERTICAL, EL_INVISIBLE_STEELWALL_VERTICAL },
- { EL_STEELWALL_HORIZONTAL, EL_INVISIBLE_STEELWALL_HORIZONTAL },
- { EL_STEELWALL, EL_INVISIBLE_STEELWALL }
- };
- int steel_type = (BorderElement == EL_STEELWALL ? 0 : 1);
- int steel_position = (x == -1 && y == -1 ? 0 :
- x == lev_fieldx && y == -1 ? 1 :
- x == -1 && y == lev_fieldy ? 2 :
- x == lev_fieldx && y == lev_fieldy ? 3 :
- x == -1 || x == lev_fieldx ? 4 :
- y == -1 || y == lev_fieldy ? 5 : 6);
+ int x,y;
- return border[steel_position][steel_type];
-}
+ for (x = 0; x < size_x; x++)
+ for (y = 0; y < size_y; y++)
+ DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
-void DrawScreenElement(int x, int y, int element)
-{
- DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
- DrawLevelFieldCrumbledSand(LEVELX(x), LEVELY(y));
+ redraw_mask |= REDRAW_FIELD;
}
-void DrawLevelElement(int x, int y, int element)
+static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
{
- if (IN_LEV_FIELD(x, y) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawScreenElement(SCREENX(x), SCREENY(y), element);
-}
+ int x, y;
-void DrawScreenField(int x, int y)
-{
- int lx = LEVELX(x), ly = LEVELY(y);
- int element, content;
+ DrawBackground(xpos, ypos, MICROLEVEL_XSIZE, MICROLEVEL_YSIZE);
- if (!IN_LEV_FIELD(lx, ly))
+ if (lev_fieldx < STD_LEV_FIELDX)
+ xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
+ if (lev_fieldy < STD_LEV_FIELDY)
+ ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
+
+ xpos += MICRO_TILEX;
+ ypos += MICRO_TILEY;
+
+ for (x = -1; x <= STD_LEV_FIELDX; x++)
{
- if (lx < -1 || lx > lev_fieldx || ly < -1 || ly > lev_fieldy)
- element = EL_EMPTY;
- else
- element = getBorderElement(lx, ly);
+ for (y = -1; y <= STD_LEV_FIELDY; y++)
+ {
+ int lx = from_x + x, ly = from_y + y;
- DrawScreenElement(x, y, element);
- return;
+ if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
+ DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
+ level.field[lx][ly]);
+ else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1
+ && BorderElement != EL_EMPTY)
+ DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
+ getBorderElement(lx, ly));
+ }
}
- element = Feld[lx][ly];
- content = Store[lx][ly];
+ redraw_mask |= REDRAW_MICROLEVEL;
+}
- if (IS_MOVING(lx, ly))
- {
- int horiz_move = (MovDir[lx][ly] == MV_LEFT || MovDir[lx][ly] == MV_RIGHT);
- boolean cut_mode = NO_CUTTING;
+#define MICROLABEL_EMPTY 0
+#define MICROLABEL_LEVEL_NAME 1
+#define MICROLABEL_LEVEL_AUTHOR_HEAD 2
+#define MICROLABEL_LEVEL_AUTHOR 3
+#define MICROLABEL_IMPORTED_FROM_HEAD 4
+#define MICROLABEL_IMPORTED_FROM 5
+#define MICROLABEL_IMPORTED_BY_HEAD 6
+#define MICROLABEL_IMPORTED_BY 7
- if (element == EL_QUICKSAND_EMPTYING ||
- element == EL_MAGIC_WALL_EMPTYING ||
- element == EL_BD_MAGIC_WALL_EMPTYING ||
- element == EL_AMOEBA_DROPPING)
- cut_mode = CUT_ABOVE;
- else if (element == EL_QUICKSAND_FILLING ||
- element == EL_MAGIC_WALL_FILLING ||
- element == EL_BD_MAGIC_WALL_FILLING)
- cut_mode = CUT_BELOW;
+static void DrawMicroLevelLabelExt(int mode)
+{
+ char label_text[MAX_OUTPUT_LINESIZE + 1];
+ int max_len_label_text;
+ int font_nr = FONT_TEXT_2;
+ int i;
- if (cut_mode == CUT_ABOVE)
- DrawScreenElementShifted(x, y, 0, 0, element, NO_CUTTING);
- else
- DrawScreenElement(x, y, EL_EMPTY);
+ if (mode == MICROLABEL_LEVEL_AUTHOR_HEAD ||
+ mode == MICROLABEL_IMPORTED_FROM_HEAD ||
+ mode == MICROLABEL_IMPORTED_BY_HEAD)
+ font_nr = FONT_TEXT_3;
- if (horiz_move)
- DrawScreenElementShifted(x, y, MovPos[lx][ly], 0, element, NO_CUTTING);
- else if (cut_mode == NO_CUTTING)
- DrawScreenElementShifted(x, y, 0, MovPos[lx][ly], element, cut_mode);
- else
- DrawScreenElementShifted(x, y, 0, MovPos[lx][ly], content, cut_mode);
+ max_len_label_text = SXSIZE / getFontWidth(font_nr);
- if (content == EL_ACID)
- {
- int dir = MovDir[lx][ly];
- int newlx = lx + (dir == MV_LEFT ? -1 : dir == MV_RIGHT ? +1 : 0);
- int newly = ly + (dir == MV_UP ? -1 : dir == MV_DOWN ? +1 : 0);
+#if 1
- DrawLevelElementThruMask(newlx, newly, EL_ACID);
- }
- }
- else if (IS_BLOCKED(lx, ly))
+ for (i = 0; i < max_len_label_text; i++)
+ label_text[i] = ' ';
+ label_text[max_len_label_text] = '\0';
+
+ if (strlen(label_text) > 0)
{
- int oldx, oldy;
- int sx, sy;
- int horiz_move;
- boolean cut_mode = NO_CUTTING;
- int element_old, content_old;
+ int lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2;
+ int lypos = MICROLABEL2_YPOS;
- Blocked2Moving(lx, ly, &oldx, &oldy);
- sx = SCREENX(oldx);
- sy = SCREENY(oldy);
- horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
- MovDir[oldx][oldy] == MV_RIGHT);
+ DrawText(lxpos, lypos, label_text, font_nr);
+ }
- element_old = Feld[oldx][oldy];
- content_old = Store[oldx][oldy];
+#else
- if (element_old == EL_QUICKSAND_EMPTYING ||
- element_old == EL_MAGIC_WALL_EMPTYING ||
- element_old == EL_BD_MAGIC_WALL_EMPTYING ||
- element_old == EL_AMOEBA_DROPPING)
- cut_mode = CUT_ABOVE;
+ DrawBackground(SX, MICROLABEL2_YPOS, SXSIZE, getFontHeight(font_nr));
- DrawScreenElement(x, y, EL_EMPTY);
+#endif
- if (horiz_move)
- DrawScreenElementShifted(sx, sy, MovPos[oldx][oldy], 0, element_old,
- NO_CUTTING);
- else if (cut_mode == NO_CUTTING)
- DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], element_old,
- cut_mode);
- else
- DrawScreenElementShifted(sx, sy, 0, MovPos[oldx][oldy], content_old,
- cut_mode);
+ strncpy(label_text,
+ (mode == MICROLABEL_LEVEL_NAME ? level.name :
+ mode == MICROLABEL_LEVEL_AUTHOR_HEAD ? "created by" :
+ mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
+ mode == MICROLABEL_IMPORTED_FROM_HEAD ? "imported from" :
+ mode == MICROLABEL_IMPORTED_FROM ? leveldir_current->imported_from :
+ mode == MICROLABEL_IMPORTED_BY_HEAD ? "imported by" :
+ mode == MICROLABEL_IMPORTED_BY ? leveldir_current->imported_by :""),
+ max_len_label_text);
+ label_text[max_len_label_text] = '\0';
+
+ if (strlen(label_text) > 0)
+ {
+ int lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2;
+ int lypos = MICROLABEL2_YPOS;
+
+ DrawText(lxpos, lypos, label_text, font_nr);
}
- else if (IS_DRAWABLE(element))
- DrawScreenElement(x, y, element);
- else
- DrawScreenElement(x, y, EL_EMPTY);
+
+ redraw_mask |= REDRAW_MICROLEVEL;
}
-void DrawLevelField(int x, int y)
+void DrawMicroLevel(int xpos, int ypos, boolean restart)
{
- if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawScreenField(SCREENX(x), SCREENY(y));
- else if (IS_MOVING(x, y))
+ static unsigned long scroll_delay = 0;
+ static unsigned long label_delay = 0;
+ static int from_x, from_y, scroll_direction;
+ static int label_state, label_counter;
+ int last_game_status = game_status; /* save current game status */
+
+ /* force PREVIEW font on preview level */
+ game_status = GAME_MODE_PSEUDO_PREVIEW;
+
+ if (restart)
{
- int newx,newy;
+ from_x = from_y = 0;
+ scroll_direction = MV_RIGHT;
+ label_state = 1;
+ label_counter = 0;
- Moving2Blocked(x, y, &newx, &newy);
- if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
- DrawScreenField(SCREENX(newx), SCREENY(newy));
+ DrawMicroLevelExt(xpos, ypos, from_x, from_y);
+ DrawMicroLevelLabelExt(label_state);
+
+ /* initialize delay counters */
+ DelayReached(&scroll_delay, 0);
+ DelayReached(&label_delay, 0);
+
+ if (leveldir_current->name)
+ {
+ char label_text[MAX_OUTPUT_LINESIZE + 1];
+ int font_nr = FONT_TEXT_1;
+ int max_len_label_text = SXSIZE / getFontWidth(font_nr);
+ int lxpos, lypos;
+
+ strncpy(label_text, leveldir_current->name, max_len_label_text);
+ label_text[max_len_label_text] = '\0';
+
+ lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2;
+ lypos = SY + MICROLABEL1_YPOS;
+
+ DrawText(lxpos, lypos, label_text, font_nr);
+ }
+
+ game_status = last_game_status; /* restore current game status */
+
+ return;
}
- else if (IS_BLOCKED(x, y))
+
+ /* scroll micro level, if needed */
+ if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
+ DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
{
- int oldx, oldy;
+ switch (scroll_direction)
+ {
+ case MV_LEFT:
+ if (from_x > 0)
+ from_x--;
+ else
+ scroll_direction = MV_UP;
+ break;
- Blocked2Moving(x, y, &oldx, &oldy);
- if (IN_SCR_FIELD(SCREENX(oldx), SCREENY(oldy)))
- DrawScreenField(SCREENX(oldx), SCREENY(oldy));
+ case MV_RIGHT:
+ if (from_x < lev_fieldx - STD_LEV_FIELDX)
+ from_x++;
+ else
+ scroll_direction = MV_DOWN;
+ break;
+
+ case MV_UP:
+ if (from_y > 0)
+ from_y--;
+ else
+ scroll_direction = MV_RIGHT;
+ break;
+
+ case MV_DOWN:
+ if (from_y < lev_fieldy - STD_LEV_FIELDY)
+ from_y++;
+ else
+ scroll_direction = MV_LEFT;
+ break;
+
+ default:
+ break;
+ }
+
+ DrawMicroLevelExt(xpos, ypos, from_x, from_y);
}
-}
-void DrawMiniElement(int x, int y, int element)
-{
- int graphic;
+ /* !!! THIS ALL SUCKS -- SHOULD BE CLEANLY REWRITTEN !!! */
+ /* redraw micro level label, if needed */
+ if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
+ strcmp(level.author, ANONYMOUS_NAME) != 0 &&
+ strcmp(level.author, leveldir_current->name) != 0 &&
+ DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
+ {
+ int max_label_counter = 23;
- graphic = el2edimg(element);
- DrawMiniGraphic(x, y, graphic);
+ if (leveldir_current->imported_from != NULL &&
+ strlen(leveldir_current->imported_from) > 0)
+ max_label_counter += 14;
+ if (leveldir_current->imported_by != NULL &&
+ strlen(leveldir_current->imported_by) > 0)
+ max_label_counter += 14;
+
+ label_counter = (label_counter + 1) % max_label_counter;
+ label_state = (label_counter >= 0 && label_counter <= 7 ?
+ MICROLABEL_LEVEL_NAME :
+ label_counter >= 9 && label_counter <= 12 ?
+ MICROLABEL_LEVEL_AUTHOR_HEAD :
+ label_counter >= 14 && label_counter <= 21 ?
+ MICROLABEL_LEVEL_AUTHOR :
+ label_counter >= 23 && label_counter <= 26 ?
+ MICROLABEL_IMPORTED_FROM_HEAD :
+ label_counter >= 28 && label_counter <= 35 ?
+ MICROLABEL_IMPORTED_FROM :
+ label_counter >= 37 && label_counter <= 40 ?
+ MICROLABEL_IMPORTED_BY_HEAD :
+ label_counter >= 42 && label_counter <= 49 ?
+ MICROLABEL_IMPORTED_BY : MICROLABEL_EMPTY);
+
+ if (leveldir_current->imported_from == NULL &&
+ (label_state == MICROLABEL_IMPORTED_FROM_HEAD ||
+ label_state == MICROLABEL_IMPORTED_FROM))
+ label_state = (label_state == MICROLABEL_IMPORTED_FROM_HEAD ?
+ MICROLABEL_IMPORTED_BY_HEAD : MICROLABEL_IMPORTED_BY);
+
+ DrawMicroLevelLabelExt(label_state);
+ }
+
+ game_status = last_game_status; /* restore current game status */
}
-void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y)
+inline void DrawGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y,
+ int graphic, int sync_frame, int mask_mode)
{
- int x = sx + scroll_x, y = sy + scroll_y;
+ int frame = getGraphicAnimationFrame(graphic, sync_frame);
- if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
- DrawMiniElement(sx, sy, EL_EMPTY);
- else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
- DrawMiniElement(sx, sy, Feld[x][y]);
+ if (mask_mode == USE_MASKING)
+ DrawGraphicThruMaskExt(dst_bitmap, x, y, graphic, frame);
else
- DrawMiniGraphic(sx, sy, el2edimg(getBorderElement(x, y)));
+ DrawGraphicExt(dst_bitmap, x, y, graphic, frame);
}
-void DrawEnvelopeBackground(int envelope_nr, int startx, int starty,
- int x, int y, int xsize, int ysize, int font_nr)
+inline void DrawGraphicAnimation(int x, int y, int graphic)
{
- int font_width = getFontWidth(font_nr);
- int font_height = getFontHeight(font_nr);
- int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr;
- Bitmap *src_bitmap;
- int src_x, src_y;
- int dst_x = SX + startx + x * font_width;
- int dst_y = SY + starty + y * font_height;
- int width = graphic_info[graphic].width;
- int height = graphic_info[graphic].height;
- int inner_width = MAX(width - 2 * font_width, font_width);
- int inner_height = MAX(height - 2 * font_height, font_height);
- int inner_sx = (width >= 3 * font_width ? font_width : 0);
- int inner_sy = (height >= 3 * font_height ? font_height : 0);
- boolean draw_masked = graphic_info[graphic].draw_masked;
-
- getGraphicSource(graphic, 0, &src_bitmap, &src_x, &src_y);
+ int lx = LEVELX(x), ly = LEVELY(y);
- if (src_bitmap == NULL || width < font_width || height < font_height)
- {
- ClearRectangle(drawto, dst_x, dst_y, font_width, font_height);
+ if (!IN_SCR_FIELD(x, y))
return;
- }
- src_x += (x == 0 ? 0 : x == xsize - 1 ? width - font_width :
- inner_sx + (x - 1) * font_width % inner_width);
- src_y += (y == 0 ? 0 : y == ysize - 1 ? height - font_height :
- inner_sy + (y - 1) * font_height % inner_height);
+ DrawGraphicAnimationExt(drawto_field, FX + x * TILEX, FY + y * TILEY,
+ graphic, GfxFrame[lx][ly], NO_MASKING);
+ MarkTileDirty(x, y);
+}
- if (draw_masked)
- {
- SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
- dst_x - src_x, dst_y - src_y);
- BlitBitmapMasked(src_bitmap, drawto, src_x, src_y, font_width, font_height,
- dst_x, dst_y);
- }
- else
- BlitBitmap(src_bitmap, drawto, src_x, src_y, font_width, font_height,
- dst_x, dst_y);
+void DrawLevelGraphicAnimation(int x, int y, int graphic)
+{
+ DrawGraphicAnimation(SCREENX(x), SCREENY(y), graphic);
}
-void AnimateEnvelope(int envelope_nr, int anim_mode, int action)
+void DrawLevelElementAnimation(int x, int y, int element)
{
- int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr;
#if 1
- Bitmap *src_bitmap = graphic_info[graphic].bitmap;
- int mask_mode = (src_bitmap != NULL ? BLIT_MASKED : BLIT_ON_BACKGROUND);
+ int graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]);
+
+ DrawGraphicAnimation(SCREENX(x), SCREENY(y), graphic);
#else
- boolean draw_masked = graphic_info[graphic].draw_masked;
- int mask_mode = (draw_masked ? BLIT_MASKED : BLIT_ON_BACKGROUND);
+ DrawGraphicAnimation(SCREENX(x), SCREENY(y), el2img(element));
#endif
- boolean ffwd_delay = (tape.playing && tape.fast_forward);
- boolean no_delay = (tape.warp_forward);
- unsigned long anim_delay = 0;
- int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay);
- int anim_delay_value = (no_delay ? 0 : frame_delay_value);
- int font_nr = FONT_ENVELOPE_1 + envelope_nr;
- int font_width = getFontWidth(font_nr);
- int font_height = getFontHeight(font_nr);
- int max_xsize = level.envelope_xsize[envelope_nr];
- int max_ysize = level.envelope_ysize[envelope_nr];
- int xstart = (anim_mode & ANIM_VERTICAL ? max_xsize : 0);
- int ystart = (anim_mode & ANIM_HORIZONTAL ? max_ysize : 0);
- int xend = max_xsize;
- int yend = (anim_mode != ANIM_DEFAULT ? max_ysize : 0);
- int xstep = (xstart < xend ? 1 : 0);
- int ystep = (ystart < yend || xstep == 0 ? 1 : 0);
- int x, y;
-
- for (x = xstart, y = ystart; x <= xend && y <= yend; x += xstep, y += ystep)
- {
- int xsize = (action == ACTION_CLOSING ? xend - (x - xstart) : x) + 2;
- int ysize = (action == ACTION_CLOSING ? yend - (y - ystart) : y) + 2;
- int sx = (SXSIZE - xsize * font_width) / 2;
- int sy = (SYSIZE - ysize * font_height) / 2;
- int xx, yy;
-
- SetDrawtoField(DRAW_BUFFERED);
-
- BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY);
+}
- SetDrawtoField(DRAW_BACKBUFFER);
+inline void DrawLevelGraphicAnimationIfNeeded(int x, int y, int graphic)
+{
+ int sx = SCREENX(x), sy = SCREENY(y);
- for (yy = 0; yy < ysize; yy++) for (xx = 0; xx < xsize; xx++)
- DrawEnvelopeBackground(envelope_nr, sx,sy, xx,yy, xsize, ysize, font_nr);
+ if (!IN_LEV_FIELD(x, y) || !IN_SCR_FIELD(sx, sy))
+ return;
- DrawTextToTextArea(SX + sx + font_width, SY + sy + font_height,
- level.envelope_text[envelope_nr], font_nr, max_xsize,
- xsize - 2, ysize - 2, mask_mode);
+ if (!IS_NEW_FRAME(GfxFrame[x][y], graphic))
+ return;
- redraw_mask |= REDRAW_FIELD | REDRAW_FROM_BACKBUFFER;
- BackToFront();
+ DrawGraphicAnimation(sx, sy, graphic);
- WaitUntilDelayReached(&anim_delay, anim_delay_value / 2);
- }
+ if (GFX_CRUMBLED(Feld[x][y]))
+ DrawLevelFieldCrumbledSand(x, y);
}
-void ShowEnvelope(int envelope_nr)
+void DrawLevelElementAnimationIfNeeded(int x, int y, int element)
{
- int element = EL_ENVELOPE_1 + envelope_nr;
- int graphic = IMG_BACKGROUND_ENVELOPE_1 + envelope_nr;
- int sound_opening = element_info[element].sound[ACTION_OPENING];
- int sound_closing = element_info[element].sound[ACTION_CLOSING];
- boolean ffwd_delay = (tape.playing && tape.fast_forward);
- boolean no_delay = (tape.warp_forward);
- int normal_delay_value = ONE_SECOND_DELAY / (ffwd_delay ? 2 : 1);
- int wait_delay_value = (no_delay ? 0 : normal_delay_value);
- int anim_mode = graphic_info[graphic].anim_mode;
- int main_anim_mode = (anim_mode == ANIM_NONE ? ANIM_VERTICAL|ANIM_HORIZONTAL:
- anim_mode == ANIM_DEFAULT ? ANIM_VERTICAL : anim_mode);
-
- game.envelope_active = TRUE; /* needed for RedrawPlayfield() events */
+ int sx = SCREENX(x), sy = SCREENY(y);
+ int graphic;
- PlaySoundStereo(sound_opening, SOUND_MIDDLE);
+ if (!IN_LEV_FIELD(x, y) || !IN_SCR_FIELD(sx, sy))
+ return;
- if (anim_mode == ANIM_DEFAULT)
- AnimateEnvelope(envelope_nr, ANIM_DEFAULT, ACTION_OPENING);
+ graphic = el_act_dir2img(element, GfxAction[x][y], GfxDir[x][y]);
- AnimateEnvelope(envelope_nr, main_anim_mode, ACTION_OPENING);
+ if (!IS_NEW_FRAME(GfxFrame[x][y], graphic))
+ return;
- if (tape.playing)
- Delay(wait_delay_value);
- else
- WaitForEventToContinue();
+ DrawGraphicAnimation(sx, sy, graphic);
- PlaySoundStereo(sound_closing, SOUND_MIDDLE);
+ if (GFX_CRUMBLED(element))
+ DrawLevelFieldCrumbledSand(x, y);
+}
- if (anim_mode != ANIM_NONE)
- AnimateEnvelope(envelope_nr, main_anim_mode, ACTION_CLOSING);
+static int getPlayerGraphic(struct PlayerInfo *player, int move_dir)
+{
+ if (player->use_murphy_graphic)
+ {
+ /* this works only because currently only one player can be "murphy" ... */
+ static int last_horizontal_dir = MV_LEFT;
+ int graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, move_dir);
- if (anim_mode == ANIM_DEFAULT)
- AnimateEnvelope(envelope_nr, ANIM_DEFAULT, ACTION_CLOSING);
+ if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
+ last_horizontal_dir = move_dir;
- game.envelope_active = FALSE;
+ if (graphic == IMG_SP_MURPHY) /* undefined => use special graphic */
+ {
+ int direction = (player->is_snapping ? move_dir : last_horizontal_dir);
- SetDrawtoField(DRAW_BUFFERED);
+ graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, direction);
+ }
- redraw_mask |= REDRAW_FIELD;
- BackToFront();
+ return graphic;
+ }
+ else
+ return el_act_dir2img(player->element_nr, player->GfxAction, move_dir);
}
-void getMicroGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
+static boolean equalGraphics(int graphic1, int graphic2)
{
- Bitmap *src_bitmap = graphic_info[graphic].bitmap;
- int mini_startx = src_bitmap->width * 3 / 4;
- int mini_starty = src_bitmap->height * 2 / 3;
- int src_x = mini_startx + graphic_info[graphic].src_x / 8;
- int src_y = mini_starty + graphic_info[graphic].src_y / 8;
+ struct GraphicInfo *g1 = &graphic_info[graphic1];
+ struct GraphicInfo *g2 = &graphic_info[graphic2];
- *bitmap = src_bitmap;
- *x = src_x;
- *y = src_y;
+ return (g1->bitmap == g2->bitmap &&
+ g1->src_x == g2->src_x &&
+ g1->src_y == g2->src_y &&
+ g1->anim_frames == g2->anim_frames &&
+ g1->anim_delay == g2->anim_delay &&
+ g1->anim_mode == g2->anim_mode);
}
-void DrawMicroElement(int xpos, int ypos, int element)
+void DrawAllPlayers()
{
- Bitmap *src_bitmap;
- int src_x, src_y;
- int graphic = el2preimg(element);
+ int i;
- getMicroGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
- BlitBitmap(src_bitmap, drawto, src_x, src_y, MICRO_TILEX, MICRO_TILEY,
- xpos, ypos);
+ for (i = 0; i < MAX_PLAYERS; i++)
+ if (stored_player[i].active)
+ DrawPlayer(&stored_player[i]);
}
-void DrawLevel()
+void DrawPlayerField(int x, int y)
{
- int x,y;
-
- SetDrawBackgroundMask(REDRAW_NONE);
- ClearWindow();
-
- for (x = BX1; x <= BX2; x++)
- for (y = BY1; y <= BY2; y++)
- DrawScreenField(x, y);
+ if (!IS_PLAYER(x, y))
+ return;
- redraw_mask |= REDRAW_FIELD;
+ DrawPlayer(PLAYERINFO(x, y));
}
-void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
+void DrawPlayer(struct PlayerInfo *player)
{
- int x,y;
+ int jx = player->jx;
+ int jy = player->jy;
+ int move_dir = player->MovDir;
+#if 0
+ int last_jx = player->last_jx;
+ int last_jy = player->last_jy;
+ int next_jx = jx + (jx - last_jx);
+ int next_jy = jy + (jy - last_jy);
+ boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
+#else
+ int dx = (move_dir == MV_LEFT ? -1 : move_dir == MV_RIGHT ? +1 : 0);
+ int dy = (move_dir == MV_UP ? -1 : move_dir == MV_DOWN ? +1 : 0);
+ int last_jx = (player->is_moving ? jx - dx : jx);
+ int last_jy = (player->is_moving ? jy - dy : jy);
+ int next_jx = jx + dx;
+ int next_jy = jy + dy;
+ boolean player_is_moving = (player->MovPos ? TRUE : FALSE);
+#endif
+ int sx = SCREENX(jx), sy = SCREENY(jy);
+ int sxx = 0, syy = 0;
+ int element = Feld[jx][jy], last_element = Feld[last_jx][last_jy];
+ int graphic;
+ int action = ACTION_DEFAULT;
+ int last_player_graphic = getPlayerGraphic(player, move_dir);
+ int last_player_frame = player->Frame;
+ int frame = 0;
- for (x = 0; x < size_x; x++)
- for (y = 0; y < size_y; y++)
- DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
+ if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
+ return;
- redraw_mask |= REDRAW_FIELD;
-}
+#if DEBUG
+ if (!IN_LEV_FIELD(jx, jy))
+ {
+ printf("DrawPlayerField(): x = %d, y = %d\n",jx,jy);
+ printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
+ printf("DrawPlayerField(): This should never happen!\n");
+ return;
+ }
+#endif
-static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
-{
- int x, y;
+ if (element == EL_EXPLOSION)
+ return;
- DrawBackground(xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
+ action = (player->is_pushing ? ACTION_PUSHING :
+ player->is_digging ? ACTION_DIGGING :
+ player->is_collecting ? ACTION_COLLECTING :
+ player->is_moving ? ACTION_MOVING :
+ player->is_snapping ? ACTION_SNAPPING :
+ player->is_dropping ? ACTION_DROPPING :
+ player->is_waiting ? player->action_waiting : ACTION_DEFAULT);
- if (lev_fieldx < STD_LEV_FIELDX)
- xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
- if (lev_fieldy < STD_LEV_FIELDY)
- ypos += (STD_LEV_FIELDY - lev_fieldy) / 2 * MICRO_TILEY;
+ InitPlayerGfxAnimation(player, action, move_dir);
- xpos += MICRO_TILEX;
- ypos += MICRO_TILEY;
+ /* ----------------------------------------------------------------------- */
+ /* draw things in the field the player is leaving, if needed */
+ /* ----------------------------------------------------------------------- */
- for (x = -1; x <= STD_LEV_FIELDX; x++)
+#if 1
+ if (player->is_moving)
+#else
+ if (player_is_moving)
+#endif
{
- for (y = -1; y <= STD_LEV_FIELDY; y++)
+ if (Back[last_jx][last_jy] && IS_DRAWABLE(last_element))
{
- int lx = from_x + x, ly = from_y + y;
+ DrawLevelElement(last_jx, last_jy, Back[last_jx][last_jy]);
- if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
- DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
- level.field[lx][ly]);
- else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1
- && BorderElement != EL_EMPTY)
- DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
- getBorderElement(lx, ly));
+ if (last_element == EL_DYNAMITE_ACTIVE ||
+ last_element == EL_SP_DISK_RED_ACTIVE)
+ DrawDynamite(last_jx, last_jy);
+ else
+ DrawLevelFieldThruMask(last_jx, last_jy);
}
+ else if (last_element == EL_DYNAMITE_ACTIVE ||
+ last_element == EL_SP_DISK_RED_ACTIVE)
+ DrawDynamite(last_jx, last_jy);
+ else
+ DrawLevelField(last_jx, last_jy);
+
+ if (player->is_pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
+ DrawLevelElement(next_jx, next_jy, EL_EMPTY);
}
- redraw_mask |= REDRAW_MICROLEVEL;
-}
+ if (!IN_SCR_FIELD(sx, sy))
+ return;
-#define MICROLABEL_EMPTY 0
-#define MICROLABEL_LEVEL_NAME 1
-#define MICROLABEL_CREATED_BY 2
-#define MICROLABEL_LEVEL_AUTHOR 3
-#define MICROLABEL_IMPORTED_FROM 4
-#define MICROLABEL_LEVEL_IMPORT_INFO 5
+ if (setup.direct_draw)
+ SetDrawtoField(DRAW_BUFFERED);
-static void DrawMicroLevelLabelExt(int mode)
-{
- char label_text[MAX_OUTPUT_LINESIZE + 1];
- int max_len_label_text;
- int font_nr = FONT_TEXT_2;
+ /* ----------------------------------------------------------------------- */
+ /* draw things behind the player, if needed */
+ /* ----------------------------------------------------------------------- */
- if (mode == MICROLABEL_CREATED_BY || mode == MICROLABEL_IMPORTED_FROM)
- font_nr = FONT_TEXT_3;
+ if (Back[jx][jy])
+ DrawLevelElement(jx, jy, Back[jx][jy]);
+ else if (IS_ACTIVE_BOMB(element))
+ DrawLevelElement(jx, jy, EL_EMPTY);
+ else
+ {
+ if (player_is_moving && GfxElement[jx][jy] != EL_UNDEFINED)
+ {
+ if (GFX_CRUMBLED(GfxElement[jx][jy]))
+ DrawLevelFieldCrumbledSandDigging(jx, jy, move_dir, player->StepFrame);
+ else
+ {
+ int old_element = GfxElement[jx][jy];
+ int old_graphic = el_act_dir2img(old_element, action, move_dir);
+ int frame = getGraphicAnimationFrame(old_graphic, player->StepFrame);
- max_len_label_text = SXSIZE / getFontWidth(font_nr);
+ DrawGraphic(sx, sy, old_graphic, frame);
+ }
+ }
+ else
+ {
+ GfxElement[jx][jy] = EL_UNDEFINED;
- DrawBackground(SX, MICROLABEL_YPOS, SXSIZE, getFontHeight(font_nr));
+ DrawLevelField(jx, jy);
+ }
+ }
- strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
- mode == MICROLABEL_CREATED_BY ? "created by" :
- mode == MICROLABEL_LEVEL_AUTHOR ? level.author :
- mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
- mode == MICROLABEL_LEVEL_IMPORT_INFO ?
- leveldir_current->imported_from : ""),
- max_len_label_text);
- label_text[max_len_label_text] = '\0';
+ /* ----------------------------------------------------------------------- */
+ /* draw player himself */
+ /* ----------------------------------------------------------------------- */
- if (strlen(label_text) > 0)
- {
- int lxpos = SX + (SXSIZE - getTextWidth(label_text, font_nr)) / 2;
- int lypos = MICROLABEL_YPOS;
+#if 1
- DrawText(lxpos, lypos, label_text, font_nr);
- }
-
- redraw_mask |= REDRAW_MICROLEVEL;
-}
+ graphic = getPlayerGraphic(player, move_dir);
-void DrawMicroLevel(int xpos, int ypos, boolean restart)
-{
- static unsigned long scroll_delay = 0;
- static unsigned long label_delay = 0;
- static int from_x, from_y, scroll_direction;
- static int label_state, label_counter;
- int last_game_status = game_status; /* save current game status */
+ /* in the case of changed player action or direction, prevent the current
+ animation frame from being restarted for identical animations */
+ if (player->Frame == 0 && equalGraphics(graphic, last_player_graphic))
+ player->Frame = last_player_frame;
- /* force PREVIEW font on preview level */
- game_status = GAME_MODE_PSEUDO_PREVIEW;
+#else
- if (restart)
+ if (player->use_murphy_graphic)
{
- from_x = from_y = 0;
- scroll_direction = MV_RIGHT;
- label_state = 1;
- label_counter = 0;
+ static int last_horizontal_dir = MV_LEFT;
- DrawMicroLevelExt(xpos, ypos, from_x, from_y);
- DrawMicroLevelLabelExt(label_state);
+ if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
+ last_horizontal_dir = move_dir;
- /* initialize delay counters */
- DelayReached(&scroll_delay, 0);
- DelayReached(&label_delay, 0);
+ graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, move_dir);
- if (leveldir_current->name)
+ if (graphic == IMG_SP_MURPHY) /* undefined => use special graphic */
{
- int text_width = getTextWidth(leveldir_current->name, FONT_TEXT_1);
- int lxpos = SX + (SXSIZE - text_width) / 2;
- int lypos = SY + 352;
+ int direction = (player->is_snapping ? move_dir : last_horizontal_dir);
- DrawText(lxpos, lypos, leveldir_current->name, FONT_TEXT_1);
+ graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, direction);
}
+ }
+ else
+ graphic = el_act_dir2img(player->element_nr, player->GfxAction, move_dir);
- game_status = last_game_status; /* restore current game status */
+#endif
- return;
+ frame = getGraphicAnimationFrame(graphic, player->Frame);
+
+ if (player->GfxPos)
+ {
+ if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
+ sxx = player->GfxPos;
+ else
+ syy = player->GfxPos;
}
- /* scroll micro level, if needed */
- if ((lev_fieldx > STD_LEV_FIELDX || lev_fieldy > STD_LEV_FIELDY) &&
- DelayReached(&scroll_delay, MICROLEVEL_SCROLL_DELAY))
+ if (!setup.soft_scrolling && ScreenMovPos)
+ sxx = syy = 0;
+
+ DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING);
+
+ if (SHIELD_ON(player))
{
- switch (scroll_direction)
- {
- case MV_LEFT:
- if (from_x > 0)
- from_x--;
- else
- scroll_direction = MV_UP;
- break;
+ int graphic = (player->shield_deadly_time_left ? IMG_SHIELD_DEADLY_ACTIVE :
+ IMG_SHIELD_NORMAL_ACTIVE);
+ int frame = getGraphicAnimationFrame(graphic, -1);
- case MV_RIGHT:
- if (from_x < lev_fieldx - STD_LEV_FIELDX)
- from_x++;
- else
- scroll_direction = MV_DOWN;
- break;
+ DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING);
+ }
- case MV_UP:
- if (from_y > 0)
- from_y--;
- else
- scroll_direction = MV_RIGHT;
- break;
+ /* ----------------------------------------------------------------------- */
+ /* draw things the player is pushing, if needed */
+ /* ----------------------------------------------------------------------- */
- case MV_DOWN:
- if (from_y < lev_fieldy - STD_LEV_FIELDY)
- from_y++;
- else
- scroll_direction = MV_LEFT;
- break;
+#if 0
+ printf("::: %d, %d [%d, %d] [%d]\n",
+ player->is_pushing, player_is_moving, player->GfxAction,
+ player->is_moving, player_is_moving);
+#endif
- default:
- break;
+#if 1
+ if (player->is_pushing && player->is_moving)
+#else
+ if (player->is_pushing && player_is_moving)
+#endif
+ {
+#if 1
+ int px = SCREENX(jx), py = SCREENY(jy);
+ int pxx = (TILEX - ABS(sxx)) * dx;
+ int pyy = (TILEY - ABS(syy)) * dy;
+#else
+ int px = SCREENX(next_jx), py = SCREENY(next_jy);
+ int pxx = sxx;
+ int pyy = syy;
+#endif
+
+#if 1
+ int graphic;
+ int frame;
+
+ if (!IS_MOVING(jx, jy)) /* push movement already finished */
+ element = Feld[next_jx][next_jy];
+
+ graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir);
+ frame = getGraphicAnimationFrame(graphic, player->StepFrame);
+
+ /* draw background element under pushed element (like the Sokoban field) */
+ if (Back[next_jx][next_jy])
+ DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]);
+
+ /* masked drawing is needed for EMC style (double) movement graphics */
+ DrawGraphicShiftedThruMask(px, py, pxx, pyy, graphic, frame, NO_CUTTING);
+
+#else
+ if (Back[next_jx][next_jy])
+ DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]);
+
+ if ((pxx || pyy) && element == EL_SOKOBAN_OBJECT)
+ DrawGraphicShiftedThruMask(px, py, pxx, pyy, IMG_SOKOBAN_OBJECT, 0,
+ NO_CUTTING);
+ else
+ {
+ int element = MovingOrBlocked2Element(next_jx, next_jy);
+ int graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir);
+#if 1
+ int frame = getGraphicAnimationFrame(graphic, player->StepFrame);
+#else
+ int frame = getGraphicAnimationFrame(graphic, player->Frame);
+#endif
+
+#if 1
+ /* masked drawing is needed for EMC style (double) movement graphics */
+ DrawGraphicShiftedThruMask(px, py, pxx, pyy, graphic, frame,
+ NO_CUTTING);
+#else
+ DrawGraphicShifted(px, py, pxx, pyy, graphic, frame,
+ NO_CUTTING, NO_MASKING);
+#endif
}
+#endif
+ }
- DrawMicroLevelExt(xpos, ypos, from_x, from_y);
+ /* ----------------------------------------------------------------------- */
+ /* draw things in front of player (active dynamite or dynabombs) */
+ /* ----------------------------------------------------------------------- */
+
+ if (IS_ACTIVE_BOMB(element))
+ {
+ graphic = el2img(element);
+ frame = getGraphicAnimationFrame(graphic, GfxFrame[jx][jy]);
+
+ if (game.emulation == EMU_SUPAPLEX)
+ DrawGraphic(sx, sy, IMG_SP_DISK_RED, frame);
+ else
+ DrawGraphicThruMask(sx, sy, graphic, frame);
}
- /* redraw micro level label, if needed */
- if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
- strcmp(level.author, ANONYMOUS_NAME) != 0 &&
- strcmp(level.author, leveldir_current->name) != 0 &&
- DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
+ if (player_is_moving && last_element == EL_EXPLOSION)
{
- int max_label_counter = 23;
+ int graphic = el_act2img(GfxElement[last_jx][last_jy], ACTION_EXPLODING);
+ int delay = (game.emulation == EMU_SUPAPLEX ? 3 : 2);
+ int phase = ExplodePhase[last_jx][last_jy] - 1;
+ int frame = getGraphicAnimationFrame(graphic, phase - delay);
- if (leveldir_current->imported_from != NULL)
- max_label_counter += 14;
+ if (phase >= delay)
+ DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy), graphic, frame);
+ }
- label_counter = (label_counter + 1) % max_label_counter;
- label_state = (label_counter >= 0 && label_counter <= 7 ?
- MICROLABEL_LEVEL_NAME :
- label_counter >= 9 && label_counter <= 12 ?
- MICROLABEL_CREATED_BY :
- label_counter >= 14 && label_counter <= 21 ?
- MICROLABEL_LEVEL_AUTHOR :
- label_counter >= 23 && label_counter <= 26 ?
- MICROLABEL_IMPORTED_FROM :
- label_counter >= 28 && label_counter <= 35 ?
- MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
- DrawMicroLevelLabelExt(label_state);
+ /* ----------------------------------------------------------------------- */
+ /* draw elements the player is just walking/passing through/under */
+ /* ----------------------------------------------------------------------- */
+
+ if (player_is_moving)
+ {
+ /* handle the field the player is leaving ... */
+ if (IS_ACCESSIBLE_INSIDE(last_element))
+ DrawLevelField(last_jx, last_jy);
+ else if (IS_ACCESSIBLE_UNDER(last_element))
+ DrawLevelFieldThruMask(last_jx, last_jy);
}
- game_status = last_game_status; /* restore current game status */
+#if 1
+ /* do not redraw accessible elements if the player is just pushing them */
+ if (!player_is_moving || !player->is_pushing)
+ {
+ /* ... and the field the player is entering */
+ if (IS_ACCESSIBLE_INSIDE(element))
+ DrawLevelField(jx, jy);
+ else if (IS_ACCESSIBLE_UNDER(element))
+ DrawLevelFieldThruMask(jx, jy);
+ }
+
+#else
+
+#if 0
+ /* !!! I have forgotton what this should be good for !!! */
+ /* !!! causes player being visible when pushing from within tubes !!! */
+ if (!player->is_pushing)
+#endif
+ {
+ /* ... and the field the player is entering */
+ if (IS_ACCESSIBLE_INSIDE(element))
+ DrawLevelField(jx, jy);
+ else if (IS_ACCESSIBLE_UNDER(element))
+ DrawLevelFieldThruMask(jx, jy);
+ }
+#endif
+
+ if (setup.direct_draw)
+ {
+ int dst_x = SX + SCREENX(MIN(jx, last_jx)) * TILEX;
+ int dst_y = SY + SCREENY(MIN(jy, last_jy)) * TILEY;
+ int x_size = TILEX * (1 + ABS(jx - last_jx));
+ int y_size = TILEY * (1 + ABS(jy - last_jy));
+
+ BlitBitmap(drawto_field, window,
+ dst_x, dst_y, x_size, y_size, dst_x, dst_y);
+ SetDrawtoField(DRAW_DIRECT);
+ }
+
+ MarkTileDirty(sx, sy);
}
+/* ------------------------------------------------------------------------- */
+
void WaitForEventToContinue()
{
boolean still_wait = TRUE;
}
}
+#if 1
+ if (game_status == GAME_MODE_PLAYING &&
+ level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ BlitScreenToBitmap_EM(backbuffer);
+#endif
+
#if 1
/* disable deactivated drawing when quick-loading level tape recording */
if (tape.playing && tape.deactivate_display)
/* pause network game while waiting for request to answer */
if (options.network &&
game_status == GAME_MODE_PLAYING &&
- req_state & REQUEST_WAIT_FOR)
+ req_state & REQUEST_WAIT_FOR_INPUT)
SendToServer_PausePlaying();
#endif
UnmapAllGadgets();
- CloseDoor(DOOR_CLOSE_1);
+ if (old_door_state & DOOR_OPEN_1)
+ {
+ CloseDoor(DOOR_CLOSE_1);
- /* save old door content */
- BlitBitmap(bitmap_db_door, bitmap_db_door,
- DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
- DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
+ /* save old door content */
+ BlitBitmap(bitmap_db_door, bitmap_db_door,
+ DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
+ DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1);
+ }
SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1);
ClearEventQueue();
#endif
- if (!(req_state & REQUEST_WAIT_FOR))
+ if (!(req_state & REQUEST_WAIT_FOR_INPUT))
{
SetDrawBackgroundMask(REDRAW_FIELD);
{
CloseDoor(DOOR_CLOSE_1);
- if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
- {
- BlitBitmap(bitmap_db_door, bitmap_db_door,
- DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
- DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
- OpenDoor(DOOR_OPEN_1);
- }
+ if (((old_door_state & DOOR_OPEN_1) && !(req_state & REQ_STAY_CLOSED)) ||
+ (req_state & REQ_REOPEN))
+ OpenDoor(DOOR_OPEN_1 | DOOR_COPY_BACK);
}
RemapAllGadgets();
/* continue network game after request */
if (options.network &&
game_status == GAME_MODE_PLAYING &&
- req_state & REQUEST_WAIT_FOR)
+ req_state & REQUEST_WAIT_FOR_INPUT)
SendToServer_ContinuePlaying();
#endif
unsigned int OpenDoor(unsigned int door_state)
{
- unsigned int new_door_state;
-
if (door_state & DOOR_COPY_BACK)
{
- BlitBitmap(bitmap_db_door, bitmap_db_door,
- DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
- DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+ if (door_state & DOOR_OPEN_1)
+ BlitBitmap(bitmap_db_door, bitmap_db_door,
+ DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE,
+ DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+
+ if (door_state & DOOR_OPEN_2)
+ BlitBitmap(bitmap_db_door, bitmap_db_door,
+ DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY2, VXSIZE, VYSIZE,
+ DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
+
door_state &= ~DOOR_COPY_BACK;
}
- new_door_state = MoveDoor(door_state);
-
- return(new_door_state);
+ return MoveDoor(door_state);
}
unsigned int CloseDoor(unsigned int door_state)
{
- unsigned int new_door_state;
+ unsigned int old_door_state = GetDoorState();
- BlitBitmap(backbuffer, bitmap_db_door,
- DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
- BlitBitmap(backbuffer, bitmap_db_door,
- VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
+ if (!(door_state & DOOR_NO_COPY_BACK))
+ {
+ if (old_door_state & DOOR_OPEN_1)
+ BlitBitmap(backbuffer, bitmap_db_door,
+ DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
+
+ if (old_door_state & DOOR_OPEN_2)
+ BlitBitmap(backbuffer, bitmap_db_door,
+ VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
- new_door_state = MoveDoor(door_state);
+ door_state &= ~DOOR_NO_COPY_BACK;
+ }
- return(new_door_state);
+ return MoveDoor(door_state);
}
unsigned int GetDoorState()
{
BlitBitmap(bitmap_db_door, drawto,
DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i / 2,
- DXSIZE,DYSIZE - i / 2, DX, DY);
+ DXSIZE, DYSIZE - i / 2, DX, DY);
ClearRectangle(drawto, DX, DY + DYSIZE - i / 2, DXSIZE, i / 2);
}
}
};
-void CreateToolButtons()
+void CreateToolButtons()
+{
+ int i;
+
+ for (i = 0; i < NUM_TOOL_BUTTONS; i++)
+ {
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ Bitmap *deco_bitmap = None;
+ int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
+ struct GadgetInfo *gi;
+ unsigned long event_mask;
+ int gd_xoffset, gd_yoffset;
+ int gd_x1, gd_x2, gd_y;
+ int id = i;
+
+ event_mask = GD_EVENT_RELEASED;
+
+ gd_xoffset = toolbutton_info[i].xpos;
+ gd_yoffset = toolbutton_info[i].ypos;
+ gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
+ gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
+ gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
+
+ if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
+ {
+ int player_nr = id - TOOL_CTRL_ID_PLAYER_1;
+
+ getMiniGraphicSource(PLAYER_NR_GFX(IMG_PLAYER_1, player_nr),
+ &deco_bitmap, &deco_x, &deco_y);
+ deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
+ deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
+ }
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_INFO_TEXT, toolbutton_info[i].infotext,
+ GDI_X, DX + toolbutton_info[i].x,
+ GDI_Y, DY + toolbutton_info[i].y,
+ GDI_WIDTH, toolbutton_info[i].width,
+ GDI_HEIGHT, toolbutton_info[i].height,
+ GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
+ GDI_STATE, GD_BUTTON_UNPRESSED,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
+ GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
+ GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
+ GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
+ GDI_DECORATION_SHIFTING, 1, 1,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_ACTION, HandleToolButtons,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ tool_gadget[id] = gi;
+ }
+}
+
+void FreeToolButtons()
+{
+ int i;
+
+ for (i = 0; i < NUM_TOOL_BUTTONS; i++)
+ FreeGadget(tool_gadget[i]);
+}
+
+static void UnmapToolButtons()
+{
+ int i;
+
+ for (i = 0; i < NUM_TOOL_BUTTONS; i++)
+ UnmapGadget(tool_gadget[i]);
+}
+
+static void HandleToolButtons(struct GadgetInfo *gi)
+{
+ request_gadget_id = gi->custom_id;
+}
+
+#if 1
+
+static struct Mapping_EM_to_RND_object
+{
+ int element_em;
+ boolean is_rnd_to_em_mapping; /* unique mapping EM <-> RND */
+ boolean is_backside; /* backside of moving element */
+
+ int element_rnd;
+ int action;
+ int direction;
+}
+em_object_mapping_list[] =
+{
+ {
+ Xblank, TRUE, FALSE,
+ EL_EMPTY, -1, -1
+ },
+ {
+ Yacid_splash_eB, FALSE, FALSE,
+ EL_ACID_SPLASH_RIGHT, -1, -1
+ },
+ {
+ Yacid_splash_wB, FALSE, FALSE,
+ EL_ACID_SPLASH_LEFT, -1, -1
+ },
+
+#ifdef EM_ENGINE_BAD_ROLL
+ {
+ Xstone_force_e, FALSE, FALSE,
+ EL_ROCK, -1, MV_BIT_RIGHT
+ },
+ {
+ Xstone_force_w, FALSE, FALSE,
+ EL_ROCK, -1, MV_BIT_LEFT
+ },
+ {
+ Xnut_force_e, FALSE, FALSE,
+ EL_NUT, -1, MV_BIT_RIGHT
+ },
+ {
+ Xnut_force_w, FALSE, FALSE,
+ EL_NUT, -1, MV_BIT_LEFT
+ },
+ {
+ Xspring_force_e, FALSE, FALSE,
+ EL_SPRING, -1, MV_BIT_RIGHT
+ },
+ {
+ Xspring_force_w, FALSE, FALSE,
+ EL_SPRING, -1, MV_BIT_LEFT
+ },
+ {
+ Xemerald_force_e, FALSE, FALSE,
+ EL_EMERALD, -1, MV_BIT_RIGHT
+ },
+ {
+ Xemerald_force_w, FALSE, FALSE,
+ EL_EMERALD, -1, MV_BIT_LEFT
+ },
+ {
+ Xdiamond_force_e, FALSE, FALSE,
+ EL_DIAMOND, -1, MV_BIT_RIGHT
+ },
+ {
+ Xdiamond_force_w, FALSE, FALSE,
+ EL_DIAMOND, -1, MV_BIT_LEFT
+ },
+ {
+ Xbomb_force_e, FALSE, FALSE,
+ EL_BOMB, -1, MV_BIT_RIGHT
+ },
+ {
+ Xbomb_force_w, FALSE, FALSE,
+ EL_BOMB, -1, MV_BIT_LEFT
+ },
+#endif /* EM_ENGINE_BAD_ROLL */
+
+ {
+ Xstone, TRUE, FALSE,
+ EL_ROCK, -1, -1
+ },
+ {
+ Xstone_pause, FALSE, FALSE,
+ EL_ROCK, -1, -1
+ },
+ {
+ Xstone_fall, FALSE, FALSE,
+ EL_ROCK, -1, -1
+ },
+ {
+ Ystone_s, FALSE, FALSE,
+ EL_ROCK, ACTION_FALLING, -1
+ },
+ {
+ Ystone_sB, FALSE, TRUE,
+ EL_ROCK, ACTION_FALLING, -1
+ },
+ {
+ Ystone_e, FALSE, FALSE,
+ EL_ROCK, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ystone_eB, FALSE, TRUE,
+ EL_ROCK, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ystone_w, FALSE, FALSE,
+ EL_ROCK, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Ystone_wB, FALSE, TRUE,
+ EL_ROCK, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Xnut, TRUE, FALSE,
+ EL_NUT, -1, -1
+ },
+ {
+ Xnut_pause, FALSE, FALSE,
+ EL_NUT, -1, -1
+ },
+ {
+ Xnut_fall, FALSE, FALSE,
+ EL_NUT, -1, -1
+ },
+ {
+ Ynut_s, FALSE, FALSE,
+ EL_NUT, ACTION_FALLING, -1
+ },
+ {
+ Ynut_sB, FALSE, TRUE,
+ EL_NUT, ACTION_FALLING, -1
+ },
+ {
+ Ynut_e, FALSE, FALSE,
+ EL_NUT, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ynut_eB, FALSE, TRUE,
+ EL_NUT, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ynut_w, FALSE, FALSE,
+ EL_NUT, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Ynut_wB, FALSE, TRUE,
+ EL_NUT, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Xbug_n, TRUE, FALSE,
+ EL_BUG_UP, -1, -1
+ },
+ {
+ Xbug_e, TRUE, FALSE,
+ EL_BUG_RIGHT, -1, -1
+ },
+ {
+ Xbug_s, TRUE, FALSE,
+ EL_BUG_DOWN, -1, -1
+ },
+ {
+ Xbug_w, TRUE, FALSE,
+ EL_BUG_LEFT, -1, -1
+ },
+ {
+ Xbug_gon, FALSE, FALSE,
+ EL_BUG_UP, -1, -1
+ },
+ {
+ Xbug_goe, FALSE, FALSE,
+ EL_BUG_RIGHT, -1, -1
+ },
+ {
+ Xbug_gos, FALSE, FALSE,
+ EL_BUG_DOWN, -1, -1
+ },
+ {
+ Xbug_gow, FALSE, FALSE,
+ EL_BUG_LEFT, -1, -1
+ },
+ {
+ Ybug_n, FALSE, FALSE,
+ EL_BUG, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Ybug_nB, FALSE, TRUE,
+ EL_BUG, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Ybug_e, FALSE, FALSE,
+ EL_BUG, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ybug_eB, FALSE, TRUE,
+ EL_BUG, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ybug_s, FALSE, FALSE,
+ EL_BUG, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Ybug_sB, FALSE, TRUE,
+ EL_BUG, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Ybug_w, FALSE, FALSE,
+ EL_BUG, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Ybug_wB, FALSE, TRUE,
+ EL_BUG, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Ybug_w_n, FALSE, FALSE,
+ EL_BUG, ACTION_TURNING_FROM_LEFT, MV_BIT_UP
+ },
+ {
+ Ybug_n_e, FALSE, FALSE,
+ EL_BUG, ACTION_TURNING_FROM_UP, MV_BIT_RIGHT
+ },
+ {
+ Ybug_e_s, FALSE, FALSE,
+ EL_BUG, ACTION_TURNING_FROM_RIGHT, MV_BIT_DOWN
+ },
+ {
+ Ybug_s_w, FALSE, FALSE,
+ EL_BUG, ACTION_TURNING_FROM_DOWN, MV_BIT_LEFT
+ },
+ {
+ Ybug_e_n, FALSE, FALSE,
+ EL_BUG, ACTION_TURNING_FROM_RIGHT, MV_BIT_UP
+ },
+ {
+ Ybug_s_e, FALSE, FALSE,
+ EL_BUG, ACTION_TURNING_FROM_DOWN, MV_BIT_RIGHT
+ },
+ {
+ Ybug_w_s, FALSE, FALSE,
+ EL_BUG, ACTION_TURNING_FROM_LEFT, MV_BIT_DOWN
+ },
+ {
+ Ybug_n_w, FALSE, FALSE,
+ EL_BUG, ACTION_TURNING_FROM_UP, MV_BIT_LEFT
+ },
+ {
+ Ybug_stone, FALSE, FALSE,
+ EL_BUG, ACTION_SMASHED_BY_ROCK, -1
+ },
+ {
+ Ybug_spring, FALSE, FALSE,
+ EL_BUG, ACTION_SMASHED_BY_SPRING, -1
+ },
+ {
+ Xtank_n, TRUE, FALSE,
+ EL_SPACESHIP_UP, -1, -1
+ },
+ {
+ Xtank_e, TRUE, FALSE,
+ EL_SPACESHIP_RIGHT, -1, -1
+ },
+ {
+ Xtank_s, TRUE, FALSE,
+ EL_SPACESHIP_DOWN, -1, -1
+ },
+ {
+ Xtank_w, TRUE, FALSE,
+ EL_SPACESHIP_LEFT, -1, -1
+ },
+ {
+ Xtank_gon, FALSE, FALSE,
+ EL_SPACESHIP_UP, -1, -1
+ },
+ {
+ Xtank_goe, FALSE, FALSE,
+ EL_SPACESHIP_RIGHT, -1, -1
+ },
+ {
+ Xtank_gos, FALSE, FALSE,
+ EL_SPACESHIP_DOWN, -1, -1
+ },
+ {
+ Xtank_gow, FALSE, FALSE,
+ EL_SPACESHIP_LEFT, -1, -1
+ },
+ {
+ Ytank_n, FALSE, FALSE,
+ EL_SPACESHIP, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Ytank_nB, FALSE, TRUE,
+ EL_SPACESHIP, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Ytank_e, FALSE, FALSE,
+ EL_SPACESHIP, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ytank_eB, FALSE, TRUE,
+ EL_SPACESHIP, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ytank_s, FALSE, FALSE,
+ EL_SPACESHIP, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Ytank_sB, FALSE, TRUE,
+ EL_SPACESHIP, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Ytank_w, FALSE, FALSE,
+ EL_SPACESHIP, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Ytank_wB, FALSE, TRUE,
+ EL_SPACESHIP, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Ytank_w_n, FALSE, FALSE,
+ EL_SPACESHIP, ACTION_TURNING_FROM_LEFT, MV_BIT_UP
+ },
+ {
+ Ytank_n_e, FALSE, FALSE,
+ EL_SPACESHIP, ACTION_TURNING_FROM_UP, MV_BIT_RIGHT
+ },
+ {
+ Ytank_e_s, FALSE, FALSE,
+ EL_SPACESHIP, ACTION_TURNING_FROM_RIGHT, MV_BIT_DOWN
+ },
+ {
+ Ytank_s_w, FALSE, FALSE,
+ EL_SPACESHIP, ACTION_TURNING_FROM_DOWN, MV_BIT_LEFT
+ },
+ {
+ Ytank_e_n, FALSE, FALSE,
+ EL_SPACESHIP, ACTION_TURNING_FROM_RIGHT, MV_BIT_UP
+ },
+ {
+ Ytank_s_e, FALSE, FALSE,
+ EL_SPACESHIP, ACTION_TURNING_FROM_DOWN, MV_BIT_RIGHT
+ },
+ {
+ Ytank_w_s, FALSE, FALSE,
+ EL_SPACESHIP, ACTION_TURNING_FROM_LEFT, MV_BIT_DOWN
+ },
+ {
+ Ytank_n_w, FALSE, FALSE,
+ EL_SPACESHIP, ACTION_TURNING_FROM_UP, MV_BIT_LEFT
+ },
+ {
+ Ytank_stone, FALSE, FALSE,
+ EL_SPACESHIP, ACTION_SMASHED_BY_ROCK, -1
+ },
+ {
+ Ytank_spring, FALSE, FALSE,
+ EL_SPACESHIP, ACTION_SMASHED_BY_SPRING, -1
+ },
+ {
+ Xandroid, TRUE, FALSE,
+ EL_EMC_ANDROID, ACTION_ACTIVE, -1
+ },
+ {
+ Xandroid_1_n, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_UP
+ },
+ {
+ Xandroid_2_n, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_UP
+ },
+ {
+ Xandroid_1_e, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_RIGHT
+ },
+ {
+ Xandroid_2_e, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_RIGHT
+ },
+ {
+ Xandroid_1_w, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_LEFT
+ },
+ {
+ Xandroid_2_w, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_LEFT
+ },
+ {
+ Xandroid_1_s, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_DOWN
+ },
+ {
+ Xandroid_2_s, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_ACTIVE, MV_BIT_DOWN
+ },
+ {
+ Yandroid_n, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Yandroid_nB, FALSE, TRUE,
+ EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Yandroid_ne, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_TURNING_FROM_UP, MV_BIT_RIGHT
+ },
+ {
+ Yandroid_neB, FALSE, TRUE,
+ EL_EMC_ANDROID, ACTION_TURNING_FROM_UP, MV_BIT_RIGHT
+ },
+ {
+ Yandroid_e, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yandroid_eB, FALSE, TRUE,
+ EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yandroid_se, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_TURNING_FROM_DOWN, MV_BIT_RIGHT
+ },
+ {
+ Yandroid_seB, FALSE, TRUE,
+ EL_EMC_ANDROID, ACTION_TURNING_FROM_DOWN, MV_BIT_RIGHT
+ },
+ {
+ Yandroid_s, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Yandroid_sB, FALSE, TRUE,
+ EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Yandroid_sw, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_TURNING_FROM_DOWN, MV_BIT_LEFT
+ },
+ {
+ Yandroid_swB, FALSE, TRUE,
+ EL_EMC_ANDROID, ACTION_TURNING_FROM_DOWN, MV_BIT_LEFT
+ },
+ {
+ Yandroid_w, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yandroid_wB, FALSE, TRUE,
+ EL_EMC_ANDROID, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yandroid_nw, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_TURNING_FROM_UP, MV_BIT_LEFT
+ },
+ {
+ Yandroid_nwB, FALSE, TRUE,
+ EL_EMC_ANDROID, ACTION_TURNING_FROM_UP, MV_BIT_LEFT
+ },
+ {
+ Xspring, TRUE, FALSE,
+ EL_SPRING, -1, -1
+ },
+ {
+ Xspring_pause, FALSE, FALSE,
+ EL_SPRING, -1, -1
+ },
+ {
+ Xspring_e, FALSE, FALSE,
+ EL_SPRING, -1, -1
+ },
+ {
+ Xspring_w, FALSE, FALSE,
+ EL_SPRING, -1, -1
+ },
+ {
+ Xspring_fall, FALSE, FALSE,
+ EL_SPRING, -1, -1
+ },
+ {
+ Yspring_s, FALSE, FALSE,
+ EL_SPRING, ACTION_FALLING, -1
+ },
+ {
+ Yspring_sB, FALSE, TRUE,
+ EL_SPRING, ACTION_FALLING, -1
+ },
+ {
+ Yspring_e, FALSE, FALSE,
+ EL_SPRING, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yspring_eB, FALSE, TRUE,
+ EL_SPRING, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yspring_w, FALSE, FALSE,
+ EL_SPRING, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yspring_wB, FALSE, TRUE,
+ EL_SPRING, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yspring_kill_e, FALSE, FALSE,
+ EL_ROBOT, ACTION_SLURPED_BY_SPRING, MV_BIT_RIGHT
+ },
+ {
+ Yspring_kill_eB, FALSE, TRUE,
+ EL_ROBOT, ACTION_SLURPED_BY_SPRING, MV_BIT_RIGHT
+ },
+ {
+ Yspring_kill_w, FALSE, FALSE,
+ EL_ROBOT, ACTION_SLURPED_BY_SPRING, MV_BIT_LEFT
+ },
+ {
+ Yspring_kill_wB, FALSE, TRUE,
+ EL_ROBOT, ACTION_SLURPED_BY_SPRING, MV_BIT_LEFT
+ },
+ {
+ Xeater_n, TRUE, FALSE,
+ EL_YAMYAM, -1, -1
+ },
+ {
+ Xeater_e, FALSE, FALSE,
+ EL_YAMYAM, -1, -1
+ },
+ {
+ Xeater_w, FALSE, FALSE,
+ EL_YAMYAM, -1, -1
+ },
+ {
+ Xeater_s, FALSE, FALSE,
+ EL_YAMYAM, -1, -1
+ },
+ {
+ Yeater_n, FALSE, FALSE,
+ EL_YAMYAM, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Yeater_nB, FALSE, TRUE,
+ EL_YAMYAM, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Yeater_e, FALSE, FALSE,
+ EL_YAMYAM, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yeater_eB, FALSE, TRUE,
+ EL_YAMYAM, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yeater_s, FALSE, FALSE,
+ EL_YAMYAM, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Yeater_sB, FALSE, TRUE,
+ EL_YAMYAM, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Yeater_w, FALSE, FALSE,
+ EL_YAMYAM, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yeater_wB, FALSE, TRUE,
+ EL_YAMYAM, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yeater_stone, FALSE, FALSE,
+ EL_YAMYAM, ACTION_SMASHED_BY_ROCK, -1
+ },
+ {
+ Yeater_spring, FALSE, FALSE,
+ EL_YAMYAM, ACTION_SMASHED_BY_SPRING, -1
+ },
+ {
+ Xalien, TRUE, FALSE,
+ EL_ROBOT, -1, -1
+ },
+ {
+ Xalien_pause, FALSE, FALSE,
+ EL_ROBOT, -1, -1
+ },
+ {
+ Yalien_n, FALSE, FALSE,
+ EL_ROBOT, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Yalien_nB, FALSE, TRUE,
+ EL_ROBOT, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Yalien_e, FALSE, FALSE,
+ EL_ROBOT, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yalien_eB, FALSE, TRUE,
+ EL_ROBOT, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yalien_s, FALSE, FALSE,
+ EL_ROBOT, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Yalien_sB, FALSE, TRUE,
+ EL_ROBOT, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Yalien_w, FALSE, FALSE,
+ EL_ROBOT, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yalien_wB, FALSE, TRUE,
+ EL_ROBOT, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yalien_stone, FALSE, FALSE,
+ EL_ROBOT, ACTION_SMASHED_BY_ROCK, -1
+ },
+ {
+ Yalien_spring, FALSE, FALSE,
+ EL_ROBOT, ACTION_SMASHED_BY_SPRING, -1
+ },
+ {
+ Xemerald, TRUE, FALSE,
+ EL_EMERALD, -1, -1
+ },
+ {
+ Xemerald_pause, FALSE, FALSE,
+ EL_EMERALD, -1, -1
+ },
+ {
+ Xemerald_fall, FALSE, FALSE,
+ EL_EMERALD, -1, -1
+ },
+ {
+ Xemerald_shine, FALSE, FALSE,
+ EL_EMERALD, ACTION_TWINKLING, -1
+ },
+ {
+ Yemerald_s, FALSE, FALSE,
+ EL_EMERALD, ACTION_FALLING, -1
+ },
+ {
+ Yemerald_sB, FALSE, TRUE,
+ EL_EMERALD, ACTION_FALLING, -1
+ },
+ {
+ Yemerald_e, FALSE, FALSE,
+ EL_EMERALD, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yemerald_eB, FALSE, TRUE,
+ EL_EMERALD, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yemerald_w, FALSE, FALSE,
+ EL_EMERALD, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yemerald_wB, FALSE, TRUE,
+ EL_EMERALD, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yemerald_eat, FALSE, FALSE,
+ EL_EMERALD, ACTION_COLLECTING, -1
+ },
+ {
+ Yemerald_stone, FALSE, FALSE,
+ EL_NUT, ACTION_BREAKING, -1
+ },
+ {
+ Xdiamond, TRUE, FALSE,
+ EL_DIAMOND, -1, -1
+ },
+ {
+ Xdiamond_pause, FALSE, FALSE,
+ EL_DIAMOND, -1, -1
+ },
+ {
+ Xdiamond_fall, FALSE, FALSE,
+ EL_DIAMOND, -1, -1
+ },
+ {
+ Xdiamond_shine, FALSE, FALSE,
+ EL_DIAMOND, ACTION_TWINKLING, -1
+ },
+ {
+ Ydiamond_s, FALSE, FALSE,
+ EL_DIAMOND, ACTION_FALLING, -1
+ },
+ {
+ Ydiamond_sB, FALSE, TRUE,
+ EL_DIAMOND, ACTION_FALLING, -1
+ },
+ {
+ Ydiamond_e, FALSE, FALSE,
+ EL_DIAMOND, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ydiamond_eB, FALSE, TRUE,
+ EL_DIAMOND, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ydiamond_w, FALSE, FALSE,
+ EL_DIAMOND, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Ydiamond_wB, FALSE, TRUE,
+ EL_DIAMOND, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Ydiamond_eat, FALSE, FALSE,
+ EL_DIAMOND, ACTION_COLLECTING, -1
+ },
+ {
+ Ydiamond_stone, FALSE, FALSE,
+ EL_DIAMOND, ACTION_SMASHED_BY_ROCK, -1
+ },
+ {
+ Xdrip_fall, TRUE, FALSE,
+ EL_AMOEBA_DROP, -1, -1
+ },
+ {
+ Xdrip_stretch, FALSE, FALSE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
+ },
+ {
+ Xdrip_stretchB, FALSE, TRUE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
+ },
+ {
+ Xdrip_eat, FALSE, FALSE,
+ EL_AMOEBA_DROP, ACTION_GROWING, -1
+ },
+ {
+ Ydrip_s1, FALSE, FALSE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
+ },
+ {
+ Ydrip_s1B, FALSE, TRUE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
+ },
+ {
+ Ydrip_s2, FALSE, FALSE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
+ },
+ {
+ Ydrip_s2B, FALSE, TRUE,
+ EL_AMOEBA_DROP, ACTION_FALLING, -1
+ },
+ {
+ Xbomb, TRUE, FALSE,
+ EL_BOMB, -1, -1
+ },
+ {
+ Xbomb_pause, FALSE, FALSE,
+ EL_BOMB, -1, -1
+ },
+ {
+ Xbomb_fall, FALSE, FALSE,
+ EL_BOMB, -1, -1
+ },
+ {
+ Ybomb_s, FALSE, FALSE,
+ EL_BOMB, ACTION_FALLING, -1
+ },
+ {
+ Ybomb_sB, FALSE, TRUE,
+ EL_BOMB, ACTION_FALLING, -1
+ },
+ {
+ Ybomb_e, FALSE, FALSE,
+ EL_BOMB, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ybomb_eB, FALSE, TRUE,
+ EL_BOMB, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Ybomb_w, FALSE, FALSE,
+ EL_BOMB, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Ybomb_wB, FALSE, TRUE,
+ EL_BOMB, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Ybomb_eat, FALSE, FALSE,
+ EL_BOMB, ACTION_ACTIVATING, -1
+ },
+ {
+ Xballoon, TRUE, FALSE,
+ EL_BALLOON, -1, -1
+ },
+ {
+ Yballoon_n, FALSE, FALSE,
+ EL_BALLOON, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Yballoon_nB, FALSE, TRUE,
+ EL_BALLOON, ACTION_MOVING, MV_BIT_UP
+ },
+ {
+ Yballoon_e, FALSE, FALSE,
+ EL_BALLOON, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yballoon_eB, FALSE, TRUE,
+ EL_BALLOON, ACTION_MOVING, MV_BIT_RIGHT
+ },
+ {
+ Yballoon_s, FALSE, FALSE,
+ EL_BALLOON, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Yballoon_sB, FALSE, TRUE,
+ EL_BALLOON, ACTION_MOVING, MV_BIT_DOWN
+ },
+ {
+ Yballoon_w, FALSE, FALSE,
+ EL_BALLOON, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Yballoon_wB, FALSE, TRUE,
+ EL_BALLOON, ACTION_MOVING, MV_BIT_LEFT
+ },
+ {
+ Xgrass, TRUE, FALSE,
+ EL_EMC_GRASS, -1, -1
+ },
+ {
+ Ygrass_nB, FALSE, FALSE,
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_UP
+ },
+ {
+ Ygrass_eB, FALSE, FALSE,
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_RIGHT
+ },
+ {
+ Ygrass_sB, FALSE, FALSE,
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_DOWN
+ },
+ {
+ Ygrass_wB, FALSE, FALSE,
+ EL_EMC_GRASS, ACTION_DIGGING, MV_BIT_LEFT
+ },
+ {
+ Xdirt, TRUE, FALSE,
+ EL_SAND, -1, -1
+ },
+ {
+ Ydirt_nB, FALSE, FALSE,
+ EL_SAND, ACTION_DIGGING, MV_BIT_UP
+ },
+ {
+ Ydirt_eB, FALSE, FALSE,
+ EL_SAND, ACTION_DIGGING, MV_BIT_RIGHT
+ },
+ {
+ Ydirt_sB, FALSE, FALSE,
+ EL_SAND, ACTION_DIGGING, MV_BIT_DOWN
+ },
+ {
+ Ydirt_wB, FALSE, FALSE,
+ EL_SAND, ACTION_DIGGING, MV_BIT_LEFT
+ },
+ {
+ Xacid_ne, TRUE, FALSE,
+ EL_ACID_POOL_TOPRIGHT, -1, -1
+ },
+ {
+ Xacid_se, TRUE, FALSE,
+ EL_ACID_POOL_BOTTOMRIGHT, -1, -1
+ },
+ {
+ Xacid_s, TRUE, FALSE,
+ EL_ACID_POOL_BOTTOM, -1, -1
+ },
+ {
+ Xacid_sw, TRUE, FALSE,
+ EL_ACID_POOL_BOTTOMLEFT, -1, -1
+ },
+ {
+ Xacid_nw, TRUE, FALSE,
+ EL_ACID_POOL_TOPLEFT, -1, -1
+ },
+ {
+ Xacid_1, TRUE, FALSE,
+ EL_ACID, -1, -1
+ },
+ {
+ Xacid_2, FALSE, FALSE,
+ EL_ACID, -1, -1
+ },
+ {
+ Xacid_3, FALSE, FALSE,
+ EL_ACID, -1, -1
+ },
+ {
+ Xacid_4, FALSE, FALSE,
+ EL_ACID, -1, -1
+ },
+ {
+ Xacid_5, FALSE, FALSE,
+ EL_ACID, -1, -1
+ },
+ {
+ Xacid_6, FALSE, FALSE,
+ EL_ACID, -1, -1
+ },
+ {
+ Xacid_7, FALSE, FALSE,
+ EL_ACID, -1, -1
+ },
+ {
+ Xacid_8, FALSE, FALSE,
+ EL_ACID, -1, -1
+ },
+ {
+ Xball_1, TRUE, FALSE,
+ EL_EMC_MAGIC_BALL, -1, -1
+ },
+ {
+ Xball_1B, FALSE, FALSE,
+ EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
+ },
+ {
+ Xball_2, FALSE, FALSE,
+ EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
+ },
+ {
+ Xball_2B, FALSE, FALSE,
+ EL_EMC_MAGIC_BALL, ACTION_ACTIVE, -1
+ },
+ {
+ Yball_eat, FALSE, FALSE,
+ EL_EMC_MAGIC_BALL, ACTION_DROPPING, -1
+ },
+ {
+ Ykey_1_eat, FALSE, FALSE,
+ EL_EM_KEY_1, ACTION_COLLECTING, -1
+ },
+ {
+ Ykey_2_eat, FALSE, FALSE,
+ EL_EM_KEY_2, ACTION_COLLECTING, -1
+ },
+ {
+ Ykey_3_eat, FALSE, FALSE,
+ EL_EM_KEY_3, ACTION_COLLECTING, -1
+ },
+ {
+ Ykey_4_eat, FALSE, FALSE,
+ EL_EM_KEY_4, ACTION_COLLECTING, -1
+ },
+ {
+ Ykey_5_eat, FALSE, FALSE,
+ EL_EMC_KEY_5, ACTION_COLLECTING, -1
+ },
+ {
+ Ykey_6_eat, FALSE, FALSE,
+ EL_EMC_KEY_6, ACTION_COLLECTING, -1
+ },
+ {
+ Ykey_7_eat, FALSE, FALSE,
+ EL_EMC_KEY_7, ACTION_COLLECTING, -1
+ },
+ {
+ Ykey_8_eat, FALSE, FALSE,
+ EL_EMC_KEY_8, ACTION_COLLECTING, -1
+ },
+ {
+ Ylenses_eat, FALSE, FALSE,
+ EL_EMC_LENSES, ACTION_COLLECTING, -1
+ },
+ {
+ Ymagnify_eat, FALSE, FALSE,
+ EL_EMC_MAGNIFIER, ACTION_COLLECTING, -1
+ },
+ {
+ Ygrass_eat, FALSE, FALSE,
+ EL_EMC_GRASS, ACTION_SNAPPING, -1
+ },
+ {
+ Ydirt_eat, FALSE, FALSE,
+ EL_SAND, ACTION_SNAPPING, -1
+ },
+ {
+ Xgrow_ns, TRUE, FALSE,
+ EL_EXPANDABLE_WALL_VERTICAL, -1, -1
+ },
+ {
+ Ygrow_ns_eat, FALSE, FALSE,
+ EL_EXPANDABLE_WALL_VERTICAL, ACTION_GROWING, -1
+ },
+ {
+ Xgrow_ew, TRUE, FALSE,
+ EL_EXPANDABLE_WALL_HORIZONTAL, -1, -1
+ },
+ {
+ Ygrow_ew_eat, FALSE, FALSE,
+ EL_EXPANDABLE_WALL_HORIZONTAL, ACTION_GROWING, -1
+ },
+ {
+ Xwonderwall, TRUE, FALSE,
+ EL_MAGIC_WALL, -1, -1
+ },
+ {
+ XwonderwallB, FALSE, FALSE,
+ EL_MAGIC_WALL, ACTION_ACTIVE, -1
+ },
+ {
+ Xamoeba_1, TRUE, FALSE,
+ EL_AMOEBA_DRY, ACTION_OTHER, -1
+ },
+ {
+ Xamoeba_2, FALSE, FALSE,
+ EL_AMOEBA_DRY, ACTION_OTHER, -1
+ },
+ {
+ Xamoeba_3, FALSE, FALSE,
+ EL_AMOEBA_DRY, ACTION_OTHER, -1
+ },
+ {
+ Xamoeba_4, FALSE, FALSE,
+ EL_AMOEBA_DRY, ACTION_OTHER, -1
+ },
+ {
+ Xamoeba_5, TRUE, FALSE,
+ EL_AMOEBA_WET, ACTION_OTHER, -1
+ },
+ {
+ Xamoeba_6, FALSE, FALSE,
+ EL_AMOEBA_WET, ACTION_OTHER, -1
+ },
+ {
+ Xamoeba_7, FALSE, FALSE,
+ EL_AMOEBA_WET, ACTION_OTHER, -1
+ },
+ {
+ Xamoeba_8, FALSE, FALSE,
+ EL_AMOEBA_WET, ACTION_OTHER, -1
+ },
+ {
+ Xdoor_1, TRUE, FALSE,
+ EL_EM_GATE_1, -1, -1
+ },
+ {
+ Xdoor_2, TRUE, FALSE,
+ EL_EM_GATE_2, -1, -1
+ },
+ {
+ Xdoor_3, TRUE, FALSE,
+ EL_EM_GATE_3, -1, -1
+ },
+ {
+ Xdoor_4, TRUE, FALSE,
+ EL_EM_GATE_4, -1, -1
+ },
+ {
+ Xdoor_5, TRUE, FALSE,
+ EL_EMC_GATE_5, -1, -1
+ },
+ {
+ Xdoor_6, TRUE, FALSE,
+ EL_EMC_GATE_6, -1, -1
+ },
+ {
+ Xdoor_7, TRUE, FALSE,
+ EL_EMC_GATE_7, -1, -1
+ },
+ {
+ Xdoor_8, TRUE, FALSE,
+ EL_EMC_GATE_8, -1, -1
+ },
+ {
+ Xkey_1, TRUE, FALSE,
+ EL_EM_KEY_1, -1, -1
+ },
+ {
+ Xkey_2, TRUE, FALSE,
+ EL_EM_KEY_2, -1, -1
+ },
+ {
+ Xkey_3, TRUE, FALSE,
+ EL_EM_KEY_3, -1, -1
+ },
+ {
+ Xkey_4, TRUE, FALSE,
+ EL_EM_KEY_4, -1, -1
+ },
+ {
+ Xkey_5, TRUE, FALSE,
+ EL_EMC_KEY_5, -1, -1
+ },
+ {
+ Xkey_6, TRUE, FALSE,
+ EL_EMC_KEY_6, -1, -1
+ },
+ {
+ Xkey_7, TRUE, FALSE,
+ EL_EMC_KEY_7, -1, -1
+ },
+ {
+ Xkey_8, TRUE, FALSE,
+ EL_EMC_KEY_8, -1, -1
+ },
+ {
+ Xwind_n, TRUE, FALSE,
+ EL_BALLOON_SWITCH_UP, -1, -1
+ },
+ {
+ Xwind_e, TRUE, FALSE,
+ EL_BALLOON_SWITCH_RIGHT, -1, -1
+ },
+ {
+ Xwind_s, TRUE, FALSE,
+ EL_BALLOON_SWITCH_DOWN, -1, -1
+ },
+ {
+ Xwind_w, TRUE, FALSE,
+ EL_BALLOON_SWITCH_LEFT, -1, -1
+ },
+ {
+ Xwind_nesw, TRUE, FALSE,
+ EL_BALLOON_SWITCH_ANY, -1, -1
+ },
+ {
+ Xwind_stop, TRUE, FALSE,
+ EL_BALLOON_SWITCH_NONE, -1, -1
+ },
+ {
+ Xexit, TRUE, FALSE,
+ EL_EXIT_CLOSED, -1, -1
+ },
+ {
+ Xexit_1, TRUE, FALSE,
+ EL_EXIT_OPEN, -1, -1
+ },
+ {
+ Xexit_2, FALSE, FALSE,
+ EL_EXIT_OPEN, -1, -1
+ },
+ {
+ Xexit_3, FALSE, FALSE,
+ EL_EXIT_OPEN, -1, -1
+ },
+ {
+ Xdynamite, TRUE, FALSE,
+ EL_DYNAMITE, -1, -1
+ },
+ {
+ Ydynamite_eat, FALSE, FALSE,
+ EL_DYNAMITE, ACTION_COLLECTING, -1
+ },
+ {
+ Xdynamite_1, TRUE, FALSE,
+ EL_DYNAMITE_ACTIVE, -1, -1
+ },
+ {
+ Xdynamite_2, FALSE, FALSE,
+ EL_DYNAMITE_ACTIVE, -1, -1
+ },
+ {
+ Xdynamite_3, FALSE, FALSE,
+ EL_DYNAMITE_ACTIVE, -1, -1
+ },
+ {
+ Xdynamite_4, FALSE, FALSE,
+ EL_DYNAMITE_ACTIVE, -1, -1
+ },
+ {
+ Xbumper, TRUE, FALSE,
+ EL_EMC_SPRING_BUMPER, -1, -1
+ },
+ {
+ XbumperB, FALSE, FALSE,
+ EL_EMC_SPRING_BUMPER, ACTION_ACTIVE, -1
+ },
+ {
+ Xwheel, TRUE, FALSE,
+ EL_ROBOT_WHEEL, -1, -1
+ },
+ {
+ XwheelB, FALSE, FALSE,
+ EL_ROBOT_WHEEL, ACTION_ACTIVE, -1
+ },
+ {
+ Xswitch, TRUE, FALSE,
+ EL_EMC_MAGIC_BALL_SWITCH, -1, -1
+ },
+ {
+ XswitchB, FALSE, FALSE,
+ EL_EMC_MAGIC_BALL_SWITCH, ACTION_ACTIVE, -1
+ },
+ {
+ Xsand, TRUE, FALSE,
+ EL_QUICKSAND_EMPTY, -1, -1
+ },
+ {
+ Xsand_stone, TRUE, FALSE,
+ EL_QUICKSAND_FULL, -1, -1
+ },
+ {
+ Xsand_stonein_1, FALSE, FALSE,
+ EL_ROCK, ACTION_FILLING, -1
+ },
+ {
+ Xsand_stonein_2, FALSE, FALSE,
+ EL_ROCK, ACTION_FILLING, -1
+ },
+ {
+ Xsand_stonein_3, FALSE, FALSE,
+ EL_ROCK, ACTION_FILLING, -1
+ },
+ {
+ Xsand_stonein_4, FALSE, FALSE,
+ EL_ROCK, ACTION_FILLING, -1
+ },
+ {
+ Xsand_stonesand_1, FALSE, FALSE,
+ EL_QUICKSAND_FULL, -1, -1
+ },
+ {
+ Xsand_stonesand_2, FALSE, FALSE,
+ EL_QUICKSAND_FULL, -1, -1
+ },
+ {
+ Xsand_stonesand_3, FALSE, FALSE,
+ EL_QUICKSAND_FULL, -1, -1
+ },
+ {
+ Xsand_stonesand_4, FALSE, FALSE,
+ EL_QUICKSAND_FULL, -1, -1
+ },
+ {
+ Xsand_stoneout_1, FALSE, FALSE,
+ EL_ROCK, ACTION_EMPTYING, -1
+ },
+ {
+ Xsand_stoneout_2, FALSE, FALSE,
+ EL_ROCK, ACTION_EMPTYING, -1
+ },
+ {
+ Xsand_sandstone_1, FALSE, FALSE,
+ EL_QUICKSAND_FULL, -1, -1
+ },
+ {
+ Xsand_sandstone_2, FALSE, FALSE,
+ EL_QUICKSAND_FULL, -1, -1
+ },
+ {
+ Xsand_sandstone_3, FALSE, FALSE,
+ EL_QUICKSAND_FULL, -1, -1
+ },
+ {
+ Xsand_sandstone_4, FALSE, FALSE,
+ EL_QUICKSAND_FULL, -1, -1
+ },
+ {
+ Xplant, TRUE, FALSE,
+ EL_EMC_PLANT, -1, -1
+ },
+ {
+ Yplant, FALSE, FALSE,
+ EL_EMC_PLANT, -1, -1
+ },
+ {
+ Xlenses, TRUE, FALSE,
+ EL_EMC_LENSES, -1, -1
+ },
+ {
+ Xmagnify, TRUE, FALSE,
+ EL_EMC_MAGNIFIER, -1, -1
+ },
+ {
+ Xdripper, TRUE, FALSE,
+ EL_EMC_DRIPPER, -1, -1
+ },
+ {
+ XdripperB, FALSE, FALSE,
+ EL_EMC_DRIPPER, ACTION_ACTIVE, -1
+ },
+ {
+ Xfake_blank, TRUE, FALSE,
+ EL_INVISIBLE_WALL, -1, -1
+ },
+ {
+ Xfake_blankB, FALSE, FALSE,
+ EL_INVISIBLE_WALL, ACTION_ACTIVE, -1
+ },
+ {
+ Xfake_grass, TRUE, FALSE,
+ EL_EMC_FAKE_GRASS, -1, -1
+ },
+ {
+ Xfake_grassB, FALSE, FALSE,
+ EL_EMC_FAKE_GRASS, ACTION_ACTIVE, -1
+ },
+ {
+ Xfake_door_1, TRUE, FALSE,
+ EL_EM_GATE_1_GRAY, -1, -1
+ },
+ {
+ Xfake_door_2, TRUE, FALSE,
+ EL_EM_GATE_2_GRAY, -1, -1
+ },
+ {
+ Xfake_door_3, TRUE, FALSE,
+ EL_EM_GATE_3_GRAY, -1, -1
+ },
+ {
+ Xfake_door_4, TRUE, FALSE,
+ EL_EM_GATE_4_GRAY, -1, -1
+ },
+ {
+ Xfake_door_5, TRUE, FALSE,
+ EL_EMC_GATE_5_GRAY, -1, -1
+ },
+ {
+ Xfake_door_6, TRUE, FALSE,
+ EL_EMC_GATE_6_GRAY, -1, -1
+ },
+ {
+ Xfake_door_7, TRUE, FALSE,
+ EL_EMC_GATE_7_GRAY, -1, -1
+ },
+ {
+ Xfake_door_8, TRUE, FALSE,
+ EL_EMC_GATE_8_GRAY, -1, -1
+ },
+ {
+ Xfake_acid_1, TRUE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_2, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_3, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_4, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_5, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_6, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_7, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xfake_acid_8, FALSE, FALSE,
+ EL_EMC_FAKE_ACID, -1, -1
+ },
+ {
+ Xsteel_1, TRUE, FALSE,
+ EL_STEELWALL, -1, -1
+ },
+ {
+ Xsteel_2, TRUE, FALSE,
+ EL_EMC_STEELWALL_2, -1, -1
+ },
+ {
+ Xsteel_3, TRUE, FALSE,
+ EL_EMC_STEELWALL_3, -1, -1
+ },
+ {
+ Xsteel_4, TRUE, FALSE,
+ EL_EMC_STEELWALL_4, -1, -1
+ },
+ {
+ Xwall_1, TRUE, FALSE,
+ EL_WALL, -1, -1
+ },
+ {
+ Xwall_2, TRUE, FALSE,
+ EL_EMC_WALL_14, -1, -1
+ },
+ {
+ Xwall_3, TRUE, FALSE,
+ EL_EMC_WALL_15, -1, -1
+ },
+ {
+ Xwall_4, TRUE, FALSE,
+ EL_EMC_WALL_16, -1, -1
+ },
+ {
+ Xround_wall_1, TRUE, FALSE,
+ EL_WALL_SLIPPERY, -1, -1
+ },
+ {
+ Xround_wall_2, TRUE, FALSE,
+ EL_EMC_WALL_SLIPPERY_2, -1, -1
+ },
+ {
+ Xround_wall_3, TRUE, FALSE,
+ EL_EMC_WALL_SLIPPERY_3, -1, -1
+ },
+ {
+ Xround_wall_4, TRUE, FALSE,
+ EL_EMC_WALL_SLIPPERY_4, -1, -1
+ },
+ {
+ Xdecor_1, TRUE, FALSE,
+ EL_EMC_WALL_8, -1, -1
+ },
+ {
+ Xdecor_2, TRUE, FALSE,
+ EL_EMC_WALL_6, -1, -1
+ },
+ {
+ Xdecor_3, TRUE, FALSE,
+ EL_EMC_WALL_4, -1, -1
+ },
+ {
+ Xdecor_4, TRUE, FALSE,
+ EL_EMC_WALL_7, -1, -1
+ },
+ {
+ Xdecor_5, TRUE, FALSE,
+ EL_EMC_WALL_5, -1, -1
+ },
+ {
+ Xdecor_6, TRUE, FALSE,
+ EL_EMC_WALL_9, -1, -1
+ },
+ {
+ Xdecor_7, TRUE, FALSE,
+ EL_EMC_WALL_10, -1, -1
+ },
+ {
+ Xdecor_8, TRUE, FALSE,
+ EL_EMC_WALL_1, -1, -1
+ },
+ {
+ Xdecor_9, TRUE, FALSE,
+ EL_EMC_WALL_2, -1, -1
+ },
+ {
+ Xdecor_10, TRUE, FALSE,
+ EL_EMC_WALL_3, -1, -1
+ },
+ {
+ Xdecor_11, TRUE, FALSE,
+ EL_EMC_WALL_11, -1, -1
+ },
+ {
+ Xdecor_12, TRUE, FALSE,
+ EL_EMC_WALL_12, -1, -1
+ },
+ {
+ Xalpha_0, TRUE, FALSE,
+ EL_CHAR('0'), -1, -1
+ },
+ {
+ Xalpha_1, TRUE, FALSE,
+ EL_CHAR('1'), -1, -1
+ },
+ {
+ Xalpha_2, TRUE, FALSE,
+ EL_CHAR('2'), -1, -1
+ },
+ {
+ Xalpha_3, TRUE, FALSE,
+ EL_CHAR('3'), -1, -1
+ },
+ {
+ Xalpha_4, TRUE, FALSE,
+ EL_CHAR('4'), -1, -1
+ },
+ {
+ Xalpha_5, TRUE, FALSE,
+ EL_CHAR('5'), -1, -1
+ },
+ {
+ Xalpha_6, TRUE, FALSE,
+ EL_CHAR('6'), -1, -1
+ },
+ {
+ Xalpha_7, TRUE, FALSE,
+ EL_CHAR('7'), -1, -1
+ },
+ {
+ Xalpha_8, TRUE, FALSE,
+ EL_CHAR('8'), -1, -1
+ },
+ {
+ Xalpha_9, TRUE, FALSE,
+ EL_CHAR('9'), -1, -1
+ },
+ {
+ Xalpha_excla, TRUE, FALSE,
+ EL_CHAR('!'), -1, -1
+ },
+ {
+ Xalpha_quote, TRUE, FALSE,
+ EL_CHAR('"'), -1, -1
+ },
+ {
+ Xalpha_comma, TRUE, FALSE,
+ EL_CHAR(','), -1, -1
+ },
+ {
+ Xalpha_minus, TRUE, FALSE,
+ EL_CHAR('-'), -1, -1
+ },
+ {
+ Xalpha_perio, TRUE, FALSE,
+ EL_CHAR('.'), -1, -1
+ },
+ {
+ Xalpha_colon, TRUE, FALSE,
+ EL_CHAR(':'), -1, -1
+ },
+ {
+ Xalpha_quest, TRUE, FALSE,
+ EL_CHAR('?'), -1, -1
+ },
+ {
+ Xalpha_a, TRUE, FALSE,
+ EL_CHAR('A'), -1, -1
+ },
+ {
+ Xalpha_b, TRUE, FALSE,
+ EL_CHAR('B'), -1, -1
+ },
+ {
+ Xalpha_c, TRUE, FALSE,
+ EL_CHAR('C'), -1, -1
+ },
+ {
+ Xalpha_d, TRUE, FALSE,
+ EL_CHAR('D'), -1, -1
+ },
+ {
+ Xalpha_e, TRUE, FALSE,
+ EL_CHAR('E'), -1, -1
+ },
+ {
+ Xalpha_f, TRUE, FALSE,
+ EL_CHAR('F'), -1, -1
+ },
+ {
+ Xalpha_g, TRUE, FALSE,
+ EL_CHAR('G'), -1, -1
+ },
+ {
+ Xalpha_h, TRUE, FALSE,
+ EL_CHAR('H'), -1, -1
+ },
+ {
+ Xalpha_i, TRUE, FALSE,
+ EL_CHAR('I'), -1, -1
+ },
+ {
+ Xalpha_j, TRUE, FALSE,
+ EL_CHAR('J'), -1, -1
+ },
+ {
+ Xalpha_k, TRUE, FALSE,
+ EL_CHAR('K'), -1, -1
+ },
+ {
+ Xalpha_l, TRUE, FALSE,
+ EL_CHAR('L'), -1, -1
+ },
+ {
+ Xalpha_m, TRUE, FALSE,
+ EL_CHAR('M'), -1, -1
+ },
+ {
+ Xalpha_n, TRUE, FALSE,
+ EL_CHAR('N'), -1, -1
+ },
+ {
+ Xalpha_o, TRUE, FALSE,
+ EL_CHAR('O'), -1, -1
+ },
+ {
+ Xalpha_p, TRUE, FALSE,
+ EL_CHAR('P'), -1, -1
+ },
+ {
+ Xalpha_q, TRUE, FALSE,
+ EL_CHAR('Q'), -1, -1
+ },
+ {
+ Xalpha_r, TRUE, FALSE,
+ EL_CHAR('R'), -1, -1
+ },
+ {
+ Xalpha_s, TRUE, FALSE,
+ EL_CHAR('S'), -1, -1
+ },
+ {
+ Xalpha_t, TRUE, FALSE,
+ EL_CHAR('T'), -1, -1
+ },
+ {
+ Xalpha_u, TRUE, FALSE,
+ EL_CHAR('U'), -1, -1
+ },
+ {
+ Xalpha_v, TRUE, FALSE,
+ EL_CHAR('V'), -1, -1
+ },
+ {
+ Xalpha_w, TRUE, FALSE,
+ EL_CHAR('W'), -1, -1
+ },
+ {
+ Xalpha_x, TRUE, FALSE,
+ EL_CHAR('X'), -1, -1
+ },
+ {
+ Xalpha_y, TRUE, FALSE,
+ EL_CHAR('Y'), -1, -1
+ },
+ {
+ Xalpha_z, TRUE, FALSE,
+ EL_CHAR('Z'), -1, -1
+ },
+ {
+ Xalpha_arrow_e, TRUE, FALSE,
+ EL_CHAR('>'), -1, -1
+ },
+ {
+ Xalpha_arrow_w, TRUE, FALSE,
+ EL_CHAR('<'), -1, -1
+ },
+ {
+ Xalpha_copyr, TRUE, FALSE,
+ EL_CHAR('©'), -1, -1
+ },
+ {
+ Xalpha_copyr, TRUE, FALSE,
+ EL_CHAR('©'), -1, -1
+ },
+
+ {
+ Xboom_bug, FALSE, FALSE,
+ EL_BUG, ACTION_EXPLODING, -1
+ },
+ {
+ Xboom_bomb, FALSE, FALSE,
+ EL_BOMB, ACTION_EXPLODING, -1
+ },
+ {
+ Xboom_android, FALSE, FALSE,
+ EL_EMC_ANDROID, ACTION_OTHER, -1
+ },
+ {
+ Xboom_1, FALSE, FALSE,
+ EL_DEFAULT, ACTION_EXPLODING, -1
+ },
+ {
+ Xboom_2, FALSE, FALSE,
+ EL_DEFAULT, ACTION_EXPLODING, -1
+ },
+ {
+ Znormal, FALSE, FALSE,
+ EL_EMPTY, -1, -1
+ },
+ {
+ Zdynamite, FALSE, FALSE,
+ EL_EMPTY, -1, -1
+ },
+ {
+ Zplayer, FALSE, FALSE,
+ EL_EMPTY, -1, -1
+ },
+ {
+ ZBORDER, FALSE, FALSE,
+ EL_EMPTY, -1, -1
+ },
+
+ {
+ -1, FALSE, FALSE,
+ -1, -1, -1
+ }
+};
+
+static struct Mapping_EM_to_RND_player
+{
+ int action_em;
+ int player_nr;
+
+ int element_rnd;
+ int action;
+ int direction;
+}
+em_player_mapping_list[] =
+{
+ {
+ SPR_walk + 0, 0,
+ EL_PLAYER_1, ACTION_MOVING, MV_BIT_UP,
+ },
+ {
+ SPR_walk + 1, 0,
+ EL_PLAYER_1, ACTION_MOVING, MV_BIT_RIGHT,
+ },
+ {
+ SPR_walk + 2, 0,
+ EL_PLAYER_1, ACTION_MOVING, MV_BIT_DOWN,
+ },
+ {
+ SPR_walk + 3, 0,
+ EL_PLAYER_1, ACTION_MOVING, MV_BIT_LEFT,
+ },
+ {
+ SPR_push + 0, 0,
+ EL_PLAYER_1, ACTION_PUSHING, MV_BIT_UP,
+ },
+ {
+ SPR_push + 1, 0,
+ EL_PLAYER_1, ACTION_PUSHING, MV_BIT_RIGHT,
+ },
+ {
+ SPR_push + 2, 0,
+ EL_PLAYER_1, ACTION_PUSHING, MV_BIT_DOWN,
+ },
+ {
+ SPR_push + 3, 0,
+ EL_PLAYER_1, ACTION_PUSHING, MV_BIT_LEFT,
+ },
+ {
+ SPR_spray + 0, 0,
+ EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_UP,
+ },
+ {
+ SPR_spray + 1, 0,
+ EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_RIGHT,
+ },
+ {
+ SPR_spray + 2, 0,
+ EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_DOWN,
+ },
+ {
+ SPR_spray + 3, 0,
+ EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_LEFT,
+ },
+ {
+ SPR_walk + 0, 1,
+ EL_PLAYER_2, ACTION_MOVING, MV_BIT_UP,
+ },
+ {
+ SPR_walk + 1, 1,
+ EL_PLAYER_2, ACTION_MOVING, MV_BIT_RIGHT,
+ },
+ {
+ SPR_walk + 2, 1,
+ EL_PLAYER_2, ACTION_MOVING, MV_BIT_DOWN,
+ },
+ {
+ SPR_walk + 3, 1,
+ EL_PLAYER_2, ACTION_MOVING, MV_BIT_LEFT,
+ },
+ {
+ SPR_push + 0, 1,
+ EL_PLAYER_2, ACTION_PUSHING, MV_BIT_UP,
+ },
+ {
+ SPR_push + 1, 1,
+ EL_PLAYER_2, ACTION_PUSHING, MV_BIT_RIGHT,
+ },
+ {
+ SPR_push + 2, 1,
+ EL_PLAYER_2, ACTION_PUSHING, MV_BIT_DOWN,
+ },
+ {
+ SPR_push + 3, 1,
+ EL_PLAYER_2, ACTION_PUSHING, MV_BIT_LEFT,
+ },
+ {
+ SPR_spray + 0, 1,
+ EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_UP,
+ },
+ {
+ SPR_spray + 1, 1,
+ EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_RIGHT,
+ },
+ {
+ SPR_spray + 2, 1,
+ EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_DOWN,
+ },
+ {
+ SPR_spray + 3, 1,
+ EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_LEFT,
+ },
+ {
+ SPR_still, 0,
+ EL_PLAYER_1, ACTION_DEFAULT, -1,
+ },
+ {
+ SPR_still, 1,
+ EL_PLAYER_2, ACTION_DEFAULT, -1,
+ },
+
+ {
+ -1, -1,
+ -1, -1, -1
+ }
+};
+
+int map_element_RND_to_EM(int element_rnd)
+{
+ static unsigned short mapping_RND_to_EM[NUM_FILE_ELEMENTS];
+ static boolean mapping_initialized = FALSE;
+
+ if (!mapping_initialized)
+ {
+ int i;
+
+ /* return "Xalpha_quest" for all undefined elements in mapping array */
+ for (i = 0; i < NUM_FILE_ELEMENTS; i++)
+ mapping_RND_to_EM[i] = Xalpha_quest;
+
+ for (i = 0; em_object_mapping_list[i].element_em != -1; i++)
+ if (em_object_mapping_list[i].is_rnd_to_em_mapping)
+ mapping_RND_to_EM[em_object_mapping_list[i].element_rnd] =
+ em_object_mapping_list[i].element_em;
+
+ mapping_initialized = TRUE;
+ }
+
+ if (element_rnd >= 0 && element_rnd < NUM_FILE_ELEMENTS)
+ return mapping_RND_to_EM[element_rnd];
+
+ Error(ERR_WARN, "invalid RND level element %d", element_rnd);
+
+ return EL_UNKNOWN;
+}
+
+int map_element_EM_to_RND(int element_em)
+{
+ static unsigned short mapping_EM_to_RND[TILE_MAX];
+ static boolean mapping_initialized = FALSE;
+
+ if (!mapping_initialized)
+ {
+ int i;
+
+ /* return "EL_UNKNOWN" for all undefined elements in mapping array */
+ for (i = 0; i < TILE_MAX; i++)
+ mapping_EM_to_RND[i] = EL_UNKNOWN;
+
+ for (i = 0; em_object_mapping_list[i].element_em != -1; i++)
+ mapping_EM_to_RND[em_object_mapping_list[i].element_em] =
+ em_object_mapping_list[i].element_rnd;
+
+ mapping_initialized = TRUE;
+ }
+
+ if (element_em >= 0 && element_em < TILE_MAX)
+ return mapping_EM_to_RND[element_em];
+
+ Error(ERR_WARN, "invalid EM level element %d", element_em);
+
+ return EL_UNKNOWN;
+}
+
+#else
+
+int map_element_RND_to_EM(int element_rnd)
{
- int i;
+ static unsigned short mapping_RND_to_EM[NUM_FILE_ELEMENTS];
+ static boolean mapping_initialized = FALSE;
- for (i = 0; i < NUM_TOOL_BUTTONS; i++)
+ struct
{
- Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
- Bitmap *deco_bitmap = None;
- int deco_x = 0, deco_y = 0, deco_xpos = 0, deco_ypos = 0;
- struct GadgetInfo *gi;
- unsigned long event_mask;
- int gd_xoffset, gd_yoffset;
- int gd_x1, gd_x2, gd_y;
- int id = i;
+ int element_em;
+ int element_rnd;
+ }
+ mapping_RND_to_EM_list[] =
+ {
+ { Xblank, EL_EMPTY },
+ { Xstone, EL_ROCK },
+ { Xnut, EL_NUT },
+ { Xbug_n, EL_BUG_UP },
+ { Xbug_e, EL_BUG_RIGHT },
+ { Xbug_s, EL_BUG_DOWN },
+ { Xbug_w, EL_BUG_LEFT },
+ { Xtank_n, EL_SPACESHIP_UP },
+ { Xtank_e, EL_SPACESHIP_RIGHT },
+ { Xtank_s, EL_SPACESHIP_DOWN },
+ { Xtank_w, EL_SPACESHIP_LEFT },
+ { Xandroid, EL_EMC_ANDROID },
+ { Xandroid_1_n, EL_EMC_ANDROID_UP },
+ { Xandroid_1_e, EL_EMC_ANDROID_RIGHT },
+ { Xandroid_1_w, EL_EMC_ANDROID_LEFT },
+ { Xandroid_1_s, EL_EMC_ANDROID_DOWN },
+ { Xspring, EL_SPRING },
+ { Xeater_n, EL_YAMYAM },
+ { Xalien, EL_ROBOT },
+ { Xemerald, EL_EMERALD },
+ { Xdiamond, EL_DIAMOND },
+ { Xdrip_fall, EL_AMOEBA_DROP },
+ { Xbomb, EL_BOMB },
+ { Xballoon, EL_BALLOON },
+ { Xgrass, EL_EMC_GRASS },
+ { Xdirt, EL_SAND },
+ { Xacid_ne, EL_ACID_POOL_TOPRIGHT },
+ { Xacid_se, EL_ACID_POOL_BOTTOMRIGHT },
+ { Xacid_s, EL_ACID_POOL_BOTTOM },
+ { Xacid_sw, EL_ACID_POOL_BOTTOMLEFT },
+ { Xacid_nw, EL_ACID_POOL_TOPLEFT },
+ { Xacid_1, EL_ACID },
+ { Xball_1, EL_EMC_MAGIC_BALL },
+ { Xgrow_ns, EL_EMC_GROW },
+ { Xwonderwall, EL_MAGIC_WALL },
+ { Xamoeba_1, EL_AMOEBA_WET },
+ { Xdoor_1, EL_EM_GATE_1 },
+ { Xdoor_2, EL_EM_GATE_2 },
+ { Xdoor_3, EL_EM_GATE_3 },
+ { Xdoor_4, EL_EM_GATE_4 },
+ { Xdoor_5, EL_EMC_GATE_5 },
+ { Xdoor_6, EL_EMC_GATE_6 },
+ { Xdoor_7, EL_EMC_GATE_7 },
+ { Xdoor_8, EL_EMC_GATE_8 },
+ { Xkey_1, EL_EM_KEY_1 },
+ { Xkey_2, EL_EM_KEY_2 },
+ { Xkey_3, EL_EM_KEY_3 },
+ { Xkey_4, EL_EM_KEY_4 },
+ { Xkey_5, EL_EMC_KEY_5 },
+ { Xkey_6, EL_EMC_KEY_6 },
+ { Xkey_7, EL_EMC_KEY_7 },
+ { Xkey_8, EL_EMC_KEY_8 },
+ { Xwind_n, EL_BALLOON_SWITCH_UP },
+ { Xwind_e, EL_BALLOON_SWITCH_RIGHT },
+ { Xwind_s, EL_BALLOON_SWITCH_DOWN },
+ { Xwind_w, EL_BALLOON_SWITCH_LEFT },
+ { Xwind_nesw, EL_BALLOON_SWITCH_ANY },
+ { Xwind_stop, EL_BALLOON_SWITCH_NONE },
+ { Xexit, EL_EXIT_CLOSED },
+ { Xexit_1, EL_EXIT_OPEN },
+ { Xdynamite, EL_DYNAMITE },
+ { Xdynamite_1, EL_DYNAMITE_ACTIVE },
+ { Xbumper, EL_EMC_BUMPER },
+ { Xwheel, EL_ROBOT_WHEEL },
+ { Xswitch, EL_UNKNOWN },
+ { Xsand, EL_QUICKSAND_EMPTY },
+ { Xsand_stone, EL_QUICKSAND_FULL },
+ { Xplant, EL_EMC_PLANT },
+ { Xlenses, EL_EMC_LENSES },
+ { Xmagnify, EL_EMC_MAGNIFIER },
+ { Xdripper, EL_UNKNOWN },
+ { Xfake_blank, EL_INVISIBLE_WALL },
+ { Xfake_grass, EL_INVISIBLE_SAND },
+ { Xfake_door_1, EL_EM_GATE_1_GRAY },
+ { Xfake_door_2, EL_EM_GATE_2_GRAY },
+ { Xfake_door_3, EL_EM_GATE_3_GRAY },
+ { Xfake_door_4, EL_EM_GATE_4_GRAY },
+ { Xfake_door_5, EL_EMC_GATE_5_GRAY },
+ { Xfake_door_6, EL_EMC_GATE_6_GRAY },
+ { Xfake_door_7, EL_EMC_GATE_7_GRAY },
+ { Xfake_door_8, EL_EMC_GATE_8_GRAY },
+ { Xsteel_1, EL_STEELWALL },
+ { Xsteel_2, EL_UNKNOWN },
+ { Xsteel_3, EL_EMC_STEELWALL_1 },
+ { Xsteel_4, EL_UNKNOWN },
+ { Xwall_1, EL_WALL },
+ { Xwall_2, EL_UNKNOWN },
+ { Xwall_3, EL_UNKNOWN },
+ { Xwall_4, EL_UNKNOWN },
+ { Xround_wall_1, EL_WALL_SLIPPERY },
+ { Xround_wall_2, EL_UNKNOWN },
+ { Xround_wall_3, EL_UNKNOWN },
+ { Xround_wall_4, EL_UNKNOWN },
+ { Xdecor_1, EL_UNKNOWN },
+ { Xdecor_2, EL_EMC_WALL_6 },
+ { Xdecor_3, EL_EMC_WALL_4 },
+ { Xdecor_4, EL_EMC_WALL_5 },
+ { Xdecor_5, EL_EMC_WALL_7 },
+ { Xdecor_6, EL_EMC_WALL_8 },
+ { Xdecor_7, EL_UNKNOWN },
+ { Xdecor_8, EL_EMC_WALL_1 },
+ { Xdecor_9, EL_EMC_WALL_2 },
+ { Xdecor_10, EL_EMC_WALL_3 },
+ { Xdecor_11, EL_UNKNOWN },
+ { Xdecor_12, EL_UNKNOWN },
+ { Xalpha_0, EL_CHAR('0') },
+ { Xalpha_1, EL_CHAR('1') },
+ { Xalpha_2, EL_CHAR('2') },
+ { Xalpha_3, EL_CHAR('3') },
+ { Xalpha_4, EL_CHAR('4') },
+ { Xalpha_5, EL_CHAR('5') },
+ { Xalpha_6, EL_CHAR('6') },
+ { Xalpha_7, EL_CHAR('7') },
+ { Xalpha_8, EL_CHAR('8') },
+ { Xalpha_9, EL_CHAR('9') },
+ { Xalpha_excla, EL_CHAR('!') },
+ { Xalpha_quote, EL_CHAR('"') },
+ { Xalpha_comma, EL_CHAR(',') },
+ { Xalpha_minus, EL_CHAR('-') },
+ { Xalpha_perio, EL_CHAR('.') },
+ { Xalpha_colon, EL_CHAR(':') },
+ { Xalpha_quest, EL_CHAR('?') },
+ { Xalpha_a, EL_CHAR('A') },
+ { Xalpha_b, EL_CHAR('B') },
+ { Xalpha_c, EL_CHAR('C') },
+ { Xalpha_d, EL_CHAR('D') },
+ { Xalpha_e, EL_CHAR('E') },
+ { Xalpha_f, EL_CHAR('F') },
+ { Xalpha_g, EL_CHAR('G') },
+ { Xalpha_h, EL_CHAR('H') },
+ { Xalpha_i, EL_CHAR('I') },
+ { Xalpha_j, EL_CHAR('J') },
+ { Xalpha_k, EL_CHAR('K') },
+ { Xalpha_l, EL_CHAR('L') },
+ { Xalpha_m, EL_CHAR('M') },
+ { Xalpha_n, EL_CHAR('N') },
+ { Xalpha_o, EL_CHAR('O') },
+ { Xalpha_p, EL_CHAR('P') },
+ { Xalpha_q, EL_CHAR('Q') },
+ { Xalpha_r, EL_CHAR('R') },
+ { Xalpha_s, EL_CHAR('S') },
+ { Xalpha_t, EL_CHAR('T') },
+ { Xalpha_u, EL_CHAR('U') },
+ { Xalpha_v, EL_CHAR('V') },
+ { Xalpha_w, EL_CHAR('W') },
+ { Xalpha_x, EL_CHAR('X') },
+ { Xalpha_y, EL_CHAR('Y') },
+ { Xalpha_z, EL_CHAR('Z') },
+ { Xalpha_arrow_e, EL_CHAR('>') },
+ { Xalpha_arrow_w, EL_CHAR('<') },
+ { Xalpha_copyr, EL_CHAR('©') },
+
+ { Zplayer, EL_PLAYER_1 },
+ { Zplayer, EL_PLAYER_2 },
+ { Zplayer, EL_PLAYER_3 },
+ { Zplayer, EL_PLAYER_4 },
+
+ { ZBORDER, EL_EMC_LEVEL_BORDER },
+
+ { -1, -1 }
+ };
- event_mask = GD_EVENT_RELEASED;
+ if (!mapping_initialized)
+ {
+ int i;
- gd_xoffset = toolbutton_info[i].xpos;
- gd_yoffset = toolbutton_info[i].ypos;
- gd_x1 = DOOR_GFX_PAGEX4 + gd_xoffset;
- gd_x2 = DOOR_GFX_PAGEX3 + gd_xoffset;
- gd_y = DOOR_GFX_PAGEY1 + gd_yoffset;
+ /* return "Xalpha_quest" for all undefined elements in mapping array */
+ for (i = 0; i < NUM_FILE_ELEMENTS; i++)
+ mapping_RND_to_EM[i] = Xalpha_quest;
- if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
- {
- int player_nr = id - TOOL_CTRL_ID_PLAYER_1;
+ for (i = 0; mapping_RND_to_EM_list[i].element_rnd != -1; i++)
+ mapping_RND_to_EM[mapping_RND_to_EM_list[i].element_rnd] =
+ mapping_RND_to_EM_list[i].element_em;
- getMiniGraphicSource(PLAYER_NR_GFX(IMG_PLAYER_1, player_nr),
- &deco_bitmap, &deco_x, &deco_y);
- deco_xpos = (toolbutton_info[i].width - MINI_TILEX) / 2;
- deco_ypos = (toolbutton_info[i].height - MINI_TILEY) / 2;
- }
+ mapping_initialized = TRUE;
+ }
- gi = CreateGadget(GDI_CUSTOM_ID, id,
- GDI_INFO_TEXT, toolbutton_info[i].infotext,
- GDI_X, DX + toolbutton_info[i].x,
- GDI_Y, DY + toolbutton_info[i].y,
- GDI_WIDTH, toolbutton_info[i].width,
- GDI_HEIGHT, toolbutton_info[i].height,
- GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
- GDI_STATE, GD_BUTTON_UNPRESSED,
- GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
- GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
- GDI_DECORATION_DESIGN, deco_bitmap, deco_x, deco_y,
- GDI_DECORATION_POSITION, deco_xpos, deco_ypos,
- GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
- GDI_DECORATION_SHIFTING, 1, 1,
- GDI_EVENT_MASK, event_mask,
- GDI_CALLBACK_ACTION, HandleToolButtons,
- GDI_END);
+ if (element_rnd >= 0 && element_rnd < NUM_FILE_ELEMENTS)
+ return mapping_RND_to_EM[element_rnd];
- if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
+ Error(ERR_WARN, "invalid RND level element %d", element_rnd);
- tool_gadget[id] = gi;
- }
+ return EL_UNKNOWN;
}
-void FreeToolButtons()
+int map_element_EM_to_RND(int element_em)
{
- int i;
+ static unsigned short mapping_EM_to_RND[TILE_MAX];
+ static boolean mapping_initialized = FALSE;
- for (i = 0; i < NUM_TOOL_BUTTONS; i++)
- FreeGadget(tool_gadget[i]);
-}
+ struct
+ {
+ int element_em;
+ int element_rnd;
+ }
+ em_object_mapping_list[] =
+ {
+ { Xblank, EL_EMPTY },
+ { Yacid_splash_eB, EL_EMPTY },
+ { Yacid_splash_wB, EL_EMPTY },
+
+#ifdef EM_ENGINE_BAD_ROLL
+ { Xstone_force_e, EL_ROCK },
+ { Xstone_force_w, EL_ROCK },
+ { Xnut_force_e, EL_NUT },
+ { Xnut_force_w, EL_NUT },
+ { Xspring_force_e, EL_SPRING },
+ { Xspring_force_w, EL_SPRING },
+ { Xemerald_force_e, EL_EMERALD },
+ { Xemerald_force_w, EL_EMERALD },
+ { Xdiamond_force_e, EL_DIAMOND },
+ { Xdiamond_force_w, EL_DIAMOND },
+ { Xbomb_force_e, EL_BOMB },
+ { Xbomb_force_w, EL_BOMB },
+#endif
-static void UnmapToolButtons()
-{
- int i;
+ { Xstone, EL_ROCK },
+ { Xstone_pause, EL_ROCK },
+ { Xstone_fall, EL_ROCK },
+ { Ystone_s, EL_ROCK },
+ { Ystone_sB, EL_ROCK },
+ { Ystone_e, EL_ROCK },
+ { Ystone_eB, EL_ROCK },
+ { Ystone_w, EL_ROCK },
+ { Ystone_wB, EL_ROCK },
+ { Xnut, EL_NUT },
+ { Xnut_pause, EL_NUT },
+ { Xnut_fall, EL_NUT },
+ { Ynut_s, EL_NUT },
+ { Ynut_sB, EL_NUT },
+ { Ynut_e, EL_NUT },
+ { Ynut_eB, EL_NUT },
+ { Ynut_w, EL_NUT },
+ { Ynut_wB, EL_NUT },
+ { Xbug_n, EL_BUG_UP },
+ { Xbug_e, EL_BUG_RIGHT },
+ { Xbug_s, EL_BUG_DOWN },
+ { Xbug_w, EL_BUG_LEFT },
+ { Xbug_gon, EL_BUG_UP },
+ { Xbug_goe, EL_BUG_RIGHT },
+ { Xbug_gos, EL_BUG_DOWN },
+ { Xbug_gow, EL_BUG_LEFT },
+ { Ybug_n, EL_BUG_UP },
+ { Ybug_nB, EL_BUG_UP },
+ { Ybug_e, EL_BUG_RIGHT },
+ { Ybug_eB, EL_BUG_RIGHT },
+ { Ybug_s, EL_BUG_DOWN },
+ { Ybug_sB, EL_BUG_DOWN },
+ { Ybug_w, EL_BUG_LEFT },
+ { Ybug_wB, EL_BUG_LEFT },
+ { Ybug_w_n, EL_BUG_UP },
+ { Ybug_n_e, EL_BUG_RIGHT },
+ { Ybug_e_s, EL_BUG_DOWN },
+ { Ybug_s_w, EL_BUG_LEFT },
+ { Ybug_e_n, EL_BUG_UP },
+ { Ybug_s_e, EL_BUG_RIGHT },
+ { Ybug_w_s, EL_BUG_DOWN },
+ { Ybug_n_w, EL_BUG_LEFT },
+ { Ybug_stone, EL_ROCK },
+ { Ybug_spring, EL_SPRING },
+ { Xtank_n, EL_SPACESHIP_UP },
+ { Xtank_e, EL_SPACESHIP_RIGHT },
+ { Xtank_s, EL_SPACESHIP_DOWN },
+ { Xtank_w, EL_SPACESHIP_LEFT },
+ { Xtank_gon, EL_SPACESHIP_UP },
+ { Xtank_goe, EL_SPACESHIP_RIGHT },
+ { Xtank_gos, EL_SPACESHIP_DOWN },
+ { Xtank_gow, EL_SPACESHIP_LEFT },
+ { Ytank_n, EL_SPACESHIP_UP },
+ { Ytank_nB, EL_SPACESHIP_UP },
+ { Ytank_e, EL_SPACESHIP_RIGHT },
+ { Ytank_eB, EL_SPACESHIP_RIGHT },
+ { Ytank_s, EL_SPACESHIP_DOWN },
+ { Ytank_sB, EL_SPACESHIP_DOWN },
+ { Ytank_w, EL_SPACESHIP_LEFT },
+ { Ytank_wB, EL_SPACESHIP_LEFT },
+ { Ytank_w_n, EL_SPACESHIP_UP },
+ { Ytank_n_e, EL_SPACESHIP_RIGHT },
+ { Ytank_e_s, EL_SPACESHIP_DOWN },
+ { Ytank_s_w, EL_SPACESHIP_LEFT },
+ { Ytank_e_n, EL_SPACESHIP_UP },
+ { Ytank_s_e, EL_SPACESHIP_RIGHT },
+ { Ytank_w_s, EL_SPACESHIP_DOWN },
+ { Ytank_n_w, EL_SPACESHIP_LEFT },
+ { Ytank_stone, EL_ROCK },
+ { Ytank_spring, EL_SPRING },
+ { Xandroid, EL_EMC_ANDROID },
+ { Xandroid_1_n, EL_EMC_ANDROID_UP },
+ { Xandroid_2_n, EL_EMC_ANDROID_UP },
+ { Xandroid_1_e, EL_EMC_ANDROID_RIGHT },
+ { Xandroid_2_e, EL_EMC_ANDROID_RIGHT },
+ { Xandroid_1_w, EL_EMC_ANDROID_LEFT },
+ { Xandroid_2_w, EL_EMC_ANDROID_LEFT },
+ { Xandroid_1_s, EL_EMC_ANDROID_DOWN },
+ { Xandroid_2_s, EL_EMC_ANDROID_DOWN },
+ { Yandroid_n, EL_EMC_ANDROID_UP },
+ { Yandroid_nB, EL_EMC_ANDROID_UP },
+ { Yandroid_ne, EL_EMC_ANDROID_RIGHT_UP },
+ { Yandroid_neB, EL_EMC_ANDROID_RIGHT_UP },
+ { Yandroid_e, EL_EMC_ANDROID_RIGHT },
+ { Yandroid_eB, EL_EMC_ANDROID_RIGHT },
+ { Yandroid_se, EL_EMC_ANDROID_RIGHT_DOWN },
+ { Yandroid_seB, EL_EMC_ANDROID_RIGHT_DOWN },
+ { Yandroid_s, EL_EMC_ANDROID_DOWN },
+ { Yandroid_sB, EL_EMC_ANDROID_DOWN },
+ { Yandroid_sw, EL_EMC_ANDROID_LEFT_DOWN },
+ { Yandroid_swB, EL_EMC_ANDROID_LEFT_DOWN },
+ { Yandroid_w, EL_EMC_ANDROID_LEFT },
+ { Yandroid_wB, EL_EMC_ANDROID_LEFT },
+ { Yandroid_nw, EL_EMC_ANDROID_LEFT_UP },
+ { Yandroid_nwB, EL_EMC_ANDROID_LEFT_UP },
+ { Xspring, EL_SPRING },
+ { Xspring_pause, EL_SPRING },
+ { Xspring_e, EL_SPRING },
+ { Xspring_w, EL_SPRING },
+ { Xspring_fall, EL_SPRING },
+ { Yspring_s, EL_SPRING },
+ { Yspring_sB, EL_SPRING },
+ { Yspring_e, EL_SPRING },
+ { Yspring_eB, EL_SPRING },
+ { Yspring_w, EL_SPRING },
+ { Yspring_wB, EL_SPRING },
+ { Yspring_kill_e, EL_SPRING },
+ { Yspring_kill_eB, EL_SPRING },
+ { Yspring_kill_w, EL_SPRING },
+ { Yspring_kill_wB, EL_SPRING },
+ { Xeater_n, EL_YAMYAM },
+ { Xeater_e, EL_YAMYAM },
+ { Xeater_w, EL_YAMYAM },
+ { Xeater_s, EL_YAMYAM },
+ { Yeater_n, EL_YAMYAM },
+ { Yeater_nB, EL_YAMYAM },
+ { Yeater_e, EL_YAMYAM },
+ { Yeater_eB, EL_YAMYAM },
+ { Yeater_s, EL_YAMYAM },
+ { Yeater_sB, EL_YAMYAM },
+ { Yeater_w, EL_YAMYAM },
+ { Yeater_wB, EL_YAMYAM },
+ { Yeater_stone, EL_ROCK },
+ { Yeater_spring, EL_SPRING },
+ { Xalien, EL_ROBOT },
+ { Xalien_pause, EL_ROBOT },
+ { Yalien_n, EL_ROBOT },
+ { Yalien_nB, EL_ROBOT },
+ { Yalien_e, EL_ROBOT },
+ { Yalien_eB, EL_ROBOT },
+ { Yalien_s, EL_ROBOT },
+ { Yalien_sB, EL_ROBOT },
+ { Yalien_w, EL_ROBOT },
+ { Yalien_wB, EL_ROBOT },
+ { Yalien_stone, EL_ROCK },
+ { Yalien_spring, EL_SPRING },
+ { Xemerald, EL_EMERALD },
+ { Xemerald_pause, EL_EMERALD },
+ { Xemerald_fall, EL_EMERALD },
+ { Xemerald_shine, EL_EMERALD },
+ { Yemerald_s, EL_EMERALD },
+ { Yemerald_sB, EL_EMERALD },
+ { Yemerald_e, EL_EMERALD },
+ { Yemerald_eB, EL_EMERALD },
+ { Yemerald_w, EL_EMERALD },
+ { Yemerald_wB, EL_EMERALD },
+ { Yemerald_eat, EL_EMERALD },
+ { Yemerald_stone, EL_ROCK },
+ { Xdiamond, EL_DIAMOND },
+ { Xdiamond_pause, EL_DIAMOND },
+ { Xdiamond_fall, EL_DIAMOND },
+ { Xdiamond_shine, EL_DIAMOND },
+ { Ydiamond_s, EL_DIAMOND },
+ { Ydiamond_sB, EL_DIAMOND },
+ { Ydiamond_e, EL_DIAMOND },
+ { Ydiamond_eB, EL_DIAMOND },
+ { Ydiamond_w, EL_DIAMOND },
+ { Ydiamond_wB, EL_DIAMOND },
+ { Ydiamond_eat, EL_DIAMOND },
+ { Ydiamond_stone, EL_ROCK },
+ { Xdrip_fall, EL_AMOEBA_DROP },
+ { Xdrip_stretch, EL_AMOEBA_DROP },
+ { Xdrip_stretchB, EL_AMOEBA_DROP },
+ { Xdrip_eat, EL_AMOEBA_DROP },
+ { Ydrip_s1, EL_AMOEBA_DROP },
+ { Ydrip_s1B, EL_AMOEBA_DROP },
+ { Ydrip_s2, EL_AMOEBA_DROP },
+ { Ydrip_s2B, EL_AMOEBA_DROP },
+ { Xbomb, EL_BOMB },
+ { Xbomb_pause, EL_BOMB },
+ { Xbomb_fall, EL_BOMB },
+ { Ybomb_s, EL_BOMB },
+ { Ybomb_sB, EL_BOMB },
+ { Ybomb_e, EL_BOMB },
+ { Ybomb_eB, EL_BOMB },
+ { Ybomb_w, EL_BOMB },
+ { Ybomb_wB, EL_BOMB },
+ { Ybomb_eat, EL_BOMB },
+ { Xballoon, EL_BALLOON },
+ { Yballoon_n, EL_BALLOON },
+ { Yballoon_nB, EL_BALLOON },
+ { Yballoon_e, EL_BALLOON },
+ { Yballoon_eB, EL_BALLOON },
+ { Yballoon_s, EL_BALLOON },
+ { Yballoon_sB, EL_BALLOON },
+ { Yballoon_w, EL_BALLOON },
+ { Yballoon_wB, EL_BALLOON },
+ { Xgrass, EL_SAND },
+ { Ygrass_nB, EL_SAND },
+ { Ygrass_eB, EL_SAND },
+ { Ygrass_sB, EL_SAND },
+ { Ygrass_wB, EL_SAND },
+ { Xdirt, EL_SAND },
+ { Ydirt_nB, EL_SAND },
+ { Ydirt_eB, EL_SAND },
+ { Ydirt_sB, EL_SAND },
+ { Ydirt_wB, EL_SAND },
+ { Xacid_ne, EL_ACID_POOL_TOPRIGHT },
+ { Xacid_se, EL_ACID_POOL_BOTTOMRIGHT },
+ { Xacid_s, EL_ACID_POOL_BOTTOM },
+ { Xacid_sw, EL_ACID_POOL_BOTTOMLEFT },
+ { Xacid_nw, EL_ACID_POOL_TOPLEFT },
+ { Xacid_1, EL_ACID },
+ { Xacid_2, EL_ACID },
+ { Xacid_3, EL_ACID },
+ { Xacid_4, EL_ACID },
+ { Xacid_5, EL_ACID },
+ { Xacid_6, EL_ACID },
+ { Xacid_7, EL_ACID },
+ { Xacid_8, EL_ACID },
+ { Xball_1, EL_EMC_MAGIC_BALL },
+ { Xball_1B, EL_EMC_MAGIC_BALL },
+ { Xball_2, EL_EMC_MAGIC_BALL },
+ { Xball_2B, EL_EMC_MAGIC_BALL },
+ { Yball_eat, EL_EMC_MAGIC_BALL },
+ { Xgrow_ns, EL_EMC_GROW },
+ { Ygrow_ns_eat, EL_EMC_GROW },
+ { Xgrow_ew, EL_EMC_GROW },
+ { Ygrow_ew_eat, EL_EMC_GROW },
+ { Xwonderwall, EL_MAGIC_WALL },
+ { XwonderwallB, EL_MAGIC_WALL },
+ { Xamoeba_1, EL_AMOEBA_WET },
+ { Xamoeba_2, EL_AMOEBA_WET },
+ { Xamoeba_3, EL_AMOEBA_WET },
+ { Xamoeba_4, EL_AMOEBA_WET },
+ { Xamoeba_5, EL_AMOEBA_WET },
+ { Xamoeba_6, EL_AMOEBA_WET },
+ { Xamoeba_7, EL_AMOEBA_WET },
+ { Xamoeba_8, EL_AMOEBA_WET },
+ { Xdoor_1, EL_EM_GATE_1 },
+ { Xdoor_2, EL_EM_GATE_2 },
+ { Xdoor_3, EL_EM_GATE_3 },
+ { Xdoor_4, EL_EM_GATE_4 },
+ { Xdoor_5, EL_EMC_GATE_5 },
+ { Xdoor_6, EL_EMC_GATE_6 },
+ { Xdoor_7, EL_EMC_GATE_7 },
+ { Xdoor_8, EL_EMC_GATE_8 },
+ { Xkey_1, EL_EM_KEY_1 },
+ { Xkey_2, EL_EM_KEY_2 },
+ { Xkey_3, EL_EM_KEY_3 },
+ { Xkey_4, EL_EM_KEY_4 },
+ { Xkey_5, EL_EMC_KEY_5 },
+ { Xkey_6, EL_EMC_KEY_6 },
+ { Xkey_7, EL_EMC_KEY_7 },
+ { Xkey_8, EL_EMC_KEY_8 },
+ { Xwind_n, EL_BALLOON_SWITCH_UP },
+ { Xwind_e, EL_BALLOON_SWITCH_RIGHT },
+ { Xwind_s, EL_BALLOON_SWITCH_DOWN },
+ { Xwind_w, EL_BALLOON_SWITCH_LEFT },
+ { Xwind_nesw, EL_BALLOON_SWITCH_ANY },
+ { Xwind_stop, EL_BALLOON_SWITCH_NONE },
+ { Xexit, EL_EXIT_CLOSED },
+ { Xexit_1, EL_EXIT_OPEN },
+ { Xexit_2, EL_EXIT_OPEN },
+ { Xexit_3, EL_EXIT_OPEN },
+ { Xdynamite, EL_DYNAMITE },
+ { Ydynamite_eat, EL_DYNAMITE },
+ { Xdynamite_1, EL_DYNAMITE_ACTIVE },
+ { Xdynamite_2, EL_DYNAMITE_ACTIVE },
+ { Xdynamite_3, EL_DYNAMITE_ACTIVE },
+ { Xdynamite_4, EL_DYNAMITE_ACTIVE },
+ { Xbumper, EL_EMC_BUMPER },
+ { XbumperB, EL_EMC_BUMPER },
+ { Xwheel, EL_ROBOT_WHEEL },
+ { XwheelB, EL_ROBOT_WHEEL },
+ { Xswitch, EL_UNKNOWN },
+ { XswitchB, EL_UNKNOWN },
+ { Xsand, EL_QUICKSAND_EMPTY },
+ { Xsand_stone, EL_QUICKSAND_FULL },
+ { Xsand_stonein_1, EL_QUICKSAND_FULL },
+ { Xsand_stonein_2, EL_QUICKSAND_FULL },
+ { Xsand_stonein_3, EL_QUICKSAND_FULL },
+ { Xsand_stonein_4, EL_QUICKSAND_FULL },
+ { Xsand_stonesand_1, EL_QUICKSAND_FULL },
+ { Xsand_stonesand_2, EL_QUICKSAND_FULL },
+ { Xsand_stonesand_3, EL_QUICKSAND_FULL },
+ { Xsand_stonesand_4, EL_QUICKSAND_FULL },
+ { Xsand_stoneout_1, EL_QUICKSAND_FULL },
+ { Xsand_stoneout_2, EL_QUICKSAND_FULL },
+ { Xsand_sandstone_1, EL_QUICKSAND_FULL },
+ { Xsand_sandstone_2, EL_QUICKSAND_FULL },
+ { Xsand_sandstone_3, EL_QUICKSAND_FULL },
+ { Xsand_sandstone_4, EL_QUICKSAND_FULL },
+ { Xplant, EL_EMC_PLANT },
+ { Yplant, EL_EMC_PLANT },
+ { Xlenses, EL_EMC_LENSES },
+ { Xmagnify, EL_EMC_MAGNIFIER },
+ { Xdripper, EL_UNKNOWN },
+ { XdripperB, EL_UNKNOWN },
+ { Xfake_blank, EL_INVISIBLE_WALL },
+ { Xfake_blankB, EL_INVISIBLE_WALL },
+ { Xfake_grass, EL_INVISIBLE_SAND },
+ { Xfake_grassB, EL_INVISIBLE_SAND },
+ { Xfake_door_1, EL_EM_GATE_1_GRAY },
+ { Xfake_door_2, EL_EM_GATE_2_GRAY },
+ { Xfake_door_3, EL_EM_GATE_3_GRAY },
+ { Xfake_door_4, EL_EM_GATE_4_GRAY },
+ { Xfake_door_5, EL_EMC_GATE_5_GRAY },
+ { Xfake_door_6, EL_EMC_GATE_6_GRAY },
+ { Xfake_door_7, EL_EMC_GATE_7_GRAY },
+ { Xfake_door_8, EL_EMC_GATE_8_GRAY },
+ { Xsteel_1, EL_STEELWALL },
+ { Xsteel_2, EL_UNKNOWN },
+ { Xsteel_3, EL_EMC_STEELWALL_1 },
+ { Xsteel_4, EL_UNKNOWN },
+ { Xwall_1, EL_WALL },
+ { Xwall_2, EL_UNKNOWN },
+ { Xwall_3, EL_UNKNOWN },
+ { Xwall_4, EL_UNKNOWN },
+ { Xround_wall_1, EL_WALL_SLIPPERY },
+ { Xround_wall_2, EL_UNKNOWN },
+ { Xround_wall_3, EL_UNKNOWN },
+ { Xround_wall_4, EL_UNKNOWN },
+ { Xdecor_1, EL_UNKNOWN },
+ { Xdecor_2, EL_EMC_WALL_6 },
+ { Xdecor_3, EL_EMC_WALL_4 },
+ { Xdecor_4, EL_EMC_WALL_5 },
+ { Xdecor_5, EL_EMC_WALL_7 },
+ { Xdecor_6, EL_EMC_WALL_8 },
+ { Xdecor_7, EL_UNKNOWN },
+ { Xdecor_8, EL_EMC_WALL_1 },
+ { Xdecor_9, EL_EMC_WALL_2 },
+ { Xdecor_10, EL_EMC_WALL_3 },
+ { Xdecor_11, EL_UNKNOWN },
+ { Xdecor_12, EL_UNKNOWN },
+ { Xalpha_0, EL_CHAR('0') },
+ { Xalpha_1, EL_CHAR('1') },
+ { Xalpha_2, EL_CHAR('2') },
+ { Xalpha_3, EL_CHAR('3') },
+ { Xalpha_4, EL_CHAR('4') },
+ { Xalpha_5, EL_CHAR('5') },
+ { Xalpha_6, EL_CHAR('6') },
+ { Xalpha_7, EL_CHAR('7') },
+ { Xalpha_8, EL_CHAR('8') },
+ { Xalpha_9, EL_CHAR('9') },
+ { Xalpha_excla, EL_CHAR('!') },
+ { Xalpha_quote, EL_CHAR('"') },
+ { Xalpha_comma, EL_CHAR(',') },
+ { Xalpha_minus, EL_CHAR('-') },
+ { Xalpha_perio, EL_CHAR('.') },
+ { Xalpha_colon, EL_CHAR(':') },
+ { Xalpha_quest, EL_CHAR('?') },
+ { Xalpha_a, EL_CHAR('A') },
+ { Xalpha_b, EL_CHAR('B') },
+ { Xalpha_c, EL_CHAR('C') },
+ { Xalpha_d, EL_CHAR('D') },
+ { Xalpha_e, EL_CHAR('E') },
+ { Xalpha_f, EL_CHAR('F') },
+ { Xalpha_g, EL_CHAR('G') },
+ { Xalpha_h, EL_CHAR('H') },
+ { Xalpha_i, EL_CHAR('I') },
+ { Xalpha_j, EL_CHAR('J') },
+ { Xalpha_k, EL_CHAR('K') },
+ { Xalpha_l, EL_CHAR('L') },
+ { Xalpha_m, EL_CHAR('M') },
+ { Xalpha_n, EL_CHAR('N') },
+ { Xalpha_o, EL_CHAR('O') },
+ { Xalpha_p, EL_CHAR('P') },
+ { Xalpha_q, EL_CHAR('Q') },
+ { Xalpha_r, EL_CHAR('R') },
+ { Xalpha_s, EL_CHAR('S') },
+ { Xalpha_t, EL_CHAR('T') },
+ { Xalpha_u, EL_CHAR('U') },
+ { Xalpha_v, EL_CHAR('V') },
+ { Xalpha_w, EL_CHAR('W') },
+ { Xalpha_x, EL_CHAR('X') },
+ { Xalpha_y, EL_CHAR('Y') },
+ { Xalpha_z, EL_CHAR('Z') },
+ { Xalpha_arrow_e, EL_CHAR('>') },
+ { Xalpha_arrow_w, EL_CHAR('<') },
+ { Xalpha_copyr, EL_CHAR('©') },
+
+ { Zplayer, EL_PLAYER_1 },
+
+ { ZBORDER, EL_EMC_LEVEL_BORDER },
+
+ { -1, -1 }
+ };
- for (i = 0; i < NUM_TOOL_BUTTONS; i++)
- UnmapGadget(tool_gadget[i]);
-}
+ if (!mapping_initialized)
+ {
+ int i;
-static void HandleToolButtons(struct GadgetInfo *gi)
-{
- request_gadget_id = gi->custom_id;
+ /* return "EL_UNKNOWN" for all undefined elements in mapping array */
+ for (i = 0; i < TILE_MAX; i++)
+ mapping_EM_to_RND[i] = EL_UNKNOWN;
+
+ for (i = 0; em_object_mapping_list[i].element_em != -1; i++)
+ mapping_EM_to_RND[em_object_mapping_list[i].element_em] =
+ em_object_mapping_list[i].element_rnd;
+
+ mapping_initialized = TRUE;
+ }
+
+ if (element_em >= 0 && element_em < TILE_MAX)
+ return mapping_EM_to_RND[element_em];
+
+ Error(ERR_WARN, "invalid EM level element %d", element_em);
+
+ return EL_UNKNOWN;
}
+#endif
+
int get_next_element(int element)
{
switch(element)
}
}
+#if 0
+int el_act_dir2img(int element, int action, int direction)
+{
+ element = GFX_ELEMENT(element);
+
+ if (direction == MV_NO_MOVING)
+ return element_info[element].graphic[action];
+
+ direction = MV_DIR_BIT(direction);
+
+ return element_info[element].direction_graphic[action][direction];
+}
+#else
int el_act_dir2img(int element, int action, int direction)
{
element = GFX_ELEMENT(element);
direction = MV_DIR_BIT(direction); /* default: MV_NO_MOVING => MV_DOWN */
+ /* direction_graphic[][] == graphic[] for undefined direction graphics */
return element_info[element].direction_graphic[action][direction];
}
+#endif
+#if 0
+static int el_act_dir2crm(int element, int action, int direction)
+{
+ element = GFX_ELEMENT(element);
+
+ if (direction == MV_NO_MOVING)
+ return element_info[element].crumbled[action];
+
+ direction = MV_DIR_BIT(direction);
+
+ return element_info[element].direction_crumbled[action][direction];
+}
+#else
static int el_act_dir2crm(int element, int action, int direction)
{
element = GFX_ELEMENT(element);
direction = MV_DIR_BIT(direction); /* default: MV_NO_MOVING => MV_DOWN */
+ /* direction_graphic[][] == graphic[] for undefined direction graphics */
return element_info[element].direction_crumbled[action][direction];
}
+#endif
int el_act2img(int element, int action)
{
return element_info[element].special_graphic[GFX_SPECIAL_ARG_PREVIEW];
}
+
+int getGameFrameDelay_EM(int native_em_game_frame_delay)
+{
+ int game_frame_delay_value;
+
+ game_frame_delay_value =
+ (tape.playing && tape.fast_forward ? FfwdFrameDelay :
+ GameFrameDelay == GAME_FRAME_DELAY ? native_em_game_frame_delay :
+ GameFrameDelay);
+
+ if (tape.playing && tape.warp_forward && !tape.pausing)
+ game_frame_delay_value = 0;
+
+ return game_frame_delay_value;
+}
+
+unsigned int InitRND(long seed)
+{
+ if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ return InitEngineRND_EM(seed);
+ else
+ return InitEngineRND(seed);
+}
+
+#define DEBUG_EM_GFX 0
+
+void InitGraphicInfo_EM(void)
+{
+ struct Mapping_EM_to_RND_object object_mapping[TILE_MAX];
+ struct Mapping_EM_to_RND_player player_mapping[2][SPR_MAX];
+ int i, j, p;
+
+#if DEBUG_EM_GFX
+ if (graphic_info_em_object[0][0].bitmap == NULL)
+ {
+ /* EM graphics not yet initialized in em_open_all() */
+
+ return;
+ }
+#endif
+
+ /* always start with reliable default values */
+ for (i = 0; i < TILE_MAX; i++)
+ {
+ object_mapping[i].element_rnd = EL_UNKNOWN;
+ object_mapping[i].is_backside = FALSE;
+ object_mapping[i].action = ACTION_DEFAULT;
+ object_mapping[i].direction = MV_NO_MOVING;
+ }
+
+ /* always start with reliable default values */
+ for (p = 0; p < 2; p++)
+ {
+ for (i = 0; i < SPR_MAX; i++)
+ {
+ player_mapping[p][i].element_rnd = EL_UNKNOWN;
+ player_mapping[p][i].action = ACTION_DEFAULT;
+ player_mapping[p][i].direction = MV_NO_MOVING;
+ }
+ }
+
+ for (i = 0; em_object_mapping_list[i].element_em != -1; i++)
+ {
+ int e = em_object_mapping_list[i].element_em;
+
+ object_mapping[e].element_rnd = em_object_mapping_list[i].element_rnd;
+ object_mapping[e].is_backside = em_object_mapping_list[i].is_backside;
+
+ if (em_object_mapping_list[i].action != -1)
+ object_mapping[e].action = em_object_mapping_list[i].action;
+
+ if (em_object_mapping_list[i].direction != -1)
+ object_mapping[e].direction = (1 << em_object_mapping_list[i].direction);
+ }
+
+ for (i = 0; em_player_mapping_list[i].action_em != -1; i++)
+ {
+ int a = em_player_mapping_list[i].action_em;
+ int p = em_player_mapping_list[i].player_nr;
+
+ player_mapping[p][a].element_rnd = em_player_mapping_list[i].element_rnd;
+
+ if (em_player_mapping_list[i].action != -1)
+ player_mapping[p][a].action = em_player_mapping_list[i].action;
+
+ if (em_player_mapping_list[i].direction != -1)
+ player_mapping[p][a].direction =
+ (1 << em_player_mapping_list[i].direction);
+ }
+
+ for (i = 0; i < TILE_MAX; i++)
+ {
+ int element = object_mapping[i].element_rnd;
+ int action = object_mapping[i].action;
+ int direction = object_mapping[i].direction;
+ boolean is_backside = object_mapping[i].is_backside;
+ boolean action_removing = (action == ACTION_DIGGING ||
+ action == ACTION_SNAPPING ||
+ action == ACTION_COLLECTING);
+ boolean action_exploding = ((action == ACTION_EXPLODING ||
+ action == ACTION_SMASHED_BY_ROCK ||
+ action == ACTION_SMASHED_BY_SPRING) &&
+ element != EL_DIAMOND);
+ boolean action_active = (action == ACTION_ACTIVE);
+ boolean action_other = (action == ACTION_OTHER);
+
+ for (j = 0; j < 8; j++)
+ {
+ int effective_element = (j > 5 && i == Yacid_splash_eB ? EL_EMPTY :
+ j > 5 && i == Yacid_splash_wB ? EL_EMPTY :
+ j < 7 ? element :
+ i == Xdrip_stretch ? element :
+ i == Xdrip_stretchB ? element :
+ i == Ydrip_s1 ? element :
+ i == Ydrip_s1B ? element :
+ i == Xball_1B ? element :
+ i == Xball_2 ? element :
+ i == Xball_2B ? element :
+ i == Yball_eat ? element :
+ i == Ykey_1_eat ? element :
+ i == Ykey_2_eat ? element :
+ i == Ykey_3_eat ? element :
+ i == Ykey_4_eat ? element :
+ i == Ykey_5_eat ? element :
+ i == Ykey_6_eat ? element :
+ i == Ykey_7_eat ? element :
+ i == Ykey_8_eat ? element :
+ i == Ylenses_eat ? element :
+ i == Ymagnify_eat ? element :
+ i == Ygrass_eat ? element :
+ i == Ydirt_eat ? element :
+ i == Yspring_kill_e ? EL_SPRING :
+ i == Yspring_kill_w ? EL_SPRING :
+ i == Yemerald_stone ? EL_EMERALD :
+ i == Ydiamond_stone ? EL_ROCK :
+ i == Xsand_stonein_4 ? EL_EMPTY :
+ i == Xsand_stoneout_2 ? EL_ROCK :
+ is_backside ? EL_EMPTY :
+ action_removing ? EL_EMPTY :
+ element);
+ int effective_action = (j < 7 ? action :
+ i == Xdrip_stretch ? action :
+ i == Xdrip_stretchB ? action :
+ i == Ydrip_s1 ? action :
+ i == Ydrip_s1B ? action :
+ i == Xball_1B ? action :
+ i == Xball_2 ? action :
+ i == Xball_2B ? action :
+ i == Yball_eat ? action :
+ i == Ykey_1_eat ? action :
+ i == Ykey_2_eat ? action :
+ i == Ykey_3_eat ? action :
+ i == Ykey_4_eat ? action :
+ i == Ykey_5_eat ? action :
+ i == Ykey_6_eat ? action :
+ i == Ykey_7_eat ? action :
+ i == Ykey_8_eat ? action :
+ i == Ylenses_eat ? action :
+ i == Ymagnify_eat ? action :
+ i == Ygrass_eat ? action :
+ i == Ydirt_eat ? action :
+ i == Xsand_stonein_1 ? action :
+ i == Xsand_stonein_2 ? action :
+ i == Xsand_stonein_3 ? action :
+ i == Xsand_stonein_4 ? action :
+ i == Xsand_stoneout_1 ? action :
+ i == Xsand_stoneout_2 ? action :
+ i == Xboom_android ? ACTION_EXPLODING :
+ action_exploding ? ACTION_EXPLODING :
+ action_active ? action :
+ action_other ? action :
+ ACTION_DEFAULT);
+ int graphic = (el_act_dir2img(effective_element, effective_action,
+ direction));
+ int crumbled = (el_act_dir2crm(effective_element, effective_action,
+ direction));
+ int base_graphic = el_act2img(effective_element, ACTION_DEFAULT);
+ int base_crumbled = el_act2crm(effective_element, ACTION_DEFAULT);
+ boolean has_crumbled_graphics = (base_crumbled != base_graphic);
+ struct GraphicInfo *g = &graphic_info[graphic];
+ struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][7 - j];
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ /* ensure to get symmetric 3-frame, 2-delay animations as used in EM */
+ boolean special_animation = (action != ACTION_DEFAULT &&
+ g->anim_frames == 3 &&
+ g->anim_delay == 2 &&
+ g->anim_mode & ANIM_LINEAR);
+ int sync_frame = (i == Xdrip_stretch ? 7 :
+ i == Xdrip_stretchB ? 7 :
+ i == Ydrip_s2 ? j + 8 :
+ i == Ydrip_s2B ? j + 8 :
+ i == Xacid_1 ? 0 :
+ i == Xacid_2 ? 10 :
+ i == Xacid_3 ? 20 :
+ i == Xacid_4 ? 30 :
+ i == Xacid_5 ? 40 :
+ i == Xacid_6 ? 50 :
+ i == Xacid_7 ? 60 :
+ i == Xacid_8 ? 70 :
+ i == Xfake_acid_1 ? 0 :
+ i == Xfake_acid_2 ? 10 :
+ i == Xfake_acid_3 ? 20 :
+ i == Xfake_acid_4 ? 30 :
+ i == Xfake_acid_5 ? 40 :
+ i == Xfake_acid_6 ? 50 :
+ i == Xfake_acid_7 ? 60 :
+ i == Xfake_acid_8 ? 70 :
+ i == Xball_2 ? 7 :
+ i == Xball_2B ? j + 8 :
+ i == Yball_eat ? j + 1 :
+ i == Ykey_1_eat ? j + 1 :
+ i == Ykey_2_eat ? j + 1 :
+ i == Ykey_3_eat ? j + 1 :
+ i == Ykey_4_eat ? j + 1 :
+ i == Ykey_5_eat ? j + 1 :
+ i == Ykey_6_eat ? j + 1 :
+ i == Ykey_7_eat ? j + 1 :
+ i == Ykey_8_eat ? j + 1 :
+ i == Ylenses_eat ? j + 1 :
+ i == Ymagnify_eat ? j + 1 :
+ i == Ygrass_eat ? j + 1 :
+ i == Ydirt_eat ? j + 1 :
+ i == Xamoeba_1 ? 0 :
+ i == Xamoeba_2 ? 1 :
+ i == Xamoeba_3 ? 2 :
+ i == Xamoeba_4 ? 3 :
+ i == Xamoeba_5 ? 0 :
+ i == Xamoeba_6 ? 1 :
+ i == Xamoeba_7 ? 2 :
+ i == Xamoeba_8 ? 3 :
+ i == Xexit_2 ? j + 8 :
+ i == Xexit_3 ? j + 16 :
+ i == Xdynamite_1 ? 0 :
+ i == Xdynamite_2 ? 20 :
+ i == Xdynamite_3 ? 40 :
+ i == Xdynamite_4 ? 60 :
+ i == Xsand_stonein_1 ? j + 1 :
+ i == Xsand_stonein_2 ? j + 9 :
+ i == Xsand_stonein_3 ? j + 17 :
+ i == Xsand_stonein_4 ? j + 25 :
+ i == Xsand_stoneout_1 && j == 0 ? 0 :
+ i == Xsand_stoneout_1 && j == 1 ? 0 :
+ i == Xsand_stoneout_1 && j == 2 ? 1 :
+ i == Xsand_stoneout_1 && j == 3 ? 2 :
+ i == Xsand_stoneout_1 && j == 4 ? 2 :
+ i == Xsand_stoneout_1 && j == 5 ? 3 :
+ i == Xsand_stoneout_1 && j == 6 ? 4 :
+ i == Xsand_stoneout_1 && j == 7 ? 4 :
+ i == Xsand_stoneout_2 && j == 0 ? 5 :
+ i == Xsand_stoneout_2 && j == 1 ? 6 :
+ i == Xsand_stoneout_2 && j == 2 ? 7 :
+ i == Xsand_stoneout_2 && j == 3 ? 8 :
+ i == Xsand_stoneout_2 && j == 4 ? 9 :
+ i == Xsand_stoneout_2 && j == 5 ? 11 :
+ i == Xsand_stoneout_2 && j == 6 ? 13 :
+ i == Xsand_stoneout_2 && j == 7 ? 15 :
+ i == Xboom_bug && j == 1 ? 2 :
+ i == Xboom_bug && j == 2 ? 2 :
+ i == Xboom_bug && j == 3 ? 4 :
+ i == Xboom_bug && j == 4 ? 4 :
+ i == Xboom_bug && j == 5 ? 2 :
+ i == Xboom_bug && j == 6 ? 2 :
+ i == Xboom_bug && j == 7 ? 0 :
+ i == Xboom_bomb && j == 1 ? 2 :
+ i == Xboom_bomb && j == 2 ? 2 :
+ i == Xboom_bomb && j == 3 ? 4 :
+ i == Xboom_bomb && j == 4 ? 4 :
+ i == Xboom_bomb && j == 5 ? 2 :
+ i == Xboom_bomb && j == 6 ? 2 :
+ i == Xboom_bomb && j == 7 ? 0 :
+ i == Xboom_android && j == 7 ? 6 :
+ i == Xboom_1 && j == 1 ? 2 :
+ i == Xboom_1 && j == 2 ? 2 :
+ i == Xboom_1 && j == 3 ? 4 :
+ i == Xboom_1 && j == 4 ? 4 :
+ i == Xboom_1 && j == 5 ? 6 :
+ i == Xboom_1 && j == 6 ? 6 :
+ i == Xboom_1 && j == 7 ? 8 :
+ i == Xboom_2 && j == 0 ? 8 :
+ i == Xboom_2 && j == 1 ? 8 :
+ i == Xboom_2 && j == 2 ? 10 :
+ i == Xboom_2 && j == 3 ? 10 :
+ i == Xboom_2 && j == 4 ? 10 :
+ i == Xboom_2 && j == 5 ? 12 :
+ i == Xboom_2 && j == 6 ? 12 :
+ i == Xboom_2 && j == 7 ? 12 :
+ special_animation && j == 4 ? 3 :
+ effective_action != action ? 0 :
+ j);
+
+#if DEBUG_EM_GFX
+ Bitmap *debug_bitmap = g_em->bitmap;
+ int debug_src_x = g_em->src_x;
+ int debug_src_y = g_em->src_y;
+#endif
+
+ int frame = getAnimationFrame(g->anim_frames,
+ g->anim_delay,
+ g->anim_mode,
+ g->anim_start_frame,
+ sync_frame);
+
+ getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y,
+ g->double_movement && is_backside);
+
+#if 1
+ g_em->bitmap = src_bitmap;
+ g_em->src_x = src_x;
+ g_em->src_y = src_y;
+ g_em->src_offset_x = 0;
+ g_em->src_offset_y = 0;
+ g_em->dst_offset_x = 0;
+ g_em->dst_offset_y = 0;
+ g_em->width = TILEX;
+ g_em->height = TILEY;
+
+ g_em->crumbled_bitmap = NULL;
+ g_em->crumbled_src_x = 0;
+ g_em->crumbled_src_y = 0;
+ g_em->crumbled_border_size = 0;
+
+ g_em->has_crumbled_graphics = FALSE;
+ g_em->preserve_background = FALSE;
+#endif
+
+#if 0
+ if (effective_element == EL_EMC_GRASS &&
+ effective_action == ACTION_DIGGING)
+ printf("::: %d\n", crumbled);
+#endif
+
+#if 0
+ if (has_crumbled_graphics && crumbled == IMG_EMPTY_SPACE)
+ printf("::: empty crumbled: %d [%s], %d, %d\n",
+ effective_element, element_info[effective_element].token_name,
+ effective_action, direction);
+#endif
+
+ /* if element can be crumbled, but certain action graphics are just empty
+ space (like snapping sand with the original R'n'D graphics), do not
+ treat these empty space graphics as crumbled graphics in EMC engine */
+ if (has_crumbled_graphics && crumbled != IMG_EMPTY_SPACE)
+ {
+ getGraphicSource(crumbled, frame, &src_bitmap, &src_x, &src_y);
+
+ g_em->has_crumbled_graphics = TRUE;
+ g_em->crumbled_bitmap = src_bitmap;
+ g_em->crumbled_src_x = src_x;
+ g_em->crumbled_src_y = src_y;
+ g_em->crumbled_border_size = graphic_info[crumbled].border_size;
+ }
+
+#if 1
+ if (!g->double_movement && (effective_action == ACTION_FALLING ||
+ effective_action == ACTION_MOVING ||
+ effective_action == ACTION_PUSHING))
+ {
+ int move_dir =
+ (effective_action == ACTION_FALLING ? MV_DOWN : direction);
+ int dx = (move_dir == MV_LEFT ? -1 : move_dir == MV_RIGHT ? 1 : 0);
+ int dy = (move_dir == MV_UP ? -1 : move_dir == MV_DOWN ? 1 : 0);
+ int num_steps = (i == Ydrip_s1 ||
+ i == Ydrip_s1B ||
+ i == Ydrip_s2 ||
+ i == Ydrip_s2B ? 16 : 8);
+ int cx = ABS(dx) * (TILEX / num_steps);
+ int cy = ABS(dy) * (TILEY / num_steps);
+ int step_frame = (i == Ydrip_s2 ||
+ i == Ydrip_s2B ? j + 8 : j) + 1;
+ int step = (is_backside ? step_frame : num_steps - step_frame);
+
+ if (is_backside) /* tile where movement starts */
+ {
+ if (dx < 0 || dy < 0)
+ {
+ g_em->src_offset_x = cx * step;
+ g_em->src_offset_y = cy * step;
+ }
+ else
+ {
+ g_em->dst_offset_x = cx * step;
+ g_em->dst_offset_y = cy * step;
+ }
+ }
+ else /* tile where movement ends */
+ {
+ if (dx < 0 || dy < 0)
+ {
+ g_em->dst_offset_x = cx * step;
+ g_em->dst_offset_y = cy * step;
+ }
+ else
+ {
+ g_em->src_offset_x = cx * step;
+ g_em->src_offset_y = cy * step;
+ }
+ }
+
+ g_em->width = TILEX - cx * step;
+ g_em->height = TILEY - cy * step;
+ }
+
+#if 0
+ if (effective_action == ACTION_SMASHED_BY_ROCK &&
+ element_info[effective_element].graphic[effective_action] ==
+ element_info[effective_element].graphic[ACTION_DEFAULT])
+ {
+ int move_dir = MV_DOWN;
+ int dx = (move_dir == MV_LEFT ? -1 : move_dir == MV_RIGHT ? 1 : 0);
+ int dy = (move_dir == MV_UP ? -1 : move_dir == MV_DOWN ? 1 : 0);
+ int num_steps = 8;
+ int cx = ABS(dx) * (TILEX / num_steps);
+ int cy = ABS(dy) * (TILEY / num_steps);
+ int step_frame = j + 1;
+ int step = (is_backside ? step_frame : num_steps - step_frame);
+
+ graphic = (el_act_dir2img(EL_ROCK, ACTION_FALLING, MV_DOWN));
+ g = &graphic_info[graphic];
+ sync_frame = j;
+ frame = getAnimationFrame(g->anim_frames,
+ g->anim_delay,
+ g->anim_mode,
+ g->anim_start_frame,
+ sync_frame);
+ getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x, &src_y,
+ g->double_movement && is_backside);
+
+ g_em->bitmap = src_bitmap;
+ g_em->src_x = src_x;
+ g_em->src_y = src_y;
+ g_em->src_offset_x = 0;
+ g_em->src_offset_y = 0;
+ g_em->dst_offset_x = 0;
+ g_em->dst_offset_y = 0;
+
+ if (is_backside) /* tile where movement starts */
+ {
+ if (dx < 0 || dy < 0)
+ {
+ g_em->src_offset_x = cx * step;
+ g_em->src_offset_y = cy * step;
+ }
+ else
+ {
+ g_em->dst_offset_x = cx * step;
+ g_em->dst_offset_y = cy * step;
+ }
+ }
+ else /* tile where movement ends */
+ {
+ if (dx < 0 || dy < 0)
+ {
+ g_em->dst_offset_x = cx * step;
+ g_em->dst_offset_y = cy * step;
+ }
+ else
+ {
+ g_em->src_offset_x = cx * step;
+ g_em->src_offset_y = cy * step;
+ }
+ }
+
+ g_em->width = TILEX - cx * step;
+ g_em->height = TILEY - cy * step;
+
+#if 0
+ printf("::: -> '%s'\n", element_info[effective_element].token_name);
+#endif
+ }
+#endif
+
+#endif
+
+ /* create unique graphic identifier to decide if tile must be redrawn */
+ /* bit 31 - 16 (16 bit): EM style element
+ bit 15 - 12 ( 4 bit): EM style frame
+ bit 11 - 6 ( 6 bit): graphic width
+ bit 5 - 0 ( 6 bit): graphic height */
+ g_em->unique_identifier =
+ (i << 16) | (j << 12) | (g_em->width << 6) | g_em->height;
+
+#if DEBUG_EM_GFX
+ if (g_em->bitmap != debug_bitmap ||
+ g_em->src_x != debug_src_x ||
+ g_em->src_y != debug_src_y ||
+ g_em->src_offset_x != 0 ||
+ g_em->src_offset_y != 0 ||
+ g_em->dst_offset_x != 0 ||
+ g_em->dst_offset_y != 0 ||
+ g_em->width != TILEX ||
+ g_em->height != TILEY)
+ {
+ static int last_i = -1;
+
+ if (i != last_i)
+ {
+ printf("\n");
+ last_i = i;
+ }
+
+ printf("::: EMC GFX ERROR for element %d -> %d ('%s', '%s', %d)",
+ i, element, element_info[element].token_name,
+ element_action_info[effective_action].suffix, direction);
+
+ if (element != effective_element)
+ printf(" [%d ('%s')]",
+ effective_element,
+ element_info[effective_element].token_name);
+
+ printf("\n");
+
+ if (g_em->bitmap != debug_bitmap)
+ printf(" %d (%d): different bitmap! (0x%08x != 0x%08x)\n",
+ j, is_backside, (int)(g_em->bitmap), (int)(debug_bitmap));
+
+ if (g_em->src_x != debug_src_x ||
+ g_em->src_y != debug_src_y)
+ printf(" frame %d (%c): %d,%d (%d,%d) should be %d,%d (%d,%d)\n",
+ j, (is_backside ? 'B' : 'F'),
+ g_em->src_x, g_em->src_y,
+ g_em->src_x / 32, g_em->src_y / 32,
+ debug_src_x, debug_src_y,
+ debug_src_x / 32, debug_src_y / 32);
+
+ if (g_em->src_offset_x != 0 ||
+ g_em->src_offset_y != 0 ||
+ g_em->dst_offset_x != 0 ||
+ g_em->dst_offset_y != 0)
+ printf(" %d (%d): offsets %d,%d and %d,%d should be all 0\n",
+ j, is_backside,
+ g_em->src_offset_x, g_em->src_offset_y,
+ g_em->dst_offset_x, g_em->dst_offset_y);
+
+ if (g_em->width != TILEX ||
+ g_em->height != TILEY)
+ printf(" %d (%d): size %d,%d should be %d,%d\n",
+ j, is_backside,
+ g_em->width, g_em->height, TILEX, TILEY);
+ }
+#endif
+
+ }
+ }
+
+#if 1
+ for (i = 0; i < TILE_MAX; i++)
+ {
+ for (j = 0; j < 8; j++)
+ {
+ int element = object_mapping[i].element_rnd;
+ int action = object_mapping[i].action;
+
+ if (action == ACTION_SMASHED_BY_ROCK &&
+ element_info[element].graphic[action] ==
+ element_info[element].graphic[ACTION_DEFAULT])
+ {
+ /* no separate animation for "smashed by rock" -- use rock instead */
+ struct GraphicInfo_EM *g_em = &graphic_info_em_object[i][7 - j];
+ struct GraphicInfo_EM *g_xx = &graphic_info_em_object[Ystone_s][7 - j];
+
+ g_em->bitmap = g_xx->bitmap;
+ g_em->src_x = g_xx->src_x;
+ g_em->src_y = g_xx->src_y;
+ g_em->src_offset_x = g_xx->src_offset_x;
+ g_em->src_offset_y = g_xx->src_offset_y;
+ g_em->dst_offset_x = g_xx->dst_offset_x;
+ g_em->dst_offset_y = g_xx->dst_offset_y;
+ g_em->width = g_xx->width;
+ g_em->height = g_xx->height;
+
+ g_em->preserve_background = TRUE;
+ }
+ }
+ }
+#endif
+
+ for (p = 0; p < 2; p++)
+ {
+ for (i = 0; i < SPR_MAX; i++)
+ {
+ int element = player_mapping[p][i].element_rnd;
+ int action = player_mapping[p][i].action;
+ int direction = player_mapping[p][i].direction;
+
+ for (j = 0; j < 8; j++)
+ {
+ int effective_element = element;
+ int effective_action = action;
+ int graphic = (direction == MV_NO_MOVING ?
+ el_act2img(effective_element, effective_action) :
+ el_act_dir2img(effective_element, effective_action,
+ direction));
+ struct GraphicInfo *g = &graphic_info[graphic];
+ struct GraphicInfo_EM *g_em = &graphic_info_em_player[p][i][7 - j];
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int sync_frame = j;
+
+#if DEBUG_EM_GFX
+ Bitmap *debug_bitmap = g_em->bitmap;
+ int debug_src_x = g_em->src_x;
+ int debug_src_y = g_em->src_y;
+#endif
+
+ int frame = getAnimationFrame(g->anim_frames,
+ g->anim_delay,
+ g->anim_mode,
+ g->anim_start_frame,
+ sync_frame);
+
+ getGraphicSourceExt(graphic, frame, &src_bitmap, &src_x,&src_y, FALSE);
+
+#if 1
+ g_em->bitmap = src_bitmap;
+ g_em->src_x = src_x;
+ g_em->src_y = src_y;
+ g_em->src_offset_x = 0;
+ g_em->src_offset_y = 0;
+ g_em->dst_offset_x = 0;
+ g_em->dst_offset_y = 0;
+ g_em->width = TILEX;
+ g_em->height = TILEY;
+#endif
+
+#if DEBUG_EM_GFX
+ if (g_em->bitmap != debug_bitmap ||
+ g_em->src_x != debug_src_x ||
+ g_em->src_y != debug_src_y)
+ {
+ static int last_i = -1;
+
+ if (i != last_i)
+ {
+ printf("\n");
+ last_i = i;
+ }
+
+ printf("::: EMC GFX ERROR for p/a %d/%d -> %d ('%s', '%s', %d)",
+ p, i, element, element_info[element].token_name,
+ element_action_info[effective_action].suffix, direction);
+
+ if (element != effective_element)
+ printf(" [%d ('%s')]",
+ effective_element,
+ element_info[effective_element].token_name);
+
+ printf("\n");
+
+ if (g_em->bitmap != debug_bitmap)
+ printf(" %d: different bitmap! (0x%08x != 0x%08x)\n",
+ j, (int)(g_em->bitmap), (int)(debug_bitmap));
+
+ if (g_em->src_x != debug_src_x ||
+ g_em->src_y != debug_src_y)
+ printf(" frame %d: %d,%d (%d,%d) should be %d,%d (%d,%d)\n",
+ j,
+ g_em->src_x, g_em->src_y,
+ g_em->src_x / 32, g_em->src_y / 32,
+ debug_src_x, debug_src_y,
+ debug_src_x / 32, debug_src_y / 32);
+ }
+#endif
+
+ }
+ }
+ }
+
+#if DEBUG_EM_GFX
+ exit(0);
+#endif
+}
#define DOOR_ACTION_2 (DOOR_OPEN_2 | DOOR_CLOSE_2)
#define DOOR_ACTION (DOOR_ACTION_1 | DOOR_ACTION_2)
#define DOOR_COPY_BACK (1 << 4)
-#define DOOR_NO_DELAY (1 << 5)
-#define DOOR_GET_STATE (1 << 6)
-#define DOOR_SET_STATE (1 << 7)
+#define DOOR_NO_COPY_BACK (1 << 5)
+#define DOOR_NO_DELAY (1 << 6)
+#define DOOR_GET_STATE (1 << 7)
+#define DOOR_SET_STATE (1 << 8)
/* for Request */
#define REQ_ASK (1 << 0)
-#define REQ_OPEN (1 << 1)
-#define REQ_CLOSE (1 << 2)
-#define REQ_CONFIRM (1 << 3)
+#define REQ_CONFIRM (1 << 1)
+#define REQ_PLAYER (1 << 2)
+#define REQ_STAY_OPEN (1 << 3)
#define REQ_STAY_CLOSED (1 << 4)
-#define REQ_STAY_OPEN (1 << 5)
-#define REQ_PLAYER (1 << 6)
+#define REQ_REOPEN (1 << 5)
-#define REQUEST_WAIT_FOR (REQ_ASK | REQ_CONFIRM | REQ_PLAYER)
+#define REQUEST_WAIT_FOR_INPUT (REQ_ASK | REQ_CONFIRM | REQ_PLAYER)
void DumpTile(int, int);
void DrawPlayerField(int, int);
void DrawPlayer(struct PlayerInfo *);
+void getGraphicSourceExt(int, int, Bitmap **, int *, int *, boolean);
void getGraphicSource(int, int, Bitmap **, int *, int *);
void DrawGraphic(int, int, int, int);
void DrawGraphicExt(DrawBuffer *, int, int, int, int);
void getMiniGraphicSource(int, Bitmap **, int *, int *);
void DrawMiniGraphicExt(DrawBuffer *, int, int, int);
-void DrawGraphicShifted(int, int, int, int, int, int, int, int);
-void DrawGraphicShiftedThruMask(int, int, int, int, int, int, int);
void DrawScreenElementExt(int, int, int, int, int, int, int);
void DrawLevelElementExt(int, int, int, int, int, int, int);
void DrawScreenElementShifted(int, int, int, int, int, int);
void CreateToolButtons();
void FreeToolButtons();
+int map_element_RND_to_EM(int);
+int map_element_EM_to_RND(int);
+
int get_next_element(int);
int el_act_dir2img(int, int, int);
int el_act2img(int, int);
int el2edimg(int);
int el2preimg(int);
+unsigned int InitRND(long);
+void InitGraphicInfo_EM(void);
+
#endif /* TOOLS_H */