Merge branch 'master' into releases 3.0.8
authorHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:45:04 +0000 (10:45 +0200)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:45:04 +0000 (10:45 +0200)
51 files changed:
CHANGES
src/Makefile
src/cartoons.c
src/conf_e2g.c
src/conf_e2s.c
src/conf_g2m.c [new file with mode: 0644]
src/conf_g2s.c [new file with mode: 0644]
src/conf_gfx.c
src/conf_gfx.h
src/conf_hlp.c [new file with mode: 0644]
src/conf_mus.c [new file with mode: 0644]
src/conf_mus.h [new file with mode: 0644]
src/conf_snd.c
src/conf_snd.h
src/conftime.h
src/editor.c
src/editor.h
src/events.c
src/files.c
src/files.h
src/game.c
src/game.h
src/init.c
src/libgame/gadgets.c
src/libgame/gadgets.h
src/libgame/hash.c
src/libgame/image.c
src/libgame/joystick.c
src/libgame/misc.c
src/libgame/misc.h
src/libgame/msdos.c
src/libgame/pcx.c
src/libgame/sdl.c
src/libgame/setup.c
src/libgame/setup.h
src/libgame/sound.c
src/libgame/sound.h
src/libgame/system.c
src/libgame/system.h
src/libgame/text.c
src/libgame/text.h
src/libgame/x11.c
src/main.c
src/main.h
src/netserv.c
src/network.c
src/screens.c
src/screens.h
src/tape.c
src/tape.h
src/tools.c

diff --git a/CHANGES b/CHANGES
index a279c296d633cd5cda62efbf344cbdc1b564f431..f8bad85919f05832bae9379472b28d6114b2948e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,39 @@
+Release Version 3.0.8 [14 DEC 2003]
+-----------------------------------
+       - added "musicinfo.conf" for menu and level music configuration
+       - added "editorsetup.conf" for editor element list configuration
+       - added "copy" and "exchange" functions for custom elements to editor
+       - added configurable "bored" and "sleeping" animations for the player
+       - added "awakening" sound for player waking up after sleeping
+       - added configurable element animations for info screen
+       - added configurable music credits for info screen
+       - added configurable level set information for info screen
+       - added warnings for undefined token values in artwork config files
+       - menu text now directly clickable
+       - better sniksnak turning movement (two steps instead of only one)
+       - fixed turning movement of butterflies and fireflies (no frame reset)
+       - fixed bug with wrong default impact sound for colored emeralds
+       - fixed bug with double nut cracking sound
+       - fixed a very nasty bug in dragon turning code in TurnRoundExt()
+       - finally fixed tape recording when player is created from CE change
+       - added new contributed levels from the following players:
+         + Audrius Saikunas (4 levels)
+         + Efraim Yawitz (20 levels)
+         + Krystian Abramowicz (100 levels)
+         + Paul E Collins (formerly known as Equinox Tetrachloride; 64 levels)
+         + Sebastian Simon (12 levels)
+       - amazing new level set:
+         + "BD2K3" from Alan Bond
+         + 43 levels full of BD nostalgia, action and fantastic effects
+         + overwhelming use of custom elements
+         + complete artwork set with graphics, sounds and music
+         + available as a separate download from www.artsoft.org
+       - another great level set was updated:
+         + "jue2" from Jürgen Bonhagen
+         + 15 new mind-boggling levels full of new challenges for your brain
+         + complete artwork set with graphics and sounds
+         + available for downloading from "http://www.jb-line.de/rnd.html"
+
 Release Version 3.0.7 [10 NOV 2003]
 -----------------------------------
        - fixed incorrectly displayed animation for attacking dragon
index 61285b02c2878a4bcaafc325f15063b64804edd7..05eccd9916ed18c56496318ab01a9216a5f4c6b0 100644 (file)
@@ -135,6 +135,8 @@ LDFLAGS = $(SYS_LDFLAGS) $(EXTRA_LDFLAGS) -lm
 SRCS = main.c          \
        conf_gfx.c      \
        conf_snd.c      \
+       conf_mus.c      \
+       conf_hlp.c      \
        init.c          \
        config.c        \
        events.c        \
@@ -151,6 +153,8 @@ SRCS =      main.c          \
 OBJS = main.o          \
        conf_gfx.o      \
        conf_snd.o      \
+       conf_mus.o      \
+       conf_hlp.o      \
        init.o          \
        config.o        \
        events.o        \
@@ -166,6 +170,7 @@ OBJS =      main.o          \
 
 CNFS = conf_gfx.h      \
        conf_snd.h      \
+       conf_mus.h      \
        conf_chr.c      \
        conf_chr.h      \
        conf_cus.c      \
@@ -173,7 +178,9 @@ CNFS =      conf_gfx.h      \
        conf_e2g.c      \
        conf_esg.c      \
        conf_e2s.c      \
-       conf_fnt.c
+       conf_fnt.c      \
+       conf_g2s.c      \
+       conf_g2m.c
 
 CNFS_CMD = ../Scripts/create_element_defs.pl
 
@@ -215,6 +222,9 @@ conf_gfx.h: conf_gfx.c
 conf_snd.h: conf_snd.c
        @$(MAKE) auto-conf
 
+conf_mus.h: conf_mus.c
+       @$(MAKE) auto-conf
+
 $(TIMESTAMP_FILE): $(SRCS) $(LIBGAME)
        @date '+"[%Y-%m-%d %H:%M]"' \
        | sed -e 's/^/#define COMPILE_DATE_STRING /' \
index e6892ebb3c28a2addeba225d12ca75066b82f623..fd53e502a2e955124eaf9c656cb0b721cf83a11a 100644 (file)
@@ -26,13 +26,13 @@ static void PrepareBackbuffer()
   /* Fill empty backbuffer for animation functions */
   if (setup.direct_draw && game_status == GAME_MODE_PLAYING)
   {
-    int xx,yy;
+    int xx, yy;
 
     SetDrawtoField(DRAW_BACKBUFFER);
 
-    for(xx=0; xx<SCR_FIELDX; xx++)
-      for(yy=0; yy<SCR_FIELDY; yy++)
-       DrawScreenField(xx,yy);
+    for (xx = 0; xx < SCR_FIELDX; xx++)
+      for (yy = 0; yy < SCR_FIELDY; yy++)
+       DrawScreenField(xx, yy);
     DrawAllPlayers();
 
     SetDrawtoField(DRAW_DIRECT);
@@ -45,7 +45,7 @@ static void PrepareBackbuffer()
     fx += (ScreenMovDir & (MV_LEFT|MV_RIGHT) ? ScreenGfxPos : 0);
     fy += (ScreenMovDir & (MV_UP|MV_DOWN)    ? ScreenGfxPos : 0);
 
-    BlitBitmap(fieldbuffer, backbuffer, fx,fy, SXSIZE,SYSIZE, SX,SY);
+    BlitBitmap(fieldbuffer, backbuffer, fx, fy, SXSIZE, SYSIZE, SX, SY);
   }
 }
 
index 4f989bad88e2d0f399fedaf4f1a54d66185562db..2a70f7b836b6887b8298371e7aae1f71967d71d2 100644 (file)
@@ -109,74 +109,10 @@ element_to_graphic[] =
     EL_BD_BUTTERFLY,                   -1, -1, FALSE,
     IMG_BD_BUTTERFLY
   },
-  {
-    EL_BD_BUTTERFLY_RIGHT,             -1, -1, FALSE,
-    IMG_BD_BUTTERFLY_RIGHT
-  },
-  {
-    EL_BD_BUTTERFLY,                   -1, MV_BIT_RIGHT, FALSE,
-    IMG_BD_BUTTERFLY_RIGHT
-  },
-  {
-    EL_BD_BUTTERFLY_UP,                        -1, -1, FALSE,
-    IMG_BD_BUTTERFLY_UP
-  },
-  {
-    EL_BD_BUTTERFLY,                   -1, MV_BIT_UP, FALSE,
-    IMG_BD_BUTTERFLY_UP
-  },
-  {
-    EL_BD_BUTTERFLY_LEFT,              -1, -1, FALSE,
-    IMG_BD_BUTTERFLY_LEFT
-  },
-  {
-    EL_BD_BUTTERFLY,                   -1, MV_BIT_LEFT, FALSE,
-    IMG_BD_BUTTERFLY_LEFT
-  },
-  {
-    EL_BD_BUTTERFLY_DOWN,              -1, -1, FALSE,
-    IMG_BD_BUTTERFLY_DOWN
-  },
-  {
-    EL_BD_BUTTERFLY,                   -1, MV_BIT_DOWN, FALSE,
-    IMG_BD_BUTTERFLY_DOWN
-  },
   {
     EL_BD_FIREFLY,                     -1, -1, FALSE,
     IMG_BD_FIREFLY
   },
-  {
-    EL_BD_FIREFLY_RIGHT,               -1, -1, FALSE,
-    IMG_BD_FIREFLY_RIGHT
-  },
-  {
-    EL_BD_FIREFLY,                     -1, MV_BIT_RIGHT, FALSE,
-    IMG_BD_FIREFLY_RIGHT
-  },
-  {
-    EL_BD_FIREFLY_UP,                  -1, -1, FALSE,
-    IMG_BD_FIREFLY_UP
-  },
-  {
-    EL_BD_FIREFLY,                     -1, MV_BIT_UP, FALSE,
-    IMG_BD_FIREFLY_UP
-  },
-  {
-    EL_BD_FIREFLY_LEFT,                        -1, -1, FALSE,
-    IMG_BD_FIREFLY_LEFT
-  },
-  {
-    EL_BD_FIREFLY,                     -1, MV_BIT_LEFT, FALSE,
-    IMG_BD_FIREFLY_LEFT
-  },
-  {
-    EL_BD_FIREFLY_DOWN,                        -1, -1, FALSE,
-    IMG_BD_FIREFLY_DOWN
-  },
-  {
-    EL_BD_FIREFLY,                     -1, MV_BIT_DOWN, FALSE,
-    IMG_BD_FIREFLY_DOWN
-  },
   {
     EL_SP_DEFAULT,                     ACTION_EXPLODING, -1, FALSE,
     IMG_SP_DEFAULT_EXPLODING
@@ -949,10 +885,18 @@ element_to_graphic[] =
     EL_AMOEBA_GROWING,                 -1, -1, FALSE,
     IMG_AMOEBA_GROWING
   },
+  {
+    EL_AMOEBA,                         ACTION_GROWING, -1, FALSE,
+    IMG_AMOEBA_GROWING
+  },
   {
     EL_AMOEBA_SHRINKING,               -1, -1, FALSE,
     IMG_AMOEBA_SHRINKING
   },
+  {
+    EL_AMOEBA,                         ACTION_SHRINKING, -1, FALSE,
+    IMG_AMOEBA_SHRINKING
+  },
   {
     EL_AMOEBA_WET,                     -1, -1, FALSE,
     IMG_AMOEBA_WET
@@ -961,6 +905,10 @@ element_to_graphic[] =
     EL_AMOEBA_DROPPING,                        -1, -1, FALSE,
     IMG_AMOEBA_DROPPING
   },
+  {
+    EL_AMOEBA,                         ACTION_DROPPING, -1, FALSE,
+    IMG_AMOEBA_DROPPING
+  },
   {
     EL_AMOEBA_DRY,                     -1, -1, FALSE,
     IMG_AMOEBA_DRY
@@ -2101,6 +2049,10 @@ element_to_graphic[] =
     EL_STONEBLOCK,                     -1, -1, FALSE,
     IMG_STONEBLOCK
   },
+  {
+    EL_MAZE_RUNNER,                    -1, -1, FALSE,
+    IMG_MAZE_RUNNER
+  },
   {
     EL_PLAYER_1,                       -1, -1, FALSE,
     IMG_PLAYER_1
index de238576bba8f77aad7634571390e9caa4aac055..9b293d5b5424e4a3389c003425e5b260f26ee29e 100644 (file)
@@ -237,12 +237,12 @@ element_to_sound[] =
     SND_SAND_DIGGING
   },
   {
-    EL_EMERALD, FALSE,                         ACTION_COLLECTING,
-    SND_EMERALD_COLLECTING
+    EL_EMERALD, TRUE,                          ACTION_COLLECTING,
+    SND_CLASS_EMERALD_COLLECTING
   },
   {
-    EL_EMERALD, FALSE,                         ACTION_IMPACT,
-    SND_EMERALD_IMPACT
+    EL_EMERALD, TRUE,                          ACTION_IMPACT,
+    SND_CLASS_EMERALD_IMPACT
   },
   {
     EL_DIAMOND, FALSE,                         ACTION_COLLECTING,
diff --git a/src/conf_g2m.c b/src/conf_g2m.c
new file mode 100644 (file)
index 0000000..1c18645
--- /dev/null
@@ -0,0 +1,63 @@
+/***********************************************************
+* 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_g2m.c                                               *
+***********************************************************/
+
+/* ----- this file was automatically generated -- do not edit by hand ----- */
+
+#ifndef CONF_G2M_C
+#define CONF_G2M_C
+
+/* values for gamemode/music mapping configuration */
+
+static struct
+{
+  int gamemode;
+
+  int music;
+}
+gamemode_to_music[] =
+{
+  {
+    -1,
+    MUS_BACKGROUND
+  },
+  {
+    GFX_SPECIAL_ARG_MAIN,
+    MUS_BACKGROUND_MAIN
+  },
+  {
+    GFX_SPECIAL_ARG_LEVELS,
+    MUS_BACKGROUND_LEVELS
+  },
+  {
+    GFX_SPECIAL_ARG_SCORES,
+    MUS_BACKGROUND_SCORES
+  },
+  {
+    GFX_SPECIAL_ARG_EDITOR,
+    MUS_BACKGROUND_EDITOR
+  },
+  {
+    GFX_SPECIAL_ARG_INFO,
+    MUS_BACKGROUND_INFO
+  },
+  {
+    GFX_SPECIAL_ARG_SETUP,
+    MUS_BACKGROUND_SETUP
+  },
+  {
+    -1,
+    -1
+  },
+};
+
+#endif /* CONF_G2M_C */
diff --git a/src/conf_g2s.c b/src/conf_g2s.c
new file mode 100644 (file)
index 0000000..7ebfff0
--- /dev/null
@@ -0,0 +1,59 @@
+/***********************************************************
+* 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_g2s.c                                               *
+***********************************************************/
+
+/* ----- this file was automatically generated -- do not edit by hand ----- */
+
+#ifndef CONF_G2S_C
+#define CONF_G2S_C
+
+/* values for gamemode/sound mapping configuration */
+
+static struct
+{
+  int gamemode;
+
+  int sound;
+}
+gamemode_to_sound[] =
+{
+  {
+    GFX_SPECIAL_ARG_MAIN,
+    SND_BACKGROUND_MAIN
+  },
+  {
+    GFX_SPECIAL_ARG_LEVELS,
+    SND_BACKGROUND_LEVELS
+  },
+  {
+    GFX_SPECIAL_ARG_SCORES,
+    SND_BACKGROUND_SCORES
+  },
+  {
+    GFX_SPECIAL_ARG_EDITOR,
+    SND_BACKGROUND_EDITOR
+  },
+  {
+    GFX_SPECIAL_ARG_INFO,
+    SND_BACKGROUND_INFO
+  },
+  {
+    GFX_SPECIAL_ARG_SETUP,
+    SND_BACKGROUND_SETUP
+  },
+  {
+    -1,
+    -1
+  },
+};
+
+#endif /* CONF_G2S_C */
index 1b9fd4ee5ff2fcc296ca78abd0d7197f486d98bd..984c0972d24e6e0e14cc5562fbfa94279a919a37 100644 (file)
 
 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   },
-  { ".border_size",                    ARG_UNDEFINED,  TYPE_INTEGER },
-  { ".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 },
-  { ".draw_masked",                    "false",        TYPE_BOOLEAN },
-  { ".name",                           ARG_UNDEFINED,  TYPE_STRING  },
-
-  { NULL,                              NULL,           0            }
+  { ".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      },
+  { ".border_size",                    ARG_UNDEFINED,  TYPE_INTEGER    },
+  { ".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    },
+  { ".draw_masked",                    "false",        TYPE_BOOLEAN    },
+  { ".anim_delay_fixed",               ARG_UNDEFINED,  TYPE_INTEGER    },
+  { ".anim_delay_random",              ARG_UNDEFINED,  TYPE_INTEGER    },
+  { ".post_delay_fixed",               ARG_UNDEFINED,  TYPE_INTEGER    },
+  { ".post_delay_random",              ARG_UNDEFINED,  TYPE_INTEGER    },
+  { ".name",                           ARG_UNDEFINED,  TYPE_STRING     },
+
+  { NULL,                              NULL,           0               }
 };
 
 struct ConfigInfo image_config[] =
@@ -166,46 +170,19 @@ struct ConfigInfo image_config[] =
   { "bd_butterfly.frames",                     "2"                     },
   { "bd_butterfly.anim_mode",                  "pingpong"              },
   { "bd_butterfly.delay",                      "4"                     },
-  { "bd_butterfly.right",                      "RocksElements.pcx"     },
-  { "bd_butterfly.right.xpos",                 "4"                     },
-  { "bd_butterfly.right.ypos",                 "12"                    },
-  { "bd_butterfly.right.frames",               "2"                     },
-  { "bd_butterfly.right.anim_mode",            "pingpong"              },
-  { "bd_butterfly.right.delay",                        "4"                     },
+  { "bd_butterfly.global_sync",                        "true"                  },
   { "bd_butterfly.right.EDITOR",               "RocksElements.pcx"     },
   { "bd_butterfly.right.EDITOR.xpos",          "8"                     },
   { "bd_butterfly.right.EDITOR.ypos",          "12"                    },
-  { "bd_butterfly.right.EDITOR.frames",                "1"                     },
-  { "bd_butterfly.up",                         "RocksElements.pcx"     },
-  { "bd_butterfly.up.xpos",                    "4"                     },
-  { "bd_butterfly.up.ypos",                    "12"                    },
-  { "bd_butterfly.up.frames",                  "2"                     },
-  { "bd_butterfly.up.anim_mode",               "pingpong"              },
-  { "bd_butterfly.up.delay",                   "4"                     },
   { "bd_butterfly.up.EDITOR",                  "RocksElements.pcx"     },
   { "bd_butterfly.up.EDITOR.xpos",             "9"                     },
   { "bd_butterfly.up.EDITOR.ypos",             "12"                    },
-  { "bd_butterfly.up.EDITOR.frames",           "1"                     },
-  { "bd_butterfly.left",                       "RocksElements.pcx"     },
-  { "bd_butterfly.left.xpos",                  "4"                     },
-  { "bd_butterfly.left.ypos",                  "12"                    },
-  { "bd_butterfly.left.frames",                        "2"                     },
-  { "bd_butterfly.left.anim_mode",             "pingpong"              },
-  { "bd_butterfly.left.delay",                 "4"                     },
   { "bd_butterfly.left.EDITOR",                        "RocksElements.pcx"     },
   { "bd_butterfly.left.EDITOR.xpos",           "10"                    },
   { "bd_butterfly.left.EDITOR.ypos",           "12"                    },
-  { "bd_butterfly.left.EDITOR.frames",         "1"                     },
-  { "bd_butterfly.down",                       "RocksElements.pcx"     },
-  { "bd_butterfly.down.xpos",                  "4"                     },
-  { "bd_butterfly.down.ypos",                  "12"                    },
-  { "bd_butterfly.down.frames",                        "2"                     },
-  { "bd_butterfly.down.anim_mode",             "pingpong"              },
-  { "bd_butterfly.down.delay",                 "4"                     },
   { "bd_butterfly.down.EDITOR",                        "RocksElements.pcx"     },
   { "bd_butterfly.down.EDITOR.xpos",           "11"                    },
   { "bd_butterfly.down.EDITOR.ypos",           "12"                    },
-  { "bd_butterfly.down.EDITOR.frames",         "1"                     },
 
   { "bd_firefly",                              "RocksElements.pcx"     },
   { "bd_firefly.xpos",                         "6"                     },
@@ -213,46 +190,19 @@ struct ConfigInfo image_config[] =
   { "bd_firefly.frames",                       "2"                     },
   { "bd_firefly.anim_mode",                    "pingpong"              },
   { "bd_firefly.delay",                                "4"                     },
-  { "bd_firefly.right",                                "RocksElements.pcx"     },
-  { "bd_firefly.right.xpos",                   "6"                     },
-  { "bd_firefly.right.ypos",                   "12"                    },
-  { "bd_firefly.right.frames",                 "2"                     },
-  { "bd_firefly.right.anim_mode",              "pingpong"              },
-  { "bd_firefly.right.delay",                  "4"                     },
+  { "bd_firefly.global_sync",                  "true"                  },
   { "bd_firefly.right.EDITOR",                 "RocksElements.pcx"     },
   { "bd_firefly.right.EDITOR.xpos",            "12"                    },
   { "bd_firefly.right.EDITOR.ypos",            "12"                    },
-  { "bd_firefly.right.EDITOR.frames",          "1"                     },
-  { "bd_firefly.up",                           "RocksElements.pcx"     },
-  { "bd_firefly.up.xpos",                      "6"                     },
-  { "bd_firefly.up.ypos",                      "12"                    },
-  { "bd_firefly.up.frames",                    "2"                     },
-  { "bd_firefly.up.anim_mode",                 "pingpong"              },
-  { "bd_firefly.up.delay",                     "4"                     },
   { "bd_firefly.up.EDITOR",                    "RocksElements.pcx"     },
   { "bd_firefly.up.EDITOR.xpos",               "13"                    },
   { "bd_firefly.up.EDITOR.ypos",               "12"                    },
-  { "bd_firefly.up.EDITOR.frames",             "1"                     },
-  { "bd_firefly.left",                         "RocksElements.pcx"     },
-  { "bd_firefly.left.xpos",                    "6"                     },
-  { "bd_firefly.left.ypos",                    "12"                    },
-  { "bd_firefly.left.frames",                  "2"                     },
-  { "bd_firefly.left.anim_mode",               "pingpong"              },
-  { "bd_firefly.left.delay",                   "4"                     },
   { "bd_firefly.left.EDITOR",                  "RocksElements.pcx"     },
   { "bd_firefly.left.EDITOR.xpos",             "14"                    },
   { "bd_firefly.left.EDITOR.ypos",             "12"                    },
-  { "bd_firefly.left.EDITOR.frames",           "1"                     },
-  { "bd_firefly.down",                         "RocksElements.pcx"     },
-  { "bd_firefly.down.xpos",                    "6"                     },
-  { "bd_firefly.down.ypos",                    "12"                    },
-  { "bd_firefly.down.frames",                  "2"                     },
-  { "bd_firefly.down.anim_mode",               "pingpong"              },
-  { "bd_firefly.down.delay",                   "4"                     },
   { "bd_firefly.down.EDITOR",                  "RocksElements.pcx"     },
   { "bd_firefly.down.EDITOR.xpos",             "15"                    },
   { "bd_firefly.down.EDITOR.ypos",             "12"                    },
-  { "bd_firefly.down.EDITOR.frames",           "1"                     },
 
   /* images for Supaplex style elements and actions */
 
@@ -529,35 +479,59 @@ struct ConfigInfo image_config[] =
   { "sp_sniksnak.turning_from_left.up",                "RocksSP.pcx"           },
   { "sp_sniksnak.turning_from_left.up.xpos",   "12"                    },
   { "sp_sniksnak.turning_from_left.up.ypos",   "6"                     },
-  { "sp_sniksnak.turning_from_left.up.frames", "1"                     },
+  { "sp_sniksnak.turning_from_left.up.frames", "2"                     },
+  { "sp_sniksnak.turning_from_left.up.delay",  "4"                     },
+  { "sp_sniksnak.turning_from_left.up.offset", "1408"                  },
+  { "sp_sniksnak.turning_from_left.up.anim_mode","linear"              },
   { "sp_sniksnak.turning_from_left.down",      "RocksSP.pcx"           },
   { "sp_sniksnak.turning_from_left.down.xpos", "13"                    },
   { "sp_sniksnak.turning_from_left.down.ypos", "6"                     },
-  { "sp_sniksnak.turning_from_left.down.frames","1"                    },
+  { "sp_sniksnak.turning_from_left.down.frames","2"                    },
+  { "sp_sniksnak.turning_from_left.down.delay",        "4"                     },
+  { "sp_sniksnak.turning_from_left.down.offset","1504"                 },
+  { "sp_sniksnak.turning_from_left.down.anim_mode","linear"            },
   { "sp_sniksnak.turning_from_right.up",       "RocksSP.pcx"           },
   { "sp_sniksnak.turning_from_right.up.xpos",  "15"                    },
   { "sp_sniksnak.turning_from_right.up.ypos",  "6"                     },
-  { "sp_sniksnak.turning_from_right.up.frames",        "1"                     },
+  { "sp_sniksnak.turning_from_right.up.frames",        "2"                     },
+  { "sp_sniksnak.turning_from_right.up.delay", "4"                     },
+  { "sp_sniksnak.turning_from_right.up.offset",        "1312"                  },
+  { "sp_sniksnak.turning_from_right.up.anim_mode","linear"             },
   { "sp_sniksnak.turning_from_right.down",     "RocksSP.pcx"           },
   { "sp_sniksnak.turning_from_right.down.xpos",        "14"                    },
   { "sp_sniksnak.turning_from_right.down.ypos",        "6"                     },
-  { "sp_sniksnak.turning_from_right.down.frames","1"                   },
+  { "sp_sniksnak.turning_from_right.down.frames","2"                   },
+  { "sp_sniksnak.turning_from_right.down.delay","4"                    },
+  { "sp_sniksnak.turning_from_right.down.offset","1472"                        },
+  { "sp_sniksnak.turning_from_right.down.anim_mode","linear"           },
   { "sp_sniksnak.turning_from_up.left",                "RocksSP.pcx"           },
   { "sp_sniksnak.turning_from_up.left.xpos",   "12"                    },
   { "sp_sniksnak.turning_from_up.left.ypos",   "6"                     },
-  { "sp_sniksnak.turning_from_up.left.frames", "1"                     },
+  { "sp_sniksnak.turning_from_up.left.frames", "2"                     },
+  { "sp_sniksnak.turning_from_up.left.delay",  "4"                     },
+  { "sp_sniksnak.turning_from_up.left.offset", "896"                   },
+  { "sp_sniksnak.turning_from_up.left.anim_mode","linear"              },
   { "sp_sniksnak.turning_from_up.right",       "RocksSP.pcx"           },
   { "sp_sniksnak.turning_from_up.right.xpos",  "15"                    },
   { "sp_sniksnak.turning_from_up.right.ypos",  "6"                     },
-  { "sp_sniksnak.turning_from_up.right.frames",        "1"                     },
+  { "sp_sniksnak.turning_from_up.right.frames",        "2"                     },
+  { "sp_sniksnak.turning_from_up.right.delay", "4"                     },
+  { "sp_sniksnak.turning_from_up.right.offset",        "928"                   },
+  { "sp_sniksnak.turning_from_up.right.anim_mode","linear"             },
   { "sp_sniksnak.turning_from_down.left",      "RocksSP.pcx"           },
   { "sp_sniksnak.turning_from_down.left.xpos", "13"                    },
   { "sp_sniksnak.turning_from_down.left.ypos", "6"                     },
-  { "sp_sniksnak.turning_from_down.left.frames","1"                    },
+  { "sp_sniksnak.turning_from_down.left.frames","2"                    },
+  { "sp_sniksnak.turning_from_down.left.delay",        "4"                     },
+  { "sp_sniksnak.turning_from_down.left.offset","864"                  },
+  { "sp_sniksnak.turning_from_down.left.anim_mode","linear"            },
   { "sp_sniksnak.turning_from_down.right",     "RocksSP.pcx"           },
   { "sp_sniksnak.turning_from_down.right.xpos",        "14"                    },
   { "sp_sniksnak.turning_from_down.right.ypos",        "6"                     },
-  { "sp_sniksnak.turning_from_down.right.frames","1"                   },
+  { "sp_sniksnak.turning_from_down.right.frames","2"                   },
+  { "sp_sniksnak.turning_from_down.right.delay","4"                    },
+  { "sp_sniksnak.turning_from_down.right.offset","960"                 },
+  { "sp_sniksnak.turning_from_down.right.anim_mode","linear"           },
 
   { "sp_electron",                             "RocksSP.pcx"           },
   { "sp_electron.xpos",                                "8"                     },
@@ -2493,6 +2467,11 @@ struct ConfigInfo image_config[] =
   { "stoneblock.ypos",                         "1"                     },
   { "stoneblock.frames",                       "1"                     },
 
+  { "maze_runner",                             "RocksHeroes.pcx"       },
+  { "maze_runner.xpos",                                "15"                    },
+  { "maze_runner.ypos",                                "8"                     },
+  { "maze_runner.frames",                      "1"                     },
+
   /* images for other elements and actions */
 
   { "player_1",                                        "RocksHeroes.pcx"       },
@@ -3734,5 +3713,10 @@ struct ConfigInfo image_config[] =
   { "door_2.step_delay",                       "10"                    },
   { "door_2.anim_mode",                                "default"               },
 
+  { "[player].boring_delay_fixed",             "-1"                    },
+  { "[player].boring_delay_random",            "-1"                    },
+  { "[player].sleeping_delay_fixed",           "-1"                    },
+  { "[player].sleeping_delay_random",          "-1"                    },
+
   { NULL,                                      NULL                    }
 };
index 5aa17748dfa4cfb74c990ee637c5772951da1584..6025aada3405fa92b8d54828a1a02edee1961a24 100644 (file)
 #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_RIGHT_EDITOR                  21
-#define IMG_BD_BUTTERFLY_UP                            22
-#define IMG_BD_BUTTERFLY_UP_EDITOR                     23
-#define IMG_BD_BUTTERFLY_LEFT                          24
-#define IMG_BD_BUTTERFLY_LEFT_EDITOR                   25
-#define IMG_BD_BUTTERFLY_DOWN                          26
-#define IMG_BD_BUTTERFLY_DOWN_EDITOR                   27
-#define IMG_BD_FIREFLY                                 28
-#define IMG_BD_FIREFLY_RIGHT                           29
-#define IMG_BD_FIREFLY_RIGHT_EDITOR                    30
-#define IMG_BD_FIREFLY_UP                              31
-#define IMG_BD_FIREFLY_UP_EDITOR                       32
-#define IMG_BD_FIREFLY_LEFT                            33
-#define IMG_BD_FIREFLY_LEFT_EDITOR                     34
-#define IMG_BD_FIREFLY_DOWN                            35
-#define IMG_BD_FIREFLY_DOWN_EDITOR                     36
-#define IMG_SP_DEFAULT_EXPLODING                       37
-#define IMG_SP_ZONK                                    38
-#define IMG_SP_ZONK_MOVING_LEFT                                39
-#define IMG_SP_ZONK_MOVING_RIGHT                       40
-#define IMG_SP_ZONK_PUSHING_LEFT                       41
-#define IMG_SP_ZONK_PUSHING_RIGHT                      42
-#define IMG_SP_BASE                                    43
-#define IMG_SP_MURPHY                                  44
-#define IMG_SP_MURPHY_MOVING_LEFT                      45
-#define IMG_SP_MURPHY_MOVING_RIGHT                     46
-#define IMG_SP_MURPHY_DIGGING_LEFT                     47
-#define IMG_SP_MURPHY_DIGGING_RIGHT                    48
-#define IMG_SP_MURPHY_COLLECTING_LEFT                  49
-#define IMG_SP_MURPHY_COLLECTING_RIGHT                 50
-#define IMG_SP_MURPHY_PUSHING_LEFT                     51
-#define IMG_SP_MURPHY_PUSHING_RIGHT                    52
-#define IMG_SP_MURPHY_SNAPPING_LEFT                    53
-#define IMG_SP_MURPHY_SNAPPING_RIGHT                   54
-#define IMG_SP_MURPHY_SNAPPING_UP                      55
-#define IMG_SP_MURPHY_SNAPPING_DOWN                    56
-#define IMG_SP_MURPHY_CLONE                            57
-#define IMG_SP_INFOTRON                                        58
-#define IMG_SP_INFOTRON_EDITOR                         59
-#define IMG_SP_CHIP_SINGLE                             60
-#define IMG_SP_CHIP_LEFT                               61
-#define IMG_SP_CHIP_RIGHT                              62
-#define IMG_SP_CHIP_TOP                                        63
-#define IMG_SP_CHIP_BOTTOM                             64
-#define IMG_SP_HARDWARE_GRAY                           65
-#define IMG_SP_HARDWARE_GREEN                          66
-#define IMG_SP_HARDWARE_BLUE                           67
-#define IMG_SP_HARDWARE_RED                            68
-#define IMG_SP_HARDWARE_YELLOW                         69
-#define IMG_SP_EXIT_CLOSED                             70
-#define IMG_SP_EXIT_OPENING                            71
-#define IMG_SP_EXIT_OPEN                               72
-#define IMG_SP_EXIT_CLOSING                            73
-#define IMG_SP_DISK_ORANGE                             74
-#define IMG_SP_DISK_YELLOW                             75
-#define IMG_SP_DISK_RED                                        76
-#define IMG_SP_DISK_RED_COLLECTING                     77
-#define IMG_SP_DISK_RED_ACTIVE                         78
-#define IMG_SP_PORT_RIGHT                              79
-#define IMG_SP_PORT_DOWN                               80
-#define IMG_SP_PORT_LEFT                               81
-#define IMG_SP_PORT_UP                                 82
-#define IMG_SP_PORT_HORIZONTAL                         83
-#define IMG_SP_PORT_VERTICAL                           84
-#define IMG_SP_PORT_ANY                                        85
-#define IMG_SP_GRAVITY_PORT_RIGHT                      86
-#define IMG_SP_GRAVITY_PORT_DOWN                       87
-#define IMG_SP_GRAVITY_PORT_LEFT                       88
-#define IMG_SP_GRAVITY_PORT_UP                         89
-#define IMG_SP_SNIKSNAK                                        90
-#define IMG_SP_SNIKSNAK_LEFT                           91
-#define IMG_SP_SNIKSNAK_RIGHT                          92
-#define IMG_SP_SNIKSNAK_UP                             93
-#define IMG_SP_SNIKSNAK_DOWN                           94
-#define IMG_SP_SNIKSNAK_TURNING_FROM_LEFT_UP           95
-#define IMG_SP_SNIKSNAK_TURNING_FROM_LEFT_DOWN         96
-#define IMG_SP_SNIKSNAK_TURNING_FROM_RIGHT_UP          97
-#define IMG_SP_SNIKSNAK_TURNING_FROM_RIGHT_DOWN                98
-#define IMG_SP_SNIKSNAK_TURNING_FROM_UP_LEFT           99
-#define IMG_SP_SNIKSNAK_TURNING_FROM_UP_RIGHT          100
-#define IMG_SP_SNIKSNAK_TURNING_FROM_DOWN_LEFT         101
-#define IMG_SP_SNIKSNAK_TURNING_FROM_DOWN_RIGHT                102
-#define IMG_SP_ELECTRON                                        103
-#define IMG_SP_ELECTRON_EDITOR                         104
-#define IMG_SP_ELECTRON_EXPLODING                      105
-#define IMG_SP_TERMINAL                                        106
-#define IMG_SP_TERMINAL_EDITOR                         107
-#define IMG_SP_TERMINAL_ACTIVE                         108
-#define IMG_SP_BUGGY_BASE                              109
-#define IMG_SP_BUGGY_BASE_EDITOR                       110
-#define IMG_SP_BUGGY_BASE_ACTIVATING                   111
-#define IMG_SP_BUGGY_BASE_ACTIVE                       112
-#define IMG_SP_HARDWARE_BASE_1                         113
-#define IMG_SP_HARDWARE_BASE_2                         114
-#define IMG_SP_HARDWARE_BASE_3                         115
-#define IMG_SP_HARDWARE_BASE_4                         116
-#define IMG_SP_HARDWARE_BASE_5                         117
-#define IMG_SP_HARDWARE_BASE_6                         118
-#define IMG_SOKOBAN_OBJECT                             119
-#define IMG_SOKOBAN_OBJECT_EDITOR                      120
-#define IMG_SOKOBAN_FIELD_EMPTY                                121
-#define IMG_SOKOBAN_FIELD_FULL                         122
-#define IMG_EMPTY_SPACE                                        123
-#define IMG_SAND                                       124
-#define IMG_SAND_CRUMBLED                              125
-#define IMG_SAND_DIGGING_LEFT                          126
-#define IMG_SAND_DIGGING_RIGHT                         127
-#define IMG_SAND_DIGGING_UP                            128
-#define IMG_SAND_DIGGING_DOWN                          129
-#define IMG_SAND_DIGGING_LEFT_CRUMBLED                 130
-#define IMG_SAND_DIGGING_RIGHT_CRUMBLED                        131
-#define IMG_SAND_DIGGING_UP_CRUMBLED                   132
-#define IMG_SAND_DIGGING_DOWN_CRUMBLED                 133
-#define IMG_WALL                                       134
-#define IMG_WALL_SLIPPERY                              135
-#define IMG_STEELWALL                                  136
-#define IMG_ROCK                                       137
-#define IMG_ROCK_MOVING_LEFT                           138
-#define IMG_ROCK_MOVING_RIGHT                          139
-#define IMG_ROCK_PUSHING_LEFT                          140
-#define IMG_ROCK_PUSHING_RIGHT                         141
-#define IMG_EMERALD                                    142
-#define IMG_EMERALD_MOVING                             143
-#define IMG_EMERALD_FALLING                            144
-#define IMG_EMERALD_COLLECTING                         145
-#define IMG_DIAMOND                                    146
-#define IMG_DIAMOND_MOVING                             147
-#define IMG_DIAMOND_FALLING                            148
-#define IMG_DIAMOND_COLLECTING                         149
-#define IMG_BOMB                                       150
-#define IMG_NUT                                                151
-#define IMG_NUT_BREAKING                               152
-#define IMG_DYNAMITE                                   153
-#define IMG_DYNAMITE_EDITOR                            154
-#define IMG_DYNAMITE_ACTIVE                            155
-#define IMG_DYNAMITE_ACTIVE_EDITOR                     156
-#define IMG_WALL_EMERALD                               157
-#define IMG_WALL_DIAMOND                               158
-#define IMG_BUG                                                159
-#define IMG_BUG_RIGHT                                  160
-#define IMG_BUG_UP                                     161
-#define IMG_BUG_LEFT                                   162
-#define IMG_BUG_DOWN                                   163
-#define IMG_BUG_MOVING_RIGHT                           164
-#define IMG_BUG_MOVING_UP                              165
-#define IMG_BUG_MOVING_LEFT                            166
-#define IMG_BUG_MOVING_DOWN                            167
-#define IMG_BUG_TURNING_FROM_RIGHT_UP                  168
-#define IMG_BUG_TURNING_FROM_UP_LEFT                   169
-#define IMG_BUG_TURNING_FROM_LEFT_DOWN                 170
-#define IMG_BUG_TURNING_FROM_DOWN_RIGHT                        171
-#define IMG_BUG_TURNING_FROM_RIGHT_DOWN                        172
-#define IMG_BUG_TURNING_FROM_UP_RIGHT                  173
-#define IMG_BUG_TURNING_FROM_LEFT_UP                   174
-#define IMG_BUG_TURNING_FROM_DOWN_LEFT                 175
-#define IMG_SPACESHIP                                  176
-#define IMG_SPACESHIP_RIGHT                            177
-#define IMG_SPACESHIP_UP                               178
-#define IMG_SPACESHIP_LEFT                             179
-#define IMG_SPACESHIP_DOWN                             180
-#define IMG_SPACESHIP_MOVING_RIGHT                     181
-#define IMG_SPACESHIP_MOVING_UP                                182
-#define IMG_SPACESHIP_MOVING_LEFT                      183
-#define IMG_SPACESHIP_MOVING_DOWN                      184
-#define IMG_SPACESHIP_TURNING_FROM_RIGHT_UP            185
-#define IMG_SPACESHIP_TURNING_FROM_UP_LEFT             186
-#define IMG_SPACESHIP_TURNING_FROM_LEFT_DOWN           187
-#define IMG_SPACESHIP_TURNING_FROM_DOWN_RIGHT          188
-#define IMG_SPACESHIP_TURNING_FROM_RIGHT_DOWN          189
-#define IMG_SPACESHIP_TURNING_FROM_UP_RIGHT            190
-#define IMG_SPACESHIP_TURNING_FROM_LEFT_UP             191
-#define IMG_SPACESHIP_TURNING_FROM_DOWN_LEFT           192
-#define IMG_YAMYAM                                     193
-#define IMG_YAMYAM_MOVING                              194
-#define IMG_ROBOT                                      195
-#define IMG_ROBOT_MOVING                               196
-#define IMG_ROBOT_WHEEL                                        197
-#define IMG_ROBOT_WHEEL_ACTIVE                         198
-#define IMG_MAGIC_WALL                                 199
-#define IMG_MAGIC_WALL_ACTIVE                          200
-#define IMG_MAGIC_WALL_FILLING                         201
-#define IMG_MAGIC_WALL_FULL                            202
-#define IMG_MAGIC_WALL_EMPTYING                                203
-#define IMG_MAGIC_WALL_DEAD                            204
-#define IMG_QUICKSAND_EMPTY                            205
-#define IMG_QUICKSAND_FILLING                          206
-#define IMG_QUICKSAND_FULL                             207
-#define IMG_QUICKSAND_FULL_EDITOR                      208
-#define IMG_QUICKSAND_EMPTYING                         209
-#define IMG_ACID_POOL_TOPLEFT                          210
-#define IMG_ACID_POOL_TOPRIGHT                         211
-#define IMG_ACID_POOL_BOTTOMLEFT                       212
-#define IMG_ACID_POOL_BOTTOM                           213
-#define IMG_ACID_POOL_BOTTOMRIGHT                      214
-#define IMG_ACID                                       215
-#define IMG_ACID_SPLASH_LEFT                           216
-#define IMG_ACID_SPLASH_RIGHT                          217
-#define IMG_AMOEBA_DROP                                        218
-#define IMG_AMOEBA_GROWING                             219
-#define IMG_AMOEBA_SHRINKING                           220
-#define IMG_AMOEBA_WET                                 221
-#define IMG_AMOEBA_WET_EDITOR                          222
-#define IMG_AMOEBA_DROPPING                            223
-#define IMG_AMOEBA_DRY                                 224
-#define IMG_AMOEBA_FULL                                        225
-#define IMG_AMOEBA_FULL_EDITOR                         226
-#define IMG_AMOEBA_DEAD                                        227
-#define IMG_AMOEBA_DEAD_EDITOR                         228
-#define IMG_EM_KEY_1                                   229
-#define IMG_EM_KEY_2                                   230
-#define IMG_EM_KEY_3                                   231
-#define IMG_EM_KEY_4                                   232
-#define IMG_EM_GATE_1                                  233
-#define IMG_EM_GATE_2                                  234
-#define IMG_EM_GATE_3                                  235
-#define IMG_EM_GATE_4                                  236
-#define IMG_EM_GATE_1_GRAY                             237
-#define IMG_EM_GATE_1_GRAY_EDITOR                      238
-#define IMG_EM_GATE_2_GRAY                             239
-#define IMG_EM_GATE_2_GRAY_EDITOR                      240
-#define IMG_EM_GATE_3_GRAY                             241
-#define IMG_EM_GATE_3_GRAY_EDITOR                      242
-#define IMG_EM_GATE_4_GRAY                             243
-#define IMG_EM_GATE_4_GRAY_EDITOR                      244
-#define IMG_EXIT_CLOSED                                        245
-#define IMG_EXIT_OPENING                               246
-#define IMG_EXIT_OPEN                                  247
-#define IMG_EXIT_CLOSING                               248
-#define IMG_BALLOON                                    249
-#define IMG_BALLOON_MOVING                             250
-#define IMG_BALLOON_PUSHING                            251
-#define IMG_BALLOON_SWITCH_LEFT                                252
-#define IMG_BALLOON_SWITCH_RIGHT                       253
-#define IMG_BALLOON_SWITCH_UP                          254
-#define IMG_BALLOON_SWITCH_DOWN                                255
-#define IMG_BALLOON_SWITCH_ANY                         256
-#define IMG_SPRING                                     257
-#define IMG_EMC_STEELWALL_1                            258
-#define IMG_EMC_STEELWALL_2                            259
-#define IMG_EMC_STEELWALL_3                            260
-#define IMG_EMC_STEELWALL_4                            261
-#define IMG_EMC_WALL_1                                 262
-#define IMG_EMC_WALL_2                                 263
-#define IMG_EMC_WALL_3                                 264
-#define IMG_EMC_WALL_4                                 265
-#define IMG_EMC_WALL_5                                 266
-#define IMG_EMC_WALL_6                                 267
-#define IMG_EMC_WALL_7                                 268
-#define IMG_EMC_WALL_8                                 269
-#define IMG_INVISIBLE_STEELWALL                                270
-#define IMG_INVISIBLE_STEELWALL_EDITOR                 271
-#define IMG_INVISIBLE_STEELWALL_ACTIVE                 272
-#define IMG_INVISIBLE_WALL                             273
-#define IMG_INVISIBLE_WALL_EDITOR                      274
-#define IMG_INVISIBLE_WALL_ACTIVE                      275
-#define IMG_INVISIBLE_SAND                             276
-#define IMG_INVISIBLE_SAND_EDITOR                      277
-#define IMG_INVISIBLE_SAND_ACTIVE                      278
-#define IMG_CONVEYOR_BELT_1_MIDDLE                     279
-#define IMG_CONVEYOR_BELT_1_MIDDLE_ACTIVE              280
-#define IMG_CONVEYOR_BELT_1_LEFT                       281
-#define IMG_CONVEYOR_BELT_1_LEFT_ACTIVE                        282
-#define IMG_CONVEYOR_BELT_1_RIGHT                      283
-#define IMG_CONVEYOR_BELT_1_RIGHT_ACTIVE               284
-#define IMG_CONVEYOR_BELT_1_SWITCH_LEFT                        285
-#define IMG_CONVEYOR_BELT_1_SWITCH_MIDDLE              286
-#define IMG_CONVEYOR_BELT_1_SWITCH_RIGHT               287
-#define IMG_CONVEYOR_BELT_2_MIDDLE                     288
-#define IMG_CONVEYOR_BELT_2_MIDDLE_ACTIVE              289
-#define IMG_CONVEYOR_BELT_2_LEFT                       290
-#define IMG_CONVEYOR_BELT_2_LEFT_ACTIVE                        291
-#define IMG_CONVEYOR_BELT_2_RIGHT                      292
-#define IMG_CONVEYOR_BELT_2_RIGHT_ACTIVE               293
-#define IMG_CONVEYOR_BELT_2_SWITCH_LEFT                        294
-#define IMG_CONVEYOR_BELT_2_SWITCH_MIDDLE              295
-#define IMG_CONVEYOR_BELT_2_SWITCH_RIGHT               296
-#define IMG_CONVEYOR_BELT_3_MIDDLE                     297
-#define IMG_CONVEYOR_BELT_3_MIDDLE_ACTIVE              298
-#define IMG_CONVEYOR_BELT_3_LEFT                       299
-#define IMG_CONVEYOR_BELT_3_LEFT_ACTIVE                        300
-#define IMG_CONVEYOR_BELT_3_RIGHT                      301
-#define IMG_CONVEYOR_BELT_3_RIGHT_ACTIVE               302
-#define IMG_CONVEYOR_BELT_3_SWITCH_LEFT                        303
-#define IMG_CONVEYOR_BELT_3_SWITCH_MIDDLE              304
-#define IMG_CONVEYOR_BELT_3_SWITCH_RIGHT               305
-#define IMG_CONVEYOR_BELT_4_MIDDLE                     306
-#define IMG_CONVEYOR_BELT_4_MIDDLE_ACTIVE              307
-#define IMG_CONVEYOR_BELT_4_LEFT                       308
-#define IMG_CONVEYOR_BELT_4_LEFT_ACTIVE                        309
-#define IMG_CONVEYOR_BELT_4_RIGHT                      310
-#define IMG_CONVEYOR_BELT_4_RIGHT_ACTIVE               311
-#define IMG_CONVEYOR_BELT_4_SWITCH_LEFT                        312
-#define IMG_CONVEYOR_BELT_4_SWITCH_MIDDLE              313
-#define IMG_CONVEYOR_BELT_4_SWITCH_RIGHT               314
-#define IMG_SWITCHGATE_SWITCH_UP                       315
-#define IMG_SWITCHGATE_SWITCH_DOWN                     316
-#define IMG_LIGHT_SWITCH                               317
-#define IMG_LIGHT_SWITCH_ACTIVE                                318
-#define IMG_TIMEGATE_SWITCH                            319
-#define IMG_TIMEGATE_SWITCH_ACTIVE                     320
-#define IMG_ENVELOPE_1                                 321
-#define IMG_ENVELOPE_1_COLLECTING                      322
-#define IMG_ENVELOPE_2                                 323
-#define IMG_ENVELOPE_2_COLLECTING                      324
-#define IMG_ENVELOPE_3                                 325
-#define IMG_ENVELOPE_3_COLLECTING                      326
-#define IMG_ENVELOPE_4                                 327
-#define IMG_ENVELOPE_4_COLLECTING                      328
-#define IMG_SIGN_EXCLAMATION                           329
-#define IMG_SIGN_STOP                                  330
-#define IMG_LANDMINE                                   331
-#define IMG_STEELWALL_SLIPPERY                         332
-#define IMG_EXTRA_TIME                                 333
-#define IMG_SHIELD_NORMAL                              334
-#define IMG_SHIELD_NORMAL_ACTIVE                       335
-#define IMG_SHIELD_DEADLY                              336
-#define IMG_SHIELD_DEADLY_ACTIVE                       337
-#define IMG_SWITCHGATE_CLOSED                          338
-#define IMG_SWITCHGATE_OPENING                         339
-#define IMG_SWITCHGATE_OPEN                            340
-#define IMG_SWITCHGATE_CLOSING                         341
-#define IMG_TIMEGATE_CLOSED                            342
-#define IMG_TIMEGATE_OPENING                           343
-#define IMG_TIMEGATE_OPEN                              344
-#define IMG_TIMEGATE_CLOSING                           345
-#define IMG_PEARL                                      346
-#define IMG_PEARL_BREAKING                             347
-#define IMG_CRYSTAL                                    348
-#define IMG_WALL_PEARL                                 349
-#define IMG_WALL_CRYSTAL                               350
-#define IMG_TUBE_RIGHT_DOWN                            351
-#define IMG_TUBE_HORIZONTAL_DOWN                       352
-#define IMG_TUBE_LEFT_DOWN                             353
-#define IMG_TUBE_HORIZONTAL                            354
-#define IMG_TUBE_VERTICAL_RIGHT                                355
-#define IMG_TUBE_ANY                                   356
-#define IMG_TUBE_VERTICAL_LEFT                         357
-#define IMG_TUBE_VERTICAL                              358
-#define IMG_TUBE_RIGHT_UP                              359
-#define IMG_TUBE_HORIZONTAL_UP                         360
-#define IMG_TUBE_LEFT_UP                               361
-#define IMG_TRAP                                       362
-#define IMG_TRAP_ACTIVE                                        363
-#define IMG_DX_SUPABOMB                                        364
-#define IMG_KEY_1                                      365
-#define IMG_KEY_1_EDITOR                               366
-#define IMG_KEY_2                                      367
-#define IMG_KEY_2_EDITOR                               368
-#define IMG_KEY_3                                      369
-#define IMG_KEY_3_EDITOR                               370
-#define IMG_KEY_4                                      371
-#define IMG_KEY_4_EDITOR                               372
-#define IMG_GATE_1                                     373
-#define IMG_GATE_2                                     374
-#define IMG_GATE_3                                     375
-#define IMG_GATE_4                                     376
-#define IMG_GATE_1_GRAY                                        377
-#define IMG_GATE_1_GRAY_EDITOR                         378
-#define IMG_GATE_2_GRAY                                        379
-#define IMG_GATE_2_GRAY_EDITOR                         380
-#define IMG_GATE_3_GRAY                                        381
-#define IMG_GATE_3_GRAY_EDITOR                         382
-#define IMG_GATE_4_GRAY                                        383
-#define IMG_GATE_4_GRAY_EDITOR                         384
-#define IMG_GAME_OF_LIFE                               385
-#define IMG_BIOMAZE                                    386
-#define IMG_PACMAN                                     387
-#define IMG_PACMAN_RIGHT                               388
-#define IMG_PACMAN_UP                                  389
-#define IMG_PACMAN_LEFT                                        390
-#define IMG_PACMAN_DOWN                                        391
-#define IMG_PACMAN_TURNING_FROM_RIGHT                  392
-#define IMG_PACMAN_TURNING_FROM_UP                     393
-#define IMG_PACMAN_TURNING_FROM_LEFT                   394
-#define IMG_PACMAN_TURNING_FROM_DOWN                   395
-#define IMG_LAMP                                       396
-#define IMG_LAMP_EDITOR                                        397
-#define IMG_LAMP_ACTIVE                                        398
-#define IMG_TIME_ORB_FULL                              399
-#define IMG_TIME_ORB_EMPTY                             400
-#define IMG_EMERALD_YELLOW                             401
-#define IMG_EMERALD_YELLOW_MOVING                      402
-#define IMG_EMERALD_YELLOW_FALLING                     403
-#define IMG_EMERALD_RED                                        404
-#define IMG_EMERALD_RED_MOVING                         405
-#define IMG_EMERALD_RED_FALLING                                406
-#define IMG_EMERALD_PURPLE                             407
-#define IMG_EMERALD_PURPLE_MOVING                      408
-#define IMG_EMERALD_PURPLE_FALLING                     409
-#define IMG_WALL_EMERALD_YELLOW                                410
-#define IMG_WALL_EMERALD_RED                           411
-#define IMG_WALL_EMERALD_PURPLE                                412
-#define IMG_WALL_BD_DIAMOND                            413
-#define IMG_EXPANDABLE_WALL                            414
-#define IMG_EXPANDABLE_WALL_HORIZONTAL                 415
-#define IMG_EXPANDABLE_WALL_HORIZONTAL_EDITOR          416
-#define IMG_EXPANDABLE_WALL_VERTICAL                   417
-#define IMG_EXPANDABLE_WALL_VERTICAL_EDITOR            418
-#define IMG_EXPANDABLE_WALL_ANY                                419
-#define IMG_EXPANDABLE_WALL_ANY_EDITOR                 420
-#define IMG_EXPANDABLE_WALL_GROWING_LEFT               421
-#define IMG_EXPANDABLE_WALL_GROWING_RIGHT              422
-#define IMG_EXPANDABLE_WALL_GROWING_UP                 423
-#define IMG_EXPANDABLE_WALL_GROWING_DOWN               424
-#define IMG_BLACK_ORB                                  425
-#define IMG_SPEED_PILL                                 426
-#define IMG_DARK_YAMYAM                                        427
-#define IMG_DYNABOMB                                   428
-#define IMG_DYNABOMB_ACTIVE                            429
-#define IMG_DYNABOMB_PLAYER_1                          430
-#define IMG_DYNABOMB_PLAYER_1_ACTIVE                   431
-#define IMG_DYNABOMB_PLAYER_2                          432
-#define IMG_DYNABOMB_PLAYER_2_ACTIVE                   433
-#define IMG_DYNABOMB_PLAYER_3                          434
-#define IMG_DYNABOMB_PLAYER_3_ACTIVE                   435
-#define IMG_DYNABOMB_PLAYER_4                          436
-#define IMG_DYNABOMB_PLAYER_4_ACTIVE                   437
-#define IMG_DYNABOMB_INCREASE_NUMBER                   438
-#define IMG_DYNABOMB_INCREASE_SIZE                     439
-#define IMG_DYNABOMB_INCREASE_POWER                    440
-#define IMG_PIG                                                441
-#define IMG_PIG_DOWN                                   442
-#define IMG_PIG_UP                                     443
-#define IMG_PIG_LEFT                                   444
-#define IMG_PIG_RIGHT                                  445
-#define IMG_PIG_MOVING_DOWN                            446
-#define IMG_PIG_MOVING_UP                              447
-#define IMG_PIG_MOVING_LEFT                            448
-#define IMG_PIG_MOVING_RIGHT                           449
-#define IMG_PIG_DIGGING_DOWN                           450
-#define IMG_PIG_DIGGING_UP                             451
-#define IMG_PIG_DIGGING_LEFT                           452
-#define IMG_PIG_DIGGING_RIGHT                          453
-#define IMG_DRAGON                                     454
-#define IMG_DRAGON_DOWN                                        455
-#define IMG_DRAGON_UP                                  456
-#define IMG_DRAGON_LEFT                                        457
-#define IMG_DRAGON_RIGHT                               458
-#define IMG_DRAGON_MOVING_DOWN                         459
-#define IMG_DRAGON_MOVING_UP                           460
-#define IMG_DRAGON_MOVING_LEFT                         461
-#define IMG_DRAGON_MOVING_RIGHT                                462
-#define IMG_DRAGON_ATTACKING_DOWN                      463
-#define IMG_DRAGON_ATTACKING_UP                                464
-#define IMG_DRAGON_ATTACKING_LEFT                      465
-#define IMG_DRAGON_ATTACKING_RIGHT                     466
-#define IMG_MOLE                                       467
-#define IMG_MOLE_DOWN                                  468
-#define IMG_MOLE_UP                                    469
-#define IMG_MOLE_LEFT                                  470
-#define IMG_MOLE_RIGHT                                 471
-#define IMG_MOLE_MOVING_DOWN                           472
-#define IMG_MOLE_MOVING_UP                             473
-#define IMG_MOLE_MOVING_LEFT                           474
-#define IMG_MOLE_MOVING_RIGHT                          475
-#define IMG_MOLE_DIGGING_DOWN                          476
-#define IMG_MOLE_DIGGING_UP                            477
-#define IMG_MOLE_DIGGING_LEFT                          478
-#define IMG_MOLE_DIGGING_RIGHT                         479
-#define IMG_PENGUIN                                    480
-#define IMG_PENGUIN_EDITOR                             481
-#define IMG_PENGUIN_DOWN                               482
-#define IMG_PENGUIN_UP                                 483
-#define IMG_PENGUIN_LEFT                               484
-#define IMG_PENGUIN_RIGHT                              485
-#define IMG_PENGUIN_MOVING_DOWN                                486
-#define IMG_PENGUIN_MOVING_UP                          487
-#define IMG_PENGUIN_MOVING_LEFT                                488
-#define IMG_PENGUIN_MOVING_RIGHT                       489
-#define IMG_SATELLITE                                  490
-#define IMG_FLAMES_1_LEFT                              491
-#define IMG_FLAMES_2_LEFT                              492
-#define IMG_FLAMES_3_LEFT                              493
-#define IMG_FLAMES_1_RIGHT                             494
-#define IMG_FLAMES_2_RIGHT                             495
-#define IMG_FLAMES_3_RIGHT                             496
-#define IMG_FLAMES_1_UP                                        497
-#define IMG_FLAMES_2_UP                                        498
-#define IMG_FLAMES_3_UP                                        499
-#define IMG_FLAMES_1_DOWN                              500
-#define IMG_FLAMES_2_DOWN                              501
-#define IMG_FLAMES_3_DOWN                              502
-#define IMG_STONEBLOCK                                 503
-#define IMG_PLAYER_1                                   504
-#define IMG_PLAYER_1_EDITOR                            505
-#define IMG_PLAYER_1_DOWN                              506
-#define IMG_PLAYER_1_UP                                        507
-#define IMG_PLAYER_1_LEFT                              508
-#define IMG_PLAYER_1_RIGHT                             509
-#define IMG_PLAYER_1_MOVING_DOWN                       510
-#define IMG_PLAYER_1_MOVING_UP                         511
-#define IMG_PLAYER_1_MOVING_LEFT                       512
-#define IMG_PLAYER_1_MOVING_RIGHT                      513
-#define IMG_PLAYER_1_DIGGING_DOWN                      514
-#define IMG_PLAYER_1_DIGGING_UP                                515
-#define IMG_PLAYER_1_DIGGING_LEFT                      516
-#define IMG_PLAYER_1_DIGGING_RIGHT                     517
-#define IMG_PLAYER_1_COLLECTING_DOWN                   518
-#define IMG_PLAYER_1_COLLECTING_UP                     519
-#define IMG_PLAYER_1_COLLECTING_LEFT                   520
-#define IMG_PLAYER_1_COLLECTING_RIGHT                  521
-#define IMG_PLAYER_1_PUSHING_DOWN                      522
-#define IMG_PLAYER_1_PUSHING_UP                                523
-#define IMG_PLAYER_1_PUSHING_LEFT                      524
-#define IMG_PLAYER_1_PUSHING_RIGHT                     525
-#define IMG_PLAYER_1_SNAPPING_DOWN                     526
-#define IMG_PLAYER_1_SNAPPING_UP                       527
-#define IMG_PLAYER_1_SNAPPING_LEFT                     528
-#define IMG_PLAYER_1_SNAPPING_RIGHT                    529
-#define IMG_PLAYER_2                                   530
-#define IMG_PLAYER_2_EDITOR                            531
-#define IMG_PLAYER_2_DOWN                              532
-#define IMG_PLAYER_2_UP                                        533
-#define IMG_PLAYER_2_LEFT                              534
-#define IMG_PLAYER_2_RIGHT                             535
-#define IMG_PLAYER_2_MOVING_DOWN                       536
-#define IMG_PLAYER_2_MOVING_UP                         537
-#define IMG_PLAYER_2_MOVING_LEFT                       538
-#define IMG_PLAYER_2_MOVING_RIGHT                      539
-#define IMG_PLAYER_2_DIGGING_DOWN                      540
-#define IMG_PLAYER_2_DIGGING_UP                                541
-#define IMG_PLAYER_2_DIGGING_LEFT                      542
-#define IMG_PLAYER_2_DIGGING_RIGHT                     543
-#define IMG_PLAYER_2_COLLECTING_DOWN                   544
-#define IMG_PLAYER_2_COLLECTING_UP                     545
-#define IMG_PLAYER_2_COLLECTING_LEFT                   546
-#define IMG_PLAYER_2_COLLECTING_RIGHT                  547
-#define IMG_PLAYER_2_PUSHING_DOWN                      548
-#define IMG_PLAYER_2_PUSHING_UP                                549
-#define IMG_PLAYER_2_PUSHING_LEFT                      550
-#define IMG_PLAYER_2_PUSHING_RIGHT                     551
-#define IMG_PLAYER_2_SNAPPING_DOWN                     552
-#define IMG_PLAYER_2_SNAPPING_UP                       553
-#define IMG_PLAYER_2_SNAPPING_LEFT                     554
-#define IMG_PLAYER_2_SNAPPING_RIGHT                    555
-#define IMG_PLAYER_3                                   556
-#define IMG_PLAYER_3_EDITOR                            557
-#define IMG_PLAYER_3_DOWN                              558
-#define IMG_PLAYER_3_UP                                        559
-#define IMG_PLAYER_3_LEFT                              560
-#define IMG_PLAYER_3_RIGHT                             561
-#define IMG_PLAYER_3_MOVING_DOWN                       562
-#define IMG_PLAYER_3_MOVING_UP                         563
-#define IMG_PLAYER_3_MOVING_LEFT                       564
-#define IMG_PLAYER_3_MOVING_RIGHT                      565
-#define IMG_PLAYER_3_DIGGING_DOWN                      566
-#define IMG_PLAYER_3_DIGGING_UP                                567
-#define IMG_PLAYER_3_DIGGING_LEFT                      568
-#define IMG_PLAYER_3_DIGGING_RIGHT                     569
-#define IMG_PLAYER_3_COLLECTING_DOWN                   570
-#define IMG_PLAYER_3_COLLECTING_UP                     571
-#define IMG_PLAYER_3_COLLECTING_LEFT                   572
-#define IMG_PLAYER_3_COLLECTING_RIGHT                  573
-#define IMG_PLAYER_3_PUSHING_DOWN                      574
-#define IMG_PLAYER_3_PUSHING_UP                                575
-#define IMG_PLAYER_3_PUSHING_LEFT                      576
-#define IMG_PLAYER_3_PUSHING_RIGHT                     577
-#define IMG_PLAYER_3_SNAPPING_DOWN                     578
-#define IMG_PLAYER_3_SNAPPING_UP                       579
-#define IMG_PLAYER_3_SNAPPING_LEFT                     580
-#define IMG_PLAYER_3_SNAPPING_RIGHT                    581
-#define IMG_PLAYER_4                                   582
-#define IMG_PLAYER_4_EDITOR                            583
-#define IMG_PLAYER_4_DOWN                              584
-#define IMG_PLAYER_4_UP                                        585
-#define IMG_PLAYER_4_LEFT                              586
-#define IMG_PLAYER_4_RIGHT                             587
-#define IMG_PLAYER_4_MOVING_DOWN                       588
-#define IMG_PLAYER_4_MOVING_UP                         589
-#define IMG_PLAYER_4_MOVING_LEFT                       590
-#define IMG_PLAYER_4_MOVING_RIGHT                      591
-#define IMG_PLAYER_4_DIGGING_DOWN                      592
-#define IMG_PLAYER_4_DIGGING_UP                                593
-#define IMG_PLAYER_4_DIGGING_LEFT                      594
-#define IMG_PLAYER_4_DIGGING_RIGHT                     595
-#define IMG_PLAYER_4_COLLECTING_DOWN                   596
-#define IMG_PLAYER_4_COLLECTING_UP                     597
-#define IMG_PLAYER_4_COLLECTING_LEFT                   598
-#define IMG_PLAYER_4_COLLECTING_RIGHT                  599
-#define IMG_PLAYER_4_PUSHING_DOWN                      600
-#define IMG_PLAYER_4_PUSHING_UP                                601
-#define IMG_PLAYER_4_PUSHING_LEFT                      602
-#define IMG_PLAYER_4_PUSHING_RIGHT                     603
-#define IMG_PLAYER_4_SNAPPING_DOWN                     604
-#define IMG_PLAYER_4_SNAPPING_UP                       605
-#define IMG_PLAYER_4_SNAPPING_LEFT                     606
-#define IMG_PLAYER_4_SNAPPING_RIGHT                    607
-#define IMG_DEFAULT_EXPLODING                          608
-#define IMG_TWINKLE_BLUE                               609
-#define IMG_TWINKLE_WHITE                              610
-#define IMG_STEELWALL_TOPLEFT                          611
-#define IMG_STEELWALL_TOPRIGHT                         612
-#define IMG_STEELWALL_BOTTOMLEFT                       613
-#define IMG_STEELWALL_BOTTOMRIGHT                      614
-#define IMG_STEELWALL_HORIZONTAL                       615
-#define IMG_STEELWALL_VERTICAL                         616
-#define IMG_STEELWALL_TOPLEFT_EDITOR                   617
-#define IMG_STEELWALL_TOPRIGHT_EDITOR                  618
-#define IMG_STEELWALL_BOTTOMLEFT_EDITOR                        619
-#define IMG_STEELWALL_BOTTOMRIGHT_EDITOR               620
-#define IMG_STEELWALL_HORIZONTAL_EDITOR                        621
-#define IMG_STEELWALL_VERTICAL_EDITOR                  622
-#define IMG_INVISIBLE_STEELWALL_TOPLEFT                        623
-#define IMG_INVISIBLE_STEELWALL_TOPRIGHT               624
-#define IMG_INVISIBLE_STEELWALL_BOTTOMLEFT             625
-#define IMG_INVISIBLE_STEELWALL_BOTTOMRIGHT            626
-#define IMG_INVISIBLE_STEELWALL_HORIZONTAL             627
-#define IMG_INVISIBLE_STEELWALL_VERTICAL               628
-#define IMG_INVISIBLE_STEELWALL_TOPLEFT_EDITOR         629
-#define IMG_INVISIBLE_STEELWALL_TOPRIGHT_EDITOR                630
-#define IMG_INVISIBLE_STEELWALL_BOTTOMLEFT_EDITOR      631
-#define IMG_INVISIBLE_STEELWALL_BOTTOMRIGHT_EDITOR     632
-#define IMG_INVISIBLE_STEELWALL_HORIZONTAL_EDITOR      633
-#define IMG_INVISIBLE_STEELWALL_VERTICAL_EDITOR                634
-#define IMG_ARROW_LEFT                                 635
-#define IMG_ARROW_RIGHT                                        636
-#define IMG_ARROW_UP                                   637
-#define IMG_ARROW_DOWN                                 638
-#define IMG_CHAR_SPACE                                 639
-#define IMG_CHAR_EXCLAM                                        640
-#define IMG_CHAR_QUOTEDBL                              641
-#define IMG_CHAR_NUMBERSIGN                            642
-#define IMG_CHAR_DOLLAR                                        643
-#define IMG_CHAR_PROCENT                               644
-#define IMG_CHAR_AMPERSAND                             645
-#define IMG_CHAR_APOSTROPHE                            646
-#define IMG_CHAR_PARENLEFT                             647
-#define IMG_CHAR_PARENRIGHT                            648
-#define IMG_CHAR_ASTERISK                              649
-#define IMG_CHAR_PLUS                                  650
-#define IMG_CHAR_COMMA                                 651
-#define IMG_CHAR_MINUS                                 652
-#define IMG_CHAR_PERIOD                                        653
-#define IMG_CHAR_SLASH                                 654
-#define IMG_CHAR_0                                     655
-#define IMG_CHAR_1                                     656
-#define IMG_CHAR_2                                     657
-#define IMG_CHAR_3                                     658
-#define IMG_CHAR_4                                     659
-#define IMG_CHAR_5                                     660
-#define IMG_CHAR_6                                     661
-#define IMG_CHAR_7                                     662
-#define IMG_CHAR_8                                     663
-#define IMG_CHAR_9                                     664
-#define IMG_CHAR_COLON                                 665
-#define IMG_CHAR_SEMICOLON                             666
-#define IMG_CHAR_LESS                                  667
-#define IMG_CHAR_EQUAL                                 668
-#define IMG_CHAR_GREATER                               669
-#define IMG_CHAR_QUESTION                              670
-#define IMG_CHAR_AT                                    671
-#define IMG_CHAR_A                                     672
-#define IMG_CHAR_B                                     673
-#define IMG_CHAR_C                                     674
-#define IMG_CHAR_D                                     675
-#define IMG_CHAR_E                                     676
-#define IMG_CHAR_F                                     677
-#define IMG_CHAR_G                                     678
-#define IMG_CHAR_H                                     679
-#define IMG_CHAR_I                                     680
-#define IMG_CHAR_J                                     681
-#define IMG_CHAR_K                                     682
-#define IMG_CHAR_L                                     683
-#define IMG_CHAR_M                                     684
-#define IMG_CHAR_N                                     685
-#define IMG_CHAR_O                                     686
-#define IMG_CHAR_P                                     687
-#define IMG_CHAR_Q                                     688
-#define IMG_CHAR_R                                     689
-#define IMG_CHAR_S                                     690
-#define IMG_CHAR_T                                     691
-#define IMG_CHAR_U                                     692
-#define IMG_CHAR_V                                     693
-#define IMG_CHAR_W                                     694
-#define IMG_CHAR_X                                     695
-#define IMG_CHAR_Y                                     696
-#define IMG_CHAR_Z                                     697
-#define IMG_CHAR_BRACKETLEFT                           698
-#define IMG_CHAR_BACKSLASH                             699
-#define IMG_CHAR_BRACKETRIGHT                          700
-#define IMG_CHAR_ASCIICIRCUM                           701
-#define IMG_CHAR_UNDERSCORE                            702
-#define IMG_CHAR_COPYRIGHT                             703
-#define IMG_CHAR_AUMLAUT                               704
-#define IMG_CHAR_OUMLAUT                               705
-#define IMG_CHAR_UUMLAUT                               706
-#define IMG_CHAR_DEGREE                                        707
-#define IMG_CHAR_TRADEMARK                             708
-#define IMG_CHAR_CURSOR                                        709
-#define IMG_CUSTOM_1                                   710
-#define IMG_CUSTOM_1_EDITOR                            711
-#define IMG_CUSTOM_2                                   712
-#define IMG_CUSTOM_2_EDITOR                            713
-#define IMG_CUSTOM_3                                   714
-#define IMG_CUSTOM_3_EDITOR                            715
-#define IMG_CUSTOM_4                                   716
-#define IMG_CUSTOM_4_EDITOR                            717
-#define IMG_CUSTOM_5                                   718
-#define IMG_CUSTOM_5_EDITOR                            719
-#define IMG_CUSTOM_6                                   720
-#define IMG_CUSTOM_6_EDITOR                            721
-#define IMG_CUSTOM_7                                   722
-#define IMG_CUSTOM_7_EDITOR                            723
-#define IMG_CUSTOM_8                                   724
-#define IMG_CUSTOM_8_EDITOR                            725
-#define IMG_CUSTOM_9                                   726
-#define IMG_CUSTOM_9_EDITOR                            727
-#define IMG_CUSTOM_10                                  728
-#define IMG_CUSTOM_10_EDITOR                           729
-#define IMG_CUSTOM_11                                  730
-#define IMG_CUSTOM_11_EDITOR                           731
-#define IMG_CUSTOM_12                                  732
-#define IMG_CUSTOM_12_EDITOR                           733
-#define IMG_CUSTOM_13                                  734
-#define IMG_CUSTOM_13_EDITOR                           735
-#define IMG_CUSTOM_14                                  736
-#define IMG_CUSTOM_14_EDITOR                           737
-#define IMG_CUSTOM_15                                  738
-#define IMG_CUSTOM_15_EDITOR                           739
-#define IMG_CUSTOM_16                                  740
-#define IMG_CUSTOM_16_EDITOR                           741
-#define IMG_CUSTOM_17                                  742
-#define IMG_CUSTOM_17_EDITOR                           743
-#define IMG_CUSTOM_18                                  744
-#define IMG_CUSTOM_18_EDITOR                           745
-#define IMG_CUSTOM_19                                  746
-#define IMG_CUSTOM_19_EDITOR                           747
-#define IMG_CUSTOM_20                                  748
-#define IMG_CUSTOM_20_EDITOR                           749
-#define IMG_CUSTOM_21                                  750
-#define IMG_CUSTOM_21_EDITOR                           751
-#define IMG_CUSTOM_22                                  752
-#define IMG_CUSTOM_22_EDITOR                           753
-#define IMG_CUSTOM_23                                  754
-#define IMG_CUSTOM_23_EDITOR                           755
-#define IMG_CUSTOM_24                                  756
-#define IMG_CUSTOM_24_EDITOR                           757
-#define IMG_CUSTOM_25                                  758
-#define IMG_CUSTOM_25_EDITOR                           759
-#define IMG_CUSTOM_26                                  760
-#define IMG_CUSTOM_26_EDITOR                           761
-#define IMG_CUSTOM_27                                  762
-#define IMG_CUSTOM_27_EDITOR                           763
-#define IMG_CUSTOM_28                                  764
-#define IMG_CUSTOM_28_EDITOR                           765
-#define IMG_CUSTOM_29                                  766
-#define IMG_CUSTOM_29_EDITOR                           767
-#define IMG_CUSTOM_30                                  768
-#define IMG_CUSTOM_30_EDITOR                           769
-#define IMG_CUSTOM_31                                  770
-#define IMG_CUSTOM_31_EDITOR                           771
-#define IMG_CUSTOM_32                                  772
-#define IMG_CUSTOM_32_EDITOR                           773
-#define IMG_CUSTOM_33                                  774
-#define IMG_CUSTOM_33_EDITOR                           775
-#define IMG_CUSTOM_34                                  776
-#define IMG_CUSTOM_34_EDITOR                           777
-#define IMG_CUSTOM_35                                  778
-#define IMG_CUSTOM_35_EDITOR                           779
-#define IMG_CUSTOM_36                                  780
-#define IMG_CUSTOM_36_EDITOR                           781
-#define IMG_CUSTOM_37                                  782
-#define IMG_CUSTOM_37_EDITOR                           783
-#define IMG_CUSTOM_38                                  784
-#define IMG_CUSTOM_38_EDITOR                           785
-#define IMG_CUSTOM_39                                  786
-#define IMG_CUSTOM_39_EDITOR                           787
-#define IMG_CUSTOM_40                                  788
-#define IMG_CUSTOM_40_EDITOR                           789
-#define IMG_CUSTOM_41                                  790
-#define IMG_CUSTOM_41_EDITOR                           791
-#define IMG_CUSTOM_42                                  792
-#define IMG_CUSTOM_42_EDITOR                           793
-#define IMG_CUSTOM_43                                  794
-#define IMG_CUSTOM_43_EDITOR                           795
-#define IMG_CUSTOM_44                                  796
-#define IMG_CUSTOM_44_EDITOR                           797
-#define IMG_CUSTOM_45                                  798
-#define IMG_CUSTOM_45_EDITOR                           799
-#define IMG_CUSTOM_46                                  800
-#define IMG_CUSTOM_46_EDITOR                           801
-#define IMG_CUSTOM_47                                  802
-#define IMG_CUSTOM_47_EDITOR                           803
-#define IMG_CUSTOM_48                                  804
-#define IMG_CUSTOM_48_EDITOR                           805
-#define IMG_CUSTOM_49                                  806
-#define IMG_CUSTOM_49_EDITOR                           807
-#define IMG_CUSTOM_50                                  808
-#define IMG_CUSTOM_50_EDITOR                           809
-#define IMG_CUSTOM_51                                  810
-#define IMG_CUSTOM_51_EDITOR                           811
-#define IMG_CUSTOM_52                                  812
-#define IMG_CUSTOM_52_EDITOR                           813
-#define IMG_CUSTOM_53                                  814
-#define IMG_CUSTOM_53_EDITOR                           815
-#define IMG_CUSTOM_54                                  816
-#define IMG_CUSTOM_54_EDITOR                           817
-#define IMG_CUSTOM_55                                  818
-#define IMG_CUSTOM_55_EDITOR                           819
-#define IMG_CUSTOM_56                                  820
-#define IMG_CUSTOM_56_EDITOR                           821
-#define IMG_CUSTOM_57                                  822
-#define IMG_CUSTOM_57_EDITOR                           823
-#define IMG_CUSTOM_58                                  824
-#define IMG_CUSTOM_58_EDITOR                           825
-#define IMG_CUSTOM_59                                  826
-#define IMG_CUSTOM_59_EDITOR                           827
-#define IMG_CUSTOM_60                                  828
-#define IMG_CUSTOM_60_EDITOR                           829
-#define IMG_CUSTOM_61                                  830
-#define IMG_CUSTOM_61_EDITOR                           831
-#define IMG_CUSTOM_62                                  832
-#define IMG_CUSTOM_62_EDITOR                           833
-#define IMG_CUSTOM_63                                  834
-#define IMG_CUSTOM_63_EDITOR                           835
-#define IMG_CUSTOM_64                                  836
-#define IMG_CUSTOM_64_EDITOR                           837
-#define IMG_CUSTOM_65                                  838
-#define IMG_CUSTOM_65_EDITOR                           839
-#define IMG_CUSTOM_66                                  840
-#define IMG_CUSTOM_66_EDITOR                           841
-#define IMG_CUSTOM_67                                  842
-#define IMG_CUSTOM_67_EDITOR                           843
-#define IMG_CUSTOM_68                                  844
-#define IMG_CUSTOM_68_EDITOR                           845
-#define IMG_CUSTOM_69                                  846
-#define IMG_CUSTOM_69_EDITOR                           847
-#define IMG_CUSTOM_70                                  848
-#define IMG_CUSTOM_70_EDITOR                           849
-#define IMG_CUSTOM_71                                  850
-#define IMG_CUSTOM_71_EDITOR                           851
-#define IMG_CUSTOM_72                                  852
-#define IMG_CUSTOM_72_EDITOR                           853
-#define IMG_CUSTOM_73                                  854
-#define IMG_CUSTOM_73_EDITOR                           855
-#define IMG_CUSTOM_74                                  856
-#define IMG_CUSTOM_74_EDITOR                           857
-#define IMG_CUSTOM_75                                  858
-#define IMG_CUSTOM_75_EDITOR                           859
-#define IMG_CUSTOM_76                                  860
-#define IMG_CUSTOM_76_EDITOR                           861
-#define IMG_CUSTOM_77                                  862
-#define IMG_CUSTOM_77_EDITOR                           863
-#define IMG_CUSTOM_78                                  864
-#define IMG_CUSTOM_78_EDITOR                           865
-#define IMG_CUSTOM_79                                  866
-#define IMG_CUSTOM_79_EDITOR                           867
-#define IMG_CUSTOM_80                                  868
-#define IMG_CUSTOM_80_EDITOR                           869
-#define IMG_CUSTOM_81                                  870
-#define IMG_CUSTOM_81_EDITOR                           871
-#define IMG_CUSTOM_82                                  872
-#define IMG_CUSTOM_82_EDITOR                           873
-#define IMG_CUSTOM_83                                  874
-#define IMG_CUSTOM_83_EDITOR                           875
-#define IMG_CUSTOM_84                                  876
-#define IMG_CUSTOM_84_EDITOR                           877
-#define IMG_CUSTOM_85                                  878
-#define IMG_CUSTOM_85_EDITOR                           879
-#define IMG_CUSTOM_86                                  880
-#define IMG_CUSTOM_86_EDITOR                           881
-#define IMG_CUSTOM_87                                  882
-#define IMG_CUSTOM_87_EDITOR                           883
-#define IMG_CUSTOM_88                                  884
-#define IMG_CUSTOM_88_EDITOR                           885
-#define IMG_CUSTOM_89                                  886
-#define IMG_CUSTOM_89_EDITOR                           887
-#define IMG_CUSTOM_90                                  888
-#define IMG_CUSTOM_90_EDITOR                           889
-#define IMG_CUSTOM_91                                  890
-#define IMG_CUSTOM_91_EDITOR                           891
-#define IMG_CUSTOM_92                                  892
-#define IMG_CUSTOM_92_EDITOR                           893
-#define IMG_CUSTOM_93                                  894
-#define IMG_CUSTOM_93_EDITOR                           895
-#define IMG_CUSTOM_94                                  896
-#define IMG_CUSTOM_94_EDITOR                           897
-#define IMG_CUSTOM_95                                  898
-#define IMG_CUSTOM_95_EDITOR                           899
-#define IMG_CUSTOM_96                                  900
-#define IMG_CUSTOM_96_EDITOR                           901
-#define IMG_CUSTOM_97                                  902
-#define IMG_CUSTOM_97_EDITOR                           903
-#define IMG_CUSTOM_98                                  904
-#define IMG_CUSTOM_98_EDITOR                           905
-#define IMG_CUSTOM_99                                  906
-#define IMG_CUSTOM_99_EDITOR                           907
-#define IMG_CUSTOM_100                                 908
-#define IMG_CUSTOM_100_EDITOR                          909
-#define IMG_CUSTOM_101                                 910
-#define IMG_CUSTOM_101_EDITOR                          911
-#define IMG_CUSTOM_102                                 912
-#define IMG_CUSTOM_102_EDITOR                          913
-#define IMG_CUSTOM_103                                 914
-#define IMG_CUSTOM_103_EDITOR                          915
-#define IMG_CUSTOM_104                                 916
-#define IMG_CUSTOM_104_EDITOR                          917
-#define IMG_CUSTOM_105                                 918
-#define IMG_CUSTOM_105_EDITOR                          919
-#define IMG_CUSTOM_106                                 920
-#define IMG_CUSTOM_106_EDITOR                          921
-#define IMG_CUSTOM_107                                 922
-#define IMG_CUSTOM_107_EDITOR                          923
-#define IMG_CUSTOM_108                                 924
-#define IMG_CUSTOM_108_EDITOR                          925
-#define IMG_CUSTOM_109                                 926
-#define IMG_CUSTOM_109_EDITOR                          927
-#define IMG_CUSTOM_110                                 928
-#define IMG_CUSTOM_110_EDITOR                          929
-#define IMG_CUSTOM_111                                 930
-#define IMG_CUSTOM_111_EDITOR                          931
-#define IMG_CUSTOM_112                                 932
-#define IMG_CUSTOM_112_EDITOR                          933
-#define IMG_CUSTOM_113                                 934
-#define IMG_CUSTOM_113_EDITOR                          935
-#define IMG_CUSTOM_114                                 936
-#define IMG_CUSTOM_114_EDITOR                          937
-#define IMG_CUSTOM_115                                 938
-#define IMG_CUSTOM_115_EDITOR                          939
-#define IMG_CUSTOM_116                                 940
-#define IMG_CUSTOM_116_EDITOR                          941
-#define IMG_CUSTOM_117                                 942
-#define IMG_CUSTOM_117_EDITOR                          943
-#define IMG_CUSTOM_118                                 944
-#define IMG_CUSTOM_118_EDITOR                          945
-#define IMG_CUSTOM_119                                 946
-#define IMG_CUSTOM_119_EDITOR                          947
-#define IMG_CUSTOM_120                                 948
-#define IMG_CUSTOM_120_EDITOR                          949
-#define IMG_CUSTOM_121                                 950
-#define IMG_CUSTOM_121_EDITOR                          951
-#define IMG_CUSTOM_122                                 952
-#define IMG_CUSTOM_122_EDITOR                          953
-#define IMG_CUSTOM_123                                 954
-#define IMG_CUSTOM_123_EDITOR                          955
-#define IMG_CUSTOM_124                                 956
-#define IMG_CUSTOM_124_EDITOR                          957
-#define IMG_CUSTOM_125                                 958
-#define IMG_CUSTOM_125_EDITOR                          959
-#define IMG_CUSTOM_126                                 960
-#define IMG_CUSTOM_126_EDITOR                          961
-#define IMG_CUSTOM_127                                 962
-#define IMG_CUSTOM_127_EDITOR                          963
-#define IMG_CUSTOM_128                                 964
-#define IMG_CUSTOM_128_EDITOR                          965
-#define IMG_CUSTOM_129                                 966
-#define IMG_CUSTOM_129_EDITOR                          967
-#define IMG_CUSTOM_130                                 968
-#define IMG_CUSTOM_130_EDITOR                          969
-#define IMG_CUSTOM_131                                 970
-#define IMG_CUSTOM_131_EDITOR                          971
-#define IMG_CUSTOM_132                                 972
-#define IMG_CUSTOM_132_EDITOR                          973
-#define IMG_CUSTOM_133                                 974
-#define IMG_CUSTOM_133_EDITOR                          975
-#define IMG_CUSTOM_134                                 976
-#define IMG_CUSTOM_134_EDITOR                          977
-#define IMG_CUSTOM_135                                 978
-#define IMG_CUSTOM_135_EDITOR                          979
-#define IMG_CUSTOM_136                                 980
-#define IMG_CUSTOM_136_EDITOR                          981
-#define IMG_CUSTOM_137                                 982
-#define IMG_CUSTOM_137_EDITOR                          983
-#define IMG_CUSTOM_138                                 984
-#define IMG_CUSTOM_138_EDITOR                          985
-#define IMG_CUSTOM_139                                 986
-#define IMG_CUSTOM_139_EDITOR                          987
-#define IMG_CUSTOM_140                                 988
-#define IMG_CUSTOM_140_EDITOR                          989
-#define IMG_CUSTOM_141                                 990
-#define IMG_CUSTOM_141_EDITOR                          991
-#define IMG_CUSTOM_142                                 992
-#define IMG_CUSTOM_142_EDITOR                          993
-#define IMG_CUSTOM_143                                 994
-#define IMG_CUSTOM_143_EDITOR                          995
-#define IMG_CUSTOM_144                                 996
-#define IMG_CUSTOM_144_EDITOR                          997
-#define IMG_CUSTOM_145                                 998
-#define IMG_CUSTOM_145_EDITOR                          999
-#define IMG_CUSTOM_146                                 1000
-#define IMG_CUSTOM_146_EDITOR                          1001
-#define IMG_CUSTOM_147                                 1002
-#define IMG_CUSTOM_147_EDITOR                          1003
-#define IMG_CUSTOM_148                                 1004
-#define IMG_CUSTOM_148_EDITOR                          1005
-#define IMG_CUSTOM_149                                 1006
-#define IMG_CUSTOM_149_EDITOR                          1007
-#define IMG_CUSTOM_150                                 1008
-#define IMG_CUSTOM_150_EDITOR                          1009
-#define IMG_CUSTOM_151                                 1010
-#define IMG_CUSTOM_151_EDITOR                          1011
-#define IMG_CUSTOM_152                                 1012
-#define IMG_CUSTOM_152_EDITOR                          1013
-#define IMG_CUSTOM_153                                 1014
-#define IMG_CUSTOM_153_EDITOR                          1015
-#define IMG_CUSTOM_154                                 1016
-#define IMG_CUSTOM_154_EDITOR                          1017
-#define IMG_CUSTOM_155                                 1018
-#define IMG_CUSTOM_155_EDITOR                          1019
-#define IMG_CUSTOM_156                                 1020
-#define IMG_CUSTOM_156_EDITOR                          1021
-#define IMG_CUSTOM_157                                 1022
-#define IMG_CUSTOM_157_EDITOR                          1023
-#define IMG_CUSTOM_158                                 1024
-#define IMG_CUSTOM_158_EDITOR                          1025
-#define IMG_CUSTOM_159                                 1026
-#define IMG_CUSTOM_159_EDITOR                          1027
-#define IMG_CUSTOM_160                                 1028
-#define IMG_CUSTOM_160_EDITOR                          1029
-#define IMG_CUSTOM_161                                 1030
-#define IMG_CUSTOM_161_EDITOR                          1031
-#define IMG_CUSTOM_162                                 1032
-#define IMG_CUSTOM_162_EDITOR                          1033
-#define IMG_CUSTOM_163                                 1034
-#define IMG_CUSTOM_163_EDITOR                          1035
-#define IMG_CUSTOM_164                                 1036
-#define IMG_CUSTOM_164_EDITOR                          1037
-#define IMG_CUSTOM_165                                 1038
-#define IMG_CUSTOM_165_EDITOR                          1039
-#define IMG_CUSTOM_166                                 1040
-#define IMG_CUSTOM_166_EDITOR                          1041
-#define IMG_CUSTOM_167                                 1042
-#define IMG_CUSTOM_167_EDITOR                          1043
-#define IMG_CUSTOM_168                                 1044
-#define IMG_CUSTOM_168_EDITOR                          1045
-#define IMG_CUSTOM_169                                 1046
-#define IMG_CUSTOM_169_EDITOR                          1047
-#define IMG_CUSTOM_170                                 1048
-#define IMG_CUSTOM_170_EDITOR                          1049
-#define IMG_CUSTOM_171                                 1050
-#define IMG_CUSTOM_171_EDITOR                          1051
-#define IMG_CUSTOM_172                                 1052
-#define IMG_CUSTOM_172_EDITOR                          1053
-#define IMG_CUSTOM_173                                 1054
-#define IMG_CUSTOM_173_EDITOR                          1055
-#define IMG_CUSTOM_174                                 1056
-#define IMG_CUSTOM_174_EDITOR                          1057
-#define IMG_CUSTOM_175                                 1058
-#define IMG_CUSTOM_175_EDITOR                          1059
-#define IMG_CUSTOM_176                                 1060
-#define IMG_CUSTOM_176_EDITOR                          1061
-#define IMG_CUSTOM_177                                 1062
-#define IMG_CUSTOM_177_EDITOR                          1063
-#define IMG_CUSTOM_178                                 1064
-#define IMG_CUSTOM_178_EDITOR                          1065
-#define IMG_CUSTOM_179                                 1066
-#define IMG_CUSTOM_179_EDITOR                          1067
-#define IMG_CUSTOM_180                                 1068
-#define IMG_CUSTOM_180_EDITOR                          1069
-#define IMG_CUSTOM_181                                 1070
-#define IMG_CUSTOM_181_EDITOR                          1071
-#define IMG_CUSTOM_182                                 1072
-#define IMG_CUSTOM_182_EDITOR                          1073
-#define IMG_CUSTOM_183                                 1074
-#define IMG_CUSTOM_183_EDITOR                          1075
-#define IMG_CUSTOM_184                                 1076
-#define IMG_CUSTOM_184_EDITOR                          1077
-#define IMG_CUSTOM_185                                 1078
-#define IMG_CUSTOM_185_EDITOR                          1079
-#define IMG_CUSTOM_186                                 1080
-#define IMG_CUSTOM_186_EDITOR                          1081
-#define IMG_CUSTOM_187                                 1082
-#define IMG_CUSTOM_187_EDITOR                          1083
-#define IMG_CUSTOM_188                                 1084
-#define IMG_CUSTOM_188_EDITOR                          1085
-#define IMG_CUSTOM_189                                 1086
-#define IMG_CUSTOM_189_EDITOR                          1087
-#define IMG_CUSTOM_190                                 1088
-#define IMG_CUSTOM_190_EDITOR                          1089
-#define IMG_CUSTOM_191                                 1090
-#define IMG_CUSTOM_191_EDITOR                          1091
-#define IMG_CUSTOM_192                                 1092
-#define IMG_CUSTOM_192_EDITOR                          1093
-#define IMG_CUSTOM_193                                 1094
-#define IMG_CUSTOM_193_EDITOR                          1095
-#define IMG_CUSTOM_194                                 1096
-#define IMG_CUSTOM_194_EDITOR                          1097
-#define IMG_CUSTOM_195                                 1098
-#define IMG_CUSTOM_195_EDITOR                          1099
-#define IMG_CUSTOM_196                                 1100
-#define IMG_CUSTOM_196_EDITOR                          1101
-#define IMG_CUSTOM_197                                 1102
-#define IMG_CUSTOM_197_EDITOR                          1103
-#define IMG_CUSTOM_198                                 1104
-#define IMG_CUSTOM_198_EDITOR                          1105
-#define IMG_CUSTOM_199                                 1106
-#define IMG_CUSTOM_199_EDITOR                          1107
-#define IMG_CUSTOM_200                                 1108
-#define IMG_CUSTOM_200_EDITOR                          1109
-#define IMG_CUSTOM_201                                 1110
-#define IMG_CUSTOM_201_EDITOR                          1111
-#define IMG_CUSTOM_202                                 1112
-#define IMG_CUSTOM_202_EDITOR                          1113
-#define IMG_CUSTOM_203                                 1114
-#define IMG_CUSTOM_203_EDITOR                          1115
-#define IMG_CUSTOM_204                                 1116
-#define IMG_CUSTOM_204_EDITOR                          1117
-#define IMG_CUSTOM_205                                 1118
-#define IMG_CUSTOM_205_EDITOR                          1119
-#define IMG_CUSTOM_206                                 1120
-#define IMG_CUSTOM_206_EDITOR                          1121
-#define IMG_CUSTOM_207                                 1122
-#define IMG_CUSTOM_207_EDITOR                          1123
-#define IMG_CUSTOM_208                                 1124
-#define IMG_CUSTOM_208_EDITOR                          1125
-#define IMG_CUSTOM_209                                 1126
-#define IMG_CUSTOM_209_EDITOR                          1127
-#define IMG_CUSTOM_210                                 1128
-#define IMG_CUSTOM_210_EDITOR                          1129
-#define IMG_CUSTOM_211                                 1130
-#define IMG_CUSTOM_211_EDITOR                          1131
-#define IMG_CUSTOM_212                                 1132
-#define IMG_CUSTOM_212_EDITOR                          1133
-#define IMG_CUSTOM_213                                 1134
-#define IMG_CUSTOM_213_EDITOR                          1135
-#define IMG_CUSTOM_214                                 1136
-#define IMG_CUSTOM_214_EDITOR                          1137
-#define IMG_CUSTOM_215                                 1138
-#define IMG_CUSTOM_215_EDITOR                          1139
-#define IMG_CUSTOM_216                                 1140
-#define IMG_CUSTOM_216_EDITOR                          1141
-#define IMG_CUSTOM_217                                 1142
-#define IMG_CUSTOM_217_EDITOR                          1143
-#define IMG_CUSTOM_218                                 1144
-#define IMG_CUSTOM_218_EDITOR                          1145
-#define IMG_CUSTOM_219                                 1146
-#define IMG_CUSTOM_219_EDITOR                          1147
-#define IMG_CUSTOM_220                                 1148
-#define IMG_CUSTOM_220_EDITOR                          1149
-#define IMG_CUSTOM_221                                 1150
-#define IMG_CUSTOM_221_EDITOR                          1151
-#define IMG_CUSTOM_222                                 1152
-#define IMG_CUSTOM_222_EDITOR                          1153
-#define IMG_CUSTOM_223                                 1154
-#define IMG_CUSTOM_223_EDITOR                          1155
-#define IMG_CUSTOM_224                                 1156
-#define IMG_CUSTOM_224_EDITOR                          1157
-#define IMG_CUSTOM_225                                 1158
-#define IMG_CUSTOM_225_EDITOR                          1159
-#define IMG_CUSTOM_226                                 1160
-#define IMG_CUSTOM_226_EDITOR                          1161
-#define IMG_CUSTOM_227                                 1162
-#define IMG_CUSTOM_227_EDITOR                          1163
-#define IMG_CUSTOM_228                                 1164
-#define IMG_CUSTOM_228_EDITOR                          1165
-#define IMG_CUSTOM_229                                 1166
-#define IMG_CUSTOM_229_EDITOR                          1167
-#define IMG_CUSTOM_230                                 1168
-#define IMG_CUSTOM_230_EDITOR                          1169
-#define IMG_CUSTOM_231                                 1170
-#define IMG_CUSTOM_231_EDITOR                          1171
-#define IMG_CUSTOM_232                                 1172
-#define IMG_CUSTOM_232_EDITOR                          1173
-#define IMG_CUSTOM_233                                 1174
-#define IMG_CUSTOM_233_EDITOR                          1175
-#define IMG_CUSTOM_234                                 1176
-#define IMG_CUSTOM_234_EDITOR                          1177
-#define IMG_CUSTOM_235                                 1178
-#define IMG_CUSTOM_235_EDITOR                          1179
-#define IMG_CUSTOM_236                                 1180
-#define IMG_CUSTOM_236_EDITOR                          1181
-#define IMG_CUSTOM_237                                 1182
-#define IMG_CUSTOM_237_EDITOR                          1183
-#define IMG_CUSTOM_238                                 1184
-#define IMG_CUSTOM_238_EDITOR                          1185
-#define IMG_CUSTOM_239                                 1186
-#define IMG_CUSTOM_239_EDITOR                          1187
-#define IMG_CUSTOM_240                                 1188
-#define IMG_CUSTOM_240_EDITOR                          1189
-#define IMG_CUSTOM_241                                 1190
-#define IMG_CUSTOM_241_EDITOR                          1191
-#define IMG_CUSTOM_242                                 1192
-#define IMG_CUSTOM_242_EDITOR                          1193
-#define IMG_CUSTOM_243                                 1194
-#define IMG_CUSTOM_243_EDITOR                          1195
-#define IMG_CUSTOM_244                                 1196
-#define IMG_CUSTOM_244_EDITOR                          1197
-#define IMG_CUSTOM_245                                 1198
-#define IMG_CUSTOM_245_EDITOR                          1199
-#define IMG_CUSTOM_246                                 1200
-#define IMG_CUSTOM_246_EDITOR                          1201
-#define IMG_CUSTOM_247                                 1202
-#define IMG_CUSTOM_247_EDITOR                          1203
-#define IMG_CUSTOM_248                                 1204
-#define IMG_CUSTOM_248_EDITOR                          1205
-#define IMG_CUSTOM_249                                 1206
-#define IMG_CUSTOM_249_EDITOR                          1207
-#define IMG_CUSTOM_250                                 1208
-#define IMG_CUSTOM_250_EDITOR                          1209
-#define IMG_CUSTOM_251                                 1210
-#define IMG_CUSTOM_251_EDITOR                          1211
-#define IMG_CUSTOM_252                                 1212
-#define IMG_CUSTOM_252_EDITOR                          1213
-#define IMG_CUSTOM_253                                 1214
-#define IMG_CUSTOM_253_EDITOR                          1215
-#define IMG_CUSTOM_254                                 1216
-#define IMG_CUSTOM_254_EDITOR                          1217
-#define IMG_CUSTOM_255                                 1218
-#define IMG_CUSTOM_255_EDITOR                          1219
-#define IMG_CUSTOM_256                                 1220
-#define IMG_CUSTOM_256_EDITOR                          1221
-#define IMG_TOON_1                                     1222
-#define IMG_TOON_2                                     1223
-#define IMG_TOON_3                                     1224
-#define IMG_TOON_4                                     1225
-#define IMG_TOON_5                                     1226
-#define IMG_TOON_6                                     1227
-#define IMG_TOON_7                                     1228
-#define IMG_TOON_8                                     1229
-#define IMG_TOON_9                                     1230
-#define IMG_TOON_10                                    1231
-#define IMG_TOON_11                                    1232
-#define IMG_TOON_12                                    1233
-#define IMG_TOON_13                                    1234
-#define IMG_TOON_14                                    1235
-#define IMG_TOON_15                                    1236
-#define IMG_TOON_16                                    1237
-#define IMG_TOON_17                                    1238
-#define IMG_TOON_18                                    1239
-#define IMG_TOON_19                                    1240
-#define IMG_TOON_20                                    1241
-#define IMG_MENU_CALIBRATE_RED                         1242
-#define IMG_MENU_CALIBRATE_BLUE                                1243
-#define IMG_MENU_CALIBRATE_YELLOW                      1244
-#define IMG_MENU_BUTTON                                        1245
-#define IMG_MENU_BUTTON_ACTIVE                         1246
-#define IMG_MENU_BUTTON_LEFT                           1247
-#define IMG_MENU_BUTTON_RIGHT                          1248
-#define IMG_MENU_BUTTON_UP                             1249
-#define IMG_MENU_BUTTON_DOWN                           1250
-#define IMG_MENU_BUTTON_LEFT_ACTIVE                    1251
-#define IMG_MENU_BUTTON_RIGHT_ACTIVE                   1252
-#define IMG_MENU_BUTTON_UP_ACTIVE                      1253
-#define IMG_MENU_BUTTON_DOWN_ACTIVE                    1254
-#define IMG_MENU_SCROLLBAR                             1255
-#define IMG_MENU_SCROLLBAR_ACTIVE                      1256
-#define IMG_FONT_INITIAL_1                             1257
-#define IMG_FONT_INITIAL_2                             1258
-#define IMG_FONT_INITIAL_3                             1259
-#define IMG_FONT_INITIAL_4                             1260
-#define IMG_FONT_TITLE_1                               1261
-#define IMG_FONT_TITLE_1_LEVELS                                1262
-#define IMG_FONT_TITLE_2                               1263
-#define IMG_FONT_MENU_1                                        1264
-#define IMG_FONT_MENU_2                                        1265
-#define IMG_FONT_TEXT_1                                        1266
-#define IMG_FONT_TEXT_1_LEVELS                         1267
-#define IMG_FONT_TEXT_1_PREVIEW                                1268
-#define IMG_FONT_TEXT_1_SCORES                         1269
-#define IMG_FONT_TEXT_1_ACTIVE_SCORES                  1270
-#define IMG_FONT_TEXT_2                                        1271
-#define IMG_FONT_TEXT_2_LEVELS                         1272
-#define IMG_FONT_TEXT_2_PREVIEW                                1273
-#define IMG_FONT_TEXT_2_SCORES                         1274
-#define IMG_FONT_TEXT_2_ACTIVE_SCORES                  1275
-#define IMG_FONT_TEXT_3                                        1276
-#define IMG_FONT_TEXT_3_LEVELS                         1277
-#define IMG_FONT_TEXT_3_PREVIEW                                1278
-#define IMG_FONT_TEXT_3_SCORES                         1279
-#define IMG_FONT_TEXT_3_ACTIVE_SCORES                  1280
-#define IMG_FONT_TEXT_4                                        1281
-#define IMG_FONT_TEXT_4_LEVELS                         1282
-#define IMG_FONT_TEXT_4_SCORES                         1283
-#define IMG_FONT_TEXT_4_ACTIVE_SCORES                  1284
-#define IMG_FONT_ENVELOPE_1                            1285
-#define IMG_FONT_ENVELOPE_2                            1286
-#define IMG_FONT_ENVELOPE_3                            1287
-#define IMG_FONT_ENVELOPE_4                            1288
-#define IMG_FONT_INPUT_1                               1289
-#define IMG_FONT_INPUT_1_MAIN                          1290
-#define IMG_FONT_INPUT_1_ACTIVE                                1291
-#define IMG_FONT_INPUT_1_ACTIVE_MAIN                   1292
-#define IMG_FONT_INPUT_1_ACTIVE_SETUP                  1293
-#define IMG_FONT_INPUT_2                               1294
-#define IMG_FONT_INPUT_2_ACTIVE                                1295
-#define IMG_FONT_OPTION_OFF                            1296
-#define IMG_FONT_OPTION_ON                             1297
-#define IMG_FONT_VALUE_1                               1298
-#define IMG_FONT_VALUE_2                               1299
-#define IMG_FONT_VALUE_OLD                             1300
-#define IMG_FONT_LEVEL_NUMBER                          1301
-#define IMG_FONT_TAPE_RECORDER                         1302
-#define IMG_FONT_GAME_INFO                             1303
-#define IMG_GLOBAL_BORDER                              1304
-#define IMG_GLOBAL_DOOR                                        1305
-#define IMG_EDITOR_ELEMENT_BORDER                      1306
-#define IMG_EDITOR_ELEMENT_BORDER_INPUT                        1307
-#define IMG_BACKGROUND_ENVELOPE_1                      1308
-#define IMG_BACKGROUND_ENVELOPE_2                      1309
-#define IMG_BACKGROUND_ENVELOPE_3                      1310
-#define IMG_BACKGROUND_ENVELOPE_4                      1311
-#define IMG_BACKGROUND                                 1312
-#define IMG_BACKGROUND_MAIN                            1313
-#define IMG_BACKGROUND_LEVELS                          1314
-#define IMG_BACKGROUND_SCORES                          1315
-#define IMG_BACKGROUND_EDITOR                          1316
-#define IMG_BACKGROUND_INFO                            1317
-#define IMG_BACKGROUND_SETUP                           1318
-#define IMG_BACKGROUND_DOOR                            1319
+#define IMG_BD_BUTTERFLY_RIGHT_EDITOR                  20
+#define IMG_BD_BUTTERFLY_UP_EDITOR                     21
+#define IMG_BD_BUTTERFLY_LEFT_EDITOR                   22
+#define IMG_BD_BUTTERFLY_DOWN_EDITOR                   23
+#define IMG_BD_FIREFLY                                 24
+#define IMG_BD_FIREFLY_RIGHT_EDITOR                    25
+#define IMG_BD_FIREFLY_UP_EDITOR                       26
+#define IMG_BD_FIREFLY_LEFT_EDITOR                     27
+#define IMG_BD_FIREFLY_DOWN_EDITOR                     28
+#define IMG_SP_DEFAULT_EXPLODING                       29
+#define IMG_SP_ZONK                                    30
+#define IMG_SP_ZONK_MOVING_LEFT                                31
+#define IMG_SP_ZONK_MOVING_RIGHT                       32
+#define IMG_SP_ZONK_PUSHING_LEFT                       33
+#define IMG_SP_ZONK_PUSHING_RIGHT                      34
+#define IMG_SP_BASE                                    35
+#define IMG_SP_MURPHY                                  36
+#define IMG_SP_MURPHY_MOVING_LEFT                      37
+#define IMG_SP_MURPHY_MOVING_RIGHT                     38
+#define IMG_SP_MURPHY_DIGGING_LEFT                     39
+#define IMG_SP_MURPHY_DIGGING_RIGHT                    40
+#define IMG_SP_MURPHY_COLLECTING_LEFT                  41
+#define IMG_SP_MURPHY_COLLECTING_RIGHT                 42
+#define IMG_SP_MURPHY_PUSHING_LEFT                     43
+#define IMG_SP_MURPHY_PUSHING_RIGHT                    44
+#define IMG_SP_MURPHY_SNAPPING_LEFT                    45
+#define IMG_SP_MURPHY_SNAPPING_RIGHT                   46
+#define IMG_SP_MURPHY_SNAPPING_UP                      47
+#define IMG_SP_MURPHY_SNAPPING_DOWN                    48
+#define IMG_SP_MURPHY_CLONE                            49
+#define IMG_SP_INFOTRON                                        50
+#define IMG_SP_INFOTRON_EDITOR                         51
+#define IMG_SP_CHIP_SINGLE                             52
+#define IMG_SP_CHIP_LEFT                               53
+#define IMG_SP_CHIP_RIGHT                              54
+#define IMG_SP_CHIP_TOP                                        55
+#define IMG_SP_CHIP_BOTTOM                             56
+#define IMG_SP_HARDWARE_GRAY                           57
+#define IMG_SP_HARDWARE_GREEN                          58
+#define IMG_SP_HARDWARE_BLUE                           59
+#define IMG_SP_HARDWARE_RED                            60
+#define IMG_SP_HARDWARE_YELLOW                         61
+#define IMG_SP_EXIT_CLOSED                             62
+#define IMG_SP_EXIT_OPENING                            63
+#define IMG_SP_EXIT_OPEN                               64
+#define IMG_SP_EXIT_CLOSING                            65
+#define IMG_SP_DISK_ORANGE                             66
+#define IMG_SP_DISK_YELLOW                             67
+#define IMG_SP_DISK_RED                                        68
+#define IMG_SP_DISK_RED_COLLECTING                     69
+#define IMG_SP_DISK_RED_ACTIVE                         70
+#define IMG_SP_PORT_RIGHT                              71
+#define IMG_SP_PORT_DOWN                               72
+#define IMG_SP_PORT_LEFT                               73
+#define IMG_SP_PORT_UP                                 74
+#define IMG_SP_PORT_HORIZONTAL                         75
+#define IMG_SP_PORT_VERTICAL                           76
+#define IMG_SP_PORT_ANY                                        77
+#define IMG_SP_GRAVITY_PORT_RIGHT                      78
+#define IMG_SP_GRAVITY_PORT_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_SNIKSNAK_TURNING_FROM_LEFT_UP           87
+#define IMG_SP_SNIKSNAK_TURNING_FROM_LEFT_DOWN         88
+#define IMG_SP_SNIKSNAK_TURNING_FROM_RIGHT_UP          89
+#define IMG_SP_SNIKSNAK_TURNING_FROM_RIGHT_DOWN                90
+#define IMG_SP_SNIKSNAK_TURNING_FROM_UP_LEFT           91
+#define IMG_SP_SNIKSNAK_TURNING_FROM_UP_RIGHT          92
+#define IMG_SP_SNIKSNAK_TURNING_FROM_DOWN_LEFT         93
+#define IMG_SP_SNIKSNAK_TURNING_FROM_DOWN_RIGHT                94
+#define IMG_SP_ELECTRON                                        95
+#define IMG_SP_ELECTRON_EDITOR                         96
+#define IMG_SP_ELECTRON_EXPLODING                      97
+#define IMG_SP_TERMINAL                                        98
+#define IMG_SP_TERMINAL_EDITOR                         99
+#define IMG_SP_TERMINAL_ACTIVE                         100
+#define IMG_SP_BUGGY_BASE                              101
+#define IMG_SP_BUGGY_BASE_EDITOR                       102
+#define IMG_SP_BUGGY_BASE_ACTIVATING                   103
+#define IMG_SP_BUGGY_BASE_ACTIVE                       104
+#define IMG_SP_HARDWARE_BASE_1                         105
+#define IMG_SP_HARDWARE_BASE_2                         106
+#define IMG_SP_HARDWARE_BASE_3                         107
+#define IMG_SP_HARDWARE_BASE_4                         108
+#define IMG_SP_HARDWARE_BASE_5                         109
+#define IMG_SP_HARDWARE_BASE_6                         110
+#define IMG_SOKOBAN_OBJECT                             111
+#define IMG_SOKOBAN_OBJECT_EDITOR                      112
+#define IMG_SOKOBAN_FIELD_EMPTY                                113
+#define IMG_SOKOBAN_FIELD_FULL                         114
+#define IMG_EMPTY_SPACE                                        115
+#define IMG_SAND                                       116
+#define IMG_SAND_CRUMBLED                              117
+#define IMG_SAND_DIGGING_LEFT                          118
+#define IMG_SAND_DIGGING_RIGHT                         119
+#define IMG_SAND_DIGGING_UP                            120
+#define IMG_SAND_DIGGING_DOWN                          121
+#define IMG_SAND_DIGGING_LEFT_CRUMBLED                 122
+#define IMG_SAND_DIGGING_RIGHT_CRUMBLED                        123
+#define IMG_SAND_DIGGING_UP_CRUMBLED                   124
+#define IMG_SAND_DIGGING_DOWN_CRUMBLED                 125
+#define IMG_WALL                                       126
+#define IMG_WALL_SLIPPERY                              127
+#define IMG_STEELWALL                                  128
+#define IMG_ROCK                                       129
+#define IMG_ROCK_MOVING_LEFT                           130
+#define IMG_ROCK_MOVING_RIGHT                          131
+#define IMG_ROCK_PUSHING_LEFT                          132
+#define IMG_ROCK_PUSHING_RIGHT                         133
+#define IMG_EMERALD                                    134
+#define IMG_EMERALD_MOVING                             135
+#define IMG_EMERALD_FALLING                            136
+#define IMG_EMERALD_COLLECTING                         137
+#define IMG_DIAMOND                                    138
+#define IMG_DIAMOND_MOVING                             139
+#define IMG_DIAMOND_FALLING                            140
+#define IMG_DIAMOND_COLLECTING                         141
+#define IMG_BOMB                                       142
+#define IMG_NUT                                                143
+#define IMG_NUT_BREAKING                               144
+#define IMG_DYNAMITE                                   145
+#define IMG_DYNAMITE_EDITOR                            146
+#define IMG_DYNAMITE_ACTIVE                            147
+#define IMG_DYNAMITE_ACTIVE_EDITOR                     148
+#define IMG_WALL_EMERALD                               149
+#define IMG_WALL_DIAMOND                               150
+#define IMG_BUG                                                151
+#define IMG_BUG_RIGHT                                  152
+#define IMG_BUG_UP                                     153
+#define IMG_BUG_LEFT                                   154
+#define IMG_BUG_DOWN                                   155
+#define IMG_BUG_MOVING_RIGHT                           156
+#define IMG_BUG_MOVING_UP                              157
+#define IMG_BUG_MOVING_LEFT                            158
+#define IMG_BUG_MOVING_DOWN                            159
+#define IMG_BUG_TURNING_FROM_RIGHT_UP                  160
+#define IMG_BUG_TURNING_FROM_UP_LEFT                   161
+#define IMG_BUG_TURNING_FROM_LEFT_DOWN                 162
+#define IMG_BUG_TURNING_FROM_DOWN_RIGHT                        163
+#define IMG_BUG_TURNING_FROM_RIGHT_DOWN                        164
+#define IMG_BUG_TURNING_FROM_UP_RIGHT                  165
+#define IMG_BUG_TURNING_FROM_LEFT_UP                   166
+#define IMG_BUG_TURNING_FROM_DOWN_LEFT                 167
+#define IMG_SPACESHIP                                  168
+#define IMG_SPACESHIP_RIGHT                            169
+#define IMG_SPACESHIP_UP                               170
+#define IMG_SPACESHIP_LEFT                             171
+#define IMG_SPACESHIP_DOWN                             172
+#define IMG_SPACESHIP_MOVING_RIGHT                     173
+#define IMG_SPACESHIP_MOVING_UP                                174
+#define IMG_SPACESHIP_MOVING_LEFT                      175
+#define IMG_SPACESHIP_MOVING_DOWN                      176
+#define IMG_SPACESHIP_TURNING_FROM_RIGHT_UP            177
+#define IMG_SPACESHIP_TURNING_FROM_UP_LEFT             178
+#define IMG_SPACESHIP_TURNING_FROM_LEFT_DOWN           179
+#define IMG_SPACESHIP_TURNING_FROM_DOWN_RIGHT          180
+#define IMG_SPACESHIP_TURNING_FROM_RIGHT_DOWN          181
+#define IMG_SPACESHIP_TURNING_FROM_UP_RIGHT            182
+#define IMG_SPACESHIP_TURNING_FROM_LEFT_UP             183
+#define IMG_SPACESHIP_TURNING_FROM_DOWN_LEFT           184
+#define IMG_YAMYAM                                     185
+#define IMG_YAMYAM_MOVING                              186
+#define IMG_ROBOT                                      187
+#define IMG_ROBOT_MOVING                               188
+#define IMG_ROBOT_WHEEL                                        189
+#define IMG_ROBOT_WHEEL_ACTIVE                         190
+#define IMG_MAGIC_WALL                                 191
+#define IMG_MAGIC_WALL_ACTIVE                          192
+#define IMG_MAGIC_WALL_FILLING                         193
+#define IMG_MAGIC_WALL_FULL                            194
+#define IMG_MAGIC_WALL_EMPTYING                                195
+#define IMG_MAGIC_WALL_DEAD                            196
+#define IMG_QUICKSAND_EMPTY                            197
+#define IMG_QUICKSAND_FILLING                          198
+#define IMG_QUICKSAND_FULL                             199
+#define IMG_QUICKSAND_FULL_EDITOR                      200
+#define IMG_QUICKSAND_EMPTYING                         201
+#define IMG_ACID_POOL_TOPLEFT                          202
+#define IMG_ACID_POOL_TOPRIGHT                         203
+#define IMG_ACID_POOL_BOTTOMLEFT                       204
+#define IMG_ACID_POOL_BOTTOM                           205
+#define IMG_ACID_POOL_BOTTOMRIGHT                      206
+#define IMG_ACID                                       207
+#define IMG_ACID_SPLASH_LEFT                           208
+#define IMG_ACID_SPLASH_RIGHT                          209
+#define IMG_AMOEBA_DROP                                        210
+#define IMG_AMOEBA_GROWING                             211
+#define IMG_AMOEBA_SHRINKING                           212
+#define IMG_AMOEBA_WET                                 213
+#define IMG_AMOEBA_WET_EDITOR                          214
+#define IMG_AMOEBA_DROPPING                            215
+#define IMG_AMOEBA_DRY                                 216
+#define IMG_AMOEBA_FULL                                        217
+#define IMG_AMOEBA_FULL_EDITOR                         218
+#define IMG_AMOEBA_DEAD                                        219
+#define IMG_AMOEBA_DEAD_EDITOR                         220
+#define IMG_EM_KEY_1                                   221
+#define IMG_EM_KEY_2                                   222
+#define IMG_EM_KEY_3                                   223
+#define IMG_EM_KEY_4                                   224
+#define IMG_EM_GATE_1                                  225
+#define IMG_EM_GATE_2                                  226
+#define IMG_EM_GATE_3                                  227
+#define IMG_EM_GATE_4                                  228
+#define IMG_EM_GATE_1_GRAY                             229
+#define IMG_EM_GATE_1_GRAY_EDITOR                      230
+#define IMG_EM_GATE_2_GRAY                             231
+#define IMG_EM_GATE_2_GRAY_EDITOR                      232
+#define IMG_EM_GATE_3_GRAY                             233
+#define IMG_EM_GATE_3_GRAY_EDITOR                      234
+#define IMG_EM_GATE_4_GRAY                             235
+#define IMG_EM_GATE_4_GRAY_EDITOR                      236
+#define IMG_EXIT_CLOSED                                        237
+#define IMG_EXIT_OPENING                               238
+#define IMG_EXIT_OPEN                                  239
+#define IMG_EXIT_CLOSING                               240
+#define IMG_BALLOON                                    241
+#define IMG_BALLOON_MOVING                             242
+#define IMG_BALLOON_PUSHING                            243
+#define IMG_BALLOON_SWITCH_LEFT                                244
+#define IMG_BALLOON_SWITCH_RIGHT                       245
+#define IMG_BALLOON_SWITCH_UP                          246
+#define IMG_BALLOON_SWITCH_DOWN                                247
+#define IMG_BALLOON_SWITCH_ANY                         248
+#define IMG_SPRING                                     249
+#define IMG_EMC_STEELWALL_1                            250
+#define IMG_EMC_STEELWALL_2                            251
+#define IMG_EMC_STEELWALL_3                            252
+#define IMG_EMC_STEELWALL_4                            253
+#define IMG_EMC_WALL_1                                 254
+#define IMG_EMC_WALL_2                                 255
+#define IMG_EMC_WALL_3                                 256
+#define IMG_EMC_WALL_4                                 257
+#define IMG_EMC_WALL_5                                 258
+#define IMG_EMC_WALL_6                                 259
+#define IMG_EMC_WALL_7                                 260
+#define IMG_EMC_WALL_8                                 261
+#define IMG_INVISIBLE_STEELWALL                                262
+#define IMG_INVISIBLE_STEELWALL_EDITOR                 263
+#define IMG_INVISIBLE_STEELWALL_ACTIVE                 264
+#define IMG_INVISIBLE_WALL                             265
+#define IMG_INVISIBLE_WALL_EDITOR                      266
+#define IMG_INVISIBLE_WALL_ACTIVE                      267
+#define IMG_INVISIBLE_SAND                             268
+#define IMG_INVISIBLE_SAND_EDITOR                      269
+#define IMG_INVISIBLE_SAND_ACTIVE                      270
+#define IMG_CONVEYOR_BELT_1_MIDDLE                     271
+#define IMG_CONVEYOR_BELT_1_MIDDLE_ACTIVE              272
+#define IMG_CONVEYOR_BELT_1_LEFT                       273
+#define IMG_CONVEYOR_BELT_1_LEFT_ACTIVE                        274
+#define IMG_CONVEYOR_BELT_1_RIGHT                      275
+#define IMG_CONVEYOR_BELT_1_RIGHT_ACTIVE               276
+#define IMG_CONVEYOR_BELT_1_SWITCH_LEFT                        277
+#define IMG_CONVEYOR_BELT_1_SWITCH_MIDDLE              278
+#define IMG_CONVEYOR_BELT_1_SWITCH_RIGHT               279
+#define IMG_CONVEYOR_BELT_2_MIDDLE                     280
+#define IMG_CONVEYOR_BELT_2_MIDDLE_ACTIVE              281
+#define IMG_CONVEYOR_BELT_2_LEFT                       282
+#define IMG_CONVEYOR_BELT_2_LEFT_ACTIVE                        283
+#define IMG_CONVEYOR_BELT_2_RIGHT                      284
+#define IMG_CONVEYOR_BELT_2_RIGHT_ACTIVE               285
+#define IMG_CONVEYOR_BELT_2_SWITCH_LEFT                        286
+#define IMG_CONVEYOR_BELT_2_SWITCH_MIDDLE              287
+#define IMG_CONVEYOR_BELT_2_SWITCH_RIGHT               288
+#define IMG_CONVEYOR_BELT_3_MIDDLE                     289
+#define IMG_CONVEYOR_BELT_3_MIDDLE_ACTIVE              290
+#define IMG_CONVEYOR_BELT_3_LEFT                       291
+#define IMG_CONVEYOR_BELT_3_LEFT_ACTIVE                        292
+#define IMG_CONVEYOR_BELT_3_RIGHT                      293
+#define IMG_CONVEYOR_BELT_3_RIGHT_ACTIVE               294
+#define IMG_CONVEYOR_BELT_3_SWITCH_LEFT                        295
+#define IMG_CONVEYOR_BELT_3_SWITCH_MIDDLE              296
+#define IMG_CONVEYOR_BELT_3_SWITCH_RIGHT               297
+#define IMG_CONVEYOR_BELT_4_MIDDLE                     298
+#define IMG_CONVEYOR_BELT_4_MIDDLE_ACTIVE              299
+#define IMG_CONVEYOR_BELT_4_LEFT                       300
+#define IMG_CONVEYOR_BELT_4_LEFT_ACTIVE                        301
+#define IMG_CONVEYOR_BELT_4_RIGHT                      302
+#define IMG_CONVEYOR_BELT_4_RIGHT_ACTIVE               303
+#define IMG_CONVEYOR_BELT_4_SWITCH_LEFT                        304
+#define IMG_CONVEYOR_BELT_4_SWITCH_MIDDLE              305
+#define IMG_CONVEYOR_BELT_4_SWITCH_RIGHT               306
+#define IMG_SWITCHGATE_SWITCH_UP                       307
+#define IMG_SWITCHGATE_SWITCH_DOWN                     308
+#define IMG_LIGHT_SWITCH                               309
+#define IMG_LIGHT_SWITCH_ACTIVE                                310
+#define IMG_TIMEGATE_SWITCH                            311
+#define IMG_TIMEGATE_SWITCH_ACTIVE                     312
+#define IMG_ENVELOPE_1                                 313
+#define IMG_ENVELOPE_1_COLLECTING                      314
+#define IMG_ENVELOPE_2                                 315
+#define IMG_ENVELOPE_2_COLLECTING                      316
+#define IMG_ENVELOPE_3                                 317
+#define IMG_ENVELOPE_3_COLLECTING                      318
+#define IMG_ENVELOPE_4                                 319
+#define IMG_ENVELOPE_4_COLLECTING                      320
+#define IMG_SIGN_EXCLAMATION                           321
+#define IMG_SIGN_STOP                                  322
+#define IMG_LANDMINE                                   323
+#define IMG_STEELWALL_SLIPPERY                         324
+#define IMG_EXTRA_TIME                                 325
+#define IMG_SHIELD_NORMAL                              326
+#define IMG_SHIELD_NORMAL_ACTIVE                       327
+#define IMG_SHIELD_DEADLY                              328
+#define IMG_SHIELD_DEADLY_ACTIVE                       329
+#define IMG_SWITCHGATE_CLOSED                          330
+#define IMG_SWITCHGATE_OPENING                         331
+#define IMG_SWITCHGATE_OPEN                            332
+#define IMG_SWITCHGATE_CLOSING                         333
+#define IMG_TIMEGATE_CLOSED                            334
+#define IMG_TIMEGATE_OPENING                           335
+#define IMG_TIMEGATE_OPEN                              336
+#define IMG_TIMEGATE_CLOSING                           337
+#define IMG_PEARL                                      338
+#define IMG_PEARL_BREAKING                             339
+#define IMG_CRYSTAL                                    340
+#define IMG_WALL_PEARL                                 341
+#define IMG_WALL_CRYSTAL                               342
+#define IMG_TUBE_RIGHT_DOWN                            343
+#define IMG_TUBE_HORIZONTAL_DOWN                       344
+#define IMG_TUBE_LEFT_DOWN                             345
+#define IMG_TUBE_HORIZONTAL                            346
+#define IMG_TUBE_VERTICAL_RIGHT                                347
+#define IMG_TUBE_ANY                                   348
+#define IMG_TUBE_VERTICAL_LEFT                         349
+#define IMG_TUBE_VERTICAL                              350
+#define IMG_TUBE_RIGHT_UP                              351
+#define IMG_TUBE_HORIZONTAL_UP                         352
+#define IMG_TUBE_LEFT_UP                               353
+#define IMG_TRAP                                       354
+#define IMG_TRAP_ACTIVE                                        355
+#define IMG_DX_SUPABOMB                                        356
+#define IMG_KEY_1                                      357
+#define IMG_KEY_1_EDITOR                               358
+#define IMG_KEY_2                                      359
+#define IMG_KEY_2_EDITOR                               360
+#define IMG_KEY_3                                      361
+#define IMG_KEY_3_EDITOR                               362
+#define IMG_KEY_4                                      363
+#define IMG_KEY_4_EDITOR                               364
+#define IMG_GATE_1                                     365
+#define IMG_GATE_2                                     366
+#define IMG_GATE_3                                     367
+#define IMG_GATE_4                                     368
+#define IMG_GATE_1_GRAY                                        369
+#define IMG_GATE_1_GRAY_EDITOR                         370
+#define IMG_GATE_2_GRAY                                        371
+#define IMG_GATE_2_GRAY_EDITOR                         372
+#define IMG_GATE_3_GRAY                                        373
+#define IMG_GATE_3_GRAY_EDITOR                         374
+#define IMG_GATE_4_GRAY                                        375
+#define IMG_GATE_4_GRAY_EDITOR                         376
+#define IMG_GAME_OF_LIFE                               377
+#define IMG_BIOMAZE                                    378
+#define IMG_PACMAN                                     379
+#define IMG_PACMAN_RIGHT                               380
+#define IMG_PACMAN_UP                                  381
+#define IMG_PACMAN_LEFT                                        382
+#define IMG_PACMAN_DOWN                                        383
+#define IMG_PACMAN_TURNING_FROM_RIGHT                  384
+#define IMG_PACMAN_TURNING_FROM_UP                     385
+#define IMG_PACMAN_TURNING_FROM_LEFT                   386
+#define IMG_PACMAN_TURNING_FROM_DOWN                   387
+#define IMG_LAMP                                       388
+#define IMG_LAMP_EDITOR                                        389
+#define IMG_LAMP_ACTIVE                                        390
+#define IMG_TIME_ORB_FULL                              391
+#define IMG_TIME_ORB_EMPTY                             392
+#define IMG_EMERALD_YELLOW                             393
+#define IMG_EMERALD_YELLOW_MOVING                      394
+#define IMG_EMERALD_YELLOW_FALLING                     395
+#define IMG_EMERALD_RED                                        396
+#define IMG_EMERALD_RED_MOVING                         397
+#define IMG_EMERALD_RED_FALLING                                398
+#define IMG_EMERALD_PURPLE                             399
+#define IMG_EMERALD_PURPLE_MOVING                      400
+#define IMG_EMERALD_PURPLE_FALLING                     401
+#define IMG_WALL_EMERALD_YELLOW                                402
+#define IMG_WALL_EMERALD_RED                           403
+#define IMG_WALL_EMERALD_PURPLE                                404
+#define IMG_WALL_BD_DIAMOND                            405
+#define IMG_EXPANDABLE_WALL                            406
+#define IMG_EXPANDABLE_WALL_HORIZONTAL                 407
+#define IMG_EXPANDABLE_WALL_HORIZONTAL_EDITOR          408
+#define IMG_EXPANDABLE_WALL_VERTICAL                   409
+#define IMG_EXPANDABLE_WALL_VERTICAL_EDITOR            410
+#define IMG_EXPANDABLE_WALL_ANY                                411
+#define IMG_EXPANDABLE_WALL_ANY_EDITOR                 412
+#define IMG_EXPANDABLE_WALL_GROWING_LEFT               413
+#define IMG_EXPANDABLE_WALL_GROWING_RIGHT              414
+#define IMG_EXPANDABLE_WALL_GROWING_UP                 415
+#define IMG_EXPANDABLE_WALL_GROWING_DOWN               416
+#define IMG_BLACK_ORB                                  417
+#define IMG_SPEED_PILL                                 418
+#define IMG_DARK_YAMYAM                                        419
+#define IMG_DYNABOMB                                   420
+#define IMG_DYNABOMB_ACTIVE                            421
+#define IMG_DYNABOMB_PLAYER_1                          422
+#define IMG_DYNABOMB_PLAYER_1_ACTIVE                   423
+#define IMG_DYNABOMB_PLAYER_2                          424
+#define IMG_DYNABOMB_PLAYER_2_ACTIVE                   425
+#define IMG_DYNABOMB_PLAYER_3                          426
+#define IMG_DYNABOMB_PLAYER_3_ACTIVE                   427
+#define IMG_DYNABOMB_PLAYER_4                          428
+#define IMG_DYNABOMB_PLAYER_4_ACTIVE                   429
+#define IMG_DYNABOMB_INCREASE_NUMBER                   430
+#define IMG_DYNABOMB_INCREASE_SIZE                     431
+#define IMG_DYNABOMB_INCREASE_POWER                    432
+#define IMG_PIG                                                433
+#define IMG_PIG_DOWN                                   434
+#define IMG_PIG_UP                                     435
+#define IMG_PIG_LEFT                                   436
+#define IMG_PIG_RIGHT                                  437
+#define IMG_PIG_MOVING_DOWN                            438
+#define IMG_PIG_MOVING_UP                              439
+#define IMG_PIG_MOVING_LEFT                            440
+#define IMG_PIG_MOVING_RIGHT                           441
+#define IMG_PIG_DIGGING_DOWN                           442
+#define IMG_PIG_DIGGING_UP                             443
+#define IMG_PIG_DIGGING_LEFT                           444
+#define IMG_PIG_DIGGING_RIGHT                          445
+#define IMG_DRAGON                                     446
+#define IMG_DRAGON_DOWN                                        447
+#define IMG_DRAGON_UP                                  448
+#define IMG_DRAGON_LEFT                                        449
+#define IMG_DRAGON_RIGHT                               450
+#define IMG_DRAGON_MOVING_DOWN                         451
+#define IMG_DRAGON_MOVING_UP                           452
+#define IMG_DRAGON_MOVING_LEFT                         453
+#define IMG_DRAGON_MOVING_RIGHT                                454
+#define IMG_DRAGON_ATTACKING_DOWN                      455
+#define IMG_DRAGON_ATTACKING_UP                                456
+#define IMG_DRAGON_ATTACKING_LEFT                      457
+#define IMG_DRAGON_ATTACKING_RIGHT                     458
+#define IMG_MOLE                                       459
+#define IMG_MOLE_DOWN                                  460
+#define IMG_MOLE_UP                                    461
+#define IMG_MOLE_LEFT                                  462
+#define IMG_MOLE_RIGHT                                 463
+#define IMG_MOLE_MOVING_DOWN                           464
+#define IMG_MOLE_MOVING_UP                             465
+#define IMG_MOLE_MOVING_LEFT                           466
+#define IMG_MOLE_MOVING_RIGHT                          467
+#define IMG_MOLE_DIGGING_DOWN                          468
+#define IMG_MOLE_DIGGING_UP                            469
+#define IMG_MOLE_DIGGING_LEFT                          470
+#define IMG_MOLE_DIGGING_RIGHT                         471
+#define IMG_PENGUIN                                    472
+#define IMG_PENGUIN_EDITOR                             473
+#define IMG_PENGUIN_DOWN                               474
+#define IMG_PENGUIN_UP                                 475
+#define IMG_PENGUIN_LEFT                               476
+#define IMG_PENGUIN_RIGHT                              477
+#define IMG_PENGUIN_MOVING_DOWN                                478
+#define IMG_PENGUIN_MOVING_UP                          479
+#define IMG_PENGUIN_MOVING_LEFT                                480
+#define IMG_PENGUIN_MOVING_RIGHT                       481
+#define IMG_SATELLITE                                  482
+#define IMG_FLAMES_1_LEFT                              483
+#define IMG_FLAMES_2_LEFT                              484
+#define IMG_FLAMES_3_LEFT                              485
+#define IMG_FLAMES_1_RIGHT                             486
+#define IMG_FLAMES_2_RIGHT                             487
+#define IMG_FLAMES_3_RIGHT                             488
+#define IMG_FLAMES_1_UP                                        489
+#define IMG_FLAMES_2_UP                                        490
+#define IMG_FLAMES_3_UP                                        491
+#define IMG_FLAMES_1_DOWN                              492
+#define IMG_FLAMES_2_DOWN                              493
+#define IMG_FLAMES_3_DOWN                              494
+#define IMG_STONEBLOCK                                 495
+#define IMG_MAZE_RUNNER                                        496
+#define IMG_PLAYER_1                                   497
+#define IMG_PLAYER_1_EDITOR                            498
+#define IMG_PLAYER_1_DOWN                              499
+#define IMG_PLAYER_1_UP                                        500
+#define IMG_PLAYER_1_LEFT                              501
+#define IMG_PLAYER_1_RIGHT                             502
+#define IMG_PLAYER_1_MOVING_DOWN                       503
+#define IMG_PLAYER_1_MOVING_UP                         504
+#define IMG_PLAYER_1_MOVING_LEFT                       505
+#define IMG_PLAYER_1_MOVING_RIGHT                      506
+#define IMG_PLAYER_1_DIGGING_DOWN                      507
+#define IMG_PLAYER_1_DIGGING_UP                                508
+#define IMG_PLAYER_1_DIGGING_LEFT                      509
+#define IMG_PLAYER_1_DIGGING_RIGHT                     510
+#define IMG_PLAYER_1_COLLECTING_DOWN                   511
+#define IMG_PLAYER_1_COLLECTING_UP                     512
+#define IMG_PLAYER_1_COLLECTING_LEFT                   513
+#define IMG_PLAYER_1_COLLECTING_RIGHT                  514
+#define IMG_PLAYER_1_PUSHING_DOWN                      515
+#define IMG_PLAYER_1_PUSHING_UP                                516
+#define IMG_PLAYER_1_PUSHING_LEFT                      517
+#define IMG_PLAYER_1_PUSHING_RIGHT                     518
+#define IMG_PLAYER_1_SNAPPING_DOWN                     519
+#define IMG_PLAYER_1_SNAPPING_UP                       520
+#define IMG_PLAYER_1_SNAPPING_LEFT                     521
+#define IMG_PLAYER_1_SNAPPING_RIGHT                    522
+#define IMG_PLAYER_2                                   523
+#define IMG_PLAYER_2_EDITOR                            524
+#define IMG_PLAYER_2_DOWN                              525
+#define IMG_PLAYER_2_UP                                        526
+#define IMG_PLAYER_2_LEFT                              527
+#define IMG_PLAYER_2_RIGHT                             528
+#define IMG_PLAYER_2_MOVING_DOWN                       529
+#define IMG_PLAYER_2_MOVING_UP                         530
+#define IMG_PLAYER_2_MOVING_LEFT                       531
+#define IMG_PLAYER_2_MOVING_RIGHT                      532
+#define IMG_PLAYER_2_DIGGING_DOWN                      533
+#define IMG_PLAYER_2_DIGGING_UP                                534
+#define IMG_PLAYER_2_DIGGING_LEFT                      535
+#define IMG_PLAYER_2_DIGGING_RIGHT                     536
+#define IMG_PLAYER_2_COLLECTING_DOWN                   537
+#define IMG_PLAYER_2_COLLECTING_UP                     538
+#define IMG_PLAYER_2_COLLECTING_LEFT                   539
+#define IMG_PLAYER_2_COLLECTING_RIGHT                  540
+#define IMG_PLAYER_2_PUSHING_DOWN                      541
+#define IMG_PLAYER_2_PUSHING_UP                                542
+#define IMG_PLAYER_2_PUSHING_LEFT                      543
+#define IMG_PLAYER_2_PUSHING_RIGHT                     544
+#define IMG_PLAYER_2_SNAPPING_DOWN                     545
+#define IMG_PLAYER_2_SNAPPING_UP                       546
+#define IMG_PLAYER_2_SNAPPING_LEFT                     547
+#define IMG_PLAYER_2_SNAPPING_RIGHT                    548
+#define IMG_PLAYER_3                                   549
+#define IMG_PLAYER_3_EDITOR                            550
+#define IMG_PLAYER_3_DOWN                              551
+#define IMG_PLAYER_3_UP                                        552
+#define IMG_PLAYER_3_LEFT                              553
+#define IMG_PLAYER_3_RIGHT                             554
+#define IMG_PLAYER_3_MOVING_DOWN                       555
+#define IMG_PLAYER_3_MOVING_UP                         556
+#define IMG_PLAYER_3_MOVING_LEFT                       557
+#define IMG_PLAYER_3_MOVING_RIGHT                      558
+#define IMG_PLAYER_3_DIGGING_DOWN                      559
+#define IMG_PLAYER_3_DIGGING_UP                                560
+#define IMG_PLAYER_3_DIGGING_LEFT                      561
+#define IMG_PLAYER_3_DIGGING_RIGHT                     562
+#define IMG_PLAYER_3_COLLECTING_DOWN                   563
+#define IMG_PLAYER_3_COLLECTING_UP                     564
+#define IMG_PLAYER_3_COLLECTING_LEFT                   565
+#define IMG_PLAYER_3_COLLECTING_RIGHT                  566
+#define IMG_PLAYER_3_PUSHING_DOWN                      567
+#define IMG_PLAYER_3_PUSHING_UP                                568
+#define IMG_PLAYER_3_PUSHING_LEFT                      569
+#define IMG_PLAYER_3_PUSHING_RIGHT                     570
+#define IMG_PLAYER_3_SNAPPING_DOWN                     571
+#define IMG_PLAYER_3_SNAPPING_UP                       572
+#define IMG_PLAYER_3_SNAPPING_LEFT                     573
+#define IMG_PLAYER_3_SNAPPING_RIGHT                    574
+#define IMG_PLAYER_4                                   575
+#define IMG_PLAYER_4_EDITOR                            576
+#define IMG_PLAYER_4_DOWN                              577
+#define IMG_PLAYER_4_UP                                        578
+#define IMG_PLAYER_4_LEFT                              579
+#define IMG_PLAYER_4_RIGHT                             580
+#define IMG_PLAYER_4_MOVING_DOWN                       581
+#define IMG_PLAYER_4_MOVING_UP                         582
+#define IMG_PLAYER_4_MOVING_LEFT                       583
+#define IMG_PLAYER_4_MOVING_RIGHT                      584
+#define IMG_PLAYER_4_DIGGING_DOWN                      585
+#define IMG_PLAYER_4_DIGGING_UP                                586
+#define IMG_PLAYER_4_DIGGING_LEFT                      587
+#define IMG_PLAYER_4_DIGGING_RIGHT                     588
+#define IMG_PLAYER_4_COLLECTING_DOWN                   589
+#define IMG_PLAYER_4_COLLECTING_UP                     590
+#define IMG_PLAYER_4_COLLECTING_LEFT                   591
+#define IMG_PLAYER_4_COLLECTING_RIGHT                  592
+#define IMG_PLAYER_4_PUSHING_DOWN                      593
+#define IMG_PLAYER_4_PUSHING_UP                                594
+#define IMG_PLAYER_4_PUSHING_LEFT                      595
+#define IMG_PLAYER_4_PUSHING_RIGHT                     596
+#define IMG_PLAYER_4_SNAPPING_DOWN                     597
+#define IMG_PLAYER_4_SNAPPING_UP                       598
+#define IMG_PLAYER_4_SNAPPING_LEFT                     599
+#define IMG_PLAYER_4_SNAPPING_RIGHT                    600
+#define IMG_DEFAULT_EXPLODING                          601
+#define IMG_TWINKLE_BLUE                               602
+#define IMG_TWINKLE_WHITE                              603
+#define IMG_STEELWALL_TOPLEFT                          604
+#define IMG_STEELWALL_TOPRIGHT                         605
+#define IMG_STEELWALL_BOTTOMLEFT                       606
+#define IMG_STEELWALL_BOTTOMRIGHT                      607
+#define IMG_STEELWALL_HORIZONTAL                       608
+#define IMG_STEELWALL_VERTICAL                         609
+#define IMG_STEELWALL_TOPLEFT_EDITOR                   610
+#define IMG_STEELWALL_TOPRIGHT_EDITOR                  611
+#define IMG_STEELWALL_BOTTOMLEFT_EDITOR                        612
+#define IMG_STEELWALL_BOTTOMRIGHT_EDITOR               613
+#define IMG_STEELWALL_HORIZONTAL_EDITOR                        614
+#define IMG_STEELWALL_VERTICAL_EDITOR                  615
+#define IMG_INVISIBLE_STEELWALL_TOPLEFT                        616
+#define IMG_INVISIBLE_STEELWALL_TOPRIGHT               617
+#define IMG_INVISIBLE_STEELWALL_BOTTOMLEFT             618
+#define IMG_INVISIBLE_STEELWALL_BOTTOMRIGHT            619
+#define IMG_INVISIBLE_STEELWALL_HORIZONTAL             620
+#define IMG_INVISIBLE_STEELWALL_VERTICAL               621
+#define IMG_INVISIBLE_STEELWALL_TOPLEFT_EDITOR         622
+#define IMG_INVISIBLE_STEELWALL_TOPRIGHT_EDITOR                623
+#define IMG_INVISIBLE_STEELWALL_BOTTOMLEFT_EDITOR      624
+#define IMG_INVISIBLE_STEELWALL_BOTTOMRIGHT_EDITOR     625
+#define IMG_INVISIBLE_STEELWALL_HORIZONTAL_EDITOR      626
+#define IMG_INVISIBLE_STEELWALL_VERTICAL_EDITOR                627
+#define IMG_ARROW_LEFT                                 628
+#define IMG_ARROW_RIGHT                                        629
+#define IMG_ARROW_UP                                   630
+#define IMG_ARROW_DOWN                                 631
+#define IMG_CHAR_SPACE                                 632
+#define IMG_CHAR_EXCLAM                                        633
+#define IMG_CHAR_QUOTEDBL                              634
+#define IMG_CHAR_NUMBERSIGN                            635
+#define IMG_CHAR_DOLLAR                                        636
+#define IMG_CHAR_PROCENT                               637
+#define IMG_CHAR_AMPERSAND                             638
+#define IMG_CHAR_APOSTROPHE                            639
+#define IMG_CHAR_PARENLEFT                             640
+#define IMG_CHAR_PARENRIGHT                            641
+#define IMG_CHAR_ASTERISK                              642
+#define IMG_CHAR_PLUS                                  643
+#define IMG_CHAR_COMMA                                 644
+#define IMG_CHAR_MINUS                                 645
+#define IMG_CHAR_PERIOD                                        646
+#define IMG_CHAR_SLASH                                 647
+#define IMG_CHAR_0                                     648
+#define IMG_CHAR_1                                     649
+#define IMG_CHAR_2                                     650
+#define IMG_CHAR_3                                     651
+#define IMG_CHAR_4                                     652
+#define IMG_CHAR_5                                     653
+#define IMG_CHAR_6                                     654
+#define IMG_CHAR_7                                     655
+#define IMG_CHAR_8                                     656
+#define IMG_CHAR_9                                     657
+#define IMG_CHAR_COLON                                 658
+#define IMG_CHAR_SEMICOLON                             659
+#define IMG_CHAR_LESS                                  660
+#define IMG_CHAR_EQUAL                                 661
+#define IMG_CHAR_GREATER                               662
+#define IMG_CHAR_QUESTION                              663
+#define IMG_CHAR_AT                                    664
+#define IMG_CHAR_A                                     665
+#define IMG_CHAR_B                                     666
+#define IMG_CHAR_C                                     667
+#define IMG_CHAR_D                                     668
+#define IMG_CHAR_E                                     669
+#define IMG_CHAR_F                                     670
+#define IMG_CHAR_G                                     671
+#define IMG_CHAR_H                                     672
+#define IMG_CHAR_I                                     673
+#define IMG_CHAR_J                                     674
+#define IMG_CHAR_K                                     675
+#define IMG_CHAR_L                                     676
+#define IMG_CHAR_M                                     677
+#define IMG_CHAR_N                                     678
+#define IMG_CHAR_O                                     679
+#define IMG_CHAR_P                                     680
+#define IMG_CHAR_Q                                     681
+#define IMG_CHAR_R                                     682
+#define IMG_CHAR_S                                     683
+#define IMG_CHAR_T                                     684
+#define IMG_CHAR_U                                     685
+#define IMG_CHAR_V                                     686
+#define IMG_CHAR_W                                     687
+#define IMG_CHAR_X                                     688
+#define IMG_CHAR_Y                                     689
+#define IMG_CHAR_Z                                     690
+#define IMG_CHAR_BRACKETLEFT                           691
+#define IMG_CHAR_BACKSLASH                             692
+#define IMG_CHAR_BRACKETRIGHT                          693
+#define IMG_CHAR_ASCIICIRCUM                           694
+#define IMG_CHAR_UNDERSCORE                            695
+#define IMG_CHAR_COPYRIGHT                             696
+#define IMG_CHAR_AUMLAUT                               697
+#define IMG_CHAR_OUMLAUT                               698
+#define IMG_CHAR_UUMLAUT                               699
+#define IMG_CHAR_DEGREE                                        700
+#define IMG_CHAR_TRADEMARK                             701
+#define IMG_CHAR_CURSOR                                        702
+#define IMG_CUSTOM_1                                   703
+#define IMG_CUSTOM_1_EDITOR                            704
+#define IMG_CUSTOM_2                                   705
+#define IMG_CUSTOM_2_EDITOR                            706
+#define IMG_CUSTOM_3                                   707
+#define IMG_CUSTOM_3_EDITOR                            708
+#define IMG_CUSTOM_4                                   709
+#define IMG_CUSTOM_4_EDITOR                            710
+#define IMG_CUSTOM_5                                   711
+#define IMG_CUSTOM_5_EDITOR                            712
+#define IMG_CUSTOM_6                                   713
+#define IMG_CUSTOM_6_EDITOR                            714
+#define IMG_CUSTOM_7                                   715
+#define IMG_CUSTOM_7_EDITOR                            716
+#define IMG_CUSTOM_8                                   717
+#define IMG_CUSTOM_8_EDITOR                            718
+#define IMG_CUSTOM_9                                   719
+#define IMG_CUSTOM_9_EDITOR                            720
+#define IMG_CUSTOM_10                                  721
+#define IMG_CUSTOM_10_EDITOR                           722
+#define IMG_CUSTOM_11                                  723
+#define IMG_CUSTOM_11_EDITOR                           724
+#define IMG_CUSTOM_12                                  725
+#define IMG_CUSTOM_12_EDITOR                           726
+#define IMG_CUSTOM_13                                  727
+#define IMG_CUSTOM_13_EDITOR                           728
+#define IMG_CUSTOM_14                                  729
+#define IMG_CUSTOM_14_EDITOR                           730
+#define IMG_CUSTOM_15                                  731
+#define IMG_CUSTOM_15_EDITOR                           732
+#define IMG_CUSTOM_16                                  733
+#define IMG_CUSTOM_16_EDITOR                           734
+#define IMG_CUSTOM_17                                  735
+#define IMG_CUSTOM_17_EDITOR                           736
+#define IMG_CUSTOM_18                                  737
+#define IMG_CUSTOM_18_EDITOR                           738
+#define IMG_CUSTOM_19                                  739
+#define IMG_CUSTOM_19_EDITOR                           740
+#define IMG_CUSTOM_20                                  741
+#define IMG_CUSTOM_20_EDITOR                           742
+#define IMG_CUSTOM_21                                  743
+#define IMG_CUSTOM_21_EDITOR                           744
+#define IMG_CUSTOM_22                                  745
+#define IMG_CUSTOM_22_EDITOR                           746
+#define IMG_CUSTOM_23                                  747
+#define IMG_CUSTOM_23_EDITOR                           748
+#define IMG_CUSTOM_24                                  749
+#define IMG_CUSTOM_24_EDITOR                           750
+#define IMG_CUSTOM_25                                  751
+#define IMG_CUSTOM_25_EDITOR                           752
+#define IMG_CUSTOM_26                                  753
+#define IMG_CUSTOM_26_EDITOR                           754
+#define IMG_CUSTOM_27                                  755
+#define IMG_CUSTOM_27_EDITOR                           756
+#define IMG_CUSTOM_28                                  757
+#define IMG_CUSTOM_28_EDITOR                           758
+#define IMG_CUSTOM_29                                  759
+#define IMG_CUSTOM_29_EDITOR                           760
+#define IMG_CUSTOM_30                                  761
+#define IMG_CUSTOM_30_EDITOR                           762
+#define IMG_CUSTOM_31                                  763
+#define IMG_CUSTOM_31_EDITOR                           764
+#define IMG_CUSTOM_32                                  765
+#define IMG_CUSTOM_32_EDITOR                           766
+#define IMG_CUSTOM_33                                  767
+#define IMG_CUSTOM_33_EDITOR                           768
+#define IMG_CUSTOM_34                                  769
+#define IMG_CUSTOM_34_EDITOR                           770
+#define IMG_CUSTOM_35                                  771
+#define IMG_CUSTOM_35_EDITOR                           772
+#define IMG_CUSTOM_36                                  773
+#define IMG_CUSTOM_36_EDITOR                           774
+#define IMG_CUSTOM_37                                  775
+#define IMG_CUSTOM_37_EDITOR                           776
+#define IMG_CUSTOM_38                                  777
+#define IMG_CUSTOM_38_EDITOR                           778
+#define IMG_CUSTOM_39                                  779
+#define IMG_CUSTOM_39_EDITOR                           780
+#define IMG_CUSTOM_40                                  781
+#define IMG_CUSTOM_40_EDITOR                           782
+#define IMG_CUSTOM_41                                  783
+#define IMG_CUSTOM_41_EDITOR                           784
+#define IMG_CUSTOM_42                                  785
+#define IMG_CUSTOM_42_EDITOR                           786
+#define IMG_CUSTOM_43                                  787
+#define IMG_CUSTOM_43_EDITOR                           788
+#define IMG_CUSTOM_44                                  789
+#define IMG_CUSTOM_44_EDITOR                           790
+#define IMG_CUSTOM_45                                  791
+#define IMG_CUSTOM_45_EDITOR                           792
+#define IMG_CUSTOM_46                                  793
+#define IMG_CUSTOM_46_EDITOR                           794
+#define IMG_CUSTOM_47                                  795
+#define IMG_CUSTOM_47_EDITOR                           796
+#define IMG_CUSTOM_48                                  797
+#define IMG_CUSTOM_48_EDITOR                           798
+#define IMG_CUSTOM_49                                  799
+#define IMG_CUSTOM_49_EDITOR                           800
+#define IMG_CUSTOM_50                                  801
+#define IMG_CUSTOM_50_EDITOR                           802
+#define IMG_CUSTOM_51                                  803
+#define IMG_CUSTOM_51_EDITOR                           804
+#define IMG_CUSTOM_52                                  805
+#define IMG_CUSTOM_52_EDITOR                           806
+#define IMG_CUSTOM_53                                  807
+#define IMG_CUSTOM_53_EDITOR                           808
+#define IMG_CUSTOM_54                                  809
+#define IMG_CUSTOM_54_EDITOR                           810
+#define IMG_CUSTOM_55                                  811
+#define IMG_CUSTOM_55_EDITOR                           812
+#define IMG_CUSTOM_56                                  813
+#define IMG_CUSTOM_56_EDITOR                           814
+#define IMG_CUSTOM_57                                  815
+#define IMG_CUSTOM_57_EDITOR                           816
+#define IMG_CUSTOM_58                                  817
+#define IMG_CUSTOM_58_EDITOR                           818
+#define IMG_CUSTOM_59                                  819
+#define IMG_CUSTOM_59_EDITOR                           820
+#define IMG_CUSTOM_60                                  821
+#define IMG_CUSTOM_60_EDITOR                           822
+#define IMG_CUSTOM_61                                  823
+#define IMG_CUSTOM_61_EDITOR                           824
+#define IMG_CUSTOM_62                                  825
+#define IMG_CUSTOM_62_EDITOR                           826
+#define IMG_CUSTOM_63                                  827
+#define IMG_CUSTOM_63_EDITOR                           828
+#define IMG_CUSTOM_64                                  829
+#define IMG_CUSTOM_64_EDITOR                           830
+#define IMG_CUSTOM_65                                  831
+#define IMG_CUSTOM_65_EDITOR                           832
+#define IMG_CUSTOM_66                                  833
+#define IMG_CUSTOM_66_EDITOR                           834
+#define IMG_CUSTOM_67                                  835
+#define IMG_CUSTOM_67_EDITOR                           836
+#define IMG_CUSTOM_68                                  837
+#define IMG_CUSTOM_68_EDITOR                           838
+#define IMG_CUSTOM_69                                  839
+#define IMG_CUSTOM_69_EDITOR                           840
+#define IMG_CUSTOM_70                                  841
+#define IMG_CUSTOM_70_EDITOR                           842
+#define IMG_CUSTOM_71                                  843
+#define IMG_CUSTOM_71_EDITOR                           844
+#define IMG_CUSTOM_72                                  845
+#define IMG_CUSTOM_72_EDITOR                           846
+#define IMG_CUSTOM_73                                  847
+#define IMG_CUSTOM_73_EDITOR                           848
+#define IMG_CUSTOM_74                                  849
+#define IMG_CUSTOM_74_EDITOR                           850
+#define IMG_CUSTOM_75                                  851
+#define IMG_CUSTOM_75_EDITOR                           852
+#define IMG_CUSTOM_76                                  853
+#define IMG_CUSTOM_76_EDITOR                           854
+#define IMG_CUSTOM_77                                  855
+#define IMG_CUSTOM_77_EDITOR                           856
+#define IMG_CUSTOM_78                                  857
+#define IMG_CUSTOM_78_EDITOR                           858
+#define IMG_CUSTOM_79                                  859
+#define IMG_CUSTOM_79_EDITOR                           860
+#define IMG_CUSTOM_80                                  861
+#define IMG_CUSTOM_80_EDITOR                           862
+#define IMG_CUSTOM_81                                  863
+#define IMG_CUSTOM_81_EDITOR                           864
+#define IMG_CUSTOM_82                                  865
+#define IMG_CUSTOM_82_EDITOR                           866
+#define IMG_CUSTOM_83                                  867
+#define IMG_CUSTOM_83_EDITOR                           868
+#define IMG_CUSTOM_84                                  869
+#define IMG_CUSTOM_84_EDITOR                           870
+#define IMG_CUSTOM_85                                  871
+#define IMG_CUSTOM_85_EDITOR                           872
+#define IMG_CUSTOM_86                                  873
+#define IMG_CUSTOM_86_EDITOR                           874
+#define IMG_CUSTOM_87                                  875
+#define IMG_CUSTOM_87_EDITOR                           876
+#define IMG_CUSTOM_88                                  877
+#define IMG_CUSTOM_88_EDITOR                           878
+#define IMG_CUSTOM_89                                  879
+#define IMG_CUSTOM_89_EDITOR                           880
+#define IMG_CUSTOM_90                                  881
+#define IMG_CUSTOM_90_EDITOR                           882
+#define IMG_CUSTOM_91                                  883
+#define IMG_CUSTOM_91_EDITOR                           884
+#define IMG_CUSTOM_92                                  885
+#define IMG_CUSTOM_92_EDITOR                           886
+#define IMG_CUSTOM_93                                  887
+#define IMG_CUSTOM_93_EDITOR                           888
+#define IMG_CUSTOM_94                                  889
+#define IMG_CUSTOM_94_EDITOR                           890
+#define IMG_CUSTOM_95                                  891
+#define IMG_CUSTOM_95_EDITOR                           892
+#define IMG_CUSTOM_96                                  893
+#define IMG_CUSTOM_96_EDITOR                           894
+#define IMG_CUSTOM_97                                  895
+#define IMG_CUSTOM_97_EDITOR                           896
+#define IMG_CUSTOM_98                                  897
+#define IMG_CUSTOM_98_EDITOR                           898
+#define IMG_CUSTOM_99                                  899
+#define IMG_CUSTOM_99_EDITOR                           900
+#define IMG_CUSTOM_100                                 901
+#define IMG_CUSTOM_100_EDITOR                          902
+#define IMG_CUSTOM_101                                 903
+#define IMG_CUSTOM_101_EDITOR                          904
+#define IMG_CUSTOM_102                                 905
+#define IMG_CUSTOM_102_EDITOR                          906
+#define IMG_CUSTOM_103                                 907
+#define IMG_CUSTOM_103_EDITOR                          908
+#define IMG_CUSTOM_104                                 909
+#define IMG_CUSTOM_104_EDITOR                          910
+#define IMG_CUSTOM_105                                 911
+#define IMG_CUSTOM_105_EDITOR                          912
+#define IMG_CUSTOM_106                                 913
+#define IMG_CUSTOM_106_EDITOR                          914
+#define IMG_CUSTOM_107                                 915
+#define IMG_CUSTOM_107_EDITOR                          916
+#define IMG_CUSTOM_108                                 917
+#define IMG_CUSTOM_108_EDITOR                          918
+#define IMG_CUSTOM_109                                 919
+#define IMG_CUSTOM_109_EDITOR                          920
+#define IMG_CUSTOM_110                                 921
+#define IMG_CUSTOM_110_EDITOR                          922
+#define IMG_CUSTOM_111                                 923
+#define IMG_CUSTOM_111_EDITOR                          924
+#define IMG_CUSTOM_112                                 925
+#define IMG_CUSTOM_112_EDITOR                          926
+#define IMG_CUSTOM_113                                 927
+#define IMG_CUSTOM_113_EDITOR                          928
+#define IMG_CUSTOM_114                                 929
+#define IMG_CUSTOM_114_EDITOR                          930
+#define IMG_CUSTOM_115                                 931
+#define IMG_CUSTOM_115_EDITOR                          932
+#define IMG_CUSTOM_116                                 933
+#define IMG_CUSTOM_116_EDITOR                          934
+#define IMG_CUSTOM_117                                 935
+#define IMG_CUSTOM_117_EDITOR                          936
+#define IMG_CUSTOM_118                                 937
+#define IMG_CUSTOM_118_EDITOR                          938
+#define IMG_CUSTOM_119                                 939
+#define IMG_CUSTOM_119_EDITOR                          940
+#define IMG_CUSTOM_120                                 941
+#define IMG_CUSTOM_120_EDITOR                          942
+#define IMG_CUSTOM_121                                 943
+#define IMG_CUSTOM_121_EDITOR                          944
+#define IMG_CUSTOM_122                                 945
+#define IMG_CUSTOM_122_EDITOR                          946
+#define IMG_CUSTOM_123                                 947
+#define IMG_CUSTOM_123_EDITOR                          948
+#define IMG_CUSTOM_124                                 949
+#define IMG_CUSTOM_124_EDITOR                          950
+#define IMG_CUSTOM_125                                 951
+#define IMG_CUSTOM_125_EDITOR                          952
+#define IMG_CUSTOM_126                                 953
+#define IMG_CUSTOM_126_EDITOR                          954
+#define IMG_CUSTOM_127                                 955
+#define IMG_CUSTOM_127_EDITOR                          956
+#define IMG_CUSTOM_128                                 957
+#define IMG_CUSTOM_128_EDITOR                          958
+#define IMG_CUSTOM_129                                 959
+#define IMG_CUSTOM_129_EDITOR                          960
+#define IMG_CUSTOM_130                                 961
+#define IMG_CUSTOM_130_EDITOR                          962
+#define IMG_CUSTOM_131                                 963
+#define IMG_CUSTOM_131_EDITOR                          964
+#define IMG_CUSTOM_132                                 965
+#define IMG_CUSTOM_132_EDITOR                          966
+#define IMG_CUSTOM_133                                 967
+#define IMG_CUSTOM_133_EDITOR                          968
+#define IMG_CUSTOM_134                                 969
+#define IMG_CUSTOM_134_EDITOR                          970
+#define IMG_CUSTOM_135                                 971
+#define IMG_CUSTOM_135_EDITOR                          972
+#define IMG_CUSTOM_136                                 973
+#define IMG_CUSTOM_136_EDITOR                          974
+#define IMG_CUSTOM_137                                 975
+#define IMG_CUSTOM_137_EDITOR                          976
+#define IMG_CUSTOM_138                                 977
+#define IMG_CUSTOM_138_EDITOR                          978
+#define IMG_CUSTOM_139                                 979
+#define IMG_CUSTOM_139_EDITOR                          980
+#define IMG_CUSTOM_140                                 981
+#define IMG_CUSTOM_140_EDITOR                          982
+#define IMG_CUSTOM_141                                 983
+#define IMG_CUSTOM_141_EDITOR                          984
+#define IMG_CUSTOM_142                                 985
+#define IMG_CUSTOM_142_EDITOR                          986
+#define IMG_CUSTOM_143                                 987
+#define IMG_CUSTOM_143_EDITOR                          988
+#define IMG_CUSTOM_144                                 989
+#define IMG_CUSTOM_144_EDITOR                          990
+#define IMG_CUSTOM_145                                 991
+#define IMG_CUSTOM_145_EDITOR                          992
+#define IMG_CUSTOM_146                                 993
+#define IMG_CUSTOM_146_EDITOR                          994
+#define IMG_CUSTOM_147                                 995
+#define IMG_CUSTOM_147_EDITOR                          996
+#define IMG_CUSTOM_148                                 997
+#define IMG_CUSTOM_148_EDITOR                          998
+#define IMG_CUSTOM_149                                 999
+#define IMG_CUSTOM_149_EDITOR                          1000
+#define IMG_CUSTOM_150                                 1001
+#define IMG_CUSTOM_150_EDITOR                          1002
+#define IMG_CUSTOM_151                                 1003
+#define IMG_CUSTOM_151_EDITOR                          1004
+#define IMG_CUSTOM_152                                 1005
+#define IMG_CUSTOM_152_EDITOR                          1006
+#define IMG_CUSTOM_153                                 1007
+#define IMG_CUSTOM_153_EDITOR                          1008
+#define IMG_CUSTOM_154                                 1009
+#define IMG_CUSTOM_154_EDITOR                          1010
+#define IMG_CUSTOM_155                                 1011
+#define IMG_CUSTOM_155_EDITOR                          1012
+#define IMG_CUSTOM_156                                 1013
+#define IMG_CUSTOM_156_EDITOR                          1014
+#define IMG_CUSTOM_157                                 1015
+#define IMG_CUSTOM_157_EDITOR                          1016
+#define IMG_CUSTOM_158                                 1017
+#define IMG_CUSTOM_158_EDITOR                          1018
+#define IMG_CUSTOM_159                                 1019
+#define IMG_CUSTOM_159_EDITOR                          1020
+#define IMG_CUSTOM_160                                 1021
+#define IMG_CUSTOM_160_EDITOR                          1022
+#define IMG_CUSTOM_161                                 1023
+#define IMG_CUSTOM_161_EDITOR                          1024
+#define IMG_CUSTOM_162                                 1025
+#define IMG_CUSTOM_162_EDITOR                          1026
+#define IMG_CUSTOM_163                                 1027
+#define IMG_CUSTOM_163_EDITOR                          1028
+#define IMG_CUSTOM_164                                 1029
+#define IMG_CUSTOM_164_EDITOR                          1030
+#define IMG_CUSTOM_165                                 1031
+#define IMG_CUSTOM_165_EDITOR                          1032
+#define IMG_CUSTOM_166                                 1033
+#define IMG_CUSTOM_166_EDITOR                          1034
+#define IMG_CUSTOM_167                                 1035
+#define IMG_CUSTOM_167_EDITOR                          1036
+#define IMG_CUSTOM_168                                 1037
+#define IMG_CUSTOM_168_EDITOR                          1038
+#define IMG_CUSTOM_169                                 1039
+#define IMG_CUSTOM_169_EDITOR                          1040
+#define IMG_CUSTOM_170                                 1041
+#define IMG_CUSTOM_170_EDITOR                          1042
+#define IMG_CUSTOM_171                                 1043
+#define IMG_CUSTOM_171_EDITOR                          1044
+#define IMG_CUSTOM_172                                 1045
+#define IMG_CUSTOM_172_EDITOR                          1046
+#define IMG_CUSTOM_173                                 1047
+#define IMG_CUSTOM_173_EDITOR                          1048
+#define IMG_CUSTOM_174                                 1049
+#define IMG_CUSTOM_174_EDITOR                          1050
+#define IMG_CUSTOM_175                                 1051
+#define IMG_CUSTOM_175_EDITOR                          1052
+#define IMG_CUSTOM_176                                 1053
+#define IMG_CUSTOM_176_EDITOR                          1054
+#define IMG_CUSTOM_177                                 1055
+#define IMG_CUSTOM_177_EDITOR                          1056
+#define IMG_CUSTOM_178                                 1057
+#define IMG_CUSTOM_178_EDITOR                          1058
+#define IMG_CUSTOM_179                                 1059
+#define IMG_CUSTOM_179_EDITOR                          1060
+#define IMG_CUSTOM_180                                 1061
+#define IMG_CUSTOM_180_EDITOR                          1062
+#define IMG_CUSTOM_181                                 1063
+#define IMG_CUSTOM_181_EDITOR                          1064
+#define IMG_CUSTOM_182                                 1065
+#define IMG_CUSTOM_182_EDITOR                          1066
+#define IMG_CUSTOM_183                                 1067
+#define IMG_CUSTOM_183_EDITOR                          1068
+#define IMG_CUSTOM_184                                 1069
+#define IMG_CUSTOM_184_EDITOR                          1070
+#define IMG_CUSTOM_185                                 1071
+#define IMG_CUSTOM_185_EDITOR                          1072
+#define IMG_CUSTOM_186                                 1073
+#define IMG_CUSTOM_186_EDITOR                          1074
+#define IMG_CUSTOM_187                                 1075
+#define IMG_CUSTOM_187_EDITOR                          1076
+#define IMG_CUSTOM_188                                 1077
+#define IMG_CUSTOM_188_EDITOR                          1078
+#define IMG_CUSTOM_189                                 1079
+#define IMG_CUSTOM_189_EDITOR                          1080
+#define IMG_CUSTOM_190                                 1081
+#define IMG_CUSTOM_190_EDITOR                          1082
+#define IMG_CUSTOM_191                                 1083
+#define IMG_CUSTOM_191_EDITOR                          1084
+#define IMG_CUSTOM_192                                 1085
+#define IMG_CUSTOM_192_EDITOR                          1086
+#define IMG_CUSTOM_193                                 1087
+#define IMG_CUSTOM_193_EDITOR                          1088
+#define IMG_CUSTOM_194                                 1089
+#define IMG_CUSTOM_194_EDITOR                          1090
+#define IMG_CUSTOM_195                                 1091
+#define IMG_CUSTOM_195_EDITOR                          1092
+#define IMG_CUSTOM_196                                 1093
+#define IMG_CUSTOM_196_EDITOR                          1094
+#define IMG_CUSTOM_197                                 1095
+#define IMG_CUSTOM_197_EDITOR                          1096
+#define IMG_CUSTOM_198                                 1097
+#define IMG_CUSTOM_198_EDITOR                          1098
+#define IMG_CUSTOM_199                                 1099
+#define IMG_CUSTOM_199_EDITOR                          1100
+#define IMG_CUSTOM_200                                 1101
+#define IMG_CUSTOM_200_EDITOR                          1102
+#define IMG_CUSTOM_201                                 1103
+#define IMG_CUSTOM_201_EDITOR                          1104
+#define IMG_CUSTOM_202                                 1105
+#define IMG_CUSTOM_202_EDITOR                          1106
+#define IMG_CUSTOM_203                                 1107
+#define IMG_CUSTOM_203_EDITOR                          1108
+#define IMG_CUSTOM_204                                 1109
+#define IMG_CUSTOM_204_EDITOR                          1110
+#define IMG_CUSTOM_205                                 1111
+#define IMG_CUSTOM_205_EDITOR                          1112
+#define IMG_CUSTOM_206                                 1113
+#define IMG_CUSTOM_206_EDITOR                          1114
+#define IMG_CUSTOM_207                                 1115
+#define IMG_CUSTOM_207_EDITOR                          1116
+#define IMG_CUSTOM_208                                 1117
+#define IMG_CUSTOM_208_EDITOR                          1118
+#define IMG_CUSTOM_209                                 1119
+#define IMG_CUSTOM_209_EDITOR                          1120
+#define IMG_CUSTOM_210                                 1121
+#define IMG_CUSTOM_210_EDITOR                          1122
+#define IMG_CUSTOM_211                                 1123
+#define IMG_CUSTOM_211_EDITOR                          1124
+#define IMG_CUSTOM_212                                 1125
+#define IMG_CUSTOM_212_EDITOR                          1126
+#define IMG_CUSTOM_213                                 1127
+#define IMG_CUSTOM_213_EDITOR                          1128
+#define IMG_CUSTOM_214                                 1129
+#define IMG_CUSTOM_214_EDITOR                          1130
+#define IMG_CUSTOM_215                                 1131
+#define IMG_CUSTOM_215_EDITOR                          1132
+#define IMG_CUSTOM_216                                 1133
+#define IMG_CUSTOM_216_EDITOR                          1134
+#define IMG_CUSTOM_217                                 1135
+#define IMG_CUSTOM_217_EDITOR                          1136
+#define IMG_CUSTOM_218                                 1137
+#define IMG_CUSTOM_218_EDITOR                          1138
+#define IMG_CUSTOM_219                                 1139
+#define IMG_CUSTOM_219_EDITOR                          1140
+#define IMG_CUSTOM_220                                 1141
+#define IMG_CUSTOM_220_EDITOR                          1142
+#define IMG_CUSTOM_221                                 1143
+#define IMG_CUSTOM_221_EDITOR                          1144
+#define IMG_CUSTOM_222                                 1145
+#define IMG_CUSTOM_222_EDITOR                          1146
+#define IMG_CUSTOM_223                                 1147
+#define IMG_CUSTOM_223_EDITOR                          1148
+#define IMG_CUSTOM_224                                 1149
+#define IMG_CUSTOM_224_EDITOR                          1150
+#define IMG_CUSTOM_225                                 1151
+#define IMG_CUSTOM_225_EDITOR                          1152
+#define IMG_CUSTOM_226                                 1153
+#define IMG_CUSTOM_226_EDITOR                          1154
+#define IMG_CUSTOM_227                                 1155
+#define IMG_CUSTOM_227_EDITOR                          1156
+#define IMG_CUSTOM_228                                 1157
+#define IMG_CUSTOM_228_EDITOR                          1158
+#define IMG_CUSTOM_229                                 1159
+#define IMG_CUSTOM_229_EDITOR                          1160
+#define IMG_CUSTOM_230                                 1161
+#define IMG_CUSTOM_230_EDITOR                          1162
+#define IMG_CUSTOM_231                                 1163
+#define IMG_CUSTOM_231_EDITOR                          1164
+#define IMG_CUSTOM_232                                 1165
+#define IMG_CUSTOM_232_EDITOR                          1166
+#define IMG_CUSTOM_233                                 1167
+#define IMG_CUSTOM_233_EDITOR                          1168
+#define IMG_CUSTOM_234                                 1169
+#define IMG_CUSTOM_234_EDITOR                          1170
+#define IMG_CUSTOM_235                                 1171
+#define IMG_CUSTOM_235_EDITOR                          1172
+#define IMG_CUSTOM_236                                 1173
+#define IMG_CUSTOM_236_EDITOR                          1174
+#define IMG_CUSTOM_237                                 1175
+#define IMG_CUSTOM_237_EDITOR                          1176
+#define IMG_CUSTOM_238                                 1177
+#define IMG_CUSTOM_238_EDITOR                          1178
+#define IMG_CUSTOM_239                                 1179
+#define IMG_CUSTOM_239_EDITOR                          1180
+#define IMG_CUSTOM_240                                 1181
+#define IMG_CUSTOM_240_EDITOR                          1182
+#define IMG_CUSTOM_241                                 1183
+#define IMG_CUSTOM_241_EDITOR                          1184
+#define IMG_CUSTOM_242                                 1185
+#define IMG_CUSTOM_242_EDITOR                          1186
+#define IMG_CUSTOM_243                                 1187
+#define IMG_CUSTOM_243_EDITOR                          1188
+#define IMG_CUSTOM_244                                 1189
+#define IMG_CUSTOM_244_EDITOR                          1190
+#define IMG_CUSTOM_245                                 1191
+#define IMG_CUSTOM_245_EDITOR                          1192
+#define IMG_CUSTOM_246                                 1193
+#define IMG_CUSTOM_246_EDITOR                          1194
+#define IMG_CUSTOM_247                                 1195
+#define IMG_CUSTOM_247_EDITOR                          1196
+#define IMG_CUSTOM_248                                 1197
+#define IMG_CUSTOM_248_EDITOR                          1198
+#define IMG_CUSTOM_249                                 1199
+#define IMG_CUSTOM_249_EDITOR                          1200
+#define IMG_CUSTOM_250                                 1201
+#define IMG_CUSTOM_250_EDITOR                          1202
+#define IMG_CUSTOM_251                                 1203
+#define IMG_CUSTOM_251_EDITOR                          1204
+#define IMG_CUSTOM_252                                 1205
+#define IMG_CUSTOM_252_EDITOR                          1206
+#define IMG_CUSTOM_253                                 1207
+#define IMG_CUSTOM_253_EDITOR                          1208
+#define IMG_CUSTOM_254                                 1209
+#define IMG_CUSTOM_254_EDITOR                          1210
+#define IMG_CUSTOM_255                                 1211
+#define IMG_CUSTOM_255_EDITOR                          1212
+#define IMG_CUSTOM_256                                 1213
+#define IMG_CUSTOM_256_EDITOR                          1214
+#define IMG_TOON_1                                     1215
+#define IMG_TOON_2                                     1216
+#define IMG_TOON_3                                     1217
+#define IMG_TOON_4                                     1218
+#define IMG_TOON_5                                     1219
+#define IMG_TOON_6                                     1220
+#define IMG_TOON_7                                     1221
+#define IMG_TOON_8                                     1222
+#define IMG_TOON_9                                     1223
+#define IMG_TOON_10                                    1224
+#define IMG_TOON_11                                    1225
+#define IMG_TOON_12                                    1226
+#define IMG_TOON_13                                    1227
+#define IMG_TOON_14                                    1228
+#define IMG_TOON_15                                    1229
+#define IMG_TOON_16                                    1230
+#define IMG_TOON_17                                    1231
+#define IMG_TOON_18                                    1232
+#define IMG_TOON_19                                    1233
+#define IMG_TOON_20                                    1234
+#define IMG_MENU_CALIBRATE_RED                         1235
+#define IMG_MENU_CALIBRATE_BLUE                                1236
+#define IMG_MENU_CALIBRATE_YELLOW                      1237
+#define IMG_MENU_BUTTON                                        1238
+#define IMG_MENU_BUTTON_ACTIVE                         1239
+#define IMG_MENU_BUTTON_LEFT                           1240
+#define IMG_MENU_BUTTON_RIGHT                          1241
+#define IMG_MENU_BUTTON_UP                             1242
+#define IMG_MENU_BUTTON_DOWN                           1243
+#define IMG_MENU_BUTTON_LEFT_ACTIVE                    1244
+#define IMG_MENU_BUTTON_RIGHT_ACTIVE                   1245
+#define IMG_MENU_BUTTON_UP_ACTIVE                      1246
+#define IMG_MENU_BUTTON_DOWN_ACTIVE                    1247
+#define IMG_MENU_SCROLLBAR                             1248
+#define IMG_MENU_SCROLLBAR_ACTIVE                      1249
+#define IMG_FONT_INITIAL_1                             1250
+#define IMG_FONT_INITIAL_2                             1251
+#define IMG_FONT_INITIAL_3                             1252
+#define IMG_FONT_INITIAL_4                             1253
+#define IMG_FONT_TITLE_1                               1254
+#define IMG_FONT_TITLE_1_LEVELS                                1255
+#define IMG_FONT_TITLE_2                               1256
+#define IMG_FONT_MENU_1                                        1257
+#define IMG_FONT_MENU_2                                        1258
+#define IMG_FONT_TEXT_1                                        1259
+#define IMG_FONT_TEXT_1_LEVELS                         1260
+#define IMG_FONT_TEXT_1_PREVIEW                                1261
+#define IMG_FONT_TEXT_1_SCORES                         1262
+#define IMG_FONT_TEXT_1_ACTIVE_SCORES                  1263
+#define IMG_FONT_TEXT_2                                        1264
+#define IMG_FONT_TEXT_2_LEVELS                         1265
+#define IMG_FONT_TEXT_2_PREVIEW                                1266
+#define IMG_FONT_TEXT_2_SCORES                         1267
+#define IMG_FONT_TEXT_2_ACTIVE_SCORES                  1268
+#define IMG_FONT_TEXT_3                                        1269
+#define IMG_FONT_TEXT_3_LEVELS                         1270
+#define IMG_FONT_TEXT_3_PREVIEW                                1271
+#define IMG_FONT_TEXT_3_SCORES                         1272
+#define IMG_FONT_TEXT_3_ACTIVE_SCORES                  1273
+#define IMG_FONT_TEXT_4                                        1274
+#define IMG_FONT_TEXT_4_LEVELS                         1275
+#define IMG_FONT_TEXT_4_SCORES                         1276
+#define IMG_FONT_TEXT_4_ACTIVE_SCORES                  1277
+#define IMG_FONT_ENVELOPE_1                            1278
+#define IMG_FONT_ENVELOPE_2                            1279
+#define IMG_FONT_ENVELOPE_3                            1280
+#define IMG_FONT_ENVELOPE_4                            1281
+#define IMG_FONT_INPUT_1                               1282
+#define IMG_FONT_INPUT_1_MAIN                          1283
+#define IMG_FONT_INPUT_1_ACTIVE                                1284
+#define IMG_FONT_INPUT_1_ACTIVE_MAIN                   1285
+#define IMG_FONT_INPUT_1_ACTIVE_SETUP                  1286
+#define IMG_FONT_INPUT_2                               1287
+#define IMG_FONT_INPUT_2_ACTIVE                                1288
+#define IMG_FONT_OPTION_OFF                            1289
+#define IMG_FONT_OPTION_ON                             1290
+#define IMG_FONT_VALUE_1                               1291
+#define IMG_FONT_VALUE_2                               1292
+#define IMG_FONT_VALUE_OLD                             1293
+#define IMG_FONT_LEVEL_NUMBER                          1294
+#define IMG_FONT_TAPE_RECORDER                         1295
+#define IMG_FONT_GAME_INFO                             1296
+#define IMG_GLOBAL_BORDER                              1297
+#define IMG_GLOBAL_DOOR                                        1298
+#define IMG_EDITOR_ELEMENT_BORDER                      1299
+#define IMG_EDITOR_ELEMENT_BORDER_INPUT                        1300
+#define IMG_BACKGROUND_ENVELOPE_1                      1301
+#define IMG_BACKGROUND_ENVELOPE_2                      1302
+#define IMG_BACKGROUND_ENVELOPE_3                      1303
+#define IMG_BACKGROUND_ENVELOPE_4                      1304
+#define IMG_BACKGROUND                                 1305
+#define IMG_BACKGROUND_MAIN                            1306
+#define IMG_BACKGROUND_LEVELS                          1307
+#define IMG_BACKGROUND_SCORES                          1308
+#define IMG_BACKGROUND_EDITOR                          1309
+#define IMG_BACKGROUND_INFO                            1310
+#define IMG_BACKGROUND_SETUP                           1311
+#define IMG_BACKGROUND_DOOR                            1312
 
-#define NUM_IMAGE_FILES                                        1320
+#define NUM_IMAGE_FILES                                        1313
 
 #endif /* CONF_GFX_H */
diff --git a/src/conf_hlp.c b/src/conf_hlp.c
new file mode 100644 (file)
index 0000000..68cd4cf
--- /dev/null
@@ -0,0 +1,640 @@
+/***********************************************************
+* 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_hlp.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 helpanim_config[] =
+{
+  { "player_1.moving.down",                    "16"                    },
+  { "player_1.moving.up",                      "16"                    },
+  { "player_1.moving.left",                    "16"                    },
+  { "player_1.moving.right",                   "16"                    },
+  { "player_1.pushing.left",                   "16"                    },
+  { "player_1.pushing.right",                  "16"                    },
+  { "end",                                     ""                      },
+
+  { "sand",                                    "50"                    },
+  { "sand.digging.left",                       "8"                     },
+  { "empty_space",                             "10"                    },
+  { "sand",                                    "50"                    },
+  { "sand.digging.right",                      "8"                     },
+  { "empty_space",                             "10"                    },
+  { "sand",                                    "50"                    },
+  { "sand.digging.up",                         "8"                     },
+  { "empty_space",                             "10"                    },
+  { "sand",                                    "50"                    },
+  { "sand.digging.down",                       "8"                     },
+  { "empty_space",                             "10"                    },
+  { "end",                                     ""                      },
+
+  { "empty_space",                             "-1"                    },
+  { "end",                                     ""                      },
+
+  { "quicksand_empty",                         "-1"                    },
+  { "end",                                     ""                      },
+
+  { "steelwall",                               "-1"                    },
+  { "end",                                     ""                      },
+
+  { "wall",                                    "-1"                    },
+  { "end",                                     ""                      },
+
+  { "expandable_wall.growing.left",            "20"                    },
+  { "wall",                                    "50"                    },
+  { "expandable_wall.growing.right",           "20"                    },
+  { "wall",                                    "50"                    },
+  { "expandable_wall.growing.up",              "20"                    },
+  { "wall",                                    "50"                    },
+  { "expandable_wall.growing.down",            "20"                    },
+  { "wall",                                    "50"                    },
+  { "empty_space",                             "20"                    },
+  { "end",                                     ""                      },
+
+  { "invisible_wall",                          "-1"                    },
+  { "end",                                     ""                      },
+
+  { "wall_slippery",                           "-1"                    },
+  { "end",                                     ""                      },
+
+  { "char_space",                              "10"                    },
+  { "char_exclam",                             "10"                    },
+  { "char_quotedbl",                           "10"                    },
+  { "char_numbersign",                         "10"                    },
+  { "char_dollar",                             "10"                    },
+  { "char_procent",                            "10"                    },
+  { "char_ampersand",                          "10"                    },
+  { "char_apostrophe",                         "10"                    },
+  { "char_parenleft",                          "10"                    },
+  { "char_parenright",                         "10"                    },
+  { "char_asterisk",                           "10"                    },
+  { "char_plus",                               "10"                    },
+  { "char_comma",                              "10"                    },
+  { "char_minus",                              "10"                    },
+  { "char_period",                             "10"                    },
+  { "char_slash",                              "10"                    },
+  { "char_0",                                  "10"                    },
+  { "char_1",                                  "10"                    },
+  { "char_2",                                  "10"                    },
+  { "char_3",                                  "10"                    },
+  { "char_4",                                  "10"                    },
+  { "char_5",                                  "10"                    },
+  { "char_6",                                  "10"                    },
+  { "char_7",                                  "10"                    },
+  { "char_8",                                  "10"                    },
+  { "char_9",                                  "10"                    },
+  { "char_colon",                              "10"                    },
+  { "char_semicolon",                          "10"                    },
+  { "char_less",                               "10"                    },
+  { "char_equal",                              "10"                    },
+  { "char_greater",                            "10"                    },
+  { "char_question",                           "10"                    },
+  { "char_at",                                 "10"                    },
+  { "char_a",                                  "10"                    },
+  { "char_b",                                  "10"                    },
+  { "char_c",                                  "10"                    },
+  { "char_d",                                  "10"                    },
+  { "char_e",                                  "10"                    },
+  { "char_f",                                  "10"                    },
+  { "char_g",                                  "10"                    },
+  { "char_h",                                  "10"                    },
+  { "char_i",                                  "10"                    },
+  { "char_j",                                  "10"                    },
+  { "char_k",                                  "10"                    },
+  { "char_l",                                  "10"                    },
+  { "char_m",                                  "10"                    },
+  { "char_n",                                  "10"                    },
+  { "char_o",                                  "10"                    },
+  { "char_p",                                  "10"                    },
+  { "char_q",                                  "10"                    },
+  { "char_r",                                  "10"                    },
+  { "char_s",                                  "10"                    },
+  { "char_t",                                  "10"                    },
+  { "char_u",                                  "10"                    },
+  { "char_v",                                  "10"                    },
+  { "char_w",                                  "10"                    },
+  { "char_x",                                  "10"                    },
+  { "char_y",                                  "10"                    },
+  { "char_z",                                  "10"                    },
+  { "char_bracketleft",                                "10"                    },
+  { "char_backslash",                          "10"                    },
+  { "char_bracketright",                       "10"                    },
+  { "char_asciicircum",                                "10"                    },
+  { "char_underscore",                         "10"                    },
+  { "char_copyright",                          "10"                    },
+  { "char_aumlaut",                            "10"                    },
+  { "char_oumlaut",                            "10"                    },
+  { "char_uumlaut",                            "10"                    },
+  { "char_degree",                             "10"                    },
+  { "char_trademark",                          "10"                    },
+  { "char_cursor",                             "10"                    },
+  { "end",                                     ""                      },
+
+  { "emerald",                                 "50"                    },
+  { "emerald.collecting",                      "8"                     },
+  { "empty_space",                             "10"                    },
+  { "end",                                     ""                      },
+
+  { "diamond",                                 "50"                    },
+  { "diamond.collecting",                      "8"                     },
+  { "empty_space",                             "10"                    },
+  { "end",                                     ""                      },
+
+  { "bd_diamond",                              "50"                    },
+  { "bd_diamond.collecting",                   "8"                     },
+  { "empty_space",                             "10"                    },
+  { "end",                                     ""                      },
+
+  { "emerald_yellow",                          "50"                    },
+  { "emerald_yellow.collecting",               "8"                     },
+  { "empty_space",                             "10"                    },
+  { "emerald_red",                             "50"                    },
+  { "emerald_red.collecting",                  "8"                     },
+  { "empty_space",                             "10"                    },
+  { "emerald_purple",                          "50"                    },
+  { "emerald_purple.collecting",               "8"                     },
+  { "empty_space",                             "10"                    },
+  { "end",                                     ""                      },
+
+  { "bd_rock",                                 "-1"                    },
+  { "end",                                     ""                      },
+
+  { "bomb",                                    "100"                   },
+  { "bomb.exploding",                          "16"                    },
+  { "empty_space",                             "10"                    },
+  { "end",                                     ""                      },
+
+  { "nut",                                     "100"                   },
+  { "nut.breaking",                            "6"                     },
+  { "emerald",                                 "20"                    },
+  { "end",                                     ""                      },
+
+  { "wall_emerald",                            "100"                   },
+  { "wall_emerald.exploding",                  "16"                    },
+  { "emerald",                                 "20"                    },
+  { "end",                                     ""                      },
+
+  { "wall_diamond",                            "100"                   },
+  { "wall_diamond.exploding",                  "16"                    },
+  { "diamond",                                 "20"                    },
+  { "end",                                     ""                      },
+
+  { "wall_bd_diamond",                         "100"                   },
+  { "wall_bd_diamond.exploding",               "16"                    },
+  { "bd_diamond",                              "20"                    },
+  { "end",                                     ""                      },
+
+  { "wall_emerald_yellow",                     "100"                   },
+  { "wall_emerald_yellow.exploding",           "16"                    },
+  { "emerald_yellow",                          "20"                    },
+  { "wall_emerald_red",                                "100"                   },
+  { "wall_emerald_red.exploding",              "16"                    },
+  { "emerald_red",                             "20"                    },
+  { "wall_emerald_purple",                     "100"                   },
+  { "wall_emerald_purple.exploding",           "16"                    },
+  { "emerald_purple",                          "20"                    },
+  { "end",                                     ""                      },
+
+  { "acid",                                    "-1"                    },
+  { "end",                                     ""                      },
+
+  { "key_1",                                   "50"                    },
+  { "key_2",                                   "50"                    },
+  { "key_3",                                   "50"                    },
+  { "key_4",                                   "50"                    },
+  { "end",                                     ""                      },
+
+  { "gate_1",                                  "50"                    },
+  { "gate_2",                                  "50"                    },
+  { "gate_3",                                  "50"                    },
+  { "gate_4",                                  "50"                    },
+  { "end",                                     ""                      },
+
+  { "gate_1_gray",                             "50"                    },
+  { "gate_2_gray",                             "50"                    },
+  { "gate_3_gray",                             "50"                    },
+  { "gate_4_gray",                             "50"                    },
+  { "end",                                     ""                      },
+
+  { "dynamite",                                        "-1"                    },
+  { "end",                                     ""                      },
+
+  { "dynamite.active",                         "96"                    },
+  { "dynamite.exploding",                      "16"                    },
+  { "empty_space",                             "20"                    },
+  { "end",                                     ""                      },
+
+  { "dynabomb.active",                         "100"                   },
+  { "dynabomb.exploding",                      "16"                    },
+  { "empty_space",                             "20"                    },
+  { "end",                                     ""                      },
+
+  { "dynabomb_increase_number",                        "-1"                    },
+  { "end",                                     ""                      },
+
+  { "dynabomb_increase_size",                  "-1"                    },
+  { "end",                                     ""                      },
+
+  { "dynabomb_increase_power",                 "-1"                    },
+  { "end",                                     ""                      },
+
+  { "spaceship.turning_from_right.up",         "8"                     },
+  { "spaceship.turning_from_up.left",          "8"                     },
+  { "spaceship.turning_from_left.down",                "8"                     },
+  { "spaceship.turning_from_down.right",       "8"                     },
+  { "end",                                     ""                      },
+
+  { "bug.turning_from_right.up",               "8"                     },
+  { "bug.turning_from_up.left",                        "8"                     },
+  { "bug.turning_from_left.down",              "8"                     },
+  { "bug.turning_from_down.right",             "8"                     },
+  { "end",                                     ""                      },
+
+  { "bd_butterfly",                            "-1"                    },
+  { "end",                                     ""                      },
+
+  { "bd_firefly",                              "-1"                    },
+  { "end",                                     ""                      },
+
+  { "pacman.right",                            "16"                    },
+  { "pacman.up",                               "16"                    },
+  { "pacman.left",                             "16"                    },
+  { "pacman.down",                             "16"                    },
+  { "end",                                     ""                      },
+
+  { "yamyam",                                  "-1"                    },
+  { "end",                                     ""                      },
+
+  { "dark_yamyam",                             "-1"                    },
+  { "end",                                     ""                      },
+
+  { "robot",                                   "-1"                    },
+  { "end",                                     ""                      },
+
+  { "mole.moving.right",                       "16"                    },
+  { "mole.moving.up",                          "16"                    },
+  { "mole.moving.left",                                "16"                    },
+  { "mole.moving.down",                                "16"                    },
+  { "end",                                     ""                      },
+
+  { "penguin.moving.right",                    "16"                    },
+  { "penguin.moving.up",                       "16"                    },
+  { "penguin.moving.left",                     "16"                    },
+  { "penguin.moving.down",                     "16"                    },
+  { "end",                                     ""                      },
+
+  { "pig.moving.right",                                "16"                    },
+  { "pig.moving.up",                           "16"                    },
+  { "pig.moving.left",                         "16"                    },
+  { "pig.moving.down",                         "16"                    },
+  { "end",                                     ""                      },
+
+  { "dragon.moving.right",                     "16"                    },
+  { "dragon.moving.up",                                "16"                    },
+  { "dragon.moving.left",                      "16"                    },
+  { "dragon.moving.down",                      "16"                    },
+  { "end",                                     ""                      },
+
+  { "satellite",                               "-1"                    },
+  { "end",                                     ""                      },
+
+  { "robot_wheel",                             "50"                    },
+  { "robot_wheel.active",                      "100"                   },
+  { "end",                                     ""                      },
+
+  { "lamp",                                    "50"                    },
+  { "lamp.active",                             "50"                    },
+  { "end",                                     ""                      },
+
+  { "time_orb_full",                           "50"                    },
+  { "time_orb_empty",                          "50"                    },
+  { "end",                                     ""                      },
+
+  { "amoeba_drop",                             "50"                    },
+  { "amoeba.growing",                          "6"                     },
+  { "amoeba_wet",                              "20"                    },
+  { "end",                                     ""                      },
+
+  { "amoeba_dead",                             "-1"                    },
+  { "end",                                     ""                      },
+
+  { "amoeba_wet",                              "-1"                    },
+  { "end",                                     ""                      },
+
+  { "amoeba_wet",                              "100"                   },
+  { "amoeba.growing",                          "6"                     },
+  { "end",                                     ""                      },
+
+  { "amoeba_full",                             "50"                    },
+  { "amoeba_dead",                             "50"                    },
+  { "amoeba.exploding",                                "16"                    },
+  { "diamond",                                 "20"                    },
+  { "end",                                     ""                      },
+
+  { "game_of_life",                            "-1"                    },
+  { "end",                                     ""                      },
+
+  { "biomaze",                                 "-1"                    },
+  { "end",                                     ""                      },
+
+  { "magic_wall.active",                       "-1"                    },
+  { "end",                                     ""                      },
+
+  { "bd_magic_wall.active",                    "-1"                    },
+  { "end",                                     ""                      },
+
+  { "exit_closed",                             "200"                   },
+  { "exit.opening",                            "30"                    },
+  { "exit_open",                               "100"                   },
+  { "exit.closing",                            "30"                    },
+  { "end",                                     ""                      },
+
+  { "exit_open",                               "-1"                    },
+  { "end",                                     ""                      },
+
+  { "sokoban_object",                          "-1"                    },
+  { "end",                                     ""                      },
+
+  { "sokoban_field_empty",                     "-1"                    },
+  { "end",                                     ""                      },
+
+  { "sokoban_field_full",                      "-1"                    },
+  { "end",                                     ""                      },
+
+  { "speed_pill",                              "-1"                    },
+  { "end",                                     ""                      },
+
+  { NULL,                                      NULL                    }
+};
+
+struct ConfigInfo helptext_config[] =
+{
+  {
+    "player_1",
+    "THE HERO: (Is _this_ guy good old Rockford?)"
+  },
+  {
+    "sand",
+    "Normal sand: You can dig through it"
+  },
+  {
+    "empty_space",
+    "Empty field: You can walk through it"
+  },
+  {
+    "quicksand_empty",
+    "Quicksand: You cannot pass it, but rocks can fall through it"
+  },
+  {
+    "steelwall",
+    "Massive Wall: Nothing can go through it"
+  },
+  {
+    "wall",
+    "Normal Wall: You can't go through it, but you can bomb it away"
+  },
+  {
+    "expandable_wall",
+    "Growing Wall: Grows in several directions if there is an empty field"
+  },
+  {
+    "invisible_wall",
+    "Invisible Wall: Behaves like normal wall, but is invisible"
+  },
+  {
+    "wall_slippery",
+    "Old Wall: Like normal wall, but some things can fall down from it"
+  },
+  {
+    "char_space",
+    "Letter Wall: Looks like a letter, behaves like a normal wall"
+  },
+  {
+    "emerald",
+    "Emerald: You must collect enough of them to finish a level"
+  },
+  {
+    "diamond",
+    "Diamond: Counts as 3 emeralds, but can be destroyed by rocks"
+  },
+  {
+    "bd_diamond",
+    "Diamond (BD style): Counts like one emerald and behaves a bit different"
+  },
+  {
+    "emerald_yellow",
+    "Colorful Gems: Seem to behave like Emeralds"
+  },
+  {
+    "bd_rock",
+    "Rock: Smashes several things; Can be moved by the player"
+  },
+  {
+    "bomb",
+    "Bomb: You can move it, but be careful when dropping it"
+  },
+  {
+    "nut",
+    "Nut: Throw a rock on it to open it; Each nut contains an emerald"
+  },
+  {
+    "wall_emerald",
+    "Wall with an emerald inside: Bomb the wall away to get it"
+  },
+  {
+    "wall_diamond",
+    "Wall with a diamond inside: Bomb the wall away to get it"
+  },
+  {
+    "wall_bd_diamond",
+    "Wall with BD style diamond inside: Bomb the wall away to get it"
+  },
+  {
+    "wall_emerald_yellow",
+    "Wall with colorful gem inside: Bomb the wall away to get it"
+  },
+  {
+    "acid",
+    "Acid: Things that fall in are gone forever (including our hero)"
+  },
+  {
+    "key_1",
+    "Key: Opens the door that has the same color (red/yellow/green/blue)"
+  },
+  {
+    "gate_1",
+    "Door: Can be opened by the key with the same color"
+  },
+  {
+    "gate_1_gray",
+    "Door: You have to find out the right color of the key for it"
+  },
+  {
+    "dynamite",
+    "Dynamite: Collect it and use it to destroy walls or kill enemies"
+  },
+  {
+    "dynamite.active",
+    "Dynamite: This one explodes after a few seconds"
+  },
+  {
+    "dynabomb",
+    "Dyna Bomb: Explodes in 4 directions with variable explosion size"
+  },
+  {
+    "dynabomb_increase_number",
+    "Dyna Bomb: Increases the number of dyna bombs available at a time"
+  },
+  {
+    "dynabomb_increase_size",
+    "Dyna Bomb: Increases the size of explosion of dyna bombs"
+  },
+  {
+    "dynabomb_increase_power",
+    "Dyna Bomb: Increases the power of explosion of dyna bombs"
+  },
+  {
+    "spaceship",
+    "Spaceship: Moves at the left side of walls; don't touch it!"
+  },
+  {
+    "bug",
+    "Bug: Moves at the right side of walls; don't touch it!"
+  },
+  {
+    "bd_butterfly",
+    "Butterfly: Moves at the right side of walls; don't touch it!"
+  },
+  {
+    "bd_firefly",
+    "Firefly: Moves at the left side of walls; don't touch it!"
+  },
+  {
+    "pacman",
+    "Pacman: Eats the amoeba and you, if you're not careful"
+  },
+  {
+    "yamyam",
+    "Cruncher: Eats diamonds and you, if you're not careful"
+  },
+  {
+    "dark_yamyam",
+    "Cruncher (BD style): Eats almost everything"
+  },
+  {
+    "robot",
+    "Robot: Tries to kill the player"
+  },
+  {
+    "mole",
+    "The mole: Eats the amoeba and turns empty space into normal sand"
+  },
+  {
+    "penguin",
+    "The penguin: Guide him to the exit, but keep him away from monsters!"
+  },
+  {
+    "pig",
+    "The Pig: Harmless, but eats all gems it can get"
+  },
+  {
+    "dragon",
+    "The Dragon: Breathes fire, especially to some monsters"
+  },
+  {
+    "satellite",
+    "Sonde: Follows you everywhere; harmless, but may block your way"
+  },
+  {
+    "robot_wheel",
+    "Magic Wheel: Touch it to get rid of the robots for some seconds"
+  },
+  {
+    "lamp",
+    "Light Bulb: All of them must be switched on to finish a level"
+  },
+  {
+    "time_orb_full",
+    "Extra Time Orb: Adds some seconds to the time available for the level"
+  },
+  {
+    "amoeba_drop",
+    "Amoeba Drop: Grows to an amoeba on the ground - don't touch it"
+  },
+  {
+    "amoeba_dead",
+    "Dead Amoeba: Does not grow, but can still kill bugs and spaceships"
+  },
+  {
+    "amoeba_wet",
+    "Normal Amoeba: Grows through empty fields, sand and quicksand"
+  },
+  {
+    "amoeba_wet",
+    "Dropping Amoeba: This one makes drops that grow to a new amoeba"
+  },
+  {
+    "amoeba_full",
+    "Living Amoeba (BD style): Contains other element, when surrounded"
+  },
+  {
+    "game_of_life",
+    "Game Of Life: Behaves like the well known 'Game Of Life' (2333 style)"
+  },
+  {
+    "biomaze",
+    "Biomaze: A bit like the 'Game Of Life', but builds crazy mazes"
+  },
+  {
+    "magic_wall",
+    "Magic Wall: Changes rocks, emeralds and diamonds when they pass it"
+  },
+  {
+    "bd_magic_wall",
+    "Magic Wall (BD style): Changes rocks and BD style diamonds"
+  },
+  {
+    "exit_closed",
+    "Exit door: Opens if you have enough emeralds to finish the level"
+  },
+  {
+    "exit_open",
+    "Open exit door: Enter here to leave the level and exit the actual game"
+  },
+  {
+    "sokoban_object",
+    "Sokoban element: Object which must be pushed to an empty field"
+  },
+  {
+    "sokoban_field_empty",
+    "Sokoban element: Empty field where a Sokoban object can be placed on"
+  },
+  {
+    "sokoban_field_full",
+    "Sokoban element: Field with object which can be pushed away"
+  },
+  {
+    "speed_pill",
+    "Speed pill: Lets the player run twice as fast as normally"
+  },
+
+  {
+    NULL,
+    NULL
+  }
+};
diff --git a/src/conf_mus.c b/src/conf_mus.c
new file mode 100644 (file)
index 0000000..1c29c61
--- /dev/null
@@ -0,0 +1,44 @@
+/***********************************************************
+* 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_mus.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 MUS_ARG_UNDEFINED, it will
+   be dynamically determined, using some of the other list values. */
+
+struct ConfigInfo music_config_suffix[] =
+{
+  { ".mode_loop",                      ARG_UNDEFINED,  TYPE_BOOLEAN    },
+
+  { NULL,                              NULL,           0               }
+};
+
+struct ConfigInfo music_config[] =
+{
+  { "background",                      UNDEFINED_FILENAME              },
+  { "background.MAIN",                 UNDEFINED_FILENAME              },
+  { "background.LEVELS",               UNDEFINED_FILENAME              },
+  { "background.SCORES",               UNDEFINED_FILENAME              },
+  { "background.EDITOR",               UNDEFINED_FILENAME              },
+  { "background.INFO",                 "rhythmloop.wav"                },
+  { "background.SETUP",                        UNDEFINED_FILENAME              },
+
+  /* there is no definition for "background.PLAYING", because this would
+     prevent selecting music from music directory that is not defined in
+     "musicinfo.conf", when no default music is defined here */
+
+  { NULL,                              NULL                            }
+};
diff --git a/src/conf_mus.h b/src/conf_mus.h
new file mode 100644 (file)
index 0000000..e6ba90e
--- /dev/null
@@ -0,0 +1,31 @@
+/***********************************************************
+* 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_mus.h                                               *
+***********************************************************/
+
+/* ----- this file was automatically generated -- do not edit by hand ----- */
+
+#ifndef CONF_MUS_H
+#define CONF_MUS_H
+
+/* values for music configuration */
+
+#define MUS_BACKGROUND                                 0
+#define MUS_BACKGROUND_MAIN                            1
+#define MUS_BACKGROUND_LEVELS                          2
+#define MUS_BACKGROUND_SCORES                          3
+#define MUS_BACKGROUND_EDITOR                          4
+#define MUS_BACKGROUND_INFO                            5
+#define MUS_BACKGROUND_SETUP                           6
+
+#define NUM_MUSIC_FILES                                        7
+
+#endif /* CONF_MUS_H */
index 27b664b0f2c46306b288aa37685930342834cc35..cd9869b081fa9fc32e6dca45cdcdfea7d0897d94 100644 (file)
 
 
 /* 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
+   reliable default values. If that value is SND_ARG_UNDEFINED, it will
    be dynamically determined, using some of the other list values. */
 
 struct ConfigInfo sound_config_suffix[] =
 {
-  { ".mode_loop",                      ARG_UNDEFINED,  TYPE_BOOLEAN },
+  { ".mode_loop",                      ARG_UNDEFINED,  TYPE_BOOLEAN    },
 
-  { NULL,                              NULL,           0            }
+  { 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"             },
+  { "[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"             },
+  { "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_exit].closing",               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      },
+  { "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_exit].closing",               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      },
+  { "[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].closing",                  "oeffnen.wav"           },
-  { "[exit].passing",                  "buing.wav"             },
-  { "penguin.passing",                 "buing.wav"             },
+  { "[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].closing",                  "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      },
+  { "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"              },
-  { "[envelope].opening",              UNDEFINED_FILENAME      },
-  { "[envelope].closing",              UNDEFINED_FILENAME      },
-  { "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      },
+  { "pearl.collecting",                        "pong.wav"                      },
+  { "pearl.breaking",                  "knack.wav"                     },
+  { "pearl.impact",                    "pling.wav"                     },
+  { "crystal.collecting",              "pong.wav"                      },
+  { "crystal.impact",                  "pling.wav"                     },
+  { "[envelope].collecting",           "pong.wav"                      },
+  { "[envelope].opening",              UNDEFINED_FILENAME              },
+  { "[envelope].closing",              UNDEFINED_FILENAME              },
+  { "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      },
+  { "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      },
+  { "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"             },
+  { "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"           },
+  { "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"                  },
+  { "background.MAIN",                 UNDEFINED_FILENAME              },
+  { "background.LEVELS",               UNDEFINED_FILENAME              },
+  { "background.SCORES",               "halloffame.wav"                },
+  { "background.SCORES.mode_loop",     "false"                         },
+  { "background.EDITOR",               UNDEFINED_FILENAME              },
+  { "background.INFO",                 UNDEFINED_FILENAME              },
+  { "background.SETUP",                        UNDEFINED_FILENAME              },
 
 #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"              },
+  { "[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                    }
+  { NULL,                              NULL                            }
 };
index 9d89363f840f1d4ed2ffeb15ce6a667ce7dbde90..280815531baa9238c241769878922d857588ed8a 100644 (file)
 
 /* 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_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_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_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_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_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_CLASS_SP_EXIT_CLOSING                              38
+#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_CLASS_SP_EXIT_CLOSING                      38
 #define SND_SP_SNIKSNAK_MOVING                         39
 #define SND_SP_SNIKSNAK_WAITING                                40
 #define SND_SP_ELECTRON_MOVING                         41
 #define SND_SP_ELECTRON_WAITING                                42
-#define SND_SP_TERMINAL_ACTIVATING                             43
+#define SND_SP_TERMINAL_ACTIVATING                     43
 #define SND_SP_TERMINAL_ACTIVE                         44
-#define SND_CLASS_SOKOBAN_PUSHING                              45
-#define SND_CLASS_SOKOBAN_FILLING                              46
-#define SND_CLASS_SOKOBAN_EMPTYING                             47
-#define SND_CLASS_PLAYER_MOVING                                        48
-#define SND_SAND_DIGGING                                       49
-#define SND_EMERALD_COLLECTING                         50
-#define SND_EMERALD_IMPACT                                     51
+#define SND_CLASS_SOKOBAN_PUSHING                      45
+#define SND_CLASS_SOKOBAN_FILLING                      46
+#define SND_CLASS_SOKOBAN_EMPTYING                     47
+#define SND_CLASS_PLAYER_MOVING                                48
+#define SND_SAND_DIGGING                               49
+#define SND_CLASS_EMERALD_COLLECTING                   50
+#define SND_CLASS_EMERALD_IMPACT                       51
 #define SND_DIAMOND_COLLECTING                         52
-#define SND_DIAMOND_IMPACT                                     53
+#define SND_DIAMOND_IMPACT                             53
 #define SND_DIAMOND_BREAKING                           54
-#define SND_ROCK_PUSHING                                       55
+#define SND_ROCK_PUSHING                               55
 #define SND_ROCK_IMPACT                                        56
-#define SND_BOMB_PUSHING                                       57
+#define SND_BOMB_PUSHING                               57
 #define SND_NUT_PUSHING                                        58
-#define SND_NUT_BREAKING                                       59
+#define SND_NUT_BREAKING                               59
 #define SND_NUT_IMPACT                                 60
-#define SND_CLASS_DYNAMITE_COLLECTING                          61
-#define SND_CLASS_DYNAMITE_DROPPING                            62
-#define SND_CLASS_DYNAMITE_ACTIVE                              63
-#define SND_CLASS_KEY_COLLECTING                               64
-#define SND_CLASS_GATE_PASSING                                 65
+#define SND_CLASS_DYNAMITE_COLLECTING                  61
+#define SND_CLASS_DYNAMITE_DROPPING                    62
+#define SND_CLASS_DYNAMITE_ACTIVE                      63
+#define SND_CLASS_KEY_COLLECTING                       64
+#define SND_CLASS_GATE_PASSING                         65
 #define SND_BUG_MOVING                                 66
 #define SND_BUG_WAITING                                        67
 #define SND_SPACESHIP_MOVING                           68
 #define SND_SPACESHIP_WAITING                          69
-#define SND_YAMYAM_MOVING                                      70
-#define SND_YAMYAM_WAITING                                     71
-#define SND_YAMYAM_DIGGING                                     72
-#define SND_ROBOT_MOVING                                       73
-#define SND_ROBOT_WAITING                                      74
-#define SND_ROBOT_WHEEL_ACTIVATING                             75
+#define SND_YAMYAM_MOVING                              70
+#define SND_YAMYAM_WAITING                             71
+#define SND_YAMYAM_DIGGING                             72
+#define SND_ROBOT_MOVING                               73
+#define SND_ROBOT_WAITING                              74
+#define SND_ROBOT_WHEEL_ACTIVATING                     75
 #define SND_ROBOT_WHEEL_ACTIVE                         76
-#define SND_MAGIC_WALL_ACTIVATING                              77
+#define SND_MAGIC_WALL_ACTIVATING                      77
 #define SND_MAGIC_WALL_ACTIVE                          78
 #define SND_MAGIC_WALL_FILLING                         79
-#define SND_CLASS_AMOEBA_WAITING                               80
-#define SND_CLASS_AMOEBA_GROWING                               81
-#define SND_CLASS_AMOEBA_DROPPING                              82
-#define SND_ACID_SPLASHING                                     83
-#define SND_CLASS_QUICKSAND_FILLING                            84
-#define SND_CLASS_QUICKSAND_EMPTYING                           85
-#define SND_CLASS_EXIT_OPENING                                 86
-#define SND_CLASS_EXIT_CLOSING                                 87
-#define SND_CLASS_EXIT_PASSING                                 88
-#define SND_PENGUIN_PASSING                                    89
-#define SND_BALLOON_MOVING                                     90
-#define SND_BALLOON_WAITING                                    91
-#define SND_BALLOON_PUSHING                                    92
-#define SND_CLASS_BALLOON_SWITCH_ACTIVATING                    93
-#define SND_SPRING_MOVING                                      94
-#define SND_SPRING_PUSHING                                     95
-#define SND_SPRING_IMPACT                                      96
-#define SND_CLASS_WALL_GROWING                                 97
+#define SND_CLASS_AMOEBA_WAITING                       80
+#define SND_CLASS_AMOEBA_GROWING                       81
+#define SND_CLASS_AMOEBA_DROPPING                      82
+#define SND_ACID_SPLASHING                             83
+#define SND_CLASS_QUICKSAND_FILLING                    84
+#define SND_CLASS_QUICKSAND_EMPTYING                   85
+#define SND_CLASS_EXIT_OPENING                         86
+#define SND_CLASS_EXIT_CLOSING                         87
+#define SND_CLASS_EXIT_PASSING                         88
+#define SND_PENGUIN_PASSING                            89
+#define SND_BALLOON_MOVING                             90
+#define SND_BALLOON_WAITING                            91
+#define SND_BALLOON_PUSHING                            92
+#define SND_CLASS_BALLOON_SWITCH_ACTIVATING            93
+#define SND_SPRING_MOVING                              94
+#define SND_SPRING_PUSHING                             95
+#define SND_SPRING_IMPACT                              96
+#define SND_CLASS_WALL_GROWING                         97
 #define SND_PEARL_COLLECTING                           98
-#define SND_PEARL_BREAKING                                     99
-#define SND_PEARL_IMPACT                                       100
+#define SND_PEARL_BREAKING                             99
+#define SND_PEARL_IMPACT                               100
 #define SND_CRYSTAL_COLLECTING                         101
-#define SND_CRYSTAL_IMPACT                                     102
-#define SND_CLASS_ENVELOPE_COLLECTING                          103
-#define SND_CLASS_ENVELOPE_OPENING                             104
-#define SND_CLASS_ENVELOPE_CLOSING                             105
-#define SND_INVISIBLE_SAND_DIGGING                             106
+#define SND_CRYSTAL_IMPACT                             102
+#define SND_CLASS_ENVELOPE_COLLECTING                  103
+#define SND_CLASS_ENVELOPE_OPENING                     104
+#define SND_CLASS_ENVELOPE_CLOSING                     105
+#define SND_INVISIBLE_SAND_DIGGING                     106
 #define SND_SHIELD_NORMAL_COLLECTING                   107
-#define SND_SHIELD_NORMAL_ACTIVE                               108
+#define SND_SHIELD_NORMAL_ACTIVE                       108
 #define SND_SHIELD_DEADLY_COLLECTING                   109
-#define SND_SHIELD_DEADLY_ACTIVE                               110
-#define SND_EXTRA_TIME_COLLECTING                              111
+#define SND_SHIELD_DEADLY_ACTIVE                       110
+#define SND_EXTRA_TIME_COLLECTING                      111
 #define SND_MOLE_MOVING                                        112
-#define SND_MOLE_WAITING                                       113
-#define SND_MOLE_DIGGING                                       114
-#define SND_CLASS_SWITCHGATE_SWITCH_ACTIVATING                 115
-#define SND_CLASS_SWITCHGATE_OPENING                           116
-#define SND_CLASS_SWITCHGATE_CLOSING                           117
-#define SND_CLASS_SWITCHGATE_PASSING                           118
+#define SND_MOLE_WAITING                               113
+#define SND_MOLE_DIGGING                               114
+#define SND_CLASS_SWITCHGATE_SWITCH_ACTIVATING         115
+#define SND_CLASS_SWITCHGATE_OPENING                   116
+#define SND_CLASS_SWITCHGATE_CLOSING                   117
+#define SND_CLASS_SWITCHGATE_PASSING                   118
 #define SND_TIMEGATE_SWITCH_ACTIVATING                 119
-#define SND_TIMEGATE_SWITCH_ACTIVE                             120
-#define SND_TIMEGATE_SWITCH_DEACTIVATING                       121
+#define SND_TIMEGATE_SWITCH_ACTIVE                     120
+#define SND_TIMEGATE_SWITCH_DEACTIVATING               121
 #define SND_TIMEGATE_OPENING                           122
-#define SND_CLASS_TIMEGATE_CLOSING                             123
-#define SND_CLASS_TIMEGATE_PASSING                             124
-#define SND_CLASS_CONVEYOR_BELT_SWITCH_ACTIVATING              125
-#define SND_CLASS_CONVEYOR_BELT_ACTIVE                         126
-#define SND_CLASS_CONVEYOR_BELT_SWITCH_DEACTIVATING            127
-#define SND_LIGHT_SWITCH_ACTIVATING                            128
+#define SND_CLASS_TIMEGATE_CLOSING                     123
+#define SND_CLASS_TIMEGATE_PASSING                     124
+#define SND_CLASS_CONVEYOR_BELT_SWITCH_ACTIVATING      125
+#define SND_CLASS_CONVEYOR_BELT_ACTIVE                 126
+#define SND_CLASS_CONVEYOR_BELT_SWITCH_DEACTIVATING    127
+#define SND_LIGHT_SWITCH_ACTIVATING                    128
 #define SND_LIGHT_SWITCH_DEACTIVATING                  129
 #define SND_DX_SUPABOMB_PUSHING                                130
-#define SND_TRAP_DIGGING                                       131
-#define SND_TRAP_ACTIVATING                                    132
-#define SND_CLASS_TUBE_WALKING                                 133
-#define SND_AMOEBA_TURNING_TO_GEM                              134
-#define SND_AMOEBA_TURNING_TO_ROCK                             135
-#define SND_SPEED_PILL_COLLECTING                              136
+#define SND_TRAP_DIGGING                               131
+#define SND_TRAP_ACTIVATING                            132
+#define SND_CLASS_TUBE_WALKING                         133
+#define SND_AMOEBA_TURNING_TO_GEM                      134
+#define SND_AMOEBA_TURNING_TO_ROCK                     135
+#define SND_SPEED_PILL_COLLECTING                      136
 #define SND_DYNABOMB_INCREASE_NUMBER_COLLECTING                137
 #define SND_DYNABOMB_INCREASE_SIZE_COLLECTING          138
 #define SND_DYNABOMB_INCREASE_POWER_COLLECTING         139
-#define SND_CLASS_DYNABOMB_DROPPING                            140
-#define SND_CLASS_DYNABOMB_ACTIVE                              141
+#define SND_CLASS_DYNABOMB_DROPPING                    140
+#define SND_CLASS_DYNABOMB_ACTIVE                      141
 #define SND_SATELLITE_MOVING                           142
 #define SND_SATELLITE_WAITING                          143
 #define SND_SATELLITE_PUSHING                          144
-#define SND_LAMP_ACTIVATING                                    145
+#define SND_LAMP_ACTIVATING                            145
 #define SND_LAMP_DEACTIVATING                          146
 #define SND_TIME_ORB_FULL_COLLECTING                   147
-#define SND_TIME_ORB_FULL_IMPACT                               148
-#define SND_TIME_ORB_EMPTY_PUSHING                             149
-#define SND_TIME_ORB_EMPTY_IMPACT                              150
-#define SND_GAME_OF_LIFE_WAITING                               151
-#define SND_GAME_OF_LIFE_GROWING                               152
-#define SND_BIOMAZE_WAITING                                    153
-#define SND_BIOMAZE_GROWING                                    154
-#define SND_PACMAN_MOVING                                      155
-#define SND_PACMAN_WAITING                                     156
-#define SND_PACMAN_DIGGING                                     157
+#define SND_TIME_ORB_FULL_IMPACT                       148
+#define SND_TIME_ORB_EMPTY_PUSHING                     149
+#define SND_TIME_ORB_EMPTY_IMPACT                      150
+#define SND_GAME_OF_LIFE_WAITING                       151
+#define SND_GAME_OF_LIFE_GROWING                       152
+#define SND_BIOMAZE_WAITING                            153
+#define SND_BIOMAZE_GROWING                            154
+#define SND_PACMAN_MOVING                              155
+#define SND_PACMAN_WAITING                             156
+#define SND_PACMAN_DIGGING                             157
 #define SND_DARK_YAMYAM_MOVING                         158
 #define SND_DARK_YAMYAM_WAITING                                159
 #define SND_DARK_YAMYAM_DIGGING                                160
-#define SND_PENGUIN_MOVING                                     161
-#define SND_PENGUIN_WAITING                                    162
+#define SND_PENGUIN_MOVING                             161
+#define SND_PENGUIN_WAITING                            162
 #define SND_PIG_MOVING                                 163
 #define SND_PIG_WAITING                                        164
 #define SND_PIG_DIGGING                                        165
-#define SND_DRAGON_MOVING                                      166
-#define SND_DRAGON_WAITING                                     167
+#define SND_DRAGON_MOVING                              166
+#define SND_DRAGON_WAITING                             167
 #define SND_DRAGON_ATTACKING                           168
-#define SND_GAME_STARTING                                      169
+#define SND_GAME_STARTING                              169
 #define SND_GAME_RUNNING_OUT_OF_TIME                   170
-#define SND_GAME_LEVELTIME_BONUS                               171
+#define SND_GAME_LEVELTIME_BONUS                       171
 #define SND_GAME_LOSING                                        172
-#define SND_GAME_WINNING                                       173
-#define SND_GAME_SOKOBAN_SOLVING                               174
-#define SND_DOOR_OPENING                                       175
-#define SND_DOOR_CLOSING                                       176
-#define SND_BACKGROUND_SCORES                          177
-#define SND_BACKGROUND_INFO                                    178
+#define SND_GAME_WINNING                               173
+#define SND_GAME_SOKOBAN_SOLVING                       174
+#define SND_DOOR_OPENING                               175
+#define SND_DOOR_CLOSING                               176
+#define SND_BACKGROUND_MAIN                            177
+#define SND_BACKGROUND_LEVELS                          178
+#define SND_BACKGROUND_SCORES                          179
+#define SND_BACKGROUND_EDITOR                          180
+#define SND_BACKGROUND_INFO                            181
+#define SND_BACKGROUND_SETUP                           182
 
-#define NUM_SOUND_FILES                                179
+#define NUM_SOUND_FILES                                        183
 
 #endif /* CONF_SND_H */
index 47099876695f75946e30ffefdfd20c930f53d6d5..aa6bde03bf82d6520cfe0a15034915b27386b3de 100644 (file)
@@ -1 +1 @@
-#define COMPILE_DATE_STRING "[2003-11-09 23:35]"
+#define COMPILE_DATE_STRING "[2003-12-14 02:31]"
index 5c3298f84201a9e98daeaa1190e17a2500812152..9914b16f83b5a60a81f8ceb500e426bfec6b8b0a 100644 (file)
 #define ED_WIN_MB_RIGHT_YPOS           ED_WIN_MB_LEFT_YPOS
 
 /* values for the control window */
-#define ED_CTRL_BUTTONS_GFX_YPOS       236
-#define ED_CTRL_BUTTONS_ALT_GFX_YPOS   142
+#define ED_CTRL_NO_BUTTONS_GFX_XPOS    6
+#define ED_CTRL_NO_BUTTONS_GFX_YPOS    286
+#define ED_CTRL1_BUTTONS_GFX_YPOS      236
+#define ED_CTRL2_BUTTONS_GFX_YPOS      236
+#define ED_CTRL3_BUTTONS_GFX_YPOS      324
+#define ED_CTRL1_BUTTONS_ALT_GFX_YPOS  142
+#define ED_CTRL3_BUTTONS_ALT_GFX_YPOS  302
 
-#define ED_CTRL1_BUTTONS_HORIZ         4
-#define ED_CTRL1_BUTTONS_VERT          4
 #define ED_CTRL1_BUTTON_XSIZE          22
 #define ED_CTRL1_BUTTON_YSIZE          22
 #define ED_CTRL1_BUTTONS_XPOS          6
 #define ED_CTRL1_BUTTONS_YPOS          6
-#define ED_CTRL2_BUTTONS_HORIZ         3
-#define ED_CTRL2_BUTTONS_VERT          2
 #define ED_CTRL2_BUTTON_XSIZE          30
 #define ED_CTRL2_BUTTON_YSIZE          20
 #define ED_CTRL2_BUTTONS_XPOS          5
 #define ED_CTRL2_BUTTONS_YPOS          99
+#define ED_CTRL3_BUTTON_XSIZE          22
+#define ED_CTRL3_BUTTON_YSIZE          22
+#define ED_CTRL3_BUTTONS_XPOS          6
+#define ED_CTRL3_BUTTONS_YPOS          6
+
+#define ED_CTRL1_BUTTONS_HORIZ         4
+#define ED_CTRL1_BUTTONS_VERT          4
+#define ED_CTRL2_BUTTONS_HORIZ         3
+#define ED_CTRL2_BUTTONS_VERT          2
+#define ED_CTRL3_BUTTONS_HORIZ         3
+#define ED_CTRL3_BUTTONS_VERT          1
+
 #define ED_NUM_CTRL1_BUTTONS   (ED_CTRL1_BUTTONS_HORIZ * ED_CTRL1_BUTTONS_VERT)
 #define ED_NUM_CTRL2_BUTTONS   (ED_CTRL2_BUTTONS_HORIZ * ED_CTRL2_BUTTONS_VERT)
-#define ED_NUM_CTRL_BUTTONS    (ED_NUM_CTRL1_BUTTONS + ED_NUM_CTRL2_BUTTONS)
+#define ED_NUM_CTRL3_BUTTONS   (ED_CTRL3_BUTTONS_HORIZ * ED_CTRL3_BUTTONS_VERT)
+#define ED_NUM_CTRL1_2_BUTTONS (ED_NUM_CTRL1_BUTTONS + ED_NUM_CTRL2_BUTTONS)
+#define ED_NUM_CTRL_BUTTONS    (ED_NUM_CTRL1_BUTTONS + \
+                               ED_NUM_CTRL2_BUTTONS + \
+                               ED_NUM_CTRL3_BUTTONS)
 
 /* values for the element list */
 #define ED_ELEMENTLIST_XPOS            5
 #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_TEST                 (GADGET_ID_TOOLBOX_FIRST + 20)
 #define GADGET_ID_EXIT                 (GADGET_ID_TOOLBOX_FIRST + 21)
 
+#define GADGET_ID_CUSTOM_COPY_FROM     (GADGET_ID_TOOLBOX_FIRST + 22)
+#define GADGET_ID_CUSTOM_COPY_TO       (GADGET_ID_TOOLBOX_FIRST + 23)
+#define GADGET_ID_CUSTOM_EXCHANGE      (GADGET_ID_TOOLBOX_FIRST + 24)
+
 /* counter button identifiers */
-#define GADGET_ID_COUNTER_FIRST                (GADGET_ID_TOOLBOX_FIRST + 22)
+#define GADGET_ID_COUNTER_FIRST                (GADGET_ID_TOOLBOX_FIRST + 25)
 
 #define GADGET_ID_SELECT_LEVEL_DOWN    (GADGET_ID_COUNTER_FIRST + 0)
 #define GADGET_ID_SELECT_LEVEL_TEXT    (GADGET_ID_COUNTER_FIRST + 1)
@@ -736,28 +758,33 @@ 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"                     },
+
+  { '\0',      "copy settings from other element"      },
+  { '\0',      "copy settings to other element"        },
+  { '\0',      "exchange settings with other element"  },
 };
 
 static int random_placement_value = 10;
@@ -1044,6 +1071,10 @@ static struct ValueTextInfo options_move_pattern[] =
   { MV_TURNING_LEFT,           "turning left"                  },
   { MV_TURNING_RIGHT,          "turning right"                 },
   { MV_WHEN_PUSHED,            "when pushed"                   },
+#if 0
+  { MV_MAZE_RUNNER,            "maze runner style"             },
+  { MV_MAZE_HUNTER,            "maze hunter style"             },
+#endif
   { -1,                                NULL                            }
 };
 
@@ -1119,9 +1150,14 @@ static struct ValueTextInfo options_change_direct_action[] =
   { CE_LEFT_BY_PLAYER,         "left by player ..."            },
   { CE_DROPPED_BY_PLAYER,      "dropped by player"             },
   { CE_SWITCHED,               "switched ..."                  },
-  { CE_COLLISION,              "collision ..."                 },
-  { CE_IMPACT,                 "impact"                        },
-  { CE_SMASHED,                        "smashed"                       },
+#if 0
+  { CE_COLLISION_ACTIVE,       "hitting something ..."         },
+  { CE_COLLISION_PASSIVE,      "hit by something ..."          },
+#else
+  { CE_COLLISION_ACTIVE,       "collision ..."                 },
+#endif
+  { CE_IMPACT,                 "impact (on something)"         },
+  { CE_SMASHED,                        "smashed (from above)"          },
   { -1,                                NULL                            }
 };
 
@@ -1136,6 +1172,10 @@ static struct ValueTextInfo options_change_other_action[] =
   { CE_OTHER_GETS_COLLECTED,   "player collects"               },
   { CE_OTHER_GETS_DROPPED,     "player drops"                  },
   { CE_OTHER_IS_TOUCHING,      "touching ..."                  },
+#if 0
+  { CE_OTHER_IS_COLL_ACTIVE,   "hitting ..."                   },
+  { CE_OTHER_IS_COLL_PASSIVE,  "hit by ..."                    },
+#endif
   { CE_OTHER_IS_SWITCHING,     "switch of ..."                 },
   { CE_OTHER_IS_CHANGING,      "change of"                     },
   { CE_OTHER_IS_EXPLODING,     "explosion of"                  },
@@ -1150,7 +1190,7 @@ static struct ValueTextInfo options_change_sides[] =
   { CH_SIDE_BOTTOM,            "bottom side"                   },
   { CH_SIDE_LEFT_RIGHT,                "left/right side"               },
   { CH_SIDE_TOP_BOTTOM,                "top/bottom side"               },
-  { CH_SIDE_ANY,               "all sides"                     },
+  { CH_SIDE_ANY,               "any side"                      },
   { -1,                                NULL                            }
 };
 
@@ -1845,6 +1885,7 @@ static void RedrawDrawingElements();
 static void DrawDrawingWindow();
 static void DrawLevelInfoWindow();
 static void DrawPropertiesWindow();
+static void UpdateCustomElementGraphicGadgets();
 static boolean checkPropertiesConfig();
 static void CopyLevelToUndoBuffer(int);
 static void HandleDrawingAreas(struct GadgetInfo *);
@@ -1922,6 +1963,8 @@ static int editor_el_boulderdash[] =
   EL_BD_FIREFLY_DOWN,
   EL_EMPTY,
 };
+static int *editor_hl_boulderdash_ptr = editor_hl_boulderdash;
+static int *editor_el_boulderdash_ptr = editor_el_boulderdash;
 static int num_editor_hl_boulderdash = SIZEOF_ARRAY_INT(editor_hl_boulderdash);
 static int num_editor_el_boulderdash = SIZEOF_ARRAY_INT(editor_el_boulderdash);
 
@@ -2027,6 +2070,8 @@ static int editor_el_emerald_mine[] =
   EL_EM_GATE_3_GRAY,
   EL_EM_GATE_4_GRAY,
 };
+static int *editor_hl_emerald_mine_ptr = editor_hl_emerald_mine;
+static int *editor_el_emerald_mine_ptr = editor_el_emerald_mine;
 static int num_editor_hl_emerald_mine=SIZEOF_ARRAY_INT(editor_hl_emerald_mine);
 static int num_editor_el_emerald_mine=SIZEOF_ARRAY_INT(editor_el_emerald_mine);
 
@@ -2101,7 +2146,11 @@ static int editor_el_more[] =
   EL_BD_FIREFLY,
 
   EL_MOLE_LEFT,
+#if 0
+  EL_MAZE_RUNNER,
+#else
   EL_EMPTY,
+#endif
   EL_MOLE_RIGHT,
   EL_PACMAN,
 
@@ -2135,6 +2184,8 @@ static int editor_el_more[] =
   EL_EMC_WALL_6,
   EL_EMC_WALL_7,
 };
+static int *editor_hl_more_ptr = editor_hl_more;
+static int *editor_el_more_ptr = editor_el_more;
 static int num_editor_hl_more = SIZEOF_ARRAY_INT(editor_hl_more);
 static int num_editor_el_more = SIZEOF_ARRAY_INT(editor_el_more);
 
@@ -2158,6 +2209,8 @@ static int editor_el_sokoban[] =
   EL_SOKOBAN_FIELD_FULL,
   EL_STEELWALL,
 };
+static int *editor_hl_sokoban_ptr = editor_hl_sokoban;
+static int *editor_el_sokoban_ptr = editor_el_sokoban;
 static int num_editor_hl_sokoban = SIZEOF_ARRAY_INT(editor_hl_sokoban);
 static int num_editor_el_sokoban = SIZEOF_ARRAY_INT(editor_el_sokoban);
 
@@ -2230,6 +2283,8 @@ static int editor_el_supaplex[] =
   EL_SP_CHIP_TOP,
   EL_SP_CHIP_BOTTOM,
 };
+static int *editor_hl_supaplex_ptr = editor_hl_supaplex;
+static int *editor_el_supaplex_ptr = editor_el_supaplex;
 static int num_editor_hl_supaplex = SIZEOF_ARRAY_INT(editor_hl_supaplex);
 static int num_editor_el_supaplex = SIZEOF_ARRAY_INT(editor_el_supaplex);
 
@@ -2323,6 +2378,8 @@ static int editor_el_diamond_caves[] =
   EL_EXTRA_TIME,
   EL_EMPTY,
 };
+static int *editor_hl_diamond_caves_ptr = editor_hl_diamond_caves;
+static int *editor_el_diamond_caves_ptr = editor_el_diamond_caves;
 static int num_editor_hl_diamond_caves = SIZEOF_ARRAY_INT(editor_hl_diamond_caves);
 static int num_editor_el_diamond_caves = SIZEOF_ARRAY_INT(editor_el_diamond_caves);
 
@@ -2371,6 +2428,8 @@ static int editor_el_dx_boulderdash[] =
   EL_EMPTY,
   EL_EMPTY
 };
+static int *editor_hl_dx_boulderdash_ptr = editor_hl_dx_boulderdash;
+static int *editor_el_dx_boulderdash_ptr = editor_el_dx_boulderdash;
 static int num_editor_hl_dx_boulderdash = SIZEOF_ARRAY_INT(editor_hl_dx_boulderdash);
 static int num_editor_el_dx_boulderdash = SIZEOF_ARRAY_INT(editor_el_dx_boulderdash);
 
@@ -2474,6 +2533,8 @@ static int editor_el_chars[] =
   EL_CHAR(FONT_ASCII_CURSOR),
   EL_CHAR(' ')
 };
+static int *editor_hl_chars_ptr = editor_hl_chars;
+static int *editor_el_chars_ptr = editor_el_chars;
 static int num_editor_hl_chars = SIZEOF_ARRAY_INT(editor_hl_chars);
 static int num_editor_el_chars = SIZEOF_ARRAY_INT(editor_el_chars);
 
@@ -2662,6 +2723,8 @@ static int editor_el_custom[] =
   EL_CUSTOM_START + 126,
   EL_CUSTOM_START + 127
 };
+static int *editor_hl_custom_ptr = editor_hl_custom;
+static int *editor_el_custom_ptr = editor_el_custom;
 static int num_editor_hl_custom = SIZEOF_ARRAY_INT(editor_hl_custom);
 static int num_editor_el_custom = SIZEOF_ARRAY_INT(editor_el_custom);
 
@@ -2831,9 +2894,44 @@ static int editor_el_custom_more[] =
   EL_CUSTOM_START + 254,
   EL_CUSTOM_START + 255
 };
+static int *editor_hl_custom_more_ptr = editor_hl_custom_more;
+static int *editor_el_custom_more_ptr = editor_el_custom_more;
 static int num_editor_hl_custom_more = SIZEOF_ARRAY_INT(editor_hl_custom_more);
 static int num_editor_el_custom_more = SIZEOF_ARRAY_INT(editor_el_custom_more);
 
+static int editor_hl_user_defined[] =
+{
+  EL_CHAR('U'),
+  EL_CHAR('S'),
+  EL_CHAR('E'),
+  EL_CHAR('R'),
+
+  EL_CHAR('D'),
+  EL_CHAR('E'),
+  EL_CHAR('F'),
+  EL_CHAR('I'),
+
+  EL_CHAR('-'),
+  EL_CHAR('N'),
+  EL_CHAR('E'),
+  EL_CHAR('D'),
+};
+
+static int *editor_hl_user_defined_ptr = editor_hl_user_defined;
+static int *editor_el_user_defined_ptr = NULL;
+static int num_editor_hl_user_defined=SIZEOF_ARRAY_INT(editor_hl_user_defined);
+static int num_editor_el_user_defined = 0;
+
+static int editor_hl_empty[] = { };
+static int editor_el_empty[ED_NUM_ELEMENTLIST_BUTTONS];
+
+static int *editor_hl_empty_ptr = editor_hl_empty;
+static int *editor_el_empty_ptr = editor_el_empty;
+static int num_editor_hl_empty = 0;
+static int num_editor_el_empty = 0;    /* dynamically determined, if needed */
+
+static boolean use_el_empty = FALSE;
+
 static int *editor_elements = NULL;    /* dynamically allocated */
 static int num_editor_elements = 0;    /* dynamically determined */
 
@@ -2841,10 +2939,10 @@ static struct
 {
   boolean *setup_value;
 
-  int *headline_list;
+  int **headline_list;
   int *headline_list_size;
 
-  int *element_list;
+  int **element_list;
   int *element_list_size;
 
   boolean last_setup_value;
@@ -2853,53 +2951,63 @@ editor_elements_info[] =
 {
   {
     &setup.editor.el_boulderdash,
-    editor_hl_boulderdash,             &num_editor_hl_boulderdash,
-    editor_el_boulderdash,             &num_editor_el_boulderdash
+    &editor_hl_boulderdash_ptr,                &num_editor_hl_boulderdash,
+    &editor_el_boulderdash_ptr,                &num_editor_el_boulderdash
   },
   {
     &setup.editor.el_emerald_mine,
-    editor_hl_emerald_mine,            &num_editor_hl_emerald_mine,
-    editor_el_emerald_mine,            &num_editor_el_emerald_mine
+    &editor_hl_emerald_mine_ptr,       &num_editor_hl_emerald_mine,
+    &editor_el_emerald_mine_ptr,       &num_editor_el_emerald_mine
   },
   {
     &setup.editor.el_more,
-    editor_hl_more,                    &num_editor_hl_more,
-    editor_el_more,                    &num_editor_el_more
+    &editor_hl_more_ptr,               &num_editor_hl_more,
+    &editor_el_more_ptr,               &num_editor_el_more
   },
   {
     &setup.editor.el_sokoban,
-    editor_hl_sokoban,                 &num_editor_hl_sokoban,
-    editor_el_sokoban,                 &num_editor_el_sokoban
+    &editor_hl_sokoban_ptr,            &num_editor_hl_sokoban,
+    &editor_el_sokoban_ptr,            &num_editor_el_sokoban
   },
   {
     &setup.editor.el_supaplex,
-    editor_hl_supaplex,                        &num_editor_hl_supaplex,
-    editor_el_supaplex,                        &num_editor_el_supaplex
+    &editor_hl_supaplex_ptr,           &num_editor_hl_supaplex,
+    &editor_el_supaplex_ptr,           &num_editor_el_supaplex
   },
   {
     &setup.editor.el_diamond_caves,
-    editor_hl_diamond_caves,           &num_editor_hl_diamond_caves,
-    editor_el_diamond_caves,           &num_editor_el_diamond_caves
+    &editor_hl_diamond_caves_ptr,      &num_editor_hl_diamond_caves,
+    &editor_el_diamond_caves_ptr,      &num_editor_el_diamond_caves
   },
   {
     &setup.editor.el_dx_boulderdash,
-    editor_hl_dx_boulderdash,          &num_editor_hl_dx_boulderdash,
-    editor_el_dx_boulderdash,          &num_editor_el_dx_boulderdash
+    &editor_hl_dx_boulderdash_ptr,     &num_editor_hl_dx_boulderdash,
+    &editor_el_dx_boulderdash_ptr,     &num_editor_el_dx_boulderdash
   },
   {
     &setup.editor.el_chars,
-    editor_hl_chars,                   &num_editor_hl_chars,
-    editor_el_chars,                   &num_editor_el_chars
+    &editor_hl_chars_ptr,              &num_editor_hl_chars,
+    &editor_el_chars_ptr,              &num_editor_el_chars
   },
   {
     &setup.editor.el_custom,
-    editor_hl_custom,                  &num_editor_hl_custom,
-    editor_el_custom,                  &num_editor_el_custom
+    &editor_hl_custom_ptr,             &num_editor_hl_custom,
+    &editor_el_custom_ptr,             &num_editor_el_custom
   },
   {
     &setup.editor.el_custom_more,
-    editor_hl_custom_more,             &num_editor_hl_custom_more,
-    editor_el_custom_more,             &num_editor_el_custom_more
+    &editor_hl_custom_more_ptr,                &num_editor_hl_custom_more,
+    &editor_el_custom_more_ptr,                &num_editor_el_custom_more
+  },
+  {
+    &setup.editor.el_user_defined,
+    &editor_hl_user_defined_ptr,       &num_editor_hl_user_defined,
+    &editor_el_user_defined_ptr,       &num_editor_el_user_defined
+  },
+  {
+    &use_el_empty,
+    &editor_hl_empty_ptr,              &num_editor_hl_empty,
+    &editor_el_empty_ptr,              &num_editor_el_empty,
   },
   {
     NULL,
@@ -2967,17 +3075,24 @@ static void ReinitializeElementList()
   int pos = 0;
   int i, j;
 
-  if (editor_elements != NULL)
-    free(editor_elements);
+  checked_free(editor_elements);
 
-  /* do some sanity check for each element from element list at startup */
   if (!initialized)
   {
-    for (i=0; editor_elements_info[i].setup_value != NULL; i++)
+    /* initialize optional user defined element list */
+    LoadUserDefinedEditorElementList(&editor_el_user_defined_ptr,
+                                    &num_editor_el_user_defined);
+
+    /* initialize list of empty elements (used for padding, if needed) */
+    for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++)
+      editor_el_empty[i] = EL_EMPTY;
+
+    /* do some sanity checks for each element from element list */
+    for (i = 0; editor_elements_info[i].setup_value != NULL; i++)
     {
-      for (j=0; j < *editor_elements_info[i].element_list_size; j++)
+      for (j = 0; j < *editor_elements_info[i].element_list_size; j++)
       {
-       int element = editor_elements_info[i].element_list[j];
+       int element = (*editor_elements_info[i].element_list)[j];
 
        if (element >= NUM_FILE_ELEMENTS)
          Error(ERR_WARN, "editor element %d is runtime element", element);
@@ -2991,9 +3106,10 @@ static void ReinitializeElementList()
   }
 
   num_editor_elements = 0;
+  use_el_empty = FALSE;
 
   /* determine size of element list */
-  for (i=0; editor_elements_info[i].setup_value != NULL; i++)
+  for (i = 0; editor_elements_info[i].setup_value != NULL; i++)
   {
     if (*editor_elements_info[i].setup_value)
     {
@@ -3006,26 +3122,26 @@ static void ReinitializeElementList()
 
   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 */
+    /* offer at least as many elements as element buttons exist */
+    use_el_empty = TRUE;
+    num_editor_el_empty = ED_NUM_ELEMENTLIST_BUTTONS - num_editor_elements;
 
-    *editor_elements_info[list_nr].setup_value = TRUE;
-    num_editor_elements += *editor_elements_info[list_nr].element_list_size;
+    num_editor_elements += num_editor_el_empty;
   }
 
   editor_elements = checked_malloc(num_editor_elements * sizeof(int));
 
   /* fill element list */
-  for (i=0; editor_elements_info[i].setup_value != NULL; i++)
+  for (i = 0; editor_elements_info[i].setup_value != NULL; i++)
   {
     if (*editor_elements_info[i].setup_value)
     {
       if (setup.editor.el_headlines)
-       for (j=0; j < *editor_elements_info[i].headline_list_size; j++)
-         editor_elements[pos++] = editor_elements_info[i].headline_list[j];
+       for (j = 0; j < *editor_elements_info[i].headline_list_size; j++)
+         editor_elements[pos++] = (*editor_elements_info[i].headline_list)[j];
 
-      for (j=0; j < *editor_elements_info[i].element_list_size; j++)
-       editor_elements[pos++] = editor_elements_info[i].element_list[j];
+      for (j = 0; j < *editor_elements_info[i].element_list_size; j++)
+       editor_elements[pos++] = (*editor_elements_info[i].element_list)[j];
     }
   }
 
@@ -3036,6 +3152,35 @@ static void ReinitializeElementList()
     element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS;
 }
 
+void PrintEditorElementList()
+{
+  boolean *stop = &setup.editor.el_user_defined;
+  int i, j;
+
+  for (i = 0; editor_elements_info[i].setup_value != stop; i++)
+  {
+    for (j = 0; j < *editor_elements_info[i].headline_list_size; j++)
+    {
+      int element = (*editor_elements_info[i].headline_list)[j];
+
+      printf("# %s\n", element_info[element].token_name);
+    }
+
+    if (j > 0)
+      printf("#\n");
+
+    for (j = 0; j < *editor_elements_info[i].element_list_size; j++)
+    {
+      int element = (*editor_elements_info[i].element_list)[j];
+
+      printf("# %s\n", element_info[element].token_name);
+    }
+
+    if (j > 0)
+      printf("#\n");
+  }
+}
+
 static void ReinitializeElementListButtons()
 {
   static boolean last_setup_value_headlines = FALSE;
@@ -3047,7 +3192,7 @@ static void ReinitializeElementListButtons()
     if (last_setup_value_headlines != setup.editor.el_headlines)
       initialization_needed = TRUE;
 
-    for (i=0; editor_elements_info[i].setup_value != NULL; i++)
+    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;
@@ -3061,7 +3206,7 @@ static void ReinitializeElementListButtons()
 
   /* store current setup values for next invocation of this function */
   last_setup_value_headlines = setup.editor.el_headlines;
-  for (i=0; editor_elements_info[i].setup_value != NULL; i++)
+  for (i = 0; editor_elements_info[i].setup_value != NULL; i++)
     editor_elements_info[i].last_setup_value =
       *editor_elements_info[i].setup_value;
 
@@ -3081,8 +3226,8 @@ static void DrawElementBorder(int dest_x, int dest_y, int width, int height,
 
   getMiniGraphicSource(border_graphic, &src_bitmap, &src_x, &src_y);
 
-  for (y=0; y < num_mini_tiley; y++)
-    for (x=0; x < num_mini_tilex; x++)
+  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);
@@ -3104,8 +3249,8 @@ static void DrawDrawingArea(int id)
     DrawMiniGraphicExt(drawto, gi->x, gi->y,
                       el2edimg(custom_element.gfx_element));
   else if (id == ED_DRAWING_ID_CUSTOM_CONTENT)
-    for (y=0; y<3; y++)
-      for (x=0; x<3; x++)
+    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]));
@@ -3113,8 +3258,8 @@ static void DrawDrawingArea(int id)
     DrawMiniGraphicExt(drawto, gi->x, gi->y,
                       el2edimg(custom_element_change.target_element));
   else if (id == ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT)
-    for (y=0; y < 3; y++)
-      for (x=0; x < 3; x++)
+    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]));
@@ -3126,8 +3271,8 @@ static void DrawDrawingArea(int id)
   {
     int nr = id - ED_DRAWING_ID_ELEMENT_CONTENT_0;
 
-    for (y=0; y < 3; y++)
-      for (x=0; x < 3; x++)
+    for (y = 0; y < 3; y++)
+      for (x = 0; x < 3; x++)
        DrawMiniGraphicExt(drawto,
                           gi->x + x * MINI_TILEX, gi->y + y * MINI_TILEY,
                           el2edimg(level.yamyam_content[nr][x][y]));
@@ -3150,13 +3295,13 @@ static void ScrollMiniLevel(int from_x, int from_y, int scroll)
   if (dx)
   {
     x = (dx == 1 ? 0 : ed_fieldx - 1);
-    for(y=0; y<ed_fieldy; y++)
+    for (y = 0; y < ed_fieldy; y++)
       DrawMiniElementOrWall(x, y, from_x, from_y);
   }
   else if (dy)
   {
     y = (dy == 1 ? 0 : ed_fieldy - 1);
-    for(x=0; x<ed_fieldx; x++)
+    for (x = 0; x < ed_fieldx; x++)
       DrawMiniElementOrWall(x, y, from_x, from_y);
   }
 
@@ -3172,7 +3317,7 @@ static void CreateControlButtons()
   int i;
 
   /* create toolbox buttons */
-  for (i=0; i<ED_NUM_CTRL_BUTTONS; i++)
+  for (i = 0; i < ED_NUM_CTRL_BUTTONS; i++)
   {
     int id = i;
     int width, height;
@@ -3191,7 +3336,10 @@ static void CreateControlButtons()
        id == GADGET_ID_FILLED_BOX ||
        id == GADGET_ID_FLOOD_FILL ||
        id == GADGET_ID_GRAB_BRUSH ||
-       id == GADGET_ID_PICK_ELEMENT)
+       id == GADGET_ID_PICK_ELEMENT ||
+       id == GADGET_ID_CUSTOM_COPY_FROM ||
+       id == GADGET_ID_CUSTOM_COPY_TO ||
+       id == GADGET_ID_CUSTOM_EXCHANGE)
     {
       button_type = GD_TYPE_RADIO_BUTTON;
       radio_button_nr = RADIO_NR_DRAWING_TOOLBOX;
@@ -3222,8 +3370,13 @@ static void CreateControlButtons()
       gd_yoffset = ED_CTRL1_BUTTONS_YPOS + y * ED_CTRL1_BUTTON_YSIZE;
       width = ED_CTRL1_BUTTON_XSIZE;
       height = ED_CTRL1_BUTTON_YSIZE;
+
+      gd_x1 = DOOR_GFX_PAGEX8 + gd_xoffset;
+      gd_x2 = DOOR_GFX_PAGEX7 + gd_xoffset;
+      gd_y1 = DOOR_GFX_PAGEY1 + ED_CTRL1_BUTTONS_GFX_YPOS     + gd_yoffset;
+      gd_y2 = DOOR_GFX_PAGEY1 + ED_CTRL1_BUTTONS_ALT_GFX_YPOS + gd_yoffset;
     }
-    else
+    else if (id < ED_NUM_CTRL1_2_BUTTONS)
     {
       int x = (i - ED_NUM_CTRL1_BUTTONS) % ED_CTRL2_BUTTONS_HORIZ;
       int y = (i - ED_NUM_CTRL1_BUTTONS) / ED_CTRL2_BUTTONS_HORIZ;
@@ -3232,12 +3385,27 @@ static void CreateControlButtons()
       gd_yoffset = ED_CTRL2_BUTTONS_YPOS + y * ED_CTRL2_BUTTON_YSIZE;
       width = ED_CTRL2_BUTTON_XSIZE;
       height = ED_CTRL2_BUTTON_YSIZE;
-    }
 
-    gd_x1 = DOOR_GFX_PAGEX8 + gd_xoffset;
-    gd_x2 = DOOR_GFX_PAGEX7 + gd_xoffset;
-    gd_y1  = DOOR_GFX_PAGEY1 + ED_CTRL_BUTTONS_GFX_YPOS + gd_yoffset;
-    gd_y2  = DOOR_GFX_PAGEY1 + ED_CTRL_BUTTONS_ALT_GFX_YPOS + gd_yoffset;
+      gd_x1 = DOOR_GFX_PAGEX8 + gd_xoffset;
+      gd_x2 = DOOR_GFX_PAGEX7 + gd_xoffset;
+      gd_y1 = DOOR_GFX_PAGEY1 + ED_CTRL2_BUTTONS_GFX_YPOS + gd_yoffset;
+      gd_y2 = 0;       /* no alternative graphic for these buttons */
+    }
+    else
+    {
+      int x = (i - ED_NUM_CTRL1_2_BUTTONS) % ED_CTRL3_BUTTONS_HORIZ + 1;
+      int y = (i - ED_NUM_CTRL1_2_BUTTONS) / ED_CTRL3_BUTTONS_HORIZ;
+
+      gd_xoffset = ED_CTRL3_BUTTONS_XPOS + x * ED_CTRL3_BUTTON_XSIZE;
+      gd_yoffset = ED_CTRL3_BUTTONS_YPOS + y * ED_CTRL3_BUTTON_YSIZE;
+      width = ED_CTRL3_BUTTON_XSIZE;
+      height = ED_CTRL3_BUTTON_YSIZE;
+
+      gd_x1 = DOOR_GFX_PAGEX6 + gd_xoffset;
+      gd_x2 = DOOR_GFX_PAGEX5 + gd_xoffset;
+      gd_y1 = DOOR_GFX_PAGEY1 + ED_CTRL3_BUTTONS_GFX_YPOS     + gd_yoffset;
+      gd_y2 = DOOR_GFX_PAGEY1 + ED_CTRL3_BUTTONS_ALT_GFX_YPOS + gd_yoffset;
+    }
 
     gi = CreateGadget(GDI_CUSTOM_ID, id,
                      GDI_CUSTOM_TYPE_ID, i,
@@ -3266,7 +3434,7 @@ static void CreateControlButtons()
   }
 
   /* create buttons for scrolling of drawing area and element list */
-  for (i=0; i<ED_NUM_SCROLLBUTTONS; i++)
+  for (i = 0; i < ED_NUM_SCROLLBUTTONS; i++)
   {
     int id = scrollbutton_info[i].gadget_id;
     int x, y, width, height;
@@ -3324,7 +3492,7 @@ static void CreateControlButtons()
   }
 
   /* create buttons for element list */
-  for (i=0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++)
+  for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++)
   {
     Bitmap *deco_bitmap;
     int deco_x, deco_y, deco_xpos, deco_ypos;
@@ -3380,7 +3548,7 @@ static void CreateCounterButtons()
   int max_infotext_len = getMaxInfoTextLength();
   int i;
 
-  for (i=0; i<ED_NUM_COUNTERBUTTONS; i++)
+  for (i = 0; i < ED_NUM_COUNTERBUTTONS; i++)
   {
     int j;
     int x = SX + counterbutton_info[i].x;      /* down count button */
@@ -3395,7 +3563,7 @@ static void CreateCounterButtons()
     if (counterbutton_info[i].text_left != NULL)
       x += getTextWidthForGadget(counterbutton_info[i].text_left);
 
-    for (j=0; j<2; j++)
+    for (j = 0; j < 2; j++)
     {
       Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
       struct GadgetInfo *gi;
@@ -3531,7 +3699,7 @@ static void CreateDrawingAreas()
 {
   int i;
 
-  for (i=0; i<ED_NUM_DRAWING_AREAS; i++)
+  for (i = 0; i < ED_NUM_DRAWING_AREAS; i++)
   {
     struct GadgetInfo *gi;
     unsigned long event_mask;
@@ -3580,7 +3748,7 @@ static void CreateTextInputGadgets()
   int max_infotext_len = getMaxInfoTextLength();
   int i;
 
-  for (i=0; i<ED_NUM_TEXTINPUT; i++)
+  for (i = 0; i < ED_NUM_TEXTINPUT; i++)
   {
     Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
     int gd_x, gd_y;
@@ -3628,7 +3796,7 @@ static void CreateTextAreaGadgets()
   int max_infotext_len = getMaxInfoTextLength();
   int i;
 
-  for (i=0; i<ED_NUM_TEXTAREAS; i++)
+  for (i = 0; i < ED_NUM_TEXTAREAS; i++)
   {
     Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
     int gd_x, gd_y;
@@ -3677,7 +3845,7 @@ static void CreateSelectboxGadgets()
   int max_infotext_len = getMaxInfoTextLength();
   int i, j;
 
-  for (i=0; i<ED_NUM_SELECTBOX; i++)
+  for (i = 0; i < ED_NUM_SELECTBOX; i++)
   {
     Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
     int gd_x, gd_y;
@@ -3695,7 +3863,7 @@ static void CreateSelectboxGadgets()
         implicitely cast -1 to an unsigned integer value!) */
       selectbox_info[i].size = 0;
 
-      for (j=0; selectbox_info[i].options[j].text != NULL; j++)
+      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);
 
@@ -3754,7 +3922,7 @@ static void CreateTextbuttonGadgets()
   int max_infotext_len = getMaxInfoTextLength();
   int i;
 
-  for (i=0; i<ED_NUM_TEXTBUTTONS; i++)
+  for (i = 0; i < ED_NUM_TEXTBUTTONS; i++)
   {
     Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
     int gd_x1, gd_x2, gd_y1, gd_y2;
@@ -3835,7 +4003,7 @@ static void CreateGraphicbuttonGadgets()
   int i;
 
   /* create buttons for scrolling of drawing area and element list */
-  for (i=0; i < ED_NUM_GRAPHICBUTTONS; i++)
+  for (i = 0; i < ED_NUM_GRAPHICBUTTONS; i++)
   {
     int id = graphicbutton_info[i].gadget_id;
     int gd_x1, gd_x2, gd_y1, gd_y2;
@@ -3887,7 +4055,7 @@ static void CreateScrollbarGadgets()
 {
   int i;
 
-  for (i=0; i<ED_NUM_SCROLLBARS; 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;
@@ -3969,7 +4137,7 @@ static void CreateCheckbuttonGadgets()
   gd_x4 = DOOR_GFX_PAGEX3 + ED_CHECKBUTTON_CHECKED_XPOS;
   gd_y  = DOOR_GFX_PAGEY1 + ED_RADIOBUTTON_YPOS;
 
-  for (i=0; i<ED_NUM_CHECKBUTTONS; i++)
+  for (i = 0; i < ED_NUM_CHECKBUTTONS; i++)
   {
     int id = checkbutton_info[i].gadget_id;
     int x = SX + checkbutton_info[i].x;
@@ -4032,7 +4200,7 @@ static void CreateRadiobuttonGadgets()
   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_RADIOBUTTONS; i++)
   {
     int id = radiobutton_info[i].gadget_id;
     int x = SX + radiobutton_info[i].x;
@@ -4108,7 +4276,7 @@ void FreeLevelEditorGadgets()
 {
   int i;
 
-  for (i=0; i<NUM_EDITOR_GADGETS; i++)
+  for (i = 0; i < NUM_EDITOR_GADGETS; i++)
     FreeGadget(level_editor_gadget[i]);
 }
 
@@ -4158,12 +4326,12 @@ static void MapControlButtons()
   int counter_id;
   int i;
 
-  /* map toolbox buttons */
-  for (i=0; i<ED_NUM_CTRL_BUTTONS; i++)
+  /* map toolbox buttons (excluding special CE toolbox buttons) */
+  for (i = 0; i < ED_NUM_CTRL1_2_BUTTONS; i++)
     MapGadget(level_editor_gadget[i]);
 
   /* map buttons to select elements */
-  for (i=0; i<ED_NUM_ELEMENTLIST_BUTTONS; i++)
+  for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++)
     MapGadget(level_editor_gadget[GADGET_ID_ELEMENTLIST_FIRST + i]);
   MapGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL]);
   MapGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_UP]);
@@ -4219,7 +4387,7 @@ static void MapTextInputGadget(int id)
   int y_above = textinput_info[id].y + yoffset_above;
 
   if (textinput_info[id].text_above)
-    DrawTextF(x_above, y_above, FONT_TEXT_1, textinput_info[id].text_above);
+    DrawTextS(x_above, y_above, FONT_TEXT_1, textinput_info[id].text_above);
 
   ModifyGadget(gi, GDI_TEXT_VALUE, textinput_info[id].value, GDI_END);
 
@@ -4235,7 +4403,7 @@ static void MapTextAreaGadget(int id)
   int y_above = textarea_info[id].y + yoffset_above;
 
   if (textarea_info[id].text_above)
-    DrawTextF(x_above, y_above, FONT_TEXT_1, textarea_info[id].text_above);
+    DrawTextS(x_above, y_above, FONT_TEXT_1, textarea_info[id].text_above);
 
   ModifyGadget(gi, GDI_TEXT_VALUE, textarea_info[id].value, GDI_END);
 
@@ -4359,7 +4527,7 @@ static void MapMainDrawingArea()
   boolean no_vertical_scrollbar = (lev_fieldy + 2 <= ed_fieldy);
   int i;
 
-  for (i=ED_SCROLLBUTTON_ID_AREA_FIRST; i<=ED_SCROLLBUTTON_ID_AREA_LAST; i++)
+  for (i=ED_SCROLLBUTTON_ID_AREA_FIRST; i <= ED_SCROLLBUTTON_ID_AREA_LAST; i++)
   {
     if (((i == ED_SCROLLBUTTON_ID_AREA_LEFT ||
          i == ED_SCROLLBUTTON_ID_AREA_RIGHT) &&
@@ -4372,7 +4540,7 @@ static void MapMainDrawingArea()
     MapGadget(level_editor_gadget[scrollbutton_info[i].gadget_id]);
   }
 
-  for (i=ED_SCROLLBAR_ID_AREA_FIRST; i<=ED_SCROLLBAR_ID_AREA_LAST; i++)
+  for (i = ED_SCROLLBAR_ID_AREA_FIRST; i <= ED_SCROLLBAR_ID_AREA_LAST; i++)
   {
     if ((i == ED_SCROLLBAR_ID_AREA_HORIZONTAL && no_horizontal_scrollbar) ||
        (i == ED_SCROLLBAR_ID_AREA_VERTICAL && no_vertical_scrollbar))
@@ -4384,16 +4552,84 @@ static void MapMainDrawingArea()
   MapDrawingArea(ED_DRAWING_ID_DRAWING_LEVEL);
 }
 
+static void MapOrUnmapLevelEditorToolboxCustomGadgets(boolean map)
+{
+  int i;
+
+  for (i = 0; i < ED_NUM_CTRL_BUTTONS; i++)
+  {
+    if (i == GADGET_ID_CUSTOM_COPY_FROM ||
+        i == GADGET_ID_CUSTOM_COPY_TO ||
+        i == GADGET_ID_CUSTOM_EXCHANGE)
+    {
+      if (map)
+       MapGadget(level_editor_gadget[i]);
+      else
+       UnmapGadget(level_editor_gadget[i]);
+    }
+  }
+}
+
+static void MapLevelEditorToolboxCustomGadgets()
+{
+  MapOrUnmapLevelEditorToolboxCustomGadgets(TRUE);
+}
+
+static void UnmapLevelEditorToolboxCustomGadgets()
+{
+  MapOrUnmapLevelEditorToolboxCustomGadgets(FALSE);
+}
+
+static void MapOrUnmapLevelEditorToolboxDrawingGadgets(boolean map)
+{
+  Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+  int i;
+
+  for (i = 0; i < ED_NUM_CTRL1_BUTTONS; i++)
+  {
+    if (i != GADGET_ID_SINGLE_ITEMS &&
+       i != GADGET_ID_PROPERTIES &&
+       i != GADGET_ID_PICK_ELEMENT)
+    {
+      struct GadgetInfo *gi = level_editor_gadget[i];
+
+      if (map)
+       MapGadget(gi);
+      else
+      {
+       UnmapGadget(gi);
+
+       BlitBitmap(gd_bitmap, drawto,
+                  DOOR_GFX_PAGEX6 + ED_CTRL_NO_BUTTONS_GFX_XPOS,
+                  DOOR_GFX_PAGEY1 + ED_CTRL_NO_BUTTONS_GFX_YPOS,
+                  gi->width, gi->height, gi->x, gi->y);
+
+       redraw_mask |= REDRAW_DOOR_3;
+      }
+    }
+  }
+}
+
+static void MapLevelEditorToolboxDrawingGadgets()
+{
+  MapOrUnmapLevelEditorToolboxDrawingGadgets(TRUE);
+}
+
+static void UnmapLevelEditorToolboxDrawingGadgets()
+{
+  MapOrUnmapLevelEditorToolboxDrawingGadgets(FALSE);
+}
+
 static void UnmapDrawingArea(int id)
 {
   UnmapGadget(level_editor_gadget[id]);
 }
 
-void UnmapLevelEditorWindowGadgets()
+static void UnmapLevelEditorWindowGadgets()
 {
   int i;
 
-  for (i=0; i<NUM_EDITOR_GADGETS; i++)
+  for (i = 0; i < NUM_EDITOR_GADGETS; i++)
     if (level_editor_gadget[i]->x < SX + SXSIZE)
       UnmapGadget(level_editor_gadget[i]);
 }
@@ -4402,7 +4638,7 @@ void UnmapLevelEditorGadgets()
 {
   int i;
 
-  for (i=0; i<NUM_EDITOR_GADGETS; i++)
+  for (i = 0; i < NUM_EDITOR_GADGETS; i++)
     UnmapGadget(level_editor_gadget[i]);
 }
 
@@ -4431,8 +4667,8 @@ static boolean LevelChanged()
   boolean level_changed = FALSE;
   int x, y;
 
-  for(y=0; y<lev_fieldy; y++) 
-    for(x=0; x<lev_fieldx; x++)
+  for (y = 0; y < lev_fieldy; y++) 
+    for (x = 0; x < lev_fieldx; x++)
       if (Feld[x][y] != level.field[x][y])
        level_changed = TRUE;
 
@@ -4444,8 +4680,8 @@ static boolean LevelContainsPlayer()
   boolean player_found = FALSE;
   int x, y;
 
-  for(y=0; y<lev_fieldy; y++) 
-    for(x=0; x<lev_fieldx; x++)
+  for (y = 0; y < lev_fieldy; y++) 
+    for (x = 0; x < lev_fieldx; x++)
       if (Feld[x][y] == EL_PLAYER_1 ||
          Feld[x][y] == EL_SP_MURPHY) 
        player_found = TRUE;
@@ -4458,8 +4694,8 @@ static void CopyPlayfield(short src[MAX_LEV_FIELDX][MAX_LEV_FIELDY],
 {
   int x, y;
 
-  for(x=0; x<lev_fieldx; x++)
-    for(y=0; y<lev_fieldy; y++) 
+  for (x = 0; x < lev_fieldx; x++)
+    for (y = 0; y < lev_fieldy; y++) 
       dst[x][y] = src[x][y];
 }
 
@@ -4468,7 +4704,7 @@ static int setSelectboxValue(int selectbox_id, int new_value)
   int new_index_value = 0;
   int i;
 
-  for(i=0; selectbox_info[selectbox_id].options[i].text != NULL; 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;
 
@@ -4478,13 +4714,164 @@ static int setSelectboxValue(int selectbox_id, int new_value)
   return new_index_value;
 }
 
+static void copy_custom_element_settings(int element_from, int element_to)
+{
+  struct ElementInfo *ei_from = &element_info[element_from];
+  struct ElementInfo *ei_to = &element_info[element_to];
+  int i, x, y;
+
+  /* ---------- copy element description ---------- */
+  for (i = 0; i < MAX_ELEMENT_NAME_LEN + 1; i++)
+    ei_to->description[i] = ei_from->description[i];
+
+  /* ---------- copy element properties ---------- */
+  Properties[element_to][EP_BITFIELD_BASE] =
+    Properties[element_from][EP_BITFIELD_BASE];
+
+  /* ---------- copy custom property values ---------- */
+
+  ei_to->use_gfx_element = ei_from->use_gfx_element;
+  ei_to->gfx_element = ei_from->gfx_element;
+
+  ei_to->collect_score = ei_from->collect_score;
+  ei_to->collect_count = ei_from->collect_count;
+
+  ei_to->push_delay_fixed = ei_from->push_delay_fixed;
+  ei_to->push_delay_random = ei_from->push_delay_random;
+  ei_to->move_delay_fixed = ei_from->move_delay_fixed;
+  ei_to->move_delay_random = ei_from->move_delay_random;
+
+  ei_to->move_pattern = ei_from->move_pattern;
+  ei_to->move_direction_initial = ei_from->move_direction_initial;
+  ei_to->move_stepsize = ei_from->move_stepsize;
+
+  ei_to->slippery_type = ei_from->slippery_type;
+
+  for (y = 0; y < 3; y++)
+    for (x = 0; x < 3; x++)
+      ei_to->content[x][y] = ei_from->content[x][y];
+
+  ei_to->num_change_pages = ei_from->num_change_pages;
+  setElementChangePages(ei_to, ei_to->num_change_pages);
+
+  for (i=0; i < ei_to->num_change_pages; i++)
+  {
+    struct ElementChangeInfo *change_to = &ei_to->change_page[i];
+    struct ElementChangeInfo *change_from = &ei_from->change_page[i];
+
+    /* always start with reliable default values */
+    setElementChangeInfoToDefaults(change_to);
+
+    change_to->events = change_from->events;
+
+    change_to->target_element = change_from->target_element;
+
+    change_to->delay_fixed = change_from->delay_fixed;
+    change_to->delay_random = change_from->delay_random;
+    change_to->delay_frames = change_from->delay_frames;
+
+    change_to->trigger_element = change_from->trigger_element;
+
+    change_to->explode = change_from->explode;
+    change_to->use_content = change_from->use_content;
+    change_to->only_complete = change_from->only_complete;
+    change_to->use_random_change = change_from->use_random_change;
+
+    change_to->random = change_from->random;
+    change_to->power = change_from->power;
+
+    for (y = 0; y < 3; y++)
+      for (x = 0; x < 3; x++)
+       change_to->content[x][y] = change_from->content[x][y];
+
+    change_to->can_change = change_from->can_change;
+
+    change_to->sides = change_from->sides;
+  }
+
+  /* mark this custom element as modified */
+  ei_to->modified_settings = TRUE;
+}
+
+static void replace_custom_element_in_settings(int element_from,
+                                              int element_to)
+{
+  int i, j, x, y;
+
+  for (i = 0; i < NUM_FILE_ELEMENTS; i++)
+  {
+    struct ElementInfo *ei = &element_info[i];
+
+    for (y = 0; y < 3; y++)
+      for (x = 0; x < 3; x++)
+       if (ei->content[x][y] == element_from)
+         ei->content[x][y] = element_to;
+
+    for (j=0; j < ei->num_change_pages; j++)
+    {
+      struct ElementChangeInfo *change = &ei->change_page[j];
+
+      if (change->target_element == element_from)
+       change->target_element = element_to;
+
+      if (change->trigger_element == element_from)
+       change->trigger_element = element_to;
+
+      for (y = 0; y < 3; y++)
+       for (x = 0; x < 3; x++)
+         if (change->content[x][y] == element_from)
+           change->content[x][y] = element_to;
+    }
+  }
+}
+
+static void replace_custom_element_in_playfield(int element_from,
+                                               int element_to)
+{
+  int x, y;
+
+  for (x = 0; x < lev_fieldx; x++)
+    for (y = 0; y < lev_fieldy; y++)
+      if (Feld[x][y] == element_from)
+       Feld[x][y] = element_to;
+}
+
+static void CopyCustomElement(int element_old, int element_new, int copy_mode)
+{
+  if (copy_mode == GADGET_ID_CUSTOM_COPY_FROM)
+  {
+    copy_custom_element_settings(element_new, element_old);
+  }
+  else if (copy_mode == GADGET_ID_CUSTOM_COPY_TO)
+  {
+    copy_custom_element_settings(element_old, element_new);
+  }
+  else if (copy_mode == GADGET_ID_CUSTOM_EXCHANGE)
+  {
+    copy_custom_element_settings(element_old, EL_DUMMY);
+    copy_custom_element_settings(element_new, element_old);
+    copy_custom_element_settings(EL_DUMMY, element_new);
+
+    replace_custom_element_in_settings(element_old, EL_DUMMY);
+    replace_custom_element_in_settings(element_new, element_old);
+    replace_custom_element_in_settings(EL_DUMMY, element_new);
+
+    replace_custom_element_in_playfield(element_old, EL_DUMMY);
+    replace_custom_element_in_playfield(element_new, element_old);
+    replace_custom_element_in_playfield(EL_DUMMY, element_new);
+  }
+
+  UpdateCustomElementGraphicGadgets();
+  DrawPropertiesWindow();
+}
+
 static void CopyCustomElementPropertiesToEditor(int element)
 {
   int i;
   int current_change_page = element_info[element].current_change_page;
 
   /* dynamically (re)build selectbox for selecting change page */
-  for (i=0; i < element_info[element].num_change_pages; i++)
+  for (i = 0; i < element_info[element].num_change_pages; i++)
   {
     sprintf(options_change_page_strings[i], "%d", i + 1);
 
@@ -4505,13 +4892,13 @@ static void CopyCustomElementPropertiesToEditor(int element)
   custom_element_change = *element_info[element].change;
 
   /* needed to initially set selectbox value variables to reliable defaults */
-  for (i=0; i < ED_NUM_SELECTBOX; i++)
+  for (i = 0; i < ED_NUM_SELECTBOX; i++)
     setSelectboxValue(i, *selectbox_info[i].value);
 
-  for (i=0; i < NUM_ELEMENT_PROPERTIES; i++)
+  for (i = 0; i < NUM_ELEMENT_PROPERTIES; i++)
     custom_element_properties[i] = HAS_PROPERTY(element, i);
 
-  for (i=0; i < NUM_CHANGE_EVENTS; i++)
+  for (i = 0; i < NUM_CHANGE_EVENTS; i++)
     custom_element_change_events[i] = HAS_CHANGE_EVENT(element, i);
 
   /* ---------- element settings: configure (custom elements) ------------- */
@@ -4596,7 +4983,8 @@ static void CopyCustomElementPropertiesToEditor(int element)
      HAS_CHANGE_EVENT(element, CE_LEFT_BY_PLAYER) ? CE_LEFT_BY_PLAYER :
      HAS_CHANGE_EVENT(element, CE_DROPPED_BY_PLAYER) ? CE_DROPPED_BY_PLAYER :
      HAS_CHANGE_EVENT(element, CE_SWITCHED) ? CE_SWITCHED :
-     HAS_CHANGE_EVENT(element, CE_COLLISION) ? CE_COLLISION :
+     HAS_CHANGE_EVENT(element, CE_COLLISION_ACTIVE) ? CE_COLLISION_ACTIVE :
+     HAS_CHANGE_EVENT(element, CE_COLLISION_PASSIVE) ? CE_COLLISION_PASSIVE :
      HAS_CHANGE_EVENT(element, CE_IMPACT) ? CE_IMPACT :
      HAS_CHANGE_EVENT(element, CE_SMASHED) ? CE_SMASHED :
      custom_element_change.direct_action);
@@ -4612,6 +5000,8 @@ static void CopyCustomElementPropertiesToEditor(int element)
      HAS_CHANGE_EVENT(element, CE_OTHER_GETS_COLLECTED) ? CE_OTHER_GETS_COLLECTED :
      HAS_CHANGE_EVENT(element, CE_OTHER_GETS_DROPPED) ? CE_OTHER_GETS_DROPPED :
      HAS_CHANGE_EVENT(element, CE_OTHER_IS_TOUCHING) ? CE_OTHER_IS_TOUCHING :
+     HAS_CHANGE_EVENT(element, CE_OTHER_IS_COLL_ACTIVE) ? CE_OTHER_IS_COLL_ACTIVE :
+     HAS_CHANGE_EVENT(element, CE_OTHER_IS_COLL_PASSIVE) ? CE_OTHER_IS_COLL_PASSIVE :
      HAS_CHANGE_EVENT(element, CE_OTHER_IS_SWITCHING) ? CE_OTHER_IS_SWITCHING :
      HAS_CHANGE_EVENT(element, CE_OTHER_IS_CHANGING) ? CE_OTHER_IS_CHANGING :
      HAS_CHANGE_EVENT(element, CE_OTHER_IS_EXPLODING) ? CE_OTHER_IS_EXPLODING :
@@ -4628,7 +5018,7 @@ static void CopyCustomElementPropertiesToGame(int element)
 
   if (level.use_custom_template)
   {
-    if (Request("Copy and modify level template ?", REQ_ASK))
+    if (Request("Copy and modify level template ?", REQ_ASK))
     {
       level.use_custom_template = FALSE;
       ModifyGadget(level_editor_gadget[GADGET_ID_CUSTOM_USE_TEMPLATE],
@@ -4714,7 +5104,8 @@ static void CopyCustomElementPropertiesToGame(int element)
   custom_element_change_events[CE_LEFT_BY_PLAYER] = FALSE;
   custom_element_change_events[CE_DROPPED_BY_PLAYER] = FALSE;
   custom_element_change_events[CE_SWITCHED] = FALSE;
-  custom_element_change_events[CE_COLLISION] = FALSE;
+  custom_element_change_events[CE_COLLISION_ACTIVE] = FALSE;
+  custom_element_change_events[CE_COLLISION_PASSIVE] = FALSE;
   custom_element_change_events[CE_IMPACT] = FALSE;
   custom_element_change_events[CE_SMASHED] = FALSE;
   custom_element_change_events[custom_element_change.direct_action] =
@@ -4730,16 +5121,18 @@ static void CopyCustomElementPropertiesToGame(int element)
   custom_element_change_events[CE_OTHER_GETS_COLLECTED] = FALSE;
   custom_element_change_events[CE_OTHER_GETS_DROPPED] = FALSE;
   custom_element_change_events[CE_OTHER_IS_TOUCHING] = FALSE;
+  custom_element_change_events[CE_OTHER_IS_COLL_ACTIVE] = FALSE;
+  custom_element_change_events[CE_OTHER_IS_COLL_PASSIVE] = FALSE;
   custom_element_change_events[CE_OTHER_IS_SWITCHING] = FALSE;
   custom_element_change_events[CE_OTHER_IS_CHANGING] = FALSE;
   custom_element_change_events[CE_OTHER_IS_EXPLODING] = FALSE;
   custom_element_change_events[custom_element_change.other_action] =
     custom_element_change_events[CE_BY_OTHER_ACTION];
 
-  for (i=0; i < NUM_ELEMENT_PROPERTIES; i++)
+  for (i = 0; i < NUM_ELEMENT_PROPERTIES; i++)
     SET_PROPERTY(element, i, custom_element_properties[i]);
 
-  for (i=0; i < NUM_CHANGE_EVENTS; 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 */
@@ -4942,7 +5335,7 @@ static void ModifyEditorElementList()
 {
   int i;
 
-  for (i=0; i<ED_NUM_ELEMENTLIST_BUTTONS; 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];
@@ -4999,7 +5392,9 @@ static void DrawDrawingWindow()
 
   SetMainBackgroundImage(IMG_UNDEFINED);
   ClearWindow();
+
   UnmapLevelEditorWindowGadgets();
+  UnmapLevelEditorToolboxCustomGadgets();
 
   AdjustDrawingAreaGadgets();
   AdjustLevelScrollPosition();
@@ -5007,7 +5402,9 @@ static void DrawDrawingWindow()
   AdjustEditorScrollbar(GADGET_ID_SCROLL_VERTICAL);
 
   DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
+
   MapMainDrawingArea();
+  MapLevelEditorToolboxDrawingGadgets();
 }
 
 static void DrawLevelInfoWindow()
@@ -5026,19 +5423,19 @@ static void DrawLevelInfoWindow()
           "Editor Settings", FONT_TITLE_1);
 
   /* draw counter gadgets */
-  for (i=ED_COUNTER_ID_LEVEL_FIRST; i<=ED_COUNTER_ID_LEVEL_LAST; i++)
+  for (i = ED_COUNTER_ID_LEVEL_FIRST; i <= ED_COUNTER_ID_LEVEL_LAST; i++)
     MapCounterButtons(i);
 
   /* draw checkbutton gadgets */
-  for (i=ED_CHECKBUTTON_ID_LEVEL_FIRST; i<=ED_CHECKBUTTON_ID_LEVEL_LAST; i++)
+  for (i=ED_CHECKBUTTON_ID_LEVEL_FIRST; i <= ED_CHECKBUTTON_ID_LEVEL_LAST; i++)
     MapCheckbuttonGadget(i);
 
   /* draw radiobutton gadgets */
-  for (i=ED_RADIOBUTTON_ID_LEVEL_FIRST; i<=ED_RADIOBUTTON_ID_LEVEL_LAST; i++)
+  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++)
+  for (i = ED_TEXTINPUT_ID_LEVEL_FIRST; i <= ED_TEXTINPUT_ID_LEVEL_LAST; i++)
     MapTextInputGadget(i);
 
   /* draw drawing area */
@@ -5085,7 +5482,7 @@ static void DrawElementContentAreas()
   /* display counter to choose number of element content areas */
   MapCounterButtons(ED_COUNTER_ID_ELEMENT_CONTENT);
 
-  for (i=0; i < MAX_ELEMENT_CONTENTS; i++)
+  for (i = 0; i < MAX_ELEMENT_CONTENTS; i++)
   {
     int id = ED_DRAWING_ID_ELEMENT_CONTENT_0 + i;
     int font_height = getFontHeight(FONT_TEXT_1);
@@ -5135,8 +5532,7 @@ char *getElementDescriptionFilename(int element)
   static char *filename = NULL;
   char basename[MAX_FILENAME_LEN];
 
-  if (filename != NULL)
-    free(filename);
+  checked_free(filename);
 
   /* 1st try: look for element description file for exactly this element */
   sprintf(basename, "%s.txt", element_info[element].token_name);
@@ -5155,7 +5551,7 @@ char *getElementDescriptionFilename(int element)
   return NULL;
 }
 
-static boolean PrintInfoText(char *text, int font_nr, int screen_line)
+static boolean PrintInfoText(char *text, int font_nr, int start_line)
 {
   int font_height = getFontHeight(font_nr);
   int pad_x = ED_SETTINGS_XPOS(0);
@@ -5164,26 +5560,54 @@ static boolean PrintInfoText(char *text, int font_nr, int screen_line)
   int sy = SY + pad_y;
   int max_lines_per_screen = (SYSIZE - pad_y) / font_height - 1;
 
-  if (screen_line >= max_lines_per_screen)
+  if (start_line >= max_lines_per_screen)
     return FALSE;
 
-  DrawText(sx, sy + screen_line * font_height, text, font_nr);
+  DrawText(sx, sy + start_line * font_height, text, font_nr);
 
   return TRUE;
 }
 
-static int PrintElementDescriptionFromFile(char *filename, int screen_line)
+#if 1
+
+static int PrintElementDescriptionFromFile(char *filename, int start_line)
 {
   int font_nr = FONT_TEXT_2;
   int font_width = getFontWidth(font_nr);
+  int font_height = getFontHeight(font_nr);
   int pad_x = ED_SETTINGS_XPOS(0);
+  int pad_y = ED_SETTINGS_YPOS(0) + ED_BORDER_SIZE;
+  int sx = SX + pad_x;
+  int sy = SY + pad_y + start_line * font_height;
   int max_chars_per_line = (SXSIZE - 2 * pad_x) / font_width;
+  int max_lines_per_screen = (SYSIZE - pad_y) / font_height - 1;
+
+  return DrawTextFromFile(sx, sy, filename, font_nr, max_chars_per_line,
+                         max_lines_per_screen);
+}
+
+#else
+
+static int PrintElementDescriptionFromFile(char *filename, int start_line)
+{
+  int font_nr = FONT_TEXT_2;
+  int font_width = getFontWidth(font_nr);
+  int font_height = getFontHeight(font_nr);
+  int pad_x = ED_SETTINGS_XPOS(0);
+  int pad_y = ED_SETTINGS_YPOS(0) + ED_BORDER_SIZE;
+  int sx = SX + pad_x;
+  int sy = SY + pad_y;
+  int max_chars_per_line = (SXSIZE - 2 * pad_x) / font_width;
+  int max_lines_per_screen = (SYSIZE - pad_y) / font_height - 1;
+  int current_line = start_line;
   char line[MAX_LINE_LEN];
   char buffer[max_chars_per_line + 1];
   int buffer_len;
-  int lines_printed = 0;
   FILE *file;
 
+  if (current_line >= max_lines_per_screen)
+    return 0;
+
   if (filename == NULL)
     return 0;
 
@@ -5193,9 +5617,9 @@ static int PrintElementDescriptionFromFile(char *filename, int screen_line)
   buffer[0] = '\0';
   buffer_len = 0;
 
-  while(!feof(file))
+  while (!feof(file) && current_line < max_lines_per_screen)
   {
-    char *line_ptr, *word_ptr;
+    char *line_ptr;
     boolean last_line_was_empty = TRUE;
 
     /* read next line of input file */
@@ -5219,92 +5643,40 @@ static int PrintElementDescriptionFromFile(char *filename, int screen_line)
     if (strlen(line) == 0)             /* special case: force empty line */
       strcpy(line, "\n");
 
-    word_ptr = line;
+    line_ptr = line;
 
-    while (*word_ptr)
+    while (*line_ptr && current_line < max_lines_per_screen)
     {
-      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 */
+      boolean buffer_filled = RenderLineToBuffer(&line_ptr,
+                                                buffer, &buffer_len,
+                                                last_line_was_empty,
+                                                max_chars_per_line);
+      if (buffer_filled)
       {
-       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;
+       DrawText(sx, sy + current_line * font_height, buffer, font_nr);
+       current_line++;
 
        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++;
+  if (buffer_len > 0 && current_line < max_lines_per_screen)
+  {
+    DrawText(sx, sy + current_line * font_height, buffer, font_nr);
+    current_line++;
+  }
 
-  return lines_printed;
+  return (current_line - start_line);
 }
 
+#endif
+
 static void DrawPropertiesTabulatorGadgets()
 {
   struct GadgetInfo *gd_gi = level_editor_gadget[GADGET_ID_PROPERTIES_INFO];
@@ -5320,7 +5692,7 @@ static void DrawPropertiesTabulatorGadgets()
   if (IS_CUSTOM_ELEMENT(properties_element))
     id_last = ED_TEXTBUTTON_ID_PROPERTIES_ADVANCED;
 
-  for (i=id_first; i <= id_last; i++)
+  for (i = id_first; i <= id_last; i++)
   {
     int gadget_id = textbutton_info[i].gadget_id;
     struct GadgetInfo *gi = level_editor_gadget[gadget_id];
@@ -5424,13 +5796,13 @@ static void DrawPropertiesInfo()
   /* ----- print number of elements / percentage of this element in level */
 
   num_elements_in_level = 0;
-  for (y=0; y<lev_fieldy; y++) 
-    for (x=0; x<lev_fieldx; x++)
+  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);
 
-  DrawTextF(pad_x, pad_y + screen_line * font2_height, font1_nr,
+  DrawTextS(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,
@@ -5440,21 +5812,21 @@ static void DrawPropertiesInfo()
 
   /* ----- print standard properties of this element */
 
-  DrawTextF(pad_x, pad_y + screen_line++ * font2_height, font1_nr,
+  DrawTextS(pad_x, pad_y + screen_line++ * font2_height, font1_nr,
            properties_text);
 
-  for (i=0; properties[i].value != -1; i++)
+  for (i = 0; properties[i].value != -1; i++)
   {
     if (!HAS_PROPERTY(properties_element, properties[i].value))
       continue;
 
-    DrawTextF(pad_x, pad_y + screen_line++ * font2_height, font2_nr,
+    DrawTextS(pad_x, pad_y + screen_line++ * font2_height, font2_nr,
              properties[i].text);
     num_standard_properties++;
   }
 
   if (num_standard_properties == 0)
-    DrawTextF(pad_x + strlen(properties_text) * font1_width,
+    DrawTextS(pad_x + strlen(properties_text) * font1_width,
              pad_y + (screen_line - 1) * font2_height, font2_nr, "none");
 
   screen_line++;
@@ -5555,7 +5927,7 @@ static boolean checkPropertiesConfig()
       HAS_CONTENT(properties_element))
     return TRUE;
   else
-    for (i=0; elements_with_counter[i].element != -1; i++)
+    for (i = 0; elements_with_counter[i].element != -1; i++)
       if (elements_with_counter[i].element == properties_element)
        return TRUE;
 
@@ -5574,7 +5946,7 @@ static void DrawPropertiesConfig()
   }
 
   /* check if there are elements where a score can be chosen for */
-  for (i=0; elements_with_counter[i].element != -1; i++)
+  for (i = 0; elements_with_counter[i].element != -1; i++)
   {
     if (elements_with_counter[i].element == properties_element)
     {
@@ -5633,7 +6005,7 @@ static void DrawPropertiesConfig()
       MapCheckbuttonGadget(i);
 
     /* draw counter gadgets */
-    for (i=ED_COUNTER_ID_CUSTOM_FIRST; i<=ED_COUNTER_ID_CUSTOM_LAST; i++)
+    for (i = ED_COUNTER_ID_CUSTOM_FIRST; i <= ED_COUNTER_ID_CUSTOM_LAST; i++)
       MapCounterButtons(i);
 
     /* draw selectbox gadgets */
@@ -5674,15 +6046,15 @@ static void DrawPropertiesAdvanced()
     MapCheckbuttonGadget(i);
 
   /* draw counter gadgets */
-  for (i=ED_COUNTER_ID_CHANGE_FIRST; i<=ED_COUNTER_ID_CHANGE_LAST; i++)
+  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++)
+  for (i = ED_SELECTBOX_ID_CHANGE_FIRST; i <= ED_SELECTBOX_ID_CHANGE_LAST; i++)
     MapSelectboxGadget(i);
 
   /* draw textbutton gadgets */
-  for (i=ED_TEXTBUTTON_ID_CHANGE_FIRST; i<=ED_TEXTBUTTON_ID_CHANGE_LAST; i++)
+  for (i=ED_TEXTBUTTON_ID_CHANGE_FIRST; i <= ED_TEXTBUTTON_ID_CHANGE_LAST; i++)
     MapTextbuttonGadget(i);
 
   /* draw graphicbutton gadgets */
@@ -5705,7 +6077,7 @@ static void DrawElementName(int x, int y, int element)
   char buffer[max_chars_per_line + 1];
 
   if (strlen(element_name) <= max_chars_per_line)
-    DrawTextF(x, y, font_nr, element_name);
+    DrawTextS(x, y, font_nr, element_name);
   else
   {
     int next_pos = max_chars_per_line;
@@ -5730,12 +6102,12 @@ static void DrawElementName(int x, int y, int element)
       }
     }
 
-    DrawTextF(x, y - font_height / 2, font_nr, buffer);
+    DrawTextS(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);
+    DrawTextS(x, y + font_height / 2, font_nr, buffer);
   }
 }
 
@@ -5755,6 +6127,11 @@ static void DrawPropertiesWindow()
     CopyCustomElementPropertiesToEditor(properties_element);
 
   UnmapLevelEditorWindowGadgets();
+  UnmapLevelEditorToolboxDrawingGadgets();
+  UnmapLevelEditorToolboxCustomGadgets();
+
+  if (IS_CUSTOM_ELEMENT(properties_element))
+    MapLevelEditorToolboxCustomGadgets();
 
   SetMainBackgroundImage(IMG_BACKGROUND_EDITOR);
   ClearWindow();
@@ -5817,7 +6194,7 @@ static void DrawLine(int from_x, int from_y, int to_x, int to_y,
     if (from_x > to_x)
       swap_numbers(&from_x, &to_x);
 
-    for (x=from_x; x<=to_x; x++)
+    for (x = from_x; x <= to_x; x++)
       DrawLineElement(x, y, element, change_level);
   }
   else if (from_x == to_x)             /* vertical line */
@@ -5828,7 +6205,7 @@ static void DrawLine(int from_x, int from_y, int to_x, int to_y,
     if (from_y > to_y)
       swap_numbers(&from_y, &to_y);
 
-    for (y=from_y; y<=to_y; y++)
+    for (y = from_y; y <= to_y; y++)
       DrawLineElement(x, y, element, change_level);
   }
   else                                 /* diagonal line */
@@ -5844,7 +6221,7 @@ static void DrawLine(int from_x, int from_y, int to_x, int to_y,
       if (from_x > to_x)
        swap_number_pairs(&from_x, &from_y, &to_x, &to_y);
 
-      for (x=0; x<=len_x; x++)
+      for (x = 0; x <= len_x; x++)
       {
        y = (int)(a * x + 0.5) * (to_y < from_y ? -1 : +1);
        DrawLineElement(from_x + x, from_y + y, element, change_level);
@@ -5857,7 +6234,7 @@ static void DrawLine(int from_x, int from_y, int to_x, int to_y,
       if (from_y > to_y)
        swap_number_pairs(&from_x, &from_y, &to_x, &to_y);
 
-      for (y=0; y<=len_y; y++)
+      for (y = 0; y <= len_y; y++)
       {
        x = (int)(a * y + 0.5) * (to_x < from_x ? -1 : +1);
        DrawLineElement(from_x + x, from_y + y, element, change_level);
@@ -5883,7 +6260,7 @@ static void DrawFilledBox(int from_x, int from_y, int to_x, int to_y,
   if (from_y > to_y)
     swap_number_pairs(&from_x, &from_y, &to_x, &to_y);
 
-  for (y=from_y; y<=to_y; y++)
+  for (y = from_y; y <= to_y; y++)
     DrawLine(from_x, y, to_x, y, element, change_level);
 }
 
@@ -5901,7 +6278,7 @@ static void DrawArcExt(int from_x, int from_y, int to_x2, int to_y2,
   /* not optimal (some points get drawn twice) but simple,
      and fast enough for the few points we are drawing */
 
-  for (x=0; x<=radius; x++)
+  for (x = 0; x <= radius; x++)
   {
     int sx, sy, lx, ly;
 
@@ -5916,7 +6293,7 @@ static void DrawArcExt(int from_x, int from_y, int to_x2, int to_y2,
       DrawLineElement(sx, sy, element, change_level);
   }
 
-  for (y=0; y<=radius; y++)
+  for (y = 0; y <= radius; y++)
   {
     int sx, sy, lx, ly;
 
@@ -6029,9 +6406,9 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y,
     from_lx = from_x + level_xpos;
     from_ly = from_y + level_ypos;
 
-    for (y=0; y<brush_height; y++)
+    for (y = 0; y < brush_height; y++)
     {
-      for (x=0; x<brush_width; x++)
+      for (x=0; x < brush_width; x++)
       {
        brush_buffer[x][y] = Feld[from_lx + x][from_ly + y];
 
@@ -6065,9 +6442,9 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y,
       return;
     }
 
-    for (y=0; y<brush_height; y++)
+    for (y = 0; y < brush_height; y++)
     {
-      for (x=0; x<brush_width; x++)
+      for (x = 0; x < brush_width; x++)
       {
        int sx = cursor_from_x + x;
        int sy = cursor_from_y + y;
@@ -6143,7 +6520,7 @@ static void FloodFill(int from_x, int from_y, int fill_element)
   old_element = Feld[from_x][from_y];
   Feld[from_x][from_y] = fill_element;
 
-  for(i=0;i<4;i++)
+  for (i = 0; i < 4; i++)
   {
     x = from_x + check[i][0];
     y = from_y + check[i][1];
@@ -6312,8 +6689,8 @@ static void CopyLevelToUndoBuffer(int mode)
       undo_buffer_steps++;
   }
 
-  for(x=0; x<lev_fieldx; x++)
-    for(y=0; y<lev_fieldy; y++)
+  for (x = 0; x < lev_fieldx; x++)
+    for (y = 0; y < lev_fieldy; y++)
       UndoBuffer[undo_buffer_position][x][y] = Feld[x][y];
 
   /* check if drawing operation forces change of border style */
@@ -6334,8 +6711,8 @@ static void RandomPlacement(int new_element)
   /* determine number of free positions for the new elements */
   /* (maybe this statement should be formatted a bit more readable...) */
   num_free_positions = 0;
-  for (x=0; x<lev_fieldx; x++)
-    for (y=0; y<lev_fieldy; y++)
+  for (x = 0; x < lev_fieldx; x++)
+    for (y = 0; y < lev_fieldy; y++)
       if ((free_position[x][y] =
           ((random_placement_background_restricted &&
             Feld[x][y] == random_placement_background_element) ||
@@ -6351,8 +6728,8 @@ static void RandomPlacement(int new_element)
   /* if not more free positions than elements to place, fill whole level */
   if (num_elements >= num_free_positions)
   {
-    for (x=0; x<lev_fieldx; x++)
-      for (y=0; y<lev_fieldy; y++)
+    for (x = 0; x < lev_fieldx; x++)
+      for (y = 0; y < lev_fieldy; y++)
        Feld[x][y] = new_element;
 
     DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos);
@@ -6384,12 +6761,12 @@ void WrapLevel(int dx, int dy)
   int wrap_dy = lev_fieldy - dy;
   int x, y;
 
-  for(x=0; x<lev_fieldx; x++)
-    for(y=0; y<lev_fieldy; y++)
+  for (x = 0; x < lev_fieldx; x++)
+    for (y = 0; y < lev_fieldy; y++)
       FieldBackup[x][y] = Feld[x][y];
 
-  for(x=0; x<lev_fieldx; x++)
-    for(y=0; y<lev_fieldy; y++)
+  for (x = 0; x < lev_fieldx; x++)
+    for (y = 0; y < lev_fieldy; y++)
       Feld[x][y] =
        FieldBackup[(x + wrap_dx) % lev_fieldx][(y + wrap_dy) % lev_fieldy];
 
@@ -6461,7 +6838,10 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
 
   /* clicking into drawing area with pressed Control key picks element */
   if (GetKeyModState() & KMOD_Control)
+  {
+    last_drawing_function = drawing_function;
     actual_drawing_function = GADGET_ID_PICK_ELEMENT;
+  }
 
   switch (actual_drawing_function)
   {
@@ -6490,9 +6870,9 @@ static void HandleDrawingAreas(struct GadgetInfo *gi)
          if (new_element == EL_PLAYER_1)
          {
            /* remove player at old position */
-           for(y=0; y<lev_fieldy; y++)
+           for (y = 0; y < lev_fieldy; y++)
            {
-             for(x=0; x<lev_fieldx; x++)
+             for (x = 0; x < lev_fieldx; x++)
              {
                if (Feld[x][y] == EL_PLAYER_1)
                {
@@ -6818,11 +7198,11 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi)
     boolean new_template = (!LevelFileExists(-1));
 
     if (new_template ||
-       Request("Save this template and kill the old ?", REQ_ASK))
+       Request("Save this template and kill the old ?", REQ_ASK))
       SaveLevelTemplate();
 
     if (new_template)
-      Request("Template saved !", REQ_CONFIRM);
+      Request("Template saved !", REQ_CONFIRM);
   }
   else if (type_id == ED_TEXTBUTTON_ID_ADD_CHANGE_PAGE &&
           custom_element.num_change_pages < MAX_CHANGE_PAGES)
@@ -6905,7 +7285,7 @@ static void HandleCheckbuttons(struct GadgetInfo *gi)
   {
     if (level.use_custom_template && !LevelFileExists(-1))
     {
-      Request("No level template found !", REQ_CONFIRM);
+      Request("No level template found !", REQ_CONFIRM);
 
       level.use_custom_template = FALSE;
       ModifyGadget(gi, GDI_CHECKED, FALSE, GDI_END);
@@ -6921,6 +7301,9 @@ static void HandleCheckbuttons(struct GadgetInfo *gi)
 
 static void HandleControlButtons(struct GadgetInfo *gi)
 {
+  static int last_level_drawing_function = GADGET_ID_SINGLE_ITEMS;
+  static int last_edit_mode = ED_MODE_DRAWING;
+  static int last_custom_copy_mode = -1;
   int id = gi->custom_id;
   int button = gi->event.button;
   int step = BUTTON_STEPSIZE(button);
@@ -6930,8 +7313,11 @@ static void HandleControlButtons(struct GadgetInfo *gi)
   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 &&
-      id != GADGET_ID_PICK_ELEMENT && edit_mode != ED_MODE_DRAWING &&
+  if (id < ED_NUM_CTRL1_BUTTONS &&
+      id != GADGET_ID_SINGLE_ITEMS &&
+      id != GADGET_ID_PROPERTIES &&
+      id != GADGET_ID_PICK_ELEMENT &&
+      edit_mode != ED_MODE_DRAWING &&
       drawing_function != GADGET_ID_PICK_ELEMENT &&
       !(GetKeyModState() & KMOD_Control))
   {
@@ -7093,14 +7479,28 @@ static void HandleControlButtons(struct GadgetInfo *gi)
        properties_element = new_element;
        DrawPropertiesWindow();
        edit_mode = ED_MODE_PROPERTIES;
+
+       last_level_drawing_function = drawing_function;
+       ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS],
+                     MB_LEFTBUTTON);
       }
       else
       {
        DrawDrawingWindow();
        edit_mode = ED_MODE_DRAWING;
+
+       ClickOnGadget(level_editor_gadget[last_level_drawing_function],
+                     MB_LEFTBUTTON);
       }
       break;
 
+    case GADGET_ID_CUSTOM_COPY_FROM:
+    case GADGET_ID_CUSTOM_COPY_TO:
+    case GADGET_ID_CUSTOM_EXCHANGE:
+      last_custom_copy_mode = id;
+      last_drawing_function = drawing_function;
+      break;
+
     case GADGET_ID_UNDO:
       if (undo_buffer_steps == 0)
       {
@@ -7118,8 +7518,8 @@ static void HandleControlButtons(struct GadgetInfo *gi)
        (undo_buffer_position - 1 + NUM_UNDO_STEPS) % NUM_UNDO_STEPS;
       undo_buffer_steps--;
 
-      for(x=0; x<lev_fieldx; x++)
-       for(y=0; y<lev_fieldy; y++)
+      for (x = 0; x < lev_fieldx; x++)
+       for (y = 0; y < lev_fieldy; y++)
          Feld[x][y] = UndoBuffer[undo_buffer_position][x][y];
       DrawMiniLevel(ed_fieldx, ed_fieldy, level_xpos,level_ypos);
       break;
@@ -7127,13 +7527,16 @@ static void HandleControlButtons(struct GadgetInfo *gi)
     case GADGET_ID_INFO:
       if (edit_mode != ED_MODE_INFO)
       {
-       DrawLevelInfoWindow();
+       last_edit_mode = edit_mode;
        edit_mode = ED_MODE_INFO;
+
+       DrawLevelInfoWindow();
       }
       else
       {
-       DrawDrawingWindow();
-       edit_mode = ED_MODE_DRAWING;
+       edit_mode = last_edit_mode;
+
+       DrawEditModeWindow();
       }
       break;
 
@@ -7144,8 +7547,8 @@ static void HandleControlButtons(struct GadgetInfo *gi)
        edit_mode = ED_MODE_DRAWING;
       }
 
-      for(x=0; x<MAX_LEV_FIELDX; x++) 
-       for(y=0; y<MAX_LEV_FIELDY; y++) 
+      for (x = 0; x < MAX_LEV_FIELDX; x++) 
+       for (y = 0; y < MAX_LEV_FIELDY; y++) 
          Feld[x][y] = (button == 1 ? EL_EMPTY : new_element);
       CopyLevelToUndoBuffer(GADGET_ID_CLEAR);
 
@@ -7217,6 +7620,19 @@ static void HandleControlButtons(struct GadgetInfo *gi)
        int element_position = id - GADGET_ID_ELEMENTLIST_FIRST;
        int new_element = editor_elements[element_position + element_shift];
 
+       if (last_custom_copy_mode != -1)
+       {
+         CopyCustomElement(properties_element, new_element,
+                           last_custom_copy_mode);
+
+         ClickOnGadget(level_editor_gadget[last_drawing_function],
+                       MB_LEFTBUTTON);
+
+         last_custom_copy_mode = -1;
+
+         break;
+       }
+
        PickDrawingElement(button, new_element);
 
        if (!stick_element_properties_window &&
@@ -7313,7 +7729,7 @@ void HandleLevelEditorKeyInput(Key key)
     else if (key == KSYM_Return || key == setup.shortcut.toggle_pause)
       ClickOnGadget(level_editor_gadget[GADGET_ID_TEST], button);
     else
-      for (i=0; i<ED_NUM_CTRL_BUTTONS; i++)
+      for (i = 0; i < ED_NUM_CTRL_BUTTONS; i++)
        if (letter && letter == control_info[i].shortcut)
          if (!anyTextGadgetActive())
            ClickOnGadget(level_editor_gadget[i], button);
@@ -7552,25 +7968,25 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi)
   else
   {
     if (id == GADGET_ID_AMOEBA_CONTENT)
-      DrawTextF(INFOTEXT_XPOS - SX, INFOTEXT_YPOS - SY, FONT_TEXT_2,
+      DrawTextS(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,
+      DrawTextS(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,
+      DrawTextS(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,
+      DrawTextS(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,
+      DrawTextS(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,
+      DrawTextS(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)
index 3213c4528fdbc101e3c8d40dbddf96475683fdfb..3844a2c83d29d7f9c87a139daa0c2bb7e56e6091 100644 (file)
@@ -32,5 +32,6 @@ void HandleLevelEditorKeyInput(Key);
 void HandleLevelEditorIdle();
 void HandleEditorGadgetInfoText(void *ptr);
 void RequestExitLevelEditor(boolean);
+void PrintEditorElementList();
 
 #endif
index e021ec83239051920c36a19b4cbeebde04931ada..19c47763e05236c491659fbd15d9b772ecf204f1 100644 (file)
@@ -79,7 +79,7 @@ static boolean NextValidEvent(Event *event)
 
 void EventLoop(void)
 {
-  while(1)
+  while (1)
   {
     if (PendingEvent())                /* got event */
     {
@@ -219,7 +219,7 @@ void ClearPlayerAction()
 
   /* simulate key release events for still pressed keys */
   key_joystick_mapping = 0;
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
     stored_player[i].action = 0;
 }
 
@@ -229,7 +229,7 @@ void SleepWhileUnmapped()
 
   KeyboardAutoRepeatOn();
 
-  while(window_unmapped)
+  while (window_unmapped)
   {
     Event event;
 
@@ -374,7 +374,11 @@ void HandleButton(int mx, int my, int button)
     old_my = my;
   }
 
-  HandleGadgets(mx, my, button);
+  if (HandleGadgets(mx, my, button))
+  {
+    /* do not handle this button event anymore */
+    mx = my = -32;     /* force mouse event to be outside screen tiles */
+  }
 
   switch(game_status)
   {
@@ -398,7 +402,7 @@ void HandleButton(int mx, int my, int button)
       break;
 
     case GAME_MODE_INFO:
-      HandleHelpScreen(button);
+      HandleInfoScreen(mx,my, 0,0, button);
       break;
 
     case GAME_MODE_SETUP:
@@ -409,11 +413,10 @@ void HandleButton(int mx, int my, int button)
 #ifdef DEBUG
       if (button == MB_RELEASED)
       {
-       int sx = (mx - SX) / TILEX;
-       int sy = (my - SY) / TILEY;
-
-       if (IN_VIS_FIELD(sx,sy))
+       if (IN_GFX_SCREEN(mx, my))
        {
+         int sx = (mx - SX) / TILEX;
+         int sy = (my - SY) / TILEY;
          int x = LEVELX(sx);
          int y = LEVELY(sy);
 
@@ -446,6 +449,63 @@ void HandleButton(int mx, int my, int button)
   }
 }
 
+static boolean is_string_suffix(char *string, char *suffix)
+{
+  int string_len = strlen(string);
+  int suffix_len = strlen(suffix);
+
+  if (suffix_len > string_len)
+    return FALSE;
+
+  return (strcmp(&string[string_len - suffix_len], suffix) == 0);
+}
+
+#define MAX_CHEAT_INPUT_LEN    32
+
+static void HandleKeysCheating(Key key)
+{
+  static char cheat_input[2 * MAX_CHEAT_INPUT_LEN + 1] = "";
+  char letter = getCharFromKey(key);
+  int cheat_input_len = strlen(cheat_input);
+  int i;
+
+  if (letter == 0)
+    return;
+
+  if (cheat_input_len >= 2 * MAX_CHEAT_INPUT_LEN)
+  {
+    for (i = 0; i < MAX_CHEAT_INPUT_LEN + 1; i++)
+      cheat_input[i] = cheat_input[MAX_CHEAT_INPUT_LEN + i];
+
+    cheat_input_len = MAX_CHEAT_INPUT_LEN;
+  }
+
+  cheat_input[cheat_input_len++] = letter;
+  cheat_input[cheat_input_len] = '\0';
+
+#if 0
+  printf("::: '%s' [%d]\n", cheat_input, cheat_input_len);
+#endif
+
+#if 1
+  if (is_string_suffix(cheat_input, ":insert solution tape"))
+    InsertSolutionTape();
+#else
+  if (is_string_suffix(cheat_input, ":ist"))
+    InsertSolutionTape();
+#endif
+
+#ifdef DEBUG
+  else if (is_string_suffix(cheat_input, ":dump tape"))
+    DumpTape(&tape);
+  else if (is_string_suffix(cheat_input, ".q"))
+    for (i = 0; i < MAX_INVENTORY_SIZE; i++)
+      if (local_player->inventory_size < MAX_INVENTORY_SIZE)
+       local_player->inventory_element[local_player->inventory_size++] =
+         EL_DYNAMITE;
+#endif
+}
+
 void HandleKey(Key key, int key_status)
 {
   int joy = 0;
@@ -473,7 +533,7 @@ void HandleKey(Key key, int key_status)
     static boolean bomb_placed[MAX_PLAYERS] = { FALSE,FALSE,FALSE,FALSE };
     int pnr;
 
-    for (pnr=0; pnr<MAX_PLAYERS; pnr++)
+    for (pnr = 0; pnr < MAX_PLAYERS; pnr++)
     {
       int i;
       byte key_action = 0;
@@ -483,7 +543,7 @@ void HandleKey(Key key, int key_status)
 
       custom_key = setup.input[pnr].key;
 
-      for (i=0; i<6; i++)
+      for (i = 0; i < 6; i++)
        if (key == *key_info[i].key_custom)
          key_action |= key_info[i].action;
 
@@ -533,7 +593,7 @@ void HandleKey(Key key, int key_status)
   {
     int i;
 
-    for (i=0; i<6; i++)
+    for (i = 0; i < 6; i++)
       if (key == key_info[i].key_default)
        joy |= key_info[i].action;
   }
@@ -563,19 +623,6 @@ void HandleKey(Key key, int key_status)
     return;
   }
 
-  /* allow quick escape to the main menu with the Escape key */
-  if (key == KSYM_Escape &&
-      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 = GAME_MODE_MAIN;
-    DrawMainMenu();
-    return;
-  }
-
   /* special key shortcuts */
   if (game_status == GAME_MODE_MAIN || game_status == GAME_MODE_PLAYING)
   {
@@ -585,19 +632,15 @@ void HandleKey(Key key, int key_status)
       TapeQuickLoad();
     else if (key == setup.shortcut.toggle_pause)
       TapeTogglePause(TAPE_TOGGLE_MANUAL);
-  }
-
-#if 0
-#ifndef DEBUG
-
-  if (game_status == GAME_MODE_PLAYING && (tape.playing || tape.pausing))
-    return;
-
-#endif
-#endif
 
+    HandleKeysCheating(key);
+  }
 
-  HandleGadgetsKeyInput(key);
+  if (HandleGadgetsKeyInput(key))
+  {
+    if (key != KSYM_Escape)    /* always allow ESC key to be handled */
+      key = KSYM_UNDEFINED;
+  }
 
   switch(game_status)
   {
@@ -608,6 +651,7 @@ void HandleKey(Key key, int key_status)
     case GAME_MODE_MAIN:
     case GAME_MODE_LEVELS:
     case GAME_MODE_SETUP:
+    case GAME_MODE_INFO:
       switch(key)
       {
        case KSYM_Return:
@@ -617,6 +661,8 @@ void HandleKey(Key key, int key_status)
             HandleChooseLevel(0,0, 0,0, MB_MENU_CHOICE);
          else if (game_status == GAME_MODE_SETUP)
            HandleSetupScreen(0,0, 0,0, MB_MENU_CHOICE);
+         else if (game_status == GAME_MODE_INFO)
+           HandleInfoScreen(0,0, 0,0, MB_MENU_CHOICE);
          break;
 
        case KSYM_Escape:
@@ -624,6 +670,8 @@ void HandleKey(Key key, int key_status)
             HandleChooseLevel(0,0, 0,0, MB_MENU_LEAVE);
          else if (game_status == GAME_MODE_SETUP)
            HandleSetupScreen(0,0, 0,0, MB_MENU_LEAVE);
+         else if (game_status == GAME_MODE_INFO)
+           HandleInfoScreen(0,0, 0,0, MB_MENU_LEAVE);
          break;
 
         case KSYM_Page_Up:
@@ -631,6 +679,8 @@ void HandleKey(Key key, int key_status)
             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);
+         else if (game_status == GAME_MODE_INFO)
+           HandleInfoScreen(0,0, 0, -1 * SCROLL_PAGE, MB_MENU_MARK);
          break;
 
         case KSYM_Page_Down:
@@ -638,30 +688,22 @@ void HandleKey(Key key, int key_status)
             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);
+         else if (game_status == GAME_MODE_INFO)
+           HandleInfoScreen(0,0, 0, +1 * SCROLL_PAGE, MB_MENU_MARK);
          break;
 
-#ifdef DEBUG
-        case KSYM_t:
-         DumpTape(&tape);
-         break;
-#endif
-
        default:
          break;
       }
       break;
 
-    case GAME_MODE_INFO:
-      HandleHelpScreen(MB_RELEASED);
-      break;
-
     case GAME_MODE_SCORES:
       switch(key)
       {
        case KSYM_Return:
+       case KSYM_Escape:
          game_status = GAME_MODE_MAIN;
          DrawMainMenu();
-         BackToFront();
          break;
 
         case KSYM_Page_Up:
@@ -727,7 +769,7 @@ void HandleKey(Key key, int key_status)
          }
          break;
 
-       case KSYM_s:
+       case KSYM_S:
          if (!global.fps_slowdown)
          {
            global.fps_slowdown = TRUE;
@@ -793,27 +835,13 @@ void HandleKey(Key key, int key_status)
          printf("ScrollStepSize == %d (1/1)\n", ScrollStepSize);
          break;
 
-       case KSYM_Q:
-       case KSYM_q:
-         {
-           int i;
-
-           for (i=0; i < MAX_INVENTORY_SIZE; i++)
-             if (local_player->inventory_size < MAX_INVENTORY_SIZE)
-               local_player->inventory_element[local_player->inventory_size++] =
-                 EL_DYNAMITE;
-         }
-
-         break;
-
-
 #if 0
 
        case KSYM_z:
          {
            int i;
 
-           for(i=0; i<MAX_PLAYERS; i++)
+           for (i = 0; i < MAX_PLAYERS; i++)
            {
              printf("Player %d:\n", i);
              printf("  jx == %d, jy == %d\n",
@@ -833,8 +861,15 @@ void HandleKey(Key key, int key_status)
       }
       break;
     }
+
     default:
-      break;
+      if (key == KSYM_Escape)
+      {
+       game_status = GAME_MODE_MAIN;
+       DrawMainMenu();
+
+       return;
+      }
   }
 }
 
@@ -859,7 +894,7 @@ static int HandleJoystickForAllPlayers()
   int i;
   int result = 0;
 
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
   {
     byte joy_action = 0;
 
@@ -899,6 +934,7 @@ void HandleJoystick()
     case GAME_MODE_MAIN:
     case GAME_MODE_LEVELS:
     case GAME_MODE_SETUP:
+    case GAME_MODE_INFO:
     {
       static unsigned long joystickmove_delay = 0;
 
@@ -912,6 +948,8 @@ void HandleJoystick()
         HandleChooseLevel(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
       else if (game_status == GAME_MODE_SETUP)
        HandleSetupScreen(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
+      else if (game_status == GAME_MODE_INFO)
+       HandleInfoScreen(0,0,dx,dy,newbutton ? MB_MENU_CHOICE : MB_MENU_MARK);
       break;
     }
 
@@ -919,10 +957,6 @@ void HandleJoystick()
       HandleHallOfFame(0,0, dx,dy, !newbutton);
       break;
 
-    case GAME_MODE_INFO:
-      HandleHelpScreen(!newbutton);
-      break;
-
     case GAME_MODE_EDITOR:
       HandleLevelEditorIdle();
       break;
index 813ce976bf0bba97cc5df07d40d3c089c8812606..929ce3348b305dee810dcb66aab779fb13c73b7f 100644 (file)
@@ -13,6 +13,8 @@
 
 #include <ctype.h>
 #include <sys/stat.h>
+#include <dirent.h>
+#include <math.h>
 
 #include "libgame/libgame.h"
 
@@ -89,8 +91,8 @@ void setElementChangeInfoToDefaults(struct ElementChangeInfo *change)
   change->random = 100;
   change->power = CP_NON_DESTRUCTIVE;
 
-  for(x=0; x<3; x++)
-    for(y=0; y<3; y++)
+  for (x = 0; x < 3; x++)
+    for (y = 0; y < 3; y++)
       change->content[x][y] = EL_EMPTY_SPACE;
 
   change->direct_action = 0;
@@ -115,8 +117,8 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
   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++)
+  for (x = 0; x < MAX_LEV_FIELDX; x++)
+    for (y = 0; y < MAX_LEV_FIELDY; y++)
       level->field[x][y] = EL_SAND;
 
   level->time = 100;
@@ -133,45 +135,45 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
 
   level->use_custom_template = FALSE;
 
-  for(i=0; i<MAX_LEVEL_NAME_LEN; i++)
+  for (i = 0; i < MAX_LEVEL_NAME_LEN; i++)
     level->name[i] = '\0';
-  for(i=0; i<MAX_LEVEL_AUTHOR_LEN; i++)
+  for (i = 0; i < MAX_LEVEL_AUTHOR_LEN; i++)
     level->author[i] = '\0';
 
   strcpy(level->name, NAMELESS_LEVEL_NAME);
   strcpy(level->author, ANONYMOUS_NAME);
 
-  for (i=0; i<4; i++)
+  for (i = 0; i < 4; i++)
   {
     level->envelope_text[i][0] = '\0';
     level->envelope_xsize[i] = MAX_ENVELOPE_XSIZE;
     level->envelope_ysize[i] = MAX_ENVELOPE_YSIZE;
   }
 
-  for(i=0; i<LEVEL_SCORE_ELEMENTS; i++)
+  for (i = 0; i < LEVEL_SCORE_ELEMENTS; i++)
     level->score[i] = 10;
 
   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++)
+  for (i = 0; i < MAX_ELEMENT_CONTENTS; i++)
+    for (x = 0; x < 3; x++)
+      for (y = 0; y < 3; y++)
        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 < MAX_NUM_ELEMENTS; i++)
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
     setElementChangePages(&element_info[i], 1);
     setElementChangeInfoToDefaults(element_info[i].change);
   }
 
-  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+  for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
   {
     int element = EL_CUSTOM_START + i;
 
-    for(j=0; j < MAX_ELEMENT_NAME_LEN + 1; j++)
+    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,
@@ -197,8 +199,8 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
 
     element_info[element].slippery_type = SLIPPERY_ANY_RANDOM;
 
-    for(x=0; x<3; x++)
-      for(y=0; y<3; y++)
+    for (x = 0; x < 3; x++)
+      for (y = 0; y < 3; y++)
        element_info[element].content[x][y] = EL_EMPTY_SPACE;
 
     element_info[element].access_type = 0;
@@ -215,7 +217,7 @@ static void setLevelInfoToDefaults(struct LevelInfo *level)
     element_info[element].current_change_page = 0;
 
     /* start with no properties at all */
-    for (j=0; j < NUM_EP_BITFIELDS; j++)
+    for (j = 0; j < NUM_EP_BITFIELDS; j++)
       Properties[element][j] = EP_BITMASK_DEFAULT;
 
     element_info[element].modified_settings = FALSE;
@@ -354,17 +356,17 @@ static int LoadLevel_HEAD(FILE *file, int chunk_size, struct LevelInfo *level)
   level->time          = getFile16BitBE(file);
   level->gems_needed   = getFile16BitBE(file);
 
-  for(i=0; i<MAX_LEVEL_NAME_LEN; i++)
+  for (i = 0; i < MAX_LEVEL_NAME_LEN; i++)
     level->name[i] = getFile8Bit(file);
   level->name[MAX_LEVEL_NAME_LEN] = 0;
 
-  for(i=0; i<LEVEL_SCORE_ELEMENTS; i++)
+  for (i = 0; i < LEVEL_SCORE_ELEMENTS; i++)
     level->score[i] = getFile8Bit(file);
 
   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++)
+  for (i = 0; i < STD_ELEMENT_CONTENTS; i++)
+    for (y = 0; y < 3; y++)
+      for (x = 0; x < 3; x++)
        level->yamyam_content[i][x][y] = checkLevelElement(getFile8Bit(file));
 
   level->amoeba_speed          = getFile8Bit(file);
@@ -387,7 +389,7 @@ static int LoadLevel_AUTH(FILE *file, int chunk_size, struct LevelInfo *level)
 {
   int i;
 
-  for(i=0; i<MAX_LEVEL_AUTHOR_LEN; i++)
+  for (i = 0; i < MAX_LEVEL_AUTHOR_LEN; i++)
     level->author[i] = getFile8Bit(file);
   level->author[MAX_LEVEL_NAME_LEN] = 0;
 
@@ -413,8 +415,8 @@ static int LoadLevel_BODY(FILE *file, int chunk_size, struct LevelInfo *level)
     return chunk_size_expected;
   }
 
-  for(y=0; y<level->fieldy; y++)
-    for(x=0; x<level->fieldx; x++)
+  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));
@@ -452,9 +454,9 @@ static int LoadLevel_CONT(FILE *file, int chunk_size, struct LevelInfo *level)
       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++)
+  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));
@@ -475,9 +477,9 @@ static int LoadLevel_CNT2(FILE *file, int chunk_size, struct LevelInfo *level)
 
   ReadUnusedBytesFromFile(file, LEVEL_CHUNK_CNT2_UNUSED);
 
-  for(i=0; i<MAX_ELEMENT_CONTENTS; i++)
-    for(y=0; y<3; y++)
-      for(x=0; x<3; x++)
+  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] = checkLevelElement(getFile16BitBE(file));
 
   /* correct invalid number of content fields -- should never happen */
@@ -488,9 +490,9 @@ static int LoadLevel_CNT2(FILE *file, int chunk_size, struct LevelInfo *level)
   {
     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++)
+    for (i = 0; i < num_contents; i++)
+      for (y = 0; y < 3; y++)
+       for (x = 0; x < 3; x++)
          level->yamyam_content[i][x][y] = content_array[i][x][y];
   }
   else if (element == EL_BD_AMOEBA)
@@ -534,7 +536,7 @@ static int LoadLevel_CNT3(FILE *file, int chunk_size, struct LevelInfo *level)
     return chunk_size_expected;
   }
 
-  for(i=0; i < envelope_len; i++)
+  for (i = 0; i < envelope_len; i++)
     level->envelope_text[envelope_nr][i] = getFile8Bit(file);
 
   return chunk_size;
@@ -552,7 +554,7 @@ static int LoadLevel_CUS1(FILE *file, int chunk_size, struct LevelInfo *level)
     return chunk_size_expected;
   }
 
-  for (i=0; i < num_changed_custom_elements; i++)
+  for (i = 0; i < num_changed_custom_elements; i++)
   {
     int element = getFile16BitBE(file);
     int properties = getFile32BitBE(file);
@@ -578,7 +580,7 @@ static int LoadLevel_CUS2(FILE *file, int chunk_size, struct LevelInfo *level)
     return chunk_size_expected;
   }
 
-  for (i=0; i < num_changed_custom_elements; i++)
+  for (i = 0; i < num_changed_custom_elements; i++)
   {
     int element = getFile16BitBE(file);
     int custom_target_element = getFile16BitBE(file);
@@ -604,7 +606,7 @@ static int LoadLevel_CUS3(FILE *file, int chunk_size, struct LevelInfo *level)
     return chunk_size_expected;
   }
 
-  for (i=0; i < num_changed_custom_elements; i++)
+  for (i = 0; i < num_changed_custom_elements; i++)
   {
     int element = getFile16BitBE(file);
 
@@ -612,10 +614,10 @@ static int LoadLevel_CUS3(FILE *file, int chunk_size, struct LevelInfo *level)
     {
       Error(ERR_WARN, "invalid custom element number %d", element);
 
-      element = EL_DEFAULT;    /* dummy element used for artwork config */
+      element = EL_DUMMY;
     }
 
-    for(j=0; j<MAX_ELEMENT_NAME_LEN; j++)
+    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;
 
@@ -640,8 +642,8 @@ static int LoadLevel_CUS3(FILE *file, int chunk_size, struct LevelInfo *level)
     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++)
+    for (y = 0; y < 3; y++)
+      for (x = 0; x < 3; x++)
        element_info[element].content[x][y] =
          checkLevelElement(getFile16BitBE(file));
 
@@ -665,8 +667,8 @@ static int LoadLevel_CUS3(FILE *file, int chunk_size, struct LevelInfo *level)
     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++)
+    for (y = 0; y < 3; y++)
+      for (x = 0; x < 3; x++)
        element_info[element].change->content[x][y] =
          checkLevelElement(getFile16BitBE(file));
 
@@ -695,12 +697,12 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level)
   {
     Error(ERR_WARN, "invalid custom element number %d", element);
 
-    element = EL_DEFAULT;      /* dummy element used for artwork config */
+    element = EL_DUMMY;
   }
 
   ei = &element_info[element];
 
-  for(i=0; i < MAX_ELEMENT_NAME_LEN; i++)
+  for (i = 0; i < MAX_ELEMENT_NAME_LEN; i++)
     ei->description[i] = getFile8Bit(file);
   ei->description[MAX_ELEMENT_NAME_LEN] = 0;
 
@@ -738,8 +740,8 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level)
 
   ei->slippery_type = getFile8Bit(file);
 
-  for(y=0; y<3; y++)
-    for(x=0; x<3; x++)
+  for (y = 0; y < 3; y++)
+    for (x = 0; x < 3; x++)
       ei->content[x][y] = checkLevelElement(getFile16BitBE(file));
 
   /* some free bytes for future custom property values and padding */
@@ -749,7 +751,7 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level)
 
   setElementChangePages(ei, ei->num_change_pages);
 
-  for (i=0; i < ei->num_change_pages; i++)
+  for (i = 0; i < ei->num_change_pages; i++)
   {
     struct ElementChangeInfo *change = &ei->change_page[i];
 
@@ -774,8 +776,8 @@ static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level)
     change->random = getFile8Bit(file);
     change->power = getFile8Bit(file);
 
-    for(y=0; y<3; y++)
-      for(x=0; x<3; x++)
+    for (y = 0; y < 3; y++)
+      for (x = 0; x < 3; x++)
        change->content[x][y] = checkLevelElement(getFile16BitBE(file));
 
     change->can_change = getFile8Bit(file);
@@ -1025,12 +1027,12 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
      (these following values were accidentally changed in version 3.0.1) */
   if (level->game_version <= VERSION_IDENT(3,0,0,0))
   {
-    for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+    for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
     {
       int element = EL_CUSTOM_START + i;
 
       /* order of checking and copying events to be mapped is important */
-      for (j=CE_BY_OTHER_ACTION; j >= CE_BY_PLAYER; j--)
+      for (j = CE_BY_OTHER_ACTION; j >= CE_BY_PLAYER_OBSOLETE; j--)
       {
        if (HAS_CHANGE_EVENT(element, j - 2))
        {
@@ -1040,7 +1042,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
       }
 
       /* order of checking and copying events to be mapped is important */
-      for (j=CE_OTHER_GETS_COLLECTED; j >= CE_COLLISION; j--)
+      for (j = CE_OTHER_GETS_COLLECTED; j >= CE_COLLISION_ACTIVE; j--)
       {
        if (HAS_CHANGE_EVENT(element, j - 1))
        {
@@ -1052,15 +1054,15 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
   }
 
   /* some custom element change events get mapped since version 3.0.3 */
-  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+  for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
   {
     int element = EL_CUSTOM_START + i;
 
-    if (HAS_CHANGE_EVENT(element, CE_BY_PLAYER) ||
-       HAS_CHANGE_EVENT(element, CE_BY_COLLISION))
+    if (HAS_CHANGE_EVENT(element, CE_BY_PLAYER_OBSOLETE) ||
+       HAS_CHANGE_EVENT(element, CE_BY_COLLISION_OBSOLETE))
     {
-      SET_CHANGE_EVENT(element, CE_BY_PLAYER, FALSE);
-      SET_CHANGE_EVENT(element, CE_BY_COLLISION, FALSE);
+      SET_CHANGE_EVENT(element, CE_BY_PLAYER_OBSOLETE, FALSE);
+      SET_CHANGE_EVENT(element, CE_BY_COLLISION_OBSOLETE, FALSE);
 
       SET_CHANGE_EVENT(element, CE_BY_DIRECT_ACTION, TRUE);
     }
@@ -1069,7 +1071,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
   /* initialize "can_change" field for old levels with only one change page */
   if (level->game_version <= VERSION_IDENT(3,0,2,0))
   {
-    for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+    for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
     {
       int element = EL_CUSTOM_START + i;
 
@@ -1092,7 +1094,7 @@ static void LoadLevel_InitElements(struct LevelInfo *level, char *filename)
   }
 
   /* set uninitialized push delay values of custom elements in older levels */
-  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+  for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
   {
     int element = EL_CUSTOM_START + i;
 
@@ -1112,9 +1114,9 @@ static void LoadLevel_InitPlayfield(struct LevelInfo *level, char *filename)
   int x, y;
 
   /* map elements that have changed in newer versions */
-  for(y=0; y<level->fieldy; y++)
+  for (y = 0; y < level->fieldy; y++)
   {
-    for(x=0; x<level->fieldx; x++)
+    for (x = 0; x < level->fieldx; x++)
     {
       int element = level->field[x][y];
 
@@ -1142,8 +1144,8 @@ static void LoadLevel_InitPlayfield(struct LevelInfo *level, char *filename)
   }
 
   /* copy elements to runtime playfield array */
-  for(x=0; x<MAX_LEV_FIELDX; x++)
-    for(y=0; y<MAX_LEV_FIELDY; y++)
+  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 */
@@ -1200,15 +1202,15 @@ static void SaveLevel_HEAD(FILE *file, struct LevelInfo *level)
   putFile16BitBE(file, level->time);
   putFile16BitBE(file, level->gems_needed);
 
-  for(i=0; i<MAX_LEVEL_NAME_LEN; i++)
+  for (i = 0; i < MAX_LEVEL_NAME_LEN; i++)
     putFile8Bit(file, level->name[i]);
 
-  for(i=0; i<LEVEL_SCORE_ELEMENTS; i++)
+  for (i = 0; i < LEVEL_SCORE_ELEMENTS; i++)
     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++)
+  for (i = 0; i < STD_ELEMENT_CONTENTS; i++)
+    for (y = 0; y < 3; y++)
+      for (x = 0; x < 3; x++)
        putFile8Bit(file, (level->encoding_16bit_yamyam ? EL_EMPTY :
                           level->yamyam_content[i][x][y]));
   putFile8Bit(file, level->amoeba_speed);
@@ -1230,7 +1232,7 @@ static void SaveLevel_AUTH(FILE *file, struct LevelInfo *level)
 {
   int i;
 
-  for(i=0; i<MAX_LEVEL_AUTHOR_LEN; i++)
+  for (i = 0; i < MAX_LEVEL_AUTHOR_LEN; i++)
     putFile8Bit(file, level->author[i]);
 }
 
@@ -1238,8 +1240,8 @@ 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++) 
+  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
@@ -1256,9 +1258,9 @@ static void SaveLevel_CONT(FILE *file, struct LevelInfo *level)
   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++)
+  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->yamyam_content[i][x][y]);
        else
@@ -1278,9 +1280,9 @@ static void SaveLevel_CNT2(FILE *file, struct LevelInfo *level, int element)
     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++)
+    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->yamyam_content[i][x][y];
   }
   else if (element == EL_BD_AMOEBA)
@@ -1289,9 +1291,9 @@ static void SaveLevel_CNT2(FILE *file, struct LevelInfo *level, int element)
     content_xsize = 1;
     content_ysize = 1;
 
-    for(i=0; i<MAX_ELEMENT_CONTENTS; i++)
-      for(y=0; y<3; y++)
-       for(x=0; x<3; x++)
+    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_EMPTY;
     content_array[0][0][0] = level->amoeba_content;
   }
@@ -1311,9 +1313,9 @@ static void SaveLevel_CNT2(FILE *file, struct LevelInfo *level, int element)
 
   WriteUnusedBytesToFile(file, LEVEL_CHUNK_CNT2_UNUSED);
 
-  for(i=0; i<MAX_ELEMENT_CONTENTS; i++)
-    for(y=0; y<3; y++)
-      for(x=0; x<3; x++)
+  for (i = 0; i < MAX_ELEMENT_CONTENTS; i++)
+    for (y = 0; y < 3; y++)
+      for (x = 0; x < 3; x++)
        putFile16BitBE(file, content_array[i][x][y]);
 }
 
@@ -1330,7 +1332,7 @@ static void SaveLevel_CNT3(FILE *file, struct LevelInfo *level, int element)
 
   WriteUnusedBytesToFile(file, LEVEL_CHUNK_CNT3_UNUSED);
 
-  for(i=0; i < envelope_len; i++)
+  for (i = 0; i < envelope_len; i++)
     putFile8Bit(file, level->envelope_text[envelope_nr][i]);
 }
 
@@ -1342,7 +1344,7 @@ static void SaveLevel_CUS1(FILE *file, struct LevelInfo *level,
 
   putFile16BitBE(file, num_changed_custom_elements);
 
-  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+  for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
   {
     int element = EL_CUSTOM_START + i;
 
@@ -1371,7 +1373,7 @@ static void SaveLevel_CUS2(FILE *file, struct LevelInfo *level,
 
   putFile16BitBE(file, num_changed_custom_elements);
 
-  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+  for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
   {
     int element = EL_CUSTOM_START + i;
 
@@ -1400,7 +1402,7 @@ static void SaveLevel_CUS3(FILE *file, struct LevelInfo *level,
 
   putFile16BitBE(file, num_changed_custom_elements);
 
-  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+  for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
   {
     int element = EL_CUSTOM_START + i;
 
@@ -1410,7 +1412,7 @@ static void SaveLevel_CUS3(FILE *file, struct LevelInfo *level,
       {
        putFile16BitBE(file, element);
 
-       for(j=0; j<MAX_ELEMENT_NAME_LEN; j++)
+       for (j = 0; j < MAX_ELEMENT_NAME_LEN; j++)
          putFile8Bit(file, element_info[element].description[j]);
 
        putFile32BitBE(file, Properties[element][EP_BITFIELD_BASE]);
@@ -1433,8 +1435,8 @@ static void SaveLevel_CUS3(FILE *file, struct LevelInfo *level,
        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++)
+       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);
@@ -1455,8 +1457,8 @@ static void SaveLevel_CUS3(FILE *file, struct LevelInfo *level,
        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++)
+       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);
@@ -1481,7 +1483,7 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
 
   putFile16BitBE(file, element);
 
-  for(i=0; i < MAX_ELEMENT_NAME_LEN; i++)
+  for (i = 0; i < MAX_ELEMENT_NAME_LEN; i++)
     putFile8Bit(file, ei->description[i]);
 
   putFile32BitBE(file, Properties[element][EP_BITFIELD_BASE]);
@@ -1511,8 +1513,8 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
 
   putFile8Bit(file, ei->slippery_type);
 
-  for(y=0; y<3; y++)
-    for(x=0; x<3; x++)
+  for (y = 0; y < 3; y++)
+    for (x = 0; x < 3; x++)
       putFile16BitBE(file, ei->content[x][y]);
 
   /* some free bytes for future custom property values and padding */
@@ -1520,7 +1522,7 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
 
   /* write change property values */
 
-  for (i=0; i < ei->num_change_pages; i++)
+  for (i = 0; i < ei->num_change_pages; i++)
   {
     struct ElementChangeInfo *change = &ei->change_page[i];
 
@@ -1542,8 +1544,8 @@ static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element)
     putFile8Bit(file, change->random);
     putFile8Bit(file, change->power);
 
-    for(y=0; y<3; y++)
-      for(x=0; x<3; x++)
+    for (y = 0; y < 3; y++)
+      for (x = 0; x < 3; x++)
        putFile16BitBE(file, change->content[x][y]);
 
     putFile8Bit(file, change->can_change);
@@ -1572,16 +1574,16 @@ static void SaveLevelFromFilename(struct LevelInfo *level, char *filename)
 
   /* 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++) 
+  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_yamyam_contents; i++)
-    for(y=0; y<3; y++)
-      for(x=0; x<3; x++)
+  for (i = 0; i < level->num_yamyam_contents; i++)
+    for (y = 0; y < 3; y++)
+      for (x = 0; x < 3; x++)
        if (level->yamyam_content[i][x][y] > 255)
          level->encoding_16bit_yamyam = TRUE;
 
@@ -1623,7 +1625,7 @@ static void SaveLevelFromFilename(struct LevelInfo *level, char *filename)
   }
 
   /* check for envelope content */
-  for (i=0; i<4; i++)
+  for (i = 0; i < 4; i++)
   {
     if (strlen(level->envelope_text[i]) > 0)
     {
@@ -1637,7 +1639,7 @@ static void SaveLevelFromFilename(struct LevelInfo *level, char *filename)
   /* check for non-default custom elements (unless using template level) */
   if (!level->use_custom_template)
   {
-    for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+    for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
     {
       int element = EL_CUSTOM_START + i;
 
@@ -1713,7 +1715,7 @@ static void setTapeInfoToDefaults()
 
   /* default values (also for pre-1.2 tapes) with only the first player */
   tape.player_participates[0] = TRUE;
-  for(i=1; i<MAX_PLAYERS; i++)
+  for (i = 1; i < MAX_PLAYERS; i++)
     tape.player_participates[i] = FALSE;
 
   /* at least one (default: the first) player participates in every tape */
@@ -1752,7 +1754,7 @@ static int LoadTape_HEAD(FILE *file, int chunk_size, struct TapeInfo *tape)
 
     /* since version 1.2, tapes store which players participate in the tape */
     tape->num_participating_players = 0;
-    for(i=0; i<MAX_PLAYERS; i++)
+    for (i = 0; i < MAX_PLAYERS; i++)
     {
       tape->player_participates[i] = FALSE;
 
@@ -1785,7 +1787,7 @@ static int LoadTape_INFO(FILE *file, int chunk_size, struct TapeInfo *tape)
   tape->level_identifier =
     checked_realloc(tape->level_identifier, level_identifier_size);
 
-  for(i=0; i < level_identifier_size; i++)
+  for (i = 0; i < level_identifier_size; i++)
     tape->level_identifier[i] = getFile8Bit(file);
 
   tape->level_nr = getFile16BitBE(file);
@@ -1807,12 +1809,12 @@ static int LoadTape_BODY(FILE *file, int chunk_size, struct TapeInfo *tape)
     return chunk_size_expected;
   }
 
-  for(i=0; i<tape->length; i++)
+  for (i = 0; i < tape->length; i++)
   {
     if (i >= MAX_TAPELEN)
       break;
 
-    for(j=0; j<MAX_PLAYERS; j++)
+    for (j = 0; j < MAX_PLAYERS; j++)
     {
       tape->pos[i].action[j] = MV_NO_MOVING;
 
@@ -1831,7 +1833,7 @@ static int LoadTape_BODY(FILE *file, int chunk_size, struct TapeInfo *tape)
       byte action = tape->pos[i].action[0];
       int k, num_moves = 0;
 
-      for (k=0; k<4; k++)
+      for (k = 0; k<4; k++)
       {
        if (action & joy_dir[k])
        {
@@ -1860,7 +1862,7 @@ static int LoadTape_BODY(FILE *file, int chunk_size, struct TapeInfo *tape)
        tape->pos[i + 1].delay = 1;
 
        /* delay part */
-       for(j=0; j<MAX_PLAYERS; j++)
+       for (j = 0; j < MAX_PLAYERS; j++)
          tape->pos[i].action[j] = MV_NO_MOVING;
        tape->pos[i].delay--;
 
@@ -2009,6 +2011,13 @@ void LoadTape(int level_nr)
   LoadTapeFromFilename(filename);
 }
 
+void LoadSolutionTape(int level_nr)
+{
+  char *filename = getSolutionTapeFilename(level_nr);
+
+  LoadTapeFromFilename(filename);
+}
+
 static void SaveTape_VERS(FILE *file, struct TapeInfo *tape)
 {
   putFileVersion(file, tape->file_version);
@@ -2021,7 +2030,7 @@ static void SaveTape_HEAD(FILE *file, struct TapeInfo *tape)
   byte store_participating_players = 0;
 
   /* set bits for participating players for compact storage */
-  for(i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
     if (tape->player_participates[i])
       store_participating_players |= (1 << i);
 
@@ -2044,7 +2053,7 @@ static void SaveTape_INFO(FILE *file, struct TapeInfo *tape)
 
   putFile16BitBE(file, level_identifier_size);
 
-  for(i=0; i < level_identifier_size; i++)
+  for (i = 0; i < level_identifier_size; i++)
     putFile8Bit(file, tape->level_identifier[i]);
 
   putFile16BitBE(file, tape->level_nr);
@@ -2054,9 +2063,9 @@ static void SaveTape_BODY(FILE *file, struct TapeInfo *tape)
 {
   int i, j;
 
-  for(i=0; i<tape->length; i++)
+  for (i = 0; i < tape->length; i++)
   {
-    for(j=0; j<MAX_PLAYERS; j++)
+    for (j = 0; j < MAX_PLAYERS; j++)
       if (tape->player_participates[j])
        putFile8Bit(file, tape->pos[i].action[j]);
 
@@ -2094,7 +2103,7 @@ void SaveTape(int level_nr)
   tape.game_version = GAME_VERSION_ACTUAL;
 
   /* count number of participating players  */
-  for(i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
     if (tape.player_participates[i])
       num_participating_players++;
 
@@ -2142,14 +2151,14 @@ void DumpTape(struct TapeInfo *tape)
   printf("Level series identifier: '%s'\n", tape->level_identifier);
   printf_line("-", 79);
 
-  for(i=0; i<tape->length; i++)
+  for (i = 0; i < tape->length; i++)
   {
     if (i >= MAX_TAPELEN)
       break;
 
     printf("%03d: ", i);
 
-    for(j=0; j<MAX_PLAYERS; j++)
+    for (j = 0; j < MAX_PLAYERS; j++)
     {
       if (tape->player_participates[j])
       {
@@ -2187,7 +2196,7 @@ void LoadScore(int level_nr)
   FILE *file;
 
   /* always start with reliable default values */
-  for(i=0; i<MAX_SCORE_ENTRIES; i++)
+  for (i = 0; i < MAX_SCORE_ENTRIES; i++)
   {
     strcpy(highscore[i].Name, EMPTY_PLAYER_NAME);
     highscore[i].Score = 0;
@@ -2208,7 +2217,7 @@ void LoadScore(int level_nr)
     return;
   }
 
-  for(i=0; i<MAX_SCORE_ENTRIES; i++)
+  for (i = 0; i < MAX_SCORE_ENTRIES; i++)
   {
     fscanf(file, "%d", &highscore[i].Score);
     fgets(line, MAX_LINE_LEN, file);
@@ -2246,7 +2255,7 @@ void SaveScore(int level_nr)
 
   fprintf(file, "%s\n\n", SCORE_COOKIE);
 
-  for(i=0; i<MAX_SCORE_ENTRIES; i++)
+  for (i = 0; i < MAX_SCORE_ENTRIES; i++)
     fprintf(file, "%d %s\n", highscore[i].Score, highscore[i].Name);
 
   fclose(file);
@@ -2299,8 +2308,9 @@ void SaveScore(int level_nr)
 #define SETUP_TOKEN_EDITOR_EL_CUSTOM           8
 #define SETUP_TOKEN_EDITOR_EL_CUSTOM_MORE      9
 #define SETUP_TOKEN_EDITOR_EL_HEADLINES                10
+#define SETUP_TOKEN_EDITOR_EL_USER_DEFINED     11
 
-#define NUM_EDITOR_SETUP_TOKENS                        11
+#define NUM_EDITOR_SETUP_TOKENS                        12
 
 /* shortcut setup */
 #define SETUP_TOKEN_SHORTCUT_SAVE_GAME         0
@@ -2387,6 +2397,7 @@ static struct TokenInfo editor_setup_tokens[] =
   { TYPE_SWITCH, &sei.el_custom,       "editor.el_custom"              },
   { TYPE_SWITCH, &sei.el_custom_more,  "editor.el_custom_more"         },
   { TYPE_SWITCH, &sei.el_headlines,    "editor.el_headlines"           },
+  { TYPE_SWITCH, &sei.el_user_defined, "editor.el_user_defined"        },
 };
 
 static struct TokenInfo shortcut_setup_tokens[] =
@@ -2485,12 +2496,13 @@ static void setSetupInfoToDefaults(struct SetupInfo *si)
   si->editor.el_custom_more = FALSE;
 
   si->editor.el_headlines = TRUE;
+  si->editor.el_user_defined = FALSE;
 
   si->shortcut.save_game = DEFAULT_KEY_SAVE_GAME;
   si->shortcut.load_game = DEFAULT_KEY_LOAD_GAME;
   si->shortcut.toggle_pause = DEFAULT_KEY_TOGGLE_PAUSE;
 
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
   {
     si->input[i].use_joystick = FALSE;
     si->input[i].joy.device_name=getStringCopy(getDeviceNameFromJoystickNr(i));
@@ -2525,34 +2537,34 @@ static void decodeSetupFileHash(SetupFileHash *setup_file_hash)
 
   /* global setup */
   si = setup;
-  for (i=0; i<NUM_GLOBAL_SETUP_TOKENS; i++)
+  for (i = 0; i < NUM_GLOBAL_SETUP_TOKENS; i++)
     setSetupInfo(global_setup_tokens, i,
                 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++)
+  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++)
+  for (i = 0; i < NUM_SHORTCUT_SETUP_TOKENS; i++)
     setSetupInfo(shortcut_setup_tokens, i,
                 getHashEntry(setup_file_hash,shortcut_setup_tokens[i].text));
   setup.shortcut = ssi;
 
   /* player setup */
-  for (pnr=0; pnr<MAX_PLAYERS; pnr++)
+  for (pnr = 0; pnr < MAX_PLAYERS; pnr++)
   {
     char prefix[30];
 
     sprintf(prefix, "%s%d", TOKEN_STR_PLAYER_PREFIX, pnr + 1);
 
     sii = setup.input[pnr];
-    for (i=0; i<NUM_PLAYER_SETUP_TOKENS; i++)
+    for (i = 0; i < NUM_PLAYER_SETUP_TOKENS; i++)
     {
       char full_token[100];
 
@@ -2565,14 +2577,14 @@ static void decodeSetupFileHash(SetupFileHash *setup_file_hash)
 
   /* system setup */
   syi = setup.system;
-  for (i=0; i<NUM_SYSTEM_SETUP_TOKENS; i++)
+  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++)
+  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;
@@ -2628,7 +2640,7 @@ void SaveSetup()
 
   /* global setup */
   si = setup;
-  for (i=0; i<NUM_GLOBAL_SETUP_TOKENS; i++)
+  for (i = 0; i < NUM_GLOBAL_SETUP_TOKENS; i++)
   {
     /* just to make things nicer :) */
     if (i == SETUP_TOKEN_PLAYER_NAME + 1 ||
@@ -2641,17 +2653,17 @@ void SaveSetup()
   /* editor setup */
   sei = setup.editor;
   fprintf(file, "\n");
-  for (i=0; i<NUM_EDITOR_SETUP_TOKENS; i++)
+  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");
-  for (i=0; i<NUM_SHORTCUT_SETUP_TOKENS; i++)
+  for (i = 0; i < NUM_SHORTCUT_SETUP_TOKENS; i++)
     fprintf(file, "%s\n", getSetupLine(shortcut_setup_tokens, "", i));
 
   /* player setup */
-  for (pnr=0; pnr<MAX_PLAYERS; pnr++)
+  for (pnr = 0; pnr < MAX_PLAYERS; pnr++)
   {
     char prefix[30];
 
@@ -2659,20 +2671,20 @@ void SaveSetup()
     fprintf(file, "\n");
 
     sii = setup.input[pnr];
-    for (i=0; i<NUM_PLAYER_SETUP_TOKENS; i++)
+    for (i = 0; i < NUM_PLAYER_SETUP_TOKENS; i++)
       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++)
+  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++)
+  for (i = 0; i < NUM_OPTIONS_SETUP_TOKENS; i++)
     fprintf(file, "%s\n", getSetupLine(options_setup_tokens, "", i));
 
   fclose(file);
@@ -2686,7 +2698,7 @@ void LoadCustomElementDescriptions()
   SetupFileHash *setup_file_hash;
   int i;
 
-  for (i=0; i<NUM_FILE_ELEMENTS; i++)
+  for (i = 0; i < NUM_FILE_ELEMENTS; i++)
   {
     if (element_info[i].custom_description != NULL)
     {
@@ -2698,7 +2710,7 @@ void LoadCustomElementDescriptions()
   if ((setup_file_hash = loadSetupFileHash(filename)) == NULL)
     return;
 
-  for (i=0; i<NUM_FILE_ELEMENTS; i++)
+  for (i = 0; i < NUM_FILE_ELEMENTS; i++)
   {
     char *token = getStringCat2(element_info[i].token_name, ".name");
     char *value = getHashEntry(setup_file_hash, token);
@@ -2719,8 +2731,8 @@ void LoadSpecialMenuDesignSettings()
   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++)
+  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_auto_parameter_value(image_config_vars[i].token,
@@ -2730,7 +2742,7 @@ void LoadSpecialMenuDesignSettings()
     return;
 
   /* special case: initialize with default values that may be overwritten */
-  for (i=0; i < NUM_SPECIAL_GFX_ARGS; i++)
+  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");
@@ -2745,7 +2757,7 @@ void LoadSpecialMenuDesignSettings()
   }
 
   /* read (and overwrite with) values that may be specified in config file */
-  for (i=0; image_config_vars[i].token != NULL; i++)
+  for (i = 0; image_config_vars[i].token != NULL; i++)
   {
     char *value = getHashEntry(setup_file_hash, image_config_vars[i].token);
 
@@ -2756,3 +2768,624 @@ void LoadSpecialMenuDesignSettings()
 
   freeSetupFileHash(setup_file_hash);
 }
+
+void LoadUserDefinedEditorElementList(int **elements, int *num_elements)
+{
+  char *filename = getEditorSetupFilename();
+  SetupFileList *setup_file_list, *list;
+  SetupFileHash *element_hash;
+  int num_unknown_tokens = 0;
+  int i;
+
+  if ((setup_file_list = loadSetupFileList(filename)) == NULL)
+    return;
+
+  element_hash = newSetupFileHash();
+
+  for (i = 0; i < NUM_FILE_ELEMENTS; i++)
+    setHashEntry(element_hash, element_info[i].token_name, i_to_a(i));
+
+  /* determined size may be larger than needed (due to unknown elements) */
+  *num_elements = 0;
+  for (list = setup_file_list; list != NULL; list = list->next)
+    (*num_elements)++;
+
+  /* add space for up to 3 more elements for padding that may be needed */
+  *num_elements += 3;
+
+  *elements = checked_malloc(*num_elements * sizeof(int));
+
+  *num_elements = 0;
+  for (list = setup_file_list; list != NULL; list = list->next)
+  {
+    char *value = getHashEntry(element_hash, list->token);
+
+    if (value)
+    {
+      (*elements)[(*num_elements)++] = atoi(value);
+    }
+    else
+    {
+      if (num_unknown_tokens == 0)
+      {
+       Error(ERR_RETURN_LINE, "-");
+       Error(ERR_RETURN, "warning: unknown token(s) found in config file:");
+       Error(ERR_RETURN, "- config file: '%s'", filename);
+
+       num_unknown_tokens++;
+      }
+
+      Error(ERR_RETURN, "- token: '%s'", list->token);
+    }
+  }
+
+  if (num_unknown_tokens > 0)
+    Error(ERR_RETURN_LINE, "-");
+
+  while (*num_elements % 4)    /* pad with empty elements, if needed */
+    (*elements)[(*num_elements)++] = EL_EMPTY;
+
+  freeSetupFileList(setup_file_list);
+  freeSetupFileHash(element_hash);
+
+#if 0
+  /* TEST-ONLY */
+  for (i = 0; i < *num_elements; i++)
+    printf("editor: element '%s' [%d]\n",
+          element_info[(*elements)[i]].token_name, (*elements)[i]);
+#endif
+}
+
+static struct MusicFileInfo *get_music_file_info_ext(char *basename, int music,
+                                                    boolean is_sound)
+{
+  SetupFileHash *setup_file_hash = NULL;
+  struct MusicFileInfo tmp_music_file_info, *new_music_file_info;
+  char *filename_music, *filename_prefix, *filename_info;
+  struct
+  {
+    char *token;
+    char **value_ptr;
+  }
+  token_to_value_ptr[] =
+  {
+    { "title_header",  &tmp_music_file_info.title_header       },
+    { "artist_header", &tmp_music_file_info.artist_header      },
+    { "album_header",  &tmp_music_file_info.album_header       },
+    { "year_header",   &tmp_music_file_info.year_header        },
+
+    { "title",         &tmp_music_file_info.title              },
+    { "artist",                &tmp_music_file_info.artist             },
+    { "album",         &tmp_music_file_info.album              },
+    { "year",          &tmp_music_file_info.year               },
+
+    { NULL,            NULL                                    },
+  };
+  int i;
+
+  filename_music = (is_sound ? getCustomSoundFilename(basename) :
+                   getCustomMusicFilename(basename));
+
+  if (filename_music == NULL)
+    return NULL;
+
+  /* ---------- try to replace file extension ---------- */
+
+  filename_prefix = getStringCopy(filename_music);
+  if (strrchr(filename_prefix, '.') != NULL)
+    *strrchr(filename_prefix, '.') = '\0';
+  filename_info = getStringCat2(filename_prefix, ".txt");
+
+#if 0
+  printf("trying to load file '%s'...\n", filename_info);
+#endif
+
+  if (fileExists(filename_info))
+    setup_file_hash = loadSetupFileHash(filename_info);
+
+  free(filename_prefix);
+  free(filename_info);
+
+  if (setup_file_hash == NULL)
+  {
+    /* ---------- try to add file extension ---------- */
+
+    filename_prefix = getStringCopy(filename_music);
+    filename_info = getStringCat2(filename_prefix, ".txt");
+
+#if 0
+    printf("trying to load file '%s'...\n", filename_info);
+#endif
+
+    if (fileExists(filename_info))
+      setup_file_hash = loadSetupFileHash(filename_info);
+
+    free(filename_prefix);
+    free(filename_info);
+  }
+
+  if (setup_file_hash == NULL)
+    return NULL;
+
+  /* ---------- music file info found ---------- */
+
+  memset(&tmp_music_file_info, 0, sizeof(struct MusicFileInfo));
+
+  for (i = 0; token_to_value_ptr[i].token != NULL; i++)
+  {
+    char *value = getHashEntry(setup_file_hash, token_to_value_ptr[i].token);
+
+    *token_to_value_ptr[i].value_ptr =
+      getStringCopy(value != NULL && *value != '\0' ? value : UNKNOWN_NAME);
+  }
+
+  tmp_music_file_info.basename = getStringCopy(basename);
+  tmp_music_file_info.music = music;
+  tmp_music_file_info.is_sound = is_sound;
+
+  new_music_file_info = checked_malloc(sizeof(struct MusicFileInfo));
+  *new_music_file_info = tmp_music_file_info;
+
+  return new_music_file_info;
+}
+
+static struct MusicFileInfo *get_music_file_info(char *basename, int music)
+{
+  return get_music_file_info_ext(basename, music, FALSE);
+}
+
+static struct MusicFileInfo *get_sound_file_info(char *basename, int sound)
+{
+  return get_music_file_info_ext(basename, sound, TRUE);
+}
+
+static boolean music_info_listed_ext(struct MusicFileInfo *list,
+                                    char *basename, boolean is_sound)
+{
+  for (; list != NULL; list = list->next)
+    if (list->is_sound == is_sound && strcmp(list->basename, basename) == 0)
+      return TRUE;
+
+  return FALSE;
+}
+
+static boolean music_info_listed(struct MusicFileInfo *list, char *basename)
+{
+  return music_info_listed_ext(list, basename, FALSE);
+}
+
+static boolean sound_info_listed(struct MusicFileInfo *list, char *basename)
+{
+  return music_info_listed_ext(list, basename, TRUE);
+}
+
+void LoadMusicInfo()
+{
+  char *music_directory = getCustomMusicDirectory();
+  int num_music = getMusicListSize();
+  int num_music_noconf = 0;
+  int num_sounds = getSoundListSize();
+  DIR *dir;
+  struct dirent *dir_entry;
+  struct FileInfo *music, *sound;
+  struct MusicFileInfo *next, **new;
+  int i;
+
+  while (music_file_info != NULL)
+  {
+    next = music_file_info->next;
+
+    checked_free(music_file_info->basename);
+
+    checked_free(music_file_info->title_header);
+    checked_free(music_file_info->artist_header);
+    checked_free(music_file_info->album_header);
+    checked_free(music_file_info->year_header);
+
+    checked_free(music_file_info->title);
+    checked_free(music_file_info->artist);
+    checked_free(music_file_info->album);
+    checked_free(music_file_info->year);
+
+    free(music_file_info);
+
+    music_file_info = next;
+  }
+
+  new = &music_file_info;
+
+#if 0
+  printf("::: num_music == %d\n", num_music);
+#endif
+
+  for (i = 0; i < num_music; i++)
+  {
+    music = getMusicListEntry(i);
+
+#if 0
+    printf("::: %d [%08x]\n", i, music->filename);
+#endif
+
+    if (music->filename == NULL)
+      continue;
+
+    if (strcmp(music->filename, UNDEFINED_FILENAME) == 0)
+      continue;
+
+    /* a configured file may be not recognized as music */
+    if (!FileIsMusic(music->filename))
+      continue;
+
+#if 0
+    printf("::: -> '%s' (configured)\n", music->filename);
+#endif
+
+    if (!music_info_listed(music_file_info, music->filename))
+    {
+      *new = get_music_file_info(music->filename, i);
+      if (*new != NULL)
+       new = &(*new)->next;
+    }
+  }
+
+  if ((dir = opendir(music_directory)) == NULL)
+  {
+    Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
+    return;
+  }
+
+  while ((dir_entry = readdir(dir)) != NULL)   /* loop until last dir entry */
+  {
+    char *basename = dir_entry->d_name;
+    boolean music_already_used = FALSE;
+    int i;
+
+    for (i = 0; i < num_music; i++)
+    {
+      music = getMusicListEntry(i);
+
+      if (music->filename == NULL)
+       continue;
+
+      if (strcmp(basename, music->filename) == 0)
+      {
+       music_already_used = TRUE;
+       break;
+      }
+    }
+
+    if (music_already_used)
+      continue;
+
+    if (!FileIsMusic(basename))
+      continue;
+
+#if 0
+    printf("::: -> '%s' (found in directory)\n", basename);
+#endif
+
+    if (!music_info_listed(music_file_info, basename))
+    {
+      *new = get_music_file_info(basename, MAP_NOCONF_MUSIC(num_music_noconf));
+      if (*new != NULL)
+       new = &(*new)->next;
+    }
+
+    num_music_noconf++;
+  }
+
+  closedir(dir);
+
+  for (i = 0; i < num_sounds; i++)
+  {
+    sound = getSoundListEntry(i);
+
+    if (sound->filename == NULL)
+      continue;
+
+    if (strcmp(sound->filename, UNDEFINED_FILENAME) == 0)
+      continue;
+
+    /* a configured file may be not recognized as sound */
+    if (!FileIsSound(sound->filename))
+      continue;
+
+#if 0
+    printf("::: -> '%s' (configured)\n", sound->filename);
+#endif
+
+    if (!sound_info_listed(music_file_info, sound->filename))
+    {
+      *new = get_sound_file_info(sound->filename, i);
+      if (*new != NULL)
+       new = &(*new)->next;
+    }
+  }
+
+#if 0
+  /* TEST-ONLY */
+  for (next = music_file_info; next != NULL; next = next->next)
+    printf("::: title == '%s'\n", next->title);
+#endif
+}
+
+void add_helpanim_entry(int element, int action, int direction, int delay,
+                       int *num_list_entries)
+{
+  struct HelpAnimInfo *new_list_entry;
+  (*num_list_entries)++;
+
+  helpanim_info =
+    checked_realloc(helpanim_info,
+                   *num_list_entries * sizeof(struct HelpAnimInfo));
+  new_list_entry = &helpanim_info[*num_list_entries - 1];
+
+  new_list_entry->element = element;
+  new_list_entry->action = action;
+  new_list_entry->direction = direction;
+  new_list_entry->delay = delay;
+}
+
+void print_unknown_token(char *filename, char *token, int token_nr)
+{
+  if (token_nr == 0)
+  {
+    Error(ERR_RETURN_LINE, "-");
+    Error(ERR_RETURN, "warning: unknown token(s) found in config file:");
+    Error(ERR_RETURN, "- config file: '%s'", filename);
+  }
+
+  Error(ERR_RETURN, "- token: '%s'", token);
+}
+
+void print_unknown_token_end(int token_nr)
+{
+  if (token_nr > 0)
+    Error(ERR_RETURN_LINE, "-");
+}
+
+void LoadHelpAnimInfo()
+{
+  char *filename = getHelpAnimFilename();
+  SetupFileList *setup_file_list = NULL, *list;
+  SetupFileHash *element_hash, *action_hash, *direction_hash;
+  int num_list_entries = 0;
+  int num_unknown_tokens = 0;
+  int i;
+
+  if (fileExists(filename))
+    setup_file_list = loadSetupFileList(filename);
+
+  if (setup_file_list == NULL)
+  {
+    /* use reliable default values from static configuration */
+    SetupFileList *insert_ptr;
+
+    insert_ptr = setup_file_list =
+      newSetupFileList(helpanim_config[0].token,
+                      helpanim_config[0].value);
+
+    for (i = 1; helpanim_config[i].token; i++)
+      insert_ptr = addListEntry(insert_ptr,
+                               helpanim_config[i].token,
+                               helpanim_config[i].value);
+  }
+
+  element_hash   = newSetupFileHash();
+  action_hash    = newSetupFileHash();
+  direction_hash = newSetupFileHash();
+
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
+    setHashEntry(element_hash, element_info[i].token_name, i_to_a(i));
+
+  for (i = 0; i < NUM_ACTIONS; i++)
+    setHashEntry(action_hash, element_action_info[i].suffix,
+                i_to_a(element_action_info[i].value));
+
+  /* do not store direction index (bit) here, but direction value! */
+  for (i = 0; i < NUM_DIRECTIONS; i++)
+    setHashEntry(direction_hash, element_direction_info[i].suffix,
+                i_to_a(1 << element_direction_info[i].value));
+
+  for (list = setup_file_list; list != NULL; list = list->next)
+  {
+    char *element_token, *action_token, *direction_token;
+    char *element_value, *action_value, *direction_value;
+    int delay = atoi(list->value);
+
+    if (strcmp(list->token, "end") == 0)
+    {
+      add_helpanim_entry(HELPANIM_LIST_NEXT, -1, -1, -1, &num_list_entries);
+
+      continue;
+    }
+
+    /* first try to break element into element/action/direction parts;
+       if this does not work, also accept combined "element[.act][.dir]"
+       elements (like "dynamite.active"), which are unique elements */
+
+    if (strchr(list->token, '.') == NULL)      /* token contains no '.' */
+    {
+      element_value = getHashEntry(element_hash, list->token);
+      if (element_value != NULL)       /* element found */
+       add_helpanim_entry(atoi(element_value), -1, -1, delay,
+                          &num_list_entries);
+      else
+      {
+       /* no further suffixes found -- this is not an element */
+       print_unknown_token(filename, list->token, num_unknown_tokens++);
+      }
+
+      continue;
+    }
+
+    /* token has format "<prefix>.<something>" */
+
+    action_token = strchr(list->token, '.');   /* suffix may be action ... */
+    direction_token = action_token;            /* ... or direction */
+
+    element_token = getStringCopy(list->token);
+    *strchr(element_token, '.') = '\0';
+
+    element_value = getHashEntry(element_hash, element_token);
+
+    if (element_value == NULL)         /* this is no element */
+    {
+      element_value = getHashEntry(element_hash, list->token);
+      if (element_value != NULL)       /* combined element found */
+       add_helpanim_entry(atoi(element_value), -1, -1, delay,
+                          &num_list_entries);
+      else
+       print_unknown_token(filename, list->token, num_unknown_tokens++);
+
+      free(element_token);
+
+      continue;
+    }
+
+    action_value = getHashEntry(action_hash, action_token);
+
+    if (action_value != NULL)          /* action found */
+    {
+      add_helpanim_entry(atoi(element_value), atoi(action_value), -1, delay,
+                   &num_list_entries);
+
+      free(element_token);
+
+      continue;
+    }
+
+    direction_value = getHashEntry(direction_hash, direction_token);
+
+    if (direction_value != NULL)       /* direction found */
+    {
+      add_helpanim_entry(atoi(element_value), -1, atoi(direction_value), delay,
+                        &num_list_entries);
+
+      free(element_token);
+
+      continue;
+    }
+
+    if (strchr(action_token + 1, '.') == NULL)
+    {
+      /* no further suffixes found -- this is not an action nor direction */
+
+      element_value = getHashEntry(element_hash, list->token);
+      if (element_value != NULL)       /* combined element found */
+       add_helpanim_entry(atoi(element_value), -1, -1, delay,
+                          &num_list_entries);
+      else
+       print_unknown_token(filename, list->token, num_unknown_tokens++);
+
+      free(element_token);
+
+      continue;
+    }
+
+    /* token has format "<prefix>.<suffix>.<something>" */
+
+    direction_token = strchr(action_token + 1, '.');
+
+    action_token = getStringCopy(action_token);
+    *strchr(action_token + 1, '.') = '\0';
+
+    action_value = getHashEntry(action_hash, action_token);
+
+    if (action_value == NULL)          /* this is no action */
+    {
+      element_value = getHashEntry(element_hash, list->token);
+      if (element_value != NULL)       /* combined element found */
+       add_helpanim_entry(atoi(element_value), -1, -1, delay,
+                          &num_list_entries);
+      else
+       print_unknown_token(filename, list->token, num_unknown_tokens++);
+
+      free(element_token);
+      free(action_token);
+
+      continue;
+    }
+
+    direction_value = getHashEntry(direction_hash, direction_token);
+
+    if (direction_value != NULL)       /* direction found */
+    {
+      add_helpanim_entry(atoi(element_value), atoi(action_value),
+                        atoi(direction_value), delay, &num_list_entries);
+
+      free(element_token);
+      free(action_token);
+
+      continue;
+    }
+
+    /* this is no direction */
+
+    element_value = getHashEntry(element_hash, list->token);
+    if (element_value != NULL)         /* combined element found */
+      add_helpanim_entry(atoi(element_value), -1, -1, delay,
+                        &num_list_entries);
+    else
+      print_unknown_token(filename, list->token, num_unknown_tokens++);
+
+    free(element_token);
+    free(action_token);
+  }
+
+  print_unknown_token_end(num_unknown_tokens);
+
+  add_helpanim_entry(HELPANIM_LIST_NEXT, -1, -1, -1, &num_list_entries);
+  add_helpanim_entry(HELPANIM_LIST_END,  -1, -1, -1, &num_list_entries);
+
+  freeSetupFileList(setup_file_list);
+  freeSetupFileHash(element_hash);
+  freeSetupFileHash(action_hash);
+  freeSetupFileHash(direction_hash);
+
+#if 0
+  /* TEST ONLY */
+  for (i = 0; i < num_list_entries; i++)
+    printf("::: %d, %d, %d => %d\n",
+          helpanim_info[i].element,
+          helpanim_info[i].action,
+          helpanim_info[i].direction,
+          helpanim_info[i].delay);
+#endif
+}
+
+void LoadHelpTextInfo()
+{
+  char *filename = getHelpTextFilename();
+  int i;
+
+  if (helptext_info != NULL)
+  {
+    freeSetupFileHash(helptext_info);
+    helptext_info = NULL;
+  }
+
+  if (fileExists(filename))
+    helptext_info = loadSetupFileHash(filename);
+
+  if (helptext_info == NULL)
+  {
+    /* use reliable default values from static configuration */
+    helptext_info = newSetupFileHash();
+
+    for (i = 0; helptext_config[i].token; i++)
+      setHashEntry(helptext_info,
+                  helptext_config[i].token,
+                  helptext_config[i].value);
+  }
+
+#if 0
+  /* TEST ONLY */
+  BEGIN_HASH_ITERATION(helptext_info, itr)
+  {
+    printf("::: '%s' => '%s'\n",
+          HASH_ITERATION_TOKEN(itr), HASH_ITERATION_VALUE(itr));
+  }
+  END_HASH_ITERATION(hash, itr)
+#endif
+}
index 1ae371db1f3dee3ce13f253c3bdf77e64f697903..aa9c03e3c0d50e02cf9421b99dec9759a2f5f945 100644 (file)
@@ -29,6 +29,7 @@ void DumpLevel(struct LevelInfo *);
 
 void LoadTapeFromFilename(char *);
 void LoadTape(int);
+void LoadSolutionTape(int);
 void SaveTape(int);
 void DumpTape(struct TapeInfo *);
 
@@ -40,5 +41,9 @@ void SaveSetup();
 
 void LoadCustomElementDescriptions();
 void LoadSpecialMenuDesignSettings();
+void LoadUserDefinedEditorElementList(int **, int *);
+void LoadMusicInfo();
+void LoadHelpAnimInfo();
+void LoadHelpTextInfo();
 
 #endif /* FILES_H */
index 71013bf598ebd1a491c8cc3a52f2311f0db2fdbe..05e65026508d942835b1e28bd9c464b7fa2d2e8c 100644 (file)
                                        Feld[x][y] == EL_EXIT_OPEN ||   \
                                        Feld[x][y] == EL_ACID))
 
+#define MAZE_RUNNER_CAN_ENTER_FIELD(x, y)                              \
+               (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) ||                \
+                                       IS_FOOD_DARK_YAMYAM(Feld[x][y])))
+
 #define MOLE_CAN_ENTER_FIELD(x, y, condition)                          \
                (IN_LEV_FIELD(x, y) && (IS_FREE(x, y) || (condition)))
 
@@ -182,12 +186,14 @@ static boolean CheckTriggeredElementChange(int, int, int, int);
 static boolean CheckElementSideChange(int, int, int, int, int, int);
 static boolean CheckElementChange(int, 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 PlayLevelSound(int, int, int);
+static void PlayLevelSoundNearest(int, int, int);
+static void PlayLevelSoundAction(int, int, int);
+static void PlayLevelSoundElementAction(int, int, int, int);
+static void PlayLevelSoundElementActionIfLoop(int, int, int, int);
+static void PlayLevelSoundActionIfLoop(int, int, int);
+static void StopLevelSoundActionIfLoop(int, int, int);
+static void PlayLevelMusic();
 
 static void MapGameButtons();
 static void HandleGameButtons(struct GadgetInfo *);
@@ -754,8 +760,8 @@ void DrawGameDoorValues()
 {
   int i, j;
 
-  for (i=0; i<MAX_PLAYERS; i++)
-    for (j=0; j<4; j++)
+  for (i = 0; i < MAX_PLAYERS; i++)
+    for (j = 0; j < 4; j++)
       if (stored_player[i].key[j])
        DrawMiniGraphicExt(drawto, DX_KEYS + j * MINI_TILEX, DY_KEYS,
                           el2edimg(EL_KEY_1 + j));
@@ -818,7 +824,7 @@ static void InitGameEngine()
   /* ---------- initialize changing elements ------------------------------- */
 
   /* initialize changing elements information */
-  for (i=0; i < MAX_NUM_ELEMENTS; i++)
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
     struct ElementInfo *ei = &element_info[i];
 
@@ -834,7 +840,7 @@ static void InitGameEngine()
     }
 
     ei->change_events = CE_BITMASK_DEFAULT;
-    for (j=0; j < NUM_CHANGE_EVENTS; j++)
+    for (j = 0; j < NUM_CHANGE_EVENTS; j++)
     {
       ei->event_page_nr[j] = 0;
       ei->event_page[j] = &ei->change_page[0];
@@ -842,7 +848,7 @@ static void InitGameEngine()
   }
 
   /* add changing elements from pre-defined list */
-  for (i=0; change_delay_list[i].element != EL_UNDEFINED; i++)
+  for (i = 0; change_delay_list[i].element != EL_UNDEFINED; i++)
   {
     struct ChangingElementInfo *ch_delay = &change_delay_list[i];
     struct ElementInfo *ei = &element_info[ch_delay->element];
@@ -859,16 +865,16 @@ static void InitGameEngine()
 
 #if 1
   /* add change events from custom element configuration */
-  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+  for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
   {
     struct ElementInfo *ei = &element_info[EL_CUSTOM_START + i];
 
-    for (j=0; j < ei->num_change_pages; j++)
+    for (j = 0; j < ei->num_change_pages; j++)
     {
       if (!ei->change_page[j].can_change)
        continue;
 
-      for (k=0; k < NUM_CHANGE_EVENTS; k++)
+      for (k = 0; k < NUM_CHANGE_EVENTS; k++)
       {
        /* only add event page for the first page found with this event */
        if (ei->change_page[j].events & CH_EVENT_BIT(k) &&
@@ -885,7 +891,7 @@ static void InitGameEngine()
 #else
 
   /* add change events from custom element configuration */
-  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+  for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
   {
     int element = EL_CUSTOM_START + i;
 
@@ -898,16 +904,16 @@ static void InitGameEngine()
   /* ---------- initialize trigger events ---------------------------------- */
 
   /* initialize trigger events information */
-  for (i=0; i<MAX_NUM_ELEMENTS; i++)
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
     trigger_events[i] = EP_BITMASK_DEFAULT;
 
 #if 1
   /* add trigger events from element change event properties */
-  for (i=0; i<MAX_NUM_ELEMENTS; i++)
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
     struct ElementInfo *ei = &element_info[i];
 
-    for (j=0; j < ei->num_change_pages; j++)
+    for (j = 0; j < ei->num_change_pages; j++)
     {
       if (!ei->change_page[j].can_change)
        continue;
@@ -922,7 +928,7 @@ static void InitGameEngine()
   }
 #else
   /* add trigger events from element change event properties */
-  for (i=0; i<MAX_NUM_ELEMENTS; i++)
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
     if (HAS_CHANGE_EVENT(i, CE_BY_OTHER_ACTION))
       trigger_events[element_info[i].change->trigger_element] |=
        element_info[i].change->events;
@@ -931,7 +937,7 @@ static void InitGameEngine()
   /* ---------- initialize push delay -------------------------------------- */
 
   /* initialize push delay values to default */
-  for (i=0; i<MAX_NUM_ELEMENTS; i++)
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
     if (!IS_CUSTOM_ELEMENT(i))
     {
@@ -941,7 +947,7 @@ static void InitGameEngine()
   }
 
   /* set push delay value for certain elements from pre-defined list */
-  for (i=0; push_delay_list[i].element != EL_UNDEFINED; i++)
+  for (i = 0; push_delay_list[i].element != EL_UNDEFINED; i++)
   {
     int e = push_delay_list[i].element;
 
@@ -952,12 +958,12 @@ static void InitGameEngine()
   /* ---------- initialize move stepsize ----------------------------------- */
 
   /* initialize move stepsize values to default */
-  for (i=0; i<MAX_NUM_ELEMENTS; i++)
+  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++)
+  for (i = 0; move_stepsize_list[i].element != EL_UNDEFINED; i++)
   {
     int e = move_stepsize_list[i].element;
 
@@ -967,12 +973,12 @@ static void InitGameEngine()
   /* ---------- initialize gem count --------------------------------------- */
 
   /* initialize gem count values for each element */
-  for (i=0; i<MAX_NUM_ELEMENTS; i++)
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
     if (!IS_CUSTOM_ELEMENT(i))
       element_info[i].collect_count = 0;
 
   /* add gem count values for all elements from pre-defined list */
-  for (i=0; collect_count_list[i].element != EL_UNDEFINED; i++)
+  for (i = 0; collect_count_list[i].element != EL_UNDEFINED; i++)
     element_info[collect_count_list[i].element].collect_count =
       collect_count_list[i].count;
 }
@@ -991,7 +997,7 @@ void InitGame()
   boolean emulate_bd = TRUE;   /* unless non-BOULDERDASH elements found */
   boolean emulate_sb = TRUE;   /* unless non-SOKOBAN     elements found */
   boolean emulate_sp = TRUE;   /* unless non-SUPAPLEX    elements found */
-  int i, j, x, y;
+  int i, j, k, x, y;
 
   InitGameEngine();
 
@@ -1008,7 +1014,7 @@ void InitGame()
   /* don't play tapes over network */
   network_playing = (options.network && !tape.playing);
 
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
   {
     struct PlayerInfo *player = &stored_player[i];
 
@@ -1028,7 +1034,7 @@ void InitGame()
     player->lights_still_needed = 0;
     player->friends_still_needed = 0;
 
-    for (j=0; j<4; j++)
+    for (j = 0; j < 4; j++)
       player->key[j] = FALSE;
 
     player->dynabomb_count = 0;
@@ -1048,6 +1054,8 @@ void InitGame()
 
     player->actual_frame_counter = 0;
 
+    player->step_counter = 0;
+
     player->last_move_dir = MV_NO_MOVING;
 
     player->is_waiting = FALSE;
@@ -1058,6 +1066,53 @@ void InitGame()
     player->is_pushing = FALSE;
     player->is_switching = FALSE;
 
+    player->is_bored = FALSE;
+    player->is_sleeping = FALSE;
+
+    player->frame_counter_bored = -1;
+    player->frame_counter_sleeping = -1;
+
+    player->anim_delay_counter = 0;
+    player->post_delay_counter = 0;
+
+    player->action_waiting = ACTION_DEFAULT;
+    player->last_action_waiting = ACTION_DEFAULT;
+    player->special_action_bored = ACTION_DEFAULT;
+    player->special_action_sleeping = ACTION_DEFAULT;
+
+    player->num_special_action_bored = 0;
+    player->num_special_action_sleeping = 0;
+
+    /* determine number of special actions for bored and sleeping animation */
+    for (j = ACTION_BORING_1; j <= ACTION_BORING_LAST; j++)
+    {
+      boolean found = FALSE;
+
+      for (k = 0; k < NUM_DIRECTIONS; k++)
+       if (el_act_dir2img(player->element_nr, j, k) !=
+           el_act_dir2img(player->element_nr, ACTION_DEFAULT, k))
+         found = TRUE;
+
+      if (found)
+       player->num_special_action_bored++;
+      else
+       break;
+    }
+    for (j = ACTION_SLEEPING_1; j <= ACTION_SLEEPING_LAST; j++)
+    {
+      boolean found = FALSE;
+
+      for (k = 0; k < NUM_DIRECTIONS; k++)
+       if (el_act_dir2img(player->element_nr, j, k) !=
+           el_act_dir2img(player->element_nr, ACTION_DEFAULT, k))
+         found = TRUE;
+
+      if (found)
+       player->num_special_action_sleeping++;
+      else
+       break;
+    }
+
     player->switch_x = -1;
     player->switch_y = -1;
 
@@ -1119,18 +1174,18 @@ void InitGame()
 
   game.envelope_active = FALSE;
 
-  for (i=0; i<4; i++)
+  for (i = 0; i < 4; i++)
   {
     game.belt_dir[i] = MV_NO_MOVING;
     game.belt_dir_nr[i] = 3;           /* not moving, next moving left */
   }
 
-  for (i=0; i<MAX_NUM_AMOEBA; i++)
+  for (i = 0; i < MAX_NUM_AMOEBA; i++)
     AmoebaCnt[i] = AmoebaCnt2[i] = 0;
 
-  for (x=0; x<lev_fieldx; x++)
+  for (x = 0; x < lev_fieldx; x++)
   {
-    for (y=0; y<lev_fieldy; y++)
+    for (y = 0; y < lev_fieldy; y++)
     {
       Feld[x][y] = level.field[x][y];
       MovPos[x][y] = MovDir[x][y] = MovDelay[x][y] = 0;
@@ -1149,6 +1204,9 @@ void InitGame()
       ExplodePhase[x][y] = 0;
       ExplodeField[x][y] = EX_NO_EXPLOSION;
 
+      RunnerVisit[x][y] = 0;
+      PlayerVisit[x][y] = 0;
+
       GfxFrame[x][y] = 0;
       GfxRandom[x][y] = INIT_GFX_RANDOM();
       GfxElement[x][y] = EL_UNDEFINED;
@@ -1157,9 +1215,9 @@ void InitGame()
     }
   }
 
-  for(y=0; y<lev_fieldy; y++)
+  for (y = 0; y < lev_fieldy; y++)
   {
-    for(x=0; x<lev_fieldx; x++)
+    for (x = 0; x < lev_fieldx; x++)
     {
       if (emulate_bd && !IS_BD_ELEMENT(Feld[x][y]))
        emulate_bd = FALSE;
@@ -1179,18 +1237,18 @@ void InitGame()
                    emulate_sp ? EMU_SUPAPLEX : EMU_NONE);
 
   /* correct non-moving belts to start moving left */
-  for (i=0; i<4; i++)
+  for (i = 0; i < 4; i++)
     if (game.belt_dir[i] == MV_NO_MOVING)
       game.belt_dir_nr[i] = 3;         /* not moving, next moving left */
 
   /* check if any connected player was not found in playfield */
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
   {
     struct PlayerInfo *player = &stored_player[i];
 
     if (player->connected && !player->present)
     {
-      for (j=0; j<MAX_PLAYERS; j++)
+      for (j = 0; j < MAX_PLAYERS; j++)
       {
        struct PlayerInfo *some_player = &stored_player[j];
        int jx = some_player->jx, jy = some_player->jy;
@@ -1216,7 +1274,7 @@ void InitGame()
   {
     /* when playing a tape, eliminate all players who do not participate */
 
-    for (i=0; i<MAX_PLAYERS; i++)
+    for (i = 0; i < MAX_PLAYERS; i++)
     {
       if (stored_player[i].active && !tape.player_participates[i])
       {
@@ -1233,11 +1291,11 @@ void InitGame()
   {
     /* when in single player mode, eliminate all but the first active player */
 
-    for (i=0; i<MAX_PLAYERS; i++)
+    for (i = 0; i < MAX_PLAYERS; i++)
     {
       if (stored_player[i].active)
       {
-       for (j=i+1; j<MAX_PLAYERS; j++)
+       for (j = i + 1; j < MAX_PLAYERS; j++)
        {
          if (stored_player[j].active)
          {
@@ -1256,14 +1314,14 @@ void InitGame()
   /* when recording the game, store which players take part in the game */
   if (tape.recording)
   {
-    for (i=0; i<MAX_PLAYERS; i++)
+    for (i = 0; i < MAX_PLAYERS; i++)
       if (stored_player[i].active)
        tape.player_participates[i] = TRUE;
   }
 
   if (options.debug)
   {
-    for (i=0; i<MAX_PLAYERS; i++)
+    for (i = 0; i < MAX_PLAYERS; i++)
     {
       struct PlayerInfo *player = &stored_player[i];
 
@@ -1306,7 +1364,7 @@ void InitGame()
     int found_rating = 0;
     int found_element = EL_UNDEFINED;
 
-    for(y=0; y < lev_fieldy; y++) for(x=0; x < lev_fieldx; x++)
+    for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++)
     {
       int element = Feld[x][y];
       int content;
@@ -1318,7 +1376,7 @@ void InitGame()
 
       if (CAN_CHANGE(element))
       {
-       for (i=0; i < element_info[element].num_change_pages; i++)
+       for (i = 0; i < element_info[element].num_change_pages; i++)
        {
          content = element_info[element].change_page[i].target_element;
          is_player = ELEM_IS_PLAYER(content);
@@ -1334,7 +1392,7 @@ void InitGame()
        }
       }
 
-      for(yy=0; yy < 3; yy++) for(xx=0; xx < 3; xx++)
+      for (yy = 0; yy < 3; yy++) for (xx = 0; xx < 3; xx++)
       {
        content = element_info[element].content[xx][yy];
        is_player = ELEM_IS_PLAYER(content);
@@ -1351,7 +1409,7 @@ void InitGame()
        if (!CAN_CHANGE(element))
          continue;
 
-       for (i=0; i < element_info[element].num_change_pages; i++)
+       for (i = 0; i < element_info[element].num_change_pages; i++)
        {
          content = element_info[element].change_page[i].content[xx][yy];
          is_player = ELEM_IS_PLAYER(content);
@@ -1449,17 +1507,22 @@ void InitGame()
   OpenDoor(DOOR_OPEN_ALL);
 
   PlaySoundStereo(SND_GAME_STARTING, SOUND_MIDDLE);
+
   if (setup.sound_music)
-    PlayMusic(level_nr);
+    PlayLevelMusic();
 
   KeyboardAutoRepeatOffUnlessAutoplay();
 
   if (options.debug)
   {
-    for (i=0; i<4; i++)
+    for (i = 0; i < 4; i++)
       printf("Player %d %sactive.\n",
             i + 1, (stored_player[i].active ? "" : "not "));
   }
+
+#if 0
+  printf("::: starting game [%d]\n", FrameCounter);
+#endif
 }
 
 void InitMovDir(int x, int y)
@@ -1555,7 +1618,7 @@ void InitMovDir(int x, int y)
        else if (element_info[element].move_pattern == MV_ALONG_LEFT_SIDE ||
                 element_info[element].move_pattern == MV_ALONG_RIGHT_SIDE)
        {
-         for (i=0; i<4; i++)
+         for (i = 0; i < 4; i++)
          {
            int x1 = x + xy[i][0];
            int y1 = y + xy[i][1];
@@ -1582,7 +1645,7 @@ void InitMovDir(int x, int y)
            element != EL_BD_FIREFLY)
          break;
 
-       for (i=0; i<4; i++)
+       for (i = 0; i < 4; i++)
        {
          int x1 = x + xy[i][0];
          int y1 = y + xy[i][1];
@@ -1616,7 +1679,7 @@ void InitAmoebaNr(int x, int y)
 
   if (group_nr == 0)
   {
-    for (i=1; i<MAX_NUM_AMOEBA; i++)
+    for (i = 1; i < MAX_NUM_AMOEBA; i++)
     {
       if (AmoebaCnt[i] == 0)
       {
@@ -1713,7 +1776,7 @@ void GameWon()
     Feld[ExitX][ExitY] = (element == EL_EXIT_OPEN ? EL_EXIT_CLOSING :
                          EL_SP_EXIT_CLOSING);
 
-    PlaySoundLevelElementAction(ExitX, ExitY, element, ACTION_CLOSING);
+    PlayLevelSoundElementAction(ExitX, ExitY, element, ACTION_CLOSING);
   }
 
   /* Hero disappears */
@@ -1777,7 +1840,7 @@ int NewHiScore()
       local_player->score < highscore[MAX_SCORE_ENTRIES - 1].Score) 
     return -1;
 
-  for (k=0; k<MAX_SCORE_ENTRIES; k++) 
+  for (k = 0; k < MAX_SCORE_ENTRIES; k++) 
   {
     if (local_player->score > highscore[k].Score)
     {
@@ -1788,14 +1851,14 @@ int NewHiScore()
        int m = MAX_SCORE_ENTRIES - 1;
 
 #ifdef ONE_PER_NAME
-       for (l=k; l<MAX_SCORE_ENTRIES; l++)
+       for (l = k; l < MAX_SCORE_ENTRIES; l++)
          if (!strcmp(setup.player_name, highscore[l].Name))
            m = l;
        if (m == k)     /* player's new highscore overwrites his old one */
          goto put_into_list;
 #endif
 
-       for (l=m; l>k; l--)
+       for (l = m; l > k; l--)
        {
          strcpy(highscore[l].Name, highscore[l - 1].Name);
          highscore[l].Score = highscore[l - 1].Score;
@@ -2050,14 +2113,14 @@ void CheckDynamite(int x, int y)
     if (MovDelay[x][y] != 0)
     {
       DrawDynamite(x, y);
-      PlaySoundLevelActionIfLoop(x, y, ACTION_ACTIVE);
+      PlayLevelSoundActionIfLoop(x, y, ACTION_ACTIVE);
 
       return;
     }
   }
 
 #if 1
-  StopSoundLevelActionIfLoop(x, y, ACTION_ACTIVE);
+  StopLevelSoundActionIfLoop(x, y, ACTION_ACTIVE);
 #else
   if (Feld[x][y] == EL_DYNAMITE_ACTIVE ||
       Feld[x][y] == EL_SP_DISK_RED_ACTIVE)
@@ -2170,7 +2233,7 @@ void Explode(int ex, int ey, int phase, int mode)
 #endif
 
     if (mode == EX_NORMAL || mode == EX_CENTER)
-      PlaySoundLevelAction(ex, ey, ACTION_EXPLODING);
+      PlayLevelSoundAction(ex, ey, ACTION_EXPLODING);
 
     /* remove things displayed in background while burning dynamite */
     if (Back[ex][ey] != EL_EMPTY && !IS_INDESTRUCTIBLE(Back[ex][ey]))
@@ -2184,7 +2247,7 @@ void Explode(int ex, int ey, int phase, int mode)
       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;
@@ -2504,9 +2567,9 @@ void DynaExplode(int ex, int ey)
 
   Explode(ex, ey, EX_PHASE_START, EX_CENTER);
 
-  for (i=0; i<4; i++)
+  for (i = 0; i < 4; i++)
   {
-    for (j=1; j<=dynabomb_size; j++)
+    for (j = 1; j <= dynabomb_size; j++)
     {
       int x = ex + j * xy[i % 4][0];
       int y = ey + j * xy[i % 4][1];
@@ -2555,12 +2618,12 @@ void Bang(int x, int y)
 
 #if 0
 #if 1
-  PlaySoundLevelAction(x, y, ACTION_EXPLODING);
+  PlayLevelSoundAction(x, y, ACTION_EXPLODING);
 #else
   if (game.emulation == EMU_SUPAPLEX)
-    PlaySoundLevel(x, y, SND_SP_ELEMENT_EXPLODING);
+    PlayLevelSound(x, y, SND_SP_ELEMENT_EXPLODING);
   else
-    PlaySoundLevel(x, y, SND_ELEMENT_EXPLODING);
+    PlayLevelSound(x, y, SND_ELEMENT_EXPLODING);
 #endif
 #endif
 
@@ -2618,7 +2681,7 @@ void SplashAcid(int x, int y)
   if (element != EL_ACID_SPLASH_LEFT &&
       element != EL_ACID_SPLASH_RIGHT)
   {
-    PlaySoundLevel(x, y, SND_ACID_SPLASHING);
+    PlayLevelSound(x, y, SND_ACID_SPLASHING);
 
     if (IN_LEV_FIELD(x-1, y) && IS_FREE(x-1, y) &&
        (!IN_LEV_FIELD(x-1, y-1) ||
@@ -2652,11 +2715,11 @@ static void InitBeltMovement()
   int x, y, i, j;
 
   /* set frame order for belt animation graphic according to belt direction */
-  for (i=0; i<4; i++)
+  for (i = 0; i < 4; i++)
   {
     int belt_nr = i;
 
-    for (j=0; j<3; j++)
+    for (j = 0; j < 3; j++)
     {
       int element = belt_base_active_element[belt_nr] + j;
       int graphic = el2img(element);
@@ -2668,13 +2731,13 @@ static void InitBeltMovement()
     }
   }
 
-  for(y=0; y<lev_fieldy; y++)
+  for (y = 0; y < lev_fieldy; y++)
   {
-    for(x=0; x<lev_fieldx; x++)
+    for (x = 0; x < lev_fieldx; x++)
     {
       int element = Feld[x][y];
 
-      for (i=0; i<4; i++)
+      for (i = 0; i < 4; i++)
       {
        if (IS_BELT(element) && game.belt_dir[i] != MV_NO_MOVING)
        {
@@ -2740,7 +2803,7 @@ static void ToggleBeltSwitch(int x, int y)
     belt_dir_nr = 1;
 
   /* set frame order for belt animation graphic according to belt direction */
-  for (i=0; i<3; i++)
+  for (i = 0; i < 3; i++)
   {
     int element = belt_base_active_element[belt_nr] + i;
     int graphic = el2img(element);
@@ -2751,9 +2814,9 @@ static void ToggleBeltSwitch(int x, int y)
       graphic_info[graphic].anim_mode |=  ANIM_REVERSE;
   }
 
-  for (yy=0; yy<lev_fieldy; yy++)
+  for (yy = 0; yy < lev_fieldy; yy++)
   {
-    for (xx=0; xx<lev_fieldx; xx++)
+    for (xx = 0; xx < lev_fieldx; xx++)
     {
       int element = Feld[xx][yy];
 
@@ -2801,9 +2864,9 @@ static void ToggleSwitchgateSwitch(int x, int y)
 
   game.switchgate_pos = !game.switchgate_pos;
 
-  for (yy=0; yy<lev_fieldy; yy++)
+  for (yy = 0; yy < lev_fieldy; yy++)
   {
-    for (xx=0; xx<lev_fieldx; xx++)
+    for (xx = 0; xx < lev_fieldx; xx++)
     {
       int element = Feld[xx][yy];
 
@@ -2818,9 +2881,9 @@ static void ToggleSwitchgateSwitch(int x, int y)
       {
        Feld[xx][yy] = EL_SWITCHGATE_CLOSING;
 #if 1
-       PlaySoundLevelAction(xx, yy, ACTION_CLOSING);
+       PlayLevelSoundAction(xx, yy, ACTION_CLOSING);
 #else
-       PlaySoundLevel(xx, yy, SND_SWITCHGATE_CLOSING);
+       PlayLevelSound(xx, yy, SND_SWITCHGATE_CLOSING);
 #endif
       }
       else if (element == EL_SWITCHGATE_CLOSED ||
@@ -2828,9 +2891,9 @@ static void ToggleSwitchgateSwitch(int x, int y)
       {
        Feld[xx][yy] = EL_SWITCHGATE_OPENING;
 #if 1
-       PlaySoundLevelAction(xx, yy, ACTION_OPENING);
+       PlayLevelSoundAction(xx, yy, ACTION_OPENING);
 #else
-       PlaySoundLevel(xx, yy, SND_SWITCHGATE_OPENING);
+       PlayLevelSound(xx, yy, SND_SWITCHGATE_OPENING);
 #endif
       }
     }
@@ -2857,9 +2920,9 @@ static void RedrawAllLightSwitchesAndInvisibleElements()
 {
   int x, y;
 
-  for (y=0; y<lev_fieldy; y++)
+  for (y = 0; y < lev_fieldy; y++)
   {
-    for (x=0; x<lev_fieldx; x++)
+    for (x = 0; x < lev_fieldx; x++)
     {
       int element = Feld[x][y];
 
@@ -2914,9 +2977,9 @@ static void ActivateTimegateSwitch(int x, int y)
 
   game.timegate_time_left = level.time_timegate * FRAMES_PER_SECOND;
 
-  for (yy=0; yy<lev_fieldy; yy++)
+  for (yy = 0; yy < lev_fieldy; yy++)
   {
-    for (xx=0; xx<lev_fieldx; xx++)
+    for (xx = 0; xx < lev_fieldx; xx++)
     {
       int element = Feld[xx][yy];
 
@@ -2924,7 +2987,7 @@ static void ActivateTimegateSwitch(int x, int y)
          element == EL_TIMEGATE_CLOSING)
       {
        Feld[xx][yy] = EL_TIMEGATE_OPENING;
-       PlaySoundLevel(xx, yy, SND_TIMEGATE_OPENING);
+       PlayLevelSound(xx, yy, SND_TIMEGATE_OPENING);
       }
 
       /*
@@ -3014,12 +3077,12 @@ void Impact(int x, int y)
   else if (impact && element == EL_PEARL)
   {
     Feld[x][y] = EL_PEARL_BREAKING;
-    PlaySoundLevel(x, y, SND_PEARL_BREAKING);
+    PlayLevelSound(x, y, SND_PEARL_BREAKING);
     return;
   }
   else if (impact && CheckElementChange(x, y, element, CE_IMPACT))
   {
-    PlaySoundLevelElementAction(x, y, element, ACTION_IMPACT);
+    PlayLevelSoundElementAction(x, y, element, ACTION_IMPACT);
 
     return;
   }
@@ -3052,15 +3115,15 @@ void Impact(int x, int y)
         EL_BD_MAGIC_WALL_ACTIVE);
 
       /* activate magic wall / mill */
-      for (yy=0; yy<lev_fieldy; yy++)
-       for (xx=0; xx<lev_fieldx; xx++)
+      for (yy = 0; yy < lev_fieldy; yy++)
+       for (xx = 0; xx < lev_fieldx; xx++)
          if (Feld[xx][yy] == smashed)
            Feld[xx][yy] = activated_magic_wall;
 
       game.magic_wall_time_left = level.time_magic_wall * FRAMES_PER_SECOND;
       game.magic_wall_active = TRUE;
 
-      PlaySoundLevel(x, y, (smashed == EL_MAGIC_WALL ?
+      PlayLevelSound(x, y, (smashed == EL_MAGIC_WALL ?
                            SND_MAGIC_WALL_ACTIVATING :
                            SND_BD_MAGIC_WALL_ACTIVATING));
     }
@@ -3124,20 +3187,20 @@ void Impact(int x, int y)
        else if (smashed == EL_NUT)
        {
          Feld[x][y + 1] = EL_NUT_BREAKING;
-         PlaySoundLevel(x, y, SND_NUT_BREAKING);
+         PlayLevelSound(x, y, SND_NUT_BREAKING);
          RaiseScoreElement(EL_NUT);
          return;
        }
        else if (smashed == EL_PEARL)
        {
          Feld[x][y + 1] = EL_PEARL_BREAKING;
-         PlaySoundLevel(x, y, SND_PEARL_BREAKING);
+         PlayLevelSound(x, y, SND_PEARL_BREAKING);
          return;
        }
        else if (smashed == EL_DIAMOND)
        {
          Feld[x][y + 1] = EL_DIAMOND_BREAKING;
-         PlaySoundLevel(x, y, SND_DIAMOND_BREAKING);
+         PlayLevelSound(x, y, SND_DIAMOND_BREAKING);
          return;
        }
        else if (IS_BELT_SWITCH(smashed))
@@ -3177,16 +3240,16 @@ void Impact(int x, int y)
        Feld[x][y + 1] == EL_BD_MAGIC_WALL_ACTIVE))
   {
     if (Feld[x][y + 1] == EL_MAGIC_WALL_ACTIVE)
-      PlaySoundLevel(x, y, SND_MAGIC_WALL_FILLING);
+      PlayLevelSound(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);
+      PlayLevelSound(x, y, SND_BD_MAGIC_WALL_FILLING);
 
     return;
   }
 
   /* play sound of object that hits the ground */
   if (lastline || object_hit)
-    PlaySoundLevelElementAction(x, y, element, ACTION_IMPACT);
+    PlayLevelSoundElementAction(x, y, element, ACTION_IMPACT);
 }
 
 inline static void TurnRoundExt(int x, int y)
@@ -3221,6 +3284,8 @@ inline static void TurnRoundExt(int x, int y)
   };
 
   int element = Feld[x][y];
+  int move_pattern = element_info[element].move_pattern;
+
   int old_move_dir = MovDir[x][y];
   int left_dir  = turn[old_move_dir].left;
   int right_dir = turn[old_move_dir].right;
@@ -3388,6 +3453,11 @@ inline static void TurnRoundExt(int x, int y)
     int rnd_value = 24;
     int rnd = RND(rnd_value);
 
+#if 0
+    if (FrameCounter < 1 && x == 0 && y == 29)
+      printf(":2: %d/%d: %d [%d]\n", x, y, MovDir[x][y], FrameCounter);
+#endif
+
     if (can_move_on && rnd > rnd_value / 8)
       MovDir[x][y] = old_move_dir;
     else if (can_turn_left && can_turn_right)
@@ -3402,8 +3472,25 @@ inline static void TurnRoundExt(int x, int y)
     xx = x + move_xy[MovDir[x][y]].x;
     yy = y + move_xy[MovDir[x][y]].y;
 
+#if 0
+    if (FrameCounter < 1 && x == 0 && y == 29)
+      printf(":3: %d/%d: %d (%d/%d: %d) [%d]\n", x, y, MovDir[x][y],
+            xx, yy, Feld[xx][yy],
+            FrameCounter);
+#endif
+
+#if 1
+    if (!IN_LEV_FIELD_AND_IS_FREE(xx, yy))
+      MovDir[x][y] = old_move_dir;
+#else
     if (!IS_FREE(xx, yy))
       MovDir[x][y] = old_move_dir;
+#endif
+
+#if 0
+    if (FrameCounter < 1 && x == 0 && y == 29)
+      printf(":4: %d/%d: %d [%d]\n", x, y, MovDir[x][y], FrameCounter);
+#endif
 
     MovDelay[x][y] = 0;
   }
@@ -3463,7 +3550,7 @@ inline static void TurnRoundExt(int x, int y)
     {
       int i;
 
-      for (i=0; i<MAX_PLAYERS; i++)
+      for (i = 0; i < MAX_PLAYERS; i++)
       {
        struct PlayerInfo *player = &stored_player[i];
        int jx = player->jx, jy = player->jy;
@@ -3497,7 +3584,7 @@ inline static void TurnRoundExt(int x, int y)
        { 0, +1 }
       };
 
-      for (i=0; i<4; i++)
+      for (i = 0; i < 4; i++)
       {
        int ex = x + xy[i % 4][0];
        int ey = y + xy[i % 4][1];
@@ -3593,16 +3680,16 @@ inline static void TurnRoundExt(int x, int y)
       }
     }
   }
-  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)
+  else if (move_pattern == MV_ALL_DIRECTIONS ||
+          move_pattern == MV_TURNING_LEFT ||
+          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)
+    if (move_pattern == MV_TURNING_LEFT)
       MovDir[x][y] = left_dir;
-    else if (element_info[element].move_pattern == MV_TURNING_RIGHT)
+    else if (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);
@@ -3615,24 +3702,24 @@ inline static void TurnRoundExt(int x, int y)
 
     MovDelay[x][y] = GET_NEW_MOVE_DELAY(element);
   }
-  else if (element_info[element].move_pattern == MV_HORIZONTAL ||
-          element_info[element].move_pattern == MV_VERTICAL)
+  else if (move_pattern == MV_HORIZONTAL ||
+          move_pattern == MV_VERTICAL)
   {
-    if (element_info[element].move_pattern & old_move_dir)
+    if (move_pattern & old_move_dir)
       MovDir[x][y] = back_dir;
-    else if (element_info[element].move_pattern == MV_HORIZONTAL)
+    else if (move_pattern == MV_HORIZONTAL)
       MovDir[x][y] = (RND(2) ? MV_LEFT : MV_RIGHT);
-    else if (element_info[element].move_pattern == MV_VERTICAL)
+    else if (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)
+  else if (move_pattern & MV_ANY_DIRECTION)
   {
-    MovDir[x][y] = element_info[element].move_pattern;
+    MovDir[x][y] = move_pattern;
     MovDelay[x][y] = GET_NEW_MOVE_DELAY(element);
   }
-  else if (element_info[element].move_pattern == MV_ALONG_LEFT_SIDE)
+  else if (move_pattern == MV_ALONG_LEFT_SIDE)
   {
     if (ELEMENT_CAN_ENTER_FIELD(element, left_x, left_y))
       MovDir[x][y] = left_dir;
@@ -3642,7 +3729,7 @@ inline static void TurnRoundExt(int x, int y)
     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)
+  else if (move_pattern == MV_ALONG_RIGHT_SIDE)
   {
     if (ELEMENT_CAN_ENTER_FIELD(element, right_x, right_y))
       MovDir[x][y] = right_dir;
@@ -3652,13 +3739,12 @@ inline static void TurnRoundExt(int x, int y)
     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)
+  else if (move_pattern == MV_TOWARDS_PLAYER ||
+          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);
+    boolean move_away = (move_pattern == MV_AWAY_FROM_PLAYER);
 
     if (AllPlayersGone)
     {
@@ -3669,7 +3755,7 @@ inline static void TurnRoundExt(int x, int y)
     {
       int i;
 
-      for (i=0; i<MAX_PLAYERS; i++)
+      for (i = 0; i < MAX_PLAYERS; i++)
       {
        struct PlayerInfo *player = &stored_player[i];
        int jx = player->jx, jy = player->jy;
@@ -3720,13 +3806,84 @@ inline static void TurnRoundExt(int x, int y)
       MovDir[x][y] = old_move_dir;
     }
   }
-  else if (element_info[element].move_pattern == MV_WHEN_PUSHED)
+  else if (move_pattern == MV_WHEN_PUSHED)
   {
     if (!IN_LEV_FIELD_AND_IS_FREE(move_x, move_y))
       MovDir[x][y] = MV_NO_MOVING;
 
     MovDelay[x][y] = 0;
   }
+  else if (move_pattern & MV_MAZE_RUNNER_STYLE ||
+          element == EL_MAZE_RUNNER)
+  {
+    static int test_xy[7][2] =
+    {
+      { 0, -1 },
+      { -1, 0 },
+      { +1, 0 },
+      { 0, +1 },
+      { 0, -1 },
+      { -1, 0 },
+      { +1, 0 },
+    };
+    static int test_dir[7] =
+    {
+      MV_UP,
+      MV_LEFT,
+      MV_RIGHT,
+      MV_DOWN,
+      MV_UP,
+      MV_LEFT,
+      MV_RIGHT,
+    };
+    boolean hunter_mode = (move_pattern == MV_MAZE_HUNTER);
+    int move_preference = -1000000;    /* start with very low preference */
+    int new_move_dir = MV_NO_MOVING;
+    int start_test = RND(4);
+    int i;
+
+    for (i = 0; i < 4; i++)
+    {
+      int move_dir = test_dir[start_test + i];
+      int move_dir_preference;
+
+      xx = x + test_xy[start_test + i][0];
+      yy = y + test_xy[start_test + i][1];
+
+      if (hunter_mode && IN_LEV_FIELD(xx, yy) &&
+         (IS_PLAYER(xx, yy) || Feld[xx][yy] == EL_PLAYER_IS_LEAVING))
+      {
+       new_move_dir = move_dir;
+
+       break;
+      }
+
+      if (!MAZE_RUNNER_CAN_ENTER_FIELD(xx, yy))
+       continue;
+
+      move_dir_preference = -1 * RunnerVisit[xx][yy];
+      if (hunter_mode && PlayerVisit[xx][yy] > 0)
+       move_dir_preference = PlayerVisit[xx][yy];
+
+      if (move_dir_preference > move_preference)
+      {
+       /* prefer field that has not been visited for the longest time */
+       move_preference = move_dir_preference;
+       new_move_dir = move_dir;
+      }
+      else if (move_dir_preference == move_preference &&
+              move_dir == old_move_dir)
+      {
+       /* prefer last direction when all directions are preferred equally */
+       move_preference = move_dir_preference;
+       new_move_dir = move_dir;
+      }
+    }
+
+    MovDir[x][y] = new_move_dir;
+    if (old_move_dir != new_move_dir)
+      MovDelay[x][y] = 9;
+  }
 }
 
 static void TurnRound(int x, int y)
@@ -3759,7 +3916,7 @@ static boolean JustBeingPushed(int x, int y)
 {
   int i;
 
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
   {
     struct PlayerInfo *player = &stored_player[i];
 
@@ -3811,9 +3968,9 @@ void StartMoving(int x, int y)
        Feld[x][y] = EL_QUICKSAND_EMPTYING;
        Store[x][y] = EL_ROCK;
 #if 1
-       PlaySoundLevelAction(x, y, ACTION_EMPTYING);
+       PlayLevelSoundAction(x, y, ACTION_EMPTYING);
 #else
-       PlaySoundLevel(x, y, SND_QUICKSAND_EMPTYING);
+       PlayLevelSound(x, y, SND_QUICKSAND_EMPTYING);
 #endif
       }
       else if (Feld[x][y + 1] == EL_QUICKSAND_EMPTY)
@@ -3833,9 +3990,9 @@ void StartMoving(int x, int y)
        Store[x][y + 1] = Store[x][y];
        Store[x][y] = 0;
 #if 1
-       PlaySoundLevelAction(x, y, ACTION_FILLING);
+       PlayLevelSoundAction(x, y, ACTION_FILLING);
 #else
-       PlaySoundLevel(x, y, SND_QUICKSAND_FILLING);
+       PlayLevelSound(x, y, SND_QUICKSAND_FILLING);
 #endif
       }
     }
@@ -3848,9 +4005,9 @@ void StartMoving(int x, int y)
       Feld[x][y] = EL_QUICKSAND_FILLING;
       Store[x][y] = element;
 #if 1
-      PlaySoundLevelAction(x, y, ACTION_FILLING);
+      PlayLevelSoundAction(x, y, ACTION_FILLING);
 #else
-      PlaySoundLevel(x, y, SND_QUICKSAND_FILLING);
+      PlayLevelSound(x, y, SND_QUICKSAND_FILLING);
 #endif
     }
     else if (element == EL_MAGIC_WALL_FULL)
@@ -4067,6 +4224,7 @@ void StartMoving(int x, int y)
   /* not "else if" because of elements that can fall and move (EL_SPRING) */
   if (CAN_MOVE(element) && !started_moving)
   {
+    int move_pattern = element_info[element].move_pattern;
     int newx, newy;
 
 #if 1
@@ -4094,6 +4252,11 @@ void StartMoving(int x, int y)
 #endif
 #endif
 
+#if 0
+    if (FrameCounter < 1 && x == 0 && y == 29)
+      printf(":1: %d/%d: %d [%d]\n", x, y, MovDir[x][y], FrameCounter);
+#endif
+
     if (!MovDelay[x][y])       /* start new movement phase */
     {
       /* all objects that can change their move direction after each step
@@ -4102,12 +4265,17 @@ void StartMoving(int x, int y)
       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)
+         !(move_pattern & MV_ANY_DIRECTION) &&
+         move_pattern != MV_TURNING_LEFT &&
+         move_pattern != MV_TURNING_RIGHT)
       {
        TurnRound(x, y);
 
+#if 0
+       if (FrameCounter < 1 && x == 0 && y == 29)
+         printf(":9: %d: %d [%d]\n", y, MovDir[x][y], FrameCounter);
+#endif
+
        if (MovDelay[x][y] && (element == EL_BUG ||
                               element == EL_SPACESHIP ||
                               element == EL_SP_SNIKSNAK ||
@@ -4157,7 +4325,7 @@ void StartMoving(int x, int y)
 #else
        DrawLevelElementAnimationIfNeeded(x, y, element);
 #endif
-       PlaySoundLevelAction(x, y, ACTION_WAITING);
+       PlayLevelSoundAction(x, y, ACTION_WAITING);
       }
       else if (element == EL_SP_ELECTRON)
        DrawLevelElementAnimationIfNeeded(x, y, element);
@@ -4184,9 +4352,9 @@ void StartMoving(int x, int y)
        else
          DrawLevelField(x, y);
 
-       PlaySoundLevelActionIfLoop(x, y, ACTION_ATTACKING);
+       PlayLevelSoundActionIfLoop(x, y, ACTION_ATTACKING);
 
-       for (i=1; i <= 3; i++)
+       for (i = 1; i <= 3; i++)
        {
          int xx = x + i * dx;
          int yy = y + i * dy;
@@ -4224,7 +4392,7 @@ void StartMoving(int x, int y)
 
       if (MovDelay[x][y])      /* element still has to wait some time */
       {
-       PlaySoundLevelAction(x, y, ACTION_WAITING);
+       PlayLevelSoundAction(x, y, ACTION_WAITING);
 
        return;
       }
@@ -4274,7 +4442,7 @@ void StartMoving(int x, int y)
        Feld[x][y] = EL_EMPTY;
        DrawLevelField(x, y);
 
-       PlaySoundLevel(newx, newy, SND_PENGUIN_PASSING);
+       PlayLevelSound(newx, newy, SND_PENGUIN_PASSING);
        if (IN_SCR_FIELD(SCREENX(newx), SCREENY(newy)))
          DrawGraphicThruMask(SCREENX(newx),SCREENY(newy), el2img(element), 0);
 
@@ -4315,7 +4483,7 @@ void StartMoving(int x, int y)
          DrawLevelField(newx, newy);
        }
 
-       PlaySoundLevel(x, y, SND_PIG_DIGGING);
+       PlayLevelSound(x, y, SND_PIG_DIGGING);
       }
       else if (!IS_FREE(newx, newy))
       {
@@ -4326,6 +4494,35 @@ void StartMoving(int x, int y)
        return;
       }
     }
+    else if ((move_pattern & MV_MAZE_RUNNER_STYLE ||
+             element == EL_MAZE_RUNNER) && IN_LEV_FIELD(newx, newy))
+    {
+      if (IS_FOOD_DARK_YAMYAM(Feld[newx][newy]))
+      {
+       if (IS_MOVING(newx, newy))
+         RemoveMovingField(newx, newy);
+       else
+       {
+         Feld[newx][newy] = EL_EMPTY;
+         DrawLevelField(newx, newy);
+       }
+
+       PlayLevelSound(x, y, SND_DARK_YAMYAM_DIGGING);
+      }
+      else if (!IS_FREE(newx, newy))
+      {
+#if 0
+       if (IS_PLAYER(x, y))
+         DrawPlayerField(x, y);
+       else
+         DrawLevelField(x, y);
+#endif
+       return;
+      }
+
+      RunnerVisit[x][y] = FrameCounter;
+      PlayerVisit[x][y] /= 8;          /* expire player visit path */
+    }
     else if (element == EL_DRAGON && IN_LEV_FIELD(newx, newy))
     {
       if (!IS_FREE(newx, newy))
@@ -4364,7 +4561,7 @@ void StartMoving(int x, int y)
          else
            DrawLevelField(x, y);
 
-         PlaySoundLevel(x, y, SND_DRAGON_ATTACKING);
+         PlayLevelSound(x, y, SND_DRAGON_ATTACKING);
 
          MovDelay[x][y] = 50;
 
@@ -4389,7 +4586,7 @@ void StartMoving(int x, int y)
        DrawLevelField(newx, newy);
       }
 
-      PlaySoundLevel(x, y, SND_YAMYAM_DIGGING);
+      PlayLevelSound(x, y, SND_YAMYAM_DIGGING);
     }
     else if (element == EL_DARK_YAMYAM && IN_LEV_FIELD(newx, newy) &&
             IS_FOOD_DARK_YAMYAM(Feld[newx][newy]))
@@ -4410,7 +4607,7 @@ void StartMoving(int x, int y)
        DrawLevelField(newx, newy);
       }
 
-      PlaySoundLevel(x, y, SND_DARK_YAMYAM_DIGGING);
+      PlayLevelSound(x, y, SND_DARK_YAMYAM_DIGGING);
     }
     else if ((element == EL_PACMAN || element == EL_MOLE)
             && IN_LEV_FIELD(newx, newy) && IS_AMOEBOID(Feld[newx][newy]))
@@ -4426,7 +4623,7 @@ void StartMoving(int x, int y)
       if (element == EL_MOLE)
       {
        Feld[newx][newy] = EL_AMOEBA_SHRINKING;
-       PlaySoundLevel(x, y, SND_MOLE_DIGGING);
+       PlayLevelSound(x, y, SND_MOLE_DIGGING);
 
        ResetGfxAnimation(x, y);
        GfxAction[x][y] = ACTION_DIGGING;
@@ -4439,7 +4636,7 @@ void StartMoving(int x, int y)
       {
        Feld[newx][newy] = EL_EMPTY;
        DrawLevelField(newx, newy);
-       PlaySoundLevel(x, y, SND_PACMAN_DIGGING);
+       PlayLevelSound(x, y, SND_PACMAN_DIGGING);
       }
     }
     else if (element == EL_MOLE && IN_LEV_FIELD(newx, newy) &&
@@ -4478,7 +4675,7 @@ void StartMoving(int x, int y)
        TestIfBadThingTouchesHero(x, y);
 
 #if 0
-      PlaySoundLevelAction(x, y, ACTION_WAITING);
+      PlayLevelSoundAction(x, y, ACTION_WAITING);
 #endif
 
       return;
@@ -4486,7 +4683,7 @@ void StartMoving(int x, int y)
 
     InitMovingField(x, y, MovDir[x][y]);
 
-    PlaySoundLevelAction(x, y, ACTION_MOVING);
+    PlayLevelSoundAction(x, y, ACTION_MOVING);
   }
 
   if (MovDir[x][y])
@@ -4678,8 +4875,81 @@ void ContinueMoving(int x, int y)
 #endif
 
   if (!IN_LEV_FIELD(nextx, nexty) || !IS_FREE(nextx, nexty))
-    CheckElementSideChange(newx, newy, Feld[newx][newy], direction,
-                          CE_COLLISION, -1);
+  {
+    /* !!! fix side (direction) orientation here and elsewhere !!! */
+    CheckElementSideChange(newx, newy, Feld[newx][newy],
+                          direction, CE_COLLISION_ACTIVE, -1);
+
+#if 0
+    if (IN_LEV_FIELD(nextx, nexty))
+    {
+      static int opposite_directions[] =
+      {
+       MV_RIGHT,
+       MV_LEFT,
+       MV_DOWN,
+       MV_UP
+      };
+      int move_dir_bit = MV_DIR_BIT(direction);
+      int opposite_direction = opposite_directions[move_dir_bit];
+      int hitting_side = direction;
+      int touched_side = opposite_direction;
+      int hitting_element = Feld[newx][newy];
+      int touched_element = MovingOrBlocked2Element(nextx, nexty);
+      boolean object_hit = (!IS_MOVING(nextx, nexty) ||
+                           MovDir[nextx][nexty] != direction ||
+                           ABS(MovPos[nextx][nexty]) <= TILEY / 2);
+
+      if (object_hit)
+      {
+       int i;
+
+       CheckElementSideChange(nextx, nexty, Feld[nextx][nexty],
+                              opposite_direction, CE_COLLISION_PASSIVE, -1);
+
+       if (IS_CUSTOM_ELEMENT(hitting_element) &&
+           HAS_ANY_CHANGE_EVENT(hitting_element, CE_OTHER_IS_COLL_ACTIVE))
+       {
+         for (i = 0; i < element_info[hitting_element].num_change_pages; i++)
+         {
+           struct ElementChangeInfo *change =
+             &element_info[hitting_element].change_page[i];
+
+           if (change->can_change &&
+               change->events & CH_EVENT_BIT(CE_OTHER_IS_COLL_ACTIVE) &&
+               change->sides & touched_side &&
+               change->trigger_element == touched_element)
+           {
+             CheckElementSideChange(newx, newy, hitting_element,
+                                    CH_SIDE_ANY, CE_OTHER_IS_COLL_ACTIVE, i);
+             break;
+           }
+         }
+       }
+
+       if (IS_CUSTOM_ELEMENT(touched_element) &&
+           HAS_ANY_CHANGE_EVENT(touched_element, CE_OTHER_IS_COLL_PASSIVE))
+       {
+         for (i = 0; i < element_info[touched_element].num_change_pages; i++)
+         {
+           struct ElementChangeInfo *change =
+             &element_info[touched_element].change_page[i];
+
+           if (change->can_change &&
+               change->events & CH_EVENT_BIT(CE_OTHER_IS_COLL_PASSIVE) &&
+               change->sides & hitting_side &&
+               change->trigger_element == hitting_element)
+           {
+             CheckElementSideChange(nextx, nexty, touched_element,
+                                    CH_SIDE_ANY, CE_OTHER_IS_COLL_PASSIVE, i);
+             break;
+           }
+         }
+       }
+      }
+    }
+#endif
+  }
 
   TestIfPlayerTouchesCustomElement(newx, newy);
   TestIfElementTouchesCustomElement(newx, newy);
@@ -4698,7 +4968,7 @@ int AmoebeNachbarNr(int ax, int ay)
     { 0, +1 }
   };
 
-  for (i=0; i<4; i++)
+  for (i = 0; i < 4; i++)
   {
     int x = ax + xy[i][0];
     int y = ay + xy[i][1];
@@ -4728,7 +4998,7 @@ void AmoebenVereinigen(int ax, int ay)
   if (new_group_nr == 0)
     return;
 
-  for (i=0; i<4; i++)
+  for (i = 0; i < 4; i++)
   {
     x = ax + xy[i][0];
     y = ay + xy[i][1];
@@ -4751,9 +5021,9 @@ void AmoebenVereinigen(int ax, int ay)
       AmoebaCnt2[new_group_nr] += AmoebaCnt2[old_group_nr];
       AmoebaCnt2[old_group_nr] = 0;
 
-      for (yy=0; yy<lev_fieldy; yy++)
+      for (yy = 0; yy < lev_fieldy; yy++)
       {
-       for (xx=0; xx<lev_fieldx; xx++)
+       for (xx = 0; xx < lev_fieldx; xx++)
        {
          if (AmoebaNr[xx][yy] == old_group_nr)
            AmoebaNr[xx][yy] = new_group_nr;
@@ -4780,9 +5050,9 @@ void AmoebeUmwandeln(int ax, int ay)
     }
 #endif
 
-    for (y=0; y<lev_fieldy; y++)
+    for (y = 0; y < lev_fieldy; y++)
     {
-      for (x=0; x<lev_fieldx; x++)
+      for (x = 0; x < lev_fieldx; x++)
       {
        if (Feld[x][y] == EL_AMOEBA_DEAD && AmoebaNr[x][y] == group_nr)
        {
@@ -4791,7 +5061,7 @@ void AmoebeUmwandeln(int ax, int ay)
        }
       }
     }
-    PlaySoundLevel(ax, ay, (IS_GEM(level.amoeba_content) ?
+    PlayLevelSound(ax, ay, (IS_GEM(level.amoeba_content) ?
                            SND_AMOEBA_TURNING_TO_GEM :
                            SND_AMOEBA_TURNING_TO_ROCK));
     Bang(ax, ay);
@@ -4806,7 +5076,7 @@ void AmoebeUmwandeln(int ax, int ay)
       { 0, +1 }
     };
 
-    for (i=0; i<4; i++)
+    for (i = 0; i < 4; i++)
     {
       x = ax + xy[i][0];
       y = ay + xy[i][1];
@@ -4816,7 +5086,7 @@ void AmoebeUmwandeln(int ax, int ay)
 
       if (Feld[x][y] == EL_AMOEBA_TO_DIAMOND)
       {
-       PlaySoundLevel(x, y, (IS_GEM(level.amoeba_content) ?
+       PlayLevelSound(x, y, (IS_GEM(level.amoeba_content) ?
                              SND_AMOEBA_TURNING_TO_GEM :
                              SND_AMOEBA_TURNING_TO_ROCK));
        Bang(x, y);
@@ -4840,9 +5110,9 @@ void AmoebeUmwandelnBD(int ax, int ay, int new_element)
   }
 #endif
 
-  for (y=0; y<lev_fieldy; y++)
+  for (y = 0; y < lev_fieldy; y++)
   {
-    for (x=0; x<lev_fieldx; x++)
+    for (x = 0; x < lev_fieldx; x++)
     {
       if (AmoebaNr[x][y] == group_nr &&
          (Feld[x][y] == EL_AMOEBA_DEAD ||
@@ -4859,7 +5129,7 @@ void AmoebeUmwandelnBD(int ax, int ay, int new_element)
   }
 
   if (done)
-    PlaySoundLevel(ax, ay, (new_element == EL_BD_ROCK ?
+    PlayLevelSound(ax, ay, (new_element == EL_BD_ROCK ?
                            SND_BD_AMOEBA_TURNING_TO_ROCK :
                            SND_BD_AMOEBA_TURNING_TO_GEM));
 }
@@ -4876,12 +5146,12 @@ void AmoebeWaechst(int x, int y)
     if (DelayReached(&sound_delay, sound_delay_value))
     {
 #if 1
-      PlaySoundLevelElementAction(x, y, Store[x][y], ACTION_GROWING);
+      PlayLevelSoundElementAction(x, y, Store[x][y], ACTION_GROWING);
 #else
       if (Store[x][y] == EL_BD_AMOEBA)
-       PlaySoundLevel(x, y, SND_BD_AMOEBA_GROWING);
+       PlayLevelSound(x, y, SND_BD_AMOEBA_GROWING);
       else
-       PlaySoundLevel(x, y, SND_AMOEBA_GROWING);
+       PlayLevelSound(x, y, SND_AMOEBA_GROWING);
 #endif
       sound_delay_value = 30;
     }
@@ -5002,7 +5272,7 @@ void AmoebeAbleger(int ax, int ay)
     int start = RND(4);
     boolean waiting_for_player = FALSE;
 
-    for (i=0; i<4; i++)
+    for (i = 0; i < 4; i++)
     {
       int j = (start + i) % 4;
       int x = ax + xy[j][0];
@@ -5081,9 +5351,9 @@ void AmoebeAbleger(int ax, int ay)
   {
     Feld[newax][neway] = EL_AMOEBA_DROP;       /* drop left/right of amoeba */
 #if 1
-    PlaySoundLevelAction(newax, neway, ACTION_GROWING);
+    PlayLevelSoundAction(newax, neway, ACTION_GROWING);
 #else
-    PlaySoundLevel(newax, neway, SND_AMOEBA_GROWING);
+    PlayLevelSound(newax, neway, SND_AMOEBA_GROWING);
 #endif
   }
   else
@@ -5123,7 +5393,7 @@ void Life(int ax, int ay)
       return;
   }
 
-  for (y1=-1; y1<2; y1++) for(x1=-1; x1<2; x1++)
+  for (y1 = -1; y1 < 2; y1++) for (x1 = -1; x1 < 2; x1++)
   {
     int xx = ax+x1, yy = ay+y1;
     int nachbarn = 0;
@@ -5131,7 +5401,7 @@ void Life(int ax, int ay)
     if (!IN_LEV_FIELD(xx, yy))
       continue;
 
-    for (y2=-1; y2<2; y2++) for (x2=-1; x2<2; x2++)
+    for (y2 = -1; y2 < 2; y2++) for (x2 = -1; x2 < 2; x2++)
     {
       int x = xx+x2, y = yy+y2;
 
@@ -5172,7 +5442,7 @@ void Life(int ax, int ay)
   }
 
   if (changed)
-    PlaySoundLevel(ax, ay, element == EL_BIOMAZE ? SND_BIOMAZE_GROWING :
+    PlayLevelSound(ax, ay, element == EL_BIOMAZE ? SND_BIOMAZE_GROWING :
                   SND_GAME_OF_LIFE_GROWING);
 }
 
@@ -5183,7 +5453,7 @@ static void InitRobotWheel(int x, int y)
 
 static void RunRobotWheel(int x, int y)
 {
-  PlaySoundLevel(x, y, SND_ROBOT_WHEEL_ACTIVE);
+  PlayLevelSound(x, y, SND_ROBOT_WHEEL_ACTIVE);
 }
 
 static void StopRobotWheel(int x, int y)
@@ -5199,7 +5469,7 @@ static void InitTimegateWheel(int x, int y)
 
 static void RunTimegateWheel(int x, int y)
 {
-  PlaySoundLevel(x, y, SND_TIMEGATE_SWITCH_ACTIVE);
+  PlayLevelSound(x, y, SND_TIMEGATE_SWITCH_ACTIVE);
 }
 
 void CheckExit(int x, int y)
@@ -5222,7 +5492,7 @@ void CheckExit(int x, int y)
 
   Feld[x][y] = EL_EXIT_OPENING;
 
-  PlaySoundLevelNearest(x, y, SND_CLASS_EXIT_OPENING);
+  PlayLevelSoundNearest(x, y, SND_CLASS_EXIT_OPENING);
 }
 
 void CheckExitSP(int x, int y)
@@ -5243,16 +5513,16 @@ void CheckExitSP(int x, int y)
 
   Feld[x][y] = EL_SP_EXIT_OPENING;
 
-  PlaySoundLevelNearest(x, y, SND_CLASS_SP_EXIT_OPENING);
+  PlayLevelSoundNearest(x, y, SND_CLASS_SP_EXIT_OPENING);
 }
 
 static void CloseAllOpenTimegates()
 {
   int x, y;
 
-  for (y=0; y<lev_fieldy; y++)
+  for (y = 0; y < lev_fieldy; y++)
   {
-    for (x=0; x<lev_fieldx; x++)
+    for (x = 0; x < lev_fieldx; x++)
     {
       int element = Feld[x][y];
 
@@ -5260,9 +5530,9 @@ static void CloseAllOpenTimegates()
       {
        Feld[x][y] = EL_TIMEGATE_CLOSING;
 #if 1
-       PlaySoundLevelAction(x, y, ACTION_CLOSING);
+       PlayLevelSoundAction(x, y, ACTION_CLOSING);
 #else
-       PlaySoundLevel(x, y, SND_TIMEGATE_CLOSING);
+       PlayLevelSound(x, y, SND_TIMEGATE_CLOSING);
 #endif
       }
     }
@@ -5466,9 +5736,9 @@ void MauerAbleger(int ax, int ay)
 
   if (new_wall)
 #if 1
-    PlaySoundLevelAction(ax, ay, ACTION_GROWING);
+    PlayLevelSoundAction(ax, ay, ACTION_GROWING);
 #else
-    PlaySoundLevel(ax, ay, SND_EXPANDABLE_WALL_GROWING);
+    PlayLevelSound(ax, ay, SND_EXPANDABLE_WALL_GROWING);
 #endif
 }
 
@@ -5484,9 +5754,9 @@ void CheckForDragon(int x, int y)
     { 0, +1 }
   };
 
-  for (i=0; i<4; i++)
+  for (i = 0; i < 4; i++)
   {
-    for (j=0; j<4; j++)
+    for (j = 0; j < 4; j++)
     {
       int xx = x + j*xy[i][0], yy = y + j*xy[i][1];
 
@@ -5503,9 +5773,9 @@ void CheckForDragon(int x, int y)
 
   if (!dragon_found)
   {
-    for (i=0; i<4; i++)
+    for (i = 0; i < 4; i++)
     {
-      for (j=0; j<3; j++)
+      for (j = 0; j < 3; j++)
       {
        int xx = x + j*xy[i][0], yy = y + j*xy[i][1];
   
@@ -5546,13 +5816,13 @@ static void WarnBuggyBase(int x, int y)
     { 0, +1 }
   };
 
-  for (i=0; i<4; i++)
+  for (i = 0; i < 4; i++)
   {
     int xx = x + xy[i][0], yy = y + xy[i][1];
 
     if (IS_PLAYER(xx, yy))
     {
-      PlaySoundLevel(x, y, SND_SP_BUGGY_BASE_ACTIVE);
+      PlayLevelSound(x, y, SND_SP_BUGGY_BASE_ACTIVE);
 
       break;
     }
@@ -5566,7 +5836,7 @@ static void InitTrap(int x, int y)
 
 static void ActivateTrap(int x, int y)
 {
-  PlaySoundLevel(x, y, SND_TRAP_ACTIVATING);
+  PlayLevelSound(x, y, SND_TRAP_ACTIVATING);
 }
 
 static void ChangeActiveTrap(int x, int y)
@@ -5648,7 +5918,7 @@ static boolean ChangeElementNow(int x, int y, int element, int page)
     boolean can_change[3][3];
     int xx, yy;
 
-    for (yy = 0; yy < 3; yy++) for(xx = 0; xx < 3 ; xx++)
+    for (yy = 0; yy < 3; yy++) for (xx = 0; xx < 3 ; xx++)
     {
       boolean half_destructible;
       int ex = x + xx - 1;
@@ -5699,7 +5969,7 @@ static boolean ChangeElementNow(int x, int y, int element, int page)
          RND(100) < change->random)
        return FALSE;
 
-      for (yy = 0; yy < 3; yy++) for(xx = 0; xx < 3 ; xx++)
+      for (yy = 0; yy < 3; yy++) for (xx = 0; xx < 3 ; xx++)
       {
        int ex = x + xx - 1;
        int ey = y + yy - 1;
@@ -5723,14 +5993,14 @@ static boolean ChangeElementNow(int x, int y, int element, int page)
       }
 
       if (something_has_changed)
-       PlaySoundLevelElementAction(x, y, element, ACTION_CHANGING);
+       PlayLevelSoundElementAction(x, y, element, ACTION_CHANGING);
     }
   }
   else
   {
     ChangeElementNowExt(x, y, change->target_element);
 
-    PlaySoundLevelElementAction(x, y, element, ACTION_CHANGING);
+    PlayLevelSoundElementAction(x, y, element, ACTION_CHANGING);
   }
 
   return TRUE;
@@ -5813,7 +6083,7 @@ static boolean CheckTriggeredElementSideChange(int lx, int ly,
   if (!(trigger_events[trigger_element] & CH_EVENT_BIT(trigger_event)))
     return FALSE;
 
-  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+  for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
   {
     int element = EL_CUSTOM_START + i;
 
@@ -5823,7 +6093,7 @@ static boolean CheckTriggeredElementSideChange(int lx, int ly,
     if (!CAN_CHANGE(element) || !HAS_ANY_CHANGE_EVENT(element, trigger_event))
       continue;
 
-    for (j=0; j < element_info[element].num_change_pages; j++)
+    for (j = 0; j < element_info[element].num_change_pages; j++)
     {
       struct ElementChangeInfo *change = &element_info[element].change_page[j];
 
@@ -5850,7 +6120,7 @@ static boolean CheckTriggeredElementSideChange(int lx, int ly,
     if (!change_element)
       continue;
 
-    for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
+    for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++)
     {
 #if 0
       if (x == lx && y == ly)  /* do not change trigger element itself */
@@ -5906,6 +6176,168 @@ static boolean CheckElementChange(int x, int y, int element, int trigger_event)
   return CheckElementSideChange(x, y, element, CH_SIDE_ANY, trigger_event, -1);
 }
 
+static void PlayPlayerSound(struct PlayerInfo *player)
+{
+  int jx = player->jx, jy = player->jy;
+  int element = player->element_nr;
+  int last_action = player->last_action_waiting;
+  int action = player->action_waiting;
+
+  if (player->is_waiting)
+  {
+    if (action != last_action)
+      PlayLevelSoundElementAction(jx, jy, element, action);
+    else
+      PlayLevelSoundElementActionIfLoop(jx, jy, element, action);
+  }
+  else
+  {
+    if (action != last_action)
+      StopSound(element_info[element].sound[last_action]);
+
+    if (last_action == ACTION_SLEEPING)
+      PlayLevelSoundElementAction(jx, jy, element, ACTION_AWAKENING);
+  }
+}
+
+static void PlayAllPlayersSound()
+{
+  int i;
+
+  for (i = 0; i < MAX_PLAYERS; i++)
+    if (stored_player[i].active)
+      PlayPlayerSound(&stored_player[i]);
+}
+
+static void SetPlayerWaiting(struct PlayerInfo *player, boolean is_waiting)
+{
+  boolean last_waiting = player->is_waiting;
+  int move_dir = player->MovDir;
+
+  player->last_action_waiting = player->action_waiting;
+
+  if (is_waiting)
+  {
+    if (!last_waiting)         /* not waiting -> waiting */
+    {
+      player->is_waiting = TRUE;
+
+      player->frame_counter_bored =
+       FrameCounter +
+       game.player_boring_delay_fixed +
+       SimpleRND(game.player_boring_delay_random);
+      player->frame_counter_sleeping =
+       FrameCounter +
+       game.player_sleeping_delay_fixed +
+       SimpleRND(game.player_sleeping_delay_random);
+
+      InitPlayerGfxAnimation(player, ACTION_WAITING, player->MovDir);
+    }
+
+    if (game.player_sleeping_delay_fixed +
+       game.player_sleeping_delay_random > 0 &&
+       player->anim_delay_counter == 0 &&
+       player->post_delay_counter == 0 &&
+       FrameCounter >= player->frame_counter_sleeping)
+      player->is_sleeping = TRUE;
+    else if (game.player_boring_delay_fixed +
+            game.player_boring_delay_random > 0 &&
+            FrameCounter >= player->frame_counter_bored)
+      player->is_bored = TRUE;
+
+    player->action_waiting = (player->is_sleeping ? ACTION_SLEEPING :
+                             player->is_bored ? ACTION_BORING :
+                             ACTION_WAITING);
+
+    if (player->is_sleeping)
+    {
+      if (player->num_special_action_sleeping > 0)
+      {
+       if (player->anim_delay_counter == 0 && player->post_delay_counter == 0)
+       {
+         int last_special_action = player->special_action_sleeping;
+         int num_special_action = player->num_special_action_sleeping;
+         int special_action =
+           (last_special_action == ACTION_DEFAULT ? ACTION_SLEEPING_1 :
+            last_special_action == ACTION_SLEEPING ? ACTION_SLEEPING :
+            last_special_action < ACTION_SLEEPING_1 + num_special_action - 1 ?
+            last_special_action + 1 : ACTION_SLEEPING);
+         int special_graphic =
+           el_act_dir2img(player->element_nr, special_action, move_dir);
+
+         player->anim_delay_counter =
+           graphic_info[special_graphic].anim_delay_fixed +
+           SimpleRND(graphic_info[special_graphic].anim_delay_random);
+         player->post_delay_counter =
+           graphic_info[special_graphic].post_delay_fixed +
+           SimpleRND(graphic_info[special_graphic].post_delay_random);
+
+         player->special_action_sleeping = special_action;
+       }
+
+       if (player->anim_delay_counter > 0)
+       {
+         player->action_waiting = player->special_action_sleeping;
+         player->anim_delay_counter--;
+       }
+       else if (player->post_delay_counter > 0)
+       {
+         player->post_delay_counter--;
+       }
+      }
+    }
+    else if (player->is_bored)
+    {
+      if (player->num_special_action_bored > 0)
+      {
+       if (player->anim_delay_counter == 0 && player->post_delay_counter == 0)
+       {
+         int special_action =
+           ACTION_BORING_1 + SimpleRND(player->num_special_action_bored);
+         int special_graphic =
+           el_act_dir2img(player->element_nr, special_action, move_dir);
+
+         player->anim_delay_counter =
+           graphic_info[special_graphic].anim_delay_fixed +
+           SimpleRND(graphic_info[special_graphic].anim_delay_random);
+         player->post_delay_counter =
+           graphic_info[special_graphic].post_delay_fixed +
+           SimpleRND(graphic_info[special_graphic].post_delay_random);
+
+         player->special_action_bored = special_action;
+       }
+
+       if (player->anim_delay_counter > 0)
+       {
+         player->action_waiting = player->special_action_bored;
+         player->anim_delay_counter--;
+       }
+       else if (player->post_delay_counter > 0)
+       {
+         player->post_delay_counter--;
+       }
+      }
+    }
+  }
+  else if (last_waiting)       /* waiting -> not waiting */
+  {
+    player->is_waiting = FALSE;
+    player->is_bored = FALSE;
+    player->is_sleeping = FALSE;
+
+    player->frame_counter_bored = -1;
+    player->frame_counter_sleeping = -1;
+
+    player->anim_delay_counter = 0;
+    player->post_delay_counter = 0;
+
+    player->action_waiting = ACTION_DEFAULT;
+
+    player->special_action_bored = ACTION_DEFAULT;
+    player->special_action_sleeping = ACTION_DEFAULT;
+  }
+}
+
 #if 1
 static byte PlayerActions(struct PlayerInfo *player, byte player_action)
 {
@@ -5960,6 +6392,8 @@ static byte PlayerActions(struct PlayerInfo *player, byte player_action)
       }
     }
 
+    SetPlayerWaiting(player, FALSE);
+
 #if 1
     return player_action;
 #else
@@ -5979,7 +6413,7 @@ static byte PlayerActions(struct PlayerInfo *player, byte player_action)
     CheckGravityMovement(player);
 
     if (player->MovPos == 0)
-      InitPlayerGfxAnimation(player, ACTION_DEFAULT, player->MovDir);
+      SetPlayerWaiting(player, TRUE);
 
     if (player->MovPos == 0)   /* needed for tape.playing */
       player->is_moving = FALSE;
@@ -6129,9 +6563,13 @@ void GameActions()
   if (tape.pausing)
     return;
 
+#if 0
+  printf("::: getting new tape action [%d]\n", FrameCounter);
+#endif
+
   recorded_player_action = (tape.playing ? TapePlayAction() : NULL);
 
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
   {
     summarized_player_action |= stored_player[i].action;
 
@@ -6147,7 +6585,7 @@ void GameActions()
   if (!options.network && !setup.team_mode)
     local_player->effective_action = summarized_player_action;
 
-  for (i=0; i < MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
   {
     int actual_player_action = stored_player[i].effective_action;
 
@@ -6159,6 +6597,9 @@ void GameActions()
 
     tape_action[i] = PlayerActions(&stored_player[i], actual_player_action);
 
+    if (tape.recording && tape_action[i] && !tape.player_participates[i])
+      tape.player_participates[i] = TRUE;    /* player just appeared from CE */
+
     ScrollPlayer(&stored_player[i], SCROLL_GO_ON);
   }
 
@@ -6175,14 +6616,14 @@ void GameActions()
   FrameCounter++;
   TimeFrames++;
 
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
     stored_player[i].Frame++;
 #endif
 
 #if 1
   if (game.engine_version < VERSION_IDENT(2,2,0,7))
   {
-    for (i=0; i<MAX_PLAYERS; i++)
+    for (i = 0; i < MAX_PLAYERS; i++)
     {
       struct PlayerInfo *player = &stored_player[i];
       int x = player->jx;
@@ -6203,7 +6644,7 @@ void GameActions()
   }
 #endif
 
-  for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
+  for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++)
   {
     Changed[x][y] = CE_BITMASK_DEFAULT;
     ChangeEvent[x][y] = CE_BITMASK_DEFAULT;
@@ -6253,7 +6694,7 @@ void GameActions()
 #endif
   }
 
-  for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
+  for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++)
   {
     element = Feld[x][y];
 #if 1
@@ -6281,7 +6722,7 @@ void GameActions()
     SetRandomAnimationValue(x, y);
 
 #if 1
-    PlaySoundLevelActionIfLoop(x, y, GfxAction[x][y]);
+    PlayLevelSoundActionIfLoop(x, y, GfxAction[x][y]);
 #endif
 
     if (IS_INACTIVE(element))
@@ -6411,7 +6852,7 @@ void GameActions()
 #endif
 
     if (IS_BELT_ACTIVE(element))
-      PlaySoundLevelAction(x, y, ACTION_ACTIVE);
+      PlayLevelSoundAction(x, y, ACTION_ACTIVE);
 
     if (game.magic_wall_active)
     {
@@ -6477,7 +6918,7 @@ void GameActions()
   {
     game.explosions_delayed = FALSE;
 
-    for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
+    for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++)
     {
       element = Feld[x][y];
 
@@ -6501,9 +6942,9 @@ void GameActions()
       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);
+       PlayLevelSound(magic_wall_x, magic_wall_y, SND_BD_MAGIC_WALL_ACTIVE);
       else
-       PlaySoundLevel(magic_wall_x, magic_wall_y, SND_MAGIC_WALL_ACTIVE);
+       PlayLevelSound(magic_wall_x, magic_wall_y, SND_MAGIC_WALL_ACTIVE);
     }
 
     if (game.magic_wall_time_left > 0)
@@ -6511,7 +6952,7 @@ void GameActions()
       game.magic_wall_time_left--;
       if (!game.magic_wall_time_left)
       {
-       for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
+       for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++)
        {
          element = Feld[x][y];
 
@@ -6550,16 +6991,16 @@ void GameActions()
       CloseAllOpenTimegates();
   }
 
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
   {
     struct PlayerInfo *player = &stored_player[i];
 
     if (SHIELD_ON(player))
     {
       if (player->shield_deadly_time_left)
-       PlaySoundLevel(player->jx, player->jy, SND_SHIELD_DEADLY_ACTIVE);
+       PlayLevelSound(player->jx, player->jy, SND_SHIELD_DEADLY_ACTIVE);
       else if (player->shield_normal_time_left)
-       PlaySoundLevel(player->jx, player->jy, SND_SHIELD_NORMAL_ACTIVE);
+       PlayLevelSound(player->jx, player->jy, SND_SHIELD_NORMAL_ACTIVE);
     }
   }
 
@@ -6568,7 +7009,7 @@ void GameActions()
     TimeFrames = 0;
     TimePlayed++;
 
-    for (i=0; i<MAX_PLAYERS; i++)
+    for (i = 0; i < MAX_PLAYERS; i++)
     {
       struct PlayerInfo *player = &stored_player[i];
 
@@ -6594,7 +7035,7 @@ void GameActions()
       DrawText(DX_TIME, DY_TIME, int2str(TimeLeft, 3), FONT_TEXT_2);
 
       if (!TimeLeft && setup.time_limit)
-       for (i=0; i<MAX_PLAYERS; i++)
+       for (i = 0; i < MAX_PLAYERS; i++)
          KillHero(&stored_player[i]);
     }
     else if (level.time == 0 && !AllPlayersGone) /* level without time limit */
@@ -6602,6 +7043,7 @@ void GameActions()
   }
 
   DrawAllPlayers();
+  PlayAllPlayersSound();
 
   if (options.debug)                   /* calculate frames per second */
   {
@@ -6637,7 +7079,7 @@ void GameActions()
   FrameCounter++;
   TimeFrames++;
 
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
   {
     int move_frames =
       MOVE_DELAY_NORMAL_SPEED /  stored_player[i].move_delay_value;
@@ -6664,7 +7106,7 @@ static boolean AllPlayersInSight(struct PlayerInfo *player, int x, int y)
   int min_x = x, min_y = y, max_x = x, max_y = y;
   int i;
 
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
   {
     int jx = stored_player[i].jx, jy = stored_player[i].jy;
 
@@ -6684,7 +7126,7 @@ static boolean AllPlayersInVisibleScreen()
 {
   int i;
 
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
   {
     int jx = stored_player[i].jx, jy = stored_player[i].jy;
 
@@ -6714,14 +7156,14 @@ void ScrollLevel(int dx, int dy)
   if (dx)
   {
     x = (dx == 1 ? BX1 : BX2);
-    for (y=BY1; y <= BY2; y++)
+    for (y = BY1; y <= BY2; y++)
       DrawScreenField(x, y);
   }
 
   if (dy)
   {
     y = (dy == 1 ? BY1 : BY2);
-    for (x=BX1; x <= BX2; x++)
+    for (x = BX1; x <= BX2; x++)
       DrawScreenField(x, y);
   }
 
@@ -6843,6 +7285,10 @@ boolean MovePlayerOneStep(struct PlayerInfo *player,
   player->MovPos =
     (dx > 0 || dy > 0 ? -1 : 1) * (TILEX - TILEX / player->move_delay_value);
 
+  player->step_counter++;
+
+  PlayerVisit[jx][jy] = FrameCounter;
+
   ScrollPlayer(player, SCROLL_INIT);
 
 #if 0
@@ -7226,7 +7672,7 @@ void TestIfPlayerTouchesCustomElement(int x, int y)
   int center_element = Feld[x][y];     /* should always be non-moving! */
   int i;
 
-  for (i=0; i<4; i++)
+  for (i = 0; i < 4; i++)
   {
     int xx = x + xy[i][0];
     int yy = y + xy[i][1];
@@ -7284,7 +7730,7 @@ void TestIfElementTouchesCustomElement(int x, int y)
   };
   static int change_sides[4][2] =
   {
-    /* center side       border side */
+    /* center side     border side */
     { CH_SIDE_TOP,     CH_SIDE_BOTTOM  },      /* check top    */
     { CH_SIDE_LEFT,    CH_SIDE_RIGHT   },      /* check left   */
     { CH_SIDE_RIGHT,   CH_SIDE_LEFT    },      /* check right  */
@@ -7302,7 +7748,7 @@ void TestIfElementTouchesCustomElement(int x, int y)
   int center_element = Feld[x][y];     /* should always be non-moving! */
   int i, j;
 
-  for (i=0; i<4; i++)
+  for (i = 0; i < 4; i++)
   {
     int xx = x + xy[i][0];
     int yy = y + xy[i][1];
@@ -7327,7 +7773,7 @@ void TestIfElementTouchesCustomElement(int x, int y)
        HAS_ANY_CHANGE_EVENT(center_element, CE_OTHER_IS_TOUCHING) &&
        !change_center_element)
     {
-      for (j=0; j < element_info[center_element].num_change_pages; j++)
+      for (j = 0; j < element_info[center_element].num_change_pages; j++)
       {
        struct ElementChangeInfo *change =
          &element_info[center_element].change_page[j];
@@ -7349,7 +7795,7 @@ void TestIfElementTouchesCustomElement(int x, int y)
     if (IS_CUSTOM_ELEMENT(border_element) &&
        HAS_ANY_CHANGE_EVENT(border_element, CE_OTHER_IS_TOUCHING))
     {
-      for (j=0; j < element_info[border_element].num_change_pages; j++)
+      for (j = 0; j < element_info[border_element].num_change_pages; j++)
       {
        struct ElementChangeInfo *change =
          &element_info[border_element].change_page[j];
@@ -7390,7 +7836,7 @@ void TestIfGoodThingHitsBadThing(int good_x, int good_y, int good_move_dir)
     MV_DOWN
   };
 
-  for (i=0; i<4; i++)
+  for (i = 0; i < 4; i++)
   {
     int test_x, test_y, test_move_dir, test_element;
 
@@ -7465,7 +7911,7 @@ void TestIfBadThingHitsGoodThing(int bad_x, int bad_y, int bad_move_dir)
   if (bad_element == EL_EXPLOSION)     /* skip just exploding bad things */
     return;
 
-  for (i=0; i<4; i++)
+  for (i = 0; i < 4; i++)
   {
     int test_x, test_y, test_move_dir, test_element;
 
@@ -7569,7 +8015,7 @@ void TestIfBadThingTouchesOtherBadThing(int bad_x, int bad_y)
     { 0, +1 }
   };
 
-  for (i=0; i<4; i++)
+  for (i = 0; i < 4; i++)
   {
     int x, y, element;
 
@@ -7624,11 +8070,11 @@ void BuryHero(struct PlayerInfo *player)
     return;
 
 #if 1
-  PlaySoundLevelElementAction(jx, jy, player->element_nr, ACTION_DYING);
+  PlayLevelSoundElementAction(jx, jy, player->element_nr, ACTION_DYING);
 #else
-  PlaySoundLevel(jx, jy, SND_CLASS_PLAYER_DYING);
+  PlayLevelSound(jx, jy, SND_CLASS_PLAYER_DYING);
 #endif
-  PlaySoundLevel(jx, jy, SND_GAME_LOSING);
+  PlayLevelSound(jx, jy, SND_GAME_LOSING);
 
   player->GameOver = TRUE;
   RemoveHero(player);
@@ -7645,7 +8091,7 @@ void RemoveHero(struct PlayerInfo *player)
   if (!ExplodeField[jx][jy])
     StorePlayer[jx][jy] = 0;
 
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
     if (stored_player[i].active)
       found = TRUE;
 
@@ -7823,7 +8269,7 @@ int DigField(struct PlayerInfo *player,
       player->programmed_action = move_direction;
       DOUBLE_PLAYER_SPEED(player);
 
-      PlaySoundLevel(x, y, SND_CLASS_SP_PORT_PASSING);
+      PlayLevelSound(x, y, SND_CLASS_SP_PORT_PASSING);
       break;
 
     case EL_TUBE_ANY:
@@ -7865,7 +8311,7 @@ int DigField(struct PlayerInfo *player,
        if (!(tube_enter_directions[i][1] & move_direction))
          return MF_NO_ACTION;  /* tube has no opening in this direction */
 
-       PlaySoundLevel(x, y, SND_CLASS_TUBE_WALKING);
+       PlayLevelSound(x, y, SND_CLASS_TUBE_WALKING);
       }
       break;
 
@@ -7898,9 +8344,9 @@ int DigField(struct PlayerInfo *player,
 
        /* play sound from background or player, whatever is available */
        if (element_info[element].sound[sound_action] != SND_UNDEFINED)
-         PlaySoundLevelElementAction(x, y, element, sound_action);
+         PlayLevelSoundElementAction(x, y, element, sound_action);
        else
-         PlaySoundLevelElementAction(x, y, player->element_nr, sound_action);
+         PlayLevelSoundElementAction(x, y, player->element_nr, sound_action);
 
        break;
       }
@@ -7929,7 +8375,7 @@ int DigField(struct PlayerInfo *player,
        player->programmed_action = move_direction;
        DOUBLE_PLAYER_SPEED(player);
 
-       PlaySoundLevelAction(x, y, ACTION_PASSING);
+       PlayLevelSoundAction(x, y, ACTION_PASSING);
 
        break;
       }
@@ -7948,7 +8394,7 @@ int DigField(struct PlayerInfo *player,
          player->is_digging = TRUE;
        }
 
-       PlaySoundLevelElementAction(x, y, element, ACTION_DIGGING);
+       PlayLevelSoundElementAction(x, y, element, ACTION_DIGGING);
 
        CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_DIGGED);
 
@@ -8027,7 +8473,7 @@ int DigField(struct PlayerInfo *player,
        {
          int i;
 
-         for (i=0; i < element_info[element].collect_count; i++)
+         for (i = 0; i < element_info[element].collect_count; i++)
            if (player->inventory_size < MAX_INVENTORY_SIZE)
              player->inventory_element[player->inventory_size++] = element;
 
@@ -8046,7 +8492,7 @@ int DigField(struct PlayerInfo *player,
        }
 
        RaiseScoreElement(element);
-       PlaySoundLevelElementAction(x, y, element, ACTION_COLLECTING);
+       PlayLevelSoundElementAction(x, y, element, ACTION_COLLECTING);
 
        CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_COLLECTED);
 
@@ -8170,23 +8616,23 @@ int DigField(struct PlayerInfo *player,
          Feld[x][y] = EL_SOKOBAN_OBJECT;
 
          if (Back[x][y] == Back[nextx][nexty])
-           PlaySoundLevelAction(x, y, ACTION_PUSHING);
+           PlayLevelSoundAction(x, y, ACTION_PUSHING);
          else if (Back[x][y] != 0)
-           PlaySoundLevelElementAction(x, y, EL_SOKOBAN_FIELD_FULL,
+           PlayLevelSoundElementAction(x, y, EL_SOKOBAN_FIELD_FULL,
                                        ACTION_EMPTYING);
          else
-           PlaySoundLevelElementAction(nextx, nexty, EL_SOKOBAN_FIELD_EMPTY,
+           PlayLevelSoundElementAction(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);
+           PlayLevelSound(x, y, SND_GAME_SOKOBAN_SOLVING);
          }
        }
        else
-         PlaySoundLevelElementAction(x, y, element, ACTION_PUSHING);
+         PlayLevelSoundElementAction(x, y, element, ACTION_PUSHING);
 
        InitMovingField(x, y, move_direction);
        GfxAction[x][y] = ACTION_PUSHING;
@@ -8220,7 +8666,7 @@ int DigField(struct PlayerInfo *player,
        player->switch_x = x;
        player->switch_y = y;
 
-       PlaySoundLevelElementAction(x, y, element, ACTION_ACTIVATING);
+       PlayLevelSoundElementAction(x, y, element, ACTION_ACTIVATING);
 
        if (element == EL_ROBOT_WHEEL)
        {
@@ -8234,7 +8680,7 @@ int DigField(struct PlayerInfo *player,
        {
          int xx, yy;
 
-         for (yy=0; yy < lev_fieldy; yy++) for (xx=0; xx < lev_fieldx; xx++)
+         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);
@@ -8257,7 +8703,7 @@ int DigField(struct PlayerInfo *player,
          ToggleLightSwitch(x, y);
 
 #if 0
-         PlaySoundLevel(x, y, element == EL_LIGHT_SWITCH ?
+         PlayLevelSound(x, y, element == EL_LIGHT_SWITCH ?
                         SND_LIGHT_SWITCH_ACTIVATING :
                         SND_LIGHT_SWITCH_DEACTIVATING);
 #endif
@@ -8438,7 +8884,7 @@ boolean DropElement(struct PlayerInfo *player)
     if (IN_SCR_FIELD(SCREENX(jx), SCREENY(jy)))
       DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), el2img(Feld[jx][jy]), 0);
 
-    PlaySoundLevelAction(jx, jy, ACTION_DROPPING);
+    PlayLevelSoundAction(jx, jy, ACTION_DROPPING);
 
     CheckTriggeredElementChange(jx, jy, new_element, CE_OTHER_GETS_DROPPED);
     CheckElementChange(jx, jy, new_element, CE_DROPPED_BY_PLAYER);
@@ -8455,7 +8901,7 @@ boolean DropElement(struct PlayerInfo *player)
     if (IN_SCR_FIELD(SCREENX(jx), SCREENY(jy)))
       DrawGraphicThruMask(SCREENX(jx), SCREENY(jy), el2img(Feld[jx][jy]), 0);
 
-    PlaySoundLevelAction(jx, jy, ACTION_DROPPING);
+    PlayLevelSoundAction(jx, jy, ACTION_DROPPING);
   }
 
   return TRUE;
@@ -8468,21 +8914,18 @@ boolean DropElement(struct PlayerInfo *player)
 static int *loop_sound_frame = NULL;
 static int *loop_sound_volume = NULL;
 
-void InitPlaySoundLevel()
+void InitPlayLevelSound()
 {
   int num_sounds = getSoundListSize();
 
-  if (loop_sound_frame != NULL)
-    free(loop_sound_frame);
-
-  if (loop_sound_volume != NULL)
-    free(loop_sound_volume);
+  checked_free(loop_sound_frame);
+  checked_free(loop_sound_volume);
 
-  loop_sound_frame = checked_calloc(num_sounds * sizeof(int));
+  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 void PlayLevelSound(int x, int y, int nr)
 {
   int sx = SCREENX(x), sy = SCREENY(y);
   int volume, stereo_position;
@@ -8527,42 +8970,59 @@ static void PlaySoundLevel(int x, int y, int nr)
   PlaySoundExt(nr, volume, stereo_position, type);
 }
 
-static void PlaySoundLevelNearest(int x, int y, int sound_action)
+static void PlayLevelSoundNearest(int x, int y, int sound_action)
 {
-  PlaySoundLevel(x < LEVELX(BX1) ? LEVELX(BX1) :
+  PlayLevelSound(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)
+static void PlayLevelSoundAction(int x, int y, int action)
 {
-  PlaySoundLevelElementAction(x, y, Feld[x][y], action);
+  PlayLevelSoundElementAction(x, y, Feld[x][y], action);
 }
 
-static void PlaySoundLevelElementAction(int x, int y, int element, int action)
+static void PlayLevelSoundElementAction(int x, int y, int element, int action)
 {
   int sound_effect = element_info[element].sound[action];
 
   if (sound_effect != SND_UNDEFINED)
-    PlaySoundLevel(x, y, sound_effect);
+    PlayLevelSound(x, y, sound_effect);
 }
 
-static void PlaySoundLevelActionIfLoop(int x, int y, int action)
+static void PlayLevelSoundElementActionIfLoop(int x, int y, int element,
+                                             int action)
+{
+  int sound_effect = element_info[element].sound[action];
+
+  if (sound_effect != SND_UNDEFINED && IS_LOOP_SOUND(sound_effect))
+    PlayLevelSound(x, y, sound_effect);
+}
+
+static void PlayLevelSoundActionIfLoop(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))
-    PlaySoundLevel(x, y, sound_effect);
+    PlayLevelSound(x, y, sound_effect);
 }
 
-static void StopSoundLevelActionIfLoop(int x, int y, int action)
+static void StopLevelSoundActionIfLoop(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);
+    StopSound(sound_effect);
+}
+
+static void PlayLevelMusic()
+{
+  if (levelset.music[level_nr] != MUS_UNDEFINED)
+    PlayMusic(levelset.music[level_nr]);       /* from config file */
+  else
+    PlayMusic(MAP_NOCONF_MUSIC(level_nr));     /* from music dir */
 }
 
 void RaiseScore(int value)
@@ -8726,7 +9186,7 @@ void CreateGameButtons()
 {
   int i;
 
-  for (i=0; i<NUM_GAME_BUTTONS; i++)
+  for (i = 0; i < NUM_GAME_BUTTONS; i++)
   {
     Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
     struct GadgetInfo *gi;
@@ -8792,7 +9252,7 @@ void FreeGameButtons()
 {
   int i;
 
-  for (i=0; i<NUM_GAME_BUTTONS; i++)
+  for (i = 0; i < NUM_GAME_BUTTONS; i++)
     FreeGadget(game_gadget[i]);
 }
 
@@ -8800,7 +9260,7 @@ static void MapGameButtons()
 {
   int i;
 
-  for (i=0; i<NUM_GAME_BUTTONS; i++)
+  for (i = 0; i < NUM_GAME_BUTTONS; i++)
     MapGadget(game_gadget[i]);
 }
 
@@ -8808,7 +9268,7 @@ void UnmapGameButtons()
 {
   int i;
 
-  for (i=0; i<NUM_GAME_BUTTONS; i++)
+  for (i = 0; i < NUM_GAME_BUTTONS; i++)
     UnmapGadget(game_gadget[i]);
 }
 
@@ -8865,7 +9325,8 @@ static void HandleGameButtons(struct GadgetInfo *gi)
        setup.sound = setup.sound_music = TRUE;
 
        SetAudioMode(setup.sound);
-       PlayMusic(level_nr);
+
+       PlayLevelMusic();
       }
       break;
 
index 1821310253c4588e13e8ed7bfc57077ea30c221f..40470ea723b0c30d559c982ac2d2cb2b965aef9e 100644 (file)
@@ -72,6 +72,7 @@ void AusgangstuerBlinken(int, int);
 void EdelsteinFunkeln(int, int);
 void MauerWaechst(int, int);
 void MauerAbleger(int, int);
+
 void GameActions(void);
 void ScrollLevel(int, int);
 
@@ -91,7 +92,7 @@ int DigField(struct PlayerInfo *, int, int, int, int, int);
 boolean SnapField(struct PlayerInfo *, int, int);
 boolean DropElement(struct PlayerInfo *);
 
-void InitPlaySoundLevel();
+void InitPlayLevelSound();
 
 void RaiseScore(int);
 void RaiseScoreElement(int);
index 6db9d2463deae2799248ff3d5cc1058540cf8da5..9871ed6cd8c3f0c5c0c4dc1ed5ad04a3edeb5837 100644 (file)
@@ -30,6 +30,8 @@
 #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 */
+#include "conf_g2s.c"  /* include auto-generated data structure definitions */
+#include "conf_g2m.c"  /* include auto-generated data structure definitions */
 
 
 #define CONFIG_TOKEN_FONT_INITIAL              "font.initial"
@@ -109,7 +111,7 @@ static void InitTileClipmasks()
   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)
@@ -124,7 +126,7 @@ static void InitTileClipmasks()
                           clip_gc_valuemask, &clip_gc_values);
 
 #if 0
-  for (i=0; i<NUM_BITMAPS; i++)
+  for (i = 0; i < NUM_BITMAPS; i++)
   {
     if (pix[i]->clip_mask)
     {
@@ -147,11 +149,11 @@ static void InitTileClipmasks()
                               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;
@@ -184,7 +186,7 @@ void FreeTileClipmasks()
 #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)
     {
@@ -198,7 +200,7 @@ void FreeTileClipmasks()
   tile_clip_gc = None;
 
 #if 0
-  for (i=0; i<NUM_BITMAPS; i++)
+  for (i = 0; i < NUM_BITMAPS; i++)
   {
     if (pix[i] != NULL && pix[i]->stored_clip_gc)
     {
@@ -244,15 +246,15 @@ void InitElementSmallImages()
   int i;
 
   /* initialize normal images from static configuration */
-  for (i=0; element_to_graphic[i].element > -1; i++)
+  for (i = 0; element_to_graphic[i].element > -1; i++)
     CreateImageWithSmallImages(element_to_graphic[i].graphic);
 
   /* initialize special images from static configuration */
-  for (i=0; element_to_special_graphic[i].element > -1; i++)
+  for (i = 0; element_to_special_graphic[i].element > -1; i++)
     CreateImageWithSmallImages(element_to_special_graphic[i].graphic);
 
   /* initialize images from dynamic configuration */
-  for (i=0; i < num_property_mappings; i++)
+  for (i = 0; i < num_property_mappings; i++)
     if (property_mapping[i].artwork_index < MAX_NUM_ELEMENTS)
       CreateImageWithSmallImages(property_mapping[i].artwork_index);
 }
@@ -293,15 +295,15 @@ void InitFontGraphicInfo()
 
   /* always start with reliable default values (normal font graphics) */
 #if 1
-  for (i=0; i < NUM_FONTS; i++)
+  for (i = 0; i < NUM_FONTS; i++)
     font_info[i].graphic = IMG_FONT_INITIAL_1;
 #else
-  for (i=0; i < NUM_FONTS; i++)
+  for (i = 0; i < NUM_FONTS; i++)
     font_info[i].graphic = FONT_INITIAL_1;
 #endif
 
   /* initialize normal font/graphic mapping from static configuration */
-  for (i=0; font_to_graphic[i].font_nr > -1; i++)
+  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;
@@ -314,9 +316,9 @@ void InitFontGraphicInfo()
   }
 
   /* always start with reliable default values (special font graphics) */
-  for (i=0; i < NUM_FONTS; i++)
+  for (i = 0; i < NUM_FONTS; i++)
   {
-    for (j=0; j < NUM_SPECIAL_GFX_ARGS; j++)
+    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;
@@ -324,7 +326,7 @@ void InitFontGraphicInfo()
   }
 
   /* initialize special font/graphic mapping from static configuration */
-  for (i=0; font_to_graphic[i].font_nr > -1; i++)
+  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;
@@ -339,7 +341,7 @@ void InitFontGraphicInfo()
   }
 
   /* initialize special element/graphic mapping from dynamic configuration */
-  for (i=0; i < num_property_mappings; i++)
+  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;
@@ -366,7 +368,7 @@ void InitFontGraphicInfo()
 
   /* ---------- initialize font bitmap definitions ---------- */
 
-  for (i=0; i < NUM_FONTS; i++)
+  for (i = 0; i < NUM_FONTS; i++)
   {
     if (i < NUM_INITIAL_FONTS)
     {
@@ -374,7 +376,7 @@ void InitFontGraphicInfo()
       continue;
     }
 
-    for (j=0; j < NUM_SPECIAL_GFX_ARGS; j++)
+    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];
@@ -412,14 +414,14 @@ void InitElementGraphicInfo()
   int i, act, dir;
 
   /* set values to -1 to identify later as "uninitialized" values */
-  for (i=0; i<MAX_NUM_ELEMENTS; i++)
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
-    for (act=0; act<NUM_ACTIONS; act++)
+    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++)
+      for (dir = 0; dir < NUM_DIRECTIONS; dir++)
       {
        element_info[i].direction_graphic[act][dir] = -1;
        element_info[i].direction_crumbled[act][dir] = -1;
@@ -428,7 +430,7 @@ void InitElementGraphicInfo()
   }
 
   /* initialize normal element/graphic mapping from static configuration */
-  for (i=0; element_to_graphic[i].element > -1; i++)
+  for (i = 0; element_to_graphic[i].element > -1; i++)
   {
     int element      = element_to_graphic[i].element;
     int action       = element_to_graphic[i].action;
@@ -473,7 +475,7 @@ void InitElementGraphicInfo()
   }
 
   /* initialize normal element/graphic mapping from dynamic configuration */
-  for (i=0; i < num_property_mappings; i++)
+  for (i = 0; i < num_property_mappings; i++)
   {
     int element   = property_mapping[i].base_index;
     int action    = property_mapping[i].ext1_index;
@@ -500,7 +502,7 @@ void InitElementGraphicInfo()
     if (crumbled)
     {
       if (direction < 0)
-       for (dir=0; dir<NUM_DIRECTIONS; dir++)
+       for (dir = 0; dir < NUM_DIRECTIONS; dir++)
          element_info[element].direction_crumbled[action][dir] = -1;
 
       if (direction > -1)
@@ -511,7 +513,7 @@ void InitElementGraphicInfo()
     else
     {
       if (direction < 0)
-       for (dir=0; dir<NUM_DIRECTIONS; dir++)
+       for (dir = 0; dir < NUM_DIRECTIONS; dir++)
          element_info[element].direction_graphic[action][dir] = -1;
 
       if (direction > -1)
@@ -522,7 +524,7 @@ void InitElementGraphicInfo()
   }
 
   /* now copy all graphics that are defined to be cloned from other graphics */
-  for (i=0; i<MAX_NUM_ELEMENTS; i++)
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
     int graphic = element_info[i].graphic[ACTION_DEFAULT];
     int crumbled_like, diggable_like;
@@ -535,11 +537,11 @@ void InitElementGraphicInfo()
 
     if (crumbled_like != -1 && element_info[i].crumbled[ACTION_DEFAULT] == -1)
     {
-      for (act=0; act<NUM_ACTIONS; act++)
+      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++)
+      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];
     }
@@ -548,7 +550,7 @@ void InitElementGraphicInfo()
     {
       element_info[i].graphic[ACTION_DIGGING] =
        element_info[diggable_like].graphic[ACTION_DIGGING];
-      for (dir=0; dir<NUM_DIRECTIONS; dir++)
+      for (dir = 0; dir < NUM_DIRECTIONS; dir++)
        element_info[i].direction_graphic[ACTION_DIGGING][dir] =
          element_info[diggable_like].direction_graphic[ACTION_DIGGING][dir];
     }
@@ -556,9 +558,9 @@ void InitElementGraphicInfo()
 
 #if 1
   /* now set all undefined/invalid graphics to -1 to set to default after it */
-  for (i=0; i<MAX_NUM_ELEMENTS; i++)
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
-    for (act=0; act<NUM_ACTIONS; act++)
+    for (act = 0; act < NUM_ACTIONS; act++)
     {
       int graphic;
 
@@ -570,7 +572,7 @@ void InitElementGraphicInfo()
       if (graphic > 0 && graphic_info[graphic].bitmap == NULL)
        element_info[i].crumbled[act] = -1;
 
-      for (dir=0; dir<NUM_DIRECTIONS; dir++)
+      for (dir = 0; dir < NUM_DIRECTIONS; dir++)
       {
        graphic = element_info[i].direction_graphic[act][dir];
        if (graphic > 0 && graphic_info[graphic].bitmap == NULL)
@@ -585,7 +587,7 @@ void InitElementGraphicInfo()
 #endif
 
   /* now set all '-1' values to element specific default values */
-  for (i=0; i<MAX_NUM_ELEMENTS; i++)
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
     int default_graphic = element_info[i].graphic[ACTION_DEFAULT];
     int default_crumbled = element_info[i].crumbled[ACTION_DEFAULT];
@@ -597,7 +599,7 @@ void InitElementGraphicInfo()
     if (default_crumbled == -1)
       default_crumbled = IMG_EMPTY;
 
-    for (dir=0; dir<NUM_DIRECTIONS; dir++)
+    for (dir = 0; dir < NUM_DIRECTIONS; dir++)
     {
       default_direction_graphic[dir] =
        element_info[i].direction_graphic[ACTION_DEFAULT][dir];
@@ -610,11 +612,11 @@ void InitElementGraphicInfo()
        default_direction_crumbled[dir] = default_crumbled;
     }
 
-    for (act=0; act<NUM_ACTIONS; act++)
+    for (act = 0; act < NUM_ACTIONS; act++)
     {
-      boolean act_remove = ((IS_DIGGABLE(i)    && act == ACTION_DIGGING)  ||
-                           (IS_SNAPPABLE(i)   && act == ACTION_SNAPPING) ||
-                           (IS_COLLECTIBLE(i) && act == ACTION_COLLECTING));
+      boolean act_remove = (act == ACTION_DIGGING ||
+                           act == ACTION_SNAPPING ||
+                           act == ACTION_COLLECTING);
       boolean act_turning = (act == ACTION_TURNING_FROM_LEFT ||
                             act == ACTION_TURNING_FROM_RIGHT ||
                             act == ACTION_TURNING_FROM_UP ||
@@ -644,7 +646,7 @@ void InitElementGraphicInfo()
       if (default_action_crumbled == -1)
        default_action_crumbled = default_crumbled;
 
-      for (dir=0; dir<NUM_DIRECTIONS; dir++)
+      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];
@@ -687,9 +689,9 @@ void InitElementGraphicInfo()
 
 #if 1
   /* set animation mode to "none" for each graphic with only 1 frame */
-  for (i=0; i<MAX_NUM_ELEMENTS; i++)
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
-    for (act=0; act<NUM_ACTIONS; act++)
+    for (act = 0; act < NUM_ACTIONS; act++)
     {
       int graphic = element_info[i].graphic[act];
       int crumbled = element_info[i].crumbled[act];
@@ -699,7 +701,7 @@ void InitElementGraphicInfo()
       if (graphic_info[crumbled].anim_frames == 1)
        graphic_info[crumbled].anim_mode = ANIM_NONE;
 
-      for (dir=0; dir<NUM_DIRECTIONS; dir++)
+      for (dir = 0; dir < NUM_DIRECTIONS; dir++)
       {
        graphic = element_info[i].direction_graphic[act][dir];
        crumbled = element_info[i].direction_crumbled[act][dir];
@@ -717,7 +719,7 @@ void InitElementGraphicInfo()
 #if DEBUG
   if (options.verbose)
   {
-    for (i=0; i<MAX_NUM_ELEMENTS; i++)
+    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)",
@@ -734,13 +736,13 @@ void InitElementSpecialGraphicInfo()
   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++)
+  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++)
+  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;
@@ -759,7 +761,7 @@ void InitElementSpecialGraphicInfo()
   }
 
   /* initialize special element/graphic mapping from dynamic configuration */
-  for (i=0; i < num_property_mappings; i++)
+  for (i = 0; i < num_property_mappings; i++)
   {
     int element = property_mapping[i].base_index;
     int special = property_mapping[i].ext3_index;
@@ -774,8 +776,8 @@ void InitElementSpecialGraphicInfo()
 
 #if 1
   /* now set all undefined/invalid graphics to default */
-  for (i=0; i < MAX_NUM_ELEMENTS; i++)
-    for (j=0; j < NUM_SPECIAL_GFX_ARGS; j++)
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
+    for (j = 0; j < NUM_SPECIAL_GFX_ARGS; j++)
       if (graphic_info[element_info[i].special_graphic[j]].bitmap == NULL)
        element_info[i].special_graphic[j] =
          element_info[i].graphic[ACTION_DEFAULT];
@@ -786,7 +788,7 @@ static int get_element_from_token(char *token)
 {
   int i;
 
-  for (i=0; i < MAX_NUM_ELEMENTS; i++)
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
     if (strcmp(element_info[i].token_name, token) == 0)
       return i;
 
@@ -802,7 +804,7 @@ static void set_graphic_parameters(int graphic, char **parameter_raw)
   int i;
 
   /* get integer values from string parameters */
-  for (i=0; i < NUM_GFX_ARGS; i++)
+  for (i = 0; i < NUM_GFX_ARGS; i++)
   {
     parameter[i] =
       get_parameter_value(image_config_suffix[i].token, parameter_raw[i],
@@ -824,6 +826,10 @@ static void set_graphic_parameters(int graphic, char **parameter_raw)
   graphic_info[graphic].crumbled_like = -1;    /* do not use clone element */
   graphic_info[graphic].diggable_like = -1;    /* do not use clone element */
   graphic_info[graphic].border_size = TILEX / 8;  /* "CRUMBLED" border size */
+  graphic_info[graphic].anim_delay_fixed = 0;
+  graphic_info[graphic].anim_delay_random = 0;
+  graphic_info[graphic].post_delay_fixed = 0;
+  graphic_info[graphic].post_delay_random = 0;
 
   /* optional x and y tile position of animation frame sequence */
   if (parameter[GFX_ARG_XPOS] != ARG_UNDEFINED_VALUE)
@@ -919,6 +925,20 @@ static void set_graphic_parameters(int graphic, char **parameter_raw)
   if (parameter[GFX_ARG_BORDER_SIZE] != ARG_UNDEFINED_VALUE)
     graphic_info[graphic].border_size = parameter[GFX_ARG_BORDER_SIZE];
 
+  /* this is only used for player "boring" and "sleeping" actions */
+  if (parameter[GFX_ARG_ANIM_DELAY_FIXED] != ARG_UNDEFINED_VALUE)
+    graphic_info[graphic].anim_delay_fixed =
+      parameter[GFX_ARG_ANIM_DELAY_FIXED];
+  if (parameter[GFX_ARG_ANIM_DELAY_RANDOM] != ARG_UNDEFINED_VALUE)
+    graphic_info[graphic].anim_delay_random =
+      parameter[GFX_ARG_ANIM_DELAY_RANDOM];
+  if (parameter[GFX_ARG_POST_DELAY_FIXED] != ARG_UNDEFINED_VALUE)
+    graphic_info[graphic].post_delay_fixed =
+      parameter[GFX_ARG_POST_DELAY_FIXED];
+  if (parameter[GFX_ARG_POST_DELAY_RANDOM] != ARG_UNDEFINED_VALUE)
+    graphic_info[graphic].post_delay_random =
+      parameter[GFX_ARG_POST_DELAY_RANDOM];
+
   /* 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];
@@ -947,8 +967,7 @@ static void InitGraphicInfo()
   GC copy_clipmask_gc = None;
 #endif
 
-  if (graphic_info != NULL)
-    free(graphic_info);
+  checked_free(graphic_info);
 
   graphic_info = checked_calloc(num_images * sizeof(struct GraphicInfo));
 
@@ -959,7 +978,7 @@ static void InitGraphicInfo()
 #if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
   if (clipmasks_initialized)
   {
-    for (i=0; i<num_images; i++)
+    for (i = 0; i < num_images; i++)
     {
       if (graphic_info[i].clip_mask)
        XFreePixmap(display, graphic_info[i].clip_mask);
@@ -972,7 +991,7 @@ static void InitGraphicInfo()
   }
 #endif
 
-  for (i=0; i<num_images; i++)
+  for (i = 0; i < num_images; i++)
   {
     struct FileInfo *image = getImageListEntry(i);
     Bitmap *src_bitmap;
@@ -1097,12 +1116,12 @@ static void InitElementSoundInfo()
   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++)
+  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++)
+  for (i = 0; element_to_sound[i].element > -1; i++)
   {
     int element      = element_to_sound[i].element;
     int action       = element_to_sound[i].action;
@@ -1115,14 +1134,14 @@ static void InitElementSoundInfo()
     if (!is_class)
       element_info[element].sound[action] = sound;
     else
-      for (j=0; j < MAX_NUM_ELEMENTS; j++)
+      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++)
+  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;
@@ -1134,14 +1153,14 @@ static void InitElementSoundInfo()
     if (action < 0)
       action = ACTION_DEFAULT;
 
-    for (j=0; j < MAX_NUM_ELEMENTS; j++)
+    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++)
+  for (i = 0; i < num_property_mappings; i++)
   {
     int element = property_mapping[i].base_index;
     int action  = property_mapping[i].ext1_index;
@@ -1157,9 +1176,9 @@ static void InitElementSoundInfo()
   }
 
   /* now set all '-1' values to element specific default values */
-  for (i=0; i<MAX_NUM_ELEMENTS; i++)
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
-    for (act=0; act < NUM_ACTIONS; act++)
+    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];
@@ -1172,9 +1191,12 @@ static void InitElementSoundInfo()
       if (IS_SB_ELEMENT(i) && element_info[EL_SB_DEFAULT].sound[act] != -1)
        default_action_sound = element_info[EL_SB_DEFAULT].sound[act];
 
+      /* !!! there's no such thing as a "default action sound" !!! */
+#if 0
       /* 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];
+#endif
 
       /* no sound for this specific action -- use default action sound */
       if (element_info[i].sound[act] == -1)
@@ -1183,13 +1205,46 @@ static void InitElementSoundInfo()
   }
 }
 
+static void InitGameModeSoundInfo()
+{
+  int i;
+
+  /* set values to -1 to identify later as "uninitialized" values */
+  for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
+    menu.sound[i] = -1;
+
+  /* initialize gamemode/sound mapping from static configuration */
+  for (i = 0; gamemode_to_sound[i].sound > -1; i++)
+  {
+    int gamemode = gamemode_to_sound[i].gamemode;
+    int sound    = gamemode_to_sound[i].sound;
+
+    if (gamemode < 0)
+      gamemode = GAME_MODE_DEFAULT;
+
+    menu.sound[gamemode] = sound;
+  }
+
+  /* now set all '-1' values to levelset specific default values */
+  for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
+    if (menu.sound[i] == -1)
+      menu.sound[i] = menu.sound[GAME_MODE_DEFAULT];
+
+#if 0
+  /* TEST ONLY */
+  for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
+    if (menu.sound[i] != -1)
+      printf("::: menu.sound[%d] == %d\n", i, menu.sound[i]);
+#endif
+}
+
 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++)
+  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);
@@ -1209,24 +1264,23 @@ static void InitSoundInfo()
   int num_sounds = getSoundListSize();
   int i, j;
 
-  if (sound_info != NULL)
-    free(sound_info);
+  checked_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++)
+  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++)
+  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;
+    sound_info[i].loop = FALSE;                /* default: play sound only once */
 
 #if 0
     printf("::: sound %d: '%s'\n", i, sound->token);
@@ -1234,7 +1288,7 @@ static void InitSoundInfo()
 
     /* determine all loop sounds and identify certain sound classes */
 
-    for (j=0; element_action_info[j].suffix; j++)
+    for (j = 0; element_action_info[j].suffix; j++)
     {
       int len_action_text = strlen(element_action_info[j].suffix);
 
@@ -1256,7 +1310,7 @@ static void InitSoundInfo()
 
     /* associate elements and some selected sound actions */
 
-    for (j=0; j<MAX_NUM_ELEMENTS; j++)
+    for (j = 0; j < MAX_NUM_ELEMENTS; j++)
     {
       if (element_info[j].class_name)
       {
@@ -1282,7 +1336,7 @@ static void InitSoundInfo()
 #if 0
   /* !!! now handled in InitElementSoundInfo() !!! */
   /* initialize element/sound mapping from dynamic configuration */
-  for (i=0; i < num_property_mappings; i++)
+  for (i = 0; i < num_property_mappings; i++)
   {
     int element   = property_mapping[i].base_index;
     int action    = property_mapping[i].ext1_index;
@@ -1335,6 +1389,143 @@ static void InitSoundInfo()
 #endif
 }
 
+static void InitGameModeMusicInfo()
+{
+  struct PropertyMapping *property_mapping = getMusicListPropertyMapping();
+  int num_property_mappings = getMusicListPropertyMappingSize();
+  int default_levelset_music = -1;
+  int i;
+
+  /* set values to -1 to identify later as "uninitialized" values */
+  for (i = 0; i < MAX_LEVELS; i++)
+    levelset.music[i] = -1;
+  for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
+    menu.music[i] = -1;
+
+  /* initialize gamemode/music mapping from static configuration */
+  for (i = 0; gamemode_to_music[i].music > -1; i++)
+  {
+    int gamemode = gamemode_to_music[i].gamemode;
+    int music    = gamemode_to_music[i].music;
+
+#if 0
+    printf("::: gamemode == %d, music == %d\n", gamemode, music);
+#endif
+
+    if (gamemode < 0)
+      gamemode = GAME_MODE_DEFAULT;
+
+    menu.music[gamemode] = music;
+  }
+
+  /* initialize gamemode/music mapping from dynamic configuration */
+  for (i = 0; i < num_property_mappings; i++)
+  {
+    int prefix   = property_mapping[i].base_index;
+    int gamemode = property_mapping[i].ext1_index;
+    int level    = property_mapping[i].ext2_index;
+    int music    = property_mapping[i].artwork_index;
+
+#if 0
+    printf("::: prefix == %d, gamemode == %d, level == %d, music == %d\n",
+          prefix, gamemode, level, music);
+#endif
+
+    if (prefix < 0 || prefix >= NUM_MUSIC_PREFIXES)
+      continue;
+
+    if (gamemode < 0)
+      gamemode = GAME_MODE_DEFAULT;
+
+    /* level specific music only allowed for in-game music */
+    if (level != -1 && gamemode == GAME_MODE_DEFAULT)
+      gamemode = GAME_MODE_PLAYING;
+
+    if (level == -1)
+    {
+      level = 0;
+      default_levelset_music = music;
+    }
+
+    if (gamemode == GAME_MODE_PLAYING || gamemode == GAME_MODE_DEFAULT)
+      levelset.music[level] = music;
+    if (gamemode != GAME_MODE_PLAYING)
+      menu.music[gamemode] = music;
+  }
+
+  /* now set all '-1' values to menu specific default values */
+  /* (undefined values of "levelset.music[]" might stay at "-1" to
+     allow dynamic selection of music files from music directory!) */
+  for (i = 0; i < MAX_LEVELS; i++)
+    if (levelset.music[i] == -1)
+      levelset.music[i] = default_levelset_music;
+  for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
+    if (menu.music[i] == -1)
+      menu.music[i] = menu.music[GAME_MODE_DEFAULT];
+
+#if 0
+  /* TEST ONLY */
+  for (i = 0; i < MAX_LEVELS; i++)
+    if (levelset.music[i] != -1)
+      printf("::: levelset.music[%d] == %d\n", i, levelset.music[i]);
+  for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
+    if (menu.music[i] != -1)
+      printf("::: menu.music[%d] == %d\n", i, menu.music[i]);
+#endif
+}
+
+static void set_music_parameters(int music, char **parameter_raw)
+{
+  int parameter[NUM_MUS_ARGS];
+  int i;
+
+  /* get integer values from string parameters */
+  for (i = 0; i < NUM_MUS_ARGS; i++)
+    parameter[i] =
+      get_parameter_value(music_config_suffix[i].token, parameter_raw[i],
+                         music_config_suffix[i].type);
+
+  /* explicit loop mode setting in configuration overrides default value */
+  if (parameter[MUS_ARG_MODE_LOOP] != ARG_UNDEFINED_VALUE)
+    music_info[music].loop = parameter[MUS_ARG_MODE_LOOP];
+}
+
+static void InitMusicInfo()
+{
+  int num_music = getMusicListSize();
+  int i, j;
+
+  checked_free(music_info);
+
+  music_info = checked_calloc(num_music * sizeof(struct MusicInfo));
+
+  for (i = 0; i < num_music; i++)
+  {
+    struct FileInfo *music = getMusicListEntry(i);
+    int len_music_text = strlen(music->token);
+
+    music_info[i].loop = TRUE;         /* default: play music in loop mode */
+
+    /* determine all loop music */
+
+    for (j = 0; music_prefix_info[j].prefix; j++)
+    {
+      int len_prefix_text = strlen(music_prefix_info[j].prefix);
+
+      if (len_prefix_text < len_music_text &&
+         strncmp(music->token,
+                 music_prefix_info[j].prefix, len_prefix_text) == 0)
+      {
+       music_info[i].loop = music_prefix_info[j].is_loop_music;
+
+       break;
+      }
+    }
+
+    set_music_parameters(i, music->parameter);
+  }
+}
+
 static void ReinitializeGraphics()
 {
   InitGraphicInfo();                   /* graphic properties mapping */
@@ -1355,13 +1546,15 @@ static void ReinitializeSounds()
 {
   InitSoundInfo();             /* sound properties mapping */
   InitElementSoundInfo();      /* element game sound mapping */
+  InitGameModeSoundInfo();     /* game mode sound mapping */
 
-  InitPlaySoundLevel();                /* internal game sound settings */
+  InitPlayLevelSound();                /* internal game sound settings */
 }
 
 static void ReinitializeMusic()
 {
-  /* currently nothing to do */
+  InitMusicInfo();             /* music properties mapping */
+  InitGameModeMusicInfo();     /* game mode music mapping */
 }
 
 void InitElementPropertiesStatic()
@@ -1638,6 +1831,7 @@ void InitElementPropertiesStatic()
     EL_SP_ELECTRON,
     EL_BALLOON,
     EL_SPRING,
+    EL_MAZE_RUNNER,
     -1
   };
 
@@ -2713,21 +2907,21 @@ void InitElementPropertiesStatic()
   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++)
+  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++)
+  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++)
+  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++)
+       for (k = 1; k <= 4; k++)
          SET_PROPERTY(copy_properties[j][k], i, TRUE);
 }
 
@@ -2800,10 +2994,10 @@ void InitElementPropertiesEngine(int engine_version)
 #endif
 
   /* set all special, combined or engine dependent element properties */
-  for (i=0; i < MAX_NUM_ELEMENTS; i++)
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
 #if 0
-    for (j=EP_ACCESSIBLE_OVER; j < NUM_ELEMENT_PROPERTIES; j++)
+    for (j = EP_ACCESSIBLE_OVER; j < NUM_ELEMENT_PROPERTIES; j++)
       SET_PROPERTY(i, j, FALSE);
 #endif
 
@@ -2845,7 +3039,7 @@ void InitElementPropertiesEngine(int engine_version)
     /* ---------- WALL ----------------------------------------------------- */
     SET_PROPERTY(i, EP_WALL, TRUE);    /* default: element is wall */
 
-    for (j=0; no_wall_properties[j] != -1; j++)
+    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);
@@ -2910,7 +3104,7 @@ void InitElementPropertiesEngine(int engine_version)
 
     /* ---------- CAN_CHANGE ----------------------------------------------- */
     SET_PROPERTY(i, EP_CAN_CHANGE, FALSE);     /* default: cannot change */
-    for (j=0; j < element_info[i].num_change_pages; j++)
+    for (j = 0; j < element_info[i].num_change_pages; j++)
       if (element_info[i].change_page[j].can_change)
        SET_PROPERTY(i, EP_CAN_CHANGE, TRUE);
 
@@ -2921,11 +3115,11 @@ void InitElementPropertiesEngine(int engine_version)
 
 #if 0
   /* determine inactive elements (used for engine main loop optimization) */
-  for (i=0; i < MAX_NUM_ELEMENTS; i++)
+  for (i = 0; i < MAX_NUM_ELEMENTS; i++)
   {
     boolean active = FALSE;
 
-    for (j=0; i < NUM_ELEMENT_PROPERTIES; j++)
+    for (j = 0; i < NUM_ELEMENT_PROPERTIES; j++)
     {
       if (HAS_PROPERTY(i, j))
        active = TRUE;
@@ -2952,7 +3146,7 @@ void InitElementPropertiesEngine(int engine_version)
     };
 
     /* special EM style gems behaviour */
-    for (i=0; ep_em_slippery_wall[i] != -1; i++)
+    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);
 
@@ -2976,7 +3170,7 @@ void InitElementPropertiesEngine(int engine_version)
   }
 
   /* set uninitialized push delay values of custom elements in older levels */
-  for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
+  for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++)
   {
     int element = EL_CUSTOM_START + i;
 
@@ -2999,51 +3193,92 @@ static void InitGlobal()
 
 void Execute_Command(char *command)
 {
+  int i;
+
   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("# (The entries 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));
+    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("# (The entries 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));
+    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("# You can configure additional/alternative music files here.\n");
+    printf("# (The entries below are default and therefore commented out.)\n");
     printf("\n");
     printf("%s\n", getFormattedSetupEntry("name", "Classic Music"));
     printf("\n");
     printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
+    printf("\n");
+
+    for (i = 0; music_config[i].token != NULL; i++)
+      printf("# %s\n", getFormattedSetupEntry(music_config[i].token,
+                                             music_config[i].value));
+
+    exit(0);
+  }
+  else if (strcmp(command, "print editorsetup.conf") == 0)
+  {
+    printf("# You can configure your personal editor element list here.\n");
+    printf("# (The entries below are default and therefore commented out.)\n");
+    printf("\n");
+
+    PrintEditorElementList();
+
+    exit(0);
+  }
+  else if (strcmp(command, "print helpanim.conf") == 0)
+  {
+    printf("# You can configure different element help animations here.\n");
+    printf("# (The entries below are default and therefore commented out.)\n");
+    printf("\n");
+
+    for (i = 0; helpanim_config[i].token != NULL; i++)
+    {
+      printf("# %s\n", getFormattedSetupEntry(helpanim_config[i].token,
+                                             helpanim_config[i].value));
+
+      if (strcmp(helpanim_config[i].token, "end") == 0)
+       printf("#\n");
+    }
+
+    exit(0);
+  }
+  else if (strcmp(command, "print helptext.conf") == 0)
+  {
+    printf("# You can configure different element help text here.\n");
+    printf("# (The entries below are default and therefore commented out.)\n");
+    printf("\n");
+
+    for (i = 0; helptext_config[i].token != NULL; i++)
+      printf("# %s\n", getFormattedSetupEntry(helptext_config[i].token,
+                                             helptext_config[i].value));
 
     exit(0);
   }
@@ -3108,7 +3343,7 @@ static void InitPlayerInfo()
   /* choose default local player */
   local_player = &stored_player[0];
 
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
     stored_player[i].connected = FALSE;
 
   local_player->connected = TRUE;
@@ -3128,6 +3363,18 @@ static char *get_string_in_brackets(char *string)
   return string_in_brackets;
 }
 
+static char *get_level_id_suffix(int id_nr)
+{
+  char *id_suffix = checked_malloc(1 + 3 + 1);
+
+  if (id_nr < 0 || id_nr > 999)
+    id_nr = 0;
+
+  sprintf(id_suffix, ".%03d", id_nr);
+
+  return id_suffix;
+}
+
 #if 0
 static char *get_element_class_token(int element)
 {
@@ -3154,9 +3401,11 @@ 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 *music_id_prefix[NUM_MUSIC_PREFIXES + 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 *level_id_suffix[MAX_LEVELS + 1];
   static char *dummy[1] = { NULL };
   static char *ignore_generic_tokens[] =
   {
@@ -3164,25 +3413,29 @@ static void InitArtworkConfig()
     "sort_priority",
     NULL
   };
-  static char **ignore_image_tokens, **ignore_sound_tokens;
+  static char **ignore_image_tokens;
+  static char **ignore_sound_tokens;
+  static char **ignore_music_tokens;
   int num_ignore_generic_tokens;
-  int num_ignore_image_tokens, num_ignore_sound_tokens;
+  int num_ignore_image_tokens;
+  int num_ignore_sound_tokens;
+  int num_ignore_music_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++)
+  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++)
+  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++)
+  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++)
+  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;
@@ -3191,41 +3444,60 @@ static void InitArtworkConfig()
   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++)
+  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++)
+  /* dynamically determine list of music tokens to be ignored */
+  num_ignore_music_tokens = num_ignore_generic_tokens;
+  ignore_music_tokens =
+    checked_malloc((num_ignore_music_tokens + 1) * sizeof(char *));
+  for (i = 0; i < num_ignore_generic_tokens; i++)
+    ignore_music_tokens[i] = ignore_generic_tokens[i];
+  ignore_music_tokens[num_ignore_music_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++)
+  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++)
+  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++)
+  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++)
+  for (i = 0; i < NUM_MUSIC_PREFIXES; i++)
+    music_id_prefix[i] = music_prefix_info[i].prefix;
+  music_id_prefix[MAX_LEVELS] = 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++)
+  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++)
+  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;
 
+  for (i = 0; i < MAX_LEVELS; i++)
+    level_id_suffix[i] = get_level_id_suffix(i);
+  level_id_suffix[MAX_LEVELS] = 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);
+  InitMusicList(music_config, NUM_MUSIC_FILES, music_config_suffix,
+               music_id_prefix, special_id_suffix, level_id_suffix,
+               dummy, ignore_music_tokens);
 }
 
 static void InitMixer()
@@ -3241,9 +3513,9 @@ void InitGfx()
   int i, j;
 
   /* determine settings for initial font (for displaying startup messages) */
-  for (i=0; image_config[i].token != NULL; i++)
+  for (i = 0; image_config[i].token != NULL; i++)
   {
-    for (j=0; j < NUM_INITIAL_FONTS; j++)
+    for (j = 0; j < NUM_INITIAL_FONTS; j++)
     {
       char font_token[128];
       int len_font_token;
@@ -3268,7 +3540,7 @@ void InitGfx()
     }
   }
 
-  for (j=0; j < NUM_INITIAL_FONTS; j++)
+  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;
@@ -3291,7 +3563,7 @@ void InitGfx()
 
   bitmap_font_initial = LoadCustomImage(filename_font_initial);
 
-  for (j=0; j < NUM_INITIAL_FONTS; j++)
+  for (j = 0; j < NUM_INITIAL_FONTS; j++)
     font_initial[j].bitmap = bitmap_font_initial;
 
   InitFontGraphicInfo();
@@ -3317,8 +3589,8 @@ void InitGfxBackground()
   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++)
+  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;
index 3f56f44efc2c01526c5758b7908cb1938841f716..ddc5ac6016e98877dade4bc05699ed682fc4ad05 100644 (file)
@@ -589,7 +589,7 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct)
                               xpos, ypos);
 
        /* middle part of gadget */
-       for (i=0; i<num_steps; i++)
+       for (i=0; i < num_steps; i++)
          BlitBitmapOnBackground(gd->bitmap, drawto,
                                 gd->x, gd->y + gi->border.ysize,
                                 gi->width, design_body,
@@ -636,7 +636,7 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct)
                               xpos, ypos);
 
        /* middle part of gadget */
-       for (i=0; i<num_steps; i++)
+       for (i=0; i < num_steps; i++)
          BlitBitmapOnBackground(gd->bitmap, drawto,
                                 gd->x + gi->border.xsize, gd->y,
                                 design_body, gi->height,
@@ -1302,7 +1302,7 @@ void ClickOnGadget(struct GadgetInfo *gi, int button)
   HandleGadgets(gi->x, gi->y, 0);
 }
 
-void HandleGadgets(int mx, int my, int button)
+boolean HandleGadgets(int mx, int my, int button)
 {
   static struct GadgetInfo *last_info_gi = NULL;
   static unsigned long pressed_delay = 0;
@@ -1327,7 +1327,7 @@ void HandleGadgets(int mx, int my, int button)
 
   /* check if there are any gadgets defined */
   if (gadget_list_first_entry == NULL)
-    return;
+    return FALSE;
 
   /* simulated release of mouse button over last gadget */
   if (mx == -1 && my == -1 && button == 0)
@@ -1591,7 +1591,7 @@ void HandleGadgets(int mx, int my, int button)
        /* don't handle this scrollbar anymore while mouse button pressed */
        last_gi = NULL;
 
-       return;
+       return TRUE;
       }
     }
 
@@ -1723,6 +1723,9 @@ void HandleGadgets(int mx, int my, int button)
   /* handle gadgets unmapped/mapped between pressing and releasing */
   if (release_event && !gadget_released && new_gi)
     new_gi->state = GD_BUTTON_UNPRESSED;
+
+  return (gadget_pressed || gadget_pressed_repeated ||
+         gadget_released || gadget_moving);
 }
 
 static void insertCharIntoTextArea(struct GadgetInfo *gi, char c)
@@ -1740,7 +1743,7 @@ static void insertCharIntoTextArea(struct GadgetInfo *gi, char c)
   setTextAreaCursorPosition(gi, gi->textarea.cursor_position + 1);
 }
 
-void HandleGadgetsKeyInput(Key key)
+boolean HandleGadgetsKeyInput(Key key)
 {
   struct GadgetInfo *gi = last_gi;
 
@@ -1748,7 +1751,7 @@ void HandleGadgetsKeyInput(Key key)
       !(gi->type & GD_TYPE_TEXT_INPUT ||
        gi->type & GD_TYPE_TEXT_AREA ||
        gi->type & GD_TYPE_SELECTBOX))
-    return;
+    return FALSE;
 
   if (key == KSYM_Return)      /* valid for both text input and selectbox */
   {
@@ -1900,4 +1903,6 @@ void HandleGadgetsKeyInput(Key key)
       DrawGadget(gi, DG_PRESSED, gi->direct_draw);
     }
   }
+
+  return TRUE;
 }
index 160bd611a375311d5372208270f92499be2f21a3..4e1dd0f789d5e70beaf1107c1f615440e1ab7d40 100644 (file)
@@ -249,7 +249,7 @@ void RemapAllGadgets();
 boolean anyTextGadgetActive();
 void ClickOnGadget(struct GadgetInfo *, int);
 
-void HandleGadgets(int, int, int);
-void HandleGadgetsKeyInput(Key);
+boolean HandleGadgets(int, int, int);
+boolean HandleGadgetsKeyInput(Key);
 
 #endif /* GADGETS_H */
index 805190bfe81404424a3e34e40024bd683395e43a..bce20519104494443774eb0988a8049e39af274c 100644 (file)
@@ -58,7 +58,7 @@ create_hashtable(unsigned int minsize, float maxloadfactor,
     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; }
+    for (i=0; i < size; i++) { h->table[i] = NULL; }
     h->tablelength  = size;
     h->entrycount   = 0;
     h->hashfn       = hashf;
index f06a126ec6171fbcdc74014af811cc39c79ca202..e267fd8099604e7005ea4144be13746c60d66f86 100644 (file)
@@ -47,7 +47,7 @@ Image *newImage(unsigned int width, unsigned int height, unsigned int depth)
   image->bytes_per_row = width * bytes_per_pixel;
 
   image->rgb.used = 0;
-  for (i=0; i<MAX_COLORS; i++)
+  for (i = 0; i < MAX_COLORS; i++)
     image->rgb.color_used[i] = FALSE;
 
   image->type = (depth < 8 ? IMAGETYPE_BITMAP :
@@ -115,14 +115,14 @@ static Pixmap Image_to_Mask(Image *image, Display *display, Window window)
    * the corresponding image pixmap
    */
 
-  for (y=0; y<image->height; y++)
+  for (y = 0; y < image->height; y++)
   {
     bitmask = 0x01;            /* start with leftmost bit in the byte     */
     dst_ptr2 = dst_ptr;                /* start with leftmost byte in the row     */
 
-    for (x=0; x<image->width; x++)
+    for (x = 0; x < image->width; x++)
     {
-      for (i=0; i<image->bytes_per_pixel; i++)
+      for (i = 0; i < image->bytes_per_pixel; i++)
        if (*src_ptr++)         /* source pixel solid? (pixel index != 0)  */
          *dst_ptr2 |= bitmask; /* then write a bit into the image mask    */
 
@@ -152,7 +152,7 @@ static int bitsPerPixelAtDepth(Display *display, int screen, int depth)
   pixmap_format = XListPixmapFormats(display, &num_pixmap_formats);
 
   /* find format that matches the given depth */
-  for (i=0; i<num_pixmap_formats; i++)
+  for (i = 0; i < num_pixmap_formats; i++)
     if (pixmap_format[i].depth == depth)
       bits_per_pixel = pixmap_format[i].bits_per_pixel;
 
@@ -229,7 +229,7 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual,
       /* calculate number of distinct colors in each band */
 
       redcolors = greencolors = bluecolors = 1;
-      for (pixval=1; pixval; pixval <<= 1)
+      for (pixval = 1; pixval; pixval <<= 1)
       {
        if (pixval & visual->red_mask)
          redcolors <<= 1;
@@ -251,7 +251,7 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual,
       redbottom = greenbottom = bluebottom = 0;
       redtop = greentop = bluetop = 0;
 
-      for (a=0; a<visual->map_entries; a++)
+      for (a = 0; a < visual->map_entries; a++)
       {
        if (redbottom < 256)
          redtop = redbottom + redstep;
@@ -307,7 +307,7 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual,
 
       ximageinfo->cmap = global_cmap;
 
-      for (a=0; a<MAX_COLORS; a++)
+      for (a = 0; a < MAX_COLORS; a++)
       {
        XColor xcolor2;
        unsigned short mask;
@@ -339,7 +339,7 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual,
            /* allocate the rest of the color cells read/write */
            global_cmap_index =
              (Pixel *)checked_malloc(sizeof(Pixel) * NOFLASH_COLORS);
-           for (i=0; i<NOFLASH_COLORS; i++)
+           for (i = 0; i < NOFLASH_COLORS; i++)
              if (!XAllocColorCells(display, global_cmap, FALSE, NULL, 0,
                                    global_cmap_index + i, 1))
                break;
@@ -352,7 +352,7 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual,
            /* to minimize colormap flashing, copy default colors and try
               to keep them as near as possible to the old values */
 
-           for(i=0; i<num_cmap_entries; i++)
+           for (i = 0; i < num_cmap_entries; i++)
            {
              xcolor2.pixel = *(global_cmap_index + i);
              XQueryColor(display, DefaultColormap(display, screen), &xcolor2);
@@ -377,7 +377,7 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual,
 
          while (!color_found)
          {
-           for (i=num_cmap_entries-1; i>=0; i--)
+           for (i = num_cmap_entries - 1; i >= 0; i--)
            {
              xcolor2.pixel = *(global_cmap_index + i);
              xcolor2 = xcolor_private[xcolor2.pixel];
@@ -464,9 +464,9 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual,
       {
         case IMAGETYPE_RGB:
        {
-         for (y=0; y<image->height; y++)               /* general case */
+         for (y = 0; y < image->height; y++)           /* general case */
          {
-           for (x=0; x<image->width; x++)
+           for (x = 0; x < image->width; x++)
            {
              pixval = *src_ptr++;
              pixval =
@@ -483,9 +483,9 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual,
 
         case IMAGETYPE_TRUECOLOR:
        {
-         for (y=0; y<image->height; y++)               /* general case */
+         for (y = 0; y < image->height; y++)           /* general case */
          {
-           for (x=0; x<image->width; x++)
+           for (x = 0; x < image->width; x++)
            {
              pixval = memory_to_value(src_ptr, image->bytes_per_pixel);
              pixval =
@@ -515,15 +515,15 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual,
     {
       if (display_bytes_per_pixel == 1)                /* special case */
       {
-       for (y=0; y<image->height; y++)
-         for (x=0; x<image->width; x++)
+       for (y = 0; y < image->height; y++)
+         for (x = 0; x < image->width; x++)
            *dst_ptr++ = ximageinfo->index[c + *src_ptr++];
       }
       else                                     /* general case */
       {
-       for (y=0; y<image->height; y++)
+       for (y = 0; y < image->height; y++)
        {
-         for (x=0; x<image->width; x++)
+         for (x = 0; x < image->width; x++)
          {
            value_to_memory(ximageinfo->index[c + *src_ptr++],
                            dst_ptr, display_bytes_per_pixel);
@@ -611,9 +611,9 @@ void ZoomPixmap(Display *display, GC gc, Pixmap src_pixmap, Pixmap dst_pixmap,
   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++)
+  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 */
@@ -822,7 +822,7 @@ int getImageIDFromToken(char *token)
   int num_list_entries = image_info->num_file_list_entries;
   int i;
 
-  for (i=0; i < num_list_entries; i++)
+  for (i = 0; i < num_list_entries; i++)
     if (strcmp(file_list[i].token, token) == 0)
       return i;
 
@@ -866,7 +866,7 @@ void InitImageList(struct ConfigInfo *config_list, int 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++)
+  for (i = 0; config_suffix_list[i].token != NULL; i++)
     image_info->num_suffix_list_entries++;
 
   image_info->suffix_list = config_suffix_list;
@@ -874,23 +874,23 @@ void InitImageList(struct ConfigInfo *config_list, int num_file_list_entries,
   /* ---------- initialize base prefix and suffixes lists ---------- */
 
   image_info->num_base_prefixes = 0;
-  for (i=0; base_prefixes[i] != NULL; i++)
+  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++)
+  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++)
+  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++)
+  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++)
+  for (i = 0; ignore_tokens[i] != NULL; i++)
     image_info->num_ignore_tokens++;
 
   image_info->base_prefixes = base_prefixes;
index 32efad6f840fdccaf7d3fb224c8563db3fdf5caa..d9cad1289ddd7d9fbabd79f76219bb4be0c5e91d 100644 (file)
@@ -28,7 +28,7 @@ void UnixInitJoysticks()
 {
   int i;
 
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
   {
     char *device_name = setup.input[i].joy.device_name;
 
@@ -125,7 +125,7 @@ void translate_joyname(int *joysymbol, char **name, int mode)
   {
     *name = "[undefined]";
 
-    for (i=0; i<6; i++)
+    for (i = 0; i < 6; i++)
     {
       if (*joysymbol == translate_joy[i].joysymbol)
       {
@@ -138,7 +138,7 @@ void translate_joyname(int *joysymbol, char **name, int mode)
   {
     *joysymbol = 0;
 
-    for (i=0; i<6; i++)
+    for (i = 0; i < 6; i++)
     {
       if (strcmp(*name, translate_joy[i].name) == 0)
       {
@@ -224,7 +224,7 @@ void CheckJoystickData()
   int i;
   int distance = 100;
 
-  for(i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
   {
     if (setup.input[i].joy.xleft >= setup.input[i].joy.xmiddle)
       setup.input[i].joy.xleft = setup.input[i].joy.xmiddle - distance;
@@ -317,7 +317,7 @@ int AnyJoystick()
   int i;
   int result = 0;
 
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
     result |= Joystick(i);
 
   return result;
@@ -328,7 +328,7 @@ int AnyJoystickButton()
   int i;
   int result = JOY_BUTTON_NOT_PRESSED;
 
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
   {
     result = JoystickButton(i);
     if (result != JOY_BUTTON_NOT_PRESSED)
index a19bcace92430800df871f8918dafb0a9974fdb0..06ca9357c65f87d792349e44d0fcacaf074098c7 100644 (file)
@@ -41,7 +41,7 @@ void fprintf_line(FILE *stream, char *line_string, int line_length)
 {
   int i;
 
-  for (i=0; i<line_length; i++)
+  for (i = 0; i < line_length; i++)
     fprintf(stream, "%s", line_string);
 
   fprintf(stream, "\n");
@@ -82,6 +82,26 @@ char *int2str(int number, int size)
   }
 }
 
+/* something similar to "int2str()" above, but allocates its own memory
+   and has a different interface; we cannot use "itoa()", because this
+   seems to be already defined when cross-compiling to the win32 target */
+
+char *i_to_a(unsigned int i)
+{
+  static char *a = NULL;
+
+  checked_free(a);
+
+  if (i > 2147483647)  /* yes, this is a kludge */
+    i = 2147483647;
+
+  a = checked_malloc(10 + 1);
+
+  sprintf(a, "%d", i);
+
+  return a;
+}
+
 
 /* ------------------------------------------------------------------------- */
 /* counter functions                                                         */
@@ -243,7 +263,7 @@ void WaitUntilDelayReached(unsigned long *counter_var, unsigned long delay)
 {
   unsigned long actual_counter;
 
-  while(1)
+  while (1)
   {
     actual_counter = Counter();
 
@@ -262,48 +282,6 @@ void WaitUntilDelayReached(unsigned long *counter_var, unsigned long delay)
 /* random generator functions                                                */
 /* ------------------------------------------------------------------------- */
 
-#if 0
-unsigned int SimpleRND(unsigned int max)
-{
-  return (random_linux_libc(RND_FREE) % max);
-}
-
-unsigned int InitSimpleRND(long seed)
-{
-  if (seed == NEW_RANDOMIZE)
-  {
-    struct timeval current_time;
-
-    gettimeofday(&current_time, NULL);
-    seed = (long)current_time.tv_usec;
-  }
-
-  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)
-  {
-    struct timeval current_time;
-
-    gettimeofday(&current_time, NULL);
-    seed = (long)current_time.tv_usec;
-  }
-
-  srandom_linux_libc(RND_GAME, (unsigned int) seed);
-
-  return (unsigned int) seed;
-}
-#endif
-
 unsigned int init_random_number(int nr, long seed)
 {
   if (seed == NEW_RANDOMIZE)
@@ -323,7 +301,7 @@ unsigned int init_random_number(int nr, long seed)
   return (unsigned int) seed;
 }
 
-unsigned int get_random_number(int nr, unsigned int max)
+unsigned int get_random_number(int nr, int max)
 {
   return (max > 0 ? random_linux_libc(nr) % max : 0);
 }
@@ -522,8 +500,7 @@ char *getStringToLower(char *s)
 
 void setString(char **old_value, char *new_value)
 {
-  if (*old_value != NULL)
-    free(*old_value);
+  checked_free(*old_value);
 
   *old_value = getStringCopy(new_value);
 }
@@ -533,36 +510,7 @@ void setString(char **old_value, char *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[])
+void GetOptions(char *argv[], void (*print_usage_function)(void))
 {
   char **options_left = &argv[1];
 
@@ -624,7 +572,7 @@ void GetOptions(char *argv[])
       Error(ERR_EXIT_HELP, "unrecognized option '%s'", option);
     else if (strncmp(option, "-help", option_len) == 0)
     {
-      printUsage();
+      print_usage_function();
 
       exit(0);
     }
@@ -834,7 +782,7 @@ void Error(int mode, char *format, ...)
 
 
 /* ------------------------------------------------------------------------- */
-/* memory allocation functions                                               */
+/* checked memory allocation and freeing functions                           */
 /* ------------------------------------------------------------------------- */
 
 void *checked_malloc(unsigned long size)
@@ -871,6 +819,12 @@ void *checked_realloc(void *ptr, unsigned long size)
   return ptr;
 }
 
+void checked_free(void *ptr)
+{
+  if (ptr != NULL)     /* this check should be done by free() anyway */
+    free(ptr);
+}
+
 
 /* ------------------------------------------------------------------------- */
 /* various helper functions                                                  */
@@ -1395,8 +1349,8 @@ int get_integer_from_string(char *s)
   char *s_lower = getStringToLower(s);
   int result = -1;
 
-  for (i=0; number_text[i][0] != NULL; i++)
-    for (j=0; j < 3; j++)
+  for (i = 0; number_text[i][0] != NULL; i++)
+    for (j = 0; j < 3; j++)
       if (strcmp(s_lower, number_text[i][j]) == 0)
        result = i;
 
@@ -1530,8 +1484,7 @@ boolean fileHasPrefix(char *basename, char *prefix)
   static char *basename_lower = NULL;
   int basename_length, prefix_length;
 
-  if (basename_lower != NULL)
-    free(basename_lower);
+  checked_free(basename_lower);
 
   if (basename == NULL || prefix == NULL)
     return FALSE;
@@ -1553,8 +1506,7 @@ boolean fileHasSuffix(char *basename, char *suffix)
   static char *basename_lower = NULL;
   int basename_length, suffix_length;
 
-  if (basename_lower != NULL)
-    free(basename_lower);
+  checked_free(basename_lower);
 
   if (basename == NULL || suffix == NULL)
     return FALSE;
@@ -1571,18 +1523,30 @@ boolean fileHasSuffix(char *basename, char *suffix)
   return FALSE;
 }
 
-boolean FileIsGraphic(char *basename)
+boolean FileIsGraphic(char *filename)
 {
+  char *basename = strrchr(filename, '/');
+
+  basename = (basename != NULL ? basename + 1 : filename);
+
   return fileHasSuffix(basename, "pcx");
 }
 
-boolean FileIsSound(char *basename)
+boolean FileIsSound(char *filename)
 {
+  char *basename = strrchr(filename, '/');
+
+  basename = (basename != NULL ? basename + 1 : filename);
+
   return fileHasSuffix(basename, "wav");
 }
 
-boolean FileIsMusic(char *basename)
+boolean FileIsMusic(char *filename)
 {
+  char *basename = strrchr(filename, '/');
+
+  basename = (basename != NULL ? basename + 1 : filename);
+
   if (FileIsSound(basename))
     return TRUE;
 
@@ -1723,11 +1687,11 @@ struct FileInfo *getFileListFromConfigList(struct ConfigInfo *config_list,
 
   file_list = checked_calloc(num_file_list_entries * sizeof(struct FileInfo));
 
-  for (i=0; suffix_list[i].token != NULL; i++)
+  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++)
+  for (i = 0; i < num_file_list_entries; i++)
   {
     file_list[i].token = NULL;
 
@@ -1741,7 +1705,7 @@ struct FileInfo *getFileListFromConfigList(struct ConfigInfo *config_list,
       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++)
+      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);
@@ -1750,13 +1714,13 @@ struct FileInfo *getFileListFromConfigList(struct ConfigInfo *config_list,
   }
 
   list_pos = 0;
-  for (i=0; config_list[i].token != NULL; i++)
+  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++)
+    for (j = 0; suffix_list[j].token != NULL; j++)
     {
       int len_suffix = strlen(suffix_list[j].token);
 
@@ -1773,7 +1737,7 @@ struct FileInfo *getFileListFromConfigList(struct ConfigInfo *config_list,
     }
 
     /* the following tokens are no file definitions, but other config tokens */
-    for (j=0; ignore_tokens[j] != NULL; j++)
+    for (j = 0; ignore_tokens[j] != NULL; j++)
       if (strcmp(config_list[i].token, ignore_tokens[j]) == 0)
        is_file_entry = FALSE;
 
@@ -1843,7 +1807,7 @@ static boolean token_suffix_match(char *token, char *suffix, int start_pos)
   return FALSE;
 }
 
-#define KNOWN_TOKEN_VALUE      "[KNOWN_TOKEN]"
+#define KNOWN_TOKEN_VALUE      "[KNOWN_TOKEN_VALUE]"
 
 static void read_token_parameters(SetupFileHash *setup_file_hash,
                                  struct ConfigInfo *suffix_list,
@@ -1859,7 +1823,7 @@ static void read_token_parameters(SetupFileHash *setup_file_hash,
     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++)
+    for (i = 0; suffix_list[i].token != NULL; i++)
       setString(&file_list_entry->parameter[i], suffix_list[i].value);
 
     file_list_entry->redefined = TRUE;
@@ -1879,7 +1843,7 @@ static void read_token_parameters(SetupFileHash *setup_file_hash,
 #endif
 
   /* check for config tokens that can be build by base token and suffixes */
-  for (i=0; suffix_list[i].token != NULL; i++)
+  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);
@@ -1960,7 +1924,8 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info,
   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;
+  SetupFileHash *setup_file_hash, *valid_file_hash;
+  SetupFileHash *extra_file_hash, *empty_file_hash;
   char *known_token_value = KNOWN_TOKEN_VALUE;
   int i, j, k, l;
 
@@ -1974,26 +1939,42 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info,
   if ((setup_file_hash = loadSetupFileHash(filename)) == NULL)
     return;
 
+  /* separate valid (defined) from empty (undefined) config token values */
+  valid_file_hash = newSetupFileHash();
+  empty_file_hash = newSetupFileHash();
+  BEGIN_HASH_ITERATION(setup_file_hash, itr)
+  {
+    char *value = HASH_ITERATION_VALUE(itr);
+
+    setHashEntry(*value ? valid_file_hash : empty_file_hash,
+                HASH_ITERATION_TOKEN(itr), value);
+  }
+  END_HASH_ITERATION(setup_file_hash, itr)
+
+  /* at this point, we do not need the setup file hash anymore -- free it */
+  freeSetupFileHash(setup_file_hash);
+
   /* 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]);
+  for (i = 0; i < num_file_list_entries; i++)
+    read_token_parameters(valid_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);
+  for (i = 0; i < num_ignore_tokens; i++)
+    setHashEntry(valid_file_hash, ignore_tokens[i], known_token_value);
 
-  /* copy all unknown config file tokens to extra config list */
+  /* copy all unknown config file tokens to extra config hash */
   extra_file_hash = newSetupFileHash();
-  BEGIN_HASH_ITERATION(setup_file_hash, itr)
+  BEGIN_HASH_ITERATION(valid_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));
+    char *value = HASH_ITERATION_VALUE(itr);
+
+    if (strcmp(value, known_token_value) != 0)
+      setHashEntry(extra_file_hash, HASH_ITERATION_TOKEN(itr), value);
   }
-  END_HASH_ITERATION(setup_file_hash, itr)
+  END_HASH_ITERATION(valid_file_hash, itr)
 
-  /* at this point, we do not need the config file hash anymore -- free it */
-  freeSetupFileHash(setup_file_hash);
+  /* at this point, we do not need the valid file hash anymore -- free it */
+  freeSetupFileHash(valid_file_hash);
 
   /* now try to determine valid, dynamically defined config tokens */
 
@@ -2017,7 +1998,7 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info,
     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++)
+    for (i = 0; i < num_suffix_list_entries && !parameter_suffix_found; i++)
     {
       int len_suffix = strlen(suffix_list[i].token);
 
@@ -2041,7 +2022,7 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info,
     /* ---------- step 0: search for matching base prefix ---------- */
 
     start_pos = 0;
-    for (i=0; i<num_base_prefixes && !base_prefix_found; i++)
+    for (i = 0; i < num_base_prefixes && !base_prefix_found; i++)
     {
       char *base_prefix = base_prefixes[i];
       int len_base_prefix = strlen(base_prefix);
@@ -2086,7 +2067,7 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info,
       /* ---------- step 1: search for matching first suffix ---------- */
 
       start_pos += len_base_prefix;
-      for (j=0; j<num_ext1_suffixes && !ext1_suffix_found; j++)
+      for (j = 0; j < num_ext1_suffixes && !ext1_suffix_found; j++)
       {
        char *ext1_suffix = ext1_suffixes[j];
        int len_ext1_suffix = strlen(ext1_suffix);
@@ -2128,12 +2109,12 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info,
 
       /* ---------- step 2: search for matching second suffix ---------- */
 
-      for (k=0; k<num_ext2_suffixes && !ext2_suffix_found; k++)
+      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);
+       ext2_suffix_found = token_suffix_match(token, ext2_suffix, start_pos);
 
        if (!ext2_suffix_found)
          continue;
@@ -2170,12 +2151,12 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info,
 
       /* ---------- step 3: search for matching third suffix ---------- */
 
-      for (l=0; l<num_ext3_suffixes && !ext3_suffix_found; l++)
+      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);
+       ext3_suffix_found = token_suffix_match(token, ext3_suffix, start_pos);
 
        if (!ext3_suffix_found)
          continue;
@@ -2210,11 +2191,12 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info,
                     artwork_info->sizeof_artwork_list_entry);
   }
 
-  if (extra_file_hash != NULL && options.verbose && IS_PARENT_PROCESS())
+  if (options.verbose && IS_PARENT_PROCESS())
   {
     SetupFileList *setup_file_list, *list;
     boolean dynamic_tokens_found = FALSE;
     boolean unknown_tokens_found = FALSE;
+    boolean undefined_values_found = (hashtable_count(empty_file_hash) != 0);
 
     if ((setup_file_list = loadSetupFileList(filename)) == NULL)
       Error(ERR_EXIT, "loadSetupFileHash works, but loadSetupFileList fails");
@@ -2262,13 +2244,31 @@ static void LoadArtworkConfigFromFilename(struct ArtworkListInfo *artwork_info,
       Error(ERR_RETURN_LINE, "-");
     }
 
+    if (undefined_values_found)
+    {
+      Error(ERR_RETURN_LINE, "-");
+      Error(ERR_RETURN, "warning: undefined values found in config file:");
+      Error(ERR_RETURN, "- config file: '%s'", filename);
+
+      for (list = setup_file_list; list != NULL; list = list->next)
+      {
+       char *value = getHashEntry(empty_file_hash, list->token);
+
+       if (value != NULL)
+         Error(ERR_RETURN, "- undefined value for token: '%s'", list->token);
+      }
+
+      Error(ERR_RETURN_LINE, "-");
+    }
+
     freeSetupFileList(setup_file_list);
   }
 
   freeSetupFileHash(extra_file_hash);
+  freeSetupFileHash(empty_file_hash);
 
 #if 0
-  for (i=0; i<num_file_list_entries; i++)
+  for (i = 0; i < num_file_list_entries; i++)
   {
     printf("'%s' ", file_list[i].token);
     if (file_list[i].filename)
@@ -2295,11 +2295,11 @@ void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
   DrawInitText(ARTWORKINFO_FILENAME(artwork_info->type), 150, FC_YELLOW);
 
   /* always start with reliable default values */
-  for (i=0; i<num_file_list_entries; i++)
+  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++)
+    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;
@@ -2308,7 +2308,7 @@ void LoadArtworkConfig(struct ArtworkListInfo *artwork_info)
   /* 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++)
+    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);
@@ -2520,7 +2520,7 @@ void ReloadCustomArtworkList(struct ArtworkListInfo *artwork_info)
         num_file_list_entries);
 #endif
 
-  for(i=0; i<num_file_list_entries; i++)
+  for (i = 0; i < num_file_list_entries; i++)
   {
 #if 0
     if (strcmp(file_list[i].token, "background") == 0)
@@ -2548,7 +2548,7 @@ void ReloadCustomArtworkList(struct ArtworkListInfo *artwork_info)
         num_dynamic_file_list_entries);
 #endif
 
-  for(i=0; i<num_dynamic_file_list_entries; i++)
+  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);
 
@@ -2566,7 +2566,7 @@ static void FreeCustomArtworkList(struct ArtworkListInfo *artwork_info,
   if (*list == NULL)
     return;
 
-  for(i=0; i<*num_list_entries; i++)
+  for (i = 0; i < *num_list_entries; i++)
     deleteArtworkListEntry(artwork_info, &(*list)[i]);
   free(*list);
 
index 71c0d7fe171ffcfb47a7e85a91089676191703e3..af65d4ca98343f432654b389432a3ccfdaaa68cd 100644 (file)
@@ -70,6 +70,7 @@
 void fprintf_line(FILE *, char *, int);
 void printf_line(char *, int);
 char *int2str(int, int);
+char *i_to_a(unsigned int);
 
 void InitCounter(void);
 unsigned long Counter(void);
@@ -86,7 +87,7 @@ unsigned int InitRND(long);
 #endif
 
 unsigned int init_random_number(int, long);
-unsigned int get_random_number(int, unsigned int);
+unsigned int get_random_number(int, int);
 
 char *getLoginName(void);
 char *getRealName(void);
@@ -99,7 +100,7 @@ char *getStringCopy(char *);
 char *getStringToLower(char *);
 void setString(char **, char *);
 
-void GetOptions(char **);
+void GetOptions(char **, void (*print_usage_function)(void));
 
 void SetError(char *, ...);
 char *GetError(void);
@@ -108,6 +109,7 @@ void Error(int, char *, ...);
 void *checked_malloc(unsigned long);
 void *checked_calloc(unsigned long);
 void *checked_realloc(void *, unsigned long);
+void checked_free(void *);
 
 inline void swap_numbers(int *, int *);
 inline void swap_number_pairs(int *, int *, int *, int *);
index ec19ef6389c7d639c99f9106ef17826ff53de950..a82da6cda9b3006e06b44ee4cea20a8d8e8fe3b7 100644 (file)
@@ -60,10 +60,10 @@ static void allegro_init_drivers()
 {
   int i;
 
-  for (i=0; i<MAX_EVENT_BUFFER; i++)
+  for (i = 0; i < MAX_EVENT_BUFFER; i++)
     event_buffer[i].type = 0;
 
-  for (i=0; i<MAX_SCANCODES; i++)
+  for (i = 0; i < MAX_SCANCODES; i++)
     key_press_state[i] = KeyReleaseMask;
 
   last_mouse_pos = mouse_pos;
@@ -244,7 +244,7 @@ Pixel AllegroAllocColorCell(int r, int g, int b)
   b >>= 10;
 
   /* try to use existing colors from the global colormap */
-  for (i=0; i<global_colormap_entries_used; i++)
+  for (i = 0; i < global_colormap_entries_used; i++)
   {
     if (r == global_colormap[i].r &&
        g == global_colormap[i].g &&
@@ -378,8 +378,7 @@ Status XStringListToTextProperty(char **list, int count,
 
 void XFree(void *data)
 {
-  if (data)
-    free(data);
+  checked_free(data);
 }
 
 GC XCreateGC(Display *display, Drawable d, unsigned long value_mask,
@@ -516,7 +515,7 @@ static BITMAP *Image_to_AllegroBitmap(Image *image)
   clear(bitmap);
 
   /* try to use existing colors from the global colormap */
-  for (i=0; i<MAX_COLORS; i++)
+  for (i = 0; i < MAX_COLORS; i++)
   {
     if (!image->rgb.color_used[i])
       continue;
@@ -527,8 +526,8 @@ static BITMAP *Image_to_AllegroBitmap(Image *image)
   }
 
   /* copy bitmap data */
-  for (y=0; y<image->height; y++)
-    for (x=0; x<image->width; x++)
+  for (y = 0; y < image->height; y++)
+    for (x = 0; x < image->width; x++)
       putpixel(bitmap, x, y, pixel_mapping[*src_ptr++]);
 
   return bitmap;
@@ -598,11 +597,9 @@ void XFreePixmap(Display *display, Pixmap pixmap)
 
 void XFreeGC(Display *display, GC gc)
 {
-  XGCValues *gcv;
+  XGCValues *gcv = (XGCValues *)gc;
 
-  gcv = (XGCValues *)gc;
-  if (gcv)
-    free(gcv);
+  checked_free(gcv);
 }
 
 void XUnmapWindow(Display *display, Window window)
@@ -616,11 +613,8 @@ void XCloseDisplay(Display *display)
   if (is_screen_bitmap(bitmap))
     destroy_bitmap(bitmap);
 
-  if (display->screens)
-    free(display->screens);
-
-  if (display)
-    free(display);
+  checked_free(display->screens);
+  checked_free(display);
 
   /* return to text mode (or DOS box on Windows screen) */
   set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
@@ -671,7 +665,7 @@ static void HandleKeyboardRaw(int mode)
 {
   int i;
 
-  for (i=0; i<MAX_SCANCODES; i++)
+  for (i = 0; i < MAX_SCANCODES; i++)
   {
     int scancode, new_state, event_type;
     char key_pressed;
@@ -783,7 +777,7 @@ int XPending(Display *display)
   /* mouse button event */
   if (mouse_b != last_mouse_b)
   {
-    for (i=0; i<3; i++)                /* check all three mouse buttons */
+    for (i = 0; i < 3; i++)    /* check all three mouse buttons */
     {
       int bitmask = (1 << i);
 
@@ -969,7 +963,7 @@ void MSDOSInitJoysticks()
       install_joystick(JOY_TYPE_AUTODETECT) == 0)
     joystick.status = JOYSTICK_ACTIVATED;
 
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
   {
     char *device_name = setup.input[i].joy.device_name;
     int joystick_nr = getJoystickNrFromDeviceName(device_name);
index 47a11d462fec86888cdb14b7cd7e39c99a3708ab..5fdf6f3ecb56d7a53e3272c8b6d88e7df2a604fa 100644 (file)
@@ -220,7 +220,7 @@ static byte *PCX_ReadColormap(Image *image,byte *buffer_ptr, byte *buffer_last)
     return NULL;
 
   /* read 256 colors from PCX colormap */
-  for (i=0; i<PCX_MAXCOLORS; i++)
+  for (i = 0; i < PCX_MAXCOLORS; i++)
   {
     image->rgb.red[i]   = *buffer_ptr++ << 8;
     image->rgb.green[i] = *buffer_ptr++ << 8;
@@ -256,7 +256,7 @@ static boolean PCX_ReadColormap(FILE *file,struct PCX_Header *pcx,Image *image)
     while (value != PCX_256COLORS_MAGIC);
 
     /* read 256 colors from PCX colormap */
-    for(i = 0; i < PCX_MAXCOLORS; i++)
+    for (i = 0; i < PCX_MAXCOLORS; i++)
     {
       image->rgb.red[i]   = (byte)fgetc(file) << 8;
       image->rgb.green[i] = (byte)fgetc(file) << 8;
@@ -265,7 +265,7 @@ static boolean PCX_ReadColormap(FILE *file,struct PCX_Header *pcx,Image *image)
   }
   else
   {
-    for(i = 0; i < num_colors; i++)
+    for (i = 0; i < num_colors; i++)
     {
       image->rgb.red[i]   = pcx->palette[i][0] << 8;
       image->rgb.green[i] = pcx->palette[i][1] << 8;
@@ -375,7 +375,7 @@ Image *Read_PCX_to_Image(char *filename)
   if (pcx_depth == 8)
   {
     /* determine number of used colormap entries for 8-bit PCX images */
-    for (i=0; i<PCX_MAXCOLORS; i++)
+    for (i = 0; i < PCX_MAXCOLORS; i++)
       if (image->rgb.color_used[i])
        image->rgb.used++;
   }
index 74123228f2b2185f43100f4c3b2d5c19b70f356a..e9d10df51f3a8103acb3520b27615e00cb487e1c 100644 (file)
@@ -71,7 +71,7 @@ inline void SDLInitVideoBuffer(DrawBuffer **backbuffer, DrawWindow **window,
   fullscreen_yoffset = 0;
 
 #ifdef FULLSCREEN_BUG
-  for (i=0; screen_xy[i][0] != -1; i++)
+  for (i = 0; screen_xy[i][0] != -1; i++)
   {
     if (video.width <= screen_xy[i][0] && video.height <= screen_xy[i][1])
     {
@@ -340,11 +340,11 @@ inline void SDLDrawLines(SDL_Surface *surface, struct XY *points,
   int i, x, y;
   int line_width = 4;
 
-  for (i=0; i<num_points - 1; i++)
+  for (i = 0; i < num_points - 1; i++)
   {
-    for (x=0; x<line_width; x++)
+    for (x = 0; x < line_width; x++)
     {
-      for (y=0; y<line_width; y++)
+      for (y = 0; y < line_width; y++)
       {
        int dx = x - line_width / 2;
        int dy = y - line_width / 2;
@@ -889,9 +889,9 @@ inline void SDLInvertArea(Bitmap *bitmap, int src_x, int src_y,
 {
   int x, y;
 
-  for (y=src_y; y < src_y + height; y++)
+  for (y = src_y; y < src_y + height; y++)
   {
-    for (x=src_x; x < src_x + width; x++)
+    for (x = src_x; x < src_x + width; x++)
     {
       Uint32 pixel = SDLGetPixel(bitmap, x, y);
 
@@ -906,9 +906,9 @@ inline void SDLCopyInverseMasked(Bitmap *src_bitmap, Bitmap *dst_bitmap,
 {
   int x, y;
 
-  for (y=0; y < height; y++)
+  for (y = 0; y < height; y++)
   {
-    for (x=0; x < width; x++)
+    for (x = 0; x < width; x++)
     {
       Uint32 pixel = SDLGetPixel(src_bitmap, src_x + x, src_y + y);
 
@@ -1181,7 +1181,7 @@ SDL_Surface *zoomSurface(SDL_Surface *src, int dst_width, int dst_height)
   else
   {
     /* copy palette */
-    for (i=0; i < zoom_src->format->palette->ncolors; i++)
+    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;
@@ -1454,7 +1454,7 @@ void SDLInitJoysticks()
     }
   }
 
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
   {
     char *device_name = setup.input[i].joy.device_name;
     int joystick_nr = getJoystickNrFromDeviceName(device_name);
index 3eb935c9b2df572e5ee1ad51bcfebe5b47f58c1e..905c890ed0761d45229bdc3cf4834bf657a3079f 100644 (file)
@@ -97,8 +97,7 @@ static char *getUserLevelDir(char *level_subdir)
   char *data_dir = getUserDataDir();
   char *userlevel_subdir = LEVELS_DIRECTORY;
 
-  if (userlevel_dir)
-    free(userlevel_dir);
+  checked_free(userlevel_dir);
 
   if (level_subdir != NULL)
     userlevel_dir = getPath3(data_dir, userlevel_subdir, level_subdir);
@@ -108,31 +107,13 @@ static char *getUserLevelDir(char *level_subdir)
   return userlevel_dir;
 }
 
-static char *getTapeDir(char *level_subdir)
-{
-  static char *tape_dir = NULL;
-  char *data_dir = getUserDataDir();
-  char *tape_subdir = TAPES_DIRECTORY;
-
-  if (tape_dir)
-    free(tape_dir);
-
-  if (level_subdir != NULL)
-    tape_dir = getPath3(data_dir, tape_subdir, level_subdir);
-  else
-    tape_dir = getPath2(data_dir, tape_subdir);
-
-  return tape_dir;
-}
-
 static char *getScoreDir(char *level_subdir)
 {
   static char *score_dir = NULL;
   char *data_dir = getCommonDataDir();
   char *score_subdir = SCORES_DIRECTORY;
 
-  if (score_dir)
-    free(score_dir);
+  checked_free(score_dir);
 
   if (level_subdir != NULL)
     score_dir = getPath3(data_dir, score_subdir, level_subdir);
@@ -148,8 +129,7 @@ static char *getLevelSetupDir(char *level_subdir)
   char *data_dir = getUserDataDir();
   char *levelsetup_subdir = LEVELSETUP_DIRECTORY;
 
-  if (levelsetup_dir)
-    free(levelsetup_dir);
+  checked_free(levelsetup_dir);
 
   if (level_subdir != NULL)
     levelsetup_dir = getPath3(data_dir, levelsetup_subdir, level_subdir);
@@ -166,8 +146,7 @@ static char *getLevelDirFromTreeInfo(TreeInfo *node)
   if (node == NULL)
     return options.level_directory;
 
-  if (level_dir)
-    free(level_dir);
+  checked_free(level_dir);
 
   level_dir = getPath2((node->user_defined ? getUserLevelDir(NULL) :
                        options.level_directory), node->fullpath);
@@ -180,6 +159,35 @@ static char *getCurrentLevelDir()
   return getLevelDirFromTreeInfo(leveldir_current);
 }
 
+static char *getTapeDir(char *level_subdir)
+{
+  static char *tape_dir = NULL;
+  char *data_dir = getUserDataDir();
+  char *tape_subdir = TAPES_DIRECTORY;
+
+  checked_free(tape_dir);
+
+  if (level_subdir != NULL)
+    tape_dir = getPath3(data_dir, tape_subdir, level_subdir);
+  else
+    tape_dir = getPath2(data_dir, tape_subdir);
+
+  return tape_dir;
+}
+
+static char *getSolutionTapeDir()
+{
+  static char *tape_dir = NULL;
+  char *data_dir = getCurrentLevelDir();
+  char *tape_subdir = TAPES_DIRECTORY;
+
+  checked_free(tape_dir);
+
+  tape_dir = getPath2(data_dir, tape_subdir);
+
+  return tape_dir;
+}
+
 static char *getDefaultGraphicsDir(char *graphics_subdir)
 {
   static char *graphics_dir = NULL;
@@ -187,8 +195,7 @@ static char *getDefaultGraphicsDir(char *graphics_subdir)
   if (graphics_subdir == NULL)
     return options.graphics_directory;
 
-  if (graphics_dir)
-    free(graphics_dir);
+  checked_free(graphics_dir);
 
   graphics_dir = getPath2(options.graphics_directory, graphics_subdir);
 
@@ -202,8 +209,7 @@ static char *getDefaultSoundsDir(char *sounds_subdir)
   if (sounds_subdir == NULL)
     return options.sounds_directory;
 
-  if (sounds_dir)
-    free(sounds_dir);
+  checked_free(sounds_dir);
 
   sounds_dir = getPath2(options.sounds_directory, sounds_subdir);
 
@@ -217,8 +223,7 @@ static char *getDefaultMusicDir(char *music_subdir)
   if (music_subdir == NULL)
     return options.music_directory;
 
-  if (music_dir)
-    free(music_dir);
+  checked_free(music_dir);
 
   music_dir = getPath2(options.music_directory, music_subdir);
 
@@ -276,8 +281,7 @@ static char *getSetupArtworkDir(TreeInfo *ti)
 {
   static char *artwork_dir = NULL;
 
-  if (artwork_dir != NULL)
-    free(artwork_dir);
+  checked_free(artwork_dir);
 
   artwork_dir = getPath2(ti->basepath, ti->fullpath);
 
@@ -295,8 +299,7 @@ char *setLevelArtworkDir(TreeInfo *ti)
   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);
+  checked_free(*artwork_path_ptr);
 
   if ((level_artwork = getTreeInfoFromIdentifier(ti, *artwork_set_ptr)))
     *artwork_path_ptr = getStringCopy(getSetupArtworkDir(level_artwork));
@@ -311,8 +314,7 @@ char *setLevelArtworkDir(TreeInfo *ti)
 
     char *dir = getPath2(getCurrentLevelDir(), ARTWORK_DIRECTORY(ti->type));
 
-    if (*artwork_set_ptr != NULL)
-      free(*artwork_set_ptr);
+    checked_free(*artwork_set_ptr);
 
     if (fileExists(dir))
     {
@@ -352,8 +354,7 @@ char *getLevelFilename(int nr)
   static char *filename = NULL;
   char basename[MAX_FILENAME_LEN];
 
-  if (filename != NULL)
-    free(filename);
+  checked_free(filename);
 
   if (nr < 0)
     sprintf(basename, "template.%s", LEVELFILE_EXTENSION);
@@ -370,8 +371,7 @@ char *getTapeFilename(int nr)
   static char *filename = NULL;
   char basename[MAX_FILENAME_LEN];
 
-  if (filename != NULL)
-    free(filename);
+  checked_free(filename);
 
   sprintf(basename, "%03d.%s", nr, TAPEFILE_EXTENSION);
   filename = getPath2(getTapeDir(leveldir_current->filename), basename);
@@ -379,13 +379,25 @@ char *getTapeFilename(int nr)
   return filename;
 }
 
+char *getSolutionTapeFilename(int nr)
+{
+  static char *filename = NULL;
+  char basename[MAX_FILENAME_LEN];
+
+  checked_free(filename);
+
+  sprintf(basename, "%03d.%s", nr, TAPEFILE_EXTENSION);
+  filename = getPath2(getSolutionTapeDir(), basename);
+
+  return filename;
+}
+
 char *getScoreFilename(int nr)
 {
   static char *filename = NULL;
   char basename[MAX_FILENAME_LEN];
 
-  if (filename != NULL)
-    free(filename);
+  checked_free(filename);
 
   sprintf(basename, "%03d.%s", nr, SCOREFILE_EXTENSION);
   filename = getPath2(getScoreDir(leveldir_current->filename), basename);
@@ -397,14 +409,75 @@ char *getSetupFilename()
 {
   static char *filename = NULL;
 
-  if (filename != NULL)
-    free(filename);
+  checked_free(filename);
 
   filename = getPath2(getSetupDir(), SETUP_FILENAME);
 
   return filename;
 }
 
+char *getEditorSetupFilename()
+{
+  static char *filename = NULL;
+
+  checked_free(filename);
+
+  filename = getPath2(getSetupDir(), EDITORSETUP_FILENAME);
+
+  return filename;
+}
+
+char *getHelpAnimFilename()
+{
+  static char *filename = NULL;
+
+  checked_free(filename);
+
+  filename = getPath2(getCurrentLevelDir(), HELPANIM_FILENAME);
+
+  return filename;
+}
+
+char *getHelpTextFilename()
+{
+  static char *filename = NULL;
+
+  checked_free(filename);
+
+  filename = getPath2(getCurrentLevelDir(), HELPTEXT_FILENAME);
+
+  return filename;
+}
+
+char *getLevelSetInfoFilename()
+{
+  static char *filename = NULL;
+  char *basenames[] =
+  {
+    "README",
+    "README.txt",
+    "README.TXT",
+    "Readme",
+    "Readme.txt",
+    "readme",
+    "readme.txt",
+
+    NULL
+  };
+  int i;
+
+  for (i = 0; basenames[i] != NULL; i++)
+  {
+    checked_free(filename);
+
+    filename = getPath2(getCurrentLevelDir(), basenames[i]);
+    if (fileExists(filename))
+      return filename;
+  }
+
+  return NULL;
+}
+
 static char *getCorrectedArtworkBasename(char *basename)
 {
   char *basename_corrected = basename;
@@ -424,8 +497,7 @@ static char *getCorrectedArtworkBasename(char *basename)
     {
       static char *msdos_filename = NULL;
 
-      if (msdos_filename != NULL)
-       free(msdos_filename);
+      checked_free(msdos_filename);
 
       msdos_filename = getStringCopy(basename_corrected);
       strncpy(&msdos_filename[8], &basename[strlen(basename) - (1+3)], 1+3 +1);
@@ -443,8 +515,7 @@ char *getCustomImageFilename(char *basename)
   static char *filename = NULL;
   boolean skip_setup_artwork = FALSE;
 
-  if (filename != NULL)
-    free(filename);
+  checked_free(filename);
 
   basename = getCorrectedArtworkBasename(basename);
 
@@ -502,8 +573,7 @@ char *getCustomSoundFilename(char *basename)
   static char *filename = NULL;
   boolean skip_setup_artwork = FALSE;
 
-  if (filename != NULL)
-    free(filename);
+  checked_free(filename);
 
   basename = getCorrectedArtworkBasename(basename);
 
@@ -556,12 +626,72 @@ char *getCustomSoundFilename(char *basename)
   return NULL;         /* cannot find specified artwork file anywhere */
 }
 
+char *getCustomMusicFilename(char *basename)
+{
+  static char *filename = NULL;
+  boolean skip_setup_artwork = FALSE;
+
+  checked_free(filename);
+
+  basename = getCorrectedArtworkBasename(basename);
+
+  if (!setup.override_level_music)
+  {
+    /* 1st try: look for special artwork in current level series directory */
+    filename = getPath3(getCurrentLevelDir(), MUSIC_DIRECTORY, basename);
+    if (fileExists(filename))
+      return filename;
+
+    free(filename);
+
+    /* 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 */
+      filename = getPath2(getLevelArtworkDir(TREE_TYPE_MUSIC_DIR), basename);
+      if (fileExists(filename))
+       return filename;
+
+      free(filename);
+
+      /* take missing artwork configured in level set config from default */
+      skip_setup_artwork = TRUE;
+    }
+  }
+
+  if (!skip_setup_artwork)
+  {
+    /* 3rd try: look for special artwork in configured artwork directory */
+    filename = getPath2(getSetupArtworkDir(artwork.mus_current), basename);
+    if (fileExists(filename))
+      return filename;
+
+    free(filename);
+  }
+
+  /* 4th try: look for default artwork in new default artwork directory */
+  filename = getPath2(getDefaultMusicDir(MUS_CLASSIC_SUBDIR), basename);
+  if (fileExists(filename))
+    return filename;
+
+  free(filename);
+
+  /* 5th try: look for default artwork in old default artwork directory */
+  filename = getPath2(options.music_directory, basename);
+  if (fileExists(filename))
+    return filename;
+
+  return NULL;         /* cannot find specified artwork file anywhere */
+}
+
 char *getCustomArtworkFilename(char *basename, int type)
 {
   if (type == ARTWORK_TYPE_GRAPHICS)
     return getCustomImageFilename(basename);
   else if (type == ARTWORK_TYPE_SOUNDS)
     return getCustomSoundFilename(basename);
+  else if (type == ARTWORK_TYPE_MUSIC)
+    return getCustomMusicFilename(basename);
   else
     return UNDEFINED_FILENAME;
 }
@@ -575,8 +705,7 @@ char *getCustomArtworkLevelConfigFilename(int type)
 {
   static char *filename = NULL;
 
-  if (filename != NULL)
-    free(filename);
+  checked_free(filename);
 
   filename = getPath2(getLevelArtworkDir(type), ARTWORKINFO_FILENAME(type));
 
@@ -588,8 +717,7 @@ char *getCustomMusicDirectory(void)
   static char *directory = NULL;
   boolean skip_setup_artwork = FALSE;
 
-  if (directory != NULL)
-    free(directory);
+  checked_free(directory);
 
   if (!setup.override_level_music)
   {
@@ -813,7 +941,7 @@ void dumpTreeInfo(TreeInfo *node, int depth)
 
   while (node)
   {
-    for (i=0; i<(depth + 1) * 3; i++)
+    for (i = 0; i < (depth + 1) * 3; i++)
       printf(" ");
 
 #if 1
@@ -859,7 +987,7 @@ void sortTreeInfo(TreeInfo **node_first,
        compare_function);
 
   /* update the linkage of list elements with the sorted node array */
-  for (i=0; i<num_nodes - 1; i++)
+  for (i = 0; i < num_nodes - 1; i++)
     sort_array[i]->next = sort_array[i + 1];
   sort_array[num_nodes - 1]->next = NULL;
 
@@ -1081,9 +1209,13 @@ char *getFormattedSetupEntry(char *token, char *value)
   int i;
   static char entry[MAX_LINE_LEN];
 
+  /* if value is an empty string, just return token without value */
+  if (*value == '\0')
+    return token;
+
   /* start with the token and some spaces to format output line */
   sprintf(entry, "%s:", token);
-  for (i=strlen(entry); i<TOKEN_VALUE_POSITION; i++)
+  for (i = strlen(entry); i < TOKEN_VALUE_POSITION; i++)
     strcat(entry, " ");
 
   /* continue with the token's value */
@@ -1109,12 +1241,12 @@ void freeSetupFileList(SetupFileList *list)
   if (list == NULL)
     return;
 
-  if (list->token)
-    free(list->token);
-  if (list->value)
-    free(list->value);
+  checked_free(list->token);
+  checked_free(list->value);
+
   if (list->next)
     freeSetupFileList(list->next);
+
   free(list);
 }
 
@@ -1136,8 +1268,7 @@ SetupFileList *setListEntry(SetupFileList *list, char *token, char *value)
 
   if (strcmp(list->token, token) == 0)
   {
-    if (list->value)
-      free(list->value);
+    checked_free(list->value);
 
     list->value = getStringCopy(value);
 
@@ -1149,6 +1280,17 @@ SetupFileList *setListEntry(SetupFileList *list, char *token, char *value)
     return setListEntry(list->next, token, value);
 }
 
+SetupFileList *addListEntry(SetupFileList *list, char *token, char *value)
+{
+  if (list == NULL)
+    return NULL;
+
+  if (list->next == NULL)
+    return (list->next = newSetupFileList(token, value));
+  else
+    return addListEntry(list->next, token, value);
+}
+
 #ifdef DEBUG
 static void printSetupFileList(SetupFileList *list)
 {
@@ -1214,6 +1356,9 @@ SetupFileHash *newSetupFileHash()
   SetupFileHash *new_hash =
     create_hashtable(16, 0.75, get_hash_from_key, keys_are_equal);
 
+  if (new_hash == NULL)
+    Error(ERR_EXIT, "create_hashtable() failed -- out of memory");
+
   return new_hash;
 }
 
@@ -1248,6 +1393,14 @@ void setHashEntry(SetupFileHash *hash, char *token, char *value)
       Error(ERR_EXIT, "cannot insert into hash -- aborting");
 }
 
+char *removeHashEntry(SetupFileHash *hash, char *token)
+{
+  if (hash == NULL)
+    return NULL;
+
+  return remove_hash_entry(hash, token);
+}
+
 #if 0
 #ifdef DEBUG
 static void printSetupFileHash(SetupFileHash *hash)
@@ -1264,10 +1417,10 @@ static void printSetupFileHash(SetupFileHash *hash)
 
 static void *loadSetupFileData(char *filename, boolean use_hash)
 {
-  int line_len;
-  char line[MAX_LINE_LEN];
+  char line[MAX_LINE_LEN], previous_line[MAX_LINE_LEN];
   char *token, *value, *line_ptr;
   void *setup_file_data, *insert_ptr = NULL;
+  boolean read_continued_line = FALSE;
   FILE *file;
 
   if (use_hash)
@@ -1281,16 +1434,48 @@ static void *loadSetupFileData(char *filename, boolean use_hash)
     return NULL;
   }
 
-  while(!feof(file))
+  while (!feof(file))
   {
     /* read next line of input file */
     if (!fgets(line, MAX_LINE_LEN, file))
       break;
 
-    /* cut trailing comment or whitespace from input line */
+    /* cut trailing newline or carriage return */
+    for (line_ptr = &line[strlen(line)]; line_ptr >= line; line_ptr--)
+      if ((*line_ptr == '\n' || *line_ptr == '\r') && *(line_ptr + 1) == '\0')
+       *line_ptr = '\0';
+
+    if (read_continued_line)
+    {
+      /* cut leading whitespaces from input line */
+      for (line_ptr = line; *line_ptr; line_ptr++)
+       if (*line_ptr != ' ' && *line_ptr != '\t')
+         break;
+
+      /* append new line to existing line, if there is enough space */
+      if (strlen(previous_line) + strlen(line_ptr) < MAX_LINE_LEN)
+       strcat(previous_line, line_ptr);
+
+      strcpy(line, previous_line);     /* copy storage buffer to line */
+
+      read_continued_line = FALSE;
+    }
+
+    /* if the last character is '\', continue at next line */
+    if (strlen(line) > 0 && line[strlen(line) - 1] == '\\')
+    {
+      line[strlen(line) - 1] = '\0';   /* cut off trailing backslash */
+      strcpy(previous_line, line);     /* copy line to storage buffer */
+
+      read_continued_line = TRUE;
+
+      continue;
+    }
+
+    /* cut trailing comment from input line */
     for (line_ptr = line; *line_ptr; line_ptr++)
     {
-      if (*line_ptr == '#' || *line_ptr == '\n' || *line_ptr == '\r')
+      if (*line_ptr == '#')
       {
        *line_ptr = '\0';
        break;
@@ -1298,47 +1483,50 @@ static void *loadSetupFileData(char *filename, boolean use_hash)
     }
 
     /* cut trailing whitespaces from input line */
-    for (line_ptr = &line[strlen(line)]; line_ptr > line; line_ptr--)
-      if ((*line_ptr == ' ' || *line_ptr == '\t') && line_ptr[1] == '\0')
+    for (line_ptr = &line[strlen(line)]; line_ptr >= line; line_ptr--)
+      if ((*line_ptr == ' ' || *line_ptr == '\t') && *(line_ptr + 1) == '\0')
        *line_ptr = '\0';
 
     /* ignore empty lines */
     if (*line == '\0')
       continue;
 
-    line_len = strlen(line);
-
     /* cut leading whitespaces from token */
     for (token = line; *token; token++)
       if (*token != ' ' && *token != '\t')
        break;
 
-    /* find end of token */
+    /* start with empty value as reliable default */
+    value = "";
+
+    /* find end of token to determine start of value */
     for (line_ptr = token; *line_ptr; line_ptr++)
     {
       if (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == ':')
       {
-       *line_ptr = '\0';
+       *line_ptr = '\0';               /* terminate token string */
+       value = line_ptr + 1;           /* set beginning of value */
+
        break;
       }
     }
 
-    if (line_ptr < line + line_len)
-      value = line_ptr + 1;
-    else
-      value = "\0";
-
     /* cut leading whitespaces from value */
     for (; *value; value++)
       if (*value != ' ' && *value != '\t')
        break;
 
-    if (*token && *value)
+#if 0
+    if (*value == '\0')
+      value = "true";  /* treat tokens without value as "true" */
+#endif
+
+    if (*token)
     {
       if (use_hash)
        setHashEntry((SetupFileHash *)setup_file_data, token, value);
       else
-       insert_ptr = setListEntry((SetupFileList *)insert_ptr, token, value);
+       insert_ptr = addListEntry((SetupFileList *)insert_ptr, token, value);
     }
   }
 
@@ -1589,40 +1777,26 @@ static void setTreeInfoToDefaultsFromParent(TreeInfo *ldi, TreeInfo *parent)
 
 static void freeTreeInfo(TreeInfo *ldi)
 {
-  if (ldi->filename)
-    free(ldi->filename);
-  if (ldi->fullpath)
-    free(ldi->fullpath);
-  if (ldi->basepath)
-    free(ldi->basepath);
-  if (ldi->identifier)
-    free(ldi->identifier);
-
-  if (ldi->name)
-    free(ldi->name);
-  if (ldi->name_sorting)
-    free(ldi->name_sorting);
-  if (ldi->author)
-    free(ldi->author);
-
-  if (ldi->class_desc)
-    free(ldi->class_desc);
+  checked_free(ldi->filename);
+  checked_free(ldi->fullpath);
+  checked_free(ldi->basepath);
+  checked_free(ldi->identifier);
+
+  checked_free(ldi->name);
+  checked_free(ldi->name_sorting);
+  checked_free(ldi->author);
+
+  checked_free(ldi->class_desc);
 
   if (ldi->type == TREE_TYPE_LEVEL_DIR)
   {
-    if (ldi->graphics_set)
-      free(ldi->graphics_set);
-    if (ldi->sounds_set)
-      free(ldi->sounds_set);
-    if (ldi->music_set)
-      free(ldi->music_set);
-
-    if (ldi->graphics_path)
-      free(ldi->graphics_path);
-    if (ldi->sounds_path)
-      free(ldi->sounds_path);
-    if (ldi->music_path)
-      free(ldi->music_path);
+    checked_free(ldi->graphics_set);
+    checked_free(ldi->sounds_set);
+    checked_free(ldi->music_set);
+
+    checked_free(ldi->graphics_path);
+    checked_free(ldi->sounds_path);
+    checked_free(ldi->music_path);
   }
 }
 
@@ -1656,8 +1830,7 @@ void setSetupInfo(struct TokenInfo *token_info,
       break;
 
     case TYPE_STRING:
-      if (*(char **)setup_value != NULL)
-       free(*(char **)setup_value);
+      checked_free(*(char **)setup_value);
       *(char **)setup_value = getStringCopy(token_value);
       break;
 
@@ -1783,7 +1956,7 @@ static boolean LoadLevelInfoFromLevelConf(TreeInfo **node_first,
 
   /* set all structure fields according to the token/value pairs */
   ldi = *leveldir_new;
-  for (i=0; i<NUM_LEVELINFO_TOKENS; i++)
+  for (i = 0; i < NUM_LEVELINFO_TOKENS; i++)
     setSetupInfo(levelinfo_tokens, i,
                 getHashEntry(setup_file_hash, levelinfo_tokens[i].text));
   *leveldir_new = ldi;
@@ -2013,7 +2186,7 @@ static boolean LoadArtworkInfoFromArtworkConf(TreeInfo **node_first,
 
     /* set all structure fields according to the token/value pairs */
     ldi = *artwork_new;
-    for (i=0; i<NUM_LEVELINFO_TOKENS; i++)
+    for (i = 0; i < NUM_LEVELINFO_TOKENS; i++)
       setSetupInfo(levelinfo_tokens, i,
                   getHashEntry(setup_file_hash, levelinfo_tokens[i].text));
     *artwork_new = ldi;
@@ -2221,8 +2394,7 @@ static TreeInfo *getDummyArtworkInfo(int type)
   artwork_new->fullpath = getStringCopy(UNDEFINED_FILENAME);
   artwork_new->basepath = getStringCopy(UNDEFINED_FILENAME);
 
-  if (artwork_new->name != NULL)
-    free(artwork_new->name);
+  checked_free(artwork_new->name);
 
   artwork_new->identifier   = getStringCopy(UNDEFINED_FILENAME);
   artwork_new->name         = getStringCopy(UNDEFINED_FILENAME);
@@ -2458,7 +2630,7 @@ static void SaveUserLevelInfo()
                                                 getCookie("LEVELINFO")));
 
   ldi = *level_info;
-  for (i=0; i<NUM_LEVELINFO_TOKENS; i++)
+  for (i = 0; i < NUM_LEVELINFO_TOKENS; i++)
     if (i != LEVELINFO_TOKEN_IDENTIFIER &&
        i != LEVELINFO_TOKEN_NAME_SORTING &&
        i != LEVELINFO_TOKEN_IMPORTED_FROM)
@@ -2544,7 +2716,7 @@ char *getSetupLine(struct TokenInfo *token_info, char *prefix, int token_nr)
     {
       /* add at least one whitespace */
       strcat(line, " ");
-      for (i=strlen(line); i<TOKEN_COMMENT_POSITION; i++)
+      for (i = strlen(line); i < TOKEN_COMMENT_POSITION; i++)
        strcat(line, " ");
 
       strcat(line, "# ");
@@ -2557,17 +2729,15 @@ char *getSetupLine(struct TokenInfo *token_info, char *prefix, int token_nr)
 
 void LoadLevelSetup_LastSeries()
 {
-  char *filename;
-  SetupFileHash *level_setup_hash = NULL;
-
-  /* always start with reliable default values */
-  leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
-
   /* ----------------------------------------------------------------------- */
   /* ~/.<program>/levelsetup.conf                                            */
   /* ----------------------------------------------------------------------- */
 
-  filename = getPath2(getSetupDir(), LEVELSETUP_FILENAME);
+  char *filename = getPath2(getSetupDir(), LEVELSETUP_FILENAME);
+  SetupFileHash *level_setup_hash = NULL;
+
+  /* always start with reliable default values */
+  leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
 
   if ((level_setup_hash = loadSetupFileHash(filename)))
   {
@@ -2591,17 +2761,15 @@ void LoadLevelSetup_LastSeries()
 
 void SaveLevelSetup_LastSeries()
 {
-  char *filename;
-  char *level_subdir = leveldir_current->filename;
-  FILE *file;
-
   /* ----------------------------------------------------------------------- */
   /* ~/.<program>/levelsetup.conf                                            */
   /* ----------------------------------------------------------------------- */
 
-  InitUserDataDirectory();
+  char *filename = getPath2(getSetupDir(), LEVELSETUP_FILENAME);
+  char *level_subdir = leveldir_current->filename;
+  FILE *file;
 
-  filename = getPath2(getSetupDir(), LEVELSETUP_FILENAME);
+  InitUserDataDirectory();
 
   if (!(file = fopen(filename, MODE_WRITE)))
   {
index 2498fe7d2345f5500484d05a99590454eaa74b5d..1f46cc201aa30621b9c96fc368557277b13792af 100644 (file)
                                         TYPE_YES_NO)
 
 /* additional values for setup screen */
-#define TYPE_ENTER_MENU                        (1 << 8)
-#define TYPE_LEAVE_MENU                        (1 << 9)
-#define TYPE_EMPTY                     (1 << 10)
-#define TYPE_KEYTEXT                   (1 << 11)
+#define TYPE_ENTER_SCREEN              (1 << 8)
+#define TYPE_ENTER_MENU                        (1 << 9)
+#define TYPE_LEAVE_MENU                        (1 << 10)
+#define TYPE_EMPTY                     (1 << 11)
+#define TYPE_KEYTEXT                   (1 << 12)
 
-#define TYPE_GHOSTED                   (1 << 12)
-#define TYPE_QUERY                     (1 << 13)
+#define TYPE_GHOSTED                   (1 << 13)
+#define TYPE_QUERY                     (1 << 14)
 
 #define TYPE_VALUE                     (TYPE_BOOLEAN_STYLE     | \
                                         TYPE_KEY               | \
@@ -52,7 +53,8 @@
                                         TYPE_KEY               | \
                                         TYPE_STRING)
 
-#define TYPE_ENTER_OR_LEAVE_MENU       (TYPE_ENTER_MENU        | \
+#define TYPE_ENTER_OR_LEAVE_MENU       (TYPE_ENTER_SCREEN      | \
+                                        TYPE_ENTER_MENU        | \
                                         TYPE_LEAVE_MENU)
 
 /* cookie token for file identifier and version number */
@@ -67,7 +69,7 @@ struct TokenInfo
 
 /* some definitions for list and hash handling */
 typedef struct SetupFileList SetupFileList;
-typedef struct hashtable SetupFileHash;
+typedef struct hashtable     SetupFileHash;
 
 #define BEGIN_HASH_ITERATION(hash, itr)                                \
   if (hash != NULL && hashtable_count(hash) > 0)               \
@@ -194,11 +196,17 @@ typedef struct hashtable SetupFileHash;
 char *setLevelArtworkDir(TreeInfo *);
 char *getLevelFilename(int);
 char *getTapeFilename(int);
+char *getSolutionTapeFilename(int);
 char *getScoreFilename(int);
 char *getSetupFilename(void);
+char *getEditorSetupFilename(void);
+char *getHelpAnimFilename(void);
+char *getHelpTextFilename(void);
+char *getLevelSetInfoFilename(void);
 char *getImageFilename(char *);
 char *getCustomImageFilename(char *);
 char *getCustomSoundFilename(char *);
+char *getCustomMusicFilename(char *);
 char *getCustomArtworkFilename(char *, int);
 char *getCustomArtworkConfigFilename(int);
 char *getCustomArtworkLevelConfigFilename(int);
@@ -240,12 +248,14 @@ SetupFileList *newSetupFileList(char *, char *);
 void freeSetupFileList(SetupFileList *);
 char *getListEntry(SetupFileList *, char *);
 SetupFileList *setListEntry(SetupFileList *, char *, char *);
+SetupFileList *addListEntry(SetupFileList *, char *, char *);
 SetupFileList *loadSetupFileList(char *);
 
 SetupFileHash *newSetupFileHash();
 void freeSetupFileHash(SetupFileHash *);
 char *getHashEntry(SetupFileHash *, char *);
 void setHashEntry(SetupFileHash *, char *, char *);
+char *removeHashEntry(SetupFileHash *, char *);
 SetupFileHash *loadSetupFileHash(char *);
 void checkSetupFileHashIdentifier(SetupFileHash *, char *);
 void setSetupInfo(struct TokenInfo *, int, char *);
index 72681647ed847bbfeba8edf3ea3172408532e22a..a70ea3accf9018ed7c264f76b6bc06f61a89f5b6 100644 (file)
@@ -149,14 +149,19 @@ struct SoundControl
 typedef struct SoundControl SoundControl;
 
 static struct ArtworkListInfo *sound_info = NULL;
+static struct ArtworkListInfo *music_info = NULL;
+
 #if 0
 static SoundInfo **Sound = NULL;
 #endif
-static MusicInfo **Music = NULL;
+
+static MusicInfo **Music_NoConf = NULL;
+
 #if 0
 static int num_sounds = 0;
 #endif
-static int num_music = 0;
+
+static int num_music_noconf = 0;
 static int stereo_volume[SOUND_MAX_LEFT2RIGHT + 1];
 
 
@@ -179,8 +184,11 @@ static int ulaw_to_linear(unsigned char);
 static void ReloadCustomSounds();
 static void ReloadCustomMusic();
 static void FreeSound(void *);
+static void FreeMusic(void *);
+static void FreeAllMusic_NoConf();
 
 static SoundInfo *getSoundInfoEntryFromSoundID(int);
+static MusicInfo *getMusicInfoEntryFromMusicID(int);
 
 
 /* ------------------------------------------------------------------------- */
@@ -229,7 +237,7 @@ static boolean TestAudioDevices(void)
   int i;
 
   /* look for available audio devices, starting with preferred ones */
-  for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
+  for (i = 0; i < sizeof(audio_device_name)/sizeof(char *); i++)
     if ((audio_device_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
       break;
 
@@ -561,8 +569,7 @@ static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
                                     &setup.override_level_sounds :
                                     &setup.override_level_music);
 
-  if (set_identifier)
-    free(set_identifier);
+  checked_free(set_identifier);
 
   set_identifier = checked_malloc(snd_ctrl->data_len);
 
@@ -571,16 +578,12 @@ static void ReadReloadInfoFromPipe(SoundControl *snd_ctrl)
 
   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);
+
+  checked_free(leveldir_current->fullpath);
+  checked_free(leveldir_current->sounds_path);
+  checked_free(leveldir_current->music_path);
+  checked_free(ti->basepath);
+  checked_free(ti->fullpath);
 
   if (read(audio.mixer_pipe[0], set_identifier,
           snd_ctrl->data_len) != snd_ctrl->data_len ||
@@ -637,7 +640,7 @@ void Mixer_InitChannels()
 {
   int i;
 
-  for(i=0; i<audio.num_channels; i++)
+  for (i = 0; i < audio.num_channels; i++)
     mixer[i].active = FALSE;
   mixer_active_channels = 0;
 }
@@ -826,27 +829,72 @@ static void Mixer_InsertSound(SoundControl snd_ctrl)
   SoundInfo *snd_info;
   int i, k;
   int num_sounds = getSoundListSize();
+  int num_music  = getMusicListSize();
+
+#if 0
+  if (IS_MUSIC(snd_ctrl))
+    printf("NEW MUSIC %d ARRIVED [%d/%d] [%d ACTIVE CHANNELS]\n",
+          snd_ctrl.nr, num_music, num_music_noconf, mixer_active_channels);
+  else
+    printf("NEW SOUND %d ARRIVED [%d] [%d ACTIVE CHANNELS]\n",
+          snd_ctrl.nr, num_sounds, mixer_active_channels);
+#endif
 
 #if 0
-  printf("NEW SOUND %d ARRIVED [%d] [%d ACTIVE CHANNELS]\n",
-        snd_ctrl.nr, num_sounds, mixer_active_channels);
+  /* !!! TEST ONLY !!! */
+  if (IS_MUSIC(snd_ctrl))
+    snd_ctrl.nr = 0;
 #endif
 
+#if 1
+  if (IS_MUSIC(snd_ctrl))
+  {
+    if (snd_ctrl.nr >= num_music)      /* invalid music */
+      return;
+
+    if (snd_ctrl.nr < 0)               /* undefined music */
+    {
+      if (num_music_noconf == 0)       /* no fallback music available */
+       return;
+
+      snd_ctrl.nr = UNMAP_NOCONF_MUSIC(snd_ctrl.nr) % num_music_noconf;
+      snd_info = Music_NoConf[snd_ctrl.nr];
+    }
+    else
+      snd_info = getMusicInfoEntryFromMusicID(snd_ctrl.nr);
+  }
+  else
+  {
+    if (snd_ctrl.nr < 0 || snd_ctrl.nr >= num_sounds)
+      return;
+
+    snd_info = getSoundInfoEntryFromSoundID(snd_ctrl.nr);
+  }
+
+  /*
+  if (snd_ctrl.nr >= (IS_MUSIC(snd_ctrl) ? num_music : num_sounds))
+    return;
+  */
+#else
   if (IS_MUSIC(snd_ctrl))
   {
-    if (num_music == 0)
+    if (num_music_noconf == 0)
       return;
 
-    snd_ctrl.nr = snd_ctrl.nr % num_music;
+    snd_ctrl.nr = snd_ctrl.nr % num_music_noconf;
   }
   else if (snd_ctrl.nr >= num_sounds)
     return;
+#endif
 
 #if 0
-  snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] : Sound[snd_ctrl.nr]);
+#if 1
+  snd_info = (IS_MUSIC(snd_ctrl) ? getMusicInfoEntryFromMusicID(snd_ctrl.nr) :
+             getSoundInfoEntryFromSoundID(snd_ctrl.nr));
 #else
-  snd_info = (IS_MUSIC(snd_ctrl) ? Music[snd_ctrl.nr] :
+  snd_info = (IS_MUSIC(snd_ctrl) ? Music_NoConf[snd_ctrl.nr] :
              getSoundInfoEntryFromSoundID(snd_ctrl.nr));
+#endif
 #endif
 
   if (snd_info == NULL)
@@ -862,6 +910,10 @@ static void Mixer_InsertSound(SoundControl snd_ctrl)
   /* play music samples on a dedicated music channel */
   if (IS_MUSIC(snd_ctrl))
   {
+#if 0
+    printf("::: slot %d, ptr 0x%08x\n", snd_ctrl.nr, snd_ctrl.data_ptr);
+#endif
+
     Mixer_StopMusicChannel();
 
     mixer[audio.music_channel] = snd_ctrl;
@@ -871,7 +923,7 @@ static void Mixer_InsertSound(SoundControl snd_ctrl)
   }
 
   /* check if (and how often) this sound sample is already playing */
-  for (k=0, i=audio.first_sound_channel; i<audio.num_channels; i++)
+  for (k = 0, i = audio.first_sound_channel; i < audio.num_channels; i++)
     if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
       k++;
 
@@ -882,7 +934,7 @@ static void Mixer_InsertSound(SoundControl snd_ctrl)
   /* reset expiration delay for already playing loop sounds */
   if (k > 0 && IS_LOOP(snd_ctrl))
   {
-    for(i=audio.first_sound_channel; i<audio.num_channels; i++)
+    for (i = audio.first_sound_channel; i < audio.num_channels; i++)
     {
       if (mixer[i].active && SAME_SOUND_DATA(mixer[i], snd_ctrl))
       {
@@ -921,7 +973,7 @@ static void Mixer_InsertSound(SoundControl snd_ctrl)
     int longest = 0, longest_nr = audio.first_sound_channel;
 
     /* look for oldest equal sound */
-    for(i=audio.first_sound_channel; i<audio.num_channels; i++)
+    for (i = audio.first_sound_channel; i < audio.num_channels; i++)
     {
       int playing_time = playing_current - mixer[i].playing_starttime;
       int actual;
@@ -952,7 +1004,7 @@ static void Mixer_InsertSound(SoundControl snd_ctrl)
   if (mixer_active_channels ==
       audio.num_channels - (mixer[audio.music_channel].active ? 0 : 1))
   {
-    for (i=audio.first_sound_channel; i<audio.num_channels; i++)
+    for (i = audio.first_sound_channel; i < audio.num_channels; i++)
     {
       if (!mixer[i].active)
       {
@@ -974,7 +1026,7 @@ static void Mixer_InsertSound(SoundControl snd_ctrl)
 #if 0
 #if DEBUG
     /* print some debugging information about audio channel usage */
-    for (i=audio.first_sound_channel; i<audio.num_channels; i++)
+    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);
@@ -982,7 +1034,7 @@ static void Mixer_InsertSound(SoundControl snd_ctrl)
 #endif
 #endif
 
-    for (i=audio.first_sound_channel; i<audio.num_channels; i++)
+    for (i = audio.first_sound_channel; i < audio.num_channels; i++)
     {
       int playing_time = playing_current - mixer[i].playing_starttime;
       int actual = 1000 * playing_time / mixer[i].data_len;
@@ -998,7 +1050,7 @@ static void Mixer_InsertSound(SoundControl snd_ctrl)
   }
 
   /* add the new sound to the mixer */
-  for(i=audio.first_sound_channel; i<audio.num_channels; i++)
+  for (i = audio.first_sound_channel; i < audio.num_channels; i++)
   {
 #if 0
     printf("CHECKING CHANNEL %d FOR SOUND %d ...\n", i, snd_ctrl.nr);
@@ -1038,14 +1090,14 @@ static void HandleSoundRequest(SoundControl snd_ctrl)
 #endif
 
   /* deactivate channels that have expired since the last request */
-  for (i=0; i<audio.num_channels; i++)
+  for (i = 0; i < audio.num_channels; i++)
     if (mixer[i].active && Mixer_ChannelExpired(i))
       Mixer_StopChannel(i);
 
   if (IS_RELOADING(snd_ctrl))          /* load new sound or music files */
   {
     Mixer_StopMusicChannel();
-    for(i=audio.first_sound_channel; i<audio.num_channels; i++)
+    for (i = audio.first_sound_channel; i < audio.num_channels; i++)
       Mixer_StopChannel(i);
 
 #if defined(AUDIO_UNIX_NATIVE)
@@ -1066,7 +1118,7 @@ static void HandleSoundRequest(SoundControl snd_ctrl)
       return;
     }
 
-    for(i=audio.first_sound_channel; i<audio.num_channels; i++)
+    for (i = audio.first_sound_channel; i < audio.num_channels; i++)
       if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
        Mixer_FadeChannel(i);
   }
@@ -1078,7 +1130,7 @@ static void HandleSoundRequest(SoundControl snd_ctrl)
       return;
     }
 
-    for(i=audio.first_sound_channel; i<audio.num_channels; i++)
+    for (i = audio.first_sound_channel; i < audio.num_channels; i++)
       if (SAME_SOUND_NR(mixer[i], snd_ctrl) || ALL_SOUNDS(snd_ctrl))
        Mixer_StopChannel(i);
 
@@ -1116,7 +1168,7 @@ void StartMixer(void)
     return;
 
   /* initialize stereo position conversion information */
-  for(i=0; i<=SOUND_MAX_LEFT2RIGHT; i++)
+  for (i = 0; i <= SOUND_MAX_LEFT2RIGHT; i++)
     stereo_volume[i] =
       (int)sqrt((float)(SOUND_MAX_LEFT2RIGHT * SOUND_MAX_LEFT2RIGHT - i * i));
 
@@ -1143,11 +1195,11 @@ static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
   {
     byte *sample_ptr = (byte *)snd_ctrl->data_ptr + num_channels * sample_pos;
 
-    for (i=0; i<num_output_channels; i++)
+    for (i = 0; i < num_output_channels; i++)
     {
       int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
 
-      for (j=0; j<sample_size; j++)
+      for (j = 0; j < sample_size; j++)
        buffer_ptr[output_stepsize * j + i] =
          ((short)(sample_ptr[stepsize * j + offset] ^ 0x80)) << 8;
     }
@@ -1156,11 +1208,11 @@ static void CopySampleToMixingBuffer(SoundControl *snd_ctrl,
   {
     short *sample_ptr= (short *)snd_ctrl->data_ptr + num_channels * sample_pos;
 
-    for (i=0; i<num_output_channels; i++)
+    for (i = 0; i < num_output_channels; i++)
     {
       int offset = (snd_ctrl->num_channels == 1 ? 0 : i);
 
-      for (j=0; j<sample_size; j++)
+      for (j = 0; j < sample_size; j++)
        buffer_ptr[output_stepsize * j + i] =
          sample_ptr[stepsize * j + offset];
     }
@@ -1201,7 +1253,7 @@ static void Mixer_Main_DSP()
   memset(premix_last_buffer, 0,
         max_sample_size * num_output_channels * sizeof(long));
 
-  for(i=0; i<audio.num_channels; i++)
+  for (i = 0; i < audio.num_channels; i++)
   {
     void *sample_ptr;
     int sample_len;
@@ -1252,7 +1304,7 @@ static void Mixer_Main_DSP()
 
     /* adjust volume of actual sound sample */
     if (mixer[i].volume != SOUND_MAX_VOLUME)
-      for(j=0; j<sample_size * num_output_channels; 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;
 
@@ -1262,7 +1314,7 @@ static void Mixer_Main_DSP()
       int left_volume  = SOUND_VOLUME_LEFT(mixer[i].stereo_position);
       int right_volume = SOUND_VOLUME_RIGHT(mixer[i].stereo_position);
 
-      for(j=0; j<sample_size; j++)
+      for (j = 0; j < sample_size; j++)
       {
        premix_first_buffer[2 * j + 0] =
          left_volume  * premix_first_buffer[2 * j + 0] / SOUND_MAX_LEFT2RIGHT;
@@ -1272,7 +1324,7 @@ static void Mixer_Main_DSP()
     }
 
     /* fill the last mixing buffer with stereo or mono sound */
-    for(j=0; j<sample_size * num_output_channels; j++)
+    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 */
@@ -1288,7 +1340,7 @@ static void Mixer_Main_DSP()
   }
 
   /* prepare final playing buffer according to system audio format */
-  for(i=0; i<max_sample_size * num_output_channels; i++)
+  for (i = 0; i < max_sample_size * num_output_channels; i++)
   {
     /* cut off at 17 bit value */
     if (premix_last_buffer[i] < -65535)
@@ -1351,13 +1403,13 @@ static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
 
   /* 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; j++)
       premix_first_buffer[j] =
        mixer[i].volume * (long)premix_first_buffer[j] / SOUND_MAX_VOLUME;
 
   /* might be needed for u-law /dev/audio */
 #if 1
-  for(j=0; j<sample_size; j++)
+  for (j = 0; j < sample_size; j++)
     playing_buffer[j] =
       linear_to_ulaw(premix_first_buffer[j]);
 #endif
@@ -1366,7 +1418,7 @@ static int Mixer_Main_SimpleAudio(SoundControl snd_ctrl)
   if (mixer[i].playing_pos >= mixer[i].data_len)
     Mixer_StopChannel(i);
 
-  for(i=0; i<sample_size; i++)
+  for (i = 0; i < sample_size; i++)
     playing_buffer[i] = (premix_first_buffer[i] >> 8) ^ 0x80;
 
   /* finally play the sound fragment */
@@ -1392,7 +1444,7 @@ void Mixer_Main()
   FD_ZERO(&mixer_fdset); 
   FD_SET(audio.mixer_pipe[0], &mixer_fdset);
 
-  while(1)     /* wait for sound playing commands from client */
+  while (1)    /* wait for sound playing commands from client */
   {
     struct timeval delay = { 0, 0 };
 
@@ -1765,11 +1817,11 @@ static void *Load_WAV(char *filename)
     int i;
 
     if (snd_ctrl->format == AUDIO_FORMAT_U8)
-      for (i=0; i<sample_size; i++)
+      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++)
+      for (i = 0; i < sample_size; i++)
        *buffer_ptr++ =
          ((short *)sample_ptr)[i];
   }
@@ -1783,12 +1835,148 @@ static void *Load_WAV(char *filename)
   return snd_info;
 }
 
+static void *Load_MOD(char *filename)
+{
+#if defined(TARGET_SDL)
+  MusicInfo *mod_info;
+
+  if (!audio.sound_available)
+    return NULL;
+
+  mod_info = checked_calloc(sizeof(MusicInfo));
+
+  if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
+  {
+    Error(ERR_WARN, "cannot read music file '%s'", filename);
+    free(mod_info);
+    return NULL;
+  }
+
+  mod_info->type = MUS_TYPE_MOD;
+  mod_info->source_filename = getStringCopy(filename);
+
+  return mod_info;
+#else
+  return NULL;
+#endif
+}
+
+static void *Load_WAV_or_MOD(char *filename)
+{
+  if (FileIsSound(filename))
+    return Load_WAV(filename);
+  else if (FileIsMusic(filename))
+    return Load_MOD(filename);
+  else
+    return NULL;
+}
+
+void LoadCustomMusic_NoConf(void)
+{
+  static boolean draw_init_text = TRUE;                /* only draw at startup */
+  static char *last_music_directory = NULL;
+  char *music_directory = getCustomMusicDirectory();
+  DIR *dir;
+  struct dirent *dir_entry;
+  int num_music = getMusicListSize();
+
+  if (!audio.sound_available)
+    return;
+
+  if (last_music_directory != NULL &&
+      strcmp(last_music_directory, music_directory) == 0)
+    return;    /* old and new music directory are the same */
+
+  if (last_music_directory != NULL)
+    free(last_music_directory);
+  last_music_directory = getStringCopy(music_directory);
+
+  FreeAllMusic_NoConf();
+
+  if ((dir = opendir(music_directory)) == NULL)
+  {
+    Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
+    audio.music_available = FALSE;
+    return;
+  }
+
+  if (draw_init_text)
+    DrawInitText("Loading music:", 120, FC_GREEN);
+
+  while ((dir_entry = readdir(dir)) != NULL)   /* loop until last dir entry */
+  {
+    char *basename = dir_entry->d_name;
+    char *filename = NULL;
+    MusicInfo *mus_info = NULL;
+    boolean music_already_used = FALSE;
+    int i;
+
+    for (i = 0; i < num_music; i++)
+    {
+      struct FileInfo *music = getMusicListEntry(i);
+
+      if (strcmp(basename, music->filename) == 0)
+      {
+       music_already_used = TRUE;
+       break;
+      }
+    }
+
+    if (music_already_used)
+      continue;
+
+#if 0
+    if (FileIsSound(basename) || FileIsMusic(basename))
+      printf("DEBUG: loading music '%s' ...\n", basename);
+#endif
+
+    if (draw_init_text)
+      DrawInitText(basename, 150, FC_YELLOW);
+
+    filename = getPath2(music_directory, basename);
+
+#if 1
+    if (FileIsMusic(basename))
+      mus_info = Load_WAV_or_MOD(filename);
+#else
+    if (FileIsSound(basename))
+      mus_info = Load_WAV(filename);
+    else if (FileIsMusic(basename))
+      mus_info = Load_MOD(filename);
+#endif
+
+    free(filename);
+
+    if (mus_info)
+    {
+      num_music_noconf++;
+      Music_NoConf = checked_realloc(Music_NoConf,
+                                    num_music_noconf * sizeof(MusicInfo *));
+      Music_NoConf[num_music_noconf - 1] = mus_info;
+    }
+  }
+
+  closedir(dir);
+
+  draw_init_text = FALSE;
+
+  if (num_music_noconf == 0)
+    Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
+         music_directory);
+}
+
 int getSoundListSize()
 {
   return (sound_info->num_file_list_entries +
          sound_info->num_dynamic_file_list_entries);
 }
 
+int getMusicListSize()
+{
+  return (music_info->num_file_list_entries +
+         music_info->num_dynamic_file_list_entries);
+}
+
 struct FileInfo *getSoundListEntry(int pos)
 {
   int num_list_entries = sound_info->num_file_list_entries;
@@ -1798,6 +1986,15 @@ struct FileInfo *getSoundListEntry(int pos)
          &sound_info->dynamic_file_list[list_pos]);
 }
 
+struct FileInfo *getMusicListEntry(int pos)
+{
+  int num_list_entries = music_info->num_file_list_entries;
+  int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
+
+  return (pos < num_list_entries ? &music_info->file_list[list_pos] :
+         &music_info->dynamic_file_list[list_pos]);
+}
+
 static SoundInfo *getSoundInfoEntryFromSoundID(int pos)
 {
   int num_list_entries = sound_info->num_file_list_entries;
@@ -1809,16 +2006,37 @@ static SoundInfo *getSoundInfoEntryFromSoundID(int pos)
   return snd_info[list_pos];
 }
 
+static MusicInfo *getMusicInfoEntryFromMusicID(int pos)
+{
+  int num_list_entries = music_info->num_file_list_entries;
+  int list_pos = (pos < num_list_entries ? pos : pos - num_list_entries);
+  MusicInfo **mus_info =
+    (MusicInfo **)(pos < num_list_entries ? music_info->artwork_list :
+                  music_info->dynamic_artwork_list);
+
+  return mus_info[list_pos];
+}
+
 int getSoundListPropertyMappingSize()
 {
   return sound_info->num_property_mapping_entries;
 }
 
+int getMusicListPropertyMappingSize()
+{
+  return music_info->num_property_mapping_entries;
+}
+
 struct PropertyMapping *getSoundListPropertyMapping()
 {
   return sound_info->property_mapping;
 }
 
+struct PropertyMapping *getMusicListPropertyMapping()
+{
+  return music_info->property_mapping;
+}
+
 void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries,
                   struct ConfigInfo *config_suffix_list,
                   char **base_prefixes, char **ext1_suffixes,
@@ -1841,7 +2059,7 @@ void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries,
   sound_info->dynamic_file_list = NULL;
 
   sound_info->num_suffix_list_entries = 0;
-  for (i=0; config_suffix_list[i].token != NULL; i++)
+  for (i = 0; config_suffix_list[i].token != NULL; i++)
     sound_info->num_suffix_list_entries++;
 
   sound_info->suffix_list = config_suffix_list;
@@ -1849,23 +2067,23 @@ void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries,
   /* ---------- initialize base prefix and suffixes lists ---------- */
 
   sound_info->num_base_prefixes = 0;
-  for (i=0; base_prefixes[i] != NULL; i++)
+  for (i = 0; base_prefixes[i] != NULL; i++)
     sound_info->num_base_prefixes++;
 
   sound_info->num_ext1_suffixes = 0;
-  for (i=0; ext1_suffixes[i] != NULL; i++)
+  for (i = 0; ext1_suffixes[i] != NULL; i++)
     sound_info->num_ext1_suffixes++;
 
   sound_info->num_ext2_suffixes = 0;
-  for (i=0; ext2_suffixes[i] != NULL; i++)
+  for (i = 0; ext2_suffixes[i] != NULL; i++)
     sound_info->num_ext2_suffixes++;
 
   sound_info->num_ext3_suffixes = 0;
-  for (i=0; ext3_suffixes[i] != NULL; i++)
+  for (i = 0; ext3_suffixes[i] != NULL; i++)
     sound_info->num_ext3_suffixes++;
 
   sound_info->num_ignore_tokens = 0;
-  for (i=0; ignore_tokens[i] != NULL; i++)
+  for (i = 0; ignore_tokens[i] != NULL; i++)
     sound_info->num_ignore_tokens++;
 
   sound_info->base_prefixes = base_prefixes;
@@ -1899,98 +2117,79 @@ void InitSoundList(struct ConfigInfo *config_list, int num_file_list_entries,
 #endif
 }
 
-static MusicInfo *Load_MOD(char *filename)
+void InitMusicList(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)
 {
-#if defined(TARGET_SDL)
-  MusicInfo *mod_info;
+  int i;
 
-  if (!audio.sound_available)
-    return NULL;
+  music_info = checked_calloc(sizeof(struct ArtworkListInfo));
+  music_info->type = ARTWORK_TYPE_MUSIC;
 
-  mod_info = checked_calloc(sizeof(MusicInfo));
+  /* ---------- initialize file list and suffix lists ---------- */
 
-  if ((mod_info->data_ptr = Mix_LoadMUS(filename)) == NULL)
-  {
-    Error(ERR_WARN, "cannot read music file '%s'", filename);
-    free(mod_info);
-    return NULL;
-  }
+  music_info->num_file_list_entries = num_file_list_entries;
+  music_info->num_dynamic_file_list_entries = 0;
 
-  mod_info->type = MUS_TYPE_MOD;
-  mod_info->source_filename = getStringCopy(filename);
+  music_info->file_list =
+    getFileListFromConfigList(config_list, config_suffix_list, ignore_tokens,
+                             num_file_list_entries);
+  music_info->dynamic_file_list = NULL;
 
-  return mod_info;
-#else
-  return NULL;
-#endif
-}
+  music_info->num_suffix_list_entries = 0;
+  for (i = 0; config_suffix_list[i].token != NULL; i++)
+    music_info->num_suffix_list_entries++;
 
-void LoadCustomMusic(void)
-{
-  static boolean draw_init_text = TRUE;                /* only draw at startup */
-  static char *last_music_directory = NULL;
-  char *music_directory = getCustomMusicDirectory();
-  DIR *dir;
-  struct dirent *dir_entry;
+  music_info->suffix_list = config_suffix_list;
 
-  if (!audio.sound_available)
-    return;
+  /* ---------- initialize base prefix and suffixes lists ---------- */
 
-  if (last_music_directory != NULL &&
-      strcmp(last_music_directory, music_directory) == 0)
-    return;    /* old and new music directory are the same */
+  music_info->num_base_prefixes = 0;
+  for (i = 0; base_prefixes[i] != NULL; i++)
+    music_info->num_base_prefixes++;
 
-  if (last_music_directory != NULL)
-    free(last_music_directory);
-  last_music_directory = getStringCopy(music_directory);
+  music_info->num_ext1_suffixes = 0;
+  for (i = 0; ext1_suffixes[i] != NULL; i++)
+    music_info->num_ext1_suffixes++;
 
-  FreeAllMusic();
+  music_info->num_ext2_suffixes = 0;
+  for (i = 0; ext2_suffixes[i] != NULL; i++)
+    music_info->num_ext2_suffixes++;
 
-  if ((dir = opendir(music_directory)) == NULL)
-  {
-    Error(ERR_WARN, "cannot read music directory '%s'", music_directory);
-    audio.music_available = FALSE;
-    return;
-  }
+  music_info->num_ext3_suffixes = 0;
+  for (i = 0; ext3_suffixes[i] != NULL; i++)
+    music_info->num_ext3_suffixes++;
 
-  if (draw_init_text)
-    DrawInitText("Loading music:", 120, FC_GREEN);
+  music_info->num_ignore_tokens = 0;
+  for (i = 0; ignore_tokens[i] != NULL; i++)
+    music_info->num_ignore_tokens++;
 
-  while ((dir_entry = readdir(dir)) != NULL)   /* loop until last dir entry */
-  {
-    char *basename = dir_entry->d_name;
-    char *filename = getPath2(music_directory, basename);
-    MusicInfo *mus_info = NULL;
+  music_info->base_prefixes = base_prefixes;
+  music_info->ext1_suffixes = ext1_suffixes;
+  music_info->ext2_suffixes = ext2_suffixes;
+  music_info->ext3_suffixes = ext3_suffixes;
+  music_info->ignore_tokens = ignore_tokens;
 
-#if 0
-    printf("DEBUG: loading music '%s' ...\n", basename);
-#endif
+  music_info->num_property_mapping_entries = 0;
 
-    if (draw_init_text)
-      DrawInitText(basename, 150, FC_YELLOW);
+  music_info->property_mapping = NULL;
 
-    if (FileIsSound(basename))
-      mus_info = Load_WAV(filename);
-    else if (FileIsMusic(basename))
-      mus_info = Load_MOD(filename);
+  /* ---------- initialize artwork reference and content lists ---------- */
 
-    free(filename);
+  music_info->sizeof_artwork_list_entry = sizeof(MusicInfo *);
 
-    if (mus_info)
-    {
-      num_music++;
-      Music = checked_realloc(Music, num_music * sizeof(MusicInfo *));
-      Music[num_music - 1] = mus_info;
-    }
-  }
+  music_info->artwork_list =
+    checked_calloc(num_file_list_entries * sizeof(MusicInfo *));
+  music_info->dynamic_artwork_list = NULL;
 
-  closedir(dir);
+  music_info->content_list = NULL;
 
-  draw_init_text = FALSE;
+  /* ---------- initialize artwork loading/freeing functions ---------- */
 
-  if (num_music == 0)
-    Error(ERR_WARN, "cannot find any valid music files in directory '%s'",
-         music_directory);
+  music_info->load_artwork = Load_WAV_or_MOD;
+  music_info->free_artwork = FreeMusic;
 }
 
 void PlayMusic(int nr)
@@ -2066,10 +2265,15 @@ void FadeSound(int nr)
 
 void FadeSounds()
 {
-  FadeMusic();
   StopSoundExt(-1, SND_CTRL_FADE_ALL);
 }
 
+void FadeSoundsAndMusic()
+{
+  FadeSounds();
+  FadeMusic();
+}
+
 void StopMusic(void)
 {
   if (!audio.music_available)
@@ -2125,7 +2329,13 @@ static void ReloadCustomMusic()
   printf("DEBUG: reloading music '%s' ...\n", artwork.mus_current_identifier);
 #endif
 
-  LoadCustomMusic();
+  LoadArtworkConfig(music_info);
+  ReloadCustomArtworkList(music_info);
+
+#if 1
+  /* load all music files from directory not defined in "musicinfo.conf" */
+  LoadCustomMusic_NoConf();
+#endif
 }
 
 void InitReloadCustomSounds(char *set_identifier)
@@ -2147,6 +2357,7 @@ void InitReloadCustomMusic(char *set_identifier)
     return;
 
 #if defined(AUDIO_UNIX_NATIVE)
+  LoadArtworkConfig(music_info);       /* also load config on sound client */
   WriteReloadInfoToPipe(set_identifier, SND_CTRL_RELOAD_MUSIC);
 #else
   ReloadCustomMusic();
@@ -2171,14 +2382,15 @@ void FreeSound(void *ptr)
 #endif
   }
 
-  if (sound->source_filename)
-    free(sound->source_filename);
+  checked_free(sound->source_filename);
 
   free(sound);
 }
 
-void FreeMusic(MusicInfo *music)
+void FreeMusic(void *ptr)
 {
+  MusicInfo *music = (MusicInfo *)ptr;
+
   if (music == NULL)
     return;
 
@@ -2199,25 +2411,31 @@ void FreeMusic(MusicInfo *music)
   free(music);
 }
 
-void FreeAllSounds()
-{
-  FreeCustomArtworkLists(sound_info);
-}
-
-void FreeAllMusic()
+static void FreeAllMusic_NoConf()
 {
   int i;
 
-  if (Music == NULL)
+  if (Music_NoConf == NULL)
     return;
 
-  for(i=0; i<num_music; i++)
-    FreeMusic(Music[i]);
+  for (i = 0; i < num_music_noconf; i++)
+    FreeMusic(Music_NoConf[i]);
 
-  free(Music);
+  free(Music_NoConf);
+
+  Music_NoConf = NULL;
+  num_music_noconf = 0;
+}
 
-  Music = NULL;
-  num_music = 0;
+void FreeAllSounds()
+{
+  FreeCustomArtworkLists(sound_info);
+}
+
+void FreeAllMusic()
+{
+  FreeCustomArtworkLists(music_info);
+  FreeAllMusic_NoConf();
 }
 
 /* THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS                          */
index 3b5270b9ae13f043d27be5c096134659302e4d33..17a1cee2e2e9e8cceb951f1911958659aaa41b53 100644 (file)
                                                      SND_CTRL_RELOAD_MUSIC))
 #define ALL_SOUNDS(x)                  ((x).state & SND_CTRL_ALL_SOUNDS)
 
+#define MAP_NOCONF_MUSIC(x)            (-((x) + 1))
+#define UNMAP_NOCONF_MUSIC(x)          MAP_NOCONF_MUSIC(x)
+
+
 #define SOUND_MIN_VOLUME               0
 #if defined(TARGET_SDL)
 #define SOUND_MAX_VOLUME               SDL_MIX_MAXVOLUME
@@ -135,17 +139,24 @@ void PlaySoundExt(int, int, int, int);
 void FadeMusic(void);
 void FadeSound(int);
 void FadeSounds(void);
+void FadeSoundsAndMusic(void);
 void StopMusic(void);
 void StopSound(int);
 void StopSounds(void);
 void StopSoundExt(int, int);
 
 int getSoundListSize();
+int getMusicListSize();
 struct FileInfo *getSoundListEntry(int);
+struct FileInfo *getMusicListEntry(int);
 int getSoundListPropertyMappingSize();
+int getMusicListPropertyMappingSize();
 struct PropertyMapping *getSoundListPropertyMapping();
+struct PropertyMapping *getMusicListPropertyMapping();
 void InitSoundList(struct ConfigInfo *, int, struct ConfigInfo *,
                   char **, char **, char **, char **, char **);
+void InitMusicList(struct ConfigInfo *, int, struct ConfigInfo *,
+                  char **, char **, char **, char **, char **);
 void InitReloadCustomSounds(char *);
 void InitReloadCustomMusic(char *);
 void FreeAllSounds(void);
index 96adfcfebc88f2a50b5dd10670c805136593e617..9934650f753173d935459d8b13dc00f7b83a9d09 100644 (file)
@@ -194,9 +194,9 @@ static void DrawBitmapFromTile(Bitmap *bitmap, Bitmap *tile,
   int tile_ysteps = (bitmap_ysize + tile_ysize - 1) / tile_ysize;
   int x, y;
 
-  for (y=0; y < tile_ysteps; y++)
+  for (y = 0; y < tile_ysteps; y++)
   {
-    for (x=0; x < tile_xsteps; x++)
+    for (x = 0; x < tile_xsteps; x++)
     {
       int draw_x = dest_x + x * tile_xsize;
       int draw_y = dest_y + y * tile_ysize;
@@ -370,8 +370,7 @@ inline static void FreeBitmapPointers(Bitmap *bitmap)
   X11FreeBitmapPointers(bitmap);
 #endif
 
-  if (bitmap->source_filename)
-    free(bitmap->source_filename);
+  checked_free(bitmap->source_filename);
   bitmap->source_filename = NULL;
 }
 
@@ -559,9 +558,9 @@ inline void DrawLine(Bitmap *bitmap, int from_x, int from_y,
 {
   int x, y;
 
-  for (x=0; x<line_width; x++)
+  for (x = 0; x < line_width; x++)
   {
-    for (y=0; y<line_width; y++)
+    for (y = 0; y < line_width; y++)
     {
       int dx = x - line_width / 2;
       int dy = y - line_width / 2;
@@ -591,7 +590,7 @@ inline void DrawLines(Bitmap *bitmap, struct XY *points, int num_points,
   int line_width = 4;
   int i;
 
-  for (i=0; i<num_points - 1; i++)
+  for (i = 0; i < num_points - 1; i++)
     DrawLine(bitmap, points[i].x, points[i].y,
             points[i + 1].x, points[i + 1].y, pixel, line_width);
 
@@ -909,9 +908,9 @@ static struct MouseCursorInfo *get_cursor_from_image(const char **image)
   sscanf(image[0], " %d %d ", &cursor->width, &cursor->height);
 
   i = -1;
-  for (y=0; y < cursor->width; y++)
+  for (y = 0; y < cursor->width; y++)
   {
-    for (x=0; x < cursor->height; x++)
+    for (x = 0; x < cursor->height; x++)
     {
       int bit_nr = x % 8;
       int bit_mask = 0x01 << (bit_order_msb ? 7 - bit_nr : bit_nr );
@@ -1165,7 +1164,7 @@ inline void InitJoysticks()
 
   /* always start with reliable default values */
   joystick.status = JOYSTICK_NOT_AVAILABLE;
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
     joystick.fd[i] = -1;               /* joystick device closed */
 
 #if defined(TARGET_SDL)
index ae8473465d2f8b087086c2bd9ce40c174dd99b18..d05943775b1e7de7aba3bf502239588bbae01ae4 100644 (file)
 #define REDRAW_FPS             (1 << 11)
 #define REDRAWTILES_THRESHOLD  (SCR_FIELDX * SCR_FIELDY / 2)
 
+#define IN_GFX_SCREEN(x, y)    (x >= gfx.sx && x < gfx.sx + gfx.sxsize && \
+                                y >= gfx.sy && y < gfx.sy + gfx.sysize)
+#define IN_GFX_DOOR(x, y)      (x >= gfx.dx && x < gfx.dx + gfx.dxsize && \
+                                y >= gfx.dy && y < gfx.dy + gfx.dysize)
+#define IN_GFX_VIDEO(x, y)     (x >= gfx.vx && x < gfx.vx + gfx.vxsize && \
+                                y >= gfx.vy && y < gfx.vy + gfx.vysize)
 
 /* values for mouse cursor */
 #define CURSOR_DEFAULT         0
 /* default name for unknown player names */
 #define ANONYMOUS_NAME         "anonymous"
 
+/* default for other unknown names */
+#define UNKNOWN_NAME           "unknown"
+
 /* default name for new levels */
 #define NAMELESS_LEVEL_NAME    "nameless level"
 
 #define LEVELSETUP_DIRECTORY   "levelsetup"
 #define SETUP_FILENAME         "setup.conf"
 #define LEVELSETUP_FILENAME    "levelsetup.conf"
+#define EDITORSETUP_FILENAME   "editorsetup.conf"
+#define HELPANIM_FILENAME      "helpanim.conf"
+#define HELPTEXT_FILENAME      "helptext.conf"
 #define LEVELINFO_FILENAME     "levelinfo.conf"
 #define GRAPHICSINFO_FILENAME  "graphicsinfo.conf"
 #define SOUNDSINFO_FILENAME    "soundsinfo.conf"
 #define LEVELSETUP_DIRECTORY   "lvlsetup"
 #define SETUP_FILENAME         "setup.cnf"
 #define LEVELSETUP_FILENAME    "lvlsetup.cnf"
+#define EDITORSETUP_FILENAME   "edsetup.cnf"
+#define HELPANIM_FILENAME      "helpanim.conf"
+#define HELPTEXT_FILENAME      "helptext.conf"
 #define LEVELINFO_FILENAME     "lvlinfo.cnf"
 #define GRAPHICSINFO_FILENAME  "gfxinfo.cnf"
 #define SOUNDSINFO_FILENAME    "sndinfo.cnf"
@@ -539,6 +554,7 @@ struct SetupEditorInfo
   boolean el_chars;
   boolean el_custom;
   boolean el_custom_more;
+  boolean el_user_defined;
 
   boolean el_headlines;
 };
index f41635ae3f4863b659f9283a7238bcb761cda5d3..6fd437359014dad05bcacdf93216028f74cab43b 100644 (file)
@@ -50,7 +50,7 @@ static void InitFontClipmasks()
                               clip_gc_valuemask, &clip_gc_values);
 
   /* create only those clipping Pixmaps we really need */
-  for (i=0; i < gfx.num_fonts; i++)
+  for (i = 0; i < gfx.num_fonts; i++)
   {
     if (gfx.font_bitmap_info[i].bitmap == NULL)
       continue;
@@ -58,7 +58,7 @@ static void InitFontClipmasks()
     gfx.font_bitmap_info[i].clip_mask =
       checked_calloc(gfx.font_bitmap_info[i].num_chars * sizeof(Pixmap));
 
-    for (j=0; j < gfx.font_bitmap_info[i].num_chars; j++)
+    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;
@@ -87,11 +87,11 @@ static void FreeFontClipmasks()
   if (gfx.num_fonts == 0 || gfx.font_bitmap_info[0].bitmap == NULL)
     return;
 
-  for (i=0; i < gfx.num_fonts; i++)
+  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++)
+      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);
     }
@@ -191,7 +191,7 @@ void DrawInitText(char *text, int ypos, int font_nr)
   }
 }
 
-void DrawTextFCentered(int y, int font_nr, char *format, ...)
+void DrawTextF(int x, int y, int font_nr, char *format, ...)
 {
   char buffer[MAX_OUTPUT_LINESIZE + 1];
   va_list ap;
@@ -201,13 +201,12 @@ void DrawTextFCentered(int y, int font_nr, char *format, ...)
   va_end(ap);
 
   if (strlen(buffer) > MAX_OUTPUT_LINESIZE)
-    Error(ERR_EXIT, "string too long in DrawTextFCentered() -- aborting");
+    Error(ERR_EXIT, "string too long in DrawTextF() -- aborting");
 
-  DrawText(gfx.sx + (gfx.sxsize - getTextWidth(buffer, font_nr)) / 2,
-          gfx.sy + y, buffer, font_nr);
+  DrawText(gfx.sx + x, gfx.sy + y, buffer, font_nr);
 }
 
-void DrawTextF(int x, int y, int font_nr, char *format, ...)
+void DrawTextFCentered(int y, int font_nr, char *format, ...)
 {
   char buffer[MAX_OUTPUT_LINESIZE + 1];
   va_list ap;
@@ -217,9 +216,21 @@ void DrawTextF(int x, int y, int font_nr, char *format, ...)
   va_end(ap);
 
   if (strlen(buffer) > MAX_OUTPUT_LINESIZE)
-    Error(ERR_EXIT, "string too long in DrawTextF() -- aborting");
+    Error(ERR_EXIT, "string too long in DrawTextFCentered() -- aborting");
 
-  DrawText(gfx.sx + x, gfx.sy + y, buffer, font_nr);
+  DrawText(gfx.sx + (gfx.sxsize - getTextWidth(buffer, font_nr)) / 2,
+          gfx.sy + y, buffer, font_nr);
+}
+
+void DrawTextS(int x, int y, int font_nr, char *text)
+{
+  DrawText(gfx.sx + x, gfx.sy + y, text, font_nr);
+}
+
+void DrawTextSCentered(int y, int font_nr, char *text)
+{
+  DrawText(gfx.sx + (gfx.sxsize - getTextWidth(text, font_nr)) / 2,
+          gfx.sy + y, text, font_nr);
 }
 
 void DrawText(int x, int y, char *text, int font_nr)
@@ -340,7 +351,7 @@ void DrawTextToTextArea(int x, int y, char *text, int font_nr, int line_length,
     char buffer[MAX_OUTPUT_LINESIZE + 1];
     int i;
 
-    for (i=0; i < line_length && *text; i++)
+    for (i = 0; i < line_length && *text; i++)
       if ((buffer[i] = *text++) == '\n')
        break;
     buffer[MIN(i, area_xsize)] = '\0';
@@ -353,3 +364,183 @@ void DrawTextToTextArea(int x, int y, char *text, int font_nr, int line_length,
 
   redraw_mask |= REDRAW_FIELD;
 }
+
+boolean RenderLineToBuffer(char **src_buffer_ptr, char *dst_buffer,
+                          int *dst_buffer_len, boolean last_line_was_empty,
+                          int line_length)
+{
+  char *text_ptr = *src_buffer_ptr;
+  char *buffer = dst_buffer;
+  int buffer_len = *dst_buffer_len;
+  boolean buffer_filled = FALSE;
+
+  while (*text_ptr)
+  {
+    char *word_ptr;
+    int word_len;
+
+    /* skip leading whitespaces */
+    while (*text_ptr == ' ' || *text_ptr == '\t')
+      text_ptr++;
+
+    word_ptr = text_ptr;
+    word_len = 0;
+
+    /* look for end of next word */
+    while (*word_ptr != ' ' && *word_ptr != '\t' && *word_ptr != '\0')
+    {
+      word_ptr++;
+      word_len++;
+    }
+
+    if (word_len == 0)
+    {
+      continue;
+    }
+    else if (*text_ptr == '\n')                /* special case: force empty line */
+    {
+      if (buffer_len == 0)
+       text_ptr++;
+
+      /* prevent printing of multiple empty lines */
+      if (buffer_len > 0 || !last_line_was_empty)
+       buffer_filled = TRUE;
+    }
+    else if (word_len < line_length - buffer_len)
+    {
+      /* word fits into text buffer -- add word */
+
+      if (buffer_len > 0)
+       buffer[buffer_len++] = ' ';
+
+      strncpy(&buffer[buffer_len], text_ptr, word_len);
+      buffer_len += word_len;
+      buffer[buffer_len] = '\0';
+      text_ptr += word_len;
+    }
+    else if (buffer_len > 0)
+    {
+      /* not enough space left for word in text buffer -- print buffer */
+
+      buffer_filled = TRUE;
+    }
+    else
+    {
+      /* word does not fit at all into empty text buffer -- cut word */
+
+      strncpy(buffer, text_ptr, line_length);
+      buffer[line_length] = '\0';
+      text_ptr += line_length;
+      buffer_filled = TRUE;
+    }
+
+    if (buffer_filled)
+      break;
+  }
+
+  *src_buffer_ptr = text_ptr;
+  *dst_buffer_len = buffer_len;
+
+  return buffer_filled;
+}
+
+void DrawTextWrapped(int x, int y, char *text, int font_nr, int line_length,
+                    int max_lines)
+{
+  char *text_ptr = text;
+  char buffer[line_length + 1];
+  int buffer_len;
+  int current_line = 0;
+  int font_height = getFontHeight(font_nr);
+
+  while (*text_ptr && current_line < max_lines)
+  {
+    buffer[0] = '\0';
+    buffer_len = 0;
+
+    RenderLineToBuffer(&text_ptr, buffer, &buffer_len, TRUE, line_length);
+
+    DrawText(x, y + current_line * font_height, buffer, font_nr);
+    current_line++;
+  }
+}
+
+int DrawTextFromFile(int x, int y, char *filename, int font_nr,
+                    int line_length, int max_lines)
+{
+  int font_height = getFontHeight(font_nr);
+  char line[MAX_LINE_LEN];
+  char buffer[line_length + 1];
+  int buffer_len;
+  int current_line = 0;
+  FILE *file;
+
+  if (current_line >= max_lines)
+    return 0;
+
+  if (filename == NULL)
+    return 0;
+
+  if (!(file = fopen(filename, MODE_READ)))
+    return 0;
+
+  buffer[0] = '\0';
+  buffer_len = 0;
+
+  while (!feof(file) && current_line < max_lines)
+  {
+    char *line_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");
+
+    line_ptr = line;
+
+    while (*line_ptr && current_line < max_lines)
+    {
+      boolean buffer_filled = RenderLineToBuffer(&line_ptr,
+                                                buffer, &buffer_len,
+                                                last_line_was_empty,
+                                                line_length);
+      if (buffer_filled)
+      {
+       DrawText(x, y + current_line * font_height, buffer, font_nr);
+       current_line++;
+
+       last_line_was_empty = (buffer_len == 0);
+
+       buffer[0] = '\0';
+       buffer_len = 0;
+      }
+    }
+  }
+
+  fclose(file);
+
+  if (buffer_len > 0 && current_line < max_lines)
+  {
+    DrawText(x, y + current_line * font_height, buffer, font_nr);
+    current_line++;
+  }
+
+  return current_line;
+}
index dc29e2837c00ac9ba5f6869a4af6258f46c65959..0c5c7586d5873d5cb185c112efe4a424c10f8226 100644 (file)
@@ -64,8 +64,13 @@ void getFontCharSource(int, char, Bitmap **, int *, int *);
 void DrawInitText(char *, int, int);
 void DrawTextF(int, int, int, char *, ...);
 void DrawTextFCentered(int, int, char *, ...);
+void DrawTextS(int, int, int, char *);
+void DrawTextSCentered(int, int, char *);
 void DrawText(int, int, char *, int);
 void DrawTextExt(DrawBuffer *, int, int, char *, int, int);
 void DrawTextToTextArea(int, int, char *, int, int, int, int, int);
+boolean RenderLineToBuffer(char **, char *, int *, boolean, int);
+void DrawTextWrapped(int, int, char *, int, int, int);
+int DrawTextFromFile(int, int, char *, int, int, int);
 
 #endif /* TEXT_H */
index d7acc801be5ae6ced5087e396fa48f35ccce3bfb..ce520f6452ed70613d8fc664aec436669293541e 100644 (file)
@@ -214,7 +214,7 @@ static DrawWindow *X11InitWindow()
     XCreateGC(display, new_window->drawable, gc_valuemask, &gc_values);
 
   /* create GCs for line drawing (black and white) */
-  for(i=0; i<2; i++)
+  for (i = 0; i < 2; i++)
   {
     gc_values.graphics_exposures = False;
     gc_values.foreground = (i ? pen_fg : pen_bg);
index a06efd1ff5c5dfbdd38e456d27cddc17ce794730..7e73ba2b388ba5f089d6b20c04b5048f75f93d6d 100644 (file)
@@ -60,6 +60,8 @@ 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];
+int                    RunnerVisit[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+int                    PlayerVisit[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 
 unsigned long          Properties[MAX_NUM_ELEMENTS][NUM_EP_BITFIELDS];
 
@@ -91,6 +93,7 @@ int                   TimeFrames, TimePlayed, TimeLeft;
 
 boolean                        network_player_action_received = FALSE;
 
+struct LevelSetInfo    levelset;
 struct LevelInfo       level, level_template;
 struct PlayerInfo      stored_player[MAX_PLAYERS], *local_player = NULL;
 struct HiScore         highscore[MAX_SCORE_ENTRIES];
@@ -102,6 +105,10 @@ struct MenuInfo            menu;
 struct DoorInfo                door_1, door_2;
 struct GraphicInfo     *graphic_info = NULL;
 struct SoundInfo       *sound_info = NULL;
+struct MusicInfo       *music_info = NULL;
+struct MusicFileInfo   *music_file_info = NULL;
+struct HelpAnimInfo    *helpanim_info = NULL;
+SetupFileHash          *helptext_info = NULL;
 
 
 /* ------------------------------------------------------------------------- */
@@ -429,9 +436,9 @@ struct ElementInfo element_info[MAX_NUM_ELEMENTS + 1] =
     "invisible steel wall"
   },
   {
-    "unused_63",
-    "unused",
-    "(not used)"
+    "maze_runner",
+    "maze_runner",
+    "maze runner"
   },
   {
     "dynabomb_increase_number",
@@ -3473,12 +3480,12 @@ struct ElementInfo element_info[MAX_NUM_ELEMENTS + 1] =
     "-"
   },
   {
-    "nut_breaking",
+    "nut.breaking",
     "-",
     "-"
   },
   {
-    "diamond_breaking",
+    "diamond.breaking",
     "-",
     "-"
   },
@@ -3493,12 +3500,12 @@ struct ElementInfo element_info[MAX_NUM_ELEMENTS + 1] =
     "-"
   },
   {
-    "amoeba_growing",
+    "amoeba.growing",
     "-",
     "-"
   },
   {
-    "amoeba_shrinking",
+    "amoeba.shrinking",
     "-",
     "-"
   },
@@ -3637,6 +3644,11 @@ struct ElementInfo element_info[MAX_NUM_ELEMENTS + 1] =
     "-",
     "-"
   },
+  {
+    "amoeba",
+    "amoeba",
+    "-"
+  },
   {
     "[default]",
     "default",
@@ -3657,6 +3669,11 @@ struct ElementInfo element_info[MAX_NUM_ELEMENTS + 1] =
     "sb_default",
     "-"
   },
+  {
+    "dummy",
+    "dummy",
+    "-"
+  },
 
   /* keyword to stop parser: "ELEMENT_INFO_END" <-- do not change! */
 
@@ -3699,6 +3716,22 @@ struct ElementActionInfo element_action_info[NUM_ACTIONS + 1 + 1] =
   { ".emptying",               ACTION_EMPTYING,                FALSE   },
   { ".changing",               ACTION_CHANGING,                FALSE   },
   { ".exploding",              ACTION_EXPLODING,               FALSE   },
+  { ".boring",                 ACTION_BORING,                  FALSE   },
+  { ".boring[1]",              ACTION_BORING_1,                FALSE   },
+  { ".boring[2]",              ACTION_BORING_2,                FALSE   },
+  { ".boring[3]",              ACTION_BORING_3,                FALSE   },
+  { ".boring[4]",              ACTION_BORING_4,                FALSE   },
+  { ".boring[5]",              ACTION_BORING_5,                FALSE   },
+  { ".boring[6]",              ACTION_BORING_6,                FALSE   },
+  { ".boring[7]",              ACTION_BORING_7,                FALSE   },
+  { ".boring[8]",              ACTION_BORING_8,                FALSE   },
+  { ".boring[9]",              ACTION_BORING_9,                FALSE   },
+  { ".boring[10]",             ACTION_BORING_10,               FALSE   },
+  { ".sleeping",               ACTION_SLEEPING,                FALSE   },
+  { ".sleeping[1]",            ACTION_SLEEPING_1,              FALSE   },
+  { ".sleeping[2]",            ACTION_SLEEPING_2,              FALSE   },
+  { ".sleeping[3]",            ACTION_SLEEPING_3,              FALSE   },
+  { ".awakening",              ACTION_AWAKENING,               FALSE   },
   { ".dying",                  ACTION_DYING,                   FALSE   },
   { ".turning",                        ACTION_TURNING,                 FALSE   },
   { ".turning_from_left",      ACTION_TURNING_FROM_LEFT,       FALSE   },
@@ -3723,8 +3756,9 @@ struct ElementDirectionInfo element_direction_info[NUM_DIRECTIONS + 1] =
   { NULL,              0                               }
 };
 
-struct SpecialSuffixInfo special_suffix_info[NUM_SPECIAL_GFX_ARGS + 1] =
+struct SpecialSuffixInfo special_suffix_info[NUM_SPECIAL_GFX_ARGS + 1 + 1] =
 {
+  { ".[DEFAULT]",      GAME_MODE_DEFAULT,              },
   { ".MAIN",           GAME_MODE_MAIN,                 },
   { ".LEVELS",         GAME_MODE_LEVELS                },
   { ".SCORES",         GAME_MODE_SCORES,               },
@@ -3736,6 +3770,9 @@ struct SpecialSuffixInfo special_suffix_info[NUM_SPECIAL_GFX_ARGS + 1] =
   { ".PREVIEW",                GAME_MODE_PSEUDO_PREVIEW,       },
   { ".CRUMBLED",       GAME_MODE_PSEUDO_CRUMBLED,      },
 
+  /* empty suffix always matches -- check as last entry in InitMusicInfo() */
+  { "",                        GAME_MODE_DEFAULT,              },
+
   { NULL,              0,                              }
 };
 
@@ -3772,6 +3809,11 @@ struct TokenIntPtrInfo image_config_vars[] =
   { "door_2.step_delay",       &door_2.step_delay                         },
   { "door_2.anim_mode",                &door_2.anim_mode                          },
 
+  { "[player].boring_delay_fixed",     &game.player_boring_delay_fixed    },
+  { "[player].boring_delay_random",    &game.player_boring_delay_random   },
+  { "[player].sleeping_delay_fixed",   &game.player_sleeping_delay_fixed  },
+  { "[player].sleeping_delay_random",  &game.player_sleeping_delay_random },
+
   { NULL,                      NULL,                                      }
 };
 
@@ -3820,10 +3862,54 @@ struct FontInfo font_info[NUM_FONTS + 1] =
 };
 
 
+/* ------------------------------------------------------------------------- */
+/* music token prefix definitions                                            */
+/* ------------------------------------------------------------------------- */
+
+struct MusicPrefixInfo music_prefix_info[NUM_MUSIC_PREFIXES + 1] =
+{
+  { "background",              TRUE    },
+
+  { NULL,                      0       }
+};
+
+
 /* ========================================================================= */
 /* main()                                                                    */
 /* ========================================================================= */
 
+static void print_usage()
+{
+  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"
+        "  \"print editorsetup.conf\"         print default editor config\n"
+        "  \"print helpanim.conf\"            print default helpanim config\n"
+        "  \"print helptext.conf\"            print default helptext config\n"
+        "  \"dump level FILE\"                dump level data from FILE\n"
+        "  \"dump tape FILE\"                 dump tape data from FILE\n"
+        "  \"autoplay LEVELDIR\"              play level tapes for LEVELDIR\n"
+        "\n",
+        program.command_basename);
+}
+
 int main(int argc, char *argv[])
 {
   InitProgramInfo(argv[0], USERDATA_DIRECTORY,
@@ -3835,7 +3921,7 @@ int main(int argc, char *argv[])
   InitExitFunction(CloseAllAndExit);
   InitPlatformDependentStuff();
 
-  GetOptions(argv);
+  GetOptions(argv, print_usage);
   OpenAll();
 
   EventLoop();
index 273052ecb6fe41575b3fca7ee6b255d6cc6d3ff6..9484a5c6a90c9f4eb9f12dab53007840e732a057 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "conf_gfx.h"  /* include auto-generated data structure definitions */
 #include "conf_snd.h"  /* include auto-generated data structure definitions */
+#include "conf_mus.h"  /* include auto-generated data structure definitions */
 
 #define IMG_UNDEFINED          (-1)
 #define IMG_EMPTY              IMG_EMPTY_SPACE
@@ -35,6 +36,7 @@
 #define IMG_CUSTOM_START       IMG_CUSTOM_1
 
 #define SND_UNDEFINED          (-1)
+#define MUS_UNDEFINED          (-1)
 
 #define WIN_XSIZE              672
 #define WIN_YSIZE              560
 #define CE_PRESSED_BY_PLAYER   2
 #define CE_PUSHED_BY_PLAYER    3
 #define CE_DROPPED_BY_PLAYER   4
-#define CE_COLLISION           5
+#define CE_COLLISION_ACTIVE    5
 #define CE_IMPACT              6
 #define CE_SMASHED             7
 #define CE_OTHER_IS_TOUCHING   8
 #define CE_OTHER_GETS_PUSHED   13
 #define CE_OTHER_GETS_COLLECTED        14
 #define CE_OTHER_GETS_DROPPED  15
-#define CE_BY_PLAYER           16      /* obsolete; now CE_BY_DIRECT_ACTION */
-#define CE_BY_COLLISION                17      /* obsolete; now CE_BY_DIRECT_ACTION */
+#define CE_BY_PLAYER_OBSOLETE  16      /* obsolete; now CE_BY_DIRECT_ACTION */
+#define CE_BY_COLLISION_OBSOLETE 17    /* obsolete; now CE_BY_DIRECT_ACTION */
 #define CE_BY_OTHER_ACTION     18      /* activates other element events */
 #define CE_BY_DIRECT_ACTION    19      /* activates direct element events */
 #define CE_OTHER_GETS_DIGGED   20
 #define CE_OTHER_GETS_LEFT     24
 #define CE_SWITCHED            25
 #define CE_OTHER_IS_SWITCHING  26
+#define CE_COLLISION_PASSIVE   27
+#define CE_OTHER_IS_COLL_ACTIVE        28
+#define CE_OTHER_IS_COLL_PASSIVE 29
 
-#define NUM_CHANGE_EVENTS      27
+#define NUM_CHANGE_EVENTS      30
 
 #define CE_BITMASK_DEFAULT     0
 
 #define MV_BIT_TURNING_LEFT    8
 #define MV_BIT_TURNING_RIGHT   9
 #define MV_BIT_WHEN_PUSHED     10
+#define MV_BIT_MAZE_RUNNER     11
+#define MV_BIT_MAZE_HUNTER     12
 
 /* values for special move patterns for custom elements */
 #define MV_HORIZONTAL          (MV_LEFT | MV_RIGHT)
 #define MV_TURNING_LEFT                (1 << MV_BIT_TURNING_LEFT)
 #define MV_TURNING_RIGHT       (1 << MV_BIT_TURNING_RIGHT)
 #define MV_WHEN_PUSHED         (1 << MV_BIT_WHEN_PUSHED)
+#define MV_MAZE_RUNNER         (1 << MV_BIT_MAZE_RUNNER)
+#define MV_MAZE_HUNTER         (1 << MV_BIT_MAZE_HUNTER)
+#define MV_MAZE_RUNNER_STYLE   (MV_MAZE_RUNNER | MV_MAZE_HUNTER)
 
 /* values for slippery property for custom elements */
 #define SLIPPERY_ANY_RANDOM    0
 #define EL_BD_MAGIC_WALL               61
 #define EL_INVISIBLE_STEELWALL         62
 
-#define EL_UNUSED_63                   63
+#define EL_MAZE_RUNNER                 63
 
 #define EL_DYNABOMB_INCREASE_NUMBER    64
 #define EL_DYNABOMB_INCREASE_SIZE      65
 #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 EL_AMOEBA                              (EL_FIRST_DUMMY + 20)
+#define EL_DEFAULT                             (EL_FIRST_DUMMY + 21)
+#define EL_BD_DEFAULT                          (EL_FIRST_DUMMY + 22)
+#define EL_SP_DEFAULT                          (EL_FIRST_DUMMY + 23)
+#define EL_SB_DEFAULT                          (EL_FIRST_DUMMY + 24)
+#define EL_DUMMY                               (EL_FIRST_DUMMY + 25)
 
-#define MAX_NUM_ELEMENTS                       (EL_FIRST_DUMMY + 24)
+#define MAX_NUM_ELEMENTS                       (EL_FIRST_DUMMY + 26)
 
 
 /* values for graphics/sounds action types */
 #define ACTION_EMPTYING                                22
 #define ACTION_CHANGING                                23
 #define ACTION_EXPLODING                       24
-#define ACTION_DYING                           25
-#define ACTION_TURNING                         26
-#define ACTION_TURNING_FROM_LEFT               27
-#define ACTION_TURNING_FROM_RIGHT              28
-#define ACTION_TURNING_FROM_UP                 29
-#define ACTION_TURNING_FROM_DOWN               30
-#define ACTION_OTHER                           31
+#define ACTION_BORING                          25
+#define ACTION_BORING_1                                26
+#define ACTION_BORING_2                                27
+#define ACTION_BORING_3                                28
+#define ACTION_BORING_4                                29
+#define ACTION_BORING_5                                30
+#define ACTION_BORING_6                                31
+#define ACTION_BORING_7                                32
+#define ACTION_BORING_8                                33
+#define ACTION_BORING_9                                34
+#define ACTION_BORING_10                       35
+#define ACTION_SLEEPING                                36
+#define ACTION_SLEEPING_1                      37
+#define ACTION_SLEEPING_2                      38
+#define ACTION_SLEEPING_3                      39
+#define ACTION_AWAKENING                       40
+#define ACTION_DYING                           41
+#define ACTION_TURNING                         42
+#define ACTION_TURNING_FROM_LEFT               43
+#define ACTION_TURNING_FROM_RIGHT              44
+#define ACTION_TURNING_FROM_UP                 45
+#define ACTION_TURNING_FROM_DOWN               46
+#define ACTION_OTHER                           47
+
+#define NUM_ACTIONS                            48
+
+#define ACTION_BORING_LAST                     ACTION_BORING_10
+#define ACTION_SLEEPING_LAST                   ACTION_SLEEPING_3
 
-#define NUM_ACTIONS                            32
 
 /* 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_PLAYING                        6
-#define GFX_SPECIAL_ARG_DOOR                   7
-#define GFX_SPECIAL_ARG_PREVIEW                        8
-#define GFX_SPECIAL_ARG_CRUMBLED               9
+#define GFX_SPECIAL_ARG_DEFAULT                        0
+#define GFX_SPECIAL_ARG_MAIN                   1
+#define GFX_SPECIAL_ARG_LEVELS                 2
+#define GFX_SPECIAL_ARG_SCORES                 3
+#define GFX_SPECIAL_ARG_EDITOR                 4
+#define GFX_SPECIAL_ARG_INFO                   5
+#define GFX_SPECIAL_ARG_SETUP                  6
+#define GFX_SPECIAL_ARG_PLAYING                        7
+#define GFX_SPECIAL_ARG_DOOR                   8
+#define GFX_SPECIAL_ARG_PREVIEW                        9
+#define GFX_SPECIAL_ARG_CRUMBLED               10
 
-#define NUM_SPECIAL_GFX_ARGS                   10
+#define NUM_SPECIAL_GFX_ARGS                   11
 
 
 /* values for image configuration suffixes */
 #define GFX_ARG_DRAW_XOFFSET                   23
 #define GFX_ARG_DRAW_YOFFSET                   24
 #define GFX_ARG_DRAW_MASKED                    25
-#define GFX_ARG_NAME                           26
+#define GFX_ARG_ANIM_DELAY_FIXED               26
+#define GFX_ARG_ANIM_DELAY_RANDOM              27
+#define GFX_ARG_POST_DELAY_FIXED               28
+#define GFX_ARG_POST_DELAY_RANDOM              29
+#define GFX_ARG_NAME                           30
 
-#define NUM_GFX_ARGS                           27
+#define NUM_GFX_ARGS                           31
 
 
 /* values for sound configuration suffixes */
 #define NUM_SND_ARGS                           1
 
 
-/* values for font configuration */
+/* values for music configuration suffixes */
+#define MUS_ARG_MODE_LOOP                      0
+
+#define NUM_MUS_ARGS                           1
+
 
+/* values for font configuration */
 #define FONT_INITIAL_1                         0
 #define FONT_INITIAL_2                         1
 #define FONT_INITIAL_3                         2
 #define 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_PLAYING                      6
-#define GAME_MODE_PSEUDO_DOOR                  7
-#define GAME_MODE_PSEUDO_PREVIEW               8
-#define GAME_MODE_PSEUDO_CRUMBLED              9
+#define GAME_MODE_DEFAULT                      0
+#define GAME_MODE_MAIN                         1
+#define GAME_MODE_LEVELS                       2
+#define GAME_MODE_SCORES                       3
+#define GAME_MODE_EDITOR                       4
+#define GAME_MODE_INFO                         5
+#define GAME_MODE_SETUP                                6
+#define GAME_MODE_PLAYING                      7
+#define GAME_MODE_PSEUDO_DOOR                  8
+#define GAME_MODE_PSEUDO_PREVIEW               9
+#define GAME_MODE_PSEUDO_CRUMBLED              10
 
 /* there are no special config file suffixes for these modes */
-#define GAME_MODE_PSEUDO_TYPENAME              10
-#define GAME_MODE_QUIT                         11
+#define GAME_MODE_PSEUDO_TYPENAME              11
+#define GAME_MODE_QUIT                         12
+
+/* special definitions currently only used for custom artwork configuration */
+#define MUSIC_PREFIX_BACKGROUND                        0
+#define NUM_MUSIC_PREFIXES                     1
+#define MAX_LEVELS                             1000
+
+/* definitions for demo animation lists */
+#define HELPANIM_LIST_NEXT                     -1
+#define HELPANIM_LIST_END                      -999
+
+
+/* program information and versioning definitions */
 
 #define PROGRAM_VERSION_MAJOR  3
 #define PROGRAM_VERSION_MINOR  0
-#define PROGRAM_VERSION_PATCH  7
-#define PROGRAM_VERSION_BUILD  1
-
-#if 0
-#define PROGRAM_VERSION_STRING "3.0.7"
-#endif
+#define PROGRAM_VERSION_PATCH  8
+#define PROGRAM_VERSION_BUILD  3
 
 #define PROGRAM_TITLE_STRING   "Rocks'n'Diamonds"
 #define PROGRAM_AUTHOR_STRING  "Holger Schemel"
 #define PROGRAM_COPYRIGHT_STRING "Copyright ©1995-2003 by Holger Schemel"
 
-#if 0
-#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
-#endif
-
 #define ICON_TITLE_STRING      PROGRAM_TITLE_STRING
 #define COOKIE_PREFIX          "ROCKSNDIAMONDS"
 #define FILENAME_PREFIX                "Rocks"
@@ -1110,6 +1155,9 @@ struct MenuInfo
 
   int list_size_default;
   int list_size[NUM_SPECIAL_GFX_ARGS];
+
+  int sound[NUM_SPECIAL_GFX_ARGS];
+  int music[NUM_SPECIAL_GFX_ARGS];
 };
 
 struct DoorInfo
@@ -1140,7 +1188,7 @@ struct PlayerInfo
   byte programmed_action;      /* action forced by game itself (like moving
                                   through doors); overrides other actions */
 
-  int jx,jy, last_jx,last_jy;
+  int jx, jy, last_jx, last_jy;
   int MovDir, MovPos, GfxDir, GfxPos;
   int Frame, StepFrame;
 
@@ -1160,6 +1208,22 @@ struct PlayerInfo
   boolean is_pushing;
   boolean is_switching;
 
+  boolean is_bored;
+  boolean is_sleeping;
+
+  int frame_counter_bored;
+  int frame_counter_sleeping;
+
+  int anim_delay_counter;
+  int post_delay_counter;
+
+  int action_waiting, last_action_waiting;
+  int special_action_bored;
+  int special_action_sleeping;
+
+  int num_special_action_bored;
+  int num_special_action_sleeping;
+
   int switch_x, switch_y;
 
   int show_envelope;
@@ -1172,6 +1236,8 @@ struct PlayerInfo
 
   unsigned long actual_frame_counter;
 
+  int step_counter;
+
   int score;
   int gems_still_needed;
   int sokobanfields_still_needed;
@@ -1186,6 +1252,11 @@ struct PlayerInfo
   int inventory_size;
 };
 
+struct LevelSetInfo
+{
+  int music[MAX_LEVELS];
+};
+
 struct LevelInfo
 {
   int file_version;    /* file format version the level is stored with    */
@@ -1281,6 +1352,12 @@ struct GameInfo
   boolean gravity;
   boolean explosions_delayed;
   boolean envelope_active;
+
+  /* values for player idle animation (no effect on engine) */
+  int player_boring_delay_fixed;
+  int player_boring_delay_random;
+  int player_sleeping_delay_fixed;
+  int player_sleeping_delay_random;
 };
 
 struct GlobalInfo
@@ -1433,6 +1510,11 @@ struct GraphicInfo
   int diggable_like;           /* element for cloning digging graphics */
   int border_size;             /* border size for "crumbled" graphics */
 
+  int anim_delay_fixed;                /* optional delay values for bored and   */
+  int anim_delay_random;       /* sleeping player animations (animation */
+  int post_delay_fixed;                /* intervall and following pause before  */
+  int post_delay_random;       /* next intervall (bored animation only) */
+
   int step_offset;             /* optional step offset of toon animations */
   int step_delay;              /* optional step delay of toon animations */
 
@@ -1451,6 +1533,38 @@ struct SoundInfo
   boolean loop;
 };
 
+struct MusicInfo
+{
+  boolean loop;
+};
+
+struct MusicPrefixInfo
+{
+  char *prefix;
+  boolean is_loop_music;
+};
+
+struct MusicFileInfo
+{
+  char *basename;
+
+  char *title_header;
+  char *artist_header;
+  char *album_header;
+  char *year_header;
+
+  char *title;
+  char *artist;
+  char *album;
+  char *year;
+
+  int music;
+
+  boolean is_sound;
+
+  struct MusicFileInfo *next;
+};
+
 struct ElementActionInfo
 {
   char *suffix;
@@ -1470,6 +1584,15 @@ struct SpecialSuffixInfo
   int value;
 };
 
+struct HelpAnimInfo
+{
+  int element;
+  int action;
+  int direction;
+
+  int delay;
+};
+
 
 #if 0
 extern GC                      tile_clip_gc;
@@ -1510,6 +1633,8 @@ 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 int                     RunnerVisit[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern int                     PlayerVisit[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 
 extern unsigned long           Properties[MAX_NUM_ELEMENTS][NUM_EP_BITFIELDS];
 
@@ -1544,6 +1669,7 @@ extern boolean                    network_player_action_received;
 
 extern int                     graphics_action_mapping[];
 
+extern struct LevelSetInfo     levelset;
 extern struct LevelInfo                level, level_template;
 extern struct PlayerInfo       stored_player[], *local_player;
 extern struct HiScore          highscore[];
@@ -1558,9 +1684,20 @@ 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 MusicPrefixInfo  music_prefix_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[];
+extern struct MusicInfo               *music_info;
+extern struct MusicFileInfo    *music_file_info;
+extern struct HelpAnimInfo     *helpanim_info;
+extern SetupFileHash           *helptext_info;
+extern struct ConfigInfo       image_config[];
+extern struct ConfigInfo       sound_config[];
+extern struct ConfigInfo       music_config[];
+extern struct ConfigInfo       image_config_suffix[];
+extern struct ConfigInfo       sound_config_suffix[];
+extern struct ConfigInfo       music_config_suffix[];
+extern struct ConfigInfo       helpanim_config[];
+extern struct ConfigInfo       helptext_config[];
 
 #endif /* MAIN_H */
index 11fd9bc864c4bb528f62c00f776bc23c1b65d894..71834c3b1f17dbc8be3a778149e0db9ea569570e 100644 (file)
@@ -89,8 +89,9 @@ static void broadcast(struct NetworkServerPlayerInfo *except,
 
   realbuffer[0] = realbuffer[1] = realbuffer[2] = 0;
   realbuffer[3] = (unsigned char)len;
-  for (player=first_player; player; player=player->next)
-    if (player != except && (player->active || !activeonly) && player->introduced)
+  for (player = first_player; player; player = player->next)
+    if (player != except && player->introduced &&
+       (player->active || !activeonly))
       addtobuffer(player, realbuffer, 4 + len);
 }
 
@@ -113,7 +114,7 @@ static void RemovePlayer(struct NetworkServerPlayerInfo *player)
     first_player = player->next;
   else
   {
-    for (v=first_player; v; v=v->next)
+    for (v = first_player; v; v = v->next)
     {
       if (v->next && v->next == player)
       {
@@ -149,6 +150,7 @@ static void AddPlayer(int fd)
 {
   struct NetworkServerPlayerInfo *player, *v;
   unsigned char nxn;
+  boolean again = TRUE;
 
   player = checked_malloc(sizeof (struct NetworkServerPlayerInfo));
 
@@ -166,9 +168,28 @@ static void AddPlayer(int fd)
 
   nxn = 1;
 
+#if 1
+  while (again)
+  {
+    again = FALSE;
+    v = player->next;
+
+    while (v)
+    {
+      if (v->number == nxn)
+      {
+       nxn++;
+
+       again = TRUE;
+       break;
+      }
+      v = v->next;
+    }
+  }
+#else
  again:
   v = player->next;
-  while(v)
+  while (v)
   {
     if (v->number == nxn)
     {
@@ -177,6 +198,7 @@ static void AddPlayer(int fd)
     }
     v = v->next;
   }
+#endif
 
   player->number = nxn;
   if (options.verbose)
@@ -233,7 +255,7 @@ static void Handle_OP_NUMBER_WANTED(struct NetworkServerPlayerInfo *player)
       Error(ERR_NETWORK_SERVER, "client %d (%s) wants to switch to # %d",
            player->number, player->player_name, nr_wanted);
 
-  for (v=first_player; v; v=v->next)
+  for (v = first_player; v; v = v->next)
   {
     if (v->number == nr_wanted)
     {
@@ -281,7 +303,7 @@ static void Handle_OP_PLAYER_NAME(struct NetworkServerPlayerInfo *player,
     len=16;
   memcpy(player->player_name, &buffer[2], len-2);
   player->player_name[len-2] = 0;
-  for (i=0; i<len-2; i++)
+  for (i = 0; i < len - 2; i++)
   {
     if (player->player_name[i] < ' ' || 
        ((unsigned char)(player->player_name[i]) > 0x7e &&
@@ -307,7 +329,7 @@ static void Handle_OP_PLAYER_NAME(struct NetworkServerPlayerInfo *player,
 
   if (!player->introduced)
   {
-    for (v=first_player; v; v=v->next)
+    for (v = first_player; v; v = v->next)
     {
       if (v != player && v->introduced)
       {
@@ -336,7 +358,7 @@ static void Handle_OP_START_PLAYING(struct NetworkServerPlayerInfo *player)
          (buffer[4] << 8) + buffer[5],
          &buffer[6]);
 
-  for (w=first_player; w; w=w->next)
+  for (w = first_player; w; w = w->next)
     if (w->introduced)
       w->active = 1;
 
@@ -344,7 +366,7 @@ static void Handle_OP_START_PLAYING(struct NetworkServerPlayerInfo *player)
   ServerFrameCounter = 0;
 
   /* reset player actions */
-  for (v=first_player; v; v=v->next)
+  for (v = first_player; v; v = v->next)
   {
     v->action = 0;
     v->action_received = FALSE;
@@ -384,7 +406,7 @@ static void Handle_OP_MOVE_PLAYER(struct NetworkServerPlayerInfo *player)
   int i;
 
   /* store player action */
-  for (v=first_player; v; v=v->next)
+  for (v = first_player; v; v = v->next)
   {
     if (v->number == player->number)
     {
@@ -394,7 +416,7 @@ static void Handle_OP_MOVE_PLAYER(struct NetworkServerPlayerInfo *player)
   }
 
   /* check if server received action from each player */
-  for (v=first_player; v; v=v->next)
+  for (v = first_player; v; v = v->next)
   {
     if (!v->action_received)
       return;
@@ -404,11 +426,11 @@ static void Handle_OP_MOVE_PLAYER(struct NetworkServerPlayerInfo *player)
   }
 
   /* initialize all player actions to zero */
-  for (i=0; i<last_client_nr; i++)
+  for (i = 0; i < last_client_nr; i++)
     buffer[6 + i] = 0;
 
   /* broadcast actions of all players to all players */
-  for (v=first_player; v; v=v->next)
+  for (v = first_player; v; v = v->next)
   {
     buffer[6 + v->number-1] = v->action;
     v->action = 0;
@@ -478,7 +500,7 @@ void NetworkServer(int port, int serveronly)
   {
     /* become a daemon, breaking all ties with the controlling terminal */
     options.verbose = FALSE;
-    for (i=0; i<255; i++)
+    for (i = 0; i < 255; i++)
     {
       if (i != lfd)
        close(i);
@@ -504,11 +526,11 @@ void NetworkServer(int port, int serveronly)
          PROTOCOL_VERSION_1, PROTOCOL_VERSION_2, PROTOCOL_VERSION_3);
   }
 
-  while(1)
+  while (1)
   {
     interrupt = 0;
 
-    for (player=first_player; player; player=player->next)
+    for (player = first_player; player; player = player->next)
       flushuser(player);
 
     FD_ZERO(&fds);
index 5511d176a1b9a9264c0e9b9db35fec4efe0a39f2..73a13b1f8ab3032962e7b46a57fa048452fce944 100644 (file)
@@ -100,7 +100,7 @@ char *getNetworkPlayerName(int player_nr)
   else if (player_nr == first_player.nr)
     return("you");
   else
-    for (player=&first_player; player; player=player->next)
+    for (player = &first_player; player; player = player->next)
       if (player->nr == player_nr && player->name && strlen(player->name))
        return(player->name);
 
@@ -173,7 +173,7 @@ boolean ConnectToServer(char *hostname, int port)
   StartNetworkServer(port);
 
   /* wait for server to start up and try connecting several times */
-  for (i=0; i<6; i++)
+  for (i = 0; i < 6; i++)
   {
     Delay(500);                /* wait 500 ms == 0.5 seconds */
     close(sfd);
@@ -378,7 +378,7 @@ static void Handle_OP_PLAYER_CONNECTED()
   printf("OP_PLAYER_CONNECTED: %d\n", new_client_nr);
   Error(ERR_NETWORK_CLIENT, "new client %d connected", new_client_nr);
 
-  for (player=&first_player; player; player=player->next)
+  for (player = &first_player; player; player = player->next)
   {
     if (player->nr == new_client_nr)
       Error(ERR_EXIT, "multiplayer server sent duplicate player id");
@@ -405,7 +405,7 @@ static void Handle_OP_PLAYER_DISCONNECTED()
   Error(ERR_NETWORK_CLIENT, "client %d (%s) disconnected",
        player_nr, getNetworkPlayerName(buffer[0]));
 
-  for (player=&first_player; player; player=player->next)
+  for (player = &first_player; player; player = player->next)
     if (player->next == player_disconnected)
       player->next = player_disconnected->next;
   free(player_disconnected);
@@ -506,7 +506,7 @@ static void Handle_OP_MOVE_PLAYER(unsigned int len)
   }
 
   /* copy valid player actions */
-  for (i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
     stored_player[i].effective_action =
       (i < len - 6 && stored_player[i].active ? buffer[6 + i] : 0);
 
index 8e66c8c9ed7831cc55f2c2b163dab62f8d2a1812..079745e98a5cb7d0a2e98b1bf1ddcb8e927d8978 100644 (file)
 #define SETUPINPUT_SCREEN_POS_EMPTY1   (SETUPINPUT_SCREEN_POS_START + 3)
 #define SETUPINPUT_SCREEN_POS_EMPTY2   (SETUPINPUT_SCREEN_POS_END - 1)
 
+/* screens on the info screen */
+#define INFO_MODE_MAIN                 0
+#define INFO_MODE_ELEMENTS             1
+#define INFO_MODE_MUSIC                        2
+#define INFO_MODE_CREDITS              3
+#define INFO_MODE_PROGRAM              4
+#define INFO_MODE_LEVELSET             5
+
+#define MAX_INFO_MODES                 6
+
 /* for various menu stuff  */
+#define MAX_INFO_ELEMENTS_ON_SCREEN    10
 #define MAX_MENU_ENTRIES_ON_SCREEN     (SCR_FIELDY - 2)
 #define MENU_SCREEN_START_YPOS         2
 #define MENU_SCREEN_VALUE_XPOS         14
@@ -68,8 +79,23 @@ static void CalibrateJoystick(int);
 static void execSetupArtwork(void);
 static void HandleChooseTree(int, int, int, int, int, TreeInfo **);
 
+static void DrawChooseLevel(void);
+static void DrawInfoScreen(void);
+static void DrawSetupScreen(void);
+
+static void DrawInfoScreen_HelpAnim(int, int, boolean);
+static void DrawInfoScreen_HelpText(int, int, int, int);
+static void HandleInfoScreen_Main(int, int, int, int, int);
+static void HandleInfoScreen_Elements(int);
+static void HandleInfoScreen_Music(int);
+static void HandleInfoScreen_Credits(int);
+static void HandleInfoScreen_Program(int);
+
+static void MapChooseTreeGadgets(TreeInfo *);
+
 static struct GadgetInfo *screen_gadget[NUM_SCREEN_GADGETS];
 static int setup_mode = SETUP_MODE_MAIN;
+static int info_mode = INFO_MODE_MAIN;
 
 #define mSX (SX + (game_status >= GAME_MODE_MAIN &&    \
                   game_status <= GAME_MODE_SETUP ?     \
@@ -139,29 +165,44 @@ static void drawChooseTreeCursor(int ypos, int color)
   game_status = last_game_status;      /* restore current game status */
 }
 
-static void PlaySound_Menu_Start(int sound)
+static void PlayMenuSound()
 {
+  int sound = menu.sound[game_status];
+
+  if (sound == SND_UNDEFINED)
+    return;
+
   if (sound_info[sound].loop)
     PlaySoundLoop(sound);
   else
     PlaySound(sound);
 }
 
-static void PlaySound_Menu_Continue(int sound)
+static void PlayMenuSoundIfLoop()
 {
+  int sound = menu.sound[game_status];
+
+  if (sound == SND_UNDEFINED)
+    return;
+
   if (sound_info[sound].loop)
     PlaySoundLoop(sound);
 }
 
-void DrawHeadline()
+static void PlayMenuMusic()
 {
-  int text1_width = getTextWidth(PROGRAM_TITLE_STRING,     FONT_TITLE_1);
-  int text2_width = getTextWidth(PROGRAM_COPYRIGHT_STRING, FONT_TITLE_2);
-  int x1 = SX + (SXSIZE - text1_width) / 2;
-  int x2 = SX + (SXSIZE - text2_width) / 2;
+  int music = menu.music[game_status];
+
+  if (music == MUS_UNDEFINED)
+    return;
 
-  DrawText(x1, SY + 8,  PROGRAM_TITLE_STRING,     FONT_TITLE_1);
-  DrawText(x2, SY + 46, PROGRAM_COPYRIGHT_STRING, FONT_TITLE_2);
+  PlayMusic(music);
+}
+
+void DrawHeadline()
+{
+  DrawTextSCentered(8,  FONT_TITLE_1, PROGRAM_TITLE_STRING);
+  DrawTextSCentered(46, FONT_TITLE_2, PROGRAM_COPYRIGHT_STRING);
 }
 
 static void ToggleFullscreenIfNeeded()
@@ -192,12 +233,11 @@ void DrawMainMenu()
 {
   static LevelDirTree *leveldir_last_valid = NULL;
   char *name_text = (!options.network && setup.team_mode ? "Team:" : "Name:");
-  int name_width  = getTextWidth("Name:",  FONT_MENU_1);
-  int level_width = getTextWidth("Level:", FONT_MENU_1);
+  int name_width, level_width;
   int i;
 
   UnmapAllGadgets();
-  FadeSounds();
+  FadeSoundsAndMusic();
 
   KeyboardAutoRepeatOn();
   ActivateJoystick();
@@ -260,6 +300,10 @@ void DrawMainMenu()
   DrawText(mSX + 32, mSY + 8*32, "Setup", FONT_MENU_1);
   DrawText(mSX + 32, mSY + 9*32, "Quit", FONT_MENU_1);
 
+  /* calculated after (possible) reload of custom artwork */
+  name_width = getTextWidth(name_text, FONT_MENU_1);
+  level_width = getTextWidth("Level:", 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);
@@ -271,34 +315,35 @@ void DrawMainMenu()
 
   if (leveldir_current->readonly)
   {
-    DrawTextF(mSX + level_width + 9 * 32 - 2,
+    DrawTextS(mSX + level_width + 9 * 32 - 2,
              mSY + 3 * 32 + 1 - 7, FONT_TEXT_3, "READ");
-    DrawTextF(mSX + level_width + 9 * 32 - 2,
+    DrawTextS(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 ? IMG_MENU_BUTTON_RIGHT :IMG_MENU_BUTTON));
+  for (i = 0; i < 8; i++)
+    initCursor(i, (i == 1 || i == 4 || i == 6 ? IMG_MENU_BUTTON_RIGHT :
+                  IMG_MENU_BUTTON));
 
   drawCursorXY(level_width/32 + 4, 1, IMG_MENU_BUTTON_LEFT);
   drawCursorXY(level_width/32 + 8, 1, IMG_MENU_BUTTON_RIGHT);
 
-  DrawText(SX + 56, SY + 326, "A Game by Artsoft Entertainment", FONT_TITLE_2);
+  DrawTextSCentered(326, FONT_TITLE_2, "A Game by Artsoft Entertainment");
 
   FadeToFront();
   InitAnimation();
-  HandleMainMenu(0,0, 0,0, MB_MENU_INITIALIZE);
+
+  HandleMainMenu(0, 0, 0, 0, MB_MENU_INITIALIZE);
 
   TapeStop();
   if (TAPE_IS_EMPTY(tape))
     LoadTape(level_nr);
   DrawCompleteVideoDisplay();
 
-  OpenDoor(DOOR_CLOSE_1 | DOOR_OPEN_2);
+  PlayMenuSound();
+  PlayMenuMusic();
 
-#if 0
-  ClearEventQueue();
-#endif
+  OpenDoor(DOOR_CLOSE_1 | DOOR_OPEN_2);
 }
 
 static void gotoTopLevelDir()
@@ -361,7 +406,8 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
   {
     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 old_level_nr = level_nr;
+    int new_level_nr;
 
     new_level_nr = level_nr + (x == 10 ? -step : +step);
     if (new_level_nr < leveldir_current->first_level)
@@ -372,27 +418,29 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
     if (setup.handicap && new_level_nr > leveldir_current->handicap_level)
       new_level_nr = leveldir_current->handicap_level;
 
-    if (old_level_nr == new_level_nr ||
-       !DelayReached(&level_delay, GADGET_FRAME_DELAY))
-      goto out;
-
-    level_nr = new_level_nr;
+    if (new_level_nr != old_level_nr &&
+       DelayReached(&level_delay, GADGET_FRAME_DELAY))
+    {
+      level_nr = new_level_nr;
 
-    DrawText(mSX + 11 * 32, mSY + 3 * 32, int2str(level_nr, 3), FONT_VALUE_1);
+      DrawText(mSX + 11 * 32, mSY + 3 * 32, int2str(level_nr, 3),
+              FONT_VALUE_1);
 
-    LoadLevel(level_nr);
-    DrawMicroLevel(MICROLEV_XPOS, MICROLEV_YPOS, TRUE);
+      LoadLevel(level_nr);
+      DrawMicroLevel(MICROLEV_XPOS, MICROLEV_YPOS, TRUE);
 
-    TapeErase();
-    LoadTape(level_nr);
-    DrawCompleteVideoDisplay();
+      TapeErase();
+      LoadTape(level_nr);
+      DrawCompleteVideoDisplay();
 
-    /* needed because DrawMicroLevel() takes some time */
-    BackToFront();
-    SyncDisplay();
-    DelayReached(&level_delay, 0);     /* reset delay counter */
+      /* needed because DrawMicroLevel() takes some time */
+      BackToFront();
+      SyncDisplay();
+      DelayReached(&level_delay, 0);   /* reset delay counter */
+    }
   }
-  else if (x == 0 && y >= 0 && y <= 7)
+  else if (IN_VIS_FIELD(x, y) &&
+          y >= 0 && y <= 7 && (y != 1 || x < 10))
   {
     if (button)
     {
@@ -439,7 +487,8 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
       else if (y == 4)
       {
        game_status = GAME_MODE_INFO;
-       DrawHelpScreen();
+       info_mode = INFO_MODE_MAIN;
+       DrawInfoScreen();
       }
       else if (y == 5)
       {
@@ -473,541 +522,608 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button)
     }
   }
 
-  out:
-
   if (game_status == GAME_MODE_MAIN)
   {
     DrawMicroLevel(MICROLEV_XPOS, MICROLEV_YPOS, FALSE);
     DoAnimation();
   }
-
-  BackToFront();
 }
 
 
-#define MAX_HELPSCREEN_ELS     10
-#define HA_NEXT                        -999
-#define HA_END                 -1000
+/* ========================================================================= */
+/* info screen functions                                                     */
+/* ========================================================================= */
 
-static long helpscreen_state;
-static int helpscreen_step[MAX_HELPSCREEN_ELS];
-static int helpscreen_frame[MAX_HELPSCREEN_ELS];
+static struct TokenInfo *info_info;
+static int num_info_info;
 
-static int helpscreen_action[] =
+static void execInfoElements()
 {
-  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,
+  info_mode = INFO_MODE_ELEMENTS;
+  DrawInfoScreen();
+}
 
-  IMG_SAND,                            -1,                     HA_NEXT,
+static void execInfoMusic()
+{
+  info_mode = INFO_MODE_MUSIC;
+  DrawInfoScreen();
+}
 
-  IMG_EMPTY_SPACE,                     -1,                     HA_NEXT,
+static void execInfoCredits()
+{
+  info_mode = INFO_MODE_CREDITS;
+  DrawInfoScreen();
+}
 
-  IMG_QUICKSAND_EMPTY,                 -1,                     HA_NEXT,
+static void execInfoProgram()
+{
+  info_mode = INFO_MODE_PROGRAM;
+  DrawInfoScreen();
+}
 
-  IMG_STEELWALL,                       -1,                     HA_NEXT,
+static void execInfoLevelSet()
+{
+  info_mode = INFO_MODE_LEVELSET;
+  DrawInfoScreen();
+}
 
-  IMG_WALL,                            -1,                     HA_NEXT,
+static void execExitInfo()
+{
+  game_status = GAME_MODE_MAIN;
+  DrawMainMenu();
+}
 
-  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,
+static struct TokenInfo info_info_main[] =
+{
+  { TYPE_ENTER_SCREEN, execInfoElements,       "Elements Info"         },
+  { TYPE_ENTER_SCREEN, execInfoMusic,          "Music Info"            },
+  { TYPE_ENTER_SCREEN, execInfoCredits,        "Credits"               },
+  { TYPE_ENTER_SCREEN, execInfoProgram,        "Program Info"          },
+  { TYPE_ENTER_SCREEN, execInfoLevelSet,       "Level Set Info"        },
+  { TYPE_EMPTY,                NULL,                   ""                      },
+  { TYPE_LEAVE_MENU,   execExitInfo,           "Exit"                  },
 
-  IMG_INVISIBLE_WALL,                  -1,                     HA_NEXT,
+  { 0,                 NULL,                   NULL                    }
+};
 
-  IMG_WALL_SLIPPERY,                   -1,                     HA_NEXT,
+static void DrawInfoScreen_Main()
+{
+  int i;
 
-  IMG_FONT_GAME_INFO,                  -1,                     HA_NEXT,
+  UnmapAllGadgets();
+  CloseDoor(DOOR_CLOSE_2);
 
-  IMG_EMERALD,                         -1,                     HA_NEXT,
+  ClearWindow();
 
-  IMG_DIAMOND,                         -1,                     HA_NEXT,
+  DrawText(mSX + 16, mSY + 16, "Info Screen", FONT_TITLE_1);
 
-  IMG_BD_DIAMOND,                      -1,                     HA_NEXT,
+  info_info = info_info_main;
+  num_info_info = 0;
 
-  IMG_EMERALD_YELLOW,                  50,
-  IMG_EMERALD_RED,                     50,
-  IMG_EMERALD_PURPLE,                  50,                     HA_NEXT,
+  for (i = 0; info_info[i].type != 0 && i < NUM_MENU_ENTRIES_ON_SCREEN; i++)
+  {
+    int ypos = MENU_SCREEN_START_YPOS + i;
+    int font_nr = FONT_MENU_1;
 
-  IMG_BD_ROCK,                         -1,                     HA_NEXT,
+    DrawText(mSX + 32, mSY + ypos * 32, info_info[i].text, font_nr);
 
-  IMG_BOMB,                            100,
-  IMG_EXPLOSION,                       16,
-  IMG_EMPTY_SPACE,                     10,                     HA_NEXT,
+    if (info_info[i].type & TYPE_ENTER_MENU)
+      initCursor(i, IMG_MENU_BUTTON_RIGHT);
+    else if (info_info[i].type & TYPE_LEAVE_MENU)
+      initCursor(i, IMG_MENU_BUTTON_LEFT);
+    else if (info_info[i].type & ~TYPE_SKIP_ENTRY)
+      initCursor(i, IMG_MENU_BUTTON);
 
-  IMG_NUT,                             100,
-  IMG_NUT_BREAKING,                    6,
-  IMG_EMERALD,                         20,                     HA_NEXT,
+    num_info_info++;
+  }
 
-  IMG_WALL_EMERALD,                    100,
-  IMG_EXPLOSION,                       16,
-  IMG_EMERALD,                         20,                     HA_NEXT,
+  FadeToFront();
+  InitAnimation();
 
-  IMG_WALL_DIAMOND,                    100,
-  IMG_EXPLOSION,                       16,
-  IMG_DIAMOND,                         20,                     HA_NEXT,
+  PlayMenuSound();
+  PlayMenuMusic();
 
-  IMG_WALL_BD_DIAMOND,                         100,
-  IMG_EXPLOSION,                       16,
-  IMG_BD_DIAMOND,                      20,                     HA_NEXT,
+  HandleInfoScreen_Main(0, 0, 0, 0, MB_MENU_INITIALIZE);
+}
 
-  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,
+void HandleInfoScreen_Main(int mx, int my, int dx, int dy, int button)
+{
+  static int choice_store[MAX_INFO_MODES];
+  int choice = choice_store[info_mode];                /* always starts with 0 */
+  int x = 0;
+  int y = choice;
 
-  IMG_ACID,                            -1,                     HA_NEXT,
+  if (button == MB_MENU_INITIALIZE)
+  {
+    /* advance to first valid menu entry */
+    while (choice < num_info_info &&
+          info_info[choice].type & TYPE_SKIP_ENTRY)
+      choice++;
+    choice_store[info_mode] = choice;
 
-  IMG_KEY_1,                           50,
-  IMG_KEY_2,                           50,
-  IMG_KEY_3,                           50,
-  IMG_KEY_4,                           50,                     HA_NEXT,
+    drawCursor(choice, FC_RED);
+    return;
+  }
+  else if (button == MB_MENU_LEAVE)
+  {
+    for (y = 0; y < num_info_info; y++)
+    {
+      if (info_info[y].type & TYPE_LEAVE_MENU)
+      {
+       void (*menu_callback_function)(void) = info_info[y].value;
 
-  IMG_GATE_1,                          50,
-  IMG_GATE_2,                          50,
-  IMG_GATE_3,                          50,
-  IMG_GATE_4,                          50,                     HA_NEXT,
+       menu_callback_function();
+       break;  /* absolutely needed because function changes 'info_info'! */
+      }
+    }
 
-  IMG_GATE_1_GRAY,                     50,
-  IMG_GATE_2_GRAY,                     50,
-  IMG_GATE_3_GRAY,                     50,
-  IMG_GATE_4_GRAY,                     50,                     HA_NEXT,
+    return;
+  }
 
-  IMG_DYNAMITE,                                -1,                     HA_NEXT,
+  if (mx || my)                /* mouse input */
+  {
+    x = (mx - mSX) / 32;
+    y = (my - mSY) / 32 - MENU_SCREEN_START_YPOS;
+  }
+  else if (dx || dy)   /* keyboard input */
+  {
+    if (dx)
+    {
+      int menu_navigation_type = (dx < 0 ? TYPE_LEAVE_MENU : TYPE_ENTER_MENU);
 
-  IMG_DYNAMITE_ACTIVE,                 96,
-  IMG_EXPLOSION,                       16,
-  IMG_EMPTY_SPACE,                     20,                     HA_NEXT,
+      if (info_info[choice].type & menu_navigation_type ||
+         info_info[choice].type & TYPE_ENTER_SCREEN ||
+         info_info[choice].type & TYPE_BOOLEAN_STYLE)
+       button = MB_MENU_CHOICE;
+    }
+    else if (dy)
+      y = choice + dy;
 
-  IMG_DYNABOMB_ACTIVE,                 100,
-  IMG_EXPLOSION,                       16,
-  IMG_EMPTY_SPACE,                     20,                     HA_NEXT,
+    /* jump to next non-empty menu entry (up or down) */
+    while (y > 0 && y < num_info_info - 1 &&
+          info_info[y].type & TYPE_SKIP_ENTRY)
+      y += dy;
+  }
 
-  IMG_DYNABOMB_INCREASE_NUMBER,                -1,                     HA_NEXT,
+  if (IN_VIS_FIELD(x, y) &&
+      y >= 0 && y < num_info_info && info_info[y].type & ~TYPE_SKIP_ENTRY)
+  {
+    if (button)
+    {
+      if (y != choice)
+      {
+       drawCursor(y, FC_RED);
+       drawCursor(choice, FC_BLUE);
+       choice = choice_store[info_mode] = y;
+      }
+    }
+    else if (!(info_info[y].type & TYPE_GHOSTED))
+    {
+      if (info_info[y].type & TYPE_ENTER_OR_LEAVE_MENU)
+      {
+       void (*menu_callback_function)(void) = info_info[choice].value;
 
-  IMG_DYNABOMB_INCREASE_SIZE,          -1,                     HA_NEXT,
+       menu_callback_function();
+      }
+    }
+  }
+}
 
-  IMG_DYNABOMB_INCREASE_POWER,         -1,                     HA_NEXT,
+void DrawInfoScreen_HelpAnim(int start, int max_anims, boolean init)
+{
+  static int infoscreen_step[MAX_INFO_ELEMENTS_ON_SCREEN];
+  static int infoscreen_frame[MAX_INFO_ELEMENTS_ON_SCREEN];
+  int xstart = mSX + 16;
+  int ystart = mSY + 64 + 2 * 32;
+  int ystep = TILEY + 4;
+  int element, action, direction;
+  int graphic;
+  int delay;
+  int sync_frame;
+  int i, j;
 
-  IMG_SPACESHIP_RIGHT,                 16,
-  IMG_SPACESHIP_UP,                    16,
-  IMG_SPACESHIP_LEFT,                  16,
-  IMG_SPACESHIP_DOWN,                  16,                     HA_NEXT,
+  if (init)
+  {
+    for (i = 0; i < MAX_INFO_ELEMENTS_ON_SCREEN; i++)
+      infoscreen_step[i] = infoscreen_frame[i] = 0;
 
-  IMG_BUG_RIGHT,                       16,
-  IMG_BUG_UP,                          16,
-  IMG_BUG_LEFT,                                16,
-  IMG_BUG_DOWN,                                16,                     HA_NEXT,
+    SetMainBackgroundImage(IMG_BACKGROUND_INFO);
+    ClearWindow();
+    DrawHeadline();
 
-  IMG_BD_BUTTERFLY,                    -1,                     HA_NEXT,
+    DrawTextSCentered(100, FONT_TEXT_1, "The Game Elements:");
 
-  IMG_BD_FIREFLY,                      -1,                     HA_NEXT,
+    DrawTextSCentered(SYSIZE - 20, FONT_TEXT_4,
+                     "Press any key or button for next page");
 
-  IMG_PACMAN_RIGHT,                    16,
-  IMG_PACMAN_UP,                       16,
-  IMG_PACMAN_LEFT,                     16,
-  IMG_PACMAN_DOWN,                     16,                     HA_NEXT,
+    FrameCounter = 0;
+  }
 
-  IMG_YAMYAM,                          -1,                     HA_NEXT,
+  i = j = 0;
+  while (helpanim_info[j].element != HELPANIM_LIST_END)
+  {
+    if (i >= start + MAX_INFO_ELEMENTS_ON_SCREEN ||
+       i >= max_anims)
+      break;
+    else if (i < start)
+    {
+      while (helpanim_info[j].element != HELPANIM_LIST_NEXT)
+       j++;
 
-  IMG_DARK_YAMYAM,                     -1,                     HA_NEXT,
+      j++;
+      i++;
 
-  IMG_ROBOT,                           -1,                     HA_NEXT,
+      continue;
+    }
 
-  IMG_MOLE_MOVING_RIGHT,               16,
-  IMG_MOLE_MOVING_UP,                  16,
-  IMG_MOLE_MOVING_LEFT,                        16,
-  IMG_MOLE_MOVING_DOWN,                        16,                     HA_NEXT,
+    j += infoscreen_step[i - start];
 
-  IMG_PENGUIN_MOVING_RIGHT,            16,
-  IMG_PENGUIN_MOVING_UP,               16,
-  IMG_PENGUIN_MOVING_LEFT,             16,
-  IMG_PENGUIN_MOVING_DOWN,             16,                     HA_NEXT,
+    element = helpanim_info[j].element;
+    action = helpanim_info[j].action;
+    direction = helpanim_info[j].direction;
 
-  IMG_PIG_MOVING_RIGHT,                        16,
-  IMG_PIG_MOVING_UP,                   16,
-  IMG_PIG_MOVING_LEFT,                 16,
-  IMG_PIG_MOVING_DOWN,                 16,                     HA_NEXT,
+    if (action != -1 && direction != -1)
+      graphic = el_act_dir2img(element, action, direction);
+    else if (action != -1)
+      graphic = el_act2img(element, action);
+    else if (direction != -1)
+      graphic = el_act2img(element, direction);
+    else
+      graphic = el2img(element);
 
-  IMG_DRAGON_MOVING_RIGHT,             16,
-  IMG_DRAGON_MOVING_UP,                        16,
-  IMG_DRAGON_MOVING_LEFT,              16,
-  IMG_DRAGON_MOVING_DOWN,              16,                     HA_NEXT,
+    delay = helpanim_info[j++].delay;
 
-  IMG_SATELLITE,                       -1,                     HA_NEXT,
+    if (delay == -1)
+      delay = 1000000;
 
-  IMG_ROBOT_WHEEL,                     50,
-  IMG_ROBOT_WHEEL_ACTIVE,              100,                    HA_NEXT,
+    if (infoscreen_frame[i - start] == 0)
+    {
+      sync_frame = 0;
+      infoscreen_frame[i - start] = delay - 1;
+    }
+    else
+    {
+      sync_frame = delay - infoscreen_frame[i - start];
+      infoscreen_frame[i - start]--;
+    }
 
-  IMG_LAMP,                            50,
-  IMG_LAMP_ACTIVE,                     50,                     HA_NEXT,
+    if (helpanim_info[j].element == HELPANIM_LIST_NEXT)
+    {
+      if (!infoscreen_frame[i - start])
+       infoscreen_step[i - start] = 0;
+    }
+    else
+    {
+      if (!infoscreen_frame[i - start])
+       infoscreen_step[i - start]++;
+      while (helpanim_info[j].element != HELPANIM_LIST_NEXT)
+       j++;
+    }
 
-  IMG_TIME_ORB_FULL,                   50,
-  IMG_TIME_ORB_EMPTY,                  50,                     HA_NEXT,
+    j++;
 
-  IMG_AMOEBA_DROP,                     50,
-  IMG_AMOEBA_GROWING,                  6,
-  IMG_AMOEBA_WET,                      20,                     HA_NEXT,
+    ClearRectangleOnBackground(drawto, xstart, ystart + (i - start) * ystep,
+                              TILEX, TILEY);
+    DrawGraphicAnimationExt(drawto, xstart, ystart + (i - start) * ystep,
+                           graphic, sync_frame, USE_MASKING);
 
-  IMG_AMOEBA_DEAD,                     -1,                     HA_NEXT,
+    if (init)
+      DrawInfoScreen_HelpText(element, action, direction, i - start);
 
-  IMG_AMOEBA_WET,                      -1,                     HA_NEXT,
+    i++;
+  }
 
-  IMG_AMOEBA_WET,                      100,
-  IMG_AMOEBA_GROWING,                  6,                      HA_NEXT,
+  redraw_mask |= REDRAW_FIELD;
 
-  IMG_AMOEBA_FULL,                     50,
-  IMG_AMOEBA_DEAD,                     50,
-  IMG_EXPLOSION,                       16,
-  IMG_DIAMOND,                         20,                     HA_NEXT,
+  FrameCounter++;
+}
 
-  IMG_GAME_OF_LIFE,                    -1,                     HA_NEXT,
+static char *getHelpText(int element, int action, int direction)
+{
+  char token[MAX_LINE_LEN];
 
-  IMG_BIOMAZE,                         -1,                     HA_NEXT,
+  strcpy(token, element_info[element].token_name);
 
-  IMG_MAGIC_WALL_ACTIVE,               -1,                     HA_NEXT,
+  if (action != -1)
+    strcat(token, element_action_info[action].suffix);
 
-  IMG_BD_MAGIC_WALL_ACTIVE,            -1,                     HA_NEXT,
+  if (direction != -1)
+    strcat(token, element_direction_info[MV_DIR_BIT(direction)].suffix);
 
-  IMG_EXIT_CLOSED,                     200,
-  IMG_EXIT_OPENING,                    16,
-  IMG_EXIT_OPEN,                       100,                    HA_NEXT,
+  return getHashEntry(helptext_info, token);
+}
 
-  IMG_EXIT_OPEN,                       -1,                     HA_NEXT,
+void DrawInfoScreen_HelpText(int element, int action, int direction, int ypos)
+{
+#if 0
+  int font_nr = FONT_TEXT_2;
+#else
+  int font_nr = FONT_LEVEL_NUMBER;
+#endif
+  int font_width = getFontWidth(font_nr);
+  int sx = mSX + MINI_TILEX + TILEX + MINI_TILEX;
+  int sy = mSY + 65 + 2 * 32 + 1;
+  int ystep = TILEY + 4;
+  int pad_x = sx - SX;
+  int max_chars_per_line = (SXSIZE - pad_x - MINI_TILEX) / font_width;
+  int max_lines_per_text = 2;    
+  char *text = NULL;
 
-  IMG_SOKOBAN_OBJECT,                  -1,                     HA_NEXT,
+  if (action != -1 && direction != -1)         /* element.action.direction */
+    text = getHelpText(element, action, direction);
 
-  IMG_SOKOBAN_FIELD_EMPTY,             -1,                     HA_NEXT,
+  if (text == NULL && action != -1)            /* element.action */
+    text = getHelpText(element, action, -1);
 
-  IMG_SOKOBAN_FIELD_FULL,              -1,                     HA_NEXT,
+  if (text == NULL && direction != -1)         /* element.direction */
+    text = getHelpText(element, -1, direction);
 
-  IMG_SPEED_PILL,                      -1,                     HA_NEXT,
+  if (text == NULL)                            /* base element */
+    text = getHelpText(element, -1, -1);
 
-  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 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"},
- {"Invisible Wall: Behaves like normal","wall, but is invisible"},
- {"Old Wall: Like normal wall, but",   "some things can fall down from it"},
- {"Letter Wall: Looks like a letter,", "behaves like a normal wall"},
- {"Emerald: You must collect enough of","them to finish a level"},
- {"Diamond: Counts as 3 emeralds, but",        "can be destroyed by rocks"},
- {"Diamond (BD style): Counts like one","emerald and behaves a bit different"},
- {"Colorful Gems:",                    "Seem to behave like Emeralds"},
- {"Rock: Smashes several things;",     "Can be moved by the player"},
- {"Bomb: You can move it, but be",     "careful when dropping it"},
- {"Nut: Throw a rock on it to open it;","Each nut contains an emerald"},
- {"Wall with an emerald inside:",      "Bomb the wall away to get it"},
- {"Wall with a diamond inside:",       "Bomb the wall away to get it"},
- {"Wall with BD style diamond inside:",        "Bomb the wall away to get it"},
- {"Wall with colorful gem inside:",    "Bomb the wall away to get it"},
- {"Acid: Things that fall in are gone",        "forever (including our hero)"},
- {"Key: Opens the door that has the",  "same color (red/yellow/green/blue)"},
- {"Door: Can be opened by the key",    "with the same color"},
- {"Door: You have to find out the",    "right color of the key for it"},
- {"Dynamite: Collect it and use it to",        "destroy walls or kill enemies"},
- {"Dynamite: This one explodes after", "a few seconds"},
- {"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!"},
- {"Firefly: Moves at the left side",   "of walls; don't touch it!"},
- {"Pacman: Eats the amoeba and you,",  "if you're not careful"},
- {"Cruncher: Eats diamonds and you,",  "if you're not careful"},
- {"Cruncher (BD style):",              "Eats almost everything"},
- {"Robot: Tries to kill the player",   ""},
- {"The mole: Eats the amoeba and turns","empty space into normal sand"},
- {"The penguin: Guide him to the exit,","but keep him away from monsters!"},
- {"The Pig: Harmless, but eats all",   "gems it can get"},
- {"The Dragon: Breathes fire,",                "especially to some monsters"},
- {"Sonde: Follows you everywhere;",    "harmless, but may block your way"},
- {"Magic Wheel: Touch it to get rid of","the robots for some seconds"},
- {"Light Bulb: All of them must be",   "switched on to finish a level"},
- {"Extra Time Orb: Adds some seconds", "to the time available for the level"},
- {"Amoeba Drop: Grows to an amoeba on",        "the ground - don't touch it"},
- {"Dead Amoeba: Does not grow, but",   "can still kill bugs and spaceships"},
- {"Normal Amoeba: Grows through empty",        "fields, sand and quicksand"},
- {"Dropping Amoeba: This one makes",   "drops that grow to a new amoeba"},
- {"Living Amoeba (BD style): Contains",        "other element, when surrounded"},
- {"Game Of Life: Behaves like the well","known 'Game Of Life' (2333 style)"},
- {"Biomaze: A bit like the 'Game Of",  "Life', but builds crazy mazes"},
- {"Magic Wall: Changes rocks, emeralds","and diamonds when they pass it"},
- {"Magic Wall (BD style):",            "Changes rocks and BD style diamonds"},
- {"Exit door: Opens if you have enough","emeralds to finish the level"},
- {"Open exit door: Enter here to leave","the level and exit the actual game"},
- {"Sokoban element: Object which must", "be pushed to an empty field"},
- {"Sokoban element: Empty field where", "a Sokoban object can be placed on"},
- {"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 *));
+  if (text == NULL)                            /* not found */
+    text = "No description available";
 
-static char *helpscreen_music[][3] =
+  if (strlen(text) <= max_chars_per_line)      /* only one line of text */
+    sy += getFontHeight(font_nr) / 2;
+
+  DrawTextWrapped(sx, sy + ypos * ystep, text, font_nr,
+                 max_chars_per_line, max_lines_per_text);
+}
+
+void DrawInfoScreen_Elements()
 {
-  { "Alchemy",                 "Ian Boddy",            "Drive" },
-  { "The Chase",               "Propaganda",           "A Secret Wish" },
-  { "Network 23",              "Tangerine Dream",      "Exit" },
-  { "Czardasz",                        "Robert Pieculewicz",   "Czardasz" },
-  { "21st Century Common Man", "Tangerine Dream",      "Tyger" },
-  { "Voyager",                 "The Alan Parsons Project","Pyramid" },
-  { "Twilight Painter",                "Tangerine Dream",      "Heartbreakers" }
-};
-static int num_helpscreen_music = 7;
-static int helpscreen_musicpos;
+  LoadHelpAnimInfo();
+  LoadHelpTextInfo();
 
-#if 0
-void OLD_DrawHelpScreenElAction(int start)
+  HandleInfoScreen_Elements(MB_MENU_INITIALIZE);
+
+  FadeToFront();
+  InitAnimation();
+}
+
+void HandleInfoScreen_Elements(int button)
 {
-  int i = 0, j = 0;
-  int frame, graphic;
-  int xstart = SX+16, ystart = SY+64+2*32, ystep = TILEY+4;
+  static unsigned long info_delay = 0;
+  static int num_anims;
+  static int num_pages;
+  static int page;
+  int anims_per_page = MAX_INFO_ELEMENTS_ON_SCREEN;
+  int button_released = !button;
+  int i;
 
-  while(helpscreen_action[j] != HA_END)
+  if (button == MB_MENU_INITIALIZE)
   {
-    if (i>=start+MAX_HELPSCREEN_ELS || i>=num_helpscreen_els)
-      break;
-    else if (i<start || helpscreen_delay[i-start])
-    {
-      if (i>=start && helpscreen_delay[i-start])
-       helpscreen_delay[i-start]--;
+    boolean new_element = TRUE;
 
-      while(helpscreen_action[j] != HA_NEXT)
-       j++;
-      j++;
-      i++;
-      continue;
+    num_anims = 0;
+    for (i = 0; helpanim_info[i].element != HELPANIM_LIST_END; i++)
+    {
+      if (helpanim_info[i].element == HELPANIM_LIST_NEXT)
+       new_element = TRUE;
+      else if (new_element)
+      {
+       num_anims++;
+       new_element = FALSE;
+      }
     }
 
-    j += 3*helpscreen_step[i-start];
-    graphic = helpscreen_action[j++];
+    num_pages = (num_anims + anims_per_page - 1) / anims_per_page;
+    page = 0;
+  }
+  else if (button == MB_MENU_LEAVE)
+  {
+    info_mode = INFO_MODE_MAIN;
+    DrawInfoScreen();
 
-    if (helpscreen_frame[i-start])
-    {
-      frame = helpscreen_action[j++] - helpscreen_frame[i-start];
-      helpscreen_frame[i-start]--;
-    }
-    else
-    {
-      frame = 0;
-      helpscreen_frame[i-start] = helpscreen_action[j++]-1;
-    }
+    return;
+  }
 
-    helpscreen_delay[i-start] = helpscreen_action[j++] - 1;
+  if (button_released || button == MB_MENU_INITIALIZE)
+  {
+    if (button != MB_MENU_INITIALIZE)
+      page++;
 
-    if (helpscreen_action[j] == HA_NEXT)
-    {
-      if (!helpscreen_frame[i-start])
-       helpscreen_step[i-start] = 0;
-    }
-    else
+    if (page >= num_pages)
     {
-      if (!helpscreen_frame[i-start])
-       helpscreen_step[i-start]++;
-      while(helpscreen_action[j] != HA_NEXT)
-       j++;
+      FadeSoundsAndMusic();
+
+      info_mode = INFO_MODE_MAIN;
+      DrawInfoScreen();
+
+      return;
     }
-    j++;
 
-    DrawOldGraphicExt(drawto, xstart, ystart+(i-start)*ystep, graphic+frame);
-    i++;
+    DrawInfoScreen_HelpAnim(page * anims_per_page, num_anims, TRUE);
   }
-
-  for(i=2;i<16;i++)
+  else
   {
-    MarkTileDirty(0,i);
-    MarkTileDirty(1,i);
+    if (DelayReached(&info_delay, GAME_FRAME_DELAY))
+      if (page < num_pages)
+       DrawInfoScreen_HelpAnim(page * anims_per_page, num_anims, FALSE);
+
+    PlayMenuSoundIfLoop();
   }
 }
-#endif
 
-void DrawHelpScreenElAction(int start)
+void DrawInfoScreen_Music()
 {
-  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;
+  ClearWindow();
+  DrawHeadline();
+
+  LoadMusicInfo();
 
-  while (helpscreen_action[j] != HA_END)
+  HandleInfoScreen_Music(MB_MENU_INITIALIZE);
+}
+
+void HandleInfoScreen_Music(int button)
+{
+  static struct MusicFileInfo *list = NULL;
+  int ystart = 150, dy = 30;
+  int ybottom = SYSIZE - 20;
+  int button_released = !button;
+
+  if (button == MB_MENU_INITIALIZE)
   {
-    if (i >= start + MAX_HELPSCREEN_ELS || i >= num_helpscreen_els)
-      break;
-    else if (i < start)
+    list = music_file_info;
+
+    if (list == NULL)
     {
-      while (helpscreen_action[j] != HA_NEXT)
-       j++;
+      FadeSoundsAndMusic();
 
-      j++;
-      i++;
+      ClearWindow();
+      DrawHeadline();
 
-      continue;
-    }
+      DrawTextSCentered(100, FONT_TEXT_1, "No music info for this level set.");
 
-    j += 2 * helpscreen_step[i-start];
-    graphic = helpscreen_action[j++];
-    frame_count = helpscreen_action[j++];
-    if (frame_count == -1)
-      frame_count = 1000000;
+      DrawTextSCentered(ybottom, FONT_TEXT_4,
+                       "Press any key or button for info menu");
 
-    if (helpscreen_frame[i-start] == 0)
-    {
-      sync_frame = 0;
-      helpscreen_frame[i-start] = frame_count - 1;
+      return;
     }
-    else
+  }
+  else if (button == MB_MENU_LEAVE)
+  {
+    info_mode = INFO_MODE_MAIN;
+    DrawInfoScreen();
+
+    return;
+  }
+
+  if (button_released || button == MB_MENU_INITIALIZE)
+  {
+    int y = 0;
+
+    if (button != MB_MENU_INITIALIZE)
+      if (list != NULL)
+       list = list->next;
+
+    if (list == NULL)
     {
-      sync_frame = frame_count - helpscreen_frame[i-start];
-      helpscreen_frame[i-start]--;
+      info_mode = INFO_MODE_MAIN;
+      DrawInfoScreen();
+
+      return;
     }
 
-    if (helpscreen_action[j] == HA_NEXT)
+    FadeSoundsAndMusic();
+
+    ClearWindow();
+    DrawHeadline();
+
+    if (list->is_sound)
     {
-      if (!helpscreen_frame[i-start])
-       helpscreen_step[i-start] = 0;
+      int sound = list->music;
+
+      if (sound_info[sound].loop)
+       PlaySoundLoop(sound);
+      else
+       PlaySound(sound);
+
+      DrawTextSCentered(100, FONT_TEXT_1, "The Game Background Sounds:");
     }
     else
     {
-      if (!helpscreen_frame[i-start])
-       helpscreen_step[i-start]++;
-      while(helpscreen_action[j] != HA_NEXT)
-       j++;
+      PlayMusic(list->music);
+
+      DrawTextSCentered(100, FONT_TEXT_1, "The Game Background Music:");
     }
-    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);
+    if (strcmp(list->title, UNKNOWN_NAME) != 0)
+    {
+      if (strcmp(list->title_header, UNKNOWN_NAME) != 0)
+       DrawTextSCentered(ystart + y++ * dy, FONT_TEXT_2, list->title_header);
 
-    DrawGraphicExt(drawto, xstart, ystart + (i-start) * ystep,
-                  graphic, frame);
-#endif
+      DrawTextFCentered(ystart + y++ * dy, FONT_TEXT_3, "\"%s\"", list->title);
+    }
 
-    i++;
-  }
+    if (strcmp(list->artist, UNKNOWN_NAME) != 0)
+    {
+      if (strcmp(list->artist_header, UNKNOWN_NAME) != 0)
+       DrawTextSCentered(ystart + y++ * dy, FONT_TEXT_2, list->artist_header);
+      else
+       DrawTextSCentered(ystart + y++ * dy, FONT_TEXT_2, "by");
 
-#if 1
-  redraw_mask |= REDRAW_FIELD;
-#else
-  for(i=2; i<16; i++)
-  {
-    MarkTileDirty(0, i);
-    MarkTileDirty(1, i);
-  }
-#endif
+      DrawTextFCentered(ystart + y++ * dy, FONT_TEXT_3, "%s", list->artist);
+    }
 
-  FrameCounter++;
-}
+    if (strcmp(list->album, UNKNOWN_NAME) != 0)
+    {
+      if (strcmp(list->album_header, UNKNOWN_NAME) != 0)
+       DrawTextSCentered(ystart + y++ * dy, FONT_TEXT_2, list->album_header);
+      else
+       DrawTextSCentered(ystart + y++ * dy, FONT_TEXT_2, "from the album");
 
-void DrawHelpScreenElText(int start)
-{
-  int i;
-  int xstart = mSX + 56, ystart = mSY + 65 + 2 * 32, ystep = TILEY + 4;
-  int ybottom = SYSIZE - 20;
+      DrawTextFCentered(ystart + y++ * dy, FONT_TEXT_3, "\"%s\"", list->album);
+    }
 
-  SetMainBackgroundImage(IMG_BACKGROUND_INFO);
-  ClearWindow();
-  DrawHeadline();
+    if (strcmp(list->year, UNKNOWN_NAME) != 0)
+    {
+      if (strcmp(list->year_header, UNKNOWN_NAME) != 0)
+       DrawTextSCentered(ystart + y++ * dy, FONT_TEXT_2, list->year_header);
+      else
+       DrawTextSCentered(ystart + y++ * dy, FONT_TEXT_2, "from the year");
 
-  DrawTextFCentered(100, FONT_TEXT_1, "The game elements:");
+      DrawTextFCentered(ystart + y++ * dy, FONT_TEXT_3, "%s", list->year);
+    }
 
-  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], FONT_TEXT_2);
-    DrawText(xstart, ystart + (i - start) * ystep + 16,
-            helpscreen_eltext[i][1], FONT_TEXT_2);
+    DrawTextSCentered(ybottom, FONT_TEXT_4,
+                     "Press any key or button for next page");
   }
 
-  DrawTextFCentered(ybottom, FONT_TEXT_4,
-                   "Press any key or button for next page");
+  if (list != NULL && list->is_sound && sound_info[list->music].loop)
+    PlaySoundLoop(list->music);
 }
 
-void DrawHelpScreenMusicText(int num)
+void DrawInfoScreen_Credits()
 {
   int ystart = 150, ystep = 30;
   int ybottom = SYSIZE - 20;
 
-  FadeSounds();
+  FadeSoundsAndMusic();
+
   ClearWindow();
   DrawHeadline();
 
-  DrawTextFCentered(100, FONT_TEXT_1, "The game background music loops:");
-
-  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, FONT_TEXT_2, "from the album");
-  DrawTextFCentered(ystart + 5 * ystep, FONT_TEXT_3,
-                   "\"%s\"", helpscreen_music[num][2]);
-
-  DrawTextFCentered(ybottom, FONT_TEXT_4,
-                   "Press any key or button for next page");
+  DrawTextSCentered(100, FONT_TEXT_1, "Credits:");
+  DrawTextSCentered(ystart + 0 * ystep, FONT_TEXT_2, "DOS port of the game:");
+  DrawTextSCentered(ystart + 1 * ystep, FONT_TEXT_3, "Guido Schulz");
+  DrawTextSCentered(ystart + 2 * ystep, FONT_TEXT_2, "Additional toons:");
+  DrawTextSCentered(ystart + 3 * ystep, FONT_TEXT_3, "Karl Hörnell");
+  DrawTextSCentered(ystart + 5 * ystep, FONT_TEXT_2,
+                   "...and many thanks to all contributors");
+  DrawTextSCentered(ystart + 6 * ystep, FONT_TEXT_2, "of new levels!");
 
-#if 0
-  PlaySoundLoop(background_loop[num]);
-#endif
+  DrawTextSCentered(ybottom, FONT_TEXT_4,
+                   "Press any key or button for info menu");
 }
 
-void DrawHelpScreenCreditsText()
+void HandleInfoScreen_Credits(int button)
 {
-  int ystart = 150, ystep = 30;
-  int ybottom = SYSIZE - 20;
+  int button_released = !button;
 
-  FadeSounds();
-  ClearWindow();
-  DrawHeadline();
+  if (button == MB_MENU_LEAVE)
+  {
+    info_mode = INFO_MODE_MAIN;
+    DrawInfoScreen();
 
-  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, FONT_TEXT_2, "of new levels!");
+    return;
+  }
+
+  if (button_released)
+  {
+    FadeSoundsAndMusic();
 
-  DrawTextFCentered(ybottom, FONT_TEXT_4,
-                   "Press any key or button for next page");
+    info_mode = INFO_MODE_MAIN;
+    DrawInfoScreen();
+  }
+  else
+  {
+    PlayMenuSoundIfLoop();
+  }
 }
 
-void DrawHelpScreenContactText()
+void DrawInfoScreen_Program()
 {
   int ystart = 150, ystep = 30;
   int ybottom = SYSIZE - 20;
@@ -1015,129 +1131,168 @@ void DrawHelpScreenContactText()
   ClearWindow();
   DrawHeadline();
 
-  DrawTextFCentered(100, FONT_TEXT_1, "Program information:");
+  DrawTextSCentered(100, FONT_TEXT_1, "Program Information:");
 
-  DrawTextFCentered(ystart + 0 * ystep, FONT_TEXT_2,
+  DrawTextSCentered(ystart + 0 * ystep, FONT_TEXT_2,
                    "This game is Freeware!");
-  DrawTextFCentered(ystart + 1 * ystep, FONT_TEXT_2,
+  DrawTextSCentered(ystart + 1 * ystep, FONT_TEXT_2,
                    "If you like it, send e-mail to:");
-  DrawTextFCentered(ystart + 2 * ystep, FONT_TEXT_3,
+  DrawTextSCentered(ystart + 2 * ystep, FONT_TEXT_3,
                    "info@artsoft.org");
-  DrawTextFCentered(ystart + 3 * ystep, FONT_TEXT_2,
+  DrawTextSCentered(ystart + 3 * ystep, FONT_TEXT_2,
                    "or SnailMail to:");
-  DrawTextFCentered(ystart + 4 * ystep + 0, FONT_TEXT_3,
+  DrawTextSCentered(ystart + 4 * ystep + 0, FONT_TEXT_3,
                    "Holger Schemel");
-  DrawTextFCentered(ystart + 4 * ystep + 20, FONT_TEXT_3,
+  DrawTextSCentered(ystart + 4 * ystep + 20, FONT_TEXT_3,
                    "Detmolder Strasse 189");
-  DrawTextFCentered(ystart + 4 * ystep + 40, FONT_TEXT_3,
+  DrawTextSCentered(ystart + 4 * ystep + 40, FONT_TEXT_3,
                    "33604 Bielefeld");
-  DrawTextFCentered(ystart + 4 * ystep + 60, FONT_TEXT_3,
+  DrawTextSCentered(ystart + 4 * ystep + 60, FONT_TEXT_3,
                    "Germany");
 
-  DrawTextFCentered(ystart + 7 * ystep, FONT_TEXT_2,
+  DrawTextSCentered(ystart + 7 * ystep, FONT_TEXT_2,
                    "If you have created new levels,");
-  DrawTextFCentered(ystart + 8 * ystep, FONT_TEXT_2,
+  DrawTextSCentered(ystart + 8 * ystep, FONT_TEXT_2,
                    "send them to me to include them!");
-  DrawTextFCentered(ystart + 9 * ystep, FONT_TEXT_2,
+  DrawTextSCentered(ystart + 9 * ystep, FONT_TEXT_2,
                    ":-)");
 
-  DrawTextFCentered(ybottom, FONT_TEXT_4,
-                   "Press any key or button for main menu");
+  DrawTextSCentered(ybottom, FONT_TEXT_4,
+                   "Press any key or button for info menu");
 }
 
-void DrawHelpScreen()
+void HandleInfoScreen_Program(int button)
 {
-  int i;
+  int button_released = !button;
 
-  UnmapAllGadgets();
-  CloseDoor(DOOR_CLOSE_2);
+  if (button == MB_MENU_LEAVE)
+  {
+    info_mode = INFO_MODE_MAIN;
+    DrawInfoScreen();
 
-  for(i=0;i<MAX_HELPSCREEN_ELS;i++)
-    helpscreen_step[i] = helpscreen_frame[i] = 0;
-  helpscreen_musicpos = 0;
-  helpscreen_state = 0;
+    return;
+  }
 
-  DrawHelpScreenElText(0);
-  DrawHelpScreenElAction(0);
+  if (button_released)
+  {
+    FadeSoundsAndMusic();
 
-  FadeToFront();
-  InitAnimation();
+    info_mode = INFO_MODE_MAIN;
+    DrawInfoScreen();
+  }
+  else
+  {
+    PlayMenuSoundIfLoop();
+  }
+}
 
+void DrawInfoScreen_LevelSet()
+{
+  int ystart = 150;
+  int ybottom = SYSIZE - 20;
+  char *filename = getLevelSetInfoFilename();
 #if 0
-  PlaySoundLoop(SND_BACKGROUND_INFO);
+  int font_nr = FONT_TEXT_2;
 #else
-  PlaySound_Menu_Start(SND_BACKGROUND_INFO);
+  int font_nr = FONT_LEVEL_NUMBER;
 #endif
+  int font_width = getFontWidth(font_nr);
+  int font_height = getFontHeight(font_nr);
+  int pad_x = 32;
+  int pad_y = ystart;
+  int sx = SX + pad_x;
+  int sy = SY + pad_y;
+  int max_chars_per_line = (SXSIZE - 2 * pad_x) / font_width;
+  int max_lines_per_screen = (SYSIZE - pad_y) / font_height - 1;
+
+  ClearWindow();
+  DrawHeadline();
+
+  DrawTextSCentered(100, FONT_TEXT_1, "Level Set Information:");
+
+  DrawTextSCentered(ybottom, FONT_TEXT_4,
+                   "Press any key or button for info menu");
+
+  if (filename != NULL)
+    DrawTextFromFile(sx, sy, filename, font_nr, max_chars_per_line,
+                    max_lines_per_screen);
+  else
+    DrawTextSCentered(ystart, FONT_TEXT_2,
+                     "No information for this level set.");
 }
 
-void HandleHelpScreen(int button)
+void HandleInfoScreen_LevelSet(int button)
 {
-  static unsigned long hs_delay = 0;
-  int num_helpscreen_els_pages =
-    (num_helpscreen_els + MAX_HELPSCREEN_ELS-1) / MAX_HELPSCREEN_ELS;
   int button_released = !button;
-  int i;
 
-  if (button_released)
+  if (button == MB_MENU_LEAVE)
   {
-    if (helpscreen_state < num_helpscreen_els_pages - 1)
-    {
-      for(i=0;i<MAX_HELPSCREEN_ELS;i++)
-       helpscreen_step[i] = helpscreen_frame[i] = 0;
-      helpscreen_state++;
+    info_mode = INFO_MODE_MAIN;
+    DrawInfoScreen();
 
-      FrameCounter = 0;
-      DrawHelpScreenElText(helpscreen_state * MAX_HELPSCREEN_ELS);
-      DrawHelpScreenElAction(helpscreen_state * MAX_HELPSCREEN_ELS);
-    }
-    else if (helpscreen_state <
-            num_helpscreen_els_pages + num_helpscreen_music - 1)
-    {
-      helpscreen_state++;
-      DrawHelpScreenMusicText(helpscreen_state - num_helpscreen_els_pages);
-    }
-    else if (helpscreen_state ==
-            num_helpscreen_els_pages + num_helpscreen_music - 1)
-    {
-      helpscreen_state++;
-      DrawHelpScreenCreditsText();
-    }
-    else if (helpscreen_state ==
-            num_helpscreen_els_pages + num_helpscreen_music)
-    {
-      helpscreen_state++;
-      DrawHelpScreenContactText();
-    }
-    else
-    {
-      FadeSounds();
+    return;
+  }
 
-      game_status = GAME_MODE_MAIN;
-      DrawMainMenu();
-    }
+  if (button_released)
+  {
+    FadeSoundsAndMusic();
+
+    info_mode = INFO_MODE_MAIN;
+    DrawInfoScreen();
   }
   else
   {
-    if (DelayReached(&hs_delay, GAME_FRAME_DELAY))
-    {
-      if (helpscreen_state < num_helpscreen_els_pages)
-       DrawHelpScreenElAction(helpscreen_state * MAX_HELPSCREEN_ELS);
-    }
+    PlayMenuSoundIfLoop();
+  }
+}
 
-    /* !!! workaround for playing "music" that is really a sound loop (and
-       must therefore periodically be reactivated with the current sound
-       engine !!! */
-#if 0
-    PlaySoundLoop(SND_BACKGROUND_INFO);
-#else
-    PlaySound_Menu_Continue(SND_BACKGROUND_INFO);
-#endif
+void DrawInfoScreen()
+{
+  SetMainBackgroundImage(IMG_BACKGROUND_INFO);
+
+  if (info_mode == INFO_MODE_ELEMENTS)
+    DrawInfoScreen_Elements();
+  else if (info_mode == INFO_MODE_MUSIC)
+    DrawInfoScreen_Music();
+  else if (info_mode == INFO_MODE_CREDITS)
+    DrawInfoScreen_Credits();
+  else if (info_mode == INFO_MODE_PROGRAM)
+    DrawInfoScreen_Program();
+  else if (info_mode == INFO_MODE_LEVELSET)
+    DrawInfoScreen_LevelSet();
+  else
+    DrawInfoScreen_Main();
+
+  if (info_mode != INFO_MODE_MUSIC)
+  {
+    PlayMenuSound();
+    PlayMenuMusic();
   }
+}
+
+void HandleInfoScreen(int mx, int my, int dx, int dy, int button)
+{
+  if (info_mode == INFO_MODE_ELEMENTS)
+    HandleInfoScreen_Elements(button);
+  else if (info_mode == INFO_MODE_MUSIC)
+    HandleInfoScreen_Music(button);
+  else if (info_mode == INFO_MODE_CREDITS)
+    HandleInfoScreen_Credits(button);
+  else if (info_mode == INFO_MODE_PROGRAM)
+    HandleInfoScreen_Program(button);
+  else if (info_mode == INFO_MODE_LEVELSET)
+    HandleInfoScreen_LevelSet(button);
+  else
+    HandleInfoScreen_Main(mx, my, dx, dy, button);
 
   DoAnimation();
-  BackToFront();
 }
 
+
+/* ========================================================================= */
+/* type name functions                                                       */
+/* ========================================================================= */
+
 void HandleTypeName(int newxpos, Key key)
 {
   static int xpos = 0, ypos = 2;
@@ -1189,10 +1344,13 @@ void HandleTypeName(int newxpos, Key key)
     SaveSetup();
     game_status = GAME_MODE_MAIN;
   }
-
-  BackToFront();
 }
 
+
+/* ========================================================================= */
+/* tree menu functions                                                       */
+/* ========================================================================= */
+
 static void DrawChooseTree(TreeInfo **ti_ptr)
 {
   UnmapAllGadgets();
@@ -1204,7 +1362,7 @@ static void DrawChooseTree(TreeInfo **ti_ptr)
 
   ClearWindow();
 
-  HandleChooseTree(0,0, 0,0, MB_MENU_INITIALIZE, ti_ptr);
+  HandleChooseTree(0, 0, 0, 0, MB_MENU_INITIALIZE, ti_ptr);
   MapChooseTreeGadgets(*ti_ptr);
 
   FadeToFront();
@@ -1257,7 +1415,7 @@ static void drawChooseTreeList(int first_entry, int num_page_entries,
                 SXSIZE - 32 + menu.scrollbar_xoffset,
                 MAX_MENU_ENTRIES_ON_SCREEN * 32);
 
-  for(i=0; i<num_page_entries; i++)
+  for (i = 0; i < num_page_entries; i++)
   {
     TreeInfo *node, *node_first;
     int entry_pos = first_entry + i;
@@ -1309,7 +1467,7 @@ static void drawChooseTreeInfo(int entry_pos, TreeInfo *ti)
 
   /* let BackToFront() redraw only what is needed */
   redraw_mask = last_redraw_mask | REDRAW_TILES;
-  for (x=0; x<SCR_FIELDX; x++)
+  for (x = 0; x < SCR_FIELDX; x++)
     MarkTileDirty(x, 1);
 }
 
@@ -1476,7 +1634,9 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button,
     return;
   }
 
-  if (x == 0 && y >= 0 && y < num_page_entries)
+  if (IN_VIS_FIELD(x, y) &&
+      mx < screen_gadget[SCREEN_CTRL_ID_SCROLL_VERTICAL]->x &&
+      y >= 0 && y < num_page_entries)
   {
     if (button)
     {
@@ -1535,13 +1695,6 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button,
       }
     }
   }
-
-#if 0
-  if (game_status == GAME_MODE_LEVELS || game_status == GAME_MODE_SETUP)
-    DoAnimation();
-
-  BackToFront();
-#endif
 }
 
 void DrawChooseLevel()
@@ -1549,6 +1702,9 @@ void DrawChooseLevel()
   SetMainBackgroundImage(IMG_BACKGROUND_LEVELS);
 
   DrawChooseTree(&leveldir_current);
+
+  PlayMenuSound();
+  PlayMenuMusic();
 }
 
 void HandleChooseLevel(int mx, int my, int dx, int dy, int button)
@@ -1556,13 +1712,12 @@ void HandleChooseLevel(int mx, int my, int dx, int dy, int button)
   HandleChooseTree(mx, my, dx, dy, button, &leveldir_current);
 
   DoAnimation();
-  BackToFront();
 }
 
 void DrawHallOfFame(int highlight_position)
 {
   UnmapAllGadgets();
-  FadeSounds();
+  FadeSoundsAndMusic();
   CloseDoor(DOOR_CLOSE_2);
 
   if (highlight_position < 0) 
@@ -1571,13 +1726,10 @@ void DrawHallOfFame(int highlight_position)
   FadeToFront();
   InitAnimation();
 
-  HandleHallOfFame(highlight_position,0, 0,0, MB_MENU_INITIALIZE);
+  PlayMenuSound();
+  PlayMenuMusic();
 
-#if 0
-  PlaySound(SND_BACKGROUND_SCORES);
-#else
-  PlaySound_Menu_Start(SND_BACKGROUND_SCORES);
-#endif
+  HandleHallOfFame(highlight_position, 0, 0, 0, MB_MENU_INITIALIZE);
 }
 
 static void drawHallOfFameList(int first_entry, int highlight_position)
@@ -1590,7 +1742,7 @@ static void drawHallOfFameList(int first_entry, int highlight_position)
   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++)
+  for (i = 0; i < NUM_MENU_ENTRIES_ON_SCREEN; i++)
   {
     int entry = first_entry + i;
     boolean active = (entry == highlight_position);
@@ -1662,13 +1814,10 @@ void HandleHallOfFame(int mx, int my, int dx, int dy, int button)
     DrawMainMenu();
   }
 
-#if 1
   if (game_status == GAME_MODE_SCORES)
-    PlaySound_Menu_Continue(SND_BACKGROUND_SCORES);
-#endif
+    PlayMenuSoundIfLoop();
 
   DoAnimation();
-  BackToFront();
 }
 
 
@@ -1785,6 +1934,7 @@ static struct TokenInfo setup_info_main[] =
   { TYPE_EMPTY,                NULL,                   ""                      },
   { TYPE_LEAVE_MENU,   execExitSetup,          "Exit"                  },
   { TYPE_LEAVE_MENU,   execSaveAndExitSetup,   "Save and Exit"         },
+
   { 0,                 NULL,                   NULL                    }
 };
 
@@ -1796,12 +1946,15 @@ static struct TokenInfo setup_info_game[] =
   { TYPE_SWITCH,       &setup.autorecord,      "Auto-Record:"          },
   { TYPE_EMPTY,                NULL,                   ""                      },
   { TYPE_LEAVE_MENU,   execSetupMain,          "Back"                  },
+
   { 0,                 NULL,                   NULL                    }
 };
 
 static struct TokenInfo setup_info_editor[] =
 {
+#if 0
   { TYPE_STRING,       NULL,                   "Offer Special Elements:"},
+#endif
   { TYPE_SWITCH,       &setup.editor.el_boulderdash,   "BoulderDash:"  },
   { TYPE_SWITCH,       &setup.editor.el_emerald_mine,  "Emerald Mine:" },
   { TYPE_SWITCH,       &setup.editor.el_more,          "More:"         },
@@ -1813,8 +1966,10 @@ static struct TokenInfo setup_info_editor[] =
   { TYPE_SWITCH,       &setup.editor.el_custom,        "Custom:"       },
   { TYPE_SWITCH,       &setup.editor.el_custom_more,   "More Custom:"  },
   { TYPE_SWITCH,       &setup.editor.el_headlines,     "Headlines:"    },
+  { TYPE_SWITCH,       &setup.editor.el_user_defined,  "User defined:" },
   { TYPE_EMPTY,                NULL,                   ""                      },
   { TYPE_LEAVE_MENU,   execSetupMain,          "Back"                  },
+
   { 0,                 NULL,                   NULL                    }
 };
 
@@ -1831,6 +1986,7 @@ static struct TokenInfo setup_info_graphics[] =
   { TYPE_SWITCH,       &setup.toons,           "Toons:"                },
   { TYPE_EMPTY,                NULL,                   ""                      },
   { TYPE_LEAVE_MENU,   execSetupMain,          "Back"                  },
+
   { 0,                 NULL,                   NULL                    }
 };
 
@@ -1841,6 +1997,7 @@ static struct TokenInfo setup_info_sound[] =
   { TYPE_SWITCH,       &setup.sound_music,     "Game Music:"           },
   { TYPE_EMPTY,                NULL,                   ""                      },
   { TYPE_LEAVE_MENU,   execSetupMain,          "Back"                  },
+
   { 0,                 NULL,                   NULL                    }
 };
 
@@ -1859,6 +2016,7 @@ static struct TokenInfo setup_info_artwork[] =
   { TYPE_YES_NO,       &setup.override_level_music,    "Music:"        },
   { TYPE_EMPTY,                NULL,                   ""                      },
   { TYPE_LEAVE_MENU,   execSetupMain,          "Back"                  },
+
   { 0,                 NULL,                   NULL                    }
 };
 
@@ -1874,6 +2032,7 @@ static struct TokenInfo setup_info_shortcut[] =
   { TYPE_YES_NO,       &setup.ask_on_escape,   "Ask on Esc:"           },
   { TYPE_EMPTY,                NULL,                   ""                      },
   { TYPE_LEAVE_MENU,   execSetupMain,          "Back"                  },
+
   { 0,                 NULL,                   NULL                    }
 };
 
@@ -2038,7 +2197,7 @@ static void DrawSetupScreen_Generic()
   DrawText(mSX + 16, mSY + 16, title_string, FONT_TITLE_1);
 
   num_setup_info = 0;
-  for(i=0; setup_info[i].type != 0 && i < NUM_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;
@@ -2051,8 +2210,14 @@ static void DrawSetupScreen_Generic()
        (value_ptr == &setup.fullscreen   && !video.fullscreen_available))
       setup_info[i].type |= TYPE_GHOSTED;
 
+#if 0
+    if (setup_info[i].type & TYPE_STRING ||
+       (setup_info[i].type & TYPE_SWITCH && setup_mode == SETUP_MODE_EDITOR))
+      font_nr = FONT_MENU_2;
+#else
     if (setup_info[i].type & TYPE_STRING)
       font_nr = FONT_MENU_2;
+#endif
 
     DrawText(mSX + 32, mSY + ypos * 32, setup_info[i].text, font_nr);
 
@@ -2071,7 +2236,7 @@ static void DrawSetupScreen_Generic()
 
   FadeToFront();
   InitAnimation();
-  HandleSetupScreen_Generic(0,0,0,0,MB_MENU_INITIALIZE);
+  HandleSetupScreen_Generic(0, 0, 0, 0, MB_MENU_INITIALIZE);
 }
 
 void HandleSetupScreen_Generic(int mx, int my, int dx, int dy, int button)
@@ -2085,7 +2250,7 @@ void HandleSetupScreen_Generic(int mx, int my, int dx, int dy, int button)
   {
     /* advance to first valid menu entry */
     while (choice < num_setup_info &&
-          (setup_info[choice].type & TYPE_SKIP_ENTRY))
+          setup_info[choice].type & TYPE_SKIP_ENTRY)
       choice++;
     choice_store[setup_mode] = choice;
 
@@ -2094,7 +2259,7 @@ void HandleSetupScreen_Generic(int mx, int my, int dx, int dy, int button)
   }
   else if (button == MB_MENU_LEAVE)
   {
-    for (y=0; y<num_setup_info; y++)
+    for (y = 0; y < num_setup_info; y++)
     {
       if (setup_info[y].type & TYPE_LEAVE_MENU)
       {
@@ -2119,8 +2284,8 @@ void HandleSetupScreen_Generic(int mx, int my, int dx, int dy, int button)
     {
       int menu_navigation_type = (dx < 0 ? TYPE_LEAVE_MENU : TYPE_ENTER_MENU);
 
-      if ((setup_info[choice].type & menu_navigation_type) ||
-         (setup_info[choice].type & TYPE_BOOLEAN_STYLE))
+      if (setup_info[choice].type & menu_navigation_type ||
+         setup_info[choice].type & TYPE_BOOLEAN_STYLE)
        button = MB_MENU_CHOICE;
     }
     else if (dy)
@@ -2128,12 +2293,12 @@ void HandleSetupScreen_Generic(int mx, int my, int dx, int dy, int button)
 
     /* jump to next non-empty menu entry (up or down) */
     while (y > 0 && y < num_setup_info - 1 &&
-          (setup_info[y].type & TYPE_SKIP_ENTRY))
+          setup_info[y].type & TYPE_SKIP_ENTRY)
       y += dy;
   }
 
-  if (x == 0 && y >= 0 && y < num_setup_info &&
-      (setup_info[y].type & ~TYPE_SKIP_ENTRY))
+  if (IN_VIS_FIELD(x, y) &&
+      y >= 0 && y < num_setup_info && setup_info[y].type & ~TYPE_SKIP_ENTRY)
   {
     if (button)
     {
@@ -2154,8 +2319,8 @@ void HandleSetupScreen_Generic(int mx, int my, int dx, int dy, int button)
       }
       else
       {
-       if ((setup_info[y].type & TYPE_KEYTEXT) &&
-           (setup_info[y + 1].type & TYPE_KEY))
+       if (setup_info[y].type & TYPE_KEYTEXT &&
+           setup_info[y + 1].type & TYPE_KEY)
          y++;
 
        if (setup_info[y].type & TYPE_VALUE)
@@ -2163,13 +2328,6 @@ void HandleSetupScreen_Generic(int mx, int my, int dx, int dy, int button)
       }
     }
   }
-
-#if 0
-  BackToFront();
-
-  if (game_status == GAME_MODE_SETUP)
-    DoAnimation();
-#endif
 }
 
 void DrawSetupScreen_Input()
@@ -2192,11 +2350,11 @@ void DrawSetupScreen_Input()
 
 #if 0
   DeactivateJoystickForCalibration();
-  DrawTextFCentered(SYSIZE - 20, FONT_TEXT_4,
+  DrawTextSCentered(SYSIZE - 20, FONT_TEXT_4,
                    "Joysticks deactivated on this screen");
 #endif
 
-  HandleSetupScreen_Input(0,0, 0,0, MB_MENU_INITIALIZE);
+  HandleSetupScreen_Input(0, 0, 0, 0, MB_MENU_INITIALIZE);
   FadeToFront();
   InitAnimation();
 }
@@ -2284,7 +2442,7 @@ static void drawPlayerSetupInputInfo(int player_nr)
   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++)
+  for (i = 0; i < 6; i++)
   {
     int ypos = 6 + i + (i > 3 ? i-3 : 0);
 
@@ -2312,6 +2470,7 @@ void HandleSetupScreen_Input(int mx, int my, int dx, int dy, int button)
   {
     drawPlayerSetupInputInfo(player_nr);
     drawCursor(choice, FC_RED);
+
     return;
   }
   else if (button == MB_MENU_LEAVE)
@@ -2319,6 +2478,8 @@ void HandleSetupScreen_Input(int mx, int my, int dx, int dy, int button)
     setup_mode = SETUP_MODE_MAIN;
     DrawSetupScreen();
     InitJoysticks();
+
+    return;
   }
 
   if (mx || my)                /* mouse input */
@@ -2341,22 +2502,20 @@ void HandleSetupScreen_Input(int mx, int my, int dx, int dy, int button)
       y = (dy > 0 ? pos_empty2 + 1 : pos_empty1 - 1);
   }
 
-  if (y == 0 && ((x == 0 && !button) || ((x == 10 || x == 12) && button)))
+  if (IN_VIS_FIELD(x, y) &&
+      y == 0 && ((x < 10 && !button) || ((x == 10 || x == 12) && button)))
   {
     static unsigned long delay = 0;
 
     if (!DelayReached(&delay, GADGET_FRAME_DELAY))
-#if 1
       return;
-#else
-      goto out;
-#endif
 
     player_nr = (player_nr + (x == 10 ? -1 : +1) + MAX_PLAYERS) % MAX_PLAYERS;
 
     drawPlayerSetupInputInfo(player_nr);
   }
-  else if (x == 0 && y >= pos_start && y <= pos_end &&
+  else if (IN_VIS_FIELD(x, y) &&
+          y >= pos_start && y <= pos_end &&
           !(y >= pos_empty1 && y <= pos_empty2))
   {
     if (button)
@@ -2413,15 +2572,6 @@ void HandleSetupScreen_Input(int mx, int my, int dx, int dy, int button)
       }
     }
   }
-
-#if 0
-  BackToFront();
-
-  out:
-
-  if (game_status == GAME_MODE_SETUP)
-    DoAnimation();
-#endif
 }
 
 void CustomizeKeyboard(int player_nr)
@@ -2461,7 +2611,7 @@ void CustomizeKeyboard(int player_nr)
   DrawText(mSX + 4*32, mSY + (2+2*step_nr+1)*32,
           getKeyNameFromKey(*customize_step[step_nr].key), FONT_VALUE_OLD);
 
-  while(!finished)
+  while (!finished)
   {
     if (PendingEvent())                /* got event */
     {
@@ -2490,7 +2640,7 @@ void CustomizeKeyboard(int player_nr)
              key = *customize_step[step_nr].key;
 
            /* check if key already used */
-           for (i=0; i<step_nr; i++)
+           for (i = 0; i < step_nr; i++)
              if (*customize_step[i].key == key)
                break;
            if (i < step_nr)
@@ -2577,9 +2727,9 @@ static boolean CalibrateJoystickMain(int player_nr)
 
   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;
@@ -2608,10 +2758,10 @@ static boolean CalibrateJoystickMain(int player_nr)
   DrawGraphic(xpos + last_x, ypos + last_y, IMG_MENU_CALIBRATE_RED, 0);
   BackToFront();
 
-  while(Joystick(player_nr) & JOY_BUTTON);     /* wait for released button */
+  while (Joystick(player_nr) & JOY_BUTTON);    /* wait for released button */
   InitAnimation();
 
-  while(result < 0)
+  while (result < 0)
   {
     if (PendingEvent())                /* got event */
     {
@@ -2743,8 +2893,8 @@ void CalibrateJoystick(int player_nr)
   {
     ClearWindow();
 
-    DrawText(mSX + 16, mSY + 6*32, "  JOYSTICK NOT  ",  FONT_TITLE_1);
-    DrawText(mSX,      mSY + 7*32, "    AVAILABLE    ", FONT_TITLE_1);
+    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 */
   }
@@ -2766,6 +2916,9 @@ void DrawSetupScreen()
     DrawChooseTree(&artwork.mus_current);
   else
     DrawSetupScreen_Generic();
+
+  PlayMenuSound();
+  PlayMenuMusic();
 }
 
 void HandleSetupScreen(int mx, int my, int dx, int dy, int button)
@@ -2782,7 +2935,6 @@ void HandleSetupScreen(int mx, int my, int dx, int dy, int button)
     HandleSetupScreen_Generic(mx, my, dx, dy, button);
 
   DoAnimation();
-  BackToFront();
 }
 
 void HandleGameActions()
@@ -2797,13 +2949,10 @@ void HandleGameActions()
     TapeStop();
 
   GameActions();
-
   BackToFront();
 
-#if 1
   if (tape.auto_play && !tape.playing)
     AutoPlayTape();    /* continue automatically playing next tape */
-#endif
 }
 
 /* ---------- new screen button stuff -------------------------------------- */
@@ -2882,7 +3031,7 @@ static void CreateScreenScrollbuttons()
   unsigned long event_mask;
   int i;
 
-  for (i=0; i<NUM_SCREEN_SCROLLBUTTONS; i++)
+  for (i = 0; i < NUM_SCREEN_SCROLLBUTTONS; i++)
   {
     Bitmap *gd_bitmap_unpressed, *gd_bitmap_pressed;
     int gfx_unpressed, gfx_pressed;
@@ -2937,7 +3086,7 @@ static void CreateScreenScrollbars()
 {
   int i;
 
-  for (i=0; i<NUM_SCREEN_SCROLLBARS; i++)
+  for (i = 0; i < NUM_SCREEN_SCROLLBARS; i++)
   {
     Bitmap *gd_bitmap_unpressed, *gd_bitmap_pressed;
 #if !defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
@@ -3017,7 +3166,7 @@ void CreateScreenGadgets()
 #if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
   int i;
 
-  for (i=0; i < NUM_SCROLLBAR_BITMAPS; i++)
+  for (i = 0; i < NUM_SCROLLBAR_BITMAPS; i++)
   {
     scrollbar_bitmap[i] = CreateBitmap(TILEX, TILEY, DEFAULT_DEPTH);
 
@@ -3049,7 +3198,7 @@ void FreeScreenGadgets()
   int i;
 
 #if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
-  for (i=0; i < NUM_SCROLLBAR_BITMAPS; i++)
+  for (i = 0; i < NUM_SCROLLBAR_BITMAPS; i++)
   {
     /* prevent freeing clip mask and GC twice */
     scrollbar_bitmap[i]->clip_mask = None;
@@ -3059,7 +3208,7 @@ void FreeScreenGadgets()
   }
 #endif
 
-  for (i=0; i<NUM_SCREEN_GADGETS; i++)
+  for (i = 0; i < NUM_SCREEN_GADGETS; i++)
     FreeGadget(screen_gadget[i]);
 }
 
@@ -3071,17 +3220,19 @@ void MapChooseTreeGadgets(TreeInfo *ti)
   if (num_entries <= NUM_MENU_ENTRIES_ON_SCREEN)
     return;
 
-  for (i=0; i<NUM_SCREEN_GADGETS; i++)
+  for (i = 0; i < NUM_SCREEN_GADGETS; i++)
     MapGadget(screen_gadget[i]);
 }
 
+#if 0
 void UnmapChooseTreeGadgets()
 {
   int i;
 
-  for (i=0; i<NUM_SCREEN_GADGETS; i++)
+  for (i = 0; i < NUM_SCREEN_GADGETS; i++)
     UnmapGadget(screen_gadget[i]);
 }
+#endif
 
 static void HandleScreenGadgets(struct GadgetInfo *gi)
 {
index f4b704b462553ec3b090f6639c9a918d8ee524c9..949267f001e0586a8b9e2ffd078ca0648785d53a 100644 (file)
 
 #include "main.h"
 
-/* (randomly chosen) values for HandleChooseTree() */
+/* (arbitrary, but unique) values for HandleChooseTree() */
 #define SCROLL_LINE    (1 * SCR_FIELDY)
 #define SCROLL_PAGE    (2 * SCR_FIELDY)
 
 
-void DrawHeadline(void);
-
 void DrawMainMenu(void);
-void HandleMainMenu(int, int, int, int, int);
-
-void DrawHelpScreenElAction(int);
-void DrawHelpScreenElText(int);
-void DrawHelpScreenMusicText(int);
-void DrawHelpScreenCreditsText(void);
-void DrawHelpScreen(void);
-void HandleHelpScreen(int);
-
-void HandleTypeName(int, Key);
+void DrawHallOfFame(int);
 
-void DrawChooseLevel(void);
+void HandleMainMenu(int, int, int, int, int);
 void HandleChooseLevel(int, int, int, int, int);
-
-void DrawHallOfFame(int);
 void HandleHallOfFame(int, int, int, int, int);
-
-void DrawSetupScreen(void);
+void HandleInfoScreen(int, int, int, int, int);
 void HandleSetupScreen(int, int, int, int, int);
-
+void HandleTypeName(int, Key);
 void HandleGameActions(void);
 
 void CreateScreenGadgets();
 void FreeScreenGadgets();
-void MapChooseTreeGadgets(TreeInfo *);
-void UnmapChooseTreeGadgets();
 
 #endif /* SCREENS_H */
index 3aa2282b2edd6b1c0b5d67139f73b7757511ee15..51dcd8a2e0d85e4b47f12267cba9fef24ae118f2 100644 (file)
@@ -177,7 +177,7 @@ void DrawVideoDisplay(unsigned long state, unsigned long value)
               VY + VIDEO_REC_LABEL_YPOS);
   }
 
-  for(i=0;i<10;i++)
+  for (i = 0; i < 10; i++)
   {
     if (state & (1<<i))
     {
@@ -321,7 +321,7 @@ void TapeErase()
         level.game_version);
 #endif
 
-  for(i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
     tape.player_participates[i] = FALSE;
 }
 
@@ -433,7 +433,7 @@ void TapeRecordAction(byte action[MAX_PLAYERS])
   {
     boolean changed_events = FALSE;
 
-    for(i=0; i<MAX_PLAYERS; i++)
+    for (i = 0; i < MAX_PLAYERS; i++)
       if (tape.pos[tape.counter].action[i] != action[i])
        changed_events = TRUE;
 
@@ -448,7 +448,7 @@ void TapeRecordAction(byte action[MAX_PLAYERS])
 
   if (tape.pos[tape.counter].delay == 0)       /* store new action */
   {
-    for(i=0; i<MAX_PLAYERS; i++)
+    for (i = 0; i < MAX_PLAYERS; i++)
       tape.pos[tape.counter].action[i] = action[i];
 
     tape.pos[tape.counter].delay++;
@@ -571,7 +571,7 @@ byte *TapePlayAction()
     return NULL;
   }
 
-  for(i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
     action[i] = tape.pos[tape.counter].action[i];
 
   tape.delay_played++;
@@ -610,7 +610,7 @@ unsigned int GetTapeLength()
   if (TAPE_IS_EMPTY(tape))
     return(0);
 
-  for(i=0;i<tape.length;i++)
+  for (i = 0; i < tape.length; i++)
     tape_length += tape.pos[i].delay;
 
   return(tape_length * GAME_FRAME_DELAY / 1000);
@@ -687,6 +687,19 @@ void TapeQuickLoad()
   }
 }
 
+void InsertSolutionTape()
+{
+  if (!TAPE_IS_EMPTY(tape))
+    return;
+
+  LoadSolutionTape(level_nr);
+
+  if (TAPE_IS_EMPTY(tape))
+    Request("No solution tape for this level !", REQ_CONFIRM);
+
+  DrawCompleteVideoDisplay();
+}
+
 
 /* ------------------------------------------------------------------------- *
  * tape autoplay functions
@@ -747,7 +760,7 @@ void AutoPlayTape()
     printf_line("=", 79);
     printf("\n");
 
-    for (i=0; i<MAX_NUM_AUTOPLAY_LEVELS; i++)
+    for (i = 0; i < MAX_NUM_AUTOPLAY_LEVELS; i++)
       levels_failed[i] = FALSE;
 
     autoplay_initialized = TRUE;
@@ -768,7 +781,7 @@ void AutoPlayTape()
       continue;
     }
 
-    LoadTape(level_nr);
+    LoadSolutionTape(level_nr);
     if (TAPE_IS_EMPTY(tape))
     {
       printf("(no tape)\n");
@@ -796,7 +809,7 @@ void AutoPlayTape()
   if (num_levels_played != num_levels_solved)
   {
     printf(", FAILED:");
-    for (i=0; i<MAX_NUM_AUTOPLAY_LEVELS; i++)
+    for (i = 0; i < MAX_NUM_AUTOPLAY_LEVELS; i++)
       if (levels_failed[i])
        printf(" %03d", i);
   }
@@ -865,7 +878,7 @@ void CreateTapeButtons()
 {
   int i;
 
-  for (i=0; i<NUM_TAPE_BUTTONS; i++)
+  for (i = 0; i < NUM_TAPE_BUTTONS; i++)
   {
     Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
     struct GadgetInfo *gi;
@@ -910,7 +923,7 @@ void FreeTapeButtons()
 {
   int i;
 
-  for (i=0; i<NUM_TAPE_BUTTONS; i++)
+  for (i = 0; i < NUM_TAPE_BUTTONS; i++)
     FreeGadget(tape_gadget[i]);
 }
 
@@ -930,7 +943,7 @@ void MapTapeButtons()
 {
   int i;
 
-  for (i=0; i<NUM_TAPE_BUTTONS; i++)
+  for (i = 0; i < NUM_TAPE_BUTTONS; i++)
     if (i != TAPE_CTRL_ID_INDEX)
       MapGadget(tape_gadget[i]);
 
@@ -942,7 +955,7 @@ void UnmapTapeButtons()
 {
   int i;
 
-  for (i=0; i<NUM_TAPE_BUTTONS; i++)
+  for (i = 0; i < NUM_TAPE_BUTTONS; i++)
     UnmapGadget(tape_gadget[i]);
 }
 
index f32ad694c634c359ff1b0471a4969129b121b6a7..03cc3d24812d87fd7037deffb81c5b5d4e7b9b42 100644 (file)
@@ -99,6 +99,7 @@ void TapeErase(void);
 unsigned int GetTapeLength(void);
 void TapeQuickSave(void);
 void TapeQuickLoad(void);
+void InsertSolutionTape(void);
 
 void AutoPlayTape(void);
 
index fbb3079302ec7e5a67aa8b7986827f3596112b00..6b8ae64696af23dee2a8be92a643ba4a6bae91e0 100644 (file)
@@ -91,8 +91,8 @@ void RedrawPlayfield(boolean force_redraw, int x, int y, int width, int height)
       if (setup.direct_draw)
        SetDrawtoField(DRAW_BACKBUFFER);
 
-      for(xx=BX1; xx<=BX2; xx++)
-       for(yy=BY1; yy<=BY2; yy++)
+      for (xx = BX1; xx <= BX2; xx++)
+       for (yy = BY1; yy <= BY2; yy++)
          if (xx >= x1 && xx <= x2 && yy >= y1 && yy <= y2)
            DrawScreenField(xx, yy);
       DrawAllPlayers();
@@ -263,8 +263,8 @@ void BackToFront()
 
   if (redraw_mask & REDRAW_TILES)
   {
-    for(x=0; x<SCR_FIELDX; x++)
-      for(y=0; y<SCR_FIELDY; y++)
+    for (x = 0; x < SCR_FIELDX; x++)
+      for (y =0 ; y < SCR_FIELDY; y++)
        if (redraw[redraw_x1 + x][redraw_y1 + y])
          BlitBitmap(buffer, window,
                     FX + x * TILEX, FX + y * TILEY, TILEX, TILEY,
@@ -286,8 +286,8 @@ void BackToFront()
 
   FlushDisplay();
 
-  for(x=0; x<MAX_BUF_XSIZE; x++)
-    for(y=0; y<MAX_BUF_YSIZE; y++)
+  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_NONE;
@@ -308,9 +308,9 @@ void FadeToFront()
     ClearRectangle(window, REAL_SX,REAL_SY,FULL_SXSIZE,FULL_SYSIZE);
     FlushDisplay();
 
-    for(i=0;i<2*FULL_SYSIZE;i++)
+    for (i = 0; i < 2 * FULL_SYSIZE; i++)
     {
-      for(y=0;y<FULL_SYSIZE;y++)
+      for (y = 0; y < FULL_SYSIZE; y++)
       {
        BlitBitmap(backbuffer, window,
                   REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
@@ -321,7 +321,7 @@ void FadeToFront()
 #endif
 
 #if 0
-    for(i=1;i<FULL_SYSIZE;i+=2)
+    for (i = 1; i < FULL_SYSIZE; i+=2)
       BlitBitmap(backbuffer, window,
                 REAL_SX,REAL_SY+i, FULL_SXSIZE,1, REAL_SX,REAL_SY+i);
     FlushDisplay();
@@ -424,9 +424,9 @@ void SetBorderElement()
 
   BorderElement = EL_EMPTY;
 
-  for(y=0; y<lev_fieldy && BorderElement == EL_EMPTY; y++)
+  for (y = 0; y < lev_fieldy && BorderElement == EL_EMPTY; y++)
   {
-    for(x=0; x<lev_fieldx; x++)
+    for (x = 0; x < lev_fieldx; x++)
     {
       if (!IS_INDESTRUCTIBLE(Feld[x][y]))
        BorderElement = EL_STEELWALL;
@@ -553,11 +553,24 @@ static int getPlayerGraphic(struct PlayerInfo *player, int move_dir)
     return el_act_dir2img(player->element_nr, player->GfxAction, move_dir);
 }
 
+static boolean equalGraphics(int graphic1, int graphic2)
+{
+  struct GraphicInfo *g1 = &graphic_info[graphic1];
+  struct GraphicInfo *g2 = &graphic_info[graphic2];
+
+  return (g1->bitmap      == g2->bitmap &&
+         g1->src_x       == g2->src_x &&
+         g1->src_y       == g2->src_y &&
+         g1->anim_frames == g2->anim_frames &&
+         g1->anim_delay  == g2->anim_delay &&
+         g1->anim_mode   == g2->anim_mode);
+}
+
 void DrawAllPlayers()
 {
   int i;
 
-  for(i=0; i<MAX_PLAYERS; i++)
+  for (i = 0; i < MAX_PLAYERS; i++)
     if (stored_player[i].active)
       DrawPlayer(&stored_player[i]);
 }
@@ -615,15 +628,12 @@ void DrawPlayer(struct PlayerInfo *player)
   if (element == EL_EXPLOSION)
     return;
 
-  action = (player->is_pushing    ? ACTION_PUSHING    :
-           player->is_digging    ? ACTION_DIGGING    :
-           player->is_collecting ? ACTION_COLLECTING :
-           player->is_moving     ? ACTION_MOVING     :
-           player->is_snapping   ? ACTION_SNAPPING   : ACTION_DEFAULT);
-
-#if 0
-  printf("::: '%s'\n", element_action_info[action].suffix);
-#endif
+  action = (player->is_pushing    ? ACTION_PUSHING         :
+           player->is_digging    ? ACTION_DIGGING         :
+           player->is_collecting ? ACTION_COLLECTING      :
+           player->is_moving     ? ACTION_MOVING          :
+           player->is_snapping   ? ACTION_SNAPPING        :
+           player->is_waiting    ? player->action_waiting : ACTION_DEFAULT);
 
   InitPlayerGfxAnimation(player, action, move_dir);
 
@@ -704,8 +714,7 @@ void DrawPlayer(struct PlayerInfo *player)
 
   /* in the case of changed player action or direction, prevent the current
      animation frame from being restarted for identical animations */
-  if (player->Frame == 0 &&
-      graphic_info[graphic].bitmap == graphic_info[last_player_graphic].bitmap)
+  if (player->Frame == 0 && equalGraphics(graphic, last_player_graphic))
     player->Frame = last_player_frame;
 
 #else
@@ -1222,7 +1231,7 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame)
 
     getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
 
-    for(i=0; i<4; i++)
+    for (i = 0; i < 4; i++)
     {
       int xx = x + xy[i][0];
       int yy = y + xy[i][1];
@@ -1267,7 +1276,7 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame)
     getGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
 #endif
 
-    for(i=0; i<4; i++)
+    for (i = 0; i < 4; i++)
     {
       int xx = x + xy[i][0];
       int yy = y + xy[i][1];
@@ -1356,7 +1365,7 @@ void DrawLevelFieldCrumbledSandNeighbours(int x, int y)
   };
   int i;
 
-  for(i=0; i<4; i++)
+  for (i = 0; i < 4; i++)
   {
     int xx = x + xy[i][0];
     int yy = y + xy[i][1];
@@ -1604,7 +1613,7 @@ void AnimateEnvelope(int envelope_nr, int anim_mode, int action)
   int ystep = (ystart < yend || xstep == 0 ? 1 : 0);
   int x, y;
 
-  for (x=xstart, y=ystart; x <= xend && y <= yend; x += xstep, y += ystep)
+  for (x = xstart, y = ystart; x <= xend && y <= yend; x += xstep, y += ystep)
   {
     int xsize = (action == ACTION_CLOSING ? xend - (x - xstart) : x) + 2;
     int ysize = (action == ACTION_CLOSING ? yend - (y - ystart) : y) + 2;
@@ -1618,7 +1627,7 @@ void AnimateEnvelope(int envelope_nr, int anim_mode, int action)
 
     SetDrawtoField(DRAW_BACKBUFFER);
 
-    for (yy=0; yy < ysize; yy++) for (xx=0; xx < xsize; xx++)
+    for (yy = 0; yy < ysize; yy++) for (xx = 0; xx < xsize; xx++)
       DrawEnvelopeBackground(envelope_nr, sx,sy, xx,yy, xsize, ysize, font_nr);
 
     DrawTextToTextArea(SX + sx + font_width, SY + sy + font_height,
@@ -1705,8 +1714,8 @@ void DrawLevel()
   SetDrawBackgroundMask(REDRAW_NONE);
   ClearWindow();
 
-  for(x=BX1; x<=BX2; x++)
-    for(y=BY1; y<=BY2; y++)
+  for (x = BX1; x <= BX2; x++)
+    for (y = BY1; y <= BY2; y++)
       DrawScreenField(x, y);
 
   redraw_mask |= REDRAW_FIELD;
@@ -1716,8 +1725,8 @@ void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y)
 {
   int x,y;
 
-  for(x=0; x<size_x; x++)
-    for(y=0; y<size_y; y++)
+  for (x = 0; x < size_x; x++)
+    for (y = 0; y < size_y; y++)
       DrawMiniElementOrWall(x, y, scroll_x, scroll_y);
 
   redraw_mask |= REDRAW_FIELD;
@@ -1737,9 +1746,9 @@ static void DrawMicroLevelExt(int xpos, int ypos, int from_x, int from_y)
   xpos += MICRO_TILEX;
   ypos += MICRO_TILEY;
 
-  for(x=-1; x<=STD_LEV_FIELDX; x++)
+  for (x = -1; x <= STD_LEV_FIELDX; x++)
   {
-    for(y=-1; y<=STD_LEV_FIELDY; y++)
+    for (y = -1; y <= STD_LEV_FIELDY; y++)
     {
       int lx = from_x + x, ly = from_y + y;
 
@@ -1951,13 +1960,31 @@ void WaitForEventToContinue()
 }
 
 #define MAX_REQUEST_LINES              13
-#define MAX_REQUEST_LINE_LEN           7
+#define MAX_REQUEST_LINE_FONT1_LEN     7
+#define MAX_REQUEST_LINE_FONT2_LEN     10
 
 boolean Request(char *text, unsigned int req_state)
 {
   int mx, my, ty, result = -1;
   unsigned int old_door_state;
   int last_game_status = game_status;  /* save current game status */
+  int max_request_line_len = MAX_REQUEST_LINE_FONT1_LEN;
+  int font_nr = FONT_TEXT_2;
+  int max_word_len = 0;
+  char *text_ptr;
+
+  for (text_ptr = text; *text_ptr; text_ptr++)
+  {
+    max_word_len = (*text_ptr != ' ' ? max_word_len + 1 : 0);
+
+    if (max_word_len > MAX_REQUEST_LINE_FONT1_LEN)
+    {
+      max_request_line_len = MAX_REQUEST_LINE_FONT2_LEN;
+      font_nr = FONT_LEVEL_NUMBER;
+
+      break;
+    }
+  }
 
 #if 1
   SetMouseCursor(CURSOR_DEFAULT);
@@ -1995,15 +2022,15 @@ boolean Request(char *text, unsigned int req_state)
   game_status = GAME_MODE_PSEUDO_DOOR;
 
   /* write text for request */
-  for(ty=0; ty < MAX_REQUEST_LINES; ty++)
+  for (ty = 0; ty < MAX_REQUEST_LINES; ty++)
   {
-    char text_line[MAX_REQUEST_LINE_LEN + 1];
-    int tx, tl, tc;
+    char text_line[max_request_line_len + 1];
+    int tx, tl, tc = 0;
 
     if (!*text)
       break;
 
-    for(tl=0,tx=0; tx < MAX_REQUEST_LINE_LEN; tl++,tx++)
+    for (tl = 0, tx = 0; tx < max_request_line_len; tl++, tx++)
     {
       tc = *(text + tx);
       if (!tc || tc == ' ')
@@ -2020,9 +2047,9 @@ boolean Request(char *text, unsigned int req_state)
     strncpy(text_line, text, tl);
     text_line[tl] = 0;
 
-    DrawText(DX + (DXSIZE - tl * getFontWidth(FONT_TEXT_2)) / 2,
-            DY + 8 + ty * (getFontHeight(FONT_TEXT_2) + 2),
-            text_line, FONT_TEXT_2);
+    DrawText(DX + (DXSIZE - tl * getFontWidth(font_nr)) / 2,
+            DY + 8 + ty * (getFontHeight(font_nr) + 2),
+            text_line, font_nr);
 
     text += tl + (tc == ' ' ? 1 : 0);
   }
@@ -2077,7 +2104,7 @@ boolean Request(char *text, unsigned int req_state)
   SetMouseCursor(CURSOR_DEFAULT);
 #endif
 
-  while(result < 0)
+  while (result < 0)
   {
     if (PendingEvent())
     {
@@ -2332,7 +2359,7 @@ unsigned int MoveDoor(unsigned int door_state)
        PlaySoundStereo(SND_DOOR_CLOSING, SOUND_MIDDLE);
     }
 
-    for(x = start; x <= end && !(door_1_done && door_2_done); x += stepsize)
+    for (x = start; x <= end && !(door_1_done && door_2_done); x += stepsize)
     {
       Bitmap *bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
       GC gc = bitmap->stored_clip_gc;
@@ -2649,7 +2676,7 @@ void CreateToolButtons()
 {
   int i;
 
-  for (i=0; i<NUM_TOOL_BUTTONS; i++)
+  for (i = 0; i < NUM_TOOL_BUTTONS; i++)
   {
     Bitmap *gd_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
     Bitmap *deco_bitmap = None;
@@ -2707,7 +2734,7 @@ void FreeToolButtons()
 {
   int i;
 
-  for (i=0; i<NUM_TOOL_BUTTONS; i++)
+  for (i = 0; i < NUM_TOOL_BUTTONS; i++)
     FreeGadget(tool_gadget[i]);
 }
 
@@ -2715,7 +2742,7 @@ static void UnmapToolButtons()
 {
   int i;
 
-  for (i=0; i<NUM_TOOL_BUTTONS; i++)
+  for (i = 0; i < NUM_TOOL_BUTTONS; i++)
     UnmapGadget(tool_gadget[i]);
 }