rnd-20060225-1-src
[rocksndiamonds.git] / src / main.h
index e4b4f0d85f3207930b485ba2bea509aa0ca75c15..ffde34c3fadf17fa1f714f3713f63d5248b64b26 100644 (file)
@@ -50,8 +50,8 @@
 #define MIN_LEV_FIELDY                 3
 #define STD_LEV_FIELDX                 64
 #define STD_LEV_FIELDY                 32
-#define MAX_LEV_FIELDX                 128
-#define MAX_LEV_FIELDY                 128
+#define MAX_LEV_FIELDX                 MAX_PLAYFIELD_WIDTH
+#define MAX_LEV_FIELDY                 MAX_PLAYFIELD_HEIGHT
 
 #define SCREENX(a)                     ((a) - scroll_x)
 #define SCREENY(a)                     ((a) - scroll_y)
 #define EP_KEYGATE                     49
 #define EP_AMOEBOID                    50
 #define EP_AMOEBALIVE                  51
-#define EP_HAS_CONTENT                 52
+#define EP_HAS_EDITOR_CONTENT          52
 #define EP_CAN_TURN_EACH_MOVE          53
 #define EP_CAN_GROW                    54
 #define EP_ACTIVE_BOMB                 55
 #define EP_CAN_EXPLODE_BY_EXPLOSION    78
 #define EP_COULD_MOVE_INTO_ACID                79
 #define EP_MAYBE_DONT_COLLIDE_WITH     80
+#define EP_CAN_BE_CLONED_BY_ANDROID    81
 
 /* values for internal purpose only (level editor) */
-#define EP_WALK_TO_OBJECT              81
-#define EP_DEADLY                      82
+#define EP_WALK_TO_OBJECT              82
+#define EP_DEADLY                      83
+#define EP_EDITOR_CASCADE              84
+#define EP_EDITOR_CASCADE_ACTIVE       85
+#define EP_EDITOR_CASCADE_INACTIVE     86
 
 /* values for internal purpose only (game engine) */
-#define EP_HAS_ACTION                  83
-#define EP_CAN_CHANGE_OR_HAS_ACTION    84
+#define EP_HAS_ACTION                  87
+#define EP_CAN_CHANGE_OR_HAS_ACTION    88
 
-#define NUM_ELEMENT_PROPERTIES         85
+#define NUM_ELEMENT_PROPERTIES         89
 
 #define NUM_EP_BITFIELDS               ((NUM_ELEMENT_PROPERTIES + 31) / 32)
 #define EP_BITFIELD_BASE               0
 #define EP_BITMASK_DEFAULT             0
 
 #define PROPERTY_BIT(p)                        (1 << ((p) % 32))
+#if 1
+#define PROPERTY_VAR(e,p)              (element_info[e].properties[(p) / 32])
+#else
 #define PROPERTY_VAR(e,p)              (Properties[e][(p) / 32])
+#endif
 #define HAS_PROPERTY(e,p)      ((PROPERTY_VAR(e, p) & PROPERTY_BIT(p)) != 0)
 #define SET_PROPERTY(e,p,v)    ((v) ?                                     \
                                 (PROPERTY_VAR(e,p) |=  PROPERTY_BIT(p)) : \
 #define CE_HITTING_X                   28
 #define CE_HIT_BY_X                    29
 #define CE_BLOCKED                     30
+#define CE_SWITCHED_BY_PLAYER          31
+#define CE_PLAYER_SWITCHES_X           32
+#define CE_SNAPPED_BY_PLAYER           33
+#define CE_PLAYER_SNAPS_X              34
+#define CE_MOVE_OF_X                   35
+#define CE_DIGGING_X                   36
+#define CE_CREATION_OF_X               37
 
-#define NUM_CHANGE_EVENTS              31
+#define NUM_CHANGE_EVENTS              38
 
 #define CE_BITMASK_DEFAULT             0
 
                                         PLAYER_BITS_4)
 #define PLAYER_BITS_TRIGGER            (1 << 4)
 
+/* values for move directions (bits 0 - 3: basic move directions) */
+#define MV_BIT_PREVIOUS                        4
+#define MV_BIT_TRIGGER                 5
+#define MV_BIT_TRIGGER_BACK            6
+#define MV_BIT_NORMAL                  MV_BIT_TRIGGER
+#define MV_BIT_REVERSE                 MV_BIT_TRIGGER_BACK
+
+#define MV_PREVIOUS                    (1 << MV_BIT_PREVIOUS)
+#define MV_TRIGGER                     (1 << MV_BIT_TRIGGER)
+#define MV_TRIGGER_BACK                        (1 << MV_BIT_TRIGGER_BACK)
+#define MV_NORMAL                      (1 << MV_BIT_NORMAL)
+#define MV_REVERSE                     (1 << MV_BIT_REVERSE)
+
+/* values for move stepsize */
+#define STEPSIZE_NOT_MOVING            0
+#define STEPSIZE_VERY_SLOW             1
+#define STEPSIZE_SLOW                  2
+#define STEPSIZE_NORMAL                        4
+#define STEPSIZE_FAST                  8
+#define STEPSIZE_VERY_FAST             16
+#define STEPSIZE_EVEN_FASTER           32
+#define STEPSIZE_SLOWER                        50      /* (symbolic value only) */
+#define STEPSIZE_FASTER                        200     /* (symbolic value only) */
+#define STEPSIZE_RESET                 100     /* (symbolic value only) */
+
 /* values for change side for custom elements */
 #define CH_SIDE_NONE                   MV_NONE
 #define CH_SIDE_LEFT                   MV_LEFT
 #define CA_NO_ACTION                   0
 #define CA_EXIT_PLAYER                 1
 #define CA_KILL_PLAYER                 2
