From fcbf63e62c627deae76c1b8cb8c0876c536ed811 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Mon, 16 Mar 2020 18:49:26 +0900 Subject: Fresh start --- jni/physfs-serve-sdl-wrap.c | 162 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 jni/physfs-serve-sdl-wrap.c (limited to 'jni/physfs-serve-sdl-wrap.c') diff --git a/jni/physfs-serve-sdl-wrap.c b/jni/physfs-serve-sdl-wrap.c new file mode 100644 index 0000000..ccdbce4 --- /dev/null +++ b/jni/physfs-serve-sdl-wrap.c @@ -0,0 +1,162 @@ +#include "libphysfs-serve.h" +#include +#include +#include +#include +#include + +static void ignore_ret(bool b, ...) {}; +#define ignore_ret(x) ignore_ret(true, x); + +struct io_wrapper { + SDL_RWops *ops; + const char *path; +}; + +static SDL_RWops* +get_ops(struct io_wrapper *w) { return w->ops; } + +static const char* +get_path(struct io_wrapper *w) { return w->path; } + +static PHYSFS_sint64 +SDLRWIoRead(struct PHYSFS_Io *io, void *buf, PHYSFS_uint64 len) { + return SDL_RWread(get_ops(io->opaque), buf, 1, len); +} + +static int +SDLRWIoSeek(struct PHYSFS_Io *io, PHYSFS_uint64 offset) { + return (SDL_RWseek(get_ops(io->opaque), offset, RW_SEEK_SET) != -1); +} + +static PHYSFS_sint64 +SDLRWIoTell(struct PHYSFS_Io *io) { + return SDL_RWseek(get_ops(io->opaque), 0, RW_SEEK_CUR); +} + +static PHYSFS_sint64 +SDLRWIoLength(struct PHYSFS_Io *io) { + return SDL_RWsize(get_ops(io->opaque)); +} + +static PHYSFS_Io* SDLRWIo_new(const char *path); + +static struct PHYSFS_Io* +SDLRWIoDuplicate(struct PHYSFS_Io *io) { + PHYSFS_Io *dup = SDLRWIo_new(get_path(io->opaque)); + if (dup) SDLRWIoSeek(dup, io->tell(io)); + return dup; +} + +static void +SDLRWIoDestroy(struct PHYSFS_Io *io) { + SDL_RWclose(get_ops(io->opaque)); + free(io->opaque); + free(io); +} + +static void* +copy_dynamic(const void *ptr, const size_t size) { + void *cpy = malloc(size); + memcpy(cpy, ptr, size); + return cpy; +} +#define copy_static(x) copy_dynamic(&x, sizeof(x)) + +static PHYSFS_Io* +SDLRWIo_new(const char *path) { + struct io_wrapper wrapper = { + .ops = SDL_RWFromFile(path, "r"), + .path = path, + }; + + if (!wrapper.ops) + return NULL; + + struct PHYSFS_Io io = { + .version = 0, + .opaque = copy_static(wrapper), + .read = SDLRWIoRead, + .write = NULL, + .seek = SDLRWIoSeek, + .tell = SDLRWIoTell, + .length = SDLRWIoLength, + .duplicate = SDLRWIoDuplicate, + .flush = NULL, + .destroy = SDLRWIoDestroy + }; + + if (!io.opaque) { + SDL_RWclose(wrapper.ops); + return NULL; + } + + return copy_static(io); +} + +static bool +mount(const char *path, const char *root, bool append) { + if (PHYSFS_mount(path, root, append)) + return true; + + PHYSFS_Io *io = SDLRWIo_new(path); + if (!PHYSFS_mountIo(io, path, root, append)) { + io->destroy(io); + return false; + } + + return true; +} + +static const char* +content_type(struct physfs_serve *serve, const char *path) { + if (physfs_ends_with(path, ".rpgmvp")) return "image/png"; + else if (physfs_ends_with(path, ".rpgmvo")) return "audio/ogg"; + else if (physfs_ends_with(path, ".rpgmvm")) return "audio/mp4"; + return physfs_default_content_type(serve, path); +} + +static bool +path_rewrite(struct physfs_serve *serve, char buf[], const size_t bufsz, struct PHYSFS_Stat *st) { + if (physfs_default_path_rewrite(serve, buf, bufsz, st)) return true; + if (physfs_ends_with(buf, ".rpgmvm")) { + buf[strlen(buf) - 1] = 'o'; + if (st->filetype == -1 && PHYSFS_stat(buf, st)) return false; + } else if (physfs_ends_with(buf, ".rpgmvo")) { + buf[strlen(buf) - 1] = 'm'; + if (st->filetype == -1 && PHYSFS_stat(buf, st)) return false; + } else if (physfs_ends_with(buf, ".webm")) { + buf[strlen(buf) - 1] = '0'; + buf[strlen(buf) - 2] = '4'; + buf[strlen(buf) - 3] = 'p'; + buf[strlen(buf) - 4] = 'm'; + if (st->filetype == -1 && PHYSFS_stat(buf, st)) return false; + } else if (physfs_ends_with(buf, ".mp4")) { + buf[strlen(buf) + 2] = 0; + buf[strlen(buf) + 1] = 'm'; + buf[strlen(buf)] = 'b'; + buf[strlen(buf) - 1] = 'e'; + buf[strlen(buf) - 2] = 'w'; + if (st->filetype == -1 && PHYSFS_stat(buf, st)) return false; + } + return false; +} + +#define SERVE_INIT .content_type = content_type, .path_rewrite = path_rewrite +#define PHYSFS_mount mount +#define main physfs_serve_main +#include "physfs-serve.c" +#undef main +#undef PHYSFS_mount +#undef SERVE_INIT + +#include +#include + +int +main(int argc, char *argv[]) { + SDL_Init(0); + int ret = physfs_serve_main(argc, argv); + SDL_Quit(); + return ret; +} -- cgit v1.2.3