all repos — mgba @ ca42faae3c397fb480966637ba99bdda85e7a644

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#include "3ds-vfs.h"
  7
  8#include "util/memory.h"
  9
 10struct VFile3DS {
 11	struct VFile d;
 12
 13	Handle handle;
 14	u64 offset;
 15};
 16
 17static bool _vf3dClose(struct VFile* vf);
 18static off_t _vf3dSeek(struct VFile* vf, off_t offset, int whence);
 19static ssize_t _vf3dRead(struct VFile* vf, void* buffer, size_t size);
 20static ssize_t _vf3dWrite(struct VFile* vf, const void* buffer, size_t size);
 21static void* _vf3dMap(struct VFile* vf, size_t size, int flags);
 22static void _vf3dUnmap(struct VFile* vf, void* memory, size_t size);
 23static void _vf3dTruncate(struct VFile* vf, size_t size);
 24static ssize_t _vf3dSize(struct VFile* vf);
 25static bool _vf3dSync(struct VFile* vf, const void* buffer, size_t size);
 26
 27struct VFile* VFileOpen3DS(FS_archive* archive, const char* path, int flags) {
 28	struct VFile3DS* vf3d = malloc(sizeof(struct VFile3DS));
 29	if (!vf3d) {
 30		return 0;
 31	}
 32
 33	FS_path newPath = FS_makePath(PATH_CHAR, path);
 34	Result res = FSUSER_OpenFile(0, &vf3d->handle, *archive, newPath, flags, FS_ATTRIBUTE_NONE);
 35	if (res & 0xFFFC03FF) {
 36		free(vf3d);
 37		return 0;
 38	}
 39
 40	vf3d->offset = 0;
 41
 42	vf3d->d.close = _vf3dClose;
 43	vf3d->d.seek = _vf3dSeek;
 44	vf3d->d.read = _vf3dRead;
 45	vf3d->d.readline = 0;
 46	vf3d->d.write = _vf3dWrite;
 47	vf3d->d.map = _vf3dMap;
 48	vf3d->d.unmap = _vf3dUnmap;
 49	vf3d->d.truncate = _vf3dTruncate;
 50	vf3d->d.size = _vf3dSize;
 51	vf3d->d.sync = _vf3dSync;
 52
 53	return &vf3d->d;
 54}
 55
 56bool _vf3dClose(struct VFile* vf) {
 57	struct VFile3DS* vf3d = (struct VFile3DS*) vf;
 58
 59	FSFILE_Close(vf3d->handle);
 60	svcCloseHandle(vf3d->handle);
 61	return true;
 62}
 63
 64off_t _vf3dSeek(struct VFile* vf, off_t offset, int whence) {
 65	struct VFile3DS* vf3d = (struct VFile3DS*) vf;
 66	u64 size;
 67	switch (whence) {
 68	case SEEK_SET:
 69		vf3d->offset = offset;
 70		break;
 71	case SEEK_END:
 72		FSFILE_GetSize(vf3d->handle, &size);
 73		vf3d->offset = size;
 74		// Fall through
 75	case SEEK_CUR:
 76		vf3d->offset += offset;
 77		break;
 78	}
 79	return vf3d->offset;
 80}
 81
 82ssize_t _vf3dRead(struct VFile* vf, void* buffer, size_t size) {
 83	struct VFile3DS* vf3d = (struct VFile3DS*) vf;
 84	u32 sizeRead;
 85	Result res = FSFILE_Read(vf3d->handle, &sizeRead, vf3d->offset, buffer, size);
 86	if (res) {
 87		return -1;
 88	}
 89	vf3d->offset += sizeRead;
 90	return sizeRead;
 91}
 92
 93ssize_t _vf3dWrite(struct VFile* vf, const void* buffer, size_t size) {
 94	struct VFile3DS* vf3d = (struct VFile3DS*) vf;
 95	u32 sizeWritten;
 96	Result res = FSFILE_Write(vf3d->handle, &sizeWritten, vf3d->offset, buffer, size, FS_WRITE_FLUSH);
 97	if (res) {
 98		return -1;
 99	}
100	vf3d->offset += sizeWritten;
101	return sizeWritten;
102}
103
104static void* _vf3dMap(struct VFile* vf, size_t size, int flags) {
105	struct VFile3DS* vf3d = (struct VFile3DS*) vf;
106	UNUSED(flags);
107	void* buffer = anonymousMemoryMap(size);
108	if (buffer) {
109		u32 sizeRead;
110		FSFILE_Read(vf3d->handle, &sizeRead, 0, buffer, size);
111	}
112	return buffer;
113}
114
115static void _vf3dUnmap(struct VFile* vf, void* memory, size_t size) {
116	UNUSED(vf);
117	mappedMemoryFree(memory, size);
118}
119
120static void _vf3dTruncate(struct VFile* vf, size_t size) {
121	struct VFile3DS* vf3d = (struct VFile3DS*) vf;
122	FSFILE_SetSize(vf3d->handle, size);
123}
124
125ssize_t _vf3dSize(struct VFile* vf) {
126	struct VFile3DS* vf3d = (struct VFile3DS*) vf;
127	u64 size;
128	FSFILE_GetSize(vf3d->handle, &size);
129	return size;
130}
131
132static bool _vf3dSync(struct VFile* vf, const void* buffer, size_t size) {
133	struct VFile3DS* vf3d = (struct VFile3DS*) vf;
134	if (buffer) {
135		u32 sizeWritten;
136		Result res = FSFILE_Write(vf3d->handle, &sizeWritten, 0, buffer, size, FS_WRITE_FLUSH);
137		if (res) {
138			return false;
139		}
140	}
141	FSFILE_Flush(vf3d->handle);
142	return true;
143}