-#define CA_RESTART_LEVEL               3
-#define CA_SHOW_ENVELOPE               4
-#define CA_ADD_KEY                     5
-#define CA_REMOVE_KEY                  6
-#define CA_SET_PLAYER_SPEED            7
-#define CA_SET_PLAYER_GRAVITY          8
-#define CA_SET_WIND_DIRECTION          9
-#define CA_SET_LEVEL_GEMS              10
-#define CA_SET_LEVEL_TIME              11
-#define CA_SET_LEVEL_SCORE             12
-#define CA_SET_CE_SCORE                        13
-#define CA_SET_CE_VALUE                        14
-#if 0
-#define CA_SET_DYNABOMB_NUMBER         15
-#define CA_SET_DYNABOMB_SIZE           16
-#define CA_SET_DYNABOMB_POWER          17
-#endif
+#define CA_MOVE_PLAYER                 3
+#define CA_RESTART_LEVEL               4
+#define CA_SHOW_ENVELOPE               5
+#define CA_SET_LEVEL_TIME              6
+#define CA_SET_LEVEL_GEMS              7
+#define CA_SET_LEVEL_SCORE             8
+#define CA_SET_LEVEL_WIND              9
+#define CA_SET_LEVEL_GRAVITY           10
+#define CA_SET_PLAYER_KEYS             11
+#define CA_SET_PLAYER_SPEED            12
+#define CA_SET_PLAYER_SHIELD           13
+#define CA_SET_PLAYER_ARTWORK          14
+#define CA_SET_CE_SCORE                        15
+#define CA_SET_CE_VALUE                        16
+#define CA_SET_ENGINE_SCAN_MODE                17
+
+#define CA_HEADLINE_LEVEL_ACTIONS      250
+#define CA_HEADLINE_PLAYER_ACTIONS     251
+#define CA_HEADLINE_CE_ACTIONS         252
+#define CA_HEADLINE_ENGINE_ACTIONS     253
+#define CA_UNDEFINED                   255
 
 /* values for change action mode for custom elements */
 #define CA_MODE_UNDEFINED              0
 #define CA_ARG_NUMBER_CE_SCORE         (CA_ARG_NUMBER + 3)
 #define CA_ARG_NUMBER_CE_VALUE         (CA_ARG_NUMBER + 4)
 #define CA_ARG_NUMBER_CE_DELAY         (CA_ARG_NUMBER + 5)
+#define CA_ARG_NUMBER_LEVEL_TIME       (CA_ARG_NUMBER + 6)
+#define CA_ARG_NUMBER_LEVEL_GEMS       (CA_ARG_NUMBER + 7)
+#define CA_ARG_NUMBER_LEVEL_SCORE      (CA_ARG_NUMBER + 8)
 #define CA_ARG_NUMBER_HEADLINE         (CA_ARG_NUMBER + 999)
 #define CA_ARG_ELEMENT                 12000
-#define CA_ARG_ELEMENT_TARGET          (CA_ARG_ELEMENT + 0)
-#define CA_ARG_ELEMENT_TRIGGER         (CA_ARG_ELEMENT + 1)
-#define CA_ARG_ELEMENT_HEADLINE                (CA_ARG_ELEMENT + 999)
+#define CA_ARG_ELEMENT_RESET           (CA_ARG_ELEMENT + 0)
+#define CA_ARG_ELEMENT_TARGET          (CA_ARG_ELEMENT + 1)
+#define CA_ARG_ELEMENT_TRIGGER         (CA_ARG_ELEMENT + 2)
+#define CA_ARG_ELEMENT_HEADLINE                (CA_ARG_ELEMENT + 998)
+#define CA_ARG_ELEMENT_CV_TARGET       (CA_ARG_ELEMENT_TARGET)
+#define CA_ARG_ELEMENT_CV_TRIGGER      (CA_ARG_ELEMENT_TRIGGER)
+#define CA_ARG_ELEMENT_CV_HEADLINE     (CA_ARG_ELEMENT_HEADLINE)
+#define CA_ARG_ELEMENT_NR_TARGET       (CA_ARG_ELEMENT + 3)
+#define CA_ARG_ELEMENT_NR_TRIGGER      (CA_ARG_ELEMENT + 4)
+#define CA_ARG_ELEMENT_NR_HEADLINE     (CA_ARG_ELEMENT + 999)
 #define CA_ARG_SPEED                   13000
