3DS: Add VFile3DS type
Jeffrey Pfau jeffrey@endrift.com
Mon, 08 Dec 2014 19:32:29 -0800
4 files changed,
148 insertions(+),
1 deletions(-)
M
CMakeLists.txt
→
CMakeLists.txt
@@ -114,7 +114,7 @@ file(GLOB OS_SRC ${CMAKE_SOURCE_DIR}/src/platform/posix/*.c)
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()
A
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); +}
A
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);