From e72b05a7ac7e897fe37b855833251159dd60016e Mon Sep 17 00:00:00 2001 From: Luke Street Date: Tue, 15 Apr 2025 19:38:39 -0600 Subject: [PATCH] Reimpl CWorldShadow, OnScreenTex fixes --- Runtime/AutoMapper/CAutoMapper.cpp | 44 +++++------ Runtime/AutoMapper/CMapUniverse.cpp | 63 ++++++++------- Runtime/CStateManager.hpp | 8 +- Runtime/Character/CAnimData.cpp | 4 +- Runtime/Graphics/CCubeMaterial.cpp | 62 +++++++++++---- Runtime/Graphics/CCubeModel.cpp | 4 +- Runtime/Graphics/CCubeModel.hpp | 4 +- Runtime/Graphics/CGX.hpp | 99 ++++++++++++++---------- Runtime/Graphics/CGraphics.cpp | 46 ++++++++--- Runtime/Graphics/CGraphics.hpp | 11 +-- Runtime/Graphics/CMoviePlayer.cpp | 46 +---------- Runtime/Graphics/CTexture.cpp | 30 +++---- Runtime/GuiSys/CSplashScreen.cpp | 2 +- Runtime/MP1/CFrontEndUI.cpp | 6 +- Runtime/MP1/CInGameGuiManager.cpp | 14 ++-- Runtime/Particle/CElementGen.cpp | 4 +- Runtime/World/CScriptSpecialFunction.cpp | 4 +- Runtime/World/CWallCrawlerSwarm.cpp | 9 ++- Runtime/World/CWorldShadow.cpp | 29 ++++--- extern/aurora | 2 +- 20 files changed, 267 insertions(+), 224 deletions(-) diff --git a/Runtime/AutoMapper/CAutoMapper.cpp b/Runtime/AutoMapper/CAutoMapper.cpp index 9f6a4d853..7ad83482b 100644 --- a/Runtime/AutoMapper/CAutoMapper.cpp +++ b/Runtime/AutoMapper/CAutoMapper.cpp @@ -1449,17 +1449,9 @@ void CAutoMapper::Draw(const CStateManager& mgr, const zeus::CTransform& xf, flo if (IsInMapperState(EAutoMapperState::MapScreen)) { CAssetId wldMlvl = x24_world->IGetWorldAssetId(); const CMapWorld* mw = x24_world->IGetMapWorld(); -// std::vector& hintBeaconFilters = m_hintBeaconFilters; -// if (hintBeaconFilters.size() < x1f8_hintLocations.size()) { -// hintBeaconFilters.reserve(x1f8_hintLocations.size()); -// for (u32 i = hintBeaconFilters.size(); i < x1f8_hintLocations.size(); ++i) -// hintBeaconFilters.emplace_back(EFilterType::Add, x3c_hintBeacon); -// } auto locIt = x1f8_hintLocations.cbegin(); -// auto filterIt = hintBeaconFilters.begin(); - for (; locIt != x1f8_hintLocations.cend(); ++locIt/*, ++filterIt*/) { + for (; locIt != x1f8_hintLocations.cend(); ++locIt) { const SAutoMapperHintLocation& loc = *locIt; -// CTexturedQuadFilter& filter = *filterIt; if (loc.x8_worldId != wldMlvl) continue; const CMapArea* mapa = mw->GetMapArea(loc.xc_areaId); @@ -1474,22 +1466,26 @@ void CAutoMapper::Draw(const CStateManager& mgr, const zeus::CTransform& xf, flo beaconAlpha = loc.x4_beaconAlpha; } if (beaconAlpha > 0.f) { -// constexpr std::array verts{{ -// {{-4.f, -8.f, 8.f}, {0.f, 1.f}}, -// {{-4.f, -8.f, 0.f}, {0.f, 0.f}}, -// {{4.f, -8.f, 8.f}, {1.f, 1.f}}, -// {{4.f, -8.f, 0.f}, {1.f, 0.f}}, -// }}; - float colorAlpha = beaconAlpha; - if (x1bc_state != EAutoMapperState::MiniMap && x1c0_nextState != EAutoMapperState::MiniMap) { - } else { - colorAlpha *= xa8_renderStates[0].x34_alphaSurfaceVisited; - } - colorAlpha *= mapAlpha; + CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulate); + x3c_hintBeacon->Load(GX_TEXMAP0, EClampMode::Repeat); + g_Renderer->SetBlendMode_AdditiveAlpha(); + CGraphics::StreamBegin(ERglPrimitive::TriangleStrip); zeus::CColor color = zeus::skWhite; - color.a() = colorAlpha; - // TODO -// filter.drawVerts(color, verts); + color.a() = beaconAlpha * + ((x1bc_state != EAutoMapperState::MiniMap && x1c0_nextState != EAutoMapperState::MiniMap) + ? 1.f + : xa8_renderStates[0].x34_alphaSurfaceVisited) * + mapAlpha; + CGraphics::StreamColor(color); + CGraphics::StreamTexcoord(0.f, 1.f); + CGraphics::StreamVertex(zeus::CVector3f(-4.f, -8.f, 8.f)); + CGraphics::StreamTexcoord(0.f, 0.f); + CGraphics::StreamVertex(zeus::CVector3f(-4.f, -8.f, 0.f)); + CGraphics::StreamTexcoord(1.f, 1.f); + CGraphics::StreamVertex(zeus::CVector3f(4.f, -8.f, 8.f)); + CGraphics::StreamTexcoord(1.f, 0.f); + CGraphics::StreamVertex(zeus::CVector3f(4.f, -8.f, 0.f)); + CGraphics::StreamEnd(); } } } diff --git a/Runtime/AutoMapper/CMapUniverse.cpp b/Runtime/AutoMapper/CMapUniverse.cpp index bf7efd7e3..eb63e13c9 100644 --- a/Runtime/AutoMapper/CMapUniverse.cpp +++ b/Runtime/AutoMapper/CMapUniverse.cpp @@ -16,7 +16,7 @@ CMapUniverse::CMapUniverse(CInputStream& in, u32 version) : x0_hexagonId(in.Get< CMapUniverse::CMapWorldData::CMapWorldData(CInputStream& in, u32 version) : x0_label(in.Get()), x10_worldAssetId(in) { - x14_transform = in.Get(); + x14_transform = in.Get(); const u32 worldCount = in.ReadLong(); x44_hexagonXfs.reserve(worldCount); for (u32 i = 0; i < worldCount; ++i) { @@ -79,37 +79,40 @@ void CMapUniverse::Draw(const CMapUniverseDrawParms& parms, const zeus::CVector3 } } - std::sort(sortInfos.begin(), sortInfos.end(), [](const CMapObjectSortInfo& a, const CMapObjectSortInfo& b) { - return a.GetZDistance() > b.GetZDistance(); - }); + if (!sortInfos.empty()) { + std::sort(sortInfos.begin(), sortInfos.end(), [](const CMapObjectSortInfo& a, const CMapObjectSortInfo& b) { + return a.GetZDistance() > b.GetZDistance(); + }); + CMapArea::CMapAreaSurface::SetupGXMaterial(); - int lastWldIdx = -1; - int lastHexIdx = -1; - for (const CMapObjectSortInfo& info : sortInfos) { - const CMapWorldData& mwData = x10_worldDatas[info.GetWorldIndex()]; - zeus::CColor surfColor = info.GetSurfaceColor(); - zeus::CColor outlineColor = info.GetOutlineColor(); - if (parms.GetWorldAssetId() == mwData.GetWorldAssetId() && parms.GetClosestArea() == info.GetAreaIndex()) { - surfColor = zeus::CColor::lerp(g_tweakAutoMapper->GetSurfaceSelectVisitedColor(), - g_tweakAutoMapper->GetAreaFlashPulseColor(), parms.GetFlashPulse()); - surfColor.a() = info.GetSurfaceColor().a(); - outlineColor = zeus::CColor::lerp(g_tweakAutoMapper->GetOutlineSelectVisitedColor(), - g_tweakAutoMapper->GetAreaFlashPulseColor(), parms.GetFlashPulse()); - outlineColor.a() = info.GetOutlineColor().a(); + int lastWldIdx = -1; + int lastHexIdx = -1; + for (const CMapObjectSortInfo& info : sortInfos) { + const CMapWorldData& mwData = x10_worldDatas[info.GetWorldIndex()]; + zeus::CColor surfColor = info.GetSurfaceColor(); + zeus::CColor outlineColor = info.GetOutlineColor(); + if (parms.GetWorldAssetId() == mwData.GetWorldAssetId() && parms.GetClosestArea() == info.GetAreaIndex()) { + surfColor = zeus::CColor::lerp(g_tweakAutoMapper->GetSurfaceSelectVisitedColor(), + g_tweakAutoMapper->GetAreaFlashPulseColor(), parms.GetFlashPulse()); + surfColor.a() = info.GetSurfaceColor().a(); + outlineColor = zeus::CColor::lerp(g_tweakAutoMapper->GetOutlineSelectVisitedColor(), + g_tweakAutoMapper->GetAreaFlashPulseColor(), parms.GetFlashPulse()); + outlineColor.a() = info.GetOutlineColor().a(); + } + + zeus::CTransform hexXf = mwData.GetMapAreaData(info.GetAreaIndex()); + hexXf.orthonormalize(); + CMapArea::CMapAreaSurface& surf = x4_hexagonToken->GetSurface(info.GetObjectIndex()); + zeus::CColor color(std::max(0.f, (-parms.GetCameraTransform().basis[1]).dot(hexXf.rotate(surf.GetNormal()))) * + g_tweakAutoMapper->GetMapSurfaceNormColorLinear() + + g_tweakAutoMapper->GetMapSurfaceNormColorConstant()); + surfColor *= color; + + if (info.GetAreaIndex() != lastHexIdx || info.GetWorldIndex() != lastWldIdx) + CGraphics::SetModelMatrix(parms.GetPaneProjectionTransform() * mwData.GetMapAreaData(info.GetAreaIndex())); + + surf.Draw(x4_hexagonToken->GetVertices(), surfColor, outlineColor, 2.f); } - - zeus::CTransform hexXf = mwData.GetMapAreaData(info.GetAreaIndex()); - hexXf.orthonormalize(); - CMapArea::CMapAreaSurface& surf = x4_hexagonToken->GetSurface(info.GetObjectIndex()); - zeus::CColor color(std::max(0.f, (-parms.GetCameraTransform().basis[1]).dot(hexXf.rotate(surf.GetNormal()))) * - g_tweakAutoMapper->GetMapSurfaceNormColorLinear() + - g_tweakAutoMapper->GetMapSurfaceNormColorConstant()); - surfColor *= color; - - if (info.GetAreaIndex() != lastHexIdx || info.GetWorldIndex() != lastWldIdx) - CGraphics::SetModelMatrix(parms.GetPaneProjectionTransform() * mwData.GetMapAreaData(info.GetAreaIndex())); - - surf.Draw(x4_hexagonToken->GetVertices(), surfColor, outlineColor, 2.f); } } diff --git a/Runtime/CStateManager.hpp b/Runtime/CStateManager.hpp index 3357947cf..5d295fe9f 100644 --- a/Runtime/CStateManager.hpp +++ b/Runtime/CStateManager.hpp @@ -69,8 +69,8 @@ struct SScriptObjectStream { struct SOnScreenTex { CAssetId x0_id; - zeus::CVector2i x4_origin; - zeus::CVector2i xc_extent; + zeus::CVector2i x4_extent; + zeus::CVector2i xc_origin; }; enum class EStateManagerTransition { InGame, MapScreen, PauseGame, LogBook, SaveGame, MessageScreen }; @@ -428,8 +428,8 @@ public: u32 GetBossStringIdx() const { return xf20_bossStringIdx; } void SetPendingOnScreenTex(CAssetId texId, const zeus::CVector2i& origin, const zeus::CVector2i& extent) { xef4_pendingScreenTex.x0_id = texId; - xef4_pendingScreenTex.x4_origin = origin; - xef4_pendingScreenTex.xc_extent = extent; + xef4_pendingScreenTex.x4_extent = origin; + xef4_pendingScreenTex.xc_origin = extent; } const SOnScreenTex& GetPendingScreenTex() const { return xef4_pendingScreenTex; } void SetViewportScale(const zeus::CVector2f& scale) { xf2c_viewportScale = scale; } diff --git a/Runtime/Character/CAnimData.cpp b/Runtime/Character/CAnimData.cpp index 01eaac9c1..25189b2ed 100644 --- a/Runtime/Character/CAnimData.cpp +++ b/Runtime/Character/CAnimData.cpp @@ -560,7 +560,9 @@ void CAnimData::SetupRender(CSkinnedModel& model, CVertexMorphEffect* morphEffec } void CAnimData::DrawSkinnedModel(CSkinnedModel& model, const CModelFlags& flags) { - CGX::SetChanCtrl(CGX::EChannelId::Channel0, CGraphics::mLightActive); + CGX::SetChanCtrl(CGX::EChannelId::Channel0, GX_ENABLE, GX_SRC_REG, GX_SRC_REG, CGraphics::mLightActive, + CGraphics::mLightActive.any() ? GX_DF_CLAMP : GX_DF_NONE, + CGraphics::mLightActive.any() ? GX_AF_SPOT : GX_AF_NONE); model.Draw(flags); } diff --git a/Runtime/Graphics/CCubeMaterial.cpp b/Runtime/Graphics/CCubeMaterial.cpp index f4c98956c..b9359e9cf 100644 --- a/Runtime/Graphics/CCubeMaterial.cpp +++ b/Runtime/Graphics/CCubeMaterial.cpp @@ -6,6 +6,7 @@ #include "Graphics/CCubeSurface.hpp" #include "Graphics/CGX.hpp" #include "Graphics/CModel.hpp" +#include "Logging.hpp" namespace metaforce { static u32 sReflectionType = 0; @@ -307,16 +308,21 @@ void CCubeMaterial::EnsureViewDepStateCached(const CCubeSurface* surface) { } u32 CCubeMaterial::HandleColorChannels(u32 chanCount, u32 firstChan) { + static constexpr GXColor sGXBlack = {0, 0, 0, 0}; + static constexpr GXColor sGXWhite = {0xFF, 0xFF, 0xFF, 0xFF}; + if (CCubeModel::sRenderModelShadow) { if (chanCount != 0) { - CGX::SetChanAmbColor(CGX::EChannelId::Channel1, GX_BLACK); - CGX::SetChanMatColor(CGX::EChannelId::Channel1, GX_WHITE); + CGX::SetChanAmbColor(CGX::EChannelId::Channel1, sGXBlack); + CGX::SetChanMatColor(CGX::EChannelId::Channel1, sGXWhite); - auto chan0Lights = CGraphics::mLightActive & ~CCubeModel::sChannel0DisableLightMask; - CGX::SetChanCtrl(CGX::EChannelId::Channel0, firstChan, chan0Lights); - CGX::SetChanCtrl(CGX::EChannelId::Channel1, CCubeModel::sChannel1EnableLightMask); + CGX::SetChanCtrl(CGX::EChannelId::Channel1, true, GX_SRC_REG, GX_SRC_REG, CCubeModel::sChannel1EnableLightMask, + GX_DF_CLAMP, GX_AF_SPOT); + + const auto chan0Lights = CGraphics::GetLightMask() & ~CCubeModel::sChannel0DisableLightMask; + CGX::SetChanCtrl_Compressed(CGX::EChannelId::Channel0, chan0Lights, firstChan); if (chan0Lights.any()) { - CGX::SetChanMatColor(CGX::EChannelId::Channel0, GX_WHITE); + CGX::SetChanMatColor(CGX::EChannelId::Channel0, sGXWhite); } else { CGX::SetChanMatColor(CGX::EChannelId::Channel0, CGX::GetChanAmbColor(CGX::EChannelId::Channel0)); } @@ -325,21 +331,22 @@ u32 CCubeMaterial::HandleColorChannels(u32 chanCount, u32 firstChan) { } if (chanCount == 2) { - CGX::SetChanAmbColor(CGX::EChannelId::Channel1, GX_BLACK); - CGX::SetChanMatColor(CGX::EChannelId::Channel1, GX_WHITE); + CGX::SetChanAmbColor(CGX::EChannelId::Channel1, sGXBlack); + CGX::SetChanMatColor(CGX::EChannelId::Channel1, sGXWhite); } else { - CGX::SetChanCtrl(CGX::EChannelId::Channel1, {}); + CGX::SetChanCtrl(CGX::EChannelId::Channel1, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); } - if (chanCount == 0) { - CGX::SetChanCtrl(CGX::EChannelId::Channel0, {}); - } else { - CGX::SetChanCtrl(CGX::EChannelId::Channel0, firstChan, CGraphics::mLightActive); - if (CGraphics::mLightActive.any()) { - CGX::SetChanMatColor(CGX::EChannelId::Channel0, GX_WHITE); + if (chanCount >= 1) { + const auto lightMask = CGraphics::GetLightMask(); + CGX::SetChanCtrl_Compressed(CGX::EChannelId::Channel0, lightMask, firstChan); + if (lightMask.any()) { + CGX::SetChanMatColor(CGX::EChannelId::Channel0, sGXWhite); } else { CGX::SetChanMatColor(CGX::EChannelId::Channel0, CGX::GetChanAmbColor(CGX::EChannelId::Channel0)); } + } else { + CGX::SetChanCtrl(CGX::EChannelId::Channel0, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); } return chanCount; @@ -603,8 +610,29 @@ void CCubeMaterial::DoPassthru(u32 finalTevCount) { } void CCubeMaterial::DoModelShadow(u32 texCount, u32 tcgCount) { - // CCubeModel::sShadowTexture->Load(texCount, EClampMode::One); - // TODO + CCubeModel::sShadowTexture->Load(static_cast(texCount), EClampMode::Repeat); + const auto& xf = CCubeModel::sTextureProjectionTransform; + Mtx mtx = { + {xf.basis[0][0], xf.basis[1][0], xf.basis[2][0], xf.origin.x()}, + {xf.basis[0][2], xf.basis[1][2], xf.basis[2][2], xf.origin.z()}, + {0.f, 0.f, 0.f, 1.f}, + }; + GXLoadTexMtxImm(mtx, GX_TEXMTX5, GX_MTX3x4); + + CGX::SetTexCoordGen(static_cast(tcgCount), GX_TG_MTX3x4, GX_TG_POS, GX_TEXMTX5, GX_FALSE, + GX_PTIDENTITY); + CGX::SetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVREG0); + CGX::SetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVREG0); + CGX::SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_RASC, GX_CC_TEXC, GX_CC_ZERO); + CGX::SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA); + CGX::SetTevOrder(GX_TEVSTAGE0, static_cast(tcgCount), static_cast(texCount), GX_COLOR1A1); + + CGX::SetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVREG0); + CGX::SetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVREG0); + CGX::SetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_RASC, GX_CC_ONE, GX_CC_C0); + CGX::SetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_RASA, GX_CA_KONST, GX_CA_A0); + CGX::SetTevKAlphaSel(GX_TEVSTAGE1, GX_TEV_KASEL_1); + CGX::SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); } static GXTevStageID sCurrentTevStage = GX_MAX_TEVSTAGE; diff --git a/Runtime/Graphics/CCubeModel.cpp b/Runtime/Graphics/CCubeModel.cpp index ed6e8262c..19a699b79 100644 --- a/Runtime/Graphics/CCubeModel.cpp +++ b/Runtime/Graphics/CCubeModel.cpp @@ -11,7 +11,7 @@ namespace metaforce { bool CCubeModel::sRenderModelBlack = false; bool CCubeModel::sRenderModelShadow = false; bool CCubeModel::sUsingPackedLightmaps = false; -const CTexture* CCubeModel::sShadowTexture = nullptr; +CTexture* CCubeModel::sShadowTexture = nullptr; zeus::CTransform CCubeModel::sTextureProjectionTransform; GX::LightMask CCubeModel::sChannel0DisableLightMask; GX::LightMask CCubeModel::sChannel1EnableLightMask; @@ -246,7 +246,7 @@ void CCubeModel::DrawSurfaceWireframe(const CCubeSurface& surface) { // TODO convert vertices to line strips and draw } -void CCubeModel::EnableShadowMaps(const CTexture& shadowTex, const zeus::CTransform& textureProjXf, +void CCubeModel::EnableShadowMaps(CTexture& shadowTex, const zeus::CTransform& textureProjXf, GX::LightMask chan0DisableMask, GX::LightMask chan1EnableLightMask) { sRenderModelShadow = true; sShadowTexture = &shadowTex; diff --git a/Runtime/Graphics/CCubeModel.hpp b/Runtime/Graphics/CCubeModel.hpp index 2dd4ef1c9..e5b737494 100644 --- a/Runtime/Graphics/CCubeModel.hpp +++ b/Runtime/Graphics/CCubeModel.hpp @@ -121,7 +121,7 @@ public: } [[nodiscard]] TCachedToken& GetTexture(u32 idx) const { return x1c_textures->at(idx); } - static void EnableShadowMaps(const CTexture& shadowTex, const zeus::CTransform& textureProjXf, + static void EnableShadowMaps(CTexture& shadowTex, const zeus::CTransform& textureProjXf, GX::LightMask chan0DisableMask, GX::LightMask chan1EnableLightMask); static void DisableShadowMaps(); static void MakeTexturesFromMats(const u8* ptr, std::vector>& texture, IObjectStore* store, @@ -142,7 +142,7 @@ private: static bool sRenderModelBlack; static bool sUsingPackedLightmaps; static bool sRenderModelShadow; - static const CTexture* sShadowTexture; + static CTexture* sShadowTexture; static zeus::CTransform sTextureProjectionTransform; static GX::LightMask sChannel0DisableLightMask; static GX::LightMask sChannel1EnableLightMask; diff --git a/Runtime/Graphics/CGX.hpp b/Runtime/Graphics/CGX.hpp index 23685bca4..54722bcb0 100644 --- a/Runtime/Graphics/CGX.hpp +++ b/Runtime/Graphics/CGX.hpp @@ -32,7 +32,15 @@ struct SGXState { std::array x38_chanAmbColors; std::array x40_chanMatColors; u32 x48_descList = 0; - u8 x4c_dirtyChans = 0; + union { + u8 x4c_chanFlags = 0; + // Ordering swapped for LE + struct { + u8 numDirty : 1; + u8 chansDirty : 2; + u8 unused : 5; + } x4c_flags; + }; u8 x4d_prevNumChans = 0; u8 x4e_numChans = 0; u8 x4f_numTexGens = 0; @@ -55,6 +63,9 @@ struct SGXState { extern SGXState sGXState; extern std::array sVtxDescList; +static inline u32 MaskAndShiftLeft(u32 v, u32 m, u32 s) { return (v & m) << s; } +static inline u32 ShiftRightAndMask(u32 v, u32 m, u32 s) { return (v >> s) & m; } + static inline void update_fog(u32 value) noexcept { if (sGXState.x53_fogType == GX_FOG_NONE || (sGXState.x56_blendMode & 0xE0) == (value & 0xE0)) { return; @@ -67,28 +78,37 @@ static inline void update_fog(u32 value) noexcept { } static inline void FlushState() noexcept { - if ((sGXState.x4c_dirtyChans & 1) != 0) { - u8 numChans = sGXState.x4e_numChans; - GXSetNumChans(numChans); - sGXState.x4d_prevNumChans = numChans; + if (sGXState.x4c_chanFlags & 1) { + GXSetNumChans(sGXState.x4e_numChans); + sGXState.x4d_prevNumChans = sGXState.x4e_numChans; } - if ((sGXState.x4c_dirtyChans & 2) != 0) { - auto flags = sGXState.x34_chanCtrls[0]; - GXSetChanCtrl(GX_COLOR0, GXBool(flags & 1), GXColorSrc(flags >> 1 & 1), GXColorSrc(flags >> 2 & 1), - flags >> 3 & 0xFF, GXDiffuseFn(flags >> 11 & 3), GXAttnFn(flags >> 13 & 3)); - sGXState.x30_prevChanCtrls[0] = flags; + if (sGXState.x4c_chanFlags & 2) { + u16 flags = sGXState.x34_chanCtrls[0]; + GXBool enable = ShiftRightAndMask(flags, 1, 0); + GXColorSrc ambSrc = static_cast(ShiftRightAndMask(flags, 1, 1)); + GXColorSrc matSrc = static_cast(ShiftRightAndMask(flags, 1, 2)); + u32 lightMask = ShiftRightAndMask(flags, 0xFF, 3); + GXDiffuseFn diffFn = static_cast(ShiftRightAndMask(flags, 3, 11)); + GXAttnFn attnFn = static_cast(ShiftRightAndMask(flags, 3, 13)); + GXSetChanCtrl(GX_COLOR0, enable, ambSrc, matSrc, lightMask, diffFn, attnFn); + sGXState.x30_prevChanCtrls[0] = sGXState.x34_chanCtrls[0]; } - if ((sGXState.x4c_dirtyChans & 4) != 0) { - auto flags = sGXState.x34_chanCtrls[1]; - GXSetChanCtrl(GX_COLOR1, GXBool(flags & 1), GXColorSrc(flags >> 1 & 1), GXColorSrc(flags >> 2 & 1), - flags >> 3 & 0xFF, GXDiffuseFn(flags >> 11 & 3), GXAttnFn(flags >> 13 & 3)); - sGXState.x30_prevChanCtrls[1] = flags; + if (sGXState.x4c_chanFlags & 4) { + u16 flags = sGXState.x34_chanCtrls[1]; + GXBool enable = ShiftRightAndMask(flags, 1, 0); + GXColorSrc ambSrc = static_cast(ShiftRightAndMask(flags, 1, 1)); + GXColorSrc matSrc = static_cast(ShiftRightAndMask(flags, 1, 2)); + u32 lightMask = ShiftRightAndMask(flags, 0xFF, 3); + GXDiffuseFn diffFn = static_cast(ShiftRightAndMask(flags, 3, 11)); + GXAttnFn attnFn = static_cast(ShiftRightAndMask(flags, 3, 13)); + GXSetChanCtrl(GX_COLOR1, enable, ambSrc, matSrc, lightMask, diffFn, attnFn); + sGXState.x30_prevChanCtrls[1] = sGXState.x34_chanCtrls[1]; } - sGXState.x4c_dirtyChans = 0; + sGXState.x4c_chanFlags = 0; } static inline void Begin(GXPrimitive primitive, GXVtxFmt fmt, u16 nverts) noexcept { - if (sGXState.x4c_dirtyChans != 0) { + if (sGXState.x4c_chanFlags != 0) { FlushState(); } GXBegin(primitive, fmt, nverts); @@ -97,7 +117,7 @@ static inline void Begin(GXPrimitive primitive, GXVtxFmt fmt, u16 nverts) noexce static inline void End() noexcept { GXEnd(); } static inline void CallDisplayList(const void* data, u32 nbytes) noexcept { - if (sGXState.x4c_dirtyChans != 0) { + if (sGXState.x4c_chanFlags != 0) { FlushState(); } GXCallDisplayList(data, nbytes); @@ -165,30 +185,31 @@ static inline void SetChanAmbColor(EChannelId id, const zeus::CColor& color) noe SetChanAmbColor(id, to_gx_color(color)); } -static inline void SetChanCtrl(EChannelId id, GXBool enable, GXColorSrc ambSrc, GXColorSrc matSrc, GX::LightMask lights, - GXDiffuseFn diffFn, GXAttnFn attnFn) noexcept { - const auto idx = std::underlying_type_t(id); +static inline void SetChanCtrl(EChannelId channel, GXBool enable, GXColorSrc ambSrc, GXColorSrc matSrc, + GX::LightMask lights, GXDiffuseFn diffFn, GXAttnFn attnFn) noexcept { + const auto idx = static_cast>(channel); + u16& state = sGXState.x34_chanCtrls[idx]; + u16 prevFlags = sGXState.x30_prevChanCtrls[idx]; if (lights.none()) { - enable = false; + enable = GX_FALSE; } - const u32 flags = (attnFn & 3) << 13 | (diffFn & 3) << 11 | (lights.to_ulong() & 0xFF) << 3 | (matSrc & 1) << 2 | - (ambSrc & 1) << 1 | (u8(enable) & 1); - sGXState.x34_chanCtrls[idx] = flags; - sGXState.x4c_dirtyChans = 7; // TODO + u32 flags = MaskAndShiftLeft(enable, 1, 0) | MaskAndShiftLeft(ambSrc, 1, 1) | MaskAndShiftLeft(matSrc, 1, 2) | + MaskAndShiftLeft(lights.to_ulong(), 0xFF, 3) | MaskAndShiftLeft(diffFn, 3, 11) | + MaskAndShiftLeft(attnFn, 3, 13); + state = flags; + sGXState.x4c_chanFlags = ((flags != prevFlags) << (idx + 1)) | (sGXState.x4c_chanFlags & ~(1 << (idx + 1))); } -// Flags with lights override -static inline void SetChanCtrl(EChannelId id, u32 flags, GX::LightMask lights) noexcept { - const auto idx = std::underlying_type_t(id); - sGXState.x34_chanCtrls[idx] = lights.any() ? (flags | lights.to_ulong() << 3) : (flags & 0xFFFFFFFE); - sGXState.x4c_dirtyChans = 7; // TODO -} - -// Helper function for common logic -static inline void SetChanCtrl(EChannelId id, GX::LightMask lights) noexcept { - const bool hasLights = lights.any(); - SetChanCtrl(id, hasLights, GX_SRC_REG, GX_SRC_REG, lights, hasLights ? GX_DF_CLAMP : GX_DF_NONE, - hasLights ? GX_AF_SPOT : GX_AF_NONE); +static inline void SetChanCtrl_Compressed(EChannelId channel, GX::LightMask lights, u32 ctrl) { + const auto idx = static_cast>(channel); + u16& state = sGXState.x34_chanCtrls[idx]; + u16 prevFlags = sGXState.x30_prevChanCtrls[idx]; + u32 flags = ctrl & ~1; + if (lights.any()) { + flags = ctrl | (lights.to_ulong() & 0xFF) << 3; + } + state = flags; + sGXState.x4c_chanFlags = ((flags != prevFlags) << (idx + 1)) | (sGXState.x4c_chanFlags & ~(1 << (idx + 1))); } static inline void SetChanMatColor(EChannelId id, GXColor color) noexcept { @@ -222,8 +243,8 @@ void SetIndTexMtxSTPointFive(GXIndTexMtxID id, s8 scaleExp) noexcept; void SetLineWidth(u8 width, GXTexOffset offset) noexcept; static inline void SetNumChans(u8 num) noexcept { - sGXState.x4c_dirtyChans = 7; // TODO sGXState.x4e_numChans = num; + sGXState.x4c_flags.numDirty = sGXState.x4e_numChans != sGXState.x4d_prevNumChans; } static inline void SetNumIndStages(u8 num) noexcept { diff --git a/Runtime/Graphics/CGraphics.cpp b/Runtime/Graphics/CGraphics.cpp index ece451430..ba7358723 100644 --- a/Runtime/Graphics/CGraphics.cpp +++ b/Runtime/Graphics/CGraphics.cpp @@ -270,25 +270,47 @@ static constexpr GXVtxDescList skPosColorTexDirect[] = { {GX_VA_NULL, GX_DIRECT}, }; -void CGraphics::Render2D(CTexture& tex, u32 x, u32 y, u32 w, u32 h, const zeus::CColor& col) { +void CGraphics::Render2D(CTexture& tex, int x, int y, int w, int h, const zeus::CColor& col, bool scale) { Mtx44 proj; - MTXOrtho(proj, mViewport.mHeight / 2, -(mViewport.mHeight / 2), -(mViewport.mWidth / 2), mViewport.mWidth / 2, -1.f, - -10.f); + if (scale) { + const float viewportAspect = GetViewportAspect(); + float left = -320.f; + float right = 320.f; + float top = 224.f; + float bottom = -224.f; + if (viewportAspect > 4.f / 3.f) { + float width = 224.0f * viewportAspect; + left = -width; + right = width; + } else { + float height = 320.0f / viewportAspect; + top = height; + bottom = -height; + } + MTXOrtho(proj, top, bottom, left, right, -1.f, -10.f); + } else { + MTXOrtho(proj, mViewport.mHeight / 2, -(mViewport.mHeight / 2), -(mViewport.mWidth / 2), mViewport.mWidth / 2, -1.f, + -10.f); + } GXSetProjection(proj, GX_ORTHOGRAPHIC); uint c = col.toRGBA(); Mtx mtx; MTXIdentity(mtx); GXLoadPosMtxImm(mtx, GX_PNMTX0); - const float scaledX = static_cast(x) / 640.f * static_cast(mViewport.mWidth); - const float scaledY = static_cast(y) / 448.f * static_cast(mViewport.mHeight); - const float scaledW = static_cast(w) / 640.f * static_cast(mViewport.mWidth); - const float scaledH = static_cast(h) / 448.f * static_cast(mViewport.mHeight); - const float x1 = scaledX - (mViewport.mWidth / 2); - const float y1 = scaledY - (mViewport.mHeight / 2); - const float x2 = x1 + scaledW; - const float y2 = y1 + scaledH; + float x2, y2, x1, y1; + if (scale) { + x1 = x - 320; + y1 = y - 224; + x2 = x1 + w; + y2 = y1 + h; + } else { + x1 = x - mViewport.mWidth / 2; + y1 = y - mViewport.mHeight / 2; + x2 = x1 + w; + y2 = y1 + h; + } // Save state + setup CGX::SetVtxDescv(skPosColorTexDirect); @@ -299,9 +321,9 @@ void CGraphics::Render2D(CTexture& tex, u32 x, u32 y, u32 w, u32 h, const zeus:: } ERglCullMode cullMode = mCullMode; SetCullMode(ERglCullMode::None); + tex.Load(GX_TEXMAP0, EClampMode::Repeat); // Draw - tex.Load(GX_TEXMAP0, EClampMode::Repeat); CGX::Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4); GXPosition3f32(x1, y1, 1.f); GXColor1u32(c); diff --git a/Runtime/Graphics/CGraphics.hpp b/Runtime/Graphics/CGraphics.hpp index 179ec7b11..271fd09f8 100644 --- a/Runtime/Graphics/CGraphics.hpp +++ b/Runtime/Graphics/CGraphics.hpp @@ -340,7 +340,7 @@ public: static void SetCullMode(ERglCullMode); static void BeginScene(); static void EndScene(); - static void Render2D(CTexture& tex, u32 x, u32 y, u32 w, u32 h, const zeus::CColor& col); + static void Render2D(CTexture& tex, int x, int y, int w, int h, const zeus::CColor& col, bool scale); static void SetAlphaCompare(ERglAlphaFunc comp0, u8 ref0, ERglAlphaOp op, ERglAlphaFunc comp1, u8 ref1); static void SetViewPointMatrix(const zeus::CTransform& xf); static void SetViewMatrix(); @@ -373,10 +373,10 @@ public: static void SetClearColor(const zeus::CColor& color); static void SetCopyClear(const zeus::CColor& color, float depth); static void SetIsBeginSceneClearFb(bool clear); - static u32 GetViewportLeft() { return mViewport.mLeft; } - static u32 GetViewportTop() { return mViewport.mTop; } - static u32 GetViewportWidth() { return mViewport.mWidth; } - static u32 GetViewportHeight() { return mViewport.mHeight; } + static int GetViewportLeft() { return mViewport.mLeft; } + static int GetViewportTop() { return mViewport.mTop; } + static int GetViewportWidth() { return mViewport.mWidth; } + static int GetViewportHeight() { return mViewport.mHeight; } static float GetViewportHalfWidth() { return mViewport.mHalfWidth; } static float GetViewportHalfHeight() { return mViewport.mHalfHeight; } static float GetViewportAspect() { @@ -385,6 +385,7 @@ public: static const CVector3f& GetViewPoint() { return mViewPoint; } static const CTransform4f& GetViewMatrix() { return mViewMatrix; } static const CTransform4f& GetModelMatrix() { return mModelMatrix; } + static GX::LightMask GetLightMask() { return mLightActive; } static void LoadDolphinSpareTexture(int width, int height, GXTexFmt format, void* data, GXTexMapID id); static void LoadDolphinSpareTexture(int width, int height, GXCITexFmt format, GXTlut tlut, void* data, GXTexMapID id); diff --git a/Runtime/Graphics/CMoviePlayer.cpp b/Runtime/Graphics/CMoviePlayer.cpp index 69886445b..01ca3e577 100644 --- a/Runtime/Graphics/CMoviePlayer.cpp +++ b/Runtime/Graphics/CMoviePlayer.cpp @@ -464,9 +464,10 @@ bool CMoviePlayer::DrawVideo() { const s32 vpLeft = CGraphics::GetViewportLeft(); #ifdef AURORA // Scale to full size, maintaining aspect ratio - float vidAspect = static_cast(x6c_videoInfo.width) / static_cast(x6c_videoInfo.height); - const s32 vidWidth = vpHeight * vidAspect; - const s32 vidHeight = vpHeight; + const float scale = std::min(static_cast(CGraphics::GetViewportWidth()) / 640.0f, + static_cast(CGraphics::GetViewportHeight()) / 448.0f); + const s32 vidWidth = x6c_videoInfo.width * scale; + const s32 vidHeight = x6c_videoInfo.height * scale; #else const s32 vidWidth = x6c_videoInfo.width; const s32 vidHeight = x6c_videoInfo.height; @@ -507,20 +508,6 @@ void CMoviePlayer::DrawFrame(const zeus::CVector3f& v1, const zeus::CVector3f& v CGraphics::SetUseVideoFilter(xf4_26_fieldFlip); - /* Correct movie aspect ratio */ - float hPad, vPad; - if (CGraphics::GetViewportAspect() >= 1.78f) { - hPad = 1.78f / CGraphics::GetViewportAspect(); - vPad = 1.78f / 1.33f; - } else { - hPad = 1.f; - vPad = CGraphics::GetViewportAspect() / 1.33f; - } - - // /* draw appropriate field */ - // CTHPTextureSet& tex = x80_textures[xd0_drawTexSlot]; - // aurora::gfx::queue_movie_player(tex.Y[m_deinterlace ? (xfc_fieldIndex != 0) : 0], tex.U, tex.V, hPad, vPad); - MyTHPGXYuv2RgbSetup(CGraphics::mLastFrameUsedAbove, xf4_26_fieldFlip); uintptr_t planeSize = x6c_videoInfo.width * x6c_videoInfo.height; uintptr_t planeSizeQuarter = planeSize / 4; @@ -646,31 +633,6 @@ void CMoviePlayer::DecodeFromRead(const void* data) { case THPComponents::Type::Video: { tjDecompressToYUV(TjHandle, (u8*)inptr, frameHeader.imageSize, m_yuvBuf.get(), 0); inptr += frameHeader.imageSize; - - uintptr_t planeSize = x6c_videoInfo.width * x6c_videoInfo.height; - uintptr_t planeSizeHalf = planeSize / 2; - uintptr_t planeSizeQuarter = planeSizeHalf / 2; - - // if (m_deinterlace) { - // /* Deinterlace into 2 discrete 60-fps half-res textures */ - // auto buffer = std::make_unique(planeSizeHalf); - // for (unsigned y = 0; y < x6c_videoInfo.height / 2; ++y) { - // memcpy(buffer.get() + x6c_videoInfo.width * y, m_yuvBuf.get() + x6c_videoInfo.width * (y * 2), - // x6c_videoInfo.width); - // } - // aurora::gfx::write_texture(*tex.Y[0], {buffer.get(), planeSizeHalf}); - // for (unsigned y = 0; y < x6c_videoInfo.height / 2; ++y) { - // memcpy(buffer.get() + x6c_videoInfo.width * y, m_yuvBuf.get() + x6c_videoInfo.width * (y * 2 + 1), - // x6c_videoInfo.width); - // } - // aurora::gfx::write_texture(*tex.Y[1], {buffer.get(), planeSizeHalf}); - // } else { - // /* Direct planar load */ - // aurora::gfx::write_texture(*tex.Y[0], {m_yuvBuf.get(), planeSize}); - // } - // aurora::gfx::write_texture(*tex.U, {m_yuvBuf.get() + planeSize, planeSizeQuarter}); - // aurora::gfx::write_texture(*tex.V, {m_yuvBuf.get() + planeSize + planeSizeQuarter, planeSizeQuarter}); - break; } case THPComponents::Type::Audio: diff --git a/Runtime/Graphics/CTexture.cpp b/Runtime/Graphics/CTexture.cpp index b0433559c..ef96e387c 100644 --- a/Runtime/Graphics/CTexture.cpp +++ b/Runtime/Graphics/CTexture.cpp @@ -258,22 +258,22 @@ void CTexture::MangleMipmap(u32 mip) { return; } - constexpr uint colors[4] = { + constexpr u32 colors[4] = { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x0000FFFF, }; - const uint color = colors[(mip - 1) & 3]; - const ushort rgb565Color = ((color >> 3) & 0x001F) | // B - ((color >> 5) & 0x07E0) | // G - ((color >> 8) & 0xF800); // R - const ushort rgb555Color = ((color >> 3) & 0x001F) | // B - ((color >> 6) & 0x03E0) | // G - ((color >> 9) & 0x7C00); // R - const ushort rgb4Color = ((color >> 4) & 0x000F) | // B - ((color >> 8) & 0x00F0) | // G - ((color >> 12) & 0x0F00); // R + const u32 color = colors[(mip - 1) & 3]; + const u16 rgb565Color = ((color >> 3) & 0x001F) | // B + ((color >> 5) & 0x07E0) | // G + ((color >> 8) & 0xF800); // R + const u16 rgb555Color = ((color >> 3) & 0x001F) | // B + ((color >> 6) & 0x03E0) | // G + ((color >> 9) & 0x7C00); // R + const u16 rgb4Color = ((color >> 4) & 0x000F) | // B + ((color >> 8) & 0x00F0) | // G + ((color >> 12) & 0x0F00); // R int width = GetWidth(); int height = GetHeight(); @@ -287,7 +287,7 @@ void CTexture::MangleMipmap(u32 mip) { switch (GetTexelFormat()) { case ETexelFormat::RGB565: { - const auto ptr = reinterpret_cast(x44_aramToken_x4_buff.get()); // mARAMToken.GetMRAMSafe()); + const auto ptr = reinterpret_cast(x44_aramToken_x4_buff.get()); // mARAMToken.GetMRAMSafe()); for (int i = 0; i < width * height; ++i) { ptr[i + offset] = rgb565Color; CBasics::Swap2Bytes(reinterpret_cast(&ptr[i + offset])); @@ -295,7 +295,7 @@ void CTexture::MangleMipmap(u32 mip) { break; } case ETexelFormat::CMPR: { - auto ptr = reinterpret_cast(x44_aramToken_x4_buff.get()) + offset / 4; + auto ptr = reinterpret_cast(x44_aramToken_x4_buff.get()) + offset / 4; for (int i = 0; i < width * height / 16; ++i, ptr += 4) { ptr[0] = rgb565Color; CBasics::Swap2Bytes(reinterpret_cast(&ptr[0])); @@ -307,9 +307,9 @@ void CTexture::MangleMipmap(u32 mip) { break; } case ETexelFormat::RGB5A3: { - const auto ptr = reinterpret_cast(x44_aramToken_x4_buff.get()); + const auto ptr = reinterpret_cast(x44_aramToken_x4_buff.get()); for (int i = 0; i < width * height; ++i) { - ushort& val = ptr[i + offset]; + u16& val = ptr[i + offset]; CBasics::Swap2Bytes(reinterpret_cast(&val)); if ((val & 0x8000) != 0) { val = rgb555Color | 0x8000; diff --git a/Runtime/GuiSys/CSplashScreen.cpp b/Runtime/GuiSys/CSplashScreen.cpp index 375c82241..647dd927d 100644 --- a/Runtime/GuiSys/CSplashScreen.cpp +++ b/Runtime/GuiSys/CSplashScreen.cpp @@ -92,7 +92,7 @@ void CSplashScreen::Draw() { CGraphics::SetCullMode(ERglCullMode::Front); } else { // TODO originally uses CGraphics viewport, but Render2D needs scaling fix - CGraphics::Render2D(tex, 0, 0, 640, 448, color); + CGraphics::Render2D(tex, 0, 0, 640, 448, color, true); } // Progressive scan options omitted diff --git a/Runtime/MP1/CFrontEndUI.cpp b/Runtime/MP1/CFrontEndUI.cpp index 0fb2663a7..012c71dac 100644 --- a/Runtime/MP1/CFrontEndUI.cpp +++ b/Runtime/MP1/CFrontEndUI.cpp @@ -1825,10 +1825,10 @@ void CFrontEndUI::Draw() { CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru); g_Renderer->SetBlendMode_AdditiveAlpha(); g_Renderer->SetDepthReadWrite(false, false); - const auto width = x38_pressStart->GetWidth(); - const auto height = x38_pressStart->GetHeight(); + const int width = x38_pressStart->GetWidth(); + const int height = x38_pressStart->GetHeight(); CGraphics::Render2D(*x38_pressStart, 320 - (width / 2), 72 - (height / 2), width, - height, zeus::CColor{1.f, x64_pressStartAlpha}); + height, zeus::CColor{1.f, x64_pressStartAlpha}, true); } if (xc0_attractCount > 0) { diff --git a/Runtime/MP1/CInGameGuiManager.cpp b/Runtime/MP1/CInGameGuiManager.cpp index 118b17bb7..130c496c1 100644 --- a/Runtime/MP1/CInGameGuiManager.cpp +++ b/Runtime/MP1/CInGameGuiManager.cpp @@ -337,8 +337,8 @@ void CInGameGuiManager::Update(CStateManager& stateMgr, float dt, CArchitectureQ } } else { if (!stateMgr.GetPendingScreenTex().x0_id.IsValid() && - stateMgr.GetPendingScreenTex().x4_origin == zeus::CVector2i(0, 0)) { - x1c4_onScreenTex.x4_origin = stateMgr.GetPendingScreenTex().x4_origin; + stateMgr.GetPendingScreenTex().x4_extent == zeus::CVector2i(0, 0)) { + x1c4_onScreenTex.x4_extent = stateMgr.GetPendingScreenTex().x4_extent; x1c4_onScreenTex.x0_id = {}; x1d8_onScreenTexAlpha = 0.f; } else { @@ -477,11 +477,11 @@ void CInGameGuiManager::Draw(CStateManager& stateMgr) { g_Renderer->SetBlendMode_AlphaBlended(); CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulate); CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru); - int w = x1c4_onScreenTex.x4_origin.x; - int h = x1c4_onScreenTex.x4_origin.y; - int x = CGraphics::GetViewportLeft() + (CGraphics::GetViewportWidth() - w) / 2 + x1c4_onScreenTex.xc_extent.x; - int y = CGraphics::GetViewportTop() + (CGraphics::GetViewportHeight() - h) / 2 - x1c4_onScreenTex.xc_extent.y; - CGraphics::Render2D(*x1dc_onScreenTexTok, x, y, w, h, zeus::CColor{1.f, x1d8_onScreenTexAlpha}); + int w = x1c4_onScreenTex.x4_extent.x; + int h = x1c4_onScreenTex.x4_extent.y; + int x = (640 - w) / 2 + x1c4_onScreenTex.xc_origin.x; + int y = (448 - h) / 2 - x1c4_onScreenTex.xc_origin.y; + CGraphics::Render2D(*x1dc_onScreenTexTok, x, y, w, h, zeus::CColor{1.f, x1d8_onScreenTexAlpha}, true); } float staticAlpha = 0.f; diff --git a/Runtime/Particle/CElementGen.cpp b/Runtime/Particle/CElementGen.cpp index 428294040..980639188 100644 --- a/Runtime/Particle/CElementGen.cpp +++ b/Runtime/Particle/CElementGen.cpp @@ -913,7 +913,7 @@ void CElementGen::RenderModels() { GXVtxDescList{GX_VA_NULL, GX_NONE}, }; CGX::SetVtxDescv(vtxDescList.data()); - CGX::SetChanCtrl(CGX::EChannelId::Channel0, {}); + CGX::SetChanCtrl(CGX::EChannelId::Channel0, false, GX_SRC_REG, GX_SRC_VTX, {}, GX_DF_NONE, GX_AF_NONE); CGX::SetNumChans(1); CGX::SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, false, GX_PTIDENTITY); CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); @@ -1271,7 +1271,7 @@ void CElementGen::RenderParticles() { CGX::SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR1A1); CGX::SetChanAmbColor(CGX::EChannelId::Channel1, zeus::skBlack); CGX::SetChanMatColor(CGX::EChannelId::Channel1, x338_moduColor); - CGX::SetChanCtrl(CGX::EChannelId::Channel1, {}); + CGX::SetChanCtrl(CGX::EChannelId::Channel1, false, GX_SRC_REG, GX_SRC_REG, {}, GX_DF_NONE, GX_AF_NONE); } else { CGX::SetNumChans(1); nextStage = GX_TEVSTAGE1; diff --git a/Runtime/World/CScriptSpecialFunction.cpp b/Runtime/World/CScriptSpecialFunction.cpp index cebbf069e..b6cd34cdb 100644 --- a/Runtime/World/CScriptSpecialFunction.cpp +++ b/Runtime/World/CScriptSpecialFunction.cpp @@ -449,13 +449,13 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId const SObjectTag* objectTag = g_ResFactory->GetResourceIdByName(xec_locatorName); const CAssetId assetId = objectTag ? objectTag->id : CAssetId(); - mgr.SetPendingOnScreenTex(assetId, {int(x104_float3), int(x108_float4)}, {int(xfc_float1), int(x100_float2)}); + mgr.SetPendingOnScreenTex(assetId, {int(xfc_float1), int(x100_float2)}, {int(x104_float3), int(x108_float4)}); if (objectTag) { x1e8_ = g_SimplePool->GetObj(*objectTag); x1e5_26_displayBillboard = true; } } else if (msg == EScriptObjectMessage::Decrement) { - mgr.SetPendingOnScreenTex({}, {int(x104_float3), int(x108_float4)}, {int(xfc_float1), int(x100_float2)}); + mgr.SetPendingOnScreenTex({}, {int(xfc_float1), int(x100_float2)}, {int(x104_float3), int(x108_float4)}); if (x1e8_) x1e8_ = TLockedToken(); x1e5_26_displayBillboard = false; diff --git a/Runtime/World/CWallCrawlerSwarm.cpp b/Runtime/World/CWallCrawlerSwarm.cpp index d0ab58d59..ba6ae8eaf 100644 --- a/Runtime/World/CWallCrawlerSwarm.cpp +++ b/Runtime/World/CWallCrawlerSwarm.cpp @@ -1070,9 +1070,8 @@ void CWallCrawlerSwarm::RenderBoid(const CBoid* boid, u32& drawMask, bool therma } void CWallCrawlerSwarm::Render(CStateManager& mgr) { - SCOPED_GRAPHICS_DEBUG_GROUP( - fmt::format("CWallCrawlerSwarm::Render {} {} {}", x8_uid, xc_editorId, x10_name).c_str(), - zeus::skOrange); + SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format("CWallCrawlerSwarm::Render {} {} {}", x8_uid, xc_editorId, x10_name).c_str(), + zeus::skOrange); u32 drawMask = 0xffffffff; const bool r24 = x560_24_enableLighting; const bool r23 = x560_25_useSoftwareLight; @@ -1086,7 +1085,9 @@ void CWallCrawlerSwarm::Render(CStateManager& mgr) { if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) { flags = CModelFlags(5, 0, 3, zeus::CColor(1.f, 0.3f)); } - CGX::SetChanCtrl(CGX::EChannelId::Channel0, CGraphics::mLightActive); + CGX::SetChanCtrl(CGX::EChannelId::Channel0, r24 && !r23, GX_SRC_REG, GX_SRC_REG, CGraphics::mLightActive, + CGraphics::mLightActive.any() ? GX_DF_CLAMP : GX_DF_NONE, + CGraphics::mLightActive.any() ? GX_AF_SPOT : GX_AF_NONE); for (int r27 = 0; r27 < 5; ++r27) { for (int r28 = 0; r28 < 5; ++r28) { diff --git a/Runtime/World/CWorldShadow.cpp b/Runtime/World/CWorldShadow.cpp index ccdc7de51..80a350814 100644 --- a/Runtime/World/CWorldShadow.cpp +++ b/Runtime/World/CWorldShadow.cpp @@ -19,7 +19,7 @@ void CWorldShadow::EnableModelProjectedShadow(const zeus::CTransform& pos, s32 l texTransform = zeus::CTransform::Translate(0.5f, 0.f, 0.5f) * texTransform; GX::LightMask lightMask; lightMask.set(lightIdx); - // CCubeModel::EnableShadowMaps(*x0_texture, texTransform, lightMask, lightMask); + CCubeModel::EnableShadowMaps(*x0_texture, texTransform, lightMask, lightMask); } void CWorldShadow::DisableModelProjectedShadow() { CCubeModel::DisableShadowMaps(); } @@ -32,7 +32,6 @@ void CWorldShadow::BuildLightShadowTexture(const CStateManager& mgr, TAreaId aid x84_lightIdx = lightIdx; } - return; // TODO if (aid != kInvalidAreaId) { const CGameArea* area = mgr.GetWorld()->GetAreaAlways(aid); if (area->IsPostConstructed()) { @@ -60,16 +59,16 @@ void CWorldShadow::BuildLightShadowTexture(const CStateManager& mgr, TAreaId aid frustum.updatePlanes(x4_view, zeus::SProjPersp(zeus::degToRad(fov), 1.f, 0.1f, distance + x64_objHalfExtent)); g_Renderer->SetClippingPlanes(frustum); g_Renderer->SetPerspective(fov, x0_texture->GetWidth(), x0_texture->GetHeight(), 0.1f, 1000.f); - CViewport backupVp = CGraphics::mViewport; float backupDepthNear = CGraphics::mDepthNear; float backupDepthFar = CGraphics::mDepthFar; - g_Renderer->SetViewport(0, 0, x0_texture->GetWidth(), x0_texture->GetHeight()); CGraphics::SetDepthRange(DEPTH_NEAR, DEPTH_FAR); - - x34_model = zeus::lookAt(centerPoint - zeus::CVector3f(0.f, 0.f, 0.1f), light.GetPosition()); - CGraphics::SetModelMatrix(x34_model); + CViewport backupVp = CGraphics::mViewport; + g_Renderer->SetViewport(0, 0, x0_texture->GetWidth() * 2, x0_texture->GetHeight() * 2); float extent = float(M_SQRT2) * x64_objHalfExtent; + x34_model = zeus::lookAt(centerPoint - zeus::CVector3f(0.f, 0.f, 0.1f), light.GetPosition()); + g_Renderer->SetModelMatrix(x34_model); + g_Renderer->PrimColor(zeus::skWhite); CGraphics::SetAlphaCompare(ERglAlphaFunc::Always, 0, ERglAlphaOp::And, ERglAlphaFunc::Always, 0); CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, true); @@ -77,6 +76,7 @@ void CWorldShadow::BuildLightShadowTexture(const CStateManager& mgr, TAreaId aid ERglLogicOp::Clear); CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvPassthru); CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru); + g_Renderer->BeginTriangleStrip(4); g_Renderer->PrimVertex({-extent, 0.f, extent}); g_Renderer->PrimVertex({extent, 0.f, extent}); @@ -118,15 +118,22 @@ void CWorldShadow::BuildLightShadowTexture(const CStateManager& mgr, TAreaId aid CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulate); CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru); CGraphics::Render2D(*x0_texture, 0, x0_texture->GetWidth() * 2, x0_texture->GetHeight() * 2, - x0_texture->GetWidth() * -2, zeus::CColor{1.f, 0.85f}); + x0_texture->GetWidth() * -2, zeus::CColor{1.f, 0.85f}, false); CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, true); } x88_blurReset = false; - // TODO - // m_shader.resolveTexture(); - // CBooRenderer::BindMainDrawTarget(); + GXSetTexCopySrc(0, CGraphics::mRenderModeObj.efbHeight - x0_texture->GetHeight() * 2, + x0_texture->GetWidth() * 2, x0_texture->GetHeight() * 2); + GXTexFmt fmt = GX_TF_RGBA8; + if (x0_texture->GetTexelFormat() == ETexelFormat::RGB565) { + fmt = GX_TF_RGB565; + } + GXSetTexCopyDst(x0_texture->GetWidth(), x0_texture->GetHeight(), fmt, true); + void* dest = x0_texture->Lock(); + GXCopyTex(dest, true); + x0_texture->UnLock(); g_Renderer->SetViewport(backupVp.mLeft, backupVp.mTop, backupVp.mWidth, backupVp.mHeight); CGraphics::SetDepthRange(backupDepthNear, backupDepthFar); diff --git a/extern/aurora b/extern/aurora index 788c65592..357ecba0a 160000 --- a/extern/aurora +++ b/extern/aurora @@ -1 +1 @@ -Subproject commit 788c65592f07c3ca8e8b8bff303f4777fd2dd0cd +Subproject commit 357ecba0ae00246332447823fddd83b8da89357f