-#define CA_ARG_SPEED_VERY_SLOW         (CA_ARG_SPEED + 1)
-#define CA_ARG_SPEED_SLOW              (CA_ARG_SPEED + 2)
-#define CA_ARG_SPEED_NORMAL            (CA_ARG_SPEED + 4)
-#define CA_ARG_SPEED_FAST              (CA_ARG_SPEED + 8)
-#define CA_ARG_SPEED_VERY_FAST         (CA_ARG_SPEED + 16)
-#define CA_ARG_SPEED_EVEN_FASTER       (CA_ARG_SPEED + 32)
-#define CA_ARG_SPEED_SLOWER            (CA_ARG_SPEED + 50)
-#define CA_ARG_SPEED_FASTER            (CA_ARG_SPEED + 200)
-#define CA_ARG_SPEED_RESET             (CA_ARG_SPEED + 0)
+#define CA_ARG_SPEED_NOT_MOVING                (CA_ARG_SPEED + STEPSIZE_NOT_MOVING)
+#define CA_ARG_SPEED_VERY_SLOW         (CA_ARG_SPEED + STEPSIZE_VERY_SLOW)
+#define CA_ARG_SPEED_SLOW              (CA_ARG_SPEED + STEPSIZE_SLOW)
+#define CA_ARG_SPEED_NORMAL            (CA_ARG_SPEED + STEPSIZE_NORMAL)
+#define CA_ARG_SPEED_FAST              (CA_ARG_SPEED + STEPSIZE_FAST)
+#define CA_ARG_SPEED_VERY_FAST         (CA_ARG_SPEED + STEPSIZE_VERY_FAST)
+#define CA_ARG_SPEED_EVEN_FASTER       (CA_ARG_SPEED + STEPSIZE_EVEN_FASTER)
+#define CA_ARG_SPEED_SLOWER            (CA_ARG_SPEED + STEPSIZE_SLOWER)
+#define CA_ARG_SPEED_FASTER            (CA_ARG_SPEED + STEPSIZE_FASTER)
+#define CA_ARG_SPEED_RESET             (CA_ARG_SPEED + STEPSIZE_RESET)
 #define CA_ARG_SPEED_HEADLINE          (CA_ARG_SPEED + 999)
 #define CA_ARG_GRAVITY                 14000
 #define CA_ARG_GRAVITY_OFF             (CA_ARG_GRAVITY + 0)
 #define CA_ARG_DIRECTION_RIGHT         (CA_ARG_DIRECTION + MV_RIGHT)
 #define CA_ARG_DIRECTION_UP            (CA_ARG_DIRECTION + MV_UP)
 #define CA_ARG_DIRECTION_DOWN          (CA_ARG_DIRECTION + MV_DOWN)
-#define CA_ARG_DIRECTION_TRIGGER       (CA_ARG_DIRECTION + MV_ANY_DIRECTION)
+#define CA_ARG_DIRECTION_TRIGGER       (CA_ARG_DIRECTION + MV_TRIGGER)
+#define CA_ARG_DIRECTION_TRIGGER_BACK  (CA_ARG_DIRECTION + MV_TRIGGER_BACK)
 #define CA_ARG_DIRECTION_HEADLINE      (CA_ARG_DIRECTION + 999)
-#define CA_ARG_UNDEFINED               19999
+#define CA_ARG_SHIELD                  16000
+#define CA_ARG_SHIELD_OFF              (CA_ARG_SHIELD + 0)
+#define CA_ARG_SHIELD_NORMAL           (CA_ARG_SHIELD + 1)
+#define CA_ARG_SHIELD_DEADLY           (CA_ARG_SHIELD + 2)
+#define CA_ARG_SHIELD_HEADLINE         (CA_ARG_SHIELD + 999)
+#define CA_ARG_SCAN_MODE               17000
+#define CA_ARG_SCAN_MODE_NORMAL                (CA_ARG_SCAN_MODE + MV_NORMAL)
+#define CA_ARG_SCAN_MODE_REVERSE       (CA_ARG_SCAN_MODE + MV_REVERSE)
+#define CA_ARG_SCAN_MODE_HEADLINE      (CA_ARG_SCAN_MODE + 999)
+#define CA_ARG_UNDEFINED               65535
 
 /* values for custom move patterns (bits 0 - 3: basic move directions) */
 #define MV_BIT_TOWARDS_PLAYER          4
 #define MV_TURNING_RANDOM              (1 << MV_BIT_TURNING_RANDOM)
 #define MV_WIND_DIRECTION              (1 << MV_BIT_WIND_DIRECTION)
 
-/* values for initial move direction (bits 0 - 3: basic move directions) */
-#define MV_START_BIT_PREVIOUS          4
-
 /* values for initial move direction */
 #define MV_START_NONE                  (MV_NONE)
 #define MV_START_AUTOMATIC             (MV_NONE)
 #define MV_START_UP                    (MV_UP)
 #define MV_START_DOWN                  (MV_DOWN)
 #define MV_START_RANDOM                        (MV_ALL_DIRECTIONS)
-#define MV_START_PREVIOUS              (1 << MV_START_BIT_PREVIOUS)
+#define MV_START_PREVIOUS              (MV_PREVIOUS)
 
 /* values for elements left behind by custom elements */
 #define LEAVE_TYPE_UNLIMITED           0
 #define IS_KEYGATE(e)          HAS_PROPERTY(e, EP_KEYGATE)
 #define IS_AMOEBOID(e)         HAS_PROPERTY(e, EP_AMOEBOID)
 #define IS_AMOEBALIVE(e)       HAS_PROPERTY(e, EP_AMOEBALIVE)
