summaryrefslogtreecommitdiff
path: root/libs/JSystem/JKernel/JKRFileLoader.cpp
blob: c12ac92585a0cb0b448f59639f64f075d5873b4e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
//
// Generated By: dol2asm
// Translation Unit: JKRFileLoader
//

#include "JSystem/JKernel/JKRFileLoader.h"
#include "MSL_C/string.h"
#include "dol2asm.h"
#include "global.h"

//
// Forward References:
//

extern "C" void __ct__13JKRFileLoaderFv();
extern "C" void __dt__13JKRFileLoaderFv();
extern "C" void unmount__13JKRFileLoaderFv();
extern "C" void getGlbResource__13JKRFileLoaderFPCc();
extern "C" void getGlbResource__13JKRFileLoaderFPCcP13JKRFileLoader();
extern "C" void removeResource__13JKRFileLoaderFPvP13JKRFileLoader();
extern "C" void detachResource__13JKRFileLoaderFPvP13JKRFileLoader();
extern "C" void findVolume__13JKRFileLoaderFPPCc();
extern "C" void fetchVolumeName__13JKRFileLoaderFPclPCc();
extern "C" void __sinit_JKRFileLoader_cpp();
extern "C" void func_802D45E4(void* _this);
extern "C" extern char const* const JKRFileLoader__stringBase0;
extern "C" u8 sVolumeList__13JKRFileLoader[12];
extern "C" u8 sCurrentVolume__13JKRFileLoader[4 + 4 /* padding */];

//
// External References:
//

extern "C" void __dl__FPv();
extern "C" void __ct__11JKRDisposerFv();
extern "C" void __dt__11JKRDisposerFv();
extern "C" void __ct__10JSUPtrLinkFPv();
extern "C" void __dt__10JSUPtrLinkFv();
extern "C" void __dt__10JSUPtrListFv();
extern "C" void initiate__10JSUPtrListFv();
extern "C" void __register_global_object();
extern "C" void _savegpr_29();
extern "C" void _restgpr_29();
extern "C" extern u8 __lower_map[256];

//
// Declarations:
//

/* ############################################################################################## */
/* 80451418-80451420 000918 0004+04 2/2 3/3 0/0 .sbss            sCurrentVolume__13JKRFileLoader */
JKRFileLoader* JKRFileLoader::sCurrentVolume;
/* 80434354-80434360 061074 000C+00 5/5 14/14 0/0 .bss             sVolumeList__13JKRFileLoader */
JSUList<JKRFileLoader> JKRFileLoader::sVolumeList;

/* 802D40F0-802D4148 2CEA30 0058+00 0/0 2/2 0/0 .text            __ct__13JKRFileLoaderFv */
JKRFileLoader::JKRFileLoader(void)
    : mFileLoaderLink(this), mVolumeName(NULL), mVolumeType(0), mMountCount(0) {}

/* 802D4148-802D41D4 2CEA88 008C+00 1/0 2/2 0/0 .text            __dt__13JKRFileLoaderFv */
JKRFileLoader::~JKRFileLoader() {
    if (getCurrentVolume() == this) {
        setCurrentVolume(NULL);
    }
}

/* 802D41D4-802D4224 2CEB14 0050+00 1/0 6/0 0/0 .text            unmount__13JKRFileLoaderFv */
void JKRFileLoader::unmount(void) {
    s32 count = mMountCount;
    if (mMountCount != 0) {
        count--;
        mMountCount = count;
        if (count == 0) {
            delete this;
        }
    }
}

/* 802D4224-802D4270 2CEB64 004C+00 0/0 2/2 0/0 .text            getGlbResource__13JKRFileLoaderFPCc
 */
void* JKRFileLoader::getGlbResource(const char* name) {
    const char* name_reference[1];
    name_reference[0] = name;

    JKRFileLoader* fileLoader = findVolume(name_reference);
    void* resource;
    if (fileLoader == NULL) {
        resource = NULL;
    } else {
        resource = fileLoader->getResource(name_reference[0]);
    }

    return resource;
}

/* 802D4270-802D4308 2CEBB0 0098+00 0/0 29/29 1/1 .text
 * getGlbResource__13JKRFileLoaderFPCcP13JKRFileLoader          */
