mirror of
https://github.com/RaySollium99/picodrive.git
synced 2025-09-05 07:17:45 -04:00
libretro: add savestate support
This commit is contained in:
parent
989ba52a01
commit
86b38dc46d
3 changed files with 145 additions and 15 deletions
38
pico/state.c
38
pico/state.c
|
@ -11,15 +11,11 @@
|
|||
|
||||
#include "../cpu/sh2/sh2.h"
|
||||
#include "sound/ym2612.h"
|
||||
#include "state.h"
|
||||
|
||||
// sn76496
|
||||
extern int *sn76496_regs;
|
||||
|
||||
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);
|
||||
|
||||
static arearw *areaRead;
|
||||
static arearw *areaWrite;
|
||||
static areaeof *areaEof;
|
||||
|
@ -594,15 +590,10 @@ readend:
|
|||
return 0;
|
||||
}
|
||||
|
||||
int PicoState(const char *fname, int is_save)
|
||||
static int pico_state_internal(void *afile, int is_save)
|
||||
{
|
||||
void *afile = NULL;
|
||||
int ret;
|
||||
|
||||
afile = open_save_file(fname, is_save);
|
||||
if (afile == NULL)
|
||||
return -1;
|
||||
|
||||
if (is_save)
|
||||
ret = state_save(afile);
|
||||
else {
|
||||
|
@ -617,10 +608,35 @@ int PicoState(const char *fname, int is_save)
|
|||
Pico.m.dirtyPal = 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int PicoState(const char *fname, int is_save)
|
||||
{
|
||||
void *afile = NULL;
|
||||
int ret;
|
||||
|
||||
afile = open_save_file(fname, is_save);
|
||||
if (afile == NULL)
|
||||
return -1;
|
||||
|
||||
ret = pico_state_internal(afile, is_save);
|
||||
areaClose(afile);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int PicoStateFP(void *afile, int is_save,
|
||||
arearw *read, arearw *write, areaeof *eof, areaseek *seek)
|
||||
{
|
||||
areaRead = read;
|
||||
areaWrite = write;
|
||||
areaEof = eof;
|
||||
areaSeek = seek;
|
||||
areaClose = NULL;
|
||||
|
||||
return pico_state_internal(afile, is_save);
|
||||
}
|
||||
|
||||
int PicoStateLoadGfx(const char *fname)
|
||||
{
|
||||
void *afile;
|
||||
|
|
9
pico/state.h
Normal file
9
pico/state.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#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);
|
|
@ -17,6 +17,7 @@
|
|||
#endif
|
||||
|
||||
#include <pico/pico_int.h>
|
||||
#include <pico/state.h>
|
||||
#include "common/input_pico.h"
|
||||
#include "common/version.h"
|
||||
#include "libretro.h"
|
||||
|
@ -226,20 +227,124 @@ void retro_get_system_av_info(struct retro_system_av_info *info)
|
|||
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 */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue