1 From 3e9d5d306fb7f7c2e366e3eb84c0415673715d43 Mon Sep 17 00:00:00 2001
2 From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
3 Date: Wed, 9 Nov 2011 01:52:08 +0200
4 Subject: [PATCH 04/10] Save controller state when savestating
6 When savestating, save the controller state and restore it upon loadstate.
7 Prevents libsnes from mixing up buttons.
9 snes/controller/controller.cpp | 8 ++++++
10 snes/controller/controller.hpp | 2 +
11 snes/controller/gamepad/gamepad.cpp | 13 ++++++++++
12 snes/controller/gamepad/gamepad.hpp | 2 +-
13 snes/controller/justifier/justifier.cpp | 36 +++++++++++++++++++++++++++++
14 snes/controller/justifier/justifier.hpp | 1 +
15 snes/controller/mouse/mouse.cpp | 13 ++++++++++
16 snes/controller/mouse/mouse.hpp | 2 +-
17 snes/controller/multitap/multitap.cpp | 16 +++++++++++++
18 snes/controller/multitap/multitap.hpp | 2 +-
19 snes/controller/superscope/superscope.cpp | 31 +++++++++++++++++++++++++
20 snes/controller/superscope/superscope.hpp | 1 +
21 snes/system/input.cpp | 16 +++++++++++++
22 snes/system/input.hpp | 1 +
23 snes/system/serialization.cpp | 1 +
24 15 files changed, 142 insertions(+), 3 deletions(-)
26 diff --git a/snes/controller/controller.cpp b/snes/controller/controller.cpp
27 index 9091b21..f254bed 100755
28 --- a/snes/controller/controller.cpp
29 +++ b/snes/controller/controller.cpp
30 @@ -46,8 +46,16 @@ void Controller::iobit(bool data) {
34 +void Controller::serialize(serializer& s) {
35 + Processor::serialize(s);
36 + //Save a zero block.
37 + unsigned char blockzeroes[SaveSize] = {0};
38 + s.array(blockzeroes, SaveSize);
41 Controller::Controller(bool port) : port(port) {
42 if(!thread) create(Controller::Enter, 1);
47 diff --git a/snes/controller/controller.hpp b/snes/controller/controller.hpp
48 index 7332712..827b2eb 100755
49 --- a/snes/controller/controller.hpp
50 +++ b/snes/controller/controller.hpp
53 struct Controller : Processor {
54 enum : bool { Port1 = 0, Port2 = 1 };
55 + enum { SaveSize = 16 };
60 void step(unsigned clocks);
61 void synchronize_cpu();
62 + virtual void serialize(serializer& s);
65 void iobit(bool data);
66 diff --git a/snes/controller/gamepad/gamepad.cpp b/snes/controller/gamepad/gamepad.cpp
67 index 594020d..4fa1c99 100755
68 --- a/snes/controller/gamepad/gamepad.cpp
69 +++ b/snes/controller/gamepad/gamepad.cpp
70 @@ -13,6 +13,19 @@ void Gamepad::latch(bool data) {
74 +void Gamepad::serialize(serializer& s) {
75 + Processor::serialize(s);
77 + unsigned char block[Controller::SaveSize] = {0};
78 + block[0] = latched ? 1 : 0;
80 + s.array(block, Controller::SaveSize);
81 + if(s.mode() == nall::serializer::Load) {
82 + latched = (block[0] != 0);
87 Gamepad::Gamepad(bool port) : Controller(port) {
90 diff --git a/snes/controller/gamepad/gamepad.hpp b/snes/controller/gamepad/gamepad.hpp
91 index c5ca69c..a2392d1 100755
92 --- a/snes/controller/gamepad/gamepad.hpp
93 +++ b/snes/controller/gamepad/gamepad.hpp
94 @@ -2,7 +2,7 @@ struct Gamepad : Controller {
96 void latch(bool data);
99 + void serialize(serializer& s);
103 diff --git a/snes/controller/justifier/justifier.cpp b/snes/controller/justifier/justifier.cpp
104 index 6207916..ad13a9b 100755
105 --- a/snes/controller/justifier/justifier.cpp
106 +++ b/snes/controller/justifier/justifier.cpp
107 @@ -100,6 +100,42 @@ void Justifier::latch(bool data) {
108 if(latched == 0) active = !active; //toggle between both controllers, even when unchained
111 +void Justifier::serialize(serializer& s) {
112 + Processor::serialize(s);
114 + unsigned char block[Controller::SaveSize] = {0};
115 + block[0] = latched ? 1 : 0;
116 + block[1] = counter;
117 + block[2] = active ? 1 : 0;
118 + block[3] = player1.trigger ? 1 : 0;
119 + block[4] = player2.trigger ? 1 : 0;
120 + block[5] = player1.start ? 1 : 0;
121 + block[6] = player2.start ? 1 : 0;
122 + block[7] = (unsigned short)player1.x >> 8;
123 + block[8] = (unsigned short)player1.x;
124 + block[9] = (unsigned short)player2.x >> 8;
125 + block[10] = (unsigned short)player2.x;
126 + block[11] = (unsigned short)player1.y >> 8;
127 + block[12] = (unsigned short)player1.y;
128 + block[13] = (unsigned short)player2.y >> 8;
129 + block[14] = (unsigned short)player2.y;
130 + s.array(block, Controller::SaveSize);
131 + if(s.mode() == nall::serializer::Load) {
132 + latched = (block[0] != 0);
133 + counter = block[1];
134 + active = (block[2] != 0);
135 + player1.trigger = (block[3] != 0);
136 + player2.trigger = (block[4] != 0);
137 + player1.start = (block[5] != 0);
138 + player2.start = (block[6] != 0);
139 + player1.x = (short)(((unsigned short)block[7] << 8) | (unsigned short)block[8]);
140 + player2.x = (short)(((unsigned short)block[9] << 8) | (unsigned short)block[10]);
141 + player1.y = (short)(((unsigned short)block[11] << 8) | (unsigned short)block[12]);
142 + player2.y = (short)(((unsigned short)block[13] << 8) | (unsigned short)block[14]);
147 Justifier::Justifier(bool port, bool chained) : Controller(port), chained(chained) {
148 create(Controller::Enter, 21477272);
150 diff --git a/snes/controller/justifier/justifier.hpp b/snes/controller/justifier/justifier.hpp
151 index f927acf..6b7bba0 100755
152 --- a/snes/controller/justifier/justifier.hpp
153 +++ b/snes/controller/justifier/justifier.hpp
154 @@ -2,6 +2,7 @@ struct Justifier : Controller {
157 void latch(bool data);
158 + void serialize(serializer& s);
159 Justifier(bool port, bool chained);
162 diff --git a/snes/controller/mouse/mouse.cpp b/snes/controller/mouse/mouse.cpp
163 index c9f5d16..6b26fae 100755
164 --- a/snes/controller/mouse/mouse.cpp
165 +++ b/snes/controller/mouse/mouse.cpp
166 @@ -61,6 +61,19 @@ void Mouse::latch(bool data) {
170 +void Mouse::serialize(serializer& s) {
171 + Processor::serialize(s);
173 + unsigned char block[Controller::SaveSize] = {0};
174 + block[0] = latched ? 1 : 0;
175 + block[1] = counter;
176 + s.array(block, Controller::SaveSize);
177 + if(s.mode() == nall::serializer::Load) {
178 + latched = (block[0] != 0);
179 + counter = block[1];
183 Mouse::Mouse(bool port) : Controller(port) {
186 diff --git a/snes/controller/mouse/mouse.hpp b/snes/controller/mouse/mouse.hpp
187 index 95e24b6..b66ea51 100755
188 --- a/snes/controller/mouse/mouse.hpp
189 +++ b/snes/controller/mouse/mouse.hpp
190 @@ -2,7 +2,7 @@ struct Mouse : Controller {
192 void latch(bool data);
195 + void serialize(serializer& s);
199 diff --git a/snes/controller/multitap/multitap.cpp b/snes/controller/multitap/multitap.cpp
200 index 3a6eb72..146c41d 100755
201 --- a/snes/controller/multitap/multitap.cpp
202 +++ b/snes/controller/multitap/multitap.cpp
203 @@ -30,6 +30,22 @@ void Multitap::latch(bool data) {
207 +void Multitap::serialize(serializer& s) {
208 + Processor::serialize(s);
210 + unsigned char block[Controller::SaveSize] = {0};
211 + block[0] = latched ? 1 : 0;
212 + block[1] = counter1;
213 + block[2] = counter2;
214 + s.array(block, Controller::SaveSize);
215 + if(s.mode() == nall::serializer::Load) {
216 + latched = (block[0] != 0);
217 + counter1 = block[1];
218 + counter2 = block[2];
223 Multitap::Multitap(bool port) : Controller(port) {
226 diff --git a/snes/controller/multitap/multitap.hpp b/snes/controller/multitap/multitap.hpp
227 index 0540af7..e6324ac 100755
228 --- a/snes/controller/multitap/multitap.hpp
229 +++ b/snes/controller/multitap/multitap.hpp
230 @@ -2,7 +2,7 @@ struct Multitap : Controller {
232 void latch(bool data);
235 + void serialize(serializer& s);
239 diff --git a/snes/controller/superscope/superscope.cpp b/snes/controller/superscope/superscope.cpp
240 index 12068f0..1a1dfbf 100755
241 --- a/snes/controller/superscope/superscope.cpp
242 +++ b/snes/controller/superscope/superscope.cpp
243 @@ -100,6 +100,37 @@ void SuperScope::latch(bool data) {
247 +void SuperScope::serialize(serializer& s) {
248 + Processor::serialize(s);
250 + unsigned char block[Controller::SaveSize] = {0};
251 + block[0] = latched ? 1 : 0;
252 + block[1] = counter;
253 + block[2] = trigger ? 1 : 0;
254 + block[3] = cursor ? 1 : 0;
255 + block[4] = turbo ? 1 : 0;
256 + block[5] = pause ? 1 : 0;
257 + block[6] = offscreen ? 1 : 0;
258 + block[7] = (unsigned short)x >> 8;
259 + block[8] = (unsigned short)x;
260 + block[9] = (unsigned short)y >> 8;
261 + block[10] = (unsigned short)y;
263 + s.array(block, Controller::SaveSize);
264 + if(s.mode() == nall::serializer::Load) {
265 + latched = (block[0] != 0);
266 + counter = block[1];
267 + trigger = (block[2] != 0);
268 + cursor = (block[3] != 0);
269 + turbo = (block[4] != 0);
270 + pause = (block[5] != 0);
271 + offscreen = (block[6] != 0);
272 + x = (short)(((unsigned short)block[7] << 8) | (unsigned short)block[8]);
273 + y = (short)(((unsigned short)block[9] << 8) | (unsigned short)block[10]);
278 SuperScope::SuperScope(bool port) : Controller(port) {
279 create(Controller::Enter, 21477272);
281 diff --git a/snes/controller/superscope/superscope.hpp b/snes/controller/superscope/superscope.hpp
282 index a7a90b7..93509d7 100755
283 --- a/snes/controller/superscope/superscope.hpp
284 +++ b/snes/controller/superscope/superscope.hpp
285 @@ -2,6 +2,7 @@ struct SuperScope : Controller {
288 void latch(bool data);
289 + void serialize(serializer& s);
290 SuperScope(bool port);
293 diff --git a/snes/system/input.cpp b/snes/system/input.cpp
294 index 9050310..ec5559d 100755
295 --- a/snes/system/input.cpp
296 +++ b/snes/system/input.cpp
297 @@ -26,6 +26,22 @@ void Input::connect(bool port, Input::Device id) {
301 +void Input::serialize(serializer &s)
304 + p1 = (int)config.controller_port1;
305 + p2 = (int)config.controller_port2;
308 + if(s.mode() == nall::serializer::Load) {
309 + connect(Controller::Port1, (Device)p1);
310 + connect(Controller::Port2, (Device)p2);
312 + port1->serialize(s);
313 + port2->serialize(s);
317 Input::Input() : port1(nullptr), port2(nullptr) {
318 connect(Controller::Port1, Input::Device::Joypad);
319 connect(Controller::Port2, Input::Device::Joypad);
320 diff --git a/snes/system/input.hpp b/snes/system/input.hpp
321 index 13ef46e..6832e82 100755
322 --- a/snes/system/input.hpp
323 +++ b/snes/system/input.hpp
324 @@ -31,6 +31,7 @@ struct Input {
328 + void serialize(serializer &s);
329 void connect(bool port, Input::Device id);
332 diff --git a/snes/system/serialization.cpp b/snes/system/serialization.cpp
333 index f7d6f3b..08e7051 100755
334 --- a/snes/system/serialization.cpp
335 +++ b/snes/system/serialization.cpp
336 @@ -56,6 +56,7 @@ void System::serialize_all(serializer &s) {
340 + input.serialize(s);
342 if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.serialize(s);
343 if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) icd2.serialize(s);