diff --git a/Build/PCTomb5.idb b/Build/PCTomb5.idb index 994c068ff..26872f349 100644 Binary files a/Build/PCTomb5.idb and b/Build/PCTomb5.idb differ diff --git a/Build/SCRIPT.DAT b/Build/SCRIPT.DAT index af6e636a6..a64a4002b 100644 Binary files a/Build/SCRIPT.DAT and b/Build/SCRIPT.DAT differ diff --git a/Build/Script.dat b/Build/Script.dat index af6e636a6..a64a4002b 100644 Binary files a/Build/Script.dat and b/Build/Script.dat differ diff --git a/Build/Script/SCRIPT.TXT b/Build/Script/SCRIPT.TXT index dfc96540a..03defd7b0 100644 --- a/Build/Script/SCRIPT.TXT +++ b/Build/Script/SCRIPT.TXT @@ -30,15 +30,16 @@ PlayAnyLevel= ENABLED FlyCheat= ENABLED Diagnostic= ENABLED WorldFarView= 200 +Intro= SCREENS\MAIN.PNG ;-------------------------------------- ; Title ;-------------------------------------- [Title] -LoadScreen= SCREENS\TITLE.PNG +Background= SCREENS\TITLE.PNG LevelFile= DATA\TITLE.TRC -AmbientTrack= 104 +AmbientTrack= 83 ;-------------------------------------- ; Levels diff --git a/Build/Script/Tracks.txt b/Build/Script/Tracks.txt new file mode 100644 index 000000000..353be6235 --- /dev/null +++ b/Build/Script/Tracks.txt @@ -0,0 +1,136 @@ +xa1_TL_10B.wav +xa1_Z10.wav +xa1_TL_05.wav +xa1_TL_08.wav +xa1_TL_11.wav +xa1_ANDYPEW.wav +xa1_SECRET.wav +xa1_TL_02.wav +xa2_HMMM05.wav +xa2_TL_01.wav +xa2_ATTACK04.wav +xa2_UWATER2B.wav +xa2_SPOOKY2A.wav +xa2_TL_10A.wav +xa2_HMMM02.wav +xa2_TOMS01.wav +xa3_Attack03.wav +xa3_Attack02.wav +xa3_Hmmm01.wav +xa3_Stealth1.wav +xa3_Stealth2.wav +xa3_Attack01.wav +xa3_TL_06.wav +xa3_TL_03.wav +xa4_hmmm06.wav +xa4_mil01.wav +xa4_Z_03.wav +xa4_hit01.wav +xa4_spooky05.wav +xa4_drama01.wav +xa4_stealth4.wav +xa4_mil05.wav +xa5_HMMM04.wav +xa5_MIL06.wav +xa5_SPOOKY02.wav +xa5_TL_12.wav +xa5_MIL02A.wav +xa5_HMMM03.wav +xa5_MIL02.wav +xa5_TL_04.wav +xa6_Mil04.wav +xa6_Solo01.wav +xa6_Z12.wav +xa6_Stealth3.wav +xa6_AuthSolo.wav +xa6_Spooky03.wav +xa6_Z13.wav +xa6_Z_04anim.wav +xa7_z_06a.wav +xa7_andyoooh.wav +xa7_andyooer.wav +xa7_tl_07.wav +xa7_z_02.wav +xa7_evibes01.wav +xa7_z_06.wav +xa7_authtr.wav +xa8_mil03.wav +xa8_fightsc.wav +xa8_richcut3.wav +xa8_z_13.wav +xa8_z_08.wav +xa8_uwater2a.wav +xa8_jobyalrm.wav +xa8_mil02b.wav +xa9_swampy.wav +xa9_evibes02.wav +xa9_gods01.wav +xa9_z_03.wav +xa9_richcut4.wav +xa9_title4.wav +xa9_spooky01.wav +xa9_chopin01.wav +xa10_echoir01.wav +xa10_title3.wav +xa10_perc01.wav +xa10_vc01.wav +xa10_title2.wav +xa10_z_09.wav +xa10_spooky04.wav +xa10_z_10.wav +xa11_vc01atv.wav +xa11_andy3.wav +xa11_title1.wav +xa11_flyby1.wav +xa11_monk_2.wav +xa11_andy4.wav +xa11_flyby3.wav +xa11_flyby2.wav +xa12_moses01.wav +xa12_andy4b.wav +xa12_z_10.wav +xa12_flyby4.wav +xa12_richcut1.wav +xa12_andy5.wav +xa12_z_05.wav +xa12_z_01.wav +xa13_Joby3.wav +xa13_Andy7.wav +xa13_Andrea3B.wav +xa13_cossack.wav +xa13_Z_07.wav +xa13_Andy6.wav +xa13_Andrea3.wav +xa13_Joby7.wav +xa14_uwater1.wav +xa14_joby1.wav +xa14_andy10.wav +xa14_richcut2.wav +xa14_andrea1.wav +xa14_andy8.wav +xa14_joby6.wav +xa14_ecredits.wav +xa15_boss_01.wav +xa15_joby2.wav +xa15_joby4.wav +xa15_joby5.wav +xa15_joby9.wav +xa15_a_andy.wav +xa15_a_rome.wav +xa15_andy2.wav +xa16_Joby8.wav +xa16_A_Sub_Amb.wav +xa16_Joby10.wav +xa16_A_Harbour_out.wav +xa16_A_Andy_Out_Norm.wav +xa16_A_Andy_Out_Spooky.wav +xa16_A_Rome_Day.wav +xa16_A_Underwater.wav +xa17_A_Rome_Night.wav +xa17_A_VC_Saga.wav +xa17_A_Industry.wav +xa17_Andrea2.wav +xa17_Andy1.wav +xa17_Andrea4.wav +xa17_Andy9.wav +xa17_Andy11.wav \ No newline at end of file diff --git a/Build/Title.png b/Build/Title.png deleted file mode 100644 index 2f1d935c2..000000000 Binary files a/Build/Title.png and /dev/null differ diff --git a/Build/savegame.0 b/Build/savegame.0 index 07c8ea44e..82710d058 100644 Binary files a/Build/savegame.0 and b/Build/savegame.0 differ diff --git a/Build/savegame.6 b/Build/savegame.6 new file mode 100644 index 000000000..8fd18c120 Binary files /dev/null and b/Build/savegame.6 differ diff --git a/TR5Main/Game/camera.cpp b/TR5Main/Game/camera.cpp index 2c5d57763..8f4cc77f8 100644 --- a/TR5Main/Game/camera.cpp +++ b/TR5Main/Game/camera.cpp @@ -4,7 +4,7 @@ #include #include "draw.h" -void __cdecl phd_LookAt(__int32 posX, __int32 posY, __int32 posZ, +void __cdecl LookAt(__int32 posX, __int32 posY, __int32 posZ, __int32 targetX, __int32 targetY, __int32 targetZ, __int16 roll) { @@ -12,11 +12,12 @@ void __cdecl phd_LookAt(__int32 posX, __int32 posY, __int32 posZ, Vector3 target = Vector3(targetX, targetY, targetZ); Vector3 up = Vector3(0.0f, -1.0f, 0.0f); float fov = TR_ANGLE_TO_RAD(CurrentFOV); + float r = TR_ANGLE_TO_RAD(roll); - g_Renderer->UpdateCameraMatrices(posX, posY, posZ, targetX, targetY, targetZ, roll, fov); + g_Renderer->UpdateCameraMatrices(posX, posY, posZ, targetX, targetY, targetZ, r, fov); } -void __cdecl phd_AlterFOV(__int32 value) +void __cdecl AlterFOV(__int32 value) { CurrentFOV = value; PhdPerspective = PhdWidth / 2 * COS(CurrentFOV / 2) / SIN(CurrentFOV / 2); @@ -24,13 +25,12 @@ void __cdecl phd_AlterFOV(__int32 value) void __cdecl j_CalculateCamera() { - //printf("Item: %d\n", Camera.target); CalculateCamera(); } void Inject_Camera() { - INJECT(0x0048EDC0, phd_AlterFOV); - INJECT(0x0048F760, phd_LookAt); + INJECT(0x0048EDC0, AlterFOV); + INJECT(0x0048F760, LookAt); INJECT(0x00401D5C, j_CalculateCamera); } \ No newline at end of file diff --git a/TR5Main/Game/camera.h b/TR5Main/Game/camera.h index 75168eb23..47f1cb9f6 100644 --- a/TR5Main/Game/camera.h +++ b/TR5Main/Game/camera.h @@ -11,10 +11,10 @@ #define InitialiseCamera ((void (__cdecl*)()) 0x0040C690) #define CalculateCamera ((void (__cdecl*)()) 0x0040ED30) -void __cdecl phd_LookAt(__int32 posX, __int32 posY, __int32 posZ, +void __cdecl LookAt(__int32 posX, __int32 posY, __int32 posZ, __int32 targetX, __int32 targetY, __int32 targetZ, __int16 roll); -void __cdecl phd_AlterFOV(__int32 value); +void __cdecl AlterFOV(__int32 value); void __cdecl j_CalculateCamera(); void Inject_Camera(); \ No newline at end of file diff --git a/TR5Main/Game/control.cpp b/TR5Main/Game/control.cpp index abaa540b5..e6c3915a2 100644 --- a/TR5Main/Game/control.cpp +++ b/TR5Main/Game/control.cpp @@ -53,11 +53,14 @@ GAME_STATUS __cdecl ControlPhase(__int32 numFrames, __int32 demoMode) UpdateSky(); // Poll the keyboard and update input variables - if (S_UpdateInput() == -1) - return GAME_STATUS_NONE; - + if (CurrentLevel != 0) + { + if (S_UpdateInput() == -1) + return GAME_STATUS_NONE; + } + // Has Lara control been disabled? - if (DisableLaraControl) + if (DisableLaraControl || CurrentLevel == 0) { if (CurrentLevel != 0) DbInput = 0; @@ -87,13 +90,13 @@ GAME_STATUS __cdecl ControlPhase(__int32 numFrames, __int32 demoMode) } // Has level been completed? - if (LevelComplete) + if (CurrentLevel != 0 && LevelComplete) return GAME_STATUS_LEVEL_COMPLETED; __int32 oldInput = TrInput; // Is Lara dead? - if (Lara.deathCount > 300 || Lara.deathCount > 60 && TrInput) + if (CurrentLevel != 0 && (Lara.deathCount > 300 || Lara.deathCount > 60 && TrInput)) { __int32 inventoryResult = g_Inventory->DoInventory(); switch (inventoryResult) @@ -113,89 +116,95 @@ GAME_STATUS __cdecl ControlPhase(__int32 numFrames, __int32 demoMode) TrInput = 0; } + if (CurrentLevel == 0) + TrInput = 0; + // Handle lasersight and binocular - if (!(TrInput & IN_LOOK) || SniperCameraActive || UseSpotCam || TrackCameraInit || - ((LaraItem->currentAnimState != STATE_LARA_STOP || LaraItem->animNumber != ANIMATION_LARA_STAY_IDLE) - && (!Lara.isDucked - || TrInput & IN_DUCK - || LaraItem->animNumber != ANIMATION_LARA_CROUCH_IDLE - || LaraItem->goalAnimState != STATE_LARA_CROUCH_IDLE))) + if (CurrentLevel != 0) { - if (BinocularRange == 0) + if (!(TrInput & IN_LOOK) || SniperCameraActive || UseSpotCam || TrackCameraInit || + ((LaraItem->currentAnimState != STATE_LARA_STOP || LaraItem->animNumber != ANIMATION_LARA_STAY_IDLE) + && (!Lara.isDucked + || TrInput & IN_DUCK + || LaraItem->animNumber != ANIMATION_LARA_CROUCH_IDLE + || LaraItem->goalAnimState != STATE_LARA_CROUCH_IDLE))) { - if (SniperCameraActive || UseSpotCam || TrackCameraInit) - TrInput &= ~IN_LOOK; + if (BinocularRange == 0) + { + if (SniperCameraActive || UseSpotCam || TrackCameraInit) + TrInput &= ~IN_LOOK; + } + else + { + if (LaserSight) + { + BinocularRange = 0; + LaserSight = false; + AlterFOV(ANGLE(80)); + LaraItem->meshBits = 0xFFFFFFFF; + Lara.isDucked = false; + Camera.type = BinocularOldCamera; + + Lara.headYrot = 0; + Lara.headXrot = 0; + + Lara.torsoYrot = 0; + Lara.torsoXrot = 0; + + Camera.bounce = 0; + BinocularOn = -8; + + TrInput &= ~IN_LOOK; + } + else + { + TrInput |= IN_LOOK; + } + } + + Infrared = false; + } + else if (BinocularRange == 0) + { + if (Lara.gunStatus == LG_READY + && ((Lara.gunType == WEAPON_REVOLVER && g_LaraExtra.Weapons[WEAPON_REVOLVER].HasLasersight) + || (Lara.gunType == WEAPON_HK) + || (Lara.gunType == WEAPON_CROSSBOW && g_LaraExtra.Weapons[WEAPON_CROSSBOW].HasLasersight))) + { + BinocularRange = 128; + BinocularOldCamera = Camera.oldType; + + Lara.busy = true; + LaserSight = true; + + /*if (!(gfLevelFlags & GF_LVOP_TRAIN)) + InfraRed = TRUE; + else* + InfraRed = FALSE;*/ + Infrared = true; + } + else + Infrared = false; } else { if (LaserSight) { - BinocularRange = 0; - LaserSight = false; - phd_AlterFOV(ANGLE(80)); - LaraItem->meshBits = 0xFFFFFFFF; - Lara.isDucked = false; - Camera.type = BinocularOldCamera; - - Lara.headYrot = 0; - Lara.headXrot = 0; - - Lara.torsoYrot = 0; - Lara.torsoXrot = 0; - - Camera.bounce = 0; - BinocularOn = -8; - - TrInput &= ~IN_LOOK; + /*if (!(gfLevelFlags & GF_LVOP_TRAIN)) + InfraRed = TRUE; + else + InfraRed = FALSE;*/ + Infrared = true; } else { - TrInput |= IN_LOOK; + /*if ((gfLevelFlags & GF_LVOP_TRAIN) && (inputBusy & IN_ACTION)) + InfraRed = TRUE; + else + InfraRed = FALSE;*/ + Infrared = false; } } - - Infrared = false; - } - else if (BinocularRange == 0) - { - if (Lara.gunStatus == LG_READY - && ((Lara.gunType == WEAPON_REVOLVER && g_LaraExtra.Weapons[WEAPON_REVOLVER].HasLasersight) - || (Lara.gunType == WEAPON_HK) - || (Lara.gunType == WEAPON_CROSSBOW && g_LaraExtra.Weapons[WEAPON_CROSSBOW].HasLasersight))) - { - BinocularRange = 128; - BinocularOldCamera = Camera.oldType; - - Lara.busy = true; - LaserSight = true; - - /*if (!(gfLevelFlags & GF_LVOP_TRAIN)) - InfraRed = TRUE; - else* - InfraRed = FALSE;*/ - Infrared = true; - } - else - Infrared = false; - } - else - { - if (LaserSight) - { - /*if (!(gfLevelFlags & GF_LVOP_TRAIN)) - InfraRed = TRUE; - else - InfraRed = FALSE;*/ - Infrared = true; - } - else - { - /*if ((gfLevelFlags & GF_LVOP_TRAIN) && (inputBusy & IN_ACTION)) - InfraRed = TRUE; - else - InfraRed = FALSE;*/ - Infrared = false; - } } // Clear dynamic lights @@ -257,62 +266,67 @@ GAME_STATUS __cdecl ControlPhase(__int32 numFrames, __int32 demoMode) if (WeaponEnemyTimer) WeaponEnemyTimer--; - if (Lara.hasFired) + if (CurrentLevel != 0) { - AlertNearbyGuards(LaraItem); - Lara.hasFired = false; - } + if (Lara.hasFired) + { + AlertNearbyGuards(LaraItem); + Lara.hasFired = false; + } - // Is Lara poisoned? - if (Lara.poisoned) - { - if (Lara.poisoned <= 4096) + // Is Lara poisoned? + if (Lara.poisoned) { - if (Lara.dpoisoned) - ++Lara.dpoisoned; - } - else - { - Lara.poisoned = 4096; - } - if ((gfLevelFlags & 0x80u) != 0 && !Lara.gassed) - { - if (Lara.dpoisoned) + if (Lara.poisoned <= 4096) { - Lara.dpoisoned -= 8; - if (Lara.dpoisoned < 0) - Lara.dpoisoned = 0; + if (Lara.dpoisoned) + ++Lara.dpoisoned; + } + else + { + Lara.poisoned = 4096; + } + if ((gfLevelFlags & 0x80u) != 0 && !Lara.gassed) + { + if (Lara.dpoisoned) + { + Lara.dpoisoned -= 8; + if (Lara.dpoisoned < 0) + Lara.dpoisoned = 0; + } + } + if (Lara.dpoisoned >= 256 && !(Wibble & 0xFF)) + { + LaraItem->hitPoints -= Lara.poisoned >> (8 - Lara.gassed); + PoisonFlags = 16; } } - if (Lara.dpoisoned >= 256 && !(Wibble & 0xFF)) - { - LaraItem->hitPoints -= Lara.poisoned >> (8 - Lara.gassed); - PoisonFlags = 16; - } + + // Control Lara + InItemControlLoop = true; + Lara.skelebob = NULL; + LaraControl(); + InItemControlLoop = false; + KillMoveItems(); + + // Update Lara's ponytails + HairControl(0, 0, 0); + if (level->LaraType == LARA_YOUNG) + HairControl(0, 1, 0); } - // Control Lara - InItemControlLoop = true; - Lara.skelebob = NULL; - LaraControl(); - InItemControlLoop = false; - KillMoveItems(); - - // Update Lara's ponytails - HairControl(0, 0, 0); - if (level->LaraType == LARA_YOUNG) - HairControl(0, 1, 0); - if (UseSpotCam) { // Draw flyby cameras - g_Renderer->EnableCinematicBars(true); + if (CurrentLevel != 0) + g_Renderer->EnableCinematicBars(true); CalculateSpotCameras(); } else { // Do the standard camera g_Renderer->EnableCinematicBars(false); + TrackCameraInit = false; CalculateCamera(); } @@ -411,11 +425,63 @@ GAME_STATUS __cdecl DoTitle(__int32 index) DB_Log(2, "DoTitle - DLL"); printf("DoTitle\n"); - // Load the title level - S_LoadLevelFile(0); - - __int32 inventoryResult = g_Inventory->DoTitleInventory(); + CreditsDone = false; + CanLoad = false; + // Load the level + S_LoadLevelFile(index); + + __int32 inventoryResult; + + if (g_GameFlow->TitleType == TITLE_FLYBY) + { + // Initialise items, effects, lots, camera + InitialiseFXArray(true); + InitialisePickUpDisplay(); + InitialiseCamera(); + SOUND_Stop(); + + RequiredStartPos = false; + if (InitialiseGame) + { + GameTimer = 0; + RequiredStartPos = false; + InitialiseGame = false; + } + + Savegame.Level.Timer = 0; + if (CurrentLevel == 1) + Savegame.TLCount = 0; + + LastInventoryItem = -1; + DelCutSeqPlayer = 0; + TitleControlsLockedOut = false; + GameMode = 1; + + // Initialise flyby cameras + InitSpotCamSequences(); + + InitialiseSpotCam(2); + CurrentAtmosphere = 83; + UseSpotCam = true; + + // Play background music + //CurrentAtmosphere = ambient; + S_CDPlay(CurrentAtmosphere, 1); + IsAtmospherePlaying = true; + + // Initialise ponytails + InitialiseHair(); + + ControlPhase(2, 0); + inventoryResult = g_Inventory->DoTitleInventory(); + } + else + { + inventoryResult = g_Inventory->DoTitleInventory(); + } + + UseSpotCam = false; S_CDStop(); switch (inventoryResult) @@ -488,7 +554,7 @@ GAME_STATUS __cdecl DoLevel(__int32 index, __int32 ambient, bool loadFromSavegam // Initialise flyby cameras InitSpotCamSequences(); - + // Play background music CurrentAtmosphere = ambient; S_CDPlay(CurrentAtmosphere, 1); @@ -505,7 +571,7 @@ GAME_STATUS __cdecl DoLevel(__int32 index, __int32 ambient, bool loadFromSavegam while (true) { nframes = DrawPhaseGame(); - result = ControlPhase(nframes, 0); + result = ControlPhase(nframes, 0); printf("LastSpotCam: %d\n", LastSpotCam); if (result == GAME_STATUS_EXIT_TO_TITLE || result == GAME_STATUS_LOAD_GAME || @@ -910,7 +976,7 @@ void __cdecl TestTriggers(__int16* data, __int32 heavy, __int32 HeavyFlags) else { spotCamIndex = 0; - if (SpotCamRemap[value] > 0) + if (SpotCamRemap[value] != 0) { for (__int32 i = 0; i < SpotCamRemap[value]; i++) { @@ -918,17 +984,17 @@ void __cdecl TestTriggers(__int16* data, __int32 heavy, __int32 HeavyFlags) } } - if (!(SpotCam[spotCamIndex].flags & 0x8000)) + if (!(SpotCam[spotCamIndex].flags & SCF_CAMERA_ONE_SHOT)) { if (trigger & 0x100) - SpotCam[spotCamIndex].flags |= 0x8000; + SpotCam[spotCamIndex].flags |= SCF_CAMERA_ONE_SHOT; - if (!UseSpotCam) + if (!UseSpotCam || CurrentLevel == 0) { UseSpotCam = true; if (LastSpotCam != value) TrackCameraInit = false; - InitialiseSpotCameras(value); + InitialiseSpotCam(value); } } } @@ -1085,7 +1151,16 @@ void __cdecl AnimateWaterfalls() } } +void __cdecl TestTriggersAtXYZ(__int32 x, __int32 y, __int32 z, __int16 roomNumber, __int16 heavy, __int16 heavyFlags) +{ + FLOOR_INFO* floor = GetFloor(x, y, z, &roomNumber); + GetFloorHeight(floor, x, y, z); + TestTriggers(TriggerIndex, heavy, heavyFlags); +} + void Inject_Control() { - + INJECT(0x00416760, TestTriggers); + INJECT(0x004167B0, TestTriggers); + INJECT(0x0047D9D0, TestTriggersAtXYZ); } \ No newline at end of file diff --git a/TR5Main/Game/control.h b/TR5Main/Game/control.h index 8032d4a0f..ef149f9ac 100644 --- a/TR5Main/Game/control.h +++ b/TR5Main/Game/control.h @@ -42,6 +42,7 @@ #define AlterFloorHeight ((void (__cdecl*)(ITEM_INFO*, __int32)) 0x004159F0) #define SoundEffects ((void (__cdecl*)()) 0x00432640) //#define AnimateWaterfalls ((void (__cdecl*)()) 0x00465DF0) +//#define TestTriggersAtXYZ ((void (__cdecl*)(__int32, __int32, __int32, __int16, __int32, __int32)) 0x0047D9D0) GAME_STATUS __cdecl DoTitle(__int32 index); GAME_STATUS __cdecl DoLevel(__int32 index, __int32 ambient, bool loadFromSavegame); @@ -51,5 +52,5 @@ void __cdecl AnimateWaterfalls(); unsigned __stdcall GameMain(void*); void __cdecl TestTriggers(__int16* data, __int32 heavy, __int32 HeavyFlags); - +void __cdecl TestTriggersAtXYZ(__int32 x, __int32 y, __int32 z, __int16 roomNumber, __int16 heavy, __int16 heavyFlags); void Inject_Control(); \ No newline at end of file diff --git a/TR5Main/Game/draw.cpp b/TR5Main/Game/draw.cpp index 3b6b574ce..9c3a9f586 100644 --- a/TR5Main/Game/draw.cpp +++ b/TR5Main/Game/draw.cpp @@ -13,42 +13,13 @@ __int32 __cdecl DrawPhaseGame() // Calls my new rock & roll renderer :) g_Renderer->Draw(); - nFrames = g_Renderer->SyncRenderer(); + Camera.numberFrames = g_Renderer->SyncRenderer(); // We need to pop the matrix stack or the game will crash MatrixPtr -= 12; DxMatrixPtr -= 48; - return nFrames; -} - -__int32 DrawGame() -{ - // Control routines uses joints calculated here for getting Lara joint positions - CalcLaraMatrices(0); - phd_PushUnitMatrix(); - CalcLaraMatrices(1); - - // Calls my new rock & roll renderer :) - g_Renderer->Draw(); - nFrames = g_Renderer->SyncRenderer(); - - // We need to pop the matrix stack or the game will crash - MatrixPtr -= 12; - DxMatrixPtr -= 48; - - return nFrames; -} - -__int32 DrawInventory() -{ - return g_Renderer->DrawInventory(); -} - -void __cdecl DoBootScreen(__int32 language) -{ - //printf("DoBootScreen\n"); - //DrawFullScreenImage((char*)"load.bmp"); + return Camera.numberFrames; } __int32 __cdecl GetFrame_D2(ITEM_INFO* item, __int16* framePtr[], __int32* rate) @@ -79,5 +50,5 @@ __int32 __cdecl GetFrame_D2(ITEM_INFO* item, __int16* framePtr[], __int32* rate) void Inject_Draw() { - INJECT(0x004B8A80, DoBootScreen); + } \ No newline at end of file diff --git a/TR5Main/Game/draw.h b/TR5Main/Game/draw.h index 7eff6a951..c93d00839 100644 --- a/TR5Main/Game/draw.h +++ b/TR5Main/Game/draw.h @@ -5,19 +5,15 @@ #define DrawAnimatingItem ((void (__cdecl*)(ITEM_INFO*)) 0x0042B900) #define GetBoundsAccurate ((short* (__cdecl*)(ITEM_INFO*)) 0x0042CF80) #define GetBestFrame ((short* (__cdecl*)(ITEM_INFO*)) 0x0042D020) -//#define GetFrame_D2 ((__int32 (__cdecl*)(ITEM_INFO*, __int16**, __int32*)) 0x0042CEB0) #define CalcLaraMatrices ((void (__cdecl*)(__int32)) 0x0041E120) #define phd_PushUnitMatrix ((void (__cdecl*)()) 0x0048FA90) #define Sync ((__int32 (__cdecl*)()) 0x004D1A40) #define GetRoomBounds ((void (__cdecl*)()) 0x0042D4F0) #define UpdateStorm ((void (__cdecl*)()) 0x0042A310) #define Sub_0042A050 ((void (__cdecl*)()) 0x0042A050) -#define IsRoomOutside ((__int32 (__cdecl*)(__int32, __int32, __int32)) 0x0044C050) +#define IsRoomOutside ((__int32 (__cdecl*)(__int32, __int32, __int32)) 0x00418E90) __int32 __cdecl DrawPhaseGame(); -__int32 DrawGame(); -__int32 DrawInventory(); -void __cdecl DoBootScreen(__int32 language); __int32 __cdecl GetFrame_D2(ITEM_INFO* item, __int16* framePtr[], __int32* rate); extern Renderer11* g_Renderer; diff --git a/TR5Main/Game/inventory.cpp b/TR5Main/Game/inventory.cpp index 49e520679..e97d8af57 100644 --- a/TR5Main/Game/inventory.cpp +++ b/TR5Main/Game/inventory.cpp @@ -854,8 +854,7 @@ __int32 Inventory::DoInventory() { m_rings[m_activeRing].rotation += deltaAngle; - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } if (m_rings[m_activeRing].currentObject == m_rings[m_activeRing].numObjects - 1) @@ -878,8 +877,7 @@ __int32 Inventory::DoInventory() { m_rings[m_activeRing].rotation -= deltaAngle; - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } if (m_rings[m_activeRing].currentObject == 0) @@ -906,8 +904,7 @@ __int32 Inventory::DoInventory() g_Renderer->FadeOut(); for (__int32 i = 0; i < FADE_FRAMES_COUNT; i++) { - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } return passportResult; @@ -959,8 +956,7 @@ __int32 Inventory::DoInventory() } } - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } CloseRing(m_activeRing, true); @@ -1090,8 +1086,7 @@ __int32 Inventory::DoWeapon() } } - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } PopoverObject(); @@ -1241,8 +1236,7 @@ bool Inventory::DoCombine() { combineRing->rotation += deltaAngle; - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } if (combineRing->currentObject > 0) @@ -1264,8 +1258,7 @@ bool Inventory::DoCombine() { combineRing->rotation -= deltaAngle; - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } SoundEffect(SFX_MENU_ROTATE, NULL, 0); @@ -1303,8 +1296,7 @@ bool Inventory::DoCombine() SayNo(); } - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } CloseRing(INV_RING_COMBINE, false); @@ -1423,8 +1415,7 @@ void Inventory::DoSelectAmmo() { ammoRing->rotation += deltaAngle; - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } if (ammoRing->currentObject > 0) @@ -1446,8 +1437,7 @@ void Inventory::DoSelectAmmo() { ammoRing->rotation -= deltaAngle; - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } SoundEffect(SFX_MENU_ROTATE, NULL, 0); @@ -1484,8 +1474,7 @@ void Inventory::DoSelectAmmo() break; } - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } CloseRing(INV_RING_CHOOSE_AMMO, false); @@ -1856,6 +1845,38 @@ void Inventory::InitialiseTitle() InventoryItemChosen = -1; } +bool Inventory::UpdateSceneAndDrawInventory() +{ + __int32 nframes; + + if (CurrentLevel == 0 && g_GameFlow->TitleType == TITLE_FLYBY) + { + // Control routines uses joints calculated here for getting Lara joint positions + CalcLaraMatrices(0); + phd_PushUnitMatrix(); + CalcLaraMatrices(1); + + // Calls my new rock & roll renderer :) + g_Renderer->DumpGameScene(); + g_Renderer->DrawInventory(); + Camera.numberFrames = g_Renderer->SyncRenderer(); + + // We need to pop the matrix stack or the game will crash + MatrixPtr -= 12; + DxMatrixPtr -= 48; + + nframes = Camera.numberFrames; + ControlPhase(nframes, 0); + } + else + { + g_Renderer->DrawInventory(); + g_Renderer->SyncRenderer(); + } + + return true; +} + __int32 Inventory::DoTitleInventory() { InitialiseTitle(); @@ -1871,8 +1892,7 @@ __int32 Inventory::DoTitleInventory() g_Renderer->FadeIn(); for (__int32 i = 0; i < FADE_FRAMES_COUNT; i++) { - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } CurrentAtmosphere = CDA_XA11_FLYBY1; @@ -1904,8 +1924,7 @@ __int32 Inventory::DoTitleInventory() { ring->rotation += deltaAngle; - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } if (ring->currentObject == ring->numObjects - 1) @@ -1927,8 +1946,7 @@ __int32 Inventory::DoTitleInventory() { ring->rotation -= deltaAngle; - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } if (ring->currentObject == 0) @@ -1964,8 +1982,7 @@ __int32 Inventory::DoTitleInventory() DoSoundSettings(); } - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } CloseRing(INV_RING_OPTIONS, true); @@ -1974,8 +1991,7 @@ __int32 Inventory::DoTitleInventory() g_Renderer->FadeOut(); for (__int32 i = 0; i < FADE_FRAMES_COUNT; i++) { - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } return result; @@ -2017,8 +2033,7 @@ __int32 Inventory::DoPassport() // Open the passport for (__int32 i = 0; i < 14; i++) { - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); ring->frameIndex++; } @@ -2058,8 +2073,7 @@ __int32 Inventory::DoPassport() ring->frameIndex = 19; for (__int32 i = 0; i < 5; i++) { - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); ring->frameIndex--; } @@ -2077,8 +2091,7 @@ __int32 Inventory::DoPassport() ring->frameIndex = 14; for (__int32 i = 0; i < 5; i++) { - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); ring->frameIndex++; } @@ -2155,8 +2168,7 @@ __int32 Inventory::DoPassport() LoadSavegameInfos(); - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } } else if (choices[choice] == INV_WHAT_PASSPORT_SAVE_GAME) @@ -2231,8 +2243,7 @@ __int32 Inventory::DoPassport() LoadSavegameInfos(); - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } } else if (choices[choice] == INV_WHAT_PASSPORT_SELECT_LEVEL) @@ -2302,8 +2313,7 @@ __int32 Inventory::DoPassport() ring->selectedIndex = selectedLevel; ring->passportAction = INV_WHAT_PASSPORT_SELECT_LEVEL; - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } } else if (choices[choice] == INV_WHAT_PASSPORT_NEW_GAME) @@ -2357,8 +2367,7 @@ __int32 Inventory::DoPassport() ring->passportAction = INV_WHAT_PASSPORT_NEW_GAME; - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } } else if (choices[choice] == INV_WHAT_PASSPORT_EXIT_GAME) @@ -2412,8 +2421,7 @@ __int32 Inventory::DoPassport() ring->passportAction = INV_WHAT_PASSPORT_EXIT_GAME; - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } } else if (choices[choice] == INV_WHAT_PASSPORT_EXIT_TO_TITLE) @@ -2467,14 +2475,12 @@ __int32 Inventory::DoPassport() ring->passportAction = INV_WHAT_PASSPORT_EXIT_TO_TITLE; - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } } else { - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } } @@ -2482,8 +2488,7 @@ __int32 Inventory::DoPassport() ring->frameIndex = 24; for (__int32 i = 24; i < 30; i++) { - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); ring->frameIndex++; } @@ -2508,8 +2513,7 @@ __int32 Inventory::PopupObject() for (__int32 i = 0; i < steps; i++) { - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); ring->objects[ring->currentObject].rotation += deltaAngle; ring->objects[ring->currentObject].scale += deltaScale; @@ -2534,8 +2538,7 @@ __int32 Inventory::PopoverObject() for (__int32 i = 0; i < steps; i++) { - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); ring->objects[ring->currentObject].rotation -= deltaAngle; ring->objects[ring->currentObject].scale -= deltaScale; @@ -2620,8 +2623,7 @@ void Inventory::DoControlsSettings() } else { - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); continue; } @@ -2674,8 +2676,7 @@ void Inventory::DoControlsSettings() } } - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); SetDebounce = true; S_UpdateInput(); @@ -2684,8 +2685,7 @@ void Inventory::DoControlsSettings() } } - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } PopoverObject(); @@ -2853,8 +2853,7 @@ void Inventory::DoGraphicsSettings() } } - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } PopoverObject(); @@ -2871,13 +2870,6 @@ void Inventory::DoSoundSettings() // Copy configuration to a temporary object memcpy(&ring->Configuration, &g_Configuration, sizeof(GameConfiguration)); - // Open the passport - for (__int32 i = 0; i < 14; i++) - { - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); - } - bool closeObject = false; __int32 oldVolume = ring->Configuration.MusicVolume; __int32 oldSfxVolume = ring->Configuration.SfxVolume; @@ -3030,8 +3022,7 @@ void Inventory::DoSoundSettings() } } - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } PopoverObject(); @@ -3078,8 +3069,7 @@ void Inventory::OpenRing(__int32 r, bool animateCamera) m_cameraTilt -= deltaTilt; - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } m_cameraTilt = INV_CAMERA_TILT; @@ -3113,8 +3103,7 @@ void Inventory::CloseRing(__int32 r, bool animateCamera) m_cameraTilt += deltaTilt; - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } m_cameraTilt = (animateCamera ? INV_CAMERA_ANIMATION_TILT : INV_CAMERA_TILT); @@ -3160,8 +3149,7 @@ void Inventory::SwitchRing(__int32 from, __int32 to, float verticalShift) ring2->draw = true; } - g_Renderer->DrawInventory(); - g_Renderer->SyncRenderer(); + UpdateSceneAndDrawInventory(); } ring1->distance = 0; diff --git a/TR5Main/Game/inventory.h b/TR5Main/Game/inventory.h index b8fca0fe4..22e1436fe 100644 --- a/TR5Main/Game/inventory.h +++ b/TR5Main/Game/inventory.h @@ -375,6 +375,7 @@ public: float GetCameraY(); float GetCameraTilt(); bool HasWeaponMultipleAmmos(__int16 object); + bool UpdateSceneAndDrawInventory(); }; extern Inventory* g_Inventory; \ No newline at end of file diff --git a/TR5Main/Game/savegame.cpp b/TR5Main/Game/savegame.cpp index 67df6c013..f074a7bac 100644 --- a/TR5Main/Game/savegame.cpp +++ b/TR5Main/Game/savegame.cpp @@ -7,6 +7,7 @@ #include "..\Game\lot.h" #include "..\Game\laramisc.h" #include "..\Objects\newobjects.h" +#include "..\Game\sound.h" FileStream* SaveGame::m_stream; ChunkReader* SaveGame::m_reader; @@ -45,6 +46,8 @@ ChunkId* SaveGame::m_chunkBats; ChunkId* SaveGame::m_chunkRats; ChunkId* SaveGame::m_chunkSpiders; +extern vector g_AudioTracks; + void SaveGame::saveItems() { // Save level items @@ -171,8 +174,8 @@ void SaveGame::saveGameStatus(__int32 arg1, __int32 arg2) for (__int32 i = 0; i < NumberSpotcams; i++) m_writer->WriteChunk(m_chunkFlybyFlags, &saveFlybyFlags, i, SpotCam[i].flags); - for (__int32 i = 0; i < 136; i++) - m_writer->WriteChunk(m_chunkCdFlags, &saveCdFlags, i, CdFlags[i]); + for (__int32 i = 0; i < g_AudioTracks.size(); i++) + m_writer->WriteChunk(m_chunkCdFlags, &saveCdFlags, i, g_AudioTracks[i].Mask); for (__int32 i = 0; i < NumberCameras; i++) m_writer->WriteChunk(m_chunkCamera, &saveCamera, i, Camera.fixed[i].flags); @@ -674,7 +677,8 @@ bool SaveGame::readGameStatusChunks(ChunkId* chunkId, __int32 maxSize, __int32 a __int16 index = LEB128::ReadInt16(m_stream); printf("Index: %d\n", index); __int16 value = LEB128::ReadInt16(m_stream); - CdFlags[index] = value; + if (index < g_AudioTracks.size()) + g_AudioTracks[index].Mask = value; return true; } else if (chunkId->EqualsTo(m_chunkCamera)) diff --git a/TR5Main/Game/sound.cpp b/TR5Main/Game/sound.cpp index fd405cc2d..67ceb22aa 100644 --- a/TR5Main/Game/sound.cpp +++ b/TR5Main/Game/sound.cpp @@ -15,6 +15,8 @@ const BASS_BFX_FREEVERB BASS_ReverbTypes[NUM_REVERB_TYPES] = // Reverb preset { 1.0f, 0.25f, 0.90f, 1.00f, 1.0f, 0, -1 } // 4 = Pipe }; +vector g_AudioTracks; + bool __cdecl Sound_LoadSample(char *pointer, __int32 compSize, __int32 uncompSize, __int32 index) // Replaces DXCreateSampleADPCM() { if (index >= SOUND_MAX_SAMPLES) @@ -266,7 +268,7 @@ void __cdecl S_CDPlay(short index, unsigned int mode) DWORD crossfadeTime; DWORD flags = BASS_STREAM_AUTOFREE | BASS_SAMPLE_FLOAT | BASS_ASYNCFILE; - if (index >= SOUND_LEGACY_TRACKTABLE_SIZE || index < 0) + if (index >= g_AudioTracks.size() || index < 0) return; mode = (mode >= NUM_SOUND_TRACK_TYPES) ? SOUND_TRACK_BGM : mode; @@ -294,9 +296,9 @@ void __cdecl S_CDPlay(short index, unsigned int mode) static char fullTrackName[1024]; char* mask = &TrackNamePrefix; - char* name = TrackNameTable[index]; + char* name = g_AudioTracks[index].Name; - snprintf(fullTrackName, sizeof(fullTrackName), &TrackNamePrefix, TrackNameTable[index]); + snprintf(fullTrackName, sizeof(fullTrackName), &TrackNamePrefix, name); auto stream = BASS_StreamCreateFile(false, fullTrackName, 0, 0, flags); @@ -344,7 +346,7 @@ void __cdecl S_CDPlayEx(short index, DWORD mask, DWORD unknown) static short loopedTracks[] = { 117, 118, 121, 123, 124, 125, 126, 127, 128, 129, 130 }; bool looped = false; - if (index >= SOUND_LEGACY_TRACKTABLE_SIZE || index < 0) + if (index >= g_AudioTracks.size() || index < 0) return; // Assign looping based on hardcoded track IDs. @@ -362,10 +364,10 @@ void __cdecl S_CDPlayEx(short index, DWORD mask, DWORD unknown) if (!looped) { byte filteredMask = (mask >> 8) & 0x3F; - if ((TrackMap[index] & filteredMask) == filteredMask) + if ((g_AudioTracks[index].Mask & filteredMask) == filteredMask) return; // Mask is the same, don't play it. - TrackMap[index] |= filteredMask; + g_AudioTracks[index].Mask |= filteredMask; } S_CDPlay(index, looped); diff --git a/TR5Main/Game/sound.h b/TR5Main/Game/sound.h index 67e10a95c..f64ac6e8a 100644 --- a/TR5Main/Game/sound.h +++ b/TR5Main/Game/sound.h @@ -3,6 +3,7 @@ #include #include #include +#include #include "..\Game\control.h" #include "..\Global\global.h" @@ -664,6 +665,16 @@ enum reverb_type NUM_REVERB_TYPES }; +struct AudioTrack +{ + char* Name; + byte Mask; +}; + +using namespace std; + +extern vector g_AudioTracks; + #define SayNo ((void (__cdecl*)()) 0x004790E0) long __cdecl SoundEffect(__int32 effectID, PHD_3DPOS* position, __int32 env_flags); diff --git a/TR5Main/Game/spotcam.cpp b/TR5Main/Game/spotcam.cpp index 136d06384..56383a26d 100644 --- a/TR5Main/Game/spotcam.cpp +++ b/TR5Main/Game/spotcam.cpp @@ -1 +1,1214 @@ - \ No newline at end of file +#include "spotcam.h" + +#include "..\Global\global.h" +#include "..\Game\camera.h" +#include "..\Game\control.h" +#include "..\Game\draw.h" + + +void __cdecl InitSpotCamSequences() +{ + __int32 s, cc, n, ce; + + n = NumberSpotcams; + TrackCameraInit = 0; + cc = 1; + + if (n != 0) + { + ce = 0; + s = SpotCam[0].sequence; + + if (cc < n) + { + for (n = 1; n < NumberSpotcams; n++) + { + //Same sequence + if (SpotCam[n].sequence == s) + { + cc++; + } + else + { + //New sequence + CameraCnt[ce] = cc; + cc = 1; + SpotCamRemap[s] = ce; + ce++; + s = SpotCam[n].sequence; + } + } + } + + CameraCnt[ce] = cc; + SpotCamRemap[s] = ce; + } + + return; +} + +void __cdecl InitialiseSpotCam(__int16 Sequence) +{ + SPOTCAM* s; + __int32 cn; + __int32 sp; + __int32 i; + + if (TrackCameraInit != 0 && LastSequence == Sequence) + { + TrackCameraInit = 0; + return; + } + + BinocularRange = 0; + LaserSight = 0; + + AlterFOV(16380); + + LaraItem->meshBits = -1; + + Lara.headYrot = 0; + Lara.headXrot = 0; + Lara.torsoYrot = 0; + Lara.torsoXrot = 0; + + Camera.bounce = 0; + + Lara.busy = 0; + + CameraFade = -1; + LastSequence = Sequence; + TrackCameraInit = 0; + SpotcamTimer = 0; + SpotcamLoopCnt = 0; + DisableLaraControl = 0; + + LastFOV = CurrentFOV; + LaraAir = Lara.air; + + InitialCameraPosition.x = Camera.pos.x; + InitialCameraPosition.y = Camera.pos.y; + InitialCameraPosition.z = Camera.pos.z; + + InitialCameraTarget.x = Camera.target.x; + InitialCameraTarget.y = Camera.target.y; + InitialCameraTarget.z = Camera.target.z; + + LaraHealth = LaraItem->hitPoints; + InitialCameraRoom = Camera.pos.roomNumber; + + LaraFixedPosition.x = LaraItem->pos.xPos; + LaraFixedPosition.y = LaraItem->pos.yPos; + LaraFixedPosition.z = LaraItem->pos.zPos; + + CurrentSequence = Sequence; + CurrentSplineCamera = 0; + + for (i = 0; i < SpotCamRemap[Sequence]; i++) + { + CurrentSplineCamera += CameraCnt[i]; + } + + CurrentSplinePosition = 0; + SplineToCamera = 0; + + FirstCamera = CurrentSplineCamera; + + s = &SpotCam[CurrentSplineCamera]; + + LastCamera = CurrentSplineCamera + (CameraCnt[SpotCamRemap[Sequence]] - 1); + CurrentCameraCnt = CameraCnt[SpotCamRemap[Sequence]]; + + if ((s->flags & SCF_DISABLE_LARA_CONTROLS) /*|| gfGameMode == 1*/) + { + DisableLaraControl = 1; + /*if (gfGameMode != 1) + { + //SetFadeClip(16, 1); + }*/ + } + + if (s->flags & SCF_TRACKING_CAM) + { + CameraXposition[0] = SpotCam[FirstCamera].x; + CameraYposition[0] = SpotCam[FirstCamera].y; + CameraZposition[0] = SpotCam[FirstCamera].z; + + CameraXtarget[0] = SpotCam[FirstCamera].tx; + CameraYtarget[0] = SpotCam[FirstCamera].ty; + CameraZtarget[0] = SpotCam[FirstCamera].tz; + + CameraXtarget[0] = SpotCam[FirstCamera].tx; + CameraYtarget[0] = SpotCam[FirstCamera].ty; + CameraZtarget[0] = SpotCam[FirstCamera].tz; + + CameraRoll[0] = SpotCam[FirstCamera].roll; + CameraFOV[0] = SpotCam[FirstCamera].fov; + + SplineFromCamera = 0; + CameraSpeed[0] = SpotCam[FirstCamera].speed; + + if (CurrentCameraCnt > 0) + { + s = &SpotCam[FirstCamera]; + + for (i = 1; i < CurrentCameraCnt + 1; i++, s++) + { + CameraXposition[i] = s->x; + CameraYposition[i] = s->y; + CameraZposition[i] = s->z; + + CameraXtarget[i] = s->tx; + CameraYtarget[i] = s->ty; + CameraZtarget[i] = s->tz; + + CameraXtarget[i] = s->tx; + CameraYtarget[i] = s->ty; + CameraZtarget[i] = s->tz; + + CameraRoll[i] = s->roll; + CameraFOV[i] = s->fov; + CameraSpeed[i] = s->speed; + } + } + + //loc_379F8 + CameraXposition[1] = SpotCam[LastCamera].x; + CameraYposition[1] = SpotCam[LastCamera].y; + CameraZposition[1] = SpotCam[LastCamera].z; + + CameraXtarget[1] = SpotCam[LastCamera].tx; + CameraYtarget[1] = SpotCam[LastCamera].ty; + CameraZtarget[1] = SpotCam[LastCamera].tz; + + CameraFOV[1] = SpotCam[LastCamera].fov; + CameraRoll[1] = SpotCam[LastCamera].roll; + CameraSpeed[1] = SpotCam[LastCamera].speed; + } + else + { + //loc_37AA8 + sp = 1; + if ((s->flags & SCF_CUT_PAN)) + { + CameraXposition[0] = SpotCam[CurrentSplineCamera].x; + CameraYposition[0] = SpotCam[CurrentSplineCamera].y; + CameraZposition[0] = SpotCam[CurrentSplineCamera].z; + + CameraXtarget[0] = SpotCam[CurrentSplineCamera].tx; + CameraYtarget[0] = SpotCam[CurrentSplineCamera].ty; + CameraZtarget[0] = SpotCam[CurrentSplineCamera].tz; + + CameraRoll[0] = SpotCam[CurrentSplineCamera].roll; + CameraFOV[0] = SpotCam[CurrentSplineCamera].fov; + CameraSpeed[0] = SpotCam[CurrentSplineCamera].speed; + + SplineFromCamera = 0; + + cn = CurrentSplineCamera; + while (sp < 4) + { + if (LastCamera < CurrentSplineCamera) + { + cn = FirstCamera; + } + + //loc_37B74 + CameraXposition[sp] = SpotCam[cn].x; + CameraYposition[sp] = SpotCam[cn].y; + CameraZposition[sp] = SpotCam[cn].z; + + CameraXtarget[sp] = SpotCam[cn].tx; + CameraYtarget[sp] = SpotCam[cn].ty; + CameraZtarget[sp] = SpotCam[cn].tz; + + CameraRoll[sp] = SpotCam[cn].roll; + CameraFOV[sp] = SpotCam[cn].fov; + CameraSpeed[sp] = SpotCam[cn].speed; + cn++; + sp++; + } + + CurrentSplineCamera++; + + if (CurrentSplineCamera > LastCamera) + { + CurrentSplineCamera = FirstCamera; + } + + if (s->flags & SCF_ACTIVATE_HEAVY_TRIGGERS) + { + CheckTrigger = true; + } + + if (s->flags & SCF_VIGNETTE) + { + /*if (s->timer < 0) + { + SCOverlay = 1; + }//loc_37C8C + else if (SlowMotion == 0) + { + SlowMotion = s->timer; + }*/ + } + + if (s->flags & SCF_HIDE_LARA) + { + SpotcamDontDrawLara = true; + } + else + { + QuakeCam.spos.boxNumber = 0; + return; + } + + } + else + { + cn = CurrentSplineCamera; + + CameraRoll[0] = 0; + CameraXposition[0] = InitialCameraPosition.x; + CameraYposition[0] = InitialCameraPosition.y; + CameraZposition[0] = InitialCameraPosition.z; + CameraXtarget[0] = InitialCameraTarget.x; + CameraYtarget[0] = InitialCameraTarget.y; + CameraZtarget[0] = InitialCameraTarget.z; + CameraFOV[0] = CurrentFOV; + + CameraXposition[1] = InitialCameraPosition.x; + CameraXtarget[1] = InitialCameraTarget.x; + CameraYposition[1] = InitialCameraPosition.y; + CameraZposition[1] = InitialCameraPosition.z; + CameraYtarget[1] = InitialCameraTarget.y; + CameraZtarget[1] = InitialCameraTarget.z; + CameraRoll[1] = 0; + CameraFOV[1] = 0; + + CameraSpeed[0] = s->speed; + CameraSpeed[1] = s->speed; + + CameraXposition[2] = SpotCam[CurrentSplineCamera].x; + CameraYposition[2] = SpotCam[CurrentSplineCamera].y; + CameraZposition[2] = SpotCam[CurrentSplineCamera].z; + + SplineFromCamera = 1; + + CameraXtarget[2] = SpotCam[CurrentSplineCamera].tx; + CameraYtarget[2] = SpotCam[CurrentSplineCamera].ty; + CameraZtarget[2] = SpotCam[CurrentSplineCamera].tz; + + CameraRoll[2] = SpotCam[CurrentSplineCamera].roll; + CameraFOV[2] = SpotCam[CurrentSplineCamera].fov; + + + CameraSpeed[2] = SpotCam[CurrentSplineCamera].speed; + + cn++; + + if (LastCamera < cn) + { + cn = FirstCamera; + } + + CameraXposition[3] = SpotCam[cn].x; + CameraYposition[3] = SpotCam[cn].y; + CameraZposition[3] = SpotCam[cn].z; + + CameraXtarget[3] = SpotCam[cn].tx; + CameraYtarget[3] = SpotCam[cn].ty; + CameraZtarget[3] = SpotCam[cn].tz; + + CameraRoll[3] = SpotCam[cn].roll; + CameraFOV[3] = SpotCam[cn].fov; + CameraSpeed[3] = SpotCam[cn].speed; + } + } + + if (s->flags & SCF_HIDE_LARA) + { + SpotcamDontDrawLara = true; + } + + QuakeCam.spos.boxNumber = 0; +} + +#ifdef OLD_CODE +void __cdecl CalculateSpotCameras() +{ + __int32 cpx; // stack offset -96 + __int32 cpy; // stack offset -92 + __int32 cpz; // stack offset -88 + __int32 ctx; // stack offset -84 + __int32 cty; // stack offset -80 + __int32 ctz; // stack offset -76 + __int32 cspeed; // stack offset -72 + __int32 cfov; // stack offset -68 + __int32 croll; // stack offset -64 + SPOTCAM* s; // stack offset -60 + __int16 spline_cnt; // $s3 + int next_spline_camera; // $s0 + int n; // $s5 + static int bFirstLook; // offset 0x18 dword_A0AC4? + __int32 dx; // $v1 + __int32 dy; // $s0 + __int32 dz; // $s1 + + //{ // line 76, offset 0x38114 + __int32 cs; // $s6 + __int32 sp; // $s2 + __int32 cp; // $fp + __int32 clen; // $s4 + __int32 tlen; // $v1 + __int32 cx; // $s1 + __int32 cy; // $s0 + __int32 cz; // $v0 + __int32 lx; // stack offset -56 + __int32 lz; // stack offset -52 + __int32 ly; // stack offset -48 + int i; // $v1 + int var_2C; + int ctype; // $s0 + int cn; // $s0 + + + CAMERA_INFO Backup; + + if (DisableLaraControl) + { + LaraItem->hitPoints = LaraHealth; + Lara.air = LaraAir; + } + + SPOTCAM* s = &SpotCam[FirstCamera]; + __int16 spline_cnt = 4; + + if ((s->flags & SCF_TRACKING_CAM)) + { + spline_cnt = CurrentCameraCnt + 2; + } + + //loc_37F64 + __int32 cpx = Spline(CurrentSplinePosition, &CameraXposition[0], spline_cnt); + __int32 cpy = Spline(CurrentSplinePosition, &CameraYposition[0], spline_cnt); + __int32 cpz = Spline(CurrentSplinePosition, &CameraZposition[0], spline_cnt); + + __int32 ctx = Spline(CurrentSplinePosition, &CameraXtarget[0], spline_cnt); + __int32 cty = Spline(CurrentSplinePosition, &CameraYtarget[0], spline_cnt); + __int32 ctz = Spline(CurrentSplinePosition, &CameraZtarget[0], spline_cnt); + + __int32 cspeed = Spline(CurrentSplinePosition, &CameraSpeed[0], spline_cnt); + __int32 croll = Spline(CurrentSplinePosition, &CameraRoll[0], spline_cnt); + __int32 cfov = Spline(CurrentSplinePosition, &CameraFOV[0], spline_cnt); + + if ((SpotCam[CurrentSplineCamera].flags & SCF_SCREEN_FADE_IN) && CameraFade != CurrentSplineCamera) + { + CameraFade = CurrentSplineCamera; + + /*if (gfCurrentLevel != LVL5_TITLE) + { + ScreenFadedOut = 0; + ScreenFade = 255; + dScreenFade = 0; + SetScreenFadeIn(16); + }*/ + }//loc_38084 + + if ((SpotCam[CurrentSplineCamera].flags & SCF_SCREEN_FADE_OUT) && CameraFade != CurrentSplineCamera) + { + CameraFade = CurrentSplineCamera; + + /*if (gfCurrentLevel != LVL5_TITLE) + { + ScreenFadedOut = 0; + ScreenFade = 0; + dScreenFade = 255; + SetScreenFadeOut(16, 0); + }*/ + } + + __int32 sp = 0; + __int32 tlen = 0; + __int32 clen = 0; + __int32 cp = 0; + __int32 temp = 0; + + if ((s->flags & SCF_TRACKING_CAM)) + { + lx = LaraItem->pos.xPos; + ly = LaraItem->pos.yPos; + lz = LaraItem->pos.zPos; + + for (__int32 i = 0; i < 8; i++) + { + clen = 0x10000; + + for (__int32 j = 0; j < 8; j++) + { + cx = Spline(sp, &CameraXposition[0], spline_cnt); + cy = Spline(sp, &CameraYposition[0], spline_cnt); + cz = Spline(sp, &CameraZposition[0], spline_cnt); + + dx = SQUARE(cx - lx); + dz = SQUARE(cz - lz); + dy = SQUARE(cy - ly); + + if (tlen <= clen) + { + cp = sp; + clen = tlen; + } + + sp += temp; + + if (sp > 0x10000) + break; + } + + temp >>= 1; + sp = cp - 2 * (temp & 0xFFFE); // << 2 ? + + if (sp < 0) + sp = 0; + } + + CurrentSplinePosition += (cp - CurrentSplinePosition) >> 5; + if ((s->flags & SCF_CUT_PAN)) + { + temp = cp - CurrentSplinePosition; + if (temp < 0) + { + temp = CurrentSplinePosition - cp; + } + if (temp > 0x8000) + CurrentSplinePosition = cp; + } + if (CurrentSplinePosition >= 0) + { + if (CurrentSplinePosition >= 0x8000) + { + CurrentSplinePosition = 0x10000; + } + } + else + { + CurrentSplinePosition = 0; + } + } + else if (!SpotcamTimer) + { + CurrentSplinePosition += cspeed; + } + + if (!(TrInput & IN_LOOK)) + { + Unk_0051D024 = 0; + } + + if (s->flags & SCF_DISABLE_BREAKOUT || !(TrInput & IN_LOOK) /*&& gfGameMode != 1*/) + { + Camera.pos.x = cpx; + Camera.pos.y = cpy; + Camera.pos.z = cpz; + + if ((s->flags & SCF_FOCUS_LARA_HEAD || s->flags & SCF_TRACKING_CAM)) + { + ctx = LaraItem->pos.xPos; + cty = LaraItem->pos.yPos; + ctz = LaraItem->pos.zPos; + } + + Camera.target.x = ctx; + Camera.target.y = cty; + Camera.target.z = ctz; + + IsRoomOutsideNo = -1; + IsRoomOutside(cpx, cpy, cpz); + if (IsRoomOutsideNo == -1) + { + Camera.pos.roomNumber = SpotCam[CurrentSplineCamera].roomNumber; + GetFloor(Camera.pos.x, Camera.pos.y, Camera.pos.z, &Camera.pos.roomNumber); + } + else + { + Camera.pos.roomNumber = IsRoomOutsideNo; + } + + AlterFOV(cfov); + + if (QuakeCam.spos.boxNumber != 0) + { + dx = (Camera.pos.x - QuakeCam.epos.x); + dy = (Camera.pos.y - QuakeCam.epos.y); + dz = (Camera.pos.z - QuakeCam.epos.z); + + if (SQRT_ASM(SQUARE(dx) * SQUARE(dy) * SQUARE(dz)) < QuakeCam.epos.boxNumber) + { + dz = QuakeCam.spos.roomNumber + (((QuakeCam.epos.roomNumber - QuakeCam.spos.roomNumber) * -QuakeCam.epos.boxNumber) / QuakeCam.epos.boxNumber) >> 1; + dy = QuakeCam.spos.roomNumber + (((QuakeCam.epos.roomNumber - QuakeCam.spos.roomNumber) * -QuakeCam.epos.boxNumber) / QuakeCam.epos.boxNumber); + if (dy > 0) + { + Camera.pos.x += (GetRandomControl() / dy) - dz; + Camera.pos.y += (GetRandomControl() / dy) - dz; + Camera.pos.z += (GetRandomControl() / dy) - dz; + } + } + } + + LookAt(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.target.x, Camera.target.y, Camera.target.z, 0); + + if (CheckTrigger) + { + CAMERA_TYPE oldType = Camera.type; + Camera.type = HEAVY_CAMERA; + if (CurrentLevel != 0) + { + TestTriggersAtXYZ(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.roomNumber, 1, 0); + } + else + { + TestTriggersAtXYZ(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.roomNumber, 0, 0); + TestTriggersAtXYZ(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.roomNumber, 1, 0); + } + Camera.type = oldType; + CheckTrigger = false; + } + + if (s->flags & SCF_TRACKING_CAM) + { + TrackCameraInit = true; + } + else + { + if (CurrentSplinePosition > 0x10000 - cspeed) + { + /*v25 = current_spline_camera; + v13 = 40 * current_spline_camera; + v26 = *(__int16 *)((char *)&SpotCam[0].flags + v13); + if ( v26 & 2 ) + { + if ( *(__int16 *)((char *)&SpotCam[0].timer + v13) >= 0 ) + { + if ( !SlowMotion ) + SlowMotion = *(__int16 *)((char *)&SpotCam[0].timer + v13); + } + else + { + SCOverlay = 1; + } + }*/ + if (SpotCam[CurrentSplineCamera].flags & SCF_HIDE_LARA) + SpotcamDontDrawLara = true; + if (SpotCam[CurrentSplineCamera].flags & SCF_ACTIVATE_HEAVY_TRIGGERS) + CheckTrigger = true; + + if (SpotCam[CurrentSplineCamera].flags & SCF_STOP_MOVEMENT) + { + if (QuakeCam.spos.boxNumber == 0 || SpotCam[CurrentSplineCamera].timer != -1) + { + QuakeCam.spos.x = SpotCam[CurrentSplineCamera].x; + QuakeCam.spos.y = SpotCam[CurrentSplineCamera].y; + QuakeCam.spos.z = SpotCam[CurrentSplineCamera].z; + + if (SpotCam[CurrentSplineCamera].timer != -1) + { + QuakeCam.spos.roomNumber = SpotCam[CurrentSplineCamera].timer << 3; + } + else + { + QuakeCam.spos.roomNumber = 0; + } + QuakeCam.spos.boxNumber = 1; + QuakeCam.epos.x = SpotCam[CurrentSplineCamera + 1].x; + QuakeCam.epos.y = SpotCam[CurrentSplineCamera + 1].y; + QuakeCam.epos.z = SpotCam[CurrentSplineCamera + 1].z; + + if (SpotCam[CurrentSplineCamera + 1].timer != -1) + { + QuakeCam.epos.roomNumber = SpotCam[CurrentSplineCamera + 1].timer << 3; + } + else + { + QuakeCam.epos.roomNumber = 0; + } + + QuakeCam.epos.boxNumber = SQRT_ASM(((QuakeCam.spos.x - QuakeCam.epos.x) * (QuakeCam.spos.x - QuakeCam.epos.x)) + ((QuakeCam.spos.y - QuakeCam.epos.y) * (QuakeCam.spos.y - QuakeCam.epos.y) + ((QuakeCam.spos.z - QuakeCam.epos.z) * (QuakeCam.spos.z - QuakeCam.epos.z)))); + } + else + { + QuakeCam.spos.boxNumber = 0; + } + } + + if (!SpotcamTimer) + { + CurrentSplinePosition = 0; + + if (CurrentSplineCamera != FirstCamera) + { + cn = CurrentSplineCamera - 1; + } + else + { + cn = LastCamera; + } + + if (SplineFromCamera != 0) + { + SplineFromCamera = 0; + cn = FirstCamera - 1; + } + else + { + if ((SpotCam[CurrentSplineCamera].flags & SCF_REENABLE_LARA_CONTROLS)) + { + DisableLaraControl = false; + } + + if ((SpotCam[CurrentSplineCamera].flags & SCF_DISABLE_LARA_CONTROLS)) + { + //SetFadeClip(16, 1); + DisableLaraControl = true; + } + + sp = 0; + + if ((SpotCam[CurrentSplineCamera].flags & SCF_CUT_TO_CAM)) + { + cn = (SpotCam[CurrentSplineCamera].timer & 0xF) + FirstCamera; + + CameraXposition[0] = SpotCam[cn].x; + CameraYposition[0] = SpotCam[cn].y; + CameraZposition[0] = SpotCam[cn].z; + CameraXtarget[0] = SpotCam[cn].tx; + CameraYtarget[0] = SpotCam[cn].ty; + CameraZtarget[0] = SpotCam[cn].tz; + CameraXtarget[0] = SpotCam[cn].tx; + CameraYtarget[0] = SpotCam[cn].ty; + CameraZtarget[0] = SpotCam[cn].tz; + CameraRoll[0] = SpotCam[cn].roll; + CameraFOV[0] = SpotCam[cn].fov; + sp = 1; + CurrentSplineCamera = cn; + CameraSpeed[0] = SpotCam[cn].speed; + } + + sp++; + + CameraXposition[sp] = SpotCam[cn].x; + CameraYposition[sp] = SpotCam[cn].y; + CameraZposition[sp] = SpotCam[cn].z; + CameraXtarget[sp] = SpotCam[cn].tx; + CameraYtarget[sp] = SpotCam[cn].ty; + CameraZtarget[sp] = SpotCam[cn].tz; + CameraRoll[sp] = SpotCam[cn].roll; + CameraFOV[sp] = SpotCam[cn].fov; + CameraSpeed[sp] = SpotCam[cn].speed; + } + + + } + } + } + } + else if (s->flags & SCF_TRACKING_CAM) + { + if (!Unk_0051D024) + { + Camera.oldType = FIXED_CAMERA; + Unk_0051D024 = true; + } + + CalculateCamera(); + } + else + { + UseSpotCam = false; + DisableLaraControl = false; + Camera.speed = 1; + AlterFOV(LastFOV); + CalculateCamera(); + CheckTrigger = false; + } + + + + + + + + + + + + + + + + + + + + if (s->flags & SCF_DISABLE_BREAKOUT || !(TrInput & IN_LOOK) /*&& gfGameMode != 1*/) + { + if ((s->flags & SCF_TRACKING_CAM)) + { + if (Unk_0051D024 == 0) + { + Camera.oldType = FIXED_CAMERA; + Unk_0051D024 = 1; + }//loc_3836C + + CalculateCamera(); + + return; + } + else + { + //loc_3837C + //SetFadeClip(0, 1); + UseSpotCam = 0; + //assert(0); + DisableLaraControl = 0; + Camera.speed = 1; + + AlterFOV(LastFOV); + CalculateCamera(); + CheckTrigger = 0; + + return; + } + } + //loc_383B4 + Camera.pos.x = cpx; + Camera.pos.y = cpy; + Camera.pos.z = cpz; + + if ((s->speed & 0x280000)) + { + ctx = LaraItem->pos.xPos; + cty = LaraItem->pos.yPos; + ctz = LaraItem->pos.zPos; + } + + //loc_38420 + Camera.target.x = ctx; + Camera.target.y = cty; + Camera.target.z = ctz; + + IsRoomOutsideNo = -1; + IsRoomOutside(cpx, cpy, cpz); + + if (IsRoomOutsideNo != -1)///@FIXME IsRoomOutsideNo bad value + { + Camera.pos.roomNumber = IsRoomOutsideNo; + } + else + { + //loc_38490 + Camera.pos.roomNumber = SpotCam[CurrentSplineCamera].roomNumber; + GetFloor(Camera.pos.x, Camera.pos.y, Camera.pos.z, &Camera.pos.roomNumber); + } + + //loc_384DC + AlterFOV(cfov); + + if (QuakeCam.spos.boxNumber != 0) + { + dx = (Camera.pos.x - QuakeCam.epos.x); + dy = (Camera.pos.y - QuakeCam.epos.y); + dz = (Camera.pos.z - QuakeCam.epos.z); + + + if (SQRT_ASM(dx * dy * dz) < QuakeCam.epos.boxNumber) + { + dz = QuakeCam.spos.roomNumber + (((QuakeCam.epos.roomNumber - QuakeCam.spos.roomNumber) * -QuakeCam.epos.boxNumber) / QuakeCam.epos.boxNumber) >> 1;//s1 + dy = QuakeCam.spos.roomNumber + (((QuakeCam.epos.roomNumber - QuakeCam.spos.roomNumber) * -QuakeCam.epos.boxNumber) / QuakeCam.epos.boxNumber);//s0 + if (dy > 0) + { + Camera.pos.x += (GetRandomControl() / dy) - dz; + Camera.pos.y += (GetRandomControl() / dy) - dz; + Camera.pos.z += (GetRandomControl() / dy) - dz; + }//loc_38650 + }//loc_38650 + }//loc_38650 + +#if PSXENGINE + LookAt(camera.pos.x, camera.pos.y, camera.pos.z, camera.target.x, camera.target.y, camera.target.z, croll); +#endif + + ///sp = s0 + if (CheckTrigger) + { + ctype = Camera.type; + Camera.type = HEAVY_CAMERA; + + /*if (gfCurrentLevel != LVL5_TITLE) + { + TestTriggersAtXYZ(camera.pos.x, camera.pos.y, camera.pos.z, camera.pos.roomNumber, 1, 0); + } + else + {*/ + //loc_38704 + TestTriggersAtXYZ(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.roomNumber, 0, 0); + TestTriggersAtXYZ(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.roomNumber, 1, 0); + //} + + Camera.type = (enum camera_type)ctype; + CheckTrigger = 0; + }//loc_3876C + + if ((s->flags & SCF_TRACKING_CAM)) + { + TrackCameraInit = 1; + return; + } + + if (0x10000 - cspeed >= CurrentSplinePosition) + { + return; + } + + if ((SpotCam[CurrentSplineCamera].flags & SCF_VIGNETTE)) + { + if (SpotCam[CurrentSplineCamera].timer < 0) + { + //SCOverlay = 1; + } + else + { + //loc_387F8 + /*if (SlowMotion == 0) + { + SlowMotion = 1; + }*/ + } + }//loc_38814 + + if ((SpotCam[CurrentSplineCamera].flags & SCF_HIDE_LARA)) + { + SpotcamDontDrawLara = 1; + } + //loc_38844 + + if ((SpotCam[CurrentSplineCamera].flags & SCF_ACTIVATE_HEAVY_TRIGGERS)) + { + CheckTrigger = 1; + } + + //loc_3885C + if ((SpotCam[CurrentSplineCamera].flags & SCF_STOP_MOVEMENT)) + { + if (QuakeCam.spos.boxNumber == 0 || SpotCam[CurrentSplineCamera].timer != -1) + { + //loc_38888 + QuakeCam.spos.x = SpotCam[CurrentSplineCamera].x; + QuakeCam.spos.y = SpotCam[CurrentSplineCamera].y; + QuakeCam.spos.z = SpotCam[CurrentSplineCamera].z; + + if (SpotCam[CurrentSplineCamera].timer != -1) + { + QuakeCam.spos.roomNumber = SpotCam[CurrentSplineCamera].timer << 3; + } + else + { + //loc_388C8 + QuakeCam.spos.roomNumber = 0; + } + //loc_388CC + QuakeCam.spos.boxNumber = 1; + QuakeCam.epos.x = SpotCam[CurrentSplineCamera + 1].x; + QuakeCam.epos.y = SpotCam[CurrentSplineCamera + 1].y; + QuakeCam.epos.z = SpotCam[CurrentSplineCamera + 1].z; + + if (SpotCam[CurrentSplineCamera + 1].timer != -1) + { + QuakeCam.epos.roomNumber = SpotCam[CurrentSplineCamera + 1].timer << 3; + } + else + { + //loc_3892C + QuakeCam.epos.roomNumber = 0; + } + + //loc_38930 + QuakeCam.epos.boxNumber = SQRT_ASM(((QuakeCam.spos.x - QuakeCam.epos.x) * (QuakeCam.spos.x - QuakeCam.epos.x)) + ((QuakeCam.spos.y - QuakeCam.epos.y) * (QuakeCam.spos.y - QuakeCam.epos.y) + ((QuakeCam.spos.z - QuakeCam.epos.z) * (QuakeCam.spos.z - QuakeCam.epos.z)))); + + } + else + { + //loc_38990 + QuakeCam.spos.boxNumber = 0; + } + } + + //loc_38994 + if (SpotcamTimer != 0) + { + return; + } + + CurrentSplinePosition = 0; + + if (CurrentSplineCamera != FirstCamera)///@FIXME CurrentSplineCamera bad value when switching + { + cn = CurrentSplineCamera - 1; + } + else + { + cn = LastCamera; + } + + //loc_389BC + if (SplineFromCamera != 0) + { + SplineFromCamera = 0; + cn = FirstCamera - 1; + } + else + { + if ((SpotCam[CurrentSplineCamera].flags & SCF_REENABLE_LARA_CONTROLS)) + { + DisableLaraControl = 0; + }//loc_38A0C + + if ((SpotCam[CurrentSplineCamera].flags & SCF_DISABLE_LARA_CONTROLS)) + { + //SetFadeClip(16, 1); + DisableLaraControl = 1; + } + //loc_38A24 + + sp = 0; + if ((SpotCam[CurrentSplineCamera].flags & SCF_CUT_TO_CAM)) + { + cn = (SpotCam[CurrentSplineCamera].timer & 0xF) + FirstCamera; + //v0 = SpotCam[cn] + CameraXposition[0] = SpotCam[cn].x; + CameraYposition[0] = SpotCam[cn].y; + CameraZposition[0] = SpotCam[cn].z; + CameraXtarget[0] = SpotCam[cn].tx; + CameraYtarget[0] = SpotCam[cn].ty; + CameraZtarget[0] = SpotCam[cn].tz; + CameraXtarget[0] = SpotCam[cn].tx; + CameraYtarget[0] = SpotCam[cn].ty; + CameraZtarget[0] = SpotCam[cn].tz; + CameraRoll[0] = SpotCam[cn].roll; + CameraFOV[0] = SpotCam[cn].fov; + sp = 1; + CurrentSplineCamera = cn; + CameraSpeed[0] = SpotCam[cn].speed; + }//loc_38B04 + + CameraXposition[sp] = SpotCam[cn].x; + CameraYposition[sp] = SpotCam[cn].y; + CameraZposition[sp] = SpotCam[cn].z; + CameraXtarget[sp] = SpotCam[cn].tx; + CameraYtarget[sp] = SpotCam[cn].ty; + CameraZtarget[sp] = SpotCam[cn].tz; + sp++; + CameraXtarget[sp] = SpotCam[cn].tx; + CameraYtarget[sp] = SpotCam[cn].ty; + CameraZtarget[sp] = SpotCam[cn].tz; + CameraRoll[sp] = SpotCam[cn].roll; + CameraFOV[sp] = SpotCam[cn].fov; + CameraSpeed[sp] = SpotCam[cn].speed; + } + + cn++; + if (sp < 4) + { + //loc_38BEC + while (sp < 4) + { + if ((s->flags & SCF_LOOP_SEQUENCE)) + { + if (LastCamera < cn) + { + cn = FirstCamera; + }//loc_38C2C + }//loc_38C18 + else + { + //loc_38C18 + if (LastCamera < cn) + { + cn = LastCamera; + }//loc_38C2C + } + + //loc_38C2C + CameraXposition[sp] = SpotCam[cn].x; + CameraYposition[sp] = SpotCam[cn].y; + CameraZposition[sp] = SpotCam[cn].z; + CameraXtarget[sp] = SpotCam[cn].tx; + CameraYtarget[sp] = SpotCam[cn].ty; + CameraZtarget[sp] = SpotCam[cn].tz; + CameraXtarget[sp] = SpotCam[cn].tx; + CameraYtarget[sp] = SpotCam[cn].ty; + CameraZtarget[sp] = SpotCam[cn].tz; + CameraRoll[sp] = SpotCam[cn].roll; + CameraFOV[sp] = SpotCam[cn].fov; + CameraSpeed[sp] = SpotCam[cn].speed; + cn++; + sp++; + } + }//loc_38CF4 + + printf("First: %d, Last: %d, Current: %d\n", FirstCamera, LastCamera, CurrentSplineCamera); + + if (LastCamera > ++CurrentSplineCamera) + { + return; + } + + if ((s->flags & SCF_LOOP_SEQUENCE)) + { + CurrentSplineCamera = FirstCamera; + SpotcamLoopCnt++; + return; + }//loc_38D50 + + if (!(s->flags & SCF_PAN_TO_LARA_CAM)) + { + //loc_38D50 + if (SplineToCamera == 0) + { + CameraXposition[0] = SpotCam[CurrentSplineCamera - 1].x; + CameraYposition[0] = SpotCam[CurrentSplineCamera - 1].y; + CameraZposition[0] = SpotCam[CurrentSplineCamera - 1].z; + CameraXtarget[0] = SpotCam[CurrentSplineCamera - 1].tx; + CameraYtarget[0] = SpotCam[CurrentSplineCamera - 1].ty; + CameraZtarget[0] = SpotCam[CurrentSplineCamera - 1].tz; + CameraXtarget[0] = SpotCam[CurrentSplineCamera - 1].tx; + CameraYtarget[0] = SpotCam[CurrentSplineCamera - 1].ty; + CameraZtarget[0] = SpotCam[CurrentSplineCamera - 1].tz; + CameraRoll[0] = SpotCam[CurrentSplineCamera - 1].roll; + CameraFOV[0] = SpotCam[CurrentSplineCamera - 1].fov; + CameraSpeed[0] = SpotCam[CurrentSplineCamera - 1].speed; + + CameraXposition[1] = SpotCam[CurrentSplineCamera].x; + CameraYposition[1] = SpotCam[CurrentSplineCamera].y; + CameraZposition[1] = SpotCam[CurrentSplineCamera].z; + CurrentSplineCamera = CurrentSplineCamera;///? + CameraXtarget[1] = SpotCam[CurrentSplineCamera].tx; + CameraYtarget[1] = SpotCam[CurrentSplineCamera].ty; + CameraZtarget[1] = SpotCam[CurrentSplineCamera].tz; + CameraXtarget[1] = SpotCam[CurrentSplineCamera].tx; + CameraYtarget[1] = SpotCam[CurrentSplineCamera].ty; + CameraZtarget[1] = SpotCam[CurrentSplineCamera].tz; + CameraRoll[1] = SpotCam[CurrentSplineCamera].roll; + CameraFOV[1] = SpotCam[CurrentSplineCamera].fov; + CameraSpeed[1] = SpotCam[CurrentSplineCamera].speed; + + memcpy((char*)&Backup, (char*)&Camera, sizeof(CAMERA_INFO)); + Camera.oldType = FIXED_CAMERA; + Camera.type = CHASE_CAMERA; + Camera.speed = 1; + + CalculateCamera(); + //a0 = &camera; + //a1 = &Backup; + + CameraRoll[2] = 0; + CameraRoll[3] = 0; + CameraSpeed[2] = CameraSpeed[1]; + + InitialCameraPosition.x = Camera.pos.x; + InitialCameraPosition.y = Camera.pos.y; + InitialCameraPosition.z = Camera.pos.z; + + InitialCameraTarget.x = Camera.target.x; + InitialCameraTarget.y = Camera.target.y; + InitialCameraTarget.z = Camera.target.z; + + CameraXposition[2] = Camera.pos.x; + CameraYposition[2] = Camera.pos.y; + CameraZposition[2] = Camera.pos.z; + CameraXtarget[2] = Camera.target.x; + CameraYtarget[2] = Camera.target.y; + CameraZtarget[2] = Camera.target.z; + CameraFOV[2] = CurrentFOV; + + CameraXposition[3] = Camera.pos.x; + CameraYposition[3] = Camera.pos.y; + CameraZposition[3] = Camera.pos.z; + CameraXtarget[3] = Camera.target.x; + CameraYtarget[3] = Camera.target.y; + CameraZtarget[3] = Camera.target.z; + CameraFOV[3] = CurrentFOV; + CameraSpeed[3] = CameraSpeed[1] >> 1; + + memcpy((char*)&Camera, (char*)&Backup, sizeof(CAMERA_INFO)); +#if PSXENGINE + LookAt(camera.pos.x, camera.pos.y, camera.pos.z, camera.target.x, camera.target.y, camera.target.z, 0); +#endif + SplineToCamera = 1; + return; + } + }//loc_38FE0 + + if (CheckTrigger) + { + ctype = Camera.type; + Camera.type = HEAVY_CAMERA; + + /*if (gfCurrentLevel != LVL5_TITLE) + { + TestTriggersAtXYZ(camera.pos.x, camera.pos.y, camera.pos.z, camera.pos.roomNumber, 1, 0); + }//loc_39044 + else + {*/ + TestTriggersAtXYZ(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.roomNumber, 0, 0); + TestTriggersAtXYZ(Camera.pos.x, Camera.pos.y, Camera.pos.z, Camera.pos.roomNumber, 1, 0); + //} + + //loc_390A0 + Camera.type = (enum camera_type)ctype; + + CheckTrigger = 0; + } + + //loc_390AC + //SetFadeClip(0, 1); + + Camera.oldType = FIXED_CAMERA; + Camera.type = CHASE_CAMERA; + Camera.speed = 1; + UseSpotCam = 0; + DisableLaraControl = 0; + CheckTrigger = 0; + + if ((s->flags & SCF_PAN_TO_LARA_CAM)) + { + Camera.pos.x = InitialCameraPosition.x; + Camera.pos.y = InitialCameraPosition.y; + Camera.pos.z = InitialCameraPosition.z; + + Camera.target.x = InitialCameraTarget.x; + Camera.target.y = InitialCameraTarget.y; + Camera.target.z = InitialCameraTarget.z; + + Camera.pos.roomNumber = InitialCameraRoom; + } + + //loc_39148 + //SCOverlay = 0; + SpotcamDontDrawLara = 0; + cfov = LastFOV; + AlterFOV(LastFOV); +} +#endif + +/*void __cdecl CalculateSpotCameras() +{ + +}*/ + +void __cdecl Inject_Spotcam() +{ + INJECT(0x0047A800, InitSpotCamSequences); + //INJECT(0x0047A9D0, InitialiseSpotCam); + //INJECT(0x0047B280, CalculateSpotCameras); +} \ No newline at end of file diff --git a/TR5Main/Game/spotcam.h b/TR5Main/Game/spotcam.h index d1eb06c9f..39247d97a 100644 --- a/TR5Main/Game/spotcam.h +++ b/TR5Main/Game/spotcam.h @@ -1,6 +1,33 @@ #pragma once -#define InitSpotCamSequences ((void (__cdecl*)()) 0x0047A800) +enum spotcam_flags +{ + SCF_CUT_PAN = (1 << 0), // 0x0001 cut without panning smoothly + SCF_VIGNETTE = (1 << 1), // 0x0002 + SCF_LOOP_SEQUENCE = (1 << 2), // 0x0004 + SCF_TRACKING_CAM = (1 << 3), // 0x0008 + SCF_HIDE_LARA = (1 << 4), // 0x0010 + SCF_FOCUS_LARA_HEAD = (1 << 5), // 0x0020 + SCF_PAN_TO_LARA_CAM = (1 << 6), // 0x0040 + SCF_CUT_TO_CAM = (1 << 7), // 0x0080 + SCF_STOP_MOVEMENT = (1 << 8), // 0x0100 stops movement for a given time (cf. `Timer` field) + SCF_DISABLE_BREAKOUT = (1 << 9), // 0x0200 disables breaking out from cutscene using Look key + SCF_DISABLE_LARA_CONTROLS = (1 << 10), // 0x0400 also adds widescreen bars + SCF_REENABLE_LARA_CONTROLS = (1 << 11), // 0x0800 use with 0x0400, keeps widescreen bars + SCF_SCREEN_FADE_IN = (1 << 12), // 0x1000 + SCF_SCREEN_FADE_OUT = (1 << 13), // 0x2000 + SCF_ACTIVATE_HEAVY_TRIGGERS = (1 << 14), // 0x4000 when camera is moving above heavy trigger sector, it'll be activated + SCF_CAMERA_ONE_SHOT = (1 << 15), // 0x8000 +}; + +//#define InitSpotCamSequences ((void (__cdecl*)()) 0x0047A800) #define CalculateSpotCameras ((void (__cdecl*)()) 0x0047B280) -#define InitialiseSpotCameras ((void (__cdecl*)(__int16)) 0x0047A9D0) -#define TriggerTitleSpotcam ((void (__cdecl*)(__int32)) 0x004284A0) \ No newline at end of file +//#define InitialiseSpotCam ((void (__cdecl*)(__int16)) 0x0047A9D0) +#define TriggerTitleSpotcam ((void (__cdecl*)(__int32)) 0x004284A0) +#define Spline ((__int32 (__cdecl*)(__int32, __int32*, __int32)) 0x0047A890) + +void __cdecl InitSpotCamSequences(); +void __cdecl InitialiseSpotCam(__int16 sequence); +//void __cdecl CalculateSpotCameras(); + +void __cdecl Inject_Spotcam(); \ No newline at end of file diff --git a/TR5Main/Global/types.h b/TR5Main/Global/types.h index 8a224af8d..acac3c840 100644 --- a/TR5Main/Global/types.h +++ b/TR5Main/Global/types.h @@ -1375,6 +1375,11 @@ typedef struct BOUNDING_BOX { __int16 Z2; }; +struct QUAKE_CAMERA { + GAME_VECTOR spos; + GAME_VECTOR epos; +}; + typedef void (cdecl *EFFECT_ROUTINE)(ITEM_INFO*); typedef void (cdecl *LARA_COLLISION_ROUTINE)(ITEM_INFO*, COLL_INFO*); typedef void (cdecl *LARA_CONTROL_ROUTINE)(ITEM_INFO*, COLL_INFO*); diff --git a/TR5Main/Global/vars.h b/TR5Main/Global/vars.h index 4f1db532c..fb367b58e 100644 --- a/TR5Main/Global/vars.h +++ b/TR5Main/Global/vars.h @@ -72,7 +72,6 @@ #define CutSeqTriggered VAR_U_(0x0051CAAC, __int32) #define GlobalPlayingCutscene VAR_U_(0x0051CAB0, __int32) #define Wibble VAR_U_(0x0051CDF0, __int32) -#define CdFlags ARRAY_(0x00EEEA40, byte, [136]) #define DbInput VAR_U_(0x00878DAC, __int32) #define TrInput VAR_U_(0x00878D98, __int32) #define MatrixStack ARRAY_(0x0055D66C, __int32, [480]) @@ -85,8 +84,6 @@ #define SamplePointer ARRAY_(0x0086BEF0, HSAMPLE, [SOUND_MAX_SAMPLES]) #define SoundSlot ARRAY_(0x00E52430, SoundEffectSlot, [SOUND_MAX_CHANNELS]) #define TrackNamePrefix VAR_U_(0x00511828, char) -#define TrackNameTable ARRAY_(0x005108C0, char*, [SOUND_LEGACY_TRACKTABLE_SIZE]) -#define TrackMap ARRAY_(0x00EEEA40, byte, [SOUND_LEGACY_TRACKTABLE_SIZE]) #define IsAtmospherePlaying VAR_U_(0x00EEEFFC, byte) #define CurrentAtmosphere VAR_U_(0x00EEEB90, byte) #define GlobalMusicVolume VAR_U_(0x00517B68, unsigned int) @@ -259,6 +256,36 @@ #define KeyboardLayout1 ARRAY_(0x00516C60, __int16, [18]) #define KeyMap ARRAY_(0x0086BB8C, byte, [256]) #define ConflictingKeys ARRAY_(0x00878C4C, byte, [256]) +#define LastSequence VAR_U_(0x00E51F2C, __int16) +#define SpotcamTimer VAR_U_(0x0051D00C, __int16) +#define SpotcamLoopCnt VAR_U_(0x00E4F488, __int16) +#define LaraAir VAR_U_(0x00E4F6A8, __int32) +#define LaraHealth VAR_U_(0x00E51F20, __int32) +#define CameraFade VAR_U_(0x00E4F36C, __int32) +#define LaraFixedPosition VAR_U_(0x00E4F360, PHD_VECTOR) +#define InitialCameraRoom VAR_U_(0x00E4F588, __int16) +#define LastFOV VAR_U_(0x00E4F506, __int16) +#define InitialCameraPosition VAR_U_(0x00E4F3D0, PHD_VECTOR) +#define InitialCameraTarget VAR_U_(0x00E4F350, PHD_VECTOR) +#define CurrentSequence VAR_U_(0x00E4F502, __int16) +#define CurrentSplinePosition VAR_U_(0x00E51F28, __int32) +#define SplineToCamera VAR_U_(0x00E4F48C, __int32) +#define FirstCamera VAR_U_(0x00E51F24, __int16) +#define LastCamera VAR_U_(0x00E4F6AC, __int16) +#define CurrentCameraCnt VAR_U_(0x00E4EAA0, __int32) +#define CameraXposition ARRAY_(0x00E4F440, __int32, [18]) +#define CameraYposition ARRAY_(0x00E4F600, __int32, [18]) +#define CameraZposition ARRAY_(0x00E4F540, __int32, [18]) +#define CameraXtarget ARRAY_(0x00E4F3E0, __int32, [18]) +#define CameraYtarget ARRAY_(0x00E51EC0, __int32, [18]) +#define CameraZtarget ARRAY_(0x00E4F5A0, __int32, [18]) +#define CameraRoll ARRAY_(0x00E4F4A0, __int32, [18]) +#define CameraFOV ARRAY_(0x00E4F380, __int32, [18]) +#define CameraSpeed ARRAY_(0x00E4F660, __int32, [18]) +#define SpotcamDontDrawLara VAR_U_(0x0051D021, byte) +#define QuakeCam VAR_U_(0x00E4F520, QUAKE_CAMERA) +#define SplineFromCamera VAR_U_(0x00E4F3DC, __int32) +#define Unk_0051D024 VAR_U_(0x0051D024, byte) extern bool MonksAttackLara; diff --git a/TR5Main/Renderer/Renderer11.cpp b/TR5Main/Renderer/Renderer11.cpp index 989d81cec..4e7fde5eb 100644 --- a/TR5Main/Renderer/Renderer11.cpp +++ b/TR5Main/Renderer/Renderer11.cpp @@ -440,7 +440,7 @@ bool Renderer11::Initialise(__int32 w, __int32 h, __int32 refreshRate, bool wind return false; } - m_titleScreen = Texture2D::LoadFromFile(m_device, "Screens\\Title.jpg"); + m_titleScreen = Texture2D::LoadFromFile(m_device, (char*)g_GameFlow->GetLevel(0)->Background.c_str()); if (m_titleScreen == NULL) return false; @@ -600,8 +600,12 @@ void Renderer11::UpdateCameraMatrices(float posX, float posY, float posZ, float { g_Configuration.MaxDrawDistance = 200; + Vector3 up = -Vector3::UnitY; + Matrix upRotation = Matrix::CreateFromYawPitchRoll(0.0f, 0.0f, roll); + up = Vector3::Transform(up, upRotation); + FieldOfView = fov; - View = Matrix::CreateLookAt(Vector3(posX, posY, posZ), Vector3(targetX, targetY, targetZ), -Vector3::UnitY); + View = Matrix::CreateLookAt(Vector3(posX, posY, posZ), Vector3(targetX, targetY, targetZ), up); Projection = Matrix::CreatePerspectiveFieldOfView(fov, ScreenWidth / (float)ScreenHeight, 20.0f, g_Configuration.MaxDrawDistance * 1024.0f); m_stCameraMatrices.View = View; @@ -635,7 +639,7 @@ bool Renderer11::drawHorizonAndSky() return true; if (BinocularRange) - phd_AlterFOV(14560 - BinocularRange); + AlterFOV(14560 - BinocularRange); // Storm if (level->Storm) @@ -1181,7 +1185,7 @@ bool Renderer11::drawItems(bool transparent, bool animated) bool Renderer11::drawLara(bool transparent, bool shadowMap) { // Don't draw Lara if binoculars or sniper - if (BinocularRange || SpotcamOverlay || SpotcamDontDrawLara) + if (BinocularRange || SpotcamOverlay || SpotcamDontDrawLara || CurrentLevel == 0) return true; UINT stride = sizeof(RendererVertex); @@ -1493,6 +1497,8 @@ __int32 Renderer11::DumpGameScene() __int32 Renderer11::DrawInventory() { + if (CurrentLevel == 0 && g_GameFlow->TitleType == TITLE_FLYBY) + drawScene(true); drawInventoryScene(); drawFinalPass(); @@ -5573,7 +5579,10 @@ __int32 Renderer11::drawInventoryScene() // Clear the Z-Buffer after drawing the background if (g_Inventory->GetType() == INV_TYPE_TITLE) { - drawFullScreenQuad(m_titleScreen->ShaderResourceView, Vector3(m_fadeFactor, m_fadeFactor, m_fadeFactor), false); + if (g_GameFlow->TitleType == TITLE_BACKGROUND) + drawFullScreenQuad(m_titleScreen->ShaderResourceView, Vector3(m_fadeFactor, m_fadeFactor, m_fadeFactor), false); + else + drawFullScreenQuad(m_dumpScreenRenderTarget->ShaderResourceView, Vector3(1.0f, 1.0f, 1.0f), false); } else { @@ -5627,16 +5636,19 @@ __int32 Renderer11::drawInventoryScene() objectIndex = ring->currentObject; // Yellow title - if (ring->focusState == INV_FOCUS_STATE_NONE) + if (ring->focusState == INV_FOCUS_STATE_NONE && g_Inventory->GetType() != INV_TYPE_TITLE) PrintString(400, 20, g_GameFlow->GetString(activeRing->titleStringIndex), PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER); for (__int32 i = 0; i < numObjects; i++) { __int16 inventoryObject = ring->objects[objectIndex].inventoryObject; __int16 objectNumber = g_Inventory->GetInventoryObject(ring->objects[objectIndex].inventoryObject)->objectNumber; - + + //if (ring->focusState != INV_FOCUS_STATE_NONE && (k != g_Inventory->GetActiveRing() || inventoryObject != ring->objects[i].inventoryObject)) + // continue; + // Calculate the inventory object position and rotation - float currentAngle = 0.0f; + float currentAngle = 0.0f; __int16 steps = -objectIndex + ring->currentObject; if (steps < 0) steps += numObjects; currentAngle = steps * deltaAngle; @@ -7059,7 +7071,7 @@ bool Renderer11::drawShadowMap() bool Renderer11::DoTitleImage() { - Texture2D* texture = Texture2D::LoadFromFile(m_device, (char*)"Title.png"); + Texture2D* texture = Texture2D::LoadFromFile(m_device, (char*)g_GameFlow->Intro); if (!texture) return false; diff --git a/TR5Main/Scripting/GameFlowScript.cpp b/TR5Main/Scripting/GameFlowScript.cpp index 50a0a89a8..9fe11ed94 100644 --- a/TR5Main/Scripting/GameFlowScript.cpp +++ b/TR5Main/Scripting/GameFlowScript.cpp @@ -20,9 +20,13 @@ ChunkId* ChunkGameFlowLevelLayer = ChunkId::FromString("Tr5MainLevelLayer"); ChunkId* ChunkGameFlowLevelLuaEvent = ChunkId::FromString("Tr5MainLevelLuaEvent"); ChunkId* ChunkGameFlowLevelLegend = ChunkId::FromString("Tr5MainLevelLegend"); ChunkId* ChunkGameFlowStrings = ChunkId::FromString("Tr5MainStrings"); +ChunkId* ChunkGameFlowAudioTracks = ChunkId::FromString("Tr5MainAudioTracks"); +ChunkId* ChunkGameFlowTitleBackground = ChunkId::FromString("Tr5MainTitleBackground"); ChunkReader* g_ScriptChunkIO; +extern vector g_AudioTracks; + GameFlow::GameFlow(sol::state* lua) { m_lua = lua; @@ -105,7 +109,11 @@ bool __cdecl readGameFlowFlags() g_GameFlow->FlyCheat = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); g_GameFlow->DebugMode = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); g_GameFlow->LevelFarView = LEB128::ReadInt32(g_ScriptChunkIO->GetRawStream()); - g_GameFlow->TitleType = LEB128::ReadInt32(g_ScriptChunkIO->GetRawStream()); + //g_GameFlow->TitleType = LEB128::ReadInt32(g_ScriptChunkIO->GetRawStream()); + + char* str; + g_ScriptChunkIO->GetRawStream()->ReadString(&str); + g_GameFlow->Intro = str; return true; } @@ -117,8 +125,8 @@ bool __cdecl readGameFlowStrings() LanguageScript* lang = new LanguageScript(name); free(name); - int numStrings = LEB128::ReadUInt32(g_ScriptChunkIO->GetRawStream()); - for (int i = 0; i < numStrings; i++) + __int32 numStrings = LEB128::ReadUInt32(g_ScriptChunkIO->GetRawStream()); + for (__int32 i = 0; i < numStrings; i++) { char* str; g_ScriptChunkIO->GetRawStream()->ReadString(&str); @@ -131,6 +139,23 @@ bool __cdecl readGameFlowStrings() return true; } +bool __cdecl readGameFlowTracks() +{ + __int32 numTracks = LEB128::ReadUInt32(g_ScriptChunkIO->GetRawStream()); + for (__int32 i = 0; i < numTracks; i++) + { + char* str; + g_ScriptChunkIO->GetRawStream()->ReadString(&str); + + AudioTrack track; + track.Name = str; + track.Mask = 0; + g_AudioTracks.push_back(track); + } + + return true; +} + bool __cdecl readGameFlowLevelChunks(ChunkId* chunkId, __int32 maxSize, __int32 arg) { GameScriptLevel* level = g_GameFlow->Levels[arg]; @@ -147,6 +172,10 @@ bool __cdecl readGameFlowLevelChunks(ChunkId* chunkId, __int32 maxSize, __int32 level->LoadScreenFileName = string(str); free(str); + g_ScriptChunkIO->GetRawStream()->ReadString(&str); + level->Background = str; + free(str); + level->NameStringIndex = LEB128::ReadUInt32(g_ScriptChunkIO->GetRawStream()); level->Soundtrack = LEB128::ReadUInt32(g_ScriptChunkIO->GetRawStream()); @@ -165,7 +194,7 @@ bool __cdecl readGameFlowLevelChunks(ChunkId* chunkId, __int32 maxSize, __int32 level->Rumble = LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); level->Weather = (WEATHER_TYPES)LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); level->UnlimitedAir = (WEATHER_TYPES)LEB128::ReadByte(g_ScriptChunkIO->GetRawStream()); - + return true; } else if (chunkId->EqualsTo(ChunkGameFlowLevelPuzzle)) @@ -273,6 +302,8 @@ bool __cdecl readGameFlowChunks(ChunkId* chunkId, __int32 maxSize, __int32 arg) return readGameFlowFlags(); else if (chunkId->EqualsTo(ChunkGameFlowStrings)) return readGameFlowStrings(); + else if (chunkId->EqualsTo(ChunkGameFlowAudioTracks)) + return readGameFlowTracks(); else if (chunkId->EqualsTo(ChunkGameFlowLevel)) return readGameFlowLevel(); return false; @@ -406,6 +437,8 @@ bool GameFlow::DoGameflow() // We loop indefinitely, looking for return values of DoTitle or DoLevel bool loadFromSavegame = false; + //DoLevel(0, 120, false); + while (true) { // First we need to fill some legacy variables in PCTomb5.exe diff --git a/TR5Main/Scripting/GameFlowScript.h b/TR5Main/Scripting/GameFlowScript.h index df4d2b9d9..422ec52ae 100644 --- a/TR5Main/Scripting/GameFlowScript.h +++ b/TR5Main/Scripting/GameFlowScript.h @@ -141,6 +141,7 @@ bool __cdecl readGameFlowLevelChunks(ChunkId* chunkId, __int32 maxSize, __int32 bool __cdecl readGameFlowChunks(ChunkId* chunkId, __int32 maxSize, __int32 arg); bool __cdecl readGameFlowLevel(); bool __cdecl readGameFlowStrings(); +bool __cdecl readGameFlowTracks(); bool __cdecl readGameFlowFlags(); bool __cdecl LoadScript(); @@ -172,6 +173,7 @@ public: bool DebugMode; __int32 LevelFarView; __int32 TitleType; + char* Intro; // Selected language set LanguageScript* CurrentStrings; diff --git a/TR5Main/dllmain.cpp b/TR5Main/dllmain.cpp index 44fd8ecfd..682a0dccd 100644 Binary files a/TR5Main/dllmain.cpp and b/TR5Main/dllmain.cpp differ