2016-01-27 11:31:39 +00:00
|
|
|
#include <ws/ws.hpp>
|
|
|
|
|
|
|
|
namespace WonderSwan {
|
|
|
|
|
|
|
|
Interface* interface = nullptr;
|
|
|
|
Settings settings;
|
|
|
|
|
|
|
|
Interface::Interface() {
|
|
|
|
interface = this;
|
|
|
|
|
2016-01-30 06:40:35 +00:00
|
|
|
information.manufacturer = "Bandai";
|
|
|
|
information.name = "WonderSwan";
|
|
|
|
information.width = 224; //note: technically 224x144; but screen can be rotated
|
|
|
|
information.height = 224; //by using a square size; this can be done in the core
|
|
|
|
information.overscan = false;
|
|
|
|
information.aspectRatio = 1.0;
|
|
|
|
information.resettable = false;
|
2016-01-27 11:31:39 +00:00
|
|
|
|
|
|
|
information.capability.states = false;
|
|
|
|
information.capability.cheats = false;
|
|
|
|
|
|
|
|
media.append({ID::WonderSwan, "WonderSwan", "ws", true});
|
|
|
|
media.append({ID::WonderSwanColor, "WonderSwan Color", "wsc", true});
|
|
|
|
|
2016-01-28 11:39:49 +00:00
|
|
|
{ Device device{0, ID::DeviceHorizontal, "Controller"};
|
2016-03-02 11:19:33 +00:00
|
|
|
device.input.append({ 0, 0, "Y1"});
|
|
|
|
device.input.append({ 1, 0, "Y2"});
|
|
|
|
device.input.append({ 2, 0, "Y3"});
|
|
|
|
device.input.append({ 3, 0, "Y4"});
|
|
|
|
device.input.append({ 4, 0, "X1"});
|
|
|
|
device.input.append({ 5, 0, "X2"});
|
|
|
|
device.input.append({ 6, 0, "X3"});
|
|
|
|
device.input.append({ 7, 0, "X4"});
|
2016-01-28 11:39:49 +00:00
|
|
|
device.input.append({ 8, 0, "B"});
|
|
|
|
device.input.append({ 9, 0, "A"});
|
|
|
|
device.input.append({10, 0, "Start"});
|
|
|
|
device.order = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
2016-01-27 11:31:39 +00:00
|
|
|
this->device.append(device);
|
|
|
|
}
|
|
|
|
|
2016-01-28 11:39:49 +00:00
|
|
|
{ Device device{1, ID::DeviceVertical, "Controller"};
|
2016-03-02 11:19:33 +00:00
|
|
|
device.input.append({ 0, 0, "Y1"});
|
|
|
|
device.input.append({ 1, 0, "Y2"});
|
|
|
|
device.input.append({ 2, 0, "Y3"});
|
|
|
|
device.input.append({ 3, 0, "Y4"});
|
|
|
|
device.input.append({ 4, 0, "X1"});
|
|
|
|
device.input.append({ 5, 0, "X2"});
|
|
|
|
device.input.append({ 6, 0, "X3"});
|
|
|
|
device.input.append({ 7, 0, "X4"});
|
2016-01-28 11:39:49 +00:00
|
|
|
device.input.append({ 8, 0, "B"});
|
|
|
|
device.input.append({ 9, 0, "A"});
|
|
|
|
device.input.append({10, 0, "Start"});
|
|
|
|
device.order = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
|
|
|
|
this->device.append(device);
|
|
|
|
}
|
|
|
|
|
|
|
|
port.append({0, "Horizontal Orientation", {device[0]}});
|
|
|
|
port.append({1, "Vertical Orientation", {device[1]}});
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::manifest() -> string {
|
|
|
|
return cartridge.information.manifest;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::title() -> string {
|
|
|
|
return cartridge.information.title;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::videoFrequency() -> double {
|
|
|
|
return 3072000.0 / (159.0 * 256.0); //~75.47hz
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::audioFrequency() -> double {
|
|
|
|
return 3072000.0 / 128.0; //24Khz
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::loaded() -> bool {
|
Update to v097r12 release.
byuu says:
Nothing WS-related this time.
First, I fixed expansion port device mapping. On first load, it was
mapping the expansion port device too late, so it ended up not taking
effect. I had to spin out the logic for that into
Program::connectDevices(). This was proving to be quite annoying while
testing eBoot (SNES-Hook simulation.)
Second, I fixed the audio->set(Frequency, Latency) functions to take
(uint) parameters from the configuration file, so the weird behavior
around changing settings in the audio panel should hopefully be gone
now.
Third, I rewrote the interface->load,unload functions to call into the
(Emulator)::System::load,unload functions. And I have those call out to
Cartridge::load,unload. Before, this was inverted, and Cartridge::load()
was invoking System::load(), which I felt was kind of backward.
The Super Game Boy really didn't like this change, however. And it took
me a few hours to power through it. Before, I had the Game Boy core
dummying out all the interface->(load,save)Request calls, and having the
SNES core make them for it. This is because the folder paths and IDs
will be different between the two cores.
I've redesigned things so that ICD2's Emulator::Interface overloads
loadRequest and saveRequest, and translates the requests into new
requests for the SuperFamicom core. This allows the Game Boy code to do
its own loading for everything without a bunch of Super Game Boy special
casing, and without any awkwardness around powering on with no cartridge
inserted.
This also lets the SNES side of things simply call into higher-level
GameBoy::interface->load,save(id, stream) functions instead of stabbing
at the raw underlying state inside of various Game Boy core emulation
classes. So things are a lot better abstracted now.
2016-02-08 03:17:59 +00:00
|
|
|
return system.loaded();
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::sha256() -> string {
|
|
|
|
return cartridge.information.sha256;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::group(uint id) -> uint {
|
|
|
|
switch(id) {
|
|
|
|
case ID::SystemManifest:
|
2016-02-18 10:32:22 +00:00
|
|
|
case ID::SystemIPLROM:
|
|
|
|
case ID::SystemEEPROM:
|
2016-01-27 11:31:39 +00:00
|
|
|
return 0;
|
|
|
|
case ID::Manifest:
|
|
|
|
case ID::ROM:
|
|
|
|
case ID::RAM:
|
2016-02-18 10:32:22 +00:00
|
|
|
case ID::EEPROM:
|
2016-03-08 11:34:00 +00:00
|
|
|
switch(system.model()) {
|
|
|
|
case System::Model::WonderSwan:
|
2016-01-27 11:31:39 +00:00
|
|
|
return ID::WonderSwan;
|
2016-03-08 11:34:00 +00:00
|
|
|
case System::Model::WonderSwanColor:
|
|
|
|
case System::Model::SwanCrystal:
|
2016-01-27 11:31:39 +00:00
|
|
|
return ID::WonderSwanColor;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::load(uint id) -> void {
|
2016-03-08 11:34:00 +00:00
|
|
|
if(id == ID::WonderSwan) system.load(System::Model::WonderSwan);
|
|
|
|
if(id == ID::WonderSwanColor) system.load(System::Model::WonderSwanColor);
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::save() -> void {
|
2016-02-18 10:32:22 +00:00
|
|
|
if(auto name = system.eeprom.name()) interface->saveRequest(ID::SystemEEPROM, name);
|
|
|
|
if(auto name = cartridge.ram.name) interface->saveRequest(ID::RAM, name);
|
|
|
|
if(auto name = cartridge.eeprom.name()) interface->saveRequest(ID::EEPROM, name);
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::load(uint id, const stream& stream) -> void {
|
|
|
|
if(id == ID::SystemManifest) {
|
|
|
|
system.information.manifest = stream.text();
|
|
|
|
}
|
|
|
|
|
2016-02-18 10:32:22 +00:00
|
|
|
if(id == ID::SystemEEPROM) {
|
|
|
|
stream.read((uint8_t*)system.eeprom.data(), min(system.eeprom.size() * sizeof(uint16), stream.size()));
|
|
|
|
}
|
|
|
|
|
2016-01-27 11:31:39 +00:00
|
|
|
if(id == ID::Manifest) {
|
|
|
|
cartridge.information.manifest = stream.text();
|
|
|
|
}
|
|
|
|
|
|
|
|
if(id == ID::ROM) {
|
2016-02-16 09:27:55 +00:00
|
|
|
stream.read((uint8_t*)cartridge.rom.data, min(cartridge.rom.size, stream.size()));
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(id == ID::RAM) {
|
2016-02-16 09:27:55 +00:00
|
|
|
stream.read((uint8_t*)cartridge.ram.data, min(cartridge.ram.size, stream.size()));
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
2016-02-18 10:32:22 +00:00
|
|
|
|
|
|
|
if(id == ID::EEPROM) {
|
|
|
|
stream.read((uint8_t*)cartridge.eeprom.data(), min(cartridge.eeprom.size() * sizeof(uint16), stream.size()));
|
|
|
|
}
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::save(uint id, const stream& stream) -> void {
|
2016-02-18 10:32:22 +00:00
|
|
|
if(id == ID::SystemEEPROM) {
|
|
|
|
stream.write((uint8_t*)system.eeprom.data(), system.eeprom.size() * sizeof(uint16));
|
|
|
|
}
|
|
|
|
|
2016-01-27 11:31:39 +00:00
|
|
|
if(id == ID::RAM) {
|
2016-02-16 09:27:55 +00:00
|
|
|
stream.write((uint8_t*)cartridge.ram.data, cartridge.ram.size);
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
2016-02-18 10:32:22 +00:00
|
|
|
|
|
|
|
if(id == ID::EEPROM) {
|
|
|
|
stream.write((uint8_t*)cartridge.eeprom.data(), cartridge.eeprom.size() * sizeof(uint16));
|
|
|
|
}
|
2016-01-27 11:31:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::unload() -> void {
|
|
|
|
save();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::power() -> void {
|
|
|
|
system.power();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::run() -> void {
|
|
|
|
system.run();
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::serialize() -> serializer {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::unserialize(serializer& s) -> bool {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::cap(const string& name) -> bool {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::get(const string& name) -> any {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
auto Interface::set(const string& name, const any& value) -> bool {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|