\r
#include "../cpu/sh2/sh2.h"\r
#include "sound/ym2612.h"\r
+#include "state.h"\r
\r
// sn76496\r
extern int *sn76496_regs;\r
\r
-typedef size_t (arearw)(void *p, size_t _size, size_t _n, void *file);\r
-typedef size_t (areaeof)(void *file);\r
-typedef int (areaseek)(void *file, long offset, int whence);\r
-typedef int (areaclose)(void *file);\r
-\r
static arearw *areaRead;\r
static arearw *areaWrite;\r
static areaeof *areaEof;\r
return 0;\r
}\r
\r
-int PicoState(const char *fname, int is_save)\r
+static int pico_state_internal(void *afile, int is_save)\r
{\r
- void *afile = NULL;\r
int ret;\r
\r
- afile = open_save_file(fname, is_save);\r
- if (afile == NULL)\r
- return -1;\r
-\r
if (is_save)\r
ret = state_save(afile);\r
else {\r
Pico.m.dirtyPal = 1;\r
}\r
\r
+ return ret;\r
+}\r
+\r
+int PicoState(const char *fname, int is_save)\r
+{\r
+ void *afile = NULL;\r
+ int ret;\r
+\r
+ afile = open_save_file(fname, is_save);\r
+ if (afile == NULL)\r
+ return -1;\r
+\r
+ ret = pico_state_internal(afile, is_save);\r
areaClose(afile);\r
return ret;\r
}\r
\r
+int PicoStateFP(void *afile, int is_save,\r
+ arearw *read, arearw *write, areaeof *eof, areaseek *seek)\r
+{\r
+ areaRead = read;\r
+ areaWrite = write;\r
+ areaEof = eof;\r
+ areaSeek = seek;\r
+ areaClose = NULL;\r
+\r
+ return pico_state_internal(afile, is_save);\r
+}\r
+\r
int PicoStateLoadGfx(const char *fname)\r
{\r
void *afile;\r
--- /dev/null
+#include <stdlib.h>
+
+typedef size_t (arearw)(void *p, size_t _size, size_t _n, void *file);
+typedef size_t (areaeof)(void *file);
+typedef int (areaseek)(void *file, long offset, int whence);
+typedef int (areaclose)(void *file);
+
+int PicoStateFP(void *afile, int is_save,
+ arearw *read, arearw *write, areaeof *eof, areaseek *seek);
#endif
#include <pico/pico_int.h>
+#include <pico/state.h>
#include "common/input_pico.h"
#include "common/version.h"
#include "libretro.h"
info->geometry.aspect_ratio = 4.0 / 3.0;
}
-/* savestates - TODO */
+/* savestates */
+struct savestate_state {
+ const char *load_buf;
+ char *save_buf;
+ size_t size;
+ size_t pos;
+};
+
+size_t state_read(void *p, size_t size, size_t nmemb, void *file)
+{
+ struct savestate_state *state = file;
+ size_t bsize = size * nmemb;
+
+ if (state->pos + bsize > state->size) {
+ lprintf("savestate error: %u/%u\n",
+ state->pos + bsize, state->size);
+ bsize = state->size - state->pos;
+ if ((int)bsize <= 0)
+ return 0;
+ }
+
+ memcpy(p, state->load_buf + state->pos, bsize);
+ state->pos += bsize;
+ return bsize;
+}
+
+size_t state_write(void *p, size_t size, size_t nmemb, void *file)
+{
+ struct savestate_state *state = file;
+ size_t bsize = size * nmemb;
+
+ if (state->pos + bsize > state->size) {
+ lprintf("savestate error: %u/%u\n",
+ state->pos + bsize, state->size);
+ bsize = state->size - state->pos;
+ if ((int)bsize <= 0)
+ return 0;
+ }
+
+ memcpy(state->save_buf + state->pos, p, bsize);
+ state->pos += bsize;
+ return bsize;
+}
+
+size_t state_skip(void *p, size_t size, size_t nmemb, void *file)
+{
+ struct savestate_state *state = file;
+ size_t bsize = size * nmemb;
+
+ state->pos += bsize;
+ return bsize;
+}
+
+size_t state_eof(void *file)
+{
+ struct savestate_state *state = file;
+
+ return state->pos >= state->size;
+}
+
+int state_fseek(void *file, long offset, int whence)
+{
+ struct savestate_state *state = file;
+
+ switch (whence) {
+ case SEEK_SET:
+ state->pos = offset;
+ break;
+ case SEEK_CUR:
+ state->pos += offset;
+ break;
+ case SEEK_END:
+ state->pos = state->size + offset;
+ break;
+ }
+ return (int)state->pos;
+}
+
+/* savestate sizes vary wildly depending if cd/32x or
+ * carthw is active, so run the whole thing to get size */
size_t retro_serialize_size(void)
{
- return 0;
+ struct savestate_state state = { 0, };
+ int ret;
+
+ ret = PicoStateFP(&state, 1, NULL, state_skip, NULL, state_fseek);
+ if (ret != 0)
+ return 0;
+
+ return state.pos;
}
bool retro_serialize(void *data, size_t size)
{
- return false;
+ struct savestate_state state = { 0, };
+ int ret;
+
+ state.save_buf = data;
+ state.size = size;
+ state.pos = 0;
+
+ ret = PicoStateFP(&state, 1, NULL, state_write,
+ NULL, state_fseek);
+ return ret == 0;
}
bool retro_unserialize(const void *data, size_t size)
{
- return false;
+ struct savestate_state state = { 0, };
+ int ret;
+
+ state.load_buf = data;
+ state.size = size;
+ state.pos = 0;
+
+ ret = PicoStateFP(&state, 0, state_read, NULL,
+ state_eof, state_fseek);
+ return ret == 0;
}
/* cheats - TODO */