Created and implemented scenemanager, include cleanup, fixed winbuild?

This commit is contained in:
2025-04-14 23:53:31 +02:00
parent f8ab161270
commit b5b0ae464c
17 changed files with 346 additions and 266 deletions

View File

@@ -30,7 +30,7 @@ void psxsplash::Camera::SetRotation(psyqo::Angle x, psyqo::Angle y, psyqo::Angle
// XYZ multiplication order (matches C#)
psyqo::SoftMath::multiplyMatrix33(rotY, rotX, &rotY);
psyqo::SoftMath::multiplyMatrix33(rotY, rotZ, &rotY);
m_rotationMatrix = rotY;
}

56
src/controls.cpp Normal file
View File

@@ -0,0 +1,56 @@
#include "controls.hh"
#include <psyqo/vector.hh>
void psxsplash::Controls::Init() { m_input.initialize(); }
void psxsplash::Controls::HandleControls(psyqo::Vec3 &playerPosition, psyqo::Angle &playerRotationX,
psyqo::Angle &playerRotationY, psyqo::Angle &playerRotationZ, bool freecam,
int deltaTime) {
uint8_t rightX = m_input.getAdc(psyqo::AdvancedPad::Pad::Pad1a, 0);
uint8_t rightY = m_input.getAdc(psyqo::AdvancedPad::Pad::Pad1a, 1);
uint8_t leftX = m_input.getAdc(psyqo::AdvancedPad::Pad::Pad1a, 2);
uint8_t leftY = m_input.getAdc(psyqo::AdvancedPad::Pad::Pad1a, 3);
int16_t rightXOffset = (int16_t)rightX - 0x80;
int16_t rightYOffset = (int16_t)rightY - 0x80;
int16_t leftXOffset = (int16_t)leftX - 0x80;
int16_t leftYOffset = (int16_t)leftY - 0x80;
if (__builtin_abs(leftXOffset) < m_stickDeadzone && __builtin_abs(leftYOffset) < m_stickDeadzone) {
m_sprinting = false;
}
if (m_input.isButtonPressed(psyqo::AdvancedPad::Pad::Pad1a, psyqo::AdvancedPad::Button::L3)) {
m_sprinting = true;
}
psyqo::FixedPoint<12> speed = m_sprinting ? sprintSpeed : moveSpeed;
if (__builtin_abs(rightXOffset) > m_stickDeadzone) {
playerRotationY += (rightXOffset * rotSpeed * deltaTime) >> 7;
}
if (__builtin_abs(rightYOffset) > m_stickDeadzone) {
playerRotationX -= (rightYOffset * rotSpeed * deltaTime) >> 7;
playerRotationX = eastl::clamp(playerRotationX, -0.5_pi, 0.5_pi);
}
if (__builtin_abs(leftYOffset) > m_stickDeadzone) {
psyqo::FixedPoint<12> forward = -(leftYOffset * speed * deltaTime) >> 7;
playerPosition.x += m_trig.sin(playerRotationY) * forward;
playerPosition.z += m_trig.cos(playerRotationY) * forward;
}
if (__builtin_abs(leftXOffset) > m_stickDeadzone) {
psyqo::FixedPoint<12> strafe = -(leftXOffset * speed * deltaTime) >> 7;
playerPosition.x -= m_trig.cos(playerRotationY) * strafe;
playerPosition.z += m_trig.sin(playerRotationY) * strafe;
}
if (m_input.isButtonPressed(psyqo::AdvancedPad::Pad::Pad1a, psyqo::AdvancedPad::Button::L1)) {
playerPosition.y += speed * deltaTime;
}
if (m_input.isButtonPressed(psyqo::AdvancedPad::Pad::Pad1a, psyqo::AdvancedPad::Button::R1)) {
playerPosition.y -= speed * deltaTime;
}
}

29
src/controls.hh Normal file
View File

