NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
m_3d.cpp
1#include <game/mLib/m_3d.hpp>
2
3#include <game/mLib/m_heap.hpp>
4#include <game/mLib/m_video.hpp>
5#include <lib/egg/gx/eggGfxEngine.hpp>
6#include <lib/egg/gx/eggStateGX.hpp>
7#include <lib/egg/gx/eggScreen.hpp>
8#include <lib/egg/gx/eggDrawGX.hpp>
9#include <lib/egg/gx/eggLightTexture.hpp>
10#include <lib/nw4r/g3d/g3d.hpp>
11#include <lib/nw4r/g3d/g3d_state.hpp>
12#include <lib/MSL_C/string.h>
13
14mAllocator_c *m3d::internal::l_allocator_p;
15nw4r::g3d::ScnRoot *m3d::internal::l_scnRoot_p;
16u32 m3d::internal::l_numLightMgr;
17EGG::LightManager **m3d::internal::l_lightMgr_pp;
18u32 m3d::internal::l_numFogMgr;
19EGG::FogManager **m3d::internal::l_fogMgr_pp;
20
21void m3d::initHio(const char *name) {}
22
23bool m3d::create(EGG::Heap *heap, ulong maxChildren, ulong maxScnObj, ulong numLightObj, ulong numLightSet) {
24 internal::l_allocator_p = new(heap, 4) mAllocator_c();
25 if (internal::l_allocator_p == nullptr) {
26 return false;
27 }
28 internal::l_allocator_p->attach(heap, 0x20);
29
30 nw4r::g3d::G3dInit(true);
31 nw4r::g3d::G3DState::SetRenderModeObj(mVideo::m_video->mRenderModeObj);
32
33 size_t size;
34 internal::l_scnRoot_p = nw4r::g3d::ScnRoot::Construct(
35 internal::l_allocator_p, &size,
36 maxChildren, maxScnObj, numLightObj, numLightSet
37 );
38
39 // Clean up on failure
40 if (internal::l_scnRoot_p == nullptr) {
41 delete internal::l_allocator_p;
42 internal::l_allocator_p = nullptr;
43 return false;
44 }
45
46 return true;
47}
48
49bool m3d::create(EGG::Heap *heap, GXPixelFmt fmt, GXColor col, ulong maxChildren, ulong maxScnObj,
50 ulong numLightObj, ulong numLightSet, ulong numLightMgr, ulong numFogMgr) {
51 if (internal::l_lightMgr_pp != nullptr && internal::l_fogMgr_pp != nullptr) {
52 return false;
53 }
54
56 u16 arg1[] = { cfg.x14, cfg.x16 };
57 u16 arg2[] = { cfg.x2, cfg.x2 };
58 EGG::StateGX::initialize(cfg.x0, cfg.x2, col, fmt);
59 EGG::Screen::Initialize(arg1, arg2, nullptr);
60 EGG::Screen::SetTVModeDefault();
61 EGG::DrawGX::Initialize(heap);
62 EGG::LightTexture::initialize(0x20, heap);
63
64 internal::l_lightMgr_pp = new(heap, 4) EGG::LightManager *[numLightMgr];
65 if (internal::l_lightMgr_pp != nullptr) {
66 internal::l_numLightMgr = numLightMgr;
67 internal::l_fogMgr_pp = new(heap, 4) EGG::FogManager *[numFogMgr];
68 if (internal::l_fogMgr_pp != nullptr) {
69 internal::l_numFogMgr = numFogMgr;
70
71 // Initialize the pointer array for the light and fog managers
72 memset(internal::l_lightMgr_pp, 0, numLightMgr * sizeof(void *));
73 memset(internal::l_fogMgr_pp, 0, numFogMgr * sizeof(void *));
74
75 if (create(heap, maxChildren, maxScnObj, numLightObj, numLightSet)) {
76 return true;
77 }
78 }
79 }
80
81 // Clean up on failure
82 // [Oversight: both pointers can be null]
83 delete[] internal::l_lightMgr_pp;
84 internal::l_lightMgr_pp = nullptr;
85 delete[] internal::l_fogMgr_pp;
86 internal::l_fogMgr_pp = nullptr;
87 return false;
88}
89
90bool m3d::createLightMgr(EGG::Heap *heap, u16 lmArg1, u16 lmArg2, u8 lmArg3, bool createFogMgr, int idx) {
91 if (internal::l_lightMgr_pp == nullptr ||
92
93 // Bounds checking
94 idx < 0 || idx >= internal::l_numLightMgr || idx >= internal::l_numFogMgr ||
95
96 // Light / fog manager must not already exist
97 internal::l_lightMgr_pp[idx] != nullptr || internal::l_fogMgr_pp[idx] != nullptr) {
98 return false;
99 }
100
101 EGG::Heap *prevHeap = mHeap::setCurrentHeap(heap);
102 EGG::LightManager *lm = new(heap, 4) EGG::LightManager(lmArg1, lmArg2, lmArg3);
103 mHeap::setCurrentHeap(prevHeap);
104
105 if (lm != nullptr) {
106 // Either we don't need a fog manager or the creation was successful
107 if (!createFogMgr || m3d::createFogMgr(heap, 0x20, idx)) {
108 internal::l_lightMgr_pp[idx] = lm;
109 return true;
110 }
111 }
112
113 // [Oversight: lm here can be null]
114 delete lm;
115 return false;
116}
117
118void m3d::removeLightMgr(int idx) {
119 EGG::LightManager **mgrs = internal::l_lightMgr_pp;
120
121 // [This is a bug, mgrs[idx] != nullptr should not be checked here.
122 // The way it currently is, the intended functionality of removing all
123 // light managers with idx < 0 is broken, since we cause UB here if idx < 0]
124 if (mgrs != nullptr && mgrs[idx] != nullptr) {
125 if (idx >= 0) {
126 if (mgrs[idx] != nullptr) {
127 delete mgrs[idx];
128 mgrs[idx] = nullptr;
129 }
130 } else {
131 // If idx is negative, delete all light managers
132 for (int i = 0; i < internal::l_numLightMgr; i++) {
133 if (mgrs[i] != nullptr) {
134 delete mgrs[i];
135 }
136 }
137 delete internal::l_lightMgr_pp;
138 internal::l_lightMgr_pp = nullptr;
139 }
140 }
141 removeFogMgr(idx);
142}
143
144bool m3d::createFogMgr(EGG::Heap *heap, int fmArg, int idx) {
145 if (idx < 0 || idx >= internal::l_numFogMgr || internal::l_fogMgr_pp[idx] != nullptr) {
146 return false;
147 }
148
149 EGG::FogManager *fm = new(heap, 4) EGG::FogManager(fmArg);
150 if (fm == nullptr) {
151 return false;
152 }
153
154 internal::l_fogMgr_pp[idx] = fm;
155 return true;
156}
157
158void m3d::removeFogMgr(int idx) {
159 EGG::FogManager **mgrs = internal::l_fogMgr_pp;
160 if (mgrs == nullptr) {
161 return;
162 }
163
164 // [This is wrong, see m3d::removeLightMgr]
165 if (mgrs[idx] != nullptr) {
166 if (idx >= 0) {
167 if (mgrs[idx] != nullptr) {
168 delete mgrs[idx];
169 mgrs[idx] = nullptr;
170 }
171 } else {
172 for (int i = 0; i < internal::l_numFogMgr; i++) {
173 if (mgrs[i] != nullptr) {
174 delete mgrs[i];
175 }
176 }
177 delete internal::l_fogMgr_pp;
178 internal::l_fogMgr_pp = nullptr;
179 }
180 }
181}
182
183nw4r::g3d::ScnRoot *m3d::getScnRoot() {
184 return internal::l_scnRoot_p;
185}
186
187nw4r::g3d::Camera m3d::getCamera(int idx) {
188 return internal::l_scnRoot_p->GetCamera(idx);
189}
190
191nw4r::g3d::Camera m3d::getCurrentCamera() {
192 return internal::l_scnRoot_p->GetCurrentCamera();
193}
194
195int m3d::getCurrentCameraID() {
196 return internal::l_scnRoot_p->currCameraID;
197}
198
199void m3d::setCurrentCamera(int id) {
200 internal::l_scnRoot_p->SetCurrentCamera(id);
201}
202
203nw4r::g3d::LightSetting *m3d::getLightSettingP() {
204 return &internal::l_scnRoot_p->lightSetting;
205}
206
207EGG::LightManager *m3d::getLightMgr(int idx) {
208 return internal::l_lightMgr_pp[idx];
209}
210
211EGG::FogManager *m3d::getFogMgr(int idx) {
212 return internal::l_fogMgr_pp[idx];
213}
214
215void m3d::drawDone(int idx) {
216 if (internal::l_lightMgr_pp != nullptr && internal::l_lightMgr_pp[idx] != nullptr) {
217 internal::l_lightMgr_pp[idx]->DoneDraw();
218 }
219
220 if (internal::l_fogMgr_pp != nullptr && internal::l_fogMgr_pp[idx] != nullptr) {
221 internal::l_fogMgr_pp[idx]->DoneDraw();
222 }
223}
224
225void m3d::drawLightMapTexture(int idx) {
226 if (internal::l_lightMgr_pp != nullptr && internal::l_lightMgr_pp[idx] != nullptr) {
227 internal::l_lightMgr_pp[idx]->ltMgr->drawAndCaptureTexture(0, 0, 0, 0);
228 }
229}
230
231bool m3d::replaceLightMapTexture(char const *name, m3d::bmdl_c &mdl, int idx) {
232 if (internal::l_lightMgr_pp == nullptr) {
233 return false;
234 }
235
236 EGG::ModelEx mdlEx(mdl.getScn());
237 EGG::LightTextureManager *ltm = internal::l_lightMgr_pp[idx]->ltMgr;
238
239 return ltm->replaceModelTexture(ltm->getTextureIndex(name), &mdlEx);
240}
241
242void m3d::calcWorld(int idx) {
243 if (internal::l_lightMgr_pp != nullptr && internal::l_lightMgr_pp[idx] != nullptr) {
244 internal::l_lightMgr_pp[idx]->Calc(internal::l_scnRoot_p);
245 }
246 if (internal::l_fogMgr_pp != nullptr && internal::l_fogMgr_pp[idx] != nullptr) {
247 internal::l_fogMgr_pp[idx]->Calc();
248 }
249 internal::l_scnRoot_p->CalcWorld();
250}
251
252void m3d::calcMaterial() {
253 internal::l_scnRoot_p->CalcMaterial();
254}
255
256void m3d::calcView(int idx) {
257 if (internal::l_lightMgr_pp != nullptr && internal::l_lightMgr_pp[idx] != nullptr) {
259 nw4r::g3d::Camera cam = getCurrentCamera();
260 cam.GetCameraMtx(&mtx);
261
262 internal::l_lightMgr_pp[idx]->CalcView(mtx, getCurrentCameraID(), internal::l_scnRoot_p);
263 }
264
265 if (internal::l_fogMgr_pp != nullptr && internal::l_fogMgr_pp[idx] != nullptr) {
266 internal::l_fogMgr_pp[idx]->CopyToG3D(internal::l_scnRoot_p);
267 }
268
269 internal::l_scnRoot_p->CalcView();
270 internal::l_scnRoot_p->GatherDrawScnObj();
271 internal::l_scnRoot_p->ZSort();
272}
273
274void m3d::drawOpa() {
275 internal::l_scnRoot_p->DrawOpa();
276}
277
278void m3d::drawXlu() {
279 internal::l_scnRoot_p->DrawXlu();
280}
281
282void m3d::pushBack(nw4r::g3d::ScnObj *obj) {
283 internal::l_scnRoot_p->Insert(internal::l_scnRoot_p->count, obj);
284}
285
286void m3d::clear() {
287 nw4r::g3d::ScnRoot *scnRoot = internal::l_scnRoot_p;
288 while (scnRoot->count != 0) {
289 scnRoot->Remove(scnRoot->count - 1);
290 }
291}
292
293void m3d::reset() {
294 nw4r::g3d::G3dReset();
295 if (internal::l_lightMgr_pp != nullptr || internal::l_fogMgr_pp != nullptr) {
296 EGG::StateGX::resetGXCache();
297 }
298}
299
300int m3d::getNodeID(nw4r::g3d::ResMdl mdl, char const *name) {
301 if (mdl.IsValid()) {
302 nw4r::g3d::ResNode obj = mdl.GetResNode(name);
303 if (obj.IsValid()) {
304 return obj.GetID();
305 }
306 }
307 return -1;
308}
309
311 GXSetNumIndStages(0);
312 for (int i = 0; i < GX_MAX_TEVSTAGE; i++) {
313 GXSetTevDirect(i);
314 }
315}
316
317void m3d::proc_c_drawProc(nw4r::g3d::ScnProc *proc, bool drawOpa) {
318 m3d::proc_c *m3dProc = (m3d::proc_c *) proc->mpHolder;
319 if (drawOpa) {
320 m3dProc->drawOpa();
321 } else {
322 m3dProc->drawXlu();
323 }
324}
325
326bool m3d::proc_c::create(mAllocator_c *allocator, size_t *objSize) {
327 if (allocator == nullptr) {
328 allocator = internal::l_allocator_p;
329 }
330
331 size_t size;
332 if (objSize == nullptr) {
333 objSize = &size;
334 }
335
336 mpScn = nw4r::g3d::ScnProc::Construct(allocator, objSize, proc_c_drawProc, true, true, 0);
337 if (mpScn == nullptr) {
338 return false;
339 }
340
341 mpScn->SetPriorityDrawOpa(127);
342 mpScn->SetPriorityDrawXlu(127);
343
344 nw4r::g3d::ScnProc *p = nw4r::g3d::G3dObj::DynamicCast<nw4r::g3d::ScnProc>(mpScn);
345 p->mpHolder = this;
346 return true;
347}
An allocator class that wraps an EGG:Allocator .
struct _GXColor GXColor
A 32-bit RGBA color.
void resetMaterial()
Turns off all indirect texture processing.
Definition m_3d.cpp:310
A 3x4 matrix.
Definition mtx.hpp:15