Files
secretpsxsplash/src/scenemanager.hh
2026-03-27 16:39:10 +01:00

180 lines
6.5 KiB
C++

#pragma once
#include <EASTL/vector.h>
#include <psyqo/trigonometry.hh>
#include <psyqo/vector.hh>
#include <psyqo/gpu.hh>
#include "bvh.hh"
#include "camera.hh"
#include "collision.hh"
#include "controls.hh"
#include "gameobject.hh"
#include "lua.h"
#include "splashpack.hh"
#include "worldcollision.hh"
#include "navregion.hh"
#include "audiomanager.hh"
#include "interactable.hh"
#include "luaapi.hh"
#include "fileloader.hh"
#include "cutscene.hh"
#include "uisystem.hh"
namespace psxsplash {
// Forward-declare; full definition in loadingscreen.hh
class LoadingScreen;
class SceneManager {
public:
void InitializeScene(uint8_t* splashpackData, LoadingScreen* loading = nullptr);
void GameTick(psyqo::GPU &gpu);
// Font access (set from main.cpp after uploadSystemFont)
static void SetFont(psyqo::Font<>* font) { s_font = font; }
static psyqo::Font<>* GetFont() { return s_font; }
// Trigger event callbacks (called by CollisionSystem for trigger boxes)
void fireTriggerEnter(int16_t luaFileIndex, uint16_t triggerIndex);
void fireTriggerExit(int16_t luaFileIndex, uint16_t triggerIndex);
// Get game object by index (for collision callbacks)
GameObject* getGameObject(uint16_t index) {
if (index < m_gameObjects.size()) return m_gameObjects[index];
return nullptr;
}
// Get total object count
size_t getGameObjectCount() const { return m_gameObjects.size(); }
// Get object name by index (returns nullptr if no name table or out of range)
const char* getObjectName(uint16_t index) const {
if (index < m_objectNames.size()) return m_objectNames[index];
return nullptr;
}
// Find first object with matching name (linear scan, case-sensitive)
GameObject* findObjectByName(const char* name) const;
// Find audio clip index by name (returns -1 if not found)
int findAudioClipByName(const char* name) const;
// Get audio clip name by index (returns nullptr if out of range)
const char* getAudioClipName(int index) const {
if (index >= 0 && index < (int)m_audioClipNames.size()) return m_audioClipNames[index];
return nullptr;
}
// Public API for game systems
// Interaction system - call from Lua or native code
void triggerInteraction(GameObject* interactable);
// GameObject state control with events
void setObjectActive(GameObject* go, bool active);
// Public accessors for Lua API
Controls& getControls() { return m_controls; }
Camera& getCamera() { return m_currentCamera; }
Lua& getLua() { return L; }
AudioManager& getAudio() { return m_audio; }
// Scene loading (for multi-scene support)
void requestSceneLoad(int sceneIndex);
int getCurrentSceneIndex() const { return m_currentSceneIndex; }
/// Load a scene by index. This is the ONE canonical load path used by
/// both the initial boot (main.cpp) and runtime scene transitions.
/// Blanks the screen, shows a loading screen, tears down the old scene,
/// loads the new splashpack, and initialises.
/// @param gpu GPU reference.
/// @param sceneIndex Scene to load.
/// @param isFirstScene True when called from boot (skips clearScene / free).
void loadScene(psyqo::GPU& gpu, int sceneIndex, bool isFirstScene = false);
// Check and process pending scene load (called from GameTick)
void processPendingSceneLoad();
private:
psxsplash::Lua L;
psxsplash::SplashPackLoader m_loader;
CollisionSystem m_collisionSystem;
BVHManager m_bvh; // Spatial acceleration for frustum culling
WorldCollision m_worldCollision; // Triangle-level world collision (v7+)
NavRegionSystem m_navRegions; // Convex region navigation (v7+)
uint16_t m_playerNavRegion = NAV_NO_REGION; // Current nav region for player
// Scene type and render path: 0=exterior (BVH), 1=interior (room/portal)
uint16_t m_sceneType = 0;
// Room/portal data (v11+ interior scenes). Pointers into splashpack data.
const RoomData* m_rooms = nullptr;
uint16_t m_roomCount = 0;
const PortalData* m_portals = nullptr;
uint16_t m_portalCount = 0;
const TriangleRef* m_roomTriRefs = nullptr;
uint16_t m_roomTriRefCount = 0;
eastl::vector<LuaFile*> m_luaFiles;
eastl::vector<GameObject*> m_gameObjects;
// Object name table (v9+): parallel to m_gameObjects, points into splashpack data
eastl::vector<const char*> m_objectNames;
// Audio clip name table (v10+): parallel to audio clips, points into splashpack data
eastl::vector<const char*> m_audioClipNames;
// Component arrays
eastl::vector<Interactable*> m_interactables;
// Audio system
AudioManager m_audio;
// Cutscene playback
Cutscene m_cutscenes[MAX_CUTSCENES];
int m_cutsceneCount = 0;
CutscenePlayer m_cutscenePlayer;
// UI system (v13+)
UISystem m_uiSystem;
psxsplash::Controls m_controls;
psxsplash::Camera m_currentCamera;
psyqo::Vec3 m_playerPosition;
psyqo::Angle playerRotationX, playerRotationY, playerRotationZ;
psyqo::FixedPoint<12, uint16_t> m_playerHeight;
// Movement physics (v8+)
int32_t m_playerRadius; // Collision radius in fp12 (replaces hardcoded PLAYER_RADIUS)
int32_t m_velocityY; // Vertical velocity in fp12 per second (negative = up)
int32_t m_gravityPerFrame; // Gravity velocity change per frame (fp12)
int32_t m_jumpVelocityRaw; // Initial jump velocity in fp12 per second
bool m_isGrounded; // On the ground (can jump)
// Frame timing
uint32_t m_lastFrameTime; // gpu.now() timestamp of previous frame
int m_deltaFrames; // Elapsed frame count (1 normally, 2+ if dropped)
bool freecam = false;
// Static font pointer (set from main.cpp)
static psyqo::Font<>* s_font;
// Scene transition state
int m_currentSceneIndex = 0;
int m_pendingSceneIndex = -1; // -1 = no pending load
uint8_t* m_currentSceneData = nullptr; // Owned pointer to loaded data
uint32_t m_liveDataSize = 0; // Bytes of m_currentSceneData still needed at runtime
// System update methods (called from GameTick)
void updateInteractionSystem();
void processEnableDisableEvents();
void clearScene(); // Deallocate current scene objects
void shrinkBuffer(); // Free pixel/audio bulk data after VRAM/SPU uploads
};
}; // namespace psxsplash
// namespace psxsplash