all repos — mgba @ 3a51c59768a0e4bbba9dc516b0554eb520474c05

mGBA Game Boy Advance Emulator

–Windows: Add native VDir support
Jeffrey Pfau jeffrey@endrift.com
Wed, 20 Apr 2016 21:09:06 -0700
commit

3a51c59768a0e4bbba9dc516b0554eb520474c05

parent

c689e32856c7564c7a7a28a25d2776e1a65a7f21

3 files changed, 149 insertions(+), 1 deletions(-)

jump to
M CHANGESCHANGES

@@ -30,6 +30,7 @@ - FFmpeg: Update dependencies on Ubuntu

- OpenGL: Log shader compilation failure - All: Allow use of external minizip library - Qt: Remove some C99isms from C++ code + - Windows: Add native VDir support 0.4.0: (2016-02-02) Features:
M CMakeLists.txtCMakeLists.txt

@@ -144,7 +144,7 @@ if(WIN32)

set(WIN32_VERSION "${LIB_VERSION_MAJOR},${LIB_VERSION_MINOR},${LIB_VERSION_PATCH}") add_definitions(-D_WIN32_WINNT=0x0600) list(APPEND OS_LIB ws2_32 shlwapi) - list(APPEND CORE_VFS_SRC ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-dirent.c) + list(APPEND CORE_VFS_SRC ${CMAKE_SOURCE_DIR}/src/util/vfs/vfs-fd.c ${CMAKE_SOURCE_DIR}/src/platform/windows/vfs-w32.c) file(GLOB OS_SRC ${CMAKE_SOURCE_DIR}/src/platform/windows/*.c) source_group("Windows-specific code" FILES ${OS_SRC}) elseif(UNIX)
A src/platform/windows/vfs-w32.c

@@ -0,0 +1,147 @@

+/* Copyright (c) 2013-2016 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 "util/vfs.h" + +#include "util/string.h" + +static bool _vdwClose(struct VDir* vd); +static void _vdwRewind(struct VDir* vd); +static struct VDirEntry* _vdwListNext(struct VDir* vd); +static struct VFile* _vdwOpenFile(struct VDir* vd, const char* path, int mode); +static struct VDir* _vdwOpenDir(struct VDir* vd, const char* path); +static bool _vdwDeleteFile(struct VDir* vd, const char* path); + +static const char* _vdweName(struct VDirEntry* vde); +static enum VFSType _vdweType(struct VDirEntry* vde); + +struct VDirW32; +struct VDirEntryW32 { + struct VDirEntry d; + WIN32_FIND_DATA ffData; +}; + +struct VDirW32 { + struct VDir d; + HANDLE handle; + struct VDirEntryW32 vde; + char* path; +}; + +struct VDir* VDirOpen(const char* path) { + if (!path || !path[0]) { + return 0; + } + char name[MAX_PATH]; + _snprintf(name, sizeof(name), "%s\\*", path); + WIN32_FIND_DATA ffData; + HANDLE handle = FindFirstFile(name, &ffData); + if (handle == INVALID_HANDLE_VALUE) { + return 0; + } + + struct VDirW32* vd = malloc(sizeof(struct VDirW32)); + if (!vd) { + FindClose(handle); + return 0; + } + + vd->d.close = _vdwClose; + vd->d.rewind = _vdwRewind; + vd->d.listNext = _vdwListNext; + vd->d.openFile = _vdwOpenFile; + vd->d.openDir = _vdwOpenDir; + vd->d.deleteFile = _vdwDeleteFile; + vd->handle = handle; + vd->path = _strdup(path); + + vd->vde.d.name = _vdweName; + vd->vde.d.type = _vdweType; + vd->vde.ffData = ffData; + + return &vd->d; +} + +bool _vdwClose(struct VDir* vd) { + struct VDirW32* vdw = (struct VDirW32*) vd; + FindClose(vdw->handle); + free(vdw); + return true; +} + +void _vdwRewind(struct VDir* vd) { + struct VDirW32* vdw = (struct VDirW32*) vd; + FindClose(vdw->handle); + char name[MAX_PATH]; + _snprintf(name, sizeof(name), "%s\\*", vdw->path); + vdw->handle = FindFirstFile(name, &vdw->vde.ffData); +} + +struct VDirEntry* _vdwListNext(struct VDir* vd) { + struct VDirW32* vdw = (struct VDirW32*) vd; + if (FindNextFile(vdw->handle, &vdw->vde.ffData)) { + return &vdw->vde.d; + } + + return 0; +} + +struct VFile* _vdwOpenFile(struct VDir* vd, const char* path, int mode) { + struct VDirW32* vdw = (struct VDirW32*) vd; + if (!path) { + return 0; + } + const char* dir = vdw->path; + char* combined = malloc(sizeof(char) * (strlen(path) + strlen(dir) + 2)); + sprintf(combined, "%s\\%s", dir, path); + + struct VFile* file = VFileOpen(combined, mode); + free(combined); + return file; +} + +struct VDir* _vdwOpenDir(struct VDir* vd, const char* path) { + struct VDirW32* vdw = (struct VDirW32*) vd; + if (!path) { + return 0; + } + const char* dir = vdw->path; + char* combined = malloc(sizeof(char) * (strlen(path) + strlen(dir) + 2)); + sprintf(combined, "%s\\%s", dir, path); + + struct VDir* vd2 = VDirOpen(combined); + if (!vd2) { + vd2 = VDirOpenArchive(combined); + } + free(combined); + return vd2; +} + +bool _vdwDeleteFile(struct VDir* vd, const char* path) { + struct VDirW32* vdw = (struct VDirW32*) vd; + if (!path) { + return 0; + } + const char* dir = vdw->path; + char* combined = malloc(sizeof(char) * (strlen(path) + strlen(dir) + 2)); + sprintf(combined, "%s\\%s", dir, path); + + bool ret = DeleteFile(combined); + free(combined); + return ret; +} + +const char* _vdweName(struct VDirEntry* vde) { + struct VDirEntryW32* vdwe = (struct VDirEntryW32*) vde; + return vdwe->ffData.cFileName; +} + +static enum VFSType _vdweType(struct VDirEntry* vde) { + struct VDirEntryW32* vdwe = (struct VDirEntryW32*) vde; + if (vdwe->ffData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + return VFS_DIRECTORY; + } + return VFS_FILE; +}