all repos — mgba @ 82cccd74eb2115bbfd475291f41e261473937bf5

mGBA Game Boy Advance Emulator

src/platform/3ds/3ds-vfs.c (view raw)

  1/* Copyright (c) 2013-2014 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/* Copyright (c) 2013-2014 Jeffrey Pfau
  7 *
  8 * This Source Code Form is subject to the terms of the Mozilla Public
  9 * License, v. 2.0. If a copy of the MPL was not distributed with this
 10 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 11#include "3ds-vfs.h"
 12
 13#include "util/memory.h"
 14
 15struct VFile3DS {
 16	struct VFile d;
 17
 18	Handle handle;
 19	u64 offset;
 20};
 21
 22static bool _vf3dClose(struct VFile* vf);
 23static off_t _vf3dSeek(struct VFile* vf, off_t offset, int whence);
 24static ssize_t _vf3dRead(struct VFile* vf, void* buffer, size_t size);
 25static ssize_t _vf3dWrite(struct VFile* vf, const void* buffer, size_t size);
 26static void* _vf3dMap(struct VFile* vf, size_t size, int flags);
 27static void _vf3dUnmap(struct VFile* vf, void* memory, size_t size);
 28static void _vf3dTruncate(struct VFile* vf, size_t size);
 29
 30struct VFile* VFileOpen3DS(FS_archive archive, const char* path, int flags) {
 31	struct VFile3DS* vf3d = malloc(sizeof(struct VFile3DS));
 32	if (!vf3d) {
 33		return 0;
 34	}
 35
 36	FS_path newPath = FS_makePath(PATH_CHAR, path);
 37	Result res = FSUSER_OpenFile(0, &vf3d->handle, archive, newPath, flags, FS_ATTRIBUTE_NONE);
 38	if (res & 0xFFFC03FF) {
 39		free(vf3d);
 40		return 0;
 41	}
 42
 43	vf3d->offset = 0;
 44
 45	vf3d->d.close = _vf3dClose;
 46	vf3d->d.seek = _vf3dSeek;
 47	vf3d->d.read = _vf3dRead;
 48	vf3d->d.readline = 0;
 49	vf3d->d.write = _vf3dWrite;
 50	vf3d->d.map = _vf3dMap;
 51	vf3d->d.unmap = _vf3dUnmap;
 52	vf3d->d.truncate = _vf3dTruncate;
 53
 54	return &vf3d->d;
 55}
 56
 57bool _vf3dClose(struct VFile* vf) {
 58	struct VFile3DS* vf3d = (struct VFile3DS*) vf;
 59
 60	FSFILE_Close(vf3d->handle);
 61	svcCloseHandle(vf3d->handle);
 62	return true;
 63}
 64
 65off_t _vf3dSeek(struct VFile* vf, off_t offset, int whence) {
 66	struct VFile3DS* vf3d = (struct VFile3DS*) vf;
 67	u64 size;
 68	switch (whence) {
 69	case SEEK_SET:
 70		vf3d->offset = offset;
 71		break;
 72	case SEEK_END:
 73		FSFILE_GetSize(vf3d->handle, &size);
 74		vf3d->offset = size;
 75		// Fall through
 76	case SEEK_CUR:
 77		vf3d->offset += offset;
 78		break;
 79	}
 80	return vf3d->offset;
 81}
 82
 83ssize_t _vf3dRead(struct VFile* vf, void* buffer, size_t size) {
 84	struct VFile3DS* vf3d = (struct VFile3DS*) vf;
 85	u32 sizeRead;
 86	Result res = FSFILE_Read(vf3d->handle, &sizeRead, vf3d->offset, buffer, size);
 87	if (res) {
 88		return -1;
 89	}
 90	vf3d->offset += sizeRead;
 91	return sizeRead;
 92}
 93
 94ssize_t _vf3dWrite(struct VFile* vf, const void* buffer, size_t size) {
 95	struct VFile3DS* vf3d = (struct VFile3DS*) vf;
 96	u32 sizeWritten;
 97	Result res = FSFILE_Write(vf3d->handle, &sizeWritten, vf3d->offset, buffer, size, FS_WRITE_FLUSH);
 98	if (res) {
 99		return -1;
100	}
101	vf3d->offset += sizeWritten;
102	return sizeWritten;
103}
104
105// TODO: Move these to a generic implementation
106static void* _vf3dMap(struct VFile* vf, size_t size, int flags) {
107	UNUSED(flags);
108	void* buffer = anonymousMemoryMap(size);
109	vf->read(vf, buffer, size);
110	vf->seek(vf, -(off_t) size, SEEK_CUR);
111	return buffer;
112}
113
114static void _vf3dUnmap(struct VFile* vf, void* memory, size_t size) {
115	UNUSED(vf);
116	mappedMemoryFree(memory, size);
117}
118
119static void _vf3dTruncate(struct VFile* vf, size_t size) {
120	struct VFile3DS* vf3d = (struct VFile3DS*) vf;
121	FSFILE_SetSize(vf3d->handle, size);
122}