* Initial M3d Pass
* `m_bmdl` and `m_bline` left

---------

Co-authored-by: elijah-thomas774 <elijahthomas774@gmail.com>
Co-authored-by: Elijah Thomas <42302100+elijah-thomas774@users.noreply.github.com>
This commit is contained in:
robojumper
2024-09-12 22:36:34 +02:00
committed by GitHub
parent e2c4bb7be7
commit 1180e1f486
150 changed files with 5890 additions and 818 deletions
+281
View File
@@ -0,0 +1,281 @@
#include <egg/gfx/eggDrawGX.h>
#include <egg/gfx/eggGfxEngine.h>
#include <egg/gfx/eggScreen.h>
#include <egg/gfx/eggStateGX.h>
#include <nw4r/g3d/g3d_camera.h>
#include <nw4r/g3d/g3d_init.h>
#include <nw4r/g3d/g3d_resmat.h>
#include <nw4r/g3d/g3d_resmdl.h>
#include <nw4r/g3d/g3d_state.h>
#include <m/m3d/m3d.h>
#include <m/m_heap.h>
#include <m/m_video.h>
#include <rvl/GX.h>
namespace m3d {
namespace internal {
mAllocator_c *l_allocator_p;
nw4r::g3d::ScnRoot *l_scnRoot_p;
u32 l_numLightMgr;
EGG::LightManager **l_lightMgr_pp;
u32 l_numFogMgr;
EGG::FogManager **l_fogMgr_pp;
size_t l_alignment;
} // namespace internal
bool create(EGG::Heap *pHeap, u32 maxNumChildren, u32 maxNumScnObj, u32 numLightObj, u32 numLightSet) {
internal::l_allocator_p = new (pHeap) mAllocator_c();
if (!internal::l_allocator_p) {
return false;
}
internal::l_allocator_p->attach(pHeap, 0x20);
nw4r::g3d::G3dInit(true);
nw4r::g3d::G3DState::SetRenderModeObj(*mVideo::m_video->pRenderMode);
u32 allocedSize;
internal::l_scnRoot_p = nw4r::g3d::ScnRoot::Construct(internal::l_allocator_p, &allocedSize, maxNumChildren,
maxNumScnObj, numLightObj, numLightSet);
if (internal::l_scnRoot_p == nullptr) {
delete internal::l_allocator_p;
internal::l_allocator_p = nullptr;
return false;
}
return true;
}
bool create(EGG::Heap *pHeap, GXPixelFmt pxlFmt, GXColor clearColor, u32 maxNumChildren, u32 maxNumScnObj,
u32 numLightObj, u32 numLightSet, u32 numLightMgr, u32 numFogMgr) {
if (internal::l_lightMgr_pp && internal::l_fogMgr_pp) {
return false;
}
EGG::GfxEngine::Configuration config = EGG::GfxEngine::Configuration();
u16 temp1[2] = {config.field_0x14, config.field_0x16};
u16 temp2[2] = {config.efbHeight, config.efbHeight};
EGG::StateGX::initialize(config.efbWidth, config.efbHeight, clearColor, pxlFmt);
EGG::Screen::Initialize(temp1, temp2, nullptr);
EGG::Screen::SetTVModeDefault();
EGG::DrawGX::Initialize(pHeap);
EGG::LightTexture::initialize(0x20, pHeap);
internal::l_lightMgr_pp = new (pHeap) EGG::LightManager *[numLightMgr];
if (internal::l_lightMgr_pp) {
internal::l_numLightMgr = numLightMgr;
internal::l_fogMgr_pp = new (pHeap) EGG::FogManager *[numFogMgr];
if (internal::l_fogMgr_pp) {
internal::l_numFogMgr = numFogMgr;
memset(internal::l_lightMgr_pp, 0, numLightMgr * 4);
memset(internal::l_fogMgr_pp, 0, numFogMgr * 4);
if (create(pHeap, maxNumChildren, maxNumScnObj, numLightObj, numLightSet)) {
return true;
}
}
}
// Creation failed :(
delete[] internal::l_lightMgr_pp;
internal::l_lightMgr_pp = nullptr;
delete[] internal::l_fogMgr_pp;
internal::l_fogMgr_pp = nullptr;
return false;
}
bool createLightMgr(EGG::Heap *pHeap, u16 p2, u16 p3, u8 p4, bool bCreateFogMgr, int idx) {
using namespace internal;
if (!l_lightMgr_pp || (idx < 0 || idx >= l_numLightMgr || idx >= l_numFogMgr) ||
(l_lightMgr_pp[idx] || l_fogMgr_pp[idx])) {
return false;
}
EGG::Heap *prevHeap = mHeap::setCurrentHeap(pHeap);
EGG::LightManager *lightMgr = new (pHeap) EGG::LightManager(p2, p3, p4);
mHeap::setCurrentHeap(prevHeap);
if (lightMgr) {
if (!bCreateFogMgr || createFogMgr(pHeap, 0x20, idx)) {
l_lightMgr_pp[idx] = lightMgr;
return true;
}
}
delete lightMgr;
return false;
u8 input;
u8 *output;
switch (input % 8) {
do {
case 0:
*output++ = input;
case 1:
*output++ = input;
case 2:
*output++ = input;
} while (true);
}
}
bool createFogMgr(EGG::Heap *pHeap, int numFog, int idx) {
using namespace internal;
if (idx < 0 || idx >= l_numFogMgr || l_fogMgr_pp[idx]) {
return false;
}
EGG::FogManager *fogMgr;
{
mHeap heap(pHeap);
fogMgr = new (pHeap) EGG::FogManager(numFog);
}
if (!fogMgr) {
return false;
}
l_fogMgr_pp[idx] = fogMgr;
return true;
}
nw4r::g3d::ScnRoot *getScnRoot() {
return internal::l_scnRoot_p;
}
nw4r::g3d::Camera getCamera(int id) {
return internal::l_scnRoot_p->GetCamera(id);
}
nw4r::g3d::Camera getCurrentCamera() {
return internal::l_scnRoot_p->GetCurrentCamera();
}
int getCurrentCameraID() {
return internal::l_scnRoot_p->GetCurrentCameraID();
}
void setCurrentCamera(int id) {
internal::l_scnRoot_p->SetCurrentCamera(id);
}
nw4r::g3d::LightSetting *getLightSettingP() {
return internal::l_scnRoot_p->getLightSetting();
}
EGG::LightManager *getLightMgr(int idx) {
return internal::l_lightMgr_pp[idx];
}
EGG::FogManager *getFogMgr(int idx) {
return internal::l_fogMgr_pp[idx];
}
void drawDone(int idx) {
if (internal::l_lightMgr_pp && internal::l_lightMgr_pp[idx]) {
internal::l_lightMgr_pp[idx]->DoneDraw();
}
if (internal::l_fogMgr_pp && internal::l_fogMgr_pp[idx]) {
internal::l_fogMgr_pp[idx]->mFlag &= 0xFB;
}
}
void drawLightMapTexture(int idx) {
using namespace internal;
if (!l_lightMgr_pp) {
return;
}
if (!l_lightMgr_pp[idx]) {
return;
}
l_lightMgr_pp[idx]->GetTextureMgr()->drawAndCaptureTexture(0.0f, 0.0f, 0.0f, 0.0f);
}
void calcWorld(int idx) {
if (internal::l_lightMgr_pp && internal::l_lightMgr_pp[idx]) {
internal::l_lightMgr_pp[idx]->Calc(internal::l_scnRoot_p);
}
if (internal::l_fogMgr_pp && internal::l_fogMgr_pp[idx]) {
internal::l_fogMgr_pp[idx]->Calc();
}
internal::l_scnRoot_p->CalcWorld();
}
void calcMaterial() {
internal::l_scnRoot_p->CalcMaterial();
}
void calcView(int idx) {
if (internal::l_lightMgr_pp && internal::l_lightMgr_pp[idx]) {
nw4r::math::MTX34 camMtx;
getCurrentCamera().GetCameraMtx(&camMtx);
internal::l_lightMgr_pp[idx]->CalcView(camMtx, getCurrentCameraID(), internal::l_scnRoot_p);
}
if (internal::l_fogMgr_pp && internal::l_fogMgr_pp[idx]) {
internal::l_fogMgr_pp[idx]->CopyToG3D(internal::l_scnRoot_p);
}
internal::l_scnRoot_p->CalcView();
internal::l_scnRoot_p->GatherDrawScnObj();
internal::l_scnRoot_p->ZSort();
}
void drawOpa() {
internal::l_scnRoot_p->DrawOpa();
}
void drawXlu() {
internal::l_scnRoot_p->DrawXlu();
}
bool pushBack(nw4r::g3d::ScnObj *obj) {
return internal::l_scnRoot_p->PushBack(obj);
}
void clear() {
internal::l_scnRoot_p->Clear();
}
void reset() {
nw4r::g3d::G3dReset();
if (internal::l_lightMgr_pp || internal::l_fogMgr_pp) {
EGG::StateGX::resetGXCache();
}
}
int getMatID(nw4r::g3d::ResMdl mdl, const char *name) {
if (mdl.IsValid()) {
nw4r::g3d::ResMat mat = mdl.GetResMat(name);
if (mat.IsValid()) {
return mat.ref().id;
}
}
return -1;
}
int getNodeID(nw4r::g3d::ResMdl mdl, const char *name) {
if (mdl.IsValid()) {
nw4r::g3d::ResNode node = mdl.GetResNode(name);
if (node.IsValid()) {
return node.GetID();
}
}
return -1;
}
void resetMaterial() {
GXSetNumIndStages(0);
for (int i = GX_TEVSTAGE0; i < GX_MAX_TEVSTAGE; i++) {
GXSetTevDirect((GXTevStageID)i);
}
}
} // namespace m3d
+82
View File
@@ -0,0 +1,82 @@
#include <m/m3d/m3d.h>
#include <m/m3d/m_anmchr.h>
#include <nw4r/g3d/g3d_anmchr.h>
#include <nw4r/g3d/g3d_resanmchr.h>
namespace m3d {
anmChr_c::~anmChr_c() {}
int anmChr_c::getType() const {
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_CHR;
}
bool anmChr_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmChr anm, mAllocator_c *alloc, u32 *pSize) {
if (alloc == nullptr) {
alloc = internal::l_allocator_p;
}
u32 size;
if (pSize == nullptr) {
pSize = &size;
}
nw4r::g3d::AnmObjChrRes::Construct(nullptr, pSize, anm, mdl, false);
if (!createAllocator(alloc, pSize)) {
return false;
}
mpAnmObj = nw4r::g3d::AnmObjChrRes::Construct(&mAllocator, &size, anm, mdl, false);
if (!mpAnmObj->Bind(mdl)) {
remove();
return false;
}
setFrmCtrlDefault(anm, PLAY_MODE_4);
return true;
}
void anmChr_c::setAnm(bmdl_c &mdl, nw4r::g3d::ResAnmChr anm, playMode_e mode) {
mdl.removeAnm((nw4r::g3d::ScnMdlSimple::AnmObjType)getType());
setAnmAfter(mdl, anm, mode);
}
void anmChr_c::setAnmAfter(bmdl_c &mdl, nw4r::g3d::ResAnmChr anm, playMode_e mode) {
nw4r::g3d::AnmObjChrNode *node;
nw4r::g3d::G3dObj *parent = mpAnmObj->GetParent();
f32 weight;
int idx;
if (parent != nullptr) {
node = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjChrNode>(parent);
int size = node->Size();
idx = 0;
for (int i = 0; i < size; i++, idx++) {
if (node->GetNode(i) == mpAnmObj) {
break;
}
}
weight = node->GetWeight(idx);
node->Detach(idx);
}
mpAnmObj->Release();
mpAnmObj->Destroy();
mpFrameHeap->free(3);
u32 tmp;
mpAnmObj = nw4r::g3d::AnmObjChrRes::Construct(&mAllocator, &tmp, anm, mdl.getResMdl(), false);
mpAnmObj->Bind(mdl.getResMdl());
setFrmCtrlDefault(anm, mode);
if (parent != nullptr) {
nw4r::g3d::AnmObjChrRes *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjChrRes>(mpAnmObj);
node->SetWeight(idx, weight);
node->Attach(idx, o);
}
}
void anmChr_c::setFrmCtrlDefault(nw4r::g3d::ResAnmChr &anm, m3d::playMode_e mode) {
if (mode == PLAY_MODE_4) {
mode = anm.GetAnmPolicy() == nw4r::g3d::ANM_POLICY_ONETIME ? PLAY_MODE_1 : PLAY_MODE_0;
}
set(anm.GetNumFrame(), mode, 1.0f, -1.0f);
}
} // namespace m3d
+56
View File
@@ -0,0 +1,56 @@
#include <m/m3d/m3d.h>
#include <m/m3d/m_anmchrblend.h>
#include <nw4r/g3d/g3d_anmchr.h>
#include <nw4r/g3d/g3d_resanmchr.h>
namespace m3d {
anmChrBlend_c::~anmChrBlend_c() {}
int anmChrBlend_c::getType() const {
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_CHR;
}
bool anmChrBlend_c::create(nw4r::g3d::ResMdl mdl, int num, mAllocator_c *alloc, u32 *pSize) {
if (alloc == nullptr) {
alloc = internal::l_allocator_p;
}
u32 size;
if (pSize == nullptr) {
pSize = &size;
}
nw4r::g3d::AnmObjChrBlend::Construct(nullptr, pSize, mdl, num);
if (!createAllocator(alloc, pSize)) {
return false;
}
mpAnmObj = nw4r::g3d::AnmObjChrBlend::Construct(&mAllocator, &size, mdl, num);
return true;
}
void anmChrBlend_c::attach(int idx, nw4r::g3d::AnmObjChrRes *anm, f32 weight) {
nw4r::g3d::AnmObjChrBlend *obj = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjChrBlend>(mpAnmObj);
obj->SetWeight(idx, weight);
obj->Attach(idx, anm);
}
void anmChrBlend_c::attach(int idx, anmChr_c *anm, f32 weight) {
nw4r::g3d::AnmObjChrRes *res = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjChrRes>(anm->getAnimObj());
attach(idx, res, weight);
}
void anmChrBlend_c::detach(int idx) {
nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjChrBlend>(mpAnmObj)->Detach(idx);
}
void anmChrBlend_c::setWeight(int idx, f32 weight) {
nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjChrBlend>(mpAnmObj)->SetWeight(idx, weight);
}
f32 anmChrBlend_c::getWeight(int idx) const {
return nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjChrBlend>(mpAnmObj)->GetWeight(idx);
}
} // namespace m3d
+203
View File
@@ -0,0 +1,203 @@
#include <egg/core/eggFrmHeap.h>
#include <m/m3d/m3d.h>
#include <m/m3d/m_anmmatclr.h>
#include <m/m_heap.h>
namespace m3d {
anmMatClr_c::child_c::~child_c() {}
int anmMatClr_c::child_c::getType() const {
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_MATCLR;
}
u32 anmMatClr_c::child_c::heapCost(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmClr clr, bool b) {
u32 size = 0;
nw4r::g3d::AnmObjMatClrRes::Construct(nullptr, &size, clr, mdl, false);
if (b) {
size = ROUND_UP(mHeap::frmHeapCost(size, 0x20), 0x20);
}
return size;
}
bool anmMatClr_c::child_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmClr clr, mAllocator_c *alloc, u32 *pSize) {
if (alloc == nullptr) {
alloc = internal::l_allocator_p;
}
u32 size;
if (pSize == nullptr) {
pSize = &size;
}
*pSize = child_c::heapCost(mdl, clr, false);
if (!createAllocator(alloc, pSize)) {
return false;
}
mpAnmObj = nw4r::g3d::AnmObjMatClrRes::Construct(&mAllocator, nullptr, clr, mdl, false);
if (!mpAnmObj->Bind(mdl)) {
remove();
return false;
}
setFrmCtrlDefault(clr, PLAY_MODE_4);
return true;
}
void anmMatClr_c::child_c::setAnm(m3d::bmdl_c &mdl, nw4r::g3d::ResAnmClr clr, m3d::playMode_e mode) {
releaseAnm();
mpAnmObj = nw4r::g3d::AnmObjMatClrRes::Construct(&mAllocator, nullptr, clr, mdl.getResMdl(), false);
mpAnmObj->Bind(mdl.getResMdl());
setFrmCtrlDefault(clr, mode);
}
void anmMatClr_c::child_c::releaseAnm() {
if (mpAnmObj != nullptr) {
mpAnmObj->Release();
mpFrameHeap->free(3);
mpAnmObj = nullptr;
}
}
void anmMatClr_c::child_c::setFrmCtrlDefault(nw4r::g3d::ResAnmClr &clr, playMode_e mode) {
if (mode == PLAY_MODE_4) {
mode = clr.GetAnmPolicy() == nw4r::g3d::ANM_POLICY_ONETIME ? PLAY_MODE_1 : PLAY_MODE_0;
}
set(clr.GetNumFrame(), mode, 1.0f, -1.0f);
}
u32 anmMatClr_c::heapCost(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmClr clr, s32 num, bool b) {
u32 size = 0;
nw4r::g3d::AnmObjMatClrOverride::Construct(nullptr, &size, mdl, num);
size += ROUND_UP(num * sizeof(child_c), 0x20);
u32 childCost = child_c::heapCost(mdl, clr, true);
size += num * ROUND_UP(childCost, 0x20);
if (b) {
size = ROUND_UP(mHeap::frmHeapCost(size, 0x20), 0x20);
}
return size;
}
bool anmMatClr_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmClr clr, mAllocator_c *alloc, u32 *pSize, s32 num) {
if (alloc == nullptr) {
alloc = internal::l_allocator_p;
}
u32 size = 0;
if (pSize == nullptr) {
pSize = &size;
}
*pSize = heapCost(mdl, clr, num, false);
if (!createAllocator(alloc, pSize)) {
return false;
}
mpAnmObj = nw4r::g3d::AnmObjMatClrOverride::Construct(&mAllocator, nullptr, mdl, num);
// TODO inline?
mpChildren = (child_c *)MEMAllocFromAllocator(&mAllocator, ROUND_UP(num * sizeof(child_c), 0x20));
nw4r::g3d::AnmObjMatClrOverride *obj = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjMatClrOverride>(mpAnmObj);
child_c *child = mpChildren;
for (int i = 0; i < num; i++) {
new (child) child_c();
if (!child->create(mdl, clr, &mAllocator, nullptr)) {
mHeap::destroyFrmHeap(mpFrameHeap);
return false;
}
if (i == 0) {
obj->Attach(i, nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjMatClrRes>(child->getAnimObj()));
} else {
child->releaseAnm();
}
child++;
}
return true;
}
anmMatClr_c::~anmMatClr_c() {
anmMatClr_c::remove();
}
int anmMatClr_c::getType() const {
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_MATCLR;
}
void anmMatClr_c::remove() {
nw4r::g3d::AnmObjMatClrOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjMatClrOverride>(mpAnmObj);
if (o != nullptr && mpChildren != 0) {
int size = o->Size();
for (int i = 0; i < size; i++) {
mpChildren[i].remove();
}
mpChildren = nullptr;
}
banm_c::remove();
}
void anmMatClr_c::setAnm(bmdl_c &mdl, nw4r::g3d::ResAnmClr clr, s32 idx, playMode_e mode) {
nw4r::g3d::AnmObjMatClrOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjMatClrOverride>(mpAnmObj);
o->Detach(idx);
mpChildren[idx].setAnm(mdl, clr, mode);
nw4r::g3d::AnmObjMatClrRes *res =
nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjMatClrRes>(mpChildren[idx].getAnimObj());
o->Attach(idx, res);
}
void anmMatClr_c::play() {
nw4r::g3d::AnmObjMatClrOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjMatClrOverride>(mpAnmObj);
int size = o->Size();
for (int i = 0; i < size; i++) {
play(i);
}
}
void anmMatClr_c::play(s32 idx) {
if (mpChildren[idx].IsBound()) {
mpChildren[idx].play();
}
}
f32 anmMatClr_c::getFrame(s32 idx) const {
return mpChildren[idx].getFrame();
}
void anmMatClr_c::setFrame(f32 f, s32 idx) {
mpChildren[idx].setFrameOnly(f);
}
f32 anmMatClr_c::getRate(s32 idx) const {
return mpChildren[idx].getRate();
}
void anmMatClr_c::setRate(f32 f, s32 idx) {
mpChildren[idx].setRate(f);
}
bool anmMatClr_c::isStop(s32 idx) const {
return mpChildren[idx].isStop();
}
bool anmMatClr_c::checkFrame(f32 f, s32 idx) const {
return mpChildren[idx].checkFrame(f);
}
void anmMatClr_c::setPlayMode(playMode_e mode, s32 idx) {
mpChildren[idx].setPlayState(mode);
}
f32 anmMatClr_c::getFrameMax(s32 idx) const {
return mpChildren[idx].getEndFrame();
}
f32 anmMatClr_c::getFrameStart(s32 idx) const {
return mpChildren[idx].getStartFrame();
}
} // namespace m3d
+77
View File
@@ -0,0 +1,77 @@
#include <m/m3d/m_anmmdl.h>
namespace m3d {
mdlAnmChr::~mdlAnmChr() {}
void mdlAnmChr::play() {
mMdl.play();
}
void mdlAnmChr::setFrame(f32 f) {
mAnm.setFrameOnly(f);
}
void mdlAnmChr::setAnm(const char *name, playMode_e mode) {
setAnm(name, mode, 0.0f);
}
void mdlAnmChr::setRate(f32 rate) {
mAnm.setRate(rate);
}
bool mdlAnmChr::create(void *mdlFile, void *anmFile, const char *mdlName, const char *anmName, mAllocator_c *alloc,
u32 bufferOption, int nView, u32 *pSize) {
return create(mdlFile, anmFile, mdlName, anmName, nullptr, alloc, bufferOption, nView, pSize);
}
bool mdlAnmChr::create2(void *mdlFile, void *anmFile, const char *mdlName, const char *anmName, mAllocator_c *alloc,
u32 bufferOption, int nView, u32 *pSize) {
return create(mdlFile, anmFile, mdlName, anmName, alloc, bufferOption, nView, pSize);
}
bool mdlAnmChr::create(void *mdlFile, void *anmFile, const char *mdlName, const char *anmName,
mdl_c::mdlCallback_c *callback, mAllocator_c *alloc, u32 bufferOption, int nView, u32 *pSize) {
mMdlFile = mdlFile;
mAnmFile = anmFile;
nw4r::g3d::ResMdl resMdl = mMdlFile.GetResMdl(mdlName);
if (!mMdl.create(resMdl, callback, alloc, bufferOption, nView, pSize)) {
return false;
}
nw4r::g3d::ResAnmChr resAnm = mAnmFile.GetResAnmChr(anmName);
if (!resAnm.mAnmChr.IsValid()) {
resAnm = mMdlFile.GetResAnmChr(anmName);
}
u32 oldSize;
if (pSize != nullptr) {
oldSize = *pSize;
}
if (!mAnm.create(resMdl, resAnm, alloc, pSize)) {
mMdl.remove();
return false;
}
if (pSize != nullptr) {
*pSize += oldSize;
}
return true;
}
bool mdlAnmChr::create(void *resFile, const char *mdlName, const char *anmName, mAllocator_c *alloc, u32 bufferOption,
int nView, u32 *pSize) {
return create(resFile, resFile, mdlName, anmName, nullptr, alloc, bufferOption, nView, pSize);
}
void mdlAnmChr::setAnm(const char *name, playMode_e mode, f32 blend) {
nw4r::g3d::ResAnmChr anm = mAnmFile.GetResAnmChr(name);
if (!anm.mAnmChr.IsValid()) {
anm = mMdlFile.GetResAnmChr(name);
}
mAnm.setAnm(mMdl, anm, mode);
mMdl.setAnm(mAnm, blend);
}
} // namespace m3d
+60
View File
@@ -0,0 +1,60 @@
#include <m/m3d/m3d.h>
#include <m/m3d/m_anmshp.h>
#include <nw4r/g3d/g3d_anmshp.h>
namespace m3d {
anmShp_c::~anmShp_c() {}
int anmShp_c::getType() const {
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_SHP;
}
bool anmShp_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmShp anm, mAllocator_c *alloc, u32 *pSize) {
if (alloc == nullptr) {
alloc = internal::l_allocator_p;
}
u32 tmp;
if (pSize == nullptr) {
pSize = &tmp;
}
// This might be an nw4r inline? Note that some of the roundings
// are no-ops that still emit instructions because mwcc doesn't do
// math
u32 numEntries = mdl.GetResVtxPosNumEntries();
*pSize = ROUND_UP(ROUND_UP(numEntries * 2 + 0x38, 0x04) + numEntries * 0x0C, 0x04);
if (!createAllocator(alloc, pSize)) {
return false;
}
mpAnmObj = nw4r::g3d::AnmObjShpRes::Construct(&mAllocator, &tmp, anm, mdl, 0);
if (!mpAnmObj->Bind(mdl)) {
remove();
return false;
} else {
setFrmCtrlDefault(anm, PLAY_MODE_4);
return true;
}
}
void anmShp_c::setAnm(m3d::bmdl_c &mdl, nw4r::g3d::ResAnmShp anm, m3d::playMode_e mode) {
mdl.removeAnm((nw4r::g3d::ScnMdlSimple::AnmObjType)getType());
mpAnmObj->Release();
mpFrameHeap->free(0x3);
u32 tmp;
mpAnmObj = nw4r::g3d::AnmObjShpRes::Construct(&mAllocator, &tmp, anm, mdl.getResMdl(), 0);
mpAnmObj->Bind(mdl.getResMdl());
setFrmCtrlDefault(anm, mode);
}
void anmShp_c::setFrmCtrlDefault(nw4r::g3d::ResAnmShp &anm, m3d::playMode_e mode) {
if (mode == PLAY_MODE_4) {
mode = anm.GetAnmPolicy() == nw4r::g3d::ANM_POLICY_ONETIME ? PLAY_MODE_1 : PLAY_MODE_0;
}
set(anm.GetNumFrame(), mode, 1.0f, -1.0f);
}
} // namespace m3d
+191
View File
@@ -0,0 +1,191 @@
#include <egg/core/eggFrmHeap.h>
#include <m/m3d/m3d.h>
#include <m/m3d/m_anmtexpat.h>
#include <m/m_heap.h>
namespace m3d {
int anmTexPat_c::child_c::getType() const {
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_TEXPAT;
}
anmTexPat_c::child_c::~child_c() {}
u32 anmTexPat_c::child_c::heapCost(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmTexPat pat, bool b) {
u32 size = 0;
nw4r::g3d::AnmObjTexPatRes::Construct(nullptr, &size, pat, mdl, false);
if (b) {
size = ROUND_UP(mHeap::frmHeapCost(size, 0x20), 0x20);
}
return size;
}
bool anmTexPat_c::child_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmTexPat pat, mAllocator_c *alloc, u32 *pSize) {
if (alloc == nullptr) {
alloc = internal::l_allocator_p;
}
u32 size;
if (pSize == nullptr) {
pSize = &size;
}
*pSize = child_c::heapCost(mdl, pat, false);
if (!createAllocator(alloc, pSize)) {
return false;
}
mpAnmObj = nw4r::g3d::AnmObjTexPatRes::Construct(&mAllocator, nullptr, pat, mdl, false);
if (!mpAnmObj->Bind(mdl)) {
remove();
return false;
}
setFrmCtrlDefault(pat, PLAY_MODE_4);
return true;
}
void anmTexPat_c::child_c::setAnm(m3d::bmdl_c &mdl, nw4r::g3d::ResAnmTexPat pat, m3d::playMode_e mode) {
releaseAnm();
mpAnmObj = nw4r::g3d::AnmObjTexPatRes::Construct(&mAllocator, nullptr, pat, mdl.getResMdl(), false);
mpAnmObj->Bind(mdl.getResMdl());
setFrmCtrlDefault(pat, mode);
}
void anmTexPat_c::child_c::releaseAnm() {
if (mpAnmObj != nullptr) {
mpAnmObj->Release();
mpFrameHeap->free(3);
mpAnmObj = nullptr;
}
}
void anmTexPat_c::child_c::setFrmCtrlDefault(nw4r::g3d::ResAnmTexPat &pat, playMode_e mode) {
if (mode == PLAY_MODE_4) {
mode = pat.GetAnmPolicy() == nw4r::g3d::ANM_POLICY_ONETIME ? PLAY_MODE_1 : PLAY_MODE_0;
}
set(pat.GetNumFrame(), mode, 1.0f, -1.0f);
}
u32 anmTexPat_c::heapCost(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmTexPat pat, s32 num, bool b) {
u32 size = 0;
nw4r::g3d::AnmObjTexPatOverride::Construct(nullptr, &size, mdl, num);
size += ROUND_UP(num * sizeof(child_c), 0x20);
u32 childCost = child_c::heapCost(mdl, pat, true);
size += num * ROUND_UP(childCost, 0x20);
if (b) {
size = ROUND_UP(mHeap::frmHeapCost(size, 0x20), 0x20);
}
return size;
}
bool anmTexPat_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmTexPat pat, mAllocator_c *alloc, u32 *pSize, s32 num) {
if (alloc == nullptr) {
alloc = internal::l_allocator_p;
}
u32 size = 0;
if (pSize == nullptr) {
pSize = &size;
}
*pSize = heapCost(mdl, pat, num, false);
if (!createAllocator(alloc, pSize)) {
return false;
}
mpAnmObj = nw4r::g3d::AnmObjTexPatOverride::Construct(&mAllocator, nullptr, mdl, num);
// TODO inline?
mpChildren = (child_c *)MEMAllocFromAllocator(&mAllocator, ROUND_UP(num * sizeof(child_c), 0x20));
nw4r::g3d::AnmObjTexPatOverride *obj = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexPatOverride>(mpAnmObj);
child_c *child = mpChildren;
for (int i = 0; i < num; i++) {
new (child) child_c();
if (!child->create(mdl, pat, &mAllocator, nullptr)) {
mHeap::destroyFrmHeap(mpFrameHeap);
return false;
}
if (i == 0) {
obj->Attach(i, nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexPatRes>(child->getAnimObj()));
} else {
child->releaseAnm();
}
child++;
}
return true;
}
anmTexPat_c::~anmTexPat_c() {
anmTexPat_c::remove();
}
int anmTexPat_c::getType() const {
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_TEXPAT;
}
void anmTexPat_c::remove() {
nw4r::g3d::AnmObjTexPatOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexPatOverride>(mpAnmObj);
if (o != nullptr && mpChildren != 0) {
int size = o->Size();
for (int i = 0; i < size; i++) {
mpChildren[i].remove();
}
mpChildren = nullptr;
}
banm_c::remove();
}
void anmTexPat_c::setAnm(bmdl_c &mdl, nw4r::g3d::ResAnmTexPat pat, s32 idx, playMode_e mode) {
nw4r::g3d::AnmObjTexPatOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexPatOverride>(mpAnmObj);
o->Detach(idx);
mpChildren[idx].setAnm(mdl, pat, mode);
nw4r::g3d::AnmObjTexPatRes *res =
nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexPatRes>(mpChildren[idx].getAnimObj());
o->Attach(idx, res);
}
void anmTexPat_c::play() {
nw4r::g3d::AnmObjTexPatOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexPatOverride>(mpAnmObj);
int size = o->Size();
for (int i = 0; i < size; i++) {
play(i);
}
}
void anmTexPat_c::play(s32 idx) {
if (mpChildren[idx].IsBound()) {
mpChildren[idx].play();
}
}
f32 anmTexPat_c::getFrame(s32 idx) const {
return mpChildren[idx].getFrame();
}
void anmTexPat_c::setFrame(f32 f, s32 idx) {
mpChildren[idx].setFrameOnly(f);
}
void anmTexPat_c::setRate(f32 f, s32 idx) {
mpChildren[idx].setRate(f);
}
bool anmTexPat_c::isStop(s32 idx) const {
return mpChildren[idx].isStop();
}
f32 anmTexPat_c::getFrameMax(s32 idx) const {
return mpChildren[idx].getEndFrame();
}
void anmTexPat_c::setFrameStart(f32 f, s32 idx) {
mpChildren[idx].setStartFrame(f);
}
} // namespace m3d
+214
View File
@@ -0,0 +1,214 @@
#include <egg/core/eggFrmHeap.h>
#include <m/m3d/m3d.h>
#include <m/m3d/m_anmtexsrt.h>
#include <m/m_heap.h>
namespace m3d {
int anmTexSrt_c::child_c::getType() const {
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_TEXSRT;
}
anmTexSrt_c::child_c::~child_c() {}
u32 anmTexSrt_c::child_c::heapCost(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmTexSrt srt, bool b) {
u32 size = 0;
nw4r::g3d::AnmObjTexSrtRes::Construct(nullptr, &size, srt, mdl, false);
if (b) {
size = ROUND_UP(mHeap::frmHeapCost(size, 0x20), 0x20);
}
return size;
}
bool anmTexSrt_c::child_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmTexSrt srt, mAllocator_c *alloc, u32 *pSize) {
if (alloc == nullptr) {
alloc = internal::l_allocator_p;
}
u32 size;
if (pSize == nullptr) {
pSize = &size;
}
*pSize = child_c::heapCost(mdl, srt, false);
if (!createAllocator(alloc, pSize)) {
return false;
}
mpAnmObj = nw4r::g3d::AnmObjTexSrtRes::Construct(&mAllocator, nullptr, srt, mdl, false);
if (!mpAnmObj) {
return false;
}
if (!mpAnmObj->Bind(mdl)) {
remove();
return false;
}
setFrmCtrlDefault(srt, PLAY_MODE_4);
return true;
}
void anmTexSrt_c::child_c::setAnm(m3d::bmdl_c &mdl, nw4r::g3d::ResAnmTexSrt srt, m3d::playMode_e mode) {
releaseAnm();
mpAnmObj = nw4r::g3d::AnmObjTexSrtRes::Construct(&mAllocator, nullptr, srt, mdl.getResMdl(), false);
mpAnmObj->Bind(mdl.getResMdl());
setFrmCtrlDefault(srt, mode);
}
void anmTexSrt_c::child_c::releaseAnm() {
if (mpAnmObj != nullptr) {
mpAnmObj->Release();
mpFrameHeap->free(3);
mpAnmObj = nullptr;
}
}
void anmTexSrt_c::child_c::setFrmCtrlDefault(nw4r::g3d::ResAnmTexSrt &srt, playMode_e mode) {
if (mode == PLAY_MODE_4) {
mode = srt.GetAnmPolicy() == nw4r::g3d::ANM_POLICY_ONETIME ? PLAY_MODE_1 : PLAY_MODE_0;
}
set(srt.GetNumFrame(), mode, 1.0f, -1.0f);
}
u32 anmTexSrt_c::heapCost(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmTexSrt srt, s32 num, bool b) {
u32 size = 0;
nw4r::g3d::AnmObjTexSrtOverride::Construct(nullptr, &size, mdl, num);
size += ROUND_UP(num * sizeof(child_c), 0x20);
u32 childCost = child_c::heapCost(mdl, srt, true);
size += num * ROUND_UP(childCost, 0x20);
if (b) {
size = ROUND_UP(mHeap::frmHeapCost(size, 0x20), 0x20);
}
return size;
}
bool anmTexSrt_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmTexSrt srt, mAllocator_c *alloc, u32 *pSize, s32 num) {
if (alloc == nullptr) {
alloc = internal::l_allocator_p;
}
u32 size = 0;
if (pSize == nullptr) {
pSize = &size;
}
*pSize = heapCost(mdl, srt, num, false);
if (!createAllocator(alloc, pSize)) {
return false;
}
mpAnmObj = nw4r::g3d::AnmObjTexSrtOverride::Construct(&mAllocator, nullptr, mdl, num);
if (!mpAnmObj) {
return false;
}
// TODO inline?
mpChildren = (child_c *)MEMAllocFromAllocator(&mAllocator, ROUND_UP(num * sizeof(child_c), 0x20));
if (!mpChildren) {
remove();
return false;
}
nw4r::g3d::AnmObjTexSrtOverride *obj = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexSrtOverride>(mpAnmObj);
child_c *child = mpChildren;
for (int i = 0; i < num; i++) {
new (child) child_c();
if (!child->create(mdl, srt, &mAllocator, nullptr)) {
mHeap::destroyFrmHeap(mpFrameHeap);
EGG::Heap::free(mpFrameHeap, nullptr);
return false;
}
if (i == 0) {
obj->Attach(i, nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexSrtRes>(child->getAnimObj()));
} else {
child->releaseAnm();
}
child++;
}
return true;
}
anmTexSrt_c::~anmTexSrt_c() {
anmTexSrt_c::remove();
}
int anmTexSrt_c::getType() const {
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_TEXSRT;
}
void anmTexSrt_c::remove() {
nw4r::g3d::AnmObjTexSrtOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexSrtOverride>(mpAnmObj);
if (o != nullptr && mpChildren != 0) {
int size = o->Size();
for (int i = 0; i < size; i++) {
mpChildren[i].remove();
}
mpChildren = nullptr;
}
banm_c::remove();
}
void anmTexSrt_c::setAnm(bmdl_c &mdl, nw4r::g3d::ResAnmTexSrt srt, s32 idx, playMode_e mode) {
nw4r::g3d::AnmObjTexSrtOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexSrtOverride>(mpAnmObj);
o->Detach(idx);
mpChildren[idx].setAnm(mdl, srt, mode);
nw4r::g3d::AnmObjTexSrtRes *res =
nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexSrtRes>(mpChildren[idx].getAnimObj());
o->Attach(idx, res);
}
void anmTexSrt_c::play() {
nw4r::g3d::AnmObjTexSrtOverride *o = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::AnmObjTexSrtOverride>(mpAnmObj);
int size = o->Size();
for (int i = 0; i < size; i++) {
play(i);
}
}
void anmTexSrt_c::play(s32 idx) {
if (mpChildren[idx].IsBound()) {
mpChildren[idx].play();
}
}
f32 anmTexSrt_c::getFrame(s32 idx) const {
return mpChildren[idx].getFrame();
}
void anmTexSrt_c::setFrame(f32 f, s32 idx) {
mpChildren[idx].setFrameOnly(f);
}
void anmTexSrt_c::setRate(f32 f, s32 idx) {
mpChildren[idx].setRate(f);
}
bool anmTexSrt_c::isStop(s32 idx) const {
return mpChildren[idx].isStop();
}
bool anmTexSrt_c::checkFrame(f32 f, s32 idx) const {
return mpChildren[idx].checkFrame(f);
}
void anmTexSrt_c::setPlayMode(playMode_e mode, s32 idx) {
mpChildren[idx].setPlayState(mode);
}
f32 anmTexSrt_c::getFrameMax(s32 idx) const {
return mpChildren[idx].getEndFrame();
}
void anmTexSrt_c::setFrameStart(f32 f, s32 idx) {
mpChildren[idx].setStartFrame(f);
}
f32 anmTexSrt_c::getFrameStart(s32 idx) const {
return mpChildren[idx].getStartFrame();
}
} // namespace m3d
+57
View File
@@ -0,0 +1,57 @@
#include <m/m3d/m3d.h>
#include <m/m3d/m_anmvis.h>
#include <nw4r/g3d/g3d_anmvis.h>
#include <nw4r/g3d/g3d_resanmvis.h>
#include <nw4r/g3d/g3d_resmdl.h>
namespace m3d {
anmVis_c::~anmVis_c() {}
int anmVis_c::getType() const {
return nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_VIS;
}
bool anmVis_c::create(nw4r::g3d::ResMdl mdl, nw4r::g3d::ResAnmVis anm, mAllocator_c *alloc, u32 *pSize) {
if (alloc == nullptr) {
alloc = internal::l_allocator_p;
}
u32 tmp;
if (pSize == nullptr) {
pSize = &tmp;
}
nw4r::g3d::AnmObjVisRes::Construct(nullptr, pSize, anm, mdl);
if (!createAllocator(alloc, pSize)) {
return false;
}
mpAnmObj = nw4r::g3d::AnmObjVisRes::Construct(&mAllocator, &tmp, anm, mdl);
if (!mpAnmObj->Bind(mdl)) {
remove();
return false;
} else {
setFrmCtrlDefault(anm, PLAY_MODE_4);
return true;
}
}
void anmVis_c::setAnm(m3d::bmdl_c &mdl, nw4r::g3d::ResAnmVis anm, m3d::playMode_e mode) {
mdl.removeAnm((nw4r::g3d::ScnMdlSimple::AnmObjType)getType());
mpAnmObj->Release();
mpFrameHeap->free(0x3);
u32 tmp;
mpAnmObj = nw4r::g3d::AnmObjVisRes::Construct(&mAllocator, &tmp, anm, mdl.getResMdl());
mpAnmObj->Bind(mdl.getResMdl());
setFrmCtrlDefault(anm, mode);
}
void anmVis_c::setFrmCtrlDefault(nw4r::g3d::ResAnmVis &anm, m3d::playMode_e mode) {
if (mode == PLAY_MODE_4) {
mode = anm.GetAnmPolicy() == nw4r::g3d::ANM_POLICY_ONETIME ? PLAY_MODE_1 : PLAY_MODE_0;
}
set(anm.GetNumFrame(), mode, 1.0f, -1.0f);
}
} // namespace m3d
+61
View File
@@ -0,0 +1,61 @@
#include <m/m3d/m3d.h>
#include <m/m3d/m_banm.h>
#include <m/m_heap.h>
namespace m3d {
banm_c::~banm_c() {
banm_c::remove();
}
void banm_c::remove() {
if (mpAnmObj != nullptr) {
mpAnmObj->DetachFromParent();
mpAnmObj->Destroy();
mpAnmObj = nullptr;
}
if (mpFrameHeap != nullptr) {
mHeap::destroyFrmHeap(mpFrameHeap);
mpFrameHeap = nullptr;
}
}
bool banm_c::createAllocator(mAllocator_c *alloc, u32 *pStart) {
// TODO understand this maybe?
int i1 = mHeap::frmHeapCost(*pStart, 0x20);
int i2 = mHeap::frmHeapCost(0, 0x20);
i2 = ROUND_UP(i1, 0x20) - i2;
i1 = mHeap::frmHeapCost(i2, 0x20);
*pStart = ROUND_UP(i1, 0x20);
mpFrameHeap = mHeap::createFrmHeap(i2, (EGG::Heap *)alloc->mHeap, "アニメ切り替え用アロケータ(m3d::banm_c::m_heap)",
internal::l_alignment, 0);
mAllocator.attach(mpFrameHeap, 0x20);
return true;
}
bool banm_c::IsBound() const {
if (mpAnmObj == nullptr) {
return false;
}
return mpAnmObj->TestAnmFlag(nw4r::g3d::AnmObj::ANMFLAG_ISBOUND);
}
void banm_c::play() {}
f32 banm_c::getFrame() const {
return mpAnmObj->GetFrame();
}
void banm_c::setFrameOnly(f32 frame) {
mpAnmObj->SetFrame(frame);
}
f32 banm_c::getRate() const {
return mpAnmObj->GetUpdateRate();
}
void banm_c::setRate(f32 f) {
mpAnmObj->SetUpdateRate(f);
}
} // namespace m3d
+252
View File
@@ -0,0 +1,252 @@
#include <egg/core/eggColorFader.h>
#include <egg/core/eggHeap.h>
#include <egg/gfx/eggDrawGX.h>
#include <m/m3d/m3d.h>
#include <m/m3d/m_bline.h>
#include <nw4r/g3d/g3d_light.h>
#include <nw4r/g3d/g3d_state.h>
namespace m3d {
blineMat_c::~blineMat_c() {
remove();
}
bool blineMat_c::create(mAllocator_c *pAllocator, int numLines, u16 numLinePts, f32 width, f32 repeat,
nw4r::ut::Color &color, EGG::ResTIMG *pTex, bool p9) {
if (!proc_c::create(pAllocator, nullptr)) {
return false;
}
nw4r::ut::List_Init(&mLines, 0);
if (numLines) {
mpLineArr = new (pAllocator) bline_c[numLines];
if (!mpLineArr) {
return false;
}
bline_c *pLineArr = mpLineArr;
EGG::Heap *pHeap = pAllocator->mHeap;
for (int i = 0; i < numLines; ++i) {
if (!pLineArr->create(pHeap, numLinePts, width, repeat, color)) {
remove();
return false;
}
nw4r::ut::List_Append(&mLines, pLineArr);
pLineArr++;
}
}
mLineArrNum = numLines;
mpTex = pTex;
field_0x4A = p9;
return true;
}
void blineMat_c::remove() {
if (mpLineArr) {
delete[] mpLineArr;
mpLineArr = nullptr;
}
scnLeaf_c::remove();
}
void blineMat_c::update() {
nw4r::math::MTX34 camMtx;
mVec3_c vec;
getCurrentCamera().GetCameraMtx(&camMtx);
PSMTXInverse(camMtx, camMtx);
PSMTXMultVec(camMtx, mVec3_c::zero, vec);
for (bline_c *line = (bline_c *)nw4r::ut::List_GetNext(&mLines, 0); line != nullptr;
line = (bline_c *)nw4r::ut::List_GetNext(&mLines, line)) {
if ((line->mFlags & 1) == 0) {
line->update(&vec);
}
}
}
bline_c *blineMat_c::getLine(u16 idx) {
return (bline_c *)nw4r::ut::List_GetNth(&mLines, idx);
}
void blineMat_c::setupGX(bool bTransparent) {
EGG::DrawGX::LoadTexture(mpTex, GX_TEXMAP0);
if (field_0x4A) {
u32 mask_diff_color, mask_diff_alpha, mask_spec_color, mask_spec_alpha;
nw4r::g3d::AmbLightObj ambObj;
nw4r::g3d::G3DState::LoadLightSet(0, &mask_diff_color, &mask_diff_alpha, &mask_spec_color, &mask_spec_alpha,
&ambObj);
nw4r::ut::Color ambColor(0xFF, 0xFF, 0xFF, 0xFF);
nw4r::ut::Color matColor(0xFF, 0xFF, 0xFF, 0xFF);
GXSetChanMatColor(GX_COLOR0, matColor);
ambColor.r = ambObj.r;
ambColor.g = ambObj.g;
ambColor.b = ambObj.b;
ambColor.a = ambObj.a;
GXSetChanAmbColor(GX_COLOR0, ambColor);
GXSetNumChans(1);
GXSetChanCtrl(GX_COLOR0, TRUE, GX_SRC_REG, GX_SRC_REG, (GXLightID)mask_diff_color, GX_DF_CLAMP, GX_AF_NONE);
GXSetChanCtrl(GX_ALPHA0, FALSE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
GXSetNumTevStages(2);
GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_RASC, GX_CC_CPREV, GX_CC_ZERO);
GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV);
GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
} else {
GXSetNumChans(0);
GXSetNumTevStages(1);
}
GXSetNumTexGens(1);
GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX_IDENT, 0, GX_DUALMTX_IDENT);
GXSetNumIndStages(0);
GXSetTevDirect(GX_TEVSTAGE0);
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_C0, GX_CC_TEXC, GX_CC_ZERO);
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO);
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
GXSetZCompLoc(1);
if (!bTransparent) {
GXSetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ONE, GX_LO_SET);
GXSetZMode(TRUE, GX_LEQUAL, TRUE);
} else {
GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET);
GXSetZMode(TRUE, GX_LEQUAL, FALSE);
}
GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0);
nw4r::ut::Color fogColor = 0x0;
GXSetFog(GX_FOG_NONE, fogColor, 0.0f, 0.0f, 0.0f, 0.0f);
GXSetFogRangeAdj(FALSE, 0, NULL);
GXSetCullMode(GX_CULL_BACK);
GXSetDither(1);
GXSetClipMode(GX_CLIP_ENABLE);
GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxDesc(GX_VA_NRM, GX_DIRECT);
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_CLR_RGB, GX_RGB8, 6);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_F32, 0);
nw4r::math::MTX34 camMtx;
getCurrentCamera().GetCameraMtx(&camMtx);
GXLoadPosMtxImm(camMtx, 0);
GXLoadNrmMtxImm(camMtx, 0);
GXSetCurrentMtx(0);
}
void blineMat_c::drawOpa() {
update();
setupGX(false);
for (bline_c *line = (bline_c *)nw4r::ut::List_GetNext(&mLines, 0); line != nullptr;
line = (bline_c *)nw4r::ut::List_GetNext(&mLines, line)) {
if ((line->mFlags & 1) == 0 && line->mColor.a == 0xFF) {
line->draw();
}
}
}
void blineMat_c::drawXlu() {
update();
setupGX(true);
for (bline_c *line = (bline_c *)nw4r::ut::List_GetNext(&mLines, 0); line != nullptr;
line = (bline_c *)nw4r::ut::List_GetNext(&mLines, line)) {
if ((line->mFlags & 1) == 0 && line->mColor.a != 0xFF) {
line->draw();
}
}
}
bline_c::~bline_c() {
remove();
}
bool bline_c::create(EGG::Heap *pHeap, u16 numPts, f32 width, f32 repeat, const nw4r::ut::Color &color) {
mpPathArr = new (pHeap) mVec3_c[numPts];
if (!mpPathArr) {
return false;
}
mpVtxPosArr = new (pHeap) VtxPos[numPts];
if (!mpVtxPosArr) {
remove();
return false;
}
mpVtxNrmArr = new (pHeap) VtxNrm[numPts];
if (!mpVtxNrmArr) {
remove();
return false;
}
mpVtxTexArr = new (pHeap) VtxTex[numPts];
if (!mpVtxTexArr) {
remove();
return false;
}
mPathNum = numPts;
mVtxNum = numPts;
mWidth = width;
mColor = color;
mTexRepeat = repeat;
field_0x2C = 0;
return true;
}
void bline_c::remove() {
if (mpPathArr) {
delete[] mpPathArr;
mpPathArr = nullptr;
}
if (mpVtxPosArr) {
delete[] mpVtxPosArr;
mpVtxPosArr = nullptr;
}
if (mpVtxNrmArr) {
delete[] mpVtxNrmArr;
mpVtxNrmArr = nullptr;
}
if (mpVtxTexArr) {
delete[] mpVtxTexArr;
mpVtxTexArr = nullptr;
}
}
void bline_c::update(mVec3_c *startPos) {}
void bline_c::draw() {
GXSetTevColor(GX_TEVREG0, mColor);
VtxPos *vtxPos = mpVtxPosArr;
VtxNrm *vtxNrm = mpVtxNrmArr;
VtxTex *vtxTex = mpVtxTexArr;
GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, mVtxNum * 2);
for (int i = 0; i < mVtxNum; i++) {
// First Vtx
GXPosition3f32(vtxPos->pos1.x, vtxPos->pos1.y, vtxPos->pos1.z);
GXNormal3s8(vtxNrm->nrm1.x, vtxNrm->nrm1.y, vtxNrm->nrm1.z);
GXTexCoord2f32(0.0f, vtxTex->tex);
// Second Vtx
GXPosition3f32(vtxPos->pos2.x, vtxPos->pos2.y, vtxPos->pos2.z);
GXNormal3s8(vtxNrm->nrm2.x, vtxNrm->nrm2.y, vtxNrm->nrm2.z);
GXTexCoord2f32(0.0f, vtxTex->tex);
vtxPos++;
vtxNrm++;
vtxTex++;
}
}
} // namespace m3d
+228
View File
@@ -0,0 +1,228 @@
#include <m/m3d/m3d.h>
#include <m/m3d/m_bmdl.h>
#include <nw4r/g3d/g3d_scnmdl.h>
namespace m3d {
bmdl_c::~bmdl_c() {
remove();
}
int bmdl_c::getType() const {
return SCN_LEAF_MODEL;
}
int bmdl_c::getMatID(const char *name) const {
return m3d::getMatID(getResMdl(), name);
}
int bmdl_c::getNodeID(const char *name) const {
return m3d::getNodeID(getResMdl(), name);
}
bool bmdl_c::getNodeWorldMtx(u32 p1, nw4r::math::MTX34 *out) const {
return nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdlSimple>(mpScnLeaf)->GetScnMtxPos(out,
nw4r::g3d::ScnObj::MTX_TYPE_WORLD, p1);
}
bool bmdl_c::getNodeWorldMtxMultVecZero(u32 p1, nw4r::math::VEC3 &out) const {
nw4r::math::MTX34 mtx;
if (!getNodeWorldMtx(p1, &mtx)) {
return false;
} else {
out.x = mtx[0][3];
out.y = mtx[1][3];
out.z = mtx[2][3];
return true;
}
}
bool bmdl_c::getNodeWorldMtxMultVec(u32 p1, nw4r::math::VEC3 &in, nw4r::math::VEC3 &out) const {
nw4r::math::MTX34 mtx;
if (!getNodeWorldMtx(p1, &mtx)) {
return false;
} else {
PSMTXMultVec(mtx, in, out);
return true;
}
}
void bmdl_c::setAnm(banm_c &anm) {
nw4r::g3d::ScnMdlSimple *mdl;
if (anm.getType() == nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_SHP) {
mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdl>(mpScnLeaf);
mdl->SetAnmObj(anm.getAnimObj(), nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_NOT_SPECIFIED);
} else {
mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdlSimple>(mpScnLeaf);
if (anm.getType() == nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_CHR) {
mpCurrentAnm = &anm;
}
mdl->SetAnmObj(anm.getAnimObj(), nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_NOT_SPECIFIED);
}
}
void bmdl_c::play() {
if (mpCurrentAnm != nullptr) {
mpCurrentAnm->play();
}
}
nw4r::g3d::ResMdl bmdl_c::getResMdl() const {
return nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdlSimple>(mpScnLeaf)->GetResMdl();
}
nw4r::g3d::ResMat bmdl_c::getResMat(u32 index) const {
nw4r::g3d::ResMdl mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdlSimple>(mpScnLeaf)->GetResMdl();
return mdl.GetResMat(index);
}
void bmdl_c::removeAnm(nw4r::g3d::ScnMdlSimple::AnmObjType type) {
nw4r::g3d::ScnMdlSimple *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdlSimple>(mpScnLeaf);
if (type == nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_CHR) {
mpCurrentAnm = nullptr;
}
mdl->RemoveAnmObj(type);
}
nw4r::g3d::AnmObj *bmdl_c::getAnmObj(nw4r::g3d::ScnMdlSimple::AnmObjType type) const {
nw4r::g3d::ScnMdlSimple *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdlSimple>(mpScnLeaf);
return mdl->GetAnmObj(type);
}
void bmdl_c::setTevColor(u32 idx, GXTevRegID tevId, GXColor color, bool bMarkDirty) {
nw4r::g3d::ScnMdl *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdl>(mpScnLeaf);
if (mdl) {
nw4r::g3d::ScnMdl::CopiedMatAccess matAccess(mdl, idx);
nw4r::g3d::ResMatTevColor resMatTevClr = matAccess.GetResMatTevColor(bMarkDirty);
resMatTevClr.GXSetTevColor(tevId, color);
resMatTevClr.DCStore(false);
} else {
nw4r::g3d::ResMatTevColor resMatTevClr = getResMat(idx).GetResMatTevColor();
resMatTevClr.GXSetTevColor(tevId, color);
resMatTevClr.DCStore(false);
}
}
void bmdl_c::setTevColorAll(GXTevRegID tevId, GXColor color, bool bMarkDirty) {
nw4r::g3d::ResMdl resMdl = getResMdl();
nw4r::g3d::ScnMdl *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdl>(mpScnLeaf);
if (mdl) {
for (u32 i = 0; i < resMdl.GetResMatNumEntries(); i++) {
nw4r::g3d::ScnMdl::CopiedMatAccess matAccess(mdl, i);
nw4r::g3d::ResMatTevColor resMatTevClr = matAccess.GetResMatTevColor(bMarkDirty);
resMatTevClr.GXSetTevColor(tevId, color);
resMatTevClr.DCStore(false);
}
} else {
for (u32 i = 0; i < resMdl.GetResMatNumEntries(); i++) {
nw4r::g3d::ResMatTevColor resMatTevClr = resMdl.GetResMat(i).GetResMatTevColor();
resMatTevClr.GXSetTevColor(tevId, color);
resMatTevClr.DCStore(false);
}
}
}
void bmdl_c::setTevKColor(u32 idx, GXTevKColorID tevKId, GXColor color, bool bMarkDirty) {
nw4r::g3d::ScnMdl *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdl>(mpScnLeaf);
if (mdl) {
nw4r::g3d::ScnMdl::CopiedMatAccess matAccess(mdl, idx);
nw4r::g3d::ResMatTevColor resMatTevClr = matAccess.GetResMatTevColor(bMarkDirty);
resMatTevClr.GXSetTevKColor(tevKId, color);
resMatTevClr.DCStore(false);
} else {
nw4r::g3d::ResMatTevColor resMatTevClr = getResMat(idx).GetResMatTevColor();
resMatTevClr.GXSetTevKColor(tevKId, color);
resMatTevClr.DCStore(false);
}
}
void bmdl_c::setTevKColorAll(GXTevKColorID tevKId, GXColor color, bool bMarkDirty) {
nw4r::g3d::ResMdl resMdl = getResMdl();
nw4r::g3d::ScnMdl *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdl>(mpScnLeaf);
if (mdl) {
for (u32 i = 0; i < resMdl.GetResMatNumEntries(); i++) {
nw4r::g3d::ScnMdl::CopiedMatAccess matAccess(mdl, i);
nw4r::g3d::ResMatTevColor resMatTevClr = matAccess.GetResMatTevColor(bMarkDirty);
resMatTevClr.GXSetTevKColor(tevKId, color);
resMatTevClr.DCStore(false);
}
} else {
for (u32 i = 0; i < resMdl.GetResMatNumEntries(); i++) {
nw4r::g3d::ResMatTevColor resMatTevClr = resMdl.GetResMat(i).GetResMatTevColor();
resMatTevClr.GXSetTevKColor(tevKId, color);
resMatTevClr.DCStore(false);
}
}
}
void bmdl_c::setBlendModeAll(GXBlendMode blendMode, GXBlendFactor srcFactor, GXBlendFactor dstFactor, GXLogicOp op,
bool bMarkDirty) {
nw4r::g3d::ResMdl resMdl = getResMdl();
nw4r::g3d::ScnMdl *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdl>(mpScnLeaf);
if (mdl) {
for (u32 i = 0; i < resMdl.GetResMatNumEntries(); i++) {
nw4r::g3d::ScnMdl::CopiedMatAccess matAccess(mdl, i);
nw4r::g3d::ResMatPix resMatPix = matAccess.GetResMatPix(bMarkDirty);
resMatPix.GXSetBlendMode(blendMode, srcFactor, dstFactor, op);
resMatPix.DCStore(false);
}
} else {
for (u32 i = 0; i < resMdl.GetResMatNumEntries(); i++) {
nw4r::g3d::ResMatPix resMatPix = resMdl.GetResMat(i).GetResMatPix();
resMatPix.GXSetBlendMode(blendMode, srcFactor, dstFactor, op);
resMatPix.DCStore(false);
}
}
}
void bmdl_c::setCullMode(u32 matId, GXCullMode cullMode, bool bMarkDirty) {
nw4r::g3d::ScnMdl *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdl>(mpScnLeaf);
if (mdl) {
nw4r::g3d::ScnMdl::CopiedMatAccess matAccess(mdl, matId);
nw4r::g3d::ResGenMode resGenMode = matAccess.GetResGenMode(bMarkDirty);
resGenMode.GXSetCullMode(cullMode);
} else {
nw4r::g3d::ResGenMode resGenMode = getResMat(matId).GetResGenMode();
resGenMode.GXSetCullMode(cullMode);
}
}
void bmdl_c::setCullModeAll(GXCullMode cullMode, bool bMarkDirty) {
// TODO Extra stack allocation?
nw4r::g3d::ResMdl resMdl = getResMdl();
nw4r::g3d::ScnMdl *mdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdl>(mpScnLeaf);
if (mdl) {
for (u32 i = 0; i < resMdl.GetResMatNumEntries(); i++) {
nw4r::g3d::ScnMdl::CopiedMatAccess matAccess(mdl, i);
nw4r::g3d::ResGenMode resGenMode = matAccess.GetResGenMode(bMarkDirty);
resGenMode.GXSetCullMode(cullMode);
}
} else {
for (u32 i = 0; i < resMdl.GetResMatNumEntries(); i++) {
nw4r::g3d::ResMat resMat = getResMat(i);
nw4r::g3d::ResGenMode resGenMode = resMat.GetResGenMode();
resGenMode.GXSetCullMode(cullMode);
}
}
}
void bmdl_c::setMatVisible(u32 matId, bool bVisble) {
// TODO
}
int bmdl_c::setMatTexture(char *name, GXTexObj *texObj, bool copy, void *unk, int, int) {
// TODO
}
bool bmdl_c::getBounds(mVec3_c *min, mVec3_c *max) {
// TODO
}
void bmdl_c::remove() {
mpCurrentAnm = nullptr;
scnLeaf_c::remove();
}
} // namespace m3d
+73
View File
@@ -0,0 +1,73 @@
#include <m/m3d/m_calc_ratio.h>
#include <nw4r/math/math_arithmetic.h>
namespace m3d {
calcRatio_c::calcRatio_c() {
mf1 = 0.0f;
mf2 = 1.0f;
mf3 = 0.0f;
mf4 = 0.0f;
mf5 = 1.0f;
mb1 = 0;
mb2 = 0;
}
calcRatio_c::~calcRatio_c() {}
void calcRatio_c::remove() {
mb1 = 0;
reset();
}
void calcRatio_c::reset() {
mf1 = 0.0f;
mf2 = 1.0f;
mf4 = 0.0f;
mf5 = 1.0f;
}
void calcRatio_c::offUpdate() {
mb1 = 1;
mb2 = 0;
}
void calcRatio_c::set(f32 value) {
if (value == 0.0f) {
reset();
return;
}
mf1 = 1.0f;
mf2 = 0.0f;
mf4 = 1.0f;
mf5 = 0.0f;
mb2 = 1;
mf3 = 1.0f / value;
}
void calcRatio_c::calc() {
if (mf1 == 0.0f) {
return;
}
mf2 += mf3;
if (mf2 >= 1.0f) {
reset();
} else {
mb2 = 1;
f32 start = mf1;
f32 tmp = start - start * mf2 * mf2;
mf1 = tmp;
f32 max = 1.0f - mf1;
tmp = mf1 / start;
f32 inv = nw4r::math::FInv(tmp + max);
mf4 = tmp * inv;
mf5 = max * inv;
}
}
bool calcRatio_c::isEnd() const {
return mf1 == 0.0f;
}
} // namespace m3d
+133
View File
@@ -0,0 +1,133 @@
#include <m/m3d/m_fanm.h>
namespace m3d {
fanm_c::fanm_c() {
mEndFrame = 0.0f;
mCurrentFrame = 0.0f;
mPlayState = 0.0f;
}
fanm_c::~fanm_c() {}
void fanm_c::play() {
f32 frame = mpAnmObj->GetFrame();
f32 rate = mpAnmObj->GetUpdateRate();
bool rateWasNegative = rate < 0.0f;
if (rateWasNegative) {
rate *= -1.0f;
}
mCurrentFrame = frame;
f32 newFrame;
if (rateWasNegative || (mPlayState & 2)) {
if (frame >= rate + mStartFrame) {
newFrame = frame - rate;
} else if ((mPlayState & 1) == 0) {
newFrame = frame + ((mEndFrame - rate) - mStartFrame);
} else {
newFrame = mStartFrame;
}
} else {
newFrame = frame + rate;
if ((mPlayState & 1) == 0) {
if (newFrame >= mEndFrame) {
newFrame = newFrame - mEndFrame;
}
} else {
f32 t = mEndFrame - 1.0f;
if (newFrame >= t) {
newFrame = t;
}
}
}
mpAnmObj->SetFrame(newFrame);
}
void fanm_c::set(f32 startFrame, playMode_e mode, f32 updateRate, f32 currentFrame) {
if (currentFrame < 0.0f) {
currentFrame = startFrame;
if (mode == PLAY_MODE_1) {
currentFrame = 0.0f;
} else {
currentFrame -= 1.0f;
}
}
mEndFrame = startFrame;
mStartFrame = 0.0f;
mpAnmObj->SetFrame(currentFrame);
mpAnmObj->SetUpdateRate(updateRate);
mPlayState = (u8)mode;
mCurrentFrame = currentFrame;
}
void fanm_c::set2(f32 startFrame, playMode_e mode, f32 endFrame, f32 rate, f32 currentFrame) {
if (currentFrame < 0.0f) {
currentFrame = rate < 0.0f ? endFrame - 1.0f : startFrame;
}
mStartFrame = startFrame;
mEndFrame = endFrame;
mpAnmObj->SetFrame(currentFrame);
mpAnmObj->SetUpdateRate(rate);
mPlayState = (u8)mode;
mCurrentFrame = currentFrame;
}
// assumed name
void fanm_c::setFrameOnly(f32 frame) {
banm_c::setFrameOnly(frame);
mCurrentFrame = frame;
}
bool fanm_c::isStop() const {
f32 frame = mpAnmObj->GetFrame();
f32 rate = mpAnmObj->GetUpdateRate();
if (rate < 0.0f || mPlayState == PLAY_MODE_3) {
return frame <= mStartFrame;
} else if (mPlayState == PLAY_MODE_1) {
return frame >= mEndFrame - 1.0f;
}
return false;
}
bool fanm_c::checkFrame(f32 frame) const {
f32 stored = mpAnmObj->GetFrame();
if (mCurrentFrame == stored) {
return stored == frame;
}
f32 rate = mpAnmObj->GetUpdateRate();
if (rate < 0.0f || (mPlayState & 2)) {
if (mCurrentFrame > stored) {
if (mCurrentFrame > frame && stored <= frame) {
return true;
}
} else if (frame < mCurrentFrame || frame >= stored) {
return true;
}
} else {
if (mCurrentFrame < stored) {
if (mCurrentFrame < frame && stored >= frame) {
return true;
}
} else if (frame > mCurrentFrame || frame <= stored) {
return true;
}
}
return false;
}
bool fanm_c::unk_802EAE70() const {
f32 frame = mpAnmObj->GetFrame();
f32 rate = mpAnmObj->GetUpdateRate();
if (rate < 0.0f || (mPlayState & 2)) {
return mCurrentFrame < frame;
} else {
return mCurrentFrame > frame;
}
}
} // namespace m3d
+239
View File
@@ -0,0 +1,239 @@
#include <m/m3d/m3d.h>
#include <m/m3d/m_mdl.h>
#include <nw4r/g3d/g3d_scnmdlsmpl.h>
namespace m3d {
mdl_c::mdlCallback_c::mdlCallback_c() {
mNumNode = 0;
mpNodes = nullptr;
mpBaseCallback = 0;
mpAlloc = nullptr;
}
mdl_c::mdlCallback_c::~mdlCallback_c() {}
void mdl_c::mdlCallback_c::ExecCallbackA(nw4r::g3d::ChrAnmResult *result, nw4r::g3d::ResMdl mdl,
nw4r::g3d::FuncObjCalcWorld *o) {
u16 nodeId = o->GetNodeId();
nw4r::g3d::ChrAnmResult *resPtr = &mpNodes[nodeId];
if (mCalcRatio.is0x18() && !mCalcRatio.isEnd()) {
if (!mCalcRatio.is0x19()) {
*result = *resPtr;
} else {
u32 flags = result->mFlags;
f32 f2 = mCalcRatio.get0x10();
f32 f1 = mCalcRatio.get0x14();
// TODO clean up this code, what does it even do, why do operators
// break
if ((flags & 8) == 0) {
result->VEC3_0x4.x = (result->VEC3_0x4.x * f1 + resPtr->VEC3_0x4.x * f2);
result->VEC3_0x4.y = (result->VEC3_0x4.y * f1 + resPtr->VEC3_0x4.y * f2);
result->VEC3_0x4.z = (result->VEC3_0x4.z * f1 + resPtr->VEC3_0x4.z * f2);
} else {
result->VEC3_0x4.x = (f1 + resPtr->VEC3_0x4.x * f2);
result->VEC3_0x4.y = (f1 + resPtr->VEC3_0x4.y * f2);
result->VEC3_0x4.z = (f1 + resPtr->VEC3_0x4.z * f2);
}
nw4r::math::QUAT q1;
nw4r::math::QUAT q2;
C_QUATMtx(q1, resPtr->mMtx);
if ((flags & 0x20) == 0) {
C_QUATMtx(q2, result->mMtx);
} else {
q2.x = 0.0f;
q2.y = 0.0f;
q2.z = 0.0f;
q2.w = 1.0f;
}
C_QUATSlerp(q1, q2, q1, f1);
nw4r::math::VEC3 tmp;
tmp.x = result->mMtx._03;
tmp.y = result->mMtx._13;
tmp.z = result->mMtx._23;
PSMTXQuat(result->mMtx, q1);
result->mMtx._03 = tmp.x;
result->mMtx._13 = tmp.y;
result->mMtx._23 = tmp.z;
if ((flags & 0x40) == 0) {
result->mMtx._03 = tmp.x * f1;
result->mMtx._13 = tmp.y * f1;
result->mMtx._23 = tmp.z * f1;
}
result->mMtx._03 += resPtr->mMtx._03 * f2;
result->mMtx._13 += resPtr->mMtx._13 * f2;
result->mMtx._23 += resPtr->mMtx._23 * f2;
result->mFlags = result->mFlags & ~(0x80000000 | 0x00000040 | 0x00000020 | 0x00000008);
*resPtr = *result;
}
} else {
*resPtr = *result;
}
if (mpBaseCallback != nullptr) {
mpBaseCallback->timingA(nodeId, result, mdl);
}
}
void mdl_c::mdlCallback_c::ExecCallbackB(nw4r::g3d::WorldMtxManip *m, nw4r::g3d::ResMdl mdl,
nw4r::g3d::FuncObjCalcWorld *o) {
u16 nodeId = o->GetNodeId();
if (mpBaseCallback != nullptr) {
mpBaseCallback->timingB(nodeId, m, mdl);
}
// Not sure what this does
u32 num = mdl.GetResNodeNumEntries();
u32 nodeInc = nodeId + 1;
u32 tmp = (nodeInc / num);
o->SetNodeId(nodeInc - tmp * num);
}
void mdl_c::mdlCallback_c::ExecCallbackC(nw4r::math::MTX34 *mat, nw4r::g3d::ResMdl mdl, nw4r::g3d::FuncObjCalcWorld *) {
if (mpBaseCallback != nullptr) {
mpBaseCallback->timingC(mat, mdl);
}
mCalcRatio.offUpdate();
}
bool mdl_c::mdlCallback_c::create(nw4r::g3d::ResMdl mdl, mAllocator_c *alloc, u32 *pSize) {
if (alloc == nullptr) {
alloc = internal::l_allocator_p;
}
u32 size = 0;
if (pSize == nullptr) {
pSize = &size;
}
mNumNode = mdl.GetResNodeNumEntries();
size_t bufSize = mNumNode * sizeof(nw4r::g3d::ChrAnmResult);
mpNodes = (nw4r::g3d::ChrAnmResult *)MEMAllocFromAllocator(alloc, bufSize);
if (mpNodes == nullptr) {
return false;
}
*pSize = ROUND_UP(bufSize + ROUND_UP(*pSize, 0x04), 0x04);
nw4r::g3d::ChrAnmResult *node = mpNodes;
for (int i = 0; i < mNumNode; i++) {
node->VEC3_0x4.x = 1.0f;
node->VEC3_0x4.y = 1.0f;
node->VEC3_0x4.z = 1.0f;
PSMTXIdentity(node->mMtx);
node++;
}
mpAlloc = alloc;
return true;
}
void mdl_c::mdlCallback_c::remove() {
mCalcRatio.remove();
if (mpNodes != nullptr) {
// Probably an m_allocator inline
MEMFreeToAllocator(mpAlloc, mpNodes);
}
mpNodes = nullptr;
mpAlloc = nullptr;
}
void mdl_c::mdlCallback_c::setBlendFrame(f32 frame) {
mCalcRatio.set(frame);
}
void mdl_c::mdlCallback_c::calcBlend() {
if (!mCalcRatio.isEnd()) {
mCalcRatio.calc();
}
}
mdl_c::mdl_c() : mpOwnedCallback(nullptr), mpCallback(nullptr) {}
mdl_c::~mdl_c() {
remove();
}
bool mdl_c::create(nw4r::g3d::ResMdl mdl, mAllocator_c *alloc, u32 bufferOption, int nView, u32 *pSize) {
return create(mdl, nullptr, alloc, bufferOption, nView, pSize);
}
bool mdl_c::create(nw4r::g3d::ResMdl mdl, mdl_c::mdlCallback_c *cb, mAllocator_c *alloc, u32 bufferOption, int nView,
u32 *pSize) {
if (alloc == nullptr) {
alloc = internal::l_allocator_p;
}
u32 tmp1;
u32 tmp2;
u32 *pSize1 = nullptr;
u32 *pSize2 = nullptr;
if (pSize != nullptr) {
pSize1 = &tmp1;
pSize2 = &tmp2;
}
if (!smdl_c::create(mdl, alloc, bufferOption, nView, pSize1)) {
return false;
}
if (cb == nullptr) {
mpOwnedCallback = (mdlCallback_c *)alloc->alloc(sizeof(mdlCallback_c));
if (mpOwnedCallback == nullptr) {
remove();
return false;
}
new (mpOwnedCallback) mdlCallback_c();
mpCallback = mpOwnedCallback;
} else {
mpCallback = cb;
}
if (!mpCallback->create(mdl, alloc, pSize2)) {
remove();
return false;
}
if (pSize != nullptr) {
*pSize = tmp1 + tmp2;
}
nw4r::g3d::ScnMdlSimple *sMdl;
sMdl = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnMdlSimple>(mpScnLeaf);
sMdl->SetCalcWorldCallback(mpCallback);
sMdl->EnableScnMdlCallbackTiming(nw4r::g3d::ScnObj::TIMING_ALL);
setCallback(nullptr);
return true;
}
void mdl_c::remove() {
if (mpOwnedCallback != nullptr) {
mAllocator_c *alloc = mpOwnedCallback->getAllocator();
mpOwnedCallback->remove();
mpOwnedCallback->~mdlCallback_c();
alloc->free(mpOwnedCallback);
mpOwnedCallback = nullptr;
mpCallback = nullptr;
}
bmdl_c::remove();
}
void mdl_c::setAnm(m3d::banm_c &anm) {
setAnm(anm, 0.0f);
}
void mdl_c::play() {
bmdl_c::play();
mpCallback->calcBlend();
}
void mdl_c::setAnm(m3d::banm_c &anm, f32 f) {
if (anm.getType() == nw4r::g3d::ScnMdlSimple::ANMOBJTYPE_CHR) {
mpCallback->setBlendFrame(f);
}
bmdl_c::setAnm(anm);
}
void mdl_c::setCallback(callback_c *cb) {
mpCallback->setBaseCallback(cb);
}
} // namespace m3d
+46
View File
@@ -0,0 +1,46 @@
#include <m/m3d/m3d.h>
#include <m/m3d/m_proc.h>
#include <nw4r/g3d/g3d_scnproc.h>
namespace m3d {
void proc_c_drawProc(nw4r::g3d::ScnProc *proc, bool b) {
proc_c *p = static_cast<proc_c *>(proc->GetUserData());
if (b) {
p->drawOpa();
} else {
p->drawXlu();
}
}
proc_c::~proc_c() {}
int proc_c::getType() const {
return SCN_LEAF_PROC;
}
void proc_c::drawOpa() {}
void proc_c::drawXlu() {}
bool proc_c::create(mAllocator_c *alloc, u32 *pSize) {
if (alloc == nullptr) {
alloc = internal::l_allocator_p;
}
u32 size;
if (pSize == nullptr) {
pSize = &size;
}
mpScnLeaf = nw4r::g3d::ScnProc::Construct(alloc, pSize, proc_c_drawProc, true, true, 0);
if (!mpScnLeaf) {
return false;
}
mpScnLeaf->SetPriorityDrawOpa(0x7f);
mpScnLeaf->SetPriorityDrawXlu(0x7f);
nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnProc>(mpScnLeaf)->SetUserData(this);
return true;
}
} // namespace m3d
+108
View File
@@ -0,0 +1,108 @@
#include <m/m3d/m3d.h>
#include <m/m3d/m_scnleaf.h>
namespace m3d {
scnLeaf_c::scnLeaf_c() : mpScnLeaf(nullptr) {}
scnLeaf_c::~scnLeaf_c() {
scnLeaf_c::remove();
}
void scnLeaf_c::remove() {
if (mpScnLeaf != nullptr) {
mpScnLeaf->Destroy();
mpScnLeaf = nullptr;
}
}
int scnLeaf_c::entry() {
return pushBack(mpScnLeaf);
}
void scnLeaf_c::setOption(u32 flag, u32 set) {
mpScnLeaf->SetScnObjOption(flag, set);
}
void scnLeaf_c::setScale(f32 x, f32 y, f32 z) {
mpScnLeaf->SetScale(x, y, z);
}
void scnLeaf_c::setScale(const nw4r::math::VEC3 &scale) {
mpScnLeaf->SetScale(scale);
}
void scnLeaf_c::getScale(nw4r::math::VEC3 *vec) const {
mpScnLeaf->GetScale(vec);
}
void scnLeaf_c::setLocalMtx(const nw4r::math::MTX34 *mtx) {
mpScnLeaf->SetMtx(nw4r::g3d::ScnObj::MTX_TYPE_LOCAL, mtx);
}
void scnLeaf_c::getLocalMtx(nw4r::math::MTX34 *mtx) const {
mpScnLeaf->GetMtx(nw4r::g3d::ScnObj::MTX_TYPE_LOCAL, mtx);
}
const nw4r::math::MTX34 *scnLeaf_c::getLocalMtx() const {
return mpScnLeaf->GetMtxPtr(nw4r::g3d::ScnObj::MTX_TYPE_LOCAL);
}
void scnLeaf_c::getWorldMtx(nw4r::math::MTX34 *mtx) const {
mpScnLeaf->GetMtx(nw4r::g3d::ScnObj::MTX_TYPE_WORLD, mtx);
}
void scnLeaf_c::getViewMtx(nw4r::math::MTX34 *mtx) const {
mpScnLeaf->GetMtx(nw4r::g3d::ScnObj::MTX_TYPE_VIEW, mtx);
}
// unofficial
void scnLeaf_c::setCallback(nw4r::g3d::IScnObjCallback *cb) {
mpScnLeaf->SetCallback(cb);
}
nw4r::g3d::IScnObjCallback *scnLeaf_c::swapCallback(nw4r::g3d::IScnObjCallback *cb) {
nw4r::g3d::IScnObjCallback *tmp = mpScnLeaf->GetScnObjCallback();
mpScnLeaf->SetCallback(cb);
return tmp;
}
void scnLeaf_c::enableCallbackTiming(nw4r::g3d::ScnObj::Timing timing) {
mpScnLeaf->EnableScnObjCallbackTiming(timing);
}
void scnLeaf_c::enableCallbackOp(nw4r::g3d::ScnObj::ExecOp op) {
mpScnLeaf->EnableScnObjCallbackExecOp(op);
}
void scnLeaf_c::calc(bool b) {
setOption(/* DISABLE_CALC_WORLD */ 0x02, false);
mpScnLeaf->G3dProc(1, 0, nullptr);
if (b == false) {
setOption(/* DISABLE_CALC_WORLD */ 0x02, true);
}
}
void scnLeaf_c::calcVtx(bool b) {
setOption(/* DISABLE_CALC_VTX */ 0x04, false);
mpScnLeaf->G3dProc(3, 0, nullptr);
if (b == false) {
setOption(/* DISABLE_CALC_VTX */ 0x04, true);
}
}
/** Unknown name/arg type */
void scnLeaf_c::calcView(void *p, bool b) {
setOption(/* DISABLE_CALC_VIEW */ 0x05, false);
mpScnLeaf->G3dProc(4, 0, p);
if (b == false) {
setOption(/* DISABLE_CALC_VIEW */ 0x05, true);
}
}
void scnLeaf_c::setPriorityDraw(int opa, int xlu) {
mpScnLeaf->SetPriorityDrawOpa(opa);
mpScnLeaf->SetPriorityDrawXlu(xlu);
}
} // namespace m3d
+35
View File
@@ -0,0 +1,35 @@
#include <m/m3d/m3d.h>
#include <m/m3d/m_smdl.h>
#include <nw4r/g3d/g3d_scnmdl.h>
#include <nw4r/g3d/g3d_scnmdlsmpl.h>
namespace m3d {
smdl_c::smdl_c() {}
smdl_c::~smdl_c() {}
bool smdl_c::create(nw4r::g3d::ResMdl mdl, mAllocator_c *alloc, u32 bufferOption, int nView, u32 *pSize) {
if (alloc == nullptr) {
alloc = internal::l_allocator_p;
}
u32 tmp;
if (pSize == nullptr) {
pSize = &tmp;
}
if (bufferOption != 0) {
mpScnLeaf = nw4r::g3d::ScnMdl::Construct(alloc, pSize, mdl, bufferOption, nView);
} else {
mpScnLeaf = nw4r::g3d::ScnMdlSimple::Construct(alloc, pSize, mdl, nView);
}
if (mpScnLeaf == nullptr) {
return false;
}
mpScnLeaf->SetPriorityDrawOpa(0x7f);
mpScnLeaf->SetPriorityDrawXlu(0x7f);
return true;
}
} // namespace m3d
+13
View File
@@ -0,0 +1,13 @@
#include <d/d_system.h>
#include <m/m_video.h>
// I dont know if this file actually exists, the place that the function exists is in an odd spot
namespace mVideo {
// 0x80065590
void create() {
// TODO
}
} // namespace mVideo
+1 -1
View File
@@ -99,6 +99,6 @@ void mHeapAllocator_c::adjustFrmHeapRestoreCurrent() {
mHeap::adjustFrmHeap(static_cast<EGG::FrmHeap *>(getHeapOfKind(heap, EGG::Heap::HEAP_KIND_FRAME)));
}
void *mHeapAllocator_c::allocOnHeap(u32 size, mHeapAllocator_c *allocator) {
void *operator new[](size_t size, mAllocator_c *allocator) {
return allocator->alloc(size);
}
+4 -7
View File
@@ -1,13 +1,10 @@
#include <m/m_fader.h>
// nw4r::g3d::G3DState::Invalidate
extern "C" void fn_8044E3B0(u32 flags);
// m3d::resetMaterial according to NSMBW
extern "C" void fn_802E46D0();
#include <m/m3d/m3d.h>
#include <nw4r/g3d/g3d_state.h>
void mFader_c::draw() {
fn_8044E3B0(0x7ff);
fn_802E46D0();
nw4r::g3d::G3DState::Invalidate(0x7ff);
m3d::resetMaterial();
mpFader->draw();
}