Update aurora; impl visors, warp & water (WIP)

This commit is contained in:
Luke Street
2026-06-12 12:56:29 -06:00
parent 9a365f37f2
commit 621ee0fed3
20 changed files with 2845 additions and 768 deletions
+4 -3
View File
@@ -514,8 +514,8 @@ static void aurora_log_callback(AuroraLogLevel level, const char* module, const
spdlog::log(severity, "[{}] {}", module, view);
if (level == LOG_FATAL) {
spdlog::default_logger()->flush();
auto msg = fmt::format("Metaforce encountered an internal error:\n\n{}", view);
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Metaforce", msg.c_str(), metaforce::g_window);
// auto msg = fmt::format("Metaforce encountered an internal error:\n\n{}", view);
// SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Metaforce", msg.c_str(), metaforce::g_window);
std::abort();
}
}
@@ -581,7 +581,8 @@ int main(int argc, char** argv) {
const AuroraConfig config{
.appName = "Metaforce",
.configPath = configPath.c_str(),
.userPath = configPath.c_str(),
.cachePath = configPath.c_str(),
.desiredBackend = metaforce::backend_from_string(cvarCmns.getGraphicsApi()),
.msaa = cvarCmns.getSamples(),
.maxTextureAnisotropy = static_cast<uint16_t>(cvarCmns.getAnisotropy()),
+2 -2
View File
@@ -776,7 +776,7 @@ void CStateManager::DrawWorld() {
g_Renderer->SetThermalColdScale(xf28_thermColdScale2 + xf24_thermColdScale1);
for (int i = areaCount - 1; i >= 0; --i) {
//OPTICK_EVENT("CStateManager::DrawWorld DrawArea");
// OPTICK_EVENT("CStateManager::DrawWorld DrawArea");
const CGameArea& area = *areaArr[i];
SetupFogForArea(area);
g_Renderer->EnablePVS(pvsArr[i], area.x4_selfIdx);
@@ -1375,7 +1375,7 @@ void CStateManager::LoadScriptObjects(TAreaId aid, CInputStream& in, std::vector
std::pair<TEditorId, TUniqueId> CStateManager::LoadScriptObject(TAreaId aid, EScriptObjectType type, u32 length,
CInputStream& in) {
//OPTICK_EVENT();
// OPTICK_EVENT();
const TEditorId id = in.ReadLong();
const u32 connCount = in.ReadLong();
length -= 8;
+1
View File
@@ -15,6 +15,7 @@ static const u8* sLastMaterialCached = nullptr;
static const CCubeModel* sLastModelCached = nullptr;
static const CCubeModel* sRenderingModel = nullptr;
static float sReflectionAlpha = 0.f;
zeus::CVector3f CCubeMaterial::sViewingFrom{};
void CCubeMaterial::SetCurrent(const CModelFlags& flags, const CCubeSurface& surface, CCubeModel& model) {
if (sLastMaterialCached == x0_data) {
+4
View File
@@ -57,6 +57,8 @@ public:
static void KillCachedViewDepState();
static void EnsureTevsDirect();
static const zeus::CVector3f& GetViewingReflection() { return sViewingFrom; }
private:
void SetCurrentBlack();
@@ -71,5 +73,7 @@ private:
u32 finalKColorCount, u32& finalCCFlags, u32& finalACFlags);
static void DoPassthru(u32 finalTevCount);
static void DoModelShadow(u32 texCount, u32 tcgCount);
static zeus::CVector3f sViewingFrom;
};
} // namespace metaforce
File diff suppressed because it is too large Load Diff
+14 -11
View File
@@ -83,7 +83,7 @@ private:
std::vector<CLight> x300_dynamicLights;
u32 x310_phazonSuitMaskCountdown = 0;
std::unique_ptr<CTexture> x314_phazonSuitMask;
bool x318_24_refectionDirty : 1 = false;
bool x318_24_reflectionDirty : 1 = false;
bool x318_25_drawWireframe : 1 = false;
bool x318_26_requestRGBA6 : 1 = false;
bool x318_27_currentRGBA6 : 1 = false;
@@ -102,6 +102,8 @@ private:
void ReallyDrawPhazonSuitIndirectEffect(const zeus::CColor& vertColor, CTexture& maskTex, CTexture& indTex,
const zeus::CColor& modColor, float scale, float offX, float offY);
void ReallyDrawPhazonSuitEffect(const zeus::CColor& modColor, CTexture& maskTex);
static void* GetRenderToTexBuffer(int);
void CopyTex(int, bool, void*, GXTexFmt, bool);
void DoPhazonSuitIndirectAlphaBlur(float blurRadius, float f2);
void ReallyDrawSpaceWarp(const zeus::CVector3f& pt, float strength);
void ReallyRenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb, const CModel* model,
@@ -215,6 +217,13 @@ public:
void DrawOverlappingWorldModelShadows(s32 alphaVal, const std::vector<u32>& modelBits, const zeus::CAABox& aabb);
void RenderBucketItems(const CAreaListItem* lights);
void DrawRenderBucketsDebug() {}
void RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel* model, const zeus::CTransform& modelXf,
const zeus::CTransform& viewXf, const CSkinnedModel* skinnedModel);
void DrawFogSlices(const zeus::CPlane* planes, int planeCount, int planeIdx, const zeus::CVector3f& point,
float extent);
void DrawFogFans(const zeus::CPlane* planes, int planeCount, const zeus::CVector3f* verts, int vertCount,
int startPlane, int curPlane);
void DrawFogFan(const zeus::CVector3f* verts, int vertCount);
void HandleUnsortedModel(CAreaListItem* areaItem, CCubeModel& model, const CModelFlags& flags);
void HandleUnsortedModelWireframe(CAreaListItem* areaItem, CCubeModel& model);
@@ -226,17 +235,11 @@ public:
// Getters
[[nodiscard]] bool IsInAreaDraw() const { return x318_30_inAreaDraw; }
[[nodiscard]] bool IsReflectionDirty() const { return x318_24_refectionDirty; }
void SetReflectionDirty(bool v) { x318_24_refectionDirty = v; }
[[nodiscard]] bool IsReflectionDirty() const { return x318_24_reflectionDirty; }
void SetReflectionDirty(bool v) { x318_24_reflectionDirty = v; }
[[nodiscard]] bool IsThermalVisorActive() const { return x318_29_thermalVisor; }
CTexture* GetRealReflection() {
x2dc_reflectionAge = 0;
if (x14c_reflectionTex) {
return x14c_reflectionTex.get();
}
return &xe4_blackTex;
}
CTexture* GetRealReflection();
const CTexture& GetZeroTexture() const { return xe4_blackTex; }
static void SetupCGraphicsState();
};
+1
View File
@@ -44,5 +44,6 @@ public:
[[nodiscard]] zeus::CAABox GetBounds() const {
return x1c_extraSize != 0 ? x24_bounds : zeus::CAABox{x0_center, x0_center};
}
[[nodiscard]] bool IsValid() const { return x0_data != nullptr; }
};
} // namespace metaforce
+37 -3
View File
@@ -244,7 +244,13 @@ static inline void SetFog(GXFogType type, float startZ, float endZ, float nearZ,
GXSetFog(type, startZ, endZ, nearZ, farZ, fogColor);
}
void SetIndTexMtxSTPointFive(GXIndTexMtxID id, s8 scaleExp) noexcept;
static inline void SetIndTexMtxSTPointFive(GXIndTexMtxID id, s8 scaleExp) noexcept {
static const float indMtx[2][3] = {
{0.5f, 0.f, 0.f},
{0.f, 0.5f, 0.f},
};
GXSetIndTexMtx(id, indMtx, scaleExp);
}
void SetLineWidth(u8 width, GXTexOffset offset) noexcept;
@@ -382,8 +388,14 @@ static inline void SetStandardDirectTev_Compressed(GXTevStageID stageId, u32 col
static inline void SetTevIndirect(GXTevStageID stageId, GXIndTexStageID indStage, GXIndTexFormat fmt,
GXIndTexBiasSel biasSel, GXIndTexMtxID mtxSel, GXIndTexWrap wrapS, GXIndTexWrap wrapT,
GXBool addPrev, GXBool indLod, GXIndTexAlphaSel alphaSel) noexcept {
// TODO
GXSetTevIndirect(stageId, indStage, fmt, biasSel, mtxSel, wrapS, wrapT, addPrev, indLod, alphaSel);
auto& state = sGXState.x68_tevStates[stageId];
uint flags = MaskAndShiftLeft(indStage, 3, 0) | MaskAndShiftLeft(fmt, 3, 2) | MaskAndShiftLeft(biasSel, 7, 4) |
MaskAndShiftLeft(mtxSel, 15, 7) | MaskAndShiftLeft(wrapS, 7, 11) | MaskAndShiftLeft(wrapT, 7, 14) |
MaskAndShiftLeft(addPrev, 1, 17) | MaskAndShiftLeft(indLod, 1, 18) | MaskAndShiftLeft(alphaSel, 3, 19);
if (state.x10_indFlags != flags) {
state.x10_indFlags = flags;
GXSetTevIndirect(stageId, indStage, fmt, biasSel, mtxSel, wrapS, wrapT, addPrev, indLod, alphaSel);
}
}
static inline void SetTevIndWarp(GXTevStageID stageId, GXIndTexStageID indStage, GXBool signedOffset,
@@ -478,6 +490,24 @@ static inline void SetVtxDescv(const GXVtxDescList* descList) noexcept {
SetVtxDescv_Compressed(flags);
}
static inline void SetVtxDesc(GXAttr attr, GXAttrType type) noexcept {
uint lshift = (attr - GX_VA_POS) * 2;
uint rshift = 3 << lshift;
uint flags = type << lshift;
if (flags != (sGXState.x48_descList & rshift)) {
sGXState.x48_descList = flags | (sGXState.x48_descList & ~rshift);
GXSetVtxDesc(attr, type);
}
}
static inline void ResetVtxDescv() noexcept {
static const GXVtxDescList vtxDescList[2] = {
{GX_VA_POS, GX_INDEX16},
{GX_VA_NULL, GX_NONE},
};
SetVtxDescv(vtxDescList);
}
static inline void SetZMode(GXBool compareEnable, GXCompare func, GXBool updateEnable) noexcept {
u32 flags = (func & 0xFF) << 2 | (u8(updateEnable) << 1) | (u8(compareEnable) & 1);
auto& state = sGXState.x52_zmode;
@@ -508,4 +538,8 @@ static inline void GetFog(GXFogType* fogType, float* fogStartZ, float* fogEndZ,
*fogColor = sGXState.x25c_fogColor;
}
}
static inline void LoadTexMtxImm(const float mtx[][4], unsigned long id, GXTexMtxType type) {
GXLoadTexMtxImm(mtx, id, type);
}
} // namespace metaforce::CGX
+14 -11
View File
@@ -224,7 +224,7 @@ void CGraphics::SetCullMode(ERglCullMode cullMode) {
void CGraphics::ClearBackAndDepthBuffers() {
GXInvalidateTexAll();
GXSetViewport(0.f, 0.f, mRenderModeObj.fbWidth, mRenderModeObj.xfbHeight, 0.f, 1.f);
GXSetViewportRender(0.f, 0.f, mRenderModeObj.fbWidth, mRenderModeObj.xfbHeight, 0.f, 1.f);
GXInvalidateVtxCache();
}
@@ -630,19 +630,21 @@ void CGraphics::SetViewport(int left, int bottom, int width, int height) {
mViewport.mHeight = height;
mViewport.mHalfWidth = static_cast<float>(width / 2);
mViewport.mHalfHeight = static_cast<float>(height / 2);
GXSetViewport(static_cast<float>(mViewport.mLeft), static_cast<float>(mViewport.mTop),
static_cast<float>(mViewport.mWidth), static_cast<float>(mViewport.mHeight), mDepthNear, mDepthFar);
GXSetViewportRender(static_cast<float>(mViewport.mLeft), static_cast<float>(mViewport.mTop),
static_cast<float>(mViewport.mWidth), static_cast<float>(mViewport.mHeight), mDepthNear,
mDepthFar);
}
void CGraphics::SetScissor(int left, int bottom, int width, int height) {
GXSetScissor(left, mRenderModeObj.efbHeight - (bottom + height), width, height);
GXSetScissorRender(left, mRenderModeObj.efbHeight - (bottom + height), width, height);
}
void CGraphics::SetDepthRange(float nearPlane, float farPlane) {
mDepthNear = nearPlane;
mDepthFar = farPlane;
GXSetViewport(static_cast<float>(mViewport.mLeft), static_cast<float>(mViewport.mTop),
static_cast<float>(mViewport.mWidth), static_cast<float>(mViewport.mHeight), mDepthNear, mDepthFar);
GXSetViewportRender(static_cast<float>(mViewport.mLeft), static_cast<float>(mViewport.mTop),
static_cast<float>(mViewport.mWidth), static_cast<float>(mViewport.mHeight), mDepthNear,
mDepthFar);
}
float CGraphics::GetSecondsMod900() {
@@ -653,7 +655,7 @@ float CGraphics::GetSecondsMod900() {
}
void CGraphics::TickRenderTimings() {
//OPTICK_EVENT();
// OPTICK_EVENT();
mRenderTimings = (mRenderTimings + 1) % (900 * 60);
mSecondsMod900 = static_cast<float>(mRenderTimings) / 60.f;
}
@@ -1058,12 +1060,13 @@ void CGraphics::ConfigureFrameBuffer(/*const COsContext& osContext*/) {
// mRenderModeObj = osContext.GetRenderModeObj();
// mpFrameBuf1 = osContext.GetFramebuf1();
// mpFrameBuf2 = osContext.GetFramebuf2();
// VIConfigure(&mRenderModeObj);
VIConfigure(&mRenderModeObj);
AuroraSetViewportPolicy(AURORA_VIEWPORT_NATIVE);
// VISetNextFrameBuffer(mpFrameBuf1);
mpCurrenFrameBuf = mpFrameBuf2;
GXSetViewport(0.f, 0.f, static_cast<float>(mRenderModeObj.fbWidth), static_cast<float>(mRenderModeObj.efbHeight), 0.f,
1.f);
GXSetScissor(0, 0, mRenderModeObj.fbWidth, mRenderModeObj.efbHeight);
GXSetViewportRender(0.f, 0.f, static_cast<float>(mRenderModeObj.fbWidth),
static_cast<float>(mRenderModeObj.efbHeight), 0.f, 1.f);
GXSetScissorRender(0, 0, mRenderModeObj.fbWidth, mRenderModeObj.efbHeight);
GXSetDispCopySrc(0, 0, mRenderModeObj.fbWidth, mRenderModeObj.efbHeight);
GXSetDispCopyDst(mRenderModeObj.fbWidth, mRenderModeObj.efbHeight);
GXSetDispCopyYScale(static_cast<float>(mRenderModeObj.xfbHeight) / static_cast<float>(mRenderModeObj.efbHeight));
+1
View File
@@ -130,6 +130,7 @@ public:
[[nodiscard]] bool IsCITexture() const {
return x0_fmt == ETexelFormat::C4 || x0_fmt == ETexelFormat::C8 || x0_fmt == ETexelFormat::C14X2;
}
void SetLocked(bool b) { xa_24_locked = b; }
static void InvalidateTexMap(GXTexMapID id);
static void SetMangleMips(bool b) { sMangleMips = b; }
+6 -1
View File
@@ -12,6 +12,8 @@
#include "TCastTo.hpp" // Generated file, do not modify include path
#include <cmath>
namespace metaforce::MP1 {
CPlayerVisor::CPlayerVisor(CStateManager&) {
@@ -366,7 +368,10 @@ void CPlayerVisor::DrawScanEffect(const CStateManager& mgr, CTargetingManager* t
const zeus::CTransform seventeenScale = zeus::CTransform::Scale(17.f * vpScale, 1.f, 17.f * vpScale);
const zeus::CTransform mm = seventeenScale * windowScale;
g_Renderer->SetModelMatrix(mm);
CGraphics::LoadDolphinSpareTexture(vpW, vpH, GX_TF_RGB565, CGraphics::mpSpareBuffer, GX_TEXMAP0);
const float logicalScale = CGraphics::GetViewportHeight() / 448.f;
CGraphics::LoadDolphinSpareTexture(std::lround(vpW / logicalScale), std::lround(vpH / logicalScale), GX_TF_RGB565,
CGraphics::mpSpareBuffer, GX_TEXMAP0);
if (x108_newScanPane) {
SCOPED_GRAPHICS_DEBUG_GROUP("x108_newScanPane Draw", zeus::skMagenta);
+1 -3
View File
@@ -2163,9 +2163,7 @@ void CPlayerGun::DrawScreenTex(float z) {
g_Renderer->SetViewportOrtho(false, -1.f, 1.f);
g_Renderer->SetBlendMode_AlphaBlended();
CGraphics::SetDepthWriteMode(true, ERglEnum::GEqual, true);
u16 width = CGraphics::mViewport.mWidth / 2;
u16 height = CGraphics::mViewport.mHeight / 2;
CGraphics::LoadDolphinSpareTexture(width, height, GX_TF_RGBA8, nullptr, GX_TEXMAP7);
CGraphics::LoadDolphinSpareTexture(320, 224, GX_TF_RGBA8, nullptr, GX_TEXMAP7);
constexpr std::array vtxDescList{
GXVtxDescList{GX_VA_POS, GX_DIRECT},
GXVtxDescList{GX_VA_TEX0, GX_DIRECT},
File diff suppressed because it is too large Load Diff
+4 -11
View File
@@ -134,20 +134,13 @@ protected:
float x48_rippleIntensity;
CFluidUVMotion x4c_uvMotion;
// std::vector<CFluidPlaneShader::Vertex> m_verts;
// std::vector<CFluidPlaneShader::PatchVertex> m_pVerts;
// std::optional<CFluidPlaneShader> m_shader;
float ProjectRippleVelocity(float baseI, float velDot) const;
float CalculateRippleIntensity(float baseI) const;
// virtual void RenderStripWithRipples(float curY, const Heights& heights, const Flags& flags, int startYDiv,
// const CFluidPlaneRender::SPatchInfo& info,
// std::vector<CFluidPlaneShader::Vertex>& vOut,
// std::vector<CFluidPlaneShader::PatchVertex>& pvOut);
// void RenderPatch(const CFluidPlaneRender::SPatchInfo& info, const Heights& heights, const Flags& flags,
// bool noRipples, bool flagIs1, std::vector<CFluidPlaneShader::Vertex>& vOut,
// std::vector<CFluidPlaneShader::PatchVertex>& pvOut);
void RenderStripWithRipples(const Heights& heights, const Flags& flags, int startYDiv, float curY,
const CFluidPlaneRender::SPatchInfo& info);
void RenderPatch(const CFluidPlaneRender::SPatchInfo& info, const Heights& heights, const Flags& flags,
bool noRipples, bool flaggedGridGen);
public:
virtual ~CFluidPlane() = default;
File diff suppressed because it is too large Load Diff
+6 -4
View File
@@ -79,6 +79,9 @@ protected:
bool UpdatePatch(float time, const CFluidPlaneRender::SPatchInfo& info, Heights& heights, Flags& flags,
const zeus::CVector3f& areaCenter, const std::optional<CRippleManager>& rippleManager, int fromX,
int toX, int fromY, int toY) const;
void CalculateLightmapMtx(const zeus::CTransform& areaXf, const zeus::CTransform& xf, const zeus::CAABox& aabb,
int idx);
void RenderCleanup() const;
public:
CFluidPlaneCPU(CAssetId texPattern1, CAssetId texPattern2, CAssetId texColor, CAssetId bumpMap, CAssetId envMap,
@@ -90,10 +93,9 @@ public:
float reflectionSize, float rippleIntensity, u32 maxVertCount);
void CreateRipple(const CRipple& ripple, CStateManager& mgr);
void CalculateLightmapMatrix(const zeus::CTransform& areaXf, const zeus::CTransform& xf, const zeus::CAABox& aabb,
zeus::CMatrix4f& mtxOut) const;
// CFluidPlaneShader::RenderSetupInfo RenderSetup(const CStateManager& mgr, float, const zeus::CTransform& xf,
// const zeus::CTransform& areaXf, const zeus::CAABox& aabb,
// const CScriptWater* water);
int idx) const;
void RenderSetup(const CStateManager& mgr, float, const zeus::CTransform& xf, const zeus::CTransform& areaXf,
const zeus::CAABox& aabb, const CScriptWater* water);
void Render(const CStateManager& mgr, float alpha, const zeus::CAABox& aabb, const zeus::CTransform& xf,
const zeus::CTransform& areaXf, bool noNormals, const zeus::CFrustum& frustum,
const std::optional<CRippleManager>& rippleManager, TUniqueId waterId, const bool* gridFlags,
+3
View File
@@ -47,6 +47,9 @@ public:
CFluidUVMotion(float timeToWrap, float orientation);
const rstl::reserved_vector<SFluidLayerMotion, 3>& GetFluidLayers() const { return x0_fluidLayers; }
const SFluidLayerMotion& GetFluidLayerMotion(EFluidUVMotion motion) const {
return x0_fluidLayers[static_cast<int>(motion)];
}
float GetOrientation() const { return x50_orientation; }
float GetOOTimeToWrapTexPage() const { return x4c_ooTimeToWrap; }
+1 -1
Vendored
+1 -1
+2
View File
@@ -2,6 +2,8 @@
#include "imgui.h"
#include "misc/cpp/imgui_stdlib.h"
#include <cstdint>
#include <memory>
namespace metaforce {