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}
20
21void mDirectorySetDeinit(struct mDirectorySet* dirs) {
22 mDirectorySetDetachBase(dirs);
23
24 if (dirs->archive) {
25 if (dirs->archive == dirs->save) {
26 dirs->save = NULL;
27 }
28 if (dirs->archive == dirs->patch) {
29 dirs->patch = NULL;
30 }
31 if (dirs->archive == dirs->state) {
32 dirs->state = NULL;
33 }
34 if (dirs->archive == dirs->screenshot) {
35 dirs->screenshot = NULL;
36 }
37 dirs->archive->close(dirs->archive);
38 dirs->archive = NULL;
39 }
40
41 if (dirs->save) {
42 if (dirs->save == dirs->patch) {
43 dirs->patch = NULL;
44 }
45 if (dirs->save == dirs->state) {
46 dirs->state = NULL;
47 }
48 if (dirs->save == dirs->screenshot) {
49 dirs->screenshot = NULL;
50 }
51 dirs->save->close(dirs->save);
52 dirs->save = NULL;
53 }
54
55 if (dirs->patch) {
56 if (dirs->patch == dirs->state) {
57 dirs->state = NULL;
58 }
59 if (dirs->patch == dirs->screenshot) {
60 dirs->screenshot = NULL;
61 }
62 dirs->patch->close(dirs->patch);
63 dirs->patch = NULL;
64 }
65
66 if (dirs->state) {
67 if (dirs->state == dirs->screenshot) {
68 dirs->state = NULL;
69 }
70 dirs->state->close(dirs->state);
71 dirs->state = NULL;
72 }
73
74 if (dirs->screenshot) {
75 dirs->screenshot->close(dirs->screenshot);
76 dirs->screenshot = NULL;
77 }
78}
79
80void mDirectorySetAttachBase(struct mDirectorySet* dirs, struct VDir* base) {
81 dirs->base = base;
82 if (!dirs->save) {
83 dirs->save = dirs->base;
84 }
85 if (!dirs->patch) {
86 dirs->patch = dirs->base;
87 }
88 if (!dirs->state) {
89 dirs->state = dirs->base;
90 }
91 if (!dirs->screenshot) {
92 dirs->screenshot = dirs->base;
93 }
94}
95
96void mDirectorySetDetachBase(struct mDirectorySet* dirs) {
97 if (dirs->save == dirs->base) {
98 dirs->save = NULL;
99 }
100 if (dirs->patch == dirs->base) {
101 dirs->patch = NULL;
102 }
103 if (dirs->state == dirs->base) {
104 dirs->state = NULL;
105 }
106 if (dirs->screenshot == dirs->base) {
107 dirs->screenshot = NULL;
108 }
109
110 if (dirs->base) {
111 dirs->base->close(dirs->base);
112 dirs->base = NULL;
113 }
114}
115
116struct VFile* mDirectorySetOpenPath(struct mDirectorySet* dirs, const char* path, bool (*filter)(struct VFile*)) {
117 dirs->archive = VDirOpenArchive(path);
118 struct VFile* file;
119 if (dirs->archive) {
120 file = VDirFindFirst(dirs->archive, filter);
121 if (!file) {
122 dirs->archive->close(dirs->archive);
123 dirs->archive = 0;
124 }
125 } else {
126 file = VFileOpen(path, O_RDONLY);
127 if (file && !filter(file)) {
128 file->close(file);
129 file = 0;
130 }
131 }
132 if (file) {
133 char dirname[PATH_MAX];
134 separatePath(path, dirname, dirs->baseName, 0);
135 mDirectorySetAttachBase(dirs, VDirOpen(dirname));
136 }
137 return file;
138}
139
140struct VFile* mDirectorySetOpenSuffix(struct mDirectorySet* dirs, struct VDir* dir, const char* suffix, int mode) {
141 char name[PATH_MAX + 1] = "";
142 snprintf(name, sizeof(name) - 1, "%s%s", dirs->baseName, suffix);
143 return dir->openFile(dir, name, mode);
144}
145
146void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct mCoreOptions* opts) {
147 if (opts->savegamePath) {
148 struct VDir* dir = VDirOpen(opts->savegamePath);
149 if (dir) {
150 if (dirs->save && dirs->save != dirs->base) {
151 dirs->save->close(dirs->save);
152 }
153 dirs->save = dir;
154 }
155 }
156
157 if (opts->savestatePath) {
158 struct VDir* dir = VDirOpen(opts->savestatePath);
159 if (dir) {
160 if (dirs->state && dirs->state != dirs->base) {
161 dirs->state->close(dirs->state);
162 }
163 dirs->state = dir;
164 }
165 }
166
167 if (opts->screenshotPath) {
168 struct VDir* dir = VDirOpen(opts->screenshotPath);
169 if (dir) {
170 if (dirs->screenshot && dirs->screenshot != dirs->base) {
171 dirs->screenshot->close(dirs->screenshot);
172 }
173 dirs->screenshot = dir;
174 }
175 }
176
177 if (opts->patchPath) {
178 struct VDir* dir = VDirOpen(opts->patchPath);
179 if (dir) {
180 if (dirs->patch && dirs->patch != dirs->base) {
181 dirs->patch->close(dirs->patch);
182 }
183 dirs->patch = dir;
184 }
185 }
186}
187#endif