#ifndef EMU_COMPILE
#error "Hi I forgot to set EMU_COMPILE"
#endif
#include "vfs.h"
sint32 EMU_CALL vfs_init(void) { return 0; }
#define VFS_MAXPATH (250)
#define VFS_MAXOPENFILES (32)
struct VFS_STATE {
psx_readfile_t readfile_cb;
void *readfile_context;
sint32 ofs[VFS_MAXOPENFILES];
sint32 length[VFS_MAXOPENFILES];
char path[VFS_MAXOPENFILES][VFS_MAXPATH];
};
#define VFSSTATE ((struct VFS_STATE*)(state))
uint32 EMU_CALL vfs_get_state_size(void) {
return sizeof(struct VFS_STATE);
}
void EMU_CALL vfs_clear_state(void *state) {
memset(VFSSTATE, 0, sizeof(struct VFS_STATE));
}
void EMU_CALL vfs_set_readfile(void *state, psx_readfile_t readfile, void *context) {
VFSSTATE->readfile_cb = readfile;
VFSSTATE->readfile_context = context;
}
static sint32 EMU_CALL isvalidfd(struct VFS_STATE *state, sint32 fd) {
if(fd < 0 || fd >= VFS_MAXOPENFILES) return 0;
if(state->path[fd][0] == 0) return 0;
return 1;
}
sint32 EMU_CALL vfs_open(void *state, const char *path) {
sint32 l;
sint32 fd;
char tempbuf[4];
if(!(VFSSTATE->readfile_cb)) return -5; if(!path) return -22; if(!path[0]) return -2; l = (VFSSTATE->readfile_cb)(
VFSSTATE->readfile_context,
path,
0,
tempbuf,
0
);
if(l < -1) return -5; if(l == -1) return -2; for(fd = 0; fd < VFS_MAXOPENFILES; fd++) {
if(VFSSTATE->path[fd][0] == 0) break;
}
if(fd >= VFS_MAXOPENFILES) return -24; VFSSTATE->ofs[fd] = 0;
VFSSTATE->length[fd] = l;
strncpy(VFSSTATE->path[fd], path, VFS_MAXPATH);
VFSSTATE->path[fd][VFS_MAXPATH-1] = 0;
return fd;
}
sint32 EMU_CALL vfs_close(void *state, sint32 fd) {
if(!(VFSSTATE->readfile_cb)) return -5; if(!isvalidfd(VFSSTATE, fd)) return -9; VFSSTATE->path[fd][0] = 0;
return 0;
}
sint32 EMU_CALL vfs_read(void *state, sint32 fd, char *buffer, sint32 length) {
sint32 r;
if(!(VFSSTATE->readfile_cb)) return -5; if(!isvalidfd(VFSSTATE, fd)) return -9; if(!length) return 0;
if(VFSSTATE->ofs[fd] >= VFSSTATE->length[fd]) return 0;
{ sint32 remain = VFSSTATE->length[fd] - VFSSTATE->ofs[fd];
if(length > remain) length = remain;
}
r = (VFSSTATE->readfile_cb)(
VFSSTATE->readfile_context,
VFSSTATE->path[fd],
VFSSTATE->ofs[fd],
buffer,
length
);
if(r < -1) return -5; if(r == -1) return -2; VFSSTATE->ofs[fd] += r;
return r;
}
sint32 EMU_CALL vfs_lseek(void *state, sint32 fd, sint32 offset, sint32 whence) {
if(!(VFSSTATE->readfile_cb)) return -5; if(!isvalidfd(VFSSTATE, fd)) return -9; switch(whence) {
case 0: break;
case 1: offset += VFSSTATE->ofs[fd];
break;
case 2: offset += VFSSTATE->length[fd];
break;
default:
return -22; }
if(offset < 0) return -22; VFSSTATE->ofs[fd] = offset;
return offset;
}