Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 85 additions & 4 deletions src/animation/CutsceneMgr.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#include "common.h"

#include "crossplatform.h"
#include "General.h"
#include "CutsceneMgr.h"
#include "Game.h"
#include "Directory.h"
#include "Camera.h"
#include "Streaming.h"
Expand All @@ -22,6 +24,7 @@
#include "ColStore.h"
#include "Radar.h"
#include "Pools.h"
#include "Timer.h"

const struct {
const char *szTrackName;
Expand Down Expand Up @@ -129,6 +132,12 @@ float CCutsceneMgr::ms_cutsceneTimer;
bool CCutsceneMgr::ms_wasCutsceneSkipped;
uint32 CCutsceneMgr::ms_cutsceneLoadStatus;
bool CCutsceneMgr::ms_useCutsceneShadows = true;
bool CCutsceneMgr::ms_cutsceneHasMusic;
bool CCutsceneMgr::ms_cutsceneMusicNeedsResume;
bool CCutsceneMgr::ms_wasWindowPaused;
uint32 CCutsceneMgr::ms_cutsceneMusicResumeFrames;

static const uint32 CUTSCENE_MUSIC_RESUME_RETRY_FRAMES = 60;

bool bCamLoaded;
bool bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver; // pls don't shrink the name :P
Expand Down Expand Up @@ -164,6 +173,10 @@ CCutsceneMgr::Initialise(void)
ms_useLodMultiplier = false;
ms_animLoaded = false;
ms_cutsceneProcessing = false;
ms_cutsceneHasMusic = false;
ms_cutsceneMusicNeedsResume = false;
ms_wasWindowPaused = false;
ms_cutsceneMusicResumeFrames = 0;

ms_pCutsceneDir = new CDirectory(CUTSCENEDIRSIZE);
ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR");
Expand All @@ -188,6 +201,10 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)

ms_cutsceneProcessing = true;
ms_wasCutsceneSkipped = false;
ms_cutsceneHasMusic = false;
ms_cutsceneMusicNeedsResume = false;
ms_wasWindowPaused = false;
ms_cutsceneMusicResumeFrames = 0;
CTimer::Suspend();
if (!bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver)
CStreaming::RemoveCurrentZonesModels();
Expand Down Expand Up @@ -241,6 +258,7 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName)
printf("Start preload audio %s\n", szCutsceneName);
DMAudio.PreloadCutSceneMusic(trackId);
printf("End preload audio %s\n", szCutsceneName);
ms_cutsceneHasMusic = true;
}
}

Expand Down Expand Up @@ -271,6 +289,37 @@ CCutsceneMgr::FinishCutscene()
CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(false);
}

void
CCutsceneMgr::RecordWindowPause(void)
{
if (IsActiveOrLoadingForPause()) {
ms_wasWindowPaused = true;
ms_cutsceneMusicNeedsResume = ms_cutsceneMusicNeedsResume ||
(ms_cutsceneHasMusic && (ms_cutsceneLoadStatus != 0 || DMAudio.IsCutSceneMusicPlaying()));
ms_cutsceneMusicResumeFrames = CUTSCENE_MUSIC_RESUME_RETRY_FRAMES;
}
}

bool
CCutsceneMgr::SyncCutsceneToMusic(void)
{
if (!ms_cutsceneHasMusic || !bCamLoaded)
return false;

uint32 finishTime = TheCamera.GetCutSceneFinishTime();
if (finishTime == 0)
return false;

int32 musicPosition = DMAudio.GetCutSceneMusicPosition();
if (musicPosition < 0)
return false;

uint32 clampedPosition = musicPosition > (int32)finishTime ? finishTime : musicPosition;
TheCamera.SetPercentAlongCutScene(100.0f * (float)clampedPosition / (float)finishTime);
ms_cutsceneTimer = clampedPosition * 0.001f;
return true;
}

void
CCutsceneMgr::SetupCutsceneToStart(void)
{
Expand Down Expand Up @@ -452,6 +501,10 @@ CCutsceneMgr::DeleteCutsceneData(void)
}
ms_running = false;
ms_loaded = false;
ms_cutsceneHasMusic = false;
ms_cutsceneMusicNeedsResume = false;
ms_wasWindowPaused = false;
ms_cutsceneMusicResumeFrames = 0;

