diff options
Diffstat (limited to 'src/animation/CutsceneMgr.cpp')
-rw-r--r-- | src/animation/CutsceneMgr.cpp | 533 |
1 files changed, 397 insertions, 136 deletions
diff --git a/src/animation/CutsceneMgr.cpp b/src/animation/CutsceneMgr.cpp index 83c4dbcb..b312236b 100644 --- a/src/animation/CutsceneMgr.cpp +++ b/src/animation/CutsceneMgr.cpp @@ -16,94 +16,94 @@ #include "World.h" #include "PlayerPed.h" #include "Wanted.h" -#include "CutsceneHead.h" #include "RpAnimBlend.h" #include "ModelIndices.h" #include "TempColModels.h" +#include "ColStore.h" +#include "Radar.h" +#include "Pools.h" + +//--MIAMI: file done const struct { const char *szTrackName; int iTrackId; } musicNameIdAssoc[] = { - { "JB", STREAMED_SOUND_NEWS_INTRO }, - { "BET", STREAMED_SOUND_BANK_INTRO }, - { "L1_LG", STREAMED_SOUND_CUTSCENE_LUIGI1_LG }, - { "L2_DSB", STREAMED_SOUND_CUTSCENE_LUIGI2_DSB }, - { "L3_DM", STREAMED_SOUND_CUTSCENE_LUIGI3_DM }, - { "L4_PAP", STREAMED_SOUND_CUTSCENE_LUIGI4_PAP }, - { "L5_TFB", STREAMED_SOUND_CUTSCENE_LUIGI5_TFB }, - { "J0_DM2", STREAMED_SOUND_CUTSCENE_JOEY0_DM2 }, - { "J1_LFL", STREAMED_SOUND_CUTSCENE_JOEY1_LFL }, - { "J2_KCL", STREAMED_SOUND_CUTSCENE_JOEY2_KCL }, - { "J3_VH", STREAMED_SOUND_CUTSCENE_JOEY3_VH }, - { "J4_ETH", STREAMED_SOUND_CUTSCENE_JOEY4_ETH }, - { "J5_DST", STREAMED_SOUND_CUTSCENE_JOEY5_DST }, - { "J6_TBJ", STREAMED_SOUND_CUTSCENE_JOEY6_TBJ }, - { "T1_TOL", STREAMED_SOUND_CUTSCENE_TONI1_TOL }, - { "T2_TPU", STREAMED_SOUND_CUTSCENE_TONI2_TPU }, - { "T3_MAS", STREAMED_SOUND_CUTSCENE_TONI3_MAS }, - { "T4_TAT", STREAMED_SOUND_CUTSCENE_TONI4_TAT }, - { "T5_BF", STREAMED_SOUND_CUTSCENE_TONI5_BF }, - { "S0_MAS", STREAMED_SOUND_CUTSCENE_SAL0_MAS }, - { "S1_PF", STREAMED_SOUND_CUTSCENE_SAL1_PF }, - { "S2_CTG", STREAMED_SOUND_CUTSCENE_SAL2_CTG }, - { "S3_RTC", STREAMED_SOUND_CUTSCENE_SAL3_RTC }, - { "S5_LRQ", STREAMED_SOUND_CUTSCENE_SAL5_LRQ }, - { "S4_BDBA", STREAMED_SOUND_CUTSCENE_SAL4_BDBA }, - { "S4_BDBB", STREAMED_SOUND_CUTSCENE_SAL4_BDBB }, - { "S2_CTG2", STREAMED_SOUND_CUTSCENE_SAL2_CTG2 }, - { "S4_BDBD", STREAMED_SOUND_CUTSCENE_SAL4_BDBD }, - { "S5_LRQB", STREAMED_SOUND_CUTSCENE_SAL5_LRQB }, - { "S5_LRQC", STREAMED_SOUND_CUTSCENE_SAL5_LRQC }, - { "A1_SS0", STREAMED_SOUND_CUTSCENE_ASUKA_1_SSO }, - { "A2_PP", STREAMED_SOUND_CUTSCENE_ASUKA_2_PP }, - { "A3_SS", STREAMED_SOUND_CUTSCENE_ASUKA_3_SS }, - { "A4_PDR", STREAMED_SOUND_CUTSCENE_ASUKA_4_PDR }, - { "A5_K2FT", STREAMED_SOUND_CUTSCENE_ASUKA_5_K2FT}, - { "K1_KBO", STREAMED_SOUND_CUTSCENE_KENJI1_KBO }, - { "K2_GIS", STREAMED_SOUND_CUTSCENE_KENJI2_GIS }, - { "K3_DS", STREAMED_SOUND_CUTSCENE_KENJI3_DS }, - { "K4_SHI", STREAMED_SOUND_CUTSCENE_KENJI4_SHI }, - { "K5_SD", STREAMED_SOUND_CUTSCENE_KENJI5_SD }, - { "R0_PDR2", STREAMED_SOUND_CUTSCENE_RAY0_PDR2 }, - { "R1_SW", STREAMED_SOUND_CUTSCENE_RAY1_SW }, - { "R2_AP", STREAMED_SOUND_CUTSCENE_RAY2_AP }, - { "R3_ED", STREAMED_SOUND_CUTSCENE_RAY3_ED }, - { "R4_GF", STREAMED_SOUND_CUTSCENE_RAY4_GF }, - { "R5_PB", STREAMED_SOUND_CUTSCENE_RAY5_PB }, - { "R6_MM", STREAMED_SOUND_CUTSCENE_RAY6_MM }, - { "D1_STOG", STREAMED_SOUND_CUTSCENE_DONALD1_STOG }, - { "D2_KK", STREAMED_SOUND_CUTSCENE_DONALD2_KK }, - { "D3_ADO", STREAMED_SOUND_CUTSCENE_DONALD3_ADO }, - { "D5_ES", STREAMED_SOUND_CUTSCENE_DONALD5_ES }, - { "D7_MLD", STREAMED_SOUND_CUTSCENE_DONALD7_MLD }, - { "D4_GTA", STREAMED_SOUND_CUTSCENE_DONALD4_GTA }, - { "D4_GTA2", STREAMED_SOUND_CUTSCENE_DONALD4_GTA2 }, - { "D6_STS", STREAMED_SOUND_CUTSCENE_DONALD6_STS }, - { "A6_BAIT", STREAMED_SOUND_CUTSCENE_ASUKA6_BAIT }, - { "A7_ETG", STREAMED_SOUND_CUTSCENE_ASUKA7_ETG }, - { "A8_PS", STREAMED_SOUND_CUTSCENE_ASUKA8_PS }, - { "A9_ASD", STREAMED_SOUND_CUTSCENE_ASUKA9_ASD }, - { "K4_SHI2", STREAMED_SOUND_CUTSCENE_KENJI4_SHI2 }, - { "C1_TEX", STREAMED_SOUND_CUTSCENE_CATALINA1_TEX }, - { "EL_PH1", STREAMED_SOUND_CUTSCENE_ELBURRO1_PH1 }, - { "EL_PH2", STREAMED_SOUND_CUTSCENE_ELBURRO2_PH2 }, - { "EL_PH3", STREAMED_SOUND_CUTSCENE_ELBURRO3_PH3 }, - { "EL_PH4", STREAMED_SOUND_CUTSCENE_ELBURRO4_PH4 }, - { "YD_PH1", STREAMED_SOUND_CUTSCENE_YARDIE_PH1 }, - { "YD_PH2", STREAMED_SOUND_CUTSCENE_YARDIE_PH2 }, - { "YD_PH3", STREAMED_SOUND_CUTSCENE_YARDIE_PH3 }, - { "YD_PH4", STREAMED_SOUND_CUTSCENE_YARDIE_PH4 }, - { "HD_PH1", STREAMED_SOUND_CUTSCENE_HOODS_PH1 }, - { "HD_PH2", STREAMED_SOUND_CUTSCENE_HOODS_PH2 }, - { "HD_PH3", STREAMED_SOUND_CUTSCENE_HOODS_PH3 }, - { "HD_PH4", STREAMED_SOUND_CUTSCENE_HOODS_PH4 }, - { "HD_PH5", STREAMED_SOUND_CUTSCENE_HOODS_PH5 }, - { "MT_PH1", STREAMED_SOUND_CUTSCENE_MARTY_PH1 }, - { "MT_PH2", STREAMED_SOUND_CUTSCENE_MARTY_PH2 }, - { "MT_PH3", STREAMED_SOUND_CUTSCENE_MARTY_PH3 }, - { "MT_PH4", STREAMED_SOUND_CUTSCENE_MARTY_PH4 }, - { NULL, 0 } + { "ASS_1", STREAMED_SOUND_CUTSCENE_ASS_1 }, + { "ASS_2", STREAMED_SOUND_CUTSCENE_ASS_2 }, + { "BANK_1", STREAMED_SOUND_CUTSCENE_BANK_1 }, + { "BANK_2A", STREAMED_SOUND_CUTSCENE_BANK_2A }, + { "BANK_2B", STREAMED_SOUND_CUTSCENE_BANK_2B }, + { "BANK_3A", STREAMED_SOUND_CUTSCENE_BANK_3A }, + { "BANK_3B", STREAMED_SOUND_CUTSCENE_BANK_3B }, + { "BANK_4", STREAMED_SOUND_CUTSCENE_BANK_4 }, + { "BIKE_1", STREAMED_SOUND_CUTSCENE_BIKE_1 }, + { "BIKE_2", STREAMED_SOUND_CUTSCENE_BIKE_2 }, + { "BIKE_3", STREAMED_SOUND_CUTSCENE_BIKE_3 }, + { "BUD_1", STREAMED_SOUND_CUTSCENE_BUD_1 }, + { "BUD_2", STREAMED_SOUND_CUTSCENE_BUD_2 }, + { "BUD_3", STREAMED_SOUND_CUTSCENE_BUD_3 }, + { "CAP_1", STREAMED_SOUND_CUTSCENE_CAP_1 }, + { "CAR_1", STREAMED_SOUND_CUTSCENE_CAR_1 }, + { "CNT_1A", STREAMED_SOUND_CUTSCENE_CNT_1A }, + { "CNT_1B", STREAMED_SOUND_CUTSCENE_CNT_1B }, + { "CNT_2", STREAMED_SOUND_CUTSCENE_CNT_2 }, + { "COK_1", STREAMED_SOUND_CUTSCENE_COK_1 }, + { "COK_2A", STREAMED_SOUND_CUTSCENE_COK_2A }, + { "COK_2B", STREAMED_SOUND_CUTSCENE_COK_2B }, + { "COK_3", STREAMED_SOUND_CUTSCENE_COK_3 }, + { "COK_4A", STREAMED_SOUND_CUTSCENE_COK_4A }, + { "COK_4A2", STREAMED_SOUND_CUTSCENE_COK_4A2 }, + { "COK_4B", STREAMED_SOUND_CUTSCENE_COK_4B }, + { "COL_1", STREAMED_SOUND_CUTSCENE_COL_1 }, + { "COL_2", STREAMED_SOUND_CUTSCENE_COL_2 }, + { "COL_3A", STREAMED_SOUND_CUTSCENE_COL_3A }, + { "COL_4A", STREAMED_SOUND_CUTSCENE_COL_4A }, + { "COL_5A", STREAMED_SOUND_CUTSCENE_COL_5A }, + { "COL_5B", STREAMED_SOUND_CUTSCENE_COL_5B }, + { "CUB_1", STREAMED_SOUND_CUTSCENE_CUB_1 }, + { "CUB_2", STREAMED_SOUND_CUTSCENE_CUB_2 }, + { "CUB_3", STREAMED_SOUND_CUTSCENE_CUB_3 }, + { "CUB_4", STREAMED_SOUND_CUTSCENE_CUB_4 }, + { "DRUG_1", STREAMED_SOUND_CUTSCENE_DRUG_1 }, + { "FIN", STREAMED_SOUND_CUTSCENE_FIN }, + { "FIN_2", STREAMED_SOUND_CUTSCENE_FIN2 }, + { "FINALE", STREAMED_SOUND_CUTSCENE_FINALE }, + { "HAT_1", STREAMED_SOUND_CUTSCENE_HAT_1 }, + { "HAT_2", STREAMED_SOUND_CUTSCENE_HAT_2 }, + { "HAT_3", STREAMED_SOUND_CUTSCENE_HAT_3 }, + { "ICE_1", STREAMED_SOUND_CUTSCENE_ICE_1 }, + { "INT_A", STREAMED_SOUND_CUTSCENE_INT_A }, + { "INT_B", STREAMED_SOUND_CUTSCENE_INT_B }, + { "INT_D", STREAMED_SOUND_CUTSCENE_INT_D }, + { "INT_M", STREAMED_SOUND_CUTSCENE_INT_M }, + { "LAW_1A", STREAMED_SOUND_CUTSCENE_LAW_1A }, + { "LAW_1B", STREAMED_SOUND_CUTSCENE_LAW_1B }, + { "LAW_2A", STREAMED_SOUND_CUTSCENE_LAW_2A }, + { "LAW_2B", STREAMED_SOUND_CUTSCENE_LAW_2B }, + { "LAW_2C", STREAMED_SOUND_CUTSCENE_LAW_2C }, + { "LAW_3", STREAMED_SOUND_CUTSCENE_LAW_3 }, + { "LAW_4", STREAMED_SOUND_CUTSCENE_LAW_4 }, + { "PHIL_1", STREAMED_SOUND_CUTSCENE_PHIL_1 }, + { "PHIL_2", STREAMED_SOUND_CUTSCENE_PHIL_2 }, + { "PORN_1", STREAMED_SOUND_CUTSCENE_PORN_1 }, + { "PORN_2", STREAMED_SOUND_CUTSCENE_PORN_2 }, + { "PORN_3", STREAMED_SOUND_CUTSCENE_PORN_3 }, + { "PORN_4", STREAMED_SOUND_CUTSCENE_PORN_4 }, + { "RESC_1A", STREAMED_SOUND_CUTSCENE_RESC_1A }, + { "ROK_1", STREAMED_SOUND_CUTSCENE_ROK_1 }, + { "ROK_2", STREAMED_SOUND_CUTSCENE_ROK_2 }, + { "ROK_3A", STREAMED_SOUND_CUTSCENE_ROK_3A }, + { "STRIPA", STREAMED_SOUND_CUTSCENE_STRIPA }, + { "TAX_1", STREAMED_SOUND_CUTSCENE_TAX_1 }, + { "TEX_1", STREAMED_SOUND_CUTSCENE_TEX_1 }, + { "TEX_2", STREAMED_SOUND_CUTSCENE_TEX_2 }, + { "TEX_3", STREAMED_SOUND_CUTSCENE_TEX_3 }, + { "GSPOT", STREAMED_SOUND_CUTSCENE_GLIGHT }, + { "FIST", STREAMED_SOUND_CUTSCENE_FIST }, + { "EL_PH1", STREAMED_SOUND_CUTSCENE_ELBURRO1_PH1 }, + { "EL_PH2", STREAMED_SOUND_CUTSCENE_ELBURRO2_PH2 }, + { NULL, 0 } }; int @@ -128,7 +128,18 @@ char CCutsceneMgr::ms_cutsceneName[CUTSCENENAMESIZE]; CAnimBlendAssocGroup CCutsceneMgr::ms_cutsceneAssociations; CVector CCutsceneMgr::ms_cutsceneOffset; float CCutsceneMgr::ms_cutsceneTimer; +bool CCutsceneMgr::ms_wasCutsceneSkipped; uint32 CCutsceneMgr::ms_cutsceneLoadStatus; +bool CCutsceneMgr::ms_useCutsceneShadows = true; + +bool bCamLoaded; +bool bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver; // pls don't shrink the name :P +int32 NumberOfSavedWeapons; +eWeaponType SavedWeaponIDs[TOTAL_WEAPON_SLOTS]; +int32 SavedWeaponAmmo[TOTAL_WEAPON_SLOTS]; +char uncompressedAnims[8][32]; +uint32 numUncompressedAnims; + RpAtomic * CalculateBoundingSphereRadiusCB(RpAtomic *atomic, void *data) @@ -150,13 +161,17 @@ CCutsceneMgr::Initialise(void) { ms_numCutsceneObjs = 0; ms_loaded = false; + ms_wasCutsceneSkipped = false; ms_running = false; + ms_useLodMultiplier = false; ms_animLoaded = false; ms_cutsceneProcessing = false; - ms_useLodMultiplier = false; ms_pCutsceneDir = new CDirectory(CUTSCENEDIRSIZE); ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR"); + + numUncompressedAnims = 0; + uncompressedAnims[0][0] = '\0'; } void @@ -174,9 +189,10 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName) CPlayerPed *pPlayerPed; ms_cutsceneProcessing = true; - if (!strcasecmp(szCutsceneName, "jb")) - ms_useLodMultiplier = true; - CTimer::Stop(); + ms_wasCutsceneSkipped = false; + CTimer::Suspend(); + if (!bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver) + CStreaming::RemoveCurrentZonesModels(); ms_pCutsceneDir->numEntries = 0; ms_pCutsceneDir->ReadDirFile("ANIM\\CUTS.DIR"); @@ -185,32 +201,42 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName) CGame::DrasticTidyUpMemory(true); strcpy(ms_cutsceneName, szCutsceneName); - file = CFileMgr::OpenFile("ANIM\\CUTS.IMG", "rb"); + + RwStream *stream; + stream = RwStreamOpen(rwSTREAMFILENAME, rwSTREAMREAD, "ANIM\\CUTS.IMG"); + assert(stream); // Load animations sprintf(gString, "%s.IFP", szCutsceneName); if (ms_pCutsceneDir->FindItem(gString, offset, size)) { CStreaming::MakeSpaceFor(size << 11); CStreaming::ImGonnaUseStreamingMemory(); - CFileMgr::Seek(file, offset << 11, SEEK_SET); - CAnimManager::LoadAnimFile(file, false); + RwStreamSkip(stream, offset << 11); + CAnimManager::LoadAnimFile(stream, true, uncompressedAnims); ms_cutsceneAssociations.CreateAssociations(szCutsceneName); CStreaming::IHaveUsedStreamingMemory(); ms_animLoaded = true; } else { ms_animLoaded = false; } + RwStreamClose(stream, nil); // Load camera data + file = CFileMgr::OpenFile("ANIM\\CUTS.IMG", "rb"); sprintf(gString, "%s.DAT", szCutsceneName); if (ms_pCutsceneDir->FindItem(gString, offset, size)) { + CStreaming::ImGonnaUseStreamingMemory(); CFileMgr::Seek(file, offset << 11, SEEK_SET); TheCamera.LoadPathSplines(file); + CStreaming::IHaveUsedStreamingMemory(); + bCamLoaded = true; + } else { + bCamLoaded = false; } CFileMgr::CloseFile(file); - if (CGeneral::faststricmp(ms_cutsceneName, "end")) { + if (CGeneral::faststricmp(ms_cutsceneName, "finale")) { DMAudio.ChangeMusicMode(MUSICMODE_CUTSCENE); int trackId = FindCutsceneAudioTrackId(szCutsceneName); if (trackId != -1) { @@ -225,30 +251,23 @@ CCutsceneMgr::LoadCutsceneData(const char *szCutsceneName) ms_cutsceneOffset = CVector(0.0f, 0.0f, 0.0f); pPlayerPed = FindPlayerPed(); - CTimer::Update(); - pPlayerPed->m_pWanted->ClearQdCrimes(); pPlayerPed->bIsVisible = false; pPlayerPed->m_fCurrentStamina = pPlayerPed->m_fMaxStamina; CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_CUTSCENE); CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(true); -} - -void -CCutsceneMgr::SetHeadAnim(const char *animName, CObject *pObject) -{ - CCutsceneHead *pCutsceneHead = (CCutsceneHead*)pObject; - char szAnim[CUTSCENENAMESIZE * 2]; - sprintf(szAnim, "%s_%s", ms_cutsceneName, animName); - pCutsceneHead->PlayAnimation(szAnim); + CTimer::Resume(); } void CCutsceneMgr::FinishCutscene() { - CCutsceneMgr::ms_cutsceneTimer = TheCamera.GetCutSceneFinishTime() * 0.001f; - TheCamera.FinishCutscene(); + ms_wasCutsceneSkipped = true; + if (bCamLoaded) { + CCutsceneMgr::ms_cutsceneTimer = TheCamera.GetCutSceneFinishTime() * 0.001f; + TheCamera.FinishCutscene(); + } FindPlayerPed()->bIsVisible = true; CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(false); @@ -257,9 +276,11 @@ CCutsceneMgr::FinishCutscene() void CCutsceneMgr::SetupCutsceneToStart(void) { - TheCamera.SetCamCutSceneOffSet(ms_cutsceneOffset); - TheCamera.TakeControlWithSpline(JUMP_CUT); - TheCamera.SetWideScreenOn(); + if (bCamLoaded) { + TheCamera.SetCamCutSceneOffSet(ms_cutsceneOffset); + TheCamera.TakeControlWithSpline(JUMP_CUT); + TheCamera.SetWideScreenOn(); + } ms_cutsceneOffset.z++; @@ -267,12 +288,27 @@ CCutsceneMgr::SetupCutsceneToStart(void) assert(RwObjectGetType(ms_pCutsceneObjects[i]->m_rwObject) == rpCLUMP); if (CAnimBlendAssociation *pAnimBlendAssoc = RpAnimBlendClumpGetFirstAssociation((RpClump*)ms_pCutsceneObjects[i]->m_rwObject)) { assert(pAnimBlendAssoc->hierarchy->sequences[0].HasTranslation()); - ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0))->translation); - CWorld::Add(ms_pCutsceneObjects[i]); + if (ms_pCutsceneObjects[i]->m_pAttachTo != nil) { + pAnimBlendAssoc->flags &= (~ASSOC_HAS_TRANSLATION); + } else { + if (pAnimBlendAssoc->hierarchy->IsCompressed()){ + KeyFrameTransCompressed *keyFrames = ((KeyFrameTransCompressed*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrameCompressed(0)); + CVector trans; + keyFrames->GetTranslation(&trans); + ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + trans); + }else{ + KeyFrameTrans *keyFrames = ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0)); + ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + keyFrames->translation); + } + } pAnimBlendAssoc->SetRun(); } else { ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset); } + CWorld::Add(ms_pCutsceneObjects[i]); + if (RwObjectGetType(ms_pCutsceneObjects[i]->m_rwObject) == rpCLUMP) { + ms_pCutsceneObjects[i]->UpdateRpHAnim(); + } } CTimer::Update(); @@ -288,25 +324,55 @@ CCutsceneMgr::SetCutsceneAnim(const char *animName, CObject *pObject) CAnimBlendClumpData *pAnimBlendClumpData; assert(RwObjectGetType(pObject->m_rwObject) == rpCLUMP); + debug("Give cutscene anim %s\n", animName); RpAnimBlendClumpRemoveAllAssociations((RpClump*)pObject->m_rwObject); + pNewAnim = ms_cutsceneAssociations.GetAnimation(animName); + if (!pNewAnim) { + debug("\n\nHaven't I told you I can't find the fucking animation %s\n\n\n", animName); + return; + } + + if (pNewAnim->hierarchy->IsCompressed()) + pNewAnim->hierarchy->keepCompressed = true; + + CStreaming::ImGonnaUseStreamingMemory(); pNewAnim = ms_cutsceneAssociations.CopyAnimation(animName); + CStreaming::IHaveUsedStreamingMemory(); + pNewAnim->SetCurrentTime(0.0f); pNewAnim->flags |= ASSOC_HAS_TRANSLATION; pNewAnim->flags &= ~ASSOC_RUNNING; pAnimBlendClumpData = *RPANIMBLENDCLUMPDATA(pObject->m_rwObject); pAnimBlendClumpData->link.Prepend(&pNewAnim->link); + + if (pNewAnim->hierarchy->keepCompressed) + pAnimBlendClumpData->frames->flag |= AnimBlendFrameData::COMPRESSED; +} + +void +CCutsceneMgr::SetCutsceneAnimToLoop(const char* animName) +{ + ms_cutsceneAssociations.GetAnimation(animName)->flags |= ASSOC_REPEAT; } CCutsceneHead * CCutsceneMgr::AddCutsceneHead(CObject *pObject, int modelId) { - CCutsceneHead *pHead = new CCutsceneHead(pObject); - pHead->SetModelIndex(modelId); - CWorld::Add(pHead); - ms_pCutsceneObjects[ms_numCutsceneObjs++] = pHead; - return pHead; + return nil; +} + +void UpdateCutsceneObjectBoundingBox(RpClump* clump, int modelId) +{ + if (modelId >= MI_CUTOBJ01 && modelId <= MI_CUTOBJ05) { + CColModel* pColModel = &CTempColModels::ms_colModelCutObj[modelId - MI_CUTOBJ01]; + float radius = 0.0f; + RpClumpForAllAtomics(clump, CalculateBoundingSphereRadiusCB, &radius); + pColModel->boundingSphere.radius = radius; + pColModel->boundingBox.min = CVector(-radius, -radius, -radius); + pColModel->boundingBox.max = CVector(radius, radius, radius); + } } CCutsceneObject * @@ -314,20 +380,25 @@ CCutsceneMgr::CreateCutsceneObject(int modelId) { CBaseModelInfo *pModelInfo; CColModel *pColModel; - float radius; - RpClump *clump; CCutsceneObject *pCutsceneObject; + CStreaming::ImGonnaUseStreamingMemory(); + debug("Created cutscene object %s\n", CModelInfo::GetModelInfo(modelId)->GetName()); if (modelId >= MI_CUTOBJ01 && modelId <= MI_CUTOBJ05) { pModelInfo = CModelInfo::GetModelInfo(modelId); pColModel = &CTempColModels::ms_colModelCutObj[modelId - MI_CUTOBJ01]; - radius = 0.0f; - pModelInfo->SetColModel(pColModel); - clump = (RpClump*)pModelInfo->GetRwObject(); - assert(RwObjectGetType((RwObject*)clump) == rpCLUMP); - RpClumpForAllAtomics(clump, CalculateBoundingSphereRadiusCB, &radius); - + UpdateCutsceneObjectBoundingBox((RpClump*)pModelInfo->GetRwObject(), modelId); + } else if (modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL21) { + pModelInfo = CModelInfo::GetModelInfo(modelId); + if (pModelInfo->GetColModel() == &CTempColModels::ms_colModelPed1) { + CColModel *colModel = new CColModel(); + colModel->boundingSphere.radius = 2.0f; + colModel->boundingSphere.center = CVector(0.0f, 0.0f, 0.0f); + pModelInfo->SetColModel(colModel, true); + } + pColModel = pModelInfo->GetColModel(); + float radius = 2.0f; pColModel->boundingSphere.radius = radius; pColModel->boundingBox.min = CVector(-radius, -radius, -radius); pColModel->boundingBox.max = CVector(radius, radius, radius); @@ -335,7 +406,10 @@ CCutsceneMgr::CreateCutsceneObject(int modelId) pCutsceneObject = new CCutsceneObject(); pCutsceneObject->SetModelIndex(modelId); + if (ms_useCutsceneShadows) + pCutsceneObject->CreateShadow(); ms_pCutsceneObjects[ms_numCutsceneObjs++] = pCutsceneObject; + CStreaming::IHaveUsedStreamingMemory(); return pCutsceneObject; } @@ -343,9 +417,11 @@ void CCutsceneMgr::DeleteCutsceneData(void) { if (!ms_loaded) return; + CTimer::Suspend(); ms_cutsceneProcessing = false; ms_useLodMultiplier = false; + ms_useCutsceneShadows = true; for (--ms_numCutsceneObjs; ms_numCutsceneObjs >= 0; ms_numCutsceneObjs--) { CWorld::Remove(ms_pCutsceneObjects[ms_numCutsceneObjs]); @@ -355,12 +431,27 @@ CCutsceneMgr::DeleteCutsceneData(void) } ms_numCutsceneObjs = 0; + for (int i = MI_SPECIAL01; i < MI_SPECIAL21; i++) { + CBaseModelInfo *minfo = CModelInfo::GetModelInfo(i); + CColModel *colModel = minfo->GetColModel(); + if (colModel != &CTempColModels::ms_colModelPed1) { + delete colModel; + minfo->SetColModel(&CTempColModels::ms_colModelPed1); + } + } + if (ms_animLoaded) CAnimManager::RemoveLastAnimFile(); ms_animLoaded = false; - TheCamera.RestoreWithJumpCut(); - TheCamera.SetWideScreenOff(); + numUncompressedAnims = 0; + uncompressedAnims[0][0] = '\0'; + + if (bCamLoaded) { + TheCamera.RestoreWithJumpCut(); + TheCamera.SetWideScreenOff(); + TheCamera.DeleteCutSceneCamDataMemory(); + } ms_running = false; ms_loaded = false; @@ -368,14 +459,42 @@ CCutsceneMgr::DeleteCutsceneData(void) CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_CUTSCENE); CWorld::Players[CWorld::PlayerInFocus].MakePlayerSafe(false); - if (CGeneral::faststricmp(ms_cutsceneName, "end")) { + if (CGeneral::faststricmp(ms_cutsceneName, "finale")) { DMAudio.StopCutSceneMusic(); - if (CGeneral::faststricmp(ms_cutsceneName, "bet")) - DMAudio.ChangeMusicMode(MUSICMODE_GAME); + DMAudio.ChangeMusicMode(MUSICMODE_GAME); } - CTimer::Stop(); - CGame::DrasticTidyUpMemory(TheCamera.GetScreenFadeStatus() == FADE_2); - CTimer::Update(); + + CStreaming::ms_disableStreaming = false; + CWorld::bProcessCutsceneOnly = false; + + if(bCamLoaded) + CGame::DrasticTidyUpMemory(TheCamera.GetScreenFadeStatus() == FADE_2); + + CPad::GetPad(0)->Clear(false); + if (bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver) { + CStreaming::LoadInitialPeds(); + CStreaming::LoadInitialWeapons(); + CStreaming::LoadInitialVehicles(); + bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver = false; + + CPlayerPed *pPlayerPed = FindPlayerPed(); + for (int i = 0; i < NumberOfSavedWeapons; i++) { + int32 weaponModelId = CWeaponInfo::GetWeaponInfo(SavedWeaponIDs[i])->m_nModelId; + uint8 flags = CStreaming::ms_aInfoForModel[weaponModelId].m_flags; + CStreaming::RequestModel(weaponModelId, STREAMFLAGS_DONT_REMOVE); + CStreaming::LoadAllRequestedModels(false); + if (CWeaponInfo::GetWeaponInfo(SavedWeaponIDs[i])->m_nModel2Id != -1) { + CStreaming::RequestModel(CWeaponInfo::GetWeaponInfo(SavedWeaponIDs[i])->m_nModel2Id, 0); + CStreaming::LoadAllRequestedModels(false); + } + if (!(flags & STREAMFLAGS_DONT_REMOVE)) + CStreaming::SetModelIsDeletable(weaponModelId); + pPlayerPed->GiveWeapon(SavedWeaponIDs[i], SavedWeaponAmmo[i], true); + } + NumberOfSavedWeapons = 0; + } + + CTimer::Resume(); } void @@ -392,7 +511,7 @@ CCutsceneMgr::Update(void) switch (ms_cutsceneLoadStatus) { case CUTSCENE_LOADING_AUDIO: SetupCutsceneToStart(); - if (CGeneral::faststricmp(ms_cutsceneName, "end")) + if (CGeneral::faststricmp(ms_cutsceneName, "finale")) DMAudio.PlayPreloadedCutSceneMusic(); ms_cutsceneLoadStatus++; break; @@ -410,15 +529,157 @@ CCutsceneMgr::Update(void) if (!ms_running) return; ms_cutsceneTimer += CTimer::GetTimeStepNonClippedInSeconds(); - if (CGeneral::faststricmp(ms_cutsceneName, "end") && TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FLYBY && ms_cutsceneLoadStatus == CUTSCENE_LOADING_0) { - if (CPad::GetPad(0)->GetCrossJustDown() - || (CGame::playingIntro && CPad::GetPad(0)->GetStartJustDown()) - || CPad::GetPad(0)->GetLeftMouseJustDown() - || CPad::GetPad(0)->GetEnterJustDown() - || CPad::GetPad(0)->GetCharJustDown(' ')) - FinishCutscene(); + + for (int i = 0; i < ms_numCutsceneObjs; i++) { + int modelId = ms_pCutsceneObjects[i]->GetModelIndex(); + if (modelId >= MI_CUTOBJ01 && modelId <= MI_CUTOBJ05) + UpdateCutsceneObjectBoundingBox(ms_pCutsceneObjects[i]->GetClump(), modelId); + + if (ms_pCutsceneObjects[i]->m_pAttachTo != nil && modelId >= MI_SPECIAL01 && modelId <= MI_SPECIAL21) + UpdateCutsceneObjectBoundingBox(ms_pCutsceneObjects[i]->GetClump(), modelId); } + + if (bCamLoaded) + if (CGeneral::faststricmp(ms_cutsceneName, "finale") && TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FLYBY && ms_cutsceneLoadStatus == CUTSCENE_LOADING_0) { + if (CPad::GetPad(0)->GetCrossJustDown() + || (CGame::playingIntro && CPad::GetPad(0)->GetStartJustDown()) + || CPad::GetPad(0)->GetLeftMouseJustDown() + || CPad::GetPad(0)->GetEnterJustDown() + || CPad::GetPad(0)->GetCharJustDown(' ')) + FinishCutscene(); + } } -bool CCutsceneMgr::HasCutsceneFinished(void) { return TheCamera.GetPositionAlongSpline() == 1.0f; } +bool CCutsceneMgr::HasCutsceneFinished(void) { return !bCamLoaded || TheCamera.GetPositionAlongSpline() == 1.0f; } + +void +CCutsceneMgr::LoadAnimationUncompressed(char const* name) +{ + strcpy(uncompressedAnims[numUncompressedAnims], name); + + // Because that's how CAnimManager knows the end of array + ++numUncompressedAnims; + assert(numUncompressedAnims < ARRAY_SIZE(uncompressedAnims)); + uncompressedAnims[numUncompressedAnims][0] = '\0'; +} +void +CCutsceneMgr::AttachObjectToParent(CObject *pObject, CEntity *pAttachTo) +{ + ((CCutsceneObject*)pObject)->m_pAttachmentObject = nil; + ((CCutsceneObject*)pObject)->m_pAttachTo = RpClumpGetFrame(pAttachTo->GetClump()); + + debug("Attach %s to %s\n", CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetName(), CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName()); +} + +void +CCutsceneMgr::AttachObjectToFrame(CObject *pObject, CEntity *pAttachTo, const char *frame) +{ + ((CCutsceneObject*)pObject)->m_pAttachmentObject = nil; + ((CCutsceneObject*)pObject)->m_pAttachTo = RpAnimBlendClumpFindFrame(pAttachTo->GetClump(), frame)->frame; + debug("Attach %s to component %s of %s\n", + CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetName(), + frame, + CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName()); + if (RwObjectGetType(pObject->m_rwObject) == rpCLUMP) { + RpClump *clump = (RpClump*)pObject->m_rwObject; + if (IsClumpSkinned(clump)) + RpAtomicGetBoundingSphere(GetFirstAtomic(clump))->radius *= 1.1f; + } +} + +void +CCutsceneMgr::AttachObjectToBone(CObject *pObject, CObject *pAttachTo, int bone) +{ + RpHAnimHierarchy *hanim = GetAnimHierarchyFromSkinClump(pAttachTo->GetClump()); + RwInt32 id = RpHAnimIDGetIndex(hanim, bone); + RwMatrix *matrixArray = RpHAnimHierarchyGetMatrixArray(hanim); + ((CCutsceneObject*)pObject)->m_pAttachmentObject = pAttachTo; + ((CCutsceneObject*)pObject)->m_pAttachTo = &matrixArray[id]; + debug("Attach %s to %s\n", + CModelInfo::GetModelInfo(pObject->GetModelIndex())->GetName(), + CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName()); +} + +void +CCutsceneMgr::RemoveEverythingFromTheWorldForTheBiggestFuckoffCutsceneEver() +{ + CStreaming::ms_disableStreaming = true; + CColStore::RemoveAllCollision(); + CWorld::bProcessCutsceneOnly = true; + ms_cutsceneProcessing = true; + + for (int i = CPools::GetPedPool()->GetSize() - 1; i >= 0; i--) { + CPed *pPed = CPools::GetPedPool()->GetSlot(i); + if (pPed) { + if (!pPed->IsPlayer() && pPed->CanBeDeleted()) { + CWorld::Remove(pPed); + delete pPed; + } + } + } + + for (int i = CPools::GetVehiclePool()->GetSize() - 1; i >= 0; i--) { + CVehicle *pVehicle = CPools::GetVehiclePool()->GetSlot(i); + if (pVehicle) { + if (pVehicle->CanBeDeleted()) { + CWorld::Remove(pVehicle); + delete pVehicle; + } + } + } + + bIsEverythingRemovedFromTheWorldForTheBiggestFuckoffCutsceneEver = true; + CStreaming::RemoveCurrentZonesModels(); + CStreaming::SetModelIsDeletable(MI_MALE01); + CStreaming::SetModelTxdIsDeletable(MI_MALE01); + CStreaming::SetModelIsDeletable(MI_HMOCA); + CStreaming::SetModelTxdIsDeletable(MI_HMOCA); + CStreaming::SetModelIsDeletable(MI_NIGHTSTICK); + CStreaming::SetModelTxdIsDeletable(MI_NIGHTSTICK); + CStreaming::SetModelIsDeletable(MI_MISSILE); + CStreaming::SetModelTxdIsDeletable(MI_MISSILE); + CStreaming::SetModelIsDeletable(MI_POLICE); + CStreaming::SetModelTxdIsDeletable(MI_POLICE); + + while (CStreaming::RemoveLoadedVehicle()) ; + + CRadar::RemoveRadarSections(); + + for (int i = CPools::GetDummyPool()->GetSize() - 1; i >= 0; i--) { + CDummy* pDummy = CPools::GetDummyPool()->GetSlot(i); + if (pDummy) + pDummy->DeleteRwObject(); + } + + for (int i = CPools::GetObjectPool()->GetSize() - 1; i >= 0; i--) { + CObject* pObject = CPools::GetObjectPool()->GetSlot(i); + if (pObject) + pObject->DeleteRwObject(); + } + + for (int i = CPools::GetBuildingPool()->GetSize() - 1; i >= 0; i--) { + CBuilding* pBuilding = CPools::GetBuildingPool()->GetSlot(i); + if (pBuilding && pBuilding->m_rwObject != nil && pBuilding->bIsBIGBuilding && pBuilding->bStreamBIGBuilding) { + if (pBuilding->bIsBIGBuilding) + CStreaming::RequestModel(pBuilding->GetModelIndex(), 0); + if (!pBuilding->bImBeingRendered) + pBuilding->DeleteRwObject(); + } + } + + CPlayerPed *pPlayerPed = FindPlayerPed(); + pPlayerPed->RemoveWeaponAnims(0, -1000.0f); + NumberOfSavedWeapons = 0; + + for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) { + if (pPlayerPed->m_weapons[i].m_eWeaponType != WEAPONTYPE_UNARMED) { + SavedWeaponIDs[NumberOfSavedWeapons] = pPlayerPed->m_weapons[i].m_eWeaponType; + SavedWeaponAmmo[NumberOfSavedWeapons] = pPlayerPed->m_weapons[i].m_nAmmoTotal; + NumberOfSavedWeapons++; + } + } + + pPlayerPed->ClearWeapons(); + CGame::DrasticTidyUpMemory(true); +}
\ No newline at end of file |