-#define HAS_CONTENT(e)         HAS_PROPERTY(e, EP_HAS_CONTENT)
+#define HAS_EDITOR_CONTENT(e)  HAS_PROPERTY(e, EP_HAS_EDITOR_CONTENT)
 #define CAN_TURN_EACH_MOVE(e)  HAS_PROPERTY(e, EP_CAN_TURN_EACH_MOVE)
 #define CAN_GROW(e)            HAS_PROPERTY(e, EP_CAN_GROW)
 #define IS_ACTIVE_BOMB(e)      HAS_PROPERTY(e, EP_ACTIVE_BOMB)
                                HAS_PROPERTY(e, EP_CAN_EXPLODE_BY_EXPLOSION)
 #define COULD_MOVE_INTO_ACID(e)        HAS_PROPERTY(e, EP_COULD_MOVE_INTO_ACID)
 #define MAYBE_DONT_COLLIDE_WITH(e) HAS_PROPERTY(e, EP_MAYBE_DONT_COLLIDE_WITH)
+#define CAN_BE_CLONED_BY_ANDROID(e)    \
+                               HAS_PROPERTY(e, EP_CAN_BE_CLONED_BY_ANDROID)
+
+#define IS_EDITOR_CASCADE(e)   HAS_PROPERTY(e, EP_EDITOR_CASCADE)
+#define IS_EDITOR_CASCADE_ACTIVE(e)    \
+                               HAS_PROPERTY(e, EP_EDITOR_CASCADE_ACTIVE)
+#define IS_EDITOR_CASCADE_INACTIVE(e)  \
+                               HAS_PROPERTY(e, EP_EDITOR_CASCADE_INACTIVE)
+
 #define HAS_ACTION(e)          HAS_PROPERTY(e, EP_HAS_ACTION)
 #define CAN_CHANGE_OR_HAS_ACTION(e)    \
                                HAS_PROPERTY(e, EP_CAN_CHANGE_OR_HAS_ACTION)
 
 #define IS_RND_GATE_GRAY(e)    ((e) >= EL_GATE_1_GRAY &&               \
                                 (e) <= EL_GATE_4_GRAY)
+#define IS_RND_GATE_GRAY_ACTIVE(e) ((e) >= EL_GATE_1_GRAY_ACTIVE &&    \
+                                (e) <= EL_GATE_4_GRAY_ACTIVE)
 #define IS_EM_GATE_GRAY(e)     ((e) >= EL_EM_GATE_1_GRAY &&            \
                                 (e) <= EL_EM_GATE_4_GRAY)
+#define IS_EM_GATE_GRAY_ACTIVE(e) ((e) >= EL_EM_GATE_1_GRAY_ACTIVE &&  \
+                                (e) <= EL_EM_GATE_4_GRAY_ACTIVE)
 #define IS_EMC_GATE_GRAY(e)    ((e) >= EL_EMC_GATE_5_GRAY &&           \
                                 (e) <= EL_EMC_GATE_8_GRAY)
+#define IS_EMC_GATE_GRAY_ACTIVE(e) ((e) >= EL_EMC_GATE_5_GRAY_ACTIVE &&        \
+                                (e) <= EL_EMC_GATE_8_GRAY_ACTIVE)
 #define IS_GATE_GRAY(e)                (IS_RND_GATE_GRAY(e) ||                 \
                                 IS_EM_GATE_GRAY(e) ||                  \
                                 IS_EMC_GATE_GRAY(e))
+#define IS_GATE_GRAY_ACTIVE(e) (IS_RND_GATE_GRAY_ACTIVE(e) ||          \
+                                IS_EM_GATE_GRAY_ACTIVE(e) ||           \
+                                IS_EMC_GATE_GRAY_ACTIVE(e))
 #define RND_GATE_GRAY_NR(e)    ((e) - EL_GATE_1_GRAY)
+#define RND_GATE_GRAY_ACTIVE_NR(e) ((e) - EL_GATE_1_GRAY_ACTIVE)
 #define EM_GATE_GRAY_NR(e)     ((e) - EL_EM_GATE_1_GRAY)
+#define EM_GATE_GRAY_ACTIVE_NR(e) ((e) - EL_EM_GATE_1_GRAY_ACTIVE)
 #define EMC_GATE_GRAY_NR(e)    ((e) - EL_EMC_GATE_5_GRAY + 4)
+#define EMC_GATE_GRAY_ACTIVE_NR(e) ((e) - EL_EMC_GATE_5_GRAY_ACTIVE + 4)
 #define GATE_GRAY_NR(e)                (IS_RND_GATE_GRAY(e) ? RND_GATE_GRAY_NR(e) :  \
                                 IS_EM_GATE_GRAY(e) ?  EM_GATE_GRAY_NR(e) :   \
                                 IS_EMC_GATE_GRAY(e) ? EMC_GATE_GRAY_NR(e) : 0)
 #define SND_ELEMENT(e)         (e)
 #endif
 
+#if 1
+#define GROUP_NR(e)            ((e) - EL_GROUP_START)
+#define IS_IN_GROUP(e, nr)     (element_info[e].in_group[nr] == TRUE)
+#define IS_IN_GROUP_EL(e, ge)  (IS_IN_GROUP(e, (ge) - EL_GROUP_START))
+
+#define IS_EQUAL_OR_IN_GROUP(e, ge)                                    \
+       (IS_GROUP_ELEMENT(ge) ? IS_IN_GROUP(e, GROUP_NR(ge)) : (e) == (ge))
+#endif
+
 #define IS_PLAYER(x, y)                (ELEM_IS_PLAYER(StorePlayer[x][y]))
 
 #define IS_FREE(x, y)          (Feld[x][y] == EL_EMPTY && !IS_PLAYER(x, y))
 #define IS_FALLING(x,y)                (MovPos[x][y] != 0 && MovDir[x][y] == MV_DOWN)
 #define IS_BLOCKED(x,y)                (Feld[x][y] == EL_BLOCKED)
 
