Rob Loach 2 дней назад
Родитель
Сommit
c45bb5dbb7
3 измененных файлов с 260 добавлено и 1 удалено
  1. 6 0
      CMakeLists.txt
  2. 251 0
      src/physfs_platform_sdl3.c
  3. 3 1
      src/physfs_platforms.h

+ 6 - 0
CMakeLists.txt

@@ -88,6 +88,7 @@ set(PHYSFS_SRCS
     src/physfs_platform_dos.c
     src/physfs_platform_emscripten.c
     src/physfs_platform_posix.c
+    src/physfs_platform_sdl3.c
     src/physfs_platform_unix.c
     src/physfs_platform_windows.c
     src/physfs_platform_ogc.c
@@ -193,6 +194,11 @@ if(NOT PHYSFS_ARCHIVE_POD)
     add_definitions(-DPHYSFS_SUPPORTS_POD=0)
 endif()
 
+option(PHYSFS_PLATFORM_SDL3 "Enable building for the SDL3 file system" FALSE)
+if(PHYSFS_PLATFORM_SDL3)
+    add_definitions(-DPHYSFS_PLATFORM_SDL3=1)
+endif()
+
 if(EMSCRIPTEN)
     set(PHYSFS_EMSCRIPTEN_STORAGE_PATH "" CACHE STRING "Specify a path for prefdir on Emscripten")
     if(NOT PHYSFS_EMSCRIPTEN_STORAGE_PATH STREQUAL "")

+ 251 - 0
src/physfs_platform_sdl3.c

@@ -0,0 +1,251 @@
+/*
+ * SDL3 support routines for PhysicsFS.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ *  This file written by Rob Loach (@RobLoach).
+ */
+
+#define __PHYSICSFS_INTERNAL__
+#include "physfs_internal.h"
+
+#ifdef PHYSFS_PLATFORM_SDL3
+
+#include <SDL3/SDL.h>
+
+/**
+ * Context for enumeration.
+ *
+ * @see __PHYSFS_platformEnumerate()
+ */
+typedef struct platformEnumerateContext
+{
+    PHYSFS_EnumerateCallback callback;
+    const char *origdir;
+    void *callbackdata;
+    PHYSFS_EnumerateCallbackResult result;
+} platformEnumerateContext;
+
+int __PHYSFS_platformInit(const char *argv0)
+{
+    (void)argv0;
+    return 1; /* always succeed. */
+} /* __PHYSFS_platformInit */
+
+void __PHYSFS_platformDeinit(void)
+{
+    /* no-op */
+} /* __PHYSFS_platformDeinit */
+
+void *__PHYSFS_platformGetThreadID(void)
+{
+    return (void *)(size_t)SDL_GetCurrentThreadID();
+} /* __PHYSFS_platformGetThreadID */
+
+void *__PHYSFS_platformCreateMutex(void)
+{
+    return (void *)SDL_CreateMutex();
+} /* __PHYSFS_platformCreateMutex */
+
+void __PHYSFS_platformDestroyMutex(void *mutex)
+{
+    SDL_DestroyMutex((SDL_Mutex *)mutex);
+} /* __PHYSFS_platformDestroyMutex */
+
+int __PHYSFS_platformGrabMutex(void *mutex)
+{
+    SDL_LockMutex((SDL_Mutex *)mutex);
+    return 1;
+} /* __PHYSFS_platformGrabMutex */
+
+void __PHYSFS_platformReleaseMutex(void *mutex)
+{
+    SDL_UnlockMutex((SDL_Mutex *)mutex);
+} /* __PHYSFS_platformReleaseMutex */
+
+/**
+ * Not supported by SDL3.
+ */
+void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
+{
+    (void)cb;
+    (void)data;
+} /* __PHYSFS_platformDetectAvailableCDs */
+
+char *__PHYSFS_platformCalcBaseDir(const char *argv0)
+{
+    const char *base = SDL_GetBasePath();
+    (void)argv0;
+    BAIL_IF(base == NULL, PHYSFS_ERR_OS_ERROR, NULL);
+    return __PHYSFS_strdup(base);
+} /* __PHYSFS_platformCalcBaseDir */
+
+char *__PHYSFS_platformCalcUserDir(void)
+{
+    const char *home = SDL_GetUserFolder(SDL_FOLDER_HOME);
+    BAIL_IF(home == NULL, PHYSFS_ERR_OS_ERROR, NULL);
+    return __PHYSFS_strdup(home);
+} /* __PHYSFS_platformCalcUserDir */
+
+char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
+{
+    char *out = SDL_GetPrefPath(org, app);
+    BAIL_IF(out == NULL, PHYSFS_ERR_OS_ERROR, NULL);
+    /* Unlike SDL_GetBasePath() or SDL_GetUserFolder(), SDL_GetPrefPath() allocates the string for us. */
+    return out;
+} /* __PHYSFS_platformCalcPrefDir */
+
+static SDL_EnumerationResult SDLCALL platformEnumerateCallback(void *userdata,
+                                                               const char *dirname,
+                                                               const char *fname)
+{
+    platformEnumerateContext *ctx = (platformEnumerateContext *)userdata;
+    (void)dirname;
+
+    ctx->result = ctx->callback(ctx->callbackdata, ctx->origdir, fname);
+
+    switch (ctx->result) {
+        case PHYSFS_ENUM_OK:    return SDL_ENUM_CONTINUE;
+        case PHYSFS_ENUM_STOP:  return SDL_ENUM_SUCCESS;
+        case PHYSFS_ENUM_ERROR: return SDL_ENUM_FAILURE;
+    }
+    return SDL_ENUM_FAILURE;
+} /* platformEnumerateCallback */
+
+PHYSFS_EnumerateCallbackResult __PHYSFS_platformEnumerate(const char *dirname,
+                                                          PHYSFS_EnumerateCallback callback,
+                                                          const char *origdir,
+                                                          void *callbackdata)
+{
+    platformEnumerateContext ctx;
+    ctx.callback = callback;
+    ctx.origdir = origdir;
+    ctx.callbackdata = callbackdata;
+    ctx.result = PHYSFS_ENUM_OK;
+
+    BAIL_IF(!SDL_EnumerateDirectory(dirname, platformEnumerateCallback, &ctx),
+            /* Determine the correct PhysFS error to report. */
+            ctx.result == PHYSFS_ENUM_ERROR ? PHYSFS_ERR_APP_CALLBACK : PHYSFS_ERR_OS_ERROR,
+            PHYSFS_ENUM_ERROR);
+
+    return ctx.result;
+} /* __PHYSFS_platformEnumerate */
+
+int __PHYSFS_platformMkDir(const char *path)
+{
+    BAIL_IF(!SDL_CreateDirectory(path), PHYSFS_ERR_OS_ERROR, 0);
+    return 1;
+} /* __PHYSFS_platformMkDir */
+
+int __PHYSFS_platformDelete(const char *path)
+{
+    BAIL_IF(!SDL_RemovePath(path), PHYSFS_ERR_OS_ERROR, 0);
+    return 1;
+} /* __PHYSFS_platformDelete */
+
+int __PHYSFS_platformStat(const char *fn, PHYSFS_Stat *stat, const int follow)
+{
+    SDL_PathInfo info;
+    (void)follow;
+
+    BAIL_IF(!SDL_GetPathInfo(fn, &info), PHYSFS_ERR_NOT_FOUND, 0);
+
+    switch (info.type) {
+        case SDL_PATHTYPE_FILE:
+            stat->filetype = PHYSFS_FILETYPE_REGULAR;
+            stat->filesize = (PHYSFS_sint64)info.size;
+            break;
+        case SDL_PATHTYPE_DIRECTORY:
+            stat->filetype = PHYSFS_FILETYPE_DIRECTORY;
+            stat->filesize = 0;
+            break;
+        case SDL_PATHTYPE_OTHER:
+            stat->filetype = PHYSFS_FILETYPE_OTHER;
+            stat->filesize = -1;
+            break;
+        case SDL_PATHTYPE_NONE:
+        default:
+            BAIL(PHYSFS_ERR_NOT_FOUND, 0);
+    }
+
+    stat->accesstime = (PHYSFS_sint64)(info.access_time / SDL_NS_PER_SECOND);
+    stat->createtime = (PHYSFS_sint64)(info.create_time / SDL_NS_PER_SECOND);
+    stat->modtime = (PHYSFS_sint64)(info.modify_time / SDL_NS_PER_SECOND);
+    stat->readonly = 0;
+    return 1;
+} /* __PHYSFS_platformStat */
+
+static void *doOpen(const char *filename, const char* mode)
+{
+    SDL_IOStream *io = SDL_IOFromFile(filename, mode);
+    BAIL_IF(io == NULL, PHYSFS_ERR_OS_ERROR, NULL);
+    return io;
+} /* doOpen */
+
+void *__PHYSFS_platformOpenRead(const char *filename)
+{
+    return doOpen(filename, "rb");
+}  /* __PHYSFS_platformOpenRead */
+
+void *__PHYSFS_platformOpenWrite(const char *filename)
+{
+    return doOpen(filename, "wb");
+} /* __PHYSFS_platformOpenWrite */
+
+void *__PHYSFS_platformOpenAppend(const char *filename)
+{
+    return doOpen(filename, "ab");
+} /* __PHYSFS_platformOpenAppend */
+
+PHYSFS_sint64 __PHYSFS_platformRead(void *opaque, void *buf, PHYSFS_uint64 len)
+{
+    SDL_IOStream *io = (SDL_IOStream *)opaque;
+    size_t size = (size_t)len;
+    size_t rc = SDL_ReadIO(io, buf, size);
+    BAIL_IF(rc < size && SDL_GetIOStatus(io) == SDL_IO_STATUS_ERROR, PHYSFS_ERR_IO, -1);
+    return (PHYSFS_sint64)rc;
+} /* __PHYSFS_platformRead */
+
+PHYSFS_sint64 __PHYSFS_platformWrite(void *opaque, const void *buf, PHYSFS_uint64 len)
+{
+    SDL_IOStream *io = (SDL_IOStream *)opaque;
+    size_t size = (size_t)len;
+    size_t rc = SDL_WriteIO(io, buf, size);
+    BAIL_IF(rc < size && SDL_GetIOStatus(io) == SDL_IO_STATUS_ERROR, PHYSFS_ERR_IO, -1);
+    return (PHYSFS_sint64)rc;
+} /* __PHYSFS_platformWrite */
+
+int __PHYSFS_platformSeek(void *opaque, PHYSFS_uint64 pos)
+{
+    BAIL_IF(SDL_SeekIO((SDL_IOStream *)opaque, (Sint64)pos, SDL_IO_SEEK_SET) < 0, PHYSFS_ERR_IO, 0);
+    return 1;
+} /* __PHYSFS_platformSeek */
+
+PHYSFS_sint64 __PHYSFS_platformTell(void *opaque)
+{
+    Sint64 pos = SDL_TellIO((SDL_IOStream *)opaque);
+    BAIL_IF(pos < 0, PHYSFS_ERR_IO, -1);
+    return (PHYSFS_sint64)pos;
+} /* __PHYSFS_platformTell */
+
+PHYSFS_sint64 __PHYSFS_platformFileLength(void *opaque)
+{
+    Sint64 size = SDL_GetIOSize((SDL_IOStream *)opaque);
+    BAIL_IF(size < 0, PHYSFS_ERR_IO, -1);
+    return (PHYSFS_sint64)size;
+} /* __PHYSFS_platformFileLength */
+
+int __PHYSFS_platformFlush(void *opaque)
+{
+    BAIL_IF(!SDL_FlushIO((SDL_IOStream *)opaque), PHYSFS_ERR_IO, 0);
+    return 1;
+} /* __PHYSFS_platformFlush */
+
+void __PHYSFS_platformClose(void *opaque)
+{
+    if (!SDL_CloseIO((SDL_IOStream *)opaque)) {
+        SDL_ClearError();
+    }
+} /* __PHYSFS_platformClose */
+
+#endif

+ 3 - 1
src/physfs_platforms.h

@@ -12,7 +12,9 @@
  *  PHYSFS_PLATFORM_UNIX on that system.
  */
 
-#if defined(TARGET_EXTENSION) && (defined(TARGET_PLAYDATE) || defined(TARGET_SIMULATOR))
+#if defined(PHYSFS_PLATFORM_SDL3)
+#define PHYSFS_NO_CDROM_SUPPORT 1
+#elif defined(TARGET_EXTENSION) && (defined(TARGET_PLAYDATE) || defined(TARGET_SIMULATOR))
 #  define PHYSFS_PLATFORM_PLAYDATE 1
 #  define PHYSFS_NO_CRUNTIME_MALLOC 1
 #elif (defined __EMSCRIPTEN__)