diff options
| author | robojumper <robojumper@gmail.com> | 2024-09-13 04:01:40 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-09-12 22:01:40 -0400 |
| commit | 5aa30927fff8abeca36cbecddec3f77935477046 (patch) | |
| tree | 6578959f3ce60ce878421b3233372c5abed60819 /src/m/m2d.cpp | |
| parent | 3d0adbc87458679420263f1d8e496465e1eddb34 (diff) | |
m2d (#22)
* m2d
---------
Co-authored-by: elijah-thomas774 <elijahthomas774@gmail.com>
Diffstat (limited to 'src/m/m2d.cpp')
| -rw-r--r-- | src/m/m2d.cpp | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/src/m/m2d.cpp b/src/m/m2d.cpp new file mode 100644 index 00000000..dab95700 --- /dev/null +++ b/src/m/m2d.cpp @@ -0,0 +1,350 @@ +#include <egg/core/eggExpHeap.h> +#include <egg/core/eggHeap.h> +#include <egg/gfx/eggScreen.h> + +#include <m/m2d.h> + +#include <rvl/GX.h> +#include <rvl/SC.h> + +namespace m2d { + +nw4r::ut::List l_list; +mAllocator_c *l_allocator; + +void reset() { + nw4r::ut::List_Init(&l_list, 0); +} + +bool init(mAllocator_c *allocator) { + nw4r::lyt::LytInit(); + l_allocator = allocator; + nw4r::lyt::Layout::mspAllocator = allocator; + reset(); + return true; +} + +void create(EGG::Heap *heap, u32 size) { + if (size != 0) { + heap = EGG::ExpHeap::create(size, heap, 0); + // Supposed to be 2D表示用ヒープ(m2d::create), but creates a linux compile issue + heap->setName("2D\x95\x5C示用ヒープ(m2d::create)"); + } + mAllocator_c *allocator = new (heap, 0x04) mAllocator_c(); + allocator->attach(heap, 4); + init(allocator); +} + +// TODO This is literally the first sbss2 symbol. +extern "C" GXColor lbl_8057FFA0; + +void defaultSet() { + GXSetCullMode(GX_CULL_NONE); + GXSetZMode(false, GX_ALWAYS, false); + GXSetFog(GX_FOG_NONE, lbl_8057FFA0, 0.0f, 0.0f, 0.0f, 0.0f); +} + +void draw(u8 priority) { + for (Base_c *base = static_cast<Base_c *>(nw4r::ut::List_GetFirst(&l_list)); base != nullptr; + base = static_cast<Base_c *>(nw4r::ut::List_GetNext(&l_list, base))) { + if (base->mPriority >= priority) { + break; + } + base->draw(); + } +} + +void drawBefore(u8 priority) { + for (Base_c *base = static_cast<Base_c *>(nw4r::ut::List_GetFirst(&l_list)); base != nullptr; + base = static_cast<Base_c *>(nw4r::ut::List_GetNext(&l_list, base))) { + if (base->mPriority > priority) { + base->draw(); + } + } +} + +// Despite the name this *updates* Lyt's allocator +void getAllocator() { + nw4r::lyt::Layout::mspAllocator = l_allocator; +} + +nw4r::lyt::AnimTransform *Layout_c::CreateAnimTransform(const void *animResBuf, nw4r::lyt::ResourceAccessor *pResAcsr) { + nw4r::lyt::AnimTransform *result = nw4r::lyt::Layout::CreateAnimTransform(animResBuf, pResAcsr); + if (result != nullptr) { + GetAnimTransformList().Erase(result); + } + return result; +} + +ResAccIfBase_c::~ResAccIfBase_c() {} +ResAccIf_c::~ResAccIf_c() {} + +nw4r::lyt::ArcResourceAccessor *ResAccIf_c::getAccessor() { + return &mAccessor; +} + +void ResAccIf_c::noop() {} + +void ResAccIf_c::attach(void *data, const char *name) { + mAccessor.Attach(data, name); +} +void ResAccIf_c::detach() { + mAccessor.Detach(); +} + +FrameCtrl_c::~FrameCtrl_c() {} + +void FrameCtrl_c::play() { + mPrevFrame = mCurrFrame; + f32 newFrame; + if (isBackwards()) { + if (mCurrFrame >= mRate) { + newFrame = mCurrFrame - mRate; + } else { + if (notLooping()) { + newFrame = 0.0f; + } else { + newFrame = mCurrFrame + (mEndFrame - mRate); + } + } + } else { + newFrame = mCurrFrame + mRate; + if (notLooping()) { + f32 forwardsEnd = mEndFrame - 1.0f; + if (newFrame > forwardsEnd) { + newFrame = forwardsEnd; + } + } else { + if (newFrame >= mEndFrame) { + newFrame = newFrame - mEndFrame; + } + } + } + + mCurrFrame = newFrame; +} + +void FrameCtrl_c::set(f32 endFrame, u8 flags, f32 rate, f32 currFrame) { + if (currFrame < 0.0f) { + currFrame = 0.0f; + } + mEndFrame = endFrame; + mCurrFrame = currFrame; + setRate(rate); + mFlags = flags; + mPrevFrame = mCurrFrame; +} + +void FrameCtrl_c::setFrame(f32 frame) { + mCurrFrame = frame; + mPrevFrame = frame; +} + +void FrameCtrl_c::setRate(f32 rate) { + mRate = rate; +} + +bool FrameCtrl_c::isStop() const { + f32 actualEnd; + switch (mFlags) { + case FLAG_NO_LOOP: + actualEnd = mEndFrame - 1.0f; + return mCurrFrame >= actualEnd; + case FLAG_NO_LOOP | FLAG_BACKWARDS: + return mCurrFrame <= 0; + default: + return false; + } +} + +f32 FrameCtrl_c::getEndFrame() const { + if (isBackwards()) { + if (notLooping()) { + return mEndFrame - 1.0f; + } + return mEndFrame; + } + + return 0.0f; +} + +f32 FrameCtrl_c::getEndFrame2() const { + if (isBackwards()) { + return 0.0f; + } + if (notLooping()) { + return mEndFrame - 1.0f; + } + return mEndFrame; +} + +bool FrameCtrl_c::isStop2() const { + if (isBackwards()) { + return mCurrFrame <= 0.0f; + } + if (notLooping()) { + f32 actualEnd = mEndFrame - 1.0f; + return mCurrFrame >= actualEnd; + } + return mCurrFrame >= mEndFrame; +} + +Anm_c::~Anm_c() { + destroySomething(); +} + +bool Anm_c::doSomething(const char *path, ResAccIf_c *acc) { + if (mpTransform != nullptr) { + destroySomething(); + } + + static Layout_c l_layout; + + void *resource = acc->getAccessor()->GetResource(0, path, nullptr); + nw4r::lyt::AnimTransform *transform = l_layout.CreateAnimTransform(resource, acc->getAccessor()); + if (transform == nullptr) { + return false; + } + + setTransform(transform); + return true; +} + +void Anm_c::setTransform(nw4r::lyt::AnimTransform *transform) { + mpTransform = transform; + u8 flags = 1; + if (mpTransform->IsLoopData()) { + flags = 0; + } + set(mpTransform->GetFrameSize(), flags, 1.0f, -1.0); +} + +void Anm_c::destroySomething() { + if (mpTransform != nullptr) { + mpTransform->~AnimTransform(); + nw4r::lyt::Layout::FreeMemory(mpTransform); + mpTransform = nullptr; + } +} + +void Anm_c::set(f32 endFrame, u8 flags, f32 rate, f32 currFrame) { + mFrameCtrl.set(endFrame, flags, rate, currFrame); + updateFrame(); +} + +void Anm_c::setFrame(f32 frame) { + mFrameCtrl.setFrame(frame); + updateFrame(); +} + +void Anm_c::updateFrame() { + mpTransform->SetFrame(mFrameCtrl.getFrame()); +} + +void Anm_c::play() { + mFrameCtrl.play(); + updateFrame(); +} + +Base_c::~Base_c() {} +void Base_c::draw() {} + +void Base_c::addToDrawList() { + Base_c *target = static_cast<Base_c *>(nw4r::ut::List_GetFirst(&l_list)); + while (target != nullptr) { + if (target->mPriority > mPriority) { + nw4r::ut::List_Insert(&l_list, target, this); + return; + } + + target = static_cast<Base_c *>(nw4r::ut::List_GetNext(&l_list, target)); + } + nw4r::ut::List_Append(&l_list, this); +} + +Simple_c::~Simple_c() {} +Simple_c::Simple_c() : Base_c(0x80), mLayout(), mDrawInfo(), mpResAcc(nullptr), mVec(0.0f, 0.0f, 0.0f), field_0x94(0) { + if (SCGetAspectRatio() == 1) { + mDrawInfo.SetLocationAdjustScale(nw4r::math::VEC2(EGG::Screen::GetAdjustScale(), 1.0f)); + mDrawInfo.SetLocationAdjust(true); + } +} + +void Simple_c::calc() { + calcBefore(); + nw4r::math::MTX34 mtx; + PSMTXIdentity(mtx.m); + // Probably inlines + mVec3_c v = mVec; + PSMTXTransApply(mtx.m, mtx.m, v.x, v.y, v.z); + mDrawInfo.SetViewMtx(mtx); + calcAfter(); +} + +void Simple_c::calcBefore() { + u32 flag = 0; + if ((field_0x94 & 1) != 0) { + flag = 1; + } + mLayout.Animate(flag); +} + +void Simple_c::calcAfter() { + mDrawInfo.SetViewRect(mLayout.GetLayoutRect()); + mLayout.CalculateMtx(mDrawInfo); +} + +void Simple_c::draw() { + nw4r::ut::Rect r = mLayout.GetLayoutRect(); + f32 near = 0.0f; + f32 far = 500.0f; + EGG::Screen s; + bool needsAdjust = EGG::Screen::GetTVMode() == EGG::Screen::TV_MODE_2; + f32 f1 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_2); + f32 f2 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_1); + + f32 left = needsAdjust ? f1 * r.left / f2 : r.left; + f32 right = needsAdjust ? f1 * r.right / f2 : r.right; + s.SetProjectionType(EGG::Frustum::PROJ_ORTHO); + s.ResetOrthographic(r.top, r.bottom, left, right, near, far); + if (needsAdjust) { + s.SetScale(nw4r::math::VEC3(f2 / f1, 1.0f, 1.0f)); + } + s.SetProjectionGX(); + mLayout.Draw(mDrawInfo); +} + +bool Simple_c::build(const char *name, ResAccIf_c *acc) { + if (mLayout.GetRootPane() != nullptr) { + return true; + } + if (acc == nullptr) { + acc = mpResAcc; + if (acc == nullptr) { + return false; + } + } + + void *resource = acc->getAccessor()->GetResource(0, name, nullptr); + if (resource == nullptr) { + return false; + } else { + bool success = mLayout.Build(resource, acc->getAccessor()); + if (success) { + calc(); + } + return success; + } +} + +void Simple_c::bind(Anm_c *anm) { + anm->setBound(); + mLayout.BindAnimation(anm->getTransform()); +} + +void Simple_c::unbind(Anm_c *anm) { + anm->setUnbound(); + mLayout.UnbindAnimation(anm->getTransform()); +} + +} // namespace m2d |