+#define IS_MV_DIAGONAL(x)      ((x) & MV_HORIZONTAL && (x) & MV_VERTICAL)
+
 #define EL_CHANGED(e)          ((e) == EL_ROCK           ? EL_EMERALD :    \
                                 (e) == EL_BD_ROCK        ? EL_BD_DIAMOND : \
                                 (e) == EL_EMERALD        ? EL_DIAMOND :    \
 
 #define PLAYER_NR_GFX(g,i)     ((g) + i * (IMG_PLAYER_2 - IMG_PLAYER_1))
 
+#define GET_PLAYER_ELEMENT(e)  ((e) >= EL_PLAYER_1 && (e) <= EL_PLAYER_4 ? \
+                                (e) : EL_PLAYER_1)
+
+#define GET_PLAYER_NR(e)       (GET_PLAYER_ELEMENT(e) - EL_PLAYER_1)
+
 #define ANIM_FRAMES(g)         (graphic_info[g].anim_frames)
 #define ANIM_DELAY(g)          (graphic_info[g].anim_delay)
 #define ANIM_MODE(g)           (graphic_info[g].anim_mode)
 
 #define IS_LOOP_SOUND(s)       (sound_info[s].loop)
 
+#define EL_CASCADE_ACTIVE(e)   (IS_EDITOR_CASCADE_INACTIVE(e) ? (e) + 1 : (e))
+#define EL_CASCADE_INACTIVE(e) (IS_EDITOR_CASCADE_ACTIVE(e)   ? (e) - 1 : (e))
+#define EL_CASCADE_TOGGLE(e)   (IS_EDITOR_CASCADE_INACTIVE(e) ? (e) + 1 :    \
+                                IS_EDITOR_CASCADE_ACTIVE(e)   ? (e) - 1 : (e))
+
+#define EL_NAME(e)             ((e) >= 0 ? element_info[e].token_name : "(?)")
 
 /* fundamental game speed values */
 #define ONE_SECOND_DELAY       1000    /* delay value for one second */
 #define MAX_CHANGE_PAGES       32
 #define MIN_ELEMENTS_IN_GROUP  1
 #define MAX_ELEMENTS_IN_GROUP  16
+#define MIN_ANDROID_ELEMENTS   1
+#define MAX_ANDROID_ELEMENTS   16
 
 /* values for elements with content */
 #define MIN_ELEMENT_CONTENTS   1
 #define EL_EM_GATE_3_GRAY              252
 #define EL_EM_GATE_4_GRAY              253
 
-#define EL_UNUSED_254                  254
-#define EL_UNUSED_255                  255
+#define EL_EM_DYNAMITE                 254
+#define EL_EM_DYNAMITE_ACTIVE          255
 
 #define EL_PEARL                       256
 #define EL_CRYSTAL                     257
 #define EL_TRIGGER_ELEMENT             657
 #define EL_TRIGGER_PLAYER              658
 
+/* SP style elements */
 #define EL_SP_GRAVITY_ON_PORT_RIGHT    659
 #define EL_SP_GRAVITY_ON_PORT_DOWN     660
 #define EL_SP_GRAVITY_ON_PORT_LEFT     661
 #define EL_SP_GRAVITY_OFF_PORT_LEFT    665
 #define EL_SP_GRAVITY_OFF_PORT_UP      666
 
-
-/* the following EMC style elements are currently not implemented in R'n'D */
+/* EMC style elements */
 #define EL_BALLOON_SWITCH_NONE         667
 #define EL_EMC_GATE_5                  668
 #define EL_EMC_GATE_6                  669
 #define EL_EMC_FAKE_ACID               703
 #define EL_EMC_DRIPPER                 704
 
-#define NUM_FILE_ELEMENTS              705
+#define EL_TRIGGER_CE_VALUE            705
+
+#define NUM_FILE_ELEMENTS              706
 
 
 /* "real" (and therefore drawable) runtime elements */
 #define EL_BD_MAGIC_WALL_EMPTYING      (EL_FIRST_RUNTIME_REAL + 42)
 #define EL_MAGIC_WALL_DEAD             (EL_FIRST_RUNTIME_REAL + 43)
 #define EL_BD_MAGIC_WALL_DEAD          (EL_FIRST_RUNTIME_REAL + 44)
