all repos — mgba @ 22245617f434049f4646916d1b2930d376503b0d

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