diff --git a/src/data.h b/src/data.h index 4b69d61a..949cec48 100644 --- a/src/data.h +++ b/src/data.h @@ -762,6 +762,8 @@ extern custom_options_type custom_defaults INIT(= { .demo_hitp = 4, .demo_end_room = 24, .intro_music_level = 1, + .intro_music_time_initial = 33, + .intro_music_time_restart = 4, .have_sword_from_level = 2, .checkpoint_level = 3, .checkpoint_respawn_dir = dir_FF_left, diff --git a/src/menu.c b/src/menu.c index fecfc911..f83f00c4 100644 --- a/src/menu.c +++ b/src/menu.c @@ -197,6 +197,7 @@ enum setting_ids { SETTING_FIX_HANG_ON_TELEPORT, SETTING_FIX_EXIT_DOOR, SETTING_FIX_QUICKSAVE_DURING_FEATHER, + SETTING_FIX_QUICKSAVE_DURING_LVL1_MUSIC, SETTING_USE_CUSTOM_OPTIONS, SETTING_START_MINUTES_LEFT, SETTING_START_TICKS_LEFT, @@ -552,6 +553,10 @@ setting_type gameplay_settings[] = { .linked = &fixes_saved.fix_quicksave_during_feather, .required = &use_fixes_and_enhancements, .text = "Fix quick save in feather mode", .explanation = "You cannot save game while floating in feather mode."}, + {.id = SETTING_FIX_QUICKSAVE_DURING_LVL1_MUSIC, .style = SETTING_STYLE_TOGGLE, + .linked = &fixes_saved.fix_quicksave_during_lvl1_music, .required = &use_fixes_and_enhancements, + .text = "Fix quick save during level 1 initial music", + .explanation = "If you save during the level 1 initial music and reload, you stand up faster than otherwise."}, }; NAMES_LIST(tile_type_setting_names, { diff --git a/src/options.c b/src/options.c index 1bfe4734..8dc6a68a 100644 --- a/src/options.c +++ b/src/options.c @@ -273,6 +273,7 @@ static int global_ini_callback(const char *section, const char *name, const char process_boolean("fix_hang_on_teleport", &fixes_saved.fix_hang_on_teleport); process_boolean("fix_exit_door", &fixes_saved.fix_exit_door); process_boolean("fix_quicksave_during_feather", &fixes_saved.fix_quicksave_during_feather); + process_boolean("fix_quicksave_during_lvl1_music", &fixes_saved.fix_quicksave_during_lvl1_music); } if (check_ini_section("CustomGameplay")) { diff --git a/src/replay.c b/src/replay.c index f4e583bf..e9f1df78 100644 --- a/src/replay.c +++ b/src/replay.c @@ -367,6 +367,7 @@ void options_process_fixes(SDL_RWops* rw, rw_process_func_type process_func) { process(fixes_options_replay.fix_hang_on_teleport); process(fixes_options_replay.fix_exit_door); process(fixes_options_replay.fix_quicksave_during_feather); + process(fixes_options_replay.fix_quicksave_during_lvl1_music); } void options_process_custom_general(SDL_RWops* rw, rw_process_func_type process_func) { diff --git a/src/seg003.c b/src/seg003.c index 7317edbb..2b5bb043 100644 --- a/src/seg003.c +++ b/src/seg003.c @@ -42,7 +42,12 @@ void __pascal far init_game(int level) { rem_tick = custom->start_ticks_left; // 719 hitp_beg_lev = custom->start_hitp; // 3 } - need_level1_music = (level == /*1*/ custom->intro_music_level); + + if (fixes->fix_quicksave_during_lvl1_music) + if (level == /*1*/ custom->intro_music_level) need_level1_music = custom->intro_music_time_initial; + else + need_level1_music = (level == /*1*/ custom->intro_music_level); + play_level(level); } @@ -368,6 +373,10 @@ int __pascal far play_level_2() { timers(); play_frame(); + if (need_level1_music != 0 && current_level == /*1*/ custom->intro_music_level) + if (fixes->fix_quicksave_during_lvl1_music) + need_level1_music = custom->intro_music_time_restart; + #ifdef USE_REPLAY // At the exact "end of level" frame, preserve the seed to ensure reproducibility, // regardless of how long the sound is still playing *after* this frame (torch animation modifies the seed!) diff --git a/src/seg005.c b/src/seg005.c index f79f0538..1742f51b 100644 --- a/src/seg005.c +++ b/src/seg005.c @@ -307,19 +307,27 @@ void __pascal far control() { // seg005:02EB void __pascal far control_crouched() { if (need_level1_music != 0 && current_level == /*1*/ custom->intro_music_level) { - // Special event: music when crouching - if (! check_sound_playing()) { - if (need_level1_music == 1) { - play_sound(sound_25_presentation); // presentation (level 1 start) - need_level1_music = 2; - } else { -#ifdef USE_REPLAY - if (recording) special_move = MOVE_EFFECT_END; - if (!replaying) // during replays, crouch immobilization gets cancelled in do_replay_move() -#endif - need_level1_music = 0; - } - } + + if (fixes->fix_quicksave_during_lvl1_music) + { + need_level1_music--; + } + else + { + // Special event: music when crouching + if (! check_sound_playing()) { + if (need_level1_music == 1) { + play_sound(sound_25_presentation); // presentation (level 1 start) + need_level1_music = 2; + } else { + #ifdef USE_REPLAY + if (recording) special_move = MOVE_EFFECT_END; + if (!replaying) // during replays, crouch immobilization gets cancelled in do_replay_move() + #endif + need_level1_music = 0; + } + } + } } else { need_level1_music = 0; if (control_shift2 < 0 && check_get_item()) return; diff --git a/src/types.h b/src/types.h index 1f696d17..59946031 100644 --- a/src/types.h +++ b/src/types.h @@ -1216,6 +1216,7 @@ typedef struct fixes_options_type { byte fix_hang_on_teleport; byte fix_exit_door; byte fix_quicksave_during_feather; + byte fix_quicksave_during_lvl1_music; } fixes_options_type; #define NUM_GUARD_SKILLS 12 @@ -1244,6 +1245,8 @@ typedef struct custom_options_type { word demo_hitp; word demo_end_room; word intro_music_level; + word intro_music_time_initial; + word intro_music_time_restart; word have_sword_from_level; word checkpoint_level; sbyte checkpoint_respawn_dir;