NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
d_res.hpp
1#pragma once
2#include <types.h>
3#include <lib/rvl/arc/ARC.h>
4#include <lib/egg/heap/eggHeap.hpp>
5#include <lib/egg/heap/eggFrmHeap.hpp>
6#include <lib/egg/archive.hpp>
7#include <game/mLib/m_dvd.h>
8
9/**
10 * @brief An archive resource management class.
11 * @ingroup bases
12 * @details
13 * The dRes_c class manages resource archives ( @p \.arc files). It does so by storing multiple
14 * @ref info_c "archive holders". The class is instantiated automatically by dResMng_c, whose usage is
15 * recommended for basic resource loading.
16 *
17 * ## Path Notes
18 * Resource paths are subject to the following restrictions:
19 * - The @p \.arc extension is appended automatically to archive names and therefore must not be included.
20 * - The @p / character is prepended automatically to archive paths and therefore must not be included.
21 * - Archive names (excluding the file extension) cannot exceed 32 characters.
22 * - Full paths to archive files (including the appended extension and prepended slash) cannot exceed 80
23 * characters.
24 * - Full paths to resources inside an archive should not exceed 250 characters.
25 *
26 * ## Opening Archives
27 * Use the ::setRes function to open an archive. For opening multiple archives at once, see
28 * @ref dResMng_c::setRes "the dResMng_c equivalent". Only up to ::mNumArcs archives can be open at the same
29 * time.
30 *
31 * @note Many kinds of assets are loaded automatically, therefore doing so manually is not necessary.
32 * These include:
33 * - Stages
34 * - Tilesets
35 * - Backgrounds
36 * - Actor resources
37 * - Worldmaps and their resources
38 *
39 * ### Notes for BRRES Resources
40 * The game automatically handles the initialization of any BRRES files within an archive, as long as their
41 * parent directory is named @p g3d .
42 *
43 * ### Notes for Layout Resources
44 * For layout archives, it's recommended to use the
45 * @ref LytBase_c::ReadResource3 "dedicated LytBase_c functions" instead of this class.
46 *
47 * ## Loading Archives
48 * Use the ::syncAllRes function to perform the actual archive file loading. The function will return
49 * @p true until all opened archives are loaded successfully.
50 *
51 * ## Getting Archive Resources
52 * Use the ::getRes function to obtain a resource inside a specific archive once it has been loaded.
53 * Overloads are provided to obtain the size of the resource and optionally detect compressed resources.
54 *
55 * If the file could not be found under the archive, a warning is printed to the console.
56 * Use ::getResSilently if this behaviour is undesired (such as with an optional file).
57 *
58 * @note No overload for ::getResSilently with compression support is available.
59 *
60 * ### Compressed Resources
61 * While the @ref getRes(const char*, const char*, unsigned long*, int*) const "getRes" function can detect
62 * compression and return the decompressed data size, it does not actually perform the decompression itself.
63 * This can be achieved by calling the @ref copyRes(const void*, void*, int, int) "copyRes" function with
64 * the compressed data and the compression type returned by the previous function, plus a buffer to store
65 * the decompressed data into.
66 *
67 * @note Only LZ77 compression is supported.
68 *
69 * ## Deleting Archives
70 * Use the ::deleteRes function to mark an archive as no longer needed by the calling entity.
71 * This ensures that archives no longer in use are properly disposed of.
72 *
73 * ## Unused Content
74 * - ::mSetCallback is an unused callback for when an archive is added to the class. It was probably
75 * used to debug resource loading.
76 */
77class dRes_c {
78public:
79
80 /// @brief A callback class for processing resources.
81 /// @details The calls to ::execute occur during the initial loading of an archive.
82 class callback_c {
83 public:
84 /// @brief Initializes the callback with the resource name.
85 virtual void init(const char *name) = 0;
86
87 /**
88 * @brief Executes the callback.
89 * @param data The resource data.
90 * @param folderSig The first 4 characters of the folder name.
91 * @param path The path to the current resource.
92 * @return The resource data.
93 */
94 virtual void *execute(void *data, u32 folderSig, const char* path) = 0;
95 };
96
97 /// @brief A callback class for EGG::Archive::searchInside.
98 /// @unofficial
100 public:
101 /// @brief Constructs a new searchCallback_c.
102 searchCallback_c(callback_c *callback, u8 **files, int numFiles, int fileIdx, u32 folderSig) :
104 mpFiles(files),
105 mNumFiles(numFiles),
106 mFileIdx(fileIdx),
107 mFolderSig(folderSig) {
108 }
109
110 /// @brief The callback function.
111 static void callback(void *cbInfo, void *file, const ARCDirEntry *dirEntry, const char *path);
112
113 private:
114 /// @brief The internal callback function.
115 void callback(void *file, const ARCDirEntry *dirEntry, const char *path);
116
117 callback_c *mpCallback; ///< The file processing callback.
118 u8 **mpFiles; ///< An array of pointers to the data of each loaded resource.
119 int mNumFiles; ///< The number of files in ::mpFiles.
120 unsigned int mFileIdx; ///< The index of the current file in ::mpFiles.
121 u32 mFolderSig; ///< The first 4 characters of the current folder.
122 };
123
124 /**
125 * @brief An archive holder.
126 * @details
127 * info_c is a high-level interface to resource archives ( @p \.arc files). It is generally not accessed
128 * directly, but is managed by the outer dRes_c class. It wraps the functionalities of
129 * mDvd_mountMemArchive_c and EGG::Archive to simplify the loading and iteration of resource archives.
130 *
131 * ## Loading an Archive
132 * Use the ::set function to manually schedule an archive for loading. If successful, a
133 * @ref mpDvdCmd "file loading command" is generated and queued to continue the loading process
134 * in the background.
135 *
136 * ## Checking Progress
137 * Use the ::setRes function to query the @ref LOAD_STATUS_e "archive's loading state". Once the
138 * loading process is completed, the @ref mpDvdCmd "command" is deleted and the
139 * @ref mpFiles "archive's resource list" is built using the provided callback.
140 *
141 * ## Archive Disposal
142 * Each archive holder features a @ref ::mRefCount "reference count", which acts as a garbage disposal
143 * mechanism: each time the archive is requested the count increases, while it decreases when its deletion
144 * is requested. When the counter reaches zero (or the holder is deleted), the archive is automatically
145 * @ref cleanup "disposed".
146 */
147 class info_c {
148 public:
149
150 /// @brief The loading status of the archive.
152 LOAD_ERROR = -1, ///< An error occurred while loading the archive.
153 LOAD_SUCCESS = 0, ///< The archive was loaded successfully.
154 LOAD_IN_PROGRESS = 1, ///< The archive is currently being loaded.
155 };
156
157 info_c(); ///< Constructs a new archive holder.
158 ~info_c(); ///< Destroys the archive holder.
159
160 /// @brief Unmounts the archive and frees the holder for use.
161 /// @return Whether the operation was successful.
162 bool cleanup();
163
164 /**
165 * @brief Sets information about the archive to be loaded.
166 *
167 * @param arcName The name of the archive.
168 * @param containingFolder The path to the folder which the archive is in.
169 * @param allocDirection The allocation direction. See ::MEMExpHeapAllocDir.
170 * @param heap The heap to load the resources of the archive into, or @p nullptr to use the default heap.
171 * @return Whether the archive was prepared successfully and will be loaded.
172 */
173 bool set(const char *arcName, const char *containingFolder, u8 allocDirection, EGG::Heap *heap);
174
175 /**
176 * @brief Attempts to load the archive into memory and load the resources with a callback.
177 *
178 * @param callback The resource loaded callback, or @p nullptr .
179 * @return The result of the operation.
180 */
182
183 const char *getName() const { return mName; }
184 int getRefCount() const { return mRefCount; }
185
186 /// @brief Gets the file loading command.
187 /// @return The file loading command, or @p nullptr if the archive has already been loaded
188 /// or the holder is empty.
190
191 /// @brief Gets the archive accessor.
192 /// @return The archive accessor, or @p nullptr if the archive has not yet been loaded
193 /// or the holder is empty.
194 EGG::Archive *getArchive() const { return mpArchive; }
195
196 void incRefCount() { mRefCount++; } ///< Increments the reference count.
197 void decRefCount() { mRefCount--; } ///< Decrements the reference count.
198
199 private:
200
201 /**
202 * @brief Builds the resource list and executes a callback on each file and directory.
203 * @param callback The resource loaded callback, or @p nullptr .
204 * @return The result of the operation.
205 */
207
208 char mName[0x20]; ///< The name of the archive.
209 u16 mRefCount; ///< The number of references to this archive.
210 mDvd_mountMemArchive_c *mpDvdCmd; ///< The DVD command for mounting the archive.
211 EGG::Archive *mpArchive; ///< The accessor for this archive.
212 EGG::Heap *mpMountHeap; ///< The heap used for mounting the archive.
213 void *mpArcBinary; ///< The raw archive data.
214 int mArchiveSize; ///< The archive size.
215
216 /// @brief The heap used for loading the resources of the archive.
217 /// @decompnote{No p because of the string "dRes_c::info_c::mDataHeap"}
219
220 u8 **mpFiles; ///< An array of pointers to the data of each loaded resource.
221 };
222
223 dRes_c(); ///< Constructs a new manager.
224 ~dRes_c(); ///< Destroys the manager.
225
226 /**
227 * @brief Initializes the manager by allocating the archive holders and setting the callback.
228 *
229 * @param maxCount The number of archive holders to allocate.
230 * @param callback The resource loaded callback.
231 * @return Whether the initialization was successful.
232 */
233 bool init(u16 maxCount, callback_c *callback);
234
235 /**
236 * @brief Schedules an archive for loading.
237 * @param arcName The name of the archive to load. See the [path notes](#path-notes).
238 * @param containingFolder The path to the folder the archive is in. See the [path notes](#path-notes).
239 * @param allocDir The allocation direction. See ::MEMExpHeapAllocDir.
240 * @param heap The heap to load the archive into, or @p nullptr to use the default archive heap.
241 * @return Whether the operation was successful.
242 */
243 bool setRes(const char *arcName, const char *containingFolder, u8 allocDir, EGG::Heap *heap);
244
245 /**
246 * @brief Marks an archive as no longer needed.
247 *
248 * @param arcName The name of the archive to unload. See the [path notes](#path-notes).
249 * @return Whether the operation was successful.
250 */
251 bool deleteRes(const char *arcName);
252
253 /**
254 * @brief Gets a resource.
255 *
256 * @param arcName The name of the archive which contains the resource. See the [path notes](#path-notes).
257 * @param resPath The path to the resource within the archive. See the [path notes](#path-notes).
258 * @return A pointer to the contents of the resource.
259 */
260 void *getRes(const char *arcName, const char *resPath) const;
261
262 /**
263 * @brief Gets a resource.
264 *
265 * @param arcName The name of the archive which contains the resource. See the [path notes](#path-notes).
266 * @param resPath The path to the resource within the archive. See the [path notes](#path-notes).
267 * @param size A pointer where the size of the resource will be written to.
268 * @return A pointer to the contents of the resource.
269 */
270 void *getRes(const char *arcName, const char *resPath, unsigned long *size) const;
271
272 /**
273 * @brief Gets a resource which may optionally be compressed.
274 * @details If the resource is available in both compressed and uncompressed form, the latter is
275 * prioritized. Only LZ77 compression is supported (the resource must be named @p <resPath>\.LZ
276 * for it to be found).
277 *
278 * @param arcName The name of the archive which contains the resource. See the [path notes](#path-notes).
279 * @param resPath The path to the resource within the archive. See the [path notes](#path-notes).
280 * @param size A pointer where the uncompressed size of the resource will be written to, or @p nullptr .
281 * @param compressionType A pointer where the compression type of the resource will be written to, or
282 * @p nullptr . See ::CXCompressionType.
283 * @return A pointer to the compressed contents of the resource.
284 */
285 void *getRes(const char *arcName, const char *resPath, unsigned long *size, int *compressionType) const;
286
287 /// @brief Gets a resource without logging a message if the resource is not found.
288 /// @see ::getRes(const char*, const char*) const
289 void *getResSilently(const char *arcName, const char *resPath) const;
290
291 /// @brief Gets a resource without logging a message if the resource is not found.
292 /// @see ::getRes(const char*, const char*, unsigned long*) const
293 void *getResSilently(const char *arcName, const char *resPath, unsigned long *size) const;
294
295 /// @brief Attempts to load the resources of an archive that has finished loading since the last call to this function. The callback is executed on all files and folders.
296 /// @return Whether such an archive was found.
297 bool syncAllRes();
298
299private:
300 /**
301 * @brief Gets the holder for an archive.
302 * @param arcName The name of the archive.
303 * @return The holder for the archive, or @p nullptr if the holder doesn't exist.
304 */
305 info_c *getResInfo(const char *arcName) const;
306
307 /**
308 * @brief Gets the holder for a loaded archive.
309 * @param arcName The name of the archive.
310 * @return The holder for the archive, or @p nullptr if the holder doesn't exist or the archive
311 * hasn't been loaded into memory yet.
312 */
313 info_c *getResInfoLoaded(const char *arcName) const;
314
315 /// @brief Gets a free archive holder that can be used to store an archive reference.
316 /// @return The free archive holder, or @p nullptr if none is available.
318
319public:
320 /// @brief Copies an uncompressed resource.
321 static void copyRes(const void *from, void *to, int size);
322
323 /// @brief Copies an optionally compressed resource.
324 /// @param size The size of the data. Only used for uncompressed resources.
325 /// @param compressionType The compression type. See ::CXCompressionType for the possible values.
326 static void copyRes(const void *from, void *to, int size, int compressionType);
327
328private:
329 info_c *mpArcInfos; ///< An array of archive holders.
330 u16 mNumArcs; ///< The number of archive holders.
331 callback_c *mpCallback; ///< The callback for when a resource is loaded.
332
333 /// @unused The callback for when an archive is scheduled for loading.
334 static void (*mSetCallback)(const char *arcName, EGG::Heap *heap);
335};
A callback class for processing resources.
Definition d_res.hpp:82
virtual void init(const char *name)=0
Initializes the callback with the resource name.
virtual void * execute(void *data, u32 folderSig, const char *path)=0
Executes the callback.
An archive holder.
Definition d_res.hpp:147
EGG::Archive * mpArchive
The accessor for this archive.
Definition d_res.hpp:211
bool set(const char *arcName, const char *containingFolder, u8 allocDirection, EGG::Heap *heap)
Sets information about the archive to be loaded.
mDvd_mountMemArchive_c * getDvdCmd() const
Gets the file loading command.
Definition d_res.hpp:189
~info_c()
Destroys the archive holder.
LOAD_STATUS_e
The loading status of the archive.
Definition d_res.hpp:151
@ LOAD_IN_PROGRESS
The archive is currently being loaded.
Definition d_res.hpp:154
@ LOAD_SUCCESS
The archive was loaded successfully.
Definition d_res.hpp:153
@ LOAD_ERROR
An error occurred while loading the archive.
Definition d_res.hpp:152
info_c()
Constructs a new archive holder.
Definition d_res_info.cpp:7
EGG::Heap * mpMountHeap
The heap used for mounting the archive.
Definition d_res.hpp:212
mDvd_mountMemArchive_c * mpDvdCmd
The DVD command for mounting the archive.
Definition d_res.hpp:210
void decRefCount()
Decrements the reference count.
Definition d_res.hpp:197
char mName[0x20]
The name of the archive.
Definition d_res.hpp:208
void * mpArcBinary
The raw archive data.
Definition d_res.hpp:213
u8 ** mpFiles
An array of pointers to the data of each loaded resource.
Definition d_res.hpp:220
int mArchiveSize
The archive size.
Definition d_res.hpp:214
void incRefCount()
Increments the reference count.
Definition d_res.hpp:196
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:218
u16 mRefCount
The number of references to this archive.
Definition d_res.hpp:209
EGG::Archive * getArchive() const
Gets the archive accessor.
Definition d_res.hpp:194
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.
searchCallback_c(callback_c *callback, u8 **files, int numFiles, int fileIdx, u32 folderSig)
Constructs a new searchCallback_c.
Definition d_res.hpp:102
unsigned int mFileIdx
The index of the current file in mpFiles.
Definition d_res.hpp:120
callback_c * mpCallback
The file processing callback.
Definition d_res.hpp:117
u32 mFolderSig
The first 4 characters of the current folder.
Definition d_res.hpp:121
u8 ** mpFiles
An array of pointers to the data of each loaded resource.
Definition d_res.hpp:118
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:119
~dRes_c()
Destroys the manager.
Definition d_res.cpp:13
info_c * newResInfo()
Gets a free archive holder that can be used to store an archive reference.
Definition d_res.cpp:206
u16 mNumArcs
The number of archive holders.
Definition d_res.hpp:330
dRes_c()
Constructs a new manager.
Definition d_res.cpp:7
static void copyRes(const void *from, void *to, int size)
Copies an uncompressed resource.
Definition d_res.cpp:130
info_c * getResInfoLoaded(const char *arcName) const
Gets the holder for a loaded archive.
Definition d_res.cpp:218
static void(* mSetCallback)(const char *arcName, EGG::Heap *heap)
[Unused]. The callback for when an archive is scheduled for loading.
Definition d_res.hpp:334
callback_c * mpCallback
The callback for when a resource is loaded.
Definition d_res.hpp:331
bool syncAllRes()
Attempts to load the resources of an archive that has finished loading since the last call to this fu...
Definition d_res.cpp:181
bool deleteRes(const char *arcName)
Marks an archive as no longer needed.
Definition d_res.cpp:50
void * getRes(const char *arcName, const char *resPath) const
Gets a resource.
Definition d_res.cpp:64
info_c * mpArcInfos
An array of archive holders.
Definition d_res.hpp:329
void * getResSilently(const char *arcName, const char *resPath) const
Gets a resource without logging a message if the resource is not found.
Definition d_res.cpp:142
bool setRes(const char *arcName, const char *containingFolder, u8 allocDir, EGG::Heap *heap)
Schedules an archive for loading.
Definition d_res.cpp:32
bool init(u16 maxCount, callback_c *callback)
Initializes the manager by allocating the archive holders and setting the callback.
Definition d_res.cpp:21
info_c * getResInfo(const char *arcName) const
Gets the holder for an archive.
Definition d_res.cpp:194