Don't use BESS for internal in-memory saves
This commit is contained in:
parent
dfdbff7304
commit
fada772cb1
@ -1899,7 +1899,7 @@ static bool undo(GB_gameboy_t *gb, char *arguments, char *modifiers, const debug
|
||||
return true;
|
||||
}
|
||||
uint16_t pc = gb->pc;
|
||||
GB_load_state_from_buffer(gb, gb->undo_state, GB_get_save_state_size(gb));
|
||||
GB_load_state_from_buffer(gb, gb->undo_state, GB_get_save_state_size_no_bess(gb));
|
||||
GB_log(gb, "Reverted a \"%s\" command.\n", gb->undo_label);
|
||||
if (pc != gb->pc) {
|
||||
GB_cpu_disassemble(gb, gb->pc, 5);
|
||||
@ -2205,8 +2205,8 @@ bool GB_debugger_execute_command(GB_gameboy_t *gb, char *input)
|
||||
|
||||
const debugger_command_t *command = find_command(command_string);
|
||||
if (command) {
|
||||
uint8_t *old_state = malloc(GB_get_save_state_size(gb));
|
||||
GB_save_state_to_buffer(gb, old_state);
|
||||
uint8_t *old_state = malloc(GB_get_save_state_size_no_bess(gb));
|
||||
GB_save_state_to_buffer_no_bess(gb, old_state);
|
||||
bool ret = command->implementation(gb, arguments, modifiers, command);
|
||||
if (!ret) { // Command continues, save state in any case
|
||||
free(gb->undo_state);
|
||||
@ -2214,9 +2214,9 @@ bool GB_debugger_execute_command(GB_gameboy_t *gb, char *input)
|
||||
gb->undo_label = command->command;
|
||||
}
|
||||
else {
|
||||
uint8_t *new_state = malloc(GB_get_save_state_size(gb));
|
||||
GB_save_state_to_buffer(gb, new_state);
|
||||
if (memcmp(new_state, old_state, GB_get_save_state_size(gb)) != 0) {
|
||||
uint8_t *new_state = malloc(GB_get_save_state_size_no_bess(gb));
|
||||
GB_save_state_to_buffer_no_bess(gb, new_state);
|
||||
if (memcmp(new_state, old_state, GB_get_save_state_size_no_bess(gb)) != 0) {
|
||||
// State changed, save the old state as the new undo state
|
||||
free(gb->undo_state);
|
||||
gb->undo_state = old_state;
|
||||
@ -2306,8 +2306,8 @@ void GB_debugger_run(GB_gameboy_t *gb)
|
||||
if (gb->debug_disable) return;
|
||||
|
||||
if (!gb->undo_state) {
|
||||
gb->undo_state = malloc(GB_get_save_state_size(gb));
|
||||
GB_save_state_to_buffer(gb, gb->undo_state);
|
||||
gb->undo_state = malloc(GB_get_save_state_size_no_bess(gb));
|
||||
GB_save_state_to_buffer_no_bess(gb, gb->undo_state);
|
||||
}
|
||||
|
||||
char *input = NULL;
|
||||
@ -2355,9 +2355,9 @@ next_command:
|
||||
}
|
||||
else if (jump_to_result == JUMP_TO_NONTRIVIAL) {
|
||||
if (!gb->nontrivial_jump_state) {
|
||||
gb->nontrivial_jump_state = malloc(GB_get_save_state_size(gb));
|
||||
gb->nontrivial_jump_state = malloc(GB_get_save_state_size_no_bess(gb));
|
||||
}
|
||||
GB_save_state_to_buffer(gb, gb->nontrivial_jump_state);
|
||||
GB_save_state_to_buffer_no_bess(gb, gb->nontrivial_jump_state);
|
||||
gb->non_trivial_jump_breakpoint_occured = false;
|
||||
should_delete_state = false;
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ static void state_decompress(const uint8_t *prev, uint8_t *data, uint8_t *dest,
|
||||
|
||||
void GB_rewind_push(GB_gameboy_t *gb)
|
||||
{
|
||||
const size_t save_size = GB_get_save_state_size(gb);
|
||||
const size_t save_size = GB_get_save_state_size_no_bess(gb);
|
||||
if (!gb->rewind_sequences) {
|
||||
if (gb->rewind_buffer_length) {
|
||||
gb->rewind_sequences = malloc(sizeof(*gb->rewind_sequences) * gb->rewind_buffer_length);
|
||||
@ -140,11 +140,11 @@ void GB_rewind_push(GB_gameboy_t *gb)
|
||||
|
||||
if (!gb->rewind_sequences[gb->rewind_pos].key_state) {
|
||||
gb->rewind_sequences[gb->rewind_pos].key_state = malloc(save_size);
|
||||
GB_save_state_to_buffer(gb, gb->rewind_sequences[gb->rewind_pos].key_state);
|
||||
GB_save_state_to_buffer_no_bess(gb, gb->rewind_sequences[gb->rewind_pos].key_state);
|
||||
}
|
||||
else {
|
||||
uint8_t *save_state = malloc(save_size);
|
||||
GB_save_state_to_buffer(gb, save_state);
|
||||
GB_save_state_to_buffer_no_bess(gb, save_state);
|
||||
gb->rewind_sequences[gb->rewind_pos].compressed_states[gb->rewind_sequences[gb->rewind_pos].pos++] =
|
||||
state_compress(gb->rewind_sequences[gb->rewind_pos].key_state, save_state, save_size);
|
||||
free(save_state);
|
||||
@ -158,7 +158,7 @@ bool GB_rewind_pop(GB_gameboy_t *gb)
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t save_size = GB_get_save_state_size(gb);
|
||||
const size_t save_size = GB_get_save_state_size_no_bess(gb);
|
||||
if (gb->rewind_sequences[gb->rewind_pos].pos == 0) {
|
||||
GB_load_state_from_buffer(gb, gb->rewind_sequences[gb->rewind_pos].key_state, save_size);
|
||||
free(gb->rewind_sequences[gb->rewind_pos].key_state);
|
||||
|
@ -218,7 +218,7 @@ static size_t bess_size_for_cartridge(const GB_cartridge_t *cart)
|
||||
}
|
||||
}
|
||||
|
||||
size_t GB_get_save_state_size(GB_gameboy_t *gb)
|
||||
size_t GB_get_save_state_size_no_bess(GB_gameboy_t *gb)
|
||||
{
|
||||
return GB_SECTION_SIZE(header)
|
||||
+ GB_SECTION_SIZE(core_state) + sizeof(uint32_t)
|
||||
@ -232,7 +232,12 @@ size_t GB_get_save_state_size(GB_gameboy_t *gb)
|
||||
+ (GB_is_hle_sgb(gb)? sizeof(*gb->sgb) + sizeof(uint32_t) : 0)
|
||||
+ gb->mbc_ram_size
|
||||
+ gb->ram_size
|
||||
+ gb->vram_size
|
||||
+ gb->vram_size;
|
||||
}
|
||||
|
||||
size_t GB_get_save_state_size(GB_gameboy_t *gb)
|
||||
{
|
||||
return GB_get_save_state_size_no_bess(gb) +
|
||||
// BESS
|
||||
+ sizeof(BESS_CORE_t)
|
||||
+ sizeof(BESS_block_t) // NAME
|
||||
@ -453,7 +458,7 @@ static int save_bess_mbc_block(GB_gameboy_t *gb, virtual_file_t *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int save_state_internal(GB_gameboy_t *gb, virtual_file_t *file)
|
||||
static int save_state_internal(GB_gameboy_t *gb, virtual_file_t *file, bool append_bess)
|
||||
{
|
||||
if (file->write(file, GB_GET_SECTION(gb, header), GB_SECTION_SIZE(header)) != GB_SECTION_SIZE(header)) goto error;
|
||||
if (!DUMP_SECTION(gb, file, core_state)) goto error;
|
||||
@ -475,6 +480,7 @@ static int save_state_internal(GB_gameboy_t *gb, virtual_file_t *file)
|
||||
if (!dump_section(file, gb->sgb, sizeof(*gb->sgb))) goto error;
|
||||
}
|
||||
|
||||
|
||||
BESS_CORE_t bess_core = {0,};
|
||||
|
||||
bess_core.mbc_ram.offset = LE32(file->tell(file));
|
||||
@ -495,6 +501,8 @@ static int save_state_internal(GB_gameboy_t *gb, virtual_file_t *file)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!append_bess) return 0;
|
||||
|
||||
BESS_footer_t bess_footer = {
|
||||
.start_offset = LE32(file->tell(file)),
|
||||
.magic = BE32('BESS'),
|
||||
@ -694,7 +702,7 @@ int GB_save_state(GB_gameboy_t *gb, const char *path)
|
||||
.tell = file_tell,
|
||||
.file = f,
|
||||
};
|
||||
int ret = save_state_internal(gb, &file);
|
||||
int ret = save_state_internal(gb, &file, true);
|
||||
fclose(f);
|
||||
return ret;
|
||||
}
|
||||
@ -709,10 +717,23 @@ void GB_save_state_to_buffer(GB_gameboy_t *gb, uint8_t *buffer)
|
||||
.position = 0,
|
||||
};
|
||||
|
||||
save_state_internal(gb, &file);
|
||||
save_state_internal(gb, &file, true);
|
||||
assert(file.position == GB_get_save_state_size(gb));
|
||||
}
|
||||
|
||||
void GB_save_state_to_buffer_no_bess(GB_gameboy_t *gb, uint8_t *buffer)
|
||||
{
|
||||
virtual_file_t file = {
|
||||
.write = buffer_write,
|
||||
.seek = buffer_seek,
|
||||
.tell = buffer_tell,
|
||||
.buffer = (uint8_t *)buffer,
|
||||
.position = 0,
|
||||
};
|
||||
|
||||
save_state_internal(gb, &file, false);
|
||||
assert(file.position == GB_get_save_state_size_no_bess(gb));
|
||||
}
|
||||
|
||||
static bool read_section(virtual_file_t *file, void *dest, uint32_t size, bool fix_broken_windows_saves)
|
||||
{
|
||||
|
@ -27,4 +27,11 @@ void GB_save_state_to_buffer(GB_gameboy_t *gb, uint8_t *buffer);
|
||||
|
||||
int GB_load_state(GB_gameboy_t *gb, const char *path);
|
||||
int GB_load_state_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t length);
|
||||
|
||||
#ifdef GB_INTERNAL
|
||||
/* For internal in-memory save states (rewind, debugger) that do not need BESS */
|
||||
size_t GB_get_save_state_size_no_bess(GB_gameboy_t *gb);
|
||||
void GB_save_state_to_buffer_no_bess(GB_gameboy_t *gb, uint8_t *buffer);
|
||||
#endif
|
||||
|
||||
#endif /* save_state_h */
|
||||
|
Loading…
Reference in New Issue
Block a user