Basic rewind works!

This commit is contained in:
Themaister 2011-01-31 16:48:42 +01:00
parent c5f825eaa5
commit 351e098da1
6 changed files with 53 additions and 2 deletions

View File

@ -1,6 +1,6 @@
TARGET = ssnes.exe
JTARGET = ssnes-joyconfig.exe
OBJ = ssnes.o file.o driver.o conf/config_file.o settings.o dynamic.o message.o
OBJ = ssnes.o file.o driver.o conf/config_file.o settings.o dynamic.o message.o rewind.o
JOBJ = conf/config_file.o tools/main-stub.o tools/ssnes-joyconfig.o
CC = gcc

View File

@ -184,6 +184,7 @@ static const struct snes_keybind snes_keybinds_1[] = {
{ SSNES_STATE_SLOT_PLUS, SDLK_F7, NO_BTN, AXIS_NONE },
{ SSNES_AUDIO_INPUT_RATE_PLUS, SDLK_KP_PLUS, NO_BTN, AXIS_NONE },
{ SSNES_AUDIO_INPUT_RATE_MINUS, SDLK_KP_MINUS, NO_BTN, AXIS_NONE },
{ SSNES_REWIND, SDLK_r, NO_BTN, AXIS_NONE },
{ -1 }
};

View File

@ -36,6 +36,7 @@ enum
SSNES_STATE_SLOT_MINUS,
SSNES_AUDIO_INPUT_RATE_PLUS,
SSNES_AUDIO_INPUT_RATE_MINUS,
SSNES_REWIND,
};
struct snes_keybind

View File

@ -24,6 +24,7 @@
#include <stdio.h>
#include "record/ffemu.h"
#include "message.h"
#include "rewind.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
@ -35,7 +36,7 @@
#define MAX_PLAYERS 5
#define MAX_BINDS 22 // Needs to be increased every time there are new binds added.
#define MAX_BINDS 23 // Needs to be increased every time there are new binds added.
#define SSNES_NO_JOYPAD 0xFFFF
struct settings
{
@ -145,6 +146,10 @@ struct global
msg_queue_t *msg_queue;
state_manager_t *state_manager;
void *state_buf;
bool rewind_enable;
#ifdef HAVE_FFMPEG
ffemu_t *rec;
char record_path[256];

View File

@ -21,6 +21,8 @@
#include <stdbool.h>
#include <string.h>
//#include <stdio.h>
struct state_manager
{
uint64_t *buffer;
@ -120,6 +122,7 @@ static void reassign_bottom(state_manager_t *state)
static void generate_delta(state_manager_t *state, const void *data, bool aligned)
{
unsigned patch_size = 0;
bool crossed = false;
const uint32_t *old_state = state->tmp_state;
uint32_t *new_state = aligned ? (uint32_t*)data : state->scratch_buf;
@ -138,6 +141,7 @@ static void generate_delta(state_manager_t *state, const void *data, bool aligne
// This, if states don't really differ much, we'll save lots of space :) Hopefully this will work really well with save states.
if (xor)
{
patch_size++;
state->buffer[state->top_ptr] = (i << 32) | xor;
state->top_ptr = (state->top_ptr + 1) % state->buf_size;
@ -148,6 +152,8 @@ static void generate_delta(state_manager_t *state, const void *data, bool aligne
if (crossed)
reassign_bottom(state);
//fprintf(stderr, "DELTA SIZE: %u, ORIG SIZE: %u\n", (unsigned)patch_size << 3, (unsigned)state->state_size << 2);
}
bool state_manager_push(state_manager_t *state, const void *data, bool aligned)

38
ssnes.c
View File

@ -28,6 +28,7 @@
#include "general.h"
#include "dynamic.h"
#include "record/ffemu.h"
#include "rewind.h"
#include <assert.h>
#ifdef HAVE_SRC
#include <samplerate.h>
@ -636,6 +637,22 @@ static void deinit_msg_queue(void)
msg_queue_free(g_extern.msg_queue);
}
static void init_rewind(void)
{
size_t serial_size = snes_serialize_size();
g_extern.state_buf = malloc(serial_size);
snes_serialize(g_extern.state_buf, serial_size);
g_extern.state_manager = state_manager_new(serial_size, 10 << 20, g_extern.state_buf);
}
static void deinit_rewind(void)
{
if (g_extern.state_manager)
state_manager_free(g_extern.state_manager);
if (g_extern.state_buf)
free(g_extern.state_buf);
}
static void fill_pathnames(void)
{
switch (g_extern.game_type)
@ -773,6 +790,24 @@ static void check_input_rate(void)
}
}
static void check_rewind(void)
{
if (!g_extern.state_manager)
return;
if (driver.input->key_pressed(driver.input_data, SSNES_REWIND))
{
void *buf;
if (state_manager_pop(g_extern.state_manager, &buf))
snes_unserialize(buf, snes_serialize_size());
}
else
{
snes_serialize(g_extern.state_buf, snes_serialize_size());
state_manager_push(g_extern.state_manager, g_extern.state_buf, true);
}
}
static void do_state_checks(void)
{
set_fast_forward_button(driver.input->key_pressed(driver.input_data, SSNES_FAST_FORWARD_KEY));
@ -781,6 +816,7 @@ static void do_state_checks(void)
check_savestates();
check_fullscreen();
check_input_rate();
check_rewind();
}
@ -817,6 +853,7 @@ int main(int argc, char *argv[])
#endif
init_msg_queue();
init_rewind();
// Main loop
for(;;)
@ -833,6 +870,7 @@ int main(int argc, char *argv[])
psnes_run();
}
deinit_rewind();
deinit_msg_queue();
#ifdef HAVE_FFMPEG
deinit_recording();