cutscene system

This commit is contained in:
Jan Racek
2026-03-24 15:51:04 +01:00
parent e51c06b012
commit 60a7063a17
12 changed files with 651 additions and 11 deletions

View File

@@ -23,7 +23,7 @@ void psxsplash::SceneManager::InitializeScene(uint8_t* splashpackData) {
m_audio.init();
// Register the Lua API
LuaAPI::RegisterAll(L.getState(), this);
LuaAPI::RegisterAll(L.getState(), this, &m_cutscenePlayer);
#ifdef PSXSPLASH_PROFILER
debug::Profiler::getInstance().initialize();
@@ -73,6 +73,20 @@ void psxsplash::SceneManager::InitializeScene(uint8_t* splashpackData) {
m_audio.loadClip((int)i, clip.adpcmData, clip.sizeBytes, clip.sampleRate, clip.loop);
}
// Copy cutscene data into scene manager storage (sceneSetup is stack-local)
m_cutsceneCount = sceneSetup.cutsceneCount;
for (int i = 0; i < m_cutsceneCount; i++) {
m_cutscenes[i] = sceneSetup.loadedCutscenes[i];
}
// Initialize cutscene player (v12+)
m_cutscenePlayer.init(
m_cutsceneCount > 0 ? m_cutscenes : nullptr,
m_cutsceneCount,
&m_currentCamera,
&m_audio
);
m_playerPosition = sceneSetup.playerStartPosition;
playerRotationX = 0.0_pi;
@@ -150,6 +164,9 @@ void psxsplash::SceneManager::InitializeScene(uint8_t* splashpackData) {
void psxsplash::SceneManager::GameTick(psyqo::GPU &gpu) {
LuaAPI::IncrementFrameCount();
// Tick cutscene player (advance frame and apply tracks before rendering)
m_cutscenePlayer.tick();
// Delta-time measurement: count elapsed frames based on gpu timer
// PS1 NTSC frame = ~33333 microseconds (30fps vsync)
{
@@ -168,12 +185,24 @@ void psxsplash::SceneManager::GameTick(psyqo::GPU &gpu) {
// Dispatch render path based on scene type.
// Interior scenes (type 1) use room/portal occlusion; exterior scenes use BVH culling.
if (m_sceneType == 1 && m_roomCount > 0 && m_rooms != nullptr) {
// Get camera room from nav region system (authoritative) instead of AABB guessing.
// NavRegion::roomIndex is set during export from the room each region belongs to.
// Determine which room the camera is in for portal culling.
// During cutscene playback the camera may be elsewhere from the player,
// so use the actual camera position to find the room.
int camRoom = -1;
if (m_navRegions.isLoaded() && m_playerNavRegion != NAV_NO_REGION) {
uint8_t ri = m_navRegions.getRoomIndex(m_playerNavRegion);
if (ri != 0xFF) camRoom = (int)ri;
if (m_navRegions.isLoaded()) {
if (m_cutscenePlayer.isPlaying()) {
// Camera-driven: look up nav region from camera world position
auto& camPos = m_currentCamera.GetPosition();
uint16_t camRegion = m_navRegions.findRegion(camPos.x.value, camPos.z.value);
if (camRegion != NAV_NO_REGION) {
uint8_t ri = m_navRegions.getRoomIndex(camRegion);
if (ri != 0xFF) camRoom = (int)ri;
}
} else if (m_playerNavRegion != NAV_NO_REGION) {
// Normal gameplay: use cached player nav region
uint8_t ri = m_navRegions.getRoomIndex(m_playerNavRegion);
if (ri != 0xFF) camRoom = (int)ri;
}
}
renderer.RenderWithRooms(m_gameObjects, m_rooms, m_roomCount,
m_portals, m_portalCount, m_roomTriRefs, camRoom);
@@ -574,6 +603,8 @@ void psxsplash::SceneManager::clearScene() {
// 3. Reset hardware / subsystems
m_audio.reset(); // Free SPU RAM and stop all voices
m_collisionSystem.init(); // Re-init collision system
m_cutsceneCount = 0;
m_cutscenePlayer.init(nullptr, 0, nullptr, nullptr); // Reset cutscene player
// BVH, WorldCollision, and NavRegions will be overwritten by next load
// Reset room/portal pointers (they point into splashpack data which is being freed)