From 39c88da6508b85d121918de88dfa4c20b392832a Mon Sep 17 00:00:00 2001 From: Jeffrey Pfau Date: Mon, 8 Dec 2014 19:32:29 -0800 Subject: [PATCH] 3DS: Add VFile3DS type --- CMakeLists.txt | 2 +- src/platform/3ds/{memory.c => 3ds-memory.c} | 0 src/platform/3ds/3ds-vfs.c | 134 ++++++++++++++++++++ src/platform/3ds/3ds-vfs.h | 13 ++ 4 files changed, 148 insertions(+), 1 deletion(-) rename src/platform/3ds/{memory.c => 3ds-memory.c} (100%) create mode 100644 src/platform/3ds/3ds-vfs.c create mode 100644 src/platform/3ds/3ds-vfs.h diff --git a/CMakeLists.txt b/CMakeLists.txt index abff46f68..e67add0fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,7 +114,7 @@ elseif(UNIX) source_group("POSIX-specific code" FILES ${OS_SRC}) elseif(3DS) list(APPEND OS_LIB ctru) - list(APPEND OS_SRC ${CMAKE_SOURCE_DIR}/src/platform/3ds/memory.c) + file(GLOB OS_SRC ${CMAKE_SOURCE_DIR}/src/platform/3ds/3ds-*.c) source_group("3DS-specific code" FILES ${OS_SRC}) set(BINARY_TYPE STATIC) endif() diff --git a/src/platform/3ds/memory.c b/src/platform/3ds/3ds-memory.c similarity index 100% rename from src/platform/3ds/memory.c rename to src/platform/3ds/3ds-memory.c diff --git a/src/platform/3ds/3ds-vfs.c b/src/platform/3ds/3ds-vfs.c new file mode 100644 index 000000000..0dd254630 --- /dev/null +++ b/src/platform/3ds/3ds-vfs.c @@ -0,0 +1,134 @@ +/* Copyright (c) 2013-2014 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* Copyright (c) 2013-2014 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "3ds-vfs.h" + +#include "util/vfs.h" + +#include "util/memory.h" + +struct VFile3DS { + struct VFile d; + + Handle handle; + u64 offset; +}; + +static bool _vf3dClose(struct VFile* vf); +static off_t _vf3dSeek(struct VFile* vf, off_t offset, int whence); +static ssize_t _vf3dRead(struct VFile* vf, void* buffer, size_t size); +static ssize_t _vf3dWrite(struct VFile* vf, const void* buffer, size_t size); +static void* _vf3dMap(struct VFile* vf, size_t size, int flags); +static void _vf3dUnmap(struct VFile* vf, void* memory, size_t size); +static void _vf3dTruncate(struct VFile* vf, size_t size); + +struct VFile* VFileOpen3DS(FS_archive archive, const char* path, int flags) { + struct VFile3DS* vf3d = malloc(sizeof(struct VFile3DS)); + if (!vf3d) { + return 0; + } + + int newFlags = 0; + if (flags & O_RDONLY) { + newFlags |= FS_OPEN_READ; + } + if (flags & O_WRONLY) { + newFlags |= FS_OPEN_WRITE; + } + if (flags & O_CREAT) { + newFlags |= FS_OPEN_CREATE; + } + + FS_path lowPath = FS_makePath(PATH_CHAR, path); + if (FSUSER_OpenFileDirectly(0, &vf3d->handle, archive, lowPath, newFlags, FS_ATTRIBUTE_NONE)) { + free(vf3d); + return 0; + } + + vf3d->offset = 0; + + vf3d->d.close = _vf3dClose; + vf3d->d.seek = _vf3dSeek; + vf3d->d.read = _vf3dRead; + vf3d->d.readline = 0; + vf3d->d.write = _vf3dWrite; + vf3d->d.map = _vf3dMap; + vf3d->d.unmap = _vf3dUnmap; + vf3d->d.truncate = _vf3dTruncate; + + return &vf3d->d; +} + +bool _vf3dClose(struct VFile* vf) { + struct VFile3DS* vf3d = (struct VFile3DS*) vf; + + FSFILE_Close(vf3d->handle); + svcCloseHandle(vf3d->handle); + return true; +} + +off_t _vf3dSeek(struct VFile* vf, off_t offset, int whence) { + struct VFile3DS* vf3d = (struct VFile3DS*) vf; + u64 size; + switch (whence) { + case SEEK_SET: + vf3d->offset = offset; + break; + case SEEK_END: + FSFILE_GetSize(vf3d->handle, &size); + vf3d->offset = size; + // Fall through + case SEEK_CUR: + vf3d->offset += offset; + break; + } + return vf3d->offset; +} + +ssize_t _vf3dRead(struct VFile* vf, void* buffer, size_t size) { + struct VFile3DS* vf3d = (struct VFile3DS*) vf; + u32 sizeRead; + Result res = FSFILE_Read(vf3d->handle, &sizeRead, vf3d->offset, buffer, size); + if (res) { + return -1; + } + vf3d->offset += sizeRead; + return sizeRead; +} + +ssize_t _vf3dWrite(struct VFile* vf, const void* buffer, size_t size) { + struct VFile3DS* vf3d = (struct VFile3DS*) vf; + u32 sizeWritten; + Result res = FSFILE_Write(vf3d->handle, &sizeWritten, vf3d->offset, buffer, size, FS_WRITE_FLUSH); + if (res) { + return -1; + } + vf3d->offset += sizeWritten; + return sizeWritten; +} + +// TODO: Move these to a generic implementation +static void* _vf3dMap(struct VFile* vf, size_t size, int flags) { + UNUSED(flags); + void* buffer = anonymousMemoryMap(size); + vf->read(vf, buffer, size); + vf->seek(vf, -(off_t) size, SEEK_CUR); + return buffer; +} + +static void _vf3dUnmap(struct VFile* vf, void* memory, size_t size) { + UNUSED(vf); + mappedMemoryFree(memory, size); +} + +static void _vf3dTruncate(struct VFile* vf, size_t size) { + struct VFile3DS* vf3d = (struct VFile3DS*) vf; + FSFILE_SetSize(vf3d->handle, size); +} diff --git a/src/platform/3ds/3ds-vfs.h b/src/platform/3ds/3ds-vfs.h new file mode 100644 index 000000000..89d5b9152 --- /dev/null +++ b/src/platform/3ds/3ds-vfs.h @@ -0,0 +1,13 @@ +/* Copyright (c) 2013-2014 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* Copyright (c) 2013-2014 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <3ds.h> + +struct VFile* VFileOpen3DS(FS_archive archive, const char* path, int flags);