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