snes-apply lsnes patches

This commit is contained in:
zeromus 2012-09-04 20:23:18 +00:00
parent 44e03b1923
commit b2b1c8755c
27 changed files with 852 additions and 155 deletions

View File

@ -236,13 +236,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
int di = y * vidWidth + x;
int rgb = data[si];
vidBuffer[di] = rgb;
//int r = rgb >> 10;
//int g = (rgb >> 5) & 0x1F;
//int b = (rgb) & 0x1F;
//r = r * 255 / 31;
//g = g * 255 / 31;
//b = b * 255 / 31;
//vidBuffer[di] = (int)unchecked((int)0xFF000000 | (r << 16) | (g << 8) | b);
}
}

Binary file not shown.

View File

@ -35,13 +35,13 @@ uint8 BSXSatellaview::mmio_read(unsigned addr) {
case 0x2192: {
unsigned counter = regs.r2192_counter++;
if(regs.r2192_counter >= 18) regs.r2192_counter = 0;
if(counter == 0) {
time_t rawtime;
time(&rawtime);
tm *t = localtime(&rawtime);
regs.r2192_hour = t->tm_hour;
if(counter == 0) {
time_t rawtime;
rawtime = SNES::interface->currentTime();
tm *t = localtime(&rawtime);
regs.r2192_hour = t->tm_hour;
regs.r2192_minute = t->tm_min;
regs.r2192_second = t->tm_sec;
}

View File

@ -98,13 +98,13 @@ unsigned SPC7110::data_adjust() { return r4814 + (r4815 << 8); }
unsigned SPC7110::data_increment() { return r4816 + (r4817 << 8); }
void SPC7110::set_data_pointer(unsigned addr) { r4811 = addr; r4812 = addr >> 8; r4813 = addr >> 16; }
void SPC7110::set_data_adjust(unsigned addr) { r4814 = addr; r4815 = addr >> 8; }
void SPC7110::update_time(int offset) {
time_t rtc_time = (rtc[16] << 0) | (rtc[17] << 8) | (rtc[18] << 16) | (rtc[19] << 24);
time_t current_time = time(0) - offset;
//sizeof(time_t) is platform-dependent; though rtc[] needs to be platform-agnostic.
//yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by
void SPC7110::update_time(int offset) {
time_t rtc_time = (rtc[16] << 0) | (rtc[17] << 8) | (rtc[18] << 16) | (rtc[19] << 24);
time_t current_time = SNES::interface->currentTime() - offset;
//sizeof(time_t) is platform-dependent; though rtc[] needs to be platform-agnostic.
//yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by
//accounting for overflow at the cost of 1-bit precision (to catch underflow). this will allow
//rtc[] timestamp to remain valid for up to ~34 years from the last update, even if
//time_t overflows. calculation should be valid regardless of number representation, time_t size,

View File

@ -28,13 +28,13 @@ void SRTC::reset() {
rtc_index = -1;
update_time();
}
void SRTC::update_time() {
time_t rtc_time = (rtc[16] << 0) | (rtc[17] << 8) | (rtc[18] << 16) | (rtc[19] << 24);
time_t current_time = time(0);
//sizeof(time_t) is platform-dependent; though rtc[] needs to be platform-agnostic.
//yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by
void SRTC::update_time() {
time_t rtc_time = (rtc[16] << 0) | (rtc[17] << 8) | (rtc[18] << 16) | (rtc[19] << 24);
time_t current_time = SNES::interface->currentTime();
//sizeof(time_t) is platform-dependent; though rtc[] needs to be platform-agnostic.
//yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by
//accounting for overflow at the cost of 1-bit precision (to catch underflow). this will allow
//rtc[] timestamp to remain valid for up to ~34 years from the last update, even if
//time_t overflows. calculation should be valid regardless of number representation, time_t size,

View File

@ -43,11 +43,19 @@ void Controller::iobit(bool data) {
switch(port) {
case Controller::Port1: bus.write(0x4201, (cpu.pio() & ~0x40) | (data << 6)); break;
case Controller::Port2: bus.write(0x4201, (cpu.pio() & ~0x80) | (data << 7)); break;
}
}
Controller::Controller(bool port) : port(port) {
if(!thread) create(Controller::Enter, 1);
}
}
}
}
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);
}
}

View File

@ -10,18 +10,20 @@
// 5: data2 $4016.d1 read $4017.d1 read
// 6: iobit $4201.d6 write; $4213.d6 read $4201.d7 write; $4213.d7 read
// 7: gnd
struct Controller : Processor {
enum : bool { Port1 = 0, Port2 = 1 };
const bool port;
static void Enter();
virtual void enter();
void step(unsigned clocks);
void synchronize_cpu();
bool iobit();
void iobit(bool data);
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);
virtual uint2 data() { return 0; }
virtual void latch(bool data) {}
Controller(bool port);

View File

@ -10,12 +10,25 @@ uint2 Gamepad::data() {
void Gamepad::latch(bool data) {
if(latched == data) return;
latched = data;
counter = 0;
}
Gamepad::Gamepad(bool port) : Controller(port) {
latched = 0;
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) {
latched = 0;
counter = 0;
}
#endif

View File

@ -1,9 +1,9 @@
struct Gamepad : Controller {
uint2 data();
void latch(bool data);
Gamepad(bool port);
private:
bool latched;
unsigned counter;
uint2 data();
void latch(bool data);
Gamepad(bool port);
void serialize(serializer& s);
private:
bool latched;
unsigned counter;
};

View File

@ -97,12 +97,48 @@ void Justifier::latch(bool data) {
if(latched == data) return;
latched = data;
counter = 0;
if(latched == 0) active = !active; //toggle between both controllers, even when unchained
}
Justifier::Justifier(bool port, bool chained) : Controller(port), chained(chained) {
create(Controller::Enter, 21477272);
latched = 0;
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;
counter = 0;
active = 0;

View File

@ -1,10 +1,11 @@
struct Justifier : Controller {
void enter();
uint2 data();
void latch(bool data);
Justifier(bool port, bool chained);
//private:
void enter();
uint2 data();
void latch(bool data);
void serialize(serializer& s);
Justifier(bool port, bool chained);
//private:
const bool chained; //true if the second justifier is attached to the first
bool latched;
unsigned counter;

View File

@ -1,13 +1,15 @@
#ifdef CONTROLLER_CPP
uint2 Mouse::data() {
if(counter >= 32) return 1;
int position_x = interface->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::X); //-n = left, 0 = center, +n = right
int position_y = interface->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::Y); //-n = up, 0 = center, +n = down
bool direction_x = position_x < 0; //0 = right, 1 = left
bool direction_y = position_y < 0; //0 = down, 1 = up
uint2 Mouse::data() {
if(counter >= 32) return 1;
if(counter == 0) {
position_x = interface->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::X); //-n = left, 0 = center, +n = right
position_y = interface->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::Y); //-n = up, 0 = center, +n = down
}
bool direction_x = position_x < 0; //0 = right, 1 = left
bool direction_y = position_y < 0; //0 = down, 1 = up
if(position_x < 0) position_x = -position_x; //abs(position_x)
if(position_y < 0) position_y = -position_y; //abs(position_y)
@ -58,12 +60,31 @@ uint2 Mouse::data() {
void Mouse::latch(bool data) {
if(latched == data) return;
latched = data;
counter = 0;
}
Mouse::Mouse(bool port) : Controller(port) {
latched = 0;
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;
block[2] = (unsigned short)position_x >> 8;
block[3] = (unsigned short)position_x;
block[4] = (unsigned short)position_y >> 8;
block[5] = (unsigned short)position_y;
s.array(block, Controller::SaveSize);
if(s.mode() == nall::serializer::Load) {
latched = (block[0] != 0);
counter = block[1];
position_x = (short)(((unsigned short)block[2] << 8) | (unsigned short)block[3]);
position_y = (short)(((unsigned short)block[4] << 8) | (unsigned short)block[5]);
}
}
Mouse::Mouse(bool port) : Controller(port) {
latched = 0;
counter = 0;
}
#endif

View File

@ -1,9 +1,11 @@
struct Mouse : Controller {
uint2 data();
void latch(bool data);
Mouse(bool port);
private:
bool latched;
unsigned counter;
};
uint2 data();
void latch(bool data);
Mouse(bool port);
void serialize(serializer& s);
private:
bool latched;
unsigned counter;
int position_x;
int position_y;
};

View File

@ -27,12 +27,28 @@ void Multitap::latch(bool data) {
if(latched == data) return;
latched = data;
counter1 = 0;
counter2 = 0;
}
Multitap::Multitap(bool port) : Controller(port) {
latched = 0;
counter1 = 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) {
latched = 0;
counter1 = 0;
counter2 = 0;
}

View File

@ -1,10 +1,10 @@
struct Multitap : Controller {
uint2 data();
void latch(bool data);
Multitap(bool port);
private:
bool latched;
unsigned counter1;
uint2 data();
void latch(bool data);
Multitap(bool port);
void serialize(serializer& s);
private:
bool latched;
unsigned counter1;
unsigned counter2;
};

View File

@ -97,12 +97,43 @@ uint2 SuperScope::data() {
void SuperScope::latch(bool data) {
if(latched == data) return;
latched = data;
counter = 0;
}
SuperScope::SuperScope(bool port) : Controller(port) {
create(Controller::Enter, 21477272);
latched = 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) {
create(Controller::Enter, 21477272);
latched = 0;
counter = 0;
//center cursor onscreen

View File

@ -1,10 +1,11 @@
struct SuperScope : Controller {
void enter();
uint2 data();
void latch(bool data);
SuperScope(bool port);
//private:
void enter();
uint2 data();
void latch(bool data);
void serialize(serializer& s);
SuperScope(bool port);
//private:
bool latched;
unsigned counter;

View File

@ -15,7 +15,17 @@ int16_t Interface::inputPoll(bool port, Input::Device device, unsigned index, un
}
void Interface::message(const string &text) {
print(text, "\n");
}
}
print(text, "\n");
}
time_t Interface::currentTime()
{
return time(0);
}
time_t Interface::randomSeed()
{
return time(0);
}
}

View File

@ -2,9 +2,11 @@ struct Interface {
virtual void videoRefresh(const uint32_t *data, bool hires, bool interlace, bool overscan);
virtual void audioSample(int16_t lsample, int16_t rsample);
virtual int16_t inputPoll(bool port, Input::Device device, unsigned index, unsigned id);
virtual string path(Cartridge::Slot slot, const string &hint) = 0;
virtual void message(const string &text);
};
extern Interface *interface;
virtual string path(Cartridge::Slot slot, const string &hint) = 0;
virtual void message(const string &text);
virtual time_t currentTime();
virtual time_t randomSeed();
};
extern Interface *interface;

View File

@ -23,12 +23,28 @@ void Input::connect(bool port, Input::Device id) {
switch(port) {
case Controller::Port1: config.controller_port1 = id; break;
case Controller::Port2: config.controller_port2 = id; break;
}
}
Input::Input() : port1(nullptr), port2(nullptr) {
connect(Controller::Port1, Input::Device::Joypad);
connect(Controller::Port2, Input::Device::Joypad);
}
}
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);
}
Input::~Input() {

View File

@ -28,12 +28,13 @@ struct Input {
X = 0, Y = 1, Trigger = 2, Start = 3,
};
Controller *port1;
Controller *port2;
void connect(bool port, Input::Device id);
Input();
~Input();
Controller *port1;
Controller *port2;
void serialize(serializer &s);
void connect(bool port, Input::Device id);
Input();
~Input();
};
extern Input input;

