all repos — mgba @ 66e9b921a9264ee8186bb7dd1df022a5077a6ab1

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}
 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