@@ -0,0 +1,29 @@
#pragma once
#include <psyqo/advancedpad.hh>
#include <psyqo/trigonometry.hh>
#include <psyqo/vector.hh>
namespace psxsplash {
using namespace psyqo::fixed_point_literals;
using namespace psyqo::trig_literals;
class Controls {
public:
void Init();
void HandleControls(psyqo::Vec3 &playerPosition, psyqo::Angle &playerRotationX, psyqo::Angle &playerRotationY,
psyqo::Angle &playerRotationZ, bool freecam, int deltaTime);
private:
psyqo::AdvancedPad m_input;
psyqo::Trig<> m_trig;
bool m_sprinting = false;
static constexpr uint8_t m_stickDeadzone = 0x30;
static constexpr psyqo::FixedPoint<12> moveSpeed = 0.002_fp;
static constexpr psyqo::Angle rotSpeed = 0.01_pi;
static constexpr psyqo::FixedPoint<12> sprintSpeed = 0.01_fp;
};
}; // namespace psxsplash

View File

@@ -1,6 +1,5 @@
#pragma once
#include <cstdint>
#include <psyqo/matrix.hh>
#include <psyqo/vector.hh>
@@ -17,7 +16,7 @@ class GameObject final {
psyqo::Vec3 position;
psyqo::Matrix33 rotation;
uint16_t polyCount;
uint16_t reserved;
int16_t luaFileIndex;
};
static_assert(sizeof(GameObject) == 56, "GameObject is not 56 bytes");
} // namespace psxsplash

View File

