mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-23 16:09:47 +00:00
Fix up stuff. Alignment is done in client code.
This commit is contained in:
parent
47d0b12d40
commit
a81d6bc247
20
rewind.c
20
rewind.c
@ -20,6 +20,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
//#include <stdio.h>
|
||||
|
||||
@ -43,6 +44,7 @@ state_manager_t *state_manager_new(size_t state_size, size_t buffer_size, void *
|
||||
if (!state)
|
||||
return NULL;
|
||||
|
||||
assert(state_size % 4 == 0); // We need 4-byte aligned state_size to avoid having to enforce this with unneeded memcpy's!
|
||||
state->top_ptr = 1;
|
||||
state->state_size = (state_size + 3) >> 2; // Multiple of 4.
|
||||
state->buf_size = (buffer_size + 7) >> 3; // Multiple of 8.
|
||||
@ -50,8 +52,6 @@ state_manager_t *state_manager_new(size_t state_size, size_t buffer_size, void *
|
||||
goto error;
|
||||
if (!(state->tmp_state = calloc(1, state->state_size * sizeof(uint32_t))))
|
||||
goto error;
|
||||
if (!(state->scratch_buf = calloc(1, state->state_size * sizeof(uint32_t))))
|
||||
goto error;
|
||||
|
||||
memcpy(state->tmp_state, init_buffer, state_size);
|
||||
|
||||
@ -62,7 +62,6 @@ error:
|
||||
{
|
||||
free(state->buffer);
|
||||
free(state->tmp_state);
|
||||
free(state->scratch_buf);
|
||||
free(state);
|
||||
}
|
||||
return NULL;
|
||||
@ -72,7 +71,6 @@ void state_manager_free(state_manager_t *state)
|
||||
{
|
||||
free(state->buffer);
|
||||
free(state->tmp_state);
|
||||
free(state->scratch_buf);
|
||||
free(state);
|
||||
}
|
||||
|
||||
@ -120,14 +118,12 @@ static void reassign_bottom(state_manager_t *state)
|
||||
state->bottom_ptr = (state->bottom_ptr + 1) % state->buf_size;
|
||||
}
|
||||
|
||||
static void generate_delta(state_manager_t *state, const void *data, bool aligned)
|
||||
static void generate_delta(state_manager_t *state, const void *data)
|
||||
{
|
||||
unsigned patch_size = 0;
|
||||
//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;
|
||||
if (!aligned)
|
||||
memcpy(new_state, data, state->state_size * sizeof(uint32_t)); // If not guaranteed to be aligned, we need to make sure it is.
|
||||
const uint32_t *new_state = data;
|
||||
|
||||
state->buffer[state->top_ptr++] = 0; // For each separate delta, we have a 0 value sentinel in between.
|
||||
if (state->top_ptr == state->bottom_ptr) // Check if top_ptr and bottom_ptr crossed eachother, which means we need to delete old cruft.
|
||||
@ -141,7 +137,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++;
|
||||
//patch_size++;
|
||||
state->buffer[state->top_ptr] = (i << 32) | xor;
|
||||
state->top_ptr = (state->top_ptr + 1) % state->buf_size;
|
||||
|
||||
@ -156,9 +152,9 @@ static void generate_delta(state_manager_t *state, const void *data, bool aligne
|
||||
//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)
|
||||
bool state_manager_push(state_manager_t *state, const void *data)
|
||||
{
|
||||
generate_delta(state, data, aligned);
|
||||
generate_delta(state, data);
|
||||
memcpy(state->tmp_state, data, state->state_size * sizeof(uint32_t));
|
||||
|
||||
return true;
|
||||
|
4
rewind.h
4
rewind.h
@ -23,9 +23,11 @@
|
||||
|
||||
typedef struct state_manager state_manager_t;
|
||||
|
||||
// Always pass in at least 4-byte aligned data and sizes!
|
||||
|
||||
state_manager_t *state_manager_new(size_t state_size, size_t buffer_size, void *init_buffer);
|
||||
void state_manager_free(state_manager_t *state);
|
||||
bool state_manager_pop(state_manager_t *state, void **data);
|
||||
bool state_manager_push(state_manager_t *state, const void *data, bool aligned);
|
||||
bool state_manager_push(state_manager_t *state, const void *data);
|
||||
|
||||
#endif
|
||||
|
8
ssnes.c
8
ssnes.c
@ -646,10 +646,10 @@ static void init_rewind(void)
|
||||
if (g_settings.rewind_enable)
|
||||
{
|
||||
size_t serial_size = snes_serialize_size();
|
||||
g_extern.state_buf = malloc(serial_size);
|
||||
g_extern.state_buf = malloc((serial_size + 3) & ~3); // Make sure we allocate at least 4-byte multiple.
|
||||
snes_serialize(g_extern.state_buf, serial_size);
|
||||
SSNES_LOG("Initing rewind buffer with size: %u MB\n", (unsigned)g_settings.rewind_buffer_size / 1000000);
|
||||
g_extern.state_manager = state_manager_new(serial_size, g_settings.rewind_buffer_size, g_extern.state_buf);
|
||||
g_extern.state_manager = state_manager_new((serial_size + 3) & ~3, g_settings.rewind_buffer_size, g_extern.state_buf);
|
||||
if (!g_extern.state_manager)
|
||||
SSNES_WARN("Failed to init rewind buffer. Rewinding will be disabled!\n");
|
||||
}
|
||||
@ -811,6 +811,8 @@ static void check_rewind(void)
|
||||
void *buf;
|
||||
if (state_manager_pop(g_extern.state_manager, &buf))
|
||||
{
|
||||
msg_queue_clear(g_extern.msg_queue);
|
||||
msg_queue_push(g_extern.msg_queue, "Rewinding!", 0, 30);
|
||||
snes_unserialize(buf, snes_serialize_size());
|
||||
g_extern.frame_is_reverse = true;
|
||||
}
|
||||
@ -818,7 +820,7 @@ static void check_rewind(void)
|
||||
else
|
||||
{
|
||||
snes_serialize(g_extern.state_buf, snes_serialize_size());
|
||||
state_manager_push(g_extern.state_manager, g_extern.state_buf, true);
|
||||
state_manager_push(g_extern.state_manager, g_extern.state_buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user