all repos — mgba @ 60577e83948647d36a2e6a8b4ec8f8556df3f72f

mGBA Game Boy Advance Emulator

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