#define CONFIG_TOKEN_GLOBAL_BUSY_INITIAL "global.busy_initial"
#define CONFIG_TOKEN_GLOBAL_BUSY "global.busy"
#define CONFIG_TOKEN_GLOBAL_BUSY_PLAYFIELD "global.busy_playfield"
+#define CONFIG_TOKEN_BACKGROUND "background"
#define CONFIG_TOKEN_BACKGROUND_LOADING_INITIAL "background.LOADING_INITIAL"
#define CONFIG_TOKEN_BACKGROUND_LOADING "background.LOADING"
#define NUM_INITIAL_IMAGES_BUSY 3
-#define INITIAL_IMG_BACKGROUND_LOADING_INITIAL 3
-#define INITIAL_IMG_BACKGROUND_LOADING 4
+#define INITIAL_IMG_BACKGROUND 3
+#define INITIAL_IMG_BACKGROUND_LOADING_INITIAL 4
+#define INITIAL_IMG_BACKGROUND_LOADING 5
-#define NUM_INITIAL_IMAGES 5
+#define NUM_INITIAL_IMAGES 6
static struct FontBitmapInfo font_initial[NUM_INITIAL_FONTS];
static int get_graphic_parameter_value(char *, char *, int);
+static int getLoadingBackgroundImage(int graphic)
+{
+ return getImageFromGraphicOrDefault(graphic, INITIAL_IMG_BACKGROUND);
+}
+
+static void SetLoadingWindowBackgroundImage(int graphic)
+{
+ SetBackgroundImage(getLoadingBackgroundImage(graphic), REDRAW_ALL);
+}
+
static void SetLoadingBackgroundImage(void)
{
struct GraphicInfo *graphic_info_last = graphic_info;
SetDrawDeactivationMask(REDRAW_NONE);
SetDrawBackgroundMask(REDRAW_ALL);
- SetWindowBackgroundImage(background_image);
+ SetLoadingWindowBackgroundImage(background_image);
graphic_info = graphic_info_last;
}
game_status == GAME_MODE_LOADING ?
&init_last.busy :
&init_last.busy_playfield);
- static unsigned int action_delay = 0;
- unsigned int action_delay_value = GameFrameDelay;
+ static DelayCounter action_delay = { 0 };
int sync_frame = FrameCounter;
int x, y;
+ action_delay.value = GameFrameDelay;
+
// prevent OS (Windows) from complaining about program not responding
CheckQuitEvent();
if (image_initial[graphic].bitmap == NULL || window == NULL)
return;
- if (!DelayReached(&action_delay, action_delay_value))
+ if (!DelayReached(&action_delay))
return;
if (busy->x == -1)
CreateImageTextures(texture_graphics[i]);
}
-static int getFontBitmapID(int font_nr)
+static int getFontSpecialSuffix(void)
{
int special = -1;
else if (game_status == GAME_MODE_PSEUDO_TYPENAMES)
special = GFX_SPECIAL_ARG_NAMES;
+ return special;
+}
+
+static int getFontBitmapID(int font_nr)
+{
+ int special = getFontSpecialSuffix();
+
if (special != -1)
return font_info[font_nr].special_bitmap_id[special];
else
return FONT_INITIAL_1;
}
+static char *getTokenFromFont(int font_nr)
+{
+ static char *token = NULL;
+ int special = getFontSpecialSuffix();
+
+ checked_free(token);
+
+ if (special != -1)
+ token = getStringCat2(font_info[font_nr].token_name,
+ special_suffix_info[special].suffix);
+ else
+ token = getStringCopy(font_info[font_nr].token_name);
+
+ return token;
+}
+
static void InitFontGraphicInfo(void)
{
static struct FontBitmapInfo *font_bitmap_info = NULL;
if (graphic_info == NULL) // still at startup phase
{
InitFontInfo(font_initial, NUM_INITIAL_FONTS,
- getFontBitmapID, getFontFromToken);
+ getFontBitmapID, getFontFromToken, getTokenFromFont);
return;
}
}
InitFontInfo(font_bitmap_info, num_font_bitmaps,
- getFontBitmapID, getFontFromToken);
+ getFontBitmapID, getFontFromToken, getTokenFromFont);
}
static void InitGlobalAnimGraphicInfo(void)
// animation synchronized with global frame counter, not move position
g->anim_global_sync = parameter[GFX_ARG_GLOBAL_SYNC];
+ // animation synchronized with global anim frame counter, not move position
+ g->anim_global_anim_sync = parameter[GFX_ARG_GLOBAL_ANIM_SYNC];
+
// optional element for cloning crumble graphics
if (parameter[GFX_ARG_CRUMBLED_LIKE] != ARG_UNDEFINED_VALUE)
g->crumbled_like = parameter[GFX_ARG_CRUMBLED_LIKE];
g->active_yoffset = parameter[GFX_ARG_ACTIVE_YOFFSET];
g->pressed_xoffset = parameter[GFX_ARG_PRESSED_XOFFSET];
g->pressed_yoffset = parameter[GFX_ARG_PRESSED_YOFFSET];
+
+ // this is only used for drawing stacked global animations
+ g->stacked_xfactor = parameter[GFX_ARG_STACKED_XFACTOR];
+ g->stacked_yfactor = parameter[GFX_ARG_STACKED_YFACTOR];
+ g->stacked_xoffset = parameter[GFX_ARG_STACKED_XOFFSET];
+ g->stacked_yoffset = parameter[GFX_ARG_STACKED_YOFFSET];
}
static void set_graphic_parameters(int graphic)
// process all images which default to same image as "global.door"
if (strEqual(fi->default_filename, fi_global_door->default_filename))
{
+ // skip all images that are cloned from images that default to same
+ // image as "global.door", but that are redefined to something else
+ if (graphic_info[i].clone_from != -1)
+ {
+ int cloned_graphic = graphic_info[i].clone_from;
+
+ if (getImageListEntryFromImageID(cloned_graphic)->redefined)
+ continue;
+ }
+
#if 0
Debug("init:InitGraphicCompatibilityInfo",
"special treatment needed for token '%s'", fi->token);
}
}
+ // special compatibility handling for "Snake Bite" graphics set
+ if (strPrefix(leveldir_current->identifier, "snake_bite"))
+ {
+ Bitmap *bitmap = graphic_info[IMG_BACKGROUND_SCORES].bitmap;
+
+ BlitBitmap(bitmap, bitmap, 18, 66, 32, 480, 50, 66);
+ BlitBitmap(bitmap, bitmap, 466, 66, 32, 480, 434, 66);
+
+ ClearRectangle(bitmap, 2, 66, 32, 480);
+ ClearRectangle(bitmap, 514, 66, 32, 480);
+ }
+
+ // special compatibility handling for "Jue" graphics sets (2007 and 2019)
+ boolean supports_score_info = (menu.draw_xoffset[GAME_MODE_SCOREINFO] != 0);
+ if (strPrefix(artwork.gfx_current_identifier, "jue") && !supports_score_info)
+ {
+ int font_title[] =
+ {
+ FONT_TITLE_1,
+ FONT_TITLE_2,
+
+ -1
+ };
+ int font_text[] =
+ {
+ FONT_TEXT_1,
+ FONT_TEXT_2,
+ FONT_TEXT_3,
+ FONT_TEXT_4,
+
+ -1
+ };
+ int mode_old = GAME_MODE_SCORES;
+ int mode_new = GAME_MODE_SCOREINFO;
+ int i, j;
+
+ // adjust title screens on score info page
+ for (i = 0; font_title[i] != -1; i++)
+ {
+ struct FontInfo *fi = &font_info[font_title[i]];
+
+ fi->special_graphic[mode_new] = fi->special_graphic[mode_old];
+ fi->special_bitmap_id[mode_new] = fi->special_bitmap_id[mode_old];
+ }
+
+ // adjust vertical text and button positions on scores page
+ for (i = 0; font_text[i] != -1; i++)
+ {
+ for (j = 0; j < 2; j++)
+ {
+ boolean jue0 = strEqual(artwork.gfx_current_identifier, "jue0");
+ int font_nr = (j == 0 ? font_text[i] : FONT_ACTIVE(font_text[i]));
+ int font_bitmap_id = font_info[font_nr].special_bitmap_id[mode_old];
+ int font_yoffset = (jue0 ? 10 : 5);
+
+ gfx.font_bitmap_info[font_bitmap_id].draw_yoffset = font_yoffset;
+ }
+ }
+
+ // adjust page offsets on score info page
+ menu.draw_xoffset[mode_new] = menu.draw_xoffset[mode_old];
+ menu.draw_yoffset[mode_new] = menu.draw_yoffset[mode_old];
+ }
+
InitGraphicCompatibilityInfo_Doors();
}
EL_BD_AMOEBA,
EL_EMC_MAGIC_BALL,
EL_EMC_ANDROID,
+ EL_MM_GRAY_BALL,
-1
};
global_anim_info[i].token_name = global_anim_name_info[i].token_name;
}
+ // create hash to store URLs for global animations
+ anim_url_hash = newSetupFileHash();
+
// create hash from image config list
image_config_hash = newSetupFileHash();
for (i = 0; image_config[i].token != NULL; i++)
if (setup.options.verbose)
options.verbose = TRUE;
+ if (setup.options.debug)
+ options.debug = TRUE;
+
+ if (!strEqual(setup.options.debug_mode, ARG_UNDEFINED_STRING))
+ options.debug_mode = getStringCopy(setup.options.debug_mode);
+
if (setup.debug.show_frames_per_second)
global.show_frames_per_second = TRUE;
}
}
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);
CONFIG_TOKEN_GLOBAL_BUSY_INITIAL,
CONFIG_TOKEN_GLOBAL_BUSY,
CONFIG_TOKEN_GLOBAL_BUSY_PLAYFIELD,
+ CONFIG_TOKEN_BACKGROUND,
CONFIG_TOKEN_BACKGROUND_LOADING_INITIAL,
CONFIG_TOKEN_BACKGROUND_LOADING
};
print_timestamp_done("InitImages");
}
-static void InitSound(char *identifier)
+static void InitSound(void)
{
print_timestamp_init("InitSound");
- if (identifier == NULL)
- identifier = artwork.snd_current->identifier;
-
// set artwork path to send it to the sound server process
setLevelArtworkDir(artwork.snd_first);
- InitReloadCustomSounds(identifier);
+ InitReloadCustomSounds();
print_timestamp_time("InitReloadCustomSounds");
ReinitializeSounds();
print_timestamp_done("InitSound");
}
-static void InitMusic(char *identifier)
+static void InitMusic(void)
{
print_timestamp_init("InitMusic");
- if (identifier == NULL)
- identifier = artwork.mus_current->identifier;
-
// set artwork path to send it to the sound server process
setLevelArtworkDir(artwork.mus_first);
- InitReloadCustomMusic(identifier);
+ InitReloadCustomMusic();
print_timestamp_time("InitReloadCustomMusic");
ReinitializeMusic();
#endif
}
-static char *getNewArtworkIdentifier(int type)
+static char *setNewArtworkIdentifier(int type)
{
static char *last_leveldir_identifier[3] = { NULL, NULL, NULL };
static char *last_artwork_identifier[3] = { NULL, NULL, NULL };
// (we cannot compare string pointers here, so copy string content itself)
setString(&last_artwork_identifier[type], artwork_current_identifier);
+ // ---------- set new artwork identifier ----------
*(ARTWORK_CURRENT_IDENTIFIER_PTR(artwork, type)) = artwork_current_identifier;
// ---------- do not reload directly after starting -------------------------
return artwork_new_identifier;
}
+static void InitArtworkIdentifier(void)
+{
+ setNewArtworkIdentifier(ARTWORK_TYPE_GRAPHICS);
+ setNewArtworkIdentifier(ARTWORK_TYPE_SOUNDS);
+ setNewArtworkIdentifier(ARTWORK_TYPE_MUSIC);
+}
+
void ReloadCustomArtwork(int force_reload)
{
int last_game_status = game_status; // save current game status
AdjustGraphicsForEMC();
AdjustSoundsForEMC();
- gfx_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_GRAPHICS);
- snd_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_SOUNDS);
- mus_new_identifier = getNewArtworkIdentifier(ARTWORK_TYPE_MUSIC);
+ gfx_new_identifier = setNewArtworkIdentifier(ARTWORK_TYPE_GRAPHICS);
+ snd_new_identifier = setNewArtworkIdentifier(ARTWORK_TYPE_SOUNDS);
+ mus_new_identifier = setNewArtworkIdentifier(ARTWORK_TYPE_MUSIC);
reload_needed = (gfx_new_identifier != NULL || force_reload_gfx ||
snd_new_identifier != NULL || force_reload_snd ||
UPDATE_BUSY_STATE();
+ InitMissingFileHash();
+
if (gfx_new_identifier != NULL || force_reload_gfx)
{
#if 0
if (snd_new_identifier != NULL || force_reload_snd)
{
- InitSound(snd_new_identifier);
+ InitSound();
print_timestamp_time("InitSound");
}
if (mus_new_identifier != NULL || force_reload_mus)
{
- InitMusic(mus_new_identifier);
+ InitMusic();
print_timestamp_time("InitMusic");
}
sy += 3 * font_height;
num_lines_printed =
- DrawTextBuffer(sx, sy, program.log_filename[LOG_ERR_ID], font_2,
+ DrawTextBuffer(sx, sy, program.log_filename, font_2,
line_length, line_length, max_lines,
0, BLIT_ON_BACKGROUND, TRUE, TRUE, FALSE);
InitSimpleRandom(NEW_RANDOMIZE);
InitBetterRandom(NEW_RANDOMIZE);
+ InitMissingFileHash();
+
print_timestamp_time("[init global stuff]");
InitSetup();
InitOverrideArtwork(); // needs to know current level directory
print_timestamp_time("InitOverrideArtwork");
+ InitArtworkIdentifier(); // needs to know current level directory
+ print_timestamp_time("InitArtworkIdentifier");
+
InitImages(); // needs to know current level directory
print_timestamp_time("InitImages");
- InitSound(NULL); // needs to know current level directory
+ InitSound(); // needs to know current level directory
print_timestamp_time("InitSound");
- InitMusic(NULL); // needs to know current level directory
+ InitMusic(); // needs to know current level directory
print_timestamp_time("InitMusic");
InitArtworkDone();
static boolean WaitForApiThreads(void)
{
- unsigned int thread_delay = 0;
- unsigned int thread_delay_value = 10000;
+ DelayCounter thread_delay = { 10000 };
if (program.api_thread_count == 0)
return TRUE;
// wait for threads to finish (and fail on timeout)
while (program.api_thread_count > 0)
{
- if (DelayReached(&thread_delay, thread_delay_value))
+ if (DelayReached(&thread_delay))
{
Error("failed waiting for threads - TIMEOUT");