FindPlayerPed()->bIsVisible = true;
CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_CUTSCENE);
Expand Down Expand Up @@ -506,10 +559,17 @@ CCutsceneMgr::Update(void)
CUTSCENE_LOADING_4
};

if (CGame::IsWindowPauseMenuActive() || CTimer::GetIsWindowMinimizedPaused() || psRefreshAndGetWindowMinimizedPause()) {
RecordWindowPause();
CTimer::SetTimeStep(0.0f);
CTimer::SetTimeStepNonClipped(0.0f);
return;
}

switch (ms_cutsceneLoadStatus) {
case CUTSCENE_LOADING_AUDIO:
SetupCutsceneToStart();
if (CGeneral::faststricmp(ms_cutsceneName, "finale"))
if (ms_cutsceneHasMusic)
DMAudio.PlayPreloadedCutSceneMusic();
ms_cutsceneLoadStatus++;
break;
Expand All @@ -526,7 +586,28 @@ CCutsceneMgr::Update(void)

if (!ms_running) return;

ms_cutsceneTimer += CTimer::GetTimeStepNonClippedInSeconds();
bool syncedToMusic = false;
if (ms_wasWindowPaused) {
if (ms_cutsceneMusicNeedsResume) {
DMAudio.ResumeCutSceneMusicAfterPause();
syncedToMusic = SyncCutsceneToMusic();
if (!syncedToMusic && ms_cutsceneMusicResumeFrames != 0 && TheCamera.GetCutSceneFinishTime() != 0) {
--ms_cutsceneMusicResumeFrames;
CTimer::SetTimeStep(0.0f);
CTimer::SetTimeStepNonClipped(0.0f);
return;
}
}
ms_wasWindowPaused = false;
ms_cutsceneMusicNeedsResume = false;
ms_cutsceneMusicResumeFrames = 0;
}

if (!syncedToMusic)
syncedToMusic = SyncCutsceneToMusic();

if (!syncedToMusic)
ms_cutsceneTimer += CTimer::GetTimeStepNonClippedInSeconds();

for (int i = 0; i < ms_numCutsceneObjs; i++) {
int modelId = ms_pCutsceneObjects[i]->GetModelIndex();
Expand All @@ -548,7 +629,7 @@ CCutsceneMgr::Update(void)
}
}

bool CCutsceneMgr::HasCutsceneFinished(void) { return !bCamLoaded || TheCamera.GetPositionAlongSpline() == 1.0f; }
bool CCutsceneMgr::HasCutsceneFinished(void) { return !bCamLoaded || TheCamera.GetPositionAlongSpline() >= 1.0f; }

void
CCutsceneMgr::LoadAnimationUncompressed(char const* name)
Expand Down Expand Up @@ -680,4 +761,4 @@ CCutsceneMgr::RemoveEverythingFromTheWorldForTheBiggestFuckoffCutsceneEver()

pPlayerPed->ClearWeapons();
CGame::DrasticTidyUpMemory(true);
}
}
7 changes: 7 additions & 0 deletions src/animation/CutsceneMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ class CCutsceneMgr
static bool ms_wasCutsceneSkipped;
static bool ms_cutsceneProcessing;
static bool ms_useCutsceneShadows;
static bool ms_cutsceneHasMusic;
static bool ms_cutsceneMusicNeedsResume;
static bool ms_wasWindowPaused;
static uint32 ms_cutsceneMusicResumeFrames;
static bool SyncCutsceneToMusic(void);
public:
static CDirectory *ms_pCutsceneDir;
static uint32 ms_cutsceneLoadStatus;
Expand All @@ -32,6 +37,7 @@ class CCutsceneMgr
static bool IsRunning(void) { return ms_running; }
static bool HasLoaded(void) { return ms_loaded; }
static bool IsCutsceneProcessing(void) { return ms_cutsceneProcessing; }
static bool IsActiveOrLoadingForPause(void) { return ms_running || ms_cutsceneProcessing || ms_loaded || ms_cutsceneLoadStatus != 0; }
static bool WasCutsceneSkipped(void) { return ms_wasCutsceneSkipped; }
static bool UseLodMultiplier(void) { return ms_useLodMultiplier; }
static CCutsceneObject* GetCutsceneObject(int id) { return ms_pCutsceneObjects[id]; }
Expand All @@ -44,6 +50,7 @@ class CCutsceneMgr
static void Shutdown(void);
static void LoadCutsceneData(const char *szCutsceneName);
static void FinishCutscene(void);
static void RecordWindowPause(void);
static void SetupCutsceneToStart(void);
static void SetCutsceneAnim(const char *animName, CObject *pObject);
static void SetCutsceneAnimToLoop(const char *animName);
Expand Down
82 changes: 58 additions & 24 deletions src/audio/AudioLogic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9841,8 +9841,16 @@ cAudioManager::ProcessMissionAudioSlot(uint8 slot)
static uint8 nCheckPlayingDelay[MISSION_AUDIO_SLOTS] = { 0, 0 };
static uint8 nFramesUntilFailedLoad[MISSION_AUDIO_SLOTS] = { 0, 0 };
static uint8 nFramesForPretendPlaying[MISSION_AUDIO_SLOTS] = { 0, 0 };
static uint8 nFramesUntilFailedResume[MISSION_AUDIO_SLOTS] = { 0, 0 };
const uint8 RESUME_RETRY_FRAMES = 60;

