NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
f_base.cpp
1#include <dol/framework/f_base.hpp>
2#include <dol/mLib/m_heap.hpp>
3#include <lib/MSL_C/string.h>
4#include <constants/sjis_constants.h>
5
11
14
16 mUniqueID(m_rootUniqueID),
17 mParam(m_tmpCtParam),
18 mProfName(m_tmpCtProfName),
19 mGroupType(m_tmpCtGroupType),
20 mMng(this) {
21
22 // Update the unique ID. If it maxes out the counter, stall the game
25 while (true);
26 }
27
28 // Add the base to the connect and search trees
30 int idx = mMng.getSearchTableNum();
32
33 // Try to get the profile and set the order fields
34 const fProfile::fBaseProfile_c *prof = (*fProfile::sProfileList)[mProfName];
35 if (prof != nullptr) {
36 u16 executeOrder = prof->mExecuteOrder;
37 mMng.mMainNode.mOrder = executeOrder;
38 mMng.mMainNode.mNewOrder = executeOrder;
39
40 u16 drawOrder = prof->mDrawOrder;
41 mMng.mDrawNode.mOrder = drawOrder;
42 mMng.mDrawNode.mNewOrder = drawOrder;
43 }
44
45 // Update process control flags to match the parent base
46 fBase_c *parent = getConnectParent();
47 if (parent != nullptr) {
50 }
53 }
54 }
55}
56
58 // [Clear the unused list]
59 fLiNdBa_c *curr = mUnusedList.getFirst();
60 while (curr != nullptr) {
61 curr->removeSelf();
62 curr = mUnusedList.getFirst();
63 }
64}
65
66int fBase_c::commonPack(int (fBase_c::*doFunc)(), int (fBase_c::*preFunc)(), void (fBase_c::*postFunc)(MAIN_STATE_e)) {
67 MAIN_STATE_e state;
68
69 int result = (this->*preFunc)();
70 if (result) {
71 result = (this->*doFunc)();
72 if (result == NOT_READY) {
73 state = WAITING;
74 } else if (result == SUCCEEDED) {
75 state = SUCCESS;
76 } else {
77 state = ERROR;
78 }
79
80 } else {
81 state = CANCELED;
82 }
83
84 (this->*postFunc)(state);
85 return result;
86}
87
89 return SUCCEEDED;
90}
91
93 return SUCCEEDED;
94}
95
97
98 // Creation successful, remove the base from the creation list
99 if (state == SUCCESS) {
101
102 // Since operations cannot be scheduled while the corresponding process
103 // is running, defer execution scheduling to the connect operation
104 if (fManager_c::m_nowLoopProc == fManager_c::EXECUTE) {
105 mDeferExecute = true;
106 } else {
110 }
111
112 // Something went wrong, the base must be discarded
113 } else if (state == ERROR) {
115 }
116}
117
119 return SUCCEEDED;
120}
121
124}
125
127 // [Unused code]
128 if (mpUnusedHelper != nullptr) {
129 if (!mpUnusedHelper->LoadOnlyOne()) {
130 return NOT_READY;
131 }
132 }
133
134 // If the base has children, do not delete it yet
135 fBase_c *child = getConnectChild();
136 if (child != nullptr) {
137 return NOT_READY;
138 }
139 return SUCCEEDED;
140}
141
143 if (state == SUCCESS) {
144 // Remove from all manager lists
148
149 // Delete the heap
150 if (mpHeap != nullptr) {
151 mpHeap->destroy();
152 }
153
154 // Delete the unused helper
155 if (mpUnusedHelper != nullptr) {
157 }
158
159 // Delete the base itself
160 delete this;
161 }
162}
163
166}
167
169 return SUCCEEDED;
170}
171
173 // Can only execute if not deleting and execution is enabled
175 return NOT_READY;
176 }
177 return SUCCEEDED;
178}
179
181 // Do nothing
182}
183
186}
187
189 return SUCCEEDED;
190}
191
193 // Can only draw if not deleting and drawing is enabled
195 return NOT_READY;
196 }
197 return SUCCEEDED;
198}
199
201 // Do nothing
202}
203
206}
207
209 // Do nothing
210}
211
213 if (mDeleteRequested) {
214 mDeleteRequested = false;
215
216 // Move the base from its current manager lists to the delete list
217 if (mLifecycleState == ACTIVE) {
220 } else {
222 }
223
226
227 // Delete all its children recursively
228 // [Pointless code, since this is already done in deleteRequest]
229 for (fTrNdBa_c *curr = mMng.mConnectNode.getChild(); curr != nullptr; curr = curr->getBrNext()) {
230 curr->mpOwner->deleteRequest();
231 }
232
233 } else {
234 // Update process control flags to match the parent base
235 fBase_c *parent = getConnectParent();
236 if (parent != nullptr) {
241 }
242
245 } else if (isProcControlFlag(DISABLE_DRAW)) {
247 }
248 }
249
250 // Assert the correct order in the execute and draw lists
251 // [There's probably some inlining going on here, which is the reason
252 // for all those duplicated temporaries. Couldn't figure out a better solution, though]
253 if (mLifecycleState == ACTIVE) {
254
255 fLiNdPrio_c *executeNode = &mMng.mMainNode;
256 if (executeNode->mNewOrder != executeNode->mOrder) {
258 fLiNdPrio_c *executeNode2 = &mMng.mMainNode;
259 executeNode2->mOrder = executeNode2->mNewOrder;
261 }
262
263 fLiNdPrio_c *drawNode = &mMng.mDrawNode;
264 if (drawNode->mNewOrder != drawNode->mOrder) {
266 fLiNdPrio_c *drawNode2 = &mMng.mDrawNode;
267 drawNode2->mOrder = drawNode2->mNewOrder;
269 }
270
271 // Process deferred operation scheduling requests
272 } else if (mLifecycleState != DELETING) {
273 if (mDeferRetryCreate) {
274 mDeferRetryCreate = false;
276
277 } else if (mDeferExecute) {
278 mDeferExecute = false;
282 }
283 }
284 }
285
286 return SUCCEEDED;
287}
288
290
291 // Check that deletion hasn't already been requested
293 mDeleteRequested = true;
294 deleteReady();
295
296 // Delete all children recursively
297 for (fTrNdBa_c *curr = mMng.mConnectNode.getChild(); curr != nullptr; curr = curr->getBrNext()) {
298 curr->mpOwner->deleteRequest();
299 }
300 }
301}
302
304 if (mMng.mConnectNode.getParent() != nullptr) {
305 return mMng.mConnectNode.getParent()->mpOwner;
306 }
307 return nullptr;
308}
309
311 if (mMng.mConnectNode.getChild() != nullptr) {
312 return mMng.mConnectNode.getChild()->mpOwner;
313 }
314 return nullptr;
315}
316
318 if (mMng.mConnectNode.getBrNext() != nullptr) {
319 return mMng.mConnectNode.getBrNext()->mpOwner;
320 }
321 return nullptr;
322}
323
324bool fBase_c::entryFrmHeap(unsigned long size, EGG::Heap *parentHeap) {
325
326 // Check if heap was already set
327 if (mpHeap != nullptr) {
328 return true;
329 }
330
331 unsigned long heapSize = 0;
332 EGG::FrmHeap *newHeap = nullptr;
333
334 // First, try to make a heap with the given size
335 if (size != 0) {
336 newHeap = mHeap::makeFrmHeapAndUpdate(size, parentHeap, F_BASE_HEAP_NAME, 0x20, 0);
337
338 if (newHeap != nullptr) {
339 bool createSuccess = createHeap();
340 mHeap::restoreCurrentHeap();
341
342 if (!createSuccess) {
343 mHeap::destroyFrmHeap(newHeap);
344 newHeap = nullptr;
345 } else {
346 heapSize = mHeap::adjustFrmHeap(newHeap);
347 if (size == heapSize) {
348 mpHeap = newHeap;
349 return true;
350 }
351 }
352 }
353 }
354
355 // If that failed, allocate all available space
356 if (newHeap == nullptr) {
357 newHeap = mHeap::makeFrmHeapAndUpdate(-1, parentHeap, F_BASE_HEAP_NAME, 0x20, 0);
358
359 if (newHeap != nullptr) {
360 bool createSuccess = createHeap();
361 mHeap::restoreCurrentHeap();
362
363 if (!createSuccess) {
364 mHeap::destroyFrmHeap(newHeap);
365 newHeap = nullptr;
366 } else {
367 heapSize = mHeap::adjustFrmHeap(newHeap);
368 }
369 }
370 }
371
372 // [I think this is trying to verify if adjusting the new heap freed up some more space]
373 if (newHeap != nullptr) {
374 EGG::FrmHeap *largerHeap = mHeap::makeFrmHeapAndUpdate(heapSize, parentHeap, F_BASE_HEAP_NAME, 0x20, 0);
375
376 if (largerHeap != nullptr) {
377 if (largerHeap < newHeap) {
378 mHeap::destroyFrmHeap(newHeap);
379 newHeap = nullptr;
380 bool createSuccess = createHeap();
381 mHeap::restoreCurrentHeap();
382
383 if (!createSuccess) {
384 mHeap::destroyFrmHeap(largerHeap);
385 } else {
386 mHeap::adjustFrmHeap(largerHeap);
387 mpHeap = largerHeap;
388 return true;
389 }
390
391 } else {
392 mHeap::restoreCurrentHeap();
393 mHeap::destroyFrmHeap(largerHeap);
394 }
395 }
396 }
397
398 if (newHeap != nullptr) {
399 mpHeap = newHeap;
400 return true;
401 }
402
403 // Everything failed, delete self
405 return false;
406}
407
408bool fBase_c::entryFrmHeapNonAdjust(unsigned long size, EGG::Heap *parentHeap) {
409
410 // Check if heap was already set
411 if (mpHeap != nullptr) {
412 return true;
413 }
414
415 // Try to make a heap with the given size
416 EGG::FrmHeap *newHeap = mHeap::makeFrmHeapAndUpdate(size, parentHeap, F_BASE_HEAP_NAME, 0x20, 0);
417 if (newHeap != nullptr) {
418 bool createSuccess = createHeap();
419 mHeap::restoreCurrentHeap();
420
421 if (!createSuccess) {
422 mHeap::destroyFrmHeap(newHeap);
423 } else {
424 mpHeap = newHeap;
425 return true;
426 }
427 }
428
429 // Heap creation failed, delete self
431 return false;
432}
433
435 return true;
436}
437
438void *fBase_c::operator new(size_t size) {
439 void *mem = EGG::Heap::alloc(size, -4, mHeap::g_gameHeaps[0]);
440 if (mem != nullptr) {
441 memset(mem, 0, size);
442 }
443 return mem;
444}
445
446void fBase_c::operator delete(void *mem) {
447 EGG::Heap::free(mem, mHeap::g_gameHeaps[0]);
448}
449
451 createPack();
452
453 // If the create operation has not yet been completed, reschedule it for the next tick
454 // Since operations cannot be scheduled while the corresponding process is running, defer
455 // it to the connect operation
457 if (fManager_c::m_nowLoopProc == fManager_c::CREATE) {
458 mDeferRetryCreate = true;
459 } else {
461 }
462 }
463}
464
466 const fTrNdBa_c *connectNode = &mMng.mConnectNode;
467 fTrNdBa_c *end = connectNode->getTreeNextNotChild();
468 fTrNdBa_c *curr = connectNode->getChild();
469
470 while (curr != nullptr && curr != end) {
471 if (curr->mpOwner->mLifecycleState == CREATING) {
472 return curr->mpOwner;
473 }
474 curr = curr->getTreeNext();
475 }
476 return nullptr;
477}
478
480 return getChildProcessCreateState() != nullptr;
481}
482
483void fBase_c::setTmpCtData(ProfileName profName, fTrNdBa_c *connectParent, unsigned long param, u8 groupType) {
484 m_tmpCtParam = param;
485 m_tmpCtProfName = profName;
486 m_tmpCtGroupType = groupType;
487 m_tmpCtConnectParent = connectParent;
488}
489
490fBase_c *fBase_c::fBase_make(ProfileName profName, fTrNdBa_c *connectParent, unsigned long param, u8 groupType) {
491
492 // Check if the profile exists
493 if ((*fProfile::sProfileList)[profName] == nullptr) {
494 return nullptr;
495 }
496
497 // Construct the base
498 setTmpCtData(profName, connectParent, param, groupType);
499 fBase_c *res = (fBase_c *) (*fProfile::sProfileList)[profName]->mpClassInit();
500
501 // Reset the temporary data
502 setTmpCtData(0, nullptr, 0, 0);
503
504 // Run create operation if the construction was successful
505 if (res != nullptr) {
506 res->runCreate();
507 }
508 return res;
509}
510
511fBase_c *fBase_c::createChild(ProfileName profName, fBase_c *connectParent, unsigned long param, u8 groupType) {
512 if (connectParent == nullptr) {
513 return nullptr;
514 }
515 return fBase_make(profName, &connectParent->mMng.mConnectNode, param, groupType);
516}
517
518fBase_c *fBase_c::createRoot(ProfileName profName, unsigned long param, u8 groupType) {
519 return fBase_make(profName, nullptr, param, groupType);
520}
bool append(cListNd_c *node)
Adds a node to the end of the list.
Definition c_list.cpp:60
bool remove(cListNd_c *node)
Removes a node from the list.
Definition c_list.cpp:30
bool prepend(cListNd_c *node)
Adds a node to the beginning of the list.
Definition c_list.cpp:80
bool addTreeNode(cTreeNd_c *node, cTreeNd_c *parent)
Adds a node to the tree, either to the root node or to a specified parent node.
Definition c_tree.cpp:15
bool removeTreeNode(cTreeNd_c *node)
Removes a node from the tree.
Definition c_tree.cpp:57
bool LoadOnlyOne()
[Unused].
void Delete()
[Unused].
The base class for all scenes, actors and various other processes.
Definition f_base.hpp:117
int commonPack(int(fBase_c::*doFunc)(), int(fBase_c::*preFunc)(), void(fBase_c::*postFunc)(MAIN_STATE_e))
Executes an operation. See here for more details.
Definition f_base.cpp:66
fBase_c * getChildProcessCreateState() const
Gets a child of the base in the CREATING state.
Definition f_base.cpp:465
MAIN_STATE_e
The possible operation results.
Definition f_base.hpp:135
@ ERROR
The operation could not be completed.
Definition f_base.hpp:137
@ SUCCESS
The operation was completed successfully.
Definition f_base.hpp:138
@ CANCELED
The operation was canceled early.
Definition f_base.hpp:136
@ WAITING
The operation is waiting for something and cannot be completed yet.
Definition f_base.hpp:139
static ProfileName m_tmpCtProfName
Temporary storage for the next constructed base's profile name. See mProfName.
Definition f_base.hpp:377
virtual int preCreate()
pre method for the create operation.
Definition f_base.cpp:92
static int(* sLoadAsyncCallback)()
[Unused]. See Unused Content.
Definition f_base.hpp:371
virtual int draw()
do method for the draw operation.
Definition f_base.cpp:188
virtual int preDelete()
pre method for the delete operation.
Definition f_base.cpp:126
fLiMgBa_c mUnusedList
[Unused]. See Unused Content.
Definition f_base.hpp:194
bool mDeferExecute
If the create operation was completed, but scheduling the execute and draw operations isn't possible ...
Definition f_base.hpp:174
static fBase_c * createChild(ProfileName profName, fBase_c *parent, unsigned long param, u8 groupType)
Creates a child base under the given parent.
Definition f_base.cpp:511
static fBaseID_e m_rootUniqueID
Unique ID counter for base construction. See mUniqueID.
Definition f_base.hpp:375
int createPack()
Executes the create operation. See commonPack.
Definition f_base.cpp:122
void runCreate()
Kickstarts the base's lifecycle by running the create operation.
Definition f_base.cpp:450
EGG::FrmHeap * mpHeap
[Unused]. The base's dedicated heap.
Definition f_base.hpp:196
virtual ~fBase_c()
Destroys the base.
Definition f_base.cpp:57
fBase_c * getConnectChild() const
Gets the base's first child.
Definition f_base.cpp:310
fBase_c * getConnectBrNext() const
Gets the base's next sibling.
Definition f_base.cpp:317
void deleteRequest()
Requests deletion of the base.
Definition f_base.cpp:289
int connectProc()
Executes the connect operation.
Definition f_base.cpp:212
virtual int create()
do method for the create operation.
Definition f_base.cpp:88
static fBase_c * fBase_make(ProfileName profName, fTrNdBa_c *connectParent, unsigned long param, u8 groupType)
Internal function for base construction.
Definition f_base.cpp:490
virtual int preExecute()
pre method for the execute operation.
Definition f_base.cpp:172
fManager_c mMng
The base's process manager.
Definition f_base.hpp:191
static u8 m_tmpCtGroupType
Temporary storage for the next constructed base's group type. See mGroupType.
Definition f_base.hpp:378
virtual bool entryFrmHeap(unsigned long size, EGG::Heap *parentHeap)
[Unused]. Creates a heap of the given size for the base.
Definition f_base.cpp:324
virtual bool createHeap()
[Unused]. [Does nothing].
Definition f_base.cpp:434
virtual void postCreate(MAIN_STATE_e state)
post method for the create operation.
Definition f_base.cpp:96
static u32 m_tmpCtParam
Temporary storage for the next constructed base's params. See mParam.
Definition f_base.hpp:376
ProfileName mProfName
The base's profile name.
Definition f_base.hpp:162
bool checkChildProcessCreateState() const
Checks if the base has at least one child in the CREATING state.
Definition f_base.cpp:479
bool mDeferRetryCreate
If the create operation has not been completed, and rescheduling it isn't possible at this time.
Definition f_base.hpp:179
fBaHelper_c * mpUnusedHelper
[Unused]. See Unused Content.
Definition f_base.hpp:193
@ CREATING
The base's create operation has yet to conclude.
Definition f_base.hpp:122
@ DELETING
The base's delete operation is about to run.
Definition f_base.hpp:124
@ ACTIVE
The base is in the main execution cycle.
Definition f_base.hpp:123
bool mDeleteRequested
If deletion of the base was requested, but the corresponding operation has not been scheduled yet.
Definition f_base.hpp:169
virtual void postExecute(MAIN_STATE_e state)
post method for the execute operation.
Definition f_base.cpp:180
virtual int preDraw()
pre method for the draw operation.
Definition f_base.cpp:192
void clearProcControlFlag(u8 flag)
Clears a flag in mProcControl.
Definition f_base.hpp:189
int deletePack()
Executes the delete operation. See commonPack.
Definition f_base.cpp:164
virtual int execute()
do method for the execute operation.
Definition f_base.cpp:168
void setProcControlFlag(u8 flag)
Sets a flag in mProcControl.
Definition f_base.hpp:187
int executePack()
Executes the execute operation. See commonPack.
Definition f_base.cpp:184
static fBase_c * createRoot(ProfileName profName, unsigned long param, u8 groupType)
Creates a root base.
Definition f_base.cpp:518
@ DISABLE_DRAW
Drawing is disabled.
Definition f_base.hpp:154
@ ROOT_DISABLE_EXECUTE
Execution is disabled, and this is a root base.
Definition f_base.hpp:151
@ DISABLE_EXECUTE
Execution is disabled.
Definition f_base.hpp:152
@ ROOT_DISABLE_DRAW
Drawing is disabled, and this is a root base.
Definition f_base.hpp:153
virtual bool entryFrmHeapNonAdjust(unsigned long size, EGG::Heap *parentHeap)
[Unused]. Creates a heap of the given size for the base.
Definition f_base.cpp:408
u8 mLifecycleState
The base's lifecycle state. Value is a LIFECYCLE_e.
Definition f_base.hpp:165
virtual void postDraw(MAIN_STATE_e state)
post method for the draw operation.
Definition f_base.cpp:200
virtual void postDelete(MAIN_STATE_e state)
post method for the delete operation.
Definition f_base.cpp:142
fBase_c * getConnectParent() const
Gets the base's parent.
Definition f_base.cpp:303
@ NOT_READY
The step could not completed at this time.
Definition f_base.hpp:144
@ SUCCEEDED
The step was completed successfully.
Definition f_base.hpp:145
int drawPack()
Executes the draw operation. See commonPack.
Definition f_base.cpp:204
static void setTmpCtData(ProfileName profName, fTrNdBa_c *connectParent, unsigned long param, u8 groupType)
Sets temporary data to be used for the next base's construction.
Definition f_base.cpp:483
virtual void deleteReady()
Informs the base that it's about to be deleted.
Definition f_base.cpp:208
static fTrNdBa_c * m_tmpCtConnectParent
Temporary storage for the next constructed base's parent connect node.
Definition f_base.hpp:379
virtual int doDelete()
do method for the delete operation.
Definition f_base.cpp:118
static void(* sUnloadCallback)()
[Unused]. See Unused Content.
Definition f_base.hpp:372
bool isProcControlFlag(u8 flag) const
Checks if a flag is set in mProcControl.
Definition f_base.hpp:185
fBase_c()
Constructs a new base.
Definition f_base.cpp:15
bool addNode(fLiNdPrio_c *node)
Adds a node to the list, according to its priority.
Definition f_list.cpp:6
A base list node.
Definition f_list_nd.hpp:11
void removeSelf()
Removes this node from the owner's fBase_c::mUnusedList mUnusedList.
Definition f_list.cpp:68
A base list node, with priority fields for reordering.
u16 mNewOrder
The priority the node should change to if it differs from mOrder.
u16 mOrder
The priority of this node. Lower values mean higher priority.
static fLiMgPTMF_c m_drawManage
A list of all the bases scheduled for drawing.
static fTrMgPTMF_c m_connectManage
A tree that connects all loaded bases.
static fLiMgBa_c m_searchManage[8]
An array of lists used for base lookup.
static LOOP_PROC_e m_nowLoopProc
The current operation being globally executed. See mainLoop.
static fLiMgPTMF_c m_executeManage
A list of all the bases scheduled for execution.
int getSearchTableNum()
Gets the index of the search list the owning base was added to. See m_searchManage.
Definition f_manager.cpp:14
static fLiMgPTMF_c m_deleteManage
A list of all the bases scheduled for deletion.
fLiNdPrio_c mDrawNode
The node in the draw list.
fTrNdBa_c mConnectNode
The node in the connect tree.
static fLiMgPTMF_c m_createManage
A list of all the bases scheduled for creation.
fLiNdBa_c mSearchNode
The node in the search lists.
fLiNdPrio_c mMainNode
The node in the create, execute or delete list.
A base tree node.
Definition f_tree_nd.hpp:12
fBase_c * mpOwner
The owner of this node.
Definition f_tree_nd.hpp:45
fTrNdBa_c * getTreeNextNotChild() const
Gets the next node in preorder traversal order, excluding the node's children.
Definition f_tree_nd.hpp:25
fTrNdBa_c * getTreeNext() const
Gets the next node in preorder traversal order.
Definition f_tree_nd.hpp:20
fBaseID_e
A unique identifier for each base.
Definition f_base_id.hpp:6
@ BASE_ID_MAX
The maximum identifier value.
Definition f_base_id.hpp:9
@ BASE_ID_FIRST
The starting identifier value.
Definition f_base_id.hpp:8
u16 ProfileName
The name of a profile. Value is a fProfile::PROFILE_NAME_e.
Definition f_profile.hpp:32
const fBaseProfile_c *(* sProfileList)[PROFILE_COUNT]
A list of all profiles.
Definition f_profile.cpp:5
A set of basic information needed to construct a generic base.
Definition f_profile.hpp:52
u16 mDrawOrder
The draw priority of the base. Lower values mean higher priority.
Definition f_profile.hpp:55
u16 mExecuteOrder
The execution priority of the base. Lower values mean higher priority.
Definition f_profile.hpp:54