Path: blob/master/libsnes/lsnes_patches/0002-Save-controller-state-when-savestating.patch
2 views
From fe11984ad18561506a7cc874cb7c0421f1e21ad1 Mon Sep 17 00:00:00 20011From: Ilari Liusvaara <[email protected]>2Date: Wed, 9 Nov 2011 01:52:08 +02003Subject: [PATCH 2/4] Save controller state when savestating45When savestating, save the controller state and restore it upon loadstate.6Prevents libsnes from mixing up buttons.7---8snes/controller/controller.cpp | 8 ++++++9snes/controller/controller.hpp | 2 +10snes/controller/gamepad/gamepad.cpp | 13 ++++++++++11snes/controller/gamepad/gamepad.hpp | 2 +-12snes/controller/justifier/justifier.cpp | 36 +++++++++++++++++++++++++++++13snes/controller/justifier/justifier.hpp | 1 +14snes/controller/mouse/mouse.cpp | 13 ++++++++++15snes/controller/mouse/mouse.hpp | 2 +-16snes/controller/multitap/multitap.cpp | 16 +++++++++++++17snes/controller/multitap/multitap.hpp | 2 +-18snes/controller/superscope/superscope.cpp | 31 +++++++++++++++++++++++++19snes/controller/superscope/superscope.hpp | 1 +20snes/system/input.cpp | 16 +++++++++++++21snes/system/input.hpp | 1 +22snes/system/serialization.cpp | 1 +2315 files changed, 142 insertions(+), 3 deletions(-)2425diff --git a/snes/controller/controller.cpp b/snes/controller/controller.cpp26index fa8e07d..5f37849 10075527--- snes/controller/controller.cpp28+++ snes/controller/controller.cpp29@@ -46,8 +46,16 @@ void Controller::iobit(bool data) {30}31}3233+void Controller::serialize(serializer& s) {34+ Processor::serialize(s);35+ //Save a zero block.36+ unsigned char blockzeroes[SaveSize] = {0};37+ s.array(blockzeroes, SaveSize);38+}39+40Controller::Controller(bool port) : port(port) {41if(!thread) create(Controller::Enter, 1);42}4344+45}46diff --git a/snes/controller/controller.hpp b/snes/controller/controller.hpp47index dd748a1..46095a8 10075548--- snes/controller/controller.hpp49+++ snes/controller/controller.hpp50@@ -13,12 +13,14 @@5152struct Controller : Processor {53enum : bool { Port1 = 0, Port2 = 1 };54+ enum { SaveSize = 16 };55const bool port;5657static void Enter();58virtual void enter();59void step(unsigned clocks);60void synchronize_cpu();61+ virtual void serialize(serializer& s);6263bool iobit();64void iobit(bool data);65diff --git a/snes/controller/gamepad/gamepad.cpp b/snes/controller/gamepad/gamepad.cpp66index 594020d..4fa1c99 10075567--- snes/controller/gamepad/gamepad.cpp68+++ snes/controller/gamepad/gamepad.cpp69@@ -13,6 +13,19 @@ void Gamepad::latch(bool data) {70counter = 0;71}7273+void Gamepad::serialize(serializer& s) {74+ Processor::serialize(s);75+ //Save block.76+ unsigned char block[Controller::SaveSize] = {0};77+ block[0] = latched ? 1 : 0;78+ block[1] = counter;79+ s.array(block, Controller::SaveSize);80+ if(s.mode() == nall::serializer::Load) {81+ latched = (block[0] != 0);82+ counter = block[1];83+ }84+}85+86Gamepad::Gamepad(bool port) : Controller(port) {87latched = 0;88counter = 0;89diff --git a/snes/controller/gamepad/gamepad.hpp b/snes/controller/gamepad/gamepad.hpp90index c5ca69c..a2392d1 10075591--- snes/controller/gamepad/gamepad.hpp92+++ snes/controller/gamepad/gamepad.hpp93@@ -2,7 +2,7 @@ struct Gamepad : Controller {94uint2 data();95void latch(bool data);96Gamepad(bool port);97-98+ void serialize(serializer& s);99private:100bool latched;101unsigned counter;102diff --git a/snes/controller/justifier/justifier.cpp b/snes/controller/justifier/justifier.cpp103index 6207916..ad13a9b 100755104--- snes/controller/justifier/justifier.cpp105+++ snes/controller/justifier/justifier.cpp106@@ -100,6 +100,42 @@ void Justifier::latch(bool data) {107if(latched == 0) active = !active; //toggle between both controllers, even when unchained108}109110+void Justifier::serialize(serializer& s) {111+ Processor::serialize(s);112+ //Save block.113+ unsigned char block[Controller::SaveSize] = {0};114+ block[0] = latched ? 1 : 0;115+ block[1] = counter;116+ block[2] = active ? 1 : 0;117+ block[3] = player1.trigger ? 1 : 0;118+ block[4] = player2.trigger ? 1 : 0;119+ block[5] = player1.start ? 1 : 0;120+ block[6] = player2.start ? 1 : 0;121+ block[7] = (unsigned short)player1.x >> 8;122+ block[8] = (unsigned short)player1.x;123+ block[9] = (unsigned short)player2.x >> 8;124+ block[10] = (unsigned short)player2.x;125+ block[11] = (unsigned short)player1.y >> 8;126+ block[12] = (unsigned short)player1.y;127+ block[13] = (unsigned short)player2.y >> 8;128+ block[14] = (unsigned short)player2.y;129+ s.array(block, Controller::SaveSize);130+ if(s.mode() == nall::serializer::Load) {131+ latched = (block[0] != 0);132+ counter = block[1];133+ active = (block[2] != 0);134+ player1.trigger = (block[3] != 0);135+ player2.trigger = (block[4] != 0);136+ player1.start = (block[5] != 0);137+ player2.start = (block[6] != 0);138+ player1.x = (short)(((unsigned short)block[7] << 8) | (unsigned short)block[8]);139+ player2.x = (short)(((unsigned short)block[9] << 8) | (unsigned short)block[10]);140+ player1.y = (short)(((unsigned short)block[11] << 8) | (unsigned short)block[12]);141+ player2.y = (short)(((unsigned short)block[13] << 8) | (unsigned short)block[14]);142+ }143+}144+145+146Justifier::Justifier(bool port, bool chained) : Controller(port), chained(chained) {147create(Controller::Enter, 21477272);148latched = 0;149diff --git a/snes/controller/justifier/justifier.hpp b/snes/controller/justifier/justifier.hpp150index f927acf..6b7bba0 100755151--- snes/controller/justifier/justifier.hpp152+++ snes/controller/justifier/justifier.hpp153@@ -2,6 +2,7 @@ struct Justifier : Controller {154void enter();155uint2 data();156void latch(bool data);157+ void serialize(serializer& s);158Justifier(bool port, bool chained);159160//private:161diff --git a/snes/controller/mouse/mouse.cpp b/snes/controller/mouse/mouse.cpp162index c9f5d16..6b26fae 100755163--- snes/controller/mouse/mouse.cpp164+++ snes/controller/mouse/mouse.cpp165@@ -61,6 +61,19 @@ void Mouse::latch(bool data) {166counter = 0;167}168169+void Mouse::serialize(serializer& s) {170+ Processor::serialize(s);171+ //Save block.172+ unsigned char block[Controller::SaveSize] = {0};173+ block[0] = latched ? 1 : 0;174+ block[1] = counter;175+ s.array(block, Controller::SaveSize);176+ if(s.mode() == nall::serializer::Load) {177+ latched = (block[0] != 0);178+ counter = block[1];179+ }180+}181+182Mouse::Mouse(bool port) : Controller(port) {183latched = 0;184counter = 0;185diff --git a/snes/controller/mouse/mouse.hpp b/snes/controller/mouse/mouse.hpp186index 95e24b6..b66ea51 100755187--- snes/controller/mouse/mouse.hpp188+++ snes/controller/mouse/mouse.hpp189@@ -2,7 +2,7 @@ struct Mouse : Controller {190uint2 data();191void latch(bool data);192Mouse(bool port);193-194+ void serialize(serializer& s);195private:196bool latched;197unsigned counter;198diff --git a/snes/controller/multitap/multitap.cpp b/snes/controller/multitap/multitap.cpp199index 3a6eb72..146c41d 100755200--- snes/controller/multitap/multitap.cpp201+++ snes/controller/multitap/multitap.cpp202@@ -30,6 +30,22 @@ void Multitap::latch(bool data) {203counter2 = 0;204}205206+void Multitap::serialize(serializer& s) {207+ Processor::serialize(s);208+ //Save block.209+ unsigned char block[Controller::SaveSize] = {0};210+ block[0] = latched ? 1 : 0;211+ block[1] = counter1;212+ block[2] = counter2;213+ s.array(block, Controller::SaveSize);214+ if(s.mode() == nall::serializer::Load) {215+ latched = (block[0] != 0);216+ counter1 = block[1];217+ counter2 = block[2];218+ }219+}220+221+222Multitap::Multitap(bool port) : Controller(port) {223latched = 0;224counter1 = 0;225diff --git a/snes/controller/multitap/multitap.hpp b/snes/controller/multitap/multitap.hpp226index 0540af7..e6324ac 100755227--- snes/controller/multitap/multitap.hpp228+++ snes/controller/multitap/multitap.hpp229@@ -2,7 +2,7 @@ struct Multitap : Controller {230uint2 data();231void latch(bool data);232Multitap(bool port);233-234+ void serialize(serializer& s);235private:236bool latched;237unsigned counter1;238diff --git a/snes/controller/superscope/superscope.cpp b/snes/controller/superscope/superscope.cpp239index 12068f0..1a1dfbf 100755240--- snes/controller/superscope/superscope.cpp241+++ snes/controller/superscope/superscope.cpp242@@ -100,6 +100,37 @@ void SuperScope::latch(bool data) {243counter = 0;244}245246+void SuperScope::serialize(serializer& s) {247+ Processor::serialize(s);248+ //Save block.249+ unsigned char block[Controller::SaveSize] = {0};250+ block[0] = latched ? 1 : 0;251+ block[1] = counter;252+ block[2] = trigger ? 1 : 0;253+ block[3] = cursor ? 1 : 0;254+ block[4] = turbo ? 1 : 0;255+ block[5] = pause ? 1 : 0;256+ block[6] = offscreen ? 1 : 0;257+ block[7] = (unsigned short)x >> 8;258+ block[8] = (unsigned short)x;259+ block[9] = (unsigned short)y >> 8;260+ block[10] = (unsigned short)y;261+262+ s.array(block, Controller::SaveSize);263+ if(s.mode() == nall::serializer::Load) {264+ latched = (block[0] != 0);265+ counter = block[1];266+ trigger = (block[2] != 0);267+ cursor = (block[3] != 0);268+ turbo = (block[4] != 0);269+ pause = (block[5] != 0);270+ offscreen = (block[6] != 0);271+ x = (short)(((unsigned short)block[7] << 8) | (unsigned short)block[8]);272+ y = (short)(((unsigned short)block[9] << 8) | (unsigned short)block[10]);273+ }274+}275+276+277SuperScope::SuperScope(bool port) : Controller(port) {278create(Controller::Enter, 21477272);279latched = 0;280diff --git a/snes/controller/superscope/superscope.hpp b/snes/controller/superscope/superscope.hpp281index a7a90b7..93509d7 100755282--- snes/controller/superscope/superscope.hpp283+++ snes/controller/superscope/superscope.hpp284@@ -2,6 +2,7 @@ struct SuperScope : Controller {285void enter();286uint2 data();287void latch(bool data);288+ void serialize(serializer& s);289SuperScope(bool port);290291//private:292diff --git a/snes/system/input.cpp b/snes/system/input.cpp293index 894de0e..4479acc 100755294--- snes/system/input.cpp295+++ snes/system/input.cpp296@@ -26,6 +26,22 @@ void Input::connect(bool port, Input::Device id) {297}298}299300+void Input::serialize(serializer &s)301+{302+ int p1, p2;303+ p1 = (int)config.controller_port1;304+ p2 = (int)config.controller_port2;305+ s.integer(p1);306+ s.integer(p2);307+ if(s.mode() == nall::serializer::Load) {308+ connect(Controller::Port1, (Device)p1);309+ connect(Controller::Port2, (Device)p2);310+ }311+ port1->serialize(s);312+ port2->serialize(s);313+}314+315+316Input::Input() : port1(nullptr), port2(nullptr) {317connect(Controller::Port1, Input::Device::Joypad);318connect(Controller::Port2, Input::Device::Joypad);319diff --git a/snes/system/input.hpp b/snes/system/input.hpp320index 7a6bd9e..d2f5fef 100755321--- snes/system/input.hpp322+++ snes/system/input.hpp323@@ -31,6 +31,7 @@ struct Input {324Controller *port1;325Controller *port2;326327+ void serialize(serializer &s);328void connect(bool port, Input::Device id);329Input();330~Input();331diff --git a/snes/system/serialization.cpp b/snes/system/serialization.cpp332index f746c3a..67e08a2 100755333--- snes/system/serialization.cpp334+++ snes/system/serialization.cpp335@@ -56,6 +56,7 @@ void System::serialize_all(serializer &s) {336smp.serialize(s);337ppu.serialize(s);338dsp.serialize(s);339+ input.serialize(s);340341if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.serialize(s);342#if defined(GAMEBOY)343--3441.7.9.48.g85da4d345346347348