mirror of
https://github.com/zeldaret/ss
synced 2026-07-03 20:40:09 -04:00
m2d (#22)
* m2d --------- Co-authored-by: elijah-thomas774 <elijahthomas774@gmail.com>
This commit is contained in:
+350
@@ -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
|
||||
Reference in New Issue
Block a user