/* ---------- initialize font graphic definitions ---------- */
/* always start with reliable default values (normal font graphics) */
+#if 1
+ for (i=0; i < NUM_FONTS; i++)
+ font_info[i].graphic = IMG_FONT_INITIAL_1;
+#else
for (i=0; i < NUM_FONTS; i++)
font_info[i].graphic = FONT_INITIAL_1;
+#endif
/* initialize normal font/graphic mapping from static configuration */
for (i=0; font_to_graphic[i].font_nr > -1; i++)
}
}
+#if 1
+ /* now set all undefined/invalid graphics to -1 to set to default after it */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ {
+ for (act=0; act<NUM_ACTIONS; act++)
+ {
+ int graphic;
+
+ graphic = element_info[i].graphic[act];
+ if (graphic > 0 && graphic_info[graphic].bitmap == NULL)
+ element_info[i].graphic[act] = -1;
+
+ graphic = element_info[i].crumbled[act];
+ if (graphic > 0 && graphic_info[graphic].bitmap == NULL)
+ element_info[i].crumbled[act] = -1;
+
+ for (dir=0; dir<NUM_DIRECTIONS; dir++)
+ {
+ graphic = element_info[i].direction_graphic[act][dir];
+ if (graphic > 0 && graphic_info[graphic].bitmap == NULL)
+ element_info[i].direction_graphic[act][dir] = -1;
+
+ graphic = element_info[i].direction_crumbled[act][dir];
+ if (graphic > 0 && graphic_info[graphic].bitmap == NULL)
+ element_info[i].direction_crumbled[act][dir] = -1;
+ }
+ }
+ }
+#endif
+
/* now set all '-1' values to element specific default values */
for (i=0; i<MAX_NUM_ELEMENTS; i++)
{
for (act=0; act<NUM_ACTIONS; act++)
{
- boolean act_remove = (act == ACTION_DIGGING ||
- act == ACTION_SNAPPING ||
- act == ACTION_COLLECTING);
+ boolean act_remove = ((IS_DIGGABLE(i) && act == ACTION_DIGGING) ||
+ (IS_SNAPPABLE(i) && act == ACTION_SNAPPING) ||
+ (IS_COLLECTIBLE(i) && act == ACTION_COLLECTING));
/* generic default action graphic (defined by "[default]" directive) */
int default_action_graphic = element_info[EL_DEFAULT].graphic[act];
}
}
+#if 1
+ /* set animation mode to "none" for each graphic with only 1 frame */
+ for (i=0; i<MAX_NUM_ELEMENTS; i++)
+ {
+ for (act=0; act<NUM_ACTIONS; act++)
+ {
+ int graphic = element_info[i].graphic[act];
+ int crumbled = element_info[i].crumbled[act];
+
+ if (graphic_info[graphic].anim_frames == 1)
+ graphic_info[graphic].anim_mode = ANIM_NONE;
+ if (graphic_info[crumbled].anim_frames == 1)
+ graphic_info[crumbled].anim_mode = ANIM_NONE;
+
+ for (dir=0; dir<NUM_DIRECTIONS; dir++)
+ {
+ graphic = element_info[i].direction_graphic[act][dir];
+ crumbled = element_info[i].direction_crumbled[act][dir];
+
+ if (graphic_info[graphic].anim_frames == 1)
+ graphic_info[graphic].anim_mode = ANIM_NONE;
+ if (graphic_info[crumbled].anim_frames == 1)
+ graphic_info[crumbled].anim_mode = ANIM_NONE;
+ }
+ }
+ }
+#endif
+
#if 0
#if DEBUG
if (options.verbose)
if (special >= 0 && special < NUM_SPECIAL_GFX_ARGS)
element_info[element].special_graphic[special] = graphic;
}
+
+#if 1
+ /* now set all undefined/invalid graphics to default */
+ for (i=0; i < MAX_NUM_ELEMENTS; i++)
+ for (j=0; j < NUM_SPECIAL_GFX_ARGS; j++)
+ if (graphic_info[element_info[i].special_graphic[j]].bitmap == NULL)
+ element_info[i].special_graphic[j] =
+ element_info[i].graphic[ACTION_DEFAULT];
+#endif
}
static int get_element_from_token(char *token)
graphic_info[graphic].offset_y = 0; /* ... will be corrected later */
graphic_info[graphic].crumbled_like = -1; /* do not use clone element */
graphic_info[graphic].diggable_like = -1; /* do not use clone element */
+ graphic_info[graphic].border_size = TILEX / 8; /* "CRUMBLED" border size */
/* optional x and y tile position of animation frame sequence */
if (parameter[GFX_ARG_XPOS] != ARG_UNDEFINED_VALUE)
graphic_info[graphic].anim_delay = 1;
graphic_info[graphic].anim_mode = parameter[GFX_ARG_ANIM_MODE];
+#if 0
if (graphic_info[graphic].anim_frames == 1)
graphic_info[graphic].anim_mode = ANIM_NONE;
+#endif
/* automatically determine correct start frame, if not defined */
if (parameter[GFX_ARG_START_FRAME] == ARG_UNDEFINED_VALUE)
if (parameter[GFX_ARG_DIGGABLE_LIKE] != ARG_UNDEFINED_VALUE)
graphic_info[graphic].diggable_like = parameter[GFX_ARG_DIGGABLE_LIKE];
+ /* optional border size for "crumbling" diggable graphics */
+ if (parameter[GFX_ARG_BORDER_SIZE] != ARG_UNDEFINED_VALUE)
+ graphic_info[graphic].border_size = parameter[GFX_ARG_BORDER_SIZE];
+
/* this is only used for toon animations */
graphic_info[graphic].step_offset = parameter[GFX_ARG_STEP_OFFSET];
graphic_info[graphic].step_delay = parameter[GFX_ARG_STEP_DELAY];
/* this is only used for drawing font characters */
graphic_info[graphic].draw_x = parameter[GFX_ARG_DRAW_XOFFSET];
graphic_info[graphic].draw_y = parameter[GFX_ARG_DRAW_YOFFSET];
+
+ /* this is only used for drawing envelope graphics */
+ graphic_info[graphic].draw_masked = parameter[GFX_ARG_DRAW_MASKED];
}
static void InitGraphicInfo()
graphic_info = checked_calloc(num_images * sizeof(struct GraphicInfo));
+#if 0
+ printf("::: graphic_info: %d entries\n", num_images);
+#endif
+
#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
if (clipmasks_initialized)
{
int first_frame, last_frame;
#if 0
- printf("::: image: '%s'\n", image->token);
+ printf("::: image: '%s' [%d]\n", image->token, i);
#endif
#if 0
-1
};
- static int ep_collectible[] =
+ static int ep_collectible_only[] =
{
EL_BD_DIAMOND,
EL_EMERALD,
EL_SHIELD_NORMAL,
EL_SHIELD_DEADLY,
EL_EXTRA_TIME,
- EL_ENVELOPE,
+ EL_ENVELOPE_1,
+ EL_ENVELOPE_2,
+ EL_ENVELOPE_3,
+ EL_ENVELOPE_4,
EL_SPEED_PILL,
-1
};
/* !!! maybe this should better be handled by 'ep_diggable' !!! */
#if 1
- EL_SP_BUGGY_BASE_ACTIVE,
- EL_TRAP_ACTIVE,
EL_LANDMINE,
+ EL_TRAP_ACTIVE,
+ EL_SP_BUGGY_BASE_ACTIVE,
#endif
-1
};
EL_SOKOBAN_FIELD_EMPTY,
EL_EXIT_OPEN,
EL_SP_EXIT_OPEN,
+ EL_SP_EXIT_OPENING,
EL_GATE_1,
EL_GATE_2,
EL_GATE_3,
-1
};
+ static int ep_droppable[] =
+ {
+ -1
+ };
+
+ static int ep_can_explode_1x1[] =
+ {
+ -1
+ };
+
static int ep_pushable[] =
{
EL_ROCK,
-1
};
- static int ep_can_be_crumbled[] =
- {
- EL_SAND,
- EL_LANDMINE,
- EL_TRAP,
- EL_TRAP_ACTIVE,
- -1
- };
-
static int ep_player[] =
{
EL_PLAYER_1,
EL_PLAYER_2,
EL_PLAYER_3,
EL_PLAYER_4,
+ EL_SP_MURPHY,
-1
};
static int ep_sp_element[] =
{
+ /* should always be valid */
+ EL_EMPTY,
+
EL_SP_EMPTY,
EL_SP_ZONK,
EL_SP_BASE,
EL_SP_TERMINAL_ACTIVE,
EL_SP_BUGGY_BASE_ACTIVATING,
EL_SP_BUGGY_BASE_ACTIVE,
+ EL_SP_EXIT_OPENING,
+ EL_SP_EXIT_CLOSING,
-1
};
-1
};
+ static int ep_em_slippery_wall[] =
+ {
+ -1
+ };
+
+ static int ep_gfx_crumbled[] =
+ {
+ EL_SAND,
+ EL_LANDMINE,
+ EL_TRAP,
+ EL_TRAP_ACTIVE,
+ -1
+ };
+
static struct
{
int *elements;
} element_properties[] =
{
{ ep_diggable, EP_DIGGABLE },
- { ep_collectible, EP_COLLECTIBLE },
+ { ep_collectible_only, EP_COLLECTIBLE_ONLY },
{ ep_dont_run_into, EP_DONT_RUN_INTO },
{ ep_dont_collide_with, EP_DONT_COLLIDE_WITH },
{ ep_dont_touch, EP_DONT_TOUCH },
{ ep_passable_over, EP_PASSABLE_OVER },
{ ep_passable_inside, EP_PASSABLE_INSIDE },
{ ep_passable_under, EP_PASSABLE_UNDER },
+ { ep_droppable, EP_DROPPABLE },
+ { ep_can_explode_1x1, EP_CAN_EXPLODE_1X1 },
{ ep_pushable, EP_PUSHABLE },
- { ep_can_be_crumbled, EP_CAN_BE_CRUMBLED },
-
{ ep_player, EP_PLAYER },
{ ep_can_pass_magic_wall, EP_CAN_PASS_MAGIC_WALL },
{ ep_switchable, EP_SWITCHABLE },
{ ep_active_bomb, EP_ACTIVE_BOMB },
{ ep_inactive, EP_INACTIVE },
+ { ep_em_slippery_wall, EP_EM_SLIPPERY_WALL },
+
+ { ep_gfx_crumbled, EP_GFX_CRUMBLED },
+
{ NULL, -1 }
};
EP_BELT_SWITCH,
EP_WALKABLE_UNDER,
EP_EM_SLIPPERY_WALL,
- EP_CAN_BE_CRUMBLED,
};
#endif
static int no_wall_properties[] =
{
EP_DIGGABLE,
- EP_COLLECTIBLE,
+ EP_COLLECTIBLE_ONLY,
EP_DONT_RUN_INTO,
EP_DONT_COLLIDE_WITH,
EP_CAN_MOVE,
EP_CAN_SMASH_EVERYTHING,
EP_PUSHABLE,
- EP_CAN_BE_CRUMBLED,
-
EP_PLAYER,
EP_GEM,
EP_FOOD_DARK_YAMYAM,
SET_PROPERTY(i, EP_ACCESSIBLE, (IS_WALKABLE(i) ||
IS_PASSABLE(i)));
+ /* ---------- COLLECTIBLE ---------------------------------------------- */
+ SET_PROPERTY(i, EP_COLLECTIBLE, (IS_COLLECTIBLE_ONLY(i) ||
+ IS_DROPPABLE(i)));
+
/* ---------- SNAPPABLE ------------------------------------------------ */
SET_PROPERTY(i, EP_SNAPPABLE, (IS_DIGGABLE(i) ||
IS_COLLECTIBLE(i) ||
CAN_EXPLODE_SMASHED(i) ||
CAN_EXPLODE_IMPACT(i)));
- /* ---------- CAN_BE_CRUMBLED ------------------------------------------ */
- SET_PROPERTY(i, EP_CAN_BE_CRUMBLED,
- element_info[i].crumbled[ACTION_DEFAULT] != IMG_EMPTY);
+ /* ---------- CAN_EXPLODE_3X3 ------------------------------------------ */
+ SET_PROPERTY(i, EP_CAN_EXPLODE_3X3, (CAN_EXPLODE(i) &&
+ !CAN_EXPLODE_1X1(i)));
-#if 0
- if (CAN_BE_CRUMBLED(i))
- printf("::: '%s' can be crumbled [%d]\n",
- element_info[i].token_name,
- element_info[i].crumbled[ACTION_DEFAULT]);
-#endif
+ /* ---------- CAN_CHANGE ----------------------------------------------- */
+ SET_PROPERTY(i, EP_CAN_CHANGE, FALSE); /* default: cannot change */
+ for (j=0; j < element_info[i].num_change_pages; j++)
+ if (element_info[i].change_page[j].can_change)
+ SET_PROPERTY(i, EP_CAN_CHANGE, TRUE);
+
+ /* ---------- GFX_CRUMBLED --------------------------------------------- */
+ SET_PROPERTY(i, EP_GFX_CRUMBLED,
+ element_info[i].crumbled[ACTION_DEFAULT] != IMG_EMPTY);
}
#if 0
(level.em_slippery_gems &&
engine_version > VERSION_IDENT(2,0,1)));
}
-
-#if 0
- /* dynamically adjust element properties according to game engine version */
-#if 0
- if (engine_version < RELEASE_IDENT(2,2,0,7))
-#endif
- {
- for (i=0; i < NUM_CUSTOM_ELEMENTS; i++)
- {
- int element = EL_CUSTOM_START + i;
-
- element_info[element].push_delay_fixed = 2;
- element_info[element].push_delay_random = 8;
- }
- }
-#endif
}
static void InitGlobal()
static void InitImages()
{
+#if 1
setLevelArtworkDir(artwork.gfx_first);
+#endif
#if 0
printf("::: InitImages for '%s' ['%s', '%s'] ['%s', '%s']\n",
if (identifier == NULL)
identifier = artwork.snd_current->identifier;
+#if 1
/* set artwork path to send it to the sound server process */
setLevelArtworkDir(artwork.snd_first);
+#endif
InitReloadCustomSounds(identifier);
ReinitializeSounds();
if (identifier == NULL)
identifier = artwork.mus_current->identifier;
+#if 1
/* set artwork path to send it to the sound server process */
setLevelArtworkDir(artwork.mus_first);
+#endif
InitReloadCustomMusic(identifier);
ReinitializeMusic();
boolean setup_override_artwork = SETUP_OVERRIDE_ARTWORK(setup, type);
char *setup_artwork_set = SETUP_ARTWORK_SET(setup, type);
char *leveldir_identifier = leveldir_current->identifier;
+#if 1
+ /* !!! setLevelArtworkDir() should be moved to an earlier stage !!! */
+ char *leveldir_artwork_set = setLevelArtworkDir(artwork_first_node);
+#else
char *leveldir_artwork_set = LEVELDIR_ARTWORK_SET(leveldir_current, type);
+#endif
boolean has_level_artwork_set = (leveldir_artwork_set != NULL);
char *artwork_current_identifier;
char *artwork_new_identifier = NULL; /* default: nothing has changed */
if (!validLevelSeries(leveldir_current))
return NULL;
-
/* 1st step: determine artwork set to be activated in descending order:
--------------------------------------------------------------------
1. setup artwork (when configured to override everything else)
/* 2nd step: check if it is really needed to reload artwork set
------------------------------------------------------------ */
+#if 0
+ if (type == ARTWORK_TYPE_GRAPHICS)
+ printf("::: 0: '%s' ['%s', '%s'] ['%s' ('%s')]\n",
+ artwork_new_identifier,
+ ARTWORK_CURRENT_IDENTIFIER(artwork, type),
+ artwork_current_identifier,
+ leveldir_current->graphics_set,
+ leveldir_current->identifier);
+#endif
+
/* ---------- reload if level set and also artwork set has changed ------- */
if (leveldir_current_identifier[type] != leveldir_identifier &&
(last_has_level_artwork_set[type] || has_level_artwork_set))
leveldir_current_identifier[type] = leveldir_identifier;
last_has_level_artwork_set[type] = has_level_artwork_set;
+#if 0
+ if (type == ARTWORK_TYPE_GRAPHICS)
+ printf("::: 1: '%s'\n", artwork_new_identifier);
+#endif
+
/* ---------- reload if "override artwork" setting has changed ----------- */
if (last_override_level_artwork[type] != setup_override_artwork)
artwork_new_identifier = artwork_current_identifier;
last_override_level_artwork[type] = setup_override_artwork;
+#if 0
+ if (type == ARTWORK_TYPE_GRAPHICS)
+ printf("::: 2: '%s'\n", artwork_new_identifier);
+#endif
+
/* ---------- reload if current artwork identifier has changed ----------- */
if (strcmp(ARTWORK_CURRENT_IDENTIFIER(artwork, type),
artwork_current_identifier) != 0)
*(&(ARTWORK_CURRENT_IDENTIFIER(artwork, type))) = artwork_current_identifier;
+#if 0
+ if (type == ARTWORK_TYPE_GRAPHICS)
+ printf("::: 3: '%s'\n", artwork_new_identifier);
+#endif
+
/* ---------- do not reload directly after starting ---------------------- */
if (!initialized[type])
artwork_new_identifier = NULL;
initialized[type] = TRUE;
#if 0
- printf("CHECKING OLD/NEW GFX:\n- OLD: %s\n- NEW: %s ['%s', '%s'] ['%s']\n",
- artwork.gfx_current_identifier, artwork_current_identifier,
- artwork.gfx_current->identifier, leveldir_current->graphics_set,
- artwork_new_identifier);
+ if (type == ARTWORK_TYPE_GRAPHICS)
+ printf("::: 4: '%s'\n", artwork_new_identifier);
+#endif
+
+#if 0
+ if (type == ARTWORK_TYPE_GRAPHICS)
+ printf("CHECKING OLD/NEW GFX:\n- OLD: %s\n- NEW: %s ['%s', '%s'] ['%s']\n",
+ artwork.gfx_current_identifier, artwork_current_identifier,
+ artwork.gfx_current->identifier, leveldir_current->graphics_set,
+ artwork_new_identifier);
#endif
return artwork_new_identifier;
if (gfx_new_identifier != NULL)
{
#if 0
- printf("RELOADING GRAPHICS '%s' -> '%s' ['%s']\n",
+ printf("RELOADING GRAPHICS '%s' -> '%s' ['%s', '%s']\n",
artwork.gfx_current_identifier,
gfx_new_identifier,
- artwork.gfx_current->identifier);
+ artwork.gfx_current->identifier,
+ leveldir_current->graphics_set);
#endif
ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE);
InitImages();
+#if 0
+ printf("... '%s'\n",
+ leveldir_current->graphics_set);
+#endif
+
FreeTileClipmasks();
InitTileClipmasks();
InitEventFilter(FilterMouseMotionEvents);
InitElementPropertiesStatic();
+ InitElementPropertiesEngine(GAME_VERSION_ACTUAL);
InitGfx();