From 22edfeae16eedf3d5c65f219212ff5bf2675ae66 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 16 Jun 2024 11:56:52 +0200 Subject: [PATCH 1/2] m_faders --- config/SOUE01/splits.txt | 12 +++++ config/SOUE01/symbols.txt | 34 ++++++------ configure.py | 3 ++ include/m/m_color.h | 35 +++++++++++++ include/m/m_color_fader.h | 21 ++++++++ include/m/m_fader.h | 18 +++++++ include/m/m_fader_base.h | 42 +++++++++++++++ src/m/m_color_fader.cpp | 105 ++++++++++++++++++++++++++++++++++++++ src/m/m_fader.cpp | 36 +++++++++++++ src/m/m_fader_base.cpp | 68 ++++++++++++++++++++++++ 10 files changed, 357 insertions(+), 17 deletions(-) create mode 100644 include/m/m_color.h create mode 100644 include/m/m_color_fader.h create mode 100644 include/m/m_fader_base.h create mode 100644 src/m/m_color_fader.cpp create mode 100644 src/m/m_fader.cpp create mode 100644 src/m/m_fader_base.cpp diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 6278d342..6546f185 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -276,6 +276,11 @@ m/m_angle.cpp: .ctors start:0x804DB8CC end:0x804DB8D0 .sbss start:0x80575C08 end:0x80575C10 +m/m_color_fader.cpp: + .text start:0x802EE7E0 end:0x802EEB94 + .data start:0x80542848 end:0x80542870 + .sdata2 start:0x8057CDC0 end:0x8057CDD8 + m/m_dvd.cpp: .text start:0x802EEBA0 end:0x802F0494 .ctors start:0x804DB8D0 end:0x804DB8D4 @@ -284,6 +289,13 @@ m/m_dvd.cpp: .sbss start:0x80575C10 end:0x80575C38 .bss start:0x805B85C0 end:0x805CB078 +m/m_fader.cpp: + .text start:0x802F04A0 end:0x802F061C + +m/m_fader_base.cpp: + .text start:0x802F0620 end:0x802F081C + .data start:0x80542968 end:0x80542990 + m/m_heap.cpp: .text start:0x802F0F00 end:0x802F1660 .rodata start:0x804F0570 end:0x804F0580 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 268e77c7..9d2774a3 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -17713,11 +17713,11 @@ allocOnHeap__16mHeapAllocator_cFUlP16mHeapAllocator_c = .text:0x802EE5D0; // typ step__4mAngFslss = .text:0x802EE5F0; // type:function size:0xA4 __sinit_\m_angle_cpp = .text:0x802EE6A0; // type:function size:0x18 scope:local fn_802EE6C0 = .text:0x802EE6C0; // type:function size:0x114 -fn_802EE7E0 = .text:0x802EE7E0; // type:function size:0x44 -fn_802EE830 = .text:0x802EE830; // type:function size:0x58 -fn_802EE890 = .text:0x802EE890; // type:function size:0x38 -fn_802EE8D0 = .text:0x802EE8D0; // type:function size:0xB0 -fn_802EE980 = .text:0x802EE980; // type:function size:0x214 +__ct__13mColorFader_cFRC6mColorQ212mFaderBase_c7EStatus = .text:0x802EE7E0; // type:function size:0x44 +__dt__13mColorFader_cFv = .text:0x802EE830; // type:function size:0x58 +setStatus__13mColorFader_cFQ212mFaderBase_c7EStatus = .text:0x802EE890; // type:function size:0x38 +calc__13mColorFader_cFv = .text:0x802EE8D0; // type:function size:0xB0 +draw__13mColorFader_cFv = .text:0x802EE980; // type:function size:0x214 __dt__Q24mDvd42TUncompressInfo_cFv = .text:0x802EEBA0; // type:function size:0x40 __dt__Q24mDvd41TUncompressInfo_cFv = .text:0x802EEBE0; // type:function size:0x40 __dt__Q24mDvd41TUncompressInfo_cFv = .text:0x802EEC20; // type:function size:0x40 @@ -17798,16 +17798,16 @@ Construct__Q24mDvd41TUncompressInfo_cCFv = .text:0x802F0 Destruct__Q24mDvd41TUncompressInfo_cCFv = .text:0x802F0440; // type:function size:0x4 Construct__Q24mDvd42TUncompressInfo_cCFv = .text:0x802F0450; // type:function size:0x3C Destruct__Q24mDvd42TUncompressInfo_cCFv = .text:0x802F0490; // type:function size:0x4 -fn_802F04A0 = .text:0x802F04A0; // type:function size:0x48 -fn_802F04F0 = .text:0x802F04F0; // type:function size:0x12C -fn_802F0620 = .text:0x802F0620; // type:function size:0x9C -fn_802F06C0 = .text:0x802F06C0; // type:function size:0x40 -fn_802F0700 = .text:0x802F0700; // type:function size:0x8 -fn_802F0710 = .text:0x802F0710; // type:function size:0x1C -fn_802F0730 = .text:0x802F0730; // type:function size:0x8 -fn_802F0740 = .text:0x802F0740; // type:function size:0x28 -fn_802F0770 = .text:0x802F0770; // type:function size:0x2C -fn_802F07A0 = .text:0x802F07A0; // type:function size:0x7C +draw__8mFader_cFv = .text:0x802F04A0; // type:function size:0x48 +setFader__8mFader_cFP12mFaderBase_c = .text:0x802F04F0; // type:function size:0x12C +__ct__12mFaderBase_cFRC6mColorQ212mFaderBase_c7EStatus = .text:0x802F0620; // type:function size:0x9C +__dt__12mFaderBase_cFv = .text:0x802F06C0; // type:function size:0x40 +setFrame__12mFaderBase_cFUs = .text:0x802F0700; // type:function size:0x8 +setColor__12mFaderBase_cFRC6mColor = .text:0x802F0710; // type:function size:0x1C +getStatus__12mFaderBase_cCFv = .text:0x802F0730; // type:function size:0x8 +fadeIn__12mFaderBase_cFv = .text:0x802F0740; // type:function size:0x28 +fadeOut__12mFaderBase_cFv = .text:0x802F0770; // type:function size:0x2C +calc__12mFaderBase_cFv = .text:0x802F07A0; // type:function size:0x7C fn_802F0820 = .text:0x802F0820; // type:function size:0xB8 fn_802F08E0 = .text:0x802F08E0; // type:function size:0x370 fn_802F0C50 = .text:0x802F0C50; // type:function size:0x160 @@ -35714,7 +35714,7 @@ lbl_805427E0 = .data:0x805427E0; // type:object size:0x10 lbl_805427F0 = .data:0x805427F0; // type:object size:0x30 __vt__16mHeapAllocator_c = .data:0x80542820; // type:object size:0x14 __vt__12mAllocator_c = .data:0x80542834; // type:object size:0x14 -lbl_80542848 = .data:0x80542848; // type:object size:0x28 +__vt__13mColorFader_c = .data:0x80542848; // type:object size:0x24 __vt__Q24mDvd10MyThread_c = .data:0x80542870; // type:object size:0x18 __vt__23mDvd_toMainRam_normal_c = .data:0x80542888; // type:object size:0x14 __vt__20mDvd_toMainRam_arc_c = .data:0x8054289C; // type:object size:0x14 @@ -35727,7 +35727,7 @@ __vt__Q24mDvd42TUncompressInfo_c = .data:0x80542914; // __vt__Q24mDvd41TUncompressInfo_c = .data:0x80542928; // type:object size:0x14 __vt__Q24mDvd41TUncompressInfo_c = .data:0x8054293C; // type:object size:0x14 __vt__Q24mDvd42TUncompressInfo_c = .data:0x80542950; // type:object size:0x14 -lbl_80542968 = .data:0x80542968; // type:object size:0x28 +__vt__12mFaderBase_c = .data:0x80542968; // type:object size:0x24 lbl_80542990 = .data:0x80542990; // type:object size:0x29 lbl_805429BC = .data:0x805429BC; // type:object size:0x29 lbl_805429E8 = .data:0x805429E8; // type:object size:0x31 diff --git a/configure.py b/configure.py index e963e0fa..9cf6553a 100644 --- a/configure.py +++ b/configure.py @@ -314,7 +314,10 @@ def nw4rLib(lib_name, objects, extra_cflags=[]): Object(Matching, "f/f_manager.cpp"), Object(Matching, "m/m_allocator.cpp"), Object(Matching, "m/m_angle.cpp"), + Object(Matching, "m/m_color_fader.cpp"), Object(Matching, "m/m_dvd.cpp"), + Object(Matching, "m/m_fader.cpp"), + Object(Matching, "m/m_fader_base.cpp"), Object(Matching, "m/m_heap.cpp"), Object(NonMatching, "m/m_mtx.cpp"), Object(Matching, "m/m_pad.cpp"), diff --git a/include/m/m_color.h b/include/m/m_color.h new file mode 100644 index 00000000..e090baa1 --- /dev/null +++ b/include/m/m_color.h @@ -0,0 +1,35 @@ +#ifndef M_COLOR_H +#define M_COLOR_H + +#include + +struct mColor { + mColor() { + rgba = 0xFFFFFFFF; + } + mColor(u8 red, u8 green, u8 blue, u8 alpha) { + r = red; + g = green; + b = blue; + a = alpha; + } + mColor(u32 color) { + rgba = color; + } + + // The alternative is that GXColor is a union and this extends GXColor? + operator GXColor &() { + return reinterpret_cast(*this); + } + + union { + struct { + u8 r; + u8 g; + u8 b; + u8 a; + }; + u32 rgba; + }; +}; +#endif diff --git a/include/m/m_color_fader.h b/include/m/m_color_fader.h new file mode 100644 index 00000000..f0c4eca4 --- /dev/null +++ b/include/m/m_color_fader.h @@ -0,0 +1,21 @@ +#ifndef M_COLOR_FADER_H +#define M_COLOR_FADER_H + +#include +#include +#include + + +class mColorFader_c : public mFaderBase_c { +public: + mColorFader_c(const mColor &color, EStatus status); + virtual ~mColorFader_c(); + + virtual void setStatus(EStatus status) override; + virtual u8 calc() override; + virtual void draw() override; + + u8 mAspectRatio; +}; + +#endif diff --git a/include/m/m_fader.h b/include/m/m_fader.h index e69de29b..83967dc4 100644 --- a/include/m/m_fader.h +++ b/include/m/m_fader.h @@ -0,0 +1,18 @@ +#ifndef M_FADER_H +#define M_FADER_H + +#include + +class mFader_c { +public: + void draw(); + bool setFader(mFaderBase_c *fader); + + bool isStatus(mFaderBase_c::EStatus status) { + return mpFader->getStatus() == status; + } + + mFaderBase_c *mpFader; +}; + +#endif diff --git a/include/m/m_fader_base.h b/include/m/m_fader_base.h new file mode 100644 index 00000000..f6feb043 --- /dev/null +++ b/include/m/m_fader_base.h @@ -0,0 +1,42 @@ +#ifndef M_FADER_BASE_H +#define M_FADER_BASE_H + +#include +#include + + +class mFaderBase_c { +public: + enum EStatus { + FADED_OUT = 0, + FADED_IN = 1, + FADING_IN = 2, + FADING_OUT = 3, + }; + + enum EFlag { + FLAG_1 = 1, + FLAG_2 = 2, + }; + + mFaderBase_c(const mColor &color, EStatus status); + virtual ~mFaderBase_c(); + + virtual void setStatus(EStatus status) = 0; + virtual EStatus getStatus() const; + virtual bool fadeIn(); + virtual bool fadeOut(); + virtual u8 calc(); + virtual void draw() = 0; + + void setFrame(u16 frame); + void setColor(const mColor &color); + + EStatus mStatus; + u8 mFlag; + u16 mFrame; + u16 mElapsed; + mColor mFaderColor; +}; + +#endif diff --git a/src/m/m_color_fader.cpp b/src/m/m_color_fader.cpp new file mode 100644 index 00000000..66a03b35 --- /dev/null +++ b/src/m/m_color_fader.cpp @@ -0,0 +1,105 @@ +#include +#include +#include + +mColorFader_c::mColorFader_c(const mColor &color, EStatus status) : mFaderBase_c(color, status) { + mAspectRatio = SCGetAspectRatio(); +} + +mColorFader_c::~mColorFader_c() {} + +void mColorFader_c::setStatus(EStatus status) { + if (status == FADED_OUT) { + mStatus = FADED_OUT; + mFaderColor.a = 0xff; + } else if (status == FADED_IN) { + mStatus = FADED_IN; + mFaderColor.a = 0; + } +} + +u8 mColorFader_c::calc() { + u8 result = mFaderBase_c::calc(); + u16 elapsed = mElapsed; + u16 frame = mFrame; + if (elapsed > mFrame) { + elapsed = frame; + } + + switch (mStatus) { + case FADED_IN: + mFaderColor.a = 0; + break; + case FADED_OUT: + mFaderColor.a = 0xff; + break; + case FADING_IN: + mFaderColor.a = 0xff - (elapsed * 0xff / frame); + break; + case FADING_OUT: + mFaderColor.a = elapsed * 0xff / frame; + break; + } + + + return result; +} + +#define VI_VIRTUAL_HALF_WIDTH_WIDE (406.0f) +#define VI_VIRTUAL_HALF_WIDTH_STD (304.0f) +#define VI_VIRTUAL_HALF_HEIGHT (228.0f) + +void mColorFader_c::draw() { + f32 h = (mAspectRatio == 1) ? VI_VIRTUAL_HALF_WIDTH_WIDE : VI_VIRTUAL_HALF_WIDTH_STD; + + if (mFaderColor.a == 0) { + return; + } + + Mtx44 projMtx; + C_MTXOrtho(projMtx, -VI_VIRTUAL_HALF_HEIGHT, VI_VIRTUAL_HALF_HEIGHT, -h, h, 0, 1); + GXSetProjection(projMtx, GX_ORTHOGRAPHIC); + + Mtx posMtx; + PSMTXIdentity(posMtx); + GXLoadPosMtxImm(posMtx, 0); + GXSetCurrentMtx(0); + + GXClearVtxDesc(); + GXInvalidateVtxCache(); + + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0); + + GXSetNumChans(1); + GXSetChanMatColor(GX_COLOR0A0, mFaderColor); + GXSetChanCtrl(GX_COLOR0A0, 0, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + + GXSetNumTexGens(0); + GXSetNumIndStages(0); + __GXSetIndirectMask(0); + + GXSetNumTevStages(1); + GXSetTevOp(GX_TEVSTAGE0, 4); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + + if (mFaderColor.a == 255) { + GXSetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_SET); + } else { + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); + } + + GXSetColorUpdate(1); + GXSetAlphaUpdate(1); + GXSetZMode(0, GX_NEVER, 0); + GXSetCullMode(GX_CULL_BACK); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + + GXPosition3f32(-h, -VI_VIRTUAL_HALF_HEIGHT, 0); + GXPosition3f32(h, -VI_VIRTUAL_HALF_HEIGHT, 0); + GXPosition3f32(h, VI_VIRTUAL_HALF_HEIGHT, 0); + GXPosition3f32(-h, VI_VIRTUAL_HALF_HEIGHT, 0); + + // GXEnd(); +} diff --git a/src/m/m_fader.cpp b/src/m/m_fader.cpp new file mode 100644 index 00000000..8f88a4ab --- /dev/null +++ b/src/m/m_fader.cpp @@ -0,0 +1,36 @@ +#include + +// nw4r::g3d::G3DState::Invalidate +extern "C" void fn_8044E3B0(u32 flags); +// m3d::resetMaterial according to NSMBW +extern "C" void fn_802E46D0(); + +void mFader_c::draw() { + fn_8044E3B0(0x7ff); + fn_802E46D0(); + mpFader->draw(); +} + +bool mFader_c::setFader(mFaderBase_c *fader) { + if (mpFader != nullptr) { + bool isFading = isStatus(mFaderBase_c::FADING_IN) || isStatus(mFaderBase_c::FADING_OUT); + + if (isFading) { + return false; + } + } + + mFaderBase_c::EStatus status = mpFader != nullptr ? mpFader->getStatus() : fader->getStatus(); + + mpFader = fader; + switch (status) { + case mFaderBase_c::FADED_OUT: + fader->setStatus(mFaderBase_c::FADED_OUT); + break; + case mFaderBase_c::FADED_IN: + fader->setStatus(mFaderBase_c::FADED_IN); + break; + } + + return true; +} diff --git a/src/m/m_fader_base.cpp b/src/m/m_fader_base.cpp new file mode 100644 index 00000000..ae5c182b --- /dev/null +++ b/src/m/m_fader_base.cpp @@ -0,0 +1,68 @@ +#include + +mFaderBase_c::mFaderBase_c(const mColor &color, EStatus status) : mFlag(0), mFrame(20), mElapsed(0) { + setColor(color); + mFlag |= FLAG_2; + + switch (status) { + case FADED_OUT: + mStatus = FADED_OUT; + break; + case FADED_IN: + mStatus = FADED_IN; + break; + } +} + +mFaderBase_c::~mFaderBase_c() {} + +void mFaderBase_c::setFrame(u16 frame) { + mFrame = frame; +} + +void mFaderBase_c::setColor(const mColor &newColor) { + mFaderColor.r = newColor.r; + mFaderColor.g = newColor.g; + mFaderColor.b = newColor.b; +} + +mFaderBase_c::EStatus mFaderBase_c::getStatus() const { + return mStatus; +} + +bool mFaderBase_c::fadeIn() { + bool canFadeIn = mStatus == FADED_OUT; + if (canFadeIn) { + mStatus = FADING_IN; + mElapsed = 0; + } + + return canFadeIn; +} + +bool mFaderBase_c::fadeOut() { + bool canFadeOut = mStatus == FADED_IN; + if (canFadeOut) { + mStatus = FADING_OUT; + mElapsed = 0; + } + + return canFadeOut; +} + +u8 mFaderBase_c::calc() { + u8 result = 0; + if (mStatus == FADING_IN) { + if (mElapsed++ > mFrame) { + mStatus = FADED_IN; + result = (mFlag & FLAG_1) != 0; + } + } else if (mStatus == FADING_OUT) { + if (++mElapsed > mFrame + 1) { + mStatus = FADED_OUT; + result = (mFlag & FLAG_2) != 0; + } + } + + return result; +} From e296019657b4edd227f85ff50c37061df4e35741 Mon Sep 17 00:00:00 2001 From: robojumper Date: Wed, 26 Jun 2024 20:08:59 +0200 Subject: [PATCH 2/2] mColor can extend ut::Color --- include/m/m_color.h | 30 ++---------------------------- include/nw4r/ut/ut_Color.h | 2 +- 2 files changed, 3 insertions(+), 29 deletions(-) diff --git a/include/m/m_color.h b/include/m/m_color.h index e090baa1..a5ce85b8 100644 --- a/include/m/m_color.h +++ b/include/m/m_color.h @@ -1,35 +1,9 @@ #ifndef M_COLOR_H #define M_COLOR_H +#include #include -struct mColor { - mColor() { - rgba = 0xFFFFFFFF; - } - mColor(u8 red, u8 green, u8 blue, u8 alpha) { - r = red; - g = green; - b = blue; - a = alpha; - } - mColor(u32 color) { - rgba = color; - } +struct mColor : public nw4r::ut::Color {}; - // The alternative is that GXColor is a union and this extends GXColor? - operator GXColor &() { - return reinterpret_cast(*this); - } - - union { - struct { - u8 r; - u8 g; - u8 b; - u8 a; - }; - u32 rgba; - }; -}; #endif diff --git a/include/nw4r/ut/ut_Color.h b/include/nw4r/ut/ut_Color.h index 77b63b36..5f3374c3 100644 --- a/include/nw4r/ut/ut_Color.h +++ b/include/nw4r/ut/ut_Color.h @@ -60,7 +60,7 @@ class Color : public GXColor { operator u32() const { return ToU32ref(); } -}; +} ALIGN(4); } // namespace ut } // namespace nw4r