+Release Version 3.0.0 [05 AUG 2003]
+------------------------------------------
+ - final version bumped to 3.0.0 due to the massive changes
+ - graphics and sounds now completely and dynamically customizable
+ - custom elements now have lots of configurable properties
+ - advanced custom element settings for powerful, self-created elements
+ - fixed Supaplex gravity tubes
+ - fixed very nasty bug in SDL_image (and X11) PCX loading routine
+ - fixed some very nasty bugs in bitmap zoom routine
+ - fixed very nasty bug in level/artwork loading routine
+ - added new contributed levels and artwork from the following players:
+ * in the section "Contributions - 2002":
+ + Abby King (14 levels)
+ + Alan Bond (30 levels, all solvable, BD style artwork set)
+ + David Hutchinson (25 levels, artwork set)
+ + Equinox Tetrachloride (50 levels + 100 levels, all solvable)
+ + Sylvan Hancock (39 levels)
+ * in the section "Contributions - 2003":
+ + Andreas Buschbeck (85 levels, all solvable, complete artwork set)
+ + Edward Leuf (10 levels, all solvable, artwork set)
+ + Emanuel Schmieg (22 levels, all solvable, complete artwork set)
+ + Gavin Davidson (47 levels)
+ + Jorge Jordan (17 levels)
+ + Rafael Gatti (17 levels)
+ + Randy Johannessen (17 levels)
+ + Richard Valvona (3 levels)
+ + Sam Bateman (35 levels)
+ - great new levels with full artwork are now available from:
+ + Juergen Bonhagen (with complete artwork set)
+ * download these levels from "http://www.jb-line.de/"
+ + Andreas Buschbeck (with complete artwork set)
+ * download these levels from "http://home.vr-web.de/~abuschbeck/"
+
+Pre-Release Version 2.2.0rc7 [17 JUL 2003]
+------------------------------------------
+ - fixed bug when picking element in the editor
+ - added more custom elements properties
+ - fixed bugs when smashing penguin
+
+Pre-Release Version 2.2.0rc6 [22 APR 2003]
+------------------------------------------
+ - fixed small font configuration directive bug
+ - tape recorder font slightly enhanced (now complete character set)
+ - added missing font configuration source file
+ - added updated CHANGES file ;-)
+
+Pre-Release Version 2.2.0rc5 [20 APR 2003]
+------------------------------------------
+ - added generic selectbox gadget
+ - added special mouse cursor for playfield while playing
+ - font handling now more flexible (support for ISO-Latin-1 fonts)
+ - font graphics adjusted accordingly
+
+Pre-Release Version 2.2.0rc4 [30 MAR 2003]
+------------------------------------------
+ - changes for menu configuration
+ - not officially announced pre-release version
+ - Emerald Mine text font now much better quality
+
+Pre-Release Version 2.2.0rc3 [11 FEB 2003]
+------------------------------------------
+ - first custom element properties
+ - animation configuration for dynamically defined element actions
+ - automatically downscaled graphics (small graphics not needed anymore)
+ - ".EDITOR" and ".PREVIEW" suffixes for special editor/preview graphics
+ - toon animations (and number of toons) now fully configurable
+
+Pre-Release Version 2.2.0rc2 [13 JAN 2003]
+------------------------------------------
+ - added support for stereo WAV sound files
+ - moving objects can now have arbitrary animation length
+ - new batch command for dumping level information
+ - added support for background images for all menu screens
+ - added 128 custom elements that can be decorated with own graphics
+ - added some example levels showing how to create custom artwork
+ - added new contributed levels from the following players:
+ + Emanuel Schmieg: "Into The Ice Caves" (22 levels + artwork)
+
+Pre-Release Version 2.2.0rc1 [31 DEC 2002]
+------------------------------------------
+ - level series artwork now configurable via level series config file
+ - single graphics and animations can now be replaced with different
+ ones (independantly from default image files which may be larger)
+ by defining and using additional image files
+ - element animation length, speed and mode now freely configurable
+ - automatic tape playing function for game engine and level testing
+ - missing steel wall graphic added (thanks to Equinox Tetrachloride)
+ - added new contributed levels from the following players:
+ + Abby King (14 levels)
+ + Andreas Buschbeck (80 levels with complete artwork set)
+ + David Hutchinson (25 levels with graphics set)
+ + Equinox Tetrachloride (150 levels guaranteed to be solvable)
+ + Sylvan Hancock (39 levels)
+
Release Version 2.1.1 [13 AUG 2002]
-----------------------------------
- sound bug (causing crashes) fixed (reported by Keith Peterston)
- default keys for "snap field" and "place bomb" fixed for Mac OS X
- added new contributed levels from the following players:
+ Alan Bond
- + Gerrit Holl
+ + Gerrit Holl and Timen van den Berg
Release Version 2.1.0 [05 AUG 2002]
-----------------------------------
------------------------------------------
- new game elements
-Prerelease Version 0.9b [4 NOV 1995]
-------------------------------------
+Pre-Release Version 0.9b [4 NOV 1995]
+-------------------------------------
- the game is now completely Freeware
- the game is now better playable by keyboard
(in the last version, the player was making more than
- FreeBSD sound and joystick support (thanks to Jean-Marc
Zucconi)
-Prerelease Version 0.9 [23 OCT 1995]
-------------------------------------
+Pre-Release Version 0.9 [23 OCT 1995]
+-------------------------------------
- first (pre)release version
SRC_DIR = src
MAKE_CMD = $(MAKE) -C $(SRC_DIR)
+# DEFAULT_TARGET = x11
+DEFAULT_TARGET = sdl
+
all:
- @$(MAKE_CMD) TARGET=x11
+ @$(MAKE_CMD) TARGET=$(DEFAULT_TARGET)
x11:
@$(MAKE_CMD) TARGET=x11
# development only stuff #
#-----------------------------------------------------------------------------#
+auto-conf:
+ @$(MAKE_CMD) auto-conf
+
run:
- @$(MAKE_CMD) TARGET=x11 && ./rocksndiamonds --verbose
+ @$(MAKE_CMD) TARGET=$(DEFAULT_TARGET) && ./rocksndiamonds --verbose
+
+gdb:
+ @$(MAKE_CMD) TARGET=$(DEFAULT_TARGET) && gdb ./rocksndiamonds
+
+enginetest:
+ ./Scripts/make_enginetest.sh
+
+enginetestfast:
+ ./Scripts/make_enginetest.sh fast
backup:
./Scripts/make_backup.sh src
dist-macosx:
./Scripts/make_dist.sh mac . $(MAKE)
+upload-unix:
+ ./Scripts/make_dist.sh unix . upload
+
+upload-msdos:
+ ./Scripts/make_dist.sh dos . upload
+
+upload-win32:
+ ./Scripts/make_dist.sh win . upload
+
+upload-macosx:
+ ./Scripts/make_dist.sh mac . upload
+
dist-clean:
@$(MAKE_CMD) dist-clean
+dist-build-unix:
+ @BUILD_DIST=TRUE $(MAKE) x11
+
+dist-build-win32:
+ @BUILD_DIST=TRUE $(MAKE) cross-win32
+
+dist-build-msdos:
+ @BUILD_DIST=TRUE $(MAKE) cross-msdos
+
dist-build-all:
$(MAKE) clean
- @BUILD_DIST=TRUE $(MAKE) x11 ; $(MAKE) dist-clean
- @BUILD_DIST=TRUE $(MAKE) cross-win32 ; $(MAKE) dist-clean
- @BUILD_DIST=TRUE $(MAKE) cross-msdos ; $(MAKE) dist-clean
+ $(MAKE) dist-build-unix ; $(MAKE) dist-clean
+ $(MAKE) dist-build-win32 ; $(MAKE) dist-clean
+ $(MAKE) dist-build-msdos ; $(MAKE) dist-clean
dist-all: dist-build-all dist-unix dist-msdos dist-win32 dist-macosx
+upload-all: upload-unix upload-msdos upload-win32 upload-macosx
+
depend dep:
$(MAKE_CMD) depend
endif
ifeq ($(PLATFORM),cross-win32)
+EXTRA_LDFLAGS = -lshfolder
PROGNAME = ../$(PROGBASE).exe
TARGET = sdl
endif
# PROFILING = $(PROFILING_FLAGS)
# OPTIONS = $(DEBUG) -Wall # only for debugging purposes
-OPTIONS = $(DEBUG) -O3 -Wall # only for debugging purposes
+# OPTIONS = $(DEBUG) -O3 -Wall # only for debugging purposes
+OPTIONS = $(DEBUG) -Wall # only for debugging purposes
# OPTIONS = $(DEBUG) -Wall -ansi -pedantic # only for debugging purposes
# OPTIONS = -O3 -Wall -ansi -pedantic
# OPTIONS = -O3 -Wall
SRCS = main.c \
+ conf_gfx.c \
+ conf_snd.c \
init.c \
config.c \
events.c \
netserv.c
OBJS = main.o \
+ conf_gfx.o \
+ conf_snd.o \
init.o \
config.o \
events.o \
network.o \
netserv.o
+CNFS = conf_gfx.h \
+ conf_snd.h \
+ conf_chr.c \
+ conf_chr.h \
+ conf_cus.c \
+ conf_cus.h \
+ conf_e2g.c \
+ conf_esg.c \
+ conf_e2s.c \
+ conf_fnt.c
+
+CNFS_CMD = ../Scripts/create_element_defs.pl
+
TIMESTAMP_FILE = conftime.h
LIBDIR = libgame
$(LIBGAME):
@$(MAKE) -C $(LIBDIR)
+auto-conf:
+ @for i in $(CNFS); do \
+ echo "$(CNFS_CMD) $$i > $$i"; \
+ $(CNFS_CMD) $$i > $$i; \
+ done
+
+conf_gfx.h: conf_gfx.c
+ @$(MAKE) auto-conf
+
+conf_snd.h: conf_snd.c
+ @$(MAKE) auto-conf
+
$(TIMESTAMP_FILE): $(SRCS) $(LIBGAME)
@date '+"[%Y-%m-%d %H:%M]"' \
| sed -e 's/^/#define COMPILE_DATE_STRING /' \
/* values for toon definition */
-#define NUM_TOONS 18
+#define MAX_NUM_TOONS 20
-#define DWARF_XSIZE 40
-#define DWARF_YSIZE 48
-#define DWARF_X 2
-#define DWARF_Y 72
-#define DWARF2_Y 186
-#define DWARF_FRAMES 8
-#define DWARF_FPS 10
-#define DWARF_STEPSIZE 4
-#define JUMPER_XSIZE 48
-#define JUMPER_YSIZE 56
-#define JUMPER_X 2
-#define JUMPER_Y 125
-#define JUMPER_FRAMES 8
-#define JUMPER_FPS 10
-#define JUMPER_STEPSIZE 4
-#define CLOWN_XSIZE 80
-#define CLOWN_YSIZE 110
-#define CLOWN_X 327
-#define CLOWN_Y 10
-#define CLOWN_FRAMES 1
-#define CLOWN_FPS 10
-#define CLOWN_STEPSIZE 4
-#define BIRD_XSIZE 32
-#define BIRD_YSIZE 30
-#define BIRD1_X 2
-#define BIRD1_Y 2
-#define BIRD2_X 2
-#define BIRD2_Y 37
-#define BIRD_FRAMES 8
-#define BIRD_FPS 20
-#define BIRD_STEPSIZE 4
-
-#define GAMETOON_XSIZE TILEX
-#define GAMETOON_YSIZE TILEY
-#define GAMETOON_FRAMES_4 4
-#define GAMETOON_FRAMES_8 8
-#define GAMETOON_FPS 20
-#define GAMETOON_STEPSIZE 4
-
-struct ToonInfo toons[NUM_TOONS] =
-{
- {
- PIX_TOONS,
- DWARF_XSIZE, DWARF_YSIZE,
- DWARF_X, DWARF_Y,
- DWARF_FRAMES,
- DWARF_FPS,
- DWARF_STEPSIZE,
- ANIM_NORMAL,
- ANIMDIR_RIGHT,
- ANIMPOS_DOWN
- },
- {
- PIX_TOONS,
- DWARF_XSIZE, DWARF_YSIZE,
- DWARF_X, DWARF2_Y,
- DWARF_FRAMES,
- DWARF_FPS,
- DWARF_STEPSIZE,
- ANIM_NORMAL,
- ANIMDIR_LEFT,
- ANIMPOS_DOWN
- },
- {
- PIX_TOONS,
- JUMPER_XSIZE, JUMPER_YSIZE,
- JUMPER_X, JUMPER_Y,
- JUMPER_FRAMES,
- JUMPER_FPS,
- JUMPER_STEPSIZE,
- ANIM_NORMAL,
- ANIMDIR_RIGHT,
- ANIMPOS_DOWN
- },
- {
- PIX_TOONS,
- CLOWN_XSIZE, CLOWN_YSIZE,
- CLOWN_X, CLOWN_Y,
- CLOWN_FRAMES,
- CLOWN_FPS,
- CLOWN_STEPSIZE,
- ANIM_NORMAL,
- ANIMDIR_UP,
- ANIMPOS_ANY
- },
- {
- PIX_TOONS,
- BIRD_XSIZE, BIRD_YSIZE,
- BIRD1_X, BIRD1_Y,
- BIRD_FRAMES,
- BIRD_FPS,
- BIRD_STEPSIZE,
- ANIM_OSCILLATE,
- ANIMDIR_RIGHT,
- ANIMPOS_UPPER
- },
- {
- PIX_TOONS,
- BIRD_XSIZE, BIRD_YSIZE,
- BIRD2_X, BIRD2_Y,
- BIRD_FRAMES,
- BIRD_FPS,
- BIRD_STEPSIZE,
- ANIM_OSCILLATE,
- ANIMDIR_LEFT,
- ANIMPOS_UPPER
- },
- {
- PIX_HEROES,
- GAMETOON_XSIZE, GAMETOON_YSIZE,
- ((GFX_SPIELER1_LEFT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
- ((GFX_SPIELER1_LEFT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
- GAMETOON_FRAMES_4,
- GAMETOON_FPS,
- GAMETOON_STEPSIZE,
- ANIM_NORMAL,
- ANIMDIR_LEFT,
- ANIMPOS_DOWN
- },
- {
- PIX_HEROES,
- GAMETOON_XSIZE, GAMETOON_YSIZE,
- ((GFX_SPIELER1_RIGHT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
- ((GFX_SPIELER1_RIGHT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
- GAMETOON_FRAMES_4,
- GAMETOON_FPS,
- GAMETOON_STEPSIZE,
- ANIM_NORMAL,
- ANIMDIR_RIGHT,
- ANIMPOS_DOWN
- },
- {
- PIX_HEROES,
- GAMETOON_XSIZE, GAMETOON_YSIZE,
- ((GFX_PINGUIN_LEFT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
- ((GFX_PINGUIN_LEFT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
- GAMETOON_FRAMES_4,
- GAMETOON_FPS,
- GAMETOON_STEPSIZE,
- ANIM_NORMAL,
- ANIMDIR_LEFT,
- ANIMPOS_DOWN
- },
- {
- PIX_HEROES,
- GAMETOON_XSIZE, GAMETOON_YSIZE,
- ((GFX_PINGUIN_RIGHT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
- ((GFX_PINGUIN_RIGHT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
- GAMETOON_FRAMES_4,
- GAMETOON_FPS,
- GAMETOON_STEPSIZE,
- ANIM_NORMAL,
- ANIMDIR_RIGHT,
- ANIMPOS_DOWN
- },
- {
- PIX_HEROES,
- GAMETOON_XSIZE, GAMETOON_YSIZE,
- ((GFX_MOLE_LEFT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
- ((GFX_MOLE_LEFT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
- GAMETOON_FRAMES_4,
- GAMETOON_FPS,
- GAMETOON_STEPSIZE,
- ANIM_NORMAL,
- ANIMDIR_LEFT,
- ANIMPOS_DOWN
- },
- {
- PIX_HEROES,
- GAMETOON_XSIZE, GAMETOON_YSIZE,
- ((GFX_MOLE_RIGHT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
- ((GFX_MOLE_RIGHT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
- GAMETOON_FRAMES_4,
- GAMETOON_FPS,
- GAMETOON_STEPSIZE,
- ANIM_NORMAL,
- ANIMDIR_RIGHT,
- ANIMPOS_DOWN
- },
- {
- PIX_HEROES,
- GAMETOON_XSIZE, GAMETOON_YSIZE,
- ((GFX_SCHWEIN_LEFT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
- ((GFX_SCHWEIN_LEFT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
- GAMETOON_FRAMES_4,
- GAMETOON_FPS,
- GAMETOON_STEPSIZE,
- ANIM_NORMAL,
- ANIMDIR_LEFT,
- ANIMPOS_DOWN
- },
- {
- PIX_HEROES,
- GAMETOON_XSIZE, GAMETOON_YSIZE,
- ((GFX_SCHWEIN_RIGHT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
- ((GFX_SCHWEIN_RIGHT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
- GAMETOON_FRAMES_4,
- GAMETOON_FPS,
- GAMETOON_STEPSIZE,
- ANIM_NORMAL,
- ANIMDIR_RIGHT,
- ANIMPOS_DOWN
- },
- {
- PIX_HEROES,
- GAMETOON_XSIZE, GAMETOON_YSIZE,
- ((GFX_DRACHE_LEFT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
- ((GFX_DRACHE_LEFT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
- GAMETOON_FRAMES_4,
- GAMETOON_FPS,
- GAMETOON_STEPSIZE,
- ANIM_NORMAL,
- ANIMDIR_LEFT,
- ANIMPOS_DOWN
- },
- {
- PIX_HEROES,
- GAMETOON_XSIZE, GAMETOON_YSIZE,
- ((GFX_DRACHE_RIGHT - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
- ((GFX_DRACHE_RIGHT - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
- GAMETOON_FRAMES_4,
- GAMETOON_FPS,
- GAMETOON_STEPSIZE,
- ANIM_NORMAL,
- ANIMDIR_RIGHT,
- ANIMPOS_DOWN
- },
- {
- PIX_HEROES,
- GAMETOON_XSIZE, GAMETOON_YSIZE,
- ((GFX_SONDE - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
- ((GFX_SONDE - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
- GAMETOON_FRAMES_8,
- GAMETOON_FPS,
- GAMETOON_STEPSIZE,
- ANIM_NORMAL,
- ANIMDIR_LEFT,
- ANIMPOS_ANY
- },
- {
- PIX_HEROES,
- GAMETOON_XSIZE, GAMETOON_YSIZE,
- ((GFX_SONDE - GFX_START_ROCKSHEROES) % HEROES_PER_LINE)*TILEX,
- ((GFX_SONDE - GFX_START_ROCKSHEROES) / HEROES_PER_LINE)*TILEY,
- GAMETOON_FRAMES_8,
- GAMETOON_FPS,
- GAMETOON_STEPSIZE,
- ANIM_NORMAL,
- ANIMDIR_RIGHT,
- ANIMPOS_ANY
- },
-};
+static struct ToonInfo toons[MAX_NUM_TOONS];
static void PrepareBackbuffer()
{
/* Fill empty backbuffer for animation functions */
- if (setup.direct_draw && game_status == PLAYING)
+ if (setup.direct_draw && game_status == GAME_MODE_PLAYING)
{
int xx,yy;
SetDrawtoField(DRAW_DIRECT);
}
- if (setup.soft_scrolling && game_status == PLAYING)
+ if (setup.soft_scrolling && game_status == GAME_MODE_PLAYING)
{
int fx = FX, fy = FY;
boolean ToonNeedsRedraw()
{
- return (game_status == HELPSCREEN ||
- (game_status == MAINMENU &&
+ return (game_status == GAME_MODE_INFO ||
+ (game_status == GAME_MODE_MAIN &&
((redraw_mask & REDRAW_MICROLEVEL) ||
(redraw_mask & REDRAW_MICROLABEL))));
}
void InitToons()
{
- InitToonScreen(pix, pix[PIX_DB_DOOR],
+ int num_toons = MAX_NUM_TOONS;
+ int i;
+
+ if (global.num_toons > 0 && global.num_toons < MAX_NUM_TOONS)
+ num_toons = global.num_toons;
+
+ for (i=0; i < num_toons; i++)
+ {
+ int graphic = IMG_TOON_1 + i;
+ struct FileInfo *image = getImageListEntry(graphic);
+
+ toons[i].bitmap = graphic_info[graphic].bitmap;
+
+ toons[i].src_x = graphic_info[graphic].src_x;
+ toons[i].src_y = graphic_info[graphic].src_y;
+
+ toons[i].width = graphic_info[graphic].width;
+ toons[i].height = graphic_info[graphic].height;
+
+ toons[i].anim_frames = graphic_info[graphic].anim_frames;
+ toons[i].anim_delay = graphic_info[graphic].anim_delay;
+ toons[i].anim_mode = graphic_info[graphic].anim_mode;
+ toons[i].anim_start_frame = graphic_info[graphic].anim_start_frame;
+
+ toons[i].step_offset = graphic_info[graphic].step_offset;
+ toons[i].step_delay = graphic_info[graphic].step_delay;
+
+ toons[i].direction = image->parameter[GFX_ARG_DIRECTION];
+ toons[i].position = image->parameter[GFX_ARG_POSITION];
+ }
+
+ InitToonScreen(bitmap_db_door,
BackToFront, PrepareBackbuffer, ToonNeedsRedraw,
- toons, NUM_TOONS,
- REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
+ toons, num_toons,
+ REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE,
+ GAME_FRAME_DELAY);
}
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* (c) 1995-2002 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* conf_chr.c *
+***********************************************************/
+
+/* ----- this file was automatically generated -- do not edit by hand ----- */
+
+#ifndef CONF_CHR_C
+#define CONF_CHR_C
+
+/* values for graphics configuration (character elements) */
+
+ { "char_space", "RocksFontEM.pcx" },
+ { "char_space.xpos", "0" },
+ { "char_space.ypos", "0" },
+ { "char_space.frames", "1" },
+
+ { "char_exclam", "RocksFontEM.pcx" },
+ { "char_exclam.xpos", "1" },
+ { "char_exclam.ypos", "0" },
+ { "char_exclam.frames", "1" },
+
+ { "char_quotedbl", "RocksFontEM.pcx" },
+ { "char_quotedbl.xpos", "2" },
+ { "char_quotedbl.ypos", "0" },
+ { "char_quotedbl.frames", "1" },
+
+ { "char_numbersign", "RocksFontEM.pcx" },
+ { "char_numbersign.xpos", "3" },
+ { "char_numbersign.ypos", "0" },
+ { "char_numbersign.frames", "1" },
+
+ { "char_dollar", "RocksFontEM.pcx" },
+ { "char_dollar.xpos", "4" },
+ { "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_ampersand", "RocksFontEM.pcx" },
+ { "char_ampersand.xpos", "6" },
+ { "char_ampersand.ypos", "0" },
+ { "char_ampersand.frames", "1" },
+
+ { "char_apostrophe", "RocksFontEM.pcx" },
+ { "char_apostrophe.xpos", "7" },
+ { "char_apostrophe.ypos", "0" },
+ { "char_apostrophe.frames", "1" },
+
+ { "char_parenleft", "RocksFontEM.pcx" },
+ { "char_parenleft.xpos", "8" },
+ { "char_parenleft.ypos", "0" },
+ { "char_parenleft.frames", "1" },
+
+ { "char_parenright", "RocksFontEM.pcx" },
+ { "char_parenright.xpos", "9" },
+ { "char_parenright.ypos", "0" },
+ { "char_parenright.frames", "1" },
+
+ { "char_asterisk", "RocksFontEM.pcx" },
+ { "char_asterisk.xpos", "10" },
+ { "char_asterisk.ypos", "0" },
+ { "char_asterisk.frames", "1" },
+
+ { "char_plus", "RocksFontEM.pcx" },
+ { "char_plus.xpos", "11" },
+ { "char_plus.ypos", "0" },
+ { "char_plus.frames", "1" },
+
+ { "char_comma", "RocksFontEM.pcx" },
+ { "char_comma.xpos", "12" },
+ { "char_comma.ypos", "0" },
+ { "char_comma.frames", "1" },
+
+ { "char_minus", "RocksFontEM.pcx" },
+ { "char_minus.xpos", "13" },
+ { "char_minus.ypos", "0" },
+ { "char_minus.frames", "1" },
+
+ { "char_period", "RocksFontEM.pcx" },
+ { "char_period.xpos", "14" },
+ { "char_period.ypos", "0" },
+ { "char_period.frames", "1" },
+
+ { "char_slash", "RocksFontEM.pcx" },
+ { "char_slash.xpos", "15" },
+ { "char_slash.ypos", "0" },
+ { "char_slash.frames", "1" },
+
+ { "char_0", "RocksFontEM.pcx" },
+ { "char_0.xpos", "0" },
+ { "char_0.ypos", "1" },
+ { "char_0.frames", "1" },
+
+ { "char_1", "RocksFontEM.pcx" },
+ { "char_1.xpos", "1" },
+ { "char_1.ypos", "1" },
+ { "char_1.frames", "1" },
+
+ { "char_2", "RocksFontEM.pcx" },
+ { "char_2.xpos", "2" },
+ { "char_2.ypos", "1" },
+ { "char_2.frames", "1" },
+
+ { "char_3", "RocksFontEM.pcx" },
+ { "char_3.xpos", "3" },
+ { "char_3.ypos", "1" },
+ { "char_3.frames", "1" },
+
+ { "char_4", "RocksFontEM.pcx" },
+ { "char_4.xpos", "4" },
+ { "char_4.ypos", "1" },
+ { "char_4.frames", "1" },
+
+ { "char_5", "RocksFontEM.pcx" },
+ { "char_5.xpos", "5" },
+ { "char_5.ypos", "1" },
+ { "char_5.frames", "1" },
+
+ { "char_6", "RocksFontEM.pcx" },
+ { "char_6.xpos", "6" },
+ { "char_6.ypos", "1" },
+ { "char_6.frames", "1" },
+
+ { "char_7", "RocksFontEM.pcx" },
+ { "char_7.xpos", "7" },
+ { "char_7.ypos", "1" },
+ { "char_7.frames", "1" },
+
+ { "char_8", "RocksFontEM.pcx" },
+ { "char_8.xpos", "8" },
+ { "char_8.ypos", "1" },
+ { "char_8.frames", "1" },
+
+ { "char_9", "RocksFontEM.pcx" },
+ { "char_9.xpos", "9" },
+ { "char_9.ypos", "1" },
+ { "char_9.frames", "1" },
+
+ { "char_colon", "RocksFontEM.pcx" },
+ { "char_colon.xpos", "10" },
+ { "char_colon.ypos", "1" },
+ { "char_colon.frames", "1" },
+
+ { "char_semicolon", "RocksFontEM.pcx" },
+ { "char_semicolon.xpos", "11" },
+ { "char_semicolon.ypos", "1" },
+ { "char_semicolon.frames", "1" },
+
+ { "char_less", "RocksFontEM.pcx" },
+ { "char_less.xpos", "12" },
+ { "char_less.ypos", "1" },
+ { "char_less.frames", "1" },
+
+ { "char_equal", "RocksFontEM.pcx" },
+ { "char_equal.xpos", "13" },
+ { "char_equal.ypos", "1" },
+ { "char_equal.frames", "1" },
+
+ { "char_greater", "RocksFontEM.pcx" },
+ { "char_greater.xpos", "14" },
+ { "char_greater.ypos", "1" },
+ { "char_greater.frames", "1" },
+
+ { "char_question", "RocksFontEM.pcx" },
+ { "char_question.xpos", "15" },
+ { "char_question.ypos", "1" },
+ { "char_question.frames", "1" },
+
+ { "char_at", "RocksFontEM.pcx" },
+ { "char_at.xpos", "0" },
+ { "char_at.ypos", "2" },
+ { "char_at.frames", "1" },
+
+ { "char_a", "RocksFontEM.pcx" },
+ { "char_a.xpos", "1" },
+ { "char_a.ypos", "2" },
+ { "char_a.frames", "1" },
+
+ { "char_b", "RocksFontEM.pcx" },
+ { "char_b.xpos", "2" },
+ { "char_b.ypos", "2" },
+ { "char_b.frames", "1" },
+
+ { "char_c", "RocksFontEM.pcx" },
+ { "char_c.xpos", "3" },
+ { "char_c.ypos", "2" },
+ { "char_c.frames", "1" },
+
+ { "char_d", "RocksFontEM.pcx" },
+ { "char_d.xpos", "4" },
+ { "char_d.ypos", "2" },
+ { "char_d.frames", "1" },
+
+ { "char_e", "RocksFontEM.pcx" },
+ { "char_e.xpos", "5" },
+ { "char_e.ypos", "2" },
+ { "char_e.frames", "1" },
+
+ { "char_f", "RocksFontEM.pcx" },
+ { "char_f.xpos", "6" },
+ { "char_f.ypos", "2" },
+ { "char_f.frames", "1" },
+
+ { "char_g", "RocksFontEM.pcx" },
+ { "char_g.xpos", "7" },
+ { "char_g.ypos", "2" },
+ { "char_g.frames", "1" },
+
+ { "char_h", "RocksFontEM.pcx" },
+ { "char_h.xpos", "8" },
+ { "char_h.ypos", "2" },
+ { "char_h.frames", "1" },
+
+ { "char_i", "RocksFontEM.pcx" },
+ { "char_i.xpos", "9" },
+ { "char_i.ypos", "2" },
+ { "char_i.frames", "1" },
+
+ { "char_j", "RocksFontEM.pcx" },
+ { "char_j.xpos", "10" },
+ { "char_j.ypos", "2" },
+ { "char_j.frames", "1" },
+
+ { "char_k", "RocksFontEM.pcx" },
+ { "char_k.xpos", "11" },
+ { "char_k.ypos", "2" },
+ { "char_k.frames", "1" },
+
+ { "char_l", "RocksFontEM.pcx" },
+ { "char_l.xpos", "12" },
+ { "char_l.ypos", "2" },
+ { "char_l.frames", "1" },
+
+ { "char_m", "RocksFontEM.pcx" },
+ { "char_m.xpos", "13" },
+ { "char_m.ypos", "2" },
+ { "char_m.frames", "1" },
+
+ { "char_n", "RocksFontEM.pcx" },
+ { "char_n.xpos", "14" },
+ { "char_n.ypos", "2" },
+ { "char_n.frames", "1" },
+
+ { "char_o", "RocksFontEM.pcx" },
+ { "char_o.xpos", "15" },
+ { "char_o.ypos", "2" },
+ { "char_o.frames", "1" },
+
+ { "char_p", "RocksFontEM.pcx" },
+ { "char_p.xpos", "0" },
+ { "char_p.ypos", "3" },
+ { "char_p.frames", "1" },
+
+ { "char_q", "RocksFontEM.pcx" },
+ { "char_q.xpos", "1" },
+ { "char_q.ypos", "3" },
+ { "char_q.frames", "1" },
+
+ { "char_r", "RocksFontEM.pcx" },
+ { "char_r.xpos", "2" },
+ { "char_r.ypos", "3" },
+ { "char_r.frames", "1" },
+
+ { "char_s", "RocksFontEM.pcx" },
+ { "char_s.xpos", "3" },
+ { "char_s.ypos", "3" },
+ { "char_s.frames", "1" },
+
+ { "char_t", "RocksFontEM.pcx" },
+ { "char_t.xpos", "4" },
+ { "char_t.ypos", "3" },
+ { "char_t.frames", "1" },
+
+ { "char_u", "RocksFontEM.pcx" },
+ { "char_u.xpos", "5" },
+ { "char_u.ypos", "3" },
+ { "char_u.frames", "1" },
+
+ { "char_v", "RocksFontEM.pcx" },
+ { "char_v.xpos", "6" },
+ { "char_v.ypos", "3" },
+ { "char_v.frames", "1" },
+
+ { "char_w", "RocksFontEM.pcx" },
+ { "char_w.xpos", "7" },
+ { "char_w.ypos", "3" },
+ { "char_w.frames", "1" },
+
+ { "char_x", "RocksFontEM.pcx" },
+ { "char_x.xpos", "8" },
+ { "char_x.ypos", "3" },
+ { "char_x.frames", "1" },
+
+ { "char_y", "RocksFontEM.pcx" },
+ { "char_y.xpos", "9" },
+ { "char_y.ypos", "3" },
+ { "char_y.frames", "1" },
+
+ { "char_z", "RocksFontEM.pcx" },
+ { "char_z.xpos", "10" },
+ { "char_z.ypos", "3" },
+ { "char_z.frames", "1" },
+
+ { "char_bracketleft", "RocksFontEM.pcx" },
+ { "char_bracketleft.xpos", "11" },
+ { "char_bracketleft.ypos", "3" },
+ { "char_bracketleft.frames", "1" },
+
+ { "char_backslash", "RocksFontEM.pcx" },
+ { "char_backslash.xpos", "12" },
+ { "char_backslash.ypos", "3" },
+ { "char_backslash.frames", "1" },
+
+ { "char_bracketright", "RocksFontEM.pcx" },
+ { "char_bracketright.xpos", "13" },
+ { "char_bracketright.ypos", "3" },
+ { "char_bracketright.frames", "1" },
+
+ { "char_asciicircum", "RocksFontEM.pcx" },
+ { "char_asciicircum.xpos", "14" },
+ { "char_asciicircum.ypos", "3" },
+ { "char_asciicircum.frames", "1" },
+
+ { "char_underscore", "RocksFontEM.pcx" },
+ { "char_underscore.xpos", "15" },
+ { "char_underscore.ypos", "3" },
+ { "char_underscore.frames", "1" },
+
+ { "char_copyright", "RocksFontEM.pcx" },
+ { "char_copyright.xpos", "0" },
+ { "char_copyright.ypos", "4" },
+ { "char_copyright.frames", "1" },
+
+ { "char_aumlaut", "RocksFontEM.pcx" },
+ { "char_aumlaut.xpos", "1" },
+ { "char_aumlaut.ypos", "4" },
+ { "char_aumlaut.frames", "1" },
+
+ { "char_oumlaut", "RocksFontEM.pcx" },
+ { "char_oumlaut.xpos", "2" },
+ { "char_oumlaut.ypos", "4" },
+ { "char_oumlaut.frames", "1" },
+
+ { "char_uumlaut", "RocksFontEM.pcx" },
+ { "char_uumlaut.xpos", "3" },
+ { "char_uumlaut.ypos", "4" },
+ { "char_uumlaut.frames", "1" },
+
+ { "char_degree", "RocksFontEM.pcx" },
+ { "char_degree.xpos", "4" },
+ { "char_degree.ypos", "4" },
+ { "char_degree.frames", "1" },
+
+ { "char_trademark", "RocksFontEM.pcx" },
+ { "char_trademark.xpos", "5" },
+ { "char_trademark.ypos", "4" },
+ { "char_trademark.frames", "1" },
+
+ { "char_cursor", "RocksFontEM.pcx" },
+ { "char_cursor.xpos", "6" },
+ { "char_cursor.ypos", "4" },
+ { "char_cursor.frames", "1" },
+
+
+#endif /* CONF_CHR_C */
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* (c) 1995-2002 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* conf_chr.h *
+***********************************************************/
+
+/* ----- this file was automatically generated -- do not edit by hand ----- */
+
+#ifndef CONF_CHR_H
+#define CONF_CHR_H
+
+/* values for elements configuration (character elements) */
+
+#define EL_CHAR_SPACE (EL_CHAR_ASCII0 + 32)
+#define EL_CHAR_EXCLAM (EL_CHAR_ASCII0 + 33)
+#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_AMPERSAND (EL_CHAR_ASCII0 + 38)
+#define EL_CHAR_APOSTROPHE (EL_CHAR_ASCII0 + 39)
+#define EL_CHAR_PARENLEFT (EL_CHAR_ASCII0 + 40)
+#define EL_CHAR_PARENRIGHT (EL_CHAR_ASCII0 + 41)
+#define EL_CHAR_ASTERISK (EL_CHAR_ASCII0 + 42)
+#define EL_CHAR_PLUS (EL_CHAR_ASCII0 + 43)
+#define EL_CHAR_COMMA (EL_CHAR_ASCII0 + 44)
+#define EL_CHAR_MINUS (EL_CHAR_ASCII0 + 45)
+#define EL_CHAR_PERIOD (EL_CHAR_ASCII0 + 46)
+#define EL_CHAR_SLASH (EL_CHAR_ASCII0 + 47)
+#define EL_CHAR_0 (EL_CHAR_ASCII0 + 48)
+#define EL_CHAR_1 (EL_CHAR_ASCII0 + 49)
+#define EL_CHAR_2 (EL_CHAR_ASCII0 + 50)
+#define EL_CHAR_3 (EL_CHAR_ASCII0 + 51)
+#define EL_CHAR_4 (EL_CHAR_ASCII0 + 52)
+#define EL_CHAR_5 (EL_CHAR_ASCII0 + 53)
+#define EL_CHAR_6 (EL_CHAR_ASCII0 + 54)
+#define EL_CHAR_7 (EL_CHAR_ASCII0 + 55)
+#define EL_CHAR_8 (EL_CHAR_ASCII0 + 56)
+#define EL_CHAR_9 (EL_CHAR_ASCII0 + 57)
+#define EL_CHAR_COLON (EL_CHAR_ASCII0 + 58)
+#define EL_CHAR_SEMICOLON (EL_CHAR_ASCII0 + 59)
+#define EL_CHAR_LESS (EL_CHAR_ASCII0 + 60)
+#define EL_CHAR_EQUAL (EL_CHAR_ASCII0 + 61)
+#define EL_CHAR_GREATER (EL_CHAR_ASCII0 + 62)
+#define EL_CHAR_QUESTION (EL_CHAR_ASCII0 + 63)
+#define EL_CHAR_AT (EL_CHAR_ASCII0 + 64)
+#define EL_CHAR_A (EL_CHAR_ASCII0 + 65)
+#define EL_CHAR_B (EL_CHAR_ASCII0 + 66)
+#define EL_CHAR_C (EL_CHAR_ASCII0 + 67)
+#define EL_CHAR_D (EL_CHAR_ASCII0 + 68)
+#define EL_CHAR_E (EL_CHAR_ASCII0 + 69)
+#define EL_CHAR_F (EL_CHAR_ASCII0 + 70)
+#define EL_CHAR_G (EL_CHAR_ASCII0 + 71)
+#define EL_CHAR_H (EL_CHAR_ASCII0 + 72)
+#define EL_CHAR_I (EL_CHAR_ASCII0 + 73)
+#define EL_CHAR_J (EL_CHAR_ASCII0 + 74)
+#define EL_CHAR_K (EL_CHAR_ASCII0 + 75)
+#define EL_CHAR_L (EL_CHAR_ASCII0 + 76)
+#define EL_CHAR_M (EL_CHAR_ASCII0 + 77)
+#define EL_CHAR_N (EL_CHAR_ASCII0 + 78)
+#define EL_CHAR_O (EL_CHAR_ASCII0 + 79)
+#define EL_CHAR_P (EL_CHAR_ASCII0 + 80)
+#define EL_CHAR_Q (EL_CHAR_ASCII0 + 81)
+#define EL_CHAR_R (EL_CHAR_ASCII0 + 82)
+#define EL_CHAR_S (EL_CHAR_ASCII0 + 83)
+#define EL_CHAR_T (EL_CHAR_ASCII0 + 84)
+#define EL_CHAR_U (EL_CHAR_ASCII0 + 85)
+#define EL_CHAR_V (EL_CHAR_ASCII0 + 86)
+#define EL_CHAR_W (EL_CHAR_ASCII0 + 87)
+#define EL_CHAR_X (EL_CHAR_ASCII0 + 88)
+#define EL_CHAR_Y (EL_CHAR_ASCII0 + 89)
+#define EL_CHAR_Z (EL_CHAR_ASCII0 + 90)
+#define EL_CHAR_BRACKETLEFT (EL_CHAR_ASCII0 + 91)
+#define EL_CHAR_BACKSLASH (EL_CHAR_ASCII0 + 92)
+#define EL_CHAR_BRACKETRIGHT (EL_CHAR_ASCII0 + 93)
+#define EL_CHAR_ASCIICIRCUM (EL_CHAR_ASCII0 + 94)
+#define EL_CHAR_UNDERSCORE (EL_CHAR_ASCII0 + 95)
+#define EL_CHAR_COPYRIGHT (EL_CHAR_ASCII0 + 96)
+#define EL_CHAR_AUMLAUT (EL_CHAR_ASCII0 + 97)
+#define EL_CHAR_OUMLAUT (EL_CHAR_ASCII0 + 98)
+#define EL_CHAR_UUMLAUT (EL_CHAR_ASCII0 + 99)
+#define EL_CHAR_DEGREE (EL_CHAR_ASCII0 + 100)
+#define EL_CHAR_TRADEMARK (EL_CHAR_ASCII0 + 101)
+#define EL_CHAR_CURSOR (EL_CHAR_ASCII0 + 102)
+
+#endif /* CONF_CHR_C */
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* (c) 1995-2002 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* conf_cus.c *
+***********************************************************/
+
+/* ----- this file was automatically generated -- do not edit by hand ----- */
+
+#ifndef CONF_CUS_C
+#define CONF_CUS_C
+
+/* values for graphics configuration (custom elements) */
+
+ { "custom_1", "RocksElements.pcx" },
+ { "custom_1.xpos", "7" },
+ { "custom_1.ypos", "9" },
+ { "custom_1.frames", "1" },
+ { "custom_1.EDITOR", "RocksElements.pcx" },
+ { "custom_1.EDITOR.xpos", "15" },
+ { "custom_1.EDITOR.ypos", "13" },
+
+ { "custom_2", "RocksElements.pcx" },
+ { "custom_2.xpos", "7" },
+ { "custom_2.ypos", "9" },
+ { "custom_2.frames", "1" },
+ { "custom_2.EDITOR", "RocksElements.pcx" },
+ { "custom_2.EDITOR.xpos", "15" },
+ { "custom_2.EDITOR.ypos", "13" },
+
+ { "custom_3", "RocksElements.pcx" },
+ { "custom_3.xpos", "7" },
+ { "custom_3.ypos", "9" },
+ { "custom_3.frames", "1" },
+ { "custom_3.EDITOR", "RocksElements.pcx" },
+ { "custom_3.EDITOR.xpos", "15" },
+ { "custom_3.EDITOR.ypos", "13" },
+
+ { "custom_4", "RocksElements.pcx" },
+ { "custom_4.xpos", "7" },
+ { "custom_4.ypos", "9" },
+ { "custom_4.frames", "1" },
+ { "custom_4.EDITOR", "RocksElements.pcx" },
+ { "custom_4.EDITOR.xpos", "15" },
+ { "custom_4.EDITOR.ypos", "13" },
+
+ { "custom_5", "RocksElements.pcx" },
+ { "custom_5.xpos", "7" },
+ { "custom_5.ypos", "9" },
+ { "custom_5.frames", "1" },
+ { "custom_5.EDITOR", "RocksElements.pcx" },
+ { "custom_5.EDITOR.xpos", "15" },
+ { "custom_5.EDITOR.ypos", "13" },
+
+ { "custom_6", "RocksElements.pcx" },
+ { "custom_6.xpos", "7" },
+ { "custom_6.ypos", "9" },
+ { "custom_6.frames", "1" },
+ { "custom_6.EDITOR", "RocksElements.pcx" },
+ { "custom_6.EDITOR.xpos", "15" },
+ { "custom_6.EDITOR.ypos", "13" },
+
+ { "custom_7", "RocksElements.pcx" },
+ { "custom_7.xpos", "7" },
+ { "custom_7.ypos", "9" },
+ { "custom_7.frames", "1" },
+ { "custom_7.EDITOR", "RocksElements.pcx" },
+ { "custom_7.EDITOR.xpos", "15" },
+ { "custom_7.EDITOR.ypos", "13" },
+
+ { "custom_8", "RocksElements.pcx" },
+ { "custom_8.xpos", "7" },
+ { "custom_8.ypos", "9" },
+ { "custom_8.frames", "1" },
+ { "custom_8.EDITOR", "RocksElements.pcx" },
+ { "custom_8.EDITOR.xpos", "15" },
+ { "custom_8.EDITOR.ypos", "13" },
+
+ { "custom_9", "RocksElements.pcx" },
+ { "custom_9.xpos", "7" },
+ { "custom_9.ypos", "9" },
+ { "custom_9.frames", "1" },
+ { "custom_9.EDITOR", "RocksElements.pcx" },
+ { "custom_9.EDITOR.xpos", "15" },
+ { "custom_9.EDITOR.ypos", "13" },
+
+ { "custom_10", "RocksElements.pcx" },
+ { "custom_10.xpos", "7" },
+ { "custom_10.ypos", "9" },
+ { "custom_10.frames", "1" },
+ { "custom_10.EDITOR", "RocksElements.pcx" },
+ { "custom_10.EDITOR.xpos", "15" },
+ { "custom_10.EDITOR.ypos", "13" },
+
+ { "custom_11", "RocksElements.pcx" },
+ { "custom_11.xpos", "7" },
+ { "custom_11.ypos", "9" },
+ { "custom_11.frames", "1" },
+ { "custom_11.EDITOR", "RocksElements.pcx" },
+ { "custom_11.EDITOR.xpos", "15" },
+ { "custom_11.EDITOR.ypos", "13" },
+
+ { "custom_12", "RocksElements.pcx" },
+ { "custom_12.xpos", "7" },
+ { "custom_12.ypos", "9" },
+ { "custom_12.frames", "1" },
+ { "custom_12.EDITOR", "RocksElements.pcx" },
+ { "custom_12.EDITOR.xpos", "15" },
+ { "custom_12.EDITOR.ypos", "13" },
+
+ { "custom_13", "RocksElements.pcx" },
+ { "custom_13.xpos", "7" },
+ { "custom_13.ypos", "9" },
+ { "custom_13.frames", "1" },
+ { "custom_13.EDITOR", "RocksElements.pcx" },
+ { "custom_13.EDITOR.xpos", "15" },
+ { "custom_13.EDITOR.ypos", "13" },
+
+ { "custom_14", "RocksElements.pcx" },
+ { "custom_14.xpos", "7" },
+ { "custom_14.ypos", "9" },
+ { "custom_14.frames", "1" },
+ { "custom_14.EDITOR", "RocksElements.pcx" },
+ { "custom_14.EDITOR.xpos", "15" },
+ { "custom_14.EDITOR.ypos", "13" },
+
+ { "custom_15", "RocksElements.pcx" },
+ { "custom_15.xpos", "7" },
+ { "custom_15.ypos", "9" },
+ { "custom_15.frames", "1" },
+ { "custom_15.EDITOR", "RocksElements.pcx" },
+ { "custom_15.EDITOR.xpos", "15" },
+ { "custom_15.EDITOR.ypos", "13" },
+
+ { "custom_16", "RocksElements.pcx" },
+ { "custom_16.xpos", "7" },
+ { "custom_16.ypos", "9" },
+ { "custom_16.frames", "1" },
+ { "custom_16.EDITOR", "RocksElements.pcx" },
+ { "custom_16.EDITOR.xpos", "15" },
+ { "custom_16.EDITOR.ypos", "13" },
+
+ { "custom_17", "RocksElements.pcx" },
+ { "custom_17.xpos", "7" },
+ { "custom_17.ypos", "9" },
+ { "custom_17.frames", "1" },
+ { "custom_17.EDITOR", "RocksElements.pcx" },
+ { "custom_17.EDITOR.xpos", "15" },
+ { "custom_17.EDITOR.ypos", "13" },
+
+ { "custom_18", "RocksElements.pcx" },
+ { "custom_18.xpos", "7" },
+ { "custom_18.ypos", "9" },
+ { "custom_18.frames", "1" },
+ { "custom_18.EDITOR", "RocksElements.pcx" },
+ { "custom_18.EDITOR.xpos", "15" },
+ { "custom_18.EDITOR.ypos", "13" },
+
+ { "custom_19", "RocksElements.pcx" },
+ { "custom_19.xpos", "7" },
+ { "custom_19.ypos", "9" },
+ { "custom_19.frames", "1" },
+ { "custom_19.EDITOR", "RocksElements.pcx" },
+ { "custom_19.EDITOR.xpos", "15" },
+ { "custom_19.EDITOR.ypos", "13" },
+
+ { "custom_20", "RocksElements.pcx" },
+ { "custom_20.xpos", "7" },
+ { "custom_20.ypos", "9" },
+ { "custom_20.frames", "1" },
+ { "custom_20.EDITOR", "RocksElements.pcx" },
+ { "custom_20.EDITOR.xpos", "15" },
+ { "custom_20.EDITOR.ypos", "13" },
+
+ { "custom_21", "RocksElements.pcx" },
+ { "custom_21.xpos", "7" },
+ { "custom_21.ypos", "9" },
+ { "custom_21.frames", "1" },
+ { "custom_21.EDITOR", "RocksElements.pcx" },
+ { "custom_21.EDITOR.xpos", "15" },
+ { "custom_21.EDITOR.ypos", "13" },
+
+ { "custom_22", "RocksElements.pcx" },
+ { "custom_22.xpos", "7" },
+ { "custom_22.ypos", "9" },
+ { "custom_22.frames", "1" },
+ { "custom_22.EDITOR", "RocksElements.pcx" },
+ { "custom_22.EDITOR.xpos", "15" },
+ { "custom_22.EDITOR.ypos", "13" },
+
+ { "custom_23", "RocksElements.pcx" },
+ { "custom_23.xpos", "7" },
+ { "custom_23.ypos", "9" },
+ { "custom_23.frames", "1" },
+ { "custom_23.EDITOR", "RocksElements.pcx" },
+ { "custom_23.EDITOR.xpos", "15" },
+ { "custom_23.EDITOR.ypos", "13" },
+
+ { "custom_24", "RocksElements.pcx" },
+ { "custom_24.xpos", "7" },
+ { "custom_24.ypos", "9" },
+ { "custom_24.frames", "1" },
+ { "custom_24.EDITOR", "RocksElements.pcx" },
+ { "custom_24.EDITOR.xpos", "15" },
+ { "custom_24.EDITOR.ypos", "13" },
+
+ { "custom_25", "RocksElements.pcx" },
+ { "custom_25.xpos", "7" },
+ { "custom_25.ypos", "9" },
+ { "custom_25.frames", "1" },
+ { "custom_25.EDITOR", "RocksElements.pcx" },
+ { "custom_25.EDITOR.xpos", "15" },
+ { "custom_25.EDITOR.ypos", "13" },
+
+ { "custom_26", "RocksElements.pcx" },
+ { "custom_26.xpos", "7" },
+ { "custom_26.ypos", "9" },
+ { "custom_26.frames", "1" },
+ { "custom_26.EDITOR", "RocksElements.pcx" },
+ { "custom_26.EDITOR.xpos", "15" },
+ { "custom_26.EDITOR.ypos", "13" },
+
+ { "custom_27", "RocksElements.pcx" },
+ { "custom_27.xpos", "7" },
+ { "custom_27.ypos", "9" },
+ { "custom_27.frames", "1" },
+ { "custom_27.EDITOR", "RocksElements.pcx" },
+ { "custom_27.EDITOR.xpos", "15" },
+ { "custom_27.EDITOR.ypos", "13" },
+
+ { "custom_28", "RocksElements.pcx" },
+ { "custom_28.xpos", "7" },
+ { "custom_28.ypos", "9" },
+ { "custom_28.frames", "1" },
+ { "custom_28.EDITOR", "RocksElements.pcx" },
+ { "custom_28.EDITOR.xpos", "15" },
+ { "custom_28.EDITOR.ypos", "13" },
+
+ { "custom_29", "RocksElements.pcx" },
+ { "custom_29.xpos", "7" },
+ { "custom_29.ypos", "9" },
+ { "custom_29.frames", "1" },
+ { "custom_29.EDITOR", "RocksElements.pcx" },
+ { "custom_29.EDITOR.xpos", "15" },
+ { "custom_29.EDITOR.ypos", "13" },
+
+ { "custom_30", "RocksElements.pcx" },
+ { "custom_30.xpos", "7" },
+ { "custom_30.ypos", "9" },
+ { "custom_30.frames", "1" },
+ { "custom_30.EDITOR", "RocksElements.pcx" },
+ { "custom_30.EDITOR.xpos", "15" },
+ { "custom_30.EDITOR.ypos", "13" },
+
+ { "custom_31", "RocksElements.pcx" },
+ { "custom_31.xpos", "7" },
+ { "custom_31.ypos", "9" },
+ { "custom_31.frames", "1" },
+ { "custom_31.EDITOR", "RocksElements.pcx" },
+ { "custom_31.EDITOR.xpos", "15" },
+ { "custom_31.EDITOR.ypos", "13" },
+
+ { "custom_32", "RocksElements.pcx" },
+ { "custom_32.xpos", "7" },
+ { "custom_32.ypos", "9" },
+ { "custom_32.frames", "1" },
+ { "custom_32.EDITOR", "RocksElements.pcx" },
+ { "custom_32.EDITOR.xpos", "15" },
+ { "custom_32.EDITOR.ypos", "13" },
+
+ { "custom_33", "RocksElements.pcx" },
+ { "custom_33.xpos", "7" },
+ { "custom_33.ypos", "9" },
+ { "custom_33.frames", "1" },
+ { "custom_33.EDITOR", "RocksElements.pcx" },
+ { "custom_33.EDITOR.xpos", "15" },
+ { "custom_33.EDITOR.ypos", "13" },
+
+ { "custom_34", "RocksElements.pcx" },
+ { "custom_34.xpos", "7" },
+ { "custom_34.ypos", "9" },
+ { "custom_34.frames", "1" },
+ { "custom_34.EDITOR", "RocksElements.pcx" },
+ { "custom_34.EDITOR.xpos", "15" },
+ { "custom_34.EDITOR.ypos", "13" },
+
+ { "custom_35", "RocksElements.pcx" },
+ { "custom_35.xpos", "7" },
+ { "custom_35.ypos", "9" },
+ { "custom_35.frames", "1" },
+ { "custom_35.EDITOR", "RocksElements.pcx" },
+ { "custom_35.EDITOR.xpos", "15" },
+ { "custom_35.EDITOR.ypos", "13" },
+
+ { "custom_36", "RocksElements.pcx" },
+ { "custom_36.xpos", "7" },
+ { "custom_36.ypos", "9" },
+ { "custom_36.frames", "1" },
+ { "custom_36.EDITOR", "RocksElements.pcx" },
+ { "custom_36.EDITOR.xpos", "15" },
+ { "custom_36.EDITOR.ypos", "13" },
+
+ { "custom_37", "RocksElements.pcx" },
+ { "custom_37.xpos", "7" },
+ { "custom_37.ypos", "9" },
+ { "custom_37.frames", "1" },
+ { "custom_37.EDITOR", "RocksElements.pcx" },
+ { "custom_37.EDITOR.xpos", "15" },
+ { "custom_37.EDITOR.ypos", "13" },
+
+ { "custom_38", "RocksElements.pcx" },
+ { "custom_38.xpos", "7" },
+ { "custom_38.ypos", "9" },
+ { "custom_38.frames", "1" },
+ { "custom_38.EDITOR", "RocksElements.pcx" },
+ { "custom_38.EDITOR.xpos", "15" },
+ { "custom_38.EDITOR.ypos", "13" },
+
+ { "custom_39", "RocksElements.pcx" },
+ { "custom_39.xpos", "7" },
+ { "custom_39.ypos", "9" },
+ { "custom_39.frames", "1" },
+ { "custom_39.EDITOR", "RocksElements.pcx" },
+ { "custom_39.EDITOR.xpos", "15" },
+ { "custom_39.EDITOR.ypos", "13" },
+
+ { "custom_40", "RocksElements.pcx" },
+ { "custom_40.xpos", "7" },
+ { "custom_40.ypos", "9" },
+ { "custom_40.frames", "1" },
+ { "custom_40.EDITOR", "RocksElements.pcx" },
+ { "custom_40.EDITOR.xpos", "15" },
+ { "custom_40.EDITOR.ypos", "13" },
+
+ { "custom_41", "RocksElements.pcx" },
+ { "custom_41.xpos", "7" },
+ { "custom_41.ypos", "9" },
+ { "custom_41.frames", "1" },
+ { "custom_41.EDITOR", "RocksElements.pcx" },
+ { "custom_41.EDITOR.xpos", "15" },
+ { "custom_41.EDITOR.ypos", "13" },
+
+ { "custom_42", "RocksElements.pcx" },
+ { "custom_42.xpos", "7" },
+ { "custom_42.ypos", "9" },
+ { "custom_42.frames", "1" },
+ { "custom_42.EDITOR", "RocksElements.pcx" },
+ { "custom_42.EDITOR.xpos", "15" },
+ { "custom_42.EDITOR.ypos", "13" },
+
+ { "custom_43", "RocksElements.pcx" },
+ { "custom_43.xpos", "7" },
+ { "custom_43.ypos", "9" },
+ { "custom_43.frames", "1" },
+ { "custom_43.EDITOR", "RocksElements.pcx" },
+ { "custom_43.EDITOR.xpos", "15" },
+ { "custom_43.EDITOR.ypos", "13" },
+
+ { "custom_44", "RocksElements.pcx" },
+ { "custom_44.xpos", "7" },
+ { "custom_44.ypos", "9" },
+ { "custom_44.frames", "1" },
+ { "custom_44.EDITOR", "RocksElements.pcx" },
+ { "custom_44.EDITOR.xpos", "15" },
+ { "custom_44.EDITOR.ypos", "13" },
+
+ { "custom_45", "RocksElements.pcx" },
+ { "custom_45.xpos", "7" },
+ { "custom_45.ypos", "9" },
+ { "custom_45.frames", "1" },
+ { "custom_45.EDITOR", "RocksElements.pcx" },
+ { "custom_45.EDITOR.xpos", "15" },
+ { "custom_45.EDITOR.ypos", "13" },
+
+ { "custom_46", "RocksElements.pcx" },
+ { "custom_46.xpos", "7" },
+ { "custom_46.ypos", "9" },
+ { "custom_46.frames", "1" },
+ { "custom_46.EDITOR", "RocksElements.pcx" },
+ { "custom_46.EDITOR.xpos", "15" },
+ { "custom_46.EDITOR.ypos", "13" },
+
+ { "custom_47", "RocksElements.pcx" },
+ { "custom_47.xpos", "7" },
+ { "custom_47.ypos", "9" },
+ { "custom_47.frames", "1" },
+ { "custom_47.EDITOR", "RocksElements.pcx" },
+ { "custom_47.EDITOR.xpos", "15" },
+ { "custom_47.EDITOR.ypos", "13" },
+
+ { "custom_48", "RocksElements.pcx" },
+ { "custom_48.xpos", "7" },
+ { "custom_48.ypos", "9" },
+ { "custom_48.frames", "1" },
+ { "custom_48.EDITOR", "RocksElements.pcx" },
+ { "custom_48.EDITOR.xpos", "15" },
+ { "custom_48.EDITOR.ypos", "13" },
+
+ { "custom_49", "RocksElements.pcx" },
+ { "custom_49.xpos", "7" },
+ { "custom_49.ypos", "9" },
+ { "custom_49.frames", "1" },
+ { "custom_49.EDITOR", "RocksElements.pcx" },
+ { "custom_49.EDITOR.xpos", "15" },
+ { "custom_49.EDITOR.ypos", "13" },
+
+ { "custom_50", "RocksElements.pcx" },
+ { "custom_50.xpos", "7" },
+ { "custom_50.ypos", "9" },
+ { "custom_50.frames", "1" },
+ { "custom_50.EDITOR", "RocksElements.pcx" },
+ { "custom_50.EDITOR.xpos", "15" },
+ { "custom_50.EDITOR.ypos", "13" },
+
+ { "custom_51", "RocksElements.pcx" },
+ { "custom_51.xpos", "7" },
+ { "custom_51.ypos", "9" },
+ { "custom_51.frames", "1" },
+ { "custom_51.EDITOR", "RocksElements.pcx" },
+ { "custom_51.EDITOR.xpos", "15" },
+ { "custom_51.EDITOR.ypos", "13" },
+
+ { "custom_52", "RocksElements.pcx" },
+ { "custom_52.xpos", "7" },
+ { "custom_52.ypos", "9" },
+ { "custom_52.frames", "1" },
+ { "custom_52.EDITOR", "RocksElements.pcx" },
+ { "custom_52.EDITOR.xpos", "15" },
+ { "custom_52.EDITOR.ypos", "13" },
+
+ { "custom_53", "RocksElements.pcx" },
+ { "custom_53.xpos", "7" },
+ { "custom_53.ypos", "9" },
+ { "custom_53.frames", "1" },
+ { "custom_53.EDITOR", "RocksElements.pcx" },
+ { "custom_53.EDITOR.xpos", "15" },
+ { "custom_53.EDITOR.ypos", "13" },
+
+ { "custom_54", "RocksElements.pcx" },
+ { "custom_54.xpos", "7" },
+ { "custom_54.ypos", "9" },
+ { "custom_54.frames", "1" },
+ { "custom_54.EDITOR", "RocksElements.pcx" },
+ { "custom_54.EDITOR.xpos", "15" },
+ { "custom_54.EDITOR.ypos", "13" },
+
+ { "custom_55", "RocksElements.pcx" },
+ { "custom_55.xpos", "7" },
+ { "custom_55.ypos", "9" },
+ { "custom_55.frames", "1" },
+ { "custom_55.EDITOR", "RocksElements.pcx" },
+ { "custom_55.EDITOR.xpos", "15" },
+ { "custom_55.EDITOR.ypos", "13" },
+
+ { "custom_56", "RocksElements.pcx" },
+ { "custom_56.xpos", "7" },
+ { "custom_56.ypos", "9" },
+ { "custom_56.frames", "1" },
+ { "custom_56.EDITOR", "RocksElements.pcx" },
+ { "custom_56.EDITOR.xpos", "15" },
+ { "custom_56.EDITOR.ypos", "13" },
+
+ { "custom_57", "RocksElements.pcx" },
+ { "custom_57.xpos", "7" },
+ { "custom_57.ypos", "9" },
+ { "custom_57.frames", "1" },
+ { "custom_57.EDITOR", "RocksElements.pcx" },
+ { "custom_57.EDITOR.xpos", "15" },
+ { "custom_57.EDITOR.ypos", "13" },
+
+ { "custom_58", "RocksElements.pcx" },
+ { "custom_58.xpos", "7" },
+ { "custom_58.ypos", "9" },
+ { "custom_58.frames", "1" },
+ { "custom_58.EDITOR", "RocksElements.pcx" },
+ { "custom_58.EDITOR.xpos", "15" },
+ { "custom_58.EDITOR.ypos", "13" },
+
+ { "custom_59", "RocksElements.pcx" },
+ { "custom_59.xpos", "7" },
+ { "custom_59.ypos", "9" },
+ { "custom_59.frames", "1" },
+ { "custom_59.EDITOR", "RocksElements.pcx" },
+ { "custom_59.EDITOR.xpos", "15" },
+ { "custom_59.EDITOR.ypos", "13" },
+
+ { "custom_60", "RocksElements.pcx" },
+ { "custom_60.xpos", "7" },
+ { "custom_60.ypos", "9" },
+ { "custom_60.frames", "1" },
+ { "custom_60.EDITOR", "RocksElements.pcx" },
+ { "custom_60.EDITOR.xpos", "15" },
+ { "custom_60.EDITOR.ypos", "13" },
+
+ { "custom_61", "RocksElements.pcx" },
+ { "custom_61.xpos", "7" },
+ { "custom_61.ypos", "9" },
+ { "custom_61.frames", "1" },
+ { "custom_61.EDITOR", "RocksElements.pcx" },
+ { "custom_61.EDITOR.xpos", "15" },
+ { "custom_61.EDITOR.ypos", "13" },
+
+ { "custom_62", "RocksElements.pcx" },
+ { "custom_62.xpos", "7" },
+ { "custom_62.ypos", "9" },
+ { "custom_62.frames", "1" },
+ { "custom_62.EDITOR", "RocksElements.pcx" },
+ { "custom_62.EDITOR.xpos", "15" },
+ { "custom_62.EDITOR.ypos", "13" },
+
+ { "custom_63", "RocksElements.pcx" },
+ { "custom_63.xpos", "7" },
+ { "custom_63.ypos", "9" },
+ { "custom_63.frames", "1" },
+ { "custom_63.EDITOR", "RocksElements.pcx" },
+ { "custom_63.EDITOR.xpos", "15" },
+ { "custom_63.EDITOR.ypos", "13" },
+
+ { "custom_64", "RocksElements.pcx" },
+ { "custom_64.xpos", "7" },
+ { "custom_64.ypos", "9" },
+ { "custom_64.frames", "1" },
+ { "custom_64.EDITOR", "RocksElements.pcx" },
+ { "custom_64.EDITOR.xpos", "15" },
+ { "custom_64.EDITOR.ypos", "13" },
+
+ { "custom_65", "RocksElements.pcx" },
+ { "custom_65.xpos", "7" },
+ { "custom_65.ypos", "9" },
+ { "custom_65.frames", "1" },
+ { "custom_65.EDITOR", "RocksElements.pcx" },
+ { "custom_65.EDITOR.xpos", "15" },
+ { "custom_65.EDITOR.ypos", "13" },
+
+ { "custom_66", "RocksElements.pcx" },
+ { "custom_66.xpos", "7" },
+ { "custom_66.ypos", "9" },
+ { "custom_66.frames", "1" },
+ { "custom_66.EDITOR", "RocksElements.pcx" },
+ { "custom_66.EDITOR.xpos", "15" },
+ { "custom_66.EDITOR.ypos", "13" },
+
+ { "custom_67", "RocksElements.pcx" },
+ { "custom_67.xpos", "7" },
+ { "custom_67.ypos", "9" },
+ { "custom_67.frames", "1" },
+ { "custom_67.EDITOR", "RocksElements.pcx" },
+ { "custom_67.EDITOR.xpos", "15" },
+ { "custom_67.EDITOR.ypos", "13" },
+
+ { "custom_68", "RocksElements.pcx" },
+ { "custom_68.xpos", "7" },
+ { "custom_68.ypos", "9" },
+ { "custom_68.frames", "1" },
+ { "custom_68.EDITOR", "RocksElements.pcx" },
+ { "custom_68.EDITOR.xpos", "15" },
+ { "custom_68.EDITOR.ypos", "13" },
+
+ { "custom_69", "RocksElements.pcx" },
+ { "custom_69.xpos", "7" },
+ { "custom_69.ypos", "9" },
+ { "custom_69.frames", "1" },
+ { "custom_69.EDITOR", "RocksElements.pcx" },
+ { "custom_69.EDITOR.xpos", "15" },
+ { "custom_69.EDITOR.ypos", "13" },
+
+ { "custom_70", "RocksElements.pcx" },
+ { "custom_70.xpos", "7" },
+ { "custom_70.ypos", "9" },
+ { "custom_70.frames", "1" },
+ { "custom_70.EDITOR", "RocksElements.pcx" },
+ { "custom_70.EDITOR.xpos", "15" },
+ { "custom_70.EDITOR.ypos", "13" },
+
+ { "custom_71", "RocksElements.pcx" },
+ { "custom_71.xpos", "7" },
+ { "custom_71.ypos", "9" },
+ { "custom_71.frames", "1" },
+ { "custom_71.EDITOR", "RocksElements.pcx" },
+ { "custom_71.EDITOR.xpos", "15" },
+ { "custom_71.EDITOR.ypos", "13" },
+
+ { "custom_72", "RocksElements.pcx" },
+ { "custom_72.xpos", "7" },
+ { "custom_72.ypos", "9" },
+ { "custom_72.frames", "1" },
+ { "custom_72.EDITOR", "RocksElements.pcx" },
+ { "custom_72.EDITOR.xpos", "15" },
+ { "custom_72.EDITOR.ypos", "13" },
+
+ { "custom_73", "RocksElements.pcx" },
+ { "custom_73.xpos", "7" },
+ { "custom_73.ypos", "9" },
+ { "custom_73.frames", "1" },
+ { "custom_73.EDITOR", "RocksElements.pcx" },
+ { "custom_73.EDITOR.xpos", "15" },
+ { "custom_73.EDITOR.ypos", "13" },
+
+ { "custom_74", "RocksElements.pcx" },
+ { "custom_74.xpos", "7" },
+ { "custom_74.ypos", "9" },
+ { "custom_74.frames", "1" },
+ { "custom_74.EDITOR", "RocksElements.pcx" },
+ { "custom_74.EDITOR.xpos", "15" },
+ { "custom_74.EDITOR.ypos", "13" },
+
+ { "custom_75", "RocksElements.pcx" },
+ { "custom_75.xpos", "7" },
+ { "custom_75.ypos", "9" },
+ { "custom_75.frames", "1" },
+ { "custom_75.EDITOR", "RocksElements.pcx" },
+ { "custom_75.EDITOR.xpos", "15" },
+ { "custom_75.EDITOR.ypos", "13" },
+
+ { "custom_76", "RocksElements.pcx" },
+ { "custom_76.xpos", "7" },
+ { "custom_76.ypos", "9" },
+ { "custom_76.frames", "1" },
+ { "custom_76.EDITOR", "RocksElements.pcx" },
+ { "custom_76.EDITOR.xpos", "15" },
+ { "custom_76.EDITOR.ypos", "13" },
+
+ { "custom_77", "RocksElements.pcx" },
+ { "custom_77.xpos", "7" },
+ { "custom_77.ypos", "9" },
+ { "custom_77.frames", "1" },
+ { "custom_77.EDITOR", "RocksElements.pcx" },
+ { "custom_77.EDITOR.xpos", "15" },
+ { "custom_77.EDITOR.ypos", "13" },
+
+ { "custom_78", "RocksElements.pcx" },
+ { "custom_78.xpos", "7" },
+ { "custom_78.ypos", "9" },
+ { "custom_78.frames", "1" },
+ { "custom_78.EDITOR", "RocksElements.pcx" },
+ { "custom_78.EDITOR.xpos", "15" },
+ { "custom_78.EDITOR.ypos", "13" },
+
+ { "custom_79", "RocksElements.pcx" },
+ { "custom_79.xpos", "7" },
+ { "custom_79.ypos", "9" },
+ { "custom_79.frames", "1" },
+ { "custom_79.EDITOR", "RocksElements.pcx" },
+ { "custom_79.EDITOR.xpos", "15" },
+ { "custom_79.EDITOR.ypos", "13" },
+
+ { "custom_80", "RocksElements.pcx" },
+ { "custom_80.xpos", "7" },
+ { "custom_80.ypos", "9" },
+ { "custom_80.frames", "1" },
+ { "custom_80.EDITOR", "RocksElements.pcx" },
+ { "custom_80.EDITOR.xpos", "15" },
+ { "custom_80.EDITOR.ypos", "13" },
+
+ { "custom_81", "RocksElements.pcx" },
+ { "custom_81.xpos", "7" },
+ { "custom_81.ypos", "9" },
+ { "custom_81.frames", "1" },
+ { "custom_81.EDITOR", "RocksElements.pcx" },
+ { "custom_81.EDITOR.xpos", "15" },
+ { "custom_81.EDITOR.ypos", "13" },
+
+ { "custom_82", "RocksElements.pcx" },
+ { "custom_82.xpos", "7" },
+ { "custom_82.ypos", "9" },
+ { "custom_82.frames", "1" },
+ { "custom_82.EDITOR", "RocksElements.pcx" },
+ { "custom_82.EDITOR.xpos", "15" },
+ { "custom_82.EDITOR.ypos", "13" },
+
+ { "custom_83", "RocksElements.pcx" },
+ { "custom_83.xpos", "7" },
+ { "custom_83.ypos", "9" },
+ { "custom_83.frames", "1" },
+ { "custom_83.EDITOR", "RocksElements.pcx" },
+ { "custom_83.EDITOR.xpos", "15" },
+ { "custom_83.EDITOR.ypos", "13" },
+
+ { "custom_84", "RocksElements.pcx" },
+ { "custom_84.xpos", "7" },
+ { "custom_84.ypos", "9" },
+ { "custom_84.frames", "1" },
+ { "custom_84.EDITOR", "RocksElements.pcx" },
+ { "custom_84.EDITOR.xpos", "15" },
+ { "custom_84.EDITOR.ypos", "13" },
+
+ { "custom_85", "RocksElements.pcx" },
+ { "custom_85.xpos", "7" },
+ { "custom_85.ypos", "9" },
+ { "custom_85.frames", "1" },
+ { "custom_85.EDITOR", "RocksElements.pcx" },
+ { "custom_85.EDITOR.xpos", "15" },
+ { "custom_85.EDITOR.ypos", "13" },
+
+ { "custom_86", "RocksElements.pcx" },
+ { "custom_86.xpos", "7" },
+ { "custom_86.ypos", "9" },
+ { "custom_86.frames", "1" },
+ { "custom_86.EDITOR", "RocksElements.pcx" },
+ { "custom_86.EDITOR.xpos", "15" },
+ { "custom_86.EDITOR.ypos", "13" },
+
+ { "custom_87", "RocksElements.pcx" },
+ { "custom_87.xpos", "7" },
+ { "custom_87.ypos", "9" },
+ { "custom_87.frames", "1" },
+ { "custom_87.EDITOR", "RocksElements.pcx" },
+ { "custom_87.EDITOR.xpos", "15" },
+ { "custom_87.EDITOR.ypos", "13" },
+
+ { "custom_88", "RocksElements.pcx" },
+ { "custom_88.xpos", "7" },
+ { "custom_88.ypos", "9" },
+ { "custom_88.frames", "1" },
+ { "custom_88.EDITOR", "RocksElements.pcx" },
+ { "custom_88.EDITOR.xpos", "15" },
+ { "custom_88.EDITOR.ypos", "13" },
+
+ { "custom_89", "RocksElements.pcx" },
+ { "custom_89.xpos", "7" },
+ { "custom_89.ypos", "9" },
+ { "custom_89.frames", "1" },
+ { "custom_89.EDITOR", "RocksElements.pcx" },
+ { "custom_89.EDITOR.xpos", "15" },
+ { "custom_89.EDITOR.ypos", "13" },
+
+ { "custom_90", "RocksElements.pcx" },
+ { "custom_90.xpos", "7" },
+ { "custom_90.ypos", "9" },
+ { "custom_90.frames", "1" },
+ { "custom_90.EDITOR", "RocksElements.pcx" },
+ { "custom_90.EDITOR.xpos", "15" },
+ { "custom_90.EDITOR.ypos", "13" },
+
+ { "custom_91", "RocksElements.pcx" },
+ { "custom_91.xpos", "7" },
+ { "custom_91.ypos", "9" },
+ { "custom_91.frames", "1" },
+ { "custom_91.EDITOR", "RocksElements.pcx" },
+ { "custom_91.EDITOR.xpos", "15" },
+ { "custom_91.EDITOR.ypos", "13" },
+
+ { "custom_92", "RocksElements.pcx" },
+ { "custom_92.xpos", "7" },
+ { "custom_92.ypos", "9" },
+ { "custom_92.frames", "1" },
+ { "custom_92.EDITOR", "RocksElements.pcx" },
+ { "custom_92.EDITOR.xpos", "15" },
+ { "custom_92.EDITOR.ypos", "13" },
+
+ { "custom_93", "RocksElements.pcx" },
+ { "custom_93.xpos", "7" },
+ { "custom_93.ypos", "9" },
+ { "custom_93.frames", "1" },
+ { "custom_93.EDITOR", "RocksElements.pcx" },
+ { "custom_93.EDITOR.xpos", "15" },
+ { "custom_93.EDITOR.ypos", "13" },
+
+ { "custom_94", "RocksElements.pcx" },
+ { "custom_94.xpos", "7" },
+ { "custom_94.ypos", "9" },
+ { "custom_94.frames", "1" },
+ { "custom_94.EDITOR", "RocksElements.pcx" },
+ { "custom_94.EDITOR.xpos", "15" },
+ { "custom_94.EDITOR.ypos", "13" },
+
+ { "custom_95", "RocksElements.pcx" },
+ { "custom_95.xpos", "7" },
+ { "custom_95.ypos", "9" },
+ { "custom_95.frames", "1" },
+ { "custom_95.EDITOR", "RocksElements.pcx" },
+ { "custom_95.EDITOR.xpos", "15" },
+ { "custom_95.EDITOR.ypos", "13" },
+
+ { "custom_96", "RocksElements.pcx" },
+ { "custom_96.xpos", "7" },
+ { "custom_96.ypos", "9" },
+ { "custom_96.frames", "1" },
+ { "custom_96.EDITOR", "RocksElements.pcx" },
+ { "custom_96.EDITOR.xpos", "15" },
+ { "custom_96.EDITOR.ypos", "13" },
+
+ { "custom_97", "RocksElements.pcx" },
+ { "custom_97.xpos", "7" },
+ { "custom_97.ypos", "9" },
+ { "custom_97.frames", "1" },
+ { "custom_97.EDITOR", "RocksElements.pcx" },
+ { "custom_97.EDITOR.xpos", "15" },
+ { "custom_97.EDITOR.ypos", "13" },
+
+ { "custom_98", "RocksElements.pcx" },
+ { "custom_98.xpos", "7" },
+ { "custom_98.ypos", "9" },
+ { "custom_98.frames", "1" },
+ { "custom_98.EDITOR", "RocksElements.pcx" },
+ { "custom_98.EDITOR.xpos", "15" },
+ { "custom_98.EDITOR.ypos", "13" },
+
+ { "custom_99", "RocksElements.pcx" },
+ { "custom_99.xpos", "7" },
+ { "custom_99.ypos", "9" },
+ { "custom_99.frames", "1" },
+ { "custom_99.EDITOR", "RocksElements.pcx" },
+ { "custom_99.EDITOR.xpos", "15" },
+ { "custom_99.EDITOR.ypos", "13" },
+
+ { "custom_100", "RocksElements.pcx" },
+ { "custom_100.xpos", "7" },
+ { "custom_100.ypos", "9" },
+ { "custom_100.frames", "1" },
+ { "custom_100.EDITOR", "RocksElements.pcx" },
+ { "custom_100.EDITOR.xpos", "15" },
+ { "custom_100.EDITOR.ypos", "13" },
+
+ { "custom_101", "RocksElements.pcx" },
+ { "custom_101.xpos", "7" },
+ { "custom_101.ypos", "9" },
+ { "custom_101.frames", "1" },
+ { "custom_101.EDITOR", "RocksElements.pcx" },
+ { "custom_101.EDITOR.xpos", "15" },
+ { "custom_101.EDITOR.ypos", "13" },
+
+ { "custom_102", "RocksElements.pcx" },
+ { "custom_102.xpos", "7" },
+ { "custom_102.ypos", "9" },
+ { "custom_102.frames", "1" },
+ { "custom_102.EDITOR", "RocksElements.pcx" },
+ { "custom_102.EDITOR.xpos", "15" },
+ { "custom_102.EDITOR.ypos", "13" },
+
+ { "custom_103", "RocksElements.pcx" },
+ { "custom_103.xpos", "7" },
+ { "custom_103.ypos", "9" },
+ { "custom_103.frames", "1" },
+ { "custom_103.EDITOR", "RocksElements.pcx" },
+ { "custom_103.EDITOR.xpos", "15" },
+ { "custom_103.EDITOR.ypos", "13" },
+
+ { "custom_104", "RocksElements.pcx" },
+ { "custom_104.xpos", "7" },
+ { "custom_104.ypos", "9" },
+ { "custom_104.frames", "1" },
+ { "custom_104.EDITOR", "RocksElements.pcx" },
+ { "custom_104.EDITOR.xpos", "15" },
+ { "custom_104.EDITOR.ypos", "13" },
+
+ { "custom_105", "RocksElements.pcx" },
+ { "custom_105.xpos", "7" },
+ { "custom_105.ypos", "9" },
+ { "custom_105.frames", "1" },
+ { "custom_105.EDITOR", "RocksElements.pcx" },
+ { "custom_105.EDITOR.xpos", "15" },
+ { "custom_105.EDITOR.ypos", "13" },
+
+ { "custom_106", "RocksElements.pcx" },
+ { "custom_106.xpos", "7" },
+ { "custom_106.ypos", "9" },
+ { "custom_106.frames", "1" },
+ { "custom_106.EDITOR", "RocksElements.pcx" },
+ { "custom_106.EDITOR.xpos", "15" },
+ { "custom_106.EDITOR.ypos", "13" },
+
+ { "custom_107", "RocksElements.pcx" },
+ { "custom_107.xpos", "7" },
+ { "custom_107.ypos", "9" },
+ { "custom_107.frames", "1" },
+ { "custom_107.EDITOR", "RocksElements.pcx" },
+ { "custom_107.EDITOR.xpos", "15" },
+ { "custom_107.EDITOR.ypos", "13" },
+
+ { "custom_108", "RocksElements.pcx" },
+ { "custom_108.xpos", "7" },
+ { "custom_108.ypos", "9" },
+ { "custom_108.frames", "1" },
+ { "custom_108.EDITOR", "RocksElements.pcx" },
+ { "custom_108.EDITOR.xpos", "15" },
+ { "custom_108.EDITOR.ypos", "13" },
+
+ { "custom_109", "RocksElements.pcx" },
+ { "custom_109.xpos", "7" },
+ { "custom_109.ypos", "9" },
+ { "custom_109.frames", "1" },
+ { "custom_109.EDITOR", "RocksElements.pcx" },
+ { "custom_109.EDITOR.xpos", "15" },
+ { "custom_109.EDITOR.ypos", "13" },
+
+ { "custom_110", "RocksElements.pcx" },
+ { "custom_110.xpos", "7" },
+ { "custom_110.ypos", "9" },
+ { "custom_110.frames", "1" },
+ { "custom_110.EDITOR", "RocksElements.pcx" },
+ { "custom_110.EDITOR.xpos", "15" },
+ { "custom_110.EDITOR.ypos", "13" },
+
+ { "custom_111", "RocksElements.pcx" },
+ { "custom_111.xpos", "7" },
+ { "custom_111.ypos", "9" },
+ { "custom_111.frames", "1" },
+ { "custom_111.EDITOR", "RocksElements.pcx" },
+ { "custom_111.EDITOR.xpos", "15" },
+ { "custom_111.EDITOR.ypos", "13" },
+
+ { "custom_112", "RocksElements.pcx" },
+ { "custom_112.xpos", "7" },
+ { "custom_112.ypos", "9" },
+ { "custom_112.frames", "1" },
+ { "custom_112.EDITOR", "RocksElements.pcx" },
+ { "custom_112.EDITOR.xpos", "15" },
+ { "custom_112.EDITOR.ypos", "13" },
+
+ { "custom_113", "RocksElements.pcx" },
+ { "custom_113.xpos", "7" },
+ { "custom_113.ypos", "9" },
+ { "custom_113.frames", "1" },
+ { "custom_113.EDITOR", "RocksElements.pcx" },
+ { "custom_113.EDITOR.xpos", "15" },
+ { "custom_113.EDITOR.ypos", "13" },
+
+ { "custom_114", "RocksElements.pcx" },
+ { "custom_114.xpos", "7" },
+ { "custom_114.ypos", "9" },
+ { "custom_114.frames", "1" },
+ { "custom_114.EDITOR", "RocksElements.pcx" },
+ { "custom_114.EDITOR.xpos", "15" },
+ { "custom_114.EDITOR.ypos", "13" },
+
+ { "custom_115", "RocksElements.pcx" },
+ { "custom_115.xpos", "7" },
+ { "custom_115.ypos", "9" },
+ { "custom_115.frames", "1" },
+ { "custom_115.EDITOR", "RocksElements.pcx" },
+ { "custom_115.EDITOR.xpos", "15" },
+ { "custom_115.EDITOR.ypos", "13" },
+
+ { "custom_116", "RocksElements.pcx" },
+ { "custom_116.xpos", "7" },
+ { "custom_116.ypos", "9" },
+ { "custom_116.frames", "1" },
+ { "custom_116.EDITOR", "RocksElements.pcx" },
+ { "custom_116.EDITOR.xpos", "15" },
+ { "custom_116.EDITOR.ypos", "13" },
+
+ { "custom_117", "RocksElements.pcx" },
+ { "custom_117.xpos", "7" },
+ { "custom_117.ypos", "9" },
+ { "custom_117.frames", "1" },
+ { "custom_117.EDITOR", "RocksElements.pcx" },
+ { "custom_117.EDITOR.xpos", "15" },
+ { "custom_117.EDITOR.ypos", "13" },
+
+ { "custom_118", "RocksElements.pcx" },
+ { "custom_118.xpos", "7" },
+ { "custom_118.ypos", "9" },
+ { "custom_118.frames", "1" },
+ { "custom_118.EDITOR", "RocksElements.pcx" },
+ { "custom_118.EDITOR.xpos", "15" },
+ { "custom_118.EDITOR.ypos", "13" },
+
+ { "custom_119", "RocksElements.pcx" },
+ { "custom_119.xpos", "7" },
+ { "custom_119.ypos", "9" },
+ { "custom_119.frames", "1" },
+ { "custom_119.EDITOR", "RocksElements.pcx" },
+ { "custom_119.EDITOR.xpos", "15" },
+ { "custom_119.EDITOR.ypos", "13" },
+
+ { "custom_120", "RocksElements.pcx" },
+ { "custom_120.xpos", "7" },
+ { "custom_120.ypos", "9" },
+ { "custom_120.frames", "1" },
+ { "custom_120.EDITOR", "RocksElements.pcx" },
+ { "custom_120.EDITOR.xpos", "15" },
+ { "custom_120.EDITOR.ypos", "13" },
+
+ { "custom_121", "RocksElements.pcx" },
+ { "custom_121.xpos", "7" },
+ { "custom_121.ypos", "9" },
+ { "custom_121.frames", "1" },
+ { "custom_121.EDITOR", "RocksElements.pcx" },
+ { "custom_121.EDITOR.xpos", "15" },
+ { "custom_121.EDITOR.ypos", "13" },
+
+ { "custom_122", "RocksElements.pcx" },
+ { "custom_122.xpos", "7" },
+ { "custom_122.ypos", "9" },
+ { "custom_122.frames", "1" },
+ { "custom_122.EDITOR", "RocksElements.pcx" },
+ { "custom_122.EDITOR.xpos", "15" },
+ { "custom_122.EDITOR.ypos", "13" },
+
+ { "custom_123", "RocksElements.pcx" },
+ { "custom_123.xpos", "7" },
+ { "custom_123.ypos", "9" },
+ { "custom_123.frames", "1" },
+ { "custom_123.EDITOR", "RocksElements.pcx" },
+ { "custom_123.EDITOR.xpos", "15" },
+ { "custom_123.EDITOR.ypos", "13" },
+
+ { "custom_124", "RocksElements.pcx" },
+ { "custom_124.xpos", "7" },
+ { "custom_124.ypos", "9" },
+ { "custom_124.frames", "1" },
+ { "custom_124.EDITOR", "RocksElements.pcx" },
+ { "custom_124.EDITOR.xpos", "15" },
+ { "custom_124.EDITOR.ypos", "13" },
+
+ { "custom_125", "RocksElements.pcx" },
+ { "custom_125.xpos", "7" },
+ { "custom_125.ypos", "9" },
+ { "custom_125.frames", "1" },
+ { "custom_125.EDITOR", "RocksElements.pcx" },
+ { "custom_125.EDITOR.xpos", "15" },
+ { "custom_125.EDITOR.ypos", "13" },
+
+ { "custom_126", "RocksElements.pcx" },
+ { "custom_126.xpos", "7" },
+ { "custom_126.ypos", "9" },
+ { "custom_126.frames", "1" },
+ { "custom_126.EDITOR", "RocksElements.pcx" },
+ { "custom_126.EDITOR.xpos", "15" },
+ { "custom_126.EDITOR.ypos", "13" },
+
+ { "custom_127", "RocksElements.pcx" },
+ { "custom_127.xpos", "7" },
+ { "custom_127.ypos", "9" },
+ { "custom_127.frames", "1" },
+ { "custom_127.EDITOR", "RocksElements.pcx" },
+ { "custom_127.EDITOR.xpos", "15" },
+ { "custom_127.EDITOR.ypos", "13" },
+
+ { "custom_128", "RocksElements.pcx" },
+ { "custom_128.xpos", "7" },
+ { "custom_128.ypos", "9" },
+ { "custom_128.frames", "1" },
+ { "custom_128.EDITOR", "RocksElements.pcx" },
+ { "custom_128.EDITOR.xpos", "15" },
+ { "custom_128.EDITOR.ypos", "13" },
+
+
+#endif /* CONF_CUS_C */
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* (c) 1995-2002 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* conf_cus.h *
+***********************************************************/
+
+/* ----- this file was automatically generated -- do not edit by hand ----- */
+
+#ifndef CONF_CUS_H
+#define CONF_CUS_H
+
+/* values for elements configuration (custom elements) */
+
+#define EL_CUSTOM_1 (EL_CUSTOM_START + 0)
+#define EL_CUSTOM_2 (EL_CUSTOM_START + 1)
+#define EL_CUSTOM_3 (EL_CUSTOM_START + 2)
+#define EL_CUSTOM_4 (EL_CUSTOM_START + 3)
+#define EL_CUSTOM_5 (EL_CUSTOM_START + 4)
+#define EL_CUSTOM_6 (EL_CUSTOM_START + 5)
+#define EL_CUSTOM_7 (EL_CUSTOM_START + 6)
+#define EL_CUSTOM_8 (EL_CUSTOM_START + 7)
+#define EL_CUSTOM_9 (EL_CUSTOM_START + 8)
+#define EL_CUSTOM_10 (EL_CUSTOM_START + 9)
+#define EL_CUSTOM_11 (EL_CUSTOM_START + 10)
+#define EL_CUSTOM_12 (EL_CUSTOM_START + 11)
+#define EL_CUSTOM_13 (EL_CUSTOM_START + 12)
+#define EL_CUSTOM_14 (EL_CUSTOM_START + 13)
+#define EL_CUSTOM_15 (EL_CUSTOM_START + 14)
+#define EL_CUSTOM_16 (EL_CUSTOM_START + 15)
+#define EL_CUSTOM_17 (EL_CUSTOM_START + 16)
+#define EL_CUSTOM_18 (EL_CUSTOM_START + 17)
+#define EL_CUSTOM_19 (EL_CUSTOM_START + 18)
+#define EL_CUSTOM_20 (EL_CUSTOM_START + 19)
+#define EL_CUSTOM_21 (EL_CUSTOM_START + 20)
+#define EL_CUSTOM_22 (EL_CUSTOM_START + 21)
+#define EL_CUSTOM_23 (EL_CUSTOM_START + 22)
+#define EL_CUSTOM_24 (EL_CUSTOM_START + 23)
+#define EL_CUSTOM_25 (EL_CUSTOM_START + 24)
+#define EL_CUSTOM_26 (EL_CUSTOM_START + 25)
+#define EL_CUSTOM_27 (EL_CUSTOM_START + 26)
+#define EL_CUSTOM_28 (EL_CUSTOM_START + 27)
+#define EL_CUSTOM_29 (EL_CUSTOM_START + 28)
+#define EL_CUSTOM_30 (EL_CUSTOM_START + 29)
+#define EL_CUSTOM_31 (EL_CUSTOM_START + 30)
+#define EL_CUSTOM_32 (EL_CUSTOM_START + 31)
+#define EL_CUSTOM_33 (EL_CUSTOM_START + 32)
+#define EL_CUSTOM_34 (EL_CUSTOM_START + 33)
+#define EL_CUSTOM_35 (EL_CUSTOM_START + 34)
+#define EL_CUSTOM_36 (EL_CUSTOM_START + 35)
+#define EL_CUSTOM_37 (EL_CUSTOM_START + 36)
+#define EL_CUSTOM_38 (EL_CUSTOM_START + 37)
+#define EL_CUSTOM_39 (EL_CUSTOM_START + 38)
+#define EL_CUSTOM_40 (EL_CUSTOM_START + 39)
+#define EL_CUSTOM_41 (EL_CUSTOM_START + 40)
+#define EL_CUSTOM_42 (EL_CUSTOM_START + 41)
+#define EL_CUSTOM_43 (EL_CUSTOM_START + 42)
+#define EL_CUSTOM_44 (EL_CUSTOM_START + 43)
+#define EL_CUSTOM_45 (EL_CUSTOM_START + 44)
+#define EL_CUSTOM_46 (EL_CUSTOM_START + 45)
+#define EL_CUSTOM_47 (EL_CUSTOM_START + 46)
+#define EL_CUSTOM_48 (EL_CUSTOM_START + 47)
+#define EL_CUSTOM_49 (EL_CUSTOM_START + 48)
+#define EL_CUSTOM_50 (EL_CUSTOM_START + 49)
+#define EL_CUSTOM_51 (EL_CUSTOM_START + 50)
+#define EL_CUSTOM_52 (EL_CUSTOM_START + 51)
+#define EL_CUSTOM_53 (EL_CUSTOM_START + 52)
+#define EL_CUSTOM_54 (EL_CUSTOM_START + 53)
+#define EL_CUSTOM_55 (EL_CUSTOM_START + 54)
+#define EL_CUSTOM_56 (EL_CUSTOM_START + 55)
+#define EL_CUSTOM_57 (EL_CUSTOM_START + 56)
+#define EL_CUSTOM_58 (EL_CUSTOM_START + 57)
+#define EL_CUSTOM_59 (EL_CUSTOM_START + 58)
+#define EL_CUSTOM_60 (EL_CUSTOM_START + 59)
+#define EL_CUSTOM_61 (EL_CUSTOM_START + 60)
+#define EL_CUSTOM_62 (EL_CUSTOM_START + 61)
+#define EL_CUSTOM_63 (EL_CUSTOM_START + 62)
+#define EL_CUSTOM_64 (EL_CUSTOM_START + 63)
+#define EL_CUSTOM_65 (EL_CUSTOM_START + 64)
+#define EL_CUSTOM_66 (EL_CUSTOM_START + 65)
+#define EL_CUSTOM_67 (EL_CUSTOM_START + 66)
+#define EL_CUSTOM_68 (EL_CUSTOM_START + 67)
+#define EL_CUSTOM_69 (EL_CUSTOM_START + 68)
+#define EL_CUSTOM_70 (EL_CUSTOM_START + 69)
+#define EL_CUSTOM_71 (EL_CUSTOM_START + 70)
+#define EL_CUSTOM_72 (EL_CUSTOM_START + 71)
+#define EL_CUSTOM_73 (EL_CUSTOM_START + 72)
+#define EL_CUSTOM_74 (EL_CUSTOM_START + 73)
+#define EL_CUSTOM_75 (EL_CUSTOM_START + 74)
+#define EL_CUSTOM_76 (EL_CUSTOM_START + 75)
+#define EL_CUSTOM_77 (EL_CUSTOM_START + 76)
+#define EL_CUSTOM_78 (EL_CUSTOM_START + 77)
+#define EL_CUSTOM_79 (EL_CUSTOM_START + 78)
+#define EL_CUSTOM_80 (EL_CUSTOM_START + 79)
+#define EL_CUSTOM_81 (EL_CUSTOM_START + 80)
+#define EL_CUSTOM_82 (EL_CUSTOM_START + 81)
+#define EL_CUSTOM_83 (EL_CUSTOM_START + 82)
+#define EL_CUSTOM_84 (EL_CUSTOM_START + 83)
+#define EL_CUSTOM_85 (EL_CUSTOM_START + 84)
+#define EL_CUSTOM_86 (EL_CUSTOM_START + 85)
+#define EL_CUSTOM_87 (EL_CUSTOM_START + 86)
+#define EL_CUSTOM_88 (EL_CUSTOM_START + 87)
+#define EL_CUSTOM_89 (EL_CUSTOM_START + 88)
+#define EL_CUSTOM_90 (EL_CUSTOM_START + 89)
+#define EL_CUSTOM_91 (EL_CUSTOM_START + 90)
+#define EL_CUSTOM_92 (EL_CUSTOM_START + 91)
+#define EL_CUSTOM_93 (EL_CUSTOM_START + 92)
+#define EL_CUSTOM_94 (EL_CUSTOM_START + 93)
+#define EL_CUSTOM_95 (EL_CUSTOM_START + 94)
+#define EL_CUSTOM_96 (EL_CUSTOM_START + 95)
+#define EL_CUSTOM_97 (EL_CUSTOM_START + 96)
+#define EL_CUSTOM_98 (EL_CUSTOM_START + 97)
+#define EL_CUSTOM_99 (EL_CUSTOM_START + 98)
+#define EL_CUSTOM_100 (EL_CUSTOM_START + 99)
+#define EL_CUSTOM_101 (EL_CUSTOM_START + 100)
+#define EL_CUSTOM_102 (EL_CUSTOM_START + 101)
+#define EL_CUSTOM_103 (EL_CUSTOM_START + 102)
+#define EL_CUSTOM_104 (EL_CUSTOM_START + 103)
+#define EL_CUSTOM_105 (EL_CUSTOM_START + 104)
+#define EL_CUSTOM_106 (EL_CUSTOM_START + 105)
+#define EL_CUSTOM_107 (EL_CUSTOM_START + 106)
+#define EL_CUSTOM_108 (EL_CUSTOM_START + 107)
+#define EL_CUSTOM_109 (EL_CUSTOM_START + 108)
+#define EL_CUSTOM_110 (EL_CUSTOM_START + 109)
+#define EL_CUSTOM_111 (EL_CUSTOM_START + 110)
+#define EL_CUSTOM_112 (EL_CUSTOM_START + 111)
+#define EL_CUSTOM_113 (EL_CUSTOM_START + 112)
+#define EL_CUSTOM_114 (EL_CUSTOM_START + 113)
+#define EL_CUSTOM_115 (EL_CUSTOM_START + 114)
+#define EL_CUSTOM_116 (EL_CUSTOM_START + 115)
+#define EL_CUSTOM_117 (EL_CUSTOM_START + 116)
+#define EL_CUSTOM_118 (EL_CUSTOM_START + 117)
+#define EL_CUSTOM_119 (EL_CUSTOM_START + 118)
+#define EL_CUSTOM_120 (EL_CUSTOM_START + 119)
+#define EL_CUSTOM_121 (EL_CUSTOM_START + 120)
+#define EL_CUSTOM_122 (EL_CUSTOM_START + 121)
+#define EL_CUSTOM_123 (EL_CUSTOM_START + 122)
+#define EL_CUSTOM_124 (EL_CUSTOM_START + 123)
+#define EL_CUSTOM_125 (EL_CUSTOM_START + 124)
+#define EL_CUSTOM_126 (EL_CUSTOM_START + 125)
+#define EL_CUSTOM_127 (EL_CUSTOM_START + 126)
+#define EL_CUSTOM_128 (EL_CUSTOM_START + 127)
+
+#endif /* CONF_CUS_C */
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* (c) 1995-2002 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* conf_e2g.c *
+***********************************************************/
+
+/* ----- this file was automatically generated -- do not edit by hand ----- */
+
+#ifndef CONF_E2G_C
+#define CONF_E2G_C
+
+/* values for element/graphics mapping configuration (normal) */
+
+static struct
+{
+ int element;
+ int action;
+ int direction;
+ boolean crumbled;
+
+ int graphic;
+}
+element_to_graphic[] =
+{
+ {
+ EL_BD_WALL, -1, -1, FALSE,
+ IMG_BD_WALL
+ },
+ {
+ EL_BD_ROCK, -1, -1, FALSE,
+ IMG_BD_ROCK
+ },
+ {
+ EL_BD_ROCK, ACTION_MOVING, MV_BIT_LEFT, FALSE,
+ IMG_BD_ROCK_MOVING_LEFT
+ },
+ {
+ EL_BD_ROCK, ACTION_MOVING, MV_BIT_RIGHT, FALSE,
+ IMG_BD_ROCK_MOVING_RIGHT
+ },
+ {
+ EL_BD_ROCK, ACTION_PUSHING, MV_BIT_LEFT, FALSE,
+ IMG_BD_ROCK_PUSHING_LEFT
+ },
+ {
+ EL_BD_ROCK, ACTION_PUSHING, MV_BIT_RIGHT, FALSE,
+ IMG_BD_ROCK_PUSHING_RIGHT
+ },
+ {
+ EL_BD_DIAMOND, -1, -1, FALSE,
+ IMG_BD_DIAMOND
+ },
+ {
+ EL_BD_DIAMOND, ACTION_MOVING, -1, FALSE,
+ IMG_BD_DIAMOND_MOVING
+ },
+ {
+ EL_BD_DIAMOND, ACTION_FALLING, -1, FALSE,
+ IMG_BD_DIAMOND_FALLING
+ },
+ {
+ EL_BD_MAGIC_WALL, -1, -1, FALSE,
+ IMG_BD_MAGIC_WALL
+ },
+ {
+ EL_BD_MAGIC_WALL_ACTIVE, -1, -1, FALSE,
+ IMG_BD_MAGIC_WALL_ACTIVE
+ },
+ {
+ EL_BD_MAGIC_WALL, ACTION_ACTIVE, -1, FALSE,
+ IMG_BD_MAGIC_WALL_ACTIVE
+ },
+ {
+ EL_BD_MAGIC_WALL_FILLING, -1, -1, FALSE,
+ IMG_BD_MAGIC_WALL_FILLING
+ },
+ {
+ EL_BD_MAGIC_WALL, ACTION_FILLING, -1, FALSE,
+ IMG_BD_MAGIC_WALL_FILLING
+ },
+ {
+ EL_BD_MAGIC_WALL_FULL, -1, -1, FALSE,
+ IMG_BD_MAGIC_WALL_FULL
+ },
+ {
+ EL_BD_MAGIC_WALL_EMPTYING, -1, -1, FALSE,
+ IMG_BD_MAGIC_WALL_EMPTYING
+ },
+ {
+ EL_BD_MAGIC_WALL, ACTION_EMPTYING, -1, FALSE,
+ IMG_BD_MAGIC_WALL_EMPTYING
+ },
+ {
+ EL_BD_MAGIC_WALL_DEAD, -1, -1, FALSE,
+ IMG_BD_MAGIC_WALL_DEAD
+ },
+ {
+ EL_BD_AMOEBA, -1, -1, FALSE,
+ IMG_BD_AMOEBA
+ },
+ {
+ 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_BUTTERFLY, ACTION_MOVING, -1, FALSE,
+ IMG_BD_BUTTERFLY_MOVING
+ },
+ {
+ 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_BD_FIREFLY, ACTION_MOVING, -1, FALSE,
+ IMG_BD_FIREFLY_MOVING
+ },
+ {
+ EL_SP_DEFAULT, ACTION_EXPLODING, -1, FALSE,
+ IMG_SP_DEFAULT_EXPLODING
+ },
+ {
+ EL_SP_EMPTY_SPACE, -1, -1, FALSE,
+ IMG_SP_EMPTY_SPACE
+ },
+ {
+ EL_SP_ZONK, -1, -1, FALSE,
+ IMG_SP_ZONK
+ },
+ {
+ EL_SP_ZONK, ACTION_MOVING, MV_BIT_LEFT, FALSE,
+ IMG_SP_ZONK_MOVING_LEFT
+ },
+ {
+ EL_SP_ZONK, ACTION_MOVING, MV_BIT_RIGHT, FALSE,
+ IMG_SP_ZONK_MOVING_RIGHT
+ },
+ {
+ EL_SP_ZONK, ACTION_PUSHING, MV_BIT_LEFT, FALSE,
+ IMG_SP_ZONK_PUSHING_LEFT
+ },
+ {
+ EL_SP_ZONK, ACTION_PUSHING, MV_BIT_RIGHT, FALSE,
+ IMG_SP_ZONK_PUSHING_RIGHT
+ },
+ {
+ EL_SP_BASE, -1, -1, FALSE,
+ IMG_SP_BASE
+ },
+ {
+ EL_SP_MURPHY, -1, -1, FALSE,
+ IMG_SP_MURPHY
+ },
+ {
+ EL_SP_MURPHY, ACTION_MOVING, MV_BIT_LEFT, FALSE,
+ IMG_SP_MURPHY_MOVING_LEFT
+ },
+ {
+ EL_SP_MURPHY, ACTION_MOVING, MV_BIT_RIGHT, FALSE,
+ IMG_SP_MURPHY_MOVING_RIGHT
+ },
+ {
+ EL_SP_MURPHY, ACTION_DIGGING, MV_BIT_LEFT, FALSE,
+ IMG_SP_MURPHY_DIGGING_LEFT
+ },
+ {
+ EL_SP_MURPHY, ACTION_DIGGING, MV_BIT_RIGHT, FALSE,
+ IMG_SP_MURPHY_DIGGING_RIGHT
+ },
+ {
+ EL_SP_MURPHY, ACTION_COLLECTING, MV_BIT_LEFT, FALSE,
+ IMG_SP_MURPHY_COLLECTING_LEFT
+ },
+ {
+ EL_SP_MURPHY, ACTION_COLLECTING, MV_BIT_RIGHT, FALSE,
+ IMG_SP_MURPHY_COLLECTING_RIGHT
+ },
+ {
+ EL_SP_MURPHY, ACTION_PUSHING, MV_BIT_LEFT, FALSE,
+ IMG_SP_MURPHY_PUSHING_LEFT
+ },
+ {
+ EL_SP_MURPHY, ACTION_PUSHING, MV_BIT_RIGHT, FALSE,
+ IMG_SP_MURPHY_PUSHING_RIGHT
+ },
+ {
+ EL_SP_MURPHY, ACTION_SNAPPING, MV_BIT_LEFT, FALSE,
+ IMG_SP_MURPHY_SNAPPING_LEFT
+ },
+ {
+ EL_SP_MURPHY, ACTION_SNAPPING, MV_BIT_RIGHT, FALSE,
+ IMG_SP_MURPHY_SNAPPING_RIGHT
+ },
+ {
+ EL_SP_MURPHY, ACTION_SNAPPING, MV_BIT_UP, FALSE,
+ IMG_SP_MURPHY_SNAPPING_UP
+ },
+ {
+ EL_SP_MURPHY, ACTION_SNAPPING, MV_BIT_DOWN, FALSE,
+ IMG_SP_MURPHY_SNAPPING_DOWN
+ },
+ {
+ EL_SP_MURPHY_CLONE, -1, -1, FALSE,
+ IMG_SP_MURPHY_CLONE
+ },
+ {
+ EL_SP_INFOTRON, -1, -1, FALSE,
+ IMG_SP_INFOTRON
+ },
+ {
+ EL_SP_CHIP_SINGLE, -1, -1, FALSE,
+ IMG_SP_CHIP_SINGLE
+ },
+ {
+ EL_SP_CHIP_LEFT, -1, -1, FALSE,
+ IMG_SP_CHIP_LEFT
+ },
+ {
+ EL_SP_CHIP_RIGHT, -1, -1, FALSE,
+ IMG_SP_CHIP_RIGHT
+ },
+ {
+ EL_SP_CHIP_TOP, -1, -1, FALSE,
+ IMG_SP_CHIP_TOP
+ },
+ {
+ EL_SP_CHIP_BOTTOM, -1, -1, FALSE,
+ IMG_SP_CHIP_BOTTOM
+ },
+ {
+ EL_SP_HARDWARE_GRAY, -1, -1, FALSE,
+ IMG_SP_HARDWARE_GRAY
+ },
+ {
+ EL_SP_HARDWARE_GREEN, -1, -1, FALSE,
+ IMG_SP_HARDWARE_GREEN
+ },
+ {
+ EL_SP_HARDWARE_BLUE, -1, -1, FALSE,
+ IMG_SP_HARDWARE_BLUE
+ },
+ {
+ EL_SP_HARDWARE_RED, -1, -1, FALSE,
+ IMG_SP_HARDWARE_RED
+ },
+ {
+ EL_SP_HARDWARE_YELLOW, -1, -1, FALSE,
+ IMG_SP_HARDWARE_YELLOW
+ },
+ {
+ EL_SP_EXIT_CLOSED, -1, -1, FALSE,
+ IMG_SP_EXIT_CLOSED
+ },
+ {
+ EL_SP_EXIT_OPEN, -1, -1, FALSE,
+ IMG_SP_EXIT_OPEN
+ },
+ {
+ EL_SP_DISK_ORANGE, -1, -1, FALSE,
+ IMG_SP_DISK_ORANGE
+ },
+ {
+ EL_SP_DISK_YELLOW, -1, -1, FALSE,
+ IMG_SP_DISK_YELLOW
+ },
+ {
+ EL_SP_DISK_RED, -1, -1, FALSE,
+ IMG_SP_DISK_RED
+ },
+ {
+ EL_SP_DISK_RED, ACTION_COLLECTING, -1, FALSE,
+ IMG_SP_DISK_RED_COLLECTING
+ },
+ {
+ EL_SP_PORT_RIGHT, -1, -1, FALSE,
+ IMG_SP_PORT_RIGHT
+ },
+ {
+ EL_SP_PORT_DOWN, -1, -1, FALSE,
+ IMG_SP_PORT_DOWN
+ },
+ {
+ EL_SP_PORT_LEFT, -1, -1, FALSE,
+ IMG_SP_PORT_LEFT
+ },
+ {
+ EL_SP_PORT_UP, -1, -1, FALSE,
+ IMG_SP_PORT_UP
+ },
+ {
+ EL_SP_PORT_HORIZONTAL, -1, -1, FALSE,
+ IMG_SP_PORT_HORIZONTAL
+ },
+ {
+ EL_SP_PORT_VERTICAL, -1, -1, FALSE,
+ IMG_SP_PORT_VERTICAL
+ },
+ {
+ EL_SP_PORT_ANY, -1, -1, FALSE,
+ IMG_SP_PORT_ANY
+ },
+ {
+ EL_SP_GRAVITY_PORT_RIGHT, -1, -1, FALSE,
+ IMG_SP_GRAVITY_PORT_RIGHT
+ },
+ {
+ EL_SP_GRAVITY_PORT_DOWN, -1, -1, FALSE,
+ IMG_SP_GRAVITY_PORT_DOWN
+ },
+ {
+ EL_SP_GRAVITY_PORT_LEFT, -1, -1, FALSE,
+ IMG_SP_GRAVITY_PORT_LEFT
+ },
+ {
+ EL_SP_GRAVITY_PORT_UP, -1, -1, FALSE,
+ IMG_SP_GRAVITY_PORT_UP
+ },
+ {
+ EL_SP_SNIKSNAK, -1, -1, FALSE,
+ IMG_SP_SNIKSNAK
+ },
+ {
+ EL_SP_SNIKSNAK, -1, MV_BIT_LEFT, FALSE,
+ IMG_SP_SNIKSNAK_LEFT
+ },
+ {
+ EL_SP_SNIKSNAK, -1, MV_BIT_RIGHT, FALSE,
+ IMG_SP_SNIKSNAK_RIGHT
+ },
+ {
+ EL_SP_SNIKSNAK, -1, MV_BIT_UP, FALSE,
+ IMG_SP_SNIKSNAK_UP
+ },
+ {
+ EL_SP_SNIKSNAK, -1, MV_BIT_DOWN, FALSE,
+ IMG_SP_SNIKSNAK_DOWN
+ },
+ {
+ EL_SP_ELECTRON, -1, -1, FALSE,
+ IMG_SP_ELECTRON
+ },
+ {
+ EL_SP_ELECTRON, ACTION_EXPLODING, -1, FALSE,
+ IMG_SP_ELECTRON_EXPLODING
+ },
+ {
+ EL_SP_TERMINAL, -1, -1, FALSE,
+ IMG_SP_TERMINAL
+ },
+ {
+ EL_SP_TERMINAL_ACTIVE, -1, -1, FALSE,
+ IMG_SP_TERMINAL_ACTIVE
+ },
+ {
+ EL_SP_TERMINAL, ACTION_ACTIVE, -1, FALSE,
+ IMG_SP_TERMINAL_ACTIVE
+ },
+ {
+ EL_SP_BUGGY_BASE, -1, -1, FALSE,
+ IMG_SP_BUGGY_BASE
+ },
+ {
+ EL_SP_BUGGY_BASE_ACTIVATING, -1, -1, FALSE,
+ IMG_SP_BUGGY_BASE_ACTIVATING
+ },
+ {
+ EL_SP_BUGGY_BASE, ACTION_ACTIVATING, -1, FALSE,
+ IMG_SP_BUGGY_BASE_ACTIVATING
+ },
+ {
+ EL_SP_BUGGY_BASE_ACTIVE, -1, -1, FALSE,
+ IMG_SP_BUGGY_BASE_ACTIVE
+ },
+ {
+ EL_SP_BUGGY_BASE, ACTION_ACTIVE, -1, FALSE,
+ IMG_SP_BUGGY_BASE_ACTIVE
+ },
+ {
+ EL_SP_HARDWARE_BASE_1, -1, -1, FALSE,
+ IMG_SP_HARDWARE_BASE_1
+ },
+ {
+ EL_SP_HARDWARE_BASE_2, -1, -1, FALSE,
+ IMG_SP_HARDWARE_BASE_2
+ },
+ {
+ EL_SP_HARDWARE_BASE_3, -1, -1, FALSE,
+ IMG_SP_HARDWARE_BASE_3
+ },
+ {
+ EL_SP_HARDWARE_BASE_4, -1, -1, FALSE,
+ IMG_SP_HARDWARE_BASE_4
+ },
+ {
+ EL_SP_HARDWARE_BASE_5, -1, -1, FALSE,
+ IMG_SP_HARDWARE_BASE_5
+ },
+ {
+ EL_SP_HARDWARE_BASE_6, -1, -1, FALSE,
+ IMG_SP_HARDWARE_BASE_6
+ },
+ {
+ EL_SOKOBAN_OBJECT, -1, -1, FALSE,
+ IMG_SOKOBAN_OBJECT
+ },
+ {
+ EL_SOKOBAN_FIELD_EMPTY, -1, -1, FALSE,
+ IMG_SOKOBAN_FIELD_EMPTY
+ },
+ {
+ EL_SOKOBAN_FIELD_FULL, -1, -1, FALSE,
+ IMG_SOKOBAN_FIELD_FULL
+ },
+ {
+ EL_EMPTY_SPACE, -1, -1, FALSE,
+ IMG_EMPTY_SPACE
+ },
+ {
+ EL_SAND, -1, -1, FALSE,
+ IMG_SAND
+ },
+ {
+ EL_SAND, -1, -1, TRUE,
+ IMG_SAND_CRUMBLED
+ },
+ {
+ EL_SAND, ACTION_DIGGING, MV_BIT_LEFT, FALSE,
+ IMG_SAND_DIGGING_LEFT
+ },
+ {
+ EL_SAND, ACTION_DIGGING, MV_BIT_RIGHT, FALSE,
+ IMG_SAND_DIGGING_RIGHT
+ },
+ {
+ EL_SAND, ACTION_DIGGING, MV_BIT_UP, FALSE,
+ IMG_SAND_DIGGING_UP
+ },
+ {
+ EL_SAND, ACTION_DIGGING, MV_BIT_DOWN, FALSE,
+ IMG_SAND_DIGGING_DOWN
+ },
+ {
+ EL_SAND, ACTION_DIGGING, MV_BIT_LEFT, TRUE,
+ IMG_SAND_DIGGING_LEFT_CRUMBLED
+ },
+ {
+ EL_SAND, ACTION_DIGGING, MV_BIT_RIGHT, TRUE,
+ IMG_SAND_DIGGING_RIGHT_CRUMBLED
+ },
+ {
+ EL_SAND, ACTION_DIGGING, MV_BIT_UP, TRUE,
+ IMG_SAND_DIGGING_UP_CRUMBLED
+ },
+ {
+ EL_SAND, ACTION_DIGGING, MV_BIT_DOWN, TRUE,
+ IMG_SAND_DIGGING_DOWN_CRUMBLED
+ },
+ {
+ EL_WALL, -1, -1, FALSE,
+ IMG_WALL
+ },
+ {
+ EL_WALL_SLIPPERY, -1, -1, FALSE,
+ IMG_WALL_SLIPPERY
+ },
+ {
+ EL_STEELWALL, -1, -1, FALSE,
+ IMG_STEELWALL
+ },
+ {
+ EL_ROCK, -1, -1, FALSE,
+ IMG_ROCK
+ },
+ {
+ EL_ROCK, ACTION_MOVING, MV_BIT_LEFT, FALSE,
+ IMG_ROCK_MOVING_LEFT
+ },
+ {
+ EL_ROCK, ACTION_MOVING, MV_BIT_RIGHT, FALSE,
+ IMG_ROCK_MOVING_RIGHT
+ },
+ {
+ EL_ROCK, ACTION_PUSHING, MV_BIT_LEFT, FALSE,
+ IMG_ROCK_PUSHING_LEFT
+ },
+ {
+ EL_ROCK, ACTION_PUSHING, MV_BIT_RIGHT, FALSE,
+ IMG_ROCK_PUSHING_RIGHT
+ },
+ {
+ EL_EMERALD, -1, -1, FALSE,
+ IMG_EMERALD
+ },
+ {
+ EL_EMERALD, ACTION_MOVING, -1, FALSE,
+ IMG_EMERALD_MOVING
+ },
+ {
+ EL_EMERALD, ACTION_FALLING, -1, FALSE,
+ IMG_EMERALD_FALLING
+ },
+ {
+ EL_EMERALD, ACTION_COLLECTING, -1, FALSE,
+ IMG_EMERALD_COLLECTING
+ },
+ {
+ EL_DIAMOND, -1, -1, FALSE,
+ IMG_DIAMOND
+ },
+ {
+ EL_DIAMOND, ACTION_MOVING, -1, FALSE,
+ IMG_DIAMOND_MOVING
+ },
+ {
+ EL_DIAMOND, ACTION_FALLING, -1, FALSE,
+ IMG_DIAMOND_FALLING
+ },
+ {
+ EL_DIAMOND, ACTION_COLLECTING, -1, FALSE,
+ IMG_DIAMOND_COLLECTING
+ },
+ {
+ EL_BOMB, -1, -1, FALSE,
+ IMG_BOMB
+ },
+ {
+ EL_NUT, -1, -1, FALSE,
+ IMG_NUT
+ },
+ {
+ EL_NUT_BREAKING, -1, -1, FALSE,
+ IMG_NUT_BREAKING
+ },
+ {
+ EL_NUT, ACTION_BREAKING, -1, FALSE,
+ IMG_NUT_BREAKING
+ },
+ {
+ EL_DYNAMITE, -1, -1, FALSE,
+ IMG_DYNAMITE
+ },
+ {
+ EL_DYNAMITE_ACTIVE, -1, -1, FALSE,
+ IMG_DYNAMITE_ACTIVE
+ },
+ {
+ EL_DYNAMITE, ACTION_ACTIVE, -1, FALSE,
+ IMG_DYNAMITE_ACTIVE
+ },
+ {
+ EL_WALL_EMERALD, -1, -1, FALSE,
+ IMG_WALL_EMERALD
+ },
+ {
+ EL_WALL_DIAMOND, -1, -1, FALSE,
+ IMG_WALL_DIAMOND
+ },
+ {
+ EL_BUG, -1, -1, FALSE,
+ IMG_BUG
+ },
+ {
+ EL_BUG_RIGHT, -1, -1, FALSE,
+ IMG_BUG_RIGHT
+ },
+ {
+ EL_BUG, -1, MV_BIT_RIGHT, FALSE,
+ IMG_BUG_RIGHT
+ },
+ {
+ EL_BUG_UP, -1, -1, FALSE,
+ IMG_BUG_UP
+ },
+ {
+ EL_BUG, -1, MV_BIT_UP, FALSE,
+ IMG_BUG_UP
+ },
+ {
+ EL_BUG_LEFT, -1, -1, FALSE,
+ IMG_BUG_LEFT
+ },
+ {
+ EL_BUG, -1, MV_BIT_LEFT, FALSE,
+ IMG_BUG_LEFT
+ },
+ {
+ EL_BUG_DOWN, -1, -1, FALSE,
+ IMG_BUG_DOWN
+ },
+ {
+ EL_BUG, -1, MV_BIT_DOWN, FALSE,
+ IMG_BUG_DOWN
+ },
+ {
+ EL_BUG, ACTION_MOVING, MV_BIT_RIGHT, FALSE,
+ IMG_BUG_MOVING_RIGHT
+ },
+ {
+ EL_BUG, ACTION_MOVING, MV_BIT_UP, FALSE,
+ IMG_BUG_MOVING_UP
+ },
+ {
+ EL_BUG, ACTION_MOVING, MV_BIT_LEFT, FALSE,
+ IMG_BUG_MOVING_LEFT
+ },
+ {
+ EL_BUG, ACTION_MOVING, MV_BIT_DOWN, FALSE,
+ IMG_BUG_MOVING_DOWN
+ },
+ {
+ EL_SPACESHIP, -1, -1, FALSE,
+ IMG_SPACESHIP
+ },
+ {
+ EL_SPACESHIP_RIGHT, -1, -1, FALSE,
+ IMG_SPACESHIP_RIGHT
+ },
+ {
+ EL_SPACESHIP, -1, MV_BIT_RIGHT, FALSE,
+ IMG_SPACESHIP_RIGHT
+ },
+ {
+ EL_SPACESHIP_UP, -1, -1, FALSE,
+ IMG_SPACESHIP_UP
+ },
+ {
+ EL_SPACESHIP, -1, MV_BIT_UP, FALSE,
+ IMG_SPACESHIP_UP
+ },
+ {
+ EL_SPACESHIP_LEFT, -1, -1, FALSE,
+ IMG_SPACESHIP_LEFT
+ },
+ {
+ EL_SPACESHIP, -1, MV_BIT_LEFT, FALSE,
+ IMG_SPACESHIP_LEFT
+ },
+ {
+ EL_SPACESHIP_DOWN, -1, -1, FALSE,
+ IMG_SPACESHIP_DOWN
+ },
+ {
+ EL_SPACESHIP, -1, MV_BIT_DOWN, FALSE,
+ IMG_SPACESHIP_DOWN
+ },
+ {
+ EL_SPACESHIP, ACTION_MOVING, MV_BIT_RIGHT, FALSE,
+ IMG_SPACESHIP_MOVING_RIGHT
+ },
+ {
+ EL_SPACESHIP, ACTION_MOVING, MV_BIT_UP, FALSE,
+ IMG_SPACESHIP_MOVING_UP
+ },
+ {
+ EL_SPACESHIP, ACTION_MOVING, MV_BIT_LEFT, FALSE,
+ IMG_SPACESHIP_MOVING_LEFT
+ },
+ {
+ EL_SPACESHIP, ACTION_MOVING, MV_BIT_DOWN, FALSE,
+ IMG_SPACESHIP_MOVING_DOWN
+ },
+ {
+ EL_YAMYAM, -1, -1, FALSE,
+ IMG_YAMYAM
+ },
+ {
+ EL_YAMYAM, ACTION_MOVING, -1, FALSE,
+ IMG_YAMYAM_MOVING
+ },
+ {
+ EL_ROBOT, -1, -1, FALSE,
+ IMG_ROBOT
+ },
+ {
+ EL_ROBOT, ACTION_MOVING, -1, FALSE,
+ IMG_ROBOT_MOVING
+ },
+ {
+ EL_ROBOT_WHEEL, -1, -1, FALSE,
+ IMG_ROBOT_WHEEL
+ },
+ {
+ EL_ROBOT_WHEEL_ACTIVE, -1, -1, FALSE,
+ IMG_ROBOT_WHEEL_ACTIVE
+ },
+ {
+ EL_ROBOT_WHEEL, ACTION_ACTIVE, -1, FALSE,
+ IMG_ROBOT_WHEEL_ACTIVE
+ },
+ {
+ EL_MAGIC_WALL, -1, -1, FALSE,
+ IMG_MAGIC_WALL
+ },
+ {
+ EL_MAGIC_WALL_ACTIVE, -1, -1, FALSE,
+ IMG_MAGIC_WALL_ACTIVE
+ },
+ {
+ EL_MAGIC_WALL, ACTION_ACTIVE, -1, FALSE,
+ IMG_MAGIC_WALL_ACTIVE
+ },
+ {
+ EL_MAGIC_WALL_FILLING, -1, -1, FALSE,
+ IMG_MAGIC_WALL_FILLING
+ },
+ {
+ EL_MAGIC_WALL, ACTION_FILLING, -1, FALSE,
+ IMG_MAGIC_WALL_FILLING
+ },
+ {
+ EL_MAGIC_WALL_FULL, -1, -1, FALSE,
+ IMG_MAGIC_WALL_FULL
+ },
+ {
+ EL_MAGIC_WALL_EMPTYING, -1, -1, FALSE,
+ IMG_MAGIC_WALL_EMPTYING
+ },
+ {
+ EL_MAGIC_WALL, ACTION_EMPTYING, -1, FALSE,
+ IMG_MAGIC_WALL_EMPTYING
+ },
+ {
+ EL_MAGIC_WALL_DEAD, -1, -1, FALSE,
+ IMG_MAGIC_WALL_DEAD
+ },
+ {
+ EL_QUICKSAND_EMPTY, -1, -1, FALSE,
+ IMG_QUICKSAND_EMPTY
+ },
+ {
+ EL_QUICKSAND_FILLING, -1, -1, FALSE,
+ IMG_QUICKSAND_FILLING
+ },
+ {
+ EL_QUICKSAND_FULL, -1, -1, FALSE,
+ IMG_QUICKSAND_FULL
+ },
+ {
+ EL_QUICKSAND_EMPTYING, -1, -1, FALSE,
+ IMG_QUICKSAND_EMPTYING
+ },
+ {
+ EL_ACID_POOL_TOPLEFT, -1, -1, FALSE,
+ IMG_ACID_POOL_TOPLEFT
+ },
+ {
+ EL_ACID_POOL_TOPRIGHT, -1, -1, FALSE,
+ IMG_ACID_POOL_TOPRIGHT
+ },
+ {
+ EL_ACID_POOL_BOTTOMLEFT, -1, -1, FALSE,
+ IMG_ACID_POOL_BOTTOMLEFT
+ },
+ {
+ EL_ACID_POOL_BOTTOM, -1, -1, FALSE,
+ IMG_ACID_POOL_BOTTOM
+ },
+ {
+ EL_ACID_POOL_BOTTOMRIGHT, -1, -1, FALSE,
+ IMG_ACID_POOL_BOTTOMRIGHT
+ },
+ {
+ EL_ACID, -1, -1, FALSE,
+ IMG_ACID
+ },
+ {
+ EL_ACID_SPLASH_LEFT, -1, -1, FALSE,
+ IMG_ACID_SPLASH_LEFT
+ },
+ {
+ EL_ACID_SPLASH_RIGHT, -1, -1, FALSE,
+ IMG_ACID_SPLASH_RIGHT
+ },
+ {
+ EL_AMOEBA_DROP, -1, -1, FALSE,
+ IMG_AMOEBA_DROP
+ },
+ {
+ EL_AMOEBA_GROWING, -1, -1, FALSE,
+ IMG_AMOEBA_GROWING
+ },
+ {
+ EL_AMOEBA_SHRINKING, -1, -1, FALSE,
+ IMG_AMOEBA_SHRINKING
+ },
+ {
+ EL_AMOEBA_WET, -1, -1, FALSE,
+ IMG_AMOEBA_WET
+ },
+ {
+ EL_AMOEBA_DROPPING, -1, -1, FALSE,
+ IMG_AMOEBA_DROPPING
+ },
+ {
+ EL_AMOEBA_DRY, -1, -1, FALSE,
+ IMG_AMOEBA_DRY
+ },
+ {
+ EL_AMOEBA_FULL, -1, -1, FALSE,
+ IMG_AMOEBA_FULL
+ },
+ {
+ EL_AMOEBA_DEAD, -1, -1, FALSE,
+ IMG_AMOEBA_DEAD
+ },
+ {
+ EL_EM_KEY_1, -1, -1, FALSE,
+ IMG_EM_KEY_1
+ },
+ {
+ EL_EM_KEY_2, -1, -1, FALSE,
+ IMG_EM_KEY_2
+ },
+ {
+ EL_EM_KEY_3, -1, -1, FALSE,
+ IMG_EM_KEY_3
+ },
+ {
+ EL_EM_KEY_4, -1, -1, FALSE,
+ IMG_EM_KEY_4
+ },
+ {
+ EL_EM_GATE_1, -1, -1, FALSE,
+ IMG_EM_GATE_1
+ },
+ {
+ EL_EM_GATE_2, -1, -1, FALSE,
+ IMG_EM_GATE_2
+ },
+ {
+ EL_EM_GATE_3, -1, -1, FALSE,
+ IMG_EM_GATE_3
+ },
+ {
+ EL_EM_GATE_4, -1, -1, FALSE,
+ IMG_EM_GATE_4
+ },
+ {
+ EL_EM_GATE_1_GRAY, -1, -1, FALSE,
+ IMG_EM_GATE_1_GRAY
+ },
+ {
+ EL_EM_GATE_2_GRAY, -1, -1, FALSE,
+ IMG_EM_GATE_2_GRAY
+ },
+ {
+ EL_EM_GATE_3_GRAY, -1, -1, FALSE,
+ IMG_EM_GATE_3_GRAY
+ },
+ {
+ EL_EM_GATE_4_GRAY, -1, -1, FALSE,
+ IMG_EM_GATE_4_GRAY
+ },
+ {
+ EL_EXIT_CLOSED, -1, -1, FALSE,
+ IMG_EXIT_CLOSED
+ },
+ {
+ EL_EXIT_OPENING, -1, -1, FALSE,
+ IMG_EXIT_OPENING
+ },
+ {
+ EL_EXIT_OPEN, -1, -1, FALSE,
+ IMG_EXIT_OPEN
+ },
+ {
+ EL_BALLOON, -1, -1, FALSE,
+ IMG_BALLOON
+ },
+ {
+ EL_BALLOON, ACTION_MOVING, -1, FALSE,
+ IMG_BALLOON_MOVING
+ },
+ {
+ EL_BALLOON, ACTION_PUSHING, -1, FALSE,
+ IMG_BALLOON_PUSHING
+ },
+ {
+ EL_BALLOON_SWITCH_LEFT, -1, -1, FALSE,
+ IMG_BALLOON_SWITCH_LEFT
+ },
+ {
+ EL_BALLOON_SWITCH_RIGHT, -1, -1, FALSE,
+ IMG_BALLOON_SWITCH_RIGHT
+ },
+ {
+ EL_BALLOON_SWITCH_UP, -1, -1, FALSE,
+ IMG_BALLOON_SWITCH_UP
+ },
+ {
+ EL_BALLOON_SWITCH_DOWN, -1, -1, FALSE,
+ IMG_BALLOON_SWITCH_DOWN
+ },
+ {
+ EL_BALLOON_SWITCH_ANY, -1, -1, FALSE,
+ IMG_BALLOON_SWITCH_ANY
+ },
+ {
+ EL_SPRING, -1, -1, FALSE,
+ IMG_SPRING
+ },
+ {
+ EL_EMC_STEELWALL_1, -1, -1, FALSE,
+ IMG_EMC_STEELWALL_1
+ },
+ {
+ EL_EMC_STEELWALL_2, -1, -1, FALSE,
+ IMG_EMC_STEELWALL_2
+ },
+ {
+ EL_EMC_STEELWALL_3, -1, -1, FALSE,
+ IMG_EMC_STEELWALL_3
+ },
+ {
+ EL_EMC_STEELWALL_4, -1, -1, FALSE,
+ IMG_EMC_STEELWALL_4
+ },
+ {
+ EL_EMC_WALL_1, -1, -1, FALSE,
+ IMG_EMC_WALL_1
+ },
+ {
+ EL_EMC_WALL_2, -1, -1, FALSE,
+ IMG_EMC_WALL_2
+ },
+ {
+ EL_EMC_WALL_3, -1, -1, FALSE,
+ IMG_EMC_WALL_3
+ },
+ {
+ EL_EMC_WALL_4, -1, -1, FALSE,
+ IMG_EMC_WALL_4
+ },
+ {
+ EL_EMC_WALL_5, -1, -1, FALSE,
+ IMG_EMC_WALL_5
+ },
+ {
+ EL_EMC_WALL_6, -1, -1, FALSE,
+ IMG_EMC_WALL_6
+ },
+ {
+ EL_EMC_WALL_7, -1, -1, FALSE,
+ IMG_EMC_WALL_7
+ },
+ {
+ EL_EMC_WALL_8, -1, -1, FALSE,
+ IMG_EMC_WALL_8
+ },
+ {
+ EL_INVISIBLE_STEELWALL, -1, -1, FALSE,
+ IMG_INVISIBLE_STEELWALL
+ },
+ {
+ EL_INVISIBLE_STEELWALL_ACTIVE, -1, -1, FALSE,
+ IMG_INVISIBLE_STEELWALL_ACTIVE
+ },
+ {
+ EL_INVISIBLE_STEELWALL, ACTION_ACTIVE, -1, FALSE,
+ IMG_INVISIBLE_STEELWALL_ACTIVE
+ },
+ {
+ EL_INVISIBLE_WALL, -1, -1, FALSE,
+ IMG_INVISIBLE_WALL
+ },
+ {
+ EL_INVISIBLE_WALL_ACTIVE, -1, -1, FALSE,
+ IMG_INVISIBLE_WALL_ACTIVE
+ },
+ {
+ EL_INVISIBLE_WALL, ACTION_ACTIVE, -1, FALSE,
+ IMG_INVISIBLE_WALL_ACTIVE
+ },
+ {
+ EL_INVISIBLE_SAND, -1, -1, FALSE,
+ IMG_INVISIBLE_SAND
+ },
+ {
+ EL_INVISIBLE_SAND_ACTIVE, -1, -1, FALSE,
+ IMG_INVISIBLE_SAND_ACTIVE
+ },
+ {
+ EL_INVISIBLE_SAND, ACTION_ACTIVE, -1, FALSE,
+ IMG_INVISIBLE_SAND_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_1_MIDDLE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_1_MIDDLE
+ },
+ {
+ EL_CONVEYOR_BELT_1_MIDDLE_ACTIVE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_1_MIDDLE_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_1_MIDDLE, ACTION_ACTIVE, -1, FALSE,
+ IMG_CONVEYOR_BELT_1_MIDDLE_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_1_LEFT, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_1_LEFT
+ },
+ {
+ EL_CONVEYOR_BELT_1_LEFT_ACTIVE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_1_LEFT_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_1_LEFT, ACTION_ACTIVE, -1, FALSE,
+ IMG_CONVEYOR_BELT_1_LEFT_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_1_RIGHT, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_1_RIGHT
+ },
+ {
+ EL_CONVEYOR_BELT_1_RIGHT_ACTIVE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_1_RIGHT_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_1_RIGHT, ACTION_ACTIVE, -1, FALSE,
+ IMG_CONVEYOR_BELT_1_RIGHT_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_1_SWITCH_LEFT, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_1_SWITCH_LEFT
+ },
+ {
+ EL_CONVEYOR_BELT_1_SWITCH_MIDDLE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_1_SWITCH_MIDDLE
+ },
+ {
+ EL_CONVEYOR_BELT_1_SWITCH_RIGHT, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_1_SWITCH_RIGHT
+ },
+ {
+ EL_CONVEYOR_BELT_2_MIDDLE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_2_MIDDLE
+ },
+ {
+ EL_CONVEYOR_BELT_2_MIDDLE_ACTIVE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_2_MIDDLE_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_2_MIDDLE, ACTION_ACTIVE, -1, FALSE,
+ IMG_CONVEYOR_BELT_2_MIDDLE_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_2_LEFT, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_2_LEFT
+ },
+ {
+ EL_CONVEYOR_BELT_2_LEFT_ACTIVE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_2_LEFT_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_2_LEFT, ACTION_ACTIVE, -1, FALSE,
+ IMG_CONVEYOR_BELT_2_LEFT_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_2_RIGHT, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_2_RIGHT
+ },
+ {
+ EL_CONVEYOR_BELT_2_RIGHT_ACTIVE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_2_RIGHT_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_2_RIGHT, ACTION_ACTIVE, -1, FALSE,
+ IMG_CONVEYOR_BELT_2_RIGHT_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_2_SWITCH_LEFT, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_2_SWITCH_LEFT
+ },
+ {
+ EL_CONVEYOR_BELT_2_SWITCH_MIDDLE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_2_SWITCH_MIDDLE
+ },
+ {
+ EL_CONVEYOR_BELT_2_SWITCH_RIGHT, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_2_SWITCH_RIGHT
+ },
+ {
+ EL_CONVEYOR_BELT_3_MIDDLE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_3_MIDDLE
+ },
+ {
+ EL_CONVEYOR_BELT_3_MIDDLE_ACTIVE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_3_MIDDLE_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_3_MIDDLE, ACTION_ACTIVE, -1, FALSE,
+ IMG_CONVEYOR_BELT_3_MIDDLE_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_3_LEFT, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_3_LEFT
+ },
+ {
+ EL_CONVEYOR_BELT_3_LEFT_ACTIVE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_3_LEFT_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_3_LEFT, ACTION_ACTIVE, -1, FALSE,
+ IMG_CONVEYOR_BELT_3_LEFT_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_3_RIGHT, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_3_RIGHT
+ },
+ {
+ EL_CONVEYOR_BELT_3_RIGHT_ACTIVE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_3_RIGHT_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_3_RIGHT, ACTION_ACTIVE, -1, FALSE,
+ IMG_CONVEYOR_BELT_3_RIGHT_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_3_SWITCH_LEFT, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_3_SWITCH_LEFT
+ },
+ {
+ EL_CONVEYOR_BELT_3_SWITCH_MIDDLE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_3_SWITCH_MIDDLE
+ },
+ {
+ EL_CONVEYOR_BELT_3_SWITCH_RIGHT, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_3_SWITCH_RIGHT
+ },
+ {
+ EL_CONVEYOR_BELT_4_MIDDLE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_4_MIDDLE
+ },
+ {
+ EL_CONVEYOR_BELT_4_MIDDLE_ACTIVE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_4_MIDDLE_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_4_MIDDLE, ACTION_ACTIVE, -1, FALSE,
+ IMG_CONVEYOR_BELT_4_MIDDLE_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_4_LEFT, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_4_LEFT
+ },
+ {
+ EL_CONVEYOR_BELT_4_LEFT_ACTIVE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_4_LEFT_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_4_LEFT, ACTION_ACTIVE, -1, FALSE,
+ IMG_CONVEYOR_BELT_4_LEFT_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_4_RIGHT, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_4_RIGHT
+ },
+ {
+ EL_CONVEYOR_BELT_4_RIGHT_ACTIVE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_4_RIGHT_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_4_RIGHT, ACTION_ACTIVE, -1, FALSE,
+ IMG_CONVEYOR_BELT_4_RIGHT_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_4_SWITCH_LEFT, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_4_SWITCH_LEFT
+ },
+ {
+ EL_CONVEYOR_BELT_4_SWITCH_MIDDLE, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_4_SWITCH_MIDDLE
+ },
+ {
+ EL_CONVEYOR_BELT_4_SWITCH_RIGHT, -1, -1, FALSE,
+ IMG_CONVEYOR_BELT_4_SWITCH_RIGHT
+ },
+ {
+ EL_SWITCHGATE_SWITCH_UP, -1, -1, FALSE,
+ IMG_SWITCHGATE_SWITCH_UP
+ },
+ {
+ EL_SWITCHGATE_SWITCH_DOWN, -1, -1, FALSE,
+ IMG_SWITCHGATE_SWITCH_DOWN
+ },
+ {
+ EL_LIGHT_SWITCH, -1, -1, FALSE,
+ IMG_LIGHT_SWITCH
+ },
+ {
+ EL_LIGHT_SWITCH_ACTIVE, -1, -1, FALSE,
+ IMG_LIGHT_SWITCH_ACTIVE
+ },
+ {
+ EL_LIGHT_SWITCH, ACTION_ACTIVE, -1, FALSE,
+ IMG_LIGHT_SWITCH_ACTIVE
+ },
+ {
+ EL_TIMEGATE_SWITCH, -1, -1, FALSE,
+ IMG_TIMEGATE_SWITCH
+ },
+ {
+ EL_TIMEGATE_SWITCH_ACTIVE, -1, -1, FALSE,
+ IMG_TIMEGATE_SWITCH_ACTIVE
+ },
+ {
+ EL_TIMEGATE_SWITCH, ACTION_ACTIVE, -1, FALSE,
+ IMG_TIMEGATE_SWITCH_ACTIVE
+ },
+ {
+ EL_ENVELOPE, -1, -1, FALSE,
+ IMG_ENVELOPE
+ },
+ {
+ EL_SIGN_EXCLAMATION, -1, -1, FALSE,
+ IMG_SIGN_EXCLAMATION
+ },
+ {
+ EL_SIGN_STOP, -1, -1, FALSE,
+ IMG_SIGN_STOP
+ },
+ {
+ EL_LANDMINE, -1, -1, FALSE,
+ IMG_LANDMINE
+ },
+ {
+ EL_STEELWALL_SLIPPERY, -1, -1, FALSE,
+ IMG_STEELWALL_SLIPPERY
+ },
+ {
+ EL_EXTRA_TIME, -1, -1, FALSE,
+ IMG_EXTRA_TIME
+ },
+ {
+ EL_SHIELD_NORMAL, -1, -1, FALSE,
+ IMG_SHIELD_NORMAL
+ },
+ {
+ EL_SHIELD_NORMAL_ACTIVE, -1, -1, FALSE,
+ IMG_SHIELD_NORMAL_ACTIVE
+ },
+ {
+ EL_SHIELD_NORMAL, ACTION_ACTIVE, -1, FALSE,
+ IMG_SHIELD_NORMAL_ACTIVE
+ },
+ {
+ EL_SHIELD_DEADLY, -1, -1, FALSE,
+ IMG_SHIELD_DEADLY
+ },
+ {
+ EL_SHIELD_DEADLY_ACTIVE, -1, -1, FALSE,
+ IMG_SHIELD_DEADLY_ACTIVE
+ },
+ {
+ EL_SHIELD_DEADLY, ACTION_ACTIVE, -1, FALSE,
+ IMG_SHIELD_DEADLY_ACTIVE
+ },
+ {
+ EL_SWITCHGATE_CLOSED, -1, -1, FALSE,
+ IMG_SWITCHGATE_CLOSED
+ },
+ {
+ EL_SWITCHGATE_OPENING, -1, -1, FALSE,
+ IMG_SWITCHGATE_OPENING
+ },
+ {
+ EL_SWITCHGATE_OPEN, -1, -1, FALSE,
+ IMG_SWITCHGATE_OPEN
+ },
+ {
+ EL_SWITCHGATE_CLOSING, -1, -1, FALSE,
+ IMG_SWITCHGATE_CLOSING
+ },
+ {
+ EL_TIMEGATE_CLOSED, -1, -1, FALSE,
+ IMG_TIMEGATE_CLOSED
+ },
+ {
+ EL_TIMEGATE_OPENING, -1, -1, FALSE,
+ IMG_TIMEGATE_OPENING
+ },
+ {
+ EL_TIMEGATE_OPEN, -1, -1, FALSE,
+ IMG_TIMEGATE_OPEN
+ },
+ {
+ EL_TIMEGATE_CLOSING, -1, -1, FALSE,
+ IMG_TIMEGATE_CLOSING
+ },
+ {
+ EL_PEARL, -1, -1, FALSE,
+ IMG_PEARL
+ },
+ {
+ EL_PEARL_BREAKING, -1, -1, FALSE,
+ IMG_PEARL_BREAKING
+ },
+ {
+ EL_PEARL, ACTION_BREAKING, -1, FALSE,
+ IMG_PEARL_BREAKING
+ },
+ {
+ EL_CRYSTAL, -1, -1, FALSE,
+ IMG_CRYSTAL
+ },
+ {
+ EL_WALL_PEARL, -1, -1, FALSE,
+ IMG_WALL_PEARL
+ },
+ {
+ EL_WALL_CRYSTAL, -1, -1, FALSE,
+ IMG_WALL_CRYSTAL
+ },
+ {
+ EL_TUBE_RIGHT_DOWN, -1, -1, FALSE,
+ IMG_TUBE_RIGHT_DOWN
+ },
+ {
+ EL_TUBE_HORIZONTAL_DOWN, -1, -1, FALSE,
+ IMG_TUBE_HORIZONTAL_DOWN
+ },
+ {
+ EL_TUBE_LEFT_DOWN, -1, -1, FALSE,
+ IMG_TUBE_LEFT_DOWN
+ },
+ {
+ EL_TUBE_HORIZONTAL, -1, -1, FALSE,
+ IMG_TUBE_HORIZONTAL
+ },
+ {
+ EL_TUBE_VERTICAL_RIGHT, -1, -1, FALSE,
+ IMG_TUBE_VERTICAL_RIGHT
+ },
+ {
+ EL_TUBE_ANY, -1, -1, FALSE,
+ IMG_TUBE_ANY
+ },
+ {
+ EL_TUBE_VERTICAL_LEFT, -1, -1, FALSE,
+ IMG_TUBE_VERTICAL_LEFT
+ },
+ {
+ EL_TUBE_VERTICAL, -1, -1, FALSE,
+ IMG_TUBE_VERTICAL
+ },
+ {
+ EL_TUBE_RIGHT_UP, -1, -1, FALSE,
+ IMG_TUBE_RIGHT_UP
+ },
+ {
+ EL_TUBE_HORIZONTAL_UP, -1, -1, FALSE,
+ IMG_TUBE_HORIZONTAL_UP
+ },
+ {
+ EL_TUBE_LEFT_UP, -1, -1, FALSE,
+ IMG_TUBE_LEFT_UP
+ },
+ {
+ EL_TRAP, -1, -1, FALSE,
+ IMG_TRAP
+ },
+ {
+ EL_TRAP_ACTIVE, -1, -1, FALSE,
+ IMG_TRAP_ACTIVE
+ },
+ {
+ EL_TRAP, ACTION_ACTIVE, -1, FALSE,
+ IMG_TRAP_ACTIVE
+ },
+ {
+ EL_DX_SUPABOMB, -1, -1, FALSE,
+ IMG_DX_SUPABOMB
+ },
+ {
+ EL_KEY_1, -1, -1, FALSE,
+ IMG_KEY_1
+ },
+ {
+ EL_KEY_2, -1, -1, FALSE,
+ IMG_KEY_2
+ },
+ {
+ EL_KEY_3, -1, -1, FALSE,
+ IMG_KEY_3
+ },
+ {
+ EL_KEY_4, -1, -1, FALSE,
+ IMG_KEY_4
+ },
+ {
+ EL_GATE_1, -1, -1, FALSE,
+ IMG_GATE_1
+ },
+ {
+ EL_GATE_2, -1, -1, FALSE,
+ IMG_GATE_2
+ },
+ {
+ EL_GATE_3, -1, -1, FALSE,
+ IMG_GATE_3
+ },
+ {
+ EL_GATE_4, -1, -1, FALSE,
+ IMG_GATE_4
+ },
+ {
+ EL_GATE_1_GRAY, -1, -1, FALSE,
+ IMG_GATE_1_GRAY
+ },
+ {
+ EL_GATE_2_GRAY, -1, -1, FALSE,
+ IMG_GATE_2_GRAY
+ },
+ {
+ EL_GATE_3_GRAY, -1, -1, FALSE,
+ IMG_GATE_3_GRAY
+ },
+ {
+ EL_GATE_4_GRAY, -1, -1, FALSE,
+ IMG_GATE_4_GRAY
+ },
+ {
+ EL_GAME_OF_LIFE, -1, -1, FALSE,
+ IMG_GAME_OF_LIFE
+ },
+ {
+ EL_BIOMAZE, -1, -1, FALSE,
+ IMG_BIOMAZE
+ },
+ {
+ EL_PACMAN, -1, -1, FALSE,
+ IMG_PACMAN
+ },
+ {
+ EL_PACMAN_RIGHT, -1, -1, FALSE,
+ IMG_PACMAN_RIGHT
+ },
+ {
+ EL_PACMAN, -1, MV_BIT_RIGHT, FALSE,
+ IMG_PACMAN_RIGHT
+ },
+ {
+ EL_PACMAN_UP, -1, -1, FALSE,
+ IMG_PACMAN_UP
+ },
+ {
+ EL_PACMAN, -1, MV_BIT_UP, FALSE,
+ IMG_PACMAN_UP
+ },
+ {
+ EL_PACMAN_LEFT, -1, -1, FALSE,
+ IMG_PACMAN_LEFT
+ },
+ {
+ EL_PACMAN, -1, MV_BIT_LEFT, FALSE,
+ IMG_PACMAN_LEFT
+ },
+ {
+ EL_PACMAN_DOWN, -1, -1, FALSE,
+ IMG_PACMAN_DOWN
+ },
+ {
+ EL_PACMAN, -1, MV_BIT_DOWN, FALSE,
+ IMG_PACMAN_DOWN
+ },
+ {
+ EL_PACMAN, ACTION_MOVING, MV_BIT_RIGHT, FALSE,
+ IMG_PACMAN_MOVING_RIGHT
+ },
+ {
+ EL_PACMAN, ACTION_MOVING, MV_BIT_UP, FALSE,
+ IMG_PACMAN_MOVING_UP
+ },
+ {
+ EL_PACMAN, ACTION_MOVING, MV_BIT_LEFT, FALSE,
+ IMG_PACMAN_MOVING_LEFT
+ },
+ {
+ EL_PACMAN, ACTION_MOVING, MV_BIT_DOWN, FALSE,
+ IMG_PACMAN_MOVING_DOWN
+ },
+ {
+ EL_LAMP, -1, -1, FALSE,
+ IMG_LAMP
+ },
+ {
+ EL_LAMP_ACTIVE, -1, -1, FALSE,
+ IMG_LAMP_ACTIVE
+ },
+ {
+ EL_LAMP, ACTION_ACTIVE, -1, FALSE,
+ IMG_LAMP_ACTIVE
+ },
+ {
+ EL_TIME_ORB_FULL, -1, -1, FALSE,
+ IMG_TIME_ORB_FULL
+ },
+ {
+ EL_TIME_ORB_EMPTY, -1, -1, FALSE,
+ IMG_TIME_ORB_EMPTY
+ },
+ {
+ EL_EMERALD_YELLOW, -1, -1, FALSE,
+ IMG_EMERALD_YELLOW
+ },
+ {
+ EL_EMERALD_YELLOW, ACTION_MOVING, -1, FALSE,
+ IMG_EMERALD_YELLOW_MOVING
+ },
+ {
+ EL_EMERALD_YELLOW, ACTION_FALLING, -1, FALSE,
+ IMG_EMERALD_YELLOW_FALLING
+ },
+ {
+ EL_EMERALD_RED, -1, -1, FALSE,
+ IMG_EMERALD_RED
+ },
+ {
+ EL_EMERALD_RED, ACTION_MOVING, -1, FALSE,
+ IMG_EMERALD_RED_MOVING
+ },
+ {
+ EL_EMERALD_RED, ACTION_FALLING, -1, FALSE,
+ IMG_EMERALD_RED_FALLING
+ },
+ {
+ EL_EMERALD_PURPLE, -1, -1, FALSE,
+ IMG_EMERALD_PURPLE
+ },
+ {
+ EL_EMERALD_PURPLE, ACTION_MOVING, -1, FALSE,
+ IMG_EMERALD_PURPLE_MOVING
+ },
+ {
+ EL_EMERALD_PURPLE, ACTION_FALLING, -1, FALSE,
+ IMG_EMERALD_PURPLE_FALLING
+ },
+ {
+ EL_WALL_EMERALD_YELLOW, -1, -1, FALSE,
+ IMG_WALL_EMERALD_YELLOW
+ },
+ {
+ EL_WALL_EMERALD_RED, -1, -1, FALSE,
+ IMG_WALL_EMERALD_RED
+ },
+ {
+ EL_WALL_EMERALD_PURPLE, -1, -1, FALSE,
+ IMG_WALL_EMERALD_PURPLE
+ },
+ {
+ EL_WALL_BD_DIAMOND, -1, -1, FALSE,
+ IMG_WALL_BD_DIAMOND
+ },
+ {
+ EL_EXPANDABLE_WALL, -1, -1, FALSE,
+ IMG_EXPANDABLE_WALL
+ },
+ {
+ EL_EXPANDABLE_WALL_HORIZONTAL, -1, -1, FALSE,
+ IMG_EXPANDABLE_WALL_HORIZONTAL
+ },
+ {
+ EL_EXPANDABLE_WALL_VERTICAL, -1, -1, FALSE,
+ IMG_EXPANDABLE_WALL_VERTICAL
+ },
+ {
+ EL_EXPANDABLE_WALL_ANY, -1, -1, FALSE,
+ IMG_EXPANDABLE_WALL_ANY
+ },
+ {
+ EL_EXPANDABLE_WALL, ACTION_GROWING, MV_BIT_LEFT, FALSE,
+ IMG_EXPANDABLE_WALL_GROWING_LEFT
+ },
+ {
+ EL_EXPANDABLE_WALL_GROWING, -1, MV_BIT_LEFT, FALSE,
+ IMG_EXPANDABLE_WALL_GROWING_LEFT
+ },
+ {
+ EL_EXPANDABLE_WALL, ACTION_GROWING, MV_BIT_RIGHT, FALSE,
+ IMG_EXPANDABLE_WALL_GROWING_RIGHT
+ },
+ {
+ EL_EXPANDABLE_WALL_GROWING, -1, MV_BIT_RIGHT, FALSE,
+ IMG_EXPANDABLE_WALL_GROWING_RIGHT
+ },
+ {
+ EL_EXPANDABLE_WALL, ACTION_GROWING, MV_BIT_UP, FALSE,
+ IMG_EXPANDABLE_WALL_GROWING_UP
+ },
+ {
+ EL_EXPANDABLE_WALL_GROWING, -1, MV_BIT_UP, FALSE,
+ IMG_EXPANDABLE_WALL_GROWING_UP
+ },
+ {
+ EL_EXPANDABLE_WALL, ACTION_GROWING, MV_BIT_DOWN, FALSE,
+ IMG_EXPANDABLE_WALL_GROWING_DOWN
+ },
+ {
+ EL_EXPANDABLE_WALL_GROWING, -1, MV_BIT_DOWN, FALSE,
+ IMG_EXPANDABLE_WALL_GROWING_DOWN
+ },
+ {
+ EL_BLACK_ORB, -1, -1, FALSE,
+ IMG_BLACK_ORB
+ },
+ {
+ EL_SPEED_PILL, -1, -1, FALSE,
+ IMG_SPEED_PILL
+ },
+ {
+ EL_DARK_YAMYAM, -1, -1, FALSE,
+ IMG_DARK_YAMYAM
+ },
+ {
+ EL_DYNABOMB, -1, -1, FALSE,
+ IMG_DYNABOMB
+ },
+ {
+ EL_DYNABOMB_ACTIVE, -1, -1, FALSE,
+ IMG_DYNABOMB_ACTIVE
+ },
+ {
+ EL_DYNABOMB, ACTION_ACTIVE, -1, FALSE,
+ IMG_DYNABOMB_ACTIVE
+ },
+ {
+ EL_DYNABOMB_PLAYER_1, -1, -1, FALSE,
+ IMG_DYNABOMB_PLAYER_1
+ },
+ {
+ EL_DYNABOMB_PLAYER_1_ACTIVE, -1, -1, FALSE,
+ IMG_DYNABOMB_PLAYER_1_ACTIVE
+ },
+ {
+ EL_DYNABOMB_PLAYER_1, ACTION_ACTIVE, -1, FALSE,
+ IMG_DYNABOMB_PLAYER_1_ACTIVE
+ },
+ {
+ EL_DYNABOMB_PLAYER_2, -1, -1, FALSE,
+ IMG_DYNABOMB_PLAYER_2
+ },
+ {
+ EL_DYNABOMB_PLAYER_2_ACTIVE, -1, -1, FALSE,
+ IMG_DYNABOMB_PLAYER_2_ACTIVE
+ },
+ {
+ EL_DYNABOMB_PLAYER_2, ACTION_ACTIVE, -1, FALSE,
+ IMG_DYNABOMB_PLAYER_2_ACTIVE
+ },
+ {
+ EL_DYNABOMB_PLAYER_3, -1, -1, FALSE,
+ IMG_DYNABOMB_PLAYER_3
+ },
+ {
+ EL_DYNABOMB_PLAYER_3_ACTIVE, -1, -1, FALSE,
+ IMG_DYNABOMB_PLAYER_3_ACTIVE
+ },
+ {
+ EL_DYNABOMB_PLAYER_3, ACTION_ACTIVE, -1, FALSE,
+ IMG_DYNABOMB_PLAYER_3_ACTIVE
+ },
+ {
+ EL_DYNABOMB_PLAYER_4, -1, -1, FALSE,
+ IMG_DYNABOMB_PLAYER_4
+ },
+ {
+ EL_DYNABOMB_PLAYER_4_ACTIVE, -1, -1, FALSE,
+ IMG_DYNABOMB_PLAYER_4_ACTIVE
+ },
+ {
+ EL_DYNABOMB_PLAYER_4, ACTION_ACTIVE, -1, FALSE,
+ IMG_DYNABOMB_PLAYER_4_ACTIVE
+ },
+ {
+ EL_DYNABOMB_INCREASE_NUMBER, -1, -1, FALSE,
+ IMG_DYNABOMB_INCREASE_NUMBER
+ },
+ {
+ EL_DYNABOMB_INCREASE_SIZE, -1, -1, FALSE,
+ IMG_DYNABOMB_INCREASE_SIZE
+ },
+ {
+ EL_DYNABOMB_INCREASE_POWER, -1, -1, FALSE,
+ IMG_DYNABOMB_INCREASE_POWER
+ },
+ {
+ EL_PIG, -1, -1, FALSE,
+ IMG_PIG
+ },
+ {
+ EL_PIG, -1, MV_BIT_DOWN, FALSE,
+ IMG_PIG_DOWN
+ },
+ {
+ EL_PIG, -1, MV_BIT_UP, FALSE,
+ IMG_PIG_UP
+ },
+ {
+ EL_PIG, -1, MV_BIT_LEFT, FALSE,
+ IMG_PIG_LEFT
+ },
+ {
+ EL_PIG, -1, MV_BIT_RIGHT, FALSE,
+ IMG_PIG_RIGHT
+ },
+ {
+ EL_PIG, ACTION_MOVING, MV_BIT_DOWN, FALSE,
+ IMG_PIG_MOVING_DOWN
+ },
+ {
+ EL_PIG, ACTION_MOVING, MV_BIT_UP, FALSE,
+ IMG_PIG_MOVING_UP
+ },
+ {
+ EL_PIG, ACTION_MOVING, MV_BIT_LEFT, FALSE,
+ IMG_PIG_MOVING_LEFT
+ },
+ {
+ EL_PIG, ACTION_MOVING, MV_BIT_RIGHT, FALSE,
+ IMG_PIG_MOVING_RIGHT
+ },
+ {
+ EL_PIG, ACTION_DIGGING, MV_BIT_DOWN, FALSE,
+ IMG_PIG_DIGGING_DOWN
+ },
+ {
+ EL_PIG, ACTION_DIGGING, MV_BIT_UP, FALSE,
+ IMG_PIG_DIGGING_UP
+ },
+ {
+ EL_PIG, ACTION_DIGGING, MV_BIT_LEFT, FALSE,
+ IMG_PIG_DIGGING_LEFT
+ },
+ {
+ EL_PIG, ACTION_DIGGING, MV_BIT_RIGHT, FALSE,
+ IMG_PIG_DIGGING_RIGHT
+ },
+ {
+ EL_DRAGON, -1, -1, FALSE,
+ IMG_DRAGON
+ },
+ {
+ EL_DRAGON, -1, MV_BIT_DOWN, FALSE,
+ IMG_DRAGON_DOWN
+ },
+ {
+ EL_DRAGON, -1, MV_BIT_UP, FALSE,
+ IMG_DRAGON_UP
+ },
+ {
+ EL_DRAGON, -1, MV_BIT_LEFT, FALSE,
+ IMG_DRAGON_LEFT
+ },
+ {
+ EL_DRAGON, -1, MV_BIT_RIGHT, FALSE,
+ IMG_DRAGON_RIGHT
+ },
+ {
+ EL_DRAGON, ACTION_MOVING, MV_BIT_DOWN, FALSE,
+ IMG_DRAGON_MOVING_DOWN
+ },
+ {
+ EL_DRAGON, ACTION_MOVING, MV_BIT_UP, FALSE,
+ IMG_DRAGON_MOVING_UP
+ },
+ {
+ EL_DRAGON, ACTION_MOVING, MV_BIT_LEFT, FALSE,
+ IMG_DRAGON_MOVING_LEFT
+ },
+ {
+ EL_DRAGON, ACTION_MOVING, MV_BIT_RIGHT, FALSE,
+ IMG_DRAGON_MOVING_RIGHT
+ },
+ {
+ EL_DRAGON, ACTION_ATTACKING, MV_BIT_DOWN, FALSE,
+ IMG_DRAGON_ATTACKING_DOWN
+ },
+ {
+ EL_DRAGON, ACTION_ATTACKING, MV_BIT_UP, FALSE,
+ IMG_DRAGON_ATTACKING_UP
+ },
+ {
+ EL_DRAGON, ACTION_ATTACKING, MV_BIT_LEFT, FALSE,
+ IMG_DRAGON_ATTACKING_LEFT
+ },
+ {
+ EL_DRAGON, ACTION_ATTACKING, MV_BIT_RIGHT, FALSE,
+ IMG_DRAGON_ATTACKING_RIGHT
+ },
+ {
+ EL_MOLE, -1, -1, FALSE,
+ IMG_MOLE
+ },
+ {
+ EL_MOLE_DOWN, -1, -1, FALSE,
+ IMG_MOLE_DOWN
+ },
+ {
+ EL_MOLE, -1, MV_BIT_DOWN, FALSE,
+ IMG_MOLE_DOWN
+ },
+ {
+ EL_MOLE_UP, -1, -1, FALSE,
+ IMG_MOLE_UP
+ },
+ {
+ EL_MOLE, -1, MV_BIT_UP, FALSE,
+ IMG_MOLE_UP
+ },
+ {
+ EL_MOLE_LEFT, -1, -1, FALSE,
+ IMG_MOLE_LEFT
+ },
+ {
+ EL_MOLE, -1, MV_BIT_LEFT, FALSE,
+ IMG_MOLE_LEFT
+ },
+ {
+ EL_MOLE_RIGHT, -1, -1, FALSE,
+ IMG_MOLE_RIGHT
+ },
+ {
+ EL_MOLE, -1, MV_BIT_RIGHT, FALSE,
+ IMG_MOLE_RIGHT
+ },
+ {
+ EL_MOLE, ACTION_MOVING, MV_BIT_DOWN, FALSE,
+ IMG_MOLE_MOVING_DOWN
+ },
+ {
+ EL_MOLE, ACTION_MOVING, MV_BIT_UP, FALSE,
+ IMG_MOLE_MOVING_UP
+ },
+ {
+ EL_MOLE, ACTION_MOVING, MV_BIT_LEFT, FALSE,
+ IMG_MOLE_MOVING_LEFT
+ },
+ {
+ EL_MOLE, ACTION_MOVING, MV_BIT_RIGHT, FALSE,
+ IMG_MOLE_MOVING_RIGHT
+ },
+ {
+ EL_MOLE, ACTION_DIGGING, MV_BIT_DOWN, FALSE,
+ IMG_MOLE_DIGGING_DOWN
+ },
+ {
+ EL_MOLE, ACTION_DIGGING, MV_BIT_UP, FALSE,
+ IMG_MOLE_DIGGING_UP
+ },
+ {
+ EL_MOLE, ACTION_DIGGING, MV_BIT_LEFT, FALSE,
+ IMG_MOLE_DIGGING_LEFT
+ },
+ {
+ EL_MOLE, ACTION_DIGGING, MV_BIT_RIGHT, FALSE,
+ IMG_MOLE_DIGGING_RIGHT
+ },
+ {
+ EL_PENGUIN, -1, -1, FALSE,
+ IMG_PENGUIN
+ },
+ {
+ EL_PENGUIN, -1, MV_BIT_DOWN, FALSE,
+ IMG_PENGUIN_DOWN
+ },
+ {
+ EL_PENGUIN, -1, MV_BIT_UP, FALSE,
+ IMG_PENGUIN_UP
+ },
+ {
+ EL_PENGUIN, -1, MV_BIT_LEFT, FALSE,
+ IMG_PENGUIN_LEFT
+ },
+ {
+ EL_PENGUIN, -1, MV_BIT_RIGHT, FALSE,
+ IMG_PENGUIN_RIGHT
+ },
+ {
+ EL_PENGUIN, ACTION_MOVING, MV_BIT_DOWN, FALSE,
+ IMG_PENGUIN_MOVING_DOWN
+ },
+ {
+ EL_PENGUIN, ACTION_MOVING, MV_BIT_UP, FALSE,
+ IMG_PENGUIN_MOVING_UP
+ },
+ {
+ EL_PENGUIN, ACTION_MOVING, MV_BIT_LEFT, FALSE,
+ IMG_PENGUIN_MOVING_LEFT
+ },
+ {
+ EL_PENGUIN, ACTION_MOVING, MV_BIT_RIGHT, FALSE,
+ IMG_PENGUIN_MOVING_RIGHT
+ },
+ {
+ EL_SATELLITE, -1, -1, FALSE,
+ IMG_SATELLITE
+ },
+ {
+ EL_STONEBLOCK, -1, -1, FALSE,
+ IMG_STONEBLOCK
+ },
+ {
+ EL_PLAYER_1, -1, -1, FALSE,
+ IMG_PLAYER_1
+ },
+ {
+ EL_PLAYER_1, -1, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_1_DOWN
+ },
+ {
+ EL_PLAYER_1, -1, MV_BIT_UP, FALSE,
+ IMG_PLAYER_1_UP
+ },
+ {
+ EL_PLAYER_1, -1, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_1_LEFT
+ },
+ {
+ EL_PLAYER_1, -1, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_1_RIGHT
+ },
+ {
+ EL_PLAYER_1, ACTION_MOVING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_1_MOVING_DOWN
+ },
+ {
+ EL_PLAYER_1, ACTION_MOVING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_1_MOVING_UP
+ },
+ {
+ EL_PLAYER_1, ACTION_MOVING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_1_MOVING_LEFT
+ },
+ {
+ EL_PLAYER_1, ACTION_MOVING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_1_MOVING_RIGHT
+ },
+ {
+ EL_PLAYER_1, ACTION_DIGGING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_1_DIGGING_DOWN
+ },
+ {
+ EL_PLAYER_1, ACTION_DIGGING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_1_DIGGING_UP
+ },
+ {
+ EL_PLAYER_1, ACTION_DIGGING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_1_DIGGING_LEFT
+ },
+ {
+ EL_PLAYER_1, ACTION_DIGGING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_1_DIGGING_RIGHT
+ },
+ {
+ EL_PLAYER_1, ACTION_COLLECTING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_1_COLLECTING_DOWN
+ },
+ {
+ EL_PLAYER_1, ACTION_COLLECTING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_1_COLLECTING_UP
+ },
+ {
+ EL_PLAYER_1, ACTION_COLLECTING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_1_COLLECTING_LEFT
+ },
+ {
+ EL_PLAYER_1, ACTION_COLLECTING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_1_COLLECTING_RIGHT
+ },
+ {
+ EL_PLAYER_1, ACTION_PUSHING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_1_PUSHING_DOWN
+ },
+ {
+ EL_PLAYER_1, ACTION_PUSHING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_1_PUSHING_UP
+ },
+ {
+ EL_PLAYER_1, ACTION_PUSHING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_1_PUSHING_LEFT
+ },
+ {
+ EL_PLAYER_1, ACTION_PUSHING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_1_PUSHING_RIGHT
+ },
+ {
+ EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_1_SNAPPING_DOWN
+ },
+ {
+ EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_1_SNAPPING_UP
+ },
+ {
+ EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_1_SNAPPING_LEFT
+ },
+ {
+ EL_PLAYER_1, ACTION_SNAPPING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_1_SNAPPING_RIGHT
+ },
+ {
+ EL_PLAYER_2, -1, -1, FALSE,
+ IMG_PLAYER_2
+ },
+ {
+ EL_PLAYER_2, -1, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_2_DOWN
+ },
+ {
+ EL_PLAYER_2, -1, MV_BIT_UP, FALSE,
+ IMG_PLAYER_2_UP
+ },
+ {
+ EL_PLAYER_2, -1, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_2_LEFT
+ },
+ {
+ EL_PLAYER_2, -1, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_2_RIGHT
+ },
+ {
+ EL_PLAYER_2, ACTION_MOVING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_2_MOVING_DOWN
+ },
+ {
+ EL_PLAYER_2, ACTION_MOVING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_2_MOVING_UP
+ },
+ {
+ EL_PLAYER_2, ACTION_MOVING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_2_MOVING_LEFT
+ },
+ {
+ EL_PLAYER_2, ACTION_MOVING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_2_MOVING_RIGHT
+ },
+ {
+ EL_PLAYER_2, ACTION_DIGGING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_2_DIGGING_DOWN
+ },
+ {
+ EL_PLAYER_2, ACTION_DIGGING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_2_DIGGING_UP
+ },
+ {
+ EL_PLAYER_2, ACTION_DIGGING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_2_DIGGING_LEFT
+ },
+ {
+ EL_PLAYER_2, ACTION_DIGGING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_2_DIGGING_RIGHT
+ },
+ {
+ EL_PLAYER_2, ACTION_COLLECTING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_2_COLLECTING_DOWN
+ },
+ {
+ EL_PLAYER_2, ACTION_COLLECTING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_2_COLLECTING_UP
+ },
+ {
+ EL_PLAYER_2, ACTION_COLLECTING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_2_COLLECTING_LEFT
+ },
+ {
+ EL_PLAYER_2, ACTION_COLLECTING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_2_COLLECTING_RIGHT
+ },
+ {
+ EL_PLAYER_2, ACTION_PUSHING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_2_PUSHING_DOWN
+ },
+ {
+ EL_PLAYER_2, ACTION_PUSHING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_2_PUSHING_UP
+ },
+ {
+ EL_PLAYER_2, ACTION_PUSHING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_2_PUSHING_LEFT
+ },
+ {
+ EL_PLAYER_2, ACTION_PUSHING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_2_PUSHING_RIGHT
+ },
+ {
+ EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_2_SNAPPING_DOWN
+ },
+ {
+ EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_2_SNAPPING_UP
+ },
+ {
+ EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_2_SNAPPING_LEFT
+ },
+ {
+ EL_PLAYER_2, ACTION_SNAPPING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_2_SNAPPING_RIGHT
+ },
+ {
+ EL_PLAYER_3, -1, -1, FALSE,
+ IMG_PLAYER_3
+ },
+ {
+ EL_PLAYER_3, -1, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_3_DOWN
+ },
+ {
+ EL_PLAYER_3, -1, MV_BIT_UP, FALSE,
+ IMG_PLAYER_3_UP
+ },
+ {
+ EL_PLAYER_3, -1, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_3_LEFT
+ },
+ {
+ EL_PLAYER_3, -1, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_3_RIGHT
+ },
+ {
+ EL_PLAYER_3, ACTION_MOVING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_3_MOVING_DOWN
+ },
+ {
+ EL_PLAYER_3, ACTION_MOVING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_3_MOVING_UP
+ },
+ {
+ EL_PLAYER_3, ACTION_MOVING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_3_MOVING_LEFT
+ },
+ {
+ EL_PLAYER_3, ACTION_MOVING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_3_MOVING_RIGHT
+ },
+ {
+ EL_PLAYER_3, ACTION_DIGGING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_3_DIGGING_DOWN
+ },
+ {
+ EL_PLAYER_3, ACTION_DIGGING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_3_DIGGING_UP
+ },
+ {
+ EL_PLAYER_3, ACTION_DIGGING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_3_DIGGING_LEFT
+ },
+ {
+ EL_PLAYER_3, ACTION_DIGGING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_3_DIGGING_RIGHT
+ },
+ {
+ EL_PLAYER_3, ACTION_COLLECTING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_3_COLLECTING_DOWN
+ },
+ {
+ EL_PLAYER_3, ACTION_COLLECTING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_3_COLLECTING_UP
+ },
+ {
+ EL_PLAYER_3, ACTION_COLLECTING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_3_COLLECTING_LEFT
+ },
+ {
+ EL_PLAYER_3, ACTION_COLLECTING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_3_COLLECTING_RIGHT
+ },
+ {
+ EL_PLAYER_3, ACTION_PUSHING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_3_PUSHING_DOWN
+ },
+ {
+ EL_PLAYER_3, ACTION_PUSHING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_3_PUSHING_UP
+ },
+ {
+ EL_PLAYER_3, ACTION_PUSHING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_3_PUSHING_LEFT
+ },
+ {
+ EL_PLAYER_3, ACTION_PUSHING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_3_PUSHING_RIGHT
+ },
+ {
+ EL_PLAYER_3, ACTION_SNAPPING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_3_SNAPPING_DOWN
+ },
+ {
+ EL_PLAYER_3, ACTION_SNAPPING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_3_SNAPPING_UP
+ },
+ {
+ EL_PLAYER_3, ACTION_SNAPPING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_3_SNAPPING_LEFT
+ },
+ {
+ EL_PLAYER_3, ACTION_SNAPPING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_3_SNAPPING_RIGHT
+ },
+ {
+ EL_PLAYER_4, -1, -1, FALSE,
+ IMG_PLAYER_4
+ },
+ {
+ EL_PLAYER_4, -1, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_4_DOWN
+ },
+ {
+ EL_PLAYER_4, -1, MV_BIT_UP, FALSE,
+ IMG_PLAYER_4_UP
+ },
+ {
+ EL_PLAYER_4, -1, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_4_LEFT
+ },
+ {
+ EL_PLAYER_4, -1, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_4_RIGHT
+ },
+ {
+ EL_PLAYER_4, ACTION_MOVING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_4_MOVING_DOWN
+ },
+ {
+ EL_PLAYER_4, ACTION_MOVING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_4_MOVING_UP
+ },
+ {
+ EL_PLAYER_4, ACTION_MOVING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_4_MOVING_LEFT
+ },
+ {
+ EL_PLAYER_4, ACTION_MOVING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_4_MOVING_RIGHT
+ },
+ {
+ EL_PLAYER_4, ACTION_DIGGING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_4_DIGGING_DOWN
+ },
+ {
+ EL_PLAYER_4, ACTION_DIGGING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_4_DIGGING_UP
+ },
+ {
+ EL_PLAYER_4, ACTION_DIGGING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_4_DIGGING_LEFT
+ },
+ {
+ EL_PLAYER_4, ACTION_DIGGING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_4_DIGGING_RIGHT
+ },
+ {
+ EL_PLAYER_4, ACTION_COLLECTING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_4_COLLECTING_DOWN
+ },
+ {
+ EL_PLAYER_4, ACTION_COLLECTING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_4_COLLECTING_UP
+ },
+ {
+ EL_PLAYER_4, ACTION_COLLECTING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_4_COLLECTING_LEFT
+ },
+ {
+ EL_PLAYER_4, ACTION_COLLECTING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_4_COLLECTING_RIGHT
+ },
+ {
+ EL_PLAYER_4, ACTION_PUSHING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_4_PUSHING_DOWN
+ },
+ {
+ EL_PLAYER_4, ACTION_PUSHING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_4_PUSHING_UP
+ },
+ {
+ EL_PLAYER_4, ACTION_PUSHING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_4_PUSHING_LEFT
+ },
+ {
+ EL_PLAYER_4, ACTION_PUSHING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_4_PUSHING_RIGHT
+ },
+ {
+ EL_PLAYER_4, ACTION_SNAPPING, MV_BIT_DOWN, FALSE,
+ IMG_PLAYER_4_SNAPPING_DOWN
+ },
+ {
+ EL_PLAYER_4, ACTION_SNAPPING, MV_BIT_UP, FALSE,
+ IMG_PLAYER_4_SNAPPING_UP
+ },
+ {
+ EL_PLAYER_4, ACTION_SNAPPING, MV_BIT_LEFT, FALSE,
+ IMG_PLAYER_4_SNAPPING_LEFT
+ },
+ {
+ EL_PLAYER_4, ACTION_SNAPPING, MV_BIT_RIGHT, FALSE,
+ IMG_PLAYER_4_SNAPPING_RIGHT
+ },
+ {
+ EL_DEFAULT, ACTION_EXPLODING, -1, FALSE,
+ IMG_DEFAULT_EXPLODING
+ },
+ {
+ EL_STEELWALL_TOPLEFT, -1, -1, FALSE,
+ IMG_STEELWALL_TOPLEFT
+ },
+ {
+ EL_STEELWALL_TOPRIGHT, -1, -1, FALSE,
+ IMG_STEELWALL_TOPRIGHT
+ },
+ {
+ EL_STEELWALL_BOTTOMLEFT, -1, -1, FALSE,
+ IMG_STEELWALL_BOTTOMLEFT
+ },
+ {
+ EL_STEELWALL_BOTTOMRIGHT, -1, -1, FALSE,
+ IMG_STEELWALL_BOTTOMRIGHT
+ },
+ {
+ EL_STEELWALL_HORIZONTAL, -1, -1, FALSE,
+ IMG_STEELWALL_HORIZONTAL
+ },
+ {
+ EL_STEELWALL_VERTICAL, -1, -1, FALSE,
+ IMG_STEELWALL_VERTICAL
+ },
+ {
+ EL_INVISIBLE_STEELWALL_TOPLEFT, -1, -1, FALSE,
+ IMG_INVISIBLE_STEELWALL_TOPLEFT
+ },
+ {
+ EL_INVISIBLE_STEELWALL_TOPRIGHT, -1, -1, FALSE,
+ IMG_INVISIBLE_STEELWALL_TOPRIGHT
+ },
+ {
+ EL_INVISIBLE_STEELWALL_BOTTOMLEFT, -1, -1, FALSE,
+ IMG_INVISIBLE_STEELWALL_BOTTOMLEFT
+ },
+ {
+ EL_INVISIBLE_STEELWALL_BOTTOMRIGHT, -1, -1, FALSE,
+ IMG_INVISIBLE_STEELWALL_BOTTOMRIGHT
+ },
+ {
+ EL_INVISIBLE_STEELWALL_HORIZONTAL, -1, -1, FALSE,
+ IMG_INVISIBLE_STEELWALL_HORIZONTAL
+ },
+ {
+ EL_INVISIBLE_STEELWALL_VERTICAL, -1, -1, FALSE,
+ IMG_INVISIBLE_STEELWALL_VERTICAL
+ },
+ {
+ EL_ARROW_LEFT, -1, -1, FALSE,
+ IMG_ARROW_LEFT
+ },
+ {
+ EL_ARROW_RIGHT, -1, -1, FALSE,
+ IMG_ARROW_RIGHT
+ },
+ {
+ EL_ARROW_UP, -1, -1, FALSE,
+ IMG_ARROW_UP
+ },
+ {
+ EL_ARROW_DOWN, -1, -1, FALSE,
+ IMG_ARROW_DOWN
+ },
+ {
+ EL_DOOR_WHITE, -1, -1, FALSE,
+ IMG_CHAR_QUESTION
+ },
+ {
+ EL_DOOR_WHITE_GRAY, -1, -1, FALSE,
+ IMG_CHAR_QUESTION
+ },
+ {
+ EL_DX_UNKNOWN_15, -1, -1, FALSE,
+ IMG_CHAR_QUESTION
+ },
+ {
+ EL_DX_UNKNOWN_42, -1, -1, FALSE,
+ IMG_CHAR_QUESTION
+ },
+ {
+ EL_EM_KEY_1_FILE, -1, -1, FALSE,
+ IMG_EM_KEY_1
+ },
+ {
+ EL_EM_KEY_2_FILE, -1, -1, FALSE,
+ IMG_EM_KEY_2
+ },
+ {
+ EL_EM_KEY_3_FILE, -1, -1, FALSE,
+ IMG_EM_KEY_3
+ },
+ {
+ EL_EM_KEY_4_FILE, -1, -1, FALSE,
+ IMG_EM_KEY_4
+ },
+ {
+ EL_KEY_WHITE, -1, -1, FALSE,
+ IMG_CHAR_QUESTION
+ },
+ {
+ EL_SIGN_EXIT, -1, -1, FALSE,
+ IMG_CHAR_QUESTION
+ },
+ {
+ EL_SIGN_HEART, -1, -1, FALSE,
+ IMG_CHAR_QUESTION
+ },
+ {
+ EL_SIGN_ONEWAY, -1, -1, FALSE,
+ IMG_CHAR_QUESTION
+ },
+ {
+ EL_SIGN_OTHER, -1, -1, FALSE,
+ IMG_CHAR_QUESTION
+ },
+ {
+ EL_SIGN_PARKING, -1, -1, FALSE,
+ IMG_CHAR_QUESTION
+ },
+ {
+ EL_SIGN_RADIOACTIVITY, -1, -1, FALSE,
+ IMG_CHAR_QUESTION
+ },
+ {
+ EL_SIGN_ROUND, -1, -1, FALSE,
+ IMG_CHAR_QUESTION
+ },
+ {
+ EL_SIGN_TRIANGLE, -1, -1, FALSE,
+ IMG_CHAR_QUESTION
+ },
+ {
+ EL_SIGN_WHEELCHAIR, -1, -1, FALSE,
+ IMG_CHAR_QUESTION
+ },
+ {
+ EL_SIGN_YINYANG, -1, -1, FALSE,
+ IMG_CHAR_QUESTION
+ },
+ {
+ EL_CHAR_SPACE, -1, -1, FALSE,
+ IMG_CHAR_SPACE
+ },
+ {
+ EL_CHAR_EXCLAM, -1, -1, FALSE,
+ IMG_CHAR_EXCLAM
+ },
+ {
+ EL_CHAR_QUOTEDBL, -1, -1, FALSE,
+ IMG_CHAR_QUOTEDBL
+ },
+ {
+ EL_CHAR_NUMBERSIGN, -1, -1, FALSE,
+ IMG_CHAR_NUMBERSIGN
+ },
+ {
+ EL_CHAR_DOLLAR, -1, -1, FALSE,
+ IMG_CHAR_DOLLAR
+ },
+ {
+ EL_CHAR_PROCENT, -1, -1, FALSE,
+ IMG_CHAR_PROCENT
+ },
+ {
+ EL_CHAR_AMPERSAND, -1, -1, FALSE,
+ IMG_CHAR_AMPERSAND
+ },
+ {
+ EL_CHAR_APOSTROPHE, -1, -1, FALSE,
+ IMG_CHAR_APOSTROPHE
+ },
+ {
+ EL_CHAR_PARENLEFT, -1, -1, FALSE,
+ IMG_CHAR_PARENLEFT
+ },
+ {
+ EL_CHAR_PARENRIGHT, -1, -1, FALSE,
+ IMG_CHAR_PARENRIGHT
+ },
+ {
+ EL_CHAR_ASTERISK, -1, -1, FALSE,
+ IMG_CHAR_ASTERISK
+ },
+ {
+ EL_CHAR_PLUS, -1, -1, FALSE,
+ IMG_CHAR_PLUS
+ },
+ {
+ EL_CHAR_COMMA, -1, -1, FALSE,
+ IMG_CHAR_COMMA
+ },
+ {
+ EL_CHAR_MINUS, -1, -1, FALSE,
+ IMG_CHAR_MINUS
+ },
+ {
+ EL_CHAR_PERIOD, -1, -1, FALSE,
+ IMG_CHAR_PERIOD
+ },
+ {
+ EL_CHAR_SLASH, -1, -1, FALSE,
+ IMG_CHAR_SLASH
+ },
+ {
+ EL_CHAR_0, -1, -1, FALSE,
+ IMG_CHAR_0
+ },
+ {
+ EL_CHAR_1, -1, -1, FALSE,
+ IMG_CHAR_1
+ },
+ {
+ EL_CHAR_2, -1, -1, FALSE,
+ IMG_CHAR_2
+ },
+ {
+ EL_CHAR_3, -1, -1, FALSE,
+ IMG_CHAR_3
+ },
+ {
+ EL_CHAR_4, -1, -1, FALSE,
+ IMG_CHAR_4
+ },
+ {
+ EL_CHAR_5, -1, -1, FALSE,
+ IMG_CHAR_5
+ },
+ {
+ EL_CHAR_6, -1, -1, FALSE,
+ IMG_CHAR_6
+ },
+ {
+ EL_CHAR_7, -1, -1, FALSE,
+ IMG_CHAR_7
+ },
+ {
+ EL_CHAR_8, -1, -1, FALSE,
+ IMG_CHAR_8
+ },
+ {
+ EL_CHAR_9, -1, -1, FALSE,
+ IMG_CHAR_9
+ },
+ {
+ EL_CHAR_COLON, -1, -1, FALSE,
+ IMG_CHAR_COLON
+ },
+ {
+ EL_CHAR_SEMICOLON, -1, -1, FALSE,
+ IMG_CHAR_SEMICOLON
+ },
+ {
+ EL_CHAR_LESS, -1, -1, FALSE,
+ IMG_CHAR_LESS
+ },
+ {
+ EL_CHAR_EQUAL, -1, -1, FALSE,
+ IMG_CHAR_EQUAL
+ },
+ {
+ EL_CHAR_GREATER, -1, -1, FALSE,
+ IMG_CHAR_GREATER
+ },
+ {
+ EL_CHAR_QUESTION, -1, -1, FALSE,
+ IMG_CHAR_QUESTION
+ },
+ {
+ EL_CHAR_AT, -1, -1, FALSE,
+ IMG_CHAR_AT
+ },
+ {
+ EL_CHAR_A, -1, -1, FALSE,
+ IMG_CHAR_A
+ },
+ {
+ EL_CHAR_B, -1, -1, FALSE,
+ IMG_CHAR_B
+ },
+ {
+ EL_CHAR_C, -1, -1, FALSE,
+ IMG_CHAR_C
+ },
+ {
+ EL_CHAR_D, -1, -1, FALSE,
+ IMG_CHAR_D
+ },
+ {
+ EL_CHAR_E, -1, -1, FALSE,
+ IMG_CHAR_E
+ },
+ {
+ EL_CHAR_F, -1, -1, FALSE,
+ IMG_CHAR_F
+ },
+ {
+ EL_CHAR_G, -1, -1, FALSE,
+ IMG_CHAR_G
+ },
+ {
+ EL_CHAR_H, -1, -1, FALSE,
+ IMG_CHAR_H
+ },
+ {
+ EL_CHAR_I, -1, -1, FALSE,
+ IMG_CHAR_I
+ },
+ {
+ EL_CHAR_J, -1, -1, FALSE,
+ IMG_CHAR_J
+ },
+ {
+ EL_CHAR_K, -1, -1, FALSE,
+ IMG_CHAR_K
+ },
+ {
+ EL_CHAR_L, -1, -1, FALSE,
+ IMG_CHAR_L
+ },
+ {
+ EL_CHAR_M, -1, -1, FALSE,
+ IMG_CHAR_M
+ },
+ {
+ EL_CHAR_N, -1, -1, FALSE,
+ IMG_CHAR_N
+ },
+ {
+ EL_CHAR_O, -1, -1, FALSE,
+ IMG_CHAR_O
+ },
+ {
+ EL_CHAR_P, -1, -1, FALSE,
+ IMG_CHAR_P
+ },
+ {
+ EL_CHAR_Q, -1, -1, FALSE,
+ IMG_CHAR_Q
+ },
+ {
+ EL_CHAR_R, -1, -1, FALSE,
+ IMG_CHAR_R
+ },
+ {
+ EL_CHAR_S, -1, -1, FALSE,
+ IMG_CHAR_S
+ },
+ {
+ EL_CHAR_T, -1, -1, FALSE,
+ IMG_CHAR_T
+ },
+ {
+ EL_CHAR_U, -1, -1, FALSE,
+ IMG_CHAR_U
+ },
+ {
+ EL_CHAR_V, -1, -1, FALSE,
+ IMG_CHAR_V
+ },
+ {
+ EL_CHAR_W, -1, -1, FALSE,
+ IMG_CHAR_W
+ },
+ {
+ EL_CHAR_X, -1, -1, FALSE,
+ IMG_CHAR_X
+ },
+ {
+ EL_CHAR_Y, -1, -1, FALSE,
+ IMG_CHAR_Y
+ },
+ {
+ EL_CHAR_Z, -1, -1, FALSE,
+ IMG_CHAR_Z
+ },
+ {
+ EL_CHAR_BRACKETLEFT, -1, -1, FALSE,
+ IMG_CHAR_BRACKETLEFT
+ },
+ {
+ EL_CHAR_BACKSLASH, -1, -1, FALSE,
+ IMG_CHAR_BACKSLASH
+ },
+ {
+ EL_CHAR_BRACKETRIGHT, -1, -1, FALSE,
+ IMG_CHAR_BRACKETRIGHT
+ },
+ {
+ EL_CHAR_ASCIICIRCUM, -1, -1, FALSE,
+ IMG_CHAR_ASCIICIRCUM
+ },
+ {
+ EL_CHAR_UNDERSCORE, -1, -1, FALSE,
+ IMG_CHAR_UNDERSCORE
+ },
+ {
+ EL_CHAR_COPYRIGHT, -1, -1, FALSE,
+ IMG_CHAR_COPYRIGHT
+ },
+ {
+ EL_CHAR_AUMLAUT, -1, -1, FALSE,
+ IMG_CHAR_AUMLAUT
+ },
+ {
+ EL_CHAR_OUMLAUT, -1, -1, FALSE,
+ IMG_CHAR_OUMLAUT
+ },
+ {
+ EL_CHAR_UUMLAUT, -1, -1, FALSE,
+ IMG_CHAR_UUMLAUT
+ },
+ {
+ EL_CHAR_DEGREE, -1, -1, FALSE,
+ IMG_CHAR_DEGREE
+ },
+ {
+ EL_CHAR_TRADEMARK, -1, -1, FALSE,
+ IMG_CHAR_TRADEMARK
+ },
+ {
+ EL_CHAR_CURSOR, -1, -1, FALSE,
+ IMG_CHAR_CURSOR
+ },
+ {
+ EL_CUSTOM_1, -1, -1, FALSE,
+ IMG_CUSTOM_1
+ },
+ {
+ EL_CUSTOM_2, -1, -1, FALSE,
+ IMG_CUSTOM_2
+ },
+ {
+ EL_CUSTOM_3, -1, -1, FALSE,
+ IMG_CUSTOM_3
+ },
+ {
+ EL_CUSTOM_4, -1, -1, FALSE,
+ IMG_CUSTOM_4
+ },
+ {
+ EL_CUSTOM_5, -1, -1, FALSE,
+ IMG_CUSTOM_5
+ },
+ {
+ EL_CUSTOM_6, -1, -1, FALSE,
+ IMG_CUSTOM_6
+ },
+ {
+ EL_CUSTOM_7, -1, -1, FALSE,
+ IMG_CUSTOM_7
+ },
+ {
+ EL_CUSTOM_8, -1, -1, FALSE,
+ IMG_CUSTOM_8
+ },
+ {
+ EL_CUSTOM_9, -1, -1, FALSE,
+ IMG_CUSTOM_9
+ },
+ {
+ EL_CUSTOM_10, -1, -1, FALSE,
+ IMG_CUSTOM_10
+ },
+ {
+ EL_CUSTOM_11, -1, -1, FALSE,
+ IMG_CUSTOM_11
+ },
+ {
+ EL_CUSTOM_12, -1, -1, FALSE,
+ IMG_CUSTOM_12
+ },
+ {
+ EL_CUSTOM_13, -1, -1, FALSE,
+ IMG_CUSTOM_13
+ },
+ {
+ EL_CUSTOM_14, -1, -1, FALSE,
+ IMG_CUSTOM_14
+ },
+ {
+ EL_CUSTOM_15, -1, -1, FALSE,
+ IMG_CUSTOM_15
+ },
+ {
+ EL_CUSTOM_16, -1, -1, FALSE,
+ IMG_CUSTOM_16
+ },
+ {
+ EL_CUSTOM_17, -1, -1, FALSE,
+ IMG_CUSTOM_17
+ },
+ {
+ EL_CUSTOM_18, -1, -1, FALSE,
+ IMG_CUSTOM_18
+ },
+ {
+ EL_CUSTOM_19, -1, -1, FALSE,
+ IMG_CUSTOM_19
+ },
+ {
+ EL_CUSTOM_20, -1, -1, FALSE,
+ IMG_CUSTOM_20
+ },
+ {
+ EL_CUSTOM_21, -1, -1, FALSE,
+ IMG_CUSTOM_21
+ },
+ {
+ EL_CUSTOM_22, -1, -1, FALSE,
+ IMG_CUSTOM_22
+ },
+ {
+ EL_CUSTOM_23, -1, -1, FALSE,
+ IMG_CUSTOM_23
+ },
+ {
+ EL_CUSTOM_24, -1, -1, FALSE,
+ IMG_CUSTOM_24
+ },
+ {
+ EL_CUSTOM_25, -1, -1, FALSE,
+ IMG_CUSTOM_25
+ },
+ {
+ EL_CUSTOM_26, -1, -1, FALSE,
+ IMG_CUSTOM_26
+ },
+ {
+ EL_CUSTOM_27, -1, -1, FALSE,
+ IMG_CUSTOM_27
+ },
+ {
+ EL_CUSTOM_28, -1, -1, FALSE,
+ IMG_CUSTOM_28
+ },
+ {
+ EL_CUSTOM_29, -1, -1, FALSE,
+ IMG_CUSTOM_29
+ },
+ {
+ EL_CUSTOM_30, -1, -1, FALSE,
+ IMG_CUSTOM_30
+ },
+ {
+ EL_CUSTOM_31, -1, -1, FALSE,
+ IMG_CUSTOM_31
+ },
+ {
+ EL_CUSTOM_32, -1, -1, FALSE,
+ IMG_CUSTOM_32
+ },
+ {
+ EL_CUSTOM_33, -1, -1, FALSE,
+ IMG_CUSTOM_33
+ },
+ {
+ EL_CUSTOM_34, -1, -1, FALSE,
+ IMG_CUSTOM_34
+ },
+ {
+ EL_CUSTOM_35, -1, -1, FALSE,
+ IMG_CUSTOM_35
+ },
+ {
+ EL_CUSTOM_36, -1, -1, FALSE,
+ IMG_CUSTOM_36
+ },
+ {
+ EL_CUSTOM_37, -1, -1, FALSE,
+ IMG_CUSTOM_37
+ },
+ {
+ EL_CUSTOM_38, -1, -1, FALSE,
+ IMG_CUSTOM_38
+ },
+ {
+ EL_CUSTOM_39, -1, -1, FALSE,
+ IMG_CUSTOM_39
+ },
+ {
+ EL_CUSTOM_40, -1, -1, FALSE,
+ IMG_CUSTOM_40
+ },
+ {
+ EL_CUSTOM_41, -1, -1, FALSE,
+ IMG_CUSTOM_41
+ },
+ {
+ EL_CUSTOM_42, -1, -1, FALSE,
+ IMG_CUSTOM_42
+ },
+ {
+ EL_CUSTOM_43, -1, -1, FALSE,
+ IMG_CUSTOM_43
+ },
+ {
+ EL_CUSTOM_44, -1, -1, FALSE,
+ IMG_CUSTOM_44
+ },
+ {
+ EL_CUSTOM_45, -1, -1, FALSE,
+ IMG_CUSTOM_45
+ },
+ {
+ EL_CUSTOM_46, -1, -1, FALSE,
+ IMG_CUSTOM_46
+ },
+ {
+ EL_CUSTOM_47, -1, -1, FALSE,
+ IMG_CUSTOM_47
+ },
+ {
+ EL_CUSTOM_48, -1, -1, FALSE,
+ IMG_CUSTOM_48
+ },
+ {
+ EL_CUSTOM_49, -1, -1, FALSE,
+ IMG_CUSTOM_49
+ },
+ {
+ EL_CUSTOM_50, -1, -1, FALSE,
+ IMG_CUSTOM_50
+ },
+ {
+ EL_CUSTOM_51, -1, -1, FALSE,
+ IMG_CUSTOM_51
+ },
+ {
+ EL_CUSTOM_52, -1, -1, FALSE,
+ IMG_CUSTOM_52
+ },
+ {
+ EL_CUSTOM_53, -1, -1, FALSE,
+ IMG_CUSTOM_53
+ },
+ {
+ EL_CUSTOM_54, -1, -1, FALSE,
+ IMG_CUSTOM_54
+ },
+ {
+ EL_CUSTOM_55, -1, -1, FALSE,
+ IMG_CUSTOM_55
+ },
+ {
+ EL_CUSTOM_56, -1, -1, FALSE,
+ IMG_CUSTOM_56
+ },
+ {
+ EL_CUSTOM_57, -1, -1, FALSE,
+ IMG_CUSTOM_57
+ },
+ {
+ EL_CUSTOM_58, -1, -1, FALSE,
+ IMG_CUSTOM_58
+ },
+ {
+ EL_CUSTOM_59, -1, -1, FALSE,
+ IMG_CUSTOM_59
+ },
+ {
+ EL_CUSTOM_60, -1, -1, FALSE,
+ IMG_CUSTOM_60
+ },
+ {
+ EL_CUSTOM_61, -1, -1, FALSE,
+ IMG_CUSTOM_61
+ },
+ {
+ EL_CUSTOM_62, -1, -1, FALSE,
+ IMG_CUSTOM_62
+ },
+ {
+ EL_CUSTOM_63, -1, -1, FALSE,
+ IMG_CUSTOM_63
+ },
+ {
+ EL_CUSTOM_64, -1, -1, FALSE,
+ IMG_CUSTOM_64
+ },
+ {
+ EL_CUSTOM_65, -1, -1, FALSE,
+ IMG_CUSTOM_65
+ },
+ {
+ EL_CUSTOM_66, -1, -1, FALSE,
+ IMG_CUSTOM_66
+ },
+ {
+ EL_CUSTOM_67, -1, -1, FALSE,
+ IMG_CUSTOM_67
+ },
+ {
+ EL_CUSTOM_68, -1, -1, FALSE,
+ IMG_CUSTOM_68
+ },
+ {
+ EL_CUSTOM_69, -1, -1, FALSE,
+ IMG_CUSTOM_69
+ },
+ {
+ EL_CUSTOM_70, -1, -1, FALSE,
+ IMG_CUSTOM_70
+ },
+ {
+ EL_CUSTOM_71, -1, -1, FALSE,
+ IMG_CUSTOM_71
+ },
+ {
+ EL_CUSTOM_72, -1, -1, FALSE,
+ IMG_CUSTOM_72
+ },
+ {
+ EL_CUSTOM_73, -1, -1, FALSE,
+ IMG_CUSTOM_73
+ },
+ {
+ EL_CUSTOM_74, -1, -1, FALSE,
+ IMG_CUSTOM_74
+ },
+ {
+ EL_CUSTOM_75, -1, -1, FALSE,
+ IMG_CUSTOM_75
+ },
+ {
+ EL_CUSTOM_76, -1, -1, FALSE,
+ IMG_CUSTOM_76
+ },
+ {
+ EL_CUSTOM_77, -1, -1, FALSE,
+ IMG_CUSTOM_77
+ },
+ {
+ EL_CUSTOM_78, -1, -1, FALSE,
+ IMG_CUSTOM_78
+ },
+ {
+ EL_CUSTOM_79, -1, -1, FALSE,
+ IMG_CUSTOM_79
+ },
+ {
+ EL_CUSTOM_80, -1, -1, FALSE,
+ IMG_CUSTOM_80
+ },
+ {
+ EL_CUSTOM_81, -1, -1, FALSE,
+ IMG_CUSTOM_81
+ },
+ {
+ EL_CUSTOM_82, -1, -1, FALSE,
+ IMG_CUSTOM_82
+ },
+ {
+ EL_CUSTOM_83, -1, -1, FALSE,
+ IMG_CUSTOM_83
+ },
+ {
+ EL_CUSTOM_84, -1, -1, FALSE,
+ IMG_CUSTOM_84
+ },
+ {
+ EL_CUSTOM_85, -1, -1, FALSE,
+ IMG_CUSTOM_85
+ },
+ {
+ EL_CUSTOM_86, -1, -1, FALSE,
+ IMG_CUSTOM_86
+ },
+ {
+ EL_CUSTOM_87, -1, -1, FALSE,
+ IMG_CUSTOM_87
+ },
+ {
+ EL_CUSTOM_88, -1, -1, FALSE,
+ IMG_CUSTOM_88
+ },
+ {
+ EL_CUSTOM_89, -1, -1, FALSE,
+ IMG_CUSTOM_89
+ },
+ {
+ EL_CUSTOM_90, -1, -1, FALSE,
+ IMG_CUSTOM_90
+ },
+ {
+ EL_CUSTOM_91, -1, -1, FALSE,
+ IMG_CUSTOM_91
+ },
+ {
+ EL_CUSTOM_92, -1, -1, FALSE,
+ IMG_CUSTOM_92
+ },
+ {
+ EL_CUSTOM_93, -1, -1, FALSE,
+ IMG_CUSTOM_93
+ },
+ {
+ EL_CUSTOM_94, -1, -1, FALSE,
+ IMG_CUSTOM_94
+ },
+ {
+ EL_CUSTOM_95, -1, -1, FALSE,
+ IMG_CUSTOM_95
+ },
+ {
+ EL_CUSTOM_96, -1, -1, FALSE,
+ IMG_CUSTOM_96
+ },
+ {
+ EL_CUSTOM_97, -1, -1, FALSE,
+ IMG_CUSTOM_97
+ },
+ {
+ EL_CUSTOM_98, -1, -1, FALSE,
+ IMG_CUSTOM_98
+ },
+ {
+ EL_CUSTOM_99, -1, -1, FALSE,
+ IMG_CUSTOM_99
+ },
+ {
+ EL_CUSTOM_100, -1, -1, FALSE,
+ IMG_CUSTOM_100
+ },
+ {
+ EL_CUSTOM_101, -1, -1, FALSE,
+ IMG_CUSTOM_101
+ },
+ {
+ EL_CUSTOM_102, -1, -1, FALSE,
+ IMG_CUSTOM_102
+ },
+ {
+ EL_CUSTOM_103, -1, -1, FALSE,
+ IMG_CUSTOM_103
+ },
+ {
+ EL_CUSTOM_104, -1, -1, FALSE,
+ IMG_CUSTOM_104
+ },
+ {
+ EL_CUSTOM_105, -1, -1, FALSE,
+ IMG_CUSTOM_105
+ },
+ {
+ EL_CUSTOM_106, -1, -1, FALSE,
+ IMG_CUSTOM_106
+ },
+ {
+ EL_CUSTOM_107, -1, -1, FALSE,
+ IMG_CUSTOM_107
+ },
+ {
+ EL_CUSTOM_108, -1, -1, FALSE,
+ IMG_CUSTOM_108
+ },
+ {
+ EL_CUSTOM_109, -1, -1, FALSE,
+ IMG_CUSTOM_109
+ },
+ {
+ EL_CUSTOM_110, -1, -1, FALSE,
+ IMG_CUSTOM_110
+ },
+ {
+ EL_CUSTOM_111, -1, -1, FALSE,
+ IMG_CUSTOM_111
+ },
+ {
+ EL_CUSTOM_112, -1, -1, FALSE,
+ IMG_CUSTOM_112
+ },
+ {
+ EL_CUSTOM_113, -1, -1, FALSE,
+ IMG_CUSTOM_113
+ },
+ {
+ EL_CUSTOM_114, -1, -1, FALSE,
+ IMG_CUSTOM_114
+ },
+ {
+ EL_CUSTOM_115, -1, -1, FALSE,
+ IMG_CUSTOM_115
+ },
+ {
+ EL_CUSTOM_116, -1, -1, FALSE,
+ IMG_CUSTOM_116
+ },
+ {
+ EL_CUSTOM_117, -1, -1, FALSE,
+ IMG_CUSTOM_117
+ },
+ {
+ EL_CUSTOM_118, -1, -1, FALSE,
+ IMG_CUSTOM_118
+ },
+ {
+ EL_CUSTOM_119, -1, -1, FALSE,
+ IMG_CUSTOM_119
+ },
+ {
+ EL_CUSTOM_120, -1, -1, FALSE,
+ IMG_CUSTOM_120
+ },
+ {
+ EL_CUSTOM_121, -1, -1, FALSE,
+ IMG_CUSTOM_121
+ },
+ {
+ EL_CUSTOM_122, -1, -1, FALSE,
+ IMG_CUSTOM_122
+ },
+ {
+ EL_CUSTOM_123, -1, -1, FALSE,
+ IMG_CUSTOM_123
+ },
+ {
+ EL_CUSTOM_124, -1, -1, FALSE,
+ IMG_CUSTOM_124
+ },
+ {
+ EL_CUSTOM_125, -1, -1, FALSE,
+ IMG_CUSTOM_125
+ },
+ {
+ EL_CUSTOM_126, -1, -1, FALSE,
+ IMG_CUSTOM_126
+ },
+ {
+ EL_CUSTOM_127, -1, -1, FALSE,
+ IMG_CUSTOM_127
+ },
+ {
+ EL_CUSTOM_128, -1, -1, FALSE,
+ IMG_CUSTOM_128
+ },
+ {
+ -1, -1, -1, FALSE,
+ -1
+ },
+};
+
+#endif /* CONF_E2G_C */
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* (c) 1995-2002 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* conf_e2s.c *
+***********************************************************/
+
+/* ----- this file was automatically generated -- do not edit by hand ----- */
+
+#ifndef CONF_E2S_C
+#define CONF_E2S_C
+
+/* values for element/sounds mapping configuration */
+
+static struct
+{
+ int element;
+ boolean is_class;
+ int action;
+
+ int sound;
+}
+element_to_sound[] =
+{
+ {
+ EL_DEFAULT, TRUE, ACTION_DIGGING,
+ SND_CLASS_DEFAULT_DIGGING
+ },
+ {
+ EL_DEFAULT, TRUE, ACTION_COLLECTING,
+ SND_CLASS_DEFAULT_COLLECTING
+ },
+ {
+ EL_DEFAULT, TRUE, ACTION_SNAPPING,
+ SND_CLASS_DEFAULT_SNAPPING
+ },
+ {
+ EL_DEFAULT, TRUE, ACTION_PUSHING,
+ SND_CLASS_DEFAULT_PUSHING
+ },
+ {
+ EL_DEFAULT, TRUE, ACTION_IMPACT,
+ SND_CLASS_DEFAULT_IMPACT
+ },
+ {
+ EL_DEFAULT, TRUE, ACTION_WALKING,
+ SND_CLASS_DEFAULT_WALKING
+ },
+ {
+ EL_DEFAULT, TRUE, ACTION_PASSING,
+ SND_CLASS_DEFAULT_PASSING
+ },
+ {
+ EL_DEFAULT, TRUE, ACTION_DYING,
+ SND_CLASS_DEFAULT_DYING
+ },
+ {
+ EL_DEFAULT, TRUE, ACTION_EXPLODING,
+ SND_CLASS_DEFAULT_EXPLODING
+ },
+ {
+ EL_SP_DEFAULT, TRUE, ACTION_EXPLODING,
+ SND_CLASS_SP_DEFAULT_EXPLODING
+ },
+ {
+ EL_BD_DIAMOND, FALSE, ACTION_COLLECTING,
+ SND_BD_DIAMOND_COLLECTING
+ },
+ {
+ EL_BD_DIAMOND, FALSE, ACTION_IMPACT,
+ SND_BD_DIAMOND_IMPACT
+ },
+ {
+ EL_BD_ROCK, FALSE, ACTION_PUSHING,
+ SND_BD_ROCK_PUSHING
+ },
+ {
+ EL_BD_ROCK, FALSE, ACTION_IMPACT,
+ SND_BD_ROCK_IMPACT
+ },
+ {
+ EL_BD_MAGIC_WALL, FALSE, ACTION_ACTIVATING,
+ SND_BD_MAGIC_WALL_ACTIVATING
+ },
+ {
+ EL_BD_MAGIC_WALL_ACTIVE, FALSE, -1,
+ SND_BD_MAGIC_WALL_ACTIVE
+ },
+ {
+ EL_BD_MAGIC_WALL, FALSE, ACTION_ACTIVE,
+ SND_BD_MAGIC_WALL_ACTIVE
+ },
+ {
+ EL_BD_MAGIC_WALL_FILLING, FALSE, -1,
+ SND_BD_MAGIC_WALL_FILLING
+ },
+ {
+ EL_BD_MAGIC_WALL, FALSE, ACTION_FILLING,
+ SND_BD_MAGIC_WALL_FILLING
+ },
+ {
+ EL_BD_AMOEBA, FALSE, ACTION_WAITING,
+ SND_BD_AMOEBA_WAITING
+ },
+ {
+ EL_BD_AMOEBA, FALSE, ACTION_GROWING,
+ SND_BD_AMOEBA_GROWING
+ },
+ {
+ EL_BD_BUTTERFLY, FALSE, ACTION_MOVING,
+ SND_BD_BUTTERFLY_MOVING
+ },
+ {
+ EL_BD_BUTTERFLY, FALSE, ACTION_WAITING,
+ SND_BD_BUTTERFLY_WAITING
+ },
+ {
+ EL_BD_FIREFLY, FALSE, ACTION_MOVING,
+ SND_BD_FIREFLY_MOVING
+ },
+ {
+ EL_BD_FIREFLY, FALSE, ACTION_WAITING,
+ SND_BD_FIREFLY_WAITING
+ },
+ {
+ EL_SP_BASE, FALSE, ACTION_DIGGING,
+ SND_SP_BASE_DIGGING
+ },
+ {
+ EL_SP_BUGGY_BASE, FALSE, ACTION_DIGGING,
+ SND_SP_BUGGY_BASE_DIGGING
+ },
+ {
+ EL_SP_BUGGY_BASE_ACTIVE, FALSE, -1,
+ SND_SP_BUGGY_BASE_ACTIVE
+ },
+ {
+ EL_SP_BUGGY_BASE, FALSE, ACTION_ACTIVE,
+ SND_SP_BUGGY_BASE_ACTIVE
+ },
+ {
+ EL_SP_INFOTRON, FALSE, ACTION_COLLECTING,
+ SND_SP_INFOTRON_COLLECTING
+ },
+ {
+ EL_SP_INFOTRON, FALSE, ACTION_IMPACT,
+ SND_SP_INFOTRON_IMPACT
+ },
+ {
+ EL_SP_ZONK, FALSE, ACTION_PUSHING,
+ SND_SP_ZONK_PUSHING
+ },
+ {
+ EL_SP_ZONK, FALSE, ACTION_IMPACT,
+ SND_SP_ZONK_IMPACT
+ },
+ {
+ EL_SP_DISK_RED, FALSE, ACTION_COLLECTING,
+ SND_SP_DISK_RED_COLLECTING
+ },
+ {
+ EL_SP_DISK_ORANGE, FALSE, ACTION_PUSHING,
+ SND_SP_DISK_ORANGE_PUSHING
+ },
+ {
+ EL_SP_DISK_YELLOW, FALSE, ACTION_PUSHING,
+ SND_SP_DISK_YELLOW_PUSHING
+ },
+ {
+ EL_SP_PORT_RIGHT, TRUE, ACTION_PASSING,
+ SND_CLASS_SP_PORT_PASSING
+ },
+ {
+ EL_SP_EXIT_CLOSED, TRUE, ACTION_PASSING,
+ SND_CLASS_SP_EXIT_PASSING
+ },
+ {
+ EL_SP_EXIT_CLOSED, TRUE, ACTION_OPENING,
+ SND_CLASS_SP_EXIT_OPENING
+ },
+ {
+ EL_SP_SNIKSNAK, FALSE, ACTION_MOVING,
+ SND_SP_SNIKSNAK_MOVING
+ },
+ {
+ EL_SP_SNIKSNAK, FALSE, ACTION_WAITING,
+ SND_SP_SNIKSNAK_WAITING
+ },
+ {
+ EL_SP_ELECTRON, FALSE, ACTION_MOVING,
+ SND_SP_ELECTRON_MOVING
+ },
+ {
+ EL_SP_ELECTRON, FALSE, ACTION_WAITING,
+ SND_SP_ELECTRON_WAITING
+ },
+ {
+ EL_SP_TERMINAL, FALSE, ACTION_ACTIVATING,
+ SND_SP_TERMINAL_ACTIVATING
+ },
+ {
+ EL_SP_TERMINAL_ACTIVE, FALSE, -1,
+ SND_SP_TERMINAL_ACTIVE
+ },
+ {
+ EL_SP_TERMINAL, FALSE, ACTION_ACTIVE,
+ SND_SP_TERMINAL_ACTIVE
+ },
+ {
+ EL_SOKOBAN_OBJECT, TRUE, ACTION_PUSHING,
+ SND_CLASS_SOKOBAN_PUSHING
+ },
+ {
+ EL_SOKOBAN_OBJECT, TRUE, ACTION_FILLING,
+ SND_CLASS_SOKOBAN_FILLING
+ },
+ {
+ EL_SOKOBAN_OBJECT, TRUE, ACTION_EMPTYING,
+ SND_CLASS_SOKOBAN_EMPTYING
+ },
+ {
+ EL_PLAYER_OBSOLETE, TRUE, ACTION_MOVING,
+ SND_CLASS_PLAYER_MOVING
+ },
+ {
+ EL_SAND, FALSE, ACTION_DIGGING,
+ SND_SAND_DIGGING
+ },
+ {
+ EL_EMERALD, FALSE, ACTION_COLLECTING,
+ SND_EMERALD_COLLECTING
+ },
+ {
+ EL_EMERALD, FALSE, ACTION_IMPACT,
+ SND_EMERALD_IMPACT
+ },
+ {
+ EL_DIAMOND, FALSE, ACTION_COLLECTING,
+ SND_DIAMOND_COLLECTING
+ },
+ {
+ EL_DIAMOND, FALSE, ACTION_IMPACT,
+ SND_DIAMOND_IMPACT
+ },
+ {
+ EL_DIAMOND_BREAKING, FALSE, -1,
+ SND_DIAMOND_BREAKING
+ },
+ {
+ EL_DIAMOND, FALSE, ACTION_BREAKING,
+ SND_DIAMOND_BREAKING
+ },
+ {
+ EL_ROCK, FALSE, ACTION_PUSHING,
+ SND_ROCK_PUSHING
+ },
+ {
+ EL_ROCK, FALSE, ACTION_IMPACT,
+ SND_ROCK_IMPACT
+ },
+ {
+ EL_BOMB, FALSE, ACTION_PUSHING,
+ SND_BOMB_PUSHING
+ },
+ {
+ EL_NUT, FALSE, ACTION_PUSHING,
+ SND_NUT_PUSHING
+ },
+ {
+ EL_NUT_BREAKING, FALSE, -1,
+ SND_NUT_BREAKING
+ },
+ {
+ EL_NUT, FALSE, ACTION_BREAKING,
+ SND_NUT_BREAKING
+ },
+ {
+ EL_NUT, FALSE, ACTION_IMPACT,
+ SND_NUT_IMPACT
+ },
+ {
+ EL_DYNAMITE_ACTIVE, TRUE, ACTION_COLLECTING,
+ SND_CLASS_DYNAMITE_COLLECTING
+ },
+ {
+ EL_DYNAMITE_ACTIVE, TRUE, ACTION_DROPPING,
+ SND_CLASS_DYNAMITE_DROPPING
+ },
+ {
+ EL_DYNAMITE_ACTIVE, TRUE, ACTION_ACTIVE,
+ SND_CLASS_DYNAMITE_ACTIVE
+ },
+ {
+ EL_KEY_OBSOLETE, TRUE, ACTION_COLLECTING,
+ SND_CLASS_KEY_COLLECTING
+ },
+ {
+ EL_GATE_1, TRUE, ACTION_PASSING,
+ SND_CLASS_GATE_PASSING
+ },
+ {
+ EL_BUG, FALSE, ACTION_MOVING,
+ SND_BUG_MOVING
+ },
+ {
+ EL_BUG, FALSE, ACTION_WAITING,
+ SND_BUG_WAITING
+ },
+ {
+ EL_SPACESHIP, FALSE, ACTION_MOVING,
+ SND_SPACESHIP_MOVING
+ },
+ {
+ EL_SPACESHIP, FALSE, ACTION_WAITING,
+ SND_SPACESHIP_WAITING
+ },
+ {
+ EL_YAMYAM, FALSE, ACTION_MOVING,
+ SND_YAMYAM_MOVING
+ },
+ {
+ EL_YAMYAM, FALSE, ACTION_WAITING,
+ SND_YAMYAM_WAITING
+ },
+ {
+ EL_YAMYAM, FALSE, ACTION_DIGGING,
+ SND_YAMYAM_DIGGING
+ },
+ {
+ EL_ROBOT, FALSE, ACTION_MOVING,
+ SND_ROBOT_MOVING
+ },
+ {
+ EL_ROBOT, FALSE, ACTION_WAITING,
+ SND_ROBOT_WAITING
+ },
+ {
+ EL_ROBOT_WHEEL, FALSE, ACTION_ACTIVATING,
+ SND_ROBOT_WHEEL_ACTIVATING
+ },
+ {
+ EL_ROBOT_WHEEL_ACTIVE, FALSE, -1,
+ SND_ROBOT_WHEEL_ACTIVE
+ },
+ {
+ EL_ROBOT_WHEEL, FALSE, ACTION_ACTIVE,
+ SND_ROBOT_WHEEL_ACTIVE
+ },
+ {
+ EL_MAGIC_WALL, FALSE, ACTION_ACTIVATING,
+ SND_MAGIC_WALL_ACTIVATING
+ },
+ {
+ EL_MAGIC_WALL_ACTIVE, FALSE, -1,
+ SND_MAGIC_WALL_ACTIVE
+ },
+ {
+ EL_MAGIC_WALL, FALSE, ACTION_ACTIVE,
+ SND_MAGIC_WALL_ACTIVE
+ },
+ {
+ EL_MAGIC_WALL_FILLING, FALSE, -1,
+ SND_MAGIC_WALL_FILLING
+ },
+ {
+ EL_MAGIC_WALL, FALSE, ACTION_FILLING,
+ SND_MAGIC_WALL_FILLING
+ },
+ {
+ EL_AMOEBA_DEAD, TRUE, ACTION_WAITING,
+ SND_CLASS_AMOEBA_WAITING
+ },
+ {
+ EL_AMOEBA_DEAD, TRUE, ACTION_GROWING,
+ SND_CLASS_AMOEBA_GROWING
+ },
+ {
+ EL_AMOEBA_DEAD, TRUE, ACTION_DROPPING,
+ SND_CLASS_AMOEBA_DROPPING
+ },
+ {
+ EL_QUICKSAND_EMPTY, TRUE, ACTION_FILLING,
+ SND_CLASS_QUICKSAND_FILLING
+ },
+ {
+ EL_QUICKSAND_EMPTY, TRUE, ACTION_EMPTYING,
+ SND_CLASS_QUICKSAND_EMPTYING
+ },
+ {
+ EL_EXIT_CLOSED, TRUE, ACTION_OPENING,
+ SND_CLASS_EXIT_OPENING
+ },
+ {
+ EL_EXIT_CLOSED, TRUE, ACTION_PASSING,
+ SND_CLASS_EXIT_PASSING
+ },
+ {
+ EL_PENGUIN, FALSE, ACTION_PASSING,
+ SND_PENGUIN_PASSING
+ },
+ {
+ EL_BALLOON, FALSE, ACTION_MOVING,
+ SND_BALLOON_MOVING
+ },
+ {
+ EL_BALLOON, FALSE, ACTION_WAITING,
+ SND_BALLOON_WAITING
+ },
+ {
+ EL_BALLOON, FALSE, ACTION_PUSHING,
+ SND_BALLOON_PUSHING
+ },
+ {
+ EL_BALLOON_SWITCH_LEFT, TRUE, ACTION_ACTIVATING,
+ SND_CLASS_BALLOON_SWITCH_ACTIVATING
+ },
+ {
+ EL_SPRING, FALSE, ACTION_MOVING,
+ SND_SPRING_MOVING
+ },
+ {
+ EL_SPRING, FALSE, ACTION_PUSHING,
+ SND_SPRING_PUSHING
+ },
+ {
+ EL_SPRING, FALSE, ACTION_IMPACT,
+ SND_SPRING_IMPACT
+ },
+ {
+ EL_WALL, TRUE, ACTION_GROWING,
+ SND_CLASS_WALL_GROWING
+ },
+ {
+ EL_PEARL, FALSE, ACTION_COLLECTING,
+ SND_PEARL_COLLECTING
+ },
+ {
+ EL_PEARL_BREAKING, FALSE, -1,
+ SND_PEARL_BREAKING
+ },
+ {
+ EL_PEARL, FALSE, ACTION_BREAKING,
+ SND_PEARL_BREAKING
+ },
+ {
+ EL_PEARL, FALSE, ACTION_IMPACT,
+ SND_PEARL_IMPACT
+ },
+ {
+ EL_CRYSTAL, FALSE, ACTION_COLLECTING,
+ SND_CRYSTAL_COLLECTING
+ },
+ {
+ EL_CRYSTAL, FALSE, ACTION_IMPACT,
+ SND_CRYSTAL_IMPACT
+ },
+ {
+ EL_ENVELOPE, FALSE, ACTION_COLLECTING,
+ SND_ENVELOPE_COLLECTING
+ },
+ {
+ EL_INVISIBLE_SAND, FALSE, ACTION_DIGGING,
+ SND_INVISIBLE_SAND_DIGGING
+ },
+ {
+ EL_SHIELD_NORMAL, FALSE, ACTION_COLLECTING,
+ SND_SHIELD_NORMAL_COLLECTING
+ },
+ {
+ EL_SHIELD_NORMAL_ACTIVE, FALSE, -1,
+ SND_SHIELD_NORMAL_ACTIVE
+ },
+ {
+ EL_SHIELD_NORMAL, FALSE, ACTION_ACTIVE,
+ SND_SHIELD_NORMAL_ACTIVE
+ },
+ {
+ EL_SHIELD_DEADLY, FALSE, ACTION_COLLECTING,
+ SND_SHIELD_DEADLY_COLLECTING
+ },
+ {
+ EL_SHIELD_DEADLY_ACTIVE, FALSE, -1,
+ SND_SHIELD_DEADLY_ACTIVE
+ },
+ {
+ EL_SHIELD_DEADLY, FALSE, ACTION_ACTIVE,
+ SND_SHIELD_DEADLY_ACTIVE
+ },
+ {
+ EL_EXTRA_TIME, FALSE, ACTION_COLLECTING,
+ SND_EXTRA_TIME_COLLECTING
+ },
+ {
+ EL_MOLE, FALSE, ACTION_MOVING,
+ SND_MOLE_MOVING
+ },
+ {
+ EL_MOLE, FALSE, ACTION_WAITING,
+ SND_MOLE_WAITING
+ },
+ {
+ EL_MOLE, FALSE, ACTION_DIGGING,
+ SND_MOLE_DIGGING
+ },
+ {
+ EL_SWITCHGATE_SWITCH_UP, TRUE, ACTION_ACTIVATING,
+ SND_CLASS_SWITCHGATE_SWITCH_ACTIVATING
+ },
+ {
+ EL_SWITCHGATE_OPEN, TRUE, ACTION_OPENING,
+ SND_CLASS_SWITCHGATE_OPENING
+ },
+ {
+ EL_SWITCHGATE_OPEN, TRUE, ACTION_CLOSING,
+ SND_CLASS_SWITCHGATE_CLOSING
+ },
+ {
+ EL_SWITCHGATE_OPEN, TRUE, ACTION_PASSING,
+ SND_CLASS_SWITCHGATE_PASSING
+ },
+ {
+ EL_TIMEGATE_SWITCH, FALSE, ACTION_ACTIVATING,
+ SND_TIMEGATE_SWITCH_ACTIVATING
+ },
+ {
+ EL_TIMEGATE_SWITCH_ACTIVE, FALSE, -1,
+ SND_TIMEGATE_SWITCH_ACTIVE
+ },
+ {
+ EL_TIMEGATE_SWITCH, FALSE, ACTION_ACTIVE,
+ SND_TIMEGATE_SWITCH_ACTIVE
+ },
+ {
+ EL_TIMEGATE_SWITCH, FALSE, ACTION_DEACTIVATING,
+ SND_TIMEGATE_SWITCH_DEACTIVATING
+ },
+ {
+ EL_TIMEGATE_OPENING, FALSE, -1,
+ SND_TIMEGATE_OPENING
+ },
+ {
+ EL_TIMEGATE_OPEN, TRUE, ACTION_CLOSING,
+ SND_CLASS_TIMEGATE_CLOSING
+ },
+ {
+ EL_TIMEGATE_OPEN, TRUE, ACTION_PASSING,
+ SND_CLASS_TIMEGATE_PASSING
+ },
+ {
+ EL_CONVEYOR_BELT_1_SWITCH_LEFT, TRUE, ACTION_ACTIVATING,
+ SND_CLASS_CONVEYOR_BELT_SWITCH_ACTIVATING
+ },
+ {
+ EL_CONVEYOR_BELT_1_LEFT, TRUE, ACTION_ACTIVE,
+ SND_CLASS_CONVEYOR_BELT_ACTIVE
+ },
+ {
+ EL_CONVEYOR_BELT_1_SWITCH_LEFT, TRUE, ACTION_DEACTIVATING,
+ SND_CLASS_CONVEYOR_BELT_SWITCH_DEACTIVATING
+ },
+ {
+ EL_LIGHT_SWITCH, FALSE, ACTION_ACTIVATING,
+ SND_LIGHT_SWITCH_ACTIVATING
+ },
+ {
+ EL_LIGHT_SWITCH, FALSE, ACTION_DEACTIVATING,
+ SND_LIGHT_SWITCH_DEACTIVATING
+ },
+ {
+ EL_DX_SUPABOMB, FALSE, ACTION_PUSHING,
+ SND_DX_SUPABOMB_PUSHING
+ },
+ {
+ EL_TRAP, FALSE, ACTION_DIGGING,
+ SND_TRAP_DIGGING
+ },
+ {
+ EL_TRAP, FALSE, ACTION_ACTIVATING,
+ SND_TRAP_ACTIVATING
+ },
+ {
+ EL_TUBE_ANY, TRUE, ACTION_WALKING,
+ SND_CLASS_TUBE_WALKING
+ },
+ {
+ EL_SPEED_PILL, FALSE, ACTION_COLLECTING,
+ SND_SPEED_PILL_COLLECTING
+ },
+ {
+ EL_DYNABOMB_INCREASE_NUMBER, FALSE, ACTION_COLLECTING,
+ SND_DYNABOMB_INCREASE_NUMBER_COLLECTING
+ },
+ {
+ EL_DYNABOMB_INCREASE_SIZE, FALSE, ACTION_COLLECTING,
+ SND_DYNABOMB_INCREASE_SIZE_COLLECTING
+ },
+ {
+ EL_DYNABOMB_INCREASE_POWER, FALSE, ACTION_COLLECTING,
+ SND_DYNABOMB_INCREASE_POWER_COLLECTING
+ },
+ {
+ EL_DYNABOMB_INCREASE_NUMBER, TRUE, ACTION_DROPPING,
+ SND_CLASS_DYNABOMB_DROPPING
+ },
+ {
+ EL_DYNABOMB_INCREASE_NUMBER, TRUE, ACTION_ACTIVE,
+ SND_CLASS_DYNABOMB_ACTIVE
+ },
+ {
+ EL_SATELLITE, FALSE, ACTION_MOVING,
+ SND_SATELLITE_MOVING
+ },
+ {
+ EL_SATELLITE, FALSE, ACTION_WAITING,
+ SND_SATELLITE_WAITING
+ },
+ {
+ EL_SATELLITE, FALSE, ACTION_PUSHING,
+ SND_SATELLITE_PUSHING
+ },
+ {
+ EL_LAMP, FALSE, ACTION_ACTIVATING,
+ SND_LAMP_ACTIVATING
+ },
+ {
+ EL_LAMP, FALSE, ACTION_DEACTIVATING,
+ SND_LAMP_DEACTIVATING
+ },
+ {
+ EL_TIME_ORB_FULL, FALSE, ACTION_COLLECTING,
+ SND_TIME_ORB_FULL_COLLECTING
+ },
+ {
+ EL_TIME_ORB_FULL, FALSE, ACTION_IMPACT,
+ SND_TIME_ORB_FULL_IMPACT
+ },
+ {
+ EL_TIME_ORB_EMPTY, FALSE, ACTION_PUSHING,
+ SND_TIME_ORB_EMPTY_PUSHING
+ },
+ {
+ EL_TIME_ORB_EMPTY, FALSE, ACTION_IMPACT,
+ SND_TIME_ORB_EMPTY_IMPACT
+ },
+ {
+ EL_GAME_OF_LIFE, FALSE, ACTION_WAITING,
+ SND_GAME_OF_LIFE_WAITING
+ },
+ {
+ EL_GAME_OF_LIFE, FALSE, ACTION_GROWING,
+ SND_GAME_OF_LIFE_GROWING
+ },
+ {
+ EL_BIOMAZE, FALSE, ACTION_WAITING,
+ SND_BIOMAZE_WAITING
+ },
+ {
+ EL_BIOMAZE, FALSE, ACTION_GROWING,
+ SND_BIOMAZE_GROWING
+ },
+ {
+ EL_PACMAN, FALSE, ACTION_MOVING,
+ SND_PACMAN_MOVING
+ },
+ {
+ EL_PACMAN, FALSE, ACTION_WAITING,
+ SND_PACMAN_WAITING
+ },
+ {
+ EL_PACMAN, FALSE, ACTION_DIGGING,
+ SND_PACMAN_DIGGING
+ },
+ {
+ EL_DARK_YAMYAM, FALSE, ACTION_MOVING,
+ SND_DARK_YAMYAM_MOVING
+ },
+ {
+ EL_DARK_YAMYAM, FALSE, ACTION_WAITING,
+ SND_DARK_YAMYAM_WAITING
+ },
+ {
+ EL_DARK_YAMYAM, FALSE, ACTION_DIGGING,
+ SND_DARK_YAMYAM_DIGGING
+ },
+ {
+ EL_PENGUIN, FALSE, ACTION_MOVING,
+ SND_PENGUIN_MOVING
+ },
+ {
+ EL_PENGUIN, FALSE, ACTION_WAITING,
+ SND_PENGUIN_WAITING
+ },
+ {
+ EL_PIG, FALSE, ACTION_MOVING,
+ SND_PIG_MOVING
+ },
+ {
+ EL_PIG, FALSE, ACTION_WAITING,
+ SND_PIG_WAITING
+ },
+ {
+ EL_PIG, FALSE, ACTION_DIGGING,
+ SND_PIG_DIGGING
+ },
+ {
+ EL_DRAGON, FALSE, ACTION_MOVING,
+ SND_DRAGON_MOVING
+ },
+ {
+ EL_DRAGON, FALSE, ACTION_WAITING,
+ SND_DRAGON_WAITING
+ },
+ {
+ EL_DRAGON, FALSE, ACTION_ATTACKING,
+ SND_DRAGON_ATTACKING
+ },
+ {
+ -1, -1, -1,
+ -1
+ },
+};
+
+#endif /* CONF_E2S_C */
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* (c) 1995-2002 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* conf_esg.c *
+***********************************************************/
+
+/* ----- this file was automatically generated -- do not edit by hand ----- */
+
+#ifndef CONF_ESG_C
+#define CONF_ESG_C
+
+/* values for element/graphics mapping configuration (special) */
+
+static struct
+{
+ int element;
+ int special;
+
+ int graphic;
+}
+element_to_special_graphic[] =
+{
+ {
+ EL_BD_WALL, GFX_SPECIAL_ARG_EDITOR,
+ IMG_BD_WALL_EDITOR
+ },
+ {
+ EL_BD_ROCK, GFX_SPECIAL_ARG_EDITOR,
+ IMG_BD_ROCK_EDITOR
+ },
+ {
+ EL_BD_AMOEBA, GFX_SPECIAL_ARG_EDITOR,
+ IMG_BD_AMOEBA_EDITOR
+ },
+ {
+ EL_SP_INFOTRON, GFX_SPECIAL_ARG_EDITOR,
+ IMG_SP_INFOTRON_EDITOR
+ },
+ {
+ EL_SP_ELECTRON, GFX_SPECIAL_ARG_EDITOR,
+ IMG_SP_ELECTRON_EDITOR
+ },
+ {
+ EL_SP_TERMINAL, GFX_SPECIAL_ARG_EDITOR,
+ IMG_SP_TERMINAL_EDITOR
+ },
+ {
+ EL_SP_BUGGY_BASE, GFX_SPECIAL_ARG_EDITOR,
+ IMG_SP_BUGGY_BASE_EDITOR
+ },
+ {
+ EL_SOKOBAN_OBJECT, GFX_SPECIAL_ARG_EDITOR,
+ IMG_SOKOBAN_OBJECT_EDITOR
+ },
+ {
+ EL_DYNAMITE, GFX_SPECIAL_ARG_EDITOR,
+ IMG_DYNAMITE_EDITOR
+ },
+ {
+ EL_DYNAMITE_ACTIVE, GFX_SPECIAL_ARG_EDITOR,
+ IMG_DYNAMITE_ACTIVE_EDITOR
+ },
+ {
+ EL_QUICKSAND_FULL, GFX_SPECIAL_ARG_EDITOR,
+ IMG_QUICKSAND_FULL_EDITOR
+ },
+ {
+ EL_AMOEBA_WET, GFX_SPECIAL_ARG_EDITOR,
+ IMG_AMOEBA_WET_EDITOR
+ },
+ {
+ EL_AMOEBA_FULL, GFX_SPECIAL_ARG_EDITOR,
+ IMG_AMOEBA_FULL_EDITOR
+ },
+ {
+ EL_AMOEBA_DEAD, GFX_SPECIAL_ARG_EDITOR,
+ IMG_AMOEBA_DEAD_EDITOR
+ },
+ {
+ EL_EM_GATE_1_GRAY, GFX_SPECIAL_ARG_EDITOR,
+ IMG_EM_GATE_1_GRAY_EDITOR
+ },
+ {
+ EL_EM_GATE_2_GRAY, GFX_SPECIAL_ARG_EDITOR,
+ IMG_EM_GATE_2_GRAY_EDITOR
+ },
+ {
+ EL_EM_GATE_3_GRAY, GFX_SPECIAL_ARG_EDITOR,
+ IMG_EM_GATE_3_GRAY_EDITOR
+ },
+ {
+ EL_EM_GATE_4_GRAY, GFX_SPECIAL_ARG_EDITOR,
+ IMG_EM_GATE_4_GRAY_EDITOR
+ },
+ {
+ EL_INVISIBLE_STEELWALL, GFX_SPECIAL_ARG_EDITOR,
+ IMG_INVISIBLE_STEELWALL_EDITOR
+ },
+ {
+ EL_INVISIBLE_WALL, GFX_SPECIAL_ARG_EDITOR,
+ IMG_INVISIBLE_WALL_EDITOR
+ },
+ {
+ EL_INVISIBLE_SAND, GFX_SPECIAL_ARG_EDITOR,
+ IMG_INVISIBLE_SAND_EDITOR
+ },
+ {
+ EL_KEY_1, GFX_SPECIAL_ARG_EDITOR,
+ IMG_KEY_1_EDITOR
+ },
+ {
+ EL_KEY_2, GFX_SPECIAL_ARG_EDITOR,
+ IMG_KEY_2_EDITOR
+ },
+ {
+ EL_KEY_3, GFX_SPECIAL_ARG_EDITOR,
+ IMG_KEY_3_EDITOR
+ },
+ {
+ EL_KEY_4, GFX_SPECIAL_ARG_EDITOR,
+ IMG_KEY_4_EDITOR
+ },
+ {
+ EL_GATE_1_GRAY, GFX_SPECIAL_ARG_EDITOR,
+ IMG_GATE_1_GRAY_EDITOR
+ },
+ {
+ EL_GATE_2_GRAY, GFX_SPECIAL_ARG_EDITOR,
+ IMG_GATE_2_GRAY_EDITOR
+ },
+ {
+ EL_GATE_3_GRAY, GFX_SPECIAL_ARG_EDITOR,
+ IMG_GATE_3_GRAY_EDITOR
+ },
+ {
+ EL_GATE_4_GRAY, GFX_SPECIAL_ARG_EDITOR,
+ IMG_GATE_4_GRAY_EDITOR
+ },
+ {
+ EL_LAMP, GFX_SPECIAL_ARG_EDITOR,
+ IMG_LAMP_EDITOR
+ },
+ {
+ EL_EXPANDABLE_WALL_HORIZONTAL, GFX_SPECIAL_ARG_EDITOR,
+ IMG_EXPANDABLE_WALL_HORIZONTAL_EDITOR
+ },
+ {
+ EL_EXPANDABLE_WALL_VERTICAL, GFX_SPECIAL_ARG_EDITOR,
+ IMG_EXPANDABLE_WALL_VERTICAL_EDITOR
+ },
+ {
+ EL_EXPANDABLE_WALL_ANY, GFX_SPECIAL_ARG_EDITOR,
+ IMG_EXPANDABLE_WALL_ANY_EDITOR
+ },
+ {
+ EL_PENGUIN, GFX_SPECIAL_ARG_EDITOR,
+ IMG_PENGUIN_EDITOR
+ },
+ {
+ EL_PLAYER_1, GFX_SPECIAL_ARG_EDITOR,
+ IMG_PLAYER_1_EDITOR
+ },
+ {
+ EL_PLAYER_2, GFX_SPECIAL_ARG_EDITOR,
+ IMG_PLAYER_2_EDITOR
+ },
+ {
+ EL_PLAYER_3, GFX_SPECIAL_ARG_EDITOR,
+ IMG_PLAYER_3_EDITOR
+ },
+ {
+ EL_PLAYER_4, GFX_SPECIAL_ARG_EDITOR,
+ IMG_PLAYER_4_EDITOR
+ },
+ {
+ EL_STEELWALL_TOPLEFT, GFX_SPECIAL_ARG_EDITOR,
+ IMG_STEELWALL_TOPLEFT_EDITOR
+ },
+ {
+ EL_STEELWALL_TOPRIGHT, GFX_SPECIAL_ARG_EDITOR,
+ IMG_STEELWALL_TOPRIGHT_EDITOR
+ },
+ {
+ EL_STEELWALL_BOTTOMLEFT, GFX_SPECIAL_ARG_EDITOR,
+ IMG_STEELWALL_BOTTOMLEFT_EDITOR
+ },
+ {
+ EL_STEELWALL_BOTTOMRIGHT, GFX_SPECIAL_ARG_EDITOR,
+ IMG_STEELWALL_BOTTOMRIGHT_EDITOR
+ },
+ {
+ EL_STEELWALL_HORIZONTAL, GFX_SPECIAL_ARG_EDITOR,
+ IMG_STEELWALL_HORIZONTAL_EDITOR
+ },
+ {
+ EL_STEELWALL_VERTICAL, GFX_SPECIAL_ARG_EDITOR,
+ IMG_STEELWALL_VERTICAL_EDITOR
+ },
+ {
+ EL_INVISIBLE_STEELWALL_TOPLEFT, GFX_SPECIAL_ARG_EDITOR,
+ IMG_INVISIBLE_STEELWALL_TOPLEFT_EDITOR
+ },
+ {
+ EL_INVISIBLE_STEELWALL_TOPRIGHT, GFX_SPECIAL_ARG_EDITOR,
+ IMG_INVISIBLE_STEELWALL_TOPRIGHT_EDITOR
+ },
+ {
+ EL_INVISIBLE_STEELWALL_BOTTOMLEFT, GFX_SPECIAL_ARG_EDITOR,
+ IMG_INVISIBLE_STEELWALL_BOTTOMLEFT_EDITOR
+ },
+ {
+ EL_INVISIBLE_STEELWALL_BOTTOMRIGHT, GFX_SPECIAL_ARG_EDITOR,
+ IMG_INVISIBLE_STEELWALL_BOTTOMRIGHT_EDITOR
+ },
+ {
+ EL_INVISIBLE_STEELWALL_HORIZONTAL, GFX_SPECIAL_ARG_EDITOR,
+ IMG_INVISIBLE_STEELWALL_HORIZONTAL_EDITOR
+ },
+ {
+ EL_INVISIBLE_STEELWALL_VERTICAL, GFX_SPECIAL_ARG_EDITOR,
+ IMG_INVISIBLE_STEELWALL_VERTICAL_EDITOR
+ },
+ {
+ EL_CUSTOM_1, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_1_EDITOR
+ },
+ {
+ EL_CUSTOM_2, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_2_EDITOR
+ },
+ {
+ EL_CUSTOM_3, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_3_EDITOR
+ },
+ {
+ EL_CUSTOM_4, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_4_EDITOR
+ },
+ {
+ EL_CUSTOM_5, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_5_EDITOR
+ },
+ {
+ EL_CUSTOM_6, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_6_EDITOR
+ },
+ {
+ EL_CUSTOM_7, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_7_EDITOR
+ },
+ {
+ EL_CUSTOM_8, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_8_EDITOR
+ },
+ {
+ EL_CUSTOM_9, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_9_EDITOR
+ },
+ {
+ EL_CUSTOM_10, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_10_EDITOR
+ },
+ {
+ EL_CUSTOM_11, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_11_EDITOR
+ },
+ {
+ EL_CUSTOM_12, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_12_EDITOR
+ },
+ {
+ EL_CUSTOM_13, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_13_EDITOR
+ },
+ {
+ EL_CUSTOM_14, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_14_EDITOR
+ },
+ {
+ EL_CUSTOM_15, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_15_EDITOR
+ },
+ {
+ EL_CUSTOM_16, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_16_EDITOR
+ },
+ {
+ EL_CUSTOM_17, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_17_EDITOR
+ },
+ {
+ EL_CUSTOM_18, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_18_EDITOR
+ },
+ {
+ EL_CUSTOM_19, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_19_EDITOR
+ },
+ {
+ EL_CUSTOM_20, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_20_EDITOR
+ },
+ {
+ EL_CUSTOM_21, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_21_EDITOR
+ },
+ {
+ EL_CUSTOM_22, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_22_EDITOR
+ },
+ {
+ EL_CUSTOM_23, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_23_EDITOR
+ },
+ {
+ EL_CUSTOM_24, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_24_EDITOR
+ },
+ {
+ EL_CUSTOM_25, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_25_EDITOR
+ },
+ {
+ EL_CUSTOM_26, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_26_EDITOR
+ },
+ {
+ EL_CUSTOM_27, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_27_EDITOR
+ },
+ {
+ EL_CUSTOM_28, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_28_EDITOR
+ },
+ {
+ EL_CUSTOM_29, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_29_EDITOR
+ },
+ {
+ EL_CUSTOM_30, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_30_EDITOR
+ },
+ {
+ EL_CUSTOM_31, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_31_EDITOR
+ },
+ {
+ EL_CUSTOM_32, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_32_EDITOR
+ },
+ {
+ EL_CUSTOM_33, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_33_EDITOR
+ },
+ {
+ EL_CUSTOM_34, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_34_EDITOR
+ },
+ {
+ EL_CUSTOM_35, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_35_EDITOR
+ },
+ {
+ EL_CUSTOM_36, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_36_EDITOR
+ },
+ {
+ EL_CUSTOM_37, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_37_EDITOR
+ },
+ {
+ EL_CUSTOM_38, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_38_EDITOR
+ },
+ {
+ EL_CUSTOM_39, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_39_EDITOR
+ },
+ {
+ EL_CUSTOM_40, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_40_EDITOR
+ },
+ {
+ EL_CUSTOM_41, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_41_EDITOR
+ },
+ {
+ EL_CUSTOM_42, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_42_EDITOR
+ },
+ {
+ EL_CUSTOM_43, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_43_EDITOR
+ },
+ {
+ EL_CUSTOM_44, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_44_EDITOR
+ },
+ {
+ EL_CUSTOM_45, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_45_EDITOR
+ },
+ {
+ EL_CUSTOM_46, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_46_EDITOR
+ },
+ {
+ EL_CUSTOM_47, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_47_EDITOR
+ },
+ {
+ EL_CUSTOM_48, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_48_EDITOR
+ },
+ {
+ EL_CUSTOM_49, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_49_EDITOR
+ },
+ {
+ EL_CUSTOM_50, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_50_EDITOR
+ },
+ {
+ EL_CUSTOM_51, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_51_EDITOR
+ },
+ {
+ EL_CUSTOM_52, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_52_EDITOR
+ },
+ {
+ EL_CUSTOM_53, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_53_EDITOR
+ },
+ {
+ EL_CUSTOM_54, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_54_EDITOR
+ },
+ {
+ EL_CUSTOM_55, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_55_EDITOR
+ },
+ {
+ EL_CUSTOM_56, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_56_EDITOR
+ },
+ {
+ EL_CUSTOM_57, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_57_EDITOR
+ },
+ {
+ EL_CUSTOM_58, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_58_EDITOR
+ },
+ {
+ EL_CUSTOM_59, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_59_EDITOR
+ },
+ {
+ EL_CUSTOM_60, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_60_EDITOR
+ },
+ {
+ EL_CUSTOM_61, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_61_EDITOR
+ },
+ {
+ EL_CUSTOM_62, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_62_EDITOR
+ },
+ {
+ EL_CUSTOM_63, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_63_EDITOR
+ },
+ {
+ EL_CUSTOM_64, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_64_EDITOR
+ },
+ {
+ EL_CUSTOM_65, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_65_EDITOR
+ },
+ {
+ EL_CUSTOM_66, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_66_EDITOR
+ },
+ {
+ EL_CUSTOM_67, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_67_EDITOR
+ },
+ {
+ EL_CUSTOM_68, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_68_EDITOR
+ },
+ {
+ EL_CUSTOM_69, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_69_EDITOR
+ },
+ {
+ EL_CUSTOM_70, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_70_EDITOR
+ },
+ {
+ EL_CUSTOM_71, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_71_EDITOR
+ },
+ {
+ EL_CUSTOM_72, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_72_EDITOR
+ },
+ {
+ EL_CUSTOM_73, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_73_EDITOR
+ },
+ {
+ EL_CUSTOM_74, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_74_EDITOR
+ },
+ {
+ EL_CUSTOM_75, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_75_EDITOR
+ },
+ {
+ EL_CUSTOM_76, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_76_EDITOR
+ },
+ {
+ EL_CUSTOM_77, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_77_EDITOR
+ },
+ {
+ EL_CUSTOM_78, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_78_EDITOR
+ },
+ {
+ EL_CUSTOM_79, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_79_EDITOR
+ },
+ {
+ EL_CUSTOM_80, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_80_EDITOR
+ },
+ {
+ EL_CUSTOM_81, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_81_EDITOR
+ },
+ {
+ EL_CUSTOM_82, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_82_EDITOR
+ },
+ {
+ EL_CUSTOM_83, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_83_EDITOR
+ },
+ {
+ EL_CUSTOM_84, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_84_EDITOR
+ },
+ {
+ EL_CUSTOM_85, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_85_EDITOR
+ },
+ {
+ EL_CUSTOM_86, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_86_EDITOR
+ },
+ {
+ EL_CUSTOM_87, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_87_EDITOR
+ },
+ {
+ EL_CUSTOM_88, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_88_EDITOR
+ },
+ {
+ EL_CUSTOM_89, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_89_EDITOR
+ },
+ {
+ EL_CUSTOM_90, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_90_EDITOR
+ },
+ {
+ EL_CUSTOM_91, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_91_EDITOR
+ },
+ {
+ EL_CUSTOM_92, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_92_EDITOR
+ },
+ {
+ EL_CUSTOM_93, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_93_EDITOR
+ },
+ {
+ EL_CUSTOM_94, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_94_EDITOR
+ },
+ {
+ EL_CUSTOM_95, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_95_EDITOR
+ },
+ {
+ EL_CUSTOM_96, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_96_EDITOR
+ },
+ {
+ EL_CUSTOM_97, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_97_EDITOR
+ },
+ {
+ EL_CUSTOM_98, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_98_EDITOR
+ },
+ {
+ EL_CUSTOM_99, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_99_EDITOR
+ },
+ {
+ EL_CUSTOM_100, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_100_EDITOR
+ },
+ {
+ EL_CUSTOM_101, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_101_EDITOR
+ },
+ {
+ EL_CUSTOM_102, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_102_EDITOR
+ },
+ {
+ EL_CUSTOM_103, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_103_EDITOR
+ },
+ {
+ EL_CUSTOM_104, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_104_EDITOR
+ },
+ {
+ EL_CUSTOM_105, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_105_EDITOR
+ },
+ {
+ EL_CUSTOM_106, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_106_EDITOR
+ },
+ {
+ EL_CUSTOM_107, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_107_EDITOR
+ },
+ {
+ EL_CUSTOM_108, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_108_EDITOR
+ },
+ {
+ EL_CUSTOM_109, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_109_EDITOR
+ },
+ {
+ EL_CUSTOM_110, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_110_EDITOR
+ },
+ {
+ EL_CUSTOM_111, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_111_EDITOR
+ },
+ {
+ EL_CUSTOM_112, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_112_EDITOR
+ },
+ {
+ EL_CUSTOM_113, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_113_EDITOR
+ },
+ {
+ EL_CUSTOM_114, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_114_EDITOR
+ },
+ {
+ EL_CUSTOM_115, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_115_EDITOR
+ },
+ {
+ EL_CUSTOM_116, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_116_EDITOR
+ },
+ {
+ EL_CUSTOM_117, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_117_EDITOR
+ },
+ {
+ EL_CUSTOM_118, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_118_EDITOR
+ },
+ {
+ EL_CUSTOM_119, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_119_EDITOR
+ },
+ {
+ EL_CUSTOM_120, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_120_EDITOR
+ },
+ {
+ EL_CUSTOM_121, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_121_EDITOR
+ },
+ {
+ EL_CUSTOM_122, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_122_EDITOR
+ },
+ {
+ EL_CUSTOM_123, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_123_EDITOR
+ },
+ {
+ EL_CUSTOM_124, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_124_EDITOR
+ },
+ {
+ EL_CUSTOM_125, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_125_EDITOR
+ },
+ {
+ EL_CUSTOM_126, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_126_EDITOR
+ },
+ {
+ EL_CUSTOM_127, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_127_EDITOR
+ },
+ {
+ EL_CUSTOM_128, GFX_SPECIAL_ARG_EDITOR,
+ IMG_CUSTOM_128_EDITOR
+ },
+ {
+ -1, -1,
+ -1
+ },
+};
+
+#endif /* CONF_ESG_C */
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* (c) 1995-2002 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* conf_fnt.c *
+***********************************************************/
+
+/* ----- this file was automatically generated -- do not edit by hand ----- */
+
+#ifndef CONF_FNT_C
+#define CONF_FNT_C
+
+/* values for font/graphics mapping configuration */
+
+static struct
+{
+ int font_nr;
+ int special;
+
+ int graphic;
+}
+font_to_graphic[] =
+{
+ {
+ FONT_INITIAL_1, -1,
+ IMG_FONT_INITIAL_1
+ },
+ {
+ FONT_INITIAL_2, -1,
+ IMG_FONT_INITIAL_2
+ },
+ {
+ FONT_INITIAL_3, -1,
+ IMG_FONT_INITIAL_3
+ },
+ {
+ FONT_INITIAL_4, -1,
+ IMG_FONT_INITIAL_4
+ },
+ {
+ FONT_TITLE_1, -1,
+ IMG_FONT_TITLE_1
+ },
+ {
+ FONT_TITLE_1, GFX_SPECIAL_ARG_LEVELS,
+ IMG_FONT_TITLE_1_LEVELS
+ },
+ {
+ FONT_TITLE_2, -1,
+ IMG_FONT_TITLE_2
+ },
+ {
+ FONT_MENU_1, -1,
+ IMG_FONT_MENU_1
+ },
+ {
+ FONT_MENU_2, -1,
+ IMG_FONT_MENU_2
+ },
+ {
+ FONT_TEXT_1, -1,
+ IMG_FONT_TEXT_1
+ },
+ {
+ FONT_TEXT_1, GFX_SPECIAL_ARG_LEVELS,
+ IMG_FONT_TEXT_1_LEVELS
+ },
+ {
+ FONT_TEXT_1, GFX_SPECIAL_ARG_PREVIEW,
+ IMG_FONT_TEXT_1_PREVIEW
+ },
+ {
+ FONT_TEXT_1, GFX_SPECIAL_ARG_SCORES,
+ IMG_FONT_TEXT_1_SCORES
+ },
+ {
+ FONT_TEXT_1_ACTIVE, GFX_SPECIAL_ARG_SCORES,
+ IMG_FONT_TEXT_1_ACTIVE_SCORES
+ },
+ {
+ FONT_TEXT_2, -1,
+ IMG_FONT_TEXT_2
+ },
+ {
+ FONT_TEXT_2, GFX_SPECIAL_ARG_LEVELS,
+ IMG_FONT_TEXT_2_LEVELS
+ },
+ {
+ FONT_TEXT_2, GFX_SPECIAL_ARG_PREVIEW,
+ IMG_FONT_TEXT_2_PREVIEW
+ },
+ {
+ FONT_TEXT_2, GFX_SPECIAL_ARG_SCORES,
+ IMG_FONT_TEXT_2_SCORES
+ },
+ {
+ FONT_TEXT_2_ACTIVE, GFX_SPECIAL_ARG_SCORES,
+ IMG_FONT_TEXT_2_ACTIVE_SCORES
+ },
+ {
+ FONT_TEXT_3, -1,
+ IMG_FONT_TEXT_3
+ },
+ {
+ FONT_TEXT_3, GFX_SPECIAL_ARG_LEVELS,
+ IMG_FONT_TEXT_3_LEVELS
+ },
+ {
+ FONT_TEXT_3, GFX_SPECIAL_ARG_PREVIEW,
+ IMG_FONT_TEXT_3_PREVIEW
+ },
+ {
+ FONT_TEXT_3, GFX_SPECIAL_ARG_SCORES,
+ IMG_FONT_TEXT_3_SCORES
+ },
+ {
+ FONT_TEXT_3_ACTIVE, GFX_SPECIAL_ARG_SCORES,
+ IMG_FONT_TEXT_3_ACTIVE_SCORES
+ },
+ {
+ FONT_TEXT_4, -1,
+ IMG_FONT_TEXT_4
+ },
+ {
+ FONT_TEXT_4, GFX_SPECIAL_ARG_LEVELS,
+ IMG_FONT_TEXT_4_LEVELS
+ },
+ {
+ FONT_TEXT_4, GFX_SPECIAL_ARG_SCORES,
+ IMG_FONT_TEXT_4_SCORES
+ },
+ {
+ FONT_TEXT_4_ACTIVE, GFX_SPECIAL_ARG_SCORES,
+ IMG_FONT_TEXT_4_ACTIVE_SCORES
+ },
+ {
+ FONT_INPUT_1, -1,
+ IMG_FONT_INPUT_1
+ },
+ {
+ FONT_INPUT_1, GFX_SPECIAL_ARG_MAIN,
+ IMG_FONT_INPUT_1_MAIN
+ },
+ {
+ FONT_INPUT_1_ACTIVE, -1,
+ IMG_FONT_INPUT_1_ACTIVE
+ },
+ {
+ FONT_INPUT_1_ACTIVE, GFX_SPECIAL_ARG_MAIN,
+ IMG_FONT_INPUT_1_ACTIVE_MAIN
+ },
+ {
+ FONT_INPUT_1_ACTIVE, GFX_SPECIAL_ARG_SETUP,
+ IMG_FONT_INPUT_1_ACTIVE_SETUP
+ },
+ {
+ FONT_INPUT_2, -1,
+ IMG_FONT_INPUT_2
+ },
+ {
+ FONT_INPUT_2_ACTIVE, -1,
+ IMG_FONT_INPUT_2_ACTIVE
+ },
+ {
+ FONT_OPTION_OFF, -1,
+ IMG_FONT_OPTION_OFF
+ },
+ {
+ FONT_OPTION_ON, -1,
+ IMG_FONT_OPTION_ON
+ },
+ {
+ FONT_VALUE_1, -1,
+ IMG_FONT_VALUE_1
+ },
+ {
+ FONT_VALUE_2, -1,
+ IMG_FONT_VALUE_2
+ },
+ {
+ FONT_VALUE_OLD, -1,
+ IMG_FONT_VALUE_OLD
+ },
+ {
+ FONT_LEVEL_NUMBER, -1,
+ IMG_FONT_LEVEL_NUMBER
+ },
+ {
+ FONT_TAPE_RECORDER, -1,
+ IMG_FONT_TAPE_RECORDER
+ },
+ {
+ FONT_GAME_INFO, -1,
+ IMG_FONT_GAME_INFO
+ },
+ {
+ -1, -1,
+ -1
+ },
+};
+
+#endif /* CONF_FNT_C */
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* (c) 1995-2002 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* conf_gfx.c *
+***********************************************************/
+
+#include "libgame/libgame.h"
+#include "main.h"
+
+
+/* List values that are not defined in the configuration file are set to
+ 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[] =
+{
+ { ".x", ARG_UNDEFINED, TYPE_INTEGER },
+ { ".y", ARG_UNDEFINED, TYPE_INTEGER },
+ { ".xpos", 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 },
+ { ".xoffset", ARG_UNDEFINED, TYPE_INTEGER },
+ { ".yoffset", ARG_UNDEFINED, TYPE_INTEGER },
+ { ".frames", ARG_UNDEFINED, TYPE_INTEGER },
+ { ".frames_per_line", ARG_UNDEFINED, TYPE_INTEGER },
+ { ".start_frame", ARG_UNDEFINED, TYPE_INTEGER },
+ { ".delay", "1", TYPE_INTEGER },
+ { ".anim_mode", ARG_UNDEFINED, TYPE_STRING },
+ { ".global_sync", "false", TYPE_BOOLEAN },
+ { ".crumbled_like", ARG_UNDEFINED, TYPE_TOKEN },
+ { ".diggable_like", ARG_UNDEFINED, TYPE_TOKEN },
+ { ".step_offset", "4", TYPE_INTEGER },
+ { ".step_delay", "1", TYPE_INTEGER },
+ { ".direction", ARG_UNDEFINED, TYPE_STRING },
+ { ".position", ARG_UNDEFINED, TYPE_STRING },
+ { ".draw_xoffset", "0", TYPE_INTEGER },
+ { ".draw_yoffset", "0", TYPE_INTEGER },
+ { ".name", ARG_UNDEFINED, TYPE_STRING },
+
+ { NULL, NULL, 0 }
+};
+
+struct ConfigInfo image_config[] =
+{
+ /* images for Boulder Dash style elements and actions */
+
+ { "bd_wall", "RocksDC.pcx" },
+ { "bd_wall.xpos", "12" },
+ { "bd_wall.ypos", "9" },
+ { "bd_wall.frames", "1" },
+ { "bd_wall.EDITOR", "RocksDC.pcx" },
+ { "bd_wall.EDITOR.xpos", "14" },
+ { "bd_wall.EDITOR.ypos", "13" },
+
+ { "bd_rock", "RocksDC.pcx" },
+ { "bd_rock.xpos", "12" },
+ { "bd_rock.ypos", "10" },
+ { "bd_rock.frames", "1" },
+ { "bd_rock.EDITOR", "RocksDC.pcx" },
+ { "bd_rock.EDITOR.xpos", "14" },
+ { "bd_rock.EDITOR.ypos", "14" },
+ { "bd_rock.moving.left", "RocksDC.pcx" },
+ { "bd_rock.moving.left.xpos", "12" },
+ { "bd_rock.moving.left.ypos", "10" },
+ { "bd_rock.moving.left.frames", "4" },
+ { "bd_rock.moving.left.delay", "2" },
+ { "bd_rock.moving.left.anim_mode", "reverse" },
+ { "bd_rock.moving.right", "RocksDC.pcx" },
+ { "bd_rock.moving.right.xpos", "12" },
+ { "bd_rock.moving.right.ypos", "10" },
+ { "bd_rock.moving.right.frames", "4" },
+ { "bd_rock.moving.right.start_frame", "1" },
+ { "bd_rock.moving.right.delay", "2" },
+ { "bd_rock.pushing.left", "RocksDC.pcx" },
+ { "bd_rock.pushing.left.xpos", "12" },
+ { "bd_rock.pushing.left.ypos", "10" },
+ { "bd_rock.pushing.left.frames", "4" },
+ { "bd_rock.pushing.left.delay", "2" },
+ { "bd_rock.pushing.left.anim_mode", "reverse" },
+ { "bd_rock.pushing.right", "RocksDC.pcx" },
+ { "bd_rock.pushing.right.xpos", "12" },
+ { "bd_rock.pushing.right.ypos", "10" },
+ { "bd_rock.pushing.right.frames", "4" },
+ { "bd_rock.pushing.right.start_frame", "1" },
+ { "bd_rock.pushing.right.delay", "2" },
+
+ { "bd_diamond", "RocksElements.pcx" },
+ { "bd_diamond.xpos", "0" },
+ { "bd_diamond.ypos", "10" },
+ { "bd_diamond.frames", "4" },
+ { "bd_diamond.delay", "4" },
+ { "bd_diamond.anim_mode", "reverse" },
+ { "bd_diamond.moving", "RocksElements.pcx" },
+ { "bd_diamond.moving.xpos", "3" },
+ { "bd_diamond.moving.ypos", "10" },
+ { "bd_diamond.moving.frames", "2" },
+ { "bd_diamond.moving.delay", "4" },
+ { "bd_diamond.falling", "RocksElements.pcx" },
+ { "bd_diamond.falling.xpos", "3" },
+ { "bd_diamond.falling.ypos", "10" },
+ { "bd_diamond.falling.frames", "2" },
+ { "bd_diamond.falling.delay", "4" },
+
+ { "bd_magic_wall", "RocksElements.pcx" },
+ { "bd_magic_wall.xpos", "12" },
+ { "bd_magic_wall.ypos", "10" },
+ { "bd_magic_wall.frames", "1" },
+ { "bd_magic_wall.active", "RocksElements.pcx" },
+ { "bd_magic_wall.active.xpos", "12" },
+ { "bd_magic_wall.active.ypos", "10" },
+ { "bd_magic_wall.active.frames", "4" },
+ { "bd_magic_wall.active.anim_mode", "reverse" },
+ { "bd_magic_wall.active.delay", "4" },
+ { "bd_magic_wall.active.global_sync", "true" },
+ { "bd_magic_wall.filling", "RocksElements.pcx" },
+ { "bd_magic_wall.filling.xpos", "12" },
+ { "bd_magic_wall.filling.ypos", "10" },
+ { "bd_magic_wall.filling.frames", "4" },
+ { "bd_magic_wall.filling.anim_mode", "reverse" },
+ { "bd_magic_wall.filling.delay", "4" },
+ { "bd_magic_wall.filling.global_sync", "true" },
+ { "bd_magic_wall_full", "RocksElements.pcx" },
+ { "bd_magic_wall_full.xpos", "12" },
+ { "bd_magic_wall_full.ypos", "10" },
+ { "bd_magic_wall_full.frames", "4" },
+ { "bd_magic_wall_full.anim_mode", "reverse" },
+ { "bd_magic_wall_full.delay", "4" },
+ { "bd_magic_wall_full.global_sync", "true" },
+ { "bd_magic_wall.emptying", "RocksElements.pcx" },
+ { "bd_magic_wall.emptying.xpos", "12" },
+ { "bd_magic_wall.emptying.ypos", "10" },
+ { "bd_magic_wall.emptying.frames", "4" },
+ { "bd_magic_wall.emptying.anim_mode", "reverse" },
+ { "bd_magic_wall.emptying.delay", "4" },
+ { "bd_magic_wall.emptying.global_sync", "true" },
+ { "bd_magic_wall_dead", "RocksElements.pcx" },
+ { "bd_magic_wall_dead.xpos", "12" },
+ { "bd_magic_wall_dead.ypos", "10" },
+ { "bd_magic_wall_dead.frames", "1" },
+
+ { "bd_amoeba", "RocksElements.pcx" },
+ { "bd_amoeba.xpos", "8" },
+ { "bd_amoeba.ypos", "6" },
+ { "bd_amoeba.frames", "4" },
+ { "bd_amoeba.delay", "1000000" },
+ { "bd_amoeba.anim_mode", "random" },
+ { "bd_amoeba.EDITOR", "RocksElements.pcx" },
+ { "bd_amoeba.EDITOR.xpos", "8" },
+ { "bd_amoeba.EDITOR.ypos", "7" },
+
+ { "bd_butterfly", "RocksElements.pcx" },
+ { "bd_butterfly.xpos", "4" },
+ { "bd_butterfly.ypos", "12" },
+ { "bd_butterfly.frames", "2" },
+ { "bd_butterfly.anim_mode", "pingpong" },
+ { "bd_butterfly.delay", "4" },
+ { "bd_butterfly.right", "RocksElements.pcx" },
+ { "bd_butterfly.right.xpos", "8" },
+ { "bd_butterfly.right.ypos", "12" },
+ { "bd_butterfly.right.frames", "1" },
+ { "bd_butterfly.up", "RocksElements.pcx" },
+ { "bd_butterfly.up.xpos", "9" },
+ { "bd_butterfly.up.ypos", "12" },
+ { "bd_butterfly.up.frames", "1" },
+ { "bd_butterfly.left", "RocksElements.pcx" },
+ { "bd_butterfly.left.xpos", "10" },
+ { "bd_butterfly.left.ypos", "12" },
+ { "bd_butterfly.left.frames", "1" },
+ { "bd_butterfly.down", "RocksElements.pcx" },
+ { "bd_butterfly.down.xpos", "11" },
+ { "bd_butterfly.down.ypos", "12" },
+ { "bd_butterfly.down.frames", "1" },
+ { "bd_butterfly.moving", "RocksElements.pcx" },
+ { "bd_butterfly.moving.xpos", "4" },
+ { "bd_butterfly.moving.ypos", "12" },
+ { "bd_butterfly.moving.frames", "2" },
+ { "bd_butterfly.moving.anim_mode", "pingpong" },
+ { "bd_butterfly.moving.delay", "4" },
+
+ { "bd_firefly", "RocksElements.pcx" },
+ { "bd_firefly.xpos", "6" },
+ { "bd_firefly.ypos", "12" },
+ { "bd_firefly.frames", "2" },
+ { "bd_firefly.anim_mode", "pingpong" },
+ { "bd_firefly.delay", "4" },
+ { "bd_firefly.right", "RocksElements.pcx" },
+ { "bd_firefly.right.xpos", "12" },
+ { "bd_firefly.right.ypos", "12" },
+ { "bd_firefly.right.frames", "1" },
+ { "bd_firefly.up", "RocksElements.pcx" },
+ { "bd_firefly.up.xpos", "13" },
+ { "bd_firefly.up.ypos", "12" },
+ { "bd_firefly.up.frames", "1" },
+ { "bd_firefly.left", "RocksElements.pcx" },
+ { "bd_firefly.left.xpos", "14" },
+ { "bd_firefly.left.ypos", "12" },
+ { "bd_firefly.left.frames", "1" },
+ { "bd_firefly.down", "RocksElements.pcx" },
+ { "bd_firefly.down.xpos", "15" },
+ { "bd_firefly.down.ypos", "12" },
+ { "bd_firefly.down.frames", "1" },
+ { "bd_firefly.moving", "RocksElements.pcx" },
+ { "bd_firefly.moving.xpos", "6" },
+ { "bd_firefly.moving.ypos", "12" },
+ { "bd_firefly.moving.frames", "2" },
+ { "bd_firefly.moving.anim_mode", "pingpong" },
+ { "bd_firefly.moving.delay", "4" },
+
+ /* images for Supaplex style elements and actions */
+
+ { "[sp_default].exploding", "RocksSP.pcx" },
+ { "[sp_default].exploding.xpos", "8" },
+ { "[sp_default].exploding.ypos", "3" },
+ { "[sp_default].exploding.frames", "8" },
+ { "[sp_default].exploding.delay", "3" },
+ { "[sp_default].exploding.anim_mode", "linear" },
+
+ { "sp_empty_space", "RocksSP.pcx" },
+ { "sp_empty_space.xpos", "0" },
+ { "sp_empty_space.ypos", "0" },
+ { "sp_empty_space.frames", "1" },
+
+ { "sp_zonk", "RocksSP.pcx" },
+ { "sp_zonk.xpos", "1" },
+ { "sp_zonk.ypos", "0" },
+ { "sp_zonk.frames", "1" },
+ { "sp_zonk.moving.left", "RocksSP.pcx" },
+ { "sp_zonk.moving.left.xpos", "0" },
+ { "sp_zonk.moving.left.ypos", "6" },
+ { "sp_zonk.moving.left.frames", "4" },
+ { "sp_zonk.moving.left.delay", "2" },
+ { "sp_zonk.moving.left.anim_mode", "reverse" },
+ { "sp_zonk.moving.right", "RocksSP.pcx" },
+ { "sp_zonk.moving.right.xpos", "0" },
+ { "sp_zonk.moving.right.ypos", "6" },
+ { "sp_zonk.moving.right.frames", "4" },
+ { "sp_zonk.moving.right.start_frame", "1" },
+ { "sp_zonk.moving.right.delay", "2" },
+ { "sp_zonk.pushing.left", "RocksSP.pcx" },
+ { "sp_zonk.pushing.left.xpos", "0" },
+ { "sp_zonk.pushing.left.ypos", "6" },
+ { "sp_zonk.pushing.left.frames", "4" },
+ { "sp_zonk.pushing.left.delay", "2" },
+ { "sp_zonk.pushing.left.anim_mode", "reverse" },
+ { "sp_zonk.pushing.right", "RocksSP.pcx" },
+ { "sp_zonk.pushing.right.xpos", "0" },
+ { "sp_zonk.pushing.right.ypos", "6" },
+ { "sp_zonk.pushing.right.frames", "4" },
+ { "sp_zonk.pushing.right.start_frame", "1" },
+ { "sp_zonk.pushing.right.delay", "2" },
+
+ { "sp_base", "RocksSP.pcx" },
+ { "sp_base.xpos", "2" },
+ { "sp_base.ypos", "0" },
+ { "sp_base.frames", "1" },
+
+ { "sp_murphy", "RocksSP.pcx" },
+ { "sp_murphy.xpos", "3" },
+ { "sp_murphy.ypos", "0" },
+ { "sp_murphy.frames", "1" },
+ { "sp_murphy.moving.left", "RocksSP.pcx" },
+ { "sp_murphy.moving.left.xpos", "8" },
+ { "sp_murphy.moving.left.ypos", "0" },
+ { "sp_murphy.moving.left.frames", "3" },
+ { "sp_murphy.moving.left.anim_mode", "pingpong" },
+ { "sp_murphy.moving.left.delay", "2" },
+ { "sp_murphy.moving.right", "RocksSP.pcx" },
+ { "sp_murphy.moving.right.xpos", "11" },
+ { "sp_murphy.moving.right.ypos", "0" },
+ { "sp_murphy.moving.right.frames", "3" },
+ { "sp_murphy.moving.right.anim_mode", "pingpong" },
+ { "sp_murphy.moving.right.delay", "2" },
+ { "sp_murphy.digging.left", "RocksSP.pcx" },
+ { "sp_murphy.digging.left.xpos", "8" },
+ { "sp_murphy.digging.left.ypos", "0" },
+ { "sp_murphy.digging.left.frames", "3" },
+ { "sp_murphy.digging.left.anim_mode", "pingpong" },
+ { "sp_murphy.digging.left.delay", "2" },
+ { "sp_murphy.digging.right", "RocksSP.pcx" },
+ { "sp_murphy.digging.right.xpos", "11" },
+ { "sp_murphy.digging.right.ypos", "0" },
+ { "sp_murphy.digging.right.frames", "3" },
+ { "sp_murphy.digging.right.anim_mode", "pingpong" },
+ { "sp_murphy.digging.right.delay", "2" },
+ { "sp_murphy.collecting.left", "RocksSP.pcx" },
+ { "sp_murphy.collecting.left.xpos", "8" },
+ { "sp_murphy.collecting.left.ypos", "0" },
+ { "sp_murphy.collecting.left.frames", "3" },
+ { "sp_murphy.collecting.left.anim_mode", "pingpong" },
+ { "sp_murphy.collecting.left.delay", "2" },
+ { "sp_murphy.collecting.right", "RocksSP.pcx" },
+ { "sp_murphy.collecting.right.xpos", "11" },
+ { "sp_murphy.collecting.right.ypos", "0" },
+ { "sp_murphy.collecting.right.frames", "3" },
+ { "sp_murphy.collecting.right.anim_mode", "pingpong" },
+ { "sp_murphy.collecting.right.delay", "2" },
+ { "sp_murphy.pushing.left", "RocksSP.pcx" },
+ { "sp_murphy.pushing.left.xpos", "11" },
+ { "sp_murphy.pushing.left.ypos", "1" },
+ { "sp_murphy.pushing.left.frames", "1" },
+ { "sp_murphy.pushing.right", "RocksSP.pcx" },
+ { "sp_murphy.pushing.right.xpos", "10" },
+ { "sp_murphy.pushing.right.ypos", "1" },
+ { "sp_murphy.pushing.right.frames", "1" },
+ { "sp_murphy.snapping.left", "RocksSP.pcx" },
+ { "sp_murphy.snapping.left.xpos", "9" },
+ { "sp_murphy.snapping.left.ypos", "1" },
+ { "sp_murphy.snapping.left.frames", "1" },
+ { "sp_murphy.snapping.right", "RocksSP.pcx" },
+ { "sp_murphy.snapping.right.xpos", "8" },
+ { "sp_murphy.snapping.right.ypos", "1" },
+ { "sp_murphy.snapping.right.frames", "1" },
+ { "sp_murphy.snapping.up", "RocksSP.pcx" },
+ { "sp_murphy.snapping.up.xpos", "14" },
+ { "sp_murphy.snapping.up.ypos", "0" },
+ { "sp_murphy.snapping.up.frames", "1" },
+ { "sp_murphy.snapping.down", "RocksSP.pcx" },
+ { "sp_murphy.snapping.down.xpos", "15" },
+ { "sp_murphy.snapping.down.ypos", "0" },
+ { "sp_murphy.snapping.down.frames", "1" },
+
+ { "sp_murphy_clone", "RocksSP.pcx" },
+ { "sp_murphy_clone.xpos", "3" },
+ { "sp_murphy_clone.ypos", "0" },
+ { "sp_murphy_clone.frames", "1" },
+
+ { "sp_infotron", "RocksSP.pcx" },
+ { "sp_infotron.xpos", "4" },
+ { "sp_infotron.ypos", "0" },
+ { "sp_infotron.frames", "1" },
+ { "sp_infotron.EDITOR", "RocksSP.pcx" },
+ { "sp_infotron.EDITOR.xpos", "8" },
+ { "sp_infotron.EDITOR.ypos", "11" },
+
+ { "sp_chip_single", "RocksSP.pcx" },
+ { "sp_chip_single.xpos", "5" },
+ { "sp_chip_single.ypos", "0" },
+ { "sp_chip_single.frames", "1" },
+ { "sp_chip_left", "RocksSP.pcx" },
+ { "sp_chip_left.xpos", "2" },
+ { "sp_chip_left.ypos", "3" },
+ { "sp_chip_left.frames", "1" },
+ { "sp_chip_right", "RocksSP.pcx" },
+ { "sp_chip_right.xpos", "3" },
+ { "sp_chip_right.ypos", "3" },
+ { "sp_chip_right.frames", "1" },
+ { "sp_chip_top", "RocksSP.pcx" },
+ { "sp_chip_top.xpos", "6" },
+ { "sp_chip_top.ypos", "4" },
+ { "sp_chip_top.frames", "1" },
+ { "sp_chip_bottom", "RocksSP.pcx" },
+ { "sp_chip_bottom.xpos", "7" },
+ { "sp_chip_bottom.ypos", "4" },
+ { "sp_chip_bottom.frames", "1" },
+
+ { "sp_hardware_gray", "RocksSP.pcx" },
+ { "sp_hardware_gray.xpos", "6" },
+ { "sp_hardware_gray.ypos", "0" },
+ { "sp_hardware_gray.frames", "1" },
+ { "sp_hardware_green", "RocksSP.pcx" },
+ { "sp_hardware_green.xpos", "5" },
+ { "sp_hardware_green.ypos", "3" },
+ { "sp_hardware_green.frames", "1" },
+ { "sp_hardware_blue", "RocksSP.pcx" },
+ { "sp_hardware_blue.xpos", "6" },
+ { "sp_hardware_blue.ypos", "3" },
+ { "sp_hardware_blue.frames", "1" },
+ { "sp_hardware_red", "RocksSP.pcx" },
+ { "sp_hardware_red.xpos", "7" },
+ { "sp_hardware_red.ypos", "3" },
+ { "sp_hardware_red.frames", "1" },
+ { "sp_hardware_yellow", "RocksSP.pcx" },
+ { "sp_hardware_yellow.xpos", "0" },
+ { "sp_hardware_yellow.ypos", "4" },
+ { "sp_hardware_yellow.frames", "1" },
+
+ { "sp_exit_closed", "RocksSP.pcx" },
+ { "sp_exit_closed.xpos", "7" },
+ { "sp_exit_closed.ypos", "0" },
+ { "sp_exit_closed.frames", "1" },
+ { "sp_exit_open", "RocksSP.pcx" },
+ { "sp_exit_open.xpos", "7" },
+ { "sp_exit_open.ypos", "0" },
+ { "sp_exit_open.frames", "1" },
+
+ { "sp_disk_orange", "RocksSP.pcx" },
+ { "sp_disk_orange.xpos", "0" },
+ { "sp_disk_orange.ypos", "1" },
+ { "sp_disk_orange.frames", "1" },
+
+ { "sp_disk_yellow", "RocksSP.pcx" },
+ { "sp_disk_yellow.xpos", "2" },
+ { "sp_disk_yellow.ypos", "2" },
+ { "sp_disk_yellow.frames", "1" },
+
+ { "sp_disk_red", "RocksSP.pcx" },
+ { "sp_disk_red.xpos", "4" },
+ { "sp_disk_red.ypos", "2" },
+ { "sp_disk_red.frames", "1" },
+ { "sp_disk_red.collecting", "RocksSP.pcx" },
+ { "sp_disk_red.collecting.xpos", "8" },
+ { "sp_disk_red.collecting.ypos", "5" },
+ { "sp_disk_red.collecting.frames", "8" },
+
+ { "sp_port_right", "RocksSP.pcx" },
+ { "sp_port_right.xpos", "1" },
+ { "sp_port_right.ypos", "1" },
+ { "sp_port_right.frames", "1" },
+ { "sp_port_down", "RocksSP.pcx" },
+ { "sp_port_down.xpos", "2" },
+ { "sp_port_down.ypos", "1" },
+ { "sp_port_down.frames", "1" },
+ { "sp_port_left", "RocksSP.pcx" },
+ { "sp_port_left.xpos", "3" },
+ { "sp_port_left.ypos", "1" },
+ { "sp_port_left.frames", "1" },
+ { "sp_port_up", "RocksSP.pcx" },
+ { "sp_port_up.xpos", "4" },
+ { "sp_port_up.ypos", "1" },
+ { "sp_port_up.frames", "1" },
+ { "sp_port_horizontal", "RocksSP.pcx" },
+ { "sp_port_horizontal.xpos", "6" },
+ { "sp_port_horizontal.ypos", "2" },
+ { "sp_port_horizontal.frames", "1" },
+ { "sp_port_vertical", "RocksSP.pcx" },
+ { "sp_port_vertical.xpos", "5" },
+ { "sp_port_vertical.ypos", "2" },
+ { "sp_port_vertical.frames", "1" },
+ { "sp_port_any", "RocksSP.pcx" },
+ { "sp_port_any.xpos", "7" },
+ { "sp_port_any.ypos", "2" },
+ { "sp_port_any.frames", "1" },
+ { "sp_gravity_port_right", "RocksSP.pcx" },
+ { "sp_gravity_port_right.xpos", "5" },
+ { "sp_gravity_port_right.ypos", "1" },
+ { "sp_gravity_port_right.frames", "1" },
+ { "sp_gravity_port_down", "RocksSP.pcx" },
+ { "sp_gravity_port_down.xpos", "6" },
+ { "sp_gravity_port_down.ypos", "1" },
+ { "sp_gravity_port_down.frames", "1" },
+ { "sp_gravity_port_left", "RocksSP.pcx" },
+ { "sp_gravity_port_left.xpos", "7" },
+ { "sp_gravity_port_left.ypos", "1" },
+ { "sp_gravity_port_left.frames", "1" },
+ { "sp_gravity_port_up", "RocksSP.pcx" },
+ { "sp_gravity_port_up.xpos", "0" },
+ { "sp_gravity_port_up.ypos", "2" },
+ { "sp_gravity_port_up.frames", "1" },
+
+ { "sp_sniksnak", "RocksSP.pcx" },
+ { "sp_sniksnak.xpos", "1" },
+ { "sp_sniksnak.ypos", "2" },
+ { "sp_sniksnak.frames", "1" },
+ { "sp_sniksnak.left", "RocksSP.pcx" },
+ { "sp_sniksnak.left.xpos", "8" },
+ { "sp_sniksnak.left.ypos", "8" },
+ { "sp_sniksnak.left.frames", "4" },
+ { "sp_sniksnak.left.anim_mode", "pingpong2" },
+ { "sp_sniksnak.right", "RocksSP.pcx" },
+ { "sp_sniksnak.right.xpos", "12" },
+ { "sp_sniksnak.right.ypos", "8" },
+ { "sp_sniksnak.right.frames", "4" },
+ { "sp_sniksnak.right.anim_mode", "pingpong2" },
+ { "sp_sniksnak.up", "RocksSP.pcx" },
+ { "sp_sniksnak.up.xpos", "8" },
+ { "sp_sniksnak.up.ypos", "9" },
+ { "sp_sniksnak.up.frames", "4" },
+ { "sp_sniksnak.up.anim_mode", "pingpong2" },
+ { "sp_sniksnak.down", "RocksSP.pcx" },
+ { "sp_sniksnak.down.xpos", "12" },
+ { "sp_sniksnak.down.ypos", "9" },
+ { "sp_sniksnak.down.frames", "4" },
+ { "sp_sniksnak.down.anim_mode", "pingpong2" },
+
+ { "sp_electron", "RocksSP.pcx" },
+ { "sp_electron.xpos", "8" },
+ { "sp_electron.ypos", "10" },
+ { "sp_electron.frames", "8" },
+ { "sp_electron.delay", "2" },
+ { "sp_electron.EDITOR", "RocksSP.pcx" },
+ { "sp_electron.EDITOR.xpos", "10" },
+ { "sp_electron.EDITOR.ypos", "11" },
+ { "sp_electron.exploding", "RocksSP.pcx" },
+ { "sp_electron.exploding.xpos", "8" },
+ { "sp_electron.exploding.ypos", "4" },
+ { "sp_electron.exploding.frames", "8" },
+ { "sp_electron.exploding.delay", "3" },
+ { "sp_electron.exploding.anim_mode", "linear" },
+
+ { "sp_terminal", "RocksSP.pcx" },
+ { "sp_terminal.xpos", "0" },
+ { "sp_terminal.ypos", "10" },
+ { "sp_terminal.frames", "7" },
+ { "sp_terminal.delay", "12" },
+ { "sp_terminal.EDITOR", "RocksSP.pcx" },
+ { "sp_terminal.EDITOR.xpos", "9" },
+ { "sp_terminal.EDITOR.ypos", "11" },
+ { "sp_terminal.active", "RocksSP.pcx" },
+ { "sp_terminal.active.xpos", "0" },
+ { "sp_terminal.active.ypos", "11" },
+ { "sp_terminal.active.frames", "7" },
+ { "sp_terminal.active.delay", "4" },
+
+ { "sp_buggy_base", "RocksSP.pcx" },
+ { "sp_buggy_base.xpos", "1" },
+ { "sp_buggy_base.ypos", "3" },
+ { "sp_buggy_base.frames", "1" },
+ { "sp_buggy_base.EDITOR", "RocksSP.pcx" },
+ { "sp_buggy_base.EDITOR.xpos", "9" },
+ { "sp_buggy_base.EDITOR.ypos", "6" },
+ { "sp_buggy_base.activating", "RocksSP.pcx" },
+ { "sp_buggy_base.activating.xpos", "15" },
+ { "sp_buggy_base.activating.ypos", "2" },
+ { "sp_buggy_base.activating.frames", "1" },
+ { "sp_buggy_base.active", "RocksSP.pcx" },
+ { "sp_buggy_base.active.xpos", "8" },
+ { "sp_buggy_base.active.ypos", "6" },
+ { "sp_buggy_base.active.frames", "4" },
+ { "sp_buggy_base.active.anim_mode", "random" },
+
+ { "sp_hardware_base_1", "RocksSP.pcx" },
+ { "sp_hardware_base_1.xpos", "4" },
+ { "sp_hardware_base_1.ypos", "3" },
+ { "sp_hardware_base_1.frames", "1" },
+ { "sp_hardware_base_2", "RocksSP.pcx" },
+ { "sp_hardware_base_2.xpos", "1" },
+ { "sp_hardware_base_2.ypos", "4" },
+ { "sp_hardware_base_2.frames", "1" },
+ { "sp_hardware_base_3", "RocksSP.pcx" },
+ { "sp_hardware_base_3.xpos", "2" },
+ { "sp_hardware_base_3.ypos", "4" },
+ { "sp_hardware_base_3.frames", "1" },
+ { "sp_hardware_base_4", "RocksSP.pcx" },
+ { "sp_hardware_base_4.xpos", "3" },
+ { "sp_hardware_base_4.ypos", "4" },
+ { "sp_hardware_base_4.frames", "1" },
+ { "sp_hardware_base_5", "RocksSP.pcx" },
+ { "sp_hardware_base_5.xpos", "4" },
+ { "sp_hardware_base_5.ypos", "4" },
+ { "sp_hardware_base_5.frames", "1" },
+ { "sp_hardware_base_6", "RocksSP.pcx" },
+ { "sp_hardware_base_6.xpos", "5" },
+ { "sp_hardware_base_6.ypos", "4" },
+ { "sp_hardware_base_6.frames", "1" },
+
+ /* images for Sokoban style elements and actions */
+
+ { "sokoban_object", "RocksElements.pcx" },
+ { "sokoban_object.xpos", "9" },
+ { "sokoban_object.ypos", "7" },
+ { "sokoban_object.frames", "1" },
+ { "sokoban_object.EDITOR", "RocksElements.pcx" },
+ { "sokoban_object.EDITOR.xpos", "2" },
+ { "sokoban_object.EDITOR.ypos", "14" },
+
+ { "sokoban_field_empty", "RocksElements.pcx" },
+ { "sokoban_field_empty.xpos", "10" },
+ { "sokoban_field_empty.ypos", "7" },
+ { "sokoban_field_empty.frames", "1" },
+
+ { "sokoban_field_full", "RocksElements.pcx" },
+ { "sokoban_field_full.xpos", "11" },
+ { "sokoban_field_full.ypos", "7" },
+ { "sokoban_field_full.frames", "1" },
+
+ /* images for Emerald Mine style elements and actions */
+
+ { "empty_space", "RocksSP.pcx" },
+ { "empty_space.xpos", "0" },
+ { "empty_space.ypos", "0" },
+ { "empty_space.frames", "1" },
+
+ { "sand", "RocksElements.pcx" },
+ { "sand.xpos", "0" },
+ { "sand.ypos", "0" },
+ { "sand.frames", "1" },
+ { "sand.CRUMBLED", "RocksElements.pcx" },
+ { "sand.CRUMBLED.xpos", "1" },
+ { "sand.CRUMBLED.ypos", "0" },
+ { "sand.CRUMBLED.frames", "1" },
+ { "sand.digging.left", "RocksMore.pcx" },
+ { "sand.digging.left.xpos", "6" },
+ { "sand.digging.left.ypos", "3" },
+ { "sand.digging.left.frames", "3" },
+ { "sand.digging.left.delay", "2" },
+ { "sand.digging.left.anim_mode", "linear" },
+ { "sand.digging.right", "RocksMore.pcx" },
+ { "sand.digging.right.xpos", "9" },
+ { "sand.digging.right.ypos", "3" },
+ { "sand.digging.right.frames", "3" },
+ { "sand.digging.right.delay", "2" },
+ { "sand.digging.right.anim_mode", "linear" },
+ { "sand.digging.up", "RocksMore.pcx" },
+ { "sand.digging.up.xpos", "0" },
+ { "sand.digging.up.ypos", "3" },
+ { "sand.digging.up.frames", "3" },
+ { "sand.digging.up.delay", "2" },
+ { "sand.digging.up.anim_mode", "linear" },
+ { "sand.digging.down", "RocksMore.pcx" },
+ { "sand.digging.down.xpos", "3" },
+ { "sand.digging.down.ypos", "3" },
+ { "sand.digging.down.frames", "3" },
+ { "sand.digging.down.delay", "2" },
+ { "sand.digging.down.anim_mode", "linear" },
+ { "sand.digging.left.CRUMBLED", "RocksMore.pcx" },
+ { "sand.digging.left.CRUMBLED.xpos", "6" },
+ { "sand.digging.left.CRUMBLED.ypos", "0" },
+ { "sand.digging.left.CRUMBLED.frames", "3" },
+ { "sand.digging.left.CRUMBLED.delay", "2" },
+ { "sand.digging.left.CRUMBLED.anim_mode", "linear" },
+ { "sand.digging.right.CRUMBLED", "RocksMore.pcx" },
+ { "sand.digging.right.CRUMBLED.xpos", "9" },
+ { "sand.digging.right.CRUMBLED.ypos", "0" },
+ { "sand.digging.right.CRUMBLED.frames", "3" },
+ { "sand.digging.right.CRUMBLED.delay", "2" },
+ { "sand.digging.right.CRUMBLED.anim_mode", "linear" },
+ { "sand.digging.up.CRUMBLED", "RocksMore.pcx" },
+ { "sand.digging.up.CRUMBLED.xpos", "0" },
+ { "sand.digging.up.CRUMBLED.ypos", "0" },
+ { "sand.digging.up.CRUMBLED.frames", "3" },
+ { "sand.digging.up.CRUMBLED.delay", "2" },
+ { "sand.digging.up.CRUMBLED.anim_mode", "linear" },
+ { "sand.digging.down.CRUMBLED", "RocksMore.pcx" },
+ { "sand.digging.down.CRUMBLED.xpos", "3" },
+ { "sand.digging.down.CRUMBLED.ypos", "0" },
+ { "sand.digging.down.CRUMBLED.frames", "3" },
+ { "sand.digging.down.CRUMBLED.delay", "2" },
+ { "sand.digging.down.CRUMBLED.anim_mode", "linear" },
+
+ { "wall", "RocksElements.pcx" },
+ { "wall.xpos", "5" },
+ { "wall.ypos", "0" },
+ { "wall.frames", "1" },
+
+ { "wall_slippery", "RocksElements.pcx" },
+ { "wall_slippery.xpos", "6" },
+ { "wall_slippery.ypos", "0" },
+ { "wall_slippery.frames", "1" },
+
+ { "steelwall", "RocksElements.pcx" },
+ { "steelwall.xpos", "4" },
+ { "steelwall.ypos", "0" },
+ { "steelwall.frames", "1" },
+
+ { "rock", "RocksElements.pcx" },
+ { "rock.xpos", "12" },
+ { "rock.ypos", "0" },
+ { "rock.frames", "1" },
+ { "rock.moving.left", "RocksElements.pcx" },
+ { "rock.moving.left.xpos", "12" },
+ { "rock.moving.left.ypos", "0" },
+ { "rock.moving.left.frames", "4" },
+ { "rock.moving.left.delay", "2" },
+ { "rock.moving.left.anim_mode", "reverse" },
+ { "rock.moving.right", "RocksElements.pcx" },
+ { "rock.moving.right.xpos", "12" },
+ { "rock.moving.right.ypos", "0" },
+ { "rock.moving.right.frames", "4" },
+ { "rock.moving.right.start_frame", "1" },
+ { "rock.moving.right.delay", "2" },
+ { "rock.pushing.left", "RocksElements.pcx" },
+ { "rock.pushing.left.xpos", "12" },
+ { "rock.pushing.left.ypos", "0" },
+ { "rock.pushing.left.frames", "4" },
+ { "rock.pushing.left.delay", "2" },
+ { "rock.pushing.left.anim_mode", "reverse" },
+ { "rock.pushing.right", "RocksElements.pcx" },
+ { "rock.pushing.right.xpos", "12" },
+ { "rock.pushing.right.ypos", "0" },
+ { "rock.pushing.right.frames", "4" },
+ { "rock.pushing.right.start_frame", "1" },
+ { "rock.pushing.right.delay", "2" },
+
+ { "emerald", "RocksElements.pcx" },
+ { "emerald.xpos", "8" },
+ { "emerald.ypos", "0" },
+ { "emerald.frames", "1" },
+ { "emerald.moving", "RocksElements.pcx" },
+ { "emerald.moving.xpos", "8" },
+ { "emerald.moving.ypos", "0" },
+ { "emerald.moving.frames", "2" },
+ { "emerald.moving.delay", "4" },
+ { "emerald.falling", "RocksElements.pcx" },
+ { "emerald.falling.xpos", "8" },
+ { "emerald.falling.ypos", "0" },
+ { "emerald.falling.frames", "2" },
+ { "emerald.falling.delay", "4" },
+ { "emerald.collecting", "RocksMore.pcx" },
+ { "emerald.collecting.xpos", "3" },
+ { "emerald.collecting.ypos", "2" },
+ { "emerald.collecting.frames", "3" },
+ { "emerald.collecting.delay", "2" },
+ { "emerald.collecting.anim_mode", "linear" },
+
+ { "diamond", "RocksElements.pcx" },
+ { "diamond.xpos", "10" },
+ { "diamond.ypos", "0" },
+ { "diamond.frames", "1" },
+ { "diamond.moving", "RocksElements.pcx" },
+ { "diamond.moving.xpos", "10" },
+ { "diamond.moving.ypos", "0" },
+ { "diamond.moving.frames", "2" },
+ { "diamond.moving.delay", "4" },
+ { "diamond.falling", "RocksElements.pcx" },
+ { "diamond.falling.xpos", "10" },
+ { "diamond.falling.ypos", "0" },
+ { "diamond.falling.frames", "2" },
+ { "diamond.falling.delay", "4" },
+ { "diamond.collecting", "RocksMore.pcx" },
+ { "diamond.collecting.xpos", "7" },
+ { "diamond.collecting.ypos", "2" },
+ { "diamond.collecting.frames", "3" },
+ { "diamond.collecting.delay", "2" },
+ { "diamond.collecting.anim_mode", "linear" },
+
+ { "bomb", "RocksElements.pcx" },
+ { "bomb.xpos", "11" },
+ { "bomb.ypos", "1" },
+ { "bomb.frames", "1" },
+
+ { "nut", "RocksElements.pcx" },
+ { "nut.xpos", "12" },
+ { "nut.ypos", "1" },
+ { "nut.frames", "1" },
+ { "nut.breaking", "RocksElements.pcx" },
+ { "nut.breaking.xpos", "13" },
+ { "nut.breaking.ypos", "1" },
+ { "nut.breaking.frames", "3" },
+ { "nut.breaking.delay", "2" },
+ { "nut.breaking.anim_mode", "linear" },
+
+ { "dynamite", "RocksElements.pcx" },
+ { "dynamite.xpos", "0" },
+ { "dynamite.ypos", "3" },
+ { "dynamite.frames", "1" },
+ { "dynamite.EDITOR", "RocksElements.pcx" },
+ { "dynamite.EDITOR.xpos", "0" },
+ { "dynamite.EDITOR.ypos", "14" },
+ { "dynamite.active", "RocksElements.pcx" },
+ { "dynamite.active.xpos", "1" },
+ { "dynamite.active.ypos", "3" },
+ { "dynamite.active.frames", "7" },
+ { "dynamite.active.delay", "12" },
+ { "dynamite.active.anim_mode", "linear" },
+ { "dynamite.active.EDITOR", "RocksElements.pcx" },
+ { "dynamite.active.EDITOR.xpos", "1" },
+ { "dynamite.active.EDITOR.ypos", "14" },
+
+ { "wall_emerald", "RocksElements.pcx" },
+ { "wall_emerald.xpos", "4" },
+ { "wall_emerald.ypos", "8" },
+ { "wall_emerald.frames", "1" },
+
+ { "wall_diamond", "RocksElements.pcx" },
+ { "wall_diamond.xpos", "5" },
+ { "wall_diamond.ypos", "8" },
+ { "wall_diamond.frames", "1" },
+
+ { "bug", "RocksElements.pcx" },
+ { "bug.xpos", "8" },
+ { "bug.ypos", "4" },
+ { "bug.frames", "4" },
+ { "bug.delay", "8" },
+ { "bug.right", "RocksElements.pcx" },
+ { "bug.right.xpos", "8" },
+ { "bug.right.ypos", "4" },
+ { "bug.right.frames", "1" },
+ { "bug.up", "RocksElements.pcx" },
+ { "bug.up.xpos", "9" },
+ { "bug.up.ypos", "4" },
+ { "bug.up.frames", "1" },
+ { "bug.left", "RocksElements.pcx" },
+ { "bug.left.xpos", "10" },
+ { "bug.left.ypos", "4" },
+ { "bug.left.frames", "1" },
+ { "bug.down", "RocksElements.pcx" },
+ { "bug.down.xpos", "11" },
+ { "bug.down.ypos", "4" },
+ { "bug.down.frames", "1" },
+ { "bug.moving.right", "RocksElements.pcx" },
+ { "bug.moving.right.xpos", "8" },
+ { "bug.moving.right.ypos", "4" },
+ { "bug.moving.right.frames", "2" },
+ { "bug.moving.right.delay", "4" },
+ { "bug.moving.right.offset", "128" },
+ { "bug.moving.up", "RocksElements.pcx" },
+ { "bug.moving.up.xpos", "9" },
+ { "bug.moving.up.ypos", "4" },
+ { "bug.moving.up.frames", "2" },
+ { "bug.moving.up.delay", "4" },
+ { "bug.moving.up.offset", "128" },
+ { "bug.moving.left", "RocksElements.pcx" },
+ { "bug.moving.left.xpos", "10" },
+ { "bug.moving.left.ypos", "4" },
+ { "bug.moving.left.frames", "2" },
+ { "bug.moving.left.delay", "4" },
+ { "bug.moving.left.offset", "128" },
+ { "bug.moving.down", "RocksElements.pcx" },
+ { "bug.moving.down.xpos", "11" },
+ { "bug.moving.down.ypos", "4" },
+ { "bug.moving.down.frames", "2" },
+ { "bug.moving.down.delay", "4" },
+ { "bug.moving.down.offset", "128" },
+
+ { "spaceship", "RocksElements.pcx" },
+ { "spaceship.xpos", "8" },
+ { "spaceship.ypos", "3" },
+ { "spaceship.frames", "4" },
+ { "spaceship.delay", "8" },
+ { "spaceship.right", "RocksElements.pcx" },
+ { "spaceship.right.xpos", "8" },
+ { "spaceship.right.ypos", "3" },
+ { "spaceship.right.frames", "1" },
+ { "spaceship.up", "RocksElements.pcx" },
+ { "spaceship.up.xpos", "9" },
+ { "spaceship.up.ypos", "3" },
+ { "spaceship.up.frames", "1" },
+ { "spaceship.left", "RocksElements.pcx" },
+ { "spaceship.left.xpos", "10" },
+ { "spaceship.left.ypos", "3" },
+ { "spaceship.left.frames", "1" },
+ { "spaceship.down", "RocksElements.pcx" },
+ { "spaceship.down.xpos", "11" },
+ { "spaceship.down.ypos", "3" },
+ { "spaceship.down.frames", "1" },
+ { "spaceship.moving.right", "RocksElements.pcx" },
+ { "spaceship.moving.right.xpos", "8" },
+ { "spaceship.moving.right.ypos", "3" },
+ { "spaceship.moving.right.frames", "2" },
+ { "spaceship.moving.right.delay", "4" },
+ { "spaceship.moving.right.offset", "128" },
+ { "spaceship.moving.up", "RocksElements.pcx" },
+ { "spaceship.moving.up.xpos", "9" },
+ { "spaceship.moving.up.ypos", "3" },
+ { "spaceship.moving.up.frames", "2" },
+ { "spaceship.moving.up.delay", "4" },
+ { "spaceship.moving.up.offset", "128" },
+ { "spaceship.moving.left", "RocksElements.pcx" },
+ { "spaceship.moving.left.xpos", "10" },
+ { "spaceship.moving.left.ypos", "3" },
+ { "spaceship.moving.left.frames", "2" },
+ { "spaceship.moving.left.delay", "4" },
+ { "spaceship.moving.left.offset", "128" },
+ { "spaceship.moving.down", "RocksElements.pcx" },
+ { "spaceship.moving.down.xpos", "11" },
+ { "spaceship.moving.down.ypos", "3" },
+ { "spaceship.moving.down.frames", "2" },
+ { "spaceship.moving.down.delay", "4" },
+ { "spaceship.moving.down.offset", "128" },
+
+ { "yamyam", "RocksElements.pcx" },
+ { "yamyam.xpos", "0" },
+ { "yamyam.ypos", "5" },
+ { "yamyam.frames", "4" },
+ { "yamyam.anim_mode", "pingpong2" },
+ { "yamyam.moving", "RocksElements.pcx" },
+ { "yamyam.moving.xpos", "0" },
+ { "yamyam.moving.ypos", "5" },
+ { "yamyam.moving.frames", "1" },
+
+ { "robot", "RocksElements.pcx" },
+ { "robot.xpos", "4" },
+ { "robot.ypos", "5" },
+ { "robot.frames", "4" },
+ { "robot.anim_mode", "pingpong2" },
+ { "robot.moving", "RocksElements.pcx" },
+ { "robot.moving.xpos", "4" },
+ { "robot.moving.ypos", "5" },
+ { "robot.moving.frames", "1" },
+
+ { "robot_wheel", "RocksElements.pcx" },
+ { "robot_wheel.xpos", "0" },
+ { "robot_wheel.ypos", "6" },
+ { "robot_wheel.frames", "1" },
+ { "robot_wheel.active", "RocksElements.pcx" },
+ { "robot_wheel.active.xpos", "0" },
+ { "robot_wheel.active.ypos", "6" },
+ { "robot_wheel.active.frames", "4" },
+
+ { "magic_wall", "RocksElements.pcx" },
+ { "magic_wall.xpos", "0" },
+ { "magic_wall.ypos", "8" },
+ { "magic_wall.frames", "1" },
+ { "magic_wall.active", "RocksElements.pcx" },
+ { "magic_wall.active.xpos", "0" },
+ { "magic_wall.active.ypos", "8" },
+ { "magic_wall.active.frames", "4" },
+ { "magic_wall.active.anim_mode", "reverse" },
+ { "magic_wall.active.delay", "4" },
+ { "magic_wall.active.global_sync", "true" },
+ { "magic_wall.filling", "RocksElements.pcx" },
+ { "magic_wall.filling.xpos", "0" },
+ { "magic_wall.filling.ypos", "8" },
+ { "magic_wall.filling.frames", "4" },
+ { "magic_wall.filling.anim_mode", "reverse" },
+ { "magic_wall.filling.delay", "4" },
+ { "magic_wall.filling.global_sync", "true" },
+ { "magic_wall_full", "RocksElements.pcx" },
+ { "magic_wall_full.xpos", "0" },
+ { "magic_wall_full.ypos", "8" },
+ { "magic_wall_full.frames", "4" },
+ { "magic_wall_full.anim_mode", "reverse" },
+ { "magic_wall_full.delay", "4" },
+ { "magic_wall_full.global_sync", "true" },
+ { "magic_wall.emptying", "RocksElements.pcx" },
+ { "magic_wall.emptying.xpos", "0" },
+ { "magic_wall.emptying.ypos", "8" },
+ { "magic_wall.emptying.frames", "4" },
+ { "magic_wall.emptying.anim_mode", "reverse" },
+ { "magic_wall.emptying.delay", "4" },
+ { "magic_wall.emptying.global_sync", "true" },
+ { "magic_wall_dead", "RocksElements.pcx" },
+ { "magic_wall_dead.xpos", "0" },
+ { "magic_wall_dead.ypos", "8" },
+ { "magic_wall_dead.frames", "1" },
+
+ { "quicksand_empty", "RocksElements.pcx" },
+ { "quicksand_empty.xpos", "2" },
+ { "quicksand_empty.ypos", "0" },
+ { "quicksand_empty.frames", "1" },
+ { "quicksand.filling", "RocksElements.pcx" },
+ { "quicksand.filling.xpos", "3" },
+ { "quicksand.filling.ypos", "0" },
+ { "quicksand.filling.frames", "1" },
+ { "quicksand_full", "RocksElements.pcx" },
+ { "quicksand_full.xpos", "3" },
+ { "quicksand_full.ypos", "0" },
+ { "quicksand_full.frames", "1" },
+ { "quicksand_full.EDITOR", "RocksElements.pcx" },
+ { "quicksand_full.EDITOR.xpos", "3" },
+ { "quicksand_full.EDITOR.ypos", "14" },
+ { "quicksand.emptying", "RocksElements.pcx" },
+ { "quicksand.emptying.xpos", "3" },
+ { "quicksand.emptying.ypos", "0" },
+ { "quicksand.emptying.frames", "1" },
+
+ { "acid_pool_topleft", "RocksElements.pcx" },
+ { "acid_pool_topleft.xpos", "0" },
+ { "acid_pool_topleft.ypos", "1" },
+ { "acid_pool_topleft.frames", "1" },
+ { "acid_pool_topright", "RocksElements.pcx" },
+ { "acid_pool_topright.xpos", "2" },
+ { "acid_pool_topright.ypos", "1" },
+ { "acid_pool_topright.frames", "1" },
+ { "acid_pool_bottomleft", "RocksElements.pcx" },
+ { "acid_pool_bottomleft.xpos", "0" },
+ { "acid_pool_bottomleft.ypos", "2" },
+ { "acid_pool_bottomleft.frames", "1" },
+ { "acid_pool_bottom", "RocksElements.pcx" },
+ { "acid_pool_bottom.xpos", "1" },
+ { "acid_pool_bottom.ypos", "2" },
+ { "acid_pool_bottom.frames", "1" },
+ { "acid_pool_bottomright", "RocksElements.pcx" },
+ { "acid_pool_bottomright.xpos", "2" },
+ { "acid_pool_bottomright.ypos", "2" },
+ { "acid_pool_bottomright.frames", "1" },
+
+ { "acid", "RocksElements.pcx" },
+ { "acid.xpos", "12" },
+ { "acid.ypos", "7" },
+ { "acid.frames", "4" },
+ { "acid.delay", "10" },
+ { "acid.global_sync", "true" },
+
+ { "acid_splash_left", "RocksHeroes.pcx" },
+ { "acid_splash_left.xpos", "8" },
+ { "acid_splash_left.ypos", "10" },
+ { "acid_splash_left.frames", "4" },
+ { "acid_splash_left.delay", "2" },
+ { "acid_splash_left.anim_mode", "linear" },
+ { "acid_splash_right", "RocksHeroes.pcx" },
+ { "acid_splash_right.xpos", "12" },
+ { "acid_splash_right.ypos", "10" },
+ { "acid_splash_right.frames", "4" },
+ { "acid_splash_right.delay", "2" },
+ { "acid_splash_right.anim_mode", "linear" },
+
+ { "amoeba_drop", "RocksElements.pcx" },
+ { "amoeba_drop.xpos", "5" },
+ { "amoeba_drop.ypos", "6" },
+ { "amoeba_drop.frames", "1" },
+ { "amoeba.growing", "RocksElements.pcx" },
+ { "amoeba.growing.xpos", "5" },
+ { "amoeba.growing.ypos", "6" },
+ { "amoeba.growing.frames", "3" },
+ { "amoeba.growing.delay", "2" },
+ { "amoeba.growing.anim_mode", "linear" },
+ { "amoeba.shrinking", "RocksElements.pcx" },
+ { "amoeba.shrinking.xpos", "5" },
+ { "amoeba.shrinking.ypos", "6" },
+ { "amoeba.shrinking.frames", "3" },
+ { "amoeba.shrinking.delay", "2" },
+ { "amoeba.shrinking.anim_mode", "linear,reverse" },
+ { "amoeba_wet", "RocksElements.pcx" },
+ { "amoeba_wet.xpos", "8" },
+ { "amoeba_wet.ypos", "6" },
+ { "amoeba_wet.frames", "4" },
+ { "amoeba_wet.delay", "1000000" },
+ { "amoeba_wet.anim_mode", "random" },
+ { "amoeba_wet.EDITOR", "RocksElements.pcx" },
+ { "amoeba_wet.EDITOR.xpos", "4" },
+ { "amoeba_wet.EDITOR.ypos", "6" },
+ { "amoeba.dropping", "RocksElements.pcx" },
+ { "amoeba.dropping.xpos", "8" },
+ { "amoeba.dropping.ypos", "6" },
+ { "amoeba.dropping.frames", "4" },
+ { "amoeba.dropping.delay", "1000000" },
+ { "amoeba.dropping.anim_mode", "random" },
+ { "amoeba_dry", "RocksElements.pcx" },
+ { "amoeba_dry.xpos", "8" },
+ { "amoeba_dry.ypos", "6" },
+ { "amoeba_dry.frames", "4" },
+ { "amoeba_dry.delay", "1000000" },
+ { "amoeba_dry.anim_mode", "random" },
+ { "amoeba_full", "RocksElements.pcx" },
+ { "amoeba_full.xpos", "8" },
+ { "amoeba_full.ypos", "6" },
+ { "amoeba_full.frames", "4" },
+ { "amoeba_full.delay", "1000000" },
+ { "amoeba_full.anim_mode", "random" },
+ { "amoeba_full.EDITOR", "RocksElements.pcx" },
+ { "amoeba_full.EDITOR.xpos", "8" },
+ { "amoeba_full.EDITOR.ypos", "7" },
+ { "amoeba_dead", "RocksElements.pcx" },
+ { "amoeba_dead.xpos", "12" },
+ { "amoeba_dead.ypos", "6" },
+ { "amoeba_dead.frames", "4" },
+ { "amoeba_dead.delay", "1000000" },
+ { "amoeba_dead.anim_mode", "random" },
+ { "amoeba_dead.EDITOR", "RocksElements.pcx" },
+ { "amoeba_dead.EDITOR.xpos", "12" },
+ { "amoeba_dead.EDITOR.ypos", "6" },
+
+ { "em_key_1", "RocksSP.pcx" },
+ { "em_key_1.xpos", "4" },
+ { "em_key_1.ypos", "6" },
+ { "em_key_1.frames", "1" },
+ { "em_key_2", "RocksSP.pcx" },
+ { "em_key_2.xpos", "5" },
+ { "em_key_2.ypos", "6" },
+ { "em_key_2.frames", "1" },
+ { "em_key_3", "RocksSP.pcx" },
+ { "em_key_3.xpos", "6" },
+ { "em_key_3.ypos", "6" },
+ { "em_key_3.frames", "1" },
+ { "em_key_4", "RocksSP.pcx" },
+ { "em_key_4.xpos", "7" },
+ { "em_key_4.ypos", "6" },
+ { "em_key_4.frames", "1" },
+
+ { "em_gate_1", "RocksSP.pcx" },
+ { "em_gate_1.xpos", "0" },
+ { "em_gate_1.ypos", "7" },
+ { "em_gate_1.frames", "1" },
+ { "em_gate_2", "RocksSP.pcx" },
+ { "em_gate_2.xpos", "1" },
+ { "em_gate_2.ypos", "7" },
+ { "em_gate_2.frames", "1" },
+ { "em_gate_3", "RocksSP.pcx" },
+ { "em_gate_3.xpos", "2" },
+ { "em_gate_3.ypos", "7" },
+ { "em_gate_3.frames", "1" },
+ { "em_gate_4", "RocksSP.pcx" },
+ { "em_gate_4.xpos", "3" },
+ { "em_gate_4.ypos", "7" },
+ { "em_gate_4.frames", "1" },
+ { "em_gate_1_gray", "RocksSP.pcx" },
+ { "em_gate_1_gray.xpos", "4" },
+ { "em_gate_1_gray.ypos", "7" },
+ { "em_gate_1_gray.frames", "1" },
+ { "em_gate_1_gray.EDITOR", "RocksSP.pcx" },
+ { "em_gate_1_gray.EDITOR.xpos", "12" },
+ { "em_gate_1_gray.EDITOR.ypos", "11" },
+ { "em_gate_2_gray", "RocksSP.pcx" },
+ { "em_gate_2_gray.xpos", "5" },
+ { "em_gate_2_gray.ypos", "7" },
+ { "em_gate_2_gray.frames", "1" },
+ { "em_gate_2_gray.EDITOR", "RocksSP.pcx" },
+ { "em_gate_2_gray.EDITOR.xpos", "13" },
+ { "em_gate_2_gray.EDITOR.ypos", "11" },
+ { "em_gate_3_gray", "RocksSP.pcx" },
+ { "em_gate_3_gray.xpos", "6" },
+ { "em_gate_3_gray.ypos", "7" },
+ { "em_gate_3_gray.frames", "1" },
+ { "em_gate_3_gray.EDITOR", "RocksSP.pcx" },
+ { "em_gate_3_gray.EDITOR.xpos", "14" },
+ { "em_gate_3_gray.EDITOR.ypos", "11" },
+ { "em_gate_4_gray", "RocksSP.pcx" },
+ { "em_gate_4_gray.xpos", "7" },
+ { "em_gate_4_gray.ypos", "7" },
+ { "em_gate_4_gray.frames", "1" },
+ { "em_gate_4_gray.EDITOR", "RocksSP.pcx" },
+ { "em_gate_4_gray.EDITOR.xpos", "15" },
+ { "em_gate_4_gray.EDITOR.ypos", "11" },
+
+ { "exit_closed", "RocksElements.pcx" },
+ { "exit_closed.xpos", "0" },
+ { "exit_closed.ypos", "11" },
+ { "exit_closed.frames", "1" },
+ { "exit.opening", "RocksElements.pcx" },
+ { "exit.opening.xpos", "0" },
+ { "exit.opening.ypos", "11" },
+ { "exit.opening.frames", "5" },
+ { "exit.opening.delay", "6" },
+ { "exit.opening.anim_mode", "linear" },
+ { "exit_open", "RocksElements.pcx" },
+ { "exit_open.xpos", "4" },
+ { "exit_open.ypos", "11" },
+ { "exit_open.frames", "4" },
+ { "exit_open.delay", "4" },
+ { "exit_open.anim_mode", "pingpong" },
+
+ /* images for Emerald Mine Club style elements and actions */
+
+ { "balloon", "RocksDC.pcx" },
+ { "balloon.xpos", "12" },
+ { "balloon.ypos", "7" },
+ { "balloon.frames", "1" },
+ { "balloon.moving", "RocksDC.pcx" },
+ { "balloon.moving.xpos", "12" },
+ { "balloon.moving.ypos", "7" },
+ { "balloon.moving.frames", "4" },
+ { "balloon.moving.anim_mode", "pingpong" },
+ { "balloon.moving.delay", "2" },
+ { "balloon.pushing", "RocksDC.pcx" },
+ { "balloon.pushing.xpos", "12" },
+ { "balloon.pushing.ypos", "7" },
+ { "balloon.pushing.frames", "4" },
+ { "balloon.pushing.anim_mode", "pingpong" },
+ { "balloon.pushing.delay", "2" },
+ { "balloon_switch_left", "RocksDC.pcx" },
+ { "balloon_switch_left.xpos", "8" },
+ { "balloon_switch_left.ypos", "7" },
+ { "balloon_switch_left.frames", "1" },
+ { "balloon_switch_right", "RocksDC.pcx" },
+ { "balloon_switch_right.xpos", "9" },
+ { "balloon_switch_right.ypos", "7" },
+ { "balloon_switch_right.frames", "1" },
+ { "balloon_switch_up", "RocksDC.pcx" },
+ { "balloon_switch_up.xpos", "10" },
+ { "balloon_switch_up.ypos", "7" },
+ { "balloon_switch_up.frames", "1" },
+ { "balloon_switch_down", "RocksDC.pcx" },
+ { "balloon_switch_down.xpos", "11" },
+ { "balloon_switch_down.ypos", "7" },
+ { "balloon_switch_down.frames", "1" },
+ { "balloon_switch_any", "RocksDC.pcx" },
+ { "balloon_switch_any.xpos", "15" },
+ { "balloon_switch_any.ypos", "0" },
+ { "balloon_switch_any.frames", "1" },
+
+ { "spring", "RocksDC.pcx" },
+ { "spring.xpos", "8" },
+ { "spring.ypos", "13" },
+ { "spring.frames", "1" },
+
+ { "emc_steelwall_1", "RocksDC.pcx" },
+ { "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.frames", "1" },
+ { "emc_steelwall_3", "RocksDC.pcx" },
+ { "emc_steelwall_3.xpos", "14" },
+ { "emc_steelwall_3.ypos", "0" },
+ { "emc_steelwall_3.frames", "1" },
+ { "emc_steelwall_4", "RocksDC.pcx" },
+ { "emc_steelwall_4.xpos", "14" },
+ { "emc_steelwall_4.ypos", "0" },
+ { "emc_steelwall_4.frames", "1" },
+
+ { "emc_wall_1", "RocksDC.pcx" },
+ { "emc_wall_1.xpos", "13" },
+ { "emc_wall_1.ypos", "6" },
+ { "emc_wall_1.frames", "1" },
+ { "emc_wall_2", "RocksDC.pcx" },
+ { "emc_wall_2.xpos", "14" },
+ { "emc_wall_2.ypos", "6" },
+ { "emc_wall_2.frames", "1" },
+ { "emc_wall_3", "RocksDC.pcx" },
+ { "emc_wall_3.xpos", "15" },
+ { "emc_wall_3.ypos", "6" },
+ { "emc_wall_3.frames", "1" },
+ { "emc_wall_4", "RocksDC.pcx" },
+ { "emc_wall_4.xpos", "14" },
+ { "emc_wall_4.ypos", "1" },
+ { "emc_wall_4.frames", "1" },
+ { "emc_wall_5", "RocksDC.pcx" },
+ { "emc_wall_5.xpos", "15" },
+ { "emc_wall_5.ypos", "1" },
+ { "emc_wall_5.frames", "1" },
+ { "emc_wall_6", "RocksDC.pcx" },
+ { "emc_wall_6.xpos", "14" },
+ { "emc_wall_6.ypos", "2" },
+ { "emc_wall_6.frames", "1" },
+ { "emc_wall_7", "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.frames", "1" },
+
+ /* images for Diamond Caves style elements and actions */
+
+ { "invisible_steelwall", "RocksSP.pcx" },
+ { "invisible_steelwall.xpos", "3" },
+ { "invisible_steelwall.ypos", "5" },
+ { "invisible_steelwall.frames", "1" },
+ { "invisible_steelwall.EDITOR", "RocksSP.pcx" },
+ { "invisible_steelwall.EDITOR.xpos", "1" },
+ { "invisible_steelwall.EDITOR.ypos", "5" },
+ { "invisible_steelwall.active", "RocksSP.pcx" },
+ { "invisible_steelwall.active.xpos", "1" },
+ { "invisible_steelwall.active.ypos", "5" },
+ { "invisible_steelwall.active.frames", "1" },
+
+ { "invisible_wall", "RocksSP.pcx" },
+ { "invisible_wall.xpos", "7" },
+ { "invisible_wall.ypos", "5" },
+ { "invisible_wall.frames", "1" },
+ { "invisible_wall.EDITOR", "RocksSP.pcx" },
+ { "invisible_wall.EDITOR.xpos", "5" },
+ { "invisible_wall.EDITOR.ypos", "5" },
+ { "invisible_wall.active", "RocksSP.pcx" },
+ { "invisible_wall.active.xpos", "5" },
+ { "invisible_wall.active.ypos", "5" },
+ { "invisible_wall.active.frames", "1" },
+
+ { "invisible_sand", "RocksSP.pcx" },
+ { "invisible_sand.xpos", "6" },
+ { "invisible_sand.ypos", "5" },
+ { "invisible_sand.frames", "1" },
+ { "invisible_sand.EDITOR", "RocksSP.pcx" },
+ { "invisible_sand.EDITOR.xpos", "2" },
+ { "invisible_sand.EDITOR.ypos", "5" },
+ { "invisible_sand.active", "RocksSP.pcx" },
+ { "invisible_sand.active.xpos", "2" },
+ { "invisible_sand.active.ypos", "5" },
+ { "invisible_sand.active.frames", "1" },
+
+ { "conveyor_belt_1_middle", "RocksDC.pcx" },
+ { "conveyor_belt_1_middle.xpos", "0" },
+ { "conveyor_belt_1_middle.ypos", "0" },
+ { "conveyor_belt_1_middle.frames", "1" },
+ { "conveyor_belt_1_middle.active", "RocksDC.pcx" },
+ { "conveyor_belt_1_middle.active.xpos", "0" },
+ { "conveyor_belt_1_middle.active.ypos", "0" },
+ { "conveyor_belt_1_middle.active.frames", "8" },
+ { "conveyor_belt_1_middle.active.delay", "2" },
+ { "conveyor_belt_1_left", "RocksDC.pcx" },
+ { "conveyor_belt_1_left.xpos", "0" },
+ { "conveyor_belt_1_left.ypos", "1" },
+ { "conveyor_belt_1_left.frames", "1" },
+ { "conveyor_belt_1_left.active", "RocksDC.pcx" },
+ { "conveyor_belt_1_left.active.xpos", "0" },
+ { "conveyor_belt_1_left.active.ypos", "1" },
+ { "conveyor_belt_1_left.active.frames", "8" },
+ { "conveyor_belt_1_left.active.delay", "2" },
+ { "conveyor_belt_1_right", "RocksDC.pcx" },
+ { "conveyor_belt_1_right.xpos", "0" },
+ { "conveyor_belt_1_right.ypos", "2" },
+ { "conveyor_belt_1_right.frames", "1" },
+ { "conveyor_belt_1_right.active", "RocksDC.pcx" },
+ { "conveyor_belt_1_right.active.xpos", "0" },
+ { "conveyor_belt_1_right.active.ypos", "2" },
+ { "conveyor_belt_1_right.active.frames", "8" },
+ { "conveyor_belt_1_right.active.delay", "2" },
+ { "conveyor_belt_1_switch_left", "RocksDC.pcx" },
+ { "conveyor_belt_1_switch_left.xpos", "0" },
+ { "conveyor_belt_1_switch_left.ypos", "12" },
+ { "conveyor_belt_1_switch_left.frames", "1" },
+ { "conveyor_belt_1_switch_middle", "RocksDC.pcx" },
+ { "conveyor_belt_1_switch_middle.xpos", "0" },
+ { "conveyor_belt_1_switch_middle.ypos", "13" },
+ { "conveyor_belt_1_switch_middle.frames", "1" },
+ { "conveyor_belt_1_switch_right", "RocksDC.pcx" },
+ { "conveyor_belt_1_switch_right.xpos", "0" },
+ { "conveyor_belt_1_switch_right.ypos", "14" },
+ { "conveyor_belt_1_switch_right.frames", "1" },
+
+ { "conveyor_belt_2_middle", "RocksDC.pcx" },
+ { "conveyor_belt_2_middle.xpos", "0" },
+ { "conveyor_belt_2_middle.ypos", "3" },
+ { "conveyor_belt_2_middle.frames", "1" },
+ { "conveyor_belt_2_middle.active", "RocksDC.pcx" },
+ { "conveyor_belt_2_middle.active.xpos", "0" },
+ { "conveyor_belt_2_middle.active.ypos", "3" },
+ { "conveyor_belt_2_middle.active.frames", "8" },
+ { "conveyor_belt_2_middle.active.delay", "2" },
+ { "conveyor_belt_2_left", "RocksDC.pcx" },
+ { "conveyor_belt_2_left.xpos", "0" },
+ { "conveyor_belt_2_left.ypos", "4" },
+ { "conveyor_belt_2_left.frames", "1" },
+ { "conveyor_belt_2_left.active", "RocksDC.pcx" },
+ { "conveyor_belt_2_left.active.xpos", "0" },
+ { "conveyor_belt_2_left.active.ypos", "4" },
+ { "conveyor_belt_2_left.active.frames", "8" },
+ { "conveyor_belt_2_left.active.delay", "2" },
+ { "conveyor_belt_2_right", "RocksDC.pcx" },
+ { "conveyor_belt_2_right.xpos", "0" },
+ { "conveyor_belt_2_right.ypos", "5" },
+ { "conveyor_belt_2_right.frames", "1" },
+ { "conveyor_belt_2_right.active", "RocksDC.pcx" },
+ { "conveyor_belt_2_right.active.xpos", "0" },
+ { "conveyor_belt_2_right.active.ypos", "5" },
+ { "conveyor_belt_2_right.active.frames", "8" },
+ { "conveyor_belt_2_right.active.delay", "2" },
+ { "conveyor_belt_2_switch_left", "RocksDC.pcx" },
+ { "conveyor_belt_2_switch_left.xpos", "1" },
+ { "conveyor_belt_2_switch_left.ypos", "12" },
+ { "conveyor_belt_2_switch_left.frames", "1" },
+ { "conveyor_belt_2_switch_middle", "RocksDC.pcx" },
+ { "conveyor_belt_2_switch_middle.xpos", "1" },
+ { "conveyor_belt_2_switch_middle.ypos", "13" },
+ { "conveyor_belt_2_switch_middle.frames", "1" },
+ { "conveyor_belt_2_switch_right", "RocksDC.pcx" },
+ { "conveyor_belt_2_switch_right.xpos", "1" },
+ { "conveyor_belt_2_switch_right.ypos", "14" },
+ { "conveyor_belt_2_switch_right.frames", "1" },
+
+ { "conveyor_belt_3_middle", "RocksDC.pcx" },
+ { "conveyor_belt_3_middle.xpos", "0" },
+ { "conveyor_belt_3_middle.ypos", "6" },
+ { "conveyor_belt_3_middle.frames", "1" },
+ { "conveyor_belt_3_middle.active", "RocksDC.pcx" },
+ { "conveyor_belt_3_middle.active.xpos", "0" },
+ { "conveyor_belt_3_middle.active.ypos", "6" },
+ { "conveyor_belt_3_middle.active.frames", "8" },
+ { "conveyor_belt_3_middle.active.delay", "2" },
+ { "conveyor_belt_3_left", "RocksDC.pcx" },
+ { "conveyor_belt_3_left.xpos", "0" },
+ { "conveyor_belt_3_left.ypos", "7" },
+ { "conveyor_belt_3_left.frames", "1" },
+ { "conveyor_belt_3_left.active", "RocksDC.pcx" },
+ { "conveyor_belt_3_left.active.xpos", "0" },
+ { "conveyor_belt_3_left.active.ypos", "7" },
+ { "conveyor_belt_3_left.active.frames", "8" },
+ { "conveyor_belt_3_left.active.delay", "2" },
+ { "conveyor_belt_3_right", "RocksDC.pcx" },
+ { "conveyor_belt_3_right.xpos", "0" },
+ { "conveyor_belt_3_right.ypos", "8" },
+ { "conveyor_belt_3_right.frames", "1" },
+ { "conveyor_belt_3_right.active", "RocksDC.pcx" },
+ { "conveyor_belt_3_right.active.xpos", "0" },
+ { "conveyor_belt_3_right.active.ypos", "8" },
+ { "conveyor_belt_3_right.active.frames", "8" },
+ { "conveyor_belt_3_right.active.delay", "2" },
+ { "conveyor_belt_3_switch_left", "RocksDC.pcx" },
+ { "conveyor_belt_3_switch_left.xpos", "2" },
+ { "conveyor_belt_3_switch_left.ypos", "12" },
+ { "conveyor_belt_3_switch_left.frames", "1" },
+ { "conveyor_belt_3_switch_middle", "RocksDC.pcx" },
+ { "conveyor_belt_3_switch_middle.xpos", "2" },
+ { "conveyor_belt_3_switch_middle.ypos", "13" },
+ { "conveyor_belt_3_switch_middle.frames", "1" },
+ { "conveyor_belt_3_switch_right", "RocksDC.pcx" },
+ { "conveyor_belt_3_switch_right.xpos", "2" },
+ { "conveyor_belt_3_switch_right.ypos", "14" },
+ { "conveyor_belt_3_switch_right.frames", "1" },
+
+ { "conveyor_belt_4_middle", "RocksDC.pcx" },
+ { "conveyor_belt_4_middle.xpos", "0" },
+ { "conveyor_belt_4_middle.ypos", "9" },
+ { "conveyor_belt_4_middle.frames", "1" },
+ { "conveyor_belt_4_middle.active", "RocksDC.pcx" },
+ { "conveyor_belt_4_middle.active.xpos", "0" },
+ { "conveyor_belt_4_middle.active.ypos", "9" },
+ { "conveyor_belt_4_middle.active.frames", "8" },
+ { "conveyor_belt_4_middle.active.delay", "2" },
+ { "conveyor_belt_4_left", "RocksDC.pcx" },
+ { "conveyor_belt_4_left.xpos", "0" },
+ { "conveyor_belt_4_left.ypos", "10" },
+ { "conveyor_belt_4_left.frames", "1" },
+ { "conveyor_belt_4_left.active", "RocksDC.pcx" },
+ { "conveyor_belt_4_left.active.xpos", "0" },
+ { "conveyor_belt_4_left.active.ypos", "10" },
+ { "conveyor_belt_4_left.active.frames", "8" },
+ { "conveyor_belt_4_left.active.delay", "2" },
+ { "conveyor_belt_4_right", "RocksDC.pcx" },
+ { "conveyor_belt_4_right.xpos", "0" },
+ { "conveyor_belt_4_right.ypos", "11" },
+ { "conveyor_belt_4_right.frames", "1" },
+ { "conveyor_belt_4_right.active", "RocksDC.pcx" },
+ { "conveyor_belt_4_right.active.xpos", "0" },
+ { "conveyor_belt_4_right.active.ypos", "11" },
+ { "conveyor_belt_4_right.active.frames", "8" },
+ { "conveyor_belt_4_right.active.delay", "2" },
+ { "conveyor_belt_4_switch_left", "RocksDC.pcx" },
+ { "conveyor_belt_4_switch_left.xpos", "3" },
+ { "conveyor_belt_4_switch_left.ypos", "12" },
+ { "conveyor_belt_4_switch_left.frames", "1" },
+ { "conveyor_belt_4_switch_middle", "RocksDC.pcx" },
+ { "conveyor_belt_4_switch_middle.xpos", "3" },
+ { "conveyor_belt_4_switch_middle.ypos", "13" },
+ { "conveyor_belt_4_switch_middle.frames", "1" },
+ { "conveyor_belt_4_switch_right", "RocksDC.pcx" },
+ { "conveyor_belt_4_switch_right.xpos", "3" },
+ { "conveyor_belt_4_switch_right.ypos", "14" },
+ { "conveyor_belt_4_switch_right.frames", "1" },
+
+ { "switchgate_switch_up", "RocksDC.pcx" },
+ { "switchgate_switch_up.xpos", "4" },
+ { "switchgate_switch_up.ypos", "12" },
+ { "switchgate_switch_up.frames", "1" },
+ { "switchgate_switch_down", "RocksDC.pcx" },
+ { "switchgate_switch_down.xpos", "5" },
+ { "switchgate_switch_down.ypos", "12" },
+ { "switchgate_switch_down.frames", "1" },
+
+ { "light_switch", "RocksDC.pcx" },
+ { "light_switch.xpos", "6" },
+ { "light_switch.ypos", "12" },
+ { "light_switch.frames", "1" },
+ { "light_switch.active", "RocksDC.pcx" },
+ { "light_switch.active.xpos", "7" },
+ { "light_switch.active.ypos", "12" },
+ { "light_switch.active.frames", "1" },
+
+ { "timegate_switch", "RocksDC.pcx" },
+ { "timegate_switch.xpos", "0" },
+ { "timegate_switch.ypos", "15" },
+ { "timegate_switch.frames", "1" },
+ { "timegate_switch.active", "RocksDC.pcx" },
+ { "timegate_switch.active.xpos", "0" },
+ { "timegate_switch.active.ypos", "15" },
+ { "timegate_switch.active.frames", "4" },
+
+ { "envelope", "RocksDC.pcx" },
+ { "envelope.xpos", "4" },
+ { "envelope.ypos", "14" },
+ { "envelope.frames", "1" },
+
+ { "sign_exclamation", "RocksDC.pcx" },
+ { "sign_exclamation.xpos", "5" },
+ { "sign_exclamation.ypos", "14" },
+ { "sign_exclamation.frames", "1" },
+
+ { "sign_stop", "RocksDC.pcx" },
+ { "sign_stop.xpos", "6" },
+ { "sign_stop.ypos", "14" },
+ { "sign_stop.frames", "1" },
+
+ { "landmine", "RocksDC.pcx" },
+ { "landmine.xpos", "7" },
+ { "landmine.ypos", "14" },
+ { "landmine.frames", "1" },
+ { "landmine.crumbled_like", "sand" },
+
+ { "steelwall_slippery", "RocksDC.pcx" },
+ { "steelwall_slippery.xpos", "5" },
+ { "steelwall_slippery.ypos", "15" },
+ { "steelwall_slippery.frames", "1" },
+
+ { "extra_time", "RocksDC.pcx" },
+ { "extra_time.xpos", "8" },
+ { "extra_time.ypos", "0" },
+ { "extra_time.frames", "6" },
+ { "extra_time.delay", "4" },
+
+ { "shield_normal", "RocksDC.pcx" },
+ { "shield_normal.xpos", "8" },
+ { "shield_normal.ypos", "2" },
+ { "shield_normal.frames", "6" },
+ { "shield_normal.delay", "4" },
+ { "shield_normal.active", "RocksHeroes.pcx" },
+ { "shield_normal.active.xpos", "1" },
+ { "shield_normal.active.ypos", "13" },
+ { "shield_normal.active.frames", "3" },
+ { "shield_normal.active.delay", "8" },
+ { "shield_normal.active.anim_mode", "pingpong" },
+
+ { "shield_deadly", "RocksDC.pcx" },
+ { "shield_deadly.xpos", "8" },
+ { "shield_deadly.ypos", "1" },
+ { "shield_deadly.frames", "6" },
+ { "shield_deadly.delay", "4" },
+ { "shield_deadly.active", "RocksHeroes.pcx" },
+ { "shield_deadly.active.xpos", "5" },
+ { "shield_deadly.active.ypos", "13" },
+ { "shield_deadly.active.frames", "3" },
+ { "shield_deadly.active.delay", "8" },
+ { "shield_deadly.active.anim_mode", "pingpong" },
+
+ { "switchgate_closed", "RocksDC.pcx" },
+ { "switchgate_closed.xpos", "8" },
+ { "switchgate_closed.ypos", "5" },
+ { "switchgate_closed.frames", "1" },
+ { "switchgate.opening", "RocksDC.pcx" },
+ { "switchgate.opening.xpos", "8" },
+ { "switchgate.opening.ypos", "5" },
+ { "switchgate.opening.frames", "5" },
+ { "switchgate.opening.delay", "6" },
+ { "switchgate_open", "RocksDC.pcx" },
+ { "switchgate_open.xpos", "12" },
+ { "switchgate_open.ypos", "5" },
+ { "switchgate_open.frames", "1" },
+ { "switchgate.closing", "RocksDC.pcx" },
+ { "switchgate.closing.xpos", "8" },
+ { "switchgate.closing.ypos", "5" },
+ { "switchgate.closing.frames", "5" },
+ { "switchgate.closing.delay", "6" },
+ { "switchgate.closing.anim_mode", "reverse" },
+
+ { "timegate_closed", "RocksDC.pcx" },
+ { "timegate_closed.xpos", "8" },
+ { "timegate_closed.ypos", "6" },
+ { "timegate_closed.frames", "1" },
+ { "timegate.opening", "RocksDC.pcx" },
+ { "timegate.opening.xpos", "8" },
+ { "timegate.opening.ypos", "6" },
+ { "timegate.opening.frames", "5" },
+ { "timegate.opening.delay", "6" },
+ { "timegate_open", "RocksDC.pcx" },
+ { "timegate_open.xpos", "12" },
+ { "timegate_open.ypos", "6" },
+ { "timegate_open.frames", "1" },
+ { "timegate.closing", "RocksDC.pcx" },
+ { "timegate.closing.xpos", "8" },
+ { "timegate.closing.ypos", "6" },
+ { "timegate.closing.frames", "5" },
+ { "timegate.closing.delay", "6" },
+ { "timegate.closing.anim_mode", "reverse" },
+
+ { "pearl", "RocksDC.pcx" },
+ { "pearl.xpos", "8" },
+ { "pearl.ypos", "11" },
+ { "pearl.frames", "1" },
+ { "pearl.breaking", "RocksDC.pcx" },
+ { "pearl.breaking.xpos", "8" },
+ { "pearl.breaking.ypos", "12" },
+ { "pearl.breaking.frames", "4" },
+ { "pearl.breaking.delay", "2" },
+ { "pearl.breaking.anim_mode", "linear" },
+
+ { "crystal", "RocksDC.pcx" },
+ { "crystal.xpos", "9" },
+ { "crystal.ypos", "11" },
+ { "crystal.frames", "1" },
+
+ { "wall_pearl", "RocksDC.pcx" },
+ { "wall_pearl.xpos", "10" },
+ { "wall_pearl.ypos", "11" },
+ { "wall_pearl.frames", "1" },
+
+ { "wall_crystal", "RocksDC.pcx" },
+ { "wall_crystal.xpos", "11" },
+ { "wall_crystal.ypos", "11" },
+ { "wall_crystal.frames", "1" },
+
+ /* images for DX Boulderdash style elements and actions */
+
+ { "tube_right_down", "RocksDC.pcx" },
+ { "tube_right_down.xpos", "9" },
+ { "tube_right_down.ypos", "13" },
+ { "tube_right_down.frames", "1" },
+
+ { "tube_horizontal_down", "RocksDC.pcx" },
+ { "tube_horizontal_down.xpos", "10" },
+ { "tube_horizontal_down.ypos", "13" },
+ { "tube_horizontal_down.frames", "1" },
+
+ { "tube_left_down", "RocksDC.pcx" },
+ { "tube_left_down.xpos", "11" },
+ { "tube_left_down.ypos", "13" },
+ { "tube_left_down.frames", "1" },
+
+ { "tube_horizontal", "RocksDC.pcx" },
+ { "tube_horizontal.xpos", "8" },
+ { "tube_horizontal.ypos", "14" },
+ { "tube_horizontal.frames", "1" },
+
+ { "tube_vertical_right", "RocksDC.pcx" },
+ { "tube_vertical_right.xpos", "9" },
+ { "tube_vertical_right.ypos", "14" },
+ { "tube_vertical_right.frames", "1" },
+
+ { "tube_any", "RocksDC.pcx" },
+ { "tube_any.xpos", "10" },
+ { "tube_any.ypos", "14" },
+ { "tube_any.frames", "1" },
+
+ { "tube_vertical_left", "RocksDC.pcx" },
+ { "tube_vertical_left.xpos", "11" },
+ { "tube_vertical_left.ypos", "14" },
+ { "tube_vertical_left.frames", "1" },
+
+ { "tube_vertical", "RocksDC.pcx" },
+ { "tube_vertical.xpos", "8" },
+ { "tube_vertical.ypos", "15" },
+ { "tube_vertical.frames", "1" },
+
+ { "tube_right_up", "RocksDC.pcx" },
+ { "tube_right_up.xpos", "9" },
+ { "tube_right_up.ypos", "15" },
+ { "tube_right_up.frames", "1" },
+
+ { "tube_horizontal_up", "RocksDC.pcx" },
+ { "tube_horizontal_up.xpos", "10" },
+ { "tube_horizontal_up.ypos", "15" },
+ { "tube_horizontal_up.frames", "1" },
+
+ { "tube_left_up", "RocksDC.pcx" },
+ { "tube_left_up.xpos", "11" },
+ { "tube_left_up.ypos", "15" },
+ { "tube_left_up.frames", "1" },
+
+ { "trap", "RocksDC.pcx" },
+ { "trap.xpos", "12" },
+ { "trap.ypos", "8" },
+ { "trap.frames", "1" },
+ { "trap.crumbled_like", "sand" },
+ { "trap.diggable_like", "sand" },
+ { "trap.active", "RocksDC.pcx" },
+ { "trap.active.xpos", "12" },
+ { "trap.active.ypos", "8" },
+ { "trap.active.frames", "4" },
+ { "trap.active.delay", "4" },
+ { "trap.active.anim_mode", "pingpong2" },
+ { "trap.active.crumbled_like", "sand" },
+
+ { "dx_supabomb", "RocksDC.pcx" },
+ { "dx_supabomb.xpos", "15" },
+ { "dx_supabomb.ypos", "9" },
+ { "dx_supabomb.frames", "1" },
+
+ /* images for Rocks'n'Diamonds style elements and actions */
+
+ { "key_1", "RocksElements.pcx" },
+ { "key_1.xpos", "4" },
+ { "key_1.ypos", "1" },
+ { "key_1.frames", "1" },
+ { "key_1.EDITOR", "RocksElements.pcx" },
+ { "key_1.EDITOR.xpos", "4" },
+ { "key_1.EDITOR.ypos", "14" },
+ { "key_2", "RocksElements.pcx" },
+ { "key_2.xpos", "5" },
+ { "key_2.ypos", "1" },
+ { "key_2.frames", "1" },
+ { "key_2.EDITOR", "RocksElements.pcx" },
+ { "key_2.EDITOR.xpos", "5" },
+ { "key_2.EDITOR.ypos", "14" },
+ { "key_3", "RocksElements.pcx" },
+ { "key_3.xpos", "6" },
+ { "key_3.ypos", "1" },
+ { "key_3.frames", "1" },
+ { "key_3.EDITOR", "RocksElements.pcx" },
+ { "key_3.EDITOR.xpos", "6" },
+ { "key_3.EDITOR.ypos", "14" },
+ { "key_4", "RocksElements.pcx" },
+ { "key_4.xpos", "7" },
+ { "key_4.ypos", "1" },
+ { "key_4.frames", "1" },
+ { "key_4.EDITOR", "RocksElements.pcx" },
+ { "key_4.EDITOR.xpos", "7" },
+ { "key_4.EDITOR.ypos", "14" },
+
+ { "gate_1", "RocksElements.pcx" },
+ { "gate_1.xpos", "4" },
+ { "gate_1.ypos", "2" },
+ { "gate_1.frames", "1" },
+ { "gate_2", "RocksElements.pcx" },
+ { "gate_2.xpos", "5" },
+ { "gate_2.ypos", "2" },
+ { "gate_2.frames", "1" },
+ { "gate_3", "RocksElements.pcx" },
+ { "gate_3.xpos", "6" },
+ { "gate_3.ypos", "2" },
+ { "gate_3.frames", "1" },
+ { "gate_4", "RocksElements.pcx" },
+ { "gate_4.xpos", "7" },
+ { "gate_4.ypos", "2" },
+ { "gate_4.frames", "1" },
+ { "gate_1_gray", "RocksElements.pcx" },
+ { "gate_1_gray.xpos", "8" },
+ { "gate_1_gray.ypos", "2" },
+ { "gate_1_gray.frames", "1" },
+ { "gate_1_gray.EDITOR", "RocksElements.pcx" },
+ { "gate_1_gray.EDITOR.xpos", "8" },
+ { "gate_1_gray.EDITOR.ypos", "14" },
+ { "gate_2_gray", "RocksElements.pcx" },
+ { "gate_2_gray.xpos", "9" },
+ { "gate_2_gray.ypos", "2" },
+ { "gate_2_gray.frames", "1" },
+ { "gate_2_gray.EDITOR", "RocksElements.pcx" },
+ { "gate_2_gray.EDITOR.xpos", "9" },
+ { "gate_2_gray.EDITOR.ypos", "14" },
+ { "gate_3_gray", "RocksElements.pcx" },
+ { "gate_3_gray.xpos", "10" },
+ { "gate_3_gray.ypos", "2" },
+ { "gate_3_gray.frames", "1" },
+ { "gate_3_gray.EDITOR", "RocksElements.pcx" },
+ { "gate_3_gray.EDITOR.xpos", "10" },
+ { "gate_3_gray.EDITOR.ypos", "14" },
+ { "gate_4_gray", "RocksElements.pcx" },
+ { "gate_4_gray.xpos", "11" },
+ { "gate_4_gray.ypos", "2" },
+ { "gate_4_gray.frames", "1" },
+ { "gate_4_gray.EDITOR", "RocksElements.pcx" },
+ { "gate_4_gray.EDITOR.xpos", "11" },
+ { "gate_4_gray.EDITOR.ypos", "14" },
+
+ { "game_of_life", "RocksElements.pcx" },
+ { "game_of_life.xpos", "8" },
+ { "game_of_life.ypos", "1" },
+ { "game_of_life.frames", "1" },
+
+ { "biomaze", "RocksElements.pcx" },
+ { "biomaze.xpos", "9" },
+ { "biomaze.ypos", "1" },
+ { "biomaze.frames", "1" },
+
+ { "pacman", "RocksElements.pcx" },
+ { "pacman.xpos", "8" },
+ { "pacman.ypos", "5" },
+ { "pacman.frames", "4" },
+ { "pacman.delay", "8" },
+ { "pacman.right", "RocksElements.pcx" },
+ { "pacman.right.xpos", "8" },
+ { "pacman.right.ypos", "5" },
+ { "pacman.right.frames", "1" },
+ { "pacman.up", "RocksElements.pcx" },
+ { "pacman.up.xpos", "9" },
+ { "pacman.up.ypos", "5" },
+ { "pacman.up.frames", "1" },
+ { "pacman.left", "RocksElements.pcx" },
+ { "pacman.left.xpos", "10" },
+ { "pacman.left.ypos", "5" },
+ { "pacman.left.frames", "1" },
+ { "pacman.down", "RocksElements.pcx" },
+ { "pacman.down.xpos", "11" },
+ { "pacman.down.ypos", "5" },
+ { "pacman.down.frames", "1" },
+ { "pacman.moving.right", "RocksElements.pcx" },
+ { "pacman.moving.right.xpos", "8" },
+ { "pacman.moving.right.ypos", "5" },
+ { "pacman.moving.right.frames", "2" },
+ { "pacman.moving.right.anim_mode", "reverse" },
+ { "pacman.moving.right.delay", "4" },
+ { "pacman.moving.right.offset", "128" },
+ { "pacman.moving.up", "RocksElements.pcx" },
+ { "pacman.moving.up.xpos", "9" },
+ { "pacman.moving.up.ypos", "5" },
+ { "pacman.moving.up.frames", "2" },
+ { "pacman.moving.up.anim_mode", "reverse" },
+ { "pacman.moving.up.delay", "4" },
+ { "pacman.moving.up.offset", "128" },
+ { "pacman.moving.left", "RocksElements.pcx" },
+ { "pacman.moving.left.xpos", "10" },
+ { "pacman.moving.left.ypos", "5" },
+ { "pacman.moving.left.frames", "2" },
+ { "pacman.moving.left.anim_mode", "reverse" },
+ { "pacman.moving.left.delay", "4" },
+ { "pacman.moving.left.offset", "128" },
+ { "pacman.moving.down", "RocksElements.pcx" },
+ { "pacman.moving.down.xpos", "11" },
+ { "pacman.moving.down.ypos", "5" },
+ { "pacman.moving.down.frames", "2" },
+ { "pacman.moving.down.anim_mode", "reverse" },
+ { "pacman.moving.down.delay", "4" },
+ { "pacman.moving.down.offset", "128" },
+
+ { "lamp", "RocksElements.pcx" },
+ { "lamp.xpos", "0" },
+ { "lamp.ypos", "7" },
+ { "lamp.frames", "1" },
+ { "lamp.EDITOR", "RocksElements.pcx" },
+ { "lamp.EDITOR.xpos", "2" },
+ { "lamp.EDITOR.ypos", "14" },
+ { "lamp.active", "RocksElements.pcx" },
+ { "lamp.active.xpos", "1" },
+ { "lamp.active.ypos", "7" },
+ { "lamp.active.frames", "1" },
+
+ { "time_orb_full", "RocksElements.pcx" },
+ { "time_orb_full.xpos", "2" },
+ { "time_orb_full.ypos", "7" },
+ { "time_orb_full.frames", "1" },
+ { "time_orb_empty", "RocksElements.pcx" },
+ { "time_orb_empty.xpos", "3" },
+ { "time_orb_empty.ypos", "7" },
+ { "time_orb_empty.frames", "1" },
+
+ { "emerald_yellow", "RocksElements.pcx" },
+ { "emerald_yellow.xpos", "10" },
+ { "emerald_yellow.ypos", "8" },
+ { "emerald_yellow.frames", "1" },
+ { "emerald_yellow.moving", "RocksElements.pcx" },
+ { "emerald_yellow.moving.xpos", "10" },
+ { "emerald_yellow.moving.ypos", "8" },
+ { "emerald_yellow.moving.frames", "2" },
+ { "emerald_yellow.moving.delay", "4" },
+ { "emerald_yellow.falling", "RocksElements.pcx" },
+ { "emerald_yellow.falling.xpos", "10" },
+ { "emerald_yellow.falling.ypos", "8" },
+ { "emerald_yellow.falling.frames", "2" },
+ { "emerald_yellow.falling.delay", "4" },
+ { "emerald_red", "RocksElements.pcx" },
+ { "emerald_red.xpos", "8" },
+ { "emerald_red.ypos", "9" },
+ { "emerald_red.frames", "1" },
+ { "emerald_red.moving", "RocksElements.pcx" },
+ { "emerald_red.moving.xpos", "8" },
+ { "emerald_red.moving.ypos", "9" },
+ { "emerald_red.moving.frames", "2" },
+ { "emerald_red.moving.delay", "4" },
+ { "emerald_red.falling", "RocksElements.pcx" },
+ { "emerald_red.falling.xpos", "8" },
+ { "emerald_red.falling.ypos", "9" },
+ { "emerald_red.falling.frames", "2" },
+ { "emerald_red.falling.delay", "4" },
+ { "emerald_purple", "RocksElements.pcx" },
+ { "emerald_purple.xpos", "10" },
+ { "emerald_purple.ypos", "9" },
+ { "emerald_purple.frames", "1" },
+ { "emerald_purple.moving", "RocksElements.pcx" },
+ { "emerald_purple.moving.xpos", "10" },
+ { "emerald_purple.moving.ypos", "9" },
+ { "emerald_purple.moving.frames", "2" },
+ { "emerald_purple.moving.delay", "4" },
+ { "emerald_purple.falling", "RocksElements.pcx" },
+ { "emerald_purple.falling.xpos", "10" },
+ { "emerald_purple.falling.ypos", "9" },
+ { "emerald_purple.falling.frames", "2" },
+ { "emerald_purple.falling.delay", "4" },
+
+ { "wall_emerald_yellow", "RocksElements.pcx" },
+ { "wall_emerald_yellow.xpos", "8" },
+ { "wall_emerald_yellow.ypos", "8" },
+ { "wall_emerald_yellow.frames", "1" },
+ { "wall_emerald_red", "RocksElements.pcx" },
+ { "wall_emerald_red.xpos", "6" },
+ { "wall_emerald_red.ypos", "8" },
+ { "wall_emerald_red.frames", "1" },
+ { "wall_emerald_purple", "RocksElements.pcx" },
+ { "wall_emerald_purple.xpos", "7" },
+ { "wall_emerald_purple.ypos", "8" },
+ { "wall_emerald_purple.frames", "1" },
+ { "wall_bd_diamond", "RocksElements.pcx" },
+ { "wall_bd_diamond.xpos", "9" },
+ { "wall_bd_diamond.ypos", "8" },
+ { "wall_bd_diamond.frames", "1" },
+
+ { "expandable_wall", "RocksElements.pcx" },
+ { "expandable_wall.xpos", "11" },
+ { "expandable_wall.ypos", "10" },
+ { "expandable_wall.frames", "1" },
+ { "expandable_wall_horizontal", "RocksElements.pcx" },
+ { "expandable_wall_horizontal.xpos", "5" },
+ { "expandable_wall_horizontal.ypos", "9" },
+ { "expandable_wall_horizontal.frames", "1" },
+ { "expandable_wall_horizontal.EDITOR", "RocksElements.pcx" },
+ { "expandable_wall_horizontal.EDITOR.xpos", "13" },
+ { "expandable_wall_horizontal.EDITOR.ypos", "13" },
+ { "expandable_wall_vertical", "RocksElements.pcx" },
+ { "expandable_wall_vertical.xpos", "6" },
+ { "expandable_wall_vertical.ypos", "9" },
+ { "expandable_wall_vertical.frames", "1" },
+ { "expandable_wall_vertical.EDITOR", "RocksElements.pcx" },
+ { "expandable_wall_vertical.EDITOR.xpos", "14" },
+ { "expandable_wall_vertical.EDITOR.ypos", "13" },
+ { "expandable_wall_any", "RocksElements.pcx" },
+ { "expandable_wall_any.xpos", "4" },
+ { "expandable_wall_any.ypos", "9" },
+ { "expandable_wall_any.frames", "1" },
+ { "expandable_wall_any.EDITOR", "RocksElements.pcx" },
+ { "expandable_wall_any.EDITOR.xpos", "12" },
+ { "expandable_wall_any.EDITOR.ypos", "13" },
+
+ { "expandable_wall.growing.left", "RocksElements.pcx" },
+ { "expandable_wall.growing.left.xpos", "8" },
+ { "expandable_wall.growing.left.ypos", "10" },
+ { "expandable_wall.growing.left.frames", "3" },
+ { "expandable_wall.growing.left.delay", "6" },
+ { "expandable_wall.growing.left.anim_mode", "linear" },
+ { "expandable_wall.growing.right", "RocksElements.pcx" },
+ { "expandable_wall.growing.right.xpos", "5" },
+ { "expandable_wall.growing.right.ypos", "10" },
+ { "expandable_wall.growing.right.frames", "3" },
+ { "expandable_wall.growing.right.delay", "6" },
+ { "expandable_wall.growing.right.anim_mode", "linear" },
+ { "expandable_wall.growing.up", "RocksHeroes.pcx" },
+ { "expandable_wall.growing.up.xpos", "3" },
+ { "expandable_wall.growing.up.ypos", "12" },
+ { "expandable_wall.growing.up.frames", "3" },
+ { "expandable_wall.growing.up.delay", "6" },
+ { "expandable_wall.growing.up.anim_mode", "linear" },
+ { "expandable_wall.growing.down", "RocksHeroes.pcx" },
+ { "expandable_wall.growing.down.xpos", "0" },
+ { "expandable_wall.growing.down.ypos", "12" },
+ { "expandable_wall.growing.down.frames", "3" },
+ { "expandable_wall.growing.down.delay", "6" },
+ { "expandable_wall.growing.down.anim_mode", "linear" },
+
+ { "black_orb", "RocksElements.pcx" },
+ { "black_orb.xpos", "13" },
+ { "black_orb.ypos", "9" },
+ { "black_orb.frames", "1" },
+
+ { "speed_pill", "RocksElements.pcx" },
+ { "speed_pill.xpos", "14" },
+ { "speed_pill.ypos", "9" },
+ { "speed_pill.frames", "1" },
+
+ { "dark_yamyam", "RocksElements.pcx" },
+ { "dark_yamyam.xpos", "8" },
+ { "dark_yamyam.ypos", "11" },
+ { "dark_yamyam.frames", "4" },
+ { "dark_yamyam.anim_mode", "pingpong2" },
+
+ { "dynabomb", "RocksElements.pcx" },
+ { "dynabomb.xpos", "12" },
+ { "dynabomb.ypos", "11" },
+ { "dynabomb.frames", "1" },
+ { "dynabomb.active", "RocksElements.pcx" },
+ { "dynabomb.active.xpos", "12" },
+ { "dynabomb.active.ypos", "11" },
+ { "dynabomb.active.frames", "4" },
+ { "dynabomb.active.delay", "6" },
+ { "dynabomb.active.anim_mode", "pingpong" },
+ { "dynabomb_player_1", "RocksElements.pcx" },
+ { "dynabomb_player_1.xpos", "12" },
+ { "dynabomb_player_1.ypos", "11" },
+ { "dynabomb_player_1.frames", "1" },
+ { "dynabomb_player_1.active", "RocksElements.pcx" },
+ { "dynabomb_player_1.active.xpos", "12" },
+ { "dynabomb_player_1.active.ypos", "11" },
+ { "dynabomb_player_1.active.frames", "4" },
+ { "dynabomb_player_1.active.delay", "6" },
+ { "dynabomb_player_1.active.anim_mode", "pingpong" },
+ { "dynabomb_player_2", "RocksElements.pcx" },
+ { "dynabomb_player_2.xpos", "12" },
+ { "dynabomb_player_2.ypos", "11" },
+ { "dynabomb_player_2.frames", "1" },
+ { "dynabomb_player_2.active", "RocksElements.pcx" },
+ { "dynabomb_player_2.active.xpos", "12" },
+ { "dynabomb_player_2.active.ypos", "11" },
+ { "dynabomb_player_2.active.frames", "4" },
+ { "dynabomb_player_2.active.delay", "6" },
+ { "dynabomb_player_2.active.anim_mode", "pingpong" },
+ { "dynabomb_player_3", "RocksElements.pcx" },
+ { "dynabomb_player_3.xpos", "12" },
+ { "dynabomb_player_3.ypos", "11" },
+ { "dynabomb_player_3.frames", "1" },
+ { "dynabomb_player_3.active", "RocksElements.pcx" },
+ { "dynabomb_player_3.active.xpos", "12" },
+ { "dynabomb_player_3.active.ypos", "11" },
+ { "dynabomb_player_3.active.frames", "4" },
+ { "dynabomb_player_3.active.delay", "6" },
+ { "dynabomb_player_3.active.anim_mode", "pingpong" },
+ { "dynabomb_player_4", "RocksElements.pcx" },
+ { "dynabomb_player_4.xpos", "12" },
+ { "dynabomb_player_4.ypos", "11" },
+ { "dynabomb_player_4.frames", "1" },
+ { "dynabomb_player_4.active", "RocksElements.pcx" },
+ { "dynabomb_player_4.active.xpos", "12" },
+ { "dynabomb_player_4.active.ypos", "11" },
+ { "dynabomb_player_4.active.frames", "4" },
+ { "dynabomb_player_4.active.delay", "6" },
+ { "dynabomb_player_4.active.anim_mode", "pingpong" },
+ { "dynabomb_increase_number", "RocksElements.pcx" },
+ { "dynabomb_increase_number.xpos", "12" },
+ { "dynabomb_increase_number.ypos", "11" },
+ { "dynabomb_increase_number.frames", "1" },
+ { "dynabomb_increase_size", "RocksElements.pcx" },
+ { "dynabomb_increase_size.xpos", "15" },
+ { "dynabomb_increase_size.ypos", "11" },
+ { "dynabomb_increase_size.frames", "1" },
+ { "dynabomb_increase_power", "RocksElements.pcx" },
+ { "dynabomb_increase_power.xpos", "12" },
+ { "dynabomb_increase_power.ypos", "9" },
+ { "dynabomb_increase_power.frames", "1" },
+
+ { "pig", "RocksHeroes.pcx" },
+ { "pig.xpos", "8" },
+ { "pig.ypos", "0" },
+ { "pig.frames", "1" },
+ { "pig.down", "RocksHeroes.pcx" },
+ { "pig.down.xpos", "8" },
+ { "pig.down.ypos", "0" },
+ { "pig.down.frames", "1" },
+ { "pig.up", "RocksHeroes.pcx" },
+ { "pig.up.xpos", "12" },
+ { "pig.up.ypos", "0" },
+ { "pig.up.frames", "1" },
+ { "pig.left", "RocksHeroes.pcx" },
+ { "pig.left.xpos", "8" },
+ { "pig.left.ypos", "1" },
+ { "pig.left.frames", "1" },
+ { "pig.right", "RocksHeroes.pcx" },
+ { "pig.right.xpos", "12" },
+ { "pig.right.ypos", "1" },
+ { "pig.right.frames", "1" },
+ { "pig.moving.down", "RocksHeroes.pcx" },
+ { "pig.moving.down.xpos", "8" },
+ { "pig.moving.down.ypos", "0" },
+ { "pig.moving.down.frames", "4" },
+ { "pig.moving.down.delay", "2" },
+ { "pig.moving.up", "RocksHeroes.pcx" },
+ { "pig.moving.up.xpos", "12" },
+ { "pig.moving.up.ypos", "0" },
+ { "pig.moving.up.frames", "4" },
+ { "pig.moving.up.delay", "2" },
+ { "pig.moving.left", "RocksHeroes.pcx" },
+ { "pig.moving.left.xpos", "8" },
+ { "pig.moving.left.ypos", "1" },
+ { "pig.moving.left.frames", "4" },
+ { "pig.moving.left.delay", "2" },
+ { "pig.moving.right", "RocksHeroes.pcx" },
+ { "pig.moving.right.xpos", "12" },
+ { "pig.moving.right.ypos", "1" },
+ { "pig.moving.right.frames", "4" },
+ { "pig.moving.right.delay", "2" },
+ { "pig.digging.down", "RocksHeroes.pcx" },
+ { "pig.digging.down.xpos", "8" },
+ { "pig.digging.down.ypos", "0" },
+ { "pig.digging.down.frames", "4" },
+ { "pig.digging.down.delay", "2" },
+ { "pig.digging.up", "RocksHeroes.pcx" },
+ { "pig.digging.up.xpos", "12" },
+ { "pig.digging.up.ypos", "0" },
+ { "pig.digging.up.frames", "4" },
+ { "pig.digging.up.delay", "2" },
+ { "pig.digging.left", "RocksHeroes.pcx" },
+ { "pig.digging.left.xpos", "8" },
+ { "pig.digging.left.ypos", "1" },
+ { "pig.digging.left.frames", "4" },
+ { "pig.digging.left.delay", "2" },
+ { "pig.digging.right", "RocksHeroes.pcx" },
+ { "pig.digging.right.xpos", "12" },
+ { "pig.digging.right.ypos", "1" },
+ { "pig.digging.right.frames", "4" },
+ { "pig.digging.right.delay", "2" },
+
+ { "dragon", "RocksHeroes.pcx" },
+ { "dragon.xpos", "8" },
+ { "dragon.ypos", "2" },
+ { "dragon.frames", "1" },
+ { "dragon.down", "RocksHeroes.pcx" },
+ { "dragon.down.xpos", "8" },
+ { "dragon.down.ypos", "2" },
+ { "dragon.down.frames", "1" },
+ { "dragon.up", "RocksHeroes.pcx" },
+ { "dragon.up.xpos", "12" },
+ { "dragon.up.ypos", "2" },
+ { "dragon.up.frames", "1" },
+ { "dragon.left", "RocksHeroes.pcx" },
+ { "dragon.left.xpos", "8" },
+ { "dragon.left.ypos", "3" },
+ { "dragon.left.frames", "1" },
+ { "dragon.right", "RocksHeroes.pcx" },
+ { "dragon.right.xpos", "12" },
+ { "dragon.right.ypos", "3" },
+ { "dragon.right.frames", "1" },
+ { "dragon.moving.down", "RocksHeroes.pcx" },
+ { "dragon.moving.down.xpos", "8" },
+ { "dragon.moving.down.ypos", "2" },
+ { "dragon.moving.down.frames", "4" },
+ { "dragon.moving.down.delay", "2" },
+ { "dragon.moving.up", "RocksHeroes.pcx" },
+ { "dragon.moving.up.xpos", "12" },
+ { "dragon.moving.up.ypos", "2" },
+ { "dragon.moving.up.frames", "4" },
+ { "dragon.moving.up.delay", "2" },
+ { "dragon.moving.left", "RocksHeroes.pcx" },
+ { "dragon.moving.left.xpos", "8" },
+ { "dragon.moving.left.ypos", "3" },
+ { "dragon.moving.left.frames", "4" },
+ { "dragon.moving.left.delay", "2" },
+ { "dragon.moving.right", "RocksHeroes.pcx" },
+ { "dragon.moving.right.xpos", "12" },
+ { "dragon.moving.right.ypos", "3" },
+ { "dragon.moving.right.frames", "4" },
+ { "dragon.moving.right.delay", "2" },
+ { "dragon.attacking.down", "RocksHeroes.pcx" },
+ { "dragon.attacking.down.xpos", "8" },
+ { "dragon.attacking.down.ypos", "2" },
+ { "dragon.attacking.down.frames", "1" },
+ { "dragon.attacking.up", "RocksHeroes.pcx" },
+ { "dragon.attacking.up.xpos", "12" },
+ { "dragon.attacking.up.ypos", "2" },
+ { "dragon.attacking.up.frames", "1" },
+ { "dragon.attacking.left", "RocksHeroes.pcx" },
+ { "dragon.attacking.left.xpos", "8" },
+ { "dragon.attacking.left.ypos", "3" },
+ { "dragon.attacking.left.frames", "1" },
+ { "dragon.attacking.right", "RocksHeroes.pcx" },
+ { "dragon.attacking.right.xpos", "12" },
+ { "dragon.attacking.right.ypos", "3" },
+ { "dragon.attacking.right.frames", "1" },
+
+ { "mole", "RocksHeroes.pcx" },
+ { "mole.xpos", "8" },
+ { "mole.ypos", "4" },
+ { "mole.frames", "1" },
+ { "mole.down", "RocksHeroes.pcx" },
+ { "mole.down.xpos", "8" },
+ { "mole.down.ypos", "4" },
+ { "mole.down.frames", "1" },
+ { "mole.up", "RocksHeroes.pcx" },
+ { "mole.up.xpos", "12" },
+ { "mole.up.ypos", "4" },
+ { "mole.up.frames", "1" },
+ { "mole.left", "RocksHeroes.pcx" },
+ { "mole.left.xpos", "8" },
+ { "mole.left.ypos", "5" },
+ { "mole.left.frames", "1" },
+ { "mole.right", "RocksHeroes.pcx" },
+ { "mole.right.xpos", "12" },
+ { "mole.right.ypos", "5" },
+ { "mole.right.frames", "1" },
+ { "mole.moving.down", "RocksHeroes.pcx" },
+ { "mole.moving.down.xpos", "8" },
+ { "mole.moving.down.ypos", "4" },
+ { "mole.moving.down.frames", "4" },
+ { "mole.moving.down.delay", "2" },
+ { "mole.moving.up", "RocksHeroes.pcx" },
+ { "mole.moving.up.xpos", "12" },
+ { "mole.moving.up.ypos", "4" },
+ { "mole.moving.up.frames", "4" },
+ { "mole.moving.up.delay", "2" },
+ { "mole.moving.left", "RocksHeroes.pcx" },
+ { "mole.moving.left.xpos", "8" },
+ { "mole.moving.left.ypos", "5" },
+ { "mole.moving.left.frames", "4" },
+ { "mole.moving.left.delay", "2" },
+ { "mole.moving.right", "RocksHeroes.pcx" },
+ { "mole.moving.right.xpos", "12" },
+ { "mole.moving.right.ypos", "5" },
+ { "mole.moving.right.frames", "4" },
+ { "mole.moving.right.delay", "2" },
+ { "mole.digging.down", "RocksHeroes.pcx" },
+ { "mole.digging.down.xpos", "8" },
+ { "mole.digging.down.ypos", "4" },
+ { "mole.digging.down.frames", "4" },
+ { "mole.digging.down.delay", "2" },
+ { "mole.digging.up", "RocksHeroes.pcx" },
+ { "mole.digging.up.xpos", "12" },
+ { "mole.digging.up.ypos", "4" },
+ { "mole.digging.up.frames", "4" },
+ { "mole.digging.up.delay", "2" },
+ { "mole.digging.left", "RocksHeroes.pcx" },
+ { "mole.digging.left.xpos", "8" },
+ { "mole.digging.left.ypos", "5" },
+ { "mole.digging.left.frames", "4" },
+ { "mole.digging.left.delay", "2" },
+ { "mole.digging.right", "RocksHeroes.pcx" },
+ { "mole.digging.right.xpos", "12" },
+ { "mole.digging.right.ypos", "5" },
+ { "mole.digging.right.frames", "4" },
+ { "mole.digging.right.delay", "2" },
+
+ { "penguin", "RocksHeroes.pcx" },
+ { "penguin.xpos", "8" },
+ { "penguin.ypos", "6" },
+ { "penguin.frames", "1" },
+ { "penguin.EDITOR", "RocksElements.pcx" },
+ { "penguin.EDITOR.xpos", "12" },
+ { "penguin.EDITOR.ypos", "14" },
+ { "penguin.down", "RocksHeroes.pcx" },
+ { "penguin.down.xpos", "8" },
+ { "penguin.down.ypos", "6" },
+ { "penguin.down.frames", "1" },
+ { "penguin.up", "RocksHeroes.pcx" },
+ { "penguin.up.xpos", "12" },
+ { "penguin.up.ypos", "6" },
+ { "penguin.up.frames", "1" },
+ { "penguin.left", "RocksHeroes.pcx" },
+ { "penguin.left.xpos", "8" },
+ { "penguin.left.ypos", "7" },
+ { "penguin.left.frames", "1" },
+ { "penguin.right", "RocksHeroes.pcx" },
+ { "penguin.right.xpos", "12" },
+ { "penguin.right.ypos", "7" },
+ { "penguin.right.frames", "1" },
+ { "penguin.moving.down", "RocksHeroes.pcx" },
+ { "penguin.moving.down.xpos", "8" },
+ { "penguin.moving.down.ypos", "6" },
+ { "penguin.moving.down.frames", "4" },
+ { "penguin.moving.down.delay", "2" },
+ { "penguin.moving.up", "RocksHeroes.pcx" },
+ { "penguin.moving.up.xpos", "12" },
+ { "penguin.moving.up.ypos", "6" },
+ { "penguin.moving.up.frames", "4" },
+ { "penguin.moving.up.delay", "2" },
+ { "penguin.moving.left", "RocksHeroes.pcx" },
+ { "penguin.moving.left.xpos", "8" },
+ { "penguin.moving.left.ypos", "7" },
+ { "penguin.moving.left.frames", "4" },
+ { "penguin.moving.left.delay", "2" },
+ { "penguin.moving.right", "RocksHeroes.pcx" },
+ { "penguin.moving.right.xpos", "12" },
+ { "penguin.moving.right.ypos", "7" },
+ { "penguin.moving.right.frames", "4" },
+ { "penguin.moving.right.delay", "2" },
+
+ { "satellite", "RocksHeroes.pcx" },
+ { "satellite.xpos", "8" },
+ { "satellite.ypos", "9" },
+ { "satellite.frames", "8" },
+ { "satellite.delay", "2" },
+ { "satellite.global_sync", "true" },
+
+ { "flames_1_left", "RocksHeroes.pcx" },
+ { "flames_1_left.xpos", "8" },
+ { "flames_1_left.ypos", "12" },
+ { "flames_1_left.frames", "2" },
+ { "flames_1_left.offset", "96" },
+ { "flames_2_left", "RocksHeroes.pcx" },
+ { "flames_2_left.xpos", "9" },
+ { "flames_2_left.ypos", "12" },
+ { "flames_2_left.frames", "2" },
+ { "flames_2_left.offset", "96" },
+ { "flames_3_left", "RocksHeroes.pcx" },
+ { "flames_3_left.xpos", "10" },
+ { "flames_3_left.ypos", "12" },
+ { "flames_3_left.frames", "2" },
+ { "flames_3_left.offset", "96" },
+
+ { "flames_1_right", "RocksHeroes.pcx" },
+ { "flames_1_right.xpos", "8" },
+ { "flames_1_right.ypos", "13" },
+ { "flames_1_right.frames", "2" },
+ { "flames_1_right.offset", "96" },
+ { "flames_2_right", "RocksHeroes.pcx" },
+ { "flames_2_right.xpos", "9" },
+ { "flames_2_right.ypos", "13" },
+ { "flames_2_right.frames", "2" },
+ { "flames_2_right.offset", "96" },
+ { "flames_3_right", "RocksHeroes.pcx" },
+ { "flames_3_right.xpos", "10" },
+ { "flames_3_right.ypos", "13" },
+ { "flames_3_right.frames", "2" },
+ { "flames_3_right.offset", "96" },
+
+ { "flames_1_up", "RocksHeroes.pcx" },
+ { "flames_1_up.xpos", "8" },
+ { "flames_1_up.ypos", "14" },
+ { "flames_1_up.frames", "2" },
+ { "flames_1_up.offset", "96" },
+ { "flames_2_up", "RocksHeroes.pcx" },
+ { "flames_2_up.xpos", "9" },
+ { "flames_2_up.ypos", "14" },
+ { "flames_2_up.frames", "2" },
+ { "flames_2_up.offset", "96" },
+ { "flames_3_up", "RocksHeroes.pcx" },
+ { "flames_3_up.xpos", "10" },
+ { "flames_3_up.ypos", "14" },
+ { "flames_3_up.frames", "2" },
+ { "flames_3_up.offset", "96" },
+
+ { "flames_1_down", "RocksHeroes.pcx" },
+ { "flames_1_down.xpos", "8" },
+ { "flames_1_down.ypos", "15" },
+ { "flames_1_down.frames", "2" },
+ { "flames_1_down.offset", "96" },
+ { "flames_2_down", "RocksHeroes.pcx" },
+ { "flames_2_down.xpos", "9" },
+ { "flames_2_down.ypos", "15" },
+ { "flames_2_down.frames", "2" },
+ { "flames_2_down.offset", "96" },
+ { "flames_3_down", "RocksHeroes.pcx" },
+ { "flames_3_down.xpos", "10" },
+ { "flames_3_down.ypos", "15" },
+ { "flames_3_down.frames", "2" },
+ { "flames_3_down.offset", "96" },
+
+ { "stoneblock", "RocksElements.pcx" },
+ { "stoneblock.xpos", "10" },
+ { "stoneblock.ypos", "1" },
+ { "stoneblock.frames", "1" },
+
+ /* images for other elements and actions */
+
+ { "player_1", "RocksHeroes.pcx" },
+ { "player_1.xpos", "0" },
+ { "player_1.ypos", "0" },
+ { "player_1.frames", "1" },
+ { "player_1.EDITOR", "RocksElements.pcx" },
+ { "player_1.EDITOR.xpos", "4" },
+ { "player_1.EDITOR.ypos", "7" },
+ { "player_1.down", "RocksHeroes.pcx" },
+ { "player_1.down.xpos", "0" },
+ { "player_1.down.ypos", "0" },
+ { "player_1.down.frames", "1" },
+ { "player_1.up", "RocksHeroes.pcx" },
+ { "player_1.up.xpos", "4" },
+ { "player_1.up.ypos", "0" },
+ { "player_1.up.frames", "1" },
+ { "player_1.left", "RocksHeroes.pcx" },
+ { "player_1.left.xpos", "0" },
+ { "player_1.left.ypos", "1" },
+ { "player_1.left.frames", "1" },
+ { "player_1.right", "RocksHeroes.pcx" },
+ { "player_1.right.xpos", "4" },
+ { "player_1.right.ypos", "1" },
+ { "player_1.right.frames", "1" },
+ { "player_1.moving.down", "RocksHeroes.pcx" },
+ { "player_1.moving.down.xpos", "0" },
+ { "player_1.moving.down.ypos", "0" },
+ { "player_1.moving.down.frames", "4" },
+ { "player_1.moving.down.start_frame", "1" },
+ { "player_1.moving.down.delay", "4" },
+ { "player_1.moving.up", "RocksHeroes.pcx" },
+ { "player_1.moving.up.xpos", "4" },
+ { "player_1.moving.up.ypos", "0" },
+ { "player_1.moving.up.frames", "4" },
+ { "player_1.moving.up.start_frame", "1" },
+ { "player_1.moving.up.delay", "4" },
+ { "player_1.moving.left", "RocksHeroes.pcx" },
+ { "player_1.moving.left.xpos", "0" },
+ { "player_1.moving.left.ypos", "1" },
+ { "player_1.moving.left.frames", "4" },
+ { "player_1.moving.left.start_frame", "1" },
+ { "player_1.moving.left.delay", "4" },
+ { "player_1.moving.right", "RocksHeroes.pcx" },
+ { "player_1.moving.right.xpos", "4" },
+ { "player_1.moving.right.ypos", "1" },
+ { "player_1.moving.right.frames", "4" },
+ { "player_1.moving.right.start_frame", "1" },
+ { "player_1.moving.right.delay", "4" },
+ { "player_1.digging.down", "RocksHeroes.pcx" },
+ { "player_1.digging.down.xpos", "0" },
+ { "player_1.digging.down.ypos", "0" },
+ { "player_1.digging.down.frames", "4" },
+ { "player_1.digging.down.start_frame", "1" },
+ { "player_1.digging.down.delay", "4" },
+ { "player_1.digging.up", "RocksHeroes.pcx" },
+ { "player_1.digging.up.xpos", "4" },
+ { "player_1.digging.up.ypos", "0" },
+ { "player_1.digging.up.frames", "4" },
+ { "player_1.digging.up.start_frame", "1" },
+ { "player_1.digging.up.delay", "4" },
+ { "player_1.digging.left", "RocksHeroes.pcx" },
+ { "player_1.digging.left.xpos", "0" },
+ { "player_1.digging.left.ypos", "1" },
+ { "player_1.digging.left.frames", "4" },
+ { "player_1.digging.left.start_frame", "1" },
+ { "player_1.digging.left.delay", "4" },
+ { "player_1.digging.right", "RocksHeroes.pcx" },
+ { "player_1.digging.right.xpos", "4" },
+ { "player_1.digging.right.ypos", "1" },
+ { "player_1.digging.right.frames", "4" },
+ { "player_1.digging.right.start_frame", "1" },
+ { "player_1.digging.right.delay", "4" },
+ { "player_1.collecting.down", "RocksHeroes.pcx" },
+ { "player_1.collecting.down.xpos", "0" },
+ { "player_1.collecting.down.ypos", "0" },
+ { "player_1.collecting.down.frames", "4" },
+ { "player_1.collecting.down.start_frame", "1" },
+ { "player_1.collecting.down.delay", "4" },
+ { "player_1.collecting.up", "RocksHeroes.pcx" },
+ { "player_1.collecting.up.xpos", "4" },
+ { "player_1.collecting.up.ypos", "0" },
+ { "player_1.collecting.up.frames", "4" },
+ { "player_1.collecting.up.start_frame", "1" },
+ { "player_1.collecting.up.delay", "4" },
+ { "player_1.collecting.left", "RocksHeroes.pcx" },
+ { "player_1.collecting.left.xpos", "0" },
+ { "player_1.collecting.left.ypos", "1" },
+ { "player_1.collecting.left.frames", "4" },
+ { "player_1.collecting.left.start_frame", "1" },
+ { "player_1.collecting.left.delay", "4" },
+ { "player_1.collecting.right", "RocksHeroes.pcx" },
+ { "player_1.collecting.right.xpos", "4" },
+ { "player_1.collecting.right.ypos", "1" },
+ { "player_1.collecting.right.frames", "4" },
+ { "player_1.collecting.right.start_frame", "1" },
+ { "player_1.collecting.right.delay", "4" },
+ { "player_1.pushing.down", "RocksHeroes.pcx" },
+ { "player_1.pushing.down.xpos", "0" },
+ { "player_1.pushing.down.ypos", "0" },
+ { "player_1.pushing.down.frames", "4" },
+ { "player_1.pushing.down.delay", "4" },
+ { "player_1.pushing.up", "RocksHeroes.pcx" },
+ { "player_1.pushing.up.xpos", "4" },
+ { "player_1.pushing.up.ypos", "0" },
+ { "player_1.pushing.up.frames", "4" },
+ { "player_1.pushing.up.delay", "4" },
+ { "player_1.pushing.left", "RocksHeroes.pcx" },
+ { "player_1.pushing.left.xpos", "4" },
+ { "player_1.pushing.left.ypos", "2" },
+ { "player_1.pushing.left.frames", "4" },
+ { "player_1.pushing.left.delay", "4" },
+ { "player_1.pushing.right", "RocksHeroes.pcx" },
+ { "player_1.pushing.right.xpos", "0" },
+ { "player_1.pushing.right.ypos", "2" },
+ { "player_1.pushing.right.frames", "4" },
+ { "player_1.pushing.right.delay", "4" },
+ { "player_1.snapping.down", "RocksHeroes.pcx" },
+ { "player_1.snapping.down.xpos", "0" },
+ { "player_1.snapping.down.ypos", "0" },
+ { "player_1.snapping.down.frames", "1" },
+ { "player_1.snapping.up", "RocksHeroes.pcx" },
+ { "player_1.snapping.up.xpos", "4" },
+ { "player_1.snapping.up.ypos", "0" },
+ { "player_1.snapping.up.frames", "1" },
+ { "player_1.snapping.left", "RocksHeroes.pcx" },
+ { "player_1.snapping.left.xpos", "0" },
+ { "player_1.snapping.left.ypos", "1" },
+ { "player_1.snapping.left.frames", "1" },
+ { "player_1.snapping.right", "RocksHeroes.pcx" },
+ { "player_1.snapping.right.xpos", "4" },
+ { "player_1.snapping.right.ypos", "1" },
+ { "player_1.snapping.right.frames", "1" },
+
+ { "player_2", "RocksHeroes.pcx" },
+ { "player_2.xpos", "0" },
+ { "player_2.ypos", "3" },
+ { "player_2.frames", "1" },
+ { "player_2.EDITOR", "RocksElements.pcx" },
+ { "player_2.EDITOR.xpos", "5" },
+ { "player_2.EDITOR.ypos", "7" },
+ { "player_2.down", "RocksHeroes.pcx" },
+ { "player_2.down.xpos", "0" },
+ { "player_2.down.ypos", "3" },
+ { "player_2.down.frames", "1" },
+ { "player_2.up", "RocksHeroes.pcx" },
+ { "player_2.up.xpos", "4" },
+ { "player_2.up.ypos", "3" },
+ { "player_2.up.frames", "1" },
+ { "player_2.left", "RocksHeroes.pcx" },
+ { "player_2.left.xpos", "0" },
+ { "player_2.left.ypos", "4" },
+ { "player_2.left.frames", "1" },
+ { "player_2.right", "RocksHeroes.pcx" },
+ { "player_2.right.xpos", "4" },
+ { "player_2.right.ypos", "4" },
+ { "player_2.right.frames", "1" },
+ { "player_2.moving.down", "RocksHeroes.pcx" },
+ { "player_2.moving.down.xpos", "0" },
+ { "player_2.moving.down.ypos", "3" },
+ { "player_2.moving.down.frames", "4" },
+ { "player_2.moving.down.start_frame", "1" },
+ { "player_2.moving.down.delay", "4" },
+ { "player_2.moving.up", "RocksHeroes.pcx" },
+ { "player_2.moving.up.xpos", "4" },
+ { "player_2.moving.up.ypos", "3" },
+ { "player_2.moving.up.frames", "4" },
+ { "player_2.moving.up.start_frame", "1" },
+ { "player_2.moving.up.delay", "4" },
+ { "player_2.moving.left", "RocksHeroes.pcx" },
+ { "player_2.moving.left.xpos", "0" },
+ { "player_2.moving.left.ypos", "4" },
+ { "player_2.moving.left.frames", "4" },
+ { "player_2.moving.left.start_frame", "1" },
+ { "player_2.moving.left.delay", "4" },
+ { "player_2.moving.right", "RocksHeroes.pcx" },
+ { "player_2.moving.right.xpos", "4" },
+ { "player_2.moving.right.ypos", "4" },
+ { "player_2.moving.right.frames", "4" },
+ { "player_2.moving.right.start_frame", "1" },
+ { "player_2.moving.right.delay", "4" },
+ { "player_2.digging.down", "RocksHeroes.pcx" },
+ { "player_2.digging.down.xpos", "0" },
+ { "player_2.digging.down.ypos", "3" },
+ { "player_2.digging.down.frames", "4" },
+ { "player_2.digging.down.start_frame", "1" },
+ { "player_2.digging.down.delay", "4" },
+ { "player_2.digging.up", "RocksHeroes.pcx" },
+ { "player_2.digging.up.xpos", "4" },
+ { "player_2.digging.up.ypos", "3" },
+ { "player_2.digging.up.frames", "4" },
+ { "player_2.digging.up.start_frame", "1" },
+ { "player_2.digging.up.delay", "4" },
+ { "player_2.digging.left", "RocksHeroes.pcx" },
+ { "player_2.digging.left.xpos", "0" },
+ { "player_2.digging.left.ypos", "4" },
+ { "player_2.digging.left.frames", "4" },
+ { "player_2.digging.left.start_frame", "1" },
+ { "player_2.digging.left.delay", "4" },
+ { "player_2.digging.right", "RocksHeroes.pcx" },
+ { "player_2.digging.right.xpos", "4" },
+ { "player_2.digging.right.ypos", "4" },
+ { "player_2.digging.right.frames", "4" },
+ { "player_2.digging.right.start_frame", "1" },
+ { "player_2.digging.right.delay", "4" },
+ { "player_2.collecting.down", "RocksHeroes.pcx" },
+ { "player_2.collecting.down.xpos", "0" },
+ { "player_2.collecting.down.ypos", "3" },
+ { "player_2.collecting.down.frames", "4" },
+ { "player_2.collecting.down.start_frame", "1" },
+ { "player_2.collecting.down.delay", "4" },
+ { "player_2.collecting.up", "RocksHeroes.pcx" },
+ { "player_2.collecting.up.xpos", "4" },
+ { "player_2.collecting.up.ypos", "3" },
+ { "player_2.collecting.up.frames", "4" },
+ { "player_2.collecting.up.start_frame", "1" },
+ { "player_2.collecting.up.delay", "4" },
+ { "player_2.collecting.left", "RocksHeroes.pcx" },
+ { "player_2.collecting.left.xpos", "0" },
+ { "player_2.collecting.left.ypos", "4" },
+ { "player_2.collecting.left.frames", "4" },
+ { "player_2.collecting.left.start_frame", "1" },
+ { "player_2.collecting.left.delay", "4" },
+ { "player_2.collecting.right", "RocksHeroes.pcx" },
+ { "player_2.collecting.right.xpos", "4" },
+ { "player_2.collecting.right.ypos", "4" },
+ { "player_2.collecting.right.frames", "4" },
+ { "player_2.collecting.right.start_frame", "1" },
+ { "player_2.collecting.right.delay", "4" },
+ { "player_2.pushing.down", "RocksHeroes.pcx" },
+ { "player_2.pushing.down.xpos", "0" },
+ { "player_2.pushing.down.ypos", "3" },
+ { "player_2.pushing.down.frames", "4" },
+ { "player_2.pushing.down.delay", "4" },
+ { "player_2.pushing.up", "RocksHeroes.pcx" },
+ { "player_2.pushing.up.xpos", "4" },
+ { "player_2.pushing.up.ypos", "3" },
+ { "player_2.pushing.up.frames", "4" },
+ { "player_2.pushing.up.delay", "4" },
+ { "player_2.pushing.left", "RocksHeroes.pcx" },
+ { "player_2.pushing.left.xpos", "4" },
+ { "player_2.pushing.left.ypos", "5" },
+ { "player_2.pushing.left.frames", "4" },
+ { "player_2.pushing.left.delay", "4" },
+ { "player_2.pushing.right", "RocksHeroes.pcx" },
+ { "player_2.pushing.right.xpos", "0" },
+ { "player_2.pushing.right.ypos", "5" },
+ { "player_2.pushing.right.frames", "4" },
+ { "player_2.pushing.right.delay", "4" },
+ { "player_2.snapping.down", "RocksHeroes.pcx" },
+ { "player_2.snapping.down.xpos", "0" },
+ { "player_2.snapping.down.ypos", "3" },
+ { "player_2.snapping.down.frames", "1" },
+ { "player_2.snapping.up", "RocksHeroes.pcx" },
+ { "player_2.snapping.up.xpos", "4" },
+ { "player_2.snapping.up.ypos", "3" },
+ { "player_2.snapping.up.frames", "1" },
+ { "player_2.snapping.left", "RocksHeroes.pcx" },
+ { "player_2.snapping.left.xpos", "0" },
+ { "player_2.snapping.left.ypos", "4" },
+ { "player_2.snapping.left.frames", "1" },
+ { "player_2.snapping.right", "RocksHeroes.pcx" },
+ { "player_2.snapping.right.xpos", "4" },
+ { "player_2.snapping.right.ypos", "4" },
+ { "player_2.snapping.right.frames", "1" },
+
+ { "player_3", "RocksHeroes.pcx" },
+ { "player_3.xpos", "0" },
+ { "player_3.ypos", "6" },
+ { "player_3.frames", "1" },
+ { "player_3.EDITOR", "RocksElements.pcx" },
+ { "player_3.EDITOR.xpos", "6" },
+ { "player_3.EDITOR.ypos", "7" },
+ { "player_3.down", "RocksHeroes.pcx" },
+ { "player_3.down.xpos", "0" },
+ { "player_3.down.ypos", "6" },
+ { "player_3.down.frames", "1" },
+ { "player_3.up", "RocksHeroes.pcx" },
+ { "player_3.up.xpos", "4" },
+ { "player_3.up.ypos", "6" },
+ { "player_3.up.frames", "1" },
+ { "player_3.left", "RocksHeroes.pcx" },
+ { "player_3.left.xpos", "0" },
+ { "player_3.left.ypos", "7" },
+ { "player_3.left.frames", "1" },
+ { "player_3.right", "RocksHeroes.pcx" },
+ { "player_3.right.xpos", "4" },
+ { "player_3.right.ypos", "7" },
+ { "player_3.right.frames", "1" },
+ { "player_3.moving.down", "RocksHeroes.pcx" },
+ { "player_3.moving.down.xpos", "0" },
+ { "player_3.moving.down.ypos", "6" },
+ { "player_3.moving.down.frames", "4" },
+ { "player_3.moving.down.start_frame", "1" },
+ { "player_3.moving.down.delay", "4" },
+ { "player_3.moving.up", "RocksHeroes.pcx" },
+ { "player_3.moving.up.xpos", "4" },
+ { "player_3.moving.up.ypos", "6" },
+ { "player_3.moving.up.frames", "4" },
+ { "player_3.moving.up.start_frame", "1" },
+ { "player_3.moving.up.delay", "4" },
+ { "player_3.moving.left", "RocksHeroes.pcx" },
+ { "player_3.moving.left.xpos", "0" },
+ { "player_3.moving.left.ypos", "7" },
+ { "player_3.moving.left.frames", "4" },
+ { "player_3.moving.left.start_frame", "1" },
+ { "player_3.moving.left.delay", "4" },
+ { "player_3.moving.right", "RocksHeroes.pcx" },
+ { "player_3.moving.right.xpos", "4" },
+ { "player_3.moving.right.ypos", "7" },
+ { "player_3.moving.right.frames", "4" },
+ { "player_3.moving.right.start_frame", "1" },
+ { "player_3.moving.right.delay", "4" },
+ { "player_3.digging.down", "RocksHeroes.pcx" },
+ { "player_3.digging.down.xpos", "0" },
+ { "player_3.digging.down.ypos", "6" },
+ { "player_3.digging.down.frames", "4" },
+ { "player_3.digging.down.start_frame", "1" },
+ { "player_3.digging.down.delay", "4" },
+ { "player_3.digging.up", "RocksHeroes.pcx" },
+ { "player_3.digging.up.xpos", "4" },
+ { "player_3.digging.up.ypos", "6" },
+ { "player_3.digging.up.frames", "4" },
+ { "player_3.digging.up.start_frame", "1" },
+ { "player_3.digging.up.delay", "4" },
+ { "player_3.digging.left", "RocksHeroes.pcx" },
+ { "player_3.digging.left.xpos", "0" },
+ { "player_3.digging.left.ypos", "7" },
+ { "player_3.digging.left.frames", "4" },
+ { "player_3.digging.left.start_frame", "1" },
+ { "player_3.digging.left.delay", "4" },
+ { "player_3.digging.right", "RocksHeroes.pcx" },
+ { "player_3.digging.right.xpos", "4" },
+ { "player_3.digging.right.ypos", "7" },
+ { "player_3.digging.right.frames", "4" },
+ { "player_3.digging.right.start_frame", "1" },
+ { "player_3.digging.right.delay", "4" },
+ { "player_3.collecting.down", "RocksHeroes.pcx" },
+ { "player_3.collecting.down.xpos", "0" },
+ { "player_3.collecting.down.ypos", "6" },
+ { "player_3.collecting.down.frames", "4" },
+ { "player_3.collecting.down.start_frame", "1" },
+ { "player_3.collecting.down.delay", "4" },
+ { "player_3.collecting.up", "RocksHeroes.pcx" },
+ { "player_3.collecting.up.xpos", "4" },
+ { "player_3.collecting.up.ypos", "6" },
+ { "player_3.collecting.up.frames", "4" },
+ { "player_3.collecting.up.start_frame", "1" },
+ { "player_3.collecting.up.delay", "4" },
+ { "player_3.collecting.left", "RocksHeroes.pcx" },
+ { "player_3.collecting.left.xpos", "0" },
+ { "player_3.collecting.left.ypos", "7" },
+ { "player_3.collecting.left.frames", "4" },
+ { "player_3.collecting.left.start_frame", "1" },
+ { "player_3.collecting.left.delay", "4" },
+ { "player_3.collecting.right", "RocksHeroes.pcx" },
+ { "player_3.collecting.right.xpos", "4" },
+ { "player_3.collecting.right.ypos", "7" },
+ { "player_3.collecting.right.frames", "4" },
+ { "player_3.collecting.right.start_frame", "1" },
+ { "player_3.collecting.right.delay", "4" },
+ { "player_3.pushing.down", "RocksHeroes.pcx" },
+ { "player_3.pushing.down.xpos", "0" },
+ { "player_3.pushing.down.ypos", "6" },
+ { "player_3.pushing.down.frames", "4" },
+ { "player_3.pushing.down.delay", "4" },
+ { "player_3.pushing.up", "RocksHeroes.pcx" },
+ { "player_3.pushing.up.xpos", "4" },
+ { "player_3.pushing.up.ypos", "6" },
+ { "player_3.pushing.up.frames", "4" },
+ { "player_3.pushing.up.delay", "4" },
+ { "player_3.pushing.left", "RocksHeroes.pcx" },
+ { "player_3.pushing.left.xpos", "4" },
+ { "player_3.pushing.left.ypos", "8" },
+ { "player_3.pushing.left.frames", "4" },
+ { "player_3.pushing.left.delay", "4" },
+ { "player_3.pushing.right", "RocksHeroes.pcx" },
+ { "player_3.pushing.right.xpos", "0" },
+ { "player_3.pushing.right.ypos", "8" },
+ { "player_3.pushing.right.frames", "4" },
+ { "player_3.pushing.right.delay", "4" },
+ { "player_3.snapping.down", "RocksHeroes.pcx" },
+ { "player_3.snapping.down.xpos", "0" },
+ { "player_3.snapping.down.ypos", "6" },
+ { "player_3.snapping.down.frames", "1" },
+ { "player_3.snapping.up", "RocksHeroes.pcx" },
+ { "player_3.snapping.up.xpos", "4" },
+ { "player_3.snapping.up.ypos", "6" },
+ { "player_3.snapping.up.frames", "1" },
+ { "player_3.snapping.left", "RocksHeroes.pcx" },
+ { "player_3.snapping.left.xpos", "0" },
+ { "player_3.snapping.left.ypos", "7" },
+ { "player_3.snapping.left.frames", "1" },
+ { "player_3.snapping.right", "RocksHeroes.pcx" },
+ { "player_3.snapping.right.xpos", "4" },
+ { "player_3.snapping.right.ypos", "7" },
+ { "player_3.snapping.right.frames", "1" },
+
+ { "player_4", "RocksHeroes.pcx" },
+ { "player_4.xpos", "0" },
+ { "player_4.ypos", "9" },
+ { "player_4.frames", "1" },
+ { "player_4.EDITOR", "RocksElements.pcx" },
+ { "player_4.EDITOR.xpos", "7" },
+ { "player_4.EDITOR.ypos", "7" },
+ { "player_4.down", "RocksHeroes.pcx" },
+ { "player_4.down.xpos", "0" },
+ { "player_4.down.ypos", "9" },
+ { "player_4.down.frames", "1" },
+ { "player_4.up", "RocksHeroes.pcx" },
+ { "player_4.up.xpos", "4" },
+ { "player_4.up.ypos", "9" },
+ { "player_4.up.frames", "1" },
+ { "player_4.left", "RocksHeroes.pcx" },
+ { "player_4.left.xpos", "0" },
+ { "player_4.left.ypos", "10" },
+ { "player_4.left.frames", "1" },
+ { "player_4.right", "RocksHeroes.pcx" },
+ { "player_4.right.xpos", "4" },
+ { "player_4.right.ypos", "10" },
+ { "player_4.right.frames", "1" },
+ { "player_4.moving.down", "RocksHeroes.pcx" },
+ { "player_4.moving.down.xpos", "0" },
+ { "player_4.moving.down.ypos", "9" },
+ { "player_4.moving.down.frames", "4" },
+ { "player_4.moving.down.start_frame", "1" },
+ { "player_4.moving.down.delay", "4" },
+ { "player_4.moving.up", "RocksHeroes.pcx" },
+ { "player_4.moving.up.xpos", "4" },
+ { "player_4.moving.up.ypos", "9" },
+ { "player_4.moving.up.frames", "4" },
+ { "player_4.moving.up.start_frame", "1" },
+ { "player_4.moving.up.delay", "4" },
+ { "player_4.moving.left", "RocksHeroes.pcx" },
+ { "player_4.moving.left.xpos", "0" },
+ { "player_4.moving.left.ypos", "10" },
+ { "player_4.moving.left.frames", "4" },
+ { "player_4.moving.left.start_frame", "1" },
+ { "player_4.moving.left.delay", "4" },
+ { "player_4.moving.right", "RocksHeroes.pcx" },
+ { "player_4.moving.right.xpos", "4" },
+ { "player_4.moving.right.ypos", "10" },
+ { "player_4.moving.right.frames", "4" },
+ { "player_4.moving.right.start_frame", "1" },
+ { "player_4.moving.right.delay", "4" },
+ { "player_4.digging.down", "RocksHeroes.pcx" },
+ { "player_4.digging.down.xpos", "0" },
+ { "player_4.digging.down.ypos", "9" },
+ { "player_4.digging.down.frames", "4" },
+ { "player_4.digging.down.start_frame", "1" },
+ { "player_4.digging.down.delay", "4" },
+ { "player_4.digging.up", "RocksHeroes.pcx" },
+ { "player_4.digging.up.xpos", "4" },
+ { "player_4.digging.up.ypos", "9" },
+ { "player_4.digging.up.frames", "4" },
+ { "player_4.digging.up.start_frame", "1" },
+ { "player_4.digging.up.delay", "4" },
+ { "player_4.digging.left", "RocksHeroes.pcx" },
+ { "player_4.digging.left.xpos", "0" },
+ { "player_4.digging.left.ypos", "10" },
+ { "player_4.digging.left.frames", "4" },
+ { "player_4.digging.left.start_frame", "1" },
+ { "player_4.digging.left.delay", "4" },
+ { "player_4.digging.right", "RocksHeroes.pcx" },
+ { "player_4.digging.right.xpos", "4" },
+ { "player_4.digging.right.ypos", "10" },
+ { "player_4.digging.right.frames", "4" },
+ { "player_4.digging.right.start_frame", "1" },
+ { "player_4.digging.right.delay", "4" },
+ { "player_4.collecting.down", "RocksHeroes.pcx" },
+ { "player_4.collecting.down.xpos", "0" },
+ { "player_4.collecting.down.ypos", "9" },
+ { "player_4.collecting.down.frames", "4" },
+ { "player_4.collecting.down.start_frame", "1" },
+ { "player_4.collecting.down.delay", "4" },
+ { "player_4.collecting.up", "RocksHeroes.pcx" },
+ { "player_4.collecting.up.xpos", "4" },
+ { "player_4.collecting.up.ypos", "9" },
+ { "player_4.collecting.up.frames", "4" },
+ { "player_4.collecting.up.start_frame", "1" },
+ { "player_4.collecting.up.delay", "4" },
+ { "player_4.collecting.left", "RocksHeroes.pcx" },
+ { "player_4.collecting.left.xpos", "0" },
+ { "player_4.collecting.left.ypos", "10" },
+ { "player_4.collecting.left.frames", "4" },
+ { "player_4.collecting.left.start_frame", "1" },
+ { "player_4.collecting.left.delay", "4" },
+ { "player_4.collecting.right", "RocksHeroes.pcx" },
+ { "player_4.collecting.right.xpos", "4" },
+ { "player_4.collecting.right.ypos", "10" },
+ { "player_4.collecting.right.frames", "4" },
+ { "player_4.collecting.right.start_frame", "1" },
+ { "player_4.collecting.right.delay", "4" },
+ { "player_4.pushing.down", "RocksHeroes.pcx" },
+ { "player_4.pushing.down.xpos", "0" },
+ { "player_4.pushing.down.ypos", "9" },
+ { "player_4.pushing.down.frames", "4" },
+ { "player_4.pushing.down.delay", "4" },
+ { "player_4.pushing.up", "RocksHeroes.pcx" },
+ { "player_4.pushing.up.xpos", "4" },
+ { "player_4.pushing.up.ypos", "9" },
+ { "player_4.pushing.up.frames", "4" },
+ { "player_4.pushing.up.delay", "4" },
+ { "player_4.pushing.left", "RocksHeroes.pcx" },
+ { "player_4.pushing.left.xpos", "4" },
+ { "player_4.pushing.left.ypos", "11" },
+ { "player_4.pushing.left.frames", "4" },
+ { "player_4.pushing.left.delay", "4" },
+ { "player_4.pushing.right", "RocksHeroes.pcx" },
+ { "player_4.pushing.right.xpos", "0" },
+ { "player_4.pushing.right.ypos", "11" },
+ { "player_4.pushing.right.frames", "4" },
+ { "player_4.pushing.right.delay", "4" },
+ { "player_4.snapping.down", "RocksHeroes.pcx" },
+ { "player_4.snapping.down.xpos", "0" },
+ { "player_4.snapping.down.ypos", "9" },
+ { "player_4.snapping.down.frames", "1" },
+ { "player_4.snapping.up", "RocksHeroes.pcx" },
+ { "player_4.snapping.up.xpos", "4" },
+ { "player_4.snapping.up.ypos", "9" },
+ { "player_4.snapping.up.frames", "1" },
+ { "player_4.snapping.left", "RocksHeroes.pcx" },
+ { "player_4.snapping.left.xpos", "0" },
+ { "player_4.snapping.left.ypos", "10" },
+ { "player_4.snapping.left.frames", "1" },
+ { "player_4.snapping.right", "RocksHeroes.pcx" },
+ { "player_4.snapping.right.xpos", "4" },
+ { "player_4.snapping.right.ypos", "10" },
+ { "player_4.snapping.right.frames", "1" },
+
+ { "[default].exploding", "RocksElements.pcx" },
+ { "[default].exploding.xpos", "0" },
+ { "[default].exploding.ypos", "4" },
+ { "[default].exploding.frames", "8" },
+ { "[default].exploding.delay", "2" },
+ { "[default].exploding.anim_mode", "linear" },
+
+ { "twinkle_blue", "RocksHeroes.pcx" },
+ { "twinkle_blue.xpos", "9" },
+ { "twinkle_blue.ypos", "11" },
+ { "twinkle_blue.frames", "3" },
+ { "twinkle_blue.delay", "2" },
+ { "twinkle_blue.anim_mode", "pingpong" },
+ { "twinkle_blue.global_sync", "false" },
+ { "twinkle_white", "RocksHeroes.pcx" },
+ { "twinkle_white.xpos", "13" },
+ { "twinkle_white.ypos", "11" },
+ { "twinkle_white.frames", "3" },
+ { "twinkle_white.delay", "2" },
+ { "twinkle_white.anim_mode", "pingpong" },
+ { "twinkle_white.global_sync", "false" },
+
+ { "steelwall_topleft", "RocksElements.pcx" },
+ { "steelwall_topleft.xpos", "4" },
+ { "steelwall_topleft.ypos", "0" },
+ { "steelwall_topleft.frames", "1" },
+ { "steelwall_topright", "RocksElements.pcx" },
+ { "steelwall_topright.xpos", "4" },
+ { "steelwall_topright.ypos", "0" },
+ { "steelwall_topright.frames", "1" },
+ { "steelwall_bottomleft", "RocksElements.pcx" },
+ { "steelwall_bottomleft.xpos", "4" },
+ { "steelwall_bottomleft.ypos", "0" },
+ { "steelwall_bottomleft.frames", "1" },
+ { "steelwall_bottomright", "RocksElements.pcx" },
+ { "steelwall_bottomright.xpos", "4" },
+ { "steelwall_bottomright.ypos", "0" },
+ { "steelwall_bottomright.frames", "1" },
+ { "steelwall_horizontal", "RocksElements.pcx" },
+ { "steelwall_horizontal.xpos", "4" },
+ { "steelwall_horizontal.ypos", "0" },
+ { "steelwall_horizontal.frames", "1" },
+ { "steelwall_vertical", "RocksElements.pcx" },
+ { "steelwall_vertical.xpos", "4" },
+ { "steelwall_vertical.ypos", "0" },
+ { "steelwall_vertical.frames", "1" },
+
+ { "steelwall_topleft.EDITOR", "RocksElements.pcx" },
+ { "steelwall_topleft.EDITOR.xpos", "0" },
+ { "steelwall_topleft.EDITOR.ypos", "13" },
+ { "steelwall_topright.EDITOR", "RocksElements.pcx" },
+ { "steelwall_topright.EDITOR.xpos", "1" },
+ { "steelwall_topright.EDITOR.ypos", "13" },
+ { "steelwall_bottomleft.EDITOR", "RocksElements.pcx" },
+ { "steelwall_bottomleft.EDITOR.xpos", "2" },
+ { "steelwall_bottomleft.EDITOR.ypos", "13" },
+ { "steelwall_bottomright.EDITOR", "RocksElements.pcx" },
+ { "steelwall_bottomright.EDITOR.xpos", "3" },
+ { "steelwall_bottomright.EDITOR.ypos", "13" },
+ { "steelwall_horizontal.EDITOR", "RocksElements.pcx" },
+ { "steelwall_horizontal.EDITOR.xpos", "4" },
+ { "steelwall_horizontal.EDITOR.ypos", "13" },
+ { "steelwall_vertical.EDITOR", "RocksElements.pcx" },
+ { "steelwall_vertical.EDITOR.xpos", "5" },
+ { "steelwall_vertical.EDITOR.ypos", "13" },
+
+ { "invisible_steelwall_topleft", "RocksSP.pcx" },
+ { "invisible_steelwall_topleft.xpos", "0" },
+ { "invisible_steelwall_topleft.ypos", "0" },
+ { "invisible_steelwall_topleft.frames", "1" },
+ { "invisible_steelwall_topright", "RocksSP.pcx" },
+ { "invisible_steelwall_topright.xpos", "0" },
+ { "invisible_steelwall_topright.ypos", "0" },
+ { "invisible_steelwall_topright.frames", "1" },
+ { "invisible_steelwall_bottomleft", "RocksSP.pcx" },
+ { "invisible_steelwall_bottomleft.xpos", "0" },
+ { "invisible_steelwall_bottomleft.ypos", "0" },
+ { "invisible_steelwall_bottomleft.frames", "1" },
+ { "invisible_steelwall_bottomright", "RocksSP.pcx" },
+ { "invisible_steelwall_bottomright.xpos", "0" },
+ { "invisible_steelwall_bottomright.ypos", "0" },
+ { "invisible_steelwall_bottomright.frames", "1" },
+ { "invisible_steelwall_horizontal", "RocksSP.pcx" },
+ { "invisible_steelwall_horizontal.xpos", "0" },
+ { "invisible_steelwall_horizontal.ypos", "0" },
+ { "invisible_steelwall_horizontal.frames", "1" },
+ { "invisible_steelwall_vertical", "RocksSP.pcx" },
+ { "invisible_steelwall_vertical.xpos", "0" },
+ { "invisible_steelwall_vertical.ypos", "0" },
+ { "invisible_steelwall_vertical.frames", "1" },
+
+ { "invisible_steelwall_topleft.EDITOR", "RocksElements.pcx" },
+ { "invisible_steelwall_topleft.EDITOR.xpos", "6" },
+ { "invisible_steelwall_topleft.EDITOR.ypos", "13" },
+ { "invisible_steelwall_topright.EDITOR", "RocksElements.pcx" },
+ { "invisible_steelwall_topright.EDITOR.xpos", "7" },
+ { "invisible_steelwall_topright.EDITOR.ypos", "13" },
+ { "invisible_steelwall_bottomleft.EDITOR", "RocksElements.pcx" },
+ { "invisible_steelwall_bottomleft.EDITOR.xpos","8" },
+ { "invisible_steelwall_bottomleft.EDITOR.ypos","13" },
+ { "invisible_steelwall_bottomright.EDITOR", "RocksElements.pcx" },
+ { "invisible_steelwall_bottomright.EDITOR.xpos","9" },
+ { "invisible_steelwall_bottomright.EDITOR.ypos","13" },
+ { "invisible_steelwall_horizontal.EDITOR", "RocksElements.pcx" },
+ { "invisible_steelwall_horizontal.EDITOR.xpos","10" },
+ { "invisible_steelwall_horizontal.EDITOR.ypos","13" },
+ { "invisible_steelwall_vertical.EDITOR", "RocksElements.pcx" },
+ { "invisible_steelwall_vertical.EDITOR.xpos", "11" },
+ { "invisible_steelwall_vertical.EDITOR.ypos", "13" },
+
+ { "arrow_left", "RocksDC.pcx" },
+ { "arrow_left.xpos", "8" },
+ { "arrow_left.ypos", "8" },
+ { "arrow_left.frames", "1" },
+ { "arrow_right", "RocksDC.pcx" },
+ { "arrow_right.xpos", "9" },
+ { "arrow_right.ypos", "8" },
+ { "arrow_right.frames", "1" },
+ { "arrow_up", "RocksDC.pcx" },
+ { "arrow_up.xpos", "10" },
+ { "arrow_up.ypos", "8" },
+ { "arrow_up.frames", "1" },
+ { "arrow_down", "RocksDC.pcx" },
+ { "arrow_down.xpos", "11" },
+ { "arrow_down.ypos", "8" },
+ { "arrow_down.frames", "1" },
+
+#include "conf_chr.c" /* include auto-generated data structure definitions */
+#include "conf_cus.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! */
+
+ { "toon_1", "RocksToons.pcx" },
+ { "toon_1.x", "2" },
+ { "toon_1.y", "72" },
+ { "toon_1.width", "40" },
+ { "toon_1.height", "48" },
+ { "toon_1.frames", "8" },
+ { "toon_1.delay", "1" },
+ { "toon_1.step_offset", "4" },
+ { "toon_1.step_delay", "5" },
+ { "toon_1.direction", "right" },
+ { "toon_1.position", "bottom" },
+
+ { "toon_2", "RocksToons.pcx" },
+ { "toon_2.x", "2" },
+ { "toon_2.y", "186" },
+ { "toon_2.width", "40" },
+ { "toon_2.height", "48" },
+ { "toon_2.frames", "8" },
+ { "toon_2.delay", "1" },
+ { "toon_2.step_offset", "4" },
+ { "toon_2.step_delay", "5" },
+ { "toon_2.direction", "left" },
+ { "toon_2.position", "bottom" },
+
+ { "toon_3", "RocksToons.pcx" },
+ { "toon_3.x", "2" },
+ { "toon_3.y", "125" },
+ { "toon_3.width", "48" },
+ { "toon_3.height", "56" },
+ { "toon_3.frames", "8" },
+ { "toon_3.delay", "1" },
+ { "toon_3.step_offset", "4" },
+ { "toon_3.step_delay", "5" },
+ { "toon_3.direction", "right" },
+ { "toon_3.position", "bottom" },
+
+ { "toon_4", "RocksToons.pcx" },
+ { "toon_4.x", "327" },
+ { "toon_4.y", "10" },
+ { "toon_4.width", "80" },
+ { "toon_4.height", "110" },
+ { "toon_4.frames", "1" },
+ { "toon_4.delay", "1" },
+ { "toon_4.step_offset", "1" },
+ { "toon_4.step_delay", "1" },
+ { "toon_4.direction", "up" },
+ { "toon_4.position", "any" },
+
+ { "toon_5", "RocksToons.pcx" },
+ { "toon_5.x", "2" },
+ { "toon_5.y", "2" },
+ { "toon_5.width", "32" },
+ { "toon_5.height", "30" },
+ { "toon_5.frames", "8" },
+ { "toon_5.delay", "2" },
+ { "toon_5.anim_mode", "pingpong2" },
+ { "toon_5.step_offset", "2" },
+ { "toon_5.step_delay", "1" },
+ { "toon_5.direction", "right" },
+ { "toon_5.position", "upper" },
+
+ { "toon_6", "RocksToons.pcx" },
+ { "toon_6.x", "2" },
+ { "toon_6.y", "37" },
+ { "toon_6.width", "32" },
+ { "toon_6.height", "30" },
+ { "toon_6.frames", "8" },
+ { "toon_6.delay", "2" },
+ { "toon_6.anim_mode", "pingpong2" },
+ { "toon_6.step_offset", "2" },
+ { "toon_6.step_delay", "1" },
+ { "toon_6.direction", "left" },
+ { "toon_6.position", "upper" },
+
+ { "toon_7", "RocksHeroes.pcx" },
+ { "toon_7.xpos", "0" },
+ { "toon_7.ypos", "1" },
+ { "toon_7.frames", "4" },
+ { "toon_7.delay", "4" },
+ { "toon_7.direction", "left" },
+ { "toon_7.position", "bottom" },
+
+ { "toon_8", "RocksHeroes.pcx" },
+ { "toon_8.xpos", "4" },
+ { "toon_8.ypos", "1" },
+ { "toon_8.frames", "4" },
+ { "toon_8.delay", "4" },
+ { "toon_8.direction", "right" },
+ { "toon_8.position", "bottom" },
+
+ { "toon_9", "RocksHeroes.pcx" },
+ { "toon_9.xpos", "8" },
+ { "toon_9.ypos", "7" },
+ { "toon_9.frames", "4" },
+ { "toon_9.delay", "2" },
+ { "toon_9.direction", "left" },
+ { "toon_9.position", "bottom" },
+
+ { "toon_10", "RocksHeroes.pcx" },
+ { "toon_10.xpos", "12" },
+ { "toon_10.ypos", "7" },
+ { "toon_10.frames", "4" },
+ { "toon_10.delay", "2" },
+ { "toon_10.direction", "right" },
+ { "toon_10.position", "bottom" },
+
+ { "toon_11", "RocksHeroes.pcx" },
+ { "toon_11.xpos", "8" },
+ { "toon_11.ypos", "5" },
+ { "toon_11.frames", "4" },
+ { "toon_11.delay", "2" },
+ { "toon_11.direction", "left" },
+ { "toon_11.position", "bottom" },
+
+ { "toon_12", "RocksHeroes.pcx" },
+ { "toon_12.xpos", "12" },
+ { "toon_12.ypos", "5" },
+ { "toon_12.frames", "4" },
+ { "toon_12.delay", "2" },
+ { "toon_12.direction", "right" },
+ { "toon_12.position", "bottom" },
+
+ { "toon_13", "RocksHeroes.pcx" },
+ { "toon_13.xpos", "8" },
+ { "toon_13.ypos", "1" },
+ { "toon_13.frames", "4" },
+ { "toon_13.delay", "2" },
+ { "toon_13.direction", "left" },
+ { "toon_13.position", "bottom" },
+
+ { "toon_14", "RocksHeroes.pcx" },
+ { "toon_14.xpos", "12" },
+ { "toon_14.ypos", "1" },
+ { "toon_14.frames", "4" },
+ { "toon_14.delay", "2" },
+ { "toon_14.direction", "right" },
+ { "toon_14.position", "bottom" },
+
+ { "toon_15", "RocksHeroes.pcx" },
+ { "toon_15.xpos", "8" },
+ { "toon_15.ypos", "3" },
+ { "toon_15.frames", "4" },
+ { "toon_15.delay", "2" },
+ { "toon_15.direction", "left" },
+ { "toon_15.position", "bottom" },
+
+ { "toon_16", "RocksHeroes.pcx" },
+ { "toon_16.xpos", "12" },
+ { "toon_16.ypos", "3" },
+ { "toon_16.frames", "4" },
+ { "toon_16.delay", "2" },
+ { "toon_16.direction", "right" },
+ { "toon_16.position", "bottom" },
+
+ { "toon_17", "RocksHeroes.pcx" },
+ { "toon_17.xpos", "8" },
+ { "toon_17.ypos", "9" },
+ { "toon_17.frames", "8" },
+ { "toon_17.delay", "2" },
+ { "toon_17.direction", "left" },
+ { "toon_17.position", "any" },
+
+ { "toon_18", "RocksHeroes.pcx" },
+ { "toon_18.xpos", "8" },
+ { "toon_18.ypos", "9" },
+ { "toon_18.frames", "8" },
+ { "toon_18.delay", "2" },
+ { "toon_18.direction", "right" },
+ { "toon_18.position", "any" },
+
+ { "toon_19", "RocksElements.pcx" },
+ { "toon_19.xpos", "8" },
+ { "toon_19.ypos", "0" },
+ { "toon_19.frames", "2" },
+ { "toon_19.delay", "4" },
+ { "toon_19.direction", "down" },
+ { "toon_19.position", "any" },
+
+ { "toon_20", "RocksElements.pcx" },
+ { "toon_20.xpos", "10" },
+ { "toon_20.ypos", "0" },
+ { "toon_20.frames", "2" },
+ { "toon_20.delay", "4" },
+ { "toon_20.direction", "down" },
+ { "toon_20.position", "any" },
+
+ { "menu.calibrate_red", "RocksElements.pcx" },
+ { "menu.calibrate_red.xpos", "12" },
+ { "menu.calibrate_red.ypos", "8" },
+ { "menu.calibrate_red.frames", "1" },
+ { "menu.calibrate_blue", "RocksElements.pcx" },
+ { "menu.calibrate_blue.xpos", "13" },
+ { "menu.calibrate_blue.ypos", "8" },
+ { "menu.calibrate_blue.frames", "1" },
+ { "menu.calibrate_yellow", "RocksElements.pcx" },
+ { "menu.calibrate_yellow.xpos", "14" },
+ { "menu.calibrate_yellow.ypos", "8" },
+ { "menu.calibrate_yellow.frames", "1" },
+
+ { "menu.button", "RocksElements.pcx" },
+ { "menu.button.xpos", "13" },
+ { "menu.button.ypos", "8" },
+ { "menu.button.frames", "1" },
+ { "menu.button.active", "RocksElements.pcx" },
+ { "menu.button.active.xpos", "12" },
+ { "menu.button.active.ypos", "8" },
+ { "menu.button.active.frames", "1" },
+
+ { "menu.button_left", "RocksDC.pcx" },
+ { "menu.button_left.xpos", "8" },
+ { "menu.button_left.ypos", "8" },
+ { "menu.button_left.frames", "1" },
+ { "menu.button_right", "RocksDC.pcx" },
+ { "menu.button_right.xpos", "9" },
+ { "menu.button_right.ypos", "8" },
+ { "menu.button_right.frames", "1" },
+ { "menu.button_up", "RocksDC.pcx" },
+ { "menu.button_up.xpos", "10" },
+ { "menu.button_up.ypos", "8" },
+ { "menu.button_up.frames", "1" },
+ { "menu.button_down", "RocksDC.pcx" },
+ { "menu.button_down.xpos", "11" },
+ { "menu.button_down.ypos", "8" },
+ { "menu.button_down.frames", "1" },
+ { "menu.button_left.active", "RocksDC.pcx" },
+ { "menu.button_left.active.xpos", "8" },
+ { "menu.button_left.active.ypos", "9" },
+ { "menu.button_left.active.frames", "1" },
+ { "menu.button_right.active", "RocksDC.pcx" },
+ { "menu.button_right.active.xpos", "9" },
+ { "menu.button_right.active.ypos", "9" },
+ { "menu.button_right.active.frames", "1" },
+ { "menu.button_up.active", "RocksDC.pcx" },
+ { "menu.button_up.active.xpos", "10" },
+ { "menu.button_up.active.ypos", "9" },
+ { "menu.button_up.active.frames", "1" },
+ { "menu.button_down.active", "RocksDC.pcx" },
+ { "menu.button_down.active.xpos", "11" },
+ { "menu.button_down.active.ypos", "9" },
+ { "menu.button_down.active.frames", "1" },
+
+ { "menu.scrollbar", "RocksDC.pcx" },
+ { "menu.scrollbar.xpos", "8" },
+ { "menu.scrollbar.ypos", "10" },
+ { "menu.scrollbar.frames", "1" },
+ { "menu.scrollbar.active", "RocksDC.pcx" },
+ { "menu.scrollbar.active.xpos", "9" },
+ { "menu.scrollbar.active.ypos", "10" },
+ { "menu.scrollbar.active.frames", "1" },
+
+ { "font.initial_1", "RocksFontSmall.pcx" },
+ { "font.initial_1.x", "0" },
+ { "font.initial_1.y", "0" },
+ { "font.initial_1.width", "14" },
+ { "font.initial_1.height", "14" },
+ { "font.initial_2", "RocksFontSmall.pcx" },
+ { "font.initial_2.x", "0" },
+ { "font.initial_2.y", "70" },
+ { "font.initial_2.width", "14" },
+ { "font.initial_2.height", "14" },
+ { "font.initial_3", "RocksFontSmall.pcx" },
+ { "font.initial_3.x", "0" },
+ { "font.initial_3.y", "140" },
+ { "font.initial_3.width", "14" },
+ { "font.initial_3.height", "14" },
+ { "font.initial_4", "RocksFontSmall.pcx" },
+ { "font.initial_4.x", "0" },
+ { "font.initial_4.y", "210" },
+ { "font.initial_4.width", "14" },
+ { "font.initial_4.height", "14" },
+
+ { "font.title_1", "RocksFontBig.pcx" },
+ { "font.title_1.x", "0" },
+ { "font.title_1.y", "480" },
+ { "font.title_1.width", "32" },
+ { "font.title_1.height", "32" },
+ { "font.title_1.LEVELS", "RocksFontBig.pcx" },
+ { "font.title_1.LEVELS.x", "0" },
+ { "font.title_1.LEVELS.y", "320" },
+ { "font.title_1.LEVELS.width", "32" },
+ { "font.title_1.LEVELS.height", "32" },
+ { "font.title_2", "RocksFontSmall.pcx" },
+ { "font.title_2.x", "0" },
+ { "font.title_2.y", "0" },
+ { "font.title_2.width", "14" },
+ { "font.title_2.height", "14" },
+
+ { "font.menu_1", "RocksFontBig.pcx" },
+ { "font.menu_1.x", "0" },
+ { "font.menu_1.y", "320" },
+ { "font.menu_1.width", "32" },
+ { "font.menu_1.height", "32" },
+ { "font.menu_2", "RocksFontMedium.pcx" },
+ { "font.menu_2.x", "0" },
+ { "font.menu_2.y", "320" },
+ { "font.menu_2.width", "16" },
+ { "font.menu_2.height", "32" },
+
+ { "font.text_1", "RocksFontSmall.pcx" },
+ { "font.text_1.x", "0" },
+ { "font.text_1.y", "140" },
+ { "font.text_1.width", "14" },
+ { "font.text_1.height", "14" },
+ { "font.text_1.LEVELS", "RocksFontMedium.pcx" },
+ { "font.text_1.LEVELS.x", "0" },
+ { "font.text_1.LEVELS.y", "0" },
+ { "font.text_1.LEVELS.width", "16" },
+ { "font.text_1.LEVELS.height", "32" },
+ { "font.text_1.PREVIEW", "RocksFontEM.pcx" },
+ { "font.text_1.PREVIEW.x", "0" },
+ { "font.text_1.PREVIEW.y", "160" },
+ { "font.text_1.PREVIEW.width", "16" },
+ { "font.text_1.PREVIEW.height", "16" },
+ { "font.text_1.SCORES", "RocksFontMedium.pcx" },
+ { "font.text_1.SCORES.x", "0" },
+ { "font.text_1.SCORES.y", "480" },
+ { "font.text_1.SCORES.width", "16" },
+ { "font.text_1.SCORES.height", "32" },
+ { "font.text_1.active.SCORES", "RocksFontMedium.pcx" },
+ { "font.text_1.active.SCORES.x", "0" },
+ { "font.text_1.active.SCORES.y", "0" },
+ { "font.text_1.active.SCORES.width", "16" },
+ { "font.text_1.active.SCORES.height", "32" },
+ { "font.text_2", "RocksFontSmall.pcx" },
+ { "font.text_2.x", "0" },
+ { "font.text_2.y", "210" },
+ { "font.text_2.width", "14" },
+ { "font.text_2.height", "14" },
+ { "font.text_2.LEVELS", "RocksFontMedium.pcx" },
+ { "font.text_2.LEVELS.x", "0" },
+ { "font.text_2.LEVELS.y", "160" },
+ { "font.text_2.LEVELS.width", "16" },
+ { "font.text_2.LEVELS.height", "32" },
+ { "font.text_2.PREVIEW", "RocksFontEM.pcx" },
+ { "font.text_2.PREVIEW.x", "0" },
+ { "font.text_2.PREVIEW.y", "160" },
+ { "font.text_2.PREVIEW.width", "16" },
+ { "font.text_2.PREVIEW.height", "16" },
+ { "font.text_2.SCORES", "RocksFontBig.pcx" },
+ { "font.text_2.SCORES.x", "0" },
+ { "font.text_2.SCORES.y", "320" },
+ { "font.text_2.SCORES.width", "32" },
+ { "font.text_2.SCORES.height", "32" },
+ { "font.text_2.active.SCORES", "RocksFontBig.pcx" },
+ { "font.text_2.active.SCORES.x", "0" },
+ { "font.text_2.active.SCORES.y", "0" },
+ { "font.text_2.active.SCORES.width", "32" },
+ { "font.text_2.active.SCORES.height", "32" },
+ { "font.text_3", "RocksFontSmall.pcx" },
+ { "font.text_3.x", "0" },
+ { "font.text_3.y", "0" },
+ { "font.text_3.width", "14" },
+ { "font.text_3.height", "14" },
+ { "font.text_3.LEVELS", "RocksFontMedium.pcx" },
+ { "font.text_3.LEVELS.x", "0" },
+ { "font.text_3.LEVELS.y", "320" },
+ { "font.text_3.LEVELS.width", "16" },
+ { "font.text_3.LEVELS.height", "32" },
+ { "font.text_3.PREVIEW", "RocksFontEM.pcx" },
+ { "font.text_3.PREVIEW.x", "0" },
+ { "font.text_3.PREVIEW.y", "160" },
+ { "font.text_3.PREVIEW.width", "16" },
+ { "font.text_3.PREVIEW.height", "16" },
+ { "font.text_3.SCORES", "RocksFontMedium.pcx" },
+ { "font.text_3.SCORES.x", "0" },
+ { "font.text_3.SCORES.y", "480" },
+ { "font.text_3.SCORES.width", "16" },
+ { "font.text_3.SCORES.height", "32" },
+ { "font.text_3.active.SCORES", "RocksFontMedium.pcx" },
+ { "font.text_3.active.SCORES.x", "0" },
+ { "font.text_3.active.SCORES.y", "0" },
+ { "font.text_3.active.SCORES.width", "16" },
+ { "font.text_3.active.SCORES.height", "32" },
+ { "font.text_4", "RocksFontSmall.pcx" },
+ { "font.text_4.x", "0" },
+ { "font.text_4.y", "70" },
+ { "font.text_4.width", "14" },
+ { "font.text_4.height", "14" },
+ { "font.text_4.LEVELS", "RocksFontMedium.pcx" },
+ { "font.text_4.LEVELS.x", "0" },
+ { "font.text_4.LEVELS.y", "480" },
+ { "font.text_4.LEVELS.width", "16" },
+ { "font.text_4.LEVELS.height", "32" },
+ { "font.text_4.SCORES", "RocksFontMedium.pcx" },
+ { "font.text_4.SCORES.x", "0" },
+ { "font.text_4.SCORES.y", "480" },
+ { "font.text_4.SCORES.width", "16" },
+ { "font.text_4.SCORES.height", "32" },
+ { "font.text_4.active.SCORES", "RocksFontMedium.pcx" },
+ { "font.text_4.active.SCORES.x", "0" },
+ { "font.text_4.active.SCORES.y", "0" },
+ { "font.text_4.active.SCORES.width", "16" },
+ { "font.text_4.active.SCORES.height", "32" },
+
+ { "font.input_1", "RocksFontSmall.pcx" },
+ { "font.input_1.x", "0" },
+ { "font.input_1.y", "210" },
+ { "font.input_1.width", "14" },
+ { "font.input_1.height", "14" },
+ { "font.input_1.MAIN", "RocksFontBig.pcx" },
+ { "font.input_1.MAIN.x", "0" },
+ { "font.input_1.MAIN.y", "0" },
+ { "font.input_1.MAIN.width", "32" },
+ { "font.input_1.MAIN.height", "32" },
+ { "font.input_1.active", "RocksFontSmall.pcx" },
+ { "font.input_1.active.x", "0" },
+ { "font.input_1.active.y", "210" },
+ { "font.input_1.active.width", "14" },
+ { "font.input_1.active.height", "14" },
+ { "font.input_1.active.MAIN", "RocksFontBig.pcx" },
+ { "font.input_1.active.MAIN.x", "0" },
+ { "font.input_1.active.MAIN.y", "480" },
+ { "font.input_1.active.MAIN.width", "32" },
+ { "font.input_1.active.MAIN.height", "32" },
+ { "font.input_1.active.SETUP", "RocksFontBig.pcx" },
+ { "font.input_1.active.SETUP.x", "0" },
+ { "font.input_1.active.SETUP.y", "0" },
+ { "font.input_1.active.SETUP.width", "32" },
+ { "font.input_1.active.SETUP.height", "32" },
+ { "font.input_2", "RocksFontSmall.pcx" },
+ { "font.input_2.x", "0" },
+ { "font.input_2.y", "210" },
+ { "font.input_2.width", "14" },
+ { "font.input_2.height", "14" },
+ { "font.input_2.active", "RocksFontSmall.pcx" },
+ { "font.input_2.active.x", "0" },
+ { "font.input_2.active.y", "210" },
+ { "font.input_2.active.width", "14" },
+ { "font.input_2.active.height", "14" },
+
+ { "font.option_off", "RocksFontBig.pcx" },
+ { "font.option_off.x", "0" },
+ { "font.option_off.y", "160" },
+ { "font.option_off.width", "32" },
+ { "font.option_off.height", "32" },
+ { "font.option_on", "RocksFontBig.pcx" },
+ { "font.option_on.x", "0" },
+ { "font.option_on.y", "480" },
+ { "font.option_on.width", "32" },
+ { "font.option_on.height", "32" },
+
+ { "font.value_1", "RocksFontBig.pcx" },
+ { "font.value_1.x", "0" },
+ { "font.value_1.y", "480" },
+ { "font.value_1.width", "32" },
+ { "font.value_1.height", "32" },
+ { "font.value_2", "RocksFontMedium.pcx" },
+ { "font.value_2.x", "0" },
+ { "font.value_2.y", "480" },
+ { "font.value_2.width", "16" },
+ { "font.value_2.height", "32" },
+ { "font.value_old", "RocksFontBig.pcx" },
+ { "font.value_old.x", "0" },
+ { "font.value_old.y", "160" },
+ { "font.value_old.width", "32" },
+ { "font.value_old.height", "32" },
+
+ { "font.level_number", "RocksFontSmall.pcx" },
+ { "font.level_number.x", "0" },
+ { "font.level_number.y", "350" },
+ { "font.level_number.width", "10" },
+ { "font.level_number.height", "14" },
+
+ { "font.tape_recorder", "RocksFontSmall.pcx" },
+ { "font.tape_recorder.x", "0" },
+ { "font.tape_recorder.y", "280" },
+ { "font.tape_recorder.width", "11" },
+ { "font.tape_recorder.height", "14" },
+
+ { "font.game_info", "RocksFontEM.pcx" },
+ { "font.game_info.xpos", "0" },
+ { "font.game_info.ypos", "0" },
+ { "font.game_info.delay", "10" },
+
+ { "global.border", "RocksScreen.pcx" },
+ { "global.door", "RocksDoor.pcx" },
+
+ { "editor.element_border", "RocksElements.pcx" },
+ { "editor.element_border.xpos", "0" },
+ { "editor.element_border.ypos", "0" },
+
+ { "editor.element_border_input", "RocksElements.pcx" },
+ { "editor.element_border_input.xpos", "0" },
+ { "editor.element_border_input.ypos", "0" },
+
+ { "background", UNDEFINED_FILENAME },
+ { "background.MAIN", UNDEFINED_FILENAME },
+ { "background.LEVELS", UNDEFINED_FILENAME },
+ { "background.SCORES", UNDEFINED_FILENAME },
+ { "background.EDITOR", UNDEFINED_FILENAME },
+ { "background.INFO", UNDEFINED_FILENAME },
+ { "background.SETUP", UNDEFINED_FILENAME },
+ { "background.DOOR", UNDEFINED_FILENAME },
+
+ /* the following directives are not associated with an image, but
+ probably make sense to be defined in "graphicsinfo.conf", too */
+
+ { "global.num_toons", "20" },
+
+ { "menu.draw_xoffset", "0" },
+ { "menu.draw_yoffset", "0" },
+ { "menu.draw_xoffset.MAIN", "0" },
+ { "menu.draw_yoffset.MAIN", "0" },
+ { "menu.draw_xoffset.LEVELS", "0" },
+ { "menu.draw_yoffset.LEVELS", "0" },
+ { "menu.draw_xoffset.SCORES", "0" },
+ { "menu.draw_yoffset.SCORES", "0" },
+ { "menu.draw_xoffset.EDITOR", "0" },
+ { "menu.draw_yoffset.EDITOR", "0" },
+ { "menu.draw_xoffset.INFO", "0" },
+ { "menu.draw_yoffset.INFO", "0" },
+ { "menu.draw_xoffset.SETUP", "0" },
+ { "menu.draw_yoffset.SETUP", "0" },
+
+ { "menu.scrollbar_xoffset", "0" },
+
+ { "menu.list_size", "-1" },
+ { "menu.list_size.LEVELS", "-1" },
+ { "menu.list_size.SCORES", "-1" },
+ { "menu.list_size.INFO", "-1" },
+
+ { "door.step_offset", "2" },
+ { "door.step_delay", "10" },
+
+ { NULL, NULL }
+};
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* (c) 1995-2002 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* conf_gfx.h *
+***********************************************************/
+
+/* ----- this file was automatically generated -- do not edit by hand ----- */
+
+#ifndef CONF_GFX_H
+#define CONF_GFX_H
+
+/* values for graphics configuration (normal elements) */
+
+#define IMG_BD_WALL 0
+#define IMG_BD_WALL_EDITOR 1
+#define IMG_BD_ROCK 2
+#define IMG_BD_ROCK_EDITOR 3
+#define IMG_BD_ROCK_MOVING_LEFT 4
+#define IMG_BD_ROCK_MOVING_RIGHT 5
+#define IMG_BD_ROCK_PUSHING_LEFT 6
+#define IMG_BD_ROCK_PUSHING_RIGHT 7
+#define IMG_BD_DIAMOND 8
+#define IMG_BD_DIAMOND_MOVING 9
+#define IMG_BD_DIAMOND_FALLING 10
+#define IMG_BD_MAGIC_WALL 11
+#define IMG_BD_MAGIC_WALL_ACTIVE 12
+#define IMG_BD_MAGIC_WALL_FILLING 13
+#define IMG_BD_MAGIC_WALL_FULL 14
+#define IMG_BD_MAGIC_WALL_EMPTYING 15
+#define IMG_BD_MAGIC_WALL_DEAD 16
+#define IMG_BD_AMOEBA 17
+#define IMG_BD_AMOEBA_EDITOR 18
+#define IMG_BD_BUTTERFLY 19
+#define IMG_BD_BUTTERFLY_RIGHT 20
+#define IMG_BD_BUTTERFLY_UP 21
+#define IMG_BD_BUTTERFLY_LEFT 22
+#define IMG_BD_BUTTERFLY_DOWN 23
+#define IMG_BD_BUTTERFLY_MOVING 24
+#define IMG_BD_FIREFLY 25
+#define IMG_BD_FIREFLY_RIGHT 26
+#define IMG_BD_FIREFLY_UP 27
+#define IMG_BD_FIREFLY_LEFT 28
+#define IMG_BD_FIREFLY_DOWN 29
+#define IMG_BD_FIREFLY_MOVING 30
+#define IMG_SP_DEFAULT_EXPLODING 31
+#define IMG_SP_EMPTY_SPACE 32
+#define IMG_SP_ZONK 33
+#define IMG_SP_ZONK_MOVING_LEFT 34
+#define IMG_SP_ZONK_MOVING_RIGHT 35
+#define IMG_SP_ZONK_PUSHING_LEFT 36
+#define IMG_SP_ZONK_PUSHING_RIGHT 37
+#define IMG_SP_BASE 38
+#define IMG_SP_MURPHY 39
+#define IMG_SP_MURPHY_MOVING_LEFT 40
+#define IMG_SP_MURPHY_MOVING_RIGHT 41
+#define IMG_SP_MURPHY_DIGGING_LEFT 42
+#define IMG_SP_MURPHY_DIGGING_RIGHT 43
+#define IMG_SP_MURPHY_COLLECTING_LEFT 44
+#define IMG_SP_MURPHY_COLLECTING_RIGHT 45
+#define IMG_SP_MURPHY_PUSHING_LEFT 46
+#define IMG_SP_MURPHY_PUSHING_RIGHT 47
+#define IMG_SP_MURPHY_SNAPPING_LEFT 48
+#define IMG_SP_MURPHY_SNAPPING_RIGHT 49
+#define IMG_SP_MURPHY_SNAPPING_UP 50
+#define IMG_SP_MURPHY_SNAPPING_DOWN 51
+#define IMG_SP_MURPHY_CLONE 52
+#define IMG_SP_INFOTRON 53
+#define IMG_SP_INFOTRON_EDITOR 54
+#define IMG_SP_CHIP_SINGLE 55
+#define IMG_SP_CHIP_LEFT 56
+#define IMG_SP_CHIP_RIGHT 57
+#define IMG_SP_CHIP_TOP 58
+#define IMG_SP_CHIP_BOTTOM 59
+#define IMG_SP_HARDWARE_GRAY 60
+#define IMG_SP_HARDWARE_GREEN 61
+#define IMG_SP_HARDWARE_BLUE 62
+#define IMG_SP_HARDWARE_RED 63
+#define IMG_SP_HARDWARE_YELLOW 64
+#define IMG_SP_EXIT_CLOSED 65
+#define IMG_SP_EXIT_OPEN 66
+#define IMG_SP_DISK_ORANGE 67
+#define IMG_SP_DISK_YELLOW 68
+#define IMG_SP_DISK_RED 69
+#define IMG_SP_DISK_RED_COLLECTING 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_DOWN 79
+#define IMG_SP_GRAVITY_PORT_LEFT 80
+#define IMG_SP_GRAVITY_PORT_UP 81
+#define IMG_SP_SNIKSNAK 82
+#define IMG_SP_SNIKSNAK_LEFT 83
+#define IMG_SP_SNIKSNAK_RIGHT 84
+#define IMG_SP_SNIKSNAK_UP 85
+#define IMG_SP_SNIKSNAK_DOWN 86
+#define IMG_SP_ELECTRON 87
+#define IMG_SP_ELECTRON_EDITOR 88
+#define IMG_SP_ELECTRON_EXPLODING 89
+#define IMG_SP_TERMINAL 90
+#define IMG_SP_TERMINAL_EDITOR 91
+#define IMG_SP_TERMINAL_ACTIVE 92
+#define IMG_SP_BUGGY_BASE 93
+#define IMG_SP_BUGGY_BASE_EDITOR 94
+#define IMG_SP_BUGGY_BASE_ACTIVATING 95
+#define IMG_SP_BUGGY_BASE_ACTIVE 96
+#define IMG_SP_HARDWARE_BASE_1 97
+#define IMG_SP_HARDWARE_BASE_2 98
+#define IMG_SP_HARDWARE_BASE_3 99
+#define IMG_SP_HARDWARE_BASE_4 100
+#define IMG_SP_HARDWARE_BASE_5 101
+#define IMG_SP_HARDWARE_BASE_6 102
+#define IMG_SOKOBAN_OBJECT 103
+#define IMG_SOKOBAN_OBJECT_EDITOR 104
+#define IMG_SOKOBAN_FIELD_EMPTY 105
+#define IMG_SOKOBAN_FIELD_FULL 106
+#define IMG_EMPTY_SPACE 107
+#define IMG_SAND 108
+#define IMG_SAND_CRUMBLED 109
+#define IMG_SAND_DIGGING_LEFT 110
+#define IMG_SAND_DIGGING_RIGHT 111
+#define IMG_SAND_DIGGING_UP 112
+#define IMG_SAND_DIGGING_DOWN 113
+#define IMG_SAND_DIGGING_LEFT_CRUMBLED 114
+#define IMG_SAND_DIGGING_RIGHT_CRUMBLED 115
+#define IMG_SAND_DIGGING_UP_CRUMBLED 116
+#define IMG_SAND_DIGGING_DOWN_CRUMBLED 117
+#define IMG_WALL 118
+#define IMG_WALL_SLIPPERY 119
+#define IMG_STEELWALL 120
+#define IMG_ROCK 121
+#define IMG_ROCK_MOVING_LEFT 122
+#define IMG_ROCK_MOVING_RIGHT 123
+#define IMG_ROCK_PUSHING_LEFT 124
+#define IMG_ROCK_PUSHING_RIGHT 125
+#define IMG_EMERALD 126
+#define IMG_EMERALD_MOVING 127
+#define IMG_EMERALD_FALLING 128
+#define IMG_EMERALD_COLLECTING 129
+#define IMG_DIAMOND 130
+#define IMG_DIAMOND_MOVING 131
+#define IMG_DIAMOND_FALLING 132
+#define IMG_DIAMOND_COLLECTING 133
+#define IMG_BOMB 134
+#define IMG_NUT 135
+#define IMG_NUT_BREAKING 136
+#define IMG_DYNAMITE 137
+#define IMG_DYNAMITE_EDITOR 138
+#define IMG_DYNAMITE_ACTIVE 139
+#define IMG_DYNAMITE_ACTIVE_EDITOR 140
+#define IMG_WALL_EMERALD 141
+#define IMG_WALL_DIAMOND 142
+#define IMG_BUG 143
+#define IMG_BUG_RIGHT 144
+#define IMG_BUG_UP 145
+#define IMG_BUG_LEFT 146
+#define IMG_BUG_DOWN 147
+#define IMG_BUG_MOVING_RIGHT 148
+#define IMG_BUG_MOVING_UP 149
+#define IMG_BUG_MOVING_LEFT 150
+#define IMG_BUG_MOVING_DOWN 151
+#define IMG_SPACESHIP 152
+#define IMG_SPACESHIP_RIGHT 153
+#define IMG_SPACESHIP_UP 154
+#define IMG_SPACESHIP_LEFT 155
+#define IMG_SPACESHIP_DOWN 156
+#define IMG_SPACESHIP_MOVING_RIGHT 157
+#define IMG_SPACESHIP_MOVING_UP 158
+#define IMG_SPACESHIP_MOVING_LEFT 159
+#define IMG_SPACESHIP_MOVING_DOWN 160
+#define IMG_YAMYAM 161
+#define IMG_YAMYAM_MOVING 162
+#define IMG_ROBOT 163
+#define IMG_ROBOT_MOVING 164
+#define IMG_ROBOT_WHEEL 165
+#define IMG_ROBOT_WHEEL_ACTIVE 166
+#define IMG_MAGIC_WALL 167
+#define IMG_MAGIC_WALL_ACTIVE 168
+#define IMG_MAGIC_WALL_FILLING 169
+#define IMG_MAGIC_WALL_FULL 170
+#define IMG_MAGIC_WALL_EMPTYING 171
+#define IMG_MAGIC_WALL_DEAD 172
+#define IMG_QUICKSAND_EMPTY 173
+#define IMG_QUICKSAND_FILLING 174
+#define IMG_QUICKSAND_FULL 175
+#define IMG_QUICKSAND_FULL_EDITOR 176
+#define IMG_QUICKSAND_EMPTYING 177
+#define IMG_ACID_POOL_TOPLEFT 178
+#define IMG_ACID_POOL_TOPRIGHT 179
+#define IMG_ACID_POOL_BOTTOMLEFT 180
+#define IMG_ACID_POOL_BOTTOM 181
+#define IMG_ACID_POOL_BOTTOMRIGHT 182
+#define IMG_ACID 183
+#define IMG_ACID_SPLASH_LEFT 184
+#define IMG_ACID_SPLASH_RIGHT 185
+#define IMG_AMOEBA_DROP 186
+#define IMG_AMOEBA_GROWING 187
+#define IMG_AMOEBA_SHRINKING 188
+#define IMG_AMOEBA_WET 189
+#define IMG_AMOEBA_WET_EDITOR 190
+#define IMG_AMOEBA_DROPPING 191
+#define IMG_AMOEBA_DRY 192
+#define IMG_AMOEBA_FULL 193
+#define IMG_AMOEBA_FULL_EDITOR 194
+#define IMG_AMOEBA_DEAD 195
+#define IMG_AMOEBA_DEAD_EDITOR 196
+#define IMG_EM_KEY_1 197
+#define IMG_EM_KEY_2 198
+#define IMG_EM_KEY_3 199
+#define IMG_EM_KEY_4 200
+#define IMG_EM_GATE_1 201
+#define IMG_EM_GATE_2 202
+#define IMG_EM_GATE_3 203
+#define IMG_EM_GATE_4 204
+#define IMG_EM_GATE_1_GRAY 205
+#define IMG_EM_GATE_1_GRAY_EDITOR 206
+#define IMG_EM_GATE_2_GRAY 207
+#define IMG_EM_GATE_2_GRAY_EDITOR 208
+#define IMG_EM_GATE_3_GRAY 209
+#define IMG_EM_GATE_3_GRAY_EDITOR 210
+#define IMG_EM_GATE_4_GRAY 211
+#define IMG_EM_GATE_4_GRAY_EDITOR 212
+#define IMG_EXIT_CLOSED 213
+#define IMG_EXIT_OPENING 214
+#define IMG_EXIT_OPEN 215
+#define IMG_BALLOON 216
+#define IMG_BALLOON_MOVING 217
+#define IMG_BALLOON_PUSHING 218
+#define IMG_BALLOON_SWITCH_LEFT 219
+#define IMG_BALLOON_SWITCH_RIGHT 220
+#define IMG_BALLOON_SWITCH_UP 221
+#define IMG_BALLOON_SWITCH_DOWN 222
+#define IMG_BALLOON_SWITCH_ANY 223
+#define IMG_SPRING 224
+#define IMG_EMC_STEELWALL_1 225
+#define IMG_EMC_STEELWALL_2 226
+#define IMG_EMC_STEELWALL_3 227
+#define IMG_EMC_STEELWALL_4 228
+#define IMG_EMC_WALL_1 229
+#define IMG_EMC_WALL_2 230
+#define IMG_EMC_WALL_3 231
+#define IMG_EMC_WALL_4 232
+#define IMG_EMC_WALL_5 233
+#define IMG_EMC_WALL_6 234
+#define IMG_EMC_WALL_7 235
+#define IMG_EMC_WALL_8 236
+#define IMG_INVISIBLE_STEELWALL 237
+#define IMG_INVISIBLE_STEELWALL_EDITOR 238
+#define IMG_INVISIBLE_STEELWALL_ACTIVE 239
+#define IMG_INVISIBLE_WALL 240
+#define IMG_INVISIBLE_WALL_EDITOR 241
+#define IMG_INVISIBLE_WALL_ACTIVE 242
+#define IMG_INVISIBLE_SAND 243
+#define IMG_INVISIBLE_SAND_EDITOR 244
+#define IMG_INVISIBLE_SAND_ACTIVE 245
+#define IMG_CONVEYOR_BELT_1_MIDDLE 246
+#define IMG_CONVEYOR_BELT_1_MIDDLE_ACTIVE 247
+#define IMG_CONVEYOR_BELT_1_LEFT 248
+#define IMG_CONVEYOR_BELT_1_LEFT_ACTIVE 249
+#define IMG_CONVEYOR_BELT_1_RIGHT 250
+#define IMG_CONVEYOR_BELT_1_RIGHT_ACTIVE 251
+#define IMG_CONVEYOR_BELT_1_SWITCH_LEFT 252
+#define IMG_CONVEYOR_BELT_1_SWITCH_MIDDLE 253
+#define IMG_CONVEYOR_BELT_1_SWITCH_RIGHT 254
+#define IMG_CONVEYOR_BELT_2_MIDDLE 255
+#define IMG_CONVEYOR_BELT_2_MIDDLE_ACTIVE 256
+#define IMG_CONVEYOR_BELT_2_LEFT 257
+#define IMG_CONVEYOR_BELT_2_LEFT_ACTIVE 258
+#define IMG_CONVEYOR_BELT_2_RIGHT 259
+#define IMG_CONVEYOR_BELT_2_RIGHT_ACTIVE 260
+#define IMG_CONVEYOR_BELT_2_SWITCH_LEFT 261
+#define IMG_CONVEYOR_BELT_2_SWITCH_MIDDLE 262
+#define IMG_CONVEYOR_BELT_2_SWITCH_RIGHT 263
+#define IMG_CONVEYOR_BELT_3_MIDDLE 264
+#define IMG_CONVEYOR_BELT_3_MIDDLE_ACTIVE 265
+#define IMG_CONVEYOR_BELT_3_LEFT 266
+#define IMG_CONVEYOR_BELT_3_LEFT_ACTIVE 267
+#define IMG_CONVEYOR_BELT_3_RIGHT 268
+#define IMG_CONVEYOR_BELT_3_RIGHT_ACTIVE 269
+#define IMG_CONVEYOR_BELT_3_SWITCH_LEFT 270
+#define IMG_CONVEYOR_BELT_3_SWITCH_MIDDLE 271
+#define IMG_CONVEYOR_BELT_3_SWITCH_RIGHT 272
+#define IMG_CONVEYOR_BELT_4_MIDDLE 273
+#define IMG_CONVEYOR_BELT_4_MIDDLE_ACTIVE 274
+#define IMG_CONVEYOR_BELT_4_LEFT 275
+#define IMG_CONVEYOR_BELT_4_LEFT_ACTIVE 276
+#define IMG_CONVEYOR_BELT_4_RIGHT 277
+#define IMG_CONVEYOR_BELT_4_RIGHT_ACTIVE 278
+#define IMG_CONVEYOR_BELT_4_SWITCH_LEFT 279
+#define IMG_CONVEYOR_BELT_4_SWITCH_MIDDLE 280
+#define IMG_CONVEYOR_BELT_4_SWITCH_RIGHT 281
+#define IMG_SWITCHGATE_SWITCH_UP 282
+#define IMG_SWITCHGATE_SWITCH_DOWN 283
+#define IMG_LIGHT_SWITCH 284
+#define IMG_LIGHT_SWITCH_ACTIVE 285
+#define IMG_TIMEGATE_SWITCH 286
+#define IMG_TIMEGATE_SWITCH_ACTIVE 287
+#define IMG_ENVELOPE 288
+#define IMG_SIGN_EXCLAMATION 289
+#define IMG_SIGN_STOP 290
+#define IMG_LANDMINE 291
+#define IMG_STEELWALL_SLIPPERY 292
+#define IMG_EXTRA_TIME 293
+#define IMG_SHIELD_NORMAL 294
+#define IMG_SHIELD_NORMAL_ACTIVE 295
+#define IMG_SHIELD_DEADLY 296
+#define IMG_SHIELD_DEADLY_ACTIVE 297
+#define IMG_SWITCHGATE_CLOSED 298
+#define IMG_SWITCHGATE_OPENING 299
+#define IMG_SWITCHGATE_OPEN 300
+#define IMG_SWITCHGATE_CLOSING 301
+#define IMG_TIMEGATE_CLOSED 302
+#define IMG_TIMEGATE_OPENING 303
+#define IMG_TIMEGATE_OPEN 304
+#define IMG_TIMEGATE_CLOSING 305
+#define IMG_PEARL 306
+#define IMG_PEARL_BREAKING 307
+#define IMG_CRYSTAL 308
+#define IMG_WALL_PEARL 309
+#define IMG_WALL_CRYSTAL 310
+#define IMG_TUBE_RIGHT_DOWN 311
+#define IMG_TUBE_HORIZONTAL_DOWN 312
+#define IMG_TUBE_LEFT_DOWN 313
+#define IMG_TUBE_HORIZONTAL 314
+#define IMG_TUBE_VERTICAL_RIGHT 315
+#define IMG_TUBE_ANY 316
+#define IMG_TUBE_VERTICAL_LEFT 317
+#define IMG_TUBE_VERTICAL 318
+#define IMG_TUBE_RIGHT_UP 319
+#define IMG_TUBE_HORIZONTAL_UP 320
+#define IMG_TUBE_LEFT_UP 321
+#define IMG_TRAP 322
+#define IMG_TRAP_ACTIVE 323
+#define IMG_DX_SUPABOMB 324
+#define IMG_KEY_1 325
+#define IMG_KEY_1_EDITOR 326
+#define IMG_KEY_2 327
+#define IMG_KEY_2_EDITOR 328
+#define IMG_KEY_3 329
+#define IMG_KEY_3_EDITOR 330
+#define IMG_KEY_4 331
+#define IMG_KEY_4_EDITOR 332
+#define IMG_GATE_1 333
+#define IMG_GATE_2 334
+#define IMG_GATE_3 335
+#define IMG_GATE_4 336
+#define IMG_GATE_1_GRAY 337
+#define IMG_GATE_1_GRAY_EDITOR 338
+#define IMG_GATE_2_GRAY 339
+#define IMG_GATE_2_GRAY_EDITOR 340
+#define IMG_GATE_3_GRAY 341
+#define IMG_GATE_3_GRAY_EDITOR 342
+#define IMG_GATE_4_GRAY 343
+#define IMG_GATE_4_GRAY_EDITOR 344
+#define IMG_GAME_OF_LIFE 345
+#define IMG_BIOMAZE 346
+#define IMG_PACMAN 347
+#define IMG_PACMAN_RIGHT 348
+#define IMG_PACMAN_UP 349
+#define IMG_PACMAN_LEFT 350
+#define IMG_PACMAN_DOWN 351
+#define IMG_PACMAN_MOVING_RIGHT 352
+#define IMG_PACMAN_MOVING_UP 353
+#define IMG_PACMAN_MOVING_LEFT 354
+#define IMG_PACMAN_MOVING_DOWN 355
+#define IMG_LAMP 356
+#define IMG_LAMP_EDITOR 357
+#define IMG_LAMP_ACTIVE 358
+#define IMG_TIME_ORB_FULL 359
+#define IMG_TIME_ORB_EMPTY 360
+#define IMG_EMERALD_YELLOW 361
+#define IMG_EMERALD_YELLOW_MOVING 362
+#define IMG_EMERALD_YELLOW_FALLING 363
+#define IMG_EMERALD_RED 364
+#define IMG_EMERALD_RED_MOVING 365
+#define IMG_EMERALD_RED_FALLING 366
+#define IMG_EMERALD_PURPLE 367
+#define IMG_EMERALD_PURPLE_MOVING 368
+#define IMG_EMERALD_PURPLE_FALLING 369
+#define IMG_WALL_EMERALD_YELLOW 370
+#define IMG_WALL_EMERALD_RED 371
+#define IMG_WALL_EMERALD_PURPLE 372
+#define IMG_WALL_BD_DIAMOND 373
+#define IMG_EXPANDABLE_WALL 374
+#define IMG_EXPANDABLE_WALL_HORIZONTAL 375
+#define IMG_EXPANDABLE_WALL_HORIZONTAL_EDITOR 376
+#define IMG_EXPANDABLE_WALL_VERTICAL 377
+#define IMG_EXPANDABLE_WALL_VERTICAL_EDITOR 378
+#define IMG_EXPANDABLE_WALL_ANY 379
+#define IMG_EXPANDABLE_WALL_ANY_EDITOR 380
+#define IMG_EXPANDABLE_WALL_GROWING_LEFT 381
+#define IMG_EXPANDABLE_WALL_GROWING_RIGHT 382
+#define IMG_EXPANDABLE_WALL_GROWING_UP 383
+#define IMG_EXPANDABLE_WALL_GROWING_DOWN 384
+#define IMG_BLACK_ORB 385
+#define IMG_SPEED_PILL 386
+#define IMG_DARK_YAMYAM 387
+#define IMG_DYNABOMB 388
+#define IMG_DYNABOMB_ACTIVE 389
+#define IMG_DYNABOMB_PLAYER_1 390
+#define IMG_DYNABOMB_PLAYER_1_ACTIVE 391
+#define IMG_DYNABOMB_PLAYER_2 392
+#define IMG_DYNABOMB_PLAYER_2_ACTIVE 393
+#define IMG_DYNABOMB_PLAYER_3 394
+#define IMG_DYNABOMB_PLAYER_3_ACTIVE 395
+#define IMG_DYNABOMB_PLAYER_4 396
+#define IMG_DYNABOMB_PLAYER_4_ACTIVE 397
+#define IMG_DYNABOMB_INCREASE_NUMBER 398
+#define IMG_DYNABOMB_INCREASE_SIZE 399
+#define IMG_DYNABOMB_INCREASE_POWER 400
+#define IMG_PIG 401
+#define IMG_PIG_DOWN 402
+#define IMG_PIG_UP 403
+#define IMG_PIG_LEFT 404
+#define IMG_PIG_RIGHT 405
+#define IMG_PIG_MOVING_DOWN 406
+#define IMG_PIG_MOVING_UP 407
+#define IMG_PIG_MOVING_LEFT 408
+#define IMG_PIG_MOVING_RIGHT 409
+#define IMG_PIG_DIGGING_DOWN 410
+#define IMG_PIG_DIGGING_UP 411
+#define IMG_PIG_DIGGING_LEFT 412
+#define IMG_PIG_DIGGING_RIGHT 413
+#define IMG_DRAGON 414
+#define IMG_DRAGON_DOWN 415
+#define IMG_DRAGON_UP 416
+#define IMG_DRAGON_LEFT 417
+#define IMG_DRAGON_RIGHT 418
+#define IMG_DRAGON_MOVING_DOWN 419
+#define IMG_DRAGON_MOVING_UP 420
+#define IMG_DRAGON_MOVING_LEFT 421
+#define IMG_DRAGON_MOVING_RIGHT 422
+#define IMG_DRAGON_ATTACKING_DOWN 423
+#define IMG_DRAGON_ATTACKING_UP 424
+#define IMG_DRAGON_ATTACKING_LEFT 425
+#define IMG_DRAGON_ATTACKING_RIGHT 426
+#define IMG_MOLE 427
+#define IMG_MOLE_DOWN 428
+#define IMG_MOLE_UP 429
+#define IMG_MOLE_LEFT 430
+#define IMG_MOLE_RIGHT 431
+#define IMG_MOLE_MOVING_DOWN 432
+#define IMG_MOLE_MOVING_UP 433
+#define IMG_MOLE_MOVING_LEFT 434
+#define IMG_MOLE_MOVING_RIGHT 435
+#define IMG_MOLE_DIGGING_DOWN 436
+#define IMG_MOLE_DIGGING_UP 437
+#define IMG_MOLE_DIGGING_LEFT 438
+#define IMG_MOLE_DIGGING_RIGHT 439
+#define IMG_PENGUIN 440
+#define IMG_PENGUIN_EDITOR 441
+#define IMG_PENGUIN_DOWN 442
+#define IMG_PENGUIN_UP 443
+#define IMG_PENGUIN_LEFT 444
+#define IMG_PENGUIN_RIGHT 445
+#define IMG_PENGUIN_MOVING_DOWN 446
+#define IMG_PENGUIN_MOVING_UP 447
+#define IMG_PENGUIN_MOVING_LEFT 448
+#define IMG_PENGUIN_MOVING_RIGHT 449
+#define IMG_SATELLITE 450
+#define IMG_FLAMES_1_LEFT 451
+#define IMG_FLAMES_2_LEFT 452
+#define IMG_FLAMES_3_LEFT 453
+#define IMG_FLAMES_1_RIGHT 454
+#define IMG_FLAMES_2_RIGHT 455
+#define IMG_FLAMES_3_RIGHT 456
+#define IMG_FLAMES_1_UP 457
+#define IMG_FLAMES_2_UP 458
+#define IMG_FLAMES_3_UP 459
+#define IMG_FLAMES_1_DOWN 460
+#define IMG_FLAMES_2_DOWN 461
+#define IMG_FLAMES_3_DOWN 462
+#define IMG_STONEBLOCK 463
+#define IMG_PLAYER_1 464
+#define IMG_PLAYER_1_EDITOR 465
+#define IMG_PLAYER_1_DOWN 466
+#define IMG_PLAYER_1_UP 467
+#define IMG_PLAYER_1_LEFT 468
+#define IMG_PLAYER_1_RIGHT 469
+#define IMG_PLAYER_1_MOVING_DOWN 470
+#define IMG_PLAYER_1_MOVING_UP 471
+#define IMG_PLAYER_1_MOVING_LEFT 472
+#define IMG_PLAYER_1_MOVING_RIGHT 473
+#define IMG_PLAYER_1_DIGGING_DOWN 474
+#define IMG_PLAYER_1_DIGGING_UP 475
+#define IMG_PLAYER_1_DIGGING_LEFT 476
+#define IMG_PLAYER_1_DIGGING_RIGHT 477
+#define IMG_PLAYER_1_COLLECTING_DOWN 478
+#define IMG_PLAYER_1_COLLECTING_UP 479
+#define IMG_PLAYER_1_COLLECTING_LEFT 480
+#define IMG_PLAYER_1_COLLECTING_RIGHT 481
+#define IMG_PLAYER_1_PUSHING_DOWN 482
+#define IMG_PLAYER_1_PUSHING_UP 483
+#define IMG_PLAYER_1_PUSHING_LEFT 484
+#define IMG_PLAYER_1_PUSHING_RIGHT 485
+#define IMG_PLAYER_1_SNAPPING_DOWN 486
+#define IMG_PLAYER_1_SNAPPING_UP 487
+#define IMG_PLAYER_1_SNAPPING_LEFT 488
+#define IMG_PLAYER_1_SNAPPING_RIGHT 489
+#define IMG_PLAYER_2 490
+#define IMG_PLAYER_2_EDITOR 491
+#define IMG_PLAYER_2_DOWN 492
+#define IMG_PLAYER_2_UP 493
+#define IMG_PLAYER_2_LEFT 494
+#define IMG_PLAYER_2_RIGHT 495
+#define IMG_PLAYER_2_MOVING_DOWN 496
+#define IMG_PLAYER_2_MOVING_UP 497
+#define IMG_PLAYER_2_MOVING_LEFT 498
+#define IMG_PLAYER_2_MOVING_RIGHT 499
+#define IMG_PLAYER_2_DIGGING_DOWN 500
+#define IMG_PLAYER_2_DIGGING_UP 501
+#define IMG_PLAYER_2_DIGGING_LEFT 502
+#define IMG_PLAYER_2_DIGGING_RIGHT 503
+#define IMG_PLAYER_2_COLLECTING_DOWN 504
+#define IMG_PLAYER_2_COLLECTING_UP 505
+#define IMG_PLAYER_2_COLLECTING_LEFT 506
+#define IMG_PLAYER_2_COLLECTING_RIGHT 507
+#define IMG_PLAYER_2_PUSHING_DOWN 508
+#define IMG_PLAYER_2_PUSHING_UP 509
+#define IMG_PLAYER_2_PUSHING_LEFT 510
+#define IMG_PLAYER_2_PUSHING_RIGHT 511
+#define IMG_PLAYER_2_SNAPPING_DOWN 512
+#define IMG_PLAYER_2_SNAPPING_UP 513
+#define IMG_PLAYER_2_SNAPPING_LEFT 514
+#define IMG_PLAYER_2_SNAPPING_RIGHT 515
+#define IMG_PLAYER_3 516
+#define IMG_PLAYER_3_EDITOR 517
+#define IMG_PLAYER_3_DOWN 518
+#define IMG_PLAYER_3_UP 519
+#define IMG_PLAYER_3_LEFT 520
+#define IMG_PLAYER_3_RIGHT 521
+#define IMG_PLAYER_3_MOVING_DOWN 522
+#define IMG_PLAYER_3_MOVING_UP 523
+#define IMG_PLAYER_3_MOVING_LEFT 524
+#define IMG_PLAYER_3_MOVING_RIGHT 525
+#define IMG_PLAYER_3_DIGGING_DOWN 526
+#define IMG_PLAYER_3_DIGGING_UP 527
+#define IMG_PLAYER_3_DIGGING_LEFT 528
+#define IMG_PLAYER_3_DIGGING_RIGHT 529
+#define IMG_PLAYER_3_COLLECTING_DOWN 530
+#define IMG_PLAYER_3_COLLECTING_UP 531
+#define IMG_PLAYER_3_COLLECTING_LEFT 532
+#define IMG_PLAYER_3_COLLECTING_RIGHT 533
+#define IMG_PLAYER_3_PUSHING_DOWN 534
+#define IMG_PLAYER_3_PUSHING_UP 535
+#define IMG_PLAYER_3_PUSHING_LEFT 536
+#define IMG_PLAYER_3_PUSHING_RIGHT 537
+#define IMG_PLAYER_3_SNAPPING_DOWN 538
+#define IMG_PLAYER_3_SNAPPING_UP 539
+#define IMG_PLAYER_3_SNAPPING_LEFT 540
+#define IMG_PLAYER_3_SNAPPING_RIGHT 541
+#define IMG_PLAYER_4 542
+#define IMG_PLAYER_4_EDITOR 543
+#define IMG_PLAYER_4_DOWN 544
+#define IMG_PLAYER_4_UP 545
+#define IMG_PLAYER_4_LEFT 546
+#define IMG_PLAYER_4_RIGHT 547
+#define IMG_PLAYER_4_MOVING_DOWN 548
+#define IMG_PLAYER_4_MOVING_UP 549
+#define IMG_PLAYER_4_MOVING_LEFT 550
+#define IMG_PLAYER_4_MOVING_RIGHT 551
+#define IMG_PLAYER_4_DIGGING_DOWN 552
+#define IMG_PLAYER_4_DIGGING_UP 553
+#define IMG_PLAYER_4_DIGGING_LEFT 554
+#define IMG_PLAYER_4_DIGGING_RIGHT 555
+#define IMG_PLAYER_4_COLLECTING_DOWN 556
+#define IMG_PLAYER_4_COLLECTING_UP 557
+#define IMG_PLAYER_4_COLLECTING_LEFT 558
+#define IMG_PLAYER_4_COLLECTING_RIGHT 559
+#define IMG_PLAYER_4_PUSHING_DOWN 560
+#define IMG_PLAYER_4_PUSHING_UP 561
+#define IMG_PLAYER_4_PUSHING_LEFT 562
+#define IMG_PLAYER_4_PUSHING_RIGHT 563
+#define IMG_PLAYER_4_SNAPPING_DOWN 564
+#define IMG_PLAYER_4_SNAPPING_UP 565
+#define IMG_PLAYER_4_SNAPPING_LEFT 566
+#define IMG_PLAYER_4_SNAPPING_RIGHT 567
+#define IMG_DEFAULT_EXPLODING 568
+#define IMG_TWINKLE_BLUE 569
+#define IMG_TWINKLE_WHITE 570
+#define IMG_STEELWALL_TOPLEFT 571
+#define IMG_STEELWALL_TOPRIGHT 572
+#define IMG_STEELWALL_BOTTOMLEFT 573
+#define IMG_STEELWALL_BOTTOMRIGHT 574
+#define IMG_STEELWALL_HORIZONTAL 575
+#define IMG_STEELWALL_VERTICAL 576
+#define IMG_STEELWALL_TOPLEFT_EDITOR 577
+#define IMG_STEELWALL_TOPRIGHT_EDITOR 578
+#define IMG_STEELWALL_BOTTOMLEFT_EDITOR 579
+#define IMG_STEELWALL_BOTTOMRIGHT_EDITOR 580
+#define IMG_STEELWALL_HORIZONTAL_EDITOR 581
+#define IMG_STEELWALL_VERTICAL_EDITOR 582
+#define IMG_INVISIBLE_STEELWALL_TOPLEFT 583
+#define IMG_INVISIBLE_STEELWALL_TOPRIGHT 584
+#define IMG_INVISIBLE_STEELWALL_BOTTOMLEFT 585
+#define IMG_INVISIBLE_STEELWALL_BOTTOMRIGHT 586
+#define IMG_INVISIBLE_STEELWALL_HORIZONTAL 587
+#define IMG_INVISIBLE_STEELWALL_VERTICAL 588
+#define IMG_INVISIBLE_STEELWALL_TOPLEFT_EDITOR 589
+#define IMG_INVISIBLE_STEELWALL_TOPRIGHT_EDITOR 590
+#define IMG_INVISIBLE_STEELWALL_BOTTOMLEFT_EDITOR 591
+#define IMG_INVISIBLE_STEELWALL_BOTTOMRIGHT_EDITOR 592
+#define IMG_INVISIBLE_STEELWALL_HORIZONTAL_EDITOR 593
+#define IMG_INVISIBLE_STEELWALL_VERTICAL_EDITOR 594
+#define IMG_ARROW_LEFT 595
+#define IMG_ARROW_RIGHT 596
+#define IMG_ARROW_UP 597
+#define IMG_ARROW_DOWN 598
+#define IMG_CHAR_SPACE 599
+#define IMG_CHAR_EXCLAM 600
+#define IMG_CHAR_QUOTEDBL 601
+#define IMG_CHAR_NUMBERSIGN 602
+#define IMG_CHAR_DOLLAR 603
+#define IMG_CHAR_PROCENT 604
+#define IMG_CHAR_AMPERSAND 605
+#define IMG_CHAR_APOSTROPHE 606
+#define IMG_CHAR_PARENLEFT 607
+#define IMG_CHAR_PARENRIGHT 608
+#define IMG_CHAR_ASTERISK 609
+#define IMG_CHAR_PLUS 610
+#define IMG_CHAR_COMMA 611
+#define IMG_CHAR_MINUS 612
+#define IMG_CHAR_PERIOD 613
+#define IMG_CHAR_SLASH 614
+#define IMG_CHAR_0 615
+#define IMG_CHAR_1 616
+#define IMG_CHAR_2 617
+#define IMG_CHAR_3 618
+#define IMG_CHAR_4 619
+#define IMG_CHAR_5 620
+#define IMG_CHAR_6 621
+#define IMG_CHAR_7 622
+#define IMG_CHAR_8 623
+#define IMG_CHAR_9 624
+#define IMG_CHAR_COLON 625
+#define IMG_CHAR_SEMICOLON 626
+#define IMG_CHAR_LESS 627
+#define IMG_CHAR_EQUAL 628
+#define IMG_CHAR_GREATER 629
+#define IMG_CHAR_QUESTION 630
+#define IMG_CHAR_AT 631
+#define IMG_CHAR_A 632
+#define IMG_CHAR_B 633
+#define IMG_CHAR_C 634
+#define IMG_CHAR_D 635
+#define IMG_CHAR_E 636
+#define IMG_CHAR_F 637
+#define IMG_CHAR_G 638
+#define IMG_CHAR_H 639
+#define IMG_CHAR_I 640
+#define IMG_CHAR_J 641
+#define IMG_CHAR_K 642
+#define IMG_CHAR_L 643
+#define IMG_CHAR_M 644
+#define IMG_CHAR_N 645
+#define IMG_CHAR_O 646
+#define IMG_CHAR_P 647
+#define IMG_CHAR_Q 648
+#define IMG_CHAR_R 649
+#define IMG_CHAR_S 650
+#define IMG_CHAR_T 651
+#define IMG_CHAR_U 652
+#define IMG_CHAR_V 653
+#define IMG_CHAR_W 654
+#define IMG_CHAR_X 655
+#define IMG_CHAR_Y 656
+#define IMG_CHAR_Z 657
+#define IMG_CHAR_BRACKETLEFT 658
+#define IMG_CHAR_BACKSLASH 659
+#define IMG_CHAR_BRACKETRIGHT 660
+#define IMG_CHAR_ASCIICIRCUM 661
+#define IMG_CHAR_UNDERSCORE 662
+#define IMG_CHAR_COPYRIGHT 663
+#define IMG_CHAR_AUMLAUT 664
+#define IMG_CHAR_OUMLAUT 665
+#define IMG_CHAR_UUMLAUT 666
+#define IMG_CHAR_DEGREE 667
+#define IMG_CHAR_TRADEMARK 668
+#define IMG_CHAR_CURSOR 669
+#define IMG_CUSTOM_1 670
+#define IMG_CUSTOM_1_EDITOR 671
+#define IMG_CUSTOM_2 672
+#define IMG_CUSTOM_2_EDITOR 673
+#define IMG_CUSTOM_3 674
+#define IMG_CUSTOM_3_EDITOR 675
+#define IMG_CUSTOM_4 676
+#define IMG_CUSTOM_4_EDITOR 677
+#define IMG_CUSTOM_5 678
+#define IMG_CUSTOM_5_EDITOR 679
+#define IMG_CUSTOM_6 680
+#define IMG_CUSTOM_6_EDITOR 681
+#define IMG_CUSTOM_7 682
+#define IMG_CUSTOM_7_EDITOR 683
+#define IMG_CUSTOM_8 684
+#define IMG_CUSTOM_8_EDITOR 685
+#define IMG_CUSTOM_9 686
+#define IMG_CUSTOM_9_EDITOR 687
+#define IMG_CUSTOM_10 688
+#define IMG_CUSTOM_10_EDITOR 689
+#define IMG_CUSTOM_11 690
+#define IMG_CUSTOM_11_EDITOR 691
+#define IMG_CUSTOM_12 692
+#define IMG_CUSTOM_12_EDITOR 693
+#define IMG_CUSTOM_13 694
+#define IMG_CUSTOM_13_EDITOR 695
+#define IMG_CUSTOM_14 696
+#define IMG_CUSTOM_14_EDITOR 697
+#define IMG_CUSTOM_15 698
+#define IMG_CUSTOM_15_EDITOR 699
+#define IMG_CUSTOM_16 700
+#define IMG_CUSTOM_16_EDITOR 701
+#define IMG_CUSTOM_17 702
+#define IMG_CUSTOM_17_EDITOR 703
+#define IMG_CUSTOM_18 704
+#define IMG_CUSTOM_18_EDITOR 705
+#define IMG_CUSTOM_19 706
+#define IMG_CUSTOM_19_EDITOR 707
+#define IMG_CUSTOM_20 708
+#define IMG_CUSTOM_20_EDITOR 709
+#define IMG_CUSTOM_21 710
+#define IMG_CUSTOM_21_EDITOR 711
+#define IMG_CUSTOM_22 712
+#define IMG_CUSTOM_22_EDITOR 713
+#define IMG_CUSTOM_23 714
+#define IMG_CUSTOM_23_EDITOR 715
+#define IMG_CUSTOM_24 716
+#define IMG_CUSTOM_24_EDITOR 717
+#define IMG_CUSTOM_25 718
+#define IMG_CUSTOM_25_EDITOR 719
+#define IMG_CUSTOM_26 720
+#define IMG_CUSTOM_26_EDITOR 721
+#define IMG_CUSTOM_27 722
+#define IMG_CUSTOM_27_EDITOR 723
+#define IMG_CUSTOM_28 724
+#define IMG_CUSTOM_28_EDITOR 725
+#define IMG_CUSTOM_29 726
+#define IMG_CUSTOM_29_EDITOR 727
+#define IMG_CUSTOM_30 728
+#define IMG_CUSTOM_30_EDITOR 729
+#define IMG_CUSTOM_31 730
+#define IMG_CUSTOM_31_EDITOR 731
+#define IMG_CUSTOM_32 732
+#define IMG_CUSTOM_32_EDITOR 733
+#define IMG_CUSTOM_33 734
+#define IMG_CUSTOM_33_EDITOR 735
+#define IMG_CUSTOM_34 736
+#define IMG_CUSTOM_34_EDITOR 737
+#define IMG_CUSTOM_35 738
+#define IMG_CUSTOM_35_EDITOR 739
+#define IMG_CUSTOM_36 740
+#define IMG_CUSTOM_36_EDITOR 741
+#define IMG_CUSTOM_37 742
+#define IMG_CUSTOM_37_EDITOR 743
+#define IMG_CUSTOM_38 744
+#define IMG_CUSTOM_38_EDITOR 745
+#define IMG_CUSTOM_39 746
+#define IMG_CUSTOM_39_EDITOR 747
+#define IMG_CUSTOM_40 748
+#define IMG_CUSTOM_40_EDITOR 749
+#define IMG_CUSTOM_41 750
+#define IMG_CUSTOM_41_EDITOR 751
+#define IMG_CUSTOM_42 752
+#define IMG_CUSTOM_42_EDITOR 753
+#define IMG_CUSTOM_43 754
+#define IMG_CUSTOM_43_EDITOR 755
+#define IMG_CUSTOM_44 756
+#define IMG_CUSTOM_44_EDITOR 757
+#define IMG_CUSTOM_45 758
+#define IMG_CUSTOM_45_EDITOR 759
+#define IMG_CUSTOM_46 760
+#define IMG_CUSTOM_46_EDITOR 761
+#define IMG_CUSTOM_47 762
+#define IMG_CUSTOM_47_EDITOR 763
+#define IMG_CUSTOM_48 764
+#define IMG_CUSTOM_48_EDITOR 765
+#define IMG_CUSTOM_49 766
+#define IMG_CUSTOM_49_EDITOR 767
+#define IMG_CUSTOM_50 768
+#define IMG_CUSTOM_50_EDITOR 769
+#define IMG_CUSTOM_51 770
+#define IMG_CUSTOM_51_EDITOR 771
+#define IMG_CUSTOM_52 772
+#define IMG_CUSTOM_52_EDITOR 773
+#define IMG_CUSTOM_53 774
+#define IMG_CUSTOM_53_EDITOR 775
+#define IMG_CUSTOM_54 776
+#define IMG_CUSTOM_54_EDITOR 777
+#define IMG_CUSTOM_55 778
+#define IMG_CUSTOM_55_EDITOR 779
+#define IMG_CUSTOM_56 780
+#define IMG_CUSTOM_56_EDITOR 781
+#define IMG_CUSTOM_57 782
+#define IMG_CUSTOM_57_EDITOR 783
+#define IMG_CUSTOM_58 784
+#define IMG_CUSTOM_58_EDITOR 785
+#define IMG_CUSTOM_59 786
+#define IMG_CUSTOM_59_EDITOR 787
+#define IMG_CUSTOM_60 788
+#define IMG_CUSTOM_60_EDITOR 789
+#define IMG_CUSTOM_61 790
+#define IMG_CUSTOM_61_EDITOR 791
+#define IMG_CUSTOM_62 792
+#define IMG_CUSTOM_62_EDITOR 793
+#define IMG_CUSTOM_63 794
+#define IMG_CUSTOM_63_EDITOR 795
+#define IMG_CUSTOM_64 796
+#define IMG_CUSTOM_64_EDITOR 797
+#define IMG_CUSTOM_65 798
+#define IMG_CUSTOM_65_EDITOR 799
+#define IMG_CUSTOM_66 800
+#define IMG_CUSTOM_66_EDITOR 801
+#define IMG_CUSTOM_67 802
+#define IMG_CUSTOM_67_EDITOR 803
+#define IMG_CUSTOM_68 804
+#define IMG_CUSTOM_68_EDITOR 805
+#define IMG_CUSTOM_69 806
+#define IMG_CUSTOM_69_EDITOR 807
+#define IMG_CUSTOM_70 808
+#define IMG_CUSTOM_70_EDITOR 809
+#define IMG_CUSTOM_71 810
+#define IMG_CUSTOM_71_EDITOR 811
+#define IMG_CUSTOM_72 812
+#define IMG_CUSTOM_72_EDITOR 813
+#define IMG_CUSTOM_73 814
+#define IMG_CUSTOM_73_EDITOR 815
+#define IMG_CUSTOM_74 816
+#define IMG_CUSTOM_74_EDITOR 817
+#define IMG_CUSTOM_75 818
+#define IMG_CUSTOM_75_EDITOR 819
+#define IMG_CUSTOM_76 820
+#define IMG_CUSTOM_76_EDITOR 821
+#define IMG_CUSTOM_77 822
+#define IMG_CUSTOM_77_EDITOR 823
+#define IMG_CUSTOM_78 824
+#define IMG_CUSTOM_78_EDITOR 825
+#define IMG_CUSTOM_79 826
+#define IMG_CUSTOM_79_EDITOR 827
+#define IMG_CUSTOM_80 828
+#define IMG_CUSTOM_80_EDITOR 829
+#define IMG_CUSTOM_81 830
+#define IMG_CUSTOM_81_EDITOR 831
+#define IMG_CUSTOM_82 832
+#define IMG_CUSTOM_82_EDITOR 833
+#define IMG_CUSTOM_83 834
+#define IMG_CUSTOM_83_EDITOR 835
+#define IMG_CUSTOM_84 836
+#define IMG_CUSTOM_84_EDITOR 837
+#define IMG_CUSTOM_85 838
+#define IMG_CUSTOM_85_EDITOR 839
+#define IMG_CUSTOM_86 840
+#define IMG_CUSTOM_86_EDITOR 841
+#define IMG_CUSTOM_87 842
+#define IMG_CUSTOM_87_EDITOR 843
+#define IMG_CUSTOM_88 844
+#define IMG_CUSTOM_88_EDITOR 845
+#define IMG_CUSTOM_89 846
+#define IMG_CUSTOM_89_EDITOR 847
+#define IMG_CUSTOM_90 848
+#define IMG_CUSTOM_90_EDITOR 849
+#define IMG_CUSTOM_91 850
+#define IMG_CUSTOM_91_EDITOR 851
+#define IMG_CUSTOM_92 852
+#define IMG_CUSTOM_92_EDITOR 853
+#define IMG_CUSTOM_93 854
+#define IMG_CUSTOM_93_EDITOR 855
+#define IMG_CUSTOM_94 856
+#define IMG_CUSTOM_94_EDITOR 857
+#define IMG_CUSTOM_95 858
+#define IMG_CUSTOM_95_EDITOR 859
+#define IMG_CUSTOM_96 860
+#define IMG_CUSTOM_96_EDITOR 861
+#define IMG_CUSTOM_97 862
+#define IMG_CUSTOM_97_EDITOR 863
+#define IMG_CUSTOM_98 864
+#define IMG_CUSTOM_98_EDITOR 865
+#define IMG_CUSTOM_99 866
+#define IMG_CUSTOM_99_EDITOR 867
+#define IMG_CUSTOM_100 868
+#define IMG_CUSTOM_100_EDITOR 869
+#define IMG_CUSTOM_101 870
+#define IMG_CUSTOM_101_EDITOR 871
+#define IMG_CUSTOM_102 872
+#define IMG_CUSTOM_102_EDITOR 873
+#define IMG_CUSTOM_103 874
+#define IMG_CUSTOM_103_EDITOR 875
+#define IMG_CUSTOM_104 876
+#define IMG_CUSTOM_104_EDITOR 877
+#define IMG_CUSTOM_105 878
+#define IMG_CUSTOM_105_EDITOR 879
+#define IMG_CUSTOM_106 880
+#define IMG_CUSTOM_106_EDITOR 881
+#define IMG_CUSTOM_107 882
+#define IMG_CUSTOM_107_EDITOR 883
+#define IMG_CUSTOM_108 884
+#define IMG_CUSTOM_108_EDITOR 885
+#define IMG_CUSTOM_109 886
+#define IMG_CUSTOM_109_EDITOR 887
+#define IMG_CUSTOM_110 888
+#define IMG_CUSTOM_110_EDITOR 889
+#define IMG_CUSTOM_111 890
+#define IMG_CUSTOM_111_EDITOR 891
+#define IMG_CUSTOM_112 892
+#define IMG_CUSTOM_112_EDITOR 893
+#define IMG_CUSTOM_113 894
+#define IMG_CUSTOM_113_EDITOR 895
+#define IMG_CUSTOM_114 896
+#define IMG_CUSTOM_114_EDITOR 897
+#define IMG_CUSTOM_115 898
+#define IMG_CUSTOM_115_EDITOR 899
+#define IMG_CUSTOM_116 900
+#define IMG_CUSTOM_116_EDITOR 901
+#define IMG_CUSTOM_117 902
+#define IMG_CUSTOM_117_EDITOR 903
+#define IMG_CUSTOM_118 904
+#define IMG_CUSTOM_118_EDITOR 905
+#define IMG_CUSTOM_119 906
+#define IMG_CUSTOM_119_EDITOR 907
+#define IMG_CUSTOM_120 908
+#define IMG_CUSTOM_120_EDITOR 909
+#define IMG_CUSTOM_121 910
+#define IMG_CUSTOM_121_EDITOR 911
+#define IMG_CUSTOM_122 912
+#define IMG_CUSTOM_122_EDITOR 913
+#define IMG_CUSTOM_123 914
+#define IMG_CUSTOM_123_EDITOR 915
+#define IMG_CUSTOM_124 916
+#define IMG_CUSTOM_124_EDITOR 917
+#define IMG_CUSTOM_125 918
+#define IMG_CUSTOM_125_EDITOR 919
+#define IMG_CUSTOM_126 920
+#define IMG_CUSTOM_126_EDITOR 921
+#define IMG_CUSTOM_127 922
+#define IMG_CUSTOM_127_EDITOR 923
+#define IMG_CUSTOM_128 924
+#define IMG_CUSTOM_128_EDITOR 925
+#define IMG_TOON_1 926
+#define IMG_TOON_2 927
+#define IMG_TOON_3 928
+#define IMG_TOON_4 929
+#define IMG_TOON_5 930
+#define IMG_TOON_6 931
+#define IMG_TOON_7 932
+#define IMG_TOON_8 933
+#define IMG_TOON_9 934
+#define IMG_TOON_10 935
+#define IMG_TOON_11 936
+#define IMG_TOON_12 937
+#define IMG_TOON_13 938
+#define IMG_TOON_14 939
+#define IMG_TOON_15 940
+#define IMG_TOON_16 941
+#define IMG_TOON_17 942
+#define IMG_TOON_18 943
+#define IMG_TOON_19 944
+#define IMG_TOON_20 945
+#define IMG_MENU_CALIBRATE_RED 946
+#define IMG_MENU_CALIBRATE_BLUE 947
+#define IMG_MENU_CALIBRATE_YELLOW 948
+#define IMG_MENU_BUTTON 949
+#define IMG_MENU_BUTTON_ACTIVE 950
+#define IMG_MENU_BUTTON_LEFT 951
+#define IMG_MENU_BUTTON_RIGHT 952
+#define IMG_MENU_BUTTON_UP 953
+#define IMG_MENU_BUTTON_DOWN 954
+#define IMG_MENU_BUTTON_LEFT_ACTIVE 955
+#define IMG_MENU_BUTTON_RIGHT_ACTIVE 956
+#define IMG_MENU_BUTTON_UP_ACTIVE 957
+#define IMG_MENU_BUTTON_DOWN_ACTIVE 958
+#define IMG_MENU_SCROLLBAR 959
+#define IMG_MENU_SCROLLBAR_ACTIVE 960
+#define IMG_FONT_INITIAL_1 961
+#define IMG_FONT_INITIAL_2 962
+#define IMG_FONT_INITIAL_3 963
+#define IMG_FONT_INITIAL_4 964
+#define IMG_FONT_TITLE_1 965
+#define IMG_FONT_TITLE_1_LEVELS 966
+#define IMG_FONT_TITLE_2 967
+#define IMG_FONT_MENU_1 968
+#define IMG_FONT_MENU_2 969
+#define IMG_FONT_TEXT_1 970
+#define IMG_FONT_TEXT_1_LEVELS 971
+#define IMG_FONT_TEXT_1_PREVIEW 972
+#define IMG_FONT_TEXT_1_SCORES 973
+#define IMG_FONT_TEXT_1_ACTIVE_SCORES 974
+#define IMG_FONT_TEXT_2 975
+#define IMG_FONT_TEXT_2_LEVELS 976
+#define IMG_FONT_TEXT_2_PREVIEW 977
+#define IMG_FONT_TEXT_2_SCORES 978
+#define IMG_FONT_TEXT_2_ACTIVE_SCORES 979
+#define IMG_FONT_TEXT_3 980
+#define IMG_FONT_TEXT_3_LEVELS 981
+#define IMG_FONT_TEXT_3_PREVIEW 982
+#define IMG_FONT_TEXT_3_SCORES 983
+#define IMG_FONT_TEXT_3_ACTIVE_SCORES 984
+#define IMG_FONT_TEXT_4 985
+#define IMG_FONT_TEXT_4_LEVELS 986
+#define IMG_FONT_TEXT_4_SCORES 987
+#define IMG_FONT_TEXT_4_ACTIVE_SCORES 988
+#define IMG_FONT_INPUT_1 989
+#define IMG_FONT_INPUT_1_MAIN 990
+#define IMG_FONT_INPUT_1_ACTIVE 991
+#define IMG_FONT_INPUT_1_ACTIVE_MAIN 992
+#define IMG_FONT_INPUT_1_ACTIVE_SETUP 993
+#define IMG_FONT_INPUT_2 994
+#define IMG_FONT_INPUT_2_ACTIVE 995
+#define IMG_FONT_OPTION_OFF 996
+#define IMG_FONT_OPTION_ON 997
+#define IMG_FONT_VALUE_1 998
+#define IMG_FONT_VALUE_2 999
+#define IMG_FONT_VALUE_OLD 1000
+#define IMG_FONT_LEVEL_NUMBER 1001
+#define IMG_FONT_TAPE_RECORDER 1002
+#define IMG_FONT_GAME_INFO 1003
+#define IMG_GLOBAL_BORDER 1004
+#define IMG_GLOBAL_DOOR 1005
+#define IMG_EDITOR_ELEMENT_BORDER 1006
+#define IMG_EDITOR_ELEMENT_BORDER_INPUT 1007
+#define IMG_BACKGROUND 1008
+#define IMG_BACKGROUND_MAIN 1009
+#define IMG_BACKGROUND_LEVELS 1010
+#define IMG_BACKGROUND_SCORES 1011
+#define IMG_BACKGROUND_EDITOR 1012
+#define IMG_BACKGROUND_INFO 1013
+#define IMG_BACKGROUND_SETUP 1014
+#define IMG_BACKGROUND_DOOR 1015
+
+#define NUM_IMAGE_FILES 1016
+
+#endif /* CONF_GFX_H */
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* (c) 1995-2002 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* conf_snd.c *
+***********************************************************/
+
+#include "libgame/libgame.h"
+#include "main.h"
+
+
+/* List values that are not defined in the configuration file are set to
+ reliable default values. If that value is GFX_ARG_UNDEFINED, it will
+ be dynamically determined, using some of the other list values. */
+
+struct ConfigInfo sound_config_suffix[] =
+{
+ { ".mode_loop", ARG_UNDEFINED, TYPE_BOOLEAN },
+
+ { NULL, NULL, 0 }
+};
+
+struct ConfigInfo sound_config[] =
+{
+ /* some default sounds */
+ { "[default].digging", "schlurf.wav" },
+ { "[default].collecting", "pong.wav" },
+ { "[default].snapping", "pong.wav" },
+ { "[default].pushing", "pusch.wav" },
+ { "[default].impact", "klopf.wav" },
+ { "[default].walking", "empty.wav" },
+ { "[default].passing", "gate.wav" },
+ { "[default].dying", "autsch.wav" },
+ { "[default].exploding", "roaaar.wav" },
+ { "[sp_default].exploding", "booom.wav" },
+
+ /* sounds for Boulder Dash style elements and actions */
+ { "bd_diamond.collecting", "pong.wav" },
+ { "bd_diamond.impact", "pling.wav" },
+ { "bd_rock.pushing", "pusch.wav" },
+ { "bd_rock.impact", "klopf.wav" },
+ { "bd_magic_wall.activating", "quirk.wav" },
+ { "bd_magic_wall.active", "miep.wav" },
+ { "bd_magic_wall.filling", "quirk.wav" },
+ { "bd_amoeba.waiting", UNDEFINED_FILENAME },
+ { "bd_amoeba.growing", "amoebe.wav" },
+ { "bd_amoeba.turning_to_gem", "pling.wav" },
+ { "bd_amoeba.turning_to_rock", "klopf.wav" },
+ { "bd_butterfly.moving", "klapper.wav" },
+ { "bd_butterfly.waiting", "klapper.wav" },
+ { "bd_firefly.moving", "roehr.wav" },
+ { "bd_firefly.waiting", "roehr.wav" },
+
+ /* sounds for Supaplex style elements and actions */
+ { "sp_base.digging", "base.wav" },
+ { "sp_buggy_base.digging", "base.wav" },
+ { "sp_buggy_base.active", "bug.wav" },
+ { "sp_infotron.collecting", "infotron.wav" },
+ { "sp_infotron.impact", "pling.wav" },
+ { "sp_zonk.pushing", "zonkpush.wav" },
+ { "sp_zonk.impact", "zonkdown.wav" },
+ { "sp_disk_red.collecting", "infotron.wav" },
+ { "sp_disk_orange.pushing", "zonkpush.wav" },
+ { "sp_disk_yellow.pushing", "pusch.wav" },
+ { "[sp_port].passing", "gate.wav" },
+ { "[sp_exit].passing", "exit.wav" },
+ { "[sp_exit].opening", UNDEFINED_FILENAME },
+ { "sp_sniksnak.moving", UNDEFINED_FILENAME },
+ { "sp_sniksnak.waiting", UNDEFINED_FILENAME },
+ { "sp_electron.moving", UNDEFINED_FILENAME },
+ { "sp_electron.waiting", UNDEFINED_FILENAME },
+ { "sp_terminal.activating", UNDEFINED_FILENAME },
+ { "sp_terminal.active", UNDEFINED_FILENAME },
+
+ /* sounds for Sokoban style elements and actions */
+ { "[sokoban].pushing", "pusch.wav" },
+ { "[sokoban].filling", "deng.wav" },
+ { "[sokoban].emptying", UNDEFINED_FILENAME },
+
+ /* sounds for Emerald Mine style elements and actions */
+ { "[player].moving", "empty.wav" },
+ { "[player].moving.mode_loop", "false" },
+ { "sand.digging", "schlurf.wav" },
+ { "emerald.collecting", "pong.wav" },
+ { "emerald.impact", "pling.wav" },
+ { "diamond.collecting", "pong.wav" },
+ { "diamond.impact", "pling.wav" },
+ { "diamond.breaking", "quirk.wav" },
+ { "rock.pushing", "pusch.wav" },
+ { "rock.impact", "klopf.wav" },
+ { "bomb.pushing", "pusch.wav" },
+ { "nut.pushing", "knurk.wav" },
+ { "nut.breaking", "knack.wav" },
+ { "nut.impact", "klumpf.wav" },
+ { "[dynamite].collecting", "pong.wav" },
+ { "[dynamite].dropping", "deng.wav" },
+ { "[dynamite].active", "zisch.wav" },
+ { "[key].collecting", "pong.wav" },
+ { "[gate].passing", "gate.wav" },
+ { "bug.moving", "klapper.wav" },
+ { "bug.waiting", "klapper.wav" },
+ { "spaceship.moving", "roehr.wav" },
+ { "spaceship.waiting", "roehr.wav" },
+ { "yamyam.moving", UNDEFINED_FILENAME },
+ { "yamyam.waiting", "njam.wav" },
+ { "yamyam.digging", UNDEFINED_FILENAME },
+ { "robot.moving", "schlurf.wav" },
+ { "robot.moving.mode_loop", "false" },
+ { "robot.waiting", UNDEFINED_FILENAME },
+ { "robot_wheel.activating", "deng.wav" },
+ { "robot_wheel.active", "miep.wav" },
+ { "magic_wall.activating", "quirk.wav" },
+ { "magic_wall.active", "miep.wav" },
+ { "magic_wall.filling", "quirk.wav" },
+ { "[amoeba].waiting", UNDEFINED_FILENAME },
+ { "[amoeba].growing", "amoebe.wav" },
+ { "[amoeba].dropping", UNDEFINED_FILENAME },
+ { "acid.splashing", "blurb.wav" },
+ { "[quicksand].filling", UNDEFINED_FILENAME },
+ { "[quicksand].emptying", UNDEFINED_FILENAME },
+ { "[exit].opening", "oeffnen.wav" },
+ { "[exit].passing", "buing.wav" },
+ { "penguin.passing", "buing.wav" },
+
+ /* sounds for Emerald Mine Club style elements and actions */
+ { "balloon.moving", UNDEFINED_FILENAME },
+ { "balloon.waiting", UNDEFINED_FILENAME },
+ { "balloon.pushing", "schlurf.wav" },
+ { "[balloon_switch].activating", UNDEFINED_FILENAME },
+ { "spring.moving", UNDEFINED_FILENAME },
+ { "spring.pushing", "pusch.wav" },
+ { "spring.impact", "klopf.wav" },
+ { "[wall].growing", UNDEFINED_FILENAME },
+
+ /* sounds for Diamond Caves style elements and actions */
+ { "pearl.collecting", "pong.wav" },
+ { "pearl.breaking", "knack.wav" },
+ { "pearl.impact", "pling.wav" },
+ { "crystal.collecting", "pong.wav" },
+ { "crystal.impact", "pling.wav" },
+ { "envelope.collecting", "pong.wav" },
+ { "invisible_sand.digging", "schlurf.wav" },
+ { "shield_normal.collecting", "pong.wav" },
+ { "shield_normal.active", UNDEFINED_FILENAME },
+ { "shield_deadly.collecting", "pong.wav" },
+ { "shield_deadly.active", UNDEFINED_FILENAME },
+ { "extra_time.collecting", "gong.wav" },
+ { "mole.moving", UNDEFINED_FILENAME },
+ { "mole.waiting", UNDEFINED_FILENAME },
+ { "mole.digging", "blurb.wav" },
+ { "[switchgate_switch].activating", UNDEFINED_FILENAME },
+ { "[switchgate].opening", "oeffnen.wav" },
+ { "[switchgate].closing", "oeffnen.wav" },
+ { "[switchgate].passing", "gate.wav" },
+ { "timegate_switch.activating", "deng.wav" },
+ { "timegate_switch.active", "miep.wav" },
+ { "timegate_switch.deactivating", UNDEFINED_FILENAME },
+ { "timegate.opening", "oeffnen.wav" },
+ { "[timegate].closing", "oeffnen.wav" },
+ { "[timegate].passing", "gate.wav" },
+ { "[conveyor_belt_switch].activating",UNDEFINED_FILENAME },
+ { "[conveyor_belt].active", UNDEFINED_FILENAME },
+ { "[conveyor_belt_switch].deactivating",UNDEFINED_FILENAME },
+ { "light_switch.activating", UNDEFINED_FILENAME },
+ { "light_switch.deactivating", UNDEFINED_FILENAME },
+
+ /* sounds for DX Boulderdash style elements and actions */
+ { "dx_supabomb.pushing", "pusch.wav" },
+ { "trap.digging", "schlurf.wav" },
+ { "trap.activating", UNDEFINED_FILENAME },
+ { "[tube].walking", UNDEFINED_FILENAME },
+
+ /* sounds for Rocks'n'Diamonds style elements and actions */
+ { "amoeba.turning_to_gem", "pling.wav" },
+ { "amoeba.turning_to_rock", "klopf.wav" },
+ { "speed_pill.collecting", "pong.wav" },
+ { "dynabomb_increase_number.collecting","pong.wav" },
+ { "dynabomb_increase_size.collecting","pong.wav" },
+ { "dynabomb_increase_power.collecting","pong.wav" },
+ { "[dynabomb].dropping", "deng.wav" },
+ { "[dynabomb].active", "zisch.wav" },
+ { "satellite.moving", UNDEFINED_FILENAME },
+ { "satellite.waiting", UNDEFINED_FILENAME },
+ { "satellite.pushing", "pusch.wav" },
+ { "lamp.activating", "deng.wav" },
+ { "lamp.deactivating", "deng.wav" },
+ { "time_orb_full.collecting", "gong.wav" },
+ { "time_orb_full.impact", "deng.wav" },
+ { "time_orb_empty.pushing", "pusch.wav" },
+ { "time_orb_empty.impact", "deng.wav" },
+ { "game_of_life.waiting", UNDEFINED_FILENAME },
+ { "game_of_life.growing", "amoebe.wav" },
+ { "biomaze.waiting", UNDEFINED_FILENAME },
+ { "biomaze.growing", "amoebe.wav" },
+ { "pacman.moving", UNDEFINED_FILENAME },
+ { "pacman.waiting", UNDEFINED_FILENAME },
+ { "pacman.digging", UNDEFINED_FILENAME },
+ { "dark_yamyam.moving", UNDEFINED_FILENAME },
+ { "dark_yamyam.waiting", "njam.wav" },
+ { "dark_yamyam.digging", UNDEFINED_FILENAME },
+ { "penguin.moving", UNDEFINED_FILENAME },
+ { "penguin.waiting", UNDEFINED_FILENAME },
+ { "pig.moving", UNDEFINED_FILENAME },
+ { "pig.waiting", UNDEFINED_FILENAME },
+ { "pig.digging", UNDEFINED_FILENAME },
+ { "dragon.moving", UNDEFINED_FILENAME },
+ { "dragon.waiting", UNDEFINED_FILENAME },
+ { "dragon.attacking", UNDEFINED_FILENAME },
+
+ /* sounds not associated to game elements (used for menu screens etc.) */
+ /* keyword to stop parser: "NO_MORE_ELEMENT_SOUNDS" <-- do not change! */
+
+ /* sounds for other game actions */
+ { "game.starting", UNDEFINED_FILENAME },
+ { "game.running_out_of_time", "gong.wav" },
+ { "game.leveltime_bonus", "sirr.wav" },
+ { "game.losing", "lachen.wav" },
+ { "game.winning", UNDEFINED_FILENAME },
+ { "game.sokoban_solving", "buing.wav" },
+
+ /* sounds for other non-game actions */
+ { "door.opening", "oeffnen.wav" },
+ { "door.closing", "oeffnen.wav" },
+
+ { "background.SCORES", "halloffame.wav" },
+ { "background.SCORES.mode_loop", "false" },
+
+ { "background.INFO", "rhythmloop.wav" },
+ { "background.INFO.mode_loop", "true" },
+
+#if 0
+ { "[not used]", "antigrav.wav" },
+ { "[not used]", "bong.wav" },
+ { "[not used]", "fuel.wav" },
+ { "[not used]", "holz.wav" },
+ { "[not used]", "hui.wav" },
+ { "[not used]", "kabumm.wav" },
+ { "[not used]", "kink.wav" },
+ { "[not used]", "kling.wav" },
+ { "[not used]", "krach.wav" },
+ { "[not used]", "laser.wav" },
+ { "[not used]", "quiek.wav" },
+ { "[not used]", "rumms.wav" },
+ { "[not used]", "schlopp.wav" },
+ { "[not used]", "schrff.wav" },
+ { "[not used]", "schwirr.wav" },
+ { "[not used]", "slurp.wav" },
+ { "[not used]", "sproing.wav" },
+ { "[not used]", "warnton.wav" },
+ { "[not used]", "whoosh.wav" },
+ { "[not used]", "boom.wav" },
+#endif
+
+ { NULL, NULL }
+};
--- /dev/null
+/***********************************************************
+* Rocks'n'Diamonds -- McDuffin Strikes Back! *
+*----------------------------------------------------------*
+* (c) 1995-2002 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* conf_snd.h *
+***********************************************************/
+
+/* ----- this file was automatically generated -- do not edit by hand ----- */
+
+#ifndef CONF_SND_H
+#define CONF_SND_H
+
+/* values for sounds configuration */
+
+#define SND_CLASS_DEFAULT_DIGGING 0
+#define SND_CLASS_DEFAULT_COLLECTING 1
+#define SND_CLASS_DEFAULT_SNAPPING 2
+#define SND_CLASS_DEFAULT_PUSHING 3
+#define SND_CLASS_DEFAULT_IMPACT 4
+#define SND_CLASS_DEFAULT_WALKING 5
+#define SND_CLASS_DEFAULT_PASSING 6
+#define SND_CLASS_DEFAULT_DYING 7
+#define SND_CLASS_DEFAULT_EXPLODING 8
+#define SND_CLASS_SP_DEFAULT_EXPLODING 9
+#define SND_BD_DIAMOND_COLLECTING 10
+#define SND_BD_DIAMOND_IMPACT 11
+#define SND_BD_ROCK_PUSHING 12
+#define SND_BD_ROCK_IMPACT 13
+#define SND_BD_MAGIC_WALL_ACTIVATING 14
+#define SND_BD_MAGIC_WALL_ACTIVE 15
+#define SND_BD_MAGIC_WALL_FILLING 16
+#define SND_BD_AMOEBA_WAITING 17
+#define SND_BD_AMOEBA_GROWING 18
+#define SND_BD_AMOEBA_TURNING_TO_GEM 19
+#define SND_BD_AMOEBA_TURNING_TO_ROCK 20
+#define SND_BD_BUTTERFLY_MOVING 21
+#define SND_BD_BUTTERFLY_WAITING 22
+#define SND_BD_FIREFLY_MOVING 23
+#define SND_BD_FIREFLY_WAITING 24
+#define SND_SP_BASE_DIGGING 25
+#define SND_SP_BUGGY_BASE_DIGGING 26
+#define SND_SP_BUGGY_BASE_ACTIVE 27
+#define SND_SP_INFOTRON_COLLECTING 28
+#define SND_SP_INFOTRON_IMPACT 29
+#define SND_SP_ZONK_PUSHING 30
+#define SND_SP_ZONK_IMPACT 31
+#define SND_SP_DISK_RED_COLLECTING 32
+#define SND_SP_DISK_ORANGE_PUSHING 33
+#define SND_SP_DISK_YELLOW_PUSHING 34
+#define SND_CLASS_SP_PORT_PASSING 35
+#define SND_CLASS_SP_EXIT_PASSING 36
+#define SND_CLASS_SP_EXIT_OPENING 37
+#define SND_SP_SNIKSNAK_MOVING 38
+#define SND_SP_SNIKSNAK_WAITING 39
+#define SND_SP_ELECTRON_MOVING 40
+#define SND_SP_ELECTRON_WAITING 41
+#define SND_SP_TERMINAL_ACTIVATING 42
+#define SND_SP_TERMINAL_ACTIVE 43
+#define SND_CLASS_SOKOBAN_PUSHING 44
+#define SND_CLASS_SOKOBAN_FILLING 45
+#define SND_CLASS_SOKOBAN_EMPTYING 46
+#define SND_CLASS_PLAYER_MOVING 47
+#define SND_SAND_DIGGING 48
+#define SND_EMERALD_COLLECTING 49
+#define SND_EMERALD_IMPACT 50
+#define SND_DIAMOND_COLLECTING 51
+#define SND_DIAMOND_IMPACT 52
+#define SND_DIAMOND_BREAKING 53
+#define SND_ROCK_PUSHING 54
+#define SND_ROCK_IMPACT 55
+#define SND_BOMB_PUSHING 56
+#define SND_NUT_PUSHING 57
+#define SND_NUT_BREAKING 58
+#define SND_NUT_IMPACT 59
+#define SND_CLASS_DYNAMITE_COLLECTING 60
+#define SND_CLASS_DYNAMITE_DROPPING 61
+#define SND_CLASS_DYNAMITE_ACTIVE 62
+#define SND_CLASS_KEY_COLLECTING 63
+#define SND_CLASS_GATE_PASSING 64
+#define SND_BUG_MOVING 65
+#define SND_BUG_WAITING 66
+#define SND_SPACESHIP_MOVING 67
+#define SND_SPACESHIP_WAITING 68
+#define SND_YAMYAM_MOVING 69
+#define SND_YAMYAM_WAITING 70
+#define SND_YAMYAM_DIGGING 71
+#define SND_ROBOT_MOVING 72
+#define SND_ROBOT_WAITING 73
+#define SND_ROBOT_WHEEL_ACTIVATING 74
+#define SND_ROBOT_WHEEL_ACTIVE 75
+#define SND_MAGIC_WALL_ACTIVATING 76
+#define SND_MAGIC_WALL_ACTIVE 77
+#define SND_MAGIC_WALL_FILLING 78
+#define SND_CLASS_AMOEBA_WAITING 79
+#define SND_CLASS_AMOEBA_GROWING 80
+#define SND_CLASS_AMOEBA_DROPPING 81
+#define SND_ACID_SPLASHING 82
+#define SND_CLASS_QUICKSAND_FILLING 83
+#define SND_CLASS_QUICKSAND_EMPTYING 84
+#define SND_CLASS_EXIT_OPENING 85
+#define SND_CLASS_EXIT_PASSING 86
+#define SND_PENGUIN_PASSING 87
+#define SND_BALLOON_MOVING 88
+#define SND_BALLOON_WAITING 89
+#define SND_BALLOON_PUSHING 90
+#define SND_CLASS_BALLOON_SWITCH_ACTIVATING 91
+#define SND_SPRING_MOVING 92
+#define SND_SPRING_PUSHING 93
+#define SND_SPRING_IMPACT 94
+#define SND_CLASS_WALL_GROWING 95
+#define SND_PEARL_COLLECTING 96
+#define SND_PEARL_BREAKING 97
+#define SND_PEARL_IMPACT 98
+#define SND_CRYSTAL_COLLECTING 99
+#define SND_CRYSTAL_IMPACT 100
+#define SND_ENVELOPE_COLLECTING 101
+#define SND_INVISIBLE_SAND_DIGGING 102
+#define SND_SHIELD_NORMAL_COLLECTING 103
+#define SND_SHIELD_NORMAL_ACTIVE 104
+#define SND_SHIELD_DEADLY_COLLECTING 105
+#define SND_SHIELD_DEADLY_ACTIVE 106
+#define SND_EXTRA_TIME_COLLECTING 107
+#define SND_MOLE_MOVING 108
+#define SND_MOLE_WAITING 109
+#define SND_MOLE_DIGGING 110
+#define SND_CLASS_SWITCHGATE_SWITCH_ACTIVATING 111
+#define SND_CLASS_SWITCHGATE_OPENING 112
+#define SND_CLASS_SWITCHGATE_CLOSING 113
+#define SND_CLASS_SWITCHGATE_PASSING 114
+#define SND_TIMEGATE_SWITCH_ACTIVATING 115
+#define SND_TIMEGATE_SWITCH_ACTIVE 116
+#define SND_TIMEGATE_SWITCH_DEACTIVATING 117
+#define SND_TIMEGATE_OPENING 118
+#define SND_CLASS_TIMEGATE_CLOSING 119
+#define SND_CLASS_TIMEGATE_PASSING 120
+#define SND_CLASS_CONVEYOR_BELT_SWITCH_ACTIVATING 121
+#define SND_CLASS_CONVEYOR_BELT_ACTIVE 122
+#define SND_CLASS_CONVEYOR_BELT_SWITCH_DEACTIVATING 123
+#define SND_LIGHT_SWITCH_ACTIVATING 124
+#define SND_LIGHT_SWITCH_DEACTIVATING 125
+#define SND_DX_SUPABOMB_PUSHING 126
+#define SND_TRAP_DIGGING 127
+#define SND_TRAP_ACTIVATING 128
+#define SND_CLASS_TUBE_WALKING 129
+#define SND_AMOEBA_TURNING_TO_GEM 130
+#define SND_AMOEBA_TURNING_TO_ROCK 131
+#define SND_SPEED_PILL_COLLECTING 132
+#define SND_DYNABOMB_INCREASE_NUMBER_COLLECTING 133
+#define SND_DYNABOMB_INCREASE_SIZE_COLLECTING 134
+#define SND_DYNABOMB_INCREASE_POWER_COLLECTING 135
+#define SND_CLASS_DYNABOMB_DROPPING 136
+#define SND_CLASS_DYNABOMB_ACTIVE 137
+#define SND_SATELLITE_MOVING 138
+#define SND_SATELLITE_WAITING 139
+#define SND_SATELLITE_PUSHING 140
+#define SND_LAMP_ACTIVATING 141
+#define SND_LAMP_DEACTIVATING 142
+#define SND_TIME_ORB_FULL_COLLECTING 143
+#define SND_TIME_ORB_FULL_IMPACT 144
+#define SND_TIME_ORB_EMPTY_PUSHING 145
+#define SND_TIME_ORB_EMPTY_IMPACT 146
+#define SND_GAME_OF_LIFE_WAITING 147
+#define SND_GAME_OF_LIFE_GROWING 148
+#define SND_BIOMAZE_WAITING 149
+#define SND_BIOMAZE_GROWING 150
+#define SND_PACMAN_MOVING 151
+#define SND_PACMAN_WAITING 152
+#define SND_PACMAN_DIGGING 153
+#define SND_DARK_YAMYAM_MOVING 154
+#define SND_DARK_YAMYAM_WAITING 155
+#define SND_DARK_YAMYAM_DIGGING 156
+#define SND_PENGUIN_MOVING 157
+#define SND_PENGUIN_WAITING 158
+#define SND_PIG_MOVING 159
+#define SND_PIG_WAITING 160
+#define SND_PIG_DIGGING 161
+#define SND_DRAGON_MOVING 162
+#define SND_DRAGON_WAITING 163
+#define SND_DRAGON_ATTACKING 164
+#define SND_GAME_STARTING 165
+#define SND_GAME_RUNNING_OUT_OF_TIME 166
+#define SND_GAME_LEVELTIME_BONUS 167
+#define SND_GAME_LOSING 168
+#define SND_GAME_WINNING 169
+#define SND_GAME_SOKOBAN_SOLVING 170
+#define SND_DOOR_OPENING 171
+#define SND_DOOR_CLOSING 172
+#define SND_BACKGROUND_SCORES 173
+#define SND_BACKGROUND_INFO 174
+
+#define NUM_SOUND_FILES 175
+
+#endif /* CONF_SND_H */
-#define COMPILE_DATE_STRING "[2002-08-13 01:52]"
+#define COMPILE_DATE_STRING "[2003-08-05 01:57]"
#include "tools.h"
#include "files.h"
#include "game.h"
+#include "init.h"
#include "tape.h"
+
+/*
+ -----------------------------------------------------------------------------
+ screen and artwork graphic pixel position definitions
+ -----------------------------------------------------------------------------
+*/
+
/* positions in the level editor */
#define ED_WIN_MB_LEFT_XPOS 6
#define ED_WIN_MB_LEFT_YPOS 258
#define ED_WIN_MB_RIGHT_XPOS 78
#define ED_WIN_MB_RIGHT_YPOS ED_WIN_MB_LEFT_YPOS
-/* other constants for the editor */
-#define ED_SCROLL_NO 0
-#define ED_SCROLL_LEFT 1
-#define ED_SCROLL_RIGHT 2
-#define ED_SCROLL_UP 4
-#define ED_SCROLL_DOWN 8
-
-/* screens in the level editor */
-#define ED_MODE_DRAWING 0
-#define ED_MODE_INFO 1
-#define ED_MODE_PROPERTIES 2
-
-/* how many steps can be cancelled */
-#define NUM_UNDO_STEPS (10 + 1)
-
-/* values for elements with score */
-#define MIN_SCORE 0
-#define MAX_SCORE 255
-
/* values for the control window */
#define ED_CTRL_BUTTONS_GFX_YPOS 236
#define ED_CTRL_BUTTONS_ALT_GFX_YPOS 142
#define ED_NUM_ELEMENTLIST_BUTTONS (ED_ELEMENTLIST_BUTTONS_HORIZ * \
ED_ELEMENTLIST_BUTTONS_VERT)
+/* standard distances */
+#define ED_BORDER_SIZE 3
+#define ED_BORDER_TEXT_XSIZE 5
+#define ED_BORDER_AREA_YSIZE 1
+
+#define ED_GADGET_DISTANCE 2
+#define ED_GADGET_TEXT_DISTANCE (2 * ED_GADGET_DISTANCE)
+
/* values for the setting windows */
-#define ED_SETTINGS_XPOS (MINI_TILEX + 8)
+#define ED_SETTINGS_XSTART (3 * MINI_TILEX / 2)
+#define ED_SETTINGS_YSTART (MINI_TILEY * 10)
+
+#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 + \
+ n * ED_SETTINGS_XOFFSET)
+#define ED_SETTINGS_YPOS(n) (ED_SETTINGS_YSTART + \
+ n * ED_SETTINGS_YOFFSET)
+
+#define ED_SETTINGS1_YPOS MINI_TILEY
#define ED_SETTINGS2_XPOS MINI_TILEX
-#define ED_SETTINGS_YPOS MINI_TILEY
-#define ED_SETTINGS2_YPOS (ED_SETTINGS_YPOS + 12 * TILEY - 2)
+#define ED_SETTINGS2_YPOS (ED_SETTINGS1_YPOS + 12 * TILEY - 2)
/* values for counter gadgets */
-#define ED_COUNT_ELEM_SCORE_XPOS ED_SETTINGS_XPOS
-#define ED_COUNT_ELEM_SCORE_YPOS (14 * MINI_TILEY)
-#define ED_COUNT_ELEM_CONTENT_XPOS ED_SETTINGS_XPOS
-#define ED_COUNT_ELEM_CONTENT_YPOS (19 * MINI_TILEY)
+#define ED_COUNT_PUSH_DELAY_RND_XPOS (ED_SETTINGS_XPOS(1) + 16 * MINI_TILEX)
+#define ED_COUNT_MOVE_DELAY_RND_XPOS ED_COUNT_PUSH_DELAY_RND_XPOS
+#define ED_COUNT_CHANGE_DELAY_RND_XPOS (ED_SETTINGS_XPOS(1) + 13 * MINI_TILEX)
-#define ED_COUNTER_YSTART (ED_SETTINGS_YPOS + 2 * TILEY)
+#define ED_COUNTER_YSTART (ED_SETTINGS1_YPOS + 2 * TILEY)
#define ED_COUNTER_YDISTANCE (3 * MINI_TILEY)
#define ED_COUNTER_YPOS(n) (ED_COUNTER_YSTART + \
n * ED_COUNTER_YDISTANCE)
#define ED_COUNTER2_YPOS(n) (ED_COUNTER_YSTART + \
n * ED_COUNTER_YDISTANCE - 2)
-/* standard distances */
-#define ED_BORDER_SIZE 3
-#define ED_GADGET_DISTANCE 2
/* values for element content drawing areas */
+/* amoeba content */
#define ED_AREA_ELEM_CONTENT_XPOS ( 2 * MINI_TILEX)
#define ED_AREA_ELEM_CONTENT_YPOS (22 * MINI_TILEY)
+/* yamyam content */
+#define ED_AREA_YAMYAM_CONTENT_XPOS(n) (ED_AREA_ELEM_CONTENT_XPOS + \
+ 5 * (n % 4) * MINI_TILEX)
+#define ED_AREA_YAMYAM_CONTENT_YPOS(n) (ED_AREA_ELEM_CONTENT_YPOS + \
+ 6 * (n / 4) * MINI_TILEY)
+
+/* custom change target */
+#define ED_AREA_ELEM_CONTENT2_XPOS (20 * MINI_TILEX)
+#define ED_AREA_ELEM_CONTENT2_YPOS (ED_SETTINGS_YPOS(2) + \
+ ED_GADGET_DISTANCE)
+/* optional custom graphic */
+#define ED_AREA_ELEM_CONTENT3_XPOS (24 * MINI_TILEX)
+#define ED_AREA_ELEM_CONTENT3_YPOS (ED_SETTINGS_YPOS(1) + \
+ ED_GADGET_DISTANCE)
+/* custom element content */
+#define ED_AREA_ELEM_CONTENT4_XPOS (29 * MINI_TILEX)
+#define ED_AREA_ELEM_CONTENT4_YPOS (ED_SETTINGS_YPOS(12) + \
+ ED_GADGET_DISTANCE - MINI_TILEY)
+/* custom change trigger element */
+#define ED_AREA_ELEM_CONTENT5_XPOS (28 * MINI_TILEX)
+#define ED_AREA_ELEM_CONTENT5_YPOS (ED_SETTINGS_YPOS(7) + \
+ ED_GADGET_DISTANCE)
+/* extended custom change target */
+#define ED_AREA_ELEM_CONTENT6_XPOS (29 * MINI_TILEX)
+#define ED_AREA_ELEM_CONTENT6_YPOS (ED_SETTINGS_YPOS(10) + \
+ ED_GADGET_DISTANCE - MINI_TILEY)
+
/* values for random placement background drawing area */
#define ED_AREA_RANDOM_BACKGROUND_XPOS (29 * MINI_TILEX)
#define ED_AREA_RANDOM_BACKGROUND_YPOS (31 * MINI_TILEY)
#define ED_STICKYBUTTON_YPOS (ED_BUTTON_MINUS_YPOS + 66)
/* some positions in the editor control window */
-#define ED_BUTTON_ELEM_XPOS 6
-#define ED_BUTTON_ELEM_YPOS 30
-#define ED_BUTTON_ELEM_XSIZE 22
-#define ED_BUTTON_ELEM_YSIZE 22
-
-/* some values for text input and counter gadgets */
-#define ED_BUTTON_COUNT_YPOS 60
-#define ED_BUTTON_COUNT_XSIZE 20
-#define ED_BUTTON_COUNT_YSIZE 20
-#define ED_WIN_COUNT_XPOS (2 + ED_BUTTON_COUNT_XSIZE + 2)
-#define ED_WIN_COUNT_YPOS ED_BUTTON_COUNT_YPOS
-#define ED_WIN_COUNT_XSIZE 52
-#define ED_WIN_COUNT_YSIZE ED_BUTTON_COUNT_YSIZE
-#define ED_WIN_COUNT2_XPOS 27
-#define ED_WIN_COUNT2_YPOS 3
-#define ED_WIN_COUNT2_XSIZE 46
-#define ED_WIN_COUNT2_YSIZE ED_BUTTON_COUNT_YSIZE
-
-#define ED_BUTTON_MINUS_XPOS 2
-#define ED_BUTTON_MINUS_YPOS ED_BUTTON_COUNT_YPOS
-#define ED_BUTTON_MINUS_XSIZE ED_BUTTON_COUNT_XSIZE
-#define ED_BUTTON_MINUS_YSIZE ED_BUTTON_COUNT_YSIZE
-#define ED_BUTTON_PLUS_XPOS (ED_WIN_COUNT_XPOS + ED_WIN_COUNT_XSIZE + 2)
-#define ED_BUTTON_PLUS_YPOS ED_BUTTON_COUNT_YPOS
-#define ED_BUTTON_PLUS_XSIZE ED_BUTTON_COUNT_XSIZE
-#define ED_BUTTON_PLUS_YSIZE ED_BUTTON_COUNT_YSIZE
-
-/* editor gadget identifiers */
+#define ED_BUTTON_ELEM_XPOS 6
+#define ED_BUTTON_ELEM_YPOS 30
+#define ED_BUTTON_ELEM_XSIZE 22
+#define ED_BUTTON_ELEM_YSIZE 22
+
+/* some values for text input, selectbox and counter gadgets */
+#define ED_BUTTON_COUNT_YPOS 60
+#define ED_BUTTON_COUNT_XSIZE 20
+#define ED_BUTTON_COUNT_YSIZE 20
+#define ED_WIN_COUNT_XPOS (2 + ED_BUTTON_COUNT_XSIZE + 2)
+#define ED_WIN_COUNT_YPOS ED_BUTTON_COUNT_YPOS
+#define ED_WIN_COUNT_XSIZE 52
+#define ED_WIN_COUNT_YSIZE ED_BUTTON_COUNT_YSIZE
+#define ED_WIN_COUNT2_XPOS 27
+#define ED_WIN_COUNT2_YPOS 3
+#define ED_WIN_COUNT2_XSIZE 46
+#define ED_WIN_COUNT2_YSIZE ED_BUTTON_COUNT_YSIZE
+
+#define ED_BUTTON_MINUS_XPOS 2
+#define ED_BUTTON_MINUS_YPOS ED_BUTTON_COUNT_YPOS
+#define ED_BUTTON_MINUS_XSIZE ED_BUTTON_COUNT_XSIZE
+#define ED_BUTTON_MINUS_YSIZE ED_BUTTON_COUNT_YSIZE
+#define ED_BUTTON_PLUS_XPOS (ED_WIN_COUNT_XPOS + \
+ ED_WIN_COUNT_XSIZE + 2)
+#define ED_BUTTON_PLUS_YPOS ED_BUTTON_COUNT_YPOS
+#define ED_BUTTON_PLUS_XSIZE ED_BUTTON_COUNT_XSIZE
+#define ED_BUTTON_PLUS_YSIZE ED_BUTTON_COUNT_YSIZE
+
+#define ED_SELECTBOX_XPOS ED_WIN_COUNT_XPOS
+#define ED_SELECTBOX_YPOS (ED_WIN_COUNT_YPOS + \
+ 2 + ED_WIN_COUNT_YSIZE)
+#define ED_SELECTBOX_XSIZE ED_WIN_COUNT_XSIZE
+#define ED_SELECTBOX_YSIZE ED_WIN_COUNT_YSIZE
+
+#define ED_SELECTBOX_BUTTON_XSIZE 14
+
+#define ED_TEXTBUTTON_XPOS ED_WIN_COUNT_XPOS
+#define ED_TEXTBUTTON_YPOS (ED_WIN_COUNT_YPOS + \
+ 4 * (2 + ED_WIN_COUNT_YSIZE))
+#define ED_TEXTBUTTON_INACTIVE_YPOS ED_TEXTBUTTON_YPOS
+
+#define ED_TEXTBUTTON_TAB_XPOS ED_WIN_COUNT_XPOS
+#define ED_TEXTBUTTON_TAB_YPOS (ED_WIN_COUNT_YPOS + \
+ 2 * (2 + ED_WIN_COUNT_YSIZE))
+#define ED_TEXTBUTTON_TAB_INACTIVE_YPOS (ED_WIN_COUNT_YPOS + \
+ 3 * (2 + ED_WIN_COUNT_YSIZE))
+
+#define ED_TEXTBUTTON_XSIZE ED_WIN_COUNT_XSIZE
+#define ED_TEXTBUTTON_YSIZE ED_WIN_COUNT_YSIZE
+
+/* values for ClearEditorGadgetInfoText() and HandleGadgetInfoText() */
+#define INFOTEXT_XPOS SX
+#define INFOTEXT_YPOS (SY + SYSIZE - MINI_TILEX + 2)
+#define INFOTEXT_XSIZE SXSIZE
+#define INFOTEXT_YSIZE MINI_TILEX
+
+
+/*
+ -----------------------------------------------------------------------------
+ editor gadget definitions
+ -----------------------------------------------------------------------------
+*/
/* drawing toolbox buttons */
#define GADGET_ID_NONE -1
-#define GADGET_ID_SINGLE_ITEMS 0
-#define GADGET_ID_CONNECTED_ITEMS 1
-#define GADGET_ID_LINE 2
-#define GADGET_ID_ARC 3
-#define GADGET_ID_RECTANGLE 4
-#define GADGET_ID_FILLED_BOX 5
-#define GADGET_ID_WRAP_UP 6
-#define GADGET_ID_TEXT 7
-#define GADGET_ID_FLOOD_FILL 8
-#define GADGET_ID_WRAP_LEFT 9
-#define GADGET_ID_PROPERTIES 10
-#define GADGET_ID_WRAP_RIGHT 11
-#define GADGET_ID_RANDOM_PLACEMENT 12
-#define GADGET_ID_GRAB_BRUSH 13
-#define GADGET_ID_WRAP_DOWN 14
-#define GADGET_ID_PICK_ELEMENT 15
-#define GADGET_ID_UNDO 16
-#define GADGET_ID_INFO 17
-#define GADGET_ID_SAVE 18
-#define GADGET_ID_CLEAR 19
-#define GADGET_ID_TEST 20
-#define GADGET_ID_EXIT 21
+#define GADGET_ID_TOOLBOX_FIRST 0
+
+#define GADGET_ID_SINGLE_ITEMS (GADGET_ID_TOOLBOX_FIRST + 0)
+#define GADGET_ID_CONNECTED_ITEMS (GADGET_ID_TOOLBOX_FIRST + 1)
+#define GADGET_ID_LINE (GADGET_ID_TOOLBOX_FIRST + 2)
+#define GADGET_ID_ARC (GADGET_ID_TOOLBOX_FIRST + 3)
+#define GADGET_ID_RECTANGLE (GADGET_ID_TOOLBOX_FIRST + 4)
+#define GADGET_ID_FILLED_BOX (GADGET_ID_TOOLBOX_FIRST + 5)
+#define GADGET_ID_WRAP_UP (GADGET_ID_TOOLBOX_FIRST + 6)
+#define GADGET_ID_TEXT (GADGET_ID_TOOLBOX_FIRST + 7)
+#define GADGET_ID_FLOOD_FILL (GADGET_ID_TOOLBOX_FIRST + 8)
+#define GADGET_ID_WRAP_LEFT (GADGET_ID_TOOLBOX_FIRST + 9)
+#define GADGET_ID_PROPERTIES (GADGET_ID_TOOLBOX_FIRST + 10)
+#define GADGET_ID_WRAP_RIGHT (GADGET_ID_TOOLBOX_FIRST + 11)
+#define GADGET_ID_RANDOM_PLACEMENT (GADGET_ID_TOOLBOX_FIRST + 12)
+#define GADGET_ID_GRAB_BRUSH (GADGET_ID_TOOLBOX_FIRST + 13)
+#define GADGET_ID_WRAP_DOWN (GADGET_ID_TOOLBOX_FIRST + 14)
+#define GADGET_ID_PICK_ELEMENT (GADGET_ID_TOOLBOX_FIRST + 15)
+#define GADGET_ID_UNDO (GADGET_ID_TOOLBOX_FIRST + 16)
+#define GADGET_ID_INFO (GADGET_ID_TOOLBOX_FIRST + 17)
+#define GADGET_ID_SAVE (GADGET_ID_TOOLBOX_FIRST + 18)
+#define GADGET_ID_CLEAR (GADGET_ID_TOOLBOX_FIRST + 19)
+#define GADGET_ID_TEST (GADGET_ID_TOOLBOX_FIRST + 20)
+#define GADGET_ID_EXIT (GADGET_ID_TOOLBOX_FIRST + 21)
/* counter button identifiers */
-#define GADGET_ID_ELEM_SCORE_DOWN 22
-#define GADGET_ID_ELEM_SCORE_TEXT 23
-#define GADGET_ID_ELEM_SCORE_UP 24
-#define GADGET_ID_ELEM_CONTENT_DOWN 25
-#define GADGET_ID_ELEM_CONTENT_TEXT 26
-#define GADGET_ID_ELEM_CONTENT_UP 27
-#define GADGET_ID_LEVEL_XSIZE_DOWN 28
-#define GADGET_ID_LEVEL_XSIZE_TEXT 29
-#define GADGET_ID_LEVEL_XSIZE_UP 30
-#define GADGET_ID_LEVEL_YSIZE_DOWN 31
-#define GADGET_ID_LEVEL_YSIZE_TEXT 32
-#define GADGET_ID_LEVEL_YSIZE_UP 33
-#define GADGET_ID_LEVEL_RANDOM_DOWN 34
-#define GADGET_ID_LEVEL_RANDOM_TEXT 35
-#define GADGET_ID_LEVEL_RANDOM_UP 36
-#define GADGET_ID_LEVEL_COLLECT_DOWN 37
-#define GADGET_ID_LEVEL_COLLECT_TEXT 38
-#define GADGET_ID_LEVEL_COLLECT_UP 39
-#define GADGET_ID_LEVEL_TIMELIMIT_DOWN 40
-#define GADGET_ID_LEVEL_TIMELIMIT_TEXT 41
-#define GADGET_ID_LEVEL_TIMELIMIT_UP 42
-#define GADGET_ID_LEVEL_TIMESCORE_DOWN 43
-#define GADGET_ID_LEVEL_TIMESCORE_TEXT 44
-#define GADGET_ID_LEVEL_TIMESCORE_UP 45
-#define GADGET_ID_SELECT_LEVEL_DOWN 46
-#define GADGET_ID_SELECT_LEVEL_TEXT 47
-#define GADGET_ID_SELECT_LEVEL_UP 48
+#define GADGET_ID_COUNTER_FIRST (GADGET_ID_TOOLBOX_FIRST + 22)
+
+#define GADGET_ID_SELECT_LEVEL_DOWN (GADGET_ID_COUNTER_FIRST + 0)
+#define GADGET_ID_SELECT_LEVEL_TEXT (GADGET_ID_COUNTER_FIRST + 1)
+#define GADGET_ID_SELECT_LEVEL_UP (GADGET_ID_COUNTER_FIRST + 2)
+#define GADGET_ID_LEVEL_XSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 3)
+#define GADGET_ID_LEVEL_XSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 4)
+#define GADGET_ID_LEVEL_XSIZE_UP (GADGET_ID_COUNTER_FIRST + 5)
+#define GADGET_ID_LEVEL_YSIZE_DOWN (GADGET_ID_COUNTER_FIRST + 6)
+#define GADGET_ID_LEVEL_YSIZE_TEXT (GADGET_ID_COUNTER_FIRST + 7)
+#define GADGET_ID_LEVEL_YSIZE_UP (GADGET_ID_COUNTER_FIRST + 8)
+#define GADGET_ID_LEVEL_RANDOM_DOWN (GADGET_ID_COUNTER_FIRST + 9)
+#define GADGET_ID_LEVEL_RANDOM_TEXT (GADGET_ID_COUNTER_FIRST + 10)
+#define GADGET_ID_LEVEL_RANDOM_UP (GADGET_ID_COUNTER_FIRST + 11)
+#define GADGET_ID_LEVEL_GEMSLIMIT_DOWN (GADGET_ID_COUNTER_FIRST + 12)
+#define GADGET_ID_LEVEL_GEMSLIMIT_TEXT (GADGET_ID_COUNTER_FIRST + 13)
+#define GADGET_ID_LEVEL_GEMSLIMIT_UP (GADGET_ID_COUNTER_FIRST + 14)
+#define GADGET_ID_LEVEL_TIMELIMIT_DOWN (GADGET_ID_COUNTER_FIRST + 15)
+#define GADGET_ID_LEVEL_TIMELIMIT_TEXT (GADGET_ID_COUNTER_FIRST + 16)
+#define GADGET_ID_LEVEL_TIMELIMIT_UP (GADGET_ID_COUNTER_FIRST + 17)
+#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_CUSTOM_SCORE_DOWN (GADGET_ID_COUNTER_FIRST + 27)
+#define GADGET_ID_CUSTOM_SCORE_TEXT (GADGET_ID_COUNTER_FIRST + 28)
+#define GADGET_ID_CUSTOM_SCORE_UP (GADGET_ID_COUNTER_FIRST + 29)
+#define GADGET_ID_CUSTOM_GEMCOUNT_DOWN (GADGET_ID_COUNTER_FIRST + 30)
+#define GADGET_ID_CUSTOM_GEMCOUNT_TEXT (GADGET_ID_COUNTER_FIRST + 31)
+#define GADGET_ID_CUSTOM_GEMCOUNT_UP (GADGET_ID_COUNTER_FIRST + 32)
+#define GADGET_ID_PUSH_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 33)
+#define GADGET_ID_PUSH_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 34)
+#define GADGET_ID_PUSH_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 35)
+#define GADGET_ID_PUSH_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 36)
+#define GADGET_ID_PUSH_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 37)
+#define GADGET_ID_PUSH_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 38)
+#define GADGET_ID_MOVE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 39)
+#define GADGET_ID_MOVE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 40)
+#define GADGET_ID_MOVE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 41)
+#define GADGET_ID_MOVE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 42)
+#define GADGET_ID_MOVE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 43)
+#define GADGET_ID_MOVE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 44)
+#define GADGET_ID_CHANGE_DELAY_FIX_DOWN (GADGET_ID_COUNTER_FIRST + 45)
+#define GADGET_ID_CHANGE_DELAY_FIX_TEXT (GADGET_ID_COUNTER_FIRST + 46)
+#define GADGET_ID_CHANGE_DELAY_FIX_UP (GADGET_ID_COUNTER_FIRST + 47)
+#define GADGET_ID_CHANGE_DELAY_RND_DOWN (GADGET_ID_COUNTER_FIRST + 48)
+#define GADGET_ID_CHANGE_DELAY_RND_TEXT (GADGET_ID_COUNTER_FIRST + 49)
+#define GADGET_ID_CHANGE_DELAY_RND_UP (GADGET_ID_COUNTER_FIRST + 50)
+#define GADGET_ID_CHANGE_CONT_RND_DOWN (GADGET_ID_COUNTER_FIRST + 51)
+#define GADGET_ID_CHANGE_CONT_RND_TEXT (GADGET_ID_COUNTER_FIRST + 52)
+#define GADGET_ID_CHANGE_CONT_RND_UP (GADGET_ID_COUNTER_FIRST + 53)
/* drawing area identifiers */
-#define GADGET_ID_DRAWING_LEVEL 49
-#define GADGET_ID_ELEM_CONTENT_0 50
-#define GADGET_ID_ELEM_CONTENT_1 51
-#define GADGET_ID_ELEM_CONTENT_2 52
-#define GADGET_ID_ELEM_CONTENT_3 53
-#define GADGET_ID_ELEM_CONTENT_4 54
-#define GADGET_ID_ELEM_CONTENT_5 55
-#define GADGET_ID_ELEM_CONTENT_6 56
-#define GADGET_ID_ELEM_CONTENT_7 57
-#define GADGET_ID_AMOEBA_CONTENT 58
+#define GADGET_ID_DRAWING_AREA_FIRST (GADGET_ID_COUNTER_FIRST + 54)
+
+#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_CHANGE_TARGET (GADGET_ID_DRAWING_AREA_FIRST + 12)
+#define GADGET_ID_CUSTOM_CHANGE_CONTENT (GADGET_ID_DRAWING_AREA_FIRST + 13)
+#define GADGET_ID_CUSTOM_CHANGE_TRIGGER (GADGET_ID_DRAWING_AREA_FIRST + 14)
+#define GADGET_ID_RANDOM_BACKGROUND (GADGET_ID_DRAWING_AREA_FIRST + 15)
/* text input identifiers */
-#define GADGET_ID_LEVEL_NAME 59
-#define GADGET_ID_LEVEL_AUTHOR 60
+#define GADGET_ID_TEXT_INPUT_FIRST (GADGET_ID_DRAWING_AREA_FIRST + 16)
+
+#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_ELEMENT_NAME (GADGET_ID_TEXT_INPUT_FIRST + 2)
+
+/* selectbox identifiers */
+#define GADGET_ID_SELECTBOX_FIRST (GADGET_ID_TEXT_INPUT_FIRST + 3)
+
+#define GADGET_ID_CUSTOM_WALK_TO_ACTION (GADGET_ID_SELECTBOX_FIRST + 0)
+#define GADGET_ID_CUSTOM_CONSISTENCY (GADGET_ID_SELECTBOX_FIRST + 1)
+#define GADGET_ID_CUSTOM_DEADLINESS (GADGET_ID_SELECTBOX_FIRST + 2)
+#define GADGET_ID_CUSTOM_MOVE_PATTERN (GADGET_ID_SELECTBOX_FIRST + 3)
+#define GADGET_ID_CUSTOM_MOVE_DIRECTION (GADGET_ID_SELECTBOX_FIRST + 4)
+#define GADGET_ID_CUSTOM_MOVE_STEPSIZE (GADGET_ID_SELECTBOX_FIRST + 5)
+#define GADGET_ID_CUSTOM_SMASH_TARGETS (GADGET_ID_SELECTBOX_FIRST + 6)
+#define GADGET_ID_CUSTOM_SLIPPERY_TYPE (GADGET_ID_SELECTBOX_FIRST + 7)
+#define GADGET_ID_CUSTOM_ACCESS_TYPE (GADGET_ID_SELECTBOX_FIRST + 8)
+#define GADGET_ID_CUSTOM_ACCESS_LAYER (GADGET_ID_SELECTBOX_FIRST + 9)
+#define GADGET_ID_CHANGE_TIME_UNITS (GADGET_ID_SELECTBOX_FIRST + 10)
+#define GADGET_ID_CHANGE_PLAYER_ACTION (GADGET_ID_SELECTBOX_FIRST + 11)
+#define GADGET_ID_CHANGE_COLLIDE_ACTION (GADGET_ID_SELECTBOX_FIRST + 12)
+#define GADGET_ID_CHANGE_OTHER_ACTION (GADGET_ID_SELECTBOX_FIRST + 13)
+#define GADGET_ID_CHANGE_POWER (GADGET_ID_SELECTBOX_FIRST + 14)
+
+/* textbutton identifiers */
+#define GADGET_ID_TEXTBUTTON_FIRST (GADGET_ID_SELECTBOX_FIRST + 15)
+
+#define GADGET_ID_PROPERTIES_INFO (GADGET_ID_TEXTBUTTON_FIRST + 0)
+#define GADGET_ID_PROPERTIES_CONFIG (GADGET_ID_TEXTBUTTON_FIRST + 1)
+#define GADGET_ID_PROPERTIES_ADVANCED (GADGET_ID_TEXTBUTTON_FIRST + 2)
+#define GADGET_ID_SAVE_AS_TEMPLATE (GADGET_ID_TEXTBUTTON_FIRST + 3)
/* gadgets for scrolling of drawing area */
-#define GADGET_ID_SCROLL_UP 61
-#define GADGET_ID_SCROLL_DOWN 62
-#define GADGET_ID_SCROLL_LEFT 63
-#define GADGET_ID_SCROLL_RIGHT 64
-#define GADGET_ID_SCROLL_HORIZONTAL 65
-#define GADGET_ID_SCROLL_VERTICAL 66
+#define GADGET_ID_SCROLLING_FIRST (GADGET_ID_TEXTBUTTON_FIRST + 4)
+
+#define GADGET_ID_SCROLL_UP (GADGET_ID_SCROLLING_FIRST + 0)
+#define GADGET_ID_SCROLL_DOWN (GADGET_ID_SCROLLING_FIRST + 1)
+#define GADGET_ID_SCROLL_LEFT (GADGET_ID_SCROLLING_FIRST + 2)
+#define GADGET_ID_SCROLL_RIGHT (GADGET_ID_SCROLLING_FIRST + 3)
+#define GADGET_ID_SCROLL_HORIZONTAL (GADGET_ID_SCROLLING_FIRST + 4)
+#define GADGET_ID_SCROLL_VERTICAL (GADGET_ID_SCROLLING_FIRST + 5)
/* gadgets for scrolling element list */
-#define GADGET_ID_SCROLL_LIST_UP 67
-#define GADGET_ID_SCROLL_LIST_DOWN 68
-#define GADGET_ID_SCROLL_LIST_VERTICAL 69
-
-/* buttons for level settings */
-#define GADGET_ID_RANDOM_PERCENTAGE 70
-#define GADGET_ID_RANDOM_QUANTITY 71
-#define GADGET_ID_RANDOM_RESTRICTED 72
-#define GADGET_ID_DOUBLE_SPEED 73
-#define GADGET_ID_GRAVITY 74
-#define GADGET_ID_STICK_ELEMENT 75
-#define GADGET_ID_EM_SLIPPERY_GEMS 76
-
-/* another drawing area for random placement */
-#define GADGET_ID_RANDOM_BACKGROUND 77
+#define GADGET_ID_SCROLLING_LIST_FIRST (GADGET_ID_SCROLLING_FIRST + 6)
+
+#define GADGET_ID_SCROLL_LIST_UP (GADGET_ID_SCROLLING_LIST_FIRST + 0)
+#define GADGET_ID_SCROLL_LIST_DOWN (GADGET_ID_SCROLLING_LIST_FIRST + 1)
+#define GADGET_ID_SCROLL_LIST_VERTICAL (GADGET_ID_SCROLLING_LIST_FIRST + 2)
+
+/* checkbuttons for level/element properties */
+#define GADGET_ID_CHECKBUTTON_FIRST (GADGET_ID_SCROLLING_LIST_FIRST + 3)
+
+#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_CUSTOM_EXPLODE_RESULT (GADGET_ID_CHECKBUTTON_FIRST + 7)
+#define GADGET_ID_CUSTOM_EXPLODE_FIRE (GADGET_ID_CHECKBUTTON_FIRST + 8)
+#define GADGET_ID_CUSTOM_EXPLODE_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 9)
+#define GADGET_ID_CUSTOM_EXPLODE_IMPACT (GADGET_ID_CHECKBUTTON_FIRST + 10)
+#define GADGET_ID_CUSTOM_WALK_TO_OBJECT (GADGET_ID_CHECKBUTTON_FIRST + 11)
+#define GADGET_ID_CUSTOM_DEADLY (GADGET_ID_CHECKBUTTON_FIRST + 12)
+#define GADGET_ID_CUSTOM_CAN_MOVE (GADGET_ID_CHECKBUTTON_FIRST + 13)
+#define GADGET_ID_CUSTOM_CAN_FALL (GADGET_ID_CHECKBUTTON_FIRST + 14)
+#define GADGET_ID_CUSTOM_CAN_SMASH (GADGET_ID_CHECKBUTTON_FIRST + 15)
+#define GADGET_ID_CUSTOM_SLIPPERY (GADGET_ID_CHECKBUTTON_FIRST + 16)
+#define GADGET_ID_CUSTOM_ACCESSIBLE (GADGET_ID_CHECKBUTTON_FIRST + 17)
+#define GADGET_ID_CUSTOM_USE_GRAPHIC (GADGET_ID_CHECKBUTTON_FIRST + 18)
+#define GADGET_ID_CUSTOM_USE_TEMPLATE (GADGET_ID_CHECKBUTTON_FIRST + 19)
+#define GADGET_ID_CUSTOM_CAN_CHANGE (GADGET_ID_CHECKBUTTON_FIRST + 20)
+#define GADGET_ID_CHANGE_USE_CONTENT (GADGET_ID_CHECKBUTTON_FIRST + 21)
+#define GADGET_ID_CHANGE_USE_EXPLOSION (GADGET_ID_CHECKBUTTON_FIRST + 22)
+#define GADGET_ID_CHANGE_ONLY_COMPLETE (GADGET_ID_CHECKBUTTON_FIRST + 23)
+#define GADGET_ID_CHANGE_USE_RANDOM (GADGET_ID_CHECKBUTTON_FIRST + 24)
+#define GADGET_ID_CHANGE_DELAY (GADGET_ID_CHECKBUTTON_FIRST + 25)
+#define GADGET_ID_CHANGE_BY_PLAYER (GADGET_ID_CHECKBUTTON_FIRST + 26)
+#define GADGET_ID_CHANGE_BY_COLLISION (GADGET_ID_CHECKBUTTON_FIRST + 27)
+#define GADGET_ID_CHANGE_BY_OTHER (GADGET_ID_CHECKBUTTON_FIRST + 28)
/* gadgets for buttons in element list */
-#define GADGET_ID_ELEMENTLIST_FIRST 78
-#define GADGET_ID_ELEMENTLIST_LAST (78 + ED_NUM_ELEMENTLIST_BUTTONS - 1)
+#define GADGET_ID_ELEMENTLIST_FIRST (GADGET_ID_CHECKBUTTON_FIRST + 29)
+#define GADGET_ID_ELEMENTLIST_LAST (GADGET_ID_ELEMENTLIST_FIRST + \
+ ED_NUM_ELEMENTLIST_BUTTONS - 1)
#define NUM_EDITOR_GADGETS (GADGET_ID_ELEMENTLIST_LAST + 1)
#define RADIO_NR_RANDOM_ELEMENTS 2
/* values for counter gadgets */
-#define ED_COUNTER_ID_ELEM_SCORE 0
-#define ED_COUNTER_ID_ELEM_CONTENT 1
-#define ED_COUNTER_ID_LEVEL_XSIZE 2
-#define ED_COUNTER_ID_LEVEL_YSIZE 3
-#define ED_COUNTER_ID_LEVEL_COLLECT 4
-#define ED_COUNTER_ID_LEVEL_TIMELIMIT 5
-#define ED_COUNTER_ID_LEVEL_TIMESCORE 6
-#define ED_COUNTER_ID_LEVEL_RANDOM 7
-#define ED_COUNTER_ID_SELECT_LEVEL 8
-
-#define ED_NUM_COUNTERBUTTONS 9
+#define ED_COUNTER_ID_SELECT_LEVEL 0
+#define ED_COUNTER_ID_LEVEL_XSIZE 1
+#define ED_COUNTER_ID_LEVEL_YSIZE 2
+#define ED_COUNTER_ID_LEVEL_GEMSLIMIT 3
+#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_CUSTOM_SCORE 9
+#define ED_COUNTER_ID_CUSTOM_GEMCOUNT 10
+#define ED_COUNTER_ID_PUSH_DELAY_FIX 11
+#define ED_COUNTER_ID_PUSH_DELAY_RND 12
+#define ED_COUNTER_ID_MOVE_DELAY_FIX 13
+#define ED_COUNTER_ID_MOVE_DELAY_RND 14
+#define ED_COUNTER_ID_CHANGE_DELAY_FIX 15
+#define ED_COUNTER_ID_CHANGE_DELAY_RND 16
+#define ED_COUNTER_ID_CHANGE_CONT_RND 17
+
+#define ED_NUM_COUNTERBUTTONS 18
#define ED_COUNTER_ID_LEVEL_FIRST ED_COUNTER_ID_LEVEL_XSIZE
#define ED_COUNTER_ID_LEVEL_LAST ED_COUNTER_ID_LEVEL_RANDOM
+#define ED_COUNTER_ID_CUSTOM_FIRST ED_COUNTER_ID_CUSTOM_SCORE
+#define ED_COUNTER_ID_CUSTOM_LAST ED_COUNTER_ID_MOVE_DELAY_RND
+
+#define ED_COUNTER_ID_CHANGE_FIRST ED_COUNTER_ID_CHANGE_DELAY_FIX
+#define ED_COUNTER_ID_CHANGE_LAST ED_COUNTER_ID_CHANGE_CONT_RND
+
/* values for scrollbutton gadgets */
#define ED_SCROLLBUTTON_ID_AREA_UP 0
#define ED_SCROLLBUTTON_ID_AREA_DOWN 1
/* values for text input gadgets */
#define ED_TEXTINPUT_ID_LEVEL_NAME 0
#define ED_TEXTINPUT_ID_LEVEL_AUTHOR 1
+#define ED_TEXTINPUT_ID_ELEMENT_NAME 2
-#define ED_NUM_TEXTINPUT 2
+#define ED_NUM_TEXTINPUT 3
#define ED_TEXTINPUT_ID_LEVEL_FIRST ED_TEXTINPUT_ID_LEVEL_NAME
#define ED_TEXTINPUT_ID_LEVEL_LAST ED_TEXTINPUT_ID_LEVEL_AUTHOR
+/* values for selectbox gadgets */
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE 0
+#define ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER 1
+#define ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION 2
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN 3
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_DIRECTION 4
+#define ED_SELECTBOX_ID_CUSTOM_MOVE_STEPSIZE 5
+#define ED_SELECTBOX_ID_CUSTOM_SMASH_TARGETS 6
+#define ED_SELECTBOX_ID_CUSTOM_SLIPPERY_TYPE 7
+#define ED_SELECTBOX_ID_CUSTOM_DEADLINESS 8
+#define ED_SELECTBOX_ID_CUSTOM_CONSISTENCY 9
+#define ED_SELECTBOX_ID_CHANGE_TIME_UNITS 10
+#define ED_SELECTBOX_ID_CHANGE_PLAYER_ACTION 11
+#define ED_SELECTBOX_ID_CHANGE_COLLIDE_ACTION 12
+#define ED_SELECTBOX_ID_CHANGE_OTHER_ACTION 13
+#define ED_SELECTBOX_ID_CHANGE_POWER 14
+
+#define ED_NUM_SELECTBOX 15
+
+#define ED_SELECTBOX_ID_CUSTOM_FIRST ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE
+#define ED_SELECTBOX_ID_CUSTOM_LAST ED_SELECTBOX_ID_CUSTOM_CONSISTENCY
+
+#define ED_SELECTBOX_ID_CHANGE_FIRST ED_SELECTBOX_ID_CHANGE_TIME_UNITS
+#define ED_SELECTBOX_ID_CHANGE_LAST ED_SELECTBOX_ID_CHANGE_POWER
+
+/* values for textbutton gadgets */
+#define ED_TEXTBUTTON_ID_PROPERTIES_INFO 0
+#define ED_TEXTBUTTON_ID_PROPERTIES_CONFIG 1
+#define ED_TEXTBUTTON_ID_PROPERTIES_ADVANCED 2
+#define ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE 3
+
+#define ED_NUM_TEXTBUTTON 4
+
/* 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_NUM_CHECKBUTTONS 5
+#define ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE 5
+#define ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT 6
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE 7
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL 8
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH 9
+#define ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY 10
+#define ED_CHECKBUTTON_ID_CUSTOM_DEADLY 11
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_RESULT 12
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE 13
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH 14
+#define ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT 15
+#define ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC 16
+#define ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE 17
+#define ED_CHECKBUTTON_ID_CHANGE_DELAY 18
+#define ED_CHECKBUTTON_ID_CHANGE_BY_PLAYER 19
+#define ED_CHECKBUTTON_ID_CHANGE_BY_COLLISION 20
+#define ED_CHECKBUTTON_ID_CHANGE_BY_OTHER 21
+#define ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION 22
+#define ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT 23
+#define ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE 24
+#define ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM 25
+#define ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE 26
+
+#define ED_NUM_CHECKBUTTONS 27
#define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_DOUBLE_SPEED
#define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED
+#define ED_CHECKBUTTON_ID_CUSTOM_FIRST ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE
+#define ED_CHECKBUTTON_ID_CUSTOM_LAST ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT
+
+#define ED_CHECKBUTTON_ID_CHANGE_FIRST ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC
+#define ED_CHECKBUTTON_ID_CHANGE_LAST ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE
+
/* values for radiobutton gadgets */
#define ED_RADIOBUTTON_ID_PERCENTAGE 0
#define ED_RADIOBUTTON_ID_QUANTITY 1
#define ED_RADIOBUTTON_ID_LEVEL_FIRST ED_RADIOBUTTON_ID_PERCENTAGE
#define ED_RADIOBUTTON_ID_LEVEL_LAST ED_RADIOBUTTON_ID_QUANTITY
+/* 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_CHANGE_TARGET 12
+#define ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT 13
+#define ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER 14
+#define ED_DRAWING_ID_RANDOM_BACKGROUND 15
+
+#define ED_NUM_DRAWING_AREAS 16
+
+
+/*
+ -----------------------------------------------------------------------------
+ some internally used definitions
+ -----------------------------------------------------------------------------
+*/
+
/* values for CopyLevelToUndoBuffer() */
#define UNDO_IMMEDIATE 0
#define UNDO_ACCUMULATE 1
-/* values for ClearEditorGadgetInfoText() and HandleGadgetInfoText() */
-#define INFOTEXT_XPOS SX
-#define INFOTEXT_YPOS (SY + SYSIZE - MINI_TILEX + 2)
-#define INFOTEXT_XSIZE SXSIZE
-#define INFOTEXT_YSIZE MINI_TILEX
-#define MAX_INFOTEXT_LEN (SXSIZE / FONT2_XSIZE)
+/* values for scrollbars */
+#define ED_SCROLL_NO 0
+#define ED_SCROLL_LEFT 1
+#define ED_SCROLL_RIGHT 2
+#define ED_SCROLL_UP 4
+#define ED_SCROLL_DOWN 8
+
+/* screens in the level editor */
+#define ED_MODE_DRAWING 0
+#define ED_MODE_INFO 1
+#define ED_MODE_PROPERTIES 2
+
+/* sub-screens in the element properties section */
+#define ED_MODE_PROPERTIES_INFO ED_TEXTBUTTON_ID_PROPERTIES_INFO
+#define ED_MODE_PROPERTIES_CONFIG ED_TEXTBUTTON_ID_PROPERTIES_CONFIG
+#define ED_MODE_PROPERTIES_ADVANCED ED_TEXTBUTTON_ID_PROPERTIES_ADVANCED
+
+/* how many steps can be cancelled */
+#define NUM_UNDO_STEPS (10 + 1)
+
+/* values for elements with score */
+#define MIN_SCORE 0
+#define MAX_SCORE 255
+
+/* values for elements with gem count */
+#define MIN_GEM_COUNT 0
+#define MAX_GEM_COUNT 100
+
+/* values for random placement */
+#define RANDOM_USE_PERCENTAGE 0
+#define RANDOM_USE_QUANTITY 1
+
+/* maximal size of level editor drawing area */
+#define MAX_ED_FIELDX (2 * SCR_FIELDX)
+#define MAX_ED_FIELDY (2 * SCR_FIELDY - 1)
+
+
+/*
+ -----------------------------------------------------------------------------
+ some internally used data structure definitions
+ -----------------------------------------------------------------------------
+*/
static struct
{
char *text;
} control_info[ED_NUM_CTRL_BUTTONS] =
{
- { 's', "draw single items" },
- { 'd', "draw connected items" },
- { 'l', "draw lines" },
- { 'a', "draw arcs" },
- { 'r', "draw outline rectangles" },
- { 'R', "draw filled rectangles" },
- { '\0', "wrap (rotate) level up" },
- { 't', "enter text elements" },
- { 'f', "flood fill" },
- { '\0', "wrap (rotate) level left" },
- { '?', "properties of drawing element" },
- { '\0', "wrap (rotate) level right" },
- { '\0', "random element placement" },
- { 'b', "grab brush" },
- { '\0', "wrap (rotate) level down" },
- { ',', "pick drawing element" },
- { 'U', "undo last operation" },
- { 'I', "level properties" },
- { 'S', "save level" },
- { 'C', "clear level" },
- { 'T', "test level" },
- { 'E', "exit level editor" }
+ { 's', "draw single items" },
+ { 'd', "draw connected items" },
+ { 'l', "draw lines" },
+ { 'a', "draw arcs" },
+ { 'r', "draw outline rectangles" },
+ { 'R', "draw filled rectangles" },
+ { '\0', "wrap (rotate) level up" },
+ { 't', "enter text elements" },
+ { 'f', "flood fill" },
+ { '\0', "wrap (rotate) level left" },
+ { '?', "properties of drawing element" },
+ { '\0', "wrap (rotate) level right" },
+ { '\0', "random element placement" },
+ { 'b', "grab brush" },
+ { '\0', "wrap (rotate) level down" },
+ { ',', "pick drawing element" },
+ { 'U', "undo last operation" },
+ { 'I', "level properties" },
+ { 'S', "save level" },
+ { 'C', "clear level" },
+ { 'T', "test level" },
+ { 'E', "exit level editor" }
};
-/* values for random placement */
-#define RANDOM_USE_PERCENTAGE 0
-#define RANDOM_USE_QUANTITY 1
-
static int random_placement_value = 10;
static int random_placement_method = RANDOM_USE_QUANTITY;
-static int random_placement_background_element = EL_ERDREICH;
+static int random_placement_background_element = EL_SAND;
static boolean random_placement_background_restricted = FALSE;
static boolean stick_element_properties_window = FALSE;
+static boolean custom_element_properties[NUM_ELEMENT_PROPERTIES];
+static boolean custom_element_change_events[NUM_CHANGE_EVENTS];
+static struct ElementInfo custom_element;
static struct
{
int min_value, max_value;
int gadget_id_down, gadget_id_up;
int gadget_id_text;
+ int gadget_id_align;
int *value;
- char *infotext_above, *infotext_right;
+ char *text_above, *text_left, *text_right;
} counterbutton_info[ED_NUM_COUNTERBUTTONS] =
{
+ /* ---------- level and editor settings ---------------------------------- */
+
{
- ED_COUNT_ELEM_SCORE_XPOS, ED_COUNT_ELEM_SCORE_YPOS,
- MIN_SCORE, MAX_SCORE,
- GADGET_ID_ELEM_SCORE_DOWN, GADGET_ID_ELEM_SCORE_UP,
- GADGET_ID_ELEM_SCORE_TEXT,
- NULL, /* will be set when used */
- "element score", NULL
- },
- {
- ED_COUNT_ELEM_CONTENT_XPOS, ED_COUNT_ELEM_CONTENT_YPOS,
- MIN_ELEMENT_CONTENTS, MAX_ELEMENT_CONTENTS,
- GADGET_ID_ELEM_CONTENT_DOWN, GADGET_ID_ELEM_CONTENT_UP,
- GADGET_ID_ELEM_CONTENT_TEXT,
- &level.num_yam_contents,
- "element content", NULL
+ DX + 5 - SX, DY + 3 - SY,
+ 1, 100,
+ GADGET_ID_SELECT_LEVEL_DOWN, GADGET_ID_SELECT_LEVEL_UP,
+ GADGET_ID_SELECT_LEVEL_TEXT, GADGET_ID_NONE,
+ &level_nr,
+ NULL, NULL, NULL
},
{
- ED_SETTINGS_XPOS, ED_COUNTER_YPOS(2),
+ ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(2),
MIN_LEV_FIELDX, MAX_LEV_FIELDX,
GADGET_ID_LEVEL_XSIZE_DOWN, GADGET_ID_LEVEL_XSIZE_UP,
- GADGET_ID_LEVEL_XSIZE_TEXT,
+ GADGET_ID_LEVEL_XSIZE_TEXT, GADGET_ID_NONE,
&level.fieldx,
- "playfield size", "width",
+ "playfield size:", NULL, "width",
},
{
- ED_SETTINGS_XPOS + 2 * DXSIZE, ED_COUNTER_YPOS(2),
+ ED_SETTINGS_XPOS(0) + 2 * DXSIZE, ED_COUNTER_YPOS(2),
MIN_LEV_FIELDY, MAX_LEV_FIELDY,
GADGET_ID_LEVEL_YSIZE_DOWN, GADGET_ID_LEVEL_YSIZE_UP,
- GADGET_ID_LEVEL_YSIZE_TEXT,
+ GADGET_ID_LEVEL_YSIZE_TEXT, GADGET_ID_LEVEL_XSIZE_UP,
&level.fieldy,
- NULL, "height",
+ NULL, " ", "height",
},
{
- ED_SETTINGS_XPOS, ED_COUNTER_YPOS(3),
+ ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(3),
0, 999,
- GADGET_ID_LEVEL_COLLECT_DOWN, GADGET_ID_LEVEL_COLLECT_UP,
- GADGET_ID_LEVEL_COLLECT_TEXT,
+ GADGET_ID_LEVEL_GEMSLIMIT_DOWN, GADGET_ID_LEVEL_GEMSLIMIT_UP,
+ GADGET_ID_LEVEL_GEMSLIMIT_TEXT, GADGET_ID_NONE,
&level.gems_needed,
- "number of emeralds to collect", NULL
+ "number of emeralds to collect:", NULL, NULL
},
{
- ED_SETTINGS_XPOS, ED_COUNTER_YPOS(4),
+ ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(4),
0, 999,
GADGET_ID_LEVEL_TIMELIMIT_DOWN, GADGET_ID_LEVEL_TIMELIMIT_UP,
- GADGET_ID_LEVEL_TIMELIMIT_TEXT,
+ GADGET_ID_LEVEL_TIMELIMIT_TEXT, GADGET_ID_NONE,
&level.time,
- "time available to solve level", "(0 => no time limit)"
+ "time available to solve level:", NULL, "(0 => no time limit)"
},
{
- ED_SETTINGS_XPOS, ED_COUNTER_YPOS(5),
+ ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(5),
0, 255,
GADGET_ID_LEVEL_TIMESCORE_DOWN, GADGET_ID_LEVEL_TIMESCORE_UP,
- GADGET_ID_LEVEL_TIMESCORE_TEXT,
- &level.score[SC_ZEITBONUS],
- "score for each 10 seconds left", NULL
+ GADGET_ID_LEVEL_TIMESCORE_TEXT, GADGET_ID_NONE,
+ &level.score[SC_TIME_BONUS],
+ "score for each 10 seconds left:", NULL, NULL
},
{
- ED_SETTINGS_XPOS, ED_COUNTER2_YPOS(8),
+ ED_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_LEVEL_RANDOM_TEXT, GADGET_ID_NONE,
&random_placement_value,
- "random element placement", "in"
+ "random element placement:", NULL, "in"
},
+
+ /* ---------- element settings: configure (various elements) ------------- */
+
{
- DX + 5 - SX, DY + 3 - SY,
- 1, 100,
- GADGET_ID_SELECT_LEVEL_DOWN, GADGET_ID_SELECT_LEVEL_UP,
- GADGET_ID_SELECT_LEVEL_TEXT,
- &level_nr,
- NULL, NULL
- }
+ ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(0),
+ MIN_SCORE, MAX_SCORE,
+ GADGET_ID_ELEMENT_SCORE_DOWN, GADGET_ID_ELEMENT_SCORE_UP,
+ GADGET_ID_ELEMENT_SCORE_TEXT, GADGET_ID_NONE,
+ NULL, /* will be set when used */
+ NULL, NULL, NULL
+ },
+ {
+ ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(6),
+ MIN_ELEMENT_CONTENTS, MAX_ELEMENT_CONTENTS,
+ GADGET_ID_ELEMENT_CONTENT_DOWN, GADGET_ID_ELEMENT_CONTENT_UP,
+ GADGET_ID_ELEMENT_CONTENT_TEXT, GADGET_ID_NONE,
+ &level.num_yamyam_contents,
+ NULL, NULL, "number of content areas"
+ },
+
+ /* ---------- element settings: configure (custom elements) ------------- */
+
+ {
+ ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(3),
+ MIN_SCORE, MAX_SCORE,
+ GADGET_ID_CUSTOM_SCORE_DOWN, GADGET_ID_CUSTOM_SCORE_UP,
+ GADGET_ID_CUSTOM_SCORE_TEXT, GADGET_ID_NONE,
+ &custom_element.score,
+ NULL, "collect score", NULL
+ },
+ {
+ ED_SETTINGS_XPOS(13) + 10, ED_SETTINGS_YPOS(3),
+ MIN_GEM_COUNT, MAX_GEM_COUNT,
+ GADGET_ID_CUSTOM_GEMCOUNT_DOWN, GADGET_ID_CUSTOM_GEMCOUNT_UP,
+ GADGET_ID_CUSTOM_GEMCOUNT_TEXT, GADGET_ID_CUSTOM_SCORE_UP,
+ &custom_element.gem_count,
+ NULL, "gems", NULL
+ },
+ {
+ ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(4),
+ 0, 999,
+ GADGET_ID_PUSH_DELAY_FIX_DOWN, GADGET_ID_PUSH_DELAY_FIX_UP,
+ GADGET_ID_PUSH_DELAY_FIX_TEXT, GADGET_ID_NONE,
+ &custom_element.push_delay_fixed,
+ NULL, "push delay", NULL
+ },
+ {
+ ED_COUNT_PUSH_DELAY_RND_XPOS, ED_SETTINGS_YPOS(4),
+ 0, 999,
+ GADGET_ID_PUSH_DELAY_RND_DOWN, GADGET_ID_PUSH_DELAY_RND_UP,
+ GADGET_ID_PUSH_DELAY_RND_TEXT, GADGET_ID_PUSH_DELAY_FIX_UP,
+ &custom_element.push_delay_random,
+ NULL, "+random", NULL
+ },
+ {
+ ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(7),
+ 0, 999,
+ GADGET_ID_MOVE_DELAY_FIX_DOWN, GADGET_ID_MOVE_DELAY_FIX_UP,
+ GADGET_ID_MOVE_DELAY_FIX_TEXT, GADGET_ID_NONE,
+ &custom_element.move_delay_fixed,
+ NULL, "move delay", NULL
+ },
+ {
+ ED_COUNT_MOVE_DELAY_RND_XPOS, ED_SETTINGS_YPOS(7),
+ 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,
+ &custom_element.move_delay_random,
+ NULL, "+random", NULL
+ },
+
+ /* ---------- element settings: advanced (custom elements) --------------- */
+
+ {
+ ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(3),
+ 0, 999,
+ GADGET_ID_CHANGE_DELAY_FIX_DOWN, GADGET_ID_CHANGE_DELAY_FIX_UP,
+ GADGET_ID_CHANGE_DELAY_FIX_TEXT, GADGET_ID_NONE,
+ &custom_element.change.delay_fixed,
+ NULL, "delay", NULL,
+ },
+ {
+ ED_COUNT_CHANGE_DELAY_RND_XPOS+20, ED_SETTINGS_YPOS(3),
+ 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,
+ &custom_element.change.delay_random,
+ NULL, "+random", NULL
+ },
+ {
+ ED_SETTINGS_XPOS(3), ED_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,
+ &custom_element.change.random,
+ NULL, "use random change:", "(%)"
+ },
};
static struct
} textinput_info[ED_NUM_TEXTINPUT] =
{
{
- ED_SETTINGS_XPOS, ED_COUNTER_YPOS(0),
+ ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(0),
GADGET_ID_LEVEL_NAME,
MAX_LEVEL_NAME_LEN,
level.name,
"Title"
},
{
- ED_SETTINGS_XPOS, ED_COUNTER_YPOS(1),
+ ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(1),
GADGET_ID_LEVEL_AUTHOR,
MAX_LEVEL_AUTHOR_LEN,
level.author,
"Author"
+ },
+ {
+ 5 * MINI_TILEX, 5 * MINI_TILEY - ED_BORDER_SIZE,
+ GADGET_ID_ELEMENT_NAME,
+ MAX_ELEMENT_NAME_LEN - 2, /* currently 2 chars less editable */
+ custom_element.description,
+ NULL
}
};
+static struct ValueTextInfo options_access_type[] =
+{
+ { EP_WALKABLE, "walk" },
+ { EP_PASSABLE, "pass" },
+ { -1, NULL }
+};
+
+static struct ValueTextInfo options_access_layer[] =
+{
+ { EP_ACCESSIBLE_OVER, "over" },
+ { EP_ACCESSIBLE_INSIDE, "inside" },
+ { EP_ACCESSIBLE_UNDER, "under" },
+ { -1, NULL }
+};
+
+static struct ValueTextInfo options_walk_to_action[] =
+{
+ { EP_DIGGABLE, "diggable" },
+ { EP_COLLECTIBLE, "collectible" },
+ { EP_PUSHABLE, "pushable" },
+ { -1, NULL }
+};
+
+static struct ValueTextInfo options_move_pattern[] =
+{
+ { MV_LEFT, "left" },
+ { MV_RIGHT, "right" },
+ { MV_UP, "up" },
+ { MV_DOWN, "down" },
+ { MV_HORIZONTAL, "horizontal" },
+ { MV_VERTICAL, "vertical" },
+ { MV_ALL_DIRECTIONS, "all directions" },
+ { MV_TOWARDS_PLAYER, "towards player" },
+ { MV_AWAY_FROM_PLAYER, "away from player" },
+ { MV_ALONG_LEFT_SIDE, "along left side" },
+ { MV_ALONG_RIGHT_SIDE, "along right side" },
+ { MV_TURNING_LEFT, "turning left" },
+ { MV_TURNING_RIGHT, "turning right" },
+ { -1, NULL }
+};
+
+static struct ValueTextInfo options_move_direction[] =
+{
+ { MV_NO_MOVING, "automatic" },
+ { MV_LEFT, "left" },
+ { MV_RIGHT, "right" },
+ { MV_UP, "up" },
+ { MV_DOWN, "down" },
+ { -1, NULL }
+};
+
+static struct ValueTextInfo options_move_stepsize[] =
+{
+ { 1, "very slow" },
+ { 2, "slow" },
+ { 4, "normal" },
+ { 8, "fast" },
+ { 16, "very fast" },
+ { -1, NULL }
+};
+
+static struct ValueTextInfo options_smash_targets[] =
+{
+ { EP_CAN_SMASH_PLAYER, "player" },
+#if 0
+ { EP_CAN_SMASH_ENEMIES, "enemies" },
+#endif
+ { EP_CAN_SMASH_EVERYTHING, "everything" },
+ { -1, NULL }
+};
+
+static struct ValueTextInfo options_slippery_type[] =
+{
+ { SLIPPERY_ANY_RANDOM, "random" },
+ { SLIPPERY_ANY_LEFT_RIGHT, "left, right" },
+ { SLIPPERY_ANY_RIGHT_LEFT, "right, left" },
+ { SLIPPERY_ONLY_LEFT, "only left" },
+ { SLIPPERY_ONLY_RIGHT, "only right" },
+ { -1, NULL }
+};
+
+static struct ValueTextInfo options_deadliness[] =
+{
+ { EP_DONT_RUN_INTO, "running into" },
+ { EP_DONT_COLLIDE_WITH, "colliding with" },
+ { EP_DONT_TOUCH, "touching" },
+ { -1, NULL }
+};
+
+static struct ValueTextInfo options_consistency[] =
+{
+ { EP_CAN_EXPLODE, "can explode" },
+ { EP_INDESTRUCTIBLE, "indestructible" },
+ { -1, NULL }
+};
+
+static struct ValueTextInfo options_time_units[] =
+{
+ { 50, "seconds" },
+ { 1, "frames" },
+ { -1, NULL }
+};
+
+static struct ValueTextInfo options_change_player_action[] =
+{
+ { CE_TOUCHED_BY_PLAYER, "touched" },
+ { CE_PRESSED_BY_PLAYER, "pressed" },
+ { CE_PUSHED_BY_PLAYER, "pushed" },
+ { -1, NULL }
+};
+
+static struct ValueTextInfo options_change_collide_action[] =
+{
+ { CE_COLLISION, "on collision" },
+ { CE_IMPACT, "on impact" },
+ { CE_SMASHED, "when smashed" },
+ { -1, NULL }
+};
+
+static struct ValueTextInfo options_change_other_action[] =
+{
+ { CE_OTHER_IS_TOUCHING, "touching" },
+ { CE_OTHER_IS_CHANGING, "change of" },
+ { CE_OTHER_IS_EXPLODING, "explosion of" },
+ { CE_OTHER_GETS_TOUCHED, "player touches" },
+ { CE_OTHER_GETS_PRESSED, "player presses" },
+ { CE_OTHER_GETS_PUSHED, "player pushes" },
+ { CE_OTHER_GETS_COLLECTED, "player collects" },
+ { -1, NULL }
+};
+
+static struct ValueTextInfo options_change_power[] =
+{
+ { CP_NON_DESTRUCTIVE, "non-destructive" },
+ { CP_HALF_DESTRUCTIVE, "half-destructive" },
+ { CP_FULL_DESTRUCTIVE, "full-destructive" },
+ { -1, NULL }
+};
+
+static struct
+{
+ int x, y;
+ int gadget_id;
+ int gadget_id_align;
+ int size; /* char size of selectbox or '-1' (dynamically determined) */
+ struct ValueTextInfo *options;
+ int *value;
+ char *text_left, *text_right, *infotext;
+} selectbox_info[ED_NUM_SELECTBOX] =
+{
+ /* ---------- element settings: configure (custom elements) ------------- */
+
+ {
+ ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(1),
+ GADGET_ID_CUSTOM_ACCESS_TYPE, GADGET_ID_NONE,
+ -1,
+ options_access_type,
+ &custom_element.access_type,
+ "player can", NULL, "type of access to this field"
+ },
+ {
+ ED_SETTINGS_XPOS(11), ED_SETTINGS_YPOS(1),
+ GADGET_ID_CUSTOM_ACCESS_LAYER, GADGET_ID_CUSTOM_ACCESS_TYPE,
+ -1,
+ options_access_layer,
+ &custom_element.access_layer,
+ NULL, NULL, "layer of access for this field"
+ },
+ {
+ ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(2),
+ GADGET_ID_CUSTOM_WALK_TO_ACTION, GADGET_ID_NONE,
+ -1,
+ options_walk_to_action,
+ &custom_element.walk_to_action,
+ NULL, NULL, "diggable/collectible/pushable"
+ },
+ {
+ ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(5),
+ GADGET_ID_CUSTOM_MOVE_PATTERN, GADGET_ID_NONE,
+ -1,
+ options_move_pattern,
+ &custom_element.move_pattern,
+ "can move", NULL, "element move direction"
+ },
+ {
+ ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(6),
+ GADGET_ID_CUSTOM_MOVE_DIRECTION, GADGET_ID_NONE,
+ -1,
+ options_move_direction,
+ &custom_element.move_direction_initial,
+ "starts moving", NULL, "initial element move direction"
+ },
+ {
+ ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(8),
+ GADGET_ID_CUSTOM_MOVE_STEPSIZE, GADGET_ID_NONE,
+ -1,
+ options_move_stepsize,
+ &custom_element.move_stepsize,
+ "move/fall speed", NULL, "speed of element movement"
+ },
+ {
+ ED_SETTINGS_XPOS(7), ED_SETTINGS_YPOS(9),
+ GADGET_ID_CUSTOM_SMASH_TARGETS, GADGET_ID_CUSTOM_CAN_SMASH,
+ -1,
+ options_smash_targets,
+ &custom_element.smash_targets,
+ "can smash", NULL, "elements that can be smashed"
+ },
+ {
+ ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(10),
+ GADGET_ID_CUSTOM_SLIPPERY_TYPE, GADGET_ID_NONE,
+ -1,
+ options_slippery_type,
+ &custom_element.slippery_type,
+ "slippery", NULL, "where other elements fall down"
+ },
+ {
+ ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(11),
+ GADGET_ID_CUSTOM_DEADLINESS, GADGET_ID_NONE,
+ -1,
+ options_deadliness,
+ &custom_element.deadliness,
+ "deadly when", NULL, "deadliness of element"
+ },
+ {
+ ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(12),
+ GADGET_ID_CUSTOM_CONSISTENCY, GADGET_ID_NONE,
+ -1,
+ options_consistency,
+ &custom_element.consistency,
+ NULL, "explodes to:", "consistency/destructibility"
+ },
+
+ /* ---------- element settings: advanced (custom elements) --------------- */
+
+ {
+ ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(4),
+ GADGET_ID_CHANGE_TIME_UNITS, GADGET_ID_NONE,
+ -1,
+ options_time_units,
+ &custom_element.change.delay_frames,
+ "delay time given in", NULL, "delay time units for change"
+ },
+ {
+ ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(5),
+ GADGET_ID_CHANGE_PLAYER_ACTION, GADGET_ID_NONE,
+ -1,
+ options_change_player_action,
+ &custom_element.change_player_action,
+ NULL, "by player", "type of player contact"
+ },
+ {
+ ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(6),
+ GADGET_ID_CHANGE_COLLIDE_ACTION, GADGET_ID_NONE,
+ -1,
+ options_change_collide_action,
+ &custom_element.change_collide_action,
+ NULL, NULL, "change after impact or smash"
+ },
+ {
+ ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(7),
+ GADGET_ID_CHANGE_OTHER_ACTION, GADGET_ID_NONE,
+ -1,
+ options_change_other_action,
+ &custom_element.change_other_action,
+ NULL, "element:", "type of other element action"
+ },
+ {
+ ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(10),
+ GADGET_ID_CHANGE_POWER, GADGET_ID_NONE,
+ -1,
+ options_change_power,
+ &custom_element.change.power,
+ "power:", NULL, "power of extended change"
+ },
+};
+
+static struct
+{
+ int x, y;
+ int gadget_id;
+ int gadget_id_align;
+ int size;
+ char *text, *infotext;
+} textbutton_info[ED_NUM_TEXTBUTTON] =
+{
+ {
+ ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(1),
+ GADGET_ID_PROPERTIES_INFO, GADGET_ID_NONE,
+ 11, "Information", "Show information about element"
+ },
+ {
+ ED_SETTINGS_XPOS(0) + 166, ED_COUNTER_YPOS(1),
+ GADGET_ID_PROPERTIES_CONFIG, GADGET_ID_NONE,
+ 11, "Configure", "Configure element properties"
+ },
+ {
+ ED_SETTINGS_XPOS(0) + 332, ED_COUNTER_YPOS(1),
+ GADGET_ID_PROPERTIES_ADVANCED, GADGET_ID_NONE,
+ 11, "Advanced", "Advanced element configuration"
+ },
+ {
+ ED_SETTINGS_XPOS(0) + 262, ED_SETTINGS_YPOS(13),
+ GADGET_ID_SAVE_AS_TEMPLATE, GADGET_ID_CUSTOM_USE_TEMPLATE,
+ -1, "Save as template", "Save current settings as new template"
+ },
+};
+
static struct
{
- int xpos, ypos;
+ int gd_x, gd_y;
int x, y;
int gadget_id;
char *infotext;
static struct
{
- int xpos, ypos;
+ int gd_x, gd_y;
int x, y;
int width, height;
int type;
{
int x, y;
int gadget_id;
+ int gadget_id_align;
int radio_button_nr;
int *value;
int checked_value;
- char *text, *infotext;
+ char *text_left, *text_right, *infotext;
} radiobutton_info[ED_NUM_RADIOBUTTONS] =
{
{
- ED_SETTINGS_XPOS + 160, ED_COUNTER2_YPOS(8),
- GADGET_ID_RANDOM_PERCENTAGE,
+ ED_SETTINGS_XPOS(0) + 160, ED_COUNTER2_YPOS(8),
+ GADGET_ID_RANDOM_PERCENTAGE, GADGET_ID_LEVEL_RANDOM_UP,
RADIO_NR_RANDOM_ELEMENTS,
&random_placement_method, RANDOM_USE_PERCENTAGE,
- "percentage", "use percentage for random elements"
+ " ", "percentage", "use percentage for random elements"
},
{
- ED_SETTINGS_XPOS + 340, ED_COUNTER2_YPOS(8),
- GADGET_ID_RANDOM_QUANTITY,
+ ED_SETTINGS_XPOS(0) + 340, ED_COUNTER2_YPOS(8),
+ GADGET_ID_RANDOM_QUANTITY, GADGET_ID_RANDOM_PERCENTAGE,
RADIO_NR_RANDOM_ELEMENTS,
&random_placement_method, RANDOM_USE_QUANTITY,
- "quantity", "use quantity for random elements"
+ " ", "quantity", "use quantity for random elements"
}
};
{
int x, y;
int gadget_id;
+ int gadget_id_align;
boolean *value;
- char *text, *infotext;
+ char *text_left, *text_right, *infotext;
} checkbutton_info[ED_NUM_CHECKBUTTONS] =
{
+ /* ---------- level and editor settings ---------------------------------- */
+
{
- ED_SETTINGS_XPOS, ED_COUNTER_YPOS(6) - MINI_TILEY,
- GADGET_ID_DOUBLE_SPEED,
+ ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(6) - MINI_TILEY,
+ GADGET_ID_DOUBLE_SPEED, GADGET_ID_NONE,
&level.double_speed,
- "double speed movement", "set movement speed of player"
+ NULL, "double speed movement", "set movement speed of player"
},
{
- ED_SETTINGS_XPOS + 340, ED_COUNTER_YPOS(6) - MINI_TILEY,
- GADGET_ID_GRAVITY,
+ ED_SETTINGS_XPOS(0) + 340, ED_COUNTER_YPOS(6) - MINI_TILEY,
+ GADGET_ID_GRAVITY, GADGET_ID_DOUBLE_SPEED,
&level.gravity,
- "gravity", "set level gravity"
+ " ", "gravity", "set level gravity"
},
{
- ED_SETTINGS_XPOS, ED_COUNTER2_YPOS(9) - MINI_TILEY,
- GADGET_ID_RANDOM_RESTRICTED,
+ ED_SETTINGS_XPOS(0), ED_COUNTER2_YPOS(9) - MINI_TILEY,
+ GADGET_ID_RANDOM_RESTRICTED, GADGET_ID_NONE,
&random_placement_background_restricted,
- "restrict random placement to", "set random placement restriction"
+ NULL,
+ "restrict random placement to:", "set random placement restriction"
},
+
+ /* ---------- element settings: configure (various elements) ------------- */
+
{
- ED_SETTINGS_XPOS, ED_COUNTER_YPOS(4),
- GADGET_ID_STICK_ELEMENT,
+ ED_SETTINGS_XPOS(0), 0, /* set at runtime */
+ GADGET_ID_STICK_ELEMENT, GADGET_ID_NONE,
&stick_element_properties_window,
- "stick window to edit content", "stick window to edit content"
+ NULL,
+ "stick this screen to edit content","stick this screen to edit content"
},
{
- ED_SETTINGS_XPOS, ED_COUNTER_YPOS(4),
- GADGET_ID_EM_SLIPPERY_GEMS,
+ ED_SETTINGS_XPOS(0), ED_COUNTER_YPOS(4),
+ GADGET_ID_EM_SLIPPERY_GEMS, GADGET_ID_NONE,
&level.em_slippery_gems,
+ NULL,
"slip down from certain flat walls","use EM style slipping behaviour"
- }
-};
+ },
-/* maximal size of level editor drawing area */
-#define MAX_ED_FIELDX (2 * SCR_FIELDX)
-#define MAX_ED_FIELDY (2 * SCR_FIELDY - 1)
+ /* ---------- element settings: configure (custom elements) ------------- */
+
+ {
+ ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(1),
+ 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(2),
+ 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(5),
+ GADGET_ID_CUSTOM_CAN_MOVE, GADGET_ID_NONE,
+ &custom_element_properties[EP_CAN_MOVE],
+ NULL, NULL, "element can move in some direction"
+ },
+ {
+ ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(9),
+ GADGET_ID_CUSTOM_CAN_FALL, GADGET_ID_NONE,
+ &custom_element_properties[EP_CAN_FALL],
+ NULL, "can fall", "element can fall down"
+ },
+ {
+ ED_SETTINGS_XPOS(6), ED_SETTINGS_YPOS(9),
+ 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(10),
+ 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(11),
+ 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(12),
+ GADGET_ID_CUSTOM_EXPLODE_RESULT, GADGET_ID_NONE,
+ &custom_element_properties[EP_EXPLODE_RESULT],
+ NULL, NULL, "set consistency/destructibility"
+ },
+ {
+ ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(13),
+ GADGET_ID_CUSTOM_EXPLODE_FIRE, GADGET_ID_NONE,
+ &custom_element.can_explode_by_fire,
+ NULL, "by fire", "element can explode by fire/explosion"
+ },
+ {
+ ED_SETTINGS_XPOS(7), ED_SETTINGS_YPOS(13),
+ GADGET_ID_CUSTOM_EXPLODE_SMASH, GADGET_ID_CUSTOM_EXPLODE_FIRE,
+ &custom_element.can_explode_smashed,
+ " ", "smashed", "element can explode when smashed"
+ },
+ {
+ ED_SETTINGS_XPOS(13), ED_SETTINGS_YPOS(13),
+ GADGET_ID_CUSTOM_EXPLODE_IMPACT, GADGET_ID_CUSTOM_EXPLODE_SMASH,
+ &custom_element.can_explode_impact,
+ " ", "impact", "element can explode on impact"
+ },
+
+ /* ---------- element settings: advanced (custom elements) --------------- */
+
+ {
+ ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(1),
+ GADGET_ID_CUSTOM_USE_GRAPHIC, GADGET_ID_NONE,
+ &custom_element.use_gfx_element,
+ NULL, "use graphic of element:", "use graphic for custom element"
+ },
+ {
+ ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(2),
+ GADGET_ID_CUSTOM_CAN_CHANGE, GADGET_ID_NONE,
+ &custom_element_properties[EP_CAN_CHANGE],
+ NULL, "element changes to:", "element can change to other element"
+ },
+ {
+ ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(3),
+ 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(5),
+ GADGET_ID_CHANGE_BY_PLAYER, GADGET_ID_NONE,
+ &custom_element_change_events[CE_BY_PLAYER],
+ NULL, NULL, "element changes by player contact"
+ },
+ {
+ ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(6),
+ GADGET_ID_CHANGE_BY_COLLISION, GADGET_ID_NONE,
+ &custom_element_change_events[CE_BY_COLLISION],
+ NULL, NULL, "element changes by impact or smash"
+ },
+ {
+ ED_SETTINGS_XPOS(1), ED_SETTINGS_YPOS(7),
+ GADGET_ID_CHANGE_BY_OTHER, GADGET_ID_NONE,
+ &custom_element_change_events[CE_BY_OTHER],
+ NULL, NULL, "element changes by other element"
+ },
+ {
+ ED_SETTINGS_XPOS(1), ED_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),
+ GADGET_ID_CHANGE_USE_CONTENT, GADGET_ID_NONE,
+ &custom_element.change.use_content,
+ NULL, "use extended change target:","element changes to more elements"
+ },
+ {
+ ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(11),
+ GADGET_ID_CHANGE_ONLY_COMPLETE, GADGET_ID_NONE,
+ &custom_element.change.only_complete,
+ NULL, "only use complete change", "only use complete extended content"
+ },
+ {
+ ED_SETTINGS_XPOS(2), ED_SETTINGS_YPOS(12),
+ GADGET_ID_CHANGE_USE_RANDOM, GADGET_ID_NONE,
+ &custom_element.change.use_random_change,
+ NULL, NULL, "use random value for new content"
+ },
+ {
+ ED_SETTINGS_XPOS(0), ED_SETTINGS_YPOS(13),
+ GADGET_ID_CUSTOM_USE_TEMPLATE, GADGET_ID_NONE,
+ &level.use_custom_template,
+ NULL, "use template", "use template for custom properties"
+ },
+};
+
+static struct
+{
+ int x, y;
+ int area_xsize, area_ysize;
+ int gadget_id;
+ int gadget_id_align;
+ char *text_left, *text_right;
+} drawingarea_info[ED_NUM_DRAWING_AREAS] =
+{
+ /* ---------- level playfield content ------------------------------------ */
+
+ {
+ 0, 0,
+ MAX_ED_FIELDX, MAX_ED_FIELDY,
+ GADGET_ID_DRAWING_LEVEL, GADGET_ID_NONE,
+ NULL, NULL
+ },
+
+ /* ---------- yam yam content -------------------------------------------- */
+
+ {
+ ED_AREA_YAMYAM_CONTENT_XPOS(0), ED_AREA_YAMYAM_CONTENT_YPOS(0),
+ 3, 3,
+ GADGET_ID_ELEMENT_CONTENT_0, GADGET_ID_NONE,
+ NULL, NULL
+ },
+ {
+ ED_AREA_YAMYAM_CONTENT_XPOS(1), ED_AREA_YAMYAM_CONTENT_YPOS(1),
+ 3, 3,
+ GADGET_ID_ELEMENT_CONTENT_1, GADGET_ID_NONE,
+ NULL, NULL
+ },
+ {
+ ED_AREA_YAMYAM_CONTENT_XPOS(2), ED_AREA_YAMYAM_CONTENT_YPOS(2),
+ 3, 3,
+ GADGET_ID_ELEMENT_CONTENT_2, GADGET_ID_NONE,
+ NULL, NULL
+ },
+ {
+ ED_AREA_YAMYAM_CONTENT_XPOS(3), ED_AREA_YAMYAM_CONTENT_YPOS(3),
+ 3, 3,
+ GADGET_ID_ELEMENT_CONTENT_3, GADGET_ID_NONE,
+ NULL, NULL
+ },
+ {
+ ED_AREA_YAMYAM_CONTENT_XPOS(4), ED_AREA_YAMYAM_CONTENT_YPOS(4),
+ 3, 3,
+ GADGET_ID_ELEMENT_CONTENT_4, GADGET_ID_NONE,
+ NULL, NULL
+ },
+ {
+ ED_AREA_YAMYAM_CONTENT_XPOS(5), ED_AREA_YAMYAM_CONTENT_YPOS(5),
+ 3, 3,
+ GADGET_ID_ELEMENT_CONTENT_5, GADGET_ID_NONE,
+ NULL, NULL
+ },
+ {
+ ED_AREA_YAMYAM_CONTENT_XPOS(6), ED_AREA_YAMYAM_CONTENT_YPOS(6),
+ 3, 3,
+ GADGET_ID_ELEMENT_CONTENT_6, GADGET_ID_NONE,
+ NULL, NULL
+ },
+ {
+ ED_AREA_YAMYAM_CONTENT_XPOS(7), ED_AREA_YAMYAM_CONTENT_YPOS(7),
+ 3, 3,
+ GADGET_ID_ELEMENT_CONTENT_7, GADGET_ID_NONE,
+ NULL, NULL
+ },
+
+ /* ---------- amoeba content --------------------------------------------- */
+
+ {
+ ED_AREA_ELEM_CONTENT_XPOS, ED_AREA_ELEM_CONTENT_YPOS,
+ 1, 1,
+ GADGET_ID_AMOEBA_CONTENT, GADGET_ID_NONE,
+ NULL, NULL
+ },
+
+ /* ---------- custom graphic --------------------------------------------- */
+
+ {
+ ED_AREA_ELEM_CONTENT3_XPOS, ED_AREA_ELEM_CONTENT3_YPOS,
+ 1, 1,
+ GADGET_ID_CUSTOM_GRAPHIC, GADGET_ID_CUSTOM_USE_GRAPHIC,
+ NULL, NULL
+ },
+
+ /* ---------- custom content (when exploding) ---------------------------- */
+
+ {
+ ED_AREA_ELEM_CONTENT4_XPOS, ED_AREA_ELEM_CONTENT4_YPOS,
+ 3, 3,
+ GADGET_ID_CUSTOM_CONTENT, GADGET_ID_NONE, /* align three rows */
+ NULL, NULL
+ },
+
+ /* ---------- custom change target --------------------------------------- */
+
+ {
+ ED_AREA_ELEM_CONTENT2_XPOS, ED_AREA_ELEM_CONTENT2_YPOS,
+ 1, 1,
+ GADGET_ID_CUSTOM_CHANGE_TARGET, GADGET_ID_CUSTOM_CAN_CHANGE,
+ NULL, "after/when:"
+ },
+
+ /* ---------- custom change content (extended change target) ------------- */
+
+ {
+ ED_AREA_ELEM_CONTENT6_XPOS, ED_AREA_ELEM_CONTENT6_YPOS,
+ 3, 3,
+ GADGET_ID_CUSTOM_CHANGE_CONTENT, GADGET_ID_NONE, /* align three rows */
+ NULL, NULL
+ },
+
+ /* ---------- custom change trigger (element causing change) ------------- */
+
+ {
+ ED_AREA_ELEM_CONTENT5_XPOS, ED_AREA_ELEM_CONTENT5_YPOS,
+ 1, 1,
+ GADGET_ID_CUSTOM_CHANGE_TRIGGER, GADGET_ID_CHANGE_OTHER_ACTION,
+ NULL, NULL
+ },
+
+ /* ---------- random background (for random painting) -------------------- */
+
+ {
+ ED_AREA_RANDOM_BACKGROUND_XPOS, ED_AREA_RANDOM_BACKGROUND_YPOS,
+ 1, 1,
+ GADGET_ID_RANDOM_BACKGROUND, GADGET_ID_RANDOM_RESTRICTED,
+ NULL, NULL
+ },
+};
+
+
+/*
+ -----------------------------------------------------------------------------
+ some internally used variables
+ -----------------------------------------------------------------------------
+*/
/* actual size of level editor drawing area */
static int ed_fieldx = MAX_ED_FIELDX - 1, ed_fieldy = MAX_ED_FIELDY - 1;
#define IN_ED_FIELD(x,y) ((x)>=0 && (x)<ed_fieldx && (y)>=0 &&(y)<ed_fieldy)
/* drawing elements on the three mouse buttons */
-static int new_element1 = EL_MAUERWERK;
-static int new_element2 = EL_LEERRAUM;
-static int new_element3 = EL_ERDREICH;
+static int new_element1 = EL_WALL;
+static int new_element2 = EL_EMPTY;
+static int new_element3 = EL_SAND;
#define BUTTON_ELEMENT(button) ((button) == 1 ? new_element1 : \
(button) == 2 ? new_element2 : \
- (button) == 3 ? new_element3 : EL_LEERRAUM)
+ (button) == 3 ? new_element3 : EL_EMPTY)
#define BUTTON_STEPSIZE(button) ((button) == 1 ? 1 : (button) == 2 ? 5 : 10)
/* forward declaration for internal use */
static void ModifyEditorCounter(int, int);
static void ModifyEditorCounterLimits(int, int, int);
+static void ModifyEditorSelectbox(int, int);
+static void ModifyEditorElementList();
+static void RedrawDrawingElements();
static void DrawDrawingWindow();
static void DrawLevelInfoWindow();
static void DrawPropertiesWindow();
+static boolean checkPropertiesConfig();
static void CopyLevelToUndoBuffer(int);
static void HandleDrawingAreas(struct GadgetInfo *);
static void HandleCounterButtons(struct GadgetInfo *);
static void HandleTextInputGadgets(struct GadgetInfo *);
+static void HandleSelectboxGadgets(struct GadgetInfo *);
+static void HandleTextbuttonGadgets(struct GadgetInfo *);
static void HandleRadiobuttons(struct GadgetInfo *);
static void HandleCheckbuttons(struct GadgetInfo *);
static void HandleControlButtons(struct GadgetInfo *);
static void HandleDrawingAreaInfo(struct GadgetInfo *);
static struct GadgetInfo *level_editor_gadget[NUM_EDITOR_GADGETS];
+static int right_gadget_border[NUM_EDITOR_GADGETS];
static int drawing_function = GADGET_ID_SINGLE_ITEMS;
static int last_drawing_function = GADGET_ID_SINGLE_ITEMS;
static boolean draw_with_brush = FALSE;
static int properties_element = 0;
-static short ElementContent[MAX_ELEMENT_CONTENTS][3][3];
static short FieldBackup[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
static short UndoBuffer[NUM_UNDO_STEPS][MAX_LEV_FIELDX][MAX_LEV_FIELDY];
static int undo_buffer_position = 0;
static int undo_buffer_steps = 0;
static int edit_mode;
+static int edit_mode_properties;
-static int counter_xsize = DXSIZE + FONT2_XSIZE - 2 * ED_GADGET_DISTANCE;
-
-int element_shift = 0;
+static int element_shift = 0;
-int editor_element[] =
+static int editor_el_boulderdash[] =
{
EL_CHAR('B'),
EL_CHAR('O'),
EL_CHAR('S'),
EL_CHAR('H'),
- EL_SPIELFIGUR,
- EL_LEERRAUM,
- EL_ERDREICH,
- EL_BETON,
+ EL_PLAYER_1,
+ EL_EMPTY,
+ EL_SAND,
+ EL_STEELWALL,
EL_BD_WALL,
- EL_MAGIC_WALL_BD_OFF,
- EL_AUSGANG_ZU,
- EL_AUSGANG_AUF,
+ EL_BD_MAGIC_WALL,
+ EL_EXIT_CLOSED,
+ EL_EXIT_OPEN,
- EL_EDELSTEIN_BD,
- EL_BUTTERFLY_UP,
- EL_FIREFLY_UP,
+ EL_BD_DIAMOND,
+ EL_BD_BUTTERFLY_UP,
+ EL_BD_FIREFLY_UP,
EL_BD_ROCK,
- EL_BUTTERFLY_LEFT,
- EL_FIREFLY_LEFT,
- EL_BUTTERFLY_RIGHT,
- EL_FIREFLY_RIGHT,
+ EL_BD_BUTTERFLY_LEFT,
+ EL_BD_FIREFLY_LEFT,
+ EL_BD_BUTTERFLY_RIGHT,
+ EL_BD_FIREFLY_RIGHT,
- EL_AMOEBE_BD,
- EL_BUTTERFLY_DOWN,
- EL_FIREFLY_DOWN,
- EL_LEERRAUM,
+ EL_BD_AMOEBA,
+ EL_BD_BUTTERFLY_DOWN,
+ EL_BD_FIREFLY_DOWN,
+ EL_EMPTY,
+};
+static int num_editor_el_boulderdash = SIZEOF_ARRAY_INT(editor_el_boulderdash);
+static int editor_el_emerald_mine[] =
+{
EL_CHAR('E'),
EL_CHAR('M'),
EL_CHAR('E'),
EL_CHAR('N'),
EL_CHAR('E'),
- EL_SPIELER1,
- EL_SPIELER2,
- EL_SPIELER3,
- EL_SPIELER4,
+ EL_PLAYER_1,
+ EL_PLAYER_2,
+ EL_PLAYER_3,
+ EL_PLAYER_4,
- EL_SPIELFIGUR,
- EL_LEERRAUM,
- EL_ERDREICH,
- EL_FELSBROCKEN,
+ EL_PLAYER_1,
+ EL_EMPTY,
+ EL_SAND,
+ EL_ROCK,
- EL_BETON,
- EL_MAUERWERK,
- EL_FELSBODEN,
- EL_MAGIC_WALL_OFF,
+ EL_STEELWALL,
+ EL_WALL,
+ EL_WALL_SLIPPERY,
+ EL_MAGIC_WALL,
- EL_EDELSTEIN,
- EL_DIAMANT,
- EL_KOKOSNUSS,
- EL_BOMBE,
+ EL_EMERALD,
+ EL_DIAMOND,
+ EL_NUT,
+ EL_BOMB,
- EL_ERZ_EDEL,
- EL_ERZ_DIAM,
- EL_MORAST_LEER,
- EL_MORAST_VOLL,
+ EL_WALL_EMERALD,
+ EL_WALL_DIAMOND,
+ EL_QUICKSAND_EMPTY,
+ EL_QUICKSAND_FULL,
- EL_DYNAMITE_INACTIVE,
+ EL_DYNAMITE,
EL_DYNAMITE_ACTIVE,
- EL_AUSGANG_ZU,
- EL_AUSGANG_AUF,
+ EL_EXIT_CLOSED,
+ EL_EXIT_OPEN,
- EL_MAMPFER,
- EL_KAEFER_UP,
- EL_FLIEGER_UP,
+ EL_YAMYAM,
+ EL_BUG_UP,
+ EL_SPACESHIP_UP,
EL_ROBOT,
- EL_KAEFER_LEFT,
- EL_FLIEGER_LEFT,
- EL_KAEFER_RIGHT,
- EL_FLIEGER_RIGHT,
+ EL_BUG_LEFT,
+ EL_SPACESHIP_LEFT,
+ EL_BUG_RIGHT,
+ EL_SPACESHIP_RIGHT,
- EL_ABLENK_AUS,
- EL_KAEFER_DOWN,
- EL_FLIEGER_DOWN,
- EL_UNSICHTBAR,
+ EL_ROBOT_WHEEL,
+ EL_BUG_DOWN,
+ EL_SPACESHIP_DOWN,
+ EL_INVISIBLE_WALL,
- EL_BADEWANNE1,
- EL_SALZSAEURE,
- EL_BADEWANNE2,
- EL_LEERRAUM,
+ EL_ACID_POOL_TOPLEFT,
+ EL_ACID,
+ EL_ACID_POOL_TOPRIGHT,
+ EL_EMPTY,
- EL_BADEWANNE3,
- EL_BADEWANNE4,
- EL_BADEWANNE5,
- EL_LEERRAUM,
+ EL_ACID_POOL_BOTTOMLEFT,
+ EL_ACID_POOL_BOTTOM,
+ EL_ACID_POOL_BOTTOMRIGHT,
+ EL_EMPTY,
- EL_TROPFEN,
- EL_AMOEBE_TOT,
- EL_AMOEBE_NASS,
- EL_AMOEBE_NORM,
+ EL_AMOEBA_DROP,
+ EL_AMOEBA_DEAD,
+ EL_AMOEBA_WET,
+ EL_AMOEBA_DRY,
EL_EM_KEY_1_FILE,
EL_EM_KEY_2_FILE,
EL_EM_GATE_3,
EL_EM_GATE_4,
- EL_EM_GATE_1X,
- EL_EM_GATE_2X,
- EL_EM_GATE_3X,
- EL_EM_GATE_4X,
+ EL_EM_GATE_1_GRAY,
+ EL_EM_GATE_2_GRAY,
+ EL_EM_GATE_3_GRAY,
+ EL_EM_GATE_4_GRAY,
+};
+static int num_editor_el_emerald_mine = SIZEOF_ARRAY_INT(editor_el_emerald_mine);
+static int editor_el_more[] =
+{
EL_CHAR('M'),
EL_CHAR('O'),
EL_CHAR('R'),
EL_CHAR('E'),
- EL_SCHLUESSEL1,
- EL_SCHLUESSEL2,
- EL_SCHLUESSEL3,
- EL_SCHLUESSEL4,
-
- EL_PFORTE1,
- EL_PFORTE2,
- EL_PFORTE3,
- EL_PFORTE4,
-
- EL_PFORTE1X,
- EL_PFORTE2X,
- EL_PFORTE3X,
- EL_PFORTE4X,
-
- EL_PFEIL_LEFT,
- EL_PFEIL_RIGHT,
- EL_PFEIL_UP,
- EL_PFEIL_DOWN,
-
- EL_AMOEBE_VOLL,
- EL_EDELSTEIN_GELB,
- EL_EDELSTEIN_ROT,
- EL_EDELSTEIN_LILA,
-
- EL_ERZ_EDEL_BD,
- EL_ERZ_EDEL_GELB,
- EL_ERZ_EDEL_ROT,
- EL_ERZ_EDEL_LILA,
-
- EL_LIFE,
+ EL_KEY_1,
+ EL_KEY_2,
+ EL_KEY_3,
+ EL_KEY_4,
+
+ EL_GATE_1,
+ EL_GATE_2,
+ EL_GATE_3,
+ EL_GATE_4,
+
+ EL_GATE_1_GRAY,
+ EL_GATE_2_GRAY,
+ EL_GATE_3_GRAY,
+ EL_GATE_4_GRAY,
+
+ EL_ARROW_LEFT,
+ EL_ARROW_RIGHT,
+ EL_ARROW_UP,
+ EL_ARROW_DOWN,
+
+ EL_AMOEBA_FULL,
+ EL_EMERALD_YELLOW,
+ EL_EMERALD_RED,
+ EL_EMERALD_PURPLE,
+
+ EL_WALL_BD_DIAMOND,
+ EL_WALL_EMERALD_YELLOW,
+ EL_WALL_EMERALD_RED,
+ EL_WALL_EMERALD_PURPLE,
+
+ EL_GAME_OF_LIFE,
EL_PACMAN_UP,
- EL_ZEIT_VOLL,
- EL_ZEIT_LEER,
+ EL_TIME_ORB_FULL,
+ EL_TIME_ORB_EMPTY,
EL_PACMAN_LEFT,
- EL_MAMPFER2,
+ EL_DARK_YAMYAM,
EL_PACMAN_RIGHT,
- EL_MAUER_LEBT,
+ EL_EXPANDABLE_WALL,
- EL_LIFE_ASYNC,
+ EL_BIOMAZE,
EL_PACMAN_DOWN,
- EL_BIRNE_AUS,
- EL_BIRNE_EIN,
+ EL_LAMP,
+ EL_LAMP_ACTIVE,
- EL_DYNABOMB_NR,
- EL_DYNABOMB_SZ,
- EL_DYNABOMB_XL,
- EL_BADEWANNE,
+ EL_DYNABOMB_INCREASE_NUMBER,
+ EL_DYNABOMB_INCREASE_SIZE,
+ EL_DYNABOMB_INCREASE_POWER,
+ EL_STONEBLOCK,
EL_MOLE,
- EL_PINGUIN,
- EL_SCHWEIN,
- EL_DRACHE,
+ EL_PENGUIN,
+ EL_PIG,
+ EL_DRAGON,
- EL_LEERRAUM,
+ EL_EMPTY,
EL_MOLE_UP,
- EL_LEERRAUM,
- EL_LEERRAUM,
+ EL_EMPTY,
+ EL_EMPTY,
EL_MOLE_LEFT,
- EL_LEERRAUM,
+ EL_EMPTY,
EL_MOLE_RIGHT,
- EL_LEERRAUM,
+ EL_EMPTY,
- EL_LEERRAUM,
+ EL_EMPTY,
EL_MOLE_DOWN,
EL_BALLOON,
- EL_BALLOON_SEND_ANY,
+ EL_BALLOON_SWITCH_ANY,
- EL_BALLOON_SEND_LEFT,
- EL_BALLOON_SEND_RIGHT,
- EL_BALLOON_SEND_UP,
- EL_BALLOON_SEND_DOWN,
+ EL_BALLOON_SWITCH_LEFT,
+ EL_BALLOON_SWITCH_RIGHT,
+ EL_BALLOON_SWITCH_UP,
+ EL_BALLOON_SWITCH_DOWN,
- EL_SONDE,
- EL_MAUER_X,
- EL_MAUER_Y,
- EL_MAUER_XY,
+ EL_SATELLITE,
+ EL_EXPANDABLE_WALL_HORIZONTAL,
+ EL_EXPANDABLE_WALL_VERTICAL,
+ EL_EXPANDABLE_WALL_ANY,
- EL_INVISIBLE_STEEL,
- EL_UNSICHTBAR,
+ EL_INVISIBLE_STEELWALL,
+ EL_INVISIBLE_WALL,
EL_SPEED_PILL,
EL_BLACK_ORB,
- EL_EMC_STEEL_WALL_1,
+ EL_EMC_STEELWALL_1,
EL_EMC_WALL_1,
EL_EMC_WALL_2,
EL_EMC_WALL_3,
EL_EMC_WALL_5,
EL_EMC_WALL_6,
EL_EMC_WALL_7,
+};
+static int num_editor_el_more = SIZEOF_ARRAY_INT(editor_el_more);
-
+static int editor_el_sokoban[] =
+{
EL_CHAR('S'),
EL_CHAR('O'),
EL_CHAR('K'),
EL_CHAR('A'),
EL_CHAR('N'),
- EL_SOKOBAN_OBJEKT,
- EL_SOKOBAN_FELD_LEER,
- EL_SOKOBAN_FELD_VOLL,
- EL_BETON,
+ EL_SOKOBAN_OBJECT,
+ EL_SOKOBAN_FIELD_EMPTY,
+ EL_SOKOBAN_FIELD_FULL,
+ EL_STEELWALL,
+};
+static int num_editor_el_sokoban = SIZEOF_ARRAY_INT(editor_el_sokoban);
+static int editor_el_supaplex[] =
+{
EL_CHAR('S'),
EL_CHAR('U'),
EL_CHAR('P'),
EL_SP_INFOTRON,
EL_SP_CHIP_SINGLE,
- EL_SP_HARD_GRAY,
- EL_SP_EXIT,
+ EL_SP_HARDWARE_GRAY,
+ EL_SP_EXIT_CLOSED,
EL_SP_DISK_ORANGE,
- EL_SP_PORT1_RIGHT,
- EL_SP_PORT1_DOWN,
- EL_SP_PORT1_LEFT,
+ EL_SP_PORT_RIGHT,
+ EL_SP_PORT_DOWN,
+ EL_SP_PORT_LEFT,
- EL_SP_PORT1_UP,
- EL_SP_PORT2_RIGHT,
- EL_SP_PORT2_DOWN,
- EL_SP_PORT2_LEFT,
+ EL_SP_PORT_UP,
+ EL_SP_GRAVITY_PORT_RIGHT,
+ EL_SP_GRAVITY_PORT_DOWN,
+ EL_SP_GRAVITY_PORT_LEFT,
- EL_SP_PORT2_UP,
+ EL_SP_GRAVITY_PORT_UP,
EL_SP_SNIKSNAK,
EL_SP_DISK_YELLOW,
EL_SP_TERMINAL,
EL_SP_DISK_RED,
- EL_SP_PORT_Y,
- EL_SP_PORT_X,
- EL_SP_PORT_XY,
+ EL_SP_PORT_VERTICAL,
+ EL_SP_PORT_HORIZONTAL,
+ EL_SP_PORT_ANY,
EL_SP_ELECTRON,
- EL_SP_BUG,
+ EL_SP_BUGGY_BASE,
EL_SP_CHIP_LEFT,
EL_SP_CHIP_RIGHT,
- EL_SP_HARD_BASE1,
- EL_SP_HARD_GREEN,
- EL_SP_HARD_BLUE,
- EL_SP_HARD_RED,
+ EL_SP_HARDWARE_BASE_1,
+ EL_SP_HARDWARE_GREEN,
+ EL_SP_HARDWARE_BLUE,
+ EL_SP_HARDWARE_RED,
- EL_SP_HARD_YELLOW,
- EL_SP_HARD_BASE2,
- EL_SP_HARD_BASE3,
- EL_SP_HARD_BASE4,
+ EL_SP_HARDWARE_YELLOW,
+ EL_SP_HARDWARE_BASE_2,
+ EL_SP_HARDWARE_BASE_3,
+ EL_SP_HARDWARE_BASE_4,
- EL_SP_HARD_BASE5,
- EL_SP_HARD_BASE6,
- EL_SP_CHIP_UPPER,
- EL_SP_CHIP_LOWER,
+ EL_SP_HARDWARE_BASE_5,
+ EL_SP_HARDWARE_BASE_6,
+ EL_SP_CHIP_TOP,
+ EL_SP_CHIP_BOTTOM,
+};
+static int num_editor_el_supaplex = SIZEOF_ARRAY_INT(editor_el_supaplex);
+static int editor_el_diamond_caves[] =
+{
EL_CHAR('D'),
EL_CHAR('I'),
EL_CHAR('A'),
EL_WALL_PEARL,
EL_WALL_CRYSTAL,
- EL_BELT1_LEFT,
- EL_BELT1_MIDDLE,
- EL_BELT1_RIGHT,
- EL_BELT1_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_1_LEFT,
+ EL_CONVEYOR_BELT_1_MIDDLE,
+ EL_CONVEYOR_BELT_1_RIGHT,
+ EL_CONVEYOR_BELT_1_SWITCH_MIDDLE,
- EL_BELT2_LEFT,
- EL_BELT2_MIDDLE,
- EL_BELT2_RIGHT,
- EL_BELT2_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_2_LEFT,
+ EL_CONVEYOR_BELT_2_MIDDLE,
+ EL_CONVEYOR_BELT_2_RIGHT,
+ EL_CONVEYOR_BELT_2_SWITCH_MIDDLE,
- EL_BELT3_LEFT,
- EL_BELT3_MIDDLE,
- EL_BELT3_RIGHT,
- EL_BELT3_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_3_LEFT,
+ EL_CONVEYOR_BELT_3_MIDDLE,
+ EL_CONVEYOR_BELT_3_RIGHT,
+ EL_CONVEYOR_BELT_3_SWITCH_MIDDLE,
- EL_BELT4_LEFT,
- EL_BELT4_MIDDLE,
- EL_BELT4_RIGHT,
- EL_BELT4_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_4_LEFT,
+ EL_CONVEYOR_BELT_4_MIDDLE,
+ EL_CONVEYOR_BELT_4_RIGHT,
+ EL_CONVEYOR_BELT_4_SWITCH_MIDDLE,
- EL_BELT1_SWITCH_LEFT,
- EL_BELT2_SWITCH_LEFT,
- EL_BELT3_SWITCH_LEFT,
- EL_BELT4_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_1_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_2_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_3_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_4_SWITCH_LEFT,
- EL_BELT1_SWITCH_RIGHT,
- EL_BELT2_SWITCH_RIGHT,
- EL_BELT3_SWITCH_RIGHT,
- EL_BELT4_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_1_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_2_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_3_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_4_SWITCH_RIGHT,
EL_SWITCHGATE_OPEN,
EL_SWITCHGATE_CLOSED,
- EL_SWITCHGATE_SWITCH_1,
+ EL_SWITCHGATE_SWITCH_UP,
EL_ENVELOPE,
EL_TIMEGATE_CLOSED,
EL_TIMEGATE_OPEN,
- EL_TIMEGATE_SWITCH_OFF,
- EL_LEERRAUM,
+ EL_TIMEGATE_SWITCH,
+ EL_EMPTY,
EL_LANDMINE,
- EL_SAND_INVISIBLE,
- EL_STEEL_SLANTED,
- EL_LEERRAUM,
+ EL_INVISIBLE_SAND,
+ EL_STEELWALL_SLIPPERY,
+ EL_EMPTY,
EL_SIGN_EXCLAMATION,
EL_SIGN_STOP,
- EL_LIGHT_SWITCH_OFF,
- EL_LIGHT_SWITCH_ON,
+ EL_LIGHT_SWITCH,
+ EL_LIGHT_SWITCH_ACTIVE,
- EL_SHIELD_PASSIVE,
- EL_SHIELD_ACTIVE,
+ EL_SHIELD_NORMAL,
+ EL_SHIELD_DEADLY,
EL_EXTRA_TIME,
- EL_LEERRAUM,
+ EL_EMPTY,
+};
+static int num_editor_el_diamond_caves = SIZEOF_ARRAY_INT(editor_el_diamond_caves);
+static int editor_el_dx_boulderdash[] =
+{
EL_CHAR('D'),
EL_CHAR('X'),
EL_CHAR('-'),
EL_SPRING,
EL_TUBE_RIGHT_DOWN,
- EL_TUBE_HORIZ_DOWN,
+ EL_TUBE_HORIZONTAL_DOWN,
EL_TUBE_LEFT_DOWN,
EL_TUBE_HORIZONTAL,
- EL_TUBE_VERT_RIGHT,
- EL_TUBE_CROSS,
- EL_TUBE_VERT_LEFT,
+ EL_TUBE_VERTICAL_RIGHT,
+ EL_TUBE_ANY,
+ EL_TUBE_VERTICAL_LEFT,
EL_TUBE_VERTICAL,
EL_TUBE_RIGHT_UP,
- EL_TUBE_HORIZ_UP,
+ EL_TUBE_HORIZONTAL_UP,
EL_TUBE_LEFT_UP,
- EL_TRAP_INACTIVE,
+ EL_TRAP,
EL_DX_SUPABOMB,
- EL_LEERRAUM,
- EL_LEERRAUM,
-
- /*
- EL_CHAR('D'),
- EL_CHAR('Y'),
- EL_CHAR('N'),
- EL_CHAR('A'),
-
- EL_CHAR('B'),
- EL_CHAR('L'),
- EL_CHAR('A'),
- EL_CHAR('S'),
+ EL_EMPTY,
+ EL_EMPTY
+};
+static int num_editor_el_dx_boulderdash = SIZEOF_ARRAY_INT(editor_el_dx_boulderdash);
- EL_CHAR_MINUS,
+static int editor_el_chars[] =
+{
EL_CHAR('T'),
EL_CHAR('E'),
- EL_CHAR('R'),
- */
-
- EL_LEERRAUM,
- EL_LEERRAUM,
- EL_LEERRAUM,
- EL_LEERRAUM,
+ EL_CHAR('X'),
+ EL_CHAR('T'),
EL_CHAR(' '),
EL_CHAR('!'),
EL_CHAR('X'),
EL_CHAR('Y'),
EL_CHAR('Z'),
- EL_CHAR('Ä'),
+ EL_CHAR('['),
+
+ EL_CHAR('\\'),
+ EL_CHAR(']'),
+ EL_CHAR('^'),
+ EL_CHAR('_'),
+ EL_CHAR('©'),
+ EL_CHAR('Ä'),
EL_CHAR('Ö'),
EL_CHAR('Ü'),
- EL_CHAR('^'),
+
+ EL_CHAR('°'),
+ EL_CHAR('®'),
+ EL_CHAR(FONT_ASCII_CURSOR),
EL_CHAR(' ')
};
-int elements_in_list = sizeof(editor_element)/sizeof(int);
+static int num_editor_el_chars = SIZEOF_ARRAY_INT(editor_el_chars);
+
+static int editor_el_custom[] =
+{
+ EL_CHAR('C'),
+ EL_CHAR('U'),
+ EL_CHAR('S'),
+ EL_CHAR('-'),
+
+ EL_CHAR('T'),
+ EL_CHAR('O'),
+ EL_CHAR('M'),
+ EL_CHAR(' '),
+
+ EL_CHAR('E'),
+ EL_CHAR('L'),
+ EL_CHAR('E'),
+ EL_CHAR('M'),
+
+ EL_CHAR('E'),
+ EL_CHAR('N'),
+ EL_CHAR('T'),
+ EL_CHAR('S'),
+
+ EL_CUSTOM_START + 0,
+ EL_CUSTOM_START + 1,
+ EL_CUSTOM_START + 2,
+ EL_CUSTOM_START + 3,
+
+ EL_CUSTOM_START + 4,
+ EL_CUSTOM_START + 5,
+ EL_CUSTOM_START + 6,
+ EL_CUSTOM_START + 7,
+
+ EL_CUSTOM_START + 8,
+ EL_CUSTOM_START + 9,
+ EL_CUSTOM_START + 10,
+ EL_CUSTOM_START + 11,
+
+ EL_CUSTOM_START + 12,
+ EL_CUSTOM_START + 13,
+ EL_CUSTOM_START + 14,
+ EL_CUSTOM_START + 15,
+
+ EL_CUSTOM_START + 16,
+ EL_CUSTOM_START + 17,
+ EL_CUSTOM_START + 18,
+ EL_CUSTOM_START + 19,
+
+ EL_CUSTOM_START + 20,
+ EL_CUSTOM_START + 21,
+ EL_CUSTOM_START + 22,
+ EL_CUSTOM_START + 23,
+
+ EL_CUSTOM_START + 24,
+ EL_CUSTOM_START + 25,
+ EL_CUSTOM_START + 26,
+ EL_CUSTOM_START + 27,
+
+ EL_CUSTOM_START + 28,
+ EL_CUSTOM_START + 29,
+ EL_CUSTOM_START + 30,
+ EL_CUSTOM_START + 31,
+
+ EL_CUSTOM_START + 32,
+ EL_CUSTOM_START + 33,
+ EL_CUSTOM_START + 34,
+ EL_CUSTOM_START + 35,
+
+ EL_CUSTOM_START + 36,
+ EL_CUSTOM_START + 37,
+ EL_CUSTOM_START + 38,
+ EL_CUSTOM_START + 39,
+
+ EL_CUSTOM_START + 40,
+ EL_CUSTOM_START + 41,
+ EL_CUSTOM_START + 42,
+ EL_CUSTOM_START + 43,
+
+ EL_CUSTOM_START + 44,
+ EL_CUSTOM_START + 45,
+ EL_CUSTOM_START + 46,
+ EL_CUSTOM_START + 47,
+
+ EL_CUSTOM_START + 48,
+ EL_CUSTOM_START + 49,
+ EL_CUSTOM_START + 50,
+ EL_CUSTOM_START + 51,
+
+ EL_CUSTOM_START + 52,
+ EL_CUSTOM_START + 53,
+ EL_CUSTOM_START + 54,
+ EL_CUSTOM_START + 55,
+
+ EL_CUSTOM_START + 56,
+ EL_CUSTOM_START + 57,
+ EL_CUSTOM_START + 58,
+ EL_CUSTOM_START + 59,
+
+ EL_CUSTOM_START + 60,
+ EL_CUSTOM_START + 61,
+ EL_CUSTOM_START + 62,
+ EL_CUSTOM_START + 63,
+
+ EL_CUSTOM_START + 64,
+ EL_CUSTOM_START + 65,
+ EL_CUSTOM_START + 66,
+ EL_CUSTOM_START + 67,
+
+ EL_CUSTOM_START + 68,
+ EL_CUSTOM_START + 69,
+ EL_CUSTOM_START + 70,
+ EL_CUSTOM_START + 71,
+
+ EL_CUSTOM_START + 72,
+ EL_CUSTOM_START + 73,
+ EL_CUSTOM_START + 74,
+ EL_CUSTOM_START + 75,
+
+ EL_CUSTOM_START + 76,
+ EL_CUSTOM_START + 77,
+ EL_CUSTOM_START + 78,
+ EL_CUSTOM_START + 79,
+
+ EL_CUSTOM_START + 80,
+ EL_CUSTOM_START + 81,
+ EL_CUSTOM_START + 82,
+ EL_CUSTOM_START + 83,
+
+ EL_CUSTOM_START + 84,
+ EL_CUSTOM_START + 85,
+ EL_CUSTOM_START + 86,
+ EL_CUSTOM_START + 87,
+
+ EL_CUSTOM_START + 88,
+ EL_CUSTOM_START + 89,
+ EL_CUSTOM_START + 90,
+ EL_CUSTOM_START + 91,
+
+ EL_CUSTOM_START + 92,
+ EL_CUSTOM_START + 93,
+ EL_CUSTOM_START + 94,
+ EL_CUSTOM_START + 95,
+
+ EL_CUSTOM_START + 96,
+ EL_CUSTOM_START + 97,
+ EL_CUSTOM_START + 98,
+ EL_CUSTOM_START + 99,
+
+ EL_CUSTOM_START + 100,
+ EL_CUSTOM_START + 101,
+ EL_CUSTOM_START + 102,
+ EL_CUSTOM_START + 103,
+
+ EL_CUSTOM_START + 104,
+ EL_CUSTOM_START + 105,
+ EL_CUSTOM_START + 106,
+ EL_CUSTOM_START + 107,
+
+ EL_CUSTOM_START + 108,
+ EL_CUSTOM_START + 109,
+ EL_CUSTOM_START + 110,
+ EL_CUSTOM_START + 111,
+
+ EL_CUSTOM_START + 112,
+ EL_CUSTOM_START + 113,
+ EL_CUSTOM_START + 114,
+ EL_CUSTOM_START + 115,
+
+ EL_CUSTOM_START + 116,
+ EL_CUSTOM_START + 117,
+ EL_CUSTOM_START + 118,
+ EL_CUSTOM_START + 119,
+
+ EL_CUSTOM_START + 120,
+ EL_CUSTOM_START + 121,
+ EL_CUSTOM_START + 122,
+ EL_CUSTOM_START + 123,
+
+ EL_CUSTOM_START + 124,
+ EL_CUSTOM_START + 125,
+ EL_CUSTOM_START + 126,
+ EL_CUSTOM_START + 127
+};
+static int num_editor_el_custom = SIZEOF_ARRAY_INT(editor_el_custom);
+
+static int *editor_elements = NULL; /* dynamically allocated */
+static int num_editor_elements = 0; /* dynamically determined */
+
+static struct
+{
+ boolean *setup_value;
+ int *element_list;
+ int *element_list_size;
+
+ boolean last_setup_value;
+}
+editor_elements_info[] =
+{
+ { &setup.editor.el_boulderdash, editor_el_boulderdash,
+ &num_editor_el_boulderdash },
+ { &setup.editor.el_emerald_mine, editor_el_emerald_mine,
+ &num_editor_el_emerald_mine },
+ { &setup.editor.el_more, editor_el_more,
+ &num_editor_el_more },
+ { &setup.editor.el_sokoban, editor_el_sokoban,
+ &num_editor_el_sokoban },
+ { &setup.editor.el_supaplex, editor_el_supaplex,
+ &num_editor_el_supaplex },
+ { &setup.editor.el_diamond_caves, editor_el_diamond_caves,
+ &num_editor_el_diamond_caves },
+ { &setup.editor.el_dx_boulderdash, editor_el_dx_boulderdash,
+ &num_editor_el_dx_boulderdash },
+ { &setup.editor.el_chars, editor_el_chars,
+ &num_editor_el_chars },
+ { &setup.editor.el_custom, editor_el_custom,
+ &num_editor_el_custom },
+ { NULL, NULL,
+ NULL }
+};
+
+
+/*
+ -----------------------------------------------------------------------------
+ functions
+ -----------------------------------------------------------------------------
+*/
+
+static void ReinitializeElementList()
+{
+ int pos = 0;
+ int i, j;
+
+ if (editor_elements != NULL)
+ free(editor_elements);
+
+ num_editor_elements = 0;
+
+ /* determine size of element list */
+ for (i=0; editor_elements_info[i].setup_value != NULL; i++)
+ if (*editor_elements_info[i].setup_value)
+ num_editor_elements += *editor_elements_info[i].element_list_size;
+
+ if (num_editor_elements < ED_NUM_ELEMENTLIST_BUTTONS)
+ {
+ /* workaround: offer at least as many elements as element buttons exist */
+ int list_nr = 1; /* see above: editor_elements_info for Emerald Mine */
+
+ *editor_elements_info[list_nr].setup_value = TRUE;
+ num_editor_elements += *editor_elements_info[list_nr].element_list_size;
+ }
+
+ editor_elements = checked_malloc(num_editor_elements * sizeof(int));
+
+ /* fill element list */
+ for (i=0; editor_elements_info[i].setup_value != NULL; i++)
+ if (*editor_elements_info[i].setup_value)
+ for (j=0; j<*editor_elements_info[i].element_list_size; j++)
+ editor_elements[pos++] = editor_elements_info[i].element_list[j];
+}
+
+static void ReinitializeElementListButtons()
+{
+ static boolean initialization_needed = TRUE;
+ int i;
+
+ if (!initialization_needed) /* check if editor element setup has changed */
+ for (i=0; editor_elements_info[i].setup_value != NULL; i++)
+ if (editor_elements_info[i].last_setup_value !=
+ *editor_elements_info[i].setup_value)
+ initialization_needed = TRUE;
+
+ if (!initialization_needed)
+ return;
+
+ FreeLevelEditorGadgets();
+ CreateLevelEditorGadgets();
+
+ /* store current setup values for next invocation of this function */
+ for (i=0; editor_elements_info[i].setup_value != NULL; i++)
+ editor_elements_info[i].last_setup_value =
+ *editor_elements_info[i].setup_value;
+
+ initialization_needed = FALSE;
+}
+
+static int getMaxInfoTextLength()
+{
+ return (SXSIZE / getFontWidth(FONT_TEXT_2));
+}
+
+static int getFullTextWidth(char *text)
+{
+ if (text == NULL)
+ return 0;
+
+ return (strlen(text) * getFontWidth(FONT_TEXT_1) + ED_GADGET_TEXT_DISTANCE);
+}
+
+static int getRightGadgetBorder(struct GadgetInfo *gi, char *text)
+{
+ return (gi->x + gi->width + getFullTextWidth(text));
+}
static char *getElementInfoText(int element)
{
- char *info_text = "unknown";
+ char *info_text = NULL;
+
+ if (element < NUM_FILE_ELEMENTS)
+ {
+ if (strlen(element_info[element].description) > 0)
+ info_text = element_info[element].description;
+ else if (element_info[element].custom_description != NULL)
+ info_text = element_info[element].custom_description;
+ else if (element_info[element].editor_description != NULL)
+ info_text = element_info[element].editor_description;
+ }
+
+ if (info_text == NULL)
+ {
+ info_text = "unknown";
- if (element < NUM_LEVEL_ELEMENTS)
- info_text = element_info[element].editor_description;
- else
Error(ERR_WARN, "no element description for element %d", element);
+ }
return info_text;
}
static void CreateControlButtons()
{
- Bitmap *gd_bitmap = pix[PIX_DOOR];
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
struct GadgetInfo *gi;
unsigned long event_mask;
int i;
y += DY;
width = ED_SCROLLBUTTON2_XSIZE;
height = ED_SCROLLBUTTON2_YSIZE;
- gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[i].xpos;
- gd_y1 = DOOR_GFX_PAGEY1 + scrollbutton_info[i].ypos;
+ gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[i].gd_x;
+ gd_y1 = DOOR_GFX_PAGEY1 + scrollbutton_info[i].gd_y;
gd_x2 = gd_x1 - ED_SCROLLBUTTON2_XSIZE;
gd_y2 = gd_y1;
}
y += SY;
width = ED_SCROLLBUTTON_XSIZE;
height = ED_SCROLLBUTTON_YSIZE;
- gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[i].xpos;
- gd_y1 = DOOR_GFX_PAGEY1 + scrollbutton_info[i].ypos;
+ gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[i].gd_x;
+ gd_y1 = DOOR_GFX_PAGEY1 + scrollbutton_info[i].gd_y;
gd_x2 = gd_x1 - ED_SCROLLBUTTON_XSIZE;
gd_y2 = gd_y1;
}
int x = i % ED_ELEMENTLIST_BUTTONS_HORIZ;
int y = i / ED_ELEMENTLIST_BUTTONS_HORIZ;
int id = GADGET_ID_ELEMENTLIST_FIRST + i;
+ int element = editor_elements[i];
event_mask = GD_EVENT_RELEASED;
gd_x2 = DOOR_GFX_PAGEX6 + ED_ELEMENTLIST_XPOS;
gd_y = DOOR_GFX_PAGEY1 + ED_ELEMENTLIST_YPOS;
- getMiniGraphicSource(el2gfx(editor_element[i]),
- &deco_bitmap, &deco_x, &deco_y);
+ getMiniGraphicSource(el2edimg(element), &deco_bitmap, &deco_x, &deco_y);
deco_xpos = (ED_ELEMENTLIST_XSIZE - MINI_TILEX) / 2;
deco_ypos = (ED_ELEMENTLIST_YSIZE - MINI_TILEY) / 2;
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
- GDI_INFO_TEXT, getElementInfoText(editor_element[i]),
+ GDI_INFO_TEXT, getElementInfoText(element),
GDI_X, DX + gd_xoffset,
GDI_Y, DY + gd_yoffset,
GDI_WIDTH, ED_ELEMENTLIST_XSIZE,
static void CreateCounterButtons()
{
+ int max_infotext_len = getMaxInfoTextLength();
int i;
for (i=0; i<ED_NUM_COUNTERBUTTONS; i++)
{
int j;
- int xpos = SX + counterbutton_info[i].x; /* xpos of down count button */
- int ypos = SY + counterbutton_info[i].y;
+ int x = SX + counterbutton_info[i].x; /* down count button */
+ int y = SY + counterbutton_info[i].y;
+
+ /* determine horizontal position to the right of specified gadget */
+ if (counterbutton_info[i].gadget_id_align != GADGET_ID_NONE)
+ x = (right_gadget_border[counterbutton_info[i].gadget_id_align] +
+ ED_GADGET_TEXT_DISTANCE);
+
+ /* determine horizontal offset for leading text */
+ if (counterbutton_info[i].text_left != NULL)
+ x += (getFontWidth(FONT_TEXT_1) * strlen(counterbutton_info[i].text_left)
+ + ED_GADGET_TEXT_DISTANCE);
for (j=0; j<2; j++)
{
- Bitmap *gd_bitmap = pix[PIX_DOOR];
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
struct GadgetInfo *gi;
int id = (j == 0 ?
counterbutton_info[i].gadget_id_down :
int gd_x, gd_x1, gd_x2, gd_y;
int x_size, y_size;
unsigned long event_mask;
- char infotext[MAX_INFOTEXT_LEN + 1];
+ char infotext[max_infotext_len + 1];
event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED;
event_mask |= GD_EVENT_RELEASED;
if (j == 1)
- xpos += 2 * ED_GADGET_DISTANCE;
- ypos += ED_GADGET_DISTANCE;
+ x += 2 * ED_GADGET_DISTANCE;
+ y += ED_GADGET_DISTANCE;
- gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[sid].xpos;
+ gd_x1 = DOOR_GFX_PAGEX8 + scrollbutton_info[sid].gd_x;
gd_x2 = gd_x1 - ED_SCROLLBUTTON_XSIZE;
- gd_y = DOOR_GFX_PAGEY1 + scrollbutton_info[sid].ypos;
+ gd_y = DOOR_GFX_PAGEY1 + scrollbutton_info[sid].gd_y;
x_size = ED_SCROLLBUTTON_XSIZE;
y_size = ED_SCROLLBUTTON_YSIZE;
}
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
GDI_INFO_TEXT, infotext,
- GDI_X, xpos,
- GDI_Y, ypos,
+ GDI_X, x,
+ GDI_Y, y,
GDI_WIDTH, x_size,
GDI_HEIGHT, y_size,
GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
Error(ERR_EXIT, "cannot create gadget");
level_editor_gadget[id] = gi;
- xpos += gi->width + ED_GADGET_DISTANCE; /* xpos of text count button */
+ right_gadget_border[id] =
+ getRightGadgetBorder(gi, counterbutton_info[i].text_right);
+
+ x += gi->width + ED_GADGET_DISTANCE; /* text count button */
if (j == 0)
{
- int font_type = FC_YELLOW;
+ int font_type = FONT_INPUT_1;
+ int font_type_active = FONT_INPUT_1_ACTIVE;
int gd_width = ED_WIN_COUNT_XSIZE;
id = counterbutton_info[i].gadget_id_text;
if (i == ED_COUNTER_ID_SELECT_LEVEL)
{
- font_type = FC_SPECIAL3;
+ font_type = FONT_LEVEL_NUMBER;
+ font_type_active = FONT_LEVEL_NUMBER;
- xpos += 2 * ED_GADGET_DISTANCE;
- ypos -= ED_GADGET_DISTANCE;
+ x += 2 * ED_GADGET_DISTANCE;
+ y -= ED_GADGET_DISTANCE;
gd_x = DOOR_GFX_PAGEX6 + ED_WIN_COUNT2_XPOS;
gd_y = DOOR_GFX_PAGEY1 + ED_WIN_COUNT2_YPOS;
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
GDI_INFO_TEXT, "enter counter value",
- GDI_X, xpos,
- GDI_Y, ypos,
+ GDI_X, x,
+ GDI_Y, y,
GDI_TYPE, GD_TYPE_TEXTINPUT_NUMERIC,
GDI_NUMBER_VALUE, 0,
GDI_NUMBER_MIN, counterbutton_info[i].min_value,
GDI_NUMBER_MAX, counterbutton_info[i].max_value,
GDI_TEXT_SIZE, 3,
GDI_TEXT_FONT, font_type,
+ GDI_TEXT_FONT_ACTIVE, font_type_active,
GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y,
GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y,
- GDI_BORDER_SIZE, ED_BORDER_SIZE,
- GDI_TEXTINPUT_DESIGN_WIDTH, gd_width,
+ GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
+ GDI_DESIGN_WIDTH, gd_width,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
GDI_CALLBACK_ACTION, HandleCounterButtons,
Error(ERR_EXIT, "cannot create gadget");
level_editor_gadget[id] = gi;
- xpos += gi->width + ED_GADGET_DISTANCE; /* xpos of up count button */
+ right_gadget_border[id] =
+ getRightGadgetBorder(gi, counterbutton_info[i].text_right);
+
+ x += gi->width + ED_GADGET_DISTANCE; /* up count button */
}
}
}
static void CreateDrawingAreas()
{
- struct GadgetInfo *gi;
- unsigned long event_mask;
- int id;
int i;
- event_mask =
- GD_EVENT_PRESSED | GD_EVENT_RELEASED | GD_EVENT_MOVING |
- GD_EVENT_OFF_BORDERS;
-
- /* one for the level drawing area ... */
- id = GADGET_ID_DRAWING_LEVEL;
- gi = CreateGadget(GDI_CUSTOM_ID, id,
- GDI_X, SX,
- GDI_Y, SY,
- GDI_TYPE, GD_TYPE_DRAWING_AREA,
- GDI_AREA_SIZE, ed_fieldx, ed_fieldy,
- GDI_ITEM_SIZE, MINI_TILEX, MINI_TILEY,
- GDI_EVENT_MASK, event_mask,
- GDI_CALLBACK_INFO, HandleDrawingAreaInfo,
- GDI_CALLBACK_ACTION, HandleDrawingAreas,
- GDI_END);
-
- if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
-
- level_editor_gadget[id] = gi;
-
- /* ... up to eight areas for element content ... */
- for (i=0; i<MAX_ELEMENT_CONTENTS; i++)
+ for (i=0; i<ED_NUM_DRAWING_AREAS; i++)
{
- int gx = SX + ED_AREA_ELEM_CONTENT_XPOS + 5 * (i % 4) * MINI_TILEX;
- int gy = SX + ED_AREA_ELEM_CONTENT_YPOS + 6 * (i / 4) * MINI_TILEY;
+ struct GadgetInfo *gi;
+ unsigned long event_mask;
+ int id = drawingarea_info[i].gadget_id;
+ int x = SX + drawingarea_info[i].x;
+ int y = SY + drawingarea_info[i].y;
+ int area_xsize = drawingarea_info[i].area_xsize;
+ int area_ysize = drawingarea_info[i].area_ysize;
+
+ event_mask =
+ GD_EVENT_PRESSED | GD_EVENT_RELEASED | GD_EVENT_MOVING |
+ GD_EVENT_OFF_BORDERS;
+
+ /* determine horizontal position to the right of specified gadget */
+ if (drawingarea_info[i].gadget_id_align != GADGET_ID_NONE)
+ x = (right_gadget_border[drawingarea_info[i].gadget_id_align] +
+ ED_GADGET_TEXT_DISTANCE + MINI_TILEX / 2);
+
+ /* determine horizontal offset for leading text */
+ if (drawingarea_info[i].text_left != NULL)
+ x += (getFontWidth(FONT_TEXT_1) * strlen(drawingarea_info[i].text_left) +
+ ED_GADGET_TEXT_DISTANCE + MINI_TILEX / 2);
- id = GADGET_ID_ELEM_CONTENT_0 + i;
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
- GDI_X, gx,
- GDI_Y, gy,
- GDI_WIDTH, 3 * MINI_TILEX,
- GDI_HEIGHT, 3 * MINI_TILEY,
+ GDI_X, x,
+ GDI_Y, y,
GDI_TYPE, GD_TYPE_DRAWING_AREA,
+ GDI_AREA_SIZE, area_xsize, area_ysize,
GDI_ITEM_SIZE, MINI_TILEX, MINI_TILEY,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleDrawingAreaInfo,
Error(ERR_EXIT, "cannot create gadget");
level_editor_gadget[id] = gi;
+ right_gadget_border[id] =
+ getRightGadgetBorder(gi, drawingarea_info[i].text_right);
}
-
- /* ... one for the amoeba content */
- id = GADGET_ID_AMOEBA_CONTENT;
- gi = CreateGadget(GDI_CUSTOM_ID, id,
- GDI_X, SX + ED_AREA_ELEM_CONTENT_XPOS,
- GDI_Y, SY + ED_AREA_ELEM_CONTENT_YPOS,
- GDI_WIDTH, MINI_TILEX,
- GDI_HEIGHT, MINI_TILEY,
- GDI_TYPE, GD_TYPE_DRAWING_AREA,
- GDI_ITEM_SIZE, MINI_TILEX, MINI_TILEY,
- GDI_EVENT_MASK, event_mask,
- GDI_CALLBACK_INFO, HandleDrawingAreaInfo,
- GDI_CALLBACK_ACTION, HandleDrawingAreas,
- GDI_END);
-
- if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
-
- level_editor_gadget[id] = gi;
-
- /* ... and one for random placement background restrictions */
-
- id = GADGET_ID_RANDOM_BACKGROUND;
- gi = CreateGadget(GDI_CUSTOM_ID, id,
- GDI_X, SX + ED_AREA_RANDOM_BACKGROUND_XPOS,
- GDI_Y, SY + ED_AREA_RANDOM_BACKGROUND_YPOS,
- GDI_WIDTH, MINI_TILEX,
- GDI_HEIGHT, MINI_TILEY,
- GDI_TYPE, GD_TYPE_DRAWING_AREA,
- GDI_ITEM_SIZE, MINI_TILEX, MINI_TILEY,
- GDI_EVENT_MASK, event_mask,
- GDI_CALLBACK_INFO, HandleDrawingAreaInfo,
- GDI_CALLBACK_ACTION, HandleDrawingAreas,
- GDI_END);
-
- if (gi == NULL)
- Error(ERR_EXIT, "cannot create gadget");
-
- level_editor_gadget[id] = gi;
}
static void CreateTextInputGadgets()
{
+ int max_infotext_len = getMaxInfoTextLength();
int i;
for (i=0; i<ED_NUM_TEXTINPUT; i++)
{
- Bitmap *gd_bitmap = pix[PIX_DOOR];
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
int gd_x, gd_y;
struct GadgetInfo *gi;
unsigned long event_mask;
- char infotext[1024];
+ char infotext[MAX_OUTPUT_LINESIZE + 1];
int id = textinput_info[i].gadget_id;
event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING;
gd_y = DOOR_GFX_PAGEY1 + ED_WIN_COUNT_YPOS;
sprintf(infotext, "Enter %s", textinput_info[i].infotext);
- infotext[MAX_INFOTEXT_LEN] = '\0';
+ infotext[max_infotext_len] = '\0';
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
GDI_TYPE, GD_TYPE_TEXTINPUT_ALPHANUMERIC,
GDI_TEXT_VALUE, textinput_info[i].value,
GDI_TEXT_SIZE, textinput_info[i].size,
- GDI_TEXT_FONT, FC_YELLOW,
+ GDI_TEXT_FONT, FONT_INPUT_1,
+ GDI_TEXT_FONT_ACTIVE, FONT_INPUT_1_ACTIVE,
GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y,
GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y,
- GDI_BORDER_SIZE, ED_BORDER_SIZE,
- GDI_TEXTINPUT_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
+ GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
+ GDI_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
GDI_CALLBACK_ACTION, HandleTextInputGadgets,
}
}
-static void CreateScrollbarGadgets()
+static void CreateSelectboxGadgets()
{
- int i;
+ int max_infotext_len = getMaxInfoTextLength();
+ int i, j;
- for (i=0; i<ED_NUM_SCROLLBARS; i++)
+ for (i=0; i<ED_NUM_SELECTBOX; i++)
{
- int id = scrollbar_info[i].gadget_id;
- Bitmap *gd_bitmap = pix[PIX_DOOR];
- int gd_x1, gd_x2, gd_y1, gd_y2;
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ int gd_x, gd_y;
struct GadgetInfo *gi;
- int items_max, items_visible, item_position;
unsigned long event_mask;
+ char infotext[MAX_OUTPUT_LINESIZE + 1];
+ int id = selectbox_info[i].gadget_id;
+ int x = SX + selectbox_info[i].x;
+ int y = SY + selectbox_info[i].y;
- if (i == ED_SCROLLBAR_ID_LIST_VERTICAL)
- {
- items_max = elements_in_list / ED_ELEMENTLIST_BUTTONS_HORIZ;
- items_visible = ED_ELEMENTLIST_BUTTONS_VERT;
- item_position = 0;
- }
- else /* drawing area scrollbars */
+ if (selectbox_info[i].size == -1) /* dynamically determine size */
{
- if (scrollbar_info[i].type == GD_TYPE_SCROLLBAR_HORIZONTAL)
- {
- items_max = MAX(lev_fieldx + 2, ed_fieldx);
- items_visible = ed_fieldx;
- item_position = 0;
- }
- else
- {
- items_max = MAX(lev_fieldy + 2, ed_fieldy);
- items_visible = ed_fieldy;
- item_position = 0;
- }
+ /* (we cannot use -1 for uninitialized values if we directly compare
+ with results from strlen(), because the '<' and '>' operation will
+ implicitely cast -1 to an unsigned integer value!) */
+ selectbox_info[i].size = 0;
+
+ for (j=0; selectbox_info[i].options[j].text != NULL; j++)
+ if (strlen(selectbox_info[i].options[j].text) > selectbox_info[i].size)
+ selectbox_info[i].size = strlen(selectbox_info[i].options[j].text);
+
+ selectbox_info[i].size++; /* add one character empty space */
}
- event_mask = GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS;
+ event_mask = GD_EVENT_RELEASED |
+ GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING;
- gd_x1 = DOOR_GFX_PAGEX8 + scrollbar_info[i].xpos;
- gd_x2 = (gd_x1 - (scrollbar_info[i].type == GD_TYPE_SCROLLBAR_HORIZONTAL ?
- scrollbar_info[i].height : scrollbar_info[i].width));
- gd_y1 = DOOR_GFX_PAGEY1 + scrollbar_info[i].ypos;
- gd_y2 = DOOR_GFX_PAGEY1 + scrollbar_info[i].ypos;
+ gd_x = DOOR_GFX_PAGEX4 + ED_SELECTBOX_XPOS;
+ gd_y = DOOR_GFX_PAGEY1 + ED_SELECTBOX_YPOS;
+
+ /* determine horizontal position to the right of specified gadget */
+ if (selectbox_info[i].gadget_id_align != GADGET_ID_NONE)
+ x = (right_gadget_border[selectbox_info[i].gadget_id_align] +
+ ED_GADGET_TEXT_DISTANCE);
+
+ /* determine horizontal offset for leading text */
+ if (selectbox_info[i].text_left != NULL)
+ x += (getFontWidth(FONT_TEXT_1) * strlen(selectbox_info[i].text_left) +
+ ED_GADGET_TEXT_DISTANCE);
+
+ sprintf(infotext, "Select %s", selectbox_info[i].infotext);
+ infotext[max_infotext_len] = '\0';
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, infotext,
+ GDI_X, x,
+ GDI_Y, y,
+ GDI_TYPE, GD_TYPE_SELECTBOX,
+ GDI_SELECTBOX_OPTIONS, selectbox_info[i].options,
+ GDI_TEXT_SIZE, selectbox_info[i].size,
+ GDI_TEXT_FONT, FONT_INPUT_1,
+ GDI_TEXT_FONT_ACTIVE, FONT_INPUT_1_ACTIVE,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x, gd_y,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x, gd_y,
+ GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
+ GDI_BORDER_SIZE_SELECTBUTTON, ED_SELECTBOX_BUTTON_XSIZE,
+ GDI_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
+ GDI_CALLBACK_ACTION, HandleSelectboxGadgets,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+ right_gadget_border[id] =
+ getRightGadgetBorder(gi, selectbox_info[i].text_right);
+ }
+}
+
+static void CreateTextbuttonGadgets()
+{
+ int max_infotext_len = getMaxInfoTextLength();
+ int i;
+
+ for (i=0; i<ED_NUM_TEXTBUTTON; i++)
+ {
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ int gd_x1, gd_x2, gd_y1, gd_y2;
+ struct GadgetInfo *gi;
+ unsigned long event_mask;
+ char infotext[MAX_OUTPUT_LINESIZE + 1];
+ int id = textbutton_info[i].gadget_id;
+ int x = SX + textbutton_info[i].x;
+ int y = SY + textbutton_info[i].y;
+
+ if (textbutton_info[i].size == -1) /* dynamically determine size */
+ textbutton_info[i].size = strlen(textbutton_info[i].text);
+
+ event_mask = GD_EVENT_RELEASED;
+
+ if (id >= GADGET_ID_PROPERTIES_INFO && id <= GADGET_ID_PROPERTIES_ADVANCED)
+ {
+ gd_x1 = DOOR_GFX_PAGEX4 + ED_TEXTBUTTON_TAB_XPOS;
+ gd_x2 = DOOR_GFX_PAGEX3 + ED_TEXTBUTTON_TAB_XPOS;
+ gd_y1 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_TAB_YPOS;
+ gd_y2 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_TAB_INACTIVE_YPOS;
+ }
+ else
+ {
+ gd_x1 = DOOR_GFX_PAGEX4 + ED_TEXTBUTTON_XPOS;
+ gd_x2 = DOOR_GFX_PAGEX3 + ED_TEXTBUTTON_XPOS;
+ gd_y1 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_YPOS;
+ gd_y2 = DOOR_GFX_PAGEY1 + ED_TEXTBUTTON_INACTIVE_YPOS;
+ }
+
+ sprintf(infotext, "%s", textbutton_info[i].infotext);
+ infotext[max_infotext_len] = '\0';
+
+ /* determine horizontal position to the right of specified gadget */
+ if (textbutton_info[i].gadget_id_align != GADGET_ID_NONE)
+ x = (right_gadget_border[textbutton_info[i].gadget_id_align] +
+ ED_GADGET_TEXT_DISTANCE);
+
+ gi = CreateGadget(GDI_CUSTOM_ID, id,
+ GDI_CUSTOM_TYPE_ID, i,
+ GDI_INFO_TEXT, infotext,
+ GDI_X, x,
+ GDI_Y, y,
+ GDI_TYPE, GD_TYPE_TEXT_BUTTON,
+ GDI_TEXT_VALUE, textbutton_info[i].text,
+ GDI_TEXT_SIZE, textbutton_info[i].size,
+ GDI_TEXT_FONT, FONT_INPUT_2_ACTIVE,
+ GDI_TEXT_FONT_ACTIVE, FONT_INPUT_2,
+ GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y1,
+ GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y2,
+ GDI_BORDER_SIZE, ED_BORDER_TEXT_XSIZE, ED_BORDER_SIZE,
+ GDI_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
+ GDI_DECORATION_SHIFTING, 1, 1,
+ GDI_EVENT_MASK, event_mask,
+ GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
+ GDI_CALLBACK_ACTION, HandleTextbuttonGadgets,
+ GDI_END);
+
+ if (gi == NULL)
+ Error(ERR_EXIT, "cannot create gadget");
+
+ level_editor_gadget[id] = gi;
+ }
+}
+
+static void CreateScrollbarGadgets()
+{
+ int i;
+
+ for (i=0; i<ED_NUM_SCROLLBARS; i++)
+ {
+ int id = scrollbar_info[i].gadget_id;
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ int gd_x1, gd_x2, gd_y1, gd_y2;
+ struct GadgetInfo *gi;
+ int items_max, items_visible, item_position;
+ unsigned long event_mask;
+
+ if (i == ED_SCROLLBAR_ID_LIST_VERTICAL)
+ {
+ items_max = num_editor_elements / ED_ELEMENTLIST_BUTTONS_HORIZ;
+ items_visible = ED_ELEMENTLIST_BUTTONS_VERT;
+ item_position = element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ;
+ }
+ else /* drawing area scrollbars */
+ {
+ if (scrollbar_info[i].type == GD_TYPE_SCROLLBAR_HORIZONTAL)
+ {
+ items_max = MAX(lev_fieldx + 2, ed_fieldx);
+ items_visible = ed_fieldx;
+ item_position = 0;
+ }
+ else
+ {
+ items_max = MAX(lev_fieldy + 2, ed_fieldy);
+ items_visible = ed_fieldy;
+ item_position = 0;
+ }
+ }
+
+ event_mask = GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS;
+
+ gd_x1 = DOOR_GFX_PAGEX8 + scrollbar_info[i].gd_x;
+ gd_x2 = (gd_x1 - (scrollbar_info[i].type == GD_TYPE_SCROLLBAR_HORIZONTAL ?
+ scrollbar_info[i].height : scrollbar_info[i].width));
+ gd_y1 = DOOR_GFX_PAGEY1 + scrollbar_info[i].gd_y;
+ gd_y2 = DOOR_GFX_PAGEY1 + scrollbar_info[i].gd_y;
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
GDI_STATE, GD_BUTTON_UNPRESSED,
GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2,
- GDI_BORDER_SIZE, ED_BORDER_SIZE,
+ GDI_BORDER_SIZE, ED_BORDER_SIZE, ED_BORDER_SIZE,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
GDI_CALLBACK_ACTION, HandleControlButtons,
static void CreateCheckbuttonGadgets()
{
- Bitmap *gd_bitmap = pix[PIX_DOOR];
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
struct GadgetInfo *gi;
unsigned long event_mask;
int gd_x1, gd_x2, gd_x3, gd_x4, gd_y;
- boolean checked;
int i;
event_mask = GD_EVENT_PRESSED;
gd_x4 = DOOR_GFX_PAGEX3 + ED_CHECKBUTTON_CHECKED_XPOS;
gd_y = DOOR_GFX_PAGEY1 + ED_RADIOBUTTON_YPOS;
- for (i=0; i<ED_NUM_RADIOBUTTONS; i++)
+ for (i=0; i<ED_NUM_CHECKBUTTONS; i++)
{
- int id = radiobutton_info[i].gadget_id;
+ int id = checkbutton_info[i].gadget_id;
+ int x = SX + checkbutton_info[i].x;
+ int y = SY + checkbutton_info[i].y;
- checked =
- (*radiobutton_info[i].value == radiobutton_info[i].checked_value);
+ if (id == GADGET_ID_STICK_ELEMENT)
+ gd_y = DOOR_GFX_PAGEY1 + ED_STICKYBUTTON_YPOS;
+ else
+ gd_y = DOOR_GFX_PAGEY1 + ED_CHECKBUTTON_YPOS;
+
+ /* determine horizontal position to the right of specified gadget */
+ if (checkbutton_info[i].gadget_id_align != GADGET_ID_NONE)
+ x = (right_gadget_border[checkbutton_info[i].gadget_id_align] +
+ ED_GADGET_TEXT_DISTANCE);
+
+ /* determine horizontal offset for leading text */
+ if (checkbutton_info[i].text_left != NULL)
+ x += (getFontWidth(FONT_TEXT_1) * strlen(checkbutton_info[i].text_left) +
+ ED_GADGET_TEXT_DISTANCE);
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
- GDI_INFO_TEXT, radiobutton_info[i].infotext,
- GDI_X, SX + radiobutton_info[i].x,
- GDI_Y, SY + radiobutton_info[i].y,
+ GDI_INFO_TEXT, checkbutton_info[i].infotext,
+ GDI_X, x,
+ GDI_Y, y,
GDI_WIDTH, ED_CHECKBUTTON_XSIZE,
GDI_HEIGHT, ED_CHECKBUTTON_YSIZE,
- GDI_TYPE, GD_TYPE_RADIO_BUTTON,
- GDI_RADIO_NR, radiobutton_info[i].radio_button_nr,
- GDI_CHECKED, checked,
+ GDI_TYPE, GD_TYPE_CHECK_BUTTON,
+ GDI_CHECKED, *checkbutton_info[i].value,
GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x3, gd_y,
GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x4, gd_y,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
- GDI_CALLBACK_ACTION, HandleRadiobuttons,
+ GDI_CALLBACK_ACTION, HandleCheckbuttons,
GDI_END);
if (gi == NULL)
Error(ERR_EXIT, "cannot create gadget");
level_editor_gadget[id] = gi;
+ right_gadget_border[id] =
+ getRightGadgetBorder(gi, checkbutton_info[i].text_right);
}
+}
- for (i=0; i<ED_NUM_CHECKBUTTONS; i++)
+static void CreateRadiobuttonGadgets()
+{
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ struct GadgetInfo *gi;
+ unsigned long event_mask;
+ int gd_x1, gd_x2, gd_x3, gd_x4, gd_y;
+ int i;
+
+ event_mask = GD_EVENT_PRESSED;
+
+ gd_x1 = DOOR_GFX_PAGEX4 + ED_CHECKBUTTON_UNCHECKED_XPOS;
+ gd_x2 = DOOR_GFX_PAGEX3 + ED_CHECKBUTTON_UNCHECKED_XPOS;
+ gd_x3 = DOOR_GFX_PAGEX4 + ED_CHECKBUTTON_CHECKED_XPOS;
+ gd_x4 = DOOR_GFX_PAGEX3 + ED_CHECKBUTTON_CHECKED_XPOS;
+ gd_y = DOOR_GFX_PAGEY1 + ED_RADIOBUTTON_YPOS;
+
+ for (i=0; i<ED_NUM_RADIOBUTTONS; i++)
{
- int id = checkbutton_info[i].gadget_id;
+ int id = radiobutton_info[i].gadget_id;
+ int x = SX + radiobutton_info[i].x;
+ int y = SY + radiobutton_info[i].y;
- if (id == GADGET_ID_STICK_ELEMENT)
- gd_y = DOOR_GFX_PAGEY1 + ED_STICKYBUTTON_YPOS;
- else
- gd_y = DOOR_GFX_PAGEY1 + ED_CHECKBUTTON_YPOS;
+ int checked =
+ (*radiobutton_info[i].value == radiobutton_info[i].checked_value);
+
+ /* determine horizontal position to the right of specified gadget */
+ if (radiobutton_info[i].gadget_id_align != GADGET_ID_NONE)
+ x = (right_gadget_border[radiobutton_info[i].gadget_id_align] +
+ ED_GADGET_TEXT_DISTANCE);
+
+ /* determine horizontal offset for leading text */
+ if (radiobutton_info[i].text_left != NULL)
+ x += (getFontWidth(FONT_TEXT_1) * strlen(radiobutton_info[i].text_left) +
+ ED_GADGET_TEXT_DISTANCE);
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
- GDI_INFO_TEXT, checkbutton_info[i].infotext,
- GDI_X, SX + checkbutton_info[i].x,
- GDI_Y, SY + checkbutton_info[i].y,
+ GDI_INFO_TEXT, radiobutton_info[i].infotext,
+ GDI_X, x,
+ GDI_Y, y,
GDI_WIDTH, ED_CHECKBUTTON_XSIZE,
GDI_HEIGHT, ED_CHECKBUTTON_YSIZE,
- GDI_TYPE, GD_TYPE_CHECK_BUTTON,
- GDI_CHECKED, *checkbutton_info[i].value,
+ GDI_TYPE, GD_TYPE_RADIO_BUTTON,
+ GDI_RADIO_NR, radiobutton_info[i].radio_button_nr,
+ GDI_CHECKED, checked,
GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x3, gd_y,
GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x4, gd_y,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
- GDI_CALLBACK_ACTION, HandleCheckbuttons,
+ GDI_CALLBACK_ACTION, HandleRadiobuttons,
GDI_END);
if (gi == NULL)
Error(ERR_EXIT, "cannot create gadget");
level_editor_gadget[id] = gi;
+ right_gadget_border[id] =
+ getRightGadgetBorder(gi, radiobutton_info[i].text_right);
}
}
void CreateLevelEditorGadgets()
{
+ int old_game_status = game_status;
+
+ /* setting 'game_status' is needed to get the right fonts for the editor */
+ game_status = GAME_MODE_EDITOR;
+
+ ReinitializeElementList();
+
CreateControlButtons();
- CreateCounterButtons();
- CreateDrawingAreas();
- CreateTextInputGadgets();
CreateScrollbarGadgets();
+
+ /* order of function calls is important because of cross-references */
CreateCheckbuttonGadgets();
+ CreateCounterButtons();
+ CreateRadiobuttonGadgets();
+ CreateTextInputGadgets();
+ CreateTextbuttonGadgets();
+ CreateSelectboxGadgets();
+ CreateDrawingAreas();
+
+ game_status = old_game_status;
+}
+
+void FreeLevelEditorGadgets()
+{
+ int i;
+
+ for (i=0; i<NUM_EDITOR_GADGETS; i++)
+ FreeGadget(level_editor_gadget[i]);
}
static void MapCounterButtons(int id)
{
+ int gadget_id_down = counterbutton_info[id].gadget_id_down;
+ int gadget_id_up = counterbutton_info[id].gadget_id_up;
+ struct GadgetInfo *gi_down = level_editor_gadget[gadget_id_down];
+ struct GadgetInfo *gi_up = level_editor_gadget[gadget_id_up];
+#if 0
+ char infotext[MAX_OUTPUT_LINESIZE + 1];
+ int max_infotext_len = getMaxInfoTextLength();
+ int xoffset_left = 0;
+ int yoffset_left = ED_BORDER_SIZE;
+ int xoffset_right = getCounterGadgetWidth();
+ int yoffset_right = ED_BORDER_SIZE;
+#else
+ int xoffset_left = getFullTextWidth(counterbutton_info[id].text_left);
+ int xoffset_right = ED_GADGET_TEXT_DISTANCE;
+ int yoffset_above = MINI_TILEX + ED_GADGET_DISTANCE;
+ int yoffset = ED_BORDER_SIZE;
+ int x_left = gi_down->x - xoffset_left;
+ int x_right = gi_up->x + gi_up->width + xoffset_right;
+ int y_above = gi_down->y - yoffset_above;
+ int x = gi_down->x;
+ int y = gi_up->y + yoffset;
+#endif
+
+ if (counterbutton_info[id].text_above)
+ DrawText(x, y_above, counterbutton_info[id].text_above, FONT_TEXT_1);
+
+ if (counterbutton_info[id].text_left)
+ DrawText(x_left, y, counterbutton_info[id].text_left, FONT_TEXT_1);
+
+ if (counterbutton_info[id].text_right)
+ DrawText(x_right, y, counterbutton_info[id].text_right, FONT_TEXT_1);
+
+ ModifyEditorCounter(id, *counterbutton_info[id].value);
+
MapGadget(level_editor_gadget[counterbutton_info[id].gadget_id_down]);
MapGadget(level_editor_gadget[counterbutton_info[id].gadget_id_text]);
MapGadget(level_editor_gadget[counterbutton_info[id].gadget_id_up]);
ModifyEditorCounterLimits(counter_id,
leveldir_current->first_level,
leveldir_current->last_level);
- ModifyEditorCounter(counter_id, *counterbutton_info[counter_id].value);
MapCounterButtons(counter_id);
}
static void MapDrawingArea(int id)
{
- MapGadget(level_editor_gadget[id]);
+ MapGadget(level_editor_gadget[drawingarea_info[id].gadget_id]);
}
static void MapTextInputGadget(int id)
{
+ char infotext[MAX_OUTPUT_LINESIZE + 1];
+ int max_infotext_len = getMaxInfoTextLength();
+ int xoffset_above = 0;
+ int yoffset_above = -(MINI_TILEX + ED_GADGET_DISTANCE);
+ int x = textinput_info[id].x + xoffset_above;
+ int y = textinput_info[id].y + yoffset_above;
+
+ if (textinput_info[id].infotext)
+ {
+ sprintf(infotext, "%s:", textinput_info[id].infotext);
+ infotext[max_infotext_len] = '\0';
+ DrawTextF(x, y, FONT_TEXT_1, infotext);
+ }
+
+ ModifyGadget(level_editor_gadget[textinput_info[id].gadget_id],
+ GDI_TEXT_VALUE, textinput_info[id].value, GDI_END);
+
MapGadget(level_editor_gadget[textinput_info[id].gadget_id]);
}
+static void MapSelectboxGadget(int id)
+{
+ struct GadgetInfo *gi = level_editor_gadget[selectbox_info[id].gadget_id];
+#if 0
+ int xoffset_left = 0;
+ int yoffset_left = ED_BORDER_SIZE;
+ int xoffset_right = ED_GADGET_TEXT_DISTANCE;
+ int yoffset_right = ED_BORDER_SIZE;
+ int x = selectbox_info[id].x + xoffset_left;
+ int y = selectbox_info[id].y + yoffset_left;
+#else
+ int xoffset_left = getFullTextWidth(selectbox_info[id].text_left);
+ int xoffset_right = ED_GADGET_TEXT_DISTANCE;
+ int yoffset = ED_BORDER_SIZE;
+ int x_left = gi->x - xoffset_left;
+ int x_right = gi->x + gi->width + xoffset_right;
+ int y = gi->y + yoffset;
+#endif
+
+ if (selectbox_info[id].text_left)
+ DrawText(x_left, y, selectbox_info[id].text_left, FONT_TEXT_1);
+
+ if (selectbox_info[id].text_right)
+ DrawText(x_right, y, selectbox_info[id].text_right, FONT_TEXT_1);
+
+ ModifyEditorSelectbox(id, *selectbox_info[id].value);
+
+ MapGadget(level_editor_gadget[selectbox_info[id].gadget_id]);
+}
+
+static void MapTextbuttonGadget(int id)
+{
+ MapGadget(level_editor_gadget[textbutton_info[id].gadget_id]);
+}
+
static void MapRadiobuttonGadget(int id)
{
+ struct GadgetInfo *gi = level_editor_gadget[radiobutton_info[id].gadget_id];
+#if 0
+ int xoffset_right = ED_XOFFSET_CHECKBOX;
+ int yoffset_right = ED_BORDER_SIZE;
+ int x = radiobutton_info[id].x + xoffset_right;
+ int y = radiobutton_info[id].y + yoffset_right;
+#else
+ int xoffset_left = getFullTextWidth(checkbutton_info[id].text_left);
+ int xoffset_right = ED_GADGET_TEXT_DISTANCE;
+ int yoffset = ED_BORDER_SIZE;
+ int x_left = gi->x - xoffset_left;
+ int x_right = gi->x + gi->width + xoffset_right;
+ int y = gi->y + yoffset;
+#endif
+ boolean checked =
+ (*radiobutton_info[id].value == radiobutton_info[id].checked_value);
+
+ if (radiobutton_info[id].text_left)
+ DrawText(x_left, y, radiobutton_info[id].text_left, FONT_TEXT_1);
+
+ if (radiobutton_info[id].text_right)
+ DrawText(x_right, y, radiobutton_info[id].text_right, FONT_TEXT_1);
+
+ ModifyGadget(level_editor_gadget[radiobutton_info[id].gadget_id],
+ GDI_CHECKED, checked, GDI_END);
+
MapGadget(level_editor_gadget[radiobutton_info[id].gadget_id]);
}
static void MapCheckbuttonGadget(int id)
{
+ struct GadgetInfo *gi = level_editor_gadget[checkbutton_info[id].gadget_id];
+#if 0
+ int xoffset_right = ED_XOFFSET_CHECKBOX;
+ int yoffset_right = ED_BORDER_SIZE;
+ int x = checkbutton_info[id].x + xoffset_right;
+ int y = checkbutton_info[id].y + yoffset_right;
+#else
+ int xoffset_left = getFullTextWidth(checkbutton_info[id].text_left);
+ int xoffset_right = ED_GADGET_TEXT_DISTANCE;
+ int yoffset = ED_BORDER_SIZE;
+ int x_left = gi->x - xoffset_left;
+ int x_right = gi->x + gi->width + xoffset_right;
+ int y = gi->y + yoffset;
+#endif
+
+ /* special case needed for "sticky" gadget */
+ ModifyGadget(level_editor_gadget[checkbutton_info[id].gadget_id],
+ GDI_CHECKED, *checkbutton_info[id].value,
+ GDI_Y, SY + checkbutton_info[id].y, GDI_END);
+ y = gi->y + yoffset;
+
+ if (checkbutton_info[id].text_left)
+ DrawText(x_left, y, checkbutton_info[id].text_left, FONT_TEXT_1);
+
+ if (checkbutton_info[id].text_right)
+ DrawText(x_right, y, checkbutton_info[id].text_right, FONT_TEXT_1);
+
MapGadget(level_editor_gadget[checkbutton_info[id].gadget_id]);
}
MapGadget(level_editor_gadget[scrollbar_info[i].gadget_id]);
}
- MapDrawingArea(GADGET_ID_DRAWING_LEVEL);
+ MapDrawingArea(ED_DRAWING_ID_DRAWING_LEVEL);
}
static void UnmapDrawingArea(int id)
static void DrawEditModeWindow()
{
+ ModifyEditorElementList();
+ RedrawDrawingElements();
+
if (edit_mode == ED_MODE_INFO)
DrawLevelInfoWindow();
else if (edit_mode == ED_MODE_PROPERTIES)
for(y=0; y<lev_fieldy; y++)
for(x=0; x<lev_fieldx; x++)
- if (Feld[x][y] != Ur[x][y])
+ if (Feld[x][y] != level.field[x][y])
level_changed = TRUE;
return level_changed;
for(y=0; y<lev_fieldy; y++)
for(x=0; x<lev_fieldx; x++)
- if (Feld[x][y] == EL_SPIELFIGUR ||
- Feld[x][y] == EL_SPIELER1 ||
+ if (Feld[x][y] == EL_PLAYER_1 ||
Feld[x][y] == EL_SP_MURPHY)
player_found = TRUE;
return player_found;
}
+static void CopyPlayfield(short src[MAX_LEV_FIELDX][MAX_LEV_FIELDY],
+ short dst[MAX_LEV_FIELDX][MAX_LEV_FIELDY])
+{
+ int x, y;
+
+ for(x=0; x<lev_fieldx; x++)
+ for(y=0; y<lev_fieldy; y++)
+ dst[x][y] = src[x][y];
+}
+
+static void CopyCustomElementPropertiesToEditor(int element)
+{
+ int i;
+
+ /* needed here to initialize combined element properties */
+ InitElementPropertiesEngine(level.game_version);
+
+ custom_element = element_info[element];
+
+ for (i=0; i < NUM_ELEMENT_PROPERTIES; i++)
+ custom_element_properties[i] = HAS_PROPERTY(element, i);
+
+ for (i=0; i < NUM_CHANGE_EVENTS; i++)
+ custom_element_change_events[i] = HAS_CHANGE_EVENT(element, i);
+
+ /* ---------- element settings: configure (custom elements) ------------- */
+
+ /* set accessible layer selectbox help value */
+ custom_element.access_type =
+ (IS_WALKABLE(element) ? EP_WALKABLE :
+ IS_PASSABLE(element) ? EP_PASSABLE :
+ custom_element.access_type);
+ custom_element.access_layer =
+ (IS_ACCESSIBLE_OVER(element) ? EP_ACCESSIBLE_OVER :
+ IS_ACCESSIBLE_INSIDE(element) ? EP_ACCESSIBLE_INSIDE :
+ IS_ACCESSIBLE_UNDER(element) ? EP_ACCESSIBLE_UNDER :
+ custom_element.access_layer);
+ custom_element_properties[EP_ACCESSIBLE] =
+ (IS_ACCESSIBLE_OVER(element) ||
+ IS_ACCESSIBLE_INSIDE(element) ||
+ IS_ACCESSIBLE_UNDER(element));
+
+ /* set walk-to-object action selectbox help value */
+ custom_element.walk_to_action =
+ (IS_DIGGABLE(element) ? EP_DIGGABLE :
+ IS_COLLECTIBLE(element) ? EP_COLLECTIBLE :
+ IS_PUSHABLE(element) ? EP_PUSHABLE :
+ custom_element.walk_to_action);
+ custom_element_properties[EP_WALK_TO_OBJECT] =
+ (IS_DIGGABLE(element) ||
+ IS_COLLECTIBLE(element) ||
+ IS_PUSHABLE(element));
+
+ /* set smash targets selectbox help value */
+ custom_element.smash_targets =
+ (CAN_SMASH_EVERYTHING(element) ? EP_CAN_SMASH_EVERYTHING :
+ CAN_SMASH_ENEMIES(element) ? EP_CAN_SMASH_ENEMIES :
+ CAN_SMASH_PLAYER(element) ? EP_CAN_SMASH_PLAYER :
+ custom_element.smash_targets);
+ custom_element_properties[EP_CAN_SMASH] =
+ (CAN_SMASH_EVERYTHING(element) ||
+ CAN_SMASH_ENEMIES(element) ||
+ CAN_SMASH_PLAYER(element));
+
+ /* set deadliness selectbox help value */
+ custom_element.deadliness =
+ (DONT_TOUCH(element) ? EP_DONT_TOUCH :
+ DONT_COLLIDE_WITH(element) ? EP_DONT_COLLIDE_WITH :
+ DONT_RUN_INTO(element) ? EP_DONT_RUN_INTO :
+ custom_element.deadliness);
+ custom_element_properties[EP_DEADLY] =
+ (DONT_TOUCH(element) ||
+ DONT_COLLIDE_WITH(element) ||
+ DONT_RUN_INTO(element));
+
+ /* set consistency selectbox help value */
+ custom_element.consistency =
+ (IS_INDESTRUCTIBLE(element) ? EP_INDESTRUCTIBLE :
+ CAN_EXPLODE(element) ? EP_CAN_EXPLODE :
+ custom_element.consistency);
+ custom_element_properties[EP_EXPLODE_RESULT] =
+ (IS_INDESTRUCTIBLE(element) ||
+ CAN_EXPLODE(element));
+
+ /* special case: sub-settings dependent from main setting */
+ if (CAN_EXPLODE_BY_FIRE(element))
+ custom_element.can_explode_by_fire = TRUE;
+ if (CAN_EXPLODE_SMASHED(element))
+ custom_element.can_explode_smashed = TRUE;
+ if (CAN_EXPLODE_IMPACT(element))
+ custom_element.can_explode_impact = TRUE;
+
+ /* ---------- element settings: advanced (custom elements) --------------- */
+
+ /* set change by player selectbox help value */
+ custom_element.change_player_action =
+ (HAS_CHANGE_EVENT(element, CE_PUSHED_BY_PLAYER) ? CE_PUSHED_BY_PLAYER :
+ HAS_CHANGE_EVENT(element, CE_PRESSED_BY_PLAYER) ? CE_PRESSED_BY_PLAYER :
+ HAS_CHANGE_EVENT(element, CE_TOUCHED_BY_PLAYER) ? CE_TOUCHED_BY_PLAYER :
+ custom_element.change_player_action);
+
+ /* set change by collision selectbox help value */
+ custom_element.change_collide_action =
+ (HAS_CHANGE_EVENT(element, CE_SMASHED) ? CE_SMASHED :
+ HAS_CHANGE_EVENT(element, CE_IMPACT) ? CE_IMPACT :
+ HAS_CHANGE_EVENT(element, CE_COLLISION) ? CE_COLLISION :
+ custom_element.change_collide_action);
+
+ /* set change by other element action selectbox help value */
+ custom_element.change_other_action =
+ (HAS_CHANGE_EVENT(element, CE_OTHER_GETS_COLLECTED) ? CE_OTHER_GETS_COLLECTED :
+ HAS_CHANGE_EVENT(element, CE_OTHER_GETS_PUSHED) ? CE_OTHER_GETS_PUSHED :
+ HAS_CHANGE_EVENT(element, CE_OTHER_GETS_PRESSED) ? CE_OTHER_GETS_PRESSED :
+ HAS_CHANGE_EVENT(element, CE_OTHER_GETS_TOUCHED) ? CE_OTHER_GETS_TOUCHED :
+ HAS_CHANGE_EVENT(element, CE_OTHER_IS_EXPLODING) ? CE_OTHER_IS_EXPLODING :
+ HAS_CHANGE_EVENT(element, CE_OTHER_IS_CHANGING) ? CE_OTHER_IS_CHANGING :
+ HAS_CHANGE_EVENT(element, CE_OTHER_IS_TOUCHING) ? CE_OTHER_IS_TOUCHING :
+ custom_element.change_other_action);
+}
+
+static void CopyCustomElementPropertiesToGame(int element)
+{
+ int i;
+ int access_type_and_layer;
+
+ if (level.use_custom_template)
+ {
+ if (Request("Copy and modify level tem- plate ?", REQ_ASK))
+ {
+ level.use_custom_template = FALSE;
+ ModifyGadget(level_editor_gadget[GADGET_ID_CUSTOM_USE_TEMPLATE],
+ GDI_CHECKED, FALSE, GDI_END);
+ }
+ else
+ {
+ LoadLevelTemplate(-1);
+
+ DrawEditModeWindow();
+ }
+ }
+
+ element_info[element] = custom_element;
+
+ /* ---------- element settings: configure (custom elements) ------------- */
+
+ /* set accessible property from checkbox and selectbox */
+ custom_element_properties[EP_WALKABLE_OVER] = FALSE;
+ custom_element_properties[EP_WALKABLE_INSIDE] = FALSE;
+ custom_element_properties[EP_WALKABLE_UNDER] = FALSE;
+ custom_element_properties[EP_PASSABLE_OVER] = FALSE;
+ custom_element_properties[EP_PASSABLE_INSIDE] = FALSE;
+ custom_element_properties[EP_PASSABLE_UNDER] = FALSE;
+ access_type_and_layer = ((custom_element.access_type == EP_WALKABLE ?
+ EP_WALKABLE_OVER : EP_PASSABLE_OVER) +
+ (custom_element.access_layer - EP_ACCESSIBLE_OVER));
+ custom_element_properties[access_type_and_layer] =
+ custom_element_properties[EP_ACCESSIBLE];
+
+ /* set walk-to-object property from checkbox and selectbox */
+ custom_element_properties[EP_DIGGABLE] = FALSE;
+ custom_element_properties[EP_COLLECTIBLE] = FALSE;
+ custom_element_properties[EP_PUSHABLE] = FALSE;
+ custom_element_properties[custom_element.walk_to_action] =
+ custom_element_properties[EP_WALK_TO_OBJECT];
+
+ /* set smash property from checkbox and selectbox */
+ custom_element_properties[EP_CAN_SMASH_PLAYER] = FALSE;
+ custom_element_properties[EP_CAN_SMASH_ENEMIES] = FALSE;
+ custom_element_properties[EP_CAN_SMASH_EVERYTHING] = FALSE;
+ custom_element_properties[custom_element.smash_targets] =
+ custom_element_properties[EP_CAN_SMASH];
+
+ /* set deadliness property from checkbox and selectbox */
+ custom_element_properties[EP_DONT_RUN_INTO] = FALSE;
+ custom_element_properties[EP_DONT_COLLIDE_WITH] = FALSE;
+ custom_element_properties[EP_DONT_TOUCH] = FALSE;
+ custom_element_properties[custom_element.deadliness] =
+ custom_element_properties[EP_DEADLY];
+
+ /* set consistency property from checkbox and selectbox */
+ custom_element_properties[EP_INDESTRUCTIBLE] = FALSE;
+ custom_element_properties[EP_CAN_EXPLODE] = FALSE;
+ custom_element_properties[EP_CAN_EXPLODE_BY_FIRE] = FALSE;
+ custom_element_properties[EP_CAN_EXPLODE_SMASHED] = FALSE;
+ custom_element_properties[EP_CAN_EXPLODE_IMPACT] = FALSE;
+ custom_element_properties[custom_element.consistency] =
+ custom_element_properties[EP_EXPLODE_RESULT];
+
+ /* special case: sub-settings dependent from main setting */
+ if (custom_element_properties[EP_CAN_EXPLODE])
+ {
+ custom_element_properties[EP_CAN_EXPLODE_BY_FIRE] =
+ custom_element.can_explode_by_fire;
+ custom_element_properties[EP_CAN_EXPLODE_SMASHED] =
+ custom_element.can_explode_smashed;
+ custom_element_properties[EP_CAN_EXPLODE_IMPACT] =
+ custom_element.can_explode_impact;
+ }
+
+ /* ---------- element settings: advanced (custom elements) --------------- */
+
+ /* set player change event from checkbox and selectbox */
+ custom_element_change_events[CE_TOUCHED_BY_PLAYER] = FALSE;
+ custom_element_change_events[CE_PRESSED_BY_PLAYER] = FALSE;
+ custom_element_change_events[CE_PUSHED_BY_PLAYER] = FALSE;
+ custom_element_change_events[custom_element.change_player_action] =
+ custom_element_change_events[CE_BY_PLAYER];
+
+ /* set collision change event from checkbox and selectbox */
+ custom_element_change_events[CE_COLLISION] = FALSE;
+ custom_element_change_events[CE_IMPACT] = FALSE;
+ custom_element_change_events[CE_SMASHED] = FALSE;
+ custom_element_change_events[custom_element.change_collide_action] =
+ custom_element_change_events[CE_BY_COLLISION];
+
+ /* set other element action change event from checkbox and selectbox */
+ custom_element_change_events[CE_OTHER_IS_TOUCHING] = FALSE;
+ custom_element_change_events[CE_OTHER_IS_CHANGING] = FALSE;
+ custom_element_change_events[CE_OTHER_IS_EXPLODING] = FALSE;
+ 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_COLLECTED] = FALSE;
+ custom_element_change_events[custom_element.change_other_action] =
+ custom_element_change_events[CE_BY_OTHER];
+
+ for (i=0; i < NUM_ELEMENT_PROPERTIES; i++)
+ SET_PROPERTY(element, i, custom_element_properties[i]);
+
+ for (i=0; i < NUM_CHANGE_EVENTS; i++)
+ SET_CHANGE_EVENT(element, i, custom_element_change_events[i]);
+
+ /* copy change events also to special level editor variable */
+ custom_element = element_info[element];
+}
+
void DrawLevelEd()
{
CloseDoor(DOOR_CLOSE_ALL);
if (level_editor_test_game)
{
- int x, y;
-
- for(x=0; x<lev_fieldx; x++)
- for(y=0; y<lev_fieldy; y++)
- Feld[x][y] = Ur[x][y];
-
- for(x=0; x<lev_fieldx; x++)
- for(y=0; y<lev_fieldy; y++)
- Ur[x][y] = FieldBackup[x][y];
+ CopyPlayfield(level.field, Feld);
+ CopyPlayfield(FieldBackup, level.field);
level_editor_test_game = FALSE;
}
else
{
edit_mode = ED_MODE_DRAWING;
+ edit_mode_properties = ED_MODE_PROPERTIES_INFO;
ResetUndoBuffer();
+
level_xpos = -1;
level_ypos = -1;
}
/* copy default editor door content to main double buffer */
- BlitBitmap(pix[PIX_DOOR], drawto,
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
DOOR_GFX_PAGEX6, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY);
+#if 0
/* draw mouse button brush elements */
- DrawMiniGraphicExt(drawto,
- DX + ED_WIN_MB_LEFT_XPOS, DY + ED_WIN_MB_LEFT_YPOS,
- el2gfx(new_element1));
- DrawMiniGraphicExt(drawto,
- DX + ED_WIN_MB_MIDDLE_XPOS, DY + ED_WIN_MB_MIDDLE_YPOS,
- el2gfx(new_element2));
- DrawMiniGraphicExt(drawto,
- DX + ED_WIN_MB_RIGHT_XPOS, DY + ED_WIN_MB_RIGHT_YPOS,
- el2gfx(new_element3));
+ RedrawDrawingElements();
+#endif
/* draw bigger door */
DrawSpecialEditorDoor();
/* draw new control window */
- BlitBitmap(pix[PIX_DOOR], drawto,
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
DOOR_GFX_PAGEX8, 236, EXSIZE, EYSIZE, EX, EY);
redraw_mask |= REDRAW_ALL;
+ ReinitializeElementListButtons(); /* only needed after setup changes */
+#if 0
+ ModifyEditorElementList(); /* may be needed for custom elements */
+#endif
+
+ UnmapTapeButtons();
MapControlButtons();
- /* copy actual editor door content to door double buffer for OpenDoor() */
- BlitBitmap(drawto, pix[PIX_DB_DOOR],
- DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
-
DrawEditModeWindow();
- /*
- FadeToFront();
- */
-
+ /* copy actual editor door content to door double buffer for OpenDoor() */
+ BlitBitmap(drawto, bitmap_db_door,
+ DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
OpenDoor(DOOR_OPEN_1);
-
- /*
- OpenDoor(DOOR_OPEN_1 | DOOR_OPEN_2);
- */
}
static void AdjustDrawingAreaGadgets()
GDI_SCROLLBAR_ITEM_POSITION, item_position, GDI_END);
}
-static void ModifyEditorTextInput(int textinput_id, char *new_text)
-{
- int gadget_id = textinput_info[textinput_id].gadget_id;
- struct GadgetInfo *gi = level_editor_gadget[gadget_id];
-
- ModifyGadget(gi, GDI_TEXT_VALUE, new_text, GDI_END);
-}
-
static void ModifyEditorCounter(int counter_id, int new_value)
{
int *counter_value = counterbutton_info[counter_id].value;
ModifyGadget(gi, GDI_NUMBER_MIN, min, GDI_NUMBER_MAX, max, GDI_END);
}
+static void ModifyEditorSelectbox(int selectbox_id, int new_value)
+{
+ int gadget_id = selectbox_info[selectbox_id].gadget_id;
+ struct GadgetInfo *gi = level_editor_gadget[gadget_id];
+ int new_index_value = 0;
+ int i;
+
+ for(i=0; selectbox_info[selectbox_id].options[i].text != NULL; i++)
+ if (selectbox_info[selectbox_id].options[i].value == new_value)
+ new_index_value = i;
+
+ *selectbox_info[selectbox_id].value =
+ selectbox_info[selectbox_id].options[new_index_value].value;
+
+ ModifyGadget(gi, GDI_SELECTBOX_INDEX, new_index_value, GDI_END);
+}
+
+static void ModifyEditorElementList()
+{
+ int i;
+
+ for (i=0; i<ED_NUM_ELEMENTLIST_BUTTONS; i++)
+ {
+ int gadget_id = GADGET_ID_ELEMENTLIST_FIRST + i;
+ struct GadgetInfo *gi = level_editor_gadget[gadget_id];
+ struct GadgetDesign *gd = &gi->deco.design;
+ int element = editor_elements[element_shift + i];
+
+ UnmapGadget(gi);
+ getMiniGraphicSource(el2edimg(element), &gd->bitmap, &gd->x, &gd->y);
+ ModifyGadget(gi, GDI_INFO_TEXT, getElementInfoText(element), GDI_END);
+ MapGadget(gi);
+ }
+}
+
static void PickDrawingElement(int button, int element)
{
if (button < 1 || button > 3)
new_element1 = element;
DrawMiniGraphicExt(drawto,
DX + ED_WIN_MB_LEFT_XPOS, DY + ED_WIN_MB_LEFT_YPOS,
- el2gfx(new_element1));
+ el2edimg(new_element1));
}
else if (button == 2)
{
new_element2 = element;
DrawMiniGraphicExt(drawto,
DX + ED_WIN_MB_MIDDLE_XPOS, DY + ED_WIN_MB_MIDDLE_YPOS,
- el2gfx(new_element2));
+ el2edimg(new_element2));
}
else
{
new_element3 = element;
DrawMiniGraphicExt(drawto,
DX + ED_WIN_MB_RIGHT_XPOS, DY + ED_WIN_MB_RIGHT_YPOS,
- el2gfx(new_element3));
+ el2edimg(new_element3));
}
redraw_mask |= REDRAW_DOOR_1;
}
+static void RedrawDrawingElements()
+{
+ PickDrawingElement(1, new_element1);
+ PickDrawingElement(2, new_element2);
+ PickDrawingElement(3, new_element3);
+}
+
static void DrawDrawingWindow()
{
+ stick_element_properties_window = FALSE;
+
+ SetMainBackgroundImage(IMG_UNDEFINED);
ClearWindow();
UnmapLevelEditorWindowGadgets();
+
AdjustDrawingAreaGadgets();
AdjustLevelScrollPosition();
AdjustEditorScrollbar(GADGET_ID_SCROLL_HORIZONTAL);
AdjustEditorScrollbar(GADGET_ID_SCROLL_VERTICAL);
+
DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
MapMainDrawingArea();
}
-static void DrawRandomPlacementBackgroundArea()
+static void DrawElementBorder(int dest_x, int dest_y, int width, int height,
+ boolean input)
{
- int area_x = ED_AREA_RANDOM_BACKGROUND_XPOS / MINI_TILEX;
- int area_y = ED_AREA_RANDOM_BACKGROUND_YPOS / MINI_TILEY;
- int area_sx = SX + ED_AREA_RANDOM_BACKGROUND_XPOS;
- int area_sy = SY + ED_AREA_RANDOM_BACKGROUND_YPOS;
+ int border_graphic =
+ (input ? IMG_EDITOR_ELEMENT_BORDER_INPUT : IMG_EDITOR_ELEMENT_BORDER);
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int num_mini_tilex = width / MINI_TILEX + 1;
+ int num_mini_tiley = width / MINI_TILEY + 1;
int x, y;
- ElementContent[0][0][0] = random_placement_background_element;
+ getMiniGraphicSource(border_graphic, &src_bitmap, &src_x, &src_y);
- /* draw decorative border for the object */
- for (y=0; y<2; y++)
- for (x=0; x<2; x++)
- DrawMiniElement(area_x + x, area_y + y, EL_ERDREICH);
+ for (y=0; y < num_mini_tiley; y++)
+ for (x=0; x < num_mini_tilex; x++)
+ BlitBitmap(src_bitmap, drawto, src_x, src_y, MINI_TILEX, MINI_TILEY,
+ dest_x - MINI_TILEX / 2 + x * MINI_TILEX,
+ dest_y - MINI_TILEY / 2 + y * MINI_TILEY);
- ClearRectangle(drawto,
- area_sx + MINI_TILEX/2 - 1, area_sy + MINI_TILEY/2 - 1,
- MINI_TILEX + 2, MINI_TILEY + 2);
+ ClearRectangle(drawto, dest_x - 1, dest_y - 1, width + 2, height + 2);
+}
- /* copy border to the right location */
- BlitBitmap(drawto, drawto,
- area_sx, area_sy, 3 * MINI_TILEX, 3 * MINI_TILEY,
- area_sx - MINI_TILEX/2, area_sy - MINI_TILEY/2);
+static void DrawRandomPlacementBackgroundArea()
+{
+ struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_RANDOM_BACKGROUND];
+#if 0
+ int area_x = ED_AREA_RANDOM_BACKGROUND_XPOS / MINI_TILEX;
+ int area_y = ED_AREA_RANDOM_BACKGROUND_YPOS / MINI_TILEY;
+ int area_sx = SX + ED_AREA_RANDOM_BACKGROUND_XPOS;
+ int area_sy = SY + ED_AREA_RANDOM_BACKGROUND_YPOS;
+#endif
- DrawMiniElement(area_x, area_y, ElementContent[0][0][0]);
+ DrawElementBorder(gi->x, gi->y, MINI_TILEX, MINI_TILEY, TRUE);
+ DrawMiniElement(gi->x, gi->y, random_placement_background_element);
- MapDrawingArea(GADGET_ID_RANDOM_BACKGROUND);
+ MapDrawingArea(ED_DRAWING_ID_RANDOM_BACKGROUND);
}
static void DrawLevelInfoWindow()
{
- char infotext[1024];
- int xoffset_above = 0;
- int yoffset_above = -(MINI_TILEX + ED_GADGET_DISTANCE);
- int xoffset_right = counter_xsize;
- int yoffset_right = ED_BORDER_SIZE;
- int xoffset_right2 = ED_CHECKBUTTON_XSIZE + 2 * ED_GADGET_DISTANCE;
- int yoffset_right2 = ED_BORDER_SIZE;
- int font_color = FC_GREEN;
- int i, x, y;
+ int i;
+ stick_element_properties_window = FALSE;
+
+ SetMainBackgroundImage(IMG_BACKGROUND_EDITOR);
ClearWindow();
UnmapLevelEditorWindowGadgets();
- DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS_YPOS,
- "Level Settings", FS_BIG, FC_YELLOW);
+ DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS1_YPOS,
+ "Level Settings", FONT_TITLE_1);
DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS2_YPOS,
- "Editor Settings", FS_BIG, FC_YELLOW);
+ "Editor Settings", FONT_TITLE_1);
/* draw counter gadgets */
for (i=ED_COUNTER_ID_LEVEL_FIRST; i<=ED_COUNTER_ID_LEVEL_LAST; i++)
- {
- if (counterbutton_info[i].infotext_above)
- {
- x = counterbutton_info[i].x + xoffset_above;
- y = counterbutton_info[i].y + yoffset_above;
-
- sprintf(infotext, "%s:", counterbutton_info[i].infotext_above);
- infotext[MAX_INFOTEXT_LEN] = '\0';
- DrawTextF(x, y, font_color, infotext);
- }
-
- if (counterbutton_info[i].infotext_right)
- {
- x = counterbutton_info[i].x + xoffset_right;
- y = counterbutton_info[i].y + yoffset_right;
+ MapCounterButtons(i);
- sprintf(infotext, "%s", counterbutton_info[i].infotext_right);
- infotext[MAX_INFOTEXT_LEN] = '\0';
- DrawTextF(x, y, font_color, infotext);
- }
+ /* draw checkbutton gadgets */
+ for (i=ED_CHECKBUTTON_ID_LEVEL_FIRST; i<=ED_CHECKBUTTON_ID_LEVEL_LAST; i++)
+ MapCheckbuttonGadget(i);
- ModifyEditorCounter(i, *counterbutton_info[i].value);
- MapCounterButtons(i);
- }
+ /* draw radiobutton gadgets */
+ for (i=ED_RADIOBUTTON_ID_LEVEL_FIRST; i<=ED_RADIOBUTTON_ID_LEVEL_LAST; i++)
+ MapRadiobuttonGadget(i);
/* draw text input gadgets */
for (i=ED_TEXTINPUT_ID_LEVEL_FIRST; i<=ED_TEXTINPUT_ID_LEVEL_LAST; i++)
- {
- x = textinput_info[i].x + xoffset_above;
- y = textinput_info[i].y + yoffset_above;
+ MapTextInputGadget(i);
- sprintf(infotext, "%s:", textinput_info[i].infotext);
- infotext[MAX_INFOTEXT_LEN] = '\0';
+ /* draw drawing area */
+ DrawRandomPlacementBackgroundArea();
+}
- DrawTextF(x, y, font_color, infotext);
- ModifyEditorTextInput(i, textinput_info[i].value);
- MapTextInputGadget(i);
- }
+static void DrawAmoebaContentArea()
+{
+ int area_x = ED_AREA_ELEM_CONTENT_XPOS / MINI_TILEX;
+ int area_y = ED_AREA_ELEM_CONTENT_YPOS / MINI_TILEY;
+ int area_sx = SX + ED_AREA_ELEM_CONTENT_XPOS;
+ int area_sy = SY + ED_AREA_ELEM_CONTENT_YPOS;
- /* draw radiobutton gadgets */
- for (i=ED_RADIOBUTTON_ID_LEVEL_FIRST; i<=ED_RADIOBUTTON_ID_LEVEL_LAST; i++)
+ DrawElementBorder(area_sx, area_sy, MINI_TILEX, MINI_TILEY, TRUE);
+ DrawMiniElement(area_x, area_y, level.amoeba_content);
+
+ DrawText(area_sx + TILEX, area_sy + 1, "Content of amoeba", FONT_TEXT_1);
+
+ MapDrawingArea(ED_DRAWING_ID_AMOEBA_CONTENT);
+}
+
+static void DrawCustomGraphicElementArea()
+{
+ struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_GRAPHIC];
+#if 0
+ int xpos = ED_AREA_ELEM_CONTENT3_XPOS;
+ int ypos = ED_AREA_ELEM_CONTENT3_YPOS;
+ int area_sx = SX + xpos;
+ int area_sy = SY + ypos;
+#endif
+
+ if (!IS_CUSTOM_ELEMENT(properties_element))
{
- boolean checked =
- (*radiobutton_info[i].value == radiobutton_info[i].checked_value);
+ /* this should never happen */
+ Error(ERR_WARN, "element %d is no custom element", properties_element);
- x = radiobutton_info[i].x + xoffset_right2;
- y = radiobutton_info[i].y + yoffset_right2;
+ return;
+ }
- DrawTextF(x, y, font_color, radiobutton_info[i].text);
- ModifyGadget(level_editor_gadget[radiobutton_info[i].gadget_id],
- GDI_CHECKED, checked, GDI_END);
- MapRadiobuttonGadget(i);
+ DrawElementBorder(gi->x, gi->y, MINI_TILEX, MINI_TILEY, TRUE);
+ DrawMiniGraphicExt(drawto, gi->x, gi->y,
+ el2edimg(custom_element.gfx_element));
+
+ MapDrawingArea(ED_DRAWING_ID_CUSTOM_GRAPHIC);
+}
+
+static void DrawCustomContentArea()
+{
+ struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CONTENT];
+#if 0
+ int area_sx = SX + ED_AREA_ELEM_CONTENT4_XPOS;
+ int area_sy = SY + ED_AREA_ELEM_CONTENT4_YPOS;
+#endif
+ int x1 = right_gadget_border[GADGET_ID_CUSTOM_DEADLINESS];
+ int x2 = right_gadget_border[GADGET_ID_CUSTOM_CONSISTENCY];
+ int x3 = right_gadget_border[GADGET_ID_CUSTOM_EXPLODE_IMPACT];
+ int xoffset = ED_GADGET_TEXT_DISTANCE + MINI_TILEX / 2;
+ int x, y;
+
+ if (!IS_CUSTOM_ELEMENT(properties_element))
+ {
+ /* this should never happen */
+ Error(ERR_WARN, "element %d is no custom element", properties_element);
+
+ return;
}
- /* draw checkbutton gadgets */
- for (i=ED_CHECKBUTTON_ID_LEVEL_FIRST; i<=ED_CHECKBUTTON_ID_LEVEL_LAST; i++)
+ ModifyGadget(gi, GDI_X, MAX(x1, MAX(x2, x3)) + xoffset, GDI_END);
+
+ DrawElementBorder(gi->x, gi->y, 3 * MINI_TILEX, 3 * MINI_TILEY, TRUE);
+
+ 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(custom_element.content[x][y]));
+
+ MapDrawingArea(ED_DRAWING_ID_CUSTOM_CONTENT);
+}
+
+static void DrawCustomChangeTargetArea()
+{
+ int id = ED_DRAWING_ID_CUSTOM_CHANGE_TARGET;
+ int gadget_id = drawingarea_info[id].gadget_id;
+ struct GadgetInfo *gi = level_editor_gadget[gadget_id];
+#if 0
+ int xpos = ED_AREA_ELEM_CONTENT2_XPOS;
+ int ypos = ED_AREA_ELEM_CONTENT2_YPOS;
+ int area_sx = SX + xpos;
+ int area_sy = SY + ypos;
+#endif
+ int xoffset_left = 0;
+ int yoffset_left = ED_BORDER_AREA_YSIZE;
+ int xoffset_right = ED_GADGET_TEXT_DISTANCE + MINI_TILEX / 2;
+ int yoffset_right = ED_BORDER_AREA_YSIZE;
+ int x = drawingarea_info[id].x + xoffset_left;
+ int y = drawingarea_info[id].y + yoffset_left;
+
+ if (!IS_CUSTOM_ELEMENT(properties_element))
{
- x = checkbutton_info[i].x + xoffset_right2;
- y = checkbutton_info[i].y + yoffset_right2;
+ /* this should never happen */
+ Error(ERR_WARN, "element %d is no custom element", properties_element);
- DrawTextF(x, y, font_color, checkbutton_info[i].text);
- ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id],
- GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
- MapCheckbuttonGadget(i);
+ return;
}
- /* draw drawing area */
- DrawRandomPlacementBackgroundArea();
+ DrawElementBorder(gi->x, gi->y, MINI_TILEX, MINI_TILEY, TRUE);
+ DrawMiniGraphicExt(drawto, gi->x, gi->y,
+ el2edimg(custom_element.change.target_element));
+
+ MapDrawingArea(ED_DRAWING_ID_CUSTOM_CHANGE_TARGET);
+
+ if (drawingarea_info[id].text_left)
+ DrawTextF(x, y, FONT_TEXT_1, drawingarea_info[id].text_left);
+
+ if (drawingarea_info[id].text_right)
+ {
+ x = gi->x + gi->width + xoffset_right;
+ y = SY + drawingarea_info[id].y + yoffset_right;
+
+ DrawText(x, y, drawingarea_info[id].text_right, FONT_TEXT_1);
+ }
}
-static void DrawAmoebaContentArea()
+static void DrawCustomChangeContentArea()
{
- int area_x = ED_AREA_ELEM_CONTENT_XPOS / MINI_TILEX;
- int area_y = ED_AREA_ELEM_CONTENT_YPOS / MINI_TILEY;
- int area_sx = SX + ED_AREA_ELEM_CONTENT_XPOS;
- int area_sy = SY + ED_AREA_ELEM_CONTENT_YPOS;
- int font_color = FC_GREEN;
+ struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGE_CONTENT];
+#if 0
+ int area_sx = SX + ED_AREA_ELEM_CONTENT6_XPOS;
+ int area_sy = SY + ED_AREA_ELEM_CONTENT6_YPOS;
+#endif
+ int x1 = right_gadget_border[GADGET_ID_CHANGE_USE_CONTENT];
+ int x2 = right_gadget_border[GADGET_ID_CHANGE_POWER];
+ int x3 = right_gadget_border[GADGET_ID_CHANGE_ONLY_COMPLETE];
+ int xoffset = ED_GADGET_TEXT_DISTANCE + MINI_TILEX / 2;
int x, y;
- ElementContent[0][0][0] = level.amoeba_content;
+ if (!IS_CUSTOM_ELEMENT(properties_element))
+ {
+ /* this should never happen */
+ Error(ERR_WARN, "element %d is no custom element", properties_element);
- /* draw decorative border for the object */
- for (y=0; y<2; y++)
- for (x=0; x<2; x++)
- DrawMiniElement(area_x + x, area_y + y, EL_ERDREICH);
+ return;
+ }
- ClearRectangle(drawto,
- area_sx + MINI_TILEX/2 - 1, area_sy + MINI_TILEY/2 - 1,
- MINI_TILEX + 2, MINI_TILEY + 2);
+ ModifyGadget(gi, GDI_X, MAX(x1, MAX(x2, x3)) + xoffset, GDI_END);
- /* copy border to the right location */
- BlitBitmap(drawto, drawto,
- area_sx, area_sy, 3 * MINI_TILEX, 3 * MINI_TILEY,
- area_sx - MINI_TILEX/2, area_sy - MINI_TILEY/2);
+ DrawElementBorder(gi->x, gi->y, 3 * MINI_TILEX, 3 * MINI_TILEY, TRUE);
+
+ 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(custom_element.change.content[x][y]));
+
+ MapDrawingArea(ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT);
+}
+
+static void DrawCustomChangeTriggerArea()
+{
+ struct GadgetInfo *gi = level_editor_gadget[GADGET_ID_CUSTOM_CHANGE_TRIGGER];
+#if 0
+ int xpos = ED_AREA_ELEM_CONTENT5_XPOS;
+ int ypos = ED_AREA_ELEM_CONTENT5_YPOS;
+ int area_sx = SX + xpos;
+ int area_sy = SY + ypos;
+#endif
+
+ if (!IS_CUSTOM_ELEMENT(properties_element))
+ {
+ /* this should never happen */
+ Error(ERR_WARN, "element %d is no custom element", properties_element);
- DrawText(area_sx + TILEX, area_sy + 1, "Content of amoeba",
- FS_SMALL, font_color);
+ return;
+ }
- DrawMiniElement(area_x, area_y, ElementContent[0][0][0]);
+ DrawElementBorder(gi->x, gi->y, MINI_TILEX, MINI_TILEY, TRUE);
+ DrawMiniGraphicExt(drawto, gi->x, gi->y,
+ el2edimg(custom_element.change.trigger_element));
- MapDrawingArea(GADGET_ID_AMOEBA_CONTENT);
+ MapDrawingArea(ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER);
}
static void DrawElementContentAreas()
{
- int counter_id = ED_COUNTER_ID_ELEM_CONTENT;
int area_x = ED_AREA_ELEM_CONTENT_XPOS / MINI_TILEX;
int area_y = ED_AREA_ELEM_CONTENT_YPOS / MINI_TILEY;
int area_sx = SX + ED_AREA_ELEM_CONTENT_XPOS;
int area_sy = SY + ED_AREA_ELEM_CONTENT_YPOS;
- int xoffset_right = counter_xsize;
- int yoffset_right = ED_BORDER_SIZE;
- int font_color = FC_GREEN;
int i, x, y;
- for (i=0; i<MAX_ELEMENT_CONTENTS; i++)
- for (y=0; y<3; y++)
- for (x=0; x<3; x++)
- ElementContent[i][x][y] = level.yam_content[i][x][y];
+ for (i=0; i<MAX_ELEMENT_CONTENTS; i++)
+ UnmapDrawingArea(GADGET_ID_ELEMENT_CONTENT_0 + i);
+
+ /* display counter to choose number of element content areas */
+ MapCounterButtons(ED_COUNTER_ID_ELEMENT_CONTENT);
+
+ /* delete content areas in case of reducing number of them */
+ DrawBackground(SX, area_sy - MINI_TILEX, SXSIZE, 12 * MINI_TILEY);
+
+ for (i=0; i<level.num_yamyam_contents; i++)
+ DrawElementBorder(area_sx + 5 * (i % 4) * MINI_TILEX,
+ area_sy + 6 * (i / 4) * MINI_TILEY,
+ 3 * MINI_TILEX, 3 * MINI_TILEY, TRUE);
+
+ DrawText(area_sx + (5 * 4 - 1) * MINI_TILEX, area_sy + 0 * MINI_TILEY + 1,
+ "Content", FONT_TEXT_1);
+ DrawText(area_sx + (5 * 4 - 1) * MINI_TILEX, area_sy + 1 * MINI_TILEY + 1,
+ "when", FONT_TEXT_1);
+ DrawText(area_sx + (5 * 4 - 1) * MINI_TILEX, area_sy + 2 * MINI_TILEY + 1,
+ "smashed", FONT_TEXT_1);
+
+ for (i=0; i<level.num_yamyam_contents; i++)
+ {
+ for (y=0; y<3; y++)
+ for (x=0; x<3; x++)
+ DrawMiniElement(area_x + 5 * (i % 4) + x, area_y + 6 * (i / 4) + y,
+ level.yamyam_content[i][x][y]);
+
+ DrawTextF(area_sx - SX + 5 * (i % 4) * MINI_TILEX + MINI_TILEX + 1,
+ area_sy - SY + 6 * (i / 4) * MINI_TILEY + 4 * MINI_TILEY - 4,
+ FONT_TEXT_1, "%d", i + 1);
+ }
+
+ for (i=0; i<level.num_yamyam_contents; i++)
+ MapDrawingArea(ED_DRAWING_ID_ELEMENT_CONTENT_0 + i);
+}
+
+char *getElementDescriptionFilename(int element)
+{
+ char *docs_dir = options.docs_directory;
+ char *elements_subdir = "elements";
+ static char *filename = NULL;
+ char basename[MAX_FILENAME_LEN];
+
+ if (filename != NULL)
+ free(filename);
+
+ /* 1st try: look for element description file for exactly this element */
+ sprintf(basename, "%s.txt", element_info[element].token_name);
+ filename = getPath3(docs_dir, elements_subdir, basename);
+ if (fileExists(filename))
+ return filename;
+
+ free(filename);
+
+ /* 2nd try: look for element description file for this element's class */
+ sprintf(basename, "%s.txt", element_info[element].class_name);
+ filename = getPath3(docs_dir, elements_subdir, basename);
+ if (fileExists(filename))
+ return filename;
+
+ return NULL;
+}
+
+static boolean PrintInfoText(char *text, int font_nr, int screen_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 sx = SX + pad_x;
+ int sy = SY + pad_y;
+ int max_lines_per_screen = (SYSIZE - pad_y) / font_height - 1;
+
+ if (screen_line >= max_lines_per_screen)
+ return FALSE;
+
+ DrawText(sx, sy + screen_line * font_height, text, font_nr);
+
+ return TRUE;
+}
+
+static int PrintElementDescriptionFromFile(char *filename, int screen_line)
+{
+ int font_nr = FONT_TEXT_2;
+ int font_width = getFontWidth(font_nr);
+ int pad_x = ED_SETTINGS_XPOS(0);
+ int max_chars_per_line = (SXSIZE - 2 * pad_x) / font_width;
+ char line[MAX_LINE_LEN];
+ char buffer[max_chars_per_line + 1];
+ int buffer_len;
+ int lines_printed = 0;
+ FILE *file;
+
+ if (filename == NULL)
+ return 0;
+
+ if (!(file = fopen(filename, MODE_READ)))
+ return 0;
+
+ buffer[0] = '\0';
+ buffer_len = 0;
+
+ while(!feof(file))
+ {
+ char *line_ptr, *word_ptr;
+ boolean last_line_was_empty = TRUE;
+
+ /* read next line of input file */
+ if (!fgets(line, MAX_LINE_LEN, file))
+ break;
+
+ /* skip comments (lines directly beginning with '#') */
+ if (line[0] == '#')
+ continue;
+
+ /* cut trailing newline from input line */
+ for (line_ptr = line; *line_ptr; line_ptr++)
+ {
+ if (*line_ptr == '\n' || *line_ptr == '\r')
+ {
+ *line_ptr = '\0';
+ break;
+ }
+ }
+
+ if (strlen(line) == 0) /* special case: force empty line */
+ strcpy(line, "\n");
+
+ word_ptr = line;
+
+ while (*word_ptr)
+ {
+ boolean print_buffer = FALSE;
+ int word_len;
+
+ /* skip leading whitespaces */
+ while (*word_ptr == ' ' || *word_ptr == '\t')
+ word_ptr++;
+
+ line_ptr = word_ptr;
+ word_len = 0;
+
+ /* look for end of next word */
+ while (*line_ptr != ' ' && *line_ptr != '\t' && *line_ptr != '\0')
+ {
+ line_ptr++;
+ word_len++;
+ }
+
+ if (word_len == 0)
+ {
+ continue;
+ }
+ else if (*word_ptr == '\n') /* special case: force empty line */
+ {
+ if (buffer_len == 0)
+ word_ptr++;
+
+ /* prevent printing of multiple empty lines */
+ if (buffer_len > 0 || !last_line_was_empty)
+ print_buffer = TRUE;
+ }
+ else if (word_len < max_chars_per_line - buffer_len)
+ {
+ /* word fits into text buffer -- add word */
+
+ if (buffer_len > 0)
+ buffer[buffer_len++] = ' ';
+
+ strncpy(&buffer[buffer_len], word_ptr, word_len);
+ buffer_len += word_len;
+ buffer[buffer_len] = '\0';
+ word_ptr += word_len;
+ }
+ else if (buffer_len > 0)
+ {
+ /* not enough space left for word in text buffer -- print buffer */
+
+ print_buffer = TRUE;
+ }
+ else
+ {
+ /* word does not fit at all into empty text buffer -- cut word */
+
+ strncpy(buffer, word_ptr, max_chars_per_line);
+ buffer[max_chars_per_line] = '\0';
+ word_ptr += max_chars_per_line;
+ print_buffer = TRUE;
+ }
+
+ if (print_buffer)
+ {
+ if (!PrintInfoText(buffer, font_nr, screen_line + lines_printed))
+ return lines_printed;
+
+ last_line_was_empty = (buffer_len == 0);
+ lines_printed++;
+
+ buffer[0] = '\0';
+ buffer_len = 0;
+ print_buffer = FALSE;
+ }
+ }
+ }
+
+ fclose(file);
+
+ if (buffer_len > 0)
+ if (PrintInfoText(buffer, font_nr, screen_line + lines_printed))
+ lines_printed++;
+
+ return lines_printed;
+}
+
+static void DrawPropertiesTabulatorGadgets()
+{
+ struct GadgetInfo *gd_gi = level_editor_gadget[GADGET_ID_PROPERTIES_INFO];
+ struct GadgetDesign *gd = &gd_gi->alt_design[GD_BUTTON_UNPRESSED];
+ int gd_x = gd->x + gd_gi->border.width / 2;
+ int gd_y = gd->y + gd_gi->height - 1;
+ Pixel tab_color = GetPixel(gd->bitmap, gd_x, gd_y);
+ int id_first = ED_TEXTBUTTON_ID_PROPERTIES_INFO;
+ int id_last = ED_TEXTBUTTON_ID_PROPERTIES_CONFIG;
+ int i;
+
+ /* draw additional "advanced" tabulator for custom elements */
+ if (IS_CUSTOM_ELEMENT(properties_element))
+ id_last = ED_TEXTBUTTON_ID_PROPERTIES_ADVANCED;
+
+ for (i=id_first; i <= id_last; i++)
+ {
+ int gadget_id = textbutton_info[i].gadget_id;
+ struct GadgetInfo *gi = level_editor_gadget[gadget_id];
+ boolean active = (i != edit_mode_properties);
+
+ /* draw background line below tabulator button */
+ ClearRectangleOnBackground(drawto, gi->x, gi->y + gi->height, gi->width,1);
+
+ /* draw solid line below inactive tabulator buttons */
+ if (!active && tab_color != BLACK_PIXEL) /* black => transparent */
+ FillRectangle(drawto, gi->x, gi->y + gi->height, gi->width,1, tab_color);
+
+ ModifyGadget(gi, GDI_ACTIVE, active, GDI_END);
+ MapTextbuttonGadget(i);
+ }
+
+ /* draw little border line below tabulator buttons */
+ if (tab_color != BLACK_PIXEL) /* black => transparent */
+ FillRectangle(drawto, gd_gi->x, gd_gi->y + gd_gi->height + 1,
+ 3 * gd_gi->width + 2 * ED_GADGET_DISTANCE,
+ ED_GADGET_DISTANCE, tab_color);
+}
+
+static void DrawPropertiesInfo()
+{
+ static struct
+ {
+ int value;
+ char *text;
+ }
+ properties[] =
+ {
+ /* configurable properties */
+
+ { EP_WALKABLE_OVER, "- player can walk over it" },
+ { EP_WALKABLE_INSIDE, "- player can walk inside it" },
+ { EP_WALKABLE_UNDER, "- player can walk under it" },
+ { EP_PASSABLE_OVER, "- player can pass over it" },
+ { EP_PASSABLE_INSIDE, "- player can pass through it" },
+ { EP_PASSABLE_UNDER, "- player can pass under it" },
+
+ { EP_DIGGABLE, "- diggable" },
+ { EP_COLLECTIBLE, "- collectible" },
+ { EP_PUSHABLE, "- pushable" },
+
+ { EP_CAN_MOVE, "- can move" },
+ { EP_CAN_FALL, "- can fall" },
+
+ { EP_CAN_SMASH_PLAYER, "- can smash player" },
+#if 0
+ { EP_CAN_SMASH_ENEMIES, "- can smash good and bad guys" },
+#endif
+ { EP_CAN_SMASH_EVERYTHING, "- can smash everything smashable" },
+
+ { EP_SLIPPERY, "- slippery for falling objects" },
+ { EP_EM_SLIPPERY_WALL, "- slippery for some gems (EM style)" },
+
+ { EP_DONT_RUN_INTO, "- deadly when running into" },
+ { EP_DONT_COLLIDE_WITH, "- deadly when colliding with" },
+ { EP_DONT_TOUCH, "- deadly when touching" },
+
+ { EP_INDESTRUCTIBLE, "- undestructible" },
+
+ { EP_CAN_EXPLODE_BY_FIRE, "- can explode by fire or explosions" },
+ { EP_CAN_EXPLODE_SMASHED, "- can explode when smashed" },
+ { EP_CAN_EXPLODE_IMPACT, "- can explode on impact" },
- for (i=0; i<MAX_ELEMENT_CONTENTS; i++)
- UnmapDrawingArea(GADGET_ID_ELEM_CONTENT_0 + i);
+ { EP_CAN_CHANGE, "- can change to other element" },
- /* display counter to choose number of element content areas */
- x = counterbutton_info[counter_id].x + xoffset_right;
- y = counterbutton_info[counter_id].y + yoffset_right;
- DrawTextF(x, y, font_color, "number of content areas");
+ /* pre-defined properties */
+ { EP_CAN_PASS_MAGIC_WALL, "- can pass magic walls" },
+ { EP_HAS_CONTENT, "- can contain other elements" },
- ModifyEditorCounter(counter_id, *counterbutton_info[counter_id].value);
- MapCounterButtons(counter_id);
+ { -1, NULL }
+ };
+ char *filename = getElementDescriptionFilename(properties_element);
+ char *percentage_text = "In this level:";
+ char *properties_text = "Standard properties:";
+ float percentage;
+ int num_elements_in_level;
+ int num_standard_properties = 0;
+ int font1_nr = FONT_TEXT_1;
+ 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 screen_line = 0;
+ int i, x, y;
- /* delete content areas in case of reducing number of them */
- ClearRectangle(backbuffer,
- SX, area_sy - MINI_TILEX,
- SXSIZE, 12 * MINI_TILEY);
+ /* ----- print number of elements / percentage of this element in level */
- /* draw some decorative border for the objects */
- for (i=0; i<level.num_yam_contents; i++)
- {
- for (y=0; y<4; y++)
- for (x=0; x<4; x++)
- DrawMiniElement(area_x + 5 * (i % 4) + x, area_y + 6 * (i / 4) + y,
- EL_ERDREICH);
+ num_elements_in_level = 0;
+ for (y=0; y<lev_fieldy; y++)
+ for (x=0; x<lev_fieldx; x++)
+ if (Feld[x][y] == properties_element)
+ num_elements_in_level++;
+ percentage = num_elements_in_level * 100.0 / (lev_fieldx * lev_fieldy);
- ClearRectangle(drawto,
- area_sx + 5 * (i % 4) * MINI_TILEX + MINI_TILEX/2 - 1,
- area_sy + 6 * (i / 4) * MINI_TILEY + MINI_TILEY/2 - 1,
- 3 * MINI_TILEX + 2, 3 * MINI_TILEY + 2);
- }
+ DrawTextF(pad_x, pad_y + screen_line * font2_height, font1_nr,
+ percentage_text);
+ DrawTextF(pad_x + strlen(percentage_text) * font1_width,
+ pad_y + screen_line++ * font2_height, font2_nr,
+ "%d (%.2f%%)", num_elements_in_level, percentage);
- /* copy border to the right location */
- BlitBitmap(drawto, drawto,
- area_sx, area_sy, (5 * 4 + 1) * MINI_TILEX, 11 * MINI_TILEY,
- area_sx - MINI_TILEX/2, area_sy - MINI_TILEY/2);
+ screen_line++;
- DrawText(area_sx + (5 * 4 - 1) * MINI_TILEX, area_sy + 0 * MINI_TILEY + 1,
- "Content", FS_SMALL, font_color);
- DrawText(area_sx + (5 * 4 - 1) * MINI_TILEX, area_sy + 1 * MINI_TILEY + 1,
- "when", FS_SMALL, font_color);
- DrawText(area_sx + (5 * 4 - 1) * MINI_TILEX, area_sy + 2 * MINI_TILEY + 1,
- "smashed", FS_SMALL, font_color);
+ /* ----- print standard properties of this element */
+
+ DrawTextF(pad_x, pad_y + screen_line++ * font2_height, font1_nr,
+ properties_text);
- for (i=0; i<level.num_yam_contents; i++)
+ for (i=0; properties[i].value != -1; i++)
{
- for (y=0; y<3; y++)
- for (x=0; x<3; x++)
- DrawMiniElement(area_x + 5 * (i % 4) + x, area_y + 6 * (i / 4) + y,
- ElementContent[i][x][y]);
+ if (!HAS_PROPERTY(properties_element, properties[i].value))
+ continue;
- DrawTextF(area_sx - SX + 5 * (i % 4) * MINI_TILEX + MINI_TILEX + 1,
- area_sy - SY + 6 * (i / 4) * MINI_TILEY + 4 * MINI_TILEY - 4,
- font_color, "%d", i + 1);
+ DrawTextF(pad_x, pad_y + screen_line++ * font2_height, font2_nr,
+ properties[i].text);
+ num_standard_properties++;
}
- for (i=0; i<level.num_yam_contents; i++)
- MapDrawingArea(GADGET_ID_ELEM_CONTENT_0 + i);
+ if (num_standard_properties == 0)
+ DrawTextF(pad_x + strlen(properties_text) * font1_width,
+ pad_y + (screen_line - 1) * font2_height, font2_nr, "none");
+
+ screen_line++;
+
+ /* ----- print special description of this element */
+
+ PrintInfoText("Description:", FONT_TEXT_1, screen_line);
+ if (PrintElementDescriptionFromFile(filename, screen_line + 1) == 0)
+ PrintInfoText("No description available.", FONT_TEXT_1, screen_line);
}
#define TEXT_COLLECTING "Score for collecting"
#define TEXT_SPEED "Speed of amoeba growth"
#define TEXT_DURATION "Duration when activated"
-static void DrawPropertiesWindow()
+static struct
{
- int counter_id = ED_COUNTER_ID_ELEM_SCORE;
- int num_elements_in_level;
- float percentage;
- int xoffset_right = counter_xsize;
- int yoffset_right = ED_BORDER_SIZE;
- int xoffset_right2 = ED_CHECKBUTTON_XSIZE + 2 * ED_GADGET_DISTANCE;
- int yoffset_right2 = ED_BORDER_SIZE;
- int xstart = 2;
- int ystart = 4;
- int font_color = FC_GREEN;
- int i, x, y;
- static struct
- {
- int element;
- int *value;
- char *text;
- } elements_with_counter[] =
- {
- { EL_EDELSTEIN, &level.score[SC_EDELSTEIN], TEXT_COLLECTING },
- { EL_EDELSTEIN_BD, &level.score[SC_EDELSTEIN], TEXT_COLLECTING },
- { EL_EDELSTEIN_GELB,&level.score[SC_EDELSTEIN], TEXT_COLLECTING },
- { EL_EDELSTEIN_ROT, &level.score[SC_EDELSTEIN], TEXT_COLLECTING },
- { EL_EDELSTEIN_LILA,&level.score[SC_EDELSTEIN], TEXT_COLLECTING },
- { EL_DIAMANT, &level.score[SC_DIAMANT], TEXT_COLLECTING },
- { EL_KAEFER_RIGHT, &level.score[SC_KAEFER], TEXT_SMASHING },
- { EL_KAEFER_UP, &level.score[SC_KAEFER], TEXT_SMASHING },
- { EL_KAEFER_LEFT, &level.score[SC_KAEFER], TEXT_SMASHING },
- { EL_KAEFER_DOWN, &level.score[SC_KAEFER], TEXT_SMASHING },
- { EL_BUTTERFLY_RIGHT,&level.score[SC_KAEFER], TEXT_SMASHING },
- { EL_BUTTERFLY_UP, &level.score[SC_KAEFER], TEXT_SMASHING },
- { EL_BUTTERFLY_LEFT,&level.score[SC_KAEFER], TEXT_SMASHING },
- { EL_BUTTERFLY_DOWN,&level.score[SC_KAEFER], TEXT_SMASHING },
- { EL_FLIEGER_RIGHT, &level.score[SC_FLIEGER], TEXT_SMASHING },
- { EL_FLIEGER_UP, &level.score[SC_FLIEGER], TEXT_SMASHING },
- { EL_FLIEGER_LEFT, &level.score[SC_FLIEGER], TEXT_SMASHING },
- { EL_FLIEGER_DOWN, &level.score[SC_FLIEGER], TEXT_SMASHING },
- { EL_FIREFLY_RIGHT, &level.score[SC_FLIEGER], TEXT_SMASHING },
- { EL_FIREFLY_UP, &level.score[SC_FLIEGER], TEXT_SMASHING },
- { EL_FIREFLY_LEFT, &level.score[SC_FLIEGER], TEXT_SMASHING },
- { EL_FIREFLY_DOWN, &level.score[SC_FLIEGER], TEXT_SMASHING },
- { EL_MAMPFER, &level.score[SC_MAMPFER], TEXT_SMASHING },
- { EL_MAMPFER2, &level.score[SC_MAMPFER], TEXT_SMASHING },
- { EL_ROBOT, &level.score[SC_ROBOT], TEXT_SMASHING },
- { EL_PACMAN_RIGHT, &level.score[SC_PACMAN], TEXT_SMASHING },
- { EL_PACMAN_UP, &level.score[SC_PACMAN], TEXT_SMASHING },
- { EL_PACMAN_LEFT, &level.score[SC_PACMAN], TEXT_SMASHING },
- { EL_PACMAN_DOWN, &level.score[SC_PACMAN], TEXT_SMASHING },
- { EL_KOKOSNUSS, &level.score[SC_KOKOSNUSS], TEXT_CRACKING },
- { EL_DYNAMITE_INACTIVE,&level.score[SC_DYNAMIT], TEXT_COLLECTING },
- { EL_SCHLUESSEL1, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING },
- { EL_SCHLUESSEL2, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING },
- { EL_SCHLUESSEL3, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING },
- { EL_SCHLUESSEL4, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING },
- { EL_EM_KEY_1_FILE, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING },
- { EL_EM_KEY_2_FILE, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING },
- { EL_EM_KEY_3_FILE, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING },
- { EL_EM_KEY_4_FILE, &level.score[SC_SCHLUESSEL], TEXT_COLLECTING },
- { EL_AMOEBE_NASS, &level.amoeba_speed, TEXT_SPEED },
- { EL_AMOEBE_NORM, &level.amoeba_speed, TEXT_SPEED },
- { EL_AMOEBE_VOLL, &level.amoeba_speed, TEXT_SPEED },
- { EL_AMOEBE_BD, &level.amoeba_speed, TEXT_SPEED },
- { EL_MAGIC_WALL_OFF,&level.time_magic_wall, TEXT_DURATION },
- { EL_ABLENK_AUS, &level.time_wheel, TEXT_DURATION },
- { -1, NULL, NULL }
- };
-
- ClearWindow();
- UnmapLevelEditorWindowGadgets();
-
- DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS_YPOS,
- "Element Settings", FS_BIG, FC_YELLOW);
-
- /* draw some decorative border for the object */
- for (y=0; y<3; y++)
- for (x=0; x<3; x++)
- DrawMiniElement(xstart + x , ystart + y, EL_ERDREICH);
-
- ClearRectangle(drawto,
- SX + xstart * MINI_TILEX + MINI_TILEX/2 - 1,
- SY + ystart * MINI_TILEY + MINI_TILEY/2 - 1,
- TILEX + 2, TILEY + 2);
+ int element;
+ int *value;
+ char *text;
+} elements_with_counter[] =
+{
+ { EL_EMERALD, &level.score[SC_EMERALD], TEXT_COLLECTING },
+ { EL_BD_DIAMOND, &level.score[SC_EMERALD], TEXT_COLLECTING },
+ { EL_EMERALD_YELLOW, &level.score[SC_EMERALD], TEXT_COLLECTING },
+ { EL_EMERALD_RED, &level.score[SC_EMERALD], TEXT_COLLECTING },
+ { EL_EMERALD_PURPLE, &level.score[SC_EMERALD], TEXT_COLLECTING },
+ { EL_SP_INFOTRON, &level.score[SC_EMERALD], TEXT_COLLECTING },
+ { EL_DIAMOND, &level.score[SC_DIAMOND], TEXT_COLLECTING },
+ { EL_CRYSTAL, &level.score[SC_CRYSTAL], TEXT_COLLECTING },
+ { EL_PEARL, &level.score[SC_PEARL], TEXT_COLLECTING },
+ { EL_BUG_RIGHT, &level.score[SC_BUG], TEXT_SMASHING },
+ { EL_BUG_UP, &level.score[SC_BUG], TEXT_SMASHING },
+ { EL_BUG_LEFT, &level.score[SC_BUG], TEXT_SMASHING },
+ { EL_BUG_DOWN, &level.score[SC_BUG], TEXT_SMASHING },
+ { EL_BD_BUTTERFLY_RIGHT,&level.score[SC_BUG], TEXT_SMASHING },
+ { EL_BD_BUTTERFLY_UP, &level.score[SC_BUG], TEXT_SMASHING },
+ { EL_BD_BUTTERFLY_LEFT, &level.score[SC_BUG], TEXT_SMASHING },
+ { EL_BD_BUTTERFLY_DOWN, &level.score[SC_BUG], TEXT_SMASHING },
+ { EL_SP_ELECTRON, &level.score[SC_BUG], TEXT_SMASHING },
+ { EL_SPACESHIP_RIGHT, &level.score[SC_SPACESHIP], TEXT_SMASHING },
+ { EL_SPACESHIP_UP, &level.score[SC_SPACESHIP], TEXT_SMASHING },
+ { EL_SPACESHIP_LEFT, &level.score[SC_SPACESHIP], TEXT_SMASHING },
+ { EL_SPACESHIP_DOWN, &level.score[SC_SPACESHIP], TEXT_SMASHING },
+ { EL_BD_FIREFLY_RIGHT,&level.score[SC_SPACESHIP], TEXT_SMASHING },
+ { EL_BD_FIREFLY_UP, &level.score[SC_SPACESHIP], TEXT_SMASHING },
+ { EL_BD_FIREFLY_LEFT, &level.score[SC_SPACESHIP], TEXT_SMASHING },
+ { EL_BD_FIREFLY_DOWN, &level.score[SC_SPACESHIP], TEXT_SMASHING },
+ { EL_SP_SNIKSNAK, &level.score[SC_SPACESHIP], TEXT_SMASHING },
+ { EL_YAMYAM, &level.score[SC_YAMYAM], TEXT_SMASHING },
+ { EL_DARK_YAMYAM, &level.score[SC_YAMYAM], TEXT_SMASHING },
+ { EL_ROBOT, &level.score[SC_ROBOT], TEXT_SMASHING },
+ { EL_PACMAN_RIGHT, &level.score[SC_PACMAN], TEXT_SMASHING },
+ { EL_PACMAN_UP, &level.score[SC_PACMAN], TEXT_SMASHING },
+ { EL_PACMAN_LEFT, &level.score[SC_PACMAN], TEXT_SMASHING },
+ { EL_PACMAN_DOWN, &level.score[SC_PACMAN], TEXT_SMASHING },
+ { EL_NUT, &level.score[SC_NUT], TEXT_CRACKING },
+ { EL_DYNAMITE, &level.score[SC_DYNAMITE], TEXT_COLLECTING },
+ { EL_DYNABOMB_INCREASE_NUMBER,&level.score[SC_DYNAMITE],TEXT_COLLECTING },
+ { EL_DYNABOMB_INCREASE_SIZE, &level.score[SC_DYNAMITE],TEXT_COLLECTING },
+ { EL_DYNABOMB_INCREASE_POWER, &level.score[SC_DYNAMITE],TEXT_COLLECTING },
+ { EL_SHIELD_NORMAL, &level.score[SC_SHIELD], TEXT_COLLECTING },
+ { EL_SHIELD_DEADLY, &level.score[SC_SHIELD], TEXT_COLLECTING },
+ { EL_EXTRA_TIME, &level.score[SC_TIME_BONUS], TEXT_COLLECTING },
+ { EL_KEY_1, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_KEY_2, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_KEY_3, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_KEY_4, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_EM_KEY_1_FILE, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_EM_KEY_2_FILE, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_EM_KEY_3_FILE, &level.score[SC_KEY], TEXT_COLLECTING },
+ { EL_EM_KEY_4_FILE, &level.score[SC_KEY], TEXT_COLLECTING },
+ { 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_MAGIC_WALL, &level.time_magic_wall, TEXT_DURATION },
+ { EL_ROBOT_WHEEL, &level.time_wheel, TEXT_DURATION },
+ { -1, NULL, NULL }
+};
- /* copy border to the right location */
- BlitBitmap(drawto, drawto,
- SX + xstart * MINI_TILEX,
- SY + ystart * MINI_TILEY,
- 2 * TILEX, 2 * TILEY,
- SX + xstart * MINI_TILEX - MINI_TILEX/2,
- SY + ystart * MINI_TILEY - MINI_TILEY/2);
+static boolean checkPropertiesConfig()
+{
+ int i;
- DrawGraphic(xstart/2, ystart/2, el2gfx(properties_element));
+ if (IS_GEM(properties_element) ||
+ IS_CUSTOM_ELEMENT(properties_element) ||
+ HAS_CONTENT(properties_element))
+ return TRUE;
+ else
+ for (i=0; elements_with_counter[i].element != -1; i++)
+ if (elements_with_counter[i].element == properties_element)
+ return TRUE;
- /* copy the whole stuff to the definitive location */
- BlitBitmap(drawto, drawto,
- SX + xstart * MINI_TILEX - MINI_TILEX/2,
- SY + ystart * MINI_TILEY - MINI_TILEY,
- 2 * TILEX, 2 * TILEY,
- SX + xstart * MINI_TILEX - MINI_TILEX/2,
- SY + ystart * MINI_TILEY - MINI_TILEY/2);
+ return FALSE;
+}
- DrawTextF((xstart + 3) * MINI_TILEX, (ystart + 1) * MINI_TILEY,
- font_color, getElementInfoText(properties_element));
+static void DrawPropertiesConfig()
+{
+ int i;
- num_elements_in_level = 0;
- for (y=0; y<lev_fieldy; y++)
- for (x=0; x<lev_fieldx; x++)
- if (Feld[x][y] == properties_element)
- num_elements_in_level++;
- percentage = num_elements_in_level * 100.0 / (lev_fieldx * lev_fieldy);
+ if (!checkPropertiesConfig())
+ {
+ PrintInfoText("No configuration options available.", FONT_TEXT_1, 0);
- DrawTextF(ED_SETTINGS_XPOS, 5 * TILEY, font_color, "In this level:");
- DrawTextF(ED_SETTINGS_XPOS + 15 * FONT2_XSIZE, 5 * TILEY, FC_YELLOW,
- "%d (%.2f%%)", num_elements_in_level, percentage);
+ return;
+ }
/* check if there are elements where a score can be chosen for */
for (i=0; elements_with_counter[i].element != -1; i++)
{
if (elements_with_counter[i].element == properties_element)
{
- int x = counterbutton_info[counter_id].x + xoffset_right;
- int y = counterbutton_info[counter_id].y + yoffset_right;
+ int counter_id = ED_COUNTER_ID_ELEMENT_SCORE;
counterbutton_info[counter_id].value = elements_with_counter[i].value;
- DrawTextF(x, y, font_color, elements_with_counter[i].text);
-
- ModifyEditorCounter(counter_id, *counterbutton_info[counter_id].value);
+ counterbutton_info[counter_id].text_right= elements_with_counter[i].text;
MapCounterButtons(counter_id);
+
break;
}
}
{
/* draw stickybutton gadget */
i = ED_CHECKBUTTON_ID_STICK_ELEMENT;
- x = checkbutton_info[i].x + xoffset_right2;
- y = checkbutton_info[i].y + yoffset_right2;
-
- DrawTextF(x, y, font_color, checkbutton_info[i].text);
- ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id],
- GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
+ checkbutton_info[i].y = ED_COUNTER_YPOS(4);
MapCheckbuttonGadget(i);
if (IS_AMOEBOID(properties_element))
}
if (IS_GEM(properties_element))
+ MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS);
+
+ if (IS_CUSTOM_ELEMENT(properties_element))
{
- /* draw checkbutton gadget */
- i = ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS;
- x = checkbutton_info[i].x + xoffset_right2;
- y = checkbutton_info[i].y + yoffset_right2;
+ /* draw stickybutton gadget */
+ i = ED_CHECKBUTTON_ID_STICK_ELEMENT;
+ checkbutton_info[i].y = ED_SETTINGS_YPOS(0);
+ MapCheckbuttonGadget(i);
+
+ /* draw checkbutton gadgets */
+ for (i = ED_CHECKBUTTON_ID_CUSTOM_FIRST;
+ i <= ED_CHECKBUTTON_ID_CUSTOM_LAST; i++)
+ MapCheckbuttonGadget(i);
+
+ /* draw counter gadgets */
+ for (i=ED_COUNTER_ID_CUSTOM_FIRST; i<=ED_COUNTER_ID_CUSTOM_LAST; i++)
+ MapCounterButtons(i);
+
+ /* draw selectbox gadgets */
+ for (i=ED_SELECTBOX_ID_CUSTOM_FIRST; i <= ED_SELECTBOX_ID_CUSTOM_LAST; i++)
+ MapSelectboxGadget(i);
+
+ /* draw drawing area gadgets */
+ DrawCustomContentArea();
+
+ /* draw text input gadgets */
+ MapTextInputGadget(ED_TEXTINPUT_ID_ELEMENT_NAME);
+ }
+}
+
+static void DrawPropertiesAdvancedDrawingAreas()
+{
+ DrawCustomGraphicElementArea();
+ DrawCustomChangeTargetArea();
+ DrawCustomChangeTriggerArea();
+ DrawCustomChangeContentArea();
+
+ redraw_mask |= REDRAW_FIELD;
+}
- DrawTextF(x, y, font_color, checkbutton_info[i].text);
- ModifyGadget(level_editor_gadget[checkbutton_info[i].gadget_id],
- GDI_CHECKED, *checkbutton_info[i].value, GDI_END);
+static void DrawPropertiesAdvanced()
+{
+ int i;
+
+ /* draw stickybutton gadget */
+ i = ED_CHECKBUTTON_ID_STICK_ELEMENT;
+ checkbutton_info[i].y = ED_SETTINGS_YPOS(0);
+ MapCheckbuttonGadget(i);
+
+ /* draw checkbutton gadgets */
+ for (i = ED_CHECKBUTTON_ID_CHANGE_FIRST;
+ i <= ED_CHECKBUTTON_ID_CHANGE_LAST; i++)
MapCheckbuttonGadget(i);
+
+ /* draw counter gadgets */
+ for (i=ED_COUNTER_ID_CHANGE_FIRST; i<=ED_COUNTER_ID_CHANGE_LAST; i++)
+ MapCounterButtons(i);
+
+ /* draw selectbox gadgets */
+ for (i=ED_SELECTBOX_ID_CHANGE_FIRST; i<=ED_SELECTBOX_ID_CHANGE_LAST; i++)
+ MapSelectboxGadget(i);
+
+ /* draw textbutton gadgets */
+ MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE);
+
+ /* draw drawing area gadgets */
+ DrawPropertiesAdvancedDrawingAreas();
+}
+
+static void DrawElementName(int x, int y, int element)
+{
+ char *element_name = getElementInfoText(element);
+ 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_chars_per_line = max_text_width / font_width;
+ char buffer[max_chars_per_line + 1];
+
+ if (strlen(element_name) <= max_chars_per_line)
+ DrawTextF(x, y, font_nr, element_name);
+ else
+ {
+ int next_pos = max_chars_per_line;
+
+ strncpy(buffer, element_name, max_chars_per_line);
+ buffer[max_chars_per_line] = '\0';
+
+ if (element_name[max_chars_per_line] == ' ')
+ next_pos++;
+ else
+ {
+ int i;
+
+ for (i = max_chars_per_line - 1; i >= 0; i--)
+ if (buffer[i] == ' ')
+ break;
+
+ if (strlen(&element_name[i + 1]) <= max_chars_per_line)
+ {
+ buffer[i] = '\0';
+ next_pos = i + 1;
+ }
+ }
+
+ DrawTextF(x, y - font_height / 2, font_nr, buffer);
+
+ strncpy(buffer, &element_name[next_pos], max_chars_per_line);
+ buffer[max_chars_per_line] = '\0';
+
+ DrawTextF(x, y + font_height / 2, font_nr, buffer);
}
}
+static void DrawPropertiesWindow()
+{
+ int xstart = 2;
+ int ystart = 4;
+
+ stick_element_properties_window = FALSE;
+
+ /* make sure that previous properties edit mode exists for this element */
+ if (edit_mode_properties == ED_MODE_PROPERTIES_ADVANCED &&
+ !IS_CUSTOM_ELEMENT(properties_element))
+ edit_mode_properties = ED_MODE_PROPERTIES_CONFIG;
+
+ if (IS_CUSTOM_ELEMENT(properties_element))
+ CopyCustomElementPropertiesToEditor(properties_element);
+
+ UnmapLevelEditorWindowGadgets();
+
+ SetMainBackgroundImage(IMG_BACKGROUND_EDITOR);
+ ClearWindow();
+
+ DrawText(SX + ED_SETTINGS2_XPOS, SY + ED_SETTINGS1_YPOS,
+ "Element Settings", FONT_TITLE_1);
+
+ DrawElementBorder(SX + xstart * MINI_TILEX,
+ SY + ystart * MINI_TILEY + MINI_TILEY / 2,
+ TILEX, TILEY, FALSE);
+ DrawGraphicAnimationExt(drawto,
+ SX + xstart * MINI_TILEX,
+ SY + ystart * MINI_TILEY + MINI_TILEY / 2,
+ el2img(properties_element), -1, NO_MASKING);
+
+ FrameCounter = 0; /* restart animation frame counter */
+
+ DrawElementName((xstart + 3) * MINI_TILEX, (ystart + 1) * MINI_TILEY,
+ properties_element);
+
+ DrawPropertiesTabulatorGadgets();
+
+ if (edit_mode_properties == ED_MODE_PROPERTIES_INFO)
+ DrawPropertiesInfo();
+ else if (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG)
+ DrawPropertiesConfig();
+ else /* edit_mode_properties == ED_MODE_PROPERTIES_ADVANCED */
+ DrawPropertiesAdvanced();
+}
+
+static void UpdateCustomElementGraphicGadgets()
+{
+ ModifyEditorElementList();
+ RedrawDrawingElements();
+
+ if (edit_mode == ED_MODE_PROPERTIES &&
+ edit_mode_properties == ED_MODE_PROPERTIES_ADVANCED)
+ DrawPropertiesAdvancedDrawingAreas();
+}
+
static void DrawLineElement(int sx, int sy, int element, boolean change_level)
{
int lx = sx + level_xpos;
}
}
-static void DrawRectangle(int from_x, int from_y, int to_x, int to_y,
- int element, boolean change_level)
+static void DrawBox(int from_x, int from_y, int to_x, int to_y,
+ int element, boolean change_level)
{
DrawLine(from_x, from_y, from_x, to_y, element, change_level);
DrawLine(from_x, to_y, to_x, to_y, element, change_level);
int element, boolean change_level)
{
if (element == -1 || change_level)
- DrawRectangle(from_x, from_y, to_x, to_y, -1, FALSE);
+ DrawBox(from_x, from_y, to_x, to_y, -1, FALSE);
else
DrawAreaBorder(from_x, from_y, to_x, to_y);
}
if (letter >= 'a' && letter <= 'z')
letter_element = EL_CHAR_ASCII0 + letter + (int)('A' - 'a');
else if (letter == 'ä' || letter == 'Ä')
- letter_element = EL_CHAR_AE;
+ letter_element = EL_CHAR_AUMLAUT;
else if (letter == 'ö' || letter == 'Ö')
- letter_element = EL_CHAR_OE;
+ letter_element = EL_CHAR_OUMLAUT;
else if (letter == 'ü' || letter == 'Ü')
- letter_element = EL_CHAR_UE;
+ letter_element = EL_CHAR_UUMLAUT;
else if (letter == '^')
- letter_element = EL_CHAR_COPY;
+ letter_element = EL_CHAR_COPYRIGHT;
else
letter_element = EL_CHAR_ASCII0 + letter;
SetBorderElement();
if (BorderElement != last_border_element)
DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
-
-#if 0
-#ifdef DEBUG
- printf("level saved to undo buffer\n");
-#endif
-#endif
}
static void RandomPlacement(int new_element)
int sx = gi->event.x, sy = gi->event.y;
int min_sx = 0, min_sy = 0;
int max_sx = gi->drawing.area_xsize - 1, max_sy = gi->drawing.area_ysize - 1;
+ int item_xsize = gi->drawing.item_xsize, item_ysize = gi->drawing.item_ysize;
int lx = 0, ly = 0;
int min_lx = 0, min_ly = 0;
int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1;
/* automatically switch to 'single item' drawing mode, if needed */
actual_drawing_function =
- (draw_level ? drawing_function : GADGET_ID_SINGLE_ITEMS);
+ (draw_level || drawing_function == GADGET_ID_PICK_ELEMENT ?
+ drawing_function : GADGET_ID_SINGLE_ITEMS);
+
+ /* clicking into drawing area with pressed Control key picks element */
+ if (GetKeyModState() & KMOD_Control)
+ actual_drawing_function = GADGET_ID_PICK_ELEMENT;
switch (actual_drawing_function)
{
}
else if (new_element != Feld[lx][ly])
{
- if (new_element == EL_SPIELFIGUR)
+ if (new_element == EL_PLAYER_1)
{
/* remove player at old position */
for(y=0; y<lev_fieldy; y++)
{
for(x=0; x<lev_fieldx; x++)
{
- if (Feld[x][y] == EL_SPIELFIGUR || Feld[x][y] == EL_SPIELER1)
+ if (Feld[x][y] == EL_PLAYER_1)
{
- Feld[x][y] = EL_LEERRAUM;
+ Feld[x][y] = EL_EMPTY;
if (x - level_xpos >= 0 && x - level_xpos < ed_fieldx &&
y - level_ypos >= 0 && y - level_ypos < ed_fieldy)
DrawMiniElement(x - level_xpos, y - level_ypos,
- EL_LEERRAUM);
+ EL_EMPTY);
}
}
}
}
else
{
- DrawMiniGraphicExt(drawto,
- gi->x + sx * MINI_TILEX,
- gi->y + sy * MINI_TILEY,
- el2gfx(new_element));
- DrawMiniGraphicExt(window,
- gi->x + sx * MINI_TILEX,
- gi->y + sy * MINI_TILEY,
- el2gfx(new_element));
+ if (item_xsize == MINI_TILEX && item_ysize == MINI_TILEY)
+ DrawMiniGraphicExt(drawto,
+ gi->x + sx * MINI_TILEX,
+ gi->y + sy * MINI_TILEY,
+ el2edimg(new_element));
+ else
+ DrawGraphicExt(drawto,
+ gi->x + sx * TILEX,
+ gi->y + sy * TILEY,
+ el2img(new_element), 0);
if (id == GADGET_ID_AMOEBA_CONTENT)
level.amoeba_content = new_element;
+ else if (id == GADGET_ID_CUSTOM_GRAPHIC)
+ {
+ new_element = GFX_ELEMENT(new_element);
+ custom_element.gfx_element = new_element;
+
+ CopyCustomElementPropertiesToGame(properties_element);
+
+ UpdateCustomElementGraphicGadgets();
+
+ FrameCounter = 0; /* restart animation frame counter */
+ }
+ else if (id == GADGET_ID_CUSTOM_CONTENT)
+ {
+ custom_element.content[sx][sy] = new_element;
+
+ CopyCustomElementPropertiesToGame(properties_element);
+ }
+ else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET)
+ {
+ custom_element.change.target_element = new_element;
+
+ CopyCustomElementPropertiesToGame(properties_element);
+ }
+ else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT)
+ {
+ custom_element.change.content[sx][sy] = new_element;
+
+ CopyCustomElementPropertiesToGame(properties_element);
+ }
+ else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER)
+ {
+ custom_element.change.trigger_element = new_element;
+
+ CopyCustomElementPropertiesToGame(properties_element);
+ }
else if (id == GADGET_ID_RANDOM_BACKGROUND)
random_placement_background_element = new_element;
- else if (id >= GADGET_ID_ELEM_CONTENT_0 &&
- id <= GADGET_ID_ELEM_CONTENT_7)
- level.yam_content[id - GADGET_ID_ELEM_CONTENT_0][sx][sy] =
+ 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] =
new_element;
}
break;
else if (drawing_function == GADGET_ID_ARC)
draw_func = DrawArc;
else if (drawing_function == GADGET_ID_RECTANGLE)
- draw_func = DrawRectangle;
+ draw_func = DrawBox;
else if (drawing_function == GADGET_ID_FILLED_BOX)
draw_func = DrawFilledBox;
else if (drawing_function == GADGET_ID_GRAB_BRUSH)
if (button_release_event)
ClickOnGadget(level_editor_gadget[last_drawing_function],
MB_LEFTBUTTON);
- else
+ else if (draw_level)
PickDrawingElement(button, Feld[lx][ly]);
+ else if (id == GADGET_ID_AMOEBA_CONTENT)
+ PickDrawingElement(button, level.amoeba_content);
+ else if (id == GADGET_ID_CUSTOM_GRAPHIC)
+ PickDrawingElement(button, custom_element.gfx_element);
+ else if (id == GADGET_ID_CUSTOM_CONTENT)
+ PickDrawingElement(button, custom_element.content[sx][sy]);
+ else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET)
+ PickDrawingElement(button, custom_element.change.target_element);
+ else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT)
+ PickDrawingElement(button, custom_element.change.content[sx][sy]);
+ else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER)
+ PickDrawingElement(button, custom_element.change.trigger_element);
+ 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)
+ {
+ int i = id - GADGET_ID_ELEMENT_CONTENT_0;
+
+ PickDrawingElement(button, level.yamyam_content[i][sx][sy]);
+ }
break;
switch (counter_id)
{
- case ED_COUNTER_ID_ELEM_CONTENT:
+ case ED_COUNTER_ID_ELEMENT_CONTENT:
DrawElementContentAreas();
break;
default:
break;
}
+
+ if ((counter_id >= ED_COUNTER_ID_CUSTOM_FIRST &&
+ counter_id <= ED_COUNTER_ID_CUSTOM_LAST) ||
+ (counter_id >= ED_COUNTER_ID_CHANGE_FIRST &&
+ counter_id <= ED_COUNTER_ID_CHANGE_LAST))
+ CopyCustomElementPropertiesToGame(properties_element);
}
static void HandleTextInputGadgets(struct GadgetInfo *gi)
{
- strcpy(textinput_info[gi->custom_type_id].value, gi->text.value);
+ int type_id = gi->custom_type_id;
+
+ strcpy(textinput_info[type_id].value, gi->text.value);
+
+ if (type_id == ED_TEXTINPUT_ID_ELEMENT_NAME)
+ {
+ CopyCustomElementPropertiesToGame(properties_element);
+
+ ModifyEditorElementList(); /* update changed button info text */
+ }
+}
+
+static void HandleSelectboxGadgets(struct GadgetInfo *gi)
+{
+ int type_id = gi->custom_type_id;
+
+ *selectbox_info[type_id].value =
+ selectbox_info[type_id].options[gi->selectbox.index].value;
+
+ if ((type_id >= ED_SELECTBOX_ID_CUSTOM_FIRST &&
+ type_id <= ED_SELECTBOX_ID_CUSTOM_LAST) ||
+ (type_id >= ED_SELECTBOX_ID_CHANGE_FIRST &&
+ type_id <= ED_SELECTBOX_ID_CHANGE_LAST))
+ CopyCustomElementPropertiesToGame(properties_element);
+}
+
+static void HandleTextbuttonGadgets(struct GadgetInfo *gi)
+{
+ int type_id = gi->custom_type_id;
+
+ if (type_id >= ED_TEXTBUTTON_ID_PROPERTIES_INFO &&
+ type_id <= ED_TEXTBUTTON_ID_PROPERTIES_ADVANCED)
+ {
+ edit_mode_properties = gi->custom_type_id;
+
+ DrawPropertiesWindow();
+ }
+ else if (type_id == ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE)
+ {
+ boolean new_template = (!LevelFileExists(-1));
+
+ if (new_template ||
+ Request("Save this tem- plate and kill the old ?", REQ_ASK))
+ SaveLevelTemplate();
+
+ if (new_template)
+ Request("Tem- plate saved !", REQ_CONFIRM);
+ }
}
static void HandleRadiobuttons(struct GadgetInfo *gi)
static void HandleCheckbuttons(struct GadgetInfo *gi)
{
- *checkbutton_info[gi->custom_type_id].value ^= TRUE;
+ int type_id = gi->custom_type_id;
+
+ *checkbutton_info[type_id].value ^= TRUE;
+
+ if ((type_id >= ED_CHECKBUTTON_ID_CUSTOM_FIRST &&
+ type_id <= ED_CHECKBUTTON_ID_CUSTOM_LAST) ||
+ (type_id >= ED_CHECKBUTTON_ID_CHANGE_FIRST &&
+ type_id <= ED_CHECKBUTTON_ID_CHANGE_LAST &&
+ type_id != ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE))
+ {
+ CopyCustomElementPropertiesToGame(properties_element);
+ }
+
+ if (type_id == ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC)
+ {
+ UpdateCustomElementGraphicGadgets();
+ }
+ else if (type_id == ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE)
+ {
+ if (level.use_custom_template && !LevelFileExists(-1))
+ {
+ Request("No level tem- plate found !", REQ_CONFIRM);
+
+ level.use_custom_template = FALSE;
+ ModifyGadget(gi, GDI_CHECKED, FALSE, GDI_END);
+
+ return;
+ }
+
+ LoadLevelTemplate(level.use_custom_template ? -1 : level_nr);
+
+ DrawEditModeWindow();
+ }
}
static void HandleControlButtons(struct GadgetInfo *gi)
int button = gi->event.button;
int step = BUTTON_STEPSIZE(button);
int new_element = BUTTON_ELEMENT(button);
- int i, x, y;
+ int x, y;
if (edit_mode == ED_MODE_DRAWING && drawing_function == GADGET_ID_TEXT)
DrawLevelText(0, 0, 0, TEXT_END);
if (id < ED_NUM_CTRL1_BUTTONS && id != GADGET_ID_PROPERTIES &&
- edit_mode != ED_MODE_DRAWING)
+ id != GADGET_ID_PICK_ELEMENT && edit_mode != ED_MODE_DRAWING &&
+ drawing_function != GADGET_ID_PICK_ELEMENT &&
+ !(GetKeyModState() & KMOD_Control))
{
DrawDrawingWindow();
edit_mode = ED_MODE_DRAWING;
if (element_shift < 0)
element_shift = 0;
- if (element_shift > elements_in_list - ED_NUM_ELEMENTLIST_BUTTONS)
- element_shift = elements_in_list - ED_NUM_ELEMENTLIST_BUTTONS;
+ if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS)
+ element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS;
ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL],
GDI_SCROLLBAR_ITEM_POSITION,
element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END);
}
- for (i=0; i<ED_NUM_ELEMENTLIST_BUTTONS; i++)
- {
- int gadget_id = GADGET_ID_ELEMENTLIST_FIRST + i;
- struct GadgetInfo *gi = level_editor_gadget[gadget_id];
- struct GadgetDesign *gd = &gi->deco.design;
- int element = editor_element[element_shift + i];
-
- UnmapGadget(gi);
- getMiniGraphicSource(el2gfx(element), &gd->bitmap, &gd->x, &gd->y);
- ModifyGadget(gi, GDI_INFO_TEXT, getElementInfoText(element), GDI_END);
- MapGadget(gi);
- }
+ ModifyEditorElementList();
+
break;
case GADGET_ID_WRAP_LEFT:
case GADGET_ID_FLOOD_FILL:
case GADGET_ID_GRAB_BRUSH:
case GADGET_ID_PICK_ELEMENT:
- last_drawing_function = drawing_function;
+ if (drawing_function != GADGET_ID_PICK_ELEMENT)
+ last_drawing_function = drawing_function;
drawing_function = id;
draw_with_brush = FALSE;
break;
break;
}
+ if (edit_mode != ED_MODE_DRAWING)
+ {
+ DrawDrawingWindow();
+ edit_mode = ED_MODE_DRAWING;
+ }
+
undo_buffer_position =
(undo_buffer_position - 1 + NUM_UNDO_STEPS) % NUM_UNDO_STEPS;
undo_buffer_steps--;
break;
case GADGET_ID_CLEAR:
+ if (edit_mode != ED_MODE_DRAWING)
+ {
+ DrawDrawingWindow();
+ edit_mode = ED_MODE_DRAWING;
+ }
+
for(x=0; x<MAX_LEV_FIELDX; x++)
for(y=0; y<MAX_LEV_FIELDY; y++)
- Feld[x][y] = (button == 1 ? EL_LEERRAUM : new_element);
+ Feld[x][y] = (button == 1 ? EL_EMPTY : new_element);
CopyLevelToUndoBuffer(GADGET_ID_CLEAR);
DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
Request("No Level without Gregor Mc Duffin please !", REQ_CONFIRM);
else
{
- if (Request("Save this level and kill the old ?", REQ_ASK))
+ boolean new_level = (!LevelFileExists(level_nr));
+
+ if (new_level ||
+ Request("Save this level and kill the old ?", REQ_ASK))
{
- for(x=0; x<lev_fieldx; x++)
- for(y=0; y<lev_fieldy; y++)
- Ur[x][y] = Feld[x][y];
+ CopyPlayfield(Feld, level.field);
+
SaveLevel(level_nr);
}
+
+ if (new_level)
+ Request("Level saved !", REQ_CONFIRM);
}
break;
if (LevelChanged())
level.game_version = GAME_VERSION_ACTUAL;
- for(x=0; x<lev_fieldx; x++)
- for(y=0; y<lev_fieldy; y++)
- FieldBackup[x][y] = Ur[x][y];
-
- for(x=0; x<lev_fieldx; x++)
- for(y=0; y<lev_fieldy; y++)
- Ur[x][y] = Feld[x][y];
+ CopyPlayfield(level.field, FieldBackup);
+ CopyPlayfield(Feld, level.field);
UnmapLevelEditorGadgets();
UndrawSpecialEditorDoor();
TapeStartRecording();
level_editor_test_game = TRUE;
- game_status = PLAYING;
+ game_status = GAME_MODE_PLAYING;
InitGame();
}
id <= GADGET_ID_ELEMENTLIST_LAST)
{
int element_position = id - GADGET_ID_ELEMENTLIST_FIRST;
- int new_element = editor_element[element_position + element_shift];
+ int new_element = editor_elements[element_position + element_shift];
PickDrawingElement(button, new_element);
- if (!HAS_CONTENT(properties_element) ||
- !stick_element_properties_window)
+ if (!stick_element_properties_window &&
+ drawing_function != GADGET_ID_PICK_ELEMENT &&
+ !(GetKeyModState() & KMOD_Control))
{
properties_element = new_element;
if (edit_mode == ED_MODE_PROPERTIES)
}
}
+void HandleLevelEditorIdle()
+{
+ static unsigned long action_delay = 0;
+ unsigned long action_delay_value = GameFrameDelay;
+ int xpos = 1, ypos = 2;
+
+ if (edit_mode != ED_MODE_PROPERTIES)
+ return;
+
+ if (!DelayReached(&action_delay, action_delay_value))
+ return;
+
+ DrawGraphicAnimationExt(drawto,
+ SX + xpos * TILEX,
+ SY + ypos * TILEY + MINI_TILEY / 2,
+ el2img(properties_element), -1, NO_MASKING);
+
+ MarkTileDirty(xpos, ypos);
+ MarkTileDirty(xpos, ypos + 1);
+
+ FrameCounter++; /* increase animation frame counter */
+}
+
void ClearEditorGadgetInfoText()
{
- ClearRectangle(drawto,
- INFOTEXT_XPOS, INFOTEXT_YPOS, INFOTEXT_XSIZE, INFOTEXT_YSIZE);
- redraw_mask |= REDRAW_FIELD;
+ DrawBackground(INFOTEXT_XPOS, INFOTEXT_YPOS, INFOTEXT_XSIZE, INFOTEXT_YSIZE);
}
void HandleEditorGadgetInfoText(void *ptr)
{
struct GadgetInfo *gi = (struct GadgetInfo *)ptr;
- char infotext[MAX_INFOTEXT_LEN + 1];
- char shortcut[MAX_INFOTEXT_LEN + 1];
+ char infotext[MAX_OUTPUT_LINESIZE + 1];
+ char shortcut[MAX_OUTPUT_LINESIZE + 1];
+ int max_infotext_len = getMaxInfoTextLength();
- if (game_status != LEVELED)
+ if (game_status != GAME_MODE_EDITOR)
return;
ClearEditorGadgetInfoText();
if (gi == NULL || gi->info_text == NULL)
return;
- strncpy(infotext, gi->info_text, MAX_INFOTEXT_LEN);
- infotext[MAX_INFOTEXT_LEN] = '\0';
+ strncpy(infotext, gi->info_text, max_infotext_len);
+ infotext[max_infotext_len] = '\0';
if (gi->custom_id < ED_NUM_CTRL_BUTTONS)
{
{
if (gi->custom_id == GADGET_ID_SINGLE_ITEMS) /* special case 1 */
sprintf(shortcut, " ('.' or '%c')", key);
- else if (gi->custom_id == GADGET_ID_TEST) /* special case 2 */
+ else if (gi->custom_id == GADGET_ID_PICK_ELEMENT) /* special case 2 */
+ sprintf(shortcut, " ('%c' or 'Ctrl')", key);
+ else if (gi->custom_id == GADGET_ID_TEST) /* special case 3 */
sprintf(shortcut, " ('Enter' or 'Shift-%c')", key);
else /* normal case */
sprintf(shortcut, " ('%s%c')",
(key >= 'A' && key <= 'Z' ? "Shift-" : ""), key);
- if (strlen(infotext) + strlen(shortcut) <= MAX_INFOTEXT_LEN)
+ if (strlen(infotext) + strlen(shortcut) <= max_infotext_len)
strcat(infotext, shortcut);
}
}
- DrawText(INFOTEXT_XPOS, INFOTEXT_YPOS, infotext, FS_SMALL, FC_YELLOW);
+ DrawText(INFOTEXT_XPOS, INFOTEXT_YPOS, infotext, FONT_TEXT_2);
}
static void HandleDrawingAreaInfo(struct GadgetInfo *gi)
int min_sx = 0, min_sy = 0;
int max_sx = gi->drawing.area_xsize - 1;
int max_sy = gi->drawing.area_ysize - 1;
+ int actual_drawing_function = drawing_function;
+
+ /* pressed Control key: simulate picking element */
+ if (GetKeyModState() & KMOD_Control)
+ actual_drawing_function = GADGET_ID_PICK_ELEMENT;
ClearEditorGadgetInfoText();
start_ly = ly;
}
- switch (drawing_function)
+ switch (actual_drawing_function)
{
case GADGET_ID_SINGLE_ITEMS:
infotext = "Drawing single items";
break;
}
- if (drawing_function == GADGET_ID_PICK_ELEMENT)
- DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW,
+ if (actual_drawing_function == GADGET_ID_PICK_ELEMENT)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
"%s: %d, %d", infotext, lx, ly);
else
- DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW,
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
"%s: %d, %d", infotext,
ABS(lx - start_lx) + 1, ABS(ly - start_ly) + 1);
}
- else if (drawing_function == GADGET_ID_PICK_ELEMENT)
- DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW,
+ else if (actual_drawing_function == GADGET_ID_PICK_ELEMENT)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
"%s", getElementInfoText(Feld[lx][ly]));
else
- DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW,
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
"Level position: %d, %d", lx, ly);
}
DeleteBrushFromCursor();
}
}
- else if (id == GADGET_ID_AMOEBA_CONTENT)
- DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW,
- "Amoeba content");
- else if (id == GADGET_ID_RANDOM_BACKGROUND)
- DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW,
- "Random placement background");
+ else if (actual_drawing_function == GADGET_ID_PICK_ELEMENT)
+ {
+ if (id == GADGET_ID_AMOEBA_CONTENT)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s",
+ getElementInfoText(level.amoeba_content));
+ else if (id == GADGET_ID_CUSTOM_GRAPHIC)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s",
+ getElementInfoText(custom_element.gfx_element));
+ else if (id == GADGET_ID_CUSTOM_CONTENT)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s",
+ getElementInfoText(custom_element.content[sx][sy]));
+ else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s",
+ getElementInfoText(custom_element.change.target_element));
+ else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s",
+ getElementInfoText(custom_element.change.content[sx][sy]));
+ else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s",
+ getElementInfoText(custom_element.change.trigger_element));
+ else if (id == GADGET_ID_RANDOM_BACKGROUND)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s",
+ getElementInfoText(random_placement_background_element));
+ else if (id >= GADGET_ID_ELEMENT_CONTENT_0 &&
+ id <= GADGET_ID_ELEMENT_CONTENT_7)
+ {
+ int i = id - GADGET_ID_ELEMENT_CONTENT_0;
+
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2, "%s",
+ getElementInfoText(level.yamyam_content[i][sx][sy]));
+ }
+ }
else
- DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FC_YELLOW,
- "Content area %d position: %d, %d",
- id - GADGET_ID_ELEM_CONTENT_0 + 1, sx, sy);
+ {
+ if (id == GADGET_ID_AMOEBA_CONTENT)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
+ "Amoeba content");
+ else if (id == GADGET_ID_CUSTOM_GRAPHIC)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
+ "Custom graphic element");
+ else if (id == GADGET_ID_CUSTOM_CONTENT)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
+ "Custom element content position: %d, %d", sx, sy);
+ else if (id == GADGET_ID_CUSTOM_CHANGE_TARGET)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
+ "New element after change");
+ else if (id == GADGET_ID_CUSTOM_CHANGE_CONTENT)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
+ "New extended elements after change");
+ else if (id == GADGET_ID_CUSTOM_CHANGE_TRIGGER)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
+ "Other element triggering change");
+ else if (id == GADGET_ID_RANDOM_BACKGROUND)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
+ "Random placement background");
+ else if (id >= GADGET_ID_ELEMENT_CONTENT_0 &&
+ id <= GADGET_ID_ELEMENT_CONTENT_7)
+ DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
+ "Content area %d position: %d, %d",
+ id - GADGET_ID_ELEMENT_CONTENT_0 + 1, sx, sy);
+ }
}
void RequestExitLevelEditor(boolean ask_if_level_has_changed)
/*
CloseDoor(DOOR_CLOSE_ALL);
*/
- game_status = MAINMENU;
+ game_status = GAME_MODE_MAIN;
DrawMainMenu();
}
else
{
CloseDoor(DOOR_CLOSE_1);
- BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
+ 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);
extern int elements_in_list;
void CreateLevelEditorGadgets();
+void FreeLevelEditorGadgets();
void UnmapLevelEditorGadgets();
void DrawLevelEd(void);
void HandleLevelEditorKeyInput(Key);
+void HandleLevelEditorIdle();
void HandleEditorGadgetInfoText(void *ptr);
void RequestExitLevelEditor(boolean);
#include "tape.h"
#include "network.h"
-/* values for key_status */
-#define KEY_NOT_PRESSED FALSE
-#define KEY_RELEASED FALSE
-#define KEY_PRESSED TRUE
+
+static boolean cursor_inside_playfield = FALSE;
+static boolean playfield_cursor_set = FALSE;
+static unsigned long playfield_cursor_delay = 0;
/* event filter especially needed for SDL event filtering due to
- delay problems with lots of mouse motion events when mouse
- button not pressed */
+ delay problems with lots of mouse motion events when mouse button
+ not pressed (X11 can handle this with 'PointerMotionHintMask') */
int FilterMouseMotionEvents(const Event *event)
{
+ MotionEvent *motion;
+
+ /* non-motion events are directly passed to event handler functions */
if (event->type != EVENT_MOTIONNOTIFY)
return 1;
- /* get mouse motion events without pressed button only in level editor */
- if (button_status == MB_RELEASED && game_status != LEVELED)
+ motion = (MotionEvent *)event;
+ cursor_inside_playfield = (motion->x >= SX && motion->x < SX + SXSIZE &&
+ motion->y >= SY && motion->y < SY + SYSIZE);
+
+ if (game_status == GAME_MODE_PLAYING && playfield_cursor_set)
+ {
+ SetMouseCursor(CURSOR_DEFAULT);
+ playfield_cursor_set = FALSE;
+ DelayReached(&playfield_cursor_delay, 0);
+ }
+
+ /* 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)
return 0;
else
return 1;
}
}
else
+ {
+ /* when playing, display a special mouse pointer inside the playfield */
+ if (game_status == GAME_MODE_PLAYING)
+ {
+ if (!playfield_cursor_set && cursor_inside_playfield &&
+ DelayReached(&playfield_cursor_delay, 1000))
+ {
+ SetMouseCursor(CURSOR_PLAYFIELD);
+ playfield_cursor_set = TRUE;
+ }
+ }
+ else if (playfield_cursor_set)
+ {
+ SetMouseCursor(CURSOR_DEFAULT);
+ playfield_cursor_set = FALSE;
+ }
+
HandleNoEvent();
+ }
/* don't use all CPU time when idle; the main loop while playing
has its own synchronization and is CPU friendly, too */
- if (game_status == PLAYING)
+ if (game_status == GAME_MODE_PLAYING)
HandleGameActions();
else
{
/* refresh window contents from drawing buffer, if needed */
BackToFront();
- if (game_status == EXITGAME)
+ if (game_status == GAME_MODE_QUIT)
return;
}
}
break;
case EVENT_UNMAPNOTIFY:
+#if 0
+ /* This causes the game to stop not only when iconified, but also
+ when on another virtual desktop, which might be not desired. */
SleepWhileUnmapped();
+#endif
break;
case EVENT_FOCUSIN:
}
}
- if (game_status == PLAYING)
- KeyboardAutoRepeatOff();
+ if (game_status == GAME_MODE_PLAYING)
+ KeyboardAutoRepeatOffUnlessAutoplay();
}
void HandleExposeEvent(ExposeEvent *event)
return; /* window and pointer are on different screens */
#if 1
- if (button_status == MB_RELEASED && game_status != LEVELED)
+ if (button_status == MB_RELEASED && game_status != GAME_MODE_EDITOR)
return;
#endif
void HandleKeyEvent(KeyEvent *event)
{
int key_status = (event->type==EVENT_KEYPRESS ? KEY_PRESSED : KEY_RELEASED);
- boolean with_modifiers = (game_status == PLAYING ? FALSE : TRUE);
+ boolean with_modifiers = (game_status == GAME_MODE_PLAYING ? FALSE : TRUE);
Key key = GetEventKey(event, with_modifiers);
+ Key keymod = (with_modifiers ? GetEventKey(event, FALSE) : key);
+ HandleKeyModState(keymod, key_status);
HandleKey(key, key_status);
}
because unfortunately this is a global setting and not (which
would be far better) set for each X11 window individually.
The effect would be keyboard auto repeat while playing the game
- (game_status == PLAYING), which is not desired.
+ (game_status == GAME_MODE_PLAYING), which is not desired.
To avoid this special case, we just wait 1/10 second before
processing the 'FocusIn' event.
*/
- if (game_status == PLAYING)
+ if (game_status == GAME_MODE_PLAYING)
{
Delay(100);
- KeyboardAutoRepeatOff();
+ KeyboardAutoRepeatOffUnlessAutoplay();
}
if (old_joystick_status != -1)
joystick.status = old_joystick_status;
switch(game_status)
{
- case MAINMENU:
+ case GAME_MODE_MAIN:
HandleMainMenu(mx,my, 0,0, button);
break;
- case TYPENAME:
+ case GAME_MODE_PSEUDO_TYPENAME:
HandleTypeName(0, KSYM_Return);
break;
- case CHOOSELEVEL:
+ case GAME_MODE_LEVELS:
HandleChooseLevel(mx,my, 0,0, button);
break;
- case HALLOFFAME:
+ case GAME_MODE_SCORES:
HandleHallOfFame(0,0, 0,0, button);
break;
- case LEVELED:
+ case GAME_MODE_EDITOR:
break;
- case HELPSCREEN:
+ case GAME_MODE_INFO:
HandleHelpScreen(button);
break;
- case SETUP:
+ case GAME_MODE_SETUP:
HandleSetupScreen(mx,my, 0,0, button);
break;
- case PLAYING:
+ case GAME_MODE_PLAYING:
#ifdef DEBUG
if (button == MB_RELEASED)
{
if (!IN_LEV_FIELD(x, y))
break;
- printf(" Feld[%d][%d] == %d\n", x,y, Feld[x][y]);
+ printf(" Feld[%d][%d] == %d ('%s')\n", x,y, Feld[x][y],
+ element_info[Feld[x][y]].token_name);
printf(" Store[%d][%d] == %d\n", x,y, Store[x][y]);
printf(" Store2[%d][%d] == %d\n", x,y, Store2[x][y]);
printf(" StorePlayer[%d][%d] == %d\n", x,y, StorePlayer[x][y]);
printf(" MovPos[%d][%d] == %d\n", x,y, MovPos[x][y]);
printf(" MovDir[%d][%d] == %d\n", x,y, MovDir[x][y]);
printf(" MovDelay[%d][%d] == %d\n", x,y, MovDelay[x][y]);
+ printf(" ChangeDelay[%d][%d] == %d\n", x,y, ChangeDelay[x][y]);
+ printf(" GfxElement[%d][%d] == %d\n", x,y, GfxElement[x][y]);
+ printf(" GfxAction[%d][%d] == %d\n", x,y, GfxAction[x][y]);
printf("\n");
}
}
{ &custom_key.bomb, DEFAULT_KEY_BOMB, JOY_BUTTON_2 }
};
- if (game_status == PLAYING)
+ if (game_status == GAME_MODE_PLAYING)
{
/* only needed for single-step tape recording mode */
static boolean clear_button_2[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE };
HandleJoystick();
}
- if (game_status != PLAYING)
+ if (game_status != GAME_MODE_PLAYING)
key_joystick_mapping = 0;
if (key_status == KEY_RELEASED)
return;
if ((key == KSYM_Return || key == setup.shortcut.toggle_pause) &&
- game_status == PLAYING && AllPlayersGone)
+ game_status == GAME_MODE_PLAYING && AllPlayersGone)
{
CloseDoor(DOOR_CLOSE_1);
- game_status = MAINMENU;
+ game_status = GAME_MODE_MAIN;
DrawMainMenu();
return;
}
/* allow quick escape to the main menu with the Escape key */
if (key == KSYM_Escape &&
- game_status != MAINMENU &&
- game_status != PLAYING &&
- game_status != LEVELED &&
- game_status != CHOOSELEVEL &&
- game_status != SETUP)
+ game_status != GAME_MODE_MAIN &&
+ game_status != GAME_MODE_PLAYING &&
+ game_status != GAME_MODE_EDITOR &&
+ game_status != GAME_MODE_LEVELS &&
+ game_status != GAME_MODE_SETUP)
{
- game_status = MAINMENU;
+ game_status = GAME_MODE_MAIN;
DrawMainMenu();
return;
}
/* special key shortcuts */
- if (game_status == MAINMENU || game_status == PLAYING)
+ if (game_status == GAME_MODE_MAIN || game_status == GAME_MODE_PLAYING)
{
if (key == setup.shortcut.save_game)
TapeQuickSave();
TapeTogglePause(TAPE_TOGGLE_MANUAL);
}
-
+#if 0
#ifndef DEBUG
- if (game_status == PLAYING && (tape.playing || tape.pausing))
+ if (game_status == GAME_MODE_PLAYING && (tape.playing || tape.pausing))
return;
#endif
-
+#endif
HandleGadgetsKeyInput(key);
switch(game_status)
{
- case TYPENAME:
+ case GAME_MODE_PSEUDO_TYPENAME:
HandleTypeName(0, key);
break;
- case MAINMENU:
- case CHOOSELEVEL:
- case SETUP:
+ case GAME_MODE_MAIN:
+ case GAME_MODE_LEVELS:
+ case GAME_MODE_SETUP:
switch(key)
{
case KSYM_Return:
- if (game_status == MAINMENU)
+ if (game_status == GAME_MODE_MAIN)
HandleMainMenu(0,0, 0,0, MB_MENU_CHOICE);
- else if (game_status == CHOOSELEVEL)
+ else if (game_status == GAME_MODE_LEVELS)
HandleChooseLevel(0,0, 0,0, MB_MENU_CHOICE);
- else if (game_status == SETUP)
+ else if (game_status == GAME_MODE_SETUP)
HandleSetupScreen(0,0, 0,0, MB_MENU_CHOICE);
break;
case KSYM_Escape:
- if (game_status == CHOOSELEVEL)
+ if (game_status == GAME_MODE_LEVELS)
HandleChooseLevel(0,0, 0,0, MB_MENU_LEAVE);
- else if (game_status == SETUP)
+ else if (game_status == GAME_MODE_SETUP)
HandleSetupScreen(0,0, 0,0, MB_MENU_LEAVE);
break;
case KSYM_Page_Up:
- if (game_status == CHOOSELEVEL)
- HandleChooseLevel(0,0, 0,-SCR_FIELDY, MB_MENU_MARK);
- else if (game_status == SETUP)
- HandleSetupScreen(0,0, 0,-SCR_FIELDY, MB_MENU_MARK);
+ if (game_status == GAME_MODE_LEVELS)
+ HandleChooseLevel(0,0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK);
+ else if (game_status == GAME_MODE_SETUP)
+ HandleSetupScreen(0,0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK);
break;
case KSYM_Page_Down:
- if (game_status == CHOOSELEVEL)
- HandleChooseLevel(0,0, 0,SCR_FIELDY, MB_MENU_MARK);
- else if (game_status == SETUP)
- HandleSetupScreen(0,0, 0,SCR_FIELDY, MB_MENU_MARK);
+ if (game_status == GAME_MODE_LEVELS)
+ HandleChooseLevel(0,0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK);
+ else if (game_status == GAME_MODE_SETUP)
+ HandleSetupScreen(0,0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK);
break;
#ifdef DEBUG
}
break;
- case HELPSCREEN:
+ case GAME_MODE_INFO:
HandleHelpScreen(MB_RELEASED);
break;
- case HALLOFFAME:
+ case GAME_MODE_SCORES:
switch(key)
{
case KSYM_Return:
- game_status = MAINMENU;
+ game_status = GAME_MODE_MAIN;
DrawMainMenu();
BackToFront();
break;
case KSYM_Page_Up:
- HandleHallOfFame(0,0, 0,-SCR_FIELDY, MB_MENU_MARK);
+ HandleHallOfFame(0,0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK);
break;
case KSYM_Page_Down:
- HandleHallOfFame(0,0, 0,SCR_FIELDY, MB_MENU_MARK);
+ HandleHallOfFame(0,0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK);
break;
default:
}
break;
- case LEVELED:
+ case GAME_MODE_EDITOR:
if (!anyTextGadgetActiveOrJustFinished || key == KSYM_Escape)
HandleLevelEditorKeyInput(key);
break;
- case PLAYING:
+ case GAME_MODE_PLAYING:
{
switch(key)
{
void HandleNoEvent()
{
- if (button_status && game_status != PLAYING)
+ if (button_status && game_status != GAME_MODE_PLAYING)
{
HandleButton(0, 0, -button_status);
return;
switch(game_status)
{
- case MAINMENU:
- case CHOOSELEVEL:
- case SETUP:
+ case GAME_MODE_MAIN:
+ case GAME_MODE_LEVELS:
+ case GAME_MODE_SETUP:
{
static unsigned long joystickmove_delay = 0;
!DelayReached(&joystickmove_delay, GADGET_FRAME_DELAY))
newbutton = dx = dy = 0;
- if (game_status == MAINMENU)
+ if (game_status == GAME_MODE_MAIN)
HandleMainMenu(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
- else if (game_status == CHOOSELEVEL)
+ else if (game_status == GAME_MODE_LEVELS)
HandleChooseLevel(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
- else if (game_status == SETUP)
+ else if (game_status == GAME_MODE_SETUP)
HandleSetupScreen(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
break;
}
- case HALLOFFAME:
+ case GAME_MODE_SCORES:
HandleHallOfFame(0,0, dx,dy, !newbutton);
break;
- case HELPSCREEN:
+ case GAME_MODE_INFO:
HandleHelpScreen(!newbutton);
break;
- case PLAYING:
+ case GAME_MODE_EDITOR:
+ HandleLevelEditorIdle();
+ break;
+
+ case GAME_MODE_PLAYING:
if (tape.playing || keyboard)
newbutton = ((joy & JOY_BUTTON) != 0);
if (AllPlayersGone && newbutton)
{
CloseDoor(DOOR_CLOSE_1);
- game_status = MAINMENU;
+ game_status = GAME_MODE_MAIN;
DrawMainMenu();
return;
}
#include "libgame/libgame.h"
#include "files.h"
+#include "init.h"
#include "tools.h"
#include "tape.h"
#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 14 /* unused level header bytes */
+#define LEVEL_HEADER_UNUSED 13 /* 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_CPART_CUS3_SIZE 134 /* size of CUS3 chunk part */
+#define LEVEL_CPART_CUS3_UNUSED 15 /* unused CUS3 bytes / part */
#define TAPE_HEADER_SIZE 20 /* size of tape file header */
#define TAPE_HEADER_UNUSED 3 /* unused tape header bytes */
+#define LEVEL_CHUNK_CUS3_SIZE(x) (2 + x * LEVEL_CPART_CUS3_SIZE)
+
/* file identifier strings */
#define LEVEL_COOKIE_TMPL "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_x.x"
#define TAPE_COOKIE_TMPL "ROCKSNDIAMONDS_TAPE_FILE_VERSION_x.x"
/* level file functions */
/* ========================================================================= */
-static void setLevelInfoToDefaults()
+static void setLevelInfoToDefaults(struct LevelInfo *level)
{
- int i, x, y;
+ int i, j, x, y;
- level.file_version = FILE_VERSION_ACTUAL;
- level.game_version = GAME_VERSION_ACTUAL;
+ level->file_version = FILE_VERSION_ACTUAL;
+ level->game_version = GAME_VERSION_ACTUAL;
- level.encoding_16bit_field = FALSE; /* default: only 8-bit elements */
- level.encoding_16bit_yamyam = FALSE; /* default: only 8-bit elements */
- level.encoding_16bit_amoeba = FALSE; /* default: only 8-bit elements */
+ level->encoding_16bit_field = FALSE; /* default: only 8-bit elements */
+ level->encoding_16bit_yamyam = FALSE; /* default: only 8-bit elements */
+ level->encoding_16bit_amoeba = FALSE; /* default: only 8-bit elements */
- lev_fieldx = level.fieldx = STD_LEV_FIELDX;
- lev_fieldy = level.fieldy = STD_LEV_FIELDY;
+ level->fieldx = STD_LEV_FIELDX;
+ level->fieldy = STD_LEV_FIELDY;
for(x=0; x<MAX_LEV_FIELDX; x++)
for(y=0; y<MAX_LEV_FIELDY; y++)
- Feld[x][y] = Ur[x][y] = EL_ERDREICH;
-
- level.time = 100;
- level.gems_needed = 0;
- level.amoeba_speed = 10;
- level.time_magic_wall = 10;
- level.time_wheel = 10;
- level.time_light = 10;
- level.time_timegate = 10;
- level.amoeba_content = EL_DIAMANT;
- level.double_speed = FALSE;
- level.gravity = FALSE;
- level.em_slippery_gems = FALSE;
+ level->field[x][y] = EL_SAND;
+
+ level->time = 100;
+ level->gems_needed = 0;
+ level->amoeba_speed = 10;
+ level->time_magic_wall = 10;
+ level->time_wheel = 10;
+ level->time_light = 10;
+ level->time_timegate = 10;
+ level->amoeba_content = EL_DIAMOND;
+ level->double_speed = FALSE;
+ level->gravity = FALSE;
+ level->em_slippery_gems = FALSE;
+
+ level->use_custom_template = FALSE;
for(i=0; i<MAX_LEVEL_NAME_LEN; i++)
- level.name[i] = '\0';
+ level->name[i] = '\0';
for(i=0; i<MAX_LEVEL_AUTHOR_LEN; i++)
- level.author[i] = '\0';
+ level->author[i] = '\0';
- strcpy(level.name, NAMELESS_LEVEL_NAME);
- strcpy(level.author, ANONYMOUS_NAME);
+ strcpy(level->name, NAMELESS_LEVEL_NAME);
+ strcpy(level->author, ANONYMOUS_NAME);
for(i=0; i<LEVEL_SCORE_ELEMENTS; i++)
- level.score[i] = 10;
+ level->score[i] = 10;
- level.num_yam_contents = STD_ELEMENT_CONTENTS;
+ level->num_yamyam_contents = STD_ELEMENT_CONTENTS;
for(i=0; i<MAX_ELEMENT_CONTENTS; i++)
for(x=0; x<3; x++)
for(y=0; y<3; y++)
- level.yam_content[i][x][y] =
- (i < STD_ELEMENT_CONTENTS ? EL_FELSBROCKEN : EL_LEERRAUM);
+ level->yamyam_content[i][x][y] =
+ (i < STD_ELEMENT_CONTENTS ? EL_ROCK : EL_EMPTY);
+
+ level->field[0][0] = EL_PLAYER_1;
+ level->field[STD_LEV_FIELDX - 1][STD_LEV_FIELDY - 1] = EL_EXIT_CLOSED;
+
+ for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+ {
+ int element = EL_CUSTOM_START + i;
+
+ for(j=0; j<MAX_ELEMENT_NAME_LEN + 1; j++)
+ element_info[element].description[j] = '\0';
+ if (element_info[element].custom_description != NULL)
+ strncpy(element_info[element].description,
+ element_info[element].custom_description, MAX_ELEMENT_NAME_LEN);
+ else
+ strcpy(element_info[element].description,
+ element_info[element].editor_description);
+
+ element_info[element].use_gfx_element = FALSE;
+ element_info[element].gfx_element = EL_EMPTY_SPACE;
+
+ element_info[element].score = 0;
+ element_info[element].gem_count = 0;
+
+ element_info[element].push_delay_fixed = 2; /* special default */
+ element_info[element].push_delay_random = 8; /* special default */
+ element_info[element].move_delay_fixed = 0;
+ element_info[element].move_delay_random = 0;
+
+ element_info[element].move_pattern = MV_ALL_DIRECTIONS;
+ element_info[element].move_direction_initial = MV_NO_MOVING;
+ element_info[element].move_stepsize = TILEX / 8;
+
+ element_info[element].slippery_type = SLIPPERY_ANY_RANDOM;
+
+ for(x=0; x<3; x++)
+ for(y=0; y<3; y++)
+ element_info[element].content[x][y] = EL_EMPTY_SPACE;
+
+ element_info[element].change.events = CE_BITMASK_DEFAULT;
+ element_info[element].change.target_element = EL_EMPTY_SPACE;
+
+ element_info[element].change.delay_fixed = 0;
+ element_info[element].change.delay_random = 0;
+ element_info[element].change.delay_frames = -1; /* use default */
+
+ element_info[element].change.trigger_element = EL_EMPTY_SPACE;
- Feld[0][0] = Ur[0][0] = EL_SPIELFIGUR;
- Feld[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] =
- Ur[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] = EL_AUSGANG_ZU;
+ element_info[element].change.explode = FALSE;
+ element_info[element].change.use_content = FALSE;
+ element_info[element].change.only_complete = FALSE;
+ element_info[element].change.use_random_change = FALSE;
+ element_info[element].change.random = 0;
+ element_info[element].change.power = CP_NON_DESTRUCTIVE;
- BorderElement = EL_BETON;
+ for(x=0; x<3; x++)
+ for(y=0; y<3; y++)
+ element_info[element].change.content[x][y] = EL_EMPTY_SPACE;
+
+ element_info[element].access_type = 0;
+ element_info[element].access_layer = 0;
+ element_info[element].walk_to_action = 0;
+ element_info[element].smash_targets = 0;
+ element_info[element].deadliness = 0;
+ element_info[element].consistency = 0;
+ element_info[element].change_player_action = 0;
+ element_info[element].change_collide_action = 0;
+ element_info[element].change_other_action = 0;
+
+ element_info[element].can_explode_by_fire = FALSE;
+ element_info[element].can_explode_smashed = FALSE;
+ element_info[element].can_explode_impact = FALSE;
+
+ /* start with no properties at all */
+ for (j=0; j < NUM_EP_BITFIELDS; j++)
+ Properties[element][j] = EP_BITMASK_DEFAULT;
+ }
+
+ BorderElement = EL_STEELWALL;
+
+ level->no_level_file = FALSE;
+
+ if (leveldir_current == NULL) /* only when dumping level */
+ return;
/* try to determine better author name than 'anonymous' */
if (strcmp(leveldir_current->author, ANONYMOUS_NAME) != 0)
{
- strncpy(level.author, leveldir_current->author, MAX_LEVEL_AUTHOR_LEN);
- level.author[MAX_LEVEL_AUTHOR_LEN] = '\0';
+ strncpy(level->author, leveldir_current->author, MAX_LEVEL_AUTHOR_LEN);
+ level->author[MAX_LEVEL_AUTHOR_LEN] = '\0';
}
else
{
switch (LEVELCLASS(leveldir_current))
{
case LEVELCLASS_TUTORIAL:
- strcpy(level.author, PROGRAM_AUTHOR_STRING);
+ strcpy(level->author, PROGRAM_AUTHOR_STRING);
break;
case LEVELCLASS_CONTRIBUTION:
- strncpy(level.author, leveldir_current->name,MAX_LEVEL_AUTHOR_LEN);
- level.author[MAX_LEVEL_AUTHOR_LEN] = '\0';
+ strncpy(level->author, leveldir_current->name,MAX_LEVEL_AUTHOR_LEN);
+ level->author[MAX_LEVEL_AUTHOR_LEN] = '\0';
break;
case LEVELCLASS_USER:
- strncpy(level.author, getRealName(), MAX_LEVEL_AUTHOR_LEN);
- level.author[MAX_LEVEL_AUTHOR_LEN] = '\0';
+ strncpy(level->author, getRealName(), MAX_LEVEL_AUTHOR_LEN);
+ level->author[MAX_LEVEL_AUTHOR_LEN] = '\0';
break;
default:
}
}
+static void ActivateLevelTemplate()
+{
+ /* Currently there is no special action needed to activate the template
+ data, because 'element_info' and 'Properties' overwrite the original
+ level data, while all other variables do not change. */
+}
+
+boolean LevelFileExists(int level_nr)
+{
+ char *filename = getLevelFilename(level_nr);
+
+ return (access(filename, F_OK) == 0);
+}
+
static int checkLevelElement(int element)
{
- if (element >= EL_FIRST_RUNTIME_EL)
+ if (element >= NUM_FILE_ELEMENTS)
{
Error(ERR_WARN, "invalid level element %d", element);
- element = EL_CHAR_FRAGE;
+ element = EL_CHAR_QUESTION;
}
+ else if (element == EL_PLAYER_OBSOLETE)
+ element = EL_PLAYER_1;
+ else if (element == EL_KEY_OBSOLETE)
+ element = EL_KEY_1;
return element;
}
{
int i, x, y;
- lev_fieldx = level->fieldx = fgetc(file);
- lev_fieldy = level->fieldy = fgetc(file);
+ level->fieldx = getFile8Bit(file);
+ level->fieldy = getFile8Bit(file);
level->time = getFile16BitBE(file);
level->gems_needed = getFile16BitBE(file);
for(i=0; i<MAX_LEVEL_NAME_LEN; i++)
- level->name[i] = fgetc(file);
+ level->name[i] = getFile8Bit(file);
level->name[MAX_LEVEL_NAME_LEN] = 0;
for(i=0; i<LEVEL_SCORE_ELEMENTS; i++)
- level->score[i] = fgetc(file);
+ level->score[i] = getFile8Bit(file);
- level->num_yam_contents = STD_ELEMENT_CONTENTS;
+ level->num_yamyam_contents = STD_ELEMENT_CONTENTS;
for(i=0; i<STD_ELEMENT_CONTENTS; i++)
for(y=0; y<3; y++)
for(x=0; x<3; x++)
- level->yam_content[i][x][y] = checkLevelElement(fgetc(file));
+ level->yamyam_content[i][x][y] = checkLevelElement(getFile8Bit(file));
+
+ level->amoeba_speed = getFile8Bit(file);
+ level->time_magic_wall = getFile8Bit(file);
+ level->time_wheel = getFile8Bit(file);
+ level->amoeba_content = checkLevelElement(getFile8Bit(file));
+ level->double_speed = (getFile8Bit(file) == 1 ? TRUE : FALSE);
+ level->gravity = (getFile8Bit(file) == 1 ? TRUE : FALSE);
+ level->encoding_16bit_field = (getFile8Bit(file) == 1 ? TRUE : FALSE);
+ level->em_slippery_gems = (getFile8Bit(file) == 1 ? TRUE : FALSE);
- level->amoeba_speed = fgetc(file);
- level->time_magic_wall = fgetc(file);
- level->time_wheel = fgetc(file);
- level->amoeba_content = checkLevelElement(fgetc(file));
- level->double_speed = (fgetc(file) == 1 ? TRUE : FALSE);
- level->gravity = (fgetc(file) == 1 ? TRUE : FALSE);
- level->encoding_16bit_field = (fgetc(file) == 1 ? TRUE : FALSE);
- level->em_slippery_gems = (fgetc(file) == 1 ? TRUE : FALSE);
+ level->use_custom_template = (getFile8Bit(file) == 1 ? TRUE : FALSE);
ReadUnusedBytesFromFile(file, LEVEL_HEADER_UNUSED);
int i;
for(i=0; i<MAX_LEVEL_AUTHOR_LEN; i++)
- level->author[i] = fgetc(file);
+ level->author[i] = getFile8Bit(file);
level->author[MAX_LEVEL_NAME_LEN] = 0;
return chunk_size;
}
-static int LoadLevel_CONT(FILE *file, int chunk_size, struct LevelInfo *level)
+static int LoadLevel_BODY(FILE *file, int chunk_size, struct LevelInfo *level)
{
- int i, x, y;
- int header_size = 4;
- int content_size = MAX_ELEMENT_CONTENTS * 3 * 3;
- int chunk_size_expected = header_size + content_size;
+ int x, y;
+ int chunk_size_expected = level->fieldx * level->fieldy;
/* Note: "chunk_size" was wrong before version 2.0 when elements are
stored with 16-bit encoding (and should be twice as big then).
contained 16-bit elements and vice versa. */
if (level->encoding_16bit_field && level->file_version >= FILE_VERSION_2_0)
- chunk_size_expected += content_size;
+ chunk_size_expected *= 2;
if (chunk_size_expected != chunk_size)
{
return chunk_size_expected;
}
- fgetc(file);
- level->num_yam_contents = fgetc(file);
- fgetc(file);
- fgetc(file);
-
- /* correct invalid number of content fields -- should never happen */
- if (level->num_yam_contents < 1 ||
- level->num_yam_contents > MAX_ELEMENT_CONTENTS)
- level->num_yam_contents = STD_ELEMENT_CONTENTS;
-
- for(i=0; i<MAX_ELEMENT_CONTENTS; i++)
- for(y=0; y<3; y++)
- for(x=0; x<3; x++)
- level->yam_content[i][x][y] =
- checkLevelElement(level->encoding_16bit_field ?
- getFile16BitBE(file) : fgetc(file));
+ for(y=0; y<level->fieldy; y++)
+ for(x=0; x<level->fieldx; x++)
+ level->field[x][y] =
+ checkLevelElement(level->encoding_16bit_field ? getFile16BitBE(file) :
+ getFile8Bit(file));
return chunk_size;
}
-static int LoadLevel_BODY(FILE *file, int chunk_size, struct LevelInfo *level)
+static int LoadLevel_CONT(FILE *file, int chunk_size, struct LevelInfo *level)
{
- int x, y;
- int chunk_size_expected = level->fieldx * level->fieldy;
+ int i, x, y;
+ int header_size = 4;
+ int content_size = MAX_ELEMENT_CONTENTS * 3 * 3;
+ int chunk_size_expected = header_size + content_size;
/* Note: "chunk_size" was wrong before version 2.0 when elements are
stored with 16-bit encoding (and should be twice as big then).
contained 16-bit elements and vice versa. */
if (level->encoding_16bit_field && level->file_version >= FILE_VERSION_2_0)
- chunk_size_expected *= 2;
+ chunk_size_expected += content_size;
if (chunk_size_expected != chunk_size)
{
return chunk_size_expected;
}
- for(y=0; y<level->fieldy; y++)
- for(x=0; x<level->fieldx; x++)
- Feld[x][y] = Ur[x][y] =
- checkLevelElement(level->encoding_16bit_field ?
- getFile16BitBE(file) : fgetc(file));
+ getFile8Bit(file);
+ level->num_yamyam_contents = getFile8Bit(file);
+ getFile8Bit(file);
+ getFile8Bit(file);
+
+ /* correct invalid number of content fields -- should never happen */
+ if (level->num_yamyam_contents < 1 ||
+ level->num_yamyam_contents > MAX_ELEMENT_CONTENTS)
+ level->num_yamyam_contents = STD_ELEMENT_CONTENTS;
+
+ for(i=0; i<MAX_ELEMENT_CONTENTS; i++)
+ for(y=0; y<3; y++)
+ for(x=0; x<3; x++)
+ level->yamyam_content[i][x][y] =
+ checkLevelElement(level->encoding_16bit_field ?
+ getFile16BitBE(file) : getFile8Bit(file));
return chunk_size;
}
int content_array[MAX_ELEMENT_CONTENTS][3][3];
element = checkLevelElement(getFile16BitBE(file));
- num_contents = fgetc(file);
- content_xsize = fgetc(file);
- content_ysize = fgetc(file);
+ num_contents = getFile8Bit(file);
+ content_xsize = getFile8Bit(file);
+ content_ysize = getFile8Bit(file);
ReadUnusedBytesFromFile(file, LEVEL_CHUNK_CNT2_UNUSED);
for(i=0; i<MAX_ELEMENT_CONTENTS; i++)
if (num_contents < 1 || num_contents > MAX_ELEMENT_CONTENTS)
num_contents = STD_ELEMENT_CONTENTS;
- if (element == EL_MAMPFER)
+ if (element == EL_YAMYAM)
{
- level->num_yam_contents = num_contents;
+ level->num_yamyam_contents = num_contents;
for(i=0; i<num_contents; i++)
for(y=0; y<3; y++)
for(x=0; x<3; x++)
- level->yam_content[i][x][y] = content_array[i][x][y];
+ level->yamyam_content[i][x][y] = content_array[i][x][y];
}
- else if (element == EL_AMOEBE_BD)
+ else if (element == EL_BD_AMOEBA)
{
level->amoeba_content = content_array[0][0][0];
}
return chunk_size;
}
-void LoadLevel(int level_nr)
+static int LoadLevel_CUS1(FILE *file, int chunk_size, struct LevelInfo *level)
+{
+ int num_changed_custom_elements = getFile16BitBE(file);
+ int chunk_size_expected = 2 + num_changed_custom_elements * 6;
+ int i;
+
+ if (chunk_size_expected != chunk_size)
+ {
+ ReadUnusedBytesFromFile(file, chunk_size - 2);
+ return chunk_size_expected;
+ }
+
+ for (i=0; i < num_changed_custom_elements; i++)
+ {
+ int element = getFile16BitBE(file);
+ int properties = getFile32BitBE(file);
+
+ if (IS_CUSTOM_ELEMENT(element))
+ Properties[element][EP_BITFIELD_BASE] = properties;
+ else
+ Error(ERR_WARN, "invalid custom element number %d", element);
+ }
+
+ return chunk_size;
+}
+
+static int LoadLevel_CUS2(FILE *file, int chunk_size, struct LevelInfo *level)
+{
+ int num_changed_custom_elements = getFile16BitBE(file);
+ int chunk_size_expected = 2 + num_changed_custom_elements * 4;
+ int i;
+
+ if (chunk_size_expected != chunk_size)
+ {
+ ReadUnusedBytesFromFile(file, chunk_size - 2);
+ return chunk_size_expected;
+ }
+
+ for (i=0; i < num_changed_custom_elements; i++)
+ {
+ int element = getFile16BitBE(file);
+ int custom_target_element = getFile16BitBE(file);
+
+ if (IS_CUSTOM_ELEMENT(element))
+ element_info[element].change.target_element = custom_target_element;
+ else
+ Error(ERR_WARN, "invalid custom element number %d", element);
+ }
+
+ return chunk_size;
+}
+
+static int LoadLevel_CUS3(FILE *file, int chunk_size, struct LevelInfo *level)
+{
+ int num_changed_custom_elements = getFile16BitBE(file);
+ int chunk_size_expected = LEVEL_CHUNK_CUS3_SIZE(num_changed_custom_elements);
+ int i, j, x, y;
+
+ if (chunk_size_expected != chunk_size)
+ {
+ ReadUnusedBytesFromFile(file, chunk_size - 2);
+ return chunk_size_expected;
+ }
+
+ for (i=0; i < num_changed_custom_elements; i++)
+ {
+ int element = getFile16BitBE(file);
+
+ if (!IS_CUSTOM_ELEMENT(element))
+ {
+ Error(ERR_WARN, "invalid custom element number %d", element);
+
+ element = EL_DEFAULT; /* dummy element used for artwork config */
+ }
+
+ for(j=0; j<MAX_ELEMENT_NAME_LEN; j++)
+ element_info[element].description[j] = getFile8Bit(file);
+ element_info[element].description[MAX_ELEMENT_NAME_LEN] = 0;
+
+ Properties[element][EP_BITFIELD_BASE] = getFile32BitBE(file);
+
+ /* some free bytes for future properties and padding */
+ ReadUnusedBytesFromFile(file, 7);
+
+ element_info[element].use_gfx_element = getFile8Bit(file);
+ element_info[element].gfx_element =
+ checkLevelElement(getFile16BitBE(file));
+
+ element_info[element].score = getFile8Bit(file);
+ element_info[element].gem_count = getFile8Bit(file);
+
+ element_info[element].push_delay_fixed = getFile16BitBE(file);
+ element_info[element].push_delay_random = getFile16BitBE(file);
+ element_info[element].move_delay_fixed = getFile16BitBE(file);
+ element_info[element].move_delay_random = getFile16BitBE(file);
+
+ element_info[element].move_pattern = getFile16BitBE(file);
+ element_info[element].move_direction_initial = getFile8Bit(file);
+ element_info[element].move_stepsize = getFile8Bit(file);
+
+ for(y=0; y<3; y++)
+ for(x=0; x<3; x++)
+ element_info[element].content[x][y] =
+ checkLevelElement(getFile16BitBE(file));
+
+ element_info[element].change.events = getFile32BitBE(file);
+
+ element_info[element].change.target_element =
+ checkLevelElement(getFile16BitBE(file));
+
+ element_info[element].change.delay_fixed = getFile16BitBE(file);
+ element_info[element].change.delay_random = getFile16BitBE(file);
+ element_info[element].change.delay_frames = getFile16BitBE(file);
+
+ element_info[element].change.trigger_element =
+ checkLevelElement(getFile16BitBE(file));
+
+ element_info[element].change.explode = getFile8Bit(file);
+ element_info[element].change.use_content = getFile8Bit(file);
+ element_info[element].change.only_complete = getFile8Bit(file);
+ element_info[element].change.use_random_change = getFile8Bit(file);
+
+ element_info[element].change.random = getFile8Bit(file);
+ element_info[element].change.power = getFile8Bit(file);
+
+ for(y=0; y<3; y++)
+ for(x=0; x<3; x++)
+ element_info[element].change.content[x][y] =
+ checkLevelElement(getFile16BitBE(file));
+
+ element_info[element].slippery_type = getFile8Bit(file);
+
+ /* some free bytes for future properties and padding */
+ ReadUnusedBytesFromFile(file, LEVEL_CPART_CUS3_UNUSED);
+ }
+
+ return chunk_size;
+}
+
+void LoadLevelFromFilename(struct LevelInfo *level, char *filename)
{
- char *filename = getLevelFilename(level_nr);
char cookie[MAX_LINE_LEN];
char chunk_name[CHUNK_ID_LEN + 1];
int chunk_size;
FILE *file;
/* always start with reliable default values */
- setLevelInfoToDefaults();
+ setLevelInfoToDefaults(level);
if (!(file = fopen(filename, MODE_READ)))
{
- Error(ERR_WARN, "cannot read level '%s' - creating new level", filename);
+ level->no_level_file = TRUE;
+
+ if (level != &level_template)
+ Error(ERR_WARN, "cannot read level '%s' - creating new level", filename);
+
return;
}
return;
}
- if ((level.file_version = getFileVersionFromCookieString(cookie)) == -1)
+ if ((level->file_version = getFileVersionFromCookieString(cookie)) == -1)
{
Error(ERR_WARN, "unsupported version of level file '%s'", filename);
fclose(file);
}
/* pre-2.0 level files have no game version, so use file version here */
- level.game_version = level.file_version;
+ level->game_version = level->file_version;
}
- if (level.file_version < FILE_VERSION_1_2)
+ if (level->file_version < FILE_VERSION_1_2)
{
/* level files from versions before 1.2.0 without chunk structure */
- LoadLevel_HEAD(file, LEVEL_HEADER_SIZE, &level);
- LoadLevel_BODY(file, level.fieldx * level.fieldy, &level);
+ LoadLevel_HEAD(file, LEVEL_HEADER_SIZE, level);
+ LoadLevel_BODY(file, level->fieldx * level->fieldy, level);
}
else
{
{ "VERS", FILE_VERS_CHUNK_SIZE, LoadLevel_VERS },
{ "HEAD", LEVEL_HEADER_SIZE, LoadLevel_HEAD },
{ "AUTH", MAX_LEVEL_AUTHOR_LEN, LoadLevel_AUTH },
- { "CONT", -1, LoadLevel_CONT },
{ "BODY", -1, LoadLevel_BODY },
+ { "CONT", -1, LoadLevel_CONT },
{ "CNT2", LEVEL_CHUNK_CNT2_SIZE, LoadLevel_CNT2 },
+ { "CUS1", -1, LoadLevel_CUS1 },
+ { "CUS2", -1, LoadLevel_CUS2 },
+ { "CUS3", -1, LoadLevel_CUS3 },
{ NULL, 0, NULL }
};
{
/* call function to load this level chunk */
int chunk_size_expected =
- (chunk_info[i].loader)(file, chunk_size, &level);
+ (chunk_info[i].loader)(file, chunk_size, level);
/* the size of some chunks cannot be checked before reading other
chunks first (like "HEAD" and "BODY") that contain some header
}
fclose(file);
+}
+
+static void LoadLevel_InitLevel(struct LevelInfo *level, char *filename)
+{
+ int x, y;
+
+ if (leveldir_current == NULL) /* only when dumping level */
+ return;
if (IS_LEVELCLASS_CONTRIBUTION(leveldir_current) ||
IS_LEVELCLASS_USER(leveldir_current))
{
+#if 0
+ printf("::: This level is private or contributed: '%s'\n", filename);
+#endif
+
/* For user contributed and private levels, use the version of
the game engine the levels were created for.
Since 2.0.1, the game engine version is now directly stored
file format version used to store the level -- see above). */
/* do some special adjustments to support older level versions */
- if (level.file_version == FILE_VERSION_1_0)
+ if (level->file_version == FILE_VERSION_1_0)
{
- Error(ERR_WARN, "level file '%s' has version number 1.0", filename);
+ Error(ERR_WARN, "level file '%s'has version number 1.0", filename);
Error(ERR_WARN, "using high speed movement for player");
/* player was faster than monsters in (pre-)1.0 levels */
- level.double_speed = TRUE;
+ level->double_speed = TRUE;
}
/* Default behaviour for EM style gems was "slippery" only in 2.0.1 */
- if (level.game_version == VERSION_IDENT(2,0,1))
- level.em_slippery_gems = TRUE;
+ if (level->game_version == VERSION_IDENT(2,0,1))
+ level->em_slippery_gems = TRUE;
}
else
{
+#if 0
+ printf("::: ALWAYS USE LATEST ENGINE FOR THIS LEVEL: [%d] '%s'\n",
+ leveldir_current->sort_priority, filename);
+#endif
+
/* Always use the latest version of the game engine for all but
user contributed and private levels; this allows for actual
corrections in the game engine to take effect for existing,
make the game emulation more accurate, while (hopefully) not
breaking existing levels created from other players. */
- level.game_version = GAME_VERSION_ACTUAL;
+ level->game_version = GAME_VERSION_ACTUAL;
/* Set special EM style gems behaviour: EM style gems slip down from
normal, steel and growing wall. As this is a more fundamental change,
of gem style elements). Already existing converted levels (neither
private nor contributed levels) are changed to the new behaviour. */
- if (level.file_version < FILE_VERSION_2_0)
- level.em_slippery_gems = TRUE;
+ if (level->file_version < FILE_VERSION_2_0)
+ level->em_slippery_gems = TRUE;
+ }
+
+ /* map elements which have changed in newer versions */
+ for(y=0; y<level->fieldy; y++)
+ {
+ for(x=0; x<level->fieldx; x++)
+ {
+ int element = level->field[x][y];
+
+ if (level->game_version <= VERSION_IDENT(2,2,0))
+ {
+ /* map game font elements */
+ element = (element == EL_CHAR('[') ? EL_CHAR_AUMLAUT :
+ element == EL_CHAR('\\') ? EL_CHAR_OUMLAUT :
+ element == EL_CHAR(']') ? EL_CHAR_UUMLAUT :
+ element == EL_CHAR('^') ? EL_CHAR_COPYRIGHT : element);
+ }
+
+ if (level->game_version < VERSION_IDENT(3,0,0))
+ {
+ /* map Supaplex gravity tube elements */
+ element = (element == EL_SP_GRAVITY_PORT_LEFT ? EL_SP_PORT_LEFT :
+ element == EL_SP_GRAVITY_PORT_RIGHT ? EL_SP_PORT_RIGHT :
+ element == EL_SP_GRAVITY_PORT_UP ? EL_SP_PORT_UP :
+ element == EL_SP_GRAVITY_PORT_DOWN ? EL_SP_PORT_DOWN :
+ element);
+ }
+
+ level->field[x][y] = element;
+ }
}
+ /* copy elements to runtime playfield array */
+ for(x=0; x<MAX_LEV_FIELDX; x++)
+ for(y=0; y<MAX_LEV_FIELDY; y++)
+ Feld[x][y] = level->field[x][y];
+
+ /* initialize level size variables for faster access */
+ lev_fieldx = level->fieldx;
+ lev_fieldy = level->fieldy;
+
/* determine border element for this level */
SetBorderElement();
+
+ /* initialize element properties for level editor etc. */
+ InitElementPropertiesEngine(level->game_version);
+}
+
+void LoadLevelTemplate(int level_nr)
+{
+ char *filename = getLevelFilename(level_nr);
+
+ LoadLevelFromFilename(&level_template, filename);
+
+ ActivateLevelTemplate();
+}
+
+void LoadLevel(int level_nr)
+{
+ char *filename = getLevelFilename(level_nr);
+
+ LoadLevelFromFilename(&level, filename);
+
+ if (level.use_custom_template)
+ LoadLevelTemplate(-1);
+
+ LoadLevel_InitLevel(&level, filename);
}
static void SaveLevel_VERS(FILE *file, struct LevelInfo *level)
{
int i, x, y;
- fputc(level->fieldx, file);
- fputc(level->fieldy, file);
+ putFile8Bit(file, level->fieldx);
+ putFile8Bit(file, level->fieldy);
putFile16BitBE(file, level->time);
putFile16BitBE(file, level->gems_needed);
for(i=0; i<MAX_LEVEL_NAME_LEN; i++)
- fputc(level->name[i], file);
+ putFile8Bit(file, level->name[i]);
for(i=0; i<LEVEL_SCORE_ELEMENTS; i++)
- fputc(level->score[i], file);
+ putFile8Bit(file, level->score[i]);
for(i=0; i<STD_ELEMENT_CONTENTS; i++)
for(y=0; y<3; y++)
for(x=0; x<3; x++)
- fputc((level->encoding_16bit_yamyam ? EL_LEERRAUM :
- level->yam_content[i][x][y]),
- file);
- fputc(level->amoeba_speed, file);
- fputc(level->time_magic_wall, file);
- fputc(level->time_wheel, file);
- fputc((level->encoding_16bit_amoeba ? EL_LEERRAUM : level->amoeba_content),
- file);
- fputc((level->double_speed ? 1 : 0), file);
- fputc((level->gravity ? 1 : 0), file);
- fputc((level->encoding_16bit_field ? 1 : 0), file);
- fputc((level->em_slippery_gems ? 1 : 0), file);
+ putFile8Bit(file, (level->encoding_16bit_yamyam ? EL_EMPTY :
+ level->yamyam_content[i][x][y]));
+ putFile8Bit(file, level->amoeba_speed);
+ putFile8Bit(file, level->time_magic_wall);
+ putFile8Bit(file, level->time_wheel);
+ putFile8Bit(file, (level->encoding_16bit_amoeba ? EL_EMPTY :
+ level->amoeba_content));
+ putFile8Bit(file, (level->double_speed ? 1 : 0));
+ putFile8Bit(file, (level->gravity ? 1 : 0));
+ putFile8Bit(file, (level->encoding_16bit_field ? 1 : 0));
+ putFile8Bit(file, (level->em_slippery_gems ? 1 : 0));
+
+ putFile8Bit(file, (level->use_custom_template ? 1 : 0));
WriteUnusedBytesToFile(file, LEVEL_HEADER_UNUSED);
}
int i;
for(i=0; i<MAX_LEVEL_AUTHOR_LEN; i++)
- fputc(level->author[i], file);
+ putFile8Bit(file, level->author[i]);
+}
+
+static void SaveLevel_BODY(FILE *file, struct LevelInfo *level)
+{
+ int x, y;
+
+ for(y=0; y<level->fieldy; y++)
+ for(x=0; x<level->fieldx; x++)
+ if (level->encoding_16bit_field)
+ putFile16BitBE(file, level->field[x][y]);
+ else
+ putFile8Bit(file, level->field[x][y]);
}
#if 0
{
int i, x, y;
- fputc(EL_MAMPFER, file);
- fputc(level->num_yam_contents, file);
- fputc(0, file);
- fputc(0, file);
+ putFile8Bit(file, EL_YAMYAM);
+ putFile8Bit(file, level->num_yamyam_contents);
+ putFile8Bit(file, 0);
+ putFile8Bit(file, 0);
for(i=0; i<MAX_ELEMENT_CONTENTS; i++)
for(y=0; y<3; y++)
for(x=0; x<3; x++)
if (level->encoding_16bit_field)
- putFile16BitBE(file, level->yam_content[i][x][y]);
+ putFile16BitBE(file, level->yamyam_content[i][x][y]);
else
- fputc(level->yam_content[i][x][y], file);
+ putFile8Bit(file, level->yamyam_content[i][x][y]);
}
#endif
-static void SaveLevel_BODY(FILE *file, struct LevelInfo *level)
-{
- int x, y;
-
- for(y=0; y<level->fieldy; y++)
- for(x=0; x<level->fieldx; x++)
- if (level->encoding_16bit_field)
- putFile16BitBE(file, Ur[x][y]);
- else
- fputc(Ur[x][y], file);
-}
-
static void SaveLevel_CNT2(FILE *file, struct LevelInfo *level, int element)
{
int i, x, y;
int num_contents, content_xsize, content_ysize;
int content_array[MAX_ELEMENT_CONTENTS][3][3];
- if (element == EL_MAMPFER)
+ if (element == EL_YAMYAM)
{
- num_contents = level->num_yam_contents;
+ num_contents = level->num_yamyam_contents;
content_xsize = 3;
content_ysize = 3;
for(i=0; i<MAX_ELEMENT_CONTENTS; i++)
for(y=0; y<3; y++)
for(x=0; x<3; x++)
- content_array[i][x][y] = level->yam_content[i][x][y];
+ content_array[i][x][y] = level->yamyam_content[i][x][y];
}
- else if (element == EL_AMOEBE_BD)
+ else if (element == EL_BD_AMOEBA)
{
num_contents = 1;
content_xsize = 1;
for(i=0; i<MAX_ELEMENT_CONTENTS; i++)
for(y=0; y<3; y++)
for(x=0; x<3; x++)
- content_array[i][x][y] = EL_LEERRAUM;
+ content_array[i][x][y] = EL_EMPTY;
content_array[0][0][0] = level->amoeba_content;
}
else
}
putFile16BitBE(file, element);
- fputc(num_contents, file);
- fputc(content_xsize, file);
- fputc(content_ysize, file);
+ putFile8Bit(file, num_contents);
+ putFile8Bit(file, content_xsize);
+ putFile8Bit(file, content_ysize);
WriteUnusedBytesToFile(file, LEVEL_CHUNK_CNT2_UNUSED);
putFile16BitBE(file, content_array[i][x][y]);
}
-void SaveLevel(int level_nr)
+#if 0
+static void SaveLevel_CUS1(FILE *file, struct LevelInfo *level,
+ int num_changed_custom_elements)
+{
+ int i, check = 0;
+
+ putFile16BitBE(file, num_changed_custom_elements);
+
+ for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+ {
+ int element = EL_CUSTOM_START + i;
+
+ if (Properties[element][EP_BITFIELD_BASE] != EP_BITMASK_DEFAULT)
+ {
+ if (check < num_changed_custom_elements)
+ {
+ putFile16BitBE(file, element);
+ putFile32BitBE(file, Properties[element][EP_BITFIELD_BASE]);
+ }
+
+ check++;
+ }
+ }
+
+ if (check != num_changed_custom_elements) /* should not happen */
+ Error(ERR_WARN, "inconsistent number of custom element properties");
+}
+#endif
+
+#if 0
+static void SaveLevel_CUS2(FILE *file, struct LevelInfo *level,
+ int num_changed_custom_elements)
+{
+ int i, check = 0;
+
+ putFile16BitBE(file, num_changed_custom_elements);
+
+ for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+ {
+ int element = EL_CUSTOM_START + i;
+
+ if (element_info[element].change.target_element != EL_EMPTY_SPACE)
+ {
+ if (check < num_changed_custom_elements)
+ {
+ putFile16BitBE(file, element);
+ putFile16BitBE(file, element_info[element].change.target_element);
+ }
+
+ check++;
+ }
+ }
+
+ if (check != num_changed_custom_elements) /* should not happen */
+ Error(ERR_WARN, "inconsistent number of custom target elements");
+}
+#endif
+
+static void SaveLevel_CUS3(FILE *file, struct LevelInfo *level,
+ int num_changed_custom_elements)
+{
+ int i, j, x, y, check = 0;
+
+ putFile16BitBE(file, num_changed_custom_elements);
+
+ for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+ {
+ int element = EL_CUSTOM_START + i;
+
+ if (Properties[element][EP_BITFIELD_BASE] != EP_BITMASK_DEFAULT)
+ {
+ if (check < num_changed_custom_elements)
+ {
+ putFile16BitBE(file, element);
+
+ for(j=0; j<MAX_ELEMENT_NAME_LEN; j++)
+ putFile8Bit(file, element_info[element].description[j]);
+
+ putFile32BitBE(file, Properties[element][EP_BITFIELD_BASE]);
+
+ /* some free bytes for future properties and padding */
+ WriteUnusedBytesToFile(file, 7);
+
+ putFile8Bit(file, element_info[element].use_gfx_element);
+ putFile16BitBE(file, element_info[element].gfx_element);
+
+ putFile8Bit(file, element_info[element].score);
+ putFile8Bit(file, element_info[element].gem_count);
+
+ putFile16BitBE(file, element_info[element].push_delay_fixed);
+ putFile16BitBE(file, element_info[element].push_delay_random);
+ putFile16BitBE(file, element_info[element].move_delay_fixed);
+ putFile16BitBE(file, element_info[element].move_delay_random);
+
+ putFile16BitBE(file, element_info[element].move_pattern);
+ putFile8Bit(file, element_info[element].move_direction_initial);
+ putFile8Bit(file, element_info[element].move_stepsize);
+
+ for(y=0; y<3; y++)
+ for(x=0; x<3; x++)
+ putFile16BitBE(file, element_info[element].content[x][y]);
+
+ putFile32BitBE(file, element_info[element].change.events);
+
+ putFile16BitBE(file, element_info[element].change.target_element);
+
+ putFile16BitBE(file, element_info[element].change.delay_fixed);
+ putFile16BitBE(file, element_info[element].change.delay_random);
+ putFile16BitBE(file, element_info[element].change.delay_frames);
+
+ putFile16BitBE(file, element_info[element].change.trigger_element);
+
+ putFile8Bit(file, element_info[element].change.explode);
+ putFile8Bit(file, element_info[element].change.use_content);
+ putFile8Bit(file, element_info[element].change.only_complete);
+ putFile8Bit(file, element_info[element].change.use_random_change);
+
+ putFile8Bit(file, element_info[element].change.random);
+ putFile8Bit(file, element_info[element].change.power);
+
+ for(y=0; y<3; y++)
+ for(x=0; x<3; x++)
+ putFile16BitBE(file, element_info[element].change.content[x][y]);
+
+ putFile8Bit(file, element_info[element].slippery_type);
+
+ /* some free bytes for future properties and padding */
+ WriteUnusedBytesToFile(file, LEVEL_CPART_CUS3_UNUSED);
+ }
+
+ check++;
+ }
+ }
+
+ if (check != num_changed_custom_elements) /* should not happen */
+ Error(ERR_WARN, "inconsistent number of custom element properties");
+}
+
+static void SaveLevelFromFilename(struct LevelInfo *level, char *filename)
{
- int i, x, y;
- char *filename = getLevelFilename(level_nr);
int body_chunk_size;
+ int num_changed_custom_elements = 0;
+ int level_chunk_CUS3_size;
+ int i, x, y;
FILE *file;
if (!(file = fopen(filename, MODE_WRITE)))
return;
}
- level.file_version = FILE_VERSION_ACTUAL;
- level.game_version = GAME_VERSION_ACTUAL;
+ level->file_version = FILE_VERSION_ACTUAL;
+ level->game_version = GAME_VERSION_ACTUAL;
/* check level field for 16-bit elements */
- level.encoding_16bit_field = FALSE;
- for(y=0; y<level.fieldy; y++)
- for(x=0; x<level.fieldx; x++)
- if (Ur[x][y] > 255)
- level.encoding_16bit_field = TRUE;
+ level->encoding_16bit_field = FALSE;
+ for(y=0; y<level->fieldy; y++)
+ for(x=0; x<level->fieldx; x++)
+ if (level->field[x][y] > 255)
+ level->encoding_16bit_field = TRUE;
/* check yamyam content for 16-bit elements */
- level.encoding_16bit_yamyam = FALSE;
- for(i=0; i<level.num_yam_contents; i++)
+ level->encoding_16bit_yamyam = FALSE;
+ for(i=0; i<level->num_yamyam_contents; i++)
for(y=0; y<3; y++)
for(x=0; x<3; x++)
- if (level.yam_content[i][x][y] > 255)
- level.encoding_16bit_yamyam = TRUE;
+ if (level->yamyam_content[i][x][y] > 255)
+ level->encoding_16bit_yamyam = TRUE;
/* check amoeba content for 16-bit elements */
- level.encoding_16bit_amoeba = FALSE;
- if (level.amoeba_content > 255)
- level.encoding_16bit_amoeba = TRUE;
+ level->encoding_16bit_amoeba = FALSE;
+ if (level->amoeba_content > 255)
+ level->encoding_16bit_amoeba = TRUE;
+ /* calculate size of "BODY" chunk */
body_chunk_size =
- level.fieldx * level.fieldy * (level.encoding_16bit_field ? 2 : 1);
+ level->fieldx * level->fieldy * (level->encoding_16bit_field ? 2 : 1);
+
+ /* check for non-standard custom elements and calculate "CUS3" chunk size */
+ for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+ if (Properties[EL_CUSTOM_START +i][EP_BITFIELD_BASE] != EP_BITMASK_DEFAULT)
+ num_changed_custom_elements++;
+ level_chunk_CUS3_size = LEVEL_CHUNK_CUS3_SIZE(num_changed_custom_elements);
putFileChunkBE(file, "RND1", CHUNK_SIZE_UNDEFINED);
putFileChunkBE(file, "CAVE", CHUNK_SIZE_NONE);
putFileChunkBE(file, "VERS", FILE_VERS_CHUNK_SIZE);
- SaveLevel_VERS(file, &level);
+ SaveLevel_VERS(file, level);
putFileChunkBE(file, "HEAD", LEVEL_HEADER_SIZE);
- SaveLevel_HEAD(file, &level);
+ SaveLevel_HEAD(file, level);
putFileChunkBE(file, "AUTH", MAX_LEVEL_AUTHOR_LEN);
- SaveLevel_AUTH(file, &level);
+ SaveLevel_AUTH(file, level);
putFileChunkBE(file, "BODY", body_chunk_size);
- SaveLevel_BODY(file, &level);
+ SaveLevel_BODY(file, level);
- if (level.encoding_16bit_yamyam ||
- level.num_yam_contents != STD_ELEMENT_CONTENTS)
+ if (level->encoding_16bit_yamyam ||
+ level->num_yamyam_contents != STD_ELEMENT_CONTENTS)
{
putFileChunkBE(file, "CNT2", LEVEL_CHUNK_CNT2_SIZE);
- SaveLevel_CNT2(file, &level, EL_MAMPFER);
+ SaveLevel_CNT2(file, level, EL_YAMYAM);
}
- if (level.encoding_16bit_amoeba)
+ if (level->encoding_16bit_amoeba)
{
putFileChunkBE(file, "CNT2", LEVEL_CHUNK_CNT2_SIZE);
- SaveLevel_CNT2(file, &level, EL_AMOEBE_BD);
+ SaveLevel_CNT2(file, level, EL_BD_AMOEBA);
+ }
+
+ if (num_changed_custom_elements > 0 && !level->use_custom_template)
+ {
+ putFileChunkBE(file, "CUS3", level_chunk_CUS3_size);
+ SaveLevel_CUS3(file, level, num_changed_custom_elements);
}
fclose(file);
SetFilePermissions(filename, PERMS_PRIVATE);
}
+void SaveLevel(int level_nr)
+{
+ char *filename = getLevelFilename(level_nr);
+
+ SaveLevelFromFilename(&level, filename);
+}
+
+void SaveLevelTemplate()
+{
+ char *filename = getLevelFilename(-1);
+
+ SaveLevelFromFilename(&level, filename);
+}
+
+void DumpLevel(struct LevelInfo *level)
+{
+ printf_line("-", 79);
+ printf("Level xxx (file version %08d, game version %08d)\n",
+ level->file_version, level->game_version);
+ printf_line("-", 79);
+
+ printf("Level Author: '%s'\n", level->author);
+ printf("Level Title: '%s'\n", level->name);
+ printf("\n");
+ printf("Playfield Size: %d x %d\n", level->fieldx, level->fieldy);
+ printf("\n");
+ printf("Level Time: %d seconds\n", level->time);
+ printf("Gems needed: %d\n", level->gems_needed);
+ printf("\n");
+ printf("Time for Magic Wall: %d seconds\n", level->time_magic_wall);
+ printf("Time for Wheel: %d seconds\n", level->time_wheel);
+ printf("Time for Light: %d seconds\n", level->time_light);
+ printf("Time for Timegate: %d seconds\n", level->time_timegate);
+ printf("\n");
+ printf("Amoeba Speed: %d\n", level->amoeba_speed);
+ printf("\n");
+ printf("Gravity: %s\n", (level->gravity ? "yes" : "no"));
+ printf("Double Speed Movement: %s\n", (level->double_speed ? "yes" : "no"));
+ printf("EM style slippery gems: %s\n", (level->em_slippery_gems ? "yes" : "no"));
+
+ printf_line("-", 79);
+}
+
/* ========================================================================= */
/* tape file functions */
/* read header fields that are new since version 1.2 */
if (tape->file_version >= FILE_VERSION_1_2)
{
- byte store_participating_players = fgetc(file);
+ byte store_participating_players = getFile8Bit(file);
int engine_version;
/* since version 1.2, tapes store which players participate in the tape */
return chunk_size;
}
+static int LoadTape_INFO(FILE *file, int chunk_size, struct TapeInfo *tape)
+{
+ int level_identifier_size;
+ int i;
+
+ level_identifier_size = getFile16BitBE(file);
+
+ tape->level_identifier =
+ checked_realloc(tape->level_identifier, level_identifier_size);
+
+ for(i=0; i < level_identifier_size; i++)
+ tape->level_identifier[i] = getFile8Bit(file);
+
+ tape->level_nr = getFile16BitBE(file);
+
+ chunk_size = 2 + level_identifier_size + 2;
+
+ return chunk_size;
+}
+
static int LoadTape_BODY(FILE *file, int chunk_size, struct TapeInfo *tape)
{
int i, j;
tape->pos[i].action[j] = MV_NO_MOVING;
if (tape->player_participates[j])
- tape->pos[i].action[j] = fgetc(file);
+ tape->pos[i].action[j] = getFile8Bit(file);
}
- tape->pos[i].delay = fgetc(file);
+ tape->pos[i].delay = getFile8Bit(file);
if (tape->file_version == FILE_VERSION_1_0)
{
return chunk_size;
}
-void LoadTape(int level_nr)
+void LoadTapeFromFilename(char *filename)
{
- char *filename = getTapeFilename(level_nr);
char cookie[MAX_LINE_LEN];
char chunk_name[CHUNK_ID_LEN + 1];
FILE *file;
{
{ "VERS", FILE_VERS_CHUNK_SIZE, LoadTape_VERS },
{ "HEAD", TAPE_HEADER_SIZE, LoadTape_HEAD },
+ { "INFO", -1, LoadTape_INFO },
{ "BODY", -1, LoadTape_BODY },
{ NULL, 0, NULL }
};
fclose(file);
tape.length_seconds = GetTapeLength();
+
+#if 0
+ printf("tape version: %d\n", tape.game_version);
+#endif
+}
+
+void LoadTape(int level_nr)
+{
+ char *filename = getTapeFilename(level_nr);
+
+ LoadTapeFromFilename(filename);
}
static void SaveTape_VERS(FILE *file, struct TapeInfo *tape)
putFile32BitBE(file, tape->date);
putFile32BitBE(file, tape->length);
- fputc(store_participating_players, file);
+ putFile8Bit(file, store_participating_players);
/* unused bytes not at the end here for 4-byte alignment of engine_version */
WriteUnusedBytesToFile(file, TAPE_HEADER_UNUSED);
putFileVersion(file, tape->engine_version);
}
+static void SaveTape_INFO(FILE *file, struct TapeInfo *tape)
+{
+ int level_identifier_size = strlen(tape->level_identifier) + 1;
+ int i;
+
+ putFile16BitBE(file, level_identifier_size);
+
+ for(i=0; i < level_identifier_size; i++)
+ putFile8Bit(file, tape->level_identifier[i]);
+
+ putFile16BitBE(file, tape->level_nr);
+}
+
static void SaveTape_BODY(FILE *file, struct TapeInfo *tape)
{
int i, j;
{
for(j=0; j<MAX_PLAYERS; j++)
if (tape->player_participates[j])
- fputc(tape->pos[i].action[j], file);
+ putFile8Bit(file, tape->pos[i].action[j]);
- fputc(tape->pos[i].delay, file);
+ putFile8Bit(file, tape->pos[i].delay);
}
}
void SaveTape(int level_nr)
{
- int i;
char *filename = getTapeFilename(level_nr);
FILE *file;
boolean new_tape = TRUE;
int num_participating_players = 0;
+ int info_chunk_size;
int body_chunk_size;
+ int i;
InitTapeDirectory(leveldir_current->filename);
if (tape.player_participates[i])
num_participating_players++;
+ info_chunk_size = 2 + (strlen(tape.level_identifier) + 1) + 2;
body_chunk_size = (num_participating_players + 1) * tape.length;
putFileChunkBE(file, "RND1", CHUNK_SIZE_UNDEFINED);
putFileChunkBE(file, "HEAD", TAPE_HEADER_SIZE);
SaveTape_HEAD(file, &tape);
+ putFileChunkBE(file, "INFO", info_chunk_size);
+ SaveTape_INFO(file, &tape);
+
putFileChunkBE(file, "BODY", body_chunk_size);
SaveTape_BODY(file, &tape);
return;
}
- printf("\n");
- printf("-------------------------------------------------------------------------------\n");
- printf("Tape of Level %d (file version %06d, game version %06d)\n",
+ 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("-------------------------------------------------------------------------------\n");
+ printf("Level series identifier: '%s'\n", tape->level_identifier);
+ printf_line("-", 79);
for(i=0; i<tape->length; i++)
{
if (i >= MAX_TAPELEN)
break;
+ printf("%03d: ", i);
+
for(j=0; j<MAX_PLAYERS; j++)
{
if (tape->player_participates[j])
printf("(%03d)\n", tape->pos[i].delay);
}
- printf("-------------------------------------------------------------------------------\n");
+ printf_line("-", 79);
}
#define NUM_GLOBAL_SETUP_TOKENS 22
+/* 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 NUM_EDITOR_SETUP_TOKENS 9
+
/* shortcut setup */
-#define SETUP_TOKEN_SAVE_GAME 0
-#define SETUP_TOKEN_LOAD_GAME 1
-#define SETUP_TOKEN_TOGGLE_PAUSE 2
+#define SETUP_TOKEN_SHORTCUT_SAVE_GAME 0
+#define SETUP_TOKEN_SHORTCUT_LOAD_GAME 1
+#define SETUP_TOKEN_SHORTCUT_TOGGLE_PAUSE 2
#define NUM_SHORTCUT_SETUP_TOKENS 3
/* player setup */
-#define SETUP_TOKEN_USE_JOYSTICK 0
-#define SETUP_TOKEN_JOY_DEVICE_NAME 1
-#define SETUP_TOKEN_JOY_XLEFT 2
-#define SETUP_TOKEN_JOY_XMIDDLE 3
-#define SETUP_TOKEN_JOY_XRIGHT 4
-#define SETUP_TOKEN_JOY_YUPPER 5
-#define SETUP_TOKEN_JOY_YMIDDLE 6
-#define SETUP_TOKEN_JOY_YLOWER 7
-#define SETUP_TOKEN_JOY_SNAP 8
-#define SETUP_TOKEN_JOY_BOMB 9
-#define SETUP_TOKEN_KEY_LEFT 10
-#define SETUP_TOKEN_KEY_RIGHT 11
-#define SETUP_TOKEN_KEY_UP 12
-#define SETUP_TOKEN_KEY_DOWN 13
-#define SETUP_TOKEN_KEY_SNAP 14
-#define SETUP_TOKEN_KEY_BOMB 15
+#define SETUP_TOKEN_PLAYER_USE_JOYSTICK 0
+#define SETUP_TOKEN_PLAYER_JOY_DEVICE_NAME 1
+#define SETUP_TOKEN_PLAYER_JOY_XLEFT 2
+#define SETUP_TOKEN_PLAYER_JOY_XMIDDLE 3
+#define SETUP_TOKEN_PLAYER_JOY_XRIGHT 4
+#define SETUP_TOKEN_PLAYER_JOY_YUPPER 5
+#define SETUP_TOKEN_PLAYER_JOY_YMIDDLE 6
+#define SETUP_TOKEN_PLAYER_JOY_YLOWER 7
+#define SETUP_TOKEN_PLAYER_JOY_SNAP 8
+#define SETUP_TOKEN_PLAYER_JOY_BOMB 9
+#define SETUP_TOKEN_PLAYER_KEY_LEFT 10
+#define SETUP_TOKEN_PLAYER_KEY_RIGHT 11
+#define SETUP_TOKEN_PLAYER_KEY_UP 12
+#define SETUP_TOKEN_PLAYER_KEY_DOWN 13
+#define SETUP_TOKEN_PLAYER_KEY_SNAP 14
+#define SETUP_TOKEN_PLAYER_KEY_BOMB 15
#define NUM_PLAYER_SETUP_TOKENS 16
+/* system setup */
+#define SETUP_TOKEN_SYSTEM_SDL_AUDIODRIVER 0
+#define SETUP_TOKEN_SYSTEM_AUDIO_FRAGMENT_SIZE 1
+
+#define NUM_SYSTEM_SETUP_TOKENS 2
+
+/* options setup */
+#define SETUP_TOKEN_OPTIONS_VERBOSE 0
+
+#define NUM_OPTIONS_SETUP_TOKENS 1
+
+
static struct SetupInfo si;
+static struct SetupEditorInfo sei;
static struct SetupShortcutInfo ssi;
static struct SetupInputInfo sii;
+static struct SetupSystemInfo syi;
+static struct OptionInfo soi;
static struct TokenInfo global_setup_tokens[] =
{
- /* global setup */
{ TYPE_STRING, &si.player_name, "player_name" },
{ TYPE_SWITCH, &si.sound, "sound" },
{ TYPE_SWITCH, &si.sound_loops, "repeating_sound_loops" },
{ TYPE_SWITCH, &si.override_level_music, "override_level_music" },
};
+static struct TokenInfo editor_setup_tokens[] =
+{
+ { TYPE_SWITCH, &sei.el_boulderdash, "editor.el_boulderdash" },
+ { TYPE_SWITCH, &sei.el_emerald_mine, "editor.el_emerald_mine" },
+ { TYPE_SWITCH, &sei.el_more, "editor.el_more" },
+ { TYPE_SWITCH, &sei.el_sokoban, "editor.el_sokoban" },
+ { TYPE_SWITCH, &sei.el_supaplex, "editor.el_supaplex" },
+ { TYPE_SWITCH, &sei.el_diamond_caves, "editor.el_diamond_caves" },
+ { TYPE_SWITCH, &sei.el_dx_boulderdash,"editor.el_dx_boulderdash" },
+ { TYPE_SWITCH, &sei.el_chars, "editor.el_chars" },
+ { TYPE_SWITCH, &sei.el_custom, "editor.el_custom" },
+};
+
static struct TokenInfo shortcut_setup_tokens[] =
{
- /* shortcut setup */
{ TYPE_KEY_X11, &ssi.save_game, "shortcut.save_game" },
{ TYPE_KEY_X11, &ssi.load_game, "shortcut.load_game" },
{ TYPE_KEY_X11, &ssi.toggle_pause, "shortcut.toggle_pause" }
static struct TokenInfo player_setup_tokens[] =
{
- /* player setup */
{ TYPE_BOOLEAN, &sii.use_joystick, ".use_joystick" },
{ TYPE_STRING, &sii.joy.device_name, ".joy.device_name" },
{ TYPE_INTEGER, &sii.joy.xleft, ".joy.xleft" },
{ TYPE_KEY_X11, &sii.key.bomb, ".key.place_bomb" }
};
+static struct TokenInfo system_setup_tokens[] =
+{
+ { TYPE_STRING, &syi.sdl_audiodriver, "system.sdl_audiodriver" },
+ { TYPE_INTEGER, &syi.audio_fragment_size,"system.audio_fragment_size" }
+};
+
+static struct TokenInfo options_setup_tokens[] =
+{
+ { TYPE_BOOLEAN, &soi.verbose, "options.verbose" }
+};
+
+static char *get_corrected_login_name(char *login_name)
+{
+ /* needed because player name must be a fixed length string */
+ char *login_name_new = checked_malloc(MAX_PLAYER_NAME_LEN + 1);
+
+ strncpy(login_name_new, login_name, MAX_PLAYER_NAME_LEN);
+ login_name_new[MAX_PLAYER_NAME_LEN] = '\0';
+
+ if (strlen(login_name) > MAX_PLAYER_NAME_LEN) /* name has been cut */
+ if (strchr(login_name_new, ' '))
+ *strchr(login_name_new, ' ') = '\0';
+
+ return login_name_new;
+}
+
static void setSetupInfoToDefaults(struct SetupInfo *si)
{
int i;
- si->player_name = getStringCopy(getLoginName());
+ si->player_name = get_corrected_login_name(getLoginName());
si->sound = TRUE;
si->sound_loops = 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->shortcut.save_game = DEFAULT_KEY_SAVE_GAME;
si->shortcut.load_game = DEFAULT_KEY_LOAD_GAME;
si->shortcut.toggle_pause = DEFAULT_KEY_TOGGLE_PAUSE;
si->input[i].key.snap = (i == 0 ? DEFAULT_KEY_SNAP : KSYM_UNDEFINED);
si->input[i].key.bomb = (i == 0 ? DEFAULT_KEY_BOMB : KSYM_UNDEFINED);
}
+
+ si->system.sdl_audiodriver = getStringCopy(ARG_DEFAULT);
+ si->system.audio_fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
+
+ si->options.verbose = FALSE;
}
-static void decodeSetupFileList(struct SetupFileList *setup_file_list)
+static void decodeSetupFileHash(SetupFileHash *setup_file_hash)
{
int i, pnr;
- if (!setup_file_list)
+ if (!setup_file_hash)
return;
/* global setup */
si = setup;
for (i=0; i<NUM_GLOBAL_SETUP_TOKENS; i++)
setSetupInfo(global_setup_tokens, i,
- getTokenValue(setup_file_list, global_setup_tokens[i].text));
+ getHashEntry(setup_file_hash, global_setup_tokens[i].text));
setup = si;
+ /* editor setup */
+ sei = setup.editor;
+ for (i=0; i<NUM_EDITOR_SETUP_TOKENS; i++)
+ setSetupInfo(editor_setup_tokens, i,
+ getHashEntry(setup_file_hash,editor_setup_tokens[i].text));
+ setup.editor = sei;
+
/* shortcut setup */
ssi = setup.shortcut;
for (i=0; i<NUM_SHORTCUT_SETUP_TOKENS; i++)
setSetupInfo(shortcut_setup_tokens, i,
- getTokenValue(setup_file_list,shortcut_setup_tokens[i].text));
+ getHashEntry(setup_file_hash,shortcut_setup_tokens[i].text));
setup.shortcut = ssi;
/* player setup */
sprintf(full_token, "%s%s", prefix, player_setup_tokens[i].text);
setSetupInfo(player_setup_tokens, i,
- getTokenValue(setup_file_list, full_token));
+ getHashEntry(setup_file_hash, full_token));
}
setup.input[pnr] = sii;
}
+
+ /* system setup */
+ syi = setup.system;
+ for (i=0; i<NUM_SYSTEM_SETUP_TOKENS; i++)
+ setSetupInfo(system_setup_tokens, i,
+ getHashEntry(setup_file_hash, system_setup_tokens[i].text));
+ setup.system = syi;
+
+ /* options setup */
+ soi = setup.options;
+ for (i=0; i<NUM_OPTIONS_SETUP_TOKENS; i++)
+ setSetupInfo(options_setup_tokens, i,
+ getHashEntry(setup_file_hash, options_setup_tokens[i].text));
+ setup.options = soi;
}
void LoadSetup()
{
char *filename = getSetupFilename();
- struct SetupFileList *setup_file_list = NULL;
+ SetupFileHash *setup_file_hash = NULL;
/* always start with reliable default values */
setSetupInfoToDefaults(&setup);
- setup_file_list = loadSetupFileList(filename);
+ setup_file_hash = loadSetupFileHash(filename);
- if (setup_file_list)
+ if (setup_file_hash)
{
- checkSetupFileListIdentifier(setup_file_list, getCookie("SETUP"));
- decodeSetupFileList(setup_file_list);
+ char *player_name_new;
+
+ checkSetupFileHashIdentifier(setup_file_hash, getCookie("SETUP"));
+ decodeSetupFileHash(setup_file_hash);
setup.direct_draw = !setup.double_buffering;
- freeSetupFileList(setup_file_list);
+ freeSetupFileHash(setup_file_hash);
/* needed to work around problems with fixed length strings */
- if (strlen(setup.player_name) > MAX_PLAYER_NAME_LEN)
- setup.player_name[MAX_PLAYER_NAME_LEN] = '\0';
- else if (strlen(setup.player_name) < MAX_PLAYER_NAME_LEN)
- {
- char *new_name = checked_malloc(MAX_PLAYER_NAME_LEN + 1);
-
- strcpy(new_name, setup.player_name);
- free(setup.player_name);
- setup.player_name = new_name;
- }
+ player_name_new = get_corrected_login_name(setup.player_name);
+ free(setup.player_name);
+ setup.player_name = player_name_new;
}
else
Error(ERR_WARN, "using default setup values");
si = setup;
for (i=0; i<NUM_GLOBAL_SETUP_TOKENS; i++)
{
- fprintf(file, "%s\n", getSetupLine(global_setup_tokens, "", i));
-
/* just to make things nicer :) */
- if (i == SETUP_TOKEN_PLAYER_NAME || i == SETUP_TOKEN_GRAPHICS_SET - 1)
+ if (i == SETUP_TOKEN_PLAYER_NAME + 1 ||
+ i == SETUP_TOKEN_GRAPHICS_SET)
fprintf(file, "\n");
+
+ fprintf(file, "%s\n", getSetupLine(global_setup_tokens, "", i));
}
+ /* editor setup */
+ sei = setup.editor;
+ fprintf(file, "\n");
+ for (i=0; i<NUM_EDITOR_SETUP_TOKENS; i++)
+ fprintf(file, "%s\n", getSetupLine(editor_setup_tokens, "", i));
+
/* shortcut setup */
ssi = setup.shortcut;
fprintf(file, "\n");
fprintf(file, "%s\n", getSetupLine(player_setup_tokens, prefix, i));
}
+ /* system setup */
+ syi = setup.system;
+ fprintf(file, "\n");
+ for (i=0; i<NUM_SYSTEM_SETUP_TOKENS; i++)
+ fprintf(file, "%s\n", getSetupLine(system_setup_tokens, "", i));
+
+ /* options setup */
+ soi = setup.options;
+ fprintf(file, "\n");
+ for (i=0; i<NUM_OPTIONS_SETUP_TOKENS; i++)
+ fprintf(file, "%s\n", getSetupLine(options_setup_tokens, "", i));
+
fclose(file);
SetFilePermissions(filename, PERMS_PRIVATE);
}
+
+void LoadCustomElementDescriptions()
+{
+ char *filename = getCustomArtworkConfigFilename(ARTWORK_TYPE_GRAPHICS);
+ SetupFileHash *setup_file_hash;
+ int i;
+
+ for (i=0; i<NUM_FILE_ELEMENTS; i++)
+ {
+ if (element_info[i].custom_description != NULL)
+ {
+ free(element_info[i].custom_description);
+ element_info[i].custom_description = NULL;
+ }
+ }
+
+ if ((setup_file_hash = loadSetupFileHash(filename)) == NULL)
+ return;
+
+ for (i=0; i<NUM_FILE_ELEMENTS; i++)
+ {
+ char *token = getStringCat2(element_info[i].token_name, ".name");
+ char *value = getHashEntry(setup_file_hash, token);
+
+ if (value != NULL)
+ element_info[i].custom_description = getStringCopy(value);
+
+ free(token);
+ }
+
+ freeSetupFileHash(setup_file_hash);
+}
+
+void LoadSpecialMenuDesignSettings()
+{
+ char *filename = getCustomArtworkConfigFilename(ARTWORK_TYPE_GRAPHICS);
+ SetupFileHash *setup_file_hash;
+ int i, j;
+
+ /* always start with reliable default values from default config */
+ for (i=0; image_config_vars[i].token != NULL; i++)
+ for (j=0; image_config[j].token != NULL; j++)
+ if (strcmp(image_config_vars[i].token, image_config[j].token) == 0)
+ *image_config_vars[i].value =
+ get_integer_from_string(image_config[j].value);
+
+ if ((setup_file_hash = loadSetupFileHash(filename)) == NULL)
+ return;
+
+ /* special case: initialize with default values that may be overwritten */
+ for (i=0; i < NUM_SPECIAL_GFX_ARGS; i++)
+ {
+ char *value_x = getHashEntry(setup_file_hash, "menu.draw_xoffset");
+ char *value_y = getHashEntry(setup_file_hash, "menu.draw_yoffset");
+ char *list_size = getHashEntry(setup_file_hash, "menu.list_size");
+
+ if (value_x != NULL)
+ menu.draw_xoffset[i] = get_integer_from_string(value_x);
+ if (value_y != NULL)
+ menu.draw_yoffset[i] = get_integer_from_string(value_y);
+ if (list_size != NULL)
+ menu.list_size[i] = get_integer_from_string(list_size);
+ }
+
+ /* read (and overwrite with) values that may be specified in config file */
+ for (i=0; image_config_vars[i].token != NULL; i++)
+ {
+ char *value = getHashEntry(setup_file_hash, image_config_vars[i].token);
+
+ if (value != NULL)
+ *image_config_vars[i].value = get_integer_from_string(value);
+ }
+
+ freeSetupFileHash(setup_file_hash);
+}
#include "main.h"
+boolean LevelFileExists(int);
+void LoadLevelFromFilename(struct LevelInfo *, char *);
void LoadLevel(int);
+void LoadLevelTemplate(int);
void SaveLevel(int);
+void SaveLevelTemplate();
+void DumpLevel(struct LevelInfo *);
+void LoadTapeFromFilename(char *);
void LoadTape(int);
void SaveTape(int);
void DumpTape(struct TapeInfo *);
void LoadScore(int);
void SaveScore(int);
-void LoadSetup(void);
-void SaveSetup(void);
+void LoadSetup();
+void SaveSetup();
+
+void LoadCustomElementDescriptions();
+void LoadSpecialMenuDesignSettings();
#endif /* FILES_H */
#include "libgame/libgame.h"
#include "game.h"
+#include "init.h"
#include "tools.h"
#include "screens.h"
-#include "init.h"
#include "files.h"
#include "tape.h"
#include "network.h"
#define DOUBLE_PLAYER_SPEED(p) (HALVE_MOVE_DELAY((p)->move_delay_value))
#define HALVE_PLAYER_SPEED(p) (DOUBLE_MOVE_DELAY((p)->move_delay_value))
+/* values for other actions */
+#define MOVE_STEPSIZE_NORMAL (TILEX / MOVE_DELAY_NORMAL_SPEED)
+
+#define INIT_GFX_RANDOM() (SimpleRND(1000000))
+
+#define GET_NEW_PUSH_DELAY(e) ( (element_info[e].push_delay_fixed) + \
+ RND(element_info[e].push_delay_random))
+#define GET_NEW_MOVE_DELAY(e) ( (element_info[e].move_delay_fixed) + \
+ RND(element_info[e].move_delay_random))
+
+#define ELEMENT_CAN_ENTER_FIELD_GENERIC(e, x, y, condition) \
+ (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) || \
+ (condition) || \
+ (DONT_COLLIDE_WITH(e) && \
+ IS_FREE_OR_PLAYER(x, y))))
+
+#define ELEMENT_CAN_ENTER_FIELD_GENERIC_2(x, y, condition) \
+ (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) || \
+ (condition)))
+
+#define ELEMENT_CAN_ENTER_FIELD(e, x, y) \
+ ELEMENT_CAN_ENTER_FIELD_GENERIC(e, x, y, 0)
+
+#define ELEMENT_CAN_ENTER_FIELD_OR_ACID(e, x, y) \
+ ELEMENT_CAN_ENTER_FIELD_GENERIC(e, x, y, (Feld[x][y] == EL_ACID))
+
+#define ELEMENT_CAN_ENTER_FIELD_OR_ACID_2(x, y) \
+ ELEMENT_CAN_ENTER_FIELD_GENERIC_2(x, y, (Feld[x][y] == EL_ACID))
+
+#define ENEMY_CAN_ENTER_FIELD(x, y) (IN_LEV_FIELD(x, y) && IS_FREE(x, y))
+
+#define YAMYAM_CAN_ENTER_FIELD(x, y) \
+ (IN_LEV_FIELD(x, y) && (IS_FREE_OR_PLAYER(x, y) || \
+ Feld[x][y] == EL_DIAMOND))
+
+#define DARK_YAMYAM_CAN_ENTER_FIELD(x, y) \
+ (IN_LEV_FIELD(x, y) && (IS_FREE_OR_PLAYER(x, y) || \
+ IS_FOOD_DARK_YAMYAM(Feld[x][y])))
+
+#define PACMAN_CAN_ENTER_FIELD(x, y) \
+ (IN_LEV_FIELD(x, y) && (IS_FREE_OR_PLAYER(x, y) || \
+ IS_AMOEBOID(Feld[x][y])))
+
+#define PIG_CAN_ENTER_FIELD(x, y) \
+ (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) || \
+ IS_FOOD_PIG(Feld[x][y])))
+
+#define PENGUIN_CAN_ENTER_FIELD(x, y) \
+ (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) || \
+ IS_FOOD_PENGUIN(Feld[x][y]) || \
+ Feld[x][y] == EL_EXIT_OPEN || \
+ Feld[x][y] == EL_ACID))
+
+#define MOLE_CAN_ENTER_FIELD(x, y, condition) \
+ (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) || (condition)))
+
+#define IN_LEV_FIELD_AND_IS_FREE(x, y) (IN_LEV_FIELD(x, y) && IS_FREE(x, y))
+#define IN_LEV_FIELD_AND_NOT_FREE(x, y) (IN_LEV_FIELD(x, y) && !IS_FREE(x, y))
+
/* game button identifiers */
#define GAME_CTRL_ID_STOP 0
#define GAME_CTRL_ID_PAUSE 1
#define NUM_GAME_BUTTONS 6
+
/* forward declaration for internal use */
+
+static void InitBeltMovement(void);
static void CloseAllOpenTimegates(void);
static void CheckGravityMovement(struct PlayerInfo *);
static void KillHeroUnlessProtected(int, int);
-void PlaySoundLevel(int, int, int);
-void PlaySoundLevelAction(int, int, int);
-void PlaySoundLevelElementAction(int, int, int, int);
+static void TestIfPlayerTouchesCustomElement(int, int);
+static void TestIfElementTouchesCustomElement(int, int);
+
+static boolean CheckTriggeredElementChange(int, int, int, int);
+static boolean CheckElementChange(int, int, int, int);
+static void ChangeElementNow(int, int, int);
+
+static void PlaySoundLevel(int, int, int);
+static void PlaySoundLevelNearest(int, int, int);
+static void PlaySoundLevelAction(int, int, int);
+static void PlaySoundLevelElementAction(int, int, int, int);
+static void PlaySoundLevelActionIfLoop(int, int, int);
+static void StopSoundLevelActionIfLoop(int, int, int);
static void MapGameButtons();
static void HandleGameButtons(struct GadgetInfo *);
static struct GadgetInfo *game_gadget[NUM_GAME_BUTTONS];
-#define SND_ACTION_UNKNOWN 0
-#define SND_ACTION_WAITING 1
-#define SND_ACTION_MOVING 2
-#define SND_ACTION_DIGGING 3
-#define SND_ACTION_COLLECTING 4
-#define SND_ACTION_PASSING 5
-#define SND_ACTION_IMPACT 6
-#define SND_ACTION_PUSHING 7
-#define SND_ACTION_ACTIVATING 8
-#define SND_ACTION_BURNING 9
-#define NUM_SND_ACTIONS 10
+/* ------------------------------------------------------------------------- */
+/* definition of elements that automatically change to other elements after */
+/* a specified time, eventually calling a function when changing */
+/* ------------------------------------------------------------------------- */
-static struct
-{
- char *text;
- int value;
- boolean is_loop;
-} sound_action_properties[] =
-{
- /* insert _all_ loop sound actions here */
- { ".waiting", SND_ACTION_WAITING, TRUE },
- { ".moving", SND_ACTION_MOVING, TRUE }, /* continuos moving */
- { ".running", SND_ACTION_UNKNOWN, TRUE },
- { ".burning", SND_ACTION_BURNING, TRUE },
- { ".growing", SND_ACTION_UNKNOWN, TRUE },
- { ".attacking", SND_ACTION_UNKNOWN, TRUE },
- { ".activated", SND_ACTION_UNKNOWN, TRUE },
-
- /* other (non-loop) sound actions are optional */
- { ".stepping", SND_ACTION_MOVING, FALSE }, /* discrete moving */
- { ".digging", SND_ACTION_DIGGING, FALSE },
- { ".collecting", SND_ACTION_COLLECTING, FALSE },
- { ".passing", SND_ACTION_PASSING, FALSE },
- { ".impact", SND_ACTION_IMPACT, FALSE },
- { ".pushing", SND_ACTION_PUSHING, FALSE },
- { ".activating", SND_ACTION_ACTIVATING, FALSE },
- { NULL, 0, 0 },
-};
-static int element_action_sound[NUM_LEVEL_ELEMENTS][NUM_SND_ACTIONS];
-static boolean is_loop_sound[NUM_SOUND_EFFECTS];
+/* forward declaration for changer functions */
+static void InitBuggyBase(int x, int y);
+static void WarnBuggyBase(int x, int y);
-#define IS_LOOP_SOUND(x) (is_loop_sound[x])
+static void InitTrap(int x, int y);
+static void ActivateTrap(int x, int y);
+static void ChangeActiveTrap(int x, int y);
+static void InitRobotWheel(int x, int y);
+static void RunRobotWheel(int x, int y);
+static void StopRobotWheel(int x, int y);
-#ifdef DEBUG
-#if 0
-static unsigned int getStateCheckSum(int counter)
+static void InitTimegateWheel(int x, int y);
+static void RunTimegateWheel(int x, int y);
+
+struct ChangingElementInfo
{
- int x, y;
- unsigned int mult = 1;
- unsigned int checksum = 0;
- /*
- static short lastFeld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
- */
- static boolean first_game = TRUE;
+ int element;
+ int target_element;
+ int change_delay;
+ void (*pre_change_function)(int x, int y);
+ void (*change_function)(int x, int y);
+ void (*post_change_function)(int x, int y);
+};
- for (y=0; y<lev_fieldy; y++) for(x=0; x<lev_fieldx; x++)
+static struct ChangingElementInfo changing_element_list[] =
+{
{
- /*
- if (counter == 3)
- {
- if (first_game)
- lastFeld[x][y] = Feld[x][y];
- else if (lastFeld[x][y] != Feld[x][y])
- printf("DIFF: [%d][%d]: lastFeld == %d != %d == Feld\n",
- x, y, lastFeld[x][y], Feld[x][y]);
- }
- */
+ EL_NUT_BREAKING,
+ EL_EMERALD,
+ 6,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ EL_PEARL_BREAKING,
+ EL_EMPTY,
+ 8,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ EL_EXIT_OPENING,
+ EL_EXIT_OPEN,
+ 29,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ EL_SWITCHGATE_OPENING,
+ EL_SWITCHGATE_OPEN,
+ 29,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ EL_SWITCHGATE_CLOSING,
+ EL_SWITCHGATE_CLOSED,
+ 29,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ EL_TIMEGATE_OPENING,
+ EL_TIMEGATE_OPEN,
+ 29,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ EL_TIMEGATE_CLOSING,
+ EL_TIMEGATE_CLOSED,
+ 29,
+ NULL,
+ NULL,
+ NULL
+ },
- checksum += mult++ * Ur[x][y];
- checksum += mult++ * Feld[x][y];
+ {
+ EL_ACID_SPLASH_LEFT,
+ EL_EMPTY,
+ 8,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ EL_ACID_SPLASH_RIGHT,
+ EL_EMPTY,
+ 8,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ EL_SP_BUGGY_BASE,
+ EL_SP_BUGGY_BASE_ACTIVATING,
+ 0,
+ InitBuggyBase,
+ NULL,
+ NULL
+ },
+ {
+ EL_SP_BUGGY_BASE_ACTIVATING,
+ EL_SP_BUGGY_BASE_ACTIVE,
+ 0,
+ InitBuggyBase,
+ NULL,
+ NULL
+ },
+ {
+ EL_SP_BUGGY_BASE_ACTIVE,
+ EL_SP_BUGGY_BASE,
+ 0,
+ InitBuggyBase,
+ WarnBuggyBase,
+ NULL
+ },
+ {
+ EL_TRAP,
+ EL_TRAP_ACTIVE,
+ 0,
+ InitTrap,
+ NULL,
+ ActivateTrap
+ },
+ {
+ EL_TRAP_ACTIVE,
+ EL_TRAP,
+ 31,
+ NULL,
+ ChangeActiveTrap,
+ NULL
+ },
+ {
+ EL_ROBOT_WHEEL_ACTIVE,
+ EL_ROBOT_WHEEL,
+ 0,
+ InitRobotWheel,
+ RunRobotWheel,
+ StopRobotWheel
+ },
+ {
+ EL_TIMEGATE_SWITCH_ACTIVE,
+ EL_TIMEGATE_SWITCH,
+ 0,
+ InitTimegateWheel,
+ RunTimegateWheel,
+ NULL
+ },
- /*
- checksum += mult++ * MovPos[x][y];
- checksum += mult++ * MovDir[x][y];
- checksum += mult++ * MovDelay[x][y];
- checksum += mult++ * Store[x][y];
- checksum += mult++ * Store2[x][y];
- checksum += mult++ * StorePlayer[x][y];
- checksum += mult++ * Frame[x][y];
- checksum += mult++ * AmoebaNr[x][y];
- checksum += mult++ * JustStopped[x][y];
- checksum += mult++ * Stop[x][y];
- */
+ {
+ EL_UNDEFINED,
+ EL_UNDEFINED,
+ -1,
+ NULL,
+ NULL,
+ NULL
}
+};
+
+struct
+{
+ int element;
+ int push_delay_fixed, push_delay_random;
+}
+push_delay_list[] =
+{
+ { EL_SPRING, 0, 0 },
+ { EL_BALLOON, 0, 0 },
- if (counter == 3 && first_game)
- first_game = FALSE;
+ { EL_SOKOBAN_OBJECT, 2, 0 },
+ { EL_SOKOBAN_FIELD_FULL, 2, 0 },
+ { EL_SATELLITE, 2, 0 },
+ { EL_SP_DISK_YELLOW, 2, 0 },
+
+ { EL_UNDEFINED, 0, 0 },
+};
+
+struct
+{
+ int element;
+ int move_stepsize;
+}
+move_stepsize_list[] =
+{
+ { EL_AMOEBA_DROP, 2 },
+ { EL_AMOEBA_DROPPING, 2 },
+ { EL_QUICKSAND_FILLING, 1 },
+ { EL_QUICKSAND_EMPTYING, 1 },
+ { EL_MAGIC_WALL_FILLING, 2 },
+ { EL_BD_MAGIC_WALL_FILLING, 2 },
+ { EL_MAGIC_WALL_EMPTYING, 2 },
+ { EL_BD_MAGIC_WALL_EMPTYING, 2 },
+
+ { EL_UNDEFINED, 0 },
+};
- return checksum;
+struct
+{
+ int element;
+ int gem_count;
}
-#endif
-#endif
+gem_count_list[] =
+{
+ { EL_EMERALD, 1 },
+ { EL_BD_DIAMOND, 1 },
+ { EL_EMERALD_YELLOW, 1 },
+ { EL_EMERALD_RED, 1 },
+ { EL_EMERALD_PURPLE, 1 },
+ { EL_DIAMOND, 3 },
+ { EL_SP_INFOTRON, 1 },
+ { EL_PEARL, 5 },
+ { EL_CRYSTAL, 8 },
+
+ { EL_UNDEFINED, 0 },
+};
+static boolean changing_element[MAX_NUM_ELEMENTS];
+static unsigned long trigger_events[MAX_NUM_ELEMENTS];
+#define IS_AUTO_CHANGING(e) (changing_element[e])
+#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))
void GetPlayerConfig()
InitJoysticks();
}
-static int getBeltNrFromElement(int element)
+static int getBeltNrFromBeltElement(int element)
+{
+ return (element < EL_CONVEYOR_BELT_2_LEFT ? 0 :
+ element < EL_CONVEYOR_BELT_3_LEFT ? 1 :
+ element < EL_CONVEYOR_BELT_4_LEFT ? 2 : 3);
+}
+
+static int getBeltNrFromBeltActiveElement(int element)
{
- return (element < EL_BELT2_LEFT ? 0 :
- element < EL_BELT3_LEFT ? 1 :
- element < EL_BELT4_LEFT ? 2 : 3);
+ return (element < EL_CONVEYOR_BELT_2_LEFT_ACTIVE ? 0 :
+ element < EL_CONVEYOR_BELT_3_LEFT_ACTIVE ? 1 :
+ element < EL_CONVEYOR_BELT_4_LEFT_ACTIVE ? 2 : 3);
}
-static int getBeltNrFromSwitchElement(int element)
+static int getBeltNrFromBeltSwitchElement(int element)
{
- return (element < EL_BELT2_SWITCH_LEFT ? 0 :
- element < EL_BELT3_SWITCH_LEFT ? 1 :
- element < EL_BELT4_SWITCH_LEFT ? 2 : 3);
+ return (element < EL_CONVEYOR_BELT_2_SWITCH_LEFT ? 0 :
+ element < EL_CONVEYOR_BELT_3_SWITCH_LEFT ? 1 :
+ element < EL_CONVEYOR_BELT_4_SWITCH_LEFT ? 2 : 3);
}
-static int getBeltDirNrFromSwitchElement(int element)
+static int getBeltDirNrFromBeltSwitchElement(int element)
{
static int belt_base_element[4] =
{
- EL_BELT1_SWITCH_LEFT,
- EL_BELT2_SWITCH_LEFT,
- EL_BELT3_SWITCH_LEFT,
- EL_BELT4_SWITCH_LEFT
+ EL_CONVEYOR_BELT_1_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_2_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_3_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_4_SWITCH_LEFT
};
- int belt_nr = getBeltNrFromSwitchElement(element);
+ int belt_nr = getBeltNrFromBeltSwitchElement(element);
int belt_dir_nr = element - belt_base_element[belt_nr];
return (belt_dir_nr % 3);
}
-static int getBeltDirFromSwitchElement(int element)
+static int getBeltDirFromBeltSwitchElement(int element)
{
static int belt_move_dir[3] =
{
MV_RIGHT
};
- int belt_dir_nr = getBeltDirNrFromSwitchElement(element);
+ int belt_dir_nr = getBeltDirNrFromBeltSwitchElement(element);
return belt_move_dir[belt_dir_nr];
}
static void InitField(int x, int y, boolean init_game)
{
- switch (Feld[x][y])
+ int element = Feld[x][y];
+
+ switch (element)
{
case EL_SP_MURPHY:
if (init_game)
Feld[x][y] = EL_SP_MURPHY_CLONE;
break;
}
+ else
+ {
+ stored_player[0].use_murphy_graphic = TRUE;
+ }
+
+ Feld[x][y] = EL_PLAYER_1;
}
/* no break! */
- case EL_SPIELFIGUR:
- if (init_game)
- Feld[x][y] = EL_SPIELER1;
- /* no break! */
- case EL_SPIELER1:
- case EL_SPIELER2:
- case EL_SPIELER3:
- case EL_SPIELER4:
+ case EL_PLAYER_1:
+ case EL_PLAYER_2:
+ case EL_PLAYER_3:
+ case EL_PLAYER_4:
if (init_game)
{
- struct PlayerInfo *player = &stored_player[Feld[x][y] - EL_SPIELER1];
+ struct PlayerInfo *player = &stored_player[Feld[x][y] - EL_PLAYER_1];
int jx = player->jx, jy = player->jy;
player->present = TRUE;
}
}
- Feld[x][y] = EL_LEERRAUM;
+ Feld[x][y] = EL_EMPTY;
player->jx = player->last_jx = x;
player->jy = player->last_jy = y;
}
break;
- case EL_BADEWANNE:
- if (x < lev_fieldx-1 && Feld[x+1][y] == EL_SALZSAEURE)
- Feld[x][y] = EL_BADEWANNE1;
- else if (x > 0 && Feld[x-1][y] == EL_SALZSAEURE)
- Feld[x][y] = EL_BADEWANNE2;
- else if (y > 0 && Feld[x][y-1] == EL_BADEWANNE1)
- Feld[x][y] = EL_BADEWANNE3;
- else if (y > 0 && Feld[x][y-1] == EL_SALZSAEURE)
- Feld[x][y] = EL_BADEWANNE4;
- else if (y > 0 && Feld[x][y-1] == EL_BADEWANNE2)
- Feld[x][y] = EL_BADEWANNE5;
+ case EL_STONEBLOCK:
+ if (x < lev_fieldx-1 && Feld[x+1][y] == EL_ACID)
+ Feld[x][y] = EL_ACID_POOL_TOPLEFT;
+ else if (x > 0 && Feld[x-1][y] == EL_ACID)
+ Feld[x][y] = EL_ACID_POOL_TOPRIGHT;
+ else if (y > 0 && Feld[x][y-1] == EL_ACID_POOL_TOPLEFT)
+ Feld[x][y] = EL_ACID_POOL_BOTTOMLEFT;
+ else if (y > 0 && Feld[x][y-1] == EL_ACID)
+ Feld[x][y] = EL_ACID_POOL_BOTTOM;
+ else if (y > 0 && Feld[x][y-1] == EL_ACID_POOL_TOPRIGHT)
+ Feld[x][y] = EL_ACID_POOL_BOTTOMRIGHT;
break;
- case EL_KAEFER_RIGHT:
- case EL_KAEFER_UP:
- case EL_KAEFER_LEFT:
- case EL_KAEFER_DOWN:
- case EL_KAEFER:
- case EL_FLIEGER_RIGHT:
- case EL_FLIEGER_UP:
- case EL_FLIEGER_LEFT:
- case EL_FLIEGER_DOWN:
- case EL_FLIEGER:
- case EL_BUTTERFLY_RIGHT:
- case EL_BUTTERFLY_UP:
- case EL_BUTTERFLY_LEFT:
- case EL_BUTTERFLY_DOWN:
- case EL_BUTTERFLY:
- case EL_FIREFLY_RIGHT:
- case EL_FIREFLY_UP:
- case EL_FIREFLY_LEFT:
- case EL_FIREFLY_DOWN:
- case EL_FIREFLY:
+ case EL_BUG_RIGHT:
+ case EL_BUG_UP:
+ case EL_BUG_LEFT:
+ case EL_BUG_DOWN:
+ case EL_BUG:
+ case EL_SPACESHIP_RIGHT:
+ case EL_SPACESHIP_UP:
+ case EL_SPACESHIP_LEFT:
+ case EL_SPACESHIP_DOWN:
+ case EL_SPACESHIP:
+ case EL_BD_BUTTERFLY_RIGHT:
+ case EL_BD_BUTTERFLY_UP:
+ case EL_BD_BUTTERFLY_LEFT:
+ case EL_BD_BUTTERFLY_DOWN:
+ case EL_BD_BUTTERFLY:
+ case EL_BD_FIREFLY_RIGHT:
+ case EL_BD_FIREFLY_UP:
+ case EL_BD_FIREFLY_LEFT:
+ case EL_BD_FIREFLY_DOWN:
+ case EL_BD_FIREFLY:
case EL_PACMAN_RIGHT:
case EL_PACMAN_UP:
case EL_PACMAN_LEFT:
case EL_PACMAN_DOWN:
- case EL_MAMPFER:
- case EL_MAMPFER2:
+ case EL_YAMYAM:
+ case EL_DARK_YAMYAM:
case EL_ROBOT:
case EL_PACMAN:
case EL_SP_SNIKSNAK:
InitMovDir(x, y);
break;
- case EL_AMOEBE_VOLL:
- case EL_AMOEBE_BD:
+ case EL_AMOEBA_FULL:
+ case EL_BD_AMOEBA:
InitAmoebaNr(x, y);
break;
- case EL_TROPFEN:
+ case EL_AMOEBA_DROP:
if (y == lev_fieldy - 1)
{
- Feld[x][y] = EL_AMOEBING;
- Store[x][y] = EL_AMOEBE_NASS;
+ Feld[x][y] = EL_AMOEBA_GROWING;
+ Store[x][y] = EL_AMOEBA_WET;
}
break;
MovDelay[x][y] = 96;
break;
- case EL_BIRNE_AUS:
+ case EL_LAMP:
local_player->lights_still_needed++;
break;
- case EL_SOKOBAN_FELD_LEER:
+ case EL_SOKOBAN_FIELD_EMPTY:
local_player->sokobanfields_still_needed++;
break;
- case EL_PINGUIN:
+ case EL_PENGUIN:
local_player->friends_still_needed++;
break;
- case EL_SCHWEIN:
- case EL_DRACHE:
+ case EL_PIG:
+ case EL_DRAGON:
MovDir[x][y] = 1 << RND(4);
break;
case EL_SP_EMPTY:
- Feld[x][y] = EL_LEERRAUM;
+ Feld[x][y] = EL_EMPTY;
break;
case EL_EM_KEY_1_FILE:
Feld[x][y] = EL_EM_KEY_4;
break;
- case EL_BELT1_SWITCH_LEFT:
- case EL_BELT1_SWITCH_MIDDLE:
- case EL_BELT1_SWITCH_RIGHT:
- case EL_BELT2_SWITCH_LEFT:
- case EL_BELT2_SWITCH_MIDDLE:
- case EL_BELT2_SWITCH_RIGHT:
- case EL_BELT3_SWITCH_LEFT:
- case EL_BELT3_SWITCH_MIDDLE:
- case EL_BELT3_SWITCH_RIGHT:
- case EL_BELT4_SWITCH_LEFT:
- case EL_BELT4_SWITCH_MIDDLE:
- case EL_BELT4_SWITCH_RIGHT:
+ case EL_CONVEYOR_BELT_1_SWITCH_LEFT:
+ case EL_CONVEYOR_BELT_1_SWITCH_MIDDLE:
+ case EL_CONVEYOR_BELT_1_SWITCH_RIGHT:
+ case EL_CONVEYOR_BELT_2_SWITCH_LEFT:
+ case EL_CONVEYOR_BELT_2_SWITCH_MIDDLE:
+ case EL_CONVEYOR_BELT_2_SWITCH_RIGHT:
+ case EL_CONVEYOR_BELT_3_SWITCH_LEFT:
+ case EL_CONVEYOR_BELT_3_SWITCH_MIDDLE:
+ case EL_CONVEYOR_BELT_3_SWITCH_RIGHT:
+ case EL_CONVEYOR_BELT_4_SWITCH_LEFT:
+ case EL_CONVEYOR_BELT_4_SWITCH_MIDDLE:
+ case EL_CONVEYOR_BELT_4_SWITCH_RIGHT:
if (init_game)
{
- int belt_nr = getBeltNrFromSwitchElement(Feld[x][y]);
- int belt_dir = getBeltDirFromSwitchElement(Feld[x][y]);
- int belt_dir_nr = getBeltDirNrFromSwitchElement(Feld[x][y]);
+ int belt_nr = getBeltNrFromBeltSwitchElement(Feld[x][y]);
+ int belt_dir = getBeltDirFromBeltSwitchElement(Feld[x][y]);
+ int belt_dir_nr = getBeltDirNrFromBeltSwitchElement(Feld[x][y]);
if (game.belt_dir_nr[belt_nr] == 3) /* initial value */
{
}
break;
- case EL_SWITCHGATE_SWITCH_2: /* always start with same switch pos */
+ case EL_SWITCHGATE_SWITCH_DOWN: /* always start with same switch pos */
if (init_game)
- Feld[x][y] = EL_SWITCHGATE_SWITCH_1;
+ Feld[x][y] = EL_SWITCHGATE_SWITCH_UP;
break;
- case EL_LIGHT_SWITCH_ON:
+ case EL_LIGHT_SWITCH_ACTIVE:
if (init_game)
game.light_time_left = level.time_light * FRAMES_PER_SECOND;
break;
default:
+ if (IS_CUSTOM_ELEMENT(element) && CAN_MOVE(element))
+ InitMovDir(x, y);
break;
}
}
for (j=0; j<4; j++)
if (stored_player[i].key[j])
DrawMiniGraphicExt(drawto, DX_KEYS + j * MINI_TILEX, DY_KEYS,
- GFX_SCHLUESSEL1 + j);
+ el2edimg(EL_KEY_1 + j));
DrawText(DX + XX_EMERALDS, DY + YY_EMERALDS,
- int2str(local_player->gems_still_needed, 3), FS_SMALL, FC_YELLOW);
+ int2str(local_player->gems_still_needed, 3), FONT_TEXT_2);
DrawText(DX + XX_DYNAMITE, DY + YY_DYNAMITE,
- int2str(local_player->dynamite, 3), FS_SMALL, FC_YELLOW);
+ int2str(local_player->dynamite, 3), FONT_TEXT_2);
DrawText(DX + XX_SCORE, DY + YY_SCORE,
- int2str(local_player->score, 5), FS_SMALL, FC_YELLOW);
+ int2str(local_player->score, 5), FONT_TEXT_2);
DrawText(DX + XX_TIME, DY + YY_TIME,
- int2str(TimeLeft, 3), FS_SMALL, FC_YELLOW);
-}
-
-
-/*
- =============================================================================
- InitGameSound()
- -----------------------------------------------------------------------------
- initialize sound effect lookup table for element actions
- =============================================================================
-*/
-
-void InitGameSound()
-{
- int sound_effect_properties[NUM_SOUND_EFFECTS];
- int i, j;
-
-#if 0
- debug_print_timestamp(0, NULL);
-#endif
-
- for (i=0; i<NUM_SND_ACTIONS; i++)
- for (j=0; j<NUM_LEVEL_ELEMENTS; j++)
- element_action_sound[j][i] = -1;
-
- for (i=0; i<NUM_SOUND_EFFECTS; i++)
- {
- int len_effect_text = strlen(sound_effects[i].text);
-
- sound_effect_properties[i] = SND_ACTION_UNKNOWN;
- is_loop_sound[i] = FALSE;
-
- /* determine all loop sounds and identify certain sound classes */
-
- j = 0;
- while (sound_action_properties[j].text)
- {
- int len_action_text = strlen(sound_action_properties[j].text);
-
- if (len_action_text < len_effect_text &&
- strcmp(&sound_effects[i].text[len_effect_text - len_action_text],
- sound_action_properties[j].text) == 0)
- {
- sound_effect_properties[i] = sound_action_properties[j].value;
-
- if (sound_action_properties[j].is_loop)
- is_loop_sound[i] = TRUE;
- }
-
- j++;
- }
-
- /* associate elements and some selected sound actions */
-
- for (j=0; j<NUM_LEVEL_ELEMENTS; j++)
- {
- if (element_info[j].sound_class_name)
- {
- int len_class_text = strlen(element_info[j].sound_class_name);
-
- if (len_class_text + 1 < len_effect_text &&
- strncmp(sound_effects[i].text,
- element_info[j].sound_class_name, len_class_text) == 0 &&
- sound_effects[i].text[len_class_text] == '.')
- {
- int sound_action_value = sound_effect_properties[i];
-
- element_action_sound[j][sound_action_value] = i;
- }
- }
- }
- }
-
-#if 0
- debug_print_timestamp(0, "InitGameEngine");
-#endif
-
-#if 0
- /* TEST ONLY */
- {
- int element = EL_ERDREICH;
- int sound_action = SND_ACTION_DIGGING;
- int j = 0;
-
- while (sound_action_properties[j].text)
- {
- if (sound_action_properties[j].value == sound_action)
- printf("element %d, sound action '%s' == %d\n",
- element, sound_action_properties[j].text,
- element_action_sound[element][sound_action]);
- j++;
- }
- }
-#endif
+ int2str(TimeLeft, 3), FONT_TEXT_2);
}
{
int i;
+ /* set game engine from tape file when re-playing, else from level file */
game.engine_version = (tape.playing ? tape.engine_version :
level.game_version);
+ /* dynamically adjust element properties according to game engine version */
+ InitElementPropertiesEngine(game.engine_version);
+
#if 0
printf("level %d: level version == %06d\n", level_nr, level.game_version);
printf(" tape version == %06d [%s] [file: %06d]\n",
printf(" => game.engine_version == %06d\n", game.engine_version);
#endif
+ /* ---------- initialize player's initial move delay --------------------- */
+
/* dynamically adjust player properties according to game engine version */
game.initial_move_delay =
(game.engine_version <= VERSION_IDENT(2,0,1) ? INITIAL_MOVE_DELAY_ON :
game.initial_move_delay_value =
(level.double_speed ? MOVE_DELAY_HIGH_SPEED : MOVE_DELAY_NORMAL_SPEED);
- /* dynamically adjust element properties according to game engine version */
+ /* ---------- initialize changing elements ------------------------------- */
+
+ /* initialize changing elements information */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
{
- static int ep_em_slippery_wall[] =
+#if 1
+ element_info[i].change.pre_change_function = NULL;
+ element_info[i].change.change_function = NULL;
+ element_info[i].change.post_change_function = NULL;
+
+ if (!IS_CUSTOM_ELEMENT(i))
{
- EL_BETON,
- EL_MAUERWERK,
- EL_MAUER_LEBT,
- EL_MAUER_X,
- EL_MAUER_Y,
- EL_MAUER_XY
- };
- static int ep_em_slippery_wall_num = SIZEOF_ARRAY_INT(ep_em_slippery_wall);
+ element_info[i].change.target_element = EL_EMPTY_SPACE;
+ element_info[i].change.delay_fixed = 0;
+ element_info[i].change.delay_random = 0;
+ element_info[i].change.delay_frames = 1;
+ }
- for (i=0; i<ep_em_slippery_wall_num; i++)
+ changing_element[i] = FALSE;
+#else
+ changing_element[i].base_element = EL_UNDEFINED;
+ changing_element[i].next_element = EL_UNDEFINED;
+ changing_element[i].change_delay = -1;
+ changing_element[i].pre_change_function = NULL;
+ changing_element[i].change_function = NULL;
+ changing_element[i].post_change_function = NULL;
+#endif
+ }
+
+ /* add changing elements from pre-defined list */
+ for (i=0; changing_element_list[i].element != EL_UNDEFINED; i++)
+ {
+ int element = changing_element_list[i].element;
+ struct ChangingElementInfo *ce = &changing_element_list[i];
+ struct ElementChangeInfo *change = &element_info[element].change;
+
+#if 1
+ change->target_element = ce->target_element;
+ change->delay_fixed = ce->change_delay;
+ change->pre_change_function = ce->pre_change_function;
+ change->change_function = ce->change_function;
+ change->post_change_function = ce->post_change_function;
+
+ changing_element[element] = TRUE;
+#else
+ changing_element[element].base_element = ce->base_element;
+ changing_element[element].next_element = ce->next_element;
+ changing_element[element].change_delay = ce->change_delay;
+ changing_element[element].pre_change_function = ce->pre_change_function;
+ changing_element[element].change_function = ce->change_function;
+ changing_element[element].post_change_function = ce->post_change_function;
+#endif
+ }
+
+ /* add changing elements from custom element configuration */
+ for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+ {
+ int element = EL_CUSTOM_START + i;
+#if 0
+ struct ElementChangeInfo *change = &element_info[element].change;
+#endif
+
+ /* only add custom elements that change after fixed/random frame delay */
+ if (!CAN_CHANGE(element) || !HAS_CHANGE_EVENT(element, CE_DELAY))
+ continue;
+
+#if 1
+ changing_element[element] = TRUE;
+#else
+ changing_element[element].base_element = element;
+ changing_element[element].next_element = change->target_element;
+ changing_element[element].change_delay = (change->delay_fixed *
+ change->delay_frames);
+#endif
+ }
+
+ /* ---------- initialize trigger events ---------------------------------- */
+
+ /* initialize trigger events information */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ trigger_events[i] = EP_BITMASK_DEFAULT;
+
+ /* add trigger events from element change event properties */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ if (HAS_CHANGE_EVENT(i, CE_BY_OTHER))
+ trigger_events[element_info[i].change.trigger_element] |=
+ element_info[i].change.events;
+
+ /* ---------- initialize push delay -------------------------------------- */
+
+ /* initialize push delay values to default */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ {
+ if (!IS_CUSTOM_ELEMENT(i))
{
- if (level.em_slippery_gems) /* special EM style gems behaviour */
- Elementeigenschaften2[ep_em_slippery_wall[i]] |=
- EP_BIT_EM_SLIPPERY_WALL;
- else
- Elementeigenschaften2[ep_em_slippery_wall[i]] &=
- ~EP_BIT_EM_SLIPPERY_WALL;
+ element_info[i].push_delay_fixed = 2;
+ element_info[i].push_delay_random = 8;
}
+ }
- /* "EL_MAUERND" was not slippery for EM gems in version 2.0.1 */
- if (level.em_slippery_gems && game.engine_version > VERSION_IDENT(2,0,1))
- Elementeigenschaften2[EL_MAUERND] |= EP_BIT_EM_SLIPPERY_WALL;
- else
- Elementeigenschaften2[EL_MAUERND] &= ~EP_BIT_EM_SLIPPERY_WALL;
+ /* set push delay value for certain elements from pre-defined list */
+ for (i=0; push_delay_list[i].element != EL_UNDEFINED; i++)
+ {
+ int e = push_delay_list[i].element;
+
+ element_info[e].push_delay_fixed = push_delay_list[i].push_delay_fixed;
+ element_info[e].push_delay_random = push_delay_list[i].push_delay_random;
+ }
+
+ /* ---------- initialize move stepsize ----------------------------------- */
+
+ /* initialize move stepsize values to default */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ if (!IS_CUSTOM_ELEMENT(i))
+ element_info[i].move_stepsize = MOVE_STEPSIZE_NORMAL;
+
+ /* set move stepsize value for certain elements from pre-defined list */
+ for (i=0; move_stepsize_list[i].element != EL_UNDEFINED; i++)
+ {
+ int e = move_stepsize_list[i].element;
+
+ element_info[e].move_stepsize = move_stepsize_list[i].move_stepsize;
}
+
+ /* ---------- initialize gem count --------------------------------------- */
+
+ /* initialize gem count values for each element */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ if (!IS_CUSTOM_ELEMENT(i))
+ element_info[i].gem_count = 0;
+
+ /* add gem count values for all elements from pre-defined list */
+ for (i=0; gem_count_list[i].element != EL_UNDEFINED; i++)
+ element_info[gem_count_list[i].element].gem_count =
+ gem_count_list[i].gem_count;
}
InitGameEngine();
+#if 0
#if DEBUG
#if USE_NEW_AMOEBA_CODE
printf("Using new amoeba code.\n");
#else
printf("Using old amoeba code.\n");
#endif
+#endif
#endif
/* don't play tapes over network */
struct PlayerInfo *player = &stored_player[i];
player->index_nr = i;
- player->element_nr = EL_SPIELER1 + i;
+ player->element_nr = EL_PLAYER_1 + i;
player->present = FALSE;
player->active = FALSE;
player->Pushing = FALSE;
player->Switching = FALSE;
player->GfxPos = 0;
+ player->GfxDir = MV_NO_MOVING;
+ player->GfxAction = ACTION_DEFAULT;
player->Frame = 0;
+ player->StepFrame = 0;
- player->actual_frame_counter = 0;
+ player->use_murphy_graphic = FALSE;
+ player->use_disk_red_graphic = FALSE;
- player->frame_reset_delay = 0;
+ player->actual_frame_counter = 0;
player->last_move_dir = MV_NO_MOVING;
+
player->is_moving = FALSE;
+ player->is_waiting = FALSE;
+ player->is_digging = FALSE;
+ player->is_collecting = FALSE;
player->move_delay = game.initial_move_delay;
player->move_delay_value = game.initial_move_delay_value;
player->last_jx = player->last_jy = 0;
player->jx = player->jy = 0;
- player->shield_passive_time_left = 0;
- player->shield_active_time_left = 0;
+ player->shield_normal_time_left = 0;
+ player->shield_deadly_time_left = 0;
DigField(player, 0, 0, 0, 0, DF_NO_PUSH);
SnapField(player, 0, 0);
AllPlayersGone = FALSE;
- game.yam_content_nr = 0;
+ game.yamyam_content_nr = 0;
game.magic_wall_active = FALSE;
game.magic_wall_time_left = 0;
game.light_time_left = 0;
{
for (y=0; y<lev_fieldy; y++)
{
- Feld[x][y] = Ur[x][y];
+ Feld[x][y] = level.field[x][y];
MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0;
- Store[x][y] = Store2[x][y] = StorePlayer[x][y] = 0;
- Frame[x][y] = 0;
+ ChangeDelay[x][y] = 0;
+ Store[x][y] = Store2[x][y] = StorePlayer[x][y] = Back[x][y] = 0;
AmoebaNr[x][y] = 0;
JustStopped[x][y] = 0;
Stop[x][y] = FALSE;
+ Pushed[x][y] = FALSE;
+ Changing[x][y] = FALSE;
+ ExplodePhase[x][y] = 0;
ExplodeField[x][y] = EX_NO_EXPLOSION;
+
+ GfxFrame[x][y] = 0;
+ GfxAction[x][y] = ACTION_DEFAULT;
+ GfxRandom[x][y] = INIT_GFX_RANDOM();
+ GfxElement[x][y] = EL_UNDEFINED;
}
}
}
}
+ InitBeltMovement();
+
game.emulation = (emulate_bd ? EMU_BOULDERDASH :
emulate_sb ? EMU_SOKOBAN :
emulate_sp ? EMU_SUPAPLEX : EMU_NONE);
player->active = FALSE;
StorePlayer[jx][jy] = 0;
- Feld[jx][jy] = EL_LEERRAUM;
+ Feld[jx][jy] = EL_EMPTY;
}
}
}
player->active = FALSE;
StorePlayer[jx][jy] = 0;
- Feld[jx][jy] = EL_LEERRAUM;
+ Feld[jx][jy] = EL_EMPTY;
}
}
}
}
}
- if (BorderElement == EL_LEERRAUM)
+ if (BorderElement == EL_EMPTY)
{
SBX_Left = 0;
SBX_Right = lev_fieldx - SCR_FIELDX;
DrawLevel();
DrawAllPlayers();
- FadeToFront();
/* after drawing the level, correct some elements */
if (game.timegate_time_left == 0)
BlitBitmap(fieldbuffer, backbuffer, FX, FY, SXSIZE, SYSIZE, SX, SY);
redraw_mask |= REDRAW_FROM_BACKBUFFER;
+ FadeToFront();
/* copy default game door content to main double buffer */
- BlitBitmap(pix[PIX_DOOR], drawto,
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
DOOR_GFX_PAGEX5, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY);
if (level_nr < 100)
- DrawText(DX + XX_LEVEL, DY + YY_LEVEL,
- int2str(level_nr, 2), FS_SMALL, FC_YELLOW);
+ DrawText(DX + XX_LEVEL, DY + YY_LEVEL, int2str(level_nr, 2), FONT_TEXT_2);
else
{
DrawTextExt(drawto, DX + XX_EMERALDS, DY + YY_EMERALDS,
- int2str(level_nr, 3), FS_SMALL, FC_SPECIAL3);
+ int2str(level_nr, 3), FONT_LEVEL_NUMBER, BLIT_OPAQUE);
BlitBitmap(drawto, drawto,
DX + XX_EMERALDS, DY + YY_EMERALDS + 1,
- FONT5_XSIZE * 3, FONT5_YSIZE - 1,
+ getFontWidth(FONT_LEVEL_NUMBER) * 3,
+ getFontHeight(FONT_LEVEL_NUMBER) - 1,
DX + XX_LEVEL - 1, DY + YY_LEVEL + 1);
}
MapTapeButtons();
/* copy actual game door content to door double buffer for OpenDoor() */
- BlitBitmap(drawto, pix[PIX_DB_DOOR],
+ BlitBitmap(drawto, bitmap_db_door,
DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
OpenDoor(DOOR_OPEN_ALL);
- PlaySoundStereo(SND_GAME_STARTING, SOUND_MAX_RIGHT);
+ PlaySoundStereo(SND_GAME_STARTING, SOUND_MIDDLE);
if (setup.sound_music)
PlayMusic(level_nr);
- KeyboardAutoRepeatOff();
+ KeyboardAutoRepeatOffUnlessAutoplay();
if (options.debug)
{
switch(element)
{
- case EL_KAEFER_RIGHT:
- case EL_KAEFER_UP:
- case EL_KAEFER_LEFT:
- case EL_KAEFER_DOWN:
- Feld[x][y] = EL_KAEFER;
- MovDir[x][y] = direction[0][element - EL_KAEFER_RIGHT];
+ case EL_BUG_RIGHT:
+ case EL_BUG_UP:
+ case EL_BUG_LEFT:
+ case EL_BUG_DOWN:
+ Feld[x][y] = EL_BUG;
+ MovDir[x][y] = direction[0][element - EL_BUG_RIGHT];
break;
- case EL_FLIEGER_RIGHT:
- case EL_FLIEGER_UP:
- case EL_FLIEGER_LEFT:
- case EL_FLIEGER_DOWN:
- Feld[x][y] = EL_FLIEGER;
- MovDir[x][y] = direction[0][element - EL_FLIEGER_RIGHT];
+ case EL_SPACESHIP_RIGHT:
+ case EL_SPACESHIP_UP:
+ case EL_SPACESHIP_LEFT:
+ case EL_SPACESHIP_DOWN:
+ Feld[x][y] = EL_SPACESHIP;
+ MovDir[x][y] = direction[0][element - EL_SPACESHIP_RIGHT];
break;
- case EL_BUTTERFLY_RIGHT:
- case EL_BUTTERFLY_UP:
- case EL_BUTTERFLY_LEFT:
- case EL_BUTTERFLY_DOWN:
- Feld[x][y] = EL_BUTTERFLY;
- MovDir[x][y] = direction[0][element - EL_BUTTERFLY_RIGHT];
+ case EL_BD_BUTTERFLY_RIGHT:
+ case EL_BD_BUTTERFLY_UP:
+ case EL_BD_BUTTERFLY_LEFT:
+ case EL_BD_BUTTERFLY_DOWN:
+ Feld[x][y] = EL_BD_BUTTERFLY;
+ MovDir[x][y] = direction[0][element - EL_BD_BUTTERFLY_RIGHT];
break;
- case EL_FIREFLY_RIGHT:
- case EL_FIREFLY_UP:
- case EL_FIREFLY_LEFT:
- case EL_FIREFLY_DOWN:
- Feld[x][y] = EL_FIREFLY;
- MovDir[x][y] = direction[0][element - EL_FIREFLY_RIGHT];
+ case EL_BD_FIREFLY_RIGHT:
+ case EL_BD_FIREFLY_UP:
+ case EL_BD_FIREFLY_LEFT:
+ case EL_BD_FIREFLY_DOWN:
+ Feld[x][y] = EL_BD_FIREFLY;
+ MovDir[x][y] = direction[0][element - EL_BD_FIREFLY_RIGHT];
break;
case EL_PACMAN_RIGHT:
break;
default:
- MovDir[x][y] = 1 << RND(4);
- if (element != EL_KAEFER &&
- element != EL_FLIEGER &&
- element != EL_BUTTERFLY &&
- element != EL_FIREFLY)
- break;
-
- for (i=0; i<4; i++)
+ if (IS_CUSTOM_ELEMENT(element))
{
- int x1 = x + xy[i][0];
- int y1 = y + xy[i][1];
-
- if (!IN_LEV_FIELD(x1, y1) || !IS_FREE(x1, y1))
+ if (element_info[element].move_direction_initial != MV_NO_MOVING)
+ MovDir[x][y] = element_info[element].move_direction_initial;
+ else if (element_info[element].move_pattern == MV_ALL_DIRECTIONS ||
+ element_info[element].move_pattern == MV_TURNING_LEFT ||
+ element_info[element].move_pattern == MV_TURNING_RIGHT)
+ MovDir[x][y] = 1 << RND(4);
+ else if (element_info[element].move_pattern == MV_HORIZONTAL)
+ MovDir[x][y] = (RND(2) ? MV_LEFT : MV_RIGHT);
+ else if (element_info[element].move_pattern == MV_VERTICAL)
+ MovDir[x][y] = (RND(2) ? MV_UP : MV_DOWN);
+ else if (element_info[element].move_pattern & MV_ANY_DIRECTION)
+ MovDir[x][y] = element_info[element].move_pattern;
+ else if (element_info[element].move_pattern == MV_ALONG_LEFT_SIDE ||
+ element_info[element].move_pattern == MV_ALONG_RIGHT_SIDE)
{
- if (element == EL_KAEFER || element == EL_BUTTERFLY)
+ for (i=0; i<4; i++)
{
- MovDir[x][y] = direction[0][i];
- break;
+ int x1 = x + xy[i][0];
+ int y1 = y + xy[i][1];
+
+ if (!IN_LEV_FIELD(x1, y1) || !IS_FREE(x1, y1))
+ {
+ if (element_info[element].move_pattern == MV_ALONG_RIGHT_SIDE)
+ MovDir[x][y] = direction[0][i];
+ else
+ MovDir[x][y] = direction[1][i];
+
+ break;
+ }
}
- else if (element == EL_FLIEGER || element == EL_FIREFLY ||
- element == EL_SP_SNIKSNAK || element == EL_SP_ELECTRON)
+ }
+ }
+ else
+ {
+ MovDir[x][y] = 1 << RND(4);
+
+ if (element != EL_BUG &&
+ element != EL_SPACESHIP &&
+ element != EL_BD_BUTTERFLY &&
+ element != EL_BD_FIREFLY)
+ break;
+
+ for (i=0; i<4; i++)
+ {
+ int x1 = x + xy[i][0];
+ int y1 = y + xy[i][1];
+
+ if (!IN_LEV_FIELD(x1, y1) || !IS_FREE(x1, y1))
{
- MovDir[x][y] = direction[1][i];
- break;
+ if (element == EL_BUG || element == EL_BD_BUTTERFLY)
+ {
+ MovDir[x][y] = direction[0][i];
+ break;
+ }
+ else if (element == EL_SPACESHIP || element == EL_BD_FIREFLY ||
+ element == EL_SP_SNIKSNAK || element == EL_SP_ELECTRON)
+ {
+ MovDir[x][y] = direction[1][i];
+ break;
+ }
}
}
}
if (local_player->MovPos)
return;
+ if (tape.playing && tape.auto_play)
+ tape.auto_play_level_solved = TRUE;
+
local_player->LevelSolved = FALSE;
- PlaySoundStereo(SND_GAME_WINNING, SOUND_MAX_RIGHT);
+ PlaySoundStereo(SND_GAME_WINNING, SOUND_MIDDLE);
if (TimeLeft)
{
if (!tape.playing && setup.sound_loops)
- PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MAX_RIGHT,
+ PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MIDDLE,
SND_CTRL_PLAY_LOOP);
while (TimeLeft > 0)
{
if (!tape.playing && !setup.sound_loops)
- PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_RIGHT);
+ PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MIDDLE);
if (TimeLeft > 0 && !(TimeLeft % 10))
- RaiseScore(level.score[SC_ZEITBONUS]);
+ RaiseScore(level.score[SC_TIME_BONUS]);
if (TimeLeft > 100 && !(TimeLeft % 10))
TimeLeft -= 10;
else
TimeLeft--;
- DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FS_SMALL, FC_YELLOW);
+ DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FONT_TEXT_2);
BackToFront();
if (!tape.playing)
else if (level.time == 0) /* level without time limit */
{
if (!tape.playing && setup.sound_loops)
- PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MAX_RIGHT,
+ PlaySoundExt(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_VOLUME, SOUND_MIDDLE,
SND_CTRL_PLAY_LOOP);
while (TimePlayed < 999)
{
if (!tape.playing && !setup.sound_loops)
- PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MAX_RIGHT);
+ PlaySoundStereo(SND_GAME_LEVELTIME_BONUS, SOUND_MIDDLE);
if (TimePlayed < 999 && !(TimePlayed % 10))
- RaiseScore(level.score[SC_ZEITBONUS]);
+ RaiseScore(level.score[SC_TIME_BONUS]);
if (TimePlayed < 900 && !(TimePlayed % 10))
TimePlayed += 10;
else
TimePlayed++;
- DrawText(DX_TIME, DY_TIME, int2str(TimePlayed, 3), FS_SMALL, FC_YELLOW);
+ DrawText(DX_TIME, DY_TIME, int2str(TimePlayed, 3), FONT_TEXT_2);
BackToFront();
if (!tape.playing)
StopSound(SND_GAME_LEVELTIME_BONUS);
}
-#if 0
- FadeSounds();
-#endif
-
/* Hero disappears */
DrawLevelField(ExitX, ExitY);
BackToFront();
if ((hi_pos = NewHiScore()) >= 0)
{
- game_status = HALLOFFAME;
+ game_status = GAME_MODE_SCORES;
DrawHallOfFame(hi_pos);
if (raise_level)
{
}
else
{
- game_status = MAINMENU;
+ game_status = GAME_MODE_MAIN;
if (raise_level)
{
level_nr++;
return position;
}
+void InitPlayerGfxAnimation(struct PlayerInfo *player, int action, int dir)
+{
+ if (player->GfxAction != action || player->GfxDir != dir)
+ {
+#if 0
+ printf("Player frame reset! (%d => %d, %d => %d)\n",
+ player->GfxAction, action, player->GfxDir, dir);
+#endif
+
+ player->GfxAction = action;
+ player->GfxDir = dir;
+ player->Frame = 0;
+ player->StepFrame = 0;
+ }
+}
+
+static void ResetRandomAnimationValue(int x, int y)
+{
+ GfxRandom[x][y] = INIT_GFX_RANDOM();
+}
+
+static void ResetGfxAnimation(int x, int y)
+{
+ GfxFrame[x][y] = 0;
+ GfxAction[x][y] = ACTION_DEFAULT;
+}
+
void InitMovingField(int x, int y, int direction)
{
- int newx = x + (direction == MV_LEFT ? -1 : direction == MV_RIGHT ? +1 : 0);
- int newy = y + (direction == MV_UP ? -1 : direction == MV_DOWN ? +1 : 0);
+ int element = Feld[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 newx = x + dx;
+ int newy = y + dy;
+
+ if (!JustStopped[x][y] || direction != MovDir[x][y])
+ ResetGfxAnimation(x, y);
- MovDir[x][y] = direction;
- MovDir[newx][newy] = direction;
- if (Feld[newx][newy] == EL_LEERRAUM)
+ MovDir[newx][newy] = MovDir[x][y] = direction;
+
+ if (Feld[newx][newy] == EL_EMPTY)
Feld[newx][newy] = EL_BLOCKED;
+
+ if (direction == MV_DOWN && CAN_FALL(element))
+ GfxAction[x][y] = ACTION_FALLING;
+ else
+ GfxAction[x][y] = ACTION_MOVING;
+
+ GfxFrame[newx][newy] = GfxFrame[x][y];
+ GfxAction[newx][newy] = GfxAction[x][y];
+ GfxRandom[newx][newy] = GfxRandom[x][y];
}
void Moving2Blocked(int x, int y, int *goes_to_x, int *goes_to_y)
static void RemoveField(int x, int y)
{
- Feld[x][y] = EL_LEERRAUM;
+ Feld[x][y] = EL_EMPTY;
+
MovPos[x][y] = 0;
MovDir[x][y] = 0;
MovDelay[x][y] = 0;
+
+ AmoebaNr[x][y] = 0;
+ ChangeDelay[x][y] = 0;
+ Pushed[x][y] = FALSE;
+
+ GfxElement[x][y] = EL_UNDEFINED;
+ GfxAction[x][y] = ACTION_DEFAULT;
}
void RemoveMovingField(int x, int y)
{
int oldx = x, oldy = y, newx = x, newy = y;
+ int element = Feld[x][y];
+ int next_element = EL_UNDEFINED;
- if (Feld[x][y] != EL_BLOCKED && !IS_MOVING(x, y))
+ if (element != EL_BLOCKED && !IS_MOVING(x, y))
return;
if (IS_MOVING(x, y))
if (Feld[newx][newy] != EL_BLOCKED)
return;
}
- else if (Feld[x][y] == EL_BLOCKED)
+ else if (element == EL_BLOCKED)
{
Blocked2Moving(x, y, &oldx, &oldy);
if (!IS_MOVING(oldx, oldy))
return;
}
- if (Feld[x][y] == EL_BLOCKED &&
+ if (element == EL_BLOCKED &&
(Feld[oldx][oldy] == EL_QUICKSAND_EMPTYING ||
Feld[oldx][oldy] == EL_MAGIC_WALL_EMPTYING ||
- Feld[oldx][oldy] == EL_MAGIC_WALL_BD_EMPTYING ||
- Feld[oldx][oldy] == EL_AMOEBA_DRIPPING))
- Feld[oldx][oldy] = get_next_element(Feld[oldx][oldy]);
- else
- Feld[oldx][oldy] = EL_LEERRAUM;
+ Feld[oldx][oldy] == EL_BD_MAGIC_WALL_EMPTYING ||
+ Feld[oldx][oldy] == EL_AMOEBA_DROPPING))
+ next_element = get_next_element(Feld[oldx][oldy]);
+
+ RemoveField(oldx, oldy);
+ RemoveField(newx, newy);
Store[oldx][oldy] = Store2[oldx][oldy] = 0;
- Feld[newx][newy] = EL_LEERRAUM;
- MovPos[oldx][oldy] = MovDir[oldx][oldy] = MovDelay[oldx][oldy] = 0;
- MovPos[newx][newy] = MovDir[newx][newy] = MovDelay[newx][newy] = 0;
+ if (next_element != EL_UNDEFINED)
+ Feld[oldx][oldy] = next_element;
DrawLevelField(oldx, oldy);
DrawLevelField(newx, newy);
void DrawDynamite(int x, int y)
{
int sx = SCREENX(x), sy = SCREENY(y);
- int graphic = el2gfx(Feld[x][y]);
- int phase;
+ int graphic = el2img(Feld[x][y]);
+ int frame;
if (!IN_SCR_FIELD(sx, sy) || IS_PLAYER(x, y))
return;
- if (Store[x][y])
- DrawGraphic(sx, sy, el2gfx(Store[x][y]));
+ if (IS_WALKABLE_INSIDE(Back[x][y]))
+ return;
- if (Feld[x][y] == EL_DYNAMITE_ACTIVE)
- {
- if ((phase = (96 - MovDelay[x][y]) / 12) > 6)
- phase = 6;
- }
- else
- {
- if ((phase = ((96 - MovDelay[x][y]) / 6) % 8) > 3)
- phase = 7 - phase;
- }
+ if (Back[x][y])
+ DrawGraphic(sx, sy, el2img(Back[x][y]), 0);
+ else if (Store[x][y])
+ DrawGraphic(sx, sy, el2img(Store[x][y]), 0);
+
+ frame = getGraphicAnimationFrame(graphic, GfxFrame[x][y]);
+#if 1
+ if (Back[x][y] || Store[x][y])
+ DrawGraphicThruMask(sx, sy, graphic, frame);
+ else
+ DrawGraphic(sx, sy, graphic, frame);
+#else
if (game.emulation == EMU_SUPAPLEX)
- DrawGraphic(sx, sy, GFX_SP_DISK_RED);
+ DrawGraphic(sx, sy, IMG_SP_DISK_RED, frame);
else if (Store[x][y])
- DrawGraphicThruMask(sx, sy, graphic + phase);
+ DrawGraphicThruMask(sx, sy, graphic, frame);
else
- DrawGraphic(sx, sy, graphic + phase);
+ DrawGraphic(sx, sy, graphic, frame);
+#endif
}
void CheckDynamite(int x, int y)
{
- if (MovDelay[x][y]) /* dynamite is still waiting to explode */
+ if (MovDelay[x][y] != 0) /* dynamite is still waiting to explode */
{
MovDelay[x][y]--;
- if (MovDelay[x][y])
- {
- if (!(MovDelay[x][y] % 6))
- PlaySoundLevelAction(x, y, SND_ACTION_BURNING);
-
- if (IS_ACTIVE_BOMB(Feld[x][y]))
- {
- int delay = (Feld[x][y] == EL_DYNAMITE_ACTIVE ? 12 : 6);
- if (!(MovDelay[x][y] % delay))
- DrawDynamite(x, y);
- }
+ if (MovDelay[x][y] != 0)
+ {
+ DrawDynamite(x, y);
+ PlaySoundLevelActionIfLoop(x, y, ACTION_ACTIVE);
return;
}
}
- if (Feld[x][y] == EL_DYNAMITE_ACTIVE)
- StopSound(SND_DYNAMITE_BURNING);
+#if 1
+ StopSoundLevelActionIfLoop(x, y, ACTION_ACTIVE);
+#else
+ if (Feld[x][y] == EL_DYNAMITE_ACTIVE ||
+ Feld[x][y] == EL_SP_DISK_RED_ACTIVE)
+ StopSound(SND_DYNAMITE_ACTIVE);
else
- StopSound(SND_DYNABOMB_BURNING);
+ StopSound(SND_DYNABOMB_ACTIVE);
+#endif
Bang(x, y);
}
void Explode(int ex, int ey, int phase, int mode)
{
int x, y;
- int num_phase = 9, delay = (game.emulation == EMU_SUPAPLEX ? 3 : 2);
+ int num_phase = 9;
+ int delay = (game.emulation == EMU_SUPAPLEX ? 3 : 2);
int last_phase = num_phase * delay;
int half_phase = (num_phase / 2) * delay;
int first_phase_after_start = EX_PHASE_START + 1;
{
int center_element = Feld[ex][ey];
+#if 0
+ /* --- This is only really needed (and now handled) in "Impact()". --- */
+ /* do not explode moving elements that left the explode field in time */
+ if (game.engine_version >= RELEASE_IDENT(2,2,0,7) &&
+ center_element == EL_EMPTY && (mode == EX_NORMAL || mode == EX_CENTER))
+ return;
+#endif
+
+ if (mode == EX_NORMAL || mode == EX_CENTER)
+ PlaySoundLevelAction(ex, ey, ACTION_EXPLODING);
+
+ /* remove things displayed in background while burning dynamite */
+ if (Back[ex][ey] != EL_EMPTY && !IS_INDESTRUCTIBLE(Back[ex][ey]))
+ Back[ex][ey] = 0;
+
if (IS_MOVING(ex, ey) || IS_BLOCKED(ex, ey))
{
/* put moving element to center field (and let it explode there) */
Feld[ex][ey] = center_element;
}
- for (y=ey-1; y<=ey+1; y++) for(x=ex-1; x<=ex+1; x++)
+ for (y = ey - 1; y <= ey + 1; y++) for(x = ex - 1; x <= ex + 1; x++)
{
+ int xx = x - ex + 1;
+ int yy = y - ey + 1;
int element;
if (!IN_LEV_FIELD(x, y) ||
- ((mode != EX_NORMAL || center_element == EL_AMOEBA2DIAM) &&
+ ((mode != EX_NORMAL || center_element == EL_AMOEBA_TO_DIAMOND) &&
(x != ex || y != ey)))
continue;
if (IS_MOVING(x, y) || IS_BLOCKED(x, y))
{
element = MovingOrBlocked2Element(x, y);
- RemoveMovingField(x, y);
+
+ if (!IS_EXPLOSION_PROOF(element))
+ RemoveMovingField(x, y);
}
- if (IS_MASSIVE(element) || element == EL_BURNING)
+#if 1
+
+#if 0
+ if (IS_EXPLOSION_PROOF(element))
+ continue;
+#else
+ /* indestructible elements can only explode in center (but not flames) */
+ if ((IS_EXPLOSION_PROOF(element) && (x != ex || y != ey)) ||
+ element == EL_FLAMES)
+ continue;
+#endif
+
+#else
+ if ((IS_INDESTRUCTIBLE(element) &&
+ (game.engine_version < VERSION_IDENT(2,2,0) ||
+ (!IS_WALKABLE_OVER(element) && !IS_WALKABLE_UNDER(element)))) ||
+ element == EL_FLAMES)
continue;
+#endif
if (IS_PLAYER(x, y) && SHIELD_ON(PLAYERINFO(x, y)))
{
if (IS_ACTIVE_BOMB(element))
{
/* re-activate things under the bomb like gate or penguin */
- Feld[x][y] = (Store[x][y] ? Store[x][y] : EL_LEERRAUM);
+ Feld[x][y] = (Store[x][y] ? Store[x][y] : EL_EMPTY);
Store[x][y] = 0;
}
continue;
}
- if (element == EL_EXPLODING)
+ /* save walkable background elements while explosion on same tile */
+#if 0
+ if (IS_INDESTRUCTIBLE(element))
+ Back[x][y] = element;
+#else
+ if (IS_WALKABLE(element) && IS_INDESTRUCTIBLE(element))
+ Back[x][y] = element;
+#endif
+
+ /* ignite explodable elements reached by other explosion */
+ if (element == EL_EXPLOSION)
element = Store2[x][y];
+#if 1
+ if (AmoebaNr[x][y] &&
+ (element == EL_AMOEBA_FULL ||
+ element == EL_BD_AMOEBA ||
+ element == EL_AMOEBA_GROWING))
+ {
+ AmoebaCnt[AmoebaNr[x][y]]--;
+ AmoebaCnt2[AmoebaNr[x][y]]--;
+ }
+
+ RemoveField(x, y);
+#endif
+
if (IS_PLAYER(ex, ey) && !PLAYER_PROTECTED(ex, ey))
{
switch(StorePlayer[ex][ey])
{
- case EL_SPIELER2:
- Store[x][y] = EL_EDELSTEIN_ROT;
+ case EL_PLAYER_2:
+ Store[x][y] = EL_EMERALD_RED;
break;
- case EL_SPIELER3:
- Store[x][y] = EL_EDELSTEIN;
+ case EL_PLAYER_3:
+ Store[x][y] = EL_EMERALD;
break;
- case EL_SPIELER4:
- Store[x][y] = EL_EDELSTEIN_LILA;
+ case EL_PLAYER_4:
+ Store[x][y] = EL_EMERALD_PURPLE;
break;
- case EL_SPIELER1:
+ case EL_PLAYER_1:
default:
- Store[x][y] = EL_EDELSTEIN_GELB;
+ Store[x][y] = EL_EMERALD_YELLOW;
break;
}
if (game.emulation == EMU_SUPAPLEX)
- Store[x][y] = EL_LEERRAUM;
+ Store[x][y] = EL_EMPTY;
}
else if (center_element == EL_MOLE)
- Store[x][y] = EL_EDELSTEIN_ROT;
- else if (center_element == EL_PINGUIN)
- Store[x][y] = EL_EDELSTEIN_LILA;
- else if (center_element == EL_KAEFER)
- Store[x][y] = ((x == ex && y == ey) ? EL_DIAMANT : EL_EDELSTEIN);
- else if (center_element == EL_BUTTERFLY)
- Store[x][y] = EL_EDELSTEIN_BD;
+ Store[x][y] = EL_EMERALD_RED;
+ else if (center_element == EL_PENGUIN)
+ Store[x][y] = EL_EMERALD_PURPLE;
+ else if (center_element == EL_BUG)
+ Store[x][y] = ((x == ex && y == ey) ? EL_DIAMOND : EL_EMERALD);
+ else if (center_element == EL_BD_BUTTERFLY)
+ Store[x][y] = EL_BD_DIAMOND;
else if (center_element == EL_SP_ELECTRON)
Store[x][y] = EL_SP_INFOTRON;
- else if (center_element == EL_MAMPFER)
- Store[x][y] = level.yam_content[game.yam_content_nr][x-ex+1][y-ey+1];
- else if (center_element == EL_AMOEBA2DIAM)
+ else if (center_element == EL_AMOEBA_TO_DIAMOND)
Store[x][y] = level.amoeba_content;
- else if (element == EL_ERZ_EDEL)
- Store[x][y] = EL_EDELSTEIN;
- else if (element == EL_ERZ_DIAM)
- Store[x][y] = EL_DIAMANT;
- else if (element == EL_ERZ_EDEL_BD)
- Store[x][y] = EL_EDELSTEIN_BD;
- else if (element == EL_ERZ_EDEL_GELB)
- Store[x][y] = EL_EDELSTEIN_GELB;
- else if (element == EL_ERZ_EDEL_ROT)
- Store[x][y] = EL_EDELSTEIN_ROT;
- else if (element == EL_ERZ_EDEL_LILA)
- Store[x][y] = EL_EDELSTEIN_LILA;
+ else if (center_element == EL_YAMYAM)
+ Store[x][y] = level.yamyam_content[game.yamyam_content_nr][xx][yy];
+ else if (IS_CUSTOM_ELEMENT(center_element) &&
+ element_info[center_element].content[xx][yy] != EL_EMPTY)
+ Store[x][y] = element_info[center_element].content[xx][yy];
+ else if (element == EL_WALL_EMERALD)
+ Store[x][y] = EL_EMERALD;
+ else if (element == EL_WALL_DIAMOND)
+ Store[x][y] = EL_DIAMOND;
+ else if (element == EL_WALL_BD_DIAMOND)
+ Store[x][y] = EL_BD_DIAMOND;
+ else if (element == EL_WALL_EMERALD_YELLOW)
+ Store[x][y] = EL_EMERALD_YELLOW;
+ else if (element == EL_WALL_EMERALD_RED)
+ Store[x][y] = EL_EMERALD_RED;
+ else if (element == EL_WALL_EMERALD_PURPLE)
+ Store[x][y] = EL_EMERALD_PURPLE;
else if (element == EL_WALL_PEARL)
Store[x][y] = EL_PEARL;
else if (element == EL_WALL_CRYSTAL)
Store[x][y] = EL_CRYSTAL;
- else if (!IS_PFORTE(Store[x][y]))
- Store[x][y] = EL_LEERRAUM;
+ else if (IS_CUSTOM_ELEMENT(element))
+ Store[x][y] = element_info[element].content[1][1];
+ else
+ Store[x][y] = EL_EMPTY;
if (x != ex || y != ey ||
- center_element == EL_AMOEBA2DIAM || mode == EX_BORDER)
+ center_element == EL_AMOEBA_TO_DIAMOND || mode == EX_BORDER)
Store2[x][y] = element;
+#if 0
if (AmoebaNr[x][y] &&
- (element == EL_AMOEBE_VOLL ||
- element == EL_AMOEBE_BD ||
- element == EL_AMOEBING))
+ (element == EL_AMOEBA_FULL ||
+ element == EL_BD_AMOEBA ||
+ element == EL_AMOEBA_GROWING))
{
AmoebaCnt[AmoebaNr[x][y]]--;
AmoebaCnt2[AmoebaNr[x][y]]--;
}
- Feld[x][y] = EL_EXPLODING;
+#if 1
+ RemoveField(x, y);
+#else
MovDir[x][y] = MovPos[x][y] = 0;
AmoebaNr[x][y] = 0;
- Frame[x][y] = 1;
+#endif
+#endif
+
+ Feld[x][y] = EL_EXPLOSION;
+#if 1
+ GfxElement[x][y] = center_element;
+#else
+ GfxElement[x][y] = EL_UNDEFINED;
+#endif
+
+ ExplodePhase[x][y] = 1;
Stop[x][y] = TRUE;
}
- if (center_element == EL_MAMPFER)
- game.yam_content_nr = (game.yam_content_nr + 1) % level.num_yam_contents;
+ if (center_element == EL_YAMYAM)
+ game.yamyam_content_nr =
+ (game.yamyam_content_nr + 1) % level.num_yamyam_contents;
return;
}
x = ex;
y = ey;
- Frame[x][y] = (phase < last_phase ? phase + 1 : 0);
+ ExplodePhase[x][y] = (phase < last_phase ? phase + 1 : 0);
if (phase == first_phase_after_start)
{
if (IS_PLAYER(x, y))
KillHeroUnlessProtected(x, y);
- else if (IS_EXPLOSIVE(element))
+ else if (CAN_EXPLODE_BY_FIRE(element))
{
Feld[x][y] = Store2[x][y];
Store2[x][y] = 0;
Bang(x, y);
}
- else if (element == EL_AMOEBA2DIAM)
+ else if (element == EL_AMOEBA_TO_DIAMOND)
AmoebeUmwandeln(x, y);
}
element = Feld[x][y] = Store[x][y];
Store[x][y] = Store2[x][y] = 0;
- MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = 0;
+ GfxElement[x][y] = EL_UNDEFINED;
+
+ if (Back[x][y] && IS_INDESTRUCTIBLE(Back[x][y]))
+ element = Feld[x][y] = Back[x][y];
+ Back[x][y] = 0;
+
+ MovDir[x][y] = MovPos[x][y] = MovDelay[x][y] = ChangeDelay[x][y] = 0;
InitField(x, y, FALSE);
- if (CAN_MOVE(element) || COULD_MOVE(element))
+ if (CAN_MOVE(element))
InitMovDir(x, y);
DrawLevelField(x, y);
+ if (CAN_BE_CRUMBLED(element))
+ DrawLevelFieldCrumbledSandNeighbours(x, y);
+
if (IS_PLAYER(x, y) && !PLAYERINFO(x,y)->present)
StorePlayer[x][y] = 0;
}
- else if (!(phase % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+ else if (phase >= delay && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
{
- int graphic = GFX_EXPLOSION;
-
- if (game.emulation == EMU_SUPAPLEX)
- graphic = (Store[x][y] == EL_SP_INFOTRON ?
- GFX_SP_EXPLODE_INFOTRON :
- GFX_SP_EXPLODE_EMPTY);
+#if 1
+ int graphic = el_act2img(GfxElement[x][y], ACTION_EXPLODING);
+#else
+ int stored = Store[x][y];
+ int graphic = (game.emulation != EMU_SUPAPLEX ? IMG_EXPLOSION :
+ stored == EL_SP_INFOTRON ? IMG_SP_EXPLOSION_INFOTRON :
+ IMG_SP_EXPLOSION);
+#endif
+ int frame = getGraphicAnimationFrame(graphic, phase - delay);
if (phase == delay)
- ErdreichAnbroeckeln(SCREENX(x), SCREENY(y));
+ DrawLevelFieldCrumbledSand(x, y);
- graphic += (phase / delay - 1);
-
- if (IS_PFORTE(Store[x][y]))
+ if (IS_WALKABLE_OVER(Back[x][y]) && Back[x][y] != EL_EMPTY)
{
- DrawLevelElement(x, y, Store[x][y]);
- DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic);
+ DrawLevelElement(x, y, Back[x][y]);
+ DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic, frame);
}
- else
- DrawGraphic(SCREENX(x), SCREENY(y), graphic);
+ else if (IS_WALKABLE_UNDER(Back[x][y]))
+ {
+ DrawGraphic(SCREENX(x), SCREENY(y), graphic, frame);
+ DrawLevelElementThruMask(x, y, Back[x][y]);
+ }
+ else if (!IS_WALKABLE_INSIDE(Back[x][y]))
+ DrawGraphic(SCREENX(x), SCREENY(y), graphic, frame);
}
}
if (IS_ACTIVE_BOMB(Feld[ex][ey]))
{
- player = &stored_player[Feld[ex][ey] - EL_DYNABOMB_ACTIVE_1];
+ player = &stored_player[Feld[ex][ey] - EL_DYNABOMB_PLAYER_1_ACTIVE];
dynabomb_size = player->dynabomb_size;
dynabomb_xl = player->dynabomb_xl;
player->dynabombs_left++;
int y = ey + j * xy[i % 4][1];
int element;
- if (!IN_LEV_FIELD(x, y) || IS_MASSIVE(Feld[x][y]))
+ if (!IN_LEV_FIELD(x, y) || IS_INDESTRUCTIBLE(Feld[x][y]))
break;
element = Feld[x][y];
/* do not restart explosions of fields with active bombs */
- if (element == EL_EXPLODING && IS_ACTIVE_BOMB(Store2[x][y]))
+ if (element == EL_EXPLOSION && IS_ACTIVE_BOMB(Store2[x][y]))
continue;
Explode(x, y, EX_PHASE_START, EX_BORDER);
- if (element != EL_LEERRAUM &&
- element != EL_ERDREICH &&
- element != EL_EXPLODING &&
+ /* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
+ if (element != EL_EMPTY &&
+ element != EL_SAND &&
+ element != EL_EXPLOSION &&
!dynabomb_xl)
break;
}
void Bang(int x, int y)
{
+#if 1
+ int element = MovingOrBlocked2Element(x, y);
+#else
int element = Feld[x][y];
+#endif
+
+ if (IS_PLAYER(x, y))
+ {
+ struct PlayerInfo *player = PLAYERINFO(x, y);
+
+ element = Feld[x][y] = (player->use_murphy_graphic ? EL_SP_MURPHY :
+ player->element_nr);
+ }
+#if 0
+#if 1
+ PlaySoundLevelAction(x, y, ACTION_EXPLODING);
+#else
if (game.emulation == EMU_SUPAPLEX)
PlaySoundLevel(x, y, SND_SP_ELEMENT_EXPLODING);
else
PlaySoundLevel(x, y, SND_ELEMENT_EXPLODING);
+#endif
+#endif
#if 0
if (IS_PLAYER(x, y)) /* remove objects that might cause smaller explosion */
- element = EL_LEERRAUM;
+ element = EL_EMPTY;
#endif
switch(element)
{
- case EL_KAEFER:
- case EL_FLIEGER:
- case EL_BUTTERFLY:
- case EL_FIREFLY:
- case EL_MAMPFER:
- case EL_MAMPFER2:
+ case EL_BUG:
+ case EL_SPACESHIP:
+ case EL_BD_BUTTERFLY:
+ case EL_BD_FIREFLY:
+ case EL_YAMYAM:
+ case EL_DARK_YAMYAM:
case EL_ROBOT:
case EL_PACMAN:
case EL_MOLE:
RaiseScoreElement(element);
Explode(x, y, EX_PHASE_START, EX_NORMAL);
break;
- case EL_DYNABOMB_ACTIVE_1:
- case EL_DYNABOMB_ACTIVE_2:
- case EL_DYNABOMB_ACTIVE_3:
- case EL_DYNABOMB_ACTIVE_4:
- case EL_DYNABOMB_NR:
- case EL_DYNABOMB_SZ:
- case EL_DYNABOMB_XL:
+ case EL_DYNABOMB_PLAYER_1_ACTIVE:
+ case EL_DYNABOMB_PLAYER_2_ACTIVE:
+ case EL_DYNABOMB_PLAYER_3_ACTIVE:
+ case EL_DYNABOMB_PLAYER_4_ACTIVE:
+ case EL_DYNABOMB_INCREASE_NUMBER:
+ case EL_DYNABOMB_INCREASE_SIZE:
+ case EL_DYNABOMB_INCREASE_POWER:
DynaExplode(x, y);
break;
- case EL_PINGUIN:
- case EL_BIRNE_AUS:
- case EL_BIRNE_EIN:
+ case EL_PENGUIN:
+ case EL_LAMP:
+ case EL_LAMP_ACTIVE:
if (IS_PLAYER(x, y))
Explode(x, y, EX_PHASE_START, EX_NORMAL);
else
Explode(x, y, EX_PHASE_START, EX_NORMAL);
break;
}
+
+ CheckTriggeredElementChange(x, y, element, CE_OTHER_IS_EXPLODING);
}
-void Blurb(int x, int y)
+void SplashAcid(int x, int y)
{
int element = Feld[x][y];
- if (element != EL_BLURB_LEFT && element != EL_BLURB_RIGHT) /* start */
+ if (element != EL_ACID_SPLASH_LEFT &&
+ element != EL_ACID_SPLASH_RIGHT)
{
PlaySoundLevel(x, y, SND_ACID_SPLASHING);
+
if (IN_LEV_FIELD(x-1, y) && IS_FREE(x-1, y) &&
(!IN_LEV_FIELD(x-1, y-1) ||
!CAN_FALL(MovingOrBlocked2Element(x-1, y-1))))
- {
- Feld[x-1][y] = EL_BLURB_LEFT;
- }
+ Feld[x-1][y] = EL_ACID_SPLASH_LEFT;
+
if (IN_LEV_FIELD(x+1, y) && IS_FREE(x+1, y) &&
(!IN_LEV_FIELD(x+1, y-1) ||
!CAN_FALL(MovingOrBlocked2Element(x+1, y-1))))
- {
- Feld[x+1][y] = EL_BLURB_RIGHT;
- }
+ Feld[x+1][y] = EL_ACID_SPLASH_RIGHT;
}
- else /* go on */
+}
+
+static void InitBeltMovement()
+{
+ static int belt_base_element[4] =
+ {
+ EL_CONVEYOR_BELT_1_LEFT,
+ EL_CONVEYOR_BELT_2_LEFT,
+ EL_CONVEYOR_BELT_3_LEFT,
+ EL_CONVEYOR_BELT_4_LEFT
+ };
+ static int belt_base_active_element[4] =
{
- int graphic = (element==EL_BLURB_LEFT ? GFX_BLURB_LEFT : GFX_BLURB_RIGHT);
+ EL_CONVEYOR_BELT_1_LEFT_ACTIVE,
+ EL_CONVEYOR_BELT_2_LEFT_ACTIVE,
+ EL_CONVEYOR_BELT_3_LEFT_ACTIVE,
+ EL_CONVEYOR_BELT_4_LEFT_ACTIVE
+ };
- if (!MovDelay[x][y]) /* initialize animation counter */
- MovDelay[x][y] = 9;
+ int x, y, i, j;
+
+ /* set frame order for belt animation graphic according to belt direction */
+ for (i=0; i<4; i++)
+ {
+ int belt_nr = i;
- if (MovDelay[x][y]) /* continue animation */
+ for (j=0; j<3; j++)
{
- MovDelay[x][y]--;
- if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y), graphic+4-MovDelay[x][y]/2);
+ int element = belt_base_active_element[belt_nr] + j;
+ int graphic = el2img(element);
+
+ if (game.belt_dir[i] == MV_LEFT)
+ graphic_info[graphic].anim_mode &= ~ANIM_REVERSE;
+ else
+ graphic_info[graphic].anim_mode |= ANIM_REVERSE;
+ }
+ }
+
+ for(y=0; y<lev_fieldy; y++)
+ {
+ for(x=0; x<lev_fieldx; x++)
+ {
+ int element = Feld[x][y];
- if (!MovDelay[x][y])
+ for (i=0; i<4; i++)
{
- Feld[x][y] = EL_LEERRAUM;
- DrawLevelField(x, y);
+ if (IS_BELT(element) && game.belt_dir[i] != MV_NO_MOVING)
+ {
+ int e_belt_nr = getBeltNrFromBeltElement(element);
+ int belt_nr = i;
+
+ if (e_belt_nr == belt_nr)
+ {
+ int belt_part = Feld[x][y] - belt_base_element[belt_nr];
+
+ Feld[x][y] = belt_base_active_element[belt_nr] + belt_part;
+ }
+ }
}
}
}
{
static int belt_base_element[4] =
{
- EL_BELT1_SWITCH_LEFT,
- EL_BELT2_SWITCH_LEFT,
- EL_BELT3_SWITCH_LEFT,
- EL_BELT4_SWITCH_LEFT
+ EL_CONVEYOR_BELT_1_LEFT,
+ EL_CONVEYOR_BELT_2_LEFT,
+ EL_CONVEYOR_BELT_3_LEFT,
+ EL_CONVEYOR_BELT_4_LEFT
+ };
+ static int belt_base_active_element[4] =
+ {
+ EL_CONVEYOR_BELT_1_LEFT_ACTIVE,
+ EL_CONVEYOR_BELT_2_LEFT_ACTIVE,
+ EL_CONVEYOR_BELT_3_LEFT_ACTIVE,
+ EL_CONVEYOR_BELT_4_LEFT_ACTIVE
+ };
+ static int belt_base_switch_element[4] =
+ {
+ EL_CONVEYOR_BELT_1_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_2_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_3_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_4_SWITCH_LEFT
};
static int belt_move_dir[4] =
{
};
int element = Feld[x][y];
- int belt_nr = getBeltNrFromSwitchElement(element);
+ int belt_nr = getBeltNrFromBeltSwitchElement(element);
int belt_dir_nr = (game.belt_dir_nr[belt_nr] + 1) % 4;
int belt_dir = belt_move_dir[belt_dir_nr];
- int xx, yy;
+ int xx, yy, i;
if (!IS_BELT_SWITCH(element))
return;
if (belt_dir_nr == 3)
belt_dir_nr = 1;
+ /* set frame order for belt animation graphic according to belt direction */
+ for (i=0; i<3; i++)
+ {
+ int element = belt_base_active_element[belt_nr] + i;
+ int graphic = el2img(element);
+
+ if (belt_dir == MV_LEFT)
+ graphic_info[graphic].anim_mode &= ~ANIM_REVERSE;
+ else
+ graphic_info[graphic].anim_mode |= ANIM_REVERSE;
+ }
+
for (yy=0; yy<lev_fieldy; yy++)
{
for (xx=0; xx<lev_fieldx; xx++)
if (IS_BELT_SWITCH(element))
{
- int e_belt_nr = getBeltNrFromSwitchElement(element);
+ int e_belt_nr = getBeltNrFromBeltSwitchElement(element);
+
+ if (e_belt_nr == belt_nr)
+ {
+ Feld[xx][yy] = belt_base_switch_element[belt_nr] + belt_dir_nr;
+ DrawLevelField(xx, yy);
+ }
+ }
+ else if (IS_BELT(element) && belt_dir != MV_NO_MOVING)
+ {
+ int e_belt_nr = getBeltNrFromBeltElement(element);
if (e_belt_nr == belt_nr)
{
- Feld[xx][yy] = belt_base_element[belt_nr] + belt_dir_nr;
+ int belt_part = Feld[xx][yy] - belt_base_element[belt_nr];
+
+ Feld[xx][yy] = belt_base_active_element[belt_nr] + belt_part;
DrawLevelField(xx, yy);
}
}
- else if (belt_dir == MV_NO_MOVING && IS_BELT(element))
+ else if (IS_BELT_ACTIVE(element) && belt_dir == MV_NO_MOVING)
{
- int e_belt_nr = getBeltNrFromElement(element);
+ int e_belt_nr = getBeltNrFromBeltActiveElement(element);
if (e_belt_nr == belt_nr)
- DrawLevelField(xx, yy); /* set belt to parking position */
+ {
+ int belt_part = Feld[xx][yy] - belt_base_active_element[belt_nr];
+
+ Feld[xx][yy] = belt_base_element[belt_nr] + belt_part;
+ DrawLevelField(xx, yy);
+ }
}
}
}
{
int element = Feld[xx][yy];
- if (element == EL_SWITCHGATE_SWITCH_1 ||
- element == EL_SWITCHGATE_SWITCH_2)
+ if (element == EL_SWITCHGATE_SWITCH_UP ||
+ element == EL_SWITCHGATE_SWITCH_DOWN)
{
- Feld[xx][yy] = EL_SWITCHGATE_SWITCH_1 + game.switchgate_pos;
+ Feld[xx][yy] = EL_SWITCHGATE_SWITCH_UP + game.switchgate_pos;
DrawLevelField(xx, yy);
}
else if (element == EL_SWITCHGATE_OPEN ||
element == EL_SWITCHGATE_OPENING)
{
Feld[xx][yy] = EL_SWITCHGATE_CLOSING;
+#if 1
+ PlaySoundLevelAction(xx, yy, ACTION_CLOSING);
+#else
PlaySoundLevel(xx, yy, SND_SWITCHGATE_CLOSING);
+#endif
}
else if (element == EL_SWITCHGATE_CLOSED ||
element == EL_SWITCHGATE_CLOSING)
{
Feld[xx][yy] = EL_SWITCHGATE_OPENING;
+#if 1
+ PlaySoundLevelAction(xx, yy, ACTION_OPENING);
+#else
PlaySoundLevel(xx, yy, SND_SWITCHGATE_OPENING);
+#endif
}
}
}
}
+static int getInvisibleActiveFromInvisibleElement(int element)
+{
+ return (element == EL_INVISIBLE_STEELWALL ? EL_INVISIBLE_STEELWALL_ACTIVE :
+ element == EL_INVISIBLE_WALL ? EL_INVISIBLE_WALL_ACTIVE :
+ element == EL_INVISIBLE_SAND ? EL_INVISIBLE_SAND_ACTIVE :
+ element);
+}
+
+static int getInvisibleFromInvisibleActiveElement(int element)
+{
+ return (element == EL_INVISIBLE_STEELWALL_ACTIVE ? EL_INVISIBLE_STEELWALL :
+ element == EL_INVISIBLE_WALL_ACTIVE ? EL_INVISIBLE_WALL :
+ element == EL_INVISIBLE_SAND_ACTIVE ? EL_INVISIBLE_SAND :
+ element);
+}
+
static void RedrawAllLightSwitchesAndInvisibleElements()
{
int x, y;
{
int element = Feld[x][y];
- if (element == EL_LIGHT_SWITCH_OFF &&
+ if (element == EL_LIGHT_SWITCH &&
game.light_time_left > 0)
{
- Feld[x][y] = EL_LIGHT_SWITCH_ON;
+ Feld[x][y] = EL_LIGHT_SWITCH_ACTIVE;
DrawLevelField(x, y);
}
- else if (element == EL_LIGHT_SWITCH_ON &&
+ else if (element == EL_LIGHT_SWITCH_ACTIVE &&
game.light_time_left == 0)
{
- Feld[x][y] = EL_LIGHT_SWITCH_OFF;
+ Feld[x][y] = EL_LIGHT_SWITCH;
+ DrawLevelField(x, y);
+ }
+ else if (element == EL_INVISIBLE_STEELWALL ||
+ element == EL_INVISIBLE_WALL ||
+ element == EL_INVISIBLE_SAND)
+ {
+ if (game.light_time_left > 0)
+ Feld[x][y] = getInvisibleActiveFromInvisibleElement(element);
+
DrawLevelField(x, y);
}
+ else if (element == EL_INVISIBLE_STEELWALL_ACTIVE ||
+ element == EL_INVISIBLE_WALL_ACTIVE ||
+ element == EL_INVISIBLE_SAND_ACTIVE)
+ {
+ if (game.light_time_left == 0)
+ Feld[x][y] = getInvisibleFromInvisibleActiveElement(element);
- if (element == EL_INVISIBLE_STEEL ||
- element == EL_UNSICHTBAR ||
- element == EL_SAND_INVISIBLE)
DrawLevelField(x, y);
+ }
}
}
}
int element = Feld[x][y];
game.light_time_left =
- (element == EL_LIGHT_SWITCH_OFF ?
+ (element == EL_LIGHT_SWITCH ?
level.time_light * FRAMES_PER_SECOND : 0);
RedrawAllLightSwitchesAndInvisibleElements();
}
/*
- else if (element == EL_TIMEGATE_SWITCH_ON)
+ else if (element == EL_TIMEGATE_SWITCH_ACTIVE)
{
- Feld[xx][yy] = EL_TIMEGATE_SWITCH_OFF;
+ Feld[xx][yy] = EL_TIMEGATE_SWITCH;
DrawLevelField(xx, yy);
}
*/
}
}
- Feld[x][y] = EL_TIMEGATE_SWITCH_ON;
+ 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 (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;
+ }
+
+ return step;
}
void Impact(int x, int y)
{
boolean lastline = (y == lev_fieldy-1);
boolean object_hit = FALSE;
+ boolean impact = (lastline || object_hit);
int element = Feld[x][y];
- int smashed = 0;
+ int smashed = EL_UNDEFINED;
if (!lastline) /* check if element below was hit */
{
- if (Feld[x][y+1] == EL_PLAYER_IS_LEAVING)
+ if (Feld[x][y + 1] == EL_PLAYER_IS_LEAVING)
return;
- object_hit = (!IS_FREE(x, y+1) && (!IS_MOVING(x, y+1) ||
- MovDir[x][y+1]!=MV_DOWN ||
- MovPos[x][y+1]<=TILEY/2));
+ object_hit = (!IS_FREE(x, y + 1) && (!IS_MOVING(x, y + 1) ||
+ MovDir[x][y + 1] != MV_DOWN ||
+ MovPos[x][y + 1] <= TILEY / 2));
+
+ /* do not smash moving elements that left the smashed field in time */
+ if (game.engine_version >= RELEASE_IDENT(2,2,0,7) && IS_MOVING(x, y + 1) &&
+ ABS(MovPos[x][y + 1] + getElementMoveStepsize(x, y + 1)) >= TILEX)
+ object_hit = FALSE;
+
if (object_hit)
- smashed = MovingOrBlocked2Element(x, y+1);
+ smashed = MovingOrBlocked2Element(x, y + 1);
+
+ impact = (lastline || object_hit);
}
- if (!lastline && smashed == EL_SALZSAEURE) /* element falls into acid */
+ if (!lastline && smashed == EL_ACID) /* element falls into acid */
{
- Blurb(x, y);
+ SplashAcid(x, y);
return;
}
- if ((element == EL_BOMBE ||
- element == EL_SP_DISK_ORANGE ||
- element == EL_DX_SUPABOMB) &&
- (lastline || object_hit)) /* element is bomb */
+ if (impact)
+ {
+ ResetGfxAnimation(x, y);
+ DrawLevelField(x, y);
+ }
+
+ if (impact && CAN_EXPLODE_IMPACT(element))
{
Bang(x, y);
return;
}
- else if (element == EL_PEARL)
+ else if (impact && element == EL_PEARL)
{
Feld[x][y] = EL_PEARL_BREAKING;
PlaySoundLevel(x, y, SND_PEARL_BREAKING);
return;
}
+#if 1
+ else if (impact && CheckElementChange(x, y, element, CE_IMPACT))
+ {
+ PlaySoundLevelElementAction(x, y, element, ACTION_IMPACT);
+
+ return;
+ }
+#else
+ else if (impact && CAN_CHANGE(element) &&
+ HAS_CHANGE_EVENT(element, CE_IMPACT))
+ {
+ PlaySoundLevelElementAction(x, y, element, ACTION_IMPACT);
+
+ ChangeElementNow(x, y, element);
+
+ return;
+ }
+#endif
- if (element == EL_TROPFEN && (lastline || object_hit)) /* acid drop */
+ if (impact && element == EL_AMOEBA_DROP)
{
- if (object_hit && IS_PLAYER(x, y+1))
- KillHeroUnlessProtected(x, y+1);
- else if (object_hit && smashed == EL_PINGUIN)
- Bang(x, y+1);
+ if (object_hit && IS_PLAYER(x, y + 1))
+ KillHeroUnlessProtected(x, y + 1);
+ else if (object_hit && smashed == EL_PENGUIN)
+ Bang(x, y + 1);
else
{
- Feld[x][y] = EL_AMOEBING;
- Store[x][y] = EL_AMOEBE_NASS;
+ Feld[x][y] = EL_AMOEBA_GROWING;
+ Store[x][y] = EL_AMOEBA_WET;
+
+ ResetRandomAnimationValue(x, y);
}
return;
}
- if (!lastline && object_hit) /* check which object was hit */
+ if (object_hit) /* check which object was hit */
{
- if (CAN_CHANGE(element) &&
- (smashed == EL_MAGIC_WALL_OFF || smashed == EL_MAGIC_WALL_BD_OFF))
+ if (CAN_PASS_MAGIC_WALL(element) &&
+ (smashed == EL_MAGIC_WALL ||
+ smashed == EL_BD_MAGIC_WALL))
{
int xx, yy;
int activated_magic_wall =
- (smashed == EL_MAGIC_WALL_OFF ? EL_MAGIC_WALL_EMPTY :
- EL_MAGIC_WALL_BD_EMPTY);
+ (smashed == EL_MAGIC_WALL ? EL_MAGIC_WALL_ACTIVE :
+ EL_BD_MAGIC_WALL_ACTIVE);
/* activate magic wall / mill */
for (yy=0; yy<lev_fieldy; yy++)
game.magic_wall_time_left = level.time_magic_wall * FRAMES_PER_SECOND;
game.magic_wall_active = TRUE;
- PlaySoundLevel(x, y, (smashed == EL_MAGIC_WALL_OFF ?
+ PlaySoundLevel(x, y, (smashed == EL_MAGIC_WALL ?
SND_MAGIC_WALL_ACTIVATING :
SND_BD_MAGIC_WALL_ACTIVATING));
}
- if (IS_PLAYER(x, y+1))
+ if (IS_PLAYER(x, y + 1))
{
- KillHeroUnlessProtected(x, y+1);
- return;
+ if (CAN_SMASH_PLAYER(element))
+ {
+ KillHeroUnlessProtected(x, y + 1);
+ return;
+ }
}
- else if (smashed == EL_PINGUIN)
+ else if (smashed == EL_PENGUIN)
{
- Bang(x, y+1);
- return;
+ if (CAN_SMASH_PLAYER(element))
+ {
+ Bang(x, y + 1);
+ return;
+ }
}
- else if (element == EL_EDELSTEIN_BD)
+ else if (element == EL_BD_DIAMOND)
{
- if (IS_ENEMY(smashed) && IS_BD_ELEMENT(smashed))
+ if (IS_CLASSIC_ENEMY(smashed) && IS_BD_ELEMENT(smashed))
{
- Bang(x, y+1);
+ Bang(x, y + 1);
return;
}
}
- else if ((element == EL_SP_INFOTRON || element == EL_SP_ZONK) &&
- (smashed == EL_SP_SNIKSNAK || smashed == EL_SP_ELECTRON ||
+ else if ((element == EL_SP_INFOTRON ||
+ element == EL_SP_ZONK) &&
+ (smashed == EL_SP_SNIKSNAK ||
+ smashed == EL_SP_ELECTRON ||
smashed == EL_SP_DISK_ORANGE))
{
- Bang(x, y+1);
+ Bang(x, y + 1);
return;
}
- else if (element == EL_FELSBROCKEN ||
- element == EL_SP_ZONK ||
- element == EL_BD_ROCK)
+#if 0
+ else if (CAN_SMASH_ENEMIES(element) && IS_CLASSIC_ENEMY(smashed))
+ {
+ Bang(x, y + 1);
+ return;
+ }
+#endif
+ else if (CAN_SMASH_EVERYTHING(element))
{
- if (IS_ENEMY(smashed) ||
- smashed == EL_BOMBE || smashed == EL_SP_DISK_ORANGE ||
- smashed == EL_DX_SUPABOMB ||
- smashed == EL_SONDE || smashed == EL_SCHWEIN ||
- smashed == EL_DRACHE || smashed == EL_MOLE)
+ if (IS_CLASSIC_ENEMY(smashed) ||
+ CAN_EXPLODE_SMASHED(smashed))
{
- Bang(x, y+1);
+ Bang(x, y + 1);
return;
}
- else if (!IS_MOVING(x, y+1))
+ else if (!IS_MOVING(x, y + 1) && !IS_BLOCKED(x, y + 1))
{
- if (smashed == EL_BIRNE_AUS || smashed == EL_BIRNE_EIN)
+ if (smashed == EL_LAMP ||
+ smashed == EL_LAMP_ACTIVE)
{
- Bang(x, y+1);
+ Bang(x, y + 1);
return;
}
- else if (smashed == EL_KOKOSNUSS)
+ else if (smashed == EL_NUT)
{
- Feld[x][y+1] = EL_CRACKINGNUT;
- PlaySoundLevel(x, y, SND_NUT_CRACKING);
- RaiseScoreElement(EL_KOKOSNUSS);
+ Feld[x][y + 1] = EL_NUT_BREAKING;
+ PlaySoundLevel(x, y, SND_NUT_BREAKING);
+ RaiseScoreElement(EL_NUT);
return;
}
else if (smashed == EL_PEARL)
{
- Feld[x][y+1] = EL_PEARL_BREAKING;
+ Feld[x][y + 1] = EL_PEARL_BREAKING;
PlaySoundLevel(x, y, SND_PEARL_BREAKING);
return;
}
- else if (smashed == EL_DIAMANT)
+ else if (smashed == EL_DIAMOND)
{
- Feld[x][y+1] = EL_LEERRAUM;
+ Feld[x][y + 1] = EL_DIAMOND_BREAKING;
PlaySoundLevel(x, y, SND_DIAMOND_BREAKING);
return;
}
else if (IS_BELT_SWITCH(smashed))
{
- ToggleBeltSwitch(x, y+1);
+ ToggleBeltSwitch(x, y + 1);
+ }
+ else if (smashed == EL_SWITCHGATE_SWITCH_UP ||
+ smashed == EL_SWITCHGATE_SWITCH_DOWN)
+ {
+ ToggleSwitchgateSwitch(x, y + 1);
+ }
+ else if (smashed == EL_LIGHT_SWITCH ||
+ smashed == EL_LIGHT_SWITCH_ACTIVE)
+ {
+ ToggleLightSwitch(x, y + 1);
}
- else if (smashed == EL_SWITCHGATE_SWITCH_1 ||
- smashed == EL_SWITCHGATE_SWITCH_2)
+#if 1
+ else
{
- ToggleSwitchgateSwitch(x, y+1);
+ CheckElementChange(x, y + 1, smashed, CE_SMASHED);
}
- else if (smashed == EL_LIGHT_SWITCH_OFF ||
- smashed == EL_LIGHT_SWITCH_ON)
+#else
+ else if (CAN_CHANGE(smashed) && HAS_CHANGE_EVENT(smashed, CE_SMASHED))
{
- ToggleLightSwitch(x, y+1);
+ ChangeElementNow(x, y + 1, smashed);
}
+#endif
+ }
+ else
+ {
+ CheckElementChange(x, y + 1, smashed, CE_SMASHED);
}
}
}
/* play sound of magic wall / mill */
if (!lastline &&
- (Feld[x][y+1] == EL_MAGIC_WALL_EMPTY ||
- Feld[x][y+1] == EL_MAGIC_WALL_BD_EMPTY))
+ (Feld[x][y + 1] == EL_MAGIC_WALL_ACTIVE ||
+ Feld[x][y + 1] == EL_BD_MAGIC_WALL_ACTIVE))
{
- if (Feld[x][y+1] == EL_MAGIC_WALL_EMPTY)
- PlaySoundLevel(x, y, SND_MAGIC_WALL_CHANGING);
- else if (Feld[x][y+1] == EL_MAGIC_WALL_BD_EMPTY)
- PlaySoundLevel(x, y, SND_BD_MAGIC_WALL_CHANGING);
+ if (Feld[x][y + 1] == EL_MAGIC_WALL_ACTIVE)
+ PlaySoundLevel(x, y, SND_MAGIC_WALL_FILLING);
+ else if (Feld[x][y + 1] == EL_BD_MAGIC_WALL_ACTIVE)
+ PlaySoundLevel(x, y, SND_BD_MAGIC_WALL_FILLING);
return;
}
/* play sound of object that hits the ground */
if (lastline || object_hit)
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_IMPACT);
+ PlaySoundLevelElementAction(x, y, element, ACTION_IMPACT);
}
void TurnRound(int x, int y)
int x, y;
} move_xy[] =
{
- { 0, 0 },
- {-1, 0 },
- {+1, 0 },
- { 0, 0 },
- { 0, -1 },
- { 0, 0 }, { 0, 0 }, { 0, 0 },
- { 0, +1 }
+ { 0, 0 },
+ { -1, 0 },
+ { +1, 0 },
+ { 0, 0 },
+ { 0, -1 },
+ { 0, 0 }, { 0, 0 }, { 0, 0 },
+ { 0, +1 }
};
static struct
{
int left, right, back;
} turn[] =
{
- { 0, 0, 0 },
+ { 0, 0, 0 },
{ MV_DOWN, MV_UP, MV_RIGHT },
- { MV_UP, MV_DOWN, MV_LEFT },
- { 0, 0, 0 },
- { MV_LEFT, MV_RIGHT, MV_DOWN },
- { 0,0,0 }, { 0,0,0 }, { 0,0,0 },
- { MV_RIGHT, MV_LEFT, MV_UP }
+ { MV_UP, MV_DOWN, MV_LEFT },
+ { 0, 0, 0 },
+ { MV_LEFT, MV_RIGHT, MV_DOWN },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { MV_RIGHT, MV_LEFT, MV_UP }
};
int element = Feld[x][y];
int old_move_dir = MovDir[x][y];
- int left_dir = turn[old_move_dir].left;
+ int left_dir = turn[old_move_dir].left;
int right_dir = turn[old_move_dir].right;
- int back_dir = turn[old_move_dir].back;
+ int back_dir = turn[old_move_dir].back;
- int left_dx = move_xy[left_dir].x, left_dy = move_xy[left_dir].y;
- int right_dx = move_xy[right_dir].x, right_dy = move_xy[right_dir].y;
- int move_dx = move_xy[old_move_dir].x, move_dy = move_xy[old_move_dir].y;
- int back_dx = move_xy[back_dir].x, back_dy = move_xy[back_dir].y;
+ int left_dx = move_xy[left_dir].x, left_dy = move_xy[left_dir].y;
+ int right_dx = move_xy[right_dir].x, right_dy = move_xy[right_dir].y;
+ int move_dx = move_xy[old_move_dir].x, move_dy = move_xy[old_move_dir].y;
+ int back_dx = move_xy[back_dir].x, back_dy = move_xy[back_dir].y;
- int left_x = x+left_dx, left_y = y+left_dy;
- int right_x = x+right_dx, right_y = y+right_dy;
- int move_x = x+move_dx, move_y = y+move_dy;
+ int left_x = x + left_dx, left_y = y + left_dy;
+ int right_x = x + right_dx, right_y = y + right_dy;
+ int move_x = x + move_dx, move_y = y + move_dy;
- if (element == EL_KAEFER || element == EL_BUTTERFLY)
+ int xx, yy;
+
+ if (element == EL_BUG || element == EL_BD_BUTTERFLY)
{
TestIfBadThingTouchesOtherBadThing(x, y);
- if (IN_LEV_FIELD(right_x, right_y) &&
- IS_FREE(right_x, right_y))
+ if (ENEMY_CAN_ENTER_FIELD(right_x, right_y))
MovDir[x][y] = right_dir;
- else if (!IN_LEV_FIELD(move_x, move_y) ||
- !IS_FREE(move_x, move_y))
+ else if (!ENEMY_CAN_ENTER_FIELD(move_x, move_y))
MovDir[x][y] = left_dir;
- if (element == EL_KAEFER && MovDir[x][y] != old_move_dir)
+ if (element == EL_BUG && MovDir[x][y] != old_move_dir)
MovDelay[x][y] = 9;
- else if (element == EL_BUTTERFLY) /* && MovDir[x][y] == left_dir) */
+ else if (element == EL_BD_BUTTERFLY) /* && MovDir[x][y] == left_dir) */
MovDelay[x][y] = 1;
}
- else if (element == EL_FLIEGER || element == EL_FIREFLY ||
+ else if (element == EL_SPACESHIP || element == EL_BD_FIREFLY ||
element == EL_SP_SNIKSNAK || element == EL_SP_ELECTRON)
{
TestIfBadThingTouchesOtherBadThing(x, y);
- if (IN_LEV_FIELD(left_x, left_y) &&
- IS_FREE(left_x, left_y))
+ if (ENEMY_CAN_ENTER_FIELD(left_x, left_y))
MovDir[x][y] = left_dir;
- else if (!IN_LEV_FIELD(move_x, move_y) ||
- !IS_FREE(move_x, move_y))
+ else if (!ENEMY_CAN_ENTER_FIELD(move_x, move_y))
MovDir[x][y] = right_dir;
- if ((element == EL_FLIEGER ||
- element == EL_SP_SNIKSNAK || element == EL_SP_ELECTRON)
+ if ((element == EL_SPACESHIP ||
+ element == EL_SP_SNIKSNAK ||
+ element == EL_SP_ELECTRON)
&& MovDir[x][y] != old_move_dir)
MovDelay[x][y] = 9;
- else if (element == EL_FIREFLY) /* && MovDir[x][y] == right_dir) */
+ else if (element == EL_BD_FIREFLY) /* && MovDir[x][y] == right_dir) */
MovDelay[x][y] = 1;
}
- else if (element == EL_MAMPFER)
+ else if (element == EL_YAMYAM)
{
- boolean can_turn_left = FALSE, can_turn_right = FALSE;
-
- if (IN_LEV_FIELD(left_x, left_y) &&
- (IS_FREE_OR_PLAYER(left_x, left_y) ||
- Feld[left_x][left_y] == EL_DIAMANT))
- can_turn_left = TRUE;
- if (IN_LEV_FIELD(right_x, right_y) &&
- (IS_FREE_OR_PLAYER(right_x, right_y) ||
- Feld[right_x][right_y] == EL_DIAMANT))
- can_turn_right = TRUE;
+ boolean can_turn_left = YAMYAM_CAN_ENTER_FIELD(left_x, left_y);
+ boolean can_turn_right = YAMYAM_CAN_ENTER_FIELD(right_x, right_y);
if (can_turn_left && can_turn_right)
MovDir[x][y] = (RND(3) ? (RND(2) ? left_dir : right_dir) : back_dir);
else
MovDir[x][y] = back_dir;
- MovDelay[x][y] = 16+16*RND(3);
+ MovDelay[x][y] = 16 + 16 * RND(3);
}
- else if (element == EL_MAMPFER2)
+ else if (element == EL_DARK_YAMYAM)
{
- boolean can_turn_left = FALSE, can_turn_right = FALSE;
-
- if (IN_LEV_FIELD(left_x, left_y) &&
- (IS_FREE_OR_PLAYER(left_x, left_y) ||
- IS_MAMPF2(Feld[left_x][left_y])))
- can_turn_left = TRUE;
- if (IN_LEV_FIELD(right_x, right_y) &&
- (IS_FREE_OR_PLAYER(right_x, right_y) ||
- IS_MAMPF2(Feld[right_x][right_y])))
- can_turn_right = TRUE;
+ boolean can_turn_left = DARK_YAMYAM_CAN_ENTER_FIELD(left_x, left_y);
+ boolean can_turn_right = DARK_YAMYAM_CAN_ENTER_FIELD(right_x, right_y);
if (can_turn_left && can_turn_right)
MovDir[x][y] = (RND(3) ? (RND(2) ? left_dir : right_dir) : back_dir);
else
MovDir[x][y] = back_dir;
- MovDelay[x][y] = 16+16*RND(3);
+ MovDelay[x][y] = 16 + 16 * RND(3);
}
else if (element == EL_PACMAN)
{
- boolean can_turn_left = FALSE, can_turn_right = FALSE;
-
- if (IN_LEV_FIELD(left_x, left_y) &&
- (IS_FREE_OR_PLAYER(left_x, left_y) ||
- IS_AMOEBOID(Feld[left_x][left_y])))
- can_turn_left = TRUE;
- if (IN_LEV_FIELD(right_x, right_y) &&
- (IS_FREE_OR_PLAYER(right_x, right_y) ||
- IS_AMOEBOID(Feld[right_x][right_y])))
- can_turn_right = TRUE;
+ boolean can_turn_left = PACMAN_CAN_ENTER_FIELD(left_x, left_y);
+ boolean can_turn_right = PACMAN_CAN_ENTER_FIELD(right_x, right_y);
if (can_turn_left && can_turn_right)
MovDir[x][y] = (RND(3) ? (RND(2) ? left_dir : right_dir) : back_dir);
else
MovDir[x][y] = back_dir;
- MovDelay[x][y] = 6+RND(40);
+ MovDelay[x][y] = 6 + RND(40);
}
- else if (element == EL_SCHWEIN)
+ else if (element == EL_PIG)
{
- boolean can_turn_left = FALSE, can_turn_right = FALSE, can_move_on = FALSE;
- boolean should_turn_left = FALSE, should_turn_right = FALSE;
- boolean should_move_on = FALSE;
+ boolean can_turn_left = PIG_CAN_ENTER_FIELD(left_x, left_y);
+ boolean can_turn_right = PIG_CAN_ENTER_FIELD(right_x, right_y);
+ boolean can_move_on = PIG_CAN_ENTER_FIELD(move_x, move_y);
+ boolean should_turn_left, should_turn_right, should_move_on;
int rnd_value = 24;
int rnd = RND(rnd_value);
- if (IN_LEV_FIELD(left_x, left_y) &&
- (IS_FREE(left_x, left_y) || IS_GEM(Feld[left_x][left_y])))
- can_turn_left = TRUE;
- if (IN_LEV_FIELD(right_x, right_y) &&
- (IS_FREE(right_x, right_y) || IS_GEM(Feld[right_x][right_y])))
- can_turn_right = TRUE;
- if (IN_LEV_FIELD(move_x, move_y) &&
- (IS_FREE(move_x, move_y) || IS_GEM(Feld[move_x][move_y])))
- can_move_on = TRUE;
-
- if (can_turn_left &&
- (!can_move_on ||
- (IN_LEV_FIELD(x+back_dx+left_dx, y+back_dy+left_dy) &&
- !IS_FREE(x+back_dx+left_dx, y+back_dy+left_dy))))
- should_turn_left = TRUE;
- if (can_turn_right &&
- (!can_move_on ||
- (IN_LEV_FIELD(x+back_dx+right_dx, y+back_dy+right_dy) &&
- !IS_FREE(x+back_dx+right_dx, y+back_dy+right_dy))))
- should_turn_right = TRUE;
- if (can_move_on &&
- (!can_turn_left || !can_turn_right ||
- (IN_LEV_FIELD(x+move_dx+left_dx, y+move_dy+left_dy) &&
- !IS_FREE(x+move_dx+left_dx, y+move_dy+left_dy)) ||
- (IN_LEV_FIELD(x+move_dx+right_dx, y+move_dy+right_dy) &&
- !IS_FREE(x+move_dx+right_dx, y+move_dy+right_dy))))
- should_move_on = TRUE;
+ should_turn_left = (can_turn_left &&
+ (!can_move_on ||
+ IN_LEV_FIELD_AND_NOT_FREE(x + back_dx + left_dx,
+ y + back_dy + left_dy)));
+ should_turn_right = (can_turn_right &&
+ (!can_move_on ||
+ IN_LEV_FIELD_AND_NOT_FREE(x + back_dx + right_dx,
+ y + back_dy + right_dy)));
+ should_move_on = (can_move_on &&
+ (!can_turn_left ||
+ !can_turn_right ||
+ IN_LEV_FIELD_AND_NOT_FREE(x + move_dx + left_dx,
+ y + move_dy + left_dy) ||
+ IN_LEV_FIELD_AND_NOT_FREE(x + move_dx + right_dx,
+ y + move_dy + right_dy)));
if (should_turn_left || should_turn_right || should_move_on)
{
if (should_turn_left && should_turn_right && should_move_on)
- MovDir[x][y] = (rnd < rnd_value/3 ? left_dir :
- rnd < 2*rnd_value/3 ? right_dir :
+ MovDir[x][y] = (rnd < rnd_value / 3 ? left_dir :
+ rnd < 2 * rnd_value / 3 ? right_dir :
old_move_dir);
else if (should_turn_left && should_turn_right)
- MovDir[x][y] = (rnd < rnd_value/2 ? left_dir : right_dir);
+ MovDir[x][y] = (rnd < rnd_value / 2 ? left_dir : right_dir);
else if (should_turn_left && should_move_on)
- MovDir[x][y] = (rnd < rnd_value/2 ? left_dir : old_move_dir);
+ MovDir[x][y] = (rnd < rnd_value / 2 ? left_dir : old_move_dir);
else if (should_turn_right && should_move_on)
- MovDir[x][y] = (rnd < rnd_value/2 ? right_dir : old_move_dir);
+ MovDir[x][y] = (rnd < rnd_value / 2 ? right_dir : old_move_dir);
else if (should_turn_left)
MovDir[x][y] = left_dir;
else if (should_turn_right)
else if (should_move_on)
MovDir[x][y] = old_move_dir;
}
- else if (can_move_on && rnd > rnd_value/8)
+ else if (can_move_on && rnd > rnd_value / 8)
MovDir[x][y] = old_move_dir;
else if (can_turn_left && can_turn_right)
- MovDir[x][y] = (rnd < rnd_value/2 ? left_dir : right_dir);
- else if (can_turn_left && rnd > rnd_value/8)
+ MovDir[x][y] = (rnd < rnd_value / 2 ? left_dir : right_dir);
+ else if (can_turn_left && rnd > rnd_value / 8)
MovDir[x][y] = left_dir;
else if (can_turn_right && rnd > rnd_value/8)
MovDir[x][y] = right_dir;
else
MovDir[x][y] = back_dir;
- if (!IS_FREE(x+move_xy[MovDir[x][y]].x, y+move_xy[MovDir[x][y]].y) &&
- !IS_GEM(Feld[x+move_xy[MovDir[x][y]].x][y+move_xy[MovDir[x][y]].y]))
+ xx = x + move_xy[MovDir[x][y]].x;
+ yy = y + move_xy[MovDir[x][y]].y;
+
+ if (!IS_FREE(xx, yy) && !IS_FOOD_PIG(Feld[xx][yy]))
MovDir[x][y] = old_move_dir;
MovDelay[x][y] = 0;
}
- else if (element == EL_DRACHE)
+ else if (element == EL_DRAGON)
{
- boolean can_turn_left = FALSE, can_turn_right = FALSE, can_move_on = FALSE;
+ boolean can_turn_left = IN_LEV_FIELD_AND_IS_FREE(left_x, left_y);
+ boolean can_turn_right = IN_LEV_FIELD_AND_IS_FREE(right_x, right_y);
+ boolean can_move_on = IN_LEV_FIELD_AND_IS_FREE(move_x, move_y);
int rnd_value = 24;
int rnd = RND(rnd_value);
- if (IN_LEV_FIELD(left_x, left_y) && IS_FREE(left_x, left_y))
- can_turn_left = TRUE;
- if (IN_LEV_FIELD(right_x, right_y) && IS_FREE(right_x, right_y))
- can_turn_right = TRUE;
- if (IN_LEV_FIELD(move_x, move_y) && IS_FREE(move_x, move_y))
- can_move_on = TRUE;
-
- if (can_move_on && rnd > rnd_value/8)
+ if (can_move_on && rnd > rnd_value / 8)
MovDir[x][y] = old_move_dir;
else if (can_turn_left && can_turn_right)
- MovDir[x][y] = (rnd < rnd_value/2 ? left_dir : right_dir);
- else if (can_turn_left && rnd > rnd_value/8)
+ MovDir[x][y] = (rnd < rnd_value / 2 ? left_dir : right_dir);
+ else if (can_turn_left && rnd > rnd_value / 8)
MovDir[x][y] = left_dir;
- else if (can_turn_right && rnd > rnd_value/8)
+ else if (can_turn_right && rnd > rnd_value / 8)
MovDir[x][y] = right_dir;
else
MovDir[x][y] = back_dir;
- if (!IS_FREE(x+move_xy[MovDir[x][y]].x, y+move_xy[MovDir[x][y]].y))
+ xx = x + move_xy[MovDir[x][y]].x;
+ yy = y + move_xy[MovDir[x][y]].y;
+
+ if (!IS_FREE(xx, yy))
MovDir[x][y] = old_move_dir;
MovDelay[x][y] = 0;
}
else if (element == EL_MOLE)
{
- boolean can_turn_left = FALSE, can_turn_right = FALSE, can_move_on = FALSE;
-
- if (IN_LEV_FIELD(move_x, move_y) &&
- (IS_FREE(move_x, move_y) || IS_AMOEBOID(Feld[move_x][move_y]) ||
- Feld[move_x][move_y] == EL_DEAMOEBING))
- can_move_on = TRUE;
-
+ boolean can_move_on =
+ (MOLE_CAN_ENTER_FIELD(move_x, move_y,
+ IS_AMOEBOID(Feld[move_x][move_y]) ||
+ Feld[move_x][move_y] == EL_AMOEBA_SHRINKING));
if (!can_move_on)
{
- if (IN_LEV_FIELD(left_x, left_y) &&
- (IS_FREE(left_x, left_y) || IS_AMOEBOID(Feld[left_x][left_y])))
- can_turn_left = TRUE;
- if (IN_LEV_FIELD(right_x, right_y) &&
- (IS_FREE(right_x, right_y) || IS_AMOEBOID(Feld[right_x][right_y])))
- can_turn_right = TRUE;
+ boolean can_turn_left =
+ (MOLE_CAN_ENTER_FIELD(left_x, left_y,
+ IS_AMOEBOID(Feld[left_x][left_y])));
+
+ boolean can_turn_right =
+ (MOLE_CAN_ENTER_FIELD(right_x, right_y,
+ IS_AMOEBOID(Feld[right_x][right_y])));
if (can_turn_left && can_turn_right)
MovDir[x][y] = (RND(2) ? left_dir : right_dir);
MovDir[x][y] = game.balloon_dir;
MovDelay[x][y] = 0;
}
- else if (element == EL_SPRING_MOVING)
+ else if (element == EL_SPRING)
{
- if (!IN_LEV_FIELD(move_x, move_y) || !IS_FREE(move_x, move_y) ||
- (IN_LEV_FIELD(x, y+1) && IS_FREE(x, y+1)))
- {
- Feld[x][y] = EL_SPRING;
+ if (MovDir[x][y] & MV_HORIZONTAL &&
+ (!IN_LEV_FIELD_AND_IS_FREE(move_x, move_y) ||
+ IN_LEV_FIELD_AND_IS_FREE(x, y + 1)))
MovDir[x][y] = MV_NO_MOVING;
- }
+
MovDelay[x][y] = 0;
}
- else if (element == EL_ROBOT || element == EL_SONDE || element == EL_PINGUIN)
+ else if (element == EL_ROBOT ||
+ element == EL_SATELLITE ||
+ element == EL_PENGUIN)
{
int attr_x = -1, attr_y = -1;
if (!player->active)
continue;
- if (attr_x == -1 || ABS(jx-x)+ABS(jy-y) < ABS(attr_x-x)+ABS(attr_y-y))
+ if (attr_x == -1 ||
+ ABS(jx - x) + ABS(jy - y) < ABS(attr_x - x) + ABS(attr_y - y))
{
attr_x = jx;
attr_y = jy;
}
}
- if (element == EL_ROBOT && ZX>=0 && ZY>=0)
+ if (element == EL_ROBOT && ZX >= 0 && ZY >= 0)
{
attr_x = ZX;
attr_y = ZY;
}
- if (element == EL_PINGUIN)
+ if (element == EL_PENGUIN)
{
int i;
static int xy[4][2] =
for (i=0; i<4; i++)
{
- int ex = x + xy[i%4][0];
- int ey = y + xy[i%4][1];
+ int ex = x + xy[i % 4][0];
+ int ey = y + xy[i % 4][1];
- if (IN_LEV_FIELD(ex, ey) && Feld[ex][ey] == EL_AUSGANG_AUF)
+ if (IN_LEV_FIELD(ex, ey) && Feld[ex][ey] == EL_EXIT_OPEN)
{
attr_x = ex;
attr_y = ey;
}
MovDir[x][y] = MV_NO_MOVING;
- if (attr_x<x)
+ if (attr_x < x)
MovDir[x][y] |= (AllPlayersGone ? MV_RIGHT : MV_LEFT);
- else if (attr_x>x)
+ else if (attr_x > x)
MovDir[x][y] |= (AllPlayersGone ? MV_LEFT : MV_RIGHT);
- if (attr_y<y)
+ if (attr_y < y)
MovDir[x][y] |= (AllPlayersGone ? MV_DOWN : MV_UP);
- else if (attr_y>y)
+ else if (attr_y > y)
MovDir[x][y] |= (AllPlayersGone ? MV_UP : MV_DOWN);
if (element == EL_ROBOT)
{
int newx, newy;
- if ((MovDir[x][y]&(MV_LEFT|MV_RIGHT)) && (MovDir[x][y]&(MV_UP|MV_DOWN)))
- MovDir[x][y] &= (RND(2) ? (MV_LEFT|MV_RIGHT) : (MV_UP|MV_DOWN));
+ if (MovDir[x][y] & MV_HORIZONTAL && MovDir[x][y] & MV_VERTICAL)
+ MovDir[x][y] &= (RND(2) ? MV_HORIZONTAL : MV_VERTICAL);
Moving2Blocked(x, y, &newx, &newy);
if (IN_LEV_FIELD(newx, newy) && IS_FREE_OR_PLAYER(newx, newy))
- MovDelay[x][y] = 8+8*!RND(3);
+ MovDelay[x][y] = 8 + 8 * !RND(3);
else
MovDelay[x][y] = 16;
}
- else
+ else if (element == EL_PENGUIN)
{
int newx, newy;
MovDelay[x][y] = 1;
- if ((MovDir[x][y]&(MV_LEFT|MV_RIGHT)) && (MovDir[x][y]&(MV_UP|MV_DOWN)))
+ if (MovDir[x][y] & MV_HORIZONTAL && MovDir[x][y] & MV_VERTICAL)
{
boolean first_horiz = RND(2);
int new_move_dir = MovDir[x][y];
MovDir[x][y] =
- new_move_dir & (first_horiz ? (MV_LEFT|MV_RIGHT) : (MV_UP|MV_DOWN));
+ new_move_dir & (first_horiz ? MV_HORIZONTAL : MV_VERTICAL);
Moving2Blocked(x, y, &newx, &newy);
- if (IN_LEV_FIELD(newx, newy) &&
- (IS_FREE(newx, newy) ||
- Feld[newx][newy] == EL_SALZSAEURE ||
- (element == EL_PINGUIN &&
- (Feld[newx][newy] == EL_AUSGANG_AUF ||
- IS_MAMPF3(Feld[newx][newy])))))
+ if (PENGUIN_CAN_ENTER_FIELD(newx, newy))
return;
MovDir[x][y] =
- new_move_dir & (!first_horiz ? (MV_LEFT|MV_RIGHT) : (MV_UP|MV_DOWN));
+ new_move_dir & (!first_horiz ? MV_HORIZONTAL : MV_VERTICAL);
Moving2Blocked(x, y, &newx, &newy);
- if (IN_LEV_FIELD(newx, newy) &&
- (IS_FREE(newx, newy) ||
- Feld[newx][newy] == EL_SALZSAEURE ||
- (element == EL_PINGUIN &&
- (Feld[newx][newy] == EL_AUSGANG_AUF ||
- IS_MAMPF3(Feld[newx][newy])))))
+ if (PENGUIN_CAN_ENTER_FIELD(newx, newy))
return;
MovDir[x][y] = old_move_dir;
return;
}
}
- }
-}
-
-static boolean JustBeingPushed(int x, int y)
-{
- int i;
+ else /* (element == EL_SATELLITE) */
+ {
+ int newx, newy;
- for (i=0; i<MAX_PLAYERS; i++)
- {
- struct PlayerInfo *player = &stored_player[i];
+ MovDelay[x][y] = 1;
+
+ if (MovDir[x][y] & MV_HORIZONTAL && MovDir[x][y] & MV_VERTICAL)
+ {
+ boolean first_horiz = RND(2);
+ int new_move_dir = MovDir[x][y];
+
+ MovDir[x][y] =
+ new_move_dir & (first_horiz ? MV_HORIZONTAL : MV_VERTICAL);
+ Moving2Blocked(x, y, &newx, &newy);
+
+ if (ELEMENT_CAN_ENTER_FIELD_OR_ACID_2(newx, newy))
+ return;
+
+ MovDir[x][y] =
+ new_move_dir & (!first_horiz ? MV_HORIZONTAL : MV_VERTICAL);
+ Moving2Blocked(x, y, &newx, &newy);
+
+ if (ELEMENT_CAN_ENTER_FIELD_OR_ACID_2(newx, newy))
+ return;
+
+ MovDir[x][y] = old_move_dir;
+ return;
+ }
+ }
+ }
+ else if (element_info[element].move_pattern == MV_ALL_DIRECTIONS ||
+ element_info[element].move_pattern == MV_TURNING_LEFT ||
+ element_info[element].move_pattern == MV_TURNING_RIGHT)
+ {
+ boolean can_turn_left = ELEMENT_CAN_ENTER_FIELD(element, left_x, left_y);
+ boolean can_turn_right = ELEMENT_CAN_ENTER_FIELD(element, right_x,right_y);
+
+ if (element_info[element].move_pattern == MV_TURNING_LEFT)
+ MovDir[x][y] = left_dir;
+ else if (element_info[element].move_pattern == MV_TURNING_RIGHT)
+ MovDir[x][y] = right_dir;
+ else if (can_turn_left && can_turn_right)
+ MovDir[x][y] = (RND(3) ? (RND(2) ? left_dir : right_dir) : back_dir);
+ else if (can_turn_left)
+ MovDir[x][y] = (RND(2) ? left_dir : back_dir);
+ else if (can_turn_right)
+ MovDir[x][y] = (RND(2) ? right_dir : back_dir);
+ else
+ MovDir[x][y] = back_dir;
+
+ MovDelay[x][y] = GET_NEW_MOVE_DELAY(element);
+ }
+ else if (element_info[element].move_pattern == MV_HORIZONTAL ||
+ element_info[element].move_pattern == MV_VERTICAL)
+ {
+ if (element_info[element].move_pattern & old_move_dir)
+ MovDir[x][y] = back_dir;
+ else if (element_info[element].move_pattern == MV_HORIZONTAL)
+ MovDir[x][y] = (RND(2) ? MV_LEFT : MV_RIGHT);
+ else if (element_info[element].move_pattern == MV_VERTICAL)
+ MovDir[x][y] = (RND(2) ? MV_UP : MV_DOWN);
+
+ MovDelay[x][y] = GET_NEW_MOVE_DELAY(element);
+ }
+ else if (element_info[element].move_pattern & MV_ANY_DIRECTION)
+ {
+ MovDir[x][y] = element_info[element].move_pattern;
+ MovDelay[x][y] = GET_NEW_MOVE_DELAY(element);
+ }
+ else if (element_info[element].move_pattern == MV_ALONG_LEFT_SIDE)
+ {
+ if (ELEMENT_CAN_ENTER_FIELD(element, left_x, left_y))
+ MovDir[x][y] = left_dir;
+ else if (!ELEMENT_CAN_ENTER_FIELD(element, move_x, move_y))
+ MovDir[x][y] = right_dir;
+
+ if (MovDir[x][y] != old_move_dir)
+ MovDelay[x][y] = GET_NEW_MOVE_DELAY(element);
+ }
+ else if (element_info[element].move_pattern == MV_ALONG_RIGHT_SIDE)
+ {
+ if (ELEMENT_CAN_ENTER_FIELD(element, right_x, right_y))
+ MovDir[x][y] = right_dir;
+ else if (!ELEMENT_CAN_ENTER_FIELD(element, move_x, move_y))
+ MovDir[x][y] = left_dir;
+
+ if (MovDir[x][y] != old_move_dir)
+ MovDelay[x][y] = GET_NEW_MOVE_DELAY(element);
+ }
+ else if (element_info[element].move_pattern == MV_TOWARDS_PLAYER ||
+ element_info[element].move_pattern == MV_AWAY_FROM_PLAYER)
+ {
+ int attr_x = -1, attr_y = -1;
+ int newx, newy;
+ boolean move_away =
+ (element_info[element].move_pattern == MV_AWAY_FROM_PLAYER);
+
+ if (AllPlayersGone)
+ {
+ attr_x = ExitX;
+ attr_y = ExitY;
+ }
+ else
+ {
+ int i;
+
+ for (i=0; i<MAX_PLAYERS; i++)
+ {
+ struct PlayerInfo *player = &stored_player[i];
+ int jx = player->jx, jy = player->jy;
+
+ if (!player->active)
+ continue;
+
+ if (attr_x == -1 ||
+ ABS(jx - x) + ABS(jy - y) < ABS(attr_x - x) + ABS(attr_y - y))
+ {
+ attr_x = jx;
+ attr_y = jy;
+ }
+ }
+ }
+
+ MovDir[x][y] = MV_NO_MOVING;
+ if (attr_x < x)
+ MovDir[x][y] |= (move_away ? MV_RIGHT : MV_LEFT);
+ else if (attr_x > x)
+ MovDir[x][y] |= (move_away ? MV_LEFT : MV_RIGHT);
+ if (attr_y < y)
+ MovDir[x][y] |= (move_away ? MV_DOWN : MV_UP);
+ else if (attr_y > y)
+ MovDir[x][y] |= (move_away ? MV_UP : MV_DOWN);
+
+ MovDelay[x][y] = GET_NEW_MOVE_DELAY(element);
+
+ if (MovDir[x][y] & MV_HORIZONTAL && MovDir[x][y] & MV_VERTICAL)
+ {
+ boolean first_horiz = RND(2);
+ int new_move_dir = MovDir[x][y];
+
+ MovDir[x][y] =
+ new_move_dir & (first_horiz ? MV_HORIZONTAL : MV_VERTICAL);
+ Moving2Blocked(x, y, &newx, &newy);
+
+ if (ELEMENT_CAN_ENTER_FIELD_OR_ACID(element, newx, newy))
+ return;
+
+ MovDir[x][y] =
+ new_move_dir & (!first_horiz ? MV_HORIZONTAL : MV_VERTICAL);
+ Moving2Blocked(x, y, &newx, &newy);
+
+ if (ELEMENT_CAN_ENTER_FIELD_OR_ACID(element, newx, newy))
+ return;
+
+ MovDir[x][y] = old_move_dir;
+ }
+ }
+}
+
+static boolean JustBeingPushed(int x, int y)
+{
+ int i;
+
+ for (i=0; i<MAX_PLAYERS; i++)
+ {
+ struct PlayerInfo *player = &stored_player[i];
if (player->active && player->Pushing && player->MovPos)
{
void StartMoving(int x, int y)
{
+ boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0));
+ boolean started_moving = FALSE; /* some elements can fall _and_ move */
int element = Feld[x][y];
if (Stop[x][y])
return;
- if (CAN_FALL(element) && y<lev_fieldy-1)
+ /* !!! this should be handled more generic (not only for mole) !!! */
+ if (element != EL_MOLE && GfxAction[x][y] != ACTION_DIGGING)
+ GfxAction[x][y] = ACTION_DEFAULT;
+
+ if (CAN_FALL(element) && y < lev_fieldy - 1)
{
if ((x>0 && IS_PLAYER(x-1, y)) || (x<lev_fieldx-1 && IS_PLAYER(x+1, y)))
if (JustBeingPushed(x, y))
return;
- if (element == EL_MORAST_VOLL)
+ if (element == EL_QUICKSAND_FULL)
{
- if (IS_FREE(x, y+1))
+ if (IS_FREE(x, y + 1))
{
InitMovingField(x, y, MV_DOWN);
+ started_moving = TRUE;
+
Feld[x][y] = EL_QUICKSAND_EMPTYING;
- Store[x][y] = EL_FELSBROCKEN;
+ Store[x][y] = EL_ROCK;
+#if 1
+ PlaySoundLevelAction(x, y, ACTION_EMPTYING);
+#else
PlaySoundLevel(x, y, SND_QUICKSAND_EMPTYING);
+#endif
}
- else if (Feld[x][y+1] == EL_MORAST_LEER)
+ else if (Feld[x][y + 1] == EL_QUICKSAND_EMPTY)
{
if (!MovDelay[x][y])
MovDelay[x][y] = TILEY + 1;
return;
}
- Feld[x][y] = EL_MORAST_LEER;
- Feld[x][y+1] = EL_MORAST_VOLL;
- Store[x][y+1] = Store[x][y];
+ Feld[x][y] = EL_QUICKSAND_EMPTY;
+ Feld[x][y + 1] = EL_QUICKSAND_FULL;
+ Store[x][y + 1] = Store[x][y];
Store[x][y] = 0;
- PlaySoundLevel(x, y, SND_QUICKSAND_SLIPPING_THROUGH);
+#if 1
+ PlaySoundLevelAction(x, y, ACTION_FILLING);
+#else
+ PlaySoundLevel(x, y, SND_QUICKSAND_FILLING);
+#endif
}
}
- else if ((element == EL_FELSBROCKEN || element == EL_BD_ROCK) &&
- Feld[x][y+1] == EL_MORAST_LEER)
+ else if ((element == EL_ROCK || element == EL_BD_ROCK) &&
+ Feld[x][y + 1] == EL_QUICKSAND_EMPTY)
{
InitMovingField(x, y, MV_DOWN);
+ started_moving = TRUE;
+
Feld[x][y] = EL_QUICKSAND_FILLING;
Store[x][y] = element;
+#if 1
+ PlaySoundLevelAction(x, y, ACTION_FILLING);
+#else
PlaySoundLevel(x, y, SND_QUICKSAND_FILLING);
+#endif
}
else if (element == EL_MAGIC_WALL_FULL)
{
- if (IS_FREE(x, y+1))
+ if (IS_FREE(x, y + 1))
{
InitMovingField(x, y, MV_DOWN);
+ started_moving = TRUE;
+
Feld[x][y] = EL_MAGIC_WALL_EMPTYING;
Store[x][y] = EL_CHANGED(Store[x][y]);
}
- else if (Feld[x][y+1] == EL_MAGIC_WALL_EMPTY)
+ else if (Feld[x][y + 1] == EL_MAGIC_WALL_ACTIVE)
{
if (!MovDelay[x][y])
MovDelay[x][y] = TILEY/4 + 1;
return;
}
- Feld[x][y] = EL_MAGIC_WALL_EMPTY;
- Feld[x][y+1] = EL_MAGIC_WALL_FULL;
- Store[x][y+1] = EL_CHANGED(Store[x][y]);
+ Feld[x][y] = EL_MAGIC_WALL_ACTIVE;
+ Feld[x][y + 1] = EL_MAGIC_WALL_FULL;
+ Store[x][y + 1] = EL_CHANGED(Store[x][y]);
Store[x][y] = 0;
}
}
- else if (element == EL_MAGIC_WALL_BD_FULL)
+ else if (element == EL_BD_MAGIC_WALL_FULL)
{
- if (IS_FREE(x, y+1))
+ if (IS_FREE(x, y + 1))
{
InitMovingField(x, y, MV_DOWN);
- Feld[x][y] = EL_MAGIC_WALL_BD_EMPTYING;
+ started_moving = TRUE;
+
+ Feld[x][y] = EL_BD_MAGIC_WALL_EMPTYING;
Store[x][y] = EL_CHANGED2(Store[x][y]);
}
- else if (Feld[x][y+1] == EL_MAGIC_WALL_BD_EMPTY)
+ else if (Feld[x][y + 1] == EL_BD_MAGIC_WALL_ACTIVE)
{
if (!MovDelay[x][y])
MovDelay[x][y] = TILEY/4 + 1;
return;
}
- Feld[x][y] = EL_MAGIC_WALL_BD_EMPTY;
- Feld[x][y+1] = EL_MAGIC_WALL_BD_FULL;
- Store[x][y+1] = EL_CHANGED2(Store[x][y]);
+ Feld[x][y] = EL_BD_MAGIC_WALL_ACTIVE;
+ Feld[x][y + 1] = EL_BD_MAGIC_WALL_FULL;
+ Store[x][y + 1] = EL_CHANGED2(Store[x][y]);
Store[x][y] = 0;
}
}
- else if (CAN_CHANGE(element) &&
- (Feld[x][y+1] == EL_MAGIC_WALL_EMPTY ||
- Feld[x][y+1] == EL_MAGIC_WALL_BD_EMPTY))
+ else if (CAN_PASS_MAGIC_WALL(element) &&
+ (Feld[x][y + 1] == EL_MAGIC_WALL_ACTIVE ||
+ Feld[x][y + 1] == EL_BD_MAGIC_WALL_ACTIVE))
{
InitMovingField(x, y, MV_DOWN);
+ started_moving = TRUE;
+
Feld[x][y] =
- (Feld[x][y+1] == EL_MAGIC_WALL_EMPTY ? EL_MAGIC_WALL_FILLING :
- EL_MAGIC_WALL_BD_FILLING);
+ (Feld[x][y + 1] == EL_MAGIC_WALL_ACTIVE ? EL_MAGIC_WALL_FILLING :
+ EL_BD_MAGIC_WALL_FILLING);
Store[x][y] = element;
}
- else if (CAN_SMASH(element) && Feld[x][y+1] == EL_SALZSAEURE)
+#if 0
+ else if (CAN_SMASH(element) && Feld[x][y + 1] == EL_ACID)
+#else
+ else if (CAN_FALL(element) && Feld[x][y + 1] == EL_ACID)
+#endif
{
- Blurb(x, y);
+ SplashAcid(x, y);
+
InitMovingField(x, y, MV_DOWN);
- Store[x][y] = EL_SALZSAEURE;
+ started_moving = TRUE;
+
+ Store[x][y] = EL_ACID;
+#if 0
+ /* !!! TEST !!! better use "_FALLING" etc. !!! */
+ GfxAction[x][y + 1] = ACTION_ACTIVE;
+#endif
}
- else if (CAN_SMASH(element) && Feld[x][y+1] == EL_BLOCKED &&
+#if 1
+#if 1
+ else if (game.engine_version < RELEASE_IDENT(2,2,0,7) &&
+ CAN_SMASH(element) && Feld[x][y + 1] == EL_BLOCKED &&
+ JustStopped[x][y] && !Pushed[x][y + 1])
+#else
+ else if (CAN_SMASH(element) && Feld[x][y + 1] == EL_BLOCKED &&
JustStopped[x][y])
+#endif
{
+ /* calling "Impact()" here is not only completely unneccessary
+ (because it already gets called from "ContinueMoving()" in
+ all relevant situations), but also completely bullshit, because
+ "JustStopped" also indicates a finished *horizontal* movement;
+ we must keep this trash for backwards compatibility with older
+ tapes */
+
Impact(x, y);
}
- else if (IS_FREE(x, y+1))
+#endif
+ else if (IS_FREE(x, y + 1) && element == EL_SPRING && use_spring_bug)
+ {
+ if (MovDir[x][y] == MV_NO_MOVING)
+ {
+ InitMovingField(x, y, MV_DOWN);
+ started_moving = TRUE;
+ }
+ }
+ else if (IS_FREE(x, y + 1) || Feld[x][y + 1] == EL_DIAMOND_BREAKING)
{
+ if (JustStopped[x][y]) /* prevent animation from being restarted */
+ MovDir[x][y] = MV_DOWN;
+
InitMovingField(x, y, MV_DOWN);
+ started_moving = TRUE;
}
- else if (element == EL_TROPFEN)
+ else if (element == EL_AMOEBA_DROP)
{
- Feld[x][y] = EL_AMOEBING;
- Store[x][y] = EL_AMOEBE_NASS;
+ Feld[x][y] = EL_AMOEBA_GROWING;
+ Store[x][y] = EL_AMOEBA_WET;
}
- /* Store[x][y+1] must be zero, because:
- (EL_MORAST_VOLL -> EL_FELSBROCKEN): Store[x][y+1] == EL_MORAST_LEER
+ /* Store[x][y + 1] must be zero, because:
+ (EL_QUICKSAND_FULL -> EL_ROCK): Store[x][y + 1] == EL_QUICKSAND_EMPTY
*/
#if 0
#if OLD_GAME_BEHAVIOUR
- else if (IS_SLIPPERY(Feld[x][y+1]) && !Store[x][y+1])
+ else if (IS_SLIPPERY(Feld[x][y + 1]) && !Store[x][y + 1])
#else
- else if (IS_SLIPPERY(Feld[x][y+1]) && !Store[x][y+1] &&
- !IS_FALLING(x, y+1) && !JustStopped[x][y+1] &&
+ else if (IS_SLIPPERY(Feld[x][y + 1]) && !Store[x][y + 1] &&
+ !IS_FALLING(x, y + 1) && !JustStopped[x][y + 1] &&
element != EL_DX_SUPABOMB)
#endif
#else
- else if ((IS_SLIPPERY(Feld[x][y+1]) ||
- (IS_EM_SLIPPERY_WALL(Feld[x][y+1]) && IS_GEM(element))) &&
- !IS_FALLING(x, y+1) && !JustStopped[x][y+1] &&
+ else if (((IS_SLIPPERY(Feld[x][y + 1]) && !IS_PLAYER(x, y + 1)) ||
+ (IS_EM_SLIPPERY_WALL(Feld[x][y + 1]) && IS_GEM(element))) &&
+ !IS_FALLING(x, y + 1) && !JustStopped[x][y + 1] &&
element != EL_DX_SUPABOMB && element != EL_SP_DISK_ORANGE)
#endif
{
- boolean left = (x>0 && IS_FREE(x-1, y) &&
- (IS_FREE(x-1, y+1) || Feld[x-1][y+1] == EL_SALZSAEURE));
- boolean right = (x<lev_fieldx-1 && IS_FREE(x+1, y) &&
- (IS_FREE(x+1, y+1) || Feld[x+1][y+1] == EL_SALZSAEURE));
+ boolean can_fall_left = (x > 0 && IS_FREE(x - 1, y) &&
+ (IS_FREE(x - 1, y + 1) ||
+ Feld[x - 1][y + 1] == EL_ACID));
+ boolean can_fall_right = (x < lev_fieldx - 1 && IS_FREE(x + 1, y) &&
+ (IS_FREE(x + 1, y + 1) ||
+ Feld[x + 1][y + 1] == EL_ACID));
+ boolean can_fall_any = (can_fall_left || can_fall_right);
+ boolean can_fall_both = (can_fall_left && can_fall_right);
+
+ if (can_fall_any && IS_CUSTOM_ELEMENT(Feld[x][y + 1]))
+ {
+ int slippery_type = element_info[Feld[x][y + 1]].slippery_type;
+
+ if (slippery_type == SLIPPERY_ONLY_LEFT)
+ can_fall_right = FALSE;
+ else if (slippery_type == SLIPPERY_ONLY_RIGHT)
+ can_fall_left = FALSE;
+ else if (slippery_type == SLIPPERY_ANY_LEFT_RIGHT && can_fall_both)
+ can_fall_right = FALSE;
+ else if (slippery_type == SLIPPERY_ANY_RIGHT_LEFT && can_fall_both)
+ can_fall_left = FALSE;
+
+ can_fall_any = (can_fall_left || can_fall_right);
+ can_fall_both = (can_fall_left && can_fall_right);
+ }
- if (left || right)
+ if (can_fall_any)
{
- if (left && right &&
+ if (can_fall_both &&
(game.emulation != EMU_BOULDERDASH &&
- element != EL_BD_ROCK && element != EL_EDELSTEIN_BD))
- left = !(right = RND(2));
+ element != EL_BD_ROCK && element != EL_BD_DIAMOND))
+ can_fall_left = !(can_fall_right = RND(2));
- InitMovingField(x, y, left ? MV_LEFT : MV_RIGHT);
+ InitMovingField(x, y, can_fall_left ? MV_LEFT : MV_RIGHT);
+ started_moving = TRUE;
}
}
- else if (IS_BELT(Feld[x][y+1]))
+ else if (IS_BELT_ACTIVE(Feld[x][y + 1]))
{
- boolean left_is_free = (x>0 && IS_FREE(x-1, y));
- boolean right_is_free = (x<lev_fieldx-1 && IS_FREE(x+1, y));
- int belt_nr = getBeltNrFromElement(Feld[x][y+1]);
+ boolean left_is_free = (x > 0 && IS_FREE(x - 1, y));
+ boolean right_is_free = (x < lev_fieldx - 1 && IS_FREE(x + 1, y));
+ int belt_nr = getBeltNrFromBeltActiveElement(Feld[x][y + 1]);
int belt_dir = game.belt_dir[belt_nr];
if ((belt_dir == MV_LEFT && left_is_free) ||
(belt_dir == MV_RIGHT && right_is_free))
+ {
InitMovingField(x, y, belt_dir);
+ started_moving = TRUE;
+
+ GfxAction[x][y] = ACTION_DEFAULT;
+ }
}
}
- else if (CAN_MOVE(element))
+
+ /* not "else if" because of elements that can fall and move (EL_SPRING) */
+ if (CAN_MOVE(element) && !started_moving)
{
int newx, newy;
- if ((element == EL_SONDE || element == EL_BALLOON ||
- element == EL_SPRING_MOVING)
+ if ((element == EL_SATELLITE ||
+ element == EL_BALLOON ||
+ element == EL_SPRING)
&& JustBeingPushed(x, y))
return;
+#if 0
+#if 0
+ if (element == EL_SPRING && MovDir[x][y] == MV_DOWN)
+ Feld[x][y + 1] = EL_EMPTY; /* was set to EL_BLOCKED above */
+#else
+ if (element == EL_SPRING && MovDir[x][y] != MV_NO_MOVING)
+ {
+ Moving2Blocked(x, y, &newx, &newy);
+ if (Feld[newx][newy] == EL_BLOCKED)
+ Feld[newx][newy] = EL_EMPTY; /* was set to EL_BLOCKED above */
+ }
+#endif
+#endif
+
if (!MovDelay[x][y]) /* start new movement phase */
{
- /* all objects that can change their move direction after each step */
- /* (MAMPFER, MAMPFER2 and PACMAN go straight until they hit a wall */
+ /* all objects that can change their move direction after each step
+ (YAMYAM, DARK_YAMYAM and PACMAN go straight until they hit a wall */
- if (element!=EL_MAMPFER && element!=EL_MAMPFER2 && element!=EL_PACMAN)
+ if (element != EL_YAMYAM &&
+ element != EL_DARK_YAMYAM &&
+ element != EL_PACMAN &&
+ !(element_info[element].move_pattern & MV_ANY_DIRECTION) &&
+ element_info[element].move_pattern != MV_TURNING_LEFT &&
+ element_info[element].move_pattern != MV_TURNING_RIGHT)
{
TurnRound(x, y);
- if (MovDelay[x][y] && (element == EL_KAEFER ||
- element == EL_FLIEGER ||
+ if (MovDelay[x][y] && (element == EL_BUG ||
+ element == EL_SPACESHIP ||
element == EL_SP_SNIKSNAK ||
element == EL_SP_ELECTRON ||
element == EL_MOLE))
{
MovDelay[x][y]--;
- if (element == EL_ROBOT ||
- element == EL_MAMPFER || element == EL_MAMPFER2)
+#if 0
+ if (element == EL_YAMYAM)
{
- int phase = MovDelay[x][y] % 8;
-
- if (phase > 3)
- phase = 7 - phase;
+ printf("::: %d\n",
+ el_act_dir2img(EL_YAMYAM, ACTION_WAITING, MV_LEFT));
+ DrawLevelElementAnimation(x, y, element);
+ }
+#endif
- if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y), el2gfx(element) + phase);
+ if (MovDelay[x][y]) /* element still has to wait some time */
+ {
+#if 0
+ /* !!! PLACE THIS SOMEWHERE AFTER "TurnRound()" !!! */
+ ResetGfxAnimation(x, y);
+#endif
+ GfxAction[x][y] = ACTION_WAITING;
+ }
- if (MovDelay[x][y] % 4 == 3)
- {
- if (element == EL_MAMPFER)
- PlaySoundLevel(x, y, SND_YAMYAM_WAITING);
- else if (element == EL_MAMPFER2)
- PlaySoundLevel(x, y, SND_DARK_YAMYAM_WAITING);
- }
+ if (element == EL_ROBOT ||
+#if 0
+ element == EL_PACMAN ||
+#endif
+ element == EL_YAMYAM ||
+ element == EL_DARK_YAMYAM)
+ {
+#if 0
+ DrawLevelElementAnimation(x, y, element);
+#else
+ DrawLevelElementAnimationIfNeeded(x, y, element);
+#endif
+ PlaySoundLevelAction(x, y, ACTION_WAITING);
}
else if (element == EL_SP_ELECTRON)
- DrawGraphicAnimation(x, y, GFX2_SP_ELECTRON, 8, 2, ANIM_NORMAL);
- else if (element == EL_DRACHE)
+ DrawLevelElementAnimationIfNeeded(x, y, element);
+ else if (element == EL_DRAGON)
{
int i;
int dir = MovDir[x][y];
int dx = (dir == MV_LEFT ? -1 : dir == MV_RIGHT ? +1 : 0);
int dy = (dir == MV_UP ? -1 : dir == MV_DOWN ? +1 : 0);
- int graphic = (dir == MV_LEFT ? GFX_FLAMMEN_LEFT :
- dir == MV_RIGHT ? GFX_FLAMMEN_RIGHT :
- dir == MV_UP ? GFX_FLAMMEN_UP :
- dir == MV_DOWN ? GFX_FLAMMEN_DOWN : GFX_LEERRAUM);
- int phase = FrameCounter % 2;
+ int graphic = (dir == MV_LEFT ? IMG_FLAMES_1_LEFT :
+ dir == MV_RIGHT ? IMG_FLAMES_1_RIGHT :
+ dir == MV_UP ? IMG_FLAMES_1_UP :
+ dir == MV_DOWN ? IMG_FLAMES_1_DOWN : IMG_EMPTY);
+ int frame = getGraphicAnimationFrame(graphic, -1);
for (i=1; i<=3; i++)
{
int xx = x + i*dx, yy = y + i*dy;
int sx = SCREENX(xx), sy = SCREENY(yy);
+ int flame_graphic = graphic + (i - 1);
- if (!IN_LEV_FIELD(xx, yy) ||
- IS_SOLID(Feld[xx][yy]) || Feld[xx][yy] == EL_EXPLODING)
+ if (!IN_LEV_FIELD(xx, yy) || IS_DRAGONFIRE_PROOF(Feld[xx][yy]))
break;
if (MovDelay[x][y])
{
int flamed = MovingOrBlocked2Element(xx, yy);
- if (IS_ENEMY(flamed) || IS_EXPLOSIVE(flamed))
+ if (IS_CLASSIC_ENEMY(flamed) || CAN_EXPLODE_BY_FIRE(flamed))
Bang(xx, yy);
else
RemoveMovingField(xx, yy);
- Feld[xx][yy] = EL_BURNING;
+ Feld[xx][yy] = EL_FLAMES;
if (IN_SCR_FIELD(sx, sy))
- DrawGraphic(sx, sy, graphic + phase*3 + i-1);
+ DrawGraphic(sx, sy, flame_graphic, frame);
}
else
{
- if (Feld[xx][yy] == EL_BURNING)
- Feld[xx][yy] = EL_LEERRAUM;
+ if (Feld[xx][yy] == EL_FLAMES)
+ Feld[xx][yy] = EL_EMPTY;
DrawLevelField(xx, yy);
}
}
if (MovDelay[x][y]) /* element still has to wait some time */
{
- PlaySoundLevelAction(x, y, SND_ACTION_WAITING);
+ PlaySoundLevelAction(x, y, ACTION_WAITING);
return;
}
+
+ /* special case of "moving" animation of waiting elements (FIX THIS !!!);
+ for all other elements GfxAction will be set by InitMovingField() */
+ if (element == EL_BD_BUTTERFLY || element == EL_BD_FIREFLY)
+ GfxAction[x][y] = ACTION_MOVING;
}
/* now make next step */
Moving2Blocked(x, y, &newx, &newy); /* get next screen position */
- if (IS_ENEMY(element) && IS_PLAYER(newx, newy) &&
+ if (DONT_COLLIDE_WITH(element) && IS_PLAYER(newx, newy) &&
!PLAYER_PROTECTED(newx, newy))
{
-
#if 1
TestIfBadThingRunsIntoHero(x, y, MovDir[x][y]);
return;
#else
- /* enemy got the player */
+ /* player killed by element which is deadly when colliding with */
MovDir[x][y] = 0;
KillHero(PLAYERINFO(newx, newy));
return;
#endif
}
- else if ((element == EL_PINGUIN || element == EL_ROBOT ||
- element == EL_SONDE || element == EL_BALLOON) &&
+ else if ((element == EL_PENGUIN ||
+ element == EL_ROBOT ||
+ element == EL_SATELLITE ||
+ element == EL_BALLOON ||
+ IS_CUSTOM_ELEMENT(element)) &&
IN_LEV_FIELD(newx, newy) &&
- MovDir[x][y] == MV_DOWN && Feld[newx][newy] == EL_SALZSAEURE)
+ MovDir[x][y] == MV_DOWN && Feld[newx][newy] == EL_ACID)
{
- Blurb(x, y);
- Store[x][y] = EL_SALZSAEURE;
+ SplashAcid(x, y);
+ Store[x][y] = EL_ACID;
}
- else if (element == EL_PINGUIN && IN_LEV_FIELD(newx, newy))
+ else if (element == EL_PENGUIN && IN_LEV_FIELD(newx, newy))
{
- if (Feld[newx][newy] == EL_AUSGANG_AUF)
+ if (Feld[newx][newy] == EL_EXIT_OPEN)
{
- Feld[x][y] = EL_LEERRAUM;
+ Feld[x][y] = EL_EMPTY;
DrawLevelField(x, y);
- PlaySoundLevel(newx, newy, SND_PENGUIN_ENTERING_EXIT);
+ PlaySoundLevel(newx, newy, SND_PENGUIN_PASSING);
if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
- DrawGraphicThruMask(SCREENX(newx), SCREENY(newy), el2gfx(element));
+ DrawGraphicThruMask(SCREENX(newx),SCREENY(newy), el2img(element), 0);
local_player->friends_still_needed--;
if (!local_player->friends_still_needed &&
return;
}
- else if (IS_MAMPF3(Feld[newx][newy]))
+ else if (IS_FOOD_PENGUIN(Feld[newx][newy]))
{
if (DigField(local_player, newx, newy, 0, 0, DF_DIG) == MF_MOVING)
DrawLevelField(newx, newy);
}
else if (!IS_FREE(newx, newy))
{
+ GfxAction[x][y] = ACTION_WAITING;
+
if (IS_PLAYER(x, y))
DrawPlayerField(x, y);
else
return;
}
}
- else if (element == EL_SCHWEIN && IN_LEV_FIELD(newx, newy))
+ else if (element == EL_PIG && IN_LEV_FIELD(newx, newy))
{
- if (IS_GEM(Feld[newx][newy]))
+ if (IS_FOOD_PIG(Feld[newx][newy]))
{
if (IS_MOVING(newx, newy))
RemoveMovingField(newx, newy);
else
{
- Feld[newx][newy] = EL_LEERRAUM;
+ Feld[newx][newy] = EL_EMPTY;
DrawLevelField(newx, newy);
}
- PlaySoundLevel(x, y, SND_PIG_EATING_GEM);
+ PlaySoundLevel(x, y, SND_PIG_DIGGING);
}
else if (!IS_FREE(newx, newy))
{
return;
}
}
- else if (element == EL_DRACHE && IN_LEV_FIELD(newx, newy))
+ else if (element == EL_DRAGON && IN_LEV_FIELD(newx, newy))
{
if (!IS_FREE(newx, newy))
{
int newx1 = newx+1*dx, newy1 = newy+1*dy;
int newx2 = newx+2*dx, newy2 = newy+2*dy;
int element1 = (IN_LEV_FIELD(newx1, newy1) ?
- MovingOrBlocked2Element(newx1, newy1) : EL_BETON);
+ MovingOrBlocked2Element(newx1, newy1) : EL_STEELWALL);
int element2 = (IN_LEV_FIELD(newx2, newy2) ?
- MovingOrBlocked2Element(newx2, newy2) : EL_BETON);
+ MovingOrBlocked2Element(newx2, newy2) : EL_STEELWALL);
- if ((wanna_flame || IS_ENEMY(element1) || IS_ENEMY(element2)) &&
- element1 != EL_DRACHE && element2 != EL_DRACHE &&
- element1 != EL_BURNING && element2 != EL_BURNING)
+ if ((wanna_flame ||
+ IS_CLASSIC_ENEMY(element1) ||
+ IS_CLASSIC_ENEMY(element2)) &&
+ element1 != EL_DRAGON && element2 != EL_DRAGON &&
+ element1 != EL_FLAMES && element2 != EL_FLAMES)
{
if (IS_PLAYER(x, y))
DrawPlayerField(x, y);
PlaySoundLevel(x, y, SND_DRAGON_ATTACKING);
MovDelay[x][y] = 50;
- Feld[newx][newy] = EL_BURNING;
- if (IN_LEV_FIELD(newx1, newy1) && Feld[newx1][newy1] == EL_LEERRAUM)
- Feld[newx1][newy1] = EL_BURNING;
- if (IN_LEV_FIELD(newx2, newy2) && Feld[newx2][newy2] == EL_LEERRAUM)
- Feld[newx2][newy2] = EL_BURNING;
+ Feld[newx][newy] = EL_FLAMES;
+ if (IN_LEV_FIELD(newx1, newy1) && Feld[newx1][newy1] == EL_EMPTY)
+ Feld[newx1][newy1] = EL_FLAMES;
+ if (IN_LEV_FIELD(newx2, newy2) && Feld[newx2][newy2] == EL_EMPTY)
+ Feld[newx2][newy2] = EL_FLAMES;
return;
}
}
}
- else if (element == EL_MAMPFER && IN_LEV_FIELD(newx, newy) &&
- Feld[newx][newy] == EL_DIAMANT)
+ else if (element == EL_YAMYAM && IN_LEV_FIELD(newx, newy) &&
+ Feld[newx][newy] == EL_DIAMOND)
{
if (IS_MOVING(newx, newy))
RemoveMovingField(newx, newy);
else
{
- Feld[newx][newy] = EL_LEERRAUM;
+ Feld[newx][newy] = EL_EMPTY;
DrawLevelField(newx, newy);
}
- PlaySoundLevel(x, y, SND_YAMYAM_EATING_DIAMOND);
+ PlaySoundLevel(x, y, SND_YAMYAM_DIGGING);
}
- else if (element == EL_MAMPFER2 && IN_LEV_FIELD(newx, newy) &&
- IS_MAMPF2(Feld[newx][newy]))
+ else if (element == EL_DARK_YAMYAM && IN_LEV_FIELD(newx, newy) &&
+ IS_FOOD_DARK_YAMYAM(Feld[newx][newy]))
{
if (AmoebaNr[newx][newy])
{
AmoebaCnt2[AmoebaNr[newx][newy]]--;
- if (Feld[newx][newy] == EL_AMOEBE_VOLL ||
- Feld[newx][newy] == EL_AMOEBE_BD)
+ if (Feld[newx][newy] == EL_AMOEBA_FULL ||
+ Feld[newx][newy] == EL_BD_AMOEBA)
AmoebaCnt[AmoebaNr[newx][newy]]--;
}
RemoveMovingField(newx, newy);
else
{
- Feld[newx][newy] = EL_LEERRAUM;
+ Feld[newx][newy] = EL_EMPTY;
DrawLevelField(newx, newy);
}
- PlaySoundLevel(x, y, SND_DARK_YAMYAM_EATING_ANY);
+ PlaySoundLevel(x, y, SND_DARK_YAMYAM_DIGGING);
}
else if ((element == EL_PACMAN || element == EL_MOLE)
&& IN_LEV_FIELD(newx, newy) && IS_AMOEBOID(Feld[newx][newy]))
if (AmoebaNr[newx][newy])
{
AmoebaCnt2[AmoebaNr[newx][newy]]--;
- if (Feld[newx][newy] == EL_AMOEBE_VOLL ||
- Feld[newx][newy] == EL_AMOEBE_BD)
+ if (Feld[newx][newy] == EL_AMOEBA_FULL ||
+ Feld[newx][newy] == EL_BD_AMOEBA)
AmoebaCnt[AmoebaNr[newx][newy]]--;
}
if (element == EL_MOLE)
{
- Feld[newx][newy] = EL_DEAMOEBING;
- PlaySoundLevel(x, y, SND_MOLE_EATING_AMOEBA);
+ Feld[newx][newy] = EL_AMOEBA_SHRINKING;
+ PlaySoundLevel(x, y, SND_MOLE_DIGGING);
+
+ ResetGfxAnimation(x, y);
+ GfxAction[x][y] = ACTION_DIGGING;
+ DrawLevelField(x, y);
+
MovDelay[newx][newy] = 0; /* start amoeba shrinking delay */
return; /* wait for shrinking amoeba */
}
else /* element == EL_PACMAN */
{
- Feld[newx][newy] = EL_LEERRAUM;
+ Feld[newx][newy] = EL_EMPTY;
DrawLevelField(newx, newy);
- PlaySoundLevel(x, y, SND_PACMAN_EATING_AMOEBA);
+ PlaySoundLevel(x, y, SND_PACMAN_DIGGING);
}
}
else if (element == EL_MOLE && IN_LEV_FIELD(newx, newy) &&
- (Feld[newx][newy] == EL_DEAMOEBING ||
- (Feld[newx][newy] == EL_LEERRAUM && Stop[newx][newy])))
+ (Feld[newx][newy] == EL_AMOEBA_SHRINKING ||
+ (Feld[newx][newy] == EL_EMPTY && Stop[newx][newy])))
{
/* wait for shrinking amoeba to completely disappear */
return;
TurnRound(x, y);
- if (element == EL_KAEFER || element == EL_FLIEGER ||
- element == EL_SP_SNIKSNAK || element == EL_MOLE)
+#if 1
+ if (GFX_ELEMENT(element) != EL_SAND) /* !!! FIX THIS (crumble) !!! */
+ DrawLevelElementAnimation(x, y, element);
+#else
+ if (element == EL_BUG ||
+ element == EL_SPACESHIP ||
+ element == EL_SP_SNIKSNAK)
DrawLevelField(x, y);
- else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
- DrawGraphicAnimation(x, y, el2gfx(element), 2, 4, ANIM_NORMAL);
- else if (element == EL_SONDE)
- DrawGraphicAnimation(x, y, GFX_SONDE_START, 8, 2, ANIM_NORMAL);
+ else if (element == EL_MOLE)
+ DrawLevelField(x, y);
+ else if (element == EL_BD_BUTTERFLY ||
+ element == EL_BD_FIREFLY)
+ DrawLevelElementAnimationIfNeeded(x, y, element);
+ else if (element == EL_SATELLITE)
+ DrawLevelElementAnimationIfNeeded(x, y, element);
else if (element == EL_SP_ELECTRON)
- DrawGraphicAnimation(x, y, GFX2_SP_ELECTRON, 8, 2, ANIM_NORMAL);
+ DrawLevelElementAnimationIfNeeded(x, y, element);
+#endif
if (DONT_TOUCH(element))
TestIfBadThingTouchesHero(x, y);
- PlaySoundLevelAction(x, y, SND_ACTION_WAITING);
+#if 0
+ PlaySoundLevelAction(x, y, ACTION_WAITING);
+#endif
return;
}
InitMovingField(x, y, MovDir[x][y]);
- PlaySoundLevelAction(x, y, SND_ACTION_MOVING);
+ PlaySoundLevelAction(x, y, ACTION_MOVING);
}
if (MovDir[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 newx = x + dx, newy = y + dy;
- int step = (horiz_move ? dx : dy) * TILEX / 8;
-
- if (element == EL_TROPFEN || element == EL_AMOEBA_DRIPPING)
- step /= 2;
- else if (element == EL_QUICKSAND_FILLING ||
- element == EL_QUICKSAND_EMPTYING)
- step /= 4;
- else if (element == EL_MAGIC_WALL_FILLING ||
- element == EL_MAGIC_WALL_BD_FILLING ||
- element == EL_MAGIC_WALL_EMPTYING ||
- element == EL_MAGIC_WALL_BD_EMPTYING)
- step /= 2;
- else if (CAN_FALL(element) && horiz_move &&
- y < lev_fieldy-1 && IS_BELT(Feld[x][y+1]))
- step /= 2;
- else if (element == EL_SPRING_MOVING)
- step*=2;
+ int nextx = newx + dx, nexty = newy + dy;
+ boolean pushed = Pushed[x][y];
-#if OLD_GAME_BEHAVIOUR
- else if (CAN_FALL(element) && horiz_move && !IS_SP_ELEMENT(element))
- step*=2;
-#endif
+ MovPos[x][y] += getElementMoveStepsize(x, y);
- MovPos[x][y] += step;
+ if (pushed) /* special case: moving object pushed by player */
+ MovPos[x][y] = SIGN(MovPos[x][y]) * (TILEX - ABS(PLAYERINFO(x,y)->MovPos));
if (ABS(MovPos[x][y]) >= TILEX) /* object reached its destination */
{
- Feld[x][y] = EL_LEERRAUM;
+ Feld[x][y] = EL_EMPTY;
Feld[newx][newy] = element;
+ MovPos[x][y] = 0; /* force "not moving" for "crumbled sand" */
if (element == EL_MOLE)
{
- int i;
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
-
- Feld[x][y] = EL_ERDREICH;
- DrawLevelField(x, y);
-
- for(i=0; i<4; i++)
- {
- int xx, yy;
+ Feld[x][y] = EL_SAND;
- xx = x + xy[i][0];
- yy = y + xy[i][1];
-
- if (IN_LEV_FIELD(xx, yy) && Feld[xx][yy] == EL_ERDREICH)
- DrawLevelField(xx, yy); /* for "ErdreichAnbroeckeln()" */
- }
+ DrawLevelFieldCrumbledSandNeighbours(x, y);
}
-
- if (element == EL_QUICKSAND_FILLING)
+ else if (element == EL_QUICKSAND_FILLING)
{
element = Feld[newx][newy] = get_next_element(element);
Store[newx][newy] = Store[x][y];
Feld[x][y] = EL_MAGIC_WALL_DEAD;
element = Feld[newx][newy] = Store[x][y];
}
- else if (element == EL_MAGIC_WALL_BD_FILLING)
+ else if (element == EL_BD_MAGIC_WALL_FILLING)
{
element = Feld[newx][newy] = get_next_element(element);
if (!game.magic_wall_active)
- element = Feld[newx][newy] = EL_MAGIC_WALL_BD_DEAD;
+ element = Feld[newx][newy] = EL_BD_MAGIC_WALL_DEAD;
Store[newx][newy] = Store[x][y];
}
- else if (element == EL_MAGIC_WALL_BD_EMPTYING)
+ else if (element == EL_BD_MAGIC_WALL_EMPTYING)
{
Feld[x][y] = get_next_element(element);
if (!game.magic_wall_active)
- Feld[x][y] = EL_MAGIC_WALL_BD_DEAD;
+ Feld[x][y] = EL_BD_MAGIC_WALL_DEAD;
element = Feld[newx][newy] = Store[x][y];
}
- else if (element == EL_AMOEBA_DRIPPING)
+ else if (element == EL_AMOEBA_DROPPING)
{
Feld[x][y] = get_next_element(element);
element = Feld[newx][newy] = Store[x][y];
}
- else if (Store[x][y] == EL_SALZSAEURE)
+ else if (element == EL_SOKOBAN_OBJECT)
+ {
+ if (Back[x][y])
+ Feld[x][y] = Back[x][y];
+
+ if (Back[newx][newy])
+ Feld[newx][newy] = EL_SOKOBAN_FIELD_FULL;
+
+ Back[x][y] = Back[newx][newy] = 0;
+ }
+ else if (Store[x][y] == EL_ACID)
{
- element = Feld[newx][newy] = EL_SALZSAEURE;
+ element = Feld[newx][newy] = EL_ACID;
}
Store[x][y] = 0;
MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0;
MovDelay[newx][newy] = 0;
+ /* copy element change control values to new field */
+ ChangeDelay[newx][newy] = ChangeDelay[x][y];
+
+ /* copy animation control values to new field */
+ GfxFrame[newx][newy] = GfxFrame[x][y];
+ GfxAction[newx][newy] = GfxAction[x][y]; /* keep action one frame */
+ GfxRandom[newx][newy] = GfxRandom[x][y]; /* keep same random value */
+
+ Pushed[x][y] = Pushed[newx][newy] = FALSE;
+
+ ResetGfxAnimation(x, y); /* reset animation values for old field */
+
+#if 0
+ /* 2.1.1 (does not work correctly for spring) */
if (!CAN_MOVE(element))
MovDir[newx][newy] = 0;
+#else
+
+#if 0
+ /* (does not work for falling objects that slide horizontally) */
+ if (CAN_FALL(element) && MovDir[newx][newy] == MV_DOWN)
+ MovDir[newx][newy] = 0;
+#else
+ /*
+ if (!CAN_MOVE(element) ||
+ (element == EL_SPRING && MovDir[newx][newy] == MV_DOWN))
+ MovDir[newx][newy] = 0;
+ */
+
+ if (!CAN_MOVE(element) ||
+ (CAN_FALL(element) && MovDir[newx][newy] == MV_DOWN))
+ MovDir[newx][newy] = 0;
+#endif
+#endif
DrawLevelField(x, y);
DrawLevelField(newx, newy);
- Stop[newx][newy] = TRUE;
- JustStopped[newx][newy] = 3;
+ Stop[newx][newy] = TRUE; /* ignore this element until the next frame */
+
+ if (!pushed) /* special case: moving object pushed by player */
+ JustStopped[newx][newy] = 3;
if (DONT_TOUCH(element)) /* object may be nasty to player or others */
{
TestIfBadThingTouchesFriend(newx, newy);
TestIfBadThingTouchesOtherBadThing(newx, newy);
}
- else if (element == EL_PINGUIN)
+ else if (element == EL_PENGUIN)
TestIfFriendTouchesBadThing(newx, newy);
- if (CAN_SMASH(element) && direction == MV_DOWN &&
- (newy == lev_fieldy-1 || !IS_FREE(x, newy+1)))
+ if (CAN_FALL(element) && direction == MV_DOWN &&
+ (newy == lev_fieldy - 1 || !IS_FREE(x, newy + 1)))
Impact(x, newy);
+
+ if (!IN_LEV_FIELD(nextx, nexty) || !IS_FREE(nextx, nexty))
+ CheckElementChange(newx, newy, element, CE_COLLISION);
+
+ TestIfPlayerTouchesCustomElement(newx, newy);
+ TestIfElementTouchesCustomElement(newx, newy);
}
else /* still moving on */
+ {
DrawLevelField(x, y);
+ }
}
int AmoebeNachbarNr(int ax, int ay)
if (!IN_LEV_FIELD(x, y))
continue;
- if ((Feld[x][y] == EL_AMOEBE_VOLL ||
- Feld[x][y] == EL_AMOEBE_BD ||
- Feld[x][y] == EL_AMOEBE_TOT) &&
+ if ((Feld[x][y] == EL_AMOEBA_FULL ||
+ Feld[x][y] == EL_BD_AMOEBA ||
+ Feld[x][y] == EL_AMOEBA_DEAD) &&
AmoebaNr[x][y] != new_group_nr)
{
int old_group_nr = AmoebaNr[x][y];
{
int i, x, y;
- if (Feld[ax][ay] == EL_AMOEBE_TOT)
+ if (Feld[ax][ay] == EL_AMOEBA_DEAD)
{
int group_nr = AmoebaNr[ax][ay];
{
for (x=0; x<lev_fieldx; x++)
{
- if (Feld[x][y] == EL_AMOEBE_TOT && AmoebaNr[x][y] == group_nr)
+ if (Feld[x][y] == EL_AMOEBA_DEAD && AmoebaNr[x][y] == group_nr)
{
AmoebaNr[x][y] = 0;
- Feld[x][y] = EL_AMOEBA2DIAM;
+ Feld[x][y] = EL_AMOEBA_TO_DIAMOND;
}
}
}
if (!IN_LEV_FIELD(x, y))
continue;
- if (Feld[x][y] == EL_AMOEBA2DIAM)
+ if (Feld[x][y] == EL_AMOEBA_TO_DIAMOND)
{
PlaySoundLevel(x, y, (IS_GEM(level.amoeba_content) ?
SND_AMOEBA_TURNING_TO_GEM :
for (x=0; x<lev_fieldx; x++)
{
if (AmoebaNr[x][y] == group_nr &&
- (Feld[x][y] == EL_AMOEBE_TOT ||
- Feld[x][y] == EL_AMOEBE_BD ||
- Feld[x][y] == EL_AMOEBING))
+ (Feld[x][y] == EL_AMOEBA_DEAD ||
+ Feld[x][y] == EL_BD_AMOEBA ||
+ Feld[x][y] == EL_AMOEBA_GROWING))
{
AmoebaNr[x][y] = 0;
Feld[x][y] = new_element;
if (DelayReached(&sound_delay, sound_delay_value))
{
- if (Store[x][y] == EL_AMOEBE_BD)
- PlaySoundLevel(x, y, SND_BD_AMOEBA_CREATING);
+#if 1
+ PlaySoundLevelElementAction(x, y, Store[x][y], ACTION_GROWING);
+#else
+ if (Store[x][y] == EL_BD_AMOEBA)
+ PlaySoundLevel(x, y, SND_BD_AMOEBA_GROWING);
else
- PlaySoundLevel(x, y, SND_AMOEBA_CREATING);
+ PlaySoundLevel(x, y, SND_AMOEBA_GROWING);
+#endif
sound_delay_value = 30;
}
}
{
MovDelay[x][y]--;
if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_AMOEBING + 3 - MovDelay[x][y]/2);
+ {
+ int frame = getGraphicAnimationFrame(IMG_AMOEBA_GROWING,
+ 6 - MovDelay[x][y]);
+
+ DrawGraphic(SCREENX(x), SCREENY(y), IMG_AMOEBA_GROWING, frame);
+ }
if (!MovDelay[x][y])
{
{
MovDelay[x][y]--;
if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_AMOEBING + MovDelay[x][y]/2);
+ {
+ int frame = getGraphicAnimationFrame(IMG_AMOEBA_SHRINKING,
+ 6 - MovDelay[x][y]);
+
+ DrawGraphic(SCREENX(x), SCREENY(y), IMG_AMOEBA_SHRINKING, frame);
+ }
if (!MovDelay[x][y])
{
- Feld[x][y] = EL_LEERRAUM;
+ Feld[x][y] = EL_EMPTY;
DrawLevelField(x, y);
/* don't let mole enter this field in this cycle;
{
int i;
int element = Feld[ax][ay];
+ int graphic = el2img(element);
int newax = ax, neway = ay;
static int xy[4][2] =
{
if (!level.amoeba_speed)
{
- Feld[ax][ay] = EL_AMOEBE_TOT;
+ Feld[ax][ay] = EL_AMOEBA_DEAD;
DrawLevelField(ax, ay);
return;
}
+ if (IS_ANIMATED(graphic))
+ DrawLevelGraphicAnimationIfNeeded(ax, ay, graphic);
+
if (!MovDelay[ax][ay]) /* start making new amoeba field */
MovDelay[ax][ay] = RND(FRAMES_PER_SECOND * 25 / (1 + level.amoeba_speed));
return;
}
- if (element == EL_AMOEBE_NASS) /* object is an acid / amoeba drop */
+ if (element == EL_AMOEBA_WET) /* object is an acid / amoeba drop */
{
int start = RND(4);
int x = ax + xy[start][0];
if (!IN_LEV_FIELD(x, y))
return;
+ /* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
if (IS_FREE(x, y) ||
- Feld[x][y] == EL_ERDREICH || Feld[x][y] == EL_MORAST_LEER)
+ Feld[x][y] == EL_SAND || Feld[x][y] == EL_QUICKSAND_EMPTY)
{
newax = x;
neway = y;
if (!IN_LEV_FIELD(x, y))
continue;
+ /* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
if (IS_FREE(x, y) ||
- Feld[x][y] == EL_ERDREICH || Feld[x][y] == EL_MORAST_LEER)
+ Feld[x][y] == EL_SAND || Feld[x][y] == EL_QUICKSAND_EMPTY)
{
newax = x;
neway = y;
{
if (i == 4 && (!waiting_for_player || game.emulation == EMU_BOULDERDASH))
{
- Feld[ax][ay] = EL_AMOEBE_TOT;
+ Feld[ax][ay] = EL_AMOEBA_DEAD;
DrawLevelField(ax, ay);
AmoebaCnt[AmoebaNr[ax][ay]]--;
if (AmoebaCnt[AmoebaNr[ax][ay]] <= 0) /* amoeba is completely dead */
{
- if (element == EL_AMOEBE_VOLL)
+ if (element == EL_AMOEBA_FULL)
AmoebeUmwandeln(ax, ay);
- else if (element == EL_AMOEBE_BD)
+ else if (element == EL_BD_AMOEBA)
AmoebeUmwandelnBD(ax, ay, level.amoeba_content);
}
}
return;
}
- else if (element == EL_AMOEBE_VOLL || element == EL_AMOEBE_BD)
+ else if (element == EL_AMOEBA_FULL || element == EL_BD_AMOEBA)
{
/* amoeba gets larger by growing in some direction */
/* if amoeba touches other amoeba(s) after growing, unify them */
AmoebenVereinigen(newax, neway);
- if (element == EL_AMOEBE_BD && AmoebaCnt2[new_group_nr] >= 200)
+ if (element == EL_BD_AMOEBA && AmoebaCnt2[new_group_nr] >= 200)
{
AmoebeUmwandelnBD(newax, neway, EL_BD_ROCK);
return;
}
}
- if (element != EL_AMOEBE_NASS || neway < ay || !IS_FREE(newax, neway) ||
+ if (element != EL_AMOEBA_WET || neway < ay || !IS_FREE(newax, neway) ||
(neway == lev_fieldy - 1 && newax != ax))
{
- Feld[newax][neway] = EL_AMOEBING; /* simple growth of new amoeba tile */
+ Feld[newax][neway] = EL_AMOEBA_GROWING; /* creation of new amoeba */
Store[newax][neway] = element;
}
else if (neway == ay)
{
- Feld[newax][neway] = EL_TROPFEN; /* drop left or right from amoeba */
- PlaySoundLevel(newax, neway, SND_AMOEBA_DROPPING);
+ Feld[newax][neway] = EL_AMOEBA_DROP; /* drop left/right of amoeba */
+#if 1
+ PlaySoundLevelAction(newax, neway, ACTION_GROWING);
+#else
+ PlaySoundLevel(newax, neway, SND_AMOEBA_GROWING);
+#endif
}
else
{
- InitMovingField(ax, ay, MV_DOWN); /* drop dripping out of amoeba */
- Feld[ax][ay] = EL_AMOEBA_DRIPPING;
- Store[ax][ay] = EL_TROPFEN;
+ InitMovingField(ax, ay, MV_DOWN); /* drop dripping from amoeba */
+ Feld[ax][ay] = EL_AMOEBA_DROPPING;
+ Store[ax][ay] = EL_AMOEBA_DROP;
ContinueMoving(ax, ay);
return;
}
static int life[4] = { 2, 3, 3, 3 }; /* parameters for "game of life" */
int life_time = 40;
int element = Feld[ax][ay];
+ int graphic = el2img(element);
boolean changed = FALSE;
+ if (IS_ANIMATED(graphic))
+ DrawLevelGraphicAnimationIfNeeded(ax, ay, graphic);
+
if (Stop[ax][ay])
return;
continue;
if (((Feld[x][y] == element ||
- (element == EL_LIFE && IS_PLAYER(x, y))) &&
+ (element == EL_GAME_OF_LIFE && IS_PLAYER(x, y))) &&
!Stop[x][y]) ||
(IS_FREE(x, y) && Stop[x][y]))
nachbarn++;
{
if (nachbarn < life[0] || nachbarn > life[1])
{
- Feld[xx][yy] = EL_LEERRAUM;
+ Feld[xx][yy] = EL_EMPTY;
if (!Stop[xx][yy])
DrawLevelField(xx, yy);
Stop[xx][yy] = TRUE;
changed = TRUE;
}
}
- else if (IS_FREE(xx, yy) || Feld[xx][yy] == EL_ERDREICH)
+ /* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
+ else if (IS_FREE(xx, yy) || Feld[xx][yy] == EL_SAND)
{ /* free border field */
if (nachbarn >= life[2] && nachbarn <= life[3])
{
Feld[xx][yy] = element;
- MovDelay[xx][yy] = (element == EL_LIFE ? 0 : life_time-1);
+ MovDelay[xx][yy] = (element == EL_GAME_OF_LIFE ? 0 : life_time-1);
if (!Stop[xx][yy])
DrawLevelField(xx, yy);
Stop[xx][yy] = TRUE;
}
if (changed)
- PlaySoundLevel(ax, ay, element == EL_LIFE ? SND_GAMEOFLIFE_CREATING :
- SND_BIOMAZE_CREATING);
+ PlaySoundLevel(ax, ay, element == EL_BIOMAZE ? SND_BIOMAZE_GROWING :
+ SND_GAME_OF_LIFE_GROWING);
}
-void RobotWheel(int x, int y)
+static void InitRobotWheel(int x, int y)
{
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = level.time_wheel * FRAMES_PER_SECOND;
+ ChangeDelay[x][y] = level.time_wheel * FRAMES_PER_SECOND;
+}
- if (MovDelay[x][y]) /* wait some time before next frame */
- {
- MovDelay[x][y]--;
- if (MovDelay[x][y])
- {
- if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_ABLENK+MovDelay[x][y]%4);
- if (!(MovDelay[x][y]%4))
- PlaySoundLevel(x, y, SND_ROBOT_WHEEL_RUNNING);
- return;
- }
- }
+static void RunRobotWheel(int x, int y)
+{
+ PlaySoundLevel(x, y, SND_ROBOT_WHEEL_ACTIVE);
+}
- Feld[x][y] = EL_ABLENK_AUS;
- DrawLevelField(x, y);
- if (ZX == x && ZY == y)
- ZX = ZY = -1;
-}
-
-void TimegateWheel(int x, int y)
+static void StopRobotWheel(int x, int y)
{
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = level.time_wheel * FRAMES_PER_SECOND;
-
- if (MovDelay[x][y]) /* wait some time before next frame */
- {
- MovDelay[x][y]--;
- if (MovDelay[x][y])
- {
- if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y),
- GFX_TIMEGATE_SWITCH + MovDelay[x][y]%4);
- if (!(MovDelay[x][y]%4))
- PlaySoundLevel(x, y, SND_TIMEGATE_WHEEL_RUNNING);
- return;
- }
- }
-
- Feld[x][y] = EL_TIMEGATE_SWITCH_OFF;
- DrawLevelField(x, y);
if (ZX == x && ZY == y)
ZX = ZY = -1;
}
-void Birne(int x, int y)
+static void InitTimegateWheel(int x, int y)
{
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 800;
-
- if (MovDelay[x][y]) /* wait some time before next frame */
- {
- MovDelay[x][y]--;
- if (MovDelay[x][y])
- {
- if (!(MovDelay[x][y]%5))
- {
- if (!(MovDelay[x][y]%10))
- Feld[x][y]=EL_ABLENK_EIN;
- else
- Feld[x][y]=EL_ABLENK_AUS;
- DrawLevelField(x, y);
- Feld[x][y]=EL_ABLENK_EIN;
- }
- return;
- }
- }
-
- Feld[x][y]=EL_ABLENK_AUS;
- DrawLevelField(x, y);
- if (ZX == x && ZY == y)
- ZX=ZY=-1;
+ ChangeDelay[x][y] = level.time_wheel * FRAMES_PER_SECOND;
}
-void Blubber(int x, int y)
+static void RunTimegateWheel(int x, int y)
{
- if (y > 0 && IS_MOVING(x, y-1) && MovDir[x][y-1] == MV_DOWN)
- DrawLevelField(x, y-1);
- else
- DrawGraphicAnimation(x, y, GFX_GEBLUBBER, 4, 10, ANIM_NORMAL);
+ PlaySoundLevel(x, y, SND_TIMEGATE_SWITCH_ACTIVE);
}
-void NussKnacken(int x, int y)
+void CheckExit(int x, int y)
{
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 7;
-
- if (MovDelay[x][y]) /* wait some time before next frame */
+ if (local_player->gems_still_needed > 0 ||
+ local_player->sokobanfields_still_needed > 0 ||
+ local_player->lights_still_needed > 0)
{
- MovDelay[x][y]--;
- if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y),
- GFX_CRACKINGNUT + 3 - MovDelay[x][y]/2);
+ int element = Feld[x][y];
+ int graphic = el2img(element);
- if (!MovDelay[x][y])
- {
- Feld[x][y] = EL_EDELSTEIN;
- DrawLevelField(x, y);
- }
- }
-}
+ if (IS_ANIMATED(graphic))
+ DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
-void BreakingPearl(int x, int y)
-{
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 9;
-
- if (MovDelay[x][y]) /* wait some time before next frame */
- {
- MovDelay[x][y]--;
- if (MovDelay[x][y]/2 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y),
- GFX_PEARL_BREAKING + 4 - MovDelay[x][y]/2);
-
- if (!MovDelay[x][y])
- {
- Feld[x][y] = EL_LEERRAUM;
- DrawLevelField(x, y);
- }
- }
-}
-
-void SiebAktivieren(int x, int y, int typ)
-{
- int graphic = (typ == 1 ? GFX_MAGIC_WALL_FULL : GFX_MAGIC_WALL_BD_FULL) + 3;
-
- DrawGraphicAnimation(x, y, graphic, 4, 4, ANIM_REVERSE);
-}
-
-void AusgangstuerPruefen(int x, int y)
-{
- if (!local_player->gems_still_needed &&
- !local_player->sokobanfields_still_needed &&
- !local_player->lights_still_needed)
- {
- Feld[x][y] = EL_AUSGANG_ACT;
-
- PlaySoundLevel(x < LEVELX(BX1) ? LEVELX(BX1) :
- (x > LEVELX(BX2) ? LEVELX(BX2) : x),
- y < LEVELY(BY1) ? LEVELY(BY1) :
- (y > LEVELY(BY2) ? LEVELY(BY2) : y),
- SND_EXIT_OPENING);
- }
-}
-
-void AusgangstuerOeffnen(int x, int y)
-{
- int delay = 6;
-
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 5*delay;
-
- if (MovDelay[x][y]) /* wait some time before next frame */
- {
- int tuer;
-
- MovDelay[x][y]--;
- tuer = MovDelay[x][y]/delay;
- if (!(MovDelay[x][y]%delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_AUSGANG_AUF-tuer);
-
- if (!MovDelay[x][y])
- {
- Feld[x][y] = EL_AUSGANG_AUF;
- DrawLevelField(x, y);
- }
+ return;
}
-}
-
-void AusgangstuerBlinken(int x, int y)
-{
- DrawGraphicAnimation(x, y, GFX_AUSGANG_AUF, 4, 4, ANIM_OSCILLATE);
-}
-
-void OpenSwitchgate(int x, int y)
-{
- int delay = 6;
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 5 * delay;
-
- if (MovDelay[x][y]) /* wait some time before next frame */
- {
- int phase;
+ Feld[x][y] = EL_EXIT_OPENING;
- MovDelay[x][y]--;
- phase = MovDelay[x][y] / delay;
- if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_SWITCHGATE_OPEN - phase);
-
- if (!MovDelay[x][y])
- {
- Feld[x][y] = EL_SWITCHGATE_OPEN;
- DrawLevelField(x, y);
- }
- }
+ PlaySoundLevelNearest(x, y, SND_CLASS_EXIT_OPENING);
}
-void CloseSwitchgate(int x, int y)
+void CheckExitSP(int x, int y)
{
- int delay = 6;
-
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 5 * delay;
-
- if (MovDelay[x][y]) /* wait some time before next frame */
+ if (local_player->gems_still_needed > 0)
{
- int phase;
-
- MovDelay[x][y]--;
- phase = MovDelay[x][y] / delay;
- if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_SWITCHGATE_CLOSED + phase);
+ int element = Feld[x][y];
+ int graphic = el2img(element);
- if (!MovDelay[x][y])
- {
- Feld[x][y] = EL_SWITCHGATE_CLOSED;
- DrawLevelField(x, y);
- }
- }
-}
+ if (IS_ANIMATED(graphic))
+ DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
-void OpenTimegate(int x, int y)
-{
- int delay = 6;
-
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 5 * delay;
-
- if (MovDelay[x][y]) /* wait some time before next frame */
- {
- int phase;
-
- MovDelay[x][y]--;
- phase = MovDelay[x][y] / delay;
- if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_TIMEGATE_OPEN - phase);
-
- if (!MovDelay[x][y])
- {
- Feld[x][y] = EL_TIMEGATE_OPEN;
- DrawLevelField(x, y);
- }
+ return;
}
-}
-void CloseTimegate(int x, int y)
-{
- int delay = 6;
-
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 5 * delay;
-
- if (MovDelay[x][y]) /* wait some time before next frame */
- {
- int phase;
+ Feld[x][y] = EL_SP_EXIT_OPEN;
- MovDelay[x][y]--;
- phase = MovDelay[x][y] / delay;
- if (!(MovDelay[x][y] % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_TIMEGATE_CLOSED + phase);
-
- if (!MovDelay[x][y])
- {
- Feld[x][y] = EL_TIMEGATE_CLOSED;
- DrawLevelField(x, y);
- }
- }
+ PlaySoundLevelNearest(x, y, SND_CLASS_SP_EXIT_OPENING);
}
static void CloseAllOpenTimegates()
if (element == EL_TIMEGATE_OPEN || element == EL_TIMEGATE_OPENING)
{
Feld[x][y] = EL_TIMEGATE_CLOSING;
+#if 1
+ PlaySoundLevelAction(x, y, ACTION_CLOSING);
+#else
PlaySoundLevel(x, y, SND_TIMEGATE_CLOSING);
+#endif
}
}
}
if (!IN_SCR_FIELD(SCREENX(x), SCREENY(y)) || IS_MOVING(x, y))
return;
- if (Feld[x][y] == EL_EDELSTEIN_BD)
- DrawGraphicAnimation(x, y, GFX_EDELSTEIN_BD, 4, 4, ANIM_REVERSE);
- else
- {
- if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 11 * !SimpleRND(500);
+ if (Feld[x][y] == EL_BD_DIAMOND)
+ return;
- if (MovDelay[x][y]) /* wait some time before next frame */
- {
- MovDelay[x][y]--;
+ if (MovDelay[x][y] == 0) /* next animation frame */
+ MovDelay[x][y] = 11 * !SimpleRND(500);
- if (setup.direct_draw && MovDelay[x][y])
- SetDrawtoField(DRAW_BUFFERED);
+ if (MovDelay[x][y] != 0) /* wait some time before next frame */
+ {
+ MovDelay[x][y]--;
- DrawGraphic(SCREENX(x), SCREENY(y), el2gfx(Feld[x][y]));
+ if (setup.direct_draw && MovDelay[x][y])
+ SetDrawtoField(DRAW_BUFFERED);
- if (MovDelay[x][y])
- {
- int phase = (MovDelay[x][y]-1)/2;
+ DrawLevelElementAnimation(x, y, Feld[x][y]);
- if (phase > 2)
- phase = 4-phase;
+ if (MovDelay[x][y] != 0)
+ {
+ int frame = getGraphicAnimationFrame(IMG_TWINKLE_WHITE,
+ 10 - MovDelay[x][y]);
- DrawGraphicThruMask(SCREENX(x), SCREENY(y), GFX_FUNKELN_WEISS + phase);
+ DrawGraphicThruMask(SCREENX(x), SCREENY(y), IMG_TWINKLE_WHITE, frame);
- if (setup.direct_draw)
- {
- int dest_x, dest_y;
+ if (setup.direct_draw)
+ {
+ int dest_x, dest_y;
- dest_x = FX + SCREENX(x)*TILEX;
- dest_y = FY + SCREENY(y)*TILEY;
+ dest_x = FX + SCREENX(x) * TILEX;
+ dest_y = FY + SCREENY(y) * TILEY;
- BlitBitmap(drawto_field, window,
- dest_x, dest_y, TILEX, TILEY, dest_x, dest_y);
- SetDrawtoField(DRAW_DIRECT);
- }
+ BlitBitmap(drawto_field, window,
+ dest_x, dest_y, TILEX, TILEY, dest_x, dest_y);
+ SetDrawtoField(DRAW_DIRECT);
}
}
}
int delay = 6;
if (!MovDelay[x][y]) /* next animation frame */
- MovDelay[x][y] = 3*delay;
+ MovDelay[x][y] = 3 * delay;
if (MovDelay[x][y]) /* wait some time before next frame */
{
- int phase;
-
MovDelay[x][y]--;
- phase = 2-MovDelay[x][y]/delay;
- if (!(MovDelay[x][y]%delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y),
- (MovDir[x][y] == MV_LEFT ? GFX_MAUER_LEFT :
- MovDir[x][y] == MV_RIGHT ? GFX_MAUER_RIGHT :
- MovDir[x][y] == MV_UP ? GFX_MAUER_UP :
- GFX_MAUER_DOWN ) + phase);
+
+ if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+ {
+ int graphic = el_dir2img(Feld[x][y], MovDir[x][y]);
+ int frame = getGraphicAnimationFrame(graphic, 17 - MovDelay[x][y]);
+
+ DrawGraphic(SCREENX(x), SCREENY(y), graphic, frame);
+ }
if (!MovDelay[x][y])
{
if (MovDir[x][y] == MV_LEFT)
{
- if (IN_LEV_FIELD(x-1, y) && IS_MAUER(Feld[x-1][y]))
- DrawLevelField(x-1, y);
+ if (IN_LEV_FIELD(x - 1, y) && IS_WALL(Feld[x - 1][y]))
+ DrawLevelField(x - 1, y);
}
else if (MovDir[x][y] == MV_RIGHT)
{
- if (IN_LEV_FIELD(x+1, y) && IS_MAUER(Feld[x+1][y]))
- DrawLevelField(x+1, y);
+ if (IN_LEV_FIELD(x + 1, y) && IS_WALL(Feld[x + 1][y]))
+ DrawLevelField(x + 1, y);
}
else if (MovDir[x][y] == MV_UP)
{
- if (IN_LEV_FIELD(x, y-1) && IS_MAUER(Feld[x][y-1]))
- DrawLevelField(x, y-1);
+ if (IN_LEV_FIELD(x, y - 1) && IS_WALL(Feld[x][y - 1]))
+ DrawLevelField(x, y - 1);
}
else
{
- if (IN_LEV_FIELD(x, y+1) && IS_MAUER(Feld[x][y+1]))
- DrawLevelField(x, y+1);
+ if (IN_LEV_FIELD(x, y + 1) && IS_WALL(Feld[x][y + 1]))
+ DrawLevelField(x, y + 1);
}
Feld[x][y] = Store[x][y];
void MauerAbleger(int ax, int ay)
{
int element = Feld[ax][ay];
+ int graphic = el2img(element);
boolean oben_frei = FALSE, unten_frei = FALSE;
boolean links_frei = FALSE, rechts_frei = FALSE;
boolean oben_massiv = FALSE, unten_massiv = FALSE;
boolean links_massiv = FALSE, rechts_massiv = FALSE;
boolean new_wall = FALSE;
+ if (IS_ANIMATED(graphic))
+ DrawLevelGraphicAnimationIfNeeded(ax, ay, graphic);
+
if (!MovDelay[ax][ay]) /* start building new wall */
MovDelay[ax][ay] = 6;
if (IN_LEV_FIELD(ax+1, ay) && IS_FREE(ax+1, ay))
rechts_frei = TRUE;
- if (element == EL_MAUER_Y || element == EL_MAUER_XY)
+ if (element == EL_EXPANDABLE_WALL_VERTICAL ||
+ element == EL_EXPANDABLE_WALL_ANY)
{
if (oben_frei)
{
- Feld[ax][ay-1] = EL_MAUERND;
+ Feld[ax][ay-1] = EL_EXPANDABLE_WALL_GROWING;
Store[ax][ay-1] = element;
MovDir[ax][ay-1] = MV_UP;
if (IN_SCR_FIELD(SCREENX(ax), SCREENY(ay-1)))
- DrawGraphic(SCREENX(ax), SCREENY(ay-1), GFX_MAUER_UP);
+ DrawGraphic(SCREENX(ax), SCREENY(ay - 1),
+ IMG_EXPANDABLE_WALL_GROWING_UP, 0);
new_wall = TRUE;
}
if (unten_frei)
{
- Feld[ax][ay+1] = EL_MAUERND;
+ Feld[ax][ay+1] = EL_EXPANDABLE_WALL_GROWING;
Store[ax][ay+1] = element;
MovDir[ax][ay+1] = MV_DOWN;
if (IN_SCR_FIELD(SCREENX(ax), SCREENY(ay+1)))
- DrawGraphic(SCREENX(ax), SCREENY(ay+1), GFX_MAUER_DOWN);
+ DrawGraphic(SCREENX(ax), SCREENY(ay + 1),
+ IMG_EXPANDABLE_WALL_GROWING_DOWN, 0);
new_wall = TRUE;
}
}
- if (element == EL_MAUER_X || element == EL_MAUER_XY ||
- element == EL_MAUER_LEBT)
+ if (element == EL_EXPANDABLE_WALL_HORIZONTAL ||
+ element == EL_EXPANDABLE_WALL_ANY ||
+ element == EL_EXPANDABLE_WALL)
{
if (links_frei)
{
- Feld[ax-1][ay] = EL_MAUERND;
+ Feld[ax-1][ay] = EL_EXPANDABLE_WALL_GROWING;
Store[ax-1][ay] = element;
MovDir[ax-1][ay] = MV_LEFT;
if (IN_SCR_FIELD(SCREENX(ax-1), SCREENY(ay)))
- DrawGraphic(SCREENX(ax-1), SCREENY(ay), GFX_MAUER_LEFT);
+ DrawGraphic(SCREENX(ax - 1), SCREENY(ay),
+ IMG_EXPANDABLE_WALL_GROWING_LEFT, 0);
new_wall = TRUE;
}
if (rechts_frei)
{
- Feld[ax+1][ay] = EL_MAUERND;
+ Feld[ax+1][ay] = EL_EXPANDABLE_WALL_GROWING;
Store[ax+1][ay] = element;
MovDir[ax+1][ay] = MV_RIGHT;
if (IN_SCR_FIELD(SCREENX(ax+1), SCREENY(ay)))
- DrawGraphic(SCREENX(ax+1), SCREENY(ay), GFX_MAUER_RIGHT);
+ DrawGraphic(SCREENX(ax + 1), SCREENY(ay),
+ IMG_EXPANDABLE_WALL_GROWING_RIGHT, 0);
new_wall = TRUE;
}
}
- if (element == EL_MAUER_LEBT && (links_frei || rechts_frei))
+ if (element == EL_EXPANDABLE_WALL && (links_frei || rechts_frei))
DrawLevelField(ax, ay);
- if (!IN_LEV_FIELD(ax, ay-1) || IS_MAUER(Feld[ax][ay-1]))
+ if (!IN_LEV_FIELD(ax, ay-1) || IS_WALL(Feld[ax][ay-1]))
oben_massiv = TRUE;
- if (!IN_LEV_FIELD(ax, ay+1) || IS_MAUER(Feld[ax][ay+1]))
+ if (!IN_LEV_FIELD(ax, ay+1) || IS_WALL(Feld[ax][ay+1]))
unten_massiv = TRUE;
- if (!IN_LEV_FIELD(ax-1, ay) || IS_MAUER(Feld[ax-1][ay]))
+ if (!IN_LEV_FIELD(ax-1, ay) || IS_WALL(Feld[ax-1][ay]))
links_massiv = TRUE;
- if (!IN_LEV_FIELD(ax+1, ay) || IS_MAUER(Feld[ax+1][ay]))
+ if (!IN_LEV_FIELD(ax+1, ay) || IS_WALL(Feld[ax+1][ay]))
rechts_massiv = TRUE;
if (((oben_massiv && unten_massiv) ||
- element == EL_MAUER_X || element == EL_MAUER_LEBT) &&
+ element == EL_EXPANDABLE_WALL_HORIZONTAL ||
+ element == EL_EXPANDABLE_WALL) &&
((links_massiv && rechts_massiv) ||
- element == EL_MAUER_Y))
- Feld[ax][ay] = EL_MAUERWERK;
+ element == EL_EXPANDABLE_WALL_VERTICAL))
+ Feld[ax][ay] = EL_WALL;
if (new_wall)
- PlaySoundLevel(ax, ay, SND_WALL_GROWING);
+#if 1
+ PlaySoundLevelAction(ax, ay, ACTION_GROWING);
+#else
+ PlaySoundLevel(ax, ay, SND_EXPANDABLE_WALL_GROWING);
+#endif
}
void CheckForDragon(int x, int y)
int xx = x + j*xy[i][0], yy = y + j*xy[i][1];
if (IN_LEV_FIELD(xx, yy) &&
- (Feld[xx][yy] == EL_BURNING || Feld[xx][yy] == EL_DRACHE))
+ (Feld[xx][yy] == EL_FLAMES || Feld[xx][yy] == EL_DRAGON))
{
- if (Feld[xx][yy] == EL_DRACHE)
+ if (Feld[xx][yy] == EL_DRAGON)
dragon_found = TRUE;
}
else
{
int xx = x + j*xy[i][0], yy = y + j*xy[i][1];
- if (IN_LEV_FIELD(xx, yy) && Feld[xx][yy] == EL_BURNING)
+ if (IN_LEV_FIELD(xx, yy) && Feld[xx][yy] == EL_FLAMES)
{
- Feld[xx][yy] = EL_LEERRAUM;
+ Feld[xx][yy] = EL_EMPTY;
DrawLevelField(xx, yy);
}
else
}
}
-static void CheckBuggyBase(int x, int y)
+static void InitBuggyBase(int x, int y)
{
int element = Feld[x][y];
+ int activating_delay = FRAMES_PER_SECOND / 4;
+
+ ChangeDelay[x][y] =
+ (element == EL_SP_BUGGY_BASE ?
+ 2 * FRAMES_PER_SECOND + RND(5 * FRAMES_PER_SECOND) - activating_delay :
+ element == EL_SP_BUGGY_BASE_ACTIVATING ?
+ activating_delay :
+ element == EL_SP_BUGGY_BASE_ACTIVE ?
+ 1 * FRAMES_PER_SECOND + RND(1 * FRAMES_PER_SECOND) : 1);
+}
+
+static void WarnBuggyBase(int x, int y)
+{
+ int i;
+ static int xy[4][2] =
+ {
+ { 0, -1 },
+ { -1, 0 },
+ { +1, 0 },
+ { 0, +1 }
+ };
- if (element == EL_SP_BUG)
+ for (i=0; i<4; i++)
{
- if (!MovDelay[x][y]) /* wait some time before activating base */
- MovDelay[x][y] = 2 * FRAMES_PER_SECOND + RND(5 * FRAMES_PER_SECOND);
+ int xx = x + xy[i][0], yy = y + xy[i][1];
- if (MovDelay[x][y])
+ if (IS_PLAYER(xx, yy))
{
- MovDelay[x][y]--;
- if (MovDelay[x][y] < 5 && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x), SCREENY(y), GFX_SP_BUG_WARNING);
- if (MovDelay[x][y])
- return;
+ PlaySoundLevel(x, y, SND_SP_BUGGY_BASE_ACTIVE);
- Feld[x][y] = EL_SP_BUG_ACTIVE;
+ break;
}
}
- else if (element == EL_SP_BUG_ACTIVE)
+}
+
+static void InitTrap(int x, int y)
+{
+ ChangeDelay[x][y] = 2 * FRAMES_PER_SECOND + RND(5 * FRAMES_PER_SECOND);
+}
+
+static void ActivateTrap(int x, int y)
+{
+ PlaySoundLevel(x, y, SND_TRAP_ACTIVATING);
+}
+
+static void ChangeActiveTrap(int x, int y)
+{
+ int graphic = IMG_TRAP_ACTIVE;
+
+ /* if new animation frame was drawn, correct crumbled sand border */
+ if (IS_NEW_FRAME(GfxFrame[x][y], graphic))
+ DrawLevelFieldCrumbledSand(x, y);
+}
+
+static void ChangeElementNowExt(int x, int y, int target_element)
+{
+ if (IS_PLAYER(x, y) && !IS_ACCESSIBLE(target_element))
+ {
+ Bang(x, y);
+ return;
+ }
+
+ RemoveField(x, y);
+ Feld[x][y] = target_element;
+
+ ResetGfxAnimation(x, y);
+ ResetRandomAnimationValue(x, y);
+
+ InitField(x, y, FALSE);
+ if (CAN_MOVE(Feld[x][y]))
+ InitMovDir(x, y);
+
+ DrawLevelField(x, y);
+
+ if (CAN_BE_CRUMBLED(Feld[x][y]))
+ DrawLevelFieldCrumbledSandNeighbours(x, y);
+
+ TestIfBadThingTouchesHero(x, y);
+ TestIfPlayerTouchesCustomElement(x, y);
+ TestIfElementTouchesCustomElement(x, y);
+}
+
+static void ChangeElementNow(int x, int y, int element)
+{
+ struct ElementChangeInfo *change = &element_info[element].change;
+
+ /* prevent CheckTriggeredElementChange() from looping */
+ Changing[x][y] = TRUE;
+
+ CheckTriggeredElementChange(x, y, Feld[x][y], CE_OTHER_IS_CHANGING);
+
+ Changing[x][y] = FALSE;
+
+ if (change->explode)
+ {
+ Bang(x, y);
+ return;
+ }
+
+ if (change->use_content)
{
- if (!MovDelay[x][y]) /* start activating buggy base */
- MovDelay[x][y] = 1 * FRAMES_PER_SECOND + RND(1 * FRAMES_PER_SECOND);
+ boolean complete_change = TRUE;
+ boolean can_change[3][3];
+ int xx, yy;
- if (MovDelay[x][y])
+ for (yy = 0; yy < 3; yy++) for(xx = 0; xx < 3 ; xx++)
{
- MovDelay[x][y]--;
- if (MovDelay[x][y])
+ boolean half_destructible;
+ int ex = x + xx - 1;
+ int ey = y + yy - 1;
+ int e;
+
+ can_change[xx][yy] = TRUE;
+
+ if (ex == x && ey == y) /* do not check changing element itself */
+ continue;
+
+ if (change->content[xx][yy] == EL_EMPTY_SPACE)
{
- int i;
- static int xy[4][2] =
- {
- { 0, -1 },
- { -1, 0 },
- { +1, 0 },
- { 0, +1 }
- };
+ can_change[xx][yy] = FALSE; /* do not change empty borders */
- if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- DrawGraphic(SCREENX(x),SCREENY(y), GFX_SP_BUG_ACTIVE + SimpleRND(4));
+ continue;
+ }
- for (i=0; i<4; i++)
- {
- int xx = x + xy[i][0], yy = y + xy[i][1];
+ if (!IN_LEV_FIELD(ex, ey))
+ {
+ can_change[xx][yy] = FALSE;
+ complete_change = FALSE;
- if (IS_PLAYER(xx, yy))
- {
- PlaySoundLevel(x, y, SND_SP_BUGGY_BASE_ACTIVATING);
- break;
- }
- }
+ continue;
+ }
+
+ e = Feld[ex][ey];
+
+ if (IS_MOVING(ex, ey) || IS_BLOCKED(ex, ey))
+ e = MovingOrBlocked2Element(ex, ey);
+
+ half_destructible = (IS_FREE(ex, ey) || IS_DIGGABLE(e));
+
+ if ((change->power <= CP_NON_DESTRUCTIVE && !IS_FREE(ex, ey)) ||
+ (change->power <= CP_HALF_DESTRUCTIVE && !half_destructible) ||
+ (change->power <= CP_FULL_DESTRUCTIVE && IS_INDESTRUCTIBLE(e)))
+ {
+ can_change[xx][yy] = FALSE;
+ complete_change = FALSE;
+ }
+ }
+
+ if (!change->only_complete || complete_change)
+ {
+ boolean something_has_changed = FALSE;
+ if (change->only_complete && change->use_random_change &&
+ RND(100) < change->random)
return;
+
+ for (yy = 0; yy < 3; yy++) for(xx = 0; xx < 3 ; xx++)
+ {
+ int ex = x + xx - 1;
+ int ey = y + yy - 1;
+
+ if (can_change[xx][yy] && (!change->use_random_change ||
+ RND(100) < change->random))
+ {
+ if (IS_MOVING(ex, ey) || IS_BLOCKED(ex, ey))
+ RemoveMovingField(ex, ey);
+
+ ChangeElementNowExt(ex, ey, change->content[xx][yy]);
+
+ something_has_changed = TRUE;
+
+ /* for symmetry reasons, stop newly created border elements */
+ if (ex != x || ey != y)
+ Stop[ex][ey] = TRUE;
+ }
}
- Feld[x][y] = EL_SP_BUG;
- DrawLevelField(x, y);
+ if (something_has_changed)
+ PlaySoundLevelElementAction(x, y, element, ACTION_CHANGING);
}
}
+ else
+ {
+ ChangeElementNowExt(x, y, change->target_element);
+
+ PlaySoundLevelElementAction(x, y, element, ACTION_CHANGING);
+ }
}
-static void CheckTrap(int x, int y)
+static void ChangeElement(int x, int y)
{
+#if 1
+ int element = MovingOrBlocked2Element(x, y);
+#else
int element = Feld[x][y];
+#endif
+ struct ElementChangeInfo *change = &element_info[element].change;
- if (element == EL_TRAP_INACTIVE)
+ if (ChangeDelay[x][y] == 0) /* initialize element change */
{
- if (!MovDelay[x][y]) /* wait some time before activating trap */
- MovDelay[x][y] = 2 * FRAMES_PER_SECOND + RND(5 * FRAMES_PER_SECOND);
+#if 1
+ ChangeDelay[x][y] = ( change->delay_fixed * change->delay_frames +
+ RND(change->delay_random * change->delay_frames)) + 1;
+#else
+ ChangeDelay[x][y] = changing_element[element].change_delay + 1;
- if (MovDelay[x][y])
+ if (IS_CUSTOM_ELEMENT(element) && HAS_CHANGE_EVENT(element, CE_DELAY))
{
- MovDelay[x][y]--;
- if (MovDelay[x][y])
- return;
+ int max_random_delay = element_info[element].change.delay_random;
+ int delay_frames = element_info[element].change.delay_frames;
- Feld[x][y] = EL_TRAP_ACTIVE;
- PlaySoundLevel(x, y, SND_TRAP_ACTIVATING);
+ ChangeDelay[x][y] += RND(max_random_delay * delay_frames);
}
+#endif
+
+ ResetGfxAnimation(x, y);
+ ResetRandomAnimationValue(x, y);
+
+#if 1
+ if (change->pre_change_function)
+ change->pre_change_function(x, y);
+#else
+ if (changing_element[element].pre_change_function)
+ changing_element[element].pre_change_function(x, y);
+#endif
}
- else if (element == EL_TRAP_ACTIVE)
+
+ ChangeDelay[x][y]--;
+
+ if (ChangeDelay[x][y] != 0) /* continue element change */
{
- int delay = 4;
- int num_frames = 8;
+ int graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]);
- if (!MovDelay[x][y]) /* start activating trap */
- MovDelay[x][y] = num_frames * delay;
+ if (IS_ANIMATED(graphic))
+ DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
- if (MovDelay[x][y])
- {
- MovDelay[x][y]--;
+#if 1
+ if (change->change_function)
+ change->change_function(x, y);
+#else
+ if (changing_element[element].change_function)
+ changing_element[element].change_function(x, y);
+#endif
+ }
+ else /* finish element change */
+ {
+#if 0
+ int next_element = changing_element[element].next_element;
+#endif
- if (MovDelay[x][y])
- {
- if (!(MovDelay[x][y] % delay))
- {
- int phase = MovDelay[x][y]/delay;
+ if (IS_MOVING(x, y)) /* never change a running system ;-) */
+ {
+ ChangeDelay[x][y] = 1; /* try change after next move step */
- if (phase >= num_frames/2)
- phase = num_frames - phase;
+ return;
+ }
- if (IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
- {
- DrawGraphic(SCREENX(x),SCREENY(y), GFX_TRAP_INACTIVE + phase - 1);
- ErdreichAnbroeckeln(SCREENX(x), SCREENY(y));
- }
- }
+#if 1
+ ChangeElementNow(x, y, element);
- return;
- }
+ if (change->post_change_function)
+ change->post_change_function(x, y);
+#else
+ if (next_element != EL_UNDEFINED)
+ ChangeElementNow(x, y, next_element);
+ else
+ ChangeElementNow(x, y, element_info[element].change.target_element);
- Feld[x][y] = EL_TRAP_INACTIVE;
- DrawLevelField(x, y);
- }
+ if (changing_element[element].post_change_function)
+ changing_element[element].post_change_function(x, y);
+#endif
}
}
-static void DrawBeltAnimation(int x, int y, int element)
+static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element,
+ int trigger_event)
{
- int belt_nr = getBeltNrFromElement(element);
- int belt_dir = game.belt_dir[belt_nr];
+ int i, x, y;
- if (belt_dir != MV_NO_MOVING)
+ if (!(trigger_events[trigger_element] & CH_EVENT_BIT(trigger_event)))
+ return FALSE;
+
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
{
- int delay = 2;
- int mode = (belt_dir == MV_LEFT ? ANIM_NORMAL : ANIM_REVERSE);
- int graphic = el2gfx(element) + (belt_dir == MV_LEFT ? 0 : 7);
+ if (!CAN_CHANGE(i) || !HAS_CHANGE_EVENT(i, trigger_event) ||
+ element_info[i].change.trigger_element != trigger_element)
+ continue;
- DrawGraphicAnimation(x, y, graphic, 8, delay, mode);
+ for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
+ {
+ if (x == lx && y == ly) /* do not change trigger element itself */
+ continue;
+
+ if (Changing[x][y]) /* do not change just changing elements */
+ continue;
- if (!(FrameCounter % 2))
- PlaySoundLevel(x, y, SND_CONVEYOR_BELT_RUNNING);
+ if (Feld[x][y] == i)
+ {
+ ChangeDelay[x][y] = 1;
+ ChangeElement(x, y);
+ }
+ }
}
+
+ return TRUE;
+}
+
+static boolean CheckElementChange(int x, int y, int element, int trigger_event)
+{
+ if (!CAN_CHANGE(element) || !HAS_CHANGE_EVENT(element, trigger_event))
+ return FALSE;
+
+ if (Feld[x][y] == EL_BLOCKED)
+ Blocked2Moving(x, y, &x, &y);
+
+ ChangeDelay[x][y] = 1;
+ ChangeElement(x, y);
+
+ return TRUE;
}
static void PlayerActions(struct PlayerInfo *player, byte player_action)
{
static byte stored_player_action[MAX_PLAYERS];
static int num_stored_actions = 0;
-#if 0
- static boolean save_tape_entry = FALSE;
-#endif
boolean moved = FALSE, snapped = FALSE, bombed = FALSE;
int left = player_action & JOY_LEFT;
int right = player_action & JOY_RIGHT;
if (player_action)
{
-#if 0
- save_tape_entry = TRUE;
-#endif
- player->frame_reset_delay = 0;
-
if (button1)
snapped = SnapField(player, dx, dy);
else
}
}
-#if 0
- if (tape.recording && (moved || snapped || bombed))
- {
- if (bombed && !moved)
- player_action &= JOY_BUTTON;
-
- stored_player_action[player->index_nr] = player_action;
- save_tape_entry = TRUE;
- }
- else if (tape.playing && snapped)
- SnapField(player, 0, 0); /* stop snapping */
-#else
stored_player_action[player->index_nr] = player_action;
-#endif
}
else
{
SnapField(player, 0, 0);
CheckGravityMovement(player);
-#if 1
- if (player->MovPos == 0) /* needed for tape.playing */
- player->is_moving = FALSE;
-#endif
+ if (player->MovPos == 0)
+ {
#if 0
- if (player->MovPos == 0) /* needed for tape.playing */
- player->last_move_dir = MV_NO_MOVING;
-
- /* !!! CHECK THIS AGAIN !!!
- (Seems to be needed for some EL_ROBOT stuff, but breaks
- tapes when walking through pipes!)
- */
+ printf("Trying... Player frame reset\n");
+#endif
- /* it seems that "player->last_move_dir" is misused as some sort of
- "player->is_just_moving_in_this_moment", which is needed for the
- robot stuff (robots don't kill players when they are moving)
- */
-#endif
+ InitPlayerGfxAnimation(player, ACTION_DEFAULT, player->MovDir);
+ }
- if (++player->frame_reset_delay > player->move_delay_value)
- player->Frame = 0;
+ if (player->MovPos == 0) /* needed for tape.playing */
+ player->is_moving = FALSE;
}
-#if 0
- if (tape.recording && num_stored_actions >= MAX_PLAYERS && save_tape_entry)
- {
- TapeRecordAction(stored_player_action);
- num_stored_actions = 0;
- save_tape_entry = FALSE;
- }
-#else
if (tape.recording && num_stored_actions >= MAX_PLAYERS)
{
TapeRecordAction(stored_player_action);
num_stored_actions = 0;
}
-#endif
-
-#if 0
- if (tape.playing && !tape.pausing && !player_action &&
- tape.counter < tape.length)
- {
- int jx = player->jx, jy = player->jy;
- int next_joy =
- tape.pos[tape.counter].action[player->index_nr] & (JOY_LEFT|JOY_RIGHT);
-
- if ((next_joy == JOY_LEFT || next_joy == JOY_RIGHT) &&
- (player->MovDir != JOY_UP && player->MovDir != JOY_DOWN))
- {
- int dx = (next_joy == JOY_LEFT ? -1 : +1);
-
- if (IN_LEV_FIELD(jx+dx, jy) && IS_PUSHABLE(Feld[jx+dx][jy]))
- {
- int el = Feld[jx+dx][jy];
- int push_delay = (IS_SB_ELEMENT(el) || el == EL_SONDE ? 2 :
- (el == EL_BALLOON || el == EL_SPRING) ? 0 : 10);
-
- if (tape.delay_played + push_delay >= tape.pos[tape.counter].delay)
- {
- player->MovDir = next_joy;
- player->Frame = FrameCounter % 4;
- player->Pushing = TRUE;
- }
- }
- }
- }
-#endif
}
void GameActions()
{
static unsigned long action_delay = 0;
unsigned long action_delay_value;
- int sieb_x = 0, sieb_y = 0;
- int i, x, y, element;
+ int magic_wall_x = 0, magic_wall_y = 0;
+ int i, x, y, element, graphic;
byte *recorded_player_action;
byte summarized_player_action = 0;
- if (game_status != PLAYING)
+ if (game_status != GAME_MODE_PLAYING)
return;
action_delay_value =
HandleNetworking();
#endif
- if (game_status != PLAYING)
+ if (game_status != GAME_MODE_PLAYING)
return;
if (!network_player_action_received)
ScrollScreen(NULL, SCROLL_GO_ON);
-
-
-#ifdef DEBUG
#if 0
- if (TimeFrames == 0 && local_player->active)
- {
- extern unsigned int last_RND();
-
- printf("DEBUG: %03d last RND was %d \t [state checksum is %d]\n",
- TimePlayed, last_RND(), getStateCheckSum(TimePlayed));
- }
-#endif
-#endif
+ FrameCounter++;
+ TimeFrames++;
-#ifdef DEBUG
-#if 0
- if (GameFrameDelay >= 500)
- printf("FrameCounter == %d\n", FrameCounter);
-#endif
+ for (i=0; i<MAX_PLAYERS; i++)
+ stored_player[i].Frame++;
#endif
+#if 1
+ if (game.engine_version < RELEASE_IDENT(2,2,0,7))
+ {
+ for (i=0; i<MAX_PLAYERS; i++)
+ {
+ struct PlayerInfo *player = &stored_player[i];
+ int x = player->jx;
+ int y = player->jy;
+ if (player->active && player->Pushing && player->is_moving &&
+ IS_MOVING(x, y))
+ {
+ ContinueMoving(x, y);
- FrameCounter++;
- TimeFrames++;
+ /* continue moving after pushing (this is actually a bug) */
+ if (!IS_MOVING(x, y))
+ {
+ Stop[x][y] = FALSE;
+ }
+ }
+ }
+ }
+#endif
for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
{
if (JustStopped[x][y] > 0)
JustStopped[x][y]--;
+ GfxFrame[x][y]++;
+
+#if 1
+ /* reset finished pushing action (not done in ContinueMoving() to allow
+ continous pushing animation for elements without push delay) */
+ if (GfxAction[x][y] == ACTION_PUSHING && !IS_MOVING(x, y))
+ {
+ ResetGfxAnimation(x, y);
+ DrawLevelField(x, y);
+ }
+#endif
+
#if DEBUG
if (IS_BLOCKED(x, y))
{
for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
{
element = Feld[x][y];
+#if 1
+ graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]);
+#else
+ graphic = el2img(element);
+#endif
+
+#if 0
+ if (element == -1)
+ {
+ printf("::: %d,%d: %d [%d]\n", x, y, element, FrameCounter);
+
+ element = graphic = 0;
+ }
+#endif
+
+ if (graphic_info[graphic].anim_global_sync)
+ GfxFrame[x][y] = FrameCounter;
+
+ if (ANIM_MODE(graphic) == ANIM_RANDOM &&
+ IS_NEXT_FRAME(GfxFrame[x][y], graphic))
+ ResetRandomAnimationValue(x, y);
+
+ SetRandomAnimationValue(x, y);
+
+#if 1
+ PlaySoundLevelActionIfLoop(x, y, GfxAction[x][y]);
+#endif
if (IS_INACTIVE(element))
+ {
+ if (IS_ANIMATED(graphic))
+ DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
+
continue;
+ }
+
+#if 1
+ /* this may take place after moving, so 'element' may have changed */
+ if (IS_CHANGING(x, y))
+ {
+ ChangeElement(x, y);
+ element = Feld[x][y];
+ graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]);
+ }
+#endif
if (!IS_MOVING(x, y) && (CAN_FALL(element) || CAN_MOVE(element)))
{
StartMoving(x, y);
+#if 1
+ graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]);
+#if 0
+ if (element == EL_MOLE)
+ printf("::: %d, %d, %d [%d]\n",
+ IS_ANIMATED(graphic), IS_MOVING(x, y), Stop[x][y],
+ GfxAction[x][y]);
+#endif
+#if 0
+ if (element == EL_YAMYAM)
+ printf("::: %d, %d, %d\n",
+ IS_ANIMATED(graphic), IS_MOVING(x, y), Stop[x][y]);
+#endif
+#endif
+
+ if (IS_ANIMATED(graphic) &&
+ !IS_MOVING(x, y) &&
+ !Stop[x][y])
+ {
+ DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
+
+#if 0
+ if (element == EL_MOLE)
+ printf("::: %d, %d\n", graphic, GfxFrame[x][y]);
+#endif
+ }
+
if (IS_GEM(element) || element == EL_SP_INFOTRON)
EdelsteinFunkeln(x, y);
}
+ else if ((element == EL_ACID ||
+ element == EL_EXIT_OPEN ||
+ element == EL_SP_EXIT_OPEN ||
+ element == EL_SP_TERMINAL ||
+ element == EL_SP_TERMINAL_ACTIVE ||
+ element == EL_EXTRA_TIME ||
+ element == EL_SHIELD_NORMAL ||
+ element == EL_SHIELD_DEADLY) &&
+ IS_ANIMATED(graphic))
+ DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
else if (IS_MOVING(x, y))
ContinueMoving(x, y);
else if (IS_ACTIVE_BOMB(element))
CheckDynamite(x, y);
#if 0
- else if (element == EL_EXPLODING && !game.explosions_delayed)
- Explode(x, y, Frame[x][y], EX_NORMAL);
+ else if (element == EL_EXPLOSION && !game.explosions_delayed)
+ Explode(x, y, ExplodePhase[x][y], EX_NORMAL);
#endif
- else if (element == EL_AMOEBING)
+ else if (element == EL_AMOEBA_GROWING)
AmoebeWaechst(x, y);
- else if (element == EL_DEAMOEBING)
+ else if (element == EL_AMOEBA_SHRINKING)
AmoebaDisappearing(x, y);
#if !USE_NEW_AMOEBA_CODE
AmoebeAbleger(x, y);
#endif
- else if (element == EL_LIFE || element == EL_LIFE_ASYNC)
+ else if (element == EL_GAME_OF_LIFE || element == EL_BIOMAZE)
Life(x, y);
- else if (element == EL_ABLENK_EIN)
- RobotWheel(x, y);
- else if (element == EL_TIMEGATE_SWITCH_ON)
- TimegateWheel(x, y);
- else if (element == EL_SALZSAEURE)
- Blubber(x, y);
- else if (element == EL_BLURB_LEFT || element == EL_BLURB_RIGHT)
- Blurb(x, y);
- else if (element == EL_CRACKINGNUT)
- NussKnacken(x, y);
- else if (element == EL_PEARL_BREAKING)
- BreakingPearl(x, y);
- else if (element == EL_AUSGANG_ZU)
- AusgangstuerPruefen(x, y);
- else if (element == EL_AUSGANG_ACT)
- AusgangstuerOeffnen(x, y);
- else if (element == EL_AUSGANG_AUF)
- AusgangstuerBlinken(x, y);
- else if (element == EL_MAUERND)
+ else if (element == EL_EXIT_CLOSED)
+ CheckExit(x, y);
+ else if (element == EL_SP_EXIT_CLOSED)
+ CheckExitSP(x, y);
+ else if (element == EL_EXPANDABLE_WALL_GROWING)
MauerWaechst(x, y);
- else if (element == EL_MAUER_LEBT ||
- element == EL_MAUER_X ||
- element == EL_MAUER_Y ||
- element == EL_MAUER_XY)
+ else if (element == EL_EXPANDABLE_WALL ||
+ element == EL_EXPANDABLE_WALL_HORIZONTAL ||
+ element == EL_EXPANDABLE_WALL_VERTICAL ||
+ element == EL_EXPANDABLE_WALL_ANY)
MauerAbleger(x, y);
- else if (element == EL_BURNING)
+ else if (element == EL_FLAMES)
CheckForDragon(x, y);
- else if (element == EL_SP_BUG || element == EL_SP_BUG_ACTIVE)
- CheckBuggyBase(x, y);
- else if (element == EL_TRAP_INACTIVE || element == EL_TRAP_ACTIVE)
- CheckTrap(x, y);
- else if (element == EL_SP_TERMINAL)
- DrawGraphicAnimation(x, y, GFX2_SP_TERMINAL, 7, 12, ANIM_NORMAL);
- else if (element == EL_SP_TERMINAL_ACTIVE)
- DrawGraphicAnimation(x, y, GFX2_SP_TERMINAL_ACTIVE, 7, 4, ANIM_NORMAL);
- else if (IS_BELT(element))
- DrawBeltAnimation(x, y, element);
- else if (element == EL_SWITCHGATE_OPENING)
- OpenSwitchgate(x, y);
- else if (element == EL_SWITCHGATE_CLOSING)
- CloseSwitchgate(x, y);
- else if (element == EL_TIMEGATE_OPENING)
- OpenTimegate(x, y);
- else if (element == EL_TIMEGATE_CLOSING)
- CloseTimegate(x, y);
- else if (element == EL_EXTRA_TIME)
- DrawGraphicAnimation(x, y, GFX_EXTRA_TIME, 6, 4, ANIM_NORMAL);
- else if (element == EL_SHIELD_PASSIVE)
- {
- DrawGraphicAnimation(x, y, GFX_SHIELD_PASSIVE, 6, 4, ANIM_NORMAL);
#if 0
- if (!(FrameCounter % 4))
- PlaySoundLevel(x, y, SND_SHIELD_PASSIVE_ACTIVATED);
+ else if (IS_AUTO_CHANGING(element))
+ ChangeElement(x, y);
#endif
- }
- else if (element == EL_SHIELD_ACTIVE)
- {
- DrawGraphicAnimation(x, y, GFX_SHIELD_ACTIVE, 6, 4, ANIM_NORMAL);
+ else if (element == EL_EXPLOSION)
+ ; /* drawing of correct explosion animation is handled separately */
+ else if (IS_ANIMATED(graphic) && !IS_CHANGING(x, y))
+ DrawLevelGraphicAnimationIfNeeded(x, y, graphic);
+
#if 0
- if (!(FrameCounter % 4))
- PlaySoundLevel(x, y, SND_SHIELD_ACTIVE_ACTIVATED);
+ /* this may take place after moving, so 'element' may have changed */
+ if (IS_AUTO_CHANGING(Feld[x][y]))
+ ChangeElement(x, y);
#endif
- }
+
+ if (IS_BELT_ACTIVE(element))
+ PlaySoundLevelAction(x, y, ACTION_ACTIVE);
if (game.magic_wall_active)
{
- boolean sieb = FALSE;
int jx = local_player->jx, jy = local_player->jy;
- if (element == EL_MAGIC_WALL_FULL ||
- element == EL_MAGIC_WALL_EMPTY ||
- element == EL_MAGIC_WALL_EMPTYING)
- {
- SiebAktivieren(x, y, 1);
- sieb = TRUE;
- }
- else if (element == EL_MAGIC_WALL_BD_FULL ||
- element == EL_MAGIC_WALL_BD_EMPTY ||
- element == EL_MAGIC_WALL_BD_EMPTYING)
- {
- SiebAktivieren(x, y, 2);
- sieb = TRUE;
- }
-
/* play the element sound at the position nearest to the player */
- if (sieb && ABS(x-jx)+ABS(y-jy) < ABS(sieb_x-jx)+ABS(sieb_y-jy))
+ if ((element == EL_MAGIC_WALL_FULL ||
+ element == EL_MAGIC_WALL_ACTIVE ||
+ element == EL_MAGIC_WALL_EMPTYING ||
+ element == EL_BD_MAGIC_WALL_FULL ||
+ element == EL_BD_MAGIC_WALL_ACTIVE ||
+ element == EL_BD_MAGIC_WALL_EMPTYING) &&
+ ABS(x-jx) + ABS(y-jy) < ABS(magic_wall_x-jx) + ABS(magic_wall_y-jy))
{
- sieb_x = x;
- sieb_y = y;
+ magic_wall_x = x;
+ magic_wall_y = y;
}
}
}
#endif
element = Feld[x][y];
+ /* !!! extend EL_SAND to anything diggable (but maybe not SP_BASE) !!! */
if (!IS_PLAYER(x,y) &&
- (element == EL_LEERRAUM ||
- element == EL_ERDREICH ||
- element == EL_MORAST_LEER ||
- element == EL_BLURB_LEFT ||
- element == EL_BLURB_RIGHT))
+ (element == EL_EMPTY ||
+ element == EL_SAND ||
+ element == EL_QUICKSAND_EMPTY ||
+ element == EL_ACID_SPLASH_LEFT ||
+ element == EL_ACID_SPLASH_RIGHT))
{
- if ((IN_LEV_FIELD(x, y-1) && Feld[x][y-1] == EL_AMOEBE_NASS) ||
- (IN_LEV_FIELD(x-1, y) && Feld[x-1][y] == EL_AMOEBE_NASS) ||
- (IN_LEV_FIELD(x+1, y) && Feld[x+1][y] == EL_AMOEBE_NASS) ||
- (IN_LEV_FIELD(x, y+1) && Feld[x][y+1] == EL_AMOEBE_NASS))
- Feld[x][y] = EL_TROPFEN;
+ if ((IN_LEV_FIELD(x, y-1) && Feld[x][y-1] == EL_AMOEBA_WET) ||
+ (IN_LEV_FIELD(x-1, y) && Feld[x-1][y] == EL_AMOEBA_WET) ||
+ (IN_LEV_FIELD(x+1, y) && Feld[x+1][y] == EL_AMOEBA_WET) ||
+ (IN_LEV_FIELD(x, y+1) && Feld[x][y+1] == EL_AMOEBA_WET))
+ Feld[x][y] = EL_AMOEBA_DROP;
}
random = random * 129 + 1;
if (ExplodeField[x][y])
Explode(x, y, EX_PHASE_START, ExplodeField[x][y]);
- else if (element == EL_EXPLODING)
- Explode(x, y, Frame[x][y], EX_NORMAL);
+ else if (element == EL_EXPLOSION)
+ Explode(x, y, ExplodePhase[x][y], EX_NORMAL);
ExplodeField[x][y] = EX_NO_EXPLOSION;
}
{
if (!(game.magic_wall_time_left % 4))
{
- int element = Feld[sieb_x][sieb_y];
+ int element = Feld[magic_wall_x][magic_wall_y];
- if (element == EL_MAGIC_WALL_BD_FULL ||
- element == EL_MAGIC_WALL_BD_EMPTY ||
- element == EL_MAGIC_WALL_BD_EMPTYING)
- PlaySoundLevel(sieb_x, sieb_y, SND_BD_MAGIC_WALL_RUNNING);
+ if (element == EL_BD_MAGIC_WALL_FULL ||
+ element == EL_BD_MAGIC_WALL_ACTIVE ||
+ element == EL_BD_MAGIC_WALL_EMPTYING)
+ PlaySoundLevel(magic_wall_x, magic_wall_y, SND_BD_MAGIC_WALL_ACTIVE);
else
- PlaySoundLevel(sieb_x, sieb_y, SND_MAGIC_WALL_RUNNING);
+ PlaySoundLevel(magic_wall_x, magic_wall_y, SND_MAGIC_WALL_ACTIVE);
}
if (game.magic_wall_time_left > 0)
{
element = Feld[x][y];
- if (element == EL_MAGIC_WALL_EMPTY ||
+ if (element == EL_MAGIC_WALL_ACTIVE ||
element == EL_MAGIC_WALL_FULL)
{
Feld[x][y] = EL_MAGIC_WALL_DEAD;
DrawLevelField(x, y);
}
- else if (element == EL_MAGIC_WALL_BD_EMPTY ||
- element == EL_MAGIC_WALL_BD_FULL)
+ else if (element == EL_BD_MAGIC_WALL_ACTIVE ||
+ element == EL_BD_MAGIC_WALL_FULL)
{
- Feld[x][y] = EL_MAGIC_WALL_BD_DEAD;
+ Feld[x][y] = EL_BD_MAGIC_WALL_DEAD;
DrawLevelField(x, y);
}
}
{
game.light_time_left--;
- if (game.light_time_left == 0)
- {
- for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
- {
- element = Feld[x][y];
-
- if (element == EL_LIGHT_SWITCH_ON)
- {
- Feld[x][y] = EL_LIGHT_SWITCH_OFF;
- DrawLevelField(x, y);
- }
- else if (element == EL_INVISIBLE_STEEL ||
- element == EL_UNSICHTBAR ||
- element == EL_SAND_INVISIBLE)
- DrawLevelField(x, y);
- }
- }
+ if (game.light_time_left == 0)
+ RedrawAllLightSwitchesAndInvisibleElements();
}
if (game.timegate_time_left > 0)
if (SHIELD_ON(player))
{
- if (player->shield_active_time_left)
- PlaySoundLevel(player->jx, player->jy, SND_SHIELD_ACTIVE_ACTIVATED);
- else if (player->shield_passive_time_left)
- PlaySoundLevel(player->jx, player->jy, SND_SHIELD_PASSIVE_ACTIVATED);
+ if (player->shield_deadly_time_left)
+ PlaySoundLevel(player->jx, player->jy, SND_SHIELD_DEADLY_ACTIVE);
+ else if (player->shield_normal_time_left)
+ PlaySoundLevel(player->jx, player->jy, SND_SHIELD_NORMAL_ACTIVE);
}
}
if (SHIELD_ON(player))
{
- player->shield_passive_time_left--;
+ player->shield_normal_time_left--;
- if (player->shield_active_time_left > 0)
- player->shield_active_time_left--;
+ if (player->shield_deadly_time_left > 0)
+ player->shield_deadly_time_left--;
}
}
TimeLeft--;
if (TimeLeft <= 10 && setup.time_limit)
- PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MAX_RIGHT);
+ PlaySoundStereo(SND_GAME_RUNNING_OUT_OF_TIME, SOUND_MIDDLE);
- DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FS_SMALL, FC_YELLOW);
+ DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FONT_TEXT_2);
if (!TimeLeft && setup.time_limit)
for (i=0; i<MAX_PLAYERS; i++)
KillHero(&stored_player[i]);
}
else if (level.time == 0 && !AllPlayersGone) /* level without time limit */
- DrawText(DX_TIME, DY_TIME, int2str(TimePlayed, 3), FS_SMALL, FC_YELLOW);
+ DrawText(DX_TIME, DY_TIME, int2str(TimePlayed, 3), FONT_TEXT_2);
}
DrawAllPlayers();
redraw_mask |= REDRAW_FPS;
}
+
+#if 0
+ if (stored_player[0].jx != stored_player[0].last_jx ||
+ stored_player[0].jy != stored_player[0].last_jy)
+ printf("::: %d, %d, %d, %d, %d\n",
+ stored_player[0].MovDir,
+ stored_player[0].MovPos,
+ stored_player[0].GfxPos,
+ stored_player[0].Frame,
+ stored_player[0].StepFrame);
+#endif
+
+#if 1
+ FrameCounter++;
+ TimeFrames++;
+
+ for (i=0; i<MAX_PLAYERS; i++)
+ {
+ int move_frames =
+ MOVE_DELAY_NORMAL_SPEED / stored_player[i].move_delay_value;
+
+ stored_player[i].Frame += move_frames;
+
+ if (stored_player[i].MovPos != 0)
+ stored_player[i].StepFrame += move_frames;
+ }
+#endif
}
static boolean AllPlayersInSight(struct PlayerInfo *player, int x, int y)
for (y=BY1; y<=BY2; y++)
DrawScreenField(x, y);
}
+
if (dy)
{
y = (dy == 1 ? BY1 : BY2);
boolean player_is_moving_to_valid_field =
(IN_LEV_FIELD(new_jx, new_jy) &&
(Feld[new_jx][new_jy] == EL_SP_BASE ||
- Feld[new_jx][new_jy] == EL_ERDREICH));
+ Feld[new_jx][new_jy] == EL_SAND));
+ /* !!! extend EL_SAND to anything diggable !!! */
if (field_under_player_is_free &&
!player_is_moving_to_valid_field &&
- !IS_TUBE(Feld[jx][jy]))
+ !IS_WALKABLE_INSIDE(Feld[jx][jy]))
player->programmed_action = MV_DOWN;
}
}
+/*
+ MoveFigureOneStep()
+ -----------------------------------------------------------------------------
+ dx, dy: direction (non-diagonal) to try to move the player to
+ real_dx, real_dy: direction as read from input device (can be diagonal)
+*/
+
boolean MoveFigureOneStep(struct PlayerInfo *player,
int dx, int dy, int real_dx, int real_dy)
{
element = MovingOrBlocked2ElementIfNotLeaving(new_jx, new_jy);
#endif
- if (DONT_GO_TO(element))
+ if (DONT_RUN_INTO(element))
{
- if (element == EL_SALZSAEURE && dx == 0 && dy == 1)
+ if (element == EL_ACID && dx == 0 && dy == 1)
{
- Blurb(jx, jy);
- Feld[jx][jy] = EL_SPIELFIGUR;
+ SplashAcid(jx, jy);
+ Feld[jx][jy] = EL_PLAYER_1;
InitMovingField(jx, jy, MV_DOWN);
- Store[jx][jy] = EL_SALZSAEURE;
+ Store[jx][jy] = EL_ACID;
ContinueMoving(jx, jy);
BuryHero(player);
}
int original_move_delay_value = player->move_delay_value;
#if DEBUG
- printf("THIS SHOULD ONLY HAPPEN WITH PRE-1.2 LEVEL TAPES.\n");
+ printf("THIS SHOULD ONLY HAPPEN WITH PRE-1.2 LEVEL TAPES. [%ld]\n",
+ tape.counter);
#endif
/* scroll remaining steps with finest movement resolution */
}
}
+#if 0
+#if 1
+ InitPlayerGfxAnimation(player, ACTION_DEFAULT);
+#else
if (!(moved & MF_MOVING) && !player->Pushing)
player->Frame = 0;
- else
- player->Frame = (player->Frame + 1) % 4;
+#endif
+#endif
+
+ player->StepFrame = 0;
if (moved & MF_MOVING)
{
else if (old_jx == jx && old_jy != jy)
player->MovDir = (old_jy < jy ? MV_DOWN : MV_UP);
- DrawLevelField(jx, jy); /* for "ErdreichAnbroeckeln()" */
+ DrawLevelField(jx, jy); /* for "crumbled sand" */
player->last_move_dir = player->MovDir;
player->is_moving = TRUE;
}
TestIfHeroTouchesBadThing(jx, jy);
+ TestIfPlayerTouchesCustomElement(jx, jy);
if (!player->active)
RemoveHero(player);
player->actual_frame_counter = FrameCounter;
player->GfxPos = move_stepsize * (player->MovPos / move_stepsize);
- if (Feld[last_jx][last_jy] == EL_LEERRAUM)
+ if (Feld[last_jx][last_jy] == EL_EMPTY)
Feld[last_jx][last_jy] = EL_PLAYER_IS_LEAVING;
+#if 0
DrawPlayer(player);
+#endif
return;
}
else if (!FrameReached(&player->actual_frame_counter, 1))
player->GfxPos = move_stepsize * (player->MovPos / move_stepsize);
if (Feld[last_jx][last_jy] == EL_PLAYER_IS_LEAVING)
- Feld[last_jx][last_jy] = EL_LEERRAUM;
+ Feld[last_jx][last_jy] = EL_EMPTY;
/* before DrawPlayer() to draw correct player graphic for this case */
if (player->MovPos == 0)
CheckGravityMovement(player);
- DrawPlayer(player);
+#if 0
+ DrawPlayer(player); /* needed here only to cleanup last field */
+#endif
if (player->MovPos == 0)
{
- if (IS_QUICK_GATE(Feld[last_jx][last_jy]))
+ if (IS_PASSABLE(Feld[last_jx][last_jy]))
{
/* continue with normal speed after quickly moving through gate */
HALVE_PLAYER_SPEED(player);
player->last_jx = jx;
player->last_jy = jy;
- if (Feld[jx][jy] == EL_AUSGANG_AUF)
+ if (Feld[jx][jy] == EL_EXIT_OPEN ||
+ Feld[jx][jy] == EL_SP_EXIT_OPEN)
{
RemoveHero(player);
- if (!local_player->friends_still_needed)
+ if (local_player->friends_still_needed == 0 ||
+ Feld[jx][jy] == EL_SP_EXIT_OPEN)
player->LevelSolved = player->GameOver = TRUE;
}
ScreenMovDir = MV_NO_MOVING;
}
+void TestIfPlayerTouchesCustomElement(int x, int y)
+{
+ static boolean check_changing = FALSE;
+ static int xy[4][2] =
+ {
+ { 0, -1 },
+ { -1, 0 },
+ { +1, 0 },
+ { 0, +1 }
+ };
+ boolean center_is_player = (IS_PLAYER(x, y));
+ int i;
+
+ /* prevent TestIfPlayerTouchesCustomElement() from looping */
+ if (check_changing)
+ return;
+
+ check_changing = TRUE;
+
+ for (i=0; i<4; i++)
+ {
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
+
+ if (!IN_LEV_FIELD(xx, yy))
+ continue;
+
+ if (center_is_player)
+ {
+ CheckTriggeredElementChange(xx, yy, Feld[xx][yy], CE_OTHER_GETS_TOUCHED);
+ CheckElementChange(xx, yy, Feld[xx][yy], CE_TOUCHED_BY_PLAYER);
+ }
+ else if (IS_PLAYER(xx, yy))
+ {
+ CheckTriggeredElementChange(x, y, Feld[x][y], CE_OTHER_GETS_TOUCHED);
+ CheckElementChange(x, y, Feld[x][y], CE_TOUCHED_BY_PLAYER);
+
+ break;
+ }
+ }
+
+ check_changing = FALSE;
+}
+
+void TestIfElementTouchesCustomElement(int x, int y)
+{
+ static boolean check_changing = FALSE;
+ static int xy[4][2] =
+ {
+ { 0, -1 },
+ { -1, 0 },
+ { +1, 0 },
+ { 0, +1 }
+ };
+ boolean center_is_custom = (IS_CUSTOM_ELEMENT(Feld[x][y]));
+ int i;
+
+ /* prevent TestIfElementTouchesCustomElement() from looping */
+ if (check_changing)
+ return;
+
+ check_changing = TRUE;
+
+ for (i=0; i<4; i++)
+ {
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
+
+ if (!IN_LEV_FIELD(xx, yy))
+ continue;
+
+ if (center_is_custom &&
+ Feld[xx][yy] == element_info[Feld[x][y]].change.trigger_element)
+ {
+ CheckElementChange(x, y, Feld[x][y], CE_OTHER_IS_TOUCHING);
+ }
+
+ if (IS_CUSTOM_ELEMENT(Feld[xx][yy]) &&
+ Feld[x][y] == element_info[Feld[xx][yy]].change.trigger_element)
+ {
+ CheckElementChange(xx, yy, Feld[xx][yy], CE_OTHER_IS_TOUCHING);
+ }
+ }
+
+ check_changing = FALSE;
+}
+
void TestIfGoodThingHitsBadThing(int good_x, int good_y, int good_move_dir)
{
int i, kill_x = -1, kill_y = -1;
test_element = MovingOrBlocked2ElementIfNotLeaving(test_x, test_y);
#endif
- /* 1st case: good thing is moving towards DONT_GO_TO style bad thing;
+ /* 1st case: good thing is moving towards DONT_RUN_INTO style bad thing;
2nd case: DONT_TOUCH style bad thing does not move away from good thing
*/
- if ((DONT_GO_TO(test_element) && good_move_dir == test_dir[i]) ||
- (DONT_TOUCH(test_element) && test_move_dir != test_dir[i]))
+ if ((DONT_RUN_INTO(test_element) && good_move_dir == test_dir[i]) ||
+ (DONT_TOUCH(test_element) && test_move_dir != test_dir[i]))
{
kill_x = test_x;
kill_y = test_y;
{
struct PlayerInfo *player = PLAYERINFO(good_x, good_y);
- if (player->shield_active_time_left > 0)
+ if (player->shield_deadly_time_left > 0)
Bang(kill_x, kill_y);
else if (!PLAYER_PROTECTED(good_x, good_y))
KillHero(player);
MV_DOWN
};
- if (bad_element == EL_EXPLODING) /* skip just exploding bad things */
+ if (bad_element == EL_EXPLOSION) /* skip just exploding bad things */
return;
for (i=0; i<4; i++)
test_element = Feld[test_x][test_y];
- /* 1st case: good thing is moving towards DONT_GO_TO style bad thing;
+ /* 1st case: good thing is moving towards DONT_RUN_INTO style bad thing;
2nd case: DONT_TOUCH style bad thing does not move away from good thing
*/
- if ((DONT_GO_TO(bad_element) && bad_move_dir == test_dir[i]) ||
- (DONT_TOUCH(bad_element) && test_move_dir != test_dir[i]))
+ if ((DONT_RUN_INTO(bad_element) && bad_move_dir == test_dir[i]) ||
+ (DONT_TOUCH(bad_element) && test_move_dir != test_dir[i]))
{
/* good thing is player or penguin that does not move away */
if (IS_PLAYER(test_x, test_y))
kill_y = test_y;
break;
}
- else if (test_element == EL_PINGUIN)
+ else if (test_element == EL_PENGUIN)
{
kill_x = test_x;
kill_y = test_y;
;
#endif
- if (player->shield_active_time_left > 0)
+ if (player->shield_deadly_time_left > 0)
Bang(bad_x, bad_y);
else if (!PLAYER_PROTECTED(kill_x, kill_y))
KillHero(player);
continue;
element = Feld[x][y];
- if (IS_AMOEBOID(element) || element == EL_LIFE ||
- element == EL_AMOEBING || element == EL_TROPFEN)
+ if (IS_AMOEBOID(element) || element == EL_GAME_OF_LIFE ||
+ element == EL_AMOEBA_GROWING || element == EL_AMOEBA_DROP)
{
kill_x = x;
kill_y = y;
if (!player->active)
return;
- if (IS_PFORTE(Feld[jx][jy]))
- Feld[jx][jy] = EL_LEERRAUM;
+ /* remove accessible field at the player's position */
+ Feld[jx][jy] = EL_EMPTY;
/* deactivate shield (else Bang()/Explode() would not work right) */
- player->shield_passive_time_left = 0;
- player->shield_active_time_left = 0;
+ player->shield_normal_time_left = 0;
+ player->shield_deadly_time_left = 0;
Bang(jx, jy);
BuryHero(player);
if (!player->active)
return;
- PlaySoundLevel(jx, jy, SND_PLAYER_DYING);
+#if 1
+ PlaySoundLevelElementAction(jx, jy, player->element_nr, ACTION_DYING);
+#else
+ PlaySoundLevel(jx, jy, SND_CLASS_PLAYER_DYING);
+#endif
PlaySoundLevel(jx, jy, SND_GAME_LOSING);
player->GameOver = TRUE;
ExitY = ZY = jy;
}
+/*
+ =============================================================================
+ checkDiagonalPushing()
+ -----------------------------------------------------------------------------
+ check if diagonal input device direction results in pushing of object
+ (by checking if the alternative direction is walkable, diggable, ...)
+ =============================================================================
+*/
+
+static boolean checkDiagonalPushing(struct PlayerInfo *player,
+ int x, int y, int real_dx, int real_dy)
+{
+ int jx, jy, dx, dy, xx, yy;
+
+ if (real_dx == 0 || real_dy == 0) /* no diagonal direction => push */
+ return TRUE;
+
+ /* diagonal direction: check alternative direction */
+ jx = player->jx;
+ jy = player->jy;
+ dx = x - jx;
+ dy = y - jy;
+ xx = jx + (dx == 0 ? real_dx : 0);
+ yy = jy + (dy == 0 ? real_dy : 0);
+
+ return (!IN_LEV_FIELD(xx, yy) || IS_SOLID_FOR_PUSHING(Feld[xx][yy]));
+}
+
+/*
+ =============================================================================
+ DigField()
+ -----------------------------------------------------------------------------
+ x, y: field next to player (non-diagonal) to try to dig to
+ real_dx, real_dy: direction as read from input device (can be diagonal)
+ =============================================================================
+*/
+
int DigField(struct PlayerInfo *player,
int x, int y, int real_dx, int real_dy, int mode)
{
+ boolean use_spring_bug = (game.engine_version < VERSION_IDENT(2,2,0));
int jx = player->jx, jy = player->jy;
int dx = x - jx, dy = y - jy;
+ int nextx = x + dx, nexty = y + dy;
int move_direction = (dx == -1 ? MV_LEFT :
dx == +1 ? MV_RIGHT :
dy == -1 ? MV_UP :
int element;
if (player->MovPos == 0)
+ {
+ player->is_digging = FALSE;
+ player->is_collecting = FALSE;
+ }
+
+ if (player->MovPos == 0) /* last pushing move finished */
player->Pushing = FALSE;
- if (mode == DF_NO_PUSH)
+ if (mode == DF_NO_PUSH) /* player just stopped pushing */
{
player->Switching = FALSE;
player->push_delay = 0;
+
return MF_NO_ACTION;
}
if (IS_MOVING(x, y) || IS_PLAYER(x, y))
return MF_NO_ACTION;
- if (IS_TUBE(Feld[jx][jy]))
+#if 0
+ if (IS_TUBE(Feld[jx][jy]) || IS_TUBE(Back[jx][jy]))
+#else
+ if (IS_TUBE(Feld[jx][jy]) ||
+ (IS_TUBE(Back[jx][jy]) && game.engine_version >= VERSION_IDENT(2,2,0)))
+#endif
{
int i = 0;
+ int tube_element = (IS_TUBE(Feld[jx][jy]) ? Feld[jx][jy] : Back[jx][jy]);
int tube_leave_directions[][2] =
{
- { EL_TUBE_CROSS, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
- { EL_TUBE_VERTICAL, MV_UP | MV_DOWN },
- { EL_TUBE_HORIZONTAL, MV_LEFT | MV_RIGHT },
- { EL_TUBE_VERT_LEFT, MV_LEFT | MV_UP | MV_DOWN },
- { EL_TUBE_VERT_RIGHT, MV_RIGHT | MV_UP | MV_DOWN },
- { EL_TUBE_HORIZ_UP, MV_LEFT | MV_RIGHT | MV_UP },
- { EL_TUBE_HORIZ_DOWN, MV_LEFT | MV_RIGHT | MV_DOWN },
- { EL_TUBE_LEFT_UP, MV_LEFT | MV_UP },
- { EL_TUBE_LEFT_DOWN, MV_LEFT | MV_DOWN },
- { EL_TUBE_RIGHT_UP, MV_RIGHT | MV_UP },
- { EL_TUBE_RIGHT_DOWN, MV_RIGHT | MV_DOWN },
- { -1, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN }
+ { EL_TUBE_ANY, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
+ { EL_TUBE_VERTICAL, MV_UP | MV_DOWN },
+ { EL_TUBE_HORIZONTAL, MV_LEFT | MV_RIGHT },
+ { EL_TUBE_VERTICAL_LEFT, MV_LEFT | MV_UP | MV_DOWN },
+ { EL_TUBE_VERTICAL_RIGHT, MV_RIGHT | MV_UP | MV_DOWN },
+ { EL_TUBE_HORIZONTAL_UP, MV_LEFT | MV_RIGHT | MV_UP },
+ { EL_TUBE_HORIZONTAL_DOWN, MV_LEFT | MV_RIGHT | MV_DOWN },
+ { EL_TUBE_LEFT_UP, MV_LEFT | MV_UP },
+ { EL_TUBE_LEFT_DOWN, MV_LEFT | MV_DOWN },
+ { EL_TUBE_RIGHT_UP, MV_RIGHT | MV_UP },
+ { EL_TUBE_RIGHT_DOWN, MV_RIGHT | MV_DOWN },
+ { -1, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN }
};
- while (tube_leave_directions[i][0] != Feld[jx][jy])
+ while (tube_leave_directions[i][0] != tube_element)
{
i++;
if (tube_leave_directions[i][0] == -1) /* should not happen */
element = Feld[x][y];
+ if (mode == DF_SNAP && !IS_SNAPPABLE(element) &&
+ game.engine_version >= VERSION_IDENT(2,2,0))
+ return MF_NO_ACTION;
+
switch (element)
{
- case EL_LEERRAUM:
- case EL_ERDREICH:
- case EL_SAND_INVISIBLE:
- case EL_TRAP_INACTIVE:
- case EL_SP_BASE:
- case EL_SP_BUG:
- RemoveField(x, y);
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_DIGGING);
- break;
-
- case EL_EDELSTEIN:
- case EL_EDELSTEIN_BD:
- case EL_EDELSTEIN_GELB:
- case EL_EDELSTEIN_ROT:
- case EL_EDELSTEIN_LILA:
- case EL_DIAMANT:
- case EL_SP_INFOTRON:
- case EL_PEARL:
- case EL_CRYSTAL:
- RemoveField(x, y);
- local_player->gems_still_needed -= (element == EL_DIAMANT ? 3 :
- element == EL_PEARL ? 5 :
- element == EL_CRYSTAL ? 8 : 1);
- if (local_player->gems_still_needed < 0)
- local_player->gems_still_needed = 0;
- RaiseScoreElement(element);
- DrawText(DX_EMERALDS, DY_EMERALDS,
- int2str(local_player->gems_still_needed, 3),
- FS_SMALL, FC_YELLOW);
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_COLLECTING);
- break;
-
- case EL_SPEED_PILL:
- RemoveField(x, y);
- player->move_delay_value = MOVE_DELAY_HIGH_SPEED;
- PlaySoundLevel(x, y, SND_SPEED_PILL_COLLECTING);
- break;
-
- case EL_ENVELOPE:
- Feld[x][y] = EL_LEERRAUM;
- PlaySoundLevel(x, y, SND_ENVELOPE_COLLECTING);
- break;
-
- case EL_EXTRA_TIME:
- RemoveField(x, y);
- if (level.time > 0)
- {
- TimeLeft += 10;
- DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FS_SMALL, FC_YELLOW);
- }
- PlaySoundStereo(SND_EXTRA_TIME_COLLECTING, SOUND_MAX_RIGHT);
- break;
-
- case EL_SHIELD_PASSIVE:
- RemoveField(x, y);
- player->shield_passive_time_left += 10;
- PlaySoundLevel(x, y, SND_SHIELD_PASSIVE_COLLECTING);
- break;
-
- case EL_SHIELD_ACTIVE:
- RemoveField(x, y);
- player->shield_passive_time_left += 10;
- player->shield_active_time_left += 10;
- PlaySoundLevel(x, y, SND_SHIELD_ACTIVE_COLLECTING);
- break;
-
- case EL_DYNAMITE_INACTIVE:
- case EL_SP_DISK_RED:
- RemoveField(x, y);
- player->dynamite++;
- RaiseScoreElement(EL_DYNAMITE_INACTIVE);
- DrawText(DX_DYNAMITE, DY_DYNAMITE,
- int2str(local_player->dynamite, 3),
- FS_SMALL, FC_YELLOW);
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_COLLECTING);
- break;
-
- case EL_DYNABOMB_NR:
- RemoveField(x, y);
- player->dynabomb_count++;
- player->dynabombs_left++;
- RaiseScoreElement(EL_DYNAMITE_INACTIVE);
- PlaySoundLevel(x, y, SND_DYNABOMB_NR_COLLECTING);
- break;
-
- case EL_DYNABOMB_SZ:
- RemoveField(x, y);
- player->dynabomb_size++;
- RaiseScoreElement(EL_DYNAMITE_INACTIVE);
- PlaySoundLevel(x, y, SND_DYNABOMB_SZ_COLLECTING);
- break;
-
- case EL_DYNABOMB_XL:
- RemoveField(x, y);
- player->dynabomb_xl = TRUE;
- RaiseScoreElement(EL_DYNAMITE_INACTIVE);
- PlaySoundLevel(x, y, SND_DYNABOMB_XL_COLLECTING);
- break;
-
- case EL_SCHLUESSEL1:
- case EL_SCHLUESSEL2:
- case EL_SCHLUESSEL3:
- case EL_SCHLUESSEL4:
- {
- int key_nr = element - EL_SCHLUESSEL1;
-
- RemoveField(x, y);
- player->key[key_nr] = TRUE;
- RaiseScoreElement(EL_SCHLUESSEL);
- DrawMiniGraphicExt(drawto, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS,
- GFX_SCHLUESSEL1 + key_nr);
- DrawMiniGraphicExt(window, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS,
- GFX_SCHLUESSEL1 + key_nr);
- PlaySoundLevel(x, y, SND_KEY_COLLECTING);
- break;
- }
-
- case EL_EM_KEY_1:
- case EL_EM_KEY_2:
- case EL_EM_KEY_3:
- case EL_EM_KEY_4:
- {
- int key_nr = element - EL_EM_KEY_1;
-
- RemoveField(x, y);
- player->key[key_nr] = TRUE;
- RaiseScoreElement(EL_SCHLUESSEL);
- DrawMiniGraphicExt(drawto, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS,
- GFX_SCHLUESSEL1 + key_nr);
- DrawMiniGraphicExt(window, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS,
- GFX_SCHLUESSEL1 + key_nr);
- PlaySoundLevel(x, y, SND_KEY_COLLECTING);
- break;
- }
-
- case EL_ABLENK_AUS:
- Feld[x][y] = EL_ABLENK_EIN;
+ case EL_ROBOT_WHEEL:
+ Feld[x][y] = EL_ROBOT_WHEEL_ACTIVE;
ZX = x;
ZY = y;
DrawLevelField(x, y);
{
int xx, yy;
- PlaySoundLevel(x, y, SND_SP_TERMINAL_ACTIVATING);
-
- for (yy=0; yy<lev_fieldy; yy++)
- {
- for (xx=0; xx<lev_fieldx; xx++)
- {
- if (Feld[xx][yy] == EL_SP_DISK_YELLOW)
- Bang(xx, yy);
- else if (Feld[xx][yy] == EL_SP_TERMINAL)
- Feld[xx][yy] = EL_SP_TERMINAL_ACTIVE;
- }
- }
-
- return MF_ACTION;
- }
- break;
-
- case EL_BELT1_SWITCH_LEFT:
- case EL_BELT1_SWITCH_MIDDLE:
- case EL_BELT1_SWITCH_RIGHT:
- case EL_BELT2_SWITCH_LEFT:
- case EL_BELT2_SWITCH_MIDDLE:
- case EL_BELT2_SWITCH_RIGHT:
- case EL_BELT3_SWITCH_LEFT:
- case EL_BELT3_SWITCH_MIDDLE:
- case EL_BELT3_SWITCH_RIGHT:
- case EL_BELT4_SWITCH_LEFT:
- case EL_BELT4_SWITCH_MIDDLE:
- case EL_BELT4_SWITCH_RIGHT:
- if (!player->Switching)
- {
- player->Switching = TRUE;
- ToggleBeltSwitch(x, y);
- PlaySoundLevel(x, y, SND_CONVEYOR_BELT_SWITCH_ACTIVATING);
- }
- return MF_ACTION;
- break;
-
- case EL_SWITCHGATE_SWITCH_1:
- case EL_SWITCHGATE_SWITCH_2:
- if (!player->Switching)
- {
- player->Switching = TRUE;
- ToggleSwitchgateSwitch(x, y);
- PlaySoundLevel(x, y, SND_SWITCHGATE_SWITCH_ACTIVATING);
- }
- return MF_ACTION;
- break;
-
- case EL_LIGHT_SWITCH_OFF:
- case EL_LIGHT_SWITCH_ON:
- if (!player->Switching)
- {
- player->Switching = TRUE;
- ToggleLightSwitch(x, y);
- PlaySoundLevel(x, y, element == EL_LIGHT_SWITCH_OFF ?
- SND_LIGHT_SWITCH_ACTIVATING :
- SND_LIGHT_SWITCH_DEACTIVATING);
- }
- return MF_ACTION;
- break;
-
- case EL_TIMEGATE_SWITCH_OFF:
- ActivateTimegateSwitch(x, y);
- PlaySoundLevel(x, y, SND_TIMEGATE_WHEEL_ACTIVATING);
-
- return MF_ACTION;
- break;
-
- case EL_BALLOON_SEND_LEFT:
- case EL_BALLOON_SEND_RIGHT:
- case EL_BALLOON_SEND_UP:
- case EL_BALLOON_SEND_DOWN:
- case EL_BALLOON_SEND_ANY:
- if (element == EL_BALLOON_SEND_ANY)
- game.balloon_dir = move_direction;
- else
- game.balloon_dir = (element == EL_BALLOON_SEND_LEFT ? MV_LEFT :
- element == EL_BALLOON_SEND_RIGHT ? MV_RIGHT :
- element == EL_BALLOON_SEND_UP ? MV_UP :
- element == EL_BALLOON_SEND_DOWN ? MV_DOWN :
- MV_NO_MOVING);
- PlaySoundLevel(x, y, SND_BALLOON_SWITCH_ACTIVATING);
-
- return MF_ACTION;
- break;
-
- case EL_SP_EXIT:
- if (local_player->gems_still_needed > 0)
- return MF_NO_ACTION;
-
- player->LevelSolved = player->GameOver = TRUE;
- PlaySoundStereo(SND_SP_EXIT_ENTERING, SOUND_MAX_RIGHT);
- break;
-
- /* the following elements cannot be pushed by "snapping" */
- case EL_FELSBROCKEN:
- case EL_BOMBE:
- case EL_DX_SUPABOMB:
- case EL_KOKOSNUSS:
- case EL_ZEIT_LEER:
- case EL_SP_ZONK:
- case EL_SP_DISK_ORANGE:
- case EL_SPRING:
- if (mode == DF_SNAP)
- return MF_NO_ACTION;
- /* no "break" -- fall through to next case */
- /* the following elements can be pushed by "snapping" */
- case EL_BD_ROCK:
- if (dy)
- return MF_NO_ACTION;
-
- player->Pushing = TRUE;
-
- if (!IN_LEV_FIELD(x+dx, y+dy) || !IS_FREE(x+dx, y+dy))
- return MF_NO_ACTION;
-
- if (real_dy)
- {
- if (IN_LEV_FIELD(jx, jy+real_dy) && !IS_SOLID(Feld[jx][jy+real_dy]))
- return MF_NO_ACTION;
- }
-
- if (player->push_delay == 0)
- player->push_delay = FrameCounter;
-#if 0
- if (!FrameReached(&player->push_delay, player->push_delay_value) &&
- !tape.playing && element != EL_SPRING)
- return MF_NO_ACTION;
-#else
- if (!FrameReached(&player->push_delay, player->push_delay_value) &&
- !(tape.playing && tape.file_version < FILE_VERSION_2_0) &&
- element != EL_SPRING)
- return MF_NO_ACTION;
-#endif
-
- if (mode == DF_SNAP)
- {
- InitMovingField(x, y, move_direction);
- ContinueMoving(x, y);
- }
- else
- {
- RemoveField(x, y);
- Feld[x+dx][y+dy] = element;
- }
-
- if (element == EL_SPRING)
- {
- Feld[x+dx][y+dy] = EL_SPRING_MOVING;
- MovDir[x+dx][y+dy] = move_direction;
- }
+ PlaySoundLevel(x, y, SND_SP_TERMINAL_ACTIVATING);
- player->push_delay_value = (element == EL_SPRING ? 0 : 2 + RND(8));
+ for (yy=0; yy<lev_fieldy; yy++)
+ {
+ for (xx=0; xx<lev_fieldx; xx++)
+ {
+ if (Feld[xx][yy] == EL_SP_DISK_YELLOW)
+ Bang(xx, yy);
+ else if (Feld[xx][yy] == EL_SP_TERMINAL)
+ Feld[xx][yy] = EL_SP_TERMINAL_ACTIVE;
+ }
+ }
- DrawLevelField(x+dx, y+dy);
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_PUSHING);
+ return MF_ACTION;
+ }
break;
- case EL_PFORTE1:
- case EL_PFORTE2:
- case EL_PFORTE3:
- case EL_PFORTE4:
- if (!player->key[element - EL_PFORTE1])
- return MF_NO_ACTION;
+ case EL_CONVEYOR_BELT_1_SWITCH_LEFT:
+ case EL_CONVEYOR_BELT_1_SWITCH_MIDDLE:
+ case EL_CONVEYOR_BELT_1_SWITCH_RIGHT:
+ case EL_CONVEYOR_BELT_2_SWITCH_LEFT:
+ case EL_CONVEYOR_BELT_2_SWITCH_MIDDLE:
+ case EL_CONVEYOR_BELT_2_SWITCH_RIGHT:
+ case EL_CONVEYOR_BELT_3_SWITCH_LEFT:
+ case EL_CONVEYOR_BELT_3_SWITCH_MIDDLE:
+ case EL_CONVEYOR_BELT_3_SWITCH_RIGHT:
+ case EL_CONVEYOR_BELT_4_SWITCH_LEFT:
+ case EL_CONVEYOR_BELT_4_SWITCH_MIDDLE:
+ case EL_CONVEYOR_BELT_4_SWITCH_RIGHT:
+ if (!player->Switching)
+ {
+ player->Switching = TRUE;
+ ToggleBeltSwitch(x, y);
+ PlaySoundLevel(x, y, SND_CLASS_CONVEYOR_BELT_SWITCH_ACTIVATING);
+ }
+ return MF_ACTION;
break;
- case EL_PFORTE1X:
- case EL_PFORTE2X:
- case EL_PFORTE3X:
- case EL_PFORTE4X:
- if (!player->key[element - EL_PFORTE1X])
- return MF_NO_ACTION;
+ case EL_SWITCHGATE_SWITCH_UP:
+ case EL_SWITCHGATE_SWITCH_DOWN:
+ if (!player->Switching)
+ {
+ player->Switching = TRUE;
+ ToggleSwitchgateSwitch(x, y);
+ PlaySoundLevel(x, y, SND_CLASS_SWITCHGATE_SWITCH_ACTIVATING);
+ }
+ return MF_ACTION;
break;
- case EL_EM_GATE_1:
- case EL_EM_GATE_2:
- case EL_EM_GATE_3:
- case EL_EM_GATE_4:
- if (!player->key[element - EL_EM_GATE_1])
- return MF_NO_ACTION;
- if (!IN_LEV_FIELD(x + dx, y + dy) || !IS_FREE(x + dx, y + dy))
- return MF_NO_ACTION;
-
- /* automatically move to the next field with double speed */
- player->programmed_action = move_direction;
- DOUBLE_PLAYER_SPEED(player);
-
- PlaySoundLevel(x, y, SND_GATE_PASSING);
+ case EL_LIGHT_SWITCH:
+ case EL_LIGHT_SWITCH_ACTIVE:
+ if (!player->Switching)
+ {
+ player->Switching = TRUE;
+ ToggleLightSwitch(x, y);
+ PlaySoundLevel(x, y, element == EL_LIGHT_SWITCH ?
+ SND_LIGHT_SWITCH_ACTIVATING :
+ SND_LIGHT_SWITCH_DEACTIVATING);
+ }
+ return MF_ACTION;
break;
- case EL_EM_GATE_1X:
- case EL_EM_GATE_2X:
- case EL_EM_GATE_3X:
- case EL_EM_GATE_4X:
- if (!player->key[element - EL_EM_GATE_1X])
- return MF_NO_ACTION;
- if (!IN_LEV_FIELD(x + dx, y + dy) || !IS_FREE(x + dx, y + dy))
- return MF_NO_ACTION;
-
- /* automatically move to the next field with double speed */
- player->programmed_action = move_direction;
- DOUBLE_PLAYER_SPEED(player);
+ case EL_TIMEGATE_SWITCH:
+ ActivateTimegateSwitch(x, y);
+ PlaySoundLevel(x, y, SND_TIMEGATE_SWITCH_ACTIVATING);
- PlaySoundLevel(x, y, SND_GATE_PASSING);
+ return MF_ACTION;
break;
- case EL_SWITCHGATE_OPEN:
- case EL_TIMEGATE_OPEN:
- if (!IN_LEV_FIELD(x + dx, y + dy) || !IS_FREE(x + dx, y + dy))
- return MF_NO_ACTION;
-
- /* automatically move to the next field with double speed */
- player->programmed_action = move_direction;
- DOUBLE_PLAYER_SPEED(player);
+ case EL_BALLOON_SWITCH_LEFT:
+ case EL_BALLOON_SWITCH_RIGHT:
+ case EL_BALLOON_SWITCH_UP:
+ case EL_BALLOON_SWITCH_DOWN:
+ case EL_BALLOON_SWITCH_ANY:
+ if (element == EL_BALLOON_SWITCH_ANY)
+ game.balloon_dir = move_direction;
+ else
+ game.balloon_dir = (element == EL_BALLOON_SWITCH_LEFT ? MV_LEFT :
+ element == EL_BALLOON_SWITCH_RIGHT ? MV_RIGHT :
+ element == EL_BALLOON_SWITCH_UP ? MV_UP :
+ element == EL_BALLOON_SWITCH_DOWN ? MV_DOWN :
+ MV_NO_MOVING);
+ PlaySoundLevel(x, y, SND_CLASS_BALLOON_SWITCH_ACTIVATING);
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_PASSING);
+ return MF_ACTION;
break;
- case EL_SP_PORT1_LEFT:
- case EL_SP_PORT2_LEFT:
- case EL_SP_PORT1_RIGHT:
- case EL_SP_PORT2_RIGHT:
- case EL_SP_PORT1_UP:
- case EL_SP_PORT2_UP:
- case EL_SP_PORT1_DOWN:
- case EL_SP_PORT2_DOWN:
- case EL_SP_PORT_X:
- case EL_SP_PORT_Y:
- case EL_SP_PORT_XY:
+ case EL_SP_PORT_LEFT:
+ case EL_SP_PORT_RIGHT:
+ case EL_SP_PORT_UP:
+ case EL_SP_PORT_DOWN:
+ case EL_SP_PORT_HORIZONTAL:
+ case EL_SP_PORT_VERTICAL:
+ case EL_SP_PORT_ANY:
+ case EL_SP_GRAVITY_PORT_LEFT:
+ case EL_SP_GRAVITY_PORT_RIGHT:
+ case EL_SP_GRAVITY_PORT_UP:
+ case EL_SP_GRAVITY_PORT_DOWN:
if ((dx == -1 &&
- element != EL_SP_PORT1_LEFT &&
- element != EL_SP_PORT2_LEFT &&
- element != EL_SP_PORT_X &&
- element != EL_SP_PORT_XY) ||
+ element != EL_SP_PORT_LEFT &&
+ element != EL_SP_GRAVITY_PORT_LEFT &&
+ element != EL_SP_PORT_HORIZONTAL &&
+ element != EL_SP_PORT_ANY) ||
(dx == +1 &&
- element != EL_SP_PORT1_RIGHT &&
- element != EL_SP_PORT2_RIGHT &&
- element != EL_SP_PORT_X &&
- element != EL_SP_PORT_XY) ||
+ element != EL_SP_PORT_RIGHT &&
+ element != EL_SP_GRAVITY_PORT_RIGHT &&
+ element != EL_SP_PORT_HORIZONTAL &&
+ element != EL_SP_PORT_ANY) ||
(dy == -1 &&
- element != EL_SP_PORT1_UP &&
- element != EL_SP_PORT2_UP &&
- element != EL_SP_PORT_Y &&
- element != EL_SP_PORT_XY) ||
+ element != EL_SP_PORT_UP &&
+ element != EL_SP_GRAVITY_PORT_UP &&
+ element != EL_SP_PORT_VERTICAL &&
+ element != EL_SP_PORT_ANY) ||
(dy == +1 &&
- element != EL_SP_PORT1_DOWN &&
- element != EL_SP_PORT2_DOWN &&
- element != EL_SP_PORT_Y &&
- element != EL_SP_PORT_XY) ||
- !IN_LEV_FIELD(x + dx, y + dy) ||
- !IS_FREE(x + dx, y + dy))
+ element != EL_SP_PORT_DOWN &&
+ element != EL_SP_GRAVITY_PORT_DOWN &&
+ element != EL_SP_PORT_VERTICAL &&
+ element != EL_SP_PORT_ANY) ||
+ !IN_LEV_FIELD(nextx, nexty) ||
+ !IS_FREE(nextx, nexty))
return MF_NO_ACTION;
+ if (element == EL_SP_GRAVITY_PORT_LEFT ||
+ element == EL_SP_GRAVITY_PORT_RIGHT ||
+ element == EL_SP_GRAVITY_PORT_UP ||
+ element == EL_SP_GRAVITY_PORT_DOWN)
+ level.gravity = !level.gravity;
+
/* automatically move to the next field with double speed */
player->programmed_action = move_direction;
DOUBLE_PLAYER_SPEED(player);
- PlaySoundLevel(x, y, SND_SP_PORT_PASSING);
+ PlaySoundLevel(x, y, SND_CLASS_SP_PORT_PASSING);
break;
- case EL_TUBE_CROSS:
+ case EL_TUBE_ANY:
case EL_TUBE_VERTICAL:
case EL_TUBE_HORIZONTAL:
- case EL_TUBE_VERT_LEFT:
- case EL_TUBE_VERT_RIGHT:
- case EL_TUBE_HORIZ_UP:
- case EL_TUBE_HORIZ_DOWN:
+ case EL_TUBE_VERTICAL_LEFT:
+ case EL_TUBE_VERTICAL_RIGHT:
+ case EL_TUBE_HORIZONTAL_UP:
+ case EL_TUBE_HORIZONTAL_DOWN:
case EL_TUBE_LEFT_UP:
case EL_TUBE_LEFT_DOWN:
case EL_TUBE_RIGHT_UP:
int i = 0;
int tube_enter_directions[][2] =
{
- { EL_TUBE_CROSS, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
- { EL_TUBE_VERTICAL, MV_UP | MV_DOWN },
- { EL_TUBE_HORIZONTAL, MV_LEFT | MV_RIGHT },
- { EL_TUBE_VERT_LEFT, MV_RIGHT | MV_UP | MV_DOWN },
- { EL_TUBE_VERT_RIGHT, MV_LEFT | MV_UP | MV_DOWN },
- { EL_TUBE_HORIZ_UP, MV_LEFT | MV_RIGHT | MV_DOWN },
- { EL_TUBE_HORIZ_DOWN, MV_LEFT | MV_RIGHT | MV_UP },
- { EL_TUBE_LEFT_UP, MV_RIGHT | MV_DOWN },
- { EL_TUBE_LEFT_DOWN, MV_RIGHT | MV_UP },
- { EL_TUBE_RIGHT_UP, MV_LEFT | MV_DOWN },
- { EL_TUBE_RIGHT_DOWN, MV_LEFT | MV_UP },
- { -1, MV_NO_MOVING }
+ { EL_TUBE_ANY, MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN },
+ { EL_TUBE_VERTICAL, MV_UP | MV_DOWN },
+ { EL_TUBE_HORIZONTAL, MV_LEFT | MV_RIGHT },
+ { EL_TUBE_VERTICAL_LEFT, MV_RIGHT | MV_UP | MV_DOWN },
+ { EL_TUBE_VERTICAL_RIGHT, MV_LEFT | MV_UP | MV_DOWN },
+ { EL_TUBE_HORIZONTAL_UP, MV_LEFT | MV_RIGHT | MV_DOWN },
+ { EL_TUBE_HORIZONTAL_DOWN, MV_LEFT | MV_RIGHT | MV_UP },
+ { EL_TUBE_LEFT_UP, MV_RIGHT | MV_DOWN },
+ { EL_TUBE_LEFT_DOWN, MV_RIGHT | MV_UP },
+ { EL_TUBE_RIGHT_UP, MV_LEFT | MV_DOWN },
+ { EL_TUBE_RIGHT_DOWN, MV_LEFT | MV_UP },
+ { -1, MV_NO_MOVING }
};
while (tube_enter_directions[i][0] != element)
if (!(tube_enter_directions[i][1] & move_direction))
return MF_NO_ACTION; /* tube has no opening in this direction */
- PlaySoundLevel(x, y, SND_TUBE_PASSING);
+ PlaySoundLevel(x, y, SND_CLASS_TUBE_WALKING);
}
break;
- case EL_AUSGANG_ZU:
- case EL_AUSGANG_ACT:
- /* door is not (yet) open */
- return MF_NO_ACTION;
- break;
-
- case EL_AUSGANG_AUF:
- if (mode == DF_SNAP)
- return MF_NO_ACTION;
-
- PlaySoundLevel(x, y, SND_EXIT_ENTERING);
-
- break;
-
- case EL_BIRNE_AUS:
- Feld[x][y] = EL_BIRNE_EIN;
+ case EL_LAMP:
+ Feld[x][y] = EL_LAMP_ACTIVE;
local_player->lights_still_needed--;
DrawLevelField(x, y);
PlaySoundLevel(x, y, SND_LAMP_ACTIVATING);
return MF_ACTION;
break;
- case EL_ZEIT_VOLL:
- Feld[x][y] = EL_ZEIT_LEER;
+ case EL_TIME_ORB_FULL:
+ Feld[x][y] = EL_TIME_ORB_EMPTY;
TimeLeft += 10;
- DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FS_SMALL, FC_YELLOW);
+ DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FONT_TEXT_2);
DrawLevelField(x, y);
- PlaySoundStereo(SND_TIME_ORB_FULL_COLLECTING, SOUND_MAX_RIGHT);
+ PlaySoundStereo(SND_TIME_ORB_FULL_COLLECTING, SOUND_MIDDLE);
return MF_ACTION;
break;
- case EL_SOKOBAN_FELD_LEER:
- break;
+ default:
- case EL_SOKOBAN_OBJEKT:
- case EL_SOKOBAN_FELD_VOLL:
- case EL_SONDE:
- case EL_SP_DISK_YELLOW:
- case EL_BALLOON:
- if (mode == DF_SNAP)
- return MF_NO_ACTION;
+ if (IS_WALKABLE(element))
+ {
+ int sound_action = ACTION_WALKING;
- player->Pushing = TRUE;
+ if (element >= EL_GATE_1 && element <= EL_GATE_4)
+ {
+ if (!player->key[element - EL_GATE_1])
+ return MF_NO_ACTION;
+ }
+ else if (element >= EL_GATE_1_GRAY && element <= EL_GATE_4_GRAY)
+ {
+ if (!player->key[element - EL_GATE_1_GRAY])
+ return MF_NO_ACTION;
+ }
+ else if (element == EL_EXIT_OPEN || element == EL_SP_EXIT_OPEN)
+ {
+ sound_action = ACTION_PASSING; /* player is passing exit */
+ }
+ else if (element == EL_EMPTY)
+ {
+ sound_action = ACTION_MOVING; /* nothing to walk on */
+ }
- if (!IN_LEV_FIELD(x+dx, y+dy)
- || (!IS_FREE(x+dx, y+dy)
- && (Feld[x+dx][y+dy] != EL_SOKOBAN_FELD_LEER
- || !IS_SB_ELEMENT(element))))
- return MF_NO_ACTION;
+ /* play sound from background or player, whatever is available */
+ if (element_info[element].sound[sound_action] != SND_UNDEFINED)
+ PlaySoundLevelElementAction(x, y, element, sound_action);
+ else
+ PlaySoundLevelElementAction(x, y, player->element_nr, sound_action);
- if (dx && real_dy)
- {
- if (IN_LEV_FIELD(jx, jy+real_dy) && !IS_SOLID(Feld[jx][jy+real_dy]))
- return MF_NO_ACTION;
+ break;
}
- else if (dy && real_dx)
+ else if (IS_PASSABLE(element))
{
- if (IN_LEV_FIELD(jx+real_dx, jy) && !IS_SOLID(Feld[jx+real_dx][jy]))
+ if (!IN_LEV_FIELD(nextx, nexty) || !IS_FREE(nextx, nexty))
return MF_NO_ACTION;
+
+ if (element >= EL_EM_GATE_1 && element <= EL_EM_GATE_4)
+ {
+ if (!player->key[element - EL_EM_GATE_1])
+ return MF_NO_ACTION;
+ }
+ else if (element >= EL_EM_GATE_1_GRAY && element <= EL_EM_GATE_4_GRAY)
+ {
+ if (!player->key[element - EL_EM_GATE_1_GRAY])
+ return MF_NO_ACTION;
+ }
+
+ /* automatically move to the next field with double speed */
+ player->programmed_action = move_direction;
+ DOUBLE_PLAYER_SPEED(player);
+
+ PlaySoundLevelAction(x, y, ACTION_PASSING);
+
+ break;
}
+ else if (IS_DIGGABLE(element))
+ {
+ RemoveField(x, y);
- if (player->push_delay == 0)
- player->push_delay = FrameCounter;
-#if 0
- if (!FrameReached(&player->push_delay, player->push_delay_value) &&
- !tape.playing && element != EL_BALLOON)
- return MF_NO_ACTION;
+ if (mode != DF_SNAP)
+ {
+#if 1
+ GfxElement[x][y] = GFX_ELEMENT(element);
#else
- if (!FrameReached(&player->push_delay, player->push_delay_value) &&
- !(tape.playing && tape.file_version < FILE_VERSION_2_0) &&
- element != EL_BALLOON)
- return MF_NO_ACTION;
+ GfxElement[x][y] =
+ (CAN_BE_CRUMBLED(element) ? EL_SAND : GFX_ELEMENT(element));
#endif
+ player->is_digging = TRUE;
+ }
- if (IS_SB_ELEMENT(element))
+ PlaySoundLevelElementAction(x, y, element, ACTION_DIGGING);
+
+ break;
+ }
+ else if (IS_COLLECTIBLE(element))
{
- if (element == EL_SOKOBAN_FELD_VOLL)
+ RemoveField(x, y);
+
+ if (mode != DF_SNAP)
{
- Feld[x][y] = EL_SOKOBAN_FELD_LEER;
- local_player->sokobanfields_still_needed++;
+ GfxElement[x][y] = element;
+ player->is_collecting = TRUE;
}
- else
- RemoveField(x, y);
- if (Feld[x+dx][y+dy] == EL_SOKOBAN_FELD_LEER)
+ if (element == EL_SPEED_PILL)
+ player->move_delay_value = MOVE_DELAY_HIGH_SPEED;
+ else if (element == EL_EXTRA_TIME && level.time > 0)
{
- Feld[x+dx][y+dy] = EL_SOKOBAN_FELD_VOLL;
- local_player->sokobanfields_still_needed--;
- if (element == EL_SOKOBAN_OBJEKT)
- PlaySoundLevel(x, y, SND_SOKOBAN_FIELD_FILLING);
- else
- PlaySoundLevel(x, y, SND_SOKOBAN_OBJECT_PUSHING);
+ TimeLeft += 10;
+ DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FONT_TEXT_2);
}
- else
+ else if (element == EL_SHIELD_NORMAL || element == EL_SHIELD_DEADLY)
{
- Feld[x+dx][y+dy] = EL_SOKOBAN_OBJEKT;
- if (element == EL_SOKOBAN_FELD_VOLL)
- PlaySoundLevel(x, y, SND_SOKOBAN_FIELD_CLEARING);
- else
- PlaySoundLevel(x, y, SND_SOKOBAN_OBJECT_PUSHING);
+ player->shield_normal_time_left += 10;
+ if (element == EL_SHIELD_DEADLY)
+ player->shield_deadly_time_left += 10;
+ }
+ else if (element == EL_DYNAMITE || element == EL_SP_DISK_RED)
+ {
+ player->dynamite++;
+ player->use_disk_red_graphic = (element == EL_SP_DISK_RED);
+
+ DrawText(DX_DYNAMITE, DY_DYNAMITE,
+ int2str(local_player->dynamite, 3), FONT_TEXT_2);
+ }
+ else if (element == EL_DYNABOMB_INCREASE_NUMBER)
+ {
+ player->dynabomb_count++;
+ player->dynabombs_left++;
+ }
+ else if (element == EL_DYNABOMB_INCREASE_SIZE)
+ {
+ player->dynabomb_size++;
+ }
+ else if (element == EL_DYNABOMB_INCREASE_POWER)
+ {
+ player->dynabomb_xl = TRUE;
+ }
+ else if ((element >= EL_KEY_1 && element <= EL_KEY_4) ||
+ (element >= EL_EM_KEY_1 && element <= EL_EM_KEY_4))
+ {
+ 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;
+
+ DrawMiniGraphicExt(drawto, DX_KEYS + key_nr * MINI_TILEX, DY_KEYS,
+ el2edimg(EL_KEY_1 + key_nr));
+ redraw_mask |= REDRAW_DOOR_1;
+ }
+ else if (element_info[element].gem_count > 0)
+ {
+ local_player->gems_still_needed -=
+ element_info[element].gem_count;
+ if (local_player->gems_still_needed < 0)
+ local_player->gems_still_needed = 0;
+
+ DrawText(DX_EMERALDS, DY_EMERALDS,
+ int2str(local_player->gems_still_needed, 3), FONT_TEXT_2);
}
+
+ RaiseScoreElement(element);
+ PlaySoundLevelElementAction(x, y, element, ACTION_COLLECTING);
+
+ CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_COLLECTED);
+
+ break;
}
- else
+ else if (IS_PUSHABLE(element))
{
- RemoveField(x, y);
- Feld[x+dx][y+dy] = element;
- PlaySoundLevelElementAction(x, y, element, SND_ACTION_PUSHING);
- }
+ if (mode == DF_SNAP && element != EL_BD_ROCK)
+ return MF_NO_ACTION;
- player->push_delay_value = (element == EL_BALLOON ? 0 : 2);
+ if (CAN_FALL(element) && dy)
+ return MF_NO_ACTION;
- DrawLevelField(x, y);
- DrawLevelField(x+dx, y+dy);
+ if (CAN_FALL(element) && IN_LEV_FIELD(x, y + 1) && IS_FREE(x, y + 1) &&
+ !(element == EL_SPRING && use_spring_bug))
+ return MF_NO_ACTION;
- if (IS_SB_ELEMENT(element) &&
- local_player->sokobanfields_still_needed == 0 &&
- game.emulation == EMU_SOKOBAN)
- {
- player->LevelSolved = player->GameOver = TRUE;
- PlaySoundLevel(x, y, SND_SOKOBAN_GAME_SOLVING);
- }
+ if (element == EL_SPRING && MovDir[x][y] != MV_NO_MOVING)
+ return MF_NO_ACTION;
- break;
+ if (!player->Pushing &&
+ game.engine_version >= RELEASE_IDENT(2,2,0,7))
+ player->push_delay_value = GET_NEW_PUSH_DELAY(element);
- case EL_PINGUIN:
- case EL_SCHWEIN:
- case EL_DRACHE:
- break;
+ player->Pushing = TRUE;
+
+ if (!(IN_LEV_FIELD(nextx, nexty) &&
+ (IS_FREE(nextx, nexty) ||
+ (Feld[nextx][nexty] == EL_SOKOBAN_FIELD_EMPTY &&
+ IS_SB_ELEMENT(element)))))
+ return MF_NO_ACTION;
+
+ if (!checkDiagonalPushing(player, x, y, real_dx, real_dy))
+ return MF_NO_ACTION;
+
+ if (player->push_delay == 0) /* new pushing; restart delay */
+ player->push_delay = FrameCounter;
+
+ if (!FrameReached(&player->push_delay, player->push_delay_value) &&
+ !(tape.playing && tape.file_version < FILE_VERSION_2_0) &&
+ element != EL_SPRING && element != EL_BALLOON)
+ return MF_NO_ACTION;
+
+ if (IS_SB_ELEMENT(element))
+ {
+ if (element == EL_SOKOBAN_FIELD_FULL)
+ {
+ Back[x][y] = EL_SOKOBAN_FIELD_EMPTY;
+ local_player->sokobanfields_still_needed++;
+ }
+
+ if (Feld[nextx][nexty] == EL_SOKOBAN_FIELD_EMPTY)
+ {
+ Back[nextx][nexty] = EL_SOKOBAN_FIELD_EMPTY;
+ local_player->sokobanfields_still_needed--;
+ }
+
+ Feld[x][y] = EL_SOKOBAN_OBJECT;
+
+ if (Back[x][y] == Back[nextx][nexty])
+ PlaySoundLevelAction(x, y, ACTION_PUSHING);
+ else if (Back[x][y] != 0)
+ PlaySoundLevelElementAction(x, y, EL_SOKOBAN_FIELD_FULL,
+ ACTION_EMPTYING);
+ else
+ PlaySoundLevelElementAction(nextx, nexty, EL_SOKOBAN_FIELD_EMPTY,
+ ACTION_FILLING);
+
+ if (local_player->sokobanfields_still_needed == 0 &&
+ game.emulation == EMU_SOKOBAN)
+ {
+ player->LevelSolved = player->GameOver = TRUE;
+ PlaySoundLevel(x, y, SND_GAME_SOKOBAN_SOLVING);
+ }
+ }
+ else
+ PlaySoundLevelElementAction(x, y, element, ACTION_PUSHING);
+
+ InitMovingField(x, y, move_direction);
+ GfxAction[x][y] = ACTION_PUSHING;
+
+ if (mode == DF_SNAP)
+ ContinueMoving(x, y);
+ else
+ MovPos[x][y] = (dx != 0 ? dx : dy);
+
+ Pushed[x][y] = TRUE;
+ Pushed[nextx][nexty] = TRUE;
+
+ if (game.engine_version < RELEASE_IDENT(2,2,0,7))
+ player->push_delay_value = GET_NEW_PUSH_DELAY(element);
+
+ CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_PUSHED);
+ CheckElementChange(x, y, element, CE_PUSHED_BY_PLAYER);
+
+ break;
+ }
+ else
+ {
+ CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_PRESSED);
+ CheckElementChange(x, y, element, CE_PRESSED_BY_PLAYER);
+ }
- default:
return MF_NO_ACTION;
}
player->push_delay = 0;
+ if (Feld[x][y] != element) /* really digged/collected something */
+ player->is_collecting = !player->is_digging;
+
return MF_MOVING;
}
{
int jx = player->jx, jy = player->jy;
int x = jx + dx, y = jy + dy;
+ int snap_direction = (dx == -1 ? MV_LEFT :
+ dx == +1 ? MV_RIGHT :
+ dy == -1 ? MV_UP :
+ dy == +1 ? MV_DOWN : MV_NO_MOVING);
+
+ if (player->MovPos && game.engine_version >= VERSION_IDENT(2,2,0))
+ return FALSE;
if (!player->active || !IN_LEV_FIELD(x, y))
return FALSE;
player->Pushing = FALSE;
player->snapped = FALSE;
+
+ if (player->MovPos == 0)
+ {
+ player->is_digging = FALSE;
+ player->is_collecting = FALSE;
+ }
+
return FALSE;
}
if (player->snapped)
return FALSE;
- player->MovDir = (dx < 0 ? MV_LEFT :
- dx > 0 ? MV_RIGHT :
- dy < 0 ? MV_UP :
- dy > 0 ? MV_DOWN : MV_NO_MOVING);
+ player->MovDir = snap_direction;
- if (!DigField(player, x, y, 0, 0, DF_SNAP))
+ if (DigField(player, x, y, 0, 0, DF_SNAP) == MF_NO_ACTION)
return FALSE;
player->snapped = TRUE;
+ player->is_digging = FALSE;
+ player->is_collecting = FALSE;
+
DrawLevelField(x, y);
BackToFront();
element = Feld[jx][jy];
if ((player->dynamite == 0 && player->dynabombs_left == 0) ||
- IS_ACTIVE_BOMB(element) || element == EL_EXPLODING)
+ IS_ACTIVE_BOMB(element) || element == EL_EXPLOSION)
+ return FALSE;
+
+#if 0
+ if (element != EL_EMPTY)
return FALSE;
+#endif
- if (element != EL_LEERRAUM)
+ if (element != EL_EMPTY)
+ {
+#if 0
Store[jx][jy] = element;
+#else
+ Back[jx][jy] = element;
+#endif
+ }
+
+ MovDelay[jx][jy] = 96;
+
+ ResetGfxAnimation(jx, jy);
+ ResetRandomAnimationValue(jx, jy);
if (player->dynamite)
{
- Feld[jx][jy] = EL_DYNAMITE_ACTIVE;
- MovDelay[jx][jy] = 96;
+ Feld[jx][jy] = (player->use_disk_red_graphic ? EL_SP_DISK_RED_ACTIVE :
+ EL_DYNAMITE_ACTIVE);
player->dynamite--;
+
DrawText(DX_DYNAMITE, DY_DYNAMITE, int2str(local_player->dynamite, 3),
- FS_SMALL, FC_YELLOW);
+ FONT_TEXT_2);
if (IN_SCR_FIELD(SCREENX(jx), SCREENY(jy)))
{
+#if 1
+ DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), el2img(Feld[jx][jy]), 0);
+#else
if (game.emulation == EMU_SUPAPLEX)
- DrawGraphic(SCREENX(jx), SCREENY(jy), GFX_SP_DISK_RED);
+ DrawGraphic(SCREENX(jx), SCREENY(jy), IMG_SP_DISK_RED, 0);
else
- DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), GFX_DYNAMIT);
+ DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), IMG_DYNAMITE_ACTIVE, 0);
+#endif
}
- PlaySoundLevel(jx, jy, SND_DYNAMITE_PLACING);
+ PlaySoundLevelAction(jx, jy, ACTION_DROPPING);
}
else
{
- Feld[jx][jy] = EL_DYNABOMB_ACTIVE_1 + (player->element_nr - EL_SPIELER1);
- MovDelay[jx][jy] = 96;
+ Feld[jx][jy] =
+ EL_DYNABOMB_PLAYER_1_ACTIVE + (player->element_nr - EL_PLAYER_1);
player->dynabombs_left--;
+
if (IN_SCR_FIELD(SCREENX(jx), SCREENY(jy)))
- DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), GFX_DYNABOMB);
+ DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), el2img(Feld[jx][jy]), 0);
- PlaySoundLevel(jx, jy, SND_DYNABOMB_PLACING);
+ PlaySoundLevelAction(jx, jy, ACTION_DROPPING);
}
return TRUE;
}
-void PlaySoundLevel(int x, int y, int nr)
+/* ------------------------------------------------------------------------- */
+/* game sound playing functions */
+/* ------------------------------------------------------------------------- */
+
+static int *loop_sound_frame = NULL;
+static int *loop_sound_volume = NULL;
+
+void InitPlaySoundLevel()
+{
+ int num_sounds = getSoundListSize();
+
+ if (loop_sound_frame != NULL)
+ free(loop_sound_frame);
+
+ if (loop_sound_volume != NULL)
+ free(loop_sound_volume);
+
+ loop_sound_frame = checked_calloc(num_sounds * sizeof(int));
+ loop_sound_volume = checked_calloc(num_sounds * sizeof(int));
+}
+
+static void PlaySoundLevel(int x, int y, int nr)
{
- static int loop_sound_frame[NUM_SOUND_EFFECTS];
- static int loop_sound_volume[NUM_SOUND_EFFECTS];
int sx = SCREENX(x), sy = SCREENY(y);
int volume, stereo_position;
int max_distance = 8;
PlaySoundExt(nr, volume, stereo_position, type);
}
-void PlaySoundLevelAction(int x, int y, int sound_action)
+static void PlaySoundLevelNearest(int x, int y, int sound_action)
+{
+ PlaySoundLevel(x < LEVELX(BX1) ? LEVELX(BX1) :
+ x > LEVELX(BX2) ? LEVELX(BX2) : x,
+ y < LEVELY(BY1) ? LEVELY(BY1) :
+ y > LEVELY(BY2) ? LEVELY(BY2) : y,
+ sound_action);
+}
+
+static void PlaySoundLevelAction(int x, int y, int action)
+{
+ PlaySoundLevelElementAction(x, y, Feld[x][y], action);
+}
+
+static void PlaySoundLevelElementAction(int x, int y, int element, int action)
{
- PlaySoundLevelElementAction(x, y, Feld[x][y], sound_action);
+ int sound_effect = element_info[element].sound[action];
+
+ if (sound_effect != SND_UNDEFINED)
+ PlaySoundLevel(x, y, sound_effect);
}
-void PlaySoundLevelElementAction(int x, int y, int element, int sound_action)
+static void PlaySoundLevelActionIfLoop(int x, int y, int action)
{
- int sound_effect = element_action_sound[element][sound_action];
+ int sound_effect = element_info[Feld[x][y]].sound[action];
- if (sound_effect != -1)
+ if (sound_effect != SND_UNDEFINED && IS_LOOP_SOUND(sound_effect))
PlaySoundLevel(x, y, sound_effect);
}
+static void StopSoundLevelActionIfLoop(int x, int y, int action)
+{
+ int sound_effect = element_info[Feld[x][y]].sound[action];
+
+ if (sound_effect != SND_UNDEFINED && IS_LOOP_SOUND(sound_effect))
+ StopSoundExt(sound_effect, SND_CTRL_STOP_SOUND);
+}
+
void RaiseScore(int value)
{
local_player->score += value;
- DrawText(DX_SCORE, DY_SCORE, int2str(local_player->score, 5),
- FS_SMALL, FC_YELLOW);
+ DrawText(DX_SCORE, DY_SCORE, int2str(local_player->score, 5), FONT_TEXT_2);
}
void RaiseScoreElement(int element)
{
switch(element)
{
- case EL_EDELSTEIN:
- case EL_EDELSTEIN_BD:
- case EL_EDELSTEIN_GELB:
- case EL_EDELSTEIN_ROT:
- case EL_EDELSTEIN_LILA:
- RaiseScore(level.score[SC_EDELSTEIN]);
+ case EL_EMERALD:
+ case EL_BD_DIAMOND:
+ case EL_EMERALD_YELLOW:
+ case EL_EMERALD_RED:
+ case EL_EMERALD_PURPLE:
+ case EL_SP_INFOTRON:
+ RaiseScore(level.score[SC_EMERALD]);
+ break;
+ case EL_DIAMOND:
+ RaiseScore(level.score[SC_DIAMOND]);
break;
- case EL_DIAMANT:
- RaiseScore(level.score[SC_DIAMANT]);
+ case EL_CRYSTAL:
+ RaiseScore(level.score[SC_CRYSTAL]);
+ break;
+ case EL_PEARL:
+ RaiseScore(level.score[SC_PEARL]);
break;
- case EL_KAEFER:
- case EL_BUTTERFLY:
- RaiseScore(level.score[SC_KAEFER]);
+ case EL_BUG:
+ case EL_BD_BUTTERFLY:
+ case EL_SP_ELECTRON:
+ RaiseScore(level.score[SC_BUG]);
break;
- case EL_FLIEGER:
- case EL_FIREFLY:
- RaiseScore(level.score[SC_FLIEGER]);
+ case EL_SPACESHIP:
+ case EL_BD_FIREFLY:
+ case EL_SP_SNIKSNAK:
+ RaiseScore(level.score[SC_SPACESHIP]);
break;
- case EL_MAMPFER:
- case EL_MAMPFER2:
- RaiseScore(level.score[SC_MAMPFER]);
+ case EL_YAMYAM:
+ case EL_DARK_YAMYAM:
+ RaiseScore(level.score[SC_YAMYAM]);
break;
case EL_ROBOT:
RaiseScore(level.score[SC_ROBOT]);
case EL_PACMAN:
RaiseScore(level.score[SC_PACMAN]);
break;
- case EL_KOKOSNUSS:
- RaiseScore(level.score[SC_KOKOSNUSS]);
+ case EL_NUT:
+ RaiseScore(level.score[SC_NUT]);
+ break;
+ case EL_DYNAMITE:
+ case EL_SP_DISK_RED:
+ case EL_DYNABOMB_INCREASE_NUMBER:
+ case EL_DYNABOMB_INCREASE_SIZE:
+ case EL_DYNABOMB_INCREASE_POWER:
+ RaiseScore(level.score[SC_DYNAMITE]);
+ break;
+ case EL_SHIELD_NORMAL:
+ case EL_SHIELD_DEADLY:
+ RaiseScore(level.score[SC_SHIELD]);
break;
- case EL_DYNAMITE_INACTIVE:
- RaiseScore(level.score[SC_DYNAMIT]);
+ case EL_EXTRA_TIME:
+ RaiseScore(level.score[SC_TIME_BONUS]);
break;
- case EL_SCHLUESSEL:
- RaiseScore(level.score[SC_SCHLUESSEL]);
+ case EL_KEY_1:
+ case EL_KEY_2:
+ case EL_KEY_3:
+ case EL_KEY_4:
+ RaiseScore(level.score[SC_KEY]);
break;
default:
+ RaiseScore(element_info[element].score);
break;
}
}
else
#endif
{
- game_status = MAINMENU;
+ game_status = GAME_MODE_MAIN;
DrawMainMenu();
}
}
for (i=0; i<NUM_GAME_BUTTONS; i++)
{
- Bitmap *gd_bitmap = pix[PIX_DOOR];
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
struct GadgetInfo *gi;
int button_type;
boolean checked;
}
}
+void FreeGameButtons()
+{
+ int i;
+
+ for (i=0; i<NUM_GAME_BUTTONS; i++)
+ FreeGadget(game_gadget[i]);
+}
+
static void MapGameButtons()
{
int i;
{
int id = gi->custom_id;
- if (game_status != PLAYING)
+ if (game_status != GAME_MODE_PLAYING)
return;
switch (id)
else if (audio.music_available)
{
setup.sound = setup.sound_music = TRUE;
+
+ SetAudioMode(setup.sound);
PlayMusic(level_nr);
}
break;
if (setup.sound_loops)
setup.sound_loops = FALSE;
else if (audio.loops_available)
+ {
setup.sound = setup.sound_loops = TRUE;
+ SetAudioMode(setup.sound);
+ }
break;
case SOUND_CTRL_ID_SIMPLE:
if (setup.sound_simple)
setup.sound_simple = FALSE;
else if (audio.sound_available)
+ {
setup.sound = setup.sound_simple = TRUE;
+ SetAudioMode(setup.sound);
+ }
break;
default:
#include "main.h"
/* score for elements (also used by editor.c) */
-#define SC_EDELSTEIN 0
-#define SC_DIAMANT 1
-#define SC_KAEFER 2
-#define SC_FLIEGER 3
-#define SC_MAMPFER 4
+#define SC_EMERALD 0
+#define SC_DIAMOND 1
+#define SC_BUG 2
+#define SC_SPACESHIP 3
+#define SC_YAMYAM 4
#define SC_ROBOT 5
#define SC_PACMAN 6
-#define SC_KOKOSNUSS 7
-#define SC_DYNAMIT 8
-#define SC_SCHLUESSEL 9
-#define SC_ZEITBONUS 10
+#define SC_NUT 7
+#define SC_DYNAMITE 8
+#define SC_KEY 9
+#define SC_TIME_BONUS 10
+#define SC_CRYSTAL 11
+#define SC_PEARL 12
+#define SC_SHIELD 13
void GetPlayerConfig(void);
void DrawGameDoorValues(void);
void InitAmoebaNr(int, int);
void GameWon(void);
int NewHiScore(void);
+
+void InitPlayerGfxAnimation(struct PlayerInfo *, int, int);
void InitMovingField(int, int, int);
void Moving2Blocked(int, int, int *, int *);
void Blocked2Moving(int, int, int *, int *);
int DigField(struct PlayerInfo *, int, int, int, int, int);
boolean SnapField(struct PlayerInfo *, int, int);
boolean PlaceBomb(struct PlayerInfo *);
+
+void InitPlaySoundLevel();
+
void RaiseScore(int);
void RaiseScoreElement(int);
void RequestQuitGame(boolean);
void CreateGameButtons();
+void FreeGameButtons();
void UnmapGameButtons();
#endif
#include "network.h"
#include "netserv.h"
#include "cartoons.h"
-#include "config.h"
-static char *image_filename[NUM_PICTURES] =
-{
- "RocksScreen.pcx",
- "RocksDoor.pcx",
- "RocksHeroes.pcx",
- "RocksToons.pcx",
- "RocksSP.pcx",
- "RocksDC.pcx",
- "RocksMore.pcx",
- "RocksFont.pcx",
- "RocksFont2.pcx",
- "RocksFont3.pcx"
-};
-
-static void InitSetup(void);
-static void InitPlayerInfo(void);
-static void InitLevelInfo(void);
-static void InitArtworkInfo(void);
-static void InitLevelArtworkInfo(void);
-static void InitNetworkServer(void);
-static void InitMixer(void);
-static void InitSound(void);
-static void InitGfx(void);
-static void InitGfxBackground(void);
-static void InitGadgets(void);
-static void InitElementProperties(void);
-static void Execute_Debug_Command(char *);
-
-void OpenAll(void)
-{
- if (options.debug_command)
- {
- Execute_Debug_Command(options.debug_command);
-
- exit(0);
- }
-
- if (options.serveronly)
- {
-#if defined(PLATFORM_UNIX)
- NetworkServer(options.server_port, options.serveronly);
-#else
- Error(ERR_WARN, "networking only supported in Unix version");
-#endif
- exit(0); /* never reached */
- }
-
- InitProgramInfo(UNIX_USERDATA_DIRECTORY,
- PROGRAM_TITLE_STRING, getWindowTitleString(),
- ICON_TITLE_STRING, X11_ICON_FILENAME, X11_ICONMASK_FILENAME,
- MSDOS_POINTER_FILENAME,
- COOKIE_PREFIX, FILENAME_PREFIX, GAME_VERSION_ACTUAL);
-
- InitSetup();
- InitPlayerInfo();
- InitArtworkInfo(); /* needed before loading gfx, sound & music */
-
- InitCounter();
- InitMixer();
- InitJoysticks();
- InitRND(NEW_RANDOMIZE);
-
- InitVideoDisplay();
- InitVideoBuffer(&backbuffer, &window, WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH,
- setup.fullscreen);
-
- InitEventFilter(FilterMouseMotionEvents);
-
- InitGfx();
- InitElementProperties(); /* initializes IS_CHAR() for el2gfx() */
-
- InitLevelInfo();
- InitLevelArtworkInfo();
- InitGadgets(); /* needs to know number of level series */
- InitSound(); /* needs to know current level directory */
-
- InitGfxBackground();
- InitToons();
-
- DrawMainMenu();
-
- InitNetworkServer();
-}
-
-void InitSetup()
-{
- LoadSetup(); /* global setup info */
-}
-
-void InitPlayerInfo()
-{
- int i;
-
- /* choose default local player */
- local_player = &stored_player[0];
-
- for (i=0; i<MAX_PLAYERS; i++)
- stored_player[i].connected = FALSE;
-
- local_player->connected = TRUE;
-}
-
-void InitLevelInfo()
-{
- LoadLevelInfo(); /* global level info */
- LoadLevelSetup_LastSeries(); /* last played series info */
- LoadLevelSetup_SeriesInfo(); /* last played level info */
-}
-
-void InitArtworkInfo()
-{
- LoadArtworkInfo();
-}
-
-void InitLevelArtworkInfo()
-{
- LoadLevelArtworkInfo();
-}
-
-void InitNetworkServer()
-{
-#if defined(PLATFORM_UNIX)
- int nr_wanted;
-#endif
-
- if (!options.network)
- return;
-
-#if defined(PLATFORM_UNIX)
- nr_wanted = Request("Choose player", REQ_PLAYER | REQ_STAY_CLOSED);
+#include "conf_e2g.c" /* include auto-generated data structure definitions */
+#include "conf_esg.c" /* include auto-generated data structure definitions */
+#include "conf_e2s.c" /* include auto-generated data structure definitions */
+#include "conf_fnt.c" /* include auto-generated data structure definitions */
- if (!ConnectToServer(options.server_host, options.server_port))
- Error(ERR_EXIT, "cannot connect to network game server");
-
- SendToServer_PlayerName(setup.player_name);
- SendToServer_ProtocolVersion();
-
- if (nr_wanted)
- SendToServer_NrWanted(nr_wanted);
-#endif
-}
-static void InitMixer()
-{
- OpenAudio();
- InitSoundList(sound_effects, NUM_SOUND_EFFECTS);
+#define CONFIG_TOKEN_FONT_INITIAL "font.initial"
- StartMixer();
-}
-static void InitSound()
-{
- /* load custom sounds and music */
- InitReloadSounds(artwork.snd_current->name);
- InitReloadMusic(artwork.mus_current->name);
+struct FontBitmapInfo font_initial[NUM_INITIAL_FONTS];
- /* initialize sound effect lookup table for element actions */
- InitGameSound();
-}
static void InitTileClipmasks()
{
+#if 0
#if defined(TARGET_X11)
XGCValues clip_gc_values;
unsigned long clip_gc_valuemask;
#if defined(TARGET_X11_NATIVE)
+
+#if 0
GC copy_clipmask_gc;
static struct
{ GFX2_SHIELD_ACTIVE, 3 },
{ -1, 0 }
};
+#endif
+
#endif /* TARGET_X11_NATIVE */
#endif /* TARGET_X11 */
int i;
/* initialize pixmap array for special X11 tile clipping to Pixmap 'None' */
- for(i=0; i<NUM_TILES; i++)
+ for (i=0; i<NUM_TILES; i++)
tile_clipmask[i] = None;
#if defined(TARGET_X11)
clip_gc_values.graphics_exposures = False;
clip_gc_valuemask = GCGraphicsExposures;
- tile_clip_gc =
- XCreateGC(display, window->drawable, clip_gc_valuemask, &clip_gc_values);
+ tile_clip_gc = XCreateGC(display, window->drawable,
+ clip_gc_valuemask, &clip_gc_values);
- for(i=0; i<NUM_BITMAPS; i++)
+#if 0
+ for (i=0; i<NUM_BITMAPS; i++)
{
if (pix[i]->clip_mask)
{
clip_gc_valuemask, &clip_gc_values);
}
}
+#endif
#if defined(TARGET_X11_NATIVE)
+#if 0
/* create graphic context structures needed for clipping */
clip_gc_values.graphics_exposures = False;
clip_gc_valuemask = GCGraphicsExposures;
- copy_clipmask_gc =
- XCreateGC(display, pix[PIX_BACK]->clip_mask,
- clip_gc_valuemask, &clip_gc_values);
+ copy_clipmask_gc = XCreateGC(display, pix[PIX_BACK]->clip_mask,
+ clip_gc_valuemask, &clip_gc_values);
/* create only those clipping Pixmaps we really need */
- for(i=0; tile_needs_clipping[i].start>=0; i++)
+ for (i=0; tile_needs_clipping[i].start>=0; i++)
{
int j;
- for(j=0; j<tile_needs_clipping[i].count; j++)
+ for (j=0; j<tile_needs_clipping[i].count; j++)
{
int tile = tile_needs_clipping[i].start + j;
int graphic = tile;
int src_x, src_y;
- int pixmap_nr;
+ Bitmap *src_bitmap;
Pixmap src_pixmap;
- getGraphicSource(graphic, &pixmap_nr, &src_x, &src_y);
- src_pixmap = pix[pixmap_nr]->clip_mask;
+ getGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
+ src_pixmap = src_bitmap->clip_mask;
tile_clipmask[tile] = XCreatePixmap(display, window->drawable,
TILEX, TILEY, 1);
}
XFreeGC(display, copy_clipmask_gc);
+#endif
#endif /* TARGET_X11_NATIVE */
#endif /* TARGET_X11 */
+#endif
}
void FreeTileClipmasks()
{
+#if 0
#if defined(TARGET_X11)
int i;
- for(i=0; i<NUM_TILES; i++)
+ for (i=0; i<NUM_TILES; i++)
{
if (tile_clipmask[i] != None)
{
XFreeGC(display, tile_clip_gc);
tile_clip_gc = None;
- for(i=0; i<NUM_BITMAPS; i++)
+#if 0
+ for (i=0; i<NUM_BITMAPS; i++)
{
if (pix[i] != NULL && pix[i]->stored_clip_gc)
{
pix[i]->stored_clip_gc = None;
}
}
+#endif
+
#endif /* TARGET_X11 */
+#endif
}
-void InitGfx()
+void FreeGadgets()
+{
+ FreeLevelEditorGadgets();
+ FreeGameButtons();
+ FreeTapeButtons();
+ FreeToolButtons();
+ FreeScreenGadgets();
+}
+
+void InitGadgets()
+{
+ static boolean gadgets_initialized = FALSE;
+
+ if (gadgets_initialized)
+ FreeGadgets();
+
+ CreateLevelEditorGadgets();
+ CreateGameButtons();
+ CreateTapeButtons();
+ CreateToolButtons();
+ CreateScreenGadgets();
+
+ gadgets_initialized = TRUE;
+}
+
+void InitElementSmallImages()
{
+ struct PropertyMapping *property_mapping = getImageListPropertyMapping();
+ int num_property_mappings = getImageListPropertyMappingSize();
int i;
- /* initialize some global variables */
- global.frames_per_second = 0;
- global.fps_slowdown = FALSE;
- global.fps_slowdown_factor = 1;
+ /* initialize normal images from static configuration */
+ for (i=0; element_to_graphic[i].element > -1; i++)
+ CreateImageWithSmallImages(element_to_graphic[i].graphic);
- /* initialize screen properties */
- InitGfxFieldInfo(SX, SY, SXSIZE, SYSIZE,
- REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
- InitGfxDoor1Info(DX, DY, DXSIZE, DYSIZE);
- InitGfxDoor2Info(VX, VY, VXSIZE, VYSIZE);
- InitGfxScrollbufferInfo(FXSIZE, FYSIZE);
+ /* initialize special images from static configuration */
+ for (i=0; element_to_special_graphic[i].element > -1; i++)
+ CreateImageWithSmallImages(element_to_special_graphic[i].graphic);
- /* create additional image buffers for double-buffering */
- pix[PIX_DB_DOOR] = CreateBitmap(3 * DXSIZE, DYSIZE + VYSIZE, DEFAULT_DEPTH);
- pix[PIX_DB_FIELD] = CreateBitmap(FXSIZE, FYSIZE, DEFAULT_DEPTH);
+ /* initialize images from dynamic configuration */
+ for (i=0; i < num_property_mappings; i++)
+ if (property_mapping[i].artwork_index < MAX_NUM_ELEMENTS)
+ CreateImageWithSmallImages(property_mapping[i].artwork_index);
+}
- pix[PIX_SMALLFONT] = LoadCustomImage(image_filename[PIX_SMALLFONT]);
+static int getFontBitmapID(int font_nr)
+{
+ int special = -1;
+
+ if (game_status >= GAME_MODE_MAIN && game_status <= GAME_MODE_PSEUDO_PREVIEW)
+ special = game_status;
+ else if (game_status == GAME_MODE_PSEUDO_TYPENAME)
+ special = GFX_SPECIAL_ARG_MAIN;
+ else if (game_status == GAME_MODE_PLAYING)
+ special = GFX_SPECIAL_ARG_DOOR;
+
+ if (special != -1)
+ return font_info[font_nr].special_bitmap_id[special];
+ else
+ return font_nr;
+}
- InitFontInfo(NULL, NULL, pix[PIX_SMALLFONT]);
+void InitFontGraphicInfo()
+{
+ static struct FontBitmapInfo *font_bitmap_info = NULL;
+ struct PropertyMapping *property_mapping = getImageListPropertyMapping();
+ int num_property_mappings = getImageListPropertyMappingSize();
+ int num_font_bitmaps = NUM_FONTS;
+ int i, j;
- DrawInitText(WINDOW_TITLE_STRING, 20, FC_YELLOW);
- DrawInitText(WINDOW_SUBTITLE_STRING, 50, FC_RED);
+ if (graphic_info == NULL) /* still at startup phase */
+ {
+ InitFontInfo(font_initial, NUM_INITIAL_FONTS, getFontBitmapID);
- DrawInitText("Loading graphics:", 120, FC_GREEN);
+ return;
+ }
+
+ /* ---------- initialize font graphic definitions ---------- */
+
+ /* always start with reliable default values (normal font graphics) */
+ for (i=0; i < NUM_FONTS; i++)
+ font_info[i].graphic = FONT_INITIAL_1;
+
+ /* initialize normal font/graphic mapping from static configuration */
+ for (i=0; font_to_graphic[i].font_nr > -1; i++)
+ {
+ int font_nr = font_to_graphic[i].font_nr;
+ int special = font_to_graphic[i].special;
+ int graphic = font_to_graphic[i].graphic;
+
+ if (special != -1)
+ continue;
+
+ font_info[font_nr].graphic = graphic;
+ }
+
+ /* always start with reliable default values (special font graphics) */
+ for (i=0; i < NUM_FONTS; i++)
+ {
+ for (j=0; j < NUM_SPECIAL_GFX_ARGS; j++)
+ {
+ font_info[i].special_graphic[j] = font_info[i].graphic;
+ font_info[i].special_bitmap_id[j] = i;
+ }
+ }
- for(i=0; i<NUM_PICTURES; i++)
+ /* initialize special font/graphic mapping from static configuration */
+ for (i=0; font_to_graphic[i].font_nr > -1; i++)
{
- if (i != PIX_SMALLFONT)
+ int font_nr = font_to_graphic[i].font_nr;
+ int special = font_to_graphic[i].special;
+ int graphic = font_to_graphic[i].graphic;
+
+ if (special >= 0 && special < NUM_SPECIAL_GFX_ARGS)
{
- DrawInitText(image_filename[i], 150, FC_YELLOW);
+ font_info[font_nr].special_graphic[special] = graphic;
+ font_info[font_nr].special_bitmap_id[special] = num_font_bitmaps;
+ num_font_bitmaps++;
+ }
+ }
- pix[i] = LoadCustomImage(image_filename[i]);
+ /* initialize special element/graphic mapping from dynamic configuration */
+ for (i=0; i < num_property_mappings; i++)
+ {
+ int font_nr = property_mapping[i].base_index - MAX_NUM_ELEMENTS;
+ int special = property_mapping[i].ext3_index;
+ int graphic = property_mapping[i].artwork_index;
+
+ if (font_nr < 0)
+ continue;
+
+ if (special >= 0 && special < NUM_SPECIAL_GFX_ARGS)
+ {
+ font_info[font_nr].special_graphic[special] = graphic;
+ font_info[font_nr].special_bitmap_id[special] = num_font_bitmaps;
+ num_font_bitmaps++;
}
}
- InitFontInfo(pix[PIX_BIGFONT], pix[PIX_MEDIUMFONT], pix[PIX_SMALLFONT]);
+ /* ---------- initialize font bitmap array ---------- */
- InitTileClipmasks();
-}
+ if (font_bitmap_info != NULL)
+ FreeFontInfo(font_bitmap_info);
-void InitGfxBackground()
-{
- int x, y;
+ font_bitmap_info =
+ checked_calloc(num_font_bitmaps * sizeof(struct FontBitmapInfo));
- drawto = backbuffer;
- fieldbuffer = pix[PIX_DB_FIELD];
- SetDrawtoField(DRAW_BACKBUFFER);
+ /* ---------- initialize font bitmap definitions ---------- */
- BlitBitmap(pix[PIX_BACK], backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
- ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
- ClearRectangle(pix[PIX_DB_DOOR], 0, 0, 3 * DXSIZE, DYSIZE + VYSIZE);
+ for (i=0; i < NUM_FONTS; i++)
+ {
+ if (i < NUM_INITIAL_FONTS)
+ {
+ font_bitmap_info[i] = font_initial[i];
+ continue;
+ }
- for(x=0; x<MAX_BUF_XSIZE; x++)
- for(y=0; y<MAX_BUF_YSIZE; y++)
- redraw[x][y] = 0;
- redraw_tiles = 0;
- redraw_mask = REDRAW_ALL;
+ for (j=0; j < NUM_SPECIAL_GFX_ARGS; j++)
+ {
+ int font_bitmap_id = font_info[i].special_bitmap_id[j];
+ int graphic = font_info[i].special_graphic[j];
+
+ /* set 'graphic_info' for font entries, if uninitialized (guessed) */
+ if (graphic_info[graphic].anim_frames < MIN_NUM_CHARS_PER_FONT)
+ {
+ graphic_info[graphic].anim_frames = DEFAULT_NUM_CHARS_PER_FONT;
+ graphic_info[graphic].anim_frames_per_line= DEFAULT_NUM_CHARS_PER_LINE;
+ }
+
+ /* copy font relevant information from graphics information */
+ font_bitmap_info[font_bitmap_id].bitmap = graphic_info[graphic].bitmap;
+ font_bitmap_info[font_bitmap_id].src_x = graphic_info[graphic].src_x;
+ font_bitmap_info[font_bitmap_id].src_y = graphic_info[graphic].src_y;
+ font_bitmap_info[font_bitmap_id].width = graphic_info[graphic].width;
+ font_bitmap_info[font_bitmap_id].height = graphic_info[graphic].height;
+ font_bitmap_info[font_bitmap_id].draw_x = graphic_info[graphic].draw_x;
+ font_bitmap_info[font_bitmap_id].draw_y = graphic_info[graphic].draw_y;
+
+ font_bitmap_info[font_bitmap_id].num_chars =
+ graphic_info[graphic].anim_frames;
+ font_bitmap_info[font_bitmap_id].num_chars_per_line =
+ graphic_info[graphic].anim_frames_per_line;
+ }
+ }
+
+ InitFontInfo(font_bitmap_info, num_font_bitmaps, getFontBitmapID);
}
-void ReloadCustomArtwork()
+void InitElementGraphicInfo()
{
- static char *leveldir_current_filename = NULL;
- static boolean last_override_level_graphics = FALSE;
- static boolean last_override_level_sounds = FALSE;
- static boolean last_override_level_music = FALSE;
-
- if (leveldir_current_filename != leveldir_current->filename)
- {
- char *filename_old = leveldir_current_filename;
- char *filename_new = leveldir_current->filename;
-
- /* force reload of custom artwork after new level series was selected,
- but reload only that part of the artwork that really has changed */
- if (getTreeInfoFromFilename(artwork.gfx_first, filename_old) !=
- getTreeInfoFromFilename(artwork.gfx_first, filename_new))
- artwork.graphics_set_current_name = NULL;
- if (getTreeInfoFromFilename(artwork.snd_first, filename_old) !=
- getTreeInfoFromFilename(artwork.snd_first, filename_new))
- artwork.sounds_set_current_name = NULL;
- if (getTreeInfoFromFilename(artwork.mus_first, filename_new) !=
- getTreeInfoFromFilename(artwork.mus_first, filename_new))
- artwork.music_set_current_name = NULL;
-
- leveldir_current_filename = leveldir_current->filename;
+ struct PropertyMapping *property_mapping = getImageListPropertyMapping();
+ int num_property_mappings = getImageListPropertyMappingSize();
+ int i, act, dir;
+
+ /* set values to -1 to identify later as "uninitialized" values */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ {
+ for (act=0; act<NUM_ACTIONS; act++)
+ {
+ element_info[i].graphic[act] = -1;
+ element_info[i].crumbled[act] = -1;
+
+ for (dir=0; dir<NUM_DIRECTIONS; dir++)
+ {
+ element_info[i].direction_graphic[act][dir] = -1;
+ element_info[i].direction_crumbled[act][dir] = -1;
+ }
+ }
}
- if (artwork.graphics_set_current_name != artwork.gfx_current->name ||
- last_override_level_graphics != setup.override_level_graphics)
+ /* initialize normal element/graphic mapping from static configuration */
+ for (i=0; element_to_graphic[i].element > -1; i++)
{
- int i;
+ int element = element_to_graphic[i].element;
+ int action = element_to_graphic[i].action;
+ int direction = element_to_graphic[i].direction;
+ boolean crumbled = element_to_graphic[i].crumbled;
+ int graphic = element_to_graphic[i].graphic;
- ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE);
+ if (graphic_info[graphic].bitmap == NULL)
+ continue;
- for(i=0; i<NUM_PICTURES; i++)
+ if ((action > -1 || direction > -1 || crumbled == TRUE) &&
+ el2img(element) != -1)
{
- DrawInitText(image_filename[i], 150, FC_YELLOW);
- ReloadCustomImage(pix[i], image_filename[i]);
+ boolean base_redefined = getImageListEntry(el2img(element))->redefined;
+ boolean act_dir_redefined = getImageListEntry(graphic)->redefined;
+
+ /* if the base graphic ("emerald", for example) has been redefined,
+ but not the action graphic ("emerald.falling", for example), do not
+ use an existing (in this case considered obsolete) action graphic
+ anymore, but use the automatically determined default graphic */
+ if (base_redefined && !act_dir_redefined)
+ continue;
}
- FreeTileClipmasks();
- InitTileClipmasks();
- InitGfxBackground();
+ if (action < 0)
+ action = ACTION_DEFAULT;
- /* force redraw of (open or closed) door graphics */
- SetDoorState(DOOR_OPEN_ALL);
- CloseDoor(DOOR_CLOSE_ALL | DOOR_NO_DELAY);
+ if (crumbled)
+ {
+ if (direction > -1)
+ element_info[element].direction_crumbled[action][direction] = graphic;
+ else
+ element_info[element].crumbled[action] = graphic;
+ }
+ else
+ {
+ if (direction > -1)
+ element_info[element].direction_graphic[action][direction] = graphic;
+ else
+ element_info[element].graphic[action] = graphic;
+ }
+ }
+
+ /* initialize normal element/graphic mapping from dynamic configuration */
+ for (i=0; i < num_property_mappings; i++)
+ {
+ int element = property_mapping[i].base_index;
+ int action = property_mapping[i].ext1_index;
+ int direction = property_mapping[i].ext2_index;
+ int special = property_mapping[i].ext3_index;
+ int graphic = property_mapping[i].artwork_index;
+ boolean crumbled = FALSE;
+
+ if (special == GFX_SPECIAL_ARG_CRUMBLED)
+ {
+ special = -1;
+ crumbled = TRUE;
+ }
- artwork.graphics_set_current_name = artwork.gfx_current->name;
- last_override_level_graphics = setup.override_level_graphics;
+ if (graphic_info[graphic].bitmap == NULL)
+ continue;
+
+ if (element >= MAX_NUM_ELEMENTS || special != -1)
+ continue;
+
+ if (action < 0)
+ action = ACTION_DEFAULT;
+
+ if (crumbled)
+ {
+ if (direction < 0)
+ for (dir=0; dir<NUM_DIRECTIONS; dir++)
+ element_info[element].direction_crumbled[action][dir] = -1;
+
+ if (direction > -1)
+ element_info[element].direction_crumbled[action][direction] = graphic;
+ else
+ element_info[element].crumbled[action] = graphic;
+ }
+ else
+ {
+ if (direction < 0)
+ for (dir=0; dir<NUM_DIRECTIONS; dir++)
+ element_info[element].direction_graphic[action][dir] = -1;
+
+ if (direction > -1)
+ element_info[element].direction_graphic[action][direction] = graphic;
+ else
+ element_info[element].graphic[action] = graphic;
+ }
}
- if (artwork.sounds_set_current_name != artwork.snd_current->name ||
- last_override_level_sounds != setup.override_level_sounds)
+ /* now copy all graphics that are defined to be cloned from other graphics */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
{
- InitReloadSounds(artwork.snd_current->name);
+ int graphic = element_info[i].graphic[ACTION_DEFAULT];
+ int crumbled_like, diggable_like;
+
+ if (graphic == -1)
+ continue;
- artwork.sounds_set_current_name = artwork.snd_current->name;
- last_override_level_sounds = setup.override_level_sounds;
+ crumbled_like = graphic_info[graphic].crumbled_like;
+ diggable_like = graphic_info[graphic].diggable_like;
+
+ if (crumbled_like != -1 && element_info[i].crumbled[ACTION_DEFAULT] == -1)
+ {
+ for (act=0; act<NUM_ACTIONS; act++)
+ element_info[i].crumbled[act] =
+ element_info[crumbled_like].crumbled[act];
+ for (act=0; act<NUM_ACTIONS; act++)
+ for (dir=0; dir<NUM_DIRECTIONS; dir++)
+ element_info[i].direction_crumbled[act][dir] =
+ element_info[crumbled_like].direction_crumbled[act][dir];
+ }
+
+ if (diggable_like != -1 && element_info[i].graphic[ACTION_DIGGING] == -1)
+ {
+ element_info[i].graphic[ACTION_DIGGING] =
+ element_info[diggable_like].graphic[ACTION_DIGGING];
+ for (dir=0; dir<NUM_DIRECTIONS; dir++)
+ element_info[i].direction_graphic[ACTION_DIGGING][dir] =
+ element_info[diggable_like].direction_graphic[ACTION_DIGGING][dir];
+ }
}
- if (artwork.music_set_current_name != artwork.mus_current->name ||
- last_override_level_music != setup.override_level_music)
+ /* now set all '-1' values to element specific default values */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
{
- InitReloadMusic(artwork.mus_current->name);
+ int default_graphic = element_info[i].graphic[ACTION_DEFAULT];
+ int default_crumbled = element_info[i].crumbled[ACTION_DEFAULT];
+ int default_direction_graphic[NUM_DIRECTIONS];
+ int default_direction_crumbled[NUM_DIRECTIONS];
+
+ if (default_graphic == -1)
+ default_graphic = IMG_CHAR_QUESTION;
+ if (default_crumbled == -1)
+ default_crumbled = IMG_EMPTY;
+
+ for (dir=0; dir<NUM_DIRECTIONS; dir++)
+ {
+ default_direction_graphic[dir] =
+ element_info[i].direction_graphic[ACTION_DEFAULT][dir];
+ default_direction_crumbled[dir] =
+ element_info[i].direction_crumbled[ACTION_DEFAULT][dir];
+
+ if (default_direction_graphic[dir] == -1)
+ default_direction_graphic[dir] = default_graphic;
+ if (default_direction_crumbled[dir] == -1)
+ default_direction_crumbled[dir] = default_crumbled;
+ }
+
+ for (act=0; act<NUM_ACTIONS; act++)
+ {
+ boolean act_remove = (act == ACTION_DIGGING ||
+ act == ACTION_SNAPPING ||
+ act == ACTION_COLLECTING);
+
+ /* 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];
+
+ /* look for special default action graphic (classic game specific) */
+ if (IS_BD_ELEMENT(i) && element_info[EL_BD_DEFAULT].graphic[act] != -1)
+ default_action_graphic = element_info[EL_BD_DEFAULT].graphic[act];
+ if (IS_SP_ELEMENT(i) && element_info[EL_SP_DEFAULT].graphic[act] != -1)
+ default_action_graphic = element_info[EL_SP_DEFAULT].graphic[act];
+ if (IS_SB_ELEMENT(i) && element_info[EL_SB_DEFAULT].graphic[act] != -1)
+ default_action_graphic = element_info[EL_SB_DEFAULT].graphic[act];
+
+ if (IS_BD_ELEMENT(i) && element_info[EL_BD_DEFAULT].crumbled[act] != -1)
+ default_action_crumbled = element_info[EL_BD_DEFAULT].crumbled[act];
+ if (IS_SP_ELEMENT(i) && element_info[EL_SP_DEFAULT].crumbled[act] != -1)
+ default_action_crumbled = element_info[EL_SP_DEFAULT].crumbled[act];
+ if (IS_SB_ELEMENT(i) && element_info[EL_SB_DEFAULT].crumbled[act] != -1)
+ default_action_crumbled = element_info[EL_SB_DEFAULT].crumbled[act];
+
+ if (default_action_graphic == -1)
+ default_action_graphic = default_graphic;
+ if (default_action_crumbled == -1)
+ default_action_crumbled = default_crumbled;
+
+ for (dir=0; dir<NUM_DIRECTIONS; dir++)
+ {
+ 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 : default_direction_graphic[dir]);
+ if (default_action_direction_crumbled == -1)
+ default_action_direction_crumbled =
+ (act_remove ? IMG_EMPTY : default_direction_crumbled[dir]);
+
+ 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;
+ }
+
+ /* 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 : default_action_graphic);
+ if (element_info[i].crumbled[act] == -1)
+ element_info[i].crumbled[act] =
+ (act_remove ? IMG_EMPTY : default_action_crumbled);
+ }
+ }
- artwork.music_set_current_name = artwork.mus_current->name;
- last_override_level_music = setup.override_level_music;
+#if 0
+#if DEBUG
+ if (options.verbose)
+ {
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ if (element_info[i].graphic[ACTION_DEFAULT] == IMG_CHAR_QUESTION &&
+ i != EL_CHAR_QUESTION)
+ Error(ERR_RETURN, "warning: no graphic for element '%s' (%d)",
+ element_info[i].token_name, i);
}
+#endif
+#endif
}
-void InitGadgets()
+void InitElementSpecialGraphicInfo()
{
- CreateLevelEditorGadgets();
- CreateGameButtons();
- CreateTapeButtons();
- CreateToolButtons();
- CreateScreenGadgets();
+ struct PropertyMapping *property_mapping = getImageListPropertyMapping();
+ int num_property_mappings = getImageListPropertyMappingSize();
+ int i, j;
+
+ /* always start with reliable default values */
+ for (i=0; i < MAX_NUM_ELEMENTS; i++)
+ for (j=0; j < NUM_SPECIAL_GFX_ARGS; j++)
+ element_info[i].special_graphic[j] =
+ element_info[i].graphic[ACTION_DEFAULT];
+
+ /* initialize special element/graphic mapping from static configuration */
+ for (i=0; element_to_special_graphic[i].element > -1; i++)
+ {
+ int element = element_to_special_graphic[i].element;
+ int special = element_to_special_graphic[i].special;
+ int graphic = element_to_special_graphic[i].graphic;
+ boolean base_redefined = getImageListEntry(el2img(element))->redefined;
+ boolean special_redefined = getImageListEntry(graphic)->redefined;
+
+ /* if the base graphic ("emerald", for example) has been redefined,
+ but not the special graphic ("emerald.EDITOR", for example), do not
+ use an existing (in this case considered obsolete) special graphic
+ anymore, but use the automatically created (down-scaled) graphic */
+ if (base_redefined && !special_redefined)
+ continue;
+
+ element_info[element].special_graphic[special] = graphic;
+ }
+
+ /* initialize special element/graphic mapping from dynamic configuration */
+ for (i=0; i < num_property_mappings; i++)
+ {
+ int element = property_mapping[i].base_index;
+ int special = property_mapping[i].ext3_index;
+ int graphic = property_mapping[i].artwork_index;
+
+ if (element >= MAX_NUM_ELEMENTS)
+ continue;
+
+ if (special >= 0 && special < NUM_SPECIAL_GFX_ARGS)
+ element_info[element].special_graphic[special] = graphic;
+ }
}
-void InitElementProperties()
+static int get_element_from_token(char *token)
{
- int i,j;
+ int i;
- static int ep_amoebalive[] =
- {
- EL_AMOEBE_NASS,
- EL_AMOEBE_NORM,
- EL_AMOEBE_VOLL,
- EL_AMOEBE_BD
- };
- static int ep_amoebalive_num = SIZEOF_ARRAY_INT(ep_amoebalive);
+ for (i=0; i < MAX_NUM_ELEMENTS; i++)
+ if (strcmp(element_info[i].token_name, token) == 0)
+ return i;
- static int ep_amoeboid[] =
- {
- EL_AMOEBE_TOT,
- EL_AMOEBE_NASS,
- EL_AMOEBE_NORM,
- EL_AMOEBE_VOLL,
- EL_AMOEBE_BD
- };
- static int ep_amoeboid_num = SIZEOF_ARRAY_INT(ep_amoeboid);
+ return -1;
+}
- static int ep_schluessel[] =
- {
- EL_SCHLUESSEL1,
- EL_SCHLUESSEL2,
- EL_SCHLUESSEL3,
- EL_SCHLUESSEL4,
- EL_EM_KEY_1,
+static void set_graphic_parameters(int graphic, char **parameter_raw)
+{
+ Bitmap *src_bitmap = getBitmapFromImageID(graphic);
+ int parameter[NUM_GFX_ARGS];
+ int anim_frames_per_row = 1, anim_frames_per_col = 1;
+ int anim_frames_per_line = 1;
+ int i;
+
+ /* get integer values from string parameters */
+ for (i=0; i < NUM_GFX_ARGS; i++)
+ {
+ parameter[i] =
+ get_parameter_value(image_config_suffix[i].token, parameter_raw[i],
+ image_config_suffix[i].type);
+
+ if (image_config_suffix[i].type == TYPE_TOKEN)
+ parameter[i] = get_element_from_token(parameter_raw[i]);
+ }
+
+ graphic_info[graphic].bitmap = src_bitmap;
+
+ /* start with reliable default values */
+ graphic_info[graphic].src_x = 0;
+ graphic_info[graphic].src_y = 0;
+ graphic_info[graphic].width = TILEX;
+ 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].crumbled_like = -1; /* do not use clone element */
+ graphic_info[graphic].diggable_like = -1; /* do not use clone element */
+
+ /* optional x and y tile position of animation frame sequence */
+ if (parameter[GFX_ARG_XPOS] != ARG_UNDEFINED_VALUE)
+ graphic_info[graphic].src_x = parameter[GFX_ARG_XPOS] * TILEX;
+ if (parameter[GFX_ARG_YPOS] != ARG_UNDEFINED_VALUE)
+ graphic_info[graphic].src_y = parameter[GFX_ARG_YPOS] * TILEY;
+
+ /* optional x and y pixel position of animation frame sequence */
+ if (parameter[GFX_ARG_X] != ARG_UNDEFINED_VALUE)
+ graphic_info[graphic].src_x = parameter[GFX_ARG_X];
+ if (parameter[GFX_ARG_Y] != ARG_UNDEFINED_VALUE)
+ graphic_info[graphic].src_y = parameter[GFX_ARG_Y];
+
+ /* optional width and height of each animation frame */
+ if (parameter[GFX_ARG_WIDTH] != ARG_UNDEFINED_VALUE)
+ graphic_info[graphic].width = parameter[GFX_ARG_WIDTH];
+ if (parameter[GFX_ARG_HEIGHT] != ARG_UNDEFINED_VALUE)
+ graphic_info[graphic].height = parameter[GFX_ARG_HEIGHT];
+
+ 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;
+ }
+
+ /* correct x or y offset dependent of vertical or horizontal frame order */
+ if (parameter[GFX_ARG_VERTICAL]) /* frames are ordered vertically */
+ {
+ graphic_info[graphic].offset_y =
+ (parameter[GFX_ARG_OFFSET] != ARG_UNDEFINED_VALUE ?
+ parameter[GFX_ARG_OFFSET] : graphic_info[graphic].height);
+ anim_frames_per_line = anim_frames_per_col;
+ }
+ else /* frames are ordered horizontally */
+ {
+ graphic_info[graphic].offset_x =
+ (parameter[GFX_ARG_OFFSET] != ARG_UNDEFINED_VALUE ?
+ parameter[GFX_ARG_OFFSET] : graphic_info[graphic].width);
+ anim_frames_per_line = anim_frames_per_row;
+ }
+
+ /* optionally, the x and y offset of frames can be specified directly */
+ if (parameter[GFX_ARG_XOFFSET] != ARG_UNDEFINED_VALUE)
+ graphic_info[graphic].offset_x = parameter[GFX_ARG_XOFFSET];
+ if (parameter[GFX_ARG_YOFFSET] != ARG_UNDEFINED_VALUE)
+ graphic_info[graphic].offset_y = parameter[GFX_ARG_YOFFSET];
+
+ /* 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];
+ else if (parameter[GFX_ARG_XPOS] == 0 && !parameter[GFX_ARG_VERTICAL])
+ graphic_info[graphic].anim_frames = anim_frames_per_row;
+ else if (parameter[GFX_ARG_YPOS] == 0 && parameter[GFX_ARG_VERTICAL])
+ graphic_info[graphic].anim_frames = anim_frames_per_col;
+ else
+ graphic_info[graphic].anim_frames = 1;
+
+ graphic_info[graphic].anim_frames_per_line =
+ (parameter[GFX_ARG_FRAMES_PER_LINE] != ARG_UNDEFINED_VALUE ?
+ parameter[GFX_ARG_FRAMES_PER_LINE] : anim_frames_per_line);
+
+ graphic_info[graphic].anim_delay = parameter[GFX_ARG_DELAY];
+ if (graphic_info[graphic].anim_delay == 0) /* delay must be at least 1 */
+ graphic_info[graphic].anim_delay = 1;
+
+ graphic_info[graphic].anim_mode = parameter[GFX_ARG_ANIM_MODE];
+ if (graphic_info[graphic].anim_frames == 1)
+ graphic_info[graphic].anim_mode = ANIM_NONE;
+
+ /* automatically determine correct start frame, if not defined */
+ if (parameter[GFX_ARG_START_FRAME] == ARG_UNDEFINED_VALUE)
+ graphic_info[graphic].anim_start_frame = 0;
+ else if (graphic_info[graphic].anim_mode & ANIM_REVERSE)
+ graphic_info[graphic].anim_start_frame =
+ graphic_info[graphic].anim_frames - parameter[GFX_ARG_START_FRAME] - 1;
+ else
+ graphic_info[graphic].anim_start_frame = parameter[GFX_ARG_START_FRAME];
+
+ /* animation synchronized with global frame counter, not move position */
+ graphic_info[graphic].anim_global_sync = parameter[GFX_ARG_GLOBAL_SYNC];
+
+ /* optional element for cloning crumble graphics */
+ if (parameter[GFX_ARG_CRUMBLED_LIKE] != ARG_UNDEFINED_VALUE)
+ graphic_info[graphic].crumbled_like = parameter[GFX_ARG_CRUMBLED_LIKE];
+
+ /* optional element for cloning digging graphics */
+ if (parameter[GFX_ARG_DIGGABLE_LIKE] != ARG_UNDEFINED_VALUE)
+ graphic_info[graphic].diggable_like = parameter[GFX_ARG_DIGGABLE_LIKE];
+
+ /* this is only used for toon animations */
+ graphic_info[graphic].step_offset = parameter[GFX_ARG_STEP_OFFSET];
+ graphic_info[graphic].step_delay = parameter[GFX_ARG_STEP_DELAY];
+
+ /* this is only used for drawing font characters */
+ graphic_info[graphic].draw_x = parameter[GFX_ARG_DRAW_XOFFSET];
+ graphic_info[graphic].draw_y = parameter[GFX_ARG_DRAW_YOFFSET];
+}
+
+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;
+
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ static boolean clipmasks_initialized = FALSE;
+ Pixmap src_pixmap;
+ XGCValues clip_gc_values;
+ unsigned long clip_gc_valuemask;
+ GC copy_clipmask_gc = None;
+#endif
+
+ if (graphic_info != NULL)
+ free(graphic_info);
+
+ graphic_info = checked_calloc(num_images * sizeof(struct GraphicInfo));
+
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ if (clipmasks_initialized)
+ {
+ for (i=0; i<num_images; i++)
+ {
+ if (graphic_info[i].clip_mask)
+ XFreePixmap(display, graphic_info[i].clip_mask);
+ if (graphic_info[i].clip_gc)
+ XFreeGC(display, graphic_info[i].clip_gc);
+
+ graphic_info[i].clip_mask = None;
+ graphic_info[i].clip_gc = None;
+ }
+ }
+#endif
+
+ 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;
+
+#if 0
+ printf("::: image: '%s'\n", image->token);
+#endif
+
+#if 0
+ printf("::: image # %d: '%s' ['%s']\n",
+ i, image->token,
+ getTokenFromImageID(i));
+#endif
+
+ set_graphic_parameters(i, image->parameter);
+
+ /* 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 */
+
+ 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)
+ {
+ Error(ERR_RETURN_LINE, "-");
+ Error(ERR_RETURN, "warning: error found in config file:");
+ Error(ERR_RETURN, "- config file: '%s'",
+ getImageConfigFilename());
+ Error(ERR_RETURN, "- config token: '%s'",
+ getTokenFromImageID(i));
+ Error(ERR_RETURN, "- image file: '%s'",
+ src_bitmap->source_filename);
+ Error(ERR_RETURN,
+ "error: first animation frame out of bounds (%d, %d)",
+ src_x, src_y);
+ Error(ERR_RETURN, "custom graphic rejected for this element/action");
+
+ 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;
+ }
+
+ 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)
+ {
+ Error(ERR_RETURN_LINE, "-");
+ Error(ERR_RETURN, "warning: error found in config file:");
+ Error(ERR_RETURN, "- config file: '%s'",
+ getImageConfigFilename());
+ Error(ERR_RETURN, "- config token: '%s'",
+ getTokenFromImageID(i));
+ Error(ERR_RETURN, "- image file: '%s'",
+ src_bitmap->source_filename);
+ Error(ERR_RETURN,
+ "error: last animation frame (%d) out of bounds (%d, %d)",
+ last_frame, src_x, src_y);
+ Error(ERR_RETURN, "custom graphic rejected for this element/action");
+
+ 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;
+ }
+
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ /* currently we need only a tile clip mask from the first frame */
+ getGraphicSource(i, first_frame, &src_bitmap, &src_x, &src_y);
+
+ if (copy_clipmask_gc == None)
+ {
+ clip_gc_values.graphics_exposures = False;
+ clip_gc_valuemask = GCGraphicsExposures;
+ copy_clipmask_gc = XCreateGC(display, src_bitmap->clip_mask,
+ clip_gc_valuemask, &clip_gc_values);
+ }
+
+ graphic_info[i].clip_mask =
+ XCreatePixmap(display, window->drawable, TILEX, TILEY, 1);
+
+ src_pixmap = src_bitmap->clip_mask;
+ XCopyArea(display, src_pixmap, graphic_info[i].clip_mask,
+ copy_clipmask_gc, src_x, src_y, TILEX, TILEY, 0, 0);
+
+ clip_gc_values.graphics_exposures = False;
+ clip_gc_values.clip_mask = graphic_info[i].clip_mask;
+ clip_gc_valuemask = GCGraphicsExposures | GCClipMask;
+
+ graphic_info[i].clip_gc =
+ XCreateGC(display, window->drawable, clip_gc_valuemask, &clip_gc_values);
+#endif
+ }
+
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ if (copy_clipmask_gc)
+ XFreeGC(display, copy_clipmask_gc);
+
+ clipmasks_initialized = TRUE;
+#endif
+}
+
+static void InitElementSoundInfo()
+{
+ struct PropertyMapping *property_mapping = getSoundListPropertyMapping();
+ int num_property_mappings = getSoundListPropertyMappingSize();
+ int i, j, act;
+
+ /* set values to -1 to identify later as "uninitialized" values */
+ for (i=0; i < MAX_NUM_ELEMENTS; i++)
+ for (act=0; act < NUM_ACTIONS; act++)
+ element_info[i].sound[act] = -1;
+
+ /* initialize element/sound mapping from static configuration */
+ for (i=0; element_to_sound[i].element > -1; i++)
+ {
+ int element = element_to_sound[i].element;
+ int action = element_to_sound[i].action;
+ int sound = element_to_sound[i].sound;
+ boolean is_class = element_to_sound[i].is_class;
+
+ if (action < 0)
+ action = ACTION_DEFAULT;
+
+ if (!is_class)
+ element_info[element].sound[action] = sound;
+ else
+ for (j=0; j < MAX_NUM_ELEMENTS; j++)
+ if (strcmp(element_info[j].class_name,
+ element_info[element].class_name) == 0)
+ element_info[j].sound[action] = sound;
+ }
+
+ /* initialize element class/sound mapping from dynamic configuration */
+ for (i=0; i < num_property_mappings; i++)
+ {
+ int element_class = property_mapping[i].base_index - MAX_NUM_ELEMENTS;
+ int action = property_mapping[i].ext1_index;
+ int sound = property_mapping[i].artwork_index;
+
+ if (element_class < 0 || element_class >= MAX_NUM_ELEMENTS)
+ continue;
+
+ if (action < 0)
+ action = ACTION_DEFAULT;
+
+ for (j=0; j < MAX_NUM_ELEMENTS; j++)
+ if (strcmp(element_info[j].class_name,
+ element_info[element_class].class_name) == 0)
+ element_info[j].sound[action] = sound;
+ }
+
+ /* initialize element/sound mapping from dynamic configuration */
+ for (i=0; i < num_property_mappings; i++)
+ {
+ int element = property_mapping[i].base_index;
+ int action = property_mapping[i].ext1_index;
+ int sound = property_mapping[i].artwork_index;
+
+ if (element >= MAX_NUM_ELEMENTS)
+ continue;
+
+ if (action < 0)
+ action = ACTION_DEFAULT;
+
+ element_info[element].sound[action] = sound;
+ }
+
+ /* now set all '-1' values to element specific default values */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ {
+ for (act=0; act < NUM_ACTIONS; act++)
+ {
+ /* generic default action sound (defined by "[default]" directive) */
+ int default_action_sound = element_info[EL_DEFAULT].sound[act];
+
+ /* look for special default action sound (classic game specific) */
+ if (IS_BD_ELEMENT(i) && element_info[EL_BD_DEFAULT].sound[act] != -1)
+ default_action_sound = element_info[EL_BD_DEFAULT].sound[act];
+ if (IS_SP_ELEMENT(i) && element_info[EL_SP_DEFAULT].sound[act] != -1)
+ default_action_sound = element_info[EL_SP_DEFAULT].sound[act];
+ if (IS_SB_ELEMENT(i) && element_info[EL_SB_DEFAULT].sound[act] != -1)
+ default_action_sound = element_info[EL_SB_DEFAULT].sound[act];
+
+ /* look for element specific default sound (independent from action) */
+ if (element_info[i].sound[ACTION_DEFAULT] != -1)
+ default_action_sound = element_info[i].sound[ACTION_DEFAULT];
+
+ /* 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;
+ }
+ }
+}
+
+static void set_sound_parameters(int sound, char **parameter_raw)
+{
+ int parameter[NUM_SND_ARGS];
+ int i;
+
+ /* get integer values from string parameters */
+ for (i=0; i < NUM_SND_ARGS; i++)
+ parameter[i] =
+ get_parameter_value(sound_config_suffix[i].token, parameter_raw[i],
+ sound_config_suffix[i].type);
+
+ /* 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];
+}
+
+static void InitSoundInfo()
+{
+#if 0
+ struct PropertyMapping *property_mapping = getSoundListPropertyMapping();
+ int num_property_mappings = getSoundListPropertyMappingSize();
+#endif
+ int *sound_effect_properties;
+ int num_sounds = getSoundListSize();
+ int i, j;
+
+ if (sound_info != NULL)
+ free(sound_info);
+
+ sound_effect_properties = checked_calloc(num_sounds * sizeof(int));
+ sound_info = checked_calloc(num_sounds * sizeof(struct SoundInfo));
+
+ /* initialize sound effect for all elements to "no sound" */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ for (j=0; j<NUM_ACTIONS; j++)
+ element_info[i].sound[j] = SND_UNDEFINED;
+
+ for (i=0; i<num_sounds; i++)
+ {
+ struct FileInfo *sound = getSoundListEntry(i);
+ int len_effect_text = strlen(sound->token);
+
+ sound_effect_properties[i] = ACTION_OTHER;
+ sound_info[i].loop = FALSE;
+
+#if 0
+ printf("::: sound %d: '%s'\n", i, sound->token);
+#endif
+
+ /* determine all loop sounds and identify certain sound classes */
+
+ for (j=0; element_action_info[j].suffix; j++)
+ {
+ int len_action_text = strlen(element_action_info[j].suffix);
+
+ if (len_action_text < len_effect_text &&
+ strcmp(&sound->token[len_effect_text - len_action_text],
+ element_action_info[j].suffix) == 0)
+ {
+ sound_effect_properties[i] = element_action_info[j].value;
+ sound_info[i].loop = element_action_info[j].is_loop_sound;
+
+ break;
+ }
+ }
+
+#if 0
+ if (strcmp(sound->token, "custom_42") == 0)
+ printf("::: '%s' -> %d\n", sound->token, sound_info[i].loop);
+#endif
+
+ /* associate elements and some selected sound actions */
+
+ for (j=0; j<MAX_NUM_ELEMENTS; j++)
+ {
+ if (element_info[j].class_name)
+ {
+ int len_class_text = strlen(element_info[j].class_name);
+
+ if (len_class_text + 1 < len_effect_text &&
+ strncmp(sound->token,
+ element_info[j].class_name, len_class_text) == 0 &&
+ sound->token[len_class_text] == '.')
+ {
+ int sound_action_value = sound_effect_properties[i];
+
+ element_info[j].sound[sound_action_value] = i;
+ }
+ }
+ }
+
+ set_sound_parameters(i, sound->parameter);
+ }
+
+ free(sound_effect_properties);
+
+#if 0
+ /* !!! now handled in InitElementSoundInfo() !!! */
+ /* initialize element/sound mapping from dynamic configuration */
+ for (i=0; i < num_property_mappings; i++)
+ {
+ int element = property_mapping[i].base_index;
+ int action = property_mapping[i].ext1_index;
+ int sound = property_mapping[i].artwork_index;
+
+ if (action < 0)
+ action = ACTION_DEFAULT;
+
+ printf("::: %d: %d, %d, %d ['%s']\n",
+ i, element, action, sound, element_info[element].token_name);
+
+ element_info[element].sound[action] = sound;
+ }
+#endif
+
+#if 0
+ /* TEST ONLY */
+ {
+ int element = EL_CUSTOM_11;
+ int j = 0;
+
+ while (element_action_info[j].suffix)
+ {
+ printf("element %d, sound action '%s' == %d\n",
+ element, element_action_info[j].suffix,
+ element_info[element].sound[j]);
+ j++;
+ }
+ }
+
+ PlaySoundLevelElementAction(0,0, EL_CUSTOM_11, ACTION_PUSHING);
+#endif
+
+#if 0
+ /* TEST ONLY */
+ {
+ int element = EL_SAND;
+ int sound_action = ACTION_DIGGING;
+ int j = 0;
+
+ while (element_action_info[j].suffix)
+ {
+ if (element_action_info[j].value == sound_action)
+ printf("element %d, sound action '%s' == %d\n",
+ element, element_action_info[j].suffix,
+ element_info[element].sound[sound_action]);
+ j++;
+ }
+ }
+#endif
+}
+
+static void ReinitializeGraphics()
+{
+ InitGraphicInfo(); /* graphic properties mapping */
+ InitElementGraphicInfo(); /* element game graphic mapping */
+ InitElementSpecialGraphicInfo(); /* element special graphic mapping */
+
+ InitElementSmallImages(); /* create editor and preview images */
+ InitFontGraphicInfo(); /* initialize text drawing functions */
+
+ SetMainBackgroundImage(IMG_BACKGROUND);
+ SetDoorBackgroundImage(IMG_BACKGROUND_DOOR);
+
+ InitGadgets();
+ InitToons();
+}
+
+static void ReinitializeSounds()
+{
+ InitSoundInfo(); /* sound properties mapping */
+ InitElementSoundInfo(); /* element game sound mapping */
+
+ InitPlaySoundLevel(); /* internal game sound settings */
+}
+
+static void ReinitializeMusic()
+{
+ /* currently nothing to do */
+}
+
+void InitElementPropertiesStatic()
+{
+ static int ep_diggable[] =
+ {
+ EL_SAND,
+ EL_SP_BASE,
+ EL_SP_BUGGY_BASE,
+ EL_SP_BUGGY_BASE_ACTIVATING,
+ EL_TRAP,
+ EL_INVISIBLE_SAND,
+ EL_INVISIBLE_SAND_ACTIVE,
+
+ /* !!! currently not diggable, but handled by 'ep_dont_run_into' !!! */
+#if 0
+ EL_LANDMINE,
+ EL_TRAP_ACTIVE,
+ EL_SP_BUGGY_BASE_ACTIVE,
+#endif
+ -1
+ };
+
+ static int ep_collectible[] =
+ {
+ EL_BD_DIAMOND,
+ EL_EMERALD,
+ EL_DIAMOND,
+ EL_EMERALD_YELLOW,
+ EL_EMERALD_RED,
+ EL_EMERALD_PURPLE,
+ EL_KEY_1,
+ EL_KEY_2,
+ EL_KEY_3,
+ EL_KEY_4,
+ EL_EM_KEY_1,
EL_EM_KEY_2,
EL_EM_KEY_3,
- EL_EM_KEY_4
+ EL_EM_KEY_4,
+ EL_DYNAMITE,
+ EL_DYNABOMB_INCREASE_NUMBER,
+ EL_DYNABOMB_INCREASE_SIZE,
+ EL_DYNABOMB_INCREASE_POWER,
+ EL_SP_INFOTRON,
+ EL_SP_DISK_RED,
+ EL_PEARL,
+ EL_CRYSTAL,
+ EL_KEY_WHITE,
+ EL_SHIELD_NORMAL,
+ EL_SHIELD_DEADLY,
+ EL_EXTRA_TIME,
+ EL_ENVELOPE,
+ EL_SPEED_PILL,
+ -1
};
- static int ep_schluessel_num = SIZEOF_ARRAY_INT(ep_schluessel);
-
- static int ep_pforte[] =
- {
- EL_PFORTE1,
- EL_PFORTE2,
- EL_PFORTE3,
- EL_PFORTE4,
- EL_PFORTE1X,
- EL_PFORTE2X,
- EL_PFORTE3X,
- EL_PFORTE4X,
- EL_EM_GATE_1,
- EL_EM_GATE_2,
- EL_EM_GATE_3,
- EL_EM_GATE_4,
- EL_EM_GATE_1X,
- EL_EM_GATE_2X,
- EL_EM_GATE_3X,
- EL_EM_GATE_4X,
- EL_SWITCHGATE_OPEN,
- EL_SWITCHGATE_OPENING,
- EL_SWITCHGATE_CLOSED,
- EL_SWITCHGATE_CLOSING,
- EL_TIMEGATE_OPEN,
- EL_TIMEGATE_OPENING,
- EL_TIMEGATE_CLOSED,
- EL_TIMEGATE_CLOSING,
- EL_TUBE_CROSS,
- EL_TUBE_VERTICAL,
- EL_TUBE_HORIZONTAL,
- EL_TUBE_VERT_LEFT,
- EL_TUBE_VERT_RIGHT,
- EL_TUBE_HORIZ_UP,
- EL_TUBE_HORIZ_DOWN,
- EL_TUBE_LEFT_UP,
- EL_TUBE_LEFT_DOWN,
- EL_TUBE_RIGHT_UP,
- EL_TUBE_RIGHT_DOWN
+
+ static int ep_dont_run_into[] =
+ {
+ /* same elements as in 'ep_dont_touch' */
+ EL_BUG,
+ EL_SPACESHIP,
+ EL_BD_BUTTERFLY,
+ EL_BD_FIREFLY,
+
+ /* same elements as in 'ep_dont_collide_with' */
+ EL_YAMYAM,
+ EL_DARK_YAMYAM,
+ EL_ROBOT,
+ EL_PACMAN,
+ EL_SP_SNIKSNAK,
+ EL_SP_ELECTRON,
+
+ /* new elements */
+ EL_AMOEBA_DROP,
+ EL_ACID,
+
+ /* !!! maybe this should better be handled by 'ep_diggable' !!! */
+#if 1
+ EL_SP_BUGGY_BASE_ACTIVE,
+ EL_TRAP_ACTIVE,
+ EL_LANDMINE,
+#endif
+ -1
};
- static int ep_pforte_num = SIZEOF_ARRAY_INT(ep_pforte);
- static int ep_solid[] =
+ static int ep_dont_collide_with[] =
{
- EL_BETON,
- EL_MAUERWERK,
- EL_MAUER_LEBT,
- EL_MAUER_X,
- EL_MAUER_Y,
- EL_MAUER_XY,
- EL_BD_WALL,
- EL_FELSBODEN,
- EL_AUSGANG_ZU,
- EL_AUSGANG_ACT,
- EL_AUSGANG_AUF,
- EL_AMOEBE_TOT,
- EL_AMOEBE_NASS,
- EL_AMOEBE_NORM,
- EL_AMOEBE_VOLL,
- EL_AMOEBE_BD,
- EL_MORAST_VOLL,
- EL_MORAST_LEER,
- EL_QUICKSAND_FILLING,
- EL_QUICKSAND_EMPTYING,
- EL_MAGIC_WALL_OFF,
- EL_MAGIC_WALL_EMPTY,
- EL_MAGIC_WALL_EMPTYING,
- EL_MAGIC_WALL_FILLING,
- EL_MAGIC_WALL_FULL,
- EL_MAGIC_WALL_DEAD,
- EL_MAGIC_WALL_BD_OFF,
- EL_MAGIC_WALL_BD_EMPTY,
- EL_MAGIC_WALL_BD_EMPTYING,
- EL_MAGIC_WALL_BD_FULL,
- EL_MAGIC_WALL_BD_FILLING,
- EL_MAGIC_WALL_BD_DEAD,
- EL_LIFE,
- EL_LIFE_ASYNC,
- EL_BADEWANNE1,
- EL_BADEWANNE2,
- EL_BADEWANNE3,
- EL_BADEWANNE4,
- EL_BADEWANNE5,
- EL_SP_CHIP_SINGLE,
- EL_SP_CHIP_LEFT,
- EL_SP_CHIP_RIGHT,
- EL_SP_CHIP_UPPER,
- EL_SP_CHIP_LOWER,
- EL_SP_HARD_GRAY,
- EL_SP_HARD_GREEN,
- EL_SP_HARD_BLUE,
- EL_SP_HARD_RED,
- EL_SP_HARD_YELLOW,
- EL_SP_HARD_BASE1,
- EL_SP_HARD_BASE2,
- EL_SP_HARD_BASE3,
- EL_SP_HARD_BASE4,
- EL_SP_HARD_BASE5,
- EL_SP_HARD_BASE6,
- EL_SP_TERMINAL,
- EL_SP_TERMINAL_ACTIVE,
- EL_SP_EXIT,
- EL_INVISIBLE_STEEL,
- EL_BELT1_SWITCH_LEFT,
- EL_BELT1_SWITCH_MIDDLE,
- EL_BELT1_SWITCH_RIGHT,
- EL_BELT2_SWITCH_LEFT,
- EL_BELT2_SWITCH_MIDDLE,
- EL_BELT2_SWITCH_RIGHT,
- EL_BELT3_SWITCH_LEFT,
- EL_BELT3_SWITCH_MIDDLE,
- EL_BELT3_SWITCH_RIGHT,
- EL_BELT4_SWITCH_LEFT,
- EL_BELT4_SWITCH_MIDDLE,
- EL_BELT4_SWITCH_RIGHT,
- EL_SWITCHGATE_SWITCH_1,
- EL_SWITCHGATE_SWITCH_2,
- EL_LIGHT_SWITCH_OFF,
- EL_LIGHT_SWITCH_ON,
- EL_TIMEGATE_SWITCH_OFF,
- EL_TIMEGATE_SWITCH_ON,
+ /* same elements as in 'ep_dont_touch' */
+ EL_BUG,
+ EL_SPACESHIP,
+ EL_BD_BUTTERFLY,
+ EL_BD_FIREFLY,
+
+ /* new elements */
+ EL_YAMYAM,
+ EL_DARK_YAMYAM,
+ EL_ROBOT,
+ EL_PACMAN,
+ EL_SP_SNIKSNAK,
+ EL_SP_ELECTRON,
+ -1
+ };
+
+ static int ep_dont_touch[] =
+ {
+ EL_BUG,
+ EL_SPACESHIP,
+ EL_BD_BUTTERFLY,
+ EL_BD_FIREFLY,
+ -1
+ };
+
+ static int ep_indestructible[] =
+ {
+ EL_STEELWALL,
+ EL_ACID,
+ EL_ACID_POOL_TOPLEFT,
+ EL_ACID_POOL_TOPRIGHT,
+ EL_ACID_POOL_BOTTOMLEFT,
+ EL_ACID_POOL_BOTTOM,
+ EL_ACID_POOL_BOTTOMRIGHT,
+ EL_SP_HARDWARE_GRAY,
+ EL_SP_HARDWARE_GREEN,
+ EL_SP_HARDWARE_BLUE,
+ EL_SP_HARDWARE_RED,
+ EL_SP_HARDWARE_YELLOW,
+ EL_SP_HARDWARE_BASE_1,
+ EL_SP_HARDWARE_BASE_2,
+ EL_SP_HARDWARE_BASE_3,
+ EL_SP_HARDWARE_BASE_4,
+ EL_SP_HARDWARE_BASE_5,
+ EL_SP_HARDWARE_BASE_6,
+ EL_INVISIBLE_STEELWALL,
+ EL_INVISIBLE_STEELWALL_ACTIVE,
+ EL_CONVEYOR_BELT_1_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_1_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_1_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_2_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_2_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_2_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_3_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_3_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_3_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_4_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_4_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_4_SWITCH_RIGHT,
+ EL_LIGHT_SWITCH,
+ EL_LIGHT_SWITCH_ACTIVE,
EL_SIGN_EXCLAMATION,
EL_SIGN_RADIOACTIVITY,
EL_SIGN_STOP,
EL_SIGN_EXIT,
EL_SIGN_YINYANG,
EL_SIGN_OTHER,
- EL_STEEL_SLANTED,
- EL_EMC_STEEL_WALL_1,
- EL_EMC_STEEL_WALL_2,
- EL_EMC_STEEL_WALL_3,
- EL_EMC_STEEL_WALL_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_STEELWALL_SLIPPERY,
+ EL_EMC_STEELWALL_1,
+ EL_EMC_STEELWALL_2,
+ EL_EMC_STEELWALL_3,
+ EL_EMC_STEELWALL_4,
EL_CRYSTAL,
- EL_WALL_PEARL,
- EL_WALL_CRYSTAL,
- EL_PFORTE1,
- EL_PFORTE2,
- EL_PFORTE3,
- EL_PFORTE4,
- EL_PFORTE1X,
- EL_PFORTE2X,
- EL_PFORTE3X,
- EL_PFORTE4X,
+ EL_GATE_1,
+ EL_GATE_2,
+ EL_GATE_3,
+ EL_GATE_4,
+ EL_GATE_1_GRAY,
+ EL_GATE_2_GRAY,
+ EL_GATE_3_GRAY,
+ EL_GATE_4_GRAY,
EL_EM_GATE_1,
EL_EM_GATE_2,
EL_EM_GATE_3,
EL_EM_GATE_4,
- EL_EM_GATE_1X,
- EL_EM_GATE_2X,
- EL_EM_GATE_3X,
- EL_EM_GATE_4X,
+ EL_EM_GATE_1_GRAY,
+ EL_EM_GATE_2_GRAY,
+ EL_EM_GATE_3_GRAY,
+ EL_EM_GATE_4_GRAY,
EL_SWITCHGATE_OPEN,
EL_SWITCHGATE_OPENING,
EL_SWITCHGATE_CLOSED,
EL_SWITCHGATE_CLOSING,
+#if 0
+ EL_SWITCHGATE_SWITCH_UP,
+ EL_SWITCHGATE_SWITCH_DOWN,
+#endif
EL_TIMEGATE_OPEN,
EL_TIMEGATE_OPENING,
EL_TIMEGATE_CLOSED,
EL_TIMEGATE_CLOSING,
- EL_TUBE_CROSS,
+#if 0
+ EL_TIMEGATE_SWITCH,
+ EL_TIMEGATE_SWITCH_ACTIVE,
+#endif
+ EL_TUBE_ANY,
EL_TUBE_VERTICAL,
EL_TUBE_HORIZONTAL,
- EL_TUBE_VERT_LEFT,
- EL_TUBE_VERT_RIGHT,
- EL_TUBE_HORIZ_UP,
- EL_TUBE_HORIZ_DOWN,
+ EL_TUBE_VERTICAL_LEFT,
+ EL_TUBE_VERTICAL_RIGHT,
+ EL_TUBE_HORIZONTAL_UP,
+ EL_TUBE_HORIZONTAL_DOWN,
EL_TUBE_LEFT_UP,
EL_TUBE_LEFT_DOWN,
EL_TUBE_RIGHT_UP,
- EL_TUBE_RIGHT_DOWN
+ EL_TUBE_RIGHT_DOWN,
+ -1
};
- static int ep_solid_num = SIZEOF_ARRAY_INT(ep_solid);
-
- static int ep_massive[] =
- {
- EL_BETON,
- EL_SALZSAEURE,
- EL_BADEWANNE1,
- EL_BADEWANNE2,
- EL_BADEWANNE3,
- EL_BADEWANNE4,
- EL_BADEWANNE5,
- EL_SP_HARD_GRAY,
- EL_SP_HARD_GREEN,
- EL_SP_HARD_BLUE,
- EL_SP_HARD_RED,
- EL_SP_HARD_YELLOW,
- EL_SP_HARD_BASE1,
- EL_SP_HARD_BASE2,
- EL_SP_HARD_BASE3,
- EL_SP_HARD_BASE4,
- EL_SP_HARD_BASE5,
- EL_SP_HARD_BASE6,
- EL_INVISIBLE_STEEL,
- EL_BELT1_SWITCH_LEFT,
- EL_BELT1_SWITCH_MIDDLE,
- EL_BELT1_SWITCH_RIGHT,
- EL_BELT2_SWITCH_LEFT,
- EL_BELT2_SWITCH_MIDDLE,
- EL_BELT2_SWITCH_RIGHT,
- EL_BELT3_SWITCH_LEFT,
- EL_BELT3_SWITCH_MIDDLE,
- EL_BELT3_SWITCH_RIGHT,
- EL_BELT4_SWITCH_LEFT,
- EL_BELT4_SWITCH_MIDDLE,
- EL_BELT4_SWITCH_RIGHT,
- EL_LIGHT_SWITCH_OFF,
- EL_LIGHT_SWITCH_ON,
- EL_SIGN_EXCLAMATION,
- EL_SIGN_RADIOACTIVITY,
- EL_SIGN_STOP,
- EL_SIGN_WHEELCHAIR,
- EL_SIGN_PARKING,
- EL_SIGN_ONEWAY,
- EL_SIGN_HEART,
- EL_SIGN_TRIANGLE,
- EL_SIGN_ROUND,
- EL_SIGN_EXIT,
- EL_SIGN_YINYANG,
- EL_SIGN_OTHER,
- EL_STEEL_SLANTED,
- EL_EMC_STEEL_WALL_1,
- EL_EMC_STEEL_WALL_2,
- EL_EMC_STEEL_WALL_3,
- EL_EMC_STEEL_WALL_4,
- EL_CRYSTAL,
- EL_PFORTE1,
- EL_PFORTE2,
- EL_PFORTE3,
- EL_PFORTE4,
- EL_PFORTE1X,
- EL_PFORTE2X,
- EL_PFORTE3X,
- EL_PFORTE4X,
- EL_EM_GATE_1,
- EL_EM_GATE_2,
- EL_EM_GATE_3,
- EL_EM_GATE_4,
- EL_EM_GATE_1X,
- EL_EM_GATE_2X,
- EL_EM_GATE_3X,
- EL_EM_GATE_4X,
- EL_SWITCHGATE_OPEN,
- EL_SWITCHGATE_OPENING,
- EL_SWITCHGATE_CLOSED,
- EL_SWITCHGATE_CLOSING,
- EL_TIMEGATE_OPEN,
- EL_TIMEGATE_OPENING,
- EL_TIMEGATE_CLOSED,
- EL_TIMEGATE_CLOSING,
- EL_TUBE_CROSS,
- EL_TUBE_VERTICAL,
- EL_TUBE_HORIZONTAL,
- EL_TUBE_VERT_LEFT,
- EL_TUBE_VERT_RIGHT,
- EL_TUBE_HORIZ_UP,
- EL_TUBE_HORIZ_DOWN,
- EL_TUBE_LEFT_UP,
- EL_TUBE_LEFT_DOWN,
- EL_TUBE_RIGHT_UP,
- EL_TUBE_RIGHT_DOWN
- };
- static int ep_massive_num = SIZEOF_ARRAY_INT(ep_massive);
static int ep_slippery[] =
{
- EL_FELSBODEN,
+ EL_WALL_SLIPPERY,
EL_BD_WALL,
- EL_FELSBROCKEN,
+ EL_ROCK,
EL_BD_ROCK,
- EL_EDELSTEIN,
- EL_EDELSTEIN_BD,
- EL_EDELSTEIN_GELB,
- EL_EDELSTEIN_ROT,
- EL_EDELSTEIN_LILA,
- EL_DIAMANT,
- EL_BOMBE,
- EL_KOKOSNUSS,
- EL_ABLENK_EIN,
- EL_ABLENK_AUS,
- EL_ZEIT_VOLL,
- EL_ZEIT_LEER,
- EL_BIRNE_EIN,
- EL_BIRNE_AUS,
- EL_BADEWANNE1,
- EL_BADEWANNE2,
- EL_SONDE,
+ EL_EMERALD,
+ EL_BD_DIAMOND,
+ EL_EMERALD_YELLOW,
+ EL_EMERALD_RED,
+ EL_EMERALD_PURPLE,
+ EL_DIAMOND,
+ EL_BOMB,
+ EL_NUT,
+ EL_ROBOT_WHEEL_ACTIVE,
+ EL_ROBOT_WHEEL,
+ EL_TIME_ORB_FULL,
+ EL_TIME_ORB_EMPTY,
+ EL_LAMP_ACTIVE,
+ EL_LAMP,
+ EL_ACID_POOL_TOPLEFT,
+ EL_ACID_POOL_TOPRIGHT,
+ EL_SATELLITE,
EL_SP_ZONK,
EL_SP_INFOTRON,
EL_SP_CHIP_SINGLE,
EL_SP_CHIP_LEFT,
EL_SP_CHIP_RIGHT,
- EL_SP_CHIP_UPPER,
- EL_SP_CHIP_LOWER,
+ EL_SP_CHIP_TOP,
+ EL_SP_CHIP_BOTTOM,
EL_SPEED_PILL,
- EL_STEEL_SLANTED,
+ EL_STEELWALL_SLIPPERY,
EL_PEARL,
- EL_CRYSTAL
+ EL_CRYSTAL,
+ -1
+ };
+
+ static int ep_can_change[] =
+ {
+ -1
};
- static int ep_slippery_num = SIZEOF_ARRAY_INT(ep_slippery);
- static int ep_enemy[] =
+ static int ep_can_move[] =
{
- EL_KAEFER,
- EL_FLIEGER,
- EL_BUTTERFLY,
- EL_FIREFLY,
- EL_MAMPFER,
- EL_MAMPFER2,
+ EL_BUG,
+ EL_SPACESHIP,
+ EL_BD_BUTTERFLY,
+ EL_BD_FIREFLY,
+ EL_YAMYAM,
+ EL_DARK_YAMYAM,
EL_ROBOT,
EL_PACMAN,
+ EL_MOLE,
+ EL_PENGUIN,
+ EL_PIG,
+ EL_DRAGON,
+ EL_SATELLITE,
EL_SP_SNIKSNAK,
- EL_SP_ELECTRON
- };
- static int ep_enemy_num = SIZEOF_ARRAY_INT(ep_enemy);
-
- static int ep_mauer[] =
- {
- EL_BETON,
- EL_PFORTE1,
- EL_PFORTE2,
- EL_PFORTE3,
- EL_PFORTE4,
- EL_PFORTE1X,
- EL_PFORTE2X,
- EL_PFORTE3X,
- EL_PFORTE4X,
- EL_EM_GATE_1,
- EL_EM_GATE_2,
- EL_EM_GATE_3,
- EL_EM_GATE_4,
- EL_EM_GATE_1X,
- EL_EM_GATE_2X,
- EL_EM_GATE_3X,
- EL_EM_GATE_4X,
- EL_AUSGANG_ZU,
- EL_AUSGANG_ACT,
- EL_AUSGANG_AUF,
- EL_MAUERWERK,
- EL_FELSBODEN,
- EL_MAUER_LEBT,
- EL_MAUER_X,
- EL_MAUER_Y,
- EL_MAUER_XY,
- EL_MAUERND,
- EL_BD_WALL,
- EL_SP_CHIP_SINGLE,
- EL_SP_CHIP_LEFT,
- EL_SP_CHIP_RIGHT,
- EL_SP_CHIP_UPPER,
- EL_SP_CHIP_LOWER,
- EL_SP_HARD_GRAY,
- EL_SP_HARD_GREEN,
- EL_SP_HARD_BLUE,
- EL_SP_HARD_RED,
- EL_SP_HARD_YELLOW,
- EL_SP_HARD_BASE1,
- EL_SP_HARD_BASE2,
- EL_SP_HARD_BASE3,
- EL_SP_HARD_BASE4,
- EL_SP_HARD_BASE5,
- EL_SP_HARD_BASE6,
- EL_SP_TERMINAL,
- EL_SP_TERMINAL_ACTIVE,
- EL_SP_EXIT,
- EL_INVISIBLE_STEEL,
- EL_STEEL_SLANTED,
- EL_EMC_STEEL_WALL_1,
- EL_EMC_STEEL_WALL_2,
- EL_EMC_STEEL_WALL_3,
- EL_EMC_STEEL_WALL_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_SP_ELECTRON,
+ EL_BALLOON,
+ EL_SPRING,
+ -1
};
- static int ep_mauer_num = SIZEOF_ARRAY_INT(ep_mauer);
static int ep_can_fall[] =
{
- EL_FELSBROCKEN,
+ EL_ROCK,
EL_BD_ROCK,
- EL_EDELSTEIN,
- EL_EDELSTEIN_BD,
- EL_EDELSTEIN_GELB,
- EL_EDELSTEIN_ROT,
- EL_EDELSTEIN_LILA,
- EL_DIAMANT,
- EL_BOMBE,
- EL_KOKOSNUSS,
- EL_TROPFEN,
- EL_MORAST_VOLL,
+ EL_EMERALD,
+ EL_BD_DIAMOND,
+ EL_EMERALD_YELLOW,
+ EL_EMERALD_RED,
+ EL_EMERALD_PURPLE,
+ EL_DIAMOND,
+ EL_BOMB,
+ EL_NUT,
+ EL_AMOEBA_DROP,
+ EL_QUICKSAND_FULL,
EL_MAGIC_WALL_FULL,
- EL_MAGIC_WALL_BD_FULL,
- EL_ZEIT_VOLL,
- EL_ZEIT_LEER,
+ EL_BD_MAGIC_WALL_FULL,
+ EL_TIME_ORB_FULL,
+ EL_TIME_ORB_EMPTY,
EL_SP_ZONK,
EL_SP_INFOTRON,
EL_SP_DISK_ORANGE,
EL_PEARL,
EL_CRYSTAL,
EL_SPRING,
- EL_DX_SUPABOMB
+ EL_DX_SUPABOMB,
+ -1
};
- static int ep_can_fall_num = SIZEOF_ARRAY_INT(ep_can_fall);
- static int ep_can_smash[] =
+ static int ep_can_smash_player[] =
{
- EL_FELSBROCKEN,
+ EL_ROCK,
EL_BD_ROCK,
- EL_EDELSTEIN,
- EL_EDELSTEIN_BD,
- EL_EDELSTEIN_GELB,
- EL_EDELSTEIN_ROT,
- EL_EDELSTEIN_LILA,
- EL_DIAMANT,
- EL_SCHLUESSEL1,
- EL_SCHLUESSEL2,
- EL_SCHLUESSEL3,
- EL_SCHLUESSEL4,
- EL_EM_KEY_1,
- EL_EM_KEY_2,
- EL_EM_KEY_3,
- EL_EM_KEY_4,
- EL_BOMBE,
- EL_KOKOSNUSS,
- EL_TROPFEN,
- EL_ZEIT_VOLL,
- EL_ZEIT_LEER,
+ EL_EMERALD,
+ EL_BD_DIAMOND,
+ EL_EMERALD_YELLOW,
+ EL_EMERALD_RED,
+ EL_EMERALD_PURPLE,
+ EL_DIAMOND,
+ EL_BOMB,
+ EL_NUT,
+ EL_AMOEBA_DROP,
+ EL_TIME_ORB_FULL,
+ EL_TIME_ORB_EMPTY,
EL_SP_ZONK,
EL_SP_INFOTRON,
EL_SP_DISK_ORANGE,
EL_PEARL,
EL_CRYSTAL,
EL_SPRING,
- EL_DX_SUPABOMB
+ EL_DX_SUPABOMB,
+ -1
};
- static int ep_can_smash_num = SIZEOF_ARRAY_INT(ep_can_smash);
- static int ep_can_change[] =
+ static int ep_can_smash_enemies[] =
{
- EL_FELSBROCKEN,
+ EL_ROCK,
EL_BD_ROCK,
- EL_EDELSTEIN,
- EL_EDELSTEIN_BD,
- EL_EDELSTEIN_GELB,
- EL_EDELSTEIN_ROT,
- EL_EDELSTEIN_LILA,
- EL_DIAMANT
+ EL_SP_ZONK,
+ -1
};
- static int ep_can_change_num = SIZEOF_ARRAY_INT(ep_can_change);
- static int ep_can_move[] =
+ static int ep_can_smash_everything[] =
{
- EL_KAEFER,
- EL_FLIEGER,
- EL_BUTTERFLY,
- EL_FIREFLY,
- EL_MAMPFER,
- EL_MAMPFER2,
- EL_ROBOT,
- EL_PACMAN,
+ EL_ROCK,
+ EL_BD_ROCK,
+ EL_SP_ZONK,
+ -1
+ };
+
+ static int ep_can_explode_by_fire[] =
+ {
+ /* same elements as in 'ep_can_explode_impact' */
+ EL_BOMB,
+ EL_SP_DISK_ORANGE,
+ EL_DX_SUPABOMB,
+
+ /* same elements as in 'ep_can_explode_smashed' */
+ EL_SATELLITE,
+ EL_PIG,
+ EL_DRAGON,
EL_MOLE,
- EL_PINGUIN,
- EL_SCHWEIN,
- EL_DRACHE,
- EL_SONDE,
+
+ /* new elements */
+ EL_DYNAMITE_ACTIVE,
+ EL_DYNAMITE,
+ EL_DYNABOMB_PLAYER_1_ACTIVE,
+ EL_DYNABOMB_PLAYER_2_ACTIVE,
+ EL_DYNABOMB_PLAYER_3_ACTIVE,
+ EL_DYNABOMB_PLAYER_4_ACTIVE,
+ EL_DYNABOMB_INCREASE_NUMBER,
+ EL_DYNABOMB_INCREASE_SIZE,
+ EL_DYNABOMB_INCREASE_POWER,
+ EL_SP_DISK_RED_ACTIVE,
+ EL_BUG,
+ EL_PENGUIN,
+ EL_SP_DISK_RED,
+ EL_SP_DISK_YELLOW,
EL_SP_SNIKSNAK,
EL_SP_ELECTRON,
+ -1
+ };
+
+ static int ep_can_explode_smashed[] =
+ {
+ /* same elements as in 'ep_can_explode_impact' */
+ EL_BOMB,
+ EL_SP_DISK_ORANGE,
+ EL_DX_SUPABOMB,
+
+ /* new elements */
+ EL_SATELLITE,
+ EL_PIG,
+ EL_DRAGON,
+ EL_MOLE,
+ -1
+ };
+
+ static int ep_can_explode_impact[] =
+ {
+ EL_BOMB,
+ EL_SP_DISK_ORANGE,
+ EL_DX_SUPABOMB,
+ -1
+ };
+
+ static int ep_walkable_over[] =
+ {
+ EL_EMPTY_SPACE,
+ EL_SP_EMPTY_SPACE,
+ EL_SOKOBAN_FIELD_EMPTY,
+ EL_EXIT_OPEN,
+ EL_SP_EXIT_OPEN,
+ EL_GATE_1,
+ EL_GATE_2,
+ EL_GATE_3,
+ EL_GATE_4,
+ EL_GATE_1_GRAY,
+ EL_GATE_2_GRAY,
+ EL_GATE_3_GRAY,
+ EL_GATE_4_GRAY,
+ EL_PENGUIN,
+ EL_PIG,
+ EL_DRAGON,
+ -1
+ };
+
+ static int ep_walkable_inside[] =
+ {
+ EL_TUBE_ANY,
+ EL_TUBE_VERTICAL,
+ EL_TUBE_HORIZONTAL,
+ EL_TUBE_VERTICAL_LEFT,
+ EL_TUBE_VERTICAL_RIGHT,
+ EL_TUBE_HORIZONTAL_UP,
+ EL_TUBE_HORIZONTAL_DOWN,
+ EL_TUBE_LEFT_UP,
+ EL_TUBE_LEFT_DOWN,
+ EL_TUBE_RIGHT_UP,
+ EL_TUBE_RIGHT_DOWN,
+ -1
+ };
+
+ static int ep_walkable_under[] =
+ {
+ -1
+ };
+
+ static int ep_passable_over[] =
+ {
+ EL_EM_GATE_1,
+ EL_EM_GATE_2,
+ EL_EM_GATE_3,
+ EL_EM_GATE_4,
+ EL_EM_GATE_1_GRAY,
+ EL_EM_GATE_2_GRAY,
+ EL_EM_GATE_3_GRAY,
+ EL_EM_GATE_4_GRAY,
+ EL_SWITCHGATE_OPEN,
+ EL_TIMEGATE_OPEN,
+ -1
+ };
+
+ static int ep_passable_inside[] =
+ {
+ EL_SP_PORT_LEFT,
+ EL_SP_PORT_RIGHT,
+ EL_SP_PORT_UP,
+ EL_SP_PORT_DOWN,
+ EL_SP_PORT_HORIZONTAL,
+ EL_SP_PORT_VERTICAL,
+ EL_SP_PORT_ANY,
+ EL_SP_GRAVITY_PORT_LEFT,
+ EL_SP_GRAVITY_PORT_RIGHT,
+ EL_SP_GRAVITY_PORT_UP,
+ EL_SP_GRAVITY_PORT_DOWN,
+ -1
+ };
+
+ static int ep_passable_under[] =
+ {
+ -1
+ };
+
+ static int ep_pushable[] =
+ {
+ EL_ROCK,
+ EL_BOMB,
+ EL_DX_SUPABOMB,
+ EL_NUT,
+ EL_TIME_ORB_EMPTY,
+ EL_SP_ZONK,
+ EL_SP_DISK_ORANGE,
+ EL_SPRING,
+ EL_BD_ROCK,
+ EL_SOKOBAN_OBJECT,
+ EL_SOKOBAN_FIELD_FULL,
+ EL_SATELLITE,
+ EL_SP_DISK_YELLOW,
EL_BALLOON,
- EL_SPRING_MOVING
+ -1
+ };
+
+ static int ep_can_be_crumbled[] =
+ {
+ EL_SAND,
+ EL_LANDMINE,
+ EL_TRAP,
+ EL_TRAP_ACTIVE,
+ -1
+ };
+
+ static int ep_player[] =
+ {
+ EL_PLAYER_1,
+ EL_PLAYER_2,
+ EL_PLAYER_3,
+ EL_PLAYER_4,
+ -1
+ };
+
+ static int ep_can_pass_magic_wall[] =
+ {
+ EL_ROCK,
+ EL_BD_ROCK,
+ EL_EMERALD,
+ EL_BD_DIAMOND,
+ EL_EMERALD_YELLOW,
+ EL_EMERALD_RED,
+ EL_EMERALD_PURPLE,
+ EL_DIAMOND,
+ -1
+ };
+
+ static int ep_switchable[] =
+ {
+ EL_ROBOT_WHEEL,
+ EL_SP_TERMINAL,
+ EL_CONVEYOR_BELT_1_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_1_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_1_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_2_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_2_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_2_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_3_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_3_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_3_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_4_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_4_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_4_SWITCH_RIGHT,
+ EL_SWITCHGATE_SWITCH_UP,
+ EL_SWITCHGATE_SWITCH_DOWN,
+ EL_LIGHT_SWITCH,
+ EL_LIGHT_SWITCH_ACTIVE,
+ EL_TIMEGATE_SWITCH,
+ EL_BALLOON_SWITCH_LEFT,
+ EL_BALLOON_SWITCH_RIGHT,
+ EL_BALLOON_SWITCH_UP,
+ EL_BALLOON_SWITCH_DOWN,
+ EL_BALLOON_SWITCH_ANY,
+ EL_LAMP,
+ EL_TIME_ORB_FULL,
+ -1
+ };
+
+ static int ep_bd_element[] =
+ {
+ EL_EMPTY,
+ EL_SAND,
+ EL_WALL_SLIPPERY,
+ EL_BD_WALL,
+ EL_ROCK,
+ EL_BD_ROCK,
+ EL_BD_DIAMOND,
+ EL_BD_MAGIC_WALL,
+ EL_EXIT_CLOSED,
+ EL_EXIT_OPEN,
+ EL_STEELWALL,
+ EL_PLAYER_1,
+ EL_BD_FIREFLY,
+ EL_BD_FIREFLY_1,
+ EL_BD_FIREFLY_2,
+ EL_BD_FIREFLY_3,
+ EL_BD_FIREFLY_4,
+ EL_BD_BUTTERFLY,
+ EL_BD_BUTTERFLY_1,
+ EL_BD_BUTTERFLY_2,
+ EL_BD_BUTTERFLY_3,
+ EL_BD_BUTTERFLY_4,
+ EL_BD_AMOEBA,
+ EL_CHAR_QUESTION,
+ -1
+ };
+
+ static int ep_sp_element[] =
+ {
+ EL_SP_EMPTY,
+ EL_SP_ZONK,
+ EL_SP_BASE,
+ EL_SP_MURPHY,
+ EL_SP_INFOTRON,
+ EL_SP_CHIP_SINGLE,
+ EL_SP_HARDWARE_GRAY,
+ EL_SP_EXIT_CLOSED,
+ EL_SP_EXIT_OPEN,
+ EL_SP_DISK_ORANGE,
+ EL_SP_PORT_RIGHT,
+ EL_SP_PORT_DOWN,
+ EL_SP_PORT_LEFT,
+ EL_SP_PORT_UP,
+ EL_SP_GRAVITY_PORT_RIGHT,
+ EL_SP_GRAVITY_PORT_DOWN,
+ EL_SP_GRAVITY_PORT_LEFT,
+ EL_SP_GRAVITY_PORT_UP,
+ EL_SP_SNIKSNAK,
+ EL_SP_DISK_YELLOW,
+ EL_SP_TERMINAL,
+ EL_SP_DISK_RED,
+ EL_SP_PORT_VERTICAL,
+ EL_SP_PORT_HORIZONTAL,
+ EL_SP_PORT_ANY,
+ EL_SP_ELECTRON,
+ EL_SP_BUGGY_BASE,
+ EL_SP_CHIP_LEFT,
+ EL_SP_CHIP_RIGHT,
+ EL_SP_HARDWARE_BASE_1,
+ EL_SP_HARDWARE_GREEN,
+ EL_SP_HARDWARE_BLUE,
+ EL_SP_HARDWARE_RED,
+ EL_SP_HARDWARE_YELLOW,
+ EL_SP_HARDWARE_BASE_2,
+ EL_SP_HARDWARE_BASE_3,
+ EL_SP_HARDWARE_BASE_4,
+ EL_SP_HARDWARE_BASE_5,
+ EL_SP_HARDWARE_BASE_6,
+ EL_SP_CHIP_TOP,
+ EL_SP_CHIP_BOTTOM,
+ /* additional elements that appeared in newer Supaplex levels */
+ EL_INVISIBLE_WALL,
+ /* more than one murphy in a level results in an inactive clone */
+ EL_SP_MURPHY_CLONE,
+ /* runtime elements*/
+ EL_SP_DISK_RED_ACTIVE,
+ EL_SP_TERMINAL_ACTIVE,
+ EL_SP_BUGGY_BASE_ACTIVATING,
+ EL_SP_BUGGY_BASE_ACTIVE,
+ -1
+ };
+
+ static int ep_sb_element[] =
+ {
+ EL_EMPTY,
+ EL_STEELWALL,
+ EL_SOKOBAN_OBJECT,
+ EL_SOKOBAN_FIELD_EMPTY,
+ EL_SOKOBAN_FIELD_FULL,
+ EL_PLAYER_1,
+ EL_INVISIBLE_STEELWALL,
+ -1
+ };
+
+ static int ep_gem[] =
+ {
+ EL_BD_DIAMOND,
+ EL_EMERALD,
+ EL_EMERALD_YELLOW,
+ EL_EMERALD_RED,
+ EL_EMERALD_PURPLE,
+ EL_DIAMOND,
+ -1
+ };
+
+ static int ep_food_dark_yamyam[] =
+ {
+ EL_SAND,
+ EL_BUG,
+ EL_SPACESHIP,
+ EL_BD_BUTTERFLY,
+ EL_BD_FIREFLY,
+ EL_YAMYAM,
+ EL_ROBOT,
+ EL_PACMAN,
+ EL_AMOEBA_DROP,
+ EL_AMOEBA_DEAD,
+ EL_AMOEBA_WET,
+ EL_AMOEBA_DRY,
+ EL_AMOEBA_FULL,
+ EL_BD_AMOEBA,
+ EL_EMERALD,
+ EL_BD_DIAMOND,
+ EL_EMERALD_YELLOW,
+ EL_EMERALD_RED,
+ EL_EMERALD_PURPLE,
+ EL_DIAMOND,
+ EL_PEARL,
+ EL_CRYSTAL,
+ -1
+ };
+
+ static int ep_food_penguin[] =
+ {
+ EL_EMERALD,
+ EL_BD_DIAMOND,
+ EL_EMERALD_YELLOW,
+ EL_EMERALD_RED,
+ EL_EMERALD_PURPLE,
+ EL_DIAMOND,
+ EL_PEARL,
+ EL_CRYSTAL,
+ -1
+ };
+
+ static int ep_food_pig[] =
+ {
+ EL_EMERALD,
+ EL_BD_DIAMOND,
+ EL_EMERALD_YELLOW,
+ EL_EMERALD_RED,
+ EL_EMERALD_PURPLE,
+ EL_DIAMOND,
+ -1
+ };
+
+ static int ep_historic_wall[] =
+ {
+ EL_STEELWALL,
+ EL_GATE_1,
+ EL_GATE_2,
+ EL_GATE_3,
+ EL_GATE_4,
+ EL_GATE_1_GRAY,
+ EL_GATE_2_GRAY,
+ EL_GATE_3_GRAY,
+ EL_GATE_4_GRAY,
+ EL_EM_GATE_1,
+ EL_EM_GATE_2,
+ EL_EM_GATE_3,
+ EL_EM_GATE_4,
+ EL_EM_GATE_1_GRAY,
+ EL_EM_GATE_2_GRAY,
+ EL_EM_GATE_3_GRAY,
+ EL_EM_GATE_4_GRAY,
+ EL_EXIT_CLOSED,
+ EL_EXIT_OPENING,
+ EL_EXIT_OPEN,
+ EL_WALL,
+ EL_WALL_SLIPPERY,
+ EL_EXPANDABLE_WALL,
+ EL_EXPANDABLE_WALL_HORIZONTAL,
+ EL_EXPANDABLE_WALL_VERTICAL,
+ EL_EXPANDABLE_WALL_ANY,
+ EL_EXPANDABLE_WALL_GROWING,
+ EL_BD_WALL,
+ EL_SP_CHIP_SINGLE,
+ EL_SP_CHIP_LEFT,
+ EL_SP_CHIP_RIGHT,
+ EL_SP_CHIP_TOP,
+ EL_SP_CHIP_BOTTOM,
+ EL_SP_HARDWARE_GRAY,
+ EL_SP_HARDWARE_GREEN,
+ EL_SP_HARDWARE_BLUE,
+ EL_SP_HARDWARE_RED,
+ EL_SP_HARDWARE_YELLOW,
+ EL_SP_HARDWARE_BASE_1,
+ EL_SP_HARDWARE_BASE_2,
+ EL_SP_HARDWARE_BASE_3,
+ EL_SP_HARDWARE_BASE_4,
+ EL_SP_HARDWARE_BASE_5,
+ EL_SP_HARDWARE_BASE_6,
+ EL_SP_TERMINAL,
+ EL_SP_TERMINAL_ACTIVE,
+ EL_SP_EXIT_CLOSED,
+ EL_SP_EXIT_OPEN,
+ EL_INVISIBLE_STEELWALL,
+ EL_INVISIBLE_STEELWALL_ACTIVE,
+ EL_INVISIBLE_WALL,
+ EL_INVISIBLE_WALL_ACTIVE,
+ EL_STEELWALL_SLIPPERY,
+ EL_EMC_STEELWALL_1,
+ EL_EMC_STEELWALL_2,
+ EL_EMC_STEELWALL_3,
+ EL_EMC_STEELWALL_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,
+ -1
+ };
+
+ static int ep_historic_solid[] =
+ {
+ EL_WALL,
+ EL_EXPANDABLE_WALL,
+ EL_EXPANDABLE_WALL_HORIZONTAL,
+ EL_EXPANDABLE_WALL_VERTICAL,
+ EL_EXPANDABLE_WALL_ANY,
+ EL_BD_WALL,
+ EL_WALL_SLIPPERY,
+ EL_EXIT_CLOSED,
+ EL_EXIT_OPENING,
+ EL_EXIT_OPEN,
+ EL_AMOEBA_DEAD,
+ EL_AMOEBA_WET,
+ EL_AMOEBA_DRY,
+ EL_AMOEBA_FULL,
+ EL_BD_AMOEBA,
+ EL_QUICKSAND_EMPTY,
+ EL_QUICKSAND_FULL,
+ EL_QUICKSAND_FILLING,
+ EL_QUICKSAND_EMPTYING,
+ EL_MAGIC_WALL,
+ EL_MAGIC_WALL_ACTIVE,
+ EL_MAGIC_WALL_EMPTYING,
+ EL_MAGIC_WALL_FILLING,
+ EL_MAGIC_WALL_FULL,
+ EL_MAGIC_WALL_DEAD,
+ EL_BD_MAGIC_WALL,
+ EL_BD_MAGIC_WALL_ACTIVE,
+ EL_BD_MAGIC_WALL_EMPTYING,
+ EL_BD_MAGIC_WALL_FULL,
+ EL_BD_MAGIC_WALL_FILLING,
+ EL_BD_MAGIC_WALL_DEAD,
+ EL_GAME_OF_LIFE,
+ EL_BIOMAZE,
+ EL_SP_CHIP_SINGLE,
+ EL_SP_CHIP_LEFT,
+ EL_SP_CHIP_RIGHT,
+ EL_SP_CHIP_TOP,
+ EL_SP_CHIP_BOTTOM,
+ EL_SP_TERMINAL,
+ EL_SP_TERMINAL_ACTIVE,
+ EL_SP_EXIT_CLOSED,
+ EL_SP_EXIT_OPEN,
+ EL_INVISIBLE_WALL,
+ EL_INVISIBLE_WALL_ACTIVE,
+ EL_SWITCHGATE_SWITCH_UP,
+ EL_SWITCHGATE_SWITCH_DOWN,
+ EL_TIMEGATE_SWITCH,
+ EL_TIMEGATE_SWITCH_ACTIVE,
+ 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_WALL_PEARL,
+ EL_WALL_CRYSTAL,
+
+ /* the following elements are a direct copy of "indestructible" elements,
+ except "EL_ACID", which is "indestructible", but not "solid"! */
+#if 0
+ EL_ACID,
+#endif
+ EL_STEELWALL,
+ EL_ACID_POOL_TOPLEFT,
+ EL_ACID_POOL_TOPRIGHT,
+ EL_ACID_POOL_BOTTOMLEFT,
+ EL_ACID_POOL_BOTTOM,
+ EL_ACID_POOL_BOTTOMRIGHT,
+ EL_SP_HARDWARE_GRAY,
+ EL_SP_HARDWARE_GREEN,
+ EL_SP_HARDWARE_BLUE,
+ EL_SP_HARDWARE_RED,
+ EL_SP_HARDWARE_YELLOW,
+ EL_SP_HARDWARE_BASE_1,
+ EL_SP_HARDWARE_BASE_2,
+ EL_SP_HARDWARE_BASE_3,
+ EL_SP_HARDWARE_BASE_4,
+ EL_SP_HARDWARE_BASE_5,
+ EL_SP_HARDWARE_BASE_6,
+ EL_INVISIBLE_STEELWALL,
+ EL_INVISIBLE_STEELWALL_ACTIVE,
+ EL_CONVEYOR_BELT_1_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_1_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_1_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_2_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_2_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_2_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_3_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_3_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_3_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_4_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_4_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_4_SWITCH_RIGHT,
+ EL_LIGHT_SWITCH,
+ EL_LIGHT_SWITCH_ACTIVE,
+ EL_SIGN_EXCLAMATION,
+ EL_SIGN_RADIOACTIVITY,
+ EL_SIGN_STOP,
+ EL_SIGN_WHEELCHAIR,
+ EL_SIGN_PARKING,
+ EL_SIGN_ONEWAY,
+ EL_SIGN_HEART,
+ EL_SIGN_TRIANGLE,
+ EL_SIGN_ROUND,
+ EL_SIGN_EXIT,
+ EL_SIGN_YINYANG,
+ EL_SIGN_OTHER,
+ EL_STEELWALL_SLIPPERY,
+ EL_EMC_STEELWALL_1,
+ EL_EMC_STEELWALL_2,
+ EL_EMC_STEELWALL_3,
+ EL_EMC_STEELWALL_4,
+ EL_CRYSTAL,
+ EL_GATE_1,
+ EL_GATE_2,
+ EL_GATE_3,
+ EL_GATE_4,
+ EL_GATE_1_GRAY,
+ EL_GATE_2_GRAY,
+ EL_GATE_3_GRAY,
+ EL_GATE_4_GRAY,
+ EL_EM_GATE_1,
+ EL_EM_GATE_2,
+ EL_EM_GATE_3,
+ EL_EM_GATE_4,
+ EL_EM_GATE_1_GRAY,
+ EL_EM_GATE_2_GRAY,
+ EL_EM_GATE_3_GRAY,
+ EL_EM_GATE_4_GRAY,
+ EL_SWITCHGATE_OPEN,
+ EL_SWITCHGATE_OPENING,
+ EL_SWITCHGATE_CLOSED,
+ EL_SWITCHGATE_CLOSING,
+ EL_TIMEGATE_OPEN,
+ EL_TIMEGATE_OPENING,
+ EL_TIMEGATE_CLOSED,
+ EL_TIMEGATE_CLOSING,
+ EL_TUBE_ANY,
+ EL_TUBE_VERTICAL,
+ EL_TUBE_HORIZONTAL,
+ EL_TUBE_VERTICAL_LEFT,
+ EL_TUBE_VERTICAL_RIGHT,
+ EL_TUBE_HORIZONTAL_UP,
+ EL_TUBE_HORIZONTAL_DOWN,
+ EL_TUBE_LEFT_UP,
+ EL_TUBE_LEFT_DOWN,
+ EL_TUBE_RIGHT_UP,
+ EL_TUBE_RIGHT_DOWN,
+ -1
};
- static int ep_can_move_num = SIZEOF_ARRAY_INT(ep_can_move);
-
- static int ep_could_move[] =
- {
- EL_KAEFER_RIGHT,
- EL_KAEFER_UP,
- EL_KAEFER_LEFT,
- EL_KAEFER_DOWN,
- EL_FLIEGER_RIGHT,
- EL_FLIEGER_UP,
- EL_FLIEGER_LEFT,
- EL_FLIEGER_DOWN,
- EL_BUTTERFLY_RIGHT,
- EL_BUTTERFLY_UP,
- EL_BUTTERFLY_LEFT,
- EL_BUTTERFLY_DOWN,
- EL_FIREFLY_RIGHT,
- EL_FIREFLY_UP,
- EL_FIREFLY_LEFT,
- EL_FIREFLY_DOWN,
- EL_PACMAN_RIGHT,
- EL_PACMAN_UP,
- EL_PACMAN_LEFT,
- EL_PACMAN_DOWN
+
+ static int ep_classic_enemy[] =
+ {
+ EL_BUG,
+ EL_SPACESHIP,
+ EL_BD_BUTTERFLY,
+ EL_BD_FIREFLY,
+
+ EL_YAMYAM,
+ EL_DARK_YAMYAM,
+ EL_ROBOT,
+ EL_PACMAN,
+ EL_SP_SNIKSNAK,
+ EL_SP_ELECTRON,
+ -1
};
- static int ep_could_move_num = SIZEOF_ARRAY_INT(ep_could_move);
- static int ep_dont_touch[] =
- {
- EL_KAEFER,
- EL_FLIEGER,
- EL_BUTTERFLY,
- EL_FIREFLY
- };
- static int ep_dont_touch_num = SIZEOF_ARRAY_INT(ep_dont_touch);
+ static int ep_belt[] =
+ {
+ EL_CONVEYOR_BELT_1_LEFT,
+ EL_CONVEYOR_BELT_1_MIDDLE,
+ EL_CONVEYOR_BELT_1_RIGHT,
+ EL_CONVEYOR_BELT_2_LEFT,
+ EL_CONVEYOR_BELT_2_MIDDLE,
+ EL_CONVEYOR_BELT_2_RIGHT,
+ EL_CONVEYOR_BELT_3_LEFT,
+ EL_CONVEYOR_BELT_3_MIDDLE,
+ EL_CONVEYOR_BELT_3_RIGHT,
+ EL_CONVEYOR_BELT_4_LEFT,
+ EL_CONVEYOR_BELT_4_MIDDLE,
+ EL_CONVEYOR_BELT_4_RIGHT,
+ -1
+ };
+
+ static int ep_belt_active[] =
+ {
+ EL_CONVEYOR_BELT_1_LEFT_ACTIVE,
+ EL_CONVEYOR_BELT_1_MIDDLE_ACTIVE,
+ EL_CONVEYOR_BELT_1_RIGHT_ACTIVE,
+ EL_CONVEYOR_BELT_2_LEFT_ACTIVE,
+ EL_CONVEYOR_BELT_2_MIDDLE_ACTIVE,
+ EL_CONVEYOR_BELT_2_RIGHT_ACTIVE,
+ EL_CONVEYOR_BELT_3_LEFT_ACTIVE,
+ EL_CONVEYOR_BELT_3_MIDDLE_ACTIVE,
+ EL_CONVEYOR_BELT_3_RIGHT_ACTIVE,
+ EL_CONVEYOR_BELT_4_LEFT_ACTIVE,
+ EL_CONVEYOR_BELT_4_MIDDLE_ACTIVE,
+ EL_CONVEYOR_BELT_4_RIGHT_ACTIVE,
+ -1
+ };
+
+ static int ep_belt_switch[] =
+ {
+ EL_CONVEYOR_BELT_1_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_1_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_1_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_2_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_2_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_2_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_3_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_3_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_3_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_4_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_4_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_4_SWITCH_RIGHT,
+ -1
+ };
+
+ static int ep_tube[] =
+ {
+ EL_TUBE_LEFT_UP,
+ EL_TUBE_LEFT_DOWN,
+ EL_TUBE_RIGHT_UP,
+ EL_TUBE_RIGHT_DOWN,
+ EL_TUBE_HORIZONTAL,
+ EL_TUBE_HORIZONTAL_UP,
+ EL_TUBE_HORIZONTAL_DOWN,
+ EL_TUBE_VERTICAL,
+ EL_TUBE_VERTICAL_LEFT,
+ EL_TUBE_VERTICAL_RIGHT,
+ EL_TUBE_ANY,
+ -1
+ };
+
+ static int ep_keygate[] =
+ {
+ EL_GATE_1,
+ EL_GATE_2,
+ EL_GATE_3,
+ EL_GATE_4,
+ EL_GATE_1_GRAY,
+ EL_GATE_2_GRAY,
+ EL_GATE_3_GRAY,
+ EL_GATE_4_GRAY,
+ EL_EM_GATE_1,
+ EL_EM_GATE_2,
+ EL_EM_GATE_3,
+ EL_EM_GATE_4,
+ EL_EM_GATE_1_GRAY,
+ EL_EM_GATE_2_GRAY,
+ EL_EM_GATE_3_GRAY,
+ EL_EM_GATE_4_GRAY,
+ -1
+ };
+
+ static int ep_amoeboid[] =
+ {
+ EL_AMOEBA_DEAD,
+ EL_AMOEBA_WET,
+ EL_AMOEBA_DRY,
+ EL_AMOEBA_FULL,
+ EL_BD_AMOEBA,
+ -1
+ };
+
+ static int ep_amoebalive[] =
+ {
+ EL_AMOEBA_WET,
+ EL_AMOEBA_DRY,
+ EL_AMOEBA_FULL,
+ EL_BD_AMOEBA,
+ -1
+ };
+
+ static int ep_has_content[] =
+ {
+ EL_YAMYAM,
+ EL_AMOEBA_WET,
+ EL_AMOEBA_DRY,
+ EL_AMOEBA_FULL,
+ EL_BD_AMOEBA,
+ -1
+ };
+
+ static int ep_active_bomb[] =
+ {
+ EL_DYNAMITE_ACTIVE,
+ EL_DYNABOMB_PLAYER_1_ACTIVE,
+ EL_DYNABOMB_PLAYER_2_ACTIVE,
+ EL_DYNABOMB_PLAYER_3_ACTIVE,
+ EL_DYNABOMB_PLAYER_4_ACTIVE,
+ EL_SP_DISK_RED_ACTIVE,
+ -1
+ };
+
+ static int ep_inactive[] =
+ {
+ EL_EMPTY,
+ EL_SAND,
+ EL_WALL,
+ EL_BD_WALL,
+ EL_WALL_SLIPPERY,
+ EL_STEELWALL,
+ EL_AMOEBA_DEAD,
+ EL_QUICKSAND_EMPTY,
+ EL_STONEBLOCK,
+ EL_ROBOT_WHEEL,
+ EL_KEY_1,
+ EL_KEY_2,
+ EL_KEY_3,
+ EL_KEY_4,
+ EL_EM_KEY_1,
+ EL_EM_KEY_2,
+ EL_EM_KEY_3,
+ EL_EM_KEY_4,
+ EL_GATE_1,
+ EL_GATE_2,
+ EL_GATE_3,
+ EL_GATE_4,
+ EL_GATE_1_GRAY,
+ EL_GATE_2_GRAY,
+ EL_GATE_3_GRAY,
+ EL_GATE_4_GRAY,
+ EL_EM_GATE_1,
+ EL_EM_GATE_2,
+ EL_EM_GATE_3,
+ EL_EM_GATE_4,
+ EL_EM_GATE_1_GRAY,
+ EL_EM_GATE_2_GRAY,
+ EL_EM_GATE_3_GRAY,
+ EL_EM_GATE_4_GRAY,
+ EL_DYNAMITE,
+ EL_INVISIBLE_STEELWALL,
+ EL_INVISIBLE_WALL,
+ EL_INVISIBLE_SAND,
+ EL_LAMP,
+ EL_LAMP_ACTIVE,
+ EL_WALL_EMERALD,
+ EL_WALL_DIAMOND,
+ EL_WALL_BD_DIAMOND,
+ EL_WALL_EMERALD_YELLOW,
+ EL_DYNABOMB_INCREASE_NUMBER,
+ EL_DYNABOMB_INCREASE_SIZE,
+ EL_DYNABOMB_INCREASE_POWER,
+#if 0
+ EL_SOKOBAN_OBJECT,
+#endif
+ EL_SOKOBAN_FIELD_EMPTY,
+ EL_SOKOBAN_FIELD_FULL,
+ EL_WALL_EMERALD_RED,
+ EL_WALL_EMERALD_PURPLE,
+ EL_ACID_POOL_TOPLEFT,
+ EL_ACID_POOL_TOPRIGHT,
+ EL_ACID_POOL_BOTTOMLEFT,
+ EL_ACID_POOL_BOTTOM,
+ EL_ACID_POOL_BOTTOMRIGHT,
+ EL_MAGIC_WALL,
+ EL_MAGIC_WALL_DEAD,
+ EL_BD_MAGIC_WALL,
+ EL_BD_MAGIC_WALL_DEAD,
+ EL_AMOEBA_TO_DIAMOND,
+ EL_BLOCKED,
+ EL_SP_EMPTY,
+ EL_SP_BASE,
+ EL_SP_PORT_RIGHT,
+ EL_SP_PORT_DOWN,
+ EL_SP_PORT_LEFT,
+ EL_SP_PORT_UP,
+ EL_SP_GRAVITY_PORT_RIGHT,
+ EL_SP_GRAVITY_PORT_DOWN,
+ EL_SP_GRAVITY_PORT_LEFT,
+ EL_SP_GRAVITY_PORT_UP,
+ EL_SP_PORT_HORIZONTAL,
+ EL_SP_PORT_VERTICAL,
+ EL_SP_PORT_ANY,
+ EL_SP_DISK_RED,
+#if 0
+ EL_SP_DISK_YELLOW,
+#endif
+ EL_SP_CHIP_SINGLE,
+ EL_SP_CHIP_LEFT,
+ EL_SP_CHIP_RIGHT,
+ EL_SP_CHIP_TOP,
+ EL_SP_CHIP_BOTTOM,
+ EL_SP_HARDWARE_GRAY,
+ EL_SP_HARDWARE_GREEN,
+ EL_SP_HARDWARE_BLUE,
+ EL_SP_HARDWARE_RED,
+ EL_SP_HARDWARE_YELLOW,
+ EL_SP_HARDWARE_BASE_1,
+ EL_SP_HARDWARE_BASE_2,
+ EL_SP_HARDWARE_BASE_3,
+ EL_SP_HARDWARE_BASE_4,
+ EL_SP_HARDWARE_BASE_5,
+ EL_SP_HARDWARE_BASE_6,
+ EL_CONVEYOR_BELT_1_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_1_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_1_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_2_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_2_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_2_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_3_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_3_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_3_SWITCH_RIGHT,
+ EL_CONVEYOR_BELT_4_SWITCH_LEFT,
+ EL_CONVEYOR_BELT_4_SWITCH_MIDDLE,
+ EL_CONVEYOR_BELT_4_SWITCH_RIGHT,
+ EL_SIGN_EXCLAMATION,
+ EL_SIGN_RADIOACTIVITY,
+ EL_SIGN_STOP,
+ EL_SIGN_WHEELCHAIR,
+ EL_SIGN_PARKING,
+ EL_SIGN_ONEWAY,
+ EL_SIGN_HEART,
+ EL_SIGN_TRIANGLE,
+ EL_SIGN_ROUND,
+ EL_SIGN_EXIT,
+ EL_SIGN_YINYANG,
+ EL_SIGN_OTHER,
+ EL_STEELWALL_SLIPPERY,
+ EL_EMC_STEELWALL_1,
+ EL_EMC_STEELWALL_2,
+ EL_EMC_STEELWALL_3,
+ EL_EMC_STEELWALL_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,
+ -1
+ };
+
+ static struct
+ {
+ int *elements;
+ int property;
+ } element_properties[] =
+ {
+ { ep_diggable, EP_DIGGABLE },
+ { ep_collectible, EP_COLLECTIBLE },
+ { ep_dont_run_into, EP_DONT_RUN_INTO },
+ { ep_dont_collide_with, EP_DONT_COLLIDE_WITH },
+ { ep_dont_touch, EP_DONT_TOUCH },
+ { ep_indestructible, EP_INDESTRUCTIBLE },
+ { ep_slippery, EP_SLIPPERY },
+ { ep_can_change, EP_CAN_CHANGE },
+ { ep_can_move, EP_CAN_MOVE },
+ { ep_can_fall, EP_CAN_FALL },
+ { ep_can_smash_player, EP_CAN_SMASH_PLAYER },
+ { ep_can_smash_enemies, EP_CAN_SMASH_ENEMIES },
+ { ep_can_smash_everything, EP_CAN_SMASH_EVERYTHING },
+ { ep_can_explode_by_fire, EP_CAN_EXPLODE_BY_FIRE },
+ { ep_can_explode_smashed, EP_CAN_EXPLODE_SMASHED },
+ { ep_can_explode_impact, EP_CAN_EXPLODE_IMPACT },
+ { ep_walkable_over, EP_WALKABLE_OVER },
+ { ep_walkable_inside, EP_WALKABLE_INSIDE },
+ { ep_walkable_under, EP_WALKABLE_UNDER },
+ { ep_passable_over, EP_PASSABLE_OVER },
+ { ep_passable_inside, EP_PASSABLE_INSIDE },
+ { ep_passable_under, EP_PASSABLE_UNDER },
+ { ep_pushable, EP_PUSHABLE },
+
+ { ep_can_be_crumbled, EP_CAN_BE_CRUMBLED },
+
+ { ep_player, EP_PLAYER },
+ { ep_can_pass_magic_wall, EP_CAN_PASS_MAGIC_WALL },
+ { ep_switchable, EP_SWITCHABLE },
+ { ep_bd_element, EP_BD_ELEMENT },
+ { ep_sp_element, EP_SP_ELEMENT },
+ { ep_sb_element, EP_SB_ELEMENT },
+ { ep_gem, EP_GEM },
+ { ep_food_dark_yamyam, EP_FOOD_DARK_YAMYAM },
+ { ep_food_penguin, EP_FOOD_PENGUIN },
+ { ep_food_pig, EP_FOOD_PIG },
+ { ep_historic_wall, EP_HISTORIC_WALL },
+ { ep_historic_solid, EP_HISTORIC_SOLID },
+ { ep_classic_enemy, EP_CLASSIC_ENEMY },
+ { ep_belt, EP_BELT },
+ { ep_belt_active, EP_BELT_ACTIVE },
+ { ep_belt_switch, EP_BELT_SWITCH },
+ { ep_tube, EP_TUBE },
+ { ep_keygate, EP_KEYGATE },
+ { ep_amoeboid, EP_AMOEBOID },
+ { ep_amoebalive, EP_AMOEBALIVE },
+ { ep_has_content, EP_HAS_CONTENT },
+ { ep_active_bomb, EP_ACTIVE_BOMB },
+ { ep_inactive, EP_INACTIVE },
+
+ { 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
+ },
+ {
+ -1,
+ -1, -1, -1, -1
+ }
+ };
+
+ int i, j, k;
+
+ /* always start with reliable default values (element has no properties) */
+ for (i=0; i < MAX_NUM_ELEMENTS; i++)
+ for (j=0; j < NUM_ELEMENT_PROPERTIES; j++)
+ SET_PROPERTY(i, j, FALSE);
+
+ /* set all base element properties from above array definitions */
+ for (i=0; element_properties[i].elements != NULL; i++)
+ for (j=0; (element_properties[i].elements)[j] != -1; j++)
+ SET_PROPERTY((element_properties[i].elements)[j],
+ element_properties[i].property, TRUE);
+
+ /* copy properties to some elements that are only stored in level file */
+ for (i=0; i < NUM_ELEMENT_PROPERTIES; i++)
+ for (j=0; copy_properties[j][0] != -1; j++)
+ if (HAS_PROPERTY(copy_properties[j][0], i))
+ for (k=1; k<=4; k++)
+ SET_PROPERTY(copy_properties[j][k], i, TRUE);
+}
+
+void InitElementPropertiesEngine(int engine_version)
+{
+#if 0
+ static int active_properties[] =
+ {
+ EP_AMOEBALIVE,
+ EP_AMOEBOID,
+ EP_PFORTE,
+ EP_DONT_COLLIDE_WITH,
+ EP_MAUER,
+ EP_CAN_FALL,
+ EP_CAN_SMASH,
+ EP_CAN_PASS_MAGIC_WALL,
+ EP_CAN_MOVE,
+ EP_DONT_TOUCH,
+ EP_DONT_RUN_INTO,
+ EP_GEM,
+ EP_CAN_EXPLODE_BY_FIRE,
+ EP_PUSHABLE,
+ EP_PLAYER,
+ EP_HAS_CONTENT,
+ EP_DIGGABLE,
+ EP_PASSABLE_INSIDE,
+ EP_OVER_PLAYER,
+ EP_ACTIVE_BOMB,
+
+ EP_BELT,
+ EP_BELT_ACTIVE,
+ EP_BELT_SWITCH,
+ EP_WALKABLE_UNDER,
+ EP_EM_SLIPPERY_WALL,
+ EP_CAN_BE_CRUMBLED,
+ };
+#endif
+
+ static int no_wall_properties[] =
+ {
+ EP_DIGGABLE,
+ EP_COLLECTIBLE,
+ EP_DONT_RUN_INTO,
+ EP_DONT_COLLIDE_WITH,
+ EP_CAN_MOVE,
+ EP_CAN_FALL,
+ EP_CAN_SMASH_PLAYER,
+ EP_CAN_SMASH_ENEMIES,
+ EP_CAN_SMASH_EVERYTHING,
+ EP_PUSHABLE,
+
+ EP_CAN_BE_CRUMBLED,
+
+ EP_PLAYER,
+ EP_GEM,
+ EP_FOOD_DARK_YAMYAM,
+ EP_FOOD_PENGUIN,
+ EP_BELT,
+ EP_BELT_ACTIVE,
+ EP_TUBE,
+ EP_AMOEBOID,
+ EP_AMOEBALIVE,
+ EP_ACTIVE_BOMB,
+
+ EP_ACCESSIBLE,
+ -1
+ };
+
+ int i, j;
+
+#if 0
+ InitElementPropertiesStatic();
+#endif
+
+ /* set all special, combined or engine dependent element properties */
+ for (i=0; i < MAX_NUM_ELEMENTS; i++)
+ {
+#if 0
+ for (j=EP_ACCESSIBLE_OVER; j < NUM_ELEMENT_PROPERTIES; j++)
+ SET_PROPERTY(i, j, FALSE);
+#endif
+
+ /* ---------- INACTIVE ------------------------------------------------- */
+ if (i >= EL_CHAR_START && i <= EL_CHAR_END)
+ SET_PROPERTY(i, EP_INACTIVE, TRUE);
+
+ /* ---------- WALKABLE, PASSABLE, ACCESSIBLE --------------------------- */
+ SET_PROPERTY(i, EP_WALKABLE, (IS_WALKABLE_OVER(i) ||
+ IS_WALKABLE_INSIDE(i) ||
+ IS_WALKABLE_UNDER(i)));
+
+ SET_PROPERTY(i, EP_PASSABLE, (IS_PASSABLE_OVER(i) ||
+ IS_PASSABLE_INSIDE(i) ||
+ IS_PASSABLE_UNDER(i)));
+
+ SET_PROPERTY(i, EP_ACCESSIBLE_OVER, (IS_WALKABLE_OVER(i) ||
+ IS_PASSABLE_OVER(i)));
+
+ SET_PROPERTY(i, EP_ACCESSIBLE_INSIDE, (IS_WALKABLE_INSIDE(i) ||
+ IS_PASSABLE_INSIDE(i)));
+
+ SET_PROPERTY(i, EP_ACCESSIBLE_UNDER, (IS_WALKABLE_UNDER(i) ||
+ IS_PASSABLE_UNDER(i)));
+
+ SET_PROPERTY(i, EP_ACCESSIBLE, (IS_WALKABLE(i) ||
+ IS_PASSABLE(i)));
+
+ /* ---------- SNAPPABLE ------------------------------------------------ */
+ SET_PROPERTY(i, EP_SNAPPABLE, (IS_DIGGABLE(i) ||
+ IS_COLLECTIBLE(i) ||
+ IS_SWITCHABLE(i) ||
+ i == EL_BD_ROCK));
+
+ /* ---------- WALL ----------------------------------------------------- */
+ SET_PROPERTY(i, EP_WALL, TRUE); /* default: element is wall */
+
+ for (j=0; no_wall_properties[j] != -1; j++)
+ if (HAS_PROPERTY(i, no_wall_properties[j]) ||
+ i >= EL_FIRST_RUNTIME_UNREAL)
+ SET_PROPERTY(i, EP_WALL, FALSE);
+
+ if (IS_HISTORIC_WALL(i))
+ SET_PROPERTY(i, EP_WALL, TRUE);
+
+ /* ---------- SOLID_FOR_PUSHING ---------------------------------------- */
+ if (engine_version < VERSION_IDENT(2,2,0))
+ SET_PROPERTY(i, EP_SOLID_FOR_PUSHING, IS_HISTORIC_SOLID(i));
+ else
+ SET_PROPERTY(i, EP_SOLID_FOR_PUSHING, (!IS_WALKABLE(i) &&
+ !IS_DIGGABLE(i) &&
+ !IS_COLLECTIBLE(i)));
+
+ /* ---------- DRAGONFIRE_PROOF ----------------------------------------- */
+
+ if (IS_HISTORIC_SOLID(i) || i == EL_EXPLOSION)
+ SET_PROPERTY(i, EP_DRAGONFIRE_PROOF, TRUE);
+ else
+ SET_PROPERTY(i, EP_DRAGONFIRE_PROOF, (IS_CUSTOM_ELEMENT(i) &&
+ IS_INDESTRUCTIBLE(i)));
+
+ /* ---------- EXPLOSION_PROOF ------------------------------------------ */
+ if (i == EL_FLAMES)
+ SET_PROPERTY(i, EP_EXPLOSION_PROOF, TRUE);
+ else if (engine_version < VERSION_IDENT(2,2,0))
+ SET_PROPERTY(i, EP_EXPLOSION_PROOF, IS_INDESTRUCTIBLE(i));
+ else
+ SET_PROPERTY(i, EP_EXPLOSION_PROOF, (IS_INDESTRUCTIBLE(i) &&
+ !IS_WALKABLE_OVER(i) &&
+ !IS_WALKABLE_UNDER(i)));
+
+ if (IS_CUSTOM_ELEMENT(i))
+ {
+ /* ---------- DONT_COLLIDE_WITH / DONT_RUN_INTO ---------------------- */
+ if (DONT_TOUCH(i))
+ SET_PROPERTY(i, EP_DONT_COLLIDE_WITH, TRUE);
+ if (DONT_COLLIDE_WITH(i))
+ SET_PROPERTY(i, EP_DONT_RUN_INTO, TRUE);
+
+ /* ---------- CAN_SMASH_ENEMIES / CAN_SMASH_PLAYER ------------------- */
+ if (CAN_SMASH_EVERYTHING(i))
+ SET_PROPERTY(i, EP_CAN_SMASH_ENEMIES, TRUE);
+ if (CAN_SMASH_ENEMIES(i))
+ SET_PROPERTY(i, EP_CAN_SMASH_PLAYER, TRUE);
+ }
+
+ /* ---------- CAN_SMASH ------------------------------------------------ */
+ SET_PROPERTY(i, EP_CAN_SMASH, (CAN_SMASH_PLAYER(i) ||
+ CAN_SMASH_ENEMIES(i) ||
+ CAN_SMASH_EVERYTHING(i)));
+
+ /* ---------- CAN_EXPLODE ---------------------------------------------- */
+ SET_PROPERTY(i, EP_CAN_EXPLODE, (CAN_EXPLODE_BY_FIRE(i) ||
+ CAN_EXPLODE_SMASHED(i) ||
+ CAN_EXPLODE_IMPACT(i)));
+
+ /* ---------- CAN_BE_CRUMBLED ------------------------------------------ */
+ SET_PROPERTY(i, EP_CAN_BE_CRUMBLED,
+ element_info[i].crumbled[ACTION_DEFAULT] != IMG_EMPTY);
+
+#if 0
+ if (CAN_BE_CRUMBLED(i))
+ printf("::: '%s' can be crumbled [%d]\n",
+ element_info[i].token_name,
+ element_info[i].crumbled[ACTION_DEFAULT]);
+#endif
+ }
+
+#if 0
+ /* determine inactive elements (used for engine main loop optimization) */
+ for (i=0; i < MAX_NUM_ELEMENTS; i++)
+ {
+ boolean active = FALSE;
+
+ for (j=0; i < NUM_ELEMENT_PROPERTIES; j++)
+ {
+ if (HAS_PROPERTY(i, j))
+ active = TRUE;
+ }
+
+#if 0
+ if (!active)
+ SET_PROPERTY(i, EP_INACTIVE, TRUE);
+#endif
+ }
+#endif
+
+ /* dynamically adjust element properties according to game engine version */
+ {
+ static int ep_em_slippery_wall[] =
+ {
+ EL_STEELWALL,
+ EL_WALL,
+ EL_EXPANDABLE_WALL,
+ EL_EXPANDABLE_WALL_HORIZONTAL,
+ EL_EXPANDABLE_WALL_VERTICAL,
+ EL_EXPANDABLE_WALL_ANY,
+ -1
+ };
+
+ /* special EM style gems behaviour */
+ for (i=0; ep_em_slippery_wall[i] != -1; i++)
+ SET_PROPERTY(ep_em_slippery_wall[i], EP_EM_SLIPPERY_WALL,
+ level.em_slippery_gems);
+
+ /* "EL_EXPANDABLE_WALL_GROWING" wasn't slippery for EM gems in 2.0.1 */
+ SET_PROPERTY(EL_EXPANDABLE_WALL_GROWING, EP_EM_SLIPPERY_WALL,
+ (level.em_slippery_gems &&
+ engine_version > VERSION_IDENT(2,0,1)));
+ }
+
+#if 0
+ /* dynamically adjust element properties according to game engine version */
+#if 0
+ if (engine_version < RELEASE_IDENT(2,2,0,7))
+#endif
+ {
+ for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+ {
+ int element = EL_CUSTOM_START + i;
+
+ element_info[element].push_delay_fixed = 2;
+ element_info[element].push_delay_random = 8;
+ }
+ }
+#endif
+}
+
+static void InitGlobal()
+{
+ global.autoplay_leveldir = NULL;
+
+ global.frames_per_second = 0;
+ global.fps_slowdown = FALSE;
+ global.fps_slowdown_factor = 1;
+}
+
+void Execute_Command(char *command)
+{
+ if (strcmp(command, "print graphicsinfo.conf") == 0)
+ {
+ int i;
+
+ printf("# You can configure additional/alternative image files here.\n");
+ printf("# (The images below are default and therefore commented out.)\n");
+ printf("\n");
+ printf("%s\n", getFormattedSetupEntry("name", "Classic Graphics"));
+ printf("\n");
+ printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
+ printf("\n");
+
+ for (i=0; image_config[i].token != NULL; i++)
+ printf("# %s\n",
+ getFormattedSetupEntry(image_config[i].token,
+ image_config[i].value));
+
+ exit(0);
+ }
+ else if (strcmp(command, "print soundsinfo.conf") == 0)
+ {
+ int i;
+
+ printf("# You can configure additional/alternative sound files here.\n");
+ printf("# (The sounds below are default and therefore commented out.)\n");
+ printf("\n");
+ printf("%s\n", getFormattedSetupEntry("name", "Classic Sounds"));
+ printf("\n");
+ printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
+ printf("\n");
+
+ for (i=0; sound_config[i].token != NULL; i++)
+ printf("# %s\n",
+ getFormattedSetupEntry(sound_config[i].token,
+ sound_config[i].value));
+
+ exit(0);
+ }
+ else if (strcmp(command, "print musicinfo.conf") == 0)
+ {
+ printf("# (Currently only \"name\" and \"sort_priority\" recognized.)\n");
+ printf("\n");
+ printf("%s\n", getFormattedSetupEntry("name", "Classic Music"));
+ printf("\n");
+ printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
+
+ exit(0);
+ }
+ else if (strncmp(command, "dump level ", 11) == 0)
+ {
+ char *filename = &command[11];
+
+ if (access(filename, F_OK) != 0)
+ Error(ERR_EXIT, "cannot open file '%s'", filename);
+
+ LoadLevelFromFilename(&level, filename);
+ DumpLevel(&level);
+
+ exit(0);
+ }
+ else if (strncmp(command, "dump tape ", 10) == 0)
+ {
+ char *filename = &command[10];
+
+ if (access(filename, F_OK) != 0)
+ Error(ERR_EXIT, "cannot open file '%s'", filename);
+
+ LoadTapeFromFilename(filename);
+ DumpTape(&tape);
+
+ exit(0);
+ }
+ else if (strncmp(command, "autoplay ", 9) == 0)
+ {
+ char *str_copy = getStringCopy(&command[9]);
+ char *str_ptr = strchr(str_copy, ' ');
+
+ global.autoplay_leveldir = str_copy;
+ global.autoplay_level_nr = -1;
+
+ if (str_ptr != NULL)
+ {
+ *str_ptr++ = '\0'; /* terminate leveldir string */
+ global.autoplay_level_nr = atoi(str_ptr); /* get level_nr value */
+ }
+ }
+ else
+ {
+ Error(ERR_EXIT_HELP, "unrecognized command '%s'", command);
+ }
+}
+
+static void InitSetup()
+{
+ LoadSetup(); /* global setup info */
+
+ /* set some options from setup file */
+
+ if (setup.options.verbose)
+ options.verbose = TRUE;
+}
+
+static void InitPlayerInfo()
+{
+ int i;
+
+ /* choose default local player */
+ local_player = &stored_player[0];
+
+ for (i=0; i<MAX_PLAYERS; i++)
+ stored_player[i].connected = FALSE;
+
+ local_player->connected = TRUE;
+}
+
+static void InitArtworkInfo()
+{
+ LoadArtworkInfo();
+}
+
+static char *get_string_in_brackets(char *string)
+{
+ char *string_in_brackets = checked_malloc(strlen(string) + 3);
+
+ sprintf(string_in_brackets, "[%s]", string);
+
+ return string_in_brackets;
+}
+
+#if 0
+static char *get_element_class_token(int element)
+{
+ char *element_class_name = element_info[element].class_name;
+ char *element_class_token = checked_malloc(strlen(element_class_name) + 3);
+
+ sprintf(element_class_token, "[%s]", element_class_name);
+
+ return element_class_token;
+}
+
+static char *get_action_class_token(int action)
+{
+ char *action_class_name = &element_action_info[action].suffix[1];
+ char *action_class_token = checked_malloc(strlen(action_class_name) + 3);
+
+ sprintf(action_class_token, "[%s]", action_class_name);
+
+ return action_class_token;
+}
+#endif
+
+static void InitArtworkConfig()
+{
+ static char *image_id_prefix[MAX_NUM_ELEMENTS + NUM_FONTS + 1];
+ static char *sound_id_prefix[2 * MAX_NUM_ELEMENTS + 1];
+ static char *action_id_suffix[NUM_ACTIONS + 1];
+ static char *direction_id_suffix[NUM_DIRECTIONS + 1];
+ static char *special_id_suffix[NUM_SPECIAL_GFX_ARGS + 1];
+ static char *dummy[1] = { NULL };
+ static char *ignore_generic_tokens[] =
+ {
+ "name",
+ "sort_priority",
+ NULL
+ };
+ static char **ignore_image_tokens, **ignore_sound_tokens;
+ int num_ignore_generic_tokens;
+ int num_ignore_image_tokens, num_ignore_sound_tokens;
+ int i;
+
+ /* dynamically determine list of generic tokens to be ignored */
+ num_ignore_generic_tokens = 0;
+ for (i=0; ignore_generic_tokens[i] != NULL; i++)
+ num_ignore_generic_tokens++;
+
+ /* dynamically determine list of image tokens to be ignored */
+ num_ignore_image_tokens = num_ignore_generic_tokens;
+ for (i=0; image_config_vars[i].token != NULL; i++)
+ num_ignore_image_tokens++;
+ ignore_image_tokens =
+ checked_malloc((num_ignore_image_tokens + 1) * sizeof(char *));
+ for (i=0; i < num_ignore_generic_tokens; i++)
+ ignore_image_tokens[i] = ignore_generic_tokens[i];
+ for (i=0; i < num_ignore_image_tokens - num_ignore_generic_tokens; i++)
+ ignore_image_tokens[num_ignore_generic_tokens + i] =
+ image_config_vars[i].token;
+ ignore_image_tokens[num_ignore_image_tokens] = NULL;
+
+ /* dynamically determine list of sound tokens to be ignored */
+ num_ignore_sound_tokens = num_ignore_generic_tokens;
+ ignore_sound_tokens =
+ checked_malloc((num_ignore_sound_tokens + 1) * sizeof(char *));
+ for (i=0; i < num_ignore_generic_tokens; i++)
+ ignore_sound_tokens[i] = ignore_generic_tokens[i];
+ ignore_sound_tokens[num_ignore_sound_tokens] = NULL;
+
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ image_id_prefix[i] = element_info[i].token_name;
+ for (i=0; i<NUM_FONTS; i++)
+ image_id_prefix[MAX_NUM_ELEMENTS + i] = font_info[i].token_name;
+ image_id_prefix[MAX_NUM_ELEMENTS + NUM_FONTS] = NULL;
+
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ sound_id_prefix[i] = element_info[i].token_name;
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ sound_id_prefix[MAX_NUM_ELEMENTS + i] =
+ get_string_in_brackets(element_info[i].class_name);
+ sound_id_prefix[2 * MAX_NUM_ELEMENTS] = NULL;
+
+ for (i=0; i<NUM_ACTIONS; i++)
+ action_id_suffix[i] = element_action_info[i].suffix;
+ action_id_suffix[NUM_ACTIONS] = NULL;
+
+ for (i=0; i<NUM_DIRECTIONS; i++)
+ direction_id_suffix[i] = element_direction_info[i].suffix;
+ direction_id_suffix[NUM_DIRECTIONS] = NULL;
+
+ for (i=0; i<NUM_SPECIAL_GFX_ARGS; i++)
+ special_id_suffix[i] = special_suffix_info[i].suffix;
+ special_id_suffix[NUM_SPECIAL_GFX_ARGS] = NULL;
+
+ InitImageList(image_config, NUM_IMAGE_FILES, image_config_suffix,
+ image_id_prefix, action_id_suffix, direction_id_suffix,
+ special_id_suffix, ignore_image_tokens);
+ InitSoundList(sound_config, NUM_SOUND_FILES, sound_config_suffix,
+ sound_id_prefix, action_id_suffix, dummy,
+ special_id_suffix, ignore_sound_tokens);
+}
+
+static void InitMixer()
+{
+ OpenAudio();
+ StartMixer();
+}
+
+void InitGfx()
+{
+ char *filename_font_initial = NULL;
+ Bitmap *bitmap_font_initial = NULL;
+ int i, j;
+
+ /* determine settings for initial font (for displaying startup messages) */
+ for (i=0; image_config[i].token != NULL; i++)
+ {
+ for (j=0; j < NUM_INITIAL_FONTS; j++)
+ {
+ char font_token[128];
+ int len_font_token;
+
+ sprintf(font_token, "%s_%d", CONFIG_TOKEN_FONT_INITIAL, j + 1);
+ len_font_token = strlen(font_token);
+
+ if (strcmp(image_config[i].token, font_token) == 0)
+ filename_font_initial = image_config[i].value;
+ else if (strlen(image_config[i].token) > len_font_token &&
+ strncmp(image_config[i].token, font_token, len_font_token) == 0)
+ {
+ if (strcmp(&image_config[i].token[len_font_token], ".x") == 0)
+ font_initial[j].src_x = atoi(image_config[i].value);
+ else if (strcmp(&image_config[i].token[len_font_token], ".y") == 0)
+ font_initial[j].src_y = atoi(image_config[i].value);
+ else if (strcmp(&image_config[i].token[len_font_token], ".width") == 0)
+ font_initial[j].width = atoi(image_config[i].value);
+ else if (strcmp(&image_config[i].token[len_font_token],".height") == 0)
+ font_initial[j].height = atoi(image_config[i].value);
+ }
+ }
+ }
+
+ for (j=0; j < NUM_INITIAL_FONTS; j++)
+ {
+ font_initial[j].num_chars = DEFAULT_NUM_CHARS_PER_FONT;
+ font_initial[j].num_chars_per_line = DEFAULT_NUM_CHARS_PER_LINE;
+ }
+
+ if (filename_font_initial == NULL) /* should not happen */
+ Error(ERR_EXIT, "cannot get filename for '%s'", CONFIG_TOKEN_FONT_INITIAL);
+
+ /* create additional image buffers for double-buffering */
+ bitmap_db_field = CreateBitmap(FXSIZE, FYSIZE, DEFAULT_DEPTH);
+ bitmap_db_door = CreateBitmap(3 * DXSIZE, DYSIZE + VYSIZE, DEFAULT_DEPTH);
+
+ /* initialize screen properties */
+ InitGfxFieldInfo(SX, SY, SXSIZE, SYSIZE,
+ REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE,
+ bitmap_db_field);
+ InitGfxDoor1Info(DX, DY, DXSIZE, DYSIZE);
+ InitGfxDoor2Info(VX, VY, VXSIZE, VYSIZE);
+ InitGfxScrollbufferInfo(FXSIZE, FYSIZE);
+
+ bitmap_font_initial = LoadCustomImage(filename_font_initial);
+
+ for (j=0; j < NUM_INITIAL_FONTS; j++)
+ font_initial[j].bitmap = bitmap_font_initial;
+
+ InitFontGraphicInfo();
+
+ DrawInitText(WINDOW_TITLE_STRING, 20, FC_YELLOW);
+ DrawInitText(WINDOW_SUBTITLE_STRING, 50, FC_RED);
+
+ DrawInitText("Loading graphics:", 120, FC_GREEN);
+
+ InitTileClipmasks();
+}
+
+void InitGfxBackground()
+{
+ int x, y;
+
+ drawto = backbuffer;
+ fieldbuffer = bitmap_db_field;
+ SetDrawtoField(DRAW_BACKBUFFER);
+
+ BlitBitmap(graphic_info[IMG_GLOBAL_BORDER].bitmap, backbuffer,
+ 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+ ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
+ ClearRectangle(bitmap_db_door, 0, 0, 3 * DXSIZE, DYSIZE + VYSIZE);
+
+ for (x=0; x<MAX_BUF_XSIZE; x++)
+ for (y=0; y<MAX_BUF_YSIZE; y++)
+ redraw[x][y] = 0;
+ redraw_tiles = 0;
+ redraw_mask = REDRAW_ALL;
+}
+
+static void InitLevelInfo()
+{
+ LoadLevelInfo(); /* global level info */
+ LoadLevelSetup_LastSeries(); /* last played series info */
+ LoadLevelSetup_SeriesInfo(); /* last played level info */
+}
+
+void InitLevelArtworkInfo()
+{
+ LoadLevelArtworkInfo();
+}
+
+static void InitImages()
+{
+ setLevelArtworkDir(artwork.gfx_first);
+
+#if 0
+ printf("::: InitImages for '%s' ['%s', '%s'] ['%s', '%s']\n",
+ leveldir_current->identifier,
+ artwork.gfx_current_identifier,
+ artwork.gfx_current->identifier,
+ leveldir_current->graphics_set,
+ leveldir_current->graphics_path);
+#endif
+
+ ReloadCustomImages();
+
+ LoadCustomElementDescriptions();
+ LoadSpecialMenuDesignSettings();
+
+ ReinitializeGraphics();
+}
+
+static void InitSound(char *identifier)
+{
+ if (identifier == NULL)
+ identifier = artwork.snd_current->identifier;
+
+ /* set artwork path to send it to the sound server process */
+ setLevelArtworkDir(artwork.snd_first);
+
+ InitReloadCustomSounds(identifier);
+ ReinitializeSounds();
+}
+
+static void InitMusic(char *identifier)
+{
+ if (identifier == NULL)
+ identifier = artwork.mus_current->identifier;
+
+ /* set artwork path to send it to the sound server process */
+ setLevelArtworkDir(artwork.mus_first);
+
+ InitReloadCustomMusic(identifier);
+ ReinitializeMusic();
+}
+
+void InitNetworkServer()
+{
+#if defined(PLATFORM_UNIX)
+ int nr_wanted;
+#endif
+
+ if (!options.network)
+ return;
- static int ep_dont_go_to[] =
- {
- EL_KAEFER,
- EL_FLIEGER,
- EL_BUTTERFLY,
- EL_FIREFLY,
- EL_MAMPFER,
- EL_MAMPFER2,
- EL_ROBOT,
- EL_PACMAN,
- EL_TROPFEN,
- EL_SALZSAEURE,
- EL_SP_SNIKSNAK,
- EL_SP_ELECTRON,
- EL_SP_BUG_ACTIVE,
- EL_TRAP_ACTIVE,
- EL_LANDMINE
- };
- static int ep_dont_go_to_num = SIZEOF_ARRAY_INT(ep_dont_go_to);
+#if defined(PLATFORM_UNIX)
+ nr_wanted = Request("Choose player", REQ_PLAYER | REQ_STAY_CLOSED);
- static int ep_mampf2[] =
- {
- EL_ERDREICH,
- EL_KAEFER,
- EL_FLIEGER,
- EL_BUTTERFLY,
- EL_FIREFLY,
- EL_MAMPFER,
- EL_ROBOT,
- EL_PACMAN,
- EL_TROPFEN,
- EL_AMOEBE_TOT,
- EL_AMOEBE_NASS,
- EL_AMOEBE_NORM,
- EL_AMOEBE_VOLL,
- EL_AMOEBE_BD,
- EL_EDELSTEIN,
- EL_EDELSTEIN_BD,
- EL_EDELSTEIN_GELB,
- EL_EDELSTEIN_ROT,
- EL_EDELSTEIN_LILA,
- EL_DIAMANT,
- EL_PEARL,
- EL_CRYSTAL
- };
- static int ep_mampf2_num = SIZEOF_ARRAY_INT(ep_mampf2);
+ if (!ConnectToServer(options.server_host, options.server_port))
+ Error(ERR_EXIT, "cannot connect to network game server");
- static int ep_bd_element[] =
- {
- EL_LEERRAUM,
- EL_ERDREICH,
- EL_FELSBODEN,
- EL_BD_WALL,
- EL_FELSBROCKEN,
- EL_BD_ROCK,
- EL_EDELSTEIN_BD,
- EL_MAGIC_WALL_BD_OFF,
- EL_AUSGANG_ZU,
- EL_AUSGANG_AUF,
- EL_BETON,
- EL_SPIELFIGUR,
- EL_FIREFLY,
- EL_FIREFLY_1,
- EL_FIREFLY_2,
- EL_FIREFLY_3,
- EL_FIREFLY_4,
- EL_BUTTERFLY,
- EL_BUTTERFLY_1,
- EL_BUTTERFLY_2,
- EL_BUTTERFLY_3,
- EL_BUTTERFLY_4,
- EL_AMOEBE_BD,
- EL_CHAR_FRAGE
- };
- static int ep_bd_element_num = SIZEOF_ARRAY_INT(ep_bd_element);
+ SendToServer_PlayerName(setup.player_name);
+ SendToServer_ProtocolVersion();
- static int ep_sb_element[] =
- {
- EL_LEERRAUM,
- EL_BETON,
- EL_SOKOBAN_OBJEKT,
- EL_SOKOBAN_FELD_LEER,
- EL_SOKOBAN_FELD_VOLL,
- EL_SPIELFIGUR,
- EL_INVISIBLE_STEEL
- };
- static int ep_sb_element_num = SIZEOF_ARRAY_INT(ep_sb_element);
+ if (nr_wanted)
+ SendToServer_NrWanted(nr_wanted);
+#endif
+}
- static int ep_gem[] =
- {
- EL_EDELSTEIN,
- EL_EDELSTEIN_BD,
- EL_EDELSTEIN_GELB,
- EL_EDELSTEIN_ROT,
- EL_EDELSTEIN_LILA,
- EL_DIAMANT
- };
- static int ep_gem_num = SIZEOF_ARRAY_INT(ep_gem);
+static char *getNewArtworkIdentifier(int type)
+{
+ static char *leveldir_current_identifier[3] = { NULL, NULL, NULL };
+ static boolean last_override_level_artwork[3] = { FALSE, FALSE, FALSE };
+ static boolean last_has_level_artwork_set[3] = { FALSE, FALSE, FALSE };
+ static boolean initialized[3] = { FALSE, FALSE, FALSE };
+ TreeInfo *artwork_first_node = ARTWORK_FIRST_NODE(artwork, type);
+ boolean setup_override_artwork = SETUP_OVERRIDE_ARTWORK(setup, type);
+ char *setup_artwork_set = SETUP_ARTWORK_SET(setup, type);
+ char *leveldir_identifier = leveldir_current->identifier;
+ char *leveldir_artwork_set = LEVELDIR_ARTWORK_SET(leveldir_current, type);
+ boolean has_level_artwork_set = (leveldir_artwork_set != NULL);
+ char *artwork_current_identifier;
+ char *artwork_new_identifier = NULL; /* default: nothing has changed */
+
+ /* leveldir_current may be invalid (level group, parent link) */
+ if (!validLevelSeries(leveldir_current))
+ return NULL;
+
+
+ /* 1st step: determine artwork set to be activated in descending order:
+ --------------------------------------------------------------------
+ 1. setup artwork (when configured to override everything else)
+ 2. artwork set configured in "levelinfo.conf" of current level set
+ (artwork in level directory will have priority when loading later)
+ 3. artwork in level directory (stored in artwork sub-directory)
+ 4. setup artwork (currently configured in setup menu) */
+
+ if (setup_override_artwork)
+ artwork_current_identifier = setup_artwork_set;
+ else if (leveldir_artwork_set != NULL)
+ artwork_current_identifier = leveldir_artwork_set;
+ else if (getTreeInfoFromIdentifier(artwork_first_node, leveldir_identifier))
+ artwork_current_identifier = leveldir_identifier;
+ else
+ artwork_current_identifier = setup_artwork_set;
+
+
+ /* 2nd step: check if it is really needed to reload artwork set
+ ------------------------------------------------------------ */
+
+ /* ---------- reload if level set and also artwork set has changed ------- */
+ if (leveldir_current_identifier[type] != leveldir_identifier &&
+ (last_has_level_artwork_set[type] || has_level_artwork_set))
+ artwork_new_identifier = artwork_current_identifier;
+
+ leveldir_current_identifier[type] = leveldir_identifier;
+ last_has_level_artwork_set[type] = has_level_artwork_set;
+
+ /* ---------- reload if "override artwork" setting has changed ----------- */
+ if (last_override_level_artwork[type] != setup_override_artwork)
+ artwork_new_identifier = artwork_current_identifier;
+
+ last_override_level_artwork[type] = setup_override_artwork;
+
+ /* ---------- reload if current artwork identifier has changed ----------- */
+ if (strcmp(ARTWORK_CURRENT_IDENTIFIER(artwork, type),
+ artwork_current_identifier) != 0)
+ artwork_new_identifier = artwork_current_identifier;
+
+ *(&(ARTWORK_CURRENT_IDENTIFIER(artwork, type))) = artwork_current_identifier;
+
+ /* ---------- do not reload directly after starting ---------------------- */
+ if (!initialized[type])
+ artwork_new_identifier = NULL;
+
+ initialized[type] = TRUE;
+
+#if 0
+ printf("CHECKING OLD/NEW GFX:\n- OLD: %s\n- NEW: %s ['%s', '%s'] ['%s']\n",
+ artwork.gfx_current_identifier, artwork_current_identifier,
+ artwork.gfx_current->identifier, leveldir_current->graphics_set,
+ artwork_new_identifier);
+#endif
- static int ep_inactive[] =
- {
- EL_LEERRAUM,
- EL_ERDREICH,
- EL_MAUERWERK,
- EL_BD_WALL,
- EL_FELSBODEN,
- EL_SCHLUESSEL,
- EL_BETON,
- EL_AMOEBE_TOT,
- EL_MORAST_LEER,
- EL_BADEWANNE,
- EL_ABLENK_AUS,
- EL_SCHLUESSEL1,
- EL_SCHLUESSEL2,
- EL_SCHLUESSEL3,
- EL_SCHLUESSEL4,
- EL_EM_KEY_1,
- EL_EM_KEY_2,
- EL_EM_KEY_3,
- EL_EM_KEY_4,
- EL_PFORTE1,
- EL_PFORTE2,
- EL_PFORTE3,
- EL_PFORTE4,
- EL_PFORTE1X,
- EL_PFORTE2X,
- EL_PFORTE3X,
- EL_PFORTE4X,
- EL_EM_GATE_1,
- EL_EM_GATE_2,
- EL_EM_GATE_3,
- EL_EM_GATE_4,
- EL_EM_GATE_1X,
- EL_EM_GATE_2X,
- EL_EM_GATE_3X,
- EL_EM_GATE_4X,
- EL_DYNAMITE_INACTIVE,
- EL_UNSICHTBAR,
- EL_BIRNE_AUS,
- EL_BIRNE_EIN,
- EL_ERZ_EDEL,
- EL_ERZ_DIAM,
- EL_ERZ_EDEL_BD,
- EL_ERZ_EDEL_GELB,
- EL_DYNABOMB_NR,
- EL_DYNABOMB_SZ,
- EL_DYNABOMB_XL,
- EL_SOKOBAN_OBJEKT,
- EL_SOKOBAN_FELD_LEER,
- EL_SOKOBAN_FELD_VOLL,
- EL_ERZ_EDEL_ROT,
- EL_ERZ_EDEL_LILA,
- EL_BADEWANNE1,
- EL_BADEWANNE2,
- EL_BADEWANNE3,
- EL_BADEWANNE4,
- EL_BADEWANNE5,
- EL_MAGIC_WALL_OFF,
- EL_MAGIC_WALL_DEAD,
- EL_MAGIC_WALL_BD_OFF,
- EL_MAGIC_WALL_BD_DEAD,
- EL_AMOEBA2DIAM,
- EL_BLOCKED,
- EL_SP_EMPTY,
- EL_SP_BASE,
- EL_SP_PORT1_RIGHT,
- EL_SP_PORT1_DOWN,
- EL_SP_PORT1_LEFT,
- EL_SP_PORT1_UP,
- EL_SP_PORT2_RIGHT,
- EL_SP_PORT2_DOWN,
- EL_SP_PORT2_LEFT,
- EL_SP_PORT2_UP,
- EL_SP_PORT_X,
- EL_SP_PORT_Y,
- EL_SP_PORT_XY,
- EL_SP_DISK_RED,
- EL_SP_DISK_YELLOW,
- EL_SP_CHIP_SINGLE,
- EL_SP_CHIP_LEFT,
- EL_SP_CHIP_RIGHT,
- EL_SP_CHIP_UPPER,
- EL_SP_CHIP_LOWER,
- EL_SP_HARD_GRAY,
- EL_SP_HARD_GREEN,
- EL_SP_HARD_BLUE,
- EL_SP_HARD_RED,
- EL_SP_HARD_YELLOW,
- EL_SP_HARD_BASE1,
- EL_SP_HARD_BASE2,
- EL_SP_HARD_BASE3,
- EL_SP_HARD_BASE4,
- EL_SP_HARD_BASE5,
- EL_SP_HARD_BASE6,
- EL_SP_EXIT,
- EL_INVISIBLE_STEEL,
- EL_BELT1_SWITCH_LEFT,
- EL_BELT1_SWITCH_MIDDLE,
- EL_BELT1_SWITCH_RIGHT,
- EL_BELT2_SWITCH_LEFT,
- EL_BELT2_SWITCH_MIDDLE,
- EL_BELT2_SWITCH_RIGHT,
- EL_BELT3_SWITCH_LEFT,
- EL_BELT3_SWITCH_MIDDLE,
- EL_BELT3_SWITCH_RIGHT,
- EL_BELT4_SWITCH_LEFT,
- EL_BELT4_SWITCH_MIDDLE,
- EL_BELT4_SWITCH_RIGHT,
- EL_SIGN_EXCLAMATION,
- EL_SIGN_RADIOACTIVITY,
- EL_SIGN_STOP,
- EL_SIGN_WHEELCHAIR,
- EL_SIGN_PARKING,
- EL_SIGN_ONEWAY,
- EL_SIGN_HEART,
- EL_SIGN_TRIANGLE,
- EL_SIGN_ROUND,
- EL_SIGN_EXIT,
- EL_SIGN_YINYANG,
- EL_SIGN_OTHER,
- EL_STEEL_SLANTED,
- EL_EMC_STEEL_WALL_1,
- EL_EMC_STEEL_WALL_2,
- EL_EMC_STEEL_WALL_3,
- EL_EMC_STEEL_WALL_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
- };
- static int ep_inactive_num = SIZEOF_ARRAY_INT(ep_inactive);
+ return artwork_new_identifier;
+}
- static int ep_explosive[] =
- {
- EL_BOMBE,
- EL_DYNAMITE_ACTIVE,
- EL_DYNAMITE_INACTIVE,
- EL_DYNABOMB_ACTIVE_1,
- EL_DYNABOMB_ACTIVE_2,
- EL_DYNABOMB_ACTIVE_3,
- EL_DYNABOMB_ACTIVE_4,
- EL_DYNABOMB_NR,
- EL_DYNABOMB_SZ,
- EL_DYNABOMB_XL,
- EL_KAEFER,
- EL_MOLE,
- EL_PINGUIN,
- EL_SCHWEIN,
- EL_DRACHE,
- EL_SONDE,
- EL_SP_DISK_RED,
- EL_SP_DISK_ORANGE,
- EL_SP_DISK_YELLOW,
- EL_SP_SNIKSNAK,
- EL_SP_ELECTRON,
- EL_DX_SUPABOMB
- };
- static int ep_explosive_num = SIZEOF_ARRAY_INT(ep_explosive);
+void ReloadCustomArtwork()
+{
+ char *gfx_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_GRAPHICS);
+ char *snd_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_SOUNDS);
+ char *mus_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_MUSIC);
+ boolean redraw_screen = FALSE;
- static int ep_mampf3[] =
+ if (gfx_new_identifier != NULL)
{
- EL_EDELSTEIN,
- EL_EDELSTEIN_BD,
- EL_EDELSTEIN_GELB,
- EL_EDELSTEIN_ROT,
- EL_EDELSTEIN_LILA,
- EL_DIAMANT,
- EL_PEARL,
- EL_CRYSTAL
- };
- static int ep_mampf3_num = SIZEOF_ARRAY_INT(ep_mampf3);
+#if 0
+ printf("RELOADING GRAPHICS '%s' -> '%s' ['%s']\n",
+ artwork.gfx_current_identifier,
+ gfx_new_identifier,
+ artwork.gfx_current->identifier);
+#endif
- static int ep_pushable[] =
- {
- EL_FELSBROCKEN,
- EL_BD_ROCK,
- EL_BOMBE,
- EL_KOKOSNUSS,
- EL_ZEIT_LEER,
- EL_SOKOBAN_FELD_VOLL,
- EL_SOKOBAN_OBJEKT,
- EL_SONDE,
- EL_SP_ZONK,
- EL_SP_DISK_ORANGE,
- EL_SP_DISK_YELLOW,
- EL_BALLOON,
- EL_SPRING,
- EL_DX_SUPABOMB
- };
- static int ep_pushable_num = SIZEOF_ARRAY_INT(ep_pushable);
+ ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE);
- static int ep_player[] =
- {
- EL_SPIELFIGUR,
- EL_SPIELER1,
- EL_SPIELER2,
- EL_SPIELER3,
- EL_SPIELER4
- };
- static int ep_player_num = SIZEOF_ARRAY_INT(ep_player);
+ InitImages();
- static int ep_has_content[] =
- {
- EL_MAMPFER,
- EL_AMOEBE_NASS,
- EL_AMOEBE_NORM,
- EL_AMOEBE_VOLL,
- EL_AMOEBE_BD
- };
- static int ep_has_content_num = SIZEOF_ARRAY_INT(ep_has_content);
+ FreeTileClipmasks();
+ InitTileClipmasks();
- static int ep_eatable[] =
- {
- EL_ERDREICH,
- EL_SP_BASE,
- EL_SP_BUG,
- EL_TRAP_INACTIVE,
- EL_SAND_INVISIBLE
- };
- static int ep_eatable_num = SIZEOF_ARRAY_INT(ep_eatable);
+ redraw_screen = TRUE;
+ }
- static int ep_sp_element[] =
+ if (snd_new_identifier != NULL)
{
- EL_SP_EMPTY,
- EL_SP_ZONK,
- EL_SP_BASE,
- EL_SP_MURPHY,
- EL_SP_INFOTRON,
- EL_SP_CHIP_SINGLE,
- EL_SP_HARD_GRAY,
- EL_SP_EXIT,
- EL_SP_DISK_ORANGE,
- EL_SP_PORT1_RIGHT,
- EL_SP_PORT1_DOWN,
- EL_SP_PORT1_LEFT,
- EL_SP_PORT1_UP,
- EL_SP_PORT2_RIGHT,
- EL_SP_PORT2_DOWN,
- EL_SP_PORT2_LEFT,
- EL_SP_PORT2_UP,
- EL_SP_SNIKSNAK,
- EL_SP_DISK_YELLOW,
- EL_SP_TERMINAL,
- EL_SP_DISK_RED,
- EL_SP_PORT_Y,
- EL_SP_PORT_X,
- EL_SP_PORT_XY,
- EL_SP_ELECTRON,
- EL_SP_BUG,
- EL_SP_CHIP_LEFT,
- EL_SP_CHIP_RIGHT,
- EL_SP_HARD_BASE1,
- EL_SP_HARD_GREEN,
- EL_SP_HARD_BLUE,
- EL_SP_HARD_RED,
- EL_SP_HARD_YELLOW,
- EL_SP_HARD_BASE2,
- EL_SP_HARD_BASE3,
- EL_SP_HARD_BASE4,
- EL_SP_HARD_BASE5,
- EL_SP_HARD_BASE6,
- EL_SP_CHIP_UPPER,
- EL_SP_CHIP_LOWER,
- /* additional elements that appeared in newer Supaplex levels */
- EL_UNSICHTBAR,
- /* more than one murphy in a level results in an inactive clone */
- EL_SP_MURPHY_CLONE
- };
- static int ep_sp_element_num = SIZEOF_ARRAY_INT(ep_sp_element);
+ ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE);
- static int ep_quick_gate[] =
- {
- EL_EM_GATE_1,
- EL_EM_GATE_2,
- EL_EM_GATE_3,
- EL_EM_GATE_4,
- EL_EM_GATE_1X,
- EL_EM_GATE_2X,
- EL_EM_GATE_3X,
- EL_EM_GATE_4X,
- EL_SP_PORT1_LEFT,
- EL_SP_PORT2_LEFT,
- EL_SP_PORT1_RIGHT,
- EL_SP_PORT2_RIGHT,
- EL_SP_PORT1_UP,
- EL_SP_PORT2_UP,
- EL_SP_PORT1_DOWN,
- EL_SP_PORT2_DOWN,
- EL_SP_PORT_X,
- EL_SP_PORT_Y,
- EL_SP_PORT_XY,
- EL_SWITCHGATE_OPEN,
- EL_TIMEGATE_OPEN
- };
- static int ep_quick_gate_num = SIZEOF_ARRAY_INT(ep_quick_gate);
-
- static int ep_over_player[] =
- {
- EL_SP_PORT1_LEFT,
- EL_SP_PORT2_LEFT,
- EL_SP_PORT1_RIGHT,
- EL_SP_PORT2_RIGHT,
- EL_SP_PORT1_UP,
- EL_SP_PORT2_UP,
- EL_SP_PORT1_DOWN,
- EL_SP_PORT2_DOWN,
- EL_SP_PORT_X,
- EL_SP_PORT_Y,
- EL_SP_PORT_XY,
- EL_TUBE_CROSS,
- EL_TUBE_VERTICAL,
- EL_TUBE_HORIZONTAL,
- EL_TUBE_VERT_LEFT,
- EL_TUBE_VERT_RIGHT,
- EL_TUBE_HORIZ_UP,
- EL_TUBE_HORIZ_DOWN,
- EL_TUBE_LEFT_UP,
- EL_TUBE_LEFT_DOWN,
- EL_TUBE_RIGHT_UP,
- EL_TUBE_RIGHT_DOWN
- };
- static int ep_over_player_num = SIZEOF_ARRAY_INT(ep_over_player);
+ InitSound(snd_new_identifier);
- static int ep_active_bomb[] =
- {
- EL_DYNAMITE_ACTIVE,
- EL_DYNABOMB_ACTIVE_1,
- EL_DYNABOMB_ACTIVE_2,
- EL_DYNABOMB_ACTIVE_3,
- EL_DYNABOMB_ACTIVE_4
- };
- static int ep_active_bomb_num = SIZEOF_ARRAY_INT(ep_active_bomb);
+ redraw_screen = TRUE;
+ }
- static int ep_belt[] =
+ if (mus_new_identifier != NULL)
{
- EL_BELT1_LEFT,
- EL_BELT1_MIDDLE,
- EL_BELT1_RIGHT,
- EL_BELT2_LEFT,
- EL_BELT2_MIDDLE,
- EL_BELT2_RIGHT,
- EL_BELT3_LEFT,
- EL_BELT3_MIDDLE,
- EL_BELT3_RIGHT,
- EL_BELT4_LEFT,
- EL_BELT4_MIDDLE,
- EL_BELT4_RIGHT,
- };
- static int ep_belt_num = SIZEOF_ARRAY_INT(ep_belt);
+ ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE);
- static int ep_belt_switch[] =
- {
- EL_BELT1_SWITCH_LEFT,
- EL_BELT1_SWITCH_MIDDLE,
- EL_BELT1_SWITCH_RIGHT,
- EL_BELT2_SWITCH_LEFT,
- EL_BELT2_SWITCH_MIDDLE,
- EL_BELT2_SWITCH_RIGHT,
- EL_BELT3_SWITCH_LEFT,
- EL_BELT3_SWITCH_MIDDLE,
- EL_BELT3_SWITCH_RIGHT,
- EL_BELT4_SWITCH_LEFT,
- EL_BELT4_SWITCH_MIDDLE,
- EL_BELT4_SWITCH_RIGHT,
- };
- static int ep_belt_switch_num = SIZEOF_ARRAY_INT(ep_belt_switch);
+ InitMusic(mus_new_identifier);
- static int ep_tube[] =
- {
- EL_TUBE_CROSS,
- EL_TUBE_VERTICAL,
- EL_TUBE_HORIZONTAL,
- EL_TUBE_VERT_LEFT,
- EL_TUBE_VERT_RIGHT,
- EL_TUBE_HORIZ_UP,
- EL_TUBE_HORIZ_DOWN,
- EL_TUBE_LEFT_UP,
- EL_TUBE_LEFT_DOWN,
- EL_TUBE_RIGHT_UP,
- EL_TUBE_RIGHT_DOWN
- };
- static int ep_tube_num = SIZEOF_ARRAY_INT(ep_tube);
-
- static long ep1_bit[] =
- {
- EP_BIT_AMOEBALIVE,
- EP_BIT_AMOEBOID,
- EP_BIT_SCHLUESSEL,
- EP_BIT_PFORTE,
- EP_BIT_SOLID,
- EP_BIT_MASSIVE,
- EP_BIT_SLIPPERY,
- EP_BIT_ENEMY,
- EP_BIT_MAUER,
- EP_BIT_CAN_FALL,
- EP_BIT_CAN_SMASH,
- EP_BIT_CAN_CHANGE,
- EP_BIT_CAN_MOVE,
- EP_BIT_COULD_MOVE,
- EP_BIT_DONT_TOUCH,
- EP_BIT_DONT_GO_TO,
- EP_BIT_MAMPF2,
- EP_BIT_BD_ELEMENT,
- EP_BIT_SB_ELEMENT,
- EP_BIT_GEM,
- EP_BIT_INACTIVE,
- EP_BIT_EXPLOSIVE,
- EP_BIT_MAMPF3,
- EP_BIT_PUSHABLE,
- EP_BIT_PLAYER,
- EP_BIT_HAS_CONTENT,
- EP_BIT_EATABLE,
- EP_BIT_SP_ELEMENT,
- EP_BIT_QUICK_GATE,
- EP_BIT_OVER_PLAYER,
- EP_BIT_ACTIVE_BOMB
- };
- static long ep2_bit[] =
- {
- EP_BIT_BELT,
- EP_BIT_BELT_SWITCH,
- EP_BIT_TUBE
- };
- static int *ep1_array[] =
- {
- ep_amoebalive,
- ep_amoeboid,
- ep_schluessel,
- ep_pforte,
- ep_solid,
- ep_massive,
- ep_slippery,
- ep_enemy,
- ep_mauer,
- ep_can_fall,
- ep_can_smash,
- ep_can_change,
- ep_can_move,
- ep_could_move,
- ep_dont_touch,
- ep_dont_go_to,
- ep_mampf2,
- ep_bd_element,
- ep_sb_element,
- ep_gem,
- ep_inactive,
- ep_explosive,
- ep_mampf3,
- ep_pushable,
- ep_player,
- ep_has_content,
- ep_eatable,
- ep_sp_element,
- ep_quick_gate,
- ep_over_player,
- ep_active_bomb
- };
- static int *ep2_array[] =
- {
- ep_belt,
- ep_belt_switch,
- ep_tube
- };
- static int *ep1_num[] =
- {
- &ep_amoebalive_num,
- &ep_amoeboid_num,
- &ep_schluessel_num,
- &ep_pforte_num,
- &ep_solid_num,
- &ep_massive_num,
- &ep_slippery_num,
- &ep_enemy_num,
- &ep_mauer_num,
- &ep_can_fall_num,
- &ep_can_smash_num,
- &ep_can_change_num,
- &ep_can_move_num,
- &ep_could_move_num,
- &ep_dont_touch_num,
- &ep_dont_go_to_num,
- &ep_mampf2_num,
- &ep_bd_element_num,
- &ep_sb_element_num,
- &ep_gem_num,
- &ep_inactive_num,
- &ep_explosive_num,
- &ep_mampf3_num,
- &ep_pushable_num,
- &ep_player_num,
- &ep_has_content_num,
- &ep_eatable_num,
- &ep_sp_element_num,
- &ep_quick_gate_num,
- &ep_over_player_num,
- &ep_active_bomb_num
- };
- static int *ep2_num[] =
- {
- &ep_belt_num,
- &ep_belt_switch_num,
- &ep_tube_num
- };
- static int num_properties1 = SIZEOF_ARRAY(ep1_num, int *);
- static int num_properties2 = SIZEOF_ARRAY(ep2_num, int *);
+ redraw_screen = TRUE;
+ }
- for(i=0; i<MAX_ELEMENTS; i++)
+ if (redraw_screen)
{
- Elementeigenschaften1[i] = 0;
- Elementeigenschaften2[i] = 0;
- }
+ InitGfxBackground();
- for(i=0; i<num_properties1; i++)
- for(j=0; j<*(ep1_num[i]); j++)
- Elementeigenschaften1[(ep1_array[i])[j]] |= ep1_bit[i];
- for(i=0; i<num_properties2; i++)
- for(j=0; j<*(ep2_num[i]); j++)
- Elementeigenschaften2[(ep2_array[i])[j]] |= ep2_bit[i];
+ /* force redraw of (open or closed) door graphics */
+ SetDoorState(DOOR_OPEN_ALL);
+ CloseDoor(DOOR_CLOSE_ALL | DOOR_NO_DELAY);
+ }
+}
- for(i=EL_CHAR_START; i<=EL_CHAR_END; i++)
- Elementeigenschaften1[i] |= (EP_BIT_CHAR | EP_BIT_INACTIVE);
+void KeyboardAutoRepeatOffUnlessAutoplay()
+{
+ if (global.autoplay_leveldir == NULL)
+ KeyboardAutoRepeatOff();
}
-void Execute_Debug_Command(char *command)
+
+/* ========================================================================= */
+/* OpenAll() */
+/* ========================================================================= */
+
+void OpenAll()
{
- if (strcmp(command, "create graphicsinfo.conf") == 0)
+ InitGlobal(); /* initialize some global variables */
+
+ if (options.execute_command)
+ Execute_Command(options.execute_command);
+
+ if (options.serveronly)
{
- printf("# (Currently only \"name\" and \"sort_priority\" recognized.)\n");
- printf("\n");
- printf("%s\n", getFormattedSetupEntry("name", "Classic Graphics"));
- printf("\n");
- printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
+#if defined(PLATFORM_UNIX)
+ NetworkServer(options.server_port, options.serveronly);
+#else
+ Error(ERR_WARN, "networking only supported in Unix version");
+#endif
+ exit(0); /* never reached */
}
- else if (strcmp(command, "create soundsinfo.conf") == 0)
- {
- int i;
- printf("# You can configure additional/alternative sound effects here\n");
- printf("# (The sounds below are default and therefore commented out.)\n");
- printf("\n");
- printf("%s\n", getFormattedSetupEntry("name", "Classic Sounds"));
- printf("\n");
- printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
- printf("\n");
+ InitSetup();
- for (i=0; i<NUM_SOUND_EFFECTS; i++)
- printf("# %s\n",
- getFormattedSetupEntry(sound_effects[i].text,
- sound_effects[i].default_filename));
- }
- else if (strcmp(command, "create musicinfo.conf") == 0)
+ InitPlayerInfo();
+ InitArtworkInfo(); /* needed before loading gfx, sound & music */
+ InitArtworkConfig(); /* needed before forking sound child process */
+ InitMixer();
+
+ InitCounter();
+
+ InitRND(NEW_RANDOMIZE);
+ InitSimpleRND(NEW_RANDOMIZE);
+
+ InitJoysticks();
+
+ InitVideoDisplay();
+ InitVideoBuffer(&backbuffer, &window, WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH,
+ setup.fullscreen);
+
+ InitEventFilter(FilterMouseMotionEvents);
+
+ InitElementPropertiesStatic();
+
+ InitGfx();
+
+ InitLevelInfo();
+ InitLevelArtworkInfo();
+
+ InitImages(); /* needs to know current level directory */
+ InitSound(NULL); /* needs to know current level directory */
+ InitMusic(NULL); /* needs to know current level directory */
+
+ InitGfxBackground();
+
+ if (global.autoplay_leveldir)
{
- printf("# (Currently only \"name\" and \"sort_priority\" recognized.)\n");
- printf("\n");
- printf("%s\n", getFormattedSetupEntry("name", "Classic Music"));
- printf("\n");
- printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
+ AutoPlayTape();
+ return;
}
+
+ game_status = GAME_MODE_MAIN;
+
+ DrawMainMenu();
+
+ InitNetworkServer();
}
void CloseAllAndExit(int exit_value)
{
- int i;
-
StopSounds();
FreeAllSounds();
FreeAllMusic();
CloseAudio(); /* called after freeing sounds (needed for SDL) */
+ FreeAllImages();
FreeTileClipmasks();
- for(i=0; i<NUM_BITMAPS; i++)
- FreeBitmap(pix[i]);
CloseVideoDisplay();
- ClosePlatformDependantStuff();
+ ClosePlatformDependentStuff();
exit(exit_value);
}
#include "main.h"
+void InitElementPropertiesStatic(void);
+void InitElementPropertiesEngine(int);
+
+void ReloadCustomArtwork(void);
+
+void KeyboardAutoRepeatOffUnlessAutoplay();
+
void OpenAll(void);
-void ReloadCustomArtwork();
void CloseAllAndExit(int);
#endif
pcx.c \
image.c \
random.c \
+ hash.c \
setup.c \
misc.c \
msdos.c \
pcx.o \
image.o \
random.o \
+ hash.o \
setup.o \
misc.o \
msdos.o \
return id;
}
-static struct GadgetInfo *getGadgetInfoFromMousePosition(int mx, int my)
+#if 0
+void DUMP_GADGET_MAP_STATE()
{
struct GadgetInfo *gi = gadget_list_first_entry;
- while (gi)
+ while (gi != NULL)
{
- if (gi->mapped &&
- mx >= gi->x && mx < gi->x + gi->width &&
- my >= gi->y && my < gi->y + gi->height)
- break;
+ printf("-XXX-1-> '%s': %s\n",
+ gi->info_text, (gi->mapped ? "mapped" : "not mapped"));
gi = gi->next;
}
+}
+#endif
- return gi;
+static struct GadgetInfo *getGadgetInfoFromMousePosition(int mx, int my)
+{
+ struct GadgetInfo *gi;
+
+ /* open selectboxes may overlap other active gadgets, so check them first */
+ for (gi = gadget_list_first_entry; gi != NULL; gi = gi->next)
+ {
+ if (gi->mapped && gi->active &&
+ gi->type & GD_TYPE_SELECTBOX && gi->selectbox.open &&
+ mx >= gi->selectbox.x && mx < gi->selectbox.x + gi->selectbox.width &&
+ my >= gi->selectbox.y && my < gi->selectbox.y + gi->selectbox.height)
+ return gi;
+ }
+
+ /* check all other gadgets */
+ for (gi = gadget_list_first_entry; gi != NULL; gi = gi->next)
+ {
+ if (gi->mapped && gi->active &&
+ mx >= gi->x && mx < gi->x + gi->width &&
+ my >= gi->y && my < gi->y + gi->height)
+ return gi;
+ }
+
+ return NULL;
}
static void default_callback_info(void *ptr)
static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct)
{
- int state = (pressed ? 1 : 0);
- struct GadgetDesign *gd = (gi->checked ?
- &gi->alt_design[state] :
+ int state = (pressed ? GD_BUTTON_PRESSED : GD_BUTTON_UNPRESSED);
+ struct GadgetDesign *gd = (!gi->active ? &gi->alt_design[state] :
+ gi->checked ? &gi->alt_design[state] :
&gi->design[state]);
+ boolean redraw_selectbox = FALSE;
switch (gi->type)
{
case GD_TYPE_NORMAL_BUTTON:
case GD_TYPE_CHECK_BUTTON:
case GD_TYPE_RADIO_BUTTON:
- BlitBitmap(gd->bitmap, drawto,
- gd->x, gd->y, gi->width, gi->height, gi->x, gi->y);
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x, gd->y, gi->width, gi->height,
+ gi->x, gi->y);
if (gi->deco.design.bitmap)
BlitBitmap(gi->deco.design.bitmap, drawto,
gi->deco.design.x, gi->deco.design.y,
gi->y + gi->deco.y + (pressed ? gi->deco.yshift : 0));
break;
+ case GD_TYPE_TEXT_BUTTON:
+ {
+ int i;
+ int font_nr = (gi->active ? gi->font_active : gi->font);
+ int font_width = getFontWidth(font_nr);
+ int border_x = gi->border.xsize;
+ int border_y = gi->border.ysize;
+ int text_size = strlen(gi->textbutton.value);
+ int text_start = (gi->width - text_size * font_width) / 2;
+
+ /* left part of gadget */
+ BlitBitmapOnBackground(gd->bitmap, drawto, gd->x, gd->y,
+ border_x, gi->height, gi->x, gi->y);
+
+ /* middle part of gadget */
+ for (i=0; i < gi->textbutton.size; i++)
+ BlitBitmapOnBackground(gd->bitmap, drawto, gd->x + border_x, gd->y,
+ font_width, gi->height,
+ gi->x + border_x + i * font_width, gi->y);
+
+ /* right part of gadget */
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x + gi->border.width - border_x, gd->y,
+ border_x, gi->height,
+ gi->x + gi->width - border_x, gi->y);
+
+ /* gadget text value */
+ DrawTextExt(drawto,
+ gi->x + text_start + (pressed ? gi->deco.xshift : 0),
+ gi->y + border_y + (pressed ? gi->deco.yshift : 0),
+ gi->textbutton.value, font_nr, BLIT_MASKED);
+ }
+ break;
+
case GD_TYPE_TEXTINPUT_ALPHANUMERIC:
case GD_TYPE_TEXTINPUT_NUMERIC:
{
int i;
char cursor_letter;
- char cursor_string[3];
+ char cursor_string[2];
char text[MAX_GADGET_TEXTSIZE + 1];
- int font_type = gi->text.font_type;
- int font_width = getFontWidth(FS_SMALL, font_type);
- int border = gi->border.size;
- strcpy(text, gi->text.value);
- strcat(text, " ");
+ int font_nr = (pressed ? gi->font_active : gi->font);
+ int font_width = getFontWidth(font_nr);
+ int border_x = gi->border.xsize;
+ int border_y = gi->border.ysize;
/* left part of gadget */
- BlitBitmap(gd->bitmap, drawto,
- gd->x, gd->y, border, gi->height, gi->x, gi->y);
+ BlitBitmapOnBackground(gd->bitmap, drawto, gd->x, gd->y,
+ border_x, gi->height, gi->x, gi->y);
/* middle part of gadget */
- for (i=0; i<=gi->text.size; i++)
- BlitBitmap(gd->bitmap, drawto,
- gd->x + border, gd->y, font_width, gi->height,
- gi->x + border + i * font_width, gi->y);
+ for (i=0; i < gi->text.size + 1; i++)
+ BlitBitmapOnBackground(gd->bitmap, drawto, gd->x + border_x, gd->y,
+ font_width, gi->height,
+ gi->x + border_x + i * font_width, gi->y);
/* right part of gadget */
- BlitBitmap(gd->bitmap, drawto,
- gd->x + gi->border.width - border, gd->y,
- border, gi->height, gi->x + gi->width - border, gi->y);
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x + gi->border.width - border_x, gd->y,
+ border_x, gi->height,
+ gi->x + gi->width - border_x, gi->y);
+
+ /* set text value */
+ strcpy(text, gi->text.value);
+ strcat(text, " ");
/* gadget text value */
- DrawText(gi->x + border, gi->y + border, text, FS_SMALL, font_type);
+ DrawTextExt(drawto,
+ gi->x + border_x, gi->y + border_y, text,
+ font_nr, BLIT_MASKED);
cursor_letter = gi->text.value[gi->text.cursor_position];
- cursor_string[0] = '~';
- cursor_string[1] = (cursor_letter != '\0' ? cursor_letter : ' ');
- cursor_string[2] = '\0';
+ cursor_string[0] = (cursor_letter != '\0' ? cursor_letter : ' ');
+ cursor_string[1] = '\0';
/* draw cursor, if active */
if (pressed)
- DrawText(gi->x + border + gi->text.cursor_position * font_width,
- gi->y + border, cursor_string, FS_SMALL, font_type);
+ DrawTextExt(drawto,
+ gi->x + border_x + gi->text.cursor_position * font_width,
+ gi->y + border_y, cursor_string,
+ font_nr, BLIT_INVERSE);
+ }
+ break;
+
+ case GD_TYPE_SELECTBOX:
+ {
+ int i;
+ char text[MAX_GADGET_TEXTSIZE + 1];
+ int font_nr = (pressed ? gi->font_active : gi->font);
+ int font_width = getFontWidth(font_nr);
+ int font_height = getFontHeight(font_nr);
+ int border_x = gi->border.xsize;
+ int border_y = gi->border.ysize;
+ int button = gi->border.xsize_selectbutton;
+ int width_inner = gi->border.width - button - 2 * border_x;
+ int box_width = gi->selectbox.width;
+ int box_height = gi->selectbox.height;
+
+ /* left part of gadget */
+ BlitBitmapOnBackground(gd->bitmap, drawto, gd->x, gd->y,
+ border_x, gi->height, gi->x, gi->y);
+
+ /* middle part of gadget */
+ for (i=0; i < gi->selectbox.size; i++)
+ BlitBitmapOnBackground(gd->bitmap, drawto, gd->x + border_x, gd->y,
+ font_width, gi->height,
+ gi->x + border_x + i * font_width, gi->y);
+
+ /* button part of gadget */
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x + border_x + width_inner, gd->y,
+ button, gi->height,
+ gi->x + gi->width - border_x - button, gi->y);
+
+ /* right part of gadget */
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x + gi->border.width - border_x, gd->y,
+ border_x, gi->height,
+ gi->x + gi->width - border_x, gi->y);
+
+ /* set text value */
+ strncpy(text, gi->selectbox.options[gi->selectbox.index].text,
+ gi->selectbox.size);
+ text[gi->selectbox.size] = '\0';
+
+ /* gadget text value */
+ DrawTextExt(drawto, gi->x + border_x, gi->y + border_y, text,
+ font_nr, BLIT_MASKED);
+
+ if (pressed)
+ {
+ if (!gi->selectbox.open)
+ {
+ gi->selectbox.open = TRUE;
+ gi->selectbox.stay_open = FALSE;
+ gi->selectbox.current_index = gi->selectbox.index;
+
+ /* save background under selectbox */
+ BlitBitmap(drawto, gfx.field_save_buffer,
+ gi->selectbox.x, gi->selectbox.y,
+ gi->selectbox.width, gi->selectbox.height,
+ gi->selectbox.x, gi->selectbox.y);
+ }
+
+ /* draw open selectbox */
+
+ /* top left part of gadget border */
+ BlitBitmapOnBackground(gd->bitmap, drawto, gd->x, gd->y,
+ border_x, border_y,
+ gi->selectbox.x, gi->selectbox.y);
+
+ /* top middle part of gadget border */
+ for (i=0; i < gi->selectbox.size; i++)
+ BlitBitmapOnBackground(gd->bitmap, drawto, gd->x + border_x, gd->y,
+ font_width, border_y,
+ gi->selectbox.x + border_x + i * font_width,
+ gi->selectbox.y);
+
+ /* top button part of gadget border */
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x + border_x + width_inner, gd->y,
+ button, border_y,
+ gi->selectbox.x + box_width -border_x -button,
+ gi->selectbox.y);
+
+ /* top right part of gadget border */
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x + gi->border.width - border_x, gd->y,
+ border_x, border_y,
+ gi->selectbox.x + box_width - border_x,
+ gi->selectbox.y);
+
+ /* left and right part of gadget border for each row */
+ for (i=0; i < gi->selectbox.num_values; i++)
+ {
+ BlitBitmapOnBackground(gd->bitmap, drawto, gd->x, gd->y + border_y,
+ border_x, font_height,
+ gi->selectbox.x,
+ gi->selectbox.y + border_y + i*font_height);
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x + gi->border.width - border_x,
+ gd->y + border_y,
+ border_x, font_height,
+ gi->selectbox.x + box_width - border_x,
+ gi->selectbox.y + border_y + i*font_height);
+ }
+
+ /* bottom left part of gadget border */
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x, gd->y + gi->height - border_y,
+ border_x, border_y,
+ gi->selectbox.x,
+ gi->selectbox.y + box_height - border_y);
+
+ /* bottom middle part of gadget border */
+ for (i=0; i < gi->selectbox.size; i++)
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x + border_x,
+ gd->y + gi->height - border_y,
+ font_width, border_y,
+ gi->selectbox.x + border_x + i * font_width,
+ gi->selectbox.y + box_height - border_y);
+
+ /* bottom button part of gadget border */
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x + border_x + width_inner,
+ gd->y + gi->height - border_y,
+ button, border_y,
+ gi->selectbox.x + box_width -border_x -button,
+ gi->selectbox.y + box_height - border_y);
+
+ /* bottom right part of gadget border */
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x + gi->border.width - border_x,
+ gd->y + gi->height - border_y,
+ border_x, border_y,
+ gi->selectbox.x + box_width - border_x,
+ gi->selectbox.y + box_height - border_y);
+
+ ClearRectangleOnBackground(drawto,
+ gi->selectbox.x + border_x,
+ gi->selectbox.y + border_y,
+ gi->selectbox.width - 2 * border_x,
+ gi->selectbox.height - 2 * border_y);
+
+ /* selectbox text values */
+ for (i=0; i < gi->selectbox.num_values; i++)
+ {
+ int mask_mode;
+
+ if (i == gi->selectbox.current_index)
+ {
+ FillRectangle(drawto,
+ gi->selectbox.x + border_x,
+ gi->selectbox.y + border_y + i * font_height,
+ gi->selectbox.width - 2 * border_x, font_height,
+ gi->selectbox.inverse_color);
+
+ strncpy(text, gi->selectbox.options[i].text, gi->selectbox.size);
+ text[1 + gi->selectbox.size] = '\0';
+
+ mask_mode = BLIT_INVERSE;
+ }
+ else
+ {
+ strncpy(text, gi->selectbox.options[i].text, gi->selectbox.size);
+ text[gi->selectbox.size] = '\0';
+
+ mask_mode = BLIT_MASKED;
+ }
+
+ DrawTextExt(drawto,
+ gi->selectbox.x + border_x,
+ gi->selectbox.y + border_y + i * font_height, text,
+ font_nr, mask_mode);
+ }
+
+ redraw_selectbox = TRUE;
+ }
+ else if (gi->selectbox.open)
+ {
+ gi->selectbox.open = FALSE;
+
+ /* redraw closed selectbox */
+ DrawGadget(gi, FALSE, FALSE);
+
+ /* restore background under selectbox */
+ BlitBitmap(gfx.field_save_buffer, drawto,
+ gi->selectbox.x, gi->selectbox.y,
+ gi->selectbox.width, gi->selectbox.height,
+ gi->selectbox.x, gi->selectbox.y);
+
+ redraw_selectbox = TRUE;
+ }
}
break;
int xpos = gi->x;
int ypos = gi->y + gi->scrollbar.position;
int design_full = gi->width;
- int design_body = design_full - 2 * gi->border.size;
+ int design_body = design_full - 2 * gi->border.ysize;
int size_full = gi->scrollbar.size;
- int size_body = size_full - 2 * gi->border.size;
+ int size_body = size_full - 2 * gi->border.ysize;
int num_steps = size_body / design_body;
int step_size_remain = size_body - num_steps * design_body;
/* clear scrollbar area */
- ClearRectangle(backbuffer, gi->x, gi->y, gi->width, gi->height);
+ ClearRectangleOnBackground(backbuffer, gi->x, gi->y,
+ gi->width, gi->height);
/* upper part of gadget */
- BlitBitmap(gd->bitmap, drawto,
- gd->x, gd->y,
- gi->width, gi->border.size,
- xpos, ypos);
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x, gd->y,
+ gi->width, gi->border.ysize,
+ xpos, ypos);
/* middle part of gadget */
for (i=0; i<num_steps; i++)
- BlitBitmap(gd->bitmap, drawto,
- gd->x, gd->y + gi->border.size,
- gi->width, design_body,
- xpos, ypos + gi->border.size + i * design_body);
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x, gd->y + gi->border.ysize,
+ gi->width, design_body,
+ xpos,
+ ypos + gi->border.ysize + i * design_body);
/* remaining middle part of gadget */
if (step_size_remain > 0)
- BlitBitmap(gd->bitmap, drawto,
- gd->x, gd->y + gi->border.size,
- gi->width, step_size_remain,
- xpos, ypos + gi->border.size + num_steps * design_body);
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x, gd->y + gi->border.ysize,
+ gi->width, step_size_remain,
+ xpos,
+ ypos + gi->border.ysize
+ + num_steps * design_body);
/* lower part of gadget */
- BlitBitmap(gd->bitmap, drawto,
- gd->x, gd->y + design_full - gi->border.size,
- gi->width, gi->border.size,
- xpos, ypos + size_full - gi->border.size);
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x, gd->y + design_full - gi->border.ysize,
+ gi->width, gi->border.ysize,
+ xpos, ypos + size_full - gi->border.ysize);
}
break;
int xpos = gi->x + gi->scrollbar.position;
int ypos = gi->y;
int design_full = gi->height;
- int design_body = design_full - 2 * gi->border.size;
+ int design_body = design_full - 2 * gi->border.xsize;
int size_full = gi->scrollbar.size;
- int size_body = size_full - 2 * gi->border.size;
+ int size_body = size_full - 2 * gi->border.xsize;
int num_steps = size_body / design_body;
int step_size_remain = size_body - num_steps * design_body;
/* clear scrollbar area */
- ClearRectangle(backbuffer, gi->x, gi->y, gi->width, gi->height);
+ ClearRectangleOnBackground(backbuffer, gi->x, gi->y,
+ gi->width, gi->height);
/* left part of gadget */
- BlitBitmap(gd->bitmap, drawto,
- gd->x, gd->y,
- gi->border.size, gi->height,
- xpos, ypos);
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x, gd->y,
+ gi->border.xsize, gi->height,
+ xpos, ypos);
/* middle part of gadget */
for (i=0; i<num_steps; i++)
- BlitBitmap(gd->bitmap, drawto,
- gd->x + gi->border.size, gd->y,
- design_body, gi->height,
- xpos + gi->border.size + i * design_body, ypos);
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x + gi->border.xsize, gd->y,
+ design_body, gi->height,
+ xpos + gi->border.xsize + i * design_body,
+ ypos);
/* remaining middle part of gadget */
if (step_size_remain > 0)
- BlitBitmap(gd->bitmap, drawto,
- gd->x + gi->border.size, gd->y,
- step_size_remain, gi->height,
- xpos + gi->border.size + num_steps * design_body, ypos);
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x + gi->border.xsize, gd->y,
+ step_size_remain, gi->height,
+ xpos + gi->border.xsize
+ + num_steps * design_body,
+ ypos);
/* right part of gadget */
- BlitBitmap(gd->bitmap, drawto,
- gd->x + design_full - gi->border.size, gd->y,
- gi->border.size, gi->height,
- xpos + size_full - gi->border.size, ypos);
+ BlitBitmapOnBackground(gd->bitmap, drawto,
+ gd->x + design_full - gi->border.xsize, gd->y,
+ gi->border.xsize, gi->height,
+ xpos + size_full - gi->border.xsize, ypos);
}
break;
}
if (direct)
+ {
BlitBitmap(drawto, window,
gi->x, gi->y, gi->width, gi->height, gi->x, gi->y);
+
+ if (gi->type == GD_TYPE_SELECTBOX && redraw_selectbox)
+ BlitBitmap(drawto, window,
+ gi->selectbox.x, gi->selectbox.y,
+ gi->selectbox.width, gi->selectbox.height,
+ gi->selectbox.x, gi->selectbox.y);
+ }
else
redraw_mask |= (gi->x < gfx.sx + gfx.sxsize ? REDRAW_FIELD :
gi->y < gfx.dy + gfx.dysize ? REDRAW_DOOR_1 :
case GDI_INFO_TEXT:
{
int max_textsize = MAX_INFO_TEXTSIZE - 1;
+ char *text = va_arg(ap, char *);
+
+ if (text != NULL)
+ strncpy(gi->info_text, text, max_textsize);
+ else
+ max_textsize = 0;
- strncpy(gi->info_text, va_arg(ap, char *), max_textsize);
gi->info_text[max_textsize] = '\0';
}
break;
gi->state = va_arg(ap, unsigned long);
break;
+ case GDI_ACTIVE:
+ /* take care here: "boolean" is typedef'ed as "unsigned char",
+ which gets promoted to "int" */
+ gi->active = (boolean)va_arg(ap, int);
+ break;
+
case GDI_CHECKED:
/* take care here: "boolean" is typedef'ed as "unsigned char",
which gets promoted to "int" */
strncpy(gi->text.value, va_arg(ap, char *), max_textsize);
gi->text.value[max_textsize] = '\0';
gi->text.cursor_position = strlen(gi->text.value);
+
+ /* same tag also used for textbutton definition */
+ strcpy(gi->textbutton.value, gi->text.value);
}
break;
gi->text.size = max_textsize;
gi->text.value[max_textsize] = '\0';
+
+ /* same tag also used for textbutton and selectbox definition */
+ strcpy(gi->textbutton.value, gi->text.value);
+ gi->textbutton.size = gi->text.size;
+ gi->selectbox.size = gi->text.size;
}
break;
case GDI_TEXT_FONT:
- gi->text.font_type = va_arg(ap, int);
+ gi->font = va_arg(ap, int);
+ if (gi->font_active == 0)
+ gi->font_active = gi->font;
+ break;
+
+ case GDI_TEXT_FONT_ACTIVE:
+ gi->font_active = va_arg(ap, int);
+ break;
+
+ case GDI_SELECTBOX_OPTIONS:
+ gi->selectbox.options = va_arg(ap, struct ValueTextInfo *);
+ break;
+
+ case GDI_SELECTBOX_INDEX:
+ gi->selectbox.index = va_arg(ap, int);
break;
case GDI_DESIGN_UNPRESSED:
break;
case GDI_BORDER_SIZE:
- gi->border.size = va_arg(ap, int);
+ gi->border.xsize = va_arg(ap, int);
+ gi->border.ysize = va_arg(ap, int);
break;
- case GDI_TEXTINPUT_DESIGN_WIDTH:
+ case GDI_BORDER_SIZE_SELECTBUTTON:
+ gi->border.xsize_selectbutton = va_arg(ap, int);
+ break;
+
+ case GDI_DESIGN_WIDTH:
gi->border.width = va_arg(ap, int);
break;
tag = va_arg(ap, int); /* read next tag */
}
- /* check if gadget complete */
+ /* check if gadget is complete */
if (gi->type != GD_TYPE_DRAWING_AREA &&
(!gi->design[GD_BUTTON_UNPRESSED].bitmap ||
!gi->design[GD_BUTTON_PRESSED].bitmap))
if (gi->type & GD_TYPE_TEXTINPUT)
{
- int font_width = getFontWidth(FS_SMALL, gi->text.font_type);
- int font_height = getFontHeight(FS_SMALL, gi->text.font_type);
+ int font_nr = gi->font_active;
+ int font_width = getFontWidth(font_nr);
+ int font_height = getFontHeight(font_nr);
+ int border_xsize = gi->border.xsize;
+ int border_ysize = gi->border.ysize;
+
+ gi->width = 2 * border_xsize + (gi->text.size + 1) * font_width;
+ gi->height = 2 * border_ysize + font_height;
+ }
- gi->width = 2 * gi->border.size + (gi->text.size + 1) * font_width;
- gi->height = 2 * gi->border.size + font_height;
+ if (gi->type & GD_TYPE_SELECTBOX)
+ {
+ int font_nr = gi->font_active;
+ int font_width = getFontWidth(font_nr);
+ int font_height = getFontHeight(font_nr);
+ int border_xsize = gi->border.xsize;
+ int border_ysize = gi->border.ysize;
+ int button_size = gi->border.xsize_selectbutton;
+ int bottom_screen_border = gfx.sy + gfx.sysize - font_height;
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+
+ gi->width = 2 * border_xsize + gi->text.size * font_width + button_size;
+ gi->height = 2 * border_ysize + font_height;
+
+ if (gi->selectbox.options == NULL)
+ Error(ERR_EXIT, "selectbox gadget incomplete (missing options array)");
+
+ gi->selectbox.num_values = 0;
+ while (gi->selectbox.options[gi->selectbox.num_values].text != NULL)
+ gi->selectbox.num_values++;
+
+ /* calculate values for open selectbox */
+ gi->selectbox.width = gi->width;
+ gi->selectbox.height =
+ 2 * border_ysize + gi->selectbox.num_values * font_height;
+
+ gi->selectbox.x = gi->x;
+ gi->selectbox.y = gi->y + gi->height;
+ if (gi->selectbox.y + gi->selectbox.height > bottom_screen_border)
+ gi->selectbox.y = gi->y - gi->selectbox.height;
+ if (gi->selectbox.y < 0)
+ gi->selectbox.y = bottom_screen_border - gi->selectbox.height;
+
+ 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);
+
+ /* always start with closed selectbox */
+ gi->selectbox.open = FALSE;
}
if (gi->type & GD_TYPE_TEXTINPUT_NUMERIC)
sprintf(text->value, "%d", text->number_value);
}
+ if (gi->type & GD_TYPE_TEXT_BUTTON)
+ {
+ int font_nr = gi->font_active;
+ int font_width = getFontWidth(font_nr);
+ int font_height = getFontHeight(font_nr);
+ int border_xsize = gi->border.xsize;
+ int border_ysize = gi->border.ysize;
+
+ gi->width = 2 * border_xsize + gi->textbutton.size * font_width;
+ gi->height = 2 * border_ysize + font_height;
+ }
+
if (gi->type & GD_TYPE_SCROLLBAR)
{
struct GadgetScrollbar *gs = &gi->scrollbar;
struct GadgetInfo *CreateGadget(int first_tag, ...)
{
- struct GadgetInfo *new_gadget = checked_malloc(sizeof(struct GadgetInfo));
+ struct GadgetInfo *new_gadget = checked_calloc(sizeof(struct GadgetInfo));
va_list ap;
/* always start with reliable default values */
- memset(new_gadget, 0, sizeof(struct GadgetInfo)); /* zero all fields */
new_gadget->id = getNewGadgetID();
new_gadget->callback_info = default_callback_info;
new_gadget->callback_action = default_callback_action;
+ new_gadget->active = TRUE;
+ new_gadget->next = NULL;
va_start(ap, first_tag);
HandleGadgetTags(new_gadget, first_tag, ap);
{
struct GadgetInfo *gi_previous = gadget_list_first_entry;
- while (gi_previous && gi_previous->next != gi)
+ while (gi_previous != NULL && gi_previous->next != gi)
gi_previous = gi_previous->next;
if (gi == gadget_list_first_entry)
if (gi == gadget_list_last_entry)
gadget_list_last_entry = gi_previous;
- gi_previous->next = gi->next;
+ if (gi_previous != NULL)
+ gi_previous->next = gi->next;
+
free(gi);
}
static boolean map_state[MAX_NUM_GADGETS];
int map_count = 0;
- while (gi)
+ while (gi != NULL)
{
if ((mode & MULTIMAP_PLAYFIELD &&
gi->x < gfx.sx + gfx.sxsize) ||
MultiMapGadgets(MULTIMAP_ALL | MULTIMAP_REMAP);
}
+boolean anyTextInputGadgetActive()
+{
+ return (last_gi && (last_gi->type & GD_TYPE_TEXTINPUT) && last_gi->mapped);
+}
+
+boolean anySelectboxGadgetActive()
+{
+ return (last_gi && (last_gi->type & GD_TYPE_SELECTBOX) && last_gi->mapped);
+}
+
boolean anyTextGadgetActive()
{
- return (last_gi && last_gi->type & GD_TYPE_TEXTINPUT && last_gi->mapped);
+ return (anyTextInputGadgetActive() || anySelectboxGadgetActive());
}
void ClickOnGadget(struct GadgetInfo *gi, int button)
boolean gadget_moving_off_borders;
boolean gadget_released;
boolean gadget_released_inside;
+ boolean gadget_released_inside_select_line;
+ boolean gadget_released_inside_select_area;
boolean gadget_released_off_borders;
boolean changed_position = FALSE;
if (gadget_list_first_entry == NULL)
return;
+ /* simulated release of mouse button over last gadget */
+ if (mx == -1 && my == -1 && button == 0)
+ {
+ mx = last_mx;
+ my = last_my;
+ }
+
/* check which gadget is under the mouse pointer */
new_gi = getGadgetInfoFromMousePosition(mx, my);
last_my = my;
/* special treatment for text and number input gadgets */
- if (anyTextGadgetActive() && button != 0 && !motion_status)
+ if (anyTextInputGadgetActive() && button != 0 && !motion_status)
{
struct GadgetInfo *gi = last_gi;
if (new_gi == last_gi)
{
+ int old_cursor_position = gi->text.cursor_position;
+
/* if mouse button pressed inside activated text gadget, set cursor */
gi->text.cursor_position =
- (mx - gi->x - gi->border.size) /
- getFontWidth(FS_SMALL, gi->text.font_type);
+ (mx - gi->x - gi->border.xsize) / getFontWidth(gi->font);
if (gi->text.cursor_position < 0)
gi->text.cursor_position = 0;
else if (gi->text.cursor_position > strlen(gi->text.value))
gi->text.cursor_position = strlen(gi->text.value);
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ if (gi->text.cursor_position != old_cursor_position)
+ DrawGadget(gi, DG_PRESSED, DG_DIRECT);
}
else
{
}
}
+ /* special treatment for selectbox gadgets */
+ if (anySelectboxGadgetActive() && button != 0 && !motion_status)
+ {
+ struct GadgetInfo *gi = last_gi;
+
+ if (new_gi == last_gi)
+ {
+ int old_index = gi->selectbox.current_index;
+
+ /* if mouse button pressed inside activated selectbox, select value */
+ if (my >= gi->selectbox.y && my < gi->selectbox.y + gi->selectbox.height)
+ gi->selectbox.current_index =
+ (my - gi->selectbox.y - gi->border.ysize) / getFontHeight(gi->font);
+
+ if (gi->selectbox.current_index < 0)
+ gi->selectbox.current_index = 0;
+ else if (gi->selectbox.current_index > gi->selectbox.num_values - 1)
+ gi->selectbox.current_index = gi->selectbox.num_values - 1;
+
+ if (gi->selectbox.current_index != old_index)
+ DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ }
+ else
+ {
+ /* if mouse button pressed outside selectbox gadget, deactivate it */
+ DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
+
+ gi->event.type = GD_EVENT_TEXT_LEAVING;
+
+ if (gi->event_mask & GD_EVENT_TEXT_LEAVING)
+ gi->callback_action(gi);
+
+ last_gi = NULL;
+ }
+ }
+
gadget_pressed =
(button != 0 && last_gi == NULL && new_gi != NULL && press_event);
gadget_pressed_repeated =
gadget_moving_inside = (gadget_moving && new_gi == last_gi);
gadget_moving_off_borders = (gadget_moving && new_gi != last_gi);
+ /* when handling selectbox, set additional state values */
+ if (gadget_released_inside && (last_gi->type & GD_TYPE_SELECTBOX))
+ {
+ struct GadgetInfo *gi = last_gi;
+
+ gadget_released_inside_select_line =
+ (mx >= gi->x && mx < gi->x + gi->width &&
+ my >= gi->y && my < gi->y + gi->height);
+ gadget_released_inside_select_area =
+ (mx >= gi->selectbox.x && mx < gi->selectbox.x + gi->selectbox.width &&
+ my >= gi->selectbox.y && my < gi->selectbox.y + gi->selectbox.height);
+ }
+ else
+ {
+ gadget_released_inside_select_line = FALSE;
+ gadget_released_inside_select_area = FALSE;
+ }
+
/* if new gadget pressed, store this gadget */
if (gadget_pressed)
last_gi = new_gi;
(gi->type == GD_TYPE_SCROLLBAR_HORIZONTAL ? mx - gi->x : my - gi->y);
/* if mouse button released, no gadget needs to be handled anymore */
- if (button == 0 && last_gi && !(last_gi->type & GD_TYPE_TEXTINPUT))
- last_gi = NULL;
+ if (gadget_released)
+ {
+ if ((last_gi->type & GD_TYPE_SELECTBOX) &&
+ (gadget_released_inside_select_line ||
+ gadget_released_off_borders)) /* selectbox stays open */
+ gi->selectbox.stay_open = TRUE;
+ else if (!(last_gi->type & GD_TYPE_TEXTINPUT)) /* text input stays open */
+ last_gi = NULL;
+ }
/* modify event position values even if no gadget is pressed */
if (button == 0 && !release_event)
gi = new_gi;
- if (gi)
+ if (gi != NULL)
{
int last_x = gi->event.x;
int last_y = gi->event.y;
if (last_x != gi->event.x || last_y != gi->event.y)
changed_position = TRUE;
}
+ else if (gi->type & GD_TYPE_SELECTBOX)
+ {
+ int old_index = gi->selectbox.current_index;
+
+ /* if mouse moving inside activated selectbox, select value */
+ if (my >= gi->selectbox.y && my < gi->selectbox.y + gi->selectbox.height)
+ gi->selectbox.current_index =
+ (my - gi->selectbox.y - gi->border.ysize) / getFontHeight(gi->font);
+
+ if (gi->selectbox.current_index < 0)
+ gi->selectbox.current_index = 0;
+ else if (gi->selectbox.current_index > gi->selectbox.num_values - 1)
+ gi->selectbox.current_index = gi->selectbox.num_values - 1;
+
+ if (gi->selectbox.current_index != old_index)
+ DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ }
}
/* handle gadget popup info text */
else if (gadget_moving_off_borders && gi->state == GD_BUTTON_PRESSED)
DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
}
+ else if (gi->type & GD_TYPE_SELECTBOX)
+ {
+ int old_index = gi->selectbox.current_index;
- if (gi->type & GD_TYPE_SCROLLBAR)
+ /* if mouse moving inside activated selectbox, select value */
+ if (my >= gi->selectbox.y && my < gi->selectbox.y + gi->selectbox.height)
+ gi->selectbox.current_index =
+ (my - gi->selectbox.y - gi->border.ysize) / getFontHeight(gi->font);
+
+ if (gi->selectbox.current_index < 0)
+ gi->selectbox.current_index = 0;
+ else if (gi->selectbox.current_index > gi->selectbox.num_values - 1)
+ gi->selectbox.current_index = gi->selectbox.num_values - 1;
+
+ if (gi->selectbox.current_index != old_index)
+ DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ }
+ else if (gi->type & GD_TYPE_SCROLLBAR)
{
struct GadgetScrollbar *gs = &gi->scrollbar;
int old_item_position = gs->item_position;
if (gadget_released_inside)
{
- if (!(gi->type & GD_TYPE_TEXTINPUT))
+ boolean deactivate_gadget = TRUE;
+
+ if (gi->type & GD_TYPE_SELECTBOX)
+ {
+ if (gadget_released_inside_select_line ||
+ gadget_released_off_borders) /* selectbox stays open */
+ deactivate_gadget = FALSE;
+ else
+ gi->selectbox.index = gi->selectbox.current_index;
+ }
+
+ if (deactivate_gadget &&
+ !(gi->type & GD_TYPE_TEXTINPUT)) /* text input stays open */
DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
gi->state = GD_BUTTON_UNPRESSED;
gi->event.type = GD_EVENT_RELEASED;
- if (gi->event_mask & GD_EVENT_RELEASED)
+ if ((gi->event_mask & GD_EVENT_RELEASED) && deactivate_gadget)
gi->callback_action(gi);
}
gi->event_mask & GD_EVENT_OFF_BORDERS)
gi->callback_action(gi);
}
+
+ /* handle gadgets unmapped/mapped between pressing and releasing */
+ if (release_event && !gadget_released && new_gi)
+ new_gi->state = GD_BUTTON_UNPRESSED;
}
void HandleGadgetsKeyInput(Key key)
{
struct GadgetInfo *gi = last_gi;
- char text[MAX_GADGET_TEXTSIZE];
- int text_length;
- int cursor_pos;
- char letter;
- boolean legal_letter;
- if (gi == NULL || !(gi->type & GD_TYPE_TEXTINPUT) || !gi->mapped)
+ if (gi == NULL || !gi->mapped ||
+ !((gi->type & GD_TYPE_TEXTINPUT) || (gi->type & GD_TYPE_SELECTBOX)))
return;
- text_length = strlen(gi->text.value);
- cursor_pos = gi->text.cursor_position;
- letter = getCharFromKey(key);
- legal_letter = (gi->type == GD_TYPE_TEXTINPUT_NUMERIC ?
- letter >= '0' && letter <= '9' :
- letter != 0);
-
- if (legal_letter && text_length < gi->text.size)
+ if (key == KSYM_Return) /* valid for both text input and selectbox */
{
- strcpy(text, gi->text.value);
- strcpy(&gi->text.value[cursor_pos + 1], &text[cursor_pos]);
- gi->text.value[cursor_pos] = letter;
- gi->text.cursor_position++;
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
- }
- else if (key == KSYM_Left && cursor_pos > 0)
- {
- gi->text.cursor_position--;
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
- }
- else if (key == KSYM_Right && cursor_pos < text_length)
- {
- gi->text.cursor_position++;
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
- }
- else if (key == KSYM_BackSpace && cursor_pos > 0)
- {
- strcpy(text, gi->text.value);
- strcpy(&gi->text.value[cursor_pos - 1], &text[cursor_pos]);
- gi->text.cursor_position--;
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
- }
- else if (key == KSYM_Delete && cursor_pos < text_length)
- {
- strcpy(text, gi->text.value);
- strcpy(&gi->text.value[cursor_pos], &text[cursor_pos + 1]);
- DrawGadget(gi, DG_PRESSED, DG_DIRECT);
- }
- else if (key == KSYM_Return)
- {
- CheckRangeOfNumericInputGadget(gi);
+ if (gi->type & GD_TYPE_TEXTINPUT)
+ CheckRangeOfNumericInputGadget(gi);
+ else if (gi->type & GD_TYPE_SELECTBOX)
+ gi->selectbox.index = gi->selectbox.current_index;
+
DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
gi->event.type = GD_EVENT_TEXT_RETURN;
last_gi = NULL;
}
+ else if (gi->type & GD_TYPE_TEXTINPUT) /* only valid for text input */
+ {
+ char text[MAX_GADGET_TEXTSIZE];
+ int text_length = strlen(gi->text.value);
+ int cursor_pos = gi->text.cursor_position;
+ char letter = getCharFromKey(key);
+ boolean legal_letter = (gi->type == GD_TYPE_TEXTINPUT_NUMERIC ?
+ letter >= '0' && letter <= '9' :
+ letter != 0);
+
+ if (legal_letter && text_length < gi->text.size)
+ {
+ strcpy(text, gi->text.value);
+ strcpy(&gi->text.value[cursor_pos + 1], &text[cursor_pos]);
+ gi->text.value[cursor_pos] = letter;
+ gi->text.cursor_position++;
+
+ DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ }
+ else if (key == KSYM_Left && cursor_pos > 0)
+ {
+ gi->text.cursor_position--;
+ DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ }
+ else if (key == KSYM_Right && cursor_pos < text_length)
+ {
+ gi->text.cursor_position++;
+ DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ }
+ else if (key == KSYM_BackSpace && cursor_pos > 0)
+ {
+ strcpy(text, gi->text.value);
+ strcpy(&gi->text.value[cursor_pos - 1], &text[cursor_pos]);
+ gi->text.cursor_position--;
+ DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ }
+ else if (key == KSYM_Delete && cursor_pos < text_length)
+ {
+ strcpy(text, gi->text.value);
+ strcpy(&gi->text.value[cursor_pos], &text[cursor_pos + 1]);
+ DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ }
+ }
+ else if (gi->type & GD_TYPE_SELECTBOX) /* only valid for selectbox */
+ {
+ int index = gi->selectbox.current_index;
+ int num_values = gi->selectbox.num_values;
+
+ if (key == KSYM_Up && index > 0)
+ {
+ gi->selectbox.current_index--;
+ DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ }
+ else if (key == KSYM_Down && index < num_values - 1)
+ {
+ gi->selectbox.current_index++;
+ DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+ }
+ }
}
/* gadget types */
#define GD_TYPE_NORMAL_BUTTON (1 << 0)
-#define GD_TYPE_CHECK_BUTTON (1 << 1)
-#define GD_TYPE_RADIO_BUTTON (1 << 2)
-#define GD_TYPE_DRAWING_AREA (1 << 3)
-#define GD_TYPE_TEXTINPUT_ALPHANUMERIC (1 << 4)
-#define GD_TYPE_TEXTINPUT_NUMERIC (1 << 5)
-#define GD_TYPE_SCROLLBAR_VERTICAL (1 << 6)
-#define GD_TYPE_SCROLLBAR_HORIZONTAL (1 << 7)
+#define GD_TYPE_TEXT_BUTTON (1 << 1)
+#define GD_TYPE_CHECK_BUTTON (1 << 2)
+#define GD_TYPE_RADIO_BUTTON (1 << 3)
+#define GD_TYPE_DRAWING_AREA (1 << 4)
+#define GD_TYPE_TEXTINPUT_ALPHANUMERIC (1 << 5)
+#define GD_TYPE_TEXTINPUT_NUMERIC (1 << 6)
+#define GD_TYPE_SELECTBOX (1 << 7)
+#define GD_TYPE_SCROLLBAR_VERTICAL (1 << 8)
+#define GD_TYPE_SCROLLBAR_HORIZONTAL (1 << 9)
#define GD_TYPE_BUTTON (GD_TYPE_NORMAL_BUTTON | \
+ GD_TYPE_TEXT_BUTTON | \
GD_TYPE_CHECK_BUTTON | \
GD_TYPE_RADIO_BUTTON)
#define GD_TYPE_SCROLLBAR (GD_TYPE_SCROLLBAR_VERTICAL | \
#define GDI_TEXT_VALUE 14
#define GDI_TEXT_SIZE 15
#define GDI_TEXT_FONT 16
-#define GDI_DESIGN_UNPRESSED 17
-#define GDI_DESIGN_PRESSED 18
-#define GDI_ALT_DESIGN_UNPRESSED 19
-#define GDI_ALT_DESIGN_PRESSED 20
-#define GDI_BORDER_SIZE 21
-#define GDI_TEXTINPUT_DESIGN_WIDTH 22
-#define GDI_DECORATION_DESIGN 23
-#define GDI_DECORATION_POSITION 24
-#define GDI_DECORATION_SIZE 25
-#define GDI_DECORATION_SHIFTING 26
-#define GDI_EVENT_MASK 27
-#define GDI_EVENT 28
-#define GDI_CALLBACK_INFO 29
-#define GDI_CALLBACK_ACTION 30
-#define GDI_AREA_SIZE 31
-#define GDI_ITEM_SIZE 32
-#define GDI_SCROLLBAR_ITEMS_MAX 33
-#define GDI_SCROLLBAR_ITEMS_VISIBLE 34
-#define GDI_SCROLLBAR_ITEM_POSITION 35
-#define GDI_INFO_TEXT 36
+#define GDI_TEXT_FONT_ACTIVE 17
+#define GDI_SELECTBOX_OPTIONS 18
+#define GDI_SELECTBOX_INDEX 19
+#define GDI_DESIGN_UNPRESSED 20
+#define GDI_DESIGN_PRESSED 21
+#define GDI_ALT_DESIGN_UNPRESSED 22
+#define GDI_ALT_DESIGN_PRESSED 23
+#define GDI_BORDER_SIZE 24
+#define GDI_BORDER_SIZE_SELECTBUTTON 25
+#define GDI_DESIGN_WIDTH 26
+#define GDI_DECORATION_DESIGN 27
+#define GDI_DECORATION_POSITION 28
+#define GDI_DECORATION_SIZE 29
+#define GDI_DECORATION_SHIFTING 30
+#define GDI_EVENT_MASK 31
+#define GDI_EVENT 32
+#define GDI_CALLBACK_INFO 33
+#define GDI_CALLBACK_ACTION 34
+#define GDI_AREA_SIZE 35
+#define GDI_ITEM_SIZE 36
+#define GDI_SCROLLBAR_ITEMS_MAX 37
+#define GDI_SCROLLBAR_ITEMS_VISIBLE 38
+#define GDI_SCROLLBAR_ITEM_POSITION 39
+#define GDI_INFO_TEXT 40
+#define GDI_ACTIVE 41
typedef void (*gadget_function)(void *);
struct GadgetBorder
{
- int size; /* size of gadget border */
- int width; /* for text input gadgets */
+ int xsize, ysize; /* size of gadget border */
+ int xsize_selectbutton; /* for selectbox gadgets */
+ int width; /* for selectbox/text input gadgets */
};
struct GadgetDesign
int item_xsize, item_ysize; /* size of each item in drawing area */
};
+struct GadgetTextButton
+{
+ char value[MAX_GADGET_TEXTSIZE]; /* text written on the button */
+ int size; /* maximal size of button text */
+};
+
struct GadgetTextInput
{
char value[MAX_GADGET_TEXTSIZE]; /* 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 */
int number_max; /* maximal allowed numeric value */
int size; /* maximal size of input text */
- int cursor_position; /* actual cursor position */
- int font_type; /* font to use for text input */
+};
+
+struct GadgetSelectbox
+{
+ struct ValueTextInfo *options; /* pointer to text/value array */
+ int index; /* index of actual text string */
+ int size; /* maximal size of text strings */
+
+ /* automatically determined values */
+ int x, y; /* open selectbox position */
+ int width, height; /* open selectbox size */
+ int num_values; /* number of text strings */
+ Pixel inverse_color; /* color for highlighting */
+
+ /* runtime values */
+ boolean open; /* opening state of selectbox */
+ boolean stay_open; /* open after button release */
+ int current_index; /* index of text while selecting */
};
struct GadgetScrollbar
unsigned long state; /* state (pressed, released, ...) */
boolean checked; /* check/radio button state */
int radio_nr; /* number of radio button series */
- boolean mapped; /* gadget is active */
+ boolean mapped; /* gadget is mapped on the screen */
+ boolean active; /* gadget is active */
+ int font; /* font to use when inactive */
+ int font_active; /* font to use when active */
struct GadgetBorder border; /* gadget border design */
struct GadgetDesign design[2]; /* 0: normal; 1: pressed */
struct GadgetDesign alt_design[2]; /* alternative design */
gadget_function callback_info; /* function for pop-up info text */
gadget_function callback_action; /* function for gadget action */
struct GadgetDrawingArea drawing; /* fields for drawing area gadget */
+ struct GadgetTextButton textbutton; /* fields for text button gadget */
struct GadgetTextInput text; /* fields for text input gadget */
+ struct GadgetSelectbox selectbox; /* fields for selectbox gadget */
struct GadgetScrollbar scrollbar; /* fields for scrollbar gadget */
struct GadgetInfo *next; /* next list entry */
};
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2003 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* hash.c *
+***********************************************************/
+
+/*
+ * Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies of the Software and its documentation and acknowledgment shall be
+ * given in the documentation and software packages that this Software was
+ * used.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "hash.h"
+
+
+/*****************************************************************************/
+struct hashtable *
+create_hashtable(unsigned int minsize, float maxloadfactor,
+ unsigned int (*hashf) (void*),
+ int (*eqf) (void*,void*))
+{
+ struct hashtable *h;
+ unsigned int i, size = 1u;
+ /* Check requested hashtable isn't too large */
+ if (minsize > (1u << 31)) return NULL;
+ /* Enforce size as power of 2 */
+ while (size < minsize) size <<= 1;
+ h = (struct hashtable *)malloc(sizeof(struct hashtable));
+ if (NULL == h) return NULL; /*oom*/
+ h->table = (struct entry **)malloc(sizeof(struct entry*) * size);
+ if (NULL == h->table) { free(h); return NULL; } /*oom*/
+
+ for (i=0;i<size;i++) { h->table[i] = NULL; }
+ h->tablelength = size;
+ h->entrycount = 0;
+ h->hashfn = hashf;
+ h->eqfn = eqf;
+ h->loadlimit = (unsigned int) ((float)size * maxloadfactor);
+ return h;
+}
+
+/*****************************************************************************/
+static unsigned int
+hash(struct hashtable *h, void *k)
+{
+ /* Aim to protect against poor hash functions by adding logic here
+ * - logic taken from java 1.4 hashtable source */
+ unsigned int i = h->hashfn(k);
+ i += ~(i << 9);
+ i ^= ((i >> 14) | (i << 18)); /* >>> */
+ i += (i << 4);
+ i ^= ((i >> 10) | (i << 22)); /* >>> */
+ return i;
+}
+/*****************************************************************************/
+static unsigned int
+indexFor(unsigned int tablelength, unsigned int hashvalue)
+{
+ /* Only works if tablelength == 2^N */
+ return (hashvalue & (tablelength - 1u));
+}
+
+/*****************************************************************************/
+static int
+hashtable_expand(struct hashtable *h)
+{
+ /* Double the size of the table to accomodate more entries */
+ struct entry **newtable;
+ struct entry *e;
+ struct entry **pE;
+ unsigned int newsize, i, index;
+ /* Check we're not hitting max capacity */
+ if (0 == (newsize = (h->tablelength << 1))) return 0;
+
+ newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize);
+ if (NULL != newtable)
+ {
+ memset(newtable, 0, newsize * sizeof(struct entry *));
+ /* This algorithm is not 'stable'. ie. it reverses the list
+ * when it transfers entries between the tables */
+ for (i = 0; i < h->tablelength; i++) {
+ while (NULL != (e = h->table[i])) {
+ h->table[i] = e->next;
+ index = indexFor(newsize,e->h);
+ e->next = newtable[index];
+ newtable[index] = e;
+ }
+ }
+ free(h->table);
+ h->table = newtable;
+ }
+ /* Plan B: realloc instead */
+ else
+ {
+ newtable = (struct entry **)
+ realloc(h->table, newsize * sizeof(struct entry *));
+ if (NULL == newtable) return 0;
+ h->table = newtable;
+ for (i = h->tablelength; i < newsize; i++) {
+ newtable[i] = NULL;
+ }
+ for (i = 0; i < h->tablelength; i++) {
+ for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
+ index = indexFor(newsize,e->h);
+ if (index == i)
+ {
+ pE = &(e->next);
+ }
+ else
+ {
+ *pE = e->next;
+ e->next = newtable[index];
+ newtable[index] = e;
+ }
+ }
+ }
+ }
+ h->tablelength = newsize;
+ h->loadlimit <<= 1;
+ return -1;
+}
+
+/*****************************************************************************/
+unsigned int
+hashtable_count(struct hashtable *h)
+{
+ return h->entrycount;
+}
+
+/*****************************************************************************/
+int
+hashtable_insert(struct hashtable *h, void *k, void *v)
+{
+ /* This method allows duplicate keys - but they shouldn't be used */
+ unsigned int index;
+ struct entry *e;
+ if (++(h->entrycount) > h->loadlimit)
+ {
+ /* Ignore the return value. If expand fails, we should
+ * still try cramming just this value into the existing table
+ * -- we may not have memory for a larger table, but one more
+ * element may be ok. Next time we insert, we'll try expanding again.*/
+ hashtable_expand(h);
+ }
+ e = (struct entry *)malloc(sizeof(struct entry));
+ if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
+ e->h = hash(h,k);
+ index = indexFor(h->tablelength,e->h);
+ e->k = k;
+ e->v = v;
+ e->next = h->table[index];
+ h->table[index] = e;
+ return -1;
+}
+
+/*****************************************************************************/
+int
+hashtable_change(struct hashtable *h, void *k, void *v)
+{
+ struct entry *e;
+ unsigned int hashvalue, index;
+ hashvalue = hash(h,k);
+ index = indexFor(h->tablelength,hashvalue);
+ e = h->table[index];
+ while (NULL != e)
+ {
+ /* Check hash value to short circuit heavier comparison */
+ if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
+ {
+ free(e->v);
+ e->v = v;
+ return -1;
+ }
+ e = e->next;
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_search(struct hashtable *h, void *k)
+{
+ struct entry *e;
+ unsigned int hashvalue, index;
+ hashvalue = hash(h,k);
+ index = indexFor(h->tablelength,hashvalue);
+ e = h->table[index];
+ while (NULL != e)
+ {
+ /* Check hash value to short circuit heavier comparison */
+ if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;
+ e = e->next;
+ }
+ return NULL;
+}
+
+/*****************************************************************************/
+void * /* returns value associated with key */
+hashtable_remove(struct hashtable *h, void *k)
+{
+ /* TODO: consider compacting the table when the load factor drops enough,
+ * or provide a 'compact' method. */
+
+ struct entry *e;
+ struct entry **pE;
+ void *v;
+
+ unsigned int index = indexFor(h->tablelength,hash(h,k));
+ pE = &(h->table[index]);
+ e = *pE;
+ while (NULL != e)
+ {
+ if (h->eqfn(k, e->k))
+ {
+ *pE = e->next;
+ h->entrycount--;
+ v = e->v;
+ free(e->k);
+ free(e);
+ return v;
+ }
+ pE = &(e->next);
+ e = e->next;
+ }
+ return NULL;
+}
+
+/*****************************************************************************/
+/* destroy */
+void
+hashtable_destroy(struct hashtable *h, int free_values)
+{
+ unsigned int i;
+ struct entry *e, *f;
+ struct entry **table = h->table;
+
+ for (i = 0; i < h->tablelength; i++)
+ {
+ e = table[i];
+ while (NULL != e)
+ {
+ f = e;
+ e = e->next;
+ free(f->k);
+ if (free_values)
+ free(f->v);
+ free(f);
+ }
+ }
+
+ free(h->table);
+ free(h);
+}
+
+
+/*****************************************************************************/
+/* hashtable_iterator - iterator constructor */
+
+struct hashtable_itr *
+hashtable_iterator(struct hashtable *h)
+{
+ unsigned int i, tablelength;
+ struct hashtable_itr *itr = (struct hashtable_itr *)
+ malloc(sizeof(struct hashtable_itr));
+ if (NULL == itr) return NULL;
+ itr->h = h;
+ itr->e = NULL;
+ tablelength = h->tablelength;
+ itr->index = tablelength;
+ if (0 == h->entrycount) return itr;
+
+ for (i = 0; i < tablelength; i++)
+ {
+ if (NULL != h->table[i])
+ {
+ itr->e = h->table[i];
+ itr->index = i;
+ break;
+ }
+ }
+ return itr;
+}
+
+/*****************************************************************************/
+/* key - return the key of the (key,value) pair at the current position */
+
+void *
+hashtable_iterator_key(struct hashtable_itr *i)
+{
+ return i->e->k;
+}
+
+/*****************************************************************************/
+/* value - return the value of the (key,value) pair at the current position */
+
+void *
+hashtable_iterator_value(struct hashtable_itr *i)
+{
+ return i->e->v;
+}
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ * returns zero if advanced to end of table */
+
+int
+hashtable_iterator_advance(struct hashtable_itr *itr)
+{
+ unsigned int j,tablelength;
+ struct entry **table;
+ struct entry *next;
+ if (NULL == itr->e) return 0; /* stupidity check */
+
+ next = itr->e->next;
+ if (NULL != next)
+ {
+ itr->e = next;
+ return -1;
+ }
+ tablelength = itr->h->tablelength;
+ if (tablelength <= (j = ++(itr->index)))
+ {
+ itr->e = NULL;
+ return 0;
+ }
+ table = itr->h->table;
+ while (NULL == (next = table[j]))
+ {
+ if (++j >= tablelength)
+ {
+ itr->index = tablelength;
+ return 0;
+ }
+ }
+ itr->index = j;
+ itr->e = next;
+ return -1;
+}
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2003 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* hash.h *
+***********************************************************/
+
+/*
+ * Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies of the Software and its documentation and acknowledgment shall be
+ * given in the documentation and software packages that this Software was
+ * used.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * */
+
+#ifndef HASH_H
+#define HASH_H
+
+
+/* Example of use:
+ *
+ * struct hashtable *h;
+ * struct some_key *k;
+ * struct some_value *v;
+ *
+ * static unsigned int hash_from_key_fn( void *k );
+ * static int keys_equal_fn ( void *key1, void *key2 );
+ *
+ * h = create_hashtable(16, 0.75, hash_from_key_fn, keys_equal_fn);
+ * k = (struct some_key *) malloc(sizeof(struct some_key));
+ * v = (struct some_value *) malloc(sizeof(struct some_value));
+ *
+ * (initialise k and v to suitable values)
+ *
+ * if (! hashtable_insert(h,k,v) )
+ * { exit(-1); }
+ *
+ * if (NULL == (found = hashtable_search(h,k) ))
+ * { printf("not found!"); }
+ *
+ * if (NULL == (found = hashtable_remove(h,k) ))
+ * { printf("Not found\n"); }
+ *
+ */
+
+/* Macros may be used to define type-safe(r) hashtable access functions, with
+ * methods specialized to take known key and value types as parameters.
+ *
+ * Example:
+ *
+ * Insert this at the start of your file:
+ *
+ * DEFINE_HASHTABLE_INSERT(insert_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_SEARCH(search_some, struct some_key, struct some_value);
+ * DEFINE_HASHTABLE_REMOVE(remove_some, struct some_key, struct some_value);
+ *
+ * This defines the functions 'insert_some', 'search_some' and 'remove_some'.
+ * These operate just like hashtable_insert etc., with the same parameters,
+ * but their function signatures have 'struct some_key *' rather than
+ * 'void *', and hence can generate compile time errors if your program is
+ * supplying incorrect data as a key (and similarly for value).
+ *
+ * Note that the hash and key equality functions passed to create_hashtable
+ * still take 'void *' parameters instead of 'some key *'. This shouldn't be
+ * a difficult issue as they're only defined and passed once, and the other
+ * functions will ensure that only valid keys are supplied to them.
+ *
+ * The cost for this checking is increased code size and runtime overhead
+ * - if performance is important, it may be worth switching back to the
+ * unsafe methods once your program has been debugged with the safe methods.
+ * This just requires switching to some simple alternative defines - eg:
+ * #define insert_some hashtable_insert
+ *
+ */
+
+
+/*****************************************************************************/
+struct entry
+{
+ void *k, *v;
+ unsigned int h;
+ struct entry *next;
+};
+
+struct hashtable {
+ unsigned int tablelength;
+ struct entry **table;
+ unsigned int entrycount;
+ unsigned int loadlimit;
+ unsigned int (*hashfn) (void *k);
+ int (*eqfn) (void *k1, void *k2);
+};
+
+/*****************************************************************************/
+struct hashtable_itr
+{
+ struct hashtable *h;
+ struct entry *e;
+ unsigned int index;
+};
+
+
+/*****************************************************************************
+ * create_hashtable
+
+ * @name create_hashtable
+ * @param minsize minimum initial size of hashtable
+ * @param maxloadfactor maximum ratio entries / tablesize
+ * @param hashfunction function for hashing keys
+ * @param key_eq_fn function for determining key equality
+ * @return newly created hashtable or NULL on failure
+ */
+
+struct hashtable *
+create_hashtable(unsigned int minsize, float maxloadfactor,
+ unsigned int (*hashfunction) (void*),
+ int (*key_eq_fn) (void*,void*));
+
+/*****************************************************************************
+ * hashtable_insert
+
+ * @name hashtable_insert
+ * @param h the hashtable to insert into
+ * @param k the key - hashtable claims ownership and will free on removal
+ * @param v the value - does not claim ownership
+ * @return non-zero for successful insertion
+ *
+ * This function will cause the table to expand if the insertion would take
+ * the ratio of entries to table size over the maximum load factor.
+ *
+ * This function does not check for repeated insertions with a duplicate key.
+ * The value returned when using a duplicate key is undefined -- when
+ * the hashtable changes size, the order of retrieval of duplicate key
+ * entries is reversed.
+ * If in doubt, remove before insert.
+ */
+
+int
+hashtable_insert(struct hashtable *h, void *k, void *v);
+
+#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
+int fnname (struct hashtable *h, keytype *k, valuetype *v) \
+{ \
+ return hashtable_insert(h,k,v); \
+}
+
+/*****************************************************************************
+ * hashtable_change
+
+ * @name hashtable_change
+ * @param h the hashtable to search
+ * @param k the key of the entry to change
+ * @param v the new value
+ * @return non-zero for successful change
+ */
+
+int
+hashtable_change(struct hashtable *h, void *k, void *v);
+
+#define DEFINE_HASHTABLE_CHANGE(fnname, keytype, valuetype) \
+int fnname (struct hashtable *h, keytype *k, valuetype *v) \
+{ \
+ return hashtable_change(h,k,v); \
+}
+
+/*****************************************************************************
+ * hashtable_search
+
+ * @name hashtable_search
+ * @param h the hashtable to search
+ * @param k the key to search for - does not claim ownership
+ * @return the value associated with the key, or NULL if none found
+ */
+
+void *
+hashtable_search(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+ return (valuetype *) (hashtable_search(h,k)); \
+}
+
+/*****************************************************************************
+ * hashtable_remove
+
+ * @name hashtable_remove
+ * @param h the hashtable to remove the item from
+ * @param k the key to search for - does not claim ownership
+ * @return the value associated with the key, or NULL if none found
+ */
+
+void * /* returns value */
+hashtable_remove(struct hashtable *h, void *k);
+
+#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
+valuetype * fnname (struct hashtable *h, keytype *k) \
+{ \
+ return (valuetype *) (hashtable_remove(h,k)); \
+}
+
+
+/*****************************************************************************
+ * hashtable_count
+
+ * @name hashtable_count
+ * @return the number of items stored in the hashtable
+ */
+unsigned int
+hashtable_count(struct hashtable *h);
+
+
+/*****************************************************************************
+ * hashtable_destroy
+
+ * @name hashtable_destroy
+ * @param free_values whether to call 'free' on the remaining values
+ */
+
+void
+hashtable_destroy(struct hashtable *h, int free_values);
+
+
+/*****************************************************************************/
+/* hashtable_iterator
+ */
+
+struct hashtable_itr *
+hashtable_iterator(struct hashtable *h);
+
+/*****************************************************************************/
+/* hashtable_iterator_key
+ * - return the value of the (key,value) pair at the current position */
+
+extern inline void *
+hashtable_iterator_key(struct hashtable_itr *i)
+{
+ return i->e->k;
+}
+
+/*****************************************************************************/
+/* value - return the value of the (key,value) pair at the current position */
+
+extern inline void *
+hashtable_iterator_value(struct hashtable_itr *i)
+{
+ return i->e->v;
+}
+
+/*****************************************************************************/
+/* advance - advance the iterator to the next element
+ * returns zero if advanced to end of table */
+
+int
+hashtable_iterator_advance(struct hashtable_itr *itr);
+
+#endif
#include "image.h"
#include "pcx.h"
#include "misc.h"
+#include "setup.h"
+/* ========================================================================= */
+/* PLATFORM SPECIFIC IMAGE FUNCTIONS */
+/* ========================================================================= */
+
#if defined(TARGET_X11)
/* for MS-DOS/Allegro, exclude all except newImage() and freeImage() */
depth = 8;
#endif
- image = checked_malloc(sizeof(Image));
- image->data = checked_malloc(width * height * bytes_per_pixel);
+ image = checked_calloc(sizeof(Image));
+ image->data = checked_calloc(width * height * bytes_per_pixel);
image->width = width;
image->height = height;
image->depth = depth;
display_bits_per_pixel = bitsPerPixelAtDepth(display, screen, depth);
display_bytes_per_pixel = (display_bits_per_pixel + 7) / 8;
- ximage = XCreateImage(display, visual, depth, ZPixmap, 0,
- NULL, image->width, image->height,
+ ximage = XCreateImage(display, visual, depth, ZPixmap,
+ 0, NULL, image->width, image->height,
8, image->width * display_bytes_per_pixel);
ximage->data =
checked_malloc(image->width * image->height * display_bytes_per_pixel);
return ximageinfo;
}
+/*
+ -----------------------------------------------------------------------------
+ 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!
+ -----------------------------------------------------------------------------
+*/
+
+void ZoomPixmap(Display *display, GC gc, Pixmap src_pixmap, Pixmap dst_pixmap,
+ int src_width, int src_height,
+ int dst_width, int dst_height)
+{
+ XImage *src_ximage, *dst_ximage;
+ 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 row_skip, col_skip;
+
+ /* adjust source image size to integer multiple of destination image size */
+ src_width = dst_width * zoom_factor;
+ src_height = dst_height * zoom_factor;
+
+ /* copy source pixmap to temporary image */
+ src_ximage = XGetImage(display, src_pixmap, 0, 0, src_width, src_height,
+ AllPlanes, ZPixmap);
+
+ 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);
+ 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;
+
+ /* 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++;
+
+ /* copy scaled image to destination pixmap */
+ XPutImage(display, dst_pixmap, gc, dst_ximage, 0, 0, 0, 0,
+ dst_width, dst_height);
+
+ /* free temporary images */
+ XDestroyImage(src_ximage);
+ XDestroyImage(dst_ximage);
+}
+
void freeXImage(Image *image, XImageInfo *ximageinfo)
{
if (ximageinfo->index != NULL && ximageinfo->no > 0)
#endif /* PLATFORM_UNIX */
#endif /* TARGET_X11 */
+
+
+/* ========================================================================= */
+/* PLATFORM INDEPENDENT IMAGE FUNCTIONS */
+/* ========================================================================= */
+
+struct ImageInfo
+{
+ char *source_filename;
+ int num_references;
+
+ Bitmap *bitmap;
+ boolean contains_small_images;
+};
+typedef struct ImageInfo ImageInfo;
+
+static struct ArtworkListInfo *image_info = NULL;
+
+static void *Load_PCX(char *filename)
+{
+ ImageInfo *img_info;
+
+#if 0
+ printf("loading PCX file '%s'\n", filename);
+#endif
+
+ img_info = checked_calloc(sizeof(ImageInfo));
+
+ if ((img_info->bitmap = LoadImage(filename)) == NULL)
+ {
+ Error(ERR_WARN, "cannot read image file '%s': LoadImage() failed: %s",
+ filename, GetError());
+ free(img_info);
+ return NULL;
+ }
+
+ img_info->source_filename = getStringCopy(filename);
+
+ img_info->contains_small_images = FALSE;
+
+ return img_info;
+}
+
+static void FreeImage(void *ptr)
+{
+ ImageInfo *image = (ImageInfo *)ptr;
+
+ if (image == NULL)
+ return;
+
+ if (image->bitmap)
+ FreeBitmap(image->bitmap);
+
+ if (image->source_filename)
+ free(image->source_filename);
+
+ free(image);
+}
+
+int getImageListSize()
+{
+ return (image_info->num_file_list_entries +
+ image_info->num_dynamic_file_list_entries);
+}
+
+struct FileInfo *getImageListEntry(int pos)
+{
+ int num_list_entries = image_info->num_file_list_entries;
+ int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
+
+ return (pos < num_list_entries ? &image_info->file_list[list_pos] :
+ &image_info->dynamic_file_list[list_pos]);
+}
+
+static ImageInfo *getImageInfoEntryFromImageID(int pos)
+{
+ 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];
+}
+
+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)
+{
+#if 0
+ /* !!! this does not work for dynamic artwork (crash!) !!! */
+ struct FileInfo *file_list = (struct FileInfo *)image_info->file_list;
+
+ return file_list[graphic].token;
+#else
+ struct FileInfo *file_list = getImageListEntry(graphic);
+
+ return (file_list != NULL ? file_list->token : NULL);
+#endif
+}
+
+int getImageIDFromToken(char *token)
+{
+ struct FileInfo *file_list = image_info->file_list;
+ int num_list_entries = image_info->num_file_list_entries;
+ int i;
+
+ for (i=0; i < num_list_entries; i++)
+ if (strcmp(file_list[i].token, token) == 0)
+ return i;
+
+ return -1;
+}
+
+char *getImageConfigFilename()
+{
+ return getCustomArtworkConfigFilename(image_info->type);
+}
+
+int getImageListPropertyMappingSize()
+{
+ return image_info->num_property_mapping_entries;
+}
+
+struct PropertyMapping *getImageListPropertyMapping()
+{
+ return image_info->property_mapping;
+}
+
+void InitImageList(struct ConfigInfo *config_list, int num_file_list_entries,
+ struct ConfigInfo *config_suffix_list,
+ char **base_prefixes, char **ext1_suffixes,
+ char **ext2_suffixes, char **ext3_suffixes,
+ char **ignore_tokens)
+{
+ int i;
+
+ image_info = checked_calloc(sizeof(struct ArtworkListInfo));
+ image_info->type = ARTWORK_TYPE_GRAPHICS;
+
+ /* ---------- initialize file list and suffix lists ---------- */
+
+ image_info->num_file_list_entries = num_file_list_entries;
+ image_info->num_dynamic_file_list_entries = 0;
+
+ image_info->file_list =
+ getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
+ num_file_list_entries);
+ image_info->dynamic_file_list = NULL;
+
+ image_info->num_suffix_list_entries = 0;
+ for (i=0; config_suffix_list[i].token != NULL; i++)
+ image_info->num_suffix_list_entries++;
+
+ image_info->suffix_list = config_suffix_list;
+
+ /* ---------- initialize base prefix and suffixes lists ---------- */
+
+ image_info->num_base_prefixes = 0;
+ for (i=0; base_prefixes[i] != NULL; i++)
+ image_info->num_base_prefixes++;
+
+ image_info->num_ext1_suffixes = 0;
+ for (i=0; ext1_suffixes[i] != NULL; i++)
+ image_info->num_ext1_suffixes++;
+
+ image_info->num_ext2_suffixes = 0;
+ for (i=0; ext2_suffixes[i] != NULL; i++)
+ image_info->num_ext2_suffixes++;
+
+ image_info->num_ext3_suffixes = 0;
+ for (i=0; ext3_suffixes[i] != NULL; i++)
+ image_info->num_ext3_suffixes++;
+
+ image_info->num_ignore_tokens = 0;
+ for (i=0; ignore_tokens[i] != NULL; i++)
+ image_info->num_ignore_tokens++;
+
+ image_info->base_prefixes = base_prefixes;
+ image_info->ext1_suffixes = ext1_suffixes;
+ image_info->ext2_suffixes = ext2_suffixes;
+ image_info->ext3_suffixes = ext3_suffixes;
+ image_info->ignore_tokens = ignore_tokens;
+
+ image_info->num_property_mapping_entries = 0;
+
+ image_info->property_mapping = NULL;
+
+ /* ---------- initialize artwork reference and content lists ---------- */
+
+ image_info->sizeof_artwork_list_entry = sizeof(ImageInfo *);
+
+ image_info->artwork_list =
+ checked_calloc(num_file_list_entries * sizeof(ImageInfo *));
+ image_info->dynamic_artwork_list = NULL;
+
+ image_info->content_list = NULL;
+
+ /* ---------- initialize artwork loading/freeing functions ---------- */
+
+ image_info->load_artwork = Load_PCX;
+ image_info->free_artwork = FreeImage;
+}
+
+void ReloadCustomImages()
+{
+#if 0
+ printf("DEBUG: reloading images '%s' ...\n", artwork.gfx_current_identifier);
+#endif
+
+ LoadArtworkConfig(image_info);
+ ReloadCustomArtworkList(image_info);
+}
+
+void CreateImageWithSmallImages(int pos)
+{
+ ImageInfo *img_info = getImageInfoEntryFromImageID(pos);
+
+ if (img_info == NULL || img_info->contains_small_images)
+ return;
+
+ CreateBitmapWithSmallBitmaps(img_info->bitmap);
+
+ img_info->contains_small_images = TRUE;
+
+#if 0
+ printf("CreateImageWithSmallImages: '%s' done\n", img_info->source_filename);
+#endif
+}
+
+void FreeAllImages()
+{
+ FreeCustomArtworkLists(image_info);
+}
Image *newImage(unsigned int, unsigned int, unsigned int);
void freeImage(Image *);
void freeXImage(Image *, XImageInfo *);
+
+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);
+Bitmap *getBitmapFromImageID(int);
+char *getTokenFromImageID(int);
+int getImageIDFromToken(char *);
+char *getImageConfigFilename();
+int getImageListPropertyMappingSize();
+struct PropertyMapping *getImageListPropertyMapping();
+void InitImageList(struct ConfigInfo *, int, struct ConfigInfo *,
+ char **, char **, char **, char **, char **);
+
+void ReloadCustomImages();
+void CreateImageWithSmallImages(int);
+
+void FreeAllImages();
+
#endif /* IMAGE_H */
/* ========================================================================= */
-/* platform dependant joystick functions */
+/* platform dependent joystick functions */
/* ========================================================================= */
#if defined(PLATFORM_UNIX) && !defined(TARGET_SDL)
/* ========================================================================= */
-/* platform independant joystick functions */
+/* platform independent joystick functions */
/* ========================================================================= */
#define TRANSLATE_JOYSYMBOL_TO_JOYNAME 0
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2003 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* macosx.h *
+***********************************************************/
+
+#ifndef MACOSX_H
+#define MACOSX_H
+
+
+/* some symbols are already defined on Mac OS X */
+#define Delay Delay_internal
+#define DrawLine DrawLine_internal
+#define DrawText DrawText_internal
+#define GetPixel GetPixel_internal
+
+#endif /* MACOSX_H */
#include "misc.h"
#include "setup.h"
#include "random.h"
+#include "text.h"
+#include "image.h"
+/* ------------------------------------------------------------------------- */
+/* some generic helper functions */
+/* ------------------------------------------------------------------------- */
+
+void fprintf_line(FILE *stream, char *line_string, int line_length)
+{
+ int i;
+
+ for (i=0; i<line_length; i++)
+ fprintf(stream, "%s", line_string);
+
+ fprintf(stream, "\n");
+}
+
+void printf_line(char *line_string, int line_length)
+{
+ fprintf_line(stdout, line_string, line_length);
+}
+
+/* int2str() returns a number converted to a string;
+ the used memory is static, but will be overwritten by later calls,
+ so if you want to save the result, copy it to a private string buffer;
+ there can be 10 local calls of int2str() without buffering the result --
+ the 11th call will then destroy the result from the first call and so on.
+*/
+
+char *int2str(int number, int size)
+{
+ static char shift_array[10][40];
+ static int shift_counter = 0;
+ char *s = shift_array[shift_counter];
+
+ shift_counter = (shift_counter + 1) % 10;
+
+ if (size > 20)
+ size = 20;
+
+ if (size)
+ {
+ sprintf(s, " %09d", number);
+ return &s[strlen(s) - size];
+ }
+ else
+ {
+ sprintf(s, "%d", number);
+ return s;
+ }
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* counter functions */
+/* ------------------------------------------------------------------------- */
+
#if defined(PLATFORM_MSDOS)
volatile unsigned long counter = 0;
{
unsigned long actual_frame_counter = FrameCounter;
- if (actual_frame_counter < *frame_counter_var + frame_delay &&
- actual_frame_counter >= *frame_counter_var)
+ if (actual_frame_counter >= *frame_counter_var &&
+ actual_frame_counter < *frame_counter_var + frame_delay)
return FALSE;
*frame_counter_var = actual_frame_counter;
{
unsigned long actual_counter = Counter();
- if (actual_counter < *counter_var + delay &&
- actual_counter >= *counter_var)
+ if (actual_counter >= *counter_var &&
+ actual_counter < *counter_var + delay)
return FALSE;
*counter_var = actual_counter;
{
actual_counter = Counter();
- if (actual_counter < *counter_var + delay &&
- actual_counter >= *counter_var)
+ if (actual_counter >= *counter_var &&
+ actual_counter < *counter_var + delay)
sleep_milliseconds((*counter_var + delay - actual_counter) / 2);
else
break;
*counter_var = actual_counter;
}
-/* int2str() returns a number converted to a string;
- the used memory is static, but will be overwritten by later calls,
- so if you want to save the result, copy it to a private string buffer;
- there can be 10 local calls of int2str() without buffering the result --
- the 11th call will then destroy the result from the first call and so on.
-*/
-
-char *int2str(int number, int size)
-{
- static char shift_array[10][40];
- static int shift_counter = 0;
- char *s = shift_array[shift_counter];
- shift_counter = (shift_counter + 1) % 10;
+/* ------------------------------------------------------------------------- */
+/* random generator functions */
+/* ------------------------------------------------------------------------- */
- if (size > 20)
- size = 20;
+#if 0
+unsigned int SimpleRND(unsigned int max)
+{
+ return (random_linux_libc(RND_FREE) % max);
+}
- if (size)
+unsigned int InitSimpleRND(long seed)
+{
+ if (seed == NEW_RANDOMIZE)
{
- sprintf(s, " %09d", number);
- return &s[strlen(s) - size];
+ struct timeval current_time;
+
+ gettimeofday(¤t_time, NULL);
+ seed = (long)current_time.tv_usec;
}
- else
+
+ srandom_linux_libc(RND_FREE, (unsigned int) seed);
+
+ return (unsigned int) seed;
+}
+
+unsigned int RND(unsigned int max)
+{
+ return (random_linux_libc(RND_GAME) % max);
+}
+
+unsigned int InitRND(long seed)
+{
+ if (seed == NEW_RANDOMIZE)
{
- sprintf(s, "%d", number);
- return s;
+ struct timeval current_time;
+
+ gettimeofday(¤t_time, NULL);
+ seed = (long)current_time.tv_usec;
}
+
+ srandom_linux_libc(RND_GAME, (unsigned int) seed);
+
+ return (unsigned int) seed;
}
+#endif
-unsigned int SimpleRND(unsigned int max)
+unsigned int init_random_number(int nr, long seed)
{
+ if (seed == NEW_RANDOMIZE)
+ {
#if defined(TARGET_SDL)
- static unsigned long root = 654321;
- unsigned long current_ms;
-
- current_ms = SDL_GetTicks();
- root = root * 4253261 + current_ms;
- return (root % max);
+ seed = (long)SDL_GetTicks();
#else
- static unsigned long root = 654321;
- struct timeval current_time;
+ struct timeval current_time;
- gettimeofday(¤t_time, NULL);
- root = root * 4253261 + current_time.tv_sec + current_time.tv_usec;
- return (root % max);
+ gettimeofday(¤t_time, NULL);
+ seed = (long)current_time.tv_usec;
#endif
-}
+ }
-#ifdef DEBUG
-static unsigned int last_RND_value = 0;
+ srandom_linux_libc(nr, (unsigned int) seed);
-unsigned int last_RND()
-{
- return last_RND_value;
+ return (unsigned int) seed;
}
-#endif
-unsigned int RND(unsigned int max)
+unsigned int get_random_number(int nr, unsigned int max)
{
-#ifdef DEBUG
- return (last_RND_value = random_linux_libc() % max);
-#else
- return (random_linux_libc() % max);
-#endif
+ return (max > 0 ? random_linux_libc(nr) % max : 0);
}
-unsigned int InitRND(long seed)
+
+/* ------------------------------------------------------------------------- */
+/* system info functions */
+/* ------------------------------------------------------------------------- */
+
+#if !defined(PLATFORM_MSDOS)
+static char *get_corrected_real_name(char *real_name)
{
-#if defined(TARGET_SDL)
- unsigned long current_ms;
+ char *real_name_new = checked_malloc(MAX_USERNAME_LEN + 1);
+ char *from_ptr = real_name;
+ char *to_ptr = real_name_new;
- if (seed == NEW_RANDOMIZE)
- {
- current_ms = SDL_GetTicks();
- srandom_linux_libc((unsigned int) current_ms);
- return (unsigned int) current_ms;
- }
- else
+ if (strchr(real_name, 'ß') == NULL) /* name does not contain 'ß' */
{
- srandom_linux_libc((unsigned int) seed);
- return (unsigned int) seed;
- }
-#else
- struct timeval current_time;
+ strncpy(real_name_new, real_name, MAX_USERNAME_LEN);
+ real_name_new[MAX_USERNAME_LEN] = '\0';
- if (seed == NEW_RANDOMIZE)
- {
- gettimeofday(¤t_time, NULL);
- srandom_linux_libc((unsigned int) current_time.tv_usec);
- return (unsigned int) current_time.tv_usec;
+ return real_name_new;
}
- else
+
+ /* the user's real name may contain a 'ß' character (german sharp s),
+ which has no equivalent in upper case letters (which our fonts use) */
+ while (*from_ptr && (long)(to_ptr - real_name_new) < MAX_USERNAME_LEN - 1)
{
- srandom_linux_libc((unsigned int) seed);
- return (unsigned int) seed;
+ if (*from_ptr != 'ß')
+ *to_ptr++ = *from_ptr++;
+ else
+ {
+ from_ptr++;
+ *to_ptr++ = 's';
+ *to_ptr++ = 's';
+ }
}
-#endif
+
+ *to_ptr = '\0';
+
+ return real_name_new;
}
+#endif
char *getLoginName()
{
-#if defined(PLATFORM_WIN32)
- return ANONYMOUS_NAME;
-#else
static char *login_name = NULL;
+#if defined(PLATFORM_WIN32)
+ if (login_name == NULL)
+ {
+ unsigned long buffer_size = MAX_USERNAME_LEN + 1;
+ login_name = checked_malloc(buffer_size);
+
+ if (GetUserName(login_name, &buffer_size) == 0)
+ strcpy(login_name, ANONYMOUS_NAME);
+ }
+#else
if (login_name == NULL)
{
struct passwd *pwd;
else
login_name = getStringCopy(pwd->pw_name);
}
+#endif
return login_name;
-#endif
}
char *getRealName()
{
-#if defined(PLATFORM_UNIX)
- struct passwd *pwd;
+ static char *real_name = NULL;
- if ((pwd = getpwuid(getuid())) == NULL || strlen(pwd->pw_gecos) == 0)
- return ANONYMOUS_NAME;
- else
+#if defined(PLATFORM_WIN32)
+ if (real_name == NULL)
{
- static char real_name[1024];
- char *from_ptr = pwd->pw_gecos, *to_ptr = real_name;
-
- if (strchr(pwd->pw_gecos, 'ß') == NULL)
- return pwd->pw_gecos;
+ static char buffer[MAX_USERNAME_LEN + 1];
+ unsigned long buffer_size = MAX_USERNAME_LEN + 1;
- /* the user's real name contains a 'ß' character (german sharp s),
- which has no equivalent in upper case letters (which our fonts use) */
- while (*from_ptr != '\0' && (long)(to_ptr - real_name) < 1024 - 2)
- {
- if (*from_ptr != 'ß')
- *to_ptr++ = *from_ptr++;
- else
- {
- from_ptr++;
- *to_ptr++ = 's';
- *to_ptr++ = 's';
- }
- }
- *to_ptr = '\0';
+ if (GetUserName(buffer, &buffer_size) != 0)
+ real_name = get_corrected_real_name(buffer);
+ else
+ real_name = ANONYMOUS_NAME;
+ }
+#elif defined(PLATFORM_UNIX)
+ if (real_name == NULL)
+ {
+ struct passwd *pwd;
- return real_name;
+ if ((pwd = getpwuid(getuid())) != NULL && strlen(pwd->pw_gecos) != 0)
+ real_name = get_corrected_real_name(pwd->pw_gecos);
+ else
+ real_name = ANONYMOUS_NAME;
}
-#else /* !PLATFORM_UNIX */
- return ANONYMOUS_NAME;
+#else
+ real_name = ANONYMOUS_NAME;
#endif
+
+ return real_name;
}
char *getHomeDir()
{
-#if defined(PLATFORM_UNIX)
- static char *home_dir = NULL;
+ static char *dir = NULL;
+
+#if defined(PLATFORM_WIN32)
+ if (dir == NULL)
+ {
+ dir = checked_malloc(MAX_PATH + 1);
- if (home_dir == NULL)
+ if (!SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, dir)))
+ strcpy(dir, ".");
+ }
+#elif defined(PLATFORM_UNIX)
+ if (dir == NULL)
{
- if ((home_dir = getenv("HOME")) == NULL)
+ if ((dir = getenv("HOME")) == NULL)
{
struct passwd *pwd;
- if ((pwd = getpwuid(getuid())) == NULL)
- home_dir = ".";
+ if ((pwd = getpwuid(getuid())) != NULL)
+ dir = getStringCopy(pwd->pw_dir);
else
- home_dir = getStringCopy(pwd->pw_dir);
+ dir = ".";
}
}
-
- return home_dir;
#else
- return ".";
+ dir = ".";
#endif
+
+ return dir;
}
+
+/* ------------------------------------------------------------------------- */
+/* various string functions */
+/* ------------------------------------------------------------------------- */
+
char *getPath2(char *path1, char *path2)
{
char *complete_path = checked_malloc(strlen(path1) + 1 +
strlen(path2) + 1);
sprintf(complete_path, "%s/%s", path1, path2);
+
return complete_path;
}
strlen(path3) + 1);
sprintf(complete_path, "%s/%s/%s", path1, path2, path3);
+
return complete_path;
}
+char *getStringCat2(char *s1, char *s2)
+{
+ char *complete_string = checked_malloc(strlen(s1) + strlen(s2) + 1);
+
+ sprintf(complete_string, "%s%s", s1, s2);
+
+ return complete_string;
+}
+
char *getStringCopy(char *s)
{
char *s_copy;
return NULL;
s_copy = checked_malloc(strlen(s) + 1);
-
strcpy(s_copy, s);
+
return s_copy;
}
return s_copy;
}
+void setString(char **old_value, char *new_value)
+{
+ if (*old_value != NULL)
+ free(*old_value);
+
+ *old_value = getStringCopy(new_value);
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* command line option handling functions */
+/* ------------------------------------------------------------------------- */
+
+static void printUsage()
+{
+ printf("\n"
+ "Usage: %s [OPTION]... [HOSTNAME [PORT]]\n"
+ "\n"
+ "Options:\n"
+ " -d, --display HOSTNAME[:SCREEN] specify X server display\n"
+ " -b, --basepath DIRECTORY alternative base DIRECTORY\n"
+ " -l, --level DIRECTORY alternative level DIRECTORY\n"
+ " -g, --graphics DIRECTORY alternative graphics DIRECTORY\n"
+ " -s, --sounds DIRECTORY alternative sounds DIRECTORY\n"
+ " -m, --music DIRECTORY alternative music DIRECTORY\n"
+ " -n, --network network multiplayer game\n"
+ " --serveronly only start network server\n"
+ " -v, --verbose verbose mode\n"
+ " --debug display debugging information\n"
+ " -e, --execute COMMAND execute batch COMMAND:\n"
+ "\n"
+ "Valid commands for '--execute' option:\n"
+ " \"print graphicsinfo.conf\" print default graphics config\n"
+ " \"print soundsinfo.conf\" print default sounds config\n"
+ " \"print musicinfo.conf\" print default music config\n"
+ " \"dump level FILE\" dump level data from FILE\n"
+ " \"dump tape FILE\" dump tape data from FILE\n"
+ " \"autoplay LEVELDIR\" play level tapes for LEVELDIR\n"
+ "\n",
+ program.command_basename);
+}
+
void GetOptions(char *argv[])
{
char **options_left = &argv[1];
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.execute_command = NULL;
options.serveronly = FALSE;
options.network = FALSE;
options.verbose = FALSE;
options.debug = FALSE;
- options.debug_command = NULL;
+
+#if !defined(PLATFORM_UNIX)
+ if (*options_left == NULL) /* no options given -- enable verbose mode */
+ options.verbose = TRUE;
+#endif
while (*options_left)
{
Error(ERR_EXIT_HELP, "unrecognized option '%s'", option);
else if (strncmp(option, "-help", option_len) == 0)
{
- printf("Usage: %s [options] [<server host> [<server port>]]\n"
- "Options:\n"
- " -d, --display <host>[:<scr>] X server display\n"
- " -b, --basepath <directory> alternative base directory\n"
- " -l, --level <directory> alternative level directory\n"
- " -g, --graphics <directory> alternative graphics directory\n"
- " -s, --sounds <directory> alternative sounds directory\n"
- " -m, --music <directory> alternative music directory\n"
- " -n, --network network multiplayer game\n"
- " --serveronly only start network server\n"
- " -v, --verbose verbose mode\n"
- " --debug display debugging information\n",
- program.command_basename);
-
- if (options.debug)
- printf(" --debug-command <command> execute special command\n");
+ printUsage();
exit(0);
}
{
options.debug = TRUE;
}
- else if (strncmp(option, "-debug-command", option_len) == 0)
+ else if (strncmp(option, "-execute", option_len) == 0)
{
if (option_arg == NULL)
Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str);
- options.debug_command = option_arg;
+ options.execute_command = option_arg;
if (option_arg == next_option)
options_left++;
}
}
}
+
+/* ------------------------------------------------------------------------- */
+/* error handling functions */
+/* ------------------------------------------------------------------------- */
+
/* used by SetError() and GetError() to store internal error messages */
static char internal_error[1024]; /* this is bad */
void Error(int mode, char *format, ...)
{
+ static boolean last_line_was_separator = FALSE;
char *process_name = "";
FILE *error = stderr;
char *newline = "\n";
if (mode & ERR_WARN && !options.verbose)
return;
+ if (mode == ERR_RETURN_LINE)
+ {
+ if (!last_line_was_separator)
+ fprintf_line(error, format, 79);
+
+ last_line_was_separator = TRUE;
+
+ return;
+ }
+
+ last_line_was_separator = FALSE;
+
#if defined(PLATFORM_MSDOS)
newline = "\r\n";
}
}
+
+/* ------------------------------------------------------------------------- */
+/* memory allocation functions */
+/* ------------------------------------------------------------------------- */
+
void *checked_malloc(unsigned long size)
{
void *ptr;
return ptr;
}
+
+/* ------------------------------------------------------------------------- */
+/* various helper functions */
+/* ------------------------------------------------------------------------- */
+
inline void swap_numbers(int *i1, int *i2)
{
int help = *i1;
int getFileVersion(FILE *file)
{
- int version_major, version_minor, version_patch;
+ int version_major, version_minor, version_patch, version_release;
- version_major = fgetc(file);
- version_minor = fgetc(file);
- version_patch = fgetc(file);
- fgetc(file); /* not used */
+ version_major = fgetc(file);
+ version_minor = fgetc(file);
+ version_patch = fgetc(file);
+ version_release = fgetc(file);
- return VERSION_IDENT(version_major, version_minor, version_patch);
+ return RELEASE_IDENT(version_major, version_minor, version_patch,
+ version_release);
}
void putFileVersion(FILE *file, int version)
{
- int version_major = VERSION_MAJOR(version);
- int version_minor = VERSION_MINOR(version);
- int version_patch = VERSION_PATCH(version);
-
- fputc(version_major, file);
- fputc(version_minor, file);
- fputc(version_patch, file);
- fputc(0, file); /* not used */
+ int version_major = VERSION_MAJOR(version);
+ int version_minor = VERSION_MINOR(version);
+ int version_patch = VERSION_PATCH(version);
+ int version_release = VERSION_RELEASE(version);
+
+ fputc(version_major, file);
+ fputc(version_minor, file);
+ fputc(version_patch, file);
+ fputc(version_release, file);
}
void ReadUnusedBytesFromFile(FILE *file, unsigned long bytes)
}
-/* ========================================================================= */
-/* functions for checking filenames */
-/* ========================================================================= */
+/* ------------------------------------------------------------------------- */
+/* functions to translate string identifiers to integer or boolean value */
+/* ------------------------------------------------------------------------- */
-boolean FileIsGraphic(char *filename)
+int get_integer_from_string(char *s)
{
- if (strlen(filename) > 4 &&
- strcmp(&filename[strlen(filename) - 4], ".pcx") == 0)
- return TRUE;
+ static char *number_text[][3] =
+ {
+ { "0", "zero", "null", },
+ { "1", "one", "first" },
+ { "2", "two", "second" },
+ { "3", "three", "third" },
+ { "4", "four", "fourth" },
+ { "5", "five", "fifth" },
+ { "6", "six", "sixth" },
+ { "7", "seven", "seventh" },
+ { "8", "eight", "eighth" },
+ { "9", "nine", "ninth" },
+ { "10", "ten", "tenth" },
+ { "11", "eleven", "eleventh" },
+ { "12", "twelve", "twelfth" },
+ };
- return FALSE;
+ int i, j;
+ char *s_lower = getStringToLower(s);
+ int result = -1;
+
+ for (i=0; i<13; i++)
+ for (j=0; j<3; j++)
+ if (strcmp(s_lower, number_text[i][j]) == 0)
+ result = i;
+
+ if (result == -1)
+ result = atoi(s);
+
+ free(s_lower);
+
+ return result;
}
-boolean FileIsSound(char *basename)
+boolean get_boolean_from_string(char *s)
{
- if (strlen(basename) > 4 &&
- strcmp(&basename[strlen(basename) - 4], ".wav") == 0)
- return TRUE;
+ char *s_lower = getStringToLower(s);
+ boolean result = FALSE;
- return FALSE;
+ if (strcmp(s_lower, "true") == 0 ||
+ strcmp(s_lower, "yes") == 0 ||
+ strcmp(s_lower, "on") == 0 ||
+ get_integer_from_string(s) == 1)
+ result = TRUE;
+
+ free(s_lower);
+
+ return result;
}
-boolean FileIsMusic(char *basename)
+
+/* ------------------------------------------------------------------------- */
+/* functions for generic lists */
+/* ------------------------------------------------------------------------- */
+
+ListNode *newListNode()
{
- /* "music" can be a WAV (loop) file or (if compiled with SDL) a MOD file */
+ return checked_calloc(sizeof(ListNode));
+}
- if (FileIsSound(basename))
- return TRUE;
+void addNodeToList(ListNode **node_first, char *key, void *content)
+{
+ ListNode *node_new = newListNode();
-#if defined(TARGET_SDL)
- if (strlen(basename) > 4 &&
- (strcmp(&basename[strlen(basename) - 4], ".mod") == 0 ||
- strcmp(&basename[strlen(basename) - 4], ".MOD") == 0 ||
- strncmp(basename, "mod.", 4) == 0 ||
- strncmp(basename, "MOD.", 4) == 0))
- return TRUE;
+#if 0
+ printf("LIST: adding node with key '%s'\n", key);
#endif
- return FALSE;
+ node_new->key = getStringCopy(key);
+ node_new->content = content;
+ node_new->next = *node_first;
+ *node_first = node_new;
}
-boolean FileIsArtworkType(char *basename, int type)
+void deleteNodeFromList(ListNode **node_first, char *key,
+ void (*destructor_function)(void *))
{
- if ((type == TREE_TYPE_GRAPHICS_DIR && FileIsGraphic(basename)) ||
+ if (node_first == NULL || *node_first == NULL)
+ return;
+
+#if 0
+ printf("[CHECKING LIST KEY '%s' == '%s']\n",
+ (*node_first)->key, key);
+#endif
+
+ if (strcmp((*node_first)->key, key) == 0)
+ {
+#if 0
+ printf("[DELETING LIST ENTRY]\n");
+#endif
+
+ free((*node_first)->key);
+ if (destructor_function)
+ destructor_function((*node_first)->content);
+ *node_first = (*node_first)->next;
+ }
+ else
+ deleteNodeFromList(&(*node_first)->next, key, destructor_function);
+}
+
+ListNode *getNodeFromKey(ListNode *node_first, char *key)
+{
+ if (node_first == NULL)
+ return NULL;
+
+ if (strcmp(node_first->key, key) == 0)
+ return node_first;
+ else
+ return getNodeFromKey(node_first->next, key);
+}
+
+int getNumNodes(ListNode *node_first)
+{
+ return (node_first ? 1 + getNumNodes(node_first->next) : 0);
+}
+
+void dumpList(ListNode *node_first)
+{
+ ListNode *node = node_first;
+
+ while (node)
+ {
+ printf("['%s' (%d)]\n", node->key,
+ ((struct ListNodeInfo *)node->content)->num_references);
+ node = node->next;
+ }
+
+ printf("[%d nodes]\n", getNumNodes(node_first));
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* functions for checking files and filenames */
+/* ------------------------------------------------------------------------- */
+
+boolean fileExists(char *filename)
+{
+#if 0
+ printf("checking file '%s'\n", filename);
+#endif
+
+ return (access(filename, F_OK) == 0);
+}
+
+boolean FileIsGraphic(char *filename)
+{
+ if (strlen(filename) > 4 &&
+ strcmp(&filename[strlen(filename) - 4], ".pcx") == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+boolean FileIsSound(char *basename)
+{
+ if (strlen(basename) > 4 &&
+ strcmp(&basename[strlen(basename) - 4], ".wav") == 0)
+ return TRUE;
+
+ return FALSE;
+}
+
+boolean FileIsMusic(char *basename)
+{
+ /* "music" can be a WAV (loop) file or (if compiled with SDL) a MOD file */
+
+ if (FileIsSound(basename))
+ return TRUE;
+
+#if defined(TARGET_SDL)
+ if (strlen(basename) > 4 &&
+ (strcmp(&basename[strlen(basename) - 4], ".mod") == 0 ||
+ strcmp(&basename[strlen(basename) - 4], ".MOD") == 0 ||
+ strncmp(basename, "mod.", 4) == 0 ||
+ strncmp(basename, "MOD.", 4) == 0))
+ return TRUE;
+#endif
+
+ return FALSE;
+}
+
+boolean FileIsArtworkType(char *basename, int type)
+{
+ if ((type == TREE_TYPE_GRAPHICS_DIR && FileIsGraphic(basename)) ||
(type == TREE_TYPE_SOUNDS_DIR && FileIsSound(basename)) ||
(type == TREE_TYPE_MUSIC_DIR && FileIsMusic(basename)))
return TRUE;
return FALSE;
}
+/* ------------------------------------------------------------------------- */
+/* functions for loading artwork configuration information */
+/* ------------------------------------------------------------------------- */
+
+/* This function checks if a string <s> of the format "string1, string2, ..."
+ exactly contains a string <s_contained>. */
+
+static boolean string_has_parameter(char *s, char *s_contained)
+{
+ char *substring;
+
+ if (s == NULL || s_contained == NULL)
+ return FALSE;
+
+ if (strlen(s_contained) > strlen(s))
+ return FALSE;
+
+ if (strncmp(s, s_contained, strlen(s_contained)) == 0)
+ {
+ char next_char = s[strlen(s_contained)];
+
+ /* check if next character is delimiter or whitespace */
+ return (next_char == ',' || next_char == '\0' ||
+ next_char == ' ' || next_char == '\t' ? TRUE : FALSE);
+ }
+
+ /* check if string contains another parameter string after a comma */
+ substring = strchr(s, ',');
+ if (substring == NULL) /* string does not contain a comma */
+ return FALSE;
+
+ /* advance string pointer to next character after the comma */
+ substring++;
+
+ /* skip potential whitespaces after the comma */
+ while (*substring == ' ' || *substring == '\t')
+ substring++;
+
+ return string_has_parameter(substring, s_contained);
+}
+
+int get_parameter_value(char *token, char *value_raw, int type)
+{
+ char *value = getStringToLower(value_raw);
+ int result = 0; /* probably a save default value */
+
+ if (strcmp(token, ".direction") == 0)
+ {
+ result = (strcmp(value, "left") == 0 ? MV_LEFT :
+ strcmp(value, "right") == 0 ? MV_RIGHT :
+ strcmp(value, "up") == 0 ? MV_UP :
+ strcmp(value, "down") == 0 ? MV_DOWN : MV_NO_MOVING);
+ }
+ else if (strcmp(token, ".anim_mode") == 0)
+ {
+ result = (string_has_parameter(value, "loop") ? ANIM_LOOP :
+ string_has_parameter(value, "linear") ? ANIM_LINEAR :
+ string_has_parameter(value, "pingpong") ? ANIM_PINGPONG :
+ string_has_parameter(value, "pingpong2") ? ANIM_PINGPONG2 :
+ string_has_parameter(value, "random") ? ANIM_RANDOM :
+ string_has_parameter(value, "none") ? ANIM_NONE :
+ ANIM_LOOP);
+
+ if (string_has_parameter(value, "reverse"))
+ result |= ANIM_REVERSE;
+ }
+ else /* generic parameter of type integer or boolean */
+ {
+ result = (strcmp(value, ARG_UNDEFINED) == 0 ? ARG_UNDEFINED_VALUE :
+ type == TYPE_INTEGER ? get_integer_from_string(value) :
+ type == TYPE_BOOLEAN ? get_boolean_from_string(value) :
+ ARG_UNDEFINED_VALUE);
+ }
+
+ free(value);
+
+ return result;
+}
+
+static void FreeCustomArtworkList(struct ArtworkListInfo *,
+ struct ListNodeInfo ***, int *);
+
+struct FileInfo *getFileListFromConfigList(struct ConfigInfo *config_list,
+ struct ConfigInfo *suffix_list,
+ char **ignore_tokens,
+ int num_file_list_entries)
+{
+ struct FileInfo *file_list;
+ int num_file_list_entries_found = 0;
+ int num_suffix_list_entries = 0;
+ int list_pos;
+ int i, j;
+
+ file_list = checked_calloc(num_file_list_entries * sizeof(struct FileInfo));
+
+ for (i=0; suffix_list[i].token != NULL; i++)
+ num_suffix_list_entries++;
+
+ /* always start with reliable default values */
+ for (i=0; i<num_file_list_entries; i++)
+ {
+ file_list[i].token = NULL;
+
+ file_list[i].default_filename = NULL;
+ file_list[i].filename = NULL;
+
+ if (num_suffix_list_entries > 0)
+ {
+ int parameter_array_size = num_suffix_list_entries * sizeof(char *);
+
+ file_list[i].default_parameter = checked_calloc(parameter_array_size);
+ file_list[i].parameter = checked_calloc(parameter_array_size);
+
+ for (j=0; j<num_suffix_list_entries; j++)
+ {
+ setString(&file_list[i].default_parameter[j], suffix_list[j].value);
+ setString(&file_list[i].parameter[j], suffix_list[j].value);
+ }
+ }
+ }
+
+ list_pos = 0;
+ for (i=0; config_list[i].token != NULL; i++)
+ {
+ int len_config_token = strlen(config_list[i].token);
+ int len_config_value = strlen(config_list[i].value);
+ boolean is_file_entry = TRUE;
+
+ for (j=0; suffix_list[j].token != NULL; j++)
+ {
+ int len_suffix = strlen(suffix_list[j].token);
+
+ if (len_suffix < len_config_token &&
+ strcmp(&config_list[i].token[len_config_token - len_suffix],
+ suffix_list[j].token) == 0)
+ {
+ setString(&file_list[list_pos].default_parameter[j],
+ config_list[i].value);
+
+ is_file_entry = FALSE;
+ break;
+ }
+ }
+
+ /* the following tokens are no file definitions, but other config tokens */
+ for (j=0; ignore_tokens[j] != NULL; j++)
+ if (strcmp(config_list[i].token, ignore_tokens[j]) == 0)
+ is_file_entry = FALSE;
+
+ if (is_file_entry)
+ {
+ if (i > 0)
+ list_pos++;
+
+ if (list_pos >= num_file_list_entries)
+ break;
+
+ /* simple sanity check if this is really a file definition */
+ if (strcmp(&config_list[i].value[len_config_value - 4], ".pcx") != 0 &&
+ strcmp(&config_list[i].value[len_config_value - 4], ".wav") != 0 &&
+ strcmp(config_list[i].value, UNDEFINED_FILENAME) != 0)
+ {
+ Error(ERR_RETURN, "Configuration directive '%s' -> '%s':",
+ config_list[i].token, config_list[i].value);
+ Error(ERR_EXIT, "This seems to be no valid definition -- please fix");
+ }
+
+ file_list[list_pos].token = config_list[i].token;
+ file_list[list_pos].default_filename = config_list[i].value;
+ }
+ }
+
+ num_file_list_entries_found = list_pos + 1;
+ if (num_file_list_entries_found != num_file_list_entries)
+ {
+ Error(ERR_RETURN_LINE, "-");
+ Error(ERR_RETURN, "inconsistant config list information:");
+ Error(ERR_RETURN, "- should be: %d (according to 'src/conf_gfx.h')",
+ num_file_list_entries);
+ Error(ERR_RETURN, "- found to be: %d (according to 'src/conf_gfx.c')",
+ num_file_list_entries_found);
+ Error(ERR_EXIT, "please fix");
+ }
+
+ return file_list;
+}
+
+static boolean token_suffix_match(char *token, char *suffix, int start_pos)
+{
+ int len_token = strlen(token);
+ int len_suffix = strlen(suffix);
+
+#if 0
+ if (IS_PARENT_PROCESS())
+ printf(":::::::::: check '%s' for '%s' ::::::::::\n", token, suffix);
+#endif
+
+ if (start_pos < 0) /* compare suffix from end of string */
+ start_pos += len_token;
+
+ if (start_pos < 0 || start_pos + len_suffix > len_token)
+ return FALSE;
+
+ if (strncmp(&token[start_pos], suffix, len_suffix) != 0)
+ return FALSE;
+
+ if (token[start_pos + len_suffix] == '\0')
+ return TRUE;
+
+ if (token[start_pos + len_suffix] == '.')
+ return TRUE;
+
+ return FALSE;
+}
+
+#define KNOWN_TOKEN_VALUE "[KNOWN_TOKEN]"
+
+static void read_token_parameters(SetupFileHash *setup_file_hash,
+ struct ConfigInfo *suffix_list,
+ struct FileInfo *file_list_entry)
+{
+ /* check for config token that is the base token without any suffixes */
+ char *filename = getHashEntry(setup_file_hash, file_list_entry->token);
+ char *known_token_value = KNOWN_TOKEN_VALUE;
+ int i;
+
+ if (filename != NULL)
+ {
+ setString(&file_list_entry->filename, filename);
+
+ /* when file definition found, set all parameters to default values */
+ for (i=0; suffix_list[i].token != NULL; i++)
+ setString(&file_list_entry->parameter[i], suffix_list[i].value);
+
+ file_list_entry->redefined = TRUE;
+
+ /* mark config file token as well known from default config */
+ setHashEntry(setup_file_hash, file_list_entry->token, known_token_value);
+ }
+#if 0
+ else
+ {
+ if (strcmp(file_list_entry->filename,
+ file_list_entry->default_filename) != 0)
+ printf("___ resetting '%s' to default\n", file_list_entry->token);
+
+ setString(&file_list_entry->filename, file_list_entry->default_filename);
+ }
+#endif
+
+ /* check for config tokens that can be build by base token and suffixes */
+ for (i=0; suffix_list[i].token != NULL; i++)
+ {
+ char *token = getStringCat2(file_list_entry->token, suffix_list[i].token);
+ char *value = getHashEntry(setup_file_hash, token);
+
+ if (value != NULL)
+ {
+ setString(&file_list_entry->parameter[i], value);
+
+ /* mark config file token as well known from default config */
+ setHashEntry(setup_file_hash, token, known_token_value);
+ }
+
+ free(token);
+ }
+}
+
+static void add_dynamic_file_list_entry(struct FileInfo **list,
+ int *num_list_entries,
+ SetupFileHash *extra_file_hash,
+ struct ConfigInfo *suffix_list,
+ int num_suffix_list_entries,
+ char *token)
+{
+ struct FileInfo *new_list_entry;
+ int parameter_array_size = num_suffix_list_entries * sizeof(char *);
+
+#if 0
+ if (IS_PARENT_PROCESS())
+ printf("===> found dynamic definition '%s'\n", token);
+#endif
+
+ (*num_list_entries)++;
+ *list = checked_realloc(*list, *num_list_entries * sizeof(struct FileInfo));
+ new_list_entry = &(*list)[*num_list_entries - 1];
+
+ new_list_entry->token = getStringCopy(token);
+ new_list_entry->filename = NULL;
+ new_list_entry->parameter = checked_calloc(parameter_array_size);
+
+ read_token_parameters(extra_file_hash, suffix_list, new_list_entry);
+}
+
+static void add_property_mapping(struct PropertyMapping **list,
+ int *num_list_entries,
+ int base_index, int ext1_index,
+ int ext2_index, int ext3_index,
+ int artwork_index)
+{
+ struct PropertyMapping *new_list_entry;
+
+ (*num_list_entries)++;
+ *list = checked_realloc(*list,
+ *num_list_entries * sizeof(struct PropertyMapping));
+ new_list_entry = &(*list)[*num_list_entries - 1];
+
+ new_list_entry->base_index = base_index;
+ new_list_entry->ext1_index = ext1_index;
+ new_list_entry->ext2_index = ext2_index;
+ new_list_entry->ext3_index = ext3_index;
+
+ new_list_entry->artwork_index = artwork_index;
+}
+
+static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info,
+ char *filename)
+{
+ struct FileInfo *file_list = artwork_info->file_list;
+ struct ConfigInfo *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;
+ char **ext3_suffixes = artwork_info->ext3_suffixes;
+ char **ignore_tokens = artwork_info->ignore_tokens;
+ int num_file_list_entries = artwork_info->num_file_list_entries;
+ int num_suffix_list_entries = artwork_info->num_suffix_list_entries;
+ int num_base_prefixes = artwork_info->num_base_prefixes;
+ int num_ext1_suffixes = artwork_info->num_ext1_suffixes;
+ int num_ext2_suffixes = artwork_info->num_ext2_suffixes;
+ int num_ext3_suffixes = artwork_info->num_ext3_suffixes;
+ int num_ignore_tokens = artwork_info->num_ignore_tokens;
+ SetupFileHash *setup_file_hash, *extra_file_hash;
+ char *known_token_value = KNOWN_TOKEN_VALUE;
+ int i, j, k, l;
+
+ if (filename == NULL)
+ return;
+
+#if 0
+ printf("::: LoadArtworkConfigFromFilename: '%s'\n", filename);
+#endif
+
+ if ((setup_file_hash = loadSetupFileHash(filename)) == NULL)
+ return;
+
+ /* read parameters for all known config file tokens */
+ for (i=0; i<num_file_list_entries; i++)
+ read_token_parameters(setup_file_hash, suffix_list, &file_list[i]);
+
+ /* set all tokens that can be ignored here to "known" keyword */
+ for (i=0; i < num_ignore_tokens; i++)
+ setHashEntry(setup_file_hash, ignore_tokens[i], known_token_value);
+
+ /* copy all unknown config file tokens to extra config list */
+ extra_file_hash = newSetupFileHash();
+ BEGIN_HASH_ITERATION(setup_file_hash, itr)
+ {
+ if (strcmp(HASH_ITERATION_VALUE(itr), known_token_value) != 0)
+ setHashEntry(extra_file_hash,
+ HASH_ITERATION_TOKEN(itr), HASH_ITERATION_VALUE(itr));
+ }
+ END_HASH_ITERATION(setup_file_hash, itr)
+
+ /* at this point, we do not need the config file hash anymore -- free it */
+ freeSetupFileHash(setup_file_hash);
+
+ /* now try to determine valid, dynamically defined config tokens */
+
+ BEGIN_HASH_ITERATION(extra_file_hash, itr)
+ {
+ struct FileInfo **dynamic_file_list =
+ &artwork_info->dynamic_file_list;
+ int *num_dynamic_file_list_entries =
+ &artwork_info->num_dynamic_file_list_entries;
+ struct PropertyMapping **property_mapping =
+ &artwork_info->property_mapping;
+ int *num_property_mapping_entries =
+ &artwork_info->num_property_mapping_entries;
+ int current_summarized_file_list_entry =
+ artwork_info->num_file_list_entries +
+ artwork_info->num_dynamic_file_list_entries;
+ char *token = HASH_ITERATION_TOKEN(itr);
+ int len_token = strlen(token);
+ int start_pos;
+ boolean base_prefix_found = FALSE;
+ boolean parameter_suffix_found = FALSE;
+
+ /* skip all parameter definitions (handled by read_token_parameters()) */
+ for (i=0; i < num_suffix_list_entries && !parameter_suffix_found; i++)
+ {
+ int len_suffix = strlen(suffix_list[i].token);
+
+ if (token_suffix_match(token, suffix_list[i].token, -len_suffix))
+ parameter_suffix_found = TRUE;
+ }
+
+#if 0
+ if (IS_PARENT_PROCESS())
+ {
+ if (parameter_suffix_found)
+ printf("---> skipping token '%s' (parameter token)\n", token);
+ else
+ printf("---> examining token '%s': search prefix ...\n", token);
+ }
+#endif
+
+ if (parameter_suffix_found)
+ continue;
+
+ /* ---------- step 0: search for matching base prefix ---------- */
+
+ start_pos = 0;
+ for (i=0; i<num_base_prefixes && !base_prefix_found; i++)
+ {
+ char *base_prefix = base_prefixes[i];
+ int len_base_prefix = strlen(base_prefix);
+ boolean ext1_suffix_found = FALSE;
+ boolean ext2_suffix_found = FALSE;
+ boolean ext3_suffix_found = FALSE;
+ boolean exact_match = FALSE;
+ int base_index = -1;
+ int ext1_index = -1;
+ int ext2_index = -1;
+ int ext3_index = -1;
+
+ base_prefix_found = token_suffix_match(token, base_prefix, start_pos);
+
+ if (!base_prefix_found)
+ continue;
+
+ base_index = i;
+
+ if (start_pos + len_base_prefix == len_token) /* exact match */
+ {
+ exact_match = TRUE;
+
+ add_dynamic_file_list_entry(dynamic_file_list,
+ num_dynamic_file_list_entries,
+ extra_file_hash,
+ suffix_list,
+ num_suffix_list_entries,
+ token);
+ add_property_mapping(property_mapping,
+ num_property_mapping_entries,
+ base_index, -1, -1, -1,
+ current_summarized_file_list_entry);
+ continue;
+ }
+
+#if 0
+ if (IS_PARENT_PROCESS())
+ printf("---> examining token '%s': search 1st suffix ...\n", token);
+#endif
+
+ /* ---------- step 1: search for matching first suffix ---------- */
+
+ start_pos += len_base_prefix;
+ for (j=0; j<num_ext1_suffixes && !ext1_suffix_found; j++)
+ {
+ char *ext1_suffix = ext1_suffixes[j];
+ int len_ext1_suffix = strlen(ext1_suffix);
+
+ ext1_suffix_found = token_suffix_match(token, ext1_suffix, start_pos);
+
+ if (!ext1_suffix_found)
+ continue;
+
+ ext1_index = j;
-/* ========================================================================= */
+ if (start_pos + len_ext1_suffix == len_token) /* exact match */
+ {
+ exact_match = TRUE;
+
+ add_dynamic_file_list_entry(dynamic_file_list,
+ num_dynamic_file_list_entries,
+ extra_file_hash,
+ suffix_list,
+ num_suffix_list_entries,
+ token);
+ add_property_mapping(property_mapping,
+ num_property_mapping_entries,
+ base_index, ext1_index, -1, -1,
+ current_summarized_file_list_entry);
+ continue;
+ }
+
+ start_pos += len_ext1_suffix;
+ }
+
+ if (exact_match)
+ break;
+
+#if 0
+ if (IS_PARENT_PROCESS())
+ printf("---> examining token '%s': search 2nd suffix ...\n", token);
+#endif
+
+ /* ---------- step 2: search for matching second suffix ---------- */
+
+ for (k=0; k<num_ext2_suffixes && !ext2_suffix_found; k++)
+ {
+ char *ext2_suffix = ext2_suffixes[k];
+ int len_ext2_suffix = strlen(ext2_suffix);
+
+ ext2_suffix_found = token_suffix_match(token, ext2_suffix,start_pos);
+
+ if (!ext2_suffix_found)
+ continue;
+
+ ext2_index = k;
+
+ if (start_pos + len_ext2_suffix == len_token) /* exact match */
+ {
+ exact_match = TRUE;
+
+ add_dynamic_file_list_entry(dynamic_file_list,
+ num_dynamic_file_list_entries,
+ extra_file_hash,
+ suffix_list,
+ num_suffix_list_entries,
+ token);
+ add_property_mapping(property_mapping,
+ num_property_mapping_entries,
+ base_index, ext1_index, ext2_index, -1,
+ current_summarized_file_list_entry);
+ continue;
+ }
+
+ start_pos += len_ext2_suffix;
+ }
+
+ if (exact_match)
+ break;
+
+#if 0
+ if (IS_PARENT_PROCESS())
+ printf("---> examining token '%s': search 3rd suffix ...\n",token);
+#endif
+
+ /* ---------- step 3: search for matching third suffix ---------- */
+
+ for (l=0; l<num_ext3_suffixes && !ext3_suffix_found; l++)
+ {
+ char *ext3_suffix = ext3_suffixes[l];
+ int len_ext3_suffix = strlen(ext3_suffix);
+
+ ext3_suffix_found =token_suffix_match(token,ext3_suffix,start_pos);
+
+ if (!ext3_suffix_found)
+ continue;
+
+ ext3_index = l;
+
+ if (start_pos + len_ext3_suffix == len_token) /* exact match */
+ {
+ exact_match = TRUE;
+
+ add_dynamic_file_list_entry(dynamic_file_list,
+ num_dynamic_file_list_entries,
+ extra_file_hash,
+ suffix_list,
+ num_suffix_list_entries,
+ token);
+ add_property_mapping(property_mapping,
+ num_property_mapping_entries,
+ base_index, ext1_index, ext2_index, ext3_index,
+ current_summarized_file_list_entry);
+ continue;
+ }
+ }
+ }
+ }
+ END_HASH_ITERATION(extra_file_hash, itr)
+
+ if (artwork_info->num_dynamic_file_list_entries > 0)
+ {
+ artwork_info->dynamic_artwork_list =
+ checked_calloc(artwork_info->num_dynamic_file_list_entries *
+ artwork_info->sizeof_artwork_list_entry);
+ }
+
+ if (extra_file_hash != NULL && options.verbose && IS_PARENT_PROCESS())
+ {
+ SetupFileList *setup_file_list, *list;
+ boolean dynamic_tokens_found = FALSE;
+ boolean unknown_tokens_found = FALSE;
+
+ if ((setup_file_list = loadSetupFileList(filename)) == NULL)
+ Error(ERR_EXIT, "loadSetupFileHash works, but loadSetupFileList fails");
+
+ BEGIN_HASH_ITERATION(extra_file_hash, itr)
+ {
+ if (strcmp(HASH_ITERATION_VALUE(itr), known_token_value) == 0)
+ dynamic_tokens_found = TRUE;
+ else
+ unknown_tokens_found = TRUE;
+ }
+ END_HASH_ITERATION(extra_file_hash, itr)
+
+#if DEBUG
+ if (dynamic_tokens_found)
+ {
+ Error(ERR_RETURN_LINE, "-");
+ Error(ERR_RETURN, "dynamic token(s) found in config file:");
+ Error(ERR_RETURN, "- config file: '%s'", filename);
+
+ for (list = setup_file_list; list != NULL; list = list->next)
+ {
+ char *value = getHashEntry(extra_file_hash, list->token);
+
+ if (value != NULL && strcmp(value, known_token_value) == 0)
+ Error(ERR_RETURN, "- dynamic token: '%s'", list->token);
+ }
+
+ Error(ERR_RETURN_LINE, "-");
+ }
+#endif
+
+ if (unknown_tokens_found)
+ {
+ Error(ERR_RETURN_LINE, "-");
+ Error(ERR_RETURN, "warning: unknown token(s) found in config file:");
+ Error(ERR_RETURN, "- config file: '%s'", filename);
+
+ for (list = setup_file_list; list != NULL; list = list->next)
+ {
+ char *value = getHashEntry(extra_file_hash, list->token);
+
+ if (value != NULL && strcmp(value, known_token_value) != 0)
+ Error(ERR_RETURN, "- dynamic token: '%s'", list->token);
+ }
+
+ Error(ERR_RETURN_LINE, "-");
+ }
+
+ freeSetupFileList(setup_file_list);
+ }
+
+ freeSetupFileHash(extra_file_hash);
+
+#if 0
+ for (i=0; i<num_file_list_entries; i++)
+ {
+ printf("'%s' ", file_list[i].token);
+ if (file_list[i].filename)
+ printf("-> '%s'\n", file_list[i].filename);
+ else
+ printf("-> UNDEFINED [-> '%s']\n", file_list[i].default_filename);
+ }
+#endif
+}
+
+void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
+{
+ struct FileInfo *file_list = artwork_info->file_list;
+ int num_file_list_entries = artwork_info->num_file_list_entries;
+ int num_suffix_list_entries = artwork_info->num_suffix_list_entries;
+ char *filename_base = UNDEFINED_FILENAME, *filename_local;
+ int i, j;
+
+#if 0
+ printf("GOT CUSTOM ARTWORK CONFIG FILE '%s'\n", filename);
+#endif
+
+ /* always start with reliable default values */
+ for (i=0; i<num_file_list_entries; i++)
+ {
+ setString(&file_list[i].filename, file_list[i].default_filename);
+
+ for (j=0; j<num_suffix_list_entries; j++)
+ setString(&file_list[i].parameter[j], file_list[i].default_parameter[j]);
+
+ file_list[i].redefined = FALSE;
+ }
+
+ /* free previous dynamic artwork file array */
+ if (artwork_info->dynamic_file_list != NULL)
+ {
+ for (i=0; i<artwork_info->num_dynamic_file_list_entries; i++)
+ {
+ free(artwork_info->dynamic_file_list[i].token);
+ free(artwork_info->dynamic_file_list[i].filename);
+ free(artwork_info->dynamic_file_list[i].parameter);
+ }
+
+ free(artwork_info->dynamic_file_list);
+ artwork_info->dynamic_file_list = NULL;
+
+ FreeCustomArtworkList(artwork_info, &artwork_info->dynamic_artwork_list,
+ &artwork_info->num_dynamic_file_list_entries);
+ }
+
+ /* free previous property mapping */
+ if (artwork_info->property_mapping != NULL)
+ {
+ free(artwork_info->property_mapping);
+
+ artwork_info->property_mapping = NULL;
+ artwork_info->num_property_mapping_entries = 0;
+ }
+
+ if (!SETUP_OVERRIDE_ARTWORK(setup, artwork_info->type))
+ {
+ /* first look for special artwork configured in level series config */
+ filename_base = getCustomArtworkLevelConfigFilename(artwork_info->type);
+
+ if (fileExists(filename_base))
+ LoadArtworkConfigFromFilename(artwork_info, filename_base);
+ }
+
+ filename_local = getCustomArtworkConfigFilename(artwork_info->type);
+
+ if (filename_local != NULL && strcmp(filename_base, filename_local) != 0)
+ LoadArtworkConfigFromFilename(artwork_info, filename_local);
+}
+
+static void deleteArtworkListEntry(struct ArtworkListInfo *artwork_info,
+ struct ListNodeInfo **listnode)
+{
+ if (*listnode)
+ {
+ char *filename = (*listnode)->source_filename;
+
+#if 0
+ printf("[decrementing reference counter of artwork '%s']\n", filename);
+#endif
+
+ if (--(*listnode)->num_references <= 0)
+ {
+#if 0
+ printf("[deleting artwork '%s']\n", filename);
+#endif
+
+ deleteNodeFromList(&artwork_info->content_list, filename,
+ artwork_info->free_artwork);
+ }
+
+ *listnode = NULL;
+ }
+}
+
+static void replaceArtworkListEntry(struct ArtworkListInfo *artwork_info,
+ struct ListNodeInfo **listnode,
+ char *basename)
+{
+ char *init_text[] =
+ {
+ "Loading graphics:",
+ "Loading sounds:",
+ "Loading music:"
+ };
+
+ ListNode *node;
+ char *filename = getCustomArtworkFilename(basename, artwork_info->type);
+
+ if (filename == NULL)
+ {
+ int error_mode = ERR_WARN;
+
+#if 1
+ /* 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;
+#endif
+
+ Error(error_mode, "cannot find 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
+ 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;
+ }
+}
+
+static void LoadCustomArtwork(struct ArtworkListInfo *artwork_info,
+ struct ListNodeInfo **listnode,
+ char *basename)
+{
+#if 0
+ printf("GOT CUSTOM ARTWORK FILE '%s'\n", filename);
+#endif
+
+ if (strcmp(basename, UNDEFINED_FILENAME) == 0)
+ {
+ deleteArtworkListEntry(artwork_info, listnode);
+ return;
+ }
+
+ replaceArtworkListEntry(artwork_info, listnode, basename);
+}
+
+static void LoadArtworkToList(struct ArtworkListInfo *artwork_info,
+ struct ListNodeInfo **listnode,
+ char *basename, int list_pos)
+{
+#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",
+ basename, getNumNodes(artwork_info->content_list));
+#endif
+
+#if 1
+ LoadCustomArtwork(artwork_info, listnode, basename);
+#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
+}
+
+void ReloadCustomArtworkList(struct ArtworkListInfo *artwork_info)
+{
+ struct FileInfo *file_list = artwork_info->file_list;
+ struct FileInfo *dynamic_file_list = artwork_info->dynamic_file_list;
+ int num_file_list_entries = artwork_info->num_file_list_entries;
+ int num_dynamic_file_list_entries =
+ artwork_info->num_dynamic_file_list_entries;
+ int i;
+
+#if 0
+ printf("DEBUG: reloading %d static artwork files ...\n",
+ num_file_list_entries);
+#endif
+
+ for(i=0; i<num_file_list_entries; i++)
+ {
+#if 0
+ if (strcmp(file_list[i].token, "background") == 0)
+ printf("::: '%s' -> '%s'\n", file_list[i].token, file_list[i].filename);
+#endif
+
+ LoadArtworkToList(artwork_info, &artwork_info->artwork_list[i],
+ file_list[i].filename, i);
+
+#if 0
+ if (artwork_info->artwork_list[i] == NULL &&
+ strcmp(file_list[i].default_filename, file_list[i].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);
+ }
+#endif
+ }
+
+#if 0
+ printf("DEBUG: reloading %d dynamic artwork files ...\n",
+ num_dynamic_file_list_entries);
+#endif
+
+ for(i=0; i<num_dynamic_file_list_entries; i++)
+ LoadArtworkToList(artwork_info, &artwork_info->dynamic_artwork_list[i],
+ dynamic_file_list[i].filename, i);
+
+#if 0
+ dumpList(artwork_info->content_list);
+#endif
+}
+
+static void FreeCustomArtworkList(struct ArtworkListInfo *artwork_info,
+ struct ListNodeInfo ***list,
+ int *num_list_entries)
+{
+ int i;
+
+ if (*list == NULL)
+ return;
+
+ for(i=0; i<*num_list_entries; i++)
+ deleteArtworkListEntry(artwork_info, &(*list)[i]);
+ free(*list);
+
+ *list = NULL;
+ *num_list_entries = 0;
+}
+
+void FreeCustomArtworkLists(struct ArtworkListInfo *artwork_info)
+{
+ if (artwork_info == NULL)
+ return;
+
+#if 0
+ printf("%s: FREEING ARTWORK ...\n",
+ IS_CHILD_PROCESS() ? "CHILD" : "PARENT");
+#endif
+
+ FreeCustomArtworkList(artwork_info, &artwork_info->artwork_list,
+ &artwork_info->num_file_list_entries);
+
+ FreeCustomArtworkList(artwork_info, &artwork_info->dynamic_artwork_list,
+ &artwork_info->num_dynamic_file_list_entries);
+
+#if 0
+ printf("%s: FREEING ARTWORK -- DONE\n",
+ IS_CHILD_PROCESS() ? "CHILD" : "PARENT");
+#endif
+}
+
+
+/* ------------------------------------------------------------------------- */
/* functions only needed for non-Unix (non-command-line) systems */
/* (MS-DOS only; SDL/Windows creates files "stdout.txt" and "stderr.txt") */
-/* ========================================================================= */
+/* ------------------------------------------------------------------------- */
#if defined(PLATFORM_MSDOS)
#endif
-/* ========================================================================= */
+/* ------------------------------------------------------------------------- */
/* the following is only for debugging purpose and normally not used */
-/* ========================================================================= */
+/* ------------------------------------------------------------------------- */
#define DEBUG_NUM_TIMESTAMPS 3
counter[counter_nr][1] = Counter();
}
+
+void debug_print_parent_only(char *format, ...)
+{
+ if (!IS_PARENT_PROCESS())
+ return;
+
+ if (format)
+ {
+ va_list ap;
+
+ va_start(ap, format);
+ vprintf(format, ap);
+ va_end(ap);
+
+ printf("\n");
+ }
+}
/* values for InitRND() */
#define NEW_RANDOMIZE -1
+#define InitRND(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)
+
/* values for Error() */
#define ERR_RETURN 0
-#define ERR_WARN (1 << 0)
-#define ERR_EXIT (1 << 1)
-#define ERR_HELP (1 << 2)
-#define ERR_SOUND_SERVER (1 << 3)
-#define ERR_NETWORK_SERVER (1 << 4)
-#define ERR_NETWORK_CLIENT (1 << 5)
+#define ERR_RETURN_LINE (1 << 0)
+#define ERR_WARN (1 << 1)
+#define ERR_EXIT (1 << 2)
+#define ERR_HELP (1 << 3)
+#define ERR_SOUND_SERVER (1 << 4)
+#define ERR_NETWORK_SERVER (1 << 5)
+#define ERR_NETWORK_CLIENT (1 << 6)
#define ERR_FROM_SERVER (ERR_SOUND_SERVER | ERR_NETWORK_SERVER)
#define ERR_EXIT_HELP (ERR_EXIT | ERR_HELP)
#define ERR_EXIT_SOUND_SERVER (ERR_EXIT | ERR_SOUND_SERVER)
#define BYTE_ORDER_BIG_ENDIAN 0
#define BYTE_ORDER_LITTLE_ENDIAN 1
+/* values for cursor bitmap creation */
+#define BIT_ORDER_MSB 0
+#define BIT_ORDER_LSB 1
+
/* values for createDirectory() */
#define PERMS_PRIVATE 0
#define PERMS_PUBLIC 1
/* values for general file handling stuff */
#define MAX_FILENAME_LEN 256
-#define MAX_LINE_LEN 1000
+#define MAX_LINE_LEN 1024
+
+/* values for general username handling stuff */
+#define MAX_USERNAME_LEN 1024
+
+
+void fprintf_line(FILE *, char *, int);
+void printf_line(char *, int);
+char *int2str(int, int);
void InitCounter(void);
unsigned long Counter(void);
boolean FrameReached(unsigned long *, unsigned long);
boolean DelayReached(unsigned long *, unsigned long);
void WaitUntilDelayReached(unsigned long *, unsigned long);
-char *int2str(int, int);
+
+#if 0
unsigned int SimpleRND(unsigned int);
+unsigned int InitSimpleRND(long);
unsigned int RND(unsigned int);
unsigned int InitRND(long);
+#endif
+
+unsigned int init_random_number(int, long);
+unsigned int get_random_number(int, unsigned int);
+
char *getLoginName(void);
char *getRealName(void);
char *getHomeDir(void);
+
char *getPath2(char *, char *);
char *getPath3(char *, char *, char*);
+char *getStringCat2(char *, char *);
char *getStringCopy(char *);
char *getStringToLower(char *);
+void setString(char **, char *);
void GetOptions(char **);
void *checked_malloc(unsigned long);
void *checked_calloc(unsigned long);
void *checked_realloc(void *, unsigned long);
+
inline void swap_numbers(int *, int *);
inline void swap_number_pairs(int *, int *, int *, int *);
void ReadUnusedBytesFromFile(FILE *, unsigned long);
void WriteUnusedBytesToFile(FILE *, unsigned long);
+#define getFile8Bit(f) fgetc(f)
+#define putFile8Bit(f,x) fputc(x, f)
#define getFile16BitBE(f) getFile16BitInteger(f,BYTE_ORDER_BIG_ENDIAN)
#define getFile16BitLE(f) getFile16BitInteger(f,BYTE_ORDER_LITTLE_ENDIAN)
#define putFile16BitBE(f,x) putFile16BitInteger(f,x,BYTE_ORDER_BIG_ENDIAN)
Key getKeyFromX11KeyName(char *);
char getCharFromKey(Key);
+int get_integer_from_string(char *);
+boolean get_boolean_from_string(char *);
+
+ListNode *newListNode(void);
+void addNodeToList(ListNode **, char *, void *);
+void deleteNodeFromList(ListNode **, char *, void (*function)(void *));
+ListNode *getNodeFromKey(ListNode *, char *);
+int getNumNodes(ListNode *);
+
+boolean fileExists(char *);
boolean FileIsGraphic(char *);
boolean FileIsSound(char *);
boolean FileIsMusic(char *);
boolean FileIsArtworkType(char *, int);
+int get_parameter_value(char *, char *, int);
+
+struct FileInfo *getFileListFromConfigList(struct ConfigInfo *,
+ struct ConfigInfo *, char **, int);
+void LoadArtworkConfig(struct ArtworkListInfo *);
+void ReloadCustomArtworkList(struct ArtworkListInfo *);
+void FreeCustomArtworkLists(struct ArtworkListInfo *);
+
#if !defined(PLATFORM_UNIX)
void initErrorFile();
FILE *openErrorFile();
Screen *screen;
Display *display;
BITMAP *mouse_bitmap = NULL;
- char *mouse_filename =getCustomImageFilename(program.msdos_pointer_filename);
+ char *mouse_filename = getCustomImageFilename(program.msdos_cursor_filename);
if ((mouse_bitmap = Read_PCX_to_AllegroBitmap(mouse_filename)) == NULL)
return NULL;
return getpixel((BITMAP *)d, x, y);
}
+void AllegroZoomBitmap(Drawable src, Drawable dst,
+ int src_width, int src_height,
+ int dst_width, int dst_height)
+{
+ stretch_blit((BITMAP *)src, (BITMAP *)dst,
+ 0, 0, src_width, src_height, 0, 0, dst_width, dst_height);
+}
+
void MSDOSOpenAudio(void)
{
if (allegro_init_audio())
void AllegroDrawLine(Drawable, int, int, int, int, Pixel);
Pixel AllegroGetPixel(Drawable, int, int);
+void AllegroZoomBitmap(Drawable, Drawable, int, int, int, int);
+
void MSDOSOpenAudio(void);
void MSDOSCloseAudio(void);
#include "misc.h"
-#define PCX_DEBUG FALSE
+#define PCX_DEBUG 0
#define PCX_MAGIC 0x0a /* first byte in a PCX image file */
#define PCX_SUPPORTED_VERSION 5 /* last acceptable version number */
for (y = 0; y < height; y++)
{
/* decode a scan line into a temporary buffer first */
- byte *dst_ptr = (pcx_depth == 8) ? bitmap_ptr : row_buffer;
+ byte *dst_ptr = (pcx_depth == 8 ? bitmap_ptr : row_buffer);
byte value = 0, count = 0;
int value_int;
int i;
if (count == 0)
{
if ((value_int = fgetc(file)) == EOF)
+ {
+ free(row_buffer);
return FALSE;
+ }
+
value = (byte)value_int;
if ((value & 0xc0) == 0xc0) /* this is a repeat count byte */
{
count = value & 0x3f; /* extract repeat count from byte */
+
if ((value_int = fgetc(file)) == EOF)
+ {
+ free(row_buffer);
return FALSE;
+ }
+
value = (byte)value_int;
}
else
{
int i, j, x = 0;
- for(i = 0; i < pcx->bytes_per_line; i++)
+ for (i = 0; i < pcx->bytes_per_line; i++)
{
byte value = *src_ptr++;
- for(j = 7; j >= 0; j--)
+ for (j = 7; j >= 0; j--)
{
byte bit = (value >> j) & 1;
+ if (i * 8 + j >= width) /* skip padding bits */
+ continue;
+
bitmap_ptr[x++] |= bit << plane;
}
}
byte *src_ptr = row_buffer;
int plane;
- for(plane = 0; plane < pcx->color_planes; plane++)
+ for (plane = 0; plane < pcx->color_planes; plane++)
{
int x;
dst_ptr = bitmap_ptr + plane;
- for(x = 0; x < width; x++)
+ for (x = 0; x < width; x++)
{
*dst_ptr = *src_ptr++;
dst_ptr += pcx->color_planes;
bitmap_ptr += image->bytes_per_row;
}
+ free(row_buffer);
+
return TRUE;
}
#if PCX_DEBUG
if (options.verbose)
{
+ printf("\n");
printf("%s is a %dx%d PC Paintbrush image\n", filename, width, height);
printf("depth: %d\n", depth);
printf("bits_per_pixel: %d\n", pcx.bits_per_pixel);
if (pcx_depth == 8)
{
/* determine number of used colormap entries for 8-bit PCX images */
- image->rgb.used = 0;
for (i=0; i<PCX_MAXCOLORS; i++)
if (image->rgb.color_used[i])
image->rgb.used++;
#if PCX_DEBUG
if (options.verbose)
- printf("Read_PCX_to_Image: %d colors found\n", image->rgb.used);
+ printf("Read_PCX_to_Image: %d colors in colormap\n", image->rgb.used);
#endif
return image;
position of the rear pointer is just
(MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3. */
-static long int randtbl[DEG_3 + 1] =
+static long int randtbl_0[DEG_3 + 1] =
{
TYPE_3,
-851904987, -43806228, -2029755270, 1390239686, -1912102820,
-607508183, -205999574, -1696891592, 1492211999, -1528267240,
-952028296, -189082757, 362343714, 1424981831, 2039449641,
};
+static long int randtbl_1[DEG_3 + 1] =
+{
+ TYPE_3,
+ -851904987, -43806228, -2029755270, 1390239686, -1912102820,
+ -485608943, 1969813258, -1590463333, -1944053249, 455935928, 508023712,
+ -1714531963, 1800685987, -2015299881, 654595283, -1149023258,
+ -1470005550, -1143256056, -1325577603, -1568001885, 1275120390,
+ -607508183, -205999574, -1696891592, 1492211999, -1528267240,
+ -952028296, -189082757, 362343714, 1424981831, 2039449641,
+};
+
/* FPTR and RPTR are two pointers into the state info, a front and a rear
pointer. These two pointers are always rand_sep places aparts, as they
in the initialization of randtbl) because the state table pointer is set
to point to randtbl[1] (as explained below).) */
-static long int *fptr = &randtbl[SEP_3 + 1];
-static long int *rptr = &randtbl[1];
+static long int *fptr[2] = { &randtbl_0[SEP_3 + 1], &randtbl_1[SEP_3 + 1] };
+static long int *rptr[2] = { &randtbl_0[1], &randtbl_1[1] };
indexing every time to find the address of the last element to see if
the front and rear pointers have wrapped. */
-static long int *state = &randtbl[1];
+static long int *state[2] = { &randtbl_0[1], &randtbl_1[1] };
-static int rand_type = TYPE_3;
-static int rand_deg = DEG_3;
-static int rand_sep = SEP_3;
+static int rand_type[2] = { TYPE_3, TYPE_3 };
+static int rand_deg[2] = { DEG_3, DEG_3 };
+static int rand_sep[2] = { SEP_3, SEP_3 };
-static long int *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])];
+static long int *end_ptr[2] =
+{
+ &randtbl_0[sizeof(randtbl_0) / sizeof(randtbl_0[0])],
+ &randtbl_1[sizeof(randtbl_1) / sizeof(randtbl_1[0])]
+};
/* Initialize the random number generator based on the given seed. If the
type is the trivial no-state-information type, just remember the seed.
introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
for default usage relies on values produced by this routine. */
-void srandom_linux_libc(unsigned int x)
+void srandom_linux_libc(int nr, unsigned int x)
{
- state[0] = x;
- if (rand_type != TYPE_0)
+ state[nr][0] = x;
+
+ if (rand_type[nr] != TYPE_0)
{
register long int i;
- for (i = 1; i < rand_deg; ++i)
- state[i] = (1103515145 * state[i - 1]) + 12345;
- fptr = &state[rand_sep];
- rptr = &state[0];
- for (i = 0; i < 10 * rand_deg; ++i)
- (void) random_linux_libc();
+
+ for (i = 1; i < rand_deg[nr]; ++i)
+ state[nr][i] = (1103515145 * state[nr][i - 1]) + 12345;
+
+ fptr[nr] = &state[nr][rand_sep[nr]];
+ rptr[nr] = &state[nr][0];
+
+ for (i = 0; i < 10 * rand_deg[nr]; ++i)
+ random_linux_libc(nr);
}
}
rear pointers can't wrap on the same call by not testing the rear
pointer if the front one has wrapped. Returns a 31-bit random number. */
-long int random_linux_libc()
+long int random_linux_libc(int nr)
{
- if (rand_type == TYPE_0)
+ if (rand_type[nr] == TYPE_0)
{
- state[0] = ((state[0] * 1103515245) + 12345) & LONG_MAX;
- return state[0];
+ state[nr][0] = ((state[nr][0] * 1103515245) + 12345) & LONG_MAX;
+ return state[nr][0];
}
else
{
long int i;
- *fptr += *rptr;
+
+ *fptr[nr] += *rptr[nr];
+
/* Chucking least random bit. */
- i = (*fptr >> 1) & LONG_MAX;
- ++fptr;
- if (fptr >= end_ptr)
+ i = (*fptr[nr] >> 1) & LONG_MAX;
+ fptr[nr]++;
+
+ if (fptr[nr] >= end_ptr[nr])
{
- fptr = state;
- ++rptr;
+ fptr[nr] = state[nr];
+ rptr[nr]++;
}
else
{
- ++rptr;
- if (rptr >= end_ptr)
- rptr = state;
+ rptr[nr]++;
+ if (rptr[nr] >= end_ptr[nr])
+ rptr[nr] = state[nr];
}
+
return i;
}
}
#ifndef RANDOM_H
#define RANDOM_H
-void srandom_linux_libc(unsigned int);
-long int random_linux_libc(void);
+void srandom_linux_libc(int, unsigned int);
+long int random_linux_libc(int);
#endif
/* functions from SGE library */
inline void sge_Line(SDL_Surface *, Sint16, Sint16, Sint16, Sint16, Uint32);
-#ifdef PLATFORM_WIN32
+/* #ifdef PLATFORM_WIN32 */
#define FULLSCREEN_BUG
-#endif
+/* #endif */
/* stuff needed to work around SDL/Windows fullscreen drawing bug */
static int fullscreen_width;
inline void SDLInitVideoDisplay(void)
{
+ putenv("SDL_VIDEO_CENTERED=1");
+
/* initialize SDL video */
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
Error(ERR_EXIT, "SDL_InitSubSystem() failed: %s", SDL_GetError());
return success;
}
+inline void SDLCreateBitmapContent(Bitmap *new_bitmap,
+ int width, int height, int depth)
+{
+ SDL_Surface *surface_tmp, *surface_native;
+
+ if ((surface_tmp = SDL_CreateRGBSurface(SURFACE_FLAGS, width, height, depth,
+ 0, 0, 0, 0))
+ == NULL)
+ Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError());
+
+ if ((surface_native = SDL_DisplayFormat(surface_tmp)) == NULL)
+ Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s", SDL_GetError());
+
+ SDL_FreeSurface(surface_tmp);
+
+ new_bitmap->surface = surface_native;
+}
+
+inline void SDLFreeBitmapPointers(Bitmap *bitmap)
+{
+ if (bitmap->surface)
+ SDL_FreeSurface(bitmap->surface);
+ if (bitmap->surface_masked)
+ SDL_FreeSurface(bitmap->surface_masked);
+ bitmap->surface = NULL;
+ bitmap->surface_masked = NULL;
+}
+
inline void SDLCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap,
int src_x, int src_y,
int width, int height,
- int dst_x, int dst_y, int copy_mode)
+ int dst_x, int dst_y, int mask_mode)
{
Bitmap *real_dst_bitmap = (dst_bitmap == window ? backbuffer : dst_bitmap);
SDL_Rect src_rect, dst_rect;
dst_rect.h = height;
if (src_bitmap != backbuffer || dst_bitmap != window)
- SDL_BlitSurface((copy_mode == SDLCOPYAREA_MASKED ?
+ SDL_BlitSurface((mask_mode == BLIT_MASKED ?
src_bitmap->surface_masked : src_bitmap->surface),
&src_rect, real_dst_bitmap->surface, &dst_rect);
}
inline void SDLFillRectangle(Bitmap *dst_bitmap, int x, int y,
- int width, int height, unsigned int color)
+ int width, int height, Uint32 color)
{
Bitmap *real_dst_bitmap = (dst_bitmap == window ? backbuffer : dst_bitmap);
SDL_Rect rect;
- unsigned int color_r = (color >> 16) && 0xff;
- unsigned int color_g = (color >> 8) && 0xff;
- unsigned int color_b = (color >> 0) && 0xff;
+#if 0
+ unsigned int color_r = (color >> 16) & 0xff;
+ unsigned int color_g = (color >> 8) & 0xff;
+ unsigned int color_b = (color >> 0) & 0xff;
+#endif
#ifdef FULLSCREEN_BUG
if (dst_bitmap == backbuffer || dst_bitmap == window)
rect.w = width;
rect.h = height;
+#if 1
+ SDL_FillRect(real_dst_bitmap->surface, &rect, color);
+#else
SDL_FillRect(real_dst_bitmap->surface, &rect,
SDL_MapRGB(real_dst_bitmap->surface->format,
color_r, color_g, color_b));
+#endif
if (dst_bitmap == window)
SDL_UpdateRect(backbuffer->surface, x, y, width, height);
}
inline void SDLDrawSimpleLine(Bitmap *dst_bitmap, int from_x, int from_y,
- int to_x, int to_y, unsigned int color)
+ int to_x, int to_y, Uint32 color)
{
SDL_Surface *surface = dst_bitmap->surface;
SDL_Rect rect;
+#if 0
unsigned int color_r = (color >> 16) & 0xff;
unsigned int color_g = (color >> 8) & 0xff;
unsigned int color_b = (color >> 0) & 0xff;
+#endif
if (from_x > to_x)
swap_numbers(&from_x, &to_x);
}
#endif
+#if 1
+ SDL_FillRect(surface, &rect, color);
+#else
SDL_FillRect(surface, &rect,
SDL_MapRGB(surface->format, color_r, color_g, color_b));
+#endif
}
inline void SDLDrawLine(Bitmap *dst_bitmap, int from_x, int from_y,
}
#endif
-inline Pixel SDLGetPixel(Bitmap *dst_bitmap, int x, int y)
+inline Pixel SDLGetPixel(Bitmap *src_bitmap, int x, int y)
{
- SDL_Surface *surface = dst_bitmap->surface;
+ SDL_Surface *surface = src_bitmap->surface;
#ifdef FULLSCREEN_BUG
- if (dst_bitmap == backbuffer || dst_bitmap == window)
+ if (src_bitmap == backbuffer || src_bitmap == window)
{
x += video_xoffset;
y += video_yoffset;
/* ========================================================================= */
-/* The following functions have been taken from the SGE library */
+/* The following functions were taken from the SGE library */
/* (SDL Graphics Extension Library) by Anders Lindström */
/* http://www.etek.chalmers.se/~e8cal1/sge/index.html */
/* ========================================================================= */
}
void sge_PutPixelRGB(SDL_Surface *surface, Sint16 x, Sint16 y,
- Uint8 R, Uint8 G, Uint8 B)
+ Uint8 r, Uint8 g, Uint8 b)
{
- sge_PutPixel(surface, x, y, SDL_MapRGB(surface->format, R, G, B));
+ sge_PutPixel(surface, x, y, SDL_MapRGB(surface->format, r, g, b));
}
Sint32 sge_CalcYPitch(SDL_Surface *dest, Sint16 y)
sge_Line(Surface, x1, y1, x2, y2, SDL_MapRGB(Surface->format, R, G, B));
}
+inline void SDLPutPixel(Bitmap *dst_bitmap, int x, int y, Pixel pixel)
+{
+#ifdef FULLSCREEN_BUG
+ if (dst_bitmap == backbuffer || dst_bitmap == window)
+ {
+ x += video_xoffset;
+ y += video_yoffset;
+ }
+#endif
+
+ sge_PutPixel(dst_bitmap->surface, x, y, pixel);
+}
+
+
+/*
+ -----------------------------------------------------------------------------
+ quick (no, it's slow) and dirty hack to "invert" rectangle inside SDL surface
+ -----------------------------------------------------------------------------
+*/
+
+inline void SDLInvertArea(Bitmap *bitmap, int src_x, int src_y,
+ int width, int height, Uint32 color)
+{
+ int x, y;
+
+ for (y=src_y; y < src_y + height; y++)
+ {
+ for (x=src_x; x < src_x + width; x++)
+ {
+ Uint32 pixel = SDLGetPixel(bitmap, x, y);
+
+ SDLPutPixel(bitmap, x, y, pixel == BLACK_PIXEL ? color : BLACK_PIXEL);
+ }
+ }
+}
+
+inline void SDLCopyInverseMasked(Bitmap *src_bitmap, Bitmap *dst_bitmap,
+ int src_x, int src_y, int width, int height,
+ int dst_x, int dst_y)
+{
+ int x, y;
+
+ for (y=0; y < height; y++)
+ {
+ for (x=0; x < width; x++)
+ {
+ Uint32 pixel = SDLGetPixel(src_bitmap, src_x + x, src_y + y);
+
+ if (pixel != BLACK_PIXEL)
+ SDLPutPixel(dst_bitmap, dst_x + x, dst_y + y, BLACK_PIXEL);
+ }
+ }
+}
+
+
+/* ========================================================================= */
+/* The following functions were taken from the SDL_gfx library version 2.0.3 */
+/* (Rotozoomer) by Andreas Schiffler */
+/* http://www.ferzkopp.net/Software/SDL_gfx-2.0/index.html */
+/* ========================================================================= */
+
+/*
+ -----------------------------------------------------------------------------
+ 32 bit zoomer
+
+ zoomes 32bit RGBA/ABGR 'src' surface to 'dst' surface.
+ -----------------------------------------------------------------------------
+*/
+
+typedef struct
+{
+ Uint8 r;
+ Uint8 g;
+ Uint8 b;
+ Uint8 a;
+} tColorRGBA;
+
+int zoomSurfaceRGBA(SDL_Surface *src, SDL_Surface *dst)
+{
+ int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy;
+ tColorRGBA *sp, *csp, *dp;
+ int sgap, dgap;
+
+ /* variable setup */
+ sx = (int) (65536.0 * (float) src->w / (float) dst->w);
+ sy = (int) (65536.0 * (float) src->h / (float) dst->h);
+
+ /* allocate memory for row increments */
+ sax = (int *)checked_malloc((dst->w + 1) * sizeof(Uint32));
+ say = (int *)checked_malloc((dst->h + 1) * sizeof(Uint32));
+
+ /* precalculate row increments */
+ csx = 0;
+ csax = sax;
+ for (x = 0; x <= dst->w; x++)
+ {
+ *csax = csx;
+ csax++;
+ csx &= 0xffff;
+ csx += sx;
+ }
+
+ csy = 0;
+ csay = say;
+ for (y = 0; y <= dst->h; y++)
+ {
+ *csay = csy;
+ csay++;
+ csy &= 0xffff;
+ csy += sy;
+ }
+
+ /* pointer setup */
+ sp = csp = (tColorRGBA *) src->pixels;
+ dp = (tColorRGBA *) dst->pixels;
+ sgap = src->pitch - src->w * 4;
+ dgap = dst->pitch - dst->w * 4;
+
+ csay = say;
+ for (y = 0; y < dst->h; y++)
+ {
+ sp = csp;
+ csax = sax;
+
+ for (x = 0; x < dst->w; x++)
+ {
+ /* draw */
+ *dp = *sp;
+
+ /* advance source pointers */
+ csax++;
+ sp += (*csax >> 16);
+
+ /* advance destination pointer */
+ dp++;
+ }
+
+ /* advance source pointer */
+ csay++;
+ csp = (tColorRGBA *) ((Uint8 *) csp + (*csay >> 16) * src->pitch);
+
+ /* advance destination pointers */
+ dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
+ }
+
+ free(sax);
+ free(say);
+
+ return 0;
+}
+
+/*
+ -----------------------------------------------------------------------------
+ 8 bit zoomer
+
+ zoomes 8 bit palette/Y 'src' surface to 'dst' surface
+ -----------------------------------------------------------------------------
+*/
+
+int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst)
+{
+ Uint32 x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy;
+ Uint8 *sp, *dp, *csp;
+ int dgap;
+
+ /* variable setup */
+ sx = (Uint32) (65536.0 * (float) src->w / (float) dst->w);
+ sy = (Uint32) (65536.0 * (float) src->h / (float) dst->h);
+
+ /* allocate memory for row increments */
+ sax = (Uint32 *)checked_malloc(dst->w * sizeof(Uint32));
+ say = (Uint32 *)checked_malloc(dst->h * sizeof(Uint32));
+
+ /* precalculate row increments */
+ csx = 0;
+ csax = sax;
+ for (x = 0; x < dst->w; x++)
+ {
+ csx += sx;
+ *csax = (csx >> 16);
+ csx &= 0xffff;
+ csax++;
+ }
+
+ csy = 0;
+ csay = say;
+ for (y = 0; y < dst->h; y++)
+ {
+ csy += sy;
+ *csay = (csy >> 16);
+ csy &= 0xffff;
+ csay++;
+ }
+
+ csx = 0;
+ csax = sax;
+ for (x = 0; x < dst->w; x++)
+ {
+ csx += (*csax);
+ csax++;
+ }
+
+ csy = 0;
+ csay = say;
+ for (y = 0; y < dst->h; y++)
+ {
+ csy += (*csay);
+ csay++;
+ }
+
+ /* pointer setup */
+ sp = csp = (Uint8 *) src->pixels;
+ dp = (Uint8 *) dst->pixels;
+ dgap = dst->pitch - dst->w;
+
+ /* draw */
+ csay = say;
+ for (y = 0; y < dst->h; y++)
+ {
+ csax = sax;
+ sp = csp;
+ for (x = 0; x < dst->w; x++)
+ {
+ /* draw */
+ *dp = *sp;
+
+ /* advance source pointers */
+ sp += (*csax);
+ csax++;
+
+ /* advance destination pointer */
+ dp++;
+ }
+
+ /* advance source pointer (for row) */
+ csp += ((*csay) * src->pitch);
+ csay++;
+
+ /* advance destination pointers */
+ dp += dgap;
+ }
+
+ free(sax);
+ free(say);
+
+ return 0;
+}
+
+/*
+ -----------------------------------------------------------------------------
+ zoomSurface()
+
+ Zoomes 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.
+ -----------------------------------------------------------------------------
+*/
+
+SDL_Surface *zoomSurface(SDL_Surface *src, int dst_width, int dst_height)
+{
+ SDL_Surface *zoom_src = NULL;
+ SDL_Surface *zoom_dst = NULL;
+ boolean is_converted = FALSE;
+ boolean is_32bit;
+ int i;
+
+ if (src == NULL)
+ return NULL;
+
+ /* determine if source surface is 32 bit or 8 bit */
+ is_32bit = (src->format->BitsPerPixel == 32);
+
+ if (is_32bit || src->format->BitsPerPixel == 8)
+ {
+ /* use source surface 'as is' */
+ zoom_src = src;
+ }
+ else
+ {
+ /* new source surface is 32 bit with a defined RGB ordering */
+ zoom_src = SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32,
+ 0x000000ff, 0x0000ff00, 0x00ff0000, 0);
+ SDL_BlitSurface(src, NULL, zoom_src, NULL);
+ is_32bit = TRUE;
+ is_converted = TRUE;
+ }
+
+ /* allocate surface to completely contain the zoomed surface */
+ if (is_32bit)
+ {
+ /* target surface is 32 bit with source RGBA/ABGR ordering */
+ zoom_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dst_width, dst_height, 32,
+ zoom_src->format->Rmask,
+ zoom_src->format->Gmask,
+ zoom_src->format->Bmask, 0);
+ }
+ else
+ {
+ /* target surface is 8 bit */
+ zoom_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dst_width, dst_height, 8,
+ 0, 0, 0, 0);
+ }
+
+ /* lock source surface */
+ SDL_LockSurface(zoom_src);
+
+ /* check which kind of surface we have */
+ if (is_32bit)
+ {
+ /* call the 32 bit transformation routine to do the zooming */
+ zoomSurfaceRGBA(zoom_src, zoom_dst);
+ }
+ else
+ {
+ /* copy palette */
+ for (i=0; i < zoom_src->format->palette->ncolors; i++)
+ zoom_dst->format->palette->colors[i] =
+ zoom_src->format->palette->colors[i];
+ zoom_dst->format->palette->ncolors = zoom_src->format->palette->ncolors;
+
+ /* call the 8 bit transformation routine to do the zooming */
+ zoomSurfaceY(zoom_src, zoom_dst);
+ }
+
+ /* unlock source surface */
+ SDL_UnlockSurface(zoom_src);
+
+ /* free temporary surface */
+ if (is_converted)
+ SDL_FreeSurface(zoom_src);
+
+ /* return destination surface */
+ return zoom_dst;
+}
+
+void SDLZoomBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap)
+{
+ SDL_Surface *sdl_surface_tmp;
+ int dst_width = dst_bitmap->width;
+ int dst_height = dst_bitmap->height;
+
+ /* throw away old destination surface */
+ SDL_FreeSurface(dst_bitmap->surface);
+
+ /* create zoomed temporary surface from source surface */
+ sdl_surface_tmp = zoomSurface(src_bitmap->surface, dst_width, dst_height);
+
+ /* create native format destination surface from zoomed temporary surface */
+ dst_bitmap->surface = SDL_DisplayFormat(sdl_surface_tmp);
+
+ /* free temporary surface */
+ SDL_FreeSurface(sdl_surface_tmp);
+}
+
+
+/* ========================================================================= */
+/* load image to bitmap */
+/* ========================================================================= */
+
Bitmap *SDLLoadImage(char *filename)
{
Bitmap *new_bitmap = CreateBitmapStruct();
}
+/* ------------------------------------------------------------------------- */
+/* custom cursor fuctions */
+/* ------------------------------------------------------------------------- */
+
+static SDL_Cursor *create_cursor(struct MouseCursorInfo *cursor_info)
+{
+ return SDL_CreateCursor(cursor_info->data, cursor_info->mask,
+ cursor_info->width, cursor_info->height,
+ cursor_info->hot_x, cursor_info->hot_y);
+}
+
+void SDLSetMouseCursor(struct MouseCursorInfo *cursor_info)
+{
+ static struct MouseCursorInfo *last_cursor_info = NULL;
+ static SDL_Cursor *cursor_default = NULL;
+ static SDL_Cursor *cursor_current = NULL;
+
+ if (cursor_default == NULL)
+ cursor_default = SDL_GetCursor();
+
+ if (cursor_info != NULL && cursor_info != last_cursor_info)
+ {
+ cursor_current = create_cursor(cursor_info);
+ last_cursor_info = cursor_info;
+ }
+
+ SDL_SetCursor(cursor_info ? cursor_current : cursor_default);
+}
+
+
/* ========================================================================= */
/* audio functions */
/* ========================================================================= */
inline void SDLOpenAudio(void)
{
+ if (strcmp(setup.system.sdl_audiodriver, ARG_DEFAULT) != 0)
+ putenv(getStringCat2("SDL_AUDIODRIVER=", setup.system.sdl_audiodriver));
+
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
{
Error(ERR_WARN, "SDL_InitSubSystem() failed: %s", SDL_GetError());
if (Mix_OpenAudio(DEFAULT_AUDIO_SAMPLE_RATE, MIX_DEFAULT_FORMAT,
AUDIO_NUM_CHANNELS_STEREO,
- DEFAULT_AUDIO_FRAGMENT_SIZE) < 0)
+ setup.system.audio_fragment_size) < 0)
{
Error(ERR_WARN, "Mix_OpenAudio() failed: %s", SDL_GetError());
return;
}
else if (event->type == EVENT_MOTIONNOTIFY)
{
- if (((ButtonEvent *)event)->x > video_xoffset)
- ((ButtonEvent *)event)->x -= video_xoffset;
+ if (((MotionEvent *)event)->x > video_xoffset)
+ ((MotionEvent *)event)->x -= video_xoffset;
else
- ((ButtonEvent *)event)->x = 0;
- if (((ButtonEvent *)event)->y > video_yoffset)
- ((ButtonEvent *)event)->y -= video_yoffset;
+ ((MotionEvent *)event)->x = 0;
+ if (((MotionEvent *)event)->y > video_yoffset)
+ ((MotionEvent *)event)->y -= video_yoffset;
else
- ((ButtonEvent *)event)->y = 0;
+ ((MotionEvent *)event)->y = 0;
}
#endif
}
#define SURFACE_FLAGS (SDL_SWSURFACE)
-#define SDLCOPYAREA_OPAQUE 0
-#define SDLCOPYAREA_MASKED 1
-
/* system dependent definitions */
#define TARGET_STRING "SDL"
#define FULLSCREEN_STATUS FULLSCREEN_AVAILABLE
+#define CURSOR_MAX_WIDTH 32
+#define CURSOR_MAX_HEIGHT 32
+
/* SDL type definitions */
typedef struct SDLSurfaceInfo DrawBuffer;
typedef struct SDLSurfaceInfo DrawWindow;
typedef Uint32 Pixel;
+typedef SDL_Cursor *Cursor;
typedef SDLKey Key;
+typedef unsigned int KeyMod;
typedef SDL_Event Event;
typedef SDL_MouseButtonEvent ButtonEvent;
GC stored_clip_gc;
};
+struct MouseCursorInfo
+{
+ int width, height;
+ int hot_x, hot_y;
+
+ char data[CURSOR_MAX_WIDTH * CURSOR_MAX_HEIGHT / 8];
+ char mask[CURSOR_MAX_WIDTH * CURSOR_MAX_HEIGHT / 8];
+};
+
struct XY
{
short x, y;
#define None 0L
+#define BLACK_PIXEL 0x000000
+#define WHITE_PIXEL 0xffffff
+
#define EVENT_BUTTONPRESS SDL_MOUSEBUTTONDOWN
#define EVENT_BUTTONRELEASE SDL_MOUSEBUTTONUP
#define EVENT_MOTIONNOTIFY SDL_MOUSEMOTION
#define KSYM_FKEY_LAST KSYM_F15
#define KSYM_NUM_FKEYS (KSYM_FKEY_LAST - KSYM_FKEY_FIRST + 1)
+#define KMOD_None None
+#define KMOD_Shift_L KMOD_LSHIFT
+#define KMOD_Shift_R KMOD_RSHIFT
+#define KMOD_Control_L KMOD_LCTRL
+#define KMOD_Control_R KMOD_RCTRL
+#define KMOD_Meta_L KMOD_LMETA
+#define KMOD_Meta_R KMOD_RMETA
+#define KMOD_Alt_L KMOD_LALT
+#define KMOD_Alt_R KMOD_RALT
+
+#define KMOD_Shift (KMOD_Shift_L | KMOD_Shift_R)
+#define KMOD_Control (KMOD_Control_L | KMOD_Control_R)
+#define KMOD_Meta (KMOD_Meta_L | KMOD_Meta_R)
+#define KMOD_Alt (KMOD_Alt_L | KMOD_Alt_R)
+
/* SDL function definitions */
inline void SDLInitVideoDisplay(void);
inline void SDLInitVideoBuffer(DrawBuffer **, DrawWindow **, boolean);
inline boolean SDLSetVideoMode(DrawBuffer **, boolean);
+inline void SDLCreateBitmapContent(Bitmap *, int, int, int);
+inline void SDLFreeBitmapPointers(Bitmap *);
inline void SDLCopyArea(Bitmap *, Bitmap *, int, int, int, int, int, int, int);
-inline void SDLFillRectangle(Bitmap *, int, int, int, int, unsigned int);
-inline void SDLDrawSimpleLine(Bitmap *, int, int, int, int, unsigned int);
+inline void SDLFillRectangle(Bitmap *, int, int, int, int, Uint32);
+inline void SDLDrawSimpleLine(Bitmap *, int, int, int, int, Uint32);
inline void SDLDrawLine(Bitmap *, int, int, int, int, Uint32);
inline Pixel SDLGetPixel(Bitmap *, int, int);
+inline void SDLPutPixel(Bitmap *, int, int, Pixel);
+
+inline void SDLInvertArea(Bitmap *, int, int, int, int, Uint32);
+inline void SDLCopyInverseMasked(Bitmap *, Bitmap *, int, int, int, int,
+ int, int);
+
+void SDLZoomBitmap(Bitmap *, Bitmap *);
Bitmap *SDLLoadImage(char *);
+void SDLSetMouseCursor(struct MouseCursorInfo *);
+
inline void SDLOpenAudio(void);
inline void SDLCloseAudio(void);
#include "joystick.h"
#include "text.h"
#include "misc.h"
+#include "hash.h"
/* file names and filename extensions */
#if !defined(PLATFORM_MSDOS)
#define MAX_COOKIE_LEN 256
-#define ARTWORKINFO_FILENAME(type) ((type) == TREE_TYPE_GRAPHICS_DIR ? \
- GRAPHICSINFO_FILENAME : \
- (type) == TREE_TYPE_SOUNDS_DIR ? \
- SOUNDSINFO_FILENAME : \
- (type) == TREE_TYPE_MUSIC_DIR ? \
+#define ARTWORKINFO_FILENAME(type) ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ GRAPHICSINFO_FILENAME : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ SOUNDSINFO_FILENAME : \
+ (type) == ARTWORK_TYPE_MUSIC ? \
MUSICINFO_FILENAME : "")
-#define ARTWORK_DIRECTORY(type) ((type) == TREE_TYPE_GRAPHICS_DIR ? \
- GRAPHICS_DIRECTORY : \
- (type) == TREE_TYPE_SOUNDS_DIR ? \
- SOUNDS_DIRECTORY : \
- (type) == TREE_TYPE_MUSIC_DIR ? \
+#define ARTWORK_DIRECTORY(type) ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ GRAPHICS_DIRECTORY : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ SOUNDS_DIRECTORY : \
+ (type) == ARTWORK_TYPE_MUSIC ? \
MUSIC_DIRECTORY : "")
-#define OPTIONS_ARTWORK_DIRECTORY(type) ((type) == TREE_TYPE_GRAPHICS_DIR ? \
- options.graphics_directory : \
- (type) == TREE_TYPE_SOUNDS_DIR ? \
- options.sounds_directory : \
- (type) == TREE_TYPE_MUSIC_DIR ? \
+#define OPTIONS_ARTWORK_DIRECTORY(type) ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ options.graphics_directory : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ options.sounds_directory : \
+ (type) == ARTWORK_TYPE_MUSIC ? \
options.music_directory : "")
static char *getScoreDir(char *level_subdir)
{
static char *score_dir = NULL;
- char *data_dir = options.rw_base_directory;
+ char *data_dir = getCommonDataDir();
char *score_subdir = SCORES_DIRECTORY;
if (score_dir)
return music_dir;
}
+static char *getDefaultArtworkSet(int type)
+{
+ return (type == TREE_TYPE_GRAPHICS_DIR ? GRAPHICS_SUBDIR :
+ type == TREE_TYPE_SOUNDS_DIR ? SOUNDS_SUBDIR :
+ type == TREE_TYPE_MUSIC_DIR ? MUSIC_SUBDIR : "");
+}
+
+static char *getDefaultArtworkDir(int type)
+{
+ return (type == TREE_TYPE_GRAPHICS_DIR ?
+ getDefaultGraphicsDir(GRAPHICS_SUBDIR) :
+ type == TREE_TYPE_SOUNDS_DIR ?
+ getDefaultSoundsDir(SOUNDS_SUBDIR) :
+ type == TREE_TYPE_MUSIC_DIR ?
+ getDefaultMusicDir(MUSIC_SUBDIR) : "");
+}
+
static char *getUserGraphicsDir()
{
static char *usergraphics_dir = NULL;
return usermusic_dir;
}
+static char *getSetupArtworkDir(TreeInfo *ti)
+{
+ static char *artwork_dir = NULL;
+
+ if (artwork_dir != NULL)
+ free(artwork_dir);
+
+ artwork_dir = getPath2(ti->basepath, ti->fullpath);
+
+ return artwork_dir;
+}
+
+void setLevelArtworkDir(TreeInfo *ti)
+{
+ char **artwork_path_ptr, **artwork_set_ptr;
+ TreeInfo *level_artwork;
+
+ if (ti == NULL || leveldir_current == NULL)
+ return;
+
+ artwork_path_ptr = &(LEVELDIR_ARTWORK_PATH(leveldir_current, ti->type));
+ artwork_set_ptr = &(LEVELDIR_ARTWORK_SET( leveldir_current, ti->type));
+
+ if (*artwork_path_ptr != NULL)
+ free(*artwork_path_ptr);
+
+ if ((level_artwork = getTreeInfoFromIdentifier(ti, *artwork_set_ptr)))
+ *artwork_path_ptr = getStringCopy(getSetupArtworkDir(level_artwork));
+ else
+ {
+ /* No (or non-existing) artwork configured in "levelinfo.conf". This would
+ normally result in using the artwork configured in the setup menu. But
+ if an artwork subdirectory exists (which might contain custom artwork
+ or an artwork configuration file), this level artwork must be treated
+ as relative to the default "classic" artwork, not to the artwork that
+ is currently configured in the setup menu. */
+
+ char *dir = getPath2(getCurrentLevelDir(), ARTWORK_DIRECTORY(ti->type));
+
+ if (*artwork_set_ptr != NULL)
+ free(*artwork_set_ptr);
+
+ if (fileExists(dir))
+ {
+ *artwork_path_ptr = getStringCopy(getDefaultArtworkDir(ti->type));
+ *artwork_set_ptr = getStringCopy(getDefaultArtworkSet(ti->type));
+ }
+ else
+ {
+ *artwork_path_ptr = getStringCopy(UNDEFINED_FILENAME);
+ *artwork_set_ptr = NULL;
+ }
+
+ free(dir);
+ }
+}
+
+inline static char *getLevelArtworkSet(int type)
+{
+ if (leveldir_current == NULL)
+ return NULL;
+
+ return LEVELDIR_ARTWORK_SET(leveldir_current, type);
+}
+
+inline static char *getLevelArtworkDir(int type)
+{
+ if (leveldir_current == NULL)
+ return UNDEFINED_FILENAME;
+
+ return LEVELDIR_ARTWORK_PATH(leveldir_current, type);
+}
+
char *getLevelFilename(int nr)
{
static char *filename = NULL;
if (filename != NULL)
free(filename);
- sprintf(basename, "%03d.%s", nr, LEVELFILE_EXTENSION);
+ if (nr < 0)
+ sprintf(basename, "template.%s", LEVELFILE_EXTENSION);
+ else
+ sprintf(basename, "%03d.%s", nr, LEVELFILE_EXTENSION);
+
filename = getPath2(getCurrentLevelDir(), basename);
return filename;
return filename;
}
-static char *getSetupArtworkDir(TreeInfo *ti)
-{
- static char *artwork_dir = NULL;
-
- if (artwork_dir != NULL)
- free(artwork_dir);
-
- artwork_dir = getPath2(ti->basepath, ti->fullpath);
-
- return artwork_dir;
-}
-
static char *getCorrectedImageBasename(char *basename)
{
- char *result = basename;
+ char *basename_corrected = basename;
#if defined(PLATFORM_MSDOS)
if (program.filename_prefix != NULL)
int prefix_len = strlen(program.filename_prefix);
if (strncmp(basename, program.filename_prefix, prefix_len) == 0)
- result = &basename[prefix_len];
- }
-#endif
+ basename_corrected = &basename[prefix_len];
- return result;
-}
+ /* if corrected filename is still longer than standard MS-DOS filename
+ size (8 characters + 1 dot + 3 characters file extension), shorten
+ filename by writing file extension after 8th basename character */
+ if (strlen(basename_corrected) > 8+1+3)
+ {
+ static char *msdos_filename = NULL;
-static boolean fileExists(char *filename)
-{
-#if 0
- printf("checking file '%s'\n", filename);
+ if (msdos_filename != NULL)
+ free(msdos_filename);
+
+ msdos_filename = getStringCopy(basename_corrected);
+ strncpy(&msdos_filename[8], &basename[strlen(basename) - 1+3], 1+3 + 1);
+ }
+ }
#endif
- return (access(filename, F_OK) == 0);
+ return basename_corrected;
}
char *getCustomImageFilename(char *basename)
{
static char *filename = NULL;
+ boolean skip_setup_artwork = FALSE;
if (filename != NULL)
free(filename);
filename = getPath3(getCurrentLevelDir(), GRAPHICS_DIRECTORY, basename);
if (fileExists(filename))
return filename;
+
+ free(filename);
+
+ /* check if there is special artwork configured in level series config */
+ if (getLevelArtworkSet(ARTWORK_TYPE_GRAPHICS) != NULL)
+ {
+ /* 2nd try: look for special artwork configured in level series config */
+ filename = getPath2(getLevelArtworkDir(ARTWORK_TYPE_GRAPHICS), basename);
+ if (fileExists(filename))
+ return filename;
+
+ free(filename);
+
+ /* take missing artwork configured in level set config from default */
+ skip_setup_artwork = TRUE;
+ }
}
- /* 2nd try: look for special artwork in configured artwork directory */
- filename = getPath2(getSetupArtworkDir(artwork.gfx_current), basename);
- if (fileExists(filename))
- return filename;
+ if (!skip_setup_artwork)
+ {
+ /* 3rd try: look for special artwork in configured artwork directory */
+ filename = getPath2(getSetupArtworkDir(artwork.gfx_current), basename);
+ if (fileExists(filename))
+ return filename;
+
+ free(filename);
+ }
- /* 3rd try: look for default artwork in new default artwork directory */
+ /* 4th try: look for default artwork in new default artwork directory */
filename = getPath2(getDefaultGraphicsDir(GRAPHICS_SUBDIR), basename);
if (fileExists(filename))
return filename;
- /* 4th try: look for default artwork in old default artwork directory */
+ free(filename);
+
+ /* 5th try: look for default artwork in old default artwork directory */
filename = getPath2(options.graphics_directory, basename);
if (fileExists(filename))
return filename;
char *getCustomSoundFilename(char *basename)
{
static char *filename = NULL;
+ boolean skip_setup_artwork = FALSE;
if (filename != NULL)
free(filename);
filename = getPath3(getCurrentLevelDir(), SOUNDS_DIRECTORY, basename);
if (fileExists(filename))
return filename;
+
+ free(filename);
+
+ /* check if there is special artwork configured in level series config */
+ if (getLevelArtworkSet(ARTWORK_TYPE_SOUNDS) != NULL)
+ {
+ /* 2nd try: look for special artwork configured in level series config */
+ filename = getPath2(getLevelArtworkDir(TREE_TYPE_SOUNDS_DIR), basename);
+ if (fileExists(filename))
+ return filename;
+
+ free(filename);
+
+ /* take missing artwork configured in level set config from default */
+ skip_setup_artwork = TRUE;
+ }
}
- /* 2nd try: look for special artwork in configured artwork directory */
- filename = getPath2(getSetupArtworkDir(artwork.snd_current), basename);
- if (fileExists(filename))
- return filename;
+ if (!skip_setup_artwork)
+ {
+ /* 3rd try: look for special artwork in configured artwork directory */
+ filename = getPath2(getSetupArtworkDir(artwork.snd_current), basename);
+ if (fileExists(filename))
+ return filename;
- /* 3rd try: look for default artwork in new default artwork directory */
+ free(filename);
+ }
+
+ /* 4th try: look for default artwork in new default artwork directory */
filename = getPath2(getDefaultSoundsDir(SOUNDS_SUBDIR), basename);
if (fileExists(filename))
return filename;
- /* 4th try: look for default artwork in old default artwork directory */
+ free(filename);
+
+ /* 5th try: look for default artwork in old default artwork directory */
filename = getPath2(options.sounds_directory, basename);
if (fileExists(filename))
return filename;
return NULL; /* cannot find specified artwork file anywhere */
}
-char *getCustomSoundConfigFilename()
+char *getCustomArtworkFilename(char *basename, int type)
+{
+ if (type == ARTWORK_TYPE_GRAPHICS)
+ return getCustomImageFilename(basename);
+ else if (type == ARTWORK_TYPE_SOUNDS)
+ return getCustomSoundFilename(basename);
+ else
+ return UNDEFINED_FILENAME;
+}
+
+char *getCustomArtworkConfigFilename(int type)
{
- return getCustomSoundFilename(SOUNDSINFO_FILENAME);
+ return getCustomArtworkFilename(ARTWORKINFO_FILENAME(type), type);
+}
+
+char *getCustomArtworkLevelConfigFilename(int type)
+{
+ static char *filename = NULL;
+
+ if (filename != NULL)
+ free(filename);
+
+ filename = getPath2(getLevelArtworkDir(type), ARTWORKINFO_FILENAME(type));
+
+ return filename;
}
char *getCustomMusicDirectory(void)
{
static char *directory = NULL;
+ boolean skip_setup_artwork = FALSE;
if (directory != NULL)
free(directory);
directory = getPath2(getCurrentLevelDir(), MUSIC_DIRECTORY);
if (fileExists(directory))
return directory;
+
+ free(directory);
+
+ /* check if there is special artwork configured in level series config */
+ if (getLevelArtworkSet(ARTWORK_TYPE_MUSIC) != NULL)
+ {
+ /* 2nd try: look for special artwork configured in level series config */
+ directory = getStringCopy(getLevelArtworkDir(TREE_TYPE_MUSIC_DIR));
+ if (fileExists(directory))
+ return directory;
+
+ free(directory);
+
+ /* take missing artwork configured in level set config from default */
+ skip_setup_artwork = TRUE;
+ }
}
- /* 2nd try: look for special artwork in configured artwork directory */
- directory = getStringCopy(getSetupArtworkDir(artwork.mus_current));
- if (fileExists(directory))
- return directory;
+ if (!skip_setup_artwork)
+ {
+ /* 3rd try: look for special artwork in configured artwork directory */
+ directory = getStringCopy(getSetupArtworkDir(artwork.mus_current));
+ if (fileExists(directory))
+ return directory;
+
+ free(directory);
+ }
- /* 3rd try: look for default artwork in new default artwork directory */
+ /* 4th try: look for default artwork in new default artwork directory */
directory = getStringCopy(getDefaultMusicDir(MUSIC_SUBDIR));
if (fileExists(directory))
return directory;
- /* 4th try: look for default artwork in old default artwork directory */
+ free(directory);
+
+ /* 5th try: look for default artwork in old default artwork directory */
directory = getStringCopy(options.music_directory);
if (fileExists(directory))
return directory;
void InitScoreDirectory(char *level_subdir)
{
+ createDirectory(getCommonDataDir(), "common data", PERMS_PUBLIC);
createDirectory(getScoreDir(NULL), "main score", PERMS_PUBLIC);
createDirectory(getScoreDir(level_subdir), "level score", PERMS_PUBLIC);
}
return node_default;
}
-TreeInfo *getTreeInfoFromFilenameExt(TreeInfo *node, char *filename)
+TreeInfo *getTreeInfoFromIdentifier(TreeInfo *node, char *identifier)
{
- if (filename == NULL)
+ if (identifier == NULL)
return NULL;
while (node)
{
TreeInfo *node_group;
- node_group = getTreeInfoFromFilenameExt(node->node_group, filename);
+ node_group = getTreeInfoFromIdentifier(node->node_group, identifier);
if (node_group)
return node_group;
}
else if (!node->parent_link)
{
- if (strcmp(filename, node->filename) == 0)
- return node;
-
- /* special case when looking for level series artwork:
- node->name_short contains level series filename */
- if (strcmp(node->filename, ".") == 0 &&
- strcmp(filename, node->name_short) == 0)
+ if (strcmp(identifier, node->identifier) == 0)
return node;
}
return NULL;
}
-TreeInfo *getTreeInfoFromFilename(TreeInfo *ti, char *filename)
-{
- return getTreeInfoFromFilenameExt(ti, filename);
-}
-
void dumpTreeInfo(TreeInfo *node, int depth)
{
int i;
printf(" ");
printf("filename == '%s' (%s) [%s] (%d)\n",
- node->filename, node->name, node->name_short, node->sort_priority);
+ node->filename, node->name, node->identifier, node->sort_priority);
if (node->node_group != NULL)
dumpTreeInfo(node->node_group, depth + 1);
{
static char *userdata_dir = NULL;
- if (!userdata_dir)
+ if (userdata_dir == NULL)
+ userdata_dir = getPath2(getHomeDir(), program.userdata_directory);
+
+ return userdata_dir;
+}
+
+char *getCommonDataDir(void)
+{
+ static char *common_data_dir = NULL;
+
+#if defined(PLATFORM_WIN32)
+ if (common_data_dir == NULL)
{
- char *home_dir = getHomeDir();
- char *data_dir = program.userdata_directory;
+ char *dir = checked_malloc(MAX_PATH + 1);
- userdata_dir = getPath2(home_dir, data_dir);
+ if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS, NULL, 0, dir))
+ && strcmp(dir, "") != 0) /* empty for Windows 95/98 */
+ common_data_dir = getPath2(dir, program.userdata_directory);
+ else
+ common_data_dir = options.rw_base_directory;
}
+#else
+ if (common_data_dir == NULL)
+ common_data_dir = options.rw_base_directory;
+#endif
- return userdata_dir;
+ return common_data_dir;
}
char *getSetupDir()
}
/* ------------------------------------------------------------------------- */
-/* setup file list handling functions */
+/* setup file list and hash handling functions */
/* ------------------------------------------------------------------------- */
-int get_string_integer_value(char *s)
+char *getFormattedSetupEntry(char *token, char *value)
{
- static char *number_text[][3] =
- {
- { "0", "zero", "null", },
- { "1", "one", "first" },
- { "2", "two", "second" },
- { "3", "three", "third" },
- { "4", "four", "fourth" },
- { "5", "five", "fifth" },
- { "6", "six", "sixth" },
- { "7", "seven", "seventh" },
- { "8", "eight", "eighth" },
- { "9", "nine", "ninth" },
- { "10", "ten", "tenth" },
- { "11", "eleven", "eleventh" },
- { "12", "twelve", "twelfth" },
- };
+ int i;
+ static char entry[MAX_LINE_LEN];
+
+ /* start with the token and some spaces to format output line */
+ sprintf(entry, "%s:", token);
+ for (i=strlen(entry); i<TOKEN_VALUE_POSITION; i++)
+ strcat(entry, " ");
+
+ /* continue with the token's value */
+ strcat(entry, value);
- int i, j;
- char *s_lower = getStringToLower(s);
- int result = -1;
+ return entry;
+}
- for (i=0; i<13; i++)
- for (j=0; j<3; j++)
- if (strcmp(s_lower, number_text[i][j]) == 0)
- result = i;
+SetupFileList *newSetupFileList(char *token, char *value)
+{
+ SetupFileList *new = checked_malloc(sizeof(SetupFileList));
- if (result == -1)
- result = atoi(s);
+ new->token = getStringCopy(token);
+ new->value = getStringCopy(value);
- free(s_lower);
+ new->next = NULL;
- return result;
+ return new;
}
-boolean get_string_boolean_value(char *s)
+void freeSetupFileList(SetupFileList *list)
{
- char *s_lower = getStringToLower(s);
- boolean result = FALSE;
+ if (list == NULL)
+ return;
- if (strcmp(s_lower, "true") == 0 ||
- strcmp(s_lower, "yes") == 0 ||
- strcmp(s_lower, "on") == 0 ||
- get_string_integer_value(s) == 1)
- result = TRUE;
+ if (list->token)
+ free(list->token);
+ if (list->value)
+ free(list->value);
+ if (list->next)
+ freeSetupFileList(list->next);
+ free(list);
+}
- free(s_lower);
+char *getListEntry(SetupFileList *list, char *token)
+{
+ if (list == NULL)
+ return NULL;
- return result;
+ if (strcmp(list->token, token) == 0)
+ return list->value;
+ else
+ return getListEntry(list->next, token);
}
-char *getFormattedSetupEntry(char *token, char *value)
+void setListEntry(SetupFileList *list, char *token, char *value)
{
- int i;
- static char entry[MAX_LINE_LEN];
-
- /* start with the token and some spaces to format output line */
- sprintf(entry, "%s:", token);
- for (i=strlen(entry); i<TOKEN_VALUE_POSITION; i++)
- strcat(entry, " ");
+ if (list == NULL)
+ return;
- /* continue with the token's value */
- strcat(entry, value);
+ if (strcmp(list->token, token) == 0)
+ {
+ if (list->value)
+ free(list->value);
- return entry;
+ list->value = getStringCopy(value);
+ }
+ else if (list->next == NULL)
+ list->next = newSetupFileList(token, value);
+ else
+ setListEntry(list->next, token, value);
}
-void freeSetupFileList(struct SetupFileList *setup_file_list)
+#ifdef DEBUG
+static void printSetupFileList(SetupFileList *list)
{
- if (!setup_file_list)
+ if (!list)
return;
- if (setup_file_list->token)
- free(setup_file_list->token);
- if (setup_file_list->value)
- free(setup_file_list->value);
- if (setup_file_list->next)
- freeSetupFileList(setup_file_list->next);
- free(setup_file_list);
+ printf("token: '%s'\n", list->token);
+ printf("value: '%s'\n", list->value);
+
+ printSetupFileList(list->next);
}
+#endif
+
+#ifdef DEBUG
+DEFINE_HASHTABLE_INSERT(insert_hash_entry, char, char);
+DEFINE_HASHTABLE_SEARCH(search_hash_entry, char, char);
+DEFINE_HASHTABLE_CHANGE(change_hash_entry, char, char);
+DEFINE_HASHTABLE_REMOVE(remove_hash_entry, char, char);
+#else
+#define insert_hash_entry hashtable_insert
+#define search_hash_entry hashtable_search
+#define change_hash_entry hashtable_change
+#define remove_hash_entry hashtable_remove
+#endif
-static struct SetupFileList *newSetupFileList(char *token, char *value)
+static unsigned int get_hash_from_key(void *key)
{
- struct SetupFileList *new = checked_malloc(sizeof(struct SetupFileList));
+ /*
+ djb2
- new->token = checked_malloc(strlen(token) + 1);
- strcpy(new->token, token);
+ This algorithm (k=33) was first reported by Dan Bernstein many years ago in
+ 'comp.lang.c'. Another version of this algorithm (now favored by Bernstein)
+ uses XOR: hash(i) = hash(i - 1) * 33 ^ str[i]; the magic of number 33 (why
+ it works better than many other constants, prime or not) has never been
+ adequately explained.
- new->value = checked_malloc(strlen(value) + 1);
- strcpy(new->value, value);
+ If you just want to have a good hash function, and cannot wait, djb2
+ is one of the best string hash functions i know. It has excellent
+ distribution and speed on many different sets of keys and table sizes.
+ You are not likely to do better with one of the "well known" functions
+ such as PJW, K&R, etc.
- new->next = NULL;
+ Ozan (oz) Yigit [http://www.cs.yorku.ca/~oz/hash.html]
+ */
- return new;
+ char *str = (char *)key;
+ unsigned int hash = 5381;
+ int c;
+
+ while ((c = *str++))
+ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+
+ return hash;
}
-char *getTokenValue(struct SetupFileList *setup_file_list, char *token)
+static int keys_are_equal(void *key1, void *key2)
{
- if (!setup_file_list)
- return NULL;
+ return (strcmp((char *)key1, (char *)key2) == 0);
+}
- if (strcmp(setup_file_list->token, token) == 0)
- return setup_file_list->value;
- else
- return getTokenValue(setup_file_list->next, token);
+SetupFileHash *newSetupFileHash()
+{
+ SetupFileHash *new_hash =
+ create_hashtable(16, 0.75, get_hash_from_key, keys_are_equal);
+
+ return new_hash;
}
-static void setTokenValue(struct SetupFileList *setup_file_list,
- char *token, char *value)
+void freeSetupFileHash(SetupFileHash *hash)
{
- if (!setup_file_list)
+ if (hash == NULL)
return;
- if (strcmp(setup_file_list->token, token) == 0)
- {
- free(setup_file_list->value);
- setup_file_list->value = checked_malloc(strlen(value) + 1);
- strcpy(setup_file_list->value, value);
- }
- else if (setup_file_list->next == NULL)
- setup_file_list->next = newSetupFileList(token, value);
- else
- setTokenValue(setup_file_list->next, token, value);
+ hashtable_destroy(hash, 1); /* 1 == also free values stored in hash */
}
-#ifdef DEBUG
-static void printSetupFileList(struct SetupFileList *setup_file_list)
+char *getHashEntry(SetupFileHash *hash, char *token)
+{
+ if (hash == NULL)
+ return NULL;
+
+ return search_hash_entry(hash, token);
+}
+
+void setHashEntry(SetupFileHash *hash, char *token, char *value)
{
- if (!setup_file_list)
+ char *value_copy;
+
+ if (hash == NULL)
return;
- printf("token: '%s'\n", setup_file_list->token);
- printf("value: '%s'\n", setup_file_list->value);
+ value_copy = getStringCopy(value);
- printSetupFileList(setup_file_list->next);
+ /* change value; if it does not exist, insert it as new */
+ if (!change_hash_entry(hash, token, value_copy))
+ if (!insert_hash_entry(hash, getStringCopy(token), value_copy))
+ Error(ERR_EXIT, "cannot insert into hash -- aborting");
+}
+
+#if 0
+#ifdef DEBUG
+static void printSetupFileHash(SetupFileHash *hash)
+{
+ BEGIN_HASH_ITERATION(hash, itr)
+ {
+ printf("token: '%s'\n", HASH_ITERATION_TOKEN(itr));
+ printf("value: '%s'\n", HASH_ITERATION_VALUE(itr));
+ }
+ END_HASH_ITERATION(hash, itr)
}
#endif
+#endif
-struct SetupFileList *loadSetupFileList(char *filename)
+static void *loadSetupFileData(char *filename, boolean use_hash)
{
int line_len;
char line[MAX_LINE_LEN];
char *token, *value, *line_ptr;
- struct SetupFileList *setup_file_list = newSetupFileList("", "");
- struct SetupFileList *first_valid_list_entry;
-
+ void *setup_file_data;
FILE *file;
+ if (use_hash)
+ setup_file_data = newSetupFileHash();
+ else
+ setup_file_data = newSetupFileList("", "");
+
if (!(file = fopen(filename, MODE_READ)))
{
Error(ERR_WARN, "cannot open configuration file '%s'", filename);
break;
if (*token && *value)
- setTokenValue(setup_file_list, token, value);
+ {
+ if (use_hash)
+ setHashEntry((SetupFileHash *)setup_file_data, token, value);
+ else
+ setListEntry((SetupFileList *)setup_file_data, token, value);
+ }
}
fclose(file);
- first_valid_list_entry = setup_file_list->next;
+ if (use_hash)
+ {
+ if (hashtable_count((SetupFileHash *)setup_file_data) == 0)
+ Error(ERR_WARN, "configuration file '%s' is empty", filename);
+ }
+ else
+ {
+ SetupFileList *setup_file_list = (SetupFileList *)setup_file_data;
+ SetupFileList *first_valid_list_entry = setup_file_list->next;
- /* free empty list header */
- setup_file_list->next = NULL;
- freeSetupFileList(setup_file_list);
+ /* free empty list header */
+ setup_file_list->next = NULL;
+ freeSetupFileList(setup_file_list);
+ setup_file_data = first_valid_list_entry;
- if (first_valid_list_entry == NULL)
- Error(ERR_WARN, "configuration file '%s' is empty", filename);
+ if (first_valid_list_entry == NULL)
+ Error(ERR_WARN, "configuration file '%s' is empty", filename);
+ }
- return first_valid_list_entry;
+ return setup_file_data;
}
-void checkSetupFileListIdentifier(struct SetupFileList *setup_file_list,
- char *identifier)
+SetupFileList *loadSetupFileList(char *filename)
{
- if (!setup_file_list)
- return;
+ return (SetupFileList *)loadSetupFileData(filename, FALSE);
+}
- if (strcmp(setup_file_list->token, TOKEN_STR_FILE_IDENTIFIER) == 0)
- {
- if (!checkCookieString(setup_file_list->value, identifier))
- {
- Error(ERR_WARN, "configuration file has wrong file identifier");
- return;
- }
- else
- return;
- }
+SetupFileHash *loadSetupFileHash(char *filename)
+{
+ return (SetupFileHash *)loadSetupFileData(filename, TRUE);
+}
- if (setup_file_list->next)
- checkSetupFileListIdentifier(setup_file_list->next, identifier);
- else
- {
+void checkSetupFileHashIdentifier(SetupFileHash *setup_file_hash,
+ char *identifier)
+{
+ char *value = getHashEntry(setup_file_hash, TOKEN_STR_FILE_IDENTIFIER);
+
+ if (value == NULL)
Error(ERR_WARN, "configuration file has no file identifier");
- return;
- }
+ else if (!checkCookieString(value, identifier))
+ Error(ERR_WARN, "configuration file has wrong file identifier");
}
#define TOKEN_STR_HANDICAP_LEVEL "handicap_level"
/* level directory info */
-#define LEVELINFO_TOKEN_NAME 0
-#define LEVELINFO_TOKEN_NAME_SHORT 1
+#define LEVELINFO_TOKEN_IDENTIFIER 0
+#define LEVELINFO_TOKEN_NAME 1
#define LEVELINFO_TOKEN_NAME_SORTING 2
#define LEVELINFO_TOKEN_AUTHOR 3
#define LEVELINFO_TOKEN_IMPORTED_FROM 4
#define LEVELINFO_TOKEN_SORT_PRIORITY 7
#define LEVELINFO_TOKEN_LEVEL_GROUP 8
#define LEVELINFO_TOKEN_READONLY 9
+#define LEVELINFO_TOKEN_GRAPHICS_SET 10
+#define LEVELINFO_TOKEN_SOUNDS_SET 11
+#define LEVELINFO_TOKEN_MUSIC_SET 12
-#define NUM_LEVELINFO_TOKENS 10
+#define NUM_LEVELINFO_TOKENS 13
static LevelDirTree ldi;
static struct TokenInfo levelinfo_tokens[] =
{
/* level directory info */
+ { TYPE_STRING, &ldi.identifier, "identifier" },
{ TYPE_STRING, &ldi.name, "name" },
- { TYPE_STRING, &ldi.name_short, "name_short" },
{ TYPE_STRING, &ldi.name_sorting, "name_sorting" },
{ TYPE_STRING, &ldi.author, "author" },
{ TYPE_STRING, &ldi.imported_from, "imported_from" },
{ TYPE_INTEGER, &ldi.first_level, "first_level" },
{ TYPE_INTEGER, &ldi.sort_priority, "sort_priority" },
{ TYPE_BOOLEAN, &ldi.level_group, "level_group" },
- { TYPE_BOOLEAN, &ldi.readonly, "readonly" }
+ { TYPE_BOOLEAN, &ldi.readonly, "readonly" },
+ { TYPE_STRING, &ldi.graphics_set, "graphics_set" },
+ { TYPE_STRING, &ldi.sounds_set, "sounds_set" },
+ { TYPE_STRING, &ldi.music_set, "music_set" }
};
static void setTreeInfoToDefaults(TreeInfo *ldi, int type)
ldi->filename = NULL;
ldi->fullpath = NULL;
ldi->basepath = NULL;
+ ldi->identifier = NULL;
ldi->name = getStringCopy(ANONYMOUS_NAME);
- ldi->name_short = NULL;
ldi->name_sorting = NULL;
ldi->author = getStringCopy(ANONYMOUS_NAME);
if (ldi->type == TREE_TYPE_LEVEL_DIR)
{
ldi->imported_from = NULL;
+
+ ldi->graphics_set = NULL;
+ ldi->sounds_set = NULL;
+ ldi->music_set = NULL;
+ ldi->graphics_path = getStringCopy(UNDEFINED_FILENAME);
+ ldi->sounds_path = getStringCopy(UNDEFINED_FILENAME);
+ ldi->music_path = getStringCopy(UNDEFINED_FILENAME);
+
ldi->levels = 0;
ldi->first_level = 0;
ldi->last_level = 0;
{
Error(ERR_WARN, "setTreeInfoToDefaultsFromParent(): parent == NULL");
- setTreeInfoToDefaults(ldi, TREE_TYPE_GENERIC);
+ setTreeInfoToDefaults(ldi, TREE_TYPE_UNDEFINED);
+
return;
}
+#if 1
+ /* copy all values from the parent structure */
+
+ ldi->type = parent->type;
+
+ ldi->node_top = parent->node_top;
+ ldi->node_parent = parent;
+ ldi->node_group = NULL;
+ ldi->next = NULL;
+
+ ldi->cl_first = -1;
+ ldi->cl_cursor = -1;
+
+ ldi->filename = NULL;
+ ldi->fullpath = NULL;
+ ldi->basepath = NULL;
+ ldi->identifier = NULL;
+ ldi->name = getStringCopy(ANONYMOUS_NAME);
+ ldi->name_sorting = NULL;
+ ldi->author = getStringCopy(parent->author);
+
+ ldi->sort_priority = parent->sort_priority;
+ ldi->parent_link = FALSE;
+ 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->graphics_set = NULL;
+ ldi->sounds_set = NULL;
+ ldi->music_set = NULL;
+ ldi->graphics_path = getStringCopy(UNDEFINED_FILENAME);
+ ldi->sounds_path = getStringCopy(UNDEFINED_FILENAME);
+ ldi->music_path = getStringCopy(UNDEFINED_FILENAME);
+
+ ldi->levels = 0;
+ ldi->first_level = 0;
+ ldi->last_level = 0;
+ ldi->level_group = FALSE;
+ ldi->handicap_level = 0;
+ ldi->readonly = TRUE;
+ }
+
+
+#else
+
/* first copy all values from the parent structure ... */
*ldi = *parent;
ldi->filename = NULL;
ldi->fullpath = NULL;
ldi->basepath = NULL;
+ ldi->identifier = NULL;
ldi->name = getStringCopy(ANONYMOUS_NAME);
- ldi->name_short = NULL;
ldi->name_sorting = NULL;
ldi->author = getStringCopy(parent->author);
+
ldi->imported_from = getStringCopy(parent->imported_from);
+ ldi->class_desc = getStringCopy(parent->class_desc);
+
+ ldi->graphics_set = NULL;
+ ldi->sounds_set = NULL;
+ ldi->music_set = NULL;
+ ldi->graphics_path = NULL;
+ ldi->sounds_path = NULL;
+ ldi->music_path = NULL;
ldi->level_group = FALSE;
ldi->parent_link = FALSE;
ldi->node_parent = parent;
ldi->node_group = NULL;
ldi->next = NULL;
+
+#endif
}
void setSetupInfo(struct TokenInfo *token_info,
{
case TYPE_BOOLEAN:
case TYPE_SWITCH:
- *(boolean *)setup_value = get_string_boolean_value(token_value);
+ *(boolean *)setup_value = get_boolean_from_string(token_value);
break;
case TYPE_KEY:
break;
case TYPE_INTEGER:
- *(int *)setup_value = get_string_integer_value(token_value);
+ *(int *)setup_value = get_integer_from_string(token_value);
break;
case TYPE_STRING:
ti_new->node_parent = node_parent;
ti_new->parent_link = TRUE;
+ ti_new->identifier = getStringCopy(node_parent->identifier);
ti_new->name = ".. (parent directory)";
- ti_new->name_short = getStringCopy(ti_new->name);
ti_new->name_sorting = getStringCopy(ti_new->name);
ti_new->filename = "..";
{
char *directory_path = getPath2(level_directory, directory_name);
char *filename = getPath2(directory_path, LEVELINFO_FILENAME);
- struct SetupFileList *setup_file_list = loadSetupFileList(filename);
+ SetupFileHash *setup_file_hash = loadSetupFileHash(filename);
LevelDirTree *leveldir_new = NULL;
int i;
- if (setup_file_list == NULL)
+ if (setup_file_hash == NULL)
{
Error(ERR_WARN, "ignoring level directory '%s'", directory_path);
leveldir_new->filename = getStringCopy(directory_name);
- checkSetupFileListIdentifier(setup_file_list, getCookie("LEVELINFO"));
+ checkSetupFileHashIdentifier(setup_file_hash, getCookie("LEVELINFO"));
/* set all structure fields according to the token/value pairs */
ldi = *leveldir_new;
for (i=0; i<NUM_LEVELINFO_TOKENS; i++)
setSetupInfo(levelinfo_tokens, i,
- getTokenValue(setup_file_list, levelinfo_tokens[i].text));
+ getHashEntry(setup_file_hash, levelinfo_tokens[i].text));
*leveldir_new = ldi;
if (strcmp(leveldir_new->name, ANONYMOUS_NAME) == 0)
DrawInitText(leveldir_new->name, 150, FC_YELLOW);
- if (leveldir_new->name_short == NULL)
- leveldir_new->name_short = getStringCopy(leveldir_new->name);
+ if (leveldir_new->identifier == NULL)
+ leveldir_new->identifier = getStringCopy(leveldir_new->filename);
if (leveldir_new->name_sorting == NULL)
leveldir_new->name_sorting = getStringCopy(leveldir_new->name);
pushTreeInfo(node_first, leveldir_new);
- freeSetupFileList(setup_file_list);
+ freeSetupFileHash(setup_file_hash);
if (leveldir_new->level_group)
{
{
char *directory_path = getPath2(base_directory, directory_name);
char *filename = getPath2(directory_path, ARTWORKINFO_FILENAME(type));
- struct SetupFileList *setup_file_list = NULL;
+ SetupFileHash *setup_file_hash = NULL;
TreeInfo *artwork_new = NULL;
int i;
if (access(filename, F_OK) == 0) /* file exists */
- setup_file_list = loadSetupFileList(filename);
+ setup_file_hash = loadSetupFileHash(filename);
- if (setup_file_list == NULL) /* no config file -- look for artwork files */
+ if (setup_file_hash == NULL) /* no config file -- look for artwork files */
{
DIR *dir;
struct dirent *dir_entry;
artwork_new->filename = getStringCopy(directory_name);
- if (setup_file_list) /* (before defining ".color" and ".class_desc") */
+ if (setup_file_hash) /* (before defining ".color" and ".class_desc") */
{
#if 0
- checkSetupFileListIdentifier(setup_file_list, getCookie("..."));
+ checkSetupFileHashIdentifier(setup_file_hash, getCookie("..."));
#endif
/* set all structure fields according to the token/value pairs */
ldi = *artwork_new;
for (i=0; i<NUM_LEVELINFO_TOKENS; i++)
setSetupInfo(levelinfo_tokens, i,
- getTokenValue(setup_file_list, levelinfo_tokens[i].text));
+ getHashEntry(setup_file_hash, levelinfo_tokens[i].text));
*artwork_new = ldi;
if (strcmp(artwork_new->name, ANONYMOUS_NAME) == 0)
DrawInitText(artwork_new->name, 150, FC_YELLOW);
#endif
- if (artwork_new->name_short == NULL)
- artwork_new->name_short = getStringCopy(artwork_new->name);
+ if (artwork_new->identifier == NULL)
+ artwork_new->identifier = getStringCopy(artwork_new->filename);
if (artwork_new->name_sorting == NULL)
artwork_new->name_sorting = getStringCopy(artwork_new->name);
artwork_new->user_defined =
(artwork_new->basepath == OPTIONS_ARTWORK_DIRECTORY(type) ? FALSE : TRUE);
- /* (may use ".sort_priority" from "setup_file_list" above) */
+ /* (may use ".sort_priority" from "setup_file_hash" above) */
artwork_new->color = ARTWORKCOLOR(artwork_new);
artwork_new->class_desc = getLevelClassDescription(artwork_new);
- if (setup_file_list == NULL) /* (after determining ".user_defined") */
+ if (setup_file_hash == NULL) /* (after determining ".user_defined") */
{
if (artwork_new->name != NULL)
free(artwork_new->name);
{
if (artwork_new->user_defined)
{
- artwork_new->name = getStringCopy("private");
+ artwork_new->identifier = getStringCopy("private");
artwork_new->sort_priority = ARTWORKCLASS_USER;
}
else
{
- artwork_new->name = getStringCopy("classic");
+ artwork_new->identifier = getStringCopy("classic");
artwork_new->sort_priority = ARTWORKCLASS_CLASSICS;
}
+ /* set to new values after changing ".sort_priority" */
artwork_new->color = ARTWORKCOLOR(artwork_new);
artwork_new->class_desc = getLevelClassDescription(artwork_new);
}
else
- artwork_new->name = getStringCopy(artwork_new->filename);
+ {
+ artwork_new->identifier = getStringCopy(artwork_new->filename);
+ }
- artwork_new->name_short = getStringCopy(artwork_new->name);
+ artwork_new->name = getStringCopy(artwork_new->identifier);
artwork_new->name_sorting = getStringCopy(artwork_new->name);
}
pushTreeInfo(node_first, artwork_new);
- freeSetupFileList(setup_file_list);
+ freeSetupFileHash(setup_file_hash);
free(directory_path);
free(filename);
setTreeInfoToDefaults(artwork_new, type);
- artwork_new->filename = getStringCopy(NOT_AVAILABLE);
- artwork_new->fullpath = getStringCopy(NOT_AVAILABLE);
- artwork_new->basepath = getStringCopy(NOT_AVAILABLE);
+ artwork_new->filename = getStringCopy(UNDEFINED_FILENAME);
+ artwork_new->fullpath = getStringCopy(UNDEFINED_FILENAME);
+ artwork_new->basepath = getStringCopy(UNDEFINED_FILENAME);
if (artwork_new->name != NULL)
free(artwork_new->name);
- artwork_new->name = getStringCopy(NOT_AVAILABLE);
- artwork_new->name_short = getStringCopy(NOT_AVAILABLE);
- artwork_new->name_sorting = getStringCopy(NOT_AVAILABLE);
+ artwork_new->identifier = getStringCopy(UNDEFINED_FILENAME);
+ artwork_new->name = getStringCopy(UNDEFINED_FILENAME);
+ artwork_new->name_sorting = getStringCopy(UNDEFINED_FILENAME);
return artwork_new;
}
/* before sorting, the first entries will be from the user directory */
artwork.gfx_current =
- getTreeInfoFromFilename(artwork.gfx_first, setup.graphics_set);
+ getTreeInfoFromIdentifier(artwork.gfx_first, setup.graphics_set);
+ if (artwork.gfx_current == NULL)
+ artwork.gfx_current =
+ getTreeInfoFromIdentifier(artwork.gfx_first, GRAPHICS_SUBDIR);
if (artwork.gfx_current == NULL)
artwork.gfx_current = getFirstValidTreeInfoEntry(artwork.gfx_first);
artwork.snd_current =
- getTreeInfoFromFilename(artwork.snd_first, setup.sounds_set);
+ getTreeInfoFromIdentifier(artwork.snd_first, setup.sounds_set);
+ if (artwork.snd_current == NULL)
+ artwork.snd_current =
+ getTreeInfoFromIdentifier(artwork.snd_first, SOUNDS_SUBDIR);
if (artwork.snd_current == NULL)
artwork.snd_current = getFirstValidTreeInfoEntry(artwork.snd_first);
artwork.mus_current =
- getTreeInfoFromFilename(artwork.mus_first, setup.music_set);
+ getTreeInfoFromIdentifier(artwork.mus_first, setup.music_set);
+ if (artwork.mus_current == NULL)
+ artwork.mus_current =
+ getTreeInfoFromIdentifier(artwork.mus_first, MUSIC_SUBDIR);
if (artwork.mus_current == NULL)
artwork.mus_current = getFirstValidTreeInfoEntry(artwork.mus_first);
- artwork.graphics_set_current_name = artwork.gfx_current->name;
- artwork.sounds_set_current_name = artwork.snd_current->name;
- artwork.music_set_current_name = artwork.mus_current->name;
+ artwork.gfx_current_identifier = artwork.gfx_current->identifier;
+ artwork.snd_current_identifier = artwork.snd_current->identifier;
+ artwork.mus_current_identifier = artwork.mus_current->identifier;
#if 0
- printf("graphics set == %s\n\n", artwork.graphics_set_current_name);
- printf("sounds set == %s\n\n", artwork.sounds_set_current_name);
- printf("music set == %s\n\n", artwork.music_set_current_name);
+ printf("graphics set == %s\n\n", artwork.gfx_current_identifier);
+ printf("sounds set == %s\n\n", artwork.snd_current_identifier);
+ printf("music set == %s\n\n", artwork.mus_current_identifier);
#endif
sortTreeInfo(&artwork.gfx_first, compareTreeInfoEntries);
if (topnode_last != *artwork_node)
{
+ free((*artwork_node)->identifier);
free((*artwork_node)->name);
free((*artwork_node)->name_sorting);
- free((*artwork_node)->name_short);
+ (*artwork_node)->identifier = getStringCopy(level_node->filename);
(*artwork_node)->name = getStringCopy(level_node->name);
(*artwork_node)->name_sorting = getStringCopy(level_node->name);
- (*artwork_node)->name_short = getStringCopy(level_node->filename);
(*artwork_node)->sort_priority = level_node->sort_priority;
(*artwork_node)->color = LEVELCOLOR((*artwork_node));
LoadArtworkInfoFromLevelInfo(&artwork.snd_first, leveldir_first);
LoadArtworkInfoFromLevelInfo(&artwork.mus_first, leveldir_first);
+ /* needed for reloading level artwork not known at ealier stage */
+ if (strcmp(artwork.gfx_current_identifier, setup.graphics_set) != 0)
+ {
+ artwork.gfx_current =
+ getTreeInfoFromIdentifier(artwork.gfx_first, setup.graphics_set);
+ if (artwork.gfx_current == NULL)
+ artwork.gfx_current =
+ getTreeInfoFromIdentifier(artwork.gfx_first, GRAPHICS_SUBDIR);
+ if (artwork.gfx_current == NULL)
+ artwork.gfx_current = getFirstValidTreeInfoEntry(artwork.gfx_first);
+ }
+
+ if (strcmp(artwork.snd_current_identifier, setup.sounds_set) != 0)
+ {
+ artwork.snd_current =
+ getTreeInfoFromIdentifier(artwork.snd_first, setup.sounds_set);
+ if (artwork.snd_current == NULL)
+ artwork.snd_current =
+ getTreeInfoFromIdentifier(artwork.snd_first, SOUNDS_SUBDIR);
+ if (artwork.snd_current == NULL)
+ artwork.snd_current = getFirstValidTreeInfoEntry(artwork.snd_first);
+ }
+
+ if (strcmp(artwork.mus_current_identifier, setup.music_set) != 0)
+ {
+ artwork.mus_current =
+ getTreeInfoFromIdentifier(artwork.mus_first, setup.music_set);
+ if (artwork.mus_current == NULL)
+ artwork.mus_current =
+ getTreeInfoFromIdentifier(artwork.mus_first, MUSIC_SUBDIR);
+ if (artwork.mus_current == NULL)
+ artwork.mus_current = getFirstValidTreeInfoEntry(artwork.mus_first);
+ }
+
sortTreeInfo(&artwork.gfx_first, compareTreeInfoEntries);
sortTreeInfo(&artwork.snd_first, compareTreeInfoEntries);
sortTreeInfo(&artwork.mus_first, compareTreeInfoEntries);
/* always start with reliable default values */
setTreeInfoToDefaults(&ldi, TREE_TYPE_LEVEL_DIR);
+#if 0
+ /* !!! FIX ME !!! */
+ setString(&ldi.name, getLoginName());
+ setString(&ldi.author, getRealName());
+ ldi.levels = 100;
+ ldi.first_level = 1;
+ ldi.sort_priority = LEVELCLASS_USER_START;
+ ldi.readonly = FALSE;
+ setString(&ldi.graphics_set, GRAPHICS_SUBDIR);
+ setString(&ldi.sounds_set, SOUNDS_SUBDIR);
+ setString(&ldi.music_set, MUSIC_SUBDIR);
+#else
ldi.name = getStringCopy(getLoginName());
ldi.author = getStringCopy(getRealName());
ldi.levels = 100;
ldi.first_level = 1;
ldi.sort_priority = LEVELCLASS_USER_START;
ldi.readonly = FALSE;
+ ldi.graphics_set = getStringCopy(GRAPHICS_SUBDIR);
+ ldi.sounds_set = getStringCopy(SOUNDS_SUBDIR);
+ ldi.music_set = getStringCopy(MUSIC_SUBDIR);
+#endif
fprintf(file, "%s\n\n", getFormattedSetupEntry(TOKEN_STR_FILE_IDENTIFIER,
getCookie("LEVELINFO")));
for (i=0; i<NUM_LEVELINFO_TOKENS; i++)
- if (i != LEVELINFO_TOKEN_NAME_SHORT &&
+ if (i != LEVELINFO_TOKEN_IDENTIFIER &&
i != LEVELINFO_TOKEN_NAME_SORTING &&
i != LEVELINFO_TOKEN_IMPORTED_FROM)
fprintf(file, "%s\n", getSetupLine(levelinfo_tokens, "", i));
void LoadLevelSetup_LastSeries()
{
char *filename;
- struct SetupFileList *level_setup_list = NULL;
+ SetupFileHash *level_setup_hash = NULL;
/* always start with reliable default values */
leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
filename = getPath2(getSetupDir(), LEVELSETUP_FILENAME);
- if ((level_setup_list = loadSetupFileList(filename)))
+ if ((level_setup_hash = loadSetupFileHash(filename)))
{
char *last_level_series =
- getTokenValue(level_setup_list, TOKEN_STR_LAST_LEVEL_SERIES);
+ getHashEntry(level_setup_hash, TOKEN_STR_LAST_LEVEL_SERIES);
- leveldir_current = getTreeInfoFromFilename(leveldir_first,
- last_level_series);
+ leveldir_current = getTreeInfoFromIdentifier(leveldir_first,
+ last_level_series);
if (leveldir_current == NULL)
leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
- checkSetupFileListIdentifier(level_setup_list, getCookie("LEVELSETUP"));
+ checkSetupFileHashIdentifier(level_setup_hash, getCookie("LEVELSETUP"));
- freeSetupFileList(level_setup_list);
+ freeSetupFileHash(level_setup_hash);
}
else
Error(ERR_WARN, "using default setup values");
levelnum_value = atoi(levelnum_str);
+#if 0
if (levelnum_value < leveldir_current->first_level)
{
Error(ERR_WARN, "additional level %d found", levelnum_value);
Error(ERR_WARN, "additional level %d found", levelnum_value);
leveldir_current->last_level = levelnum_value;
}
+#endif
}
}
void LoadLevelSetup_SeriesInfo()
{
char *filename;
- struct SetupFileList *level_setup_list = NULL;
+ SetupFileHash *level_setup_hash = NULL;
char *level_subdir = leveldir_current->filename;
/* always start with reliable default values */
filename = getPath2(getLevelSetupDir(level_subdir), LEVELSETUP_FILENAME);
- if ((level_setup_list = loadSetupFileList(filename)))
+ if ((level_setup_hash = loadSetupFileHash(filename)))
{
char *token_value;
- token_value = getTokenValue(level_setup_list, TOKEN_STR_LAST_PLAYED_LEVEL);
+ token_value = getHashEntry(level_setup_hash, TOKEN_STR_LAST_PLAYED_LEVEL);
if (token_value)
{
level_nr = leveldir_current->last_level;
}
- token_value = getTokenValue(level_setup_list, TOKEN_STR_HANDICAP_LEVEL);
+ token_value = getHashEntry(level_setup_hash, TOKEN_STR_HANDICAP_LEVEL);
if (token_value)
{
leveldir_current->handicap_level = level_nr;
}
- checkSetupFileListIdentifier(level_setup_list, getCookie("LEVELSETUP"));
+ checkSetupFileHashIdentifier(level_setup_hash, getCookie("LEVELSETUP"));
- freeSetupFileList(level_setup_list);
+ freeSetupFileHash(level_setup_hash);
}
else
Error(ERR_WARN, "using default setup values");
#define SETUP_H
#include "system.h"
+#include "hash.h"
/* values for setup file handling */
#define TYPE_KEY_X11 (1 << 4)
#define TYPE_INTEGER (1 << 5)
#define TYPE_STRING (1 << 6)
+#define TYPE_TOKEN (1 << 7)
#define TYPE_BOOLEAN_STYLE (TYPE_BOOLEAN | \
TYPE_SWITCH | \
TYPE_YES_NO)
/* additional values for setup screen */
-#define TYPE_ENTER_MENU (1 << 7)
-#define TYPE_LEAVE_MENU (1 << 8)
-#define TYPE_EMPTY (1 << 9)
-#define TYPE_KEYTEXT (1 << 10)
-
-#define TYPE_GHOSTED (1 << 11)
-#define TYPE_QUERY (1 << 12)
-
-#define TYPE_VALUE (TYPE_BOOLEAN_STYLE | \
- TYPE_KEY | \
- TYPE_KEY_X11 | \
- TYPE_INTEGER | \
+#define TYPE_ENTER_MENU (1 << 8)
+#define TYPE_LEAVE_MENU (1 << 9)
+#define TYPE_EMPTY (1 << 10)
+#define TYPE_KEYTEXT (1 << 11)
+
+#define TYPE_GHOSTED (1 << 12)
+#define TYPE_QUERY (1 << 13)
+
+#define TYPE_VALUE (TYPE_BOOLEAN_STYLE | \
+ TYPE_KEY | \
+ TYPE_KEY_X11 | \
+ TYPE_INTEGER | \
+ TYPE_STRING | \
+ TYPE_TOKEN)
+
+#define TYPE_SKIP_ENTRY (TYPE_EMPTY | \
+ TYPE_KEY | \
TYPE_STRING)
-#define TYPE_SKIP_ENTRY (TYPE_EMPTY | \
- TYPE_KEY | \
- TYPE_STRING)
-
-#define TYPE_ENTER_OR_LEAVE_MENU (TYPE_ENTER_MENU | \
+#define TYPE_ENTER_OR_LEAVE_MENU (TYPE_ENTER_MENU | \
TYPE_LEAVE_MENU)
/* cookie token for file identifier and version number */
#define TOKEN_STR_FILE_IDENTIFIER "file_identifier"
-/* structures for setup file handling */
-struct SetupFileList
-{
- char *token;
- char *value;
- struct SetupFileList *next;
-};
-
struct TokenInfo
{
int type;
char *text;
};
+/* some definitions for list and hash handling */
+typedef struct SetupFileList SetupFileList;
+typedef struct hashtable SetupFileHash;
+
+#define BEGIN_HASH_ITERATION(hash, itr) \
+ if (hash != NULL && hashtable_count(hash) > 0) \
+ { \
+ struct hashtable_itr *itr = hashtable_iterator(hash); \
+ do { \
+
+#define HASH_ITERATION_TOKEN(itr) ((char *)hashtable_iterator_key(itr))
+#define HASH_ITERATION_VALUE(itr) ((char *)hashtable_iterator_value(itr))
+
+#define END_HASH_ITERATION(hash, itr) \
+ } while (hashtable_iterator_advance(itr)); \
+ free(itr); \
+ } \
+
+
/* sort priorities of level series (also used as level series classes) */
#define LEVELCLASS_TUTORIAL_START 10
#define LEVELCLASS_TUTORIAL_END 99
ARTWORKCLASS_UNDEFINED)
+void setLevelArtworkDir(TreeInfo *);
char *getLevelFilename(int);
char *getTapeFilename(int);
char *getScoreFilename(int);
char *getImageFilename(char *);
char *getCustomImageFilename(char *);
char *getCustomSoundFilename(char *);
-char *getCustomSoundConfigFilename(void);
+char *getCustomArtworkFilename(char *, int);
+char *getCustomArtworkConfigFilename(int);
+char *getCustomArtworkLevelConfigFilename(int);
char *getCustomMusicDirectory(void);
void InitTapeDirectory(char *);
int numTreeInfoInGroup(TreeInfo *);
int posTreeInfo(TreeInfo *);
TreeInfo *getTreeInfoFromPos(TreeInfo *, int);
-TreeInfo *getTreeInfoFromFilename(TreeInfo *, char *);
+TreeInfo *getTreeInfoFromIdentifier(TreeInfo *, char *);
void dumpTreeInfo(TreeInfo *, int);
void sortTreeInfo(TreeInfo **,
int (*compare_function)(const void *, const void *));
char *getUserDataDir(void);
+char *getCommonDataDir(void);
char *getSetupDir(void);
void createDirectory(char *, char *, int);
void InitUserDataDirectory(void);
boolean checkCookieString(const char *, const char *);
char *getFormattedSetupEntry(char *, char *);
+
+struct SetupFileList *newSetupFileList(char *, char *);
void freeSetupFileList(struct SetupFileList *);
-char *getTokenValue(struct SetupFileList *, char *);
-struct SetupFileList *loadSetupFileList(char *);
-void checkSetupFileListIdentifier(struct SetupFileList *, char *);
+char *getListEntry(struct SetupFileList *, char *);
+void setListEntry(struct SetupFileList *, char *, char *);
+SetupFileList *loadSetupFileList(char *);
+
+SetupFileHash *newSetupFileHash();
+void freeSetupFileHash(SetupFileHash *);
+char *getHashEntry(SetupFileHash *, char *);
+void setHashEntry(SetupFileHash *, char *, char *);
+SetupFileHash *loadSetupFileHash(char *);
+void checkSetupFileHashIdentifier(SetupFileHash *, char *);
void setSetupInfo(struct TokenInfo *, int, char *);
char *getSetupValue(int, void *);
char *getSetupLine(struct TokenInfo *, char *, int);
#define SOUND_FADING_VOLUME_THRESHOLD (SOUND_FADING_VOLUME_STEP * 2)
#endif
-#if !defined(PLATFORM_HPUX)
-#define SND_BLOCKSIZE 4096
-#else
-#define SND_BLOCKSIZE 32768
-#endif
-
#define SND_TYPE_NONE 0
#define SND_TYPE_WAV 1
int format;
void *data_ptr; /* pointer to first sample (8 or 16 bit) */
long data_len; /* number of samples, NOT number of bytes */
+ int num_channels; /* mono: 1 channel, stereo: 2 channels */
};
typedef struct SampleInfo SoundInfo;
typedef struct SampleInfo MusicInfo;
int format;
void *data_ptr; /* pointer to first sample (8 or 16 bit) */
long data_len; /* number of samples, NOT number of bytes */
+ int num_channels; /* mono: 1 channel, stereo: 2 channels */
#if defined(TARGET_ALLEGRO)
int voice;
};
typedef struct SoundControl SoundControl;
-struct ListNode
-{
- char *key;
- void *content;
- struct ListNode *next;
-};
-typedef struct ListNode ListNode;
-
-static ListNode *newListNode(void);
-static void addNodeToList(ListNode **, char *, void *);
-static void deleteNodeFromList(ListNode **, char *, void (*function)(void *));
-static ListNode *getNodeFromKey(ListNode *, char *);
-static int getNumNodes(ListNode *);
-
-
-static struct SoundEffectInfo *sound_effect;
-static ListNode *SoundFileList = NULL;
+static struct ArtworkListInfo *sound_info = NULL;
+#if 0
static SoundInfo **Sound = NULL;
+#endif
static MusicInfo **Music = NULL;
-static int num_sounds = 0, num_music = 0;
+#if 0
+static int num_sounds = 0;
+#endif
+static int num_music = 0;
static int stereo_volume[SOUND_MAX_LEFT2RIGHT + 1];
static void ReloadCustomMusic();
static void FreeSound(void *);
+static SoundInfo *getSoundInfoEntryFromSoundID(int);
+
/* ------------------------------------------------------------------------- */
/* functions for native (non-SDL) Unix audio/mixer support */
return FALSE;
}
- if (IS_CHILD_PROCESS(audio.mixer_pid))
+ if (audio.mixer_pid == 0) /* we are the child process */
+ audio.mixer_pid = getpid();
+
+#if 0
+ printf("PID: %d [%s]\n", getpid(),(IS_CHILD_PROCESS() ? "child" : "parent"));
+ Delay(10000 * 0);
+#endif
+
+ if (IS_CHILD_PROCESS())
Mixer_Main(); /* this function never returns */
else
close(audio.mixer_pipe[0]); /* no reading from pipe needed */
if (audio.device_fd)
close(audio.device_fd);
- if (IS_PARENT_PROCESS(audio.mixer_pid))
+ if (IS_PARENT_PROCESS() && HAS_CHILD_PROCESS())
kill(audio.mixer_pid, SIGTERM);
}
static void SendSoundControlToMixerProcess(SoundControl *snd_ctrl)
{
- if (IS_CHILD_PROCESS(audio.mixer_pid))
+ if (IS_CHILD_PROCESS())
return;
if (write(audio.mixer_pipe[1], snd_ctrl, sizeof(SoundControl)) < 0)
static void ReadSoundControlFromMainProcess(SoundControl *snd_ctrl)
{
- if (IS_PARENT_PROCESS(audio.mixer_pid))
+ if (IS_PARENT_PROCESS())
return;
if (read(audio.mixer_pipe[0], snd_ctrl, sizeof(SoundControl))
Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
}
-static void WriteReloadInfoToPipe(char *set_name, int type)
+static void WriteReloadInfoToPipe(char *set_identifier, int type)
{
SoundControl snd_ctrl;
TreeInfo *ti = (type == SND_CTRL_RELOAD_SOUNDS ? artwork.snd_current :
artwork.mus_current);
unsigned long str_size1 = strlen(leveldir_current->fullpath) + 1;
- unsigned long str_size2 = strlen(ti->basepath) + 1;
- unsigned long str_size3 = strlen(ti->fullpath) + 1;
+ unsigned long str_size2 = strlen(leveldir_current->sounds_path) + 1;
+ unsigned long str_size3 = strlen(leveldir_current->music_path) + 1;
+ unsigned long str_size4 = strlen(ti->basepath) + 1;
+ unsigned long str_size5 = strlen(ti->fullpath) + 1;
boolean override_level_artwork = (type == SND_CTRL_RELOAD_SOUNDS ?
setup.override_level_sounds :
setup.override_level_music);
- if (IS_CHILD_PROCESS(audio.mixer_pid))
+ if (IS_CHILD_PROCESS())
return;
if (leveldir_current == NULL) /* should never happen */
snd_ctrl.active = FALSE;
snd_ctrl.state = type;
- snd_ctrl.data_len = strlen(set_name) + 1;
+ snd_ctrl.data_len = strlen(set_identifier) + 1;
if (write(audio.mixer_pipe[1], &snd_ctrl,
sizeof(snd_ctrl)) < 0 ||
- write(audio.mixer_pipe[1], set_name,
+ write(audio.mixer_pipe[1], set_identifier,
snd_ctrl.data_len) < 0 ||
write(audio.mixer_pipe[1], &override_level_artwork,
sizeof(boolean)) < 0 ||
sizeof(unsigned long)) < 0 ||
write(audio.mixer_pipe[1], &str_size3,
sizeof(unsigned long)) < 0 ||
+ write(audio.mixer_pipe[1], &str_size4,
+ sizeof(unsigned long)) < 0 ||
+ write(audio.mixer_pipe[1], &str_size5,
+ sizeof(unsigned long)) < 0 ||
write(audio.mixer_pipe[1], leveldir_current->fullpath,
str_size1) < 0 ||
- write(audio.mixer_pipe[1], ti->basepath,
+ write(audio.mixer_pipe[1], leveldir_current->sounds_path,
str_size2) < 0 ||
+ write(audio.mixer_pipe[1], leveldir_current->music_path,
+ str_size3) < 0 ||
+ write(audio.mixer_pipe[1], ti->basepath,
+ str_size4) < 0 ||
write(audio.mixer_pipe[1], ti->fullpath,
- str_size3) < 0)
+ str_size5) < 0)
{
Error(ERR_WARN, "cannot pipe to child process -- no sounds");
audio.sound_available = audio.sound_enabled = FALSE;
TreeInfo **ti_ptr = ((snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS) ?
&artwork.snd_current : &artwork.mus_current);
TreeInfo *ti = *ti_ptr;
- unsigned long str_size1, str_size2, str_size3;
- static char *set_name = NULL;
+ unsigned long str_size1, str_size2, str_size3, str_size4, str_size5;
+ static char *set_identifier = NULL;
boolean *override_level_artwork = (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS ?
&setup.override_level_sounds :
&setup.override_level_music);
- if (set_name)
- free(set_name);
+ if (set_identifier)
+ free(set_identifier);
- set_name = checked_malloc(snd_ctrl->data_len);
+ set_identifier = checked_malloc(snd_ctrl->data_len);
if (leveldir_current == NULL)
leveldir_current = checked_calloc(sizeof(TreeInfo));
+
if (ti == NULL)
ti = *ti_ptr = checked_calloc(sizeof(TreeInfo));
if (leveldir_current->fullpath != NULL)
free(leveldir_current->fullpath);
+ if (leveldir_current->sounds_path != NULL)
+ free(leveldir_current->sounds_path);
+ if (leveldir_current->music_path != NULL)
+ free(leveldir_current->music_path);
if (ti->basepath != NULL)
free(ti->basepath);
if (ti->fullpath != NULL)
free(ti->fullpath);
- if (read(audio.mixer_pipe[0], set_name,
+ if (read(audio.mixer_pipe[0], set_identifier,
snd_ctrl->data_len) != snd_ctrl->data_len ||
read(audio.mixer_pipe[0], override_level_artwork,
sizeof(boolean)) != sizeof(boolean) ||
read(audio.mixer_pipe[0], &str_size2,
sizeof(unsigned long)) != sizeof(unsigned long) ||
read(audio.mixer_pipe[0], &str_size3,
+ sizeof(unsigned long)) != sizeof(unsigned long) ||
+ read(audio.mixer_pipe[0], &str_size4,
+ sizeof(unsigned long)) != sizeof(unsigned long) ||
+ read(audio.mixer_pipe[0], &str_size5,
sizeof(unsigned long)) != sizeof(unsigned long))
Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
leveldir_current->fullpath = checked_calloc(str_size1);
- ti->basepath = checked_calloc(str_size2);
- ti->fullpath = checked_calloc(str_size3);
+ leveldir_current->sounds_path = checked_calloc(str_size2);
+ leveldir_current->music_path = checked_calloc(str_size3);
+ ti->basepath = checked_calloc(str_size4);
+ ti->fullpath = checked_calloc(str_size5);
if (read(audio.mixer_pipe[0], leveldir_current->fullpath,
str_size1) != str_size1 ||
- read(audio.mixer_pipe[0], ti->basepath,
+ read(audio.mixer_pipe[0], leveldir_current->sounds_path,
str_size2) != str_size2 ||
+ read(audio.mixer_pipe[0], leveldir_current->music_path,
+ str_size3) != str_size3 ||
+ read(audio.mixer_pipe[0], ti->basepath,
+ str_size4) != str_size4 ||
read(audio.mixer_pipe[0], ti->fullpath,
- str_size3) != str_size3)
+ str_size5) != str_size5)
Error(ERR_EXIT_SOUND_SERVER, "broken pipe -- no sounds");
if (snd_ctrl->state & SND_CTRL_RELOAD_SOUNDS)
- artwork.sounds_set_current_name = set_name;
+ artwork.snd_current_identifier = set_identifier;
else
- artwork.music_set_current_name = set_name;
+ artwork.mus_current_identifier = set_identifier;
}
#endif /* AUDIO_UNIX_NATIVE */
{
SoundInfo *snd_info;
int i, k;
+ int num_sounds = getSoundListSize();
#if 0
printf("NEW SOUND %d ARRIVED [%d] [%d ACTIVE CHANNELS]\n",
else if (snd_ctrl.nr >= num_sounds)
return;
+#if 0
snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
+#else
+ snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] :
+ getSoundInfoEntryFromSoundID(snd_ctrl.nr));
+#endif
+
if (snd_info == NULL)
return;
/* copy sound sample and format information */
- snd_ctrl.type = snd_info->type;
- snd_ctrl.format = snd_info->format;
- snd_ctrl.data_ptr = snd_info->data_ptr;
- snd_ctrl.data_len = snd_info->data_len;
+ snd_ctrl.type = snd_info->type;
+ snd_ctrl.format = snd_info->format;
+ snd_ctrl.data_ptr = snd_info->data_ptr;
+ snd_ctrl.data_len = snd_info->data_len;
+ snd_ctrl.num_channels = snd_info->num_channels;
/* play music samples on a dedicated music channel */
if (IS_MUSIC(snd_ctrl))
unsigned long playing_current = Counter();
int longest = 0, longest_nr = audio.first_sound_channel;
+#if 0
+#if DEBUG
+ /* print some debugging information about audio channel usage */
for (i=audio.first_sound_channel; i<audio.num_channels; i++)
{
Error(ERR_RETURN, "Mixer_InsertSound: %d [%d]: %ld (%ld)",
i, mixer[i].active, mixer[i].data_len, (long)mixer[i].data_ptr);
}
+#endif
+#endif
for (i=audio.first_sound_channel; i<audio.num_channels; i++)
{
int i;
#if defined(AUDIO_UNIX_NATIVE)
- if (IS_PARENT_PROCESS(audio.mixer_pid))
+ if (IS_PARENT_PROCESS())
{
SendSoundControlToMixerProcess(&snd_ctrl);
return;
static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
int sample_pos, int sample_size,
- short *buffer_ptr)
+ short *buffer_base_ptr, int buffer_pos,
+ int num_output_channels)
{
- void *sample_ptr = snd_ctrl->data_ptr;
- int i;
+ short *buffer_ptr = buffer_base_ptr + num_output_channels * buffer_pos;
+ int num_channels = snd_ctrl->num_channels;
+ int stepsize = num_channels;
+ int output_stepsize = num_output_channels;
+ int i, j;
if (snd_ctrl->format == AUDIO_FORMAT_U8)
- for (i=0; i<sample_size; i++)
- *buffer_ptr++ =
- ((short)(((byte *)sample_ptr)[sample_pos + i] ^ 0x80)) << 8;
+ {
+ byte *sample_ptr = (byte *)snd_ctrl->data_ptr + num_channels * sample_pos;
+
+ for (i=0; i<num_output_channels; i++)
+ {
+ int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
+
+ for (j=0; j<sample_size; j++)
+ buffer_ptr[output_stepsize * j + i] =
+ ((short)(sample_ptr[stepsize * j + offset] ^ 0x80)) << 8;
+ }
+ }
else /* AUDIO_FORMAT_S16 */
- for (i=0; i<sample_size; i++)
- *buffer_ptr++ =
- ((short *)sample_ptr)[sample_pos + i];
+ {
+ short *sample_ptr= (short *)snd_ctrl->data_ptr + num_channels * sample_pos;
+
+ for (i=0; i<num_output_channels; i++)
+ {
+ int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
+
+ for (j=0; j<sample_size; j++)
+ buffer_ptr[output_stepsize * j + i] =
+ sample_ptr[stepsize * j + offset];
+ }
+ }
}
#if defined(AUDIO_STREAMING_DSP)
static void Mixer_Main_DSP()
{
- static short premix_first_buffer[SND_BLOCKSIZE];
- static short premix_left_buffer[SND_BLOCKSIZE];
- static short premix_right_buffer[SND_BLOCKSIZE];
- static long premix_last_buffer[SND_BLOCKSIZE];
- static byte playing_buffer[SND_BLOCKSIZE];
+ static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
+ static long premix_last_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
+ static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
boolean stereo;
int fragment_size;
int sample_bytes;
int max_sample_size;
+ int num_output_channels;
int i, j;
if (!mixer_active_channels)
stereo = afmt.stereo;
fragment_size = afmt.fragment_size;
sample_bytes = (afmt.format & AUDIO_FORMAT_U8 ? 1 : 2);
- max_sample_size = fragment_size / ((stereo ? 2 : 1) * sample_bytes);
+ num_output_channels = (stereo ? 2 : 1);
+ max_sample_size = fragment_size / (num_output_channels * sample_bytes);
/* first clear the last premixing buffer */
memset(premix_last_buffer, 0,
- max_sample_size * (stereo ? 2 : 1) * sizeof(long));
+ max_sample_size * num_output_channels * sizeof(long));
for(i=0; i<audio.num_channels; i++)
{
/* copy original sample to first mixing buffer */
CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
- premix_first_buffer);
+ premix_first_buffer, 0, num_output_channels);
/* are we about to restart a looping sound? */
if (IS_LOOP(mixer[i]) && sample_size < max_sample_size)
int restarted_sample_size =
MIN(max_sample_size - sample_size, sample_len);
- if (mixer[i].format == AUDIO_FORMAT_U8)
- for (j=0; j<restarted_sample_size; j++)
- premix_first_buffer[sample_size + j] =
- ((short)(((byte *)sample_ptr)[j] ^ 0x80)) << 8;
- else
- for (j=0; j<restarted_sample_size; j++)
- premix_first_buffer[sample_size + j] =
- ((short *)sample_ptr)[j];
+ CopySampleToMixingBuffer(&mixer[i], 0, restarted_sample_size,
+ premix_first_buffer, sample_size,
+ num_output_channels);
mixer[i].playing_pos = restarted_sample_size;
sample_size += restarted_sample_size;
/* adjust volume of actual sound sample */
if (mixer[i].volume != SOUND_MAX_VOLUME)
- for(j=0; j<sample_size; j++)
+ for(j=0; j<sample_size * num_output_channels; j++)
premix_first_buffer[j] =
mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
- /* fill the last mixing buffer with stereo or mono sound */
+ /* adjust left and right channel volume due to stereo sound position */
if (stereo)
{
int left_volume = SOUND_VOLUME_LEFT(mixer[i].stereo_position);
for(j=0; j<sample_size; j++)
{
- premix_left_buffer[j] =
- left_volume * premix_first_buffer[j] / SOUND_MAX_LEFT2RIGHT;
- premix_right_buffer[j] =
- right_volume * premix_first_buffer[j] / SOUND_MAX_LEFT2RIGHT;
-
- premix_last_buffer[2 * j + 0] += premix_left_buffer[j];
- premix_last_buffer[2 * j + 1] += premix_right_buffer[j];
+ premix_first_buffer[2 * j + 0] =
+ left_volume * premix_first_buffer[2 * j + 0] / SOUND_MAX_LEFT2RIGHT;
+ premix_first_buffer[2 * j + 1] =
+ right_volume * premix_first_buffer[2 * j + 1] / SOUND_MAX_LEFT2RIGHT;
}
}
- else
- {
- for(j=0; j<sample_size; j++)
- premix_last_buffer[j] += premix_first_buffer[j];
- }
+
+ /* fill the last mixing buffer with stereo or mono sound */
+ for(j=0; j<sample_size * num_output_channels; j++)
+ premix_last_buffer[j] += premix_first_buffer[j];
/* delete completed sound entries from the mixer */
if (mixer[i].playing_pos >= mixer[i].data_len)
}
/* prepare final playing buffer according to system audio format */
- for(i=0; i<max_sample_size * (stereo ? 2 : 1); i++)
+ for(i=0; i<max_sample_size * num_output_channels; i++)
{
/* cut off at 17 bit value */
if (premix_last_buffer[i] < -65535)
static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
{
- static short premix_first_buffer[SND_BLOCKSIZE];
- static byte playing_buffer[SND_BLOCKSIZE];
- int max_sample_size = SND_BLOCKSIZE;
+ static short premix_first_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
+ static byte playing_buffer[DEFAULT_AUDIO_FRAGMENT_SIZE];
+ int max_sample_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
+ int num_output_channels = 1;
void *sample_ptr;
int sample_len;
int sample_pos;
/* copy original sample to first mixing buffer */
CopySampleToMixingBuffer(&mixer[i], sample_pos, sample_size,
- premix_first_buffer);
+ premix_first_buffer, 0, num_output_channels);
/* adjust volume of actual sound sample */
if (mixer[i].volume != SOUND_MAX_VOLUME)
#define CHUNK_ID_LEN 4 /* IFF style chunk id length */
#define WAV_HEADER_SIZE 16 /* size of WAV file header */
-static SoundInfo *Load_WAV(char *filename)
+static void *Load_WAV(char *filename)
{
SoundInfo *snd_info;
#if defined(AUDIO_UNIX_NATIVE)
#endif
char chunk_name[CHUNK_ID_LEN + 1];
int chunk_size;
+ int data_byte_len;
FILE *file;
#endif
return NULL;
}
- if (header.num_channels != 1)
+ if (header.num_channels != 1 &&
+ header.num_channels != 2)
{
Error(ERR_WARN, "sound file '%s': number of %d channels not supported",
filename, header.num_channels);
return NULL;
}
- if (header.bits_per_sample != 8 && header.bits_per_sample != 16)
+ if (header.bits_per_sample != 8 &&
+ header.bits_per_sample != 16)
{
Error(ERR_WARN, "sound file '%s': %d bits per sample not supported",
filename, header.bits_per_sample);
}
else if (strcmp(chunk_name, "data") == 0)
{
- snd_info->data_len = chunk_size;
+ data_byte_len = chunk_size;
+
+ snd_info->data_len = data_byte_len;
snd_info->data_ptr = checked_malloc(snd_info->data_len);
/* read sound data */
return NULL;
}
- /* check for odd number of sample bytes (data chunk is word aligned) */
- if ((chunk_size % 2) == 1)
+ /* check for odd number of data bytes (data chunk is word aligned) */
+ if ((data_byte_len % 2) == 1)
ReadUnusedBytesFromFile(file, 1);
}
else /* unknown chunk -- ignore */
snd_info->data_len /= 2; /* correct number of samples */
}
+ snd_info->num_channels = header.num_channels;
+ if (header.num_channels == 2)
+ snd_info->data_len /= 2; /* correct number of samples */
+
+#if 0
+ if (header.num_channels == 1) /* convert mono sound to stereo */
+ {
+ void *buffer_ptr = checked_malloc(data_byte_len * 2);
+ void *sample_ptr = snd_info->data_ptr;
+ int sample_size = snd_info->data_len;
+ int i;
+
+ if (snd_ctrl->format == AUDIO_FORMAT_U8)
+ for (i=0; i<sample_size; i++)
+ *buffer_ptr++ =
+ ((short)(((byte *)sample_ptr)[i] ^ 0x80)) << 8;
+ else /* AUDIO_FORMAT_S16 */
+ for (i=0; i<sample_size; i++)
+ *buffer_ptr++ =
+ ((short *)sample_ptr)[i];
+ }
+#endif
+
#endif /* AUDIO_UNIX_NATIVE */
snd_info->type = SND_TYPE_WAV;
return snd_info;
}
-static void deleteSoundEntry(SoundInfo **snd_info)
+int getSoundListSize()
{
- if (*snd_info)
- {
- char *filename = (*snd_info)->source_filename;
+ return (sound_info->num_file_list_entries +
+ sound_info->num_dynamic_file_list_entries);
+}
-#if 0
- printf("[decrementing reference counter of sound '%s']\n", filename);
-#endif
+struct FileInfo *getSoundListEntry(int pos)
+{
+ int num_list_entries = sound_info->num_file_list_entries;
+ int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
- if (--(*snd_info)->num_references <= 0)
- {
-#if 0
- printf("[deleting sound '%s']\n", filename);
-#endif
+ return (pos < num_list_entries ? &sound_info->file_list[list_pos] :
+ &sound_info->dynamic_file_list[list_pos]);
+}
- /*
- FreeSound(*snd_info);
- */
- deleteNodeFromList(&SoundFileList, filename, FreeSound);
- }
+static SoundInfo *getSoundInfoEntryFromSoundID(int pos)
+{
+ int num_list_entries = sound_info->num_file_list_entries;
+ int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
+ SoundInfo **snd_info =
+ (SoundInfo **)(pos < num_list_entries ? sound_info->artwork_list :
+ sound_info->dynamic_artwork_list);
- *snd_info = NULL;
- }
+ return snd_info[list_pos];
}
-static void replaceSoundEntry(SoundInfo **snd_info, char *filename)
+int getSoundListPropertyMappingSize()
{
- ListNode *node;
+ return sound_info->num_property_mapping_entries;
+}
- /* check if the old and the new sound file are the same */
- if (*snd_info && strcmp((*snd_info)->source_filename, filename) == 0)
- {
- /* The old and new sound are the same (have the same filename and path).
- This usually means that this sound does not exist in this sound set
- and a fallback to the existing sound is done. */
+struct PropertyMapping *getSoundListPropertyMapping()
+{
+ return sound_info->property_mapping;
+}
-#if 0
- printf("[sound '%s' already exists (same list entry)]\n", filename);
-#endif
+void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries,
+ struct ConfigInfo *config_suffix_list,
+ char **base_prefixes, char **ext1_suffixes,
+ char **ext2_suffixes, char **ext3_suffixes,
+ char **ignore_tokens)
+{
+ int i;
- return;
- }
+ sound_info = checked_calloc(sizeof(struct ArtworkListInfo));
+ sound_info->type = ARTWORK_TYPE_SOUNDS;
- /* delete existing sound file entry */
- deleteSoundEntry(snd_info);
+ /* ---------- initialize file list and suffix lists ---------- */
- /* check if the new sound file already exists in the list of sounds */
- if ((node = getNodeFromKey(SoundFileList, filename)) != NULL)
- {
-#if 0
- printf("[sound '%s' already exists (other list entry)]\n", filename);
-#endif
+ sound_info->num_file_list_entries = num_file_list_entries;
+ sound_info->num_dynamic_file_list_entries = 0;
- *snd_info = (SoundInfo *)node->content;
- (*snd_info)->num_references++;
- }
- else if ((*snd_info = Load_WAV(filename)) != NULL) /* load new sound */
- {
- (*snd_info)->num_references = 1;
- addNodeToList(&SoundFileList, (*snd_info)->source_filename, *snd_info);
- }
-}
+ sound_info->file_list =
+ getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
+ num_file_list_entries);
+ sound_info->dynamic_file_list = NULL;
-static void LoadCustomSound(SoundInfo **snd_info, char *basename)
-{
- char *filename = getCustomSoundFilename(basename);
+ sound_info->num_suffix_list_entries = 0;
+ for (i=0; config_suffix_list[i].token != NULL; i++)
+ sound_info->num_suffix_list_entries++;
-#if 0
- printf("GOT CUSTOM SOUND FILE '%s'\n", filename);
-#endif
+ sound_info->suffix_list = config_suffix_list;
- if (strcmp(basename, SND_FILE_UNDEFINED) == 0)
- {
- deleteSoundEntry(snd_info);
- return;
- }
+ /* ---------- initialize base prefix and suffixes lists ---------- */
- if (filename == NULL)
- {
- Error(ERR_WARN, "cannot find sound file '%s'", basename);
- return;
- }
+ sound_info->num_base_prefixes = 0;
+ for (i=0; base_prefixes[i] != NULL; i++)
+ sound_info->num_base_prefixes++;
- replaceSoundEntry(snd_info, filename);
-}
+ sound_info->num_ext1_suffixes = 0;
+ for (i=0; ext1_suffixes[i] != NULL; i++)
+ sound_info->num_ext1_suffixes++;
-void InitSoundList(struct SoundEffectInfo *sounds_list, int num_list_entries)
-{
- if (Sound == NULL)
- Sound = checked_calloc(num_list_entries * sizeof(SoundInfo *));
+ sound_info->num_ext2_suffixes = 0;
+ for (i=0; ext2_suffixes[i] != NULL; i++)
+ sound_info->num_ext2_suffixes++;
- sound_effect = sounds_list;
- num_sounds = num_list_entries;
-}
+ sound_info->num_ext3_suffixes = 0;
+ for (i=0; ext3_suffixes[i] != NULL; i++)
+ sound_info->num_ext3_suffixes++;
-void LoadSoundToList(char *basename, int list_pos)
-{
- if (Sound == NULL || list_pos >= num_sounds)
- return;
+ sound_info->num_ignore_tokens = 0;
+ for (i=0; ignore_tokens[i] != NULL; i++)
+ sound_info->num_ignore_tokens++;
-#if 0
- printf("loading sound '%s' ... [%d]\n",
- basename, getNumNodes(SoundFileList));
-#endif
+ sound_info->base_prefixes = base_prefixes;
+ sound_info->ext1_suffixes = ext1_suffixes;
+ sound_info->ext2_suffixes = ext2_suffixes;
+ sound_info->ext3_suffixes = ext3_suffixes;
+ sound_info->ignore_tokens = ignore_tokens;
+
+ sound_info->num_property_mapping_entries = 0;
+
+ sound_info->property_mapping = NULL;
+
+ /* ---------- initialize artwork reference and content lists ---------- */
+
+ sound_info->sizeof_artwork_list_entry = sizeof(SoundInfo *);
- LoadCustomSound(&Sound[list_pos], basename);
+ sound_info->artwork_list =
+ checked_calloc(num_file_list_entries * sizeof(SoundInfo *));
+ sound_info->dynamic_artwork_list = NULL;
+
+ sound_info->content_list = NULL;
+
+ /* ---------- initialize artwork loading/freeing functions ---------- */
+
+ sound_info->load_artwork = Load_WAV;
+ sound_info->free_artwork = FreeSound;
#if 0
- printf("loading sound '%s' done [%d]\n",
- basename, getNumNodes(SoundFileList));
+ num_sounds = sound_info->num_file_list_entries;
+ Sound = (SoundInfo **)sound_info->artwork_list;
#endif
}
strcmp(last_music_directory, music_directory) == 0)
return; /* old and new music directory are the same */
- last_music_directory = music_directory;
+ if (last_music_directory != NULL)
+ free(last_music_directory);
+ last_music_directory = getStringCopy(music_directory);
FreeAllMusic();
char *filename = getPath2(music_directory, basename);
MusicInfo *mus_info = NULL;
+#if 0
+ printf("DEBUG: loading music '%s' ...\n", basename);
+#endif
+
if (draw_init_text)
DrawInitText(basename, 150, FC_YELLOW);
{
num_music++;
Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
- Music[num_music -1] = mus_info;
+ Music[num_music - 1] = mus_info;
}
}
HandleSoundRequest(snd_ctrl);
}
-ListNode *newListNode()
-{
- return checked_calloc(sizeof(ListNode));
-}
-
-void addNodeToList(ListNode **node_first, char *key, void *content)
-{
- ListNode *node_new = newListNode();
-
-#if 0
- printf("LIST: adding node with key '%s'\n", key);
-#endif
-
- node_new->key = getStringCopy(key);
- node_new->content = content;
- node_new->next = *node_first;
- *node_first = node_new;
-}
-
-void deleteNodeFromList(ListNode **node_first, char *key,
- void (*destructor_function)(void *))
-{
- if (node_first == NULL || *node_first == NULL)
- return;
-
-#if 0
- printf("[CHECKING LIST KEY '%s' == '%s']\n",
- (*node_first)->key, key);
-#endif
-
- if (strcmp((*node_first)->key, key) == 0)
- {
-#if 0
- printf("[DELETING LIST ENTRY]\n");
-#endif
-
- free((*node_first)->key);
- if (destructor_function)
- destructor_function((*node_first)->content);
- *node_first = (*node_first)->next;
- }
- else
- deleteNodeFromList(&(*node_first)->next, key, destructor_function);
-}
-
-ListNode *getNodeFromKey(ListNode *node_first, char *key)
-{
- if (node_first == NULL)
- return NULL;
-
- if (strcmp(node_first->key, key) == 0)
- return node_first;
- else
- return getNodeFromKey(node_first->next, key);
-}
-
-int getNumNodes(ListNode *node_first)
-{
- return (node_first ? 1 + getNumNodes(node_first->next) : 0);
-}
-
-void dumpList(ListNode *node_first)
-{
- ListNode *node = node_first;
-
- while (node)
- {
- printf("['%s' (%d)]\n", node->key,
- ((SoundInfo *)node->content)->num_references);
- node = node->next;
- }
-
- printf("[%d nodes]\n", getNumNodes(node_first));
-}
-
-static void LoadSoundsInfo()
-{
- char *filename = getCustomSoundConfigFilename();
- struct SetupFileList *setup_file_list;
- int i;
-
-#if 0
- printf("GOT CUSTOM SOUND CONFIG FILE '%s'\n", filename);
-#endif
-
- /* always start with reliable default values */
- for (i=0; i<num_sounds; i++)
- sound_effect[i].filename = NULL;
-
- if (filename == NULL)
- return;
-
- if ((setup_file_list = loadSetupFileList(filename)))
- {
- for (i=0; i<num_sounds; i++)
- sound_effect[i].filename =
- getStringCopy(getTokenValue(setup_file_list, sound_effect[i].text));
-
- freeSetupFileList(setup_file_list);
-
-#if 0
- for (i=0; i<num_sounds; i++)
- {
- printf("'%s' ", sound_effect[i].text);
- if (sound_effect[i].filename)
- printf("-> '%s'\n", sound_effect[i].filename);
- else
- printf("-> UNDEFINED [-> '%s']\n", sound_effect[i].default_filename);
- }
-#endif
- }
-}
-
static void ReloadCustomSounds()
{
- static boolean draw_init_text = TRUE; /* only draw at startup */
- int i;
-
#if 0
- printf("DEBUG: reloading sounds '%s' ...\n",artwork.sounds_set_current_name);
+ printf("DEBUG: reloading sounds '%s' ...\n", artwork.snd_current_identifier);
#endif
- LoadSoundsInfo();
-
- if (draw_init_text)
- DrawInitText("Loading sounds:", 120, FC_GREEN);
+ LoadArtworkConfig(sound_info);
+ ReloadCustomArtworkList(sound_info);
#if 0
- printf("DEBUG: reloading %d sounds ...\n", num_sounds);
-#endif
-
- for(i=0; i<num_sounds; i++)
- {
- if (draw_init_text)
- DrawInitText(sound_effect[i].text, 150, FC_YELLOW);
-
- if (sound_effect[i].filename)
- LoadSoundToList(sound_effect[i].filename, i);
- else
- LoadSoundToList(sound_effect[i].default_filename, i);
- }
-
- draw_init_text = FALSE;
-
- /*
- printf("list size == %d\n", getNumNodes(SoundFileList));
- */
-
-#if 0
- dumpList(SoundFileList);
+ num_sounds = getSoundListSize();
#endif
}
static void ReloadCustomMusic()
{
#if 0
- printf("DEBUG: reloading music '%s' ...\n", artwork.music_set_current_name);
-#endif
-
-#if 0
- /* this is done directly in LoadCustomMusic() now */
- FreeAllMusic();
+ printf("DEBUG: reloading music '%s' ...\n", artwork.mus_current_identifier);
#endif
LoadCustomMusic();
}
-void InitReloadSounds(char *set_name)
+void InitReloadCustomSounds(char *set_identifier)
{
if (!audio.sound_available)
return;
#if defined(AUDIO_UNIX_NATIVE)
- WriteReloadInfoToPipe(set_name, SND_CTRL_RELOAD_SOUNDS);
+ LoadArtworkConfig(sound_info); /* also load config on sound client */
+ WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_SOUNDS);
#else
ReloadCustomSounds();
#endif
}
-void InitReloadMusic(char *set_name)
+void InitReloadCustomMusic(char *set_identifier)
{
if (!audio.music_available)
return;
#if defined(AUDIO_UNIX_NATIVE)
- WriteReloadInfoToPipe(set_name, SND_CTRL_RELOAD_MUSIC);
+ WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_MUSIC);
#else
ReloadCustomMusic();
#endif
void FreeAllSounds()
{
- int i;
-
- if (Sound == NULL)
- return;
-
-#if 0
- printf("%s: FREEING SOUNDS ...\n",
- IS_CHILD_PROCESS(audio.mixer_pid) ? "CHILD" : "PARENT");
-#endif
-
- for(i=0; i<num_sounds; i++)
- deleteSoundEntry(&Sound[i]);
- /*
- FreeSound(Sound[i]);
- */
-
-#if 0
- printf("%s: FREEING SOUNDS -- DONE\n",
- IS_CHILD_PROCESS(audio.mixer_pid) ? "CHILD" : "PARENT");
-#endif
-
- free(Sound);
-
- Sound = NULL;
- num_sounds = 0;
+ FreeCustomArtworkLists(sound_info);
}
void FreeAllMusic()
#ifndef SOUND_H
#define SOUND_H
-#include "platform.h"
+#include "system.h"
#if defined(PLATFORM_UNIX) && !defined(TARGET_SDL)
#define AUDIO_FRAGMENT_SIZE_1024 1024
#define AUDIO_FRAGMENT_SIZE_2048 2048
#define AUDIO_FRAGMENT_SIZE_4096 4096
+#define AUDIO_FRAGMENT_SIZE_32768 32768
#define AUDIO_NUM_CHANNELS_MONO 1
#define AUDIO_NUM_CHANNELS_STEREO 2
#define DEFAULT_AUDIO_SAMPLE_RATE AUDIO_SAMPLE_RATE_22050
#endif
-#if defined(PLATFORM_WIN32)
-#define DEFAULT_AUDIO_FRAGMENT_SIZE AUDIO_FRAGMENT_SIZE_2048
+#if defined(PLATFORM_HPUX)
+#define DEFAULT_AUDIO_FRAGMENT_SIZE AUDIO_FRAGMENT_SIZE_32768
+#elif defined(PLATFORM_WIN32)
+#define DEFAULT_AUDIO_FRAGMENT_SIZE AUDIO_FRAGMENT_SIZE_1024
#else
#define DEFAULT_AUDIO_FRAGMENT_SIZE AUDIO_FRAGMENT_SIZE_512
#endif
#define SOUND_MAX_LEFT2RIGHT 255
#define SOUND_MIDDLE (SOUND_MAX_LEFT2RIGHT / 2)
-/* value for undefined sound effect filename */
-#define SND_FILE_UNDEFINED "NONE"
-
-
-struct SoundEffectInfo
-{
- char *text;
- char *default_filename;
-
- char *filename;
-};
-
/* general sound functions */
void UnixOpenAudio(void);
void StopSound(int);
void StopSounds(void);
void StopSoundExt(int, int);
-void InitSoundList(struct SoundEffectInfo *, int);
-void InitReloadSounds(char *);
-void InitReloadMusic(char *);
+
+int getSoundListSize();
+struct FileInfo *getSoundListEntry(int);
+int getSoundListPropertyMappingSize();
+struct PropertyMapping *getSoundListPropertyMapping();
+void InitSoundList(struct ConfigInfo *, int, struct ConfigInfo *,
+ char **, char **, char **, char **, char **);
+void InitReloadCustomSounds(char *);
+void InitReloadCustomMusic(char *);
void FreeAllSounds(void);
void FreeAllMusic(void);
/* init/close functions */
/* ========================================================================= */
-void InitCommandName(char *argv0)
+void InitProgramInfo(char *argv0,
+ char *userdata_directory, char *program_title,
+ char *window_title, char *icon_title,
+ char *x11_icon_filename, char *x11_iconmask_filename,
+ char *msdos_cursor_filename,
+ char *cookie_prefix, char *filename_prefix,
+ int program_version)
{
program.command_basename =
(strrchr(argv0, '/') ? strrchr(argv0, '/') + 1 : argv0);
+
+ program.userdata_directory = userdata_directory;
+ program.program_title = program_title;
+ program.window_title = window_title;
+ program.icon_title = icon_title;
+ program.x11_icon_filename = x11_icon_filename;
+ program.x11_iconmask_filename = x11_iconmask_filename;
+ program.msdos_cursor_filename = msdos_cursor_filename;
+
+ program.cookie_prefix = cookie_prefix;
+ program.filename_prefix = filename_prefix;
+
+ program.version_major = VERSION_MAJOR(program_version);
+ program.version_minor = VERSION_MINOR(program_version);
+ program.version_patch = VERSION_PATCH(program_version);
}
void InitExitFunction(void (*exit_function)(int))
#endif
}
-void InitPlatformDependantStuff(void)
+void InitPlatformDependentStuff(void)
{
#if defined(PLATFORM_MSDOS)
_fmode = O_BINARY;
-#endif
-
-#if !defined(PLATFORM_UNIX)
- program.userdata_directory = "userdata";
-#endif
-
-#if defined(PLATFORM_MSDOS)
initErrorFile();
#endif
#endif
}
-void ClosePlatformDependantStuff(void)
+void ClosePlatformDependentStuff(void)
{
#if defined(PLATFORM_MSDOS)
dumpErrorFile();
#endif
}
-void InitProgramInfo(char *unix_userdata_directory, char *program_title,
- char *window_title, char *icon_title,
- char *x11_icon_filename, char *x11_iconmask_filename,
- char *msdos_pointer_filename,
- char *cookie_prefix, char *filename_prefix,
- int program_version)
-{
-#if defined(PLATFORM_UNIX)
- program.userdata_directory = unix_userdata_directory;
-#else
- program.userdata_directory = "userdata";
-#endif
-
- program.program_title = program_title;
- program.window_title = window_title;
- program.icon_title = icon_title;
- program.x11_icon_filename = x11_icon_filename;
- program.x11_iconmask_filename = x11_iconmask_filename;
- program.msdos_pointer_filename = msdos_pointer_filename;
-
- program.cookie_prefix = cookie_prefix;
- program.filename_prefix = filename_prefix;
-
- program.version_major = VERSION_MAJOR(program_version);
- program.version_minor = VERSION_MINOR(program_version);
- program.version_patch = VERSION_PATCH(program_version);
-}
-
void InitGfxFieldInfo(int sx, int sy, int sxsize, int sysize,
int real_sx, int real_sy,
- int full_sxsize, int full_sysize)
+ int full_sxsize, int full_sysize,
+ Bitmap *field_save_buffer)
{
gfx.sx = sx;
gfx.sy = sy;
gfx.full_sxsize = full_sxsize;
gfx.full_sysize = full_sysize;
+ gfx.field_save_buffer = field_save_buffer;
+
+ gfx.background_bitmap = NULL;
+ gfx.background_bitmap_mask = REDRAW_NONE;
+
SetDrawDeactivationMask(REDRAW_NONE); /* do not deactivate drawing */
+ SetDrawBackgroundMask(REDRAW_NONE); /* deactivate masked drawing */
}
void InitGfxDoor1Info(int dx, int dy, int dxsize, int dysize)
gfx.draw_deactivation_mask = draw_deactivation_mask;
}
+void SetDrawBackgroundMask(int draw_background_mask)
+{
+ gfx.draw_background_mask = draw_background_mask;
+}
+
+static void DrawBitmapFromTile(Bitmap *bitmap, Bitmap *tile,
+ int dest_x, int dest_y, int width, int height)
+{
+ int bitmap_xsize = width;
+ int bitmap_ysize = height;
+ int tile_xsize = tile->width;
+ int tile_ysize = tile->height;
+ int tile_xsteps = (bitmap_xsize + tile_xsize - 1) / tile_xsize;
+ int tile_ysteps = (bitmap_ysize + tile_ysize - 1) / tile_ysize;
+ int x, y;
+
+ for (y=0; y < tile_ysteps; y++)
+ {
+ for (x=0; x < tile_xsteps; x++)
+ {
+ int draw_x = dest_x + x * tile_xsize;
+ int draw_y = dest_y + y * tile_ysize;
+ int draw_xsize = MIN(tile_xsize, bitmap_xsize - x * tile_xsize);
+ int draw_ysize = MIN(tile_ysize, bitmap_ysize - y * tile_ysize);
+
+ BlitBitmap(tile, bitmap, 0, 0, draw_xsize, draw_ysize, draw_x, draw_y);
+ }
+ }
+}
+
+void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask)
+{
+ static Bitmap *main_bitmap_tile = NULL;
+ static Bitmap *door_bitmap_tile = NULL;
+
+ if (mask == REDRAW_FIELD)
+ {
+ if (background_bitmap_tile == main_bitmap_tile)
+ return; /* main background tile has not changed */
+
+ main_bitmap_tile = background_bitmap_tile;
+ }
+ else if (mask == REDRAW_DOOR_1)
+ {
+ if (background_bitmap_tile == door_bitmap_tile)
+ return; /* main background tile has not changed */
+
+ door_bitmap_tile = background_bitmap_tile;
+ }
+ else /* should not happen */
+ return;
+
+ if (background_bitmap_tile)
+ gfx.background_bitmap_mask |= mask;
+ else
+ gfx.background_bitmap_mask &= ~mask;
+
+ if (gfx.background_bitmap == NULL)
+ gfx.background_bitmap = CreateBitmap(video.width, video.height,
+ DEFAULT_DEPTH);
+
+ if (background_bitmap_tile == NULL) /* empty background requested */
+ return;
+
+ if (mask == REDRAW_FIELD)
+ DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile,
+ gfx.real_sx, gfx.real_sy,
+ gfx.full_sxsize, gfx.full_sysize);
+ else
+ DrawBitmapFromTile(gfx.background_bitmap, background_bitmap_tile,
+ gfx.dx, gfx.dy,
+ gfx.dxsize, gfx.dysize);
+}
+
+void SetMainBackgroundBitmap(Bitmap *background_bitmap_tile)
+{
+ SetBackgroundBitmap(background_bitmap_tile, REDRAW_FIELD);
+}
+
+void SetDoorBackgroundBitmap(Bitmap *background_bitmap_tile)
+{
+ SetBackgroundBitmap(background_bitmap_tile, REDRAW_DOOR_1);
+}
+
/* ========================================================================= */
/* video functions */
return (depth == DEFAULT_DEPTH ? video.default_depth : depth);
}
+inline static void sysFillRectangle(Bitmap *bitmap, int x, int y,
+ int width, int height, Pixel color)
+{
+#if defined(TARGET_SDL)
+ SDLFillRectangle(bitmap, x, y, width, height, color);
+#else
+ X11FillRectangle(bitmap, x, y, width, height, color);
+#endif
+}
+
+inline static void sysCopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap,
+ int src_x, int src_y, int width, int height,
+ int dst_x, int dst_y, int mask_mode)
+{
+#if defined(TARGET_SDL)
+ SDLCopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
+ dst_x, dst_y, mask_mode);
+#else
+ X11CopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
+ dst_x, dst_y, mask_mode);
+#endif
+}
+
inline void InitVideoDisplay(void)
{
#if defined(TARGET_SDL)
#if defined(TARGET_SDL)
SDL_QuitSubSystem(SDL_INIT_VIDEO);
#else
-
if (display)
XCloseDisplay(display);
#endif
video.fullscreen_available = FULLSCREEN_STATUS;
video.fullscreen_enabled = FALSE;
-#ifdef TARGET_SDL
+#if defined(TARGET_SDL)
SDLInitVideoBuffer(backbuffer, window, fullscreen);
#else
X11InitVideoBuffer(backbuffer, window);
inline Bitmap *CreateBitmapStruct(void)
{
-#ifdef TARGET_SDL
+#if defined(TARGET_SDL)
return checked_calloc(sizeof(struct SDLSurfaceInfo));
#else
return checked_calloc(sizeof(struct X11DrawableInfo));
Bitmap *new_bitmap = CreateBitmapStruct();
int real_depth = GetRealDepth(depth);
-#ifdef TARGET_SDL
- SDL_Surface *surface_tmp, *surface_native;
-
- if ((surface_tmp = SDL_CreateRGBSurface(SURFACE_FLAGS, width, height,
- real_depth, 0, 0, 0, 0))
- == NULL)
- Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError());
-
- if ((surface_native = SDL_DisplayFormat(surface_tmp)) == NULL)
- Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s", SDL_GetError());
-
- SDL_FreeSurface(surface_tmp);
-
- new_bitmap->surface = surface_native;
+#if defined(TARGET_SDL)
+ SDLCreateBitmapContent(new_bitmap, width, height, real_depth);
#else
- Pixmap pixmap;
-
- if ((pixmap = XCreatePixmap(display, window->drawable,
- width, height, real_depth))
- == None)
- Error(ERR_EXIT, "cannot create pixmap");
-
- new_bitmap->drawable = pixmap;
-
- if (window == NULL)
- Error(ERR_EXIT, "Window GC needed for Bitmap -- create Window first");
-
- new_bitmap->gc = window->gc;
-
- new_bitmap->line_gc[0] = window->line_gc[0];
- new_bitmap->line_gc[1] = window->line_gc[1];
+ X11CreateBitmapContent(new_bitmap, width, height, real_depth);
#endif
+ new_bitmap->width = width;
+ new_bitmap->height = height;
+
return new_bitmap;
}
if (bitmap == NULL)
return;
-#ifdef TARGET_SDL
- if (bitmap->surface)
- SDL_FreeSurface(bitmap->surface);
- if (bitmap->surface_masked)
- SDL_FreeSurface(bitmap->surface_masked);
- bitmap->surface = NULL;
- bitmap->surface_masked = NULL;
+#if defined(TARGET_SDL)
+ SDLFreeBitmapPointers(bitmap);
#else
- /* The X11 version seems to have a memory leak here -- although
- "XFreePixmap()" is called, the correspondig memory seems not
- to be freed (according to "ps"). The SDL version apparently
- does not have this problem. */
-
- if (bitmap->drawable)
- XFreePixmap(display, bitmap->drawable);
- if (bitmap->clip_mask)
- XFreePixmap(display, bitmap->clip_mask);
- if (bitmap->stored_clip_gc)
- XFreeGC(display, bitmap->stored_clip_gc);
- /* the other GCs are only pointers to GCs used elsewhere */
- bitmap->drawable = None;
- bitmap->clip_mask = None;
- bitmap->stored_clip_gc = None;
+ X11FreeBitmapPointers(bitmap);
#endif
if (bitmap->source_filename)
inline void CloseWindow(DrawWindow *window)
{
-#ifdef TARGET_X11
+#if defined(TARGET_X11)
if (window->drawable)
{
XUnmapWindow(display, window->drawable);
#endif
}
-inline boolean DrawingDeactivated(int x, int y, int width, int height)
+static inline boolean CheckDrawingArea(int x, int y, int width, int height,
+ int draw_mask)
{
- if (gfx.draw_deactivation_mask != REDRAW_NONE)
- {
- if ((gfx.draw_deactivation_mask & REDRAW_FIELD) &&
- x < gfx.sx + gfx.sxsize)
- return TRUE;
- else if ((gfx.draw_deactivation_mask & REDRAW_DOORS) &&
- x > gfx.dx)
- {
- if ((gfx.draw_deactivation_mask & REDRAW_DOOR_1) &&
- y < gfx.dy + gfx.dysize)
- return TRUE;
- else if ((gfx.draw_deactivation_mask & REDRAW_DOOR_2) &&
- y > gfx.vy)
- return TRUE;
- }
- }
+ if (draw_mask == REDRAW_NONE)
+ return FALSE;
+
+ if (draw_mask & REDRAW_ALL)
+ return TRUE;
+
+ if ((draw_mask & REDRAW_FIELD) && x < gfx.real_sx + gfx.full_sxsize)
+ return TRUE;
+
+ if ((draw_mask & REDRAW_DOOR_1) && x >= gfx.dx && y < gfx.dy + gfx.dysize)
+ return TRUE;
+
+ if ((draw_mask & REDRAW_DOOR_2) && x >= gfx.dx && y >= gfx.vy)
+ return TRUE;
return FALSE;
}
+inline boolean DrawingDeactivated(int x, int y, int width, int height)
+{
+ return CheckDrawingArea(x, y, width, height, gfx.draw_deactivation_mask);
+}
+
+inline boolean DrawingOnBackground(int x, int y)
+{
+ return ((gfx.draw_background_mask & gfx.background_bitmap_mask) &&
+ CheckDrawingArea(x, y, 1, 1, gfx.draw_background_mask));
+}
+
inline void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap,
- int src_x, int src_y,
- int width, int height,
+ int src_x, int src_y, int width, int height,
int dst_x, int dst_y)
{
if (DrawingDeactivated(dst_x, dst_y, width, height))
return;
-#ifdef TARGET_SDL
- SDLCopyArea(src_bitmap, dst_bitmap,
- src_x, src_y, width, height, dst_x, dst_y, SDLCOPYAREA_OPAQUE);
-#else
- XCopyArea(display, src_bitmap->drawable, dst_bitmap->drawable,
- dst_bitmap->gc, src_x, src_y, width, height, dst_x, dst_y);
-#endif
+ sysCopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
+ dst_x, dst_y, BLIT_OPAQUE);
}
-inline void ClearRectangle(Bitmap *bitmap, int x, int y, int width, int height)
+inline void FillRectangle(Bitmap *bitmap, int x, int y, int width, int height,
+ Pixel color)
{
if (DrawingDeactivated(x, y, width, height))
return;
-#ifdef TARGET_SDL
- SDLFillRectangle(bitmap, x, y, width, height, 0x000000);
-#else
- XFillRectangle(display, bitmap->drawable, bitmap->gc, x, y, width, height);
-#endif
+ sysFillRectangle(bitmap, x, y, width, height, color);
+}
+
+inline void ClearRectangle(Bitmap *bitmap, int x, int y, int width, int height)
+{
+ FillRectangle(bitmap, x, y, width, height, BLACK_PIXEL);
+}
+
+inline void ClearRectangleOnBackground(Bitmap *bitmap, int x, int y,
+ int width, int height)
+{
+ if (DrawingOnBackground(x, y))
+ BlitBitmap(gfx.background_bitmap, bitmap, x, y, width, height, x, y);
+ else
+ ClearRectangle(bitmap, x, y, width, height);
}
#if 0
inline void SetClipMask(Bitmap *bitmap, GC clip_gc, Pixmap clip_pixmap)
{
-#ifdef TARGET_X11
+#if defined(TARGET_X11)
if (clip_gc)
{
bitmap->clip_gc = clip_gc;
inline void SetClipOrigin(Bitmap *bitmap, GC clip_gc, int clip_x, int clip_y)
{
-#ifdef TARGET_X11
+#if defined(TARGET_X11)
if (clip_gc)
{
bitmap->clip_gc = clip_gc;
if (DrawingDeactivated(dst_x, dst_y, width, height))
return;
-#ifdef TARGET_SDL
- SDLCopyArea(src_bitmap, dst_bitmap,
- src_x, src_y, width, height, dst_x, dst_y, SDLCOPYAREA_MASKED);
-#else
- XCopyArea(display, src_bitmap->drawable, dst_bitmap->drawable,
- src_bitmap->clip_gc, src_x, src_y, width, height, dst_x, dst_y);
-#endif
+ sysCopyArea(src_bitmap, dst_bitmap, src_x, src_y, width, height,
+ dst_x, dst_y, BLIT_MASKED);
+}
+
+inline void BlitBitmapOnBackground(Bitmap *src_bitmap, Bitmap *dst_bitmap,
+ int src_x, int src_y,
+ int width, int height,
+ int dst_x, int dst_y)
+{
+ if (DrawingOnBackground(dst_x, dst_y))
+ {
+ /* draw background */
+ BlitBitmap(gfx.background_bitmap, dst_bitmap, dst_x, dst_y, width, height,
+ dst_x, dst_y);
+
+ /* draw foreground */
+ SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(src_bitmap, dst_bitmap, src_x, src_y, width, height,
+ dst_x, dst_y);
+ }
+ else
+ BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, width, height,
+ dst_x, dst_y);
}
inline void DrawSimpleWhiteLine(Bitmap *bitmap, int from_x, int from_y,
int to_x, int to_y)
{
-#ifdef TARGET_SDL
- SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, 0xffffff);
+#if defined(TARGET_SDL)
+ SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, WHITE_PIXEL);
#else
- XSetForeground(display, bitmap->gc, WhitePixel(display, screen));
- XDrawLine(display, bitmap->drawable, bitmap->gc, from_x, from_y, to_x, to_y);
- XSetForeground(display, bitmap->gc, BlackPixel(display, screen));
+ X11DrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, WHITE_PIXEL);
#endif
}
XSetForeground(display, bitmap->line_gc[1], pixel);
XDrawLines(display, bitmap->drawable, bitmap->line_gc[1],
(XPoint *)points, num_points, CoordModeOrigin);
- /*
- XSetForeground(display, gc, BlackPixel(display, screen));
- */
#endif
}
inline Pixel GetPixel(Bitmap *bitmap, int x, int y)
{
+ if (x < 0 || x >= bitmap->width ||
+ y < 0 || y >= bitmap->height)
+ return BLACK_PIXEL;
+
#if defined(TARGET_SDL)
return SDLGetPixel(bitmap, x, y);
#elif defined(TARGET_ALLEGRO)
return AllegroGetPixel(bitmap->drawable, x, y);
#else
- unsigned long pixel_value;
- XImage *pixel_image;
-
- pixel_image = XGetImage(display, bitmap->drawable, x, y, 1, 1,
- AllPlanes, ZPixmap);
- pixel_value = XGetPixel(pixel_image, 0, 0);
-
- XDestroyImage(pixel_image);
-
- return pixel_value;
+ return X11GetPixel(bitmap, x, y);
#endif
}
inline Pixel GetPixelFromRGB(Bitmap *bitmap, unsigned int color_r,
unsigned int color_g, unsigned int color_b)
{
- Pixel pixel;
-
#if defined(TARGET_SDL)
- pixel = SDL_MapRGB(bitmap->surface->format, color_r, color_g, color_b);
+ return SDL_MapRGB(bitmap->surface->format, color_r, color_g, color_b);
#elif defined(TARGET_ALLEGRO)
- pixel = AllegroAllocColorCell(color_r << 8, color_g << 8, color_b << 8);
-#elif defined(TARGET_X11_NATIVE)
- XColor xcolor;
-
- xcolor.flags = DoRed | DoGreen | DoBlue;
- xcolor.red = (color_r << 8);
- xcolor.green = (color_g << 8);
- xcolor.blue = (color_b << 8);
- XAllocColor(display, cmap, &xcolor);
- pixel = xcolor.pixel;
+ return AllegroAllocColorCell(color_r << 8, color_g << 8, color_b << 8);
+#else
+ return X11GetPixelFromRGB(color_r, color_g, color_b);
#endif
-
- return pixel;
}
inline Pixel GetPixelFromRGBcompact(Bitmap *bitmap, unsigned int color)
inline void KeyboardAutoRepeatOn(void)
{
-#ifdef TARGET_SDL
+#if defined(TARGET_SDL)
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY / 2,
SDL_DEFAULT_REPEAT_INTERVAL / 2);
SDL_EnableUNICODE(1);
inline void KeyboardAutoRepeatOff(void)
{
-#ifdef TARGET_SDL
+#if defined(TARGET_SDL)
SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
SDL_EnableUNICODE(0);
#else
inline boolean PointerInWindow(DrawWindow *window)
{
-#ifdef TARGET_SDL
+#if defined(TARGET_SDL)
return TRUE;
#else
Window root, child;
inline boolean SetVideoMode(boolean fullscreen)
{
-#ifdef TARGET_SDL
+#if defined(TARGET_SDL)
return SDLSetVideoMode(&backbuffer, fullscreen);
#else
boolean success = TRUE;
inline boolean ChangeVideoModeIfNeeded(boolean fullscreen)
{
-#ifdef TARGET_SDL
+#if defined(TARGET_SDL)
if ((fullscreen && !video.fullscreen_enabled && video.fullscreen_available)||
(!fullscreen && video.fullscreen_enabled))
fullscreen = SetVideoMode(fullscreen);
if (bitmap->width != new_bitmap->width ||
bitmap->height != new_bitmap->height)
{
- Error(ERR_WARN, "ReloadCustomImage: new image has wrong dimensions");
+ Error(ERR_WARN, "ReloadCustomImage: new image '%s' has wrong dimensions",
+ filename);
FreeBitmap(new_bitmap);
return;
}
free(new_bitmap);
}
+Bitmap *ZoomBitmap(Bitmap *src_bitmap, int zoom_width, int zoom_height)
+{
+ Bitmap *dst_bitmap = CreateBitmap(zoom_width, zoom_height, DEFAULT_DEPTH);
+
+#if defined(TARGET_SDL)
+ SDLZoomBitmap(src_bitmap, dst_bitmap);
+#else
+ X11ZoomBitmap(src_bitmap, dst_bitmap);
+#endif
+
+ return dst_bitmap;
+}
+
+void CreateBitmapWithSmallBitmaps(Bitmap *src_bitmap)
+{
+ Bitmap *tmp_bitmap, *tmp_bitmap_2, *tmp_bitmap_8;
+ int src_width, src_height;
+ int tmp_width, tmp_height;
+
+ src_width = src_bitmap->width;
+ src_height = src_bitmap->height;
+
+ tmp_width = src_width;
+ tmp_height = src_height + (src_height + 1) / 2; /* prevent odd height */
+
+ tmp_bitmap = CreateBitmap(tmp_width, tmp_height, DEFAULT_DEPTH);
+
+ tmp_bitmap_2 = ZoomBitmap(src_bitmap, src_width / 2, src_height / 2);
+ tmp_bitmap_8 = ZoomBitmap(src_bitmap, src_width / 8, src_height / 8);
+
+ 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);
+
+ FreeBitmap(tmp_bitmap_2);
+ FreeBitmap(tmp_bitmap_8);
+
+#if defined(TARGET_SDL)
+ /* !!! what about the old src_bitmap->surface ??? FIX ME !!! */
+ src_bitmap->surface = tmp_bitmap->surface;
+ tmp_bitmap->surface = NULL;
+#else
+ /* !!! see above !!! */
+ src_bitmap->drawable = tmp_bitmap->drawable;
+ tmp_bitmap->drawable = None;
+#endif
+
+ src_bitmap->height = tmp_bitmap->height;
+
+ FreeBitmap(tmp_bitmap);
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* mouse pointer functions */
+/* ------------------------------------------------------------------------- */
+
+#if !defined(PLATFORM_MSDOS)
+/* XPM */
+static const char *cursor_image_playfield[] =
+{
+ /* width height num_colors chars_per_pixel */
+ " 16 16 3 1",
+
+ /* colors */
+ "X c #000000",
+ ". c #ffffff",
+ " c None",
+
+ /* pixels */
+ " X ",
+ "X.X ",
+ " X ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+
+ /* hot spot */
+ "1,1"
+};
+
+#if defined(TARGET_SDL)
+static const int cursor_bit_order = BIT_ORDER_MSB;
+#elif defined(TARGET_X11_NATIVE)
+static const int cursor_bit_order = BIT_ORDER_LSB;
+#endif
+
+static struct MouseCursorInfo *get_cursor_from_image(const char **image)
+{
+ struct MouseCursorInfo *cursor;
+ boolean bit_order_msb = (cursor_bit_order == BIT_ORDER_MSB);
+ int header_lines = 4;
+ int x, y, i;
+
+ cursor = checked_calloc(sizeof(struct MouseCursorInfo));
+
+ sscanf(image[0], " %d %d ", &cursor->width, &cursor->height);
+
+ i = -1;
+ for (y=0; y < cursor->width; y++)
+ {
+ for (x=0; x < cursor->height; x++)
+ {
+ int bit_nr = x % 8;
+ int bit_mask = 0x01 << (bit_order_msb ? 7 - bit_nr : bit_nr );
+
+ if (bit_nr == 0)
+ {
+ i++;
+ cursor->data[i] = cursor->mask[i] = 0;
+ }
+
+ switch (image[header_lines + y][x])
+ {
+ case 'X':
+ cursor->data[i] |= bit_mask;
+ cursor->mask[i] |= bit_mask;
+ break;
+
+ case '.':
+ cursor->mask[i] |= bit_mask;
+ break;
+
+ case ' ':
+ break;
+ }
+ }
+ }
+
+ sscanf(image[header_lines + y], "%d,%d", &cursor->hot_x, &cursor->hot_y);
+
+ return cursor;
+}
+#endif /* !PLATFORM_MSDOS */
+
+void SetMouseCursor(int mode)
+{
+#if !defined(PLATFORM_MSDOS)
+ static struct MouseCursorInfo *cursor_playfield = NULL;
+
+ if (cursor_playfield == NULL)
+ cursor_playfield = get_cursor_from_image(cursor_image_playfield);
+
+#if defined(TARGET_SDL)
+ SDLSetMouseCursor(mode == CURSOR_PLAYFIELD ? cursor_playfield : NULL);
+#elif defined(TARGET_X11_NATIVE)
+ X11SetMouseCursor(mode == CURSOR_PLAYFIELD ? cursor_playfield : NULL);
+#endif
+#endif
+}
+
/* ========================================================================= */
/* audio functions */
audio.sound_deactivated = FALSE;
audio.mixer_pipe[0] = audio.mixer_pipe[1] = 0;
- audio.mixer_pid = -1;
+ audio.mixer_pid = 0;
audio.device_name = NULL;
audio.device_fd = -1;
inline void InitEventFilter(EventFilter filter_function)
{
-#ifdef TARGET_SDL
+#if defined(TARGET_SDL)
/* set event filter to filter out certain events */
SDL_SetEventFilter(filter_function);
#endif
inline boolean PendingEvent(void)
{
-#ifdef TARGET_SDL
+#if defined(TARGET_SDL)
return (SDL_PollEvent(NULL) ? TRUE : FALSE);
#else
return (XPending(display) ? TRUE : FALSE);
inline void NextEvent(Event *event)
{
-#ifdef TARGET_SDL
+#if defined(TARGET_SDL)
SDLNextEvent(event);
#else
XNextEvent(display, event);
inline Key GetEventKey(KeyEvent *event, boolean with_modifiers)
{
-#ifdef TARGET_SDL
+#if defined(TARGET_SDL)
#if 0
printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n",
(int)event->keysym.unicode,
#endif
}
+inline KeyMod HandleKeyModState(Key key, int key_status)
+{
+ static KeyMod current_modifiers = KMOD_None;
+
+#if !defined(TARGET_SDL)
+ if (key != KSYM_UNDEFINED) /* new key => check for modifier key change */
+ {
+ KeyMod new_modifier = KMOD_None;
+
+ switch(key)
+ {
+ case KSYM_Shift_L:
+ new_modifier = KMOD_Shift_L;
+ break;
+ case KSYM_Shift_R:
+ new_modifier = KMOD_Shift_R;
+ break;
+ case KSYM_Control_L:
+ new_modifier = KMOD_Control_L;
+ break;
+ case KSYM_Control_R:
+ new_modifier = KMOD_Control_R;
+ break;
+ case KSYM_Meta_L:
+ new_modifier = KMOD_Meta_L;
+ break;
+ case KSYM_Meta_R:
+ new_modifier = KMOD_Meta_R;
+ break;
+ case KSYM_Alt_L:
+ new_modifier = KMOD_Alt_L;
+ break;
+ case KSYM_Alt_R:
+ new_modifier = KMOD_Alt_R;
+ break;
+ default:
+ break;
+ }
+
+ if (key_status == KEY_PRESSED)
+ current_modifiers |= new_modifier;
+ else
+ current_modifiers &= ~new_modifier;
+ }
+#endif
+
+ return current_modifiers;
+}
+
+inline KeyMod GetKeyModState()
+{
+#if defined(TARGET_SDL)
+ return (KeyMod)SDL_GetModState();
+#else
+ return HandleKeyModState(KSYM_UNDEFINED, 0);
+#endif
+}
+
inline boolean CheckCloseWindowEvent(ClientMessageEvent *event)
{
if (event->type != EVENT_CLIENTMESSAGE)
{
int i;
-#ifdef NO_JOYSTICK
+#if defined(NO_JOYSTICK)
return; /* joysticks generally deactivated by compile-time directive */
#endif
#include "platform.h"
#include "types.h"
-#if defined(PLATFORM_MSDOS)
+
+#if defined(PLATFORM_MACOSX)
+#include "macosx.h"
+#elif defined(PLATFORM_WIN32)
+#include "windows.h"
+#elif defined(PLATFORM_MSDOS)
#include "msdos.h"
#endif
#include "x11.h"
#endif
-#if defined(PLATFORM_MACOSX)
-/* some symbols are already defined on Mac OS X */
-#define Delay Delay_internal
-#define DrawLine DrawLine_internal
-#define DrawText DrawText_internal
-#define GetPixel GetPixel_internal
-#endif
-
/* the additional 'b' is needed for Win32 to open files in binary mode */
#define MODE_READ "rb"
#define DEFAULT_DEPTH 0
+#define BLIT_OPAQUE 0
+#define BLIT_MASKED 1
+#define BLIT_INVERSE 2
+#define BLIT_ON_BACKGROUND 3
+
#define FULLSCREEN_NOT_AVAILABLE FALSE
#define FULLSCREEN_AVAILABLE TRUE
#define DEFAULT_KEY_LOAD_GAME KSYM_F2
#define DEFAULT_KEY_TOGGLE_PAUSE KSYM_space
-/* values for move directions and special "button" keys */
-#define MV_NO_MOVING 0
-#define MV_LEFT (1 << 0)
-#define MV_RIGHT (1 << 1)
-#define MV_UP (1 << 2)
-#define MV_DOWN (1 << 3)
-#define KEY_BUTTON_1 (1 << 4)
-#define KEY_BUTTON_2 (1 << 5)
-#define KEY_MOTION (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)
-#define KEY_BUTTON (KEY_BUTTON_1 | KEY_BUTTON_2)
-#define KEY_ACTION (KEY_MOTION | KEY_BUTTON)
+/* values for key_status */
+#define KEY_NOT_PRESSED FALSE
+#define KEY_RELEASED FALSE
+#define KEY_PRESSED TRUE
/* values for button status */
#define MB_NOT_PRESSED FALSE
#define MB_MIDDLEBUTTON 2
#define MB_RIGHTBUTTON 3
+
+/* values for move directions */
+#define MV_BIT_LEFT 0
+#define MV_BIT_RIGHT 1
+#define MV_BIT_UP 2
+#define MV_BIT_DOWN 3
+
+#define NUM_DIRECTIONS 4
+
+/* values for special "button" bitmasks */
+#define BUTTON_1 4
+#define BUTTON_2 5
+
+/* values for move direction 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 KEY_BUTTON_1 (1 << BUTTON_1)
+#define KEY_BUTTON_2 (1 << BUTTON_2)
+#define KEY_MOTION (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)
+#define KEY_BUTTON (KEY_BUTTON_1 | KEY_BUTTON_2)
+#define KEY_ACTION (KEY_MOTION | KEY_BUTTON)
+
+#define MV_DIR_BIT(x) ((x) == MV_LEFT ? MV_BIT_LEFT : \
+ (x) == MV_RIGHT ? MV_BIT_RIGHT : \
+ (x) == MV_UP ? MV_BIT_UP : MV_BIT_DOWN)
+
+
+/* values for animation mode (frame order and direction) */
+#define ANIM_NONE 0
+#define ANIM_LOOP (1 << 0)
+#define ANIM_LINEAR (1 << 1)
+#define ANIM_PINGPONG (1 << 2)
+#define ANIM_PINGPONG2 (1 << 3)
+#define ANIM_RANDOM (1 << 4)
+#define ANIM_REVERSE (1 << 5)
+
+
/* values for redraw_mask */
#define REDRAW_NONE (0)
#define REDRAW_ALL (1 << 0)
#define REDRAW_FPS (1 << 11)
#define REDRAWTILES_THRESHOLD (SCR_FIELDX * SCR_FIELDY / 2)
+
+/* values for mouse cursor */
+#define CURSOR_DEFAULT 0
+#define CURSOR_PLAYFIELD 1
+
+
/* maximum number of parallel players supported by libgame functions */
#define MAX_PLAYERS 4
/* default name for unknown player names */
#define ANONYMOUS_NAME "anonymous"
+/* default name for new levels */
+#define NAMELESS_LEVEL_NAME "nameless level"
+
/* default text for non-existant artwork */
#define NOT_AVAILABLE "(not available)"
-/* default name for new levels */
-#define NAMELESS_LEVEL_NAME "nameless level"
+/* default value for undefined filename */
+#define UNDEFINED_FILENAME "[NONE]"
+
+/* default value for undefined parameter */
+#define ARG_DEFAULT "[DEFAULT]"
+
+/* default values for undefined configuration file parameters */
+#define ARG_UNDEFINED "-1000000"
+#define ARG_UNDEFINED_VALUE (atoi(ARG_UNDEFINED))
/* definitions for game sub-directories */
#ifndef RO_GAME_DIR
#define LEVELS_DIRECTORY "levels"
#define TAPES_DIRECTORY "tapes"
#define SCORES_DIRECTORY "scores"
+#define DOCS_DIRECTORY "docs"
#if !defined(PLATFORM_MSDOS)
#define GRAPHICS_SUBDIR "gfx_classic"
#define MUSIC_SUBDIR "mus_orig"
#endif
+
/* areas in bitmap PIX_DOOR */
/* meaning in PIX_DB_DOOR: (3 PAGEs)
PAGEX1: 1. buffer for DOOR_1
#define DOOR_GFX_PAGEY1 (0)
#define DOOR_GFX_PAGEY2 (gfx.dysize)
-/* functions for version handling */
-#define VERSION_IDENT(x,y,z) ((x) * 10000 + (y) * 100 + (z))
-#define VERSION_MAJOR(x) ((x) / 10000)
-#define VERSION_MINOR(x) (((x) % 10000) / 100)
-#define VERSION_PATCH(x) ((x) % 100)
-/* functions for parent/child process identification */
-#define IS_PARENT_PROCESS(pid) ((pid) > 0)
-#define IS_CHILD_PROCESS(pid) ((pid) == 0)
+/* macros for version handling */
+#define VERSION_IDENT(x,y,z) ((x) * 1000000 + (y) * 10000 + (z) * 100)
+#define RELEASE_IDENT(x,y,z,r) (VERSION_IDENT(x,y,z) + (r))
+#define VERSION_MAJOR(x) ((x) / 1000000)
+#define VERSION_MINOR(x) (((x) % 1000000) / 10000)
+#define VERSION_PATCH(x) (((x) % 10000) / 100)
+#define VERSION_RELEASE(x) ((x) % 100)
+
+
+/* macros for parent/child process identification */
+#if defined(PLATFORM_UNIX)
+#define IS_PARENT_PROCESS() (audio.mixer_pid != getpid())
+#define IS_CHILD_PROCESS() (audio.mixer_pid == getpid())
+#define HAS_CHILD_PROCESS() (audio.mixer_pid > 0)
+#else
+#define IS_PARENT_PROCESS() TRUE
+#define IS_CHILD_PROCESS() FALSE
+#define HAS_CHILD_PROCESS() FALSE
+#endif
+
+
+/* values for artwork type */
+#define ARTWORK_TYPE_GRAPHICS 0
+#define ARTWORK_TYPE_SOUNDS 1
+#define ARTWORK_TYPE_MUSIC 2
+
+#define NUM_ARTWORK_TYPES 3
+
+
+/* values for tree type (chosen to match artwork type) */
+#define TREE_TYPE_UNDEFINED -1
+#define TREE_TYPE_GRAPHICS_DIR ARTWORK_TYPE_GRAPHICS
+#define TREE_TYPE_SOUNDS_DIR ARTWORK_TYPE_SOUNDS
+#define TREE_TYPE_MUSIC_DIR ARTWORK_TYPE_MUSIC
+#define TREE_TYPE_LEVEL_DIR 3
+
+#define NUM_TREE_TYPES 4
+
+
+/* values for artwork handling */
+#define LEVELDIR_ARTWORK_SET(leveldir, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ (leveldir)->graphics_set : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ (leveldir)->sounds_set : \
+ (leveldir)->music_set)
+
+#define LEVELDIR_ARTWORK_PATH(leveldir, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ (leveldir)->graphics_path : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ (leveldir)->sounds_path : \
+ (leveldir)->music_path)
+
+#define SETUP_ARTWORK_SET(setup, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ (setup).graphics_set : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ (setup).sounds_set : \
+ (setup).music_set)
+
+#define SETUP_OVERRIDE_ARTWORK(setup, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ (setup).override_level_graphics : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ (setup).override_level_sounds : \
+ (setup).override_level_music)
+
+#define ARTWORK_FIRST_NODE(artwork, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ (artwork).gfx_first : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ (artwork).snd_first : \
+ (artwork).mus_first)
+
+#define ARTWORK_CURRENT_IDENTIFIER(artwork, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ (artwork).gfx_current_identifier : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ (artwork).snd_current_identifier : \
+ (artwork).mus_current_identifier)
/* type definitions */
char *x11_icon_filename;
char *x11_iconmask_filename;
- char *msdos_pointer_filename;
+ char *msdos_cursor_filename;
char *cookie_prefix;
char *filename_prefix; /* prefix to cut off from DOS filenames */
char *display_name;
char *server_host;
int server_port;
+
char *ro_base_directory;
char *rw_base_directory;
char *level_directory;
char *graphics_directory;
char *sounds_directory;
char *music_directory;
+ char *docs_directory;
+ char *execute_command;
+
boolean serveronly;
boolean network;
boolean verbose;
boolean debug;
- char *debug_command;
};
struct VideoSystemInfo
int first_sound_channel;
};
+struct FontBitmapInfo
+{
+ Bitmap *bitmap;
+ int src_x, src_y; /* start position of animation frames */
+ int width, height; /* width/height of each animation frame */
+ int draw_x, draw_y; /* offset for drawing font characters */
+ int num_chars;
+ int num_chars_per_line;
+
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ Pixmap *clip_mask; /* single-char-only clip mask array for X11 */
+#endif
+};
+
struct GfxInfo
{
int sx, sy;
int vx, vy;
int vxsize, vysize;
- boolean draw_deactivation_mask;
+ int draw_deactivation_mask;
+ int draw_background_mask;
+
+ Bitmap *field_save_buffer;
+
+ Bitmap *background_bitmap;
+ int background_bitmap_mask;
+
+ int num_fonts;
+ struct FontBitmapInfo *font_bitmap_info;
+ int (*select_font_function)(int);
+
+ int anim_random_frame;
};
struct JoystickInfo
struct SetupKeyboardInfo key;
};
+struct SetupEditorInfo
+{
+ boolean el_boulderdash;
+ boolean el_emerald_mine;
+ boolean el_more;
+ boolean el_sokoban;
+ boolean el_supaplex;
+ boolean el_diamond_caves;
+ boolean el_dx_boulderdash;
+ boolean el_chars;
+ boolean el_custom;
+};
+
struct SetupShortcutInfo
{
Key save_game;
Key toggle_pause;
};
+struct SetupSystemInfo
+{
+ char *sdl_audiodriver;
+ int audio_fragment_size;
+};
+
struct SetupInfo
{
char *player_name;
boolean override_level_sounds;
boolean override_level_music;
+ struct SetupEditorInfo editor;
struct SetupShortcutInfo shortcut;
struct SetupInputInfo input[MAX_PLAYERS];
+ struct SetupSystemInfo system;
+ struct OptionInfo options;
};
-#define TREE_TYPE_GENERIC 0
-#define TREE_TYPE_LEVEL_DIR 1
-#define TREE_TYPE_GRAPHICS_DIR 2
-#define TREE_TYPE_SOUNDS_DIR 3
-#define TREE_TYPE_MUSIC_DIR 4
-
struct TreeInfo
{
struct TreeInfo **node_top; /* topmost node in tree */
/* fields for "type == TREE_TYPE_LEVEL_DIR" */
- char *filename; /* level series single directory name */
- char *fullpath; /* complete path relative to level directory */
- char *basepath; /* absolute base path of level directory */
- char *name; /* level series name, as displayed on main screen */
- char *name_short; /* optional short name for level selection screen */
- char *name_sorting; /* optional sorting name for correct level sorting */
- char *author; /* level series author name levels without author */
- char *imported_from; /* optional comment for imported level series */
+ char *filename; /* tree info sub-directory basename (may be ".") */
+ char *fullpath; /* complete path relative to tree base directory */
+ char *basepath; /* absolute base path of tree base directory */
+ char *identifier; /* identifier string for configuration files */
+ char *name; /* tree info name, as displayed in selection menues */
+ 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 *graphics_set; /* optional custom graphics set (level tree only) */
+ char *sounds_set; /* optional custom sounds set (level tree only) */
+ char *music_set; /* optional custom music set (level tree only) */
+ char *graphics_path; /* path to optional custom graphics set (level only) */
+ char *sounds_path; /* path to optional custom sounds set (level only) */
+ char *music_path; /* path to optional custom music set (level only) */
+
int levels; /* number of levels in level series */
int first_level; /* first level number (to allow start with 0 or 1) */
int last_level; /* last level number (automatically calculated) */
int sort_priority; /* sort levels by 'sort_priority' and then by name */
+
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 readonly; /* readonly levels can not be changed with editor */
+
int color; /* color to use on selection screen for this level */
char *class_desc; /* description of level series class */
int handicap_level; /* number of the lowest unsolved level */
MusicDirTree *mus_first;
MusicDirTree *mus_current;
- char *graphics_set_current_name;
- char *sounds_set_current_name;
- char *music_set_current_name;
+ char *gfx_current_identifier;
+ char *snd_current_identifier;
+ char *mus_current_identifier;
+};
+
+struct ValueTextInfo
+{
+ int value;
+ char *text;
+};
+
+struct ConfigInfo
+{
+ char *token;
+ char *value;
+ int type;
+};
+
+struct TokenIntPtrInfo
+{
+ char *token;
+ int *value;
+};
+
+struct FileInfo
+{
+ char *token;
+
+ char *default_filename;
+ char *filename;
+
+ char **default_parameter; /* array of file parameters */
+ char **parameter; /* array of file parameters */
+
+ boolean redefined;
+};
+
+struct SetupFileList
+{
+ char *token;
+ char *value;
+
+ struct SetupFileList *next;
+};
+
+struct ListNodeInfo
+{
+ char *source_filename; /* primary key for node list */
+ int num_references;
+};
+
+struct PropertyMapping
+{
+ int base_index;
+ int ext1_index;
+ int ext2_index;
+ int ext3_index;
+
+ int artwork_index;
+};
+
+struct ArtworkListInfo
+{
+ int type; /* type of artwork */
+
+ int num_file_list_entries;
+ int num_dynamic_file_list_entries;
+ struct FileInfo *file_list; /* static artwork file array */
+ struct FileInfo *dynamic_file_list; /* dynamic artwrk file array */
+
+ int num_suffix_list_entries;
+ struct ConfigInfo *suffix_list; /* parameter suffixes array */
+
+ int num_base_prefixes;
+ int num_ext1_suffixes;
+ int num_ext2_suffixes;
+ int num_ext3_suffixes;
+ char **base_prefixes; /* base token prefixes array */
+ char **ext1_suffixes; /* property suffixes array 1 */
+ char **ext2_suffixes; /* property suffixes array 2 */
+ char **ext3_suffixes; /* property suffixes array 3 */
+
+ int num_ignore_tokens;
+ char **ignore_tokens; /* file tokens to be ignored */
+
+ int num_property_mapping_entries;
+ struct PropertyMapping *property_mapping; /* mapping token -> artwork */
+
+ int sizeof_artwork_list_entry;
+
+ struct ListNodeInfo **artwork_list; /* static artwork node array */
+ struct ListNodeInfo **dynamic_artwork_list; /* dynamic artwrk node array */
+ struct ListNode *content_list; /* dynamic artwork node list */
+
+ void *(*load_artwork)(char *); /* constructor function */
+ void (*free_artwork)(void *); /* destructor function */
};
extern struct VideoSystemInfo video;
extern struct AudioSystemInfo audio;
extern struct GfxInfo gfx;
+extern struct AnimInfo anim;
extern struct ArtworkInfo artwork;
extern struct JoystickInfo joystick;
extern struct SetupInfo setup;
/* function definitions */
-void InitCommandName(char *);
-void InitExitFunction(void (*exit_function)(int));
-void InitPlatformDependantStuff(void);
-void ClosePlatformDependantStuff(void);
-
void InitProgramInfo(char *, char *, char *, char *, char *, char *, char *,
- char *, char *, int);
+ char *, char *, char *, int);
+
+void InitExitFunction(void (*exit_function)(int));
+void InitPlatformDependentStuff(void);
+void ClosePlatformDependentStuff(void);
-void InitGfxFieldInfo(int, int, int, int, int, int, int, int);
+void InitGfxFieldInfo(int, int, int, int, int, int, int, int, Bitmap *);
void InitGfxDoor1Info(int, int, int, int);
void InitGfxDoor2Info(int, int, int, int);
void InitGfxScrollbufferInfo(int, int);
-void SetDrawDeactivationMask(int );
+void SetDrawDeactivationMask(int);
+void SetDrawBackgroundMask(int);
+void SetMainBackgroundBitmap(Bitmap *);
+void SetDoorBackgroundBitmap(Bitmap *);
inline void InitVideoDisplay(void);
inline void CloseVideoDisplay(void);
inline Bitmap *CreateBitmap(int, int, int);
inline void FreeBitmap(Bitmap *);
inline void BlitBitmap(Bitmap *, Bitmap *, int, int, int, int, int, int);
+inline void FillRectangle(Bitmap *, int, int, int, int, Pixel);
inline void ClearRectangle(Bitmap *, int, int, int, int);
+inline void ClearRectangleOnBackground(Bitmap *, int, int, int, int);
inline void SetClipMask(Bitmap *, GC, Pixmap);
inline void SetClipOrigin(Bitmap *, GC, int, int);
inline void BlitBitmapMasked(Bitmap *, Bitmap *, int, int, int, int, int, int);
+inline boolean DrawingOnBackground(int, int);
+inline void BlitBitmapOnBackground(Bitmap *, Bitmap *, int, int, int, int, int,
+ int);
inline void DrawSimpleWhiteLine(Bitmap *, int, int, int, int);
inline void DrawLines(Bitmap *, struct XY *, int, Pixel);
inline Pixel GetPixel(Bitmap *, int, int);
Bitmap *LoadCustomImage(char *);
void ReloadCustomImage(Bitmap *, char *);
+Bitmap *ZoomBitmap(Bitmap *, int, int);
+void CreateBitmapWithSmallBitmaps(Bitmap *);
+
+void SetMouseCursor(int);
+
inline void OpenAudio(void);
inline void CloseAudio(void);
inline void SetAudioMode(boolean);
inline boolean PendingEvent(void);
inline void NextEvent(Event *event);
inline Key GetEventKey(KeyEvent *, boolean);
+inline KeyMod HandleKeyModState(Key, int);
+inline KeyMod GetKeyModState();
inline boolean CheckCloseWindowEvent(ClientMessageEvent *);
inline void InitJoysticks();
#include <stdarg.h>
#include "text.h"
+#include "misc.h"
/* ========================================================================= */
-/* exported variables */
+/* font functions */
/* ========================================================================= */
-struct FontInfo font;
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+static GC font_clip_gc = None;
+
+static void InitFontClipmasks()
+{
+ XGCValues clip_gc_values;
+ unsigned long clip_gc_valuemask;
+ GC copy_clipmask_gc;
+ int i, j;
+
+ /* This stuff is needed because X11 (XSetClipOrigin(), to be precise) is
+ often very slow when preparing a masked XCopyArea() for big Pixmaps.
+ To prevent this, create small (tile-sized) mask Pixmaps which will then
+ be set much faster with XSetClipOrigin() and speed things up a lot. */
+
+ clip_gc_values.graphics_exposures = False;
+ clip_gc_valuemask = GCGraphicsExposures;
+ font_clip_gc = XCreateGC(display, window->drawable,
+ clip_gc_valuemask, &clip_gc_values);
+
+ /* create graphic context structures needed for clipping */
+ clip_gc_values.graphics_exposures = False;
+ clip_gc_valuemask = GCGraphicsExposures;
+ copy_clipmask_gc = XCreateGC(display,
+ gfx.font_bitmap_info[0].bitmap->clip_mask,
+ clip_gc_valuemask, &clip_gc_values);
+
+ /* create only those clipping Pixmaps we really need */
+ for (i=0; i < gfx.num_fonts; i++)
+ {
+ if (gfx.font_bitmap_info[i].bitmap == NULL)
+ continue;
+ gfx.font_bitmap_info[i].clip_mask =
+ checked_calloc(gfx.font_bitmap_info[i].num_chars * sizeof(Pixmap));
-/* ========================================================================= */
-/* font functions */
-/* ========================================================================= */
+ for (j=0; j < gfx.font_bitmap_info[i].num_chars; j++)
+ {
+ Bitmap *src_bitmap = gfx.font_bitmap_info[i].bitmap;
+ Pixmap src_pixmap = src_bitmap->clip_mask;
+ int xpos = j % gfx.font_bitmap_info[i].num_chars_per_line;
+ int ypos = j / gfx.font_bitmap_info[i].num_chars_per_line;
+ int width = gfx.font_bitmap_info[i].width;
+ int height = gfx.font_bitmap_info[i].height;
+ int src_x = gfx.font_bitmap_info[i].src_x + xpos * width;
+ int src_y = gfx.font_bitmap_info[i].src_y + ypos * height;
+
+ gfx.font_bitmap_info[i].clip_mask[j] =
+ XCreatePixmap(display, window->drawable, width, height, 1);
+
+ XCopyArea(display, src_pixmap, gfx.font_bitmap_info[i].clip_mask[j],
+ copy_clipmask_gc, src_x, src_y, width, height, 0, 0);
+ }
+ }
+
+ XFreeGC(display, copy_clipmask_gc);
+}
+
+static void FreeFontClipmasks()
+{
+ int i, j;
+
+ if (gfx.num_fonts == 0 || gfx.font_bitmap_info[0].bitmap == NULL)
+ return;
+
+ for (i=0; i < gfx.num_fonts; i++)
+ {
+ if (gfx.font_bitmap_info[i].clip_mask)
+ {
+ for (j=0; j < gfx.font_bitmap_info[i].num_chars; j++)
+ XFreePixmap(display, gfx.font_bitmap_info[i].clip_mask[j]);
+ free(gfx.font_bitmap_info[i].clip_mask);
+ }
+
+ gfx.font_bitmap_info[i].clip_mask = NULL;
+ gfx.font_bitmap_info[i].num_chars = 0;
+ }
+
+ if (font_clip_gc)
+ XFreeGC(display, font_clip_gc);
+ font_clip_gc = None;
+}
+#endif /* TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND */
+
+void InitFontInfo(struct FontBitmapInfo *font_bitmap_info, int num_fonts,
+ int (*select_font_function)(int))
+{
+ gfx.num_fonts = num_fonts;
+ gfx.font_bitmap_info = font_bitmap_info;
+ gfx.select_font_function = select_font_function;
+
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ InitFontClipmasks();
+#endif
+}
+
+void FreeFontInfo(struct FontBitmapInfo *font_bitmap_info)
+{
+ if (font_bitmap_info == NULL)
+ return;
-void InitFontInfo(Bitmap *bitmap_big, Bitmap *bitmap_medium,
- Bitmap *bitmap_small)
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ FreeFontClipmasks();
+#endif
+
+ free(font_bitmap_info);
+}
+
+int getFontWidth(int font_nr)
{
- font.bitmap_big = bitmap_big;
- font.bitmap_medium = bitmap_medium;
- font.bitmap_small = bitmap_small;
+ int font_bitmap_id = gfx.select_font_function(font_nr);
+
+ return gfx.font_bitmap_info[font_bitmap_id].width;
}
-int getFontWidth(int font_size, int font_type)
+int getFontHeight(int font_nr)
{
- return (font_size == FS_BIG ? FONT1_XSIZE :
- font_size == FS_MEDIUM ? FONT6_XSIZE :
- font_type == FC_SPECIAL1 ? FONT3_XSIZE :
- font_type == FC_SPECIAL2 ? FONT4_XSIZE :
- font_type == FC_SPECIAL3 ? FONT5_XSIZE :
- FONT2_XSIZE);
+ int font_bitmap_id = gfx.select_font_function(font_nr);
+
+ return gfx.font_bitmap_info[font_bitmap_id].height;
}
-int getFontHeight(int font_size, int font_type)
+static char getFontCharPosition(int font_nr, char c)
{
- return (font_size == FS_BIG ? FONT1_YSIZE :
- font_size == FS_MEDIUM ? FONT6_YSIZE :
- font_type == FC_SPECIAL1 ? FONT3_YSIZE :
- font_type == FC_SPECIAL2 ? FONT4_YSIZE :
- font_type == FC_SPECIAL3 ? FONT5_YSIZE :
- FONT2_YSIZE);
+ int font_bitmap_id = gfx.select_font_function(font_nr);
+ struct FontBitmapInfo *font = &gfx.font_bitmap_info[font_bitmap_id];
+ boolean default_font = (font->num_chars == DEFAULT_NUM_CHARS_PER_FONT);
+ int font_pos = c - 32;
+
+ /* map some special characters to their ascii values in default font */
+ if (default_font)
+ font_pos = MAP_FONT_ASCII(c) - 32;
+
+ /* this allows dynamic special characters together with special font */
+ if (font_pos < 0 || font_pos >= font->num_chars)
+ font_pos = 0;
+
+ return font_pos;
}
-void DrawInitText(char *text, int ypos, int color)
+void getFontCharSource(int font_nr, char c, Bitmap **bitmap, int *x, int *y)
{
- if (window && font.bitmap_small)
+ int font_bitmap_id = gfx.select_font_function(font_nr);
+ struct FontBitmapInfo *font = &gfx.font_bitmap_info[font_bitmap_id];
+ int font_pos = getFontCharPosition(font_nr, c);
+
+ *bitmap = font->bitmap;
+ *x = font->src_x + (font_pos % font->num_chars_per_line) * font->width;
+ *y = font->src_y + (font_pos / font->num_chars_per_line) * font->height;
+}
+
+void DrawInitText(char *text, int ypos, int font_nr)
+{
+ if (window &&
+ gfx.num_fonts > 0 &&
+ gfx.font_bitmap_info[font_nr].bitmap != NULL)
{
- ClearRectangle(window, 0, ypos, video.width, FONT2_YSIZE);
- DrawTextExt(window, (video.width - strlen(text) * FONT2_XSIZE)/2,
- ypos, text, FS_SMALL, color);
+ int text_width = strlen(text) * getFontWidth(font_nr);
+
+ ClearRectangle(window, 0, ypos, video.width, getFontHeight(font_nr));
+ DrawTextExt(window, (video.width - text_width) / 2, ypos, text, font_nr,
+ BLIT_OPAQUE);
FlushDisplay();
}
}
-void DrawTextFCentered(int y, int font_type, char *format, ...)
+void DrawTextFCentered(int y, int font_nr, char *format, ...)
{
char buffer[MAX_OUTPUT_LINESIZE + 1];
- int font_width = getFontWidth(FS_SMALL, font_type);
va_list ap;
va_start(ap, format);
vsprintf(buffer, format, ap);
va_end(ap);
- DrawText(gfx.sx + (gfx.sxsize - strlen(buffer) * font_width) / 2,
- gfx.sy + y, buffer, FS_SMALL, font_type);
+ if (strlen(buffer) > MAX_OUTPUT_LINESIZE)
+ Error(ERR_EXIT, "string too long in DrawTextFCentered() -- aborting");
+
+ DrawText(gfx.sx + (gfx.sxsize - strlen(buffer) * getFontWidth(font_nr)) / 2,
+ gfx.sy + y, buffer, font_nr);
}
-void DrawTextF(int x, int y, int font_type, char *format, ...)
+void DrawTextF(int x, int y, int font_nr, char *format, ...)
{
char buffer[MAX_OUTPUT_LINESIZE + 1];
va_list ap;
vsprintf(buffer, format, ap);
va_end(ap);
- DrawText(gfx.sx + x, gfx.sy + y, buffer, FS_SMALL, font_type);
+ if (strlen(buffer) > MAX_OUTPUT_LINESIZE)
+ Error(ERR_EXIT, "string too long in DrawTextF() -- aborting");
+
+ DrawText(gfx.sx + x, gfx.sy + y, buffer, font_nr);
}
-void DrawText(int x, int y, char *text, int font_size, int font_type)
+void DrawText(int x, int y, char *text, int font_nr)
{
- DrawTextExt(drawto, x, y, text, font_size, font_type);
+ int mask_mode = BLIT_OPAQUE;
+
+ if (DrawingOnBackground(x, y))
+ mask_mode = BLIT_ON_BACKGROUND;
+
+ DrawTextExt(drawto, x, y, text, font_nr, mask_mode);
if (x < gfx.dx)
redraw_mask |= REDRAW_FIELD;
redraw_mask |= REDRAW_DOOR_1;
}
-void DrawTextExt(DrawBuffer *bitmap, int x, int y,
- char *text, int font_size, int font_type)
+void DrawTextExt(DrawBuffer *dst_bitmap, int dst_x, int dst_y, char *text,
+ int font_nr, int mask_mode)
{
- Bitmap *font_bitmap;
- int font_width, font_height, font_start;
- boolean print_inverse = FALSE;
-
- if (font_size != FS_SMALL && font_size != FS_BIG && font_size != FS_MEDIUM)
- font_size = FS_SMALL;
- if (font_type < FC_RED || font_type > FC_SPECIAL3)
- font_type = FC_RED;
-
- font_width = getFontWidth(font_size, font_type);
- font_height = getFontHeight(font_size, font_type);
-
- font_bitmap = (font_size == FS_BIG ? font.bitmap_big :
- font_size == FS_MEDIUM ? font.bitmap_medium :
- font.bitmap_small);
- font_start = (font_type * (font_size == FS_BIG ? FONT1_YSIZE :
- font_size == FS_MEDIUM ? FONT6_YSIZE :
- FONT2_YSIZE) *
- FONT_LINES_PER_FONT);
-
- if (font_type == FC_SPECIAL3)
- font_start += (FONT4_YSIZE - FONT2_YSIZE) * FONT_LINES_PER_FONT;
-
- while (*text)
+ int font_bitmap_id = gfx.select_font_function(font_nr);
+ struct FontBitmapInfo *font = &gfx.font_bitmap_info[font_bitmap_id];
+ int font_width = getFontWidth(font_nr);
+ int font_height = getFontHeight(font_nr);
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ char *text_ptr = text;
+
+ if (font->bitmap == NULL)
+ return;
+
+ /* add offset for drawing font characters */
+ dst_x += font->draw_x;
+ dst_y += font->draw_y;
+
+ while (*text_ptr)
{
- char c = *text++;
+ char c = *text_ptr++;
- if (c == '~' && font_size == FS_SMALL)
- {
- print_inverse = TRUE;
- continue;
- }
+ getFontCharSource(font_nr, c, &src_bitmap, &src_x, &src_y);
- if (c >= 'a' && c <= 'z')
- c = 'A' + (c - 'a');
- else if (c == 'ä' || c == 'Ä')
- c = 91;
- else if (c == 'ö' || c == 'Ö')
- c = 92;
- else if (c == 'ü' || c == 'Ü')
- c = 93;
- else if (c == '[' || c == ']') /* map to normal braces */
- c = (c == '[' ? '(' : ')');
- else if (c == '\\') /* bad luck ... */
- c = '/';
-
- if ((c >= 32 && c <= 95) || c == '°' || c == '´')
+ if (mask_mode == BLIT_INVERSE) /* special mode for text gadgets */
{
- int src_x = ((c - 32) % FONT_CHARS_PER_LINE) * font_width;
- int src_y = ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_start;
- int dest_x = x, dest_y = y;
+ /* first step: draw solid colored rectangle (use "cursor" character) */
+ if (strlen(text) == 1) /* only one char inverted => draw cursor */
+ {
+ Bitmap *cursor_bitmap;
+ int cursor_x, cursor_y;
- if (c == '°' || c == '´') /* map '°' and 'TM' signs */
+ getFontCharSource(font_nr, FONT_ASCII_CURSOR, &cursor_bitmap,
+ &cursor_x, &cursor_y);
+
+ BlitBitmap(cursor_bitmap, dst_bitmap, cursor_x, cursor_y,
+ font_width, font_height, dst_x, dst_y);
+ }
+
+#if defined(TARGET_SDL)
+ /* second step: draw masked inverted character */
+ SDLCopyInverseMasked(src_bitmap, dst_bitmap, src_x, src_y,
+ font_width, font_height, dst_x, dst_y);
+#else
+ /* second step: draw masked black rectangle (use "space" character) */
+ SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(src_bitmap, dst_bitmap, 0, 0,
+ font_width, font_height, dst_x, dst_y);
+#endif
+ }
+ else if (mask_mode == BLIT_MASKED || mask_mode == BLIT_ON_BACKGROUND)
+ {
+ if (mask_mode == BLIT_ON_BACKGROUND)
{
- src_x = FONT_CHARS_PER_LINE * font_width;
- src_y = (c == '°' ? 1 : 2) * font_height + font_start;
+ /* clear font character background */
+ ClearRectangleOnBackground(dst_bitmap, dst_x, dst_y,
+ font_width, font_height);
}
- if (print_inverse)
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ /* use special font tile clipmasks */
{
- BlitBitmap(font_bitmap, bitmap,
- FONT_CHARS_PER_LINE * font_width,
- 3 * font_height + font_start,
- font_width, font_height, x, y);
-
- SetClipOrigin(font_bitmap, font_bitmap->stored_clip_gc,
- dest_x - src_x, dest_y - src_y);
- BlitBitmapMasked(font_bitmap, bitmap,
- 0, 0, font_width, font_height, dest_x, dest_y);
+ int font_pos = getFontCharPosition(font_nr, c);
+
+ SetClipMask(src_bitmap, font_clip_gc, font->clip_mask[font_pos]);
+ SetClipOrigin(src_bitmap, font_clip_gc, dst_x, dst_y);
}
- else
- BlitBitmap(font_bitmap, bitmap,
- src_x, src_y, font_width, font_height, dest_x, dest_y);
+#else
+ SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+#endif
+
+ BlitBitmapMasked(src_bitmap, dst_bitmap, src_x, src_y,
+ font_width, font_height, dst_x, dst_y);
+ }
+ else /* normal, non-masked font blitting */
+ {
+ BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y,
+ font_width, font_height, dst_x, dst_y);
}
- x += font_width;
+ dst_x += font_width;
}
}
#include "system.h"
-/* font types */
-#define FS_SMALL 0
-#define FS_BIG 1
-#define FS_MEDIUM 2
+/* default fonts */
+#define FONT_INITIAL_1 0
+#define FONT_INITIAL_2 1
+#define FONT_INITIAL_3 2
+#define FONT_INITIAL_4 3
/* font colors */
-#define FC_RED 0
-#define FC_BLUE 1
-#define FC_GREEN 2
-#define FC_YELLOW 3
-#define FC_SPECIAL1 4
-#define FC_SPECIAL2 5
-#define FC_SPECIAL3 6
+#define FC_RED FONT_INITIAL_1
+#define FC_BLUE FONT_INITIAL_2
+#define FC_GREEN FONT_INITIAL_3
+#define FC_YELLOW FONT_INITIAL_4
-/* font graphics definitions */
-#define FONT1_XSIZE 32
-#define FONT1_YSIZE 32
-#define FONT2_XSIZE 14
-#define FONT2_YSIZE 14
-#define FONT3_XSIZE 11
-#define FONT3_YSIZE 14
-#define FONT4_XSIZE 16
-#define FONT4_YSIZE 16
-#define FONT5_XSIZE 10
-#define FONT5_YSIZE 14
-#define FONT6_XSIZE 16
-#define FONT6_YSIZE 32
+/* text output definitions */
+#define MAX_OUTPUT_LINESIZE 1024
-#define FONT_CHARS_PER_LINE 16
-#define FONT_LINES_PER_FONT 4
+/* special character mapping for default fonts */
+#define FONT_ASCII_CURSOR ((char)160)
+#define MAP_FONT_ASCII(c) ((c) >= 'a' && (c) <= 'z' ? 'A' + (c) - 'a' : \
+ (c) == '©' ? 96 : \
+ (c) == 'ä' || (c) == 'Ä' ? 97 : \
+ (c) == 'ö' || (c) == 'Ö' ? 98 : \
+ (c) == 'ü' || (c) == 'Ü' ? 99 : \
+ (c) == '°' ? 100 : \
+ (c) == '®' ? 101 : \
+ (c) == FONT_ASCII_CURSOR ? 102 : \
+ (c))
+
+/* 64 regular ordered ASCII characters, 6 special characters, 1 cursor char. */
+#define MIN_NUM_CHARS_PER_FONT 64
+#define DEFAULT_NUM_CHARS_PER_FONT (MIN_NUM_CHARS_PER_FONT + 6 +1)
+#define DEFAULT_NUM_CHARS_PER_LINE 16
-/* text output definitions */
-#define MAX_OUTPUT_LINESIZE 256
/* font structure definitions */
-struct FontInfo
-{
- Bitmap *bitmap_big;
- Bitmap *bitmap_medium;
- Bitmap *bitmap_small;
-};
+void InitFontInfo(struct FontBitmapInfo *, int, int (*function)(int));
+void FreeFontInfo(struct FontBitmapInfo *);
+int getFontWidth(int);
+int getFontHeight(int);
+void getFontCharSource(int, char, Bitmap **, int *, int *);
-void InitFontInfo(Bitmap *, Bitmap *, Bitmap *);
-int getFontWidth(int, int);
-int getFontHeight(int, int);
void DrawInitText(char *, int, int);
void DrawTextF(int, int, int, char *, ...);
void DrawTextFCentered(int, int, char *, ...);
-void DrawText(int, int, char *, int, int);
+void DrawText(int, int, char *, int);
void DrawTextExt(DrawBuffer *, int, int, char *, int, int);
#endif /* TEXT_H */
static struct ToonScreenInfo screen_info;
-void InitToonScreen(Bitmap **toon_bitmap_array,
- Bitmap *save_buffer,
+
+/* ========================================================================= */
+/* generic animation frame calculation */
+/* ========================================================================= */
+
+int getAnimationFrame(int num_frames, int delay, int mode, int start_frame,
+ int sync_frame)
+{
+ int frame = 0;
+
+ sync_frame += start_frame * delay;
+
+ if (mode & ANIM_LOOP) /* looping animation */
+ {
+ frame = (sync_frame % (delay * num_frames)) / delay;
+ }
+ else if (mode & ANIM_LINEAR) /* linear (non-looping) animation */
+ {
+ frame = sync_frame / delay;
+
+ if (frame > num_frames - 1)
+ frame = num_frames - 1;
+ }
+ else if (mode & ANIM_PINGPONG) /* oscillate (border frames once) */
+ {
+ int max_anim_frames = 2 * num_frames - 2;
+
+ frame = (sync_frame % (delay * max_anim_frames)) / delay;
+ frame = (frame < num_frames ? frame : max_anim_frames - frame);
+ }
+ else if (mode & ANIM_PINGPONG2) /* oscillate (border frames twice) */
+ {
+ int max_anim_frames = 2 * num_frames;
+
+ frame = (sync_frame % (delay * max_anim_frames)) / delay;
+ frame = (frame < num_frames ? frame : max_anim_frames - frame - 1);
+ }
+ else if (mode & ANIM_RANDOM) /* play frames in random order */
+ {
+ /* note: expect different frames for the same delay cycle! */
+
+ if (gfx.anim_random_frame < 0)
+ frame = SimpleRND(num_frames);
+ else
+ frame = gfx.anim_random_frame % num_frames;
+ }
+
+ if (mode & ANIM_REVERSE) /* use reverse animation direction */
+ frame = num_frames - frame - 1;
+
+ return frame;
+}
+
+
+/* ========================================================================= */
+/* toon animation functions */
+/* ========================================================================= */
+
+static int get_toon_direction(char *direction_raw)
+{
+ static char *direction = NULL;
+
+ /* !!! MEMORY LEAK HERE! FIX IT! !!! */
+ setString(&direction, getStringToLower(direction_raw));
+
+ return (strcmp(direction, "left") == 0 ? MV_LEFT :
+ strcmp(direction, "right") == 0 ? MV_RIGHT :
+ strcmp(direction, "up") == 0 ? MV_UP :
+ strcmp(direction, "down") == 0 ? MV_DOWN : MV_NO_MOVING);
+}
+
+void InitToonScreen(Bitmap *save_buffer,
void (*update_function)(void),
void (*prepare_backbuffer_function)(void),
boolean (*redraw_needed_function)(void),
struct ToonInfo *toons, int num_toons,
int startx, int starty,
- int width, int height)
+ int width, int height,
+ int frame_delay_value)
{
- screen_info.toon_bitmap_array = toon_bitmap_array;
screen_info.save_buffer = save_buffer;
screen_info.update_function = update_function;
screen_info.prepare_backbuffer_function = prepare_backbuffer_function;
screen_info.starty = starty;
screen_info.width = width;
screen_info.height = height;
+ screen_info.frame_delay_value = frame_delay_value;
}
void DrawAnim(Bitmap *toon_bitmap, GC toon_clip_gc,
boolean AnimateToon(int toon_nr, boolean restart)
{
+ static unsigned long animation_frame_counter = 0;
static int pos_x = 0, pos_y = 0;
static int delta_x = 0, delta_y = 0;
- static int frame = 0, frame_step = 1;
+ static int frame = 0;
static boolean horiz_move, vert_move;
static unsigned long anim_delay = 0;
static unsigned long anim_delay_value = 0;
static int cut_x,cut_y;
static int src_x, src_y;
static int dest_x, dest_y;
-
struct ToonInfo *anim = &screen_info.toons[toon_nr];
- int bitmap_nr = screen_info.toons[toon_nr].bitmap_nr;
- Bitmap *anim_bitmap = screen_info.toon_bitmap_array[bitmap_nr];
+ Bitmap *anim_bitmap = screen_info.toons[toon_nr].bitmap;
GC anim_clip_gc = anim_bitmap->stored_clip_gc;
+ int direction = get_toon_direction(anim->direction);
if (restart)
{
- horiz_move = (anim->direction & (ANIMDIR_LEFT | ANIMDIR_RIGHT));
- vert_move = (anim->direction & (ANIMDIR_UP | ANIMDIR_DOWN));
- anim_delay_value = 1000/anim->frames_per_second;
- frame = 0;
+ horiz_move = (direction & (MV_LEFT | MV_RIGHT));
+ vert_move = (direction & (MV_UP | MV_DOWN));
+ anim_delay_value = anim->step_delay * screen_info.frame_delay_value;
+
+ frame = getAnimationFrame(anim->anim_frames, anim->anim_delay,
+ anim->anim_mode, anim->anim_start_frame,
+ animation_frame_counter++);
if (horiz_move)
{
- if (anim->position == ANIMPOS_UP)
+ int pos_bottom = screen_info.height - anim->height;
+
+ if (strcmp(anim->position, "top") == 0)
pos_y = 0;
- else if (anim->position == ANIMPOS_DOWN)
- pos_y = screen_info.height - anim->height;
- else if (anim->position == ANIMPOS_UPPER)
- pos_y = SimpleRND((screen_info.height - anim->height) / 2);
+ else if (strcmp(anim->position, "bottom") == 0)
+ pos_y = pos_bottom;
+ else if (strcmp(anim->position, "upper") == 0)
+ pos_y = SimpleRND(pos_bottom / 2);
+ else if (strcmp(anim->position, "lower") == 0)
+ pos_y = pos_bottom / 2 + SimpleRND(pos_bottom / 2);
else
- pos_y = SimpleRND(screen_info.height - anim->height);
+ pos_y = SimpleRND(pos_bottom);
- if (anim->direction == ANIMDIR_RIGHT)
+ if (direction == MV_RIGHT)
{
- delta_x = anim->stepsize;
+ delta_x = anim->step_offset;
pos_x = -anim->width + delta_x;
}
else
{
- delta_x = -anim->stepsize;
+ delta_x = -anim->step_offset;
pos_x = screen_info.width + delta_x;
}
+
delta_y = 0;
}
else
{
- if (anim->position == ANIMPOS_LEFT)
+ int pos_right = screen_info.width - anim->width;
+
+ if (strcmp(anim->position, "left") == 0)
pos_x = 0;
- else if (anim->position == ANIMPOS_RIGHT)
- pos_x = screen_info.width - anim->width;
+ else if (strcmp(anim->position, "right") == 0)
+ pos_x = pos_right;
else
- pos_x = SimpleRND(screen_info.width - anim->width);
+ pos_x = SimpleRND(pos_right);
- if (anim->direction == ANIMDIR_DOWN)
+ if (direction == MV_DOWN)
{
- delta_y = anim->stepsize;
+ delta_y = anim->step_offset;
pos_y = -anim->height + delta_y;
}
else
{
- delta_y = -anim->stepsize;
+ delta_y = -anim->step_offset;
pos_y = screen_info.width + delta_y;
}
+
delta_x = 0;
}
}
- if (pos_x <= -anim->width - anim->stepsize ||
- pos_x >= screen_info.width + anim->stepsize ||
- pos_y <= -anim->height - anim->stepsize ||
- pos_y >= screen_info.height + anim->stepsize)
+ if (pos_x <= -anim->width - anim->step_offset ||
+ pos_x >= screen_info.width + anim->step_offset ||
+ pos_y <= -anim->height - anim->step_offset ||
+ pos_y >= screen_info.height + anim->step_offset)
return TRUE;
if (!DelayReached(&anim_delay, anim_delay_value))
else if (pos_y > screen_info.height)
pos_y = screen_info.height;
- pad_x = (horiz_move ? anim->stepsize : 0);
- pad_y = (vert_move ? anim->stepsize : 0);
+ pad_x = (horiz_move ? anim->step_offset : 0);
+ pad_y = (vert_move ? anim->step_offset : 0);
src_x = anim->src_x + frame * anim->width;
src_y = anim->src_y;
dest_x = pos_x;
width = anim->width;
height = anim->height;
- if (pos_x<0)
+ if (pos_x < 0)
{
dest_x = 0;
width += pos_x;
else if (pos_x > screen_info.width - anim->width)
width -= (pos_x - (screen_info.width - anim->width));
- if (pos_y<0)
+ if (pos_y < 0)
{
dest_y = 0;
height += pos_y;
pos_x += delta_x;
pos_y += delta_y;
- frame += frame_step;
- if (frame<0 || frame>=anim->frames)
- {
- if (anim->pingpong)
- {
- frame_step *= -1;
- frame = (frame<0 ? 1 : anim->frames-2);
- }
- else
- frame = (frame<0 ? anim->frames-1 : 0);
- }
+ frame = getAnimationFrame(anim->anim_frames, anim->anim_delay,
+ anim->anim_mode, anim->anim_start_frame,
+ animation_frame_counter++);
return FALSE;
}
if (!setup.toons)
return;
+ /* this may happen after reloading graphics and redefining "num_toons" */
+ if (toon_nr >= screen_info.num_toons)
+ anim_restart = TRUE;
+
switch(mode)
{
case ANIM_START:
toon_nr = SimpleRND(screen_info.num_toons);
}
- anim_restart = reset_delay = AnimateToon(toon_nr,anim_restart);
+ anim_restart = reset_delay = AnimateToon(toon_nr, anim_restart);
}
void InitAnimation()
#include "system.h"
-/* values for toon animation */
-#define ANIMDIR_LEFT 1
-#define ANIMDIR_RIGHT 2
-#define ANIMDIR_UP 4
-#define ANIMDIR_DOWN 8
-
-#define ANIMPOS_ANY 0
-#define ANIMPOS_LEFT 1
-#define ANIMPOS_RIGHT 2
-#define ANIMPOS_UP 4
-#define ANIMPOS_DOWN 8
-#define ANIMPOS_UPPER 16
-
-
struct ToonScreenInfo
{
- Bitmap **toon_bitmap_array;
Bitmap *save_buffer;
void (*update_function)(void);
void (*prepare_backbuffer_function)(void);
int startx, starty;
int width, height;
+
+ int frame_delay_value;
};
struct ToonInfo
{
- int bitmap_nr;
+#if 0
+ int graphic;
int width, height;
int src_x, src_y;
- int frames;
- int frames_per_second;
- int stepsize;
- boolean pingpong;
+ int anim_frames;
+ int step_delay;
+ int step_offset;
+ int anim_mode;
int direction;
int position;
+
+ int anim_delay;
+ int anim_start_frame;
+ Bitmap *bitmap; /* dynamically initialized */
+
+ char *direction_str;
+ char *position_str;
+
+#else
+
+ Bitmap *bitmap;
+ int src_x, src_y;
+ int width, height;
+ int anim_frames;
+ int anim_start_frame;
+ int anim_delay;
+ int anim_mode;
+ int step_offset;
+ int step_delay;
+ char *direction;
+ char *position;
+#endif
};
-void InitToonScreen();
+int getAnimationFrame(int, int, int, int, int);
+
+void InitToonScreen(Bitmap *, void (*update_function)(void),
+ void (*prepare_backbuffer_function)(void),
+ boolean (*redraw_needed_function)(void),
+ struct ToonInfo *, int, int, int, int, int, int);
void InitAnimation(void);
void StopAnimation(void);
void DoAnimation(void);
#include <sys/types.h>
typedef unsigned char boolean;
+
+#if !defined(PLATFORM_WIN32)
typedef unsigned char byte;
+#endif
#ifndef FALSE
#define FALSE 0
#define SIZEOF_ARRAY(array, type) (sizeof(array) / sizeof(type))
#define SIZEOF_ARRAY_INT(array) SIZEOF_ARRAY(array, int)
+
+struct ListNode
+{
+ char *key;
+ void *content;
+ struct ListNode *next;
+};
+typedef struct ListNode ListNode;
+
#endif /* TYPES_H */
--- /dev/null
+/***********************************************************
+* Artsoft Retro-Game Library *
+*----------------------------------------------------------*
+* (c) 1994-2003 Artsoft Entertainment *
+* Holger Schemel *
+* Detmolder Strasse 189 *
+* 33604 Bielefeld *
+* Germany *
+* e-mail: info@artsoft.org *
+*----------------------------------------------------------*
+* windows.h *
+***********************************************************/
+
+#ifndef WINDOWS_H
+#define WINDOWS_H
+
+#include <shlobj.h>
+
+
+/* some symbols are already defined on Windows */
+#define CreateBitmap CreateBitmap_internal
+#define GetPixel GetPixel_internal
+#define CloseWindow CloseWindow_internal
+#define FloodFill FloodFill_internal
+
+#ifdef LoadImage
+#undef LoadImage
+#define LoadImage LoadImage_internal
+#endif
+
+#ifdef PlaySound
+#undef PlaySound
+#define PlaySound PlaySound_internal
+#endif
+
+#ifdef DrawText
+#undef DrawText
+#define DrawText DrawText_internal
+#endif
+
+#endif /* WINDOWS_H */
/* Select event types wanted */
window_event_mask =
ExposureMask | StructureNotifyMask | FocusChangeMask |
- ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
- PointerMotionHintMask | KeyPressMask | KeyReleaseMask;
+ ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | PointerMotionHintMask |
+ KeyPressMask | KeyReleaseMask;
XSelectInput(display, new_window->drawable, window_event_mask);
#endif
return new_window;
}
+void X11ZoomBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap)
+{
+#if defined(TARGET_ALLEGRO)
+ AllegroZoomBitmap(src_bitmap->drawable, dst_bitmap->drawable,
+ src_bitmap->width, src_bitmap->height,
+ dst_bitmap->width, dst_bitmap->height);
+#else
+ ZoomPixmap(display, src_bitmap->gc,
+ src_bitmap->drawable, dst_bitmap->drawable,
+ src_bitmap->width, src_bitmap->height,
+ dst_bitmap->width, dst_bitmap->height);
+#endif
+}
+
static void SetImageDimensions(Bitmap *bitmap)
{
#if defined(TARGET_ALLEGRO)
Bitmap *new_bitmap = CreateBitmapStruct();
char *error = "Read_PCX_to_Pixmap(): %s '%s'";
int pcx_err;
+ XGCValues clip_gc_values;
+ unsigned long clip_gc_valuemask;
pcx_err = Read_PCX_to_Pixmap(display, window->drawable, window->gc, filename,
&new_bitmap->drawable, &new_bitmap->clip_mask);
return NULL;
}
+ clip_gc_values.graphics_exposures = False;
+ clip_gc_values.clip_mask = new_bitmap->clip_mask;
+ clip_gc_valuemask = GCGraphicsExposures | GCClipMask;
+ new_bitmap->stored_clip_gc = XCreateGC(display, window->drawable,
+ clip_gc_valuemask, &clip_gc_values);
+
/* set GraphicContext inheritated from Window */
new_bitmap->gc = window->gc;
return new_bitmap;
}
+inline void X11CreateBitmapContent(Bitmap *new_bitmap,
+ int width, int height, int depth)
+{
+ Pixmap pixmap;
+
+ if ((pixmap = XCreatePixmap(display, window->drawable, width, height, depth))
+ == None)
+ Error(ERR_EXIT, "cannot create pixmap");
+
+ new_bitmap->drawable = pixmap;
+
+ if (window == NULL)
+ Error(ERR_EXIT, "Window GC needed for Bitmap -- create Window first");
+
+ new_bitmap->gc = window->gc;
+
+ new_bitmap->line_gc[0] = window->line_gc[0];
+ new_bitmap->line_gc[1] = window->line_gc[1];
+}
+
+inline void X11FreeBitmapPointers(Bitmap *bitmap)
+{
+ /* The X11 version seems to have a memory leak here -- although
+ "XFreePixmap()" is called, the corresponding memory seems not
+ to be freed (according to "ps"). The SDL version apparently
+ does not have this problem. */
+
+ if (bitmap->drawable)
+ XFreePixmap(display, bitmap->drawable);
+ if (bitmap->clip_mask)
+ XFreePixmap(display, bitmap->clip_mask);
+ if (bitmap->stored_clip_gc)
+ XFreeGC(display, bitmap->stored_clip_gc);
+ /* the other GCs are only pointers to GCs used elsewhere */
+ bitmap->drawable = None;
+ bitmap->clip_mask = None;
+ bitmap->stored_clip_gc = None;
+}
+
+inline void X11CopyArea(Bitmap *src_bitmap, Bitmap *dst_bitmap,
+ int src_x, int src_y, int width, int height,
+ int dst_x, int dst_y, int mask_mode)
+{
+ XCopyArea(display, src_bitmap->drawable, dst_bitmap->drawable,
+ (mask_mode == BLIT_MASKED ? src_bitmap->clip_gc : dst_bitmap->gc),
+ src_x, src_y, width, height, dst_x, dst_y);
+}
+
+inline void X11FillRectangle(Bitmap *bitmap, int x, int y,
+ int width, int height, Pixel color)
+{
+ XSetForeground(display, bitmap->gc, color);
+ XFillRectangle(display, bitmap->drawable, bitmap->gc, x, y, width, height);
+}
+
+inline void X11DrawSimpleLine(Bitmap *bitmap, int from_x, int from_y,
+ int to_x, int to_y, Pixel color)
+{
+ XSetForeground(display, bitmap->gc, color);
+ XDrawLine(display, bitmap->drawable, bitmap->gc, from_x, from_y, to_x, to_y);
+}
+
+inline Pixel X11GetPixel(Bitmap *bitmap, int x, int y)
+{
+ XImage *pixel_image;
+ Pixel pixel_value;
+
+ pixel_image = XGetImage(display, bitmap->drawable, x, y, 1, 1,
+ AllPlanes, ZPixmap);
+ pixel_value = XGetPixel(pixel_image, 0, 0);
+
+ XDestroyImage(pixel_image);
+
+ return pixel_value;
+}
+
+#if defined(TARGET_X11_NATIVE)
+inline Pixel X11GetPixelFromRGB(unsigned int color_r, unsigned int color_g,
+ unsigned int color_b)
+{
+ XColor xcolor;
+ Pixel pixel;
+
+ xcolor.flags = DoRed | DoGreen | DoBlue;
+ xcolor.red = (color_r << 8);
+ xcolor.green = (color_g << 8);
+ xcolor.blue = (color_b << 8);
+
+ XAllocColor(display, cmap, &xcolor);
+ pixel = xcolor.pixel;
+
+ return pixel;
+}
+#endif /* TARGET_X11_NATIVE */
+
+
+/* ------------------------------------------------------------------------- */
+/* mouse pointer functions */
+/* ------------------------------------------------------------------------- */
+
+#if defined(TARGET_X11_NATIVE)
+
+static Cursor create_cursor(struct MouseCursorInfo *cursor_info)
+{
+ Pixmap pixmap_data, pixmap_mask;
+ XColor color_fg, color_bg;
+ Cursor cursor;
+
+ /* shape and mask are single plane pixmaps */
+ pixmap_data =
+ XCreatePixmapFromBitmapData(display, window->drawable, cursor_info->data,
+ cursor_info->width, cursor_info->height,
+ 1, 0, 1);
+ pixmap_mask =
+ XCreatePixmapFromBitmapData(display, window->drawable, cursor_info->mask,
+ cursor_info->width, cursor_info->height,
+ 1, 0, 1);
+
+ XParseColor(display, cmap, "black", &color_fg);
+ XParseColor(display, cmap, "white", &color_bg);
+
+ cursor = XCreatePixmapCursor(display, pixmap_data, pixmap_mask,
+ &color_fg, &color_bg,
+ cursor_info->hot_x, cursor_info->hot_y);
+
+ return cursor;
+}
+
+void X11SetMouseCursor(struct MouseCursorInfo *cursor_info)
+{
+ static struct MouseCursorInfo *last_cursor_info = NULL;
+ static Cursor cursor_default = None;
+ static Cursor cursor_current = None;
+
+ if (cursor_info != NULL && cursor_info != last_cursor_info)
+ {
+ cursor_current = create_cursor(cursor_info);
+ last_cursor_info = cursor_info;
+ }
+
+ XDefineCursor(display, window->drawable,
+ cursor_info ? cursor_current : cursor_default);
+}
+#endif /* TARGET_X11_NATIVE */
+
#endif /* TARGET_X11 */
#define TARGET_STRING "X11"
#endif
+#if defined(PLATFORM_UNIX)
+/* This triggers some stuff that is needed because X11 (XSetClipOrigin(),
+ to be precise) is often very slow when preparing a masked XCopyArea()
+ for big Pixmaps.
+ To prevent this, small (tile-sized) mask Pixmaps are created which will
+ then be set much faster with XSetClipOrigin() and speed things up a lot. */
+#define TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND
+#endif
+
#define FULLSCREEN_STATUS FULLSCREEN_NOT_AVAILABLE
+#define CURSOR_MAX_WIDTH 32
+#define CURSOR_MAX_HEIGHT 32
+
/* X11 type definitions */
typedef struct X11DrawableInfo Bitmap;
typedef struct X11DrawableInfo DrawWindow;
typedef struct X11DrawableInfo DrawBuffer;
-/* "Pixel" is already defined in X11/Intrinsic.h */
+/* "Pixel" is already defined */
+/* "Cursor" is already defined */
typedef KeySym Key;
+typedef unsigned int KeyMod;
typedef XEvent Event;
typedef XButtonEvent ButtonEvent;
GC clip_gc; /* can be 'stored_clip_gc' or one-tile-only clip GC */
};
+struct MouseCursorInfo
+{
+ int width, height;
+ int hot_x, hot_y;
+
+ char data[CURSOR_MAX_WIDTH * CURSOR_MAX_HEIGHT / 8];
+ char mask[CURSOR_MAX_WIDTH * CURSOR_MAX_HEIGHT / 8];
+};
+
struct XY
{
short x, y;
/* X11 symbol definitions */
+#define BLACK_PIXEL BlackPixel(display, screen)
+#define WHITE_PIXEL WhitePixel(display, screen)
+
#define EVENT_BUTTONPRESS ButtonPress
#define EVENT_BUTTONRELEASE ButtonRelease
#define EVENT_MOTIONNOTIFY MotionNotify
#define KSYM_FKEY_LAST KSYM_F24
#define KSYM_NUM_FKEYS (KSYM_FKEY_LAST - KSYM_FKEY_FIRST + 1)
+#define KMOD_None None
+#define KMOD_Shift_L 0x0001
+#define KMOD_Shift_R 0x0002
+#define KMOD_Control_L 0x0040
+#define KMOD_Control_R 0x0080
+#define KMOD_Meta_L 0x0400
+#define KMOD_Meta_R 0x0800
+#define KMOD_Alt_L 0x0100
+#define KMOD_Alt_R 0x0200
+
+#define KMOD_Shift (KMOD_Shift_L | KMOD_Shift_R)
+#define KMOD_Control (KMOD_Control_L | KMOD_Control_R)
+#define KMOD_Meta (KMOD_Meta_L | KMOD_Meta_R)
+#define KMOD_Alt (KMOD_Alt_L | KMOD_Alt_R)
+
/* X11 function definitions */
inline void X11InitVideoDisplay(void);
inline void X11InitVideoBuffer(DrawBuffer **, DrawWindow **);
+
+void X11ZoomBitmap(Bitmap *, Bitmap *);
Bitmap *X11LoadImage(char *);
+inline void X11CreateBitmapContent(Bitmap *, int, int, int);
+inline void X11FreeBitmapPointers(Bitmap *);
+inline void X11CopyArea(Bitmap *, Bitmap *, int, int, int, int, int, int, int);
+inline void X11FillRectangle(Bitmap *, int, int, int, int, Pixel);
+inline void X11DrawSimpleLine(Bitmap *, int, int, int, int, Pixel);
+inline Pixel X11GetPixel(Bitmap *, int, int);
+inline Pixel X11GetPixelFromRGB(unsigned int, unsigned int, unsigned int);
+
+#if defined(TARGET_X11_NATIVE)
+void X11SetMouseCursor(struct MouseCursorInfo *);
+#endif
+
#endif /* X11_H */
#include "init.h"
#include "game.h"
#include "events.h"
+#include "config.h"
-GC tile_clip_gc;
-Bitmap *pix[NUM_BITMAPS];
-Pixmap tile_clipmask[NUM_TILES];
-DrawBuffer *fieldbuffer;
-DrawBuffer *drawto_field;
-
-int game_status = MAINMENU;
-boolean level_editor_test_game = FALSE;
-boolean network_playing = FALSE;
-
-int key_joystick_mapping = 0;
-
-boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
-int redraw_x1 = 0, redraw_y1 = 0;
-
-short Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-short Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-short MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-short MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-short MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-short Frame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-short JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-short AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-short AmoebaCnt[MAX_NUM_AMOEBA], AmoebaCnt2[MAX_NUM_AMOEBA];
-short ExplodeField[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-unsigned long Elementeigenschaften1[MAX_ELEMENTS];
-unsigned long Elementeigenschaften2[MAX_ELEMENTS];
-
-int lev_fieldx,lev_fieldy, scroll_x,scroll_y;
-
-int FX = SX, FY = SY, ScrollStepSize;
-int ScreenMovDir = MV_NO_MOVING, ScreenMovPos = 0;
-int ScreenGfxPos = 0;
-int BorderElement = EL_BETON;
-int GameFrameDelay = GAME_FRAME_DELAY;
-int FfwdFrameDelay = FFWD_FRAME_DELAY;
-int BX1 = 0, BY1 = 0, BX2 = SCR_FIELDX-1, BY2 = SCR_FIELDY-1;
-int SBX_Left, SBX_Right;
-int SBY_Upper, SBY_Lower;
-int ZX,ZY, ExitX,ExitY;
-int AllPlayersGone;
-
-int TimeFrames, TimePlayed, TimeLeft;
-
-boolean network_player_action_received = FALSE;
-
-struct LevelInfo level;
+#if 0
+GC tile_clip_gc;
+Bitmap *pix[NUM_BITMAPS];
+#endif
+Bitmap *bitmap_db_field, *bitmap_db_door;
+#if 0
+Pixmap tile_clipmask[NUM_TILES];
+#endif
+DrawBuffer *fieldbuffer;
+DrawBuffer *drawto_field;
+
+int game_status = -1;
+boolean level_editor_test_game = FALSE;
+boolean network_playing = FALSE;
+
+int key_joystick_mapping = 0;
+
+boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
+int redraw_x1 = 0, redraw_y1 = 0;
+
+short Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short ChangeDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short Back[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+boolean Pushed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+boolean Changing[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short AmoebaCnt[MAX_NUM_AMOEBA];
+short AmoebaCnt2[MAX_NUM_AMOEBA];
+short ExplodePhase[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+short ExplodeField[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+
+unsigned long Properties[MAX_NUM_ELEMENTS][NUM_EP_BITFIELDS];
+
+int GfxFrame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+int GfxAction[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+int GfxRandom[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+int GfxElement[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+
+int lev_fieldx, lev_fieldy;
+int scroll_x, scroll_y;
+
+int FX = SX, FY = SY;
+int ScrollStepSize;
+int ScreenMovDir = MV_NO_MOVING, ScreenMovPos = 0;
+int ScreenGfxPos = 0;
+int BorderElement = EL_STEELWALL;
+int GameFrameDelay = GAME_FRAME_DELAY;
+int FfwdFrameDelay = FFWD_FRAME_DELAY;
+int BX1 = 0, BY1 = 0;
+int BX2 = SCR_FIELDX - 1, BY2 = SCR_FIELDY - 1;
+int SBX_Left, SBX_Right;
+int SBY_Upper, SBY_Lower;
+int ZX, ZY;
+int ExitX, ExitY;
+int AllPlayersGone;
+
+int TimeFrames, TimePlayed, TimeLeft;
+
+boolean network_player_action_received = FALSE;
+
+struct LevelInfo level, level_template;
struct PlayerInfo stored_player[MAX_PLAYERS], *local_player = NULL;
struct HiScore highscore[MAX_SCORE_ENTRIES];
struct TapeInfo tape;
struct SetupInfo setup;
struct GameInfo game;
struct GlobalInfo global;
+struct MenuInfo menu;
+struct DoorInfo door;
+struct GraphicInfo *graphic_info = NULL;
+struct SoundInfo *sound_info = NULL;
+
+
+/* ------------------------------------------------------------------------- */
+/* element definitions */
+/* ------------------------------------------------------------------------- */
+
+struct ElementInfo element_info[MAX_NUM_ELEMENTS + 1] =
+{
+ /* keyword to start parser: "ELEMENT_INFO_START" <-- do not change! */
+
+ /* ----------------------------------------------------------------------- */
+ /* "real" level file elements */
+ /* ----------------------------------------------------------------------- */
+
+ {
+ "empty_space",
+ "empty_space",
+ "empty space"
+ },
+ {
+ "sand",
+ "sand",
+ "sand"
+ },
+ {
+ "wall",
+ "wall",
+ "normal wall"
+ },
+ {
+ "wall_slippery",
+ "wall",
+ "slippery wall"
+ },
+ {
+ "rock",
+ "rock",
+ "rock"
+ },
+ {
+ "key_obsolete",
+ "key",
+ "key"
+ },
+ {
+ "emerald",
+ "emerald",
+ "emerald"
+ },
+ {
+ "exit_closed",
+ "exit",
+ "closed exit"
+ },
+ {
+ "player_obsolete",
+ "player",
+ "player"
+ },
+ {
+ "bug",
+ "bug",
+ "bug"
+ },
+ {
+ "spaceship",
+ "spaceship",
+ "spaceship"
+ },
+ {
+ "yamyam",
+ "yamyam",
+ "yam yam"
+ },
+ {
+ "robot",
+ "robot",
+ "robot"
+ },
+ {
+ "steelwall",
+ "wall",
+ "steel wall"
+ },
+ {
+ "diamond",
+ "diamond",
+ "diamond"
+ },
+ {
+ "amoeba_dead",
+ "amoeba",
+ "dead amoeba"
+ },
+ {
+ "quicksand_empty",
+ "quicksand",
+ "empty quicksand"
+ },
+ {
+ "quicksand_full",
+ "quicksand",
+ "quicksand with rock"
+ },
+ {
+ "amoeba_drop",
+ "amoeba",
+ "amoeba drop"
+ },
+ {
+ "bomb",
+ "bomb",
+ "bomb"
+ },
+ {
+ "magic_wall",
+ "magic_wall",
+ "magic wall"
+ },
+ {
+ "speed_pill",
+ "speed_pill",
+ "speed pill"
+ },
+ {
+ "acid",
+ "acid",
+ "acid"
+ },
+ {
+ "amoeba_wet",
+ "amoeba",
+ "dropping amoeba"
+ },
+ {
+ "amoeba_dry",
+ "amoeba",
+ "normal amoeba"
+ },
+ {
+ "nut",
+ "nut",
+ "nut with emerald"
+ },
+ {
+ "game_of_life",
+ "game_of_life",
+ "Conway's wall of life"
+ },
+ {
+ "biomaze",
+ "biomaze",
+ "biomaze"
+ },
+ {
+ "dynamite_active",
+ "dynamite",
+ "burning dynamite"
+ },
+ {
+ "stoneblock",
+ "wall",
+ "wall"
+ },
+ {
+ "robot_wheel",
+ "robot_wheel",
+ "magic wheel"
+ },
+ {
+ "robot_wheel_active",
+ "robot_wheel",
+ "magic wheel (running)"
+ },
+ {
+ "key_1",
+ "key",
+ "red key"
+ },
+ {
+ "key_2",
+ "key",
+ "yellow key"
+ },
+ {
+ "key_3",
+ "key",
+ "green key"
+ },
+ {
+ "key_4",
+ "key",
+ "blue key"
+ },
+ {
+ "gate_1",
+ "gate",
+ "red door"
+ },
+ {
+ "gate_2",
+ "gate",
+ "yellow door"
+ },
+ {
+ "gate_3",
+ "gate",
+ "green door"
+ },
+ {
+ "gate_4",
+ "gate",
+ "blue door"
+ },
+ {
+ "gate_1_gray",
+ "gate",
+ "gray door (opened by red key)"
+ },
+ {
+ "gate_2_gray",
+ "gate",
+ "gray door (opened by yellow key)"},
+ {
+ "gate_3_gray",
+ "gate",
+ "gray door (opened by green key)"},
+ {
+ "gate_4_gray",
+ "gate",
+ "gray door (opened by blue key)"},
+ {
+ "dynamite",
+ "dynamite",
+ "dynamite"
+ },
+ {
+ "pacman",
+ "pacman",
+ "pac man"
+ },
+ {
+ "invisible_wall",
+ "wall",
+ "invisible normal wall"
+ },
+ {
+ "lamp",
+ "lamp",
+ "lamp (off)"
+ },
+ {
+ "lamp_active",
+ "lamp",
+ "lamp (on)"
+ },
+ {
+ "wall_emerald",
+ "wall",
+ "wall with emerald"
+ },
+ {
+ "wall_diamond",
+ "wall",
+ "wall with diamond"
+ },
+ {
+ "amoeba_full",
+ "amoeba",
+ "amoeba with content"
+ },
+ {
+ "bd_amoeba",
+ "bd_amoeba",
+ "amoeba (BD style)"
+ },
+ {
+ "time_orb_full",
+ "time_orb_full",
+ "time orb (full)"
+ },
+ {
+ "time_orb_empty",
+ "time_orb_empty",
+ "time orb (empty)"
+ },
+ {
+ "expandable_wall",
+ "wall",
+ "growing wall"
+ },
+ {
+ "bd_diamond",
+ "bd_diamond",
+ "diamond (BD style)"
+ },
+ {
+ "emerald_yellow",
+ "emerald",
+ "yellow emerald"
+ },
+ {
+ "wall_bd_diamond",
+ "wall",
+ "wall with BD style diamond"
+ },
+ {
+ "wall_emerald_yellow",
+ "wall",
+ "wall with yellow emerald"
+ },
+ {
+ "dark_yamyam",
+ "dark_yamyam",
+ "dark yam yam"
+ },
+ {
+ "bd_magic_wall",
+ "bd_magic_wall",
+ "magic wall (BD style)"
+ },
+ {
+ "invisible_steelwall",
+ "wall",
+ "invisible steel wall"
+ },
+ {
+ "unused_63",
+ "unused",
+ "(not used)"
+ },
+ {
+ "dynabomb_increase_number",
+ "dynabomb",
+ "increases number of bombs"
+ },
+ {
+ "dynabomb_increase_size",
+ "dynabomb",
+ "increases explosion size"
+ },
+ {
+ "dynabomb_increase_power",
+ "dynabomb",
+ "increases power of explosion"
+ },
+ {
+ "sokoban_object",
+ "sokoban",
+ "sokoban object"
+ },
+ {
+ "sokoban_field_empty",
+ "sokoban",
+ "sokoban empty field"
+ },
+ {
+ "sokoban_field_full",
+ "sokoban",
+ "sokoban field with object"
+ },
+ {
+ "bd_butterfly_right",
+ "bd_butterfly",
+ "butterfly (starts moving right)"},
+ {
+ "bd_butterfly_up",
+ "bd_butterfly",
+ "butterfly (starts moving up)"
+ },
+ {
+ "bd_butterfly_left",
+ "bd_butterfly",
+ "butterfly (starts moving left)"},
+ {
+ "bd_butterfly_down",
+ "bd_butterfly",
+ "butterfly (starts moving down)"},
+ {
+ "bd_firefly_right",
+ "bd_firefly",
+ "firefly (starts moving right)"
+ },
+ {
+ "bd_firefly_up",
+ "bd_firefly",
+ "firefly (starts moving up)"
+ },
+ {
+ "bd_firefly_left",
+ "bd_firefly",
+ "firefly (starts moving left)"
+ },
+ {
+ "bd_firefly_down",
+ "bd_firefly",
+ "firefly (starts moving down)"
+ },
+ {
+ "bd_butterfly",
+ "bd_butterfly",
+ "butterfly"
+ },
+ {
+ "bd_firefly",
+ "bd_firefly",
+ "firefly"
+ },
+ {
+ "player_1",
+ "player",
+ "yellow player"
+ },
+ {
+ "player_2",
+ "player",
+ "red player"
+ },
+ {
+ "player_3",
+ "player",
+ "green player"
+ },
+ {
+ "player_4",
+ "player",
+ "blue player"
+ },
+ {
+ "bug_right",
+ "bug",
+ "bug (starts moving right)"
+ },
+ {
+ "bug_up",
+ "bug",
+ "bug (starts moving up)"
+ },
+ {
+ "bug_left",
+ "bug",
+ "bug (starts moving left)"
+ },
+ {
+ "bug_down",
+ "bug",
+ "bug (starts moving down)"
+ },
+ {
+ "spaceship_right",
+ "spaceship",
+ "spaceship (starts moving right)"},
+ {
+ "spaceship_up",
+ "spaceship",
+ "spaceship (starts moving up)"
+ },
+ {
+ "spaceship_left",
+ "spaceship",
+ "spaceship (starts moving left)"},
+ {
+ "spaceship_down",
+ "spaceship",
+ "spaceship (starts moving down)"},
+ {
+ "pacman_right",
+ "pacman",
+ "pac man (starts moving right)"
+ },
+ {
+ "pacman_up",
+ "pacman",
+ "pac man (starts moving up)"
+ },
+ {
+ "pacman_left",
+ "pacman",
+ "pac man (starts moving left)"
+ },
+ {
+ "pacman_down",
+ "pacman",
+ "pac man (starts moving down)"
+ },
+ {
+ "emerald_red",
+ "emerald",
+ "red emerald"
+ },
+ {
+ "emerald_purple",
+ "emerald",
+ "purple emerald"
+ },
+ {
+ "wall_emerald_red",
+ "wall",
+ "wall with red emerald"
+ },
+ {
+ "wall_emerald_purple",
+ "wall",
+ "wall with purple emerald"
+ },
+ {
+ "acid_pool_topleft",
+ "wall",
+ "acid pool (top left)"
+ },
+ {
+ "acid_pool_topright",
+ "wall",
+ "acid pool (top right)"
+ },
+ {
+ "acid_pool_bottomleft",
+ "wall",
+ "acid pool (bottom left)"
+ },
+ {
+ "acid_pool_bottom",
+ "wall",
+ "acid pool (bottom)"
+ },
+ {
+ "acid_pool_bottomright",
+ "wall",
+ "acid pool (bottom right)"
+ },
+ {
+ "bd_wall",
+ "wall",
+ "normal wall (BD style)"
+ },
+ {
+ "bd_rock",
+ "bd_rock",
+ "rock (BD style)"
+ },
+ {
+ "exit_open",
+ "exit",
+ "open exit"
+ },
+ {
+ "black_orb",
+ "black_orb",
+ "bomb"
+ },
+ {
+ "amoeba_to_diamond",
+ "amoeba",
+ "amoeba"
+ },
+ {
+ "mole",
+ "mole",
+ "mole"
+ },
+ {
+ "penguin",
+ "penguin",
+ "penguin"
+ },
+ {
+ "satellite",
+ "satellite",
+ "satellite"
+ },
+ {
+ "arrow_left",
+ "arrow",
+ "arrow left"
+ },
+ {
+ "arrow_right",
+ "arrow",
+ "arrow right"
+ },
+ {
+ "arrow_up",
+ "arrow",
+ "arrow up"
+ },
+ {
+ "arrow_down",
+ "arrow",
+ "arrow down"
+ },
+ {
+ "pig",
+ "pig",
+ "pig"
+ },
+ {
+ "dragon",
+ "dragon",
+ "fire breathing dragon"
+ },
+ {
+ "em_key_1_file",
+ "key",
+ "red key (EM style)"
+ },
+ {
+ "char_space",
+ "char",
+ "letter ' '"
+ },
+ {
+ "char_exclam",
+ "char",
+ "letter '!'"
+ },
+ {
+ "char_quotedbl",
+ "char",
+ "letter '\"'"
+ },
+ {
+ "char_numbersign",
+ "char",
+ "letter '#'"
+ },
+ {
+ "char_dollar",
+ "char",
+ "letter '$'"
+ },
+ {
+ "char_procent",
+ "char",
+ "letter '%'"
+ },
+ {
+ "char_ampersand",
+ "char",
+ "letter '&'"
+ },
+ {
+ "char_apostrophe",
+ "char",
+ "letter '''"
+ },
+ {
+ "char_parenleft",
+ "char",
+ "letter '('"
+ },
+ {
+ "char_parenright",
+ "char",
+ "letter ')'"
+ },
+ {
+ "char_asterisk",
+ "char",
+ "letter '*'"
+ },
+ {
+ "char_plus",
+ "char",
+ "letter '+'"
+ },
+ {
+ "char_comma",
+ "char",
+ "letter ','"
+ },
+ {
+ "char_minus",
+ "char",
+ "letter '-'"
+ },
+ {
+ "char_period",
+ "char",
+ "letter '.'"
+ },
+ {
+ "char_slash",
+ "char",
+ "letter '/'"
+ },
+ {
+ "char_0",
+ "char",
+ "letter '0'"
+ },
+ {
+ "char_1",
+ "char",
+ "letter '1'"
+ },
+ {
+ "char_2",
+ "char",
+ "letter '2'"
+ },
+ {
+ "char_3",
+ "char",
+ "letter '3'"
+ },
+ {
+ "char_4",
+ "char",
+ "letter '4'"
+ },
+ {
+ "char_5",
+ "char",
+ "letter '5'"
+ },
+ {
+ "char_6",
+ "char",
+ "letter '6'"
+ },
+ {
+ "char_7",
+ "char",
+ "letter '7'"
+ },
+ {
+ "char_8",
+ "char",
+ "letter '8'"
+ },
+ {
+ "char_9",
+ "char",
+ "letter '9'"
+ },
+ {
+ "char_colon",
+ "char",
+ "letter ':'"
+ },
+ {
+ "char_semicolon",
+ "char",
+ "letter ';'"
+ },
+ {
+ "char_less",
+ "char",
+ "letter '<'"
+ },
+ {
+ "char_equal",
+ "char",
+ "letter '='"
+ },
+ {
+ "char_greater",
+ "char",
+ "letter '>'"
+ },
+ {
+ "char_question",
+ "char",
+ "letter '?'"
+ },
+ {
+ "char_at",
+ "char",
+ "letter '@'"
+ },
+ {
+ "char_a",
+ "char",
+ "letter 'A'"
+ },
+ {
+ "char_b",
+ "char",
+ "letter 'B'"
+ },
+ {
+ "char_c",
+ "char",
+ "letter 'C'"
+ },
+ {
+ "char_d",
+ "char",
+ "letter 'D'"
+ },
+ {
+ "char_e",
+ "char",
+ "letter 'E'"
+ },
+ {
+ "char_f",
+ "char",
+ "letter 'F'"
+ },
+ {
+ "char_g",
+ "char",
+ "letter 'G'"
+ },
+ {
+ "char_h",
+ "char",
+ "letter 'H'"
+ },
+ {
+ "char_i",
+ "char",
+ "letter 'I'"
+ },
+ {
+ "char_j",
+ "char",
+ "letter 'J'"
+ },
+ {
+ "char_k",
+ "char",
+ "letter 'K'"
+ },
+ {
+ "char_l",
+ "char",
+ "letter 'L'"
+ },
+ {
+ "char_m",
+ "char",
+ "letter 'M'"
+ },
+ {
+ "char_n",
+ "char",
+ "letter 'N'"
+ },
+ {
+ "char_o",
+ "char",
+ "letter 'O'"
+ },
+ {
+ "char_p",
+ "char",
+ "letter 'P'"
+ },
+ {
+ "char_q",
+ "char",
+ "letter 'Q'"
+ },
+ {
+ "char_r",
+ "char",
+ "letter 'R'"
+ },
+ {
+ "char_s",
+ "char",
+ "letter 'S'"
+ },
+ {
+ "char_t",
+ "char",
+ "letter 'T'"
+ },
+ {
+ "char_u",
+ "char",
+ "letter 'U'"
+ },
+ {
+ "char_v",
+ "char",
+ "letter 'V'"
+ },
+ {
+ "char_w",
+ "char",
+ "letter 'W'"
+ },
+ {
+ "char_x",
+ "char",
+ "letter 'X'"
+ },
+ {
+ "char_y",
+ "char",
+ "letter 'Y'"
+ },
+ {
+ "char_z",
+ "char",
+ "letter 'Z'"
+ },
+ {
+ "char_bracketleft",
+ "char",
+ "letter '['"
+ },
+ {
+ "char_backslash",
+ "char",
+ "letter '\\'"
+ },
+ {
+ "char_bracketright",
+ "char",
+ "letter ']'"
+ },
+ {
+ "char_asciicircum",
+ "char",
+ "letter '^'"
+ },
+ {
+ "char_underscore",
+ "char",
+ "letter '_'"
+ },
+ {
+ "char_copyright",
+ "char",
+ "letter '©'"
+ },
+ {
+ "char_aumlaut",
+ "char",
+ "letter 'Ä'"
+ },
+ {
+ "char_oumlaut",
+ "char",
+ "letter 'Ö'"
+ },
+ {
+ "char_uumlaut",
+ "char",
+ "letter 'Ü'"
+ },
+ {
+ "char_degree",
+ "char",
+ "letter '°'"
+ },
+ {
+ "char_trademark",
+ "char",
+ "letter '®'"
+ },
+ {
+ "char_cursor",
+ "char",
+ "letter 'Â '"
+ },
+ {
+ "char_unused",
+ "char",
+ "letter ''"
+ },
+ {
+ "char_unused",
+ "char",
+ "letter ''"
+ },
+ {
+ "char_unused",
+ "char",
+ "letter ''"
+ },
+ {
+ "char_unused",
+ "char",
+ "letter ''"
+ },
+ {
+ "char_unused",
+ "char",
+ "letter ''"
+ },
+ {
+ "char_unused",
+ "char",
+ "letter ''"
+ },
+ {
+ "char_unused",
+ "char",
+ "letter ''"
+ },
+ {
+ "char_unused",
+ "char",
+ "letter ''"
+ },
+ {
+ "char_unused",
+ "char",
+ "letter ''"
+ },
+ {
+ "expandable_wall_horizontal",
+ "wall",
+ "growing wall (horizontal)"
+ },
+ {
+ "expandable_wall_vertical",
+ "wall",
+ "growing wall (vertical)"
+ },
+ {
+ "expandable_wall_any",
+ "wall",
+ "growing wall (any direction)"
+ },
+ {
+ "em_gate_1",
+ "gate",
+ "red door (EM style)"
+ },
+ {
+ "em_gate_2",
+ "gate",
+ "yellow door (EM style)"
+ },
+ {
+ "em_gate_3",
+ "gate",
+ "green door (EM style)"
+ },
+ {
+ "em_gate_4",
+ "gate",
+ "blue door (EM style)"
+ },
+ {
+ "em_key_2_file",
+ "key",
+ "yellow key (EM style)"
+ },
+ {
+ "em_key_3_file",
+ "key",
+ "green key (EM style)"
+ },
+ {
+ "em_key_4_file",
+ "key",
+ "blue key (EM style)"
+ },
+ {
+ "sp_empty_space",
+ "empty_space",
+ "empty space"
+ },
+ {
+ "sp_zonk",
+ "sp_zonk",
+ "zonk"
+ },
+ {
+ "sp_base",
+ "sp_base",
+ "base"
+ },
+ {
+ "sp_murphy",
+ "player",
+ "murphy"
+ },
+ {
+ "sp_infotron",
+ "sp_infotron",
+ "infotron"
+ },
+ {
+ "sp_chip_single",
+ "wall",
+ "chip (single)"
+ },
+ {
+ "sp_hardware_gray",
+ "wall",
+ "hardware"
+ },
+ {
+ "sp_exit_closed",
+ "sp_exit",
+ "exit"
+ },
+ {
+ "sp_disk_orange",
+ "sp_disk_orange",
+ "orange disk"
+ },
+ {
+ "sp_port_right",
+ "sp_port",
+ "port (leading right)"
+ },
+ {
+ "sp_port_down",
+ "sp_port",
+ "port (leading down)"
+ },
+ {
+ "sp_port_left",
+ "sp_port",
+ "port (leading left)"
+ },
+ {
+ "sp_port_up",
+ "sp_port",
+ "port (leading up)"
+ },
+ {
+ "sp_gravity_port_right",
+ "sp_port",
+ "gravity port (leading right)"
+ },
+ {
+ "sp_gravity_port_down",
+ "sp_port",
+ "gravity port (leading down)"
+ },
+ {
+ "sp_gravity_port_left",
+ "sp_port",
+ "gravity port (leading left)"
+ },
+ {
+ "sp_gravity_port_up",
+ "sp_port",
+ "gravity port (leading up)"
+ },
+ {
+ "sp_sniksnak",
+ "sp_sniksnak",
+ "snik snak"
+ },
+ {
+ "sp_disk_yellow",
+ "sp_disk_yellow",
+ "yellow disk"
+ },
+ {
+ "sp_terminal",
+ "sp_terminal",
+ "terminal"
+ },
+ {
+ "sp_disk_red",
+ "dynamite",
+ "red disk"
+ },
+ {
+ "sp_port_vertical",
+ "sp_port",
+ "port (vertical)"
+ },
+ {
+ "sp_port_horizontal",
+ "sp_port",
+ "port (horizontal)"
+ },
+ {
+ "sp_port_any",
+ "sp_port",
+ "port (any direction)"
+ },
+ {
+ "sp_electron",
+ "sp_electron",
+ "electron"
+ },
+ {
+ "sp_buggy_base",
+ "sp_buggy_base",
+ "buggy base"
+ },
+ {
+ "sp_chip_left",
+ "wall",
+ "chip (left half)"
+ },
+ {
+ "sp_chip_right",
+ "wall",
+ "chip (right half)"
+ },
+ {
+ "sp_hardware_base_1",
+ "wall",
+ "hardware"
+ },
+ {
+ "sp_hardware_green",
+ "wall",
+ "hardware"
+ },
+ {
+ "sp_hardware_blue",
+ "wall",
+ "hardware"
+ },
+ {
+ "sp_hardware_red",
+ "wall",
+ "hardware"
+ },
+ {
+ "sp_hardware_yellow",
+ "wall",
+ "hardware"
+ },
+ {
+ "sp_hardware_base_2",
+ "wall",
+ "hardware"
+ },
+ {
+ "sp_hardware_base_3",
+ "wall",
+ "hardware"
+ },
+ {
+ "sp_hardware_base_4",
+ "wall",
+ "hardware"
+ },
+ {
+ "sp_hardware_base_5",
+ "wall",
+ "hardware"
+ },
+ {
+ "sp_hardware_base_6",
+ "wall",
+ "hardware"
+ },
+ {
+ "sp_chip_top",
+ "wall",
+ "chip (upper half)"
+ },
+ {
+ "sp_chip_bottom",
+ "wall",
+ "chip (lower half)"
+ },
+ {
+ "em_gate_1_gray",
+ "gate",
+ "gray door (EM style, red key)"
+ },
+ {
+ "em_gate_2_gray",
+ "gate",
+ "gray door (EM style, yellow key)"
+ },
+ {
+ "em_gate_3_gray",
+ "gate",
+ "gray door (EM style, green key)"
+ },
+ {
+ "em_gate_4_gray",
+ "gate",
+ "gray door (EM style, blue key)"
+ },
+ {
+ "unused_254",
+ "unused",
+ "(not used)"
+ },
+ {
+ "unused_255",
+ "unused",
+ "(not used)"
+ },
+ {
+ "pearl",
+ "pearl",
+ "pearl"
+ },
+ {
+ "crystal",
+ "crystal",
+ "crystal"
+ },
+ {
+ "wall_pearl",
+ "wall",
+ "wall with pearl"
+ },
+ {
+ "wall_crystal",
+ "wall",
+ "wall with crystal"
+ },
+ {
+ "door_white",
+ "gate",
+ "white door"
+ },
+ {
+ "door_white_gray",
+ "gate",
+ "gray door (opened by white key)"
+ },
+ {
+ "key_white",
+ "key",
+ "white key"
+ },
+ {
+ "shield_normal",
+ "shield_normal",
+ "shield (normal)"
+ },
+ {
+ "extra_time",
+ "extra_time",
+ "extra time"
+ },
+ {
+ "switchgate_open",
+ "switchgate",
+ "switch gate (open)"
+ },
+ {
+ "switchgate_closed",
+ "switchgate",
+ "switch gate (closed)"
+ },
+ {
+ "switchgate_switch_up",
+ "switchgate_switch",
+ "switch for switch gate"
+ },
+ {
+ "switchgate_switch_down",
+ "switchgate_switch",
+ "switch for switch gate"
+ },
+ {
+ "unused_269",
+ "unused",
+ "-"
+ },
+ {
+ "unused_270",
+ "unused",
+ "-"
+ },
+ {
+ "conveyor_belt_1_left",
+ "conveyor_belt",
+ "red conveyor belt (left)"
+ },
+ {
+ "conveyor_belt_1_middle",
+ "conveyor_belt",
+ "red conveyor belt (middle)"
+ },
+ {
+ "conveyor_belt_1_right",
+ "conveyor_belt",
+ "red conveyor belt (right)"
+ },
+ {
+ "conveyor_belt_1_switch_left",
+ "conveyor_belt_switch",
+ "switch for red conveyor belt (left)"
+ },
+ {
+ "conveyor_belt_1_switch_middle",
+ "conveyor_belt_switch",
+ "switch for red conveyor belt (middle)"
+ },
+ {
+ "conveyor_belt_1_switch_right",
+ "conveyor_belt_switch",
+ "switch for red conveyor belt (right)"
+ },
+ {
+ "conveyor_belt_2_left",
+ "conveyor_belt",
+ "yellow conveyor belt (left)"
+ },
+ {
+ "conveyor_belt_2_middle",
+ "conveyor_belt",
+ "yellow conveyor belt (middle)"
+ },
+ {
+ "conveyor_belt_2_right",
+ "conveyor_belt",
+ "yellow conveyor belt (right)"
+ },
+ {
+ "conveyor_belt_2_switch_left",
+ "conveyor_belt_switch",
+ "switch for yellow conveyor belt (left)"
+ },
+ {
+ "conveyor_belt_2_switch_middle",
+ "conveyor_belt_switch",
+ "switch for yellow conveyor belt (middle)"
+ },
+ {
+ "conveyor_belt_2_switch_right",
+ "conveyor_belt_switch",
+ "switch for yellow conveyor belt (right)"
+ },
+ {
+ "conveyor_belt_3_left",
+ "conveyor_belt",
+ "green conveyor belt (left)"
+ },
+ {
+ "conveyor_belt_3_middle",
+ "conveyor_belt",
+ "green conveyor belt (middle)"
+ },
+ {
+ "conveyor_belt_3_right",
+ "conveyor_belt",
+ "green conveyor belt (right)"
+ },
+ {
+ "conveyor_belt_3_switch_left",
+ "conveyor_belt_switch",
+ "switch for green conveyor belt (left)"
+ },
+ {
+ "conveyor_belt_3_switch_middle",
+ "conveyor_belt_switch",
+ "switch for green conveyor belt (middle)"
+ },
+ {
+ "conveyor_belt_3_switch_right",
+ "conveyor_belt_switch",
+ "switch for green conveyor belt (right)"
+ },
+ {
+ "conveyor_belt_4_left",
+ "conveyor_belt",
+ "blue conveyor belt (left)"
+ },
+ {
+ "conveyor_belt_4_middle",
+ "conveyor_belt",
+ "blue conveyor belt (middle)"
+ },
+ {
+ "conveyor_belt_4_right",
+ "conveyor_belt",
+ "blue conveyor belt (right)"
+ },
+ {
+ "conveyor_belt_4_switch_left",
+ "conveyor_belt_switch",
+ "switch for blue conveyor belt (left)"
+ },
+ {
+ "conveyor_belt_4_switch_middle",
+ "conveyor_belt_switch",
+ "switch for blue conveyor belt (middle)"
+ },
+ {
+ "conveyor_belt_4_switch_right",
+ "conveyor_belt_switch",
+ "switch for blue conveyor belt (right)"
+ },
+ {
+ "landmine",
+ "sand",
+ "land mine"
+ },
+ {
+ "envelope",
+ "envelope",
+ "mail envelope"
+ },
+ {
+ "light_switch",
+ "light_switch",
+ "light switch (off)"
+ },
+ {
+ "light_switch_active",
+ "light_switch",
+ "light switch (on)"
+ },
+ {
+ "sign_exclamation",
+ "wall",
+ "sign (exclamation)"
+ },
+ {
+ "sign_radioactivity",
+ "wall",
+ "sign (radio activity)"
+ },
+ {
+ "sign_stop",
+ "wall",
+ "sign (stop)"
+ },
+ {
+ "sign_wheelchair",
+ "wall",
+ "sign (wheel chair)"
+ },
+ {
+ "sign_parking",
+ "wall",
+ "sign (parking)"
+ },
+ {
+ "sign_oneway",
+ "wall",
+ "sign (one way)"
+ },
+ {
+ "sign_heart",
+ "wall",
+ "sign (heart)"
+ },
+ {
+ "sign_triangle",
+ "wall",
+ "sign (triangle)"
+ },
+ {
+ "sign_round",
+ "wall",
+ "sign (round)"
+ },
+ {
+ "sign_exit",
+ "wall",
+ "sign (exit)"
+ },
+ {
+ "sign_yinyang",
+ "wall",
+ "sign (yin yang)"
+ },
+ {
+ "sign_other",
+ "wall",
+ "sign (other)"
+ },
+ {
+ "mole_left",
+ "mole",
+ "mole (starts moving left)"
+ },
+ {
+ "mole_right",
+ "mole",
+ "mole (starts moving right)"
+ },
+ {
+ "mole_up",
+ "mole",
+ "mole (starts moving up)"
+ },
+ {
+ "mole_down",
+ "mole",
+ "mole (starts moving down)"
+ },
+ {
+ "steelwall_slippery",
+ "wall",
+ "slippery steel wall"
+ },
+ {
+ "invisible_sand",
+ "sand",
+ "invisible sand"
+ },
+ {
+ "dx_unknown_15",
+ "unknown",
+ "dx unknown element 15"
+ },
+ {
+ "dx_unknown_42",
+ "unknown",
+ "dx unknown element 42"
+ },
+ {
+ "unused_319",
+ "unused",
+ "(not used)"
+ },
+ {
+ "unused_320",
+ "unused",
+ "(not used)"
+ },
+ {
+ "shield_deadly",
+ "shield_deadly",
+ "shield (deadly, kills enemies)"
+ },
+ {
+ "timegate_open",
+ "timegate",
+ "time gate (open)"
+ },
+ {
+ "timegate_closed",
+ "timegate",
+ "time gate (closed)"
+ },
+ {
+ "timegate_switch_active",
+ "timegate_switch",
+ "switch for time gate"
+ },
+ {
+ "timegate_switch",
+ "timegate_switch",
+ "switch for time gate"
+ },
+ {
+ "balloon",
+ "balloon",
+ "balloon"
+ },
+ {
+ "balloon_switch_left",
+ "balloon_switch",
+ "send balloon to the left"
+ },
+ {
+ "balloon_switch_right",
+ "balloon_switch",
+ "send balloon to the right"
+ },
+ {
+ "balloon_switch_up",
+ "balloon_switch",
+ "send balloon up"
+ },
+ {
+ "balloon_switch_down",
+ "balloon_switch",
+ "send balloon down"
+ },
+ {
+ "balloon_switch_any",
+ "balloon_switch",
+ "send balloon in any direction"
+ },
+ {
+ "emc_steelwall_1",
+ "wall",
+ "steel wall"
+ },
+ {
+ "emc_steelwall_2",
+ "wall",
+ "steel wall"
+ },
+ {
+ "emc_steelwall_3",
+ "wall",
+ "steel wall"
+ },
+ {
+ "emc_steelwall_4",
+ "wall",
+ "steel wall"
+ },
+ {
+ "emc_wall_1",
+ "wall",
+ "normal wall"
+ },
+ {
+ "emc_wall_2",
+ "wall",
+ "normal wall"
+ },
+ {
+ "emc_wall_3",
+ "wall",
+ "normal wall"
+ },
+ {
+ "emc_wall_4",
+ "wall",
+ "normal wall"
+ },
+ {
+ "emc_wall_5",
+ "wall",
+ "normal wall"
+ },
+ {
+ "emc_wall_6",
+ "wall",
+ "normal wall"
+ },
+ {
+ "emc_wall_7",
+ "wall",
+ "normal wall"
+ },
+ {
+ "emc_wall_8",
+ "wall",
+ "normal wall"
+ },
+ {
+ "tube_any",
+ "tube",
+ "tube (any direction)"
+ },
+ {
+ "tube_vertical",
+ "tube",
+ "tube (vertical)"
+ },
+ {
+ "tube_horizontal",
+ "tube",
+ "tube (horizontal)"
+ },
+ {
+ "tube_vertical_left",
+ "tube",
+ "tube (vertical & left)"
+ },
+ {
+ "tube_vertical_right",
+ "tube",
+ "tube (vertical & right)"
+ },
+ {
+ "tube_horizontal_up",
+ "tube",
+ "tube (horizontal & up)"
+ },
+ {
+ "tube_horizontal_down",
+ "tube",
+ "tube (horizontal & down)"
+ },
+ {
+ "tube_left_up",
+ "tube",
+ "tube (left & up)"
+ },
+ {
+ "tube_left_down",
+ "tube",
+ "tube (left & down)"
+ },
+ {
+ "tube_right_up",
+ "tube",
+ "tube (right & up)"
+ },
+ {
+ "tube_right_down",
+ "tube",
+ "tube (right & down)"
+ },
+ {
+ "spring",
+ "spring",
+ "spring"
+ },
+ {
+ "trap",
+ "trap",
+ "trap"
+ },
+ {
+ "dx_supabomb",
+ "bomb",
+ "stable bomb (DX style)"
+ },
+ {
+ "unused_358",
+ "unused",
+ "-"
+ },
+ {
+ "unused_359",
+ "unused",
+ "-"
+ },
+ {
+ "custom_1",
+ "custom",
+ "custom element 1"
+ },
+ {
+ "custom_2",
+ "custom",
+ "custom element 2"
+ },
+ {
+ "custom_3",
+ "custom",
+ "custom element 3"
+ },
+ {
+ "custom_4",
+ "custom",
+ "custom element 4"
+ },
+ {
+ "custom_5",
+ "custom",
+ "custom element 5"
+ },
+ {
+ "custom_6",
+ "custom",
+ "custom element 6"
+ },
+ {
+ "custom_7",
+ "custom",
+ "custom element 7"
+ },
+ {
+ "custom_8",
+ "custom",
+ "custom element 8"
+ },
+ {
+ "custom_9",
+ "custom",
+ "custom element 9"
+ },
+ {
+ "custom_10",
+ "custom",
+ "custom element 10"
+ },
+ {
+ "custom_11",
+ "custom",
+ "custom element 11"
+ },
+ {
+ "custom_12",
+ "custom",
+ "custom element 12"
+ },
+ {
+ "custom_13",
+ "custom",
+ "custom element 13"
+ },
+ {
+ "custom_14",
+ "custom",
+ "custom element 14"
+ },
+ {
+ "custom_15",
+ "custom",
+ "custom element 15"
+ },
+ {
+ "custom_16",
+ "custom",
+ "custom element 16"
+ },
+ {
+ "custom_17",
+ "custom",
+ "custom element 17"
+ },
+ {
+ "custom_18",
+ "custom",
+ "custom element 18"
+ },
+ {
+ "custom_19",
+ "custom",
+ "custom element 19"
+ },
+ {
+ "custom_20",
+ "custom",
+ "custom element 20"
+ },
+ {
+ "custom_21",
+ "custom",
+ "custom element 21"
+ },
+ {
+ "custom_22",
+ "custom",
+ "custom element 22"
+ },
+ {
+ "custom_23",
+ "custom",
+ "custom element 23"
+ },
+ {
+ "custom_24",
+ "custom",
+ "custom element 24"
+ },
+ {
+ "custom_25",
+ "custom",
+ "custom element 25"
+ },
+ {
+ "custom_26",
+ "custom",
+ "custom element 26"
+ },
+ {
+ "custom_27",
+ "custom",
+ "custom element 27"
+ },
+ {
+ "custom_28",
+ "custom",
+ "custom element 28"
+ },
+ {
+ "custom_29",
+ "custom",
+ "custom element 29"
+ },
+ {
+ "custom_30",
+ "custom",
+ "custom element 30"
+ },
+ {
+ "custom_31",
+ "custom",
+ "custom element 31"
+ },
+ {
+ "custom_32",
+ "custom",
+ "custom element 32"
+ },
+ {
+ "custom_33",
+ "custom",
+ "custom element 33"
+ },
+ {
+ "custom_34",
+ "custom",
+ "custom element 34"
+ },
+ {
+ "custom_35",
+ "custom",
+ "custom element 35"
+ },
+ {
+ "custom_36",
+ "custom",
+ "custom element 36"
+ },
+ {
+ "custom_37",
+ "custom",
+ "custom element 37"
+ },
+ {
+ "custom_38",
+ "custom",
+ "custom element 38"
+ },
+ {
+ "custom_39",
+ "custom",
+ "custom element 39"
+ },
+ {
+ "custom_40",
+ "custom",
+ "custom element 40"
+ },
+ {
+ "custom_41",
+ "custom",
+ "custom element 41"
+ },
+ {
+ "custom_42",
+ "custom",
+ "custom element 42"
+ },
+ {
+ "custom_43",
+ "custom",
+ "custom element 43"
+ },
+ {
+ "custom_44",
+ "custom",
+ "custom element 44"
+ },
+ {
+ "custom_45",
+ "custom",
+ "custom element 45"
+ },
+ {
+ "custom_46",
+ "custom",
+ "custom element 46"
+ },
+ {
+ "custom_47",
+ "custom",
+ "custom element 47"
+ },
+ {
+ "custom_48",
+ "custom",
+ "custom element 48"
+ },
+ {
+ "custom_49",
+ "custom",
+ "custom element 49"
+ },
+ {
+ "custom_50",
+ "custom",
+ "custom element 50"
+ },
+ {
+ "custom_51",
+ "custom",
+ "custom element 51"
+ },
+ {
+ "custom_52",
+ "custom",
+ "custom element 52"
+ },
+ {
+ "custom_53",
+ "custom",
+ "custom element 53"
+ },
+ {
+ "custom_54",
+ "custom",
+ "custom element 54"
+ },
+ {
+ "custom_55",
+ "custom",
+ "custom element 55"
+ },
+ {
+ "custom_56",
+ "custom",
+ "custom element 56"
+ },
+ {
+ "custom_57",
+ "custom",
+ "custom element 57"
+ },
+ {
+ "custom_58",
+ "custom",
+ "custom element 58"
+ },
+ {
+ "custom_59",
+ "custom",
+ "custom element 59"
+ },
+ {
+ "custom_60",
+ "custom",
+ "custom element 60"
+ },
+ {
+ "custom_61",
+ "custom",
+ "custom element 61"
+ },
+ {
+ "custom_62",
+ "custom",
+ "custom element 62"
+ },
+ {
+ "custom_63",
+ "custom",
+ "custom element 63"
+ },
+ {
+ "custom_64",
+ "custom",
+ "custom element 64"
+ },
+ {
+ "custom_65",
+ "custom",
+ "custom element 65"
+ },
+ {
+ "custom_66",
+ "custom",
+ "custom element 66"
+ },
+ {
+ "custom_67",
+ "custom",
+ "custom element 67"
+ },
+ {
+ "custom_68",
+ "custom",
+ "custom element 68"
+ },
+ {
+ "custom_69",
+ "custom",
+ "custom element 69"
+ },
+ {
+ "custom_70",
+ "custom",
+ "custom element 70"
+ },
+ {
+ "custom_71",
+ "custom",
+ "custom element 71"
+ },
+ {
+ "custom_72",
+ "custom",
+ "custom element 72"
+ },
+ {
+ "custom_73",
+ "custom",
+ "custom element 73"
+ },
+ {
+ "custom_74",
+ "custom",
+ "custom element 74"
+ },
+ {
+ "custom_75",
+ "custom",
+ "custom element 75"
+ },
+ {
+ "custom_76",
+ "custom",
+ "custom element 76"
+ },
+ {
+ "custom_77",
+ "custom",
+ "custom element 77"
+ },
+ {
+ "custom_78",
+ "custom",
+ "custom element 78"
+ },
+ {
+ "custom_79",
+ "custom",
+ "custom element 79"
+ },
+ {
+ "custom_80",
+ "custom",
+ "custom element 80"
+ },
+ {
+ "custom_81",
+ "custom",
+ "custom element 81"
+ },
+ {
+ "custom_82",
+ "custom",
+ "custom element 82"
+ },
+ {
+ "custom_83",
+ "custom",
+ "custom element 83"
+ },
+ {
+ "custom_84",
+ "custom",
+ "custom element 84"
+ },
+ {
+ "custom_85",
+ "custom",
+ "custom element 85"
+ },
+ {
+ "custom_86",
+ "custom",
+ "custom element 86"
+ },
+ {
+ "custom_87",
+ "custom",
+ "custom element 87"
+ },
+ {
+ "custom_88",
+ "custom",
+ "custom element 88"
+ },
+ {
+ "custom_89",
+ "custom",
+ "custom element 89"
+ },
+ {
+ "custom_90",
+ "custom",
+ "custom element 90"
+ },
+ {
+ "custom_91",
+ "custom",
+ "custom element 91"
+ },
+ {
+ "custom_92",
+ "custom",
+ "custom element 92"
+ },
+ {
+ "custom_93",
+ "custom",
+ "custom element 93"
+ },
+ {
+ "custom_94",
+ "custom",
+ "custom element 94"
+ },
+ {
+ "custom_95",
+ "custom",
+ "custom element 95"
+ },
+ {
+ "custom_96",
+ "custom",
+ "custom element 96"
+ },
+ {
+ "custom_97",
+ "custom",
+ "custom element 97"
+ },
+ {
+ "custom_98",
+ "custom",
+ "custom element 98"
+ },
+ {
+ "custom_99",
+ "custom",
+ "custom element 99"
+ },
+ {
+ "custom_100",
+ "custom",
+ "custom element 100"
+ },
+ {
+ "custom_101",
+ "custom",
+ "custom element 101"
+ },
+ {
+ "custom_102",
+ "custom",
+ "custom element 102"
+ },
+ {
+ "custom_103",
+ "custom",
+ "custom element 103"
+ },
+ {
+ "custom_104",
+ "custom",
+ "custom element 104"
+ },
+ {
+ "custom_105",
+ "custom",
+ "custom element 105"
+ },
+ {
+ "custom_106",
+ "custom",
+ "custom element 106"
+ },
+ {
+ "custom_107",
+ "custom",
+ "custom element 107"
+ },
+ {
+ "custom_108",
+ "custom",
+ "custom element 108"
+ },
+ {
+ "custom_109",
+ "custom",
+ "custom element 109"
+ },
+ {
+ "custom_110",
+ "custom",
+ "custom element 110"
+ },
+ {
+ "custom_111",
+ "custom",
+ "custom element 111"
+ },
+ {
+ "custom_112",
+ "custom",
+ "custom element 112"
+ },
+ {
+ "custom_113",
+ "custom",
+ "custom element 113"
+ },
+ {
+ "custom_114",
+ "custom",
+ "custom element 114"
+ },
+ {
+ "custom_115",
+ "custom",
+ "custom element 115"
+ },
+ {
+ "custom_116",
+ "custom",
+ "custom element 116"
+ },
+ {
+ "custom_117",
+ "custom",
+ "custom element 117"
+ },
+ {
+ "custom_118",
+ "custom",
+ "custom element 118"
+ },
+ {
+ "custom_119",
+ "custom",
+ "custom element 119"
+ },
+ {
+ "custom_120",
+ "custom",
+ "custom element 120"
+ },
+ {
+ "custom_121",
+ "custom",
+ "custom element 121"
+ },
+ {
+ "custom_122",
+ "custom",
+ "custom element 122"
+ },
+ {
+ "custom_123",
+ "custom",
+ "custom element 123"
+ },
+ {
+ "custom_124",
+ "custom",
+ "custom element 124"
+ },
+ {
+ "custom_125",
+ "custom",
+ "custom element 125"
+ },
+ {
+ "custom_126",
+ "custom",
+ "custom element 126"
+ },
+ {
+ "custom_127",
+ "custom",
+ "custom element 127"
+ },
+ {
+ "custom_128",
+ "custom",
+ "custom element 128"
+ },
+
+ /* ----------------------------------------------------------------------- */
+ /* "real" (and therefore drawable) runtime elements */
+ /* ----------------------------------------------------------------------- */
+
+ {
+ "em_key_1",
+ "key",
+ "-"
+ },
+ {
+ "em_key_2",
+ "key",
+ "-"
+ },
+ {
+ "em_key_3",
+ "key",
+ "-"
+ },
+ {
+ "em_key_4",
+ "key",
+ "-"
+ },
+ {
+ "dynabomb_player_1_active",
+ "dynabomb",
+ "-"
+ },
+ {
+ "dynabomb_player_2_active",
+ "dynabomb",
+ "-"
+ },
+ {
+ "dynabomb_player_3_active",
+ "dynabomb",
+ "-"
+ },
+ {
+ "dynabomb_player_4_active",
+ "dynabomb",
+ "-"
+ },
+ {
+ "sp_disk_red_active",
+ "dynamite",
+ "-"
+ },
+ {
+ "switchgate_opening",
+ "switchgate",
+ "-"
+ },
+ {
+ "switchgate_closing",
+ "switchgate",
+ "-"
+ },
+ {
+ "timegate_opening",
+ "timegate",
+ "-"
+ },
+ {
+ "timegate_closing",
+ "timegate",
+ "-"
+ },
+ {
+ "pearl_breaking",
+ "pearl",
+ "-"
+ },
+ {
+ "trap_active",
+ "trap",
+ "-"
+ },
+ {
+ "invisible_steelwall_active",
+ "wall",
+ "-"
+ },
+ {
+ "invisible_wall_active",
+ "wall",
+ "-"
+ },
+ {
+ "invisible_sand_active",
+ "sand",
+ "-"
+ },
+ {
+ "conveyor_belt_1_left_active",
+ "conveyor_belt",
+ "-"
+ },
+ {
+ "conveyor_belt_1_middle_active",
+ "conveyor_belt",
+ "-"
+ },
+ {
+ "conveyor_belt_1_right_active",
+ "conveyor_belt",
+ "-"
+ },
+ {
+ "conveyor_belt_2_left_active",
+ "conveyor_belt",
+ "-"
+ },
+ {
+ "conveyor_belt_2_middle_active",
+ "conveyor_belt",
+ "-"
+ },
+ {
+ "conveyor_belt_2_right_active",
+ "conveyor_belt",
+ "-"
+ },
+ {
+ "conveyor_belt_3_left_active",
+ "conveyor_belt",
+ "-"
+ },
+ {
+ "conveyor_belt_3_middle_active",
+ "conveyor_belt",
+ "-"
+ },
+ {
+ "conveyor_belt_3_right_active",
+ "conveyor_belt",
+ "-"
+ },
+ {
+ "conveyor_belt_4_left_active",
+ "conveyor_belt",
+ "-"
+ },
+ {
+ "conveyor_belt_4_middle_active",
+ "conveyor_belt",
+ "-"
+ },
+ {
+ "conveyor_belt_4_right_active",
+ "conveyor_belt",
+ "-"
+ },
+ {
+ "exit_opening",
+ "exit",
+ "-"
+ },
+ {
+ "sp_exit_open",
+ "sp_exit",
+ "-"
+ },
+ {
+ "sp_terminal_active",
+ "sp_terminal",
+ "-"
+ },
+ {
+ "sp_buggy_base_activating",
+ "sp_buggy_base",
+ "-"
+ },
+ {
+ "sp_buggy_base_active",
+ "sp_buggy_base",
+ "-"
+ },
+ {
+ "sp_murphy_clone",
+ "murphy_clone",
+ "-"
+ },
+ {
+ "amoeba_dropping",
+ "amoeba",
+ "-"
+ },
+ {
+ "quicksand_emptying",
+ "quicksand",
+ "-"
+ },
+ {
+ "magic_wall_active",
+ "magic_wall",
+ "-"
+ },
+ {
+ "bd_magic_wall_active",
+ "magic_wall",
+ "-"
+ },
+ {
+ "magic_wall_full",
+ "magic_wall",
+ "-"
+ },
+ {
+ "bd_magic_wall_full",
+ "magic_wall",
+ "-"
+ },
+ {
+ "magic_wall_emptying",
+ "magic_wall",
+ "-"
+ },
+ {
+ "bd_magic_wall_emptying",
+ "magic_wall",
+ "-"
+ },
+ {
+ "magic_wall_dead",
+ "magic_wall",
+ "-"
+ },
+ {
+ "bd_magic_wall_dead",
+ "magic_wall",
+ "-"
+ },
+
+ /* ----------------------------------------------------------------------- */
+ /* "unreal" (and therefore not drawable) runtime elements */
+ /* ----------------------------------------------------------------------- */
+
+ {
+ "blocked",
+ "-",
+ "-"
+ },
+ {
+ "explosion",
+ "-",
+ "-"
+ },
+ {
+ "nut_breaking",
+ "-",
+ "-"
+ },
+ {
+ "diamond_breaking",
+ "-",
+ "-"
+ },
+ {
+ "acid_splash_left",
+ "-",
+ "-"
+ },
+ {
+ "acid_splash_right",
+ "-",
+ "-"
+ },
+ {
+ "amoeba_growing",
+ "-",
+ "-"
+ },
+ {
+ "amoeba_shrinking",
+ "-",
+ "-"
+ },
+ {
+ "expandable_wall_growing",
+ "-",
+ "-"
+ },
+ {
+ "flames",
+ "-",
+ "-"
+ },
+ {
+ "player_is_leaving",
+ "-",
+ "-"
+ },
+ {
+ "quicksand_filling",
+ "quicksand",
+ "-"
+ },
+ {
+ "magic_wall_filling",
+ "-",
+ "-"
+ },
+ {
+ "bd_magic_wall_filling",
+ "-",
+ "-"
+ },
+
+ /* ----------------------------------------------------------------------- */
+ /* dummy elements (never used as game elements, only used as graphics) */
+ /* ----------------------------------------------------------------------- */
-/* filenames of sound effects */
-char *sound_name[NUM_SOUNDS] =
+ {
+ "steelwall_topleft",
+ "-",
+ "-"
+ },
+ {
+ "steelwall_topright",
+ "-",
+ "-"
+ },
+ {
+ "steelwall_bottomleft",
+ "-",
+ "-"
+ },
+ {
+ "steelwall_bottomright",
+ "-",
+ "-"
+ },
+ {
+ "steelwall_horizontal",
+ "-",
+ "-"
+ },
+ {
+ "steelwall_vertical",
+ "-",
+ "-"
+ },
+ {
+ "invisible_steelwall_topleft",
+ "-",
+ "-"
+ },
+ {
+ "invisible_steelwall_topright",
+ "-",
+ "-"
+ },
+ {
+ "invisible_steelwall_bottomleft",
+ "-",
+ "-"
+ },
+ {
+ "invisible_steelwall_bottomright",
+ "-",
+ "-"
+ },
+ {
+ "invisible_steelwall_horizontal",
+ "-",
+ "-"
+ },
+ {
+ "invisible_steelwall_vertical",
+ "-",
+ "-"
+ },
+ {
+ "dynabomb",
+ "-",
+ "-"
+ },
+ {
+ "dynabomb_active",
+ "-",
+ "-"
+ },
+ {
+ "dynabomb_player_1",
+ "-",
+ "-"
+ },
+ {
+ "dynabomb_player_2",
+ "-",
+ "-"
+ },
+ {
+ "dynabomb_player_3",
+ "-",
+ "-"
+ },
+ {
+ "dynabomb_player_4",
+ "-",
+ "-"
+ },
+ {
+ "shield_normal_active",
+ "-",
+ "-"
+ },
+ {
+ "shield_deadly_active",
+ "-",
+ "-"
+ },
+ {
+ "[default]",
+ "default",
+ "-"
+ },
+ {
+ "[bd_default]",
+ "bd_default",
+ "-"
+ },
+ {
+ "[sp_default]",
+ "sp_default",
+ "-"
+ },
+ {
+ "[sb_default]",
+ "sb_default",
+ "-"
+ },
+
+ /* keyword to stop parser: "ELEMENT_INFO_END" <-- do not change! */
+
+ {
+ NULL,
+ NULL,
+ NULL
+ }
+};
+
+
+/* ------------------------------------------------------------------------- */
+/* element action and direction definitions */
+/* ------------------------------------------------------------------------- */
+
+struct ElementActionInfo element_action_info[NUM_ACTIONS + 1 + 1] =
{
- "amoebe.wav",
- "antigrav.wav",
- "autsch.wav",
- "blurb.wav",
- "bong.wav",
- "buing.wav",
- "deng.wav",
- "fuel.wav",
- "gong.wav",
- "halloffame.wav",
- "holz.wav",
- "hui.wav",
- "kabumm.wav",
- "kink.wav",
- "klapper.wav",
- "kling.wav",
- "klopf.wav",
- "klumpf.wav",
- "knack.wav",
- "knurk.wav",
- "krach.wav",
- "lachen.wav",
- "laser.wav",
- "miep.wav",
- "njam.wav",
- "oeffnen.wav",
- "pling.wav",
- "pong.wav",
- "pusch.wav",
- "quiek.wav",
- "quirk.wav",
- "rhythmloop.wav",
- "roaaar.wav",
- "roehr.wav",
- "rumms.wav",
- "schlopp.wav",
- "schlurf.wav",
- "schrff.wav",
- "schwirr.wav",
- "sirr.wav",
- "slurp.wav",
- "sproing.wav",
- "warnton.wav",
- "whoosh.wav",
- "zisch.wav",
- "base.wav",
- "infotron.wav",
- "zonkdown.wav",
- "zonkpush.wav",
- "bug.wav",
- "boom.wav",
- "booom.wav",
- "exit.wav",
- "empty.wav",
- "gate.wav"
+ { ".[DEFAULT]", ACTION_DEFAULT, TRUE },
+ { ".waiting", ACTION_WAITING, TRUE },
+ { ".falling", ACTION_FALLING, TRUE },
+ { ".moving", ACTION_MOVING, TRUE },
+ { ".digging", ACTION_DIGGING, FALSE },
+ { ".snapping", ACTION_SNAPPING, FALSE },
+ { ".collecting", ACTION_COLLECTING, FALSE },
+ { ".dropping", ACTION_DROPPING, FALSE },
+ { ".pushing", ACTION_PUSHING, FALSE },
+ { ".walking", ACTION_WALKING, FALSE },
+ { ".passing", ACTION_PASSING, FALSE },
+ { ".impact", ACTION_IMPACT, FALSE },
+ { ".breaking", ACTION_BREAKING, FALSE },
+ { ".activating", ACTION_ACTIVATING, FALSE },
+ { ".deactivating", ACTION_DEACTIVATING, FALSE },
+ { ".opening", ACTION_OPENING, FALSE },
+ { ".closing", ACTION_CLOSING, FALSE },
+ { ".attacking", ACTION_ATTACKING, TRUE },
+ { ".growing", ACTION_GROWING, TRUE },
+ { ".shrinking", ACTION_SHRINKING, FALSE },
+ { ".active", ACTION_ACTIVE, TRUE },
+ { ".filling", ACTION_FILLING, FALSE },
+ { ".emptying", ACTION_EMPTYING, FALSE },
+ { ".changing", ACTION_CHANGING, FALSE },
+ { ".exploding", ACTION_EXPLODING, FALSE },
+ { ".dying", ACTION_DYING, FALSE },
+ { ".other", ACTION_OTHER, FALSE },
+
+ /* empty suffix always matches -- check as last entry in InitSoundInfo() */
+ { "", ACTION_DEFAULT, TRUE },
+
+ { NULL, 0, 0 }
};
-struct SoundEffectInfo sound_effects[] =
+struct ElementDirectionInfo element_direction_info[NUM_DIRECTIONS + 1] =
{
- /* sounds for Boulder Dash style elements and actions */
- { "bd_empty_space.digging", "empty.wav" },
- { "bd_sand.digging", "schlurf.wav" },
- { "bd_diamond.collecting", "pong.wav" },
- { "bd_diamond.impact", "pling.wav" },
- { "bd_rock.pushing", "pusch.wav" },
- { "bd_rock.impact", "klopf.wav" },
- { "bd_magic_wall.activating", "quirk.wav" },
- { "bd_magic_wall.changing", "quirk.wav" },
- { "bd_magic_wall.running", "miep.wav" },
- { "bd_amoeba.waiting", SND_FILE_UNDEFINED },
- { "bd_amoeba.creating", "amoebe.wav" },
- { "bd_amoeba.turning_to_gem", "pling.wav" },
- { "bd_amoeba.turning_to_rock", "klopf.wav" },
- { "bd_butterfly.moving", "klapper.wav" },
- { "bd_butterfly.waiting", "klapper.wav" },
- { "bd_firefly.moving", "roehr.wav" },
- { "bd_firefly.waiting", "roehr.wav" },
- { "bd_exit.entering", "buing.wav" },
-
- /* sounds for Supaplex style elements and actions */
- { "sp_empty_space.digging", "empty.wav" },
- { "sp_base.digging", "base.wav" },
- { "sp_buggy_base.digging", "base.wav" },
- { "sp_buggy_base.activating", "bug.wav" },
- { "sp_infotron.collecting", "infotron.wav" },
- { "sp_infotron.impact", "pling.wav" },
- { "sp_zonk.pushing", "zonkpush.wav" },
- { "sp_zonk.impact", "zonkdown.wav" },
- { "sp_disk_red.collecting", "infotron.wav" },
- { "sp_disk_orange.pushing", "zonkpush.wav" },
- { "sp_disk_yellow.pushing", "pusch.wav" },
- { "sp_port.passing", "gate.wav" },
- { "sp_exit.entering", "exit.wav" },
- { "sp_element.exploding", "booom.wav" },
- { "sp_sniksnak.moving", SND_FILE_UNDEFINED },
- { "sp_sniksnak.waiting", SND_FILE_UNDEFINED },
- { "sp_electron.moving", SND_FILE_UNDEFINED },
- { "sp_electron.waiting", SND_FILE_UNDEFINED },
- { "sp_terminal.activating", SND_FILE_UNDEFINED },
-
- /* sounds for Sokoban style elements and actions */
- { "sokoban_object.pushing", "pusch.wav" },
- { "sokoban_field.filling", "deng.wav" },
- { "sokoban_field.clearing", SND_FILE_UNDEFINED },
- { "sokoban_game.solving", "buing.wav" },
-
- /* sounds for Emerald Mine style elements and actions */
- { "empty_space.digging", "empty.wav" },
- { "sand.digging", "schlurf.wav" },
- { "emerald.collecting", "pong.wav" },
- { "emerald.impact", "pling.wav" },
- { "diamond.collecting", "pong.wav" },
- { "diamond.impact", "pling.wav" },
- { "diamond.breaking", "quirk.wav" },
- { "rock.pushing", "pusch.wav" },
- { "rock.impact", "klopf.wav" },
- { "bomb.pushing", "pusch.wav" },
- { "nut.pushing", "knurk.wav" },
- { "nut.cracking", "knack.wav" },
- { "nut.impact", "klumpf.wav" },
- { "dynamite.collecting", "pong.wav" },
- { "dynamite.placing", "deng.wav" },
- { "dynamite.burning", "zisch.wav" },
- { "key.collecting", "pong.wav" },
- { "gate.passing", "gate.wav" },
- { "bug.moving", "klapper.wav" },
- { "bug.waiting", "klapper.wav" },
- { "spaceship.moving", "roehr.wav" },
- { "spaceship.waiting", "roehr.wav" },
- { "yamyam.moving", SND_FILE_UNDEFINED },
- { "yamyam.waiting", "njam.wav" },
- { "yamyam.eating_diamond", SND_FILE_UNDEFINED },
- { "robot.stepping", "schlurf.wav" },
- { "robot.waiting", SND_FILE_UNDEFINED },
- { "robot_wheel.activating", "deng.wav" },
- { "robot_wheel.running", "miep.wav" },
- { "magic_wall.activating", "quirk.wav" },
- { "magic_wall.changing", "quirk.wav" },
- { "magic_wall.running", "miep.wav" },
- { "amoeba.waiting", SND_FILE_UNDEFINED },
- { "amoeba.creating", "amoebe.wav" },
- { "amoeba.dropping", SND_FILE_UNDEFINED },
- { "acid.splashing", "blurb.wav" },
- { "quicksand.filling", SND_FILE_UNDEFINED },
- { "quicksand.slipping_through", SND_FILE_UNDEFINED },
- { "quicksand.emptying", SND_FILE_UNDEFINED },
- { "exit.opening", "oeffnen.wav" },
- { "exit.entering", "buing.wav" },
-
- /* sounds for Emerald Mine Club style elements and actions */
- { "balloon.moving", SND_FILE_UNDEFINED },
- { "balloon.waiting", SND_FILE_UNDEFINED },
- { "balloon.pushing", "schlurf.wav" },
- { "balloon_switch.activating", SND_FILE_UNDEFINED },
- { "spring.moving", SND_FILE_UNDEFINED },
- { "spring.pushing", "pusch.wav" },
- { "spring.impact", "klopf.wav" },
- { "wall.growing", SND_FILE_UNDEFINED },
-
- /* sounds for Diamond Caves style elements and actions */
- { "pearl.collecting", "pong.wav" },
- { "pearl.breaking", "knack.wav" },
- { "pearl.impact", "pling.wav" },
- { "crystal.collecting", "pong.wav" },
- { "crystal.impact", "pling.wav" },
- { "envelope.collecting", "pong.wav" },
- { "sand_invisible.digging", "schlurf.wav" },
- { "shield_passive.collecting", "pong.wav" },
- { "shield_passive.activated", SND_FILE_UNDEFINED },
- { "shield_active.collecting", "pong.wav" },
- { "shield_active.activated", SND_FILE_UNDEFINED },
- { "extra_time.collecting", "gong.wav" },
- { "mole.moving", SND_FILE_UNDEFINED },
- { "mole.waiting", SND_FILE_UNDEFINED },
- { "mole.eating_amoeba", "blurb.wav" },
- { "switchgate_switch.activating", SND_FILE_UNDEFINED },
- { "switchgate.opening", "oeffnen.wav" },
- { "switchgate.closing", "oeffnen.wav" },
- { "switchgate.passing", "gate.wav" },
- { "timegate_wheel.activating", "deng.wav" },
- { "timegate_wheel.running", "miep.wav" },
- { "timegate.opening", "oeffnen.wav" },
- { "timegate.closing", "oeffnen.wav" },
- { "timegate.passing", "gate.wav" },
- { "conveyor_belt_switch.activating", SND_FILE_UNDEFINED },
- { "conveyor_belt.running", SND_FILE_UNDEFINED },
- { "light_switch.activating", SND_FILE_UNDEFINED },
- { "light_switch.deactivating", SND_FILE_UNDEFINED },
-
- /* sounds for DX Boulderdash style elements and actions */
- { "dx_bomb.pushing", "pusch.wav" },
- { "trap_inactive.digging", "schlurf.wav" },
- { "trap.activating", SND_FILE_UNDEFINED },
- { "tube.passing", SND_FILE_UNDEFINED },
-
- /* sounds for Rocks'n'Diamonds style elements and actions */
- { "amoeba.turning_to_gem", "pling.wav" },
- { "amoeba.turning_to_rock", "klopf.wav" },
- { "speed_pill.collecting", "pong.wav" },
- { "dynabomb_nr.collecting", "pong.wav" },
- { "dynabomb_sz.collecting", "pong.wav" },
- { "dynabomb_xl.collecting", "pong.wav" },
- { "dynabomb.placing", "deng.wav" },
- { "dynabomb.burning", "zisch.wav" },
- { "satellite.moving", SND_FILE_UNDEFINED },
- { "satellite.waiting", SND_FILE_UNDEFINED },
- { "satellite.pushing", "pusch.wav" },
- { "lamp.activating", "deng.wav" },
- { "lamp.deactivating", "deng.wav" },
- { "time_orb_full.collecting", "gong.wav" },
- { "time_orb_full.impact", "deng.wav" },
- { "time_orb_empty.pushing", "pusch.wav" },
- { "time_orb_empty.impact", "deng.wav" },
- { "gameoflife.waiting", SND_FILE_UNDEFINED },
- { "gameoflife.creating", "amoebe.wav" },
- { "biomaze.waiting", SND_FILE_UNDEFINED },
- { "biomaze.creating", "amoebe.wav" },
- { "pacman.moving", SND_FILE_UNDEFINED },
- { "pacman.waiting", SND_FILE_UNDEFINED },
- { "pacman.eating_amoeba", SND_FILE_UNDEFINED },
- { "dark_yamyam.moving", SND_FILE_UNDEFINED },
- { "dark_yamyam.waiting", "njam.wav" },
- { "dark_yamyam.eating_any", SND_FILE_UNDEFINED },
- { "penguin.moving", SND_FILE_UNDEFINED },
- { "penguin.waiting", SND_FILE_UNDEFINED },
- { "penguin.entering_exit", "buing.wav" },
- { "pig.moving", SND_FILE_UNDEFINED },
- { "pig.waiting", SND_FILE_UNDEFINED },
- { "pig.eating_gem", SND_FILE_UNDEFINED },
- { "dragon.moving", SND_FILE_UNDEFINED },
- { "dragon.waiting", SND_FILE_UNDEFINED },
- { "dragon.attacking", SND_FILE_UNDEFINED },
-
- /* sounds for generic elements and actions */
- { "player.dying", "autsch.wav" },
- { "element.exploding", "roaaar.wav" },
-
- /* sounds for other game actions */
- { "game.starting", SND_FILE_UNDEFINED },
- { "game.running_out_of_time", "gong.wav" },
- { "game.leveltime_bonus", "sirr.wav" },
- { "game.losing", "lachen.wav" },
- { "game.winning", SND_FILE_UNDEFINED },
-
- /* sounds for other non-game actions */
- { "menu.door_opening", "oeffnen.wav" },
- { "menu.door_closing", "oeffnen.wav" },
- { "menu.hall_of_fame", "halloffame.wav" },
- { "menu.info_screen", "rhythmloop.wav" },
+ { ".left", MV_BIT_LEFT },
+ { ".right", MV_BIT_RIGHT },
+ { ".up", MV_BIT_UP },
+ { ".down", MV_BIT_DOWN },
-#if 0
- { "[not used]", "antigrav.wav" },
- { "[not used]", "bong.wav" },
- { "[not used]", "fuel.wav" },
- { "[not used]", "holz.wav" },
- { "[not used]", "hui.wav" },
- { "[not used]", "kabumm.wav" },
- { "[not used]", "kink.wav" },
- { "[not used]", "kling.wav" },
- { "[not used]", "krach.wav" },
- { "[not used]", "laser.wav" },
- { "[not used]", "quiek.wav" },
- { "[not used]", "rumms.wav" },
- { "[not used]", "schlopp.wav" },
- { "[not used]", "schrff.wav" },
- { "[not used]", "schwirr.wav" },
- { "[not used]", "slurp.wav" },
- { "[not used]", "sproing.wav" },
- { "[not used]", "warnton.wav" },
- { "[not used]", "whoosh.wav" },
- { "[not used]", "boom.wav" },
-#endif
+ { NULL, 0 }
+};
+
+struct SpecialSuffixInfo special_suffix_info[NUM_SPECIAL_GFX_ARGS + 1] =
+{
+ { ".MAIN", GAME_MODE_MAIN, },
+ { ".LEVELS", GAME_MODE_LEVELS },
+ { ".SCORES", GAME_MODE_SCORES, },
+ { ".EDITOR", GAME_MODE_EDITOR, },
+ { ".INFO", GAME_MODE_INFO, },
+ { ".SETUP", GAME_MODE_SETUP, },
+ { ".DOOR", GAME_MODE_PSEUDO_DOOR, },
+ { ".PREVIEW", GAME_MODE_PSEUDO_PREVIEW, },
+ { ".CRUMBLED", GAME_MODE_PSEUDO_CRUMBLED, },
+
+ { NULL, 0, }
};
-struct ElementInfo element_info[] =
+struct TokenIntPtrInfo image_config_vars[] =
{
- { "empty_space", "empty space" }, /* 0 */
- { "sand", "sand" },
- { "wall", "normal wall" },
- { "wall", "round wall" },
- { "rock", "rock" },
- { "key", "key" },
- { "emerald", "emerald" },
- { "exit", "closed exit" },
- { "player", "player" },
- { "bug", "bug" },
- { "spaceship", "spaceship" }, /* 10 */
- { "yamyam", "yam yam" },
- { "robot", "robot" },
- { "wall", "steel wall" },
- { "diamond", "diamond" },
- { "amoeba", "dead amoeba" },
- { "quicksand", "empty quicksand" },
- { "quicksand", "quicksand with rock" },
- { "amoeba", "amoeba drop" },
- { "bomb", "bomb" },
- { "magic_wall", "magic wall" }, /* 20 */
- { "speed_pill", "speed pill" },
- { "acid", "acid pool" },
- { "amoeba", "dropping amoeba" },
- { "amoeba", "normal amoeba" },
- { "nut", "nut with emerald" },
- { "gameoflife", "Conway's wall of life" },
- { "biomaze", "biomaze" },
- { "dynamite", "burning dynamite" },
- { NULL, "unknown" },
- { "robot_wheel", "magic wheel" }, /* 30 */
- { "robot_wheel", "magic wheel (running)" },
- { "key", "red key" },
- { "key", "yellow key" },
- { "key", "green key" },
- { "key", "blue key" },
- { "gate", "red door" },
- { "gate", "yellow door" },
- { "gate", "green door" },
- { "gate", "blue door" },
- { "gate", "gray door (opened by red key)" }, /* 40 */
- { "gate", "gray door (opened by yellow key)"},
- { "gate", "gray door (opened by green key)"},
- { "gate", "gray door (opened by blue key)"},
- { "dynamite", "dynamite" },
- { "pacman", "pac man" },
- { "wall", "invisible normal wall" },
- { "lamp", "lamp (off)" },
- { "lamp", "lamp (on)" },
- { "wall", "wall with emerald" },
- { "wall", "wall with diamond" }, /* 50 */
- { "amoeba", "amoeba with content" },
- { "bd_amoeba", "amoeba (BD style)" },
- { "time_orb_full", "time orb (full)" },
- { "time_orb_empty", "time orb (empty)" },
- { "wall", "growing wall" },
- { "bd_diamond", "diamond (BD style)" },
- { "emerald", "yellow emerald" },
- { "wall", "wall with BD style diamond" },
- { "wall", "wall with yellow emerald" },
- { "dark_yamyam", "dark yam yam" }, /* 60 */
- { "bd_magic_wall", "magic wall (BD style)" },
- { "wall", "invisible steel wall" },
- { NULL, "-" },
- { "dynabomb_nr", "increases number of bombs" },
- { "dynabomb_sz", "increases explosion size" },
- { "dynabomb_xl", "increases power of explosion" },
- { "sokoban_object", "sokoban object" },
- { "sokoban_field", "sokoban empty field" },
- { "sokoban_field", "sokoban field with object" },
- { "bd_butterfly", "butterfly (starts moving right)"}, /* 70 */
- { "bd_butterfly", "butterfly (starts moving up)" },
- { "bd_butterfly", "butterfly (starts moving left)"},
- { "bd_butterfly", "butterfly (starts moving down)"},
- { "bd_firefly", "firefly (starts moving right)" },
- { "bd_firefly", "firefly (starts moving up)" },
- { "bd_firefly", "firefly (starts moving left)" },
- { "bd_firefly", "firefly (starts moving down)" },
- { "bd_butterfly", "butterfly" },
- { "bd_firefly", "firefly" },
- { "player", "yellow player" }, /* 80 */
- { "player", "red player" },
- { "player", "green player" },
- { "player", "blue player" },
- { "bug", "bug (starts moving right)" },
- { "bug", "bug (starts moving up)" },
- { "bug", "bug (starts moving left)" },
- { "bug", "bug (starts moving down)" },
- { "spaceship", "spaceship (starts moving right)"},
- { "spaceship", "spaceship (starts moving up)" },
- { "spaceship", "spaceship (starts moving left)"}, /* 90 */
- { "spaceship", "spaceship (starts moving down)"},
- { "pacman", "pac man (starts moving right)" },
- { "pacman", "pac man (starts moving up)" },
- { "pacman", "pac man (starts moving left)" },
- { "pacman", "pac man (starts moving down)" },
- { "emerald", "red emerald" },
- { "emerald", "purple emerald" },
- { "wall", "wall with red emerald" },
- { "wall", "wall with purple emerald" },
- { NULL, "unknown" }, /* 100 */
- { NULL, "unknown" },
- { NULL, "unknown" },
- { NULL, "unknown" },
- { NULL, "unknown" },
- { NULL, "normal wall (BD style)" },
- { "bd_rock", "rock (BD style)" },
- { "exit", "open exit" },
- { NULL, "black orb bomb" },
- { "amoeba", "amoeba" },
- { "mole", "mole" }, /* 110 */
- { "penguin", "penguin" },
- { "satellite", "satellite" },
- { NULL, "arrow left" },
- { NULL, "arrow right" },
- { NULL, "arrow up" },
- { NULL, "arrow down" },
- { "pig", "pig" },
- { "dragon", "fire breathing dragon" },
- { "key", "red key (EM style)" },
- { NULL, "letter ' '" }, /* 120 */
- { NULL, "letter '!'" },
- { NULL, "letter '\"'" },
- { NULL, "letter '#'" },
- { NULL, "letter '$'" },
- { NULL, "letter '%'" },
- { NULL, "letter '&'" },
- { NULL, "letter '''" },
- { NULL, "letter '('" },
- { NULL, "letter ')'" },
- { NULL, "letter '*'" }, /* 130 */
- { NULL, "letter '+'" },
- { NULL, "letter ','" },
- { NULL, "letter '-'" },
- { NULL, "letter '.'" },
- { NULL, "letter '/'" },
- { NULL, "letter '0'" },
- { NULL, "letter '1'" },
- { NULL, "letter '2'" },
- { NULL, "letter '3'" },
- { NULL, "letter '4'" }, /* 140 */
- { NULL, "letter '5'" },
- { NULL, "letter '6'" },
- { NULL, "letter '7'" },
- { NULL, "letter '8'" },
- { NULL, "letter '9'" },
- { NULL, "letter ':'" },
- { NULL, "letter ';'" },
- { NULL, "letter '<'" },
- { NULL, "letter '='" },
- { NULL, "letter '>'" }, /* 150 */
- { NULL, "letter '?'" },
- { NULL, "letter '@'" },
- { NULL, "letter 'A'" },
- { NULL, "letter 'B'" },
- { NULL, "letter 'C'" },
- { NULL, "letter 'D'" },
- { NULL, "letter 'E'" },
- { NULL, "letter 'F'" },
- { NULL, "letter 'G'" },
- { NULL, "letter 'H'" }, /* 160 */
- { NULL, "letter 'I'" },
- { NULL, "letter 'J'" },
- { NULL, "letter 'K'" },
- { NULL, "letter 'L'" },
- { NULL, "letter 'M'" },
- { NULL, "letter 'N'" },
- { NULL, "letter 'O'" },
- { NULL, "letter 'P'" },
- { NULL, "letter 'Q'" },
- { NULL, "letter 'R'" }, /* 170 */
- { NULL, "letter 'S'" },
- { NULL, "letter 'T'" },
- { NULL, "letter 'U'" },
- { NULL, "letter 'V'" },
- { NULL, "letter 'W'" },
- { NULL, "letter 'X'" },
- { NULL, "letter 'Y'" },
- { NULL, "letter 'Z'" },
- { NULL, "letter 'Ä'" },
- { NULL, "letter 'Ö'" }, /* 180 */
- { NULL, "letter 'Ü'" },
- { NULL, "letter '^'" },
- { NULL, "letter ''" },
- { NULL, "letter ''" },
- { NULL, "letter ''" },
- { NULL, "letter ''" },
- { NULL, "letter ''" },
- { NULL, "letter ''" },
- { NULL, "letter ''" },
- { NULL, "letter ''" }, /* 190 */
- { NULL, "letter ''" },
- { NULL, "letter ''" },
- { NULL, "letter ''" },
- { NULL, "letter ''" },
- { NULL, "letter ''" },
- { NULL, "letter ''" },
- { NULL, "letter ''" },
- { NULL, "letter ''" },
- { NULL, "letter ''" },
- { "wall", "growing wall (horizontal)" }, /* 200 */
- { "wall", "growing wall (vertical)" },
- { "wall", "growing wall (all directions)" },
- { "gate", "red door (EM style)" },
- { "gate", "yellow door (EM style)" },
- { "gate", "green door (EM style)" },
- { "gate", "blue door (EM style)" },
- { "key", "yellow key (EM style)" },
- { "key", "green key (EM style)" },
- { "key", "blue key (EM style)" },
- { "empty_space", "empty space" }, /* 210 */
- { "sp_zonk", "zonk" },
- { "sp_base", "base" },
- { "player", "murphy" },
- { "sp_infotron", "infotron" },
- { "wall", "chip (single)" },
- { "wall", "hardware" },
- { "sp_exit", "exit" },
- { "sp_disk_orange", "orange disk" },
- { "sp_port", "port (leading right)" },
- { "sp_port", "port (leading down)" }, /* 220 */
- { "sp_port", "port (leading left)" },
- { "sp_port", "port (leading up)" },
- { "sp_port", "port (leading right)" },
- { "sp_port", "port (leading down)" },
- { "sp_port", "port (leading left)" },
- { "sp_port", "port (leading up)" },
- { "sp_sniksnak", "snik snak" },
- { "sp_disk_yellow", "yellow disk" },
- { "sp_terminal", "terminal" },
- { "sp_disk_red", "red disk" }, /* 230 */
- { "sp_port", "port (vertical)" },
- { "sp_port", "port (horizontal)" },
- { "sp_port", "port (all directions)" },
- { "sp_electron", "electron" },
- { "sp_buggy_base", "buggy base" },
- { "wall", "chip (left half)" },
- { "wall", "chip (right half)" },
- { "wall", "hardware" },
- { "wall", "hardware" },
- { "wall", "hardware" }, /* 240 */
- { "wall", "hardware" },
- { "wall", "hardware" },
- { "wall", "hardware" },
- { "wall", "hardware" },
- { "wall", "hardware" },
- { "wall", "hardware" },
- { "wall", "hardware" },
- { "wall", "chip (upper half)" },
- { "wall", "chip (lower half)" },
- { "gate", "gray door (EM style, red key)" }, /* 250 */
- { "gate", "gray door (EM style, yellow key)"},
- { "gate", "gray door (EM style, green key)"},
- { "gate", "gray door (EM style, blue key)"},
- { NULL, "unknown" },
- { NULL, "unknown" },
-
- /* 256 */
-
- { "pearl", "pearl" }, /* (256) */
- { "crystal", "crystal" },
- { "wall", "wall with pearl" },
- { "wall", "wall with crystal" },
- { "gate", "white door" }, /* 260 */
- { "gate", "gray door (opened by white key)"},
- { "key", "white key" },
- { "shield_passive", "shield (passive)" },
- { "extra_time", "extra time" },
- { "switchgate", "switch gate (open)" },
- { "switchgate", "switch gate (closed)" },
- { "switchgate_switch", "switch for switch gate" },
- { "switchgate_switch", "switch for switch gate" },
- { NULL, "-" },
- { NULL, "-" }, /* 270 */
- { "conveyor_belt", "red conveyor belt (left)" },
- { "conveyor_belt", "red conveyor belt (middle)" },
- { "conveyor_belt", "red conveyor belt (right)" },
- { "conveyor_belt_switch", "switch for red conveyor belt (left)"},
- { "conveyor_belt_switch", "switch for red conveyor belt (middle)"},
- { "conveyor_belt_switch", "switch for red conveyor belt (right)"},
- { "conveyor_belt", "yellow conveyor belt (left)" },
- { "conveyor_belt", "yellow conveyor belt (middle)" },
- { "conveyor_belt", "yellow conveyor belt (right)" },
- { "conveyor_belt_switch", "switch for yellow conveyor belt (left)"},
- { "conveyor_belt_switch", "switch for yellow conveyor belt (middle)"},
- { "conveyor_belt_switch", "switch for yellow conveyor belt (right)"},
- { "conveyor_belt", "green conveyor belt (left)" },
- { "conveyor_belt", "green conveyor belt (middle)" },
- { "conveyor_belt", "green conveyor belt (right)" },
- { "conveyor_belt_switch", "switch for green conveyor belt (left)"},
- { "conveyor_belt_switch", "switch for green conveyor belt (middle)"},
- { "conveyor_belt_switch", "switch for green conveyor belt (right)"},
- { "conveyor_belt", "blue conveyor belt (left)" },
- { "conveyor_belt", "blue conveyor belt (middle)" },
- { "conveyor_belt", "blue conveyor belt (right)" },
- { "conveyor_belt_switch", "switch for blue conveyor belt (left)"},
- { "conveyor_belt_switch", "switch for blue conveyor belt (middle)"},
- { "conveyor_belt_switch", "switch for blue conveyor belt (right)"},
- { "sand", "land mine" },
- { "envelope", "mail envelope" },
- { "light_switch", "light switch (off)" },
- { "light_switch", "light switch (on)" },
- { "wall", "sign (exclamation)" },
- { "wall", "sign (radio activity)" }, /* 300 */
- { "wall", "sign (stop)" },
- { "wall", "sign (wheel chair)" },
- { "wall", "sign (parking)" },
- { "wall", "sign (one way)" },
- { "wall", "sign (heart)" },
- { "wall", "sign (triangle)" },
- { "wall", "sign (round)" },
- { "wall", "sign (exit)" },
- { "wall", "sign (yin yang)" },
- { "wall", "sign (other)" }, /* 310 */
- { "mole", "mole (starts moving left)" },
- { "mole", "mole (starts moving right)" },
- { "mole", "mole (starts moving up)" },
- { "mole", "mole (starts moving down)" },
- { "wall", "steel wall (slanted)" },
- { "sand", "invisible sand" },
- { NULL, "dx unknown 15" },
- { NULL, "dx unknown 42" },
- { NULL, "-" },
- { NULL, "-" }, /* 320 */
- { "shield_active", "shield (active, kills enemies)"},
- { "timegate", "time gate (open)" },
- { "timegate", "time gate (closed)" },
- { "timegate_wheel", "switch for time gate" },
- { "timegate_wheel", "switch for time gate" },
- { "balloon", "balloon" },
- { "wall", "send balloon to the left" },
- { "wall", "send balloon to the right" },
- { "balloon_switch", "send balloon up" },
- { "balloon_switch", "send balloon down" }, /* 330 */
- { "balloon_switch", "send balloon in any direction" },
- { "wall", "steel wall" },
- { "wall", "steel wall" },
- { "wall", "steel wall" },
- { "wall", "steel wall" },
- { "wall", "normal wall" },
- { "wall", "normal wall" },
- { "wall", "normal wall" },
- { "wall", "normal wall" },
- { "wall", "normal wall" }, /* 340 */
- { "wall", "normal wall" },
- { "wall", "normal wall" },
- { "wall", "normal wall" },
- { "tube", "tube (all directions)" },
- { "tube", "tube (vertical)" },
- { "tube", "tube (horizontal)" },
- { "tube", "tube (vertical & left)" },
- { "tube", "tube (vertical & right)" },
- { "tube", "tube (horizontal & up)" },
- { "tube", "tube (horizontal & down)" }, /* 350 */
- { "tube", "tube (left & up)" },
- { "tube", "tube (left & down)" },
- { "tube", "tube (right & up)" },
- { "tube", "tube (right & down)" },
- { "spring", "spring" },
- { "trap", "trap" },
- { "dx_bomb", "stable bomb (DX style)" },
- { NULL, "-" }
-
- /*
- "-------------------------------",
- */
+ { "global.num_toons", &global.num_toons },
+
+ { "menu.draw_xoffset", &menu.draw_xoffset_default },
+ { "menu.draw_yoffset", &menu.draw_yoffset_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.draw_yoffset.LEVELS", &menu.draw_yoffset[GFX_SPECIAL_ARG_LEVELS] },
+ { "menu.draw_xoffset.SCORES", &menu.draw_xoffset[GFX_SPECIAL_ARG_SCORES] },
+ { "menu.draw_yoffset.SCORES", &menu.draw_yoffset[GFX_SPECIAL_ARG_SCORES] },
+ { "menu.draw_xoffset.EDITOR", &menu.draw_xoffset[GFX_SPECIAL_ARG_EDITOR] },
+ { "menu.draw_yoffset.EDITOR", &menu.draw_yoffset[GFX_SPECIAL_ARG_EDITOR] },
+ { "menu.draw_xoffset.INFO", &menu.draw_xoffset[GFX_SPECIAL_ARG_INFO] },
+ { "menu.draw_yoffset.INFO", &menu.draw_yoffset[GFX_SPECIAL_ARG_INFO] },
+ { "menu.draw_xoffset.SETUP", &menu.draw_xoffset[GFX_SPECIAL_ARG_SETUP] },
+ { "menu.draw_yoffset.SETUP", &menu.draw_yoffset[GFX_SPECIAL_ARG_SETUP] },
+
+ { "menu.scrollbar_xoffset", &menu.scrollbar_xoffset },
+
+ { "menu.list_size", &menu.list_size_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] },
+
+ { "door.step_offset", &door.step_offset },
+ { "door.step_delay", &door.step_delay },
+
+ { NULL, NULL, }
+};
+
+
+/* ------------------------------------------------------------------------- */
+/* font definitions */
+/* ------------------------------------------------------------------------- */
+
+/* Important: When one entry is a prefix of another entry, the longer entry
+ must come first, because the dynamic configuration does prefix matching! */
+
+struct FontInfo font_info[NUM_FONTS + 1] =
+{
+ { "font.initial_1" },
+ { "font.initial_2" },
+ { "font.initial_3" },
+ { "font.initial_4" },
+ { "font.title_1" },
+ { "font.title_2" },
+ { "font.menu_1" },
+ { "font.menu_2" },
+ { "font.text_1.active" },
+ { "font.text_2.active" },
+ { "font.text_3.active" },
+ { "font.text_4.active" },
+ { "font.text_1" },
+ { "font.text_2" },
+ { "font.text_3" },
+ { "font.text_4" },
+ { "font.input_1.active" },
+ { "font.input_2.active" },
+ { "font.input_1" },
+ { "font.input_2" },
+ { "font.option_off" },
+ { "font.option_on" },
+ { "font.value_1" },
+ { "font.value_2" },
+ { "font.value_old" },
+ { "font.level_number" },
+ { "font.tape_recorder" },
+ { "font.game_info" },
};
int main(int argc, char *argv[])
{
- InitCommandName(argv[0]);
+ InitProgramInfo(argv[0], USERDATA_DIRECTORY,
+ PROGRAM_TITLE_STRING, getWindowTitleString(),
+ ICON_TITLE_STRING, X11_ICON_FILENAME, X11_ICONMASK_FILENAME,
+ MSDOS_POINTER_FILENAME,
+ COOKIE_PREFIX, FILENAME_PREFIX, GAME_VERSION_ACTUAL);
+
InitExitFunction(CloseAllAndExit);
- InitPlatformDependantStuff();
+ InitPlatformDependentStuff();
GetOptions(argv);
OpenAll();
#include "libgame/libgame.h"
-#define WIN_XSIZE 672
-#define WIN_YSIZE 560
-
-#define SCR_FIELDX 17
-#define SCR_FIELDY 17
-#define MAX_BUF_XSIZE (SCR_FIELDX + 2)
-#define MAX_BUF_YSIZE (SCR_FIELDY + 2)
-#define MIN_LEV_FIELDX 3
-#define MIN_LEV_FIELDY 3
-#define STD_LEV_FIELDX 64
-#define STD_LEV_FIELDY 32
-#define MAX_LEV_FIELDX 128
-#define MAX_LEV_FIELDY 128
-
-#define SCREENX(a) ((a) - scroll_x)
-#define SCREENY(a) ((a) - scroll_y)
-#define LEVELX(a) ((a) + scroll_x)
-#define LEVELY(a) ((a) + scroll_y)
+#include "conf_gfx.h" /* include auto-generated data structure definitions */
+#include "conf_snd.h" /* include auto-generated data structure definitions */
+
+#define IMG_UNDEFINED (-1)
+#define IMG_EMPTY IMG_EMPTY_SPACE
+#define IMG_SP_EMPTY IMG_SP_EMPTY_SPACE
+#define IMG_EXPLOSION IMG_DEFAULT_EXPLODING
+#define IMG_CHAR_START IMG_CHAR_SPACE
+#define IMG_CUSTOM_START IMG_CUSTOM_1
+
+#define SND_UNDEFINED (-1)
+
+#define WIN_XSIZE 672
+#define WIN_YSIZE 560
+
+#define SCR_FIELDX 17
+#define SCR_FIELDY 17
+#define MAX_BUF_XSIZE (SCR_FIELDX + 2)
+#define MAX_BUF_YSIZE (SCR_FIELDY + 2)
+#define MIN_LEV_FIELDX 3
+#define MIN_LEV_FIELDY 3
+#define STD_LEV_FIELDX 64
+#define STD_LEV_FIELDY 32
+#define MAX_LEV_FIELDX 128
+#define MAX_LEV_FIELDY 128
+
+#define SCREENX(a) ((a) - scroll_x)
+#define SCREENY(a) ((a) - scroll_y)
+#define LEVELX(a) ((a) + scroll_x)
+#define LEVELY(a) ((a) + scroll_y)
#define IN_VIS_FIELD(x,y) ((x)>=0 && (x)<SCR_FIELDX && (y)>=0 &&(y)<SCR_FIELDY)
#define IN_SCR_FIELD(x,y) ((x)>=BX1 && (x)<=BX2 && (y)>=BY1 &&(y)<=BY2)
#define IN_LEV_FIELD(x,y) ((x)>=0 && (x)<lev_fieldx && (y)>=0 &&(y)<lev_fieldy)
-/* values for 'Elementeigenschaften1' */
-#define EP_BIT_AMOEBALIVE (1 << 0)
-#define EP_BIT_AMOEBOID (1 << 1)
-#define EP_BIT_SCHLUESSEL (1 << 2)
-#define EP_BIT_PFORTE (1 << 3)
-#define EP_BIT_SOLID (1 << 4)
-#define EP_BIT_MASSIVE (1 << 5)
-#define EP_BIT_SLIPPERY (1 << 6)
-#define EP_BIT_ENEMY (1 << 7)
-#define EP_BIT_MAUER (1 << 8)
-#define EP_BIT_CAN_FALL (1 << 9)
-#define EP_BIT_CAN_SMASH (1 << 10)
-#define EP_BIT_CAN_CHANGE (1 << 11)
-#define EP_BIT_CAN_MOVE (1 << 12)
-#define EP_BIT_COULD_MOVE (1 << 13)
-#define EP_BIT_DONT_TOUCH (1 << 14)
-#define EP_BIT_DONT_GO_TO (1 << 15)
-#define EP_BIT_MAMPF2 (1 << 16)
-#define EP_BIT_CHAR (1 << 17)
-#define EP_BIT_BD_ELEMENT (1 << 18)
-#define EP_BIT_SB_ELEMENT (1 << 19)
-#define EP_BIT_GEM (1 << 20)
-#define EP_BIT_INACTIVE (1 << 21)
-#define EP_BIT_EXPLOSIVE (1 << 22)
-#define EP_BIT_MAMPF3 (1 << 23)
-#define EP_BIT_PUSHABLE (1 << 24)
-#define EP_BIT_PLAYER (1 << 25)
-#define EP_BIT_HAS_CONTENT (1 << 26)
-#define EP_BIT_EATABLE (1 << 27)
-#define EP_BIT_SP_ELEMENT (1 << 28)
-#define EP_BIT_QUICK_GATE (1 << 29)
-#define EP_BIT_OVER_PLAYER (1 << 30)
-#define EP_BIT_ACTIVE_BOMB (1 << 31)
-
-/* values for 'Elementeigenschaften2' */
-#define EP_BIT_BELT (1 << 0)
-#define EP_BIT_BELT_SWITCH (1 << 1)
-#define EP_BIT_TUBE (1 << 2)
-#define EP_BIT_EM_SLIPPERY_WALL (1 << 3)
-
-#define IS_AMOEBALIVE(e) (Elementeigenschaften1[e] & EP_BIT_AMOEBALIVE)
-#define IS_AMOEBOID(e) (Elementeigenschaften1[e] & EP_BIT_AMOEBOID)
-#define IS_SCHLUESSEL(e) (Elementeigenschaften1[e] & EP_BIT_SCHLUESSEL)
-#define IS_PFORTE(e) (Elementeigenschaften1[e] & EP_BIT_PFORTE)
-#define IS_SOLID(e) (Elementeigenschaften1[e] & EP_BIT_SOLID)
-#define IS_MASSIVE(e) (Elementeigenschaften1[e] & EP_BIT_MASSIVE)
-#define IS_SLIPPERY(e) (Elementeigenschaften1[e] & EP_BIT_SLIPPERY)
-#define IS_ENEMY(e) (Elementeigenschaften1[e] & EP_BIT_ENEMY)
-#define IS_MAUER(e) (Elementeigenschaften1[e] & EP_BIT_MAUER)
-#define CAN_FALL(e) (Elementeigenschaften1[e] & EP_BIT_CAN_FALL)
-#define CAN_SMASH(e) (Elementeigenschaften1[e] & EP_BIT_CAN_SMASH)
-#define CAN_CHANGE(e) (Elementeigenschaften1[e] & EP_BIT_CAN_CHANGE)
-#define CAN_MOVE(e) (Elementeigenschaften1[e] & EP_BIT_CAN_MOVE)
-#define COULD_MOVE(e) (Elementeigenschaften1[e] & EP_BIT_COULD_MOVE)
-#define DONT_TOUCH(e) (Elementeigenschaften1[e] & EP_BIT_DONT_TOUCH)
-#define DONT_GO_TO(e) (Elementeigenschaften1[e] & EP_BIT_DONT_GO_TO)
-#define IS_MAMPF2(e) (Elementeigenschaften1[e] & EP_BIT_MAMPF2)
-#define IS_CHAR(e) (Elementeigenschaften1[e] & EP_BIT_CHAR)
-#define IS_BD_ELEMENT(e) (Elementeigenschaften1[e] & EP_BIT_BD_ELEMENT)
-#define IS_SB_ELEMENT(e) (Elementeigenschaften1[e] & EP_BIT_SB_ELEMENT)
-#define IS_GEM(e) (Elementeigenschaften1[e] & EP_BIT_GEM)
-#define IS_INACTIVE(e) (Elementeigenschaften1[e] & EP_BIT_INACTIVE)
-#define IS_EXPLOSIVE(e) (Elementeigenschaften1[e] & EP_BIT_EXPLOSIVE)
-#define IS_MAMPF3(e) (Elementeigenschaften1[e] & EP_BIT_MAMPF3)
-#define IS_PUSHABLE(e) (Elementeigenschaften1[e] & EP_BIT_PUSHABLE)
-#define ELEM_IS_PLAYER(e) (Elementeigenschaften1[e] & EP_BIT_PLAYER)
-#define HAS_CONTENT(e) (Elementeigenschaften1[e] & EP_BIT_HAS_CONTENT)
-#define IS_EATABLE(e) (Elementeigenschaften1[e] & EP_BIT_EATABLE)
-#define IS_SP_ELEMENT(e) (Elementeigenschaften1[e] & EP_BIT_SP_ELEMENT)
-#define IS_QUICK_GATE(e) (Elementeigenschaften1[e] & EP_BIT_QUICK_GATE)
-#define IS_OVER_PLAYER(e) (Elementeigenschaften1[e] & EP_BIT_OVER_PLAYER)
-#define IS_ACTIVE_BOMB(e) (Elementeigenschaften1[e] & EP_BIT_ACTIVE_BOMB)
-#define IS_BELT(e) (Elementeigenschaften2[e] & EP_BIT_BELT)
-#define IS_BELT_SWITCH(e) (Elementeigenschaften2[e] & EP_BIT_BELT_SWITCH)
-#define IS_TUBE(e) (Elementeigenschaften2[e] & EP_BIT_TUBE)
-#define IS_EM_SLIPPERY_WALL(e) (Elementeigenschaften2[e] & EP_BIT_EM_SLIPPERY_WALL)
+/* values for configurable properties (custom elem's only, else pre-defined) */
+#define EP_DIGGABLE 0
+#define EP_COLLECTIBLE 1
+#define EP_DONT_RUN_INTO 2
+#define EP_DONT_COLLIDE_WITH 3
+#define EP_DONT_TOUCH 4
+#define EP_INDESTRUCTIBLE 5
+#define EP_SLIPPERY 6
+#define EP_CAN_CHANGE 7
+#define EP_CAN_MOVE 8
+#define EP_CAN_FALL 9
+#define EP_CAN_SMASH_PLAYER 10
+#define EP_CAN_SMASH_ENEMIES 11
+#define EP_CAN_SMASH_EVERYTHING 12
+#define EP_CAN_EXPLODE_BY_FIRE 13
+#define EP_CAN_EXPLODE_SMASHED 14
+#define EP_CAN_EXPLODE_IMPACT 15
+#define EP_WALKABLE_OVER 16
+#define EP_WALKABLE_INSIDE 17
+#define EP_WALKABLE_UNDER 18
+#define EP_PASSABLE_OVER 19
+#define EP_PASSABLE_INSIDE 20
+#define EP_PASSABLE_UNDER 21
+#define EP_UNUSED_22 22
+#define EP_UNUSED_23 23
+#define EP_PUSHABLE 24
+
+/* values for special configurable properties (depending on level settings) */
+#define EP_EM_SLIPPERY_WALL 32
+
+/* values for special graphics properties (no effect on game engine) */
+#define EP_CAN_BE_CRUMBLED 33
+
+/* values for pre-defined properties */
+#define EP_PLAYER 34
+#define EP_CAN_PASS_MAGIC_WALL 35
+#define EP_SWITCHABLE 36
+#define EP_BD_ELEMENT 37
+#define EP_SP_ELEMENT 38
+#define EP_SB_ELEMENT 39
+#define EP_GEM 40
+#define EP_FOOD_DARK_YAMYAM 41
+#define EP_FOOD_PENGUIN 42
+#define EP_FOOD_PIG 43
+#define EP_HISTORIC_WALL 44
+#define EP_HISTORIC_SOLID 45
+#define EP_CLASSIC_ENEMY 46
+#define EP_BELT 47
+#define EP_BELT_ACTIVE 48
+#define EP_BELT_SWITCH 49
+#define EP_TUBE 50
+#define EP_KEYGATE 51
+#define EP_AMOEBOID 52
+#define EP_AMOEBALIVE 53
+#define EP_HAS_CONTENT 54
+#define EP_ACTIVE_BOMB 55
+#define EP_INACTIVE 56
+
+/* values for derived properties (determined from properties above) */
+#define EP_ACCESSIBLE_OVER 57
+#define EP_ACCESSIBLE_INSIDE 58
+#define EP_ACCESSIBLE_UNDER 59
+#define EP_WALKABLE 60
+#define EP_PASSABLE 61
+#define EP_ACCESSIBLE 62
+#define EP_SNAPPABLE 63
+#define EP_WALL 64
+#define EP_SOLID_FOR_PUSHING 65
+#define EP_DRAGONFIRE_PROOF 66
+#define EP_EXPLOSION_PROOF 67
+#define EP_CAN_SMASH 68
+#define EP_CAN_EXPLODE 69
+
+/* values for internal purpose only (level editor) */
+#define EP_EXPLODE_RESULT 70
+#define EP_WALK_TO_OBJECT 71
+#define EP_DEADLY 72
+
+#define NUM_ELEMENT_PROPERTIES 73
+
+#define NUM_EP_BITFIELDS ((NUM_ELEMENT_PROPERTIES + 31) / 32)
+#define EP_BITFIELD_BASE 0
+
+#define EP_BITMASK_DEFAULT 0
+
+#define PROPERTY_BIT(p) (1 << ((p) % 32))
+#define PROPERTY_VAR(e,p) (Properties[e][(p) / 32])
+#define HAS_PROPERTY(e,p) ((PROPERTY_VAR(e, p) & PROPERTY_BIT(p)) != 0)
+#define SET_PROPERTY(e,p,v) ((v) ? \
+ (PROPERTY_VAR(e,p) |= PROPERTY_BIT(p)) : \
+ (PROPERTY_VAR(e,p) &= ~PROPERTY_BIT(p)))
+
+
+/* values for change events for custom elements */
+#define CE_DELAY 0
+#define CE_TOUCHED_BY_PLAYER 1
+#define CE_PRESSED_BY_PLAYER 2
+#define CE_PUSHED_BY_PLAYER 3
+#define CE_COLLISION 4
+#define CE_IMPACT 5
+#define CE_SMASHED 6
+#define CE_OTHER_IS_TOUCHING 7
+#define CE_OTHER_IS_CHANGING 8
+#define CE_OTHER_IS_EXPLODING 9
+#define CE_OTHER_GETS_TOUCHED 10
+#define CE_OTHER_GETS_PRESSED 11
+#define CE_OTHER_GETS_PUSHED 12
+#define CE_OTHER_GETS_COLLECTED 13
+
+/* values for internal purpose only (level editor) */
+#define CE_BY_PLAYER 14
+#define CE_BY_COLLISION 15
+#define CE_BY_OTHER 16
+
+#define NUM_CHANGE_EVENTS 17
+
+#define CE_BITMASK_DEFAULT 0
+
+#define CH_EVENT_BIT(c) (1 << (c))
+#define CH_EVENT_VAR(e) (element_info[e].change.events)
+
+#define HAS_CHANGE_EVENT(e,c) (IS_CUSTOM_ELEMENT(e) && \
+ (CH_EVENT_VAR(e) & CH_EVENT_BIT(c)) != 0)
+#define SET_CHANGE_EVENT(e,c,v) (IS_CUSTOM_ELEMENT(e) ? \
+ ((v) ? \
+ (CH_EVENT_VAR(e) |= CH_EVENT_BIT(c)) : \
+ (CH_EVENT_VAR(e) &= ~CH_EVENT_BIT(c))) : 0)
+
+/* values for change power for custom elements */
+#define CP_NON_DESTRUCTIVE 0
+#define CP_HALF_DESTRUCTIVE 1
+#define CP_FULL_DESTRUCTIVE 2
+
+/* values for special move patterns (bits 0-3: basic move directions) */
+#define MV_BIT_TOWARDS_PLAYER 4
+#define MV_BIT_AWAY_FROM_PLAYER 5
+#define MV_BIT_ALONG_LEFT_SIDE 6
+#define MV_BIT_ALONG_RIGHT_SIDE 7
+#define MV_BIT_TURNING_LEFT 8
+#define MV_BIT_TURNING_RIGHT 9
+
+/* values for special move patterns for custom elements */
+#define MV_HORIZONTAL (MV_LEFT | MV_RIGHT)
+#define MV_VERTICAL (MV_UP | MV_DOWN)
+#define MV_ALL_DIRECTIONS (MV_HORIZONTAL | MV_VERTICAL)
+#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 MV_ALONG_RIGHT_SIDE (1 << MV_BIT_ALONG_RIGHT_SIDE)
+#define MV_TURNING_LEFT (1 << MV_BIT_TURNING_LEFT)
+#define MV_TURNING_RIGHT (1 << MV_BIT_TURNING_RIGHT)
+
+/* values for slippery property for custom elements */
+#define SLIPPERY_ANY_RANDOM 0
+#define SLIPPERY_ANY_LEFT_RIGHT 1
+#define SLIPPERY_ANY_RIGHT_LEFT 2
+#define SLIPPERY_ONLY_LEFT 3
+#define SLIPPERY_ONLY_RIGHT 4
+
+/* macros for configurable properties */
+#define IS_DIGGABLE(e) HAS_PROPERTY(e, EP_DIGGABLE)
+#define IS_COLLECTIBLE(e) HAS_PROPERTY(e, EP_COLLECTIBLE)
+#define DONT_RUN_INTO(e) HAS_PROPERTY(e, EP_DONT_RUN_INTO)
+#define DONT_COLLIDE_WITH(e) HAS_PROPERTY(e, EP_DONT_COLLIDE_WITH)
+#define DONT_TOUCH(e) HAS_PROPERTY(e, EP_DONT_TOUCH)
+#define IS_INDESTRUCTIBLE(e) HAS_PROPERTY(e, EP_INDESTRUCTIBLE)
+#define IS_SLIPPERY(e) HAS_PROPERTY(e, EP_SLIPPERY)
+#define CAN_CHANGE(e) HAS_PROPERTY(e, EP_CAN_CHANGE)
+#define CAN_MOVE(e) HAS_PROPERTY(e, EP_CAN_MOVE)
+#define CAN_FALL(e) HAS_PROPERTY(e, EP_CAN_FALL)
+#define CAN_SMASH_PLAYER(e) HAS_PROPERTY(e, EP_CAN_SMASH_PLAYER)
+#define CAN_SMASH_ENEMIES(e) HAS_PROPERTY(e, EP_CAN_SMASH_ENEMIES)
+#define CAN_SMASH_EVERYTHING(e) HAS_PROPERTY(e, EP_CAN_SMASH_EVERYTHING)
+#define CAN_EXPLODE_BY_FIRE(e) HAS_PROPERTY(e, EP_CAN_EXPLODE_BY_FIRE)
+#define CAN_EXPLODE_SMASHED(e) HAS_PROPERTY(e, EP_CAN_EXPLODE_SMASHED)
+#define CAN_EXPLODE_IMPACT(e) HAS_PROPERTY(e, EP_CAN_EXPLODE_IMPACT)
+#define IS_WALKABLE_OVER(e) HAS_PROPERTY(e, EP_WALKABLE_OVER)
+#define IS_WALKABLE_INSIDE(e) HAS_PROPERTY(e, EP_WALKABLE_INSIDE)
+#define IS_WALKABLE_UNDER(e) HAS_PROPERTY(e, EP_WALKABLE_UNDER)
+#define IS_PASSABLE_OVER(e) HAS_PROPERTY(e, EP_PASSABLE_OVER)
+#define IS_PASSABLE_INSIDE(e) HAS_PROPERTY(e, EP_PASSABLE_INSIDE)
+#define IS_PASSABLE_UNDER(e) HAS_PROPERTY(e, EP_PASSABLE_UNDER)
+#define IS_PUSHABLE(e) HAS_PROPERTY(e, EP_PUSHABLE)
+
+/* macros for special configurable properties */
+#define IS_EM_SLIPPERY_WALL(e) HAS_PROPERTY(e, EP_EM_SLIPPERY_WALL)
+
+/* macros for special graphics properties */
+#define CAN_BE_CRUMBLED(e) HAS_PROPERTY(GFX_ELEMENT(e),EP_CAN_BE_CRUMBLED)
+
+/* macros for pre-defined properties */
+#define ELEM_IS_PLAYER(e) HAS_PROPERTY(e, EP_PLAYER)
+#define CAN_PASS_MAGIC_WALL(e) HAS_PROPERTY(e, EP_CAN_PASS_MAGIC_WALL)
+#define IS_SWITCHABLE(e) HAS_PROPERTY(e, EP_SWITCHABLE)
+#define IS_BD_ELEMENT(e) HAS_PROPERTY(e, EP_BD_ELEMENT)
+#define IS_SP_ELEMENT(e) HAS_PROPERTY(e, EP_SP_ELEMENT)
+#define IS_SB_ELEMENT(e) HAS_PROPERTY(e, EP_SB_ELEMENT)
+#define IS_GEM(e) HAS_PROPERTY(e, EP_GEM)
+#define IS_FOOD_DARK_YAMYAM(e) HAS_PROPERTY(e, EP_FOOD_DARK_YAMYAM)
+#define IS_FOOD_PENGUIN(e) HAS_PROPERTY(e, EP_FOOD_PENGUIN)
+#define IS_FOOD_PIG(e) HAS_PROPERTY(e, EP_FOOD_PIG)
+#define IS_HISTORIC_WALL(e) HAS_PROPERTY(e, EP_HISTORIC_WALL)
+#define IS_HISTORIC_SOLID(e) HAS_PROPERTY(e, EP_HISTORIC_SOLID)
+#define IS_CLASSIC_ENEMY(e) HAS_PROPERTY(e, EP_CLASSIC_ENEMY)
+#define IS_BELT(e) HAS_PROPERTY(e, EP_BELT)
+#define IS_BELT_ACTIVE(e) HAS_PROPERTY(e, EP_BELT_ACTIVE)
+#define IS_BELT_SWITCH(e) HAS_PROPERTY(e, EP_BELT_SWITCH)
+#define IS_TUBE(e) HAS_PROPERTY(e, EP_TUBE)
+#define IS_KEYGATE(e) HAS_PROPERTY(e, EP_KEYGATE)
+#define IS_AMOEBOID(e) HAS_PROPERTY(e, EP_AMOEBOID)
+#define IS_AMOEBALIVE(e) HAS_PROPERTY(e, EP_AMOEBALIVE)
+#define HAS_CONTENT(e) HAS_PROPERTY(e, EP_HAS_CONTENT)
+#define IS_ACTIVE_BOMB(e) HAS_PROPERTY(e, EP_ACTIVE_BOMB)
+#define IS_INACTIVE(e) HAS_PROPERTY(e, EP_INACTIVE)
+
+/* macros for derived properties */
+#define IS_ACCESSIBLE_OVER(e) HAS_PROPERTY(e, EP_ACCESSIBLE_OVER)
+#define IS_ACCESSIBLE_INSIDE(e) HAS_PROPERTY(e, EP_ACCESSIBLE_INSIDE)
+#define IS_ACCESSIBLE_UNDER(e) HAS_PROPERTY(e, EP_ACCESSIBLE_UNDER)
+#define IS_SNAPPABLE(e) HAS_PROPERTY(e, EP_SNAPPABLE)
+#define IS_WALKABLE(e) HAS_PROPERTY(e, EP_WALKABLE)
+#define IS_PASSABLE(e) HAS_PROPERTY(e, EP_PASSABLE)
+#define IS_ACCESSIBLE(e) HAS_PROPERTY(e, EP_ACCESSIBLE)
+#define IS_WALL(e) HAS_PROPERTY(e, EP_WALL)
+#define IS_SOLID_FOR_PUSHING(e) HAS_PROPERTY(e, EP_SOLID_FOR_PUSHING)
+#define IS_DRAGONFIRE_PROOF(e) HAS_PROPERTY(e, EP_DRAGONFIRE_PROOF)
+#define IS_EXPLOSION_PROOF(e) HAS_PROPERTY(e, EP_EXPLOSION_PROOF)
+#define CAN_SMASH(e) HAS_PROPERTY(e, EP_CAN_SMASH)
+#define CAN_EXPLODE(e) HAS_PROPERTY(e, EP_CAN_EXPLODE)
+
+/* special macros used in game engine */
+#define IS_CUSTOM_ELEMENT(e) ((e) >= EL_CUSTOM_START && \
+ (e) <= EL_CUSTOM_END)
+
+#define GFX_ELEMENT(e) (element_info[e].use_gfx_element ? \
+ element_info[e].gfx_element : e)
#define IS_PLAYER(x,y) (ELEM_IS_PLAYER(StorePlayer[x][y]))
-#define IS_FREE(x,y) (Feld[x][y] == EL_LEERRAUM && !IS_PLAYER(x,y))
-#define IS_FREE_OR_PLAYER(x,y) (Feld[x][y] == EL_LEERRAUM)
+#define IS_FREE(x,y) (Feld[x][y] == EL_EMPTY && !IS_PLAYER(x,y))
+#define IS_FREE_OR_PLAYER(x,y) (Feld[x][y] == EL_EMPTY)
#define IS_MOVING(x,y) (MovPos[x][y] != 0)
#define IS_FALLING(x,y) (MovPos[x][y] != 0 && MovDir[x][y] == MV_DOWN)
#define IS_BLOCKED(x,y) (Feld[x][y] == EL_BLOCKED)
-#define EL_CHANGED(e) ((e) == EL_FELSBROCKEN ? EL_EDELSTEIN : \
- (e) == EL_BD_ROCK ? EL_EDELSTEIN_BD : \
- (e) == EL_EDELSTEIN ? EL_DIAMANT : \
- (e) == EL_EDELSTEIN_GELB ? EL_DIAMANT : \
- (e) == EL_EDELSTEIN_ROT ? EL_DIAMANT : \
- (e) == EL_EDELSTEIN_LILA ? EL_DIAMANT : \
- EL_FELSBROCKEN)
-#define EL_CHANGED2(e) ((e) == EL_FELSBROCKEN ? EL_EDELSTEIN_BD : \
- (e) == EL_BD_ROCK ? EL_EDELSTEIN_BD : \
+#define EL_CHANGED(e) ((e) == EL_ROCK ? EL_EMERALD : \
+ (e) == EL_BD_ROCK ? EL_BD_DIAMOND : \
+ (e) == EL_EMERALD ? EL_DIAMOND : \
+ (e) == EL_EMERALD_YELLOW ? EL_DIAMOND : \
+ (e) == EL_EMERALD_RED ? EL_DIAMOND : \
+ (e) == EL_EMERALD_PURPLE ? EL_DIAMOND : \
+ EL_ROCK)
+#define EL_CHANGED2(e) ((e) == EL_ROCK ? EL_BD_DIAMOND : \
+ (e) == EL_BD_ROCK ? EL_BD_DIAMOND : \
EL_BD_ROCK)
#define IS_DRAWABLE(e) ((e) < EL_BLOCKED)
#define IS_NOT_DRAWABLE(e) ((e) >= EL_BLOCKED)
#define TAPE_IS_EMPTY(x) ((x).length == 0)
#define TAPE_IS_STOPPED(x) (!(x).recording && !(x).playing)
-#define PLAYERINFO(x,y) (&stored_player[StorePlayer[x][y]-EL_SPIELER1])
-#define SHIELD_ON(p) ((p)->shield_passive_time_left > 0)
-#define PROTECTED_FIELD(x,y) (IS_TUBE(Feld[x][y]))
+#define PLAYERINFO(x,y) (&stored_player[StorePlayer[x][y]-EL_PLAYER_1])
+#define SHIELD_ON(p) ((p)->shield_normal_time_left > 0)
+#define PROTECTED_FIELD(x,y) (IS_ACCESSIBLE_INSIDE(Feld[x][y]) && \
+ IS_INDESTRUCTIBLE(Feld[x][y]))
#define PLAYER_PROTECTED(x,y) (SHIELD_ON(PLAYERINFO(x, y)) || \
PROTECTED_FIELD(x, y))
-/* Bitmaps with graphic file */
-#define PIX_BACK 0
-#define PIX_DOOR 1
-#define PIX_HEROES 2
-#define PIX_TOONS 3
-#define PIX_SP 4
-#define PIX_DC 5
-#define PIX_MORE 6
-#define PIX_BIGFONT 7
-#define PIX_SMALLFONT 8
-#define PIX_MEDIUMFONT 9
-/* Bitmaps without graphic file */
-#define PIX_DB_DOOR 10
-#define PIX_DB_FIELD 11
-
-#define NUM_PICTURES 10
-#define NUM_BITMAPS 12
+#define PLAYER_NR_GFX(g,i) ((g) + i * (IMG_PLAYER_2 - IMG_PLAYER_1))
+
+#define ANIM_FRAMES(g) (graphic_info[g].anim_frames)
+#define ANIM_DELAY(g) (graphic_info[g].anim_delay)
+#define ANIM_MODE(g) (graphic_info[g].anim_mode)
+
+#define IS_ANIMATED(g) (ANIM_FRAMES(g) > 1)
+#define IS_NEW_DELAY(f, g) ((f) % ANIM_DELAY(g) == 0)
+#define IS_NEW_FRAME(f, g) (IS_ANIMATED(g) && IS_NEW_DELAY(f, g))
+#define IS_NEXT_FRAME(f, g) (IS_NEW_FRAME(f, g) && (f) > 0)
+
+#define IS_LOOP_SOUND(s) (sound_info[s].loop)
+
/* boundaries of arrays etc. */
#define MAX_LEVEL_NAME_LEN 32
#define MAX_LEVEL_AUTHOR_LEN 32
+#define MAX_ELEMENT_NAME_LEN 32
#define MAX_TAPELEN (1000 * 50) /* max. time * framerate */
#define MAX_SCORE_ENTRIES 100
-#define MAX_ELEMENTS 700 /* 500 static + 200 runtime */
#define MAX_NUM_AMOEBA 100
/* values for elements with content */
#define MICROLEVEL_SCROLL_DELAY 50 /* delay for scrolling micro level */
#define MICROLEVEL_LABEL_DELAY 250 /* delay for micro level label */
+/* often used screen positions */
+#define SX 8
+#define SY 8
+#define REAL_SX (SX - 2)
+#define REAL_SY (SY - 2)
+#define DX 566
+#define DY 60
+#define VX DX
+#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 MIDPOSX (SCR_FIELDX / 2)
+#define MIDPOSY (SCR_FIELDY / 2)
+#define SXSIZE (SCR_FIELDX * TILEX)
+#define SYSIZE (SCR_FIELDY * TILEY)
+#define FXSIZE ((SCR_FIELDX + 2) * TILEX)
+#define FYSIZE ((SCR_FIELDY + 2) * TILEY)
+#define DXSIZE 100
+#define DYSIZE 280
+#define VXSIZE DXSIZE
+#define VYSIZE 100
+#define EXSIZE DXSIZE
+#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)
+
+
+/* "real" level file elements */
+#define EL_UNDEFINED -1
+
+#define EL_EMPTY_SPACE 0
+#define EL_EMPTY EL_EMPTY_SPACE
+#define EL_SAND 1
+#define EL_WALL 2
+#define EL_WALL_SLIPPERY 3
+#define EL_ROCK 4
+#define EL_KEY_OBSOLETE 5 /* obsolete; mapped to EL_KEY_1 */
+#define EL_EMERALD 6
+#define EL_EXIT_CLOSED 7
+#define EL_PLAYER_OBSOLETE 8 /* obsolete; mapped to EL_PLAYER_1 */
+#define EL_BUG 9
+#define EL_SPACESHIP 10
+#define EL_YAMYAM 11
+#define EL_ROBOT 12
+#define EL_STEELWALL 13
+#define EL_DIAMOND 14
+#define EL_AMOEBA_DEAD 15
+#define EL_QUICKSAND_EMPTY 16
+#define EL_QUICKSAND_FULL 17
+#define EL_AMOEBA_DROP 18
+#define EL_BOMB 19
+#define EL_MAGIC_WALL 20
+#define EL_SPEED_PILL 21
+#define EL_ACID 22
+#define EL_AMOEBA_WET 23
+#define EL_AMOEBA_DRY 24
+#define EL_NUT 25
+#define EL_GAME_OF_LIFE 26
+#define EL_BIOMAZE 27
+#define EL_DYNAMITE_ACTIVE 28
+#define EL_STONEBLOCK 29
+#define EL_ROBOT_WHEEL 30
+#define EL_ROBOT_WHEEL_ACTIVE 31
+#define EL_KEY_1 32
+#define EL_KEY_2 33
+#define EL_KEY_3 34
+#define EL_KEY_4 35
+#define EL_GATE_1 36
+#define EL_GATE_2 37
+#define EL_GATE_3 38
+#define EL_GATE_4 39
+#define EL_GATE_1_GRAY 40
+#define EL_GATE_2_GRAY 41
+#define EL_GATE_3_GRAY 42
+#define EL_GATE_4_GRAY 43
+#define EL_DYNAMITE 44
+#define EL_PACMAN 45
+#define EL_INVISIBLE_WALL 46
+#define EL_LAMP 47
+#define EL_LAMP_ACTIVE 48
+#define EL_WALL_EMERALD 49
+#define EL_WALL_DIAMOND 50
+#define EL_AMOEBA_FULL 51
+#define EL_BD_AMOEBA 52
+#define EL_TIME_ORB_FULL 53
+#define EL_TIME_ORB_EMPTY 54
+#define EL_EXPANDABLE_WALL 55
+#define EL_BD_DIAMOND 56
+#define EL_EMERALD_YELLOW 57
+#define EL_WALL_BD_DIAMOND 58
+#define EL_WALL_EMERALD_YELLOW 59
+#define EL_DARK_YAMYAM 60
+#define EL_BD_MAGIC_WALL 61
+#define EL_INVISIBLE_STEELWALL 62
+
+#define EL_UNUSED_63 63
+
+#define EL_DYNABOMB_INCREASE_NUMBER 64
+#define EL_DYNABOMB_INCREASE_SIZE 65
+#define EL_DYNABOMB_INCREASE_POWER 66
+#define EL_SOKOBAN_OBJECT 67
+#define EL_SOKOBAN_FIELD_EMPTY 68
+#define EL_SOKOBAN_FIELD_FULL 69
+#define EL_BD_BUTTERFLY_RIGHT 70
+#define EL_BD_BUTTERFLY_UP 71
+#define EL_BD_BUTTERFLY_LEFT 72
+#define EL_BD_BUTTERFLY_DOWN 73
+#define EL_BD_FIREFLY_RIGHT 74
+#define EL_BD_FIREFLY_UP 75
+#define EL_BD_FIREFLY_LEFT 76
+#define EL_BD_FIREFLY_DOWN 77
+#define EL_BD_BUTTERFLY_1 EL_BD_BUTTERFLY_DOWN
+#define EL_BD_BUTTERFLY_2 EL_BD_BUTTERFLY_LEFT
+#define EL_BD_BUTTERFLY_3 EL_BD_BUTTERFLY_UP
+#define EL_BD_BUTTERFLY_4 EL_BD_BUTTERFLY_RIGHT
+#define EL_BD_FIREFLY_1 EL_BD_FIREFLY_LEFT
+#define EL_BD_FIREFLY_2 EL_BD_FIREFLY_DOWN
+#define EL_BD_FIREFLY_3 EL_BD_FIREFLY_RIGHT
+#define EL_BD_FIREFLY_4 EL_BD_FIREFLY_UP
+#define EL_BD_BUTTERFLY 78
+#define EL_BD_FIREFLY 79
+#define EL_PLAYER_1 80
+#define EL_PLAYER_2 81
+#define EL_PLAYER_3 82
+#define EL_PLAYER_4 83
+#define EL_BUG_RIGHT 84
+#define EL_BUG_UP 85
+#define EL_BUG_LEFT 86
+#define EL_BUG_DOWN 87
+#define EL_SPACESHIP_RIGHT 88
+#define EL_SPACESHIP_UP 89
+#define EL_SPACESHIP_LEFT 90
+#define EL_SPACESHIP_DOWN 91
+#define EL_PACMAN_RIGHT 92
+#define EL_PACMAN_UP 93
+#define EL_PACMAN_LEFT 94
+#define EL_PACMAN_DOWN 95
+#define EL_EMERALD_RED 96
+#define EL_EMERALD_PURPLE 97
+#define EL_WALL_EMERALD_RED 98
+#define EL_WALL_EMERALD_PURPLE 99
+#define EL_ACID_POOL_TOPLEFT 100
+#define EL_ACID_POOL_TOPRIGHT 101
+#define EL_ACID_POOL_BOTTOMLEFT 102
+#define EL_ACID_POOL_BOTTOM 103
+#define EL_ACID_POOL_BOTTOMRIGHT 104
+#define EL_BD_WALL 105
+#define EL_BD_ROCK 106
+#define EL_EXIT_OPEN 107
+#define EL_BLACK_ORB 108
+#define EL_AMOEBA_TO_DIAMOND 109
+#define EL_MOLE 110
+#define EL_PENGUIN 111
+#define EL_SATELLITE 112
+#define EL_ARROW_LEFT 113
+#define EL_ARROW_RIGHT 114
+#define EL_ARROW_UP 115
+#define EL_ARROW_DOWN 116
+#define EL_PIG 117
+#define EL_DRAGON 118
+
+#define EL_EM_KEY_1_FILE 119
+
+#define EL_CHAR_START 120
+#define EL_CHAR_ASCII0 (EL_CHAR_START - 32)
+#define EL_CHAR_ASCII0_START (EL_CHAR_ASCII0 + 32)
+
+#include "conf_chr.h" /* include auto-generated data structure definitions */
+
+#define EL_CHAR_ASCII0_END (EL_CHAR_ASCII0 + 111)
+#define EL_CHAR_END (EL_CHAR_START + 79)
+
+#define EL_CHAR(c) (EL_CHAR_ASCII0 + MAP_FONT_ASCII(c))
+
+#define EL_EXPANDABLE_WALL_HORIZONTAL 200
+#define EL_EXPANDABLE_WALL_VERTICAL 201
+#define EL_EXPANDABLE_WALL_ANY 202
+
+#define EL_EM_GATE_1 203
+#define EL_EM_GATE_2 204
+#define EL_EM_GATE_3 205
+#define EL_EM_GATE_4 206
+
+#define EL_EM_KEY_2_FILE 207
+#define EL_EM_KEY_3_FILE 208
+#define EL_EM_KEY_4_FILE 209
+
+#define EL_SP_START 210
+#define EL_SP_EMPTY_SPACE (EL_SP_START + 0)
+#define EL_SP_EMPTY EL_SP_EMPTY_SPACE
+#define EL_SP_ZONK (EL_SP_START + 1)
+#define EL_SP_BASE (EL_SP_START + 2)
+#define EL_SP_MURPHY (EL_SP_START + 3)
+#define EL_SP_INFOTRON (EL_SP_START + 4)
+#define EL_SP_CHIP_SINGLE (EL_SP_START + 5)
+#define EL_SP_HARDWARE_GRAY (EL_SP_START + 6)
+#define EL_SP_EXIT_CLOSED (EL_SP_START + 7)
+#define EL_SP_DISK_ORANGE (EL_SP_START + 8)
+#define EL_SP_PORT_RIGHT (EL_SP_START + 9)
+#define EL_SP_PORT_DOWN (EL_SP_START + 10)
+#define EL_SP_PORT_LEFT (EL_SP_START + 11)
+#define EL_SP_PORT_UP (EL_SP_START + 12)
+#define EL_SP_GRAVITY_PORT_RIGHT (EL_SP_START + 13)
+#define EL_SP_GRAVITY_PORT_DOWN (EL_SP_START + 14)
+#define EL_SP_GRAVITY_PORT_LEFT (EL_SP_START + 15)
+#define EL_SP_GRAVITY_PORT_UP (EL_SP_START + 16)
+#define EL_SP_SNIKSNAK (EL_SP_START + 17)
+#define EL_SP_DISK_YELLOW (EL_SP_START + 18)
+#define EL_SP_TERMINAL (EL_SP_START + 19)
+#define EL_SP_DISK_RED (EL_SP_START + 20)
+#define EL_SP_PORT_VERTICAL (EL_SP_START + 21)
+#define EL_SP_PORT_HORIZONTAL (EL_SP_START + 22)
+#define EL_SP_PORT_ANY (EL_SP_START + 23)
+#define EL_SP_ELECTRON (EL_SP_START + 24)
+#define EL_SP_BUGGY_BASE (EL_SP_START + 25)
+#define EL_SP_CHIP_LEFT (EL_SP_START + 26)
+#define EL_SP_CHIP_RIGHT (EL_SP_START + 27)
+#define EL_SP_HARDWARE_BASE_1 (EL_SP_START + 28)
+#define EL_SP_HARDWARE_GREEN (EL_SP_START + 29)
+#define EL_SP_HARDWARE_BLUE (EL_SP_START + 30)
+#define EL_SP_HARDWARE_RED (EL_SP_START + 31)
+#define EL_SP_HARDWARE_YELLOW (EL_SP_START + 32)
+#define EL_SP_HARDWARE_BASE_2 (EL_SP_START + 33)
+#define EL_SP_HARDWARE_BASE_3 (EL_SP_START + 34)
+#define EL_SP_HARDWARE_BASE_4 (EL_SP_START + 35)
+#define EL_SP_HARDWARE_BASE_5 (EL_SP_START + 36)
+#define EL_SP_HARDWARE_BASE_6 (EL_SP_START + 37)
+#define EL_SP_CHIP_TOP (EL_SP_START + 38)
+#define EL_SP_CHIP_BOTTOM (EL_SP_START + 39)
+#define EL_SP_END (EL_SP_START + 39)
+
+#define EL_EM_GATE_1_GRAY 250
+#define EL_EM_GATE_2_GRAY 251
+#define EL_EM_GATE_3_GRAY 252
+#define EL_EM_GATE_4_GRAY 253
+
+#define EL_UNUSED_254 254
+#define EL_UNUSED_255 255
+
+#define EL_PEARL 256
+#define EL_CRYSTAL 257
+#define EL_WALL_PEARL 258
+#define EL_WALL_CRYSTAL 259
+#define EL_DOOR_WHITE 260
+#define EL_DOOR_WHITE_GRAY 261
+#define EL_KEY_WHITE 262
+#define EL_SHIELD_NORMAL 263
+#define EL_EXTRA_TIME 264
+#define EL_SWITCHGATE_OPEN 265
+#define EL_SWITCHGATE_CLOSED 266
+#define EL_SWITCHGATE_SWITCH_UP 267
+#define EL_SWITCHGATE_SWITCH_DOWN 268
+
+#define EL_UNUSED_269 269
+#define EL_UNUSED_270 270
+
+#define EL_CONVEYOR_BELT_1_LEFT 271
+#define EL_CONVEYOR_BELT_1_MIDDLE 272
+#define EL_CONVEYOR_BELT_1_RIGHT 273
+#define EL_CONVEYOR_BELT_1_SWITCH_LEFT 274
+#define EL_CONVEYOR_BELT_1_SWITCH_MIDDLE 275
+#define EL_CONVEYOR_BELT_1_SWITCH_RIGHT 276
+#define EL_CONVEYOR_BELT_2_LEFT 277
+#define EL_CONVEYOR_BELT_2_MIDDLE 278
+#define EL_CONVEYOR_BELT_2_RIGHT 279
+#define EL_CONVEYOR_BELT_2_SWITCH_LEFT 280
+#define EL_CONVEYOR_BELT_2_SWITCH_MIDDLE 281
+#define EL_CONVEYOR_BELT_2_SWITCH_RIGHT 282
+#define EL_CONVEYOR_BELT_3_LEFT 283
+#define EL_CONVEYOR_BELT_3_MIDDLE 284
+#define EL_CONVEYOR_BELT_3_RIGHT 285
+#define EL_CONVEYOR_BELT_3_SWITCH_LEFT 286
+#define EL_CONVEYOR_BELT_3_SWITCH_MIDDLE 287
+#define EL_CONVEYOR_BELT_3_SWITCH_RIGHT 288
+#define EL_CONVEYOR_BELT_4_LEFT 289
+#define EL_CONVEYOR_BELT_4_MIDDLE 290
+#define EL_CONVEYOR_BELT_4_RIGHT 291
+#define EL_CONVEYOR_BELT_4_SWITCH_LEFT 292
+#define EL_CONVEYOR_BELT_4_SWITCH_MIDDLE 293
+#define EL_CONVEYOR_BELT_4_SWITCH_RIGHT 294
+#define EL_LANDMINE 295
+#define EL_ENVELOPE 296
+#define EL_LIGHT_SWITCH 297
+#define EL_LIGHT_SWITCH_ACTIVE 298
+#define EL_SIGN_EXCLAMATION 299
+#define EL_SIGN_RADIOACTIVITY 300
+#define EL_SIGN_STOP 301
+#define EL_SIGN_WHEELCHAIR 302
+#define EL_SIGN_PARKING 303
+#define EL_SIGN_ONEWAY 304
+#define EL_SIGN_HEART 305
+#define EL_SIGN_TRIANGLE 306
+#define EL_SIGN_ROUND 307
+#define EL_SIGN_EXIT 308
+#define EL_SIGN_YINYANG 309
+#define EL_SIGN_OTHER 310
+#define EL_MOLE_LEFT 311
+#define EL_MOLE_RIGHT 312
+#define EL_MOLE_UP 313
+#define EL_MOLE_DOWN 314
+#define EL_STEELWALL_SLIPPERY 315
+#define EL_INVISIBLE_SAND 316
+#define EL_DX_UNKNOWN_15 317
+#define EL_DX_UNKNOWN_42 318
+
+#define EL_UNUSED_319 319
+#define EL_UNUSED_320 320
+
+#define EL_SHIELD_DEADLY 321
+#define EL_TIMEGATE_OPEN 322
+#define EL_TIMEGATE_CLOSED 323
+#define EL_TIMEGATE_SWITCH_ACTIVE 324
+#define EL_TIMEGATE_SWITCH 325
+
+#define EL_BALLOON 326
+#define EL_BALLOON_SWITCH_LEFT 327
+#define EL_BALLOON_SWITCH_RIGHT 328
+#define EL_BALLOON_SWITCH_UP 329
+#define EL_BALLOON_SWITCH_DOWN 330
+#define EL_BALLOON_SWITCH_ANY 331
+
+#define EL_EMC_STEELWALL_1 332
+#define EL_EMC_STEELWALL_2 333
+#define EL_EMC_STEELWALL_3 334
+#define EL_EMC_STEELWALL_4 335
+#define EL_EMC_WALL_1 336
+#define EL_EMC_WALL_2 337
+#define EL_EMC_WALL_3 338
+#define EL_EMC_WALL_4 339
+#define EL_EMC_WALL_5 340
+#define EL_EMC_WALL_6 341
+#define EL_EMC_WALL_7 342
+#define EL_EMC_WALL_8 343
+
+#define EL_TUBE_ANY 344
+#define EL_TUBE_VERTICAL 345
+#define EL_TUBE_HORIZONTAL 346
+#define EL_TUBE_VERTICAL_LEFT 347
+#define EL_TUBE_VERTICAL_RIGHT 348
+#define EL_TUBE_HORIZONTAL_UP 349
+#define EL_TUBE_HORIZONTAL_DOWN 350
+#define EL_TUBE_LEFT_UP 351
+#define EL_TUBE_LEFT_DOWN 352
+#define EL_TUBE_RIGHT_UP 353
+#define EL_TUBE_RIGHT_DOWN 354
+#define EL_SPRING 355
+#define EL_TRAP 356
+#define EL_DX_SUPABOMB 357
+
+#define EL_UNUSED_358 358
+#define EL_UNUSED_359 359
+
+#define EL_CUSTOM_START 360
+
+#include "conf_cus.h" /* include auto-generated data structure definitions */
+
+#define EL_CUSTOM_END (EL_CUSTOM_START + 127)
+
+#define NUM_CUSTOM_ELEMENTS 128
+#define NUM_FILE_ELEMENTS 488
+
+
+/* "real" (and therefore drawable) runtime elements */
+#define EL_FIRST_RUNTIME_REAL NUM_FILE_ELEMENTS
+
+#define EL_EM_KEY_1 (EL_FIRST_RUNTIME_REAL + 0)
+#define EL_EM_KEY_2 (EL_FIRST_RUNTIME_REAL + 1)
+#define EL_EM_KEY_3 (EL_FIRST_RUNTIME_REAL + 2)
+#define EL_EM_KEY_4 (EL_FIRST_RUNTIME_REAL + 3)
+#define EL_DYNABOMB_PLAYER_1_ACTIVE (EL_FIRST_RUNTIME_REAL + 4)
+#define EL_DYNABOMB_PLAYER_2_ACTIVE (EL_FIRST_RUNTIME_REAL + 5)
+#define EL_DYNABOMB_PLAYER_3_ACTIVE (EL_FIRST_RUNTIME_REAL + 6)
+#define EL_DYNABOMB_PLAYER_4_ACTIVE (EL_FIRST_RUNTIME_REAL + 7)
+#define EL_SP_DISK_RED_ACTIVE (EL_FIRST_RUNTIME_REAL + 8)
+#define EL_SWITCHGATE_OPENING (EL_FIRST_RUNTIME_REAL + 9)
+#define EL_SWITCHGATE_CLOSING (EL_FIRST_RUNTIME_REAL + 10)
+#define EL_TIMEGATE_OPENING (EL_FIRST_RUNTIME_REAL + 11)
+#define EL_TIMEGATE_CLOSING (EL_FIRST_RUNTIME_REAL + 12)
+#define EL_PEARL_BREAKING (EL_FIRST_RUNTIME_REAL + 13)
+#define EL_TRAP_ACTIVE (EL_FIRST_RUNTIME_REAL + 14)
+#define EL_INVISIBLE_STEELWALL_ACTIVE (EL_FIRST_RUNTIME_REAL + 15)
+#define EL_INVISIBLE_WALL_ACTIVE (EL_FIRST_RUNTIME_REAL + 16)
+#define EL_INVISIBLE_SAND_ACTIVE (EL_FIRST_RUNTIME_REAL + 17)
+#define EL_CONVEYOR_BELT_1_LEFT_ACTIVE (EL_FIRST_RUNTIME_REAL + 18)
+#define EL_CONVEYOR_BELT_1_MIDDLE_ACTIVE (EL_FIRST_RUNTIME_REAL + 19)
+#define EL_CONVEYOR_BELT_1_RIGHT_ACTIVE (EL_FIRST_RUNTIME_REAL + 20)
+#define EL_CONVEYOR_BELT_2_LEFT_ACTIVE (EL_FIRST_RUNTIME_REAL + 21)
+#define EL_CONVEYOR_BELT_2_MIDDLE_ACTIVE (EL_FIRST_RUNTIME_REAL + 22)
+#define EL_CONVEYOR_BELT_2_RIGHT_ACTIVE (EL_FIRST_RUNTIME_REAL + 23)
+#define EL_CONVEYOR_BELT_3_LEFT_ACTIVE (EL_FIRST_RUNTIME_REAL + 24)
+#define EL_CONVEYOR_BELT_3_MIDDLE_ACTIVE (EL_FIRST_RUNTIME_REAL + 25)
+#define EL_CONVEYOR_BELT_3_RIGHT_ACTIVE (EL_FIRST_RUNTIME_REAL + 26)
+#define EL_CONVEYOR_BELT_4_LEFT_ACTIVE (EL_FIRST_RUNTIME_REAL + 27)
+#define EL_CONVEYOR_BELT_4_MIDDLE_ACTIVE (EL_FIRST_RUNTIME_REAL + 28)
+#define EL_CONVEYOR_BELT_4_RIGHT_ACTIVE (EL_FIRST_RUNTIME_REAL + 29)
+#define EL_EXIT_OPENING (EL_FIRST_RUNTIME_REAL + 30)
+#define EL_SP_EXIT_OPEN (EL_FIRST_RUNTIME_REAL + 31)
+#define EL_SP_TERMINAL_ACTIVE (EL_FIRST_RUNTIME_REAL + 32)
+#define EL_SP_BUGGY_BASE_ACTIVATING (EL_FIRST_RUNTIME_REAL + 33)
+#define EL_SP_BUGGY_BASE_ACTIVE (EL_FIRST_RUNTIME_REAL + 34)
+#define EL_SP_MURPHY_CLONE (EL_FIRST_RUNTIME_REAL + 35)
+#define EL_AMOEBA_DROPPING (EL_FIRST_RUNTIME_REAL + 36)
+#define EL_QUICKSAND_EMPTYING (EL_FIRST_RUNTIME_REAL + 37)
+#define EL_MAGIC_WALL_ACTIVE (EL_FIRST_RUNTIME_REAL + 38)
+#define EL_BD_MAGIC_WALL_ACTIVE (EL_FIRST_RUNTIME_REAL + 39)
+#define EL_MAGIC_WALL_FULL (EL_FIRST_RUNTIME_REAL + 40)
+#define EL_BD_MAGIC_WALL_FULL (EL_FIRST_RUNTIME_REAL + 41)
+#define EL_MAGIC_WALL_EMPTYING (EL_FIRST_RUNTIME_REAL + 42)
+#define EL_BD_MAGIC_WALL_EMPTYING (EL_FIRST_RUNTIME_REAL + 43)
+#define EL_MAGIC_WALL_DEAD (EL_FIRST_RUNTIME_REAL + 44)
+#define EL_BD_MAGIC_WALL_DEAD (EL_FIRST_RUNTIME_REAL + 45)
+
+/* "unreal" (and therefore not drawable) runtime elements */
+#define EL_FIRST_RUNTIME_UNREAL (EL_FIRST_RUNTIME_REAL + 46)
+
+#define EL_BLOCKED (EL_FIRST_RUNTIME_UNREAL + 0)
+#define EL_EXPLOSION (EL_FIRST_RUNTIME_UNREAL + 1)
+#define EL_NUT_BREAKING (EL_FIRST_RUNTIME_UNREAL + 2)
+#define EL_DIAMOND_BREAKING (EL_FIRST_RUNTIME_UNREAL + 3)
+#define EL_ACID_SPLASH_LEFT (EL_FIRST_RUNTIME_UNREAL + 4)
+#define EL_ACID_SPLASH_RIGHT (EL_FIRST_RUNTIME_UNREAL + 5)
+#define EL_AMOEBA_GROWING (EL_FIRST_RUNTIME_UNREAL + 6)
+#define EL_AMOEBA_SHRINKING (EL_FIRST_RUNTIME_UNREAL + 7)
+#define EL_EXPANDABLE_WALL_GROWING (EL_FIRST_RUNTIME_UNREAL + 8)
+#define EL_FLAMES (EL_FIRST_RUNTIME_UNREAL + 9)
+#define EL_PLAYER_IS_LEAVING (EL_FIRST_RUNTIME_UNREAL + 10)
+#define EL_QUICKSAND_FILLING (EL_FIRST_RUNTIME_UNREAL + 11)
+#define EL_MAGIC_WALL_FILLING (EL_FIRST_RUNTIME_UNREAL + 12)
+#define EL_BD_MAGIC_WALL_FILLING (EL_FIRST_RUNTIME_UNREAL + 13)
+
+/* dummy elements (never used as game elements, only used as graphics) */
+#define EL_FIRST_DUMMY (EL_FIRST_RUNTIME_UNREAL + 14)
+
+#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_DEFAULT (EL_FIRST_DUMMY + 20)
+#define EL_BD_DEFAULT (EL_FIRST_DUMMY + 21)
+#define EL_SP_DEFAULT (EL_FIRST_DUMMY + 22)
+#define EL_SB_DEFAULT (EL_FIRST_DUMMY + 23)
+
+#define MAX_NUM_ELEMENTS (EL_FIRST_DUMMY + 24)
+
+
+/* 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_DYING 25
+#define ACTION_OTHER 26
+
+#define NUM_ACTIONS 27
+
+/* values for special image configuration suffixes (must match game mode) */
+#define GFX_SPECIAL_ARG_MAIN 0
+#define GFX_SPECIAL_ARG_LEVELS 1
+#define GFX_SPECIAL_ARG_SCORES 2
+#define GFX_SPECIAL_ARG_EDITOR 3
+#define GFX_SPECIAL_ARG_INFO 4
+#define GFX_SPECIAL_ARG_SETUP 5
+#define GFX_SPECIAL_ARG_DOOR 6
+#define GFX_SPECIAL_ARG_PREVIEW 7
+#define GFX_SPECIAL_ARG_CRUMBLED 8
+
+#define NUM_SPECIAL_GFX_ARGS 9
+
+
+/* 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_STEP_OFFSET 18
+#define GFX_ARG_STEP_DELAY 19
+#define GFX_ARG_DIRECTION 20
+#define GFX_ARG_POSITION 21
+#define GFX_ARG_DRAW_XOFFSET 22
+#define GFX_ARG_DRAW_YOFFSET 23
+#define GFX_ARG_NAME 24
+
+#define NUM_GFX_ARGS 25
+
+
+/* values for sound configuration suffixes */
+#define SND_ARG_MODE_LOOP 0
+
+#define NUM_SND_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_INPUT_1_ACTIVE 16
+#define FONT_INPUT_2_ACTIVE 17
+#define FONT_INPUT_1 18
+#define FONT_INPUT_2 19
+#define FONT_OPTION_OFF 20
+#define FONT_OPTION_ON 21
+#define FONT_VALUE_1 22
+#define FONT_VALUE_2 23
+#define FONT_VALUE_OLD 24
+#define FONT_LEVEL_NUMBER 25
+#define FONT_TAPE_RECORDER 26
+#define FONT_GAME_INFO 27
+
+#define NUM_FONTS 28
+#define NUM_INITIAL_FONTS 4
+
+/* values for game_status (must match special image configuration suffixes) */
+#define GAME_MODE_MAIN 0
+#define GAME_MODE_LEVELS 1
+#define GAME_MODE_SCORES 2
+#define GAME_MODE_EDITOR 3
+#define GAME_MODE_INFO 4
+#define GAME_MODE_SETUP 5
+#define GAME_MODE_PSEUDO_DOOR 6
+#define GAME_MODE_PSEUDO_PREVIEW 7
+#define GAME_MODE_PSEUDO_CRUMBLED 8
+
+/* there are no special config file suffixes for these modes */
+#define GAME_MODE_PLAYING 9
+#define GAME_MODE_PSEUDO_TYPENAME 10
+#define GAME_MODE_QUIT 11
+
+#define PROGRAM_VERSION_MAJOR 3
+#define PROGRAM_VERSION_MINOR 0
+#define PROGRAM_VERSION_PATCH 0
+#define PROGRAM_VERSION_RELEASE 0
+#define PROGRAM_VERSION_STRING "3.0.0"
+
+#define PROGRAM_TITLE_STRING "Rocks'n'Diamonds"
+#define PROGRAM_AUTHOR_STRING "Holger Schemel"
+#define PROGRAM_RIGHTS_STRING "Copyright ©1995-2003 by"
+#define PROGRAM_DOS_PORT_STRING "DOS port done by Guido Schulz"
+#define PROGRAM_IDENT_STRING PROGRAM_VERSION_STRING " " TARGET_STRING
+#define WINDOW_TITLE_STRING PROGRAM_TITLE_STRING " " PROGRAM_IDENT_STRING
+#define WINDOW_SUBTITLE_STRING PROGRAM_RIGHTS_STRING " " PROGRAM_AUTHOR_STRING
+#define ICON_TITLE_STRING PROGRAM_TITLE_STRING
+#define COOKIE_PREFIX "ROCKSNDIAMONDS"
+#define FILENAME_PREFIX "Rocks"
+
+#if defined(PLATFORM_UNIX)
+#define USERDATA_DIRECTORY ".rocksndiamonds"
+#elif defined(PLATFORM_WIN32)
+#define USERDATA_DIRECTORY PROGRAM_TITLE_STRING
+#else
+#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"
+
+/* file version numbers for resource files (levels, tapes, score, setup, etc.)
+** currently supported/known file version numbers:
+** 1.0 (old)
+** 1.2 (still in use)
+** 1.4 (still in use)
+** 2.0 (actual)
+*/
+#define FILE_VERSION_1_0 VERSION_IDENT(1,0,0)
+#define FILE_VERSION_1_2 VERSION_IDENT(1,2,0)
+#define FILE_VERSION_1_4 VERSION_IDENT(1,4,0)
+#define FILE_VERSION_2_0 VERSION_IDENT(2,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 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 RELEASE_IDENT(PROGRAM_VERSION_MAJOR, \
+ PROGRAM_VERSION_MINOR, \
+ PROGRAM_VERSION_PATCH, \
+ PROGRAM_VERSION_RELEASE)
+
+/* values for game_emulation */
+#define EMU_NONE 0
+#define EMU_BOULDERDASH 1
+#define EMU_SOKOBAN 2
+#define EMU_SUPAPLEX 3
+
struct HiScore
{
char Name[MAX_PLAYER_NAME_LEN + 1];
through doors); overrides other actions */
int jx,jy, last_jx,last_jy;
- int MovDir, MovPos, GfxPos;
- int Frame;
+ int MovDir, MovPos, GfxDir, GfxPos;
+ int Frame, StepFrame;
+
+ int GfxAction;
+
+ boolean use_murphy_graphic;
+ boolean use_disk_red_graphic;
boolean Pushing;
boolean Switching;
boolean snapped;
int last_move_dir;
- int is_moving;
+ boolean is_moving;
+ boolean is_waiting;
+ boolean is_digging;
+ boolean is_collecting;
unsigned long move_delay;
int move_delay_value;
unsigned long push_delay;
unsigned long push_delay_value;
- int frame_reset_delay;
-
unsigned long actual_frame_counter;
int score;
int key[4];
int dynamite;
int dynabomb_count, dynabomb_size, dynabombs_left, dynabomb_xl;
- int shield_passive_time_left;
- int shield_active_time_left;
+ int shield_normal_time_left;
+ int shield_deadly_time_left;
};
struct LevelInfo
char name[MAX_LEVEL_NAME_LEN + 1];
char author[MAX_LEVEL_AUTHOR_LEN + 1];
int score[LEVEL_SCORE_ELEMENTS];
- int yam_content[MAX_ELEMENT_CONTENTS][3][3];
- int num_yam_contents;
+ int yamyam_content[MAX_ELEMENT_CONTENTS][3][3];
+ int num_yamyam_contents;
int amoeba_speed;
int amoeba_content;
int time_magic_wall;
boolean double_speed;
boolean gravity;
boolean em_slippery_gems; /* EM style "gems slip from wall" behaviour */
+
+ short field[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+
+ boolean use_custom_template; /* use custom properties from template file */
+
+ boolean no_level_file;
};
struct TapeInfo
int game_version; /* game release version the tape was created with */
int engine_version; /* game engine version the tape was recorded with */
+ char *level_identifier;
int level_nr;
unsigned long random_seed;
unsigned long date;
boolean recording, playing, pausing;
boolean fast_forward;
boolean index_search;
+ boolean auto_play;
+ boolean auto_play_level_solved;
boolean quick_resume;
boolean single_step;
boolean changed;
int initial_move_delay_value;
/* variable within running game */
- int yam_content_nr;
+ int yamyam_content_nr;
boolean magic_wall_active;
int magic_wall_time_left;
int light_time_left;
struct GlobalInfo
{
+ char *autoplay_leveldir;
+ int autoplay_level_nr;
+
+ int num_toons;
+
float frames_per_second;
boolean fps_slowdown;
int fps_slowdown_factor;
};
-struct ElementInfo
+struct MenuInfo
{
- char *sound_class_name;
- char *editor_description;
+ 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];
};
-extern GC tile_clip_gc;
-extern Bitmap *pix[];
-extern Pixmap tile_clipmask[];
-extern DrawBuffer *fieldbuffer;
-extern DrawBuffer *drawto_field;
-
-extern int game_status;
-extern boolean level_editor_test_game;
-extern boolean network_playing;
-
-extern int key_joystick_mapping;
-
-extern boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
-extern int redraw_x1, redraw_y1;
-
-extern short Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern short Ur[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern short MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern short MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern short MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern short Frame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern short JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern short AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern short AmoebaCnt[MAX_NUM_AMOEBA], AmoebaCnt2[MAX_NUM_AMOEBA];
-extern short ExplodeField[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern unsigned long Elementeigenschaften1[MAX_ELEMENTS];
-extern unsigned long Elementeigenschaften2[MAX_ELEMENTS];
-
-extern int lev_fieldx,lev_fieldy, scroll_x,scroll_y;
-
-extern int FX,FY, ScrollStepSize;
-extern int ScreenMovDir, ScreenMovPos, ScreenGfxPos;
-extern int BorderElement;
-extern int GameFrameDelay;
-extern int FfwdFrameDelay;
-extern int BX1,BY1, BX2,BY2;
-extern int SBX_Left, SBX_Right;
-extern int SBY_Upper, SBY_Lower;
-extern int ZX,ZY, ExitX,ExitY;
-extern int AllPlayersGone;
-
-extern int TimeFrames, TimePlayed, TimeLeft;
-extern boolean SiebAktiv;
-extern int SiebCount;
-
-extern boolean network_player_action_received;
-
-extern struct LevelInfo level;
-extern struct PlayerInfo stored_player[], *local_player;
-extern struct HiScore highscore[];
-extern struct TapeInfo tape;
-extern struct GameInfo game;
-extern struct GlobalInfo global;
-extern struct ElementInfo element_info[];
-extern struct SoundEffectInfo sound_effects[];
+struct DoorInfo
+{
+ int step_offset;
+ int step_delay;
+};
-/* often used screen positions */
-#define SX 8
-#define SY 8
-#define REAL_SX (SX - 2)
-#define REAL_SY (SY - 2)
-#define DX 566
-#define DY 60
-#define VX DX
-#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 MIDPOSX (SCR_FIELDX / 2)
-#define MIDPOSY (SCR_FIELDY / 2)
-#define SXSIZE (SCR_FIELDX * TILEX)
-#define SYSIZE (SCR_FIELDY * TILEY)
-#define FXSIZE ((SCR_FIELDX + 2) * TILEX)
-#define FYSIZE ((SCR_FIELDY + 2) * TILEY)
-#define DXSIZE 100
-#define DYSIZE 280
-#define VXSIZE DXSIZE
-#define VYSIZE 100
-#define EXSIZE DXSIZE
-#define EYSIZE (VXSIZE + 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)
+struct ElementChangeInfo
+{
+ unsigned long events; /* bitfield for change events */
-#define GFX_STARTX SX
-#define GFX_STARTY SY
-#define MINI_GFX_STARTX SX
-#define MINI_GFX_STARTY 424
-#define MICRO_GFX_STARTX SX
-#define MICRO_GFX_STARTY 536
-#define GFX_PER_LINE 16
-#define MINI_GFX_PER_LINE 32
-#define MICRO_GFX_PER_LINE 128
-
-#define HEROES_PER_LINE 16
-
-#define MINI_SP_STARTX 0
-#define MINI_SP_STARTY 352
-#define MICRO_SP_STARTX 0
-#define MICRO_SP_STARTY 448
-#define SP_PER_LINE 16
-#define MINI_SP_PER_LINE 16
-#define MICRO_SP_PER_LINE 64
-
-#define MINI_DC_STARTX 256
-#define MINI_DC_STARTY 256
-#define MICRO_DC_STARTX 384
-#define MICRO_DC_STARTY 384
-#define DC_PER_LINE 16
-#define MINI_DC_PER_LINE 16
-#define MICRO_DC_PER_LINE 16
-
-#define MINI_MORE_STARTX 256
-#define MINI_MORE_STARTY 256
-#define MICRO_MORE_STARTX 384
-#define MICRO_MORE_STARTY 384
-#define MORE_PER_LINE 16
-#define MINI_MORE_PER_LINE 16
-#define MICRO_MORE_PER_LINE 16
-
-/* game elements:
-** 0 - 499: real elements, stored in level file
-** 500 - 699: flag elements, only used at runtime
-*/
-/* "real" level elements */
-#define EL_LEERRAUM 0
-#define EL_ERDREICH 1
-#define EL_MAUERWERK 2
-#define EL_FELSBODEN 3
-#define EL_FELSBROCKEN 4
-#define EL_SCHLUESSEL 5
-#define EL_EDELSTEIN 6
-#define EL_AUSGANG_ZU 7
-#define EL_SPIELFIGUR 8
-#define EL_KAEFER 9
-#define EL_FLIEGER 10
-#define EL_MAMPFER 11
-#define EL_ROBOT 12
-#define EL_BETON 13
-#define EL_DIAMANT 14
-#define EL_AMOEBE_TOT 15
-#define EL_MORAST_LEER 16
-#define EL_MORAST_VOLL 17
-#define EL_TROPFEN 18
-#define EL_BOMBE 19
-#define EL_MAGIC_WALL_OFF 20
-#define EL_SPEED_PILL 21
-#define EL_SALZSAEURE 22
-#define EL_AMOEBE_NASS 23
-#define EL_AMOEBE_NORM 24
-#define EL_KOKOSNUSS 25
-#define EL_LIFE 26
-#define EL_LIFE_ASYNC 27
-#define EL_DYNAMITE_ACTIVE 28
-#define EL_BADEWANNE 29
-#define EL_ABLENK_AUS 30
-#define EL_ABLENK_EIN 31
-#define EL_SCHLUESSEL1 32
-#define EL_SCHLUESSEL2 33
-#define EL_SCHLUESSEL3 34
-#define EL_SCHLUESSEL4 35
-#define EL_PFORTE1 36
-#define EL_PFORTE2 37
-#define EL_PFORTE3 38
-#define EL_PFORTE4 39
-#define EL_PFORTE1X 40
-#define EL_PFORTE2X 41
-#define EL_PFORTE3X 42
-#define EL_PFORTE4X 43
-#define EL_DYNAMITE_INACTIVE 44
-#define EL_PACMAN 45
-#define EL_UNSICHTBAR 46
-#define EL_BIRNE_AUS 47
-#define EL_BIRNE_EIN 48
-#define EL_ERZ_EDEL 49
-#define EL_ERZ_DIAM 50
-#define EL_AMOEBE_VOLL 51
-#define EL_AMOEBE_BD 52
-#define EL_ZEIT_VOLL 53
-#define EL_ZEIT_LEER 54
-#define EL_MAUER_LEBT 55
-#define EL_EDELSTEIN_BD 56
-#define EL_EDELSTEIN_GELB 57
-#define EL_ERZ_EDEL_BD 58
-#define EL_ERZ_EDEL_GELB 59
-#define EL_MAMPFER2 60
-#define EL_MAGIC_WALL_BD_OFF 61
-#define EL_INVISIBLE_STEEL 62
-
-#define EL_UNUSED_63 63
-
-#define EL_DYNABOMB_NR 64
-#define EL_DYNABOMB_SZ 65
-#define EL_DYNABOMB_XL 66
-#define EL_SOKOBAN_OBJEKT 67
-#define EL_SOKOBAN_FELD_LEER 68
-#define EL_SOKOBAN_FELD_VOLL 69
-#define EL_BUTTERFLY_RIGHT 70
-#define EL_BUTTERFLY_UP 71
-#define EL_BUTTERFLY_LEFT 72
-#define EL_BUTTERFLY_DOWN 73
-#define EL_FIREFLY_RIGHT 74
-#define EL_FIREFLY_UP 75
-#define EL_FIREFLY_LEFT 76
-#define EL_FIREFLY_DOWN 77
-#define EL_BUTTERFLY_1 EL_BUTTERFLY_DOWN
-#define EL_BUTTERFLY_2 EL_BUTTERFLY_LEFT
-#define EL_BUTTERFLY_3 EL_BUTTERFLY_UP
-#define EL_BUTTERFLY_4 EL_BUTTERFLY_RIGHT
-#define EL_FIREFLY_1 EL_FIREFLY_LEFT
-#define EL_FIREFLY_2 EL_FIREFLY_DOWN
-#define EL_FIREFLY_3 EL_FIREFLY_RIGHT
-#define EL_FIREFLY_4 EL_FIREFLY_UP
-#define EL_BUTTERFLY 78
-#define EL_FIREFLY 79
-#define EL_SPIELER1 80
-#define EL_SPIELER2 81
-#define EL_SPIELER3 82
-#define EL_SPIELER4 83
-#define EL_KAEFER_RIGHT 84
-#define EL_KAEFER_UP 85
-#define EL_KAEFER_LEFT 86
-#define EL_KAEFER_DOWN 87
-#define EL_FLIEGER_RIGHT 88
-#define EL_FLIEGER_UP 89
-#define EL_FLIEGER_LEFT 90
-#define EL_FLIEGER_DOWN 91
-#define EL_PACMAN_RIGHT 92
-#define EL_PACMAN_UP 93
-#define EL_PACMAN_LEFT 94
-#define EL_PACMAN_DOWN 95
-#define EL_EDELSTEIN_ROT 96
-#define EL_EDELSTEIN_LILA 97
-#define EL_ERZ_EDEL_ROT 98
-#define EL_ERZ_EDEL_LILA 99
-#define EL_BADEWANNE1 100
-#define EL_BADEWANNE2 101
-#define EL_BADEWANNE3 102
-#define EL_BADEWANNE4 103
-#define EL_BADEWANNE5 104
-#define EL_BD_WALL 105
-#define EL_BD_ROCK 106
-#define EL_AUSGANG_AUF 107
-#define EL_BLACK_ORB 108
-#define EL_AMOEBA2DIAM 109
-#define EL_MOLE 110
-#define EL_PINGUIN 111
-#define EL_SONDE 112
-#define EL_PFEIL_LEFT 113
-#define EL_PFEIL_RIGHT 114
-#define EL_PFEIL_UP 115
-#define EL_PFEIL_DOWN 116
-#define EL_SCHWEIN 117
-#define EL_DRACHE 118
-
-#define EL_EM_KEY_1_FILE 119
-
-#define EL_CHAR_START 120
-#define EL_CHAR_ASCII0 (EL_CHAR_START-32)
-#define EL_CHAR_AUSRUF (EL_CHAR_ASCII0+33)
-#define EL_CHAR_ZOLL (EL_CHAR_ASCII0+34)
-#define EL_CHAR_RAUTE (EL_CHAR_ASCII0+35)
-#define EL_CHAR_DOLLAR (EL_CHAR_ASCII0+36)
-#define EL_CHAR_PROZ (EL_CHAR_ASCII0+37)
-#define EL_CHAR_AMPERSAND (EL_CHAR_ASCII0+38)
-#define EL_CHAR_APOSTR (EL_CHAR_ASCII0+39)
-#define EL_CHAR_KLAMM1 (EL_CHAR_ASCII0+40)
-#define EL_CHAR_KLAMM2 (EL_CHAR_ASCII0+41)
-#define EL_CHAR_MULT (EL_CHAR_ASCII0+42)
-#define EL_CHAR_PLUS (EL_CHAR_ASCII0+43)
-#define EL_CHAR_KOMMA (EL_CHAR_ASCII0+44)
-#define EL_CHAR_MINUS (EL_CHAR_ASCII0+45)
-#define EL_CHAR_PUNKT (EL_CHAR_ASCII0+46)
-#define EL_CHAR_SLASH (EL_CHAR_ASCII0+47)
-#define EL_CHAR_0 (EL_CHAR_ASCII0+48)
-#define EL_CHAR_9 (EL_CHAR_ASCII0+57)
-#define EL_CHAR_DOPPEL (EL_CHAR_ASCII0+58)
-#define EL_CHAR_SEMIKL (EL_CHAR_ASCII0+59)
-#define EL_CHAR_LT (EL_CHAR_ASCII0+60)
-#define EL_CHAR_GLEICH (EL_CHAR_ASCII0+61)
-#define EL_CHAR_GT (EL_CHAR_ASCII0+62)
-#define EL_CHAR_FRAGE (EL_CHAR_ASCII0+63)
-#define EL_CHAR_AT (EL_CHAR_ASCII0+64)
-#define EL_CHAR_A (EL_CHAR_ASCII0+65)
-#define EL_CHAR_Z (EL_CHAR_ASCII0+90)
-#define EL_CHAR_AE (EL_CHAR_ASCII0+91)
-#define EL_CHAR_OE (EL_CHAR_ASCII0+92)
-#define EL_CHAR_UE (EL_CHAR_ASCII0+93)
-#define EL_CHAR_COPY (EL_CHAR_ASCII0+94)
-#define EL_CHAR_END (EL_CHAR_START+79)
-
-#define EL_CHAR(x) ((x) == 'Ä' ? EL_CHAR_AE : \
- (x) == 'Ö' ? EL_CHAR_OE : \
- (x) == 'Ü' ? EL_CHAR_UE : \
- EL_CHAR_A + (x) - 'A')
-
-#define EL_MAUER_X 200
-#define EL_MAUER_Y 201
-#define EL_MAUER_XY 202
-
-#define EL_EM_GATE_1 203
-#define EL_EM_GATE_2 204
-#define EL_EM_GATE_3 205
-#define EL_EM_GATE_4 206
-
-#define EL_EM_KEY_2_FILE 207
-#define EL_EM_KEY_3_FILE 208
-#define EL_EM_KEY_4_FILE 209
-
-#define EL_SP_START 210
-#define EL_SP_EMPTY (EL_SP_START + 0)
-#define EL_SP_ZONK (EL_SP_START + 1)
-#define EL_SP_BASE (EL_SP_START + 2)
-#define EL_SP_MURPHY (EL_SP_START + 3)
-#define EL_SP_INFOTRON (EL_SP_START + 4)
-#define EL_SP_CHIP_SINGLE (EL_SP_START + 5)
-#define EL_SP_HARD_GRAY (EL_SP_START + 6)
-#define EL_SP_EXIT (EL_SP_START + 7)
-#define EL_SP_DISK_ORANGE (EL_SP_START + 8)
-#define EL_SP_PORT1_RIGHT (EL_SP_START + 9)
-#define EL_SP_PORT1_DOWN (EL_SP_START + 10)
-#define EL_SP_PORT1_LEFT (EL_SP_START + 11)
-#define EL_SP_PORT1_UP (EL_SP_START + 12)
-#define EL_SP_PORT2_RIGHT (EL_SP_START + 13)
-#define EL_SP_PORT2_DOWN (EL_SP_START + 14)
-#define EL_SP_PORT2_LEFT (EL_SP_START + 15)
-#define EL_SP_PORT2_UP (EL_SP_START + 16)
-#define EL_SP_SNIKSNAK (EL_SP_START + 17)
-#define EL_SP_DISK_YELLOW (EL_SP_START + 18)
-#define EL_SP_TERMINAL (EL_SP_START + 19)
-#define EL_SP_DISK_RED (EL_SP_START + 20)
-#define EL_SP_PORT_Y (EL_SP_START + 21)
-#define EL_SP_PORT_X (EL_SP_START + 22)
-#define EL_SP_PORT_XY (EL_SP_START + 23)
-#define EL_SP_ELECTRON (EL_SP_START + 24)
-#define EL_SP_BUG (EL_SP_START + 25)
-#define EL_SP_CHIP_LEFT (EL_SP_START + 26)
-#define EL_SP_CHIP_RIGHT (EL_SP_START + 27)
-#define EL_SP_HARD_BASE1 (EL_SP_START + 28)
-#define EL_SP_HARD_GREEN (EL_SP_START + 29)
-#define EL_SP_HARD_BLUE (EL_SP_START + 30)
-#define EL_SP_HARD_RED (EL_SP_START + 31)
-#define EL_SP_HARD_YELLOW (EL_SP_START + 32)
-#define EL_SP_HARD_BASE2 (EL_SP_START + 33)
-#define EL_SP_HARD_BASE3 (EL_SP_START + 34)
-#define EL_SP_HARD_BASE4 (EL_SP_START + 35)
-#define EL_SP_HARD_BASE5 (EL_SP_START + 36)
-#define EL_SP_HARD_BASE6 (EL_SP_START + 37)
-#define EL_SP_CHIP_UPPER (EL_SP_START + 38)
-#define EL_SP_CHIP_LOWER (EL_SP_START + 39)
-#define EL_SP_END (EL_SP_START + 39)
-
-#define EL_EM_GATE_1X 250
-#define EL_EM_GATE_2X 251
-#define EL_EM_GATE_3X 252
-#define EL_EM_GATE_4X 253
-
-#define EL_UNUSED_254 254
-#define EL_UNUSED_255 255
-
-#define EL_PEARL 256
-#define EL_CRYSTAL 257
-#define EL_WALL_PEARL 258
-#define EL_WALL_CRYSTAL 259
-#define EL_DOOR_WHITE 260
-#define EL_DOOR_WHITE_GRAY 261
-#define EL_KEY_WHITE 262
-#define EL_SHIELD_PASSIVE 263
-#define EL_EXTRA_TIME 264
-#define EL_SWITCHGATE_OPEN 265
-#define EL_SWITCHGATE_CLOSED 266
-#define EL_SWITCHGATE_SWITCH_1 267
-#define EL_SWITCHGATE_SWITCH_2 268
-
-#define EL_UNUSED_269 269
-#define EL_UNUSED_270 270
-
-#define EL_BELT1_LEFT 271
-#define EL_BELT1_MIDDLE 272
-#define EL_BELT1_RIGHT 273
-#define EL_BELT1_SWITCH_LEFT 274
-#define EL_BELT1_SWITCH_MIDDLE 275
-#define EL_BELT1_SWITCH_RIGHT 276
-#define EL_BELT2_LEFT 277
-#define EL_BELT2_MIDDLE 278
-#define EL_BELT2_RIGHT 279
-#define EL_BELT2_SWITCH_LEFT 280
-#define EL_BELT2_SWITCH_MIDDLE 281
-#define EL_BELT2_SWITCH_RIGHT 282
-#define EL_BELT3_LEFT 283
-#define EL_BELT3_MIDDLE 284
-#define EL_BELT3_RIGHT 285
-#define EL_BELT3_SWITCH_LEFT 286
-#define EL_BELT3_SWITCH_MIDDLE 287
-#define EL_BELT3_SWITCH_RIGHT 288
-#define EL_BELT4_LEFT 289
-#define EL_BELT4_MIDDLE 290
-#define EL_BELT4_RIGHT 291
-#define EL_BELT4_SWITCH_LEFT 292
-#define EL_BELT4_SWITCH_MIDDLE 293
-#define EL_BELT4_SWITCH_RIGHT 294
-#define EL_LANDMINE 295
-#define EL_ENVELOPE 296
-#define EL_LIGHT_SWITCH_OFF 297
-#define EL_LIGHT_SWITCH_ON 298
-#define EL_SIGN_EXCLAMATION 299
-#define EL_SIGN_RADIOACTIVITY 300
-#define EL_SIGN_STOP 301
-#define EL_SIGN_WHEELCHAIR 302
-#define EL_SIGN_PARKING 303
-#define EL_SIGN_ONEWAY 304
-#define EL_SIGN_HEART 305
-#define EL_SIGN_TRIANGLE 306
-#define EL_SIGN_ROUND 307
-#define EL_SIGN_EXIT 308
-#define EL_SIGN_YINYANG 309
-#define EL_SIGN_OTHER 310
-#define EL_MOLE_LEFT 311
-#define EL_MOLE_RIGHT 312
-#define EL_MOLE_UP 313
-#define EL_MOLE_DOWN 314
-#define EL_STEEL_SLANTED 315
-#define EL_SAND_INVISIBLE 316
-#define EL_DX_UNKNOWN_15 317
-#define EL_DX_UNKNOWN_42 318
-
-#define EL_UNUSED_319 319
-#define EL_UNUSED_320 320
-
-#define EL_SHIELD_ACTIVE 321
-#define EL_TIMEGATE_OPEN 322
-#define EL_TIMEGATE_CLOSED 323
-#define EL_TIMEGATE_SWITCH_ON 324
-#define EL_TIMEGATE_SWITCH_OFF 325
-
-#define EL_BALLOON 326
-#define EL_BALLOON_SEND_LEFT 327
-#define EL_BALLOON_SEND_RIGHT 328
-#define EL_BALLOON_SEND_UP 329
-#define EL_BALLOON_SEND_DOWN 330
-#define EL_BALLOON_SEND_ANY 331
-
-#define EL_EMC_STEEL_WALL_1 332
-#define EL_EMC_STEEL_WALL_2 333
-#define EL_EMC_STEEL_WALL_3 334
-#define EL_EMC_STEEL_WALL_4 335
-#define EL_EMC_WALL_1 336
-#define EL_EMC_WALL_2 337
-#define EL_EMC_WALL_3 338
-#define EL_EMC_WALL_4 339
-#define EL_EMC_WALL_5 340
-#define EL_EMC_WALL_6 341
-#define EL_EMC_WALL_7 342
-#define EL_EMC_WALL_8 343
-
-#define EL_TUBE_CROSS 344
-#define EL_TUBE_VERTICAL 345
-#define EL_TUBE_HORIZONTAL 346
-#define EL_TUBE_VERT_LEFT 347
-#define EL_TUBE_VERT_RIGHT 348
-#define EL_TUBE_HORIZ_UP 349
-#define EL_TUBE_HORIZ_DOWN 350
-#define EL_TUBE_LEFT_UP 351
-#define EL_TUBE_LEFT_DOWN 352
-#define EL_TUBE_RIGHT_UP 353
-#define EL_TUBE_RIGHT_DOWN 354
-#define EL_SPRING 355
-#define EL_TRAP_INACTIVE 356
-#define EL_DX_SUPABOMB 357
-
-#define NUM_LEVEL_ELEMENTS 358
+ short target_element; /* target element after change */
+ int delay_fixed; /* added frame delay before changed (fixed) */
+ int delay_random; /* added frame delay before changed (random) */
+ int delay_frames; /* either 1 (frames) or 50 (seconds; 50 fps) */
-/* "real" (and therefore drawable) runtime elements */
-#define EL_FIRST_RUNTIME_EL 500
-
-#define EL_MAGIC_WALL_EMPTY 500
-#define EL_MAGIC_WALL_BD_EMPTY 501
-#define EL_MAGIC_WALL_FULL 502
-#define EL_MAGIC_WALL_BD_FULL 503
-#define EL_MAGIC_WALL_DEAD 504
-#define EL_MAGIC_WALL_BD_DEAD 505
-#define EL_AUSGANG_ACT 506
-#define EL_SP_TERMINAL_ACTIVE 507
-#define EL_SP_BUG_ACTIVE 508
-#define EL_EM_KEY_1 509
-#define EL_EM_KEY_2 510
-#define EL_EM_KEY_3 511
-#define EL_EM_KEY_4 512
-#define EL_DYNABOMB_ACTIVE_1 513
-#define EL_DYNABOMB_ACTIVE_2 514
-#define EL_DYNABOMB_ACTIVE_3 515
-#define EL_DYNABOMB_ACTIVE_4 516
-#define EL_SWITCHGATE_OPENING 517
-#define EL_SWITCHGATE_CLOSING 518
-#define EL_TIMEGATE_OPENING 519
-#define EL_TIMEGATE_CLOSING 520
-#define EL_PEARL_BREAKING 521
-#define EL_TRAP_ACTIVE 522
-#define EL_SPRING_MOVING 523
-#define EL_SP_MURPHY_CLONE 524
-#define EL_QUICKSAND_EMPTYING 525
-#define EL_MAGIC_WALL_EMPTYING 526
-#define EL_MAGIC_WALL_BD_EMPTYING 527
-#define EL_AMOEBA_DRIPPING 528
+ short trigger_element; /* custom element triggering change */
-/* "unreal" (and therefore not drawable) runtime elements */
-#define EL_BLOCKED 600
-#define EL_EXPLODING 601
-#define EL_CRACKINGNUT 602
-#define EL_BLURB_LEFT 603
-#define EL_BLURB_RIGHT 604
-#define EL_AMOEBING 605
-#define EL_DEAMOEBING 606
-#define EL_MAUERND 607
-#define EL_BURNING 608
-#define EL_PLAYER_IS_LEAVING 609
-#define EL_QUICKSAND_FILLING 610
-#define EL_MAGIC_WALL_FILLING 611
-#define EL_MAGIC_WALL_BD_FILLING 612
-
-/* game graphics:
-** 0 - 255: graphics from "RocksScreen"
-** 256 - 511: graphics from "RocksFont"
-** 512 - 767: graphics from "RocksHeroes"
-** 768 - 1023: graphics from "RocksSP"
-** 1024 - 1279: graphics from "RocksDC"
-** 1280 - 1535: graphics from "RocksMore"
-*/
+ int content[3][3]; /* new elements after extended change */
+ boolean use_content; /* use extended change content */
+ boolean only_complete; /* only use complete content */
+ boolean use_random_change; /* use random value for setting content */
+ int random; /* random value for setting content */
+ int power; /* power of extended change */
-#define GFX_START_ROCKSSCREEN 0
-#define GFX_END_ROCKSSCREEN 255
-#define GFX_START_ROCKSFONT 256
-#define GFX_END_ROCKSFONT 511
-#define GFX_START_ROCKSHEROES 512
-#define GFX_END_ROCKSHEROES 767
-#define GFX_START_ROCKSSP 768
-#define GFX_END_ROCKSSP 1023
-#define GFX_START_ROCKSDC 1024
-#define GFX_END_ROCKSDC 1279
-#define GFX_START_ROCKSMORE 1280
-#define GFX_END_ROCKSMORE 1535
-
-#define NUM_TILES 1536
-
-/* graphics from "RocksScreen" */
-/* Zeile 0 (0) */
-#define GFX_LEERRAUM (-1)
-#define GFX_ERDREICH 0
-#define GFX_ERDENRAND 1
-#define GFX_MORAST_LEER 2
-#define GFX_MORAST_VOLL 3
-#define GFX_BETON 4
-#define GFX_MAUERWERK 5
-#define GFX_FELSBODEN 6
-#define GFX_EDELSTEIN 8
-#define GFX_DIAMANT 10
-#define GFX_FELSBROCKEN 12
-/* Zeile 1 (16) */
-#define GFX_BADEWANNE1 16
-#define GFX_SALZSAEURE 17
-#define GFX_BADEWANNE2 18
-
-/*
-#define GFX_UNSICHTBAR 19
-*/
+ boolean explode; /* explode instead of change */
-#define GFX_SCHLUESSEL1 20
-#define GFX_SCHLUESSEL2 21
-#define GFX_SCHLUESSEL3 22
-#define GFX_SCHLUESSEL4 23
-#define GFX_LIFE 24
-#define GFX_LIFE_ASYNC 25
-#define GFX_BADEWANNE 26
-#define GFX_BOMBE 27
-#define GFX_KOKOSNUSS 28
-#define GFX_CRACKINGNUT 29
-/* Zeile 2 (32) */
-#define GFX_BADEWANNE3 32
-#define GFX_BADEWANNE4 33
-#define GFX_BADEWANNE5 34
-#define GFX_SMILEY 35
-#define GFX_PFORTE1 36
-#define GFX_PFORTE2 37
-#define GFX_PFORTE3 38
-#define GFX_PFORTE4 39
-#define GFX_PFORTE1X 40
-#define GFX_PFORTE2X 41
-#define GFX_PFORTE3X 42
-#define GFX_PFORTE4X 43
-/* Zeile 3 (48) */
-#define GFX_DYNAMIT_AUS 48
-#define GFX_DYNAMIT 49
-#define GFX_FLIEGER 56
-#define GFX_FLIEGER_RIGHT 56
-#define GFX_FLIEGER_UP 57
-#define GFX_FLIEGER_LEFT 58
-#define GFX_FLIEGER_DOWN 59
-/* Zeile 4 (64) */
-#define GFX_EXPLOSION 64
-#define GFX_KAEFER 72
-#define GFX_KAEFER_RIGHT 72
-#define GFX_KAEFER_UP 73
-#define GFX_KAEFER_LEFT 74
-#define GFX_KAEFER_DOWN 75
-/* Zeile 5 (80) */
-#define GFX_MAMPFER 80
-#define GFX_ROBOT 84
-#define GFX_PACMAN 88
-#define GFX_PACMAN_RIGHT 88
-#define GFX_PACMAN_UP 89
-#define GFX_PACMAN_LEFT 90
-#define GFX_PACMAN_DOWN 91
-/* Zeile 6 (96) */
-#define GFX_ABLENK 96
-#define GFX_ABLENK_EIN GFX_ABLENK
-#define GFX_ABLENK_AUS GFX_ABLENK
-#define GFX_AMOEBE_NASS 100
-#define GFX_TROPFEN 101
-#define GFX_AMOEBING GFX_TROPFEN
-#define GFX_AMOEBE_LEBT 104
-#define GFX_AMOEBE_NORM GFX_AMOEBE_LEBT
-#define GFX_AMOEBE_TOT 108
-#define GFX_AMOEBA2DIAM GFX_AMOEBE_TOT
-/* Zeile 7 (112) */
-#define GFX_BIRNE_AUS 112
-#define GFX_BIRNE_EIN 113
-#define GFX_ZEIT_VOLL 114
-#define GFX_ZEIT_LEER 115
-#define GFX_SPIELER1 116
-#define GFX_SPIELER2 117
-#define GFX_SPIELER3 118
-#define GFX_SPIELER4 119
-#define GFX_AMOEBE_VOLL 120
-#define GFX_AMOEBE_BD GFX_AMOEBE_VOLL
-#define GFX_SOKOBAN_OBJEKT 121
-#define GFX_SOKOBAN_FELD_LEER 122
-#define GFX_SOKOBAN_FELD_VOLL 123
-#define GFX_GEBLUBBER 124
-/* Zeile 8 (128) */
-#define GFX_MAGIC_WALL_OFF 128
-#define GFX_MAGIC_WALL_EMPTY GFX_MAGIC_WALL_OFF
-#define GFX_MAGIC_WALL_FULL GFX_MAGIC_WALL_OFF
-#define GFX_MAGIC_WALL_DEAD GFX_MAGIC_WALL_OFF
-#define GFX_ERZ_EDEL 132
-#define GFX_ERZ_DIAM 133
-#define GFX_ERZ_EDEL_ROT 134
-#define GFX_ERZ_EDEL_LILA 135
-#define GFX_ERZ_EDEL_GELB 136
-#define GFX_ERZ_EDEL_BD 137
-#define GFX_EDELSTEIN_GELB 138
-#define GFX_KUGEL_ROT 140
-#define GFX_KUGEL_BLAU 141
-#define GFX_KUGEL_GELB 142
-#define GFX_KUGEL_GRAU 143
-/* Zeile 9 (144) */
-#define GFX_PINGUIN 144
-#define GFX_MOLE 145
-#define GFX_SCHWEIN 146
-#define GFX_DRACHE 147
-#define GFX_MAUER_XY 148
-#define GFX_MAUER_X 149
-#define GFX_MAUER_Y 150
-#define GFX_EDELSTEIN_ROT 152
-#define GFX_EDELSTEIN_LILA 154
-#define GFX_DYNABOMB_XL 156
-#define GFX_BLACK_ORB 157
-#define GFX_SPEED_PILL 158
-#define GFX_SONDE 159
-/* Zeile 10 (160) */
-#define GFX_EDELSTEIN_BD 163
-#define GFX_MAUER_RIGHT 165
-#define GFX_MAUER_R1 GFX_MAUER_RIGHT
-#define GFX_MAUER_R 167
-#define GFX_MAUER_LEFT 168
-#define GFX_MAUER_L1 GFX_MAUER_LEFT
-#define GFX_MAUER_L 170
-#define GFX_MAUER_LEBT 171
-#define GFX_MAGIC_WALL_BD_OFF 172
-#define GFX_MAGIC_WALL_BD_EMPTY GFX_MAGIC_WALL_BD_OFF
-#define GFX_MAGIC_WALL_BD_FULL GFX_MAGIC_WALL_BD_OFF
-#define GFX_MAGIC_WALL_BD_DEAD GFX_MAGIC_WALL_BD_OFF
-/* Zeile 11 (176) */
-#define GFX_AUSGANG_ZU 176
-#define GFX_AUSGANG_ACT 177
-#define GFX_AUSGANG_AUF 180
-#define GFX_MAMPFER2 184
-#define GFX_DYNABOMB 188
-#define GFX_DYNABOMB_NR 188
-#define GFX_DYNABOMB_SZ 191
-/* Zeile 12 (192) */
-#define GFX_PFEIL_LEFT 192
-#define GFX_PFEIL_RIGHT 193
-#define GFX_PFEIL_UP 194
-#define GFX_PFEIL_DOWN 195
-#define GFX_BUTTERFLY 196
-#define GFX_FIREFLY 198
-#define GFX_BUTTERFLY_RIGHT 200
-#define GFX_BUTTERFLY_UP 201
-#define GFX_BUTTERFLY_LEFT 202
-#define GFX_BUTTERFLY_DOWN 203
-#define GFX_FIREFLY_RIGHT 204
-#define GFX_FIREFLY_UP 205
-#define GFX_FIREFLY_LEFT 206
-#define GFX_FIREFLY_DOWN 207
-
-/* only available as size MINI_TILE */
-#define GFX_VSTEEL_UPPER_LEFT 208
-#define GFX_VSTEEL_UPPER_RIGHT 209
-#define GFX_VSTEEL_LOWER_LEFT 210
-#define GFX_VSTEEL_LOWER_RIGHT 211
-#define GFX_VSTEEL_HORIZONTAL 212
-#define GFX_VSTEEL_VERTICAL 213
-#define GFX_ISTEEL_UPPER_LEFT 214
-#define GFX_ISTEEL_UPPER_RIGHT 215
-#define GFX_ISTEEL_LOWER_LEFT 216
-#define GFX_ISTEEL_LOWER_RIGHT 217
-#define GFX_ISTEEL_HORIZONTAL 218
-#define GFX_ISTEEL_VERTICAL 219
-
-/* elements with graphics borrowed from other elements */
-#define GFX_SCHLUESSEL GFX_SCHLUESSEL1
-#define GFX_SPIELFIGUR GFX_SPIELER1
-
-/* graphics from "RocksHeroes" */
-#define GFX_SPIELER1_DOWN (GFX_START_ROCKSHEROES + 0*HEROES_PER_LINE + 0)
-#define GFX_SPIELER1_UP (GFX_START_ROCKSHEROES + 0*HEROES_PER_LINE + 4)
-#define GFX_SPIELER1_LEFT (GFX_START_ROCKSHEROES + 1*HEROES_PER_LINE + 0)
-#define GFX_SPIELER1_RIGHT (GFX_START_ROCKSHEROES + 1*HEROES_PER_LINE + 4)
-#define GFX_SPIELER1_PUSH_RIGHT (GFX_START_ROCKSHEROES + 2*HEROES_PER_LINE + 0)
-#define GFX_SPIELER1_PUSH_LEFT (GFX_START_ROCKSHEROES + 2*HEROES_PER_LINE + 4)
-#define GFX_SPIELER2_DOWN (GFX_START_ROCKSHEROES + 3*HEROES_PER_LINE + 0)
-#define GFX_SPIELER2_UP (GFX_START_ROCKSHEROES + 3*HEROES_PER_LINE + 4)
-#define GFX_SPIELER2_LEFT (GFX_START_ROCKSHEROES + 4*HEROES_PER_LINE + 0)
-#define GFX_SPIELER2_RIGHT (GFX_START_ROCKSHEROES + 4*HEROES_PER_LINE + 4)
-#define GFX_SPIELER2_PUSH_RIGHT (GFX_START_ROCKSHEROES + 5*HEROES_PER_LINE + 0)
-#define GFX_SPIELER2_PUSH_LEFT (GFX_START_ROCKSHEROES + 5*HEROES_PER_LINE + 4)
-#define GFX_SPIELER3_DOWN (GFX_START_ROCKSHEROES + 6*HEROES_PER_LINE + 0)
-#define GFX_SPIELER3_UP (GFX_START_ROCKSHEROES + 6*HEROES_PER_LINE + 4)
-#define GFX_SPIELER3_LEFT (GFX_START_ROCKSHEROES + 7*HEROES_PER_LINE + 0)
-#define GFX_SPIELER3_RIGHT (GFX_START_ROCKSHEROES + 7*HEROES_PER_LINE + 4)
-#define GFX_SPIELER3_PUSH_RIGHT (GFX_START_ROCKSHEROES + 8*HEROES_PER_LINE + 0)
-#define GFX_SPIELER3_PUSH_LEFT (GFX_START_ROCKSHEROES + 8*HEROES_PER_LINE + 4)
-#define GFX_SPIELER4_DOWN (GFX_START_ROCKSHEROES + 9*HEROES_PER_LINE + 0)
-#define GFX_SPIELER4_UP (GFX_START_ROCKSHEROES + 9*HEROES_PER_LINE + 4)
-#define GFX_SPIELER4_LEFT (GFX_START_ROCKSHEROES +10*HEROES_PER_LINE + 0)
-#define GFX_SPIELER4_RIGHT (GFX_START_ROCKSHEROES +10*HEROES_PER_LINE + 4)
-#define GFX_SPIELER4_PUSH_RIGHT (GFX_START_ROCKSHEROES +11*HEROES_PER_LINE + 0)
-#define GFX_SPIELER4_PUSH_LEFT (GFX_START_ROCKSHEROES +11*HEROES_PER_LINE + 4)
-#define GFX_MAUER_DOWN (GFX_START_ROCKSHEROES +12*HEROES_PER_LINE + 0)
-#define GFX_MAUER_UP (GFX_START_ROCKSHEROES +12*HEROES_PER_LINE + 3)
-#define GFX2_SHIELD_PASSIVE (GFX_START_ROCKSHEROES +13*HEROES_PER_LINE + 1)
-#define GFX2_SHIELD_ACTIVE (GFX_START_ROCKSHEROES +13*HEROES_PER_LINE + 5)
-
-#define GFX_SONDE_START (GFX_START_ROCKSHEROES + 9*HEROES_PER_LINE + 8)
-#define GFX_SCHWEIN_DOWN (GFX_START_ROCKSHEROES + 0*HEROES_PER_LINE + 8)
-#define GFX_SCHWEIN_UP (GFX_START_ROCKSHEROES + 0*HEROES_PER_LINE +12)
-#define GFX_SCHWEIN_LEFT (GFX_START_ROCKSHEROES + 1*HEROES_PER_LINE + 8)
-#define GFX_SCHWEIN_RIGHT (GFX_START_ROCKSHEROES + 1*HEROES_PER_LINE +12)
-#define GFX_DRACHE_DOWN (GFX_START_ROCKSHEROES + 2*HEROES_PER_LINE + 8)
-#define GFX_DRACHE_UP (GFX_START_ROCKSHEROES + 2*HEROES_PER_LINE +12)
-#define GFX_DRACHE_LEFT (GFX_START_ROCKSHEROES + 3*HEROES_PER_LINE + 8)
-#define GFX_DRACHE_RIGHT (GFX_START_ROCKSHEROES + 3*HEROES_PER_LINE +12)
-/*
-#define GFX_MOLE_DOWN (GFX_START_ROCKSHEROES + 4*HEROES_PER_LINE + 8)
-#define GFX_MOLE_UP (GFX_START_ROCKSHEROES + 4*HEROES_PER_LINE +12)
-#define GFX_MOLE_LEFT (GFX_START_ROCKSHEROES + 5*HEROES_PER_LINE + 8)
-#define GFX_MOLE_RIGHT (GFX_START_ROCKSHEROES + 5*HEROES_PER_LINE +12)
-*/
-#define GFX_PINGUIN_DOWN (GFX_START_ROCKSHEROES + 6*HEROES_PER_LINE + 8)
-#define GFX_PINGUIN_UP (GFX_START_ROCKSHEROES + 6*HEROES_PER_LINE +12)
-#define GFX_PINGUIN_LEFT (GFX_START_ROCKSHEROES + 7*HEROES_PER_LINE + 8)
-#define GFX_PINGUIN_RIGHT (GFX_START_ROCKSHEROES + 7*HEROES_PER_LINE +12)
-#define GFX_BLURB_LEFT (GFX_START_ROCKSHEROES +10*HEROES_PER_LINE + 8)
-#define GFX_BLURB_RIGHT (GFX_START_ROCKSHEROES +10*HEROES_PER_LINE +12)
-#define GFX_FUNKELN_BLAU (GFX_START_ROCKSHEROES +11*HEROES_PER_LINE + 9)
-#define GFX_FUNKELN_WEISS (GFX_START_ROCKSHEROES +11*HEROES_PER_LINE +13)
-#define GFX_FLAMMEN_LEFT (GFX_START_ROCKSHEROES +12*HEROES_PER_LINE + 8)
-#define GFX_FLAMMEN_RIGHT (GFX_START_ROCKSHEROES +13*HEROES_PER_LINE + 8)
-#define GFX_FLAMMEN_UP (GFX_START_ROCKSHEROES +14*HEROES_PER_LINE + 8)
-#define GFX_FLAMMEN_DOWN (GFX_START_ROCKSHEROES +15*HEROES_PER_LINE + 8)
-
-/* graphics from "RocksSP" */
-#define GFX_SP_EMPTY (GFX_START_ROCKSSP + 0 * SP_PER_LINE + 0)
-/*
-#define GFX_SP_ZONK (GFX_START_ROCKSSP + 0 * SP_PER_LINE + 1)
-*/
-#define GFX_SP_BASE (GFX_START_ROCKSSP + 0 * SP_PER_LINE + 2)
-#define GFX_SP_MURPHY (GFX_START_ROCKSSP + 0 * SP_PER_LINE + 3)
-#define GFX_SP_INFOTRON (GFX_START_ROCKSSP + 0 * SP_PER_LINE + 4)
-#define GFX_SP_CHIP_SINGLE (GFX_START_ROCKSSP + 0 * SP_PER_LINE + 5)
-#define GFX_SP_HARD_GRAY (GFX_START_ROCKSSP + 0 * SP_PER_LINE + 6)
-#define GFX_SP_EXIT (GFX_START_ROCKSSP + 0 * SP_PER_LINE + 7)
-#define GFX_SP_DISK_ORANGE (GFX_START_ROCKSSP + 1 * SP_PER_LINE + 0)
-#define GFX_SP_PORT1_RIGHT (GFX_START_ROCKSSP + 1 * SP_PER_LINE + 1)
-#define GFX_SP_PORT1_DOWN (GFX_START_ROCKSSP + 1 * SP_PER_LINE + 2)
-#define GFX_SP_PORT1_LEFT (GFX_START_ROCKSSP + 1 * SP_PER_LINE + 3)
-#define GFX_SP_PORT1_UP (GFX_START_ROCKSSP + 1 * SP_PER_LINE + 4)
-#define GFX_SP_PORT2_RIGHT (GFX_START_ROCKSSP + 1 * SP_PER_LINE + 5)
-#define GFX_SP_PORT2_DOWN (GFX_START_ROCKSSP + 1 * SP_PER_LINE + 6)
-#define GFX_SP_PORT2_LEFT (GFX_START_ROCKSSP + 1 * SP_PER_LINE + 7)
-#define GFX_SP_PORT2_UP (GFX_START_ROCKSSP + 2 * SP_PER_LINE + 0)
-#define GFX_SP_SNIKSNAK (GFX_START_ROCKSSP + 2 * SP_PER_LINE + 1)
-#define GFX_SP_DISK_YELLOW (GFX_START_ROCKSSP + 2 * SP_PER_LINE + 2)
-#define GFX_SP_TERMINAL (GFX_START_ROCKSSP + 2 * SP_PER_LINE + 3)
-#define GFX_SP_DISK_RED (GFX_START_ROCKSSP + 2 * SP_PER_LINE + 4)
-#define GFX_SP_PORT_Y (GFX_START_ROCKSSP + 2 * SP_PER_LINE + 5)
-#define GFX_SP_PORT_X (GFX_START_ROCKSSP + 2 * SP_PER_LINE + 6)
-#define GFX_SP_PORT_XY (GFX_START_ROCKSSP + 2 * SP_PER_LINE + 7)
-#define GFX_SP_ELECTRON (GFX_START_ROCKSSP + 3 * SP_PER_LINE + 0)
-#define GFX_SP_BUG (GFX_START_ROCKSSP + 3 * SP_PER_LINE + 1)
-#define GFX_SP_CHIP_LEFT (GFX_START_ROCKSSP + 3 * SP_PER_LINE + 2)
-#define GFX_SP_CHIP_RIGHT (GFX_START_ROCKSSP + 3 * SP_PER_LINE + 3)
-#define GFX_SP_HARD_BASE1 (GFX_START_ROCKSSP + 3 * SP_PER_LINE + 4)
-#define GFX_SP_HARD_GREEN (GFX_START_ROCKSSP + 3 * SP_PER_LINE + 5)
-#define GFX_SP_HARD_BLUE (GFX_START_ROCKSSP + 3 * SP_PER_LINE + 6)
-#define GFX_SP_HARD_RED (GFX_START_ROCKSSP + 3 * SP_PER_LINE + 7)
-#define GFX_SP_HARD_YELLOW (GFX_START_ROCKSSP + 4 * SP_PER_LINE + 0)
-#define GFX_SP_HARD_BASE2 (GFX_START_ROCKSSP + 4 * SP_PER_LINE + 1)
-#define GFX_SP_HARD_BASE3 (GFX_START_ROCKSSP + 4 * SP_PER_LINE + 2)
-#define GFX_SP_HARD_BASE4 (GFX_START_ROCKSSP + 4 * SP_PER_LINE + 3)
-#define GFX_SP_HARD_BASE5 (GFX_START_ROCKSSP + 4 * SP_PER_LINE + 4)
-#define GFX_SP_HARD_BASE6 (GFX_START_ROCKSSP + 4 * SP_PER_LINE + 5)
-#define GFX_SP_CHIP_UPPER (GFX_START_ROCKSSP + 4 * SP_PER_LINE + 6)
-#define GFX_SP_CHIP_LOWER (GFX_START_ROCKSSP + 4 * SP_PER_LINE + 7)
-
-#define GFX_INVISIBLE_STEEL_ON (GFX_START_ROCKSSP + 5 * SP_PER_LINE + 1)
-#define GFX_SAND_INVISIBLE_ON (GFX_START_ROCKSSP + 5 * SP_PER_LINE + 2)
-#define GFX_INVISIBLE_STEEL (GFX_START_ROCKSSP + 5 * SP_PER_LINE + 3)
-#define GFX_UNSICHTBAR_ON (GFX_START_ROCKSSP + 5 * SP_PER_LINE + 5)
-#define GFX_SAND_INVISIBLE (GFX_START_ROCKSSP + 5 * SP_PER_LINE + 6)
-#define GFX_UNSICHTBAR (GFX_START_ROCKSSP + 5 * SP_PER_LINE + 7)
-
-#define GFX_SP_ZONK (GFX_START_ROCKSSP + 6 * SP_PER_LINE + 0)
-
-#define GFX_EM_KEY_1 (GFX_START_ROCKSSP + 6 * SP_PER_LINE + 4)
-#define GFX_EM_KEY_2 (GFX_START_ROCKSSP + 6 * SP_PER_LINE + 5)
-#define GFX_EM_KEY_3 (GFX_START_ROCKSSP + 6 * SP_PER_LINE + 6)
-#define GFX_EM_KEY_4 (GFX_START_ROCKSSP + 6 * SP_PER_LINE + 7)
-#define GFX_EM_GATE_1 (GFX_START_ROCKSSP + 7 * SP_PER_LINE + 0)
-#define GFX_EM_GATE_2 (GFX_START_ROCKSSP + 7 * SP_PER_LINE + 1)
-#define GFX_EM_GATE_3 (GFX_START_ROCKSSP + 7 * SP_PER_LINE + 2)
-#define GFX_EM_GATE_4 (GFX_START_ROCKSSP + 7 * SP_PER_LINE + 3)
-#define GFX_EM_GATE_1X (GFX_START_ROCKSSP + 7 * SP_PER_LINE + 4)
-#define GFX_EM_GATE_2X (GFX_START_ROCKSSP + 7 * SP_PER_LINE + 5)
-#define GFX_EM_GATE_3X (GFX_START_ROCKSSP + 7 * SP_PER_LINE + 6)
-#define GFX_EM_GATE_4X (GFX_START_ROCKSSP + 7 * SP_PER_LINE + 7)
-
-#define GFX_MURPHY_GO_LEFT (GFX_START_ROCKSSP + 0 * SP_PER_LINE + 8)
-#define GFX_MURPHY_ANY_LEFT (GFX_START_ROCKSSP + 0 * SP_PER_LINE + 9)
-#define GFX_MURPHY_GO_RIGHT (GFX_START_ROCKSSP + 0 * SP_PER_LINE + 11)
-#define GFX_MURPHY_ANY_RIGHT (GFX_START_ROCKSSP + 0 * SP_PER_LINE + 12)
-#define GFX_MURPHY_SNAP_UP (GFX_START_ROCKSSP + 0 * SP_PER_LINE + 14)
-#define GFX_MURPHY_SNAP_DOWN (GFX_START_ROCKSSP + 0 * SP_PER_LINE + 15)
-#define GFX_MURPHY_SNAP_RIGHT (GFX_START_ROCKSSP + 1 * SP_PER_LINE + 8)
-#define GFX_MURPHY_SNAP_LEFT (GFX_START_ROCKSSP + 1 * SP_PER_LINE + 9)
-#define GFX_MURPHY_PUSH_RIGHT (GFX_START_ROCKSSP + 1 * SP_PER_LINE + 10)
-#define GFX_MURPHY_PUSH_LEFT (GFX_START_ROCKSSP + 1 * SP_PER_LINE + 11)
-
-#define GFX_SP_BUG_WARNING (GFX_START_ROCKSSP + 2 * SP_PER_LINE + 15)
-#define GFX_SP_EXPLODE_EMPTY (GFX_START_ROCKSSP + 3 * SP_PER_LINE + 8)
-#define GFX_SP_EXPLODE_INFOTRON (GFX_START_ROCKSSP + 4 * SP_PER_LINE + 8)
-#define GFX_SP_BUG_ACTIVE (GFX_START_ROCKSSP + 6 * SP_PER_LINE + 8)
-#define GFX_SP_SNIKSNAK_LEFT (GFX_START_ROCKSSP + 8 * SP_PER_LINE + 8)
-#define GFX_SP_SNIKSNAK_RIGHT (GFX_START_ROCKSSP + 8 * SP_PER_LINE + 12)
-#define GFX_SP_SNIKSNAK_UP (GFX_START_ROCKSSP + 9 * SP_PER_LINE + 8)
-#define GFX_SP_SNIKSNAK_DOWN (GFX_START_ROCKSSP + 9 * SP_PER_LINE + 12)
-
-#define GFX2_SP_ELECTRON (GFX_START_ROCKSSP + 10 * SP_PER_LINE + 8)
-#define GFX2_SP_TERMINAL (GFX_START_ROCKSSP + 11 * SP_PER_LINE + 8)
-#define GFX2_SP_TERMINAL_ACTIVE (GFX_START_ROCKSSP + 12 * SP_PER_LINE + 8)
-
-#define GFX_SP_MURPHY_CLONE (GFX_START_ROCKSSP + 0 * SP_PER_LINE + 3)
-
-/* graphics from "RocksDC" */
-#define GFX_BELT1_MIDDLE (GFX_START_ROCKSDC + 0 * DC_PER_LINE + 0)
-#define GFX_BELT1_LEFT (GFX_START_ROCKSDC + 1 * DC_PER_LINE + 0)
-#define GFX_BELT1_RIGHT (GFX_START_ROCKSDC + 2 * DC_PER_LINE + 0)
-#define GFX_BELT2_MIDDLE (GFX_START_ROCKSDC + 3 * DC_PER_LINE + 0)
-#define GFX_BELT2_LEFT (GFX_START_ROCKSDC + 4 * DC_PER_LINE + 0)
-#define GFX_BELT2_RIGHT (GFX_START_ROCKSDC + 5 * DC_PER_LINE + 0)
-#define GFX_BELT3_MIDDLE (GFX_START_ROCKSDC + 6 * DC_PER_LINE + 0)
-#define GFX_BELT3_LEFT (GFX_START_ROCKSDC + 7 * DC_PER_LINE + 0)
-#define GFX_BELT3_RIGHT (GFX_START_ROCKSDC + 8 * DC_PER_LINE + 0)
-#define GFX_BELT4_MIDDLE (GFX_START_ROCKSDC + 9 * DC_PER_LINE + 0)
-#define GFX_BELT4_LEFT (GFX_START_ROCKSDC + 10 * DC_PER_LINE + 0)
-#define GFX_BELT4_RIGHT (GFX_START_ROCKSDC + 11 * DC_PER_LINE + 0)
-#define GFX_BELT1_SWITCH_LEFT (GFX_START_ROCKSDC + 12 * DC_PER_LINE + 0)
-#define GFX_BELT2_SWITCH_LEFT (GFX_START_ROCKSDC + 12 * DC_PER_LINE + 1)
-#define GFX_BELT3_SWITCH_LEFT (GFX_START_ROCKSDC + 12 * DC_PER_LINE + 2)
-#define GFX_BELT4_SWITCH_LEFT (GFX_START_ROCKSDC + 12 * DC_PER_LINE + 3)
-#define GFX_BELT1_SWITCH_MIDDLE (GFX_START_ROCKSDC + 13 * DC_PER_LINE + 0)
-#define GFX_BELT2_SWITCH_MIDDLE (GFX_START_ROCKSDC + 13 * DC_PER_LINE + 1)
-#define GFX_BELT3_SWITCH_MIDDLE (GFX_START_ROCKSDC + 13 * DC_PER_LINE + 2)
-#define GFX_BELT4_SWITCH_MIDDLE (GFX_START_ROCKSDC + 13 * DC_PER_LINE + 3)
-#define GFX_BELT1_SWITCH_RIGHT (GFX_START_ROCKSDC + 14 * DC_PER_LINE + 0)
-#define GFX_BELT2_SWITCH_RIGHT (GFX_START_ROCKSDC + 14 * DC_PER_LINE + 1)
-#define GFX_BELT3_SWITCH_RIGHT (GFX_START_ROCKSDC + 14 * DC_PER_LINE + 2)
-#define GFX_BELT4_SWITCH_RIGHT (GFX_START_ROCKSDC + 14 * DC_PER_LINE + 3)
-
-#define GFX_SWITCHGATE_SWITCH_1 (GFX_START_ROCKSDC + 12 * DC_PER_LINE + 4)
-#define GFX_SWITCHGATE_SWITCH_2 (GFX_START_ROCKSDC + 12 * DC_PER_LINE + 5)
-#define GFX_LIGHT_SWITCH_OFF (GFX_START_ROCKSDC + 12 * DC_PER_LINE + 6)
-#define GFX_LIGHT_SWITCH_ON (GFX_START_ROCKSDC + 12 * DC_PER_LINE + 7)
-#define GFX_TIMEGATE_SWITCH (GFX_START_ROCKSDC + 15 * DC_PER_LINE + 0)
-
-#define GFX_ENVELOPE (GFX_START_ROCKSDC + 14 * DC_PER_LINE + 4)
-#define GFX_SIGN_EXCLAMATION (GFX_START_ROCKSDC + 14 * DC_PER_LINE + 5)
-#define GFX_SIGN_STOP (GFX_START_ROCKSDC + 14 * DC_PER_LINE + 6)
-#define GFX_LANDMINE (GFX_START_ROCKSDC + 14 * DC_PER_LINE + 7)
-#define GFX_STEEL_SLANTED (GFX_START_ROCKSDC + 15 * DC_PER_LINE + 5)
-
-#define GFX_EXTRA_TIME (GFX_START_ROCKSDC + 0 * DC_PER_LINE + 8)
-#define GFX_SHIELD_ACTIVE (GFX_START_ROCKSDC + 1 * DC_PER_LINE + 8)
-#define GFX_SHIELD_PASSIVE (GFX_START_ROCKSDC + 2 * DC_PER_LINE + 8)
-#define GFX_MOLE_DOWN (GFX_START_ROCKSDC + 3 * DC_PER_LINE + 8)
-#define GFX_MOLE_UP (GFX_START_ROCKSDC + 3 * DC_PER_LINE + 12)
-#define GFX_MOLE_LEFT (GFX_START_ROCKSDC + 4 * DC_PER_LINE + 8)
-#define GFX_MOLE_RIGHT (GFX_START_ROCKSDC + 4 * DC_PER_LINE + 12)
-#define GFX_SWITCHGATE_CLOSED (GFX_START_ROCKSDC + 5 * DC_PER_LINE + 8)
-#define GFX_SWITCHGATE_OPEN (GFX_START_ROCKSDC + 5 * DC_PER_LINE + 12)
-#define GFX_TIMEGATE_CLOSED (GFX_START_ROCKSDC + 6 * DC_PER_LINE + 8)
-#define GFX_TIMEGATE_OPEN (GFX_START_ROCKSDC + 6 * DC_PER_LINE + 12)
-#define GFX_BALLOON_SEND_LEFT (GFX_START_ROCKSDC + 7 * DC_PER_LINE + 8)
-#define GFX_BALLOON_SEND_RIGHT (GFX_START_ROCKSDC + 7 * DC_PER_LINE + 9)
-#define GFX_BALLOON_SEND_UP (GFX_START_ROCKSDC + 7 * DC_PER_LINE + 10)
-#define GFX_BALLOON_SEND_DOWN (GFX_START_ROCKSDC + 7 * DC_PER_LINE + 11)
-#define GFX_BALLOON (GFX_START_ROCKSDC + 7 * DC_PER_LINE + 12)
-#define GFX_BALLOON_SEND_ANY (GFX_START_ROCKSDC + 0 * DC_PER_LINE + 15)
-
-#define GFX_EMC_STEEL_WALL_1 (GFX_START_ROCKSDC + 0 * DC_PER_LINE + 14)
-#define GFX_EMC_STEEL_WALL_2 (GFX_START_ROCKSDC + 0 * DC_PER_LINE + 14)
-#define GFX_EMC_STEEL_WALL_3 (GFX_START_ROCKSDC + 0 * DC_PER_LINE + 14)
-#define GFX_EMC_STEEL_WALL_4 (GFX_START_ROCKSDC + 0 * DC_PER_LINE + 14)
-#define GFX_EMC_WALL_1 (GFX_START_ROCKSDC + 6 * DC_PER_LINE + 13)
-#define GFX_EMC_WALL_2 (GFX_START_ROCKSDC + 6 * DC_PER_LINE + 14)
-#define GFX_EMC_WALL_3 (GFX_START_ROCKSDC + 6 * DC_PER_LINE + 15)
-#define GFX_EMC_WALL_4 (GFX_START_ROCKSDC + 1 * DC_PER_LINE + 14)
-#define GFX_EMC_WALL_5 (GFX_START_ROCKSDC + 1 * DC_PER_LINE + 15)
-#define GFX_EMC_WALL_6 (GFX_START_ROCKSDC + 2 * DC_PER_LINE + 14)
-#define GFX_EMC_WALL_7 (GFX_START_ROCKSDC + 2 * DC_PER_LINE + 15)
-#define GFX_EMC_WALL_8 (GFX_START_ROCKSDC + 1 * DC_PER_LINE + 14)
-
-/* graphics from "RocksMore" */
-#define GFX_ARROW_BLUE_LEFT (GFX_START_ROCKSMORE + 0 * MORE_PER_LINE + 0)
-#define GFX_ARROW_BLUE_RIGHT (GFX_START_ROCKSMORE + 0 * MORE_PER_LINE + 1)
-#define GFX_ARROW_BLUE_UP (GFX_START_ROCKSMORE + 0 * MORE_PER_LINE + 2)
-#define GFX_ARROW_BLUE_DOWN (GFX_START_ROCKSMORE + 0 * MORE_PER_LINE + 3)
-#define GFX_ARROW_RED_LEFT (GFX_START_ROCKSMORE + 1 * MORE_PER_LINE + 0)
-#define GFX_ARROW_RED_RIGHT (GFX_START_ROCKSMORE + 1 * MORE_PER_LINE + 1)
-#define GFX_ARROW_RED_UP (GFX_START_ROCKSMORE + 1 * MORE_PER_LINE + 2)
-#define GFX_ARROW_RED_DOWN (GFX_START_ROCKSMORE + 1 * MORE_PER_LINE + 3)
-#define GFX_SCROLLBAR_BLUE (GFX_START_ROCKSMORE + 2 * MORE_PER_LINE + 0)
-#define GFX_SCROLLBAR_RED (GFX_START_ROCKSMORE + 2 * MORE_PER_LINE + 1)
-#define GFX_PEARL (GFX_START_ROCKSMORE + 3 * MORE_PER_LINE + 0)
-#define GFX_CRYSTAL (GFX_START_ROCKSMORE + 3 * MORE_PER_LINE + 1)
-#define GFX_WALL_PEARL (GFX_START_ROCKSMORE + 3 * MORE_PER_LINE + 2)
-#define GFX_WALL_CRYSTAL (GFX_START_ROCKSMORE + 3 * MORE_PER_LINE + 3)
-#define GFX_PEARL_BREAKING (GFX_START_ROCKSMORE + 4 * MORE_PER_LINE + 0)
-#define GFX_SPRING (GFX_START_ROCKSMORE + 5 * MORE_PER_LINE + 0)
-#define GFX_TUBE_RIGHT_DOWN (GFX_START_ROCKSMORE + 5 * MORE_PER_LINE + 1)
-#define GFX_TUBE_HORIZ_DOWN (GFX_START_ROCKSMORE + 5 * MORE_PER_LINE + 2)
-#define GFX_TUBE_LEFT_DOWN (GFX_START_ROCKSMORE + 5 * MORE_PER_LINE + 3)
-#define GFX_TUBE_HORIZONTAL (GFX_START_ROCKSMORE + 6 * MORE_PER_LINE + 0)
-#define GFX_TUBE_VERT_RIGHT (GFX_START_ROCKSMORE + 6 * MORE_PER_LINE + 1)
-#define GFX_TUBE_CROSS (GFX_START_ROCKSMORE + 6 * MORE_PER_LINE + 2)
-#define GFX_TUBE_VERT_LEFT (GFX_START_ROCKSMORE + 6 * MORE_PER_LINE + 3)
-#define GFX_TUBE_VERTICAL (GFX_START_ROCKSMORE + 7 * MORE_PER_LINE + 0)
-#define GFX_TUBE_RIGHT_UP (GFX_START_ROCKSMORE + 7 * MORE_PER_LINE + 1)
-#define GFX_TUBE_HORIZ_UP (GFX_START_ROCKSMORE + 7 * MORE_PER_LINE + 2)
-#define GFX_TUBE_LEFT_UP (GFX_START_ROCKSMORE + 7 * MORE_PER_LINE + 3)
-
-#define GFX_TRAP_INACTIVE (GFX_START_ROCKSMORE + 0 * MORE_PER_LINE + 4)
-#define GFX_TRAP_ACTIVE (GFX_START_ROCKSMORE + 0 * MORE_PER_LINE + 7)
-#define GFX_BD_WALL (GFX_START_ROCKSMORE + 1 * MORE_PER_LINE + 4)
-#define GFX_BD_ROCK (GFX_START_ROCKSMORE + 2 * MORE_PER_LINE + 4)
-#define GFX_DX_SUPABOMB (GFX_START_ROCKSMORE + 1 * MORE_PER_LINE + 7)
-
-/* graphics from "RocksFont" */
-#define GFX_CHAR_START (GFX_START_ROCKSFONT)
-#define GFX_CHAR_ASCII0 (GFX_CHAR_START - 32)
-#define GFX_CHAR_AUSRUF (GFX_CHAR_ASCII0 + 33)
-#define GFX_CHAR_ZOLL (GFX_CHAR_ASCII0 + 34)
-#define GFX_CHAR_DOLLAR (GFX_CHAR_ASCII0 + 36)
-#define GFX_CHAR_PROZ (GFX_CHAR_ASCII0 + 37)
-#define GFX_CHAR_APOSTR (GFX_CHAR_ASCII0 + 39)
-#define GFX_CHAR_KLAMM1 (GFX_CHAR_ASCII0 + 40)
-#define GFX_CHAR_KLAMM2 (GFX_CHAR_ASCII0 + 41)
-#define GFX_CHAR_PLUS (GFX_CHAR_ASCII0 + 43)
-#define GFX_CHAR_KOMMA (GFX_CHAR_ASCII0 + 44)
-#define GFX_CHAR_MINUS (GFX_CHAR_ASCII0 + 45)
-#define GFX_CHAR_PUNKT (GFX_CHAR_ASCII0 + 46)
-#define GFX_CHAR_SLASH (GFX_CHAR_ASCII0 + 47)
-#define GFX_CHAR_0 (GFX_CHAR_ASCII0 + 48)
-#define GFX_CHAR_9 (GFX_CHAR_ASCII0 + 57)
-#define GFX_CHAR_DOPPEL (GFX_CHAR_ASCII0 + 58)
-#define GFX_CHAR_SEMIKL (GFX_CHAR_ASCII0 + 59)
-#define GFX_CHAR_LT (GFX_CHAR_ASCII0 + 60)
-#define GFX_CHAR_GLEICH (GFX_CHAR_ASCII0 + 61)
-#define GFX_CHAR_GT (GFX_CHAR_ASCII0 + 62)
-#define GFX_CHAR_FRAGE (GFX_CHAR_ASCII0 + 63)
-#define GFX_CHAR_AT (GFX_CHAR_ASCII0 + 64)
-#define GFX_CHAR_A (GFX_CHAR_ASCII0 + 65)
-#define GFX_CHAR_Z (GFX_CHAR_ASCII0 + 90)
-#define GFX_CHAR_AE (GFX_CHAR_ASCII0 + 91)
-#define GFX_CHAR_OE (GFX_CHAR_ASCII0 + 92)
-#define GFX_CHAR_UE (GFX_CHAR_ASCII0 + 93)
-#define GFX_CHAR_COPY (GFX_CHAR_ASCII0 + 94)
-#define GFX_CHAR_END (GFX_CHAR_START + 79)
-
-/* new elements which still have no graphic */
-#define GFX_DOOR_WHITE GFX_CHAR_FRAGE
-#define GFX_DOOR_WHITE_GRAY GFX_CHAR_FRAGE
-#define GFX_KEY_WHITE GFX_CHAR_FRAGE
-#define GFX_SIGN_RADIOACTIVITY GFX_CHAR_FRAGE
-#define GFX_SIGN_WHEELCHAIR GFX_CHAR_FRAGE
-#define GFX_SIGN_PARKING GFX_CHAR_FRAGE
-#define GFX_SIGN_ONEWAY GFX_CHAR_FRAGE
-#define GFX_SIGN_HEART GFX_CHAR_FRAGE
-#define GFX_SIGN_TRIANGLE GFX_CHAR_FRAGE
-#define GFX_SIGN_ROUND GFX_CHAR_FRAGE
-#define GFX_SIGN_EXIT GFX_CHAR_FRAGE
-#define GFX_SIGN_YINYANG GFX_CHAR_FRAGE
-#define GFX_SIGN_OTHER GFX_CHAR_FRAGE
-#define GFX_DX_UNKNOWN_15 GFX_CHAR_FRAGE
-#define GFX_DX_UNKNOWN_42 GFX_CHAR_FRAGE
-
-
-/* the names of the sounds */
-#define SND_AMOEBE 0
-#define SND_ANTIGRAV 1
-#define SND_AUTSCH 2
-#define SND_BLURB 3
-#define SND_BONG 4
-#define SND_BUING 5
-#define SND_DENG 6
-#define SND_FUEL 7
-#define SND_GONG 8
-#define SND_HALLOFFAME 9
-#define SND_HOLZ 10
-#define SND_HUI 11
-#define SND_KABUMM 12
-#define SND_KINK 13
-#define SND_KLAPPER 14
-#define SND_KLING 15
-#define SND_KLOPF 16
-#define SND_KLUMPF 17
-#define SND_KNACK 18
-#define SND_KNURK 19
-#define SND_KRACH 20
-#define SND_LACHEN 21
-#define SND_LASER 22
-#define SND_MIEP 23
-#define SND_NJAM 24
-#define SND_OEFFNEN 25
-#define SND_PLING 26
-#define SND_PONG 27
-#define SND_PUSCH 28
-#define SND_QUIEK 29
-#define SND_QUIRK 30
-#define SND_RHYTHMLOOP 31
-#define SND_ROAAAR 32
-#define SND_ROEHR 33
-#define SND_RUMMS 34
-#define SND_SCHLOPP 35
-#define SND_SCHLURF 36
-#define SND_SCHRFF 37
-#define SND_SCHWIRR 38
-#define SND_SIRR 39
-#define SND_SLURP 40
-#define SND_SPROING 41
-#define SND_WARNTON 42
-#define SND_WHOOSH 43
-#define SND_ZISCH 44
-#define SND_SP_BASE 45
-#define SND_SP_INFOTRON 46
-#define SND_SP_ZONKDOWN 47
-#define SND_SP_ZONKPUSH 48
-#define SND_SP_BUG 49
-#define SND_SP_BOOM 50
-#define SND_SP_BOOOM 51
-#define SND_SP_EXIT 52
-#define SND_EMPTY 53
-#define SND_GATE 54
-
-#define NUM_SOUNDS 55
-
-
-/* values for sound effects */
-#define SND_BD_EMPTY_SPACE_DIGGING 0
-#define SND_BD_SAND_DIGGING 1
-#define SND_BD_DIAMOND_COLLECTING 2
-#define SND_BD_DIAMOND_IMPACT 3
-#define SND_BD_ROCK_PUSHING 4
-#define SND_BD_ROCK_IMPACT 5
-#define SND_BD_MAGIC_WALL_ACTIVATING 6
-#define SND_BD_MAGIC_WALL_CHANGING 7
-#define SND_BD_MAGIC_WALL_RUNNING 8
-#define SND_BD_AMOEBA_WAITING 9
-#define SND_BD_AMOEBA_CREATING 10
-#define SND_BD_AMOEBA_TURNING_TO_GEM 11
-#define SND_BD_AMOEBA_TURNING_TO_ROCK 12
-#define SND_BD_BUTTERFLY_MOVING 13
-#define SND_BD_BUTTERFLY_WAITING 14
-#define SND_BD_FIREFLY_MOVING 15
-#define SND_BD_FIREFLY_WAITING 16
-#define SND_BD_EXIT_ENTERING 17
-#define SND_SP_EMPTY_SPACE_DIGGING 18
-#define SND_SP_BASE_DIGGING 19
-#define SND_SP_BUGGY_BASE_DIGGING 20
-#define SND_SP_BUGGY_BASE_ACTIVATING 21
-#define SND_SP_INFOTRON_COLLECTING 22
-#define SND_SP_INFOTRON_IMPACT 23
-#define SND_SP_ZONK_PUSHING 24
-#define SND_SP_ZONK_IMPACT 25
-#define SND_SP_DISK_RED_COLLECTING 26
-#define SND_SP_DISK_ORANGE_PUSHING 27
-#define SND_SP_DISK_YELLOW_PUSHING 28
-#define SND_SP_PORT_PASSING 29
-#define SND_SP_EXIT_ENTERING 30
-#define SND_SP_ELEMENT_EXPLODING 31
-#define SND_SP_SNIKSNAK_MOVING 32
-#define SND_SP_SNIKSNAK_WAITING 33
-#define SND_SP_ELECTRON_MOVING 34
-#define SND_SP_ELECTRON_WAITING 35
-#define SND_SP_TERMINAL_ACTIVATING 36
-#define SND_SOKOBAN_OBJECT_PUSHING 37
-#define SND_SOKOBAN_FIELD_FILLING 38
-#define SND_SOKOBAN_FIELD_CLEARING 39
-#define SND_SOKOBAN_GAME_SOLVING 40
-#define SND_EMPTY_SPACE_DIGGING 41
-#define SND_SAND_DIGGING 42
-#define SND_EMERALD_COLLECTING 43
-#define SND_EMERALD_IMPACT 44
-#define SND_DIAMOND_COLLECTING 45
-#define SND_DIAMOND_IMPACT 46
-#define SND_DIAMOND_BREAKING 47
-#define SND_ROCK_PUSHING 48
-#define SND_ROCK_IMPACT 49
-#define SND_BOMB_PUSHING 50
-#define SND_NUT_PUSHING 51
-#define SND_NUT_CRACKING 52
-#define SND_NUT_IMPACT 53
-#define SND_DYNAMITE_COLLECTING 54
-#define SND_DYNAMITE_PLACING 55
-#define SND_DYNAMITE_BURNING 56
-#define SND_KEY_COLLECTING 57
-#define SND_GATE_PASSING 58
-#define SND_BUG_MOVING 59
-#define SND_BUG_WAITING 60
-#define SND_SPACESHIP_MOVING 61
-#define SND_SPACESHIP_WAITING 62
-#define SND_YAMYAM_MOVING 63
-#define SND_YAMYAM_WAITING 64
-#define SND_YAMYAM_EATING_DIAMOND 65
-#define SND_ROBOT_STEPPING 66
-#define SND_ROBOT_WAITING 67
-#define SND_ROBOT_WHEEL_ACTIVATING 68
-#define SND_ROBOT_WHEEL_RUNNING 69
-#define SND_MAGIC_WALL_ACTIVATING 70
-#define SND_MAGIC_WALL_CHANGING 71
-#define SND_MAGIC_WALL_RUNNING 72
-#define SND_AMOEBA_WAITING 73
-#define SND_AMOEBA_CREATING 74
-#define SND_AMOEBA_DROPPING 75
-#define SND_ACID_SPLASHING 76
-#define SND_QUICKSAND_FILLING 77
-#define SND_QUICKSAND_SLIPPING_THROUGH 78
-#define SND_QUICKSAND_EMPTYING 79
-#define SND_EXIT_OPENING 80
-#define SND_EXIT_ENTERING 81
-#define SND_BALLOON_MOVING 82
-#define SND_BALLOON_WAITING 83
-#define SND_BALLOON_PUSHING 84
-#define SND_BALLOON_SWITCH_ACTIVATING 85
-#define SND_SPRING_MOVING 86
-#define SND_SPRING_PUSHING 87
-#define SND_SPRING_IMPACT 88
-#define SND_WALL_GROWING 89
-#define SND_PEARL_COLLECTING 90
-#define SND_PEARL_BREAKING 91
-#define SND_PEARL_IMPACT 92
-#define SND_CRYSTAL_COLLECTING 93
-#define SND_CRYSTAL_IMPACT 94
-#define SND_ENVELOPE_COLLECTING 95
-#define SND_SAND_INVISIBLE_DIGGING 96
-#define SND_SHIELD_PASSIVE_COLLECTING 97
-#define SND_SHIELD_PASSIVE_ACTIVATED 98
-#define SND_SHIELD_ACTIVE_COLLECTING 99
-#define SND_SHIELD_ACTIVE_ACTIVATED 100
-#define SND_EXTRA_TIME_COLLECTING 101
-#define SND_MOLE_MOVING 102
-#define SND_MOLE_WAITING 103
-#define SND_MOLE_EATING_AMOEBA 104
-#define SND_SWITCHGATE_SWITCH_ACTIVATING 105
-#define SND_SWITCHGATE_OPENING 106
-#define SND_SWITCHGATE_CLOSING 107
-#define SND_SWITCHGATE_PASSING 108
-#define SND_TIMEGATE_WHEEL_ACTIVATING 109
-#define SND_TIMEGATE_WHEEL_RUNNING 110
-#define SND_TIMEGATE_OPENING 111
-#define SND_TIMEGATE_CLOSING 112
-#define SND_TIMEGATE_PASSING 113
-#define SND_CONVEYOR_BELT_SWITCH_ACTIVATING 114
-#define SND_CONVEYOR_BELT_RUNNING 115
-#define SND_LIGHT_SWITCH_ACTIVATING 116
-#define SND_LIGHT_SWITCH_DEACTIVATING 117
-#define SND_DX_BOMB_PUSHING 118
-#define SND_TRAP_INACTIVE_DIGGING 119
-#define SND_TRAP_ACTIVATING 120
-#define SND_TUBE_PASSING 121
-#define SND_AMOEBA_TURNING_TO_GEM 122
-#define SND_AMOEBA_TURNING_TO_ROCK 123
-#define SND_SPEED_PILL_COLLECTING 124
-#define SND_DYNABOMB_NR_COLLECTING 125
-#define SND_DYNABOMB_SZ_COLLECTING 126
-#define SND_DYNABOMB_XL_COLLECTING 127
-#define SND_DYNABOMB_PLACING 128
-#define SND_DYNABOMB_BURNING 129
-#define SND_SATELLITE_MOVING 130
-#define SND_SATELLITE_WAITING 131
-#define SND_SATELLITE_PUSHING 132
-#define SND_LAMP_ACTIVATING 133
-#define SND_LAMP_DEACTIVATING 134
-#define SND_TIME_ORB_FULL_COLLECTING 135
-#define SND_TIME_ORB_FULL_IMPACT 136
-#define SND_TIME_ORB_EMPTY_PUSHING 137
-#define SND_TIME_ORB_EMPTY_IMPACT 138
-#define SND_GAMEOFLIFE_WAITING 139
-#define SND_GAMEOFLIFE_CREATING 140
-#define SND_BIOMAZE_WAITING 141
-#define SND_BIOMAZE_CREATING 142
-#define SND_PACMAN_MOVING 143
-#define SND_PACMAN_WAITING 144
-#define SND_PACMAN_EATING_AMOEBA 145
-#define SND_DARK_YAMYAM_MOVING 146
-#define SND_DARK_YAMYAM_WAITING 147
-#define SND_DARK_YAMYAM_EATING_ANY 148
-#define SND_PENGUIN_MOVING 149
-#define SND_PENGUIN_WAITING 150
-#define SND_PENGUIN_ENTERING_EXIT 151
-#define SND_PIG_MOVING 152
-#define SND_PIG_WAITING 153
-#define SND_PIG_EATING_GEM 154
-#define SND_DRAGON_MOVING 155
-#define SND_DRAGON_WAITING 156
-#define SND_DRAGON_ATTACKING 157
-#define SND_PLAYER_DYING 158
-#define SND_ELEMENT_EXPLODING 159
-#define SND_GAME_STARTING 160
-#define SND_GAME_RUNNING_OUT_OF_TIME 161
-#define SND_GAME_LEVELTIME_BONUS 162
-#define SND_GAME_LOSING 163
-#define SND_GAME_WINNING 164
-#define SND_MENU_DOOR_OPENING 165
-#define SND_MENU_DOOR_CLOSING 166
-#define SND_MENU_HALL_OF_FAME 167
-#define SND_MENU_INFO_SCREEN 168
-
-#define NUM_SOUND_EFFECTS 169
-
-
-/* values for game_status */
-#define EXITGAME 0
-#define MAINMENU 1
-#define PLAYING 2
-#define LEVELED 3
-#define HELPSCREEN 4
-#define CHOOSELEVEL 5
-#define TYPENAME 6
-#define HALLOFFAME 7
-#define SETUP 8
-
-#define PROGRAM_VERSION_MAJOR 2
-#define PROGRAM_VERSION_MINOR 1
-#define PROGRAM_VERSION_PATCH 1
-#define PROGRAM_VERSION_STRING "2.1.1"
+ /* functions that are called before, while and after the change of an
+ element -- currently only used for non-custom elements */
+ void (*pre_change_function)(int x, int y);
+ void (*change_function)(int x, int y);
+ void (*post_change_function)(int x, int y);
+};
-#define PROGRAM_TITLE_STRING "Rocks'n'Diamonds"
-#define PROGRAM_AUTHOR_STRING "Holger Schemel"
-#define PROGRAM_RIGHTS_STRING "Copyright ^1995-2002 by"
-#define PROGRAM_DOS_PORT_STRING "DOS port done by Guido Schulz"
-#define PROGRAM_IDENT_STRING PROGRAM_VERSION_STRING " " TARGET_STRING
-#define WINDOW_TITLE_STRING PROGRAM_TITLE_STRING " " PROGRAM_IDENT_STRING
-#define WINDOW_SUBTITLE_STRING PROGRAM_RIGHTS_STRING " " PROGRAM_AUTHOR_STRING
-#define ICON_TITLE_STRING PROGRAM_TITLE_STRING
-#define UNIX_USERDATA_DIRECTORY ".rocksndiamonds"
-#define COOKIE_PREFIX "ROCKSNDIAMONDS"
-#define FILENAME_PREFIX "Rocks"
+struct ElementInfo
+{
+ /* ---------- token and description strings ---------- */
-#define X11_ICON_FILENAME "rocks_icon.xbm"
-#define X11_ICONMASK_FILENAME "rocks_iconmask.xbm"
-#define MSDOS_POINTER_FILENAME "mouse.pcx"
+ 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 */
+ char *custom_description; /* alternative description from config file */
+ char description[MAX_ELEMENT_NAME_LEN + 1]; /* for custom elements */
-/* file version numbers for resource files (levels, tapes, score, setup, etc.)
-** currently supported/known file version numbers:
-** 1.0 (old)
-** 1.2 (still in use)
-** 1.4 (still in use)
-** 2.0 (actual)
-*/
-#define FILE_VERSION_1_0 VERSION_IDENT(1,0,0)
-#define FILE_VERSION_1_2 VERSION_IDENT(1,2,0)
-#define FILE_VERSION_1_4 VERSION_IDENT(1,4,0)
-#define FILE_VERSION_2_0 VERSION_IDENT(2,0,0)
+ /* ---------- graphic and sound definitions ---------- */
-/* 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
+ int graphic[NUM_ACTIONS]; /* default graphics for several actions */
+ int direction_graphic[NUM_ACTIONS][NUM_DIRECTIONS];
+ /* special graphics for left/right/up/down */
-#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
+ int crumbled[NUM_ACTIONS]; /* crumbled graphics for several actions */
+ int direction_crumbled[NUM_ACTIONS][NUM_DIRECTIONS];
+ /* crumbled graphics for left/right/up/down */
-#define GAME_VERSION_ACTUAL VERSION_IDENT(PROGRAM_VERSION_MAJOR, \
- PROGRAM_VERSION_MINOR, \
- PROGRAM_VERSION_PATCH)
+ int special_graphic[NUM_SPECIAL_GFX_ARGS];
+ /* special graphics for certain screens */
-/* for DrawGraphicAnimation() [tools.c] and AnimateToon() [cartoons.c] */
-#define ANIM_NORMAL 0
-#define ANIM_OSCILLATE 1
-#define ANIM_REVERSE 2
+ int sound[NUM_ACTIONS]; /* default sounds for several actions */
-/* values for game_emulation */
-#define EMU_NONE 0
-#define EMU_BOULDERDASH 1
-#define EMU_SOKOBAN 2
-#define EMU_SUPAPLEX 3
+ /* ---------- special element property values ---------- */
+
+ boolean use_gfx_element; /* use custom graphic element */
+ short gfx_element; /* optional custom graphic element */
+
+ int score; /* score value for collecting */
+ int gem_count; /* gem count value for collecting */
+
+ int push_delay_fixed; /* constant frame delay for pushing */
+ int push_delay_random; /* additional random frame delay for pushing */
+ int move_delay_fixed; /* constant frame delay for moving */
+ int move_delay_random; /* additional random frame delay for moving */
+
+ int move_pattern; /* direction movable element moves to */
+ int move_direction_initial; /* initial direction element moves to */
+ int move_stepsize; /* step size element moves with */
+
+ int slippery_type; /* how/where other elements slip away */
+
+ int content[3][3]; /* new elements after explosion */
+
+ struct ElementChangeInfo change;
+
+ /* ---------- internal values used in level editor ---------- */
+
+ int access_type; /* walkable or passable */
+ int access_layer; /* accessible over/inside/under */
+ int walk_to_action; /* diggable/collectible/pushable */
+ int smash_targets; /* can smash player/enemies/everything */
+ int deadliness; /* deadly when running/colliding/touching */
+ int consistency; /* indestructible/can explode */
+ int change_player_action; /* touched/pressed/pushed by player */
+ int change_collide_action; /* collision/impact/smashed */
+ int change_other_action; /* various change actions */
+
+ boolean can_explode_by_fire; /* element explodes by fire */
+ boolean can_explode_smashed; /* element explodes when smashed */
+ boolean can_explode_impact; /* element explodes on impact */
+};
+
+struct FontInfo
+{
+ char *token_name; /* font token used in config files */
+
+ int graphic; /* default graphic for this font */
+ int special_graphic[NUM_SPECIAL_GFX_ARGS];
+ /* special graphics for certain screens */
+ int special_bitmap_id[NUM_SPECIAL_GFX_ARGS];
+ /* internal bitmap ID for special graphics */
+};
+
+struct GraphicInfo
+{
+ Bitmap *bitmap;
+ 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 anim_frames;
+ int anim_frames_per_line;
+ int anim_start_frame;
+ int anim_delay; /* important: delay of 1 means "no delay"! */
+ int anim_mode;
+ boolean anim_global_sync;
+ int crumbled_like; /* element for cloning crumble graphics */
+ int diggable_like; /* element for cloning digging graphics */
+
+ int step_offset; /* optional step offset of toon animations */
+ int step_delay; /* optional step delay of toon animations */
+
+ int draw_x, draw_y; /* optional offset for drawing fonts chars */
+
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ Pixmap clip_mask; /* single-graphic-only clip mask for X11 */
+ GC clip_gc; /* single-graphic-only clip gc for X11 */
+#endif
+};
+
+struct SoundInfo
+{
+ boolean loop;
+};
+
+struct ElementActionInfo
+{
+ char *suffix;
+ int value;
+ boolean is_loop_sound;
+};
+
+struct ElementDirectionInfo
+{
+ char *suffix;
+ int value;
+};
+
+struct SpecialSuffixInfo
+{
+ char *suffix;
+ int value;
+};
+
+
+#if 0
+extern GC tile_clip_gc;
+extern Bitmap *pix[];
+#endif
+extern Bitmap *bitmap_db_field, *bitmap_db_door;
+extern Pixmap tile_clipmask[];
+extern DrawBuffer *fieldbuffer;
+extern DrawBuffer *drawto_field;
+
+extern int game_status;
+extern boolean level_editor_test_game;
+extern boolean network_playing;
+
+extern int key_joystick_mapping;
+
+extern boolean redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
+extern int redraw_x1, redraw_y1;
+
+extern short Feld[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short MovPos[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short MovDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short MovDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short ChangeDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short Store[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short Store2[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+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 boolean Changing[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short AmoebaCnt[MAX_NUM_AMOEBA];
+extern short AmoebaCnt2[MAX_NUM_AMOEBA];
+extern short ExplodePhase[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short ExplodeField[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+
+extern unsigned long Properties[MAX_NUM_ELEMENTS][NUM_EP_BITFIELDS];
+
+extern int GfxFrame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern int GfxAction[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern int GfxRandom[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern int GfxElement[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+
+extern int lev_fieldx, lev_fieldy;
+extern int scroll_x, scroll_y;
+
+extern int FX, FY;
+extern int ScrollStepSize;
+extern int ScreenMovDir, ScreenMovPos, ScreenGfxPos;
+extern int BorderElement;
+extern int GameFrameDelay;
+extern int FfwdFrameDelay;
+extern int BX1, BY1;
+extern int BX2, BY2;
+extern int SBX_Left, SBX_Right;
+extern int SBY_Upper, SBY_Lower;
+extern int ZX, ZY;
+extern int ExitX, ExitY;
+extern int AllPlayersGone;
+
+extern int TimeFrames, TimePlayed, TimeLeft;
+extern boolean SiebAktiv;
+extern int SiebCount;
+
+extern boolean network_player_action_received;
+
+extern int graphics_action_mapping[];
+
+extern struct LevelInfo level, level_template;
+extern struct PlayerInfo stored_player[], *local_player;
+extern struct HiScore highscore[];
+extern struct TapeInfo tape;
+extern struct GameInfo game;
+extern struct GlobalInfo global;
+extern struct MenuInfo menu;
+extern struct DoorInfo door;
+extern struct ElementInfo element_info[];
+extern struct ElementActionInfo element_action_info[];
+extern struct ElementDirectionInfo element_direction_info[];
+extern struct SpecialSuffixInfo special_suffix_info[];
+extern struct TokenIntPtrInfo image_config_vars[];
+extern struct FontInfo font_info[];
+extern struct GraphicInfo *graphic_info;
+extern struct SoundInfo *sound_info;
+extern struct ConfigInfo image_config[], sound_config[];
+extern struct ConfigInfo image_config_suffix[], sound_config_suffix[];
#endif /* MAIN_H */
if (is_daemon)
{
/* become a daemon, breaking all ties with the controlling terminal */
- options.verbose = 0;
+ options.verbose = FALSE;
for (i=0; i<255; i++)
{
if (i != lfd)
buffer[8] = (unsigned char)((new_random_seed >> 8) & 0xff);
buffer[9] = (unsigned char)((new_random_seed >> 0) & 0xff);
- strcpy((char *)&buffer[10], leveldir_current->filename);
+ strcpy((char *)&buffer[10], leveldir_current->identifier);
- SendBufferToServer(10 + strlen(leveldir_current->filename) + 1);
+ SendBufferToServer(10 + strlen(leveldir_current->identifier) + 1);
}
void SendToServer_PausePlaying()
int new_level_nr;
int dummy; /* !!! HAS NO MEANING ANYMORE !!! */
unsigned long new_random_seed;
- char *new_leveldir_filename;
+ char *new_leveldir_identifier;
new_level_nr = (buffer[2] << 8) + buffer[3];
dummy = (buffer[4] << 8) + buffer[5];
new_random_seed =
(buffer[6] << 24) | (buffer[7] << 16) | (buffer[8] << 8) | (buffer[9]);
- new_leveldir_filename = (char *)&buffer[10];
+ new_leveldir_identifier = (char *)&buffer[10];
- new_leveldir = getTreeInfoFromFilename(leveldir_first,new_leveldir_filename);
+ new_leveldir = getTreeInfoFromIdentifier(leveldir_first,
+ new_leveldir_identifier);
if (new_leveldir == NULL)
{
- Error(ERR_WARN, "no such level directory: '%s'", new_leveldir_filename);
+ Error(ERR_WARN, "no such level identifier: '%s'", new_leveldir_identifier);
new_leveldir = leveldir_first;
- Error(ERR_WARN, "using default level directory: '%s'", new_leveldir->name);
+ Error(ERR_WARN, "using default level set: '%s'", new_leveldir->identifier);
}
printf("OP_START_PLAYING: %d\n", buffer[0]);
Error(ERR_NETWORK_CLIENT,
- "client %d starts game [level %d from leveldir '%s']\n",
- buffer[0], new_level_nr, new_leveldir->name);
+ "client %d starts game [level %d from level identifier '%s']\n",
+ buffer[0], new_level_nr, new_leveldir->identifier);
leveldir_current = new_leveldir;
level_nr = new_level_nr;
InitRND(new_random_seed);
- game_status = PLAYING;
+ game_status = GAME_MODE_PLAYING;
InitGame();
}
printf("OP_STOP_PLAYING: %d\n", buffer[0]);
Error(ERR_NETWORK_CLIENT, "client %d stops game", buffer[0]);
- game_status = MAINMENU;
+ game_status = GAME_MODE_MAIN;
DrawMainMenu();
}
/* screens in the setup menu */
#define SETUP_MODE_MAIN 0
#define SETUP_MODE_GAME 1
-#define SETUP_MODE_INPUT 2
-#define SETUP_MODE_SHORTCUT 3
-#define SETUP_MODE_GRAPHICS 4
-#define SETUP_MODE_SOUND 5
-#define SETUP_MODE_ARTWORK 6
-#define SETUP_MODE_CHOOSE_GRAPHICS 7
-#define SETUP_MODE_CHOOSE_SOUNDS 8
-#define SETUP_MODE_CHOOSE_MUSIC 9
-
-#define MAX_SETUP_MODES 10
+#define SETUP_MODE_EDITOR 2
+#define SETUP_MODE_INPUT 3
+#define SETUP_MODE_SHORTCUT 4
+#define SETUP_MODE_GRAPHICS 5
+#define SETUP_MODE_SOUND 6
+#define SETUP_MODE_ARTWORK 7
+#define SETUP_MODE_CHOOSE_GRAPHICS 8
+#define SETUP_MODE_CHOOSE_SOUNDS 9
+#define SETUP_MODE_CHOOSE_MUSIC 10
+
+#define MAX_SETUP_MODES 11
/* for input setup functions */
#define SETUPINPUT_SCREEN_POS_START 0
static struct GadgetInfo *screen_gadget[NUM_SCREEN_GADGETS];
static int setup_mode = SETUP_MODE_MAIN;
-static void drawCursorExt(int pos, int color, int graphic)
+#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 NUM_MENU_ENTRIES_ON_SCREEN (menu.list_size[game_status] > 2 ? \
+ menu.list_size[game_status] : \
+ MAX_MENU_ENTRIES_ON_SCREEN)
+
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+#define NUM_SCROLLBAR_BITMAPS 2
+static Bitmap *scrollbar_bitmap[NUM_SCROLLBAR_BITMAPS];
+#endif
+
+
+static void drawCursorExt(int xpos, int ypos, int color, int graphic)
{
static int cursor_array[SCR_FIELDY];
- if (graphic)
- cursor_array[pos] = graphic;
-
- graphic = cursor_array[pos];
+ if (xpos == 0)
+ {
+ if (graphic != 0)
+ cursor_array[ypos] = graphic;
+ else
+ graphic = cursor_array[ypos];
+ }
if (color == FC_RED)
- graphic = (graphic == GFX_ARROW_BLUE_LEFT ? GFX_ARROW_RED_LEFT :
- graphic == GFX_ARROW_BLUE_RIGHT ? GFX_ARROW_RED_RIGHT :
- GFX_KUGEL_ROT);
+ graphic = (graphic == IMG_MENU_BUTTON_LEFT ? IMG_MENU_BUTTON_LEFT_ACTIVE :
+ graphic == IMG_MENU_BUTTON_RIGHT ? IMG_MENU_BUTTON_RIGHT_ACTIVE:
+ IMG_MENU_BUTTON_ACTIVE);
+
+ ypos += MENU_SCREEN_START_YPOS;
- DrawGraphic(0, MENU_SCREEN_START_YPOS + pos, graphic);
+ DrawBackground(mSX + xpos * TILEX, mSY + ypos * TILEY, TILEX, TILEY);
+ DrawGraphicThruMaskExt(drawto, mSX + xpos * TILEX, mSY + ypos * TILEY,
+ graphic, 0);
}
-static void initCursor(int pos, int graphic)
+static void initCursor(int ypos, int graphic)
{
- drawCursorExt(pos, FC_BLUE, graphic);
+ drawCursorExt(0, ypos, FC_BLUE, graphic);
}
-static void drawCursor(int pos, int color)
+static void drawCursor(int ypos, int color)
{
- drawCursorExt(pos, color, 0);
+ drawCursorExt(0, ypos, color, 0);
+}
+
+static void drawCursorXY(int xpos, int ypos, int graphic)
+{
+ drawCursorExt(xpos, ypos, -1, graphic);
+}
+
+static void drawChooseTreeCursor(int ypos, int color)
+{
+ int last_game_status = game_status; /* save current game status */
+
+ /* force LEVELS draw offset on artwork setup screen */
+ game_status = GAME_MODE_LEVELS;
+
+ drawCursorExt(0, ypos, color, 0);
+
+ game_status = last_game_status; /* restore current game status */
+}
+
+static void PlaySound_Menu_Start(int sound)
+{
+ if (sound_info[sound].loop)
+ PlaySoundLoop(sound);
+ else
+ PlaySound(sound);
+}
+
+static void PlaySound_Menu_Continue(int sound)
+{
+ if (sound_info[sound].loop)
+ PlaySoundLoop(sound);
}
void DrawHeadline()
{
- int x = SX + (SXSIZE - strlen(PROGRAM_TITLE_STRING) * FONT1_XSIZE) / 2;
+ int font1_width = getFontWidth(FONT_TITLE_1);
+ int font2_width = getFontWidth(FONT_TITLE_2);
+ int x1 = SX + (SXSIZE - strlen(PROGRAM_TITLE_STRING) * font1_width) / 2;
+ int x2 = SX + (SXSIZE - strlen(WINDOW_SUBTITLE_STRING) * font2_width) / 2;
- DrawText(x, SY + 8, PROGRAM_TITLE_STRING, FS_BIG, FC_YELLOW);
- DrawTextFCentered(46, FC_RED, WINDOW_SUBTITLE_STRING);
+ DrawText(x1, SY + 8, PROGRAM_TITLE_STRING, FONT_TITLE_1);
+ DrawText(x2, SY + 46, WINDOW_SUBTITLE_STRING, FONT_TITLE_2);
}
static void ToggleFullscreenIfNeeded()
if (setup.fullscreen != video.fullscreen_enabled)
{
/* save old door content */
- BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
+ BlitBitmap(backbuffer, bitmap_db_door,
DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
/* toggle fullscreen */
setup.fullscreen = video.fullscreen_enabled;
/* redraw background to newly created backbuffer */
- BlitBitmap(pix[PIX_BACK], backbuffer, 0,0, WIN_XSIZE,WIN_YSIZE, 0,0);
+ BlitBitmap(graphic_info[IMG_GLOBAL_BORDER].bitmap, backbuffer,
+ 0,0, WIN_XSIZE,WIN_YSIZE, 0,0);
/* restore old door content */
- BlitBitmap(pix[PIX_DB_DOOR], backbuffer,
+ BlitBitmap(bitmap_db_door, backbuffer,
DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY);
redraw_mask = REDRAW_ALL;
void DrawMainMenu()
{
static LevelDirTree *leveldir_last_valid = NULL;
- int i;
char *name_text = (!options.network && setup.team_mode ? "Team:" : "Name:");
+ int font_width = getFontWidth(FONT_MENU_1);
+ int name_width = font_width * strlen("Name:");
+ int level_width = font_width * strlen("Level:");
+ int i;
UnmapAllGadgets();
FadeSounds();
+
KeyboardAutoRepeatOn();
ActivateJoystick();
+
SetDrawDeactivationMask(REDRAW_NONE);
+ SetDrawBackgroundMask(REDRAW_FIELD);
+
audio.sound_deactivated = FALSE;
/* needed if last screen was the playing screen, invoked from level editor */
if (level_editor_test_game)
{
- game_status = LEVELED;
+ game_status = GAME_MODE_EDITOR;
DrawLevelEd();
return;
}
/* needed if last screen was the setup screen and fullscreen state changed */
ToggleFullscreenIfNeeded();
+ /* leveldir_current may be invalid (level group, parent link) */
+ if (!validLevelSeries(leveldir_current))
+ leveldir_current = getFirstValidTreeInfoEntry(leveldir_last_valid);
+
+ /* store valid level series information */
+ leveldir_last_valid = leveldir_current;
+
/* needed if last screen (level choice) changed graphics, sounds or music */
ReloadCustomArtwork();
/* map gadgets for main menu screen */
MapTapeButtons();
- /* leveldir_current may be invalid (level group, parent link) */
- if (!validLevelSeries(leveldir_current))
- leveldir_current = getFirstValidTreeInfoEntry(leveldir_last_valid);
-
- /* store valid level series information */
- leveldir_last_valid = leveldir_current;
-
/* level_nr may have been set to value over handicap with level editor */
if (setup.handicap && level_nr > leveldir_current->handicap_level)
level_nr = leveldir_current->handicap_level;
GetPlayerConfig();
LoadLevel(level_nr);
+ SetMainBackgroundImage(IMG_BACKGROUND_MAIN);
ClearWindow();
+
DrawHeadline();
- DrawText(SX + 32, SY + 2*32, name_text, FS_BIG, FC_GREEN);
- DrawText(SX + 6*32, SY + 2*32, setup.player_name, FS_BIG, FC_RED);
- DrawText(SX + 32, SY + 3*32, "Level:", FS_BIG, FC_GREEN);
- DrawText(SX + 11*32, SY + 3*32, int2str(level_nr,3), FS_BIG,
- (leveldir_current->readonly ? FC_RED : FC_YELLOW));
- DrawText(SX + 32, SY + 4*32, "Hall Of Fame", FS_BIG, FC_GREEN);
- DrawText(SX + 32, SY + 5*32, "Level Creator", FS_BIG, FC_GREEN);
- DrawText(SY + 32, SY + 6*32, "Info Screen", FS_BIG, FC_GREEN);
- DrawText(SX + 32, SY + 7*32, "Start Game", FS_BIG, FC_GREEN);
- DrawText(SX + 32, SY + 8*32, "Setup", FS_BIG, FC_GREEN);
- DrawText(SX + 32, SY + 9*32, "Quit", FS_BIG, FC_GREEN);
+
+ DrawText(mSX + 32, mSY + 2*32, name_text, FONT_MENU_1);
+ DrawText(mSX + 32, mSY + 3*32, "Level:", FONT_MENU_1);
+ DrawText(mSX + 32, mSY + 4*32, "Hall Of Fame", FONT_MENU_1);
+ DrawText(mSX + 32, mSY + 5*32, "Level Creator", FONT_MENU_1);
+ DrawText(mSX + 32, mSY + 6*32, "Info Screen", FONT_MENU_1);
+ DrawText(mSX + 32, mSY + 7*32, "Start Game", FONT_MENU_1);
+ DrawText(mSX + 32, mSY + 8*32, "Setup", FONT_MENU_1);
+ DrawText(mSX + 32, mSY + 9*32, "Quit", FONT_MENU_1);
+
+ DrawText(mSX + 32 + name_width, mSY + 2*32, setup.player_name, FONT_INPUT_1);
+ DrawText(mSX + level_width + 5 * 32, mSY + 3*32, int2str(level_nr,3),
+ FONT_VALUE_1);
DrawMicroLevel(MICROLEV_XPOS, MICROLEV_YPOS, TRUE);
- DrawTextF(7*32 + 6, 3*32 + 9, FC_RED, "%d-%d",
- leveldir_current->first_level,
- leveldir_current->last_level);
+ DrawTextF(mSX + 32 + level_width - 2, mSY + 3*32 + 1, FONT_TEXT_3, "%d-%d",
+ leveldir_current->first_level, leveldir_current->last_level);
if (leveldir_current->readonly)
{
- DrawTextF(15*32 + 6, 3*32 + 9 - 7, FC_RED, "READ");
- DrawTextF(15*32 + 6, 3*32 + 9 + 7, FC_RED, "ONLY");
+ DrawTextF(mSX + level_width + 9 * 32 - 2,
+ mSY + 3 * 32 + 1 - 7, FONT_TEXT_3, "READ");
+ DrawTextF(mSX + level_width + 9 * 32 - 2,
+ mSY + 3 * 32 + 1 + 7, FONT_TEXT_3, "ONLY");
}
for(i=0; i<8; i++)
- initCursor(i, (i == 1 || i == 6 ? GFX_ARROW_BLUE_RIGHT : GFX_KUGEL_BLAU));
-
- DrawGraphic(10, 3, GFX_ARROW_BLUE_LEFT);
- DrawGraphic(14, 3, GFX_ARROW_BLUE_RIGHT);
-
- DrawText(SX + 56, SY + 326, "A Game by Artsoft Entertainment",
- FS_SMALL, FC_RED);
+ initCursor(i, (i == 1 || i == 6 ? IMG_MENU_BUTTON_RIGHT :IMG_MENU_BUTTON));
- if (leveldir_current->name)
- {
- int len = strlen(leveldir_current->name);
- int lxpos = SX + (SXSIZE - len * FONT4_XSIZE) / 2;
- int lypos = SY + 352;
+ drawCursorXY(level_width/32 + 4, 1, IMG_MENU_BUTTON_LEFT);
+ drawCursorXY(level_width/32 + 8, 1, IMG_MENU_BUTTON_RIGHT);
- DrawText(lxpos, lypos, leveldir_current->name, FS_SMALL, FC_SPECIAL2);
- }
+ DrawText(SX + 56, SY + 326, "A Game by Artsoft Entertainment", FONT_TITLE_2);
FadeToFront();
InitAnimation();
int num_page_entries;
int cl_first, cl_cursor;
- if (num_leveldirs <= MAX_MENU_ENTRIES_ON_SCREEN)
+ if (num_leveldirs <= NUM_MENU_ENTRIES_ON_SCREEN)
num_page_entries = num_leveldirs;
else
- num_page_entries = MAX_MENU_ENTRIES_ON_SCREEN - 1;
+ num_page_entries = NUM_MENU_ENTRIES_ON_SCREEN;
cl_first = MAX(0, leveldir_pos - num_page_entries + 1);
cl_cursor = leveldir_pos - cl_first;
if (mx || my) /* mouse input */
{
- x = (mx - SX) / 32;
- y = (my - SY) / 32 - MENU_SCREEN_START_YPOS;
+ x = (mx - mSX) / 32;
+ y = (my - mSY) / 32 - MENU_SCREEN_START_YPOS;
}
else if (dx || dy) /* keyboard input */
{
static unsigned long level_delay = 0;
int step = (button == 1 ? 1 : button == 2 ? 5 : 10);
int new_level_nr, old_level_nr = level_nr;
- int font_color = (leveldir_current->readonly ? FC_RED : FC_YELLOW);
new_level_nr = level_nr + (x == 10 ? -step : +step);
if (new_level_nr < leveldir_current->first_level)
level_nr = new_level_nr;
- DrawTextExt(drawto, SX + 11 * 32, SY + 3 * 32,
- int2str(level_nr, 3), FS_BIG, font_color);
- DrawTextExt(window, SX + 11 * 32, SY + 3 * 32,
- int2str(level_nr, 3), FS_BIG, font_color);
+ DrawText(mSX + 11 * 32, mSY + 3 * 32, int2str(level_nr, 3), FONT_VALUE_1);
LoadLevel(level_nr);
DrawMicroLevel(MICROLEV_XPOS, MICROLEV_YPOS, TRUE);
{
if (y == 0)
{
- game_status = TYPENAME;
+ game_status = GAME_MODE_PSEUDO_TYPENAME;
HandleTypeName(strlen(setup.player_name), 0);
}
else if (y == 1)
{
if (leveldir_first)
{
- game_status = CHOOSELEVEL;
+ game_status = GAME_MODE_LEVELS;
SaveLevelSetup_LastSeries();
SaveLevelSetup_SeriesInfo();
}
else if (y == 2)
{
- game_status = HALLOFFAME;
+ game_status = GAME_MODE_SCORES;
DrawHallOfFame(-1);
}
else if (y == 3)
if (leveldir_current->readonly &&
strcmp(setup.player_name, "Artsoft") != 0)
Request("This level is read only !", REQ_CONFIRM);
- game_status = LEVELED;
+ game_status = GAME_MODE_EDITOR;
DrawLevelEd();
}
else if (y == 4)
{
- game_status = HELPSCREEN;
+ game_status = GAME_MODE_INFO;
DrawHelpScreen();
}
else if (y == 5)
else
#endif
{
- game_status = PLAYING;
+ game_status = GAME_MODE_PLAYING;
StopAnimation();
InitGame();
}
}
else if (y == 6)
{
- game_status = SETUP;
+ game_status = GAME_MODE_SETUP;
setup_mode = SETUP_MODE_MAIN;
DrawSetupScreen();
}
SaveLevelSetup_LastSeries();
SaveLevelSetup_SeriesInfo();
if (Request("Do you really want to quit ?", REQ_ASK | REQ_STAY_CLOSED))
- game_status = EXITGAME;
+ game_status = GAME_MODE_QUIT;
}
}
}
out:
- if (game_status == MAINMENU)
+ if (game_status == GAME_MODE_MAIN)
{
DrawMicroLevel(MICROLEV_XPOS, MICROLEV_YPOS, FALSE);
DoAnimation();
static long helpscreen_state;
static int helpscreen_step[MAX_HELPSCREEN_ELS];
static int helpscreen_frame[MAX_HELPSCREEN_ELS];
-static int helpscreen_delay[MAX_HELPSCREEN_ELS];
+
static int helpscreen_action[] =
{
- GFX_SPIELER1_DOWN,4,2,
- GFX_SPIELER1_UP,4,2,
- GFX_SPIELER1_LEFT,4,2,
- GFX_SPIELER1_RIGHT,4,2,
- GFX_SPIELER1_PUSH_LEFT,4,2,
- GFX_SPIELER1_PUSH_RIGHT,4,2, HA_NEXT,
- GFX_ERDREICH,1,100, HA_NEXT,
- GFX_LEERRAUM,1,100, HA_NEXT,
- GFX_MORAST_LEER,1,100, HA_NEXT,
- GFX_BETON,1,100, HA_NEXT,
- GFX_MAUERWERK,1,100, HA_NEXT,
- GFX_MAUER_L1, 3,4, GFX_MAUERWERK,1,20, GFX_LEERRAUM,1,10,
- GFX_MAUER_R1, 3,4, GFX_MAUERWERK,1,20, GFX_LEERRAUM,1,10,
- GFX_MAUER_UP, 3,4, GFX_MAUERWERK,1,20, GFX_LEERRAUM,1,10,
- GFX_MAUER_DOWN,3,4, GFX_MAUERWERK,1,20, GFX_LEERRAUM,1,10, HA_NEXT,
- GFX_UNSICHTBAR,1,100, HA_NEXT,
- GFX_FELSBODEN,1,100, HA_NEXT,
- GFX_CHAR_A,30,4, GFX_CHAR_AUSRUF,32,4, HA_NEXT,
- GFX_EDELSTEIN,2,5, HA_NEXT,
- GFX_DIAMANT,2,5, HA_NEXT,
- GFX_EDELSTEIN_BD,2,5, HA_NEXT,
- GFX_EDELSTEIN_GELB,2,5, GFX_EDELSTEIN_ROT,2,5,
- GFX_EDELSTEIN_LILA,2,5, HA_NEXT,
- GFX_FELSBROCKEN,4,5, HA_NEXT,
- GFX_BOMBE,1,50, GFX_EXPLOSION,8,1, GFX_LEERRAUM,1,10, HA_NEXT,
- GFX_KOKOSNUSS,1,50, GFX_CRACKINGNUT,3,1, GFX_EDELSTEIN,1,10, HA_NEXT,
- GFX_ERZ_EDEL,1,50, GFX_EXPLOSION,8,1, GFX_EDELSTEIN,1,10, HA_NEXT,
- GFX_ERZ_DIAM,1,50, GFX_EXPLOSION,8,1, GFX_DIAMANT,1,10, HA_NEXT,
- GFX_ERZ_EDEL_BD,1,50, GFX_EXPLOSION,8,1,GFX_EDELSTEIN_BD,1,10,HA_NEXT,
- GFX_ERZ_EDEL_GELB,1,50, GFX_EXPLOSION,8,1,
- GFX_EDELSTEIN_GELB,1,10, GFX_ERZ_EDEL_ROT,1,50,
- GFX_EXPLOSION,8,1, GFX_EDELSTEIN_ROT,1,10,
- GFX_ERZ_EDEL_LILA,1,50, GFX_EXPLOSION,8,1,
- GFX_EDELSTEIN_LILA,1,10, HA_NEXT,
- GFX_GEBLUBBER,4,4, HA_NEXT,
- GFX_SCHLUESSEL1,4,25, HA_NEXT,
- GFX_PFORTE1,4,25, HA_NEXT,
- GFX_PFORTE1X,4,25, HA_NEXT,
- GFX_DYNAMIT_AUS,1,100, HA_NEXT,
- GFX_DYNAMIT,7,6, GFX_EXPLOSION,8,1, GFX_LEERRAUM,1,10, HA_NEXT,
- GFX_DYNABOMB+0,4,3, GFX_DYNABOMB+3,1,3, GFX_DYNABOMB+2,1,3,
- GFX_DYNABOMB+1,1,3, GFX_DYNABOMB+0,1,3, GFX_EXPLOSION,8,1,
- GFX_LEERRAUM,1,10, HA_NEXT,
- GFX_DYNABOMB_NR,1,100, HA_NEXT,
- GFX_DYNABOMB_SZ,1,100, HA_NEXT,
- GFX_FLIEGER+4,1,3, GFX_FLIEGER+0,1,3, GFX_FLIEGER+4,1,3,
- GFX_FLIEGER+5,1,3, GFX_FLIEGER+1,1,3, GFX_FLIEGER+5,1,3,
- GFX_FLIEGER+6,1,3, GFX_FLIEGER+2,1,3, GFX_FLIEGER+6,1,3,
- GFX_FLIEGER+7,1,3, GFX_FLIEGER+3,1,3, GFX_FLIEGER+7,1,3, HA_NEXT,
- GFX_KAEFER+4,1,1, GFX_KAEFER+0,1,1, GFX_KAEFER+4,1,1,
- GFX_KAEFER+5,1,1, GFX_KAEFER+1,1,1, GFX_KAEFER+5,1,1,
- GFX_KAEFER+6,1,1, GFX_KAEFER+2,1,1, GFX_KAEFER+6,1,1,
- GFX_KAEFER+7,1,1, GFX_KAEFER+3,1,1, GFX_KAEFER+7,1,1, HA_NEXT,
- GFX_BUTTERFLY,2,2, HA_NEXT,
- GFX_FIREFLY,2,2, HA_NEXT,
- GFX_PACMAN+0,1,3, GFX_PACMAN+4,1,2, GFX_PACMAN+0,1,3,
- GFX_PACMAN+1,1,3, GFX_PACMAN+5,1,2, GFX_PACMAN+1,1,3,
- GFX_PACMAN+2,1,3, GFX_PACMAN+6,1,2, GFX_PACMAN+2,1,3,
- GFX_PACMAN+3,1,3, GFX_PACMAN+7,1,2, GFX_PACMAN+3,1,3, HA_NEXT,
- GFX_MAMPFER+0,4,1, GFX_MAMPFER+3,1,1, GFX_MAMPFER+2,1,1,
- GFX_MAMPFER+1,1,1, GFX_MAMPFER+0,1,1, HA_NEXT,
- GFX_MAMPFER2+0,4,1, GFX_MAMPFER2+3,1,1, GFX_MAMPFER2+2,1,1,
- GFX_MAMPFER2+1,1,1, GFX_MAMPFER2+0,1,1, HA_NEXT,
- GFX_ROBOT+0,4,1, GFX_ROBOT+3,1,1, GFX_ROBOT+2,1,1,
- GFX_ROBOT+1,1,1, GFX_ROBOT+0,1,1, HA_NEXT,
- GFX_MOLE_DOWN,4,2,
- GFX_MOLE_UP,4,2,
- GFX_MOLE_LEFT,4,2,
- GFX_MOLE_RIGHT,4,2, HA_NEXT,
- GFX_PINGUIN_DOWN,4,2,
- GFX_PINGUIN_UP,4,2,
- GFX_PINGUIN_LEFT,4,2,
- GFX_PINGUIN_RIGHT,4,2, HA_NEXT,
- GFX_SCHWEIN_DOWN,4,2,
- GFX_SCHWEIN_UP,4,2,
- GFX_SCHWEIN_LEFT,4,2,
- GFX_SCHWEIN_RIGHT,4,2, HA_NEXT,
- GFX_DRACHE_DOWN,4,2,
- GFX_DRACHE_UP,4,2,
- GFX_DRACHE_LEFT,4,2,
- GFX_DRACHE_RIGHT,4,2, HA_NEXT,
- GFX_SONDE_START,8,1, HA_NEXT,
- GFX_ABLENK,4,1, HA_NEXT,
- GFX_BIRNE_AUS,1,25, GFX_BIRNE_EIN,1,25, HA_NEXT,
- GFX_ZEIT_VOLL,1,25, GFX_ZEIT_LEER,1,25, HA_NEXT,
- GFX_TROPFEN,1,25, GFX_AMOEBING,4,1, GFX_AMOEBE_LEBT,1,10, HA_NEXT,
- GFX_AMOEBE_TOT+2,2,50, GFX_AMOEBE_TOT,2,50, HA_NEXT,
- GFX_AMOEBE_LEBT,4,40, HA_NEXT,
- GFX_AMOEBE_LEBT,1,10, GFX_AMOEBING,4,2, HA_NEXT,
- GFX_AMOEBE_LEBT,1,25, GFX_AMOEBE_TOT,1,25, GFX_EXPLOSION,8,1,
- GFX_DIAMANT,1,10, HA_NEXT,
- GFX_LIFE,1,100, HA_NEXT,
- GFX_LIFE_ASYNC,1,100, HA_NEXT,
- GFX_MAGIC_WALL_OFF,4,2, HA_NEXT,
- GFX_MAGIC_WALL_BD_OFF,4,2, HA_NEXT,
- GFX_AUSGANG_ZU,1,100, GFX_AUSGANG_ACT,4,2,
- GFX_AUSGANG_AUF+0,4,2, GFX_AUSGANG_AUF+3,1,2,
- GFX_AUSGANG_AUF+2,1,2, GFX_AUSGANG_AUF+1,1,2, HA_NEXT,
- GFX_AUSGANG_AUF+0,4,2, GFX_AUSGANG_AUF+3,1,2,
- GFX_AUSGANG_AUF+2,1,2, GFX_AUSGANG_AUF+1,1,2, HA_NEXT,
- GFX_SOKOBAN_OBJEKT,1,100, HA_NEXT,
- GFX_SOKOBAN_FELD_LEER,1,100, HA_NEXT,
- GFX_SOKOBAN_FELD_VOLL,1,100, HA_NEXT,
- GFX_SPEED_PILL,1,100, HA_NEXT,
+ IMG_PLAYER_1_MOVING_DOWN, 16,
+ IMG_PLAYER_1_MOVING_UP, 16,
+ IMG_PLAYER_1_MOVING_LEFT, 16,
+ IMG_PLAYER_1_MOVING_RIGHT, 16,
+ IMG_PLAYER_1_PUSHING_LEFT, 16,
+ IMG_PLAYER_1_PUSHING_RIGHT, 16, HA_NEXT,
+
+ IMG_SAND, -1, HA_NEXT,
+
+ IMG_EMPTY_SPACE, -1, HA_NEXT,
+
+ IMG_QUICKSAND_EMPTY, -1, HA_NEXT,
+
+ IMG_STEELWALL, -1, HA_NEXT,
+
+ IMG_WALL, -1, HA_NEXT,
+
+ IMG_EXPANDABLE_WALL_GROWING_LEFT, 20,
+ IMG_WALL, 50,
+ IMG_EMPTY_SPACE, 20,
+ IMG_EXPANDABLE_WALL_GROWING_RIGHT, 20,
+ IMG_WALL, 50,
+ IMG_EMPTY_SPACE, 20,
+ IMG_EXPANDABLE_WALL_GROWING_UP, 20,
+ IMG_WALL, 50,
+ IMG_EMPTY_SPACE, 20,
+ IMG_EXPANDABLE_WALL_GROWING_DOWN, 20,
+ IMG_WALL, 50,
+ IMG_EMPTY_SPACE, 20, HA_NEXT,
+
+ IMG_INVISIBLE_WALL, -1, HA_NEXT,
+
+ IMG_WALL_SLIPPERY, -1, HA_NEXT,
+
+ IMG_FONT_GAME_INFO, -1, HA_NEXT,
+
+ IMG_EMERALD, -1, HA_NEXT,
+
+ IMG_DIAMOND, -1, HA_NEXT,
+
+ IMG_BD_DIAMOND, -1, HA_NEXT,
+
+ IMG_EMERALD_YELLOW, 50,
+ IMG_EMERALD_RED, 50,
+ IMG_EMERALD_PURPLE, 50, HA_NEXT,
+
+ IMG_BD_ROCK, -1, HA_NEXT,
+
+ IMG_BOMB, 100,
+ IMG_EXPLOSION, 16,
+ IMG_EMPTY_SPACE, 10, HA_NEXT,
+
+ IMG_NUT, 100,
+ IMG_NUT_BREAKING, 6,
+ IMG_EMERALD, 20, HA_NEXT,
+
+ IMG_WALL_EMERALD, 100,
+ IMG_EXPLOSION, 16,
+ IMG_EMERALD, 20, HA_NEXT,
+
+ IMG_WALL_DIAMOND, 100,
+ IMG_EXPLOSION, 16,
+ IMG_DIAMOND, 20, HA_NEXT,
+
+ IMG_WALL_BD_DIAMOND, 100,
+ IMG_EXPLOSION, 16,
+ IMG_BD_DIAMOND, 20, HA_NEXT,
+
+ IMG_WALL_EMERALD_YELLOW, 100,
+ IMG_EXPLOSION, 16,
+ IMG_EMERALD_YELLOW, 20,
+ IMG_WALL_EMERALD_RED, 100,
+ IMG_EXPLOSION, 16,
+ IMG_EMERALD_RED, 20,
+ IMG_WALL_EMERALD_PURPLE, 100,
+ IMG_EXPLOSION, 16,
+ IMG_EMERALD_PURPLE, 20, HA_NEXT,
+
+ IMG_ACID, -1, HA_NEXT,
+
+ IMG_KEY_1, 50,
+ IMG_KEY_2, 50,
+ IMG_KEY_3, 50,
+ IMG_KEY_4, 50, HA_NEXT,
+
+ IMG_GATE_1, 50,
+ IMG_GATE_2, 50,
+ IMG_GATE_3, 50,
+ IMG_GATE_4, 50, HA_NEXT,
+
+ IMG_GATE_1_GRAY, 50,
+ IMG_GATE_2_GRAY, 50,
+ IMG_GATE_3_GRAY, 50,
+ IMG_GATE_4_GRAY, 50, HA_NEXT,
+
+ IMG_DYNAMITE, -1, HA_NEXT,
+
+ IMG_DYNAMITE_ACTIVE, 96,
+ IMG_EXPLOSION, 16,
+ IMG_EMPTY_SPACE, 20, HA_NEXT,
+
+ IMG_DYNABOMB_ACTIVE, 100,
+ IMG_EXPLOSION, 16,
+ IMG_EMPTY_SPACE, 20, HA_NEXT,
+
+ IMG_DYNABOMB_INCREASE_NUMBER, -1, HA_NEXT,
+
+ IMG_DYNABOMB_INCREASE_SIZE, -1, HA_NEXT,
+
+ IMG_DYNABOMB_INCREASE_POWER, -1, HA_NEXT,
+
+ IMG_SPACESHIP_RIGHT, 16,
+ IMG_SPACESHIP_UP, 16,
+ IMG_SPACESHIP_LEFT, 16,
+ IMG_SPACESHIP_DOWN, 16, HA_NEXT,
+
+ IMG_BUG_RIGHT, 16,
+ IMG_BUG_UP, 16,
+ IMG_BUG_LEFT, 16,
+ IMG_BUG_DOWN, 16, HA_NEXT,
+
+ IMG_BD_BUTTERFLY, -1, HA_NEXT,
+
+ IMG_BD_FIREFLY, -1, HA_NEXT,
+
+ IMG_PACMAN_RIGHT, 16,
+ IMG_PACMAN_UP, 16,
+ IMG_PACMAN_LEFT, 16,
+ IMG_PACMAN_DOWN, 16, HA_NEXT,
+
+ IMG_YAMYAM, -1, HA_NEXT,
+
+ IMG_DARK_YAMYAM, -1, HA_NEXT,
+
+ IMG_ROBOT, -1, HA_NEXT,
+
+ IMG_MOLE_MOVING_RIGHT, 16,
+ IMG_MOLE_MOVING_UP, 16,
+ IMG_MOLE_MOVING_LEFT, 16,
+ IMG_MOLE_MOVING_DOWN, 16, HA_NEXT,
+
+ IMG_PENGUIN_MOVING_RIGHT, 16,
+ IMG_PENGUIN_MOVING_UP, 16,
+ IMG_PENGUIN_MOVING_LEFT, 16,
+ IMG_PENGUIN_MOVING_DOWN, 16, HA_NEXT,
+
+ IMG_PIG_MOVING_RIGHT, 16,
+ IMG_PIG_MOVING_UP, 16,
+ IMG_PIG_MOVING_LEFT, 16,
+ IMG_PIG_MOVING_DOWN, 16, HA_NEXT,
+
+ IMG_DRAGON_MOVING_RIGHT, 16,
+ IMG_DRAGON_MOVING_UP, 16,
+ IMG_DRAGON_MOVING_LEFT, 16,
+ IMG_DRAGON_MOVING_DOWN, 16, HA_NEXT,
+
+ IMG_SATELLITE, -1, HA_NEXT,
+
+ IMG_ROBOT_WHEEL, 50,
+ IMG_ROBOT_WHEEL_ACTIVE, 100, HA_NEXT,
+
+ IMG_LAMP, 50,
+ IMG_LAMP_ACTIVE, 50, HA_NEXT,
+
+ IMG_TIME_ORB_FULL, 50,
+ IMG_TIME_ORB_EMPTY, 50, HA_NEXT,
+
+ IMG_AMOEBA_DROP, 50,
+ IMG_AMOEBA_GROWING, 6,
+ IMG_AMOEBA_WET, 20, HA_NEXT,
+
+ IMG_AMOEBA_DEAD, -1, HA_NEXT,
+
+ IMG_AMOEBA_WET, -1, HA_NEXT,
+
+ IMG_AMOEBA_WET, 100,
+ IMG_AMOEBA_GROWING, 6, HA_NEXT,
+
+ IMG_AMOEBA_FULL, 50,
+ IMG_AMOEBA_DEAD, 50,
+ IMG_EXPLOSION, 16,
+ IMG_DIAMOND, 20, HA_NEXT,
+
+ IMG_GAME_OF_LIFE, -1, HA_NEXT,
+
+ IMG_BIOMAZE, -1, HA_NEXT,
+
+ IMG_MAGIC_WALL_ACTIVE, -1, HA_NEXT,
+
+ IMG_BD_MAGIC_WALL_ACTIVE, -1, HA_NEXT,
+
+ IMG_EXIT_CLOSED, 200,
+ IMG_EXIT_OPENING, 16,
+ IMG_EXIT_OPEN, 100, HA_NEXT,
+
+ IMG_EXIT_OPEN, -1, HA_NEXT,
+
+ IMG_SOKOBAN_OBJECT, -1, HA_NEXT,
+
+ IMG_SOKOBAN_FIELD_EMPTY, -1, HA_NEXT,
+
+ IMG_SOKOBAN_FIELD_FULL, -1, HA_NEXT,
+
+ IMG_SPEED_PILL, -1, HA_NEXT,
+
HA_END
};
static char *helpscreen_eltext[][2] =
{"THE HERO:", "(Is _this_ guy good old Rockford?)"},
{"Normal sand:", "You can dig through it"},
{"Empty field:", "You can walk through it"},
- {"Quicksand: You cannot pass it,", "but rocks can fall though it"},
+ {"Quicksand: You cannot pass it,", "but rocks can fall through it"},
{"Massive Wall:", "Nothing can go through it"},
{"Normal Wall: You can't go through", "it, but you can bomb it away"},
{"Growing Wall: Grows in several di-", "rections if there is an empty field"},
{"Dyna Bomb: Explodes in 4 directions","with variable explosion size"},
{"Dyna Bomb: Increases the number of", "dyna bombs available at a time"},
{"Dyna Bomb: Increases the size of", "explosion of dyna bombs"},
+ {"Dyna Bomb: Increases the power of", "explosion of dyna bombs"},
{"Spaceship: Moves at the left side", "of walls; don't touch it!"},
{"Bug: Moves at the right side", "of walls; don't touch it!"},
{"Butterfly: Moves at the right side", "of walls; don't touch it!"},
{"Sokoban element: Field with object", "which can be pushed away"},
{"Speed pill: Lets the player run", "twice as fast as normally"},
};
-static int num_helpscreen_els = sizeof(helpscreen_eltext)/(2*sizeof(char *));
+static int num_helpscreen_els = sizeof(helpscreen_eltext) / (2*sizeof(char *));
static char *helpscreen_music[][3] =
{
static int num_helpscreen_music = 7;
static int helpscreen_musicpos;
-void DrawHelpScreenElAction(int start)
+#if 0
+void OLD_DrawHelpScreenElAction(int start)
{
int i = 0, j = 0;
int frame, graphic;
}
j++;
- DrawGraphicExt(drawto, xstart, ystart+(i-start)*ystep, graphic+frame);
+ DrawOldGraphicExt(drawto, xstart, ystart+(i-start)*ystep, graphic+frame);
i++;
}
MarkTileDirty(1,i);
}
}
+#endif
+
+void DrawHelpScreenElAction(int start)
+{
+ int i = 0, j = 0;
+ int xstart = mSX + 16;
+ int ystart = mSY + 64 + 2 * 32;
+ int ystep = TILEY + 4;
+ int graphic;
+ int frame_count;
+ int sync_frame;
+
+ while (helpscreen_action[j] != HA_END)
+ {
+ if (i >= start + MAX_HELPSCREEN_ELS || i >= num_helpscreen_els)
+ break;
+ else if (i < start)
+ {
+ while (helpscreen_action[j] != HA_NEXT)
+ j++;
+
+ j++;
+ i++;
+
+ continue;
+ }
+
+ j += 2 * helpscreen_step[i-start];
+ graphic = helpscreen_action[j++];
+ frame_count = helpscreen_action[j++];
+ if (frame_count == -1)
+ frame_count = 1000000;
+
+ if (helpscreen_frame[i-start] == 0)
+ {
+ sync_frame = 0;
+ helpscreen_frame[i-start] = frame_count - 1;
+ }
+ else
+ {
+ sync_frame = frame_count - helpscreen_frame[i-start];
+ helpscreen_frame[i-start]--;
+ }
+
+ if (helpscreen_action[j] == HA_NEXT)
+ {
+ if (!helpscreen_frame[i-start])
+ helpscreen_step[i-start] = 0;
+ }
+ else
+ {
+ if (!helpscreen_frame[i-start])
+ helpscreen_step[i-start]++;
+ while(helpscreen_action[j] != HA_NEXT)
+ j++;
+ }
+ j++;
+
+#if 1
+ ClearRectangleOnBackground(drawto, xstart, ystart + (i - start) * ystep,
+ TILEX, TILEY);
+ DrawGraphicAnimationExt(drawto, xstart, ystart + (i - start) * ystep,
+ graphic, sync_frame, USE_MASKING);
+#else
+ frame = getGraphicAnimationFrame(graphic, sync_frame);
+
+ DrawGraphicExt(drawto, xstart, ystart + (i-start) * ystep,
+ graphic, frame);
+#endif
+
+ i++;
+ }
+
+#if 1
+ redraw_mask |= REDRAW_FIELD;
+#else
+ for(i=2; i<16; i++)
+ {
+ MarkTileDirty(0, i);
+ MarkTileDirty(1, i);
+ }
+#endif
+
+ FrameCounter++;
+}
void DrawHelpScreenElText(int start)
{
int i;
- int xstart = SX + 56, ystart = SY + 65 + 2 * 32, ystep = TILEY + 4;
+ int xstart = mSX + 56, ystart = mSY + 65 + 2 * 32, ystep = TILEY + 4;
int ybottom = SYSIZE - 20;
+ SetMainBackgroundImage(IMG_BACKGROUND_INFO);
ClearWindow();
DrawHeadline();
- DrawTextFCentered(100, FC_GREEN, "The game elements:");
+ DrawTextFCentered(100, FONT_TEXT_1, "The game elements:");
for(i=start; i < start + MAX_HELPSCREEN_ELS && i < num_helpscreen_els; i++)
{
DrawText(xstart,
ystart + (i - start) * ystep + (*helpscreen_eltext[i][1] ? 0 : 8),
- helpscreen_eltext[i][0], FS_SMALL, FC_YELLOW);
+ helpscreen_eltext[i][0], FONT_TEXT_2);
DrawText(xstart, ystart + (i - start) * ystep + 16,
- helpscreen_eltext[i][1], FS_SMALL, FC_YELLOW);
+ helpscreen_eltext[i][1], FONT_TEXT_2);
}
- DrawTextFCentered(ybottom, FC_BLUE, "Press any key or button for next page");
+ DrawTextFCentered(ybottom, FONT_TEXT_4,
+ "Press any key or button for next page");
}
void DrawHelpScreenMusicText(int num)
ClearWindow();
DrawHeadline();
- DrawTextFCentered(100, FC_GREEN, "The game background music loops:");
+ DrawTextFCentered(100, FONT_TEXT_1, "The game background music loops:");
- DrawTextFCentered(ystart + 0 * ystep, FC_YELLOW,
- "Excerpt from");
- DrawTextFCentered(ystart + 1 * ystep, FC_RED, "\"%s\"",
- helpscreen_music[num][0]);
- DrawTextFCentered(ystart + 2 * ystep, FC_YELLOW,
- "by");
- DrawTextFCentered(ystart + 3 * ystep, FC_RED,
+ DrawTextFCentered(ystart + 0 * ystep, FONT_TEXT_2, "Excerpt from");
+ DrawTextFCentered(ystart + 1 * ystep, FONT_TEXT_3,
+ "\"%s\"", helpscreen_music[num][0]);
+ DrawTextFCentered(ystart + 2 * ystep, FONT_TEXT_2, "by");
+ DrawTextFCentered(ystart + 3 * ystep, FONT_TEXT_3,
"%s", helpscreen_music[num][1]);
- DrawTextFCentered(ystart + 4 * ystep, FC_YELLOW,
- "from the album");
- DrawTextFCentered(ystart + 5 * ystep, FC_RED, "\"%s\"",
- helpscreen_music[num][2]);
+ DrawTextFCentered(ystart + 4 * ystep, FONT_TEXT_2, "from the album");
+ DrawTextFCentered(ystart + 5 * ystep, FONT_TEXT_3,
+ "\"%s\"", helpscreen_music[num][2]);
- DrawTextFCentered(ybottom, FC_BLUE, "Press any key or button for next page");
+ DrawTextFCentered(ybottom, FONT_TEXT_4,
+ "Press any key or button for next page");
#if 0
PlaySoundLoop(background_loop[num]);
ClearWindow();
DrawHeadline();
- DrawTextFCentered(100, FC_GREEN,
- "Credits:");
- DrawTextFCentered(ystart + 0 * ystep, FC_YELLOW,
- "DOS port of the game:");
- DrawTextFCentered(ystart + 1 * ystep, FC_RED,
- "Guido Schulz");
- DrawTextFCentered(ystart + 2 * ystep, FC_YELLOW,
- "Additional toons:");
- DrawTextFCentered(ystart + 3 * ystep, FC_RED,
- "Karl Hörnell");
- DrawTextFCentered(ystart + 5 * ystep, FC_YELLOW,
+ DrawTextFCentered(100, FONT_TEXT_1, "Credits:");
+ DrawTextFCentered(ystart + 0 * ystep, FONT_TEXT_2, "DOS port of the game:");
+ DrawTextFCentered(ystart + 1 * ystep, FONT_TEXT_3, "Guido Schulz");
+ DrawTextFCentered(ystart + 2 * ystep, FONT_TEXT_2, "Additional toons:");
+ DrawTextFCentered(ystart + 3 * ystep, FONT_TEXT_3, "Karl Hörnell");
+ DrawTextFCentered(ystart + 5 * ystep, FONT_TEXT_2,
"...and many thanks to all contributors");
- DrawTextFCentered(ystart + 6 * ystep, FC_YELLOW,
- "of new levels!");
+ DrawTextFCentered(ystart + 6 * ystep, FONT_TEXT_2, "of new levels!");
- DrawTextFCentered(ybottom, FC_BLUE, "Press any key or button for next page");
+ DrawTextFCentered(ybottom, FONT_TEXT_4,
+ "Press any key or button for next page");
}
void DrawHelpScreenContactText()
ClearWindow();
DrawHeadline();
- DrawTextFCentered(100, FC_GREEN, "Program information:");
+ DrawTextFCentered(100, FONT_TEXT_1, "Program information:");
- DrawTextFCentered(ystart + 0 * ystep, FC_YELLOW,
+ DrawTextFCentered(ystart + 0 * ystep, FONT_TEXT_2,
"This game is Freeware!");
- DrawTextFCentered(ystart + 1 * ystep, FC_YELLOW,
+ DrawTextFCentered(ystart + 1 * ystep, FONT_TEXT_2,
"If you like it, send e-mail to:");
- DrawTextFCentered(ystart + 2 * ystep, FC_RED,
+ DrawTextFCentered(ystart + 2 * ystep, FONT_TEXT_3,
"info@artsoft.org");
- DrawTextFCentered(ystart + 3 * ystep, FC_YELLOW,
+ DrawTextFCentered(ystart + 3 * ystep, FONT_TEXT_2,
"or SnailMail to:");
- DrawTextFCentered(ystart + 4 * ystep + 0, FC_RED,
+ DrawTextFCentered(ystart + 4 * ystep + 0, FONT_TEXT_3,
"Holger Schemel");
- DrawTextFCentered(ystart + 4 * ystep + 20, FC_RED,
+ DrawTextFCentered(ystart + 4 * ystep + 20, FONT_TEXT_3,
"Detmolder Strasse 189");
- DrawTextFCentered(ystart + 4 * ystep + 40, FC_RED,
+ DrawTextFCentered(ystart + 4 * ystep + 40, FONT_TEXT_3,
"33604 Bielefeld");
- DrawTextFCentered(ystart + 4 * ystep + 60, FC_RED,
+ DrawTextFCentered(ystart + 4 * ystep + 60, FONT_TEXT_3,
"Germany");
- DrawTextFCentered(ystart + 7 * ystep, FC_YELLOW,
+ DrawTextFCentered(ystart + 7 * ystep, FONT_TEXT_2,
"If you have created new levels,");
- DrawTextFCentered(ystart + 8 * ystep, FC_YELLOW,
+ DrawTextFCentered(ystart + 8 * ystep, FONT_TEXT_2,
"send them to me to include them!");
- DrawTextFCentered(ystart + 9 * ystep, FC_YELLOW,
+ DrawTextFCentered(ystart + 9 * ystep, FONT_TEXT_2,
":-)");
- DrawTextFCentered(ybottom, FC_BLUE, "Press any key or button for main menu");
+ DrawTextFCentered(ybottom, FONT_TEXT_4,
+ "Press any key or button for main menu");
}
void DrawHelpScreen()
CloseDoor(DOOR_CLOSE_2);
for(i=0;i<MAX_HELPSCREEN_ELS;i++)
- helpscreen_step[i] = helpscreen_frame[i] = helpscreen_delay[i] = 0;
+ helpscreen_step[i] = helpscreen_frame[i] = 0;
helpscreen_musicpos = 0;
helpscreen_state = 0;
+
DrawHelpScreenElText(0);
DrawHelpScreenElAction(0);
FadeToFront();
InitAnimation();
- PlaySoundLoop(SND_MENU_INFO_SCREEN);
+
+#if 0
+ PlaySoundLoop(SND_BACKGROUND_INFO);
+#else
+ PlaySound_Menu_Start(SND_BACKGROUND_INFO);
+#endif
}
void HandleHelpScreen(int button)
if (helpscreen_state < num_helpscreen_els_pages - 1)
{
for(i=0;i<MAX_HELPSCREEN_ELS;i++)
- helpscreen_step[i] = helpscreen_frame[i] = helpscreen_delay[i] = 0;
+ helpscreen_step[i] = helpscreen_frame[i] = 0;
helpscreen_state++;
+
+ FrameCounter = 0;
DrawHelpScreenElText(helpscreen_state * MAX_HELPSCREEN_ELS);
DrawHelpScreenElAction(helpscreen_state * MAX_HELPSCREEN_ELS);
}
else
{
FadeSounds();
+
+ game_status = GAME_MODE_MAIN;
DrawMainMenu();
- game_status = MAINMENU;
}
}
else
{
- if (DelayReached(&hs_delay, GAME_FRAME_DELAY * 2))
+ if (DelayReached(&hs_delay, GAME_FRAME_DELAY))
{
if (helpscreen_state < num_helpscreen_els_pages)
DrawHelpScreenElAction(helpscreen_state * MAX_HELPSCREEN_ELS);
/* !!! workaround for playing "music" that is really a sound loop (and
must therefore periodically be reactivated with the current sound
engine !!! */
- PlaySoundLoop(SND_MENU_INFO_SCREEN);
+#if 0
+ PlaySoundLoop(SND_BACKGROUND_INFO);
+#else
+ PlaySound_Menu_Continue(SND_BACKGROUND_INFO);
+#endif
DoAnimation();
}
void HandleTypeName(int newxpos, Key key)
{
static int xpos = 0, ypos = 2;
+ int font_width = getFontWidth(FONT_INPUT_1_ACTIVE);
+ int name_width = getFontWidth(FONT_MENU_1) * strlen("Name:");
+ int startx = mSX + 32 + name_width;
+ int starty = mSY + ypos * 32;
if (newxpos)
{
xpos = newxpos;
- DrawText(SX + 6*32, SY + ypos*32, setup.player_name, FS_BIG, FC_YELLOW);
- DrawGraphic(xpos + 6, ypos, GFX_KUGEL_ROT);
+
+ DrawText(startx, starty, setup.player_name, FONT_INPUT_1_ACTIVE);
+ DrawText(startx + xpos * font_width, starty, "_", FONT_INPUT_1_ACTIVE);
+
return;
}
setup.player_name[xpos] = ascii;
setup.player_name[xpos + 1] = 0;
xpos++;
- DrawTextExt(drawto, SX + 6*32, SY + ypos*32,
- setup.player_name, FS_BIG, FC_YELLOW);
- DrawTextExt(window, SX + 6*32, SY + ypos*32,
- setup.player_name, FS_BIG, FC_YELLOW);
- DrawGraphic(xpos + 6, ypos, GFX_KUGEL_ROT);
+
+ DrawText(startx, starty, setup.player_name, FONT_INPUT_1_ACTIVE);
+ DrawText(startx + xpos * font_width, starty, "_", FONT_INPUT_1_ACTIVE);
}
else if ((key == KSYM_Delete || key == KSYM_BackSpace) && xpos > 0)
{
xpos--;
setup.player_name[xpos] = 0;
- DrawGraphic(xpos + 6, ypos, GFX_KUGEL_ROT);
- DrawGraphic(xpos + 7, ypos, GFX_LEERRAUM);
+
+ DrawText(startx + xpos * font_width, starty, "_ ", FONT_INPUT_1_ACTIVE);
}
else if (key == KSYM_Return && xpos > 0)
{
- DrawText(SX + 6*32, SY + ypos*32, setup.player_name, FS_BIG, FC_RED);
- DrawGraphic(xpos + 6, ypos, GFX_LEERRAUM);
+ DrawText(startx, starty, setup.player_name, FONT_INPUT_1);
+ DrawText(startx + xpos * font_width, starty, " ", FONT_INPUT_1_ACTIVE);
SaveSetup();
- game_status = MAINMENU;
+ game_status = GAME_MODE_MAIN;
}
BackToFront();
static void DrawChooseTree(TreeInfo **ti_ptr)
{
UnmapAllGadgets();
+
+ FreeScreenGadgets();
+ CreateScreenGadgets();
+
CloseDoor(DOOR_CLOSE_2);
ClearWindow();
+
HandleChooseTree(0,0, 0,0, MB_MENU_INITIALIZE, ti_ptr);
MapChooseTreeGadgets(*ti_ptr);
int items_max, items_visible, item_position;
items_max = numTreeInfoInGroup(ti);
- items_visible = MAX_MENU_ENTRIES_ON_SCREEN - 1;
+ items_visible = NUM_MENU_ENTRIES_ON_SCREEN;
item_position = first_entry;
if (item_position > items_max - items_visible)
item_position = items_max - items_visible;
ModifyGadget(gi, GDI_SCROLLBAR_ITEMS_MAX, items_max,
+ GDI_SCROLLBAR_ITEMS_VISIBLE, items_visible,
GDI_SCROLLBAR_ITEM_POSITION, item_position, GDI_END);
}
int i;
char buffer[SCR_FIELDX * 2];
int max_buffer_len = (SCR_FIELDX - 2) * 2;
- int num_entries = numTreeInfoInGroup(ti);
char *title_string = NULL;
- int offset = (ti->type == TREE_TYPE_LEVEL_DIR ? 0 : 16);
+ int xoffset_setup = 16;
+ int yoffset_setup = 16;
+ int xoffset = (ti->type == TREE_TYPE_LEVEL_DIR ? 0 : xoffset_setup);
+ int yoffset = (ti->type == TREE_TYPE_LEVEL_DIR ? 0 : yoffset_setup);
+ int last_game_status = game_status; /* save current game status */
- ClearRectangle(backbuffer, SX, SY, SXSIZE - 32, SYSIZE);
+ DrawBackground(SX, SY, SXSIZE - 32, SYSIZE);
redraw_mask |= REDRAW_FIELD;
title_string =
ti->type == TREE_TYPE_SOUNDS_DIR ? "Custom Sounds" :
ti->type == TREE_TYPE_MUSIC_DIR ? "Custom Music" : "");
- DrawText(SX + offset, SY + offset, title_string, FS_BIG,
- (ti->type == TREE_TYPE_LEVEL_DIR ? FC_GREEN : FC_YELLOW));
+ DrawText(SX + xoffset, SY + yoffset, title_string, FONT_TITLE_1);
+
+ /* force LEVELS font on artwork setup screen */
+ game_status = GAME_MODE_LEVELS;
for(i=0; i<num_page_entries; i++)
{
strncpy(buffer, node->name , max_buffer_len);
buffer[max_buffer_len] = '\0';
- DrawText(SX + 32, SY + ypos * 32, buffer, FS_MEDIUM, node->color);
+ DrawText(mSX + 32, mSY + ypos * 32, buffer, FONT_TEXT_1 + node->color);
if (node->parent_link)
- initCursor(i, GFX_ARROW_BLUE_LEFT);
+ initCursor(i, IMG_MENU_BUTTON_LEFT);
else if (node->level_group)
- initCursor(i, GFX_ARROW_BLUE_RIGHT);
+ initCursor(i, IMG_MENU_BUTTON_RIGHT);
else
- initCursor(i, GFX_KUGEL_BLAU);
+ initCursor(i, IMG_MENU_BUTTON);
}
- if (first_entry > 0)
- DrawGraphic(0, 1, GFX_ARROW_BLUE_UP);
-
- if (first_entry + num_page_entries < num_entries)
- DrawGraphic(0, MAX_MENU_ENTRIES_ON_SCREEN + 1, GFX_ARROW_BLUE_DOWN);
+ game_status = last_game_status; /* restore current game status */
}
static void drawChooseTreeInfo(int entry_pos, TreeInfo *ti)
node_first = getTreeInfoFirstGroupEntry(ti);
node = getTreeInfoFromPos(node_first, entry_pos);
- ClearRectangle(drawto, SX + 32, SY + 32, SXSIZE - 64, 32);
+ DrawBackground(SX + 32, SY + 32, SXSIZE - 64, 32);
if (node->parent_link)
- DrawTextFCentered(40, FC_RED, "leave group \"%s\"", node->class_desc);
+ DrawTextFCentered(40, FONT_TITLE_2, "leave group \"%s\"",
+ node->class_desc);
else if (node->level_group)
- DrawTextFCentered(40, FC_RED, "enter group \"%s\"", node->class_desc);
+ DrawTextFCentered(40, FONT_TITLE_2, "enter group \"%s\"",
+ node->class_desc);
else if (ti->type == TREE_TYPE_LEVEL_DIR)
- DrawTextFCentered(40, FC_RED, "%3d levels (%s)",
+ DrawTextFCentered(40, FONT_TITLE_2, "%3d levels (%s)",
node->levels, node->class_desc);
/* let BackToFront() redraw only what is needed */
static void HandleChooseTree(int mx, int my, int dx, int dy, int button,
TreeInfo **ti_ptr)
{
- static unsigned long choose_delay = 0;
TreeInfo *ti = *ti_ptr;
int x = 0;
int y = ti->cl_cursor;
int step = (button == 1 ? 1 : button == 2 ? 5 : 10);
int num_entries = numTreeInfoInGroup(ti);
int num_page_entries;
+ int last_game_status = game_status; /* save current game status */
- if (num_entries <= MAX_MENU_ENTRIES_ON_SCREEN)
+ /* force LEVELS draw offset on choose level and artwork setup screen */
+ game_status = GAME_MODE_LEVELS;
+
+ if (num_entries <= NUM_MENU_ENTRIES_ON_SCREEN)
num_page_entries = num_entries;
else
- num_page_entries = MAX_MENU_ENTRIES_ON_SCREEN - 1;
+ num_page_entries = NUM_MENU_ENTRIES_ON_SCREEN;
+
+ game_status = last_game_status; /* restore current game status */
if (button == MB_MENU_INITIALIZE)
{
+ int num_entries = numTreeInfoInGroup(ti);
int entry_pos = posTreeInfo(ti);
if (ti->cl_first == -1)
{
+ /* only on initialization */
+ ti->cl_first = MAX(0, entry_pos - num_page_entries + 1);
+ ti->cl_cursor = entry_pos - ti->cl_first;
+ }
+ else if (ti->cl_cursor >= num_page_entries ||
+ (num_entries > num_page_entries &&
+ num_entries - ti->cl_first < num_page_entries))
+ {
+ /* only after change of list size (by custom graphic configuration) */
ti->cl_first = MAX(0, entry_pos - num_page_entries + 1);
- ti->cl_cursor =
- entry_pos - ti->cl_first;
+ ti->cl_cursor = entry_pos - ti->cl_first;
}
if (dx == 999) /* first entry is set by scrollbar position */
drawChooseTreeList(ti->cl_first, num_page_entries, ti);
drawChooseTreeInfo(ti->cl_first + ti->cl_cursor, ti);
- drawCursor(ti->cl_cursor, FC_RED);
+ drawChooseTreeCursor(ti->cl_cursor, FC_RED);
+
return;
}
else if (button == MB_MENU_LEAVE)
*ti_ptr = ti->node_parent;
DrawChooseTree(ti_ptr);
}
- else if (game_status == SETUP)
+ else if (game_status == GAME_MODE_SETUP)
{
execSetupArtwork();
}
else
{
- game_status = MAINMENU;
+ game_status = GAME_MODE_MAIN;
DrawMainMenu();
}
if (mx || my) /* mouse input */
{
- x = (mx - SX) / 32;
- y = (my - SY) / 32 - MENU_SCREEN_START_YPOS;
- }
- else if (dx || dy) /* keyboard input */
- {
- if (dy)
- y = ti->cl_cursor + dy;
+ int last_game_status = game_status; /* save current game status */
- if (ABS(dy) == SCR_FIELDY) /* handle KSYM_Page_Up, KSYM_Page_Down */
- {
- dy = SIGN(dy);
- step = num_page_entries - 1;
- y = (dy < 0 ? -1 : num_page_entries);
- }
- }
+ /* force LEVELS draw offset on artwork setup screen */
+ game_status = GAME_MODE_LEVELS;
- if (x == 0 && y == -1)
- {
- if (ti->cl_first > 0 &&
- (dy || DelayReached(&choose_delay, GADGET_FRAME_DELAY)))
- {
- ti->cl_first -= step;
- if (ti->cl_first < 0)
- ti->cl_first = 0;
+ x = (mx - mSX) / 32;
+ y = (my - mSY) / 32 - MENU_SCREEN_START_YPOS;
- drawChooseTreeList(ti->cl_first, num_page_entries, ti);
- drawChooseTreeInfo(ti->cl_first + ti->cl_cursor, ti);
- drawCursor(ti->cl_cursor, FC_RED);
- AdjustChooseTreeScrollbar(SCREEN_CTRL_ID_SCROLL_VERTICAL,
- ti->cl_first, ti);
- return;
- }
+ game_status = last_game_status; /* restore current game status */
}
- else if (x == 0 && y > num_page_entries - 1)
+ else if (dx || dy) /* keyboard or scrollbar/scrollbutton input */
{
- if (ti->cl_first + num_page_entries < num_entries &&
- (dy || DelayReached(&choose_delay, GADGET_FRAME_DELAY)))
+ /* move cursor instead of scrolling when already at start/end of list */
+ if (dy == -1 * SCROLL_LINE && ti->cl_first == 0)
+ dy = -1;
+ else if (dy == +1 * SCROLL_LINE &&
+ ti->cl_first + num_page_entries == num_entries)
+ dy = 1;
+
+ /* handle scrolling screen one line or page */
+ if (ti->cl_cursor + dy < 0 ||
+ ti->cl_cursor + dy > num_page_entries - 1)
{
- ti->cl_first += step;
- if (ti->cl_first + num_page_entries > num_entries)
- ti->cl_first = MAX(0, num_entries - num_page_entries);
+ if (ABS(dy) == SCROLL_PAGE)
+ step = num_page_entries - 1;
+
+ if (dy < 0 && ti->cl_first > 0)
+ {
+ /* scroll page/line up */
+
+ ti->cl_first -= step;
+ if (ti->cl_first < 0)
+ ti->cl_first = 0;
+
+ drawChooseTreeList(ti->cl_first, num_page_entries, ti);
+ drawChooseTreeInfo(ti->cl_first + ti->cl_cursor, ti);
+ drawChooseTreeCursor(ti->cl_cursor, FC_RED);
+ AdjustChooseTreeScrollbar(SCREEN_CTRL_ID_SCROLL_VERTICAL,
+ ti->cl_first, ti);
+ }
+ else if (dy > 0 && ti->cl_first + num_page_entries < num_entries)
+ {
+ /* scroll page/line down */
+
+ ti->cl_first += step;
+ if (ti->cl_first + num_page_entries > num_entries)
+ ti->cl_first = MAX(0, num_entries - num_page_entries);
+
+ drawChooseTreeList(ti->cl_first, num_page_entries, ti);
+ drawChooseTreeInfo(ti->cl_first + ti->cl_cursor, ti);
+ drawChooseTreeCursor(ti->cl_cursor, FC_RED);
+ AdjustChooseTreeScrollbar(SCREEN_CTRL_ID_SCROLL_VERTICAL,
+ ti->cl_first, ti);
+ }
- drawChooseTreeList(ti->cl_first, num_page_entries, ti);
- drawChooseTreeInfo(ti->cl_first + ti->cl_cursor, ti);
- drawCursor(ti->cl_cursor, FC_RED);
- AdjustChooseTreeScrollbar(SCREEN_CTRL_ID_SCROLL_VERTICAL,
- ti->cl_first, ti);
return;
}
+
+ /* handle moving cursor one line */
+ y = ti->cl_cursor + dy;
}
if (dx == 1)
node_cursor->cl_cursor = ti->cl_cursor;
*ti_ptr = node_cursor->node_group;
DrawChooseTree(ti_ptr);
+
return;
}
}
{
*ti_ptr = ti->node_parent;
DrawChooseTree(ti_ptr);
+
return;
}
{
if (y != ti->cl_cursor)
{
- drawCursor(y, FC_RED);
- drawCursor(ti->cl_cursor, FC_BLUE);
+ drawChooseTreeCursor(y, FC_RED);
+ drawChooseTreeCursor(ti->cl_cursor, FC_BLUE);
drawChooseTreeInfo(ti->cl_first + y, ti);
ti->cl_cursor = y;
}
TapeErase();
}
- if (game_status == SETUP)
+ if (game_status == GAME_MODE_SETUP)
{
execSetupArtwork();
}
else
{
- game_status = MAINMENU;
+ game_status = GAME_MODE_MAIN;
DrawMainMenu();
}
}
BackToFront();
- if (game_status == CHOOSELEVEL || game_status == SETUP)
+ if (game_status == GAME_MODE_LEVELS || game_status == GAME_MODE_SETUP)
DoAnimation();
}
void DrawChooseLevel()
{
+ SetMainBackgroundImage(IMG_BACKGROUND_LEVELS);
+
DrawChooseTree(&leveldir_current);
}
FadeToFront();
InitAnimation();
+
HandleHallOfFame(highlight_position,0, 0,0, MB_MENU_INITIALIZE);
- PlaySound(SND_MENU_HALL_OF_FAME);
+
+#if 0
+ PlaySound(SND_BACKGROUND_SCORES);
+#else
+ PlaySound_Menu_Start(SND_BACKGROUND_SCORES);
+#endif
}
static void drawHallOfFameList(int first_entry, int highlight_position)
{
int i;
+ SetMainBackgroundImage(IMG_BACKGROUND_SCORES);
ClearWindow();
- DrawText(SX + 80, SY + 8, "Hall Of Fame", FS_BIG, FC_YELLOW);
- DrawTextFCentered(46, FC_RED, "HighScores of Level %d", level_nr);
- for(i=0; i<MAX_MENU_ENTRIES_ON_SCREEN; i++)
+ DrawText(mSX + 80, mSY + 8, "Hall Of Fame", FONT_TITLE_1);
+ DrawTextFCentered(46, FONT_TITLE_2, "HighScores of Level %d", level_nr);
+
+ for(i=0; i<NUM_MENU_ENTRIES_ON_SCREEN; i++)
{
int entry = first_entry + i;
- int color = (entry == highlight_position ? FC_RED : FC_GREEN);
-
-#if 0
- DrawText(SX, SY + 64 + i * 32, ".................", FS_BIG, color);
- DrawText(SX, SY + 64 + i * 32, highscore[i].Name, FS_BIG, color);
- DrawText(SX + 12 * 32, SY + 64 + i * 32,
- int2str(highscore[i].Score, 5), FS_BIG, color);
-#else
- DrawText(SX, SY + 64 + i * 32, "..................................",
- FS_MEDIUM, FC_YELLOW);
- DrawText(SX, SY + 64 + i * 32, int2str(entry + 1, 3),
- FS_MEDIUM, FC_YELLOW);
- DrawText(SX + 64, SY + 64 + i * 32, highscore[entry].Name, FS_BIG, color);
- DrawText(SX + 14 * 32 + 16, SY + 64 + i * 32,
- int2str(highscore[entry].Score, 5), FS_MEDIUM, color);
-#endif
+ boolean active = (entry == highlight_position);
+ int font_nr1 = (active ? FONT_TEXT_1_ACTIVE : FONT_TEXT_1);
+ int font_nr2 = (active ? FONT_TEXT_2_ACTIVE : FONT_TEXT_2);
+ int font_nr3 = (active ? FONT_TEXT_3_ACTIVE : FONT_TEXT_3);
+ int font_nr4 = (active ? FONT_TEXT_4_ACTIVE : FONT_TEXT_4);
+ int dx1 = 3 * getFontWidth(font_nr1);
+ int dx2 = dx1 + getFontWidth(font_nr1);
+ int dx3 = dx2 + 25 * getFontWidth(font_nr3);
+ int sy = mSY + 64 + i * 32;
+
+ DrawText(mSX, sy, int2str(entry + 1, 3), font_nr1);
+ DrawText(mSX + dx1, sy, ".", font_nr1);
+ DrawText(mSX + dx2, sy, ".........................", font_nr3);
+ if (strcmp(highscore[entry].Name, EMPTY_PLAYER_NAME) != 0)
+ DrawText(mSX + dx2, sy, highscore[entry].Name, font_nr2);
+ DrawText(mSX + dx3, sy, int2str(highscore[entry].Score, 5), font_nr4);
}
}
first_entry = 0;
highlight_position = mx;
drawHallOfFameList(first_entry, highlight_position);
+
return;
}
- if (ABS(dy) == SCR_FIELDY) /* handle KSYM_Page_Up, KSYM_Page_Down */
- step = MAX_MENU_ENTRIES_ON_SCREEN - 1;
+ if (ABS(dy) == SCROLL_PAGE) /* handle scrolling one page */
+ step = NUM_MENU_ENTRIES_ON_SCREEN - 1;
if (dy < 0)
{
first_entry = 0;
drawHallOfFameList(first_entry, highlight_position);
+
return;
}
}
else if (dy > 0)
{
- if (first_entry + MAX_MENU_ENTRIES_ON_SCREEN < MAX_SCORE_ENTRIES)
+ if (first_entry + NUM_MENU_ENTRIES_ON_SCREEN < MAX_SCORE_ENTRIES)
{
first_entry += step;
- if (first_entry + MAX_MENU_ENTRIES_ON_SCREEN > MAX_SCORE_ENTRIES)
- first_entry = MAX(0, MAX_SCORE_ENTRIES - MAX_MENU_ENTRIES_ON_SCREEN);
+ if (first_entry + NUM_MENU_ENTRIES_ON_SCREEN > MAX_SCORE_ENTRIES)
+ first_entry = MAX(0, MAX_SCORE_ENTRIES - NUM_MENU_ENTRIES_ON_SCREEN);
drawHallOfFameList(first_entry, highlight_position);
+
return;
}
}
if (button_released)
{
- FadeSound(SND_MENU_HALL_OF_FAME);
- game_status = MAINMENU;
+ FadeSound(SND_BACKGROUND_SCORES);
+ game_status = GAME_MODE_MAIN;
DrawMainMenu();
}
BackToFront();
- if (game_status == HALLOFFAME)
+ if (game_status == GAME_MODE_SCORES)
+ {
DoAnimation();
+#if 1
+ PlaySound_Menu_Continue(SND_BACKGROUND_SCORES);
+#endif
+ }
}
static struct TokenInfo *setup_info;
static int num_setup_info;
+static char *graphics_set_name;
+static char *sounds_set_name;
+static char *music_set_name;
+
static void execSetupMain()
{
setup_mode = SETUP_MODE_MAIN;
DrawSetupScreen();
}
+static void execSetupEditor()
+{
+ setup_mode = SETUP_MODE_EDITOR;
+ DrawSetupScreen();
+}
+
static void execSetupGraphics()
{
setup_mode = SETUP_MODE_GRAPHICS;
static void execSetupArtwork()
{
+ setup.graphics_set = artwork.gfx_current->identifier;
+ setup.sounds_set = artwork.snd_current->identifier;
+ setup.music_set = artwork.mus_current->identifier;
+
/* needed if last screen (setup choice) changed graphics, sounds or music */
ReloadCustomArtwork();
- setup.graphics_set = artwork.gfx_current->name;
- setup.sounds_set = artwork.snd_current->name;
- setup.music_set = artwork.mus_current->name;
+ /* needed for displaying artwork name instead of artwork identifier */
+ graphics_set_name = artwork.gfx_current->name;
+ sounds_set_name = artwork.snd_current->name;
+ music_set_name = artwork.mus_current->name;
setup_mode = SETUP_MODE_ARTWORK;
DrawSetupScreen();
static void execExitSetup()
{
- game_status = MAINMENU;
+ game_status = GAME_MODE_MAIN;
DrawMainMenu();
}
static struct TokenInfo setup_info_main[] =
{
{ TYPE_ENTER_MENU, execSetupGame, "Game Settings" },
+ { TYPE_ENTER_MENU, execSetupEditor, "Editor Settings" },
{ TYPE_ENTER_MENU, execSetupGraphics, "Graphics" },
{ TYPE_ENTER_MENU, execSetupSound, "Sound & Music" },
{ TYPE_ENTER_MENU, execSetupArtwork, "Custom Artwork" },
{ TYPE_ENTER_MENU, execSetupShortcut, "Key Shortcuts" },
{ TYPE_EMPTY, NULL, "" },
{ TYPE_LEAVE_MENU, execExitSetup, "Exit" },
- { TYPE_LEAVE_MENU, execSaveAndExitSetup, "Save and exit" },
+ { TYPE_LEAVE_MENU, execSaveAndExitSetup, "Save and Exit" },
{ 0, NULL, NULL }
};
{ TYPE_SWITCH, &setup.time_limit, "Timelimit:" },
{ TYPE_SWITCH, &setup.autorecord, "Auto-Record:" },
{ TYPE_EMPTY, NULL, "" },
- { TYPE_LEAVE_MENU, execSetupMain, "Exit" },
+ { TYPE_LEAVE_MENU, execSetupMain, "Back" },
+ { 0, NULL, NULL }
+};
+
+static struct TokenInfo setup_info_editor[] =
+{
+ { TYPE_STRING, NULL, "Offer Special Elements:"},
+ { TYPE_SWITCH, &setup.editor.el_boulderdash, "BoulderDash:" },
+ { TYPE_SWITCH, &setup.editor.el_emerald_mine, "Emerald Mine:" },
+ { TYPE_SWITCH, &setup.editor.el_more, "More:" },
+ { TYPE_SWITCH, &setup.editor.el_sokoban, "Sokoban:" },
+ { TYPE_SWITCH, &setup.editor.el_supaplex, "Supaplex:" },
+ { TYPE_SWITCH, &setup.editor.el_diamond_caves, "Diamd. Caves:" },
+ { TYPE_SWITCH, &setup.editor.el_dx_boulderdash,"DX Boulderd.:" },
+ { TYPE_SWITCH, &setup.editor.el_chars, "Characters:" },
+ { TYPE_SWITCH, &setup.editor.el_custom, "Custom:" },
+ { TYPE_EMPTY, NULL, "" },
+ { TYPE_LEAVE_MENU, execSetupMain, "Back" },
{ 0, NULL, NULL }
};
{ TYPE_SWITCH, &setup.quick_doors, "Quick Doors:" },
{ TYPE_SWITCH, &setup.toons, "Toons:" },
{ TYPE_EMPTY, NULL, "" },
- { TYPE_LEAVE_MENU, execSetupMain, "Exit" },
+ { TYPE_LEAVE_MENU, execSetupMain, "Back" },
{ 0, NULL, NULL }
};
{ TYPE_SWITCH, &setup.sound_loops, "Sound Loops:" },
{ TYPE_SWITCH, &setup.sound_music, "Game Music:" },
{ TYPE_EMPTY, NULL, "" },
- { TYPE_LEAVE_MENU, execSetupMain, "Exit" },
+ { TYPE_LEAVE_MENU, execSetupMain, "Back" },
{ 0, NULL, NULL }
};
static struct TokenInfo setup_info_artwork[] =
{
{ TYPE_ENTER_MENU, execSetupChooseGraphics,"Custom Graphics" },
- { TYPE_STRING, &setup.graphics_set, "" },
+ { TYPE_STRING, &graphics_set_name, "" },
{ TYPE_ENTER_MENU, execSetupChooseSounds, "Custom Sounds" },
- { TYPE_STRING, &setup.sounds_set, "" },
+ { TYPE_STRING, &sounds_set_name, "" },
{ TYPE_ENTER_MENU, execSetupChooseMusic, "Custom Music" },
- { TYPE_STRING, &setup.music_set, "" },
+ { TYPE_STRING, &music_set_name, "" },
{ TYPE_EMPTY, NULL, "" },
{ TYPE_STRING, NULL, "Override Level Artwork:"},
{ TYPE_YES_NO, &setup.override_level_graphics, "Graphics:" },
{ TYPE_YES_NO, &setup.override_level_sounds, "Sounds:" },
{ TYPE_YES_NO, &setup.override_level_music, "Music:" },
{ TYPE_EMPTY, NULL, "" },
- { TYPE_LEAVE_MENU, execSetupMain, "Exit" },
+ { TYPE_LEAVE_MENU, execSetupMain, "Back" },
{ 0, NULL, NULL }
};
{ TYPE_EMPTY, NULL, "" },
{ TYPE_YES_NO, &setup.ask_on_escape, "Ask on Esc:" },
{ TYPE_EMPTY, NULL, "" },
- { TYPE_LEAVE_MENU, execSetupMain, "Exit" },
+ { TYPE_LEAVE_MENU, execSetupMain, "Back" },
{ 0, NULL, NULL }
};
{
int xpos = MENU_SCREEN_VALUE_XPOS;
int ypos = MENU_SCREEN_START_YPOS + pos;
- int font_size = FS_BIG;
- int font_color = FC_YELLOW;
+ int font_nr = FONT_VALUE_1;
char *value_string = getSetupValue(setup_info[pos].type & ~TYPE_GHOSTED,
setup_info[pos].value);
if (setup_info[pos].type & TYPE_QUERY)
{
value_string = "<press key>";
- font_color = FC_RED;
+ font_nr = FONT_INPUT_1_ACTIVE;
}
}
else if (setup_info[pos].type & TYPE_STRING)
int max_value_len = (SCR_FIELDX - 2) * 2;
xpos = 1;
- font_size = FS_MEDIUM;
+ font_nr = FONT_VALUE_2;
if (strlen(value_string) > max_value_len)
value_string[max_value_len] = '\0';
}
- else if (setup_info[pos].type & TYPE_BOOLEAN_STYLE &&
- !*(boolean *)(setup_info[pos].value))
- font_color = FC_BLUE;
+ else if (setup_info[pos].type & TYPE_BOOLEAN_STYLE)
+ {
+ font_nr = (*(boolean *)(setup_info[pos].value) ? FONT_OPTION_ON :
+ FONT_OPTION_OFF);
+ }
- DrawText(SX + xpos * 32, SY + ypos * 32,
- (xpos == 3 ? " " : " "), FS_BIG, FC_YELLOW);
- DrawText(SX + xpos * 32, SY + ypos * 32, value_string, font_size,font_color);
+ DrawText(mSX + xpos * 32, mSY + ypos * 32,
+ (xpos == 3 ? " " : " "), font_nr);
+ DrawText(mSX + xpos * 32, mSY + ypos * 32, value_string, font_nr);
}
static void changeSetupValue(int pos)
UnmapAllGadgets();
CloseDoor(DOOR_CLOSE_2);
+
ClearWindow();
if (setup_mode == SETUP_MODE_MAIN)
setup_info = setup_info_game;
title_string = "Setup Game";
}
+ else if (setup_mode == SETUP_MODE_EDITOR)
+ {
+ setup_info = setup_info_editor;
+ title_string = "Setup Editor";
+ }
else if (setup_mode == SETUP_MODE_GRAPHICS)
{
setup_info = setup_info_graphics;
title_string = "Setup Shortcuts";
}
- DrawText(SX + 16, SY + 16, title_string, FS_BIG, FC_YELLOW);
+ DrawText(mSX + 16, mSY + 16, title_string, FONT_TITLE_1);
num_setup_info = 0;
- for(i=0; setup_info[i].type != 0 && i < MAX_MENU_ENTRIES_ON_SCREEN; i++)
+ for(i=0; setup_info[i].type != 0 && i < NUM_MENU_ENTRIES_ON_SCREEN; i++)
{
void *value_ptr = setup_info[i].value;
int ypos = MENU_SCREEN_START_YPOS + i;
- int font_size = FS_BIG;
+ int font_nr = FONT_MENU_1;
/* set some entries to "unchangeable" according to other variables */
if ((value_ptr == &setup.sound && !audio.sound_available) ||
setup_info[i].type |= TYPE_GHOSTED;
if (setup_info[i].type & TYPE_STRING)
- font_size = FS_MEDIUM;
+ font_nr = FONT_MENU_2;
- DrawText(SX + 32, SY + ypos * 32, setup_info[i].text, font_size, FC_GREEN);
+ DrawText(mSX + 32, mSY + ypos * 32, setup_info[i].text, font_nr);
if (setup_info[i].type & TYPE_ENTER_MENU)
- initCursor(i, GFX_ARROW_BLUE_RIGHT);
+ initCursor(i, IMG_MENU_BUTTON_RIGHT);
else if (setup_info[i].type & TYPE_LEAVE_MENU)
- initCursor(i, GFX_ARROW_BLUE_LEFT);
+ initCursor(i, IMG_MENU_BUTTON_LEFT);
else if (setup_info[i].type & ~TYPE_SKIP_ENTRY)
- initCursor(i, GFX_KUGEL_BLAU);
+ initCursor(i, IMG_MENU_BUTTON);
if (setup_info[i].type & TYPE_VALUE)
drawSetupValue(i);
void HandleSetupScreen_Generic(int mx, int my, int dx, int dy, int button)
{
static int choice_store[MAX_SETUP_MODES];
- int choice = choice_store[setup_mode];
+ int choice = choice_store[setup_mode]; /* always starts with 0 */
int x = 0;
int y = choice;
if (button == MB_MENU_INITIALIZE)
{
+ /* advance to first valid menu entry */
+ while (choice < num_setup_info &&
+ (setup_info[choice].type & TYPE_SKIP_ENTRY))
+ choice++;
+ choice_store[setup_mode] = choice;
+
drawCursor(choice, FC_RED);
return;
}
if (mx || my) /* mouse input */
{
- x = (mx - SX) / 32;
- y = (my - SY) / 32 - MENU_SCREEN_START_YPOS;
+ x = (mx - mSX) / 32;
+ y = (my - mSY) / 32 - MENU_SCREEN_START_YPOS;
}
else if (dx || dy) /* keyboard input */
{
BackToFront();
- if (game_status == SETUP)
+ if (game_status == GAME_MODE_SETUP)
DoAnimation();
}
void DrawSetupScreen_Input()
{
ClearWindow();
- DrawText(SX+16, SY+16, "Setup Input", FS_BIG, FC_YELLOW);
- initCursor(0, GFX_KUGEL_BLAU);
- initCursor(1, GFX_KUGEL_BLAU);
- initCursor(2, GFX_ARROW_BLUE_RIGHT);
- initCursor(13, GFX_ARROW_BLUE_LEFT);
+ DrawText(mSX+16, mSY+16, "Setup Input", FONT_TITLE_1);
+
+ initCursor(0, IMG_MENU_BUTTON);
+ initCursor(1, IMG_MENU_BUTTON);
+ initCursor(2, IMG_MENU_BUTTON_RIGHT);
+ initCursor(13, IMG_MENU_BUTTON_LEFT);
- DrawGraphic(10, MENU_SCREEN_START_YPOS, GFX_ARROW_BLUE_LEFT);
- DrawGraphic(12, MENU_SCREEN_START_YPOS, GFX_ARROW_BLUE_RIGHT);
+ drawCursorXY(10, 0, IMG_MENU_BUTTON_LEFT);
+ drawCursorXY(12, 0, IMG_MENU_BUTTON_RIGHT);
- DrawText(SX+32, SY+2*32, "Player:", FS_BIG, FC_GREEN);
- DrawText(SX+32, SY+3*32, "Device:", FS_BIG, FC_GREEN);
- DrawText(SX+32, SY+15*32, "Exit", FS_BIG, FC_GREEN);
+ DrawText(mSX+32, mSY+2*32, "Player:", FONT_MENU_1);
+ DrawText(mSX+32, mSY+3*32, "Device:", FONT_MENU_1);
+ DrawText(mSX+32, mSY+15*32, "Back", FONT_MENU_1);
#if 0
DeactivateJoystickForCalibration();
- DrawTextFCentered(SYSIZE - 20, FC_BLUE,
+ DrawTextFCentered(SYSIZE - 20, FONT_TEXT_4,
"Joysticks deactivated on this screen");
#endif
custom_key = setup.input[player_nr].key;
- DrawText(SX+11*32, SY+2*32, int2str(player_nr + 1, 1), FS_BIG, FC_RED);
- DrawGraphic(8, 2, GFX_SPIELER1 + player_nr);
+ DrawText(mSX+11*32, mSY+2*32, int2str(player_nr +1, 1), FONT_INPUT_1_ACTIVE);
+#if 1
+ DrawGraphicThruMaskExt(drawto, mSX + 8 * TILEX, mSY + 2 * TILEY,
+ PLAYER_NR_GFX(IMG_PLAYER_1, player_nr), 0);
+#else
+ DrawGraphicThruMask(8, 2, PLAYER_NR_GFX(IMG_PLAYER_1, player_nr), 0);
+#endif
if (setup.input[player_nr].use_joystick)
{
char *device_name = setup.input[player_nr].joy.device_name;
- DrawText(SX+8*32, SY+3*32,
+ DrawText(mSX+8*32, mSY+3*32,
joystick_name[getJoystickNrFromDeviceName(device_name)],
- FS_BIG, FC_YELLOW);
- DrawText(SX+32, SY+4*32, "Calibrate", FS_BIG, FC_GREEN);
+ FONT_VALUE_1);
+ DrawText(mSX+32, mSY+4*32, "Calibrate", FONT_MENU_1);
}
else
{
- DrawText(SX+8*32, SY+3*32, "Keyboard ", FS_BIG, FC_YELLOW);
- DrawText(SX+32, SY+4*32, "Customize", FS_BIG, FC_GREEN);
+ DrawText(mSX+8*32, mSY+3*32, "Keyboard ", FONT_VALUE_1);
+ DrawText(mSX+32, mSY+4*32, "Customize", FONT_MENU_1);
}
- DrawText(SX+32, SY+5*32, "Actual Settings:", FS_BIG, FC_GREEN);
- DrawGraphic(1, 6, GFX_ARROW_BLUE_LEFT);
- DrawGraphic(1, 7, GFX_ARROW_BLUE_RIGHT);
- DrawGraphic(1, 8, GFX_ARROW_BLUE_UP);
- DrawGraphic(1, 9, GFX_ARROW_BLUE_DOWN);
- DrawText(SX+2*32, SY+6*32, ":", FS_BIG, FC_BLUE);
- DrawText(SX+2*32, SY+7*32, ":", FS_BIG, FC_BLUE);
- DrawText(SX+2*32, SY+8*32, ":", FS_BIG, FC_BLUE);
- DrawText(SX+2*32, SY+9*32, ":", FS_BIG, FC_BLUE);
- DrawText(SX+32, SY+10*32, "Snap Field:", FS_BIG, FC_BLUE);
- DrawText(SX+32, SY+12*32, "Place Bomb:", FS_BIG, FC_BLUE);
+ DrawText(mSX+32, mSY+5*32, "Actual Settings:", FONT_MENU_1);
+ drawCursorXY(1, 4, IMG_MENU_BUTTON_LEFT);
+ drawCursorXY(1, 5, IMG_MENU_BUTTON_RIGHT);
+ drawCursorXY(1, 6, IMG_MENU_BUTTON_UP);
+ drawCursorXY(1, 7, IMG_MENU_BUTTON_DOWN);
+ DrawText(mSX+2*32, mSY+6*32, ":", FONT_VALUE_OLD);
+ DrawText(mSX+2*32, mSY+7*32, ":", FONT_VALUE_OLD);
+ DrawText(mSX+2*32, mSY+8*32, ":", FONT_VALUE_OLD);
+ DrawText(mSX+2*32, mSY+9*32, ":", FONT_VALUE_OLD);
+ DrawText(mSX+32, mSY+10*32, "Snap Field:", FONT_VALUE_OLD);
+ DrawText(mSX+32, mSY+12*32, "Place Bomb:", FONT_VALUE_OLD);
for (i=0; i<6; i++)
{
int ypos = 6 + i + (i > 3 ? i-3 : 0);
- DrawText(SX + 3*32, SY + ypos*32,
- " ", FS_BIG, FC_YELLOW);
- DrawText(SX + 3*32, SY + ypos*32,
+ DrawText(mSX + 3*32, mSY + ypos*32,
+ " ", FONT_VALUE_1);
+ DrawText(mSX + 3*32, mSY + ypos*32,
(setup.input[player_nr].use_joystick ?
custom[i].text :
- getKeyNameFromKey(*custom[i].key)),
- FS_BIG, FC_YELLOW);
+ getKeyNameFromKey(*custom[i].key)), FONT_VALUE_1);
}
}
if (mx || my) /* mouse input */
{
- x = (mx - SX) / 32;
- y = (my - SY) / 32 - MENU_SCREEN_START_YPOS;
+ x = (mx - mSX) / 32;
+ y = (my - mSY) / 32 - MENU_SCREEN_START_YPOS;
}
else if (dx || dy) /* keyboard input */
{
out:
- if (game_status == SETUP)
+ if (game_status == GAME_MODE_SETUP)
DoAnimation();
}
custom_key = setup.input[player_nr].key;
ClearWindow();
- DrawText(SX + 16, SY + 16, "Keyboard Input", FS_BIG, FC_YELLOW);
+ DrawText(mSX + 16, mSY + 16, "Keyboard Input", FONT_TITLE_1);
BackToFront();
InitAnimation();
step_nr = 0;
- DrawText(SX, SY + (2+2*step_nr)*32,
- customize_step[step_nr].text, FS_BIG, FC_RED);
- DrawText(SX, SY + (2+2*step_nr+1)*32,
- "Key:", FS_BIG, FC_RED);
- DrawText(SX + 4*32, SY + (2+2*step_nr+1)*32,
- getKeyNameFromKey(*customize_step[step_nr].key),
- FS_BIG, FC_BLUE);
+ DrawText(mSX, mSY + (2+2*step_nr)*32,
+ customize_step[step_nr].text, FONT_INPUT_1_ACTIVE);
+ DrawText(mSX, mSY + (2+2*step_nr+1)*32,
+ "Key:", FONT_INPUT_1_ACTIVE);
+ DrawText(mSX + 4*32, mSY + (2+2*step_nr+1)*32,
+ getKeyNameFromKey(*customize_step[step_nr].key), FONT_VALUE_OLD);
while(!finished)
{
/* got new key binding */
*customize_step[step_nr].key = key;
- DrawText(SX + 4*32, SY + (2+2*step_nr+1)*32,
- " ", FS_BIG, FC_YELLOW);
- DrawText(SX + 4*32, SY + (2+2*step_nr+1)*32,
- getKeyNameFromKey(key), FS_BIG, FC_YELLOW);
+ DrawText(mSX + 4*32, mSY + (2+2*step_nr+1)*32,
+ " ", FONT_VALUE_1);
+ DrawText(mSX + 4*32, mSY + (2+2*step_nr+1)*32,
+ getKeyNameFromKey(key), FONT_VALUE_1);
step_nr++;
/* un-highlight last query */
- DrawText(SX, SY+(2+2*(step_nr-1))*32,
- customize_step[step_nr-1].text, FS_BIG, FC_GREEN);
- DrawText(SX, SY+(2+2*(step_nr-1)+1)*32,
- "Key:", FS_BIG, FC_GREEN);
+ DrawText(mSX, mSY+(2+2*(step_nr-1))*32,
+ customize_step[step_nr-1].text, FONT_MENU_1);
+ DrawText(mSX, mSY+(2+2*(step_nr-1)+1)*32,
+ "Key:", FONT_MENU_1);
/* press 'Enter' to leave */
if (step_nr == 6)
{
- DrawText(SX + 16, SY + 15*32+16,
- "Press Enter", FS_BIG, FC_YELLOW);
+ DrawText(mSX + 16, mSY + 15*32+16,
+ "Press Enter", FONT_TITLE_1);
break;
}
/* query next key binding */
- DrawText(SX, SY+(2+2*step_nr)*32,
- customize_step[step_nr].text, FS_BIG, FC_RED);
- DrawText(SX, SY+(2+2*step_nr+1)*32,
- "Key:", FS_BIG, FC_RED);
- DrawText(SX + 4*32, SY+(2+2*step_nr+1)*32,
+ DrawText(mSX, mSY+(2+2*step_nr)*32,
+ customize_step[step_nr].text, FONT_INPUT_1_ACTIVE);
+ DrawText(mSX, mSY+(2+2*step_nr+1)*32,
+ "Key:", FONT_INPUT_1_ACTIVE);
+ DrawText(mSX + 4*32, mSY+(2+2*step_nr+1)*32,
getKeyNameFromKey(*customize_step[step_nr].key),
- FS_BIG, FC_BLUE);
+ FONT_VALUE_OLD);
}
break;
ClearWindow();
- for(y=0; y<3; y++)
+ for(y=0; y < 3; y++)
{
- for(x=0; x<3; x++)
+ for(x=0; x < 3; x++)
{
+ DrawGraphic(xpos + x - 1, ypos + y - 1, IMG_MENU_CALIBRATE_BLUE, 0);
check[x][y] = FALSE;
- DrawGraphic(xpos + x - 1, ypos + y - 1, GFX_KUGEL_BLAU);
}
}
- DrawText(SX, SY + 6 * 32, " ROTATE JOYSTICK ", FS_BIG, FC_YELLOW);
- DrawText(SX, SY + 7 * 32, "IN ALL DIRECTIONS", FS_BIG, FC_YELLOW);
- DrawText(SX + 16, SY + 9 * 32, " IF ALL BALLS ", FS_BIG, FC_YELLOW);
- DrawText(SX, SY + 10 * 32, " ARE YELLOW, ", FS_BIG, FC_YELLOW);
- DrawText(SX, SY + 11 * 32, " CENTER JOYSTICK ", FS_BIG, FC_YELLOW);
- DrawText(SX, SY + 12 * 32, " AND ", FS_BIG, FC_YELLOW);
- DrawText(SX, SY + 13 * 32, "PRESS ANY BUTTON!", FS_BIG, FC_YELLOW);
+ DrawText(mSX, mSY + 6 * 32, " ROTATE JOYSTICK ", FONT_TITLE_1);
+ DrawText(mSX, mSY + 7 * 32, "IN ALL DIRECTIONS", FONT_TITLE_1);
+ DrawText(mSX + 16, mSY + 9 * 32, " IF ALL BALLS ", FONT_TITLE_1);
+ DrawText(mSX, mSY + 10 * 32, " ARE YELLOW, ", FONT_TITLE_1);
+ DrawText(mSX, mSY + 11 * 32, " CENTER JOYSTICK ", FONT_TITLE_1);
+ DrawText(mSX, mSY + 12 * 32, " AND ", FONT_TITLE_1);
+ DrawText(mSX, mSY + 13 * 32, "PRESS ANY BUTTON!", FONT_TITLE_1);
joy_value = Joystick(player_nr);
last_x = (joy_value & JOY_LEFT ? -1 : joy_value & JOY_RIGHT ? +1 : 0);
new_joystick_xmiddle = joy_x;
new_joystick_ymiddle = joy_y;
- DrawGraphic(xpos + last_x, ypos + last_y, GFX_KUGEL_ROT);
+ DrawGraphic(xpos + last_x, ypos + last_y, IMG_MENU_CALIBRATE_RED, 0);
BackToFront();
while(Joystick(player_nr) & JOY_BUTTON); /* wait for released button */
if (x != last_x || y != last_y)
{
- DrawGraphic(xpos + last_x, ypos + last_y, GFX_KUGEL_GELB);
- DrawGraphic(xpos + x, ypos + y, GFX_KUGEL_ROT);
+ DrawGraphic(xpos + last_x, ypos + last_y, IMG_MENU_CALIBRATE_YELLOW, 0);
+ DrawGraphic(xpos + x, ypos + y, IMG_MENU_CALIBRATE_RED, 0);
last_x = x;
last_y = y;
{
ClearWindow();
- DrawText(SX + 16, SY + 6*32, " JOYSTICK NOT ", FS_BIG, FC_YELLOW);
- DrawText(SX, SY + 7*32, " AVAILABLE ", FS_BIG, FC_YELLOW);
+ DrawText(mSX + 16, mSY + 6*32, " JOYSTICK NOT ", FONT_TITLE_1);
+ DrawText(mSX, mSY + 7*32, " AVAILABLE ", FONT_TITLE_1);
BackToFront();
Delay(2000); /* show error message for two seconds */
}
{
DeactivateJoystick();
+ SetMainBackgroundImage(IMG_BACKGROUND_SETUP);
+
if (setup_mode == SETUP_MODE_INPUT)
DrawSetupScreen_Input();
else if (setup_mode == SETUP_MODE_CHOOSE_GRAPHICS)
void HandleGameActions()
{
- if (game_status != PLAYING)
+ if (game_status != GAME_MODE_PLAYING)
return;
if (local_player->LevelSolved)
GameActions();
BackToFront();
+
+#if 1
+ if (tape.auto_play && !tape.playing)
+ AutoPlayTape(); /* continue automatically playing next tape */
+#endif
}
/* ---------- new screen button stuff -------------------------------------- */
/* graphic position and size values for buttons and scrollbars */
-#define SC_SCROLLBUTTON_XPOS 64
-#define SC_SCROLLBUTTON_YPOS 0
-#define SC_SCROLLBAR_XPOS 0
-#define SC_SCROLLBAR_YPOS 64
-
-#define SC_SCROLLBUTTON_XSIZE 32
-#define SC_SCROLLBUTTON_YSIZE 32
+#define SC_SCROLLBUTTON_XSIZE TILEX
+#define SC_SCROLLBUTTON_YSIZE TILEY
+#define SC_SCROLL_VERTICAL_XSIZE SC_SCROLLBUTTON_XSIZE
+#define SC_SCROLL_VERTICAL_YSIZE ((MAX_MENU_ENTRIES_ON_SCREEN - 2) * \
+ SC_SCROLLBUTTON_YSIZE)
#define SC_SCROLL_UP_XPOS (SXSIZE - SC_SCROLLBUTTON_XSIZE)
-#define SC_SCROLL_UP_YPOS SC_SCROLLBUTTON_YSIZE
-#define SC_SCROLL_DOWN_XPOS SC_SCROLL_UP_XPOS
-#define SC_SCROLL_DOWN_YPOS (SYSIZE - SC_SCROLLBUTTON_YSIZE)
+#define SC_SCROLL_UP_YPOS (2 * SC_SCROLLBUTTON_YSIZE)
#define SC_SCROLL_VERTICAL_XPOS SC_SCROLL_UP_XPOS
-#define SC_SCROLL_VERTICAL_YPOS (SC_SCROLL_UP_YPOS + SC_SCROLLBUTTON_YSIZE)
-#define SC_SCROLL_VERTICAL_XSIZE SC_SCROLLBUTTON_XSIZE
-#define SC_SCROLL_VERTICAL_YSIZE (SYSIZE - 3 * SC_SCROLLBUTTON_YSIZE)
+#define SC_SCROLL_VERTICAL_YPOS (SC_SCROLL_UP_YPOS + \
+ SC_SCROLLBUTTON_YSIZE)
+#define SC_SCROLL_DOWN_XPOS SC_SCROLL_UP_XPOS
+#define SC_SCROLL_DOWN_YPOS (SC_SCROLL_VERTICAL_YPOS + \
+ SC_SCROLL_VERTICAL_YSIZE)
#define SC_BORDER_SIZE 14
static struct
{
- int xpos, ypos;
+ int gfx_unpressed, gfx_pressed;
int x, y;
int gadget_id;
char *infotext;
} scrollbutton_info[NUM_SCREEN_SCROLLBUTTONS] =
{
{
- SC_SCROLLBUTTON_XPOS + 0 * SC_SCROLLBUTTON_XSIZE, SC_SCROLLBUTTON_YPOS,
- SC_SCROLL_UP_XPOS, SC_SCROLL_UP_YPOS,
+ IMG_MENU_BUTTON_UP, IMG_MENU_BUTTON_UP_ACTIVE,
+ SC_SCROLL_UP_XPOS, SC_SCROLL_UP_YPOS,
SCREEN_CTRL_ID_SCROLL_UP,
"scroll up"
},
{
- SC_SCROLLBUTTON_XPOS + 1 * SC_SCROLLBUTTON_XSIZE, SC_SCROLLBUTTON_YPOS,
- SC_SCROLL_DOWN_XPOS, SC_SCROLL_DOWN_YPOS,
+ IMG_MENU_BUTTON_DOWN, IMG_MENU_BUTTON_DOWN_ACTIVE,
+ SC_SCROLL_DOWN_XPOS, SC_SCROLL_DOWN_YPOS,
SCREEN_CTRL_ID_SCROLL_DOWN,
"scroll down"
}
static struct
{
- int xpos, ypos;
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ Bitmap **gfx_unpressed, **gfx_pressed;
+#else
+ int gfx_unpressed, gfx_pressed;
+#endif
int x, y;
int width, height;
int type;
} scrollbar_info[NUM_SCREEN_SCROLLBARS] =
{
{
- SC_SCROLLBAR_XPOS, SC_SCROLLBAR_YPOS,
- SX + SC_SCROLL_VERTICAL_XPOS, SY + SC_SCROLL_VERTICAL_YPOS,
- SC_SCROLL_VERTICAL_XSIZE, SC_SCROLL_VERTICAL_YSIZE,
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ &scrollbar_bitmap[0], &scrollbar_bitmap[1],
+#else
+ IMG_MENU_SCROLLBAR, IMG_MENU_SCROLLBAR_ACTIVE,
+#endif
+ SC_SCROLL_VERTICAL_XPOS, SC_SCROLL_VERTICAL_YPOS,
+ SC_SCROLL_VERTICAL_XSIZE, SC_SCROLL_VERTICAL_YSIZE,
GD_TYPE_SCROLLBAR_VERTICAL,
SCREEN_CTRL_ID_SCROLL_VERTICAL,
"scroll level series vertically"
static void CreateScreenScrollbuttons()
{
- Bitmap *gd_bitmap = pix[PIX_MORE];
struct GadgetInfo *gi;
unsigned long event_mask;
int i;
for (i=0; i<NUM_SCREEN_SCROLLBUTTONS; i++)
{
- int id = scrollbutton_info[i].gadget_id;
+ Bitmap *gd_bitmap_unpressed, *gd_bitmap_pressed;
+ int gfx_unpressed, gfx_pressed;
int x, y, width, height;
int gd_x1, gd_x2, gd_y1, gd_y2;
-
- x = scrollbutton_info[i].x;
- y = scrollbutton_info[i].y;
+ int id = scrollbutton_info[i].gadget_id;
event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED;
- x += SX;
- y += SY;
+ x = mSX + scrollbutton_info[i].x + menu.scrollbar_xoffset;
+ y = mSY + scrollbutton_info[i].y;
width = SC_SCROLLBUTTON_XSIZE;
height = SC_SCROLLBUTTON_YSIZE;
- gd_x1 = scrollbutton_info[i].xpos;
- gd_y1 = scrollbutton_info[i].ypos;
- gd_x2 = gd_x1;
- gd_y2 = gd_y1 + SC_SCROLLBUTTON_YSIZE;
+
+ if (id == SCREEN_CTRL_ID_SCROLL_DOWN)
+ y = mSY + (SC_SCROLL_VERTICAL_YPOS +
+ (NUM_MENU_ENTRIES_ON_SCREEN - 2) * SC_SCROLLBUTTON_YSIZE);
+
+ gfx_unpressed = scrollbutton_info[i].gfx_unpressed;
+ gfx_pressed = scrollbutton_info[i].gfx_pressed;
+ gd_bitmap_unpressed = graphic_info[gfx_unpressed].bitmap;
+ gd_bitmap_pressed = graphic_info[gfx_pressed].bitmap;
+ gd_x1 = graphic_info[gfx_unpressed].src_x;
+ gd_y1 = graphic_info[gfx_unpressed].src_y;
+ gd_x2 = graphic_info[gfx_pressed].src_x;
+ gd_y2 = graphic_info[gfx_pressed].src_y;
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
GDI_HEIGHT, height,
GDI_TYPE, GD_TYPE_NORMAL_BUTTON,
GDI_STATE, GD_BUTTON_UNPRESSED,
- GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
- GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2,
+ GDI_DESIGN_UNPRESSED, gd_bitmap_unpressed, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd_bitmap_pressed, gd_x2, gd_y2,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_ACTION, HandleScreenGadgets,
GDI_END);
for (i=0; i<NUM_SCREEN_SCROLLBARS; i++)
{
- int id = scrollbar_info[i].gadget_id;
- Bitmap *gd_bitmap = pix[PIX_MORE];
+ Bitmap *gd_bitmap_unpressed, *gd_bitmap_pressed;
+#if !defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ int gfx_unpressed, gfx_pressed;
+#endif
+ int x, y, width, height;
int gd_x1, gd_x2, gd_y1, gd_y2;
struct GadgetInfo *gi;
int items_max, items_visible, item_position;
unsigned long event_mask;
- int num_page_entries = MAX_MENU_ENTRIES_ON_SCREEN - 1;
+ int num_page_entries = NUM_MENU_ENTRIES_ON_SCREEN;
+ int id = scrollbar_info[i].gadget_id;
-#if 0
- if (num_leveldirs <= MAX_MENU_ENTRIES_ON_SCREEN)
- num_page_entries = num_leveldirs;
- else
- num_page_entries = MAX_MENU_ENTRIES_ON_SCREEN - 1;
+ event_mask = GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS;
+
+ x = mSX + scrollbar_info[i].x + menu.scrollbar_xoffset;
+ y = mSY + scrollbar_info[i].y;
+ width = scrollbar_info[i].width;
+ height = scrollbar_info[i].height;
+
+ if (id == SCREEN_CTRL_ID_SCROLL_VERTICAL)
+ height = (NUM_MENU_ENTRIES_ON_SCREEN - 2) * SC_SCROLLBUTTON_YSIZE;
- items_max = MAX(num_leveldirs, num_page_entries);
- items_visible = num_page_entries;
- item_position = 0;
-#else
items_max = num_page_entries;
items_visible = num_page_entries;
item_position = 0;
-#endif
- event_mask = GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS;
-
- gd_x1 = scrollbar_info[i].xpos;
- gd_x2 = gd_x1 + scrollbar_info[i].width;
- gd_y1 = scrollbar_info[i].ypos;
- gd_y2 = scrollbar_info[i].ypos;
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ gd_bitmap_unpressed = *scrollbar_info[i].gfx_unpressed;
+ gd_bitmap_pressed = *scrollbar_info[i].gfx_pressed;
+ gd_x1 = 0;
+ gd_y1 = 0;
+ gd_x2 = 0;
+ gd_y2 = 0;
+#else
+ gfx_unpressed = scrollbar_info[i].gfx_unpressed;
+ gfx_pressed = scrollbar_info[i].gfx_pressed;
+ gd_bitmap_unpressed = graphic_info[gfx_unpressed].bitmap;
+ gd_bitmap_pressed = graphic_info[gfx_pressed].bitmap;
+ gd_x1 = graphic_info[gfx_unpressed].src_x;
+ gd_y1 = graphic_info[gfx_unpressed].src_y;
+ gd_x2 = graphic_info[gfx_pressed].src_x;
+ gd_y2 = graphic_info[gfx_pressed].src_y;
+#endif
gi = CreateGadget(GDI_CUSTOM_ID, id,
GDI_CUSTOM_TYPE_ID, i,
GDI_INFO_TEXT, scrollbar_info[i].infotext,
- GDI_X, scrollbar_info[i].x,
- GDI_Y, scrollbar_info[i].y,
- GDI_WIDTH, scrollbar_info[i].width,
- GDI_HEIGHT, scrollbar_info[i].height,
+ GDI_X, x,
+ GDI_Y, y,
+ GDI_WIDTH, width,
+ GDI_HEIGHT, height,
GDI_TYPE, scrollbar_info[i].type,
GDI_SCROLLBAR_ITEMS_MAX, items_max,
GDI_SCROLLBAR_ITEMS_VISIBLE, items_visible,
GDI_SCROLLBAR_ITEM_POSITION, item_position,
GDI_STATE, GD_BUTTON_UNPRESSED,
- GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
- GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2,
- GDI_BORDER_SIZE, SC_BORDER_SIZE,
+ GDI_DESIGN_UNPRESSED, gd_bitmap_unpressed, gd_x1, gd_y1,
+ GDI_DESIGN_PRESSED, gd_bitmap_pressed, gd_x2, gd_y2,
+ GDI_BORDER_SIZE, SC_BORDER_SIZE, SC_BORDER_SIZE,
GDI_EVENT_MASK, event_mask,
GDI_CALLBACK_ACTION, HandleScreenGadgets,
GDI_END);
void CreateScreenGadgets()
{
+ int last_game_status = game_status; /* save current game status */
+
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ int i;
+
+ for (i=0; i < NUM_SCROLLBAR_BITMAPS; i++)
+ {
+ scrollbar_bitmap[i] = CreateBitmap(TILEX, TILEY, DEFAULT_DEPTH);
+
+ /* copy pointers to clip mask and GC */
+ scrollbar_bitmap[i]->clip_mask =
+ graphic_info[IMG_MENU_SCROLLBAR + i].clip_mask;
+ scrollbar_bitmap[i]->stored_clip_gc =
+ graphic_info[IMG_MENU_SCROLLBAR + i].clip_gc;
+
+ BlitBitmap(graphic_info[IMG_MENU_SCROLLBAR + i].bitmap,
+ scrollbar_bitmap[i],
+ graphic_info[IMG_MENU_SCROLLBAR + i].src_x,
+ graphic_info[IMG_MENU_SCROLLBAR + i].src_y,
+ TILEX, TILEY, 0, 0);
+ }
+#endif
+
+ /* force LEVELS draw offset for scrollbar / scrollbutton gadgets */
+ game_status = GAME_MODE_LEVELS;
+
CreateScreenScrollbuttons();
CreateScreenScrollbars();
+
+ game_status = last_game_status; /* restore current game status */
+}
+
+void FreeScreenGadgets()
+{
+ int i;
+
+#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
+ for (i=0; i < NUM_SCROLLBAR_BITMAPS; i++)
+ {
+ /* prevent freeing clip mask and GC twice */
+ scrollbar_bitmap[i]->clip_mask = None;
+ scrollbar_bitmap[i]->stored_clip_gc = None;
+
+ FreeBitmap(scrollbar_bitmap[i]);
+ }
+#endif
+
+ for (i=0; i<NUM_SCREEN_GADGETS; i++)
+ FreeGadget(screen_gadget[i]);
}
void MapChooseTreeGadgets(TreeInfo *ti)
int num_entries = numTreeInfoInGroup(ti);
int i;
- if (num_entries <= MAX_MENU_ENTRIES_ON_SCREEN)
+ if (num_entries <= NUM_MENU_ENTRIES_ON_SCREEN)
return;
for (i=0; i<NUM_SCREEN_GADGETS; i++)
{
int id = gi->custom_id;
- if (game_status != CHOOSELEVEL && game_status != SETUP)
+ if (game_status != GAME_MODE_LEVELS && game_status != GAME_MODE_SETUP)
return;
switch (id)
{
case SCREEN_CTRL_ID_SCROLL_UP:
- if (game_status == CHOOSELEVEL)
- HandleChooseLevel(SX,SY + 32, 0,0, MB_MENU_MARK);
- else if (game_status == SETUP)
- HandleSetupScreen(SX,SY + 32, 0,0, MB_MENU_MARK);
+ if (game_status == GAME_MODE_LEVELS)
+ HandleChooseLevel(0,0, 0, -1 * SCROLL_LINE, MB_MENU_MARK);
+ else if (game_status == GAME_MODE_SETUP)
+ HandleSetupScreen(0,0, 0, -1 * SCROLL_LINE, MB_MENU_MARK);
break;
case SCREEN_CTRL_ID_SCROLL_DOWN:
- if (game_status == CHOOSELEVEL)
- HandleChooseLevel(SX,SY + SYSIZE - 32, 0,0, MB_MENU_MARK);
- else if (game_status == SETUP)
- HandleSetupScreen(SX,SY + SYSIZE - 32, 0,0, MB_MENU_MARK);
+ if (game_status == GAME_MODE_LEVELS)
+ HandleChooseLevel(0,0, 0, +1 * SCROLL_LINE, MB_MENU_MARK);
+ else if (game_status == GAME_MODE_SETUP)
+ HandleSetupScreen(0,0, 0, +1 * SCROLL_LINE, MB_MENU_MARK);
break;
case SCREEN_CTRL_ID_SCROLL_VERTICAL:
- if (game_status == CHOOSELEVEL)
+ if (game_status == GAME_MODE_LEVELS)
HandleChooseLevel(0,0, 999,gi->event.item_position,MB_MENU_INITIALIZE);
- else if (game_status == SETUP)
+ else if (game_status == GAME_MODE_SETUP)
HandleSetupScreen(0,0, 999,gi->event.item_position,MB_MENU_INITIALIZE);
break;
#include "main.h"
+/* (randomly chosen) values for HandleChooseTree() */
+#define SCROLL_LINE (1 * SCR_FIELDY)
+#define SCROLL_PAGE (2 * SCR_FIELDY)
+
+
void DrawHeadline(void);
void DrawMainMenu(void);
void HandleGameActions(void);
void CreateScreenGadgets();
+void FreeScreenGadgets();
void MapChooseTreeGadgets(TreeInfo *);
void UnmapChooseTreeGadgets();
#include "libgame/libgame.h"
#include "tape.h"
+#include "init.h"
#include "game.h"
#include "tools.h"
#include "files.h"
#define VIDEO_DATE_LABEL_YPOS (VIDEO_DISPLAY1_YPOS)
#define VIDEO_DATE_LABEL_XSIZE (VIDEO_DISPLAY_XSIZE)
#define VIDEO_DATE_LABEL_YSIZE (VIDEO_DISPLAY_YSIZE)
-#define VIDEO_DATE_XPOS (VIDEO_DISPLAY1_XPOS + 1)
+#define VIDEO_DATE_XPOS (VIDEO_DISPLAY1_XPOS + 2)
#define VIDEO_DATE_YPOS (VIDEO_DISPLAY1_YPOS + 14)
#define VIDEO_DATE_XSIZE (VIDEO_DISPLAY_XSIZE)
#define VIDEO_DATE_YSIZE 16
#define VIDEO_PAUSE_SYMBOL_YPOS (VIDEO_DISPLAY2_YPOS)
#define VIDEO_PAUSE_SYMBOL_XSIZE 17
#define VIDEO_PAUSE_SYMBOL_YSIZE 13
-#define VIDEO_TIME_XPOS (VIDEO_DISPLAY2_XPOS + 38)
+#define VIDEO_TIME_XPOS (VIDEO_DISPLAY2_XPOS + 39)
#define VIDEO_TIME_YPOS (VIDEO_DISPLAY2_YPOS + 14)
#define VIDEO_TIME_XSIZE 50
#define VIDEO_TIME_YSIZE 16
{
int cx = DOOR_GFX_PAGEX3, cy = DOOR_GFX_PAGEY2;
- BlitBitmap(pix[PIX_DOOR], drawto,
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
cx + VIDEO_REC_LABEL_XPOS,
cy + VIDEO_REC_LABEL_YPOS,
VIDEO_PBEND_LABEL_XSIZE,
cx = DOOR_GFX_PAGEX3; /* i gerade => STATE_OFF / PRESS_ON */
if (video_pos[pos][part_label][0] && value != VIDEO_DISPLAY_SYMBOL_ONLY)
- BlitBitmap(pix[PIX_DOOR], drawto,
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
cx + video_pos[pos][part_label][xpos],
cy + video_pos[pos][part_label][ypos],
video_pos[pos][part_label][xsize],
VX + video_pos[pos][part_label][xpos],
VY + video_pos[pos][part_label][ypos]);
if (video_pos[pos][part_symbol][0] && value != VIDEO_DISPLAY_LABEL_ONLY)
- BlitBitmap(pix[PIX_DOOR], drawto,
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
cx + video_pos[pos][part_symbol][xpos],
cy + video_pos[pos][part_symbol][ypos],
video_pos[pos][part_symbol][xsize],
{
int cx = DOOR_GFX_PAGEX4, cy = DOOR_GFX_PAGEY2;
- BlitBitmap(pix[PIX_DOOR], drawto,
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
cx + VIDEO_PLAY_SYMBOL_XPOS,
cy + VIDEO_PLAY_SYMBOL_YPOS,
VIDEO_PLAY_SYMBOL_XSIZE - 2,
{
int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY1;
- BlitBitmap(pix[PIX_DOOR], drawto,
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
cx + VIDEO_PBEND_LABEL_XPOS,
cy + VIDEO_PBEND_LABEL_YPOS,
VIDEO_PBEND_LABEL_XSIZE,
int monat = (value/100) % 100;
int jahr = (value/10000);
- DrawText(VX+VIDEO_DATE_XPOS,VY+VIDEO_DATE_YPOS,
- int2str(tag,2),FS_SMALL,FC_SPECIAL1);
- DrawText(VX+VIDEO_DATE_XPOS+27,VY+VIDEO_DATE_YPOS,
- monatsname[monat],FS_SMALL,FC_SPECIAL1);
- DrawText(VX+VIDEO_DATE_XPOS+64,VY+VIDEO_DATE_YPOS,
- int2str(jahr,2),FS_SMALL,FC_SPECIAL1);
+ DrawText(VX + VIDEO_DATE_XPOS, VY + VIDEO_DATE_YPOS,
+ int2str(tag, 2), FONT_TAPE_RECORDER);
+ DrawText(VX + VIDEO_DATE_XPOS + 27, VY + VIDEO_DATE_YPOS,
+ monatsname[monat], FONT_TAPE_RECORDER);
+ DrawText(VX + VIDEO_DATE_XPOS + 64, VY + VIDEO_DATE_YPOS,
+ int2str(jahr, 2), FONT_TAPE_RECORDER);
}
if (state & VIDEO_STATE_TIME_ON)
int min = value / 60;
int sec = value % 60;
- DrawText(VX+VIDEO_TIME_XPOS,VY+VIDEO_TIME_YPOS,
- int2str(min,2),FS_SMALL,FC_SPECIAL1);
- DrawText(VX+VIDEO_TIME_XPOS+27,VY+VIDEO_TIME_YPOS,
- int2str(sec,2),FS_SMALL,FC_SPECIAL1);
+ DrawText(VX + VIDEO_TIME_XPOS, VY + VIDEO_TIME_YPOS,
+ int2str(min, 2), FONT_TAPE_RECORDER);
+ DrawText(VX + VIDEO_TIME_XPOS + 27, VY + VIDEO_TIME_YPOS,
+ int2str(sec, 2), FONT_TAPE_RECORDER);
}
if (state & VIDEO_STATE_DATE)
void DrawCompleteVideoDisplay()
{
- BlitBitmap(pix[PIX_DOOR], drawto, DOOR_GFX_PAGEX3, DOOR_GFX_PAGEY2,
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
+ DOOR_GFX_PAGEX3, DOOR_GFX_PAGEY2,
gfx.vxsize, gfx.vysize, gfx.vx, gfx.vy);
- BlitBitmap(pix[PIX_DOOR], drawto,
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
DOOR_GFX_PAGEX4 + VIDEO_CONTROL_XPOS,
DOOR_GFX_PAGEY2 + VIDEO_CONTROL_YPOS,
VIDEO_CONTROL_XSIZE, VIDEO_CONTROL_YSIZE,
DrawVideoDisplay(VIDEO_STATE_TIME_ON, tape.length_seconds);
}
- BlitBitmap(drawto, pix[PIX_DB_DOOR], gfx.vx, gfx.vy, gfx.vxsize, gfx.vysize,
+ BlitBitmap(drawto, bitmap_db_door, gfx.vx, gfx.vy, gfx.vxsize, gfx.vysize,
DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
}
tape.length = 0;
tape.counter = 0;
+ if (leveldir_current)
+ setString(&tape.level_identifier, leveldir_current->identifier);
+
tape.level_nr = level_nr;
tape.pos[tape.counter].delay = 0;
tape.changed = TRUE;
tape.game_version = GAME_VERSION_ACTUAL;
tape.engine_version = level.game_version;
+#if 0
+ printf("::: tape.engine_version = level.game_version = %d \n",
+ level.game_version);
+#endif
+
for(i=0; i<MAX_PLAYERS; i++)
tape.player_participates[i] = FALSE;
}
tape.playing = FALSE;
tape.fast_forward = FALSE;
tape.index_search = FALSE;
+ tape.auto_play = (global.autoplay_leveldir != NULL);
+ tape.auto_play_level_solved = FALSE;
tape.quick_resume = FALSE;
tape.single_step = FALSE;
else
#endif
{
- game_status = PLAYING;
+ game_status = GAME_MODE_PLAYING;
StopAnimation();
InitGame();
}
{
TapeStartPlaying();
- game_status = PLAYING;
+ game_status = GAME_MODE_PLAYING;
StopAnimation();
InitGame();
}
if (tape.counter >= tape.length) /* end of tape reached */
{
- if (tape.index_search)
+ if (tape.index_search && !tape.auto_play)
TapeTogglePause(TAPE_TOGGLE_MANUAL);
else
TapeStop();
DrawVideoDisplay(VIDEO_STATE_DATE_ON, tape.date);
DrawVideoDisplay(VIDEO_STATE_TIME_ON, tape.length_seconds);
}
+
+#if 0
+ if (tape.auto_play)
+ AutoPlayTape(); /* continue automatically playing next tape */
+#endif
}
unsigned int GetTapeLength()
{
tape.pausing = FALSE;
- SetDrawDeactivationMask(REDRAW_FIELD | REDRAW_DOOR_1);
+ SetDrawDeactivationMask(REDRAW_FIELD);
audio.sound_deactivated = TRUE;
}
}
void TapeQuickSave()
{
- if (game_status == PLAYING)
+ if (game_status == GAME_MODE_PLAYING)
{
if (tape.recording)
TapeHaltRecording(); /* prepare tape for saving on-the-fly */
else
SaveTape(tape.level_nr);
}
- else if (game_status == MAINMENU)
+ else if (game_status == GAME_MODE_MAIN)
Request("No game that can be saved !", REQ_CONFIRM);
}
void TapeQuickLoad()
{
- if (game_status == PLAYING || game_status == MAINMENU)
+ if (game_status == GAME_MODE_PLAYING || game_status == GAME_MODE_MAIN)
{
TapeStop();
TapeErase();
}
+/* ------------------------------------------------------------------------- *
+ * tape autoplay functions
+ * ------------------------------------------------------------------------- */
+
+#define MAX_NUM_AUTOPLAY_LEVELS 1000
+
+void AutoPlayTape()
+{
+ static LevelDirTree *autoplay_leveldir = NULL;
+ static boolean autoplay_initialized = FALSE;
+ 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];
+ int i;
+
+ if (autoplay_initialized)
+ {
+ /* just finished auto-playing tape */
+ 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
+ {
+ DrawCompleteVideoDisplay();
+ audio.sound_enabled = FALSE;
+
+ autoplay_leveldir = getTreeInfoFromIdentifier(leveldir_first,
+ global.autoplay_leveldir);
+
+ if (autoplay_leveldir == NULL)
+ Error(ERR_EXIT, "no such level identifier: '%s'",
+ global.autoplay_leveldir);
+
+ 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;
+ }
+
+ autoplay_level_nr = autoplay_leveldir->first_level;
+
+ printf_line("=", 79);
+ printf("Automatically playing level tapes\n");
+ printf_line("-", 79);
+ printf("Level series identifier: '%s'\n", autoplay_leveldir->identifier);
+ printf("Level series name: '%s'\n", autoplay_leveldir->name);
+ printf("Level series author: '%s'\n", autoplay_leveldir->author);
+ printf("Number of levels: %d\n", autoplay_leveldir->levels);
+ printf_line("=", 79);
+ printf("\n");
+
+ for (i=0; i<MAX_NUM_AUTOPLAY_LEVELS; i++)
+ levels_failed[i] = FALSE;
+
+ autoplay_initialized = TRUE;
+ }
+
+ while (autoplay_level_nr <= autoplay_leveldir->last_level)
+ {
+ level_nr = autoplay_level_nr++;
+
+ TapeErase();
+
+ printf("Level %03d: ", level_nr);
+
+ LoadLevel(level_nr);
+ if (level.no_level_file)
+ {
+ printf("(no level)\n");
+ continue;
+ }
+
+ LoadTape(level_nr);
+ if (TAPE_IS_EMPTY(tape))
+ {
+ printf("(no tape)\n");
+ continue;
+ }
+
+ printf("playing tape ... ");
+
+ TapeStartGamePlaying();
+ TapeStartIndexSearch();
+
+ return;
+ }
+
+ printf("\n");
+ printf_line("=", 79);
+ printf("Number of levels played: %d\n", num_levels_played);
+ printf("Number of levels solved: %d (%d%%)\n", num_levels_solved,
+ (num_levels_played ? num_levels_solved * 100 / num_levels_played :0));
+ printf_line("-", 79);
+ printf("Summary (for automatic parsing by scripts):\n");
+ printf("LEVELDIR '%s', SOLVED %d/%d (%d%%)",
+ autoplay_leveldir->identifier, num_levels_solved, num_levels_played,
+ (num_levels_played ? num_levels_solved * 100 / num_levels_played :0));
+ if (num_levels_played != num_levels_solved)
+ {
+ printf(", FAILED:");
+ for (i=0; i<MAX_NUM_AUTOPLAY_LEVELS; i++)
+ if (levels_failed[i])
+ printf(" %03d", i);
+ }
+ printf("\n");
+ printf_line("=", 79);
+
+ CloseAllAndExit(0);
+}
+
+
/* ---------- new tape button stuff ---------------------------------------- */
/* graphic position values for tape buttons */
for (i=0; i<NUM_TAPE_BUTTONS; i++)
{
- Bitmap *gd_bitmap = pix[PIX_DOOR];
+ Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
struct GadgetInfo *gi;
int gd_xoffset, gd_yoffset;
int gd_x1, gd_x2, gd_y;
}
}
+void FreeTapeButtons()
+{
+ int i;
+
+ for (i=0; i<NUM_TAPE_BUTTONS; i++)
+ FreeGadget(tape_gadget[i]);
+}
+
void MapTapeEjectButton()
{
UnmapGadget(tape_gadget[TAPE_CTRL_ID_INDEX]);
{
int id = gi->custom_id;
- if (game_status != MAINMENU && game_status != PLAYING)
+ if (game_status != GAME_MODE_MAIN && game_status != GAME_MODE_PLAYING)
return;
switch (id)
#define VIDEO_STATE_PBEND (VIDEO_STATE_PBEND_OFF | VIDEO_STATE_PBEND_ON)
/* tags to draw video display labels or symbols only */
+/* (negative values to prevent misinterpretation in DrawVideoDisplay(), where
+ the variable "value" is also used for tape length -- better fix this) */
#define VIDEO_DISPLAY_DEFAULT 0
-#define VIDEO_DISPLAY_LABEL_ONLY 1
-#define VIDEO_DISPLAY_SYMBOL_ONLY 2
+#define VIDEO_DISPLAY_LABEL_ONLY -1
+#define VIDEO_DISPLAY_SYMBOL_ONLY -2
void DrawVideoDisplay(unsigned long, unsigned long);
void TapeQuickSave(void);
void TapeQuickLoad(void);
+void AutoPlayTape(void);
+
void CreateTapeButtons();
+void FreeTapeButtons();
void MapTapeEjectButton();
void MapTapeIndexButton();
void MapTapeButtons();
#define NUM_TOOL_BUTTONS 7
/* forward declaration for internal use */
-static int getGraphicAnimationPhase(int, int, int);
-static void DrawGraphicAnimationShiftedThruMask(int, int, int, int, int,
- int, int, int);
static void UnmapToolButtons();
static void HandleToolButtons(struct GadgetInfo *);
+static int el_act_dir2crm(int, int, int);
static struct GadgetInfo *tool_gadget[NUM_TOOL_BUTTONS];
static int request_gadget_id = -1;
void RedrawPlayfield(boolean force_redraw, int x, int y, int width, int height)
{
- if (game_status == PLAYING)
+ if (game_status == GAME_MODE_PLAYING)
{
if (force_redraw)
{
int x,y;
DrawBuffer *buffer = (drawto_field == window ? backbuffer : drawto_field);
- if (setup.direct_draw && game_status == PLAYING)
+ if (setup.direct_draw && game_status == GAME_MODE_PLAYING)
redraw_mask &= ~REDRAW_MAIN;
if (redraw_mask & REDRAW_TILES && redraw_tiles > REDRAWTILES_THRESHOLD)
if (redraw_mask == REDRAW_NONE)
return;
- if (global.fps_slowdown && game_status == PLAYING)
+ if (global.fps_slowdown && game_status == GAME_MODE_PLAYING)
{
static boolean last_frame_skipped = FALSE;
boolean skip_even_when_not_scrolling = TRUE;
if (redraw_mask & REDRAW_FIELD)
{
- if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
+ if (game_status != GAME_MODE_PLAYING ||
+ redraw_mask & REDRAW_FROM_BACKBUFFER)
{
BlitBitmap(backbuffer, window,
REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE, REAL_SX, REAL_SY);
VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
}
}
+
if (redraw_mask & REDRAW_DOOR_3)
BlitBitmap(backbuffer, window, EX, EY, EXSIZE, EYSIZE, EX, EY);
+
redraw_mask &= ~REDRAW_DOORS;
}
if (redraw_mask & REDRAW_MICROLEVEL)
{
- BlitBitmap(backbuffer, window,
- MICROLEV_XPOS, MICROLEV_YPOS, MICROLEV_XSIZE, MICROLEV_YSIZE,
- MICROLEV_XPOS, MICROLEV_YPOS);
- BlitBitmap(backbuffer, window,
- SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE,
- SX, MICROLABEL_YPOS);
+ BlitBitmap(backbuffer, window, SX, SY + 10 * TILEY, SXSIZE, 7 * TILEY,
+ SX, SY + 10 * TILEY);
+
redraw_mask &= ~REDRAW_MICROLEVEL;
}
info1[0] = '\0';
sprintf(text, "%.1f fps%s", global.frames_per_second, info1);
- DrawTextExt(window, SX, SY, text, FS_SMALL, FC_YELLOW);
+ DrawTextExt(window, SX, SY, text, FONT_TEXT_2, BLIT_OPAQUE);
}
FlushDisplay();
BackToFront();
}
+void SetMainBackgroundImage(int graphic)
+{
+ SetMainBackgroundBitmap(graphic == IMG_UNDEFINED ? NULL :
+ graphic_info[graphic].bitmap ?
+ graphic_info[graphic].bitmap :
+ graphic_info[IMG_BACKGROUND].bitmap);
+}
+
+void SetDoorBackgroundImage(int graphic)
+{
+ SetDoorBackgroundBitmap(graphic == IMG_UNDEFINED ? NULL :
+ graphic_info[graphic].bitmap ?
+ graphic_info[graphic].bitmap :
+ graphic_info[IMG_BACKGROUND].bitmap);
+}
+
+void DrawBackground(int dest_x, int dest_y, int width, int height)
+{
+ ClearRectangleOnBackground(backbuffer, dest_x, dest_y, width, height);
+
+ redraw_mask |= REDRAW_FIELD;
+}
+
void ClearWindow()
{
- ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
+ DrawBackground(REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
- if (setup.soft_scrolling && game_status == PLAYING)
+ if (setup.soft_scrolling && game_status == GAME_MODE_PLAYING)
{
ClearRectangle(fieldbuffer, 0, 0, FXSIZE, FYSIZE);
SetDrawtoField(DRAW_BUFFERED);
else
SetDrawtoField(DRAW_BACKBUFFER);
- if (setup.direct_draw && game_status == PLAYING)
+ if (setup.direct_draw && game_status == GAME_MODE_PLAYING)
{
ClearRectangle(window, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
SetDrawtoField(DRAW_DIRECT);
}
-
- redraw_mask |= REDRAW_FIELD;
}
void MarkTileDirty(int x, int y)
{
int x, y;
- BorderElement = EL_LEERRAUM;
+ BorderElement = EL_EMPTY;
- for(y=0; y<lev_fieldy && BorderElement == EL_LEERRAUM; y++)
+ for(y=0; y<lev_fieldy && BorderElement == EL_EMPTY; y++)
{
for(x=0; x<lev_fieldx; x++)
{
- if (!IS_MASSIVE(Feld[x][y]))
- BorderElement = EL_BETON;
+ if (!IS_INDESTRUCTIBLE(Feld[x][y]))
+ BorderElement = EL_STEELWALL;
if (y != 0 && y != lev_fieldy - 1 && x != lev_fieldx - 1)
x = lev_fieldx - 2;
}
}
+void SetRandomAnimationValue(int x, int y)
+{
+ gfx.anim_random_frame = GfxRandom[x][y];
+}
+
+inline int getGraphicAnimationFrame(int graphic, int sync_frame)
+{
+ /* animation synchronized with global frame counter, not move position */
+ if (graphic_info[graphic].anim_global_sync || sync_frame < 0)
+ sync_frame = FrameCounter;
+
+ return getAnimationFrame(graphic_info[graphic].anim_frames,
+ graphic_info[graphic].anim_delay,
+ graphic_info[graphic].anim_mode,
+ graphic_info[graphic].anim_start_frame,
+ sync_frame);
+}
+
+inline void DrawGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y,
+ int graphic, int sync_frame, int mask_mode)
+{
+ int frame = getGraphicAnimationFrame(graphic, sync_frame);
+
+ if (mask_mode == USE_MASKING)
+ DrawGraphicThruMaskExt(dst_bitmap, x, y, graphic, frame);
+ else
+ DrawGraphicExt(dst_bitmap, x, y, graphic, frame);
+}
+
+inline void DrawGraphicAnimation(int x, int y, int graphic)
+{
+ int lx = LEVELX(x), ly = LEVELY(y);
+
+ if (!IN_SCR_FIELD(x, y))
+ return;
+
+ DrawGraphicAnimationExt(drawto_field, FX + x * TILEX, FY + y * TILEY,
+ graphic, GfxFrame[lx][ly], NO_MASKING);
+ MarkTileDirty(x, y);
+}
+
+void DrawLevelGraphicAnimation(int x, int y, int graphic)
+{
+ DrawGraphicAnimation(SCREENX(x), SCREENY(y), graphic);
+}
+
+void DrawLevelElementAnimation(int x, int y, int element)
+{
+#if 1
+ int graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]);
+
+ DrawGraphicAnimation(SCREENX(x), SCREENY(y), graphic);
+#else
+ DrawGraphicAnimation(SCREENX(x), SCREENY(y), el2img(element));
+#endif
+}
+
+inline void DrawLevelGraphicAnimationIfNeeded(int x, int y, int graphic)
+{
+ int sx = SCREENX(x), sy = SCREENY(y);
+
+ if (!IN_LEV_FIELD(x, y) || !IN_SCR_FIELD(sx, sy))
+ return;
+
+ if (!IS_NEW_FRAME(GfxFrame[x][y], graphic))
+ return;
+
+ DrawGraphicAnimation(sx, sy, graphic);
+
+ if (CAN_BE_CRUMBLED(Feld[x][y]))
+ DrawLevelFieldCrumbledSand(x, y);
+}
+
+void DrawLevelElementAnimationIfNeeded(int x, int y, int element)
+{
+ int sx = SCREENX(x), sy = SCREENY(y);
+ int graphic;
+
+ if (!IN_LEV_FIELD(x, y) || !IN_SCR_FIELD(sx, sy))
+ return;
+
+ graphic = el_act_dir2img(element, GfxAction[x][y], MovDir[x][y]);
+
+ if (!IS_NEW_FRAME(GfxFrame[x][y], graphic))
+ return;
+
+ DrawGraphicAnimation(sx, sy, graphic);
+
+ if (CAN_BE_CRUMBLED(element))
+ DrawLevelFieldCrumbledSand(x, y);
+}
+
void DrawAllPlayers()
{
int i;
void DrawPlayer(struct PlayerInfo *player)
{
+#if 0
int jx = player->jx, jy = player->jy;
int last_jx = player->last_jx, last_jy = player->last_jy;
int next_jx = jx + (jx - last_jx), next_jy = jy + (jy - last_jy);
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, phase;
+ int graphic;
+ int frame = 0;
boolean player_is_moving = (last_jx != jx || last_jy != jy ? TRUE : FALSE);
+ int move_dir = player->MovDir;
+ int action = ACTION_DEFAULT;
+#else
+ int jx = player->jx, jy = player->jy;
+ int move_dir = player->MovDir;
+ 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;
+ 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 frame = 0;
+ boolean player_is_moving = (player->MovPos ? TRUE : FALSE);
+ int action = ACTION_DEFAULT;
+#endif
if (!player->active || !IN_SCR_FIELD(SCREENX(last_jx), SCREENY(last_jy)))
return;
}
#endif
- if (element == EL_EXPLODING)
+ if (element == EL_EXPLOSION)
return;
- /* draw things in the field the player is leaving, if needed */
+ action = (player->Pushing ? ACTION_PUSHING :
+ player->is_digging ? ACTION_DIGGING :
+ player->is_collecting ? ACTION_COLLECTING :
+ player->is_moving ? ACTION_MOVING :
+ player->snapped ? ACTION_SNAPPING : ACTION_DEFAULT);
+
+ InitPlayerGfxAnimation(player, action, move_dir);
+
+ /* ----------------------------------------------------------------------- */
+ /* draw things in the field the player is leaving, if needed */
+ /* ----------------------------------------------------------------------- */
+#if 1
+ if (player->is_moving)
+#else
if (player_is_moving)
+#endif
{
- if (Store[last_jx][last_jy] && IS_DRAWABLE(last_element))
+ if (Back[last_jx][last_jy] && IS_DRAWABLE(last_element))
{
- DrawLevelElement(last_jx, last_jy, Store[last_jx][last_jy]);
- if (last_element == EL_DYNAMITE_ACTIVE)
+ 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);
}
- else if (last_element == EL_DYNAMITE_ACTIVE)
+ 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->Pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
{
+#if 1
+#if 1
+ DrawLevelElement(next_jx, next_jy, EL_EMPTY);
+#else
if (player->GfxPos)
{
- if (Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
- DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FELD_LEER);
+ if (Feld[next_jx][next_jy] == EL_SOKOBAN_FIELD_FULL)
+ DrawLevelElement(next_jx, next_jy, EL_SOKOBAN_FIELD_EMPTY);
else
- DrawLevelElement(next_jx, next_jy, EL_LEERRAUM);
+ DrawLevelElement(next_jx, next_jy, EL_EMPTY);
}
else
DrawLevelField(next_jx, next_jy);
+#endif
+#endif
}
}
if (setup.direct_draw)
SetDrawtoField(DRAW_BUFFERED);
- /* draw things behind the player, if needed */
+ /* ----------------------------------------------------------------------- */
+ /* draw things behind the player, if needed */
+ /* ----------------------------------------------------------------------- */
- if (Store[jx][jy])
- DrawLevelElement(jx, jy, Store[jx][jy]);
- else if (!IS_ACTIVE_BOMB(element))
- DrawLevelField(jx, jy);
+ if (Back[jx][jy])
+ DrawLevelElement(jx, jy, Back[jx][jy]);
+ else if (IS_ACTIVE_BOMB(element))
+ DrawLevelElement(jx, jy, EL_EMPTY);
else
- DrawLevelElement(jx, jy, EL_LEERRAUM);
-
- /* draw player himself */
-
- if (game.emulation == EMU_SUPAPLEX)
{
- static int last_dir = MV_LEFT;
- int action = (player->programmed_action ? player->programmed_action :
- player->action);
- boolean action_moving =
- (player_is_moving ||
- ((action & (MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN)) &&
- !(action & ~(MV_LEFT | MV_RIGHT | MV_UP | MV_DOWN))));
-
- graphic = GFX_SP_MURPHY;
-
- if (player->Pushing)
+ if (player_is_moving && GfxElement[jx][jy] != EL_UNDEFINED)
{
- if (player->MovDir == MV_LEFT)
- graphic = GFX_MURPHY_PUSH_LEFT;
- else if (player->MovDir == MV_RIGHT)
- graphic = GFX_MURPHY_PUSH_RIGHT;
- else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
- graphic = GFX_MURPHY_PUSH_LEFT;
- else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
- graphic = GFX_MURPHY_PUSH_RIGHT;
- }
- else if (player->snapped)
- {
- if (player->MovDir == MV_LEFT)
- graphic = GFX_MURPHY_SNAP_LEFT;
- else if (player->MovDir == MV_RIGHT)
- graphic = GFX_MURPHY_SNAP_RIGHT;
- else if (player->MovDir == MV_UP)
- graphic = GFX_MURPHY_SNAP_UP;
- else if (player->MovDir == MV_DOWN)
- graphic = GFX_MURPHY_SNAP_DOWN;
- }
- else if (action_moving)
- {
- if (player->MovDir == MV_LEFT)
- graphic = GFX_MURPHY_GO_LEFT;
- else if (player->MovDir == MV_RIGHT)
- graphic = GFX_MURPHY_GO_RIGHT;
- else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_LEFT)
- graphic = GFX_MURPHY_GO_LEFT;
- else if (player->MovDir & (MV_UP | MV_DOWN) && last_dir == MV_RIGHT)
- graphic = GFX_MURPHY_GO_RIGHT;
+#if 1
+ if (CAN_BE_CRUMBLED(GfxElement[jx][jy]))
+ DrawLevelFieldCrumbledSandDigging(jx, jy, move_dir, player->StepFrame);
+#else
+ if (GfxElement[jx][jy] == EL_SAND)
+ DrawLevelFieldCrumbledSandDigging(jx, jy, move_dir, player->StepFrame);
+#endif
else
- graphic = GFX_MURPHY_GO_LEFT;
+ {
+ int old_element = GfxElement[jx][jy];
+ int old_graphic = el_act_dir2img(old_element, action, move_dir);
+ int frame = getGraphicAnimationFrame(old_graphic, player->StepFrame);
- graphic += getGraphicAnimationPhase(3, 2, ANIM_OSCILLATE);
+ DrawGraphic(sx, sy, old_graphic, frame);
+ }
}
+ else
+ {
+ GfxElement[jx][jy] = EL_UNDEFINED;
- if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
- last_dir = player->MovDir;
+ DrawLevelField(jx, jy);
+ }
}
- else
+
+ /* ----------------------------------------------------------------------- */
+ /* draw player himself */
+ /* ----------------------------------------------------------------------- */
+
+ if (player->use_murphy_graphic)
{
- if (player->MovDir == MV_LEFT)
- graphic =
- (player->Pushing ? GFX_SPIELER1_PUSH_LEFT : GFX_SPIELER1_LEFT);
- else if (player->MovDir == MV_RIGHT)
- graphic =
- (player->Pushing ? GFX_SPIELER1_PUSH_RIGHT : GFX_SPIELER1_RIGHT);
- else if (player->MovDir == MV_UP)
- graphic = GFX_SPIELER1_UP;
- else /* MV_DOWN || MV_NO_MOVING */
- graphic = GFX_SPIELER1_DOWN;
+ static int last_horizontal_dir = MV_LEFT;
+ int direction;
+
+ if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
+ last_horizontal_dir = move_dir;
- graphic += player->index_nr * 3 * HEROES_PER_LINE;
- graphic += player->Frame;
+ direction = (player->snapped ? move_dir : last_horizontal_dir);
+
+ graphic = el_act_dir2img(EL_SP_MURPHY, player->GfxAction, direction);
}
+ else
+ graphic = el_act_dir2img(player->element_nr, player->GfxAction, move_dir);
+
+ frame = getGraphicAnimationFrame(graphic, player->Frame);
if (player->GfxPos)
{
- if (player->MovDir == MV_LEFT || player->MovDir == MV_RIGHT)
+ if (move_dir == MV_LEFT || move_dir == MV_RIGHT)
sxx = player->GfxPos;
else
syy = player->GfxPos;
if (!setup.soft_scrolling && ScreenMovPos)
sxx = syy = 0;
- DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, NO_CUTTING);
+ DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING);
if (SHIELD_ON(player))
{
- int graphic = (player->shield_active_time_left ? GFX2_SHIELD_ACTIVE :
- GFX2_SHIELD_PASSIVE);
+ int graphic = (player->shield_deadly_time_left ? IMG_SHIELD_DEADLY_ACTIVE :
+ IMG_SHIELD_NORMAL_ACTIVE);
+ int frame = getGraphicAnimationFrame(graphic, -1);
- DrawGraphicAnimationShiftedThruMask(sx, sy, sxx, syy, graphic,
- 3, 8, ANIM_OSCILLATE);
+ DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic, frame, NO_CUTTING);
}
- if (player->Pushing && player->GfxPos)
+ /* ----------------------------------------------------------------------- */
+ /* draw things the player is pushing, if needed */
+ /* ----------------------------------------------------------------------- */
+
+#if 0
+ printf("::: %d, %d [%d, %d] [%d]\n",
+ player->Pushing, player_is_moving, player->GfxAction,
+ player->is_moving, player_is_moving);
+#endif
+
+#if 1
+ if (player->Pushing && player->is_moving)
+#else
+ if (player->Pushing && player_is_moving)
+#endif
{
int px = SCREENX(next_jx), py = SCREENY(next_jy);
- if (element == EL_SOKOBAN_FELD_LEER ||
- Feld[next_jx][next_jy] == EL_SOKOBAN_FELD_VOLL)
- DrawGraphicShiftedThruMask(px, py, sxx, syy, GFX_SOKOBAN_OBJEKT,
+ if (Back[next_jx][next_jy])
+ DrawLevelElement(next_jx, next_jy, Back[next_jx][next_jy]);
+
+#if 1
+ if ((sxx || syy) && element == EL_SOKOBAN_OBJECT)
+ DrawGraphicShiftedThruMask(px, py, sxx, syy, IMG_SOKOBAN_OBJECT, 0,
NO_CUTTING);
+#else
+ if ((sxx || syy) &&
+ (element == EL_SOKOBAN_FIELD_EMPTY ||
+ Feld[next_jx][next_jy] == EL_SOKOBAN_FIELD_FULL))
+ DrawGraphicShiftedThruMask(px, py, sxx, syy, IMG_SOKOBAN_OBJECT, 0,
+ NO_CUTTING);
+#endif
else
{
+#if 1
+ int element = MovingOrBlocked2Element(next_jx, next_jy);
+#else
+#if 1
+ int element = Feld[jx][jy];
+#else
int element = Feld[next_jx][next_jy];
- int graphic = el2gfx(element);
+#endif
+#endif
- if ((element == EL_FELSBROCKEN ||
- element == EL_SP_ZONK ||
- element == EL_BD_ROCK) && sxx)
- {
- int phase = (player->GfxPos / (TILEX / 4));
+#if 1
+ int graphic = el2img(element);
+ int frame = 0;
- if (player->MovDir == MV_LEFT)
- graphic += phase;
- else
- graphic += (phase + 4) % 4;
+#if 0
+ if ((sxx || syy) && IS_PUSHABLE(element))
+#endif
+ {
+ graphic = el_act_dir2img(element, ACTION_PUSHING, move_dir);
+ frame = getGraphicAnimationFrame(graphic, player->Frame);
}
- DrawGraphicShifted(px, py, sxx, syy, graphic, NO_CUTTING, NO_MASKING);
+#if 0
+ printf("::: pushing %d: %d ...\n", sxx, frame);
+#endif
+
+ DrawGraphicShifted(px, py, sxx, syy, graphic, frame,
+ NO_CUTTING, NO_MASKING);
+#endif
}
}
- /* draw things in front of player (active dynamite or dynabombs) */
+ /* ----------------------------------------------------------------------- */
+ /* draw things in front of player (active dynamite or dynabombs) */
+ /* ----------------------------------------------------------------------- */
if (IS_ACTIVE_BOMB(element))
{
- graphic = el2gfx(element);
-
- if (element == EL_DYNAMITE_ACTIVE)
- {
- if ((phase = (96 - MovDelay[jx][jy]) / 12) > 6)
- phase = 6;
- }
- else
- {
- if ((phase = ((96 - MovDelay[jx][jy]) / 6) % 8) > 3)
- phase = 7 - phase;
- }
+ graphic = el2img(element);
+ frame = getGraphicAnimationFrame(graphic, GfxFrame[jx][jy]);
if (game.emulation == EMU_SUPAPLEX)
- DrawGraphic(sx, sy, GFX_SP_DISK_RED);
+ DrawGraphic(sx, sy, IMG_SP_DISK_RED, frame);
else
- DrawGraphicThruMask(sx, sy, graphic + phase);
+ DrawGraphicThruMask(sx, sy, graphic, frame);
}
- if (player_is_moving && last_element == EL_EXPLODING)
+ if (player_is_moving && last_element == EL_EXPLOSION)
{
- int phase = Frame[last_jx][last_jy];
- int delay = 2;
+#if 1
+ int graphic = el_act2img(GfxElement[last_jx][last_jy], ACTION_EXPLODING);
+#else
+ int stored = Store[last_jx][last_jy];
+ int graphic = (game.emulation != EMU_SUPAPLEX ? IMG_EXPLOSION :
+ stored == EL_SP_INFOTRON ? IMG_SP_EXPLOSION_INFOTRON :
+ IMG_SP_EXPLOSION);
+#endif
+ int delay = (game.emulation == EMU_SUPAPLEX ? 3 : 2);
+ int phase = ExplodePhase[last_jx][last_jy] - 1;
+ int frame = getGraphicAnimationFrame(graphic, phase - delay);
- if (phase > 2)
- DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy),
- GFX_EXPLOSION + ((phase - 1) / delay - 1));
+ if (phase >= delay)
+ DrawGraphicThruMask(SCREENX(last_jx), SCREENY(last_jy), graphic, frame);
}
- /* draw elements that stay over the player */
+ /* ----------------------------------------------------------------------- */
+ /* draw elements the player is just walking/passing through/under */
+ /* ----------------------------------------------------------------------- */
+
/* handle the field the player is leaving ... */
- if (player_is_moving && IS_OVER_PLAYER(last_element))
+ if (player_is_moving && IS_ACCESSIBLE_INSIDE(last_element))
DrawLevelField(last_jx, last_jy);
+ else if (player_is_moving && IS_ACCESSIBLE_UNDER(last_element))
+ DrawLevelFieldThruMask(last_jx, last_jy);
+
/* ... and the field the player is entering */
- if (IS_OVER_PLAYER(element))
+ if (IS_ACCESSIBLE_INSIDE(element))
DrawLevelField(jx, jy);
+ else if (IS_ACCESSIBLE_UNDER(element))
+ DrawLevelFieldThruMask(jx, jy);
if (setup.direct_draw)
{
MarkTileDirty(sx,sy);
}
-static int getGraphicAnimationPhase(int frames, int delay, int mode)
+void getGraphicSource(int graphic, int frame, Bitmap **bitmap, int *x, int *y)
{
- int phase;
+ struct GraphicInfo *g = &graphic_info[graphic];
- if (mode == ANIM_OSCILLATE)
- {
- int max_anim_frames = 2 * frames - 2;
- phase = (FrameCounter % (delay * max_anim_frames)) / delay;
- phase = (phase < frames ? phase : max_anim_frames - phase);
- }
- else
- phase = (FrameCounter % (delay * frames)) / delay;
-
- if (mode == ANIM_REVERSE)
- phase = -phase;
+ *bitmap = g->bitmap;
- return(phase);
-}
-
-void DrawGraphicAnimationExt(int x, int y, int graphic,
- int frames, int delay, int mode, int mask_mode)
-{
- int phase = getGraphicAnimationPhase(frames, delay, mode);
-
- if (!(FrameCounter % delay) && IN_SCR_FIELD(SCREENX(x), SCREENY(y)))
+ if (g->offset_y == 0) /* frames are ordered horizontally */
{
- if (mask_mode == USE_MASKING)
- DrawGraphicThruMask(SCREENX(x), SCREENY(y), graphic + phase);
- else
- DrawGraphic(SCREENX(x), SCREENY(y), graphic + phase);
- }
-}
-
-void DrawGraphicAnimation(int x, int y, int graphic,
- int frames, int delay, int mode)
-{
- DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, NO_MASKING);
-}
-
-void DrawGraphicAnimationThruMask(int x, int y, int graphic,
- int frames, int delay, int mode)
-{
- DrawGraphicAnimationExt(x, y, graphic, frames, delay, mode, USE_MASKING);
-}
-
-static void DrawGraphicAnimationShiftedThruMask(int sx, int sy,
- int sxx, int syy,
- int graphic,
- int frames, int delay,
- int mode)
-{
- int phase = getGraphicAnimationPhase(frames, delay, mode);
-
- DrawGraphicShiftedThruMask(sx, sy, sxx, syy, graphic + phase, NO_CUTTING);
-}
+ int max_width = g->anim_frames_per_line * g->width;
-void getGraphicSource(int graphic, int *bitmap_nr, int *x, int *y)
-{
- if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
- {
- graphic -= GFX_START_ROCKSSCREEN;
- *bitmap_nr = PIX_BACK;
- *x = SX + (graphic % GFX_PER_LINE) * TILEX;
- *y = SY + (graphic / GFX_PER_LINE) * TILEY;
+ *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 (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
+ else if (g->offset_x == 0) /* frames are ordered vertically */
{
- graphic -= GFX_START_ROCKSHEROES;
- *bitmap_nr = PIX_HEROES;
- *x = (graphic % HEROES_PER_LINE) * TILEX;
- *y = (graphic / HEROES_PER_LINE) * TILEY;
- }
- else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
- {
- graphic -= GFX_START_ROCKSSP;
- *bitmap_nr = PIX_SP;
- *x = (graphic % SP_PER_LINE) * TILEX;
- *y = (graphic / SP_PER_LINE) * TILEY;
- }
- else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
- {
- graphic -= GFX_START_ROCKSDC;
- *bitmap_nr = PIX_DC;
- *x = (graphic % DC_PER_LINE) * TILEX;
- *y = (graphic / DC_PER_LINE) * TILEY;
- }
- else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
- {
- graphic -= GFX_START_ROCKSMORE;
- *bitmap_nr = PIX_MORE;
- *x = (graphic % MORE_PER_LINE) * TILEX;
- *y = (graphic / MORE_PER_LINE) * TILEY;
- }
- else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
- {
- graphic -= GFX_START_ROCKSFONT;
- *bitmap_nr = PIX_BIGFONT;
- *x = (graphic % FONT_CHARS_PER_LINE) * TILEX;
- *y = ((graphic / FONT_CHARS_PER_LINE) * TILEY +
- FC_SPECIAL1 * FONT_LINES_PER_FONT * TILEY);
+ int max_height = g->anim_frames_per_line * g->height;
+
+ *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
+ else /* frames are ordered diagonally */
{
- *bitmap_nr = PIX_SP;
- *x = 0;
- *y = 0;
+ *x = g->src_x + frame * g->offset_x;
+ *y = g->src_y + frame * g->offset_y;
}
}
-void DrawGraphic(int x, int y, int graphic)
+void DrawGraphic(int x, int y, int graphic, int frame)
{
#if DEBUG
- if (!IN_SCR_FIELD(x,y))
+ if (!IN_SCR_FIELD(x, y))
{
- printf("DrawGraphic(): x = %d, y = %d, graphic = %d\n",x,y,graphic);
+ 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);
- MarkTileDirty(x,y);
+ DrawGraphicExt(drawto_field, FX + x * TILEX, FY + y * TILEY, graphic, frame);
+ MarkTileDirty(x, y);
}
-void DrawGraphicExt(DrawBuffer *bitmap, int x, int y, int graphic)
+void DrawGraphicExt(DrawBuffer *dst_bitmap, int x, int y, int graphic,
+ int frame)
{
- int bitmap_nr;
+ Bitmap *src_bitmap;
int src_x, src_y;
- getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
- BlitBitmap(pix[bitmap_nr], bitmap, src_x, src_y, TILEX, TILEY, x, y);
+ getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
+ BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, TILEX, TILEY, x, y);
}
-void DrawGraphicThruMask(int x, int y, int graphic)
+void DrawGraphicThruMask(int x, int y, int graphic, int frame)
{
#if DEBUG
- if (!IN_SCR_FIELD(x,y))
+ 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");
}
#endif
- DrawGraphicThruMaskExt(drawto_field, FX + x*TILEX, FY + y*TILEY, graphic);
- MarkTileDirty(x,y);
+ 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)
+void DrawGraphicThruMaskExt(DrawBuffer *d, int dest_x, int dest_y, int graphic,
+ int frame)
{
- int tile = graphic;
- int bitmap_nr;
- int src_x, src_y;
+#if 1
Bitmap *src_bitmap;
+ int src_x, src_y;
GC drawing_gc;
- if (graphic == GFX_LEERRAUM)
- return;
+ getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
+ drawing_gc = src_bitmap->stored_clip_gc;
+#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;
- getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
- src_bitmap = pix[bitmap_nr];
- drawing_gc = pix[bitmap_nr]->stored_clip_gc;
+ src_x += frame * offset_x;
+ src_y += frame * offset_y;
- if (tile_clipmask[tile] != None)
- {
- SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
- SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
- BlitBitmapMasked(src_bitmap, d,
- src_x, src_y, TILEX, TILEY, dest_x, dest_y);
- }
- else
- {
-#if DEBUG
-#ifndef TARGET_SDL
- printf("DrawGraphicThruMask(): tile '%d' needs clipping!\n", tile);
-#endif
#endif
- 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);
- }
+ 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);
}
void DrawMiniGraphic(int x, int y, int graphic)
{
- DrawMiniGraphicExt(drawto, SX + x*MINI_TILEX, SY + y*MINI_TILEY, graphic);
- MarkTileDirty(x/2, y/2);
+ 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)
{
- if (graphic >= GFX_START_ROCKSSCREEN && graphic <= GFX_END_ROCKSSCREEN)
- {
- graphic -= GFX_START_ROCKSSCREEN;
- *bitmap = pix[PIX_BACK];
- *x = MINI_GFX_STARTX + (graphic % MINI_GFX_PER_LINE) * MINI_TILEX;
- *y = MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY;
- }
- else if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
- {
- graphic -= GFX_START_ROCKSSP;
- graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
- *bitmap = pix[PIX_SP];
- *x = MINI_SP_STARTX + (graphic % MINI_SP_PER_LINE) * MINI_TILEX;
- *y = MINI_SP_STARTY + (graphic / MINI_SP_PER_LINE) * MINI_TILEY;
- }
- else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
- {
- graphic -= GFX_START_ROCKSDC;
- *bitmap = pix[PIX_DC];
- *x = MINI_DC_STARTX + (graphic % MINI_DC_PER_LINE) * MINI_TILEX;
- *y = MINI_DC_STARTY + (graphic / MINI_DC_PER_LINE) * MINI_TILEY;
- }
- else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
- {
- graphic -= GFX_START_ROCKSMORE;
- *bitmap = pix[PIX_MORE];
- *x = MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX;
- *y = MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY;
- }
- else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
- {
- graphic -= GFX_START_ROCKSFONT;
- *bitmap = pix[PIX_SMALLFONT];
- *x = (graphic % FONT_CHARS_PER_LINE) * FONT4_XSIZE;
- *y = ((graphic / FONT_CHARS_PER_LINE) * FONT4_YSIZE +
- FC_SPECIAL2 * FONT2_YSIZE * FONT_LINES_PER_FONT);
- }
- else
- {
- *bitmap = pix[PIX_SP];
- *x = MINI_SP_STARTX;
- *y = MINI_SP_STARTY;
- }
+ 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 DrawMiniGraphicExt(DrawBuffer *d, int x, int y, int graphic)
{
- Bitmap *bitmap;
+ Bitmap *src_bitmap;
int src_x, src_y;
- getMiniGraphicSource(graphic, &bitmap, &src_x, &src_y);
- BlitBitmap(bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
+ getMiniGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
+ BlitBitmap(src_bitmap, d, src_x, src_y, MINI_TILEX, MINI_TILEY, x, y);
}
-void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
+void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic, int frame,
int cut_mode, int mask_mode)
{
- int width = TILEX, height = TILEY;
- int cx = 0, cy = 0;
- int src_x, src_y, dest_x, dest_y;
- int tile = graphic;
- int bitmap_nr;
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;
if (graphic < 0)
{
- DrawGraphic(x, y, graphic);
+ DrawGraphic(x, y, graphic, frame);
return;
}
- if (dx || dy) /* Verschiebung der Grafik? */
+ if (dx || dy) /* shifted graphic */
{
- if (x < BX1) /* Element kommt von links ins Bild */
+ if (x < BX1) /* object enters playfield from the left */
{
x = BX1;
width = dx;
cx = TILEX - dx;
dx = 0;
}
- else if (x > BX2) /* Element kommt von rechts ins Bild */
+ else if (x > BX2) /* object enters playfield from the right */
{
x = BX2;
width = -dx;
dx = TILEX + dx;
}
- else if (x==BX1 && dx < 0) /* Element verläßt links das Bild */
+ else if (x==BX1 && dx < 0) /* object leaves playfield to the left */
{
width += dx;
cx = -dx;
dx = 0;
}
- else if (x==BX2 && dx > 0) /* Element verläßt rechts das Bild */
+ else if (x==BX2 && dx > 0) /* object leaves playfield to the right */
width -= dx;
- else if (dx) /* allg. Bewegung in x-Richtung */
+ else if (dx) /* general horizontal movement */
MarkTileDirty(x + SIGN(dx), y);
- if (y < BY1) /* Element kommt von oben ins Bild */
+ if (y < BY1) /* object enters playfield from the top */
{
- if (cut_mode==CUT_BELOW) /* Element oberhalb des Bildes */
+ if (cut_mode==CUT_BELOW) /* object completely above top border */
return;
y = BY1;
cy = TILEY - dy;
dy = 0;
}
- else if (y > BY2) /* Element kommt von unten ins Bild */
+ else if (y > BY2) /* object enters playfield from the bottom */
{
y = BY2;
height = -dy;
dy = TILEY + dy;
}
- else if (y==BY1 && dy < 0) /* Element verläßt oben das Bild */
+ else if (y==BY1 && dy < 0) /* object leaves playfield to the top */
{
height += dy;
cy = -dy;
}
else if (dy > 0 && cut_mode == CUT_ABOVE)
{
- if (y == BY2) /* Element unterhalb des Bildes */
+ if (y == BY2) /* object completely above bottom border */
return;
height = dy;
cy = TILEY - dy;
dy = TILEY;
MarkTileDirty(x, y + 1);
- } /* Element verläßt unten das Bild */
+ } /* object leaves playfield to the bottom */
else if (dy > 0 && (y == BY2 || cut_mode == CUT_BELOW))
height -= dy;
- else if (dy) /* allg. Bewegung in y-Richtung */
+ else if (dy) /* general vertical movement */
MarkTileDirty(x, y + SIGN(dy));
}
- getGraphicSource(graphic, &bitmap_nr, &src_x, &src_y);
- src_bitmap = pix[bitmap_nr];
- drawing_gc = pix[bitmap_nr]->stored_clip_gc;
+#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
+
+ drawing_gc = src_bitmap->stored_clip_gc;
src_x += cx;
src_y += cy;
if (mask_mode == USE_MASKING)
{
- if (tile_clipmask[tile] != None)
- {
- SetClipMask(src_bitmap, tile_clip_gc, tile_clipmask[tile]);
- SetClipOrigin(src_bitmap, tile_clip_gc, dest_x, dest_y);
- BlitBitmapMasked(src_bitmap, drawto_field,
- src_x, src_y, TILEX, TILEY, dest_x, dest_y);
- }
- else
- {
-#if DEBUG
-#ifndef TARGET_SDL
- printf("DrawGraphicShifted(): tile '%d' needs clipping!\n", tile);
-#endif
-#endif
-
- 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);
- }
+ 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);
}
else
- BlitBitmap(pix[bitmap_nr], drawto_field,
- src_x, src_y, width, height, dest_x, dest_y);
+ BlitBitmap(src_bitmap, drawto_field, src_x, src_y, width, height,
+ dest_x, dest_y);
MarkTileDirty(x,y);
}
-void DrawGraphicShiftedThruMask(int x,int y, int dx,int dy, int graphic,
- int cut_mode)
+void DrawGraphicShiftedThruMask(int x, int y, int dx, int dy, int graphic,
+ int frame, int cut_mode)
{
- DrawGraphicShifted(x,y, dx,dy, graphic, cut_mode, USE_MASKING);
+ DrawGraphicShifted(x,y, dx,dy, graphic, frame, cut_mode, USE_MASKING);
}
void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
int cut_mode, int mask_mode)
{
- int ux = LEVELX(x), uy = LEVELY(y);
- int graphic = el2gfx(element);
- int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
- int phase4 = phase8 / 2;
- int phase2 = phase8 / 4;
- int dir = MovDir[ux][uy];
-
- if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
- {
- graphic += 4 * !phase2;
+ int lx = LEVELX(x), ly = LEVELY(y);
+ int graphic;
+ int frame;
- if (dir == MV_UP)
- graphic += 1;
- else if (dir == MV_LEFT)
- graphic += 2;
- else if (dir == MV_DOWN)
- graphic += 3;
- }
- else if (element == EL_SP_SNIKSNAK)
+ if (IN_LEV_FIELD(lx, ly))
{
- if (dir == MV_LEFT)
- graphic = GFX_SP_SNIKSNAK_LEFT;
- else if (dir == MV_RIGHT)
- graphic = GFX_SP_SNIKSNAK_RIGHT;
- else if (dir == MV_UP)
- graphic = GFX_SP_SNIKSNAK_UP;
- else
- graphic = GFX_SP_SNIKSNAK_DOWN;
+ SetRandomAnimationValue(lx, ly);
- graphic += (phase8 < 4 ? phase8 : 7 - phase8);
+ graphic = el_act_dir2img(element, GfxAction[lx][ly], MovDir[lx][ly]);
+ frame = getGraphicAnimationFrame(graphic, GfxFrame[lx][ly]);
}
- else if (element == EL_SP_ELECTRON)
+ else /* border element */
{
- graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
+ graphic = el2img(element);
+ frame = getGraphicAnimationFrame(graphic, -1);
}
- else if (element == EL_MOLE || element == EL_PINGUIN ||
- element == EL_SCHWEIN || element == EL_DRACHE)
- {
- if (dir == MV_LEFT)
- graphic = (element == EL_MOLE ? GFX_MOLE_LEFT :
- element == EL_PINGUIN ? GFX_PINGUIN_LEFT :
- element == EL_SCHWEIN ? GFX_SCHWEIN_LEFT : GFX_DRACHE_LEFT);
- else if (dir == MV_RIGHT)
- graphic = (element == EL_MOLE ? GFX_MOLE_RIGHT :
- element == EL_PINGUIN ? GFX_PINGUIN_RIGHT :
- element == EL_SCHWEIN ? GFX_SCHWEIN_RIGHT : GFX_DRACHE_RIGHT);
- else if (dir == MV_UP)
- graphic = (element == EL_MOLE ? GFX_MOLE_UP :
- element == EL_PINGUIN ? GFX_PINGUIN_UP :
- element == EL_SCHWEIN ? GFX_SCHWEIN_UP : GFX_DRACHE_UP);
- else
- graphic = (element == EL_MOLE ? GFX_MOLE_DOWN :
- element == EL_PINGUIN ? GFX_PINGUIN_DOWN :
- element == EL_SCHWEIN ? GFX_SCHWEIN_DOWN : GFX_DRACHE_DOWN);
- graphic += phase4;
- }
- else if (element == EL_SONDE)
- {
- graphic = GFX_SONDE_START + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
- }
- else if (element == EL_SALZSAEURE)
- {
- graphic = GFX_GEBLUBBER + getGraphicAnimationPhase(4, 10, ANIM_NORMAL);
- }
- else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
- {
- graphic += !phase2;
- }
- else if (element == EL_BALLOON)
- {
- graphic += phase4;
- }
- else if ((element == EL_FELSBROCKEN ||
- element == EL_SP_ZONK ||
- element == EL_BD_ROCK ||
- element == EL_SP_INFOTRON ||
- IS_GEM(element))
- && !cut_mode)
- {
- if (uy >= lev_fieldy-1 || !IS_BELT(Feld[ux][uy+1]))
- {
- if (element == EL_FELSBROCKEN ||
- element == EL_SP_ZONK ||
- element == EL_BD_ROCK)
- {
- if (dir == MV_LEFT)
- graphic += (4 - phase4) % 4;
- else if (dir == MV_RIGHT)
- graphic += phase4;
- else
- graphic += phase2 * 2;
- }
- else if (element != EL_SP_INFOTRON)
- graphic += phase2;
- }
- }
- else if (element == EL_MAGIC_WALL_EMPTY ||
- element == EL_MAGIC_WALL_EMPTYING ||
- element == EL_MAGIC_WALL_BD_EMPTY ||
- element == EL_MAGIC_WALL_BD_EMPTYING ||
- element == EL_MAGIC_WALL_FULL ||
- element == EL_MAGIC_WALL_BD_FULL)
- {
- graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
- }
- else if (IS_AMOEBOID(element) || element == EL_AMOEBA_DRIPPING)
- {
- graphic = (element == EL_AMOEBE_TOT ? GFX_AMOEBE_TOT : GFX_AMOEBE_LEBT);
- graphic += (x + 2 * y + 4) % 4;
- }
- else if (element == EL_MAUER_LEBT)
+ if (element == EL_EXPANDABLE_WALL)
{
- boolean links_massiv = FALSE, rechts_massiv = FALSE;
+ boolean left_stopped = FALSE, right_stopped = FALSE;
- if (!IN_LEV_FIELD(ux-1, uy) || IS_MAUER(Feld[ux-1][uy]))
- links_massiv = TRUE;
- if (!IN_LEV_FIELD(ux+1, uy) || IS_MAUER(Feld[ux+1][uy]))
- rechts_massiv = TRUE;
+ 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 (links_massiv && rechts_massiv)
- graphic = GFX_MAUERWERK;
- else if (links_massiv)
- graphic = GFX_MAUER_R;
- else if (rechts_massiv)
- graphic = GFX_MAUER_L;
- }
- else if ((element == EL_INVISIBLE_STEEL ||
- element == EL_UNSICHTBAR ||
- element == EL_SAND_INVISIBLE) && game.light_time_left)
- {
- graphic = (element == EL_INVISIBLE_STEEL ? GFX_INVISIBLE_STEEL_ON :
- element == EL_UNSICHTBAR ? GFX_UNSICHTBAR_ON :
- GFX_SAND_INVISIBLE_ON);
+ 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, cut_mode, mask_mode);
+ DrawGraphicShifted(x, y, dx, dy, graphic, frame, cut_mode, mask_mode);
else if (mask_mode == USE_MASKING)
- DrawGraphicThruMask(x, y, graphic);
+ DrawGraphicThruMask(x, y, graphic, frame);
else
- DrawGraphic(x, y, graphic);
+ DrawGraphic(x, y, graphic, frame);
}
void DrawLevelElementExt(int x, int y, int dx, int dy, int element,
DrawLevelElementExt(x, y, dx, dy, element, cut_mode, NO_MASKING);
}
-void DrawScreenElementThruMask(int x, int y, int element)
-{
- DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
-}
-
void DrawLevelElementThruMask(int x, int y, int element)
{
DrawLevelElementExt(x, y, 0, 0, element, NO_CUTTING, USE_MASKING);
DrawLevelElementExt(x, y, 0, 0, Feld[x][y], NO_CUTTING, USE_MASKING);
}
-void ErdreichAnbroeckeln(int x, int y)
+static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame)
{
- int i, width, height, cx,cy;
- int ux = LEVELX(x), uy = LEVELY(y);
- int element, graphic;
- int snip = 4;
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int sx = SCREENX(x), sy = SCREENY(y);
+ int element;
+ int width, height, cx, cy, i;
+ int snip = TILEX / 8; /* number of border pixels from "crumbled graphic" */
static int xy[4][2] =
{
{ 0, -1 },
{ 0, +1 }
};
- if (!IN_LEV_FIELD(ux, uy))
+ if (!IN_LEV_FIELD(x, y))
return;
- element = Feld[ux][uy];
+ element = (GfxElement[x][y] != EL_UNDEFINED && Feld[x][y] != EL_EXPLOSION ?
+ GfxElement[x][y] : Feld[x][y]);
- if (element == EL_ERDREICH ||
- element == EL_LANDMINE ||
- element == EL_TRAP_INACTIVE ||
- element == EL_TRAP_ACTIVE)
+ /* crumble field itself */
+ if (CAN_BE_CRUMBLED(element) && !IS_MOVING(x, y))
{
- if (!IN_SCR_FIELD(x, y))
+ if (!IN_SCR_FIELD(sx, sy))
return;
- graphic = GFX_ERDENRAND;
+ getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
for(i=0; i<4; i++)
{
- int uxx, uyy;
+ int xx = x + xy[i][0];
+ int yy = y + xy[i][1];
- uxx = ux + xy[i][0];
- uyy = uy + xy[i][1];
- if (!IN_LEV_FIELD(uxx, uyy))
- element = EL_BETON;
- else
- element = Feld[uxx][uyy];
+ element = (IN_LEV_FIELD(xx, yy) ? Feld[xx][yy] : BorderElement);
- if (element == EL_ERDREICH ||
- element == EL_LANDMINE ||
- element == EL_TRAP_INACTIVE ||
- element == EL_TRAP_ACTIVE)
+ /* check if neighbour field is of same type */
+ if (CAN_BE_CRUMBLED(element) && !IS_MOVING(xx, yy))
continue;
+#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,
+ CAN_BE_CRUMBLED(element), IS_MOVING(x, y));
+#endif
+
if (i == 1 || i == 2)
{
width = snip;
cy = (i == 3 ? TILEY - snip : 0);
}
- BlitBitmap(pix[PIX_BACK], drawto_field,
- SX + (graphic % GFX_PER_LINE) * TILEX + cx,
- SY + (graphic / GFX_PER_LINE) * TILEY + cy,
- width, height, FX + x * TILEX + cx, FY + y * TILEY + cy);
+ BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
+ width, height, FX + sx * TILEX + cx, FY + sy * TILEY + cy);
}
- MarkTileDirty(x, y);
+ MarkTileDirty(sx, sy);
}
- else
+ else /* crumble neighbour fields */
{
- graphic = GFX_ERDENRAND;
+ getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
for(i=0; i<4; i++)
{
- int xx, yy, uxx, uyy;
-
- xx = x + xy[i][0];
- yy = y + xy[i][1];
- uxx = ux + xy[i][0];
- uyy = uy + xy[i][1];
-
- if (!IN_LEV_FIELD(uxx, uyy) ||
- (Feld[uxx][uyy] != EL_ERDREICH &&
- Feld[uxx][uyy] != EL_LANDMINE &&
- Feld[uxx][uyy] != EL_TRAP_INACTIVE &&
- Feld[uxx][uyy] != EL_TRAP_ACTIVE) ||
- !IN_SCR_FIELD(xx, yy))
+ 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) ||
+ !CAN_BE_CRUMBLED(Feld[xx][yy]) ||
+ IS_MOVING(xx, yy))
continue;
if (i == 1 || i == 2)
cy = (i==0 ? TILEY-snip : 0);
}
- BlitBitmap(pix[PIX_BACK], drawto_field,
- SX + (graphic % GFX_PER_LINE) * TILEX + cx,
- SY + (graphic / GFX_PER_LINE) * TILEY + cy,
- width, height, FX + xx * TILEX + cx, FY + yy * TILEY + cy);
+ BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy,
+ width, height, FX + sxx * TILEX + cx, FY + syy * TILEY + cy);
- MarkTileDirty(xx, yy);
+ MarkTileDirty(sxx, syy);
}
}
}
+void DrawLevelFieldCrumbledSand(int x, int y)
+{
+ DrawLevelFieldCrumbledSandExt(x, y, IMG_SAND_CRUMBLED, 0);
+}
+
+void DrawLevelFieldCrumbledSandDigging(int x, int y, int direction,
+ int step_frame)
+{
+#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);
+
+ DrawGraphic(sx, sy, graphic1, frame1);
+ DrawLevelFieldCrumbledSandExt(x, y, graphic2, frame2);
+}
+
+void DrawLevelFieldCrumbledSandNeighbours(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) ||
+ !CAN_BE_CRUMBLED(Feld[xx][yy]) ||
+ IS_MOVING(xx, yy))
+ continue;
+
+ DrawLevelField(xx, yy);
+ }
+}
+
+static int getBorderElement(int x, int 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);
+
+ return border[steel_position][steel_type];
+}
+
void DrawScreenElement(int x, int y, int element)
{
DrawScreenElementExt(x, y, 0, 0, element, NO_CUTTING, NO_MASKING);
- ErdreichAnbroeckeln(x, y);
+ DrawLevelFieldCrumbledSand(LEVELX(x), LEVELY(y));
}
void DrawLevelElement(int x, int y, int element)
void DrawScreenField(int x, int y)
{
- int ux = LEVELX(x), uy = LEVELY(y);
+ int lx = LEVELX(x), ly = LEVELY(y);
int element, content;
- if (!IN_LEV_FIELD(ux, uy))
+ if (!IN_LEV_FIELD(lx, ly))
{
- if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
- element = EL_LEERRAUM;
+ if (lx < -1 || lx > lev_fieldx || ly < -1 || ly > lev_fieldy)
+ element = EL_EMPTY;
else
- element = BorderElement;
+ element = getBorderElement(lx, ly);
DrawScreenElement(x, y, element);
return;
}
- element = Feld[ux][uy];
- content = Store[ux][uy];
+ element = Feld[lx][ly];
+ content = Store[lx][ly];
- if (IS_MOVING(ux, uy))
+ if (IS_MOVING(lx, ly))
{
- int horiz_move = (MovDir[ux][uy] == MV_LEFT || MovDir[ux][uy] == MV_RIGHT);
+ int horiz_move = (MovDir[lx][ly] == MV_LEFT || MovDir[lx][ly] == MV_RIGHT);
boolean cut_mode = NO_CUTTING;
if (element == EL_QUICKSAND_EMPTYING ||
element == EL_MAGIC_WALL_EMPTYING ||
- element == EL_MAGIC_WALL_BD_EMPTYING ||
- element == EL_AMOEBA_DRIPPING)
+ 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_MAGIC_WALL_BD_FILLING)
+ element == EL_BD_MAGIC_WALL_FILLING)
cut_mode = CUT_BELOW;
if (cut_mode == CUT_ABOVE)
DrawScreenElementShifted(x, y, 0, 0, element, NO_CUTTING);
else
- DrawScreenElement(x, y, EL_LEERRAUM);
+ DrawScreenElement(x, y, EL_EMPTY);
if (horiz_move)
- DrawScreenElementShifted(x, y, MovPos[ux][uy], 0, element, NO_CUTTING);
+ DrawScreenElementShifted(x, y, MovPos[lx][ly], 0, element, NO_CUTTING);
else if (cut_mode == NO_CUTTING)
- DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], element, cut_mode);
+ DrawScreenElementShifted(x, y, 0, MovPos[lx][ly], element, cut_mode);
else
- DrawScreenElementShifted(x, y, 0, MovPos[ux][uy], content, cut_mode);
+ DrawScreenElementShifted(x, y, 0, MovPos[lx][ly], content, cut_mode);
- if (content == EL_SALZSAEURE)
- DrawLevelElementThruMask(ux, uy + 1, EL_SALZSAEURE);
+ if (content == EL_ACID)
+ DrawLevelElementThruMask(lx, ly + 1, EL_ACID);
}
- else if (IS_BLOCKED(ux, uy))
+ else if (IS_BLOCKED(lx, ly))
{
int oldx, oldy;
int sx, sy;
boolean cut_mode = NO_CUTTING;
int element_old, content_old;
- Blocked2Moving(ux, uy, &oldx, &oldy);
+ Blocked2Moving(lx, ly, &oldx, &oldy);
sx = SCREENX(oldx);
sy = SCREENY(oldy);
horiz_move = (MovDir[oldx][oldy] == MV_LEFT ||
if (element_old == EL_QUICKSAND_EMPTYING ||
element_old == EL_MAGIC_WALL_EMPTYING ||
- element_old == EL_MAGIC_WALL_BD_EMPTYING ||
- element_old == EL_AMOEBA_DRIPPING)
+ element_old == EL_BD_MAGIC_WALL_EMPTYING ||
+ element_old == EL_AMOEBA_DROPPING)
cut_mode = CUT_ABOVE;
- DrawScreenElement(x, y, EL_LEERRAUM);
+ DrawScreenElement(x, y, EL_EMPTY);
if (horiz_move)
DrawScreenElementShifted(sx, sy, MovPos[oldx][oldy], 0, element_old,
else if (IS_DRAWABLE(element))
DrawScreenElement(x, y, element);
else
- DrawScreenElement(x, y, EL_LEERRAUM);
+ DrawScreenElement(x, y, EL_EMPTY);
}
void DrawLevelField(int x, int y)
{
int graphic;
- if (!element)
- {
- DrawMiniGraphic(x, y, -1);
- return;
- }
-
- graphic = el2gfx(element);
+ graphic = el2edimg(element);
DrawMiniGraphic(x, y, graphic);
}
int x = sx + scroll_x, y = sy + scroll_y;
if (x < -1 || x > lev_fieldx || y < -1 || y > lev_fieldy)
- DrawMiniElement(sx, sy, EL_LEERRAUM);
+ DrawMiniElement(sx, sy, EL_EMPTY);
else if (x > -1 && x < lev_fieldx && y > -1 && y < lev_fieldy)
DrawMiniElement(sx, sy, Feld[x][y]);
else
- {
- int steel_type, steel_position;
- int border[6][2] =
- {
- { GFX_VSTEEL_UPPER_LEFT, GFX_ISTEEL_UPPER_LEFT },
- { GFX_VSTEEL_UPPER_RIGHT, GFX_ISTEEL_UPPER_RIGHT },
- { GFX_VSTEEL_LOWER_LEFT, GFX_ISTEEL_LOWER_LEFT },
- { GFX_VSTEEL_LOWER_RIGHT, GFX_ISTEEL_LOWER_RIGHT },
- { GFX_VSTEEL_VERTICAL, GFX_ISTEEL_VERTICAL },
- { GFX_VSTEEL_HORIZONTAL, GFX_ISTEEL_HORIZONTAL }
- };
-
- steel_type = (BorderElement == EL_BETON ? 0 : 1);
- 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 : -1);
+ DrawMiniGraphic(sx, sy, el2edimg(getBorderElement(x, y)));
+}
- if (steel_position != -1)
- DrawMiniGraphic(sx, sy, border[steel_position][steel_type]);
- }
+void getMicroGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
+{
+ 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;
+
+ *bitmap = src_bitmap;
+ *x = src_x;
+ *y = src_y;
}
void DrawMicroElement(int xpos, int ypos, int element)
{
- int graphic;
-
- if (element == EL_LEERRAUM)
- return;
-
- graphic = el2gfx(element);
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int graphic = el2preimg(element);
- if (graphic >= GFX_START_ROCKSSP && graphic <= GFX_END_ROCKSSP)
- {
- graphic -= GFX_START_ROCKSSP;
- graphic -= ((graphic / SP_PER_LINE) * SP_PER_LINE) / 2;
- BlitBitmap(pix[PIX_SP], drawto,
- MICRO_SP_STARTX + (graphic % MICRO_SP_PER_LINE) * MICRO_TILEX,
- MICRO_SP_STARTY + (graphic / MICRO_SP_PER_LINE) * MICRO_TILEY,
- MICRO_TILEX, MICRO_TILEY, xpos, ypos);
- }
- else if (graphic >= GFX_START_ROCKSDC && graphic <= GFX_END_ROCKSDC)
- {
- graphic -= GFX_START_ROCKSDC;
- BlitBitmap(pix[PIX_DC], drawto,
- MICRO_DC_STARTX + (graphic % MICRO_DC_PER_LINE) * MICRO_TILEX,
- MICRO_DC_STARTY + (graphic / MICRO_DC_PER_LINE) * MICRO_TILEY,
- MICRO_TILEX, MICRO_TILEY, xpos, ypos);
- }
- else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
- {
- graphic -= GFX_START_ROCKSMORE;
- BlitBitmap(pix[PIX_MORE], drawto,
- MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE)*MICRO_TILEX,
- MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE)*MICRO_TILEY,
- MICRO_TILEX, MICRO_TILEY, xpos, ypos);
- }
- else
- BlitBitmap(pix[PIX_BACK], drawto,
- MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
- MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
- MICRO_TILEX, MICRO_TILEY, xpos, ypos);
+ getMicroGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
+ BlitBitmap(src_bitmap, drawto, src_x, src_y, MICRO_TILEX, MICRO_TILEY,
+ xpos, ypos);
}
void DrawLevel()
{
int x,y;
+ SetDrawBackgroundMask(REDRAW_NONE);
ClearWindow();
for(x=BX1; x<=BX2; x++)
{
int x, y;
- ClearRectangle(drawto, xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
+ DrawBackground(xpos, ypos, MICROLEV_XSIZE, MICROLEV_YSIZE);
if (lev_fieldx < STD_LEV_FIELDX)
xpos += (STD_LEV_FIELDX - lev_fieldx) / 2 * MICRO_TILEX;
if (lx >= 0 && lx < lev_fieldx && ly >= 0 && ly < lev_fieldy)
DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
- Ur[lx][ly]);
- else if (lx >= -1 && lx < lev_fieldx+1 && ly >= -1 && ly < lev_fieldy+1)
+ 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,
- BorderElement);
+ getBorderElement(lx, ly));
}
}
#define MICROLABEL_IMPORTED_FROM 4
#define MICROLABEL_LEVEL_IMPORT_INFO 5
-#define MAX_MICROLABEL_SIZE (SXSIZE / FONT4_XSIZE)
-
static void DrawMicroLevelLabelExt(int mode)
{
- char label_text[MAX_MICROLABEL_SIZE + 1];
+ char label_text[MAX_OUTPUT_LINESIZE + 1];
+ int max_len_label_text;
+ int font_nr = FONT_TEXT_2;
+
+ if (mode == MICROLABEL_CREATED_BY || mode == MICROLABEL_IMPORTED_FROM)
+ font_nr = FONT_TEXT_3;
- ClearRectangle(drawto, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
+ max_len_label_text = SXSIZE / getFontWidth(font_nr);
+
+ DrawBackground(SX, MICROLABEL_YPOS, SXSIZE, getFontHeight(font_nr));
strncpy(label_text, (mode == MICROLABEL_LEVEL_NAME ? level.name :
mode == MICROLABEL_CREATED_BY ? "created by" :
mode == MICROLABEL_IMPORTED_FROM ? "imported from" :
mode == MICROLABEL_LEVEL_IMPORT_INFO ?
leveldir_current->imported_from : ""),
- MAX_MICROLABEL_SIZE);
- label_text[MAX_MICROLABEL_SIZE] = '\0';
+ max_len_label_text);
+ label_text[max_len_label_text] = '\0';
if (strlen(label_text) > 0)
{
- int lxpos = SX + (SXSIZE - strlen(label_text) * FONT4_XSIZE) / 2;
+ int text_width = strlen(label_text) * getFontWidth(font_nr);
+ int lxpos = SX + (SXSIZE - text_width) / 2;
int lypos = MICROLABEL_YPOS;
- DrawText(lxpos, lypos, label_text, FS_SMALL, FC_SPECIAL2);
+ DrawText(lxpos, lypos, label_text, font_nr);
}
redraw_mask |= REDRAW_MICROLEVEL;
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)
{
DelayReached(&scroll_delay, 0);
DelayReached(&label_delay, 0);
+ if (leveldir_current->name)
+ {
+ int len = strlen(leveldir_current->name);
+ int lxpos = SX + (SXSIZE - len * getFontWidth(FONT_TEXT_1)) / 2;
+ int lypos = SY + 352;
+
+ DrawText(lxpos, lypos, leveldir_current->name, FONT_TEXT_1);
+ }
+
+ game_status = last_game_status; /* restore current game status */
+
return;
}
MICROLABEL_LEVEL_IMPORT_INFO : MICROLABEL_EMPTY);
DrawMicroLevelLabelExt(label_state);
}
+
+ game_status = last_game_status; /* restore current game status */
}
int REQ_in_range(int x, int y)
{
int mx, my, ty, result = -1;
unsigned int old_door_state;
+ int last_game_status = game_status; /* save current game status */
#if defined(PLATFORM_UNIX)
/* pause network game while waiting for request to answer */
if (options.network &&
- game_status == PLAYING &&
+ game_status == GAME_MODE_PLAYING &&
req_state & REQUEST_WAIT_FOR)
SendToServer_PausePlaying();
#endif
old_door_state = GetDoorState();
+ /* simulate releasing mouse button over last gadget, if still pressed */
+ if (button_status)
+ HandleGadgets(-1, -1, 0);
+
UnmapAllGadgets();
CloseDoor(DOOR_CLOSE_1);
/* save old door content */
- BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
+ 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);
+
/* clear door drawing field */
- ClearRectangle(drawto, DX, DY, DXSIZE, DYSIZE);
+ DrawBackground(DX, DY, DXSIZE, DYSIZE);
+
+ /* force DOOR font on preview level */
+ game_status = GAME_MODE_PSEUDO_DOOR;
/* write text for request */
for(ty=0; ty < MAX_REQUEST_LINES; ty++)
strncpy(text_line, text, tl);
text_line[tl] = 0;
- DrawTextExt(drawto, DX + 50 - (tl * 14)/2, DY + 8 + ty * 16,
- text_line, FS_SMALL, FC_YELLOW);
+ DrawText(DX + (DXSIZE - tl * getFontWidth(FONT_TEXT_2)) / 2,
+ DY + 8 + ty * (getFontHeight(FONT_TEXT_2) + 2),
+ text_line, FONT_TEXT_2);
text += tl + (tc == ' ' ? 1 : 0);
}
+ game_status = last_game_status; /* restore current game status */
+
if (req_state & REQ_ASK)
{
MapGadget(tool_gadget[TOOL_CTRL_ID_YES]);
}
/* copy request gadgets to door backbuffer */
- BlitBitmap(drawto, pix[PIX_DB_DOOR],
+ BlitBitmap(drawto, bitmap_db_door,
DX, DY, DXSIZE, DYSIZE,
DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
#endif
if (!(req_state & REQUEST_WAIT_FOR))
- return(FALSE);
+ {
+ SetDrawBackgroundMask(REDRAW_FIELD);
+
+ return FALSE;
+ }
- if (game_status != MAINMENU)
+ if (game_status != GAME_MODE_MAIN)
InitAnimation();
button_status = MB_RELEASED;
request_gadget_id = -1;
+ SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1);
+
while(result < 0)
{
if (PendingEvent())
Delay(10);
}
- if (game_status != MAINMENU)
+ if (game_status != GAME_MODE_MAIN)
StopAnimation();
UnmapToolButtons();
if (!(req_state & REQ_STAY_CLOSED) && (old_door_state & DOOR_OPEN_1))
{
- BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
+ 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);
RemapAllGadgets();
+ SetDrawBackgroundMask(REDRAW_FIELD);
+
#if defined(PLATFORM_UNIX)
/* continue network game after request */
if (options.network &&
- game_status == PLAYING &&
+ game_status == GAME_MODE_PLAYING &&
req_state & REQUEST_WAIT_FOR)
SendToServer_ContinuePlaying();
#endif
- return(result);
+ return result;
}
unsigned int OpenDoor(unsigned int door_state)
if (door_state & DOOR_COPY_BACK)
{
- BlitBitmap(pix[PIX_DB_DOOR], pix[PIX_DB_DOOR],
+ BlitBitmap(bitmap_db_door, bitmap_db_door,
DOOR_GFX_PAGEX2, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE + VYSIZE,
DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
door_state &= ~DOOR_COPY_BACK;
{
unsigned int new_door_state;
- BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
+ BlitBitmap(backbuffer, bitmap_db_door,
DX, DY, DXSIZE, DYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1);
- BlitBitmap(backbuffer, pix[PIX_DB_DOOR],
+ BlitBitmap(backbuffer, bitmap_db_door,
VX, VY, VXSIZE, VYSIZE, DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2);
new_door_state = MoveDoor(door_state);
static int door1 = DOOR_OPEN_1;
static int door2 = DOOR_CLOSE_2;
static unsigned long door_delay = 0;
- int x, start, stepsize = 2;
- unsigned long door_delay_value = stepsize * 5;
+ int x, start, stepsize = door.step_offset;
+ unsigned long door_delay_value = door.step_delay;
if (door_state == DOOR_GET_STATE)
return(door1 | door2);
{
stepsize = 20;
door_delay_value = 0;
- StopSound(SND_MENU_DOOR_OPENING);
- StopSound(SND_MENU_DOOR_CLOSING);
+
+ StopSound(SND_DOOR_OPENING);
+ StopSound(SND_DOOR_CLOSING);
+ }
+
+ if (global.autoplay_leveldir)
+ {
+ door_state |= DOOR_NO_DELAY;
+ door_state &= ~DOOR_CLOSE_ALL;
}
if (door_state & DOOR_ACTION)
{
/* opening door sound has priority over simultaneously closing door */
if (door_state & (DOOR_OPEN_1 | DOOR_OPEN_2))
- PlaySoundStereo(SND_MENU_DOOR_OPENING, SOUND_MAX_RIGHT);
+ PlaySoundStereo(SND_DOOR_OPENING, SOUND_MIDDLE);
else if (door_state & (DOOR_CLOSE_1 | DOOR_CLOSE_2))
- PlaySoundStereo(SND_MENU_DOOR_CLOSING, SOUND_MAX_RIGHT);
+ PlaySoundStereo(SND_DOOR_CLOSING, SOUND_MIDDLE);
}
start = ((door_state & DOOR_NO_DELAY) ? DXSIZE : 0);
for(x=start; x<=DXSIZE; x+=stepsize)
{
- Bitmap *bitmap = pix[PIX_DOOR];
+ Bitmap *bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
GC gc = bitmap->stored_clip_gc;
- WaitUntilDelayReached(&door_delay, door_delay_value);
+ if (!(door_state & DOOR_NO_DELAY))
+ WaitUntilDelayReached(&door_delay, door_delay_value);
if (door_state & DOOR_ACTION_1)
{
int i = (door_state & DOOR_OPEN_1 ? DXSIZE-x : x);
int j = (DXSIZE - i) / 3;
- BlitBitmap(pix[PIX_DB_DOOR], drawto,
+ BlitBitmap(bitmap_db_door, drawto,
DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY1 + i/2,
DXSIZE,DYSIZE - i/2, DX, DY);
int i = (door_state & DOOR_OPEN_2 ? VXSIZE - x : x);
int j = (VXSIZE - i) / 3;
- BlitBitmap(pix[PIX_DB_DOOR], drawto,
+ BlitBitmap(bitmap_db_door, drawto,
DOOR_GFX_PAGEX1, DOOR_GFX_PAGEY2 + i/2,
VXSIZE, VYSIZE - i/2, VX, VY);
BackToFront();
- if (game_status == MAINMENU)
+ if (game_status == GAME_MODE_MAIN)
DoAnimation();
}
}
if (setup.quick_doors)
{
- StopSound(SND_MENU_DOOR_OPENING);
- StopSound(SND_MENU_DOOR_CLOSING);
+ StopSound(SND_DOOR_OPENING);
+ StopSound(SND_DOOR_CLOSING);
}
if (door_state & DOOR_ACTION_1)
void DrawSpecialEditorDoor()
{
/* draw bigger toolbox window */
- BlitBitmap(pix[PIX_DOOR], drawto,
- DOOR_GFX_PAGEX7, 0, 108, 56, EX - 4, EY - 12);
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
+ DOOR_GFX_PAGEX7, 0, EXSIZE + 8, 8,
+ EX - 4, EY - 12);
+ BlitBitmap(graphic_info[IMG_GLOBAL_BORDER].bitmap, drawto,
+ EX - 4, VY - 4, EXSIZE + 8, EYSIZE - VYSIZE + 4,
+ EX - 4, EY - 4);
redraw_mask |= REDRAW_ALL;
}
void UndrawSpecialEditorDoor()
{
/* draw normal tape recorder window */
- BlitBitmap(pix[PIX_BACK], drawto,
- 562, 344, 108, 56, EX - 4, EY - 12);
+ BlitBitmap(graphic_info[IMG_GLOBAL_BORDER].bitmap, drawto,
+ EX - 4, EY - 12, EXSIZE + 8, EYSIZE - VYSIZE + 12,
+ EX - 4, EY - 12);
redraw_mask |= REDRAW_ALL;
}
-#ifndef TARGET_SDL
-int ReadPixel(DrawBuffer *bitmap, int x, int y)
-{
- XImage *pixel_image;
- unsigned long pixel_value;
-
- pixel_image = XGetImage(display, bitmap->drawable,
- x, y, 1, 1, AllPlanes, ZPixmap);
- pixel_value = XGetPixel(pixel_image, 0, 0);
-
- XDestroyImage(pixel_image);
-
- return pixel_value;
-}
-#endif
/* ---------- new tool button stuff ---------------------------------------- */
for (i=0; i<NUM_TOOL_BUTTONS; i++)
{
- Bitmap *gd_bitmap = pix[PIX_DOOR];
+ 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;
if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
{
- getMiniGraphicSource(GFX_SPIELER1 + id - TOOL_CTRL_ID_PLAYER_1,
+ 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;
}
}
+void FreeToolButtons()
+{
+ int i;
+
+ for (i=0; i<NUM_TOOL_BUTTONS; i++)
+ FreeGadget(tool_gadget[i]);
+}
+
static void UnmapToolButtons()
{
int i;
{
switch(element)
{
- case EL_QUICKSAND_FILLING: return EL_MORAST_VOLL;
- case EL_QUICKSAND_EMPTYING: return EL_MORAST_LEER;
+ case EL_QUICKSAND_FILLING: return EL_QUICKSAND_FULL;
+ case EL_QUICKSAND_EMPTYING: return EL_QUICKSAND_EMPTY;
case EL_MAGIC_WALL_FILLING: return EL_MAGIC_WALL_FULL;
- case EL_MAGIC_WALL_EMPTYING: return EL_MAGIC_WALL_EMPTY;
- case EL_MAGIC_WALL_BD_FILLING: return EL_MAGIC_WALL_BD_FULL;
- case EL_MAGIC_WALL_BD_EMPTYING: return EL_MAGIC_WALL_BD_EMPTY;
- case EL_AMOEBA_DRIPPING: return EL_AMOEBE_NASS;
+ case EL_MAGIC_WALL_EMPTYING: return EL_MAGIC_WALL_ACTIVE;
+ case EL_BD_MAGIC_WALL_FILLING: return EL_BD_MAGIC_WALL_FULL;
+ case EL_BD_MAGIC_WALL_EMPTYING: return EL_BD_MAGIC_WALL_ACTIVE;
+ case EL_AMOEBA_DROPPING: return EL_AMOEBA_WET;
default: return element;
}
}
-int el2gfx(int element)
+int el_act_dir2img(int element, int action, int direction)
{
- switch(element)
- {
- case EL_LEERRAUM: return -1;
- case EL_ERDREICH: return GFX_ERDREICH;
- case EL_MAUERWERK: return GFX_MAUERWERK;
- case EL_FELSBODEN: return GFX_FELSBODEN;
- case EL_FELSBROCKEN: return GFX_FELSBROCKEN;
- case EL_SCHLUESSEL: return GFX_SCHLUESSEL;
- case EL_EDELSTEIN: return GFX_EDELSTEIN;
- case EL_AUSGANG_ZU: return GFX_AUSGANG_ZU;
- case EL_AUSGANG_ACT: return GFX_AUSGANG_ACT;
- case EL_AUSGANG_AUF: return GFX_AUSGANG_AUF;
- case EL_SPIELFIGUR: return GFX_SPIELFIGUR;
- case EL_SPIELER1: return GFX_SPIELER1;
- case EL_SPIELER2: return GFX_SPIELER2;
- case EL_SPIELER3: return GFX_SPIELER3;
- case EL_SPIELER4: return GFX_SPIELER4;
- case EL_KAEFER: return GFX_KAEFER;
- case EL_KAEFER_RIGHT: return GFX_KAEFER_RIGHT;
- case EL_KAEFER_UP: return GFX_KAEFER_UP;
- case EL_KAEFER_LEFT: return GFX_KAEFER_LEFT;
- case EL_KAEFER_DOWN: return GFX_KAEFER_DOWN;
- case EL_FLIEGER: return GFX_FLIEGER;
- case EL_FLIEGER_RIGHT: return GFX_FLIEGER_RIGHT;
- case EL_FLIEGER_UP: return GFX_FLIEGER_UP;
- case EL_FLIEGER_LEFT: return GFX_FLIEGER_LEFT;
- case EL_FLIEGER_DOWN: return GFX_FLIEGER_DOWN;
- case EL_BUTTERFLY: return GFX_BUTTERFLY;
- case EL_BUTTERFLY_RIGHT: return GFX_BUTTERFLY_RIGHT;
- case EL_BUTTERFLY_UP: return GFX_BUTTERFLY_UP;
- case EL_BUTTERFLY_LEFT: return GFX_BUTTERFLY_LEFT;
- case EL_BUTTERFLY_DOWN: return GFX_BUTTERFLY_DOWN;
- case EL_FIREFLY: return GFX_FIREFLY;
- case EL_FIREFLY_RIGHT: return GFX_FIREFLY_RIGHT;
- case EL_FIREFLY_UP: return GFX_FIREFLY_UP;
- case EL_FIREFLY_LEFT: return GFX_FIREFLY_LEFT;
- case EL_FIREFLY_DOWN: return GFX_FIREFLY_DOWN;
- case EL_MAMPFER: return GFX_MAMPFER;
- case EL_ROBOT: return GFX_ROBOT;
- case EL_BETON: return GFX_BETON;
- case EL_DIAMANT: return GFX_DIAMANT;
- case EL_MORAST_LEER: return GFX_MORAST_LEER;
- case EL_MORAST_VOLL: return GFX_MORAST_VOLL;
- case EL_QUICKSAND_EMPTYING: return GFX_MORAST_LEER;
- case EL_TROPFEN: return GFX_TROPFEN;
- case EL_BOMBE: return GFX_BOMBE;
- case EL_MAGIC_WALL_OFF: return GFX_MAGIC_WALL_OFF;
- case EL_MAGIC_WALL_EMPTY: return GFX_MAGIC_WALL_EMPTY;
- case EL_MAGIC_WALL_EMPTYING:return GFX_MAGIC_WALL_EMPTY;
- case EL_MAGIC_WALL_FULL: return GFX_MAGIC_WALL_FULL;
- case EL_MAGIC_WALL_DEAD: return GFX_MAGIC_WALL_DEAD;
- case EL_SALZSAEURE: return GFX_SALZSAEURE;
- case EL_AMOEBE_TOT: return GFX_AMOEBE_TOT;
- case EL_AMOEBE_NASS: return GFX_AMOEBE_NASS;
- case EL_AMOEBE_NORM: return GFX_AMOEBE_NORM;
- case EL_AMOEBE_VOLL: return GFX_AMOEBE_VOLL;
- case EL_AMOEBE_BD: return GFX_AMOEBE_BD;
- case EL_AMOEBA2DIAM: return GFX_AMOEBA2DIAM;
- case EL_AMOEBA_DRIPPING: return GFX_AMOEBE_NASS;
- case EL_KOKOSNUSS: return GFX_KOKOSNUSS;
- case EL_LIFE: return GFX_LIFE;
- case EL_LIFE_ASYNC: return GFX_LIFE_ASYNC;
- case EL_DYNAMITE_ACTIVE: return GFX_DYNAMIT;
- case EL_BADEWANNE: return GFX_BADEWANNE;
- case EL_BADEWANNE1: return GFX_BADEWANNE1;
- case EL_BADEWANNE2: return GFX_BADEWANNE2;
- case EL_BADEWANNE3: return GFX_BADEWANNE3;
- case EL_BADEWANNE4: return GFX_BADEWANNE4;
- case EL_BADEWANNE5: return GFX_BADEWANNE5;
- case EL_ABLENK_AUS: return GFX_ABLENK_AUS;
- case EL_ABLENK_EIN: return GFX_ABLENK_EIN;
- case EL_SCHLUESSEL1: return GFX_SCHLUESSEL1;
- case EL_SCHLUESSEL2: return GFX_SCHLUESSEL2;
- case EL_SCHLUESSEL3: return GFX_SCHLUESSEL3;
- case EL_SCHLUESSEL4: return GFX_SCHLUESSEL4;
- case EL_PFORTE1: return GFX_PFORTE1;
- case EL_PFORTE2: return GFX_PFORTE2;
- case EL_PFORTE3: return GFX_PFORTE3;
- case EL_PFORTE4: return GFX_PFORTE4;
- case EL_PFORTE1X: return GFX_PFORTE1X;
- case EL_PFORTE2X: return GFX_PFORTE2X;
- case EL_PFORTE3X: return GFX_PFORTE3X;
- case EL_PFORTE4X: return GFX_PFORTE4X;
- case EL_DYNAMITE_INACTIVE: return GFX_DYNAMIT_AUS;
- case EL_PACMAN: return GFX_PACMAN;
- case EL_PACMAN_RIGHT: return GFX_PACMAN_RIGHT;
- case EL_PACMAN_UP: return GFX_PACMAN_UP;
- case EL_PACMAN_LEFT: return GFX_PACMAN_LEFT;
- case EL_PACMAN_DOWN: return GFX_PACMAN_DOWN;
- case EL_UNSICHTBAR: return GFX_UNSICHTBAR;
- case EL_ERZ_EDEL: return GFX_ERZ_EDEL;
- case EL_ERZ_DIAM: return GFX_ERZ_DIAM;
- case EL_BIRNE_AUS: return GFX_BIRNE_AUS;
- case EL_BIRNE_EIN: return GFX_BIRNE_EIN;
- case EL_ZEIT_VOLL: return GFX_ZEIT_VOLL;
- case EL_ZEIT_LEER: return GFX_ZEIT_LEER;
- case EL_MAUER_LEBT: return GFX_MAUER_LEBT;
- case EL_MAUER_X: return GFX_MAUER_X;
- case EL_MAUER_Y: return GFX_MAUER_Y;
- case EL_MAUER_XY: return GFX_MAUER_XY;
- case EL_EDELSTEIN_BD: return GFX_EDELSTEIN_BD;
- case EL_EDELSTEIN_GELB: return GFX_EDELSTEIN_GELB;
- case EL_EDELSTEIN_ROT: return GFX_EDELSTEIN_ROT;
- case EL_EDELSTEIN_LILA: return GFX_EDELSTEIN_LILA;
- case EL_ERZ_EDEL_BD: return GFX_ERZ_EDEL_BD;
- case EL_ERZ_EDEL_GELB: return GFX_ERZ_EDEL_GELB;
- case EL_ERZ_EDEL_ROT: return GFX_ERZ_EDEL_ROT;
- case EL_ERZ_EDEL_LILA: return GFX_ERZ_EDEL_LILA;
- case EL_MAMPFER2: return GFX_MAMPFER2;
- case EL_MAGIC_WALL_BD_OFF: return GFX_MAGIC_WALL_BD_OFF;
- case EL_MAGIC_WALL_BD_EMPTY:return GFX_MAGIC_WALL_BD_EMPTY;
- case EL_MAGIC_WALL_BD_EMPTYING:return GFX_MAGIC_WALL_BD_EMPTY;
- case EL_MAGIC_WALL_BD_FULL: return GFX_MAGIC_WALL_BD_FULL;
- case EL_MAGIC_WALL_BD_DEAD: return GFX_MAGIC_WALL_BD_DEAD;
- case EL_DYNABOMB_ACTIVE_1: return GFX_DYNABOMB;
- case EL_DYNABOMB_ACTIVE_2: return GFX_DYNABOMB;
- case EL_DYNABOMB_ACTIVE_3: return GFX_DYNABOMB;
- case EL_DYNABOMB_ACTIVE_4: return GFX_DYNABOMB;
- case EL_DYNABOMB_NR: return GFX_DYNABOMB_NR;
- case EL_DYNABOMB_SZ: return GFX_DYNABOMB_SZ;
- case EL_DYNABOMB_XL: return GFX_DYNABOMB_XL;
- case EL_SOKOBAN_OBJEKT: return GFX_SOKOBAN_OBJEKT;
- case EL_SOKOBAN_FELD_LEER: return GFX_SOKOBAN_FELD_LEER;
- case EL_SOKOBAN_FELD_VOLL: return GFX_SOKOBAN_FELD_VOLL;
- case EL_MOLE: return GFX_MOLE;
- case EL_PINGUIN: return GFX_PINGUIN;
- case EL_SCHWEIN: return GFX_SCHWEIN;
- case EL_DRACHE: return GFX_DRACHE;
- case EL_SONDE: return GFX_SONDE;
- case EL_PFEIL_LEFT: return GFX_PFEIL_LEFT;
- case EL_PFEIL_RIGHT: return GFX_PFEIL_RIGHT;
- case EL_PFEIL_UP: return GFX_PFEIL_UP;
- case EL_PFEIL_DOWN: return GFX_PFEIL_DOWN;
- case EL_SPEED_PILL: return GFX_SPEED_PILL;
- case EL_SP_TERMINAL_ACTIVE: return GFX_SP_TERMINAL;
- case EL_SP_BUG_ACTIVE: return GFX_SP_BUG_ACTIVE;
- case EL_SP_ZONK: return GFX_SP_ZONK;
- /* ^^^^^^^^^^ non-standard position in supaplex graphic set! */
- case EL_INVISIBLE_STEEL: return GFX_INVISIBLE_STEEL;
- case EL_BLACK_ORB: return GFX_BLACK_ORB;
- case EL_EM_GATE_1: return GFX_EM_GATE_1;
- case EL_EM_GATE_2: return GFX_EM_GATE_2;
- case EL_EM_GATE_3: return GFX_EM_GATE_3;
- case EL_EM_GATE_4: return GFX_EM_GATE_4;
- case EL_EM_GATE_1X: return GFX_EM_GATE_1X;
- case EL_EM_GATE_2X: return GFX_EM_GATE_2X;
- case EL_EM_GATE_3X: return GFX_EM_GATE_3X;
- case EL_EM_GATE_4X: return GFX_EM_GATE_4X;
- case EL_EM_KEY_1_FILE: return GFX_EM_KEY_1;
- case EL_EM_KEY_2_FILE: return GFX_EM_KEY_2;
- case EL_EM_KEY_3_FILE: return GFX_EM_KEY_3;
- case EL_EM_KEY_4_FILE: return GFX_EM_KEY_4;
- case EL_EM_KEY_1: return GFX_EM_KEY_1;
- case EL_EM_KEY_2: return GFX_EM_KEY_2;
- case EL_EM_KEY_3: return GFX_EM_KEY_3;
- case EL_EM_KEY_4: return GFX_EM_KEY_4;
- case EL_PEARL: return GFX_PEARL;
- case EL_CRYSTAL: return GFX_CRYSTAL;
- case EL_WALL_PEARL: return GFX_WALL_PEARL;
- case EL_WALL_CRYSTAL: return GFX_WALL_CRYSTAL;
- case EL_DOOR_WHITE: return GFX_DOOR_WHITE;
- case EL_DOOR_WHITE_GRAY: return GFX_DOOR_WHITE_GRAY;
- case EL_KEY_WHITE: return GFX_KEY_WHITE;
- case EL_SHIELD_PASSIVE: return GFX_SHIELD_PASSIVE;
- case EL_SHIELD_ACTIVE: return GFX_SHIELD_ACTIVE;
- case EL_EXTRA_TIME: return GFX_EXTRA_TIME;
- case EL_SWITCHGATE_OPEN: return GFX_SWITCHGATE_OPEN;
- case EL_SWITCHGATE_CLOSED: return GFX_SWITCHGATE_CLOSED;
- case EL_SWITCHGATE_SWITCH_1:return GFX_SWITCHGATE_SWITCH_1;
- case EL_SWITCHGATE_SWITCH_2:return GFX_SWITCHGATE_SWITCH_2;
- case EL_BELT1_LEFT: return GFX_BELT1_LEFT;
- case EL_BELT1_MIDDLE: return GFX_BELT1_MIDDLE;
- case EL_BELT1_RIGHT: return GFX_BELT1_RIGHT;
- case EL_BELT1_SWITCH_LEFT: return GFX_BELT1_SWITCH_LEFT;
- case EL_BELT1_SWITCH_MIDDLE:return GFX_BELT1_SWITCH_MIDDLE;
- case EL_BELT1_SWITCH_RIGHT: return GFX_BELT1_SWITCH_RIGHT;
- case EL_BELT2_LEFT: return GFX_BELT2_LEFT;
- case EL_BELT2_MIDDLE: return GFX_BELT2_MIDDLE;
- case EL_BELT2_RIGHT: return GFX_BELT2_RIGHT;
- case EL_BELT2_SWITCH_LEFT: return GFX_BELT2_SWITCH_LEFT;
- case EL_BELT2_SWITCH_MIDDLE:return GFX_BELT2_SWITCH_MIDDLE;
- case EL_BELT2_SWITCH_RIGHT: return GFX_BELT2_SWITCH_RIGHT;
- case EL_BELT3_LEFT: return GFX_BELT3_LEFT;
- case EL_BELT3_MIDDLE: return GFX_BELT3_MIDDLE;
- case EL_BELT3_RIGHT: return GFX_BELT3_RIGHT;
- case EL_BELT3_SWITCH_LEFT: return GFX_BELT3_SWITCH_LEFT;
- case EL_BELT3_SWITCH_MIDDLE:return GFX_BELT3_SWITCH_MIDDLE;
- case EL_BELT3_SWITCH_RIGHT: return GFX_BELT3_SWITCH_RIGHT;
- case EL_BELT4_LEFT: return GFX_BELT4_LEFT;
- case EL_BELT4_MIDDLE: return GFX_BELT4_MIDDLE;
- case EL_BELT4_RIGHT: return GFX_BELT4_RIGHT;
- case EL_BELT4_SWITCH_LEFT: return GFX_BELT4_SWITCH_LEFT;
- case EL_BELT4_SWITCH_MIDDLE:return GFX_BELT4_SWITCH_MIDDLE;
- case EL_BELT4_SWITCH_RIGHT: return GFX_BELT4_SWITCH_RIGHT;
- case EL_LANDMINE: return GFX_LANDMINE;
- case EL_ENVELOPE: return GFX_ENVELOPE;
- case EL_LIGHT_SWITCH_OFF: return GFX_LIGHT_SWITCH_OFF;
- case EL_LIGHT_SWITCH_ON: return GFX_LIGHT_SWITCH_ON;
- case EL_SIGN_EXCLAMATION: return GFX_SIGN_EXCLAMATION;
- case EL_SIGN_RADIOACTIVITY: return GFX_SIGN_RADIOACTIVITY;
- case EL_SIGN_STOP: return GFX_SIGN_STOP;
- case EL_SIGN_WHEELCHAIR: return GFX_SIGN_WHEELCHAIR;
- case EL_SIGN_PARKING: return GFX_SIGN_PARKING;
- case EL_SIGN_ONEWAY: return GFX_SIGN_ONEWAY;
- case EL_SIGN_HEART: return GFX_SIGN_HEART;
- case EL_SIGN_TRIANGLE: return GFX_SIGN_TRIANGLE;
- case EL_SIGN_ROUND: return GFX_SIGN_ROUND;
- case EL_SIGN_EXIT: return GFX_SIGN_EXIT;
- case EL_SIGN_YINYANG: return GFX_SIGN_YINYANG;
- case EL_SIGN_OTHER: return GFX_SIGN_OTHER;
- case EL_MOLE_LEFT: return GFX_MOLE_LEFT;
- case EL_MOLE_RIGHT: return GFX_MOLE_RIGHT;
- case EL_MOLE_UP: return GFX_MOLE_UP;
- case EL_MOLE_DOWN: return GFX_MOLE_DOWN;
- case EL_STEEL_SLANTED: return GFX_STEEL_SLANTED;
- case EL_SAND_INVISIBLE: return GFX_SAND_INVISIBLE;
- case EL_DX_UNKNOWN_15: return GFX_DX_UNKNOWN_15;
- case EL_DX_UNKNOWN_42: return GFX_DX_UNKNOWN_42;
- case EL_TIMEGATE_OPEN: return GFX_TIMEGATE_OPEN;
- case EL_TIMEGATE_CLOSED: return GFX_TIMEGATE_CLOSED;
- case EL_TIMEGATE_SWITCH_ON: return GFX_TIMEGATE_SWITCH;
- case EL_TIMEGATE_SWITCH_OFF:return GFX_TIMEGATE_SWITCH;
- case EL_BALLOON: return GFX_BALLOON;
- case EL_BALLOON_SEND_LEFT: return GFX_BALLOON_SEND_LEFT;
- case EL_BALLOON_SEND_RIGHT: return GFX_BALLOON_SEND_RIGHT;
- case EL_BALLOON_SEND_UP: return GFX_BALLOON_SEND_UP;
- case EL_BALLOON_SEND_DOWN: return GFX_BALLOON_SEND_DOWN;
- case EL_BALLOON_SEND_ANY: return GFX_BALLOON_SEND_ANY;
- case EL_EMC_STEEL_WALL_1: return GFX_EMC_STEEL_WALL_1;
- case EL_EMC_STEEL_WALL_2: return GFX_EMC_STEEL_WALL_2;
- case EL_EMC_STEEL_WALL_3: return GFX_EMC_STEEL_WALL_3;
- case EL_EMC_STEEL_WALL_4: return GFX_EMC_STEEL_WALL_4;
- case EL_EMC_WALL_1: return GFX_EMC_WALL_1;
- case EL_EMC_WALL_2: return GFX_EMC_WALL_2;
- case EL_EMC_WALL_3: return GFX_EMC_WALL_3;
- case EL_EMC_WALL_4: return GFX_EMC_WALL_4;
- case EL_EMC_WALL_5: return GFX_EMC_WALL_5;
- case EL_EMC_WALL_6: return GFX_EMC_WALL_6;
- case EL_EMC_WALL_7: return GFX_EMC_WALL_7;
- case EL_EMC_WALL_8: return GFX_EMC_WALL_8;
- case EL_TUBE_CROSS: return GFX_TUBE_CROSS;
- case EL_TUBE_VERTICAL: return GFX_TUBE_VERTICAL;
- case EL_TUBE_HORIZONTAL: return GFX_TUBE_HORIZONTAL;
- case EL_TUBE_VERT_LEFT: return GFX_TUBE_VERT_LEFT;
- case EL_TUBE_VERT_RIGHT: return GFX_TUBE_VERT_RIGHT;
- case EL_TUBE_HORIZ_UP: return GFX_TUBE_HORIZ_UP;
- case EL_TUBE_HORIZ_DOWN: return GFX_TUBE_HORIZ_DOWN;
- case EL_TUBE_LEFT_UP: return GFX_TUBE_LEFT_UP;
- case EL_TUBE_LEFT_DOWN: return GFX_TUBE_LEFT_DOWN;
- case EL_TUBE_RIGHT_UP: return GFX_TUBE_RIGHT_UP;
- case EL_TUBE_RIGHT_DOWN: return GFX_TUBE_RIGHT_DOWN;
- case EL_SPRING: return GFX_SPRING;
- case EL_SPRING_MOVING: return GFX_SPRING;
- case EL_TRAP_INACTIVE: return GFX_TRAP_INACTIVE;
- case EL_TRAP_ACTIVE: return GFX_TRAP_ACTIVE;
- case EL_BD_WALL: return GFX_BD_WALL;
- case EL_BD_ROCK: return GFX_BD_ROCK;
- case EL_DX_SUPABOMB: return GFX_DX_SUPABOMB;
- case EL_SP_MURPHY_CLONE: return GFX_SP_MURPHY_CLONE;
-
- default:
- {
- if (IS_CHAR(element))
- return GFX_CHAR_START + (element - EL_CHAR_START);
- else if (element >= EL_SP_START && element <= EL_SP_END)
- {
- int nr_element = element - EL_SP_START;
- int gfx_per_line = 8;
- int nr_graphic =
- (nr_element / gfx_per_line) * SP_PER_LINE +
- (nr_element % gfx_per_line);
+ element = GFX_ELEMENT(element);
+ direction = MV_DIR_BIT(direction);
- return GFX_START_ROCKSSP + nr_graphic;
- }
- else
- return -1;
- }
- }
+ return element_info[element].direction_graphic[action][direction];
+}
+
+static int el_act_dir2crm(int element, int action, int direction)
+{
+ element = GFX_ELEMENT(element);
+ direction = MV_DIR_BIT(direction);
+
+ return element_info[element].direction_crumbled[action][direction];
+}
+
+int el_act2img(int element, int action)
+{
+ element = GFX_ELEMENT(element);
+
+ return element_info[element].graphic[action];
+}
+
+int el_dir2img(int element, int direction)
+{
+ element = GFX_ELEMENT(element);
+
+ return el_act_dir2img(element, ACTION_DEFAULT, direction);
+}
+
+int el2img(int element)
+{
+ element = GFX_ELEMENT(element);
+
+ return element_info[element].graphic[ACTION_DEFAULT];
+}
+
+int el2edimg(int element)
+{
+ element = GFX_ELEMENT(element);
+
+ return element_info[element].special_graphic[GFX_SPECIAL_ARG_EDITOR];
+}
+
+int el2preimg(int element)
+{
+ element = GFX_ELEMENT(element);
+
+ return element_info[element].special_graphic[GFX_SPECIAL_ARG_PREVIEW];
}
void BackToFront();
void FadeToFront();
void ClearWindow();
+void SetMainBackgroundImage(int);
+void SetDoorBackgroundImage(int);
+void DrawBackground(int, int, int, int);
void MarkTileDirty(int, int);
void SetBorderElement();
+void SetRandomAnimationValue(int, int);
+int getGraphicAnimationFrame(int, int);
+void DrawGraphicAnimationExt(DrawBuffer *, int, int, int, int, int);
+void DrawGraphicAnimation(int, int, int);
+void DrawLevelGraphicAnimation(int, int, int);
+void DrawLevelElementAnimation(int, int, int);
+void DrawLevelGraphicAnimationIfNeeded(int, int, int);
+void DrawLevelElementAnimationIfNeeded(int, int, int);
+
void DrawAllPlayers(void);
void DrawPlayerField(int, int);
void DrawPlayer(struct PlayerInfo *);
-void DrawGraphicAnimationExt(int, int, int, int, int, int, int);
-void DrawGraphicAnimation(int, int, int, int, int, int);
-void DrawGraphicAnimationThruMask(int, int, int, int, int, int);
-void getGraphicSource(int, int *, int *, int *);
-void DrawGraphic(int, int, int);
-void DrawGraphicExt(DrawBuffer *, int, int, int);
-void DrawGraphicThruMask(int, int, int);
-void DrawGraphicThruMaskExt(DrawBuffer *, int, int, int);
+
+void getGraphicSource(int, int, Bitmap **, int *, int *);
+void DrawGraphic(int, int, int, int);
+void DrawGraphicExt(DrawBuffer *, int, int, int, int);
+void DrawGraphicThruMask(int, int, int, int);
+void DrawGraphicThruMaskExt(DrawBuffer *, int, int, int, int);
+
void DrawMiniGraphic(int, int, int);
void getMiniGraphicSource(int, Bitmap **, int *, int *);
void DrawMiniGraphicExt(DrawBuffer *, int, int, int);
-void DrawGraphicShifted(int, int, int, int, int, int, int);
-void DrawGraphicShiftedThruMask(int, int, int, 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 DrawScreenElementThruMask(int, int, int);
void DrawLevelElementThruMask(int, int, int);
void DrawLevelFieldThruMask(int, int);
-void ErdreichAnbroeckeln(int, int);
+void DrawLevelFieldCrumbledSand(int, int);
+void DrawLevelFieldCrumbledSandDigging(int, int, int, int);
+void DrawLevelFieldCrumbledSandNeighbours(int, int);
void DrawScreenElement(int, int, int);
void DrawLevelElement(int, int, int);
void DrawScreenField(int, int);
void DrawLevelField(int, int);
+
void DrawMiniElement(int, int, int);
void DrawMiniElementOrWall(int, int, int, int);
+
+void getMicroGraphicSource(int, Bitmap **, int *, int *);
void DrawMicroElement(int, int, int);
void DrawLevel(void);
void DrawMiniLevel(int, int, int, int);
void DrawMicroLevel(int, int, boolean);
+
boolean Request(char *, unsigned int);
unsigned int OpenDoor(unsigned int);
unsigned int CloseDoor(unsigned int);
unsigned int GetDoorState(void);
unsigned int SetDoorState(unsigned int);
unsigned int MoveDoor(unsigned int);
+
void DrawSpecialEditorDoor();
void UndrawSpecialEditorDoor();
-int ReadPixel(DrawBuffer *, int, int);
void CreateToolButtons();
+void FreeToolButtons();
int get_next_element(int);
-int el2gfx(int);
+int el_act_dir2img(int, int, int);
+int el_act2img(int, int);
+int el_dir2img(int, int);
+int el2img(int);
+int el2edimg(int);
+int el2preimg(int);
#endif /* TOOLS_H */