From 1a30dcc5537a4263209f0f5c088be6c02b593c72 Mon Sep 17 00:00:00 2001 From: Vicki Pfau Date: Tue, 25 Jul 2017 13:44:23 -0700 Subject: [PATCH] GB Serialize: Fix audio state loading --- CHANGES | 1 + src/gb/audio.c | 2 ++ src/gb/io.c | 30 ++++++++++++++++++++++++++++++ src/gb/serialize.c | 8 ++++---- 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 38ce42b1f..4111b34da 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,7 @@ Bugfixes: - Python: Fix importing .gb or .gba before .core - GBA: Reset active region as needed when loading a ROM - Qt: Fix command line debugger closing second game + - GB Serialize: Fix audio state loading Misc: - GBA Timer: Use global cycles for timers - GBA: Extend oddly-sized ROMs to full address space (fixes mgba.io/i/722) diff --git a/src/gb/audio.c b/src/gb/audio.c index b8541b720..adaa44ff4 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -960,6 +960,8 @@ void GBAudioPSGDeserialize(struct GBAudio* audio, const struct GBSerializedPSGSt mTimingSchedule(audio->timing, &audio->frameEvent, when); LOAD_32LE(flags, 0, flagsIn); + audio->frame = GBSerializedAudioFlagsGetFrame(flags); + LOAD_32LE(ch1Flags, 0, &state->ch1.envelope); audio->ch1.envelope.currentVolume = GBSerializedAudioFlagsGetCh1Volume(flags); audio->ch1.envelope.dead = GBSerializedAudioFlagsGetCh1Dead(flags); diff --git a/src/gb/io.c b/src/gb/io.c index 3be656499..b4c42f7f9 100644 --- a/src/gb/io.c +++ b/src/gb/io.c @@ -580,6 +580,36 @@ void GBIOSerialize(const struct GB* gb, struct GBSerializedState* state) { void GBIODeserialize(struct GB* gb, const struct GBSerializedState* state) { memcpy(gb->memory.io, state->io, GB_SIZE_IO); gb->memory.ie = state->ie; + + if (GBAudioEnableGetEnable(*gb->audio.nr52)) { + GBIOWrite(gb, REG_NR10, gb->memory.io[REG_NR10]); + GBIOWrite(gb, REG_NR11, gb->memory.io[REG_NR11]); + GBIOWrite(gb, REG_NR12, gb->memory.io[REG_NR12]); + GBIOWrite(gb, REG_NR13, gb->memory.io[REG_NR13]); + gb->audio.ch1.control.frequency &= 0xFF; + gb->audio.ch1.control.frequency |= GBAudioRegisterControlGetFrequency(gb->memory.io[REG_NR14] << 8); + gb->audio.ch1.control.stop = GBAudioRegisterControlGetStop(gb->memory.io[REG_NR14] << 8); + GBIOWrite(gb, REG_NR21, gb->memory.io[REG_NR21]); + GBIOWrite(gb, REG_NR22, gb->memory.io[REG_NR22]); + GBIOWrite(gb, REG_NR22, gb->memory.io[REG_NR23]); + gb->audio.ch2.control.frequency &= 0xFF; + gb->audio.ch2.control.frequency |= GBAudioRegisterControlGetFrequency(gb->memory.io[REG_NR24] << 8); + gb->audio.ch2.control.stop = GBAudioRegisterControlGetStop(gb->memory.io[REG_NR24] << 8); + GBIOWrite(gb, REG_NR30, gb->memory.io[REG_NR30]); + GBIOWrite(gb, REG_NR31, gb->memory.io[REG_NR31]); + GBIOWrite(gb, REG_NR32, gb->memory.io[REG_NR32]); + GBIOWrite(gb, REG_NR32, gb->memory.io[REG_NR33]); + gb->audio.ch3.rate &= 0xFF; + gb->audio.ch3.rate |= GBAudioRegisterControlGetRate(gb->memory.io[REG_NR34] << 8); + gb->audio.ch3.stop = GBAudioRegisterControlGetStop(gb->memory.io[REG_NR34] << 8); + GBIOWrite(gb, REG_NR41, gb->memory.io[REG_NR41]); + GBIOWrite(gb, REG_NR42, gb->memory.io[REG_NR42]); + GBIOWrite(gb, REG_NR43, gb->memory.io[REG_NR43]); + gb->audio.ch4.stop = GBAudioRegisterNoiseControlGetStop(gb->memory.io[REG_NR44]); + GBIOWrite(gb, REG_NR50, gb->memory.io[REG_NR50]); + GBIOWrite(gb, REG_NR51, gb->memory.io[REG_NR51]); + } + gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_LCDC, state->io[REG_LCDC]); gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_SCY, state->io[REG_SCY]); gb->video.renderer->writeVideoRegister(gb->video.renderer, REG_SCX, state->io[REG_SCX]); diff --git a/src/gb/serialize.c b/src/gb/serialize.c index d9f192092..006f126a7 100644 --- a/src/gb/serialize.c +++ b/src/gb/serialize.c @@ -150,16 +150,16 @@ bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state) { gb->doubleSpeed = GBSerializedCpuFlagsGetDoubleSpeed(flags); gb->audio.timingFactor = gb->doubleSpeed + 1; + LOAD_32LE(gb->cpu->cycles, 0, &state->cpu.cycles); + LOAD_32LE(gb->cpu->nextEvent, 0, &state->cpu.nextEvent); + gb->timing.root = NULL; + uint32_t when; LOAD_32LE(when, 0, &state->cpu.eiPending); if (GBSerializedCpuFlagsIsEiPending(flags)) { mTimingSchedule(&gb->timing, &gb->eiPending, when); } - LOAD_32LE(gb->cpu->cycles, 0, &state->cpu.cycles); - LOAD_32LE(gb->cpu->nextEvent, 0, &state->cpu.nextEvent); - gb->timing.root = NULL; - gb->model = state->model; if (gb->model < GB_MODEL_CGB) {