View File

@ -53,12 +53,13 @@ void System::serialize_all(serializer &s) {
system.serialize(s);
random.serialize(s);
cpu.serialize(s);
smp.serialize(s);
ppu.serialize(s);
dsp.serialize(s);
if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.serialize(s);
#if defined(GAMEBOY)
smp.serialize(s);
ppu.serialize(s);
dsp.serialize(s);
input.serialize(s);
if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.serialize(s);
#if defined(GAMEBOY)
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) icd2.serialize(s);
#endif
if(cartridge.has_superfx()) superfx.serialize(s);

View File

@ -148,13 +148,13 @@ void System::unload() {
if(cartridge.has_obc1()) obc1.unload();
if(cartridge.has_msu1()) msu1.unload();
if(cartridge.has_link()) link.unload();
}
void System::power() {
random.seed((unsigned)time(0));
region = config.region;
expansion = config.expansion_port;
}
void System::power() {
random.seed((unsigned)interface->randomSeed());
region = config.region;
expansion = config.expansion_port;
if(region == Region::Autodetect) {
region = (cartridge.region() == Cartridge::Region::NTSC ? Region::NTSC : Region::PAL);
}

View File

@ -0,0 +1,84 @@
From 22205d4d339cfa11f6d53e644eae1c859a56d349 Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Wed, 9 Nov 2011 00:37:44 +0200
Subject: [PATCH 1/4] Don't use time() in emulating chips
Instead of using time() in chip emulation, create new interface method
currentTime(), defaulting to time(0). This way frontend can cleanly
override the current time bsnes is using.
---
snes/chip/bsx/satellaview/satellaview.cpp | 2 +-
snes/chip/spc7110/spc7110.cpp | 2 +-
snes/chip/srtc/srtc.cpp | 2 +-
snes/interface/interface.cpp | 5 +++++
snes/interface/interface.hpp | 1 +
5 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/snes/chip/bsx/satellaview/satellaview.cpp b/snes/chip/bsx/satellaview/satellaview.cpp
index 386fb62..3c98019 100755
--- snes/chip/bsx/satellaview/satellaview.cpp
+++ snes/chip/bsx/satellaview/satellaview.cpp
@@ -38,7 +38,7 @@ uint8 BSXSatellaview::mmio_read(unsigned addr) {
if(counter == 0) {
time_t rawtime;
- time(&rawtime);
+ rawtime = SNES::interface->currentTime();
tm *t = localtime(&rawtime);
regs.r2192_hour = t->tm_hour;
diff --git a/snes/chip/spc7110/spc7110.cpp b/snes/chip/spc7110/spc7110.cpp
index 27b8b77..061aa5e 100755
--- snes/chip/spc7110/spc7110.cpp
+++ snes/chip/spc7110/spc7110.cpp
@@ -101,7 +101,7 @@ void SPC7110::set_data_adjust(unsigned addr) { r4814 = addr; r4815 = addr >> 8;
void SPC7110::update_time(int offset) {
time_t rtc_time = (rtc[16] << 0) | (rtc[17] << 8) | (rtc[18] << 16) | (rtc[19] << 24);
- time_t current_time = time(0) - offset;
+ time_t current_time = SNES::interface->currentTime() - offset;
//sizeof(time_t) is platform-dependent; though rtc[] needs to be platform-agnostic.
//yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by
diff --git a/snes/chip/srtc/srtc.cpp b/snes/chip/srtc/srtc.cpp
index 0044113..725e891 100755
--- snes/chip/srtc/srtc.cpp
+++ snes/chip/srtc/srtc.cpp
@@ -31,7 +31,7 @@ void SRTC::reset() {
void SRTC::update_time() {
time_t rtc_time = (rtc[16] << 0) | (rtc[17] << 8) | (rtc[18] << 16) | (rtc[19] << 24);
- time_t current_time = time(0);
+ time_t current_time = SNES::interface->currentTime();
//sizeof(time_t) is platform-dependent; though rtc[] needs to be platform-agnostic.
//yet platforms with 32-bit signed time_t will overflow every ~68 years. handle this by
diff --git a/snes/interface/interface.cpp b/snes/interface/interface.cpp
index a0e3a81..b3017c9 100755
--- snes/interface/interface.cpp
+++ snes/interface/interface.cpp
@@ -18,4 +18,9 @@ void Interface::message(const string &text) {
print(text, "\n");
}
+time_t Interface::currentTime()
+{
+ return time(0);
+}
+
}
diff --git a/snes/interface/interface.hpp b/snes/interface/interface.hpp
index f1a48c0..df975e8 100755
--- snes/interface/interface.hpp
+++ snes/interface/interface.hpp
@@ -5,6 +5,7 @@ struct Interface {
virtual string path(Cartridge::Slot slot, const string &hint) = 0;
virtual void message(const string &text);
+ virtual time_t currentTime();
};
extern Interface *interface;
--
1.7.9.48.g85da4d

View File

@ -0,0 +1,346 @@
From fe11984ad18561506a7cc874cb7c0421f1e21ad1 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 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
--- snes/controller/controller.cpp
+++ 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
--- snes/controller/controller.hpp
+++ 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
--- snes/controller/gamepad/gamepad.cpp
+++ 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
--- snes/controller/gamepad/gamepad.hpp
+++ 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
--- snes/controller/justifier/justifier.cpp
+++ 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
--- snes/controller/justifier/justifier.hpp
+++ 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
--- snes/controller/mouse/mouse.cpp
+++ 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
--- snes/controller/mouse/mouse.hpp
+++ 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
--- snes/controller/multitap/multitap.cpp
+++ 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
--- snes/controller/multitap/multitap.hpp
+++ 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
--- snes/controller/superscope/superscope.cpp
+++ 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
--- snes/controller/superscope/superscope.hpp
+++ 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
--- snes/system/input.cpp
+++ 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
--- snes/system/input.hpp
+++ 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
--- snes/system/serialization.cpp
+++ 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

View File

@ -0,0 +1,53 @@
From 5f76449a70c9a546e18c2fdebe7588bbe90b56d2 Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Fri, 11 Nov 2011 19:49:46 +0200
Subject: [PATCH 3/4] Allow frontend to control random number seed
---
snes/interface/interface.cpp | 5 +++++
snes/interface/interface.hpp | 1 +
snes/system/system.cpp | 2 +-
3 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/snes/interface/interface.cpp b/snes/interface/interface.cpp
index b3017c9..0a21a13 100755
--- snes/interface/interface.cpp
+++ snes/interface/interface.cpp
@@ -23,4 +23,9 @@ time_t Interface::currentTime()
return time(0);
}
+time_t Interface::randomSeed()
+{
+ return time(0);
+}
+
}
diff --git a/snes/interface/interface.hpp b/snes/interface/interface.hpp
index df975e8..30ee7fd 100755
--- snes/interface/interface.hpp
+++ snes/interface/interface.hpp
@@ -6,6 +6,7 @@ struct Interface {
virtual string path(Cartridge::Slot slot, const string &hint) = 0;
virtual void message(const string &text);
virtual time_t currentTime();
+ virtual time_t randomSeed();
};
extern Interface *interface;
diff --git a/snes/system/system.cpp b/snes/system/system.cpp
index 9b70bbf..cbd096c 100755
--- snes/system/system.cpp
+++ snes/system/system.cpp
@@ -151,7 +151,7 @@ void System::unload() {
}
void System::power() {
- random.seed((unsigned)time(0));
+ random.seed((unsigned)interface->randomSeed());
region = config.region;
expansion = config.expansion_port;
--
1.7.9.48.g85da4d

View File

@ -0,0 +1,60 @@
From 160dedf35571478781737ee35307b9321cfb41bb Mon Sep 17 00:00:00 2001
From: Ilari Liusvaara <ilari.liusvaara@elisanet.fi>
Date: Wed, 7 Mar 2012 16:57:18 +0200
Subject: [PATCH 4/4] Fix mouse polling
Don't poll for mouse motion excessive number of times (no need to poll it for
each bit!)
---
snes/controller/mouse/mouse.cpp | 12 ++++++++++--
snes/controller/mouse/mouse.hpp | 2 ++
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/snes/controller/mouse/mouse.cpp b/snes/controller/mouse/mouse.cpp
index 6b26fae..824ecd3 100755
--- snes/controller/mouse/mouse.cpp
+++ snes/controller/mouse/mouse.cpp
@@ -3,8 +3,10 @@
uint2 Mouse::data() {
if(counter >= 32) return 1;
- int position_x = interface->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::X); //-n = left, 0 = center, +n = right
- int position_y = interface->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::Y); //-n = up, 0 = center, +n = down
+ if(counter == 0) {
+ position_x = interface->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::X); //-n = left, 0 = center, +n = right
+ position_y = interface->inputPoll(port, Input::Device::Mouse, 0, (unsigned)Input::MouseID::Y); //-n = up, 0 = center, +n = down
+ }
bool direction_x = position_x < 0; //0 = right, 1 = left
bool direction_y = position_y < 0; //0 = down, 1 = up
@@ -67,10 +69,16 @@ void Mouse::serialize(serializer& s) {
unsigned char block[Controller::SaveSize] = {0};
block[0] = latched ? 1 : 0;
block[1] = counter;
+ block[2] = (unsigned short)position_x >> 8;
+ block[3] = (unsigned short)position_x;
+ block[4] = (unsigned short)position_y >> 8;
+ block[5] = (unsigned short)position_y;
s.array(block, Controller::SaveSize);
if(s.mode() == nall::serializer::Load) {
latched = (block[0] != 0);
counter = block[1];
+ position_x = (short)(((unsigned short)block[2] << 8) | (unsigned short)block[3]);
+ position_y = (short)(((unsigned short)block[4] << 8) | (unsigned short)block[5]);
}
}
diff --git a/snes/controller/mouse/mouse.hpp b/snes/controller/mouse/mouse.hpp
index b66ea51..6074f34 100755
--- snes/controller/mouse/mouse.hpp
+++ snes/controller/mouse/mouse.hpp
@@ -6,4 +6,6 @@ struct Mouse : Controller {
private:
bool latched;
unsigned counter;
+ int position_x;
+ int position_y;
};
--
1.7.9.48.g85da4d