NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
d_res_info.cpp
1#include <game/bases/d_res.hpp>
2#include <game/mLib/m_heap.hpp>
3#include <revolution/VI.h>
4#include <string.h>
5
7 mRefCount(0),
8 mpDvdCmd(nullptr),
9 mpArchive(nullptr),
10 mpMountHeap(nullptr),
11 mpArcBinary(nullptr),
12 mDataHeap(nullptr),
13 mpFiles(nullptr) {
14}
15
17 if (!mpDvdCmd->mDone) {
18 // Wait until the command is done
19 do {
20 VIWaitForRetrace();
21 } while (!mpDvdCmd->mDone);
22 }
23 cleanup();
24}
25
27 // Clean up the DVD command
28 if (mpDvdCmd != nullptr) {
29 if (!mpDvdCmd->mDone) {
30 return false;
31 }
32 mpArchive = mpDvdCmd->mpArchive;
33 mpArcBinary = mpDvdCmd->getArcBinary();
34 mpMountHeap = mpDvdCmd->mpHeap;
35 mArchiveSize = mpDvdCmd->mArchiveSize;
36 mpDvdCmd->destroy();
37
38 mpDvdCmd = nullptr;
39 }
40
41 // Clean up the archive and its associated heap
42 if (mpArchive != nullptr) {
43 if (mDataHeap != nullptr) {
44 mHeap::destroyFrmHeap(mDataHeap);
45 mDataHeap = nullptr;
46 }
47 mpArchive->unmount();
48
49 mpArchive = nullptr;
50 mpFiles = nullptr;
51 }
52
53 // Free the archive binary
54 if (mpArcBinary != nullptr) {
55 EGG::Heap::free(mpArcBinary, nullptr);
56
57 mpArcBinary = nullptr;
58 }
59 return true;
60}
61
62bool dRes_c::info_c::set(const char *arcName, const char *containingFolder, u8 allocDir, EGG::Heap *heap) {
63 char pathBuf[80];
64 snprintf(pathBuf, sizeof(pathBuf), "/%s/%s.arc", containingFolder, arcName);
65 mpDvdCmd = mDvd_mountMemArchive_c::create(pathBuf, allocDir, heap);
66
67 if (mpDvdCmd == nullptr) {
68 return false;
69 }
70
71 strncpy(mName, arcName, sizeof(mName));
72 if (mSetCallback != nullptr) {
73 mSetCallback(pathBuf, heap);
74 }
75 return true;
76}
77
79 if (mpArchive == nullptr) {
80 if (mpDvdCmd == nullptr) {
81 return LOAD_ERROR;
82 }
83 if (!mpDvdCmd->mDone) {
84 return LOAD_IN_PROGRESS;
85 }
86
87 // Copy over the properties from the DVD command, then destroy it
88 mpArchive = mpDvdCmd->mpArchive;
89 mpArcBinary = mpDvdCmd->getArcBinary();
90 mpMountHeap = mpDvdCmd->mpHeap;
91 mArchiveSize = mpDvdCmd->mArchiveSize;
92 mpDvdCmd->destroy();
93 mpDvdCmd = nullptr;
94
95 if (mpArchive == nullptr) {
96 return LOAD_ERROR;
97 }
98
99 // Prepare the heap for the archive data
100 EGG::Heap *heap = (mpMountHeap != nullptr) ? mpMountHeap : mHeap::g_gameHeaps[0];
101 mDataHeap = mHeap::makeFrmHeapAndUpdate(-1, heap, "dRes_c::info_c::mDataHeap", 0x20, 0);
102 if (mDataHeap == nullptr) {
103 return LOAD_ERROR;
104 }
105
106 LOAD_STATUS_e resStatus = loadRes(callback);
107
108 // Restore the previous heap
109 mHeap::restoreCurrentHeap();
110 mHeap::adjustFrmHeap(mDataHeap);
111 if (resStatus == LOAD_ERROR) {
112 return resStatus;
113 }
114
115 // Ensure data is written to main memory
116 DCStoreRangeNoSync(mDataHeap, (size_t) mDataHeap->mHeapHandle->end - (size_t) mDataHeap);
117 }
118
119 return LOAD_SUCCESS;
120}
121
122void dRes_c::searchCallback_c::callback(void *file, const ARCDirEntry *dirEntry, const char *path) {
123 if (dirEntry->isDir) {
124 // Copy the first 4 characters of the folder name and pad with spaces
125 const char *name = dirEntry->name;
126 mFolderSig = ' ';
127 int nameLen = strlen(name);
128 memcpy(&mFolderSig, name, (nameLen <= 4) ? nameLen : 4);
129 } else {
130 // Callback only called for files
131 u8 *cbRes = (u8 *) mpCallback->execute(file, mFolderSig, path);
132 if (mFileIdx < mNumFiles) {
133 mpFiles[mFileIdx++] = cbRes;
134 }
135 }
136}
137
138void dRes_c::searchCallback_c::callback(void *cbInfo, void *file, const ARCDirEntry *dirEntry, const char *path) {
139 ((searchCallback_c *) cbInfo)->callback(file, dirEntry, path);
140}
141
143 int numFiles = mpArchive->countFile();
144 mpFiles = new u8 *[numFiles];
145 if (mpFiles == nullptr) {
146 return LOAD_ERROR;
147 }
148
149 // Prepare the file array
150 for (unsigned int i = 0; i < numFiles; i++) {
151 mpFiles[i] = nullptr;
152 }
153
154 if (callback != nullptr) {
155 // Use the callback to populate ::mpFiles
156 callback->init(mName);
157 searchCallback_c searchCallback(callback, mpFiles, numFiles, 0, ' ');
158 mpArchive->searchInside(&dRes_c::searchCallback_c::callback, &searchCallback);
159 } else {
160 // Simply populate ::mpFiles with the files
161 mpArchive->getFileArray(mpFiles, numFiles);
162 }
163 return LOAD_SUCCESS;
164}
A callback class for processing resources.
Definition d_res.hpp:16
virtual void init(const char *name)=0
Initializes the callback with the resource name.
EGG::Archive * mpArchive
The accessor for this archive.
Definition d_res.hpp:123
bool set(const char *arcName, const char *containingFolder, u8 allocDirection, EGG::Heap *heap)
Sets information about the archive to be loaded.
~info_c()
Destroys the archive holder.
LOAD_STATUS_e
The loading status of the archive.
Definition d_res.hpp:63
@ LOAD_IN_PROGRESS
The archive is currently being loaded.
Definition d_res.hpp:66
@ LOAD_SUCCESS
The archive was loaded successfully.
Definition d_res.hpp:65
@ LOAD_ERROR
An error occurred while loading the archive.
Definition d_res.hpp:64
info_c()
Constructs a new archive holder.
Definition d_res_info.cpp:6
EGG::Heap * mpMountHeap
The heap used for mounting the archive.
Definition d_res.hpp:124
mDvd_mountMemArchive_c * mpDvdCmd
The DVD command for mounting the archive.
Definition d_res.hpp:122
char mName[0x20]
The name of the archive.
Definition d_res.hpp:120
void * mpArcBinary
The raw archive data.
Definition d_res.hpp:125
u8 ** mpFiles
An array of pointers to the data of each loaded resource.
Definition d_res.hpp:132
int mArchiveSize
The archive size.
Definition d_res.hpp:126
LOAD_STATUS_e loadRes(callback_c *callback)
Builds the resource list and executes a callback on each file and directory.
EGG::FrmHeap * mDataHeap
The heap used for loading the resources of the archive.
Definition d_res.hpp:130
u16 mRefCount
The number of references to this archive.
Definition d_res.hpp:121
bool cleanup()
Unmounts the archive and frees the holder for use.
LOAD_STATUS_e setRes(callback_c *callback)
Attempts to load the archive into memory and load the resources with a callback.
A callback class for EGG::Archive::searchInside.
Definition d_res.hpp:33
searchCallback_c(callback_c *callback, u8 **files, int numFiles, int fileIdx, u32 folderSig)
Constructs a new searchCallback_c.
Definition d_res.hpp:36
unsigned int mFileIdx
The index of the current file in mpFiles.
Definition d_res.hpp:54
callback_c * mpCallback
The file processing callback.
Definition d_res.hpp:51
u32 mFolderSig
The first 4 characters of the current folder.
Definition d_res.hpp:55
u8 ** mpFiles
An array of pointers to the data of each loaded resource.
Definition d_res.hpp:52
static void callback(void *cbInfo, void *file, const ARCDirEntry *dirEntry, const char *path)
The callback function.
int mNumFiles
The number of files in mpFiles.
Definition d_res.hpp:53
static void(* mSetCallback)(const char *arcName, EGG::Heap *heap)
The callback for when an archive is scheduled for loading.
Definition d_res.hpp:247