lsnes/bsnes-patches/0004-Save-controller-state-when-savestating.patch
Ilari Liusvaara 2b7620f6d5 Patch problems in libsnes
Add patches for libsnes for making it suitable for rerecording and
add code to support some of the new features (remove time interception).
2011-11-09 02:08:57 +02:00

345 lines
11 KiB
Diff

From 5ff13d08a63040823402661f112ee8aaa047aa6a Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Wed, 9 Nov 2011 01:52:08 +0200
Subject: [PATCH 4/4] Save controller state when savestating
When savestating, save the controller state and restore it upon loadstate.
Prevents libsnes from mixing up buttons.
---
snes/controller/controller.cpp | 8 ++++++
snes/controller/controller.hpp | 2 +
snes/controller/gamepad/gamepad.cpp | 13 ++++++++++
snes/controller/gamepad/gamepad.hpp | 2 +-
snes/controller/justifier/justifier.cpp | 36 +++++++++++++++++++++++++++++
snes/controller/justifier/justifier.hpp | 1 +
snes/controller/mouse/mouse.cpp | 13 ++++++++++
snes/controller/mouse/mouse.hpp | 2 +-
snes/controller/multitap/multitap.cpp | 16 +++++++++++++
snes/controller/multitap/multitap.hpp | 2 +-
snes/controller/superscope/superscope.cpp | 31 +++++++++++++++++++++++++
snes/controller/superscope/superscope.hpp | 1 +
snes/input/input.cpp | 15 ++++++++++++
snes/input/input.hpp | 1 +
snes/system/serialization.cpp | 1 +
15 files changed, 141 insertions(+), 3 deletions(-)
diff --git a/snes/controller/controller.cpp b/snes/controller/controller.cpp
index 9091b21..f254bed 100755
--- a/snes/controller/controller.cpp
+++ b/snes/controller/controller.cpp
@@ -46,8 +46,16 @@ void Controller::iobit(bool data) {
}
}
+void Controller::serialize(serializer& s) {
+ Processor::serialize(s);
+ //Save a zero block.
+ unsigned char blockzeroes[SaveSize] = {0};
+ s.array(blockzeroes, SaveSize);
+}
+
Controller::Controller(bool port) : port(port) {
if(!thread) create(Controller::Enter, 1);
}
+
}
diff --git a/snes/controller/controller.hpp b/snes/controller/controller.hpp
index 7332712..827b2eb 100755
--- a/snes/controller/controller.hpp
+++ b/snes/controller/controller.hpp
@@ -13,12 +13,14 @@
struct Controller : Processor {
enum : bool { Port1 = 0, Port2 = 1 };
+ enum { SaveSize = 16 };
const bool port;
static void Enter();
virtual void enter();
void step(unsigned clocks);
void synchronize_cpu();
+ virtual void serialize(serializer& s);
bool iobit();
void iobit(bool data);
diff --git a/snes/controller/gamepad/gamepad.cpp b/snes/controller/gamepad/gamepad.cpp
index 594020d..4fa1c99 100755
--- a/snes/controller/gamepad/gamepad.cpp
+++ b/snes/controller/gamepad/gamepad.cpp
@@ -13,6 +13,19 @@ void Gamepad::latch(bool data) {
counter = 0;
}
+void Gamepad::serialize(serializer& s) {
+ Processor::serialize(s);
+ //Save block.
+ unsigned char block[Controller::SaveSize] = {0};
+ block[0] = latched ? 1 : 0;
+ block[1] = counter;
+ s.array(block, Controller::SaveSize);
+ if(s.mode() == nall::serializer::Load) {
+ latched = (block[0] != 0);
+ counter = block[1];
+ }
+}
+
Gamepad::Gamepad(bool port) : Controller(port) {
latched = 0;
counter = 0;
diff --git a/snes/controller/gamepad/gamepad.hpp b/snes/controller/gamepad/gamepad.hpp
index c5ca69c..a2392d1 100755
--- a/snes/controller/gamepad/gamepad.hpp
+++ b/snes/controller/gamepad/gamepad.hpp
@@ -2,7 +2,7 @@ struct Gamepad : Controller {
uint2 data();
void latch(bool data);
Gamepad(bool port);
-
+ void serialize(serializer& s);
private:
bool latched;
unsigned counter;
diff --git a/snes/controller/justifier/justifier.cpp b/snes/controller/justifier/justifier.cpp
index 8b2d3ee..4b8eca8 100755
--- a/snes/controller/justifier/justifier.cpp
+++ b/snes/controller/justifier/justifier.cpp
@@ -103,6 +103,42 @@ void Justifier::latch(bool data) {
if(latched == 0) active = !active; //toggle between both controllers, even when unchained
}
+void Justifier::serialize(serializer& s) {
+ Processor::serialize(s);
+ //Save block.
+ unsigned char block[Controller::SaveSize] = {0};
+ block[0] = latched ? 1 : 0;
+ block[1] = counter;
+ block[2] = active ? 1 : 0;
+ block[3] = trigger1 ? 1 : 0;
+ block[4] = trigger2 ? 1 : 0;
+ block[5] = start1 ? 1 : 0;
+ block[6] = start2 ? 1 : 0;
+ block[7] = (unsigned short)x1 >> 8;
+ block[8] = (unsigned short)x1;
+ block[9] = (unsigned short)x2 >> 8;
+ block[10] = (unsigned short)x2;
+ block[11] = (unsigned short)y1 >> 8;
+ block[12] = (unsigned short)y1;
+ block[13] = (unsigned short)y2 >> 8;
+ block[14] = (unsigned short)y2;
+ s.array(block, Controller::SaveSize);
+ if(s.mode() == nall::serializer::Load) {
+ latched = (block[0] != 0);
+ counter = block[1];
+ active = (block[2] != 0);
+ trigger1 = (block[3] != 0);
+ trigger2 = (block[4] != 0);
+ start1 = (block[5] != 0);
+ start2 = (block[6] != 0);
+ x1 = (short)(((unsigned short)block[7] << 8) | (unsigned short)block[8]);
+ x2 = (short)(((unsigned short)block[9] << 8) | (unsigned short)block[10]);
+ y1 = (short)(((unsigned short)block[11] << 8) | (unsigned short)block[12]);
+ y2 = (short)(((unsigned short)block[13] << 8) | (unsigned short)block[14]);
+ }
+}
+
+
Justifier::Justifier(bool port, bool chained) : Controller(port), chained(chained) {
create(Controller::Enter, 21477272);
latched = 0;
diff --git a/snes/controller/justifier/justifier.hpp b/snes/controller/justifier/justifier.hpp
index 8259147..96e09dc 100755
--- a/snes/controller/justifier/justifier.hpp
+++ b/snes/controller/justifier/justifier.hpp
@@ -2,6 +2,7 @@ struct Justifier : Controller {
void enter();
uint2 data();
void latch(bool data);
+ void serialize(serializer& s);
Justifier(bool port, bool chained);
//private:
diff --git a/snes/controller/mouse/mouse.cpp b/snes/controller/mouse/mouse.cpp
index c9f5d16..6b26fae 100755
--- a/snes/controller/mouse/mouse.cpp
+++ b/snes/controller/mouse/mouse.cpp
@@ -61,6 +61,19 @@ void Mouse::latch(bool data) {
counter = 0;
}
+void Mouse::serialize(serializer& s) {
+ Processor::serialize(s);
+ //Save block.
+ unsigned char block[Controller::SaveSize] = {0};
+ block[0] = latched ? 1 : 0;
+ block[1] = counter;
+ s.array(block, Controller::SaveSize);
+ if(s.mode() == nall::serializer::Load) {
+ latched = (block[0] != 0);
+ counter = block[1];
+ }
+}
+
Mouse::Mouse(bool port) : Controller(port) {
latched = 0;
counter = 0;
diff --git a/snes/controller/mouse/mouse.hpp b/snes/controller/mouse/mouse.hpp
index 95e24b6..b66ea51 100755
--- a/snes/controller/mouse/mouse.hpp
+++ b/snes/controller/mouse/mouse.hpp
@@ -2,7 +2,7 @@ struct Mouse : Controller {
uint2 data();
void latch(bool data);
Mouse(bool port);
-
+ void serialize(serializer& s);
private:
bool latched;
unsigned counter;
diff --git a/snes/controller/multitap/multitap.cpp b/snes/controller/multitap/multitap.cpp
index 3a6eb72..146c41d 100755
--- a/snes/controller/multitap/multitap.cpp
+++ b/snes/controller/multitap/multitap.cpp
@@ -30,6 +30,22 @@ void Multitap::latch(bool data) {
counter2 = 0;
}
+void Multitap::serialize(serializer& s) {
+ Processor::serialize(s);
+ //Save block.
+ unsigned char block[Controller::SaveSize] = {0};
+ block[0] = latched ? 1 : 0;
+ block[1] = counter1;
+ block[2] = counter2;
+ s.array(block, Controller::SaveSize);
+ if(s.mode() == nall::serializer::Load) {
+ latched = (block[0] != 0);
+ counter1 = block[1];
+ counter2 = block[2];
+ }
+}
+
+
Multitap::Multitap(bool port) : Controller(port) {
latched = 0;
counter1 = 0;
diff --git a/snes/controller/multitap/multitap.hpp b/snes/controller/multitap/multitap.hpp
index 0540af7..e6324ac 100755
--- a/snes/controller/multitap/multitap.hpp
+++ b/snes/controller/multitap/multitap.hpp
@@ -2,7 +2,7 @@ struct Multitap : Controller {
uint2 data();
void latch(bool data);
Multitap(bool port);
-
+ void serialize(serializer& s);
private:
bool latched;
unsigned counter1;
diff --git a/snes/controller/superscope/superscope.cpp b/snes/controller/superscope/superscope.cpp
index e97a2ff..bb260b9 100755
--- a/snes/controller/superscope/superscope.cpp
+++ b/snes/controller/superscope/superscope.cpp
@@ -104,6 +104,37 @@ void SuperScope::latch(bool data) {
counter = 0;
}
+void SuperScope::serialize(serializer& s) {
+ Processor::serialize(s);
+ //Save block.
+ unsigned char block[Controller::SaveSize] = {0};
+ block[0] = latched ? 1 : 0;
+ block[1] = counter;
+ block[2] = trigger ? 1 : 0;
+ block[3] = cursor ? 1 : 0;
+ block[4] = turbo ? 1 : 0;
+ block[5] = pause ? 1 : 0;
+ block[6] = offscreen ? 1 : 0;
+ block[7] = (unsigned short)x >> 8;
+ block[8] = (unsigned short)x;
+ block[9] = (unsigned short)y >> 8;
+ block[10] = (unsigned short)y;
+
+ s.array(block, Controller::SaveSize);
+ if(s.mode() == nall::serializer::Load) {
+ latched = (block[0] != 0);
+ counter = block[1];
+ trigger = (block[2] != 0);
+ cursor = (block[3] != 0);
+ turbo = (block[4] != 0);
+ pause = (block[5] != 0);
+ offscreen = (block[6] != 0);
+ x = (short)(((unsigned short)block[7] << 8) | (unsigned short)block[8]);
+ y = (short)(((unsigned short)block[9] << 8) | (unsigned short)block[10]);
+ }
+}
+
+
SuperScope::SuperScope(bool port) : Controller(port) {
create(Controller::Enter, 21477272);
latched = 0;
diff --git a/snes/controller/superscope/superscope.hpp b/snes/controller/superscope/superscope.hpp
index a7a90b7..93509d7 100755
--- a/snes/controller/superscope/superscope.hpp
+++ b/snes/controller/superscope/superscope.hpp
@@ -2,6 +2,7 @@ struct SuperScope : Controller {
void enter();
uint2 data();
void latch(bool data);
+ void serialize(serializer& s);
SuperScope(bool port);
//private:
diff --git a/snes/input/input.cpp b/snes/input/input.cpp
index 9050310..7030495 100755
--- a/snes/input/input.cpp
+++ b/snes/input/input.cpp
@@ -26,6 +26,21 @@ void Input::connect(bool port, Input::Device id) {
}
}
+void Input::serialize(serializer &s)
+{
+ int p1, p2;
+ p1 = (int)config.controller_port1;
+ p2 = (int)config.controller_port2;
+ s.integer(p1);
+ s.integer(p2);
+ if(s.mode() == nall::serializer::Load) {
+ connect(Controller::Port1, (Device)p1);
+ connect(Controller::Port2, (Device)p2);
+ }
+ port1->serialize(s);
+ port2->serialize(s);
+}
+
Input::Input() : port1(nullptr), port2(nullptr) {
connect(Controller::Port1, Input::Device::Joypad);
connect(Controller::Port2, Input::Device::Joypad);
diff --git a/snes/input/input.hpp b/snes/input/input.hpp
index 13ef46e..6832e82 100755
--- a/snes/input/input.hpp
+++ b/snes/input/input.hpp
@@ -31,6 +31,7 @@ struct Input {
Controller *port1;
Controller *port2;
+ void serialize(serializer &s);
void connect(bool port, Input::Device id);
Input();
~Input();
diff --git a/snes/system/serialization.cpp b/snes/system/serialization.cpp
index f7d6f3b..08e7051 100755
--- a/snes/system/serialization.cpp
+++ b/snes/system/serialization.cpp
@@ -56,6 +56,7 @@ void System::serialize_all(serializer &s) {
smp.serialize(s);
ppu.serialize(s);
dsp.serialize(s);
+ input.serialize(s);
if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.serialize(s);
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) icd2.serialize(s);
--
1.7.8.rc0.38.g761c4