2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-05-13 11:11:22 +00:00

Reimpl CWorldShadow, OnScreenTex fixes

This commit is contained in:
Luke Street 2025-04-15 19:38:39 -06:00
parent 166f901ffd
commit e72b05a7ac
20 changed files with 267 additions and 224 deletions

View File

@ -1449,17 +1449,9 @@ void CAutoMapper::Draw(const CStateManager& mgr, const zeus::CTransform& xf, flo
if (IsInMapperState(EAutoMapperState::MapScreen)) { if (IsInMapperState(EAutoMapperState::MapScreen)) {
CAssetId wldMlvl = x24_world->IGetWorldAssetId(); CAssetId wldMlvl = x24_world->IGetWorldAssetId();
const CMapWorld* mw = x24_world->IGetMapWorld(); const CMapWorld* mw = x24_world->IGetMapWorld();
// std::vector<CTexturedQuadFilter>& 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 locIt = x1f8_hintLocations.cbegin();
// auto filterIt = hintBeaconFilters.begin(); for (; locIt != x1f8_hintLocations.cend(); ++locIt) {
for (; locIt != x1f8_hintLocations.cend(); ++locIt/*, ++filterIt*/) {
const SAutoMapperHintLocation& loc = *locIt; const SAutoMapperHintLocation& loc = *locIt;
// CTexturedQuadFilter& filter = *filterIt;
if (loc.x8_worldId != wldMlvl) if (loc.x8_worldId != wldMlvl)
continue; continue;
const CMapArea* mapa = mw->GetMapArea(loc.xc_areaId); 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; beaconAlpha = loc.x4_beaconAlpha;
} }
if (beaconAlpha > 0.f) { if (beaconAlpha > 0.f) {
// constexpr std::array<CTexturedQuadFilter::Vert, 4> verts{{ CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulate);
// {{-4.f, -8.f, 8.f}, {0.f, 1.f}}, x3c_hintBeacon->Load(GX_TEXMAP0, EClampMode::Repeat);
// {{-4.f, -8.f, 0.f}, {0.f, 0.f}}, g_Renderer->SetBlendMode_AdditiveAlpha();
// {{4.f, -8.f, 8.f}, {1.f, 1.f}}, CGraphics::StreamBegin(ERglPrimitive::TriangleStrip);
// {{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;
zeus::CColor color = zeus::skWhite; zeus::CColor color = zeus::skWhite;
color.a() = colorAlpha; color.a() = beaconAlpha *
// TODO ((x1bc_state != EAutoMapperState::MiniMap && x1c0_nextState != EAutoMapperState::MiniMap)
// filter.drawVerts(color, verts); ? 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();
} }
} }
} }

View File

@ -79,9 +79,11 @@ void CMapUniverse::Draw(const CMapUniverseDrawParms& parms, const zeus::CVector3
} }
} }
if (!sortInfos.empty()) {
std::sort(sortInfos.begin(), sortInfos.end(), [](const CMapObjectSortInfo& a, const CMapObjectSortInfo& b) { std::sort(sortInfos.begin(), sortInfos.end(), [](const CMapObjectSortInfo& a, const CMapObjectSortInfo& b) {
return a.GetZDistance() > b.GetZDistance(); return a.GetZDistance() > b.GetZDistance();
}); });
CMapArea::CMapAreaSurface::SetupGXMaterial();
int lastWldIdx = -1; int lastWldIdx = -1;
int lastHexIdx = -1; int lastHexIdx = -1;
@ -111,6 +113,7 @@ void CMapUniverse::Draw(const CMapUniverseDrawParms& parms, const zeus::CVector3
surf.Draw(x4_hexagonToken->GetVertices(), surfColor, outlineColor, 2.f); surf.Draw(x4_hexagonToken->GetVertices(), surfColor, outlineColor, 2.f);
} }
}
} }
CFactoryFnReturn FMapUniverseFactory(const SObjectTag&, CInputStream& in, const CVParamTransfer&, CObjectReference*) { CFactoryFnReturn FMapUniverseFactory(const SObjectTag&, CInputStream& in, const CVParamTransfer&, CObjectReference*) {

View File

@ -69,8 +69,8 @@ struct SScriptObjectStream {
struct SOnScreenTex { struct SOnScreenTex {
CAssetId x0_id; CAssetId x0_id;
zeus::CVector2i x4_origin; zeus::CVector2i x4_extent;
zeus::CVector2i xc_extent; zeus::CVector2i xc_origin;
}; };
enum class EStateManagerTransition { InGame, MapScreen, PauseGame, LogBook, SaveGame, MessageScreen }; enum class EStateManagerTransition { InGame, MapScreen, PauseGame, LogBook, SaveGame, MessageScreen };
@ -428,8 +428,8 @@ public:
u32 GetBossStringIdx() const { return xf20_bossStringIdx; } u32 GetBossStringIdx() const { return xf20_bossStringIdx; }
void SetPendingOnScreenTex(CAssetId texId, const zeus::CVector2i& origin, const zeus::CVector2i& extent) { void SetPendingOnScreenTex(CAssetId texId, const zeus::CVector2i& origin, const zeus::CVector2i& extent) {
xef4_pendingScreenTex.x0_id = texId; xef4_pendingScreenTex.x0_id = texId;
xef4_pendingScreenTex.x4_origin = origin; xef4_pendingScreenTex.x4_extent = origin;
xef4_pendingScreenTex.xc_extent = extent; xef4_pendingScreenTex.xc_origin = extent;
} }
const SOnScreenTex& GetPendingScreenTex() const { return xef4_pendingScreenTex; } const SOnScreenTex& GetPendingScreenTex() const { return xef4_pendingScreenTex; }
void SetViewportScale(const zeus::CVector2f& scale) { xf2c_viewportScale = scale; } void SetViewportScale(const zeus::CVector2f& scale) { xf2c_viewportScale = scale; }

View File

@ -560,7 +560,9 @@ void CAnimData::SetupRender(CSkinnedModel& model, CVertexMorphEffect* morphEffec
} }
void CAnimData::DrawSkinnedModel(CSkinnedModel& model, const CModelFlags& flags) { 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); model.Draw(flags);
} }

