// (c) 1995-2014 by Artsoft Entertainment
// Holger Schemel
// info@artsoft.org
-// http://www.artsoft.org/
+// https://www.artsoft.org/
// ----------------------------------------------------------------------------
// init.c
// ============================================================================
#define CONFIG_TOKEN_FONT_INITIAL "font.initial"
+#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 INITIAL_IMG_GLOBAL_BUSY_INITIAL 0
+#define INITIAL_IMG_GLOBAL_BUSY 1
+#define INITIAL_IMG_GLOBAL_BUSY_PLAYFIELD 2
+
+#define NUM_INITIAL_IMAGES_BUSY 3
+
+#define INITIAL_IMG_BACKGROUND 3
+#define INITIAL_IMG_BACKGROUND_LOADING_INITIAL 4
+#define INITIAL_IMG_BACKGROUND_LOADING 5
+
+#define NUM_INITIAL_IMAGES 6
static struct FontBitmapInfo font_initial[NUM_INITIAL_FONTS];
-static struct GraphicInfo anim_initial;
+static struct GraphicInfo image_initial[NUM_INITIAL_IMAGES];
static int copy_properties[][5] =
{
EL_MOLE_LEFT, EL_MOLE_RIGHT,
EL_MOLE_UP, EL_MOLE_DOWN
},
+ {
+ EL_SPRING,
+ EL_SPRING_LEFT, EL_SPRING_RIGHT,
+ EL_SPRING_LEFT, EL_SPRING_RIGHT, // (to match array size)
+ },
{
-1,
-1, -1, -1, -1
static int get_graphic_parameter_value(char *, char *, int);
-static void DrawInitAnim(void)
+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;
- int graphic = 0;
- static unsigned int action_delay = 0;
- unsigned int action_delay_value = GameFrameDelay;
+ int background_image = (game_status_last_screen == -1 ?
+ INITIAL_IMG_BACKGROUND_LOADING_INITIAL :
+ INITIAL_IMG_BACKGROUND_LOADING);
+
+ graphic_info = image_initial;
+
+ SetDrawDeactivationMask(REDRAW_NONE);
+ SetDrawBackgroundMask(REDRAW_ALL);
+
+ SetLoadingWindowBackgroundImage(background_image);
+
+ graphic_info = graphic_info_last;
+}
+
+static void DrawInitAnim(boolean only_when_loading)
+{
+ struct GraphicInfo *graphic_info_last = graphic_info;
+ int graphic = (game_status_last_screen == -1 ?
+ INITIAL_IMG_GLOBAL_BUSY_INITIAL :
+ game_status == GAME_MODE_LOADING ?
+ INITIAL_IMG_GLOBAL_BUSY :
+ INITIAL_IMG_GLOBAL_BUSY_PLAYFIELD);
+ struct MenuPosInfo *busy = (game_status_last_screen == -1 ?
+ &init_last.busy_initial :
+ game_status == GAME_MODE_LOADING ?
+ &init_last.busy :
+ &init_last.busy_playfield);
+ 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 (game_status != GAME_MODE_LOADING)
+ if (game_status != GAME_MODE_LOADING && only_when_loading)
return;
- if (anim_initial.bitmap == NULL || window == NULL)
+ if (image_initial[graphic].bitmap == NULL || window == NULL)
return;
- if (!DelayReached(&action_delay, action_delay_value))
+ if (!DelayReached(&action_delay))
return;
- 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;
+ if (busy->x == -1)
+ busy->x = (game_status == GAME_MODE_LOADING ? WIN_XSIZE / 2 : SXSIZE / 2);
+ if (busy->y == -1)
+ busy->y = (game_status == GAME_MODE_LOADING ? WIN_YSIZE / 2 : SYSIZE / 2);
- x = ALIGNED_TEXT_XPOS(&init_last.busy);
- y = ALIGNED_TEXT_YPOS(&init_last.busy);
+ x = (game_status == GAME_MODE_LOADING ? 0 : SX) + ALIGNED_TEXT_XPOS(busy);
+ y = (game_status == GAME_MODE_LOADING ? 0 : SY) + ALIGNED_TEXT_YPOS(busy);
- graphic_info = &anim_initial; // graphic == 0 => anim_initial
+ graphic_info = image_initial;
- if (sync_frame % anim_initial.anim_delay == 0)
+ if (sync_frame % image_initial[graphic].anim_delay == 0)
{
Bitmap *src_bitmap;
int src_x, src_y;
int height = graphic_info[graphic].height;
int frame = getGraphicAnimationFrame(graphic, sync_frame);
+ ClearRectangleOnBackground(drawto, x, y, width, height);
+
getFixedGraphicSource(graphic, frame, &src_bitmap, &src_x, &src_y);
- BlitBitmap(src_bitmap, window, src_x, src_y, width, height, x, y);
+ BlitBitmapMasked(src_bitmap, drawto, src_x, src_y, width, height, x, y);
+
+ BlitBitmap(drawto, window, x, y, width, height, x, y);
}
graphic_info = graphic_info_last;
IMG_GFX_REQUEST_BUTTON_TOUCH_YES,
IMG_GFX_REQUEST_BUTTON_TOUCH_NO,
IMG_GFX_REQUEST_BUTTON_TOUCH_CONFIRM,
+ IMG_GFX_GAME_BUTTON_TOUCH_STOP,
+ IMG_GFX_GAME_BUTTON_TOUCH_PAUSE,
+ IMG_MENU_BUTTON_TOUCH_BACK,
+ IMG_MENU_BUTTON_TOUCH_NEXT,
+ IMG_MENU_BUTTON_TOUCH_BACK2,
+ IMG_MENU_BUTTON_TOUCH_NEXT2,
-1
};
int i, j, k;
CreateImageTextures(texture_graphics[i]);
}
-#if 1
-// !!! FIX THIS (CHANGE TO USING NORMAL ELEMENT GRAPHIC DEFINITIONS) !!!
-void SetBitmaps_EM(Bitmap **em_bitmap)
-{
- em_bitmap[0] = graphic_info[IMG_EMC_OBJECT].bitmap;
- em_bitmap[1] = graphic_info[IMG_EMC_SPRITE].bitmap;
-}
-#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)
+static int getFontSpecialSuffix(void)
{
int special = -1;
special = game_status;
else if (game_status == GAME_MODE_PSEUDO_TYPENAME)
special = GFX_SPECIAL_ARG_MAIN;
+ 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];
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)
}
#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]);
+ Debug("init:InitGlobalAnimGraphicInfo",
+ "anim %d, part %d, mode %d => %d",
+ i, j, k, global_anim_info[i].graphic[j][k]);
#endif
}
}
#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]);
+ Debug("init:InitGlobalAnimSoundInfo",
+ "anim %d, part %d, mode %d => %d",
+ i, j, k, global_anim_info[i].sound[j][k]);
#endif
}
}
#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]);
+ Debug("init:InitGlobalAnimMusicInfo",
+ "anim %d, part %d, mode %d => %d",
+ i, j, k, global_anim_info[i].music[j][k]);
#endif
}
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, "-");
+ Warn("---");
+ Warn("error found in config file:");
+ Warn("- config file: '%s'", getImageConfigFilename());
+ Warn("error: invalid element token '%s'", value_raw);
+ Warn("custom graphic rejected for this element/action");
+ Warn("fallback done to undefined element for this graphic");
+ Warn("---");
}
return (value != NULL ? atoi(value) : EL_UNDEFINED);
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, "-");
+ Warn("---");
+ Warn("error found in config file:");
+ Warn("- config file: '%s'", getImageConfigFilename());
+ Warn("error: invalid graphic token '%s'", value_raw);
+ Warn("custom graphic rejected for this element/action");
+ Warn("fallback done to 'char_exclam' for this graphic");
+ Warn("---");
}
return (value != NULL ? atoi(value) : fallback_graphic);
return -1;
}
-static int get_scaled_graphic_width(int graphic)
+static int get_scaled_graphic_width(Bitmap *src_bitmap, int graphic)
{
int original_width = getOriginalImageWidthFromImageID(graphic);
int scale_up_factor = graphic_info[graphic].scale_up_factor;
+ // only happens when loaded outside artwork system (like "global.busy")
+ if (graphic_info == image_initial && src_bitmap)
+ original_width = src_bitmap->width;
+
return original_width * scale_up_factor;
}
-static int get_scaled_graphic_height(int graphic)
+static int get_scaled_graphic_height(Bitmap *src_bitmap, int graphic)
{
int original_height = getOriginalImageHeightFromImageID(graphic);
int scale_up_factor = graphic_info[graphic].scale_up_factor;
+ // only happens when loaded outside artwork system (like "global.busy")
+ if (graphic_info == image_initial && src_bitmap)
+ original_height = src_bitmap->height;
+
return original_height * scale_up_factor;
}
g->sort_priority = 0; // default for title screens
g->class = 0;
g->style = STYLE_DEFAULT;
+ g->alpha = -1;
g->bitmaps = src_bitmaps;
g->bitmap = src_bitmap;
if (g->use_image_size)
{
// set new default bitmap size (with scaling, but without small images)
- g->width = get_scaled_graphic_width(graphic);
- g->height = get_scaled_graphic_height(graphic);
+ g->width = get_scaled_graphic_width(src_bitmap, graphic);
+ g->height = get_scaled_graphic_height(src_bitmap, graphic);
}
// optional width and height of each animation frame
{
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, "-");
+ Warn("---");
+ Warn("invalid value %d for '%s.width' (fallback done to %d)",
+ g->width, getTokenFromImageID(graphic), TILEX);
+ Warn("---");
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, "-");
+ Warn("---");
+ Warn("invalid value %d for '%s.height' (fallback done to %d)",
+ g->height, getTokenFromImageID(graphic), TILEY);
+ Warn("---");
g->height = TILEY; // will be checked to be inside bitmap later
}
if (src_bitmap)
{
// get final bitmap size (with scaling, but without small images)
- int src_image_width = get_scaled_graphic_width(graphic);
- int src_image_height = get_scaled_graphic_height(graphic);
-
- 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;
- }
+ int src_image_width = get_scaled_graphic_width(src_bitmap, graphic);
+ int src_image_height = get_scaled_graphic_height(src_bitmap, graphic);
if (parameter[GFX_ARG_TILE_SIZE] != ARG_UNDEFINED_VALUE)
{
// 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->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) ||
+ if ((graphic >= IMG_GFX_GLOBAL_ANIM_1 && graphic <= IMG_GFX_GLOBAL_ANIM_32) ||
(graphic >= IMG_TOON_1 && graphic <= IMG_TOON_20))
g->draw_masked = TRUE;
g->class = parameter[GFX_ARG_CLASS];
if (parameter[GFX_ARG_STYLE] != ARG_UNDEFINED_VALUE)
g->style = parameter[GFX_ARG_STYLE];
+ if (parameter[GFX_ARG_ALPHA] != ARG_UNDEFINED_VALUE)
+ g->alpha = parameter[GFX_ARG_ALPHA];
// 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];
+
+ // 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)
if (num_references_followed >= max_num_images)
{
- Error(ERR_INFO_LINE, "-");
- Error(ERR_INFO, "warning: error found in config file:");
- Error(ERR_INFO, "- config file: '%s'", getImageConfigFilename());
- Error(ERR_INFO, "- config token: '%s'", getTokenFromImageID(graphic));
- Error(ERR_INFO, "error: loop discovered when resolving cloned graphics");
- Error(ERR_INFO, "custom graphic rejected for this element/action");
+ Warn("---");
+ Warn("error found in config file:");
+ Warn("- config file: '%s'", getImageConfigFilename());
+ Warn("- config token: '%s'", getTokenFromImageID(graphic));
+ Warn("error: loop discovered when resolving cloned graphics");
+ Warn("custom graphic rejected for this element/action");
if (graphic == fallback_graphic)
- Error(ERR_EXIT, "no fallback graphic available");
+ Fail("no fallback graphic available");
- Error(ERR_INFO, "fallback done to 'char_exclam' for this graphic");
- Error(ERR_INFO_LINE, "-");
+ Warn("fallback done to 'char_exclam' for this graphic");
+ Warn("---");
graphic_info[graphic] = graphic_info[fallback_graphic];
}
IMG_BACKGROUND_REQUEST,
IMG_BACKGROUND,
+ IMG_BACKGROUND_LOADING_INITIAL,
+ IMG_BACKGROUND_LOADING,
IMG_BACKGROUND_TITLE_INITIAL,
IMG_BACKGROUND_TITLE,
IMG_BACKGROUND_MAIN,
+ IMG_BACKGROUND_NAMES,
IMG_BACKGROUND_LEVELS,
IMG_BACKGROUND_LEVELNR,
IMG_BACKGROUND_SCORES,
+ IMG_BACKGROUND_SCOREINFO,
IMG_BACKGROUND_EDITOR,
IMG_BACKGROUND_INFO,
IMG_BACKGROUND_INFO_ELEMENTS,
src_x + width > src_bitmap_width ||
src_y + height > src_bitmap_height)
{
- Error(ERR_INFO_LINE, "-");
- Error(ERR_INFO, "warning: error found in config file:");
- 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");
+ Warn("---");
+ Warn("error found in config file:");
+ Warn("- config file: '%s'", getImageConfigFilename());
+ Warn("- config token: '%s'", getTokenFromImageID(i));
+ Warn("- image file: '%s'", src_bitmap->source_filename);
+ Warn("- frame size: %d, %d", width, height);
+ Warn("error: first animation frame out of bounds (%d, %d) [%d, %d]",
+ src_x, src_y, src_bitmap_width, src_bitmap_height);
+ Warn("custom graphic rejected for this element/action");
if (i == fallback_graphic)
- Error(ERR_EXIT, "no fallback graphic available");
+ Fail("no fallback graphic available");
- Error(ERR_INFO, "fallback done to 'char_exclam' for this graphic");
- Error(ERR_INFO_LINE, "-");
+ Warn("fallback done to 'char_exclam' for this graphic");
+ Warn("---");
graphic_info[i] = graphic_info[fallback_graphic];
src_x + width > src_bitmap_width ||
src_y + height > src_bitmap_height)
{
- Error(ERR_INFO_LINE, "-");
- Error(ERR_INFO, "warning: error found in config file:");
- 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");
+ Warn("---");
+ Warn("error found in config file:");
+ Warn("- config file: '%s'", getImageConfigFilename());
+ Warn("- config token: '%s'", getTokenFromImageID(i));
+ Warn("- image file: '%s'", src_bitmap->source_filename);
+ Warn("- frame size: %d, %d", width, height);
+ Warn("error: last animation frame (%d) out of bounds (%d, %d) [%d, %d]",
+ last_frame, src_x, src_y, src_bitmap_width, src_bitmap_height);
+ Warn("custom graphic rejected for this element/action");
if (i == fallback_graphic)
- Error(ERR_EXIT, "no fallback graphic available");
+ Fail("no fallback graphic available");
- Error(ERR_INFO, "fallback done to 'char_exclam' for this graphic");
- Error(ERR_INFO_LINE, "-");
+ Warn("fallback done to 'char_exclam' for this graphic");
+ Warn("---");
graphic_info[i] = graphic_info[fallback_graphic];
}
// 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);
+ // 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);
+#endif
graphic_info[i].bitmaps = graphic_info[IMG_GLOBAL_DOOR].bitmaps;
graphic_info[i].bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
}
}
+ // 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();
}
}
set_sound_parameters(i, sound->parameter);
+
+#if 0
+ Debug("init:InitSoundInfo", "loop mode: %d ['%s']",
+ sound_info[i].loop, sound->token);
+#endif
}
free(sound_effect_properties);
}
}
+
+static void InitGameInfoFromArtworkInfo(void)
+{
+ // special case: store initial value of custom artwork setting
+ game.use_masked_elements_initial = game.use_masked_elements;
+}
+
static void ReinitializeGraphics(void)
{
print_timestamp_init("ReinitializeGraphics");
InitGraphicCompatibilityInfo();
print_timestamp_time("InitGraphicCompatibilityInfo");
- SetMainBackgroundImage(IMG_BACKGROUND);
- print_timestamp_time("SetMainBackgroundImage");
- SetDoorBackgroundImage(IMG_BACKGROUND_DOOR);
- print_timestamp_time("SetDoorBackgroundImage");
-
InitGadgets();
print_timestamp_time("InitGadgets");
InitDoors();
print_timestamp_time("InitDoors");
+ InitGameInfoFromArtworkInfo();
+
print_timestamp_done("ReinitializeGraphics");
}
{ EL_SP_ELECTRON, 15 },
{ EL_BALLOON, 16 },
{ EL_SPRING, 17 },
+ { EL_SPRING_LEFT, 17 },
+ { EL_SPRING_RIGHT, 17 },
{ EL_EMC_ANDROID, 18 },
{ -1, -1 },
if (recursion_depth > NUM_GROUP_ELEMENTS) // recursion too deep
{
- Error(ERR_WARN, "recursion too deep when resolving group element %d",
+ Warn("recursion too deep when resolving group element %d",
group_element - EL_GROUP_START + 1);
// replace element which caused too deep recursion by question mark
EL_BOMB,
EL_NUT,
EL_AMOEBA_DROP,
+ EL_AMOEBA_DROPPING,
EL_QUICKSAND_FULL,
EL_QUICKSAND_FAST_FULL,
EL_MAGIC_WALL_FULL,
static int ep_walkable_over[] =
{
EL_EMPTY_SPACE,
+ EL_EMPTY_SPACE_1,
+ EL_EMPTY_SPACE_2,
+ EL_EMPTY_SPACE_3,
+ EL_EMPTY_SPACE_4,
+ EL_EMPTY_SPACE_5,
+ EL_EMPTY_SPACE_6,
+ EL_EMPTY_SPACE_7,
+ EL_EMPTY_SPACE_8,
+ EL_EMPTY_SPACE_9,
+ EL_EMPTY_SPACE_10,
+ EL_EMPTY_SPACE_11,
+ EL_EMPTY_SPACE_12,
+ EL_EMPTY_SPACE_13,
+ EL_EMPTY_SPACE_14,
+ EL_EMPTY_SPACE_15,
+ EL_EMPTY_SPACE_16,
EL_SP_EMPTY_SPACE,
EL_SOKOBAN_FIELD_EMPTY,
EL_EXIT_OPEN,
-1
};
+ static int ep_empty_space[] =
+ {
+ EL_EMPTY_SPACE,
+ EL_EMPTY_SPACE_1,
+ EL_EMPTY_SPACE_2,
+ EL_EMPTY_SPACE_3,
+ EL_EMPTY_SPACE_4,
+ EL_EMPTY_SPACE_5,
+ EL_EMPTY_SPACE_6,
+ EL_EMPTY_SPACE_7,
+ EL_EMPTY_SPACE_8,
+ EL_EMPTY_SPACE_9,
+ EL_EMPTY_SPACE_10,
+ EL_EMPTY_SPACE_11,
+ EL_EMPTY_SPACE_12,
+ EL_EMPTY_SPACE_13,
+ EL_EMPTY_SPACE_14,
+ EL_EMPTY_SPACE_15,
+ EL_EMPTY_SPACE_16,
+
+ -1
+ };
+
static int ep_player[] =
{
EL_PLAYER_1,
EL_BD_AMOEBA,
EL_EMC_MAGIC_BALL,
EL_EMC_ANDROID,
+ EL_MM_GRAY_BALL,
-1
};
static int ep_inactive[] =
{
EL_EMPTY,
+ EL_EMPTY_SPACE_1,
+ EL_EMPTY_SPACE_2,
+ EL_EMPTY_SPACE_3,
+ EL_EMPTY_SPACE_4,
+ EL_EMPTY_SPACE_5,
+ EL_EMPTY_SPACE_6,
+ EL_EMPTY_SPACE_7,
+ EL_EMPTY_SPACE_8,
+ EL_EMPTY_SPACE_9,
+ EL_EMPTY_SPACE_10,
+ EL_EMPTY_SPACE_11,
+ EL_EMPTY_SPACE_12,
+ EL_EMPTY_SPACE_13,
+ EL_EMPTY_SPACE_14,
+ EL_EMPTY_SPACE_15,
+ EL_EMPTY_SPACE_16,
EL_SAND,
EL_WALL,
EL_BD_WALL,
EL_INTERNAL_CASCADE_STEEL_CHARS_ACTIVE,
EL_INTERNAL_CASCADE_CE_ACTIVE,
EL_INTERNAL_CASCADE_GE_ACTIVE,
+ EL_INTERNAL_CASCADE_ES_ACTIVE,
EL_INTERNAL_CASCADE_REF_ACTIVE,
EL_INTERNAL_CASCADE_USER_ACTIVE,
EL_INTERNAL_CASCADE_DYNAMIC_ACTIVE,
EL_INTERNAL_CASCADE_STEEL_CHARS,
EL_INTERNAL_CASCADE_CE,
EL_INTERNAL_CASCADE_GE,
+ EL_INTERNAL_CASCADE_ES,
EL_INTERNAL_CASCADE_REF,
EL_INTERNAL_CASCADE_USER,
EL_INTERNAL_CASCADE_DYNAMIC,
{ ep_can_explode, EP_CAN_EXPLODE },
{ ep_gravity_reachable, EP_GRAVITY_REACHABLE },
+ { ep_empty_space, EP_EMPTY_SPACE },
{ ep_player, EP_PLAYER },
{ ep_can_pass_magic_wall, EP_CAN_PASS_MAGIC_WALL },
{ ep_can_pass_dc_magic_wall, EP_CAN_PASS_DC_MAGIC_WALL },
i == EL_BLACK_ORB));
// ---------- COULD_MOVE_INTO_ACID ----------------------------------------
- SET_PROPERTY(i, EP_COULD_MOVE_INTO_ACID, (ELEM_IS_PLAYER(i) ||
+ SET_PROPERTY(i, EP_COULD_MOVE_INTO_ACID, (IS_PLAYER_ELEMENT(i) ||
CAN_MOVE(i) ||
IS_CUSTOM_ELEMENT(i)));
// ---------- CAN_BE_CLONED_BY_ANDROID ------------------------------------
for (j = 0; j < level.num_android_clone_elements; j++)
SET_PROPERTY(i, EP_CAN_BE_CLONED_BY_ANDROID,
- (i != EL_EMPTY &&
+ (!IS_EMPTY(i) &&
IS_EQUAL_OR_IN_GROUP(i, level.android_clone_element[j])));
// ---------- CAN_CHANGE --------------------------------------------------
{
// check if element_name_info entry defined for each element in "main.h"
if (i < MAX_NUM_ELEMENTS && element_name_info[i].token_name == NULL)
- Error(ERR_EXIT, "undefined 'element_name_info' entry for element %d", i);
+ Fail("undefined 'element_name_info' entry for element %d", i);
element_info[i].token_name = element_name_info[i].token_name;
element_info[i].class_name = element_name_info[i].class_name;
// 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);
+ Fail("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 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++)
}
global.autoplay_leveldir = NULL;
+ global.patchtapes_leveldir = NULL;
global.convert_leveldir = NULL;
- global.create_images_dir = NULL;
+ global.dumplevel_leveldir = NULL;
+ global.dumptape_leveldir = NULL;
+ global.create_sketch_images_dir = NULL;
+ global.create_collect_images_dir = NULL;
global.frames_per_second = 0;
global.show_frames_per_second = FALSE;
global.anim_status = global.anim_status_next = GAME_MODE_LOADING;
global.use_envelope_request = FALSE;
+
+ global.user_names = NULL;
}
static void Execute_Command(char *command)
{
char *filename = &command[11];
- if (!fileExists(filename))
- Error(ERR_EXIT, "cannot open file '%s'", filename);
+ if (fileExists(filename))
+ {
+ LoadLevelFromFilename(&level, filename);
+ DumpLevel(&level);
+
+ exit(0);
+ }
+
+ char *leveldir = getStringCopy(filename); // read command parameters
+ char *level_nr = strchr(leveldir, ' ');
- LoadLevelFromFilename(&level, filename);
- DumpLevel(&level);
+ if (level_nr == NULL)
+ Fail("cannot open file '%s'", filename);
- exit(0);
+ *level_nr++ = '\0';
+
+ global.dumplevel_leveldir = leveldir;
+ global.dumplevel_level_nr = atoi(level_nr);
+
+ program.headless = TRUE;
}
else if (strPrefix(command, "dump tape "))
{
char *filename = &command[10];
- if (!fileExists(filename))
- Error(ERR_EXIT, "cannot open file '%s'", filename);
+ if (fileExists(filename))
+ {
+ LoadTapeFromFilename(filename);
+ DumpTape(&tape);
+
+ exit(0);
+ }
+
+ char *leveldir = getStringCopy(filename); // read command parameters
+ char *level_nr = strchr(leveldir, ' ');
- LoadTapeFromFilename(filename);
- DumpTape(&tape);
+ if (level_nr == NULL)
+ Fail("cannot open file '%s'", filename);
- exit(0);
+ *level_nr++ = '\0';
+
+ global.dumptape_leveldir = leveldir;
+ global.dumptape_level_nr = atoi(level_nr);
+
+ program.headless = TRUE;
}
- else if (strPrefix(command, "autotest ") ||
- strPrefix(command, "autoplay ") ||
+ else if (strPrefix(command, "autoplay ") ||
strPrefix(command, "autoffwd ") ||
- strPrefix(command, "autowarp "))
+ strPrefix(command, "autowarp ") ||
+ strPrefix(command, "autotest ") ||
+ strPrefix(command, "autosave ") ||
+ strPrefix(command, "autoupload ") ||
+ strPrefix(command, "autofix "))
{
- char *str_ptr = getStringCopy(&command[9]); // read command parameters
+ char *arg_ptr = strchr(command, ' ');
+ char *str_ptr = getStringCopy(arg_ptr); // read command parameters
global.autoplay_mode =
- (strPrefix(command, "autotest") ? AUTOPLAY_MODE_TEST :
- strPrefix(command, "autoplay") ? AUTOPLAY_MODE_PLAY :
+ (strPrefix(command, "autoplay") ? AUTOPLAY_MODE_PLAY :
strPrefix(command, "autoffwd") ? AUTOPLAY_MODE_FFWD :
strPrefix(command, "autowarp") ? AUTOPLAY_MODE_WARP :
+ strPrefix(command, "autotest") ? AUTOPLAY_MODE_TEST :
+ strPrefix(command, "autosave") ? AUTOPLAY_MODE_SAVE :
+ strPrefix(command, "autoupload") ? AUTOPLAY_MODE_UPLOAD :
+ strPrefix(command, "autofix") ? AUTOPLAY_MODE_FIX :
AUTOPLAY_MODE_NONE);
while (*str_ptr != '\0') // continue parsing string
str_ptr++;
}
- if (global.autoplay_mode == AUTOPLAY_MODE_TEST)
+ if (global.autoplay_mode & AUTOPLAY_WARP_NO_DISPLAY)
program.headless = TRUE;
}
+ else if (strPrefix(command, "patch tapes "))
+ {
+ char *str_ptr = getStringCopy(&command[12]); // read command parameters
+
+ // skip leading whitespace
+ while (*str_ptr == ' ' || *str_ptr == '\t')
+ str_ptr++;
+
+ if (*str_ptr == '\0')
+ Fail("cannot find MODE in command '%s'", command);
+
+ global.patchtapes_mode = str_ptr; // store patch mode
+
+ // advance to next whitespace (or end of string)
+ while (*str_ptr != ' ' && *str_ptr != '\t' && *str_ptr != '\0')
+ str_ptr++;
+
+ 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';
+
+ if (*str_ptr == '\0') // end of string reached
+ break;
+
+ if (global.patchtapes_leveldir == NULL) // read level set string
+ {
+ global.patchtapes_leveldir = str_ptr;
+ global.patchtapes_all = TRUE; // default: patch all tapes
+
+ for (i = 0; i < MAX_TAPES_PER_SET; i++)
+ global.patchtapes_level[i] = FALSE;
+ }
+ else // read level number string
+ {
+ int level_nr = atoi(str_ptr); // get level_nr value
+
+ if (level_nr >= 0 && level_nr < MAX_TAPES_PER_SET)
+ global.patchtapes_level[level_nr] = TRUE;
+
+ global.patchtapes_all = FALSE;
+ }
+
+ // advance string pointer to the next whitespace (or end of string)
+ while (*str_ptr != ' ' && *str_ptr != '\t' && *str_ptr != '\0')
+ str_ptr++;
+ }
+
+ if (global.patchtapes_leveldir == NULL)
+ {
+ if (strEqual(global.patchtapes_mode, "help"))
+ global.patchtapes_leveldir = UNDEFINED_LEVELSET;
+ else
+ Fail("cannot find LEVELDIR in command '%s'", command);
+ }
+
+ program.headless = TRUE;
+ }
else if (strPrefix(command, "convert "))
{
char *str_copy = getStringCopy(strchr(command, ' ') + 1);
program.headless = TRUE;
}
- else if (strPrefix(command, "create images "))
+ else if (strPrefix(command, "create sketch images "))
{
- global.create_images_dir = getStringCopy(&command[14]);
+ global.create_sketch_images_dir = getStringCopy(&command[21]);
- 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);
+ if (access(global.create_sketch_images_dir, W_OK) != 0)
+ Fail("image target directory '%s' not found or not writable",
+ global.create_sketch_images_dir);
+ }
+ else if (strPrefix(command, "create collect image "))
+ {
+ global.create_collect_images_dir = getStringCopy(&command[21]);
+
+ if (access(global.create_collect_images_dir, W_OK) != 0)
+ Fail("image target directory '%s' not found or not writable",
+ global.create_collect_images_dir);
}
else if (strPrefix(command, "create CE image "))
{
}
else
{
- Error(ERR_EXIT_HELP, "unrecognized command '%s'", command);
+ FailWithHelp("unrecognized command '%s'", command);
}
// disable networking if any valid command was recognized
static void InitSetup(void)
{
+ LoadUserNames(); // global user names
+ LoadUserSetup(); // global user number
+
LoadSetup(); // global setup info
- LoadSetup_AutoSetup(); // global auto setup info
// set some options from setup file
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;
}
static void InitGameInfo(void)
{
game.restart_level = FALSE;
- game.restart_game_message = NULL;
game.request_active = FALSE;
+
+ game.use_masked_elements_initial = FALSE;
}
static void InitPlayerInfo(void)
}
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);
InitGfxBuffers_EM();
InitGfxBuffers_SP();
+ InitGfxBuffers_MM();
}
static void InitGfx(void)
{
struct GraphicInfo *graphic_info_last = graphic_info;
char *filename_font_initial = NULL;
- char *filename_anim_initial = NULL;
+ char *filename_image_initial[NUM_INITIAL_IMAGES] = { NULL };
+ char *image_token[NUM_INITIAL_IMAGES] =
+ {
+ 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
+ };
+ struct MenuPosInfo *init_busy[NUM_INITIAL_IMAGES_BUSY] =
+ {
+ &init.busy_initial,
+ &init.busy,
+ &init.busy_playfield
+ };
Bitmap *bitmap_font_initial = NULL;
- int i, j;
+ int parameter[NUM_INITIAL_IMAGES][NUM_GFX_ARGS];
+ int i, j, k;
// determine settings for initial font (for displaying startup messages)
for (i = 0; image_config[i].token != NULL; i++)
len_font_token = strlen(font_token);
if (strEqual(image_config[i].token, font_token))
+ {
filename_font_initial = image_config[i].value;
+ }
else if (strlen(image_config[i].token) > len_font_token &&
strncmp(image_config[i].token, font_token, len_font_token) == 0)
{
}
if (filename_font_initial == NULL) // should not happen
- Error(ERR_EXIT, "cannot get filename for '%s'", CONFIG_TOKEN_FONT_INITIAL);
+ Fail("cannot get filename for '%s'", CONFIG_TOKEN_FONT_INITIAL);
InitGfxBuffers();
InitGfxCustomArtworkInfo();
InitGfxOtherSettings();
+ InitGfxTileSizeInfo(TILESIZE, TILESIZE);
+
bitmap_font_initial = LoadCustomImage(filename_font_initial);
for (j = 0; j < NUM_INITIAL_FONTS; j++)
InitFontGraphicInfo();
- DrawProgramInfo();
-
- DrawInitText("Loading graphics", 120, FC_GREEN);
-
- // 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);
+ InitMenuDesignSettings_Static();
- char *anim_token = CONFIG_TOKEN_GLOBAL_BUSY;
- int len_anim_token = strlen(anim_token);
+ // initialize settings for initial images with default values
+ for (i = 0; i < NUM_INITIAL_IMAGES; i++)
+ for (j = 0; j < NUM_GFX_ARGS; j++)
+ parameter[i][j] =
+ get_graphic_parameter_value(image_config_suffix[j].value,
+ image_config_suffix[j].token,
+ image_config_suffix[j].type);
- // read settings for busy animation from default custom artwork config
+ // read settings for initial images from default custom artwork config
char *gfx_config_filename = getPath3(options.graphics_directory,
GFX_DEFAULT_SUBDIR,
GRAPHICSINFO_FILENAME);
if (setup_file_hash)
{
- char *filename = getHashEntry(setup_file_hash, anim_token);
-
- if (filename)
+ for (i = 0; i < NUM_INITIAL_IMAGES; i++)
{
- filename_anim_initial = getStringCopy(filename);
+ char *filename = getHashEntry(setup_file_hash, image_token[i]);
- for (j = 0; image_config_suffix[j].token != NULL; j++)
+ if (filename)
{
- 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);
+ filename_image_initial[i] = 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(image_token[i], suffix);
+ char *value = getHashEntry(setup_file_hash, token);
- checked_free(token);
+ checked_free(token);
- if (value)
- parameter[j] = get_graphic_parameter_value(value, suffix, type);
+ if (value)
+ parameter[i][j] =
+ get_graphic_parameter_value(value, suffix, type);
+ }
}
}
+ // read values from custom graphics config file
+ InitMenuDesignSettings_FromHash(setup_file_hash, FALSE);
+
freeSetupFileHash(setup_file_hash);
}
}
- if (filename_anim_initial == NULL)
+ for (i = 0; i < NUM_INITIAL_IMAGES; i++)
{
- // read settings for busy animation from static default artwork config
- for (i = 0; image_config[i].token != NULL; i++)
+ if (filename_image_initial[i] == NULL)
{
- 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)
+ int len_token = strlen(image_token[i]);
+
+ // read settings for initial images from static default artwork config
+ for (j = 0; image_config[j].token != NULL; j++)
{
- for (j = 0; image_config_suffix[j].token != NULL; j++)
+ if (strEqual(image_config[j].token, image_token[i]))
{
- 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);
+ filename_image_initial[i] = getStringCopy(image_config[j].value);
+ }
+ else if (strlen(image_config[j].token) > len_token &&
+ strncmp(image_config[j].token, image_token[i], len_token) == 0)
+ {
+ for (k = 0; image_config_suffix[k].token != NULL; k++)
+ {
+ if (strEqual(&image_config[j].token[len_token],
+ image_config_suffix[k].token))
+ parameter[i][k] =
+ get_graphic_parameter_value(image_config[j].value,
+ image_config_suffix[k].token,
+ image_config_suffix[k].type);
+ }
}
}
}
}
- if (filename_anim_initial == NULL) // should not happen
- Error(ERR_EXIT, "cannot get filename for '%s'", CONFIG_TOKEN_GLOBAL_BUSY);
+ for (i = 0; i < NUM_INITIAL_IMAGES; i++)
+ {
+ if (filename_image_initial[i] == NULL) // should not happen
+ Fail("cannot get filename for '%s'", image_token[i]);
+
+ image_initial[i].bitmaps =
+ checked_calloc(sizeof(Bitmap *) * NUM_IMG_BITMAP_POINTERS);
- anim_initial.bitmaps =
- checked_calloc(sizeof(Bitmap *) * NUM_IMG_BITMAP_POINTERS);
+ if (!strEqual(filename_image_initial[i], UNDEFINED_FILENAME))
+ image_initial[i].bitmaps[IMG_BITMAP_STANDARD] =
+ LoadCustomImage(filename_image_initial[i]);
- anim_initial.bitmaps[IMG_BITMAP_STANDARD] =
- LoadCustomImage(filename_anim_initial);
+ checked_free(filename_image_initial[i]);
+ }
- checked_free(filename_anim_initial);
+ for (i = 0; i < NUM_INITIAL_IMAGES; i++)
+ image_initial[i].use_image_size = TRUE;
- graphic_info = &anim_initial; // graphic == 0 => anim_initial
+ graphic_info = image_initial; // graphic == 0 => image_initial
- set_graphic_parameters_ext(0, parameter, anim_initial.bitmaps);
+ for (i = 0; i < NUM_INITIAL_IMAGES; i++)
+ set_graphic_parameters_ext(i, parameter[i], image_initial[i].bitmaps);
graphic_info = graphic_info_last;
- init.busy.width = anim_initial.width;
- init.busy.height = anim_initial.height;
+ for (i = 0; i < NUM_INITIAL_IMAGES_BUSY; i++)
+ {
+ // set image size for busy animations
+ init_busy[i]->width = image_initial[i].width;
+ init_busy[i]->height = image_initial[i].height;
+ }
+
+ SetLoadingBackgroundImage();
- InitMenuDesignSettings_Static();
+ ClearRectangleOnBackground(window, 0, 0, WIN_XSIZE, WIN_YSIZE);
+
+ DrawProgramInfo();
InitGfxDrawBusyAnimFunction(DrawInitAnim);
InitGfxDrawGlobalAnimFunction(DrawGlobalAnimations);
InitGfxDrawGlobalBorderFunction(DrawMaskedBorderToTarget);
InitGfxDrawTileCursorFunction(DrawTileCursor);
+ InitGfxDrawEnvelopeRequestFunction(DrawEnvelopeRequestToScreen);
gfx.fade_border_source_status = global.border_status;
gfx.fade_border_target_status = global.border_status;
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));
+ Debug("init:InitImages", "leveldir_current->identifier == '%s'",
+ leveldir_current == NULL ? "[NULL]" : leveldir_current->identifier);
+ Debug("init:InitImages", "leveldir_current->graphics_path == '%s'",
+ leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_path);
+ Debug("init:InitImages", "leveldir_current->graphics_set == '%s'",
+ leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_set);
+ Debug("init:InitImages", "getLevelArtworkSet(ARTWORK_TYPE_GRAPHICS) == '%s'",
+ 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",
+ Debug("init:InitImages", "leveldir_current->identifier == '%s'",
+ leveldir_current == NULL ? "[NULL]" : leveldir_current->identifier);
+ Debug("init:InitImages", "leveldir_current->graphics_path == '%s'",
+ leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_path);
+ Debug("init:InitImages", "leveldir_current->graphics_set == '%s'",
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));
+ Debug("init:InitImages", "getLevelArtworkSet(ARTWORK_TYPE_GRAPHICS) == '%s'",
+ 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,
- artwork.gfx_current_identifier,
- artwork.gfx_current->identifier,
- leveldir_current->graphics_set,
- leveldir_current->graphics_path);
+ Debug("init:InitImages", "InitImages for '%s' ['%s', '%s'] ['%s', '%s']",
+ leveldir_current->identifier,
+ artwork.gfx_current_identifier,
+ artwork.gfx_current->identifier,
+ leveldir_current->graphics_set,
+ leveldir_current->graphics_path);
#endif
UPDATE_BUSY_STATE();
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();
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));
+ Debug("init:CheckArtworkTypeForRedefinedCustomElements",
+ "leveldir_current->identifier == '%s'",
+ leveldir_current == NULL ? "[NULL]" : leveldir_current->identifier);
+ Debug("init:CheckArtworkTypeForRedefinedCustomElements",
+ "leveldir_current->graphics_path == '%s'",
+ leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_path);
+ Debug("init:CheckArtworkTypeForRedefinedCustomElements",
+ "leveldir_current->graphics_set == '%s'",
+ leveldir_current == NULL ? "[NULL]" : leveldir_current->graphics_set);
+ Debug("init:CheckArtworkTypeForRedefinedCustomElements",
+ "getLevelArtworkSet(ARTWORK_TYPE_GRAPHICS) == '%s'",
+ 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);
+ Debug("init:CheckArtworkTypeForRedefinedCustomElements",
+ "filename_base == '%s'", filename_base);
#endif
if (fileExists(filename_base))
filename_local = getCustomArtworkConfigFilename(type);
#if 0
- printf("::: filename_local == '%s'\n", filename_local);
+ Debug("init:CheckArtworkTypeForRedefinedCustomElements",
+ "filename_local == '%s'", 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);
+ Debug("init:CheckArtworkTypeForRedefinedCustomElements",
+ "redefined_ce_found == %d", redefined_ce_found);
#endif
return redefined_ce_found;
CheckArtworkTypeForRedefinedCustomElements(ARTWORK_TYPE_MUSIC));
#if 0
- printf("::: redefined_ce_found == %d\n", redefined_ce_found);
+ Debug("init:InitOverrideArtwork", "redefined_ce_found == %d",
+ redefined_ce_found);
#endif
if (redefined_ce_found)
}
#if 0
- printf("::: => %d, %d, %d\n",
- gfx.override_level_graphics,
- gfx.override_level_sounds,
- gfx.override_level_music);
+ Debug("init:InitOverrideArtwork", "%d, %d, %d",
+ gfx.override_level_graphics,
+ gfx.override_level_sounds,
+ gfx.override_level_music);
#endif
}
-static char *getNewArtworkIdentifier(int type)
+static char *setNewArtworkIdentifier(int type)
{
- static char *leveldir_current_identifier[3] = { NULL, NULL, NULL };
+ static char *last_leveldir_identifier[3] = { NULL, NULL, NULL };
+ static char *last_artwork_identifier[3] = { NULL, NULL, NULL };
static boolean last_override_level_artwork[3] = { FALSE, FALSE, FALSE };
- static boolean last_has_level_artwork_set[3] = { FALSE, FALSE, FALSE };
+ static boolean last_has_custom_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 = GFX_OVERRIDE_ARTWORK(type);
// !!! setLevelArtworkDir() should be moved to an earlier stage !!!
char *leveldir_artwork_set = setLevelArtworkDir(artwork_first_node);
boolean has_level_artwork_set = (leveldir_artwork_set != NULL);
+ TreeInfo *custom_artwork_set =
+ getTreeInfoFromIdentifier(artwork_first_node, leveldir_identifier);
+ boolean has_custom_artwork_set = (custom_artwork_set != NULL);
char *artwork_current_identifier;
char *artwork_new_identifier = NULL; // default: nothing has changed
if (setup_override_artwork)
artwork_current_identifier = setup_artwork_set;
- else if (leveldir_artwork_set != NULL)
+ else if (has_level_artwork_set)
artwork_current_identifier = leveldir_artwork_set;
- else if (getTreeInfoFromIdentifier(artwork_first_node, leveldir_identifier))
+ else if (has_custom_artwork_set)
artwork_current_identifier = leveldir_identifier;
else
artwork_current_identifier = setup_artwork_set;
-
/* 2nd step: check if it is really needed to reload artwork set
------------------------------------------------------------ */
// ---------- 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))
+ if (last_leveldir_identifier[type] != leveldir_identifier &&
+ (last_has_custom_artwork_set[type] || has_custom_artwork_set))
artwork_new_identifier = artwork_current_identifier;
- leveldir_current_identifier[type] = leveldir_identifier;
- last_has_level_artwork_set[type] = has_level_artwork_set;
+ last_leveldir_identifier[type] = leveldir_identifier;
+ last_has_custom_artwork_set[type] = has_custom_artwork_set;
// ---------- reload if "override artwork" setting has changed --------------
if (last_override_level_artwork[type] != setup_override_artwork)
last_override_level_artwork[type] = setup_override_artwork;
// ---------- reload if current artwork identifier has changed --------------
- if (!strEqual(ARTWORK_CURRENT_IDENTIFIER(artwork, type),
- artwork_current_identifier))
+ if (!strEqual(last_artwork_identifier[type], artwork_current_identifier))
artwork_new_identifier = artwork_current_identifier;
- *(ARTWORK_CURRENT_IDENTIFIER_PTR(artwork, type))= artwork_current_identifier;
+ // (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 -------------------------
if (!initialized[type])
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
InitOverrideArtwork();
- force_reload_gfx |= AdjustGraphicsForEMC();
+ 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 ||
FadeOut(REDRAW_ALL);
- ClearRectangle(drawto, 0, 0, WIN_XSIZE, WIN_YSIZE);
- print_timestamp_time("ClearRectangle");
+ SetLoadingBackgroundImage();
+
+ ClearRectangleOnBackground(drawto, 0, 0, WIN_XSIZE, WIN_YSIZE);
+ print_timestamp_time("ClearRectangleOnBackground");
FadeIn(REDRAW_ALL);
+ UPDATE_BUSY_STATE();
+
+ InitMissingFileHash();
+
if (gfx_new_identifier != NULL || force_reload_gfx)
{
#if 0
- printf("RELOADING GRAPHICS '%s' -> '%s' ['%s', '%s']\n",
- artwork.gfx_current_identifier,
- gfx_new_identifier,
- artwork.gfx_current->identifier,
- leveldir_current->graphics_set);
+ Debug("init:ReloadCustomArtwork",
+ "RELOADING GRAPHICS '%s' -> '%s' ['%s', '%s']",
+ artwork.gfx_current_identifier,
+ gfx_new_identifier,
+ artwork.gfx_current->identifier,
+ leveldir_current->graphics_set);
#endif
InitImages();
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");
}
SetGameStatus(last_game_status); // restore current game status
- init_last = init; // switch to new busy animation
-
FadeOut(REDRAW_ALL);
RedrawGlobalBorder();
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);
BackToFront();
- // deactivate toons on error message screen
- setup.toons = FALSE;
+ // deactivate toons and global animations on error message screen
+ setup.global_animations = FALSE;
WaitForEventToContinue();
}
InitGlobal(); // initialize some global variables
+ InitRND(NEW_RANDOMIZE);
+ InitSimpleRandom(NEW_RANDOMIZE);
+ InitBetterRandom(NEW_RANDOMIZE);
+
+ InitMissingFileHash();
+
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);
#if defined(PLATFORM_UNIX)
NetworkServer(network.server_port, TRUE);
#else
- Error(ERR_WARN, "networking only supported in Unix version");
+ Warn("networking only supported in Unix version");
#endif
exit(0); // never reached, server loops forever
InitMixer();
print_timestamp_time("[init setup/config stuff (6)]");
- InitRND(NEW_RANDOMIZE);
- InitSimpleRandom(NEW_RANDOMIZE);
-
InitJoysticks();
print_timestamp_time("[init setup/config stuff]");
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();
if (global.autoplay_leveldir)
{
- AutoPlayTape();
+ AutoPlayTapes();
+ return;
+ }
+ else if (global.patchtapes_leveldir)
+ {
+ PatchTapes();
return;
}
else if (global.convert_leveldir)
ConvertLevels();
return;
}
- else if (global.create_images_dir)
+ else if (global.dumplevel_leveldir)
+ {
+ DumpLevels();
+ return;
+ }
+ else if (global.dumptape_leveldir)
+ {
+ DumpTapes();
+ return;
+ }
+ else if (global.create_sketch_images_dir)
{
CreateLevelSketchImages();
return;
}
+ else if (global.create_collect_images_dir)
+ {
+ CreateCollectElementImages();
+ return;
+ }
InitNetworkServer();
print_timestamp_done("OpenAll");
+ if (setup.ask_for_remaining_tapes)
+ setup.ask_for_uploading_tapes = TRUE;
+
DrawMainMenu();
#if 0
- Error(ERR_DEBUG, "::: SDL_GetBasePath() == '%s'",
+ Debug("internal:path", "SDL_GetBasePath() == '%s'",
SDL_GetBasePath());
- Error(ERR_DEBUG, "::: SDL_GetPrefPath() == '%s'",
+ Debug("internal:path", "SDL_GetPrefPath() == '%s'",
SDL_GetPrefPath("artsoft", "rocksndiamonds"));
#if defined(PLATFORM_ANDROID)
- Error(ERR_DEBUG, "::: SDL_AndroidGetInternalStoragePath() == '%s'",
+ Debug("internal:path", "SDL_AndroidGetInternalStoragePath() == '%s'",
SDL_AndroidGetInternalStoragePath());
- Error(ERR_DEBUG, "::: SDL_AndroidGetExternalStoragePath() == '%s'",
+ Debug("internal:path", "SDL_AndroidGetExternalStoragePath() == '%s'",
SDL_AndroidGetExternalStoragePath());
- Error(ERR_DEBUG, "::: SDL_AndroidGetExternalStorageState() == '%s'",
+ Debug("internal:path", "SDL_AndroidGetExternalStorageState() == '%s'",
(SDL_AndroidGetExternalStorageState() &
SDL_ANDROID_EXTERNAL_STORAGE_WRITE ? "writable" :
SDL_AndroidGetExternalStorageState() &
#endif
}
+static boolean WaitForApiThreads(void)
+{
+ DelayCounter thread_delay = { 10000 };
+
+ if (program.api_thread_count == 0)
+ return TRUE;
+
+ // deactivate global animations (not accessible in game state "loading")
+ setup.global_animations = FALSE;
+
+ // set game state to "loading" to be able to show busy animation
+ SetGameStatus(GAME_MODE_LOADING);
+
+ ResetDelayCounter(&thread_delay);
+
+ // wait for threads to finish (and fail on timeout)
+ while (program.api_thread_count > 0)
+ {
+ if (DelayReached(&thread_delay))
+ {
+ Error("failed waiting for threads - TIMEOUT");
+
+ return FALSE;
+ }
+
+ UPDATE_BUSY_STATE();
+
+ Delay(20);
+ }
+
+ return TRUE;
+}
+
void CloseAllAndExit(int exit_value)
{
+ WaitForApiThreads();
+
StopSounds();
FreeAllSounds();
FreeAllMusic();
// using SDL_WaitThread()
//
// Code used with SDL 1.2:
- // if (network_server) // terminate network server
- // SDL_KillThread(server_thread);
+ // if (network.server_thread) // terminate network server
+ // SDL_KillThread(network.server_thread);
CloseVideoDisplay();
ClosePlatformDependentStuff();