summaryrefslogtreecommitdiff
path: root/src/m/m3d/m3d.cpp
diff options
context:
space:
mode:
authorrobojumper <robojumper@gmail.com>2024-09-12 22:36:34 +0200
committerGitHub <noreply@github.com>2024-09-12 16:36:34 -0400
commit1180e1f4860d62bccd64bfa2a29eaeebd2c4b019 (patch)
treece6e231ef46aacbdad52ad7f6cbcd9d02dba555e /src/m/m3d/m3d.cpp
parente2c4bb7be7fa731a335bce4bc22283d899133e39 (diff)
m3d (#13)
* 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>
Diffstat (limited to 'src/m/m3d/m3d.cpp')
-rw-r--r--src/m/m3d/m3d.cpp281
1 files changed, 281 insertions, 0 deletions
diff --git a/src/m/m3d/m3d.cpp b/src/m/m3d/m3d.cpp
new file mode 100644
index 00000000..e4ec66b8
--- /dev/null
+++ b/src/m/m3d/m3d.cpp
@@ -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