Fix savestate-related bugs
- Properly save and restore the framebuffer. Avoids display glitches one frame after loading. - Save and restore the base class of channel 4 LFSR (to avoid desyncs).
This commit is contained in:
parent
c10621e3b3
commit
03554f8722
2 changed files with 23 additions and 19 deletions
|
@ -1,4 +1,4 @@
|
|||
From 58e7bcf988a64733c22337e21b74b31d2de7b64b Mon Sep 17 00:00:00 2001
|
||||
From 0c061244bc907dc3f3202f62b771759105825b1f Mon Sep 17 00:00:00 2001
|
||||
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
|
||||
Date: Thu, 12 Jul 2012 20:49:57 +0300
|
||||
Subject: [PATCH] Changes to make libgambatte rerecording-friendly
|
||||
|
@ -41,7 +41,7 @@ Subject: [PATCH] Changes to make libgambatte rerecording-friendly
|
|||
libgambatte/src/sound/channel3.cpp | 41 +++-
|
||||
libgambatte/src/sound/channel3.h | 27 ++-
|
||||
libgambatte/src/sound/channel4.cpp | 59 ++++--
|
||||
libgambatte/src/sound/channel4.h | 39 +++--
|
||||
libgambatte/src/sound/channel4.h | 40 +++--
|
||||
libgambatte/src/sound/duty_unit.cpp | 34 +++-
|
||||
libgambatte/src/sound/duty_unit.h | 29 ++-
|
||||
libgambatte/src/sound/envelope_unit.cpp | 19 ++-
|
||||
|
@ -66,7 +66,7 @@ Subject: [PATCH] Changes to make libgambatte rerecording-friendly
|
|||
libgambatte/src/video/ppu.h | 84 ++++++---
|
||||
libgambatte/src/video/sprite_mapper.cpp | 17 +-
|
||||
libgambatte/src/video/sprite_mapper.h | 53 ++++--
|
||||
62 files changed, 2150 insertions(+), 603 deletions(-)
|
||||
62 files changed, 2151 insertions(+), 603 deletions(-)
|
||||
create mode 100644 Makefile
|
||||
create mode 100644 libgambatte/Makefile
|
||||
create mode 100644 libgambatte/src/loadsave.cpp
|
||||
|
@ -3504,7 +3504,7 @@ index 35c3c00..9d89db7 100644
|
|||
+
|
||||
}
|
||||
diff --git a/libgambatte/src/sound/channel4.h b/libgambatte/src/sound/channel4.h
|
||||
index 00b0b5a..cb923b8 100644
|
||||
index 00b0b5a..d52d9f7 100644
|
||||
--- a/libgambatte/src/sound/channel4.h
|
||||
+++ b/libgambatte/src/sound/channel4.h
|
||||
@@ -24,6 +24,11 @@
|
||||
|
@ -3519,7 +3519,7 @@ index 00b0b5a..cb923b8 100644
|
|||
|
||||
namespace gambatte {
|
||||
|
||||
@@ -31,26 +36,32 @@ struct SaveState;
|
||||
@@ -31,26 +36,33 @@ struct SaveState;
|
||||
|
||||
class Channel4 {
|
||||
class Lfsr : public SoundUnit {
|
||||
|
@ -3552,6 +3552,7 @@ index 00b0b5a..cb923b8 100644
|
|||
- void reviveCounter(unsigned long cc);
|
||||
+ void reviveCounter(unsigned cc);
|
||||
+ void loadOrSave(loadsave& state) {
|
||||
+ loadOrSave2(state);
|
||||
+ state(backupCounter);
|
||||
+ state(reg);
|
||||
+ state(nr3);
|
||||
|
@ -3560,7 +3561,7 @@ index 00b0b5a..cb923b8 100644
|
|||
};
|
||||
|
||||
class Ch4MasterDisabler : public MasterDisabler {
|
||||
@@ -70,9 +81,9 @@ class Channel4 {
|
||||
@@ -70,9 +82,9 @@ class Channel4 {
|
||||
|
||||
SoundUnit *nextEventUnit;
|
||||
|
||||
|
@ -3573,7 +3574,7 @@ index 00b0b5a..cb923b8 100644
|
|||
|
||||
unsigned char nr4;
|
||||
bool master;
|
||||
@@ -86,15 +97,17 @@ public:
|
||||
@@ -86,15 +98,17 @@ public:
|
||||
void setNr3(unsigned data) { lfsr.nr3Change(data, cycleCounter); /*setEvent();*/ }
|
||||
void setNr4(unsigned data);
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "core/window.hpp"
|
||||
#include "library/pixfmt-rgb32.hpp"
|
||||
#include "library/string.hpp"
|
||||
#include "library/serialization.hpp"
|
||||
#include "library/minmax.hpp"
|
||||
#include "library/framebuffer.hpp"
|
||||
#define HAVE_CSTDINT
|
||||
|
@ -53,6 +54,7 @@ namespace
|
|||
gambatte::GB* instance;
|
||||
unsigned frame_overflow = 0;
|
||||
std::vector<unsigned char> romdata;
|
||||
uint32_t primary_framebuffer[160*144];
|
||||
|
||||
time_t walltime_fn()
|
||||
{
|
||||
|
@ -95,6 +97,7 @@ namespace
|
|||
new(instance) gambatte::GB;
|
||||
instance->setInputGetter(&getinput);
|
||||
instance->set_walltime_fn(walltime_fn);
|
||||
memset(primary_framebuffer, 0, sizeof(primary_framebuffer));
|
||||
frame_overflow = 0;
|
||||
|
||||
rtc_fixed = true;
|
||||
|
@ -296,13 +299,9 @@ void core_emulate_frame()
|
|||
static uint32_t accumulator_r = 0;
|
||||
static unsigned accumulator_s = 0;
|
||||
uint32_t samplebuffer[SAMPLES_PER_FRAME + 2064];
|
||||
uint32_t videobuf[160*144];
|
||||
static uint32_t old_videobuf[160*144];
|
||||
while(true) {
|
||||
unsigned samples_emitted = SAMPLES_PER_FRAME - frame_overflow;
|
||||
long ret = instance->runFor(videobuf, 160, samplebuffer, samples_emitted);
|
||||
if(ret >= 0)
|
||||
memcpy(old_videobuf, videobuf, sizeof(old_videobuf));
|
||||
long ret = instance->runFor(primary_framebuffer, 160, samplebuffer, samples_emitted);
|
||||
for(unsigned i = 0; i < samples_emitted; i++) {
|
||||
uint32_t l = (int32_t)(int16_t)(samplebuffer[i]) + 32768;
|
||||
uint32_t r = (int32_t)(int16_t)(samplebuffer[i] >> 16) + 32768;
|
||||
|
@ -327,7 +326,7 @@ void core_emulate_frame()
|
|||
}
|
||||
framebuffer_info inf;
|
||||
inf.type = &_pixel_format_rgb32;
|
||||
inf.mem = const_cast<char*>(reinterpret_cast<const char*>(old_videobuf));
|
||||
inf.mem = const_cast<char*>(reinterpret_cast<const char*>(primary_framebuffer));
|
||||
inf.physwidth = 160;
|
||||
inf.physheight = 144;
|
||||
inf.physstride = 640;
|
||||
|
@ -458,23 +457,27 @@ function_ptr_command<> cmp_save2("do-cmp-save", "", "\n", []() throw(std::bad_al
|
|||
void core_serialize(std::vector<char>& out)
|
||||
{
|
||||
instance->saveState(out);
|
||||
size_t osize = out.size();
|
||||
out.resize(osize + 4 * sizeof(primary_framebuffer) / sizeof(primary_framebuffer[0]));
|
||||
for(size_t i = 0; i < sizeof(primary_framebuffer) / sizeof(primary_framebuffer[0]); i++)
|
||||
write32ube(&out[osize + 4 * i], primary_framebuffer[i]);
|
||||
out.push_back(frame_overflow >> 8);
|
||||
out.push_back(frame_overflow);
|
||||
}
|
||||
|
||||
void core_unserialize(const char* in, size_t insize)
|
||||
{
|
||||
size_t foffset = insize - 2 - 4 * sizeof(primary_framebuffer) / sizeof(primary_framebuffer[0]);
|
||||
std::vector<char> tmp;
|
||||
tmp.resize(insize - 2);
|
||||
memcpy(&tmp[0], in, insize - 2);
|
||||
tmp.resize(foffset);
|
||||
memcpy(&tmp[0], in, foffset);
|
||||
instance->loadState(tmp);
|
||||
for(size_t i = 0; i < sizeof(primary_framebuffer) / sizeof(primary_framebuffer[0]); i++)
|
||||
primary_framebuffer[i] = read32ube(&in[foffset + 4 * i]);
|
||||
|
||||
unsigned x1 = (unsigned char)in[insize - 2];
|
||||
unsigned x2 = (unsigned char)in[insize - 1];
|
||||
frame_overflow = x1 * 256 + x2;
|
||||
std::vector<char> cmpx;
|
||||
core_serialize(cmpx);
|
||||
if(cmpx.size() != insize || memcmp(&cmpx[0], in, insize))
|
||||
throw std::runtime_error("Loading and resaving won't roundtrip");
|
||||
}
|
||||
|
||||
std::pair<uint32_t, uint32_t> get_scale_factors(uint32_t width, uint32_t height)
|
||||
|
|
Loading…
Add table
Reference in a new issue