+#define EL_EMC_FAKE_GRASS_ACTIVE       (EL_FIRST_RUNTIME_REAL + 45)
+#define EL_GATE_1_GRAY_ACTIVE          (EL_FIRST_RUNTIME_REAL + 46)
+#define EL_GATE_2_GRAY_ACTIVE          (EL_FIRST_RUNTIME_REAL + 47)
+#define EL_GATE_3_GRAY_ACTIVE          (EL_FIRST_RUNTIME_REAL + 48)
+#define EL_GATE_4_GRAY_ACTIVE          (EL_FIRST_RUNTIME_REAL + 49)
+#define EL_EM_GATE_1_GRAY_ACTIVE       (EL_FIRST_RUNTIME_REAL + 50)
+#define EL_EM_GATE_2_GRAY_ACTIVE       (EL_FIRST_RUNTIME_REAL + 51)
+#define EL_EM_GATE_3_GRAY_ACTIVE       (EL_FIRST_RUNTIME_REAL + 52)
+#define EL_EM_GATE_4_GRAY_ACTIVE       (EL_FIRST_RUNTIME_REAL + 53)
+#define EL_EMC_GATE_5_GRAY_ACTIVE      (EL_FIRST_RUNTIME_REAL + 54)
+#define EL_EMC_GATE_6_GRAY_ACTIVE      (EL_FIRST_RUNTIME_REAL + 55)
+#define EL_EMC_GATE_7_GRAY_ACTIVE      (EL_FIRST_RUNTIME_REAL + 56)
+#define EL_EMC_GATE_8_GRAY_ACTIVE      (EL_FIRST_RUNTIME_REAL + 57)
+#define EL_EMC_DRIPPER_ACTIVE          (EL_FIRST_RUNTIME_REAL + 58)
+#define EL_EMC_SPRING_BUMPER_ACTIVE    (EL_FIRST_RUNTIME_REAL + 59)
 
 /* "unreal" (and therefore not drawable) runtime elements */
-#define EL_FIRST_RUNTIME_UNREAL                (EL_FIRST_RUNTIME_REAL + 45)
+#define EL_FIRST_RUNTIME_UNREAL                (EL_FIRST_RUNTIME_REAL + 60)
 
 #define EL_BLOCKED                     (EL_FIRST_RUNTIME_UNREAL + 0)
 #define EL_EXPLOSION                   (EL_FIRST_RUNTIME_UNREAL + 1)
 #define EL_QUICKSAND_FILLING           (EL_FIRST_RUNTIME_UNREAL + 15)
 #define EL_MAGIC_WALL_FILLING          (EL_FIRST_RUNTIME_UNREAL + 16)
 #define EL_BD_MAGIC_WALL_FILLING       (EL_FIRST_RUNTIME_UNREAL + 17)
+#define EL_ELEMENT_SNAPPING            (EL_FIRST_RUNTIME_UNREAL + 18)
+#define EL_DIAGONAL_SHRINKING          (EL_FIRST_RUNTIME_UNREAL + 19)
+#define EL_DIAGONAL_GROWING            (EL_FIRST_RUNTIME_UNREAL + 20)
+
+#define NUM_RUNTIME_ELEMENTS           (EL_FIRST_RUNTIME_UNREAL + 21)
 
 /* dummy elements (never used as game elements, only used as graphics) */
-#define EL_FIRST_DUMMY                 (EL_FIRST_RUNTIME_UNREAL + 18)
+#define EL_FIRST_DUMMY                 NUM_RUNTIME_ELEMENTS
 
 #define EL_STEELWALL_TOPLEFT           (EL_FIRST_DUMMY + 0)
 #define EL_STEELWALL_TOPRIGHT          (EL_FIRST_DUMMY + 1)
 #define EL_INTERNAL_CLIPBOARD_GROUP    (EL_FIRST_INTERNAL + 2)
 #define EL_INTERNAL_DUMMY              (EL_FIRST_INTERNAL + 3)
 
+#define EL_INTERNAL_CASCADE_BD                 (EL_FIRST_INTERNAL + 4)
+#define EL_INTERNAL_CASCADE_BD_ACTIVE          (EL_FIRST_INTERNAL + 5)
+#define EL_INTERNAL_CASCADE_EM                 (EL_FIRST_INTERNAL + 6)
+#define EL_INTERNAL_CASCADE_EM_ACTIVE          (EL_FIRST_INTERNAL + 7)
+#define EL_INTERNAL_CASCADE_EMC                        (EL_FIRST_INTERNAL + 8)
+#define EL_INTERNAL_CASCADE_EMC_ACTIVE         (EL_FIRST_INTERNAL + 9)
+#define EL_INTERNAL_CASCADE_RND                        (EL_FIRST_INTERNAL + 10)
+#define EL_INTERNAL_CASCADE_RND_ACTIVE         (EL_FIRST_INTERNAL + 11)
+#define EL_INTERNAL_CASCADE_SB                 (EL_FIRST_INTERNAL + 12)
+#define EL_INTERNAL_CASCADE_SB_ACTIVE          (EL_FIRST_INTERNAL + 13)
+#define EL_INTERNAL_CASCADE_SP                 (EL_FIRST_INTERNAL + 14)
+#define EL_INTERNAL_CASCADE_SP_ACTIVE          (EL_FIRST_INTERNAL + 15)
+#define EL_INTERNAL_CASCADE_DC                 (EL_FIRST_INTERNAL + 16)
+#define EL_INTERNAL_CASCADE_DC_ACTIVE          (EL_FIRST_INTERNAL + 17)
+#define EL_INTERNAL_CASCADE_DX                 (EL_FIRST_INTERNAL + 18)
+#define EL_INTERNAL_CASCADE_DX_ACTIVE          (EL_FIRST_INTERNAL + 19)
+#define EL_INTERNAL_CASCADE_CHARS              (EL_FIRST_INTERNAL + 20)
+#define EL_INTERNAL_CASCADE_CHARS_ACTIVE       (EL_FIRST_INTERNAL + 21)
+#define EL_INTERNAL_CASCADE_CE                 (EL_FIRST_INTERNAL + 22)
+#define EL_INTERNAL_CASCADE_CE_ACTIVE          (EL_FIRST_INTERNAL + 23)
+#define EL_INTERNAL_CASCADE_GE                 (EL_FIRST_INTERNAL + 24)
+#define EL_INTERNAL_CASCADE_GE_ACTIVE          (EL_FIRST_INTERNAL + 25)
+#define EL_INTERNAL_CASCADE_USER               (EL_FIRST_INTERNAL + 26)
+#define EL_INTERNAL_CASCADE_USER_ACTIVE                (EL_FIRST_INTERNAL + 27)
+#define EL_INTERNAL_CASCADE_GENERIC            (EL_FIRST_INTERNAL + 28)
+#define EL_INTERNAL_CASCADE_GENERIC_ACTIVE     (EL_FIRST_INTERNAL + 29)
+#define EL_INTERNAL_CASCADE_DYNAMIC            (EL_FIRST_INTERNAL + 30)
+#define EL_INTERNAL_CASCADE_DYNAMIC_ACTIVE     (EL_FIRST_INTERNAL + 31)
+
 #define EL_INTERNAL_CLIPBOARD_START    (EL_FIRST_INTERNAL + 0)
 #define EL_INTERNAL_CLIPBOARD_END      (EL_FIRST_INTERNAL + 2)
 #define EL_INTERNAL_START              (EL_FIRST_INTERNAL + 0)
