-/***********************************************************
-* Rocks'n'Diamonds -- McDuffin Strikes Back! *
-*----------------------------------------------------------*
-* (c) 1995-2006 Artsoft Entertainment *
-* Holger Schemel *
-* Detmolder Strasse 189 *
-* 33604 Bielefeld *
-* Germany *
-* e-mail: info@artsoft.org *
-*----------------------------------------------------------*
-* init.c *
-***********************************************************/
+// ============================================================================
+// Rocks'n'Diamonds - McDuffin Strikes Back!
+// ----------------------------------------------------------------------------
+// (c) 1995-2014 by Artsoft Entertainment
+// Holger Schemel
+// info@artsoft.org
+// http://www.artsoft.org/
+// ----------------------------------------------------------------------------
+// init.c
+// ============================================================================
#include "libgame/libgame.h"
#include "files.h"
#include "network.h"
#include "netserv.h"
-#include "cartoons.h"
+#include "anim.h"
#include "config.h"
#include "conf_e2g.c" /* include auto-generated data structure definitions */
#define CONFIG_TOKEN_FONT_INITIAL "font.initial"
#define CONFIG_TOKEN_GLOBAL_BUSY "global.busy"
-#define DEBUG_PRINT_INIT_TIMESTAMPS TRUE
-#define DEBUG_PRINT_INIT_TIMESTAMPS_DEPTH 5
-
static struct FontBitmapInfo font_initial[NUM_INITIAL_FONTS];
static struct GraphicInfo anim_initial;
};
-static void print_init_timestamp(char *message)
-{
-#if DEBUG
-#if DEBUG_PRINT_INIT_TIMESTAMPS
- static char *last_message = NULL;
- static int counter_nr = 0;
- int max_depth = DEBUG_PRINT_INIT_TIMESTAMPS_DEPTH;
-
- if (strEqualPrefix(message, "INIT"))
- {
- if (counter_nr + 1 < max_depth)
- {
- debug_print_timestamp(counter_nr, NULL);
- debug_print_timestamp(counter_nr, message);
- }
-
- counter_nr++;
-
- debug_print_timestamp(counter_nr, NULL);
- }
- else if (strEqualPrefix(message, "DONE"))
- {
- counter_nr--;
-
- if (counter_nr + 1 < max_depth)
- {
- last_message = &message[4];
+/* forward declaration for internal use */
+static int get_graphic_parameter_value(char *, char *, int);
- debug_print_timestamp(counter_nr, message);
- }
- }
- else if (!strEqualPrefix(message, "TIME") ||
- !strEqualSuffix(message, last_message))
- {
- if (counter_nr < max_depth)
- debug_print_timestamp(counter_nr, message);
- }
-#endif
-#endif
-}
void DrawInitAnim()
{
struct GraphicInfo *graphic_info_last = graphic_info;
int graphic = 0;
- static unsigned long action_delay = 0;
- unsigned long action_delay_value = GameFrameDelay;
+ static unsigned int action_delay = 0;
+ unsigned int action_delay_value = GameFrameDelay;
int sync_frame = FrameCounter;
int x, y;
+ /* prevent OS (Windows) from complaining about program not responding */
+ CheckQuitEvent();
+
+ if (game_status != GAME_MODE_LOADING)
+ return;
+
if (anim_initial.bitmap == NULL || window == NULL)
return;
if (!DelayReached(&action_delay, action_delay_value))
return;
-#if 0
- {
- static unsigned long last_counter = -1;
- unsigned long current_counter = Counter();
- unsigned long delay = current_counter - last_counter;
-
- if (last_counter != -1 && delay > action_delay_value + 5)
- printf("::: DrawInitAnim: DELAY TOO LONG: %ld\n", delay);
-
- last_counter = current_counter;
- }
-#endif
-
- anim_initial.anim_mode = ANIM_LOOP;
- anim_initial.anim_start_frame = 0;
- anim_initial.offset_x = anim_initial.width;
- anim_initial.offset_y = 0;
+ if (init_last.busy.x == -1)
+ init_last.busy.x = WIN_XSIZE / 2;
+ if (init_last.busy.y == -1)
+ init_last.busy.y = WIN_YSIZE / 2;
- x = WIN_XSIZE / 2 - TILESIZE / 2;
- y = WIN_YSIZE / 2 - TILESIZE / 2;
+ x = ALIGNED_TEXT_XPOS(&init_last.busy);
+ y = ALIGNED_TEXT_YPOS(&init_last.busy);
- graphic_info = &anim_initial;
+ graphic_info = &anim_initial; /* graphic == 0 => anim_initial */
if (sync_frame % anim_initial.anim_delay == 0)
- DrawGraphicAnimationExt(window, x, y, graphic, sync_frame, NO_MASKING);
+ {
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int width = graphic_info[graphic].width;
+ int height = graphic_info[graphic].height;
+ int frame = getGraphicAnimationFrame(graphic, sync_frame);
+
+ getFixedGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
+ BlitBitmap(src_bitmap, window, src_x, src_y, width, height, x, y);
+ }
graphic_info = graphic_info_last;
gadgets_initialized = TRUE;
}
-inline void InitElementSmallImagesScaledUp(int graphic)
+inline static void InitElementSmallImagesScaledUp(int graphic)
{
-#if 0
- struct FileInfo *fi = getImageListEntryFromImageID(graphic);
-
- printf("::: '%s' -> '%s'\n", fi->token, fi->filename);
-#endif
+ struct GraphicInfo *g = &graphic_info[graphic];
- CreateImageWithSmallImages(graphic, graphic_info[graphic].scale_up_factor);
+ // create small and game tile sized bitmaps (and scale up, if needed)
+ CreateImageWithSmallImages(graphic, g->scale_up_factor, g->tile_size);
}
void InitElementSmallImages()
{
+ print_timestamp_init("InitElementSmallImages");
+
static int special_graphics[] =
{
+ IMG_FLAMES_1_LEFT,
+ IMG_FLAMES_2_LEFT,
+ IMG_FLAMES_3_LEFT,
+ IMG_FLAMES_1_RIGHT,
+ IMG_FLAMES_2_RIGHT,
+ IMG_FLAMES_3_RIGHT,
+ IMG_FLAMES_1_UP,
+ IMG_FLAMES_2_UP,
+ IMG_FLAMES_3_UP,
+ IMG_FLAMES_1_DOWN,
+ IMG_FLAMES_2_DOWN,
+ IMG_FLAMES_3_DOWN,
IMG_EDITOR_ELEMENT_BORDER,
IMG_EDITOR_ELEMENT_BORDER_INPUT,
IMG_EDITOR_CASCADE_LIST,
int num_property_mappings = getImageListPropertyMappingSize();
int i;
- /* initialize normal images from static configuration */
+ print_timestamp_time("getImageListPropertyMapping/Size");
+
+ print_timestamp_init("InitElementSmallImagesScaledUp (1)");
+ /* initialize normal element images from static configuration */
for (i = 0; element_to_graphic[i].element > -1; i++)
InitElementSmallImagesScaledUp(element_to_graphic[i].graphic);
+ print_timestamp_done("InitElementSmallImagesScaledUp (1)");
- /* initialize special images from static configuration */
+ /* initialize special element images from static configuration */
for (i = 0; element_to_special_graphic[i].element > -1; i++)
InitElementSmallImagesScaledUp(element_to_special_graphic[i].graphic);
+ print_timestamp_time("InitElementSmallImagesScaledUp (2)");
- /* initialize images from dynamic configuration (may be elements or other) */
+ /* initialize element images from dynamic configuration */
for (i = 0; i < num_property_mappings; i++)
- InitElementSmallImagesScaledUp(property_mapping[i].artwork_index);
+ if (property_mapping[i].base_index < MAX_NUM_ELEMENTS)
+ InitElementSmallImagesScaledUp(property_mapping[i].artwork_index);
+ print_timestamp_time("InitElementSmallImagesScaledUp (3)");
- /* initialize special images from above list (non-element images) */
+ /* initialize special non-element images from above list */
for (i = 0; special_graphics[i] > -1; i++)
InitElementSmallImagesScaledUp(special_graphics[i]);
+ print_timestamp_time("InitElementSmallImagesScaledUp (4)");
+
+ print_timestamp_done("InitElementSmallImages");
+}
+
+inline static void InitScaledImagesScaledUp(int graphic)
+{
+ struct GraphicInfo *g = &graphic_info[graphic];
+
+ ScaleImage(graphic, g->scale_up_factor);
}
void InitScaledImages()
{
+ struct PropertyMapping *property_mapping = getImageListPropertyMapping();
+ int num_property_mappings = getImageListPropertyMappingSize();
int i;
/* scale normal images from static configuration, if not already scaled */
for (i = 0; i < NUM_IMAGE_FILES; i++)
- ScaleImage(i, graphic_info[i].scale_up_factor);
+ InitScaledImagesScaledUp(i);
+
+ /* scale images from dynamic configuration, if not already scaled */
+ for (i = 0; i < num_property_mappings; i++)
+ InitScaledImagesScaledUp(property_mapping[i].artwork_index);
+}
+
+void InitBitmapPointers()
+{
+ int num_images = getImageListSize();
+ int i;
+
+ // standard size bitmap may have changed -- update default bitmap pointer
+ for (i = 0; i < num_images; i++)
+ if (graphic_info[i].bitmaps)
+ graphic_info[i].bitmap = graphic_info[i].bitmaps[IMG_BITMAP_STANDARD];
+}
+
+void InitImageTextures()
+{
+ int i, j, k;
+
+ FreeAllImageTextures();
+
+ for (i = IMG_GLOBAL_BORDER_FIRST; i <= IMG_GLOBAL_BORDER_LAST; i++)
+ CreateImageTextures(i);
+
+ for (i = 0; i < MAX_NUM_TOONS; i++)
+ CreateImageTextures(IMG_TOON_1 + i);
+
+ for (i = 0; i < NUM_GLOBAL_ANIMS; i++)
+ {
+ for (j = 0; j < NUM_GLOBAL_ANIM_PARTS_ALL; j++)
+ {
+ for (k = 0; k < NUM_SPECIAL_GFX_ARGS; k++)
+ {
+ int graphic = global_anim_info[i].graphic[j][k];
+
+ if (graphic == IMG_UNDEFINED)
+ continue;
+
+ CreateImageTextures(graphic);
+ }
+ }
+ }
}
#if 1
}
#endif
+#if 0
+/* !!! FIX THIS (CHANGE TO USING NORMAL ELEMENT GRAPHIC DEFINITIONS) !!! */
+void SetBitmaps_SP(Bitmap **sp_bitmap)
+{
+ *sp_bitmap = graphic_info[IMG_SP_OBJECTS].bitmap;
+}
+#endif
+
static int getFontBitmapID(int font_nr)
{
int special = -1;
+ /* (special case: do not use special font for GAME_MODE_LOADING) */
if (game_status >= GAME_MODE_TITLE_INITIAL &&
game_status <= GAME_MODE_PSEUDO_PREVIEW)
special = game_status;
else if (game_status == GAME_MODE_PSEUDO_TYPENAME)
special = GFX_SPECIAL_ARG_MAIN;
-#if 0
- else if (game_status == GAME_MODE_PLAYING)
- special = GFX_SPECIAL_ARG_DOOR;
-#endif
if (special != -1)
return font_info[font_nr].special_bitmap_id[special];
static int getFontFromToken(char *token)
{
- int i;
+ char *value = getHashEntry(font_token_hash, token);
- /* !!! OPTIMIZE THIS BY USING HASH !!! */
- for (i = 0; i < NUM_FONTS; i++)
- if (strEqual(token, font_info[i].token_name))
- return i;
+ if (value != NULL)
+ return atoi(value);
/* if font not found, use reliable default value */
return FONT_INITIAL_1;
int special = property_mapping[i].ext3_index;
int graphic = property_mapping[i].artwork_index;
- if (font_nr < 0)
+ if (font_nr < 0 || font_nr >= NUM_FONTS)
continue;
if (IS_SPECIAL_GFX_ARG(special))
getFontBitmapID, getFontFromToken);
}
+void InitGlobalAnimGraphicInfo()
+{
+ struct PropertyMapping *property_mapping = getImageListPropertyMapping();
+ int num_property_mappings = getImageListPropertyMappingSize();
+ int i, j, k;
+
+ if (graphic_info == NULL) /* still at startup phase */
+ return;
+
+ /* always start with reliable default values (no global animations) */
+ for (i = 0; i < NUM_GLOBAL_ANIM_TOKENS; i++)
+ for (j = 0; j < NUM_GLOBAL_ANIM_PARTS_ALL; j++)
+ for (k = 0; k < NUM_SPECIAL_GFX_ARGS; k++)
+ global_anim_info[i].graphic[j][k] = IMG_UNDEFINED;
+
+ /* initialize global animation definitions from static configuration */
+ for (i = 0; i < NUM_GLOBAL_ANIM_TOKENS; i++)
+ {
+ int j = GLOBAL_ANIM_ID_PART_BASE;
+ int k = GFX_SPECIAL_ARG_DEFAULT;
+
+ global_anim_info[i].graphic[j][k] = IMG_GFX_GLOBAL_ANIM_1 + i;
+ }
+
+ /* initialize global animation definitions from dynamic configuration */
+ for (i = 0; i < num_property_mappings; i++)
+ {
+ int anim_nr = property_mapping[i].base_index - MAX_NUM_ELEMENTS - NUM_FONTS;
+ int part_nr = property_mapping[i].ext1_index - ACTION_PART_1;
+ int special = property_mapping[i].ext3_index;
+ int graphic = property_mapping[i].artwork_index;
+
+ if (anim_nr < 0 || anim_nr >= NUM_GLOBAL_ANIM_TOKENS)
+ continue;
+
+ /* set animation part to base part, if not specified */
+ if (!IS_GLOBAL_ANIM_PART(part_nr))
+ part_nr = GLOBAL_ANIM_ID_PART_BASE;
+
+ /* set animation screen to default, if not specified */
+ if (!IS_SPECIAL_GFX_ARG(special))
+ special = GFX_SPECIAL_ARG_DEFAULT;
+
+ global_anim_info[anim_nr].graphic[part_nr][special] = graphic;
+
+ /* fix default value for ".draw_masked" (for backward compatibility) */
+ struct GraphicInfo *g = &graphic_info[graphic];
+ struct FileInfo *image = getImageListEntryFromImageID(graphic);
+ char **parameter_raw = image->parameter;
+ int p = GFX_ARG_DRAW_MASKED;
+ int draw_masked = get_graphic_parameter_value(parameter_raw[p],
+ image_config_suffix[p].token,
+ image_config_suffix[p].type);
+
+ /* if ".draw_masked" parameter is undefined, use default value "TRUE" */
+ if (draw_masked == ARG_UNDEFINED_VALUE)
+ g->draw_masked = TRUE;
+ }
+
+#if 0
+ printf("::: InitGlobalAnimGraphicInfo\n");
+
+ for (i = 0; i < NUM_GLOBAL_ANIMS; i++)
+ for (j = 0; j < NUM_GLOBAL_ANIM_PARTS_ALL; j++)
+ for (k = 0; k < NUM_SPECIAL_GFX_ARGS; k++)
+ if (global_anim_info[i].graphic[j][k] != IMG_UNDEFINED &&
+ graphic_info[global_anim_info[i].graphic[j][k]].bitmap != NULL)
+ printf("::: - anim %d, part %d, mode %d => %d\n",
+ i, j, k, global_anim_info[i].graphic[j][k]);
+#endif
+}
+
+void InitGlobalAnimSoundInfo()
+{
+ struct PropertyMapping *property_mapping = getSoundListPropertyMapping();
+ int num_property_mappings = getSoundListPropertyMappingSize();
+ int i, j, k;
+
+ /* always start with reliable default values (no global animation sounds) */
+ for (i = 0; i < NUM_GLOBAL_ANIM_TOKENS; i++)
+ for (j = 0; j < NUM_GLOBAL_ANIM_PARTS_ALL; j++)
+ for (k = 0; k < NUM_SPECIAL_GFX_ARGS; k++)
+ global_anim_info[i].sound[j][k] = SND_UNDEFINED;
+
+ /* initialize global animation sound definitions from dynamic configuration */
+ for (i = 0; i < num_property_mappings; i++)
+ {
+ int anim_nr = property_mapping[i].base_index - 2 * MAX_NUM_ELEMENTS;
+ int part_nr = property_mapping[i].ext1_index - ACTION_PART_1;
+ int special = property_mapping[i].ext3_index;
+ int sound = property_mapping[i].artwork_index;
+
+ // sound uses control definition; map it to position of graphic (artwork)
+ anim_nr -= GLOBAL_ANIM_ID_CONTROL_FIRST;
+
+ if (anim_nr < 0 || anim_nr >= NUM_GLOBAL_ANIM_TOKENS)
+ continue;
+
+ /* set animation part to base part, if not specified */
+ if (!IS_GLOBAL_ANIM_PART(part_nr))
+ part_nr = GLOBAL_ANIM_ID_PART_BASE;
+
+ /* set animation screen to default, if not specified */
+ if (!IS_SPECIAL_GFX_ARG(special))
+ special = GFX_SPECIAL_ARG_DEFAULT;
+
+ global_anim_info[anim_nr].sound[part_nr][special] = sound;
+ }
+
+#if 0
+ printf("::: InitGlobalAnimSoundInfo\n");
+
+ for (i = 0; i < NUM_GLOBAL_ANIMS; i++)
+ for (j = 0; j < NUM_GLOBAL_ANIM_PARTS_ALL; j++)
+ for (k = 0; k < NUM_SPECIAL_GFX_ARGS; k++)
+ if (global_anim_info[i].sound[j][k] != SND_UNDEFINED)
+ printf("::: - anim %d, part %d, mode %d => %d\n",
+ i, j, k, global_anim_info[i].sound[j][k]);
+#endif
+}
+
+void InitGlobalAnimMusicInfo()
+{
+ struct PropertyMapping *property_mapping = getMusicListPropertyMapping();
+ int num_property_mappings = getMusicListPropertyMappingSize();
+ int i, j, k;
+
+ /* always start with reliable default values (no global animation music) */
+ for (i = 0; i < NUM_GLOBAL_ANIM_TOKENS; i++)
+ for (j = 0; j < NUM_GLOBAL_ANIM_PARTS_ALL; j++)
+ for (k = 0; k < NUM_SPECIAL_GFX_ARGS; k++)
+ global_anim_info[i].music[j][k] = MUS_UNDEFINED;
+
+ /* initialize global animation music definitions from dynamic configuration */
+ for (i = 0; i < num_property_mappings; i++)
+ {
+ int anim_nr = property_mapping[i].base_index - NUM_MUSIC_PREFIXES;
+ int part_nr = property_mapping[i].ext1_index - ACTION_PART_1;
+ int special = property_mapping[i].ext2_index;
+ int music = property_mapping[i].artwork_index;
+
+ // music uses control definition; map it to position of graphic (artwork)
+ anim_nr -= GLOBAL_ANIM_ID_CONTROL_FIRST;
+
+ if (anim_nr < 0 || anim_nr >= NUM_GLOBAL_ANIM_TOKENS)
+ continue;
+
+ /* set animation part to base part, if not specified */
+ if (!IS_GLOBAL_ANIM_PART(part_nr))
+ part_nr = GLOBAL_ANIM_ID_PART_BASE;
+
+ /* set animation screen to default, if not specified */
+ if (!IS_SPECIAL_GFX_ARG(special))
+ special = GFX_SPECIAL_ARG_DEFAULT;
+
+ global_anim_info[anim_nr].music[part_nr][special] = music;
+ }
+
+#if 0
+ printf("::: InitGlobalAnimMusicInfo\n");
+
+ for (i = 0; i < NUM_GLOBAL_ANIMS; i++)
+ for (j = 0; j < NUM_GLOBAL_ANIM_PARTS_ALL; j++)
+ for (k = 0; k < NUM_SPECIAL_GFX_ARGS; k++)
+ if (global_anim_info[i].music[j][k] != MUS_UNDEFINED)
+ printf("::: - anim %d, part %d, mode %d => %d\n",
+ i, j, k, global_anim_info[i].music[j][k]);
+#endif
+}
+
void InitElementGraphicInfo()
{
struct PropertyMapping *property_mapping = getImageListPropertyMapping();
int graphic = property_mapping[i].artwork_index;
boolean crumbled = FALSE;
-#if 0
- if ((element == EL_EM_DYNAMITE ||
- element == EL_EM_DYNAMITE_ACTIVE) &&
- action == ACTION_ACTIVE &&
- (special == GFX_SPECIAL_ARG_EDITOR ||
- special == GFX_SPECIAL_ARG_PANEL))
- printf("::: DYNAMIC: %d, %d, %d -> %d\n",
- element, action, special, graphic);
-#endif
-
if (special == GFX_SPECIAL_ARG_CRUMBLED)
{
special = -1;
}
}
-#if 1
/* set hardcoded definitions for some runtime elements without graphic */
element_info[EL_AMOEBA_TO_DIAMOND].graphic[ACTION_DEFAULT] = IMG_AMOEBA_DEAD;
-#endif
-#if 1
/* set hardcoded definitions for some internal elements without graphic */
for (i = 0; i < MAX_NUM_ELEMENTS; i++)
{
else if (IS_EDITOR_CASCADE_ACTIVE(i))
element_info[i].graphic[ACTION_DEFAULT] = IMG_EDITOR_CASCADE_LIST_ACTIVE;
}
-#endif
/* now set all undefined/invalid graphics to -1 to set to default after it */
for (i = 0; i < MAX_NUM_ELEMENTS; i++)
(move_dir == MV_BIT_UP && !front_is_left_or_upper) ||
(move_dir == MV_BIT_RIGHT && front_is_left_or_upper) ||
(move_dir == MV_BIT_DOWN && front_is_left_or_upper)));
- Bitmap *dummy;
/* swap frontside and backside graphic tile coordinates, if needed */
if (swap_movement_tiles_always || swap_movement_tiles_autodetected)
{
/* get current (wrong) backside tile coordinates */
- getGraphicSourceExt(graphic, 0, &dummy, &src_x_back, &src_y_back,
- TRUE);
+ getGraphicSourceXY(graphic, 0, &src_x_back, &src_y_back, TRUE);
/* set frontside tile coordinates to backside tile coordinates */
g->src_x = src_x_back;
if (default_graphic == -1)
default_graphic = IMG_UNKNOWN;
-#if 1
+
if (default_crumbled == -1)
default_crumbled = default_graphic;
-#else
- /* !!! THIS LOOKS CRAPPY FOR SAND ETC. WITHOUT CRUMBLED GRAPHICS !!! */
- if (default_crumbled == -1)
- default_crumbled = IMG_EMPTY;
-#endif
for (dir = 0; dir < NUM_DIRECTIONS_FULL; dir++)
{
if (default_direction_graphic[dir] == -1)
default_direction_graphic[dir] = default_graphic;
-#if 1
+
if (default_direction_crumbled[dir] == -1)
default_direction_crumbled[dir] = default_direction_graphic[dir];
-#else
- /* !!! THIS LOOKS CRAPPY FOR SAND ETC. WITHOUT CRUMBLED GRAPHICS !!! */
- if (default_direction_crumbled[dir] == -1)
- default_direction_crumbled[dir] = default_crumbled;
-#endif
}
for (act = 0; act < NUM_ACTIONS; act++)
if (IS_SB_ELEMENT(i) && element_info[EL_SB_DEFAULT].crumbled[act] != -1)
default_action_crumbled = element_info[EL_SB_DEFAULT].crumbled[act];
-#if 1
/* !!! needed because EL_EMPTY_SPACE treated as IS_SP_ELEMENT !!! */
/* !!! make this better !!! */
if (i == EL_EMPTY_SPACE)
default_action_graphic = element_info[EL_DEFAULT].graphic[act];
default_action_crumbled = element_info[EL_DEFAULT].crumbled[act];
}
-#endif
if (default_action_graphic == -1)
default_action_graphic = default_graphic;
-#if 1
+
if (default_action_crumbled == -1)
default_action_crumbled = default_action_graphic;
-#else
- /* !!! THIS LOOKS CRAPPY FOR SAND ETC. WITHOUT CRUMBLED GRAPHICS !!! */
- if (default_action_crumbled == -1)
- default_action_crumbled = default_crumbled;
-#endif
for (dir = 0; dir < NUM_DIRECTIONS_FULL; dir++)
{
element_info[i].direction_graphic[act][dir] =
default_action_direction_graphic;
-#if 1
if (default_action_direction_crumbled == -1)
default_action_direction_crumbled =
element_info[i].direction_graphic[act][dir];
-#else
- if (default_action_direction_crumbled == -1)
- default_action_direction_crumbled =
- (act_remove ? default_remove_graphic :
- act_turning ?
- element_info[i].direction_crumbled[ACTION_TURNING][dir] :
- default_action_crumbled != default_crumbled ?
- default_action_crumbled :
- default_direction_crumbled[dir]);
-#endif
if (element_info[i].direction_crumbled[act][dir] == -1)
element_info[i].direction_crumbled[act][dir] =
(act_remove ? default_remove_graphic :
act_turning ? element_info[i].graphic[ACTION_TURNING] :
default_action_graphic);
-#if 1
+
if (element_info[i].crumbled[act] == -1)
element_info[i].crumbled[act] = element_info[i].graphic[act];
-#else
- if (element_info[i].crumbled[act] == -1)
- element_info[i].crumbled[act] =
- (act_remove ? default_remove_graphic :
- act_turning ? element_info[i].crumbled[ACTION_TURNING] :
- default_action_crumbled);
-#endif
}
}
UPDATE_BUSY_STATE();
-
-#if 0
- /* !!! THIS ALSO CLEARS SPECIAL FLAGS (AND IS NOT NEEDED ANYWAY) !!! */
- /* 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_FULL; 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)
- {
- for (i = 0; i < MAX_NUM_ELEMENTS; i++)
- if (element_info[i].graphic[ACTION_DEFAULT] == IMG_UNKNOWN &&
- i != EL_UNKNOWN)
- Error(ERR_INFO, "warning: no graphic for element '%s' (%d)",
- element_info[i].token_name, i);
- }
-#endif
-#endif
}
void InitElementSpecialGraphicInfo()
boolean special_redefined =
getImageListEntryFromImageID(graphic)->redefined;
-#if 0
- if ((element == EL_EM_DYNAMITE ||
- element == EL_EM_DYNAMITE_ACTIVE) &&
- (special == GFX_SPECIAL_ARG_EDITOR ||
- special == GFX_SPECIAL_ARG_PANEL))
- printf("::: SPECIAL STATIC: %d, %d -> %d\n",
- element, special, graphic);
-#endif
-
/* if the base graphic ("emerald", for example) has been redefined,
but not the special graphic ("emerald.EDITOR", for example), do not
use an existing (in this case considered obsolete) special graphic
int special = property_mapping[i].ext3_index;
int graphic = property_mapping[i].artwork_index;
-#if 0
- if ((element == EL_EM_DYNAMITE ||
- element == EL_EM_DYNAMITE_ACTIVE ||
- element == EL_CONVEYOR_BELT_1_MIDDLE ||
- element == EL_CONVEYOR_BELT_1_MIDDLE_ACTIVE) &&
- (special == GFX_SPECIAL_ARG_EDITOR ||
- special == GFX_SPECIAL_ARG_PANEL))
- printf("::: SPECIAL DYNAMIC: %d, %d -> %d [%d]\n",
- element, special, graphic, property_mapping[i].ext1_index);
-#endif
-
-#if 0
- if (element == EL_CONVEYOR_BELT_1_MIDDLE &&
- action == ACTION_ACTIVE)
- {
- element = EL_CONVEYOR_BELT_1_MIDDLE_ACTIVE;
- action = -1;
- }
-#endif
-
-#if 0
- if (element == EL_MAGIC_WALL &&
- action == ACTION_ACTIVE)
- {
- element = EL_MAGIC_WALL_ACTIVE;
- action = -1;
- }
-#endif
-
-#if 1
/* for action ".active", replace element with active element, if exists */
if (action == ACTION_ACTIVE && element != ELEMENT_ACTIVE(element))
{
element = ELEMENT_ACTIVE(element);
action = -1;
}
-#endif
if (element >= MAX_NUM_ELEMENTS)
continue;
static int get_graphic_parameter_value(char *value_raw, char *suffix, int type)
{
- int i;
- int x = 0;
-
- if (type != TYPE_TOKEN)
+ if (type != TYPE_ELEMENT && type != TYPE_GRAPHIC)
return get_parameter_value(value_raw, suffix, type);
if (strEqual(value_raw, ARG_UNDEFINED))
return ARG_UNDEFINED_VALUE;
- /* !!! OPTIMIZE THIS BY USING HASH !!! */
- for (i = 0; i < MAX_NUM_ELEMENTS; i++)
- if (strEqual(element_info[i].token_name, value_raw))
- return i;
-
- /* !!! OPTIMIZE THIS BY USING HASH !!! */
- for (i = 0; image_config[i].token != NULL; i++)
+ if (type == TYPE_ELEMENT)
{
- int len_config_value = strlen(image_config[i].value);
-
- if (!strEqual(&image_config[i].value[len_config_value - 4], ".pcx") &&
- !strEqual(&image_config[i].value[len_config_value - 4], ".wav") &&
- !strEqual(image_config[i].value, UNDEFINED_FILENAME))
- continue;
+ char *value = getHashEntry(element_token_hash, value_raw);
- if (strEqual(image_config[i].token, value_raw))
- return x;
+ if (value == NULL)
+ {
+ Error(ERR_INFO_LINE, "-");
+ Error(ERR_INFO, "warning: error found in config file:");
+ Error(ERR_INFO, "- config file: '%s'", getImageConfigFilename());
+ Error(ERR_INFO, "error: invalid element token '%s'", value_raw);
+ Error(ERR_INFO, "custom graphic rejected for this element/action");
+ Error(ERR_INFO, "fallback done to undefined element for this graphic");
+ Error(ERR_INFO_LINE, "-");
+ }
- x++;
+ return (value != NULL ? atoi(value) : EL_UNDEFINED);
}
+ else if (type == TYPE_GRAPHIC)
+ {
+ char *value = getHashEntry(graphic_token_hash, value_raw);
+ int fallback_graphic = IMG_CHAR_EXCLAM;
- return -1;
-}
-
-static int get_scaled_graphic_width(int graphic)
-{
- int original_width = getOriginalImageWidthFromImageID(graphic);
- int scale_up_factor = graphic_info[graphic].scale_up_factor;
+ if (value == NULL)
+ {
+ Error(ERR_INFO_LINE, "-");
+ Error(ERR_INFO, "warning: error found in config file:");
+ Error(ERR_INFO, "- config file: '%s'", getImageConfigFilename());
+ Error(ERR_INFO, "error: invalid graphic token '%s'", value_raw);
+ Error(ERR_INFO, "custom graphic rejected for this element/action");
+ Error(ERR_INFO, "fallback done to 'char_exclam' for this graphic");
+ Error(ERR_INFO_LINE, "-");
+ }
+
+ return (value != NULL ? atoi(value) : fallback_graphic);
+ }
+
+ return -1;
+}
+
+static int get_scaled_graphic_width(int graphic)
+{
+ int original_width = getOriginalImageWidthFromImageID(graphic);
+ int scale_up_factor = graphic_info[graphic].scale_up_factor;
return original_width * scale_up_factor;
}
return original_height * scale_up_factor;
}
-static void set_graphic_parameters(int graphic)
+static void set_graphic_parameters_ext(int graphic, int *parameter,
+ Bitmap **src_bitmaps)
{
- struct FileInfo *image = getImageListEntryFromImageID(graphic);
- char **parameter_raw = image->parameter;
- Bitmap *src_bitmap = getBitmapFromImageID(graphic);
- int parameter[NUM_GFX_ARGS];
+ struct GraphicInfo *g = &graphic_info[graphic];
+ Bitmap *src_bitmap = (src_bitmaps ? src_bitmaps[IMG_BITMAP_STANDARD] : NULL);
int anim_frames_per_row = 1, anim_frames_per_col = 1;
int anim_frames_per_line = 1;
- int i;
-
- /* if fallback to default artwork is done, also use the default parameters */
- if (image->fallback_to_default)
- parameter_raw = image->default_parameter;
-
- /* get integer values from string parameters */
- for (i = 0; i < NUM_GFX_ARGS; i++)
- parameter[i] = get_graphic_parameter_value(parameter_raw[i],
- image_config_suffix[i].token,
- image_config_suffix[i].type);
-
- graphic_info[graphic].bitmap = src_bitmap;
/* always start with reliable default values */
- graphic_info[graphic].src_image_width = 0;
- graphic_info[graphic].src_image_height = 0;
- graphic_info[graphic].src_x = 0;
- graphic_info[graphic].src_y = 0;
- graphic_info[graphic].width = TILEX; /* default for element graphics */
- graphic_info[graphic].height = TILEY; /* default for element graphics */
- graphic_info[graphic].offset_x = 0; /* one or both of these values ... */
- graphic_info[graphic].offset_y = 0; /* ... will be corrected later */
- graphic_info[graphic].offset2_x = 0; /* one or both of these values ... */
- graphic_info[graphic].offset2_y = 0; /* ... will be corrected later */
- graphic_info[graphic].swap_double_tiles = -1; /* auto-detect tile swapping */
- graphic_info[graphic].crumbled_like = -1; /* do not use clone element */
- graphic_info[graphic].diggable_like = -1; /* do not use clone element */
- graphic_info[graphic].border_size = TILEX / 8; /* "CRUMBLED" border size */
- graphic_info[graphic].scale_up_factor = 1; /* default: no scaling up */
- graphic_info[graphic].clone_from = -1; /* do not use clone graphic */
- graphic_info[graphic].anim_delay_fixed = 0;
- graphic_info[graphic].anim_delay_random = 0;
- graphic_info[graphic].post_delay_fixed = 0;
- graphic_info[graphic].post_delay_random = 0;
- graphic_info[graphic].fade_mode = FADE_MODE_DEFAULT;
- graphic_info[graphic].fade_delay = -1;
- graphic_info[graphic].post_delay = -1;
- graphic_info[graphic].auto_delay = -1;
- graphic_info[graphic].align = ALIGN_CENTER; /* default for title screens */
- graphic_info[graphic].valign = VALIGN_MIDDLE; /* default for title screens */
- graphic_info[graphic].sort_priority = 0; /* default for title screens */
+ g->src_image_width = 0;
+ g->src_image_height = 0;
+ g->src_x = 0;
+ g->src_y = 0;
+ g->width = TILEX; /* default for element graphics */
+ g->height = TILEY; /* default for element graphics */
+ g->offset_x = 0; /* one or both of these values ... */
+ g->offset_y = 0; /* ... will be corrected later */
+ g->offset2_x = 0; /* one or both of these values ... */
+ g->offset2_y = 0; /* ... will be corrected later */
+ g->swap_double_tiles = -1; /* auto-detect tile swapping */
+ g->crumbled_like = -1; /* do not use clone element */
+ g->diggable_like = -1; /* do not use clone element */
+ g->border_size = TILEX / 8; /* "CRUMBLED" border size */
+ g->scale_up_factor = 1; /* default: no scaling up */
+ g->tile_size = TILESIZE; /* default: standard tile size */
+ g->clone_from = -1; /* do not use clone graphic */
+ g->init_delay_fixed = 0;
+ g->init_delay_random = 0;
+ g->anim_delay_fixed = 0;
+ g->anim_delay_random = 0;
+ g->post_delay_fixed = 0;
+ g->post_delay_random = 0;
+ g->init_event = ANIM_EVENT_DEFAULT;
+ g->anim_event = ANIM_EVENT_DEFAULT;
+ g->draw_masked = FALSE;
+ g->draw_order = 0;
+ g->fade_mode = FADE_MODE_DEFAULT;
+ g->fade_delay = -1;
+ g->post_delay = -1;
+ g->auto_delay = -1;
+ g->align = ALIGN_CENTER; /* default for title screens */
+ g->valign = VALIGN_MIDDLE; /* default for title screens */
+ g->sort_priority = 0; /* default for title screens */
+ g->class = 0;
+ g->style = STYLE_DEFAULT;
+
+ g->bitmaps = src_bitmaps;
+ g->bitmap = src_bitmap;
-#if 1
/* optional zoom factor for scaling up the image to a larger size */
if (parameter[GFX_ARG_SCALE_UP_FACTOR] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].scale_up_factor = parameter[GFX_ARG_SCALE_UP_FACTOR];
- if (graphic_info[graphic].scale_up_factor < 1)
- graphic_info[graphic].scale_up_factor = 1; /* no scaling */
+ g->scale_up_factor = parameter[GFX_ARG_SCALE_UP_FACTOR];
+ if (g->scale_up_factor < 1)
+ g->scale_up_factor = 1; /* no scaling */
+
+ /* optional tile size for using non-standard image size */
+ if (parameter[GFX_ARG_TILE_SIZE] != ARG_UNDEFINED_VALUE)
+ {
+ g->tile_size = parameter[GFX_ARG_TILE_SIZE];
+
+#if 0
+ // CHECK: should tile sizes less than standard tile size be allowed?
+ if (g->tile_size < TILESIZE)
+ g->tile_size = TILESIZE; /* standard tile size */
#endif
-#if 1
- if (graphic_info[graphic].use_image_size)
+ // when setting tile size, also set width and height accordingly
+ g->width = g->tile_size;
+ g->height = g->tile_size;
+ }
+
+ if (g->use_image_size)
{
/* set new default bitmap size (with scaling, but without small images) */
- graphic_info[graphic].width = get_scaled_graphic_width(graphic);
- graphic_info[graphic].height = get_scaled_graphic_height(graphic);
+ g->width = get_scaled_graphic_width(graphic);
+ g->height = get_scaled_graphic_height(graphic);
}
-#endif
+
+ /* optional width and height of each animation frame */
+ if (parameter[GFX_ARG_WIDTH] != ARG_UNDEFINED_VALUE)
+ g->width = parameter[GFX_ARG_WIDTH];
+ if (parameter[GFX_ARG_HEIGHT] != ARG_UNDEFINED_VALUE)
+ g->height = parameter[GFX_ARG_HEIGHT];
/* optional x and y tile position of animation frame sequence */
if (parameter[GFX_ARG_XPOS] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].src_x = parameter[GFX_ARG_XPOS] * TILEX;
+ g->src_x = parameter[GFX_ARG_XPOS] * g->width;
if (parameter[GFX_ARG_YPOS] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].src_y = parameter[GFX_ARG_YPOS] * TILEY;
+ g->src_y = parameter[GFX_ARG_YPOS] * g->height;
/* optional x and y pixel position of animation frame sequence */
if (parameter[GFX_ARG_X] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].src_x = parameter[GFX_ARG_X];
+ g->src_x = parameter[GFX_ARG_X];
if (parameter[GFX_ARG_Y] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].src_y = parameter[GFX_ARG_Y];
+ g->src_y = parameter[GFX_ARG_Y];
- /* optional width and height of each animation frame */
- if (parameter[GFX_ARG_WIDTH] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].width = parameter[GFX_ARG_WIDTH];
- if (parameter[GFX_ARG_HEIGHT] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].height = parameter[GFX_ARG_HEIGHT];
+ if (src_bitmap)
+ {
+ if (g->width <= 0)
+ {
+ Error(ERR_INFO_LINE, "-");
+ Error(ERR_WARN, "invalid value %d for '%s.width' (fallback done to %d)",
+ g->width, getTokenFromImageID(graphic), TILEX);
+ Error(ERR_INFO_LINE, "-");
-#if 0
- /* optional zoom factor for scaling up the image to a larger size */
- if (parameter[GFX_ARG_SCALE_UP_FACTOR] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].scale_up_factor = parameter[GFX_ARG_SCALE_UP_FACTOR];
- if (graphic_info[graphic].scale_up_factor < 1)
- graphic_info[graphic].scale_up_factor = 1; /* no scaling */
-#endif
+ g->width = TILEX; /* will be checked to be inside bitmap later */
+ }
+
+ if (g->height <= 0)
+ {
+ Error(ERR_INFO_LINE, "-");
+ Error(ERR_WARN, "invalid value %d for '%s.height' (fallback done to %d)",
+ g->height, getTokenFromImageID(graphic), TILEY);
+ Error(ERR_INFO_LINE, "-");
+
+ g->height = TILEY; /* will be checked to be inside bitmap later */
+ }
+ }
if (src_bitmap)
{
int src_image_width = get_scaled_graphic_width(graphic);
int src_image_height = get_scaled_graphic_height(graphic);
- anim_frames_per_row = src_image_width / graphic_info[graphic].width;
- anim_frames_per_col = src_image_height / graphic_info[graphic].height;
+ if (src_image_width == 0 || src_image_height == 0)
+ {
+ /* only happens when loaded outside artwork system (like "global.busy") */
+ src_image_width = src_bitmap->width;
+ src_image_height = src_bitmap->height;
+ }
- graphic_info[graphic].src_image_width = src_image_width;
- graphic_info[graphic].src_image_height = src_image_height;
+ if (parameter[GFX_ARG_TILE_SIZE] != ARG_UNDEFINED_VALUE)
+ {
+ anim_frames_per_row = MAX(1, src_image_width / g->tile_size);
+ anim_frames_per_col = MAX(1, src_image_height / g->tile_size);
+ }
+ else
+ {
+ anim_frames_per_row = MAX(1, src_image_width / g->width);
+ anim_frames_per_col = MAX(1, src_image_height / g->height);
+ }
+
+ g->src_image_width = src_image_width;
+ g->src_image_height = src_image_height;
}
/* correct x or y offset dependent of vertical or horizontal frame order */
if (parameter[GFX_ARG_VERTICAL]) /* frames are ordered vertically */
{
- graphic_info[graphic].offset_y =
- (parameter[GFX_ARG_OFFSET] != ARG_UNDEFINED_VALUE ?
- parameter[GFX_ARG_OFFSET] : graphic_info[graphic].height);
+ g->offset_y = (parameter[GFX_ARG_OFFSET] != ARG_UNDEFINED_VALUE ?
+ parameter[GFX_ARG_OFFSET] : g->height);
anim_frames_per_line = anim_frames_per_col;
}
else /* frames are ordered horizontally */
{
- graphic_info[graphic].offset_x =
- (parameter[GFX_ARG_OFFSET] != ARG_UNDEFINED_VALUE ?
- parameter[GFX_ARG_OFFSET] : graphic_info[graphic].width);
+ g->offset_x = (parameter[GFX_ARG_OFFSET] != ARG_UNDEFINED_VALUE ?
+ parameter[GFX_ARG_OFFSET] : g->width);
anim_frames_per_line = anim_frames_per_row;
}
/* optionally, the x and y offset of frames can be specified directly */
if (parameter[GFX_ARG_XOFFSET] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].offset_x = parameter[GFX_ARG_XOFFSET];
+ g->offset_x = parameter[GFX_ARG_XOFFSET];
if (parameter[GFX_ARG_YOFFSET] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].offset_y = parameter[GFX_ARG_YOFFSET];
+ g->offset_y = parameter[GFX_ARG_YOFFSET];
/* optionally, moving animations may have separate start and end graphics */
- graphic_info[graphic].double_movement = parameter[GFX_ARG_2ND_MOVEMENT_TILE];
+ g->double_movement = parameter[GFX_ARG_2ND_MOVEMENT_TILE];
if (parameter[GFX_ARG_2ND_VERTICAL] == ARG_UNDEFINED_VALUE)
parameter[GFX_ARG_2ND_VERTICAL] = !parameter[GFX_ARG_VERTICAL];
/* correct x or y offset2 dependent of vertical or horizontal frame order */
if (parameter[GFX_ARG_2ND_VERTICAL]) /* frames are ordered vertically */
- graphic_info[graphic].offset2_y =
- (parameter[GFX_ARG_2ND_OFFSET] != ARG_UNDEFINED_VALUE ?
- parameter[GFX_ARG_2ND_OFFSET] : graphic_info[graphic].height);
+ g->offset2_y = (parameter[GFX_ARG_2ND_OFFSET] != ARG_UNDEFINED_VALUE ?
+ parameter[GFX_ARG_2ND_OFFSET] : g->height);
else /* frames are ordered horizontally */
- graphic_info[graphic].offset2_x =
- (parameter[GFX_ARG_2ND_OFFSET] != ARG_UNDEFINED_VALUE ?
- parameter[GFX_ARG_2ND_OFFSET] : graphic_info[graphic].width);
+ g->offset2_x = (parameter[GFX_ARG_2ND_OFFSET] != ARG_UNDEFINED_VALUE ?
+ parameter[GFX_ARG_2ND_OFFSET] : g->width);
/* optionally, the x and y offset of 2nd graphic can be specified directly */
if (parameter[GFX_ARG_2ND_XOFFSET] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].offset2_x = parameter[GFX_ARG_2ND_XOFFSET];
+ g->offset2_x = parameter[GFX_ARG_2ND_XOFFSET];
if (parameter[GFX_ARG_2ND_YOFFSET] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].offset2_y = parameter[GFX_ARG_2ND_YOFFSET];
+ g->offset2_y = parameter[GFX_ARG_2ND_YOFFSET];
/* optionally, the second movement tile can be specified as start tile */
if (parameter[GFX_ARG_2ND_SWAP_TILES] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].swap_double_tiles= parameter[GFX_ARG_2ND_SWAP_TILES];
+ g->swap_double_tiles= parameter[GFX_ARG_2ND_SWAP_TILES];
/* automatically determine correct number of frames, if not defined */
if (parameter[GFX_ARG_FRAMES] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].anim_frames = parameter[GFX_ARG_FRAMES];
+ g->anim_frames = parameter[GFX_ARG_FRAMES];
else if (parameter[GFX_ARG_XPOS] == 0 && !parameter[GFX_ARG_VERTICAL])
- graphic_info[graphic].anim_frames = anim_frames_per_row;
+ g->anim_frames = anim_frames_per_row;
else if (parameter[GFX_ARG_YPOS] == 0 && parameter[GFX_ARG_VERTICAL])
- graphic_info[graphic].anim_frames = anim_frames_per_col;
+ g->anim_frames = anim_frames_per_col;
else
- graphic_info[graphic].anim_frames = 1;
+ g->anim_frames = 1;
- if (graphic_info[graphic].anim_frames == 0) /* frames must be at least 1 */
- graphic_info[graphic].anim_frames = 1;
+ if (g->anim_frames == 0) /* frames must be at least 1 */
+ g->anim_frames = 1;
- graphic_info[graphic].anim_frames_per_line =
+ g->anim_frames_per_line =
(parameter[GFX_ARG_FRAMES_PER_LINE] != ARG_UNDEFINED_VALUE ?
parameter[GFX_ARG_FRAMES_PER_LINE] : anim_frames_per_line);
- graphic_info[graphic].anim_delay = parameter[GFX_ARG_DELAY];
- if (graphic_info[graphic].anim_delay == 0) /* delay must be at least 1 */
- graphic_info[graphic].anim_delay = 1;
+ g->anim_delay = parameter[GFX_ARG_DELAY];
+ if (g->anim_delay == 0) /* delay must be at least 1 */
+ g->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
+ g->anim_mode = parameter[GFX_ARG_ANIM_MODE];
/* automatically determine correct start frame, if not defined */
if (parameter[GFX_ARG_START_FRAME] == ARG_UNDEFINED_VALUE)
- graphic_info[graphic].anim_start_frame = 0;
- else if (graphic_info[graphic].anim_mode & ANIM_REVERSE)
- graphic_info[graphic].anim_start_frame =
- graphic_info[graphic].anim_frames - parameter[GFX_ARG_START_FRAME] - 1;
+ g->anim_start_frame = 0;
+ else if (g->anim_mode & ANIM_REVERSE)
+ g->anim_start_frame = g->anim_frames - parameter[GFX_ARG_START_FRAME] - 1;
else
- graphic_info[graphic].anim_start_frame = parameter[GFX_ARG_START_FRAME];
+ g->anim_start_frame = parameter[GFX_ARG_START_FRAME];
/* animation synchronized with global frame counter, not move position */
- graphic_info[graphic].anim_global_sync = parameter[GFX_ARG_GLOBAL_SYNC];
+ g->anim_global_sync = parameter[GFX_ARG_GLOBAL_SYNC];
/* optional element for cloning crumble graphics */
if (parameter[GFX_ARG_CRUMBLED_LIKE] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].crumbled_like = parameter[GFX_ARG_CRUMBLED_LIKE];
+ g->crumbled_like = parameter[GFX_ARG_CRUMBLED_LIKE];
/* optional element for cloning digging graphics */
if (parameter[GFX_ARG_DIGGABLE_LIKE] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].diggable_like = parameter[GFX_ARG_DIGGABLE_LIKE];
+ g->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];
+ g->border_size = parameter[GFX_ARG_BORDER_SIZE];
- /* this is only used for player "boring" and "sleeping" actions */
+ /* used for global animations and player "boring" and "sleeping" actions */
+ if (parameter[GFX_ARG_INIT_DELAY_FIXED] != ARG_UNDEFINED_VALUE)
+ g->init_delay_fixed = parameter[GFX_ARG_INIT_DELAY_FIXED];
+ if (parameter[GFX_ARG_INIT_DELAY_RANDOM] != ARG_UNDEFINED_VALUE)
+ g->init_delay_random = parameter[GFX_ARG_INIT_DELAY_RANDOM];
if (parameter[GFX_ARG_ANIM_DELAY_FIXED] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].anim_delay_fixed =
- parameter[GFX_ARG_ANIM_DELAY_FIXED];
+ g->anim_delay_fixed = parameter[GFX_ARG_ANIM_DELAY_FIXED];
if (parameter[GFX_ARG_ANIM_DELAY_RANDOM] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].anim_delay_random =
- parameter[GFX_ARG_ANIM_DELAY_RANDOM];
+ g->anim_delay_random = parameter[GFX_ARG_ANIM_DELAY_RANDOM];
if (parameter[GFX_ARG_POST_DELAY_FIXED] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].post_delay_fixed =
- parameter[GFX_ARG_POST_DELAY_FIXED];
+ g->post_delay_fixed = parameter[GFX_ARG_POST_DELAY_FIXED];
if (parameter[GFX_ARG_POST_DELAY_RANDOM] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].post_delay_random =
- parameter[GFX_ARG_POST_DELAY_RANDOM];
-
- /* this is only used for toon animations */
- graphic_info[graphic].step_offset = parameter[GFX_ARG_STEP_OFFSET];
- graphic_info[graphic].step_delay = parameter[GFX_ARG_STEP_DELAY];
+ g->post_delay_random = parameter[GFX_ARG_POST_DELAY_RANDOM];
+
+ /* used for global animations */
+ if (parameter[GFX_ARG_INIT_EVENT] != ARG_UNDEFINED_VALUE)
+ g->init_event = parameter[GFX_ARG_INIT_EVENT];
+ if (parameter[GFX_ARG_ANIM_EVENT] != ARG_UNDEFINED_VALUE)
+ g->anim_event = parameter[GFX_ARG_ANIM_EVENT];
+
+ /* used for toon animations and global animations */
+ g->step_offset = parameter[GFX_ARG_STEP_OFFSET];
+ g->step_xoffset = parameter[GFX_ARG_STEP_XOFFSET];
+ g->step_yoffset = parameter[GFX_ARG_STEP_YOFFSET];
+ g->step_delay = parameter[GFX_ARG_STEP_DELAY];
+ g->direction = parameter[GFX_ARG_DIRECTION];
+ g->position = parameter[GFX_ARG_POSITION];
+ g->x = parameter[GFX_ARG_X]; // (may be uninitialized,
+ g->y = parameter[GFX_ARG_Y]; // unlike src_x and src_y)
/* this is only used for drawing font characters */
- graphic_info[graphic].draw_xoffset = parameter[GFX_ARG_DRAW_XOFFSET];
- graphic_info[graphic].draw_yoffset = parameter[GFX_ARG_DRAW_YOFFSET];
+ g->draw_xoffset = parameter[GFX_ARG_DRAW_XOFFSET];
+ g->draw_yoffset = parameter[GFX_ARG_DRAW_YOFFSET];
+
+ /* use a different default value for global animations and toons */
+ if ((graphic >= IMG_GFX_GLOBAL_ANIM_1 && graphic <= IMG_GFX_GLOBAL_ANIM_8) ||
+ (graphic >= IMG_TOON_1 && graphic <= IMG_TOON_20))
+ g->draw_masked = TRUE;
+
+ /* this is used for drawing envelopes, global animations and toons */
+ if (parameter[GFX_ARG_DRAW_MASKED] != ARG_UNDEFINED_VALUE)
+ g->draw_masked = parameter[GFX_ARG_DRAW_MASKED];
- /* this is only used for drawing envelope graphics */
- graphic_info[graphic].draw_masked = parameter[GFX_ARG_DRAW_MASKED];
+ /* used for toon animations and global animations */
+ if (parameter[GFX_ARG_DRAW_ORDER] != ARG_UNDEFINED_VALUE)
+ g->draw_order = parameter[GFX_ARG_DRAW_ORDER];
/* optional graphic for cloning all graphics settings */
if (parameter[GFX_ARG_CLONE_FROM] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].clone_from = parameter[GFX_ARG_CLONE_FROM];
+ g->clone_from = parameter[GFX_ARG_CLONE_FROM];
/* optional settings for drawing title screens and title messages */
if (parameter[GFX_ARG_FADE_MODE] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].fade_mode = parameter[GFX_ARG_FADE_MODE];
+ g->fade_mode = parameter[GFX_ARG_FADE_MODE];
if (parameter[GFX_ARG_FADE_DELAY] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].fade_delay = parameter[GFX_ARG_FADE_DELAY];
+ g->fade_delay = parameter[GFX_ARG_FADE_DELAY];
if (parameter[GFX_ARG_POST_DELAY] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].post_delay = parameter[GFX_ARG_POST_DELAY];
+ g->post_delay = parameter[GFX_ARG_POST_DELAY];
if (parameter[GFX_ARG_AUTO_DELAY] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].auto_delay = parameter[GFX_ARG_AUTO_DELAY];
+ g->auto_delay = parameter[GFX_ARG_AUTO_DELAY];
if (parameter[GFX_ARG_ALIGN] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].align = parameter[GFX_ARG_ALIGN];
+ g->align = parameter[GFX_ARG_ALIGN];
if (parameter[GFX_ARG_VALIGN] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].valign = parameter[GFX_ARG_VALIGN];
+ g->valign = parameter[GFX_ARG_VALIGN];
if (parameter[GFX_ARG_SORT_PRIORITY] != ARG_UNDEFINED_VALUE)
- graphic_info[graphic].sort_priority = parameter[GFX_ARG_SORT_PRIORITY];
+ g->sort_priority = parameter[GFX_ARG_SORT_PRIORITY];
+
+ if (parameter[GFX_ARG_CLASS] != ARG_UNDEFINED_VALUE)
+ g->class = parameter[GFX_ARG_CLASS];
+ if (parameter[GFX_ARG_STYLE] != ARG_UNDEFINED_VALUE)
+ g->style = parameter[GFX_ARG_STYLE];
+
+ /* this is only used for drawing menu buttons and text */
+ g->active_xoffset = parameter[GFX_ARG_ACTIVE_XOFFSET];
+ g->active_yoffset = parameter[GFX_ARG_ACTIVE_YOFFSET];
+ g->pressed_xoffset = parameter[GFX_ARG_PRESSED_XOFFSET];
+ g->pressed_yoffset = parameter[GFX_ARG_PRESSED_YOFFSET];
+}
+
+static void set_graphic_parameters(int graphic)
+{
+ struct FileInfo *image = getImageListEntryFromImageID(graphic);
+ char **parameter_raw = image->parameter;
+ Bitmap **src_bitmaps = getBitmapsFromImageID(graphic);
+ int parameter[NUM_GFX_ARGS];
+ int i;
+
+ /* if fallback to default artwork is done, also use the default parameters */
+ if (image->fallback_to_default)
+ parameter_raw = image->default_parameter;
+
+ /* get integer values from string parameters */
+ for (i = 0; i < NUM_GFX_ARGS; i++)
+ parameter[i] = get_graphic_parameter_value(parameter_raw[i],
+ image_config_suffix[i].token,
+ image_config_suffix[i].type);
+
+ set_graphic_parameters_ext(graphic, parameter, src_bitmaps);
UPDATE_BUSY_STATE();
}
Error(ERR_INFO, "custom graphic rejected for this element/action");
if (graphic == fallback_graphic)
- Error(ERR_EXIT, "fatal error: no fallback graphic available");
+ Error(ERR_EXIT, "no fallback graphic available");
Error(ERR_INFO, "fallback done to 'char_exclam' for this graphic");
Error(ERR_INFO_LINE, "-");
int num_images = getImageListSize();
int i;
-#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
- static boolean clipmasks_initialized = FALSE;
- Pixmap src_pixmap;
- XGCValues clip_gc_values;
- unsigned long clip_gc_valuemask;
- GC copy_clipmask_gc = None;
-#endif
-
/* use image size as default values for width and height for these images */
static int full_size_graphics[] =
{
IMG_GLOBAL_BORDER,
+ IMG_GLOBAL_BORDER_MAIN,
+ IMG_GLOBAL_BORDER_SCORES,
+ IMG_GLOBAL_BORDER_EDITOR,
+ IMG_GLOBAL_BORDER_PLAYING,
IMG_GLOBAL_DOOR,
IMG_BACKGROUND_ENVELOPE_1,
IMG_BACKGROUND_ENVELOPE_2,
IMG_BACKGROUND_ENVELOPE_3,
IMG_BACKGROUND_ENVELOPE_4,
+ IMG_BACKGROUND_REQUEST,
IMG_BACKGROUND,
IMG_BACKGROUND_TITLE_INITIAL,
IMG_BACKGROUND_TITLE,
IMG_BACKGROUND_MAIN,
IMG_BACKGROUND_LEVELS,
+ IMG_BACKGROUND_LEVELNR,
IMG_BACKGROUND_SCORES,
IMG_BACKGROUND_EDITOR,
IMG_BACKGROUND_INFO,
IMG_BACKGROUND_INFO_MUSIC,
IMG_BACKGROUND_INFO_CREDITS,
IMG_BACKGROUND_INFO_PROGRAM,
+ IMG_BACKGROUND_INFO_VERSION,
IMG_BACKGROUND_INFO_LEVELSET,
IMG_BACKGROUND_SETUP,
+ IMG_BACKGROUND_PLAYING,
IMG_BACKGROUND_DOOR,
+ IMG_BACKGROUND_TAPE,
+ IMG_BACKGROUND_PANEL,
+ IMG_BACKGROUND_PALETTE,
+ IMG_BACKGROUND_TOOLBOX,
IMG_TITLESCREEN_INITIAL_1,
IMG_TITLESCREEN_INITIAL_2,
IMG_TITLESCREEN_4,
IMG_TITLESCREEN_5,
+ IMG_BACKGROUND_TITLEMESSAGE_INITIAL_1,
+ IMG_BACKGROUND_TITLEMESSAGE_INITIAL_2,
+ IMG_BACKGROUND_TITLEMESSAGE_INITIAL_3,
+ IMG_BACKGROUND_TITLEMESSAGE_INITIAL_4,
+ IMG_BACKGROUND_TITLEMESSAGE_INITIAL_5,
+ IMG_BACKGROUND_TITLEMESSAGE_1,
+ IMG_BACKGROUND_TITLEMESSAGE_2,
+ IMG_BACKGROUND_TITLEMESSAGE_3,
+ IMG_BACKGROUND_TITLEMESSAGE_4,
+ IMG_BACKGROUND_TITLEMESSAGE_5,
+
-1
};
graphic_info = checked_calloc(num_images * sizeof(struct GraphicInfo));
-#if 1
/* initialize "use_image_size" flag with default value */
for (i = 0; i < num_images; i++)
graphic_info[i].use_image_size = FALSE;
/* initialize "use_image_size" flag from static configuration above */
for (i = 0; full_size_graphics[i] != -1; i++)
graphic_info[full_size_graphics[i]].use_image_size = TRUE;
-#endif
-
-#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
- if (clipmasks_initialized)
- {
- for (i = 0; i < num_images; i++)
- {
- if (graphic_info[i].clip_mask)
- XFreePixmap(display, graphic_info[i].clip_mask);
- if (graphic_info[i].clip_gc)
- XFreeGC(display, graphic_info[i].clip_gc);
-
- graphic_info[i].clip_mask = None;
- graphic_info[i].clip_gc = None;
- }
- }
-#endif
/* first set all graphic paramaters ... */
for (i = 0; i < num_images; i++)
for (i = 0; i < num_images; i++)
{
- Bitmap *src_bitmap;
+ Bitmap *src_bitmap = graphic_info[i].bitmap;
int src_x, src_y;
int width, height;
- int first_frame, last_frame;
+ int last_frame;
int src_bitmap_width, src_bitmap_height;
/* now check if no animation frames are outside of the loaded image */
/* check if first animation frame is inside specified bitmap */
- first_frame = 0;
- getGraphicSource(i, first_frame, &src_bitmap, &src_x, &src_y);
-
-#if 1
+ /* do not use getGraphicSourceXY() here to get position of first frame; */
/* this avoids calculating wrong start position for out-of-bounds frame */
src_x = graphic_info[i].src_x;
src_y = graphic_info[i].src_y;
-#endif
+
+ if (program.headless)
+ continue;
if (src_x < 0 || src_y < 0 ||
src_x + width > src_bitmap_width ||
Error(ERR_INFO, "- config file: '%s'", getImageConfigFilename());
Error(ERR_INFO, "- config token: '%s'", getTokenFromImageID(i));
Error(ERR_INFO, "- image file: '%s'", src_bitmap->source_filename);
+ Error(ERR_INFO, "- frame size: %d, %d", width, height);
Error(ERR_INFO,
"error: first animation frame out of bounds (%d, %d) [%d, %d]",
src_x, src_y, src_bitmap_width, src_bitmap_height);
Error(ERR_INFO, "custom graphic rejected for this element/action");
if (i == fallback_graphic)
- Error(ERR_EXIT, "fatal error: no fallback graphic available");
+ Error(ERR_EXIT, "no fallback graphic available");
Error(ERR_INFO, "fallback done to 'char_exclam' for this graphic");
Error(ERR_INFO_LINE, "-");
graphic_info[i] = graphic_info[fallback_graphic];
+
+ /* if first frame out of bounds, do not check last frame anymore */
+ continue;
}
/* check if last animation frame is inside specified bitmap */
last_frame = graphic_info[i].anim_frames - 1;
- getGraphicSource(i, last_frame, &src_bitmap, &src_x, &src_y);
+ getGraphicSourceXY(i, last_frame, &src_x, &src_y, FALSE);
if (src_x < 0 || src_y < 0 ||
src_x + width > src_bitmap_width ||
Error(ERR_INFO, "- config file: '%s'", getImageConfigFilename());
Error(ERR_INFO, "- config token: '%s'", getTokenFromImageID(i));
Error(ERR_INFO, "- image file: '%s'", src_bitmap->source_filename);
+ Error(ERR_INFO, "- frame size: %d, %d", width, height);
Error(ERR_INFO,
"error: last animation frame (%d) out of bounds (%d, %d) [%d, %d]",
last_frame, src_x, src_y, src_bitmap_width, src_bitmap_height);
Error(ERR_INFO, "custom graphic rejected for this element/action");
if (i == fallback_graphic)
- Error(ERR_EXIT, "fatal error: no fallback graphic available");
+ Error(ERR_EXIT, "no fallback graphic available");
Error(ERR_INFO, "fallback done to 'char_exclam' for this graphic");
Error(ERR_INFO_LINE, "-");
graphic_info[i] = graphic_info[fallback_graphic];
}
+ }
+}
-#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
- /* currently we only need a tile clip mask from the first frame */
- getGraphicSource(i, first_frame, &src_bitmap, &src_x, &src_y);
-
- if (copy_clipmask_gc == None)
- {
- clip_gc_values.graphics_exposures = False;
- clip_gc_valuemask = GCGraphicsExposures;
- copy_clipmask_gc = XCreateGC(display, src_bitmap->clip_mask,
- clip_gc_valuemask, &clip_gc_values);
- }
+static void InitGraphicCompatibilityInfo()
+{
+ struct FileInfo *fi_global_door =
+ getImageListEntryFromImageID(IMG_GLOBAL_DOOR);
+ int num_images = getImageListSize();
+ int i;
- graphic_info[i].clip_mask =
- XCreatePixmap(display, window->drawable, TILEX, TILEY, 1);
+ /* the following compatibility handling is needed for the following case:
+ versions up to 3.3.0.0 used one large bitmap "global.door" for various
+ graphics mainly used for door and panel graphics, like editor, tape and
+ in-game buttons with hard-coded bitmap positions and button sizes; as
+ these graphics now have individual definitions, redefining "global.door"
+ to change all these graphics at once like before does not work anymore
+ (because all those individual definitions still have their default values);
+ to solve this, remap all those individual definitions that are not
+ redefined to the new bitmap of "global.door" if it was redefined */
- src_pixmap = src_bitmap->clip_mask;
- XCopyArea(display, src_pixmap, graphic_info[i].clip_mask,
- copy_clipmask_gc, src_x, src_y, TILEX, TILEY, 0, 0);
+ /* special compatibility handling if image "global.door" was redefined */
+ if (fi_global_door->redefined)
+ {
+ for (i = 0; i < num_images; i++)
+ {
+ struct FileInfo *fi = getImageListEntryFromImageID(i);
- clip_gc_values.graphics_exposures = False;
- clip_gc_values.clip_mask = graphic_info[i].clip_mask;
- clip_gc_valuemask = GCGraphicsExposures | GCClipMask;
+ /* process only those images that still use the default settings */
+ if (!fi->redefined)
+ {
+ /* process all images which default to same image as "global.door" */
+ if (strEqual(fi->default_filename, fi_global_door->default_filename))
+ {
+ // printf("::: special treatment needed for token '%s'\n", fi->token);
- graphic_info[i].clip_gc =
- XCreateGC(display, window->drawable, clip_gc_valuemask, &clip_gc_values);
-#endif
+ graphic_info[i].bitmaps = graphic_info[IMG_GLOBAL_DOOR].bitmaps;
+ graphic_info[i].bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ }
+ }
+ }
}
-#if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND)
- if (copy_clipmask_gc)
- XFreeGC(display, copy_clipmask_gc);
-
- clipmasks_initialized = TRUE;
-#endif
+ InitGraphicCompatibilityInfo_Doors();
}
static void InitElementSoundInfo()
if (IS_SB_ELEMENT(i) && element_info[EL_SB_DEFAULT].sound[act] != -1)
default_action_sound = element_info[EL_SB_DEFAULT].sound[act];
- /* !!! there's no such thing as a "default action sound" !!! */
-#if 0
- /* look for element specific default sound (independent from action) */
- if (element_info[i].sound[ACTION_DEFAULT] != -1)
- default_action_sound = element_info[i].sound[ACTION_DEFAULT];
-#endif
-
-#if 1
/* !!! needed because EL_EMPTY_SPACE treated as IS_SP_ELEMENT !!! */
/* !!! make this better !!! */
if (i == EL_EMPTY_SPACE)
default_action_sound = element_info[EL_DEFAULT].sound[act];
-#endif
/* no sound for this specific action -- use default action sound */
if (element_info[i].sound[act] == -1)
for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
if (menu.sound[i] == -1)
menu.sound[i] = menu.sound[GAME_MODE_DEFAULT];
-
-#if 0
- for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
- if (menu.sound[i] != -1)
- printf("::: menu.sound[%d] == %d\n", i, menu.sound[i]);
-#endif
}
static void set_sound_parameters(int sound, char **parameter_raw)
sound_effect_properties[i] = ACTION_OTHER;
sound_info[i].loop = FALSE; /* default: play sound only once */
-#if 0
- printf("::: sound %d: '%s'\n", i, sound->token);
-#endif
-
/* determine all loop sounds and identify certain sound classes */
for (j = 0; element_action_info[j].suffix; j++)
int gamemode = gamemode_to_music[i].gamemode;
int music = gamemode_to_music[i].music;
-#if 0
- printf("::: gamemode == %d, music == %d\n", gamemode, music);
-#endif
-
if (gamemode < 0)
gamemode = GAME_MODE_DEFAULT;
for (i = 0; i < num_property_mappings; i++)
{
int prefix = property_mapping[i].base_index;
- int gamemode = property_mapping[i].ext1_index;
- int level = property_mapping[i].ext2_index;
+ int gamemode = property_mapping[i].ext2_index;
+ int level = property_mapping[i].ext3_index;
int music = property_mapping[i].artwork_index;
-#if 0
- printf("::: prefix == %d, gamemode == %d, level == %d, music == %d\n",
- prefix, gamemode, level, music);
-#endif
-
if (prefix < 0 || prefix >= NUM_MUSIC_PREFIXES)
continue;
for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
if (menu.music[i] == -1)
menu.music[i] = menu.music[GAME_MODE_DEFAULT];
-
-#if 0
- for (i = 0; i < MAX_LEVELS; i++)
- if (levelset.music[i] != -1)
- printf("::: levelset.music[%d] == %d\n", i, levelset.music[i]);
- for (i = 0; i < NUM_SPECIAL_GFX_ARGS; i++)
- if (menu.music[i] != -1)
- printf("::: menu.music[%d] == %d\n", i, menu.music[i]);
-#endif
}
static void set_music_parameters(int music, char **parameter_raw)
static void ReinitializeGraphics()
{
- print_init_timestamp("INIT ReinitializeGraphics");
+ print_timestamp_init("ReinitializeGraphics");
+
+ InitGfxTileSizeInfo(game.tile_size, TILESIZE);
InitGraphicInfo(); /* graphic properties mapping */
- print_init_timestamp("TIME InitGraphicInfo");
+ print_timestamp_time("InitGraphicInfo");
InitElementGraphicInfo(); /* element game graphic mapping */
- print_init_timestamp("TIME InitElementGraphicInfo");
+ print_timestamp_time("InitElementGraphicInfo");
InitElementSpecialGraphicInfo(); /* element special graphic mapping */
- print_init_timestamp("TIME InitElementSpecialGraphicInfo");
+ print_timestamp_time("InitElementSpecialGraphicInfo");
InitElementSmallImages(); /* scale elements to all needed sizes */
- print_init_timestamp("TIME InitElementSmallImages");
+ print_timestamp_time("InitElementSmallImages");
InitScaledImages(); /* scale all other images, if needed */
- print_init_timestamp("TIME InitScaledImages");
+ print_timestamp_time("InitScaledImages");
+ InitBitmapPointers(); /* set standard size bitmap pointers */
+ print_timestamp_time("InitBitmapPointers");
InitFontGraphicInfo(); /* initialize text drawing functions */
- print_init_timestamp("TIME InitFontGraphicInfo");
+ print_timestamp_time("InitFontGraphicInfo");
+ InitGlobalAnimGraphicInfo(); /* initialize global animation config */
+ print_timestamp_time("InitGlobalAnimGraphicInfo");
+
+ InitImageTextures(); /* create textures for certain images */
+ print_timestamp_time("InitImageTextures");
InitGraphicInfo_EM(); /* graphic mapping for EM engine */
- print_init_timestamp("TIME InitGraphicInfo_EM");
+ print_timestamp_time("InitGraphicInfo_EM");
+
+ InitGraphicCompatibilityInfo();
+ print_timestamp_time("InitGraphicCompatibilityInfo");
SetMainBackgroundImage(IMG_BACKGROUND);
- print_init_timestamp("TIME SetMainBackgroundImage");
+ print_timestamp_time("SetMainBackgroundImage");
SetDoorBackgroundImage(IMG_BACKGROUND_DOOR);
- print_init_timestamp("TIME SetDoorBackgroundImage");
+ print_timestamp_time("SetDoorBackgroundImage");
InitGadgets();
- print_init_timestamp("TIME InitGadgets");
- InitToons();
- print_init_timestamp("TIME InitToons");
+ print_timestamp_time("InitGadgets");
+ InitDoors();
+ print_timestamp_time("InitDoors");
- print_init_timestamp("DONE ReinitializeGraphics");
+ print_timestamp_done("ReinitializeGraphics");
}
static void ReinitializeSounds()
InitSoundInfo(); /* sound properties mapping */
InitElementSoundInfo(); /* element game sound mapping */
InitGameModeSoundInfo(); /* game mode sound mapping */
+ InitGlobalAnimSoundInfo(); /* global animation sound settings */
InitPlayLevelSound(); /* internal game sound settings */
}
{
InitMusicInfo(); /* music properties mapping */
InitGameModeMusicInfo(); /* game mode music mapping */
+ InitGlobalAnimMusicInfo(); /* global animation music settings */
}
static int get_special_property_bit(int element, int property_bit_nr)
void InitElementPropertiesStatic()
{
+ static boolean clipboard_elements_initialized = FALSE;
+
static int ep_diggable[] =
{
EL_SAND,
EL_SIGN_FRANKIE,
EL_STEEL_EXIT_CLOSED,
EL_STEEL_EXIT_OPEN,
+ EL_STEEL_EXIT_OPENING,
+ EL_STEEL_EXIT_CLOSING,
EL_EM_STEEL_EXIT_CLOSED,
EL_EM_STEEL_EXIT_OPEN,
+ EL_EM_STEEL_EXIT_OPENING,
+ EL_EM_STEEL_EXIT_CLOSING,
EL_DC_STEELWALL_1_LEFT,
EL_DC_STEELWALL_1_RIGHT,
EL_DC_STEELWALL_1_TOP,
EL_SWITCHGATE_OPENING,
EL_SWITCHGATE_CLOSED,
EL_SWITCHGATE_CLOSING,
-#if 1
EL_DC_SWITCHGATE_SWITCH_UP,
EL_DC_SWITCHGATE_SWITCH_DOWN,
-#endif
EL_TIMEGATE_OPEN,
EL_TIMEGATE_OPENING,
EL_TIMEGATE_CLOSED,
EL_TIMEGATE_CLOSING,
-#if 1
EL_DC_TIMEGATE_SWITCH,
EL_DC_TIMEGATE_SWITCH_ACTIVE,
-#endif
EL_TUBE_ANY,
EL_TUBE_VERTICAL,
EL_TUBE_HORIZONTAL,
EL_SOKOBAN_FIELD_EMPTY,
EL_EXIT_OPEN,
EL_EM_EXIT_OPEN,
+ EL_EM_EXIT_OPENING,
EL_SP_EXIT_OPEN,
EL_SP_EXIT_OPENING,
EL_STEEL_EXIT_OPEN,
EL_EM_STEEL_EXIT_OPEN,
+ EL_EM_STEEL_EXIT_OPENING,
EL_GATE_1,
EL_GATE_2,
EL_GATE_3,
EL_PLAYER_2,
EL_PLAYER_3,
EL_PLAYER_4,
+ EL_SOKOBAN_FIELD_PLAYER,
EL_SP_MURPHY,
EL_YAMYAM,
EL_YAMYAM_LEFT,
int i, j, k;
/* always start with reliable default values (element has no properties) */
+ /* (but never initialize clipboard elements after the very first time) */
+ /* (to be able to use clipboard elements between several levels) */
for (i = 0; i < MAX_NUM_ELEMENTS; i++)
- for (j = 0; j < NUM_ELEMENT_PROPERTIES; j++)
- SET_PROPERTY(i, j, FALSE);
+ if (!IS_CLIPBOARD_ELEMENT(i) || !clipboard_elements_initialized)
+ for (j = 0; j < NUM_ELEMENT_PROPERTIES; j++)
+ SET_PROPERTY(i, j, FALSE);
/* set all base element properties from above array definitions */
for (i = 0; element_properties[i].elements != NULL; i++)
/* set static element properties that are not listed in array definitions */
for (i = EL_STEEL_CHAR_START; i <= EL_STEEL_CHAR_END; i++)
SET_PROPERTY(i, EP_INDESTRUCTIBLE, TRUE);
+
+ clipboard_elements_initialized = TRUE;
}
void InitElementPropertiesEngine(int engine_version)
/* set all special, combined or engine dependent element properties */
for (i = 0; i < MAX_NUM_ELEMENTS; i++)
{
+ /* do not change (already initialized) clipboard elements here */
+ if (IS_CLIPBOARD_ELEMENT(i))
+ continue;
+
/* ---------- INACTIVE ------------------------------------------------- */
SET_PROPERTY(i, EP_INACTIVE, ((i >= EL_CHAR_START &&
i <= EL_CHAR_END) ||
HAS_ACTION(i)));
/* ---------- GFX_CRUMBLED --------------------------------------------- */
-#if 1
SET_PROPERTY(i, EP_GFX_CRUMBLED,
element_info[i].crumbled[ACTION_DEFAULT] !=
element_info[i].graphic[ACTION_DEFAULT]);
-#else
- /* !!! THIS LOOKS CRAPPY FOR SAND ETC. WITHOUT CRUMBLED GRAPHICS !!! */
- SET_PROPERTY(i, EP_GFX_CRUMBLED,
- element_info[i].crumbled[ACTION_DEFAULT] != IMG_EMPTY);
-#endif
/* ---------- EDITOR_CASCADE ------------------------------------------- */
SET_PROPERTY(i, EP_EDITOR_CASCADE, (IS_EDITOR_CASCADE_ACTIVE(i) ||
-1
};
+ static int ep_em_explodes_by_fire[] =
+ {
+ EL_EM_DYNAMITE,
+ EL_EM_DYNAMITE_ACTIVE,
+ EL_MOLE,
+ -1
+ };
+
/* special EM style gems behaviour */
for (i = 0; ep_em_slippery_wall[i] != -1; i++)
SET_PROPERTY(ep_em_slippery_wall[i], EP_EM_SLIPPERY_WALL,
SET_PROPERTY(EL_EXPANDABLE_WALL_GROWING, EP_EM_SLIPPERY_WALL,
(level.em_slippery_gems &&
engine_version > VERSION_IDENT(2,0,1,0)));
+
+ /* special EM style explosion behaviour regarding chain reactions */
+ for (i = 0; ep_em_explodes_by_fire[i] != -1; i++)
+ SET_PROPERTY(ep_em_explodes_by_fire[i], EP_EXPLODES_BY_FIRE,
+ level.em_explodes_by_fire);
}
/* this is needed because some graphics depend on element properties */
}
}
+void InitElementPropertiesGfxElement()
+{
+ int i;
+
+ for (i = 0; i < MAX_NUM_ELEMENTS; i++)
+ {
+ struct ElementInfo *ei = &element_info[i];
+
+ ei->gfx_element = (ei->use_gfx_element ? ei->gfx_element_initial : i);
+ }
+}
+
static void InitGlobal()
{
+ int graphic;
int i;
for (i = 0; i < MAX_NUM_ELEMENTS + 1; i++)
element_info[i].token_name = element_name_info[i].token_name;
element_info[i].class_name = element_name_info[i].class_name;
element_info[i].editor_description= element_name_info[i].editor_description;
+ }
-#if 0
- printf("%04d: %s\n", i, element_name_info[i].token_name);
-#endif
+ for (i = 0; i < NUM_GLOBAL_ANIM_TOKENS + 1; i++)
+ {
+ /* check if global_anim_name_info defined for each entry in "main.h" */
+ if (i < NUM_GLOBAL_ANIM_TOKENS &&
+ global_anim_name_info[i].token_name == NULL)
+ Error(ERR_EXIT, "undefined 'global_anim_name_info' entry for anim %d", i);
+
+ global_anim_info[i].token_name = global_anim_name_info[i].token_name;
+ }
+
+ /* create hash from image config list */
+ image_config_hash = newSetupFileHash();
+ for (i = 0; image_config[i].token != NULL; i++)
+ setHashEntry(image_config_hash,
+ image_config[i].token,
+ image_config[i].value);
+
+ /* create hash from element token list */
+ element_token_hash = newSetupFileHash();
+ for (i = 0; element_name_info[i].token_name != NULL; i++)
+ setHashEntry(element_token_hash,
+ element_name_info[i].token_name,
+ int2str(i, 0));
+
+ /* create hash from graphic token list */
+ graphic_token_hash = newSetupFileHash();
+ for (graphic = 0, i = 0; image_config[i].token != NULL; i++)
+ if (strSuffix(image_config[i].value, ".png") ||
+ strSuffix(image_config[i].value, ".pcx") ||
+ strSuffix(image_config[i].value, ".wav") ||
+ strEqual(image_config[i].value, UNDEFINED_FILENAME))
+ setHashEntry(graphic_token_hash,
+ image_config[i].token,
+ int2str(graphic++, 0));
+
+ /* create hash from font token list */
+ font_token_hash = newSetupFileHash();
+ for (i = 0; font_info[i].token_name != NULL; i++)
+ setHashEntry(font_token_hash,
+ font_info[i].token_name,
+ int2str(i, 0));
+
+ /* set default filenames for all cloned graphics in static configuration */
+ for (i = 0; image_config[i].token != NULL; i++)
+ {
+ if (strEqual(image_config[i].value, UNDEFINED_FILENAME))
+ {
+ char *token = image_config[i].token;
+ char *token_clone_from = getStringCat2(token, ".clone_from");
+ char *token_cloned = getHashEntry(image_config_hash, token_clone_from);
+
+ if (token_cloned != NULL)
+ {
+ char *value_cloned = getHashEntry(image_config_hash, token_cloned);
+
+ if (value_cloned != NULL)
+ {
+ /* set default filename in static configuration */
+ image_config[i].value = value_cloned;
+
+ /* set default filename in image config hash */
+ setHashEntry(image_config_hash, token, value_cloned);
+ }
+ }
+
+ free(token_clone_from);
+ }
}
/* always start with reliable default values (all elements) */
global.autoplay_leveldir = NULL;
global.convert_leveldir = NULL;
+ global.create_images_dir = NULL;
global.frames_per_second = 0;
- global.fps_slowdown = FALSE;
- global.fps_slowdown_factor = 1;
+ global.show_frames_per_second = FALSE;
- global.border_status = GAME_MODE_MAIN;
-#if 0
- global.fading_status = GAME_MODE_MAIN;
- global.fading_type = TYPE_ENTER_MENU;
-#endif
+ global.border_status = GAME_MODE_LOADING;
+ global.anim_status = global.anim_status_next = GAME_MODE_LOADING;
+
+ global.use_envelope_request = FALSE;
}
void Execute_Command(char *command)
if (strEqual(command, "print graphicsinfo.conf"))
{
- printf("# You can configure additional/alternative image files here.\n");
- printf("# (The entries below are default and therefore commented out.)\n");
- printf("\n");
- printf("%s\n", getFormattedSetupEntry("name", "Classic Graphics"));
- printf("\n");
- printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
- printf("\n");
+ Print("# You can configure additional/alternative image files here.\n");
+ Print("# (The entries below are default and therefore commented out.)\n");
+ Print("\n");
+ Print("%s\n", getFormattedSetupEntry("name", "Classic Graphics"));
+ Print("\n");
+ Print("%s\n", getFormattedSetupEntry("sort_priority", "100"));
+ Print("\n");
for (i = 0; image_config[i].token != NULL; i++)
- printf("# %s\n", getFormattedSetupEntry(image_config[i].token,
- image_config[i].value));
+ Print("# %s\n", getFormattedSetupEntry(image_config[i].token,
+ image_config[i].value));
exit(0);
}
else if (strEqual(command, "print soundsinfo.conf"))
{
- printf("# You can configure additional/alternative sound files here.\n");
- printf("# (The entries below are default and therefore commented out.)\n");
- printf("\n");
- printf("%s\n", getFormattedSetupEntry("name", "Classic Sounds"));
- printf("\n");
- printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
- printf("\n");
+ Print("# You can configure additional/alternative sound files here.\n");
+ Print("# (The entries below are default and therefore commented out.)\n");
+ Print("\n");
+ Print("%s\n", getFormattedSetupEntry("name", "Classic Sounds"));
+ Print("\n");
+ Print("%s\n", getFormattedSetupEntry("sort_priority", "100"));
+ Print("\n");
for (i = 0; sound_config[i].token != NULL; i++)
- printf("# %s\n", getFormattedSetupEntry(sound_config[i].token,
- sound_config[i].value));
+ Print("# %s\n", getFormattedSetupEntry(sound_config[i].token,
+ sound_config[i].value));
exit(0);
}
else if (strEqual(command, "print musicinfo.conf"))
{
- printf("# You can configure additional/alternative music files here.\n");
- printf("# (The entries below are default and therefore commented out.)\n");
- printf("\n");
- printf("%s\n", getFormattedSetupEntry("name", "Classic Music"));
- printf("\n");
- printf("%s\n", getFormattedSetupEntry("sort_priority", "100"));
- printf("\n");
+ Print("# You can configure additional/alternative music files here.\n");
+ Print("# (The entries below are default and therefore commented out.)\n");
+ Print("\n");
+ Print("%s\n", getFormattedSetupEntry("name", "Classic Music"));
+ Print("\n");
+ Print("%s\n", getFormattedSetupEntry("sort_priority", "100"));
+ Print("\n");
for (i = 0; music_config[i].token != NULL; i++)
- printf("# %s\n", getFormattedSetupEntry(music_config[i].token,
- music_config[i].value));
+ Print("# %s\n", getFormattedSetupEntry(music_config[i].token,
+ music_config[i].value));
exit(0);
}
else if (strEqual(command, "print editorsetup.conf"))
{
- printf("# You can configure your personal editor element list here.\n");
- printf("# (The entries below are default and therefore commented out.)\n");
- printf("\n");
+ Print("# You can configure your personal editor element list here.\n");
+ Print("# (The entries below are default and therefore commented out.)\n");
+ Print("\n");
/* this is needed to be able to check element list for cascade elements */
InitElementPropertiesStatic();
}
else if (strEqual(command, "print helpanim.conf"))
{
- printf("# You can configure different element help animations here.\n");
- printf("# (The entries below are default and therefore commented out.)\n");
- printf("\n");
+ Print("# You can configure different element help animations here.\n");
+ Print("# (The entries below are default and therefore commented out.)\n");
+ Print("\n");
for (i = 0; helpanim_config[i].token != NULL; i++)
{
- printf("# %s\n", getFormattedSetupEntry(helpanim_config[i].token,
- helpanim_config[i].value));
+ Print("# %s\n", getFormattedSetupEntry(helpanim_config[i].token,
+ helpanim_config[i].value));
if (strEqual(helpanim_config[i].token, "end"))
- printf("#\n");
+ Print("#\n");
}
exit(0);
}
else if (strEqual(command, "print helptext.conf"))
{
- printf("# You can configure different element help text here.\n");
- printf("# (The entries below are default and therefore commented out.)\n");
- printf("\n");
+ Print("# You can configure different element help text here.\n");
+ Print("# (The entries below are default and therefore commented out.)\n");
+ Print("\n");
for (i = 0; helptext_config[i].token != NULL; i++)
- printf("# %s\n", getFormattedSetupEntry(helptext_config[i].token,
- helptext_config[i].value));
+ Print("# %s\n", getFormattedSetupEntry(helptext_config[i].token,
+ helptext_config[i].value));
exit(0);
}
- else if (strncmp(command, "dump level ", 11) == 0)
+ else if (strPrefix(command, "dump level "))
{
char *filename = &command[11];
exit(0);
}
- else if (strncmp(command, "dump tape ", 10) == 0)
+ else if (strPrefix(command, "dump tape "))
{
char *filename = &command[10];
exit(0);
}
- else if (strncmp(command, "autoplay ", 9) == 0)
+ else if (strPrefix(command, "autotest ") ||
+ strPrefix(command, "autoplay ") ||
+ strPrefix(command, "autoffwd ") ||
+ strPrefix(command, "autowarp "))
{
char *str_ptr = getStringCopy(&command[9]); /* read command parameters */
+ global.autoplay_mode =
+ (strPrefix(command, "autotest") ? AUTOPLAY_MODE_TEST :
+ strPrefix(command, "autoplay") ? AUTOPLAY_MODE_PLAY :
+ strPrefix(command, "autoffwd") ? AUTOPLAY_MODE_FFWD :
+ strPrefix(command, "autowarp") ? AUTOPLAY_MODE_WARP :
+ AUTOPLAY_MODE_NONE);
+
while (*str_ptr != '\0') /* continue parsing string */
{
/* cut leading whitespace from string, replace it by string terminator */
while (*str_ptr != ' ' && *str_ptr != '\t' && *str_ptr != '\0')
str_ptr++;
}
+
+ if (global.autoplay_mode == AUTOPLAY_MODE_TEST)
+ program.headless = TRUE;
}
- else if (strncmp(command, "convert ", 8) == 0)
+ else if (strPrefix(command, "convert "))
{
- char *str_copy = getStringCopy(&command[8]);
+ char *str_copy = getStringCopy(strchr(command, ' ') + 1);
char *str_ptr = strchr(str_copy, ' ');
global.convert_leveldir = str_copy;
*str_ptr++ = '\0'; /* terminate leveldir string */
global.convert_level_nr = atoi(str_ptr); /* get level_nr value */
}
- }
-#if DEBUG
-#if defined(TARGET_SDL)
- else if (strEqual(command, "SDL_ListModes"))
+ program.headless = TRUE;
+ }
+ else if (strPrefix(command, "create images "))
{
- SDL_Rect **modes;
- int i;
-
- SDL_Init(SDL_INIT_VIDEO);
-
- /* get available fullscreen/hardware modes */
- modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE);
-
- /* check if there are any modes available */
- if (modes == NULL)
- {
- printf("No modes available!\n");
-
- exit(-1);
- }
-
- /* check if our resolution is restricted */
- if (modes == (SDL_Rect **)-1)
- {
- printf("All resolutions available.\n");
- }
- else
- {
- printf("Available Modes:\n");
+ global.create_images_dir = getStringCopy(&command[14]);
- for(i = 0; modes[i]; i++)
- printf(" %d x %d\n", modes[i]->w, modes[i]->h);
- }
+ if (access(global.create_images_dir, W_OK) != 0)
+ Error(ERR_EXIT, "image target directory '%s' not found or not writable",
+ global.create_images_dir);
+ }
+ else if (strPrefix(command, "create CE image "))
+ {
+ CreateCustomElementImages(&command[16]);
exit(0);
}
-#endif
-#endif
-
else
{
Error(ERR_EXIT_HELP, "unrecognized command '%s'", command);
if (setup.options.verbose)
options.verbose = TRUE;
+
+ if (setup.debug.show_frames_per_second)
+ global.show_frames_per_second = TRUE;
}
static void InitGameInfo()
return id_suffix;
}
-#if 0
-static char *get_element_class_token(int element)
-{
- char *element_class_name = element_info[element].class_name;
- char *element_class_token = checked_malloc(strlen(element_class_name) + 3);
-
- sprintf(element_class_token, "[%s]", element_class_name);
-
- return element_class_token;
-}
-
-static char *get_action_class_token(int action)
-{
- char *action_class_name = &element_action_info[action].suffix[1];
- char *action_class_token = checked_malloc(strlen(action_class_name) + 3);
-
- sprintf(action_class_token, "[%s]", action_class_name);
-
- return action_class_token;
-}
-#endif
-
static void InitArtworkConfig()
{
- static char *image_id_prefix[MAX_NUM_ELEMENTS + NUM_FONTS + 1];
- static char *sound_id_prefix[2 * MAX_NUM_ELEMENTS + 1];
- static char *music_id_prefix[NUM_MUSIC_PREFIXES + 1];
+ static char *image_id_prefix[MAX_NUM_ELEMENTS +
+ NUM_FONTS +
+ NUM_GLOBAL_ANIM_TOKENS + 1];
+ static char *sound_id_prefix[2 * MAX_NUM_ELEMENTS +
+ NUM_GLOBAL_ANIM_TOKENS + 1];
+ static char *music_id_prefix[NUM_MUSIC_PREFIXES +
+ NUM_GLOBAL_ANIM_TOKENS + 1];
static char *action_id_suffix[NUM_ACTIONS + 1];
static char *direction_id_suffix[NUM_DIRECTIONS_FULL + 1];
static char *special_id_suffix[NUM_SPECIAL_GFX_ARGS + 1];
image_id_prefix[i] = element_info[i].token_name;
for (i = 0; i < NUM_FONTS; i++)
image_id_prefix[MAX_NUM_ELEMENTS + i] = font_info[i].token_name;
- image_id_prefix[MAX_NUM_ELEMENTS + NUM_FONTS] = NULL;
+ for (i = 0; i < NUM_GLOBAL_ANIM_TOKENS; i++)
+ image_id_prefix[MAX_NUM_ELEMENTS + NUM_FONTS + i] =
+ global_anim_info[i].token_name;
+ image_id_prefix[MAX_NUM_ELEMENTS + NUM_FONTS + NUM_GLOBAL_ANIM_TOKENS] = NULL;
for (i = 0; i < MAX_NUM_ELEMENTS; i++)
sound_id_prefix[i] = element_info[i].token_name;
for (i = 0; i < MAX_NUM_ELEMENTS; i++)
sound_id_prefix[MAX_NUM_ELEMENTS + i] =
get_string_in_brackets(element_info[i].class_name);
- sound_id_prefix[2 * MAX_NUM_ELEMENTS] = NULL;
+ for (i = 0; i < NUM_GLOBAL_ANIM_TOKENS; i++)
+ sound_id_prefix[2 * MAX_NUM_ELEMENTS + i] =
+ global_anim_info[i].token_name;
+ sound_id_prefix[2 * MAX_NUM_ELEMENTS + NUM_GLOBAL_ANIM_TOKENS] = NULL;
for (i = 0; i < NUM_MUSIC_PREFIXES; i++)
music_id_prefix[i] = music_prefix_info[i].prefix;
- music_id_prefix[NUM_MUSIC_PREFIXES] = NULL;
+ for (i = 0; i < NUM_GLOBAL_ANIM_TOKENS; i++)
+ music_id_prefix[NUM_MUSIC_PREFIXES + i] =
+ global_anim_info[i].token_name;
+ music_id_prefix[NUM_MUSIC_PREFIXES + NUM_GLOBAL_ANIM_TOKENS] = NULL;
for (i = 0; i < NUM_ACTIONS; i++)
action_id_suffix[i] = element_action_info[i].suffix;
sound_id_prefix, action_id_suffix, dummy,
special_id_suffix, ignore_sound_tokens);
InitMusicList(music_config, NUM_MUSIC_FILES, music_config_suffix,
- music_id_prefix, special_id_suffix, level_id_suffix,
- dummy, ignore_music_tokens);
+ music_id_prefix, action_id_suffix, special_id_suffix,
+ level_id_suffix, ignore_music_tokens);
}
static void InitMixer()
{
OpenAudio();
+
StartMixer();
}
+void InitGfxBuffers()
+{
+ static int win_xsize_last = -1;
+ static int win_ysize_last = -1;
+
+ /* create additional image buffers for double-buffering and cross-fading */
+
+ if (WIN_XSIZE != win_xsize_last || WIN_YSIZE != win_ysize_last)
+ {
+ /* used to temporarily store the backbuffer -- only re-create if changed */
+ ReCreateBitmap(&bitmap_db_store_1, WIN_XSIZE, WIN_YSIZE);
+ ReCreateBitmap(&bitmap_db_store_2, WIN_XSIZE, WIN_YSIZE);
+
+ win_xsize_last = WIN_XSIZE;
+ win_ysize_last = WIN_YSIZE;
+ }
+
+ ReCreateBitmap(&bitmap_db_field, FXSIZE, FYSIZE);
+ ReCreateBitmap(&bitmap_db_panel, DXSIZE, DYSIZE);
+ ReCreateBitmap(&bitmap_db_door_1, 3 * DXSIZE, DYSIZE);
+ ReCreateBitmap(&bitmap_db_door_2, 3 * VXSIZE, VYSIZE);
+
+ /* initialize screen properties */
+ InitGfxFieldInfo(SX, SY, SXSIZE, SYSIZE,
+ REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE,
+ bitmap_db_field);
+ InitGfxDoor1Info(DX, DY, DXSIZE, DYSIZE);
+ InitGfxDoor2Info(VX, VY, VXSIZE, VYSIZE);
+ InitGfxDoor3Info(EX, EY, EXSIZE, EYSIZE);
+ InitGfxWindowInfo(WIN_XSIZE, WIN_YSIZE);
+ InitGfxScrollbufferInfo(FXSIZE, FYSIZE);
+ InitGfxClipRegion(FALSE, -1, -1, -1, -1);
+
+ /* required if door size definitions have changed */
+ InitGraphicCompatibilityInfo_Doors();
+
+ InitGfxBuffers_EM();
+ InitGfxBuffers_SP();
+}
+
void InitGfx()
{
+ struct GraphicInfo *graphic_info_last = graphic_info;
char *filename_font_initial = NULL;
char *filename_anim_initial = NULL;
Bitmap *bitmap_font_initial = NULL;
if (filename_font_initial == NULL) /* should not happen */
Error(ERR_EXIT, "cannot get filename for '%s'", CONFIG_TOKEN_FONT_INITIAL);
- /* create additional image buffers for double-buffering and cross-fading */
- bitmap_db_cross = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
- bitmap_db_field = CreateBitmap(FXSIZE, FYSIZE, DEFAULT_DEPTH);
- bitmap_db_panel = CreateBitmap(DXSIZE, DYSIZE, DEFAULT_DEPTH);
- bitmap_db_door = CreateBitmap(3 * DXSIZE, DYSIZE + VYSIZE, DEFAULT_DEPTH);
-
- /* initialize screen properties */
- InitGfxFieldInfo(SX, SY, SXSIZE, SYSIZE,
- REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE,
- bitmap_db_field);
- InitGfxDoor1Info(DX, DY, DXSIZE, DYSIZE);
- InitGfxDoor2Info(VX, VY, VXSIZE, VYSIZE);
- InitGfxScrollbufferInfo(FXSIZE, FYSIZE);
+ InitGfxBuffers();
+ InitGfxCustomArtworkInfo();
+ InitGfxOtherSettings();
bitmap_font_initial = LoadCustomImage(filename_font_initial);
font_height = getFontHeight(FC_RED);
-#if 1
- DrawInitText(getWindowTitleString(), 20, FC_YELLOW);
-#else
DrawInitText(getProgramInitString(), 20, FC_YELLOW);
-#endif
- DrawInitText(PROGRAM_COPYRIGHT_STRING, 50, FC_RED);
- DrawInitText(PROGRAM_WEBSITE_STRING, WIN_YSIZE - 20 - font_height, FC_RED);
+ DrawInitText(setup.internal.program_copyright, 50, FC_RED);
+ DrawInitText(setup.internal.program_website, WIN_YSIZE - 20 - font_height,
+ FC_RED);
DrawInitText("Loading graphics", 120, FC_GREEN);
-#if 1
- /* determine settings for busy animation (when displaying startup messages) */
- for (i = 0; image_config[i].token != NULL; i++)
+ /* initialize settings for busy animation with default values */
+ int parameter[NUM_GFX_ARGS];
+ for (i = 0; i < NUM_GFX_ARGS; i++)
+ parameter[i] = get_graphic_parameter_value(image_config_suffix[i].value,
+ image_config_suffix[i].token,
+ image_config_suffix[i].type);
+
+ char *anim_token = CONFIG_TOKEN_GLOBAL_BUSY;
+ int len_anim_token = strlen(anim_token);
+
+ /* read settings for busy animation from default custom artwork config */
+ char *gfx_config_filename = getPath3(options.graphics_directory,
+ GFX_DEFAULT_SUBDIR,
+ GRAPHICSINFO_FILENAME);
+
+ if (fileExists(gfx_config_filename))
{
- char *anim_token = CONFIG_TOKEN_GLOBAL_BUSY;
- int len_anim_token = strlen(anim_token);
+ SetupFileHash *setup_file_hash = loadSetupFileHash(gfx_config_filename);
- if (strEqual(image_config[i].token, anim_token))
- filename_anim_initial = image_config[i].value;
- else if (strlen(image_config[i].token) > len_anim_token &&
- strncmp(image_config[i].token, anim_token, len_anim_token) == 0)
+ if (setup_file_hash)
{
- if (strEqual(&image_config[i].token[len_anim_token], ".x"))
- anim_initial.src_x = atoi(image_config[i].value);
- else if (strEqual(&image_config[i].token[len_anim_token], ".y"))
- anim_initial.src_y = atoi(image_config[i].value);
- else if (strEqual(&image_config[i].token[len_anim_token], ".width"))
- anim_initial.width = atoi(image_config[i].value);
- else if (strEqual(&image_config[i].token[len_anim_token], ".height"))
- anim_initial.height = atoi(image_config[i].value);
- else if (strEqual(&image_config[i].token[len_anim_token], ".frames"))
- anim_initial.anim_frames = atoi(image_config[i].value);
- else if (strEqual(&image_config[i].token[len_anim_token],
- ".frames_per_line"))
- anim_initial.anim_frames_per_line = atoi(image_config[i].value);
- else if (strEqual(&image_config[i].token[len_anim_token], ".delay"))
- anim_initial.anim_delay = atoi(image_config[i].value);
+ char *filename = getHashEntry(setup_file_hash, anim_token);
+
+ if (filename)
+ {
+ filename_anim_initial = getStringCopy(filename);
+
+ for (j = 0; image_config_suffix[j].token != NULL; j++)
+ {
+ int type = image_config_suffix[j].type;
+ char *suffix = image_config_suffix[j].token;
+ char *token = getStringCat2(anim_token, suffix);
+ char *value = getHashEntry(setup_file_hash, token);
+
+ checked_free(token);
+
+ if (value)
+ parameter[j] = get_graphic_parameter_value(value, suffix, type);
+ }
+ }
+
+ freeSetupFileHash(setup_file_hash);
+ }
+ }
+
+ if (filename_anim_initial == NULL)
+ {
+ /* read settings for busy animation from static default artwork config */
+ for (i = 0; image_config[i].token != NULL; i++)
+ {
+ if (strEqual(image_config[i].token, anim_token))
+ filename_anim_initial = getStringCopy(image_config[i].value);
+ else if (strlen(image_config[i].token) > len_anim_token &&
+ strncmp(image_config[i].token, anim_token, len_anim_token) == 0)
+ {
+ for (j = 0; image_config_suffix[j].token != NULL; j++)
+ {
+ if (strEqual(&image_config[i].token[len_anim_token],
+ image_config_suffix[j].token))
+ parameter[j] =
+ get_graphic_parameter_value(image_config[i].value,
+ image_config_suffix[j].token,
+ image_config_suffix[j].type);
+ }
+ }
}
}
if (filename_anim_initial == NULL) /* should not happen */
Error(ERR_EXIT, "cannot get filename for '%s'", CONFIG_TOKEN_GLOBAL_BUSY);
- anim_initial.bitmap = LoadCustomImage(filename_anim_initial);
+ anim_initial.bitmaps =
+ checked_calloc(sizeof(Bitmap *) * NUM_IMG_BITMAP_POINTERS);
+
+ anim_initial.bitmaps[IMG_BITMAP_STANDARD] =
+ LoadCustomImage(filename_anim_initial);
+
+ checked_free(filename_anim_initial);
+
+ graphic_info = &anim_initial; /* graphic == 0 => anim_initial */
+
+ set_graphic_parameters_ext(0, parameter, anim_initial.bitmaps);
+
+ graphic_info = graphic_info_last;
+
+ init.busy.width = anim_initial.width;
+ init.busy.height = anim_initial.height;
+
+ InitMenuDesignSettings_Static();
InitGfxDrawBusyAnimFunction(DrawInitAnim);
-#endif
-}
+ InitGfxDrawGlobalAnimFunction(DrawGlobalAnimations);
+ InitGfxDrawGlobalBorderFunction(DrawMaskedBorderToTarget);
-void RedrawBackground()
-{
- BlitBitmap(graphic_info[IMG_GLOBAL_BORDER].bitmap, backbuffer,
- 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+ gfx.fade_border_source_status = global.border_status;
+ gfx.fade_border_target_status = global.border_status;
+ gfx.masked_border_bitmap_ptr = backbuffer;
- redraw_mask = REDRAW_ALL;
+ /* use copy of busy animation to prevent change while reloading artwork */
+ init_last = init;
}
void InitGfxBackground()
{
- int x, y;
-
fieldbuffer = bitmap_db_field;
- SetDrawtoField(DRAW_BACKBUFFER);
+ SetDrawtoField(DRAW_TO_BACKBUFFER);
-#if 1
ClearRectangle(backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE);
-#else
- RedrawBackground();
- ClearRectangle(backbuffer, REAL_SX, REAL_SY, FULL_SXSIZE, FULL_SYSIZE);
- ClearRectangle(bitmap_db_door, 0, 0, 3 * DXSIZE, DYSIZE + VYSIZE);
-#endif
-
- for (x = 0; x < MAX_BUF_XSIZE; x++)
- for (y = 0; y < MAX_BUF_YSIZE; y++)
- redraw[x][y] = 0;
- redraw_tiles = 0;
redraw_mask = REDRAW_ALL;
}
LoadLevelInfo(); /* global level info */
LoadLevelSetup_LastSeries(); /* last played series info */
LoadLevelSetup_SeriesInfo(); /* last played level info */
+
+ if (global.autoplay_leveldir &&
+ global.autoplay_mode != AUTOPLAY_MODE_TEST)
+ {
+ leveldir_current = getTreeInfoFromIdentifier(leveldir_first,
+ global.autoplay_leveldir);
+ if (leveldir_current == NULL)
+ leveldir_current = getFirstValidTreeInfoEntry(leveldir_first);
+ }
}
-void InitLevelArtworkInfo()
+static void InitLevelArtworkInfo()
{
LoadLevelArtworkInfo();
}
static void InitImages()
{
- print_init_timestamp("INIT InitImages");
+ print_timestamp_init("InitImages");
+
+#if 0
+ printf("::: leveldir_current->identifier == '%s'\n",
+ leveldir_current == NULL ? "[NULL]" : leveldir_current->identifier);
+ printf("::: leveldir_current->graphics_path == '%s'\n",
+ leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_path);
+ printf("::: leveldir_current->graphics_set == '%s'\n",
+ leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_set);
+ printf("::: getLevelArtworkSet(ARTWORK_TYPE_GRAPHICS) == '%s'\n",
+ leveldir_current == NULL ? "[NULL]" : LEVELDIR_ARTWORK_SET(leveldir_current, ARTWORK_TYPE_GRAPHICS));
+#endif
setLevelArtworkDir(artwork.gfx_first);
+#if 0
+ printf("::: leveldir_current->identifier == '%s'\n",
+ leveldir_current == NULL ? "[NULL]" : leveldir_current->identifier);
+ printf("::: leveldir_current->graphics_path == '%s'\n",
+ leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_path);
+ printf("::: leveldir_current->graphics_set == '%s'\n",
+ leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_set);
+ printf("::: getLevelArtworkSet(ARTWORK_TYPE_GRAPHICS) == '%s'\n",
+ leveldir_current == NULL ? "[NULL]" : LEVELDIR_ARTWORK_SET(leveldir_current, ARTWORK_TYPE_GRAPHICS));
+#endif
+
#if 0
printf("::: InitImages for '%s' ['%s', '%s'] ['%s', '%s']\n",
leveldir_current->identifier,
UPDATE_BUSY_STATE();
ReloadCustomImages();
- print_init_timestamp("TIME ReloadCustomImages");
+ print_timestamp_time("ReloadCustomImages");
UPDATE_BUSY_STATE();
LoadCustomElementDescriptions();
- print_init_timestamp("TIME LoadCustomElementDescriptions");
+ print_timestamp_time("LoadCustomElementDescriptions");
UPDATE_BUSY_STATE();
LoadMenuDesignSettings();
- print_init_timestamp("TIME LoadMenuDesignSettings");
+ print_timestamp_time("LoadMenuDesignSettings");
UPDATE_BUSY_STATE();
ReinitializeGraphics();
- print_init_timestamp("TIME ReinitializeGraphics");
+ print_timestamp_time("ReinitializeGraphics");
+
+ LoadMenuDesignSettings_AfterGraphics();
+ print_timestamp_time("LoadMenuDesignSettings_AfterGraphics");
UPDATE_BUSY_STATE();
- print_init_timestamp("DONE InitImages");
+ print_timestamp_done("InitImages");
}
static void InitSound(char *identifier)
{
- print_init_timestamp("INIT InitSound");
+ print_timestamp_init("InitSound");
if (identifier == NULL)
identifier = artwork.snd_current->identifier;
setLevelArtworkDir(artwork.snd_first);
InitReloadCustomSounds(identifier);
- print_init_timestamp("TIME InitReloadCustomSounds");
+ print_timestamp_time("InitReloadCustomSounds");
ReinitializeSounds();
- print_init_timestamp("TIME ReinitializeSounds");
+ print_timestamp_time("ReinitializeSounds");
- print_init_timestamp("DONE InitSound");
+ print_timestamp_done("InitSound");
}
static void InitMusic(char *identifier)
{
- print_init_timestamp("INIT InitMusic");
+ print_timestamp_init("InitMusic");
if (identifier == NULL)
identifier = artwork.mus_current->identifier;
setLevelArtworkDir(artwork.mus_first);
InitReloadCustomMusic(identifier);
- print_init_timestamp("TIME InitReloadCustomMusic");
+ print_timestamp_time("InitReloadCustomMusic");
ReinitializeMusic();
- print_init_timestamp("TIME ReinitializeMusic");
+ print_timestamp_time("ReinitializeMusic");
- print_init_timestamp("DONE InitMusic");
+ print_timestamp_done("InitMusic");
+}
+
+static void InitArtworkDone()
+{
+ if (program.headless)
+ return;
+
+ InitGlobalAnimations();
}
void InitNetworkServer()
#endif
}
+static boolean CheckArtworkConfigForCustomElements(char *filename)
+{
+ SetupFileHash *setup_file_hash;
+ boolean redefined_ce_found = FALSE;
+
+ /* !!! CACHE THIS BY USING HASH 'filename' => 'true/false' !!! */
+
+ if ((setup_file_hash = loadSetupFileHash(filename)) != NULL)
+ {
+ BEGIN_HASH_ITERATION(setup_file_hash, itr)
+ {
+ char *token = HASH_ITERATION_TOKEN(itr);
+
+ if (strPrefix(token, "custom_"))
+ {
+ redefined_ce_found = TRUE;
+
+ break;
+ }
+ }
+ END_HASH_ITERATION(setup_file_hash, itr)
+
+ freeSetupFileHash(setup_file_hash);
+ }
+
+ return redefined_ce_found;
+}
+
+static boolean CheckArtworkTypeForRedefinedCustomElements(int type)
+{
+ char *filename_base, *filename_local;
+ boolean redefined_ce_found = FALSE;
+
+ setLevelArtworkDir(ARTWORK_FIRST_NODE(artwork, type));
+
+#if 0
+ printf("::: leveldir_current->identifier == '%s'\n",
+ leveldir_current == NULL ? "[NULL]" : leveldir_current->identifier);
+ printf("::: leveldir_current->graphics_path == '%s'\n",
+ leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_path);
+ printf("::: leveldir_current->graphics_set == '%s'\n",
+ leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_set);
+ printf("::: getLevelArtworkSet(ARTWORK_TYPE_GRAPHICS) == '%s'\n",
+ leveldir_current == NULL ? "[NULL]" :
+ LEVELDIR_ARTWORK_SET(leveldir_current, type));
+#endif
+
+ /* first look for special artwork configured in level series config */
+ filename_base = getCustomArtworkLevelConfigFilename(type);
+
+#if 0
+ printf("::: filename_base == '%s'\n", filename_base);
+#endif
+
+ if (fileExists(filename_base))
+ redefined_ce_found |= CheckArtworkConfigForCustomElements(filename_base);
+
+ filename_local = getCustomArtworkConfigFilename(type);
+
+#if 0
+ printf("::: filename_local == '%s'\n", filename_local);
+#endif
+
+ if (filename_local != NULL && !strEqual(filename_base, filename_local))
+ redefined_ce_found |= CheckArtworkConfigForCustomElements(filename_local);
+
+#if 0
+ printf("::: redefined_ce_found == %d\n", redefined_ce_found);
+#endif
+
+ return redefined_ce_found;
+}
+
+static void InitOverrideArtwork()
+{
+ boolean redefined_ce_found = FALSE;
+
+ /* to check if this level set redefines any CEs, do not use overriding */
+ gfx.override_level_graphics = FALSE;
+ gfx.override_level_sounds = FALSE;
+ gfx.override_level_music = FALSE;
+
+ /* now check if this level set has definitions for custom elements */
+ if (setup.override_level_graphics == AUTO ||
+ setup.override_level_sounds == AUTO ||
+ setup.override_level_music == AUTO)
+ redefined_ce_found =
+ (CheckArtworkTypeForRedefinedCustomElements(ARTWORK_TYPE_GRAPHICS) |
+ CheckArtworkTypeForRedefinedCustomElements(ARTWORK_TYPE_SOUNDS) |
+ CheckArtworkTypeForRedefinedCustomElements(ARTWORK_TYPE_MUSIC));
+
+#if 0
+ printf("::: redefined_ce_found == %d\n", redefined_ce_found);
+#endif
+
+ if (redefined_ce_found)
+ {
+ /* this level set has CE definitions: change "AUTO" to "FALSE" */
+ gfx.override_level_graphics = (setup.override_level_graphics == TRUE);
+ gfx.override_level_sounds = (setup.override_level_sounds == TRUE);
+ gfx.override_level_music = (setup.override_level_music == TRUE);
+ }
+ else
+ {
+ /* this level set has no CE definitions: change "AUTO" to "TRUE" */
+ gfx.override_level_graphics = (setup.override_level_graphics != FALSE);
+ gfx.override_level_sounds = (setup.override_level_sounds != FALSE);
+ gfx.override_level_music = (setup.override_level_music != FALSE);
+ }
+
+#if 0
+ printf("::: => %d, %d, %d\n",
+ gfx.override_level_graphics,
+ gfx.override_level_sounds,
+ gfx.override_level_music);
+#endif
+}
+
static char *getNewArtworkIdentifier(int type)
{
static char *leveldir_current_identifier[3] = { NULL, NULL, NULL };
static boolean last_has_level_artwork_set[3] = { FALSE, FALSE, FALSE };
static boolean initialized[3] = { FALSE, FALSE, FALSE };
TreeInfo *artwork_first_node = ARTWORK_FIRST_NODE(artwork, type);
- boolean setup_override_artwork = SETUP_OVERRIDE_ARTWORK(setup, type);
+ boolean setup_override_artwork = GFX_OVERRIDE_ARTWORK(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 */
/* 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 (!strEqual(ARTWORK_CURRENT_IDENTIFIER(artwork, type),
artwork_current_identifier))
*(ARTWORK_CURRENT_IDENTIFIER_PTR(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
- 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;
}
void ReloadCustomArtwork(int force_reload)
{
+ int last_game_status = game_status; /* save current game status */
char *gfx_new_identifier;
char *snd_new_identifier;
char *mus_new_identifier;
boolean force_reload_mus = (force_reload & (1 << ARTWORK_TYPE_MUSIC));
boolean reload_needed;
+ InitOverrideArtwork();
+
force_reload_gfx |= AdjustGraphicsForEMC();
gfx_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_GRAPHICS);
if (!reload_needed)
return;
- print_init_timestamp("INIT ReloadCustomArtwork");
+ print_timestamp_init("ReloadCustomArtwork");
- ClearRectangle(window, 0, 0, WIN_XSIZE, WIN_YSIZE);
- print_init_timestamp("TIME ClearRectangle");
+ SetGameStatus(GAME_MODE_LOADING);
+
+ FadeOut(REDRAW_ALL);
+
+ ClearRectangle(drawto, 0, 0, WIN_XSIZE, WIN_YSIZE);
+ print_timestamp_time("ClearRectangle");
+
+ FadeIn(REDRAW_ALL);
if (gfx_new_identifier != NULL || force_reload_gfx)
{
#endif
InitImages();
- print_init_timestamp("TIME InitImages");
+ print_timestamp_time("InitImages");
}
if (snd_new_identifier != NULL || force_reload_snd)
{
InitSound(snd_new_identifier);
- print_init_timestamp("TIME InitSound");
+ print_timestamp_time("InitSound");
}
if (mus_new_identifier != NULL || force_reload_mus)
{
InitMusic(mus_new_identifier);
- print_init_timestamp("TIME InitMusic");
+ print_timestamp_time("InitMusic");
}
- RedrawBackground();
+ InitArtworkDone();
+
+ SetGameStatus(last_game_status); /* restore current game status */
+
+ init_last = init; /* switch to new busy animation */
+
+ FadeOut(REDRAW_ALL);
+
+ RedrawGlobalBorder();
/* force redraw of (open or closed) door graphics */
SetDoorState(DOOR_OPEN_ALL);
CloseDoor(DOOR_CLOSE_ALL | DOOR_NO_DELAY);
-#if 1
-#if 1
FadeSetEnterScreen();
- // FadeSkipNextFadeOut();
- // FadeSetDisabled();
-#else
- FadeSkipNext();
-#endif
-#else
- fading = fading_none;
-#endif
+ FadeSkipNextFadeOut();
- print_init_timestamp("DONE ReloadCustomArtwork");
+ print_timestamp_done("ReloadCustomArtwork");
+
+ LimitScreenUpdates(FALSE);
}
void KeyboardAutoRepeatOffUnlessAutoplay()
KeyboardAutoRepeatOff();
}
+void DisplayExitMessage(char *format, va_list ap)
+{
+ // check if draw buffer and fonts for exit message are already available
+ if (drawto == NULL || font_initial[NUM_INITIAL_FONTS - 1].bitmap == NULL)
+ return;
+
+ int font_1 = FC_RED;
+ int font_2 = FC_YELLOW;
+ int font_3 = FC_BLUE;
+ int font_width = getFontWidth(font_2);
+ int font_height = getFontHeight(font_2);
+ int sx = SX;
+ int sy = SY;
+ int sxsize = WIN_XSIZE - 2 * sx;
+ int sysize = WIN_YSIZE - 2 * sy;
+ int line_length = sxsize / font_width;
+ int max_lines = sysize / font_height;
+ int num_lines_printed;
+
+ gfx.sx = sx;
+ gfx.sy = sy;
+ gfx.sxsize = sxsize;
+ gfx.sysize = sysize;
+
+ sy = 20;
+
+ ClearRectangle(drawto, 0, 0, WIN_XSIZE, WIN_YSIZE);
+
+ DrawTextSCentered(sy, font_1, "Fatal error:");
+ sy += 3 * font_height;;
+
+ num_lines_printed =
+ DrawTextBufferVA(sx, sy, format, ap, font_2,
+ line_length, line_length, max_lines,
+ 0, BLIT_ON_BACKGROUND, TRUE, TRUE, FALSE);
+ sy += (num_lines_printed + 3) * font_height;
+
+ DrawTextSCentered(sy, font_1, "For details, see the following error file:");
+ sy += 3 * font_height;
+
+ num_lines_printed =
+ DrawTextBuffer(sx, sy, program.log_filename[LOG_ERR_ID], font_2,
+ line_length, line_length, max_lines,
+ 0, BLIT_ON_BACKGROUND, TRUE, TRUE, FALSE);
+
+ DrawTextSCentered(SYSIZE - 20, font_3, "Press any key or button to exit");
+
+ redraw_mask = REDRAW_ALL;
+
+ /* force drawing exit message even if screen updates are currently limited */
+ LimitScreenUpdates(FALSE);
+
+ BackToFront();
+
+ /* deactivate toons on error message screen */
+ setup.toons = FALSE;
+
+ WaitForEventToContinue();
+}
+
/* ========================================================================= */
/* OpenAll() */
void OpenAll()
{
- print_init_timestamp("INIT OpenAll");
+ print_timestamp_init("OpenAll");
+
+ SetGameStatus(GAME_MODE_LOADING);
+
+ InitCounter();
InitGlobal(); /* initialize some global variables */
+ print_timestamp_time("[init global stuff]");
+
+ InitSetup();
+
+ print_timestamp_time("[init setup/config stuff (1)]");
+
+ InitScoresInfo();
+
if (options.execute_command)
Execute_Command(options.execute_command);
exit(0); /* never reached, server loops forever */
}
- InitSetup();
-
InitGameInfo();
+ print_timestamp_time("[init setup/config stuff (2)]");
InitPlayerInfo();
+ print_timestamp_time("[init setup/config stuff (3)]");
InitArtworkInfo(); /* needed before loading gfx, sound & music */
+ print_timestamp_time("[init setup/config stuff (4)]");
InitArtworkConfig(); /* needed before forking sound child process */
+ print_timestamp_time("[init setup/config stuff (5)]");
InitMixer();
-
- InitCounter();
+ print_timestamp_time("[init setup/config stuff (6)]");
InitRND(NEW_RANDOMIZE);
InitSimpleRandom(NEW_RANDOMIZE);
InitJoysticks();
- print_init_timestamp("TIME [pre-video]");
+ print_timestamp_time("[init setup/config stuff]");
InitVideoDisplay();
InitVideoBuffer(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH, setup.fullscreen);
- InitEventFilter(FilterMouseMotionEvents);
+ InitOverlayInfo();
+
+ print_timestamp_time("[init video stuff]");
InitElementPropertiesStatic();
InitElementPropertiesEngine(GAME_VERSION_ACTUAL);
+ InitElementPropertiesGfxElement();
- print_init_timestamp("TIME [post-video]");
+ print_timestamp_time("[init element properties stuff]");
InitGfx();
- print_init_timestamp("TIME InitGfx");
+ print_timestamp_time("InitGfx");
InitLevelInfo();
- print_init_timestamp("TIME InitLevelInfo");
+ print_timestamp_time("InitLevelInfo");
InitLevelArtworkInfo();
- print_init_timestamp("TIME InitLevelArtworkInfo");
+ print_timestamp_time("InitLevelArtworkInfo");
+
+ InitOverrideArtwork(); /* needs to know current level directory */
+ print_timestamp_time("InitOverrideArtwork");
InitImages(); /* needs to know current level directory */
- print_init_timestamp("TIME InitImages");
+ print_timestamp_time("InitImages");
InitSound(NULL); /* needs to know current level directory */
- print_init_timestamp("TIME InitSound");
+ print_timestamp_time("InitSound");
InitMusic(NULL); /* needs to know current level directory */
- print_init_timestamp("TIME InitMusic");
+ print_timestamp_time("InitMusic");
+
+ InitArtworkDone();
InitGfxBackground();
-#if 1
em_open_all();
-#endif
+ sp_open_all();
if (global.autoplay_leveldir)
{
ConvertLevels();
return;
}
+ else if (global.create_images_dir)
+ {
+ CreateLevelSketchImages();
+ return;
+ }
- game_status = GAME_MODE_MAIN;
+ SetGameStatus(GAME_MODE_MAIN);
-#if 1
FadeSetEnterScreen();
if (!(fading.fade_mode & FADE_TYPE_TRANSFORM))
FadeSkipNextFadeOut();
- // FadeSetDisabled();
-#else
- fading = fading_none;
-#endif
- print_init_timestamp("TIME [post-artwork]");
+ print_timestamp_time("[post-artwork]");
- print_init_timestamp("DONE OpenAll");
+ print_timestamp_done("OpenAll");
DrawMainMenu();
InitNetworkServer();
+
+#if 0
+ Error(ERR_DEBUG, "::: SDL_GetBasePath() == '%s'",
+ SDL_GetBasePath());
+ Error(ERR_DEBUG, "::: SDL_GetPrefPath() == '%s'",
+ SDL_GetPrefPath("artsoft", "rocksndiamonds"));
+#if defined(PLATFORM_ANDROID)
+ Error(ERR_DEBUG, "::: SDL_AndroidGetInternalStoragePath() == '%s'",
+ SDL_AndroidGetInternalStoragePath());
+ Error(ERR_DEBUG, "::: SDL_AndroidGetExternalStoragePath() == '%s'",
+ SDL_AndroidGetExternalStoragePath());
+ Error(ERR_DEBUG, "::: SDL_AndroidGetExternalStorageState() == '%s'",
+ (SDL_AndroidGetExternalStorageState() &
+ SDL_ANDROID_EXTERNAL_STORAGE_WRITE ? "writable" :
+ SDL_AndroidGetExternalStorageState() &
+ SDL_ANDROID_EXTERNAL_STORAGE_READ ? "readable" : "not available"));
+#endif
+#endif
}
void CloseAllAndExit(int exit_value)
FreeAllMusic();
CloseAudio(); /* called after freeing sounds (needed for SDL) */
-#if 1
em_close_all();
-#endif
+ sp_close_all();
FreeAllImages();
#if defined(TARGET_SDL)
+#if defined(TARGET_SDL2)
+ // !!! TODO !!!
+ // set a flag to tell the network server thread to quit and wait for it
+ // using SDL_WaitThread()
+#else
if (network_server) /* terminate network server */
SDL_KillThread(server_thread);
+#endif
#endif
CloseVideoDisplay();
ClosePlatformDependentStuff();
- if (exit_value != 0)
- NotifyUserAboutErrorFile();
+ if (exit_value != 0 && !options.execute_command)
+ {
+ /* fall back to default level set (current set may have caused an error) */
+ SaveLevelSetup_LastSeries_Deactivate();
+
+ /* tell user where to find error log file which may contain more details */
+ // (error notification now directly displayed on screen inside R'n'D
+ // NotifyUserAboutErrorFile(); /* currently only works for Windows */
+ }
exit(exit_value);
}