From fe11984ad18561506a7cc874cb7c0421f1e21ad1 Mon Sep 17 00:00:00 2001 From: Ilari Liusvaara Date: Wed, 9 Nov 2011 01:52:08 +0200 Subject: [PATCH 2/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/system/input.cpp | 16 +++++++++++++ snes/system/input.hpp | 1 + snes/system/serialization.cpp | 1 + 15 files changed, 142 insertions(+), 3 deletions(-) diff --git a/snes/controller/controller.cpp b/snes/controller/controller.cpp index fa8e07d..5f37849 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 dd748a1..46095a8 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 6207916..ad13a9b 100755 --- a/snes/controller/justifier/justifier.cpp +++ b/snes/controller/justifier/justifier.cpp @@ -100,6 +100,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] = player1.trigger ? 1 : 0; + block[4] = player2.trigger ? 1 : 0; + block[5] = player1.start ? 1 : 0; + block[6] = player2.start ? 1 : 0; + block[7] = (unsigned short)player1.x >> 8; + block[8] = (unsigned short)player1.x; + block[9] = (unsigned short)player2.x >> 8; + block[10] = (unsigned short)player2.x; + block[11] = (unsigned short)player1.y >> 8; + block[12] = (unsigned short)player1.y; + block[13] = (unsigned short)player2.y >> 8; + block[14] = (unsigned short)player2.y; + s.array(block, Controller::SaveSize); + if(s.mode() == nall::serializer::Load) { + latched = (block[0] != 0); + counter = block[1]; + active = (block[2] != 0); + player1.trigger = (block[3] != 0); + player2.trigger = (block[4] != 0); + player1.start = (block[5] != 0); + player2.start = (block[6] != 0); + player1.x = (short)(((unsigned short)block[7] << 8) | (unsigned short)block[8]); + player2.x = (short)(((unsigned short)block[9] << 8) | (unsigned short)block[10]); + player1.y = (short)(((unsigned short)block[11] << 8) | (unsigned short)block[12]); + player2.y = (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 f927acf..6b7bba0 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 12068f0..1a1dfbf 100755 --- a/snes/controller/superscope/superscope.cpp +++ b/snes/controller/superscope/superscope.cpp @@ -100,6 +100,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/system/input.cpp b/snes/system/input.cpp index 894de0e..4479acc 100755 --- a/snes/system/input.cpp +++ b/snes/system/input.cpp @@ -26,6 +26,22 @@ 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/system/input.hpp b/snes/system/input.hpp index 7a6bd9e..d2f5fef 100755 --- a/snes/system/input.hpp +++ b/snes/system/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 f746c3a..67e08a2 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 defined(GAMEBOY) -- 1.7.9.48.g85da4d