diff --git a/CHANGES b/CHANGES index 64f2da4ae..8269b4048 100644 --- a/CHANGES +++ b/CHANGES @@ -25,6 +25,7 @@ Bugfixes: - GBA Video: Fix out of bounds sprite transforms - GBA: Only unhalt CPU if appropriate bit is set in IE - GB: Fix crash when masking savedata + - GB Audio: Fix serialization of channel 3 and NR52 properties Misc: - PSP2: Improved controller rumble - GB, GBA: Prevent loading null ROMs diff --git a/src/gb/audio.c b/src/gb/audio.c index 27070b3eb..f8211c11e 100644 --- a/src/gb/audio.c +++ b/src/gb/audio.c @@ -893,6 +893,7 @@ void GBAudioPSGSerialize(const struct GBAudio* audio, struct GBSerializedPSGStat memcpy(state->ch3.wavebanks, audio->ch3.wavedata32, sizeof(state->ch3.wavebanks)); STORE_16LE(audio->ch3.length, 0, &state->ch3.length); STORE_32LE(audio->nextCh3, 0, &state->ch3.nextEvent); + STORE_32LE(audio->fadeCh3, 0, &state->ch1.nextCh3Fade); flags = GBSerializedAudioFlagsSetCh4Volume(flags, audio->ch4.envelope.currentVolume); flags = GBSerializedAudioFlagsSetCh4Dead(flags, audio->ch4.envelope.dead); @@ -911,6 +912,12 @@ void GBAudioPSGDeserialize(struct GBAudio* audio, const struct GBSerializedPSGSt uint32_t ch2Flags = 0; uint32_t ch4Flags = 0; + audio->playingCh1 = !!(*audio->nr52 & 0x0001); + audio->playingCh2 = !!(*audio->nr52 & 0x0002); + audio->playingCh3 = !!(*audio->nr52 & 0x0004); + audio->playingCh4 = !!(*audio->nr52 & 0x0008); + audio->enable = GBAudioEnableGetEnable(*audio->nr52); + LOAD_32LE(flags, 0, flagsIn); LOAD_32LE(ch1Flags, 0, &state->ch1.envelope); audio->ch1.envelope.currentVolume = GBSerializedAudioFlagsGetCh1Volume(flags); @@ -932,10 +939,12 @@ void GBAudioPSGDeserialize(struct GBAudio* audio, const struct GBSerializedPSGSt audio->ch2.envelope.nextStep = GBSerializedAudioEnvelopeGetNextStep(ch2Flags); LOAD_32LE(audio->nextCh2, 0, &state->ch2.nextEvent); + audio->ch3.readable = GBSerializedAudioFlagsGetCh3Readable(flags); // TODO: Big endian? memcpy(audio->ch3.wavedata32, state->ch3.wavebanks, sizeof(audio->ch3.wavedata32)); LOAD_16LE(audio->ch3.length, 0, &state->ch3.length); LOAD_32LE(audio->nextCh3, 0, &state->ch3.nextEvent); + LOAD_32LE(audio->fadeCh3, 0, &state->ch1.nextCh3Fade); LOAD_32LE(ch4Flags, 0, &state->ch4.envelope); audio->ch4.envelope.currentVolume = GBSerializedAudioFlagsGetCh4Volume(flags); diff --git a/src/gb/serialize.h b/src/gb/serialize.h index 98d12d6a7..d8db7e101 100644 --- a/src/gb/serialize.h +++ b/src/gb/serialize.h @@ -54,7 +54,8 @@ mLOG_DECLARE_CATEGORY(GB_STATE); * | bits 10 - 20: Shadow frequency register * | bits 21 - 31: Reserved * | 0x0004C - 0x0004F: Next frame - * | 0x00050 - 0x00057: Reserved + * | 0x00050 - 0x00053: Next channel 3 fade + * | 0x00054 - 0x00057: Reserved * | 0x00058 - 0x0005B: Next event * 0x0005C - 0x0006B: Audio channel 2 state * | 0x0005C - 0x0005F: Envelepe timing @@ -96,7 +97,8 @@ mLOG_DECLARE_CATEGORY(GB_STATE); * | bits 0 - 3: Current frame * | bit 4: Is channel 1 sweep enabled? * | bit 5: Has channel 1 sweep occurred? - * | bits 6 - 7: Reserved + * | bit 6: Is channel 3's memory readable? + * | bit 7: Reserved * | 0x000A8 - 0x000AB: Next event * | 0x000AC - 0x000AF: Event diff * | 0x000B0 - 0x000B3: Next sample @@ -172,6 +174,7 @@ DECL_BITS(GBSerializedAudioFlags, Ch4Dead, 20, 2); DECL_BITS(GBSerializedAudioFlags, Frame, 22, 3); DECL_BIT(GBSerializedAudioFlags, Ch1SweepEnabled, 25); DECL_BIT(GBSerializedAudioFlags, Ch1SweepOccurred, 26); +DECL_BIT(GBSerializedAudioFlags, Ch3Readable, 27); DECL_BITFIELD(GBSerializedAudioEnvelope, uint32_t); DECL_BITS(GBSerializedAudioEnvelope, Length, 0, 7); @@ -182,7 +185,8 @@ struct GBSerializedPSGState { struct { GBSerializedAudioEnvelope envelope; int32_t nextFrame; - int32_t reserved[2]; + int32_t nextCh3Fade; + int32_t reserved; int32_t nextEvent; } ch1; struct {