NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
d_res.cpp
1#include <dol/bases/d_res.hpp>
2#include <lib/MSL_C/string.h>
3#include <lib/rvl/cx/cx.h>
4
5void (*dRes_c::mSetCallback)(const char *arcName, EGG::Heap *heap);
6
8 mpArcInfos(nullptr),
9 mNumArcs(0),
10 mpCallback(nullptr) {
11}
12
14 if (mpArcInfos != nullptr) {
15 delete[] mpArcInfos;
16 mpArcInfos = nullptr;
17 mNumArcs = 0;
18 }
19}
20
21bool dRes_c::init(u16 maxCount, callback_c *callback) {
22 mpArcInfos = new info_c[maxCount];
23 if (!mpArcInfos) {
24 return false;
25 }
26 mNumArcs = maxCount;
27 mpCallback = callback;
28
29 return true;
30}
31
32bool dRes_c::setRes(const char *arcName, const char *containingFolder, u8 allocDir, EGG::Heap *heap) {
33 // First try to find an existing instance of the archive
34 info_c *info = getResInfo(arcName);
35 if (info == nullptr) {
36 // We need a new instance
37 info = newResInfo();
38 if (info == nullptr) {
39 return false;
40 }
41 if (!info->set(arcName, containingFolder, allocDir, heap)) {
42 info->cleanup();
43 return false;
44 }
45 }
46 info->incRefCount();
47 return true;
48}
49
50bool dRes_c::deleteRes(const char *arcName) {
51 info_c *info = getResInfo(arcName);
52 if (info == nullptr) {
53 return false;
54 }
55
56 info->decRefCount();
57 if (info->getRefCount() == 0) {
58 // Archive not needed anymore
59 info->cleanup();
60 }
61 return true;
62}
63
64void *dRes_c::getRes(const char *arcName, const char *resPath) const {
65 void *data = nullptr;
66 info_c *info = getResInfoLoaded(arcName);
67 if (info != nullptr && info->getArchive() != nullptr) {
68 data = info->getArchive()->getFile(resPath, nullptr);
69 }
70 return data;
71}
72
73void *dRes_c::getRes(const char *arcName, const char *resPath, unsigned long *size) const {
74 void *data = nullptr;
75 int newSize = 0;
76 info_c *info = getResInfoLoaded(arcName);
77 if (info != nullptr && info->getArchive() != nullptr) {
78 EGG::Archive *archive = info->getArchive();
79 EGG::Archive::FileInfo fi = { 0, 0 };
80 data = archive->getFile(resPath, &fi);
81 newSize = fi.mFileSize;
82 }
83 *size = newSize;
84 return data;
85}
86
87void *dRes_c::getRes(const char *arcName, const char *resPath, unsigned long *size, int *compressionType) const {
88 void *data = nullptr;
89 int newSize = 0;
90 info_c *info = getResInfoLoaded(arcName);
91 if (info != nullptr && info->getArchive() != nullptr) {
92 EGG::Archive *archive = info->getArchive();
93 long entryID = archive->convertPathToEntryID(resPath);
94 if (entryID >= 0) {
95 // Resource exists
96 EGG::Archive::FileInfo fi = { 0, 0 };
97 data = archive->getFileFast(entryID, &fi);
98
99 if (data != nullptr) {
100 if (compressionType != nullptr) {
101 *compressionType = 0;
102 }
103 if (size != nullptr) {
104 *size = fi.mFileSize;
105 }
106 }
107 } else {
108 // Resource not found, try with .LZ extension
109 char path[256];
110 snprintf(path, sizeof(path), "%s.LZ", resPath);
111 entryID = archive->convertPathToEntryID(path);
112
113 if (entryID >= 0) {
114 data = archive->getFileFast(entryID, nullptr);
115
116 if (data != nullptr) {
117 if (compressionType != nullptr) {
118 *compressionType = ((u8 *) data)[0] & 0xF0;
119 }
120 if (size != nullptr) {
121 *size = CXGetUncompressedSize(data);
122 }
123 }
124 }
125 }
126 }
127 return data;
128}
129
130 void dRes_c::copyRes(const void *from, void *to, int size) {
131 memcpy(to, from, size);
132}
133
134 void dRes_c::copyRes(const void *from, void *to, int size, int compressionType) {
135 if (compressionType == 0) {
136 copyRes(from, to, size);
137 } else {
138 CXUncompressLZ(from, to);
139 }
140}
141
142void *dRes_c::getResSilently(const char *arcName, const char *resPath) const {
143 void *data = nullptr;
144
145 info_c *info = getResInfoLoaded(arcName);
146 if (info != nullptr && info->getArchive() != nullptr) {
147 EGG::Archive *archive = info->getArchive();
148 long entryID = archive->convertPathToEntryID(resPath);
149
150 if (entryID >= 0) {
151 // Resource exists, load it
152 data = archive->getFileFast(entryID, nullptr);
153 }
154 }
155
156 return data;
157}
158
159void *dRes_c::getResSilently(const char *arcName, const char *resPath, unsigned long *size) const {
160 void *data = nullptr;
161 int newSize = 0;
162
163 info_c *info = getResInfoLoaded(arcName);
164 if (info != nullptr && info->getArchive() != nullptr) {
165 EGG::Archive *archive = info->getArchive();
166 long entryID = archive->convertPathToEntryID(resPath);
167
168 if (entryID >= 0) {
169 // Resource exists, load it
170 EGG::Archive::FileInfo fi = { 0, 0 };
171 data = archive->getFileFast(entryID, &fi);
172 newSize = fi.mFileSize;
173 }
174 }
175
176 *size = newSize;
177
178 return data;
179}
180
182 info_c *info = &mpArcInfos[0];
183 for (int i = 0; i < mNumArcs; i++) {
184 if (info->getDvdCmd() != nullptr) {
185 if (info->setRes(mpCallback) > 0) {
186 return true;
187 }
188 }
189 info++;
190 }
191 return false;
192}
193
194dRes_c::info_c *dRes_c::getResInfo(const char *arcName) const {
195 int count = mNumArcs; // [Needed for matching]
196 info_c *info = &mpArcInfos[0];
197 for (int i = 0; i < count; i++) {
198 if (info->getRefCount() > 0 && strcmp(arcName, info->getName()) == 0) {
199 return info;
200 }
201 info++;
202 }
203 return nullptr;
204}
205
207 info_c *info = &mpArcInfos[0];
208 for (int i = 0; i < mNumArcs; i++) {
209 // An info_c is free if it has no references
210 if (info->getRefCount() == 0) {
211 return info;
212 }
213 info++;
214 }
215 return nullptr;
216}
217
218dRes_c::info_c *dRes_c::getResInfoLoaded(const char *arcName) const {
219 info_c *info = getResInfo(arcName);
220 if (info == nullptr) {
221 return nullptr;
222 } else if (info->getArchive() == nullptr) {
223 return nullptr;
224 }
225 return info;
226}
A callback class for processing resources.
Definition d_res.hpp:17
A class that holds information about an archive.
Definition d_res.hpp:59
bool set(const char *arcName, const char *containingFolder, u8 allocDirection, EGG::Heap *heap)
Sets information about the archive to be loaded.
void decRefCount()
Decrements the reference count.
Definition d_res.hpp:93
void incRefCount()
Increments the reference count.
Definition d_res.hpp:92
int setRes(callback_c *callback)
Attempts to load the archive into memory and load the resources with a callback.
bool cleanup()
Unmounts the archive and frees the holder for use.
~dRes_c()
Destroys this dRes_c.
Definition d_res.cpp:13
info_c * newResInfo()
Gets a free info_c 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:220
dRes_c()
Constructs a new dRes_c.
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 info_c for an archive, if it exists and has been loaded into memory.
Definition d_res.cpp:218
static void(* mSetCallback)(const char *arcName, EGG::Heap *heap)
[Unused]. The callback for when dRes_c::info_c::set is called.
Definition d_res.hpp:224
callback_c * mpCallback
The callback for when a resource is loaded.
Definition d_res.hpp:221
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 the archive as no longer needed.
Definition d_res.cpp:50
void * getRes(const char *arcName, const char *resPath) const
Loads a resource.
Definition d_res.cpp:64
info_c * mpArcInfos
An array of archive holders.
Definition d_res.hpp:219
void * getResSilently(const char *arcName, const char *resPath) const
Loads 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)
Registers an archive to be loaded next.
Definition d_res.cpp:32
bool init(u16 maxCount, callback_c *callback)
Initializes the dRes_c.
Definition d_res.cpp:21
info_c * getResInfo(const char *arcName) const
Gets the info_c for an archive, if it exists.
Definition d_res.cpp:194