-#define EL_INTERNAL_END                        (EL_FIRST_INTERNAL + 3)
+#define EL_INTERNAL_END                        (EL_FIRST_INTERNAL + 31)
 
-#define MAX_NUM_ELEMENTS               (EL_FIRST_INTERNAL + 4)
+#define MAX_NUM_ELEMENTS               (EL_FIRST_INTERNAL + 32)
 
 
 /* values for graphics/sounds action types */
 #define ACTION_TURNING_FROM_DOWN       46
 #define ACTION_SMASHED_BY_ROCK         47
 #define ACTION_SMASHED_BY_SPRING       48
-#define ACTION_SLURPED_BY_SPRING       49
+#define ACTION_EATING                  49
 #define ACTION_TWINKLING               50
 #define ACTION_SPLASHING               51
 #define ACTION_PAGE_1                  52
 
 
 /* program information and versioning definitions */
-
-#define RELEASE_3_1_2                  FALSE
-
-#if RELEASE_3_1_2
-#define PROGRAM_VERSION_MAJOR          3
-#define PROGRAM_VERSION_MINOR          1
-#define PROGRAM_VERSION_PATCH          2
-#define PROGRAM_VERSION_BUILD          0
-#else
-/* !!! make sure that packaging script can find unique version number !!! */
 #define PROGRAM_VERSION_MAJOR          3
 #define PROGRAM_VERSION_MINOR          2
 #define PROGRAM_VERSION_PATCH          0
-#define PROGRAM_VERSION_BUILD          5
-#endif
+#define PROGRAM_VERSION_BUILD          7
 
 #define PROGRAM_TITLE_STRING           "Rocks'n'Diamonds"
 #define PROGRAM_AUTHOR_STRING          "Holger Schemel"
-#define PROGRAM_COPYRIGHT_STRING       "Copyright ©1995-2005 by Holger Schemel"
+#define PROGRAM_COPYRIGHT_STRING       "Copyright ©1995-2006 by Holger Schemel"
 
 #define ICON_TITLE_STRING              PROGRAM_TITLE_STRING
 #define COOKIE_PREFIX                  "ROCKSNDIAMONDS"
