src/core/directories.c (view raw)
1/* Copyright (c) 2013-2015 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include <mgba/core/directories.h>
7
8#include <mgba/core/config.h>
9#include <mgba-util/vfs.h>
10
11#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
12void mDirectorySetInit(struct mDirectorySet* dirs) {
13 dirs->base = 0;
14 dirs->archive = 0;
15 dirs->save = 0;
16 dirs->patch = 0;
17 dirs->state = 0;
18 dirs->screenshot = 0;
19 dirs->cheats = 0;
20}
21
22void mDirectorySetDeinit(struct mDirectorySet* dirs) {
23 mDirectorySetDetachBase(dirs);
24
25 if (dirs->archive) {
26 if (dirs->archive == dirs->save) {
27 dirs->save = NULL;
28 }
29 if (dirs->archive == dirs->patch) {
30 dirs->patch = NULL;
31 }
32 if (dirs->archive == dirs->state) {
33 dirs->state = NULL;
34 }
35 if (dirs->archive == dirs->screenshot) {
36 dirs->screenshot = NULL;
37 }
38 if (dirs->archive == dirs->cheats) {
39 dirs->cheats = NULL;
40 }
41 dirs->archive->close(dirs->archive);
42 dirs->archive = NULL;
43 }
44
45 if (dirs->save) {
46 if (dirs->save == dirs->patch) {
47 dirs->patch = NULL;
48 }
49 if (dirs->save == dirs->state) {
50 dirs->state = NULL;
51 }
52 if (dirs->save == dirs->screenshot) {
53 dirs->screenshot = NULL;
54 }
55 if (dirs->save == dirs->cheats) {
56 dirs->cheats = NULL;
57 }
58 dirs->save->close(dirs->save);
59 dirs->save = NULL;
60 }
61
62 if (dirs->patch) {
63 if (dirs->patch == dirs->state) {
64 dirs->state = NULL;
65 }
66 if (dirs->patch == dirs->screenshot) {
67 dirs->screenshot = NULL;
68 }
69 if (dirs->patch == dirs->cheats) {
70 dirs->cheats = NULL;
71 }
72 dirs->patch->close(dirs->patch);
73 dirs->patch = NULL;
74 }
75
76 if (dirs->state) {
77 if (dirs->state == dirs->screenshot) {
78 dirs->state = NULL;
79 }
80 if (dirs->state == dirs->cheats) {
81 dirs->cheats = NULL;
82 }
83 dirs->state->close(dirs->state);
84 dirs->state = NULL;
85 }
86
87 if (dirs->screenshot) {
88 if (dirs->screenshot == dirs->cheats) {
89 dirs->cheats = NULL;
90 }
91 dirs->screenshot->close(dirs->screenshot);
92 dirs->screenshot = NULL;
93 }
94
95 if (dirs->cheats) {
96 dirs->cheats->close(dirs->cheats);
97 dirs->cheats = NULL;
98 }
99}
100
101void mDirectorySetAttachBase(struct mDirectorySet* dirs, struct VDir* base) {
102 dirs->base = base;
103 if (!dirs->save) {
104 dirs->save = dirs->base;
105 }
106 if (!dirs->patch) {
107 dirs->patch = dirs->base;
108 }
109 if (!dirs->state) {
110 dirs->state = dirs->base;
111 }
112 if (!dirs->screenshot) {
113 dirs->screenshot = dirs->base;
114 }
115 if (!dirs->cheats) {
116 dirs->cheats = dirs->base;
117 }
118}
119
120void mDirectorySetDetachBase(struct mDirectorySet* dirs) {
121 if (dirs->save == dirs->base) {
122 dirs->save = NULL;
123 }
124 if (dirs->patch == dirs->base) {
125 dirs->patch = NULL;
126 }
127 if (dirs->state == dirs->base) {
128 dirs->state = NULL;
129 }
130 if (dirs->screenshot == dirs->base) {
131 dirs->screenshot = NULL;
132 }
133 if (dirs->cheats == dirs->base) {
134 dirs->cheats = NULL;
135 }
136
137 if (dirs->base) {
138 dirs->base->close(dirs->base);
139 dirs->base = NULL;
140 }
141}
142
143struct VFile* mDirectorySetOpenPath(struct mDirectorySet* dirs, const char* path, bool (*filter)(struct VFile*)) {
144 dirs->archive = VDirOpenArchive(path);
145 struct VFile* file;
146 if (dirs->archive) {
147 file = VDirFindFirst(dirs->archive, filter);
148 if (!file) {
149 dirs->archive->close(dirs->archive);
150 dirs->archive = 0;
151 }
152 } else {
153 file = VFileOpen(path, O_RDONLY);
154 if (file && !filter(file)) {
155 file->close(file);
156 file = 0;
157 }
158 }
159 if (file) {
160 char dirname[PATH_MAX];
161 separatePath(path, dirname, dirs->baseName, 0);
162 mDirectorySetAttachBase(dirs, VDirOpen(dirname));
163 }
164 return file;
165}
166
167struct VFile* mDirectorySetOpenSuffix(struct mDirectorySet* dirs, struct VDir* dir, const char* suffix, int mode) {
168 char name[PATH_MAX + 1] = "";
169 snprintf(name, sizeof(name) - 1, "%s%s", dirs->baseName, suffix);
170 return dir->openFile(dir, name, mode);
171}
172
173void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct mCoreOptions* opts) {
174 if (opts->savegamePath) {
175 struct VDir* dir = VDirOpen(opts->savegamePath);
176 if (!dir && VDirCreate(opts->savegamePath)) {
177 dir = VDirOpen(opts->savegamePath);
178 }
179 if (dir) {
180 if (dirs->save && dirs->save != dirs->base) {
181 dirs->save->close(dirs->save);
182 }
183 dirs->save = dir;
184 }
185 }
186
187 if (opts->savestatePath) {
188 struct VDir* dir = VDirOpen(opts->savestatePath);
189 if (!dir && VDirCreate(opts->savestatePath)) {
190 dir = VDirOpen(opts->savestatePath);
191 }
192 if (dir) {
193 if (dirs->state && dirs->state != dirs->base) {
194 dirs->state->close(dirs->state);
195 }
196 dirs->state = dir;
197 }
198 }
199
200 if (opts->screenshotPath) {
201 struct VDir* dir = VDirOpen(opts->screenshotPath);
202 if (!dir && VDirCreate(opts->screenshotPath)) {
203 dir = VDirOpen(opts->screenshotPath);
204 }
205 if (dir) {
206 if (dirs->screenshot && dirs->screenshot != dirs->base) {
207 dirs->screenshot->close(dirs->screenshot);
208 }
209 dirs->screenshot = dir;
210 }
211 }
212
213 if (opts->patchPath) {
214 struct VDir* dir = VDirOpen(opts->patchPath);
215 if (!dir && VDirCreate(opts->patchPath)) {
216 dir = VDirOpen(opts->patchPath);
217 }
218 if (dir) {
219 if (dirs->patch && dirs->patch != dirs->base) {
220 dirs->patch->close(dirs->patch);
221 }
222 dirs->patch = dir;
223 }
224 }
225
226 if (opts->cheatsPath) {
227 struct VDir* dir = VDirOpen(opts->cheatsPath);
228 if (!dir && VDirCreate(opts->cheatsPath)) {
229 dir = VDirOpen(opts->cheatsPath);
230 }
231 if (dir) {
232 if (dirs->cheats && dirs->cheats != dirs->base) {
233 dirs->cheats->close(dirs->cheats);
234 }
235 dirs->cheats = dir;
236 }
237 }
238}
239#endif