diff --git a/distribution/changelog.txt b/distribution/changelog.txt index c1e6c7971b..2d590c17e5 100644 --- a/distribution/changelog.txt +++ b/distribution/changelog.txt @@ -17,6 +17,7 @@ - Feature: [#6414] Raise maximum launch speed of the Corkscrew RC back to 96 km/h (for RCT1 parity). - Feature: [#6433] Turn 'unlock all prices' into a regular (non-cheat, persistent) option. - Feature: Allow using object files from RCT Classic. +- Feature: Title sequences now testable in-game. - Fix: [#816] In the map window, there are more peeps flickering than there are selected (original bug). - Fix: [#1833, #4937, #6138] 'Too low!' warning when building rides and shops on the lowest land level (original bug). - Fix: [#6199] Inverted Hairpin Coaster vehicle tab is not centred. diff --git a/src/openrct2-ui/windows/Options.cpp b/src/openrct2-ui/windows/Options.cpp index f2fdbc054f..a8bde8473d 100644 --- a/src/openrct2-ui/windows/Options.cpp +++ b/src/openrct2-ui/windows/Options.cpp @@ -1962,7 +1962,7 @@ static void window_options_paint(rct_window *w, rct_drawpixelinfo *dpi) w->y + window_options_misc_widgets[WIDX_AUTOSAVE].top ); - const utf8 * name = title_sequence_manager_get_name(title_get_current_sequence()); + const utf8 * name = title_sequence_manager_get_name(title_get_config_sequence()); set_format_arg(0, uintptr_t, (uintptr_t)name); gfx_draw_string_left(dpi, STR_TITLE_SEQUENCE, w, w->colours[1], w->x + 10, w->y + window_options_misc_widgets[WIDX_TITLE_SEQUENCE].top + 1); gfx_draw_string_left_clipped( diff --git a/src/openrct2-ui/windows/TitleCommandEditor.cpp b/src/openrct2-ui/windows/TitleCommandEditor.cpp index 3aa19ed60b..b3c13c7c7b 100644 --- a/src/openrct2-ui/windows/TitleCommandEditor.cpp +++ b/src/openrct2-ui/windows/TitleCommandEditor.cpp @@ -171,7 +171,7 @@ static LocationXY16 get_location() sint32 interactionType; rct_map_element *mapElement; - get_map_coordinates_from_pos(w->viewport->view_width / 2, w->viewport->view_height / 2, VIEWPORT_INTERACTION_MASK_TERRAIN, &mapCoord.x, &mapCoord.y, &interactionType, &mapElement, nullptr); + get_map_coordinates_from_pos_window(w, w->viewport->view_width / 2, w->viewport->view_height / 2, VIEWPORT_INTERACTION_MASK_TERRAIN, &mapCoord.x, &mapCoord.y, &interactionType, &mapElement, nullptr); mapCoord.x -= 16; mapCoord.x /= 32; mapCoord.y -= 16; diff --git a/src/openrct2-ui/windows/TitleEditor.cpp b/src/openrct2-ui/windows/TitleEditor.cpp index 81b319ea87..31a35cb82e 100644 --- a/src/openrct2-ui/windows/TitleEditor.cpp +++ b/src/openrct2-ui/windows/TitleEditor.cpp @@ -280,6 +280,15 @@ void window_title_editor_open(sint32 tab) static void window_title_editor_close(rct_window *w) { + uint16 preset = title_get_config_sequence(); + title_set_current_sequence(preset, false); + if (!gTestingTitleSequenceInGame) + { + ITitleSequencePlayer * player = window_title_editor_get_player(); + player->Begin(preset); + } + gTestingTitleSequenceInGame = false; + // Close the related windows window_close_by_class(WC_TITLE_COMMAND_EDITOR); @@ -447,14 +456,26 @@ static void window_title_editor_mouseup(rct_window *w, rct_widgetindex widgetInd break; case WIDX_TITLE_EDITOR_STOP: if (_isSequencePlaying) { - title_set_current_sequence(0); + uint16 preset = title_get_config_sequence(); + title_set_current_sequence(preset, false); + if (!gTestingTitleSequenceInGame) + { + ITitleSequencePlayer * player = window_title_editor_get_player(); + player->Begin(preset); + } _isSequencePlaying = false; + gTestingTitleSequenceInGame = false; } break; case WIDX_TITLE_EDITOR_PLAY: - if (!_isSequencePlaying && (gScreenFlags & SCREEN_FLAGS_TITLE_DEMO)) { - title_set_current_sequence((uint16)_selectedTitleSequence); + if (!_isSequencePlaying || _selectedTitleSequence != title_get_current_sequence()) { + ITitleSequencePlayer * player = window_title_editor_get_player(); + title_set_current_sequence((uint16)_selectedTitleSequence, true); + player->Begin((uint32)_selectedTitleSequence); _isSequencePlaying = true; + if (!(gScreenFlags & SCREEN_FLAGS_TITLE_DEMO)) { + gTestingTitleSequenceInGame = true; + } } break; case WIDX_TITLE_EDITOR_SKIP: @@ -747,7 +768,7 @@ static void window_title_editor_invalidate(rct_window *w) window_title_editor_widgets[WIDX_TITLE_EDITOR_SKIP].top = w->height - 32; window_title_editor_widgets[WIDX_TITLE_EDITOR_SKIP].bottom = w->height - 16; - if (!(gScreenFlags & SCREEN_FLAGS_TITLE_DEMO)) { + if (!(gScreenFlags & SCREEN_FLAGS_TITLE_DEMO) && gScreenFlags != SCREEN_FLAGS_PLAYING) { w->disabled_widgets |= (1 << WIDX_TITLE_EDITOR_PLAY); } else { w->disabled_widgets &= ~(1 << WIDX_TITLE_EDITOR_PLAY); @@ -840,7 +861,7 @@ static void window_title_editor_scrollpaint_saves(rct_window *w, rct_drawpixelin static void window_title_editor_scrollpaint_commands(rct_window *w, rct_drawpixelinfo *dpi) { sint32 position = -1; - if (_isSequencePlaying) { + if (_isSequencePlaying && (uint16)_selectedTitleSequence == title_get_current_sequence()) { ITitleSequencePlayer * player = window_title_editor_get_player(); position = title_sequence_player_get_current_position(player); } diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 1657e64705..544e81efb6 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -377,12 +377,87 @@ namespace OpenRCT2 return true; } - bool LoadParkFromFile(const std::string &path, bool loadTitleScreenOnFail = false) final override + bool LoadParkFromFile(const std::string &path, bool loadTitleScreenOnFail) final override { auto fs = FileStream(path, FILE_MODE_OPEN); return LoadParkFromStream(&fs, path, loadTitleScreenOnFail); } + bool LoadParkFromStream(IStream * stream, const std::string &path, bool loadTitleScreenFirstOnFail) final override + { + ClassifiedFileInfo info; + if (TryClassifyFile(stream, &info)) + { + if (info.Type == FILE_TYPE::SAVED_GAME || + info.Type == FILE_TYPE::SCENARIO) + { + std::unique_ptr parkImporter; + if (info.Version <= FILE_TYPE_S4_CUTOFF) + { + // Save is an S4 (RCT1 format) + parkImporter.reset(ParkImporter::CreateS4()); + } + else + { + // Save is an S6 (RCT2 format) + parkImporter.reset(ParkImporter::CreateS6(_objectRepository, _objectManager)); + } + + auto result = parkImporter->LoadFromStream(stream, info.Type == FILE_TYPE::SCENARIO, false, path.c_str()); + if (result.Error == PARK_LOAD_ERROR_OK) + { + parkImporter->Import(); + game_fix_save_vars(); + sprite_position_tween_reset(); + gScreenAge = 0; + gLastAutoSaveUpdate = AUTOSAVE_PAUSE; + if (info.Type == FILE_TYPE::SAVED_GAME) + { + if (network_get_mode() == NETWORK_MODE_CLIENT) + { + network_close(); + } + game_load_init(); + if (network_get_mode() == NETWORK_MODE_SERVER) + { + network_send_map(); + } + } + else + { + scenario_begin(); + if (network_get_mode() == NETWORK_MODE_SERVER) + { + network_send_map(); + } + if (network_get_mode() == NETWORK_MODE_CLIENT) + { + network_close(); + } + } + // This ensures that the newly loaded save reflects the user's + // 'show real names of guests' option, now that it's a global setting + peep_update_names(gConfigGeneral.show_real_names_of_guests); + return true; + } + else + { + handle_park_load_failure_with_title_opt(&result, path.c_str(), loadTitleScreenFirstOnFail); + } + + } + else + { + Console::Error::WriteLine("Invalid file type."); + } + } + else + { + Console::Error::WriteLine("Unable to detect file type."); + } + return false; + } + private: std::string GetOrPromptRCT2Path() { @@ -701,81 +776,6 @@ namespace OpenRCT2 console_update(); } - bool LoadParkFromStream(IStream * stream, const std::string &path, bool loadTitleScreenFirstOnFail) - { - ClassifiedFileInfo info; - if (TryClassifyFile(stream, &info)) - { - if (info.Type == FILE_TYPE::SAVED_GAME || - info.Type == FILE_TYPE::SCENARIO) - { - std::unique_ptr parkImporter; - if (info.Version <= FILE_TYPE_S4_CUTOFF) - { - // Save is an S4 (RCT1 format) - parkImporter.reset(ParkImporter::CreateS4()); - } - else - { - // Save is an S6 (RCT2 format) - parkImporter.reset(ParkImporter::CreateS6(_objectRepository, _objectManager)); - } - - auto result = parkImporter->LoadFromStream(stream, info.Type == FILE_TYPE::SCENARIO, false, path.c_str()); - if (result.Error == PARK_LOAD_ERROR_OK) - { - parkImporter->Import(); - game_fix_save_vars(); - sprite_position_tween_reset(); - gScreenAge = 0; - gLastAutoSaveUpdate = AUTOSAVE_PAUSE; - if (info.Type == FILE_TYPE::SAVED_GAME) - { - if (network_get_mode() == NETWORK_MODE_CLIENT) - { - network_close(); - } - game_load_init(); - if (network_get_mode() == NETWORK_MODE_SERVER) - { - network_send_map(); - } - } - else - { - scenario_begin(); - if (network_get_mode() == NETWORK_MODE_SERVER) - { - network_send_map(); - } - if (network_get_mode() == NETWORK_MODE_CLIENT) - { - network_close(); - } - } - // This ensures that the newly loaded save reflects the user's - // 'show real names of guests' option, now that it's a global setting - peep_update_names(gConfigGeneral.show_real_names_of_guests); - return true; - } - else - { - handle_park_load_failure_with_title_opt(&result, path.c_str(), loadTitleScreenFirstOnFail); - } - - } - else - { - Console::Error::WriteLine("Invalid file type."); - } - } - else - { - Console::Error::WriteLine("Unable to detect file type."); - } - return false; - } - /** * Copy saved games and landscapes to user directory */ @@ -880,6 +880,11 @@ extern "C" return GetContext()->LoadParkFromFile(path); } + bool context_load_park_from_stream(void * stream) + { + return GetContext()->LoadParkFromStream((IStream*)stream, ""); + } + void openrct2_write_full_version_info(utf8 * buffer, size_t bufferSize) { String::Set(buffer, bufferSize, gVersionInfoFull); diff --git a/src/openrct2/Context.h b/src/openrct2/Context.h index d56dcc7995..5f492c285a 100644 --- a/src/openrct2/Context.h +++ b/src/openrct2/Context.h @@ -69,6 +69,8 @@ enum #include +interface IStream; + namespace OpenRCT2 { interface IPlatformEnvironment; @@ -97,6 +99,7 @@ namespace OpenRCT2 virtual bool Initialise() abstract; virtual bool LoadParkFromFile(const std::string &path, bool loadTitleScreenOnFail = false) abstract; + virtual bool LoadParkFromStream(IStream * stream, const std::string &path, bool loadTitleScreenFirstOnFail = false) abstract; virtual void Finish() abstract; virtual void Quit() abstract; @@ -221,6 +224,7 @@ extern "C" void context_quit(); const utf8 * context_get_path_legacy(sint32 pathId); bool context_load_park_from_file(const utf8 * path); + bool context_load_park_from_stream(void * stream); #ifdef __cplusplus } #endif diff --git a/src/openrct2/game.c b/src/openrct2/game.c index 10973e6b7c..d49330cfea 100644 --- a/src/openrct2/game.c +++ b/src/openrct2/game.c @@ -46,6 +46,7 @@ #include "ride/Vehicle.h" #include "scenario/scenario.h" #include "title/TitleScreen.h" +#include "title/TitleSequencePlayer.h" #include "util/sawyercoding.h" #include "util/util.h" #include "windows/Intent.h" @@ -73,6 +74,8 @@ sint32 gGameCommandNestLevel; bool gGameCommandIsNetworked; char gCurrentLoadedPath[MAX_PATH]; +bool gLoadKeepWindowsOpen = false; + uint8 gUnk13CA740; uint8 gUnk141F568; @@ -292,6 +295,11 @@ void game_update() screenshot_check(); game_handle_keyboard_input(); + if (game_is_not_paused() && gTestingTitleSequenceInGame) + { + title_sequence_player_update((ITitleSequencePlayer*)title_get_sequence_player()); + } + // Determine how many times we need to update the game if (gGameSpeed > 1) { numUpdates = 1 << (gGameSpeed - 1); @@ -1161,8 +1169,11 @@ void game_load_init() gScreenFlags = SCREEN_FLAGS_PLAYING; audio_stop_all_music_and_sounds(); - viewport_init_all(); - game_create_windows(); + if (!gLoadKeepWindowsOpen) + { + viewport_init_all(); + game_create_windows(); + } mainWindow = window_get_main(); if (mainWindow != NULL) diff --git a/src/openrct2/game.h b/src/openrct2/game.h index a0a10a094c..4d86b7f775 100644 --- a/src/openrct2/game.h +++ b/src/openrct2/game.h @@ -156,6 +156,8 @@ extern sint32 gGameCommandNestLevel; extern bool gGameCommandIsNetworked; extern char gCurrentLoadedPath[260]; +extern bool gLoadKeepWindowsOpen; + extern uint8 gUnk13CA740; extern uint8 gUnk141F568; diff --git a/src/openrct2/interface/viewport.c b/src/openrct2/interface/viewport.c index 18140ae932..d33f1e73cc 100644 --- a/src/openrct2/interface/viewport.c +++ b/src/openrct2/interface/viewport.c @@ -1348,10 +1348,16 @@ static void sub_68862C(rct_drawpixelinfo * dpi, paint_struct * ps) * viewport: edi */ void get_map_coordinates_from_pos(sint32 screenX, sint32 screenY, sint32 flags, sint16 *x, sint16 *y, sint32 *interactionType, rct_map_element **mapElement, rct_viewport **viewport) +{ + rct_window* window = window_find_from_point(screenX, screenY); + get_map_coordinates_from_pos_window(window, screenX, screenY, flags, x, y, interactionType, mapElement, viewport); +} + +void get_map_coordinates_from_pos_window(rct_window * window, sint32 screenX, sint32 screenY, sint32 flags, sint16 * x, sint16 * y, + sint32 * interactionType, rct_map_element ** mapElement, rct_viewport ** viewport) { _unk9AC154 = flags & 0xFFFF; _interactionSpriteType = 0; - rct_window* window = window_find_from_point(screenX, screenY); if (window != NULL && window->viewport != NULL) { rct_viewport* myviewport = window->viewport; diff --git a/src/openrct2/interface/viewport.h b/src/openrct2/interface/viewport.h index f4eaafd667..f5656479ff 100644 --- a/src/openrct2/interface/viewport.h +++ b/src/openrct2/interface/viewport.h @@ -143,6 +143,8 @@ void hide_construction_rights(); void viewport_set_visibility(uint8 mode); void get_map_coordinates_from_pos(sint32 screenX, sint32 screenY, sint32 flags, sint16 *x, sint16 *y, sint32 *interactionType, rct_map_element **mapElement, rct_viewport **viewport); +void get_map_coordinates_from_pos_window(rct_window * window, sint32 screenX, sint32 screenY, sint32 flags, sint16 * x, sint16 * y, + sint32 * interactionType, rct_map_element ** mapElement, rct_viewport ** viewport); sint32 viewport_interaction_get_item_left(sint32 x, sint32 y, viewport_interaction_info *info); sint32 viewport_interaction_left_over(sint32 x, sint32 y); diff --git a/src/openrct2/scenario/scenario.c b/src/openrct2/scenario/scenario.c index 86750037c8..9111a8c928 100644 --- a/src/openrct2/scenario/scenario.c +++ b/src/openrct2/scenario/scenario.c @@ -105,7 +105,7 @@ void scenario_begin() research_reset_current_item(); scenery_set_default_placement_configuration(); news_item_init_queue(); - if (gScenarioObjectiveType != OBJECTIVE_NONE) + if (gScenarioObjectiveType != OBJECTIVE_NONE && !gLoadKeepWindowsOpen) context_open_window_view(WV_PARK_OBJECTIVE); gParkRating = calculate_park_rating(); diff --git a/src/openrct2/title/TitleScreen.cpp b/src/openrct2/title/TitleScreen.cpp index 5eeae7ff74..91d4da15ae 100644 --- a/src/openrct2/title/TitleScreen.cpp +++ b/src/openrct2/title/TitleScreen.cpp @@ -58,9 +58,13 @@ uint16 TitleScreen::GetCurrentSequence() return _currentSequence; } -void TitleScreen::SetCurrentSequence(uint16 value) +void TitleScreen::SetCurrentSequence(uint16 value, bool loadSequence) { _currentSequence = value; + if (loadSequence) + { + TryLoadSequence(); + } } bool TitleScreen::ShouldHideVersionInfo() @@ -103,7 +107,7 @@ void TitleScreen::Load() if (_sequencePlayer != nullptr) { - _sequencePlayer->Reset(); + _sequencePlayer->Begin(_currentSequence); // Force the title sequence to load / update so we // don't see a blank screen for a split second. @@ -187,7 +191,7 @@ void TitleScreen::TitleInitialise() IScenarioRepository * scenarioRepository = GetScenarioRepository(); _sequencePlayer = CreateTitleSequencePlayer(scenarioRepository); } - size_t seqId = title_sequence_manager_get_index_for_config_id(gConfigInterface.current_title_sequence_preset); + size_t seqId = title_get_config_sequence(); if (seqId == SIZE_MAX) { seqId = title_sequence_manager_get_index_for_config_id("*OPENRCT2"); @@ -283,6 +287,11 @@ extern "C" } } + uint16 title_get_config_sequence() + { + return (uint16)title_sequence_manager_get_index_for_config_id(gConfigInterface.current_title_sequence_preset); + } + uint16 title_get_current_sequence() { uint16 result = 0; @@ -293,11 +302,11 @@ extern "C" return result; } - void title_set_current_sequence(uint16 value) + void title_set_current_sequence(uint16 value, bool loadSequence) { if (_singleton != nullptr) { - _singleton->SetCurrentSequence(value); + _singleton->SetCurrentSequence(value, loadSequence); } } diff --git a/src/openrct2/title/TitleScreen.h b/src/openrct2/title/TitleScreen.h index 6dd3701c78..f609ed1754 100644 --- a/src/openrct2/title/TitleScreen.h +++ b/src/openrct2/title/TitleScreen.h @@ -28,7 +28,7 @@ class TitleScreen final public: ITitleSequencePlayer * GetSequencePlayer(); uint16 GetCurrentSequence(); - void SetCurrentSequence(uint16 value); + void SetCurrentSequence(uint16 value, bool loadSequence); bool ShouldHideVersionInfo(); void SetHideVersionInfo(bool value); @@ -61,8 +61,9 @@ extern "C" void title_sequence_change_preset(sint32 preset); bool title_should_hide_version_info(); void title_set_hide_version_info(bool value); + uint16 title_get_config_sequence(); uint16 title_get_current_sequence(); - void title_set_current_sequence(uint16 value); + void title_set_current_sequence(uint16 value, bool loadSequence); void DrawOpenRCT2(rct_drawpixelinfo *dpi, sint32 x, sint32 y); #ifdef __cplusplus } diff --git a/src/openrct2/title/TitleSequencePlayer.cpp b/src/openrct2/title/TitleSequencePlayer.cpp index 5ed4896619..95084451fc 100644 --- a/src/openrct2/title/TitleSequencePlayer.cpp +++ b/src/openrct2/title/TitleSequencePlayer.cpp @@ -27,6 +27,7 @@ #include "../ParkImporter.h" #include "../scenario/ScenarioRepository.h" #include "../scenario/ScenarioSources.h" +#include "TitleScreen.h" #include "TitleSequence.h" #include "TitleSequenceManager.h" #include "TitleSequencePlayer.h" @@ -187,12 +188,17 @@ public: Reset(); } + if (_sequence->Commands[targetPosition].Type == TITLE_SCRIPT_RESTART) + { + targetPosition = 0; + } // Set position to the last LOAD command before target position for (sint32 i = targetPosition; i >= 0; i--) { const TitleCommand * command = &_sequence->Commands[i]; - if (TitleSequenceIsLoadCommand(command)) + if ((_position == i && _position != targetPosition) || TitleSequenceIsLoadCommand(command)) { + // Break if we have a new load command or if we're already in the range of the correct load command _position = i; break; } @@ -363,9 +369,18 @@ private: bool success = false; try { - auto parkImporter = std::unique_ptr(ParkImporter::Create(path)); - parkImporter->Load(path); - parkImporter->Import(); + if (gTestingTitleSequenceInGame) + { + gLoadKeepWindowsOpen = true; + CloseParkSpecificWindows(); + context_load_park_from_file(path); + } + else + { + auto parkImporter = std::unique_ptr(ParkImporter::Create(path)); + parkImporter->Load(path); + parkImporter->Import(); + } PrepareParkForPlayback(); success = true; } @@ -373,6 +388,7 @@ private: { Console::Error::WriteLine("Unable to load park: %s", path); } + gLoadKeepWindowsOpen = false; return success; } @@ -386,11 +402,20 @@ private: bool success = false; try { - std::string extension = Path::GetExtension(hintPath); - bool isScenario = ParkImporter::ExtensionIsScenario(hintPath); - auto parkImporter = std::unique_ptr(ParkImporter::Create(hintPath)); - parkImporter->LoadFromStream(stream, isScenario); - parkImporter->Import(); + if (gTestingTitleSequenceInGame) + { + gLoadKeepWindowsOpen = true; + CloseParkSpecificWindows(); + context_load_park_from_stream(stream); + } + else + { + std::string extension = Path::GetExtension(hintPath); + bool isScenario = ParkImporter::ExtensionIsScenario(hintPath); + auto parkImporter = std::unique_ptr(ParkImporter::Create(hintPath)); + parkImporter->LoadFromStream(stream, isScenario); + parkImporter->Import(); + } PrepareParkForPlayback(); success = true; } @@ -398,9 +423,34 @@ private: { Console::Error::WriteLine("Unable to load park: %s", hintPath.c_str()); } + gLoadKeepWindowsOpen = false; return success; } + void CloseParkSpecificWindows() + { + window_close_by_class(WC_CONSTRUCT_RIDE); + window_close_by_class(WC_DEMOLISH_RIDE_PROMPT); + window_close_by_class(WC_EDITOR_INVENTION_LIST_DRAG); + window_close_by_class(WC_EDITOR_INVENTION_LIST); + window_close_by_class(WC_EDITOR_OBJECT_SELECTION); + window_close_by_class(WC_EDTIOR_OBJECTIVE_OPTIONS); + window_close_by_class(WC_EDITOR_SCENARIO_OPTIONS); + window_close_by_class(WC_FINANCES); + window_close_by_class(WC_FIRE_PROMPT); + window_close_by_class(WC_GUEST_LIST); + window_close_by_class(WC_INSTALL_TRACK); + window_close_by_class(WC_PEEP); + window_close_by_class(WC_RIDE); + window_close_by_class(WC_RIDE_CONSTRUCTION); + window_close_by_class(WC_RIDE_LIST); + window_close_by_class(WC_SCENERY); + window_close_by_class(WC_STAFF); + window_close_by_class(WC_TRACK_DELETE_PROMPT); + window_close_by_class(WC_TRACK_DESIGN_LIST); + window_close_by_class(WC_TRACK_DESIGN_PLACE); + } + void PrepareParkForPlayback() { rct_window * w = window_get_main(); @@ -452,7 +502,13 @@ private: if (w != nullptr) { sint32 z = map_element_height(x, y); + + // Prevent scroll adjustment due to window placement when in-game + auto oldScreenFlags = gScreenFlags; + gScreenFlags = SCREEN_FLAGS_TITLE_DEMO; window_set_location(w, x, y, z); + gScreenFlags = oldScreenFlags; + viewport_update_position(w); // Save known tile position in case of window resize @@ -487,6 +543,8 @@ ITitleSequencePlayer * CreateTitleSequencePlayer(IScenarioRepository * scenarioR extern "C" { + bool gTestingTitleSequenceInGame = false; + sint32 title_sequence_player_get_current_position(ITitleSequencePlayer * player) { return player->GetCurrentPosition(); diff --git a/src/openrct2/title/TitleSequencePlayer.h b/src/openrct2/title/TitleSequencePlayer.h index a7b4e95d0d..df4bf0666e 100644 --- a/src/openrct2/title/TitleSequencePlayer.h +++ b/src/openrct2/title/TitleSequencePlayer.h @@ -45,6 +45,9 @@ typedef struct ITitleSequencePlayer ITitleSequencePlayer; extern "C" { #endif + // When testing title sequences within a normal game + extern bool gTestingTitleSequenceInGame; + sint32 title_sequence_player_get_current_position(ITitleSequencePlayer * player); bool title_sequence_player_begin(ITitleSequencePlayer * player, uint32 titleSequenceId); void title_sequence_player_reset(ITitleSequencePlayer * player);