diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 5edab8fa..fe294296 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -280,6 +280,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 @@ -288,6 +293,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 68118cae..99db08ad 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 @@ -35717,7 +35717,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 @@ -35730,7 +35730,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 68f6fb0b..8c85ecd1 100644 --- a/configure.py +++ b/configure.py @@ -337,7 +337,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..a5ce85b8 --- /dev/null +++ b/include/m/m_color.h @@ -0,0 +1,9 @@ +#ifndef M_COLOR_H +#define M_COLOR_H + +#include +#include + +struct mColor : public nw4r::ut::Color {}; + +#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/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 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; +}