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) {
177 if (dirs->save && dirs->save != dirs->base) {
178 dirs->save->close(dirs->save);
179 }
180 dirs->save = dir;
181 }
182 }
183
184 if (opts->savestatePath) {
185 struct VDir* dir = VDirOpen(opts->savestatePath);
186 if (dir) {
187 if (dirs->state && dirs->state != dirs->base) {
188 dirs->state->close(dirs->state);
189 }
190 dirs->state = dir;
191 }
192 }
193
194 if (opts->screenshotPath) {
195 struct VDir* dir = VDirOpen(opts->screenshotPath);
196 if (dir) {
197 if (dirs->screenshot && dirs->screenshot != dirs->base) {
198 dirs->screenshot->close(dirs->screenshot);
199 }
200 dirs->screenshot = dir;
201 }
202 }
203
204 if (opts->patchPath) {
205 struct VDir* dir = VDirOpen(opts->patchPath);
206 if (dir) {
207 if (dirs->patch && dirs->patch != dirs->base) {
208 dirs->patch->close(dirs->patch);
209 }
210 dirs->patch = dir;
211 }
212 }
213
214 if (opts->cheatsPath) {
215 struct VDir* dir = VDirOpen(opts->cheatsPath);
216 if (dir) {
217 if (dirs->cheats && dirs->cheats != dirs->base) {
218 dirs->cheats->close(dirs->cheats);
219 }
220 dirs->cheats = dir;
221 }
222 }
223}
224#endif