+ // it's currently 4380651 bytes, but have some reserved for future
+ return 0x430000;
+}
+
+struct save_fp {
+ char *buf;
+ size_t pos;
+ int is_write;
+};
+
+static void *save_open(const char *name, const char *mode)
+{
+ struct save_fp *fp;
+
+ if (name == NULL || mode == NULL)
+ return NULL;
+
+ fp = malloc(sizeof(*fp));
+ if (fp == NULL)
+ return NULL;
+
+ fp->buf = (char *)name;
+ fp->pos = 0;
+ fp->is_write = (mode[0] == 'w' || mode[1] == 'w');
+
+ return fp;
+}
+
+static int save_read(void *file, void *buf, u32 len)
+{
+ struct save_fp *fp = file;
+ if (fp == NULL || buf == NULL)
+ return -1;
+
+ memcpy(buf, fp->buf + fp->pos, len);
+ fp->pos += len;
+ return len;
+}
+
+static int save_write(void *file, const void *buf, u32 len)
+{
+ struct save_fp *fp = file;
+ if (fp == NULL || buf == NULL)
+ return -1;
+
+ memcpy(fp->buf + fp->pos, buf, len);
+ fp->pos += len;
+ return len;
+}
+
+static long save_seek(void *file, long offs, int whence)
+{
+ struct save_fp *fp = file;
+ if (fp == NULL)
+ return -1;
+
+ switch (whence) {
+ case SEEK_CUR:
+ fp->pos += offs;
+ return fp->pos;
+ case SEEK_SET:
+ fp->pos = offs;
+ return fp->pos;
+ default:
+ return -1;
+ }
+}
+
+static void save_close(void *file)
+{
+ struct save_fp *fp = file;
+ size_t r_size = retro_serialize_size();
+ if (fp == NULL)
+ return;
+
+ if (fp->pos > r_size)
+ SysPrintf("ERROR: save buffer overflow detected\n");
+ else if (fp->is_write && fp->pos < r_size)
+ // make sure we don't save trash in leftover space
+ memset(fp->buf + fp->pos, 0, r_size - fp->pos);
+ free(fp);