diff --git a/configure.py b/configure.py index 33597270..97fb7826 100755 --- a/configure.py +++ b/configure.py @@ -557,7 +557,7 @@ LIBS = [ ["Kyoto/Graphics/CLight", True], "Kyoto/Graphics/CCubeModel", ["Kyoto/Graphics/CGX", True], - "Kyoto/Graphics/CTevCombiners", + ["Kyoto/Graphics/CTevCombiners", False], "Kyoto/Graphics/DolphinCGraphics", "Kyoto/Graphics/DolphinCPalette", "Kyoto/Graphics/DolphinCTexture", diff --git a/include/Kyoto/Graphics/CTevCombiners.hpp b/include/Kyoto/Graphics/CTevCombiners.hpp index 7e41f8dc..4b4c9efe 100644 --- a/include/Kyoto/Graphics/CTevCombiners.hpp +++ b/include/Kyoto/Graphics/CTevCombiners.hpp @@ -29,6 +29,8 @@ public: public: ColorVar(EColorSrc src); + EColorSrc GetSource() const { return x0_src; } + private: EColorSrc x0_src; }; @@ -36,6 +38,10 @@ public: public: ColorPass(const ColorVar& a, const ColorVar& b, const ColorVar& c, const ColorVar& d) : x0_a(a), x4_b(b), x8_c(c), xc_d(d) {} + ColorVar GetA() const { return x0_a; } + ColorVar GetB() const { return x4_b; } + ColorVar GetC() const { return x8_c; } + ColorVar GetD() const { return xc_d; } private: ColorVar x0_a; @@ -57,6 +63,7 @@ public: class AlphaVar { public: AlphaVar(EAlphaSrc src); + EAlphaSrc GetSource() const { return x0_src; } private: EAlphaSrc x0_src; @@ -66,6 +73,11 @@ public: AlphaPass(const AlphaVar& a, const AlphaVar& b, const AlphaVar& c, const AlphaVar& d) : x0_a(a), x4_b(b), x8_c(c), xc_d(d) {} + AlphaVar GetA() const { return x0_a; } + AlphaVar GetB() const { return x4_b; } + AlphaVar GetC() const { return x8_c; } + AlphaVar GetD() const { return xc_d; } + private: AlphaVar x0_a; AlphaVar x4_b; @@ -100,6 +112,12 @@ public: bool clamp = true, ETevOutput output = kTO_Previous) : x0_clamp(clamp), x4_op(op), x8_bias(bias), xc_scale(scale), x10_output(output) {} + bool GetClamp() const { return x0_clamp; } + ETevOp GetOp() const { return x4_op; } + ETevBias GetBias() const { return x8_bias; } + ETevScale GetScale() const { return xc_scale; } + ETevOutput GetOutput() const { return x10_output; } + private: bool x0_clamp; ETevOp x4_op; @@ -111,7 +129,15 @@ public: class CTevPass { public: CTevPass(const ColorPass& colorPass, const AlphaPass& alphaPass, - const CTevOp& colorOp = CTevOp(), const CTevOp& alphaOp = CTevOp()); + const CTevOp& colorOp = CTevOp(), const CTevOp& alphaOp = CTevOp());/* + : x0_id(sUniquePass++) + , x4_colorPass(colorPass) + , x14_alphaPass(alphaPass) + , x24_colorOp(colorOp) + , x38_alphaOp(alphaOp) {} + */ + + void Execute(int) const; private: uint x0_id; @@ -121,9 +147,21 @@ public: CTevOp x38_alphaOp; }; + static void RecomputePasses(); static void Init(); + static void DeletePass(int); + static void SetupPass(int, const CTevPass& pass); + static bool SetPassCombiners(int stage, const CTevPass& pass); + static void ResetStates(); - static CTevPass kEnvPassthru; + static int sUniquePass; + static const CTevPass kEnvPassthru; + static const AlphaVar skAlphaOne; + static const ColorVar skColorOne; + +private: + static bool sValidPasses[2]; + static uint sNumEnabledPasses; }; extern CTevCombiners::CTevPass CTevPass_805a5ebc; diff --git a/src/Kyoto/Graphics/CTevCombiners.cpp b/src/Kyoto/Graphics/CTevCombiners.cpp new file mode 100644 index 00000000..98591243 --- /dev/null +++ b/src/Kyoto/Graphics/CTevCombiners.cpp @@ -0,0 +1,97 @@ +#include "Kyoto/Graphics/CTevCombiners.hpp" + +#include "Kyoto/Graphics/CGX.hpp" +#include "Kyoto/Graphics/CGraphics.hpp" + +#define TEV_MAX_PASSES 2 + +int CTevCombiners::sUniquePass = 0; +const CTevCombiners::AlphaVar CTevCombiners::skAlphaOne(CTevCombiners::kAS_Konst); +const CTevCombiners::ColorVar CTevCombiners::skColorOne(CTevCombiners::kCS_One); + +const CTevCombiners::CTevPass CTevCombiners::kEnvPassthru( + CTevCombiners::ColorPass(CTevCombiners::ColorVar(kCS_Zero), CTevCombiners::ColorVar(kCS_Zero), + CTevCombiners::ColorVar(kCS_Zero), + CTevCombiners::ColorVar(kCS_RasterColor)), + CTevCombiners::AlphaPass(CTevCombiners::AlphaVar(kAS_Zero), CTevCombiners::AlphaVar(kAS_Zero), + CTevCombiners::AlphaVar(kAS_Zero), + CTevCombiners::AlphaVar(kAS_RasterAlpha))); + +bool CTevCombiners::sValidPasses[2] = {false, false}; +uint CTevCombiners::sNumEnabledPasses = -1; + +CTevCombiners::AlphaVar::AlphaVar(EAlphaSrc src) : x0_src(src) {} +CTevCombiners::ColorVar::ColorVar(EColorSrc src) : x0_src(src) {} + +void CTevCombiners::RecomputePasses() { + sNumEnabledPasses = (uchar)(1 + (sValidPasses[TEV_MAX_PASSES - 1] != 0)); + CGX::SetNumTevStages(sNumEnabledPasses); +} + +void CTevCombiners::Init() { + for (int i = 0; i < TEV_MAX_PASSES; ++i) { + sValidPasses[i] = true; + } + + sNumEnabledPasses = TEV_MAX_PASSES; + for (int i = 0; i < TEV_MAX_PASSES; ++i) { + DeletePass(static_cast< ERglTevStage >(i)); + } + + for (int i = 0; i < TEV_MAX_PASSES; ++i) { + sValidPasses[i] = false; + } + RecomputePasses(); +} + +void CTevCombiners::DeletePass(int stage) { + SetPassCombiners(stage, kEnvPassthru); + sValidPasses[static_cast< size_t >(stage)] = false; + RecomputePasses(); +} + +void CTevCombiners::SetupPass(int stage, const CTevPass& pass) { + if (&pass == &kEnvPassthru) { + DeletePass(stage); + return; + } + if (SetPassCombiners(stage, pass)) { + sValidPasses[static_cast< size_t >(stage)] = true; + RecomputePasses(); + } +} + +bool CTevCombiners::SetPassCombiners(int stage, const CTevPass& pass) { + pass.Execute(stage); + return true; +} + +void CTevCombiners::CTevPass::Execute(int stage) const { + const GXTevStageID stageId = (GXTevStageID)(stage); + CGX::SetTevColorIn(stageId, (GXTevColorArg)x4_colorPass.GetA().GetSource(), + (GXTevColorArg)x4_colorPass.GetB().GetSource(), + (GXTevColorArg)x4_colorPass.GetC().GetSource(), + (GXTevColorArg)x4_colorPass.GetD().GetSource()); + CGX::SetTevAlphaIn(stageId, (GXTevAlphaArg)x14_alphaPass.GetA().GetSource(), + (GXTevAlphaArg)x14_alphaPass.GetB().GetSource(), + (GXTevAlphaArg)x14_alphaPass.GetC().GetSource(), + (GXTevAlphaArg)x14_alphaPass.GetD().GetSource()); + CGX::SetTevColorOp(stageId, (GXTevOp)x24_colorOp.GetOp(), (GXTevBias)x24_colorOp.GetBias(), + (GXTevScale)x24_colorOp.GetScale(), x24_colorOp.GetClamp(), + (GXTevRegID)x24_colorOp.GetOutput()); + CGX::SetTevAlphaOp(stageId, (GXTevOp)x38_alphaOp.GetOp(), (GXTevBias)x38_alphaOp.GetBias(), + (GXTevScale)x38_alphaOp.GetScale(), x38_alphaOp.GetClamp(), + (GXTevRegID)x38_alphaOp.GetOutput()); + CGX::SetTevKColorSel(stageId, GX_TEV_KCSEL_8_8); + CGX::SetTevKAlphaSel(stageId, GX_TEV_KASEL_8_8); +} + +void CTevCombiners::ResetStates() { + for (int i = 0; i < TEV_MAX_PASSES; ++i) { + sValidPasses[i] = false; + } + + kEnvPassthru.Execute(kTS_Stage0); + sNumEnabledPasses = 1; + CGX::SetNumTevStages(1); +}