summaryrefslogtreecommitdiff
path: root/tools/hopalong/vfs.cpp
diff options
context:
space:
mode:
authorclaude-bot <[email protected]>2026-07-13 12:40:03 +0000
committerclaude-bot <[email protected]>2026-07-13 12:40:03 +0000
commit847962910f0bff071f3bf07c9abb87764fb6cac3 (patch)
treeddcd429e134c7fd5f72ddc97ced175de8d66fcd0 /tools/hopalong/vfs.cpp
downloadlibrw-master.tar.gz
librw-master.zip
Import aap/librw @ masterHEADmaster
Snapshot for re3/reVC vendoring, per @lzcnt. Source: https://github.com/aap/librw (master).
Diffstat (limited to 'tools/hopalong/vfs.cpp')
-rw-r--r--tools/hopalong/vfs.cpp133
1 files changed, 133 insertions, 0 deletions
diff --git a/tools/hopalong/vfs.cpp b/tools/hopalong/vfs.cpp
new file mode 100644
index 0000000..c54d241
--- /dev/null
+++ b/tools/hopalong/vfs.cpp
@@ -0,0 +1,133 @@
+#include <rw.h>
+#include <string.h>
+
+#include "vfs.h"
+
+struct FILE_VFS
+{
+ int used;
+ rw::uint8 *data;
+ int pos;
+ int size;
+};
+FILE_VFS vfsfiles[64];
+VFS *globalVFS;
+
+void*
+vfs_fopen(const char *path, const char *mode)
+{
+ int flags = 0;
+ int i, j;
+ char *r, *w, *plus;
+
+// printf("trying to open <%s> mode <%s>\n", path, mode);
+ const char *file = strrchr((char*)path, '/');
+ if(file)
+ file++;
+ else
+ file = path;
+ for(i = 0; i < nelem(vfsfiles); i++){
+ if(!vfsfiles[i].used)
+ goto found;
+ }
+ // no file pointer available
+ return nil;
+found:
+
+ // why can't we pass const char*? urghhh....
+ r = strchr((char*)mode, 'r');
+ w = strchr((char*)mode, 'w');
+ plus = strchr((char*)mode, '+');
+ // cannot write files
+ if(w || plus)
+ return nil;
+
+ for(j = 0; j < globalVFS->numFiles; j++){
+ if(strcmp(globalVFS->files[j].name, file) == 0)
+ goto found2;
+ }
+ // file not found
+ return nil;
+found2:
+
+ vfsfiles[i].used = 1;
+ vfsfiles[i].data = globalVFS->files[j].data;
+ vfsfiles[i].pos = 0;
+ vfsfiles[i].size = globalVFS->files[j].length;
+ return &vfsfiles[i];
+}
+
+int
+vfs_fclose(void *fp)
+{
+ FILE_VFS *f = (FILE_VFS*)fp;
+ if(!f->used)
+ return EOF;
+ f->used = 0;
+ f->data = nil;
+ return 0;
+}
+
+int
+vfs_fseek(void *fp, long offset, int whence)
+{
+ FILE_VFS *f = (FILE_VFS*)fp;
+ switch(whence){
+ case 0:
+ f->pos = offset;
+ break;
+ case 1:
+ f->pos += offset;
+ break;
+ case 2:
+ f->pos = f->size - offset;
+ break;
+ }
+ if(f->pos > f->size) f->pos = f->size;
+ return f->pos;
+}
+
+long
+vfs_ftell(void *fp)
+{
+ FILE_VFS *f = (FILE_VFS*)fp;
+ return f->pos;
+}
+
+size_t
+vfs_fread(void *ptr, size_t size, size_t nmemb, void *fp)
+{
+ FILE_VFS *f = (FILE_VFS*)fp;
+ size_t sz = size*nmemb;
+ if(sz > f->size-f->pos)
+ sz = f->size-f->pos;
+ memcpy(ptr, f->data+f->pos, sz);
+ f->pos += sz;
+ return sz/size;
+}
+
+size_t
+vfs_fwrite(const void *ptr, size_t size, size_t nmemb, void *fp)
+{
+ return 0;
+}
+
+int
+vfs_feof(void *fp)
+{
+ FILE_VFS *f = (FILE_VFS*)fp;
+ return f->pos >= f->size;
+}
+
+void
+installVFS(VFS *vfs)
+{
+ globalVFS = vfs;
+ rw::engine->filefuncs.rwfopen = vfs_fopen;
+ rw::engine->filefuncs.rwfclose = vfs_fclose;
+ rw::engine->filefuncs.rwfseek = vfs_fseek;
+ rw::engine->filefuncs.rwftell = vfs_ftell;
+ rw::engine->filefuncs.rwfread = vfs_fread;
+ rw::engine->filefuncs.rwfwrite = vfs_fwrite;
+ rw::engine->filefuncs.rwfeof = vfs_feof;
+}