void* JKRFileLoader::getGlbResource(const char* name, JKRFileLoader* fileLoader) {
    void* resource = NULL;
    if (fileLoader) {
        return fileLoader->getResource(0, name);
    }

    JSUList<JKRFileLoader>& volumeList = getVolumeList();
    JSUListIterator<JKRFileLoader> iterator;
    for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator) {
        resource = iterator->getResource(0, name);
        if (resource)
            break;
    }
    return resource;
}

/* 802D4308-802D43A0 2CEC48 0098+00 0/0 1/1 0/0 .text
 * removeResource__13JKRFileLoaderFPvP13JKRFileLoader           */
bool JKRFileLoader::removeResource(void* resource, JKRFileLoader* fileLoader) {
    if (fileLoader) {
        return fileLoader->removeResource(resource);
    }

    JSUList<JKRFileLoader>& volumeList = getVolumeList();
    JSUListIterator<JKRFileLoader> iterator;
    for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator) {
        if (iterator->removeResource(resource)) {
            return true;
        }
    }

    return false;
}

/* 802D43A0-802D4438 2CECE0 0098+00 0/0 2/2 0/0 .text
 * detachResource__13JKRFileLoaderFPvP13JKRFileLoader           */
bool JKRFileLoader::detachResource(void* resource, JKRFileLoader* fileLoader) {
    if (fileLoader) {
        return fileLoader->detachResource(resource);
    }

    JSUList<JKRFileLoader>& volumeList = getVolumeList();
    JSUListIterator<JKRFileLoader> iterator;
    for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator) {
        if (iterator->detachResource(resource)) {
            return true;
        }
    }

    return false;
}

/* 802D4438-802D44C4 2CED78 008C+00 1/1 0/0 0/0 .text            findVolume__13JKRFileLoaderFPPCc */
JKRFileLoader* JKRFileLoader::findVolume(const char** volumeName) {
    if (*volumeName[0] != '/') {
        return getCurrentVolume();
    }

    char volumeNameBuffer[0x101];
    *volumeName = fetchVolumeName(volumeNameBuffer, ARRAY_SIZE(volumeNameBuffer), *volumeName);

    JSUList<JKRFileLoader>& volumeList = getVolumeList();
    JSUListIterator<JKRFileLoader> iterator;
    for (iterator = volumeList.getFirst(); iterator != volumeList.getEnd(); ++iterator) {
        if (strcmp(volumeNameBuffer, iterator->mVolumeName) == 0) {
            return iterator.getObject();
        }
    }

    return NULL;
}

/* ############################################################################################## */
/* 8039D150-8039D150 0297B0 0000+00 0/0 0/0 0/0 .rodata          @stringBase0 */
#pragma push
#pragma force_active on
SECTION_DEAD static char const* const stringBase_8039D150 = "/";
/* @stringBase0 padding */
SECTION_DEAD static char const* const pad_8039D152 = "\0\0\0\0\0";
#pragma pop

/* 804508C0-804508C8 000340 0002+06 1/1 0/0 0/0 .sdata           rootPath$2498 */
SECTION_SDATA static char rootPath[2] = "/";

/* 802D44C4-802D45A0 2CEE04 00DC+00 1/1 0/0 0/0 .text fetchVolumeName__13JKRFileLoaderFPclPCc */
// matches, but rootPath is accessed through r13
#ifdef NONMATCHING
const char* JKRFileLoader::fetchVolumeName(char* buffer, long bufferSize, const char* path) {
    if (strcmp(path, "/") == 0) {
        strcpy(buffer, rootPath);
        return rootPath;
    }

    path++;
    while (*path != 0 && *path != '/') {
        if (1 < bufferSize) {
            u8 lower_char;
            int ch = (int)*path;
            if (ch == -1) {
                lower_char = -1;
            } else {
                lower_char = __lower_map[ch & 0xFF];
            }

            *buffer = lower_char;
            buffer++;
            bufferSize--;
        }
        path++;
    }

    *buffer = '\0';
    if (*path == '\0') {
        path = rootPath;
    }

    return path;
}
#else
#pragma push
#pragma optimization_level 0
#pragma optimizewithasm off
asm const char* JKRFileLoader::fetchVolumeName(char* param_0, s32 param_1, char const* param_2) {
    nofralloc
#include "asm/JSystem/JKernel/JKRFileLoader/fetchVolumeName__13JKRFileLoaderFPclPCc.s"
}
#pragma pop
#endif