all repos — mgba @ fa884d071ecaa3e05ff20b45a67bf9500dd3d6b6

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