static int get_graphic_parameter_value(char *, char *, int);
-static Bitmap *getLoadingBackgroundBitmap(int graphic)
+static int getLoadingBackgroundImage(int graphic)
{
- return getBitmapFromGraphicOrDefault(graphic, INITIAL_IMG_BACKGROUND);
+ return getImageFromGraphicOrDefault(graphic, INITIAL_IMG_BACKGROUND);
}
static void SetLoadingWindowBackgroundImage(int graphic)
{
- SetWindowBackgroundBitmap(getLoadingBackgroundBitmap(graphic));
+ SetBackgroundImage(getLoadingBackgroundImage(graphic), REDRAW_ALL);
}
static void SetLoadingBackgroundImage(void)
{
struct GraphicInfo *g = &graphic_info[graphic];
+ // if graphic was cloned, scale cloned graphic
+ if (graphic_info[graphic].clone_from != -1)
+ graphic = graphic_info[graphic].clone_from;
+
// create small and game tile sized bitmaps (and scale up, if needed)
CreateImageWithSmallImages(graphic, g->scale_up_factor, g->tile_size);
}
{
struct GraphicInfo *g = &graphic_info[graphic];
+ // if graphic was cloned, scale cloned graphic
+ if (graphic_info[graphic].clone_from != -1)
+ graphic = graphic_info[graphic].clone_from;
+
ScaleImage(graphic, g->scale_up_factor);
}
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)
// look for special default action graphic (classic game specific)
if (IS_BD_ELEMENT(i) && element_info[EL_BD_DEFAULT].graphic[act] != -1)
default_action_graphic = element_info[EL_BD_DEFAULT].graphic[act];
+ if (IS_BDX_ELEMENT(i) && element_info[EL_BDX_DEFAULT].graphic[act] != -1)
+ default_action_graphic = element_info[EL_BDX_DEFAULT].graphic[act];
if (IS_SP_ELEMENT(i) && element_info[EL_SP_DEFAULT].graphic[act] != -1)
default_action_graphic = element_info[EL_SP_DEFAULT].graphic[act];
if (IS_SB_ELEMENT(i) && element_info[EL_SB_DEFAULT].graphic[act] != -1)
if (IS_BD_ELEMENT(i) && element_info[EL_BD_DEFAULT].crumbled[act] != -1)
default_action_crumbled = element_info[EL_BD_DEFAULT].crumbled[act];
+ if (IS_BDX_ELEMENT(i) && element_info[EL_BDX_DEFAULT].crumbled[act] != -1)
+ default_action_crumbled = element_info[EL_BDX_DEFAULT].crumbled[act];
if (IS_SP_ELEMENT(i) && element_info[EL_SP_DEFAULT].crumbled[act] != -1)
default_action_crumbled = element_info[EL_SP_DEFAULT].crumbled[act];
if (IS_SB_ELEMENT(i) && element_info[EL_SB_DEFAULT].crumbled[act] != -1)
action = -1;
}
+ // for BD effect editor graphics, replace element with effect element, if exists
+ if (action != -1 && special == GFX_SPECIAL_ARG_EDITOR)
+ {
+ int element_bd = map_element_RND_to_BD_effect(element, action);
+ int element_ef = map_element_BD_to_RND_cave(element_bd);
+
+ if (element_ef != EL_UNKNOWN)
+ {
+ element = element_ef;
+ action = -1;
+ }
+ }
+
if (element >= MAX_NUM_ELEMENTS)
continue;
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 (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)
{
// optionally, the second movement tile can be specified as start tile
if (parameter[GFX_ARG_2ND_SWAP_TILES] != ARG_UNDEFINED_VALUE)
- g->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)
// 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)
// look for special default action sound (classic game specific)
if (IS_BD_ELEMENT(i) && element_info[EL_BD_DEFAULT].sound[act] != -1)
default_action_sound = element_info[EL_BD_DEFAULT].sound[act];
+ if (IS_BDX_ELEMENT(i) && element_info[EL_BDX_DEFAULT].sound[act] != -1)
+ default_action_sound = element_info[EL_BDX_DEFAULT].sound[act];
if (IS_SP_ELEMENT(i) && element_info[EL_SP_DEFAULT].sound[act] != -1)
default_action_sound = element_info[EL_SP_DEFAULT].sound[act];
if (IS_SB_ELEMENT(i) && element_info[EL_SB_DEFAULT].sound[act] != -1)
}
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);
InitImageTextures(); // create textures for certain images
print_timestamp_time("InitImageTextures");
+ InitGraphicInfo_BD(); // graphic mapping for BD engine
+ print_timestamp_time("InitGraphicInfo_BD");
InitGraphicInfo_EM(); // graphic mapping for EM engine
print_timestamp_time("InitGraphicInfo_EM");
EL_PLAYER_3,
EL_PLAYER_4,
EL_BD_FIREFLY,
- EL_BD_FIREFLY_1,
- EL_BD_FIREFLY_2,
- EL_BD_FIREFLY_3,
- EL_BD_FIREFLY_4,
+ EL_BD_FIREFLY_LEFT,
+ EL_BD_FIREFLY_DOWN,
+ EL_BD_FIREFLY_RIGHT,
+ EL_BD_FIREFLY_UP,
EL_BD_BUTTERFLY,
- EL_BD_BUTTERFLY_1,
- EL_BD_BUTTERFLY_2,
- EL_BD_BUTTERFLY_3,
- EL_BD_BUTTERFLY_4,
+ EL_BD_BUTTERFLY_DOWN,
+ EL_BD_BUTTERFLY_LEFT,
+ EL_BD_BUTTERFLY_UP,
+ EL_BD_BUTTERFLY_RIGHT,
EL_BD_AMOEBA,
EL_CHAR_QUESTION,
EL_UNKNOWN,
EL_AMOEBA_DRY,
EL_AMOEBA_FULL,
EL_BD_AMOEBA,
+ EL_BDX_AMOEBA_1,
+ EL_BDX_AMOEBA_2,
+ EL_BDX_SLIME,
+ EL_BDX_ACID,
+ EL_BDX_BITER,
+ EL_BDX_BITER_RIGHT,
+ EL_BDX_BITER_UP,
+ EL_BDX_BITER_LEFT,
+ EL_BDX_BITER_DOWN,
+ EL_BDX_BLADDER,
+ EL_BDX_NUT,
EL_EMC_MAGIC_BALL,
EL_EMC_ANDROID,
+ EL_MM_GRAY_BALL,
-1
};
static int ep_editor_cascade_active[] =
{
EL_INTERNAL_CASCADE_BD_ACTIVE,
+ EL_INTERNAL_CASCADE_BDX_ACTIVE,
+ EL_INTERNAL_CASCADE_BDX_EFFECTS_ACTIVE,
EL_INTERNAL_CASCADE_EM_ACTIVE,
EL_INTERNAL_CASCADE_EMC_ACTIVE,
EL_INTERNAL_CASCADE_RND_ACTIVE,
static int ep_editor_cascade_inactive[] =
{
EL_INTERNAL_CASCADE_BD,
+ EL_INTERNAL_CASCADE_BDX,
+ EL_INTERNAL_CASCADE_BDX_EFFECTS,
EL_INTERNAL_CASCADE_EM,
EL_INTERNAL_CASCADE_EMC,
EL_INTERNAL_CASCADE_RND,
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;
+ element_info[i].editor_description = element_name_info[i].editor_description;
}
for (i = 0; i < NUM_GLOBAL_ANIM_TOKENS + 1; i++)
image_config[i].token,
image_config[i].value);
+ // create hash from sound config list
+ sound_config_hash = newSetupFileHash();
+ for (i = 0; sound_config[i].token != NULL; i++)
+ setHashEntry(sound_config_hash,
+ sound_config[i].token,
+ sound_config[i].value);
+
// create hash from element token list
element_token_hash = newSetupFileHash();
for (i = 0; element_name_info[i].token_name != NULL; i++)
global.autoplay_leveldir = NULL;
global.patchtapes_leveldir = NULL;
global.convert_leveldir = NULL;
+ global.dumplevelset_leveldir = NULL;
global.dumplevel_leveldir = NULL;
global.dumptape_leveldir = NULL;
global.create_sketch_images_dir = NULL;
exit(0);
}
+ else if (strPrefix(command, "dump levelset "))
+ {
+ char *filename = &command[14];
+
+ if (fileExists(filename) && isLevelsetFilename_BD(filename))
+ {
+ DumpLevelsetFromFilename_BD(filename);
+
+ exit(0);
+ }
+
+ char *leveldir = getStringCopy(filename); // read command parameters
+
+ global.dumplevelset_leveldir = leveldir;
+
+ program.headless = TRUE;
+ }
else if (strPrefix(command, "dump level "))
{
char *filename = &command[11];
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.request_active_or_moving = FALSE;
game.use_masked_elements_initial = FALSE;
}
// dynamically determine list of sound tokens to be ignored
num_ignore_sound_tokens = num_ignore_generic_tokens;
+ for (i = 0; sound_config_vars[i].token != NULL; i++)
+ num_ignore_sound_tokens++;
ignore_sound_tokens =
checked_malloc((num_ignore_sound_tokens + 1) * sizeof(char *));
for (i = 0; i < num_ignore_generic_tokens; i++)
ignore_sound_tokens[i] = ignore_generic_tokens[i];
+ for (i = 0; i < num_ignore_sound_tokens - num_ignore_generic_tokens; i++)
+ ignore_sound_tokens[num_ignore_generic_tokens + i] =
+ sound_config_vars[i].token;
ignore_sound_tokens[num_ignore_sound_tokens] = NULL;
// dynamically determine list of music tokens to be ignored
}
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);
// required if door size definitions have changed
InitGraphicCompatibilityInfo_Doors();
+ InitGfxBuffers_BD();
InitGfxBuffers_EM();
InitGfxBuffers_SP();
+ InitGfxBuffers_MM();
}
static void InitGfx(void)
InitFontGraphicInfo();
- DrawProgramInfo();
-
- DrawInitTextHead("Loading graphics");
-
InitMenuDesignSettings_Static();
// initialize settings for initial images with default values
checked_free(filename_image_initial[i]);
}
+ for (i = 0; i < NUM_INITIAL_IMAGES; i++)
+ image_initial[i].use_image_size = TRUE;
+
graphic_info = image_initial; // graphic == 0 => image_initial
for (i = 0; i < NUM_INITIAL_IMAGES; i++)
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;
redraw_mask = REDRAW_ALL;
}
+static void InitSnd(void)
+{
+ InitSoundSettings_Static();
+
+ // read settings for initial sounds from default custom artwork config
+ char *snd_config_filename = getPath3(options.sounds_directory,
+ SND_DEFAULT_SUBDIR,
+ SOUNDSINFO_FILENAME);
+
+ if (fileExists(snd_config_filename))
+ {
+ SetupFileHash *setup_file_hash = loadSetupFileHash(snd_config_filename);
+
+ if (setup_file_hash)
+ {
+ // read values from custom sounds config file
+ InitSoundSettings_FromHash(setup_file_hash, FALSE);
+
+ freeSetupFileHash(setup_file_hash);
+ }
+ }
+}
+
static void InitLevelInfo(void)
{
LoadLevelInfo(); // global level info
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");
+ LoadSoundSettings();
+ print_timestamp_time("LoadSoundSettings");
+
ReinitializeSounds();
print_timestamp_time("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();
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)
+ if (setup.override_level_graphics == STATE_AUTO ||
+ setup.override_level_sounds == STATE_AUTO ||
+ setup.override_level_music == STATE_AUTO)
redefined_ce_found =
(CheckArtworkTypeForRedefinedCustomElements(ARTWORK_TYPE_GRAPHICS) |
CheckArtworkTypeForRedefinedCustomElements(ARTWORK_TYPE_SOUNDS) |
if (redefined_ce_found)
{
- // this level set has CE definitions: change "AUTO" to "FALSE"
+ // this level set has CE definitions: change "MODE_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"
+ // this level set has no CE definitions: change "MODE_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 (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);
BackToFront();
- // deactivate toons on error message screen
- setup.toons = FALSE;
+ // deactivate toons and global animations on error message screen
+ setup.global_animations = FALSE;
WaitForEventToContinue();
}
print_timestamp_time("[init element properties stuff]");
InitGfx();
+ InitSnd();
print_timestamp_time("InitGfx");
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();
InitGfxBackground();
+ bd_open_all();
em_open_all();
sp_open_all();
mm_open_all();
ConvertLevels();
return;
}
+ else if (global.dumplevelset_leveldir)
+ {
+ DumpLevelset();
+ return;
+ }
else if (global.dumplevel_leveldir)
{
DumpLevels();
DrawMainMenu();
+ if (options.drop_file != NULL)
+ PushDropEvent(options.drop_file);
+
#if 0
Debug("internal:path", "SDL_GetBasePath() == '%s'",
SDL_GetBasePath());
return TRUE;
// deactivate global animations (not accessible in game state "loading")
- setup.toons = FALSE;
+ setup.global_animations = FALSE;
// set game state to "loading" to be able to show busy animation
SetGameStatus(GAME_MODE_LOADING);
FreeAllMusic();
CloseAudio(); // called after freeing sounds (needed for SDL)
+ bd_close_all();
em_close_all();
sp_close_all();