@@ -1,4 +1,5 @@
#pragma once
#include <psyqo/matrix.hh>
namespace psxsplash {

View File

@@ -1,44 +1,38 @@
#include "lua.h"
#include <psyqo-lua/lua.hh>
#include <psyqo/xprintf.h>
#include "gameobject.hh"
#include "psyqo-lua/lua.hh"
constexpr const char METATABLE_SCRIPT[] = R"(
metatableForAllGameObjects = {
__index = function(self, key)
if key == "position" then
local pos = rawget(self, key)
if pos == nil then
pos = get_position(self.__cpp_ptr)
end
return pos
end
return nil
end,
return function(metatable)
local get_position = metatable.get_position
local set_position = metatable.set_position
__newindex = function(self, key, value)
if key == "position" then
set_position(self.__cpp_ptr, value)
return
end
rawset(self, key, value)
metatable.get_position = nil
metatable.set_position = nil
function metatable.__index(self, key)
if key == "position" then
return get_position(self.__cpp_ptr)
end
}
return nil
end
function metatable.__newindex(self, key, value)
if key == "position" then
set_position(self.__cpp_ptr, value)
return
end
rawset(self, key, value)
end
end
)";
// Lua helpers
int traceback(lua_State *L) {
const char *msg = lua_tostring(L, 1);
if (msg)
luaL_traceback(L, L, msg, 1);
else
lua_pushliteral(L, "(no error message)");
return 1;
}
static int gameobjectSetPosition(psyqo::Lua L) {
auto go = L.toUserdata<psxsplash::GameObject>(1);
L.getField(2, "x");
@@ -69,46 +63,67 @@ static int gameobjectGetPosition(psyqo::Lua L) {
}
void psxsplash::Lua::Init() {
// L.push(luaPrint);
// L.setGlobal("print");
L.push(gameobjectGetPosition);
L.setGlobal("get_position");
L.push(gameobjectSetPosition);
L.setGlobal("set_position");
// Load and run the metatable script
if (L.loadBuffer(METATABLE_SCRIPT, "metatableForAllGameObjects") == 0) {
if (L.pcall(0, 0) == 0) {
// Script executed successfully
printf("Lua script 'metatableForAllGameObjects' loaded successfully\n");
if (L.loadBuffer(METATABLE_SCRIPT, "buffer:metatableForAllGameObjects") == 0) {
if (L.pcall(0, 1) == 0) {
// This will be our metatable
L.newTable();
L.push(gameobjectGetPosition);
L.setField(-2, "get_position");
L.push(gameobjectSetPosition);
L.setField(-2, "set_position");
L.copy(-1);
m_metatableReference = L.ref();
if (L.pcall(1, 0) == 0) {
printf("Lua script 'metatableForAllGameObjects' executed successfully");
} else {
printf("Error registering Lua script: %s\n", L.optString(-1, "Unknown error"));
L.clearStack();
return;
}
} else {
// Print Lua error if script execution fails
printf("Error executing Lua script: %s\n", L.isString(-1) ? L.toString(-1) : "Unknown error");
L.pop();
printf("Error executing Lua script: %s\n", L.optString(-1, "Unknown error"));
L.clearStack();
return;
}
} else {
// Print Lua error if script loading fails
printf("Error loading Lua script: %s\n", L.isString(-1) ? L.toString(-1) : "Unknown error");
L.pop();
printf("Error loading Lua script: %s\n", L.optString(-1, "Unknown error"));
L.clearStack();
return;
}
// Check if the metatable was set as a global
L.getGlobal("metatableForAllGameObjects");
if (L.isTable(-1)) {
printf("metatableForAllGameObjects successfully set as a global\n");
} else {
printf("Warning: metatableForAllGameObjects not found after init\n");
}
L.pop(); // Pop the global check
L.newTable();
m_luascriptsReference = L.ref();
}
void psxsplash::Lua::LoadLuaFile(const char* code, size_t len) {
if (L.loadBuffer(code, len) != LUA_OK) {
void psxsplash::Lua::LoadLuaFile(const char* code, size_t len, int index) {
char filename[32];
snprintf(filename, sizeof(filename), "lua_asset:%d", index);
if (L.loadBuffer(code, len, filename) != LUA_OK) {
printf("Lua error: %s\n", L.toString(-1));
L.pop();
}
// (1) script func
L.rawGetI(LUA_REGISTRYINDEX, m_luascriptsReference);
// (1) script func (2) scripts table
L.newTable();
// (1) script func (2) scripts table (3) {}
L.pushNumber(index);
// (1) script func (2) scripts table (3) {} (4) index
L.copy(-2);
// (1) script func (2) scripts table (3) {} (4) index (5) {}
L.setTable(-4);
// (1) script func (2) scripts table (3) {}
lua_setupvalue(L.getState(), -3, 1);
// (1) script func (2) scripts table
L.pop();
// (1) script func
if (L.pcall(0, 0)) {
printf("Lua error: %s\n", L.toString(-1));
L.pop();
@@ -116,42 +131,41 @@ void psxsplash::Lua::LoadLuaFile(const char* code, size_t len) {
}
void psxsplash::Lua::RegisterGameObject(GameObject* go) {
L.push(go); // (1) = GameObject*
// Create a new Lua table for the GameObject
L.newTable(); // (1) = GameObject*, (2) = {}
// Set the __cpp_ptr field to store the C++ pointer
L.push(go); // (1) = GameObject*, (2) = {}, (3) = GameObject*
L.push(go);
// (1) go
L.newTable();
// (1) go (2) {}
L.push(go);
// (1) go (2) {} (3) go
L.setField(-2, "__cpp_ptr");
// (1) = GameObject*, (2) = { __cpp_ptr = GameObject* }
// Set the metatable for the table
L.getGlobal("metatableForAllGameObjects");
// (1) = GameObject*, (2) = { __cpp_ptr = GameObject* }, (3) = metatableForAllGameObjects
// (1) go (2) { __cpp_ptr = go }
L.rawGetI(LUA_REGISTRYINDEX, m_metatableReference);
// (1) go (2) { __cpp_ptr = go } (3) metatable
if (L.isTable(-1)) {
L.setMetatable(-2); // Set the metatable for the table
L.setMetatable(-2);
} else {
printf("Warning: metatableForAllGameObjects not found\n");
L.pop(); // Pop the invalid metatable
L.pop();
}
// (1) = GameObject*, (2) = { __cpp_ptr = GameObject* + metatable }
// (1) go (2) { __cpp_ptr = go + metatable }
L.rawSet(LUA_REGISTRYINDEX);
// stack empty
// Debugging: Confirm the GameObject was registered
// empty stack
printf("GameObject registered in Lua registry: %p\n", go);
}
void psxsplash::Lua::CallOnCollide(GameObject* self, GameObject* other) {
L.push(traceback);
int errfunc = L.getTop(); // Save the error function index
L.getGlobal("onCollision");
if (self->luaFileIndex == -1) {
return;
}
L.rawGetI(LUA_REGISTRYINDEX, m_luascriptsReference);
// (1) scripts table
L.rawGetI(-1, self->luaFileIndex);
// (1) script table (2) script environment
L.getField(-1, "onCollision");
// (1) script table (2) script environment (3) onCollision
if (!L.isFunction(-1)) {
printf("Lua function 'onCollide' not found\n");
L.pop();
printf("Lua function 'onCollision' not found\n");
L.clearStack();
return;
}
@@ -160,16 +174,16 @@ void psxsplash::Lua::CallOnCollide(GameObject* self, GameObject* other) {
if (L.pcall(2, 0) != LUA_OK) {
printf("Lua error: %s\n", L.toString(-1));
L.pop();
}
L.clearStack();
}
void psxsplash::Lua::PushGameObject(GameObject* go) {
L.push(go);
L.rawGet(LUA_REGISTRYINDEX);
L.push(go);
L.rawGet(LUA_REGISTRYINDEX);
if (!L.isTable(-1)) {
if (!L.isTable(-1)) {
printf("Warning: GameObject not found in Lua registry\n");
L.pop();
L.pop();
}
}

View File

@@ -5,16 +5,28 @@
#include "gameobject.hh"
namespace psxsplash {
struct LuaFile {
union {
uint32_t luaCodeOffset;
const char* luaCode;
};
uint32_t length;
};
class Lua {
public:
void Init();
void LoadLuaFile(const char* code, size_t len);
void LoadLuaFile(const char* code, size_t len, int index);
void RegisterGameObject(GameObject* go);
void CallOnCollide(GameObject* self, GameObject* other);
private:
void PushGameObject(GameObject* go);
psyqo::Lua L;
int m_metatableReference;
int m_luascriptsReference;
};
} // namespace psxsplash

View File

@@ -1,7 +1,3 @@
#include <stdint.h>
#include <cmath>
#include <cstdint>
#include <psyqo/advancedpad.hh>
#include <psyqo/application.hh>
#include <psyqo/fixed-point.hh>
@@ -10,56 +6,29 @@
#include <psyqo/scene.hh>
#include <psyqo/trigonometry.hh>
#include "EASTL/algorithm.h"
#include "camera.hh"
#include "lua.h"
#include "navmesh.hh"
#include "psyqo/vector.hh"
#include "renderer.hh"
#include "splashpack.hh"
#include "scenemanager.hh"
// Data from the splashpack
extern uint8_t _binary_output_bin_start[];
namespace {
using namespace psyqo::fixed_point_literals;
using namespace psyqo::trig_literals;
class PSXSplash final : public psyqo::Application {
void prepare() override;
void createScene() override;
public:
psxsplash::Lua m_lua;
psxsplash::SplashPackLoader m_loader;
psyqo::Font<> m_font;
psyqo::AdvancedPad m_input;
static constexpr uint8_t m_stickDeadzone = 0x30;
};
class MainScene final : public psyqo::Scene {
void frame() override;
void start(StartReason reason) override;
psxsplash::Camera m_mainCamera;
psyqo::Angle camRotX, camRotY, camRotZ;
psyqo::Trig<> m_trig;
uint32_t m_lastFrameCounter;
static constexpr psyqo::FixedPoint<12> moveSpeed = 0.002_fp;
static constexpr psyqo::Angle rotSpeed = 0.01_pi;
bool m_sprinting = false;
static constexpr psyqo::FixedPoint<12> sprintSpeed = 0.01_fp;
bool m_freecam = false;
psyqo::FixedPoint<12> pheight = 0.0_fp;
bool m_renderSelect = false;
psxsplash::SceneManager m_sceneManager;
};
PSXSplash app;
@@ -77,49 +46,16 @@ void PSXSplash::prepare() {
// Initialize the Renderer singleton
psxsplash::Renderer::Init(gpu());
m_lua.Init();
}
void PSXSplash::createScene() {
m_font.uploadSystemFont(gpu());
m_input.initialize();
pushScene(&mainScene);
}
void MainScene::start(StartReason reason) {
app.m_loader.LoadSplashpack(_binary_output_bin_start, app.m_lua);
psxsplash::Renderer::GetInstance().SetCamera(m_mainCamera);
m_mainCamera.SetPosition(static_cast<psyqo::FixedPoint<12>>(app.m_loader.playerStartPos.x),
static_cast<psyqo::FixedPoint<12>>(app.m_loader.playerStartPos.y),
static_cast<psyqo::FixedPoint<12>>(app.m_loader.playerStartPos.z));
pheight = psyqo::FixedPoint<12>(app.m_loader.playerHeight);
app.m_input.setOnEvent(
eastl::function<void(psyqo::AdvancedPad::Event)>{[this](const psyqo::AdvancedPad::Event& event) {
if (event.pad != psyqo::AdvancedPad::Pad::Pad1a) return;
if (app.m_loader.navmeshes.empty()) return;
if (event.type == psyqo::AdvancedPad::Event::ButtonPressed) {
if (event.button == psyqo::AdvancedPad::Button::Triangle) {
m_freecam = !m_freecam;
} else if (event.button == psyqo::AdvancedPad::Button::Square) {
m_renderSelect = !m_renderSelect;
}
}
}});
if (app.m_loader.navmeshes.empty()) {
m_freecam = true;
}
}
void MainScene::start(StartReason reason) { m_sceneManager.InitializeScene(_binary_output_bin_start); }
void MainScene::frame() {
app.m_lua.CallOnCollide(app.m_loader.gameObjects[0], app.m_loader.gameObjects[1]);
uint32_t beginFrame = gpu().now();
auto currentFrameCounter = gpu().getFrameCount();
auto deltaTime = currentFrameCounter - mainScene.m_lastFrameCounter;
@@ -131,70 +67,10 @@ void MainScene::frame() {
mainScene.m_lastFrameCounter = currentFrameCounter;
uint8_t rightX = app.m_input.getAdc(psyqo::AdvancedPad::Pad::Pad1a, 0);
uint8_t rightY = app.m_input.getAdc(psyqo::AdvancedPad::Pad::Pad1a, 1);
uint8_t leftX = app.m_input.getAdc(psyqo::AdvancedPad::Pad::Pad1a, 2);
uint8_t leftY = app.m_input.getAdc(psyqo::AdvancedPad::Pad::Pad1a, 3);
int16_t rightXOffset = (int16_t)rightX - 0x80;
int16_t rightYOffset = (int16_t)rightY - 0x80;
int16_t leftXOffset = (int16_t)leftX - 0x80;
int16_t leftYOffset = (int16_t)leftY - 0x80;
if (__builtin_abs(leftXOffset) < app.m_stickDeadzone &&
__builtin_abs(leftYOffset) < app.m_stickDeadzone) {
m_sprinting = false;
}
if (app.m_input.isButtonPressed(psyqo::AdvancedPad::Pad::Pad1a, psyqo::AdvancedPad::Button::L3)) {
m_sprinting = true;
}
psyqo::FixedPoint<12> speed = m_sprinting ? sprintSpeed : moveSpeed;
if (__builtin_abs(rightXOffset) > app.m_stickDeadzone) {
camRotY += (rightXOffset * rotSpeed * deltaTime) >> 7;
}
if (__builtin_abs(rightYOffset) > app.m_stickDeadzone) {
camRotX -= (rightYOffset * rotSpeed * deltaTime) >> 7;
camRotX = eastl::clamp(camRotX, -0.5_pi, 0.5_pi);
}
m_mainCamera.SetRotation(camRotX, camRotY, camRotZ);
if (__builtin_abs(leftYOffset) > app.m_stickDeadzone) {
psyqo::FixedPoint<12> forward = -(leftYOffset * speed * deltaTime) >> 7;
m_mainCamera.MoveX((m_trig.sin(camRotY) * forward));
m_mainCamera.MoveZ((m_trig.cos(camRotY) * forward));
}
if (__builtin_abs(leftXOffset) > app.m_stickDeadzone) {
psyqo::FixedPoint<12> strafe = -(leftXOffset * speed * deltaTime) >> 7;
m_mainCamera.MoveX(-(m_trig.cos(camRotY) * strafe));
m_mainCamera.MoveZ((m_trig.sin(camRotY) * strafe));
}
if (app.m_input.isButtonPressed(psyqo::AdvancedPad::Pad::Pad1a, psyqo::AdvancedPad::Button::L1)) {
m_mainCamera.MoveY(speed * deltaTime);
}
if (app.m_input.isButtonPressed(psyqo::AdvancedPad::Pad::Pad1a, psyqo::AdvancedPad::Button::R1)) {
m_mainCamera.MoveY(-speed * deltaTime);
}
if (!m_freecam) {
psyqo::Vec3 adjustedPosition =
psxsplash::ComputeNavmeshPosition(m_mainCamera.GetPosition(), *app.m_loader.navmeshes[0], -pheight);
m_mainCamera.SetPosition(adjustedPosition.x, adjustedPosition.y, adjustedPosition.z);
}
if (!m_renderSelect) {
psxsplash::Renderer::GetInstance().Render(app.m_loader.gameObjects);
} else {
psxsplash::Renderer::GetInstance().RenderNavmeshPreview(*app.m_loader.navmeshes[0], true);
}
m_sceneManager.GameTick();
app.m_font.chainprintf(gpu(), {{.x = 2, .y = 2}}, {{.r = 0xff, .g = 0xff, .b = 0xff}}, "FPS: %i",
gpu().getRefreshRate() / deltaTime);
gpu().getRefreshRate() / deltaTime);
gpu().pumpCallbacks();
uint32_t endFrame = gpu().now();

View File

@@ -2,8 +2,8 @@
#include <array>
#include "psyqo/fixed-point.hh"
#include "psyqo/vector.hh"
#include <psyqo/fixed-point.hh>
#include <psyqo/vector.hh>
using namespace psyqo::fixed_point_literals;
@@ -80,10 +80,10 @@ psyqo::FixedPoint<12> CalculateY(const psyqo::Vec3& p, const NavMeshTri& tri) {
}
}
psyqo::Vec3 ComputeNavmeshPosition(psyqo::Vec3& position, Navmesh& navmesh, psyqo::FixedPoint<12> pheight) {
psyqo::Vec3 ComputeNavmeshPosition(psyqo::Vec3& position, Navmesh& navmesh, psyqo::FixedPoint<12> playerHeight) {
for (int i = 0; i < navmesh.triangleCount; i++) {
if (PointInTriangle(position, navmesh.polygons[i])) {
position.y = CalculateY(position, navmesh.polygons[i]) + pheight;
position.y = CalculateY(position, navmesh.polygons[i]) - playerHeight;
return position;
}
}
@@ -108,7 +108,7 @@ psyqo::Vec3 ComputeNavmeshPosition(psyqo::Vec3& position, Navmesh& navmesh, psyq
if (distSq < minDist) {
minDist = distSq;
closestPoint = proj;
position.y = CalculateY(position, navmesh.polygons[i]) + pheight;
position.y = CalculateY(position, navmesh.polygons[i]) - playerHeight;
}
}
}

View File

@@ -3,7 +3,6 @@
#include <EASTL/array.h>
#include <EASTL/vector.h>
#include <cstdint>
#include <psyqo/fixed-point.hh>
#include <psyqo/gte-kernels.hh>
#include <psyqo/gte-registers.hh>

View File

@@ -3,7 +3,6 @@
#include <EASTL/array.h>
#include <EASTL/vector.h>
#include <cstdint>
#include <psyqo/bump-allocator.hh>
#include <psyqo/fragments.hh>
#include <psyqo/gpu.hh>
@@ -25,7 +24,8 @@ class Renderer final {
Renderer(const Renderer&) = delete;
Renderer& operator=(const Renderer&) = delete;
// FIXME: I have no idea how to precompute the required sizes of these. It would be best to allocate them based on the scene
// FIXME: I have no idea how to precompute the required sizes of these. It would be best to allocate them based on
// the scene
static constexpr size_t ORDERING_TABLE_SIZE = 2048 * 3;
static constexpr size_t BUMP_ALLOCATOR_SIZE = 8096 * 24;
@@ -33,7 +33,6 @@ class Renderer final {
void SetCamera(Camera& camera);
void Render(eastl::vector<GameObject*>& objects);
void RenderNavmeshPreview(psxsplash::Navmesh navmesh, bool isOnMesh);
@@ -61,8 +60,8 @@ class Renderer final {
psyqo::Color m_clearcolor = {.r = 0, .g = 0, .b = 0};
void recursiveSubdivideAndRender(Tri &tri, eastl::array<psyqo::Vertex, 3> &projected, int zIndex,
int maxIterations);
void recursiveSubdivideAndRender(Tri& tri, eastl::array<psyqo::Vertex, 3>& projected, int zIndex,
int maxIterations);
};
} // namespace psxsplash

59
src/scenemanager.cpp Normal file
View File

@@ -0,0 +1,59 @@
#include "scenemanager.hh"
#include <utility>
#include "navmesh.hh"
#include "renderer.hh"
#include "splashpack.hh"
using namespace psyqo::trig_literals;
void psxsplash::SceneManager::InitializeScene(uint8_t* splashpackData) {
L.Init();
SplashpackSceneSetup sceneSetup;
m_loader.LoadSplashpack(splashpackData, sceneSetup);
m_luaFiles = std::move(sceneSetup.luaFiles);
m_gameObjects = std::move(sceneSetup.objects);
m_navmeshes = std::move(sceneSetup.navmeshes);
m_playerPosition = sceneSetup.playerStartPosition;
playerRotationX = 0.0_pi;
playerRotationY = 0.0_pi;
playerRotationZ = 0.0_pi;
m_playerHeight = sceneSetup.playerHeight;
// Load Lua files
for (int i = 0; i < m_luaFiles.size(); i++) {
auto luaFile = m_luaFiles[i];
L.LoadLuaFile(luaFile->luaCode, luaFile->length, i);
}
// Register game objects
for (auto object : m_gameObjects) {
L.RegisterGameObject(object);
}
m_controls.Init();
Renderer::GetInstance().SetCamera(m_currentCamera);
}
void psxsplash::SceneManager::GameTick() {
auto& renderer = psxsplash::Renderer::GetInstance();
renderer.Render(m_gameObjects);
m_controls.HandleControls(m_playerPosition, playerRotationX, playerRotationY, playerRotationZ, false, 1);
if (!freecam) {
psxsplash::ComputeNavmeshPosition(m_playerPosition, *m_navmeshes[0],
static_cast<psyqo::FixedPoint<12>>(m_playerHeight));
}
m_currentCamera.SetPosition(static_cast<psyqo::FixedPoint<12>>(m_playerPosition.x),
static_cast<psyqo::FixedPoint<12>>(m_playerPosition.y),
static_cast<psyqo::FixedPoint<12>>(m_playerPosition.z));
m_currentCamera.SetRotation(playerRotationX, playerRotationY, playerRotationZ);
}

40
src/scenemanager.hh Normal file
View File

@@ -0,0 +1,40 @@
#pragma once
#include <EASTL/vector.h>
#include <psyqo/trigonometry.hh>
#include <psyqo/vector.hh>
#include "camera.hh"
#include "controls.hh"
#include "gameobject.hh"
#include "lua.h"
#include "splashpack.hh"
namespace psxsplash {
class SceneManager {
public:
void InitializeScene(uint8_t* splashpackData);
void GameTick();
private:
psxsplash::Lua L;
psxsplash::SplashPackLoader m_loader;
eastl::vector<LuaFile*> m_luaFiles;
eastl::vector<GameObject*> m_gameObjects;
eastl::vector<Navmesh*> m_navmeshes;
psxsplash::Controls m_controls;
psxsplash::Camera m_currentCamera;
psyqo::Vec3 m_playerPosition;
psyqo::Angle playerRotationX, playerRotationY, playerRotationZ;
psyqo::FixedPoint<12, uint16_t> m_playerHeight;
bool previewNavmesh = false;
bool freecam = false;
};
}; // namespace psxsplash

View File

@@ -1,14 +1,15 @@
#include "splashpack.hh"
#include <cstdint>
#include <cstring>
#include <EASTL/vector.h>
#include <psyqo/fixed-point.hh>
#include <psyqo/gte-registers.hh>
#include <psyqo/primitives/common.hh>
#include "gameobject.hh"
#include "lua.h"
#include "mesh.hh"
#include "psyqo/fixed-point.hh"
#include "psyqo/gte-registers.hh"
#include "navmesh.hh"
#include "renderer.hh"
namespace psxsplash {
@@ -27,14 +28,6 @@ struct SPLASHPACKFileHeader {
uint16_t pad[2];
};
struct SPLASHPACKLuaFile {
union {
uint32_t luaCodeOffset;
const char* luaCode;
};
uint32_t length;
};
struct SPLASHPACKTextureAtlas {
uint32_t polygonsOffset;
uint16_t width, height;
@@ -49,39 +42,39 @@ struct SPLASHPACKClut {
uint16_t pad;
};
void SplashPackLoader::LoadSplashpack(uint8_t *data, psxsplash::Lua &lua) {
void SplashPackLoader::LoadSplashpack(uint8_t *data, SplashpackSceneSetup &setup) {
psyqo::Kernel::assert(data != nullptr, "Splashpack loading data pointer is null");
psxsplash::SPLASHPACKFileHeader *header = reinterpret_cast<psxsplash::SPLASHPACKFileHeader *>(data);
psyqo::Kernel::assert(memcmp(header->magic, "SP", 2) == 0, "Splashpack has incorrect magic");
psyqo::Kernel::assert(__builtin_memcmp(header->magic, "SP", 2) == 0, "Splashpack has incorrect magic");
playerStartPos = header->playerStartPos;
playerStartRot = header->playerStartRot;
playerHeight = header->playerHeight;
setup.playerStartPosition = header->playerStartPos;
setup.playerStartRotation = header->playerStartRot;
setup.playerHeight = header->playerHeight;
gameObjects.reserve(header->gameObjectCount);
navmeshes.reserve(header->navmeshCount);
setup.luaFiles.reserve(header->luaFileCount);
setup.objects.reserve(header->gameObjectCount);
setup.navmeshes.reserve(header->navmeshCount);
uint8_t *curentPointer = data + sizeof(psxsplash::SPLASHPACKFileHeader);
for (uint16_t i = 0; i < header->luaFileCount; i++) {
psxsplash::SPLASHPACKLuaFile *luaHeader = reinterpret_cast<psxsplash::SPLASHPACKLuaFile *>(curentPointer);
luaHeader->luaCode = reinterpret_cast<const char*>(data + luaHeader->luaCodeOffset);
lua.LoadLuaFile(luaHeader->luaCode, luaHeader->length);
curentPointer += sizeof(psxsplash::SPLASHPACKLuaFile);
psxsplash::LuaFile *luaHeader = reinterpret_cast<psxsplash::LuaFile *>(curentPointer);
luaHeader->luaCode = reinterpret_cast<const char *>(data + luaHeader->luaCodeOffset);
setup.luaFiles.push_back(luaHeader);
curentPointer += sizeof(psxsplash::LuaFile);
}
for (uint16_t i = 0; i < header->gameObjectCount; i++) {
psxsplash::GameObject *go = reinterpret_cast<psxsplash::GameObject *>(curentPointer);
go->polygons = reinterpret_cast<psxsplash::Tri *>(data + go->polygonsOffset);
lua.RegisterGameObject(go);
gameObjects.push_back(go);
setup.objects.push_back(go);
curentPointer += sizeof(psxsplash::GameObject);
}
for (uint16_t i = 0; i < header->navmeshCount; i++) {
psxsplash::Navmesh *navmesh = reinterpret_cast<psxsplash::Navmesh *>(curentPointer);
navmesh->polygons = reinterpret_cast<psxsplash::NavMeshTri *>(data + navmesh->polygonsOffset);
navmeshes.push_back(navmesh);
setup.navmeshes.push_back(navmesh);
curentPointer += sizeof(psxsplash::Navmesh);
}

View File

@@ -2,25 +2,26 @@
#include <EASTL/vector.h>
#include <cstdint>
#include <psyqo/fixed-point.hh>
#include "gameobject.hh"
#include "lua.h"
#include "navmesh.hh"
#include "psyqo/fixed-point.hh"
namespace psxsplash {
struct SplashpackSceneSetup {
eastl::vector<LuaFile *> luaFiles;
eastl::vector<GameObject *> objects;
eastl::vector<Navmesh *> navmeshes;
psyqo::GTE::PackedVec3 playerStartPosition;
psyqo::GTE::PackedVec3 playerStartRotation;
psyqo::FixedPoint<12, uint16_t> playerHeight;
};
class SplashPackLoader {
public:
eastl::vector<GameObject *> gameObjects;
eastl::vector<Navmesh *> navmeshes;
psyqo::GTE::PackedVec3 playerStartPos, playerStartRot;
psyqo::FixedPoint<12, uint16_t> playerHeight;
void LoadSplashpack(uint8_t *data, Lua &lua);
void LoadSplashpack(uint8_t *data, SplashpackSceneSetup &setup);
};
}; // namespace psxsplash