From dc3770ed1e9eeb1cb1c0d2c7194a8f4699fd2fea Mon Sep 17 00:00:00 2001 From: Kiwi <49212064+kiwi515@users.noreply.github.com> Date: Sat, 6 Dec 2025 09:40:15 -0500 Subject: [PATCH 1/4] Merge old ef_drawstrategy work --- .../drawstrategy/ef_drawbillboardstrategy.h | 33 ++ .../ef/drawstrategy/ef_drawstrategyimpl.h | 22 +- include/nw4r/ef/ef_drawinfo.h | 22 +- include/nw4r/ef/ef_emitter.h | 6 +- include/nw4r/ef/ef_res_emitter.h | 31 +- .../drawstrategy/ef_drawbillboardstrategy.cpp | 323 ++++++++++++++++++ .../ef/drawstrategy/ef_drawfreestrategy.cpp | 6 - .../ef/drawstrategy/ef_drawlinestrategy.cpp | 6 - .../ef/drawstrategy/ef_drawpointstrategy.cpp | 5 - 9 files changed, 418 insertions(+), 36 deletions(-) create mode 100644 src/nw4r/ef/drawstrategy/ef_drawbillboardstrategy.cpp diff --git a/include/nw4r/ef/drawstrategy/ef_drawbillboardstrategy.h b/include/nw4r/ef/drawstrategy/ef_drawbillboardstrategy.h index ef695900..e85d1d99 100644 --- a/include/nw4r/ef/drawstrategy/ef_drawbillboardstrategy.h +++ b/include/nw4r/ef/drawstrategy/ef_drawbillboardstrategy.h @@ -16,6 +16,39 @@ class DrawBillboardStrategy : public DrawStrategyImpl { virtual CalcAheadFunc GetCalcAheadFunc(ParticleManager* pManager); // at 0x18 + + void InitGraphics(const DrawInfo& rInfo, ParticleManager* pManager); + +private: + void DrawNormalBillboard(const DrawInfo& rInfo, ParticleManager* pManager); + + inline void DispParticle_Normal(Particle* pParticle, + const math::MTX34& rViewMtx, f32 vx, f32 vy, + f32 vz, f32 rc, f32 rs, f32 sx, f32 sy, + const math::VEC2& rPivot, int flags); + + void DrawYBillboard(const DrawInfo& rInfo, ParticleManager* pManager); + + inline void DispParticle_YBillboard(Particle* pParticle, + const math::MTX34& rViewMtx, f32 vx, + f32 vy, f32 vz, f32 rc, f32 rs, f32 sx, + f32 sy, const math::VEC2& rPivot, + int flags); + + void DrawDirectionalBillboard(const DrawInfo& rInfo, + ParticleManager* pManager); + + inline void DispParticle_Directional(Particle* pParticle, + const math::MTX34& rViewMtx, f32 vx, + f32 vy, f32 vz, f32 rc, f32 rs, f32 sx, + f32 sy, const math::VEC2& rPivot, + int flags); + + void DispPolygon(const math::VEC3& rP, const math::VEC3& rD1, + const math::VEC3& rD2, int flags); + + void CalcZOffset(math::MTX34* pMtx, const ParticleManager* pManager, + const DrawInfo& rInfo, f32 offsetZ); }; } // namespace ef diff --git a/include/nw4r/ef/drawstrategy/ef_drawstrategyimpl.h b/include/nw4r/ef/drawstrategy/ef_drawstrategyimpl.h index 6e3ff583..f3283400 100644 --- a/include/nw4r/ef/drawstrategy/ef_drawstrategyimpl.h +++ b/include/nw4r/ef/drawstrategy/ef_drawstrategyimpl.h @@ -6,14 +6,12 @@ #include #include #include - #include #include #include - namespace nw4r { namespace ef { @@ -23,6 +21,11 @@ class ParticleManager; struct EmitterDrawSetting; struct TextureData; +/****************************************************************************** + * + * DrawStrategyImpl + * + ******************************************************************************/ class DrawStrategyImpl : public DrawStrategy { public: typedef Particle* (*GetFirstDrawParticleFunc)(ParticleManager* pManager); @@ -156,7 +159,8 @@ class DrawStrategyImpl : public DrawStrategy { } static void CalcAhead_EmitterDesign(math::VEC3* pAxisY, - AheadContext* pContext) { + AheadContext* pContext, + Particle* /* pParticle */) { *pAxisY = pContext->mCommon.mEmitterAxisY; } @@ -180,7 +184,8 @@ class DrawStrategyImpl : public DrawStrategy { } } - static void CalcAhead_NoDesign(math::VEC3* pAxisY, AheadContext* pContext) { + static void CalcAhead_NoDesign(math::VEC3* pAxisY, AheadContext* pContext, + Particle* /* pParticle */) { *pAxisY = math::VEC3(pContext->mNoDesign.mWorldYAxis); } @@ -363,6 +368,15 @@ class DrawStrategyImpl : public DrawStrategy { static const math::MTX34 mIdentityMtx; }; +/****************************************************************************** + * + * Utility functions + * + ******************************************************************************/ +static void GXPosition(const math::VEC3& rPos) { + GXPosition3f32(rPos.x, rPos.y, rPos.z); +} + } // namespace ef } // namespace nw4r diff --git a/include/nw4r/ef/ef_drawinfo.h b/include/nw4r/ef/ef_drawinfo.h index d22e2e32..9c5fb10f 100644 --- a/include/nw4r/ef/ef_drawinfo.h +++ b/include/nw4r/ef/ef_drawinfo.h @@ -15,17 +15,17 @@ class DrawInfo { math::MTX34 mProjMtx; // at 0x30 bool mLightEnable; // at 0x60 GXLightID mLightMask; // at 0x64 - bool mIsSpotLight; // at 0x6C - GXFogType mFogType; // at 0x70 - f32 mFogStartz; // at 0x74 - f32 mFogEndz; // at 0x78 - f32 mFogNearz; // at 0x7C - f32 mFogFarz; // at 0x80 - GXColor mFogColor; // at 0x84 - f32 mZOffset; // at 0x88 - math::VEC3 mZOffsetOrig; // at 0x8C - GXColor mChanMatColor; // at 0x98 - GXColor mChanAmbColor; // at 0x9C + bool mIsSpotLight; // at 0x68 + GXFogType mFogType; // at 0x6C + f32 mFogStartz; // at 0x70 + f32 mFogEndz; // at 0x74 + f32 mFogNearz; // at 0x78 + f32 mFogFarz; // at 0x7C + GXColor mFogColor; // at 0x80 + f32 mZOffset; // at 0x84 + math::VEC3 mZOffsetOrig; // at 0x88 + GXColor mChanMatColor; // at 0x94 + GXColor mChanAmbColor; // at 0x98 public: DrawInfo() diff --git a/include/nw4r/ef/ef_emitter.h b/include/nw4r/ef/ef_emitter.h index 6e2791b9..2c021ed6 100644 --- a/include/nw4r/ef/ef_emitter.h +++ b/include/nw4r/ef/ef_emitter.h @@ -15,12 +15,12 @@ namespace nw4r { namespace ef { // Forward declarations -class ParticleManager; -struct EmitterResource; class Effect; -class EmitterForm; class Emitter; +class EmitterForm; class Particle; +class ParticleManager; +struct EmitterResource; struct EmitterInheritSetting { enum Flag { diff --git a/include/nw4r/ef/ef_res_emitter.h b/include/nw4r/ef/ef_res_emitter.h index aac9b992..86d8764f 100644 --- a/include/nw4r/ef/ef_res_emitter.h +++ b/include/nw4r/ef/ef_res_emitter.h @@ -4,7 +4,6 @@ #include #include - #include #include @@ -117,6 +116,36 @@ struct EmitterDrawSetting { ALPHAFLICK_SINE }; + enum Assist { + // Common + ASSIST_CMN_NORMAL = 0, + ASSIST_CMN_CROSS, + + // Billboard + ASSIST_BB_NORMAL = 0, + ASSIST_BB_Y, + ASSIST_BB_DIRECTIONAL, + ASSIST_BB_NOROLL, + + // Stripe + ASSIST_ST_NORMAL = 0, + ASSIST_ST_CROSS, + ASSIST_ST_BILLBOARD, + ASSIST_ST_TUBE, + }; + + enum Ahead { + // Common + AHEAD_CMN_NODESIGN = 5, + + // Billboard + AHEAD_BB_SPEED = 0, + AHEAD_BB_EMITTER_CENTER, + AHEAD_BB_EMITTER_DESIGN, + AHEAD_BB_PARTICLE, + AHEAD_BB_PARTICLE_BOTH, + }; + enum OptionTypeCommon { TYPE_CMN_NORMAL, TYPE_CMN_CROSS }; enum DirType { diff --git a/src/nw4r/ef/drawstrategy/ef_drawbillboardstrategy.cpp b/src/nw4r/ef/drawstrategy/ef_drawbillboardstrategy.cpp new file mode 100644 index 00000000..5830bc94 --- /dev/null +++ b/src/nw4r/ef/drawstrategy/ef_drawbillboardstrategy.cpp @@ -0,0 +1,323 @@ +#include + +namespace nw4r { +namespace ef { + +static u8 billboard_tex0_u8[] = {0x00, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x01, 0x01}; + +DrawBillboardStrategy::DrawBillboardStrategy() {} + +void DrawBillboardStrategy::Draw(const DrawInfo& rInfo, + ParticleManager* pManager) { + + const EmitterDrawSetting& rSetting = + *pManager->mResource->GetEmitterDrawSetting(); + + switch (rSetting.typeOption) { + case EmitterDrawSetting::ASSIST_BB_NORMAL: { + DrawNormalBillboard(rInfo, pManager); + break; + } + + case EmitterDrawSetting::ASSIST_BB_Y: { + DrawYBillboard(rInfo, pManager); + break; + } + + case EmitterDrawSetting::ASSIST_BB_DIRECTIONAL: { + DrawDirectionalBillboard(rInfo, pManager); + break; + } + } +} + +void DrawBillboardStrategy::DrawNormalBillboard(const DrawInfo& rInfo, + ParticleManager* pManager) { + + InitGraphics(rInfo, pManager); + + const EmitterDrawSetting& rSetting = + *pManager->mResource->GetEmitterDrawSetting(); + + int flags = mNumTexmap > 0 ? 1 : 0; + const math::MTX34& rInfoMtx = *rInfo.GetViewMtx(); + + math::VEC2 pivot; + pivot.x = rSetting.pivotX / 100.0f; + pivot.y = rSetting.pivotY / 100.0f; + + math::MTX34 viewMtx; + pManager->CalcGlobalMtx(&viewMtx); + math::MTX34Mult(&viewMtx, &rInfoMtx, &viewMtx); + + if (rSetting.zOffset != 0.0f) { + CalcZOffset(&viewMtx, pManager, rInfo, rSetting.zOffset); + } + + f32 vx = math::FSqrt(viewMtx._00 * viewMtx._00 + viewMtx._10 * viewMtx._10 + + viewMtx._20 * viewMtx._20); + + f32 vy = math::FSqrt(viewMtx._01 * viewMtx._01 + viewMtx._11 * viewMtx._11 + + viewMtx._21 * viewMtx._21); + + f32 vz = 0.0f; + + f32 rc, rs; + f32 mag; + + mag = + math::FSqrt(rInfoMtx._01 * rInfoMtx._01 + rInfoMtx._11 * rInfoMtx._11); + if (mag == 0.0f) { + rs = 0.0f; + rc = 1.0f; + } else { + f32 denom = 1.0f / mag; + rs = -rInfoMtx._01 * denom; + rc = rInfoMtx._11 * denom; + } + + GetFirstDrawParticleFunc pGetFirstFunc = GetGetFirstDrawParticleFunc( + rSetting.mFlags & EmitterDrawSetting::FLAG_DRAW_ORDER); + + GetNextDrawParticleFunc pGetNextFunc = GetGetNextDrawParticleFunc( + rSetting.mFlags & EmitterDrawSetting::FLAG_DRAW_ORDER); + + bool first = true; + + for (Particle* pIt = pGetFirstFunc(pManager); pIt != NULL; + pIt = pGetNextFunc(pManager, pIt)) { + + f32 sx = pIt->Draw_GetSizeX(); + if (sx < std::numeric_limits::epsilon()) { + continue; + } + + f32 sy = pIt->Draw_GetSizeY(); + if (sy < std::numeric_limits::epsilon()) { + continue; + } + + SetupGP(pIt, rSetting, rInfo, first, false); + first = false; + + DispParticle_Normal(pIt, viewMtx, vx, vy, vz, rc, rs, sx, sy, pivot, + flags); + } +} + +inline void DrawBillboardStrategy::DispParticle_Normal( + Particle* pParticle, const math::MTX34& rViewMtx, f32 vx, f32 vy, f32 vz, + f32 rc, f32 rs, f32 sx, f32 sy, const math::VEC2& rPivot, int flags) { + +#pragma unused(vz) + + math::VEC3 rot; + pParticle->Draw_GetRotate(&rot); + + math::VEC3 p0; // sp+24 + math::VEC3 d0; // sp+30 + math::VEC3 d1; // sp+3c + math::VEC3 pos; // sp+48 + + math::VEC3Transform(&pos, &rViewMtx, &pParticle->mParameter.mPosition); + + f32 px = rPivot.x; + f32 py = rPivot.y; + + f32 vx_rc = vx * rc; + f32 vx_rs = vx * rs; + f32 vy_rc = vy * rc; + f32 vy_rs = vy * rs; + + if (rot.z != 0.0f) { + f32 cr, sr; + math::SinCosRad(&sr, &cr, -rot.z); + + f32 cr_sx = cr * sx; + f32 sr_sx = sr * sx; + f32 cr_sy = cr * sy; + f32 sr_sy = sr * sy; + f32 rc_sx = rc * sx; + f32 rs_sy = rs * sy; + f32 rs_sx = rs * sx; + f32 rc_sy = rc * sy; + + f32 exp0 = (px - cr_sx * px) - sr_sy * py; + f32 exp1 = (py + sr_sx * px) - cr_sy * py; + + p0.x = vx_rc * exp0 + vy_rs * exp1 + pos.x; + p0.y = vx_rs * exp0 - vy_rc * exp1 + pos.y; + p0.z = pos.z; + + f32 vx_rc_cr_sx = vx_rc * cr_sx; + f32 vx_rc_sr_sy = vx_rc * sr_sy; + f32 vy_rs_sr_sx = vy_rs * sr_sx; + f32 vy_rs_cr_sy = vy_rs * cr_sy; + f32 vx_rs_cr_sx = vx_rs * cr_sx; + f32 vx_rs_sr_sy = vx_rs * sr_sy; + f32 vy_rc_sr_sx = vy_rc * sr_sx; + f32 vy_rc_cr_sy = vy_rc * cr_sy; + + d0.x = vx_rc_cr_sx - vx_rc_sr_sy - vy_rs_sr_sx - vy_rs_cr_sy; + d0.y = vx_rs_cr_sx - vx_rs_sr_sy + vy_rc_sr_sx + vy_rc_cr_sy; + d0.z = 0.0f; + + d1.x = vx_rc_cr_sx + vx_rc_sr_sy - vy_rs_sr_sx + vy_rs_cr_sy; + d1.y = vx_rs_cr_sx + vx_rs_sr_sy + vy_rc_sr_sx - vy_rc_cr_sy; + d1.z = 0.0f; + } else { + // todo + } + + DispPolygon(p0, d0, d1, flags); +} + +void DrawBillboardStrategy::DrawYBillboard(const DrawInfo& rInfo, + ParticleManager* pManager); + +inline void DrawBillboardStrategy::DispParticle_YBillboard( + Particle* pParticle, const math::MTX34& rViewMtx, f32 vx, f32 vy, f32 vz, + f32 rc, f32 rs, f32 sx, f32 sy, const math::VEC2& rPivot, int flags); + +void DrawBillboardStrategy::DrawDirectionalBillboard(const DrawInfo& rInfo, + ParticleManager* pManager); + +inline void DrawBillboardStrategy::DispParticle_Directional( + Particle* pParticle, const math::MTX34& rViewMtx, f32 vx, f32 vy, f32 vz, + f32 rc, f32 rs, f32 sx, f32 sy, const math::VEC2& rPivot, int flags); + +void DrawBillboardStrategy::DispPolygon(const math::VEC3& rP, + const math::VEC3& rD1, + const math::VEC3& rD2, int flags) { + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + { + GXPosition(rP - rD1); + if (flags != 0) { + GXTexCoord1x8(0); + } + + GXPosition(rP - rD2); + if (flags != 0) { + GXTexCoord1x8(1); + } + + GXPosition(rP + rD1); + if (flags != 0) { + GXTexCoord1x8(2); + } + + GXPosition(rP + rD2); + if (flags != 0) { + GXTexCoord1x8(3); + } + } + GXEnd(); +} + +void DrawBillboardStrategy::CalcZOffset(math::MTX34* pMtx, + const ParticleManager* pManager, + const DrawInfo& rInfo, f32 offsetZ) { + + f32 proj[GX_PROJECTION_SZ]; + GXGetProjectionv(proj); + + switch (static_cast(proj[0])) { + case GX_PERSPECTIVE: { + math::MTX34 glbMtx; + pManager->mManagerEM->CalcGlobalMtx(&glbMtx); + + math::VEC3 pos(glbMtx._03, glbMtx._13, glbMtx._23); + math::VEC3TransformCoord(&pos, rInfo.GetViewMtx(), &pos); + + if (Normalize(&pos)) { + if (pos.z >= 0.0f) { + pMtx->_03 += pos.x * offsetZ; + pMtx->_13 += pos.y * offsetZ; + pMtx->_23 += pos.z * offsetZ; + } else { + pMtx->_03 -= pos.x * offsetZ; + pMtx->_13 -= pos.y * offsetZ; + pMtx->_23 -= pos.z * offsetZ; + } + } + break; + } + + case GX_ORTHOGRAPHIC: { + pMtx->_23 += offsetZ; + break; + } + + default: { + break; + } + } +} + +void DrawBillboardStrategy::InitGraphics(const DrawInfo& rInfo, + ParticleManager* pManager) { + + const EmitterDrawSetting& rSetting = + *pManager->mResource->GetEmitterDrawSetting(); + + InitTexture(rSetting); + InitTev(rSetting, rInfo); + InitColor(pManager, rSetting, rInfo); + + GXEnableTexOffsets(GX_TEXCOORD0, TRUE, TRUE); + + GXSetArray(GX_VA_TEX0, billboard_tex0_u8, 2); + + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + + if (mNumTexmap > 0) { + GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8); + } + + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_U8, 0); + + math::MTX34 ident; + math::MTX34Identity(&ident); + GXLoadPosMtxImm(ident, GX_PNMTX0); + GXSetCurrentMtx(GX_PNMTX0); +} + +DrawStrategyImpl::CalcAheadFunc +DrawBillboardStrategy::GetCalcAheadFunc(ParticleManager* pManager) { + + const EmitterDrawSetting& rSetting = + *pManager->mResource->GetEmitterDrawSetting(); + + switch (rSetting.typeDir) { + case EmitterDrawSetting::AHEAD_BB_SPEED: { + return CalcAhead_Speed; + } + + case EmitterDrawSetting::AHEAD_BB_EMITTER_CENTER: { + return CalcAhead_EmitterCenter; + } + + case EmitterDrawSetting::AHEAD_BB_EMITTER_DESIGN: { + return CalcAhead_EmitterDesign; + } + + case EmitterDrawSetting::AHEAD_BB_PARTICLE: { + return CalcAhead_Particle; + } + + case EmitterDrawSetting::AHEAD_BB_PARTICLE_BOTH: { + return CalcAhead_ParticleBoth; + } + + default: { + return CalcAhead_Speed; + } + } +} + +} // namespace ef +} // namespace nw4r diff --git a/src/nw4r/ef/drawstrategy/ef_drawfreestrategy.cpp b/src/nw4r/ef/drawstrategy/ef_drawfreestrategy.cpp index bcedbae3..42cd0664 100644 --- a/src/nw4r/ef/drawstrategy/ef_drawfreestrategy.cpp +++ b/src/nw4r/ef/drawstrategy/ef_drawfreestrategy.cpp @@ -6,8 +6,6 @@ namespace nw4r { namespace ef { -static void GXPosition(const math::VEC3& rPos); - static math::MTX34 CalcLocalTransform(f32 px, f32 py, f32 sx, f32 sy, const nw4r::math::MTX34& rRot); @@ -54,10 +52,6 @@ static void DrawQuad(const math::MTX34& rMtx, const math::_VEC3* pPosArray, GXEnd(); } -static void GXPosition(const math::VEC3& rPos) { - GXPosition3f32(rPos.x, rPos.y, rPos.z); -} - DrawFreeStrategy::DrawFreeStrategy() {} void DrawFreeStrategy::Draw(const DrawInfo& rInfo, ParticleManager* pManager) { diff --git a/src/nw4r/ef/drawstrategy/ef_drawlinestrategy.cpp b/src/nw4r/ef/drawstrategy/ef_drawlinestrategy.cpp index 67504218..35bbab4e 100644 --- a/src/nw4r/ef/drawstrategy/ef_drawlinestrategy.cpp +++ b/src/nw4r/ef/drawstrategy/ef_drawlinestrategy.cpp @@ -12,8 +12,6 @@ namespace ef { static void DrawPolygon(const nw4r::math::VEC3& rP0, const nw4r::math::VEC3& rP1, bool texCoord); -static void GXPosition(const math::VEC3& rPos); - DrawLineStrategy::DrawLineStrategy() {} void DrawLineStrategy::Draw(const DrawInfo& rInfo, ParticleManager* pManager) { @@ -125,9 +123,5 @@ static void DrawPolygon(const nw4r::math::VEC3& rP0, GXEnd(); } -static void GXPosition(const math::VEC3& rPos) { - GXPosition3f32(rPos.x, rPos.y, rPos.z); -} - } // namespace ef } // namespace nw4r diff --git a/src/nw4r/ef/drawstrategy/ef_drawpointstrategy.cpp b/src/nw4r/ef/drawstrategy/ef_drawpointstrategy.cpp index cd6e10e9..453777b5 100644 --- a/src/nw4r/ef/drawstrategy/ef_drawpointstrategy.cpp +++ b/src/nw4r/ef/drawstrategy/ef_drawpointstrategy.cpp @@ -10,7 +10,6 @@ namespace nw4r { namespace ef { static void DrawPoint(const math::VEC3& rPos, bool texCoord); -static void GXPosition(const math::VEC3& rPos); DrawPointStrategy::DrawPointStrategy() {} @@ -75,10 +74,6 @@ static void DrawPoint(const math::VEC3& rPos, bool texCoord) { GXEnd(); } -static void GXPosition(const math::VEC3& rPos) { - GXPosition3f32(rPos.x, rPos.y, rPos.z); -} - void DrawPointStrategy::InitGraphics(const DrawInfo& rInfo, ParticleManager* pManager) { From 2ee830daf5b103ae528fc30dd77a20ef98ff3802 Mon Sep 17 00:00:00 2001 From: kiwi515 <49212064+kiwi515@users.noreply.github.com> Date: Tue, 9 Dec 2025 18:24:19 -0500 Subject: [PATCH 2/4] RPGrpModel, RPSysNWC24Manager work --- config/RSPE01_01/symbols.txt | 94 ++-- include/Pack/RPGraphics.h | 4 + include/Pack/RPGraphics/RPGrpDrawPath.h | 38 ++ .../Pack/RPGraphics/RPGrpDrawPathLightMap.h | 32 ++ .../Pack/RPGraphics/RPGrpDrawPathManager.h | 29 ++ include/Pack/RPGraphics/RPGrpModel.h | 15 +- include/Pack/RPGraphics/RPGrpModelManager.h | 32 ++ include/Pack/RPGraphics/RPGrpModelRfl.h | 117 +++-- include/Pack/RPKernel.h | 2 +- .../Pack/RPKernel/IRPSysKokeshiBodyManager.h | 6 +- include/Pack/RPKernel/RPSysAvatar.h | 13 +- include/Pack/RPKernel/RPSysKokeshi.h | 10 +- include/Pack/RPKernel/RPSysKokeshiManager.h | 29 +- include/Pack/RPKernel/RPSysNWC24Manager.h | 79 +++ include/Pack/RPSystem.h | 2 + include/Pack/RPSystem/RPSysSceneMgr.h | 24 + include/egg/gfxe.h | 2 +- include/egg/gfxe/eggModelEx.h | 4 + include/egg/gfxe/eggScreenEffectBase.h | 14 +- include/nw4r/g3d/g3d_scnrfl.h | 8 +- include/revolution/NWC24/NWC24Manage.h | 1 + src/Pack/RPGraphics/RPGrpModel.cpp | 30 +- src/Pack/RPGraphics/RPGrpModelImplement.cpp | 6 +- src/Pack/RPGraphics/RPGrpModelRfl.cpp | 422 ++++++++++++++++ src/Pack/RPKernel/RPSysKokeshi.cpp | 72 ++- src/Pack/RPKernel/RPSysNWC24Manager.cpp | 279 +++++++++++ src/egg/gfxe/eggDrawPathBase.cpp | 4 +- src/egg/gfxe/eggPostEffectBlur.cpp | 77 ++- src/egg/gfxe/eggScnRenderer.cpp | 459 ++++++++---------- src/egg/gfxe/eggScreenEffectBase.cpp | 441 ++++++++--------- 30 files changed, 1676 insertions(+), 669 deletions(-) create mode 100644 include/Pack/RPGraphics/RPGrpDrawPath.h create mode 100644 include/Pack/RPGraphics/RPGrpDrawPathLightMap.h create mode 100644 include/Pack/RPGraphics/RPGrpDrawPathManager.h create mode 100644 include/Pack/RPGraphics/RPGrpModelManager.h create mode 100644 include/Pack/RPKernel/RPSysNWC24Manager.h create mode 100644 include/Pack/RPSystem/RPSysSceneMgr.h create mode 100644 src/Pack/RPGraphics/RPGrpModelRfl.cpp create mode 100644 src/Pack/RPKernel/RPSysNWC24Manager.cpp diff --git a/config/RSPE01_01/symbols.txt b/config/RSPE01_01/symbols.txt index 4cccd634..6f71f394 100644 --- a/config/RSPE01_01/symbols.txt +++ b/config/RSPE01_01/symbols.txt @@ -7718,11 +7718,11 @@ fn_801A6D54 = .text:0x801A6D54; // type:function size:0xC8 fn_801A6E1C = .text:0x801A6E1C; // type:function size:0x64 fn_801A6E80 = .text:0x801A6E80; // type:function size:0x28 fn_801A6EA8 = .text:0x801A6EA8; // type:function size:0x58 -fn_801A6F00 = .text:0x801A6F00; // type:function size:0x68 -fn_801A6F68 = .text:0x801A6F68; // type:function size:0x5C8 -fn_801A7530 = .text:0x801A7530; // type:function size:0x40 -fn_801A7570 = .text:0x801A7570; // type:function size:0x68 -fn_801A75D8 = .text:0x801A75D8; // type:function size:0x60 +openLib__17RPSysNWC24ManagerFv = .text:0x801A6F00; // type:function size:0x68 +commitMail__17RPSysNWC24ManagerFPCwPCwUsPC11RPSysAvatariP16__va_list_struct = .text:0x801A6F68; // type:function size:0x5C8 +__dt__17RPSysNWC24ManagerFv = .text:0x801A7530; // type:function size:0x40 +__ct__17RPSysNWC24ManagerFPQ23EGG4Heap = .text:0x801A7570; // type:function size:0x68 +initialize__17RPSysNWC24ManagerFv = .text:0x801A75D8; // type:function size:0x60 fn_801A7638 = .text:0x801A7638; // type:function size:0x2C fn_801A7664 = .text:0x801A7664; // type:function size:0x28 fn_801A768C = .text:0x801A768C; // type:function size:0x20 @@ -8073,45 +8073,45 @@ fn_801B4F98 = .text:0x801B4F98; // type:function size:0x9C fn_801B5034 = .text:0x801B5034; // type:function size:0x70 fn_801B50A4 = .text:0x801B50A4; // type:function size:0x7C fn_801B5120 = .text:0x801B5120; // type:function size:0x40 -fn_801B5160 = .text:0x801B5160; // type:function size:0x8 -fn_801B5168 = .text:0x801B5168; // type:function size:0x8 -fn_801B5170 = .text:0x801B5170; // type:function size:0x8 -fn_801B5178 = .text:0x801B5178; // type:function size:0x8FC -fn_801B5A74 = .text:0x801B5A74; // type:function size:0x10 -fn_801B5A84 = .text:0x801B5A84; // type:function size:0x50 -fn_801B5AD4 = .text:0x801B5AD4; // type:function size:0x6C -fn_801B5B40 = .text:0x801B5B40; // type:function size:0x1A4 -fn_801B5CE4 = .text:0x801B5CE4; // type:function size:0x124 -fn_801B5E08 = .text:0x801B5E08; // type:function size:0x4 -fn_801B5E0C = .text:0x801B5E0C; // type:function size:0x14C -fn_801B5F58 = .text:0x801B5F58; // type:function size:0x1E8 -fn_801B6140 = .text:0x801B6140; // type:function size:0x8 -fn_801B6148 = .text:0x801B6148; // type:function size:0x4 -fn_801B614C = .text:0x801B614C; // type:function size:0x8 -fn_801B6154 = .text:0x801B6154; // type:function size:0x14 -fn_801B6168 = .text:0x801B6168; // type:function size:0x8 -fn_801B6170 = .text:0x801B6170; // type:function size:0x10 -fn_801B6180 = .text:0x801B6180; // type:function size:0x14 -fn_801B6194 = .text:0x801B6194; // type:function size:0x14 -fn_801B61A8 = .text:0x801B61A8; // type:function size:0x8 -fn_801B61B0 = .text:0x801B61B0; // type:function size:0x8 -fn_801B61B8 = .text:0x801B61B8; // type:function size:0x8 -fn_801B61C0 = .text:0x801B61C0; // type:function size:0x4 -fn_801B61C4 = .text:0x801B61C4; // type:function size:0x4 -fn_801B61C8 = .text:0x801B61C8; // type:function size:0x4 -fn_801B61CC = .text:0x801B61CC; // type:function size:0x4 -fn_801B61D0 = .text:0x801B61D0; // type:function size:0x4 -fn_801B61D4 = .text:0x801B61D4; // type:function size:0x4 -fn_801B61D8 = .text:0x801B61D8; // type:function size:0x4 -fn_801B61DC = .text:0x801B61DC; // type:function size:0x4 -fn_801B61E0 = .text:0x801B61E0; // type:function size:0x58 -fn_801B6238 = .text:0x801B6238; // type:function size:0x44 -fn_801B627C = .text:0x801B627C; // type:function size:0x8 -fn_801B6284 = .text:0x801B6284; // type:function size:0x8 -fn_801B628C = .text:0x801B628C; // type:function size:0x8 -fn_801B6294 = .text:0x801B6294; // type:function size:0x8 -fn_801B629C = .text:0x801B629C; // type:function size:0x8 -fn_801B62A4 = .text:0x801B62A4; // type:function size:0x8 +GetShapeName__13RPGrpModelRflCFUs = .text:0x801B5160; // type:function size:0x8 +GetMaterialName__13RPGrpModelRflCFUs = .text:0x801B5168; // type:function size:0x8 +GetJointName__13RPGrpModelRflCFUs = .text:0x801B5170; // type:function size:0x8 +DrawGX__13RPGrpModelRflFPC12RFLCharModelUlUl8_GXColorbb = .text:0x801B5178; // type:function size:0x8FC +GetCharModelDrawProc__13RPGrpModelRflFPQ34nw4r3g3d6ScnRflPC12RFLCharModelUlUl8_GXColorb = .text:0x801B5A74; // type:function size:0x10 +DrawProc__13RPGrpModelRflFPQ34nw4r3g3d6ScnRflPC12RFLCharModelUlUl8_GXColorb = .text:0x801B5A84; // type:function size:0x50 +CalcBeforeDraw__13RPGrpModelRflFv = .text:0x801B5AD4; // type:function size:0x6C +InternalCalc__13RPGrpModelRflFv = .text:0x801B5B40; // type:function size:0x1A4 +ReplaceTexture__13RPGrpModelRflFPCcRC12RPGrpTextureb = .text:0x801B5CE4; // type:function size:0x124 +CreateAnm__13RPGrpModelRflFv = .text:0x801B5E08; // type:function size:0x4 +Configure__13RPGrpModelRflFv = .text:0x801B5E0C; // type:function size:0x14C +Construct__13RPGrpModelRflF13RFLDataSourceUsP11RFLMiddleDB13RFLResolutionUlUc = .text:0x801B5F58; // type:function size:0x1E8 +GetKind__13RPGrpModelRflFv = .text:0x801B6140; // type:function size:0x8 +SetCallbackJointIndex__13RPGrpModelRflFUs = .text:0x801B6148; // type:function size:0x4 +GetCallbackJointIndex__13RPGrpModelRflCFv = .text:0x801B614C; // type:function size:0x8 +GetWorldMtx__13RPGrpModelRflCFUsPQ34nw4r4math5MTX34 = .text:0x801B6154; // type:function size:0x14 +ReferWorldMtx__13RPGrpModelRflCFUs = .text:0x801B6168; // type:function size:0x8 +GetWorldMtx__13RPGrpModelRflCFUs = .text:0x801B6170; // type:function size:0x10 +GetViewMtx__13RPGrpModelRflCFUsPQ34nw4r4math5MTX34 = .text:0x801B6180; // type:function size:0x14 +GetViewMtx__13RPGrpModelRflCFPQ34nw4r4math5MTX34 = .text:0x801B6194; // type:function size:0x14 +GetJointIndex__13RPGrpModelRflCFPCc = .text:0x801B61A8; // type:function size:0x8 +GetMaterialIndex__13RPGrpModelRflCFPCc = .text:0x801B61B0; // type:function size:0x8 +GetShapeIndex__13RPGrpModelRflCFPCc = .text:0x801B61B8; // type:function size:0x8 +VF_0x8__13RPGrpModelRflFv = .text:0x801B61C0; // type:function size:0x4 +VF_0x10__13RPGrpModelRflFv = .text:0x801B61C4; // type:function size:0x4 +VF_0xC__13RPGrpModelRflFv = .text:0x801B61C8; // type:function size:0x4 +ExecCallback_DRAW_XLU__13RPGrpModelRflFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x801B61CC; // type:function size:0x4 +ExecCallback_DRAW_OPA__13RPGrpModelRflFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x801B61D0; // type:function size:0x4 +ExecCallback_CALC_VIEW__13RPGrpModelRflFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x801B61D4; // type:function size:0x4 +ExecCallback_CALC_MAT__13RPGrpModelRflFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x801B61D8; // type:function size:0x4 +ExecCallback_CALC_WORLD__13RPGrpModelRflFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x801B61DC; // type:function size:0x4 +__dt__13RPGrpModelRflFv = .text:0x801B61E0; // type:function size:0x58 +__sinit_\RPGrpModelRfl_cpp = .text:0x801B6238; // type:function size:0x44 +@72@ExecCallback_DRAW_XLU__13RPGrpModelRflFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x801B627C; // type:function size:0x8 +@72@ExecCallback_DRAW_OPA__13RPGrpModelRflFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x801B6284; // type:function size:0x8 +@72@ExecCallback_CALC_VIEW__13RPGrpModelRflFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x801B628C; // type:function size:0x8 +@72@ExecCallback_CALC_MAT__13RPGrpModelRflFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x801B6294; // type:function size:0x8 +@72@ExecCallback_CALC_WORLD__13RPGrpModelRflFQ44nw4r3g3d6ScnObj6TimingPQ34nw4r3g3d6ScnObjUlPv = .text:0x801B629C; // type:function size:0x8 +@72@__dt__13RPGrpModelRflFv = .text:0x801B62A4; // type:function size:0x8 fn_801B62AC = .text:0x801B62AC; // type:function size:0xC4 fn_801B6370 = .text:0x801B6370; // type:function size:0xC fn_801B637C = .text:0x801B637C; // type:function size:0x2BC @@ -18584,8 +18584,8 @@ __vt__19RPSysKokeshiCtrlMgr = .data:0x803B9E78; // type:object size:0xC __vt__Q219RPSysKokeshiCtrlMgr8Disposer = .data:0x803B9E84; // type:object size:0xC scope:weak lbl_803B9E90 = .data:0x803B9E90; // type:object size:0x10 lbl_803B9EA0 = .data:0x803B9EA0; // type:object size:0x10 -jumptable_803B9EB0 = .data:0x803B9EB0; // type:object size:0x9C scope:local -lbl_803B9F4C = .data:0x803B9F4C; // type:object size:0xC +@19267 = .data:0x803B9EB0; // type:object size:0x9C scope:local +__vt__17RPSysNWC24Manager = .data:0x803B9F4C; // type:object size:0xC lbl_803B9F58 = .data:0x803B9F58; // type:object size:0x38 __vt__Q34nw4r3g3d6ScnRfl = .data:0x803B9F90; // type:object size:0x34 scope:global lbl_803B9FC8 = .data:0x803B9FC8; // type:object size:0x10 @@ -20407,7 +20407,7 @@ lbl_804BDBE0 = .sdata:0x804BDBE0; // type:object size:0x8 lbl_804BDBE8 = .sdata:0x804BDBE8; // type:object size:0x8 lbl_804BDBF0 = .sdata:0x804BDBF0; // type:object size:0x8 lbl_804BDBF8 = .sdata:0x804BDBF8; // type:object size:0x8 data:4byte -lbl_804BDC00 = .sdata:0x804BDC00; // type:object size:0x8 data:4byte +sSuccess__17RPSysNWC24Manager = .sdata:0x804BDC00; // type:object size:0x4 data:4byte lbl_804BDC08 = .sdata:0x804BDC08; // type:object size:0x4 data:4byte lbl_804BDC0C = .sdata:0x804BDC0C; // type:object size:0x4 data:4byte lbl_804BDC10 = .sdata:0x804BDC10; // type:object size:0x8 align:4 data:float diff --git a/include/Pack/RPGraphics.h b/include/Pack/RPGraphics.h index 254acbfa..37c44590 100644 --- a/include/Pack/RPGraphics.h +++ b/include/Pack/RPGraphics.h @@ -2,11 +2,15 @@ #define RP_PUBLIC_GRAPHICS_H #include +#include +#include +#include #include #include #include #include #include +#include #include #include #include diff --git a/include/Pack/RPGraphics/RPGrpDrawPath.h b/include/Pack/RPGraphics/RPGrpDrawPath.h new file mode 100644 index 00000000..382cfb12 --- /dev/null +++ b/include/Pack/RPGraphics/RPGrpDrawPath.h @@ -0,0 +1,38 @@ +#ifndef RP_GRAPHICS_DRAW_PATH_H +#define RP_GRAPHICS_DRAW_PATH_H +#include + +#include + +//! @addtogroup rp_graphics +//! @{ + +/** + * @brief Base class for draw paths + */ +class RPGrpDrawPath { +protected: + EGG::ScnRenderer* mpRenderer; // at 0x0 + EGG::DrawPathBase* mpPathImpl; // at 0x4 + +public: + template T* Construct(EGG::ScnRenderer* pRenderer); + + virtual ~RPGrpDrawPath() {} // at 0x8 + + virtual void On() { // at 0xC + mpPathImpl->setEnable(true); + } + + virtual void Off() { // at 0x10 + mpPathImpl->setEnable(false); + } + + virtual bool IsEnable() const { // at 0x10 + return mpPathImpl->isEnable(); + } +}; + +//! @} + +#endif diff --git a/include/Pack/RPGraphics/RPGrpDrawPathLightMap.h b/include/Pack/RPGraphics/RPGrpDrawPathLightMap.h new file mode 100644 index 00000000..2e898e3e --- /dev/null +++ b/include/Pack/RPGraphics/RPGrpDrawPathLightMap.h @@ -0,0 +1,32 @@ +#ifndef RP_GRAPHICS_DRAW_PATH_LIGHT_MAP_H +#define RP_GRAPHICS_DRAW_PATH_LIGHT_MAP_H +#include + +#include + +#include + +//! @addtogroup rp_graphics +//! @{ + +// Forward declarations +class RPGrpModel; + +/** + * @brief Light map draw path + */ +class RPGrpDrawPathLightMap : public RPGrpDrawPath { +public: + void ReplaceModelTexture(u16 index, RPGrpModel* pModel); + + EGG::LightTextureManager* GetLightTextureManager() const { + return mpLightTextureManager; + } + +private: + EGG::LightTextureManager* mpLightTextureManager; +}; + +//! @} + +#endif diff --git a/include/Pack/RPGraphics/RPGrpDrawPathManager.h b/include/Pack/RPGraphics/RPGrpDrawPathManager.h new file mode 100644 index 00000000..5ffaf73f --- /dev/null +++ b/include/Pack/RPGraphics/RPGrpDrawPathManager.h @@ -0,0 +1,29 @@ +#ifndef RP_GRAPHICS_DRAW_PATH_MANAGER_H +#define RP_GRAPHICS_DRAW_PATH_MANAGER_H +#include + +#include + +//! @addtogroup rp_graphics +//! @{ + +// Forward declarations +class RPGrpDrawPathLightMap; + +/** + * @brief Draw path manager + */ +class RPGrpDrawPathManager : public EGG::IScnProc { +public: + RPGrpDrawPathLightMap* GetDrawPathLightMap() const { + return mpDrawPathLightMap; + } + +private: + char unkC[0x18 - 0xC]; + RPGrpDrawPathLightMap* mpDrawPathLightMap; // at 0x18 +}; + +//! @} + +#endif diff --git a/include/Pack/RPGraphics/RPGrpModel.h b/include/Pack/RPGraphics/RPGrpModel.h index b2bb37aa..40310760 100644 --- a/include/Pack/RPGraphics/RPGrpModel.h +++ b/include/Pack/RPGraphics/RPGrpModel.h @@ -176,10 +176,9 @@ class RPGrpModel { return; } - nw4r::g3d::ScnObj* pScnObj = GetScnObj(); - if (pScnObj != NULL) { - pScnObj->G3dProc(nw4r::g3d::G3dObj::G3DPROC_CALC_VIEW, 0, - const_cast(&rViewMtx)); + if (GetScnObj() != NULL) { + GetScnObj()->G3dProc(nw4r::g3d::G3dObj::G3DPROC_CALC_VIEW, 0, + const_cast(&rViewMtx)); } } @@ -211,6 +210,10 @@ class RPGrpModel { return mpModelEx->getScnRfl(); } + bool IsVisible() const { + return (mFlags & EFlag_Visible) ? true : false; + } + /** * @brief Gets the allocator used for model-related allocations */ @@ -227,7 +230,7 @@ class RPGrpModel { } protected: - RPGrpModel(u8 viewNo); + explicit RPGrpModel(u8 viewNo); virtual ~RPGrpModel(); // at 0x88 virtual void Configure(); // at 0x8C @@ -247,6 +250,8 @@ class RPGrpModel { }; protected: + static const nw4r::math::_VEC3 GEOMETRY_MAGNIFY[1 /* ??? */]; + //! Allocator used for model-related allocations static EGG::Allocator* spAllocator; diff --git a/include/Pack/RPGraphics/RPGrpModelManager.h b/include/Pack/RPGraphics/RPGrpModelManager.h new file mode 100644 index 00000000..d657da95 --- /dev/null +++ b/include/Pack/RPGraphics/RPGrpModelManager.h @@ -0,0 +1,32 @@ +#ifndef RP_GRAPHICS_MODEL_MANAGER_H +#define RP_GRAPHICS_MODEL_MANAGER_H +#include + +//! @addtogroup rp_graphics +//! @{ + +// Forward declarations +class RPGrpDrawPathManager; + +/** + * @brief Model manager + */ +class RPGrpModelManager { +public: + /** + * @brief Gets the currently active manager instance + */ + static RPGrpModelManager* GetCurrent() { + return spCurrent; + } + + RPGrpDrawPathManager* GetDrawPathManager(); + +private: + //! Allocator used for model-related allocations + static RPGrpModelManager* spCurrent; +}; + +//! @} + +#endif diff --git a/include/Pack/RPGraphics/RPGrpModelRfl.h b/include/Pack/RPGraphics/RPGrpModelRfl.h index abe08a61..28f4377d 100644 --- a/include/Pack/RPGraphics/RPGrpModelRfl.h +++ b/include/Pack/RPGraphics/RPGrpModelRfl.h @@ -4,6 +4,8 @@ #include +#include + #include #include @@ -16,22 +18,30 @@ */ class RPGrpModelRfl : public RPGrpModel, public nw4r::g3d::IScnObjCallback { public: - RPGrpModelRfl(); - virtual ~RPGrpModelRfl() override {} // at 0x88 + enum MaterialType { + MaterialType_0, + MaterialType_1, + MaterialType_2, - virtual UNKTYPE VF_0x8(UNKTYPE) override {} // at 0x8 - virtual UNKTYPE VF_0x10(UNKTYPE) override {} // at 0x10 - virtual UNKTYPE VF_0xC(UNKTYPE) override {} // at 0xC + MaterialType_Max + }; + +public: + static RPGrpModelRfl* Construct(RFLDataSource src, u16 index, + RFLMiddleDB* pMiddleDB, + RFLResolution resolution, u32 exprFlags, + u8 viewNo); + + RPGrpModelRfl(RFLResolution resolution, u32 exprFlags, u8 viewNo); + + virtual ~RPGrpModelRfl() override {} // at 0x88 virtual Kind GetKind() override { // at 0x14 return Kind_RFL; } - virtual IRPGrpModelCallback* - SetCallback(IRPGrpModelCallback* pCallback) override; // at 0x18 - virtual u16 ReplaceTexture(const char* pName, const RPGrpTexture& rTexture, - bool keepFilterWrap); // at 0x20 + bool keepFilterWrap) override; // at 0x20 virtual void SetCallbackJointIndex(u16 /* idx */) override {} // at 0x24 @@ -39,20 +49,17 @@ class RPGrpModelRfl : public RPGrpModel, public nw4r::g3d::IScnObjCallback { return 0; } - virtual void SetJointVisible(u32 idx, bool enable) override; // at 0x2C - virtual bool IsJointVisible(u32 idx) const override; // at 0x30 - virtual void GetWorldMtx(u16 /* idx */, nw4r::math::MTX34* pMtx) const override { // at 0x3C nw4r::math::MTX34Copy( - pMtx, GetScnObj()->GetMtxPtr(nw4r::g3d::ScnObj::MTX_WORLD)); + pMtx, GetScnObj()->GetMtxPtr(nw4r::g3d::ScnObj::MTX_LOCAL)); } virtual const nw4r::math::MTX34* GetWorldMtx(u16 /* nodeIdx */) const override { // at 0x40 - return GetScnObj()->GetMtxPtr(nw4r::g3d::ScnObj::MTX_WORLD); + return GetScnObj()->GetMtxPtr(nw4r::g3d::ScnObj::MTX_LOCAL); } virtual nw4r::math::MTX34* @@ -61,7 +68,7 @@ class RPGrpModelRfl : public RPGrpModel, public nw4r::g3d::IScnObjCallback { } virtual void GetViewMtx(nw4r::math::MTX34* pMtx) const override { // at 0x4C - GetScnMdlSimple()->GetMtx(nw4r::g3d::ScnObj::MTX_VIEW, pMtx); + GetScnObj()->GetMtx(nw4r::g3d::ScnObj::MTX_VIEW, pMtx); } virtual void GetViewMtx(u16 /* nodeIdx */, @@ -69,38 +76,27 @@ class RPGrpModelRfl : public RPGrpModel, public nw4r::g3d::IScnObjCallback { GetViewMtx(pMtx); } - virtual const char* GetJointName(u16 idx) const override { // at 0x54 - return GetScnMdlSimple()->GetResMdl().GetResNode(idx).GetName(); - } + virtual const char* GetJointName(u16 idx) const override; // at 0x54 + virtual u16 GetJointIndex(const char* /* pName */) const override { // at 0x58 return 0; } - virtual const char* GetMaterialName(u16 idx) const override { // at 0x60 - return GetScnMdlSimple()->GetResMdl().GetResMat(idx).GetName(); - } + virtual const char* GetMaterialName(u16 idx) const override; // at 0x60 + virtual u16 GetMaterialIndex(const char* /* pName */) const override { // at 0x64 return 0; } - virtual const char* GetShapeName(u16 idx) const override { // at 0x6C - return GetScnMdlSimple()->GetResMdl().GetResShp(idx).GetName(); - } + virtual const char* GetShapeName(u16 idx) const override; // at 0x6C + virtual u16 GetShapeIndex(const char* /* pName */) const override { // at 0x70 return 0; } - virtual void SetShapeVisible(u32 idx, bool enable) override { // at 0x34 - GetScnMdlSimple()->GetResMdl().GetResShp(idx).SetVisible(enable); - } - - virtual bool IsShapeVisible(u32 idx) const override { // at 0x38 - return GetScnMdlSimple()->GetResMdl().GetResShp(idx).IsVisible(); - } - virtual void CalcBeforeDraw() override; // at 0x80 virtual void Configure() override; // at 0x8C @@ -137,15 +133,56 @@ class RPGrpModelRfl : public RPGrpModel, public nw4r::g3d::IScnObjCallback { void* /* pInfo */) override { // at 0x1C } + virtual UNKTYPE VF_0x8(UNKTYPE) override {} // at 0x8 + virtual UNKTYPE VF_0x10(UNKTYPE) override {} // at 0x10 + virtual UNKTYPE VF_0xC(UNKTYPE) override {} // at 0xC + + void SetOutputAlpha(u8 alpha) { + mOutputAlpha = alpha; + } + +private: + enum { + EFlag_ReverseCulling = 1 << 4, + EFlag_5 = 1 << 5, + EFlag_6 = 1 << 6, + EFlag_7 = 1 << 7, + EFlag_8 = 1 << 8, + }; + +private: + static void GetCharModelDrawProc(nw4r::g3d::ScnRfl* pScnRfl, + const RFLCharModel* pModel, u32 diffMask, + u32 specMask, GXColor ambColor, bool opa); + + static void DrawProc(nw4r::g3d::ScnRfl* pScnRfl, const RFLCharModel* pModel, + u32 diffMask, u32 specMask, GXColor ambColor, + bool opa); + + void DrawGX(const RFLCharModel* pModel, u32 diffMask, u32 specMask, + GXColor ambColor, bool opa, bool arg5); + private: - GXTexObj mLightTexObj0; // at 0x4C - GXTexObj mLightTexObj1; // at 0x6C - u32 unk8C; - u16 unk90; - u8 unk92; - u32 unk94; - u32 unk98; - u32 unk9C; + static const int LIGHT_SET_IDX = 2; + static const int FOG_IDX = 0; + + static RFLDrawCoreSetting sDrawCoreSetting; + static RPGrpModel* spDrawModel; + static f32 sBaseScale; + static nw4r::math::MTX34 lbl_804A4608; + + GXTexObj mLightTexObj0; // at 0x4C + GXTexObj mLightTexObj1; // at 0x6C + GXColor mBrightnessColor; // at 0x8C + u16 mFlagsRfl; // at 0x90 + u8 mOutputAlpha; // at 0x92 + MaterialType mMaterialType; // at 0x94 + RPGrpModelRfl* mpRflParent; // at 0x98 + const RFLCharModel* mpCharModel; // at 0x9C + RFLDataSource mDataSource; // at 0xA0 + u16 mIndex; // at 0xA4 + RFLMiddleDB* mpMiddleDB; // at 0xA8 + u32 mExprFlags; // at 0xAC }; //! @} diff --git a/include/Pack/RPKernel.h b/include/Pack/RPKernel.h index 9b04d613..38dae13f 100644 --- a/include/Pack/RPKernel.h +++ b/include/Pack/RPKernel.h @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -39,5 +40,4 @@ #include #include - #endif diff --git a/include/Pack/RPKernel/IRPSysKokeshiBodyManager.h b/include/Pack/RPKernel/IRPSysKokeshiBodyManager.h index 6bc89892..3e617cda 100644 --- a/include/Pack/RPKernel/IRPSysKokeshiBodyManager.h +++ b/include/Pack/RPKernel/IRPSysKokeshiBodyManager.h @@ -2,9 +2,10 @@ #define RP_KERNEL_I_KOKESHI_BODY_MANAGER_H #include +#include + #include -#include //! @addtogroup rp_kernel //! @{ @@ -28,7 +29,8 @@ class IRPSysKokeshiBodyManager { virtual const char* GetClothesFileName() = 0; // at 0x18 - virtual void GetClothesName(u16 bodyType, RFLSex sex, const char** ppNameA, + virtual void GetClothesName(u16 clothesType, RFLSex sex, + const char** ppNameA, const char** ppNameB) = 0; // at 0x1C virtual void GetHeadJointMtx(u16 bodyType, RPGrpModel* pBodyModel, diff --git a/include/Pack/RPKernel/RPSysAvatar.h b/include/Pack/RPKernel/RPSysAvatar.h index 4a2a1767..7d0c6bdf 100644 --- a/include/Pack/RPKernel/RPSysAvatar.h +++ b/include/Pack/RPKernel/RPSysAvatar.h @@ -15,15 +15,6 @@ * @brief Base class for Mii avatars */ class RPSysAvatar : public RP_DEBUG_STUB_1 { -public: - /** - * @brief Light map texture index - */ - enum ELightMap { - ELightMap_lm_0, - ELightMap_lm_1, - }; - public: /** * @brief Constructor @@ -57,6 +48,10 @@ class RPSysAvatar : public RP_DEBUG_STUB_1 { */ GXColor GetFavoriteColor() const; + const RPSysKokeshiGenInfo& GetGenInfo() const { + return mGenInfo; + } + protected: /** * @brief Handles post-constructor initialization diff --git a/include/Pack/RPKernel/RPSysKokeshi.h b/include/Pack/RPKernel/RPSysKokeshi.h index 825294b2..3f24aedf 100644 --- a/include/Pack/RPKernel/RPSysKokeshi.h +++ b/include/Pack/RPKernel/RPSysKokeshi.h @@ -70,9 +70,13 @@ class RPSysKokeshi : public RPSysAvatar { void Construct(); private: - RPGrpModel* mpNigaoeModel; // at 0xA4 - RPGrpModel* mpBodyModel; // at 0xA8 - RPGrpModel* mpLeftHandModel; // at 0xAC + //! Face model + RPGrpModel* mpNigaoeModel; // at 0xA4 + //! Avatar body model + RPGrpModel* mpBodyModel; // at 0xA8 + //! Left-hand model + RPGrpModel* mpLeftHandModel; // at 0xAC + //! Right-hand model RPGrpModel* mpRightHandModel; // at 0xB0 }; diff --git a/include/Pack/RPKernel/RPSysKokeshiManager.h b/include/Pack/RPKernel/RPSysKokeshiManager.h index d816b540..68898913 100644 --- a/include/Pack/RPKernel/RPSysKokeshiManager.h +++ b/include/Pack/RPKernel/RPSysKokeshiManager.h @@ -66,6 +66,16 @@ class RPSysKokeshiManager { OfficialDBState_Favorite, //!< Database index holds a favorite Mii }; + /** + * @brief Light map texture index + */ + enum LightMap { + LightMap_lm_0, + LightMap_lm_1, + + LightMap_Max + }; + public: /** * @brief Sets the active controller manager @@ -99,9 +109,11 @@ class RPSysKokeshiManager { RPGrpModel* CreateModel(void* pFile, u16 index, u8 viewNo, u32 flags, u32 bufferOption); + RPGrpTexture* CreateTexture(void* pFile, const char* pName); + const char* GetHandFileName(u32 handType) const; - void ChangeTexture(RPGrpModel*, const char*, const char*); + void ChangeTexture(RPGrpModel*, RPGrpTexture*, RPGrpTexture*); void SetMatColor(RPGrpModel* pModel, GXColor, GXColor); @@ -114,6 +126,10 @@ class RPSysKokeshiManager { return mpGuestNames[index]; } + u8 GetOutputAlpha() const { + return mOutputAlpha; + } + /** * @brief Accesses the specified controller data loader * @@ -138,14 +154,23 @@ class RPSysKokeshiManager { mpBodyManager = pBodyManager; } + static const char* GetLightTextureName(int i) { + return LIGHT_TEXTURE_NAMES[i]; + } + private: + static const char* LIGHT_TEXTURE_NAMES[LightMap_Max]; + //! Face library work buffer void* mpNglBuffer; // at 0x4 //! Names for default database ("Guest") Miis const wchar_t* mpGuestNames[RFL_DEFAULT_CHAR_MAX]; // at 0x8 - char unk20[0x44 - 0x20]; + char unk20[0x34 - 0x20]; + u8 mOutputAlpha; // at 0x34 + + char unk35[0x44 - 0x35]; //! Data loaders for every controller RPSysKokeshiCtrlDataLoader* diff --git a/include/Pack/RPKernel/RPSysNWC24Manager.h b/include/Pack/RPKernel/RPSysNWC24Manager.h new file mode 100644 index 00000000..02a23bd6 --- /dev/null +++ b/include/Pack/RPKernel/RPSysNWC24Manager.h @@ -0,0 +1,79 @@ +#ifndef RP_KERNEL_NWC24_MANAGER_H +#define RP_KERNEL_NWC24_MANAGER_H +#include + +#include + +#include + +//! @addtogroup rp_kernel +//! @{ + +// Forward declaration +class RPSysAvatar; + +/** + * @brief WiiConnect24 library manager + */ +class RPSysNWC24Manager { +protected: + u8* mpNwc24Work; // at 0x0 + wchar_t* mpMsgWork; // at 0x4 + +public: + /** + * @brief Suspends the WiiConnect24 scheduler so the library can be opened + */ + static void initialize(); + + /** + * @brief Constructor + * + * @param pHeap Heap to use for allocations + */ + RPSysNWC24Manager(EGG::Heap* pHeap); + + /** + * @brief Destructor + */ + virtual ~RPSysNWC24Manager(); // at 0x8 + + /** + * @brief Attempts to commit a message to the Wii Message Board + * + * @param pWork Library work buffer + * @param pAltName Mail letter alt name + * @param pMsg Mail letter message (can be a format string) + * @param date Mail letter send date + * @param pAvatar Mii avatar to include + * @param argc Number of message format arguments + * @param argv Message format arguments + * @return Success + */ + bool commitMail(const wchar_t* pAltName, const wchar_t* pMsg, RPTime16 date, + const RPSysAvatar* pAvatar, int argc, va_list argv); + +private: + /** + * @brief Attempts to open the WiiConnect24 library for use + * + * @return Success + */ + bool openLib() DECOMP_DONT_INLINE; + + /** + * @brief Closes the WiiConnect24 library + */ + void closeLib(); + +private: + //! Size of the message work buffer + static const int MSG_BUFFER_SIZE = 1024; + + //! Whether the last NWC24 operation was successful + static BOOL sSuccess; +}; + +//! @} + +#endif diff --git a/include/Pack/RPSystem.h b/include/Pack/RPSystem.h index 62014cf1..2bb787fa 100644 --- a/include/Pack/RPSystem.h +++ b/include/Pack/RPSystem.h @@ -6,7 +6,9 @@ #include #include #include +#include #include #include + #endif diff --git a/include/Pack/RPSystem/RPSysSceneMgr.h b/include/Pack/RPSystem/RPSysSceneMgr.h new file mode 100644 index 00000000..9d0ccc9f --- /dev/null +++ b/include/Pack/RPSystem/RPSysSceneMgr.h @@ -0,0 +1,24 @@ +#ifndef RP_SYSTEM_SCENE_MGR_H +#define RP_SYSTEM_SCENE_MGR_H +#include + +#include + +#include + +//! @addtogroup rp_kernel +//! @{ + +/** + * @brief Scene manager + */ +class RPSysSceneMgr : public EGG::SceneManager { + RP_SINGLETON_DECL(RPSysSceneMgr); + +public: + bool isShutDownReserved() const; +}; + +//! @} + +#endif diff --git a/include/egg/gfxe.h b/include/egg/gfxe.h index 1e7a0d72..ea31b261 100644 --- a/include/egg/gfxe.h +++ b/include/egg/gfxe.h @@ -25,9 +25,9 @@ #include #include #include +#include #include #include #include - #endif diff --git a/include/egg/gfxe/eggModelEx.h b/include/egg/gfxe/eggModelEx.h index 24ef59b1..e8872978 100644 --- a/include/egg/gfxe/eggModelEx.h +++ b/include/egg/gfxe/eggModelEx.h @@ -132,6 +132,10 @@ class ModelEx { } } + static u32 getDrawFlag() { + return sDrawFlag; + } + private: enum { cFlag_HasOriginalBV = 1 << 0 }; }; diff --git a/include/egg/gfxe/eggScreenEffectBase.h b/include/egg/gfxe/eggScreenEffectBase.h index 2a614156..e6a462fc 100644 --- a/include/egg/gfxe/eggScreenEffectBase.h +++ b/include/egg/gfxe/eggScreenEffectBase.h @@ -7,7 +7,7 @@ namespace EGG { class ScreenEffectBase { public: - enum ScreenEffectFlags { EFFECT_VISIBLE = (1 << 0), EFFECT_0x2 = (1 << 1) }; + enum ScreenEffectFlags { EFFECT_ENABLE = (1 << 0), EFFECT_0x2 = (1 << 1) }; enum BufferType { cBufferType_Hide_1_16, @@ -80,9 +80,17 @@ class ScreenEffectBase { return mScreen; } - bool isVisible() const { - return mFlags & EFFECT_VISIBLE; + bool isEnable() const { + return mFlags & EFFECT_ENABLE; } + void setEnable(bool enable) { + if (enable) { + mFlags |= EFFECT_ENABLE; + } else { + mFlags &= ~EFFECT_ENABLE; + } + } + bool isFlag0x2() const { return mFlags & EFFECT_0x2; } diff --git a/include/nw4r/g3d/g3d_scnrfl.h b/include/nw4r/g3d/g3d_scnrfl.h index a51813e0..8208af0e 100644 --- a/include/nw4r/g3d/g3d_scnrfl.h +++ b/include/nw4r/g3d/g3d_scnrfl.h @@ -2,10 +2,10 @@ #define NW4R_G3D_SCN_RFL_H #include -#include - #include +#include + namespace nw4r { namespace g3d { @@ -77,6 +77,10 @@ class ScnRfl : public ScnLeaf { return mpDrawProc; } + void* GetUserData() const { + return mpUserData; + } + private: void CallDrawProc(bool opa); void LoadDrawSetting(); diff --git a/include/revolution/NWC24/NWC24Manage.h b/include/revolution/NWC24/NWC24Manage.h index 74c08654..9a7b3b5e 100644 --- a/include/revolution/NWC24/NWC24Manage.h +++ b/include/revolution/NWC24/NWC24Manage.h @@ -32,6 +32,7 @@ typedef struct NWC24Work { u8 secretFlHeader[WORK_SIZE(NWC24SecretFLHeader)]; // at 0x2800 u8 dlHeader[WORK_SIZE(NWC24DlHeader)]; // at 0x3000 u8 dlTask[WORK_SIZE(NWC24DlTask)]; // at 0x3800 + u8 padding[0x4000 - 0x3A00]; } NWC24Work; #undef WORK_SIZE diff --git a/src/Pack/RPGraphics/RPGrpModel.cpp b/src/Pack/RPGraphics/RPGrpModel.cpp index 71bf24bd..ccd56f08 100644 --- a/src/Pack/RPGraphics/RPGrpModel.cpp +++ b/src/Pack/RPGraphics/RPGrpModel.cpp @@ -14,13 +14,17 @@ RPGrpModel* RPGrpModel::spCalcModel = NULL; nw4r::math::MTX34* RPGrpModel::spCalcWorldMtxArray = NULL; nw4r::math::MTX34* RPGrpModel::spCalcViewMtxArray = NULL; +const nw4r::math::_VEC3 RPGrpModel::GEOMETRY_MAGNIFY[1 /* ??? */] = { + {-1.0f, 1.0f, 1.0f}, +}; + RPGrpModel* RPGrpModel::Construct(RPGrpHandle handle, u8 viewNo, u32 typeOption, u32 bufferOption) { - RPGrpModel* pModel = NULL; + RPGrpModel* p = NULL; switch (RPGrpModelResManager::GetCurrent()->GetType(handle)) { case RPGrpModelResManager::Type_ResMdl: { - pModel = new RPGrpModelG3D(handle, viewNo, typeOption, bufferOption); + p = new RPGrpModelG3D(handle, viewNo, typeOption, bufferOption); break; } @@ -30,29 +34,29 @@ RPGrpModel* RPGrpModel::Construct(RPGrpHandle handle, u8 viewNo, u32 typeOption, } } - pModel->Configure(); - pModel->CreateAnm(); - return pModel; + p->Configure(); + p->CreateAnm(); + return p; } RPGrpModel* RPGrpModel::Construct(RPGrpHandle handle, int idx, u8 viewNo, u32 typeOption, u32 bufferOption) { - RPGrpModel* pModel = + RPGrpModel* p = new RPGrpModelG3D(handle, idx, viewNo, typeOption, bufferOption); - pModel->Configure(); - pModel->CreateAnm(); - return pModel; + p->Configure(); + p->CreateAnm(); + return p; } RPGrpModel* RPGrpModel::Construct(RPGrpHandle handle, const char* pName, u8 viewNo, u32 typeOption, u32 bufferOption) { - RPGrpModel* pModel = + RPGrpModel* p = new RPGrpModelG3D(handle, pName, viewNo, typeOption, bufferOption); - pModel->Configure(); - pModel->CreateAnm(); - return pModel; + p->Configure(); + p->CreateAnm(); + return p; } RPGrpModel::RPGrpModel(u8 viewNo) diff --git a/src/Pack/RPGraphics/RPGrpModelImplement.cpp b/src/Pack/RPGraphics/RPGrpModelImplement.cpp index e9e7ba8d..8ee5a76d 100644 --- a/src/Pack/RPGraphics/RPGrpModelImplement.cpp +++ b/src/Pack/RPGraphics/RPGrpModelImplement.cpp @@ -108,16 +108,12 @@ RPGrpModelG3D::SetCallback(IRPGrpModelCallback* pCallback) { } void RPGrpModelG3D::InternalCalc() { - static const Vec GEOMETRY_MAGNIFY[1] = { - {-1.0f, 1.0f, 1.0f}, - }; - if (!mReverseCulling) { if (GetScnLeaf() != NULL) { GetScnLeaf()->SetScale(mScale); } } else { - const Vec& rMag = GEOMETRY_MAGNIFY[mReverseCulling - 1]; + const nw4r::math::_VEC3& rMag = GEOMETRY_MAGNIFY[mReverseCulling - 1]; nw4r::math::VEC3 scale(mScale.x * rMag.x, mScale.y * rMag.y, mScale.z * rMag.z); diff --git a/src/Pack/RPGraphics/RPGrpModelRfl.cpp b/src/Pack/RPGraphics/RPGrpModelRfl.cpp new file mode 100644 index 00000000..573aa5e7 --- /dev/null +++ b/src/Pack/RPGraphics/RPGrpModelRfl.cpp @@ -0,0 +1,422 @@ +#include + +#include + +#include + +#include + +#include + +#include + +RFLDrawCoreSetting RPGrpModelRfl::sDrawCoreSetting; +f32 RPGrpModelRfl::sBaseScale = 1.0f; + +// clang-format off +nw4r::math::MTX34 RPGrpModelRfl::lbl_804A4608( + 1.0f, 0.0f, 0.0f, 0.0f, + 0.0f, 1.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 1.0f, 0.0f +); +// clang-format on + +RPGrpModelRfl* RPGrpModelRfl::Construct(RFLDataSource src, u16 index, + RFLMiddleDB* pMiddleDB, + RFLResolution resolution, u32 exprFlags, + u8 viewNo) { + + RPGrpModelRfl* p = new RPGrpModelRfl(resolution, exprFlags, viewNo); + + p->Configure(); + + if (!p->GetScnRfl()->SetupCharModel(src, index, pMiddleDB)) { + src = RFLDataSource_Default; + index = 0; + pMiddleDB = NULL; + + p->GetScnRfl()->SetupCharModel(RFLDataSource_Default, 0, NULL); + } + + p->mDataSource = src; + p->mIndex = index; + p->mpMiddleDB = pMiddleDB; + + // Manually fire the DrawProc callback as a way to get the char model + p->GetScnRfl()->SetDrawProc(GetCharModelDrawProc); + p->GetScnRfl()->G3dProc(nw4r::g3d::G3dObj::G3DPROC_DRAW_OPA, 0, NULL); + + p->GetScnRfl()->SetDrawProc(DrawProc); + + return p; +} + +RPGrpModelRfl::RPGrpModelRfl(RFLResolution resolution, u32 exprFlags, u8 viewNo) + : RPGrpModel(viewNo), + mFlagsRfl(EFlag_5 | EFlag_6 | EFlag_7), + mOutputAlpha(128), + mMaterialType(MaterialType_0), + mpRflParent(NULL), + mpCharModel(NULL), + mExprFlags(exprFlags) { + + u32 size; + nw4r::g3d::ScnRfl* pScnRfl = nw4r::g3d::ScnRfl::Construct( + spAllocator, &size, resolution, exprFlags, sizeof(RPGrpModelRfl*)); + + *static_cast(pScnRfl->GetUserData()) = this; + + mpModelEx = new EGG::ModelEx(pScnRfl); +} + +void RPGrpModelRfl::Configure() { + RPGrpModel::Configure(); + + sDrawCoreSetting.txcGenNum = 3; + sDrawCoreSetting.txcID = GX_TEXCOORD0; + sDrawCoreSetting.texMapID = GX_TEXMAP0; + sDrawCoreSetting.tevStageNum = 4; + sDrawCoreSetting.tevSwapTable = GX_TEV_SWAP0; + sDrawCoreSetting.tevKColorID = GX_KCOLOR0; + sDrawCoreSetting.tevOutRegID = GX_TEVREG2; + sDrawCoreSetting.posNrmMtxID = GX_PNMTX0; + sDrawCoreSetting.reverseCulling = false; + + GetScnRfl()->SetLightSetIdx(LIGHT_SET_IDX); + GetScnRfl()->SetFogIdx(FOG_IDX); + GetScnRfl()->SetAmbientColor((GXColor){255, 255, 255, 255}); + mBrightnessColor = (GXColor){255, 255, 255, 255}; + + InternalCalc(); +} + +void RPGrpModelRfl::CreateAnm() {} + +u16 RPGrpModelRfl::ReplaceTexture(const char* pName, + const RPGrpTexture& rTexture, + bool /* keepFilterWrap */) { + if (std::strcmp(pName, "lm_0") == 0) { + mLightTexObj0 = rTexture.GetTexObj(); + mFlagsRfl |= 1; + } else if (std::strcmp(pName, "lm_1") == 0) { + mLightTexObj1 = rTexture.GetTexObj(); + mFlagsRfl |= 2; + } else { + return 0; + } + + return 1; +} + +void RPGrpModelRfl::InternalCalc() { + if (!mReverseCulling) { + nw4r::math::VEC3 scale(mScale.x * sBaseScale, mScale.y * sBaseScale, + mScale.z * sBaseScale); + + if (GetScnLeaf() != NULL) { + GetScnLeaf()->SetScale(scale); + } + + mFlagsRfl &= ~EFlag_ReverseCulling; + } else { + const nw4r::math::_VEC3& rMag = GEOMETRY_MAGNIFY[mReverseCulling - 1]; + + nw4r::math::VEC3 scale(mScale.x * rMag.x * sBaseScale, + mScale.y * rMag.y * sBaseScale, + mScale.z * rMag.z * sBaseScale); + + if (GetScnLeaf() != NULL) { + GetScnLeaf()->SetScale(scale); + } + + mFlagsRfl |= EFlag_ReverseCulling; + } + + if (GetScnObj() != NULL) { + GetScnObj()->G3dProc(nw4r::g3d::G3dObj::G3DPROC_CALC_WORLD, 0, NULL); + } + + if (mpRecord != NULL) { + nw4r::math::MTX34 worldMtx; + spCalcWorldMtxArray = &worldMtx; + + GetScnRfl()->GetMtx(nw4r::g3d::ScnObj::MTX_WORLD, spCalcWorldMtxArray); + mpRecord->Calc(this); + GetScnRfl()->SetMtx(nw4r::g3d::ScnObj::MTX_WORLD, spCalcWorldMtxArray); + + spCalcWorldMtxArray = NULL; + } +} + +void RPGrpModelRfl::CalcBeforeDraw() { + RPGrpModel::CalcBeforeDraw(); + + if (mFlagsRfl & 0x100) { + mpModelEx->setVisible(false); + mFlagsRfl |= 0x200; + } else { + mFlagsRfl &= ~0x200; + } +} + +void RPGrpModelRfl::DrawProc(nw4r::g3d::ScnRfl* pScnRfl, + const RFLCharModel* pModel, u32 diffMask, + u32 specMask, GXColor ambColor, bool opa) { + + RPGrpModelRfl* p = *static_cast(pScnRfl->GetUserData()); + p->DrawGX(pModel, diffMask, specMask, ambColor, opa, false); +} + +void RPGrpModelRfl::GetCharModelDrawProc(nw4r::g3d::ScnRfl* pScnRfl, + const RFLCharModel* pModel, + u32 /* diffMask */, u32 /* specMask */, + GXColor /* ambColor */, + bool /* opa */) { + RPGrpModelRfl* p = *static_cast(pScnRfl->GetUserData()); + p->mpCharModel = pModel; +} + +void RPGrpModelRfl::DrawGX(const RFLCharModel* pModel, u32 diffMask, + u32 specMask, GXColor ambColor, bool opa, + bool arg5) { + + bool bVar4 = !(mFlagsRfl & EFlag_8) || (arg5 && spDrawModel == NULL); + + bool bVar6 = !arg5 || ((mFlags & 0x2) && IsVisible()); + + bool useMat = + !(EGG::ModelEx::getDrawFlag() & EGG::ModelEx::cDrawFlag_IgnoreMaterial); + + bool bVar3 = ((unkC & 0x20) || (mFlagsRfl & 0x8)) && mDrawGroup == 1; + bool bVar2 = !(mFlagsRfl & 0x400) || mDrawGroup == 1; + + bool bVar3_2 = opa && (mFlagsRfl & 0x40); + bool bVar5 = mFlagsRfl & 0x80; + + if (!useMat) { + if (bVar3) { + RFLDrawShape(mpCharModel); + } + return; + } + + bool bVar9 = bVar3 || bVar5; + u32 diffMaskSub = diffMask; + + // Accidental bitwise AND? + if (bVar6 & bVar9) { + if (bVar4) { + static const u8 TEV_STAGE_NUM[MaterialType_Max] = {4, 4, 3}; + sDrawCoreSetting.tevStageNum = TEV_STAGE_NUM[mMaterialType]; + spDrawModel = this; + sDrawCoreSetting.reverseCulling = mFlagsRfl & EFlag_ReverseCulling; + + RFLLoadMaterialSetting(&sDrawCoreSetting); + RFLLoadVertexSetting(&sDrawCoreSetting); + + if (mMaterialType == MaterialType_1) { + ambColor = (GXColor){0, 0, 0, 255}; + } + + diffMaskSub = diffMask; + + if (!(mFlagsRfl & EFlag_5)) { + diffMaskSub = 0; + ambColor.a = 255; + } + + diffMask = 0; + + GXSetNumChans(1); + + GXSetChanCtrl(GX_COLOR0, GX_TRUE, GX_SRC_REG, GX_SRC_REG, + GX_LIGHT_NULL, GX_DF_CLAMP, GX_AF_SPOT); + GXSetChanCtrl(GX_ALPHA0, (mFlagsRfl & EFlag_5) ? GX_TRUE : GX_FALSE, + GX_SRC_REG, GX_SRC_REG, + static_cast(diffMaskSub), GX_DF_CLAMP, + GX_AF_SPOT); + GXSetChanCtrl(GX_COLOR1A1, GX_FALSE, GX_SRC_REG, GX_SRC_REG, + GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + + GXSetChanAmbColor(GX_COLOR0A0, ambColor); + GXSetChanMatColor(GX_COLOR0A0, (GXColor){255, 255, 255, 255}); + + GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); + + GXLoadTexObj(&mLightTexObj0, GX_TEXMAP1); + GXLoadTexObj(&mLightTexObj1, GX_TEXMAP2); + + GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_MTX3x4, GX_TG_NRM, GX_TEXMTX0, + GX_TRUE, GX_PTTEXMTX0); + } + + nw4r::math::MTX34 viewMtx; + GetScnRfl()->GetMtx(nw4r::g3d::ScnObj::MTX_VIEW, &viewMtx); + viewMtx._03 = viewMtx._13 = viewMtx._23 = 0.0f; + + GXLoadTexMtxImm(viewMtx, GX_TEXMTX0, GX_MTX_3x4); + + nw4r::math::MTX34 trans, scale; + PSMTXScale(scale, 0.5f, -0.5f, 0.0f); + PSMTXTrans(trans, 0.5f, 0.5f, 1.0f); + + nw4r::math::MTX34 postMtx; + nw4r::math::MTX34Mult(&postMtx, &trans, &scale); + GXLoadTexMtxImm(postMtx, GX_PTTEXMTX0, GX_MTX_3x4); + + GXTevStageID stage = GX_TEVSTAGE1; + + if (bVar4) { + GXSetTevSwapModeTable(GX_TEV_SWAP2, GX_CH_RED, GX_CH_GREEN, + GX_CH_BLUE, GX_CH_ALPHA); + + GXSetTevSwapModeTable(GX_TEV_SWAP3, GX_CH_RED, GX_CH_RED, GX_CH_RED, + GX_CH_ALPHA); + + GXSetTevDirect(GX_TEVSTAGE0); + + switch (mMaterialType) { + case MaterialType_0: { + case MaterialType_1: + GXSetTevDirect(GX_TEVSTAGE1); + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP2, GX_TEV_SWAP2); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP1, + GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_TEXC, + GX_CC_RASA, GX_CC_RASC); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, + GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, + GX_CA_ZERO, GX_CA_A2); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, + GX_CS_SCALE_1, 1, GX_TEVPREV); + + GXSetTevDirect(GX_TEVSTAGE2); + GXSetTevSwapMode(GX_TEVSTAGE2, GX_TEV_SWAP2, GX_TEV_SWAP2); + GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, + GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE2, GX_CC_ZERO, GX_CC_C2, GX_CC_CPREV, + GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, + GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_ZERO, GX_CA_ZERO, + GX_CA_ZERO, GX_CA_APREV); + GXSetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, + GX_CS_SCALE_1, 1, GX_TEVPREV); + + GXSetTevDirect(GX_TEVSTAGE3); + GXSetTevSwapMode(GX_TEVSTAGE3, GX_TEV_SWAP2, GX_TEV_SWAP2); + GXSetTevOrder(GX_TEVSTAGE3, GX_TEXCOORD1, GX_TEXMAP2, + GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE3, GX_CC_ZERO, GX_CC_TEXC, + GX_CC_RASA, GX_CC_CPREV); + GXSetTevColorOp(GX_TEVSTAGE3, GX_TEV_ADD, GX_TB_ZERO, + GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE3, GX_CA_ZERO, GX_CA_ZERO, + GX_CA_ZERO, GX_CA_APREV); + GXSetTevAlphaOp(GX_TEVSTAGE3, GX_TEV_ADD, GX_TB_ZERO, + GX_CS_SCALE_1, 1, GX_TEVPREV); + + stage = GX_TEVSTAGE3; + break; + } + + case MaterialType_2: { + GXSetTevKColorSel(GX_TEVSTAGE1, GX_TEV_KCSEL_K2); + GXSetTevKColor(GX_KCOLOR2, mBrightnessColor); + + GXSetTevDirect(GX_TEVSTAGE1); + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP2, GX_TEV_SWAP2); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, + GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_ZERO, + GX_CC_ZERO, GX_CC_KONST); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, + GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, + GX_CA_ZERO, GX_CA_A2); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, + GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + + GXSetTevDirect(GX_TEVSTAGE2); + GXSetTevSwapMode(GX_TEVSTAGE2, GX_TEV_SWAP2, GX_TEV_SWAP2); + GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, + GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE2, GX_CC_ZERO, GX_CC_ZERO, + GX_CC_ZERO, GX_CC_CPREV); + GXSetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, + GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_ZERO, GX_CA_ZERO, + GX_CA_ZERO, GX_CA_APREV); + GXSetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, + GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + + stage = GX_TEVSTAGE2; + break; + } + + default: { + break; + } + } + } + + if (bVar3) { + if (bVar4) { + GXSetZCompLoc(GX_TRUE); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_NEVER, 0); + GXSetTevKAlphaSel(stage, GX_TEV_KASEL_K3_A); + GXSetTevAlphaIn(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, + GX_CA_KONST); + GXSetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, + GX_LO_COPY); + } + + GXColor tevColor = (GXColor){0, 0, 0, mOutputAlpha}; + GXSetTevColor(GX_TEVREG2, tevColor); + RFLDrawOpaCore(mpCharModel, &sDrawCoreSetting); + } + + if (bVar5) { + if (bVar4) { + GXSetZCompLoc(GX_FALSE); + + if (!bVar2) { + GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_NEVER, 0); + } else { + GXSetAlphaCompare(GX_GREATER, 128, GX_AOP_OR, GX_NEVER, 0); + } + + GXSetTevAlphaIn(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, + GX_CA_APREV); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, + GX_LO_COPY); + } + + RFLDrawXluCore(mpCharModel, &sDrawCoreSetting); + } + } + + if (mpRflParent != NULL) { + mpRflParent->DrawGX(pModel, diffMask, specMask, ambColor, opa, true); + } + + if (spDrawModel == this) { + spDrawModel = NULL; + } +} + +const char* RPGrpModelRfl::GetJointName(u16 /* idx */) const { + static const char JOINT_NAME[] = "dummy"; + return JOINT_NAME; +} + +const char* RPGrpModelRfl::GetMaterialName(u16 /* idx */) const { + static const char MATERIAL_NAME[] = "dummy"; + return MATERIAL_NAME; +} + +const char* RPGrpModelRfl::GetShapeName(u16 /* idx */) const { + static const char SHAPE_NAME[] = "dummy"; + return SHAPE_NAME; +} diff --git a/src/Pack/RPKernel/RPSysKokeshi.cpp b/src/Pack/RPKernel/RPSysKokeshi.cpp index c618b366..fff7b0f4 100644 --- a/src/Pack/RPKernel/RPSysKokeshi.cpp +++ b/src/Pack/RPKernel/RPSysKokeshi.cpp @@ -83,9 +83,10 @@ void RPSysKokeshi::LoadResource(const RPSysKokeshiOverloadInfo* pOverloadInfo) { case RPSysKokeshiManager::GenType_Friend: case RPSysKokeshiManager::GenType_Kokeshi: { - clothesType = RPUtlRandom::getU32( - pBodyManager->GetFriendClothesIndexRange()) + - pBodyManager->GetFriendClothesStartIndex(); + clothesType = static_cast( + pBodyManager->GetFriendClothesStartIndex() + + RPUtlRandom::getU32( + pBodyManager->GetFriendClothesIndexRange())); break; } @@ -93,28 +94,44 @@ void RPSysKokeshi::LoadResource(const RPSysKokeshiOverloadInfo* pOverloadInfo) { break; } } + + mOverloadInfo.SetClothesType(clothesType); } - mOverloadInfo.SetClothesType(clothesType); + // Open the clothes archive + const char* pClothFileName = pBodyManager->GetClothesFileName(); + + void* pClothFile = RPSysResourceManager::GetFileFromArchive(pKokeshiArchive, + pClothFileName); - // Change clothes textures + // Determine the correct type of clothes const char* pClothNameA = NULL; const char* pClothNameB = NULL; - pBodyManager->GetClothesName(mGenInfo.GetBodyType(), + pBodyManager->GetClothesName(clothesType, static_cast(mAdditionalInfo.sex), &pClothNameA, &pClothNameB); - pKokeshiManager->ChangeTexture(mpBodyModel, pClothNameA, pClothNameB); - pKokeshiManager->ChangeTexture(mpLeftHandModel, pClothNameA, pClothNameB); - pKokeshiManager->ChangeTexture(mpRightHandModel, pClothNameA, pClothNameB); + // Change the clothes textures + RPGrpTexture* pClothTexA = + pKokeshiManager->CreateTexture(pClothFile, pClothNameA); + RPGrpTexture* pClothTexB = + pKokeshiManager->CreateTexture(pClothFile, pClothNameB); + + pKokeshiManager->ChangeTexture(mpBodyModel, pClothTexA, pClothTexB); + pKokeshiManager->ChangeTexture(mpLeftHandModel, pClothTexA, pClothTexB); + pKokeshiManager->ChangeTexture(mpRightHandModel, pClothTexA, pClothTexB); + // Apply favorite/skin color to the models GXColor favColor = GetFavoriteColor(); - pKokeshiManager->SetMatColor(mpBodyModel, favColor, favColor); - pKokeshiManager->SetMatColor(mpLeftHandModel, favColor, favColor); - pKokeshiManager->SetMatColor(mpRightHandModel, favColor, favColor); + GXColor skinColor = mAdditionalInfo.skinColor; + + pKokeshiManager->SetMatColor(mpBodyModel, favColor, skinColor); + pKokeshiManager->SetMatColor(mpLeftHandModel, favColor, skinColor); + pKokeshiManager->SetMatColor(mpRightHandModel, favColor, skinColor); if (mpNigaoeModel->GetKind() == RPGrpModel::Kind_RFL) { - // static_cast(mpNigaoeModel)->unkA2 = ... + static_cast(mpNigaoeModel) + ->SetOutputAlpha(pKokeshiManager->GetOutputAlpha()); } } @@ -123,9 +140,32 @@ void RPSysKokeshi::LoadResource(const RPSysKokeshiOverloadInfo* pOverloadInfo) { * * @param idx Lightmap texture index */ -void RPSysKokeshi::ApplyLightTexture(u8 idx) { - // TODO - (void)idx; +void RPSysKokeshi::ApplyLightTexture(u8 /* idx */) { + RPGrpDrawPathLightMap* pLightMap = RPGrpModelManager::GetCurrent() + ->GetDrawPathManager() + ->GetDrawPathLightMap(); + + for (u32 i = 0; i < RPSysKokeshiManager::LightMap_Max; i++) { + pLightMap->ReplaceModelTexture( + pLightMap->GetLightTextureManager()->getTextureIndex( + RPSysKokeshiManager::GetLightTextureName(i)), + mpNigaoeModel); + + pLightMap->ReplaceModelTexture( + pLightMap->GetLightTextureManager()->getTextureIndex( + RPSysKokeshiManager::GetLightTextureName(i)), + mpBodyModel); + + pLightMap->ReplaceModelTexture( + pLightMap->GetLightTextureManager()->getTextureIndex( + RPSysKokeshiManager::GetLightTextureName(i)), + mpLeftHandModel); + + pLightMap->ReplaceModelTexture( + pLightMap->GetLightTextureManager()->getTextureIndex( + RPSysKokeshiManager::GetLightTextureName(i)), + mpRightHandModel); + } } /** diff --git a/src/Pack/RPKernel/RPSysNWC24Manager.cpp b/src/Pack/RPKernel/RPSysNWC24Manager.cpp new file mode 100644 index 00000000..e543c02f --- /dev/null +++ b/src/Pack/RPKernel/RPSysNWC24Manager.cpp @@ -0,0 +1,279 @@ +#include +#include + +#include + +#include + +#include + +#include + +/** + * @brief Whether the last NWC24 operation was successful + */ +BOOL RPSysNWC24Manager::sSuccess = true; + +/** + * @brief Suspends the WiiConnect24 scheduler so the library can be opened + */ +void RPSysNWC24Manager::initialize() { + s32 err = NWC24SuspendScheduler(); + if (err >= NWC24_OK) { + return; + } + + switch (err) { + case NWC24_ERR_FATAL: { + sSuccess = false; + break; + } + + case NWC24_ERR_INTERNAL_IPC: + case NWC24_ERR_MUTEX: + case NWC24_ERR_INPROGRESS: { + break; + } + + default: { + break; + } + } +} + +/** + * @brief Constructor + * + * @param pHeap Heap to use for allocations + */ +RPSysNWC24Manager::RPSysNWC24Manager(EGG::Heap* pHeap) { + mpNwc24Work = new (pHeap, 32) u8[sizeof(NWC24Work)]; + mpMsgWork = new (pHeap) wchar_t[MSG_BUFFER_SIZE]; +} + +/** + * @brief Destructor + */ +RPSysNWC24Manager::~RPSysNWC24Manager() {} + +/** + * @brief Attempts to commit a message to the Wii Message Board + * + * @param pWork Library work buffer + * @param pAltName Mail letter alt name + * @param pMsg Mail letter message (can be a format string) + * @param date Mail letter send date + * @param pAvatar Mii avatar to include + * @param argc Number of message format arguments + * @param argv Message format arguments + * @return Success + */ +bool RPSysNWC24Manager::commitMail(const wchar_t* pAltName, const wchar_t* pMsg, + RPTime16 date, const RPSysAvatar* pAvatar, + int argc, va_list argv) { + if (!sSuccess) { + return false; + } + + if (RP_GET_INSTANCE(RPSysSceneMgr)->isShutDownReserved()) { + return false; + } + + RP_GET_INSTANCE(RPSysTagProcessor) + ->PreProcessEx(pMsg, mpMsgWork, MSG_BUFFER_SIZE, NULL, argc, argv); + + if (!openLib()) { + closeLib(); + return false; + } + + NWC24MsgObj msg; + if (NWC24InitMsgObj(&msg, NWC24_MSGTYPE_RVL_MENU) != NWC24_OK) { + closeLib(); + return false; + } + + u64 uid; + if (NWC24GetMyUserId(&uid) != NWC24_OK) { + closeLib(); + return false; + } + + if (NWC24SetMsgAltName(&msg, pAltName, std::wcslen(pAltName) + 1) != + NWC24_OK) { + + closeLib(); + return false; + } + + if (NWC24SetMsgToId(&msg, uid) != NWC24_OK) { + closeLib(); + return false; + } + + if (NWC24SetMsgText(&msg, // + reinterpret_cast(mpMsgWork), // + std::wcslen(mpMsgWork) * sizeof(wchar_t), // + NWC24_UTF_16BE, NWC24_ENC_BASE64) != NWC24_OK) { + closeLib(); + return false; + } + + u32 year = 0; + u32 month = 0; + u32 day = 0; + RP_GET_INSTANCE(RPSysSystem)->getCalendarTime(&date, year, month, day); + + if (NWC24SetMsgMBNoReply(&msg, TRUE) != NWC24_OK) { + closeLib(); + return false; + } + + switch (NWC24SetMsgMBRegDate(&msg, year, month, day)) { + // This will always happen starting in 2035! + case NWC24_ERR_INVALID_VALUE: { + closeLib(); + return false; + } + + case NWC24_OK: { + break; + } + + default: { + closeLib(); + return false; + } + } + + bool attach = false; + u16 index = 0; + + if (pAvatar != NULL) { + RPSysKokeshiLocation location = pAvatar->GetGenInfo().GetLocation(); + + // RFL only supports attaching official DB Miis + if (location.GetDataSource() == RFLDataSource_Official) { + attach = true; + index = location.GetIndex(); + } + } + + s32 commitErr = NWC24_OK; + + if (attach) { + switch (RFLCommitNWC24Msg(&msg, index)) { + case RFLErrcode_NotAvailable: + case RFLErrcode_Broken: { + closeLib(); + return false; + } + + case RFLErrcode_NWC24Fail: { + commitErr = RFLGetLastReason(); + break; + } + + case RFLErrcode_Success: { + break; + } + + default: { + break; + } + } + } else { + commitErr = NWC24CommitMsg(&msg); + } + + switch (commitErr) { + case NWC24_ERR_FULL: { + closeLib(); + return false; + } + + case NWC24_ERR_NAND_CORRUPT: + case NWC24_ERR_FILE_OTHER: + case NWC24_ERR_FILE_NOEXISTS: + case NWC24_ERR_FILE_WRITE: + case NWC24_ERR_FILE_READ: + case NWC24_ERR_FILE_CLOSE: + case NWC24_ERR_FILE_OPEN: { + NWC24CloseLib(); + sSuccess = false; + return false; + } + + default: { + closeLib(); + return false; + } + + case NWC24_OK: { + closeLib(); + return true; + } + } +} + +/** + * @brief Attempts to open the WiiConnect24 library for use + * + * @return Success + */ +bool RPSysNWC24Manager::openLib() { + NWC24Work* pNwc24Work = reinterpret_cast(mpNwc24Work); + + switch (NWC24OpenLib(pNwc24Work)) { + case NWC24_ERR_LIB_OPENED: + case NWC24_OK: { + return true; + } + + case NWC24_ERR_INPROGRESS: + case NWC24_ERR_BUSY: + case NWC24_ERR_MUTEX: { + return false; + } + + case NWC24_ERR_NAND_CORRUPT: + case NWC24_ERR_FILE_OTHER: + case NWC24_ERR_FILE_NOEXISTS: + case NWC24_ERR_FILE_WRITE: + case NWC24_ERR_FILE_READ: + case NWC24_ERR_FILE_CLOSE: + case NWC24_ERR_FILE_OPEN: + case NWC24_ERR_BROKEN: + case NWC24_ERR_FATAL: { + sSuccess = false; + return false; + } + + default: { + return false; + } + } +} + +/** + * @brief Closes the WiiConnect24 library + */ +void RPSysNWC24Manager::closeLib() { + switch (NWC24CloseLib()) { + case NWC24_ERR_FILE_OTHER: + case NWC24_ERR_FILE_NOEXISTS: + case NWC24_ERR_FILE_WRITE: + case NWC24_ERR_FILE_READ: + case NWC24_ERR_FILE_CLOSE: + case NWC24_ERR_FILE_OPEN: { + sSuccess = false; + break; + } + + case NWC24_ERR_LIB_NOT_OPENED: + case NWC24_OK: + default: { + break; + } + } +} diff --git a/src/egg/gfxe/eggDrawPathBase.cpp b/src/egg/gfxe/eggDrawPathBase.cpp index acfbe8d1..41d8d636 100644 --- a/src/egg/gfxe/eggDrawPathBase.cpp +++ b/src/egg/gfxe/eggDrawPathBase.cpp @@ -5,14 +5,14 @@ namespace EGG { DrawPathBase::DrawPathBase() {} void DrawPathBase::calc() { - if (isVisible()) { + if (isEnable()) { copyFromAnother(IDrawGX::getScreen()); internalCalc(); } } void DrawPathBase::scnProcDraw(u16 step) { - if (isVisible()) { + if (isEnable()) { internalDraw(step); } } diff --git a/src/egg/gfxe/eggPostEffectBlur.cpp b/src/egg/gfxe/eggPostEffectBlur.cpp index 1dff0f89..0f752fb7 100644 --- a/src/egg/gfxe/eggPostEffectBlur.cpp +++ b/src/egg/gfxe/eggPostEffectBlur.cpp @@ -1,55 +1,48 @@ #include "eggPostEffectBlur.h" + +#include "eggCapTexture.h" #include "eggDrawGX.h" #include "eggGXUtility.h" -#include "eggCapTexture.h" + #include -namespace EGG -{ - using namespace nw4r; - - PostEffectBlur::PostEffectBlur() - { - } +namespace EGG { +using namespace nw4r; - void PostEffectBlur::reset() - { - // Maybe old code? Draw seems to suggest it is an array - BlurData* it = mBlurData; - for (int i = 0; i < CIRCLE_MAX; i++, it++){ - it->reset(); - } +PostEffectBlur::PostEffectBlur() {} - mNumBlurData = 1; - mColorScale = 1.0f; - WORD_0x24 = 0; +void PostEffectBlur::reset() { + // Maybe old code? Draw seems to suggest it is an array + BlurData* it = mBlurData; + for (int i = 0; i < CIRCLE_MAX; i++, it++) { + it->reset(); } - void PostEffectBlur::draw(f32 width, f32 height) - { - if (isVisible()) - { - loadTextureInternal(); - setMatColorChannel(); - setMatInd(); - setMatPE(); - setVtxState(); - - for (u8 i = 0; i < mNumBlurData; i++) - { - int end = (mBlurData[i].BYTE_0x0 - 1) / 8; - for (u8 j = 0; j <= end; j++) - { - drawBlurPass(i, j); - drawScreenInternal(mOffsetX, mOffsetY, width * mScaleX, height * mScaleY); - DrawGX::SetBlendMode(DrawGX::BLEND_ADD); - } + mNumBlurData = 1; + mColorScale = 1.0f; + WORD_0x24 = 0; +} + +void PostEffectBlur::draw(f32 width, f32 height) { + if (isVisible()) { + loadTextureInternal(); + setMatColorChannel(); + setMatInd(); + setMatPE(); + setVtxState(); + + for (u8 i = 0; i < mNumBlurData; i++) { + int end = (mBlurData[i].BYTE_0x0 - 1) / 8; + for (u8 j = 0; j <= end; j++) { + drawBlurPass(i, j); + drawScreenInternal(mOffsetX, mOffsetY, width * mScaleX, + height * mScaleY); + DrawGX::SetBlendMode(DrawGX::BLEND_ADD); } } } - - // https://decomp.me/scratch/pbk8u - void PostEffectBlur::drawBlurPass(u8 idx, u8 pass) - { - } } + +// https://decomp.me/scratch/pbk8u +void PostEffectBlur::drawBlurPass(u8 idx, u8 pass) {} +} // namespace EGG diff --git a/src/egg/gfxe/eggScnRenderer.cpp b/src/egg/gfxe/eggScnRenderer.cpp index 79a59e8d..62ac73b6 100644 --- a/src/egg/gfxe/eggScnRenderer.cpp +++ b/src/egg/gfxe/eggScnRenderer.cpp @@ -1,292 +1,263 @@ #include "eggScnRenderer.h" -#include "egg/gfxe/eggDrawPathXluSnap.h" + #include "eggDrawPathBase.h" -#include "eggDrawPathXluSnap.h" -#include "eggDrawPathShadowVolume.h" -#include "eggDrawPathHDR.h" #include "eggDrawPathBloom.h" #include "eggDrawPathDOF.h" +#include "eggDrawPathHDR.h" +#include "eggDrawPathShadowVolume.h" +#include "eggDrawPathXluSnap.h" + +#include "egg/gfxe/eggDrawPathXluSnap.h" + #include -namespace EGG -{ - using namespace nw4r; +namespace EGG { +using namespace nw4r; - ScnRenderer::ScnRenderer(g3d::ScnRoot *pScnRoot) : - ScnRootEx(pScnRoot), - mppPathSet(NULL), - mpTimingPrioritySet(NULL), - mFlags(RENDERER_VISIBLE) - { - } +ScnRenderer::ScnRenderer(g3d::ScnRoot* pScnRoot) + : ScnRootEx(pScnRoot), + mppPathSet(NULL), + mpTimingPrioritySet(NULL), + mFlags(RENDERER_VISIBLE) {} - ScnRenderer::~ScnRenderer() - { - #line 102 - EGG_ASSERT(mppPathSet); +ScnRenderer::~ScnRenderer() { +#line 102 + EGG_ASSERT(mppPathSet); - for (int i = 0; i < getNumDrawPath(); i++) - { - if (mppPathSet[i] != NULL) - { - delete mppPathSet[i]; - mppPathSet[i] = NULL; - } + for (int i = 0; i < getNumDrawPath(); i++) { + if (mppPathSet[i] != NULL) { + delete mppPathSet[i]; + mppPathSet[i] = NULL; } + } - delete mppPathSet; - mppPathSet = NULL; + delete mppPathSet; + mppPathSet = NULL; - delete mpTimingPrioritySet; - mpTimingPrioritySet = NULL; - } + delete mpTimingPrioritySet; + mpTimingPrioritySet = NULL; +} - u16 ScnRenderer::getNumDrawPath() const - { - return DRAW_PATH_MAX; - } +u16 ScnRenderer::getNumDrawPath() const { + return DRAW_PATH_MAX; +} - void ScnRenderer::configure() - { - #line 122 - EGG_ASSERT(mppPathSet == NULL); - - mppPathSet = new DrawPathBase*[getNumDrawPath()]; - for (int i = 0; i < getNumDrawPath(); i++) - { - mppPathSet[i] = NULL; - } +void ScnRenderer::configure() { +#line 122 + EGG_ASSERT(mppPathSet == NULL); - mpTimingPrioritySet = new TimingPriority[getNumTiming()]; - for (u16 i = 0; i < getNumTiming(); i++) - { - TimingPriority *timing = &mpTimingPrioritySet[i]; + mppPathSet = new DrawPathBase*[getNumDrawPath()]; + for (int i = 0; i < getNumDrawPath(); i++) { + mppPathSet[i] = NULL; + } + + mpTimingPrioritySet = new TimingPriority[getNumTiming()]; + for (u16 i = 0; i < getNumTiming(); i++) { + TimingPriority* timing = &mpTimingPrioritySet[i]; + timing->localPrio = 0; + timing->prioMax = 0; + timing->opa = true; + + switch (i) { + case 0: + timing->localPrio = 1; + timing->prioMax = 24; + break; + case 1: + timing->localPrio = 27; + timing->prioMax = 50; + break; + case 2: + timing->localPrio = 52; + timing->prioMax = 75; + break; + case 3: + timing->localPrio = 77; + timing->prioMax = 100; + break; + case 4: timing->localPrio = 0; - timing->prioMax = 0; - timing->opa = true; - - switch(i) - { - case 0: - timing->localPrio = 1; - timing->prioMax = 24; - break; - case 1: - timing->localPrio = 27; - timing->prioMax = 50; - break; - case 2: - timing->localPrio = 52; - timing->prioMax = 75; - break; - case 3: - timing->localPrio = 77; - timing->prioMax = 100; - break; - case 4: - timing->localPrio = 0; - timing->prioMax = 23; - timing->opa = false; - break; - case 5: - timing->localPrio = 25; - timing->prioMax = 48; - timing->opa = false; - break; - case 6: - timing->localPrio = 58; - timing->prioMax = 81; - timing->opa = false; - break; - default: - #line 186 - EGG_ASSERT(0); - break; - } + timing->prioMax = 23; + timing->opa = false; + break; + case 5: + timing->localPrio = 25; + timing->prioMax = 48; + timing->opa = false; + break; + case 6: + timing->localPrio = 58; + timing->prioMax = 81; + timing->opa = false; + break; + default: +#line 186 + EGG_ASSERT(0); + break; } } +} - u16 ScnRenderer::getNumTiming() const - { - return NUM_TIMING; - } +u16 ScnRenderer::getNumTiming() const { + return NUM_TIMING; +} - void ScnRenderer::createPath(u32 type, MEMAllocator *allocator) - { - #line 200 - EGG_ASSERT(mppPathSet != NULL); - - for (u16 i = 0; i < getNumDrawPath(); i++) - { - if ((type & 1 << i) == 0) continue; - - switch(i) - { - case DRAW_PATH_XLU_SNAP: - mppPathSet[i] = new DrawPathXluSnap(); - break; - case DRAW_PATH_SV: - mppPathSet[i] = new DrawPathShadowVolume(); - break; - case DRAW_PATH_HDR: - mppPathSet[i] = new DrawPathHDR(); - break; - case DRAW_PATH_BLOOM: - mppPathSet[i] = new DrawPathBloom(); - break; - case DRAW_PATH_DOF: - mppPathSet[i] = new DrawPathDOF(); - break; - } - - #line 235 - EGG_ASSERT(getDrawPathBase( i )); - - DrawPathBase *path = getDrawPathBase(i); - const int numScnProc = path->getNumStep(); - path->createScnProc(numScnProc, allocator); - - switch(i) - { - case DRAW_PATH_XLU_SNAP: - path->setPriorityScnProc(0, 0, true); - path->setPriorityScnProc(1, 25, true); - path->setPriorityScnProc(2, 24, false); - path->setPriorityScnProc(3, 49, false); - break; - case DRAW_PATH_SV: - path->setPriorityScnProc(0, 26, true); - path->setPriorityScnProc(1, 51, true); - path->setPriorityScnProc(2, 76, true); - break; - case DRAW_PATH_HDR: - path->setPriorityScnProc(0, 50, false); - path->setPriorityScnProc(1, 53, false); - break; - case DRAW_PATH_BLOOM: - path->setPriorityScnProc(0, 51, false); - path->setPriorityScnProc(1, 54, false); - path->setPriorityScnProc(2, 57, false); - break; - case DRAW_PATH_DOF: - path->setPriorityScnProc(0, 52, false); - path->setPriorityScnProc(1, 55, false); - path->setPriorityScnProc(2, 56, false); - break; - } +void ScnRenderer::createPath(u32 type, MEMAllocator* allocator) { +#line 200 + EGG_ASSERT(mppPathSet != NULL); + + for (u16 i = 0; i < getNumDrawPath(); i++) { + if ((type & 1 << i) == 0) + continue; + + switch (i) { + case DRAW_PATH_XLU_SNAP: + mppPathSet[i] = new DrawPathXluSnap(); + break; + case DRAW_PATH_SV: + mppPathSet[i] = new DrawPathShadowVolume(); + break; + case DRAW_PATH_HDR: + mppPathSet[i] = new DrawPathHDR(); + break; + case DRAW_PATH_BLOOM: + mppPathSet[i] = new DrawPathBloom(); + break; + case DRAW_PATH_DOF: + mppPathSet[i] = new DrawPathDOF(); + break; } - if (getDrawPathBase(DRAW_PATH_BLOOM) != NULL) - { - if (getDrawPathBase(DRAW_PATH_SV) != NULL) - { - } +#line 235 + EGG_ASSERT(getDrawPathBase( i )); + + DrawPathBase* path = getDrawPathBase(i); + const int numScnProc = path->getNumStep(); + path->createScnProc(numScnProc, allocator); + + switch (i) { + case DRAW_PATH_XLU_SNAP: + path->setPriorityScnProc(0, 0, true); + path->setPriorityScnProc(1, 25, true); + path->setPriorityScnProc(2, 24, false); + path->setPriorityScnProc(3, 49, false); + break; + case DRAW_PATH_SV: + path->setPriorityScnProc(0, 26, true); + path->setPriorityScnProc(1, 51, true); + path->setPriorityScnProc(2, 76, true); + break; + case DRAW_PATH_HDR: + path->setPriorityScnProc(0, 50, false); + path->setPriorityScnProc(1, 53, false); + break; + case DRAW_PATH_BLOOM: + path->setPriorityScnProc(0, 51, false); + path->setPriorityScnProc(1, 54, false); + path->setPriorityScnProc(2, 57, false); + break; + case DRAW_PATH_DOF: + path->setPriorityScnProc(0, 52, false); + path->setPriorityScnProc(1, 55, false); + path->setPriorityScnProc(2, 56, false); + break; } - - mDrawSettings &= ~DRAW_ALPHA_UPDATE_XLU; } - void ScnRenderer::pushBackDrawPath() - { - for(u16 i = 0; i < getNumDrawPath(); i++) - { - if (mppPathSet[i] != NULL) - mppPathSet[i]->pushBackToScnGroup(mBase); + if (getDrawPathBase(DRAW_PATH_BLOOM) != NULL) { + if (getDrawPathBase(DRAW_PATH_SV) != NULL) { } } - void ScnRenderer::changeScnRoot(g3d::ScnRoot *pScnRoot) - { - #line 328 - EGG_ASSERT(pScnRoot != NULL); - - if (pScnRoot != mBase) - { - for (u16 i = 0; i < getNumDrawPath(); i++) - { - if (mppPathSet[i] != NULL) - mppPathSet[i]->removeFromScnGroup(mBase); - } + mDrawSettings &= ~DRAW_ALPHA_UPDATE_XLU; +} - ScnRootEx::changeScnRoot(pScnRoot); +void ScnRenderer::pushBackDrawPath() { + for (u16 i = 0; i < getNumDrawPath(); i++) { + if (mppPathSet[i] != NULL) + mppPathSet[i]->pushBackToScnGroup(mBase); + } +} - for (u16 i = 0; i < getNumDrawPath(); i++) - { - if (mppPathSet[i] != NULL) - mppPathSet[i]->pushBackToScnGroup(mBase); - } +void ScnRenderer::changeScnRoot(g3d::ScnRoot* pScnRoot) { +#line 328 + EGG_ASSERT(pScnRoot != NULL); + + if (pScnRoot != mBase) { + for (u16 i = 0; i < getNumDrawPath(); i++) { + if (mppPathSet[i] != NULL) + mppPathSet[i]->removeFromScnGroup(mBase); } - } - namespace - { - void UNUSED_ASSERTS_SCNRENDERER() - { - EGG_ASSERT_MSG(false, "pObj"); - EGG_ASSERT_MSG(false, "This timing is not opa."); - EGG_ASSERT_MSG(false, "Local priority range over."); - EGG_ASSERT_MSG(false, "This timing is not xlu."); + ScnRootEx::changeScnRoot(pScnRoot); + + for (u16 i = 0; i < getNumDrawPath(); i++) { + if (mppPathSet[i] != NULL) + mppPathSet[i]->pushBackToScnGroup(mBase); } } +} - u16 ScnRenderer::getLocalPriorityMax() const - { - return LOCAL_PRIO_MAX; - } +namespace { +void UNUSED_ASSERTS_SCNRENDERER() { + EGG_ASSERT_MSG(false, "pObj"); + EGG_ASSERT_MSG(false, "This timing is not opa."); + EGG_ASSERT_MSG(false, "Local priority range over."); + EGG_ASSERT_MSG(false, "This timing is not xlu."); +} +} // namespace - void ScnRenderer::setLocalPriorityScnProc(IScnProc *pScnProc, u32 timing, u8 basePrio, u16 procIndex) const - { - #line 394 - EGG_ASSERT(pScnProc); +u16 ScnRenderer::getLocalPriorityMax() const { + return LOCAL_PRIO_MAX; +} - u8 localPrio, prioMax; - bool opa = getTimingPriority(timing, &localPrio, &prioMax); +void ScnRenderer::setLocalPriorityScnProc(IScnProc* pScnProc, u32 timing, + u8 basePrio, u16 procIndex) const { +#line 394 + EGG_ASSERT(pScnProc); - #line 397 - EGG_ASSERT_MSG(localPrio + basePrio <= prioMax, "Local priority range over."); - pScnProc->setPriorityScnProc(procIndex, localPrio + basePrio, opa); - } + u8 localPrio, prioMax; + bool opa = getTimingPriority(timing, &localPrio, &prioMax); - void ScnRenderer::calc_after_CalcWorld() - { - ScnRootEx::calc_after_CalcWorld(); +#line 397 + EGG_ASSERT_MSG(localPrio + basePrio <= prioMax, "Local priority range over."); + pScnProc->setPriorityScnProc(procIndex, localPrio + basePrio, opa); +} - for (u16 i = 0; i < getNumDrawPath(); i++) - { - if (mppPathSet[i] != NULL && mppPathSet[i]->isVisible()) - mppPathSet[i]->internalResetForDraw(); - } +void ScnRenderer::calc_after_CalcWorld() { + ScnRootEx::calc_after_CalcWorld(); + + for (u16 i = 0; i < getNumDrawPath(); i++) { + if (mppPathSet[i] != NULL && mppPathSet[i]->isEnable()) + mppPathSet[i]->internalResetForDraw(); } +} - void ScnRenderer::draw_before_CalcView() - { - ScnRootEx::draw_before_CalcView(); - - if (isVisible()) - { - if (getDrawPathBase(DRAW_PATH_BLOOM) != NULL) - { - if (getDrawPathBase(DRAW_PATH_DOF) != NULL) - { - if (getDrawPathBase(DRAW_PATH_DOF)->isVisible()) - { - DrawPathBloom *bloom = (DrawPathBloom *)getDrawPathBase(DRAW_PATH_BLOOM); - bloom->setFlag(0x8); - goto clean; - } +void ScnRenderer::draw_before_CalcView() { + ScnRootEx::draw_before_CalcView(); + + if (isVisible()) { + if (getDrawPathBase(DRAW_PATH_BLOOM) != NULL) { + if (getDrawPathBase(DRAW_PATH_DOF) != NULL) { + if (getDrawPathBase(DRAW_PATH_DOF)->isEnable()) { + DrawPathBloom* bloom = + (DrawPathBloom*)getDrawPathBase(DRAW_PATH_BLOOM); + bloom->setFlag(0x8); + goto clean; } - - DrawPathBloom *bloom = (DrawPathBloom *)getDrawPathBase(DRAW_PATH_BLOOM); - bloom->clearFlag(0x8); } - } - clean: - ScreenEffectBase::clean(); - for (u16 i = 0; i < getNumDrawPath(); i++) - { - if (mppPathSet[i] != NULL) - mppPathSet[i]->calc(); + DrawPathBloom* bloom = + (DrawPathBloom*)getDrawPathBase(DRAW_PATH_BLOOM); + bloom->clearFlag(0x8); } } + +clean: + ScreenEffectBase::clean(); + for (u16 i = 0; i < getNumDrawPath(); i++) { + if (mppPathSet[i] != NULL) + mppPathSet[i]->calc(); + } } +} // namespace EGG diff --git a/src/egg/gfxe/eggScreenEffectBase.cpp b/src/egg/gfxe/eggScreenEffectBase.cpp index 5408eb0d..a9587397 100644 --- a/src/egg/gfxe/eggScreenEffectBase.cpp +++ b/src/egg/gfxe/eggScreenEffectBase.cpp @@ -1,265 +1,242 @@ #pragma ipa file #include "eggScreenEffectBase.h" -#include "eggStateGX.h" -#include "eggTextureBuffer.h" + #include "eggPostEffectBase.h" #include "eggPostEffectSimple.h" +#include "eggStateGX.h" +#include "eggTextureBuffer.h" -namespace EGG -{ - ScreenEffectBase::EffectBuffer ScreenEffectBase::spBufferSet[cBufferType_Max]; - ScreenEffectBase::WorkView ScreenEffectBase::sWorkSpaceV; - ScreenEffectBase::WorkView ScreenEffectBase::sWorkSpaceHideV; +namespace EGG { +ScreenEffectBase::EffectBuffer ScreenEffectBase::spBufferSet[cBufferType_Max]; - u32 ScreenEffectBase::sCaptureFlag; - u32 ScreenEffectBase::sFlag; - u32 ScreenEffectBase::D_804BEC58; - u32 ScreenEffectBase::sPushCount; - s32 ScreenEffectBase::sWorkBuffer = -1; +ScreenEffectBase::WorkView ScreenEffectBase::sWorkSpaceV; +ScreenEffectBase::WorkView ScreenEffectBase::sWorkSpaceHideV; - ScreenEffectBase::ScreenEffectBase() : mFlags(EFFECT_VISIBLE) - { - } +u32 ScreenEffectBase::sCaptureFlag; +u32 ScreenEffectBase::sFlag; +u32 ScreenEffectBase::D_804BEC58; +u32 ScreenEffectBase::sPushCount; +s32 ScreenEffectBase::sWorkBuffer = -1; - void ScreenEffectBase::copyFromAnother(const Screen& screen) - { - mScreen.CopyFromAnother(screen); - } +ScreenEffectBase::ScreenEffectBase() : mFlags(EFFECT_ENABLE) {} - // https://decomp.me/scratch/w13Yi - // - There seems to be some BSS pooling(?) regarding - // the workspace views - // - The loop only increments one pointer somehow, - // despite getBuffer not returning the effect buffer - void ScreenEffectBase::clean() - { - sFlag &= ~0x3; - sWorkBuffer = -1; - D_804BEC58 = 0; - sPushCount = 0; - - for (s32 i = 0; i < cBufferType_Max; i++) - { - #line 72 - EGG_ASSERT(getBuffer( ( BufferType )i ) == NULL); - spBufferSet[i].WORD_0x8 = 0; - } - - sWorkSpaceV.x1 = sWorkSpaceHideV.x1 = 0.0f; - sWorkSpaceV.y1 = sWorkSpaceHideV.y1 = 0.0f; - sWorkSpaceV.x2 = sWorkSpaceHideV.x2 = 0.0f; - sWorkSpaceV.y2 = sWorkSpaceHideV.y2 = 0.0f; - sWorkSpaceV.FLOAT_0x10 = sWorkSpaceHideV.FLOAT_0x10 = 0.0f; - sWorkSpaceV.FLOAT_0x14 = sWorkSpaceHideV.FLOAT_0x14 = 0.0f; +void ScreenEffectBase::copyFromAnother(const Screen& screen) { + mScreen.CopyFromAnother(screen); +} + +// https://decomp.me/scratch/w13Yi +// - There seems to be some BSS pooling(?) regarding +// the workspace views +// - The loop only increments one pointer somehow, +// despite getBuffer not returning the effect buffer +void ScreenEffectBase::clean() { + sFlag &= ~0x3; + sWorkBuffer = -1; + D_804BEC58 = 0; + sPushCount = 0; + + for (s32 i = 0; i < cBufferType_Max; i++) { +#line 72 + EGG_ASSERT(getBuffer( ( BufferType )i ) == NULL); + spBufferSet[i].WORD_0x8 = 0; } - // https://decomp.me/scratch/RYUOH - // - Despite the setBuffer inline being used, it seems like - // there is a temp variable for &spBufferSet[type] - // - The cap texture copy filter application is not yet - // understood - TextureBuffer* ScreenEffectBase::capture(BufferType type, bool clear) const - { - TextureBuffer* buffer; - const Screen::DataEfb& efb = mScreen.GetDataEfb(); - - if (getBuffer(type) == NULL) - { - f32 cap_x = efb.vp.x; - f32 cap_y = efb.vp.y; - - // Doubles capture resolution - bool upscale = false; - - switch(type) - { - case cBufferType_Hide_1_16: - case cBufferType_1: - const f32 scale = - (type == cBufferType_Hide_1_16) ? 0.25f : 0.5f; - sWorkSpaceV.x2 = efb.vp.width * scale; - sWorkSpaceV.y2 = efb.vp.height * scale; - - if (sCaptureFlag & 0x1) - { - sWorkSpaceHideV.x1 = 640.0f - sWorkSpaceV.x2; - sWorkSpaceHideV.y1 = 528.0f - sWorkSpaceV.y2; - - const f32 overX = 640 - StateGX::getEfbWidth(); - const f32 overY = 528 - StateGX::getEfbHeight(); - sWorkSpaceHideV.x2 = sWorkSpaceV.x2 - overX; - sWorkSpaceHideV.y2 = sWorkSpaceV.y2 - overY; - - if (sWorkSpaceHideV.x2 < 0.0f) - sWorkSpaceHideV.x2 = 0.0f; - if (sWorkSpaceHideV.y2 < 0.0f) - sWorkSpaceHideV.y2 = 0.0f; - } - else - { - sWorkSpaceHideV.x1 = efb.vp.x; - sWorkSpaceHideV.y1 = efb.vp.y; - sWorkSpaceHideV.x2 = sWorkSpaceV.x2; - sWorkSpaceHideV.y2 = sWorkSpaceV.y2; - } - - buffer = TextureBuffer::alloc(sWorkSpaceHideV.x2, - sWorkSpaceHideV.y2, GX_TF_RGBA8); - setBuffer(type, buffer); - - if (buffer != NULL) - buffer->clearFlag(0x80); - break; - case cBufferType_2: - buffer = TextureBuffer::alloc(efb.vp.width, efb.vp.height, - GX_TF_RGBA8); - setBuffer(type, buffer); - buffer->clearFlag(0x80); - break; - case cBufferType_3: - buffer = TextureBuffer::alloc(efb.vp.width / 2.0f, - efb.vp.height / 2.0f, GX_TF_RGBA8); - setBuffer(type, buffer); - upscale = true; - buffer->setFlag(0x40); - // TO-DO: Copy filter args are set here, not colors - // buffer->setColor_24((GXColor){21, 0, 0, 22}); - // buffer->setColor_28((GXColor){21, 0, 0, 22}); - break; - default: - #line 158 - EGG_ASSERT(0); - break; + sWorkSpaceV.x1 = sWorkSpaceHideV.x1 = 0.0f; + sWorkSpaceV.y1 = sWorkSpaceHideV.y1 = 0.0f; + sWorkSpaceV.x2 = sWorkSpaceHideV.x2 = 0.0f; + sWorkSpaceV.y2 = sWorkSpaceHideV.y2 = 0.0f; + sWorkSpaceV.FLOAT_0x10 = sWorkSpaceHideV.FLOAT_0x10 = 0.0f; + sWorkSpaceV.FLOAT_0x14 = sWorkSpaceHideV.FLOAT_0x14 = 0.0f; +} + +// https://decomp.me/scratch/RYUOH +// - Despite the setBuffer inline being used, it seems like +// there is a temp variable for &spBufferSet[type] +// - The cap texture copy filter application is not yet +// understood +TextureBuffer* ScreenEffectBase::capture(BufferType type, bool clear) const { + TextureBuffer* buffer; + const Screen::DataEfb& efb = mScreen.GetDataEfb(); + + if (getBuffer(type) == NULL) { + f32 cap_x = efb.vp.x; + f32 cap_y = efb.vp.y; + + // Doubles capture resolution + bool upscale = false; + + switch (type) { + case cBufferType_Hide_1_16: + case cBufferType_1: + const f32 scale = (type == cBufferType_Hide_1_16) ? 0.25f : 0.5f; + sWorkSpaceV.x2 = efb.vp.width * scale; + sWorkSpaceV.y2 = efb.vp.height * scale; + + if (sCaptureFlag & 0x1) { + sWorkSpaceHideV.x1 = 640.0f - sWorkSpaceV.x2; + sWorkSpaceHideV.y1 = 528.0f - sWorkSpaceV.y2; + + const f32 overX = 640 - StateGX::getEfbWidth(); + const f32 overY = 528 - StateGX::getEfbHeight(); + sWorkSpaceHideV.x2 = sWorkSpaceV.x2 - overX; + sWorkSpaceHideV.y2 = sWorkSpaceV.y2 - overY; + + if (sWorkSpaceHideV.x2 < 0.0f) + sWorkSpaceHideV.x2 = 0.0f; + if (sWorkSpaceHideV.y2 < 0.0f) + sWorkSpaceHideV.y2 = 0.0f; + } else { + sWorkSpaceHideV.x1 = efb.vp.x; + sWorkSpaceHideV.y1 = efb.vp.y; + sWorkSpaceHideV.x2 = sWorkSpaceV.x2; + sWorkSpaceHideV.y2 = sWorkSpaceV.y2; } - if (getBuffer(type) != NULL) - { - spBufferSet[type].mpAllocBase = this; + buffer = TextureBuffer::alloc(sWorkSpaceHideV.x2, + sWorkSpaceHideV.y2, GX_TF_RGBA8); + setBuffer(type, buffer); + + if (buffer != NULL) + buffer->clearFlag(0x80); + break; + case cBufferType_2: + buffer = + TextureBuffer::alloc(efb.vp.width, efb.vp.height, GX_TF_RGBA8); + setBuffer(type, buffer); + buffer->clearFlag(0x80); + break; + case cBufferType_3: + buffer = TextureBuffer::alloc(efb.vp.width / 2.0f, + efb.vp.height / 2.0f, GX_TF_RGBA8); + setBuffer(type, buffer); + upscale = true; + buffer->setFlag(0x40); + // TO-DO: Copy filter args are set here, not colors + // buffer->setColor_24((GXColor){21, 0, 0, 22}); + // buffer->setColor_28((GXColor){21, 0, 0, 22}); + break; + default: +#line 158 + EGG_ASSERT(0); + break; + } - if (clear) - { - getBuffer(type)->setFlag(0x10); - getBuffer(type)->setClearColor((GXColor){0, 0, 0, 0}); - } - } + if (getBuffer(type) != NULL) { + spBufferSet[type].mpAllocBase = this; - #line 171 - EGG_ASSERT(cap_x >= 0.f && cap_y >= 0.f); - getBuffer(type)->capture(cap_x, cap_y, upscale, -1); + if (clear) { + getBuffer(type)->setFlag(0x10); + getBuffer(type)->setClearColor((GXColor){0, 0, 0, 0}); + } } - return getBuffer(type); +#line 171 + EGG_ASSERT(cap_x >= 0.f && cap_y >= 0.f); + getBuffer(type)->capture(cap_x, cap_y, upscale, -1); } - bool ScreenEffectBase::release(BufferType type) const - { - if (spBufferSet[type].mpTexBuffer != NULL - && spBufferSet[type].mpAllocBase == this) - { - spBufferSet[type].mpTexBuffer->free(); - clearBuffer(type); - return true; - } + return getBuffer(type); +} - return false; +bool ScreenEffectBase::release(BufferType type) const { + if (spBufferSet[type].mpTexBuffer != NULL && + spBufferSet[type].mpAllocBase == this) { + spBufferSet[type].mpTexBuffer->free(); + clearBuffer(type); + return true; } - void ScreenEffectBase::doCapture(int buffer) const - { - if (buffer == 0) - { - if (sWorkBuffer == 1) - { - #line 207 - EGG_ASSERT(spBufferSet[cBufferType_Hide_1_16].mpAllocBase != NULL); - spBufferSet[cBufferType_Hide_1_16].mpAllocBase->release(cBufferType_Hide_1_16); - } + return false; +} - capture(cBufferType_1, false); - sWorkBuffer = 0; - } - else if (buffer == 1 && sWorkBuffer != 0) - { - capture(cBufferType_Hide_1_16, false); - sWorkBuffer = 1; +void ScreenEffectBase::doCapture(int buffer) const { + if (buffer == 0) { + if (sWorkBuffer == 1) { +#line 207 + EGG_ASSERT(spBufferSet[cBufferType_Hide_1_16].mpAllocBase != NULL); + spBufferSet[cBufferType_Hide_1_16].mpAllocBase->release( + cBufferType_Hide_1_16); } + + capture(cBufferType_1, false); + sWorkBuffer = 0; + } else if (buffer == 1 && sWorkBuffer != 0) { + capture(cBufferType_Hide_1_16, false); + sWorkBuffer = 1; } +} + +void ScreenEffectBase::setupGX(bool cache) const { + BufferType type; + + if (sWorkBuffer != -1) { + type = static_cast(-1); + + if (sWorkBuffer == 0) + type = cBufferType_1; + else if (sWorkBuffer == 1) + type = cBufferType_Hide_1_16; - void ScreenEffectBase::setupGX(bool cache) const - { - BufferType type; - - if (sWorkBuffer != -1) - { - type = static_cast(-1); - - if (sWorkBuffer == 0) - type = cBufferType_1; - else if (sWorkBuffer == 1) - type = cBufferType_Hide_1_16; - - if (this == spBufferSet[type].mpAllocBase) - { - if (!cache) - { - StateGX::ScopedColorUpdate color(true); - StateGX::ScopedAlphaUpdate alpha(true); - StateGX::ScopedDitherUpdate dither(false); - - PostEffectBase::setProjection(mScreen); - - StateGX::GXSetViewport_(sWorkSpaceHideV.x1, sWorkSpaceHideV.y1, - sWorkSpaceHideV.x2, sWorkSpaceHideV.y2, 0.0f, 1.0f); - StateGX::GXSetScissor_(sWorkSpaceHideV.x1, sWorkSpaceHideV.y1, - sWorkSpaceHideV.x2, sWorkSpaceHideV.y2); - StateGX::GXSetScissorBoxOffset_(0, 0); - - PostEffectSimple eff; - eff.configure(); - eff.setCapTexture(getBuffer(type)); - eff.setBlendMode(PostEffectBase::EBlendMode_None); - - const f32 sx = mScreen.GetSize().x; - const f32 sy = mScreen.GetSize().y; - eff.draw(sx, sy); - } - - release(type); - - sWorkBuffer = -1; - sPushCount++; + if (this == spBufferSet[type].mpAllocBase) { + if (!cache) { + StateGX::ScopedColorUpdate color(true); + StateGX::ScopedAlphaUpdate alpha(true); + StateGX::ScopedDitherUpdate dither(false); + + PostEffectBase::setProjection(mScreen); + + StateGX::GXSetViewport_(sWorkSpaceHideV.x1, sWorkSpaceHideV.y1, + sWorkSpaceHideV.x2, sWorkSpaceHideV.y2, + 0.0f, 1.0f); + StateGX::GXSetScissor_(sWorkSpaceHideV.x1, sWorkSpaceHideV.y1, + sWorkSpaceHideV.x2, sWorkSpaceHideV.y2); + StateGX::GXSetScissorBoxOffset_(0, 0); + + PostEffectSimple eff; + eff.configure(); + eff.setCapTexture(getBuffer(type)); + eff.setBlendMode(PostEffectBase::EBlendMode_None); + + const f32 sx = mScreen.GetSize().x; + const f32 sy = mScreen.GetSize().y; + eff.draw(sx, sy); } + + release(type); + + sWorkBuffer = -1; + sPushCount++; } } +} - const ScreenEffectBase::WorkView& ScreenEffectBase::setupView() const - { - FullView vp; - const Screen::DataEfb& efb = mScreen.GetDataEfb(); - - vp.x2 = efb.vp.width + sWorkSpaceV.x1; - vp.x1 = sWorkSpaceV.x1; - - vp.y2 = efb.vp.height + sWorkSpaceV.y1; - vp.y1 = sWorkSpaceV.y1; - - // Clamp for X overscan - const f32 cx = (vp.x2 <= 640.0f) ? 0.0f : vp.x2 - 640.0f; - vp.cx = efb.vp.width - cx; - - // Clamp for Y overscan - const f32 cy = (vp.y2 <= 528.0f) ? 0.0f : vp.y2 - 528.0f; - vp.cy = efb.vp.height - cy; - - vp.z1 = efb.vp.near; - vp.z2 = efb.vp.far; - - StateGX::GXSetViewport_(vp.x1, vp.y1, vp.cx, vp.cy, vp.z1, vp.z2); - StateGX::GXSetScissor_(vp.x1, vp.y1, vp.cx, vp.cy); - StateGX::GXSetScissorBoxOffset_(0, 0); - - return sWorkSpaceV; - } +const ScreenEffectBase::WorkView& ScreenEffectBase::setupView() const { + FullView vp; + const Screen::DataEfb& efb = mScreen.GetDataEfb(); + + vp.x2 = efb.vp.width + sWorkSpaceV.x1; + vp.x1 = sWorkSpaceV.x1; + + vp.y2 = efb.vp.height + sWorkSpaceV.y1; + vp.y1 = sWorkSpaceV.y1; + + // Clamp for X overscan + const f32 cx = (vp.x2 <= 640.0f) ? 0.0f : vp.x2 - 640.0f; + vp.cx = efb.vp.width - cx; + + // Clamp for Y overscan + const f32 cy = (vp.y2 <= 528.0f) ? 0.0f : vp.y2 - 528.0f; + vp.cy = efb.vp.height - cy; + + vp.z1 = efb.vp.near; + vp.z2 = efb.vp.far; + + StateGX::GXSetViewport_(vp.x1, vp.y1, vp.cx, vp.cy, vp.z1, vp.z2); + StateGX::GXSetScissor_(vp.x1, vp.y1, vp.cx, vp.cy); + StateGX::GXSetScissorBoxOffset_(0, 0); + + return sWorkSpaceV; } +} // namespace EGG From d2487b308ef552299fa794e589ba8db03b7f5c31 Mon Sep 17 00:00:00 2001 From: kiwi515 <49212064+kiwi515@users.noreply.github.com> Date: Tue, 9 Dec 2025 18:26:27 -0500 Subject: [PATCH 3/4] Update RPSysNWC24Manager.h --- include/Pack/RPKernel/RPSysNWC24Manager.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/include/Pack/RPKernel/RPSysNWC24Manager.h b/include/Pack/RPKernel/RPSysNWC24Manager.h index 02a23bd6..49c2062b 100644 --- a/include/Pack/RPKernel/RPSysNWC24Manager.h +++ b/include/Pack/RPKernel/RPSysNWC24Manager.h @@ -17,7 +17,9 @@ class RPSysAvatar; */ class RPSysNWC24Manager { protected: - u8* mpNwc24Work; // at 0x0 + //! Work buffer for NWC24 + u8* mpNwc24Work; // at 0x0 + //! Work buffer for message formatting wchar_t* mpMsgWork; // at 0x4 public: @@ -53,6 +55,10 @@ class RPSysNWC24Manager { bool commitMail(const wchar_t* pAltName, const wchar_t* pMsg, RPTime16 date, const RPSysAvatar* pAvatar, int argc, va_list argv); +private: + //! Size of the message work buffer + static const int MSG_BUFFER_SIZE = 1024; + private: /** * @brief Attempts to open the WiiConnect24 library for use @@ -67,9 +73,6 @@ class RPSysNWC24Manager { void closeLib(); private: - //! Size of the message work buffer - static const int MSG_BUFFER_SIZE = 1024; - //! Whether the last NWC24 operation was successful static BOOL sSuccess; }; From ca1eaf5b0548fc048a545c94dac48f432bfc17ab Mon Sep 17 00:00:00 2001 From: kiwi515 <49212064+kiwi515@users.noreply.github.com> Date: Tue, 9 Dec 2025 18:27:06 -0500 Subject: [PATCH 4/4] Update RPSysNWC24Manager.h --- include/Pack/RPKernel/RPSysNWC24Manager.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/Pack/RPKernel/RPSysNWC24Manager.h b/include/Pack/RPKernel/RPSysNWC24Manager.h index 49c2062b..1c6abc56 100644 --- a/include/Pack/RPKernel/RPSysNWC24Manager.h +++ b/include/Pack/RPKernel/RPSysNWC24Manager.h @@ -2,8 +2,6 @@ #define RP_KERNEL_NWC24_MANAGER_H #include -#include - #include //! @addtogroup rp_kernel