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;
|
return true;
|
||||||
}
|
}
|
||||||
uint16_t pc = gb->pc;
|
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);
|
GB_log(gb, "Reverted a \"%s\" command.\n", gb->undo_label);
|
||||||
if (pc != gb->pc) {
|
if (pc != gb->pc) {
|
||||||
GB_cpu_disassemble(gb, gb->pc, 5);
|
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);
|
const debugger_command_t *command = find_command(command_string);
|
||||||
if (command) {
|
if (command) {
|
||||||
uint8_t *old_state = malloc(GB_get_save_state_size(gb));
|
uint8_t *old_state = malloc(GB_get_save_state_size_no_bess(gb));
|
||||||
GB_save_state_to_buffer(gb, old_state);
|
GB_save_state_to_buffer_no_bess(gb, old_state);
|
||||||
bool ret = command->implementation(gb, arguments, modifiers, command);
|
bool ret = command->implementation(gb, arguments, modifiers, command);
|
||||||
if (!ret) { // Command continues, save state in any case
|
if (!ret) { // Command continues, save state in any case
|
||||||
free(gb->undo_state);
|
free(gb->undo_state);
|
||||||
@ -2214,9 +2214,9 @@ bool GB_debugger_execute_command(GB_gameboy_t *gb, char *input)
|
|||||||
gb->undo_label = command->command;
|
gb->undo_label = command->command;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
uint8_t *new_state = malloc(GB_get_save_state_size(gb));
|
uint8_t *new_state = malloc(GB_get_save_state_size_no_bess(gb));
|
||||||
GB_save_state_to_buffer(gb, new_state);
|
GB_save_state_to_buffer_no_bess(gb, new_state);
|
||||||
if (memcmp(new_state, old_state, GB_get_save_state_size(gb)) != 0) {
|
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
|
// State changed, save the old state as the new undo state
|
||||||
free(gb->undo_state);
|
free(gb->undo_state);
|
||||||
gb->undo_state = old_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->debug_disable) return;
|
||||||
|
|
||||||
if (!gb->undo_state) {
|
if (!gb->undo_state) {
|
||||||
gb->undo_state = malloc(GB_get_save_state_size(gb));
|
gb->undo_state = malloc(GB_get_save_state_size_no_bess(gb));
|
||||||
GB_save_state_to_buffer(gb, gb->undo_state);
|
GB_save_state_to_buffer_no_bess(gb, gb->undo_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *input = NULL;
|
char *input = NULL;
|
||||||
@ -2355,9 +2355,9 @@ next_command:
|
|||||||
}
|
}
|
||||||
else if (jump_to_result == JUMP_TO_NONTRIVIAL) {
|
else if (jump_to_result == JUMP_TO_NONTRIVIAL) {
|
||||||
if (!gb->nontrivial_jump_state) {
|
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;
|
gb->non_trivial_jump_breakpoint_occured = false;
|
||||||
should_delete_state = 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)
|
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_sequences) {
|
||||||
if (gb->rewind_buffer_length) {
|
if (gb->rewind_buffer_length) {
|
||||||
gb->rewind_sequences = malloc(sizeof(*gb->rewind_sequences) * 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) {
|
if (!gb->rewind_sequences[gb->rewind_pos].key_state) {
|
||||||
gb->rewind_sequences[gb->rewind_pos].key_state = malloc(save_size);
|
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 {
|
else {
|
||||||
uint8_t *save_state = malloc(save_size);
|
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++] =
|
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);
|
state_compress(gb->rewind_sequences[gb->rewind_pos].key_state, save_state, save_size);
|
||||||
free(save_state);
|
free(save_state);
|
||||||
@ -158,7 +158,7 @@ bool GB_rewind_pop(GB_gameboy_t *gb)
|
|||||||
return false;
|
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) {
|
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);
|
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);
|
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)
|
return GB_SECTION_SIZE(header)
|
||||||
+ GB_SECTION_SIZE(core_state) + sizeof(uint32_t)
|
+ 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_is_hle_sgb(gb)? sizeof(*gb->sgb) + sizeof(uint32_t) : 0)
|
||||||
+ gb->mbc_ram_size
|
+ gb->mbc_ram_size
|
||||||
+ gb->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
|
// BESS
|
||||||
+ sizeof(BESS_CORE_t)
|
+ sizeof(BESS_CORE_t)
|
||||||
+ sizeof(BESS_block_t) // NAME
|
+ 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;
|
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 (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;
|
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;
|
if (!dump_section(file, gb->sgb, sizeof(*gb->sgb))) goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BESS_CORE_t bess_core = {0,};
|
BESS_CORE_t bess_core = {0,};
|
||||||
|
|
||||||
bess_core.mbc_ram.offset = LE32(file->tell(file));
|
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;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!append_bess) return 0;
|
||||||
|
|
||||||
BESS_footer_t bess_footer = {
|
BESS_footer_t bess_footer = {
|
||||||
.start_offset = LE32(file->tell(file)),
|
.start_offset = LE32(file->tell(file)),
|
||||||
.magic = BE32('BESS'),
|
.magic = BE32('BESS'),
|
||||||
@ -694,7 +702,7 @@ int GB_save_state(GB_gameboy_t *gb, const char *path)
|
|||||||
.tell = file_tell,
|
.tell = file_tell,
|
||||||
.file = f,
|
.file = f,
|
||||||
};
|
};
|
||||||
int ret = save_state_internal(gb, &file);
|
int ret = save_state_internal(gb, &file, true);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -709,10 +717,23 @@ void GB_save_state_to_buffer(GB_gameboy_t *gb, uint8_t *buffer)
|
|||||||
.position = 0,
|
.position = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
save_state_internal(gb, &file);
|
save_state_internal(gb, &file, true);
|
||||||
assert(file.position == GB_get_save_state_size(gb));
|
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)
|
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(GB_gameboy_t *gb, const char *path);
|
||||||
int GB_load_state_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t length);
|
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 */
|
#endif /* save_state_h */
|
||||||
|
Loading…
Reference in New Issue
Block a user