View File

@ -6,6 +6,7 @@
#include "Graphics/CCubeSurface.hpp" #include "Graphics/CCubeSurface.hpp"
#include "Graphics/CGX.hpp" #include "Graphics/CGX.hpp"
#include "Graphics/CModel.hpp" #include "Graphics/CModel.hpp"
#include "Logging.hpp"
namespace metaforce { namespace metaforce {
static u32 sReflectionType = 0; static u32 sReflectionType = 0;
@ -307,16 +308,21 @@ void CCubeMaterial::EnsureViewDepStateCached(const CCubeSurface* surface) {
} }
u32 CCubeMaterial::HandleColorChannels(u32 chanCount, u32 firstChan) { 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 (CCubeModel::sRenderModelShadow) {
if (chanCount != 0) { if (chanCount != 0) {
CGX::SetChanAmbColor(CGX::EChannelId::Channel1, GX_BLACK); CGX::SetChanAmbColor(CGX::EChannelId::Channel1, sGXBlack);
CGX::SetChanMatColor(CGX::EChannelId::Channel1, GX_WHITE); CGX::SetChanMatColor(CGX::EChannelId::Channel1, sGXWhite);
auto chan0Lights = CGraphics::mLightActive & ~CCubeModel::sChannel0DisableLightMask; CGX::SetChanCtrl(CGX::EChannelId::Channel1, true, GX_SRC_REG, GX_SRC_REG, CCubeModel::sChannel1EnableLightMask,
CGX::SetChanCtrl(CGX::EChannelId::Channel0, firstChan, chan0Lights); GX_DF_CLAMP, GX_AF_SPOT);
CGX::SetChanCtrl(CGX::EChannelId::Channel1, CCubeModel::sChannel1EnableLightMask);
const auto chan0Lights = CGraphics::GetLightMask() & ~CCubeModel::sChannel0DisableLightMask;
CGX::SetChanCtrl_Compressed(CGX::EChannelId::Channel0, chan0Lights, firstChan);
if (chan0Lights.any()) { if (chan0Lights.any()) {
CGX::SetChanMatColor(CGX::EChannelId::Channel0, GX_WHITE); CGX::SetChanMatColor(CGX::EChannelId::Channel0, sGXWhite);
} else { } else {
CGX::SetChanMatColor(CGX::EChannelId::Channel0, CGX::GetChanAmbColor(CGX::EChannelId::Channel0)); CGX::SetChanMatColor(CGX::EChannelId::Channel0, CGX::GetChanAmbColor(CGX::EChannelId::Channel0));
} }
@ -325,21 +331,22 @@ u32 CCubeMaterial::HandleColorChannels(u32 chanCount, u32 firstChan) {
} }
if (chanCount == 2) { if (chanCount == 2) {
CGX::SetChanAmbColor(CGX::EChannelId::Channel1, GX_BLACK); CGX::SetChanAmbColor(CGX::EChannelId::Channel1, sGXBlack);
CGX::SetChanMatColor(CGX::EChannelId::Channel1, GX_WHITE); CGX::SetChanMatColor(CGX::EChannelId::Channel1, sGXWhite);
} else { } 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) { if (chanCount >= 1) {
CGX::SetChanCtrl(CGX::EChannelId::Channel0, {}); const auto lightMask = CGraphics::GetLightMask();
} else { CGX::SetChanCtrl_Compressed(CGX::EChannelId::Channel0, lightMask, firstChan);
CGX::SetChanCtrl(CGX::EChannelId::Channel0, firstChan, CGraphics::mLightActive); if (lightMask.any()) {
if (CGraphics::mLightActive.any()) { CGX::SetChanMatColor(CGX::EChannelId::Channel0, sGXWhite);
CGX::SetChanMatColor(CGX::EChannelId::Channel0, GX_WHITE);
} else { } else {
CGX::SetChanMatColor(CGX::EChannelId::Channel0, CGX::GetChanAmbColor(CGX::EChannelId::Channel0)); 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; return chanCount;
@ -603,8 +610,29 @@ void CCubeMaterial::DoPassthru(u32 finalTevCount) {
} }
void CCubeMaterial::DoModelShadow(u32 texCount, u32 tcgCount) { void CCubeMaterial::DoModelShadow(u32 texCount, u32 tcgCount) {
// CCubeModel::sShadowTexture->Load(texCount, EClampMode::One); CCubeModel::sShadowTexture->Load(static_cast<GXTexMapID>(texCount), EClampMode::Repeat);
// TODO 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<GXTexCoordID>(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<GXTexCoordID>(tcgCount), static_cast<GXTexMapID>(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; static GXTevStageID sCurrentTevStage = GX_MAX_TEVSTAGE;

View File

@ -11,7 +11,7 @@ namespace metaforce {
bool CCubeModel::sRenderModelBlack = false; bool CCubeModel::sRenderModelBlack = false;
bool CCubeModel::sRenderModelShadow = false; bool CCubeModel::sRenderModelShadow = false;
bool CCubeModel::sUsingPackedLightmaps = false; bool CCubeModel::sUsingPackedLightmaps = false;
const CTexture* CCubeModel::sShadowTexture = nullptr; CTexture* CCubeModel::sShadowTexture = nullptr;
zeus::CTransform CCubeModel::sTextureProjectionTransform; zeus::CTransform CCubeModel::sTextureProjectionTransform;
GX::LightMask CCubeModel::sChannel0DisableLightMask; GX::LightMask CCubeModel::sChannel0DisableLightMask;
GX::LightMask CCubeModel::sChannel1EnableLightMask; GX::LightMask CCubeModel::sChannel1EnableLightMask;
@ -246,7 +246,7 @@ void CCubeModel::DrawSurfaceWireframe(const CCubeSurface& surface) {
// TODO convert vertices to line strips and draw // 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) { GX::LightMask chan0DisableMask, GX::LightMask chan1EnableLightMask) {
sRenderModelShadow = true; sRenderModelShadow = true;
sShadowTexture = &shadowTex; sShadowTexture = &shadowTex;

View File

@ -121,7 +121,7 @@ public:
} }
[[nodiscard]] TCachedToken<CTexture>& GetTexture(u32 idx) const { return x1c_textures->at(idx); } [[nodiscard]] TCachedToken<CTexture>& 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); GX::LightMask chan0DisableMask, GX::LightMask chan1EnableLightMask);
static void DisableShadowMaps(); static void DisableShadowMaps();
static void MakeTexturesFromMats(const u8* ptr, std::vector<TCachedToken<CTexture>>& texture, IObjectStore* store, static void MakeTexturesFromMats(const u8* ptr, std::vector<TCachedToken<CTexture>>& texture, IObjectStore* store,
@ -142,7 +142,7 @@ private:
static bool sRenderModelBlack; static bool sRenderModelBlack;
static bool sUsingPackedLightmaps; static bool sUsingPackedLightmaps;
static bool sRenderModelShadow; static bool sRenderModelShadow;
static const CTexture* sShadowTexture; static CTexture* sShadowTexture;
static zeus::CTransform sTextureProjectionTransform; static zeus::CTransform sTextureProjectionTransform;
static GX::LightMask sChannel0DisableLightMask; static GX::LightMask sChannel0DisableLightMask;
static GX::LightMask sChannel1EnableLightMask; static GX::LightMask sChannel1EnableLightMask;

View File

@ -32,7 +32,15 @@ struct SGXState {
std::array<GXColor, 2> x38_chanAmbColors; std::array<GXColor, 2> x38_chanAmbColors;
std::array<GXColor, 2> x40_chanMatColors; std::array<GXColor, 2> x40_chanMatColors;
u32 x48_descList = 0; 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 x4d_prevNumChans = 0;
u8 x4e_numChans = 0; u8 x4e_numChans = 0;
u8 x4f_numTexGens = 0; u8 x4f_numTexGens = 0;
@ -55,6 +63,9 @@ struct SGXState {
extern SGXState sGXState; extern SGXState sGXState;
extern std::array<GXVtxDescList, 12> sVtxDescList; extern std::array<GXVtxDescList, 12> 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 { static inline void update_fog(u32 value) noexcept {
if (sGXState.x53_fogType == GX_FOG_NONE || (sGXState.x56_blendMode & 0xE0) == (value & 0xE0)) { if (sGXState.x53_fogType == GX_FOG_NONE || (sGXState.x56_blendMode & 0xE0) == (value & 0xE0)) {
return; return;
@ -67,28 +78,37 @@ static inline void update_fog(u32 value) noexcept {
} }
static inline void FlushState() noexcept { static inline void FlushState() noexcept {
if ((sGXState.x4c_dirtyChans & 1) != 0) { if (sGXState.x4c_chanFlags & 1) {
u8 numChans = sGXState.x4e_numChans; GXSetNumChans(sGXState.x4e_numChans);
GXSetNumChans(numChans); sGXState.x4d_prevNumChans = sGXState.x4e_numChans;
sGXState.x4d_prevNumChans = numChans;
} }
if ((sGXState.x4c_dirtyChans & 2) != 0) { if (sGXState.x4c_chanFlags & 2) {
auto flags = sGXState.x34_chanCtrls[0]; u16 flags = sGXState.x34_chanCtrls[0];
GXSetChanCtrl(GX_COLOR0, GXBool(flags & 1), GXColorSrc(flags >> 1 & 1), GXColorSrc(flags >> 2 & 1), GXBool enable = ShiftRightAndMask(flags, 1, 0);
flags >> 3 & 0xFF, GXDiffuseFn(flags >> 11 & 3), GXAttnFn(flags >> 13 & 3)); GXColorSrc ambSrc = static_cast<GXColorSrc>(ShiftRightAndMask(flags, 1, 1));
sGXState.x30_prevChanCtrls[0] = flags; GXColorSrc matSrc = static_cast<GXColorSrc>(ShiftRightAndMask(flags, 1, 2));
u32 lightMask = ShiftRightAndMask(flags, 0xFF, 3);
GXDiffuseFn diffFn = static_cast<GXDiffuseFn>(ShiftRightAndMask(flags, 3, 11));
GXAttnFn attnFn = static_cast<GXAttnFn>(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) { if (sGXState.x4c_chanFlags & 4) {
auto flags = sGXState.x34_chanCtrls[1]; u16 flags = sGXState.x34_chanCtrls[1];
GXSetChanCtrl(GX_COLOR1, GXBool(flags & 1), GXColorSrc(flags >> 1 & 1), GXColorSrc(flags >> 2 & 1), GXBool enable = ShiftRightAndMask(flags, 1, 0);
flags >> 3 & 0xFF, GXDiffuseFn(flags >> 11 & 3), GXAttnFn(flags >> 13 & 3)); GXColorSrc ambSrc = static_cast<GXColorSrc>(ShiftRightAndMask(flags, 1, 1));
sGXState.x30_prevChanCtrls[1] = flags; GXColorSrc matSrc = static_cast<GXColorSrc>(ShiftRightAndMask(flags, 1, 2));
u32 lightMask = ShiftRightAndMask(flags, 0xFF, 3);
GXDiffuseFn diffFn = static_cast<GXDiffuseFn>(ShiftRightAndMask(flags, 3, 11));
GXAttnFn attnFn = static_cast<GXAttnFn>(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 { static inline void Begin(GXPrimitive primitive, GXVtxFmt fmt, u16 nverts) noexcept {
if (sGXState.x4c_dirtyChans != 0) { if (sGXState.x4c_chanFlags != 0) {
FlushState(); FlushState();
} }
GXBegin(primitive, fmt, nverts); 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 End() noexcept { GXEnd(); }
static inline void CallDisplayList(const void* data, u32 nbytes) noexcept { static inline void CallDisplayList(const void* data, u32 nbytes) noexcept {
if (sGXState.x4c_dirtyChans != 0) { if (sGXState.x4c_chanFlags != 0) {
FlushState(); FlushState();
} }
GXCallDisplayList(data, nbytes); GXCallDisplayList(data, nbytes);
@ -165,30 +185,31 @@ static inline void SetChanAmbColor(EChannelId id, const zeus::CColor& color) noe
SetChanAmbColor(id, to_gx_color(color)); SetChanAmbColor(id, to_gx_color(color));
} }
static inline void SetChanCtrl(EChannelId id, GXBool enable, GXColorSrc ambSrc, GXColorSrc matSrc, GX::LightMask lights, static inline void SetChanCtrl(EChannelId channel, GXBool enable, GXColorSrc ambSrc, GXColorSrc matSrc,
GXDiffuseFn diffFn, GXAttnFn attnFn) noexcept { GX::LightMask lights, GXDiffuseFn diffFn, GXAttnFn attnFn) noexcept {
const auto idx = std::underlying_type_t<EChannelId>(id); const auto idx = static_cast<std::underlying_type_t<EChannelId>>(channel);
u16& state = sGXState.x34_chanCtrls[idx];
u16 prevFlags = sGXState.x30_prevChanCtrls[idx];
if (lights.none()) { 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 | u32 flags = MaskAndShiftLeft(enable, 1, 0) | MaskAndShiftLeft(ambSrc, 1, 1) | MaskAndShiftLeft(matSrc, 1, 2) |
(ambSrc & 1) << 1 | (u8(enable) & 1); MaskAndShiftLeft(lights.to_ulong(), 0xFF, 3) | MaskAndShiftLeft(diffFn, 3, 11) |
sGXState.x34_chanCtrls[idx] = flags; MaskAndShiftLeft(attnFn, 3, 13);
sGXState.x4c_dirtyChans = 7; // TODO state = flags;
sGXState.x4c_chanFlags = ((flags != prevFlags) << (idx + 1)) | (sGXState.x4c_chanFlags & ~(1 << (idx + 1)));
} }
// Flags with lights override static inline void SetChanCtrl_Compressed(EChannelId channel, GX::LightMask lights, u32 ctrl) {
static inline void SetChanCtrl(EChannelId id, u32 flags, GX::LightMask lights) noexcept { const auto idx = static_cast<std::underlying_type_t<EChannelId>>(channel);
const auto idx = std::underlying_type_t<EChannelId>(id); u16& state = sGXState.x34_chanCtrls[idx];
sGXState.x34_chanCtrls[idx] = lights.any() ? (flags | lights.to_ulong() << 3) : (flags & 0xFFFFFFFE); u16 prevFlags = sGXState.x30_prevChanCtrls[idx];
sGXState.x4c_dirtyChans = 7; // TODO u32 flags = ctrl & ~1;
} if (lights.any()) {
flags = ctrl | (lights.to_ulong() & 0xFF) << 3;
// Helper function for common logic }
static inline void SetChanCtrl(EChannelId id, GX::LightMask lights) noexcept { state = flags;
const bool hasLights = lights.any(); sGXState.x4c_chanFlags = ((flags != prevFlags) << (idx + 1)) | (sGXState.x4c_chanFlags & ~(1 << (idx + 1)));
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 SetChanMatColor(EChannelId id, GXColor color) noexcept { 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; void SetLineWidth(u8 width, GXTexOffset offset) noexcept;
static inline void SetNumChans(u8 num) noexcept { static inline void SetNumChans(u8 num) noexcept {
sGXState.x4c_dirtyChans = 7; // TODO
sGXState.x4e_numChans = num; sGXState.x4e_numChans = num;
sGXState.x4c_flags.numDirty = sGXState.x4e_numChans != sGXState.x4d_prevNumChans;
} }
static inline void SetNumIndStages(u8 num) noexcept { static inline void SetNumIndStages(u8 num) noexcept {

View File

@ -270,25 +270,47 @@ static constexpr GXVtxDescList skPosColorTexDirect[] = {
{GX_VA_NULL, GX_DIRECT}, {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; Mtx44 proj;
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, MTXOrtho(proj, mViewport.mHeight / 2, -(mViewport.mHeight / 2), -(mViewport.mWidth / 2), mViewport.mWidth / 2, -1.f,
-10.f); -10.f);
}
GXSetProjection(proj, GX_ORTHOGRAPHIC); GXSetProjection(proj, GX_ORTHOGRAPHIC);
uint c = col.toRGBA(); uint c = col.toRGBA();
Mtx mtx; Mtx mtx;
MTXIdentity(mtx); MTXIdentity(mtx);
GXLoadPosMtxImm(mtx, GX_PNMTX0); GXLoadPosMtxImm(mtx, GX_PNMTX0);
const float scaledX = static_cast<float>(x) / 640.f * static_cast<float>(mViewport.mWidth);
const float scaledY = static_cast<float>(y) / 448.f * static_cast<float>(mViewport.mHeight);
const float scaledW = static_cast<float>(w) / 640.f * static_cast<float>(mViewport.mWidth);
const float scaledH = static_cast<float>(h) / 448.f * static_cast<float>(mViewport.mHeight);
const float x1 = scaledX - (mViewport.mWidth / 2); float x2, y2, x1, y1;
const float y1 = scaledY - (mViewport.mHeight / 2); if (scale) {
const float x2 = x1 + scaledW; x1 = x - 320;
const float y2 = y1 + scaledH; 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 // Save state + setup
CGX::SetVtxDescv(skPosColorTexDirect); 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; ERglCullMode cullMode = mCullMode;
SetCullMode(ERglCullMode::None); SetCullMode(ERglCullMode::None);
tex.Load(GX_TEXMAP0, EClampMode::Repeat);
// Draw // Draw
tex.Load(GX_TEXMAP0, EClampMode::Repeat);
CGX::Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4); CGX::Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4);
GXPosition3f32(x1, y1, 1.f); GXPosition3f32(x1, y1, 1.f);
GXColor1u32(c); GXColor1u32(c);

View File

@ -340,7 +340,7 @@ public:
static void SetCullMode(ERglCullMode); static void SetCullMode(ERglCullMode);
static void BeginScene(); static void BeginScene();
static void EndScene(); 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 SetAlphaCompare(ERglAlphaFunc comp0, u8 ref0, ERglAlphaOp op, ERglAlphaFunc comp1, u8 ref1);
static void SetViewPointMatrix(const zeus::CTransform& xf); static void SetViewPointMatrix(const zeus::CTransform& xf);
static void SetViewMatrix(); static void SetViewMatrix();
@ -373,10 +373,10 @@ public:
static void SetClearColor(const zeus::CColor& color); static void SetClearColor(const zeus::CColor& color);
static void SetCopyClear(const zeus::CColor& color, float depth); static void SetCopyClear(const zeus::CColor& color, float depth);
static void SetIsBeginSceneClearFb(bool clear); static void SetIsBeginSceneClearFb(bool clear);
static u32 GetViewportLeft() { return mViewport.mLeft; } static int GetViewportLeft() { return mViewport.mLeft; }
static u32 GetViewportTop() { return mViewport.mTop; } static int GetViewportTop() { return mViewport.mTop; }
static u32 GetViewportWidth() { return mViewport.mWidth; } static int GetViewportWidth() { return mViewport.mWidth; }
static u32 GetViewportHeight() { return mViewport.mHeight; } static int GetViewportHeight() { return mViewport.mHeight; }
static float GetViewportHalfWidth() { return mViewport.mHalfWidth; } static float GetViewportHalfWidth() { return mViewport.mHalfWidth; }
static float GetViewportHalfHeight() { return mViewport.mHalfHeight; } static float GetViewportHalfHeight() { return mViewport.mHalfHeight; }
static float GetViewportAspect() { static float GetViewportAspect() {
@ -385,6 +385,7 @@ public:
static const CVector3f& GetViewPoint() { return mViewPoint; } static const CVector3f& GetViewPoint() { return mViewPoint; }
static const CTransform4f& GetViewMatrix() { return mViewMatrix; } static const CTransform4f& GetViewMatrix() { return mViewMatrix; }
static const CTransform4f& GetModelMatrix() { return mModelMatrix; } 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, GXTexFmt format, void* data, GXTexMapID id);
static void LoadDolphinSpareTexture(int width, int height, GXCITexFmt format, GXTlut tlut, void* data, GXTexMapID id); static void LoadDolphinSpareTexture(int width, int height, GXCITexFmt format, GXTlut tlut, void* data, GXTexMapID id);

View File

@ -464,9 +464,10 @@ bool CMoviePlayer::DrawVideo() {
const s32 vpLeft = CGraphics::GetViewportLeft(); const s32 vpLeft = CGraphics::GetViewportLeft();
#ifdef AURORA #ifdef AURORA
// Scale to full size, maintaining aspect ratio // Scale to full size, maintaining aspect ratio
float vidAspect = static_cast<float>(x6c_videoInfo.width) / static_cast<float>(x6c_videoInfo.height); const float scale = std::min(static_cast<float>(CGraphics::GetViewportWidth()) / 640.0f,
const s32 vidWidth = vpHeight * vidAspect; static_cast<float>(CGraphics::GetViewportHeight()) / 448.0f);
const s32 vidHeight = vpHeight; const s32 vidWidth = x6c_videoInfo.width * scale;
const s32 vidHeight = x6c_videoInfo.height * scale;
#else #else
const s32 vidWidth = x6c_videoInfo.width; const s32 vidWidth = x6c_videoInfo.width;
const s32 vidHeight = x6c_videoInfo.height; 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); 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); MyTHPGXYuv2RgbSetup(CGraphics::mLastFrameUsedAbove, xf4_26_fieldFlip);
uintptr_t planeSize = x6c_videoInfo.width * x6c_videoInfo.height; uintptr_t planeSize = x6c_videoInfo.width * x6c_videoInfo.height;
uintptr_t planeSizeQuarter = planeSize / 4; uintptr_t planeSizeQuarter = planeSize / 4;
@ -646,31 +633,6 @@ void CMoviePlayer::DecodeFromRead(const void* data) {
case THPComponents::Type::Video: { case THPComponents::Type::Video: {
tjDecompressToYUV(TjHandle, (u8*)inptr, frameHeader.imageSize, m_yuvBuf.get(), 0); tjDecompressToYUV(TjHandle, (u8*)inptr, frameHeader.imageSize, m_yuvBuf.get(), 0);
inptr += frameHeader.imageSize; 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<u8[]>(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; break;
} }
case THPComponents::Type::Audio: case THPComponents::Type::Audio:

View File

@ -258,20 +258,20 @@ void CTexture::MangleMipmap(u32 mip) {
return; return;
} }
constexpr uint colors[4] = { constexpr u32 colors[4] = {
0x000000FF, 0x000000FF,
0x0000FF00, 0x0000FF00,
0x00FF0000, 0x00FF0000,
0x0000FFFF, 0x0000FFFF,
}; };
const uint color = colors[(mip - 1) & 3]; const u32 color = colors[(mip - 1) & 3];
const ushort rgb565Color = ((color >> 3) & 0x001F) | // B const u16 rgb565Color = ((color >> 3) & 0x001F) | // B
((color >> 5) & 0x07E0) | // G ((color >> 5) & 0x07E0) | // G
((color >> 8) & 0xF800); // R ((color >> 8) & 0xF800); // R
const ushort rgb555Color = ((color >> 3) & 0x001F) | // B const u16 rgb555Color = ((color >> 3) & 0x001F) | // B
((color >> 6) & 0x03E0) | // G ((color >> 6) & 0x03E0) | // G
((color >> 9) & 0x7C00); // R ((color >> 9) & 0x7C00); // R
const ushort rgb4Color = ((color >> 4) & 0x000F) | // B const u16 rgb4Color = ((color >> 4) & 0x000F) | // B
((color >> 8) & 0x00F0) | // G ((color >> 8) & 0x00F0) | // G
((color >> 12) & 0x0F00); // R ((color >> 12) & 0x0F00); // R
@ -287,7 +287,7 @@ void CTexture::MangleMipmap(u32 mip) {
switch (GetTexelFormat()) { switch (GetTexelFormat()) {
case ETexelFormat::RGB565: { case ETexelFormat::RGB565: {
const auto ptr = reinterpret_cast<ushort*>(x44_aramToken_x4_buff.get()); // mARAMToken.GetMRAMSafe()); const auto ptr = reinterpret_cast<u16*>(x44_aramToken_x4_buff.get()); // mARAMToken.GetMRAMSafe());
for (int i = 0; i < width * height; ++i) { for (int i = 0; i < width * height; ++i) {
ptr[i + offset] = rgb565Color; ptr[i + offset] = rgb565Color;
CBasics::Swap2Bytes(reinterpret_cast<u8*>(&ptr[i + offset])); CBasics::Swap2Bytes(reinterpret_cast<u8*>(&ptr[i + offset]));
@ -295,7 +295,7 @@ void CTexture::MangleMipmap(u32 mip) {
break; break;
} }
case ETexelFormat::CMPR: { case ETexelFormat::CMPR: {
auto ptr = reinterpret_cast<ushort*>(x44_aramToken_x4_buff.get()) + offset / 4; auto ptr = reinterpret_cast<u16*>(x44_aramToken_x4_buff.get()) + offset / 4;
for (int i = 0; i < width * height / 16; ++i, ptr += 4) { for (int i = 0; i < width * height / 16; ++i, ptr += 4) {
ptr[0] = rgb565Color; ptr[0] = rgb565Color;
CBasics::Swap2Bytes(reinterpret_cast<u8*>(&ptr[0])); CBasics::Swap2Bytes(reinterpret_cast<u8*>(&ptr[0]));
@ -307,9 +307,9 @@ void CTexture::MangleMipmap(u32 mip) {
break; break;
} }
case ETexelFormat::RGB5A3: { case ETexelFormat::RGB5A3: {
const auto ptr = reinterpret_cast<ushort*>(x44_aramToken_x4_buff.get()); const auto ptr = reinterpret_cast<u16*>(x44_aramToken_x4_buff.get());
for (int i = 0; i < width * height; ++i) { for (int i = 0; i < width * height; ++i) {
ushort& val = ptr[i + offset]; u16& val = ptr[i + offset];
CBasics::Swap2Bytes(reinterpret_cast<u8*>(&val)); CBasics::Swap2Bytes(reinterpret_cast<u8*>(&val));
if ((val & 0x8000) != 0) { if ((val & 0x8000) != 0) {
val = rgb555Color | 0x8000; val = rgb555Color | 0x8000;

View File

@ -92,7 +92,7 @@ void CSplashScreen::Draw() {
CGraphics::SetCullMode(ERglCullMode::Front); CGraphics::SetCullMode(ERglCullMode::Front);
} else { } else {
// TODO originally uses CGraphics viewport, but Render2D needs scaling fix // 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 // Progressive scan options omitted

View File

@ -1825,10 +1825,10 @@ void CFrontEndUI::Draw() {
CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru); CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru);
g_Renderer->SetBlendMode_AdditiveAlpha(); g_Renderer->SetBlendMode_AdditiveAlpha();
g_Renderer->SetDepthReadWrite(false, false); g_Renderer->SetDepthReadWrite(false, false);
const auto width = x38_pressStart->GetWidth(); const int width = x38_pressStart->GetWidth();
const auto height = x38_pressStart->GetHeight(); const int height = x38_pressStart->GetHeight();
CGraphics::Render2D(*x38_pressStart, 320 - (width / 2), 72 - (height / 2), width, 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) { if (xc0_attractCount > 0) {

View File

@ -337,8 +337,8 @@ void CInGameGuiManager::Update(CStateManager& stateMgr, float dt, CArchitectureQ
} }
} else { } else {
if (!stateMgr.GetPendingScreenTex().x0_id.IsValid() && if (!stateMgr.GetPendingScreenTex().x0_id.IsValid() &&
stateMgr.GetPendingScreenTex().x4_origin == zeus::CVector2i(0, 0)) { stateMgr.GetPendingScreenTex().x4_extent == zeus::CVector2i(0, 0)) {
x1c4_onScreenTex.x4_origin = stateMgr.GetPendingScreenTex().x4_origin; x1c4_onScreenTex.x4_extent = stateMgr.GetPendingScreenTex().x4_extent;
x1c4_onScreenTex.x0_id = {}; x1c4_onScreenTex.x0_id = {};
x1d8_onScreenTexAlpha = 0.f; x1d8_onScreenTexAlpha = 0.f;
} else { } else {
@ -477,11 +477,11 @@ void CInGameGuiManager::Draw(CStateManager& stateMgr) {
g_Renderer->SetBlendMode_AlphaBlended(); g_Renderer->SetBlendMode_AlphaBlended();
CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulate); CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulate);
CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru); CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru);
int w = x1c4_onScreenTex.x4_origin.x; int w = x1c4_onScreenTex.x4_extent.x;
int h = x1c4_onScreenTex.x4_origin.y; int h = x1c4_onScreenTex.x4_extent.y;
int x = CGraphics::GetViewportLeft() + (CGraphics::GetViewportWidth() - w) / 2 + x1c4_onScreenTex.xc_extent.x; int x = (640 - w) / 2 + x1c4_onScreenTex.xc_origin.x;
int y = CGraphics::GetViewportTop() + (CGraphics::GetViewportHeight() - h) / 2 - x1c4_onScreenTex.xc_extent.y; int y = (448 - h) / 2 - x1c4_onScreenTex.xc_origin.y;
CGraphics::Render2D(*x1dc_onScreenTexTok, x, y, w, h, zeus::CColor{1.f, x1d8_onScreenTexAlpha}); CGraphics::Render2D(*x1dc_onScreenTexTok, x, y, w, h, zeus::CColor{1.f, x1d8_onScreenTexAlpha}, true);
} }
float staticAlpha = 0.f; float staticAlpha = 0.f;

View File

@ -913,7 +913,7 @@ void CElementGen::RenderModels() {
GXVtxDescList{GX_VA_NULL, GX_NONE}, GXVtxDescList{GX_VA_NULL, GX_NONE},
}; };
CGX::SetVtxDescv(vtxDescList.data()); 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::SetNumChans(1);
CGX::SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, false, GX_PTIDENTITY); 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); 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::SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR1A1);
CGX::SetChanAmbColor(CGX::EChannelId::Channel1, zeus::skBlack); CGX::SetChanAmbColor(CGX::EChannelId::Channel1, zeus::skBlack);
CGX::SetChanMatColor(CGX::EChannelId::Channel1, x338_moduColor); 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 { } else {
CGX::SetNumChans(1); CGX::SetNumChans(1);
nextStage = GX_TEVSTAGE1; nextStage = GX_TEVSTAGE1;

View File

@ -449,13 +449,13 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
const SObjectTag* objectTag = g_ResFactory->GetResourceIdByName(xec_locatorName); const SObjectTag* objectTag = g_ResFactory->GetResourceIdByName(xec_locatorName);
const CAssetId assetId = objectTag ? objectTag->id : CAssetId(); 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) { if (objectTag) {
x1e8_ = g_SimplePool->GetObj(*objectTag); x1e8_ = g_SimplePool->GetObj(*objectTag);
x1e5_26_displayBillboard = true; x1e5_26_displayBillboard = true;
} }
} else if (msg == EScriptObjectMessage::Decrement) { } 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_) if (x1e8_)
x1e8_ = TLockedToken<CTexture>(); x1e8_ = TLockedToken<CTexture>();
x1e5_26_displayBillboard = false; x1e5_26_displayBillboard = false;

View File

@ -1070,8 +1070,7 @@ void CWallCrawlerSwarm::RenderBoid(const CBoid* boid, u32& drawMask, bool therma
} }
void CWallCrawlerSwarm::Render(CStateManager& mgr) { void CWallCrawlerSwarm::Render(CStateManager& mgr) {
SCOPED_GRAPHICS_DEBUG_GROUP( SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format("CWallCrawlerSwarm::Render {} {} {}", x8_uid, xc_editorId, x10_name).c_str(),
fmt::format("CWallCrawlerSwarm::Render {} {} {}", x8_uid, xc_editorId, x10_name).c_str(),
zeus::skOrange); zeus::skOrange);
u32 drawMask = 0xffffffff; u32 drawMask = 0xffffffff;
const bool r24 = x560_24_enableLighting; const bool r24 = x560_24_enableLighting;
@ -1086,7 +1085,9 @@ void CWallCrawlerSwarm::Render(CStateManager& mgr) {
if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) { if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) {
flags = CModelFlags(5, 0, 3, zeus::CColor(1.f, 0.3f)); 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 r27 = 0; r27 < 5; ++r27) {
for (int r28 = 0; r28 < 5; ++r28) { for (int r28 = 0; r28 < 5; ++r28) {

View File

@ -19,7 +19,7 @@ void CWorldShadow::EnableModelProjectedShadow(const zeus::CTransform& pos, s32 l
texTransform = zeus::CTransform::Translate(0.5f, 0.f, 0.5f) * texTransform; texTransform = zeus::CTransform::Translate(0.5f, 0.f, 0.5f) * texTransform;
GX::LightMask lightMask; GX::LightMask lightMask;
lightMask.set(lightIdx); lightMask.set(lightIdx);
// CCubeModel::EnableShadowMaps(*x0_texture, texTransform, lightMask, lightMask); CCubeModel::EnableShadowMaps(*x0_texture, texTransform, lightMask, lightMask);
} }
void CWorldShadow::DisableModelProjectedShadow() { CCubeModel::DisableShadowMaps(); } void CWorldShadow::DisableModelProjectedShadow() { CCubeModel::DisableShadowMaps(); }
@ -32,7 +32,6 @@ void CWorldShadow::BuildLightShadowTexture(const CStateManager& mgr, TAreaId aid
x84_lightIdx = lightIdx; x84_lightIdx = lightIdx;
} }
return; // TODO
if (aid != kInvalidAreaId) { if (aid != kInvalidAreaId) {
const CGameArea* area = mgr.GetWorld()->GetAreaAlways(aid); const CGameArea* area = mgr.GetWorld()->GetAreaAlways(aid);
if (area->IsPostConstructed()) { 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)); frustum.updatePlanes(x4_view, zeus::SProjPersp(zeus::degToRad(fov), 1.f, 0.1f, distance + x64_objHalfExtent));
g_Renderer->SetClippingPlanes(frustum); g_Renderer->SetClippingPlanes(frustum);
g_Renderer->SetPerspective(fov, x0_texture->GetWidth(), x0_texture->GetHeight(), 0.1f, 1000.f); g_Renderer->SetPerspective(fov, x0_texture->GetWidth(), x0_texture->GetHeight(), 0.1f, 1000.f);
CViewport backupVp = CGraphics::mViewport;
float backupDepthNear = CGraphics::mDepthNear; float backupDepthNear = CGraphics::mDepthNear;
float backupDepthFar = CGraphics::mDepthFar; float backupDepthFar = CGraphics::mDepthFar;
g_Renderer->SetViewport(0, 0, x0_texture->GetWidth(), x0_texture->GetHeight());
CGraphics::SetDepthRange(DEPTH_NEAR, DEPTH_FAR); CGraphics::SetDepthRange(DEPTH_NEAR, DEPTH_FAR);
CViewport backupVp = CGraphics::mViewport;
x34_model = zeus::lookAt(centerPoint - zeus::CVector3f(0.f, 0.f, 0.1f), light.GetPosition()); g_Renderer->SetViewport(0, 0, x0_texture->GetWidth() * 2, x0_texture->GetHeight() * 2);
CGraphics::SetModelMatrix(x34_model);
float extent = float(M_SQRT2) * x64_objHalfExtent; 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); g_Renderer->PrimColor(zeus::skWhite);
CGraphics::SetAlphaCompare(ERglAlphaFunc::Always, 0, ERglAlphaOp::And, ERglAlphaFunc::Always, 0); CGraphics::SetAlphaCompare(ERglAlphaFunc::Always, 0, ERglAlphaOp::And, ERglAlphaFunc::Always, 0);
CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, true); CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, true);
@ -77,6 +76,7 @@ void CWorldShadow::BuildLightShadowTexture(const CStateManager& mgr, TAreaId aid
ERglLogicOp::Clear); ERglLogicOp::Clear);
CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvPassthru); CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvPassthru);
CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru); CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru);
g_Renderer->BeginTriangleStrip(4); g_Renderer->BeginTriangleStrip(4);
g_Renderer->PrimVertex({-extent, 0.f, extent}); g_Renderer->PrimVertex({-extent, 0.f, extent});
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::Stage0, CTevCombiners::kEnvModulate);
CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru); CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru);
CGraphics::Render2D(*x0_texture, 0, x0_texture->GetWidth() * 2, x0_texture->GetHeight() * 2, 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); CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, true);
} }
x88_blurReset = false; x88_blurReset = false;
// TODO GXSetTexCopySrc(0, CGraphics::mRenderModeObj.efbHeight - x0_texture->GetHeight() * 2,
// m_shader.resolveTexture(); x0_texture->GetWidth() * 2, x0_texture->GetHeight() * 2);
// CBooRenderer::BindMainDrawTarget(); 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); g_Renderer->SetViewport(backupVp.mLeft, backupVp.mTop, backupVp.mWidth, backupVp.mHeight);
CGraphics::SetDepthRange(backupDepthNear, backupDepthFar); CGraphics::SetDepthRange(backupDepthNear, backupDepthFar);

2
extern/aurora vendored

@ -1 +1 @@
Subproject commit 788c65592f07c3ca8e8b8bff303f4777fd2dd0cd Subproject commit 357ecba0ae00246332447823fddd83b8da89357f