if (m_sMissionAudio.m_nSampleIndex[slot] == NO_SAMPLE) return;
if (m_sMissionAudio.m_nSampleIndex[slot] == NO_SAMPLE) {
nCheckPlayingDelay[slot] = 0;
nFramesUntilFailedLoad[slot] = 0;
nFramesForPretendPlaying[slot] = 0;
nFramesUntilFailedResume[slot] = 0;
return;
}

switch (m_sMissionAudio.m_nLoadingStatus[slot]) {
case LOADING_STATUS_NOT_LOADED:
Expand All @@ -9860,6 +9868,7 @@ cAudioManager::ProcessMissionAudioSlot(uint8 slot)
nFramesForPretendPlaying[slot] = 0;
nCheckPlayingDelay[slot] = 0;
nFramesUntilFailedLoad[slot] = 0;
nFramesUntilFailedResume[slot] = 0;
} else if (!m_nUserPause) {
if (++nFramesForPretendPlaying[slot] < 90) {
m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_PLAYING;
Expand All @@ -9872,11 +9881,12 @@ cAudioManager::ProcessMissionAudioSlot(uint8 slot)
}
switch (m_sMissionAudio.m_nPlayStatus[slot]) {
case PLAY_STATUS_STOPPED:
if (m_nUserPause)
break;

if (MissionScriptAudioUsesPoliceChannel(m_sMissionAudio.m_nSampleIndex[slot])) {
SetMissionScriptPoliceAudio(m_sMissionAudio.m_nSampleIndex[slot]);
} else {
if (m_nUserPause)
SampleManager.PauseStream(1, slot + 1);
if (m_sMissionAudio.m_bPredefinedProperties[slot]) {
if (m_sMissionAudio.m_nSampleIndex[slot] == STREAMED_SOUND_MISSION_CAMERAL)
SampleManager.SetStreamedVolumeAndPan(80, 0, 1, slot + 1);
Expand Down Expand Up @@ -9904,17 +9914,24 @@ cAudioManager::ProcessMissionAudioSlot(uint8 slot)
}
m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_PLAYING;
nCheckPlayingDelay[slot] = 30;
nFramesUntilFailedResume[slot] = 0;
if (m_sMissionAudio.m_nSampleIndex[slot] >= STREAMED_SOUND_MISSION_MOB_01A && m_sMissionAudio.m_nSampleIndex[slot] <= STREAMED_SOUND_MISSION_MOB_99A)
m_sMissionAudio.m_bIsMobile[slot] = true;
break;
case PLAY_STATUS_PLAYING:
if (m_bTimerJustReset) {
ClearMissionAudio(slot);
SampleManager.StopStreamedFile(slot + 1);
nFramesUntilFailedResume[slot] = 0;
break;
}
if (MissionScriptAudioUsesPoliceChannel(m_sMissionAudio.m_nSampleIndex[slot])) {
if (!m_nUserPause) {
if (m_nUserPause) {
SampleManager.PauseStream(1, 1);
nFramesUntilFailedResume[slot] = 0;
} else {
if (m_nPreviousUserPause)
SampleManager.PauseStream(0, 1);
if (nCheckPlayingDelay[slot]) {
--nCheckPlayingDelay[slot];
} else if (GetMissionScriptPoliceAudioPlayingStatus() == PLAY_STATUS_FINISHED || m_sMissionAudio.m_nMissionAudioCounter[slot]-- == 0) {
Expand All @@ -9924,30 +9941,37 @@ cAudioManager::ProcessMissionAudioSlot(uint8 slot)
m_sMissionAudio.m_nMissionAudioCounter[slot] = 0;
}
}
} else if (m_nUserPause) {
SampleManager.PauseStream(1, slot + 1);
nFramesUntilFailedResume[slot] = 0;
} else if (m_sMissionAudio.m_bIsPlaying[slot]) {
if (m_nPreviousUserPause) {
SampleManager.PauseStream(0, slot + 1);
nFramesUntilFailedResume[slot] = RESUME_RETRY_FRAMES;
}
if (SampleManager.IsStreamPlaying(slot + 1) || m_nUserPause || m_nPreviousUserPause) {
if (m_nUserPause)
SampleManager.PauseStream(1, slot + 1);
else
{
SampleManager.PauseStream(0, slot + 1);
if (!m_sMissionAudio.m_bPredefinedProperties[slot]) {
distSquared = GetDistanceSquared(m_sMissionAudio.m_vecPos[slot]);
if (distSquared >= SQR(80.0f)) {
emittingVol = 0;
pan = 63;
} else {
emittingVol = 127;
if (distSquared > 0.0f) {
dist = Sqrt(distSquared);
emittingVol = ComputeVolume(127, 80.0f, dist);
}
TranslateEntity(&m_sMissionAudio.m_vecPos[slot], &vec);
pan = ComputePan(80.f, &vec);
if (SampleManager.IsStreamPlaying(slot + 1))
nFramesUntilFailedResume[slot] = 0;
if (!m_sMissionAudio.m_bPredefinedProperties[slot]) {
distSquared = GetDistanceSquared(m_sMissionAudio.m_vecPos[slot]);
if (distSquared >= SQR(80.0f)) {
emittingVol = 0;
pan = 63;
} else {
emittingVol = 127;
if (distSquared > 0.0f) {
dist = Sqrt(distSquared);
emittingVol = ComputeVolume(127, 80.0f, dist);
}
SampleManager.SetStreamedVolumeAndPan(emittingVol, pan, 1, slot + 1);
TranslateEntity(&m_sMissionAudio.m_vecPos[slot], &vec);
pan = ComputePan(80.f, &vec);
}
SampleManager.SetStreamedVolumeAndPan(emittingVol, pan, 1, slot + 1);
}
} else if (nFramesUntilFailedResume[slot]) {
SampleManager.PauseStream(0, slot + 1);
SampleManager.StartPreloadedStreamedFile(slot + 1);
--nFramesUntilFailedResume[slot];
} else if (m_sMissionAudio.m_nSampleIndex[slot] == STREAMED_SOUND_MISSION_ROK2_01) {
m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_STOPPED;
} else {
Expand All @@ -9957,15 +9981,25 @@ cAudioManager::ProcessMissionAudioSlot(uint8 slot)
m_sMissionAudio.m_nSampleIndex[slot] = NO_SAMPLE;
SampleManager.StopStreamedFile(slot + 1);
m_sMissionAudio.m_nMissionAudioCounter[slot] = 0;
nFramesUntilFailedResume[slot] = 0;
}
} else {
if (m_nUserPause)
break;
if (nCheckPlayingDelay[slot]--) {
if (m_nPreviousUserPause) {
SampleManager.PauseStream(0, slot + 1);
if (!SampleManager.IsStreamPlaying(slot + 1))
SampleManager.StartPreloadedStreamedFile(slot + 1);
nFramesUntilFailedResume[slot] = RESUME_RETRY_FRAMES;
}
if (nCheckPlayingDelay[slot]) {
--nCheckPlayingDelay[slot];
if (!SampleManager.IsStreamPlaying(slot + 1))
break;
nCheckPlayingDelay[slot] = 0;
}
if (SampleManager.IsStreamPlaying(slot + 1))
nFramesUntilFailedResume[slot] = 0;
m_sMissionAudio.m_bIsPlaying[slot] = true;
}
break;
Expand Down
Loading