@@ -1603,6 +1750,8 @@ struct MenuInfo
 
 struct DoorInfo
 {
+  int width;
+  int height;
   int step_offset;
   int step_delay;
   int anim_mode;
@@ -1643,7 +1792,8 @@ struct PlayerInfo
 
   int GfxAction;
 
-  boolean use_murphy_graphic;
+  boolean use_murphy;
+  int artwork_element;
 
   boolean block_last_field;
   int block_delay_adjustment;  /* needed for different engine versions */
@@ -1667,6 +1817,8 @@ struct PlayerInfo
   boolean is_bored;
   boolean is_sleeping;
 
+  boolean cannot_move;
+
   int frame_counter_bored;
   int frame_counter_sleeping;
 
@@ -1777,6 +1929,18 @@ struct LevelInfo
   int extra_time;
   int time_orb_time;
 
+  int extra_time_score;
+
+  int start_element[MAX_PLAYERS];
+  boolean use_start_element[MAX_PLAYERS];
+
+  int artwork_element[MAX_PLAYERS];
+  boolean use_artwork_element[MAX_PLAYERS];
+
+  int explosion_element[MAX_PLAYERS];
+  boolean use_explosion_element[MAX_PLAYERS];
+
+#if 1
   /* values for the new EMC elements */
   int android_move_time;
   int android_clone_time;
@@ -1789,20 +1953,31 @@ struct LevelInfo
   int lenses_time;
   int magnify_time;
   int wind_direction_initial;
+
   struct Content ball_content[MAX_ELEMENT_CONTENTS];
+  int num_ball_contents;
+
+#if 0
   boolean android_array[16];
+#endif
+  int num_android_clone_elements;
+  int android_clone_element[MAX_ANDROID_ELEMENTS];
+#endif
 
   int can_move_into_acid_bits; /* bitfield to store property for elements */
   int dont_collide_with_bits;  /* bitfield to store property for elements */
 
-  boolean double_speed;
+  int initial_player_stepsize; /* initial player speed */
+
   boolean initial_gravity;
   boolean em_slippery_gems;    /* EM style "gems slip from wall" behaviour */
   boolean use_spring_bug;      /* for compatibility with old levels */
+  boolean use_time_orb_bug;    /* for compatibility with old levels */
   boolean instant_relocation;  /* no visual delay when relocating player */
   boolean can_pass_to_walkable;        /* player can pass to empty or walkable tile */
   boolean grow_into_diggable;  /* amoeba can grow into anything diggable */
 
+  boolean block_snap_field;    /* snapping blocks field to show animation */
   boolean block_last_field;    /* player blocks previous field while moving */
   boolean sp_block_last_field; /* player blocks previous field while moving */
 
@@ -1871,6 +2046,8 @@ struct GameInfo
   /* (for the latest engine version, these flags should always be "FALSE") */
   boolean use_change_when_pushing_bug;
   boolean use_block_last_field_bug;
+  boolean max_num_changes_per_frame;
+  boolean use_reverse_scan_direction;
 
   /* variable within running game */
   int yamyam_content_nr;
@@ -1886,6 +2063,14 @@ struct GameInfo
   boolean explosions_delayed;
   boolean envelope_active;
 
+#if 1
+  /* values for the new EMC elements */
+  int lenses_time_left;
+  int magnify_time_left;
+  boolean ball_state;
+  int ball_content_nr;
+#endif
+
   /* values for player idle animation (no effect on engine) */
   int player_boring_delay_fixed;
   int player_boring_delay_random;
@@ -1894,6 +2079,10 @@ struct GameInfo
 
   /* values for special game initialization control */
   boolean restart_level;
+
+  /* values for special game control */
+  int centered_player_nr;
+  int centered_player_nr_next;
 };
 
 struct GlobalInfo
@@ -1922,13 +2111,13 @@ struct ElementChangeInfo
   int trigger_side;            /* side triggering change */
   int trigger_page;            /* page triggering change */
 
-  short target_element;                /* target element after change */
+  int target_element;          /* target element after change */
 
   int delay_fixed;             /* added frame delay before changed (fixed) */
   int delay_random;            /* added frame delay before changed (random) */
   int delay_frames;            /* either 1 (frames) or 50 (seconds; 50 fps) */
 
-  short trigger_element;       /* element triggering change */
+  int trigger_element;         /* element triggering change */
 
   struct Content target_content;/* elements for extended change target */
   boolean use_target_content;  /* use extended change target */
@@ -1968,7 +2157,7 @@ struct ElementChangeInfo
 struct ElementGroupInfo
 {
   int num_elements;                    /* number of elements in this group */
-  short element[MAX_ELEMENTS_IN_GROUP];        /* list of elements in this group */
+  int element[MAX_ELEMENTS_IN_GROUP];  /* list of elements in this group */
 
   int choice_mode;             /* how to choose element from group */
 
@@ -2004,11 +2193,11 @@ struct ElementInfo
   /* ---------- graphic and sound definitions ---------- */
 
   int graphic[NUM_ACTIONS];    /* default graphics for several actions */
-  int direction_graphic[NUM_ACTIONS][NUM_DIRECTIONS];
+  int direction_graphic[NUM_ACTIONS][NUM_DIRECTIONS_FULL];
                                /* special graphics for left/right/up/down */
 
   int crumbled[NUM_ACTIONS];   /* crumbled graphics for several actions */
-  int direction_crumbled[NUM_ACTIONS][NUM_DIRECTIONS];
+  int direction_crumbled[NUM_ACTIONS][NUM_DIRECTIONS_FULL];
                                /* crumbled graphics for left/right/up/down */
 
   int special_graphic[NUM_SPECIAL_GFX_ARGS];
@@ -2018,8 +2207,10 @@ struct ElementInfo
 
   /* ---------- special element property values ---------- */
 
+  unsigned long properties[NUM_EP_BITFIELDS];  /* element base properties */
+
   boolean use_gfx_element;     /* use custom graphic element */
-  short gfx_element;           /* optional custom graphic element */
+  int gfx_element;             /* optional custom graphic element */
 
   int access_direction;                /* accessible from which direction */
 
@@ -2241,7 +2432,7 @@ extern short                      StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   Back[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern boolean                 Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern boolean                 Pushed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
-extern boolean                 Changed[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern short                   ChangeCount[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   ChangeEvent[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   WasJustMoving[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern short                   WasJustFalling[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
@@ -2255,7 +2446,9 @@ extern short                      ExplodeDelay[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern int                     RunnerVisit[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern int                     PlayerVisit[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 
+#if 0
 extern unsigned long           Properties[MAX_NUM_ELEMENTS][NUM_EP_BITFIELDS];
+#endif
 
 extern int                     GfxFrame[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
 extern int                     GfxRandom[MAX_LEV_FIELDX][MAX_LEV_FIELDY];