X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Feditor.c;h=b3304f7befcbc15ad8ba4f598b80937dcee33189;hb=edaa850fd2d2cae7ec31961fae3d56487e710c71;hp=093b229083d6f4e3539ebfd28ccd0559718e21c2;hpb=1fc11ecd0789cf873639c9bbbff6f72656abac08;p=rocksndiamonds.git diff --git a/src/editor.c b/src/editor.c index 093b2290..b3304f7b 100644 --- a/src/editor.c +++ b/src/editor.c @@ -4,7 +4,7 @@ // (c) 1995-2014 by Artsoft Entertainment // Holger Schemel // info@artsoft.org -// http://www.artsoft.org/ +// https://www.artsoft.org/ // ---------------------------------------------------------------------------- // editor.c // ============================================================================ @@ -99,6 +99,12 @@ #define ED_SETTINGS_LEVEL_TABS_X (editor.settings.tabs.x) #define ED_SETTINGS_LEVEL_TABS_Y (editor.settings.tabs.y) +#define ED_SETTINGS_ENGINE_TABS_X (editor.settings.tabs.x) +#define ED_SETTINGS_ENGINE_TABS_Y (editor.settings.tabs.y + \ + ED_TABBUTTON_YSIZE + \ + ED_GADGET_TINY_DISTANCE + \ + ED_TAB_BAR_HEIGHT + \ + ED_GADGET_TEXT_DISTANCE) #define ED_SETTINGS_ELEMENT_TABS_X (editor.settings.tabs.x) #define ED_SETTINGS_ELEMENT_TABS_Y (editor.settings.tabs.y + \ editor.settings.tabs.yoffset2) @@ -117,6 +123,17 @@ ED_SETTINGS_TABS_YOFFSET + \ getFontHeight(FONT_TEXT_1) + \ ED_GADGET_TEXT_DISTANCE) +#define ED_ENGINE_TABS_XSTART (ED_SETTINGS_ENGINE_TABS_X) +#define ED_ENGINE_TABS_YSTART (ED_SETTINGS_ENGINE_TABS_Y) +#define ED_ENGINE_SETTINGS_XSTART (ED_SETTINGS_ENGINE_TABS_X + \ + ED_SETTINGS_TABS_XOFFSET) +#define ED_ENGINE_SETTINGS_YSTART (ED_SETTINGS_ENGINE_TABS_Y + \ + ED_TABBUTTON_YSIZE + \ + ED_GADGET_TINY_DISTANCE + \ + ED_TAB_BAR_HEIGHT + \ + ED_SETTINGS_TABS_YOFFSET + \ + getFontHeight(FONT_TEXT_1) + \ + ED_GADGET_TEXT_DISTANCE) #define ED_ELEMENT_TABS_XSTART (ED_SETTINGS_ELEMENT_TABS_X) #define ED_ELEMENT_TABS_YSTART (ED_SETTINGS_ELEMENT_TABS_Y) #define ED_ELEMENT_SETTINGS_XSTART (ED_SETTINGS_ELEMENT_TABS_X + \ @@ -137,10 +154,14 @@ #define ED_POS_LEVEL_TABS_LAST (2 * ED_POS_RANGE - 1) #define ED_POS_LEVEL_SETTINGS_FIRST (2 * ED_POS_RANGE) #define ED_POS_LEVEL_SETTINGS_LAST (3 * ED_POS_RANGE - 1) -#define ED_POS_ELEMENT_TABS_FIRST (3 * ED_POS_RANGE) -#define ED_POS_ELEMENT_TABS_LAST (4 * ED_POS_RANGE - 1) -#define ED_POS_ELEMENT_SETTINGS_FIRST (4 * ED_POS_RANGE) -#define ED_POS_ELEMENT_SETTINGS_LAST (5 * ED_POS_RANGE - 1) +#define ED_POS_ENGINE_TABS_FIRST (3 * ED_POS_RANGE) +#define ED_POS_ENGINE_TABS_LAST (4 * ED_POS_RANGE - 1) +#define ED_POS_ENGINE_SETTINGS_FIRST (4 * ED_POS_RANGE) +#define ED_POS_ENGINE_SETTINGS_LAST (5 * ED_POS_RANGE - 1) +#define ED_POS_ELEMENT_TABS_FIRST (5 * ED_POS_RANGE) +#define ED_POS_ELEMENT_TABS_LAST (6 * ED_POS_RANGE - 1) +#define ED_POS_ELEMENT_SETTINGS_FIRST (6 * ED_POS_RANGE) +#define ED_POS_ELEMENT_SETTINGS_LAST (7 * ED_POS_RANGE - 1) #define ED_LEVEL_TABS_XPOS(n) (ED_POS_LEVEL_TABS_FIRST + (n)) #define ED_LEVEL_TABS_YPOS(n) (ED_POS_LEVEL_TABS_FIRST + (n)) @@ -148,6 +169,12 @@ #define ED_LEVEL_SETTINGS_XPOS(n) (ED_POS_LEVEL_SETTINGS_FIRST + (n)) #define ED_LEVEL_SETTINGS_YPOS(n) (ED_POS_LEVEL_SETTINGS_FIRST + (n)) +#define ED_ENGINE_TABS_XPOS(n) (ED_POS_ENGINE_TABS_FIRST + (n)) +#define ED_ENGINE_TABS_YPOS(n) (ED_POS_ENGINE_TABS_FIRST + (n)) + +#define ED_ENGINE_SETTINGS_XPOS(n) (ED_POS_ENGINE_SETTINGS_FIRST + (n)) +#define ED_ENGINE_SETTINGS_YPOS(n) (ED_POS_ENGINE_SETTINGS_FIRST + (n)) + #define ED_ELEMENT_TABS_XPOS(n) (ED_POS_ELEMENT_TABS_FIRST + (n)) #define ED_ELEMENT_TABS_YPOS(n) (ED_POS_ELEMENT_TABS_FIRST + (n)) @@ -158,6 +185,10 @@ (n) <= ED_POS_LEVEL_TABS_LAST) #define IS_POS_LEVEL_SETTINGS(n) ((n) >= ED_POS_LEVEL_SETTINGS_FIRST && \ (n) <= ED_POS_LEVEL_SETTINGS_LAST) +#define IS_POS_ENGINE_TABS(n) ((n) >= ED_POS_ENGINE_TABS_FIRST && \ + (n) <= ED_POS_ENGINE_TABS_LAST) +#define IS_POS_ENGINE_SETTINGS(n) ((n) >= ED_POS_ENGINE_SETTINGS_FIRST && \ + (n) <= ED_POS_ENGINE_SETTINGS_LAST) #define IS_POS_ELEMENT_TABS(n) ((n) >= ED_POS_ELEMENT_TABS_FIRST && \ (n) <= ED_POS_ELEMENT_TABS_LAST) #define IS_POS_ELEMENT_SETTINGS(n) ((n) >= ED_POS_ELEMENT_SETTINGS_FIRST && \ @@ -165,6 +196,8 @@ #define ED_LEVEL_TABS_LINE(n) ((n) - ED_POS_LEVEL_TABS_FIRST) #define ED_LEVEL_SETTINGS_LINE(n) ((n) - ED_POS_LEVEL_SETTINGS_FIRST) +#define ED_ENGINE_TABS_LINE(n) ((n) - ED_POS_ENGINE_TABS_FIRST) +#define ED_ENGINE_SETTINGS_LINE(n) ((n) - ED_POS_ENGINE_SETTINGS_FIRST) #define ED_ELEMENT_TABS_LINE(n) ((n) - ED_POS_ELEMENT_TABS_FIRST) #define ED_ELEMENT_SETTINGS_LINE(n) ((n) - ED_POS_ELEMENT_SETTINGS_FIRST) @@ -178,6 +211,16 @@ #define ED_LEVEL_SETTINGS_Y(n) (ED_LEVEL_SETTINGS_YSTART + \ (n) * ED_SETTINGS_YOFFSET) +#define ED_ENGINE_TABS_X(n) (ED_ENGINE_TABS_XSTART + \ + (n) * ED_SETTINGS_TABS_XOFFSET) +#define ED_ENGINE_TABS_Y(n) (ED_ENGINE_TABS_YSTART + \ + (n) * ED_SETTINGS_TABS_YOFFSET) + +#define ED_ENGINE_SETTINGS_X(n) (ED_ENGINE_SETTINGS_XSTART + \ + (n) * ED_SETTINGS_XOFFSET) +#define ED_ENGINE_SETTINGS_Y(n) (ED_ENGINE_SETTINGS_YSTART + \ + (n) * ED_SETTINGS_YOFFSET) + #define ED_ELEMENT_TABS_X(n) (ED_ELEMENT_TABS_XSTART + \ (n) * ED_SETTINGS_TABS_XOFFSET) #define ED_ELEMENT_TABS_Y(n) (ED_ELEMENT_TABS_YSTART + \ @@ -198,6 +241,16 @@ #define ED_POS_TO_LEVEL_SETTINGS_Y(n) \ (ED_LEVEL_SETTINGS_Y(ED_LEVEL_SETTINGS_LINE(n))) +#define ED_POS_TO_ENGINE_TABS_X(n) \ + (ED_ENGINE_TABS_X(ED_ENGINE_TABS_LINE(n))) +#define ED_POS_TO_ENGINE_TABS_Y(n) \ + (ED_ENGINE_TABS_Y(ED_ENGINE_TABS_LINE(n))) + +#define ED_POS_TO_ENGINE_SETTINGS_X(n) \ + (ED_ENGINE_SETTINGS_X(ED_ENGINE_SETTINGS_LINE(n))) +#define ED_POS_TO_ENGINE_SETTINGS_Y(n) \ + (ED_ENGINE_SETTINGS_Y(ED_ENGINE_SETTINGS_LINE(n))) + #define ED_POS_TO_ELEMENT_TABS_X(n) \ (ED_ELEMENT_TABS_X(ED_ELEMENT_TABS_LINE(n))) #define ED_POS_TO_ELEMENT_TABS_Y(n) \ @@ -212,6 +265,10 @@ ED_POS_TO_LEVEL_TABS_X(n) : \ IS_POS_LEVEL_SETTINGS(n) ? \ ED_POS_TO_LEVEL_SETTINGS_X(n) : \ + IS_POS_ENGINE_TABS(n) ? \ + ED_POS_TO_ENGINE_TABS_X(n) : \ + IS_POS_ENGINE_SETTINGS(n) ? \ + ED_POS_TO_ENGINE_SETTINGS_X(n) : \ IS_POS_ELEMENT_TABS(n) ? \ ED_POS_TO_ELEMENT_TABS_X(n) : \ IS_POS_ELEMENT_SETTINGS(n) ? \ @@ -220,6 +277,10 @@ ED_POS_TO_LEVEL_TABS_Y(n) : \ IS_POS_LEVEL_SETTINGS(n) ? \ ED_POS_TO_LEVEL_SETTINGS_Y(n) : \ + IS_POS_ENGINE_TABS(n) ? \ + ED_POS_TO_ENGINE_TABS_Y(n) : \ + IS_POS_ENGINE_SETTINGS(n) ? \ + ED_POS_TO_ENGINE_SETTINGS_Y(n) : \ IS_POS_ELEMENT_TABS(n) ? \ ED_POS_TO_ELEMENT_TABS_Y(n) : \ IS_POS_ELEMENT_SETTINGS(n) ? \ @@ -382,7 +443,7 @@ enum GADGET_ID_PICK_ELEMENT, GADGET_ID_UNDO, - GADGET_ID_INFO, + GADGET_ID_CONF, GADGET_ID_SAVE, GADGET_ID_CLEAR, GADGET_ID_TEST, @@ -429,6 +490,24 @@ enum GADGET_ID_LEVELSET_NUM_LEVELS_DOWN, GADGET_ID_LEVELSET_NUM_LEVELS_TEXT, GADGET_ID_LEVELSET_NUM_LEVELS_UP, + GADGET_ID_BD_CYCLE_DELAY_MS_DOWN, + GADGET_ID_BD_CYCLE_DELAY_MS_TEXT, + GADGET_ID_BD_CYCLE_DELAY_MS_UP, + GADGET_ID_BD_CYCLE_DELAY_C64_DOWN, + GADGET_ID_BD_CYCLE_DELAY_C64_TEXT, + GADGET_ID_BD_CYCLE_DELAY_C64_UP, + GADGET_ID_BD_HATCHING_DELAY_CYCLES_DOWN, + GADGET_ID_BD_HATCHING_DELAY_CYCLES_TEXT, + GADGET_ID_BD_HATCHING_DELAY_CYCLES_UP, + GADGET_ID_BD_HATCHING_DELAY_SECONDS_DOWN, + GADGET_ID_BD_HATCHING_DELAY_SECONDS_TEXT, + GADGET_ID_BD_HATCHING_DELAY_SECONDS_UP, + GADGET_ID_BD_PUSHING_PROB_DOWN, + GADGET_ID_BD_PUSHING_PROB_TEXT, + GADGET_ID_BD_PUSHING_PROB_UP, + GADGET_ID_BD_PUSHING_PROB_WITH_SWEET_DOWN, + GADGET_ID_BD_PUSHING_PROB_WITH_SWEET_TEXT, + GADGET_ID_BD_PUSHING_PROB_WITH_SWEET_UP, GADGET_ID_ELEMENT_VALUE1_DOWN, GADGET_ID_ELEMENT_VALUE1_TEXT, GADGET_ID_ELEMENT_VALUE1_UP, @@ -459,6 +538,9 @@ enum GADGET_ID_INVENTORY_SIZE_DOWN, GADGET_ID_INVENTORY_SIZE_TEXT, GADGET_ID_INVENTORY_SIZE_UP, + GADGET_ID_MM_BALL_CONTENT_DOWN, + GADGET_ID_MM_BALL_CONTENT_TEXT, + GADGET_ID_MM_BALL_CONTENT_UP, GADGET_ID_CUSTOM_SCORE_DOWN, GADGET_ID_CUSTOM_SCORE_TEXT, GADGET_ID_CUSTOM_SCORE_UP, @@ -489,6 +571,12 @@ enum GADGET_ID_MOVE_DELAY_RND_DOWN, GADGET_ID_MOVE_DELAY_RND_TEXT, GADGET_ID_MOVE_DELAY_RND_UP, + GADGET_ID_STEP_DELAY_FIX_DOWN, + GADGET_ID_STEP_DELAY_FIX_TEXT, + GADGET_ID_STEP_DELAY_FIX_UP, + GADGET_ID_STEP_DELAY_RND_DOWN, + GADGET_ID_STEP_DELAY_RND_TEXT, + GADGET_ID_STEP_DELAY_RND_UP, GADGET_ID_EXPLOSION_DELAY_DOWN, GADGET_ID_EXPLOSION_DELAY_TEXT, GADGET_ID_EXPLOSION_DELAY_UP, @@ -529,10 +617,52 @@ enum GADGET_ID_MAGIC_BALL_CONTENT_7, GADGET_ID_ANDROID_CONTENT, GADGET_ID_AMOEBA_CONTENT, + GADGET_ID_BD_SNAP_ELEMENT, + GADGET_ID_BD_MAGIC_WALL_DIAMOND_TO, + GADGET_ID_BD_MAGIC_WALL_ROCK_TO, + GADGET_ID_BD_MAGIC_WALL_MEGA_ROCK_TO, + GADGET_ID_BD_MAGIC_WALL_NUT_TO, + GADGET_ID_BD_MAGIC_WALL_NITRO_PACK_TO, + GADGET_ID_BD_MAGIC_WALL_FLYING_DIAMOND_TO, + GADGET_ID_BD_MAGIC_WALL_FLYING_ROCK_TO, + GADGET_ID_BD_AMOEBA_CONTENT_TOO_BIG, + GADGET_ID_BD_AMOEBA_CONTENT_ENCLOSED, + GADGET_ID_BD_AMOEBA_2_CONTENT_TOO_BIG, + GADGET_ID_BD_AMOEBA_2_CONTENT_ENCLOSED, + GADGET_ID_BD_AMOEBA_2_CONTENT_EXPLODING, + GADGET_ID_BD_AMOEBA_2_CONTENT_LOOKS_LIKE, + GADGET_ID_BD_SLIME_EATS_ELEMENT_1, + GADGET_ID_BD_SLIME_CONVERTS_TO_ELEMENT_1, + GADGET_ID_BD_SLIME_EATS_ELEMENT_2, + GADGET_ID_BD_SLIME_CONVERTS_TO_ELEMENT_2, + GADGET_ID_BD_SLIME_EATS_ELEMENT_3, + GADGET_ID_BD_SLIME_CONVERTS_TO_ELEMENT_3, + GADGET_ID_BD_ACID_EATS_ELEMENT, + GADGET_ID_BD_ACID_TURNS_TO_ELEMENT, + GADGET_ID_BD_BITER_EATS_ELEMENT, + GADGET_ID_BD_BLADDER_CONVERTS_BY_ELEMENT, + GADGET_ID_BD_NUT_CONTENT, + GADGET_ID_BD_EXPANDING_WALL_LOOKS_LIKE, + GADGET_ID_BD_SAND_LOOKS_LIKE, + GADGET_ID_BD_ROCK_TURNS_TO_ON_FALLING, + GADGET_ID_BD_ROCK_TURNS_TO_ON_IMPACT, + GADGET_ID_BD_DIAMOND_TURNS_TO_ON_FALLING, + GADGET_ID_BD_DIAMOND_TURNS_TO_ON_IMPACT, + GADGET_ID_BD_FIREFLY_EXPLODES_TO, + GADGET_ID_BD_FIREFLY_2_EXPLODES_TO, + GADGET_ID_BD_BUTTERFLY_EXPLODES_TO, + GADGET_ID_BD_BUTTERFLY_2_EXPLODES_TO, + GADGET_ID_BD_STONEFLY_EXPLODES_TO, + GADGET_ID_BD_DRAGONFLY_EXPLODES_TO, + GADGET_ID_BD_DIAMOND_BIRTH_TURNS_TO, + GADGET_ID_BD_BOMB_EXPLOSION_TURNS_TO, + GADGET_ID_BD_NITRO_EXPLOSION_TURNS_TO, + GADGET_ID_BD_EXPLOSION_TURNS_TO, GADGET_ID_START_ELEMENT, GADGET_ID_ARTWORK_ELEMENT, GADGET_ID_EXPLOSION_ELEMENT, GADGET_ID_INVENTORY_CONTENT, + GADGET_ID_MM_BALL_CONTENT, GADGET_ID_CUSTOM_GRAPHIC, GADGET_ID_CUSTOM_CONTENT, GADGET_ID_CUSTOM_MOVE_ENTER, @@ -550,6 +680,13 @@ enum GADGET_ID_LEVEL_AUTHOR, GADGET_ID_LEVELSET_NAME, GADGET_ID_LEVELSET_AUTHOR, + GADGET_ID_BD_COLOR_TEXT_B, + GADGET_ID_BD_COLOR_TEXT_0, + GADGET_ID_BD_COLOR_TEXT_1, + GADGET_ID_BD_COLOR_TEXT_2, + GADGET_ID_BD_COLOR_TEXT_3, + GADGET_ID_BD_COLOR_TEXT_4, + GADGET_ID_BD_COLOR_TEXT_5, GADGET_ID_ELEMENT_NAME, // text area identifiers @@ -559,10 +696,22 @@ enum // selectbox identifiers GADGET_ID_TIME_OR_STEPS, + GADGET_ID_TIME_SCORE_BASE, GADGET_ID_GAME_ENGINE_TYPE, GADGET_ID_LEVELSET_SAVE_MODE, + GADGET_ID_BD_SCHEDULING_TYPE, + GADGET_ID_BD_COLOR_TYPE, + GADGET_ID_BD_COLOR_C64_B, + GADGET_ID_BD_COLOR_C64_0, + GADGET_ID_BD_COLOR_C64_1, + GADGET_ID_BD_COLOR_C64_2, + GADGET_ID_BD_COLOR_C64_3, + GADGET_ID_BD_COLOR_C64_4, + GADGET_ID_BD_COLOR_C64_5, GADGET_ID_WIND_DIRECTION, GADGET_ID_PLAYER_SPEED, + GADGET_ID_BD_GRAVITY_DIRECTION, + GADGET_ID_MM_BALL_CHOICE_MODE, GADGET_ID_CUSTOM_WALK_TO_ACTION, GADGET_ID_CUSTOM_EXPLOSION_TYPE, GADGET_ID_CUSTOM_DEADLINESS, @@ -591,9 +740,12 @@ enum // textbutton identifiers - GADGET_ID_LEVELINFO_LEVEL, - GADGET_ID_LEVELINFO_LEVELSET, - GADGET_ID_LEVELINFO_EDITOR, + GADGET_ID_LEVELCONFIG_LEVEL, + GADGET_ID_LEVELCONFIG_LEVELSET, + GADGET_ID_LEVELCONFIG_EDITOR, + GADGET_ID_LEVELCONFIG_ENGINE, + GADGET_ID_ENGINECONFIG_CONFIG, + GADGET_ID_ENGINECONFIG_COLORS, GADGET_ID_PROPERTIES_INFO, GADGET_ID_PROPERTIES_CONFIG, GADGET_ID_PROPERTIES_CONFIG_1, @@ -604,6 +756,7 @@ enum GADGET_ID_SAVE_LEVELSET, GADGET_ID_ADD_CHANGE_PAGE, GADGET_ID_DEL_CHANGE_PAGE, + GADGET_ID_BD_SET_RANDOM_COLORS, // graphicbutton identifiers @@ -630,11 +783,17 @@ enum // checkbuttons/radiobuttons for level/element properties GADGET_ID_AUTO_COUNT_GEMS, + GADGET_ID_RATE_TIME_OVER_SCORE, GADGET_ID_USE_LEVELSET_ARTWORK, GADGET_ID_COPY_LEVEL_TEMPLATE, GADGET_ID_RANDOM_PERCENTAGE, GADGET_ID_RANDOM_QUANTITY, GADGET_ID_RANDOM_RESTRICTED, + GADGET_ID_BD_INTERMISSION, + GADGET_ID_BD_PAL_TIMING, + GADGET_ID_BD_LINE_SHIFTING_BORDERS, + GADGET_ID_BD_SCAN_FIRST_AND_LAST_ROW, + GADGET_ID_BD_SHORT_EXPLOSIONS, GADGET_ID_STICK_ELEMENT, GADGET_ID_EM_SLIPPERY_GEMS, GADGET_ID_EM_EXPLODES_BY_FIRE, @@ -642,12 +801,14 @@ enum GADGET_ID_USE_TIME_ORB_BUG, GADGET_ID_USE_LIFE_BUGS, GADGET_ID_RANDOM_BALL_CONTENT, - GADGET_ID_INITIAL_BALL_STATE, + GADGET_ID_INITIAL_BALL_ACTIVE, GADGET_ID_GROW_INTO_DIGGABLE, GADGET_ID_SB_FIELDS_NEEDED, GADGET_ID_SB_OBJECTS_NEEDED, GADGET_ID_AUTO_EXIT_SOKOBAN, GADGET_ID_SOLVED_BY_ONE_PLAYER, + GADGET_ID_FINISH_DIG_COLLECT, + GADGET_ID_KEEP_WALKABLE_CE, GADGET_ID_CONTINUOUS_SNAPPING, GADGET_ID_BLOCK_SNAP_FIELD, GADGET_ID_BLOCK_LAST_FIELD, @@ -664,6 +825,32 @@ enum GADGET_ID_CAN_FALL_INTO_ACID, GADGET_ID_CAN_MOVE_INTO_ACID, GADGET_ID_DONT_COLLIDE_WITH, + GADGET_ID_BD_DIAGONAL_MOVEMENTS, + GADGET_ID_BD_TOPMOST_PLAYER_ACTIVE, + GADGET_ID_BD_PUSH_MEGA_ROCK_WITH_SWEET, + GADGET_ID_BD_MAGIC_WALL_ZERO_INFINITE, + GADGET_ID_BD_MAGIC_WALL_WAIT_HATCHING, + GADGET_ID_BD_MAGIC_WALL_STOPS_AMOEBA, + GADGET_ID_BD_MAGIC_WALL_BREAK_SCAN, + GADGET_ID_BD_AMOEBA_WAIT_FOR_HATCHING, + GADGET_ID_BD_AMOEBA_START_IMMEDIATELY, + GADGET_ID_BD_AMOEBA_2_EXPLODE_BY_AMOEBA, + GADGET_ID_BD_VOODOO_COLLECTS_DIAMONDS, + GADGET_ID_BD_VOODOO_HURT_KILLS_PLAYER, + GADGET_ID_BD_VOODOO_DIES_BY_ROCK, + GADGET_ID_BD_VOODOO_VANISH_BY_EXPLOSION, + GADGET_ID_BD_SLIME_IS_PREDICTABLE, + GADGET_ID_BD_CHANGE_EXPANDING_WALL, + GADGET_ID_BD_REPLICATORS_ACTIVE, + GADGET_ID_BD_CONVEYOR_BELTS_ACTIVE, + GADGET_ID_BD_CONVEYOR_BELTS_CHANGED, + GADGET_ID_BD_WATER_CANNOT_FLOW_DOWN, + GADGET_ID_BD_HAMMER_WALLS_REAPPEAR, + GADGET_ID_BD_INFINITE_ROCKETS, + GADGET_ID_BD_CREATURES_START_BACKWARDS, + GADGET_ID_BD_CREATURES_TURN_ON_HATCHING, + GADGET_ID_BD_GRAVITY_SWITCH_ACTIVE, + GADGET_ID_BD_GRAVITY_AFFECTS_ALL, GADGET_ID_ENVELOPE_AUTOWRAP, GADGET_ID_ENVELOPE_CENTERED, GADGET_ID_MM_LASER_RED, @@ -672,6 +859,8 @@ enum GADGET_ID_DF_LASER_RED, GADGET_ID_DF_LASER_GREEN, GADGET_ID_DF_LASER_BLUE, + GADGET_ID_ROTATE_MM_BALL_CONTENT, + GADGET_ID_EXPLODE_MM_BALL, GADGET_ID_CUSTOM_INDESTRUCTIBLE, GADGET_ID_CUSTOM_CAN_EXPLODE, GADGET_ID_CUSTOM_EXPLODE_FIRE, @@ -730,6 +919,12 @@ enum ED_COUNTER_ID_LEVEL_RANDOM_SEED, ED_COUNTER_ID_LEVELSET_NUM_LEVELS, ED_COUNTER_ID_LEVEL_RANDOM, + ED_COUNTER_ID_BD_CYCLE_DELAY_MS, + ED_COUNTER_ID_BD_CYCLE_DELAY_C64, + ED_COUNTER_ID_BD_HATCHING_DELAY_CYCLES, + ED_COUNTER_ID_BD_HATCHING_DELAY_SECONDS, + ED_COUNTER_ID_BD_PUSHING_PROB, + ED_COUNTER_ID_BD_PUSHING_PROB_WITH_SWEET, ED_COUNTER_ID_ELEMENT_VALUE1, ED_COUNTER_ID_ELEMENT_VALUE2, ED_COUNTER_ID_ELEMENT_VALUE3, @@ -740,6 +935,7 @@ enum ED_COUNTER_ID_ENVELOPE_XSIZE, ED_COUNTER_ID_ENVELOPE_YSIZE, ED_COUNTER_ID_INVENTORY_SIZE, + ED_COUNTER_ID_MM_BALL_CONTENT, ED_COUNTER_ID_CUSTOM_SCORE, ED_COUNTER_ID_CUSTOM_GEMCOUNT, ED_COUNTER_ID_CUSTOM_VALUE_FIX, @@ -750,6 +946,8 @@ enum ED_COUNTER_ID_DROP_DELAY_RND, ED_COUNTER_ID_MOVE_DELAY_FIX, ED_COUNTER_ID_MOVE_DELAY_RND, + ED_COUNTER_ID_STEP_DELAY_FIX, + ED_COUNTER_ID_STEP_DELAY_RND, ED_COUNTER_ID_EXPLOSION_DELAY, ED_COUNTER_ID_IGNITION_DELAY, ED_COUNTER_ID_GROUP_CONTENT, @@ -813,6 +1011,13 @@ enum ED_TEXTINPUT_ID_LEVEL_AUTHOR, ED_TEXTINPUT_ID_LEVELSET_NAME, ED_TEXTINPUT_ID_LEVELSET_AUTHOR, + ED_TEXTINPUT_ID_BD_COLOR_TEXT_B, + ED_TEXTINPUT_ID_BD_COLOR_TEXT_0, + ED_TEXTINPUT_ID_BD_COLOR_TEXT_1, + ED_TEXTINPUT_ID_BD_COLOR_TEXT_2, + ED_TEXTINPUT_ID_BD_COLOR_TEXT_3, + ED_TEXTINPUT_ID_BD_COLOR_TEXT_4, + ED_TEXTINPUT_ID_BD_COLOR_TEXT_5, ED_TEXTINPUT_ID_ELEMENT_NAME, ED_NUM_TEXTINPUT @@ -824,6 +1029,9 @@ enum #define ED_TEXTINPUT_ID_LEVELSET_FIRST ED_TEXTINPUT_ID_LEVELSET_NAME #define ED_TEXTINPUT_ID_LEVELSET_LAST ED_TEXTINPUT_ID_LEVELSET_AUTHOR +#define ED_TEXTINPUT_ID_COLORS_FIRST ED_TEXTINPUT_ID_BD_COLOR_TEXT_B +#define ED_TEXTINPUT_ID_COLORS_LAST ED_TEXTINPUT_ID_BD_COLOR_TEXT_5 + // values for text area gadgets enum { @@ -839,10 +1047,22 @@ enum enum { ED_SELECTBOX_ID_TIME_OR_STEPS, + ED_SELECTBOX_ID_TIME_SCORE_BASE, ED_SELECTBOX_ID_GAME_ENGINE_TYPE, ED_SELECTBOX_ID_LEVELSET_SAVE_MODE, + ED_SELECTBOX_ID_BD_SCHEDULING_TYPE, + ED_SELECTBOX_ID_BD_COLOR_TYPE, + ED_SELECTBOX_ID_BD_COLOR_C64_B, + ED_SELECTBOX_ID_BD_COLOR_C64_0, + ED_SELECTBOX_ID_BD_COLOR_C64_1, + ED_SELECTBOX_ID_BD_COLOR_C64_2, + ED_SELECTBOX_ID_BD_COLOR_C64_3, + ED_SELECTBOX_ID_BD_COLOR_C64_4, + ED_SELECTBOX_ID_BD_COLOR_C64_5, ED_SELECTBOX_ID_WIND_DIRECTION, ED_SELECTBOX_ID_PLAYER_SPEED, + ED_SELECTBOX_ID_BD_GRAVITY_DIRECTION, + ED_SELECTBOX_ID_MM_BALL_CHOICE_MODE, ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE, ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER, ED_SELECTBOX_ID_CUSTOM_ACCESS_PROTECTED, @@ -878,6 +1098,12 @@ enum #define ED_SELECTBOX_ID_LEVELSET_FIRST ED_SELECTBOX_ID_LEVELSET_SAVE_MODE #define ED_SELECTBOX_ID_LEVELSET_LAST ED_SELECTBOX_ID_LEVELSET_SAVE_MODE +#define ED_SELECTBOX_ID_ENGINE_FIRST ED_SELECTBOX_ID_BD_SCHEDULING_TYPE +#define ED_SELECTBOX_ID_ENGINE_LAST ED_SELECTBOX_ID_BD_SCHEDULING_TYPE + +#define ED_SELECTBOX_ID_COLORS_FIRST ED_SELECTBOX_ID_BD_COLOR_C64_B +#define ED_SELECTBOX_ID_COLORS_LAST ED_SELECTBOX_ID_BD_COLOR_C64_5 + #define ED_SELECTBOX_ID_CUSTOM1_FIRST ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE #define ED_SELECTBOX_ID_CUSTOM1_LAST ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION #define ED_SELECTBOX_ID_CUSTOM2_FIRST ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN @@ -891,9 +1117,12 @@ enum // values for textbutton gadgets enum { - ED_TEXTBUTTON_ID_LEVELINFO_LEVEL, - ED_TEXTBUTTON_ID_LEVELINFO_LEVELSET, - ED_TEXTBUTTON_ID_LEVELINFO_EDITOR, + ED_TEXTBUTTON_ID_LEVELCONFIG_LEVEL, + ED_TEXTBUTTON_ID_LEVELCONFIG_LEVELSET, + ED_TEXTBUTTON_ID_LEVELCONFIG_EDITOR, + ED_TEXTBUTTON_ID_LEVELCONFIG_ENGINE, + ED_TEXTBUTTON_ID_ENGINECONFIG_CONFIG, + ED_TEXTBUTTON_ID_ENGINECONFIG_COLORS, ED_TEXTBUTTON_ID_PROPERTIES_INFO, ED_TEXTBUTTON_ID_PROPERTIES_CONFIG, ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_1, @@ -904,12 +1133,16 @@ enum ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1, ED_TEXTBUTTON_ID_ADD_CHANGE_PAGE, ED_TEXTBUTTON_ID_DEL_CHANGE_PAGE, + ED_TEXTBUTTON_ID_BD_SET_RANDOM_COLORS, ED_NUM_TEXTBUTTONS }; -#define ED_TAB_BUTTON_ID_LEVELINFO_FIRST ED_TEXTBUTTON_ID_LEVELINFO_LEVEL -#define ED_TAB_BUTTON_ID_LEVELINFO_LAST ED_TEXTBUTTON_ID_LEVELINFO_EDITOR +#define ED_TAB_BUTTON_ID_LEVELCONFIG_FIRST ED_TEXTBUTTON_ID_LEVELCONFIG_LEVEL +#define ED_TAB_BUTTON_ID_LEVELCONFIG_LAST ED_TEXTBUTTON_ID_LEVELCONFIG_ENGINE + +#define ED_TAB_BUTTON_ID_ENGINECONFIG_FIRST ED_TEXTBUTTON_ID_ENGINECONFIG_CONFIG +#define ED_TAB_BUTTON_ID_ENGINECONFIG_LAST ED_TEXTBUTTON_ID_ENGINECONFIG_COLORS #define ED_TAB_BUTTON_ID_PROPERTIES_FIRST ED_TEXTBUTTON_ID_PROPERTIES_INFO #define ED_TAB_BUTTON_ID_PROPERTIES_LAST ED_TEXTBUTTON_ID_PROPERTIES_CHANGE @@ -935,11 +1168,17 @@ enum enum { ED_CHECKBUTTON_ID_AUTO_COUNT_GEMS, + ED_CHECKBUTTON_ID_RATE_TIME_OVER_SCORE, ED_CHECKBUTTON_ID_USE_LEVELSET_ARTWORK, ED_CHECKBUTTON_ID_COPY_LEVEL_TEMPLATE, ED_CHECKBUTTON_ID_RANDOM_RESTRICTED, ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_3, ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_2, + ED_CHECKBUTTON_ID_BD_INTERMISSION, + ED_CHECKBUTTON_ID_BD_PAL_TIMING, + ED_CHECKBUTTON_ID_BD_LINE_SHIFTING_BORDERS, + ED_CHECKBUTTON_ID_BD_SCAN_FIRST_AND_LAST_ROW, + ED_CHECKBUTTON_ID_BD_SHORT_EXPLOSIONS, ED_CHECKBUTTON_ID_STICK_ELEMENT, ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS, ED_CHECKBUTTON_ID_EM_EXPLODES_BY_FIRE, @@ -947,12 +1186,14 @@ enum ED_CHECKBUTTON_ID_USE_TIME_ORB_BUG, ED_CHECKBUTTON_ID_USE_LIFE_BUGS, ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT, - ED_CHECKBUTTON_ID_INITIAL_BALL_STATE, + ED_CHECKBUTTON_ID_INITIAL_BALL_ACTIVE, ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE, ED_CHECKBUTTON_ID_SB_FIELDS_NEEDED, ED_CHECKBUTTON_ID_SB_OBJECTS_NEEDED, ED_CHECKBUTTON_ID_AUTO_EXIT_SOKOBAN, ED_CHECKBUTTON_ID_SOLVED_BY_ONE_PLAYER, + ED_CHECKBUTTON_ID_FINISH_DIG_COLLECT, + ED_CHECKBUTTON_ID_KEEP_WALKABLE_CE, ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING, ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD, ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD, @@ -969,6 +1210,32 @@ enum ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID, ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID, ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH, + ED_CHECKBUTTON_ID_BD_DIAGONAL_MOVEMENTS, + ED_CHECKBUTTON_ID_BD_TOPMOST_PLAYER_ACTIVE, + ED_CHECKBUTTON_ID_BD_PUSH_MEGA_ROCK_WITH_SWEET, + ED_CHECKBUTTON_ID_BD_MAGIC_WALL_ZERO_INFINITE, + ED_CHECKBUTTON_ID_BD_MAGIC_WALL_WAIT_HATCHING, + ED_CHECKBUTTON_ID_BD_MAGIC_WALL_STOPS_AMOEBA, + ED_CHECKBUTTON_ID_BD_MAGIC_WALL_BREAK_SCAN, + ED_CHECKBUTTON_ID_BD_AMOEBA_WAIT_FOR_HATCHING, + ED_CHECKBUTTON_ID_BD_AMOEBA_START_IMMEDIATELY, + ED_CHECKBUTTON_ID_BD_AMOEBA_2_EXPLODE_BY_AMOEBA, + ED_CHECKBUTTON_ID_BD_VOODOO_COLLECTS_DIAMONDS, + ED_CHECKBUTTON_ID_BD_VOODOO_HURT_KILLS_PLAYER, + ED_CHECKBUTTON_ID_BD_VOODOO_DIES_BY_ROCK, + ED_CHECKBUTTON_ID_BD_VOODOO_VANISH_BY_EXPLOSION, + ED_CHECKBUTTON_ID_BD_SLIME_IS_PREDICTABLE, + ED_CHECKBUTTON_ID_BD_CHANGE_EXPANDING_WALL, + ED_CHECKBUTTON_ID_BD_REPLICATORS_ACTIVE, + ED_CHECKBUTTON_ID_BD_CONVEYOR_BELTS_ACTIVE, + ED_CHECKBUTTON_ID_BD_CONVEYOR_BELTS_CHANGED, + ED_CHECKBUTTON_ID_BD_WATER_CANNOT_FLOW_DOWN, + ED_CHECKBUTTON_ID_BD_HAMMER_WALLS_REAPPEAR, + ED_CHECKBUTTON_ID_BD_INFINITE_ROCKETS, + ED_CHECKBUTTON_ID_BD_CREATURES_START_BACKWARDS, + ED_CHECKBUTTON_ID_BD_CREATURES_TURN_ON_HATCHING, + ED_CHECKBUTTON_ID_BD_GRAVITY_SWITCH_ACTIVE, + ED_CHECKBUTTON_ID_BD_GRAVITY_AFFECTS_ALL, ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP, ED_CHECKBUTTON_ID_ENVELOPE_CENTERED, ED_CHECKBUTTON_ID_MM_LASER_RED, @@ -977,6 +1244,8 @@ enum ED_CHECKBUTTON_ID_DF_LASER_RED, ED_CHECKBUTTON_ID_DF_LASER_GREEN, ED_CHECKBUTTON_ID_DF_LASER_BLUE, + ED_CHECKBUTTON_ID_ROTATE_MM_BALL_CONTENT, + ED_CHECKBUTTON_ID_EXPLODE_MM_BALL, ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC, ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1, ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE, @@ -1007,7 +1276,7 @@ enum }; #define ED_CHECKBUTTON_ID_LEVEL_FIRST ED_CHECKBUTTON_ID_AUTO_COUNT_GEMS -#define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_AUTO_COUNT_GEMS +#define ED_CHECKBUTTON_ID_LEVEL_LAST ED_CHECKBUTTON_ID_RATE_TIME_OVER_SCORE #define ED_CHECKBUTTON_ID_LEVELSET_FIRST ED_CHECKBUTTON_ID_USE_LEVELSET_ARTWORK #define ED_CHECKBUTTON_ID_LEVELSET_LAST ED_CHECKBUTTON_ID_COPY_LEVEL_TEMPLATE @@ -1015,6 +1284,9 @@ enum #define ED_CHECKBUTTON_ID_EDITOR_FIRST ED_CHECKBUTTON_ID_RANDOM_RESTRICTED #define ED_CHECKBUTTON_ID_EDITOR_LAST ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_2 +#define ED_CHECKBUTTON_ID_ENGINE_FIRST ED_CHECKBUTTON_ID_BD_INTERMISSION +#define ED_CHECKBUTTON_ID_ENGINE_LAST ED_CHECKBUTTON_ID_BD_SHORT_EXPLOSIONS + #define ED_CHECKBUTTON_ID_CUSTOM1_FIRST ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC #define ED_CHECKBUTTON_ID_CUSTOM1_LAST ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE #define ED_CHECKBUTTON_ID_CUSTOM2_FIRST ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE @@ -1059,10 +1331,52 @@ enum ED_DRAWING_ID_MAGIC_BALL_CONTENT_7, ED_DRAWING_ID_ANDROID_CONTENT, ED_DRAWING_ID_AMOEBA_CONTENT, + ED_DRAWING_ID_BD_SNAP_ELEMENT, + ED_DRAWING_ID_BD_MAGIC_WALL_DIAMOND_TO, + ED_DRAWING_ID_BD_MAGIC_WALL_ROCK_TO, + ED_DRAWING_ID_BD_MAGIC_WALL_MEGA_ROCK_TO, + ED_DRAWING_ID_BD_MAGIC_WALL_NUT_TO, + ED_DRAWING_ID_BD_MAGIC_WALL_NITRO_PACK_TO, + ED_DRAWING_ID_BD_MAGIC_WALL_FLYING_DIAMOND_TO, + ED_DRAWING_ID_BD_MAGIC_WALL_FLYING_ROCK_TO, + ED_DRAWING_ID_BD_AMOEBA_CONTENT_TOO_BIG, + ED_DRAWING_ID_BD_AMOEBA_CONTENT_ENCLOSED, + ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_TOO_BIG, + ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_ENCLOSED, + ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_EXPLODING, + ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_LOOKS_LIKE, + ED_DRAWING_ID_BD_SLIME_EATS_ELEMENT_1, + ED_DRAWING_ID_BD_SLIME_CONVERTS_TO_ELEMENT_1, + ED_DRAWING_ID_BD_SLIME_EATS_ELEMENT_2, + ED_DRAWING_ID_BD_SLIME_CONVERTS_TO_ELEMENT_2, + ED_DRAWING_ID_BD_SLIME_EATS_ELEMENT_3, + ED_DRAWING_ID_BD_SLIME_CONVERTS_TO_ELEMENT_3, + ED_DRAWING_ID_BD_ACID_EATS_ELEMENT, + ED_DRAWING_ID_BD_ACID_TURNS_TO_ELEMENT, + ED_DRAWING_ID_BD_BITER_EATS_ELEMENT, + ED_DRAWING_ID_BD_BLADDER_CONVERTS_BY_ELEMENT, + ED_DRAWING_ID_BD_NUT_CONTENT, + ED_DRAWING_ID_BD_EXPANDING_WALL_LOOKS_LIKE, + ED_DRAWING_ID_BD_SAND_LOOKS_LIKE, + ED_DRAWING_ID_BD_ROCK_TURNS_TO_ON_FALLING, + ED_DRAWING_ID_BD_ROCK_TURNS_TO_ON_IMPACT, + ED_DRAWING_ID_BD_DIAMOND_TURNS_TO_ON_FALLING, + ED_DRAWING_ID_BD_DIAMOND_TURNS_TO_ON_IMPACT, + ED_DRAWING_ID_BD_FIREFLY_EXPLODES_TO, + ED_DRAWING_ID_BD_FIREFLY_2_EXPLODES_TO, + ED_DRAWING_ID_BD_BUTTERFLY_EXPLODES_TO, + ED_DRAWING_ID_BD_BUTTERFLY_2_EXPLODES_TO, + ED_DRAWING_ID_BD_STONEFLY_EXPLODES_TO, + ED_DRAWING_ID_BD_DRAGONFLY_EXPLODES_TO, + ED_DRAWING_ID_BD_DIAMOND_BIRTH_TURNS_TO, + ED_DRAWING_ID_BD_BOMB_EXPLOSION_TURNS_TO, + ED_DRAWING_ID_BD_NITRO_EXPLOSION_TURNS_TO, + ED_DRAWING_ID_BD_EXPLOSION_TURNS_TO, ED_DRAWING_ID_START_ELEMENT, ED_DRAWING_ID_ARTWORK_ELEMENT, ED_DRAWING_ID_EXPLOSION_ELEMENT, ED_DRAWING_ID_INVENTORY_CONTENT, + ED_DRAWING_ID_MM_BALL_CONTENT, ED_DRAWING_ID_CUSTOM_GRAPHIC, ED_DRAWING_ID_CUSTOM_CONTENT, ED_DRAWING_ID_CUSTOM_MOVE_ENTER, @@ -1098,14 +1412,19 @@ enum // screens in the level editor #define ED_MODE_DRAWING 0 -#define ED_MODE_INFO 1 +#define ED_MODE_LEVELCONFIG 1 #define ED_MODE_PROPERTIES 2 #define ED_MODE_PALETTE 3 // sub-screens in the global settings section -#define ED_MODE_LEVELINFO_LEVEL ED_TEXTBUTTON_ID_LEVELINFO_LEVEL -#define ED_MODE_LEVELINFO_LEVELSET ED_TEXTBUTTON_ID_LEVELINFO_LEVELSET -#define ED_MODE_LEVELINFO_EDITOR ED_TEXTBUTTON_ID_LEVELINFO_EDITOR +#define ED_MODE_LEVELCONFIG_LEVEL ED_TEXTBUTTON_ID_LEVELCONFIG_LEVEL +#define ED_MODE_LEVELCONFIG_LEVELSET ED_TEXTBUTTON_ID_LEVELCONFIG_LEVELSET +#define ED_MODE_LEVELCONFIG_EDITOR ED_TEXTBUTTON_ID_LEVELCONFIG_EDITOR +#define ED_MODE_LEVELCONFIG_ENGINE ED_TEXTBUTTON_ID_LEVELCONFIG_ENGINE + +// sub-screens in the engine settings section +#define ED_MODE_ENGINECONFIG_CONFIG ED_TEXTBUTTON_ID_ENGINECONFIG_CONFIG +#define ED_MODE_ENGINECONFIG_COLORS ED_TEXTBUTTON_ID_ENGINECONFIG_COLORS // sub-screens in the element properties section #define ED_MODE_PROPERTIES_INFO ED_TEXTBUTTON_ID_PROPERTIES_INFO @@ -1160,82 +1479,82 @@ static struct { IMG_GFX_EDITOR_BUTTON_DRAW_SINGLE, GADGET_ID_SINGLE_ITEMS, &editor.button.draw_single, GD_TYPE_RADIO_BUTTON, - "draw single items", 's' + "Draw single items", 's' }, { IMG_GFX_EDITOR_BUTTON_DRAW_CONNECTED, GADGET_ID_CONNECTED_ITEMS, &editor.button.draw_connected, GD_TYPE_RADIO_BUTTON, - "draw connected items", 'd' + "Draw connected items", 'd' }, { IMG_GFX_EDITOR_BUTTON_DRAW_LINE, GADGET_ID_LINE, &editor.button.draw_line, GD_TYPE_RADIO_BUTTON, - "draw lines", 'l' + "Draw lines", 'l' }, { IMG_GFX_EDITOR_BUTTON_DRAW_ARC, GADGET_ID_ARC, &editor.button.draw_arc, GD_TYPE_RADIO_BUTTON, - "draw arcs", 'a' + "Draw arcs", 'a' }, { IMG_GFX_EDITOR_BUTTON_DRAW_RECTANGLE, GADGET_ID_RECTANGLE, &editor.button.draw_rectangle, GD_TYPE_RADIO_BUTTON, - "draw outline rectangles", 'r' + "Draw outline rectangles", 'r' }, { IMG_GFX_EDITOR_BUTTON_DRAW_FILLED_BOX, GADGET_ID_FILLED_BOX, &editor.button.draw_filled_box, GD_TYPE_RADIO_BUTTON, - "draw filled rectangles", 'R' + "Draw filled rectangles", 'R' }, { IMG_GFX_EDITOR_BUTTON_ROTATE_UP, GADGET_ID_WRAP_UP, &editor.button.rotate_up, GD_TYPE_NORMAL_BUTTON, - "wrap (rotate) level up", 0 + "Wrap (rotate) level up", 0 }, { IMG_GFX_EDITOR_BUTTON_DRAW_TEXT, GADGET_ID_TEXT, &editor.button.draw_text, GD_TYPE_RADIO_BUTTON, - "enter text elements", 't' + "Enter text elements", 't' }, { IMG_GFX_EDITOR_BUTTON_FLOOD_FILL, GADGET_ID_FLOOD_FILL, &editor.button.flood_fill, GD_TYPE_RADIO_BUTTON, - "flood fill", 'f' + "Flood fill", 'f' }, { IMG_GFX_EDITOR_BUTTON_ROTATE_LEFT, GADGET_ID_WRAP_LEFT, &editor.button.rotate_left, GD_TYPE_NORMAL_BUTTON, - "wrap (rotate) level left", 0 + "Wrap (rotate) level left", 0 }, { IMG_GFX_EDITOR_BUTTON_ZOOM_LEVEL, GADGET_ID_ZOOM, &editor.button.zoom_level, GD_TYPE_NORMAL_BUTTON, - "zoom level tile size", '+' + "Zoom level tile size", '+' }, { IMG_GFX_EDITOR_BUTTON_ROTATE_RIGHT, GADGET_ID_WRAP_RIGHT, &editor.button.rotate_right, GD_TYPE_NORMAL_BUTTON, - "wrap (rotate) level right", 0 + "Wrap (rotate) level right", 0 }, { IMG_GFX_EDITOR_BUTTON_DRAW_RANDOM, GADGET_ID_RANDOM_PLACEMENT, &editor.button.draw_random, GD_TYPE_NORMAL_BUTTON, - "random element placement", 0 + "Random element placement", 0 }, { IMG_GFX_EDITOR_BUTTON_GRAB_BRUSH, GADGET_ID_GRAB_BRUSH, &editor.button.grab_brush, GD_TYPE_RADIO_BUTTON, - "grab brush", 'b' + "Grab brush", 'b' }, { IMG_GFX_EDITOR_BUTTON_ROTATE_DOWN, GADGET_ID_WRAP_DOWN, &editor.button.rotate_down, GD_TYPE_NORMAL_BUTTON, - "wrap (rotate) level down", 0 + "Wrap (rotate) level down", 0 }, { IMG_GFX_EDITOR_BUTTON_PICK_ELEMENT, GADGET_ID_PICK_ELEMENT, &editor.button.pick_element, GD_TYPE_RADIO_BUTTON, - "pick drawing element", ',' + "Pick drawing element", ',' }, // ---------- level control buttons ----------------------------------------- @@ -1243,32 +1562,32 @@ static struct { IMG_GFX_EDITOR_BUTTON_UNDO, GADGET_ID_UNDO, &editor.button.undo, GD_TYPE_NORMAL_BUTTON, - "undo/redo last operation", 'u' + "Undo/redo last operation", 'u' }, { - IMG_GFX_EDITOR_BUTTON_CONF, GADGET_ID_INFO, + IMG_GFX_EDITOR_BUTTON_CONF, GADGET_ID_CONF, &editor.button.conf, GD_TYPE_NORMAL_BUTTON, - "properties of level", 'I' + "Level and editor settings", 'I' }, { IMG_GFX_EDITOR_BUTTON_SAVE, GADGET_ID_SAVE, &editor.button.save, GD_TYPE_NORMAL_BUTTON, - "save level", 'S' + "Save level", 'S' }, { IMG_GFX_EDITOR_BUTTON_CLEAR, GADGET_ID_CLEAR, &editor.button.clear, GD_TYPE_NORMAL_BUTTON, - "clear level", 'C' + "Clear level", 'C' }, { IMG_GFX_EDITOR_BUTTON_TEST, GADGET_ID_TEST, &editor.button.test, GD_TYPE_NORMAL_BUTTON, - "test level", 'T' + "Test level", 'T' }, { IMG_GFX_EDITOR_BUTTON_EXIT, GADGET_ID_EXIT, &editor.button.exit, GD_TYPE_NORMAL_BUTTON, - "exit level editor", 'E' + "Exit level editor", 'E' }, // ---------- CE and GE control buttons ------------------------------------- @@ -1276,27 +1595,27 @@ static struct { IMG_GFX_EDITOR_BUTTON_CE_COPY_FROM, GADGET_ID_CUSTOM_COPY_FROM, &editor.button.ce_copy_from, GD_TYPE_RADIO_BUTTON, - "copy settings from other element", 0 + "Copy settings from other element", 0 }, { IMG_GFX_EDITOR_BUTTON_CE_COPY_TO, GADGET_ID_CUSTOM_COPY_TO, &editor.button.ce_copy_to, GD_TYPE_RADIO_BUTTON, - "copy settings to other element", 0 + "Copy settings to other element", 0 }, { IMG_GFX_EDITOR_BUTTON_CE_SWAP, GADGET_ID_CUSTOM_EXCHANGE, &editor.button.ce_swap, GD_TYPE_RADIO_BUTTON, - "exchange element with other element", 0 + "Exchange element with other element", 0 }, { IMG_GFX_EDITOR_BUTTON_CE_COPY, GADGET_ID_CUSTOM_COPY, &editor.button.ce_copy, GD_TYPE_NORMAL_BUTTON, - "copy settings from this element", 0 + "Copy settings from this element", 0 }, { IMG_GFX_EDITOR_BUTTON_CE_PASTE, GADGET_ID_CUSTOM_PASTE, &editor.button.ce_paste, GD_TYPE_NORMAL_BUTTON, - "paste settings to this element", 0 + "Paste settings to this element", 0 }, // ---------- palette control buttons --------------------------------------- @@ -1304,27 +1623,27 @@ static struct { IMG_GFX_EDITOR_BUTTON_PROPERTIES, GADGET_ID_PROPERTIES, &editor.button.properties, GD_TYPE_NORMAL_BUTTON, - "properties of drawing element", 'p' + "Properties of drawing element", 'p' }, { IMG_GFX_EDITOR_BUTTON_ELEMENT_LEFT, GADGET_ID_ELEMENT_LEFT, &editor.button.element_left, GD_TYPE_NORMAL_BUTTON, - "properties of drawing element 1", '1' + "Properties of drawing element 1", '1' }, { IMG_GFX_EDITOR_BUTTON_ELEMENT_MIDDLE, GADGET_ID_ELEMENT_MIDDLE, &editor.button.element_middle, GD_TYPE_NORMAL_BUTTON, - "properties of drawing element 2", '2' + "Properties of drawing element 2", '2' }, { IMG_GFX_EDITOR_BUTTON_ELEMENT_RIGHT, GADGET_ID_ELEMENT_RIGHT, &editor.button.element_right, GD_TYPE_NORMAL_BUTTON, - "properties of drawing element 3", '3' + "Properties of drawing element 3", '3' }, { IMG_GFX_EDITOR_BUTTON_PALETTE, GADGET_ID_PALETTE, &editor.button.palette, GD_TYPE_NORMAL_BUTTON, - "show list of elements", 'e' + "Show list of elements", 'e' } }; @@ -1346,8 +1665,28 @@ static boolean levelset_use_levelset_artwork = FALSE; static boolean levelset_copy_level_template = FALSE; static int levelset_save_mode = LEVELSET_SAVE_MODE_UPDATE; +#define MAX_BD_COLORS 7 +#define MAX_BD_COLOR_TEXT_LEN 10 + +static boolean bd_color_type_changed = FALSE; +static int bd_color_type_default = GD_COLOR_TYPE_RGB; +static int bd_color_c64[MAX_BD_COLORS]; +static char bd_color_text[MAX_BD_COLORS][MAX_BD_COLOR_TEXT_LEN + 1]; +static int bd_color_default[MAX_BD_COLORS]; +static int *bd_color[MAX_BD_COLORS] = +{ + &level.bd_color_b, + &level.bd_color_0, + &level.bd_color_1, + &level.bd_color_2, + &level.bd_color_3, + &level.bd_color_4, + &level.bd_color_5, +}; + static struct { + int gadget_type_id; int x, y; int min_value, max_value; int gadget_id_down, gadget_id_up; @@ -1360,1037 +1699,1306 @@ static struct // ---------- current level number ------------------------------------------ { + ED_COUNTER_ID_SELECT_LEVEL, -1, -1, // these values are not constant, but can change at runtime - 1, 100, - GADGET_ID_SELECT_LEVEL_DOWN, GADGET_ID_SELECT_LEVEL_UP, - GADGET_ID_SELECT_LEVEL_TEXT, GADGET_ID_NONE, + 1, 100, + GADGET_ID_SELECT_LEVEL_DOWN, GADGET_ID_SELECT_LEVEL_UP, + GADGET_ID_SELECT_LEVEL_TEXT, GADGET_ID_NONE, &level_nr, - NULL, NULL, NULL + NULL, NULL, NULL }, // ---------- level and editor settings ------------------------------------- { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(4), - MIN_LEV_FIELDX, MAX_LEV_FIELDX, - GADGET_ID_LEVEL_XSIZE_DOWN, GADGET_ID_LEVEL_XSIZE_UP, - GADGET_ID_LEVEL_XSIZE_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_LEVEL_XSIZE, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(4), + MIN_LEV_FIELDX, MAX_LEV_FIELDX, + GADGET_ID_LEVEL_XSIZE_DOWN, GADGET_ID_LEVEL_XSIZE_UP, + GADGET_ID_LEVEL_XSIZE_TEXT, GADGET_ID_NONE, &level.fieldx, - "playfield size:", NULL, "width", + "Playfield size:", NULL, "Width", }, { - -1, ED_LEVEL_SETTINGS_YPOS(4), - MIN_LEV_FIELDY, MAX_LEV_FIELDY, - GADGET_ID_LEVEL_YSIZE_DOWN, GADGET_ID_LEVEL_YSIZE_UP, - GADGET_ID_LEVEL_YSIZE_TEXT, GADGET_ID_LEVEL_XSIZE_UP, + ED_COUNTER_ID_LEVEL_YSIZE, + -1, ED_LEVEL_SETTINGS_YPOS(4), + MIN_LEV_FIELDY, MAX_LEV_FIELDY, + GADGET_ID_LEVEL_YSIZE_DOWN, GADGET_ID_LEVEL_YSIZE_UP, + GADGET_ID_LEVEL_YSIZE_TEXT, GADGET_ID_LEVEL_XSIZE_UP, &level.fieldy, - NULL, " ", "height", + NULL, " ", "Height", }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(5), - 0, 999, - GADGET_ID_LEVEL_GEMSLIMIT_DOWN, GADGET_ID_LEVEL_GEMSLIMIT_UP, - GADGET_ID_LEVEL_GEMSLIMIT_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_LEVEL_GEMSLIMIT, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(5), + 0, 999, + GADGET_ID_LEVEL_GEMSLIMIT_DOWN, GADGET_ID_LEVEL_GEMSLIMIT_UP, + GADGET_ID_LEVEL_GEMSLIMIT_TEXT, GADGET_ID_NONE, &level.gems_needed, - NULL, "number of gems to collect:", NULL + NULL, "Number of gems to collect:", NULL }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(8), - 0, 9999, - GADGET_ID_LEVEL_TIMELIMIT_DOWN, GADGET_ID_LEVEL_TIMELIMIT_UP, - GADGET_ID_LEVEL_TIMELIMIT_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_LEVEL_TIMELIMIT, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(8), + 0, 9999, + GADGET_ID_LEVEL_TIMELIMIT_DOWN, GADGET_ID_LEVEL_TIMELIMIT_UP, + GADGET_ID_LEVEL_TIMELIMIT_TEXT, GADGET_ID_NONE, &level.time, - "time or step limit to solve level:", NULL, NULL + "Time or step limit to solve level:", NULL, NULL }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(10), - 0, 999, - GADGET_ID_LEVEL_TIMESCORE_DOWN, GADGET_ID_LEVEL_TIMESCORE_UP, - GADGET_ID_LEVEL_TIMESCORE_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_LEVEL_TIMESCORE, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(10), + 0, 999, + GADGET_ID_LEVEL_TIMESCORE_DOWN, GADGET_ID_LEVEL_TIMESCORE_UP, + GADGET_ID_LEVEL_TIMESCORE_TEXT, GADGET_ID_NONE, &level.score[SC_TIME_BONUS], - "score for each second/step left:", NULL, NULL + "Score for time or steps left:", NULL, NULL }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(12), - 0, 9999, - GADGET_ID_LEVEL_RANDOM_SEED_DOWN, GADGET_ID_LEVEL_RANDOM_SEED_UP, - GADGET_ID_LEVEL_RANDOM_SEED_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_LEVEL_RANDOM_SEED, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(13), + 0, 9999, + GADGET_ID_LEVEL_RANDOM_SEED_DOWN, GADGET_ID_LEVEL_RANDOM_SEED_UP, + GADGET_ID_LEVEL_RANDOM_SEED_TEXT, GADGET_ID_NONE, &level.random_seed, - NULL, "random seed:", "(0 => random)" + NULL, "Random seed:", "(0 => random)" }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(4), - 1, MAX_LEVELS, - GADGET_ID_LEVELSET_NUM_LEVELS_DOWN, GADGET_ID_LEVELSET_NUM_LEVELS_UP, - GADGET_ID_LEVELSET_NUM_LEVELS_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_LEVELSET_NUM_LEVELS, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(4), + 1, MAX_LEVELS, + GADGET_ID_LEVELSET_NUM_LEVELS_DOWN, GADGET_ID_LEVELSET_NUM_LEVELS_UP, + GADGET_ID_LEVELSET_NUM_LEVELS_TEXT, GADGET_ID_NONE, &levelset_num_levels, - "number of levels:", NULL, NULL, + "Number of levels:", NULL, NULL, }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(0), - 1, 100, - GADGET_ID_LEVEL_RANDOM_DOWN, GADGET_ID_LEVEL_RANDOM_UP, - GADGET_ID_LEVEL_RANDOM_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_LEVEL_RANDOM, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(0), + 1, 100, + GADGET_ID_LEVEL_RANDOM_DOWN, GADGET_ID_LEVEL_RANDOM_UP, + GADGET_ID_LEVEL_RANDOM_TEXT, GADGET_ID_NONE, &random_placement_value, - "random element placement:", NULL, "in" + "Random element placement:", NULL, "in" + }, + { + ED_COUNTER_ID_BD_CYCLE_DELAY_MS, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(3), + 50, 500, + GADGET_ID_BD_CYCLE_DELAY_MS_DOWN, GADGET_ID_BD_CYCLE_DELAY_MS_UP, + GADGET_ID_BD_CYCLE_DELAY_MS_TEXT, GADGET_ID_NONE, + &level.bd_cycle_delay_ms, + NULL, NULL, "Game cycle delay (ms)" + }, + { + ED_COUNTER_ID_BD_CYCLE_DELAY_C64, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(3), + 0, 32, + GADGET_ID_BD_CYCLE_DELAY_C64_DOWN, GADGET_ID_BD_CYCLE_DELAY_C64_UP, + GADGET_ID_BD_CYCLE_DELAY_C64_TEXT, GADGET_ID_NONE, + &level.bd_cycle_delay_c64, + NULL, NULL, "Game cycle delay (C64-style)" + }, + { + ED_COUNTER_ID_BD_HATCHING_DELAY_CYCLES, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(4), + 1, 40, + GADGET_ID_BD_HATCHING_DELAY_CYCLES_DOWN, GADGET_ID_BD_HATCHING_DELAY_CYCLES_UP, + GADGET_ID_BD_HATCHING_DELAY_CYCLES_TEXT, GADGET_ID_NONE, + &level.bd_hatching_delay_cycles, + NULL, NULL, "Hatching delay (cycles)" + }, + { + ED_COUNTER_ID_BD_HATCHING_DELAY_SECONDS, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(4), + 1, 40, + GADGET_ID_BD_HATCHING_DELAY_SECONDS_DOWN, GADGET_ID_BD_HATCHING_DELAY_SECONDS_UP, + GADGET_ID_BD_HATCHING_DELAY_SECONDS_TEXT, GADGET_ID_NONE, + &level.bd_hatching_delay_seconds, + NULL, NULL, "Hatching delay (seconds)" }, // ---------- element settings: configure (various elements) ---------------- { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), - MIN_SCORE, MAX_SCORE, - GADGET_ID_ELEMENT_VALUE1_DOWN, GADGET_ID_ELEMENT_VALUE1_UP, - GADGET_ID_ELEMENT_VALUE1_TEXT, GADGET_ID_NONE, - NULL, // will be set when used - NULL, NULL, NULL + ED_COUNTER_ID_BD_PUSHING_PROB, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + 0, 100, + GADGET_ID_BD_PUSHING_PROB_DOWN, GADGET_ID_BD_PUSHING_PROB_UP, + GADGET_ID_BD_PUSHING_PROB_TEXT, GADGET_ID_NONE, + &level.bd_pushing_prob, + NULL, NULL, "Push probability" + }, + { + ED_COUNTER_ID_BD_PUSHING_PROB_WITH_SWEET, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + 0, 100, + GADGET_ID_BD_PUSHING_PROB_WITH_SWEET_DOWN, GADGET_ID_BD_PUSHING_PROB_WITH_SWEET_UP, + GADGET_ID_BD_PUSHING_PROB_WITH_SWEET_TEXT, GADGET_ID_NONE, + &level.bd_pushing_prob_with_sweet, + NULL, NULL, "Push probability with sweet" + }, + { + ED_COUNTER_ID_ELEMENT_VALUE1, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + MIN_SCORE, MAX_SCORE, + GADGET_ID_ELEMENT_VALUE1_DOWN, GADGET_ID_ELEMENT_VALUE1_UP, + GADGET_ID_ELEMENT_VALUE1_TEXT, GADGET_ID_NONE, + NULL, // will be set when used + NULL, NULL, NULL }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), - MIN_SCORE, MAX_SCORE, - GADGET_ID_ELEMENT_VALUE2_DOWN, GADGET_ID_ELEMENT_VALUE2_UP, - GADGET_ID_ELEMENT_VALUE2_TEXT, GADGET_ID_NONE, - NULL, // will be set when used - NULL, NULL, NULL + ED_COUNTER_ID_ELEMENT_VALUE2, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + MIN_SCORE, MAX_SCORE, + GADGET_ID_ELEMENT_VALUE2_DOWN, GADGET_ID_ELEMENT_VALUE2_UP, + GADGET_ID_ELEMENT_VALUE2_TEXT, GADGET_ID_NONE, + NULL, // will be set when used + NULL, NULL, NULL }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), - MIN_SCORE, MAX_SCORE, - GADGET_ID_ELEMENT_VALUE3_DOWN, GADGET_ID_ELEMENT_VALUE3_UP, - GADGET_ID_ELEMENT_VALUE3_TEXT, GADGET_ID_NONE, - NULL, // will be set when used - NULL, NULL, NULL + ED_COUNTER_ID_ELEMENT_VALUE3, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + MIN_SCORE, MAX_SCORE, + GADGET_ID_ELEMENT_VALUE3_DOWN, GADGET_ID_ELEMENT_VALUE3_UP, + GADGET_ID_ELEMENT_VALUE3_TEXT, GADGET_ID_NONE, + NULL, // will be set when used + NULL, NULL, NULL }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), - MIN_SCORE, MAX_SCORE, - GADGET_ID_ELEMENT_VALUE4_DOWN, GADGET_ID_ELEMENT_VALUE4_UP, - GADGET_ID_ELEMENT_VALUE4_TEXT, GADGET_ID_NONE, - NULL, // will be set when used - NULL, NULL, NULL + ED_COUNTER_ID_ELEMENT_VALUE4, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + MIN_SCORE, MAX_SCORE, + GADGET_ID_ELEMENT_VALUE4_DOWN, GADGET_ID_ELEMENT_VALUE4_UP, + GADGET_ID_ELEMENT_VALUE4_TEXT, GADGET_ID_NONE, + NULL, // will be set when used + NULL, NULL, NULL }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), - MIN_ELEMENT_CONTENTS, MAX_ELEMENT_CONTENTS, - GADGET_ID_YAMYAM_CONTENT_DOWN, GADGET_ID_YAMYAM_CONTENT_UP, - GADGET_ID_YAMYAM_CONTENT_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_YAMYAM_CONTENT, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + MIN_ELEMENT_CONTENTS, MAX_ELEMENT_CONTENTS, + GADGET_ID_YAMYAM_CONTENT_DOWN, GADGET_ID_YAMYAM_CONTENT_UP, + GADGET_ID_YAMYAM_CONTENT_TEXT, GADGET_ID_NONE, &level.num_yamyam_contents, - NULL, NULL, "number of content areas" + NULL, NULL, "Number of content areas" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), - MIN_ELEMENT_CONTENTS, MAX_ELEMENT_CONTENTS, - GADGET_ID_BALL_CONTENT_DOWN, GADGET_ID_BALL_CONTENT_UP, - GADGET_ID_BALL_CONTENT_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_BALL_CONTENT, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), + MIN_ELEMENT_CONTENTS, MAX_ELEMENT_CONTENTS, + GADGET_ID_BALL_CONTENT_DOWN, GADGET_ID_BALL_CONTENT_UP, + GADGET_ID_BALL_CONTENT_TEXT, GADGET_ID_NONE, &level.num_ball_contents, - NULL, NULL, "number of content areas" + NULL, NULL, "Number of content areas" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), - MIN_ANDROID_ELEMENTS, MAX_ANDROID_ELEMENTS, - GADGET_ID_ANDROID_CONTENT_DOWN, GADGET_ID_ANDROID_CONTENT_UP, - GADGET_ID_ANDROID_CONTENT_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_ANDROID_CONTENT, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), + MIN_ANDROID_ELEMENTS, MAX_ANDROID_ELEMENTS, + GADGET_ID_ANDROID_CONTENT_DOWN, GADGET_ID_ANDROID_CONTENT_UP, + GADGET_ID_ANDROID_CONTENT_TEXT, GADGET_ID_NONE, &level.num_android_clone_elements, - NULL, NULL, "number of clonable elements" + NULL, NULL, "Number of clonable elements" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), - MIN_ENVELOPE_XSIZE, MAX_ENVELOPE_XSIZE, - GADGET_ID_ENVELOPE_XSIZE_DOWN, GADGET_ID_ENVELOPE_XSIZE_UP, - GADGET_ID_ENVELOPE_XSIZE_TEXT, GADGET_ID_NONE, - NULL, // will be set when used - NULL, NULL, "width", + ED_COUNTER_ID_ENVELOPE_XSIZE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + MIN_ENVELOPE_XSIZE, MAX_ENVELOPE_XSIZE, + GADGET_ID_ENVELOPE_XSIZE_DOWN, GADGET_ID_ENVELOPE_XSIZE_UP, + GADGET_ID_ENVELOPE_XSIZE_TEXT, GADGET_ID_NONE, + NULL, // will be set when used + NULL, NULL, "Width", }, { - -1, ED_ELEMENT_SETTINGS_YPOS(0), - MIN_ENVELOPE_YSIZE, MAX_ENVELOPE_YSIZE, - GADGET_ID_ENVELOPE_YSIZE_DOWN, GADGET_ID_ENVELOPE_YSIZE_UP, - GADGET_ID_ENVELOPE_YSIZE_TEXT, GADGET_ID_ENVELOPE_XSIZE_UP, - NULL, // will be set when used - NULL, " ", "height", + ED_COUNTER_ID_ENVELOPE_YSIZE, + -1, ED_ELEMENT_SETTINGS_YPOS(0), + MIN_ENVELOPE_YSIZE, MAX_ENVELOPE_YSIZE, + GADGET_ID_ENVELOPE_YSIZE_DOWN, GADGET_ID_ENVELOPE_YSIZE_UP, + GADGET_ID_ENVELOPE_YSIZE_TEXT, GADGET_ID_ENVELOPE_XSIZE_UP, + NULL, // will be set when used + NULL, " ", "Height", }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), - MIN_INITIAL_INVENTORY_SIZE, MAX_INITIAL_INVENTORY_SIZE, - GADGET_ID_INVENTORY_SIZE_DOWN, GADGET_ID_INVENTORY_SIZE_UP, - GADGET_ID_INVENTORY_SIZE_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_INVENTORY_SIZE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + MIN_INITIAL_INVENTORY_SIZE, MAX_INITIAL_INVENTORY_SIZE, + GADGET_ID_INVENTORY_SIZE_DOWN, GADGET_ID_INVENTORY_SIZE_UP, + GADGET_ID_INVENTORY_SIZE_TEXT, GADGET_ID_NONE, &level.initial_inventory_size[0], - NULL, NULL, "number of inventory elements" + NULL, NULL, "Number of inventory elements" + }, + { + ED_COUNTER_ID_MM_BALL_CONTENT, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + MIN_ELEMENTS_IN_GROUP, MAX_MM_BALL_CONTENTS, + GADGET_ID_MM_BALL_CONTENT_DOWN, GADGET_ID_MM_BALL_CONTENT_UP, + GADGET_ID_MM_BALL_CONTENT_TEXT, GADGET_ID_NONE, + &level.num_mm_ball_contents, + NULL, NULL, "Number of content elements" }, // ---------- element settings: configure 1 (custom elements) --------------- { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(5), - MIN_SCORE, MAX_SCORE, - GADGET_ID_CUSTOM_SCORE_DOWN, GADGET_ID_CUSTOM_SCORE_UP, - GADGET_ID_CUSTOM_SCORE_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_CUSTOM_SCORE, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(5), + MIN_SCORE, MAX_SCORE, + GADGET_ID_CUSTOM_SCORE_DOWN, GADGET_ID_CUSTOM_SCORE_UP, + GADGET_ID_CUSTOM_SCORE_TEXT, GADGET_ID_NONE, &custom_element.collect_score_initial, - NULL, "CE score", " " + NULL, "CE score", " " }, { - -1, ED_ELEMENT_SETTINGS_YPOS(5), - MIN_COLLECT_COUNT, MAX_COLLECT_COUNT, - GADGET_ID_CUSTOM_GEMCOUNT_DOWN, GADGET_ID_CUSTOM_GEMCOUNT_UP, - GADGET_ID_CUSTOM_GEMCOUNT_TEXT, GADGET_ID_CUSTOM_SCORE_UP, + ED_COUNTER_ID_CUSTOM_GEMCOUNT, + -1, ED_ELEMENT_SETTINGS_YPOS(5), + MIN_COLLECT_COUNT, MAX_COLLECT_COUNT, + GADGET_ID_CUSTOM_GEMCOUNT_DOWN, GADGET_ID_CUSTOM_GEMCOUNT_UP, + GADGET_ID_CUSTOM_GEMCOUNT_TEXT, GADGET_ID_CUSTOM_SCORE_UP, &custom_element.collect_count_initial, - NULL, "CE count", NULL + NULL, "CE count", NULL }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), - 0, 9999, - GADGET_ID_CUSTOM_VALUE_FIX_DOWN, GADGET_ID_CUSTOM_VALUE_FIX_UP, - GADGET_ID_CUSTOM_VALUE_FIX_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_CUSTOM_VALUE_FIX, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), + 0, 9999, + GADGET_ID_CUSTOM_VALUE_FIX_DOWN, GADGET_ID_CUSTOM_VALUE_FIX_UP, + GADGET_ID_CUSTOM_VALUE_FIX_TEXT, GADGET_ID_NONE, &custom_element.ce_value_fixed_initial, - NULL, "CE value", NULL + NULL, "CE value", NULL }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), - 0, 9999, - GADGET_ID_CUSTOM_VALUE_RND_DOWN, GADGET_ID_CUSTOM_VALUE_RND_UP, - GADGET_ID_CUSTOM_VALUE_RND_TEXT, GADGET_ID_CUSTOM_VALUE_FIX_UP, + ED_COUNTER_ID_CUSTOM_VALUE_RND, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), + 0, 9999, + GADGET_ID_CUSTOM_VALUE_RND_DOWN, GADGET_ID_CUSTOM_VALUE_RND_UP, + GADGET_ID_CUSTOM_VALUE_RND_TEXT, GADGET_ID_CUSTOM_VALUE_FIX_UP, &custom_element.ce_value_random_initial, - NULL, "+random", NULL + NULL, "+random", NULL }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(6), - 0, 999, - GADGET_ID_PUSH_DELAY_FIX_DOWN, GADGET_ID_PUSH_DELAY_FIX_UP, - GADGET_ID_PUSH_DELAY_FIX_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_PUSH_DELAY_FIX, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(6), + 0, 999, + GADGET_ID_PUSH_DELAY_FIX_DOWN, GADGET_ID_PUSH_DELAY_FIX_UP, + GADGET_ID_PUSH_DELAY_FIX_TEXT, GADGET_ID_NONE, &custom_element.push_delay_fixed, - NULL, "push delay", NULL + NULL, "Push delay", NULL }, { - -1, ED_ELEMENT_SETTINGS_YPOS(6), - 0, 999, - GADGET_ID_PUSH_DELAY_RND_DOWN, GADGET_ID_PUSH_DELAY_RND_UP, - GADGET_ID_PUSH_DELAY_RND_TEXT, GADGET_ID_PUSH_DELAY_FIX_UP, + ED_COUNTER_ID_PUSH_DELAY_RND, + -1, ED_ELEMENT_SETTINGS_YPOS(6), + 0, 999, + GADGET_ID_PUSH_DELAY_RND_DOWN, GADGET_ID_PUSH_DELAY_RND_UP, + GADGET_ID_PUSH_DELAY_RND_TEXT, GADGET_ID_PUSH_DELAY_FIX_UP, &custom_element.push_delay_random, - NULL, "+random", NULL + NULL, "+random", NULL }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(7), - 0, 999, - GADGET_ID_DROP_DELAY_FIX_DOWN, GADGET_ID_DROP_DELAY_FIX_UP, - GADGET_ID_DROP_DELAY_FIX_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_DROP_DELAY_FIX, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(7), + 0, 999, + GADGET_ID_DROP_DELAY_FIX_DOWN, GADGET_ID_DROP_DELAY_FIX_UP, + GADGET_ID_DROP_DELAY_FIX_TEXT, GADGET_ID_NONE, &custom_element.drop_delay_fixed, - NULL, "drop delay", NULL + NULL, "Drop delay", NULL }, { - -1, ED_ELEMENT_SETTINGS_YPOS(7), - 0, 999, - GADGET_ID_DROP_DELAY_RND_DOWN, GADGET_ID_DROP_DELAY_RND_UP, - GADGET_ID_DROP_DELAY_RND_TEXT, GADGET_ID_DROP_DELAY_FIX_UP, + ED_COUNTER_ID_DROP_DELAY_RND, + -1, ED_ELEMENT_SETTINGS_YPOS(7), + 0, 999, + GADGET_ID_DROP_DELAY_RND_DOWN, GADGET_ID_DROP_DELAY_RND_UP, + GADGET_ID_DROP_DELAY_RND_TEXT, GADGET_ID_DROP_DELAY_FIX_UP, &custom_element.drop_delay_random, - NULL, "+random", NULL + NULL, "+random", NULL }, // ---------- element settings: configure 2 (custom elements) --------------- { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(5), - 0, 999, - GADGET_ID_MOVE_DELAY_FIX_DOWN, GADGET_ID_MOVE_DELAY_FIX_UP, - GADGET_ID_MOVE_DELAY_FIX_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_MOVE_DELAY_FIX, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(5), + 0, 999, + GADGET_ID_MOVE_DELAY_FIX_DOWN, GADGET_ID_MOVE_DELAY_FIX_UP, + GADGET_ID_MOVE_DELAY_FIX_TEXT, GADGET_ID_NONE, &custom_element.move_delay_fixed, - NULL, "move delay", NULL + NULL, "Move delay", NULL }, { - -1, ED_ELEMENT_SETTINGS_YPOS(5), - 0, 999, - GADGET_ID_MOVE_DELAY_RND_DOWN, GADGET_ID_MOVE_DELAY_RND_UP, - GADGET_ID_MOVE_DELAY_RND_TEXT, GADGET_ID_MOVE_DELAY_FIX_UP, + ED_COUNTER_ID_MOVE_DELAY_RND, + -1, ED_ELEMENT_SETTINGS_YPOS(5), + 0, 999, + GADGET_ID_MOVE_DELAY_RND_DOWN, GADGET_ID_MOVE_DELAY_RND_UP, + GADGET_ID_MOVE_DELAY_RND_TEXT, GADGET_ID_MOVE_DELAY_FIX_UP, &custom_element.move_delay_random, - NULL, "+random", NULL + NULL, "+random", NULL + }, + { + ED_COUNTER_ID_STEP_DELAY_FIX, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(6), + 0, 999, + GADGET_ID_STEP_DELAY_FIX_DOWN, GADGET_ID_STEP_DELAY_FIX_UP, + GADGET_ID_STEP_DELAY_FIX_TEXT, GADGET_ID_NONE, + &custom_element.step_delay_fixed, + NULL, "Step delay", NULL + }, + { + ED_COUNTER_ID_STEP_DELAY_RND, + -1, ED_ELEMENT_SETTINGS_YPOS(6), + 0, 999, + GADGET_ID_STEP_DELAY_RND_DOWN, GADGET_ID_STEP_DELAY_RND_UP, + GADGET_ID_STEP_DELAY_RND_TEXT, GADGET_ID_STEP_DELAY_FIX_UP, + &custom_element.step_delay_random, + NULL, "+random", NULL }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(12), - 0, 999, - GADGET_ID_EXPLOSION_DELAY_DOWN, GADGET_ID_EXPLOSION_DELAY_UP, - GADGET_ID_EXPLOSION_DELAY_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_EXPLOSION_DELAY, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(13), + 0, 999, + GADGET_ID_EXPLOSION_DELAY_DOWN, GADGET_ID_EXPLOSION_DELAY_UP, + GADGET_ID_EXPLOSION_DELAY_TEXT, GADGET_ID_NONE, &custom_element.explosion_delay, - NULL, "explosion delay", NULL + NULL, "Explosion delay", NULL }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(13), - 0, 999, - GADGET_ID_IGNITION_DELAY_DOWN, GADGET_ID_IGNITION_DELAY_UP, - GADGET_ID_IGNITION_DELAY_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_IGNITION_DELAY, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(14), + 0, 999, + GADGET_ID_IGNITION_DELAY_DOWN, GADGET_ID_IGNITION_DELAY_UP, + GADGET_ID_IGNITION_DELAY_TEXT, GADGET_ID_NONE, &custom_element.ignition_delay, - NULL, "ignition delay", "(by fire)" + NULL, "Ignition delay", "(by fire)" }, // ---------- element settings: configure (group elements) ------------------ { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), - MIN_ELEMENTS_IN_GROUP, MAX_ELEMENTS_IN_GROUP, - GADGET_ID_GROUP_CONTENT_DOWN, GADGET_ID_GROUP_CONTENT_UP, - GADGET_ID_GROUP_CONTENT_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_GROUP_CONTENT, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + MIN_ELEMENTS_IN_GROUP, MAX_ELEMENTS_IN_GROUP, + GADGET_ID_GROUP_CONTENT_DOWN, GADGET_ID_GROUP_CONTENT_UP, + GADGET_ID_GROUP_CONTENT_TEXT, GADGET_ID_NONE, &group_element_info.num_elements, - NULL, NULL, "number of elements in group" + NULL, NULL, "Number of elements in group" }, // ---------- element settings: advanced (custom elements) ------------------ { - ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(2), - 0, 999, - GADGET_ID_CHANGE_DELAY_FIX_DOWN, GADGET_ID_CHANGE_DELAY_FIX_UP, - GADGET_ID_CHANGE_DELAY_FIX_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_CHANGE_DELAY_FIX, + ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(2), + 0, 999, + GADGET_ID_CHANGE_DELAY_FIX_DOWN, GADGET_ID_CHANGE_DELAY_FIX_UP, + GADGET_ID_CHANGE_DELAY_FIX_TEXT, GADGET_ID_NONE, &custom_element_change.delay_fixed, - NULL, "CE delay", NULL, + NULL, "CE delay", NULL, }, { - -1, ED_ELEMENT_SETTINGS_YPOS(2), - 0, 999, - GADGET_ID_CHANGE_DELAY_RND_DOWN, GADGET_ID_CHANGE_DELAY_RND_UP, - GADGET_ID_CHANGE_DELAY_RND_TEXT, GADGET_ID_CHANGE_DELAY_FIX_UP, + ED_COUNTER_ID_CHANGE_DELAY_RND, + -1, ED_ELEMENT_SETTINGS_YPOS(2), + 0, 999, + GADGET_ID_CHANGE_DELAY_RND_DOWN, GADGET_ID_CHANGE_DELAY_RND_UP, + GADGET_ID_CHANGE_DELAY_RND_TEXT, GADGET_ID_CHANGE_DELAY_FIX_UP, &custom_element_change.delay_random, - NULL, "+random", NULL + NULL, "+random", NULL }, { - ED_ELEMENT_SETTINGS_XPOS(3), ED_ELEMENT_SETTINGS_YPOS(12), - 0, 100, - GADGET_ID_CHANGE_CONT_RND_DOWN, GADGET_ID_CHANGE_CONT_RND_UP, - GADGET_ID_CHANGE_CONT_RND_TEXT, GADGET_ID_NONE, + ED_COUNTER_ID_CHANGE_CONT_RND, + ED_ELEMENT_SETTINGS_XPOS(3), ED_ELEMENT_SETTINGS_YPOS(12), + 0, 100, + GADGET_ID_CHANGE_CONT_RND_DOWN, GADGET_ID_CHANGE_CONT_RND_UP, + GADGET_ID_CHANGE_CONT_RND_TEXT, GADGET_ID_NONE, &custom_element_change.random_percentage, - NULL, "use random replace:", "%" + NULL, "Use random replace:", "%" }, }; static struct { + int gadget_type_id; int x, y; int gadget_id; int size; char *value; - char *text_above, *infotext; + char *text_above, *text_left, *text_right, *infotext; } textinput_info[ED_NUM_TEXTINPUT] = { + // ---------- level and editor settings ------------------------------------- + { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(0), + ED_TEXTINPUT_ID_LEVEL_NAME, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(0), GADGET_ID_LEVEL_NAME, MAX_LEVEL_NAME_LEN, level.name, - "Title:", "Title for this level" + "Title:", NULL, NULL, "Enter title for this level" }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(2), + ED_TEXTINPUT_ID_LEVEL_AUTHOR, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(2), GADGET_ID_LEVEL_AUTHOR, MAX_LEVEL_AUTHOR_LEN, level.author, - "Author:", "Author for this level" + "Author:", NULL, NULL, "Enter author for this level" }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(0), + ED_TEXTINPUT_ID_LEVELSET_NAME, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(0), GADGET_ID_LEVELSET_NAME, MAX_LEVEL_NAME_LEN, levelset_name, - "Title:", "Title for this or new level set" + "Title:", NULL, NULL, "Enter title for this or new level set" }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(2), + ED_TEXTINPUT_ID_LEVELSET_AUTHOR, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(2), GADGET_ID_LEVELSET_AUTHOR, MAX_LEVEL_AUTHOR_LEN, levelset_author, - "Author:", "Author for this or new level set" + "Author:", NULL, NULL, "Enter author for this or new level set" + }, + + // ---------- engine settings: colors --------------------------------------- + + { + ED_TEXTINPUT_ID_BD_COLOR_TEXT_B, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(1), + GADGET_ID_BD_COLOR_TEXT_B, + MAX_BD_COLOR_TEXT_LEN, + bd_color_text[0], + NULL, "Border color: ", NULL, "Enter border color (not used)" + }, + { + ED_TEXTINPUT_ID_BD_COLOR_TEXT_0, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(2), + GADGET_ID_BD_COLOR_TEXT_0, + MAX_BD_COLOR_TEXT_LEN, + bd_color_text[1], + NULL, "Background color: ", NULL, "Enter background color (C64 graphics)" + }, + { + ED_TEXTINPUT_ID_BD_COLOR_TEXT_1, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(3), + GADGET_ID_BD_COLOR_TEXT_1, + MAX_BD_COLOR_TEXT_LEN, + bd_color_text[2], + NULL, "Sand color: ", NULL, "Enter sand color (C64 graphics)" + }, + { + ED_TEXTINPUT_ID_BD_COLOR_TEXT_2, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(4), + GADGET_ID_BD_COLOR_TEXT_2, + MAX_BD_COLOR_TEXT_LEN, + bd_color_text[3], + NULL, "Steel wall color: ", NULL, "Enter steel wall color (C64 graphics)" + }, + { + ED_TEXTINPUT_ID_BD_COLOR_TEXT_3, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(5), + GADGET_ID_BD_COLOR_TEXT_3, + MAX_BD_COLOR_TEXT_LEN, + bd_color_text[4], + NULL, "Wall color: ", NULL, "Enter wall color (C64 graphics)" + }, + { + ED_TEXTINPUT_ID_BD_COLOR_TEXT_4, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(6), + GADGET_ID_BD_COLOR_TEXT_4, + MAX_BD_COLOR_TEXT_LEN, + bd_color_text[5], + NULL, "Amoeba color: ", NULL, "Enter amoeba color (C64 graphics)" }, { + ED_TEXTINPUT_ID_BD_COLOR_TEXT_5, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(7), + GADGET_ID_BD_COLOR_TEXT_5, + MAX_BD_COLOR_TEXT_LEN, + bd_color_text[6], + NULL, "Slime color: ", NULL, "Enter slime color (C64 graphics)" + }, + + // ---------- element settings: configure (several elements) ---------------- + + { + ED_TEXTINPUT_ID_ELEMENT_NAME, -1, -1, // these values are not constant, but can change at runtime GADGET_ID_ELEMENT_NAME, - MAX_ELEMENT_NAME_LEN - 2, // currently 2 chars less editable + MAX_ELEMENT_NAME_LEN - 2, // currently 2 chars less editable custom_element.description, - NULL, "Element name" + NULL, NULL, NULL, "Enter element name" } }; static struct { + int gadget_type_id; int x, y; int gadget_id; int xsize, ysize; char *value; - char *text_above, *infotext; + char *text_above, *text_above_cropped, *infotext; } textarea_info[ED_NUM_TEXTAREAS] = { { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + ED_TEXTAREA_ID_ENVELOPE_INFO, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), GADGET_ID_ENVELOPE_INFO, MAX_ENVELOPE_XSIZE, MAX_ENVELOPE_YSIZE, NULL, - "Envelope Content:", "Envelope Content" + "Envelope Content:", "Envelope Content (cropped):", "Envelope Content" } }; static struct ValueTextInfo options_time_or_steps[] = { - { 0, "seconds" }, - { 1, "steps" }, + { 0, "seconds" }, + { 1, "steps" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_time_score_base[] = +{ + { 1, "per second/step" }, + { 10, "per 10 seconds/steps" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_game_engine_type[] = { - { GAME_ENGINE_TYPE_RND, "Rocks'n'Diamonds" }, - { GAME_ENGINE_TYPE_EM, "Emerald Mine" }, - { GAME_ENGINE_TYPE_SP, "Supaplex" }, - { GAME_ENGINE_TYPE_MM, "Mirror Magic" }, + { GAME_ENGINE_TYPE_RND, "Rocks'n'Diamonds" }, + { GAME_ENGINE_TYPE_BD, "Boulder Dash" }, + { GAME_ENGINE_TYPE_EM, "Emerald Mine" }, + { GAME_ENGINE_TYPE_SP, "Supaplex" }, + { GAME_ENGINE_TYPE_MM, "Mirror Magic" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_levelset_save_mode[] = { - { LEVELSET_SAVE_MODE_UPDATE, "Update this level set" }, - { LEVELSET_SAVE_MODE_CREATE, "Create new level set" }, + { LEVELSET_SAVE_MODE_UPDATE, "Update this level set" }, + { LEVELSET_SAVE_MODE_CREATE, "Create new level set" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_bd_gravity_direction[] = +{ + { GD_MV_DOWN, "down" }, + { GD_MV_UP, "up" }, + { GD_MV_LEFT, "left" }, + { GD_MV_RIGHT, "right" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_wind_direction[] = { - { MV_START_NONE, "none" }, - { MV_START_LEFT, "left" }, - { MV_START_RIGHT, "right" }, - { MV_START_UP, "up" }, - { MV_START_DOWN, "down" }, + { MV_START_NONE, "none" }, + { MV_START_LEFT, "left" }, + { MV_START_RIGHT, "right" }, + { MV_START_UP, "up" }, + { MV_START_DOWN, "down" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_player_speed[] = { - { 0, "frozen" }, - { 1, "very slow" }, - { 2, "slow" }, - { 4, "normal" }, - { 8, "fast" }, - { 16, "very fast" }, - { 32, "ultrafast" }, + { 0, "frozen" }, + { 1, "very slow" }, + { 2, "slow" }, + { 4, "normal" }, + { 8, "fast" }, + { 16, "very fast" }, + { 32, "ultrafast" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_access_type[] = { - { EP_WALKABLE, "walkable" }, - { EP_PASSABLE, "passable" }, + { EP_WALKABLE, "walkable" }, + { EP_PASSABLE, "passable" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_access_layer[] = { - { EP_ACCESSIBLE_OVER, "over" }, - { EP_ACCESSIBLE_INSIDE, "inside" }, - { EP_ACCESSIBLE_UNDER, "under" }, + { EP_ACCESSIBLE_OVER, "over" }, + { EP_ACCESSIBLE_INSIDE, "inside" }, + { EP_ACCESSIBLE_UNDER, "under" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_access_protected[] = { - { 0, "unprotected" }, - { 1, "protected" }, + { 0, "unprotected" }, + { 1, "protected" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_access_direction[] = { - { MV_NO_DIRECTION, "no direction" }, - { MV_LEFT, "left" }, - { MV_RIGHT, "right" }, - { MV_UP, "up" }, - { MV_DOWN, "down" }, - { MV_LEFT | MV_UP, "left + up" }, - { MV_LEFT | MV_DOWN, "left + down" }, - { MV_RIGHT | MV_UP, "right + up" }, - { MV_RIGHT | MV_DOWN, "right + down" }, - { MV_HORIZONTAL, "horizontal" }, - { MV_VERTICAL, "vertical" }, - { MV_HORIZONTAL | MV_UP, "horizontal + up" }, - { MV_HORIZONTAL | MV_DOWN, "horizontal + down" }, - { MV_VERTICAL | MV_LEFT, "vertical + left" }, - { MV_VERTICAL | MV_RIGHT, "vertical + right" }, - { MV_ALL_DIRECTIONS, "all directions" }, - - { -1, NULL } + { MV_NO_DIRECTION, "no direction" }, + { MV_LEFT, "left" }, + { MV_RIGHT, "right" }, + { MV_UP, "up" }, + { MV_DOWN, "down" }, + { MV_LEFT | MV_UP, "left + up" }, + { MV_LEFT | MV_DOWN, "left + down" }, + { MV_RIGHT | MV_UP, "right + up" }, + { MV_RIGHT | MV_DOWN, "right + down" }, + { MV_HORIZONTAL, "horizontal" }, + { MV_VERTICAL, "vertical" }, + { MV_HORIZONTAL | MV_UP, "horizontal + up" }, + { MV_HORIZONTAL | MV_DOWN, "horizontal + down" }, + { MV_VERTICAL | MV_LEFT, "vertical + left" }, + { MV_VERTICAL | MV_RIGHT, "vertical + right" }, + { MV_ALL_DIRECTIONS, "all directions" }, + + { -1, NULL } }; static struct ValueTextInfo options_walk_to_action[] = { - { EP_DIGGABLE, "diggable" }, - { EP_COLLECTIBLE_ONLY, "collectible" }, - { EP_DROPPABLE, "collectible & droppable" }, - { EP_THROWABLE, "collectible & throwable" }, - { EP_PUSHABLE, "pushable" }, + { EP_DIGGABLE, "diggable" }, + { EP_COLLECTIBLE_ONLY, "collectible" }, + { EP_DROPPABLE, "collectible & droppable" }, + { EP_THROWABLE, "collectible & throwable" }, + { EP_PUSHABLE, "pushable" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_move_pattern[] = { - { MV_LEFT, "left" }, - { MV_RIGHT, "right" }, - { MV_UP, "up" }, - { MV_DOWN, "down" }, - { MV_HORIZONTAL, "horizontal" }, - { MV_VERTICAL, "vertical" }, - { MV_ALL_DIRECTIONS, "all directions" }, - { MV_WIND_DIRECTION, "wind direction" }, - { MV_TOWARDS_PLAYER, "towards player" }, - { MV_AWAY_FROM_PLAYER, "away from player" }, - { MV_ALONG_LEFT_SIDE, "along left side" }, - { MV_ALONG_RIGHT_SIDE, "along right side" }, - { MV_TURNING_LEFT, "turning left" }, - { MV_TURNING_RIGHT, "turning right" }, - { MV_TURNING_LEFT_RIGHT, "turning left, right" }, - { MV_TURNING_RIGHT_LEFT, "turning right, left" }, - { MV_TURNING_RANDOM, "turning random" }, - { MV_MAZE_RUNNER, "maze runner style" }, - { MV_MAZE_HUNTER, "maze hunter style" }, - { MV_WHEN_PUSHED, "when pushed" }, - { MV_WHEN_DROPPED, "when dropped/thrown" }, - - { -1, NULL } + { MV_LEFT, "left" }, + { MV_RIGHT, "right" }, + { MV_UP, "up" }, + { MV_DOWN, "down" }, + { MV_HORIZONTAL, "horizontal" }, + { MV_VERTICAL, "vertical" }, + { MV_ALL_DIRECTIONS, "all directions" }, + { MV_WIND_DIRECTION, "wind direction" }, + { MV_TOWARDS_PLAYER, "towards player" }, + { MV_AWAY_FROM_PLAYER, "away from player" }, + { MV_ALONG_LEFT_SIDE, "along left side" }, + { MV_ALONG_RIGHT_SIDE, "along right side" }, + { MV_TURNING_LEFT, "turning left" }, + { MV_TURNING_RIGHT, "turning right" }, + { MV_TURNING_LEFT_RIGHT, "turning left, right" }, + { MV_TURNING_RIGHT_LEFT, "turning right, left" }, + { MV_TURNING_RANDOM, "turning random" }, + { MV_MAZE_RUNNER, "maze runner style" }, + { MV_MAZE_HUNTER, "maze hunter style" }, + { MV_WHEN_PUSHED, "when pushed" }, + { MV_WHEN_DROPPED, "when dropped/thrown" }, + + { -1, NULL } }; static struct ValueTextInfo options_move_direction[] = { - { MV_START_AUTOMATIC, "automatic" }, - { MV_START_LEFT, "left" }, - { MV_START_RIGHT, "right" }, - { MV_START_UP, "up" }, - { MV_START_DOWN, "down" }, - { MV_START_RANDOM, "random" }, - { MV_START_PREVIOUS, "previous" }, + { MV_START_AUTOMATIC, "automatic" }, + { MV_START_LEFT, "left" }, + { MV_START_RIGHT, "right" }, + { MV_START_UP, "up" }, + { MV_START_DOWN, "down" }, + { MV_START_RANDOM, "random" }, + { MV_START_PREVIOUS, "previous" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_move_stepsize[] = { - { 0, "not moving" }, - { 1, "very slow" }, - { 2, "slow" }, - { 4, "normal" }, - { 8, "fast" }, - { 16, "very fast" }, - { 32, "even faster" }, + { 0, "not moving" }, + { 1, "very slow" }, + { 2, "slow" }, + { 4, "normal" }, + { 8, "fast" }, + { 16, "very fast" }, + { 32, "even faster" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_move_leave_type[] = { - { LEAVE_TYPE_UNLIMITED, "leave behind" }, - { LEAVE_TYPE_LIMITED, "change it to" }, + { LEAVE_TYPE_UNLIMITED, "leave behind" }, + { LEAVE_TYPE_LIMITED, "change it to" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_smash_targets[] = { - { EP_CAN_SMASH_PLAYER, "player" }, + { EP_CAN_SMASH_PLAYER, "player" }, #if 0 - { EP_CAN_SMASH_ENEMIES, "enemies" }, + { EP_CAN_SMASH_ENEMIES, "enemies" }, #endif - { EP_CAN_SMASH_EVERYTHING, "everything" }, + { EP_CAN_SMASH_EVERYTHING, "everything" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_slippery_type[] = { - { SLIPPERY_ANY_RANDOM, "random" }, - { SLIPPERY_ANY_LEFT_RIGHT, "left, right" }, - { SLIPPERY_ANY_RIGHT_LEFT, "right, left" }, - { SLIPPERY_ONLY_LEFT, "only left" }, - { SLIPPERY_ONLY_RIGHT, "only right" }, + { SLIPPERY_ANY_RANDOM, "random" }, + { SLIPPERY_ANY_LEFT_RIGHT, "left, right" }, + { SLIPPERY_ANY_RIGHT_LEFT, "right, left" }, + { SLIPPERY_ONLY_LEFT, "only left" }, + { SLIPPERY_ONLY_RIGHT, "only right" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_deadliness[] = { - { EP_DONT_RUN_INTO, "running into" }, - { EP_DONT_COLLIDE_WITH, "colliding with" }, - { EP_DONT_GET_HIT_BY, "getting hit by" }, - { EP_DONT_TOUCH, "touching" }, + { EP_DONT_RUN_INTO, "running into" }, + { EP_DONT_COLLIDE_WITH, "colliding with" }, + { EP_DONT_GET_HIT_BY, "getting hit by" }, + { EP_DONT_TOUCH, "touching" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_explosion_type[] = { - { EXPLODES_3X3, "3x3" }, - { EXPLODES_CROSS, "3+3" }, - { EXPLODES_1X1, "1x1" }, + { EXPLODES_3X3, "3x3" }, + { EXPLODES_CROSS, "3+3" }, + { EXPLODES_1X1, "1x1" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_time_units[] = { - { 1, "frames" }, - { FRAMES_PER_SECOND, "seconds" }, + { 1, "frames" }, + { FRAMES_PER_SECOND, "seconds" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_change_direct_action[] = { - { CE_TOUCHED_BY_PLAYER, "touched by player" }, - { CE_PRESSED_BY_PLAYER, "pressed by player" }, - { CE_SWITCHED_BY_PLAYER, "switched by player" }, - { CE_SNAPPED_BY_PLAYER, "snapped by player" }, - { CE_PUSHED_BY_PLAYER, "pushed by player" }, - { CE_ENTERED_BY_PLAYER, "entered by player" }, - { CE_LEFT_BY_PLAYER, "left by player" }, - { CE_DROPPED_BY_PLAYER, "dropped/thrown by player" }, - { CE_SWITCHED, "switched" }, - { CE_HITTING_SOMETHING, "hitting something" }, - { CE_HIT_BY_SOMETHING, "hit by something" }, + { CE_TOUCHED_BY_PLAYER, "touched by player" }, + { CE_PRESSED_BY_PLAYER, "pressed by player" }, + { CE_SWITCHED_BY_PLAYER, "switched by player" }, + { CE_SNAPPED_BY_PLAYER, "snapped by player" }, + { CE_PUSHED_BY_PLAYER, "pushed by player" }, + { CE_ENTERED_BY_PLAYER, "entered by player" }, + { CE_LEFT_BY_PLAYER, "left by player" }, + { CE_DROPPED_BY_PLAYER, "dropped/thrown by player" }, + { CE_SWITCHED, "switched" }, + { CE_HITTING_SOMETHING, "hitting something" }, + { CE_HIT_BY_SOMETHING, "hit by something" }, #if 0 - { CE_BLOCKED, "blocked" }, + { CE_BLOCKED, "blocked" }, #endif - { CE_IMPACT, "impact (on something)" }, - { CE_SMASHED, "smashed (from above)" }, + { CE_IMPACT, "impact (on something)" }, + { CE_SMASHED, "smashed (from above)" }, #if 0 - { CE_VALUE_CHANGES, "CE value changes" }, - { CE_SCORE_CHANGES, "CE score changes" }, + { CE_VALUE_CHANGES, "CE value changes" }, + { CE_SCORE_CHANGES, "CE score changes" }, #endif - { CE_VALUE_GETS_ZERO, "CE value gets 0" }, - { CE_SCORE_GETS_ZERO, "CE score gets 0" }, - - { -1, NULL } + { CE_VALUE_GETS_ZERO, "CE value gets 0" }, + { CE_SCORE_GETS_ZERO, "CE score gets 0" }, + { CE_UNDEFINED, " " }, + { CE_HEADLINE_SPECIAL_EVENTS, "[mouse events]" }, + { CE_CLICKED_BY_MOUSE, "clicked by mouse" }, + { CE_PRESSED_BY_MOUSE, "pressed by mouse" }, + { CE_UNDEFINED, " " }, + { CE_HEADLINE_SPECIAL_EVENTS, "[static states]" }, + { CE_NEXT_TO_PLAYER, "next to player" }, + + { -1, NULL } }; static struct ValueTextInfo options_change_other_action[] = { - { CE_PLAYER_TOUCHES_X, "player touches" }, - { CE_PLAYER_PRESSES_X, "player presses" }, - { CE_PLAYER_SWITCHES_X, "player switches" }, - { CE_PLAYER_SNAPS_X, "player snaps" }, - { CE_PLAYER_PUSHES_X, "player pushes" }, - { CE_PLAYER_ENTERS_X, "player enters" }, - { CE_PLAYER_LEAVES_X, "player leaves" }, - { CE_PLAYER_DIGS_X, "player digs" }, - { CE_PLAYER_COLLECTS_X, "player collects" }, - { CE_PLAYER_DROPS_X, "player drops/throws" }, - { CE_TOUCHING_X, "touching" }, - { CE_HITTING_X, "hitting" }, - { CE_DIGGING_X, "digging" }, - { CE_HIT_BY_X, "hit by" }, - { CE_SWITCH_OF_X, "switch of" }, - { CE_CHANGE_OF_X, "change by page of" }, - { CE_EXPLOSION_OF_X, "explosion of" }, - { CE_MOVE_OF_X, "move of" }, - { CE_CREATION_OF_X, "creation of" }, - { CE_VALUE_CHANGES_OF_X, "CE value changes of" }, - { CE_SCORE_CHANGES_OF_X, "CE score changes of" }, - { CE_VALUE_GETS_ZERO_OF_X, "CE value gets 0 of" }, - { CE_SCORE_GETS_ZERO_OF_X, "CE score gets 0 of" }, - - { -1, NULL } + { CE_PLAYER_TOUCHES_X, "player touches" }, + { CE_PLAYER_PRESSES_X, "player presses" }, + { CE_PLAYER_SWITCHES_X, "player switches" }, + { CE_PLAYER_SNAPS_X, "player snaps" }, + { CE_PLAYER_PUSHES_X, "player pushes" }, + { CE_PLAYER_ENTERS_X, "player enters" }, + { CE_PLAYER_LEAVES_X, "player leaves" }, + { CE_PLAYER_DIGS_X, "player digs" }, + { CE_PLAYER_COLLECTS_X, "player collects" }, + { CE_PLAYER_DROPS_X, "player drops/throws" }, + { CE_TOUCHING_X, "touching" }, + { CE_HITTING_X, "hitting" }, + { CE_DIGGING_X, "digging" }, + { CE_HIT_BY_X, "hit by" }, + { CE_SWITCH_OF_X, "switch of" }, + { CE_CHANGE_OF_X, "change by page of" }, + { CE_EXPLOSION_OF_X, "explosion of" }, + { CE_MOVE_OF_X, "move of" }, + { CE_CREATION_OF_X, "creation of" }, + { CE_VALUE_CHANGES_OF_X, "CE value changes of" }, + { CE_SCORE_CHANGES_OF_X, "CE score changes of" }, + { CE_VALUE_GETS_ZERO_OF_X, "CE value gets 0 of" }, + { CE_SCORE_GETS_ZERO_OF_X, "CE score gets 0 of" }, + { CE_UNDEFINED, " " }, + { CE_HEADLINE_SPECIAL_EVENTS, "[mouse events]" }, + { CE_MOUSE_CLICKED_ON_X, "mouse clicked on" }, + { CE_MOUSE_PRESSED_ON_X, "mouse pressed on" }, + { CE_UNDEFINED, " " }, + { CE_HEADLINE_SPECIAL_EVENTS, "[static states]" }, + { CE_PLAYER_NEXT_TO_X, "player next to" }, + { CE_NEXT_TO_X, "next to" }, + + { -1, NULL } }; static struct ValueTextInfo options_change_trigger_side[] = { - { CH_SIDE_LEFT, "left" }, - { CH_SIDE_RIGHT, "right" }, - { CH_SIDE_TOP, "top" }, - { CH_SIDE_BOTTOM, "bottom" }, - { CH_SIDE_LEFT_RIGHT, "left/right" }, - { CH_SIDE_TOP_BOTTOM, "top/bottom" }, - { CH_SIDE_ANY, "any" }, + { CH_SIDE_LEFT, "left" }, + { CH_SIDE_RIGHT, "right" }, + { CH_SIDE_TOP, "top" }, + { CH_SIDE_BOTTOM, "bottom" }, + { CH_SIDE_LEFT_RIGHT, "left/right" }, + { CH_SIDE_TOP_BOTTOM, "top/bottom" }, + { CH_SIDE_ANY, "any" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_change_trigger_player[] = { - { CH_PLAYER_1, "1" }, - { CH_PLAYER_2, "2" }, - { CH_PLAYER_3, "3" }, - { CH_PLAYER_4, "4" }, - { CH_PLAYER_ANY, "any" }, + { CH_PLAYER_1, "1" }, + { CH_PLAYER_2, "2" }, + { CH_PLAYER_3, "3" }, + { CH_PLAYER_4, "4" }, + { CH_PLAYER_ANY, "any" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_change_trigger_page[] = { - { (1 << 0), "1" }, - { (1 << 1), "2" }, - { (1 << 2), "3" }, - { (1 << 3), "4" }, - { (1 << 4), "5" }, - { (1 << 5), "6" }, - { (1 << 6), "7" }, - { (1 << 7), "8" }, - { (1 << 8), "9" }, - { (1 << 9), "10" }, - { (1 << 10), "11" }, - { (1 << 11), "12" }, - { (1 << 12), "13" }, - { (1 << 13), "14" }, - { (1 << 14), "15" }, - { (1 << 15), "16" }, - { (1 << 16), "17" }, - { (1 << 17), "18" }, - { (1 << 18), "19" }, - { (1 << 19), "20" }, - { (1 << 20), "21" }, - { (1 << 21), "22" }, - { (1 << 22), "23" }, - { (1 << 23), "24" }, - { (1 << 24), "25" }, - { (1 << 25), "26" }, - { (1 << 26), "27" }, - { (1 << 27), "28" }, - { (1 << 28), "29" }, - { (1 << 29), "30" }, - { (1 << 30), "31" }, - { (1 << 31), "32" }, - { CH_PAGE_ANY, "any" }, - - { -1, NULL } + { (1u << 0), "1" }, + { (1u << 1), "2" }, + { (1u << 2), "3" }, + { (1u << 3), "4" }, + { (1u << 4), "5" }, + { (1u << 5), "6" }, + { (1u << 6), "7" }, + { (1u << 7), "8" }, + { (1u << 8), "9" }, + { (1u << 9), "10" }, + { (1u << 10), "11" }, + { (1u << 11), "12" }, + { (1u << 12), "13" }, + { (1u << 13), "14" }, + { (1u << 14), "15" }, + { (1u << 15), "16" }, + { (1u << 16), "17" }, + { (1u << 17), "18" }, + { (1u << 18), "19" }, + { (1u << 19), "20" }, + { (1u << 20), "21" }, + { (1u << 21), "22" }, + { (1u << 22), "23" }, + { (1u << 23), "24" }, + { (1u << 24), "25" }, + { (1u << 25), "26" }, + { (1u << 26), "27" }, + { (1u << 27), "28" }, + { (1u << 28), "29" }, + { (1u << 29), "30" }, + { (1u << 30), "31" }, + { (1u << 31), "32" }, + { CH_PAGE_ANY, "any" }, + + { -1, NULL } }; static struct ValueTextInfo options_change_replace_when[] = { - { CP_WHEN_EMPTY, "empty" }, - { CP_WHEN_WALKABLE, "walkable" }, - { CP_WHEN_DIGGABLE, "diggable" }, - { CP_WHEN_COLLECTIBLE, "collectible" }, - { CP_WHEN_REMOVABLE, "removable" }, - { CP_WHEN_DESTRUCTIBLE, "destructible" }, + { CP_WHEN_EMPTY, "empty" }, + { CP_WHEN_WALKABLE, "walkable" }, + { CP_WHEN_DIGGABLE, "diggable" }, + { CP_WHEN_COLLECTIBLE, "collectible" }, + { CP_WHEN_REMOVABLE, "removable" }, + { CP_WHEN_DESTRUCTIBLE, "destructible" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_action_type[] = { - { CA_NO_ACTION, "no action" }, - { CA_UNDEFINED, " " }, - { CA_HEADLINE_LEVEL_ACTIONS, "[level]" }, - { CA_RESTART_LEVEL, "restart level" }, - { CA_SHOW_ENVELOPE, "show envelope" }, - { CA_SET_LEVEL_TIME, "set time" }, - { CA_SET_LEVEL_SCORE, "set score" }, - { CA_SET_LEVEL_GEMS, "set gems" }, - { CA_SET_LEVEL_WIND, "set wind dir." }, - { CA_SET_LEVEL_RANDOM_SEED, "set rand. seed" }, - { CA_UNDEFINED, " " }, - { CA_HEADLINE_PLAYER_ACTIONS, "[player]" }, - { CA_MOVE_PLAYER, "move player" }, - { CA_EXIT_PLAYER, "exit player" }, - { CA_KILL_PLAYER, "kill player" }, - { CA_SET_PLAYER_KEYS, "set keys" }, - { CA_SET_PLAYER_SPEED, "set speed" }, - { CA_SET_PLAYER_SHIELD, "set shield" }, - { CA_SET_PLAYER_GRAVITY, "set gravity" }, - { CA_SET_PLAYER_ARTWORK, "set artwork" }, - { CA_SET_PLAYER_INVENTORY, "set inventory" }, - { CA_UNDEFINED, " " }, - { CA_HEADLINE_CE_ACTIONS, "[CE]" }, - { CA_SET_CE_VALUE, "set CE value" }, - { CA_SET_CE_SCORE, "set CE score" }, - { CA_SET_CE_ARTWORK, "set CE artwork" }, - { CA_UNDEFINED, " " }, - { CA_HEADLINE_ENGINE_ACTIONS, "[engine]" }, - { CA_SET_ENGINE_SCAN_MODE, "set scan mode" }, - - { -1, NULL } + { CA_NO_ACTION, "no action" }, + { CA_UNDEFINED, " " }, + { CA_HEADLINE_LEVEL_ACTIONS, "[level]" }, + { CA_RESTART_LEVEL, "restart level" }, + { CA_SHOW_ENVELOPE, "show envelope" }, + { CA_SET_LEVEL_TIME, "set time" }, + { CA_SET_LEVEL_SCORE, "set score" }, + { CA_SET_LEVEL_GEMS, "set gems" }, + { CA_SET_LEVEL_WIND, "set wind dir." }, + { CA_SET_LEVEL_RANDOM_SEED, "set random seed" }, + { CA_UNDEFINED, " " }, + { CA_HEADLINE_PLAYER_ACTIONS, "[player]" }, + { CA_MOVE_PLAYER, "move player" }, + { CA_MOVE_PLAYER_NEW, "move player new" }, + { CA_EXIT_PLAYER, "exit player" }, + { CA_KILL_PLAYER, "kill player" }, + { CA_SET_PLAYER_KEYS, "set keys" }, + { CA_SET_PLAYER_SPEED, "set speed" }, + { CA_SET_PLAYER_SHIELD, "set shield" }, + { CA_SET_PLAYER_GRAVITY, "set gravity" }, + { CA_SET_PLAYER_ARTWORK, "set artwork" }, + { CA_SET_PLAYER_INVENTORY, "set inventory" }, + { CA_UNDEFINED, " " }, + { CA_HEADLINE_CE_ACTIONS, "[CE]" }, + { CA_SET_CE_VALUE, "set CE value" }, + { CA_SET_CE_SCORE, "set CE score" }, + { CA_SET_CE_ARTWORK, "set CE artwork" }, + { CA_UNDEFINED, " " }, + { CA_HEADLINE_ENGINE_ACTIONS, "[engine]" }, + { CA_SET_ENGINE_SCAN_MODE, "set scan mode" }, + + { -1, NULL } }; static struct ValueTextInfo options_action_mode_none[] = { - { CA_MODE_UNDEFINED, " " }, + { CA_MODE_UNDEFINED, " " }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_action_mode_assign[] = { - { CA_MODE_SET, "=" }, + { CA_MODE_SET, "=" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_action_mode_add_remove[] = { - { CA_MODE_ADD, "+" }, - { CA_MODE_SUBTRACT, "-" }, + { CA_MODE_ADD, "+" }, + { CA_MODE_SUBTRACT, "-" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_action_mode_calculate[] = { - { CA_MODE_SET, "=" }, - { CA_MODE_ADD, "+" }, - { CA_MODE_SUBTRACT, "-" }, - { CA_MODE_MULTIPLY, "*" }, - { CA_MODE_DIVIDE, "/" }, - { CA_MODE_MODULO, "%" }, + { CA_MODE_SET, "=" }, + { CA_MODE_ADD, "+" }, + { CA_MODE_SUBTRACT, "-" }, + { CA_MODE_MULTIPLY, "*" }, + { CA_MODE_DIVIDE, "/" }, + { CA_MODE_MODULO, "%" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_action_arg_none[] = { - { CA_ARG_UNDEFINED, " " }, + { CA_ARG_UNDEFINED, " " }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_action_arg_player[] = { - { CA_ARG_PLAYER_HEADLINE, "[player]" }, - { CA_ARG_PLAYER_1, "1" }, - { CA_ARG_PLAYER_2, "2" }, - { CA_ARG_PLAYER_3, "3" }, - { CA_ARG_PLAYER_4, "4" }, - { CA_ARG_PLAYER_ANY, "any" }, - { CA_ARG_PLAYER_TRIGGER, "trigger" }, - { CA_ARG_PLAYER_ACTION, "action ->" }, + { CA_ARG_PLAYER_HEADLINE, "[player]" }, + { CA_ARG_PLAYER_1, "1" }, + { CA_ARG_PLAYER_2, "2" }, + { CA_ARG_PLAYER_3, "3" }, + { CA_ARG_PLAYER_4, "4" }, + { CA_ARG_PLAYER_ANY, "any" }, + { CA_ARG_PLAYER_TRIGGER, "trigger" }, + { CA_ARG_PLAYER_ACTION, "action ->" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_action_arg_number[] = { - { CA_ARG_NUMBER_HEADLINE, "[number]" }, - { CA_ARG_0, "0" }, - { CA_ARG_1, "1" }, - { CA_ARG_2, "2" }, - { CA_ARG_3, "3" }, - { CA_ARG_4, "4" }, - { CA_ARG_5, "5" }, - { CA_ARG_10, "10" }, - { CA_ARG_100, "100" }, - { CA_ARG_1000, "1000" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_NUMBER_MIN, "min" }, - { CA_ARG_NUMBER_MAX, "max" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_NUMBER_RESET, "reset" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_NUMBER_CE_VALUE, "CE value" }, - { CA_ARG_NUMBER_CE_SCORE, "CE score" }, - { CA_ARG_NUMBER_CE_DELAY, "CE delay" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_NUMBER_LEVEL_TIME, "time" }, - { CA_ARG_NUMBER_LEVEL_GEMS, "gems" }, - { CA_ARG_NUMBER_LEVEL_SCORE, "score" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_ELEMENT_CV_HEADLINE, "[CE value]" }, - { CA_ARG_ELEMENT_CV_TARGET, "target" }, - { CA_ARG_ELEMENT_CV_TRIGGER, "trigger" }, - { CA_ARG_ELEMENT_CV_ACTION, "action ->" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_ELEMENT_CS_HEADLINE, "[CE score]" }, - { CA_ARG_ELEMENT_CS_TARGET, "target" }, - { CA_ARG_ELEMENT_CS_TRIGGER, "trigger" }, - { CA_ARG_ELEMENT_CS_ACTION, "action ->" }, - - { -1, NULL } + { CA_ARG_NUMBER_HEADLINE, "[number]" }, + { CA_ARG_0, "0" }, + { CA_ARG_1, "1" }, + { CA_ARG_2, "2" }, + { CA_ARG_3, "3" }, + { CA_ARG_4, "4" }, + { CA_ARG_5, "5" }, + { CA_ARG_10, "10" }, + { CA_ARG_100, "100" }, + { CA_ARG_1000, "1000" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_NUMBER_MIN, "min" }, + { CA_ARG_NUMBER_MAX, "max" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_NUMBER_RESET, "reset" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_NUMBER_CE_VALUE, "CE value" }, + { CA_ARG_NUMBER_CE_SCORE, "CE score" }, + { CA_ARG_NUMBER_CE_DELAY, "CE delay" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_NUMBER_LEVEL_TIME, "time" }, + { CA_ARG_NUMBER_LEVEL_GEMS, "gems" }, + { CA_ARG_NUMBER_LEVEL_SCORE, "score" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_ELEMENT_CV_HEADLINE, "[CE value]" }, + { CA_ARG_ELEMENT_CV_TARGET, "target" }, + { CA_ARG_ELEMENT_CV_TRIGGER, "trigger" }, + { CA_ARG_ELEMENT_CV_ACTION, "action ->" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_ELEMENT_CS_HEADLINE, "[CE score]" }, + { CA_ARG_ELEMENT_CS_TARGET, "target" }, + { CA_ARG_ELEMENT_CS_TRIGGER, "trigger" }, + { CA_ARG_ELEMENT_CS_ACTION, "action ->" }, + + { -1, NULL } }; static struct ValueTextInfo options_action_arg_value[] = { - { CA_ARG_NUMBER_HEADLINE, "[number]" }, - { CA_ARG_0, "0" }, - { CA_ARG_1, "1" }, - { CA_ARG_2, "2" }, - { CA_ARG_3, "3" }, - { CA_ARG_4, "4" }, - { CA_ARG_5, "5" }, - { CA_ARG_10, "10" }, - { CA_ARG_100, "100" }, - { CA_ARG_1000, "1000" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_NUMBER_MIN, "min" }, - { CA_ARG_NUMBER_MAX, "max" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_NUMBER_RESET, "reset" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_NUMBER_CE_VALUE, "CE value" }, - { CA_ARG_NUMBER_CE_SCORE, "CE score" }, - { CA_ARG_NUMBER_CE_DELAY, "CE delay" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_NUMBER_LEVEL_TIME, "time" }, - { CA_ARG_NUMBER_LEVEL_GEMS, "gems" }, - { CA_ARG_NUMBER_LEVEL_SCORE, "score" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_ELEMENT_CV_HEADLINE, "[CE value]" }, - { CA_ARG_ELEMENT_CV_TARGET, "target" }, - { CA_ARG_ELEMENT_CV_TRIGGER, "trigger" }, - { CA_ARG_ELEMENT_CV_ACTION, "action ->" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_ELEMENT_CS_HEADLINE, "[CE score]" }, - { CA_ARG_ELEMENT_CS_TARGET, "target" }, - { CA_ARG_ELEMENT_CS_TRIGGER, "trigger" }, - { CA_ARG_ELEMENT_CS_ACTION, "action ->" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_ELEMENT_NR_HEADLINE, "[element]" }, - { CA_ARG_ELEMENT_NR_TARGET, "target" }, - { CA_ARG_ELEMENT_NR_TRIGGER, "trigger" }, - { CA_ARG_ELEMENT_NR_ACTION, "action ->" }, - - { -1, NULL } + { CA_ARG_NUMBER_HEADLINE, "[number]" }, + { CA_ARG_0, "0" }, + { CA_ARG_1, "1" }, + { CA_ARG_2, "2" }, + { CA_ARG_3, "3" }, + { CA_ARG_4, "4" }, + { CA_ARG_5, "5" }, + { CA_ARG_10, "10" }, + { CA_ARG_100, "100" }, + { CA_ARG_1000, "1000" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_NUMBER_MIN, "min" }, + { CA_ARG_NUMBER_MAX, "max" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_NUMBER_RESET, "reset" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_NUMBER_CE_VALUE, "CE value" }, + { CA_ARG_NUMBER_CE_SCORE, "CE score" }, + { CA_ARG_NUMBER_CE_DELAY, "CE delay" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_NUMBER_LEVEL_TIME, "time" }, + { CA_ARG_NUMBER_LEVEL_GEMS, "gems" }, + { CA_ARG_NUMBER_LEVEL_SCORE, "score" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_ELEMENT_CV_HEADLINE, "[CE value]" }, + { CA_ARG_ELEMENT_CV_TARGET, "target" }, + { CA_ARG_ELEMENT_CV_TRIGGER, "trigger" }, + { CA_ARG_ELEMENT_CV_ACTION, "action ->" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_ELEMENT_CS_HEADLINE, "[CE score]" }, + { CA_ARG_ELEMENT_CS_TARGET, "target" }, + { CA_ARG_ELEMENT_CS_TRIGGER, "trigger" }, + { CA_ARG_ELEMENT_CS_ACTION, "action ->" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_ELEMENT_NR_HEADLINE, "[element]" }, + { CA_ARG_ELEMENT_NR_TARGET, "target" }, + { CA_ARG_ELEMENT_NR_TRIGGER, "trigger" }, + { CA_ARG_ELEMENT_NR_ACTION, "action ->" }, + + { -1, NULL } }; static struct ValueTextInfo options_action_arg_envelope[] = { - { CA_ARG_NUMBER_HEADLINE, "[number]" }, - { CA_ARG_1, "1" }, - { CA_ARG_2, "2" }, - { CA_ARG_3, "3" }, - { CA_ARG_4, "4" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_ELEMENT_HEADLINE, "[element]" }, - { CA_ARG_ELEMENT_TARGET, "target" }, - { CA_ARG_ELEMENT_TRIGGER, "trigger" }, - { CA_ARG_ELEMENT_ACTION, "action ->" }, - - { -1, NULL } + { CA_ARG_NUMBER_HEADLINE, "[number]" }, + { CA_ARG_1, "1" }, + { CA_ARG_2, "2" }, + { CA_ARG_3, "3" }, + { CA_ARG_4, "4" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_ELEMENT_HEADLINE, "[element]" }, + { CA_ARG_ELEMENT_TARGET, "target" }, + { CA_ARG_ELEMENT_TRIGGER, "trigger" }, + { CA_ARG_ELEMENT_ACTION, "action ->" }, + + { -1, NULL } }; static struct ValueTextInfo options_action_arg_key[] = { - { CA_ARG_NUMBER_HEADLINE, "[number]" }, - { CA_ARG_1, "1" }, - { CA_ARG_2, "2" }, - { CA_ARG_3, "3" }, - { CA_ARG_4, "4" }, - { CA_ARG_5, "5" }, - { CA_ARG_6, "6" }, - { CA_ARG_7, "7" }, - { CA_ARG_8, "8" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_ELEMENT_HEADLINE, "[element]" }, - { CA_ARG_ELEMENT_TARGET, "target" }, - { CA_ARG_ELEMENT_TRIGGER, "trigger" }, - { CA_ARG_ELEMENT_ACTION, "action ->" }, - - { -1, NULL } + { CA_ARG_NUMBER_HEADLINE, "[number]" }, + { CA_ARG_1, "1" }, + { CA_ARG_2, "2" }, + { CA_ARG_3, "3" }, + { CA_ARG_4, "4" }, + { CA_ARG_5, "5" }, + { CA_ARG_6, "6" }, + { CA_ARG_7, "7" }, + { CA_ARG_8, "8" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_ELEMENT_HEADLINE, "[element]" }, + { CA_ARG_ELEMENT_TARGET, "target" }, + { CA_ARG_ELEMENT_TRIGGER, "trigger" }, + { CA_ARG_ELEMENT_ACTION, "action ->" }, + + { -1, NULL } }; static struct ValueTextInfo options_action_arg_speed[] = { - { CA_ARG_SPEED_HEADLINE, "[speed]" }, - { CA_ARG_SPEED_NOT_MOVING, "frozen" }, - { CA_ARG_SPEED_VERY_SLOW, "very slow" }, - { CA_ARG_SPEED_SLOW, "slow" }, - { CA_ARG_SPEED_NORMAL, "normal" }, - { CA_ARG_SPEED_FAST, "fast" }, - { CA_ARG_SPEED_VERY_FAST, "very fast" }, - { CA_ARG_SPEED_EVEN_FASTER, "ultrafast" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_SPEED_SLOWER, "slower" }, - { CA_ARG_SPEED_FASTER, "faster" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_SPEED_RESET, "reset" }, - - { -1, NULL } + { CA_ARG_SPEED_HEADLINE, "[speed]" }, + { CA_ARG_SPEED_NOT_MOVING, "frozen" }, + { CA_ARG_SPEED_VERY_SLOW, "very slow" }, + { CA_ARG_SPEED_SLOW, "slow" }, + { CA_ARG_SPEED_NORMAL, "normal" }, + { CA_ARG_SPEED_FAST, "fast" }, + { CA_ARG_SPEED_VERY_FAST, "very fast" }, + { CA_ARG_SPEED_EVEN_FASTER, "ultrafast" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_SPEED_SLOWER, "slower" }, + { CA_ARG_SPEED_FASTER, "faster" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_SPEED_RESET, "reset" }, + + { -1, NULL } }; static struct ValueTextInfo options_action_arg_shield[] = { - { CA_ARG_SHIELD_HEADLINE, "[shield]" }, - { CA_ARG_SHIELD_OFF, "off" }, - { CA_ARG_SHIELD_NORMAL, "normal" }, - { CA_ARG_SHIELD_DEADLY, "deadly" }, + { CA_ARG_SHIELD_HEADLINE, "[shield]" }, + { CA_ARG_SHIELD_OFF, "off" }, + { CA_ARG_SHIELD_NORMAL, "normal" }, + { CA_ARG_SHIELD_DEADLY, "deadly" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_action_arg_artwork[] = { - { CA_ARG_ELEMENT_HEADLINE, "[element]" }, - { CA_ARG_ELEMENT_TARGET, "target" }, - { CA_ARG_ELEMENT_TRIGGER, "trigger" }, - { CA_ARG_ELEMENT_ACTION, "action ->" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_ELEMENT_RESET, "reset" }, + { CA_ARG_ELEMENT_HEADLINE, "[element]" }, + { CA_ARG_ELEMENT_TARGET, "target" }, + { CA_ARG_ELEMENT_TRIGGER, "trigger" }, + { CA_ARG_ELEMENT_ACTION, "action ->" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_ELEMENT_RESET, "reset" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_action_arg_gravity[] = { - { CA_ARG_GRAVITY_HEADLINE, "[gravity]" }, - { CA_ARG_GRAVITY_ON, "on" }, - { CA_ARG_GRAVITY_OFF, "off" }, - { CA_ARG_GRAVITY_TOGGLE, "toggle" }, + { CA_ARG_GRAVITY_HEADLINE, "[gravity]" }, + { CA_ARG_GRAVITY_ON, "on" }, + { CA_ARG_GRAVITY_OFF, "off" }, + { CA_ARG_GRAVITY_TOGGLE, "toggle" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_action_arg_direction[] = { - { CA_ARG_DIRECTION_HEADLINE, "[dir.]" }, - { CA_ARG_DIRECTION_NONE, "none" }, - { CA_ARG_DIRECTION_LEFT, "left" }, - { CA_ARG_DIRECTION_RIGHT, "right" }, - { CA_ARG_DIRECTION_UP, "up" }, - { CA_ARG_DIRECTION_DOWN, "down" }, - { CA_ARG_DIRECTION_TRIGGER, "trigger" }, - { CA_ARG_DIRECTION_TRIGGER_BACK, "-trigger" }, + { CA_ARG_DIRECTION_HEADLINE, "[dir.]" }, + { CA_ARG_DIRECTION_NONE, "none" }, + { CA_ARG_DIRECTION_LEFT, "left" }, + { CA_ARG_DIRECTION_RIGHT, "right" }, + { CA_ARG_DIRECTION_UP, "up" }, + { CA_ARG_DIRECTION_DOWN, "down" }, + { CA_ARG_DIRECTION_TRIGGER, "trigger" }, + { CA_ARG_DIRECTION_TRIGGER_BACK, "-trigger" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_action_arg_scan_mode[] = { - { CA_ARG_SCAN_MODE_HEADLINE, "[mode]" }, - { CA_ARG_SCAN_MODE_NORMAL, "normal" }, - { CA_ARG_SCAN_MODE_REVERSE, "reverse" }, + { CA_ARG_SCAN_MODE_HEADLINE, "[mode]" }, + { CA_ARG_SCAN_MODE_NORMAL, "normal" }, + { CA_ARG_SCAN_MODE_REVERSE, "reverse" }, - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_action_arg_inventory[] = { - { CA_ARG_INVENTORY_HEADLINE, "[add]" }, - { CA_ARG_ELEMENT_TARGET, "+ target" }, - { CA_ARG_ELEMENT_TRIGGER, "+ trigger" }, - { CA_ARG_ELEMENT_ACTION, "+ action" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_INVENTORY_RM_HEADLINE,"[remove]" }, - { CA_ARG_INVENTORY_RM_TARGET, "- target" }, - { CA_ARG_INVENTORY_RM_TRIGGER,"- trigger" }, - { CA_ARG_INVENTORY_RM_ACTION, "- action" }, - { CA_ARG_INVENTORY_RM_FIRST, "- first" }, - { CA_ARG_INVENTORY_RM_LAST, "- last" }, - { CA_ARG_INVENTORY_RM_ALL, "- all" }, - { CA_ARG_UNDEFINED, " " }, - { CA_ARG_INVENTORY_RESET, "reset" }, - - { -1, NULL } + { CA_ARG_INVENTORY_HEADLINE, "[add]" }, + { CA_ARG_ELEMENT_TARGET, "+ target" }, + { CA_ARG_ELEMENT_TRIGGER, "+ trigger" }, + { CA_ARG_ELEMENT_ACTION, "+ action" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_INVENTORY_RM_HEADLINE, "[remove]" }, + { CA_ARG_INVENTORY_RM_TARGET, "- target" }, + { CA_ARG_INVENTORY_RM_TRIGGER, "- trigger" }, + { CA_ARG_INVENTORY_RM_ACTION, "- action" }, + { CA_ARG_INVENTORY_RM_FIRST, "- first" }, + { CA_ARG_INVENTORY_RM_LAST, "- last" }, + { CA_ARG_INVENTORY_RM_ALL, "- all" }, + { CA_ARG_UNDEFINED, " " }, + { CA_ARG_INVENTORY_RESET, "reset" }, + + { -1, NULL } }; static char options_change_page_strings[MAX_CHANGE_PAGES][10]; static struct ValueTextInfo options_change_page[MAX_CHANGE_PAGES + 1] = { - { -1, NULL } + { -1, NULL } }; static struct ValueTextInfo options_group_choice_mode[] = { - { ANIM_RANDOM, "random" }, - { ANIM_LOOP, "loop" }, - { ANIM_LINEAR, "linear" }, - { ANIM_PINGPONG, "pingpong" }, - { ANIM_PINGPONG2, "pingpong 2" }, + { ANIM_RANDOM, "random" }, + { ANIM_LOOP, "loop" }, + { ANIM_LINEAR, "linear" }, + { ANIM_PINGPONG, "pingpong" }, + { ANIM_PINGPONG2, "pingpong 2" }, + { ANIM_LEVEL_NR, "level number" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_bd_scheduling_type[] = +{ + { GD_SCHEDULING_MILLISECONDS, "Milliseconds" }, + { GD_SCHEDULING_BD1, "BD1" }, + { GD_SCHEDULING_BD2, "BD2" }, + { GD_SCHEDULING_PLCK, "Construction Kit" }, + { GD_SCHEDULING_CRDR, "Crazy Dream 7" }, + { GD_SCHEDULING_BD1_ATARI, "Atari BD1" }, + { GD_SCHEDULING_BD2_PLCK_ATARI, "Atari BD2 / PLCK" }, + + { -1, NULL } +}; + +static struct ValueTextInfo options_bd_color_type[] = +{ + { GD_COLOR_TYPE_RGB, "RGB colors" }, + { GD_COLOR_TYPE_C64, "C64 colors" }, + { GD_COLOR_TYPE_C64DTV, "C64DTV colors" }, + { GD_COLOR_TYPE_ATARI, "Atari colors" }, + + { -1, NULL } +}; - { -1, NULL } +static struct ValueTextInfo options_bd_color_c64_name[] = +{ + { GD_COLOR_INDEX_BLACK, "Black" }, + { GD_COLOR_INDEX_WHITE, "White" }, + { GD_COLOR_INDEX_RED, "Red" }, + { GD_COLOR_INDEX_CYAN, "Cyan" }, + { GD_COLOR_INDEX_PURPLE, "Purple" }, + { GD_COLOR_INDEX_GREEN, "Green" }, + { GD_COLOR_INDEX_BLUE, "Blue" }, + { GD_COLOR_INDEX_YELLOW, "Yellow" }, + { GD_COLOR_INDEX_ORANGE, "Orange" }, + { GD_COLOR_INDEX_BROWN, "Brown" }, + { GD_COLOR_INDEX_LIGHTRED, "Light red" }, + { GD_COLOR_INDEX_GRAY1, "Dark gray" }, + { GD_COLOR_INDEX_GRAY2, "Gray" }, + { GD_COLOR_INDEX_LIGHTGREEN, "Light green" }, + { GD_COLOR_INDEX_LIGHTBLUE, "Light blue" }, + { GD_COLOR_INDEX_GRAY3, "Light gray" }, + + { -1, NULL } }; static struct ValueTextInfo *action_arg_modes[] = @@ -2413,6 +3021,7 @@ action_arg_options[] = { CA_EXIT_PLAYER, 0, options_action_arg_player, }, { CA_KILL_PLAYER, 0, options_action_arg_player, }, { CA_MOVE_PLAYER, 0, options_action_arg_direction, }, + { CA_MOVE_PLAYER_NEW, 0, options_action_arg_direction, }, { CA_RESTART_LEVEL, 0, options_action_arg_none, }, { CA_SHOW_ENVELOPE, 0, options_action_arg_envelope, }, { CA_SET_LEVEL_TIME, 3, options_action_arg_number, }, @@ -2436,6 +3045,7 @@ action_arg_options[] = static struct { + int gadget_type_id; int x, y; int gadget_id; int gadget_id_align; @@ -2448,267 +3058,413 @@ static struct // ---------- level and editor settings ------------------------------------- { - -1, ED_LEVEL_SETTINGS_YPOS(8), - GADGET_ID_TIME_OR_STEPS, GADGET_ID_LEVEL_TIMELIMIT_UP, + ED_SELECTBOX_ID_TIME_OR_STEPS, + -1, ED_LEVEL_SETTINGS_YPOS(8), + GADGET_ID_TIME_OR_STEPS, GADGET_ID_LEVEL_TIMELIMIT_UP, -1, options_time_or_steps, &level.use_step_counter, - NULL, NULL, "(0 => no limit)", "time or step limit" + NULL, NULL, "(0 => no limit)", "Select time or step limit" }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(11), - GADGET_ID_GAME_ENGINE_TYPE, GADGET_ID_NONE, + ED_SELECTBOX_ID_TIME_SCORE_BASE, + -1, ED_LEVEL_SETTINGS_YPOS(10), + GADGET_ID_TIME_SCORE_BASE, GADGET_ID_LEVEL_TIMESCORE_UP, + -1, + options_time_score_base, + &level.time_score_base, + NULL, NULL, NULL, "Select time score for 1 or 10 seconds/steps" + }, + { + ED_SELECTBOX_ID_GAME_ENGINE_TYPE, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(12), + GADGET_ID_GAME_ENGINE_TYPE, GADGET_ID_NONE, -1, options_game_engine_type, &level.game_engine_type, - NULL, "game engine:", NULL, "game engine" + NULL, "Game engine:", NULL, "Select game engine" }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(10), - GADGET_ID_LEVELSET_SAVE_MODE, GADGET_ID_NONE, + ED_SELECTBOX_ID_LEVELSET_SAVE_MODE, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(10), + GADGET_ID_LEVELSET_SAVE_MODE, GADGET_ID_NONE, -1, options_levelset_save_mode, &levelset_save_mode, - "Action:", NULL, NULL, "action when saving level set" + "Action:", NULL, NULL, "Select action when saving level set" + }, + + // ---------- engine settings: config --------------------------------------- + + { + ED_SELECTBOX_ID_BD_SCHEDULING_TYPE, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(1), + GADGET_ID_BD_SCHEDULING_TYPE, GADGET_ID_NONE, + -1, + options_bd_scheduling_type, + &level.bd_scheduling_type, + NULL, "Scheduling type:", NULL, "Select level timing" + }, + + // ---------- engine settings: colors --------------------------------------- + + { + ED_SELECTBOX_ID_BD_COLOR_TYPE, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(0), + GADGET_ID_BD_COLOR_TYPE, GADGET_ID_NONE, + -1, + options_bd_color_type, + &level.bd_color_type, + "Boulder Dash level colors:", + "Color palette type:", NULL, "Select color palette type" + }, + { + ED_SELECTBOX_ID_BD_COLOR_C64_B, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(1), + GADGET_ID_BD_COLOR_C64_B, GADGET_ID_NONE, + -1, + options_bd_color_c64_name, + &bd_color_c64[0], + NULL, "Border color: ", NULL, "Select border color (not used)" + }, + { + ED_SELECTBOX_ID_BD_COLOR_C64_0, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(2), + GADGET_ID_BD_COLOR_C64_0, GADGET_ID_NONE, + -1, + options_bd_color_c64_name, + &bd_color_c64[1], + NULL, "Background color: ", NULL, "Select background color (C64 graphics)" + }, + { + ED_SELECTBOX_ID_BD_COLOR_C64_1, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(3), + GADGET_ID_BD_COLOR_C64_1, GADGET_ID_NONE, + -1, + options_bd_color_c64_name, + &bd_color_c64[2], + NULL, "Sand color: ", NULL, "Select sand color (C64 graphics)" + }, + { + ED_SELECTBOX_ID_BD_COLOR_C64_2, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(4), + GADGET_ID_BD_COLOR_C64_2, GADGET_ID_NONE, + -1, + options_bd_color_c64_name, + &bd_color_c64[3], + NULL, "Steel wall color: ", NULL, "Select steel wall color (C64 graphics)" + }, + { + ED_SELECTBOX_ID_BD_COLOR_C64_3, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(5), + GADGET_ID_BD_COLOR_C64_3, GADGET_ID_NONE, + -1, + options_bd_color_c64_name, + &bd_color_c64[4], + NULL, "Wall color: ", NULL, "Select wall color (C64 graphics)" + }, + { + ED_SELECTBOX_ID_BD_COLOR_C64_4, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(6), + GADGET_ID_BD_COLOR_C64_4, GADGET_ID_NONE, + -1, + options_bd_color_c64_name, + &bd_color_c64[5], + NULL, "Amoeba color: ", NULL, "Select amoeba color (C64 graphics)" + }, + { + ED_SELECTBOX_ID_BD_COLOR_C64_5, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(7), + GADGET_ID_BD_COLOR_C64_5, GADGET_ID_NONE, + -1, + options_bd_color_c64_name, + &bd_color_c64[6], + NULL, "Slime color: ", NULL, "Select slime color (C64 graphics)" }, // ---------- element settings: configure (several elements) ---------------- { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), - GADGET_ID_WIND_DIRECTION, GADGET_ID_NONE, + ED_SELECTBOX_ID_WIND_DIRECTION, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + GADGET_ID_WIND_DIRECTION, GADGET_ID_NONE, -1, options_wind_direction, &level.wind_direction_initial, - NULL, "initial wind direction:", NULL, "initial wind direction" + NULL, "Initial wind direction:", NULL, "Select initial wind direction" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7), - GADGET_ID_PLAYER_SPEED, GADGET_ID_NONE, + ED_SELECTBOX_ID_PLAYER_SPEED, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7), + GADGET_ID_PLAYER_SPEED, GADGET_ID_NONE, -1, options_player_speed, &level.initial_player_stepsize[0], - NULL, "initial player speed:", NULL, "initial player speed" + NULL, "Initial player speed:", NULL, "Select initial player speed" + }, + { + ED_SELECTBOX_ID_BD_GRAVITY_DIRECTION, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + GADGET_ID_BD_GRAVITY_DIRECTION, GADGET_ID_NONE, + -1, + options_bd_gravity_direction, + &level.bd_gravity_direction, + NULL, "Gravity direction:", NULL, "Select initial gravity direction" + }, + { + ED_SELECTBOX_ID_MM_BALL_CHOICE_MODE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), + GADGET_ID_MM_BALL_CHOICE_MODE, GADGET_ID_NONE, + -1, + options_group_choice_mode, + &level.mm_ball_choice_mode, + NULL, "Choice type:", NULL, "Select type of content choice" }, // ---------- element settings: configure 1 (custom elements) --------------- { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(2), - GADGET_ID_CUSTOM_ACCESS_TYPE, GADGET_ID_NONE, + ED_SELECTBOX_ID_CUSTOM_ACCESS_TYPE, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_CUSTOM_ACCESS_TYPE, GADGET_ID_NONE, -1, options_access_type, &custom_element.access_type, - NULL, NULL, NULL, "type of access to this field" + NULL, NULL, NULL, "Select type of access to this field" }, { - -1, ED_ELEMENT_SETTINGS_YPOS(2), - GADGET_ID_CUSTOM_ACCESS_LAYER, GADGET_ID_CUSTOM_ACCESS_TYPE, + ED_SELECTBOX_ID_CUSTOM_ACCESS_LAYER, + -1, ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_CUSTOM_ACCESS_LAYER, GADGET_ID_CUSTOM_ACCESS_TYPE, -1, options_access_layer, &custom_element.access_layer, - NULL, NULL, NULL, "layer of access for this field" + NULL, NULL, NULL, "Select layer of access for this field" }, { - -1, ED_ELEMENT_SETTINGS_YPOS(2), - GADGET_ID_CUSTOM_ACCESS_PROTECTED, GADGET_ID_CUSTOM_ACCESS_LAYER, + ED_SELECTBOX_ID_CUSTOM_ACCESS_PROTECTED, + -1, ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_CUSTOM_ACCESS_PROTECTED, GADGET_ID_CUSTOM_ACCESS_LAYER, -1, options_access_protected, &custom_element.access_protected, - NULL, NULL, NULL, "protected access for this field" + NULL, NULL, NULL, "Select protected access for this field" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(3), - GADGET_ID_CUSTOM_ACCESS_DIRECTION, GADGET_ID_NONE, + ED_SELECTBOX_ID_CUSTOM_ACCESS_DIRECTION, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(3), + GADGET_ID_CUSTOM_ACCESS_DIRECTION, GADGET_ID_NONE, -1, options_access_direction, &custom_element.access_direction, - NULL, "from", NULL, "access direction for this field" + NULL, "from", NULL, "Select access direction for this field" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(4), - GADGET_ID_CUSTOM_WALK_TO_ACTION, GADGET_ID_NONE, + ED_SELECTBOX_ID_CUSTOM_WALK_TO_ACTION, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(4), + GADGET_ID_CUSTOM_WALK_TO_ACTION, GADGET_ID_NONE, -1, options_walk_to_action, &custom_element.walk_to_action, - NULL, NULL, NULL, "diggable/collectible/pushable" + NULL, NULL, NULL, "Select diggable/collectible/pushable" }, // ---------- element settings: configure 2 (custom elements) --------------- { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(1), - GADGET_ID_CUSTOM_MOVE_PATTERN, GADGET_ID_NONE, + ED_SELECTBOX_ID_CUSTOM_MOVE_PATTERN, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_CUSTOM_MOVE_PATTERN, GADGET_ID_NONE, -1, options_move_pattern, &custom_element.move_pattern, - NULL, "can move", NULL, "element move pattern" + NULL, "Can move", NULL, "Select element move pattern" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(2), - GADGET_ID_CUSTOM_MOVE_DIRECTION, GADGET_ID_NONE, + ED_SELECTBOX_ID_CUSTOM_MOVE_DIRECTION, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_CUSTOM_MOVE_DIRECTION, GADGET_ID_NONE, -1, options_move_direction, &custom_element.move_direction_initial, - NULL, "starts moving", NULL, "initial element move direction" + NULL, "Starts moving", NULL, "Select initial element move direction" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(4), - GADGET_ID_CUSTOM_MOVE_STEPSIZE, GADGET_ID_NONE, + ED_SELECTBOX_ID_CUSTOM_MOVE_STEPSIZE, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(4), + GADGET_ID_CUSTOM_MOVE_STEPSIZE, GADGET_ID_NONE, -1, options_move_stepsize, &custom_element.move_stepsize, - NULL, "move/fall speed", NULL, "speed of element movement" + NULL, "Move/fall speed", NULL, "Select speed of element movement" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(3), - GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE, GADGET_ID_NONE, + ED_SELECTBOX_ID_CUSTOM_MOVE_LEAVE_TYPE, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(3), + GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE, GADGET_ID_NONE, -1, options_move_leave_type, &custom_element.move_leave_type, // left text with leading spaces to place gadget next to "can dig" gadget // (needed because drawing area gadgets created after selectbox gadgets) - // NULL, "can dig: can", ":", "leave behind or change element" - NULL, " can", ":", "leave behind or change element" + // NULL, "can dig: can", ":", "leave behind or change element" + NULL, " Can", ":", "Select leave behind or change element" }, { - -1, ED_ELEMENT_SETTINGS_YPOS(7), - GADGET_ID_CUSTOM_SMASH_TARGETS, GADGET_ID_CUSTOM_CAN_SMASH, + ED_SELECTBOX_ID_CUSTOM_SMASH_TARGETS, + -1, ED_ELEMENT_SETTINGS_YPOS(8), + GADGET_ID_CUSTOM_SMASH_TARGETS, GADGET_ID_CUSTOM_CAN_SMASH, -1, options_smash_targets, &custom_element.smash_targets, - NULL, "can smash", NULL, "elements that can be smashed" + NULL, "Can smash", NULL, "Select elements that can be smashed" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(8), - GADGET_ID_CUSTOM_SLIPPERY_TYPE, GADGET_ID_NONE, + ED_SELECTBOX_ID_CUSTOM_SLIPPERY_TYPE, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(9), + GADGET_ID_CUSTOM_SLIPPERY_TYPE, GADGET_ID_NONE, -1, options_slippery_type, &custom_element.slippery_type, - NULL, "slippery", NULL, "where other elements fall down" + NULL, "Slippery", NULL, "Select where other elements fall down" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(9), - GADGET_ID_CUSTOM_DEADLINESS, GADGET_ID_NONE, + ED_SELECTBOX_ID_CUSTOM_DEADLINESS, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(10), + GADGET_ID_CUSTOM_DEADLINESS, GADGET_ID_NONE, -1, options_deadliness, &custom_element.deadliness, - NULL, "deadly when", NULL, "deadliness of element" + NULL, "Deadly when", NULL, "Select deadliness of element" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(10), - GADGET_ID_CUSTOM_EXPLOSION_TYPE, GADGET_ID_NONE, + ED_SELECTBOX_ID_CUSTOM_EXPLOSION_TYPE, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(11), + GADGET_ID_CUSTOM_EXPLOSION_TYPE, GADGET_ID_NONE, -1, options_explosion_type, &custom_element.explosion_type, - NULL, "can explode", NULL, "explosion type" + NULL, "Can explode", NULL, "Select explosion type" }, // ---------- element settings: advanced (custom elements) ------------------ { - ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(3), - GADGET_ID_CHANGE_TIME_UNITS, GADGET_ID_NONE, + ED_SELECTBOX_ID_CHANGE_TIME_UNITS, + ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(3), + GADGET_ID_CHANGE_TIME_UNITS, GADGET_ID_NONE, -1, options_time_units, &custom_element_change.delay_frames, - NULL, "delay time given in", NULL, "delay time units for change" + NULL, "Delay time given in", NULL, "Select delay time units for change" }, { - ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(4), - GADGET_ID_CHANGE_DIRECT_ACTION, GADGET_ID_NONE, + ED_SELECTBOX_ID_CHANGE_DIRECT_ACTION, + ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(4), + GADGET_ID_CHANGE_DIRECT_ACTION, GADGET_ID_NONE, -1, options_change_direct_action, &custom_element_change.direct_action, - NULL, NULL, NULL, "type of direct action" + NULL, NULL, NULL, "Select type of direct action" }, { - ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(5), - GADGET_ID_CHANGE_OTHER_ACTION, GADGET_ID_NONE, + ED_SELECTBOX_ID_CHANGE_OTHER_ACTION, + ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(5), + GADGET_ID_CHANGE_OTHER_ACTION, GADGET_ID_NONE, -1, options_change_other_action, &custom_element_change.other_action, - NULL, NULL, "element:", "type of other element action" + NULL, NULL, "element:", "Select type of other element action" }, { - ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(6), - GADGET_ID_CHANGE_SIDE, GADGET_ID_NONE, + ED_SELECTBOX_ID_CHANGE_SIDE, + ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(6), + GADGET_ID_CHANGE_SIDE, GADGET_ID_NONE, -1, options_change_trigger_side, &custom_element_change.trigger_side, - NULL, "at", "side", "element side triggering change" + NULL, "at", "side", "Select element side triggering change" }, { - ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(7), - GADGET_ID_CHANGE_PLAYER, GADGET_ID_NONE, + ED_SELECTBOX_ID_CHANGE_PLAYER, + ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(7), + GADGET_ID_CHANGE_PLAYER, GADGET_ID_NONE, -1, options_change_trigger_player, &custom_element_change.trigger_player, - NULL, "player:", " ", "player that causes change" + NULL, "Player:", " ", "Select player that causes change" }, { - ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(7), - GADGET_ID_CHANGE_PAGE, GADGET_ID_CHANGE_PLAYER, + ED_SELECTBOX_ID_CHANGE_PAGE, + ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(7), + GADGET_ID_CHANGE_PAGE, GADGET_ID_CHANGE_PLAYER, -1, options_change_trigger_page, &custom_element_change.trigger_page, - NULL, "page:", NULL, "change page that causes change" + NULL, "Page:", NULL, "Select change page that causes change" }, { - ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(10), - GADGET_ID_CHANGE_REPLACE_WHEN, GADGET_ID_NONE, + ED_SELECTBOX_ID_CHANGE_REPLACE_WHEN, + ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(10), + GADGET_ID_CHANGE_REPLACE_WHEN, GADGET_ID_NONE, -1, options_change_replace_when, &custom_element_change.replace_when, - NULL, "replace when", NULL, "which elements can be replaced" + NULL, "Replace when", NULL, "Select which elements can be replaced" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(13), - GADGET_ID_ACTION_TYPE, GADGET_ID_NONE, - -1, + ED_SELECTBOX_ID_ACTION_TYPE, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(13), + GADGET_ID_ACTION_TYPE, GADGET_ID_NONE, + 15, options_action_type, &custom_element_change.action_type, - NULL, NULL, NULL, "action on specified condition" + NULL, NULL, NULL, "Select action on specified condition" }, { - -1, ED_ELEMENT_SETTINGS_YPOS(13), - GADGET_ID_ACTION_MODE, GADGET_ID_ACTION_TYPE, + ED_SELECTBOX_ID_ACTION_MODE, + -1, ED_ELEMENT_SETTINGS_YPOS(13), + GADGET_ID_ACTION_MODE, GADGET_ID_ACTION_TYPE, -1, options_action_mode_none, &custom_element_change.action_mode, - NULL, NULL, NULL, "action operator" + NULL, NULL, NULL, "Select action operator" }, { - -1, ED_ELEMENT_SETTINGS_YPOS(13), - GADGET_ID_ACTION_ARG, GADGET_ID_ACTION_MODE, + ED_SELECTBOX_ID_ACTION_ARG, + -1, ED_ELEMENT_SETTINGS_YPOS(13), + GADGET_ID_ACTION_ARG, GADGET_ID_ACTION_MODE, -1, options_action_arg_none, &custom_element_change.action_arg, - NULL, NULL, NULL, "action parameter" + NULL, NULL, NULL, "Select action parameter" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(14), - GADGET_ID_SELECT_CHANGE_PAGE, GADGET_ID_NONE, + ED_SELECTBOX_ID_SELECT_CHANGE_PAGE, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(14), + GADGET_ID_SELECT_CHANGE_PAGE, GADGET_ID_NONE, 3, options_change_page, &custom_element.current_change_page, - NULL, NULL, NULL, "element change page" + NULL, NULL, NULL, "Select element change page" }, // ---------- element settings: configure (group elements) ------------------ { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), - GADGET_ID_GROUP_CHOICE_MODE, GADGET_ID_NONE, + ED_SELECTBOX_ID_GROUP_CHOICE_MODE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), + GADGET_ID_GROUP_CHOICE_MODE, GADGET_ID_NONE, -1, options_group_choice_mode, &group_element_info.choice_mode, - NULL, "choice type:", NULL, "type of group element choice" + NULL, "Choice type:", NULL, "Select type of group element choice" }, }; static struct { + int gadget_type_id; int x, y; int gadget_id; int gadget_id_align; @@ -2720,98 +3476,146 @@ static struct // ---------- level and editor settings (tabs) ------------------------------ { - ED_LEVEL_TABS_XPOS(0), ED_LEVEL_TABS_YPOS(0), - GADGET_ID_LEVELINFO_LEVEL, GADGET_ID_NONE, - 8, "Level", - NULL, NULL, NULL, "Configure level properties" + ED_TEXTBUTTON_ID_LEVELCONFIG_LEVEL, + ED_LEVEL_TABS_XPOS(0), ED_LEVEL_TABS_YPOS(0), + GADGET_ID_LEVELCONFIG_LEVEL, GADGET_ID_NONE, + 8, "Level", + NULL, NULL, NULL, "Configure level settings" + }, + { + ED_TEXTBUTTON_ID_LEVELCONFIG_LEVELSET, + -1, -1, + GADGET_ID_LEVELCONFIG_LEVELSET, GADGET_ID_LEVELCONFIG_LEVEL, + 8, "Levelset", + NULL, NULL, NULL, "Update this or create new level set" + }, + { + ED_TEXTBUTTON_ID_LEVELCONFIG_EDITOR, + -1, -1, + GADGET_ID_LEVELCONFIG_EDITOR, GADGET_ID_LEVELCONFIG_LEVELSET, + 8, "Editor", + NULL, NULL, NULL, "Configure editor settings" + }, + { + ED_TEXTBUTTON_ID_LEVELCONFIG_ENGINE, + -1, -1, + GADGET_ID_LEVELCONFIG_ENGINE, GADGET_ID_LEVELCONFIG_EDITOR, + 8, "Engine", + NULL, NULL, NULL, "Configure game engine settings" }, + + // ---------- engine settings (tabs) ---------------------------------------- + { - -1, -1, - GADGET_ID_LEVELINFO_LEVELSET, GADGET_ID_LEVELINFO_LEVEL, - 8, "Levelset", - NULL, NULL, NULL, "Update this or create new level set" + ED_TEXTBUTTON_ID_ENGINECONFIG_CONFIG, + ED_ENGINE_TABS_XPOS(0), ED_ENGINE_TABS_YPOS(0), + GADGET_ID_ENGINECONFIG_CONFIG, GADGET_ID_NONE, + 8, "Config", + NULL, NULL, NULL, "Configure game engine settings" }, { - -1, -1, - GADGET_ID_LEVELINFO_EDITOR, GADGET_ID_LEVELINFO_LEVELSET, - 8, "Editor", - NULL, NULL, NULL, "Configure editor properties" + ED_TEXTBUTTON_ID_ENGINECONFIG_COLORS, + -1, -1, + GADGET_ID_ENGINECONFIG_COLORS, GADGET_ID_ENGINECONFIG_CONFIG, + 8, "Colors", + NULL, NULL, NULL, "Configure level colors" }, // ---------- element settings (tabs) --------------------------------------- { - ED_ELEMENT_TABS_XPOS(0), ED_ELEMENT_TABS_YPOS(0), - GADGET_ID_PROPERTIES_INFO, GADGET_ID_NONE, - 8, "Info", - NULL, NULL, NULL, "Show information about element" + ED_TEXTBUTTON_ID_PROPERTIES_INFO, + ED_ELEMENT_TABS_XPOS(0), ED_ELEMENT_TABS_YPOS(0), + GADGET_ID_PROPERTIES_INFO, GADGET_ID_NONE, + 8, "Info", + NULL, NULL, NULL, "Show information about element" }, { - -1, -1, - GADGET_ID_PROPERTIES_CONFIG, GADGET_ID_PROPERTIES_INFO, - 8, "Config", - NULL, NULL, NULL, "Configure element properties" + ED_TEXTBUTTON_ID_PROPERTIES_CONFIG, + -1, -1, + GADGET_ID_PROPERTIES_CONFIG, GADGET_ID_PROPERTIES_INFO, + 8, "Config", + NULL, NULL, NULL, "Configure element properties" }, { - -1, -1, - GADGET_ID_PROPERTIES_CONFIG_1, GADGET_ID_PROPERTIES_INFO, - 8, "Config 1", - NULL, NULL, NULL, "Configure element properties, part 1" + ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_1, + -1, -1, + GADGET_ID_PROPERTIES_CONFIG_1, GADGET_ID_PROPERTIES_INFO, + 8, "Config 1", + NULL, NULL, NULL, "Configure element properties, part 1" }, { - -1, -1, - GADGET_ID_PROPERTIES_CONFIG_2, GADGET_ID_PROPERTIES_CONFIG_1, - 8, "Config 2", - NULL, NULL, NULL, "Configure element properties, part 2" + ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_2, + -1, -1, + GADGET_ID_PROPERTIES_CONFIG_2, GADGET_ID_PROPERTIES_CONFIG_1, + 8, "Config 2", + NULL, NULL, NULL, "Configure element properties, part 2" }, { - -1, -1, - GADGET_ID_PROPERTIES_CHANGE, GADGET_ID_PROPERTIES_CONFIG_2, - 8, "Change", - NULL, NULL, NULL, "Configure custom element change pages" + ED_TEXTBUTTON_ID_PROPERTIES_CHANGE, + -1, -1, + GADGET_ID_PROPERTIES_CHANGE, GADGET_ID_PROPERTIES_CONFIG_2, + 8, "Change", + NULL, NULL, NULL, "Configure custom element change pages" }, // ---------- level and editor settings (buttons) --------------------------- { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(10), - GADGET_ID_SAVE_LEVELSET, GADGET_ID_LEVELSET_SAVE_MODE, - -1, "Save", - NULL, NULL, NULL, "Update or create level set" + ED_TEXTBUTTON_ID_SAVE_LEVELSET, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(10), + GADGET_ID_SAVE_LEVELSET, GADGET_ID_LEVELSET_SAVE_MODE, + -1, "Save", + NULL, NULL, NULL, "Update or create level set" }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(6), - GADGET_ID_SAVE_AS_TEMPLATE_2, GADGET_ID_NONE, - -1, "Save", - NULL, NULL, "this level as level template", + ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_2, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(6), + GADGET_ID_SAVE_AS_TEMPLATE_2, GADGET_ID_NONE, + -1, "Save", + NULL, NULL, "this level as level template", "Save current settings as new template" }, // ---------- element settings (buttons) ------------------------------------ { - -1, -1, - GADGET_ID_SAVE_AS_TEMPLATE_1, GADGET_ID_CUSTOM_USE_TEMPLATE_1, - -1, "Save", - NULL, " ", "As Template", + ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1, + -1, -1, + GADGET_ID_SAVE_AS_TEMPLATE_1, GADGET_ID_CUSTOM_USE_TEMPLATE_1, + -1, "Save", + NULL, " ", "As Template", "Save current settings as new template" }, { - -1, -1, - GADGET_ID_ADD_CHANGE_PAGE, GADGET_ID_PASTE_CHANGE_PAGE, - -1, "New", - NULL, NULL, NULL, "Add new change page" + ED_TEXTBUTTON_ID_ADD_CHANGE_PAGE, + -1, -1, + GADGET_ID_ADD_CHANGE_PAGE, GADGET_ID_PASTE_CHANGE_PAGE, + -1, "New", + NULL, NULL, NULL, "Add new change page" + }, + { + ED_TEXTBUTTON_ID_DEL_CHANGE_PAGE, + -1, -1, + GADGET_ID_DEL_CHANGE_PAGE, GADGET_ID_ADD_CHANGE_PAGE, + -1, "Delete", + NULL, NULL, NULL, "Delete current change page" }, + + // ---------- engine settings (buttons) ------------------------------------- + { - -1, -1, - GADGET_ID_DEL_CHANGE_PAGE, GADGET_ID_ADD_CHANGE_PAGE, - -1, "Delete", - NULL, NULL, NULL, "Delete current change page" + ED_TEXTBUTTON_ID_BD_SET_RANDOM_COLORS, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(8), + GADGET_ID_BD_SET_RANDOM_COLORS, GADGET_ID_NONE, + -1, "Set random colors", + NULL, NULL, NULL, "Create and set random level colors" }, }; static struct { + int gadget_type_id; int graphic; int x, y; int gadget_id; @@ -2820,28 +3624,32 @@ static struct } graphicbutton_info[ED_NUM_GRAPHICBUTTONS] = { { + ED_GRAPHICBUTTON_ID_PREV_CHANGE_PAGE, IMG_EDITOR_COUNTER_DOWN, - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(14), - GADGET_ID_PREV_CHANGE_PAGE, GADGET_ID_NONE, - NULL, NULL, "select previous change page" + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(14), + GADGET_ID_PREV_CHANGE_PAGE, GADGET_ID_NONE, + NULL, NULL, "Select previous change page" }, { + ED_GRAPHICBUTTON_ID_NEXT_CHANGE_PAGE, IMG_EDITOR_COUNTER_UP, - -1, ED_ELEMENT_SETTINGS_YPOS(14), - GADGET_ID_NEXT_CHANGE_PAGE, GADGET_ID_SELECT_CHANGE_PAGE, - NULL, "change page", "select next change page" + -1, ED_ELEMENT_SETTINGS_YPOS(14), + GADGET_ID_NEXT_CHANGE_PAGE, GADGET_ID_SELECT_CHANGE_PAGE, + NULL, "Change page", "Select next change page" }, { + ED_GRAPHICBUTTON_ID_COPY_CHANGE_PAGE, IMG_GFX_EDITOR_BUTTON_CP_COPY, - -1, ED_ELEMENT_SETTINGS_YPOS(14), - GADGET_ID_COPY_CHANGE_PAGE, GADGET_ID_NEXT_CHANGE_PAGE, - " ", NULL, "copy settings from this change page" + -1, ED_ELEMENT_SETTINGS_YPOS(14), + GADGET_ID_COPY_CHANGE_PAGE, GADGET_ID_NEXT_CHANGE_PAGE, + " ", NULL, "Copy settings from this change page" }, { + ED_GRAPHICBUTTON_ID_PASTE_CHANGE_PAGE, IMG_GFX_EDITOR_BUTTON_CP_PASTE, - -1, ED_ELEMENT_SETTINGS_YPOS(14), - GADGET_ID_PASTE_CHANGE_PAGE, GADGET_ID_COPY_CHANGE_PAGE, - NULL, NULL, "paste settings to this change page" + -1, ED_ELEMENT_SETTINGS_YPOS(14), + GADGET_ID_PASTE_CHANGE_PAGE, GADGET_ID_COPY_CHANGE_PAGE, + NULL, NULL, "Paste settings to this change page" }, }; @@ -2852,40 +3660,47 @@ static struct static struct { + int gadget_type_id; int graphic; int gadget_id; char *infotext; } scrollbutton_info[ED_NUM_SCROLLBUTTONS] = { { + ED_SCROLLBUTTON_ID_AREA_UP, IMG_EDITOR_PLAYFIELD_SCROLL_UP, GADGET_ID_SCROLL_UP, - "scroll level editing area up" + "Scroll level editing area up" }, { + ED_SCROLLBUTTON_ID_AREA_DOWN, IMG_EDITOR_PLAYFIELD_SCROLL_DOWN, GADGET_ID_SCROLL_DOWN, - "scroll level editing area down" + "Scroll level editing area down" }, { + ED_SCROLLBUTTON_ID_AREA_LEFT, IMG_EDITOR_PLAYFIELD_SCROLL_LEFT, GADGET_ID_SCROLL_LEFT, - "scroll level editing area left" + "Scroll level editing area left" }, { + ED_SCROLLBUTTON_ID_AREA_RIGHT, IMG_EDITOR_PLAYFIELD_SCROLL_RIGHT, GADGET_ID_SCROLL_RIGHT, - "scroll level editing area right" + "Scroll level editing area right" }, { + ED_SCROLLBUTTON_ID_LIST_UP, IMG_EDITOR_PALETTE_SCROLL_UP, GADGET_ID_SCROLL_LIST_UP, - "scroll element list up ('Page Up')" + "Scroll element list up ('Page Up')" }, { + ED_SCROLLBUTTON_ID_LIST_DOWN, IMG_EDITOR_PALETTE_SCROLL_DOWN, GADGET_ID_SCROLL_LIST_DOWN, - "scroll element list down ('Page Down')" + "Scroll element list down ('Page Down')" }, }; @@ -2899,6 +3714,7 @@ static struct static struct { + int gadget_type_id; int graphic; int type; int gadget_id; @@ -2906,28 +3722,32 @@ static struct } scrollbar_info[ED_NUM_SCROLLBARS] = { { + ED_SCROLLBAR_ID_AREA_HORIZONTAL, IMG_EDITOR_PLAYFIELD_SCROLLBAR, GD_TYPE_SCROLLBAR_HORIZONTAL, GADGET_ID_SCROLL_HORIZONTAL, - "scroll level editing area horizontally" + "Scroll level editing area horizontally" }, { + ED_SCROLLBAR_ID_AREA_VERTICAL, IMG_EDITOR_PLAYFIELD_SCROLLBAR, GD_TYPE_SCROLLBAR_VERTICAL, GADGET_ID_SCROLL_VERTICAL, - "scroll level editing area vertically" + "Scroll level editing area vertically" }, { + ED_SCROLLBAR_ID_LIST_VERTICAL, IMG_EDITOR_PALETTE_SCROLLBAR, GD_TYPE_SCROLLBAR_VERTICAL, GADGET_ID_SCROLL_LIST_VERTICAL, - "scroll element list vertically" + "Scroll element list vertically" } }; static struct { + int gadget_type_id; int x, y; int gadget_id; int gadget_id_align; @@ -2938,23 +3758,26 @@ static struct } radiobutton_info[ED_NUM_RADIOBUTTONS] = { { - -1, ED_LEVEL_SETTINGS_YPOS(0), - GADGET_ID_RANDOM_PERCENTAGE, GADGET_ID_LEVEL_RANDOM_UP, + ED_RADIOBUTTON_ID_PERCENTAGE, + -1, ED_LEVEL_SETTINGS_YPOS(0), + GADGET_ID_RANDOM_PERCENTAGE, GADGET_ID_LEVEL_RANDOM_UP, RADIO_NR_RANDOM_ELEMENTS, - &random_placement_method, RANDOM_USE_PERCENTAGE, - " ", "percentage", "use percentage for random elements" + &random_placement_method, RANDOM_USE_PERCENTAGE, + " ", "percentage", "Use percentage for random elements" }, { - -1, ED_LEVEL_SETTINGS_YPOS(0), - GADGET_ID_RANDOM_QUANTITY, GADGET_ID_RANDOM_PERCENTAGE, + ED_RADIOBUTTON_ID_QUANTITY, + -1, ED_LEVEL_SETTINGS_YPOS(0), + GADGET_ID_RANDOM_QUANTITY, GADGET_ID_RANDOM_PERCENTAGE, RADIO_NR_RANDOM_ELEMENTS, - &random_placement_method, RANDOM_USE_QUANTITY, - " ", "quantity", "use quantity for random elements" + &random_placement_method, RANDOM_USE_QUANTITY, + " ", "quantity", "Use quantity for random elements" } }; static struct { + int gadget_type_id; int x, y; int gadget_id; int gadget_id_align; @@ -2965,693 +3788,1424 @@ static struct // ---------- level and editor settings ------------------------------------- { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(6), - GADGET_ID_AUTO_COUNT_GEMS, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_AUTO_COUNT_GEMS, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(6), + GADGET_ID_AUTO_COUNT_GEMS, GADGET_ID_NONE, &level.auto_count_gems, NULL, NULL, - "automatically count gems needed", "set counter to number of gems" + "Automatically count gems needed", "Set counter to number of gems" + }, + { + ED_CHECKBUTTON_ID_RATE_TIME_OVER_SCORE, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(11), + GADGET_ID_RATE_TIME_OVER_SCORE, GADGET_ID_NONE, + &level.rate_time_over_score, + NULL, NULL, + "Rate time/steps used over score", "Sort high scores by playing time/steps" }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(7), - GADGET_ID_USE_LEVELSET_ARTWORK, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_USE_LEVELSET_ARTWORK, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(7), + GADGET_ID_USE_LEVELSET_ARTWORK, GADGET_ID_NONE, &levelset_use_levelset_artwork, NULL, NULL, - "use current custom artwork", "use custom artwork of this level set" + "Use current custom artwork", "Use custom artwork of this level set" }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(8), - GADGET_ID_COPY_LEVEL_TEMPLATE, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_COPY_LEVEL_TEMPLATE, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(8), + GADGET_ID_COPY_LEVEL_TEMPLATE, GADGET_ID_NONE, &levelset_copy_level_template, NULL, NULL, - "copy current level template", "copy level template of this level set" + "Copy current level template", "Copy level template of this level set" }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(1), - GADGET_ID_RANDOM_RESTRICTED, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_RANDOM_RESTRICTED, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(1), + GADGET_ID_RANDOM_RESTRICTED, GADGET_ID_NONE, &random_placement_background_restricted, NULL, NULL, - "restrict random placement to:", "set random placement restriction" + "Restrict random placement to:", "Set random placement restriction" }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(4), - GADGET_ID_CUSTOM_USE_TEMPLATE_3, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_3, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(4), + GADGET_ID_CUSTOM_USE_TEMPLATE_3, GADGET_ID_NONE, &setup.editor.use_template_for_new_levels, "Template for new levels and CE/GE:", NULL, - "use template for new levels", "use template for level properties" + "Use template for new levels", "Use template for level properties" }, { - ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(5), - GADGET_ID_CUSTOM_USE_TEMPLATE_2, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_2, + ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(5), + GADGET_ID_CUSTOM_USE_TEMPLATE_2, GADGET_ID_NONE, &level.use_custom_template, NULL, NULL, - "use template for custom elements", "use template for custom properties" + "Use template for custom elements", "Use template for custom properties" + }, + { + ED_CHECKBUTTON_ID_BD_INTERMISSION, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(0), + GADGET_ID_BD_INTERMISSION, GADGET_ID_NONE, + &level.bd_intermission, + "Boulder Dash game engine settings:", NULL, + "Intermission", "Level is an intermission level" + }, + { + ED_CHECKBUTTON_ID_BD_PAL_TIMING, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(2), + GADGET_ID_BD_PAL_TIMING, GADGET_ID_NONE, + &level.bd_pal_timing, + NULL, NULL, + "PAL timing", "Use slower timer (like PAL C64)" + }, + { + ED_CHECKBUTTON_ID_BD_LINE_SHIFTING_BORDERS, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(6), + GADGET_ID_BD_LINE_SHIFTING_BORDERS, GADGET_ID_NONE, + &level.bd_line_shifting_borders, + "Compatibility settings:", NULL, + "Line-shifting borders", "Use line-shifting wrap-around" + }, + { + ED_CHECKBUTTON_ID_BD_SCAN_FIRST_AND_LAST_ROW, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(7), + GADGET_ID_BD_SCAN_FIRST_AND_LAST_ROW, GADGET_ID_NONE, + &level.bd_scan_first_and_last_row, + NULL, NULL, + "Scan first and last row", "Also process top/bottom border rows" + }, + { + ED_CHECKBUTTON_ID_BD_SHORT_EXPLOSIONS, + ED_ENGINE_SETTINGS_XPOS(0), ED_ENGINE_SETTINGS_YPOS(8), + GADGET_ID_BD_SHORT_EXPLOSIONS, GADGET_ID_NONE, + &level.bd_short_explosions, + NULL, NULL, + "Short explosions", "Use four game cycles for explosions" }, // ---------- element settings: configure (various elements) ---------------- { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), - GADGET_ID_STICK_ELEMENT, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_STICK_ELEMENT, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + GADGET_ID_STICK_ELEMENT, GADGET_ID_NONE, &stick_element_properties_window, NULL, NULL, - "stick this screen to edit content","stick this screen to edit content" + "Stick this screen to edit content", "Stick this screen to edit content" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), - GADGET_ID_EM_SLIPPERY_GEMS, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_EM_SLIPPERY_GEMS, GADGET_ID_NONE, &level.em_slippery_gems, NULL, NULL, - "slip down from certain flat walls","use EM/DC style slipping behaviour" + "Slip down from certain flat walls", "Use EM/DC style slipping behaviour" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), - GADGET_ID_EM_EXPLODES_BY_FIRE, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_EM_EXPLODES_BY_FIRE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_EM_EXPLODES_BY_FIRE, GADGET_ID_NONE, &level.em_explodes_by_fire, NULL, NULL, - "explodes with chain reaction", "use R'n'D style explosion behaviour" + "Explodes with chain reaction", "Use R'n'D style explosion behaviour" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), - GADGET_ID_USE_SPRING_BUG, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_USE_SPRING_BUG, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_USE_SPRING_BUG, GADGET_ID_NONE, &level.use_spring_bug, NULL, NULL, - "use spring pushing bug", "use odd spring pushing behaviour" + "Use spring pushing bug", "Use odd spring pushing behaviour" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), - GADGET_ID_USE_TIME_ORB_BUG, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_USE_TIME_ORB_BUG, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_USE_TIME_ORB_BUG, GADGET_ID_NONE, &level.use_time_orb_bug, NULL, NULL, - "use time orb bug", "use odd time orb behaviour" + "Use time orb bug", "Use odd time orb behaviour" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), - GADGET_ID_USE_LIFE_BUGS, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_USE_LIFE_BUGS, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), + GADGET_ID_USE_LIFE_BUGS, GADGET_ID_NONE, &level.use_life_bugs, NULL, NULL, - "use buggy element behaviour", "use odd (historic) element behaviour" + "Use buggy element behaviour", "Use odd (historic) element behaviour" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), - GADGET_ID_RANDOM_BALL_CONTENT, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_RANDOM_BALL_CONTENT, GADGET_ID_NONE, &level.ball_random, NULL, NULL, - "create single random element", "only create one element from content" + "Create single random element", "Only create one element from content" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), - GADGET_ID_INITIAL_BALL_STATE, GADGET_ID_NONE, - &level.ball_state_initial, + ED_CHECKBUTTON_ID_INITIAL_BALL_ACTIVE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_INITIAL_BALL_ACTIVE, GADGET_ID_NONE, + &level.ball_active_initial, NULL, NULL, - "magic ball initially activated", "activate magic ball after level start" + "Magic ball initially activated", "Activate magic ball after level start" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), - GADGET_ID_GROW_INTO_DIGGABLE, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + GADGET_ID_GROW_INTO_DIGGABLE, GADGET_ID_NONE, &level.grow_into_diggable, NULL, NULL, - "can grow into anything diggable", "grow into more than just sand" + "Can grow into anything diggable", "Grow into more than just sand" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), - GADGET_ID_SB_FIELDS_NEEDED, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_SB_FIELDS_NEEDED, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + GADGET_ID_SB_FIELDS_NEEDED, GADGET_ID_NONE, &level.sb_fields_needed, NULL, NULL, - "all fields need to be filled", "require all SB fields to be solved" + "All fields need to be filled", "Require all SB fields to be solved" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), - GADGET_ID_SB_OBJECTS_NEEDED, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_SB_OBJECTS_NEEDED, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + GADGET_ID_SB_OBJECTS_NEEDED, GADGET_ID_NONE, &level.sb_objects_needed, NULL, NULL, - "all objects need to be placed", "require all SB objects to be solved" + "All objects need to be placed", "Require all SB objects to be solved" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), - GADGET_ID_AUTO_EXIT_SOKOBAN, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_AUTO_EXIT_SOKOBAN, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_AUTO_EXIT_SOKOBAN, GADGET_ID_NONE, &level.auto_exit_sokoban, NULL, NULL, - "exit level if all tasks solved", "automatically finish Sokoban levels" + "Exit level if all tasks solved", "Automatically finish Sokoban levels" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(14), - GADGET_ID_SOLVED_BY_ONE_PLAYER, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_SOLVED_BY_ONE_PLAYER, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(14), + GADGET_ID_SOLVED_BY_ONE_PLAYER, GADGET_ID_NONE, &level.solved_by_one_player, NULL, NULL, - "only one player must enter exit", "level solved by first player in exit" + "Only one player must enter exit", "Level solved by first player in exit" + }, + { + ED_CHECKBUTTON_ID_FINISH_DIG_COLLECT, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + GADGET_ID_FINISH_DIG_COLLECT, GADGET_ID_NONE, + &level.finish_dig_collect, + NULL, NULL, + "CE action on finished dig/collect", "Only finished dig/collect triggers CE" + }, + { + ED_CHECKBUTTON_ID_KEEP_WALKABLE_CE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), + GADGET_ID_KEEP_WALKABLE_CE, GADGET_ID_NONE, + &level.keep_walkable_ce, + NULL, NULL, + "Keep walkable CE changed to player", "Keep CE changing to player if walkable" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), - GADGET_ID_CONTINUOUS_SNAPPING, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), + GADGET_ID_CONTINUOUS_SNAPPING, GADGET_ID_NONE, &level.continuous_snapping, NULL, NULL, - "continuous snapping", "use snapping without releasing key" + "Continuous snapping", "Use snapping without releasing key" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8), - GADGET_ID_BLOCK_SNAP_FIELD, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8), + GADGET_ID_BLOCK_SNAP_FIELD, GADGET_ID_NONE, &level.block_snap_field, NULL, NULL, - "block snapped field when snapping", "use snapping delay to show animation" + "Block snapped field when snapping", "Use snapping delay to show animation" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), - GADGET_ID_BLOCK_LAST_FIELD, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_BLOCK_LAST_FIELD, GADGET_ID_NONE, &level.block_last_field, NULL, NULL, - "block last field when moving", "player blocks last field when moving" + "Block last field when moving", "Player blocks last field when moving" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), - GADGET_ID_SP_BLOCK_LAST_FIELD, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_SP_BLOCK_LAST_FIELD, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_SP_BLOCK_LAST_FIELD, GADGET_ID_NONE, &level.sp_block_last_field, NULL, NULL, - "block last field when moving", "player blocks last field when moving" + "Block last field when moving", "Player blocks last field when moving" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), - GADGET_ID_INSTANT_RELOCATION, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_INSTANT_RELOCATION, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + GADGET_ID_INSTANT_RELOCATION, GADGET_ID_NONE, &level.instant_relocation, NULL, NULL, - "no scrolling when relocating", "player gets relocated without delay" + "No scrolling when relocating", "Player gets relocated without delay" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), - GADGET_ID_SHIFTED_RELOCATION, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_SHIFTED_RELOCATION, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), + GADGET_ID_SHIFTED_RELOCATION, GADGET_ID_NONE, &level.shifted_relocation, NULL, NULL, - "no centering when relocating", "level not centered after relocation" + "No centering when relocating", "Level not centered after relocation" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), - GADGET_ID_LAZY_RELOCATION, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_LAZY_RELOCATION, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), + GADGET_ID_LAZY_RELOCATION, GADGET_ID_NONE, &level.lazy_relocation, NULL, NULL, - "only redraw off-screen relocation","no redraw if relocation target visible" + "Only redraw off-screen relocation", "No redraw if relocation target visible" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), - GADGET_ID_USE_START_ELEMENT, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_USE_START_ELEMENT, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), + GADGET_ID_USE_START_ELEMENT, GADGET_ID_NONE, &level.use_start_element[0], NULL, NULL, - "use level start element:", "start level at this element's position" + "Use level start element:", "Start level at this element's position" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(11), - GADGET_ID_USE_ARTWORK_ELEMENT, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_USE_ARTWORK_ELEMENT, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(11), + GADGET_ID_USE_ARTWORK_ELEMENT, GADGET_ID_NONE, &level.use_artwork_element[0], NULL, NULL, - "use artwork from element:", "use player artwork from other element" + "Use artwork from element:", "Use player artwork from other element" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(12), - GADGET_ID_USE_EXPLOSION_ELEMENT, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_USE_EXPLOSION_ELEMENT, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(12), + GADGET_ID_USE_EXPLOSION_ELEMENT, GADGET_ID_NONE, &level.use_explosion_element[0], NULL, NULL, - "use explosion from element:", "use explosion properties from element" + "Use explosion from element:", "Use explosion properties from element" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(13), - GADGET_ID_INITIAL_GRAVITY, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_INITIAL_GRAVITY, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(13), + GADGET_ID_INITIAL_GRAVITY, GADGET_ID_NONE, &level.initial_player_gravity[0], NULL, NULL, - "use initial gravity", "set initial player gravity" + "Use initial gravity", "Set initial player gravity" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), - GADGET_ID_USE_INITIAL_INVENTORY, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_USE_INITIAL_INVENTORY, GADGET_ID_NONE, &level.use_initial_inventory[0], NULL, NULL, - "use initial inventory:", "use collected elements on level start" + "Use initial inventory:", "Use collected elements on level start" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6), - GADGET_ID_CAN_PASS_TO_WALKABLE, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CAN_PASS_TO_WALKABLE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6), + GADGET_ID_CAN_PASS_TO_WALKABLE, GADGET_ID_NONE, &level.can_pass_to_walkable, NULL, NULL, - "can pass to walkable element", "player can pass to empty or walkable" + "Can pass to walkable element", "Player can pass to empty or walkable" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), - GADGET_ID_CAN_FALL_INTO_ACID, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CAN_FALL_INTO_ACID, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_CAN_FALL_INTO_ACID, GADGET_ID_NONE, &custom_element_properties[EP_CAN_MOVE_INTO_ACID], NULL, NULL, - "can fall into acid (with gravity)","player can fall into acid pool" + "Can fall into acid (with gravity)", "Player can fall into acid pool" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), - GADGET_ID_CAN_MOVE_INTO_ACID, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + GADGET_ID_CAN_MOVE_INTO_ACID, GADGET_ID_NONE, &custom_element_properties[EP_CAN_MOVE_INTO_ACID], NULL, NULL, - "can move into acid", "element can move into acid pool" + "Can move into acid", "Element can move into acid pool" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), - GADGET_ID_DONT_COLLIDE_WITH, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_DONT_COLLIDE_WITH, GADGET_ID_NONE, &custom_element_properties[EP_DONT_COLLIDE_WITH], NULL, NULL, - "deadly when colliding with", "element is deadly when hitting player" + "Deadly when colliding with", "Element is deadly when hitting player" + }, + { + ED_CHECKBUTTON_ID_BD_DIAGONAL_MOVEMENTS, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + GADGET_ID_BD_DIAGONAL_MOVEMENTS, GADGET_ID_NONE, + &level.bd_diagonal_movements, + NULL, NULL, + "Can move diagonally", "Player can move diagonally" + }, + { + ED_CHECKBUTTON_ID_BD_TOPMOST_PLAYER_ACTIVE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_BD_TOPMOST_PLAYER_ACTIVE, GADGET_ID_NONE, + &level.bd_topmost_player_active, + NULL, NULL, + "Topmost player is active", "Use first player found on playfield" + }, + { + ED_CHECKBUTTON_ID_BD_PUSH_MEGA_ROCK_WITH_SWEET, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), + GADGET_ID_BD_PUSH_MEGA_ROCK_WITH_SWEET, GADGET_ID_NONE, + &level.bd_push_mega_rock_with_sweet, + NULL, NULL, + "Mega rocks pushable with sweet", "Push mega rocks after eating sweet" + }, + { + ED_CHECKBUTTON_ID_BD_MAGIC_WALL_ZERO_INFINITE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_BD_MAGIC_WALL_ZERO_INFINITE, GADGET_ID_NONE, + &level.bd_magic_wall_zero_infinite, + NULL, NULL, + "Run forever if duration is zero", "Run infinitely if timer is zero" + }, + { + ED_CHECKBUTTON_ID_BD_MAGIC_WALL_WAIT_HATCHING, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + GADGET_ID_BD_MAGIC_WALL_WAIT_HATCHING, GADGET_ID_NONE, + &level.bd_magic_wall_wait_hatching, + NULL, NULL, + "Wait for player's birth", "Timer start waits for player's birth" + }, + { + ED_CHECKBUTTON_ID_BD_MAGIC_WALL_STOPS_AMOEBA, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), + GADGET_ID_BD_MAGIC_WALL_STOPS_AMOEBA, GADGET_ID_NONE, + &level.bd_magic_wall_stops_amoeba, + NULL, NULL, + "Stop amoeba and turn to diamonds", "Activation changes amoeba to diamonds" + }, + { + ED_CHECKBUTTON_ID_BD_MAGIC_WALL_BREAK_SCAN, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), + GADGET_ID_BD_MAGIC_WALL_BREAK_SCAN, GADGET_ID_NONE, + &level.bd_magic_wall_break_scan, + NULL, NULL, + "Emulate amoeba bug in BD1", "Use buggy BD1 behavior" + }, + { + ED_CHECKBUTTON_ID_BD_AMOEBA_WAIT_FOR_HATCHING, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_BD_AMOEBA_WAIT_FOR_HATCHING, GADGET_ID_NONE, + &level.bd_amoeba_wait_for_hatching, + NULL, NULL, + "Wait for player's birth", "Timer start waits for player's birth" + }, + { + ED_CHECKBUTTON_ID_BD_AMOEBA_START_IMMEDIATELY, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_BD_AMOEBA_START_IMMEDIATELY, GADGET_ID_NONE, + &level.bd_amoeba_start_immediately, + NULL, NULL, + "Start growing immediately", "Start slow growth time immediately" + }, + { + ED_CHECKBUTTON_ID_BD_AMOEBA_2_EXPLODE_BY_AMOEBA, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), + GADGET_ID_BD_AMOEBA_2_EXPLODE_BY_AMOEBA, GADGET_ID_NONE, + &level.bd_amoeba_2_explode_by_amoeba, + NULL, NULL, + "Explodes if touched by amoeba", "Amoeba 2 explodes if touched by amoeba" + }, + { + ED_CHECKBUTTON_ID_BD_VOODOO_COLLECTS_DIAMONDS, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + GADGET_ID_BD_VOODOO_COLLECTS_DIAMONDS, GADGET_ID_NONE, + &level.bd_voodoo_collects_diamonds, + NULL, NULL, + "Can collect diamonds", "Can collect diamonds for the player" + }, + { + ED_CHECKBUTTON_ID_BD_VOODOO_HURT_KILLS_PLAYER, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_BD_VOODOO_HURT_KILLS_PLAYER, GADGET_ID_NONE, + &level.bd_voodoo_hurt_kills_player, + NULL, NULL, + "Player is killed if hurt", "If hurt in any way, player is killed" + }, + { + ED_CHECKBUTTON_ID_BD_VOODOO_DIES_BY_ROCK, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_BD_VOODOO_DIES_BY_ROCK, GADGET_ID_NONE, + &level.bd_voodoo_dies_by_rock, + NULL, NULL, + "Killed by falling rock", "Can be killed by a falling rock" + }, + { + ED_CHECKBUTTON_ID_BD_VOODOO_VANISH_BY_EXPLOSION, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + GADGET_ID_BD_VOODOO_VANISH_BY_EXPLOSION, GADGET_ID_NONE, + &level.bd_voodoo_vanish_by_explosion, + NULL, NULL, + "Disappears in explosions", "Can be destroyed by explosions" + }, + { + ED_CHECKBUTTON_ID_BD_SLIME_IS_PREDICTABLE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_BD_SLIME_IS_PREDICTABLE, GADGET_ID_NONE, + &level.bd_slime_is_predictable, + NULL, NULL, + "Slime is predictable", "Use predictable random numbers" + }, + { + ED_CHECKBUTTON_ID_BD_CHANGE_EXPANDING_WALL, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + GADGET_ID_BD_CHANGE_EXPANDING_WALL, GADGET_ID_NONE, + &level.bd_change_expanding_wall, + NULL, NULL, + "Change direction", "Switch horizontal/vertical direction" + }, + { + ED_CHECKBUTTON_ID_BD_REPLICATORS_ACTIVE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + GADGET_ID_BD_REPLICATORS_ACTIVE, GADGET_ID_NONE, + &level.bd_replicators_active, + NULL, NULL, + "Active at start", "Replicators start in active state" + }, + { + ED_CHECKBUTTON_ID_BD_CONVEYOR_BELTS_ACTIVE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + GADGET_ID_BD_CONVEYOR_BELTS_ACTIVE, GADGET_ID_NONE, + &level.bd_conveyor_belts_active, + NULL, NULL, + "Active at start", "Conveyor belts start in active state" + }, + { + ED_CHECKBUTTON_ID_BD_CONVEYOR_BELTS_CHANGED, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_BD_CONVEYOR_BELTS_CHANGED, GADGET_ID_NONE, + &level.bd_conveyor_belts_changed, + NULL, NULL, + "Change direction", "Switch conveyor belt direction" + }, + { + ED_CHECKBUTTON_ID_BD_WATER_CANNOT_FLOW_DOWN, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + GADGET_ID_BD_WATER_CANNOT_FLOW_DOWN, GADGET_ID_NONE, + &level.bd_water_cannot_flow_down, + NULL, NULL, + "Does not flow downwards", "Water can only flow up, left and right" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), - GADGET_ID_ENVELOPE_AUTOWRAP, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_BD_HAMMER_WALLS_REAPPEAR, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_BD_HAMMER_WALLS_REAPPEAR, GADGET_ID_NONE, + &level.bd_hammer_walls_reappear, + NULL, NULL, + "Hammered walls reappear", "Hammered walls reappear after delay" + }, + { + ED_CHECKBUTTON_ID_BD_INFINITE_ROCKETS, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + GADGET_ID_BD_INFINITE_ROCKETS, GADGET_ID_NONE, + &level.bd_infinite_rockets, + NULL, NULL, + "Infinite rockets", "Rocket launcher has infinite rockets" + }, + { + ED_CHECKBUTTON_ID_BD_CREATURES_START_BACKWARDS, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(0), + GADGET_ID_BD_CREATURES_START_BACKWARDS, GADGET_ID_NONE, + &level.bd_creatures_start_backwards, + NULL, NULL, + "Creatures start moving backwards", "Creatures start in opposite direction" + }, + { + ED_CHECKBUTTON_ID_BD_CREATURES_TURN_ON_HATCHING, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_BD_CREATURES_TURN_ON_HATCHING, GADGET_ID_NONE, + &level.bd_creatures_turn_on_hatching, + NULL, NULL, + "Creatures auto turn on hatching", "Creatures change direction on hatching" + }, + { + ED_CHECKBUTTON_ID_BD_GRAVITY_SWITCH_ACTIVE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_BD_GRAVITY_SWITCH_ACTIVE, GADGET_ID_NONE, + &level.bd_gravity_switch_active, + NULL, NULL, + "Gravity switch active at start", "Gravity switch starts in active state" + }, + { + ED_CHECKBUTTON_ID_BD_GRAVITY_AFFECTS_ALL, + ED_LEVEL_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + GADGET_ID_BD_GRAVITY_AFFECTS_ALL, GADGET_ID_NONE, + &level.bd_gravity_affects_all, + NULL, NULL, + "Gravity change affects everything", "Gravity affects all falling objects" + }, + { + ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_ENVELOPE_AUTOWRAP, GADGET_ID_NONE, &level.envelope[0].autowrap, NULL, NULL, - "auto-wrap", "automatically wrap envelope text" + "Auto-wrap", "Automatically wrap envelope text" }, { - -1, ED_ELEMENT_SETTINGS_YPOS(1), - GADGET_ID_ENVELOPE_CENTERED, GADGET_ID_ENVELOPE_AUTOWRAP, + ED_CHECKBUTTON_ID_ENVELOPE_CENTERED, + -1, ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_ENVELOPE_CENTERED, GADGET_ID_ENVELOPE_AUTOWRAP, &level.envelope[0].centered, NULL, " ", - "centered", "automatically center envelope text" + "Centered", "Automatically center envelope text" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), - GADGET_ID_MM_LASER_RED, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_MM_LASER_RED, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_MM_LASER_RED, GADGET_ID_NONE, &level.mm_laser_red, - "choose color components for laser:", NULL, - "red", "use red color components in laser" + "Choose color components for laser:", NULL, + "Red", "Use red color components in laser" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), - GADGET_ID_MM_LASER_GREEN, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_MM_LASER_GREEN, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_MM_LASER_GREEN, GADGET_ID_NONE, &level.mm_laser_green, NULL, NULL, - "green", "use green color components in laser" + "Green", "Use green color components in laser" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), - GADGET_ID_MM_LASER_BLUE, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_MM_LASER_BLUE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + GADGET_ID_MM_LASER_BLUE, GADGET_ID_NONE, &level.mm_laser_blue, NULL, NULL, - "blue", "use blue color components in laser" + "Blue", "Use blue color components in laser" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), - GADGET_ID_DF_LASER_RED, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_DF_LASER_RED, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_DF_LASER_RED, GADGET_ID_NONE, &level.df_laser_red, - "choose color components for laser:", NULL, - "red", "use red color components in laser" + "Choose color components for laser:", NULL, + "Red", "Use red color components in laser" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), - GADGET_ID_DF_LASER_GREEN, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_DF_LASER_GREEN, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_DF_LASER_GREEN, GADGET_ID_NONE, &level.df_laser_green, NULL, NULL, - "green", "use green color components in laser" + "Green", "Use green color components in laser" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), - GADGET_ID_DF_LASER_BLUE, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_DF_LASER_BLUE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + GADGET_ID_DF_LASER_BLUE, GADGET_ID_NONE, &level.df_laser_blue, NULL, NULL, - "blue", "use blue color components in laser" + "Blue", "Use blue color components in laser" + }, + { + ED_CHECKBUTTON_ID_ROTATE_MM_BALL_CONTENT, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(5), + GADGET_ID_ROTATE_MM_BALL_CONTENT, GADGET_ID_NONE, + &level.rotate_mm_ball_content, + NULL, NULL, + "Randomly rotate created content", "Randomly rotate newly created content" + }, + { + ED_CHECKBUTTON_ID_EXPLODE_MM_BALL, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(6), + GADGET_ID_EXPLODE_MM_BALL, GADGET_ID_NONE, + &level.explode_mm_ball, + NULL, NULL, + "Explode ball instead of melting", "Use explosion to release ball content" }, // ---------- element settings: configure 1 (custom elements) --------------- { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), - GADGET_ID_CUSTOM_USE_GRAPHIC, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_CUSTOM_USE_GRAPHIC, GADGET_ID_NONE, &custom_element.use_gfx_element, NULL, NULL, - "use graphic of element:", "use existing element graphic" + "Use graphic of element:", "Use existing element graphic" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(14), - GADGET_ID_CUSTOM_USE_TEMPLATE_1, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(14), + GADGET_ID_CUSTOM_USE_TEMPLATE_1, GADGET_ID_NONE, &level.use_custom_template, NULL, NULL, - "use template", "use template for custom properties" + "Use template", "Use template for custom properties" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), - GADGET_ID_CUSTOM_ACCESSIBLE, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CUSTOM_ACCESSIBLE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_CUSTOM_ACCESSIBLE, GADGET_ID_NONE, &custom_element_properties[EP_ACCESSIBLE], NULL, NULL, - NULL, "player can walk to or pass this field" + NULL, "Player can walk to or pass this field" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), - GADGET_ID_CUSTOM_GRAV_REACHABLE, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CUSTOM_GRAV_REACHABLE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), + GADGET_ID_CUSTOM_GRAV_REACHABLE, GADGET_ID_NONE, &custom_element_properties[EP_GRAVITY_REACHABLE], NULL, NULL, - "reachable despite gravity", "player can walk/dig despite gravity" + "Reachable despite gravity", "Player can walk/dig despite gravity" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(11), - GADGET_ID_CUSTOM_USE_LAST_VALUE, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CUSTOM_USE_LAST_VALUE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(11), + GADGET_ID_CUSTOM_USE_LAST_VALUE, GADGET_ID_NONE, &custom_element.use_last_ce_value, NULL, NULL, - "use last CE value after change", "use last CE value after change" + "Use last CE value after change", "Use last CE value after change" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), - GADGET_ID_CUSTOM_WALK_TO_OBJECT, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CUSTOM_WALK_TO_OBJECT, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(4), + GADGET_ID_CUSTOM_WALK_TO_OBJECT, GADGET_ID_NONE, &custom_element_properties[EP_WALK_TO_OBJECT], NULL, NULL, - NULL, "player can dig/collect/push element" + NULL, "Player can dig/collect/push element" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8), - GADGET_ID_CUSTOM_INDESTRUCTIBLE, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CUSTOM_INDESTRUCTIBLE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8), + GADGET_ID_CUSTOM_INDESTRUCTIBLE, GADGET_ID_NONE, &custom_element_properties[EP_INDESTRUCTIBLE], NULL, NULL, - "indestructible", "element is indestructible" + "Indestructible", "Element is indestructible" }, // ---------- element settings: configure 2 (custom elements) --------------- { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), - GADGET_ID_CUSTOM_CAN_MOVE, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CUSTOM_CAN_MOVE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_CUSTOM_CAN_MOVE, GADGET_ID_NONE, &custom_element_properties[EP_CAN_MOVE], NULL, NULL, - NULL, "element can move with some pattern" + NULL, "Element can move with some pattern" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(7), - GADGET_ID_CUSTOM_CAN_FALL, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CUSTOM_CAN_FALL, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8), + GADGET_ID_CUSTOM_CAN_FALL, GADGET_ID_NONE, &custom_element_properties[EP_CAN_FALL], NULL, NULL, - "can fall", "element can fall down" + "Can fall", "Element can fall down" }, { - -1, ED_ELEMENT_SETTINGS_YPOS(7), - GADGET_ID_CUSTOM_CAN_SMASH, GADGET_ID_CUSTOM_CAN_FALL, + ED_CHECKBUTTON_ID_CUSTOM_CAN_SMASH, + -1, ED_ELEMENT_SETTINGS_YPOS(8), + GADGET_ID_CUSTOM_CAN_SMASH, GADGET_ID_CUSTOM_CAN_FALL, &custom_element_properties[EP_CAN_SMASH], NULL, " ", - NULL, "element can smash other elements" + NULL, "Element can smash other elements" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(8), - GADGET_ID_CUSTOM_SLIPPERY, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CUSTOM_SLIPPERY, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), + GADGET_ID_CUSTOM_SLIPPERY, GADGET_ID_NONE, &custom_element_properties[EP_SLIPPERY], NULL, NULL, - NULL, "other elements can fall down from it" + NULL, "Other elements can fall down from it" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), - GADGET_ID_CUSTOM_DEADLY, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CUSTOM_DEADLY, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), + GADGET_ID_CUSTOM_DEADLY, GADGET_ID_NONE, &custom_element_properties[EP_DEADLY], NULL, NULL, - NULL, "element can kill the player" + NULL, "Element can kill the player" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(10), - GADGET_ID_CUSTOM_CAN_EXPLODE, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CUSTOM_CAN_EXPLODE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(11), + GADGET_ID_CUSTOM_CAN_EXPLODE, GADGET_ID_NONE, &custom_element_properties[EP_CAN_EXPLODE], NULL, NULL, - NULL, "element can explode" + NULL, "Element can explode" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(11), - GADGET_ID_CUSTOM_EXPLODE_FIRE, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_FIRE, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(12), + GADGET_ID_CUSTOM_EXPLODE_FIRE, GADGET_ID_NONE, &custom_element_properties[EP_EXPLODES_BY_FIRE], NULL, NULL, - "by fire", "element can explode by fire/explosion" + "By fire", "Element can explode by fire/explosion" }, { - -1, ED_ELEMENT_SETTINGS_YPOS(11), - GADGET_ID_CUSTOM_EXPLODE_SMASH, GADGET_ID_CUSTOM_EXPLODE_FIRE, + ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_SMASH, + -1, ED_ELEMENT_SETTINGS_YPOS(12), + GADGET_ID_CUSTOM_EXPLODE_SMASH, GADGET_ID_CUSTOM_EXPLODE_FIRE, &custom_element_properties[EP_EXPLODES_SMASHED], NULL, " ", - "smashed", "element can explode when smashed" + "Smashed", "Element can explode when smashed" }, { - -1, ED_ELEMENT_SETTINGS_YPOS(11), - GADGET_ID_CUSTOM_EXPLODE_IMPACT, GADGET_ID_CUSTOM_EXPLODE_SMASH, + ED_CHECKBUTTON_ID_CUSTOM_EXPLODE_IMPACT, + -1, ED_ELEMENT_SETTINGS_YPOS(12), + GADGET_ID_CUSTOM_EXPLODE_IMPACT, GADGET_ID_CUSTOM_EXPLODE_SMASH, &custom_element_properties[EP_EXPLODES_IMPACT], NULL, " ", - "impact", "element can explode on impact" + "Impact", "Element can explode on impact" }, // ---------- element settings: advanced (custom elements) ------------------ { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), - GADGET_ID_CUSTOM_CAN_CHANGE, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CUSTOM_CAN_CHANGE, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(1), + GADGET_ID_CUSTOM_CAN_CHANGE, GADGET_ID_NONE, &custom_element_change.can_change, NULL, NULL, - "element changes to:", "change element on specified condition" + "Element changes to:", "Change element on specified condition" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(2), - GADGET_ID_CHANGE_DELAY, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CHANGE_DELAY, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(2), + GADGET_ID_CHANGE_DELAY, GADGET_ID_NONE, &custom_element_change_events[CE_DELAY], NULL, NULL, - NULL, "element changes after delay" + NULL, "Element changes after delay" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(4), - GADGET_ID_CHANGE_BY_DIRECT_ACT, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CHANGE_BY_DIRECT_ACT, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(4), + GADGET_ID_CHANGE_BY_DIRECT_ACT, GADGET_ID_NONE, &custom_element_change_events[CE_BY_DIRECT_ACTION], NULL, NULL, - NULL, "element changes by direct action" + NULL, "Element changes by direct action" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(5), - GADGET_ID_CHANGE_BY_OTHER_ACT, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CHANGE_BY_OTHER_ACT, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(5), + GADGET_ID_CHANGE_BY_OTHER_ACT, GADGET_ID_NONE, &custom_element_change_events[CE_BY_OTHER_ACTION], NULL, NULL, - NULL, "element changes by other element" + NULL, "Element changes by other element" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(8), - GADGET_ID_CHANGE_USE_EXPLOSION, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CHANGE_USE_EXPLOSION, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(8), + GADGET_ID_CHANGE_USE_EXPLOSION, GADGET_ID_NONE, &custom_element_change.explode, NULL, NULL, - "explode instead of change", "element explodes instead of change" + "Explode instead of change", "Element explodes instead of change" }, { - ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(9), - GADGET_ID_CHANGE_USE_CONTENT, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CHANGE_USE_CONTENT, + ED_ELEMENT_SETTINGS_XPOS(1), ED_ELEMENT_SETTINGS_YPOS(9), + GADGET_ID_CHANGE_USE_CONTENT, GADGET_ID_NONE, &custom_element_change.use_target_content, NULL, NULL, - "use extended change target:", "element changes to more elements" + "Use extended change target:", "Element changes to more elements" }, { - ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(11), - GADGET_ID_CHANGE_ONLY_COMPLETE, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CHANGE_ONLY_COMPLETE, + ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(11), + GADGET_ID_CHANGE_ONLY_COMPLETE, GADGET_ID_NONE, &custom_element_change.only_if_complete, NULL, NULL, - "replace all or nothing", "only replace when all can be changed" + "Replace all or nothing", "Only replace when all can be changed" }, { - ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(12), - GADGET_ID_CHANGE_USE_RANDOM, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CHANGE_USE_RANDOM, + ED_ELEMENT_SETTINGS_XPOS(2), ED_ELEMENT_SETTINGS_YPOS(12), + GADGET_ID_CHANGE_USE_RANDOM, GADGET_ID_NONE, &custom_element_change.use_random_replace, NULL, NULL, - NULL, "use percentage for random replace" + NULL, "Use percentage for random replace" }, { - ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(13), - GADGET_ID_CHANGE_HAS_ACTION, GADGET_ID_NONE, + ED_CHECKBUTTON_ID_CHANGE_HAS_ACTION, + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(13), + GADGET_ID_CHANGE_HAS_ACTION, GADGET_ID_NONE, &custom_element_change.has_action, NULL, NULL, - NULL, "execute action on specified condition" + NULL, "Execute action on specified condition" }, }; static struct { + int gadget_type_id; int x, y; int xoffset, yoffset; int gadget_id; int gadget_id_align; int *value; int area_xsize, area_ysize; - char *text_left, *text_right, *text_below, *infotext; + char *text_left, *text_right, *text_above, *text_below, *infotext; } drawingarea_info[ED_NUM_DRAWING_AREAS] = { // ---------- level playfield content --------------------------------------- { - 0, 0, - 0, 0, - GADGET_ID_DRAWING_LEVEL, GADGET_ID_NONE, + ED_DRAWING_ID_DRAWING_LEVEL, + 0, 0, + 0, 0, + GADGET_ID_DRAWING_LEVEL, GADGET_ID_NONE, NULL, -1, -1, // these values are not constant, but can change at runtime - NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL }, // ---------- yam yam content ----------------------------------------------- { - ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, - ED_AREA_YAMYAM_CONTENT_XOFF(0), ED_AREA_YAMYAM_CONTENT_YOFF(0), - GADGET_ID_YAMYAM_CONTENT_0, GADGET_ID_NONE, - &level.yamyam_content[0].e[0][0], 3, 3, - NULL, NULL, "1", NULL + ED_DRAWING_ID_YAMYAM_CONTENT_0, + ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, + ED_AREA_YAMYAM_CONTENT_XOFF(0), ED_AREA_YAMYAM_CONTENT_YOFF(0), + GADGET_ID_YAMYAM_CONTENT_0, GADGET_ID_NONE, + &level.yamyam_content[0].e[0][0], 3, 3, + NULL, NULL, NULL, "1", NULL }, { - ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, - ED_AREA_YAMYAM_CONTENT_XOFF(1), ED_AREA_YAMYAM_CONTENT_YOFF(1), - GADGET_ID_YAMYAM_CONTENT_1, GADGET_ID_NONE, - &level.yamyam_content[1].e[0][0], 3, 3, - NULL, NULL, "2", NULL + ED_DRAWING_ID_YAMYAM_CONTENT_1, + ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, + ED_AREA_YAMYAM_CONTENT_XOFF(1), ED_AREA_YAMYAM_CONTENT_YOFF(1), + GADGET_ID_YAMYAM_CONTENT_1, GADGET_ID_NONE, + &level.yamyam_content[1].e[0][0], 3, 3, + NULL, NULL, NULL, "2", NULL }, { - ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, - ED_AREA_YAMYAM_CONTENT_XOFF(2), ED_AREA_YAMYAM_CONTENT_YOFF(2), - GADGET_ID_YAMYAM_CONTENT_2, GADGET_ID_NONE, - &level.yamyam_content[2].e[0][0], 3, 3, - NULL, NULL, "3", NULL + ED_DRAWING_ID_YAMYAM_CONTENT_2, + ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, + ED_AREA_YAMYAM_CONTENT_XOFF(2), ED_AREA_YAMYAM_CONTENT_YOFF(2), + GADGET_ID_YAMYAM_CONTENT_2, GADGET_ID_NONE, + &level.yamyam_content[2].e[0][0], 3, 3, + NULL, NULL, NULL, "3", NULL }, { - ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, - ED_AREA_YAMYAM_CONTENT_XOFF(3), ED_AREA_YAMYAM_CONTENT_YOFF(3), - GADGET_ID_YAMYAM_CONTENT_3, GADGET_ID_NONE, - &level.yamyam_content[3].e[0][0], 3, 3, - NULL, NULL, "4", NULL + ED_DRAWING_ID_YAMYAM_CONTENT_3, + ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, + ED_AREA_YAMYAM_CONTENT_XOFF(3), ED_AREA_YAMYAM_CONTENT_YOFF(3), + GADGET_ID_YAMYAM_CONTENT_3, GADGET_ID_NONE, + &level.yamyam_content[3].e[0][0], 3, 3, + NULL, NULL, NULL, "4", NULL }, { - ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, - ED_AREA_YAMYAM_CONTENT_XOFF(4), ED_AREA_YAMYAM_CONTENT_YOFF(4), - GADGET_ID_YAMYAM_CONTENT_4, GADGET_ID_NONE, - &level.yamyam_content[4].e[0][0], 3, 3, - NULL, NULL, "5", NULL + ED_DRAWING_ID_YAMYAM_CONTENT_4, + ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, + ED_AREA_YAMYAM_CONTENT_XOFF(4), ED_AREA_YAMYAM_CONTENT_YOFF(4), + GADGET_ID_YAMYAM_CONTENT_4, GADGET_ID_NONE, + &level.yamyam_content[4].e[0][0], 3, 3, + NULL, NULL, NULL, "5", NULL }, { - ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, - ED_AREA_YAMYAM_CONTENT_XOFF(5), ED_AREA_YAMYAM_CONTENT_YOFF(5), - GADGET_ID_YAMYAM_CONTENT_5, GADGET_ID_NONE, - &level.yamyam_content[5].e[0][0], 3, 3, - NULL, NULL, "6", NULL + ED_DRAWING_ID_YAMYAM_CONTENT_5, + ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, + ED_AREA_YAMYAM_CONTENT_XOFF(5), ED_AREA_YAMYAM_CONTENT_YOFF(5), + GADGET_ID_YAMYAM_CONTENT_5, GADGET_ID_NONE, + &level.yamyam_content[5].e[0][0], 3, 3, + NULL, NULL, NULL, "6", NULL }, { - ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, - ED_AREA_YAMYAM_CONTENT_XOFF(6), ED_AREA_YAMYAM_CONTENT_YOFF(6), - GADGET_ID_YAMYAM_CONTENT_6, GADGET_ID_NONE, - &level.yamyam_content[6].e[0][0], 3, 3, - NULL, NULL, "7", NULL + ED_DRAWING_ID_YAMYAM_CONTENT_6, + ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, + ED_AREA_YAMYAM_CONTENT_XOFF(6), ED_AREA_YAMYAM_CONTENT_YOFF(6), + GADGET_ID_YAMYAM_CONTENT_6, GADGET_ID_NONE, + &level.yamyam_content[6].e[0][0], 3, 3, + NULL, NULL, NULL, "7", NULL }, { - ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, - ED_AREA_YAMYAM_CONTENT_XOFF(7), ED_AREA_YAMYAM_CONTENT_YOFF(7), - GADGET_ID_YAMYAM_CONTENT_7, GADGET_ID_NONE, - &level.yamyam_content[7].e[0][0], 3, 3, - NULL, NULL, "8", NULL + ED_DRAWING_ID_YAMYAM_CONTENT_7, + ED_AREA_YAMYAM_CONTENT_XPOS, ED_AREA_YAMYAM_CONTENT_YPOS, + ED_AREA_YAMYAM_CONTENT_XOFF(7), ED_AREA_YAMYAM_CONTENT_YOFF(7), + GADGET_ID_YAMYAM_CONTENT_7, GADGET_ID_NONE, + &level.yamyam_content[7].e[0][0], 3, 3, + NULL, NULL, NULL, "8", NULL }, // ---------- magic ball content -------------------------------------------- { - ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, - ED_AREA_MAGIC_BALL_CONTENT_XOFF(0), ED_AREA_MAGIC_BALL_CONTENT_YOFF(0), - GADGET_ID_MAGIC_BALL_CONTENT_0, GADGET_ID_NONE, - &level.ball_content[0].e[0][0], 3, 3, - NULL, NULL, "1", NULL + ED_DRAWING_ID_MAGIC_BALL_CONTENT_0, + ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, + ED_AREA_MAGIC_BALL_CONTENT_XOFF(0), ED_AREA_MAGIC_BALL_CONTENT_YOFF(0), + GADGET_ID_MAGIC_BALL_CONTENT_0, GADGET_ID_NONE, + &level.ball_content[0].e[0][0], 3, 3, + NULL, NULL, NULL, "1", NULL }, { - ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, - ED_AREA_MAGIC_BALL_CONTENT_XOFF(1), ED_AREA_MAGIC_BALL_CONTENT_YOFF(1), - GADGET_ID_MAGIC_BALL_CONTENT_1, GADGET_ID_NONE, - &level.ball_content[1].e[0][0], 3, 3, - NULL, NULL, "2", NULL + ED_DRAWING_ID_MAGIC_BALL_CONTENT_1, + ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, + ED_AREA_MAGIC_BALL_CONTENT_XOFF(1), ED_AREA_MAGIC_BALL_CONTENT_YOFF(1), + GADGET_ID_MAGIC_BALL_CONTENT_1, GADGET_ID_NONE, + &level.ball_content[1].e[0][0], 3, 3, + NULL, NULL, NULL, "2", NULL }, { - ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, - ED_AREA_MAGIC_BALL_CONTENT_XOFF(2), ED_AREA_MAGIC_BALL_CONTENT_YOFF(2), - GADGET_ID_MAGIC_BALL_CONTENT_2, GADGET_ID_NONE, - &level.ball_content[2].e[0][0], 3, 3, - NULL, NULL, "3", NULL + ED_DRAWING_ID_MAGIC_BALL_CONTENT_2, + ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, + ED_AREA_MAGIC_BALL_CONTENT_XOFF(2), ED_AREA_MAGIC_BALL_CONTENT_YOFF(2), + GADGET_ID_MAGIC_BALL_CONTENT_2, GADGET_ID_NONE, + &level.ball_content[2].e[0][0], 3, 3, + NULL, NULL, NULL, "3", NULL }, { - ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, - ED_AREA_MAGIC_BALL_CONTENT_XOFF(3), ED_AREA_MAGIC_BALL_CONTENT_YOFF(3), - GADGET_ID_MAGIC_BALL_CONTENT_3, GADGET_ID_NONE, - &level.ball_content[3].e[0][0], 3, 3, - NULL, NULL, "4", NULL + ED_DRAWING_ID_MAGIC_BALL_CONTENT_3, + ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, + ED_AREA_MAGIC_BALL_CONTENT_XOFF(3), ED_AREA_MAGIC_BALL_CONTENT_YOFF(3), + GADGET_ID_MAGIC_BALL_CONTENT_3, GADGET_ID_NONE, + &level.ball_content[3].e[0][0], 3, 3, + NULL, NULL, NULL, "4", NULL }, { - ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, - ED_AREA_MAGIC_BALL_CONTENT_XOFF(4), ED_AREA_MAGIC_BALL_CONTENT_YOFF(4), - GADGET_ID_MAGIC_BALL_CONTENT_4, GADGET_ID_NONE, - &level.ball_content[4].e[0][0], 3, 3, - NULL, NULL, "5", NULL + ED_DRAWING_ID_MAGIC_BALL_CONTENT_4, + ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, + ED_AREA_MAGIC_BALL_CONTENT_XOFF(4), ED_AREA_MAGIC_BALL_CONTENT_YOFF(4), + GADGET_ID_MAGIC_BALL_CONTENT_4, GADGET_ID_NONE, + &level.ball_content[4].e[0][0], 3, 3, + NULL, NULL, NULL, "5", NULL }, { - ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, - ED_AREA_MAGIC_BALL_CONTENT_XOFF(5), ED_AREA_MAGIC_BALL_CONTENT_YOFF(5), - GADGET_ID_MAGIC_BALL_CONTENT_5, GADGET_ID_NONE, - &level.ball_content[5].e[0][0], 3, 3, - NULL, NULL, "6", NULL + ED_DRAWING_ID_MAGIC_BALL_CONTENT_5, + ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, + ED_AREA_MAGIC_BALL_CONTENT_XOFF(5), ED_AREA_MAGIC_BALL_CONTENT_YOFF(5), + GADGET_ID_MAGIC_BALL_CONTENT_5, GADGET_ID_NONE, + &level.ball_content[5].e[0][0], 3, 3, + NULL, NULL, NULL, "6", NULL }, { - ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, - ED_AREA_MAGIC_BALL_CONTENT_XOFF(6), ED_AREA_MAGIC_BALL_CONTENT_YOFF(6), - GADGET_ID_MAGIC_BALL_CONTENT_6, GADGET_ID_NONE, - &level.ball_content[6].e[0][0], 3, 3, - NULL, NULL, "7", NULL + ED_DRAWING_ID_MAGIC_BALL_CONTENT_6, + ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, + ED_AREA_MAGIC_BALL_CONTENT_XOFF(6), ED_AREA_MAGIC_BALL_CONTENT_YOFF(6), + GADGET_ID_MAGIC_BALL_CONTENT_6, GADGET_ID_NONE, + &level.ball_content[6].e[0][0], 3, 3, + NULL, NULL, NULL, "7", NULL }, { - ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, - ED_AREA_MAGIC_BALL_CONTENT_XOFF(7), ED_AREA_MAGIC_BALL_CONTENT_YOFF(7), - GADGET_ID_MAGIC_BALL_CONTENT_7, GADGET_ID_NONE, - &level.ball_content[7].e[0][0], 3, 3, - NULL, NULL, "8", NULL + ED_DRAWING_ID_MAGIC_BALL_CONTENT_7, + ED_AREA_MAGIC_BALL_CONTENT_XPOS, ED_AREA_MAGIC_BALL_CONTENT_YPOS, + ED_AREA_MAGIC_BALL_CONTENT_XOFF(7), ED_AREA_MAGIC_BALL_CONTENT_YOFF(7), + GADGET_ID_MAGIC_BALL_CONTENT_7, GADGET_ID_NONE, + &level.ball_content[7].e[0][0], 3, 3, + NULL, NULL, NULL, "8", NULL }, // ---------- android content ----------------------------------------------- { - ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(5), - ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, - GADGET_ID_ANDROID_CONTENT, GADGET_ID_NONE, - &level.android_clone_element[0], MAX_ANDROID_ELEMENTS, 1, - "elements:", NULL, NULL, "elements android can clone" + ED_DRAWING_ID_ANDROID_CONTENT, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(6), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_ANDROID_CONTENT, GADGET_ID_NONE, + &level.android_clone_element[0], MAX_ANDROID_ELEMENTS, 1, + NULL, NULL, "Elements:", NULL, "Elements android can clone" }, // ---------- amoeba content ------------------------------------------------ { - ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(3), - ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, - GADGET_ID_AMOEBA_CONTENT, GADGET_ID_NONE, - &level.amoeba_content, 1, 1, - "content:", NULL, NULL, "amoeba content" + ED_DRAWING_ID_AMOEBA_CONTENT, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(3), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_AMOEBA_CONTENT, GADGET_ID_NONE, + &level.amoeba_content, 1, 1, + "Content:", NULL, NULL, NULL, "Amoeba content" }, - // ---------- level start element ------------------------------------------- + // ---------- BD snap element ----------------------------------------------- { - -1, ED_AREA_1X1_SETTINGS_YPOS(10), - 0, ED_AREA_1X1_SETTINGS_YOFF, - GADGET_ID_START_ELEMENT, GADGET_ID_USE_START_ELEMENT, - &level.start_element[0], 1, 1, - NULL, NULL, NULL, "level start element" + ED_DRAWING_ID_BD_SNAP_ELEMENT, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(5), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_SNAP_ELEMENT, GADGET_ID_NONE, + &level.bd_snap_element, 1, 1, + "Snap element:", NULL, NULL, NULL, "Element created when snapping" }, - // ---------- player artwork element ---------------------------------------- + // ---------- BD magic wall elements ---------------------------------------- { - -1, ED_AREA_1X1_SETTINGS_YPOS(11), - 0, ED_AREA_1X1_SETTINGS_YOFF, - GADGET_ID_ARTWORK_ELEMENT, GADGET_ID_USE_ARTWORK_ELEMENT, - &level.artwork_element[0], 1, 1, - NULL, NULL, NULL, "element for player artwork" + ED_DRAWING_ID_BD_MAGIC_WALL_DIAMOND_TO, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(6), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_MAGIC_WALL_DIAMOND_TO, GADGET_ID_NONE, + &level.bd_magic_wall_diamond_to, 1, 1, + "Changes diamonds to:", NULL, NULL, NULL, "Element to turn diamonds to" }, - - // ---------- player explosion element -------------------------------------- - { - -1, ED_AREA_1X1_SETTINGS_YPOS(12), - 0, ED_AREA_1X1_SETTINGS_YOFF, - GADGET_ID_EXPLOSION_ELEMENT, GADGET_ID_USE_EXPLOSION_ELEMENT, - &level.explosion_element[0], 1, 1, - NULL, NULL, NULL, "element for player explosion" + ED_DRAWING_ID_BD_MAGIC_WALL_ROCK_TO, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(7), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_MAGIC_WALL_ROCK_TO, GADGET_ID_NONE, + &level.bd_magic_wall_rock_to, 1, 1, + "Changes rocks to:", NULL, NULL, NULL, "Element to turn rocks to" }, - - // ---------- player initial inventory -------------------------------------- - { - -1, ED_AREA_1X1_SETTINGS_YPOS(1), - 0, ED_AREA_1X1_SETTINGS_YOFF, - GADGET_ID_INVENTORY_CONTENT, GADGET_ID_USE_INITIAL_INVENTORY, - &level.initial_inventory_content[0][0], MAX_INITIAL_INVENTORY_SIZE, 1, - NULL, NULL, NULL, "content for initial inventory" + ED_DRAWING_ID_BD_MAGIC_WALL_MEGA_ROCK_TO, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(8), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_MAGIC_WALL_MEGA_ROCK_TO, GADGET_ID_NONE, + &level.bd_magic_wall_mega_rock_to, 1, 1, + "Changes mega rocks to:", NULL, NULL, NULL, "Element to turn mega rocks to" + }, + { + ED_DRAWING_ID_BD_MAGIC_WALL_NUT_TO, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(9), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_MAGIC_WALL_NUT_TO, GADGET_ID_NONE, + &level.bd_magic_wall_nut_to, 1, 1, + "Changes nuts to:", NULL, NULL, NULL, "Element to turn nuts to" + }, + { + ED_DRAWING_ID_BD_MAGIC_WALL_NITRO_PACK_TO, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(10), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_MAGIC_WALL_NITRO_PACK_TO, GADGET_ID_NONE, + &level.bd_magic_wall_nitro_pack_to, 1, 1, + "Changes nitro packs to:", NULL, NULL, NULL, "Element to turn nitro packs to" + }, + { + ED_DRAWING_ID_BD_MAGIC_WALL_FLYING_DIAMOND_TO, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(11), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_MAGIC_WALL_FLYING_DIAMOND_TO, GADGET_ID_NONE, + &level.bd_magic_wall_flying_diamond_to, 1, 1, + "Changes flying diamonds to:", NULL, NULL, NULL, "Element to turn flying diamonds to" + }, + { + ED_DRAWING_ID_BD_MAGIC_WALL_FLYING_ROCK_TO, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(12), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_MAGIC_WALL_FLYING_ROCK_TO, GADGET_ID_NONE, + &level.bd_magic_wall_flying_rock_to, 1, 1, + "Changes flying rocks to:", NULL, NULL, NULL, "Element to turn flying rocks to" + }, + + // ---------- BD amoeba content --------------------------------------------- + + { + ED_DRAWING_ID_BD_AMOEBA_CONTENT_TOO_BIG, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(7), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_AMOEBA_CONTENT_TOO_BIG, GADGET_ID_NONE, + &level.bd_amoeba_content_too_big, 1, 1, + "If too big, changes to:", NULL, NULL, NULL, "BD amoeba content if too big" + }, + { + ED_DRAWING_ID_BD_AMOEBA_CONTENT_ENCLOSED, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(8), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_AMOEBA_CONTENT_ENCLOSED, GADGET_ID_NONE, + &level.bd_amoeba_content_enclosed, 1, 1, + "If enclosed, changes to:", NULL, NULL, NULL, "BD amoeba content if enclosed" + }, + + // ---------- BD amoeba 2 content ------------------------------------------- + + { + ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_TOO_BIG, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(7), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_AMOEBA_2_CONTENT_TOO_BIG, GADGET_ID_NONE, + &level.bd_amoeba_2_content_too_big, 1, 1, + "If too big, changes to:", NULL, NULL, NULL, "BD amoeba 2 content if too big" + }, + { + ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_ENCLOSED, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(8), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_AMOEBA_2_CONTENT_ENCLOSED, GADGET_ID_NONE, + &level.bd_amoeba_2_content_enclosed, 1, 1, + "If enclosed, changes to:", NULL, NULL, NULL, "BD amoeba 2 content if enclosed" + }, + { + ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_EXPLODING, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(10), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_AMOEBA_2_CONTENT_EXPLODING, GADGET_ID_NONE, + &level.bd_amoeba_2_content_exploding, 1, 1, + "If exploding, changes to:", NULL, NULL, NULL, "BD amoeba 2 content if exploding" + }, + { + ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_LOOKS_LIKE, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(11), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_AMOEBA_2_CONTENT_LOOKS_LIKE, GADGET_ID_NONE, + &level.bd_amoeba_2_content_looks_like, 1, 1, + "Use graphic of element:", NULL, NULL, NULL, "BD amoeba 2 looks like this element" + }, + { + ED_DRAWING_ID_BD_SLIME_EATS_ELEMENT_1, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(5), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_SLIME_EATS_ELEMENT_1, GADGET_ID_NONE, + &level.bd_slime_eats_element_1, 1, 1, + "Can eat:", NULL, NULL, NULL, "Element that can be eaten" + }, + { + ED_DRAWING_ID_BD_SLIME_CONVERTS_TO_ELEMENT_1, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(5), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_SLIME_CONVERTS_TO_ELEMENT_1, GADGET_ID_BD_SLIME_EATS_ELEMENT_1, + &level.bd_slime_converts_to_element_1, 1, 1, + " and convert to:", NULL, NULL, NULL, "Eaten element is converted to" + }, + { + ED_DRAWING_ID_BD_SLIME_EATS_ELEMENT_2, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(6), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_SLIME_EATS_ELEMENT_2, GADGET_ID_NONE, + &level.bd_slime_eats_element_2, 1, 1, + "Can eat:", NULL, NULL, NULL, "Element that can be eaten" + }, + { + ED_DRAWING_ID_BD_SLIME_CONVERTS_TO_ELEMENT_2, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(6), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_SLIME_CONVERTS_TO_ELEMENT_2, GADGET_ID_BD_SLIME_EATS_ELEMENT_2, + &level.bd_slime_converts_to_element_2, 1, 1, + " and convert to:", NULL, NULL, NULL, "Eaten element is converted to" + }, + { + ED_DRAWING_ID_BD_SLIME_EATS_ELEMENT_3, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(7), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_SLIME_EATS_ELEMENT_3, GADGET_ID_NONE, + &level.bd_slime_eats_element_3, 1, 1, + "Can eat:", NULL, NULL, NULL, "Element that can be eaten" + }, + { + ED_DRAWING_ID_BD_SLIME_CONVERTS_TO_ELEMENT_3, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(7), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_SLIME_CONVERTS_TO_ELEMENT_3, GADGET_ID_BD_SLIME_EATS_ELEMENT_3, + &level.bd_slime_converts_to_element_3, 1, 1, + " and convert to:", NULL, NULL, NULL, "Eaten element is converted to" + }, + { + ED_DRAWING_ID_BD_ACID_EATS_ELEMENT, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(1), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_ACID_EATS_ELEMENT, GADGET_ID_NONE, + &level.bd_acid_eats_element, 1, 1, + "Can eat:", NULL, NULL, NULL, "Eats this element when spreading" + }, + { + ED_DRAWING_ID_BD_ACID_TURNS_TO_ELEMENT, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(3), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_ACID_TURNS_TO_ELEMENT, GADGET_ID_NONE, + &level.bd_acid_turns_to_element, 1, 1, + "Can leave behind:", NULL, NULL, NULL, "Turns to this element after spreading" + }, + { + ED_DRAWING_ID_BD_BITER_EATS_ELEMENT, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(2), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_BITER_EATS_ELEMENT, GADGET_ID_NONE, + &level.bd_biter_eats_element, 1, 1, + "Can eat:", NULL, NULL, NULL, "Eats this element when moving" + }, + { + ED_DRAWING_ID_BD_BLADDER_CONVERTS_BY_ELEMENT, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(1), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_BLADDER_CONVERTS_BY_ELEMENT, GADGET_ID_NONE, + &level.bd_bladder_converts_by_element, 1, 1, + "Turns to clock by touching:", NULL, NULL, NULL, "Turns to clock by touching element" + }, + { + ED_DRAWING_ID_BD_NUT_CONTENT, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(1), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_NUT_CONTENT, GADGET_ID_NONE, + &level.bd_nut_content, 1, 1, + "When breaking, changes to:", NULL, NULL, NULL, "Element created when breaking nut" + }, + { + ED_DRAWING_ID_BD_EXPANDING_WALL_LOOKS_LIKE, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(1), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_EXPANDING_WALL_LOOKS_LIKE, GADGET_ID_NONE, + &level.bd_expanding_wall_looks_like, 1, 1, + "Use graphic of element:", NULL, NULL, NULL, "Expanding wall looks like this element" + }, + { + ED_DRAWING_ID_BD_SAND_LOOKS_LIKE, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(0), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_SAND_LOOKS_LIKE, GADGET_ID_NONE, + &level.bd_sand_looks_like, 1, 1, + "Use graphic of element:", NULL, NULL, NULL, "Sand looks like this element" + }, + { + ED_DRAWING_ID_BD_ROCK_TURNS_TO_ON_FALLING, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(2), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_ROCK_TURNS_TO_ON_FALLING, GADGET_ID_NONE, + &level.bd_rock_turns_to_on_falling, 1, 1, + "Turns to when falling:", NULL, NULL, NULL, "Changes to this when falling starts" + }, + { + ED_DRAWING_ID_BD_ROCK_TURNS_TO_ON_IMPACT, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(3), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_ROCK_TURNS_TO_ON_IMPACT, GADGET_ID_NONE, + &level.bd_rock_turns_to_on_impact, 1, 1, + "Turns to on impact:", NULL, NULL, NULL, "Changes to this when falling stops" + }, + { + ED_DRAWING_ID_BD_DIAMOND_TURNS_TO_ON_FALLING, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(2), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_DIAMOND_TURNS_TO_ON_FALLING, GADGET_ID_NONE, + &level.bd_diamond_turns_to_on_falling, 1, 1, + "Turns to when falling:", NULL, NULL, NULL, "Changes to this when falling starts" + }, + { + ED_DRAWING_ID_BD_DIAMOND_TURNS_TO_ON_IMPACT, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(3), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_DIAMOND_TURNS_TO_ON_IMPACT, GADGET_ID_NONE, + &level.bd_diamond_turns_to_on_impact, 1, 1, + "Turns to on impact:", NULL, NULL, NULL, "Changes to this when falling stops" + }, + { + ED_DRAWING_ID_BD_FIREFLY_EXPLODES_TO, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(0), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_FIREFLY_EXPLODES_TO, GADGET_ID_NONE, + &level.bd_firefly_explodes_to, 1, 1, + "Explodes to:", NULL, NULL, NULL, "Changes to this when exploding" + }, + { + ED_DRAWING_ID_BD_FIREFLY_2_EXPLODES_TO, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(0), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_FIREFLY_2_EXPLODES_TO, GADGET_ID_NONE, + &level.bd_firefly_2_explodes_to, 1, 1, + "Explodes to:", NULL, NULL, NULL, "Changes to this when exploding" + }, + { + ED_DRAWING_ID_BD_BUTTERFLY_EXPLODES_TO, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(0), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_BUTTERFLY_EXPLODES_TO, GADGET_ID_NONE, + &level.bd_butterfly_explodes_to, 1, 1, + "Explodes to:", NULL, NULL, NULL, "Changes to this when exploding" + }, + { + ED_DRAWING_ID_BD_BUTTERFLY_2_EXPLODES_TO, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(0), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_BUTTERFLY_2_EXPLODES_TO, GADGET_ID_NONE, + &level.bd_butterfly_2_explodes_to, 1, 1, + "Explodes to:", NULL, NULL, NULL, "Changes to this when exploding" + }, + { + ED_DRAWING_ID_BD_STONEFLY_EXPLODES_TO, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(0), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_STONEFLY_EXPLODES_TO, GADGET_ID_NONE, + &level.bd_stonefly_explodes_to, 1, 1, + "Explodes to:", NULL, NULL, NULL, "Changes to this when exploding" + }, + { + ED_DRAWING_ID_BD_DRAGONFLY_EXPLODES_TO, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(0), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_DRAGONFLY_EXPLODES_TO, GADGET_ID_NONE, + &level.bd_dragonfly_explodes_to, 1, 1, + "Explodes to:", NULL, NULL, NULL, "Changes to this when exploding" + }, + { + ED_DRAWING_ID_BD_DIAMOND_BIRTH_TURNS_TO, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(1), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_DIAMOND_BIRTH_TURNS_TO, GADGET_ID_NONE, + &level.bd_diamond_birth_turns_to, 1, 1, + "Explosion ends in:", NULL, NULL, NULL, "Changes to this after explosion" + }, + { + ED_DRAWING_ID_BD_BOMB_EXPLOSION_TURNS_TO, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(0), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_BOMB_EXPLOSION_TURNS_TO, GADGET_ID_NONE, + &level.bd_bomb_explosion_turns_to, 1, 1, + "Explosion ends in:", NULL, NULL, NULL, "Changes to this after explosion" + }, + { + ED_DRAWING_ID_BD_NITRO_EXPLOSION_TURNS_TO, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(0), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_NITRO_EXPLOSION_TURNS_TO, GADGET_ID_NONE, + &level.bd_nitro_explosion_turns_to, 1, 1, + "Explosion ends in:", NULL, NULL, NULL, "Changes to this after explosion" + }, + { + ED_DRAWING_ID_BD_EXPLOSION_TURNS_TO, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(1), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_BD_EXPLOSION_TURNS_TO, GADGET_ID_NONE, + &level.bd_explosion_turns_to, 1, 1, + "Explosion ends in:", NULL, NULL, NULL, "Changes to this after explosion" + }, + + // ---------- level start element ------------------------------------------- + + { + ED_DRAWING_ID_START_ELEMENT, + -1, ED_AREA_1X1_SETTINGS_YPOS(10), + 0, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_START_ELEMENT, GADGET_ID_USE_START_ELEMENT, + &level.start_element[0], 1, 1, + NULL, NULL, NULL, NULL, "Level start element" + }, + + // ---------- player artwork element ---------------------------------------- + + { + ED_DRAWING_ID_ARTWORK_ELEMENT, + -1, ED_AREA_1X1_SETTINGS_YPOS(11), + 0, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_ARTWORK_ELEMENT, GADGET_ID_USE_ARTWORK_ELEMENT, + &level.artwork_element[0], 1, 1, + NULL, NULL, NULL, NULL, "Element for player artwork" + }, + + // ---------- player explosion element -------------------------------------- + + { + ED_DRAWING_ID_EXPLOSION_ELEMENT, + -1, ED_AREA_1X1_SETTINGS_YPOS(12), + 0, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_EXPLOSION_ELEMENT, GADGET_ID_USE_EXPLOSION_ELEMENT, + &level.explosion_element[0], 1, 1, + NULL, NULL, NULL, NULL, "Element for player explosion" + }, + + // ---------- player initial inventory -------------------------------------- + + { + ED_DRAWING_ID_INVENTORY_CONTENT, + -1, ED_AREA_1X1_SETTINGS_YPOS(1), + 0, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_INVENTORY_CONTENT, GADGET_ID_USE_INITIAL_INVENTORY, + &level.initial_inventory_content[0][0], MAX_INITIAL_INVENTORY_SIZE, 1, + NULL, NULL, NULL, NULL, "Content for initial inventory" + }, + + // ---------- gray ball content ----------------------------------------- + + { + ED_DRAWING_ID_MM_BALL_CONTENT, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(2), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_MM_BALL_CONTENT, GADGET_ID_NONE, + &level.mm_ball_content[0], MAX_MM_BALL_CONTENTS, 1, + "Content:", NULL, NULL, NULL, "Content for gray ball" }, // ---------- element settings: configure 1 (custom elements) --------------- @@ -3659,11 +5213,12 @@ static struct // ---------- custom graphic ------------------------------------------------ { - -1, ED_AREA_1X1_SETTINGS_YPOS(1), - 0, ED_AREA_1X1_SETTINGS_YOFF, - GADGET_ID_CUSTOM_GRAPHIC, GADGET_ID_CUSTOM_USE_GRAPHIC, - &custom_element.gfx_element_initial,1, 1, - NULL, NULL, NULL, "custom graphic element" + ED_DRAWING_ID_CUSTOM_GRAPHIC, + -1, ED_AREA_1X1_SETTINGS_YPOS(1), + 0, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_CUSTOM_GRAPHIC, GADGET_ID_CUSTOM_USE_GRAPHIC, + &custom_element.gfx_element_initial, 1, 1, + NULL, NULL, NULL, NULL, "Custom graphic element" }, // ---------- element settings: configure 2 (custom elements) --------------- @@ -3671,28 +5226,31 @@ static struct // ---------- custom content (when exploding) ------------------------------- { - -1, ED_AREA_3X3_SETTINGS_YPOS(10), - 0, ED_AREA_3X3_SETTINGS_YOFF, - GADGET_ID_CUSTOM_CONTENT, GADGET_ID_NONE, // align three rows - &custom_element.content.e[0][0], 3, 3, - "content:", NULL, NULL, NULL + ED_DRAWING_ID_CUSTOM_CONTENT, + -1, ED_AREA_3X3_SETTINGS_YPOS(11), + 0, ED_AREA_3X3_SETTINGS_YOFF, + GADGET_ID_CUSTOM_CONTENT, GADGET_ID_NONE, // align three rows + &custom_element.content.e[0][0], 3, 3, + "Content:", NULL, NULL, NULL, NULL }, // ---------- custom enter and leave element (when moving) ------------------ { - ED_AREA_1X1_SETTINGS_XPOS(1), ED_AREA_1X1_SETTINGS_YPOS(3), - ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, - GADGET_ID_CUSTOM_MOVE_ENTER, GADGET_ID_NONE, - &custom_element.move_enter_element, 1, 1, - "can dig:", " ", NULL, "element that can be digged/collected" + ED_DRAWING_ID_CUSTOM_MOVE_ENTER, + ED_AREA_1X1_SETTINGS_XPOS(1), ED_AREA_1X1_SETTINGS_YPOS(3), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_CUSTOM_MOVE_ENTER, GADGET_ID_NONE, + &custom_element.move_enter_element, 1, 1, + "Can dig:", " ", NULL, NULL, "Element that can be digged/collected" }, { - -1, ED_AREA_1X1_SETTINGS_YPOS(3), - 0, ED_AREA_1X1_SETTINGS_YOFF, - GADGET_ID_CUSTOM_MOVE_LEAVE, GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE, - &custom_element.move_leave_element, 1, 1, - NULL, NULL, NULL, "element that will be left behind" + ED_DRAWING_ID_CUSTOM_MOVE_LEAVE, + -1, ED_AREA_1X1_SETTINGS_YPOS(3), + 0, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_CUSTOM_MOVE_LEAVE, GADGET_ID_CUSTOM_MOVE_LEAVE_TYPE, + &custom_element.move_leave_element, 1, 1, + NULL, NULL, NULL, NULL, "Element that will be left behind" }, // ---------- element settings: advanced (custom elements) ------------------ @@ -3700,61 +5258,67 @@ static struct // ---------- custom change target ------------------------------------------ { - -1, ED_AREA_1X1_SETTINGS_YPOS(1), - 0, ED_AREA_1X1_SETTINGS_YOFF, - GADGET_ID_CUSTOM_CHANGE_TARGET, GADGET_ID_CUSTOM_CAN_CHANGE, - &custom_element_change.target_element, 1, 1, - NULL, "after/when:", NULL, "new target element after change" + ED_DRAWING_ID_CUSTOM_CHANGE_TARGET, + -1, ED_AREA_1X1_SETTINGS_YPOS(1), + 0, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_CUSTOM_CHANGE_TARGET, GADGET_ID_CUSTOM_CAN_CHANGE, + &custom_element_change.target_element, 1, 1, + NULL, "after/when:", NULL, NULL, "New target element after change" }, // ---------- custom change content (extended change target) ---------------- { - -1, ED_AREA_3X3_SETTINGS_YPOS(9), - 0, ED_AREA_3X3_SETTINGS_YOFF, - GADGET_ID_CUSTOM_CHANGE_CONTENT, GADGET_ID_NONE, // align three rows + ED_DRAWING_ID_CUSTOM_CHANGE_CONTENT, + -1, ED_AREA_3X3_SETTINGS_YPOS(9), + 0, ED_AREA_3X3_SETTINGS_YOFF, + GADGET_ID_CUSTOM_CHANGE_CONTENT, GADGET_ID_NONE, // align three rows &custom_element_change.target_content.e[0][0], 3, 3, - NULL, NULL, NULL, "new extended elements after change" + NULL, NULL, NULL, NULL, "New extended elements after change" }, // ---------- custom change trigger (element causing change) ---------------- { - -1, ED_AREA_1X1_SETTINGS_YPOS(5), - 0, ED_AREA_1X1_SETTINGS_YOFF, - GADGET_ID_CUSTOM_CHANGE_TRIGGER, GADGET_ID_CHANGE_OTHER_ACTION, + ED_DRAWING_ID_CUSTOM_CHANGE_TRIGGER, + -1, ED_AREA_1X1_SETTINGS_YPOS(5), + 0, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_CUSTOM_CHANGE_TRIGGER, GADGET_ID_CHANGE_OTHER_ACTION, &custom_element_change.initial_trigger_element, 1, 1, - NULL, NULL, NULL, "other element triggering change" + NULL, NULL, NULL, NULL, "Other element triggering change" }, // ---------- custom change action (element used for action) ---------------- { - -1, ED_AREA_1X1_SETTINGS_YPOS(13), - 0, ED_AREA_1X1_SETTINGS_YOFF, - GADGET_ID_CUSTOM_CHANGE_ACTION, GADGET_ID_ACTION_ARG, - &custom_element_change.action_element, 1, 1, - NULL, NULL, NULL, "element used as action parameter" + ED_DRAWING_ID_CUSTOM_CHANGE_ACTION, + -1, ED_AREA_1X1_SETTINGS_YPOS(13), + 0, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_CUSTOM_CHANGE_ACTION, GADGET_ID_ACTION_ARG, + &custom_element_change.action_element, 1, 1, + NULL, NULL, NULL, NULL, "Element used as action parameter" }, // ---------- group element content ----------------------------------------- { - ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(2), - ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, - GADGET_ID_GROUP_CONTENT, GADGET_ID_NONE, - &group_element_info.element[0], MAX_ELEMENTS_IN_GROUP, 1, - "content:", NULL, NULL, NULL + ED_DRAWING_ID_GROUP_CONTENT, + ED_AREA_1X1_SETTINGS_XPOS(0), ED_AREA_1X1_SETTINGS_YPOS(2), + ED_AREA_1X1_SETTINGS_XOFF, ED_AREA_1X1_SETTINGS_YOFF, + GADGET_ID_GROUP_CONTENT, GADGET_ID_NONE, + &group_element_info.element[0], MAX_ELEMENTS_IN_GROUP, 1, + "Content:", NULL, NULL, NULL, NULL }, // ---------- random background (for random painting) ----------------------- { - -1, ED_AREA_1X1_LSETTINGS_YPOS(1), - 0, ED_AREA_1X1_LSETTINGS_YOFF, - GADGET_ID_RANDOM_BACKGROUND, GADGET_ID_RANDOM_RESTRICTED, - &random_placement_background_element, 1, 1, - NULL, NULL, NULL, "random placement background" + ED_DRAWING_ID_RANDOM_BACKGROUND, + -1, ED_AREA_1X1_LSETTINGS_YPOS(1), + 0, ED_AREA_1X1_LSETTINGS_YOFF, + GADGET_ID_RANDOM_BACKGROUND, GADGET_ID_RANDOM_RESTRICTED, + &random_placement_background_element, 1, 1, + NULL, NULL, NULL, NULL, "Random placement background" }, }; @@ -3776,7 +5340,7 @@ static int level_xpos = -1, level_ypos = -1; static int ed_tilesize = DEFAULT_EDITOR_TILESIZE; static int ed_tilesize_default = DEFAULT_EDITOR_TILESIZE; -#define IN_ED_FIELD(x,y) IN_FIELD(x, y, ed_fieldx, ed_fieldy) +#define IN_ED_FIELD(x, y) IN_FIELD(x, y, ed_fieldx, ed_fieldy) // drawing elements on the three mouse buttons static int new_element1 = EL_WALL; @@ -3810,7 +5374,7 @@ static void AdjustElementListScrollbar(void); static void RedrawDrawingElements(void); static void DrawDrawingWindowExt(boolean); static void DrawDrawingWindow(void); -static void DrawLevelInfoWindow(void); +static void DrawLevelConfigWindow(void); static void DrawPropertiesWindow(void); static void DrawPaletteWindow(void); static void UpdateCustomElementGraphicGadgets(void); @@ -3835,6 +5399,8 @@ static boolean getDrawModeHiRes(void); static int getTabulatorBarWidth(void); static int getTabulatorBarHeight(void); static Pixel getTabulatorBarColor(void); +static void getEditorGraphicAndFrame(int, int *, int *, boolean); +static int numHiresTiles(int); static int num_editor_gadgets = 0; // dynamically determined @@ -3846,7 +5412,7 @@ static int last_drawing_function = GADGET_ID_SINGLE_ITEMS; static boolean draw_with_brush = FALSE; static int properties_element = 0; -static short FieldBackup[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; +static short TileBackup[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; static short UndoBuffer[NUM_UNDO_STEPS][MAX_LEV_FIELDX][MAX_LEV_FIELDY]; static short IntelliDrawBuffer[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; static int undo_buffer_position = 0; @@ -3854,7 +5420,8 @@ static int undo_buffer_steps = 0; static int redo_buffer_steps = 0; static int edit_mode; -static int edit_mode_levelinfo; +static int edit_mode_levelconfig; +static int edit_mode_engineconfig; static int edit_mode_properties; static int element_shift = 0; @@ -3909,6 +5476,321 @@ static int *editor_el_boulderdash_ptr = editor_el_boulderdash; static int num_editor_hl_boulderdash = ARRAY_SIZE(editor_hl_boulderdash); static int num_editor_el_boulderdash = ARRAY_SIZE(editor_el_boulderdash); +static int editor_hl_boulderdash_native[] = +{ + EL_INTERNAL_CASCADE_BD_NATIVE_ACTIVE, + EL_CHAR('B'), + EL_CHAR('D'), + EL_EMPTY, +}; + +static int editor_el_boulderdash_native[] = +{ + EL_EMPTY, + EL_BD_SAND, + EL_BD_ROCK, + EL_BD_DIAMOND, + + EL_BD_INBOX, + EL_BD_STEELWALL, + EL_BD_WALL, + EL_BD_MAGIC_WALL, + + EL_BD_AMOEBA, + EL_BD_BUTTERFLY_UP, + EL_BD_FIREFLY_UP, + EL_BD_EXIT_CLOSED, + + EL_BD_BUTTERFLY_LEFT, + EL_BD_FIREFLY_LEFT, + EL_BD_BUTTERFLY_RIGHT, + EL_BD_FIREFLY_RIGHT, + + EL_BD_SAND_2, + EL_BD_BUTTERFLY_DOWN, + EL_BD_FIREFLY_DOWN, + EL_BD_EXIT_OPEN, + + EL_BD_AMOEBA_2, + EL_BD_BUTTERFLY_2_UP, + EL_BD_FIREFLY_2_UP, + EL_BD_SLIME, + + EL_BD_BUTTERFLY_2_LEFT, + EL_BD_FIREFLY_2_LEFT, + EL_BD_BUTTERFLY_2_RIGHT, + EL_BD_FIREFLY_2_RIGHT, + + EL_BD_BOMB, + EL_BD_BUTTERFLY_2_DOWN, + EL_BD_FIREFLY_2_DOWN, + EL_BD_FLYING_DIAMOND, + + EL_BD_NITRO_PACK, + EL_BD_DRAGONFLY_UP, + EL_BD_STONEFLY_UP, + EL_BD_DIAMOND_GLUED, + + EL_BD_DRAGONFLY_LEFT, + EL_BD_STONEFLY_LEFT, + EL_BD_DRAGONFLY_RIGHT, + EL_BD_STONEFLY_RIGHT, + + EL_BD_NUT, + EL_BD_DRAGONFLY_DOWN, + EL_BD_STONEFLY_DOWN, + EL_EMPTY, + + EL_BD_BITER_SWITCH_1, + EL_BD_BITER_UP, + EL_BD_COW_UP, + EL_EMPTY, + + EL_BD_BITER_LEFT, + EL_BD_COW_LEFT, + EL_BD_BITER_RIGHT, + EL_BD_COW_RIGHT, + + EL_BD_VOODOO_DOLL, + EL_BD_BITER_DOWN, + EL_BD_COW_DOWN, + EL_BD_GHOST, + + EL_BD_SAND_GLUED, + EL_BD_SAND_BALL, + EL_BD_SAND_LOOSE, + EL_BD_WALL_NON_SLOPED, + + EL_BD_SAND_SLOPED_UP_LEFT, + EL_BD_SAND_SLOPED_UP_RIGHT, + EL_BD_WALL_SLOPED_UP_LEFT, + EL_BD_WALL_SLOPED_UP_RIGHT, + + EL_BD_SAND_SLOPED_DOWN_LEFT, + EL_BD_SAND_SLOPED_DOWN_RIGHT, + EL_BD_WALL_SLOPED_DOWN_LEFT, + EL_BD_WALL_SLOPED_DOWN_RIGHT, + + EL_BD_FLYING_ROCK, + EL_BD_ROCK_GLUED, + EL_BD_STEELWALL_SLOPED_UP_LEFT, + EL_BD_STEELWALL_SLOPED_UP_RIGHT, + + EL_BD_WAITING_ROCK, + EL_BD_CHASING_ROCK, + EL_BD_STEELWALL_SLOPED_DOWN_LEFT, + EL_BD_STEELWALL_SLOPED_DOWN_RIGHT, + + EL_BD_MEGA_ROCK, + EL_BD_SWEET, + EL_BD_INVISIBLE_EXIT_CLOSED, + EL_BD_INVISIBLE_EXIT_OPEN, + + EL_BD_STEELWALL_EXPLODABLE, + EL_BD_STEELWALL_DIGGABLE, + EL_BD_WALL_DIGGABLE, + EL_BD_FALLING_WALL, + + EL_BD_EXPANDABLE_WALL_HORIZONTAL, + EL_BD_EXPANDABLE_WALL_VERTICAL, + EL_BD_EXPANDABLE_WALL_ANY, + EL_BD_EXPANDABLE_WALL_SWITCH, + + EL_BD_EXPANDABLE_STEELWALL_HORIZONTAL, + EL_BD_EXPANDABLE_STEELWALL_VERTICAL, + EL_BD_EXPANDABLE_STEELWALL_ANY, + EL_BD_CREATURE_SWITCH, + + EL_BD_BLADDER, + EL_BD_BLADDER_SPENDER, + EL_BD_REPLICATOR, + EL_BD_REPLICATOR_SWITCH, + + EL_BD_CONVEYOR_LEFT, + EL_BD_CONVEYOR_RIGHT, + EL_BD_CONVEYOR_SWITCH, + EL_BD_CONVEYOR_DIR_SWITCH, + + EL_BD_CLOCK, + EL_BD_TIME_PENALTY, + EL_BD_GRAVESTONE, + EL_BD_SKELETON, + + EL_BD_WATER, + EL_BD_ACID, + EL_BD_LAVA, + EL_BD_BOX, + + EL_BD_GATE_1, + EL_BD_GATE_2, + EL_BD_GATE_3, + EL_BD_TRAPPED_DIAMOND, + + EL_BD_KEY_1, + EL_BD_KEY_2, + EL_BD_KEY_3, + EL_BD_DIAMOND_KEY, + + EL_BD_WALL_KEY_1, + EL_BD_WALL_KEY_2, + EL_BD_WALL_KEY_3, + EL_BD_WALL_DIAMOND, + + EL_BD_POT, + EL_BD_GRAVITY_SWITCH, + EL_BD_PNEUMATIC_HAMMER, + EL_BD_TELEPORTER, + + EL_BD_PLAYER, + EL_BD_PLAYER_WITH_BOMB, + EL_BD_PLAYER_WITH_ROCKET_LAUNCHER, + EL_BD_ROCKET_LAUNCHER, + + EL_BD_PLAYER_GLUED, + EL_BD_PLAYER_STIRRING, + EL_EMPTY, + EL_EMPTY, +}; +static int *editor_hl_boulderdash_native_ptr = editor_hl_boulderdash_native; +static int *editor_el_boulderdash_native_ptr = editor_el_boulderdash_native; +static int num_editor_hl_boulderdash_native = ARRAY_SIZE(editor_hl_boulderdash_native); +static int num_editor_el_boulderdash_native = ARRAY_SIZE(editor_el_boulderdash_native); + +static int editor_hl_boulderdash_effects[] = +{ + EL_INTERNAL_CASCADE_BD_EFFECTS_ACTIVE, + EL_CHAR('B'), + EL_CHAR('D'), + EL_CHAR('E'), +}; + +static int editor_el_boulderdash_effects[] = +{ + EL_BD_DIAMOND_FALLING, + EL_BD_ROCK_FALLING, + EL_BD_MEGA_ROCK_FALLING, + EL_BD_FLYING_DIAMOND_FLYING, + + EL_BD_FALLING_WALL_FALLING, + EL_BD_NITRO_PACK_FALLING, + EL_BD_NUT_FALLING, + EL_BD_FLYING_ROCK_FLYING, + + EL_BD_PLAYER_GROWING_1, + EL_BD_PLAYER_GROWING_2, + EL_BD_PLAYER_GROWING_3, + EL_BD_PLAYER, + + EL_BD_PLAYER_WITH_BOMB, + EL_BD_PLAYER_STIRRING, + EL_BD_EXIT_OPEN, + EL_BD_INVISIBLE_EXIT_OPEN, + + EL_BD_BLADDER_1, + EL_BD_BLADDER_2, + EL_BD_BLADDER_3, + EL_BD_BLADDER_4, + + EL_BD_BLADDER_5, + EL_BD_BLADDER_6, + EL_BD_BLADDER_7, + EL_BD_BLADDER_8, + + EL_BD_SAND_2, + EL_BD_COW_ENCLOSED_1, + EL_BD_COW_ENCLOSED_2, + EL_BD_COW_ENCLOSED_3, + + EL_BD_COW_ENCLOSED_4, + EL_BD_COW_ENCLOSED_5, + EL_BD_COW_ENCLOSED_6, + EL_BD_COW_ENCLOSED_7, + + EL_BD_WATER_1, + EL_BD_WATER_2, + EL_BD_WATER_3, + EL_BD_WATER_4, + + EL_BD_WATER_5, + EL_BD_WATER_6, + EL_BD_WATER_7, + EL_BD_WATER_8, + + EL_BD_WATER_9, + EL_BD_WATER_10, + EL_BD_WATER_11, + EL_BD_WATER_12, + + EL_BD_WATER_13, + EL_BD_WATER_14, + EL_BD_WATER_15, + EL_BD_WATER_16, + + EL_BD_BOMB_TICKING_1, + EL_BD_BOMB_TICKING_2, + EL_BD_BOMB_TICKING_3, + EL_BD_BOMB_TICKING_4, + + EL_BD_BOMB_TICKING_5, + EL_BD_BOMB_TICKING_6, + EL_BD_BOMB_TICKING_7, + EL_EMPTY, + + EL_BD_BOMB_EXPLODING_1, + EL_BD_BOMB_EXPLODING_2, + EL_BD_BOMB_EXPLODING_3, + EL_BD_BOMB_EXPLODING_4, + + EL_BD_NUT_BREAKING_1, + EL_BD_NUT_BREAKING_2, + EL_BD_NUT_BREAKING_3, + EL_BD_NUT_BREAKING_4, + + EL_BD_EXPLODING_1, + EL_BD_EXPLODING_2, + EL_BD_EXPLODING_3, + EL_BD_EXPLODING_4, + + EL_BD_EXPLODING_5, + EL_BD_TIME_PENALTY, + EL_BD_DIAMOND_GROWING_1, + EL_BD_DIAMOND_GROWING_2, + + EL_BD_DIAMOND_GROWING_3, + EL_BD_DIAMOND_GROWING_4, + EL_BD_DIAMOND_GROWING_5, + EL_BD_NITRO_PACK_EXPLODING, + + EL_BD_NITRO_PACK_EXPLODING_1, + EL_BD_NITRO_PACK_EXPLODING_2, + EL_BD_NITRO_PACK_EXPLODING_3, + EL_BD_NITRO_PACK_EXPLODING_4, + + EL_BD_ROCK_GROWING_1, + EL_BD_ROCK_GROWING_2, + EL_BD_ROCK_GROWING_3, + EL_BD_ROCK_GROWING_4, + + EL_BD_STEELWALL_GROWING_1, + EL_BD_STEELWALL_GROWING_2, + EL_BD_STEELWALL_GROWING_3, + EL_BD_STEELWALL_GROWING_4, + + EL_BD_CLOCK_GROWING_1, + EL_BD_CLOCK_GROWING_2, + EL_BD_CLOCK_GROWING_3, + EL_BD_CLOCK_GROWING_4, + + EL_BD_GHOST_EXPLODING_1, + EL_BD_GHOST_EXPLODING_2, + EL_BD_GHOST_EXPLODING_3, + EL_BD_GHOST_EXPLODING_4, +}; +static int *editor_hl_boulderdash_effects_ptr = editor_hl_boulderdash_effects; +static int *editor_el_boulderdash_effects_ptr = editor_el_boulderdash_effects; +static int num_editor_hl_boulderdash_effects = ARRAY_SIZE(editor_hl_boulderdash_effects); +static int num_editor_el_boulderdash_effects = ARRAY_SIZE(editor_el_boulderdash_effects); + static int editor_hl_emerald_mine[] = { EL_INTERNAL_CASCADE_EM_ACTIVE, @@ -4046,13 +5928,13 @@ static int editor_el_emerald_mine_club[] = EL_EMC_MAGIC_BALL, EL_EMC_MAGIC_BALL_SWITCH, - EL_SPRING, - EL_EMC_SPRING_BUMPER, - EL_EMC_LENSES, EL_EMC_MAGNIFIER, - EL_EMPTY, - EL_EMPTY, + + EL_SPRING_LEFT, + EL_SPRING, + EL_SPRING_RIGHT, + EL_EMC_SPRING_BUMPER, EL_BALLOON, EL_YAMYAM_UP, @@ -4524,7 +6406,12 @@ static int editor_el_mirror_magic[] = EL_MM_WOODEN_GRID_FIXED_1, EL_MM_WOODEN_GRID_FIXED_2, EL_MM_WOODEN_GRID_FIXED_3, - EL_MM_WOODEN_GRID_FIXED_4 + EL_MM_WOODEN_GRID_FIXED_4, + + EL_MM_ENVELOPE_1, + EL_MM_ENVELOPE_2, + EL_MM_ENVELOPE_3, + EL_MM_ENVELOPE_4 }; static int *editor_hl_mirror_magic_ptr = editor_hl_mirror_magic; static int *editor_el_mirror_magic_ptr = editor_el_mirror_magic; @@ -4553,8 +6440,8 @@ static int editor_el_deflektor[] = EL_DF_MIRROR_START, EL_DF_MIRROR_ROTATING_START, + EL_DF_MIRROR_FIXED_START, EL_DF_CELL, - EL_DF_MINE, EL_DF_FIBRE_OPTIC_RED_1, EL_DF_FIBRE_OPTIC_YELLOW_1, @@ -4569,7 +6456,12 @@ static int editor_el_deflektor[] = EL_DF_STEEL_WALL, EL_DF_WOODEN_WALL, EL_DF_REFRACTOR, - EL_EMPTY + EL_DF_MINE, + + EL_DF_SLOPE_1, + EL_DF_SLOPE_2, + EL_DF_SLOPE_3, + EL_DF_SLOPE_4 }; static int *editor_hl_deflektor_ptr = editor_hl_deflektor; static int *editor_el_deflektor_ptr = editor_el_deflektor; @@ -5186,6 +7078,41 @@ static int *editor_el_group_ptr = editor_el_group; static int num_editor_hl_group = ARRAY_SIZE(editor_hl_group); static int num_editor_el_group = ARRAY_SIZE(editor_el_group); +static int editor_hl_empty_space[] = +{ + EL_INTERNAL_CASCADE_ES_ACTIVE, + EL_CHAR('E'), + EL_CHAR('S'), + EL_EMPTY, +}; + +static int editor_el_empty_space[] = +{ + EL_EMPTY_SPACE_1, + EL_EMPTY_SPACE_2, + EL_EMPTY_SPACE_3, + EL_EMPTY_SPACE_4, + + EL_EMPTY_SPACE_5, + EL_EMPTY_SPACE_6, + EL_EMPTY_SPACE_7, + EL_EMPTY_SPACE_8, + + EL_EMPTY_SPACE_9, + EL_EMPTY_SPACE_10, + EL_EMPTY_SPACE_11, + EL_EMPTY_SPACE_12, + + EL_EMPTY_SPACE_13, + EL_EMPTY_SPACE_14, + EL_EMPTY_SPACE_15, + EL_EMPTY_SPACE_16 +}; +static int *editor_hl_empty_space_ptr = editor_hl_empty_space; +static int *editor_el_empty_space_ptr = editor_el_empty_space; +static int num_editor_hl_empty_space = ARRAY_SIZE(editor_hl_empty_space); +static int num_editor_el_empty_space = ARRAY_SIZE(editor_el_empty_space); + static int editor_hl_reference[] = { EL_INTERNAL_CASCADE_REF_ACTIVE, @@ -5274,6 +7201,8 @@ static boolean setup_editor_cascade_never = FALSE; static boolean setup_editor_el_players = TRUE; static boolean setup_editor_el_boulderdash = TRUE; +static boolean setup_editor_el_boulderdash_native = TRUE; +static boolean setup_editor_el_boulderdash_effects = TRUE; static boolean setup_editor_el_emerald_mine = TRUE; static boolean setup_editor_el_emerald_mine_club = TRUE; static boolean setup_editor_el_more = TRUE; @@ -5320,6 +7249,18 @@ editor_elements_info[] = &editor_hl_boulderdash_ptr, &num_editor_hl_boulderdash, &editor_el_boulderdash_ptr, &num_editor_el_boulderdash }, + { + &setup_editor_el_boulderdash_native, + &setup.editor_cascade.el_bd_native, + &editor_hl_boulderdash_native_ptr, &num_editor_hl_boulderdash_native, + &editor_el_boulderdash_native_ptr, &num_editor_el_boulderdash_native + }, + { + &setup_editor_el_boulderdash_effects, + &setup.editor_cascade.el_bd_effects, + &editor_hl_boulderdash_effects_ptr, &num_editor_hl_boulderdash_effects, + &editor_el_boulderdash_effects_ptr, &num_editor_el_boulderdash_effects + }, { &setup_editor_el_emerald_mine, &setup.editor_cascade.el_em, @@ -5398,6 +7339,12 @@ editor_elements_info[] = &editor_hl_group_ptr, &num_editor_hl_group, &editor_el_group_ptr, &num_editor_el_group }, + { + &setup_editor_el_custom, + &setup.editor_cascade.el_es, + &editor_hl_empty_space_ptr, &num_editor_hl_empty_space, + &editor_el_empty_space_ptr, &num_editor_el_empty_space + }, { &setup_editor_el_custom, &setup.editor_cascade.el_ref, @@ -5430,6 +7377,14 @@ editor_elements_info[] = } }; +static struct XY xy_directions[] = +{ + { -1, 0 }, + { +1, 0 }, + { 0, -1 }, + { 0, +1 } +}; + // ---------------------------------------------------------------------------- // functions @@ -5453,7 +7408,7 @@ static int getTextWidthForDrawingArea(char *text) if (text == NULL) return 0; - return (getTextWidth(text, FONT_TEXT_1) + ED_DRAWINGAREA_TEXT_DISTANCE); + return (getTextWidth(text, FONT_TEXT_1) + ED_DRAWINGAREA_BORDER_SIZE); } static int getRightGadgetBorder(struct GadgetInfo *gi, char *text) @@ -5483,7 +7438,7 @@ static char *getElementInfoText(int element) static char *getElementDescriptionFilenameExt(char *basename) { - char *elements_subdir = "elements"; + char *elements_subdir = ELEMENTS_DIRECTORY; static char *elements_subdir2 = NULL; static char *filename = NULL; @@ -5524,6 +7479,11 @@ static char *getElementDescriptionFilename(int element) if (filename != NULL) return filename; + // 3rd try: look for generic fallback text file for any element + filename = getElementDescriptionFilenameExt(FALLBACK_TEXT_FILENAME); + if (filename != NULL) + return filename; + return NULL; } @@ -5545,9 +7505,18 @@ static void InitDynamicEditorElementList(int **elements, int *num_elements) // find all elements used in current level for (y = 0; y < lev_fieldy; y++) + { for (x = 0; x < lev_fieldx; x++) - if (Feld[x][y] < NUM_FILE_ELEMENTS) // should always be true - element_found[Feld[x][y]] = TRUE; + { + if (Tile[x][y] >= NUM_FILE_ELEMENTS) // should never happen + continue; + + if (IS_MM_WALL(Tile[x][y])) + element_found[map_mm_wall_element(Tile[x][y])] = TRUE; + else + element_found[Tile[x][y]] = TRUE; + } + } *num_elements = 0; @@ -5567,14 +7536,18 @@ static void InitDynamicEditorElementList(int **elements, int *num_elements) *num_elements = 0; - // add all elements used in current level (non-custom/group elements) + // add all elements used in current level (non-custom/group/empty elements) for (i = 0; i < NUM_FILE_ELEMENTS; i++) - if (element_found[i] && !(IS_CUSTOM_ELEMENT(i) || IS_GROUP_ELEMENT(i))) + if (element_found[i] && !(IS_CUSTOM_ELEMENT(i) || + IS_GROUP_ELEMENT(i) || + IS_EMPTY_ELEMENT(i))) (*elements)[(*num_elements)++] = i; - // add all elements used in current level (custom/group elements) + // add all elements used in current level (custom/group/empty elements) for (i = 0; i < NUM_FILE_ELEMENTS; i++) - if (element_found[i] && (IS_CUSTOM_ELEMENT(i) || IS_GROUP_ELEMENT(i))) + if (element_found[i] && (IS_CUSTOM_ELEMENT(i) || + IS_GROUP_ELEMENT(i) || + IS_EMPTY_ELEMENT(i))) (*elements)[(*num_elements)++] = i; while (*num_elements % 4) // pad with empty elements, if needed @@ -5587,6 +7560,8 @@ static void ReinitializeElementList_EnableSections(void) setup_editor_el_players = TRUE; setup_editor_el_boulderdash = TRUE; + setup_editor_el_boulderdash_native = TRUE; + setup_editor_el_boulderdash_effects = TRUE; setup_editor_el_emerald_mine = TRUE; setup_editor_el_emerald_mine_club = TRUE; setup_editor_el_more = TRUE; @@ -5609,6 +7584,8 @@ static void ReinitializeElementList_EnableSections(void) { setup_editor_el_players = FALSE; setup_editor_el_boulderdash = FALSE; + setup_editor_el_boulderdash_native = FALSE; + setup_editor_el_boulderdash_effects = FALSE; setup_editor_el_emerald_mine = FALSE; setup_editor_el_emerald_mine_club = FALSE; setup_editor_el_more = FALSE; @@ -5639,12 +7616,34 @@ static void ReinitializeElementList_EnableSections(void) if (level.game_engine_type == GAME_ENGINE_TYPE_RND) { + setup_editor_el_boulderdash_native = FALSE; + setup_editor_el_boulderdash_effects = FALSE; + setup_editor_el_mirror_magic = FALSE; + setup_editor_el_deflektor = FALSE; + } + else if (level.game_engine_type == GAME_ENGINE_TYPE_BD) + { + setup_editor_el_players = FALSE; + setup_editor_el_boulderdash = FALSE; + setup_editor_el_emerald_mine = FALSE; + setup_editor_el_emerald_mine_club = FALSE; + setup_editor_el_more = FALSE; + setup_editor_el_sokoban = FALSE; + setup_editor_el_supaplex = FALSE; + setup_editor_el_diamond_caves = FALSE; + setup_editor_el_dx_boulderdash = FALSE; setup_editor_el_mirror_magic = FALSE; setup_editor_el_deflektor = FALSE; + setup_editor_el_chars = FALSE; + setup_editor_el_steel_chars = FALSE; + + setup_editor_el_custom = FALSE; } else if (level.game_engine_type == GAME_ENGINE_TYPE_EM) { setup_editor_el_boulderdash = FALSE; + setup_editor_el_boulderdash_native = FALSE; + setup_editor_el_boulderdash_effects = FALSE; setup_editor_el_more = FALSE; setup_editor_el_sokoban = FALSE; setup_editor_el_supaplex = FALSE; @@ -5660,6 +7659,8 @@ static void ReinitializeElementList_EnableSections(void) { setup_editor_el_players = FALSE; setup_editor_el_boulderdash = FALSE; + setup_editor_el_boulderdash_native = FALSE; + setup_editor_el_boulderdash_effects = FALSE; setup_editor_el_emerald_mine = FALSE; setup_editor_el_emerald_mine_club = FALSE; setup_editor_el_more = FALSE; @@ -5677,6 +7678,8 @@ static void ReinitializeElementList_EnableSections(void) { setup_editor_el_players = FALSE; setup_editor_el_boulderdash = FALSE; + setup_editor_el_boulderdash_native = FALSE; + setup_editor_el_boulderdash_effects = FALSE; setup_editor_el_emerald_mine = FALSE; setup_editor_el_emerald_mine_club = FALSE; setup_editor_el_more = FALSE; @@ -5739,10 +7742,10 @@ static void ReinitializeElementList(void) int element = (*editor_elements_info[i].element_list)[j]; if (element >= NUM_FILE_ELEMENTS) - Error(ERR_WARN, "editor element %d is runtime element", element); + Warn("editor element %d is runtime element", element); if (strEqual(getElementInfoText(element), INFOTEXT_UNKNOWN_ELEMENT)) - Error(ERR_WARN, "no element description text for element %d", element); + Warn("no element description text for element %d", element); } } @@ -5752,10 +7755,10 @@ static void ReinitializeElementList(void) // determine size of element list for (i = 0; editor_elements_info[i].setup_value != NULL; i++) { - boolean found_inactive_cascade = FALSE; - if (*editor_elements_info[i].setup_value) { + boolean found_inactive_cascade = FALSE; + if (setup.editor.el_headlines) { // required for correct padding of palette headline buttons @@ -6047,11 +8050,21 @@ static void DrawDrawingArea(int id) int tilesize = ED_DRAWINGAREA_TILE_SIZE; for (x = 0; x < area_xsize; x++) + { for (y = 0; y < area_ysize; y++) + { + int element = value[x * area_ysize + y]; + int graphic; + int frame; + + getEditorGraphicAndFrame(element, &graphic, &frame, TRUE); + DrawSizedGraphicExt(drawto, gi->x + x * tilesize, gi->y + y * tilesize, - el2edimg(value[x * area_ysize + y]), 0, tilesize); + graphic, frame, tilesize); + } + } } static void ScrollEditorLevel(int from_x, int from_y, int scroll) @@ -6085,10 +8098,47 @@ static void ScrollEditorLevel(int from_x, int from_y, int scroll) BackToFront(); } +static void getEditorGraphicAndFrame(int element, int *graphic, int *frame, boolean use_editor_gfx) +{ + if (use_editor_gfx) + { + *graphic = el2edimg(element); + *frame = 0; + } + else + { + *graphic = el2img(element); + *frame = (ANIM_MODE(*graphic) == ANIM_CE_VALUE ? + custom_element.ce_value_fixed_initial : + ANIM_MODE(*graphic) == ANIM_CE_SCORE ? + custom_element.collect_score_initial : FrameCounter); + } + + if (*graphic == IMG_UNKNOWN) + { + // no graphic defined -- if BD style, try to get runtime ("effect") element graphics + // (normal BD style elements have graphics, but runtime ("effects") elements do not) + int element_bd = map_element_RND_to_BD_cave(element); + + if (element_bd != O_UNKNOWN) + { + struct GraphicInfo_BD *g_bd = &graphic_info_bd_object[element_bd][0]; + + *graphic = g_bd->graphic; + *frame = g_bd->frame; + } + } +} + static void getEditorGraphicSource(int element, int tile_size, Bitmap **bitmap, int *x, int *y) { - getSizedGraphicSource(el2edimg(element), 0, tile_size, bitmap, x, y); + int graphic; + int frame; + + getEditorGraphicAndFrame(element, &graphic, &frame, TRUE); + + getSizedGraphicSource(graphic, frame, tile_size, bitmap, x, y); } static void CreateControlButtons(void) @@ -6099,6 +8149,7 @@ static void CreateControlButtons(void) // create toolbox buttons for (i = 0; i < ED_NUM_CTRL_BUTTONS; i++) { + int type_id = controlbutton_info[i].gadget_id; // same as gadget ID here int id = controlbutton_info[i].gadget_id; int type = controlbutton_info[i].gadget_type; int graphic = controlbutton_info[i].graphic; @@ -6122,6 +8173,9 @@ static void CreateControlButtons(void) int radio_button_nr = RADIO_NR_NONE; boolean checked = FALSE; + if (type_id != i) + Fail("'controlbutton_info' structure corrupted at index %d -- please fix", i); + if (type == GD_TYPE_RADIO_BUTTON) { event_mask = GD_EVENT_PRESSED; @@ -6182,7 +8236,7 @@ static void CreateControlButtons(void) } gi = CreateGadget(GDI_CUSTOM_ID, id, - GDI_CUSTOM_TYPE_ID, i, + GDI_CUSTOM_TYPE_ID, type_id, GDI_IMAGE_ID, graphic, GDI_INFO_TEXT, controlbutton_info[i].infotext, GDI_X, x, @@ -6208,7 +8262,7 @@ static void CreateControlButtons(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; } @@ -6231,6 +8285,7 @@ static void CreateControlButtons(void) for (i = 0; i < ED_NUM_SCROLLBUTTONS; i++) { int id = scrollbutton_info[i].gadget_id; + int type_id = scrollbutton_info[i].gadget_type_id; int graphic = scrollbutton_info[i].graphic; struct GraphicInfo *gd = &graphic_info[graphic]; Bitmap *gd_bitmap = gd->bitmap; @@ -6244,6 +8299,9 @@ static void CreateControlButtons(void) int y = scrollbutton_pos[i].y; unsigned int event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED; + if (type_id != i) + Fail("'scrollbutton_info' structure corrupted at index %d -- please fix", i); + if (id == GADGET_ID_SCROLL_LIST_UP || id == GADGET_ID_SCROLL_LIST_DOWN) { @@ -6257,7 +8315,7 @@ static void CreateControlButtons(void) } gi = CreateGadget(GDI_CUSTOM_ID, id, - GDI_CUSTOM_TYPE_ID, i, + GDI_CUSTOM_TYPE_ID, type_id, GDI_IMAGE_ID, graphic, GDI_INFO_TEXT, scrollbutton_info[i].infotext, GDI_X, x, @@ -6274,7 +8332,7 @@ static void CreateControlButtons(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; } @@ -6282,6 +8340,7 @@ static void CreateControlButtons(void) // create buttons for element list for (i = 0; i < ED_NUM_ELEMENTLIST_BUTTONS; i++) { + int type_id = i; int id = GADGET_ID_ELEMENTLIST_FIRST + i; int graphic = IMG_EDITOR_PALETTE_BUTTON; struct GraphicInfo *gd = &graphic_info[graphic]; @@ -6306,7 +8365,7 @@ static void CreateControlButtons(void) deco_ypos = (gd->height - tile_size) / 2; gi = CreateGadget(GDI_CUSTOM_ID, id, - GDI_CUSTOM_TYPE_ID, i, + GDI_CUSTOM_TYPE_ID, type_id, GDI_IMAGE_ID, graphic, GDI_INFO_TEXT, getElementInfoText(element), GDI_X, x, @@ -6327,7 +8386,7 @@ static void CreateControlButtons(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; } @@ -6340,9 +8399,13 @@ static void CreateCounterButtons(void) for (i = 0; i < ED_NUM_COUNTERBUTTONS; i++) { - int j; + int type_id = counterbutton_info[i].gadget_type_id; int x = SX + ED_SETTINGS_X(counterbutton_info[i].x); // down count button int y = SY + ED_SETTINGS_Y(counterbutton_info[i].y); + int j; + + if (type_id != i) + Fail("'counterbutton_info' structure corrupted at index %d -- please fix", i); // determine horizontal position to the right of specified gadget if (counterbutton_info[i].gadget_id_align != GADGET_ID_NONE) @@ -6362,11 +8425,9 @@ static void CreateCounterButtons(void) int graphic; struct GraphicInfo *gd; int gd_x1, gd_x2, gd_y1, gd_y2; - unsigned int event_mask; + unsigned int event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED; char infotext[max_infotext_len + 1]; - event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED; - if (i == ED_COUNTER_ID_SELECT_LEVEL) { graphic = (j == 0 ? @@ -6401,10 +8462,10 @@ static void CreateCounterButtons(void) gd_y2 = gd->src_y + gd->pressed_yoffset; sprintf(infotext, "%s counter value by 1, 5 or 10", - (j == 0 ? "decrease" : "increase")); + (j == 0 ? "Decrease" : "Increase")); gi = CreateGadget(GDI_CUSTOM_ID, id, - GDI_CUSTOM_TYPE_ID, i, + GDI_CUSTOM_TYPE_ID, type_id, GDI_IMAGE_ID, graphic, GDI_INFO_TEXT, infotext, GDI_X, x, @@ -6421,7 +8482,7 @@ static void CreateCounterButtons(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; right_gadget_border[id] = @@ -6461,9 +8522,9 @@ static void CreateCounterButtons(void) gd_y2 = gd->src_y + gd->active_yoffset; gi = CreateGadget(GDI_CUSTOM_ID, id, - GDI_CUSTOM_TYPE_ID, i, + GDI_CUSTOM_TYPE_ID, type_id, GDI_IMAGE_ID, graphic, - GDI_INFO_TEXT, "enter counter value", + GDI_INFO_TEXT, "Enter counter value", GDI_X, x, GDI_Y, y, GDI_TYPE, GD_TYPE_TEXT_INPUT_NUMERIC, @@ -6483,7 +8544,7 @@ static void CreateCounterButtons(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; right_gadget_border[id] = @@ -6506,19 +8567,21 @@ static void CreateDrawingAreas(void) for (i = 0; i < ED_NUM_DRAWING_AREAS; i++) { struct GadgetInfo *gi; - unsigned int event_mask; int id = drawingarea_info[i].gadget_id; + int type_id = drawingarea_info[i].gadget_type_id; int x = SX + ED_AREA_SETTINGS_X(drawingarea_info[i]); int y = SY + ED_AREA_SETTINGS_Y(drawingarea_info[i]); int area_xsize = drawingarea_info[i].area_xsize; int area_ysize = drawingarea_info[i].area_ysize; int item_size = (id == GADGET_ID_DRAWING_LEVEL ? ed_tilesize : ED_DRAWINGAREA_TILE_SIZE); - - event_mask = + unsigned int event_mask = GD_EVENT_PRESSED | GD_EVENT_RELEASED | GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS | GD_EVENT_PIXEL_PRECISE; + if (type_id != i) + Fail("'drawingarea_info' structure corrupted at index %d -- please fix", i); + // determine horizontal position to the right of specified gadget if (drawingarea_info[i].gadget_id_align != GADGET_ID_NONE) x = (right_gadget_border[drawingarea_info[i].gadget_id_align] + @@ -6529,7 +8592,7 @@ static void CreateDrawingAreas(void) x += getTextWidthForDrawingArea(drawingarea_info[i].text_left); gi = CreateGadget(GDI_CUSTOM_ID, id, - GDI_CUSTOM_TYPE_ID, i, + GDI_CUSTOM_TYPE_ID, type_id, GDI_X, x, GDI_Y, y, GDI_TYPE, GD_TYPE_DRAWING_AREA, @@ -6541,7 +8604,7 @@ static void CreateDrawingAreas(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; right_gadget_border[id] = @@ -6562,11 +8625,15 @@ static void CreateTextInputGadgets(void) int gd_x2 = gd->src_x + gd->active_xoffset; int gd_y2 = gd->src_y + gd->active_yoffset; struct GadgetInfo *gi; - unsigned int event_mask; + unsigned int event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; char infotext[MAX_OUTPUT_LINESIZE + 1]; int id = textinput_info[i].gadget_id; + int type_id = textinput_info[i].gadget_type_id; int x, y; + if (type_id != i) + Fail("'textinput_info' structure corrupted at index %d -- please fix", i); + if (i == ED_TEXTINPUT_ID_ELEMENT_NAME) { int element_border = graphic_info[IMG_EDITOR_ELEMENT_BORDER].border_size; @@ -6589,13 +8656,15 @@ static void CreateTextInputGadgets(void) y = ED_SETTINGS_Y(textinput_info[i].y); } - event_mask = GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; + // determine horizontal offset for leading text + if (textinput_info[i].text_left != NULL) + x += getTextWidthForGadget(textinput_info[i].text_left); - sprintf(infotext, "Enter %s", textinput_info[i].infotext); + sprintf(infotext, "%s", textinput_info[i].infotext); infotext[max_infotext_len] = '\0'; gi = CreateGadget(GDI_CUSTOM_ID, id, - GDI_CUSTOM_TYPE_ID, i, + GDI_CUSTOM_TYPE_ID, type_id, GDI_INFO_TEXT, infotext, GDI_X, SX + x, GDI_Y, SY + y, @@ -6614,7 +8683,7 @@ static void CreateTextInputGadgets(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; } @@ -6633,19 +8702,21 @@ static void CreateTextAreaGadgets(void) int gd_x2 = gd->src_x + gd->active_xoffset; int gd_y2 = gd->src_y + gd->active_yoffset; struct GadgetInfo *gi; - unsigned int event_mask; + unsigned int event_mask = GD_EVENT_TEXT_LEAVING; char infotext[MAX_OUTPUT_LINESIZE + 1]; int id = textarea_info[i].gadget_id; + int type_id = textarea_info[i].gadget_type_id; int area_xsize = textarea_info[i].xsize; int area_ysize = textarea_info[i].ysize; - event_mask = GD_EVENT_TEXT_LEAVING; + if (type_id != i) + Fail("'textarea_info' structure corrupted at index %d -- please fix", i); sprintf(infotext, "Enter %s", textarea_info[i].infotext); infotext[max_infotext_len] = '\0'; gi = CreateGadget(GDI_CUSTOM_ID, id, - GDI_CUSTOM_TYPE_ID, i, + GDI_CUSTOM_TYPE_ID, type_id, GDI_INFO_TEXT, infotext, GDI_X, SX + ED_SETTINGS_X(textarea_info[i].x), GDI_Y, SY + ED_SETTINGS_Y(textarea_info[i].y), @@ -6663,7 +8734,7 @@ static void CreateTextAreaGadgets(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; } @@ -6672,6 +8743,7 @@ static void CreateTextAreaGadgets(void) static void CreateSelectboxGadgets(void) { int max_infotext_len = getMaxInfoTextLength(); + int i, j; for (i = 0; i < ED_NUM_SELECTBOX; i++) @@ -6684,11 +8756,16 @@ static void CreateSelectboxGadgets(void) int gd_y2 = gd->src_y + gd->active_yoffset; int selectbox_button_xsize = gd2->width; struct GadgetInfo *gi; - unsigned int event_mask; char infotext[MAX_OUTPUT_LINESIZE + 1]; int id = selectbox_info[i].gadget_id; + int type_id = selectbox_info[i].gadget_type_id; int x = SX + ED_SETTINGS_X(selectbox_info[i].x); int y = SY + ED_SETTINGS_Y(selectbox_info[i].y); + unsigned int event_mask = + GD_EVENT_RELEASED | GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; + + if (type_id != i) + Fail("'selectbox_info' structure corrupted at index %d -- please fix", i); if (selectbox_info[i].size == -1) // dynamically determine size { @@ -6704,9 +8781,6 @@ static void CreateSelectboxGadgets(void) selectbox_info[i].size++; // add one character empty space } - event_mask = GD_EVENT_RELEASED | - GD_EVENT_TEXT_RETURN | GD_EVENT_TEXT_LEAVING; - // determine horizontal position to the right of specified gadget if (selectbox_info[i].gadget_id_align != GADGET_ID_NONE) x = (right_gadget_border[selectbox_info[i].gadget_id_align] + @@ -6716,11 +8790,11 @@ static void CreateSelectboxGadgets(void) if (selectbox_info[i].text_left != NULL) x += getTextWidthForGadget(selectbox_info[i].text_left); - sprintf(infotext, "Select %s", selectbox_info[i].infotext); + sprintf(infotext, "%s", selectbox_info[i].infotext); infotext[max_infotext_len] = '\0'; gi = CreateGadget(GDI_CUSTOM_ID, id, - GDI_CUSTOM_TYPE_ID, i, + GDI_CUSTOM_TYPE_ID, type_id, GDI_INFO_TEXT, infotext, GDI_X, x, GDI_Y, y, @@ -6742,7 +8816,7 @@ static void CreateSelectboxGadgets(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; right_gadget_border[id] = @@ -6758,8 +8832,10 @@ static void CreateTextbuttonGadgets(void) for (i = 0; i < ED_NUM_TEXTBUTTONS; i++) { int id = textbutton_info[i].gadget_id; + int type_id = textbutton_info[i].gadget_type_id; int is_tab_button = - ((id >= GADGET_ID_LEVELINFO_LEVEL && id <= GADGET_ID_LEVELINFO_EDITOR) || + ((id >= GADGET_ID_LEVELCONFIG_LEVEL && id <= GADGET_ID_LEVELCONFIG_ENGINE) || + (id >= GADGET_ID_ENGINECONFIG_CONFIG && id <= GADGET_ID_ENGINECONFIG_COLORS) || (id >= GADGET_ID_PROPERTIES_INFO && id <= GADGET_ID_PROPERTIES_CHANGE)); int graphic = (is_tab_button ? IMG_EDITOR_TABBUTTON : IMG_EDITOR_TEXTBUTTON); @@ -6775,16 +8851,17 @@ static void CreateTextbuttonGadgets(void) int border_xsize = gd->border_size + gd->draw_xoffset; int border_ysize = gd->border_size; struct GadgetInfo *gi; - unsigned int event_mask; + unsigned int event_mask = GD_EVENT_RELEASED; char infotext[MAX_OUTPUT_LINESIZE + 1]; int x = SX + ED_SETTINGS_X(textbutton_info[i].x); int y = SY + ED_SETTINGS_Y(textbutton_info[i].y); + if (type_id != i) + Fail("'textbutton_info' structure corrupted at index %d -- please fix", i); + if (textbutton_info[i].size == -1) // dynamically determine size textbutton_info[i].size = strlen(textbutton_info[i].text); - event_mask = GD_EVENT_RELEASED; - sprintf(infotext, "%s", textbutton_info[i].infotext); infotext[max_infotext_len] = '\0'; @@ -6804,7 +8881,7 @@ static void CreateTextbuttonGadgets(void) x += getTextWidthForGadget(textbutton_info[i].text_left); gi = CreateGadget(GDI_CUSTOM_ID, id, - GDI_CUSTOM_TYPE_ID, i, + GDI_CUSTOM_TYPE_ID, type_id, GDI_IMAGE_ID, graphic, GDI_INFO_TEXT, infotext, GDI_X, x, @@ -6826,7 +8903,7 @@ static void CreateTextbuttonGadgets(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; right_gadget_border[id] = @@ -6837,13 +8914,13 @@ static void CreateTextbuttonGadgets(void) static void CreateGraphicbuttonGadgets(void) { struct GadgetInfo *gi; - unsigned int event_mask; int i; // create buttons for scrolling of drawing area and element list for (i = 0; i < ED_NUM_GRAPHICBUTTONS; i++) { int id = graphicbutton_info[i].gadget_id; + int type_id = graphicbutton_info[i].gadget_type_id; int x = SX + ED_SETTINGS_X(graphicbutton_info[i].x); int y = SY + ED_SETTINGS_Y(graphicbutton_info[i].y); int graphic = graphicbutton_info[i].graphic; @@ -6852,8 +8929,10 @@ static void CreateGraphicbuttonGadgets(void) int gd_y1 = gd->src_y; int gd_x2 = gd->src_x + gd->pressed_xoffset; int gd_y2 = gd->src_y + gd->pressed_yoffset; + unsigned int event_mask = GD_EVENT_RELEASED; - event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED; + if (type_id != i) + Fail("'graphicbutton_info' structure corrupted at index %d -- please fix", i); // determine horizontal position to the right of specified gadget if (graphicbutton_info[i].gadget_id_align != GADGET_ID_NONE) @@ -6865,7 +8944,7 @@ static void CreateGraphicbuttonGadgets(void) x += getTextWidthForGadget(graphicbutton_info[i].text_left); gi = CreateGadget(GDI_CUSTOM_ID, id, - GDI_CUSTOM_TYPE_ID, i, + GDI_CUSTOM_TYPE_ID, type_id, GDI_IMAGE_ID, graphic, GDI_INFO_TEXT, graphicbutton_info[i].infotext, GDI_X, x, @@ -6882,7 +8961,7 @@ static void CreateGraphicbuttonGadgets(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; right_gadget_border[id] = @@ -6937,6 +9016,7 @@ static void CreateScrollbarGadgets(void) for (i = 0; i < ED_NUM_SCROLLBARS; i++) { int id = scrollbar_info[i].gadget_id; + int type_id = scrollbar_info[i].gadget_type_id; int graphic = scrollbar_info[i].graphic; struct GraphicInfo *gd = &graphic_info[graphic]; int gd_x1 = gd->src_x; @@ -6945,7 +9025,10 @@ static void CreateScrollbarGadgets(void) int gd_y2 = gd->src_y + gd->pressed_yoffset; struct GadgetInfo *gi; int items_max, items_visible, item_position; - unsigned int event_mask; + unsigned int event_mask = GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS; + + if (type_id != i) + Fail("'scrollbar_info' structure corrupted at index %d -- please fix", i); if (i == ED_SCROLLBAR_ID_LIST_VERTICAL) { @@ -6969,10 +9052,8 @@ static void CreateScrollbarGadgets(void) } } - event_mask = GD_EVENT_MOVING | GD_EVENT_OFF_BORDERS; - gi = CreateGadget(GDI_CUSTOM_ID, id, - GDI_CUSTOM_TYPE_ID, i, + GDI_CUSTOM_TYPE_ID, type_id, GDI_IMAGE_ID, graphic, GDI_INFO_TEXT, scrollbar_info[i].infotext, GDI_X, scrollbar_pos[i].x, @@ -6997,7 +9078,7 @@ static void CreateScrollbarGadgets(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; } @@ -7006,14 +9087,12 @@ static void CreateScrollbarGadgets(void) static void CreateCheckbuttonGadgets(void) { struct GadgetInfo *gi; - unsigned int event_mask; int i; - event_mask = GD_EVENT_PRESSED; - for (i = 0; i < ED_NUM_CHECKBUTTONS; i++) { int id = checkbutton_info[i].gadget_id; + int type_id = checkbutton_info[i].gadget_type_id; int graphic = (id == GADGET_ID_STICK_ELEMENT ? IMG_EDITOR_STICKYBUTTON : IMG_EDITOR_CHECKBOX); struct GraphicInfo *gd = &graphic_info[graphic]; @@ -7027,6 +9106,10 @@ static void CreateCheckbuttonGadgets(void) int gd_y2a = gd->src_y + gd->active_yoffset + gd->pressed_yoffset; int x = SX + ED_SETTINGS_X(checkbutton_info[i].x); int y = SY + ED_SETTINGS_Y(checkbutton_info[i].y); + unsigned int event_mask = GD_EVENT_PRESSED; + + if (type_id != i) + Fail("'checkbutton_info' structure corrupted at index %d -- please fix", i); // determine horizontal position to the right of specified gadget if (checkbutton_info[i].gadget_id_align != GADGET_ID_NONE) @@ -7038,7 +9121,7 @@ static void CreateCheckbuttonGadgets(void) x += getTextWidthForGadget(checkbutton_info[i].text_left); gi = CreateGadget(GDI_CUSTOM_ID, id, - GDI_CUSTOM_TYPE_ID, i, + GDI_CUSTOM_TYPE_ID, type_id, GDI_IMAGE_ID, graphic, GDI_INFO_TEXT, checkbutton_info[i].infotext, GDI_X, x, @@ -7057,7 +9140,7 @@ static void CreateCheckbuttonGadgets(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; right_gadget_border[id] = @@ -7078,16 +9161,18 @@ static void CreateRadiobuttonGadgets(void) int gd_x2a = gd->src_x + gd->active_xoffset + gd->pressed_xoffset; int gd_y2a = gd->src_y + gd->active_yoffset + gd->pressed_yoffset; struct GadgetInfo *gi; - unsigned int event_mask; int i; - event_mask = GD_EVENT_PRESSED; - for (i = 0; i < ED_NUM_RADIOBUTTONS; i++) { int id = radiobutton_info[i].gadget_id; + int type_id = radiobutton_info[i].gadget_type_id; int x = SX + ED_SETTINGS_X(radiobutton_info[i].x); int y = SY + ED_SETTINGS_Y(radiobutton_info[i].y); + unsigned int event_mask = GD_EVENT_PRESSED; + + if (type_id != i) + Fail("'radiobutton_info' structure corrupted at index %d -- please fix", i); int checked = (*radiobutton_info[i].value == radiobutton_info[i].checked_value); @@ -7102,7 +9187,7 @@ static void CreateRadiobuttonGadgets(void) x += getTextWidthForGadget(radiobutton_info[i].text_left); gi = CreateGadget(GDI_CUSTOM_ID, id, - GDI_CUSTOM_TYPE_ID, i, + GDI_CUSTOM_TYPE_ID, type_id, GDI_IMAGE_ID, graphic, GDI_INFO_TEXT, radiobutton_info[i].infotext, GDI_X, x, @@ -7122,7 +9207,7 @@ static void CreateRadiobuttonGadgets(void) GDI_END); if (gi == NULL) - Error(ERR_EXIT, "cannot create gadget"); + Fail("cannot create gadget"); level_editor_gadget[id] = gi; right_gadget_border[id] = @@ -7141,7 +9226,7 @@ void CreateLevelEditorGadgets(void) num_editor_gadgets = NUM_EDITOR_GADGETS; - // printf("::: allocating %d gadgets ...\n", num_editor_gadgets); + // Debug("editor", "allocating %d gadgets ...\n", num_editor_gadgets); level_editor_gadget = checked_calloc(num_editor_gadgets * sizeof(struct GadgetInfo *)); @@ -7156,6 +9241,8 @@ void CreateLevelEditorGadgets(void) use_permanent_palette = !editor.palette.show_as_separate_screen; + InitGadgetScreenBorders(-1, INFOTEXT_YPOS); + ReinitializeElementList(); CreateControlButtons(); @@ -7179,7 +9266,7 @@ void FreeLevelEditorGadgets(void) { int i; - // printf("::: freeing %d gadgets ...\n", num_editor_gadgets); + // Debug("editor", "freeing %d gadgets ...\n", num_editor_gadgets); for (i = 0; i < num_editor_gadgets; i++) { @@ -7223,16 +9310,12 @@ static void MapCounterButtons(int id) ModifyEditorCounterValue(id, *counterbutton_info[id].value); - // set position for "value[1,2,3,4]" counter gadgets (score in most cases) - if (id >= ED_COUNTER_ID_ELEMENT_VALUE1 && - id <= ED_COUNTER_ID_ELEMENT_VALUE4) + // set position for counter gadgets with dynamically determined position + if (id != ED_COUNTER_ID_SELECT_LEVEL) { - ModifyGadget(gi_down, GDI_Y, - SY + ED_SETTINGS_Y(counterbutton_info[id].y), GDI_END); - ModifyGadget(gi_text, GDI_Y, - SY + ED_SETTINGS_Y(counterbutton_info[id].y), GDI_END); - ModifyGadget(gi_up, GDI_Y, - SY + ED_SETTINGS_Y(counterbutton_info[id].y), GDI_END); + ModifyGadget(gi_down, GDI_Y, SY + ED_SETTINGS_Y(counterbutton_info[id].y), GDI_END); + ModifyGadget(gi_text, GDI_Y, SY + ED_SETTINGS_Y(counterbutton_info[id].y), GDI_END); + ModifyGadget(gi_up, GDI_Y, SY + ED_SETTINGS_Y(counterbutton_info[id].y), GDI_END); } // vertical position might have changed after setting position above @@ -7291,10 +9374,12 @@ static void MapDrawingArea(int id) int area_ysize = gi->drawing.area_ysize; int xoffset_left = getTextWidthForDrawingArea(drawingarea_info[id].text_left); int xoffset_below = getTextWidth(drawingarea_info[id].text_below, font_nr); - int x_left = gi->x - xoffset_left; + int x_left = gi->x - xoffset_left - ED_DRAWINGAREA_BORDER_SIZE; int x_right = gi->x + gi->width + ED_DRAWINGAREA_TEXT_DISTANCE; + int x_above = gi->x - ED_DRAWINGAREA_BORDER_SIZE; int x_below = gi->x + (gi->width - xoffset_below) / 2; int y_side = gi->y + (gi->height - font_height) / 2; + int y_above = gi->y - font_height - ED_DRAWINGAREA_TEXT_DISTANCE; int y_below = gi->y + gi->height + ED_DRAWINGAREA_TEXT_DISTANCE; if (drawingarea_info[id].text_left) @@ -7303,6 +9388,9 @@ static void MapDrawingArea(int id) if (drawingarea_info[id].text_right) DrawText(x_right, y_side, drawingarea_info[id].text_right, font_nr); + if (drawingarea_info[id].text_above) + DrawText(x_above, y_above, drawingarea_info[id].text_above, font_nr); + if (drawingarea_info[id].text_below) DrawText(x_below, y_below, drawingarea_info[id].text_below, font_nr); @@ -7323,12 +9411,23 @@ static void MapTextInputGadget(int id) int font_nr = FONT_TEXT_1; int font_height = getFontHeight(font_nr); struct GadgetInfo *gi = level_editor_gadget[textinput_info[id].gadget_id]; + int xoffset_left = getTextWidthForGadget(textinput_info[id].text_left); + int xoffset_right = ED_GADGET_TEXT_DISTANCE; int yoffset_above = font_height + ED_GADGET_LINE_DISTANCE; - int x_above = ED_SETTINGS_X(textinput_info[id].x); - int y_above = ED_SETTINGS_Y(textinput_info[id].y) - yoffset_above; + int yoffset = (gi->height - font_height) / 2; + int x_left = gi->x - xoffset_left; + int x_right = gi->x + gi->width + xoffset_right; + int y_above = gi->y - yoffset_above; + int y = gi->y + yoffset; if (textinput_info[id].text_above) - DrawTextS(x_above, y_above, font_nr, textinput_info[id].text_above); + DrawText(x_left, y_above, textinput_info[id].text_above, font_nr); + + if (textinput_info[id].text_left) + DrawText(x_left, y, textinput_info[id].text_left, font_nr); + + if (textinput_info[id].text_right) + DrawText(x_right, y, textinput_info[id].text_right, font_nr); ModifyGadget(gi, GDI_TEXT_VALUE, textinput_info[id].value, GDI_END); @@ -7343,9 +9442,13 @@ static void MapTextAreaGadget(int id) int yoffset_above = font_height + ED_GADGET_LINE_DISTANCE; int x_above = ED_SETTINGS_X(textarea_info[id].x); int y_above = ED_SETTINGS_Y(textarea_info[id].y) - yoffset_above; + char *text_above = textarea_info[id].text_above; - if (textarea_info[id].text_above) - DrawTextS(x_above, y_above, font_nr, textarea_info[id].text_above); + if (gi->textarea.cropped && textarea_info[id].text_above_cropped) + text_above = textarea_info[id].text_above_cropped; + + if (text_above) + DrawTextS(x_above, y_above, font_nr, text_above); ModifyGadget(gi, GDI_TEXT_VALUE, textarea_info[id].value, GDI_END); @@ -7364,11 +9467,10 @@ static void MapSelectboxGadget(int id) int x_left = gi->x - xoffset_left; int x_right = gi->x + gi->width + xoffset_right; int y_above = gi->y - yoffset_above; - int x = gi->x; int y = gi->y + yoffset; if (selectbox_info[id].text_above) - DrawText(x, y_above, selectbox_info[id].text_above, font_nr); + DrawText(x_left, y_above, selectbox_info[id].text_above, font_nr); if (selectbox_info[id].text_left) DrawText(x_left, y, selectbox_info[id].text_left, font_nr); @@ -7417,7 +9519,7 @@ static void MapGraphicbuttonGadget(int id) { int font_nr = FONT_TEXT_1; int font_height = getFontHeight(font_nr); - struct GadgetInfo *gi= level_editor_gadget[graphicbutton_info[id].gadget_id]; + struct GadgetInfo *gi = level_editor_gadget[graphicbutton_info[id].gadget_id]; int xoffset_left = getTextWidthForGadget(graphicbutton_info[id].text_left); int xoffset_right = ED_GADGET_TEXT_DISTANCE; int yoffset = (gi->height - font_height) / 2; @@ -7474,7 +9576,7 @@ static void MapCheckbuttonGadget(int id) // set position for gadgets with dynamically determined position if (checkbutton_info[id].x != -1) // do not change dynamic positions - ModifyGadget(gi, GDI_X, SX + ED_SETTINGS_X(checkbutton_info[id].x),GDI_END); + ModifyGadget(gi, GDI_X, SX + ED_SETTINGS_X(checkbutton_info[id].x), GDI_END); ModifyGadget(gi, GDI_Y, SY + ED_SETTINGS_Y(checkbutton_info[id].y), GDI_END); x_left = gi->x - xoffset_left; @@ -7507,7 +9609,7 @@ static void MapMainDrawingArea(void) no_vertical_scrollbar = (lev_fieldy <= ed_fieldy); } - 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) && @@ -7557,6 +9659,14 @@ static void MapLevelEditorToolboxCustomGadgets(void) MapOrUnmapLevelEditorToolboxCustomGadgets(TRUE); } +static void MapLevelEditorToolboxCustomGadgetsIfNeeded(void) +{ + if (IS_CUSTOM_ELEMENT(properties_element) || + IS_GROUP_ELEMENT(properties_element) || + IS_EMPTY_ELEMENT(properties_element)) + MapLevelEditorToolboxCustomGadgets(); +} + static void UnmapLevelEditorToolboxCustomGadgets(void) { MapOrUnmapLevelEditorToolboxCustomGadgets(FALSE); @@ -7645,8 +9755,8 @@ static void DrawEditModeWindowExt(boolean remap_toolbox_gadgets) RedrawDrawingElements(); } - if (edit_mode == ED_MODE_INFO) - DrawLevelInfoWindow(); + if (edit_mode == ED_MODE_LEVELCONFIG) + DrawLevelConfigWindow(); else if (edit_mode == ED_MODE_PROPERTIES) DrawPropertiesWindow(); else if (edit_mode == ED_MODE_PALETTE) @@ -7679,7 +9789,7 @@ static boolean LevelChanged(void) for (y = 0; y < lev_fieldy; y++) for (x = 0; x < lev_fieldx; x++) - if (Feld[x][y] != level.field[x][y]) + if (Tile[x][y] != level.field[x][y]) field_changed = TRUE; return (level.changed || field_changed); @@ -7707,7 +9817,7 @@ static boolean PrepareSavingIntoPersonalLevelSet(void) return TRUE; } - if (!Request("This level is read only! " + if (!Request("This level is read-only! " "Save into personal level set?", REQ_ASK)) return FALSE; @@ -7715,6 +9825,17 @@ static boolean PrepareSavingIntoPersonalLevelSet(void) leveldir_current = getTreeInfoFromIdentifier(leveldir_first, getLoginName()); + // this may happen if "setup.internal.create_user_levelset" is FALSE + // or if file "levelinfo.conf" is missing in personal user level set + if (leveldir_current == NULL) + { + Request("Cannot find personal level set?!", REQ_CONFIRM); + + leveldir_current = leveldir_former; + + return FALSE; + } + // find unused level number for (new_level_nr = leveldir_current->first_level; ; new_level_nr++) { @@ -7735,7 +9856,7 @@ static boolean PrepareSavingIntoPersonalLevelSet(void) return TRUE; } -static void ModifyLevelInfoForSavingIntoPersonalLevelSet(char *former_name) +static void ModifyLevelConfigForSavingIntoPersonalLevelSet(char *former_name) { static char *filename_levelinfo = NULL, *mod_name = NULL; FILE *file; @@ -7933,8 +10054,8 @@ static void replace_custom_element_in_playfield(int element_from, 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; + if (Tile[x][y] == element_from) + Tile[x][y] = element_to; } static boolean CopyCustomElement(int element_old, int element_new, @@ -7968,6 +10089,12 @@ static boolean CopyCustomElement(int element_old, int element_new, return FALSE; } + else if (IS_EMPTY_ELEMENT(element_old) && !IS_EMPTY_ELEMENT(element_new)) + { + Request("Please choose empty element!", REQ_CONFIRM); + + return FALSE; + } else { level.changed = TRUE; @@ -8110,7 +10237,8 @@ static void CopyCustomElementPropertiesToEditor(int element) // set "change by direct action" selectbox help value custom_element_change.direct_action = - (HAS_CHANGE_EVENT(element, CE_TOUCHED_BY_PLAYER) ? CE_TOUCHED_BY_PLAYER : + (HAS_CHANGE_EVENT(element, CE_NEXT_TO_PLAYER) ? CE_NEXT_TO_PLAYER : + HAS_CHANGE_EVENT(element, CE_TOUCHED_BY_PLAYER) ? CE_TOUCHED_BY_PLAYER : HAS_CHANGE_EVENT(element, CE_PRESSED_BY_PLAYER) ? CE_PRESSED_BY_PLAYER : HAS_CHANGE_EVENT(element, CE_SWITCHED_BY_PLAYER) ? CE_SWITCHED_BY_PLAYER : HAS_CHANGE_EVENT(element, CE_SNAPPED_BY_PLAYER) ? CE_SNAPPED_BY_PLAYER : @@ -8128,11 +10256,14 @@ static void CopyCustomElementPropertiesToEditor(int element) HAS_CHANGE_EVENT(element, CE_SCORE_CHANGES) ? CE_SCORE_CHANGES : HAS_CHANGE_EVENT(element, CE_VALUE_GETS_ZERO) ? CE_VALUE_GETS_ZERO : HAS_CHANGE_EVENT(element, CE_SCORE_GETS_ZERO) ? CE_SCORE_GETS_ZERO : + HAS_CHANGE_EVENT(element, CE_CLICKED_BY_MOUSE) ? CE_CLICKED_BY_MOUSE : + HAS_CHANGE_EVENT(element, CE_PRESSED_BY_MOUSE) ? CE_PRESSED_BY_MOUSE : custom_element_change.direct_action); // set "change by other element action" selectbox help value custom_element_change.other_action = - (HAS_CHANGE_EVENT(element, CE_PLAYER_TOUCHES_X) ? CE_PLAYER_TOUCHES_X : + (HAS_CHANGE_EVENT(element, CE_PLAYER_NEXT_TO_X) ? CE_PLAYER_NEXT_TO_X : + HAS_CHANGE_EVENT(element, CE_PLAYER_TOUCHES_X) ? CE_PLAYER_TOUCHES_X : HAS_CHANGE_EVENT(element, CE_PLAYER_PRESSES_X) ? CE_PLAYER_PRESSES_X : HAS_CHANGE_EVENT(element, CE_PLAYER_SWITCHES_X) ? CE_PLAYER_SWITCHES_X : HAS_CHANGE_EVENT(element, CE_PLAYER_SNAPS_X) ? CE_PLAYER_SNAPS_X : @@ -8142,6 +10273,7 @@ static void CopyCustomElementPropertiesToEditor(int element) HAS_CHANGE_EVENT(element, CE_PLAYER_DIGS_X) ? CE_PLAYER_DIGS_X : HAS_CHANGE_EVENT(element, CE_PLAYER_COLLECTS_X) ? CE_PLAYER_COLLECTS_X : HAS_CHANGE_EVENT(element, CE_PLAYER_DROPS_X) ? CE_PLAYER_DROPS_X : + HAS_CHANGE_EVENT(element, CE_NEXT_TO_X) ? CE_NEXT_TO_X : HAS_CHANGE_EVENT(element, CE_TOUCHING_X) ? CE_TOUCHING_X : HAS_CHANGE_EVENT(element, CE_HITTING_X) ? CE_HITTING_X : HAS_CHANGE_EVENT(element, CE_DIGGING_X) ? CE_DIGGING_X : @@ -8155,6 +10287,8 @@ static void CopyCustomElementPropertiesToEditor(int element) HAS_CHANGE_EVENT(element, CE_SCORE_CHANGES_OF_X) ? CE_SCORE_CHANGES_OF_X : HAS_CHANGE_EVENT(element, CE_VALUE_GETS_ZERO_OF_X) ? CE_VALUE_GETS_ZERO_OF_X : HAS_CHANGE_EVENT(element, CE_SCORE_GETS_ZERO_OF_X) ? CE_SCORE_GETS_ZERO_OF_X : + HAS_CHANGE_EVENT(element, CE_MOUSE_CLICKED_ON_X) ? CE_MOUSE_CLICKED_ON_X : + HAS_CHANGE_EVENT(element, CE_MOUSE_PRESSED_ON_X) ? CE_MOUSE_PRESSED_ON_X : custom_element_change.other_action); } @@ -8164,9 +10298,14 @@ static void CopyGroupElementPropertiesToEditor(int element) custom_element = element_info[element]; // needed for description } +static void CopyEmptyElementPropertiesToEditor(int element) +{ + custom_element = element_info[element]; +} + static void CopyClassicElementPropertiesToEditor(int element) { - if (ELEM_IS_PLAYER(element) || COULD_MOVE_INTO_ACID(element)) + if (IS_PLAYER_ELEMENT(element) || COULD_MOVE_INTO_ACID(element)) custom_element_properties[EP_CAN_MOVE_INTO_ACID] = getMoveIntoAcidProperty(&level, element); @@ -8181,6 +10320,8 @@ static void CopyElementPropertiesToEditor(int element) CopyCustomElementPropertiesToEditor(element); else if (IS_GROUP_ELEMENT(element)) CopyGroupElementPropertiesToEditor(element); + else if (IS_EMPTY_ELEMENT(element)) + CopyEmptyElementPropertiesToEditor(element); else CopyClassicElementPropertiesToEditor(element); } @@ -8268,6 +10409,7 @@ static void CopyCustomElementPropertiesToGame(int element) // ---------- element settings: advanced (custom elements) ------------------ // set player change event from checkbox and selectbox + custom_element_change_events[CE_NEXT_TO_PLAYER] = FALSE; custom_element_change_events[CE_TOUCHED_BY_PLAYER] = FALSE; custom_element_change_events[CE_PRESSED_BY_PLAYER] = FALSE; custom_element_change_events[CE_SWITCHED_BY_PLAYER] = FALSE; @@ -8286,10 +10428,13 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_change_events[CE_SCORE_CHANGES] = FALSE; custom_element_change_events[CE_VALUE_GETS_ZERO] = FALSE; custom_element_change_events[CE_SCORE_GETS_ZERO] = FALSE; + custom_element_change_events[CE_CLICKED_BY_MOUSE] = FALSE; + custom_element_change_events[CE_PRESSED_BY_MOUSE] = FALSE; custom_element_change_events[custom_element_change.direct_action] = custom_element_change_events[CE_BY_DIRECT_ACTION]; // set other element action change event from checkbox and selectbox + custom_element_change_events[CE_PLAYER_NEXT_TO_X] = FALSE; custom_element_change_events[CE_PLAYER_TOUCHES_X] = FALSE; custom_element_change_events[CE_PLAYER_PRESSES_X] = FALSE; custom_element_change_events[CE_PLAYER_SWITCHES_X] = FALSE; @@ -8300,6 +10445,7 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_change_events[CE_PLAYER_DIGS_X] = FALSE; custom_element_change_events[CE_PLAYER_COLLECTS_X] = FALSE; custom_element_change_events[CE_PLAYER_DROPS_X] = FALSE; + custom_element_change_events[CE_NEXT_TO_X] = FALSE; custom_element_change_events[CE_TOUCHING_X] = FALSE; custom_element_change_events[CE_HITTING_X] = FALSE; custom_element_change_events[CE_DIGGING_X] = FALSE; @@ -8313,6 +10459,8 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_change_events[CE_SCORE_CHANGES_OF_X] = FALSE; custom_element_change_events[CE_VALUE_GETS_ZERO_OF_X] = FALSE; custom_element_change_events[CE_SCORE_GETS_ZERO_OF_X] = FALSE; + custom_element_change_events[CE_MOUSE_CLICKED_ON_X] = FALSE; + custom_element_change_events[CE_MOUSE_PRESSED_ON_X] = FALSE; custom_element_change_events[custom_element_change.other_action] = custom_element_change_events[CE_BY_OTHER_ACTION]; @@ -8325,6 +10473,9 @@ static void CopyCustomElementPropertiesToGame(int element) // copy change events also to special level editor variable custom_element = element_info[element]; custom_element_change = *element_info[element].change; + + // needed here to restore runtime value "element_info[element].gfx_element" + InitElementPropertiesGfxElement(); } static void CopyGroupElementPropertiesToGame(int element) @@ -8338,11 +10489,29 @@ static void CopyGroupElementPropertiesToGame(int element) element_info[element] = custom_element; *element_info[element].group = group_element_info; + + // needed here to restore runtime value "element_info[element].gfx_element" + InitElementPropertiesGfxElement(); +} + +static void CopyEmptyElementPropertiesToGame(int element) +{ + // mark that this empty element has been modified + custom_element.modified_settings = TRUE; + level.changed = TRUE; + + if (level.use_custom_template) + AskToCopyAndModifyLevelTemplate(); + + element_info[element] = custom_element; + + // needed here to restore runtime value "element_info[element].gfx_element" + InitElementPropertiesGfxElement(); } static void CopyClassicElementPropertiesToGame(int element) { - if (ELEM_IS_PLAYER(element) || COULD_MOVE_INTO_ACID(element)) + if (IS_PLAYER_ELEMENT(element) || COULD_MOVE_INTO_ACID(element)) setMoveIntoAcidProperty(&level, element, custom_element_properties[EP_CAN_MOVE_INTO_ACID]); @@ -8357,6 +10526,8 @@ static void CopyElementPropertiesToGame(int element) CopyCustomElementPropertiesToGame(element); else if (IS_GROUP_ELEMENT(element)) CopyGroupElementPropertiesToGame(element); + else if (IS_EMPTY_ELEMENT(element)) + CopyEmptyElementPropertiesToGame(element); else CopyClassicElementPropertiesToGame(element); } @@ -8368,8 +10539,7 @@ static void CheckElementDescriptions(void) for (i = 0; i < NUM_FILE_ELEMENTS; i++) if (getElementDescriptionFilename(i) == NULL && !IS_OBSOLETE(i)) - Error(ERR_WARN, "no element description file for element '%s'", - EL_NAME(i)); + Warn("no element description file for element '%s'", EL_NAME(i)); } #endif @@ -8402,6 +10572,9 @@ static void InitZoomLevelSettings(int zoom_tilesize) ed_tilesize = setup.auto_setup.editor_zoom_tilesize; ed_tilesize_default = DEFAULT_EDITOR_TILESIZE; + // make sure that tile size is always a power of 2 + ed_tilesize = (1 << log_2(ed_tilesize)); + if (level.game_engine_type == GAME_ENGINE_TYPE_MM) { ed_tilesize = DEFAULT_EDITOR_TILESIZE_MM; @@ -8429,24 +10602,10 @@ static void InitDrawingElements(void) if (level.game_engine_type == game_engine_type_last) return; - if (level.game_engine_type == GAME_ENGINE_TYPE_SP) - { - new_element1 = EL_SP_CHIP_SINGLE; - new_element2 = EL_EMPTY; - new_element3 = EL_SP_BASE; - } - else if (level.game_engine_type == GAME_ENGINE_TYPE_MM) - { - new_element1 = EL_MM_MIRROR_START; - new_element2 = EL_EMPTY; - new_element3 = EL_MM_WOODEN_WALL; - } - else - { - new_element1 = EL_WALL; - new_element2 = EL_EMPTY; - new_element3 = EL_SAND; - } + // select drawing elements according to game engine type + new_element1 = getDrawingElement(EL_WALL); + new_element2 = getDrawingElement(EL_EMPTY); + new_element3 = getDrawingElement(EL_SAND); game_engine_type_last = level.game_engine_type; } @@ -8532,6 +10691,15 @@ static void DrawEditorDoorContent(void) // draw all toolbox gadgets to editor doors MapControlButtons(); + // when returning from test game to properties page, redraw toolbox gadgets + if (edit_mode == ED_MODE_PROPERTIES) + { + UnmapLevelEditorToolboxDrawingGadgets(); + UnmapLevelEditorToolboxCustomGadgets(); + + MapLevelEditorToolboxCustomGadgetsIfNeeded(); + } + // draw all palette gadgets to editor doors ModifyEditorElementList(); RedrawDrawingElements(); @@ -8566,15 +10734,16 @@ void DrawLevelEd(void) if (level_editor_test_game) { - CopyPlayfield(level.field, Feld); - CopyPlayfield(FieldBackup, level.field); + CopyPlayfield(level.field, Tile); + CopyPlayfield(TileBackup, level.field); level_editor_test_game = FALSE; } else { edit_mode = ED_MODE_DRAWING; - edit_mode_levelinfo = ED_MODE_LEVELINFO_LEVEL; + edit_mode_levelconfig = ED_MODE_LEVELCONFIG_LEVEL; + edit_mode_engineconfig = ED_MODE_ENGINECONFIG_CONFIG; edit_mode_properties = ED_MODE_PROPERTIES_INFO; ResetUndoBuffer(); @@ -8630,8 +10799,8 @@ static void AdjustDrawingAreaGadgets(void) if (suppressBorderElement()) { - ed_xsize = max_ed_fieldx; - ed_ysize = max_ed_fieldy; + ed_xsize = lev_fieldx; + ed_ysize = lev_fieldy; } // check if we need any scrollbars @@ -8957,7 +11126,7 @@ static int getTabulatorBarHeight(void) static Pixel getTabulatorBarColor(void) { - struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_LEVELINFO_LEVEL]; + struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_LEVELCONFIG_LEVEL]; struct GadgetDesign *gd = &gd_gi1->alt_design[GD_BUTTON_UNPRESSED]; int gd_x = gd->x + gd_gi1->border.width / 2; int gd_y = gd->y + gd_gi1->height - 1; @@ -8965,19 +11134,56 @@ static Pixel getTabulatorBarColor(void) return GetPixel(gd->bitmap, gd_x, gd_y); } -static void DrawLevelInfoTabulatorGadgets(void) +static void DrawEngineConfigTabulatorGadgets(void) +{ + struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_ENGINECONFIG_CONFIG]; + Pixel tab_color = getTabulatorBarColor(); + int id_first = ED_TEXTBUTTON_ID_ENGINECONFIG_CONFIG; + int id_last = ED_TEXTBUTTON_ID_ENGINECONFIG_COLORS; + int 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]; + boolean active = (i != edit_mode_engineconfig); + + // draw background line below tabulator button + ClearRectangleOnBackground(drawto, gi->x, gi->y + gi->height, gi->width, 1); + + // draw solid line below inactive tabulator buttons + if (!active && tab_color != BLACK_PIXEL) // black => transparent + FillRectangle(drawto, gi->x, gi->y + gi->height, gi->width, + ED_GADGET_TINY_DISTANCE, tab_color); + + ModifyGadget(gi, GDI_ACTIVE, active, GDI_END); + MapTextbuttonGadget(i); + } + + // draw little border line below tabulator buttons + if (tab_color != BLACK_PIXEL) // black => transparent + FillRectangle(drawto, gd_gi1->x, gd_gi1->y + gd_gi1->height + + ED_GADGET_TINY_DISTANCE, + getTabulatorBarWidth(), getTabulatorBarHeight(), tab_color); +} + +static void DrawLevelConfigTabulatorGadgets(void) { - struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_LEVELINFO_LEVEL]; + struct GadgetInfo *gd_gi1 = level_editor_gadget[GADGET_ID_LEVELCONFIG_LEVEL]; Pixel tab_color = getTabulatorBarColor(); - int id_first = ED_TAB_BUTTON_ID_LEVELINFO_FIRST; - int id_last = ED_TAB_BUTTON_ID_LEVELINFO_LAST; + int id_first = ED_TEXTBUTTON_ID_LEVELCONFIG_LEVEL; + int id_last = ED_TEXTBUTTON_ID_LEVELCONFIG_EDITOR; int i; + // draw additional "engine" tabulator when using native BD engine + if (level.game_engine_type == GAME_ENGINE_TYPE_BD) + id_last = ED_TEXTBUTTON_ID_LEVELCONFIG_ENGINE; + for (i = id_first; i <= id_last; i++) { int gadget_id = textbutton_info[i].gadget_id; struct GadgetInfo *gi = level_editor_gadget[gadget_id]; - boolean active = (i != edit_mode_levelinfo); + boolean active = (i != edit_mode_levelconfig); // draw background line below tabulator button ClearRectangleOnBackground(drawto, gi->x, gi->y + gi->height, gi->width, 1); @@ -8996,6 +11202,10 @@ static void DrawLevelInfoTabulatorGadgets(void) FillRectangle(drawto, gd_gi1->x, gd_gi1->y + gd_gi1->height + ED_GADGET_TINY_DISTANCE, getTabulatorBarWidth(), getTabulatorBarHeight(), tab_color); + + // draw second row of engine related tabulators when using native BD engine + if (edit_mode_levelconfig == ED_MODE_LEVELCONFIG_ENGINE) + DrawEngineConfigTabulatorGadgets(); } static void DrawPropertiesTabulatorGadgets(void) @@ -9010,7 +11220,7 @@ static void DrawPropertiesTabulatorGadgets(void) int i; // draw two config tabulators for player elements - if (ELEM_IS_PLAYER(properties_element)) + if (IS_PLAYER_ELEMENT(properties_element)) id_last = ED_TEXTBUTTON_ID_PROPERTIES_CONFIG_2; // draw two config and one "change" tabulator for custom elements @@ -9025,7 +11235,7 @@ static void DrawPropertiesTabulatorGadgets(void) // use "config 1" and "config 2" instead of "config" for players and CEs if (i == ED_TEXTBUTTON_ID_PROPERTIES_CONFIG && - (ELEM_IS_PLAYER(properties_element) || + (IS_PLAYER_ELEMENT(properties_element) || IS_CUSTOM_ELEMENT(properties_element))) continue; @@ -9066,7 +11276,7 @@ static int PrintElementDescriptionFromFile(char *filename, int font_nr, TRUE, FALSE, FALSE); } -static void DrawLevelInfoLevel(void) +static void DrawLevelConfigLevel(void) { int i; @@ -9095,7 +11305,7 @@ static char *getLevelSubdirFromSaveMode(int save_mode) return leveldir_current->subdir; } -static void DrawLevelInfoLevelSet_DirectoryInfo(void) +static void DrawLevelConfigLevelSet_DirectoryInfo(void) { char *directory_text = "Level set directory:"; char *directory_name = getLevelSubdirFromSaveMode(levelset_save_mode); @@ -9110,7 +11320,7 @@ static void DrawLevelInfoLevelSet_DirectoryInfo(void) PrintInfoText(directory_name, font2_nr, x, y); } -static void DrawLevelInfoLevelSet(void) +static void DrawLevelConfigLevelSet(void) { boolean artwork_exists = checkIfCustomArtworkExistsForCurrentLevelSet(); boolean template_exists = fileExists(getLocalLevelTemplateFilename()); @@ -9143,10 +11353,10 @@ static void DrawLevelInfoLevelSet(void) MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_LEVELSET); // draw info text - DrawLevelInfoLevelSet_DirectoryInfo(); + DrawLevelConfigLevelSet_DirectoryInfo(); } -static void DrawLevelInfoEditor(void) +static void DrawLevelConfigEditor(void) { int i; @@ -9155,11 +11365,11 @@ static void DrawLevelInfoEditor(void) MapCounterButtons(i); // draw checkbutton gadgets - for (i=ED_CHECKBUTTON_ID_EDITOR_FIRST; i<= ED_CHECKBUTTON_ID_EDITOR_LAST; i++) + for (i = ED_CHECKBUTTON_ID_EDITOR_FIRST; i <= ED_CHECKBUTTON_ID_EDITOR_LAST; i++) MapCheckbuttonGadget(i); // draw radiobutton gadgets - for (i=ED_RADIOBUTTON_ID_EDITOR_FIRST; i<= ED_RADIOBUTTON_ID_EDITOR_LAST; i++) + for (i = ED_RADIOBUTTON_ID_EDITOR_FIRST; i <= ED_RADIOBUTTON_ID_EDITOR_LAST; i++) MapRadiobuttonGadget(i); // draw drawing area @@ -9169,7 +11379,171 @@ static void DrawLevelInfoEditor(void) MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_2); } -static void DrawLevelInfoWindow(void) +static void DrawEngineConfigConfig(void) +{ + int i; + + // draw counter gadgets + if (level.bd_scheduling_type == GD_SCHEDULING_MILLISECONDS) + { + MapCounterButtons(ED_COUNTER_ID_BD_CYCLE_DELAY_MS); + MapCounterButtons(ED_COUNTER_ID_BD_HATCHING_DELAY_CYCLES); + } + else + { + MapCounterButtons(ED_COUNTER_ID_BD_CYCLE_DELAY_C64); + MapCounterButtons(ED_COUNTER_ID_BD_HATCHING_DELAY_SECONDS); + } + + // draw checkbutton gadgets + for (i = ED_CHECKBUTTON_ID_ENGINE_FIRST; i <= ED_CHECKBUTTON_ID_ENGINE_LAST; i++) + MapCheckbuttonGadget(i); + + // draw selectbox gadgets + for (i = ED_SELECTBOX_ID_ENGINE_FIRST; i <= ED_SELECTBOX_ID_ENGINE_LAST; i++) + MapSelectboxGadget(i); +} + +static int GetCommonColorType_BD(void) +{ + int bd_color_type = *bd_color[0] >> 24; + int i; + + // check if all colors have the same color type + for (i = 1; i < MAX_BD_COLORS; i++) + if ((*bd_color[i] >> 24) != bd_color_type) + return GD_COLOR_TYPE_RGB; + + return bd_color_type; +} + +void SetDefaultLevelColorType_BD(void) +{ + bd_color_type_default = GetCommonColorType_BD(); + + level.bd_color_type = bd_color_type_default; +} + +void SetDefaultLevelColors_BD(void) +{ + int i; + + for (i = 0; i < MAX_BD_COLORS; i++) + bd_color_default[i] = *bd_color[i]; +} + +void SetRandomLevelColors_BD(int bd_color_type) +{ + struct LevelInfo_BD *level_bd = level.native_bd_level; + GdCave *cave = level_bd->cave; + + // create random cave colors + gd_cave_set_random_colors(cave, bd_color_type); + + // copy colors to level editor + level.bd_color_b = cave->colorb; + level.bd_color_0 = cave->color0; + level.bd_color_1 = cave->color1; + level.bd_color_2 = cave->color2; + level.bd_color_3 = cave->color3; + level.bd_color_4 = cave->color4; + level.bd_color_5 = cave->color5; +} + +static void DrawColorBox_BD(int nr) +{ + int id = ED_SELECTBOX_ID_COLORS_FIRST + nr; + struct GadgetInfo *gi = level_editor_gadget[selectbox_info[id].gadget_id]; + int graphic = IMG_EDITOR_CHECKBOX; + struct GraphicInfo *gd = &graphic_info[graphic]; + int offset = ED_GADGET_TEXT_DISTANCE; + int x1 = gi->x - offset - gd->width; + int y1 = gi->y; + int x2 = x1 + offset; + int y2 = y1 + offset; + int xsize1 = gd->width; + int ysize1 = gd->height; + int xsize2 = xsize1 - 2 * offset; + int ysize2 = ysize1 - 2 * offset; + int bd_color_x = *bd_color[nr]; + int r = gd_color_get_r(bd_color_x); + int g = gd_color_get_g(bd_color_x); + int b = gd_color_get_b(bd_color_x); + Pixel color = SDL_MapRGB(drawto->surface->format, r, g, b); + + BlitBitmap(gd->bitmap, drawto, gd->src_x, gd->src_y, xsize1, ysize1, x1, y1); + FillRectangle(drawto, x2, y2, xsize2, ysize2, color); +} + +static void DrawEngineConfigColors(void) +{ + int i; + + if (bd_color_type_changed) + { + if (level.bd_color_type != GD_COLOR_TYPE_RGB && level.bd_color_type != GetCommonColorType_BD()) + { + // color type switched to non-RGB colors, but using different color type => reset colors + + if (level.bd_color_type == bd_color_type_default) + { + // color type switched to same color type as default colors => reset to defaults + for (i = 0; i < MAX_BD_COLORS; i++) + *bd_color[i] = bd_color_default[i]; + } + else + { + // color type switched to different color type as default colors => use random colors + SetRandomLevelColors_BD(level.bd_color_type); + } + } + + bd_color_type_changed = FALSE; + } + + // copy level colors to either C64-style color index or color text + for (i = 0; i < MAX_BD_COLORS; i++) + { + int bd_color_x = (level.bd_color_type == GD_COLOR_TYPE_C64 ? *bd_color[i] & 0x0f : + level.bd_color_type == GD_COLOR_TYPE_RGB ? gd_color_get_rgb(*bd_color[i]) : + *bd_color[i]); + + if (level.bd_color_type == GD_COLOR_TYPE_C64) + bd_color_c64[i] = bd_color_x; + else + snprintf(bd_color_text[i], sizeof(bd_color_text[i]), "%s", gd_color_get_string(bd_color_x)); + } + + MapSelectboxGadget(ED_SELECTBOX_ID_BD_COLOR_TYPE); + + if (level.bd_color_type == GD_COLOR_TYPE_C64) + { + // draw selectbox gadgets + for (i = ED_SELECTBOX_ID_COLORS_FIRST; i <= ED_SELECTBOX_ID_COLORS_LAST; i++) + MapSelectboxGadget(i); + } + else + { + // draw text input gadgets + for (i = ED_TEXTINPUT_ID_COLORS_FIRST; i <= ED_TEXTINPUT_ID_COLORS_LAST; i++) + MapTextInputGadget(i); + } + + for (i = 0; i < MAX_BD_COLORS; i++) + DrawColorBox_BD(i); + + MapTextbuttonGadget(ED_TEXTBUTTON_ID_BD_SET_RANDOM_COLORS); +} + +static void DrawLevelConfigEngine(void) +{ + if (edit_mode_engineconfig == ED_MODE_ENGINECONFIG_CONFIG) + DrawEngineConfigConfig(); + else if (edit_mode_engineconfig == ED_MODE_ENGINECONFIG_COLORS) + DrawEngineConfigColors(); +} + +static void DrawLevelConfigWindow(void) { char *text = "Global Settings"; int font_nr = FONT_TITLE_1; @@ -9179,6 +11553,11 @@ static void DrawLevelInfoWindow(void) stick_element_properties_window = FALSE; + // make sure that previous level config edit mode exists for this level + if (edit_mode_levelconfig == ED_MODE_LEVELCONFIG_ENGINE && + level.game_engine_type != GAME_ENGINE_TYPE_BD) + edit_mode_levelconfig = ED_MODE_LEVELCONFIG_LEVEL; + SetAutomaticNumberOfGemsNeeded(); UnmapLevelEditorFieldGadgets(); @@ -9188,14 +11567,16 @@ static void DrawLevelInfoWindow(void) DrawText(sx, sy, text, font_nr); - DrawLevelInfoTabulatorGadgets(); + DrawLevelConfigTabulatorGadgets(); - if (edit_mode_levelinfo == ED_MODE_LEVELINFO_LEVEL) - DrawLevelInfoLevel(); - else if (edit_mode_levelinfo == ED_MODE_LEVELINFO_LEVELSET) - DrawLevelInfoLevelSet(); - else if (edit_mode_levelinfo == ED_MODE_LEVELINFO_EDITOR) - DrawLevelInfoEditor(); + if (edit_mode_levelconfig == ED_MODE_LEVELCONFIG_LEVEL) + DrawLevelConfigLevel(); + else if (edit_mode_levelconfig == ED_MODE_LEVELCONFIG_LEVELSET) + DrawLevelConfigLevelSet(); + else if (edit_mode_levelconfig == ED_MODE_LEVELCONFIG_EDITOR) + DrawLevelConfigEditor(); + else if (edit_mode_levelconfig == ED_MODE_LEVELCONFIG_ENGINE) + DrawLevelConfigEngine(); } static void DrawCustomContentArea(void) @@ -9310,7 +11691,7 @@ static void DrawMagicBallContentAreas(void) DrawText(x, y + 2 * tilesize, "active", font_nr); } -static void DrawAndroidElementArea(int element) +static void DrawAndroidElementArea(void) { int id = ED_DRAWING_ID_ANDROID_CONTENT; int num_elements = level.num_android_clone_elements; @@ -9338,7 +11719,7 @@ static void DrawAndroidElementArea(int element) MapDrawingArea(id); } -static void DrawGroupElementArea(int element) +static void DrawGroupElementArea(void) { int id = ED_DRAWING_ID_GROUP_CONTENT; int num_elements = group_element_info.num_elements; @@ -9395,13 +11776,40 @@ static void DrawPlayerInitialInventoryArea(int element) MapDrawingArea(id); } +static void DrawMMBallContentArea(void) +{ + int id = ED_DRAWING_ID_MM_BALL_CONTENT; + int num_elements = level.num_mm_ball_contents; + int border_size = ED_DRAWINGAREA_BORDER_SIZE; + int sx = SX + ED_AREA_SETTINGS_X(drawingarea_info[id]) - border_size; + int sy = SY + ED_AREA_SETTINGS_Y(drawingarea_info[id]) - border_size; + int xsize = MAX_MM_BALL_CONTENTS; + int ysize = 1; + + if (drawingarea_info[id].text_left != NULL) + sx += getTextWidthForDrawingArea(drawingarea_info[id].text_left); + + UnmapDrawingArea(id); + + ModifyEditorDrawingArea(id, num_elements, 1); + + // delete content areas in case of reducing number of them + DrawBackground(sx, sy, + xsize * ED_DRAWINGAREA_TILE_SIZE + 2 * border_size, + ysize * ED_DRAWINGAREA_TILE_SIZE + 2 * border_size); + + MapDrawingArea(id); +} + static void DrawEnvelopeTextArea(int envelope_nr) { int id = ED_TEXTAREA_ID_ENVELOPE_INFO; struct GadgetInfo *gi = level_editor_gadget[textarea_info[id].gadget_id]; UnmapGadget(gi); - DrawBackground(gi->x, gi->y, gi->width, gi->height); + + DrawBackground(gi->x, gi->y, + gi->textarea.crop_width, gi->textarea.crop_height); if (envelope_nr != -1) textarea_info[id].value = level.envelope[envelope_nr].text; @@ -9475,13 +11883,16 @@ static void DrawPropertiesInfo(void) { -1, NULL } }; char *filename = getElementDescriptionFilename(properties_element); - char *percentage_text = "In this level: "; + char *num_elements_text = "In this level: "; + char *num_similar_text = "Similar tiles: "; char *properties_text = "Standard properties: "; char *description_text = "Description:"; char *no_description_text = "No description available."; char *none_text = "None"; float percentage; - int num_elements_in_level; + int num_elements_in_level = 0; + int num_similar_in_level = 0; + int num_hires_tiles_in_level = 0; int num_standard_properties = 0; int font1_nr = FONT_TEXT_1; int font2_nr = FONT_TEXT_2; @@ -9490,7 +11901,8 @@ static void DrawPropertiesInfo(void) int font2_height = getFontHeight(font2_nr); int line1_height = font1_height + ED_GADGET_LINE_DISTANCE; int font2_yoffset = (font1_height - font2_height) / 2; - int percentage_text_len = strlen(percentage_text) * font1_width; + int num_elements_text_len = strlen(num_elements_text) * font1_width; + int num_similar_text_len = strlen(num_similar_text) * font1_width; int properties_text_len = strlen(properties_text) * font1_width; int xpos = ED_ELEMENT_SETTINGS_X(0); int ypos = ED_ELEMENT_SETTINGS_Y(0) + ED_GADGET_SMALL_DISTANCE; @@ -9509,22 +11921,66 @@ static void DrawPropertiesInfo(void) // ----- print number of elements / percentage of this element in level - num_elements_in_level = 0; - for (y = 0; y < lev_fieldy; y++) + for (y = 0; y < lev_fieldy; y++) + { for (x = 0; x < lev_fieldx; x++) - if (Feld[x][y] == properties_element) + { + if (Tile[x][y] == properties_element) + { num_elements_in_level++; + } + else if (IS_MM_WALL(Tile[x][y]) && + map_mm_wall_element(Tile[x][y]) == properties_element) + { + num_hires_tiles_in_level += numHiresTiles(Tile[x][y]); + } + } + } + percentage = num_elements_in_level * 100.0 / (lev_fieldx * lev_fieldy); - DrawTextS(xpos, ypos, font1_nr, percentage_text); + DrawTextS(xpos, ypos, font1_nr, num_elements_text); - if (num_elements_in_level > 0) - DrawTextF(xpos + percentage_text_len, ypos + font2_yoffset, font2_nr, + if (num_hires_tiles_in_level > 0) + DrawTextF(xpos + num_elements_text_len, ypos + font2_yoffset, font2_nr, + "%d wall tiles", num_hires_tiles_in_level); + else if (num_elements_in_level > 0) + DrawTextF(xpos + num_elements_text_len, ypos + font2_yoffset, font2_nr, "%d (%.2f %%)", num_elements_in_level, percentage); else - DrawTextF(xpos + percentage_text_len, ypos + font2_yoffset, font2_nr, + DrawTextF(xpos + num_elements_text_len, ypos + font2_yoffset, font2_nr, none_text); + // ----- print number of similar elements / percentage of them in level + + for (y = 0; y < lev_fieldy; y++) + { + for (x = 0; x < lev_fieldx; x++) + { + if (strEqual(element_info[Tile[x][y]].class_name, + element_info[properties_element].class_name)) + { + num_similar_in_level++; + } + } + } + + if (num_similar_in_level != num_elements_in_level) + { + ypos += 1 * MAX(font1_height, font2_height); + + percentage = num_similar_in_level * 100.0 / (lev_fieldx * lev_fieldy); + + DrawTextS(xpos, ypos, font1_nr, num_similar_text); + + if (num_similar_in_level > 0) + DrawTextF(xpos + num_similar_text_len, ypos + font2_yoffset, font2_nr, + "%d (%.2f %%)", num_similar_in_level, percentage); + else + DrawTextF(xpos + num_similar_text_len, ypos + font2_yoffset, font2_nr, + none_text); + } + ypos += 2 * MAX(font1_height, font2_height); // ----- print standard properties of this element @@ -9565,174 +12021,278 @@ static void DrawPropertiesInfo(void) PrintInfoText(no_description_text, font1_nr, xpos, ypos - line1_height); } -#define TEXT_COLLECTING "Score for collecting" -#define TEXT_SMASHING "Score for smashing" -#define TEXT_SLURPING "Score for slurping robot" -#define TEXT_CRACKING "Score for cracking" -#define TEXT_AMOEBA_SPEED "Speed of amoeba growth" -#define TEXT_DURATION "Duration when activated" -#define TEXT_DELAY_ON "Delay before activating" -#define TEXT_DELAY_OFF "Delay before deactivating" -#define TEXT_DELAY_EXPLODING "Delay before exploding" -#define TEXT_DELAY_MOVING "Delay before moving" -#define TEXT_BALL_DELAY "Element generation delay" -#define TEXT_MOVE_SPEED "Speed of android moving" -#define TEXT_CLONE_SPEED "Speed of android cloning" -#define TEXT_GAME_OF_LIFE_1 "Min neighbours to survive" -#define TEXT_GAME_OF_LIFE_2 "Max neighbours to survive" -#define TEXT_GAME_OF_LIFE_3 "Min neighbours to create" -#define TEXT_GAME_OF_LIFE_4 "Max neighbours to create" -#define TEXT_TIME_BONUS "Extra time to solve level" +#define TEXT_COLLECTING "Score for collecting" +#define TEXT_COLLECTING_EXTRA "Score for extra diamonds" +#define TEXT_SMASHING "Score for smashing" +#define TEXT_SLURPING "Score for slurping robot" +#define TEXT_CRACKING "Score for cracking" +#define TEXT_AMOEBA_SPEED "Speed of amoeba growth" +#define TEXT_AMOEBA_THRESHOED "Size for turning to rocks" +#define TEXT_AMOEBA_SLOW_TIME "Slow growth time (seconds)" +#define TEXT_AMOEBA_SLOW_RATE "Slow growth rate (percent)" +#define TEXT_AMOEBA_FAST_RATE "Fast growth rate (percent)" +#define TEXT_DURATION "Duration when activated" +#define TEXT_DELAY_ON "Delay before activating" +#define TEXT_DELAY_OFF "Delay before deactivating" +#define TEXT_DELAY_CHANGING "Delay before changing" +#define TEXT_DELAY_EXPLODING "Delay before exploding" +#define TEXT_DELAY_MOVING "Delay before moving" +#define TEXT_BALL_DELAY "Element generation delay" +#define TEXT_MOVE_SPEED "Speed of android moving" +#define TEXT_CLONE_SPEED "Speed of android cloning" +#define TEXT_GAME_OF_LIFE_1 "Min neighbours to survive" +#define TEXT_GAME_OF_LIFE_2 "Max neighbours to survive" +#define TEXT_GAME_OF_LIFE_3 "Min neighbours to create" +#define TEXT_GAME_OF_LIFE_4 "Max neighbours to create" +#define TEXT_TIME_BONUS "Extra time to solve level" +#define TEXT_TIME_PENALTY "Time penalty if destroyed" +#define TEXT_PERMEABILITY_RATE "slime permeability rate" +#define TEXT_PERMEABILITY_BITS "slime permeability bits" +#define TEXT_RANDOM_SEED "slime random number seed" +#define TEXT_ACID_SPREAD_RATE "Spread rate (percent)" +#define TEXT_BITER_MOVE_DELAY "Move delay (BD frames)" +#define TEXT_REPLICATION_DELAY "Create delay (BD frames)" +#define TEXT_HAMMER_BREAK_DELAY "Delay for breaking walls" +#define TEXT_HAMMER_REAPPEAR_DELAY "Delay for reappearing walls" +#define TEXT_SKELETONS_NEEDED "Skeletons needed to use pot" +#define TEXT_SKELETONS_WORTH "Counts as this many diamonds" +#define TEXT_AUTO_TURN_DELAY "Creatures auto turn delay" +#define TEXT_GRAVITY_DELAY "Gravity switch change delay" static struct { int element; int *value; char *text; + int min_value; + int max_value; } elements_with_counter[] = { - { EL_EMERALD, &level.score[SC_EMERALD], TEXT_COLLECTING }, - { EL_BD_DIAMOND, &level.score[SC_EMERALD], TEXT_COLLECTING }, - { EL_EMERALD_YELLOW, &level.score[SC_EMERALD], TEXT_COLLECTING }, - { EL_EMERALD_RED, &level.score[SC_EMERALD], TEXT_COLLECTING }, - { EL_EMERALD_PURPLE, &level.score[SC_EMERALD], TEXT_COLLECTING }, - { EL_SP_INFOTRON, &level.score[SC_EMERALD], TEXT_COLLECTING }, - { EL_DIAMOND, &level.score[SC_DIAMOND], TEXT_COLLECTING }, - { EL_CRYSTAL, &level.score[SC_CRYSTAL], TEXT_COLLECTING }, - { EL_PEARL, &level.score[SC_PEARL], TEXT_COLLECTING }, - { EL_BUG, &level.score[SC_BUG], TEXT_SMASHING }, - { EL_BUG_RIGHT, &level.score[SC_BUG], TEXT_SMASHING }, - { EL_BUG_UP, &level.score[SC_BUG], TEXT_SMASHING }, - { EL_BUG_LEFT, &level.score[SC_BUG], TEXT_SMASHING }, - { EL_BUG_DOWN, &level.score[SC_BUG], TEXT_SMASHING }, - { EL_BD_BUTTERFLY, &level.score[SC_BUG], TEXT_SMASHING }, - { EL_BD_BUTTERFLY_RIGHT,&level.score[SC_BUG], TEXT_SMASHING }, - { EL_BD_BUTTERFLY_UP, &level.score[SC_BUG], TEXT_SMASHING }, - { EL_BD_BUTTERFLY_LEFT, &level.score[SC_BUG], TEXT_SMASHING }, - { EL_BD_BUTTERFLY_DOWN, &level.score[SC_BUG], TEXT_SMASHING }, - { EL_SP_ELECTRON, &level.score[SC_BUG], TEXT_SMASHING }, - { EL_SPACESHIP, &level.score[SC_SPACESHIP], TEXT_SMASHING }, - { EL_SPACESHIP_RIGHT, &level.score[SC_SPACESHIP], TEXT_SMASHING }, - { EL_SPACESHIP_UP, &level.score[SC_SPACESHIP], TEXT_SMASHING }, - { EL_SPACESHIP_LEFT, &level.score[SC_SPACESHIP], TEXT_SMASHING }, - { EL_SPACESHIP_DOWN, &level.score[SC_SPACESHIP], TEXT_SMASHING }, - { EL_BD_FIREFLY, &level.score[SC_SPACESHIP], TEXT_SMASHING }, - { EL_BD_FIREFLY_RIGHT,&level.score[SC_SPACESHIP], TEXT_SMASHING }, - { EL_BD_FIREFLY_UP, &level.score[SC_SPACESHIP], TEXT_SMASHING }, - { EL_BD_FIREFLY_LEFT, &level.score[SC_SPACESHIP], TEXT_SMASHING }, - { EL_BD_FIREFLY_DOWN, &level.score[SC_SPACESHIP], TEXT_SMASHING }, - { EL_SP_SNIKSNAK, &level.score[SC_SPACESHIP], TEXT_SMASHING }, - { EL_YAMYAM, &level.score[SC_YAMYAM], TEXT_SMASHING }, - { EL_YAMYAM_LEFT, &level.score[SC_YAMYAM], TEXT_SMASHING }, - { EL_YAMYAM_RIGHT, &level.score[SC_YAMYAM], TEXT_SMASHING }, - { EL_YAMYAM_UP, &level.score[SC_YAMYAM], TEXT_SMASHING }, - { EL_YAMYAM_DOWN, &level.score[SC_YAMYAM], TEXT_SMASHING }, - { EL_DARK_YAMYAM, &level.score[SC_YAMYAM], TEXT_SMASHING }, - { EL_ROBOT, &level.score[SC_ROBOT], TEXT_SMASHING }, - { EL_PACMAN, &level.score[SC_PACMAN], TEXT_SMASHING }, - { EL_PACMAN_RIGHT, &level.score[SC_PACMAN], TEXT_SMASHING }, - { EL_PACMAN_UP, &level.score[SC_PACMAN], TEXT_SMASHING }, - { EL_PACMAN_LEFT, &level.score[SC_PACMAN], TEXT_SMASHING }, - { EL_PACMAN_DOWN, &level.score[SC_PACMAN], TEXT_SMASHING }, - { EL_NUT, &level.score[SC_NUT], TEXT_CRACKING }, - { EL_DYNAMITE, &level.score[SC_DYNAMITE], TEXT_COLLECTING }, - { EL_EM_DYNAMITE, &level.score[SC_DYNAMITE], TEXT_COLLECTING }, - { EL_DYNABOMB_INCREASE_NUMBER,&level.score[SC_DYNAMITE],TEXT_COLLECTING }, - { EL_DYNABOMB_INCREASE_SIZE, &level.score[SC_DYNAMITE],TEXT_COLLECTING }, - { EL_DYNABOMB_INCREASE_POWER, &level.score[SC_DYNAMITE],TEXT_COLLECTING }, - { EL_SHIELD_NORMAL, &level.score[SC_SHIELD], TEXT_COLLECTING }, - { EL_SHIELD_DEADLY, &level.score[SC_SHIELD], TEXT_COLLECTING }, - { EL_EXTRA_TIME, &level.extra_time_score, TEXT_COLLECTING }, - { EL_KEY_1, &level.score[SC_KEY], TEXT_COLLECTING }, - { EL_KEY_2, &level.score[SC_KEY], TEXT_COLLECTING }, - { EL_KEY_3, &level.score[SC_KEY], TEXT_COLLECTING }, - { EL_KEY_4, &level.score[SC_KEY], TEXT_COLLECTING }, - { EL_EM_KEY_1, &level.score[SC_KEY], TEXT_COLLECTING }, - { EL_EM_KEY_2, &level.score[SC_KEY], TEXT_COLLECTING }, - { EL_EM_KEY_3, &level.score[SC_KEY], TEXT_COLLECTING }, - { EL_EM_KEY_4, &level.score[SC_KEY], TEXT_COLLECTING }, - { EL_EMC_KEY_5, &level.score[SC_KEY], TEXT_COLLECTING }, - { EL_EMC_KEY_6, &level.score[SC_KEY], TEXT_COLLECTING }, - { EL_EMC_KEY_7, &level.score[SC_KEY], TEXT_COLLECTING }, - { EL_EMC_KEY_8, &level.score[SC_KEY], TEXT_COLLECTING }, - { EL_DC_KEY_WHITE, &level.score[SC_KEY], TEXT_COLLECTING }, - { EL_MM_KETTLE, &level.score[SC_EMERALD], TEXT_COLLECTING }, - { EL_DF_CELL, &level.score[SC_EMERALD], TEXT_COLLECTING }, - { EL_MM_KEY, &level.score[SC_KEY], TEXT_COLLECTING }, - { EL_MM_LIGHTBALL, &level.score[SC_ELEM_BONUS], TEXT_COLLECTING }, - { EL_MM_PACMAN, &level.score[SC_PACMAN], TEXT_SMASHING }, - { EL_MM_PACMAN_RIGHT, &level.score[SC_PACMAN], TEXT_SMASHING }, - { EL_MM_PACMAN_UP, &level.score[SC_PACMAN], TEXT_SMASHING }, - { EL_MM_PACMAN_LEFT, &level.score[SC_PACMAN], TEXT_SMASHING }, - { EL_MM_PACMAN_DOWN, &level.score[SC_PACMAN], TEXT_SMASHING }, - { EL_AMOEBA_WET, &level.amoeba_speed, TEXT_AMOEBA_SPEED }, - { EL_AMOEBA_DRY, &level.amoeba_speed, TEXT_AMOEBA_SPEED }, - { EL_AMOEBA_FULL, &level.amoeba_speed, TEXT_AMOEBA_SPEED }, - { EL_BD_AMOEBA, &level.amoeba_speed, TEXT_AMOEBA_SPEED }, - { EL_EMC_DRIPPER, &level.amoeba_speed, TEXT_AMOEBA_SPEED }, - { EL_MAGIC_WALL, &level.time_magic_wall, TEXT_DURATION }, - { EL_BD_MAGIC_WALL, &level.time_magic_wall, TEXT_DURATION }, - { EL_DC_MAGIC_WALL, &level.time_magic_wall, TEXT_DURATION }, - { EL_ROBOT_WHEEL, &level.time_wheel, TEXT_DURATION }, - - { EL_TIMEGATE_SWITCH, &level.time_timegate, TEXT_DURATION }, - { EL_DC_TIMEGATE_SWITCH,&level.time_timegate, TEXT_DURATION }, - { EL_LIGHT_SWITCH, &level.time_light, TEXT_DURATION }, - { EL_LIGHT_SWITCH_ACTIVE, &level.time_light, TEXT_DURATION }, - { EL_SHIELD_NORMAL, &level.shield_normal_time, TEXT_DURATION }, - { EL_SHIELD_DEADLY, &level.shield_deadly_time, TEXT_DURATION }, - { EL_EXTRA_TIME, &level.extra_time, TEXT_TIME_BONUS }, - { EL_TIME_ORB_FULL, &level.time_orb_time, TEXT_TIME_BONUS }, - { EL_GAME_OF_LIFE, &level.game_of_life[0], TEXT_GAME_OF_LIFE_1 }, - { EL_GAME_OF_LIFE, &level.game_of_life[1], TEXT_GAME_OF_LIFE_2 }, - { EL_GAME_OF_LIFE, &level.game_of_life[2], TEXT_GAME_OF_LIFE_3 }, - { EL_GAME_OF_LIFE, &level.game_of_life[3], TEXT_GAME_OF_LIFE_4 }, - { EL_BIOMAZE, &level.biomaze[0], TEXT_GAME_OF_LIFE_1 }, - { EL_BIOMAZE, &level.biomaze[1], TEXT_GAME_OF_LIFE_2 }, - { EL_BIOMAZE, &level.biomaze[2], TEXT_GAME_OF_LIFE_3 }, - { EL_BIOMAZE, &level.biomaze[3], TEXT_GAME_OF_LIFE_4 }, - - { EL_EMC_ANDROID, &level.android_move_time, TEXT_MOVE_SPEED }, - { EL_EMC_ANDROID, &level.android_clone_time, TEXT_CLONE_SPEED }, - { EL_EMC_MAGIC_BALL, &level.ball_time, TEXT_BALL_DELAY }, - { EL_EMC_LENSES, &level.lenses_score, TEXT_COLLECTING }, - { EL_EMC_MAGNIFIER, &level.magnify_score, TEXT_COLLECTING }, - { EL_SPRING, &level.slurp_score, TEXT_SLURPING }, - { EL_EMC_LENSES, &level.lenses_time, TEXT_DURATION }, - { EL_EMC_MAGNIFIER, &level.magnify_time, TEXT_DURATION }, - { EL_MM_FUSE_ACTIVE, &level.mm_time_fuse, TEXT_DELAY_OFF }, - { EL_MM_BOMB, &level.mm_time_bomb, TEXT_DELAY_EXPLODING }, - { EL_MM_GRAY_BALL, &level.mm_time_ball, TEXT_DELAY_ON }, - { EL_MM_STEEL_BLOCK, &level.mm_time_block, TEXT_DELAY_MOVING }, - { EL_MM_WOODEN_BLOCK, &level.mm_time_block, TEXT_DELAY_MOVING }, - - { -1, NULL, NULL } + { EL_EMERALD, &level.score[SC_EMERALD], TEXT_COLLECTING }, + { EL_BD_DIAMOND, &level.score[SC_EMERALD], TEXT_COLLECTING }, + { EL_BD_DIAMOND, &level.score[SC_DIAMOND_EXTRA], TEXT_COLLECTING_EXTRA }, + { EL_EMERALD_YELLOW, &level.score[SC_EMERALD], TEXT_COLLECTING }, + { EL_EMERALD_RED, &level.score[SC_EMERALD], TEXT_COLLECTING }, + { EL_EMERALD_PURPLE, &level.score[SC_EMERALD], TEXT_COLLECTING }, + { EL_SP_INFOTRON, &level.score[SC_EMERALD], TEXT_COLLECTING }, + { EL_DIAMOND, &level.score[SC_DIAMOND], TEXT_COLLECTING }, + { EL_CRYSTAL, &level.score[SC_CRYSTAL], TEXT_COLLECTING }, + { EL_PEARL, &level.score[SC_PEARL], TEXT_COLLECTING }, + { EL_BUG, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_BUG_RIGHT, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_BUG_UP, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_BUG_LEFT, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_BUG_DOWN, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_BD_BUTTERFLY, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_BD_BUTTERFLY_RIGHT, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_BD_BUTTERFLY_UP, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_BD_BUTTERFLY_LEFT, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_BD_BUTTERFLY_DOWN, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_SP_ELECTRON, &level.score[SC_BUG], TEXT_SMASHING }, + { EL_SPACESHIP, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_SPACESHIP_RIGHT, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_SPACESHIP_UP, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_SPACESHIP_LEFT, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_SPACESHIP_DOWN, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_BD_FIREFLY, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_BD_FIREFLY_RIGHT, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_BD_FIREFLY_UP, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_BD_FIREFLY_LEFT, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_BD_FIREFLY_DOWN, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_SP_SNIKSNAK, &level.score[SC_SPACESHIP], TEXT_SMASHING }, + { EL_YAMYAM, &level.score[SC_YAMYAM], TEXT_SMASHING }, + { EL_YAMYAM_LEFT, &level.score[SC_YAMYAM], TEXT_SMASHING }, + { EL_YAMYAM_RIGHT, &level.score[SC_YAMYAM], TEXT_SMASHING }, + { EL_YAMYAM_UP, &level.score[SC_YAMYAM], TEXT_SMASHING }, + { EL_YAMYAM_DOWN, &level.score[SC_YAMYAM], TEXT_SMASHING }, + { EL_DARK_YAMYAM, &level.score[SC_YAMYAM], TEXT_SMASHING }, + { EL_ROBOT, &level.score[SC_ROBOT], TEXT_SMASHING }, + { EL_PACMAN, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_PACMAN_RIGHT, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_PACMAN_UP, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_PACMAN_LEFT, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_PACMAN_DOWN, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_NUT, &level.score[SC_NUT], TEXT_CRACKING }, + { EL_DYNAMITE, &level.score[SC_DYNAMITE], TEXT_COLLECTING }, + { EL_EM_DYNAMITE, &level.score[SC_DYNAMITE], TEXT_COLLECTING }, + { EL_DYNABOMB_INCREASE_NUMBER,&level.score[SC_DYNAMITE], TEXT_COLLECTING }, + { EL_DYNABOMB_INCREASE_SIZE, &level.score[SC_DYNAMITE], TEXT_COLLECTING }, + { EL_DYNABOMB_INCREASE_POWER, &level.score[SC_DYNAMITE], TEXT_COLLECTING }, + { EL_SHIELD_NORMAL, &level.score[SC_SHIELD], TEXT_COLLECTING }, + { EL_SHIELD_DEADLY, &level.score[SC_SHIELD], TEXT_COLLECTING }, + { EL_EXTRA_TIME, &level.extra_time_score, TEXT_COLLECTING }, + { EL_KEY_1, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_KEY_2, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_KEY_3, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_KEY_4, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_EM_KEY_1, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_EM_KEY_2, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_EM_KEY_3, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_EM_KEY_4, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_EMC_KEY_5, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_EMC_KEY_6, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_EMC_KEY_7, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_EMC_KEY_8, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_DC_KEY_WHITE, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_MM_KETTLE, &level.score[SC_EMERALD], TEXT_COLLECTING }, + { EL_DF_CELL, &level.score[SC_EMERALD], TEXT_COLLECTING }, + { EL_MM_KEY, &level.score[SC_KEY], TEXT_COLLECTING }, + { EL_MM_LIGHTBALL, &level.score[SC_ELEM_BONUS], TEXT_COLLECTING }, + { EL_MM_PACMAN, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_MM_PACMAN_RIGHT, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_MM_PACMAN_UP, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_MM_PACMAN_LEFT, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_MM_PACMAN_DOWN, &level.score[SC_PACMAN], TEXT_SMASHING }, + { EL_AMOEBA_WET, &level.amoeba_speed, TEXT_AMOEBA_SPEED }, + { EL_AMOEBA_DRY, &level.amoeba_speed, TEXT_AMOEBA_SPEED }, + { EL_AMOEBA_FULL, &level.amoeba_speed, TEXT_AMOEBA_SPEED }, + { EL_BD_AMOEBA, &level.amoeba_speed, TEXT_AMOEBA_SPEED }, + { EL_EMC_DRIPPER, &level.amoeba_speed, TEXT_AMOEBA_SPEED }, + { EL_BD_AMOEBA, &level.bd_amoeba_threshold_too_big, TEXT_AMOEBA_THRESHOED }, + { EL_BD_AMOEBA, &level.bd_amoeba_slow_growth_time, TEXT_AMOEBA_SLOW_TIME }, + { EL_BD_AMOEBA, &level.bd_amoeba_slow_growth_rate, TEXT_AMOEBA_SLOW_RATE, + 0, 100 }, + { EL_BD_AMOEBA, &level.bd_amoeba_fast_growth_rate, TEXT_AMOEBA_FAST_RATE, + 0, 100 }, + { EL_BD_AMOEBA_2, &level.bd_amoeba_2_threshold_too_big, TEXT_AMOEBA_THRESHOED }, + { EL_BD_AMOEBA_2, &level.bd_amoeba_2_slow_growth_time, TEXT_AMOEBA_SLOW_TIME }, + { EL_BD_AMOEBA_2, &level.bd_amoeba_2_slow_growth_rate, TEXT_AMOEBA_SLOW_RATE, + 0, 100 }, + { EL_BD_AMOEBA_2, &level.bd_amoeba_2_fast_growth_rate, TEXT_AMOEBA_FAST_RATE, + 0, 100 }, + { EL_MAGIC_WALL, &level.time_magic_wall, TEXT_DURATION }, + { EL_BD_MAGIC_WALL, &level.time_magic_wall, TEXT_DURATION }, + { EL_DC_MAGIC_WALL, &level.time_magic_wall, TEXT_DURATION }, + { EL_ROBOT_WHEEL, &level.time_wheel, TEXT_DURATION }, + { EL_TIMEGATE_SWITCH, &level.time_timegate, TEXT_DURATION }, + { EL_DC_TIMEGATE_SWITCH, &level.time_timegate, TEXT_DURATION }, + { EL_LIGHT_SWITCH, &level.time_light, TEXT_DURATION }, + { EL_LIGHT_SWITCH_ACTIVE, &level.time_light, TEXT_DURATION }, + { EL_SHIELD_NORMAL, &level.shield_normal_time, TEXT_DURATION }, + { EL_SHIELD_DEADLY, &level.shield_deadly_time, TEXT_DURATION }, + { EL_BD_CLOCK, &level.bd_clock_extra_time, TEXT_TIME_BONUS, + -100, 100 }, + { EL_BD_VOODOO_DOLL, &level.bd_voodoo_penalty_time, TEXT_TIME_PENALTY, + 0, 100 }, + { EL_BD_SLIME, &level.bd_slime_permeability_rate, TEXT_PERMEABILITY_RATE, + 0, 100 }, + { EL_BD_SLIME, &level.bd_slime_permeability_bits_c64, TEXT_PERMEABILITY_BITS, + 0, 255 }, + { EL_BD_SLIME, &level.bd_slime_random_seed_c64, TEXT_RANDOM_SEED, + -1, 65535 }, + { EL_BD_ACID, &level.bd_acid_spread_rate, TEXT_ACID_SPREAD_RATE, + 0, 100 }, + { EL_BD_BITER, &level.bd_biter_move_delay, TEXT_BITER_MOVE_DELAY, + 0, 3 }, + { EL_BD_BITER_RIGHT, &level.bd_biter_move_delay, TEXT_BITER_MOVE_DELAY, + 0, 3 }, + { EL_BD_BITER_UP, &level.bd_biter_move_delay, TEXT_BITER_MOVE_DELAY, + 0, 3 }, + { EL_BD_BITER_LEFT, &level.bd_biter_move_delay, TEXT_BITER_MOVE_DELAY, + 0, 3 }, + { EL_BD_BITER_DOWN, &level.bd_biter_move_delay, TEXT_BITER_MOVE_DELAY, + 0, 3 }, + { EL_BD_REPLICATOR, &level.bd_replicator_create_delay, TEXT_REPLICATION_DELAY, + 0, 100 }, + { EL_BD_PNEUMATIC_HAMMER, &level.bd_hammer_walls_break_delay, TEXT_HAMMER_BREAK_DELAY, + 1, 100 }, + { EL_BD_PNEUMATIC_HAMMER, &level.bd_hammer_walls_reappear_delay, TEXT_HAMMER_REAPPEAR_DELAY, + 1, 200 }, + { EL_BD_POT, &level.bd_num_skeletons_needed_for_pot, TEXT_SKELETONS_NEEDED, + 0, 50 }, + { EL_BD_SKELETON, &level.bd_num_skeletons_needed_for_pot, TEXT_SKELETONS_NEEDED, + 0, 50 }, + { EL_BD_SKELETON, &level.bd_skeleton_worth_num_diamonds, TEXT_SKELETONS_WORTH, + 0, 10 }, + { EL_BD_CREATURE_SWITCH, &level.bd_creatures_auto_turn_delay, TEXT_AUTO_TURN_DELAY }, + { EL_BD_GRAVITY_SWITCH, &level.bd_gravity_switch_delay, TEXT_GRAVITY_DELAY, + 1, 60 }, + { EL_EXTRA_TIME, &level.extra_time, TEXT_TIME_BONUS }, + { EL_TIME_ORB_FULL, &level.time_orb_time, TEXT_TIME_BONUS }, + { EL_GAME_OF_LIFE, &level.game_of_life[0], TEXT_GAME_OF_LIFE_1,0,8 }, + { EL_GAME_OF_LIFE, &level.game_of_life[1], TEXT_GAME_OF_LIFE_2,0,8 }, + { EL_GAME_OF_LIFE, &level.game_of_life[2], TEXT_GAME_OF_LIFE_3,0,8 }, + { EL_GAME_OF_LIFE, &level.game_of_life[3], TEXT_GAME_OF_LIFE_4,0,8 }, + { EL_BIOMAZE, &level.biomaze[0], TEXT_GAME_OF_LIFE_1,0,8 }, + { EL_BIOMAZE, &level.biomaze[1], TEXT_GAME_OF_LIFE_2,0,8 }, + { EL_BIOMAZE, &level.biomaze[2], TEXT_GAME_OF_LIFE_3,0,8 }, + { EL_BIOMAZE, &level.biomaze[3], TEXT_GAME_OF_LIFE_4,0,8 }, + { EL_EMC_ANDROID, &level.android_move_time, TEXT_MOVE_SPEED }, + { EL_EMC_ANDROID, &level.android_clone_time, TEXT_CLONE_SPEED }, + { EL_EMC_MAGIC_BALL, &level.ball_time, TEXT_BALL_DELAY }, + { EL_EMC_LENSES, &level.lenses_score, TEXT_COLLECTING }, + { EL_EMC_MAGNIFIER, &level.magnify_score, TEXT_COLLECTING }, + { EL_SPRING, &level.slurp_score, TEXT_SLURPING }, + { EL_SPRING_LEFT, &level.slurp_score, TEXT_SLURPING }, + { EL_SPRING_RIGHT, &level.slurp_score, TEXT_SLURPING }, + { EL_EMC_LENSES, &level.lenses_time, TEXT_DURATION }, + { EL_EMC_MAGNIFIER, &level.magnify_time, TEXT_DURATION }, + { EL_MM_FUSE_ACTIVE, &level.mm_time_fuse, TEXT_DELAY_OFF }, + { EL_MM_BOMB, &level.mm_time_bomb, TEXT_DELAY_EXPLODING }, + { EL_MM_GRAY_BALL, &level.mm_time_ball, TEXT_DELAY_CHANGING }, + { EL_MM_STEEL_BLOCK, &level.mm_time_block, TEXT_DELAY_MOVING }, + { EL_MM_WOODEN_BLOCK, &level.mm_time_block, TEXT_DELAY_MOVING }, + + { -1, NULL, NULL } }; static boolean checkPropertiesConfig(int element) { int i; + // special case: empty space customization only available in R'n'D game engine + if (element == EL_EMPTY_SPACE && level.game_engine_type != GAME_ENGINE_TYPE_RND) + return FALSE; + + // special case: BD style rock customization only available in BD game engine + if (element == EL_BD_ROCK && level.game_engine_type != GAME_ENGINE_TYPE_BD) + return FALSE; + if (IS_GEM(element) || IS_CUSTOM_ELEMENT(element) || IS_GROUP_ELEMENT(element) || + IS_EMPTY_ELEMENT(element) || IS_BALLOON_ELEMENT(element) || IS_ENVELOPE(element) || + IS_MM_ENVELOPE(element) || IS_MM_MCDUFFIN(element) || IS_DF_LASER(element) || - ELEM_IS_PLAYER(element) || + IS_PLAYER_ELEMENT(element) || + IS_BD_PLAYER_ELEMENT(element) || + IS_BD_FIREFLY(properties_element) || + IS_BD_FIREFLY_2(properties_element) || + IS_BD_BUTTERFLY(properties_element) || + IS_BD_BUTTERFLY_2(properties_element) || + IS_BD_STONEFLY(properties_element) || + IS_BD_DRAGONFLY(properties_element) || + IS_BD_EXPANDABLE_WALL(properties_element) || + IS_BD_EXPANDABLE_STEELWALL(properties_element) || + IS_BD_CONVEYOR_BELT(properties_element) || + IS_BD_CONVEYOR_BELT_SWITCH(properties_element) || + IS_SOKOBAN_OBJECT_OR_FIELD(element) || HAS_EDITOR_CONTENT(element) || CAN_GROW(element) || COULD_MOVE_INTO_ACID(element) || MAYBE_DONT_COLLIDE_WITH(element) || - element == EL_SOKOBAN_OBJECT || - element == EL_SOKOBAN_FIELD_EMPTY || - element == EL_SOKOBAN_FIELD_FULL) + element == EL_BD_SAND || + element == EL_BD_ROCK || + element == EL_BD_MEGA_ROCK || + element == EL_BD_BOMB || + element == EL_BD_ROCKET_LAUNCHER || + element == EL_BD_NITRO_PACK || + element == EL_BD_SWEET || + element == EL_BD_VOODOO_DOLL || + element == EL_BD_WATER || + element == EL_BD_GRAVITY_SWITCH) + { return TRUE; + } else + { for (i = 0; elements_with_counter[i].element != -1; i++) if (elements_with_counter[i].element == element) return TRUE; + } return FALSE; } @@ -9750,7 +12310,7 @@ static void SetAutomaticNumberOfGemsNeeded(void) { for (y = 0; y < lev_fieldy; y++) { - int element = Feld[x][y]; + int element = Tile[x][y]; switch (element) { @@ -9807,8 +12367,7 @@ static void DrawPropertiesConfig(void) int xpos = ED_ELEMENT_SETTINGS_X(0); int ypos = ED_ELEMENT_SETTINGS_Y(0) + ED_GADGET_SMALL_DISTANCE; - PrintInfoText("No configuration options available.", - FONT_TEXT_1, xpos, ypos); + PrintInfoText("No configuration options available.", FONT_TEXT_1, xpos, ypos); return; } @@ -9816,68 +12375,171 @@ static void DrawPropertiesConfig(void) // check if there are elements where a value can be chosen for for (i = 0; elements_with_counter[i].element != -1; i++) { - if (elements_with_counter[i].element == properties_element) - { - int counter_id = ED_COUNTER_ID_ELEMENT_VALUE1 + num_element_counters; - - counterbutton_info[counter_id].y = - ED_ELEMENT_SETTINGS_YPOS( - (HAS_EDITOR_CONTENT(properties_element) ? 1 : 0) + - (CAN_GROW(properties_element) ? 1 : 0) + - (COULD_MOVE_INTO_ACID(properties_element) ? 1 : 0) + - (MAYBE_DONT_COLLIDE_WITH(properties_element) ? 1 : 0) + - (properties_element == EL_EMC_MAGIC_BALL ? 2 : 0) + - num_element_counters); - - counterbutton_info[counter_id].value = elements_with_counter[i].value; - counterbutton_info[counter_id].text_right= elements_with_counter[i].text; - - if (properties_element == EL_GAME_OF_LIFE || - properties_element == EL_BIOMAZE) - { - counterbutton_info[counter_id].min_value = 0; // min neighbours - counterbutton_info[counter_id].max_value = 8; // max neighbours - } - else - { - // !!! CHANGE THIS FOR CERTAIN ELEMENTS !!! - counterbutton_info[counter_id].min_value = MIN_SCORE; - counterbutton_info[counter_id].max_value = MAX_SCORE; - } + if (elements_with_counter[i].element != properties_element) + continue; - MapCounterButtons(counter_id); + // special case: score for extra diamonds only available in BD game engine + if (elements_with_counter[i].element == EL_BD_DIAMOND && + elements_with_counter[i].value == &level.score[SC_DIAMOND_EXTRA] && + level.game_engine_type != GAME_ENGINE_TYPE_BD) + continue; - num_element_counters++; - if (num_element_counters >= max_num_element_counters) - break; - } + // special case: some amoeba counters only available in BD game engine + if (elements_with_counter[i].element == EL_BD_AMOEBA && + elements_with_counter[i].value != &level.amoeba_speed && + level.game_engine_type != GAME_ENGINE_TYPE_BD) + continue; + + // special case: score for smashing only available in R'n'D game engine + if ((IS_BD_FIREFLY(elements_with_counter[i].element) || + IS_BD_BUTTERFLY(elements_with_counter[i].element)) && + (elements_with_counter[i].value == &level.score[SC_BUG] || + elements_with_counter[i].value == &level.score[SC_SPACESHIP]) && + level.game_engine_type == GAME_ENGINE_TYPE_BD) + continue; + + // special case: some amoeba counters only available in R'n'D game engine + if (elements_with_counter[i].element == EL_BD_AMOEBA && + elements_with_counter[i].value == &level.amoeba_speed && + level.game_engine_type == GAME_ENGINE_TYPE_BD) + continue; + + int counter_id = ED_COUNTER_ID_ELEMENT_VALUE1 + num_element_counters; + + counterbutton_info[counter_id].y = + ED_ELEMENT_SETTINGS_YPOS((HAS_EDITOR_CONTENT(properties_element) ? 1 : 0) + + (CAN_GROW(properties_element) ? 1 : 0) + + (COULD_MOVE_INTO_ACID(properties_element) ? 1 : 0) + + (MAYBE_DONT_COLLIDE_WITH(properties_element) ? 1 : 0) + + (properties_element == EL_BD_VOODOO_DOLL ? 4 : 0) + + (properties_element == EL_BD_SLIME ? 1 : 0) + + (properties_element == EL_BD_ACID ? 1 : 0) + + (properties_element == EL_BD_REPLICATOR ? 1 : 0) + + (properties_element == EL_BD_CREATURE_SWITCH ? 1 : 0) + + (properties_element == EL_BD_GRAVITY_SWITCH ? 2 : 0) + + (properties_element == EL_EMC_MAGIC_BALL ? 2 : 0) + + num_element_counters); + + // special case: set magic wall counter for BD game engine separately + if (properties_element == EL_BD_MAGIC_WALL && level.game_engine_type == GAME_ENGINE_TYPE_BD) + counterbutton_info[counter_id].y = ED_ELEMENT_SETTINGS_YPOS(1); + + // special case: set amoeba counters for BD game engine separately + if ((properties_element == EL_BD_AMOEBA && level.game_engine_type == GAME_ENGINE_TYPE_BD) || + (properties_element == EL_BD_AMOEBA_2)) + counterbutton_info[counter_id].y = ED_ELEMENT_SETTINGS_YPOS(3 + num_element_counters); + + // special case: set position for delay counter for reappearing hammered walls + if (properties_element == EL_BD_PNEUMATIC_HAMMER && num_element_counters > 0) + counterbutton_info[counter_id].y += 1; + + counterbutton_info[counter_id].value = elements_with_counter[i].value; + counterbutton_info[counter_id].text_right = elements_with_counter[i].text; + counterbutton_info[counter_id].min_value = elements_with_counter[i].min_value; + counterbutton_info[counter_id].max_value = elements_with_counter[i].max_value; + + // default: counter values between 0 and 999 + if (counterbutton_info[counter_id].max_value == 0) + counterbutton_info[counter_id].max_value = 999; + + MapCounterButtons(counter_id); + + num_element_counters++; + if (num_element_counters >= max_num_element_counters) + break; } - if (HAS_EDITOR_CONTENT(properties_element)) + if (properties_element == EL_BD_MAGIC_WALL && level.game_engine_type == GAME_ENGINE_TYPE_BD) { // draw stickybutton gadget MapCheckbuttonGadget(ED_CHECKBUTTON_ID_STICK_ELEMENT); - if (IS_AMOEBOID(properties_element)) - MapDrawingArea(ED_DRAWING_ID_AMOEBA_CONTENT); - else if (properties_element == EL_YAMYAM || - properties_element == EL_YAMYAM_LEFT || + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_MAGIC_WALL_ZERO_INFINITE); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_MAGIC_WALL_WAIT_HATCHING); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_MAGIC_WALL_STOPS_AMOEBA); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_MAGIC_WALL_BREAK_SCAN); + + MapDrawingArea(ED_DRAWING_ID_BD_MAGIC_WALL_DIAMOND_TO); + MapDrawingArea(ED_DRAWING_ID_BD_MAGIC_WALL_ROCK_TO); + MapDrawingArea(ED_DRAWING_ID_BD_MAGIC_WALL_MEGA_ROCK_TO); + MapDrawingArea(ED_DRAWING_ID_BD_MAGIC_WALL_NUT_TO); + MapDrawingArea(ED_DRAWING_ID_BD_MAGIC_WALL_NITRO_PACK_TO); + MapDrawingArea(ED_DRAWING_ID_BD_MAGIC_WALL_FLYING_DIAMOND_TO); + MapDrawingArea(ED_DRAWING_ID_BD_MAGIC_WALL_FLYING_ROCK_TO); + } + + if (HAS_EDITOR_CONTENT(properties_element)) + { + // draw stickybutton gadget + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_STICK_ELEMENT); + + if (properties_element == EL_BD_AMOEBA && level.game_engine_type == GAME_ENGINE_TYPE_BD) + { + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_AMOEBA_WAIT_FOR_HATCHING); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_AMOEBA_START_IMMEDIATELY); + + MapDrawingArea(ED_DRAWING_ID_BD_AMOEBA_CONTENT_TOO_BIG); + MapDrawingArea(ED_DRAWING_ID_BD_AMOEBA_CONTENT_ENCLOSED); + } + else if (properties_element == EL_BD_AMOEBA_2) + { + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_AMOEBA_WAIT_FOR_HATCHING); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_AMOEBA_START_IMMEDIATELY); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_AMOEBA_2_EXPLODE_BY_AMOEBA); + + MapDrawingArea(ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_TOO_BIG); + MapDrawingArea(ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_ENCLOSED); + MapDrawingArea(ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_EXPLODING); + MapDrawingArea(ED_DRAWING_ID_BD_AMOEBA_2_CONTENT_LOOKS_LIKE); + } + else if (IS_AMOEBOID(properties_element)) + { + MapDrawingArea(ED_DRAWING_ID_AMOEBA_CONTENT); + } + else if (properties_element == EL_BD_ACID) + { + MapDrawingArea(ED_DRAWING_ID_BD_ACID_EATS_ELEMENT); + MapDrawingArea(ED_DRAWING_ID_BD_ACID_TURNS_TO_ELEMENT); + } + else if (IS_BD_BITER(properties_element)) + { + MapDrawingArea(ED_DRAWING_ID_BD_BITER_EATS_ELEMENT); + } + else if (properties_element == EL_BD_BLADDER) + { + MapDrawingArea(ED_DRAWING_ID_BD_BLADDER_CONVERTS_BY_ELEMENT); + } + else if (properties_element == EL_YAMYAM || + properties_element == EL_YAMYAM_LEFT || properties_element == EL_YAMYAM_RIGHT || properties_element == EL_YAMYAM_UP || properties_element == EL_YAMYAM_DOWN) + { DrawYamYamContentAreas(); + } else if (properties_element == EL_EMC_MAGIC_BALL) { DrawMagicBallContentAreas(); MapCheckbuttonGadget(ED_CHECKBUTTON_ID_RANDOM_BALL_CONTENT); - MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INITIAL_BALL_STATE); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_INITIAL_BALL_ACTIVE); } else if (properties_element == EL_EMC_ANDROID) - DrawAndroidElementArea(properties_element); + { + DrawAndroidElementArea(); + } + else if (properties_element == EL_MM_GRAY_BALL) + { + MapCounterButtons(ED_COUNTER_ID_MM_BALL_CONTENT); + MapSelectboxGadget(ED_SELECTBOX_ID_MM_BALL_CHOICE_MODE); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_ROTATE_MM_BALL_CONTENT); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EXPLODE_MM_BALL); + + DrawMMBallContentArea(); + } } - if (ELEM_IS_PLAYER(properties_element)) + if (IS_PLAYER_ELEMENT(properties_element)) { int player_nr = GET_PLAYER_NR(properties_element); @@ -9939,6 +12601,8 @@ static void DrawPropertiesConfig(void) // draw checkbutton gadgets MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_FINISH_DIG_COLLECT); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_KEEP_WALKABLE_CE); // draw counter gadgets MapCounterButtons(ED_COUNTER_ID_INVENTORY_SIZE); @@ -9948,14 +12612,191 @@ static void DrawPropertiesConfig(void) } } - if (IS_GEM(properties_element)) + if (IS_BD_PLAYER_ELEMENT(properties_element)) + { + counterbutton_info[ED_COUNTER_ID_BD_PUSHING_PROB].y = + ED_ELEMENT_SETTINGS_YPOS(2); + counterbutton_info[ED_COUNTER_ID_BD_PUSHING_PROB_WITH_SWEET].y = + ED_ELEMENT_SETTINGS_YPOS(3); + checkbutton_info[ED_CHECKBUTTON_ID_BD_PUSH_MEGA_ROCK_WITH_SWEET].y = + ED_ELEMENT_SETTINGS_YPOS(4); + + // draw checkbutton gadgets + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_DIAGONAL_MOVEMENTS); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_TOPMOST_PLAYER_ACTIVE); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_PUSH_MEGA_ROCK_WITH_SWEET); + + // draw counter gadgets + MapCounterButtons(ED_COUNTER_ID_BD_PUSHING_PROB); + MapCounterButtons(ED_COUNTER_ID_BD_PUSHING_PROB_WITH_SWEET); + + // draw drawing area gadgets + MapDrawingArea(ED_DRAWING_ID_BD_SNAP_ELEMENT); + } + + if (properties_element == EL_BD_SAND) + { + MapDrawingArea(ED_DRAWING_ID_BD_SAND_LOOKS_LIKE); + } + + if (properties_element == EL_BD_ROCK && level.game_engine_type == GAME_ENGINE_TYPE_BD) + { + counterbutton_info[ED_COUNTER_ID_BD_PUSHING_PROB].y = + ED_ELEMENT_SETTINGS_YPOS(0); + counterbutton_info[ED_COUNTER_ID_BD_PUSHING_PROB_WITH_SWEET].y = + ED_ELEMENT_SETTINGS_YPOS(1); + + MapCounterButtons(ED_COUNTER_ID_BD_PUSHING_PROB); + MapCounterButtons(ED_COUNTER_ID_BD_PUSHING_PROB_WITH_SWEET); + + MapDrawingArea(ED_DRAWING_ID_BD_ROCK_TURNS_TO_ON_FALLING); + MapDrawingArea(ED_DRAWING_ID_BD_ROCK_TURNS_TO_ON_IMPACT); + } + + if (properties_element == EL_BD_DIAMOND && level.game_engine_type == GAME_ENGINE_TYPE_BD) + { + MapDrawingArea(ED_DRAWING_ID_BD_DIAMOND_TURNS_TO_ON_FALLING); + MapDrawingArea(ED_DRAWING_ID_BD_DIAMOND_TURNS_TO_ON_IMPACT); + } + + if (level.game_engine_type == GAME_ENGINE_TYPE_BD) + { + if (IS_BD_FIREFLY(properties_element)) + { + MapDrawingArea(ED_DRAWING_ID_BD_FIREFLY_EXPLODES_TO); + MapDrawingArea(ED_DRAWING_ID_BD_EXPLOSION_TURNS_TO); + } + else if (IS_BD_FIREFLY_2(properties_element)) + { + MapDrawingArea(ED_DRAWING_ID_BD_FIREFLY_2_EXPLODES_TO); + MapDrawingArea(ED_DRAWING_ID_BD_EXPLOSION_TURNS_TO); + } + else if (IS_BD_BUTTERFLY(properties_element)) + { + MapDrawingArea(ED_DRAWING_ID_BD_BUTTERFLY_EXPLODES_TO); + MapDrawingArea(ED_DRAWING_ID_BD_DIAMOND_BIRTH_TURNS_TO); + } + else if (IS_BD_BUTTERFLY_2(properties_element)) + { + MapDrawingArea(ED_DRAWING_ID_BD_BUTTERFLY_2_EXPLODES_TO); + MapDrawingArea(ED_DRAWING_ID_BD_DIAMOND_BIRTH_TURNS_TO); + } + else if (IS_BD_STONEFLY(properties_element)) + { + MapDrawingArea(ED_DRAWING_ID_BD_STONEFLY_EXPLODES_TO); + } + else if (IS_BD_DRAGONFLY(properties_element)) + { + MapDrawingArea(ED_DRAWING_ID_BD_DRAGONFLY_EXPLODES_TO); + MapDrawingArea(ED_DRAWING_ID_BD_EXPLOSION_TURNS_TO); + } + else if (properties_element == EL_BD_BOMB) + { + MapDrawingArea(ED_DRAWING_ID_BD_BOMB_EXPLOSION_TURNS_TO); + } + else if (properties_element == EL_BD_NITRO_PACK) + { + MapDrawingArea(ED_DRAWING_ID_BD_NITRO_EXPLOSION_TURNS_TO); + } + } + + if (properties_element == EL_BD_MEGA_ROCK || + properties_element == EL_BD_SWEET) + { + counterbutton_info[ED_COUNTER_ID_BD_PUSHING_PROB_WITH_SWEET].y = + ED_ELEMENT_SETTINGS_YPOS(0); + checkbutton_info[ED_CHECKBUTTON_ID_BD_PUSH_MEGA_ROCK_WITH_SWEET].y = + ED_ELEMENT_SETTINGS_YPOS(1); + + MapCounterButtons(ED_COUNTER_ID_BD_PUSHING_PROB_WITH_SWEET); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_PUSH_MEGA_ROCK_WITH_SWEET); + } + + if (properties_element == EL_BD_VOODOO_DOLL) + { + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_VOODOO_COLLECTS_DIAMONDS); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_VOODOO_HURT_KILLS_PLAYER); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_VOODOO_DIES_BY_ROCK); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_VOODOO_VANISH_BY_EXPLOSION); + } + + if (properties_element == EL_BD_SLIME) + { + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_SLIME_IS_PREDICTABLE); + + MapDrawingArea(ED_DRAWING_ID_BD_SLIME_EATS_ELEMENT_1); + MapDrawingArea(ED_DRAWING_ID_BD_SLIME_CONVERTS_TO_ELEMENT_1); + MapDrawingArea(ED_DRAWING_ID_BD_SLIME_EATS_ELEMENT_2); + MapDrawingArea(ED_DRAWING_ID_BD_SLIME_CONVERTS_TO_ELEMENT_2); + MapDrawingArea(ED_DRAWING_ID_BD_SLIME_EATS_ELEMENT_3); + MapDrawingArea(ED_DRAWING_ID_BD_SLIME_CONVERTS_TO_ELEMENT_3); + } + + if (IS_BD_EXPANDABLE_WALL(properties_element) || + IS_BD_EXPANDABLE_STEELWALL(properties_element)) + { + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_CHANGE_EXPANDING_WALL); + + if (IS_BD_EXPANDABLE_WALL(properties_element)) + MapDrawingArea(ED_DRAWING_ID_BD_EXPANDING_WALL_LOOKS_LIKE); + } + + if (properties_element == EL_BD_REPLICATOR) + { + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_REPLICATORS_ACTIVE); + } + + if (IS_BD_CONVEYOR_BELT(properties_element) || + IS_BD_CONVEYOR_BELT_SWITCH(properties_element)) + { + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_CONVEYOR_BELTS_ACTIVE); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_CONVEYOR_BELTS_CHANGED); + } + + if (properties_element == EL_BD_WATER) + { + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_WATER_CANNOT_FLOW_DOWN); + } + + if (properties_element == EL_BD_PNEUMATIC_HAMMER) + { + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_HAMMER_WALLS_REAPPEAR); + } + + if (properties_element == EL_BD_ROCKET_LAUNCHER) + { + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_INFINITE_ROCKETS); + } + + if (properties_element == EL_BD_CREATURE_SWITCH) + { + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_CREATURES_START_BACKWARDS); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_CREATURES_TURN_ON_HATCHING); + } + + if (properties_element == EL_BD_GRAVITY_SWITCH) + { + MapSelectboxGadget(ED_SELECTBOX_ID_BD_GRAVITY_DIRECTION); + + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_GRAVITY_SWITCH_ACTIVE); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_BD_GRAVITY_AFFECTS_ALL); + } + + if (properties_element == EL_BD_NUT) + { + MapDrawingArea(ED_DRAWING_ID_BD_NUT_CONTENT); + } + + // special case: slippery walls option for gems only available in R'n'D game engine + if (IS_GEM(properties_element) && level.game_engine_type == GAME_ENGINE_TYPE_RND) MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EM_SLIPPERY_GEMS); if (properties_element == EL_EM_DYNAMITE) MapCheckbuttonGadget(ED_CHECKBUTTON_ID_EM_EXPLODES_BY_FIRE); - if (COULD_MOVE_INTO_ACID(properties_element) && - !ELEM_IS_PLAYER(properties_element) && + if (level.game_engine_type == GAME_ENGINE_TYPE_RND && + COULD_MOVE_INTO_ACID(properties_element) && + !IS_PLAYER_ELEMENT(properties_element) && (!IS_CUSTOM_ELEMENT(properties_element) || edit_mode_properties == ED_MODE_PROPERTIES_CONFIG_2)) { @@ -9963,7 +12804,7 @@ static void DrawPropertiesConfig(void) checkbutton_info[ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID].x = ED_ELEMENT_SETTINGS_XPOS(IS_CUSTOM_ELEMENT(properties_element) ? 1 : 0); checkbutton_info[ED_CHECKBUTTON_ID_CAN_MOVE_INTO_ACID].y = - ED_ELEMENT_SETTINGS_YPOS(IS_CUSTOM_ELEMENT(properties_element) ? 6 : + ED_ELEMENT_SETTINGS_YPOS(IS_CUSTOM_ELEMENT(properties_element) ? 7 : IS_BALLOON_ELEMENT(properties_element) || HAS_EDITOR_CONTENT(properties_element) ? 1 : 0); @@ -9973,7 +12814,9 @@ static void DrawPropertiesConfig(void) if (MAYBE_DONT_COLLIDE_WITH(properties_element)) MapCheckbuttonGadget(ED_CHECKBUTTON_ID_DONT_COLLIDE_WITH); - if (properties_element == EL_SPRING) + if (properties_element == EL_SPRING || + properties_element == EL_SPRING_LEFT || + properties_element == EL_SPRING_RIGHT) MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_SPRING_BUG); if (properties_element == EL_TIME_ORB_FULL) @@ -9983,7 +12826,7 @@ static void DrawPropertiesConfig(void) properties_element == EL_BIOMAZE) MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_LIFE_BUGS); - if (CAN_GROW(properties_element)) + if (CAN_GROW(properties_element) && level.game_engine_type != GAME_ENGINE_TYPE_BD) { checkbutton_info[ED_CHECKBUTTON_ID_GROW_INTO_DIGGABLE].y = ED_ELEMENT_SETTINGS_YPOS(HAS_EDITOR_CONTENT(properties_element) ? 1 : 0); @@ -10011,13 +12854,14 @@ static void DrawPropertiesConfig(void) if (IS_BALLOON_ELEMENT(properties_element)) MapSelectboxGadget(ED_SELECTBOX_ID_WIND_DIRECTION); - if (IS_ENVELOPE(properties_element)) + if (IS_ENVELOPE(properties_element) || + IS_MM_ENVELOPE(properties_element)) { int counter1_id = ED_COUNTER_ID_ENVELOPE_XSIZE; int counter2_id = ED_COUNTER_ID_ENVELOPE_YSIZE; int button1_id = ED_CHECKBUTTON_ID_ENVELOPE_AUTOWRAP; int button2_id = ED_CHECKBUTTON_ID_ENVELOPE_CENTERED; - int envelope_nr = properties_element - EL_ENVELOPE_1; + int envelope_nr = ENVELOPE_NR(properties_element); counterbutton_info[counter1_id].value = &level.envelope[envelope_nr].xsize; counterbutton_info[counter2_id].value = &level.envelope[envelope_nr].ysize; @@ -10125,7 +12969,7 @@ static void DrawPropertiesConfig(void) MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1); // draw drawing area gadgets - DrawGroupElementArea(properties_element); + DrawGroupElementArea(); // draw text input gadgets MapTextInputGadget(ED_TEXTINPUT_ID_ELEMENT_NAME); @@ -10135,6 +12979,23 @@ static void DrawPropertiesConfig(void) draw_footer_line = TRUE; } + else if (IS_EMPTY_ELEMENT(properties_element)) + { + // draw stickybutton gadget + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_STICK_ELEMENT); + + // draw checkbutton gadgets + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CUSTOM_USE_GRAPHIC); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_CUSTOM_USE_TEMPLATE_1); + + // draw textbutton gadgets + MapTextbuttonGadget(ED_TEXTBUTTON_ID_SAVE_AS_TEMPLATE_1); + + // draw drawing area gadgets + MapDrawingArea(ED_DRAWING_ID_CUSTOM_GRAPHIC); + + draw_footer_line = TRUE; + } // draw little footer border line above CE/GE use/save template gadgets if (draw_footer_line) @@ -10209,11 +13070,10 @@ static void DrawPropertiesChange(void) static void DrawEditorElementAnimation(int x, int y) { - int graphic = el2img(properties_element); - int frame = (ANIM_MODE(graphic) == ANIM_CE_VALUE ? - custom_element.ce_value_fixed_initial : - ANIM_MODE(graphic) == ANIM_CE_SCORE ? - custom_element.collect_score_initial : FrameCounter); + int graphic; + int frame; + + getEditorGraphicAndFrame(properties_element, &graphic, &frame, FALSE); DrawFixedGraphicAnimationExt(drawto, x, y, graphic, frame, NO_MASKING); } @@ -10225,12 +13085,12 @@ static void DrawEditorElementName(int x, int y, int font_nr) int font_height = getFontHeight(font_nr); int max_text_width = SXSIZE - x - ED_ELEMENT_SETTINGS_X(0); int max_chars_per_line = max_text_width / font_width; - char buffer[max_chars_per_line + 1]; if (strlen(element_name) <= max_chars_per_line) DrawTextS(x, y, font_nr, element_name); else { + char buffer[max_chars_per_line + 1]; int next_pos = max_chars_per_line; strncpy(buffer, element_name, max_chars_per_line); @@ -10291,12 +13151,12 @@ static void DrawPropertiesWindow(void) edit_mode_properties = ED_MODE_PROPERTIES_CONFIG_2; if (edit_mode_properties > ED_MODE_PROPERTIES_CONFIG && - !ELEM_IS_PLAYER(properties_element) && + !IS_PLAYER_ELEMENT(properties_element) && !IS_CUSTOM_ELEMENT(properties_element)) edit_mode_properties = ED_MODE_PROPERTIES_CONFIG; if (edit_mode_properties == ED_MODE_PROPERTIES_CONFIG && - (ELEM_IS_PLAYER(properties_element) || + (IS_PLAYER_ELEMENT(properties_element) || IS_CUSTOM_ELEMENT(properties_element))) edit_mode_properties = ED_MODE_PROPERTIES_CONFIG_1; @@ -10306,9 +13166,7 @@ static void DrawPropertiesWindow(void) UnmapLevelEditorToolboxDrawingGadgets(); UnmapLevelEditorToolboxCustomGadgets(); - if (IS_CUSTOM_ELEMENT(properties_element) || - IS_GROUP_ELEMENT(properties_element)) - MapLevelEditorToolboxCustomGadgets(); + MapLevelEditorToolboxCustomGadgetsIfNeeded(); SetMainBackgroundImage(IMG_BACKGROUND_EDITOR); ClearField(); @@ -10617,13 +13475,7 @@ static int getChipFromOpenDirectionNotEmpty(int direction, int element_old) static int getClosedTube(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int direction_old = getOpenDirectionFromTube(element_old); int direction_new = MV_NONE; @@ -10631,8 +13483,8 @@ static int getClosedTube(int x, int y) for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -10647,13 +13499,7 @@ static int getClosedTube(int x, int y) static int getClosedBelt(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int nr = getBeltNrFromBeltElement(element_old); int direction_old = getOpenDirectionFromBelt(element_old); @@ -10662,8 +13508,8 @@ static int getClosedBelt(int x, int y) for (i = MV_BIT_LEFT; i <= MV_BIT_RIGHT; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -10678,13 +13524,7 @@ static int getClosedBelt(int x, int y) static int getClosedPool(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int direction_old = getOpenDirectionFromPool(element_old); int direction_new = MV_NONE; @@ -10692,8 +13532,8 @@ static int getClosedPool(int x, int y) for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -10709,13 +13549,7 @@ static int getClosedPool(int x, int y) static int getClosedPillar(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int direction_old = getOpenDirectionFromPillar(element_old); int direction_new = MV_NONE; @@ -10723,8 +13557,8 @@ static int getClosedPillar(int x, int y) for (i = MV_BIT_UP; i <= MV_BIT_DOWN; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -10739,13 +13573,7 @@ static int getClosedPillar(int x, int y) static int getClosedSteel2(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int direction_old = getOpenDirectionFromSteel2(element_old); int direction_new = MV_NONE; @@ -10753,8 +13581,8 @@ static int getClosedSteel2(int x, int y) for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -10769,13 +13597,7 @@ static int getClosedSteel2(int x, int y) static int getClosedChip(int x, int y) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; int element_old = IntelliDrawBuffer[x][y]; int direction_old = getOpenDirectionFromChip(element_old); int direction_new = MV_NONE; @@ -10783,8 +13605,8 @@ static int getClosedChip(int x, int y) for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; int dir = MV_DIR_FROM_BIT(i); int dir_opposite = MV_DIR_OPPOSITE(dir); @@ -10802,7 +13624,7 @@ static void SetElementSimpleExt(int x, int y, int dx, int dy, int element, { int sx = x - level_xpos; int sy = y - level_ypos; - int old_element = Feld[x][y]; + int old_element = Tile[x][y]; int new_element = element; unsigned int new_bitmask = (getDrawModeHiRes() ? (dx + 1) << (dy * 2) : 0x0f); boolean draw_masked = FALSE; @@ -10828,7 +13650,7 @@ static void SetElementSimpleExt(int x, int y, int dx, int dy, int element, IntelliDrawBuffer[x][y] = element; if (change_level) - Feld[x][y] = element; + Tile[x][y] = element; if (IN_ED_FIELD(sx, sy)) { @@ -10864,16 +13686,10 @@ static void MergeAndCloseNeighbourElements(int x1, int y1, int *element1, SetElementSimple(x2, y2, *element2, change_level); } -static void SetElementIntelliDraw(int x, int y, int new_element, +static void SetElementIntelliDraw(int x, int y, int dx, int dy, int new_element, boolean change_level, int button) { - static int xy[4][2] = - { - { -1, 0 }, - { +1, 0 }, - { 0, -1 }, - { 0, +1 } - }; + struct XY *xy = xy_directions; static int last_x = -1; static int last_y = -1; @@ -10899,8 +13715,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_TUBE(IntelliDrawBuffer[last_x][last_y])) @@ -10937,8 +13753,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = MV_BIT_LEFT; i <= MV_BIT_RIGHT; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_BELT(IntelliDrawBuffer[last_x][last_y])) @@ -10975,8 +13791,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_ACID_POOL_OR_ACID(IntelliDrawBuffer[last_x][last_y])) @@ -11018,8 +13834,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = MV_BIT_UP; i <= MV_BIT_DOWN; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_EMC_PILLAR(IntelliDrawBuffer[last_x][last_y])) @@ -11055,8 +13871,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_DC_STEELWALL_2(IntelliDrawBuffer[last_x][last_y])) @@ -11090,8 +13906,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_SP_CHIP(IntelliDrawBuffer[last_x][last_y])) @@ -11151,8 +13967,8 @@ static void SetElementIntelliDraw(int x, int y, int new_element, for (i = 0; i < NUM_DIRECTIONS; i++) { - int xx = x + xy[i][0]; - int yy = y + xy[i][1]; + int xx = x + xy[i].x; + int yy = y + xy[i].y; if (last_x == xx && last_y == yy && IN_LEV_FIELD(last_x, last_y) && IS_IN_GROUP_EL(IntelliDrawBuffer[last_x][last_y], new_element)) @@ -11353,6 +14169,12 @@ static void SetElementIntelliDraw(int x, int y, int new_element, EL_DF_RECEIVER_DOWN, EL_DF_RECEIVER_LEFT }, + { + EL_DF_SLOPE_1, + EL_DF_SLOPE_4, + EL_DF_SLOPE_3, + EL_DF_SLOPE_2 + }, { -1, @@ -11569,6 +14391,24 @@ static void SetElementIntelliDraw(int x, int y, int new_element, EL_DF_MIRROR_ROTATING_3, EL_DF_MIRROR_ROTATING_2 }, + { + EL_DF_MIRROR_FIXED_1, + EL_DF_MIRROR_FIXED_16, + EL_DF_MIRROR_FIXED_15, + EL_DF_MIRROR_FIXED_14, + EL_DF_MIRROR_FIXED_13, + EL_DF_MIRROR_FIXED_12, + EL_DF_MIRROR_FIXED_11, + EL_DF_MIRROR_FIXED_10, + EL_DF_MIRROR_FIXED_9, + EL_DF_MIRROR_FIXED_8, + EL_DF_MIRROR_FIXED_7, + EL_DF_MIRROR_FIXED_6, + EL_DF_MIRROR_FIXED_5, + EL_DF_MIRROR_FIXED_4, + EL_DF_MIRROR_FIXED_3, + EL_DF_MIRROR_FIXED_2 + }, { -1, @@ -11642,7 +14482,10 @@ static void SetElementIntelliDraw(int x, int y, int new_element, } } - SetElementSimple(x, y, new_element, change_level); + if (IS_MM_WALL_EDITOR(new_element)) + SetElementSimpleExt(x, y, dx, dy, new_element, change_level); + else + SetElementSimple(x, y, new_element, change_level); last_x = x; last_y = y; @@ -11654,9 +14497,9 @@ static void ResetIntelliDraw(void) for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) - IntelliDrawBuffer[x][y] = Feld[x][y]; + IntelliDrawBuffer[x][y] = Tile[x][y]; - SetElementIntelliDraw(-1, -1, EL_UNDEFINED, FALSE, -1); + SetElementIntelliDraw(-1, -1, -1, -1, EL_UNDEFINED, FALSE, -1); } static boolean draw_mode_hires = FALSE; @@ -11671,6 +14514,14 @@ static boolean isHiresDrawElement(int element) return (IS_MM_WALL_EDITOR(element) || element == EL_EMPTY); } +static int numHiresTiles(int element) +{ + if (IS_MM_WALL(element)) + return get_number_of_bits(MM_WALL_BITS(element)); + + return 1; +} + static void SetDrawModeHiRes(int element) { draw_mode_hires = @@ -11697,9 +14548,9 @@ static void SetElementExt(int x, int y, int dx, int dy, int element, boolean change_level, int button) { if (element < 0) - SetElementSimple(x, y, Feld[x][y], change_level); - else if (GetKeyModState() & KMOD_Shift && !IS_MM_WALL_EDITOR(element)) - SetElementIntelliDraw(x, y, element, change_level, button); + SetElementSimple(x, y, Tile[x][y], change_level); + else if (GetKeyModState() & KMOD_Shift) + SetElementIntelliDraw(x, y, dx, dy, element, change_level, button); else SetElementSimpleExt(x, y, dx, dy, element, change_level); } @@ -11741,7 +14592,7 @@ static int getLevelElementHiRes(int lx2, int ly2) int ly = ly2 / 2; int dx = lx2 % 2; int dy = ly2 % 2; - int element = Feld[lx][ly]; + int element = Tile[lx][ly]; unsigned int bitmask = (dx + 1) << (dy * 2); if (IS_MM_WALL(element)) @@ -11901,7 +14752,7 @@ static void DrawCircle(int from_x, int from_y, int to_x, int to_y, DrawArcExt(from_x, from_y, to_x2, to_y2, element, change_level); DrawArcExt(from_x, from_y, mirror_to_x2, to_y2, element, change_level); DrawArcExt(from_x, from_y, to_x2, mirror_to_y2, element, change_level); - DrawArcExt(from_x, from_y, mirror_to_x2, mirror_to_y2, element,change_level); + DrawArcExt(from_x, from_y, mirror_to_x2, mirror_to_y2, element, change_level); } #endif @@ -11958,6 +14809,9 @@ static void SelectArea(int from_x, int from_y, int to_x, int to_y, #define CB_BRUSH_TO_CLIPBOARD 7 #define CB_BRUSH_TO_CLIPBOARD_SMALL 8 #define CB_UPDATE_BRUSH_POSITION 9 +#define CB_FLIP_BRUSH_X 10 +#define CB_FLIP_BRUSH_Y 11 +#define CB_FLIP_BRUSH_XY 12 #define MAX_CB_PART_SIZE 10 #define MAX_CB_LINE_SIZE (MAX_LEV_FIELDX + 1) // text plus newline @@ -11966,6 +14820,185 @@ static void SelectArea(int from_x, int from_y, int to_x, int to_y, MAX_CB_NUM_LINES * \ MAX_CB_PART_SIZE) +static int getFlippedTileExt(int map[], int element) +{ + int i; + + for (i = 0; map[i] != -1; i++) + if (map[i] == element) + return map[i ^ 1]; // get flipped element by flipping LSB of index + + return element; +} + +static int getFlippedTileX(int element) +{ + int map[] = + { + EL_BD_BUTTERFLY_LEFT, EL_BD_BUTTERFLY_RIGHT, + EL_BD_FIREFLY_LEFT, EL_BD_FIREFLY_RIGHT, + EL_BUG_LEFT, EL_BUG_RIGHT, + EL_SPACESHIP_LEFT, EL_SPACESHIP_RIGHT, + EL_PACMAN_LEFT, EL_PACMAN_RIGHT, + EL_ARROW_LEFT, EL_ARROW_RIGHT, + EL_MOLE_LEFT, EL_MOLE_RIGHT, + EL_BALLOON_SWITCH_LEFT, EL_BALLOON_SWITCH_RIGHT, + EL_YAMYAM_LEFT, EL_YAMYAM_RIGHT, + EL_SP_PORT_LEFT, EL_SP_PORT_RIGHT, + EL_SP_GRAVITY_PORT_LEFT, EL_SP_GRAVITY_PORT_RIGHT, + EL_SP_GRAVITY_ON_PORT_LEFT, EL_SP_GRAVITY_ON_PORT_RIGHT, + EL_SP_GRAVITY_OFF_PORT_LEFT, EL_SP_GRAVITY_OFF_PORT_RIGHT, + EL_CONVEYOR_BELT_1_LEFT, EL_CONVEYOR_BELT_1_RIGHT, + EL_CONVEYOR_BELT_2_LEFT, EL_CONVEYOR_BELT_2_RIGHT, + EL_CONVEYOR_BELT_3_LEFT, EL_CONVEYOR_BELT_3_RIGHT, + EL_CONVEYOR_BELT_4_LEFT, EL_CONVEYOR_BELT_4_RIGHT, + EL_SPRING_LEFT, EL_SPRING_RIGHT, + EL_SP_CHIP_LEFT, EL_SP_CHIP_RIGHT, + EL_TUBE_VERTICAL_LEFT, EL_TUBE_VERTICAL_RIGHT, + EL_TUBE_LEFT_UP, EL_TUBE_RIGHT_UP, + EL_TUBE_LEFT_DOWN, EL_TUBE_RIGHT_DOWN, + EL_DC_STEELWALL_1_LEFT, EL_DC_STEELWALL_1_RIGHT, + EL_DC_STEELWALL_1_TOPLEFT, EL_DC_STEELWALL_1_TOPRIGHT, + EL_DC_STEELWALL_1_BOTTOMLEFT, EL_DC_STEELWALL_1_BOTTOMRIGHT, + EL_DC_STEELWALL_1_TOPLEFT_2, EL_DC_STEELWALL_1_TOPRIGHT_2, + EL_DC_STEELWALL_1_BOTTOMLEFT_2, EL_DC_STEELWALL_1_BOTTOMRIGHT_2, + EL_DC_STEELWALL_2_LEFT, EL_DC_STEELWALL_2_RIGHT, + EL_ACID_POOL_TOPLEFT, EL_ACID_POOL_TOPRIGHT, + EL_ACID_POOL_BOTTOMLEFT, EL_ACID_POOL_BOTTOMRIGHT, + + -1 + }; + + return getFlippedTileExt(map, element); +} + +static int getFlippedTileY(int element) +{ + int map[] = + { + EL_BD_BUTTERFLY_UP, EL_BD_BUTTERFLY_DOWN, + EL_BD_FIREFLY_UP, EL_BD_FIREFLY_DOWN, + EL_BUG_UP, EL_BUG_DOWN, + EL_SPACESHIP_UP, EL_SPACESHIP_DOWN, + EL_PACMAN_UP, EL_PACMAN_DOWN, + EL_ARROW_UP, EL_ARROW_DOWN, + EL_MOLE_UP, EL_MOLE_DOWN, + EL_BALLOON_SWITCH_UP, EL_BALLOON_SWITCH_DOWN, + EL_YAMYAM_UP, EL_YAMYAM_DOWN, + EL_SP_PORT_UP, EL_SP_PORT_DOWN, + EL_SP_GRAVITY_PORT_UP, EL_SP_GRAVITY_PORT_DOWN, + EL_SP_GRAVITY_ON_PORT_UP, EL_SP_GRAVITY_ON_PORT_DOWN, + EL_SP_GRAVITY_OFF_PORT_UP, EL_SP_GRAVITY_OFF_PORT_DOWN, + EL_SP_CHIP_TOP, EL_SP_CHIP_BOTTOM, + EL_TUBE_HORIZONTAL_UP, EL_TUBE_HORIZONTAL_DOWN, + EL_TUBE_LEFT_UP, EL_TUBE_LEFT_DOWN, + EL_TUBE_RIGHT_UP, EL_TUBE_RIGHT_DOWN, + EL_DC_STEELWALL_1_TOP, EL_DC_STEELWALL_1_BOTTOM, + EL_DC_STEELWALL_1_TOPLEFT, EL_DC_STEELWALL_1_BOTTOMLEFT, + EL_DC_STEELWALL_1_TOPRIGHT, EL_DC_STEELWALL_1_BOTTOMRIGHT, + EL_DC_STEELWALL_1_TOPLEFT_2, EL_DC_STEELWALL_1_BOTTOMLEFT_2, + EL_DC_STEELWALL_1_TOPRIGHT_2, EL_DC_STEELWALL_1_BOTTOMRIGHT_2, + EL_DC_STEELWALL_2_TOP, EL_DC_STEELWALL_2_BOTTOM, + EL_EMC_WALL_1, EL_EMC_WALL_3, + + -1 + }; + + return getFlippedTileExt(map, element); +} + +static int getFlippedTileXY(int element) +{ + int map[] = + { + EL_BD_BUTTERFLY_LEFT, EL_BD_BUTTERFLY_UP, + EL_BD_BUTTERFLY_RIGHT, EL_BD_BUTTERFLY_DOWN, + EL_BD_FIREFLY_LEFT, EL_BD_FIREFLY_UP, + EL_BD_FIREFLY_RIGHT, EL_BD_FIREFLY_DOWN, + EL_BUG_LEFT, EL_BUG_UP, + EL_BUG_RIGHT, EL_BUG_DOWN, + EL_SPACESHIP_LEFT, EL_SPACESHIP_UP, + EL_SPACESHIP_RIGHT, EL_SPACESHIP_DOWN, + EL_PACMAN_LEFT, EL_PACMAN_UP, + EL_PACMAN_RIGHT, EL_PACMAN_DOWN, + EL_ARROW_LEFT, EL_ARROW_UP, + EL_ARROW_RIGHT, EL_ARROW_DOWN, + EL_MOLE_LEFT, EL_MOLE_UP, + EL_MOLE_RIGHT, EL_MOLE_DOWN, + EL_BALLOON_SWITCH_LEFT, EL_BALLOON_SWITCH_UP, + EL_BALLOON_SWITCH_RIGHT, EL_BALLOON_SWITCH_DOWN, + EL_YAMYAM_LEFT, EL_YAMYAM_UP, + EL_YAMYAM_RIGHT, EL_YAMYAM_DOWN, + EL_SP_PORT_LEFT, EL_SP_PORT_UP, + EL_SP_PORT_RIGHT, EL_SP_PORT_DOWN, + EL_SP_GRAVITY_PORT_LEFT, EL_SP_GRAVITY_PORT_UP, + EL_SP_GRAVITY_PORT_RIGHT, EL_SP_GRAVITY_PORT_DOWN, + EL_SP_GRAVITY_ON_PORT_LEFT, EL_SP_GRAVITY_ON_PORT_UP, + EL_SP_GRAVITY_ON_PORT_RIGHT, EL_SP_GRAVITY_ON_PORT_DOWN, + EL_SP_GRAVITY_OFF_PORT_LEFT, EL_SP_GRAVITY_OFF_PORT_UP, + EL_SP_GRAVITY_OFF_PORT_RIGHT, EL_SP_GRAVITY_OFF_PORT_DOWN, + EL_SP_CHIP_LEFT, EL_SP_CHIP_TOP, + EL_SP_CHIP_RIGHT, EL_SP_CHIP_BOTTOM, + EL_TUBE_VERTICAL, EL_TUBE_HORIZONTAL, + EL_TUBE_VERTICAL_LEFT, EL_TUBE_HORIZONTAL_UP, + EL_TUBE_VERTICAL_RIGHT, EL_TUBE_HORIZONTAL_DOWN, + EL_TUBE_LEFT_DOWN, EL_TUBE_RIGHT_UP, + EL_DC_STEELWALL_1_LEFT, EL_DC_STEELWALL_1_TOP, + EL_DC_STEELWALL_1_RIGHT, EL_DC_STEELWALL_1_BOTTOM, + EL_DC_STEELWALL_1_HORIZONTAL, EL_DC_STEELWALL_1_VERTICAL, + EL_DC_STEELWALL_1_TOPRIGHT, EL_DC_STEELWALL_1_BOTTOMLEFT, + EL_DC_STEELWALL_1_TOPRIGHT_2, EL_DC_STEELWALL_1_BOTTOMLEFT_2, + EL_DC_STEELWALL_2_LEFT, EL_DC_STEELWALL_2_TOP, + EL_DC_STEELWALL_2_RIGHT, EL_DC_STEELWALL_2_BOTTOM, + EL_DC_STEELWALL_2_HORIZONTAL, EL_DC_STEELWALL_2_VERTICAL, + EL_EXPANDABLE_WALL_HORIZONTAL, EL_EXPANDABLE_WALL_VERTICAL, + EL_EXPANDABLE_STEELWALL_HORIZONTAL, EL_EXPANDABLE_STEELWALL_VERTICAL, + + -1 + }; + + return getFlippedTileExt(map, element); +} + +static int getFlippedTile(int element, int mode) +{ + if (IS_MM_ELEMENT(element)) + { + // get MM game element + element = map_element_RND_to_MM(element); + + // get flipped game element + element = (mode == CB_FLIP_BRUSH_X ? getFlippedTileX_MM(element) : + mode == CB_FLIP_BRUSH_Y ? getFlippedTileY_MM(element) : + mode == CB_FLIP_BRUSH_XY ? getFlippedTileXY_MM(element) : + element); + + // get RND game element again + element = map_element_MM_to_RND(element); + } + else + { + // get flipped game element + element = (mode == CB_FLIP_BRUSH_X ? getFlippedTileX(element) : + mode == CB_FLIP_BRUSH_Y ? getFlippedTileY(element) : + mode == CB_FLIP_BRUSH_XY ? getFlippedTileXY(element) : + element); + } + + return element; +} + +static void SwapFlippedTiles(short *tile1, short *tile2, int mode) +{ + // flip tiles + short tile1_flipped = getFlippedTile(*tile1, mode); + short tile2_flipped = getFlippedTile(*tile2, mode); + + // swap tiles + *tile1 = tile2_flipped; + *tile2 = tile1_flipped; +} + static void DrawBrushElement(int sx, int sy, int element, boolean change_level) { DrawLineElement(sx, sy, element, change_level); @@ -11993,27 +15026,28 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, char text[MAX_CB_TEXT_SIZE + 1] = ""; int width = (draw_with_brush ? brush_width : lev_fieldx); int height = (draw_with_brush ? brush_height : lev_fieldy); + char *format = "%s%03d"; + + for (y = 0; y < height; y++) + for (x = 0; x < width; x++) + if ((draw_with_brush ? brush_buffer[x][y] : Tile[x][y]) > 999) + format = "%s%04d"; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { - int element = (draw_with_brush ? brush_buffer[x][y] : Feld[x][y]); - int element_mapped = element; + int element = (draw_with_brush ? brush_buffer[x][y] : Tile[x][y]); char *prefix = (mode == CB_DUMP_BRUSH || mode == CB_BRUSH_TO_CLIPBOARD ? "`" : "¸"); - if (IS_CUSTOM_ELEMENT(element)) - element_mapped = EL_CUSTOM_START; - else if (IS_GROUP_ELEMENT(element)) - element_mapped = EL_GROUP_START; - else if (element >= NUM_FILE_ELEMENTS) - element_mapped = EL_UNKNOWN; + if (element >= NUM_FILE_ELEMENTS) + element = EL_UNKNOWN; // copy brush to level sketch text buffer for the R'n'D forum: - // - large tiles: `xxx (0x60 ASCII) - // - small tiles: ¸xxx (0xb8 ISO-8859-1, 0xc2b8 UTF-8) - snprintf(part, MAX_CB_PART_SIZE + 1, "%s%03d", prefix, element_mapped); + // - large tiles: `xxx or `xxxx (0x60 ASCII) + // - small tiles: ¸xxx or ¸xxxx (0xb8 ISO-8859-1, 0xc2b8 UTF-8) + snprintf(part, MAX_CB_PART_SIZE + 1, format, prefix, element); strcat(text, part); } @@ -12024,7 +15058,7 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, mode == CB_BRUSH_TO_CLIPBOARD_SMALL) SDL_SetClipboardText(text); else - printf("%s", text); + Print("%s", text); // print brush data to console and log file return; } @@ -12060,11 +15094,13 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, char *clipboard_text = SDL_GetClipboardText(); char *ptr = clipboard_text; + boolean allow_new_row = FALSE; boolean stop = FALSE; while (*ptr && !stop) { boolean prefix_found = FALSE; + boolean start_new_row = FALSE; // level sketch element number prefixes (may be multi-byte characters) char *prefix_list[] = { "`", "¸" }; @@ -12093,19 +15129,10 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, } } - // continue with next character if prefix not found - if (!prefix_found) - { - ptr++; // !!! FIX THIS for real UTF-8 handling !!! - - continue; - } - - // continue with next character if prefix not found - if (strlen(ptr) < 3) - break; - - if (ptr[0] >= '0' && ptr[0] <= '9' && + // check if prefix found and followed by (at least) three digits + if (prefix_found && + strlen(ptr) >= 3 && + ptr[0] >= '0' && ptr[0] <= '9' && ptr[1] >= '0' && ptr[1] <= '9' && ptr[2] >= '0' && ptr[2] <= '9') { @@ -12115,6 +15142,16 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, ptr += 3; + // level sketch element number might consist of four digits + if (ptr[0] >= '0' && ptr[0] <= '9') + { + element = element * 10 + (ptr[0] - '0'); + ptr++; + } + + // remap some (historic, now obsolete) elements + element = getMappedElement(element); + if (element >= NUM_FILE_ELEMENTS) element = EL_UNKNOWN; @@ -12125,14 +15162,28 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, x++; - if (x >= MAX_LEV_FIELDX || *ptr == '\n') - { - x = 0; - y++; + if (x >= MAX_LEV_FIELDX) + start_new_row = TRUE; - if (y >= MAX_LEV_FIELDY) - stop = TRUE; - } + allow_new_row = TRUE; + } + else + { + if ((*ptr == '\n' || *ptr == '\r') && allow_new_row) + start_new_row = TRUE; + + ptr++; // !!! FIX THIS for real UTF-8 handling !!! + } + + if (start_new_row) + { + x = 0; + y++; + + if (y >= MAX_LEV_FIELDY) + stop = TRUE; + + allow_new_row = FALSE; } } @@ -12171,11 +15222,46 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, for (x = 0; x < MAX_LEV_FIELDX; x++) for (y = 0; y < MAX_LEV_FIELDY; y++) - Feld[x][y] = brush_buffer[x][y]; + Tile[x][y] = brush_buffer[x][y]; lev_fieldx = level.fieldx = brush_width; lev_fieldy = level.fieldy = brush_height; + boolean use_bd_engine = TRUE; + boolean use_em_engine = TRUE; + boolean use_sp_engine = TRUE; + boolean use_mm_engine = TRUE; + + for (x = 0; x < MAX_LEV_FIELDX; x++) + { + for (y = 0; y < MAX_LEV_FIELDY; y++) + { + int element = Tile[x][y]; + + if (!IS_BD_ELEMENT(element) && !IS_PLAYER_ELEMENT(element)) + use_bd_engine = FALSE; + + if (!IS_EM_ELEMENT(element) && !IS_PLAYER_ELEMENT(element)) + use_em_engine = FALSE; + + if (!IS_SP_ELEMENT(element)) + use_sp_engine = FALSE; + + if (!IS_MM_ELEMENT(element) && element != EL_EMPTY) + use_mm_engine = FALSE; + } + } + + level.game_engine_type = (use_bd_engine ? GAME_ENGINE_TYPE_BD : + use_em_engine ? GAME_ENGINE_TYPE_EM : + use_sp_engine ? GAME_ENGINE_TYPE_SP : + use_mm_engine ? GAME_ENGINE_TYPE_MM : + GAME_ENGINE_TYPE_RND); + + // update element selection list + ReinitializeElementList(); + ModifyEditorElementList(); + SetBorderElement(); DrawEditModeWindow(); @@ -12208,7 +15294,7 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, { for (x = 0; x < brush_width; x++) { - brush_buffer[x][y] = Feld[from_lx + x][from_ly + y]; + brush_buffer[x][y] = Tile[from_lx + x][from_ly + y]; if (button != 1) DrawBrushElement(from_x + x, from_y + y, new_element, TRUE); @@ -12278,6 +15364,37 @@ static void CopyBrushExt(int from_x, int from_y, int to_x, int to_y, delete_old_brush = TRUE; } + else if (mode == CB_FLIP_BRUSH_X) + { + for (y = 0; y < brush_height; y++) + for (x = 0; x < (brush_width + 1) / 2; x++) + SwapFlippedTiles(&brush_buffer[x][y], + &brush_buffer[brush_width - x - 1][y], mode); + + CopyBrushExt(last_cursor_x, last_cursor_y, 0, 0, 0, CB_BRUSH_TO_CURSOR); + } + else if (mode == CB_FLIP_BRUSH_Y) + { + for (y = 0; y < (brush_height + 1) / 2; y++) + for (x = 0; x < brush_width; x++) + SwapFlippedTiles(&brush_buffer[x][y], + &brush_buffer[x][brush_height - y - 1], mode); + + CopyBrushExt(last_cursor_x, last_cursor_y, 0, 0, 0, CB_BRUSH_TO_CURSOR); + } + else if (mode == CB_FLIP_BRUSH_XY) + { + CopyBrushExt(0, 0, 0, 0, 0, CB_DELETE_OLD_CURSOR); + + for (y = 0; y < MAX(brush_width, brush_height); y++) + for (x = 0; x <= y; x++) + SwapFlippedTiles(&brush_buffer[x][y], + &brush_buffer[y][x], mode); + + swap_numbers(&brush_width, &brush_height); + + CopyBrushExt(last_cursor_x, last_cursor_y, 0, 0, 0, CB_BRUSH_TO_CURSOR); + } if (mode == CB_UPDATE_BRUSH_POSITION) { @@ -12312,6 +15429,22 @@ static void DeleteBrushFromCursor(void) CopyBrushExt(0, 0, 0, 0, 0, CB_DELETE_OLD_CURSOR); } +static void FlipBrushX(void) +{ + CopyBrushExt(0, 0, 0, 0, 0, CB_FLIP_BRUSH_X); +} + +static void FlipBrushY(void) +{ + CopyBrushExt(0, 0, 0, 0, 0, CB_FLIP_BRUSH_Y); +} + +static void RotateBrush(void) +{ + CopyBrushExt(0, 0, 0, 0, 0, CB_FLIP_BRUSH_XY); + CopyBrushExt(0, 0, 0, 0, 0, CB_FLIP_BRUSH_X); +} + void DumpBrush(void) { CopyBrushExt(0, 0, 0, 0, 0, CB_DUMP_BRUSH); @@ -12337,9 +15470,19 @@ void CopyBrushToClipboard_Small(void) CopyBrushExt(0, 0, 0, 0, 0, CB_BRUSH_TO_CLIPBOARD_SMALL); } +void UndoLevelEditorOperation(void) +{ + ClickOnGadget(level_editor_gadget[GADGET_ID_UNDO], -1); +} + +void RedoLevelEditorOperation(void) +{ + ClickOnGadget(level_editor_gadget[GADGET_ID_UNDO], 3); +} + static void FloodFill(int from_x, int from_y, int fill_element) { - FloodFillLevel(from_x, from_y, fill_element, Feld, lev_fieldx, lev_fieldy); + FloodFillLevel(from_x, from_y, fill_element, Tile, lev_fieldx, lev_fieldy); } static void FloodFillWall_MM(int from_sx2, int from_sy2, int fill_element) @@ -12348,20 +15491,20 @@ static void FloodFillWall_MM(int from_sx2, int from_sy2, int fill_element) int from_y = from_sy2 + 2 * level_ypos; int max_fillx = lev_fieldx * 2; int max_filly = lev_fieldy * 2; - short FillFeld[max_fillx][max_filly]; + short Fill[max_fillx][max_filly]; int x, y; for (x = 0; x < max_fillx; x++) for (y = 0; y < max_filly; y++) - FillFeld[x][y] = getLevelElementHiRes(x, y); + Fill[x][y] = getLevelElementHiRes(x, y); FloodFillLevelExt(from_x, from_y, fill_element, max_fillx, max_filly, - FillFeld, max_fillx, max_filly); + Fill, max_fillx, max_filly); for (x = 0; x < max_fillx; x++) for (y = 0; y < max_filly; y++) - if (FillFeld[x][y] == fill_element) - SetLevelElementHiRes(x, y, FillFeld[x][y]); + if (Fill[x][y] == fill_element) + SetLevelElementHiRes(x, y, Fill[x][y]); } // values for DrawLevelText() modes @@ -12379,7 +15522,7 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) static int start_sx; static int last_sx, last_sy; static boolean typing = FALSE; - int letter_element = EL_CHAR_ASCII0 + letter; + int letter_element; int lx = 0, ly = 0; // map lower case letters to upper case and convert special characters @@ -12425,7 +15568,7 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) break; case TEXT_SETCURSOR: - DrawEditorElement(last_sx, last_sy, Feld[lx][ly]); + DrawEditorElement(last_sx, last_sy, Tile[lx][ly]); DrawAreaBorder(sx, sy, sx, sy); StartTextInput(SX + sx * ed_tilesize, SY + sy * ed_tilesize, ed_tilesize, ed_tilesize); @@ -12440,8 +15583,8 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) new_element1 <= EL_STEEL_CHAR_END) letter_element = letter_element - EL_CHAR_START + EL_STEEL_CHAR_START; - delete_buffer[sx - start_sx] = Feld[lx][ly]; - Feld[lx][ly] = letter_element; + delete_buffer[sx - start_sx] = Tile[lx][ly]; + Tile[lx][ly] = letter_element; if (sx + 1 < ed_fieldx && lx + 1 < lev_fieldx) DrawLevelText(sx + 1, sy, 0, TEXT_SETCURSOR); @@ -12457,8 +15600,8 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) case TEXT_BACKSPACE: if (sx > start_sx) { - Feld[lx - 1][ly] = delete_buffer[sx - start_sx - 1]; - DrawEditorElement(sx - 1, sy, Feld[lx - 1][ly]); + Tile[lx - 1][ly] = delete_buffer[sx - start_sx - 1]; + DrawEditorElement(sx - 1, sy, Tile[lx - 1][ly]); DrawLevelText(sx - 1, sy, 0, TEXT_SETCURSOR); } break; @@ -12472,7 +15615,7 @@ static int DrawLevelText(int sx, int sy, char letter, int mode) case TEXT_END: CopyLevelToUndoBuffer(UNDO_IMMEDIATE); - DrawEditorElement(sx, sy, Feld[lx][ly]); + DrawEditorElement(sx, sy, Tile[lx][ly]); StopTextInput(); typing = FALSE; break; @@ -12494,7 +15637,7 @@ static void SetTextCursor(int unused_sx, int unused_sy, int sx, int sy, int ly = sy + level_ypos; if (element == -1) - DrawEditorElement(sx, sy, Feld[lx][ly]); + DrawEditorElement(sx, sy, Tile[lx][ly]); else DrawAreaBorder(sx, sy, sx, sy); } @@ -12548,7 +15691,7 @@ static void CopyLevelToUndoBuffer(int mode) for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) - UndoBuffer[undo_buffer_position][x][y] = Feld[x][y]; + UndoBuffer[undo_buffer_position][x][y] = Tile[x][y]; // check if drawing operation forces change of border style CheckLevelBorderElement(TRUE); @@ -12570,8 +15713,8 @@ static void RandomPlacement(int new_element) { free_position[x][y] = (random_placement_background_restricted ? - Feld[x][y] == random_placement_background_element : - Feld[x][y] != new_element); + Tile[x][y] == random_placement_background_element : + Tile[x][y] != new_element); if (free_position[x][y]) num_free_positions++; @@ -12619,17 +15762,98 @@ static void WrapLevel(int dx, int dy) for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) - FieldBackup[x][y] = Feld[x][y]; + TileBackup[x][y] = Tile[x][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]; + Tile[x][y] = + TileBackup[(x + wrap_dx) % lev_fieldx][(y + wrap_dy) % lev_fieldy]; DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); CopyLevelToUndoBuffer(UNDO_ACCUMULATE); } +static void DrawAreaElementHighlight(boolean highlighted, + boolean highlighted_similar) +{ + DrawEditorLevel(ed_fieldx, ed_fieldy, level_xpos, level_ypos); + + if (!highlighted) + return; + + int x, y; + + for (x = 0; x < ed_fieldx; x++) + { + for (y = 0; y < ed_fieldy; y++) + { + boolean highlight = FALSE; + int lx = x + level_xpos; + int ly = y + level_ypos; + + if (!IN_LEV_FIELD(lx, ly)) + continue; + + // check if element is the same + if (Tile[lx][ly] == new_element1) + highlight = TRUE; + + // check if element is similar + if (highlighted_similar && + strEqual(element_info[Tile[lx][ly]].class_name, + element_info[new_element1].class_name)) + highlight = TRUE; + + // check if element is matching MM style wall + if (IS_MM_WALL(Tile[lx][ly]) && + map_mm_wall_element(Tile[lx][ly]) == new_element1) + highlight = TRUE; + + if (!highlight) + continue; + + if (IS_MM_WALL(Tile[lx][ly]) && !highlighted_similar) + { + int i; + + for (i = 0; i < 4; i++) + { + if (!(MM_WALL_BITS(Tile[lx][ly]) & (1 << i))) + continue; + + int xx = x * 2 + (i % 2); + int yy = y * 2 + (i / 2); + int sx = SX + xx * ed_tilesize / 2; + int sy = SY + yy * ed_tilesize / 2; + int from_sx = sx; + int from_sy = sy; + int to_sx = sx + ed_tilesize / 2 - 1; + int to_sy = sy + ed_tilesize / 2 - 1; + + DrawSimpleWhiteLine(drawto, from_sx, from_sy, to_sx, from_sy); + DrawSimpleWhiteLine(drawto, to_sx, from_sy, to_sx, to_sy); + DrawSimpleWhiteLine(drawto, to_sx, to_sy, from_sx, to_sy); + DrawSimpleWhiteLine(drawto, from_sx, to_sy, from_sx, from_sy); + } + } + else + { + int sx = SX + x * ed_tilesize; + int sy = SY + y * ed_tilesize; + int from_sx = sx; + int from_sy = sy; + int to_sx = sx + ed_tilesize - 1; + int to_sy = sy + ed_tilesize - 1; + + DrawSimpleWhiteLine(drawto, from_sx, from_sy, to_sx, from_sy); + DrawSimpleWhiteLine(drawto, to_sx, from_sy, to_sx, to_sy); + DrawSimpleWhiteLine(drawto, to_sx, to_sy, from_sx, to_sy); + DrawSimpleWhiteLine(drawto, from_sx, to_sy, from_sx, from_sy); + } + } + } +} + static void CopyLevelTemplateToUserLevelSet(char *levelset_subdir) { char *template_filename_old = getLocalLevelTemplateFilename(); @@ -12645,8 +15869,10 @@ static void CopyLevelTemplateToUserLevelSet(char *levelset_subdir) static void HandleDrawingAreas(struct GadgetInfo *gi) { static boolean started_inside_drawing_area = FALSE; - static int last_sx = -1, last_sy = -1; - static int last_sx2 = -1, last_sy2 = -1; + static int last_sx = -1; + static int last_sy = -1; + static int last_sx2 = -1; + static int last_sy2 = -1; int id = gi->custom_id; int type_id = gi->custom_type_id; boolean button_press_event; @@ -12666,8 +15892,6 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) int dx = sx2 % 2; int dy = sy2 % 2; int lx = 0, ly = 0; - int min_lx = 0, min_ly = 0; - int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1; int x, y; button_press_event = (gi->event.type == GD_EVENT_PRESSED); @@ -12679,6 +15903,9 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (draw_level) { + int min_lx = 0, min_ly = 0; + int max_lx = lev_fieldx - 1, max_ly = lev_fieldy - 1; + // get positions inside level field lx = sx + level_xpos; ly = sy + level_ypos; @@ -12707,16 +15934,9 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) sy2 = sy * 2 + dy; } - if (button_release_event) - { - last_sx = -1; - last_sy = -1; - last_sx2 = -1; - last_sy2 = -1; - } - else if (!button_press_event) + if (!button_press_event && !button_release_event) { - int old_element = (IN_LEV_FIELD(lx, ly) ? Feld[lx][ly] : EL_UNDEFINED); + int old_element = (IN_LEV_FIELD(lx, ly) ? Tile[lx][ly] : EL_UNDEFINED); boolean hires_drawing = (level.game_engine_type == GAME_ENGINE_TYPE_MM && isHiresTileElement(old_element) && isHiresDrawElement(new_element)); @@ -12741,9 +15961,6 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (!IS_VALID_BUTTON(button)) return; - if (!button && !button_release_event) - return; - // handle info callback for each invocation of action callback gi->callback_info(gi); @@ -12779,10 +15996,9 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (edit_mode == ED_MODE_DRAWING && draw_with_brush && !inside_drawing_area) DeleteBrushFromCursor(); - } - if (!button || button_release_event) break; + } if (draw_with_brush) { @@ -12792,16 +16008,17 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) { SetDrawModeHiRes(new_element); - if (ELEM_IS_PLAYER(new_element)) + if (IS_PLAYER_ELEMENT(new_element) || IS_MM_MCDUFFIN(new_element)) { // remove player at old position for (y = 0; y < lev_fieldy; y++) { for (x = 0; x < lev_fieldx; x++) { - int old_element = Feld[x][y]; + int old_element = Tile[x][y]; - if (ELEM_IS_PLAYER(old_element)) + if (IS_PLAYER_ELEMENT(old_element) && + IS_PLAYER_ELEMENT(new_element)) { int replaced_with_element = (old_element == EL_SOKOBAN_FIELD_PLAYER && @@ -12821,6 +16038,12 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) SetElement(x, y, replaced_with_element); } + else if (IS_MM_MCDUFFIN(old_element) && + IS_MM_MCDUFFIN(new_element)) + { + // remove McDuffin at old position + SetElement(x, y, EL_EMPTY); + } } } } @@ -12867,22 +16090,19 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) if (button_release_event) CopyLevelToUndoBuffer(UNDO_IMMEDIATE); - if (button) - { - SetDrawModeHiRes(new_element); + SetDrawModeHiRes(new_element); - if (getDrawModeHiRes()) - { - sx = sx2; - sy = sy2; - } + if (getDrawModeHiRes()) + { + sx = sx2; + sy = sy2; + } - if (!button_press_event) - DrawLine(last_sx, last_sy, sx, sy, new_element, TRUE); + if (!button_press_event) + DrawLine(last_sx, last_sy, sx, sy, new_element, TRUE); - last_sx = sx; - last_sy = sy; - } + last_sx = sx; + last_sy = sy; } break; @@ -12958,7 +16178,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) break; case GADGET_ID_FLOOD_FILL: - if (button_press_event && Feld[lx][ly] != new_element) + if (button_press_event && Tile[lx][ly] != new_element) { if (IS_MM_WALL_EDITOR(new_element)) FloodFillWall_MM(sx2, sy2, new_element); @@ -12975,7 +16195,7 @@ static void HandleDrawingAreas(struct GadgetInfo *gi) ClickOnGadget(level_editor_gadget[last_drawing_function], MB_LEFTBUTTON); else if (draw_level) - PickDrawingElement(button, Feld[lx][ly]); + PickDrawingElement(button, Tile[lx][ly]); else { int pos = sx * drawingarea_info[type_id].area_ysize + sy; @@ -13065,11 +16285,11 @@ static void HandleCounterButtons(struct GadgetInfo *gi) break; case ED_COUNTER_ID_ANDROID_CONTENT: - DrawAndroidElementArea(properties_element); + DrawAndroidElementArea(); break; case ED_COUNTER_ID_GROUP_CONTENT: - DrawGroupElementArea(properties_element); + DrawGroupElementArea(); CopyGroupElementPropertiesToGame(properties_element); break; @@ -13077,6 +16297,10 @@ static void HandleCounterButtons(struct GadgetInfo *gi) DrawPlayerInitialInventoryArea(properties_element); break; + case ED_COUNTER_ID_MM_BALL_CONTENT: + DrawMMBallContentArea(); + break; + case ED_COUNTER_ID_ENVELOPE_XSIZE: case ED_COUNTER_ID_ENVELOPE_YSIZE: DrawEnvelopeTextArea(-1); @@ -13124,6 +16348,15 @@ static void HandleTextInputGadgets(struct GadgetInfo *gi) ModifyEditorElementList(); // update changed button info text } + else if (type_id >= ED_TEXTINPUT_ID_COLORS_FIRST && + type_id <= ED_TEXTINPUT_ID_COLORS_LAST) + { + int pos = type_id - ED_TEXTINPUT_ID_COLORS_FIRST; + + *bd_color[pos] = gd_color_get_from_string(bd_color_text[pos]); + + DrawColorBox_BD(pos); + } // do not mark level as modified for certain non-level-changing gadgets if (type_id >= ED_TEXTINPUT_ID_LEVELSET_FIRST && @@ -13154,7 +16387,7 @@ static void HandleSelectboxGadgets(struct GadgetInfo *gi) if (type_id == ED_SELECTBOX_ID_LEVELSET_SAVE_MODE) { - DrawLevelInfoWindow(); + DrawLevelConfigWindow(); } else if (type_id == ED_SELECTBOX_ID_SELECT_CHANGE_PAGE) { @@ -13181,10 +16414,49 @@ static void HandleSelectboxGadgets(struct GadgetInfo *gi) } else if (type_id == ED_SELECTBOX_ID_GAME_ENGINE_TYPE) { - // update element selection list + // show or hide "engine" tabulator depending on game engine type + DrawLevelConfigWindow(); + + // update element selection list depending on game engine type ReinitializeElementList(); ModifyEditorElementList(); } + else if (type_id == ED_SELECTBOX_ID_BD_SCHEDULING_TYPE) + { + // update BD cycle delay counter gadgets depending on BD scheduling type + DrawLevelConfigWindow(); + } + else if (type_id == ED_SELECTBOX_ID_BD_COLOR_TYPE) + { + bd_color_type_changed = TRUE; + + if (level.bd_color_type != GD_COLOR_TYPE_RGB && level.bd_color_type != GetCommonColorType_BD()) + { + // color type switched to non-RGB colors, but using different color type => reset colors + char *message = (level.bd_color_type == bd_color_type_default ? + "This will reset colors to defaults! Continue?" : + "This will reset colors to random colors! Continue?"); + + if (!Request(message, REQ_ASK)) + { + // keep current RGB colors + level.bd_color_type = GD_COLOR_TYPE_RGB; + bd_color_type_changed = FALSE; + } + } + + // update BD color palette gadgets depending on BD color type + DrawLevelConfigWindow(); + } + else if (type_id >= ED_SELECTBOX_ID_COLORS_FIRST && + type_id <= ED_SELECTBOX_ID_COLORS_LAST) + { + int pos = type_id - ED_SELECTBOX_ID_COLORS_FIRST; + + *bd_color[pos] = gd_c64_color(bd_color_c64[pos]); + + DrawColorBox_BD(pos); + } // do not mark level as modified for certain non-level-changing gadgets if (type_id == ED_SELECTBOX_ID_LEVELSET_SAVE_MODE || @@ -13199,12 +16471,19 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) int type_id = gi->custom_type_id; int i; - if (type_id >= ED_TAB_BUTTON_ID_LEVELINFO_FIRST && - type_id <= ED_TAB_BUTTON_ID_LEVELINFO_LAST) + if (type_id >= ED_TAB_BUTTON_ID_LEVELCONFIG_FIRST && + type_id <= ED_TAB_BUTTON_ID_LEVELCONFIG_LAST) { - edit_mode_levelinfo = gi->custom_type_id; + edit_mode_levelconfig = gi->custom_type_id; - DrawLevelInfoWindow(); + DrawLevelConfigWindow(); + } + else if (type_id >= ED_TAB_BUTTON_ID_ENGINECONFIG_FIRST && + type_id <= ED_TAB_BUTTON_ID_ENGINECONFIG_LAST) + { + edit_mode_engineconfig = gi->custom_type_id; + + DrawLevelConfigWindow(); } else if (type_id >= ED_TAB_BUTTON_ID_PROPERTIES_FIRST && type_id <= ED_TAB_BUTTON_ID_PROPERTIES_LAST) @@ -13219,10 +16498,10 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) boolean new_template = !fileExists(getLocalLevelTemplateFilename()); // backup original "level.field" (needed to track playfield changes) - CopyPlayfield(level.field, FieldBackup); + CopyPlayfield(level.field, TileBackup); // "SaveLevelTemplate()" uses "level.field", so copy editor playfield - CopyPlayfield(Feld, level.field); + CopyPlayfield(Tile, level.field); if (new_template || Request("Save this template and kill the old?", REQ_ASK)) @@ -13232,7 +16511,7 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) Request("Template saved!", REQ_CONFIRM); // restore original "level.field" (needed to track playfield changes) - CopyPlayfield(FieldBackup, level.field); + CopyPlayfield(TileBackup, level.field); } else if (type_id == ED_TEXTBUTTON_ID_SAVE_LEVELSET) { @@ -13241,7 +16520,7 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) if (levelset_save_mode == LEVELSET_SAVE_MODE_UPDATE && leveldir_current->readonly) { - Request("This level set is read only!", REQ_CONFIRM); + Request("This level set is read-only!", REQ_CONFIRM); return; } @@ -13340,6 +16619,13 @@ static void HandleTextbuttonGadgets(struct GadgetInfo *gi) level.changed = TRUE; } + else if (type_id == ED_TEXTBUTTON_ID_BD_SET_RANDOM_COLORS) + { + SetRandomLevelColors_BD(level.bd_color_type); + + // update BD color palette gadgets after setting random colors + DrawLevelConfigWindow(); + } } static void HandleGraphicbuttonGadgets(struct GadgetInfo *gi) @@ -13432,9 +16718,11 @@ static void HandleCheckbuttons(struct GadgetInfo *gi) boolean template_related_changes_found = FALSE; int i; - // check if any custom or group elements have been changed + // check if any custom, group or empty elements have been changed for (i = 0; i < NUM_FILE_ELEMENTS; i++) - if ((IS_CUSTOM_ELEMENT(i) || IS_GROUP_ELEMENT(i)) && + if ((IS_CUSTOM_ELEMENT(i) || + IS_GROUP_ELEMENT(i) || + IS_EMPTY_ELEMENT(i)) && element_info[i].modified_settings) template_related_changes_found = TRUE; @@ -13702,7 +16990,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) } else { - ChangeEditModeWindow(last_edit_mode); + ChangeEditModeWindow(ED_MODE_DRAWING); ClickOnGadget(level_editor_gadget[last_level_drawing_function], MB_LEFTBUTTON); @@ -13764,6 +17052,10 @@ static void HandleControlButtons(struct GadgetInfo *gi) button == 2 ? ed_tilesize_default : button == 3 ? ed_tilesize / 2 : ed_tilesize); + // when using touch device, cycle through all zoom tilesizes + if (runtime.uses_touch_device && ed_tilesize > TILESIZE) + ed_tilesize = MICRO_TILESIZE; + // limit zoom level by upper and lower bound ed_tilesize = MIN(MAX(MICRO_TILESIZE, ed_tilesize), TILESIZE); @@ -13798,7 +17090,9 @@ static void HandleControlButtons(struct GadgetInfo *gi) break; case GADGET_ID_UNDO: - if (button == 1 && GetKeyModState() & (KMOD_Shift|KMOD_Control)) + if (button < 0) // keep button value (even if modifier keys are pressed) + button = -button; + else if (button == 1 && GetKeyModState() & (KMOD_Shift | KMOD_Control)) button = 3; if (button == 1 && undo_buffer_steps == 0) @@ -13843,7 +17137,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) for (x = 0; x < lev_fieldx; x++) for (y = 0; y < lev_fieldy; y++) - Feld[x][y] = UndoBuffer[undo_buffer_position][x][y]; + Tile[x][y] = UndoBuffer[undo_buffer_position][x][y]; // check if undo operation forces change of border style CheckLevelBorderElement(FALSE); @@ -13852,16 +17146,16 @@ static void HandleControlButtons(struct GadgetInfo *gi) break; - case GADGET_ID_INFO: - if (edit_mode != ED_MODE_INFO) + case GADGET_ID_CONF: + if (edit_mode != ED_MODE_LEVELCONFIG) { last_edit_mode = edit_mode; - ChangeEditModeWindow(ED_MODE_INFO); + ChangeEditModeWindow(ED_MODE_LEVELCONFIG); } else { - ChangeEditModeWindow(last_edit_mode); + ChangeEditModeWindow(ED_MODE_DRAWING); } break; @@ -13871,7 +17165,7 @@ static void HandleControlButtons(struct GadgetInfo *gi) for (x = 0; x < MAX_LEV_FIELDX; x++) for (y = 0; y < MAX_LEV_FIELDY; y++) - Feld[x][y] = (button == 1 ? EL_EMPTY : new_element); + Tile[x][y] = (button == 1 ? EL_EMPTY : new_element); CopyLevelToUndoBuffer(GADGET_ID_CLEAR); @@ -13898,11 +17192,11 @@ static void HandleControlButtons(struct GadgetInfo *gi) Request("Save this level and kill the old?", REQ_ASK)) { if (leveldir_former->readonly) - ModifyLevelInfoForSavingIntoPersonalLevelSet(leveldir_former->name); + ModifyLevelConfigForSavingIntoPersonalLevelSet(leveldir_former->name); SetAutomaticNumberOfGemsNeeded(); - CopyPlayfield(Feld, level.field); + CopyPlayfield(Tile, level.field); SaveLevel(level_nr); level.changed = FALSE; @@ -13933,8 +17227,8 @@ static void HandleControlButtons(struct GadgetInfo *gi) if (LevelChanged()) level.game_version = GAME_VERSION_ACTUAL; - CopyPlayfield(level.field, FieldBackup); - CopyPlayfield(Feld, level.field); + CopyPlayfield(level.field, TileBackup); + CopyPlayfield(Tile, level.field); CopyNativeLevel_RND_to_Native(&level); @@ -13963,7 +17257,8 @@ static void HandleControlButtons(struct GadgetInfo *gi) id <= GADGET_ID_ELEMENTLIST_LAST) { int element_position = id - GADGET_ID_ELEMENTLIST_FIRST; - int new_element = editor_elements[element_position + element_shift]; + + new_element = editor_elements[element_position + element_shift]; if (IS_EDITOR_CASCADE(new_element)) { @@ -13971,8 +17266,8 @@ static void HandleControlButtons(struct GadgetInfo *gi) for (i = 0; editor_elements_info[i].setup_value != NULL; i++) { - int *cascade_element= &(*editor_elements_info[i].headline_list)[0]; - boolean *cascade_value=editor_elements_info[i].setup_cascade_value; + int *cascade_element = &(*editor_elements_info[i].headline_list)[0]; + boolean *cascade_value = editor_elements_info[i].setup_cascade_value; if (*cascade_element == new_element) { @@ -14034,13 +17329,13 @@ static void HandleControlButtons(struct GadgetInfo *gi) } #ifdef DEBUG else if (gi->event.type == GD_EVENT_PRESSED) - printf("default: HandleControlButtons: GD_EVENT_PRESSED(%d)\n", id); + Debug("editor", "default: HandleControlButtons: GD_EVENT_PRESSED(%d)", id); else if (gi->event.type == GD_EVENT_RELEASED) - printf("default: HandleControlButtons: GD_EVENT_RELEASED(%d)\n", id); + Debug("editor", "default: HandleControlButtons: GD_EVENT_RELEASED(%d)", id); else if (gi->event.type == GD_EVENT_MOVING) - printf("default: HandleControlButtons: GD_EVENT_MOVING(%d)\n", id); + Debug("editor", "default: HandleControlButtons: GD_EVENT_MOVING(%d)", id); else - printf("default: HandleControlButtons: ? (id == %d)\n", id); + Debug("editor", "default: HandleControlButtons: ? (id == %d)", id); #endif break; } @@ -14049,7 +17344,6 @@ static void HandleControlButtons(struct GadgetInfo *gi) void HandleLevelEditorKeyInput(Key key) { char letter = getCharFromKey(key); - int button = MB_LEFTBUTTON; if (drawing_function == GADGET_ID_TEXT && DrawLevelText(0, 0, 0, TEXT_QUERY_TYPING) == TRUE) @@ -14062,165 +17356,164 @@ void HandleLevelEditorKeyInput(Key key) DrawLevelText(0, 0, 0, TEXT_NEWLINE); else if (key == KSYM_Escape) DrawLevelText(0, 0, 0, TEXT_END); + + return; } - else if (button_status == MB_RELEASED) + + int id = GADGET_ID_NONE; + int new_element_shift = element_shift; + int step = ED_ELEMENTLIST_BUTTONS_VERT - 1; + int button = MB_LEFTBUTTON; + int i; + + switch (key) { - int id = GADGET_ID_NONE; - int new_element_shift = element_shift; - int step = ED_ELEMENTLIST_BUTTONS_VERT - 1; - int i; + case KSYM_Left: + id = GADGET_ID_SCROLL_LEFT; + break; + case KSYM_Right: + id = GADGET_ID_SCROLL_RIGHT; + break; + case KSYM_Up: + id = GADGET_ID_SCROLL_UP; + break; + case KSYM_Down: + id = GADGET_ID_SCROLL_DOWN; + break; - switch (key) - { - case KSYM_Left: - id = GADGET_ID_SCROLL_LEFT; - break; - case KSYM_Right: - id = GADGET_ID_SCROLL_RIGHT; - break; - case KSYM_Up: - id = GADGET_ID_SCROLL_UP; - break; - case KSYM_Down: - id = GADGET_ID_SCROLL_DOWN; - break; + case KSYM_Page_Up: + case KSYM_Page_Down: + step *= (key == KSYM_Page_Up ? -1 : +1); + element_shift += step * ED_ELEMENTLIST_BUTTONS_HORIZ; - case KSYM_Page_Up: - case KSYM_Page_Down: - step *= (key == KSYM_Page_Up ? -1 : +1); - element_shift += step * ED_ELEMENTLIST_BUTTONS_HORIZ; + if (element_shift < 0) + element_shift = 0; + if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS) + element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS; - if (element_shift < 0) - element_shift = 0; - if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS) - element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS; + ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL], + GDI_SCROLLBAR_ITEM_POSITION, + element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END); - ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL], - GDI_SCROLLBAR_ITEM_POSITION, - element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END); + ModifyEditorElementList(); - ModifyEditorElementList(); + break; - break; + case KSYM_Home: + case KSYM_End: + element_shift = (key == KSYM_Home ? 0 : + num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS); - case KSYM_Home: - case KSYM_End: - element_shift = (key == KSYM_Home ? 0 : - num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS); + ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL], + GDI_SCROLLBAR_ITEM_POSITION, + element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END); - ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL], - GDI_SCROLLBAR_ITEM_POSITION, - element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END); + ModifyEditorElementList(); - ModifyEditorElementList(); + break; - break; + case KSYM_Insert: + case KSYM_Delete: - case KSYM_Insert: - case KSYM_Delete: + // this is needed to prevent interference with running "True X-Mouse" + if (GetKeyModStateFromEvents() & KMOD_Control) + break; - // this is needed to prevent interference with running "True X-Mouse" - if (GetKeyModStateFromEvents() & KMOD_Control) + // check for last or next editor cascade block in element list + for (i = 0; i < num_editor_elements; i++) + { + if ((key == KSYM_Insert && i == element_shift) || + (key == KSYM_Delete && new_element_shift > element_shift)) break; - // check for last or next editor cascade block in element list - for (i = 0; i < num_editor_elements; i++) - { - if ((key == KSYM_Insert && i == element_shift) || - (key == KSYM_Delete && new_element_shift > element_shift)) - break; - - // jump to next cascade block (or to start of element list) - if (i == 0 || IS_EDITOR_CASCADE(editor_elements[i])) - new_element_shift = i; - } + // jump to next cascade block (or to start of element list) + if (i == 0 || IS_EDITOR_CASCADE(editor_elements[i])) + new_element_shift = i; + } - if (i < num_editor_elements) - element_shift = new_element_shift; + if (i < num_editor_elements) + element_shift = new_element_shift; - if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS) - element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS; + if (element_shift > num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS) + element_shift = num_editor_elements - ED_NUM_ELEMENTLIST_BUTTONS; - ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL], - GDI_SCROLLBAR_ITEM_POSITION, - element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END); + ModifyGadget(level_editor_gadget[GADGET_ID_SCROLL_LIST_VERTICAL], + GDI_SCROLLBAR_ITEM_POSITION, + element_shift / ED_ELEMENTLIST_BUTTONS_HORIZ, GDI_END); - ModifyEditorElementList(); + ModifyEditorElementList(); - break; + break; - case KSYM_Escape: - if (edit_mode == ED_MODE_DRAWING) - { - RequestExitLevelEditor(setup.ask_on_escape_editor, TRUE); - } - else if (edit_mode == ED_MODE_INFO) - { - HandleControlButtons(level_editor_gadget[GADGET_ID_INFO]); - } - else if (edit_mode == ED_MODE_PROPERTIES) - { - HandleControlButtons(level_editor_gadget[GADGET_ID_PROPERTIES]); - } - else if (edit_mode == ED_MODE_PALETTE) - { - HandleControlButtons(level_editor_gadget[GADGET_ID_PALETTE]); - } - else // should never happen - { - ChangeEditModeWindow(ED_MODE_DRAWING); - } + case KSYM_Escape: + if (edit_mode == ED_MODE_DRAWING) + RequestExitLevelEditor(setup.ask_on_escape_editor, TRUE); + else if (edit_mode == ED_MODE_LEVELCONFIG) + HandleControlButtons(level_editor_gadget[GADGET_ID_CONF]); + else if (edit_mode == ED_MODE_PROPERTIES) + HandleControlButtons(level_editor_gadget[GADGET_ID_PROPERTIES]); + else if (edit_mode == ED_MODE_PALETTE) + HandleControlButtons(level_editor_gadget[GADGET_ID_PALETTE]); + else // should never happen + ChangeEditModeWindow(ED_MODE_DRAWING); - break; + break; - default: - break; - } + default: + break; + } - if (id != GADGET_ID_NONE) - ClickOnGadget(level_editor_gadget[id], button); - else if (letter == '1' || letter == '?') - ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_LEFT], button); - else if (letter == '2') - ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_MIDDLE], button); - else if (letter == '3') - ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_RIGHT], button); - else if (letter == '.') - ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS], button); - else if (letter == 'U') - ClickOnGadget(level_editor_gadget[GADGET_ID_UNDO], 3); - else if (letter == '-' || key == KSYM_KP_Subtract) - ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 3); - else if (letter == '0' || key == KSYM_KP_0) - ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 2); - else if (letter == '+' || key == KSYM_KP_Add || - letter == '=') // ("Shift-=" is "+" on US keyboards) - ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 1); - else if (key == KSYM_Return || - key == KSYM_space || - key == setup.shortcut.toggle_pause) - ClickOnGadget(level_editor_gadget[GADGET_ID_TEST], button); - else - for (i = 0; i < ED_NUM_CTRL_BUTTONS; i++) - if (letter && letter == controlbutton_info[i].shortcut) - if (!anyTextGadgetActive()) - ClickOnGadget(level_editor_gadget[i], button); + if (id != GADGET_ID_NONE) + ClickOnGadget(level_editor_gadget[id], button); + else if (letter == '1' || letter == '?') + ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_LEFT], button); + else if (letter == '2') + ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_MIDDLE], button); + else if (letter == '3') + ClickOnGadget(level_editor_gadget[GADGET_ID_ELEMENT_RIGHT], button); + else if (letter == '.') + ClickOnGadget(level_editor_gadget[GADGET_ID_SINGLE_ITEMS], button); + else if (letter == 'U') + ClickOnGadget(level_editor_gadget[GADGET_ID_UNDO], 3); + else if (letter == '-' || key == KSYM_KP_Subtract) + ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 3); + else if (letter == '0' || key == KSYM_KP_0) + ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 2); + else if (letter == '+' || key == KSYM_KP_Add || + letter == '=') // ("Shift-=" is "+" on US keyboards) + ClickOnGadget(level_editor_gadget[GADGET_ID_ZOOM], 1); + else if (key == KSYM_Return || + key == KSYM_space || + key == setup.shortcut.toggle_pause) + ClickOnGadget(level_editor_gadget[GADGET_ID_TEST], button); + else + for (i = 0; i < ED_NUM_CTRL_BUTTONS; i++) + if (letter && letter == controlbutton_info[i].shortcut) + if (!anyTextGadgetActive()) + ClickOnGadget(level_editor_gadget[i], button); + + if (draw_with_brush) + { + if (letter == 'x') + FlipBrushX(); + else if (letter == 'y') + FlipBrushY(); + else if (letter == 'z') + RotateBrush(); } } -void HandleLevelEditorIdle(void) +static void HandleLevelEditorIdle_Properties(void) { int element_border = graphic_info[IMG_EDITOR_ELEMENT_BORDER].border_size; int x = editor.settings.element_graphic.x + element_border; int y = editor.settings.element_graphic.y + element_border; - static unsigned int action_delay = 0; - unsigned int action_delay_value = GameFrameDelay; + static DelayCounter action_delay = { 0 }; int i; - if (edit_mode != ED_MODE_PROPERTIES) - return; + action_delay.value = GameFrameDelay; - if (!DelayReached(&action_delay, action_delay_value)) + if (!DelayReached(&action_delay)) return; for (i = 0; i < ED_NUM_SELECTBOX; i++) @@ -14238,6 +17531,33 @@ void HandleLevelEditorIdle(void) FrameCounter++; // increase animation frame counter } +static void HandleLevelEditorIdle_Drawing(void) +{ + static boolean last_highlighted = FALSE; + static boolean last_highlighted_similar = FALSE; + boolean highlighted = (GetKeyModState() & KMOD_Alt); + boolean highlighted_similar = (GetKeyModState() & KMOD_Shift); + + if (highlighted != last_highlighted || + (highlighted && highlighted_similar != last_highlighted_similar)) + { + DrawAreaElementHighlight(highlighted, highlighted_similar); + + redraw_mask |= REDRAW_FIELD; + } + + last_highlighted = highlighted; + last_highlighted_similar = highlighted_similar; +} + +void HandleLevelEditorIdle(void) +{ + if (edit_mode == ED_MODE_PROPERTIES) + HandleLevelEditorIdle_Properties(); + else if (edit_mode == ED_MODE_DRAWING) + HandleLevelEditorIdle_Drawing(); +} + static void ClearEditorGadgetInfoText(void) { DrawBackground(INFOTEXT_XPOS, INFOTEXT_YPOS, INFOTEXT_XSIZE, INFOTEXT_YSIZE); @@ -14246,7 +17566,6 @@ static void ClearEditorGadgetInfoText(void) void PrintEditorGadgetInfoText(struct GadgetInfo *gi) { char infotext[MAX_OUTPUT_LINESIZE + 1]; - char shortcut[MAX_OUTPUT_LINESIZE + 1]; int max_infotext_len = getMaxInfoTextLength(); if (gi == NULL || strlen(gi->info_text) == 0) @@ -14261,6 +17580,8 @@ void PrintEditorGadgetInfoText(struct GadgetInfo *gi) if (key) { + char shortcut[MAX_OUTPUT_LINESIZE + 1]; + if (gi->custom_id == GADGET_ID_SINGLE_ITEMS) sprintf(shortcut, " ('.' or '%c')", key); else if (gi->custom_id == GADGET_ID_PICK_ELEMENT) @@ -14304,7 +17625,6 @@ void HandleEditorGadgetInfoText(void *ptr) static void HandleDrawingAreaInfo(struct GadgetInfo *gi) { - static int start_lx, start_ly; int id = gi->custom_id; int type_id = gi->custom_type_id; int sx = gi->event.x; @@ -14317,7 +17637,6 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) int actual_drawing_function = drawing_function; int max_infotext_len = getMaxInfoTextLength(); char infotext[MAX_OUTPUT_LINESIZE + 1]; - char *text; infotext[0] = '\0'; // start with empty info text @@ -14354,10 +17673,14 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) sy = ly - level_ypos; } - if (IN_ED_FIELD(sx,sy) && IN_LEV_FIELD(lx, ly)) + if (IN_ED_FIELD(sx, sy) && IN_LEV_FIELD(lx, ly)) { if (button_status) // if (gi->state == GD_BUTTON_PRESSED) { + static int start_lx = 0; + static int start_ly = 0; + char *text; + if (gi->event.type == GD_EVENT_PRESSED) { start_lx = lx; @@ -14409,7 +17732,7 @@ static void HandleDrawingAreaInfo(struct GadgetInfo *gi) ABS(lx - start_lx) + 1, ABS(ly - start_ly) + 1); } else if (actual_drawing_function == GADGET_ID_PICK_ELEMENT) - strncpy(infotext, getElementInfoText(Feld[lx][ly]), max_infotext_len); + strncpy(infotext, getElementInfoText(Tile[lx][ly]), max_infotext_len); else sprintf(infotext, "Level position: %d, %d", lx, ly); } @@ -14488,7 +17811,7 @@ void RequestExitLevelEditor(boolean ask_if_level_has_changed, vp_door_2->height == VYSIZE) CloseDoor(DOOR_CLOSE_ALL | DOOR_NO_DELAY); else - SetDoorState(DOOR_CLOSE_2); + SetDoorState(DOOR_CLOSE_ALL); BackToFront();