// values for pre-defined properties
// (from here on, values can be changed by inserting new values)
-#define EP_PLAYER 32
-#define EP_CAN_PASS_MAGIC_WALL 33
-#define EP_CAN_PASS_DC_MAGIC_WALL 34
-#define EP_SWITCHABLE 35
-#define EP_BD_ELEMENT 36
-#define EP_SP_ELEMENT 37
-#define EP_SB_ELEMENT 38
-#define EP_GEM 39
-#define EP_FOOD_DARK_YAMYAM 40
-#define EP_FOOD_PENGUIN 41
-#define EP_FOOD_PIG 42
-#define EP_HISTORIC_WALL 43
-#define EP_HISTORIC_SOLID 44
-#define EP_CLASSIC_ENEMY 45
-#define EP_BELT 46
-#define EP_BELT_ACTIVE 47
-#define EP_BELT_SWITCH 48
-#define EP_TUBE 49
-#define EP_ACID_POOL 50
-#define EP_KEYGATE 51
-#define EP_AMOEBOID 52
-#define EP_AMOEBALIVE 53
-#define EP_HAS_EDITOR_CONTENT 54
-#define EP_CAN_TURN_EACH_MOVE 55
-#define EP_CAN_GROW 56
-#define EP_ACTIVE_BOMB 57
-#define EP_INACTIVE 58
+#define EP_EMPTY_SPACE 32
+#define EP_PLAYER 33
+#define EP_CAN_PASS_MAGIC_WALL 34
+#define EP_CAN_PASS_DC_MAGIC_WALL 35
+#define EP_SWITCHABLE 36
+#define EP_BD_ELEMENT 37
+#define EP_SP_ELEMENT 38
+#define EP_SB_ELEMENT 39
+#define EP_GEM 40
+#define EP_FOOD_DARK_YAMYAM 41
+#define EP_FOOD_PENGUIN 42
+#define EP_FOOD_PIG 43
+#define EP_HISTORIC_WALL 44
+#define EP_HISTORIC_SOLID 45
+#define EP_CLASSIC_ENEMY 46
+#define EP_BELT 47
+#define EP_BELT_ACTIVE 48
+#define EP_BELT_SWITCH 49
+#define EP_TUBE 50
+#define EP_ACID_POOL 51
+#define EP_KEYGATE 52
+#define EP_AMOEBOID 53
+#define EP_AMOEBALIVE 54
+#define EP_HAS_EDITOR_CONTENT 55
+#define EP_CAN_TURN_EACH_MOVE 56
+#define EP_CAN_GROW 57
+#define EP_ACTIVE_BOMB 58
+#define EP_INACTIVE 59
// values for special configurable properties (depending on level settings)
-#define EP_EM_SLIPPERY_WALL 59
+#define EP_EM_SLIPPERY_WALL 60
// values for special graphics properties (no effect on game engine)
-#define EP_GFX_CRUMBLED 60
+#define EP_GFX_CRUMBLED 61
// values for derived properties (determined from properties above)
-#define EP_ACCESSIBLE_OVER 61
-#define EP_ACCESSIBLE_INSIDE 62
-#define EP_ACCESSIBLE_UNDER 63
-#define EP_WALKABLE 64
-#define EP_PASSABLE 65
-#define EP_ACCESSIBLE 66
-#define EP_COLLECTIBLE 67
-#define EP_SNAPPABLE 68
-#define EP_WALL 69
-#define EP_SOLID_FOR_PUSHING 70
-#define EP_DRAGONFIRE_PROOF 71
-#define EP_EXPLOSION_PROOF 72
-#define EP_CAN_SMASH 73
-#define EP_EXPLODES_3X3_OLD 74
-#define EP_CAN_EXPLODE_BY_FIRE 75
-#define EP_CAN_EXPLODE_SMASHED 76
-#define EP_CAN_EXPLODE_IMPACT 77
-#define EP_SP_PORT 78
-#define EP_CAN_EXPLODE_BY_DRAGONFIRE 79
-#define EP_CAN_EXPLODE_BY_EXPLOSION 80
-#define EP_COULD_MOVE_INTO_ACID 81
-#define EP_MAYBE_DONT_COLLIDE_WITH 82
-#define EP_CAN_BE_CLONED_BY_ANDROID 83
+#define EP_ACCESSIBLE_OVER 62
+#define EP_ACCESSIBLE_INSIDE 63
+#define EP_ACCESSIBLE_UNDER 64
+#define EP_WALKABLE 65
+#define EP_PASSABLE 66
+#define EP_ACCESSIBLE 67
+#define EP_COLLECTIBLE 68
+#define EP_SNAPPABLE 69
+#define EP_WALL 70
+#define EP_SOLID_FOR_PUSHING 71
+#define EP_DRAGONFIRE_PROOF 72
+#define EP_EXPLOSION_PROOF 73
+#define EP_CAN_SMASH 74
+#define EP_EXPLODES_3X3_OLD 75
+#define EP_CAN_EXPLODE_BY_FIRE 76
+#define EP_CAN_EXPLODE_SMASHED 77
+#define EP_CAN_EXPLODE_IMPACT 78
+#define EP_SP_PORT 79
+#define EP_CAN_EXPLODE_BY_DRAGONFIRE 80
+#define EP_CAN_EXPLODE_BY_EXPLOSION 81
+#define EP_COULD_MOVE_INTO_ACID 82
+#define EP_MAYBE_DONT_COLLIDE_WITH 83
+#define EP_CAN_BE_CLONED_BY_ANDROID 84
// values for internal purpose only (level editor)
-#define EP_WALK_TO_OBJECT 84
-#define EP_DEADLY 85
-#define EP_EDITOR_CASCADE 86
-#define EP_EDITOR_CASCADE_ACTIVE 87
-#define EP_EDITOR_CASCADE_INACTIVE 88
+#define EP_WALK_TO_OBJECT 85
+#define EP_DEADLY 86
+#define EP_EDITOR_CASCADE 87
+#define EP_EDITOR_CASCADE_ACTIVE 88
+#define EP_EDITOR_CASCADE_INACTIVE 89
// values for internal purpose only (game engine)
-#define EP_HAS_ACTION 89
-#define EP_CAN_CHANGE_OR_HAS_ACTION 90
+#define EP_HAS_ACTION 90
+#define EP_CAN_CHANGE_OR_HAS_ACTION 91
// values for internal purpose only (other)
-#define EP_OBSOLETE 91
+#define EP_OBSOLETE 92
-#define NUM_ELEMENT_PROPERTIES 92
+#define NUM_ELEMENT_PROPERTIES 93
#define NUM_EP_BITFIELDS ((NUM_ELEMENT_PROPERTIES + 31) / 32)
#define EP_BITFIELD_BASE_NR 0
#define EP_BITMASK_BASE_DEFAULT (1 << EP_CAN_MOVE_INTO_ACID)
#define EP_BITMASK_DEFAULT 0
-#define PROPERTY_BIT(p) (1 << ((p) % 32))
-#define PROPERTY_VAR(e,p) (element_info[e].properties[(p) / 32])
-#define HAS_PROPERTY(e,p) ((PROPERTY_VAR(e, p) & PROPERTY_BIT(p)) != 0)
-#define SET_PROPERTY(e,p,v) ((v) ? \
+#define PROPERTY_BIT(p) (1u << ((p) % 32))
+#define PROPERTY_VAR(e, p) (element_info[e].properties[(p) / 32])
+#define HAS_PROPERTY(e, p) ((PROPERTY_VAR(e, p) & PROPERTY_BIT(p)) != 0)
+#define SET_PROPERTY(e, p, v) ((v) ? \
(PROPERTY_VAR(e,p) |= PROPERTY_BIT(p)) : \
(PROPERTY_VAR(e,p) &= ~PROPERTY_BIT(p)))
#define CH_EVENT_BITFIELD_NR(e) (e / 32)
#define CH_EVENT_BIT(e) (1 << ((e) % 32))
-#define CH_EVENT_VAR(e,c) (element_info[e].change->has_event[c])
-#define CH_ANY_EVENT_VAR(e,c) (element_info[e].has_change_event[c])
+#define CH_EVENT_VAR(e, c) (element_info[e].change->has_event[c])
+#define CH_ANY_EVENT_VAR(e, c) (element_info[e].has_change_event[c])
-#define PAGE_HAS_CHANGE_EVENT(p,c) ((p)->has_event[c])
-#define HAS_CHANGE_EVENT(e,c) (IS_CUSTOM_ELEMENT(e) && \
- CH_EVENT_VAR(e,c))
-#define HAS_ANY_CHANGE_EVENT(e,c) (IS_CUSTOM_ELEMENT(e) && \
- CH_ANY_EVENT_VAR(e,c))
+#define PAGE_HAS_CHANGE_EVENT(p, c) ((p)->has_event[c])
+#define HAS_CHANGE_EVENT(e, c) (IS_CUSTOM_ELEMENT(e) && \
+ CH_EVENT_VAR(e, c))
+#define HAS_ANY_CHANGE_EVENT(e, c) (IS_CUSTOM_ELEMENT(e) && \
+ CH_ANY_EVENT_VAR(e, c))
-#define SET_CHANGE_EVENT(e,c,v) (IS_CUSTOM_ELEMENT(e) ? \
- CH_EVENT_VAR(e,c) = (v) : 0)
-#define SET_ANY_CHANGE_EVENT(e,c,v) (IS_CUSTOM_ELEMENT(e) ? \
- CH_ANY_EVENT_VAR(e,c) = (v) : 0)
+#define SET_CHANGE_EVENT(e, c, v) (IS_CUSTOM_ELEMENT(e) ? \
+ CH_EVENT_VAR(e, c) = (v) : 0)
+#define SET_ANY_CHANGE_EVENT(e, c, v) (IS_CUSTOM_ELEMENT(e) ? \
+ CH_ANY_EVENT_VAR(e, c) = (v) : 0)
// values for player bitmasks
#define PLAYER_BITS_NONE 0
#define GFX_CRUMBLED(e) HAS_PROPERTY(GFX_ELEMENT(e), EP_GFX_CRUMBLED)
// macros for pre-defined properties
+#define IS_EMPTY_SPACE(e) HAS_PROPERTY(e, EP_EMPTY_SPACE)
#define IS_PLAYER_ELEMENT(e) HAS_PROPERTY(e, EP_PLAYER)
#define CAN_PASS_MAGIC_WALL(e) HAS_PROPERTY(e, EP_CAN_PASS_MAGIC_WALL)
#define CAN_PASS_DC_MAGIC_WALL(e) HAS_PROPERTY(e, EP_CAN_PASS_DC_MAGIC_WALL)
#define IS_OBSOLETE(e) HAS_PROPERTY(e, EP_OBSOLETE)
+#define IS_EMPTY(e) IS_EMPTY_SPACE(e)
+#define IS_EMPTY_ELEMENT(e) IS_EMPTY_SPACE(e)
+
// special macros used in game engine
#define IS_FILE_ELEMENT(e) ((e) >= 0 && \
(e) <= NUM_FILE_ELEMENTS)
#define IS_ENVELOPE(e) ((e) >= EL_ENVELOPE_1 && \
(e) <= EL_ENVELOPE_4)
+#define IS_MM_ENVELOPE(e) ((e) >= EL_MM_ENVELOPE_1 && \
+ (e) <= EL_MM_ENVELOPE_4)
+
#define IS_BALLOON_ELEMENT(e) ((e) == EL_BALLOON || \
(e) == EL_BALLOON_SWITCH_LEFT || \
(e) == EL_BALLOON_SWITCH_RIGHT || \
IS_EM_GATE_GRAY(e) ? EM_GATE_GRAY_NR(e) : \
IS_EMC_GATE_GRAY(e) ? EMC_GATE_GRAY_NR(e) : 0)
+#define RND_ENVELOPE_NR(e) ((e) - EL_ENVELOPE_1)
+#define MM_ENVELOPE_NR(e) ((e) - EL_MM_ENVELOPE_1)
+#define ENVELOPE_NR(e) (IS_ENVELOPE(e) ? RND_ENVELOPE_NR(e) : \
+ MM_ENVELOPE_NR(e))
+
#define IS_ACID_POOL_OR_ACID(e) (IS_ACID_POOL(e) || (e) == EL_ACID)
#define IS_EMC_PILLAR(e) ((e) >= EL_EMC_WALL_1 && \
#define IS_FREE(x, y) (Tile[x][y] == EL_EMPTY && !IS_PLAYER(x, y))
#define IS_FREE_OR_PLAYER(x, y) (Tile[x][y] == EL_EMPTY)
-#define IS_MOVING(x,y) (MovPos[x][y] != 0)
-#define IS_FALLING(x,y) (MovPos[x][y] != 0 && MovDir[x][y] == MV_DOWN)
-#define IS_BLOCKED(x,y) (Tile[x][y] == EL_BLOCKED)
+#define IS_MOVING(x, y) (MovPos[x][y] != 0)
+#define IS_FALLING(x, y) (MovPos[x][y] != 0 && MovDir[x][y] == MV_DOWN)
+#define IS_BLOCKED(x, y) (Tile[x][y] == EL_BLOCKED)
#define IS_MV_DIAGONAL(x) ((x) & MV_HORIZONTAL && (x) & MV_VERTICAL)
#define TAPE_IS_EMPTY(x) ((x).length == 0)
#define TAPE_IS_STOPPED(x) (!(x).recording && !(x).playing)
-#define PLAYERINFO(x,y) (&stored_player[StorePlayer[x][y]-EL_PLAYER_1])
+#define PLAYERINFO(x, y) (&stored_player[StorePlayer[x][y] - EL_PLAYER_1])
#define SHIELD_ON(p) ((p)->shield_normal_time_left > 0)
-#define ENEMY_PROTECTED_FIELD(x,y) (IS_PROTECTED(Tile[x][y]) || \
+#define ENEMY_PROTECTED_FIELD(x, y) (IS_PROTECTED(Tile[x][y]) || \
IS_PROTECTED(Back[x][y]))
-#define EXPLOSION_PROTECTED_FIELD(x,y) (IS_EXPLOSION_PROOF(Tile[x][y]))
-#define PLAYER_ENEMY_PROTECTED(x,y) (SHIELD_ON(PLAYERINFO(x, y)) || \
+#define EXPLOSION_PROTECTED_FIELD(x, y) (IS_EXPLOSION_PROOF(Tile[x][y]))
+#define PLAYER_ENEMY_PROTECTED(x, y) (SHIELD_ON(PLAYERINFO(x, y)) || \
ENEMY_PROTECTED_FIELD(x, y))
#define PLAYER_EXPLOSION_PROTECTED(x,y) (SHIELD_ON(PLAYERINFO(x, y)) || \
EXPLOSION_PROTECTED_FIELD(x, y))
#define PLAYER_DROPPING(p,x,y) ((p)->is_dropping && \
(p)->drop_x == (x) && (p)->drop_y == (y))
-#define PLAYER_NR_GFX(g,i) ((g) + i * (IMG_PLAYER_2 - IMG_PLAYER_1))
+#define 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 GET_EMPTY_ELEMENT(i) ((i) == 0 ? EL_EMPTY_SPACE : \
+ EL_EMPTY_SPACE_1 + (i) - 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_NEW_FRAME(f, g) (IS_ANIMATED(g) && IS_NEW_DELAY(f, g))
#define IS_NEXT_FRAME(f, g) (IS_NEW_FRAME(f, g) && (f) > 0)
-#define IS_LOOP_SOUND(s) (sound_info[s].loop)
-#define IS_LOOP_MUSIC(s) (music_info[s].loop)
+#define IS_LOOP_SOUND(s) ((s) >= 0 && sound_info[s].loop)
+#define IS_LOOP_MUSIC(s) ((s) < 0 || music_info[s].loop)
#define IS_SPECIAL_GFX_ARG(a) ((a) >= 0 && (a) < NUM_SPECIAL_GFX_ARGS)
#define MAX_ANDROID_ELEMENTS 32
#define MAX_ANDROID_ELEMENTS_OLD 16 // (extended since version 4.2.0.0)
+#define MAX_ISO_DATE_LEN 10
+#define MAX_PLATFORM_TEXT_LEN 16
+#define MAX_VERSION_TEXT_LEN 16
+#define MAX_COUNTRY_CODE_LEN 2
+#define MAX_COUNTRY_NAME_LEN 64
+
// values for elements with content
#define MIN_ELEMENT_CONTENTS 1
#define STD_ELEMENT_CONTENTS 4
#define MAX_ELEMENT_CONTENTS 8
+#define MIN_MM_BALL_CONTENTS 1
+#define STD_MM_BALL_CONTENTS 8
+#define MAX_MM_BALL_CONTENTS 16
+
// values for initial player inventory
#define MIN_INITIAL_INVENTORY_SIZE 1
#define MAX_INITIAL_INVENTORY_SIZE 8
#define NUM_GROUP_ELEMENTS 32
#define EL_GROUP_END 655
-// ---------- end of custom elements section ----------------------------------
+// ---------- end of group elements section -----------------------------------
#define EL_UNKNOWN 656
#define EL_TRIGGER_ELEMENT 657
#define EL_MM_WOODEN_GRID_FIXED_4 (EL_MM_WOODEN_GRID_FIXED_START + 3)
#define EL_MM_WOODEN_GRID_FIXED_END EL_MM_WOODEN_GRID_FIXED_03
#define EL_MM_FUEL_EMPTY (EL_MM_START + 155)
-
-#define EL_MM_UNUSED_156 (EL_MM_START + 156)
-#define EL_MM_UNUSED_157 (EL_MM_START + 157)
-#define EL_MM_UNUSED_158 (EL_MM_START + 158)
-#define EL_MM_UNUSED_159 (EL_MM_START + 159)
+#define EL_MM_ENVELOPE_1 (EL_MM_START + 156)
+#define EL_MM_ENVELOPE_2 (EL_MM_START + 157)
+#define EL_MM_ENVELOPE_3 (EL_MM_START + 158)
+#define EL_MM_ENVELOPE_4 (EL_MM_START + 159)
#define EL_MM_END_1 (EL_MM_START + 159)
#define EL_MM_START_2 (EL_MM_START + 160)
#define EL_SPRING_LEFT 1215
#define EL_SPRING_RIGHT 1216
-#define NUM_FILE_ELEMENTS 1217
+// ---------- begin of empty space elements section ---------------------------
+#define EL_EMPTY_SPACE_START 1217
+
+#include "conf_emp.h" // include auto-generated data structure definitions
+
+#define NUM_EMPTY_SPACE_ELEMENTS 16
+#define NUM_EMPTY_ELEMENTS_ALL (NUM_EMPTY_SPACE_ELEMENTS + 1)
+#define EL_EMPTY_SPACE_END 1232
+// ---------- end of empty space elements section -----------------------------
+
+#define NUM_FILE_ELEMENTS 1233
// "real" (and therefore drawable) runtime elements
#define EL_EMC_SPRING_BUMPER_ACTIVE (EL_FIRST_RUNTIME_REAL + 71)
#define EL_MM_EXIT_OPENING (EL_FIRST_RUNTIME_REAL + 72)
#define EL_MM_EXIT_CLOSING (EL_FIRST_RUNTIME_REAL + 73)
-#define EL_MM_GRAY_BALL_OPENING (EL_FIRST_RUNTIME_REAL + 74)
-#define EL_MM_ICE_WALL_SHRINKING (EL_FIRST_RUNTIME_REAL + 75)
-#define EL_MM_AMOEBA_WALL_GROWING (EL_FIRST_RUNTIME_REAL + 76)
-#define EL_MM_PACMAN_EATING_RIGHT (EL_FIRST_RUNTIME_REAL + 77)
-#define EL_MM_PACMAN_EATING_UP (EL_FIRST_RUNTIME_REAL + 78)
-#define EL_MM_PACMAN_EATING_LEFT (EL_FIRST_RUNTIME_REAL + 79)
-#define EL_MM_PACMAN_EATING_DOWN (EL_FIRST_RUNTIME_REAL + 80)
-
-#define NUM_DRAWABLE_ELEMENTS (EL_FIRST_RUNTIME_REAL + 81)
+#define EL_MM_GRAY_BALL_ACTIVE (EL_FIRST_RUNTIME_REAL + 74)
+#define EL_MM_GRAY_BALL_OPENING (EL_FIRST_RUNTIME_REAL + 75)
+#define EL_MM_ICE_WALL_SHRINKING (EL_FIRST_RUNTIME_REAL + 76)
+#define EL_MM_AMOEBA_WALL_GROWING (EL_FIRST_RUNTIME_REAL + 77)
+#define EL_MM_PACMAN_EATING_RIGHT (EL_FIRST_RUNTIME_REAL + 78)
+#define EL_MM_PACMAN_EATING_UP (EL_FIRST_RUNTIME_REAL + 79)
+#define EL_MM_PACMAN_EATING_LEFT (EL_FIRST_RUNTIME_REAL + 80)
+#define EL_MM_PACMAN_EATING_DOWN (EL_FIRST_RUNTIME_REAL + 81)
+#define EL_MM_BOMB_ACTIVE (EL_FIRST_RUNTIME_REAL + 82)
+#define EL_DF_MINE_ACTIVE (EL_FIRST_RUNTIME_REAL + 83)
+
+#define NUM_DRAWABLE_ELEMENTS (EL_FIRST_RUNTIME_REAL + 84)
#define EL_MM_RUNTIME_START EL_MM_EXIT_OPENING
#define EL_MM_RUNTIME_END EL_MM_AMOEBA_WALL_GROWING
#define EL_MM_LIGHTBALL_RED (EL_FIRST_DUMMY + 21)
#define EL_MM_LIGHTBALL_BLUE (EL_FIRST_DUMMY + 22)
#define EL_MM_LIGHTBALL_YELLOW (EL_FIRST_DUMMY + 23)
-#define EL_MM_MASK_MCDUFFIN_RIGHT (EL_FIRST_DUMMY + 24)
-#define EL_MM_MASK_MCDUFFIN_UP (EL_FIRST_DUMMY + 25)
-#define EL_MM_MASK_MCDUFFIN_LEFT (EL_FIRST_DUMMY + 26)
-#define EL_MM_MASK_MCDUFFIN_DOWN (EL_FIRST_DUMMY + 27)
-#define EL_MM_MASK_GRID_1 (EL_FIRST_DUMMY + 28)
-#define EL_MM_MASK_GRID_2 (EL_FIRST_DUMMY + 29)
-#define EL_MM_MASK_GRID_3 (EL_FIRST_DUMMY + 30)
-#define EL_MM_MASK_GRID_4 (EL_FIRST_DUMMY + 31)
-#define EL_MM_MASK_RECTANGLE (EL_FIRST_DUMMY + 32)
-#define EL_MM_MASK_CIRCLE (EL_FIRST_DUMMY + 33)
-#define EL_DEFAULT (EL_FIRST_DUMMY + 34)
-#define EL_BD_DEFAULT (EL_FIRST_DUMMY + 35)
-#define EL_SP_DEFAULT (EL_FIRST_DUMMY + 36)
-#define EL_SB_DEFAULT (EL_FIRST_DUMMY + 37)
-#define EL_MM_DEFAULT (EL_FIRST_DUMMY + 38)
-#define EL_GRAPHIC_1 (EL_FIRST_DUMMY + 39)
-#define EL_GRAPHIC_2 (EL_FIRST_DUMMY + 40)
-#define EL_GRAPHIC_3 (EL_FIRST_DUMMY + 41)
-#define EL_GRAPHIC_4 (EL_FIRST_DUMMY + 42)
-#define EL_GRAPHIC_5 (EL_FIRST_DUMMY + 43)
-#define EL_GRAPHIC_6 (EL_FIRST_DUMMY + 44)
-#define EL_GRAPHIC_7 (EL_FIRST_DUMMY + 45)
-#define EL_GRAPHIC_8 (EL_FIRST_DUMMY + 46)
-
-#define EL_MM_DUMMY_START EL_MM_MASK_MCDUFFIN_RIGHT
-#define EL_MM_DUMMY_END EL_MM_MASK_CIRCLE
+#define EL_DEFAULT (EL_FIRST_DUMMY + 24)
+#define EL_BD_DEFAULT (EL_FIRST_DUMMY + 25)
+#define EL_SP_DEFAULT (EL_FIRST_DUMMY + 26)
+#define EL_SB_DEFAULT (EL_FIRST_DUMMY + 27)
+#define EL_MM_DEFAULT (EL_FIRST_DUMMY + 28)
+#define EL_GRAPHIC_1 (EL_FIRST_DUMMY + 29)
+#define EL_GRAPHIC_2 (EL_FIRST_DUMMY + 30)
+#define EL_GRAPHIC_3 (EL_FIRST_DUMMY + 31)
+#define EL_GRAPHIC_4 (EL_FIRST_DUMMY + 32)
+#define EL_GRAPHIC_5 (EL_FIRST_DUMMY + 33)
+#define EL_GRAPHIC_6 (EL_FIRST_DUMMY + 34)
+#define EL_GRAPHIC_7 (EL_FIRST_DUMMY + 35)
+#define EL_GRAPHIC_8 (EL_FIRST_DUMMY + 36)
// internal elements (only used for internal purposes like copying)
-#define EL_FIRST_INTERNAL (EL_FIRST_DUMMY + 47)
+#define EL_FIRST_INTERNAL (EL_FIRST_DUMMY + 37)
#define EL_INTERNAL_CLIPBOARD_CUSTOM (EL_FIRST_INTERNAL + 0)
#define EL_INTERNAL_CLIPBOARD_CHANGE (EL_FIRST_INTERNAL + 1)
#define EL_INTERNAL_CASCADE_CE_ACTIVE (EL_FIRST_INTERNAL + 29)
#define EL_INTERNAL_CASCADE_GE (EL_FIRST_INTERNAL + 30)
#define EL_INTERNAL_CASCADE_GE_ACTIVE (EL_FIRST_INTERNAL + 31)
-#define EL_INTERNAL_CASCADE_REF (EL_FIRST_INTERNAL + 32)
-#define EL_INTERNAL_CASCADE_REF_ACTIVE (EL_FIRST_INTERNAL + 33)
-#define EL_INTERNAL_CASCADE_USER (EL_FIRST_INTERNAL + 34)
-#define EL_INTERNAL_CASCADE_USER_ACTIVE (EL_FIRST_INTERNAL + 35)
-#define EL_INTERNAL_CASCADE_DYNAMIC (EL_FIRST_INTERNAL + 36)
-#define EL_INTERNAL_CASCADE_DYNAMIC_ACTIVE (EL_FIRST_INTERNAL + 37)
+#define EL_INTERNAL_CASCADE_ES (EL_FIRST_INTERNAL + 32)
+#define EL_INTERNAL_CASCADE_ES_ACTIVE (EL_FIRST_INTERNAL + 33)
+#define EL_INTERNAL_CASCADE_REF (EL_FIRST_INTERNAL + 34)
+#define EL_INTERNAL_CASCADE_REF_ACTIVE (EL_FIRST_INTERNAL + 35)
+#define EL_INTERNAL_CASCADE_USER (EL_FIRST_INTERNAL + 36)
+#define EL_INTERNAL_CASCADE_USER_ACTIVE (EL_FIRST_INTERNAL + 37)
+#define EL_INTERNAL_CASCADE_DYNAMIC (EL_FIRST_INTERNAL + 38)
+#define EL_INTERNAL_CASCADE_DYNAMIC_ACTIVE (EL_FIRST_INTERNAL + 39)
#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 + 37)
+#define EL_INTERNAL_END (EL_FIRST_INTERNAL + 39)
-#define MAX_NUM_ELEMENTS (EL_FIRST_INTERNAL + 38)
+#define MAX_NUM_ELEMENTS (EL_FIRST_INTERNAL + 40)
// values for graphics/sounds action types
enum
{
GFX_SPECIAL_ARG_DEFAULT = 0,
+ GFX_SPECIAL_ARG_LOADING_INITIAL,
GFX_SPECIAL_ARG_LOADING,
GFX_SPECIAL_ARG_TITLE_INITIAL,
GFX_SPECIAL_ARG_TITLE_INITIAL_1,
GFX_SPECIAL_ARG_LEVELS,
GFX_SPECIAL_ARG_LEVELNR,
GFX_SPECIAL_ARG_SCORES,
+ GFX_SPECIAL_ARG_SCOREINFO,
GFX_SPECIAL_ARG_EDITOR,
GFX_SPECIAL_ARG_INFO,
GFX_SPECIAL_ARG_SETUP,
GFX_SPECIAL_ARG_CRUMBLED,
GFX_SPECIAL_ARG_MAINONLY,
GFX_SPECIAL_ARG_NAMESONLY,
+ GFX_SPECIAL_ARG_SCORESONLY,
GFX_SPECIAL_ARG_TYPENAME,
GFX_SPECIAL_ARG_TYPENAMES,
GFX_SPECIAL_ARG_SUBMENU,
GFX_SPECIAL_ARG_SCORESNEW,
GFX_SPECIAL_ARG_NO_TITLE,
GFX_SPECIAL_ARG_FADING,
+ GFX_SPECIAL_ARG_RESTARTING,
GFX_SPECIAL_ARG_QUIT,
NUM_SPECIAL_GFX_ARGS
GFX_ARG_DELAY,
GFX_ARG_ANIM_MODE,
GFX_ARG_GLOBAL_SYNC,
+ GFX_ARG_GLOBAL_ANIM_SYNC,
GFX_ARG_CRUMBLED_LIKE,
GFX_ARG_DIGGABLE_LIKE,
GFX_ARG_BORDER_SIZE,
GFX_ARG_ACTIVE_YOFFSET,
GFX_ARG_PRESSED_XOFFSET,
GFX_ARG_PRESSED_YOFFSET,
+ GFX_ARG_STACKED_XFACTOR,
+ GFX_ARG_STACKED_YFACTOR,
+ GFX_ARG_STACKED_XOFFSET,
+ GFX_ARG_STACKED_YOFFSET,
NUM_GFX_ARGS
};
// values for game_status (must match special image configuration suffixes)
#define GAME_MODE_DEFAULT GFX_SPECIAL_ARG_DEFAULT
+#define GAME_MODE_LOADING_INITIAL GFX_SPECIAL_ARG_LOADING_INITIAL
#define GAME_MODE_LOADING GFX_SPECIAL_ARG_LOADING
#define GAME_MODE_TITLE_INITIAL GFX_SPECIAL_ARG_TITLE_INITIAL
#define GAME_MODE_TITLE_INITIAL_1 GFX_SPECIAL_ARG_TITLE_INITIAL_1
#define GAME_MODE_LEVELS GFX_SPECIAL_ARG_LEVELS
#define GAME_MODE_LEVELNR GFX_SPECIAL_ARG_LEVELNR
#define GAME_MODE_SCORES GFX_SPECIAL_ARG_SCORES
+#define GAME_MODE_SCOREINFO GFX_SPECIAL_ARG_SCOREINFO
#define GAME_MODE_EDITOR GFX_SPECIAL_ARG_EDITOR
#define GAME_MODE_INFO GFX_SPECIAL_ARG_INFO
#define GAME_MODE_SETUP GFX_SPECIAL_ARG_SETUP
#define GAME_MODE_PSEUDO_CRUMBLED GFX_SPECIAL_ARG_CRUMBLED
#define GAME_MODE_PSEUDO_MAINONLY GFX_SPECIAL_ARG_MAINONLY
#define GAME_MODE_PSEUDO_NAMESONLY GFX_SPECIAL_ARG_NAMESONLY
+#define GAME_MODE_PSEUDO_SCORESONLY GFX_SPECIAL_ARG_SCORESONLY
#define GAME_MODE_PSEUDO_TYPENAME GFX_SPECIAL_ARG_TYPENAME
#define GAME_MODE_PSEUDO_TYPENAMES GFX_SPECIAL_ARG_TYPENAMES
#define GAME_MODE_PSEUDO_SUBMENU GFX_SPECIAL_ARG_SUBMENU
#define GAME_MODE_PSEUDO_SCORESNEW GFX_SPECIAL_ARG_SCORESNEW
#define GAME_MODE_PSEUDO_NO_TITLE GFX_SPECIAL_ARG_NO_TITLE
#define GAME_MODE_PSEUDO_FADING GFX_SPECIAL_ARG_FADING
+#define GAME_MODE_PSEUDO_RESTARTING GFX_SPECIAL_ARG_RESTARTING
#define GAME_MODE_QUIT GFX_SPECIAL_ARG_QUIT
#define NUM_GAME_MODES NUM_SPECIAL_GFX_ARGS
// program information and versioning definitions
#define PROGRAM_VERSION_SUPER 4
#define PROGRAM_VERSION_MAJOR 3
-#define PROGRAM_VERSION_MINOR 1
-#define PROGRAM_VERSION_PATCH 0
+#define PROGRAM_VERSION_MINOR 5
+#define PROGRAM_VERSION_PATCH 5
#define PROGRAM_VERSION_EXTRA ""
#define PROGRAM_TITLE_STRING "Rocks'n'Diamonds"
#define PROGRAM_AUTHOR_STRING "Holger Schemel"
#define PROGRAM_EMAIL_STRING "info@artsoft.org"
#define PROGRAM_WEBSITE_STRING "https://www.artsoft.org/"
-#define PROGRAM_COPYRIGHT_STRING "Copyright \xa9""1995-2021 by Holger Schemel"
+#define PROGRAM_COPYRIGHT_STRING "1995-2023 by Holger Schemel"
#define PROGRAM_COMPANY_STRING "A Game by Artsoft Entertainment"
-#define PROGRAM_ICON_FILENAME "RocksIcon32x32.png"
+#define PROGRAM_ICON_FILENAME "icons/icon.png"
#define COOKIE_PREFIX "ROCKSNDIAMONDS"
struct MenuPosInfo insert_solution;
struct MenuPosInfo play_solution;
+ struct MenuPosInfo levelset_info;
struct MenuPosInfo switch_ecs_aga;
};
struct MenuSetupButtonInfo button;
};
+struct MenuScoresButtonInfo
+{
+ struct MenuPosInfo prev_level;
+ struct MenuPosInfo next_level;
+ struct MenuPosInfo prev_score;
+ struct MenuPosInfo next_score;
+ struct MenuPosInfo play_tape;
+};
+
+struct MenuScoresInfo
+{
+ struct MenuScoresButtonInfo button;
+};
+
struct TitleFadingInfo
{
int fade_mode;
struct InitInfo
{
+ struct MenuPosInfo busy_initial;
struct MenuPosInfo busy;
+ struct MenuPosInfo busy_playfield;
};
struct MenuInfo
int list_size[NUM_SPECIAL_GFX_ARGS];
int list_size_info[NUM_SPECIAL_GFX_INFO_ARGS];
+ int list_entry_size_info[NUM_SPECIAL_GFX_INFO_ARGS];
+ int tile_size_info[NUM_SPECIAL_GFX_INFO_ARGS];
int left_spacing[NUM_SPECIAL_GFX_ARGS];
int left_spacing_info[NUM_SPECIAL_GFX_INFO_ARGS];
int left_spacing_setup[NUM_SPECIAL_GFX_SETUP_ARGS];
+ int middle_spacing_info[NUM_SPECIAL_GFX_INFO_ARGS];
int right_spacing[NUM_SPECIAL_GFX_ARGS];
int right_spacing_info[NUM_SPECIAL_GFX_INFO_ARGS];
int right_spacing_setup[NUM_SPECIAL_GFX_SETUP_ARGS];
struct MenuMainInfo main;
struct MenuSetupInfo setup;
+ struct MenuScoresInfo scores;
};
struct DoorInfo
char name[MAX_PLAYER_NAME_LEN + 1];
int score;
int time; // time (in frames) or steps played
+
+ // additional score information for score info screen
+ int id;
+ char tape_date[MAX_ISO_DATE_LEN + 1];
+ char platform[MAX_PLATFORM_TEXT_LEN + 1];
+ char version[MAX_VERSION_TEXT_LEN + 1];
+ char country_code[MAX_COUNTRY_CODE_LEN + 1];
+ char country_name[MAX_COUNTRY_NAME_LEN + 1];
};
struct ScoreInfo
int num_entries;
int last_added;
int last_added_local;
+ int last_level_nr;
+ int last_entry_nr;
+ int next_level_nr;
boolean updated;
boolean uploaded;
+ boolean tape_downloaded;
boolean force_last_added;
+ boolean continue_playing;
+ boolean continue_on_return;
struct ScoreEntry entry[MAX_SCORE_ENTRIES];
};
int mm_time_ball;
int mm_time_block;
+ int num_mm_ball_contents;
+ int mm_ball_choice_mode;
+ int mm_ball_content[MAX_MM_BALL_CONTENTS];
+ boolean rotate_mm_ball_content;
+ boolean explode_mm_ball;
+
// ('int' instead of 'boolean' because used as selectbox value in editor)
int use_step_counter; // count steps instead of seconds for level
int anim_mode;
boolean anim_global_sync;
+ boolean anim_global_anim_sync;
int crumbled_like; // element for cloning crumble graphics
int diggable_like; // element for cloning digging graphics
int pressed_xoffset;
int pressed_yoffset;
+ int stacked_xfactor;
+ int stacked_yfactor;
+ int stacked_xoffset;
+ int stacked_yoffset;
+
boolean use_image_size; // use image size as default width and height
};
boolean is_sound;
- struct MusicFileInfo *next;
+ struct MusicFileInfo *prev, *next;
};
struct ElementActionInfo
extern Bitmap *bitmap_db_field;
-extern Bitmap *bitmap_db_panel;
extern Bitmap *bitmap_db_door_1;
extern Bitmap *bitmap_db_door_2;
extern Bitmap *bitmap_db_store_1;
extern int game_status;
extern int game_status_last_screen;
extern boolean level_editor_test_game;
+extern boolean score_info_tape_play;
extern boolean network_playing;
extern int key_joystick_mapping;
extern int GfxRandom[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern int GfxRandomStatic[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern int GfxElement[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
+extern int GfxElementEmpty[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern int GfxAction[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern int GfxDir[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern int GfxRedraw[MAX_LEV_FIELDX][MAX_LEV_FIELDY];
extern SetupFileHash *graphic_token_hash;
extern SetupFileHash *font_token_hash;
extern SetupFileHash *hide_setup_hash;
+extern SetupFileHash *anim_url_hash;
extern struct ConfigTypeInfo image_config_suffix[];
extern struct ConfigTypeInfo sound_config_suffix[];
extern struct ConfigTypeInfo music_config_suffix[];