diff --git a/data/tr2/ship/cfg/TR2X_gameflow.json5 b/data/tr2/ship/cfg/TR2X_gameflow.json5 index fec555bad..ead177e7f 100644 --- a/data/tr2/ship/cfg/TR2X_gameflow.json5 +++ b/data/tr2/ship/cfg/TR2X_gameflow.json5 @@ -18,12 +18,13 @@ "single_level": -1, "demo_delay": 30, - "title_track": 64, "secret_track": 47, "level_complete_track": 41, + "game_complete_track": 52, "title": { "path": "data/title.tr2", + "music_track": 64, "sequence": [ {"type": "display_picture", "path": "data/legal.pcx"}, {"type": "play_fmv", "fmv_num": 0}, @@ -35,9 +36,9 @@ // 0. Lara's Home { "path": "data/assault.tr2", + "music_track": -1, "sequence": [ {"type": "set_secret_count", "count": 0}, - {"type": "set_music_track", "music_track": 0}, {"type": "play_level"}, ], }, @@ -45,15 +46,13 @@ // 1. The Great Wall { "path": "data/wall.tr2", + "music_track": 33, "sequence": [ {"type": "play_fmv", "fmv_num": 2}, - {"type": "set_music_track", "music_track": 33}, {"type": "add_secret_reward", "item": "grenade_launcher"}, {"type": "add_secret_reward", "item": "grenade_launcher_ammo", "qty": 2}, {"type": "add_secret_reward", "item": "small_medipack"}, {"type": "play_level"}, - {"type": "set_music_track", "music_track": 3}, - {"type": "set_cutscene_angle", "angle": 0}, {"type": "play_cutscene", "cutscene_num": 0}, {"type": "level_complete"}, ], @@ -65,8 +64,8 @@ // 2. Venice { "path": "data/boat.tr2", + "music_track": -1, "sequence": [ - {"type": "set_music_track", "music_track": 0}, {"type": "add_secret_reward", "item": "magnums_ammo", "qty": 4}, {"type": "play_level"}, {"type": "level_complete"}, @@ -76,8 +75,8 @@ // 3. Bartoli's Hideout { "path": "data/venice.tr2", + "music_track": -1, "sequence": [ - {"type": "set_music_track", "music_track": 0}, {"type": "enable_sunset"}, {"type": "add_secret_reward", "item": "shotgun_ammo", "qty": 4}, {"type": "play_level"}, @@ -88,12 +87,11 @@ // 4. Opera House { "path": "data/opera.tr2", + "music_track": 31, "sequence": [ - {"type": "set_music_track", "music_track": 31}, {"type": "add_secret_reward", "item": "uzis"}, {"type": "add_secret_reward", "item": "uzis_ammo", "qty": 4}, {"type": "play_level"}, - {"type": "set_music_track", "music_track": 4}, {"type": "play_cutscene", "cutscene_num": 1}, {"type": "level_complete"}, ], @@ -106,9 +104,9 @@ // 5. Offshore Rig { "path": "data/rig.tr2", + "music_track": 58, "sequence": [ {"type": "play_fmv", "fmv_num": 3}, - {"type": "set_music_track", "music_track": 58}, {"type": "set_lara_start_anim", "anim": 8}, {"type": "remove_weapons"}, {"type": "add_secret_reward", "item": "uzis"}, @@ -124,11 +122,10 @@ // 6. Diving Area { "path": "data/platform.tr2", + "music_track": 58, "sequence": [ - {"type": "set_music_track", "music_track": 58}, {"type": "add_secret_reward", "item": "uzis_ammo", "qty": 4}, {"type": "play_level"}, - {"type": "set_music_track", "music_track": 5}, {"type": "play_cutscene", "cutscene_num": 2}, {"type": "level_complete"}, ], @@ -140,9 +137,9 @@ // 7. 40 Fathoms { "path": "data/unwater.tr2", + "music_track": 34, "sequence": [ {"type": "play_fmv", "fmv_num": 4}, - {"type": "set_music_track", "music_track": 34}, {"type": "add_secret_reward", "item": "harpoon_gun_ammo", "qty": 4}, {"type": "play_level"}, {"type": "level_complete"}, @@ -152,8 +149,8 @@ // 8. Wreck of the Maria Doria { "path": "data/keel.tr2", + "music_track": 31, "sequence": [ - {"type": "set_music_track", "music_track": 31}, {"type": "add_secret_reward", "item": "grenade_launcher"}, {"type": "add_secret_reward", "item": "grenade_launcher_ammo", "qty": 2}, {"type": "play_level"}, @@ -168,8 +165,8 @@ // 9. Living Quarters { "path": "data/living.tr2", + "music_track": 34, "sequence": [ - {"type": "set_music_track", "music_track": 34}, {"type": "add_secret_reward", "item": "m16_ammo", "qty": 4}, {"type": "play_level"}, {"type": "level_complete"}, @@ -179,8 +176,8 @@ // 10. The Deck { "path": "data/deck.tr2", + "music_track": 31, "sequence": [ - {"type": "set_music_track", "music_track": 31}, {"type": "add_secret_reward", "item": "grenade_launcher_ammo", "qty": 4}, {"type": "play_level"}, {"type": "level_complete"}, @@ -193,9 +190,9 @@ // 11. Tibetan Foothills { "path": "data/skidoo.tr2", + "music_track": 33, "sequence": [ {"type": "play_fmv", "fmv_num": 5}, - {"type": "set_music_track", "music_track": 33}, {"type": "give_item", "item": "puzzle_4"}, {"type": "add_secret_reward", "item": "uzis_ammo", "qty": 4}, {"type": "play_level"}, @@ -210,8 +207,8 @@ // 12. Barkhang Monastery { "path": "data/monastry.tr2", + "music_track": -1, "sequence": [ - {"type": "set_music_track", "music_track": 0}, {"type": "give_item", "item": "puzzle_4"}, {"type": "add_secret_reward", "item": "m16_ammo", "qty": 4}, {"type": "play_level"}, @@ -225,8 +222,8 @@ // 13. Catacombs of the Talion { "path": "data/catacomb.tr2", + "music_track": 31, "sequence": [ - {"type": "set_music_track", "music_track": 31}, {"type": "add_secret_reward", "item": "grenade_launcher_ammo", "qty": 2}, {"type": "add_secret_reward", "item": "m16_ammo", "qty": 2}, {"type": "play_level"}, @@ -241,8 +238,8 @@ // 14. Ice Palace { "path": "data/icecave.tr2", + "music_track": 31, "sequence": [ - {"type": "set_music_track", "music_track": 31}, {"type": "add_secret_reward", "item": "grenade_launcher_ammo", "qty": 4}, {"type": "play_level"}, {"type": "level_complete"}, @@ -256,13 +253,11 @@ // 15. Temple of Xian { "path": "data/emprtomb.tr2", + "music_track": 59, "sequence": [ {"type": "play_fmv", "fmv_num": 6}, - {"type": "set_music_track", "music_track": 59}, {"type": "add_secret_reward", "item": "uzis_ammo", "qty": 8}, {"type": "play_level"}, - {"type": "set_music_track", "music_track": 30}, - {"type": "set_cutscene_angle", "angle": 0}, {"type": "play_cutscene", "cutscene_num": 3}, {"type": "level_complete"}, ], @@ -275,8 +270,8 @@ // 16. Floating Islands { "path": "data/floating.tr2", + "music_track": 59, "sequence": [ - {"type": "set_music_track", "music_track": 59}, {"type": "disable_floor", "height": 9728}, {"type": "add_secret_reward", "item": "grenade_launcher_ammo", "qty": 8}, {"type": "play_level"}, @@ -291,9 +286,9 @@ // 17. The Dragon's Lair { "path": "data/xian.tr2", + "music_track": 59, "sequence": [ {"type": "set_secret_count", "count": 0}, - {"type": "set_music_track", "music_track": 59}, {"type": "play_level"}, {"type": "level_complete"}, {"type": "play_fmv", "fmv_num": 7}, @@ -303,15 +298,14 @@ // 18. Home Sweet Home { "path": "data/house.tr2", + "music_track": -1, "sequence": [ {"type": "set_secret_count", "count": 0}, {"type": "give_item", "item": "key_1"}, {"type": "set_lara_start_anim", "anim": 9}, - {"type": "set_music_track", "music_track": 0}, {"type": "remove_weapons"}, {"type": "remove_ammo"}, {"type": "play_level"}, - {"type": "set_music_track", "music_track": 52}, {"type": "game_complete"}, ], "injections": [ @@ -324,10 +318,10 @@ // 0. Venice { "path": "data/boat.tr2", + "music_track": -1, "sequence": [ - {"type": "set_music_track", "music_track": 0}, {"type": "add_secret_reward", "item": "magnums_ammo", "qty": 4}, - {"type": "play_level", "level_num": 2}, + {"type": "play_level"}, {"type": "level_complete"}, ], }, @@ -335,11 +329,11 @@ // 1. Wreck of the Maria Doria { "path": "data/keel.tr2", + "music_track": 31, "sequence": [ - {"type": "set_music_track", "music_track": 31}, {"type": "add_secret_reward", "item": "grenade_launcher"}, {"type": "add_secret_reward", "item": "grenade_launcher_ammo", "qty": 2}, - {"type": "play_level", "level_num": 8}, + {"type": "play_level"}, {"type": "level_complete"}, ], "injections": [ @@ -351,11 +345,11 @@ // 2. Tibetan Foothills { "path": "data/skidoo.tr2", + "music_track": 33, "sequence": [ - {"type": "set_music_track", "music_track": 33}, {"type": "give_item", "item": "puzzle_4"}, {"type": "add_secret_reward", "item": "uzis_ammo", "qty": 4}, - {"type": "play_level", "level_num": 11}, + {"type": "play_level"}, {"type": "level_complete"}, ], "injections": [ @@ -366,10 +360,32 @@ ], "cutscenes": [ - {"path": "data/cut1.tr2"}, - {"path": "data/cut2.tr2"}, - {"path": "data/cut3.tr2"}, - {"path": "data/cut4.tr2"}, + { + "path": "data/cut1.tr2", + "music_track": 3, + "sequence": [ + {"type": "set_cutscene_angle", "angle": 0}, + {"type": "play_level"}, + ], + }, + { + "path": "data/cut2.tr2", + "music_track": 4, + "sequence": [{"type": "play_level"}], + }, + { + "path": "data/cut3.tr2", + "music_track": 5, + "sequence": [{"type": "play_level"}], + }, + { + "path": "data/cut4.tr2", + "music_track": 30, + "sequence": [ + {"type": "set_cutscene_angle", "angle": 0}, + {"type": "play_level"}, + ], + }, ], "fmvs": [ diff --git a/src/libtrx/game/game_flow/sequencer.c b/src/libtrx/game/game_flow/sequencer.c index 6880cfd56..8c79ab187 100644 --- a/src/libtrx/game/game_flow/sequencer.c +++ b/src/libtrx/game/game_flow/sequencer.c @@ -38,3 +38,28 @@ GAME_FLOW_COMMAND GF_ShowInventoryKeys(const GAME_OBJECT_ID receptacle_type_id) } return GF_ShowInventory(INV_KEYS_MODE); } + +GAME_FLOW_COMMAND GF_RunDemo(const int32_t demo_num) +{ + PHASE *const demo_phase = Phase_Demo_Create(demo_num); + const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(demo_phase); + Phase_Demo_Destroy(demo_phase); + return gf_cmd; +} + +GAME_FLOW_COMMAND GF_RunCutscene(const int32_t cutscene_num) +{ + PHASE *const cutscene_phase = Phase_Cutscene_Create(cutscene_num); + const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(cutscene_phase); + Phase_Cutscene_Destroy(cutscene_phase); + return gf_cmd; +} + +GAME_FLOW_COMMAND GF_RunGame( + const int32_t level_num, const GAME_FLOW_LEVEL_TYPE level_type) +{ + PHASE *const phase = Phase_Game_Create(level_num, level_type); + const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(phase); + Phase_Game_Destroy(phase); + return gf_cmd; +} diff --git a/src/libtrx/include/libtrx/game/game_flow/sequencer.h b/src/libtrx/include/libtrx/game/game_flow/sequencer.h index 107db99e0..e97ebee84 100644 --- a/src/libtrx/include/libtrx/game/game_flow/sequencer.h +++ b/src/libtrx/include/libtrx/game/game_flow/sequencer.h @@ -7,3 +7,7 @@ GAME_FLOW_COMMAND GF_EnterPhotoMode(void); GAME_FLOW_COMMAND GF_PauseGame(void); GAME_FLOW_COMMAND GF_ShowInventory(INVENTORY_MODE inv_mode); GAME_FLOW_COMMAND GF_ShowInventoryKeys(GAME_OBJECT_ID receptacle_type_id); +GAME_FLOW_COMMAND GF_RunDemo(int32_t demo_num); +GAME_FLOW_COMMAND GF_RunCutscene(int32_t cutscene_num); +GAME_FLOW_COMMAND GF_RunGame( + int32_t level_num, GAME_FLOW_LEVEL_TYPE level_type); diff --git a/src/tr1/game/game_flow/sequencer.c b/src/tr1/game/game_flow/sequencer.c index 9d3654b41..c7f3a030e 100644 --- a/src/tr1/game/game_flow/sequencer.c +++ b/src/tr1/game/game_flow/sequencer.c @@ -80,23 +80,20 @@ GF_InterpretSequence(int32_t level_num, GAME_FLOW_LEVEL_TYPE level_type) case GFS_PLAY_LEVEL: if (g_GameFlow.levels[level_num].level_type == GFL_CUTSCENE) { if (level_type != GFL_SAVED) { - command = GF_PlayCutscene((int32_t)(intptr_t)event->data); + command = GF_RunCutscene((int32_t)(intptr_t)event->data); if (command.action != GF_NOOP && command.action != GF_LEVEL_COMPLETE) { return command; } } } else if (level_type == GFL_DEMO) { - PHASE *const phase = Phase_Demo_Create(level_num); - const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(phase); - Phase_Demo_Destroy(phase); - return gf_cmd; + return GF_RunDemo(level_num); } else { if (level_type != GFL_SAVED && level_num != g_GameFlow.first_level_num) { Lara_RevertToPistolsIfNeeded(); } - command = GF_PlayLevel(level_num, level_type); + command = GF_RunGame(level_num, level_type); if (command.action != GF_NOOP && command.action != GF_LEVEL_COMPLETE) { return command; @@ -309,7 +306,7 @@ GF_StorySoFar(const GAME_FLOW_SEQUENCE *const sequence, int32_t savegame_level) case GFS_PLAY_LEVEL: { const int32_t level_num = (int32_t)(intptr_t)event->data; if (g_GameFlow.levels[level_num].level_type == GFL_CUTSCENE) { - command = GF_PlayCutscene((int32_t)(intptr_t)event->data); + command = GF_RunCutscene((int32_t)(intptr_t)event->data); if (command.action != GF_NOOP && command.action != GF_LEVEL_COMPLETE) { return command; @@ -395,31 +392,6 @@ GAME_FLOW_COMMAND GF_LoadLevel( return (GAME_FLOW_COMMAND) { .action = GF_NOOP }; } -GAME_FLOW_COMMAND GF_PlayLevel( - const int32_t level_num, const GAME_FLOW_LEVEL_TYPE level_type) -{ - PHASE *const phase = Phase_Game_Create(level_num, level_type); - const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(phase); - Phase_Game_Destroy(phase); - return gf_cmd; -} - -GAME_FLOW_COMMAND GF_PlayDemo(const int32_t level_num) -{ - PHASE *const phase = Phase_Demo_Create(level_num); - const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(phase); - Phase_Demo_Destroy(phase); - return gf_cmd; -} - -GAME_FLOW_COMMAND GF_PlayCutscene(const int32_t level_num) -{ - PHASE *const phase = Phase_Cutscene_Create(level_num); - const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(phase); - Phase_Cutscene_Destroy(phase); - return gf_cmd; -} - GAME_FLOW_COMMAND GF_DoDemoSequence(int32_t demo_num) { const int32_t level_num = Demo_ChooseLevel(demo_num); diff --git a/src/tr1/game/game_flow/sequencer.h b/src/tr1/game/game_flow/sequencer.h index 6f2731d0c..91af575c6 100644 --- a/src/tr1/game/game_flow/sequencer.h +++ b/src/tr1/game/game_flow/sequencer.h @@ -7,6 +7,7 @@ GAME_FLOW_COMMAND GF_InterpretSequence(int32_t level_num, GAME_FLOW_LEVEL_TYPE level_type); GAME_FLOW_COMMAND GF_DoDemoSequence(int32_t demo_num); +GAME_FLOW_COMMAND GF_DoCutsceneSequence(int32_t demo_num); GAME_FLOW_COMMAND GF_StorySoFar(const GAME_FLOW_SEQUENCE *sequence, int32_t savegame_level); GAME_FLOW_COMMAND GF_PlayAvailableStory(int32_t slot_num); @@ -16,4 +17,3 @@ GAME_FLOW_COMMAND GF_LoadLevel( GAME_FLOW_COMMAND GF_PlayLevel( int32_t demo_num, GAME_FLOW_LEVEL_TYPE level_type); GAME_FLOW_COMMAND GF_PlayDemo(int32_t demo_num); -GAME_FLOW_COMMAND GF_PlayCutscene(int32_t level_num); diff --git a/src/tr2/decomp/decomp.c b/src/tr2/decomp/decomp.c index 24841c155..bdd13ae24 100644 --- a/src/tr2/decomp/decomp.c +++ b/src/tr2/decomp/decomp.c @@ -1,51 +1,22 @@ #include "decomp/decomp.h" -#include "decomp/savegame.h" -#include "decomp/stats.h" -#include "game/camera.h" -#include "game/clock.h" #include "game/collide.h" -#include "game/console/common.h" -#include "game/effects.h" -#include "game/game.h" #include "game/game_flow.h" -#include "game/input.h" -#include "game/inventory.h" #include "game/items.h" #include "game/lara/control.h" #include "game/lara/draw.h" #include "game/level.h" -#include "game/lot.h" -#include "game/music.h" #include "game/objects/vars.h" #include "game/output.h" -#include "game/overlay.h" #include "game/phase.h" -#include "game/random.h" #include "game/requester.h" #include "game/room.h" -#include "game/shell.h" -#include "game/sound.h" -#include "game/text.h" #include "game/viewport.h" -#include "global/const.h" #include "global/vars.h" #include -#include -#include -#include -#include #include -#include -#include -#include -#include #include -#include - -#include -#include // TODO: delegate these constants to individual vehicle code #define VEHICLE_MIN_BOUNCE 50 @@ -68,18 +39,9 @@ GAME_FLOW_COMMAND TitleSequence(void) return (GAME_FLOW_COMMAND) { .action = GF_EXIT_GAME }; } - if (g_GameFlow.title_track != MX_INACTIVE) { - Music_Play(g_GameFlow.title_track, MPM_LOOPED); - } - return GF_ShowInventory(INV_TITLE_MODE); } -void Game_SetCutsceneTrack(const int32_t track) -{ - g_CineTrackID = track; -} - void CutscenePlayer_Control(const int16_t item_num) { ITEM *const item = &g_Items[item_num]; @@ -158,75 +120,6 @@ void CutscenePlayerGen_Initialise(const int16_t item_num) item->dynamic_light = 0; } -int32_t Level_Initialise( - const int32_t level_num, const GAME_FLOW_LEVEL_TYPE level_type) -{ - g_GameInfo.current_level.num = level_num; - g_GameInfo.current_level.type = level_type; - - if (level_type != GFL_TITLE && level_type != GFL_DEMO) { - g_GymInvOpenEnabled = false; - } - - if (level_type != GFL_TITLE && level_type != GFL_CUTSCENE) { - g_CurrentLevel = level_num; - } - InitialiseGameFlags(); - g_Lara.item_num = NO_ITEM; - - bool result; - if (level_type == GFL_TITLE) { - result = S_LoadLevelFile(GF_GetTitleLevelPath(), level_num, level_type); - } else if (level_type == GFL_CUTSCENE) { - if (level_num < 0 || level_num >= GF_GetCutsceneCount()) { - LOG_ERROR("Invalid cutscene number: %d", level_num); - return false; - } - result = S_LoadLevelFile( - GF_GetCutscenePath(level_num), level_num, level_type); - } else { - result = - S_LoadLevelFile(GF_GetLevelPath(level_num), level_num, level_type); - } - if (!result) { - return result; - } - - if (g_Lara.item_num != NO_ITEM) { - Lara_Initialise(level_type); - } - if (level_type == GFL_NORMAL || level_type == GFL_SAVED - || level_type == GFL_DEMO) { - GetCarriedItems(); - } - - Effect_InitialiseArray(); - LOT_InitialiseArray(); - Overlay_Reset(); - g_HealthBarTimer = 100; - Sound_StopAll(); - if (level_type == GFL_SAVED) { - ExtractSaveGameInfo(); - } else if (level_type == GFL_NORMAL) { - GF_InventoryModifier_Apply(g_CurrentLevel, GF_INV_REGULAR); - } - - if (g_Objects[O_FINAL_LEVEL_COUNTER].loaded) { - InitialiseFinalLevel(); - } - - if (level_type == GFL_NORMAL || level_type == GFL_SAVED - || level_type == GFL_DEMO) { - if (g_GF_MusicTracks[0]) { - Music_Play(g_GF_MusicTracks[0], MPM_LOOPED); - } - } - g_IsAssaultTimerActive = false; - g_IsAssaultTimerDisplay = false; - g_Camera.underwater = 0; - return true; -} - int32_t Misc_Move3DPosTo3DPos( PHD_3DPOS *const src_pos, const PHD_3DPOS *const dst_pos, const int32_t velocity, const int16_t ang_add) @@ -282,14 +175,14 @@ GAME_FLOW_COMMAND LevelCompleteSequence(void) GAME_FLOW_COMMAND DisplayCredits(void) { - S_UnloadLevelFile(); + Level_Unload(); if (!Level_Initialise(0, GFL_TITLE)) { return (GAME_FLOW_COMMAND) { .action = GF_EXIT_TO_TITLE }; } g_GymInvOpenEnabled = true; - Music_Play(MX_SKIDOO_THEME, MPM_ALWAYS); + Music_Play(g_GameFlow.game_complete_track, MPM_ALWAYS); for (int32_t i = 0; i < 8; i++) { char file_name[60]; @@ -346,22 +239,6 @@ void DecreaseScreenSize(void) } } -bool S_LoadLevelFile( - const char *const file_name, const int32_t level_num, - const GAME_FLOW_LEVEL_TYPE level_type) -{ - S_UnloadLevelFile(); - return Level_Load(file_name, level_num); -} - -void S_UnloadLevelFile(void) -{ - strcpy(g_LevelFileName, ""); - memset(g_TexturePageBuffer8, 0, sizeof(uint8_t *) * MAX_TEXTURE_PAGES); - memset(g_TexturePageBuffer16, 0, sizeof(uint16_t *) * MAX_TEXTURE_PAGES); - g_ObjectTextureCount = 0; -} - void GetValidLevelsList(REQUEST_INFO *const req) { Requester_RemoveAllItems(req); diff --git a/src/tr2/decomp/decomp.h b/src/tr2/decomp/decomp.h index efccc1cbb..8d8c94180 100644 --- a/src/tr2/decomp/decomp.h +++ b/src/tr2/decomp/decomp.h @@ -15,7 +15,6 @@ void CutscenePlayer_Control(int16_t item_num); void Lara_Control_Cutscene(int16_t item_num); void CutscenePlayer1_Initialise(int16_t item_num); void CutscenePlayerGen_Initialise(int16_t item_num); -int32_t Level_Initialise(int32_t level_num, GAME_FLOW_LEVEL_TYPE level_type); int32_t Misc_Move3DPosTo3DPos( PHD_3DPOS *src_pos, const PHD_3DPOS *dst_pos, int32_t velocity, int16_t ang_add); @@ -24,8 +23,6 @@ GAME_FLOW_COMMAND DisplayCredits(void); void S_InitialisePolyList(bool clear_back_buffer); void DecreaseScreenSize(void); void IncreaseScreenSize(void); -bool S_LoadLevelFile( - const char *file_name, int32_t level_num, GAME_FLOW_LEVEL_TYPE level_type); void S_UnloadLevelFile(void); void GetValidLevelsList(REQUEST_INFO *req); void InitialiseGameFlags(void); diff --git a/src/tr2/game/cutscene.c b/src/tr2/game/cutscene.c index d30e02d79..aa9741a90 100644 --- a/src/tr2/game/cutscene.c +++ b/src/tr2/game/cutscene.c @@ -6,6 +6,7 @@ #include "game/game_flow.h" #include "game/items.h" #include "game/lara/hair.h" +#include "game/level.h" #include "game/music.h" #include "game/output.h" #include "game/room.h" @@ -41,10 +42,6 @@ bool Cutscene_Start(const int32_t level_num) CutscenePlayer1_Initialise(g_Lara.item_num); g_Camera.target_angle = g_CineTargetAngle; - if (!Music_PlaySynced(g_CineTrackID)) { - return false; - } - Music_SetVolume(10); g_CineFrameIdx = 0; return true; diff --git a/src/tr2/game/demo.c b/src/tr2/game/demo.c index c71c3f140..2a27a7366 100644 --- a/src/tr2/game/demo.c +++ b/src/tr2/game/demo.c @@ -1,6 +1,5 @@ #include "game/demo.h" -#include "decomp/decomp.h" #include "game/camera.h" #include "game/game.h" #include "game/game_flow.h" @@ -8,6 +7,7 @@ #include "game/input.h" #include "game/items.h" #include "game/lara/cheat.h" +#include "game/level.h" #include "game/music.h" #include "game/overlay.h" #include "game/random.h" diff --git a/src/tr2/game/game.c b/src/tr2/game/game.c index 854932866..6e3b8147b 100644 --- a/src/tr2/game/game.c +++ b/src/tr2/game/game.c @@ -11,6 +11,7 @@ #include "game/lara/cheat_keys.h" #include "game/lara/control.h" #include "game/lara/hair.h" +#include "game/level.h" #include "game/music.h" #include "game/output.h" #include "game/overlay.h" diff --git a/src/tr2/game/game_flow/enum.h b/src/tr2/game/game_flow/enum.h index 226e8addf..61b95936d 100644 --- a/src/tr2/game/game_flow/enum.h +++ b/src/tr2/game/game_flow/enum.h @@ -7,7 +7,6 @@ typedef enum { GFS_PLAY_CUTSCENE, GFS_LEVEL_COMPLETE, GFS_GAME_COMPLETE, - GFS_SET_MUSIC_TRACK, GFS_SET_CAMERA_ANGLE, GFS_SET_START_ANIM, GFS_SET_NUM_SECRETS, diff --git a/src/tr2/game/game_flow/reader.c b/src/tr2/game/game_flow/reader.c index 3f92e30db..687e75a0a 100644 --- a/src/tr2/game/game_flow/reader.c +++ b/src/tr2/game/game_flow/reader.c @@ -55,19 +55,14 @@ static void M_LoadLevel( static void M_LoadLevelInjections( JSON_OBJECT *obj, const GAME_FLOW *gf, GAME_FLOW_LEVEL *level); static bool M_LoadLevels(JSON_OBJECT *obj, GAME_FLOW *gf); +static bool M_LoadCutscenes(JSON_OBJECT *obj, GAME_FLOW *gf); +static bool M_LoadDemos(JSON_OBJECT *obj, GAME_FLOW *gf); +static void M_LoadTitleLevel(JSON_OBJECT *obj, GAME_FLOW *gf); static void M_LoadFMV( JSON_OBJECT *obj, const GAME_FLOW *gf, GAME_FLOW_FMV *level); static bool M_LoadFMVs(JSON_OBJECT *obj, GAME_FLOW *gf); -static void M_LoadCutscene( - JSON_OBJECT *obj, const GAME_FLOW *gf, GAME_FLOW_CUTSCENE *level); -static bool M_LoadCutscenes(JSON_OBJECT *obj, GAME_FLOW *gf); - -static bool M_LoadDemos(JSON_OBJECT *obj, GAME_FLOW *gf); - -static void M_LoadTitleLevel(JSON_OBJECT *obj, GAME_FLOW *gf); - static M_SEQUENCE_EVENT_HANDLER m_SequenceEventHandlers[] = { // clang-format off // Events without arguments @@ -78,7 +73,6 @@ static M_SEQUENCE_EVENT_HANDLER m_SequenceEventHandlers[] = { { GFS_GAME_COMPLETE, NULL, NULL }, // Events with integer arguments - { GFS_SET_MUSIC_TRACK, M_HandleIntEvent, "music_track" }, { GFS_SET_NUM_SECRETS, M_HandleIntEvent, "count" }, { GFS_SET_CAMERA_ANGLE, M_HandleIntEvent, "anim" }, { GFS_SET_START_ANIM, M_HandleIntEvent, "anim" }, @@ -283,10 +277,11 @@ static bool M_LoadGlobal(JSON_OBJECT *const obj, GAME_FLOW *const gf) gf->single_level = JSON_ObjectGetInt(obj, "single_level", -1); // clang-format on - gf->title_track = JSON_ObjectGetInt(obj, "title_track", MX_INACTIVE); gf->secret_track = JSON_ObjectGetInt(obj, "secret_track", MX_INACTIVE); gf->level_complete_track = JSON_ObjectGetInt(obj, "level_complete_track", MX_INACTIVE); + gf->game_complete_track = + JSON_ObjectGetInt(obj, "game_complete_track", MX_INACTIVE); M_LoadGlobalInjections(obj, gf); return true; @@ -365,8 +360,9 @@ static void M_LoadLevel( } level->path = Memory_DupStr(path); - M_LoadLevelSequence(obj, level); + level->music_track = JSON_ObjectGetInt(obj, "music_track", MX_INACTIVE); + M_LoadLevelSequence(obj, level); M_LoadLevelInjections(obj, gf, level); } @@ -418,9 +414,11 @@ static bool M_LoadLevels(JSON_OBJECT *const obj, GAME_FLOW *const gf) gf, &gf->level_count, (void **)&gf->levels); for (int32_t i = 0; i < gf->level_count; i++) { - const GAME_FLOW_SEQUENCE *const sequence = &gf->levels[i].sequence; - for (int32_t j = 0; j < sequence->length; j++) { - GAME_FLOW_SEQUENCE_EVENT *const event = &sequence->events[j]; + GAME_FLOW_LEVEL *const level = &gf->levels[i]; + level->num = i; + level->type = GFL_NORMAL; + for (int32_t j = 0; j < level->sequence.length; j++) { + GAME_FLOW_SEQUENCE_EVENT *const event = &level->sequence.events[j]; if (event->type == GFS_PLAY_LEVEL && (int32_t)(intptr_t)event->data == -1) { event->data = (void *)(intptr_t)i; @@ -430,47 +428,45 @@ static bool M_LoadLevels(JSON_OBJECT *const obj, GAME_FLOW *const gf) return result; } -static void M_LoadFMV( - JSON_OBJECT *const obj, const GAME_FLOW *const gf, GAME_FLOW_FMV *const fmv) -{ - const char *const path = JSON_ObjectGetString(obj, "path", NULL); - if (path == NULL) { - Shell_ExitSystemFmt("Missing FMV path"); - } - fmv->path = Memory_DupStr(path); -} - -static bool M_LoadFMVs(JSON_OBJECT *const obj, GAME_FLOW *const gf) -{ - return M_LoadArray( - obj, "fmvs", sizeof(GAME_FLOW_FMV), (M_LOAD_ARRAY_FUNC)M_LoadFMV, gf, - &gf->fmv_count, (void **)&gf->fmvs); -} - -static void M_LoadCutscene( - JSON_OBJECT *const obj, const GAME_FLOW *const gf, - GAME_FLOW_CUTSCENE *const cutscene) -{ - const char *const path = JSON_ObjectGetString(obj, "path", NULL); - if (path == NULL) { - Shell_ExitSystemFmt("Missing cutscene path"); - } - cutscene->path = Memory_DupStr(path); -} - static bool M_LoadCutscenes(JSON_OBJECT *obj, GAME_FLOW *const gf) { - return M_LoadArray( - obj, "cutscenes", sizeof(GAME_FLOW_CUTSCENE), - (M_LOAD_ARRAY_FUNC)M_LoadCutscene, gf, &gf->cutscene_count, + const bool result = M_LoadArray( + obj, "cutscenes", sizeof(GAME_FLOW_LEVEL), + (M_LOAD_ARRAY_FUNC)M_LoadLevel, gf, &gf->cutscene_count, (void **)&gf->cutscenes); + for (int32_t i = 0; i < gf->cutscene_count; i++) { + GAME_FLOW_LEVEL *const level = &gf->cutscenes[i]; + level->num = i; + level->type = GFL_CUTSCENE; + for (int32_t j = 0; j < level->sequence.length; j++) { + GAME_FLOW_SEQUENCE_EVENT *const event = &level->sequence.events[j]; + if (event->type == GFS_PLAY_LEVEL + && (int32_t)(intptr_t)event->data == -1) { + event->data = (void *)(intptr_t)i; + } + } + } + return result; } static bool M_LoadDemos(JSON_OBJECT *obj, GAME_FLOW *const gf) { - return M_LoadArray( + const bool result = M_LoadArray( obj, "demos", sizeof(GAME_FLOW_LEVEL), (M_LOAD_ARRAY_FUNC)M_LoadLevel, gf, &gf->demo_count, (void **)&gf->demos); + for (int32_t i = 0; i < gf->demo_count; i++) { + GAME_FLOW_LEVEL *const level = &gf->demos[i]; + level->num = i; + level->type = GFL_DEMO; + for (int32_t j = 0; j < level->sequence.length; j++) { + GAME_FLOW_SEQUENCE_EVENT *const event = &level->sequence.events[j]; + if (event->type == GFS_PLAY_LEVEL + && (int32_t)(intptr_t)event->data == -1) { + event->data = (void *)(intptr_t)i; + } + } + } + return result; } static void M_LoadTitleLevel(JSON_OBJECT *obj, GAME_FLOW *const gf) @@ -479,9 +475,28 @@ static void M_LoadTitleLevel(JSON_OBJECT *obj, GAME_FLOW *const gf) if (title_obj != NULL) { gf->title_level = Memory_Alloc(sizeof(GAME_FLOW_LEVEL)); M_LoadLevel(title_obj, gf, gf->title_level); + gf->title_level->num = 0; + gf->title_level->type = GFL_TITLE; } } +static void M_LoadFMV( + JSON_OBJECT *const obj, const GAME_FLOW *const gf, GAME_FLOW_FMV *const fmv) +{ + const char *const path = JSON_ObjectGetString(obj, "path", NULL); + if (path == NULL) { + Shell_ExitSystemFmt("Missing FMV path"); + } + fmv->path = Memory_DupStr(path); +} + +static bool M_LoadFMVs(JSON_OBJECT *const obj, GAME_FLOW *const gf) +{ + return M_LoadArray( + obj, "fmvs", sizeof(GAME_FLOW_FMV), (M_LOAD_ARRAY_FUNC)M_LoadFMV, gf, + &gf->fmv_count, (void **)&gf->fmvs); +} + bool GF_Load(const char *const path) { GF_Shutdown(); diff --git a/src/tr2/game/game_flow/sequencer.c b/src/tr2/game/game_flow/sequencer.c index 953e592ad..dc94e1050 100644 --- a/src/tr2/game/game_flow/sequencer.c +++ b/src/tr2/game/game_flow/sequencer.c @@ -22,20 +22,10 @@ GAME_FLOW_COMMAND GF_DoDemoSequence(int32_t demo_num) return GF_InterpretSequence(&g_GameFlow.demos[demo_num].sequence, GFL_DEMO); } -GAME_FLOW_COMMAND GF_StartGame( - const int32_t level_num, const GAME_FLOW_LEVEL_TYPE level_type) +GAME_FLOW_COMMAND GF_DoCutsceneSequence(const int32_t cutscene_num) { - if (level_type == GFL_DEMO) { - PHASE *const demo_phase = Phase_Demo_Create(level_num); - const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(demo_phase); - Phase_Demo_Destroy(demo_phase); - return gf_cmd; - } else { - PHASE *const phase = Phase_Game_Create(level_num, level_type); - const GAME_FLOW_COMMAND gf_cmd = PhaseExecutor_Run(phase); - Phase_Game_Destroy(phase); - return gf_cmd; - } + return GF_InterpretSequence( + &g_GameFlow.cutscenes[cutscene_num].sequence, GFL_CUTSCENE); } bool GF_DoFrontendSequence(void) @@ -49,6 +39,43 @@ bool GF_DoFrontendSequence(void) return gf_cmd.action == GF_EXIT_GAME; } +GAME_FLOW_COMMAND GF_DoLevelSequence( + const int32_t start_level, const GAME_FLOW_LEVEL_TYPE type) +{ + GameStringTable_Apply(start_level); + int32_t current_level = start_level; + while (true) { + if (current_level > GF_GetLevelCount() - 1) { + return (GAME_FLOW_COMMAND) { .action = GF_EXIT_TO_TITLE }; + } + + LOG_DEBUG("running sequence for level=%d type=%d", current_level, type); + const GAME_FLOW_COMMAND gf_cmd = GF_InterpretSequence( + &g_GameFlow.levels[current_level].sequence, type); + LOG_DEBUG("sequence finished"); + current_level++; + + if (g_GameFlow.single_level >= 0) { + return gf_cmd; + } + if (gf_cmd.action != GF_LEVEL_COMPLETE) { + return gf_cmd; + } + } +} + +GAME_FLOW_COMMAND GF_RunLevel( + const int32_t level_num, const GAME_FLOW_LEVEL_TYPE level_type) +{ + if (level_type == GFL_DEMO) { + return GF_RunDemo(level_num); + } else if (level_type == GFL_CUTSCENE) { + return GF_RunCutscene(level_num); + } else { + return GF_RunGame(level_num, level_type); + } +} + GAME_FLOW_COMMAND GF_InterpretSequence( const GAME_FLOW_SEQUENCE *sequence, GAME_FLOW_LEVEL_TYPE type) { @@ -60,7 +87,6 @@ GAME_FLOW_COMMAND GF_InterpretSequence( GF_InventoryModifier_Reset(); - g_GF_MusicTracks[0] = 2; g_CineTargetAngle = DEG_90; g_GF_NumSecrets = 3; @@ -92,14 +118,11 @@ GAME_FLOW_COMMAND GF_InterpretSequence( case GFS_PLAY_LEVEL: { const int16_t level_num = (int16_t)(intptr_t)event->data; - if (level_num < 0 || level_num > GF_GetLevelCount()) { - LOG_ERROR("Invalid level number: %d", level_num); - gf_cmd = (GAME_FLOW_COMMAND) { .action = GF_EXIT_TO_TITLE }; - } else if (type != GFL_STORY) { + if (type != GFL_STORY) { if (type == GFL_MID_STORY) { return (GAME_FLOW_COMMAND) { .action = GF_EXIT_TO_TITLE }; } - gf_cmd = GF_StartGame(level_num, type); + gf_cmd = GF_RunLevel(level_num, type); if (type == GFL_SAVED) { type = GFL_NORMAL; } @@ -113,13 +136,7 @@ GAME_FLOW_COMMAND GF_InterpretSequence( case GFS_PLAY_CUTSCENE: { const int16_t cutscene_num = (int16_t)(intptr_t)event->data; if (type != GFL_SAVED) { - if (cutscene_num < 0 || cutscene_num >= GF_GetCutsceneCount()) { - LOG_ERROR("Invalid cutscene number: %d", cutscene_num); - } - PHASE *const cutscene_phase = - Phase_Cutscene_Create(cutscene_num); - gf_cmd = PhaseExecutor_Run(cutscene_phase); - Phase_Cutscene_Destroy(cutscene_phase); + gf_cmd = GF_DoCutsceneSequence(cutscene_num); if (gf_cmd.action != GF_NOOP && gf_cmd.action != GF_LEVEL_COMPLETE) { return gf_cmd; @@ -175,14 +192,6 @@ GAME_FLOW_COMMAND GF_InterpretSequence( } break; - case GFS_SET_MUSIC_TRACK: { - const int16_t music_track_id = (int16_t)(intptr_t)event->data; - g_GF_MusicTracks[ntracks] = music_track_id; - Game_SetCutsceneTrack(music_track_id); - ntracks++; - break; - } - case GFS_ENABLE_SUNSET: if (type != GFL_STORY && type != GFL_MID_STORY) { g_GF_SunsetEnabled = true; @@ -251,28 +260,3 @@ GAME_FLOW_COMMAND GF_InterpretSequence( } return gf_cmd; } - -GAME_FLOW_COMMAND GF_DoLevelSequence( - const int32_t start_level, const GAME_FLOW_LEVEL_TYPE type) -{ - GameStringTable_Apply(start_level); - int32_t current_level = start_level; - while (true) { - if (current_level > GF_GetLevelCount() - 1) { - return (GAME_FLOW_COMMAND) { .action = GF_EXIT_TO_TITLE }; - } - - LOG_DEBUG("running sequence for level=%d type=%d", current_level, type); - const GAME_FLOW_COMMAND gf_cmd = GF_InterpretSequence( - &g_GameFlow.levels[current_level].sequence, type); - LOG_DEBUG("sequence finished"); - current_level++; - - if (g_GameFlow.single_level >= 0) { - return gf_cmd; - } - if (gf_cmd.action != GF_LEVEL_COMPLETE) { - return gf_cmd; - } - } -} diff --git a/src/tr2/game/game_flow/types.h b/src/tr2/game/game_flow/types.h index c9c48da84..76668d340 100644 --- a/src/tr2/game/game_flow/types.h +++ b/src/tr2/game/game_flow/types.h @@ -49,13 +49,12 @@ typedef struct { const char *path; } GAME_FLOW_FMV; -typedef struct { - const char *path; -} GAME_FLOW_CUTSCENE; - typedef struct { const char *path; char *title; + GAME_FLOW_LEVEL_TYPE type; + int32_t num; + MUSIC_TRACK_ID music_track; GAME_FLOW_SEQUENCE sequence; INJECTION_DATA injections; } GAME_FLOW_LEVEL; @@ -72,7 +71,7 @@ typedef struct { // cutscenes struct { int32_t cutscene_count; - GAME_FLOW_CUTSCENE *cutscenes; + GAME_FLOW_LEVEL *cutscenes; }; // demos @@ -111,9 +110,9 @@ typedef struct { // music struct { - MUSIC_TRACK_ID title_track; MUSIC_TRACK_ID secret_track; MUSIC_TRACK_ID level_complete_track; + MUSIC_TRACK_ID game_complete_track; }; // other data diff --git a/src/tr2/game/level.c b/src/tr2/game/level.c index 0464417f0..f74e04afd 100644 --- a/src/tr2/game/level.c +++ b/src/tr2/game/level.c @@ -1,13 +1,17 @@ #include "game/level.h" #include "decomp/decomp.h" +#include "decomp/savegame.h" #include "game/camera.h" #include "game/effects.h" #include "game/game_flow.h" #include "game/inject.h" #include "game/items.h" +#include "game/lara/control.h" +#include "game/lot.h" #include "game/objects/setup.h" #include "game/output.h" +#include "game/overlay.h" #include "game/render/common.h" #include "game/room.h" #include "game/shell.h" @@ -23,11 +27,14 @@ #include #include #include +#include static int16_t *m_AnimFrameData = NULL; static int32_t m_AnimFrameDataLength = 0; -static void M_LoadFromFile(const char *file_name, int32_t level_num); +static GAME_FLOW_LEVEL *M_GetFromNumberAndType( + int32_t level_num, GAME_FLOW_LEVEL_TYPE level_type); +static void M_LoadFromFile(const GAME_FLOW_LEVEL *level); static void M_LoadRooms(VFILE *file); static void M_LoadObjectMeshes(VFILE *file); static void M_LoadAnims(VFILE *file); @@ -50,6 +57,41 @@ static void M_LoadDemo(VFILE *file); static void M_LoadSamples(VFILE *file); static void M_CompleteSetup(void); +GAME_FLOW_LEVEL *M_GetFromNumberAndType( + const int32_t level_num, const GAME_FLOW_LEVEL_TYPE level_type) +{ + switch (level_type) { + case GFL_TITLE: + return g_GameFlow.title_level; + + case GFL_CUTSCENE: + if (level_num < 0 || level_num >= GF_GetCutsceneCount()) { + LOG_ERROR("Invalid cutscene number: %d", level_num); + return NULL; + } + return &g_GameFlow.cutscenes[level_num]; + + case GFL_DEMO: + if (level_num < 0 || level_num >= GF_GetDemoCount()) { + LOG_ERROR("Invalid demo number: %d", level_num); + return NULL; + } + return &g_GameFlow.demos[level_num]; + + case GFL_NORMAL: + case GFL_SAVED: + if (level_num < 0 || level_num >= GF_GetLevelCount()) { + LOG_ERROR("Invalid level number: %d", level_num); + return NULL; + } + return &g_GameFlow.levels[level_num]; + + default: + LOG_ERROR("Invalid level type: %d", level_type); + return NULL; + } +} + static void M_LoadTexturePages(VFILE *const file) { BENCHMARK *const benchmark = Benchmark_Start(); @@ -673,14 +715,14 @@ static void M_LoadSamples(VFILE *const file) Benchmark_End(benchmark, NULL); } -static void M_LoadFromFile(const char *const file_name, const int32_t level_num) +static void M_LoadFromFile(const GAME_FLOW_LEVEL *const level) { - LOG_DEBUG("%s (num=%d)", GF_GetLevelTitle(level_num), level_num); + LOG_DEBUG("%s (num=%d)", level->title, level->num); GameBuf_Reset(); BENCHMARK *const benchmark = Benchmark_Start(); - const char *full_path = File_GetFullPath(file_name); + const char *full_path = File_GetFullPath(level->path); strcpy(g_LevelFileName, full_path); VFILE *const file = VFile_CreateFromPath(full_path); Memory_FreePointer(&full_path); @@ -688,8 +730,8 @@ static void M_LoadFromFile(const char *const file_name, const int32_t level_num) const int32_t version = VFile_ReadS32(file); if (version != 45) { Shell_ExitSystemFmt( - "Unexpected level version (%d, expected: %d, path: %s)", level_num, - 45, file_name); + "Unexpected level version (%d, expected: %d, path: %s)", level->num, + 45, level->path); } M_LoadPalettes(file); @@ -753,7 +795,7 @@ static void M_CompleteSetup(void) Benchmark_End(benchmark, NULL); } -bool Level_Load(const char *const file_name, const int32_t level_num) +bool Level_Load(const GAME_FLOW_LEVEL *const level) { BENCHMARK *const benchmark = Benchmark_Start(); @@ -765,10 +807,9 @@ bool Level_Load(const char *const file_name, const int32_t level_num) Object_GetStaticObject3D(i)->loaded = false; } - const GAME_FLOW_LEVEL *const level = &g_GameFlow.levels[level_num]; Inject_Init(level->injections.count, level->injections.data_paths); - M_LoadFromFile(file_name, level_num); + M_LoadFromFile(level); M_CompleteSetup(); Inject_Cleanup(); @@ -777,3 +818,74 @@ bool Level_Load(const char *const file_name, const int32_t level_num) return true; } + +bool Level_Initialise( + const int32_t level_num, const GAME_FLOW_LEVEL_TYPE level_type) +{ + LOG_DEBUG("num=%d type=%d", level_num, level_type); + g_GameInfo.current_level.num = level_num; + g_GameInfo.current_level.type = level_type; + + if (level_type != GFL_TITLE && level_type != GFL_DEMO) { + g_GymInvOpenEnabled = false; + } + + if (level_type != GFL_TITLE && level_type != GFL_CUTSCENE) { + g_CurrentLevel = level_num; + } + InitialiseGameFlags(); + g_Lara.item_num = NO_ITEM; + + const GAME_FLOW_LEVEL *level = + M_GetFromNumberAndType(level_num, level_type); + if (level == NULL) { + return false; + } + + Level_Unload(); + if (!Level_Load(level)) { + return false; + } + + if (g_Lara.item_num != NO_ITEM) { + Lara_Initialise(level_type); + } + if (level_type == GFL_NORMAL || level_type == GFL_SAVED + || level_type == GFL_DEMO) { + GetCarriedItems(); + } + + Effect_InitialiseArray(); + LOT_InitialiseArray(); + Overlay_Reset(); + g_HealthBarTimer = 100; + Sound_StopAll(); + if (level_type == GFL_SAVED) { + ExtractSaveGameInfo(); + } else if (level_type == GFL_NORMAL) { + GF_InventoryModifier_Apply(g_CurrentLevel, GF_INV_REGULAR); + } + + if (g_Objects[O_FINAL_LEVEL_COUNTER].loaded) { + InitialiseFinalLevel(); + } + + if (level->music_track != MX_INACTIVE) { + Music_Play( + level->music_track, + level_type == GFL_CUTSCENE ? MPM_ALWAYS : MPM_LOOPED); + } + + g_IsAssaultTimerActive = false; + g_IsAssaultTimerDisplay = false; + g_Camera.underwater = 0; + return true; +} + +void Level_Unload(void) +{ + strcpy(g_LevelFileName, ""); + memset(g_TexturePageBuffer8, 0, sizeof(uint8_t *) * MAX_TEXTURE_PAGES); + memset(g_TexturePageBuffer16, 0, sizeof(uint16_t *) * MAX_TEXTURE_PAGES); + g_ObjectTextureCount = 0; +} diff --git a/src/tr2/game/level.h b/src/tr2/game/level.h index 8a31cfd9e..1b1bca3e2 100644 --- a/src/tr2/game/level.h +++ b/src/tr2/game/level.h @@ -1,7 +1,8 @@ #pragma once +#include "game/game_flow/types.h" #include "global/types.h" -#include - -bool Level_Load(const char *file_name, int32_t level_num); +bool Level_Initialise(int32_t level_num, GAME_FLOW_LEVEL_TYPE level_type); +bool Level_Load(const GAME_FLOW_LEVEL *level); +void Level_Unload(void); diff --git a/src/tr2/global/enum_map.def b/src/tr2/global/enum_map.def index 051d47520..f79527cc0 100644 --- a/src/tr2/global/enum_map.def +++ b/src/tr2/global/enum_map.def @@ -19,7 +19,6 @@ ENUM_MAP_DEFINE(GAME_FLOW_SEQUENCE_EVENT_TYPE, GFS_REMOVE_WEAPONS, "remove_ ENUM_MAP_DEFINE(GAME_FLOW_SEQUENCE_EVENT_TYPE, GFS_REMOVE_AMMO, "remove_ammo") ENUM_MAP_DEFINE(GAME_FLOW_SEQUENCE_EVENT_TYPE, GFS_LEVEL_COMPLETE, "level_complete") ENUM_MAP_DEFINE(GAME_FLOW_SEQUENCE_EVENT_TYPE, GFS_GAME_COMPLETE, "game_complete") -ENUM_MAP_DEFINE(GAME_FLOW_SEQUENCE_EVENT_TYPE, GFS_SET_MUSIC_TRACK, "set_music_track") ENUM_MAP_DEFINE(GAME_FLOW_SEQUENCE_EVENT_TYPE, GFS_SET_NUM_SECRETS, "set_secret_count") ENUM_MAP_DEFINE(GAME_FLOW_SEQUENCE_EVENT_TYPE, GFS_SET_CAMERA_ANGLE, "set_cutscene_angle") ENUM_MAP_DEFINE(GAME_FLOW_SEQUENCE_EVENT_TYPE, GFS_SET_START_ANIM, "set_lara_start_anim") diff --git a/src/tr2/global/vars.c b/src/tr2/global/vars.c index a3d3f2de3..91d4a7cbc 100644 --- a/src/tr2/global/vars.c +++ b/src/tr2/global/vars.c @@ -18,7 +18,6 @@ OBJECT_TEXTURE g_ObjectTextures[MAX_OBJECT_TEXTURES]; SDL_Window *g_SDLWindow = NULL; uint32_t g_PerspectiveDistance = 0x3000000; -int32_t g_CineTrackID = 1; uint32_t g_AssaultBestTime = -1; int16_t g_CineTargetAngle = DEG_90; @@ -323,7 +322,6 @@ REQUEST_INFO g_SaveGameRequester = { bool g_GF_RemoveAmmo = false; bool g_GF_RemoveWeapons = false; bool g_GF_SunsetEnabled = false; -int16_t g_GF_MusicTracks[16] = {}; int16_t g_GF_NoFloor = 0; int16_t g_GF_NumSecrets = 3; int32_t g_GF_LaraStartAnim; diff --git a/src/tr2/global/vars.h b/src/tr2/global/vars.h index 62eb1facd..ef8c51bb1 100644 --- a/src/tr2/global/vars.h +++ b/src/tr2/global/vars.h @@ -17,7 +17,6 @@ extern uint16_t *g_TexturePageBuffer16[MAX_TEXTURE_PAGES]; extern SDL_Window *g_SDLWindow; extern uint32_t g_PerspectiveDistance; -extern int32_t g_CineTrackID; extern uint32_t g_AssaultBestTime; extern int16_t g_CineTargetAngle; extern int32_t g_OverlayStatus; @@ -131,7 +130,6 @@ extern REQUEST_INFO g_SaveGameRequester; extern bool g_GF_SunsetEnabled; extern bool g_GF_RemoveAmmo; extern bool g_GF_RemoveWeapons; -extern int16_t g_GF_MusicTracks[16]; extern int16_t g_GF_NoFloor; extern int16_t g_GF_NumSecrets; extern int32_t g_GF_LaraStartAnim;