Save controller state when savestating
When savestating, save the controller state and restore it upon loadstate. Prevents libsnes from mixing up buttons.
This commit is contained in:
parent
b481e3d161
commit
af7fdd9f73
15 changed files with 141 additions and 3 deletions
|
@ -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) {
|
Controller::Controller(bool port) : port(port) {
|
||||||
if(!thread) create(Controller::Enter, 1);
|
if(!thread) create(Controller::Enter, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,12 +13,14 @@
|
||||||
|
|
||||||
struct Controller : Processor {
|
struct Controller : Processor {
|
||||||
enum : bool { Port1 = 0, Port2 = 1 };
|
enum : bool { Port1 = 0, Port2 = 1 };
|
||||||
|
enum { SaveSize = 16 };
|
||||||
const bool port;
|
const bool port;
|
||||||
|
|
||||||
static void Enter();
|
static void Enter();
|
||||||
virtual void enter();
|
virtual void enter();
|
||||||
void step(unsigned clocks);
|
void step(unsigned clocks);
|
||||||
void synchronize_cpu();
|
void synchronize_cpu();
|
||||||
|
virtual void serialize(serializer& s);
|
||||||
|
|
||||||
bool iobit();
|
bool iobit();
|
||||||
void iobit(bool data);
|
void iobit(bool data);
|
||||||
|
|
|
@ -13,6 +13,19 @@ void Gamepad::latch(bool data) {
|
||||||
counter = 0;
|
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) {
|
Gamepad::Gamepad(bool port) : Controller(port) {
|
||||||
latched = 0;
|
latched = 0;
|
||||||
counter = 0;
|
counter = 0;
|
||||||
|
|
|
@ -2,7 +2,7 @@ struct Gamepad : Controller {
|
||||||
uint2 data();
|
uint2 data();
|
||||||
void latch(bool data);
|
void latch(bool data);
|
||||||
Gamepad(bool port);
|
Gamepad(bool port);
|
||||||
|
void serialize(serializer& s);
|
||||||
private:
|
private:
|
||||||
bool latched;
|
bool latched;
|
||||||
unsigned counter;
|
unsigned counter;
|
||||||
|
|
|
@ -103,6 +103,42 @@ void Justifier::latch(bool data) {
|
||||||
if(latched == 0) active = !active; //toggle between both controllers, even when unchained
|
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) {
|
Justifier::Justifier(bool port, bool chained) : Controller(port), chained(chained) {
|
||||||
create(Controller::Enter, 21477272);
|
create(Controller::Enter, 21477272);
|
||||||
latched = 0;
|
latched = 0;
|
||||||
|
|
|
@ -2,6 +2,7 @@ struct Justifier : Controller {
|
||||||
void enter();
|
void enter();
|
||||||
uint2 data();
|
uint2 data();
|
||||||
void latch(bool data);
|
void latch(bool data);
|
||||||
|
void serialize(serializer& s);
|
||||||
Justifier(bool port, bool chained);
|
Justifier(bool port, bool chained);
|
||||||
|
|
||||||
//private:
|
//private:
|
||||||
|
|
|
@ -61,6 +61,19 @@ void Mouse::latch(bool data) {
|
||||||
counter = 0;
|
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) {
|
Mouse::Mouse(bool port) : Controller(port) {
|
||||||
latched = 0;
|
latched = 0;
|
||||||
counter = 0;
|
counter = 0;
|
||||||
|
|
|
@ -2,7 +2,7 @@ struct Mouse : Controller {
|
||||||
uint2 data();
|
uint2 data();
|
||||||
void latch(bool data);
|
void latch(bool data);
|
||||||
Mouse(bool port);
|
Mouse(bool port);
|
||||||
|
void serialize(serializer& s);
|
||||||
private:
|
private:
|
||||||
bool latched;
|
bool latched;
|
||||||
unsigned counter;
|
unsigned counter;
|
||||||
|
|
|
@ -30,6 +30,22 @@ void Multitap::latch(bool data) {
|
||||||
counter2 = 0;
|
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) {
|
Multitap::Multitap(bool port) : Controller(port) {
|
||||||
latched = 0;
|
latched = 0;
|
||||||
counter1 = 0;
|
counter1 = 0;
|
||||||
|
|
|
@ -2,7 +2,7 @@ struct Multitap : Controller {
|
||||||
uint2 data();
|
uint2 data();
|
||||||
void latch(bool data);
|
void latch(bool data);
|
||||||
Multitap(bool port);
|
Multitap(bool port);
|
||||||
|
void serialize(serializer& s);
|
||||||
private:
|
private:
|
||||||
bool latched;
|
bool latched;
|
||||||
unsigned counter1;
|
unsigned counter1;
|
||||||
|
|
|
@ -104,6 +104,37 @@ void SuperScope::latch(bool data) {
|
||||||
counter = 0;
|
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) {
|
SuperScope::SuperScope(bool port) : Controller(port) {
|
||||||
create(Controller::Enter, 21477272);
|
create(Controller::Enter, 21477272);
|
||||||
latched = 0;
|
latched = 0;
|
||||||
|
|
|
@ -2,6 +2,7 @@ struct SuperScope : Controller {
|
||||||
void enter();
|
void enter();
|
||||||
uint2 data();
|
uint2 data();
|
||||||
void latch(bool data);
|
void latch(bool data);
|
||||||
|
void serialize(serializer& s);
|
||||||
SuperScope(bool port);
|
SuperScope(bool port);
|
||||||
|
|
||||||
//private:
|
//private:
|
||||||
|
|
|
@ -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) {
|
Input::Input() : port1(nullptr), port2(nullptr) {
|
||||||
connect(Controller::Port1, Input::Device::Joypad);
|
connect(Controller::Port1, Input::Device::Joypad);
|
||||||
connect(Controller::Port2, Input::Device::Joypad);
|
connect(Controller::Port2, Input::Device::Joypad);
|
||||||
|
|
|
@ -31,6 +31,7 @@ struct Input {
|
||||||
Controller *port1;
|
Controller *port1;
|
||||||
Controller *port2;
|
Controller *port2;
|
||||||
|
|
||||||
|
void serialize(serializer &s);
|
||||||
void connect(bool port, Input::Device id);
|
void connect(bool port, Input::Device id);
|
||||||
Input();
|
Input();
|
||||||
~Input();
|
~Input();
|
||||||
|
|
|
@ -56,6 +56,7 @@ void System::serialize_all(serializer &s) {
|
||||||
smp.serialize(s);
|
smp.serialize(s);
|
||||||
ppu.serialize(s);
|
ppu.serialize(s);
|
||||||
dsp.serialize(s);
|
dsp.serialize(s);
|
||||||
|
input.serialize(s);
|
||||||
|
|
||||||
if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.serialize(s);
|
if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.serialize(s);
|
||||||
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) icd2.serialize(s);
|
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) icd2.serialize(s);
|
||||||
|
|
Loading…
Add table
Reference in a new issue