Update to v106r52 release.

byuu says:

I stand corrected, I managed to create and even larger diff than ever.
This one weighs in at 309KiB `>__>`

I'll have to create a changelog later, I'm too tired right now to go
through all of that.
This commit is contained in:
Tim Allen 2018-07-25 22:24:03 +10:00
parent f1a4576ac4
commit 22bd4b9277
171 changed files with 1725 additions and 1403 deletions

View File

@ -1,4 +1,4 @@
target := higan
target := bsnes
binary := application
build := performance
openmp := true
@ -42,6 +42,49 @@ obj/audio.o: audio/audio.cpp
obj/video.o: video/video.cpp
obj/resource.o: resource/resource.cpp
ifeq ($(target),higan)
cores := fc sfc ms md pce gb gba ws
endif
ifeq ($(target),bsnes)
cores := sfc gb
endif
ifneq ($(filter $(cores),fc),)
include fc/GNUmakefile
endif
ifneq ($(filter $(cores),sfc),)
include sfc/GNUmakefile
endif
ifneq ($(filter $(cores),ms),)
include ms/GNUmakefile
endif
ifneq ($(filter $(cores),md),)
include md/GNUmakefile
endif
ifneq ($(filter $(cores),pce),)
include pce/GNUmakefile
endif
ifneq ($(filter $(cores),gb),)
include gb/GNUmakefile
endif
ifneq ($(filter $(cores),gba),)
include gba/GNUmakefile
endif
ifneq ($(filter $(cores),ws),)
include ws/GNUmakefile
endif
include processor/GNUmakefile
flags += $(foreach c,$(call strupper,$(cores)),-DCORE_$c)
ui := target-$(target)
include $(ui)/GNUmakefile
-include obj/*.d

View File

@ -17,11 +17,11 @@ struct Cheat {
codes.reset();
}
auto append(uint addr, uint data, maybe<uint> comp = nothing) -> void {
auto append(uint addr, uint data, maybe<uint> comp = {}) -> void {
codes.append({addr, data, comp});
}
auto assign(const string_vector& list) -> void {
auto assign(const vector<string>& list) -> void {
reset();
for(auto& entry : list) {
for(auto code : entry.split("+")) {

View File

@ -6,7 +6,7 @@ struct Game {
struct Memory;
struct Oscillator;
inline auto load(string_view) -> void;
inline auto load(view<string>) -> void;
inline auto memory(Markup::Node) -> maybe<Memory>;
inline auto oscillator(natural = 0) -> maybe<Oscillator>;
@ -44,7 +44,7 @@ struct Game {
vector<Oscillator> oscillatorList;
};
auto Game::load(string_view text) -> void {
auto Game::load(view<string> text) -> void {
document = BML::unserialize(text);
sha256 = document["game/sha256"].text();

View File

@ -3,22 +3,20 @@
namespace Emulator {
struct Interface {
//information
struct Information {
string manufacturer;
string name;
string extension;
bool resettable = false;
};
virtual auto information() -> Information = 0;
virtual auto manifest() -> string = 0;
virtual auto title() -> string = 0;
struct Display {
struct Type { enum : uint {
CRT,
LCD,
};};
uint id = 0;
string name;
uint type = 0;
uint colors = 0;
uint width = 0;
@ -28,28 +26,16 @@ struct Interface {
double aspectCorrection = 0;
double refreshRate = 0;
};
virtual auto display() -> Display = 0;
virtual auto color(uint32 color) -> uint64 = 0;
//game interface
virtual auto loaded() -> bool = 0;
virtual auto sha256() -> string { return ""; }
virtual auto load() -> bool = 0;
virtual auto save() -> void = 0;
virtual auto unload() -> void = 0;
//system interface
struct Port {
uint id;
string name;
};
virtual auto ports() -> vector<Port> = 0;
struct Device {
uint id;
string name;
};
virtual auto devices(uint port) -> vector<Device> = 0;
struct Input {
struct Type { enum : uint {
@ -60,35 +46,51 @@ struct Interface {
Axis,
Rumble,
};};
uint type;
string name;
};
virtual auto inputs(uint device) -> vector<Input> = 0;
//information
virtual auto information() -> Information { return {}; }
virtual auto displays() -> vector<Display> { return {}; }
virtual auto color(uint32 color) -> uint64 { return 0; }
//game interface
virtual auto loaded() -> bool { return false; }
virtual auto hashes() -> vector<string> { return {}; }
virtual auto manifests() -> vector<string> { return {}; }
virtual auto titles() -> vector<string> { return {}; }
virtual auto load() -> bool { return false; }
virtual auto save() -> void {}
virtual auto unload() -> void {}
//system interface
virtual auto ports() -> vector<Port> { return {}; }
virtual auto devices(uint port) -> vector<Device> { return {}; }
virtual auto inputs(uint device) -> vector<Input> { return {}; }
virtual auto connected(uint port) -> uint { return 0; }
virtual auto connect(uint port, uint device) -> void {}
virtual auto power() -> void = 0;
virtual auto power() -> void {}
virtual auto reset() -> void {}
virtual auto run() -> void = 0;
virtual auto run() -> void {}
//time functions
virtual auto rtc() -> bool { return false; }
virtual auto rtcSynchronize() -> void {}
virtual auto synchronize(uint64 timestamp = 0) -> void {}
//state functions
virtual auto serialize() -> serializer = 0;
virtual auto unserialize(serializer&) -> bool = 0;
virtual auto serialize() -> serializer { return {}; }
virtual auto unserialize(serializer&) -> bool { return false; }
//cheat functions
virtual auto cheatSet(const string_vector& = {}) -> void {}
virtual auto cheats(const vector<string>& = {}) -> void {}
//settings
virtual auto cap(const string& name) -> bool { return false; }
virtual auto get(const string& name) -> any { return {}; }
virtual auto set(const string& name, const any& value) -> bool { return false; }
//shared functions
auto videoColor(uint16 r, uint16 g, uint16 b) -> uint32;
};
}

View File

@ -4,27 +4,24 @@ namespace Emulator {
struct Platform {
struct Load {
Load() : _pathID(nothing) {}
Load(uint pathID, string option = "") : _pathID(pathID), _option(option) {}
Load() = default;
Load(uint pathID, string option = "") : valid(true), pathID(pathID), option(option) {}
explicit operator bool() const { return valid; }
explicit operator bool() const { return (bool)_pathID; }
auto pathID() const -> uint { return _pathID(); }
auto option() const -> string { return _option; }
private:
maybe<uint> _pathID;
string _option;
bool valid = false;
uint pathID = 0;
string option;
};
virtual auto path(uint id) -> string { return ""; }
virtual auto open(uint id, string name, vfs::file::mode mode, bool required = false) -> vfs::shared::file { return {}; }
virtual auto load(uint id, string name, string type, string_vector options = {}) -> Load { return {}; }
virtual auto videoRefresh(const uint32* data, uint pitch, uint width, uint height) -> void {}
virtual auto load(uint id, string name, string type, vector<string> options = {}) -> Load { return {}; }
virtual auto videoRefresh(uint display, const uint32* data, uint pitch, uint width, uint height) -> void {}
virtual auto audioSample(const double* samples, uint channels) -> void {}
virtual auto inputPoll(uint port, uint device, uint input) -> int16 { return 0; }
virtual auto inputRumble(uint port, uint device, uint input, bool enable) -> void {}
virtual auto dipSettings(Markup::Node node) -> uint { return 0; }
virtual auto notify(string text) -> void { print(text, "\n"); }
virtual auto notify(string text) -> void {}
};
extern Platform* platform;

View File

@ -22,6 +22,7 @@ struct BandaiFCG : Board {
case 2: return 0x0000 | (addr & 0x03ff);
case 3: return 0x0400 | (addr & 0x03ff);
}
unreachable;
}
auto readPRG(uint addr) -> uint8 {

View File

@ -151,6 +151,7 @@ struct Sunsoft5B : Board {
case 2: return 0x0000 | (addr & 0x03ff); //first
case 3: return 0x0400 | (addr & 0x03ff); //second
}
unreachable;
}
auto readCHR(uint addr) -> uint8 {

View File

@ -17,8 +17,8 @@ auto Cartridge::main() -> void {
auto Cartridge::load() -> bool {
if(auto loaded = platform->load(ID::Famicom, "Famicom", "fc", {"NTSC-J", "NTSC-U", "PAL"})) {
information.pathID = loaded.pathID();
information.region = loaded.option();
information.pathID = loaded.pathID;
information.region = loaded.option;
} else return false;
if(auto fp = platform->open(pathID(), "manifest.bml", File::Read, File::Required)) {

View File

@ -10,7 +10,7 @@ struct Cartridge : Thread {
auto pathID() const -> uint { return information.pathID; }
auto region() const -> string { return information.region; }
auto sha256() const -> string { return information.sha256; }
auto hash() const -> string { return information.sha256; }
auto manifest() const -> string { return information.manifest; }
auto title() const -> string { return information.title; }

View File

@ -34,6 +34,7 @@ struct MMC1 : Chip {
case 2: return ((addr & 0x0400) >> 0) | (addr & 0x03ff);
case 3: return ((addr & 0x0800) >> 1) | (addr & 0x03ff);
}
unreachable;
}
auto writeIO(uint addr, uint8 data) -> void {

View File

@ -35,6 +35,7 @@ struct MMC3 : Chip {
case 3:
return (0x3f << 13) | (addr & 0x1fff);
}
unreachable;
}
auto addrCHR(uint addr) const -> uint {
@ -53,11 +54,13 @@ struct MMC3 : Chip {
if(addr <= 0x17ff) return (chrBank[0] << 10) | (addr & 0x07ff);
if(addr <= 0x1fff) return (chrBank[1] << 10) | (addr & 0x07ff);
}
return 0;
}
auto addrCIRAM(uint addr) const -> uint {
if(mirror == 0) return ((addr & 0x0400) >> 0) | (addr & 0x03ff);
if(mirror == 1) return ((addr & 0x0800) >> 1) | (addr & 0x03ff);
unreachable;
}
auto readRAM(uint addr) -> uint8 {

View File

@ -83,6 +83,8 @@ struct MMC5 : Chip {
case 0x5205: return (multiplier * multiplicand) >> 0;
case 0x5206: return (multiplier * multiplicand) >> 8;
}
return 0x00;
}
auto writePRG(uint addr, uint8 data) -> void {
@ -215,6 +217,8 @@ struct MMC5 : Chip {
auto bank = chrSpriteBank[(addr / 0x0400)];
return (bank * 0x0400) + (addr & 0x03ff);
}
unreachable;
}
auto chrBGAddr(uint addr) -> uint {
@ -239,6 +243,8 @@ struct MMC5 : Chip {
auto bank = chrBGBank[(addr / 0x0400)];
return (bank * 0x0400) + (addr & 0x03ff);
}
unreachable;
}
auto chrVSAddr(uint addr) -> uint {
@ -274,6 +280,7 @@ struct MMC5 : Chip {
case 2: return exramMode < 2 ? exram[addr & 0x03ff] : (uint8)0x00;
case 3: return (hcounter & 2) == 0 ? fillmodeTile : fillmodeColor;
}
unreachable;
}
auto readCHR(uint addr) -> uint8 {

View File

@ -35,6 +35,7 @@ struct MMC6 : Chip {
case 3:
return (0x3f << 13) | (addr & 0x1fff);
}
unreachable;
}
auto addrCHR(uint addr) const -> uint {
@ -53,11 +54,13 @@ struct MMC6 : Chip {
if(addr <= 0x17ff) return (chrBank[0] << 10) | (addr & 0x07ff);
if(addr <= 0x1fff) return (chrBank[1] << 10) | (addr & 0x07ff);
}
return 0;
}
auto addrCIRAM(uint addr) const -> uint {
if(mirror == 0) return ((addr & 0x0400) >> 0) | (addr & 0x03ff);
if(mirror == 1) return ((addr & 0x0800) >> 1) | (addr & 0x03ff);
unreachable;
}
auto readRAM(uint addr) -> uint8 {

View File

@ -115,6 +115,7 @@ struct VRC6 : Chip {
if((addr & 0xc000) == 0x8000) return (prgBank[0] << 14) | (addr & 0x3fff);
if((addr & 0xe000) == 0xc000) return (prgBank[1] << 13) | (addr & 0x1fff);
if((addr & 0xe000) == 0xe000) return ( 0xff << 13) | (addr & 0x1fff);
return 0x00;
}
auto addrCHR(uint addr) const -> uint {
@ -129,6 +130,7 @@ struct VRC6 : Chip {
case 2: return 0x0000 | (addr & 0x03ff); //one-screen mirroring (first)
case 3: return 0x0400 | (addr & 0x03ff); //one-screen mirroring (second)
}
unreachable;
}
auto readRAM(uint addr) -> uint8 {

View File

@ -96,6 +96,7 @@ struct VRC7 : Chip {
case 2: return 0x0000 | (addr & 0x03ff); //one-screen mirroring (first)
case 3: return 0x0400 | (addr & 0x03ff); //one-screen mirroring (second)
}
unreachable;
}
auto power() -> void {

View File

@ -2,36 +2,30 @@
namespace Famicom {
#define returns(T) T { return ([&] { struct With : T { With() {
#define $ }}; return With(); })(); }
Settings settings;
auto Interface::information() -> returns(Information) {
manufacturer = "Nintendo";
name = "Famicom";
resettable = true;
}$
auto Interface::manifest() -> string {
return cartridge.manifest();
auto Interface::information() -> Information {
Information information;
information.manufacturer = "Nintendo";
information.name = "Famicom";
information.extension = "fc";
information.resettable = true;
return information;
}
auto Interface::title() -> string {
return cartridge.title();
auto Interface::displays() -> vector<Display> {
Display display;
display.type = Display::Type::CRT;
display.colors = 1 << 9;
display.width = 256;
display.height = 240;
display.internalWidth = 256;
display.internalHeight = 240;
display.aspectCorrection = 8.0 / 7.0;
display.refreshRate = system.frequency() / (ppu.vlines() * ppu.rate() * 341.0);
return {display};
}
auto Interface::display() -> returns(Display) {
type = Display::Type::CRT;
colors = 1 << 9;
width = 256;
height = 240;
internalWidth = 256;
internalHeight = 240;
aspectCorrection = 8.0 / 7.0;
refreshRate = system.frequency() / (ppu.vlines() * ppu.rate() * 341.0);
}$
auto Interface::color(uint32 n) -> uint64 {
double saturation = 2.0;
double hue = 0.0;
@ -87,8 +81,16 @@ auto Interface::loaded() -> bool {
return system.loaded();
}
auto Interface::sha256() -> string {
return cartridge.sha256();
auto Interface::hashes() -> vector<string> {
return {cartridge.hash()};
}
auto Interface::manifests() -> vector<string> {
return {cartridge.manifest()};
}
auto Interface::titles() -> vector<string> {
return {cartridge.title()};
}
auto Interface::load() -> bool {
@ -181,7 +183,7 @@ auto Interface::unserialize(serializer& s) -> bool {
return system.unserialize(s);
}
auto Interface::cheatSet(const string_vector& list) -> void {
auto Interface::cheats(const vector<string>& list) -> void {
cheat.assign(list);
}
@ -207,7 +209,4 @@ auto Interface::set(const string& name, const any& value) -> bool {
return false;
}
#undef returns
#undef $
}

View File

@ -1,3 +1,5 @@
#if defined(CORE_FC)
namespace Famicom {
struct ID {
@ -19,18 +21,15 @@ struct ID {
};
struct Interface : Emulator::Interface {
using Emulator::Interface::load;
auto information() -> Information override;
auto manifest() -> string override;
auto title() -> string override;
auto display() -> Display override;
auto displays() -> vector<Display> override;
auto color(uint32 color) -> uint64 override;
auto loaded() -> bool override;
auto sha256() -> string override;
auto hashes() -> vector<string> override;
auto manifests() -> vector<string> override;
auto titles() -> vector<string> override;
auto load() -> bool override;
auto save() -> void override;
auto unload() -> void override;
@ -48,7 +47,7 @@ struct Interface : Emulator::Interface {
auto serialize() -> serializer override;
auto unserialize(serializer&) -> bool override;
auto cheatSet(const string_vector&) -> void override;
auto cheats(const vector<string>&) -> void override;
auto cap(const string& name) -> bool override;
auto get(const string& name) -> any override;
@ -67,3 +66,5 @@ struct Settings {
extern Settings settings;
}
#endif

View File

@ -3,14 +3,11 @@ auto System::serialize() -> serializer {
uint signature = 0x31545342;
char version[16] = {0};
char hash[64] = {0};
char description[512] = {0};
memory::copy(&version, (const char*)Emulator::SerializerVersion, Emulator::SerializerVersion.size());
memory::copy(&hash, (const char*)cartridge.sha256(), 64);
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
serializeAll(s);
@ -20,12 +17,10 @@ auto System::serialize() -> serializer {
auto System::unserialize(serializer& s) -> bool {
uint signature;
char version[16];
char hash[64];
char description[512];
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
if(signature != 0x31545342) return false;
@ -54,12 +49,10 @@ auto System::serializeInit() -> void {
uint signature = 0;
char version[16];
char hash[64];
char description[512];
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
serializeAll(s);

View File

@ -28,19 +28,19 @@ auto Cartridge::load() -> bool {
if(Model::GameBoy()) {
if(auto loaded = platform->load(ID::GameBoy, "Game Boy", "gb")) {
information.pathID = loaded.pathID();
information.pathID = loaded.pathID;
} else return false;
}
if(Model::GameBoyColor()) {
if(auto loaded = platform->load(ID::GameBoyColor, "Game Boy Color", "gbc")) {
information.pathID = loaded.pathID();
information.pathID = loaded.pathID;
} else return false;
}
if(Model::SuperGameBoy()) {
if(auto loaded = platform->load(ID::SuperGameBoy, "Game Boy", "gb")) {
information.pathID = loaded.pathID();
information.pathID = loaded.pathID;
} else return false;
}

View File

@ -1,6 +1,6 @@
struct Cartridge : MMIO {
auto pathID() const -> uint { return information.pathID; }
auto sha256() const -> string { return information.sha256; }
auto hash() const -> string { return information.sha256; }
auto manifest() const -> string { return information.manifest; }
auto title() const -> string { return information.title; }

View File

@ -1,8 +1,10 @@
auto GameBoyColorInterface::information() -> returns(Information) {
manufacturer = "Nintendo";
name = "Game Boy Color";
extension = "gbc";
}$
auto GameBoyColorInterface::information() -> Information {
Information information;
information.manufacturer = "Nintendo";
information.name = "Game Boy Color";
information.extension = "gbc";
return information;
}
auto GameBoyColorInterface::color(uint32 color) -> uint64 {
uint r = color.bits( 0, 4);

View File

@ -1,8 +1,10 @@
auto GameBoyInterface::information() -> returns(Information) {
manufacturer = "Nintendo";
name = "Game Boy";
extension = "gb";
}$
auto GameBoyInterface::information() -> Information {
Information information;
information.manufacturer = "Nintendo";
information.name = "Game Boy";
information.extension = "gb";
return information;
}
auto GameBoyInterface::color(uint32 color) -> uint64 {
if(!settings.colorEmulation) {

View File

@ -2,39 +2,38 @@
namespace GameBoy {
#define returns(T) T { return ([&] { struct With : T { With() {
#define $ }}; return With(); })(); }
SuperGameBoyInterface* superGameBoy = nullptr;
Settings settings;
#include "game-boy.cpp"
#include "game-boy-color.cpp"
auto Interface::manifest() -> string {
return cartridge.manifest();
auto Interface::displays() -> vector<Display> {
Display display;
display.type = Display::Type::LCD;
display.colors = Model::GameBoyColor() ? 1 << 15 : 1 << 2;
display.width = 160;
display.height = 144;
display.internalWidth = 160;
display.internalHeight = 144;
display.aspectCorrection = 1.0;
display.refreshRate = (4.0 * 1024.0 * 1024.0) / (154.0 * 456.0);
return {display};
}
auto Interface::title() -> string {
return cartridge.title();
}
auto Interface::display() -> returns(Display) {
type = Display::Type::LCD;
colors = Model::GameBoyColor() ? 1 << 15 : 1 << 2;
width = 160;
height = 144;
internalWidth = 160;
internalHeight = 144;
aspectCorrection = 1.0;
refreshRate = (4.0 * 1024.0 * 1024.0) / (154.0 * 456.0);
}$
auto Interface::loaded() -> bool {
return system.loaded();
}
auto Interface::sha256() -> string {
return cartridge.sha256();
auto Interface::hashes() -> vector<string> {
return {cartridge.hash()};
}
auto Interface::manifests() -> vector<string> {
return {cartridge.manifest()};
}
auto Interface::titles() -> vector<string> {
return {cartridge.title()};
}
auto Interface::save() -> void {
@ -95,7 +94,7 @@ auto Interface::unserialize(serializer& s) -> bool {
return system.unserialize(s);
}
auto Interface::cheatSet(const string_vector& list) -> void {
auto Interface::cheats(const vector<string>& list) -> void {
cheat.assign(list);
}
@ -129,7 +128,4 @@ auto Interface::set(const string& name, const any& value) -> bool {
return false;
}
#undef returns
#undef $
}

View File

@ -1,3 +1,5 @@
#if defined(CORE_GB)
namespace GameBoy {
struct ID {
@ -18,13 +20,12 @@ struct ID {
};
struct Interface : Emulator::Interface {
auto manifest() -> string override;
auto title() -> string override;
auto display() -> Display override;
auto displays() -> vector<Display> override;
auto loaded() -> bool override;
auto sha256() -> string override;
auto hashes() -> vector<string> override;
auto manifests() -> vector<string> override;
auto titles() -> vector<string> override;
auto save() -> void override;
auto unload() -> void override;
@ -39,7 +40,7 @@ struct Interface : Emulator::Interface {
auto serialize() -> serializer override;
auto unserialize(serializer&) -> bool override;
auto cheatSet(const string_vector&) -> void override;
auto cheats(const vector<string>&) -> void override;
auto cap(const string& name) -> bool override;
auto get(const string& name) -> any override;
@ -47,8 +48,6 @@ struct Interface : Emulator::Interface {
};
struct GameBoyInterface : Interface {
using Emulator::Interface::load;
auto information() -> Information override;
auto color(uint32 color) -> uint64 override;
@ -57,8 +56,6 @@ struct GameBoyInterface : Interface {
};
struct GameBoyColorInterface : Interface {
using Emulator::Interface::load;
auto information() -> Information override;
auto color(uint32 color) -> uint64 override;
@ -85,3 +82,5 @@ extern SuperGameBoyInterface* superGameBoy;
extern Settings settings;
}
#endif

View File

@ -3,14 +3,11 @@ auto System::serialize() -> serializer {
uint signature = 0x31545342;
char version[16] = {0};
char hash[64] = {0};
char description[512] = {0};
memory::copy(&version, (const char*)Emulator::SerializerVersion, Emulator::SerializerVersion.size());
memory::copy(&hash, (const char*)cartridge.sha256(), 64);
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
serializeAll(s);
@ -20,12 +17,10 @@ auto System::serialize() -> serializer {
auto System::unserialize(serializer& s) -> bool {
uint signature;
char version[16] = {0};
char hash[64] = {0};
char description[512];
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
if(signature != 0x31545342) return false;
@ -53,12 +48,10 @@ auto System::serializeInit() -> void {
uint signature = 0;
char version[16] = {0};
char hash[64] = {0};
char description[512] = {0};
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
serializeAll(s);

View File

@ -37,6 +37,7 @@ auto APU::Noise::read(uint addr) const -> uint8 {
case 3: return (divisor << 0) | (narrowlfsr << 3) | (frequency << 4);
case 4: return (counter << 6);
}
return 0;
}
auto APU::Noise::write(uint addr, uint8 byte) -> void {

View File

@ -69,6 +69,7 @@ auto APU::Sequencer::read(uint addr) const -> uint8 {
| (masterenable << 7)
);
}
return 0;
}
auto APU::Sequencer::write(uint addr, uint8 byte) -> void {

View File

@ -30,6 +30,7 @@ auto APU::Square1::read(uint addr) const -> uint8 {
case 3: return 0;
case 4: return (counter << 6);
}
return 0;
}
auto APU::Square1::write(uint addr, uint8 byte) -> void {

View File

@ -5,6 +5,7 @@ auto APU::Square2::read(uint addr) const -> uint8 {
case 3: return 0;
case 4: return (counter << 6);
}
return 0;
}
auto APU::Square2::write(uint addr, uint8 byte) -> void {

View File

@ -25,6 +25,7 @@ auto APU::Wave::read(uint addr) const -> uint8 {
case 3: return 0;
case 4: return (counter << 6);
}
return 0;
}
auto APU::Wave::write(uint addr, uint8 byte) -> void {

View File

@ -27,7 +27,7 @@ auto Cartridge::load() -> bool {
information = Information();
if(auto loaded = platform->load(ID::GameBoyAdvance, "Game Boy Advance", "gba")) {
information.pathID = loaded.pathID();
information.pathID = loaded.pathID;
} else return false;
if(auto fp = platform->open(pathID(), "manifest.bml", File::Read, File::Required)) {

View File

@ -2,7 +2,7 @@ struct Cartridge {
#include "memory.hpp"
auto pathID() const -> uint { return information.pathID; }
auto sha256() const -> string { return information.sha256; }
auto hash() const -> string { return information.sha256; }
auto manifest() const -> string { return information.manifest; }
auto title() const -> string { return information.title; }

View File

@ -2,38 +2,32 @@
namespace GameBoyAdvance {
#define returns(T) T { return ([&] { struct With : T { With() {
#define $ }}; return With(); })(); }
Settings settings;
auto Interface::information() -> returns(Information) {
manufacturer = "Nintendo";
name = "Game Boy Advance";
}$
auto Interface::manifest() -> string {
return cartridge.manifest();
auto Interface::information() -> Information {
Information information;
information.manufacturer = "Nintendo";
information.name = "Game Boy Advance";
information.extension = "gba";
return information;
}
auto Interface::title() -> string {
return cartridge.title();
}
auto Interface::display() -> returns(Display) {
type = Display::Type::LCD;
colors = 1 << 15;
width = 240;
height = 160;
internalWidth = 240;
internalHeight = 160;
aspectCorrection = 1.0;
refreshRate = system.frequency() / (228.0 * 1232.0);
auto Interface::displays() -> vector<Display> {
Display display;
display.type = Display::Type::LCD;
display.colors = 1 << 15;
display.width = 240;
display.height = 160;
display.internalWidth = 240;
display.internalHeight = 160;
display.aspectCorrection = 1.0;
display.refreshRate = system.frequency() / (228.0 * 1232.0);
if(settings.rotateLeft) {
swap(width, height);
swap(internalWidth, internalHeight);
swap(display.width, display.height);
swap(display.internalWidth, display.internalHeight);
}
}$
return {display};
}
auto Interface::color(uint32 color) -> uint64 {
uint R = color.bits( 0, 4);
@ -61,6 +55,18 @@ auto Interface::loaded() -> bool {
return system.loaded();
}
auto Interface::hashes() -> vector<string> {
return {cartridge.hash()};
}
auto Interface::manifests() -> vector<string> {
return {cartridge.manifest()};
}
auto Interface::titles() -> vector<string> {
return {cartridge.title()};
}
auto Interface::load() -> bool {
return system.load(this);
}
@ -159,7 +165,4 @@ auto Interface::set(const string& name, const any& value) -> bool {
return false;
}
#undef returns
#undef $
}

View File

@ -1,3 +1,5 @@
#if defined(CORE_GBA)
namespace GameBoyAdvance {
struct ID {
@ -16,17 +18,15 @@ struct ID {
};
struct Interface : Emulator::Interface {
using Emulator::Interface::load;
auto information() -> Information override;
auto manifest() -> string override;
auto title() -> string override;
auto display() -> Display override;
auto displays() -> vector<Display> override;
auto color(uint32 color) -> uint64 override;
auto loaded() -> bool override;
auto hashes() -> vector<string> override;
auto manifests() -> vector<string> override;
auto titles() -> vector<string> override;
auto load() -> bool override;
auto save() -> void override;
auto unload() -> void override;
@ -55,3 +55,5 @@ struct Settings {
extern Settings settings;
}
#endif

View File

@ -101,6 +101,8 @@ auto PPU::readOAM(uint mode, uint32 addr) -> uint32 {
}
}
unreachable;
}
auto PPU::writeOAM(uint mode, uint32 addr, uint32 word) -> void {

View File

@ -3,14 +3,11 @@ auto System::serialize() -> serializer {
uint signature = 0x31545342;
char version[16] = {0};
char hash[64] = {0};
char description[512] = {0};
memory::copy(&version, (const char*)Emulator::SerializerVersion, Emulator::SerializerVersion.size());
memory::copy(&hash, (const char*)cartridge.sha256(), 64);
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
serializeAll(s);
@ -20,12 +17,10 @@ auto System::serialize() -> serializer {
auto System::unserialize(serializer& s) -> bool {
uint signature = 0;
char version[16] = {0};
char hash[64] = {0};
char description[512] = {0};
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
if(signature != 0x31545342) return false;
@ -55,12 +50,10 @@ auto System::serializeInit() -> void {
uint signature = 0;
char version[16] = {0};
char hash[64] = {0};
char description[512] = {0};
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
serializeAll(s);

View File

@ -11,6 +11,8 @@ auto APU::read(uint16 addr) -> uint8 {
if((addr & 0x8000) == 0x8000) {
return cartridge.read(io.bank << 15 | (addr & 0x7ffe)).byte(!addr.bit(0));
}
return 0x00;
}
auto APU::write(uint16 addr, uint8 data) -> void {

View File

@ -5,54 +5,160 @@ namespace MegaDrive {
Cartridge cartridge;
#include "serialization.cpp"
auto Cartridge::region() const -> string {
return game.region;
}
auto Cartridge::hashes() const -> vector<string> {
vector<string> hashes;
hashes.append(game.hash);
if(lockOn.hash) hashes.append(lockOn.hash);
return hashes;
}
auto Cartridge::manifests() const -> vector<string> {
vector<string> manifests;
manifests.append(game.manifest);
if(lockOn.manifest) manifests.append(lockOn.manifest);
return manifests;
}
auto Cartridge::titles() const -> vector<string> {
vector<string> titles;
titles.append(game.title);
if(lockOn.title) titles.append(lockOn.title);
return titles;
}
auto Cartridge::load() -> bool {
information = {};
game = {};
lockOn = {};
read.reset();
write.reset();
if(!loadGame()) {
game = {};
return false;
}
read = {&Cartridge::readGame, this};
write = {&Cartridge::writeGame, this};
if(game.patch.size) {
read = {&Cartridge::readLockOn, this};
write = {&Cartridge::writeLockOn, this};
if(!loadLockOn()) lockOn = {};
}
return true;
}
auto Cartridge::loadGame() -> bool {
if(auto loaded = platform->load(ID::MegaDrive, "Mega Drive", "md", {"Auto", "NTSC-J", "NTSC-U", "PAL"})) {
information.pathID = loaded.pathID();
information.region = loaded.option();
game.pathID = loaded.pathID;
game.region = loaded.option;
} else return false;
if(auto fp = platform->open(pathID(), "manifest.bml", File::Read, File::Required)) {
information.manifest = fp->reads();
if(auto fp = platform->open(game.pathID, "manifest.bml", File::Read, File::Required)) {
game.manifest = fp->reads();
} else return false;
auto document = BML::unserialize(information.manifest);
information.title = document["game/label"].text();
game.document = BML::unserialize(game.manifest);
game.hash = game.document["game/sha256"].text();
game.title = game.document["game/label"].text();
if(information.region == "Auto") {
if(auto region = document["game/region"].text()) {
information.region = region.upcase();
if(!loadROM(game.rom, game.pathID, game.document["game/board/memory(type=ROM,content=Program)"])) {
game.rom.reset();
return false;
}
if(!loadROM(game.patch, game.pathID, game.document["game/board/memory(type=ROM,content=Patch)"])) {
game.patch.reset();
}
if(!loadRAM(game.ram, game.pathID, game.document["game/board/memory(type=RAM,content=Save)"])) {
game.ram.reset();
}
if(game.region == "Auto") {
if(auto region = game.document["game/region"].text()) {
game.region = region.upcase();
} else {
information.region = "NTSC-J";
game.region = "NTSC-J";
}
}
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=ROM,content=Program)"]}) {
rom.size = memory.size >> 1;
rom.mask = bit::round(rom.size) - 1;
rom.data = new uint16[rom.mask + 1]();
if(auto fp = platform->open(pathID(), memory.name(), File::Read, File::Required)) {
for(uint n : range(rom.size)) rom.data[n] = fp->readm(2);
}
return true;
}
auto Cartridge::loadLockOn() -> bool {
if(auto loaded = platform->load(ID::MegaDrive, "Mega Drive", "md")) {
lockOn.pathID = loaded.pathID;
} else return false;
if(auto fp = platform->open(lockOn.pathID, "manifest.bml", File::Read, File::Required)) {
lockOn.manifest = fp->reads();
} else return false;
lockOn.document = BML::unserialize(lockOn.manifest);
lockOn.hash = lockOn.document["game/sha256"].text();
lockOn.title = lockOn.document["game/label"].text();
if(!loadROM(lockOn.rom, lockOn.pathID, lockOn.document["game/board/memory(type=ROM,content=Program)"])) {
lockOn.rom.reset();
return false;
}
//todo: handle mode, offset in Emulator::Game::Memory
if(auto memory = document["game/board/memory(type=RAM,content=Save)"]) {
if(auto mode = memory["mode"].text()) {
if(mode == "lo" ) ram.bits = 0x00ff;
if(mode == "hi" ) ram.bits = 0xff00;
if(mode == "word") ram.bits = 0xffff;
if(!loadRAM(lockOn.ram, lockOn.pathID, lockOn.document["game/board/memory(type=RAM,content=Save)"])) {
lockOn.ram.reset();
}
if(lockOn.rom.size >= 0x200) {
string name;
name.resize(48);
for(uint n : range(24)) {
name.get()[n * 2 + 0] = lockOn.rom.data[0x120 / 2 + n].byte(1);
name.get()[n * 2 + 1] = lockOn.rom.data[0x120 / 2 + n].byte(0);
}
ram.size = memory["size"].natural() >> (ram.bits == 0xffff);
ram.mask = bit::round(ram.size) - 1;
ram.data = new uint16[ram.mask + 1]();
if(!(bool)memory["volatile"]) {
if(auto fp = platform->open(pathID(), "save.ram", File::Read)) {
for(uint n : range(ram.size)) {
if(ram.bits != 0xffff) ram.data[n] = fp->readm(1) * 0x0101;
if(ram.bits == 0xffff) ram.data[n] = fp->readm(2);
}
name.strip();
while(name.find(" ")) name.replace(" ", " ");
lockOn.patch = name == "SONIC THE HEDGEHOG 2";
}
return true;
}
auto Cartridge::loadROM(Memory& rom, uint pathID, Markup::Node memory) -> bool {
if(!memory) return false;
auto name = string{memory["content"].text(), ".", memory["type"].text()}.downcase();
rom.size = memory["size"].natural() >> 1;
rom.mask = bit::round(rom.size) - 1;
rom.data = new uint16[rom.mask + 1]();
if(auto fp = platform->open(pathID, name, File::Read, File::Required)) {
for(uint n : range(rom.size)) rom.data[n] = fp->readm(2);
} else return false;
return true;
}
auto Cartridge::loadRAM(Memory& ram, uint pathID, Markup::Node memory) -> bool {
if(!memory) return false;
auto name = string{memory["content"].text(), ".", memory["type"].text()}.downcase();
if(auto mode = memory["mode"].text()) {
if(mode == "lo" ) ram.bits = 0x00ff;
if(mode == "hi" ) ram.bits = 0xff00;
if(mode == "word") ram.bits = 0xffff;
}
ram.size = memory["size"].natural() >> (ram.bits == 0xffff);
ram.mask = bit::round(ram.size) - 1;
ram.data = new uint16[ram.mask + 1]();
if(!(bool)memory["volatile"]) {
if(auto fp = platform->open(pathID, name, File::Read)) {
for(uint n : range(ram.size)) {
if(ram.bits != 0xffff) ram.data[n] = fp->readm(1) * 0x0101;
if(ram.bits == 0xffff) ram.data[n] = fp->readm(2);
}
}
}
@ -61,25 +167,34 @@ auto Cartridge::load() -> bool {
}
auto Cartridge::save() -> void {
auto document = BML::unserialize(information.manifest);
saveRAM(game.ram, game.pathID, game.document["game/board/memory(type=RAM,content=Save)"]);
saveRAM(lockOn.ram, lockOn.pathID, lockOn.document["game/board/memory(type=RAM,content=Save)"]);
}
if(auto memory = Emulator::Game::Memory{document["game/board/memory(type=RAM,content=Save)"]}) {
if(memory.nonVolatile) {
if(auto fp = platform->open(pathID(), memory.name(), File::Write)) {
for(uint n : range(ram.size)) {
if(ram.bits != 0xffff) fp->writem(ram.data[n], 1);
if(ram.bits == 0xffff) fp->writem(ram.data[n], 2);
}
}
auto Cartridge::saveRAM(Memory& ram, uint pathID, Markup::Node memory) -> bool {
if(!memory) return false;
if((bool)memory["volatile"]) return true;
auto name = string{memory["content"].text(), ".", memory["type"].text()}.downcase();
if(auto fp = platform->open(pathID, name, File::Write)) {
for(uint n : range(ram.size)) {
if(ram.bits != 0xffff) fp->writem(ram.data[n], 1);
if(ram.bits == 0xffff) fp->writem(ram.data[n], 2);
}
}
} else return false;
return true;
}
auto Cartridge::unload() -> void {
delete[] rom.data;
delete[] ram.data;
rom = {};
ram = {};
game.rom.reset();
game.patch.reset();
game.ram.reset();
game = {};
lockOn.rom.reset();
lockOn.ram.reset();
lockOn = {};
}
auto Cartridge::power() -> void {
@ -88,37 +203,81 @@ auto Cartridge::power() -> void {
for(auto n : range(8)) bank[n] = n;
}
auto Cartridge::read(uint24 address) -> uint16 {
if(address.bit(21) && ram.size && ramEnable) {
return ram.data[address >> 1 & ram.mask];
} else {
address = bank[address.bits(19,21)] << 19 | address.bits(0,18);
return rom.data[address >> 1 & rom.mask];
}
}
//
auto Cartridge::write(uint24 address, uint16 data) -> void {
//emulating RAM write protect bit breaks some commercial software
if(address.bit(21) && ram.size && ramEnable /* && ramWritable */) {
if(ram.bits == 0x00ff) data = data.byte(0) * 0x0101;
if(ram.bits == 0xff00) data = data.byte(1) * 0x0101;
ram.data[address >> 1 & ram.mask] = data;
}
}
auto Cartridge::readIO(uint24 addr) -> uint16 {
auto Cartridge::readIO(uint24 address) -> uint16 {
return 0x0000;
}
auto Cartridge::writeIO(uint24 addr, uint16 data) -> void {
if(addr == 0xa130f1) ramEnable = data.bit(0), ramWritable = data.bit(1);
if(addr == 0xa130f3) bank[1] = data;
if(addr == 0xa130f5) bank[2] = data;
if(addr == 0xa130f7) bank[3] = data;
if(addr == 0xa130f9) bank[4] = data;
if(addr == 0xa130fb) bank[5] = data;
if(addr == 0xa130fd) bank[6] = data;
if(addr == 0xa130ff) bank[7] = data;
auto Cartridge::writeIO(uint24 address, uint16 data) -> void {
if(address == 0xa130f1) ramEnable = data.bit(0), ramWritable = data.bit(1);
if(address == 0xa130f3) bank[1] = data;
if(address == 0xa130f5) bank[2] = data;
if(address == 0xa130f7) bank[3] = data;
if(address == 0xa130f9) bank[4] = data;
if(address == 0xa130fb) bank[5] = data;
if(address == 0xa130fd) bank[6] = data;
if(address == 0xa130ff) bank[7] = data;
}
//
auto Cartridge::readGame(uint24 address) -> uint16 {
if(address >= 0x200000 && game.ram.size && ramEnable) {
return game.ram.data[address >> 1 & game.ram.mask];
} else {
address = bank[address.bits(19,21)] << 19 | address.bits(0,18);
return game.rom.data[address >> 1 & game.rom.mask];
}
}
auto Cartridge::writeGame(uint24 address, uint16 data) -> void {
//emulating RAM write protect bit breaks some commercial software
if(address >= 0x200000 && game.ram.size && ramEnable /* && ramWritable */) {
if(game.ram.bits == 0x00ff) data = data.byte(0) * 0x0101;
if(game.ram.bits == 0xff00) data = data.byte(1) * 0x0101;
game.ram.data[address >> 1 & game.ram.mask] = data;
}
}
//
auto Cartridge::readLockOn(uint24 address) -> uint16 {
if(address >= 0x200000 && lockOn.ram.size && ramEnable) {
return lockOn.ram.data[address >> 1 & lockOn.ram.mask];
}
if(address >= 0x300000 && lockOn.patch) {
return game.patch.data[address >> 1 & game.patch.mask];
}
if(address >= 0x200000 && lockOn.rom.data) {
return lockOn.rom.data[address >> 1 & lockOn.rom.mask];
}
if(address >= 0x200000) {
return 0x00;
}
return game.rom.data[address >> 1 & game.rom.mask];
}
auto Cartridge::writeLockOn(uint24 address, uint16 data) -> void {
if(address >= 0x200000 && lockOn.ram.size && ramEnable) {
if(lockOn.ram.bits == 0x00ff) data = data.byte(0) * 0x0101;
if(lockOn.ram.bits == 0xff00) data = data.byte(1) * 0x0101;
lockOn.ram.data[address >> 1 & lockOn.ram.mask] = data;
}
}
//
auto Cartridge::Memory::reset() -> void {
delete[] data;
data = nullptr;
size = 0;
mask = 0;
bits = 0;
}
}

View File

@ -1,41 +1,69 @@
struct Cartridge {
auto pathID() const -> uint { return information.pathID; }
auto region() const -> string { return information.region; }
auto sha256() const -> string { return information.sha256; }
auto manifest() const -> string { return information.manifest; }
auto title() const -> string { return information.title; }
auto region() const -> string;
auto hashes() const -> vector<string>;
auto manifests() const -> vector<string>;
auto titles() const -> vector<string>;
struct Memory;
auto load() -> bool;
auto loadGame() -> bool;
auto loadLockOn() -> bool;
auto loadROM(Memory& rom, uint pathID, Markup::Node memory) -> bool;
auto loadRAM(Memory& ram, uint pathID, Markup::Node memory) -> bool;
auto save() -> void;
auto saveRAM(Memory& ram, uint pathID, Markup::Node memory) -> bool;
auto unload() -> void;
auto power() -> void;
auto read(uint24 addr) -> uint16;
auto write(uint24 addr, uint16 data) -> void;
function<uint16 (uint24 address)> read;
function<void (uint24 address, uint16 data)> write;
auto readIO(uint24 addr) -> uint16;
auto writeIO(uint24 addr, uint16 data) -> void;
auto readIO(uint24 address) -> uint16;
auto writeIO(uint24 address, uint16 data) -> void;
auto readGame(uint24 address) -> uint16;
auto writeGame(uint24 address, uint16 data) -> void;
auto readLockOn(uint24 address) -> uint16;
auto writeLockOn(uint24 address, uint16 data) -> void;
//serialization.cpp
auto serialize(serializer&) -> void;
struct Information {
uint pathID = 0;
string region;
string sha256;
string manifest;
string title;
} information;
struct Memory {
auto reset() -> void;
uint16* data = nullptr;
uint size = 0;
uint mask = 0;
uint bits = 0;
};
Memory rom;
Memory ram;
struct Game {
uint pathID = 0;
string region;
string hash;
string manifest;
string title;
Markup::Node document;
Memory rom;
Memory patch;
Memory ram;
} game;
struct LockOn {
uint pathID = 0;
string hash;
string manifest;
string title;
Markup::Node document;
Memory rom;
Memory ram;
bool patch = false;
} lockOn;
uint1 ramEnable;
uint1 ramWritable;

View File

@ -1,3 +1,4 @@
auto Cartridge::serialize(serializer& s) -> void {
if(ram.size) s.array(ram.data, ram.size);
if(game.ram.size) s.array(game.ram.data, game.ram.size);
if(lockOn.ram.size) s.array(lockOn.ram.data, lockOn.ram.size);
}

View File

@ -2,36 +2,30 @@
namespace MegaDrive {
#define returns(T) T { return ([&] { struct With : T { With() {
#define $ }}; return With(); })(); }
Settings settings;
auto Interface::information() -> returns(Information) {
manufacturer = "Sega";
name = "Mega Drive";
resettable = true;
}$
auto Interface::manifest() -> string {
return cartridge.manifest();
auto Interface::information() -> Information {
Information information;
information.manufacturer = "Sega";
information.name = "Mega Drive";
information.extension = "md";
information.resettable = true;
return information;
}
auto Interface::title() -> string {
return cartridge.title();
auto Interface::displays() -> vector<Display> {
Display display;
display.type = Display::Type::CRT;
display.colors = 3 * (1 << 9);
display.width = 320;
display.height = 240;
display.internalWidth = 1280;
display.internalHeight = 480;
display.aspectCorrection = 1.0;
display.refreshRate = (system.frequency() / 2.0) / (vdp.frameHeight() * 1710.0);
return {display};
}
auto Interface::display() -> returns(Display) {
type = Display::Type::CRT;
colors = 3 * (1 << 9);
width = 320;
height = 240;
internalWidth = 1280;
internalHeight = 480;
aspectCorrection = 1.0;
refreshRate = (system.frequency() / 2.0) / (vdp.frameHeight() * 1710.0);
}$
auto Interface::color(uint32 color) -> uint64 {
uint R = color.bits(0, 2);
uint G = color.bits(3, 5);
@ -55,6 +49,18 @@ auto Interface::loaded() -> bool {
return system.loaded();
}
auto Interface::hashes() -> vector<string> {
return cartridge.hashes();
}
auto Interface::manifests() -> vector<string> {
return cartridge.manifests();
}
auto Interface::titles() -> vector<string> {
return cartridge.titles();
}
auto Interface::load() -> bool {
return system.load(this);
}
@ -163,7 +169,7 @@ auto Interface::unserialize(serializer& s) -> bool {
return system.unserialize(s);
}
auto Interface::cheatSet(const string_vector& list) -> void {
auto Interface::cheats(const vector<string>& list) -> void {
cheat.assign(list);
}
@ -179,7 +185,4 @@ auto Interface::set(const string& name, const any& value) -> bool {
return false;
}
#undef returns
#undef $
}

View File

@ -1,3 +1,5 @@
#if defined(CORE_MD)
namespace MegaDrive {
struct ID {
@ -20,17 +22,15 @@ struct ID {
};
struct Interface : Emulator::Interface {
using Emulator::Interface::load;
auto information() -> Information override;
auto manifest() -> string override;
auto title() -> string override;
auto display() -> Display override;
auto displays() -> vector<Display> override;
auto color(uint32 color) -> uint64 override;
auto loaded() -> bool override;
auto hashes() -> vector<string> override;
auto manifests() -> vector<string> override;
auto titles() -> vector<string> override;
auto load() -> bool override;
auto save() -> void override;
auto unload() -> void override;
@ -48,7 +48,7 @@ struct Interface : Emulator::Interface {
auto serialize() -> serializer override;
auto unserialize(serializer&) -> bool override;
auto cheatSet(const string_vector& list) -> void override;
auto cheats(const vector<string>& list) -> void override;
auto cap(const string& name) -> bool override;
auto get(const string& name) -> any override;
@ -64,3 +64,5 @@ struct Settings {
extern Settings settings;
}
#endif

View File

@ -3,12 +3,10 @@ auto System::serializeInit() -> void {
uint signature = 0;
char version[16] = {0};
char hash[64] = {0};
char description[512] = {0};
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
serializeAll(s);
@ -20,14 +18,11 @@ auto System::serialize() -> serializer {
uint signature = 0x31545342;
char version[16] = {0};
char hash[64] = {0};
char description[512] = {0};
memory::copy(&version, (const char*)Emulator::SerializerVersion, Emulator::SerializerVersion.size());
memory::copy(&hash, (const char*)cartridge.sha256(), 64);
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
serializeAll(s);
@ -37,12 +32,10 @@ auto System::serialize() -> serializer {
auto System::unserialize(serializer& s) -> bool {
uint signature = 0;
char version[16] = {0};
char hash[64] = {0};
char description[512] = {0};
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
if(signature != 0x31545342) return false;

View File

@ -11,14 +11,14 @@ auto Cartridge::load() -> bool {
if(Model::MasterSystem()) {
if(auto loaded = platform->load(ID::MasterSystem, "Master System", "ms", {"NTSC", "PAL"})) {
information.pathID = loaded.pathID();
information.region = loaded.option();
information.pathID = loaded.pathID;
information.region = loaded.option;
} else return false;
}
if(Model::GameGear()) {
if(auto loaded = platform->load(ID::GameGear, "Game Gear", "gg", {"NTSC"})) {
information.pathID = loaded.pathID();
information.pathID = loaded.pathID;
} else return false;
}

View File

@ -1,7 +1,7 @@
struct Cartridge {
auto pathID() const -> uint { return information.pathID; }
auto region() const -> string { return information.region; }
auto sha256() const -> string { return information.sha256; }
auto hash() const -> string { return information.sha256; }
auto manifest() const -> string { return information.manifest; }
auto title() const -> string { return information.title; }

View File

@ -1,42 +1,25 @@
GameGearInterface::GameGearInterface() {
auto GameGearInterface::information() -> Information {
Information information;
information.manufacturer = "Sega";
information.name = "Game Gear";
information.overscan = false;
media.append({ID::GameGear, "Game Gear", "gg"});
Port hardware{ID::Port::Hardware, "Hardware"};
{ Device device{ID::Device::GameGearControls, "Controls"};
device.inputs.append({0, "Up"});
device.inputs.append({0, "Down"});
device.inputs.append({0, "Left"});
device.inputs.append({0, "Right"});
device.inputs.append({0, "1"});
device.inputs.append({0, "2"});
device.inputs.append({0, "Start"});
hardware.devices.append(device);
}
ports.append(move(hardware));
information.extension = "gg";
return information;
}
auto GameGearInterface::videoInformation() -> VideoInformation {
VideoInformation vi;
vi.width = 160;
vi.height = 144;
vi.internalWidth = 160;
vi.internalHeight = 144;
vi.aspectCorrection = 1.0;
vi.refreshRate = (system.colorburst() * 15.0 / 5.0) / (262.0 * 684.0);
return vi;
auto GameGearInterface::displays() -> vector<Display> {
Display display;
display.type = Display::Type::LCD;
display.colors = 1 << 12;
display.width = 160;
display.height = 144;
display.internalWidth = 160;
display.internalHeight = 144;
display.aspectCorrection = 1.0;
display.refreshRate = (system.colorburst() * 15.0 / 5.0) / (262.0 * 684.0);
return {display};
}
auto GameGearInterface::videoColors() -> uint32 {
return 1 << 12;
}
auto GameGearInterface::videoColor(uint32 color) -> uint64 {
auto GameGearInterface::color(uint32 color) -> uint64 {
uint4 B = color >> 8;
uint4 G = color >> 4;
uint4 R = color >> 0;
@ -48,7 +31,34 @@ auto GameGearInterface::videoColor(uint32 color) -> uint64 {
return r << 32 | g << 16 | b << 0;
}
auto GameGearInterface::load(uint id) -> bool {
if(id == ID::GameGear) return system.load(this, System::Model::GameGear);
return false;
auto GameGearInterface::ports() -> vector<Port> { return {
{ID::Port::Hardware, "Hardware"}};
}
auto GameGearInterface::devices(uint port) -> vector<Device> {
if(port == ID::Port::Hardware) return {
{ID::Device::GameGearControls, "Controls"}
};
return {};
}
auto GameGearInterface::inputs(uint device) -> vector<Input> {
using Type = Input::Type;
if(device == ID::Device::GameGearControls) return {
{Type::Hat, "Up" },
{Type::Hat, "Down" },
{Type::Hat, "Left" },
{Type::Hat, "Right"},
{Type::Button, "1" },
{Type::Button, "2" },
{Type::Control, "Start"}
};
return {};
}
auto GameGearInterface::load() -> bool {
return system.load(this, System::Model::GameGear);
}

View File

@ -6,21 +6,22 @@ Settings settings;
#include "master-system.cpp"
#include "game-gear.cpp"
Interface::Interface() {
}
auto Interface::manifest() -> string {
return cartridge.manifest();
}
auto Interface::title() -> string {
return cartridge.title();
}
auto Interface::loaded() -> bool {
return system.loaded();
}
auto Interface::hashes() -> vector<string> {
return {cartridge.hash()};
}
auto Interface::manifests() -> vector<string> {
return {cartridge.manifest()};
}
auto Interface::titles() -> vector<string> {
return {cartridge.title()};
}
auto Interface::save() -> void {
system.save();
}
@ -47,7 +48,7 @@ auto Interface::unserialize(serializer& s) -> bool {
return system.unserialize(s);
}
auto Interface::cheatSet(const string_vector& list) -> void {
auto Interface::cheats(const vector<string>& list) -> void {
cheat.assign(list);
}

View File

@ -1,3 +1,5 @@
#if defined(CORE_MS)
namespace MasterSystem {
struct ID {
@ -22,12 +24,10 @@ struct ID {
};
struct Interface : Emulator::Interface {
Interface();
auto manifest() -> string override;
auto title() -> string override;
auto loaded() -> bool override;
auto hashes() -> vector<string> override;
auto manifests() -> vector<string> override;
auto titles() -> vector<string> override;
auto save() -> void override;
auto unload() -> void override;
@ -37,7 +37,7 @@ struct Interface : Emulator::Interface {
auto serialize() -> serializer override;
auto unserialize(serializer&) -> bool override;
auto cheatSet(const string_vector&) -> void override;
auto cheats(const vector<string>& list) -> void override;
auto cap(const string& name) -> bool override;
auto get(const string& name) -> any override;
@ -45,36 +45,41 @@ struct Interface : Emulator::Interface {
};
struct MasterSystemInterface : Interface {
using Emulator::Interface::load;
auto information() -> Information override;
MasterSystemInterface();
auto displays() -> vector<Display> override;
auto color(uint32 color) -> uint64 override;
auto videoInformation() -> VideoInformation override;
auto videoColors() -> uint32 override;
auto videoColor(uint32 color) -> uint64 override;
auto ports() -> vector<Port> override;
auto devices(uint port) -> vector<Device> override;
auto inputs(uint device) -> vector<Input> override;
auto load(uint id) -> bool override;
auto load() -> bool override;
auto connected(uint port) -> uint override;
auto connect(uint port, uint device) -> void override;
};
struct GameGearInterface : Interface {
using Emulator::Interface::load;
auto information() -> Information override;
GameGearInterface();
auto displays() -> vector<Display> override;
auto color(uint32 color) -> uint64 override;
auto videoInformation() -> VideoInformation override;
auto videoColors() -> uint32 override;
auto videoColor(uint32 color) -> uint64 override;
auto ports() -> vector<Port> override;
auto devices(uint port) -> vector<Device> override;
auto inputs(uint device) -> vector<Input> override;
auto load(uint id) -> bool override;
auto load() -> bool override;
};
struct Settings {
uint controllerPort1 = 0;
uint controllerPort2 = 0;
uint controllerPort1 = ID::Device::Gamepad;
uint controllerPort2 = ID::Device::Gamepad;
};
extern Settings settings;
}
#endif

View File

@ -1,58 +1,26 @@
MasterSystemInterface::MasterSystemInterface() {
auto MasterSystemInterface::information() -> Information {
Information information;
information.manufacturer = "Sega";
information.name = "Master System";
information.overscan = true;
media.append({ID::MasterSystem, "Master System", "ms"});
Port controllerPort1{ID::Port::Controller1, "Controller Port 1"};
Port controllerPort2{ID::Port::Controller2, "Controller Port 2"};
Port hardware{ID::Port::Hardware, "Hardware"};
{ Device device{ID::Device::None, "None"};
controllerPort1.devices.append(device);
controllerPort2.devices.append(device);
}
{ Device device{ID::Device::Gamepad, "Gamepad"};
device.inputs.append({0, "Up"});
device.inputs.append({0, "Down"});
device.inputs.append({0, "Left"});
device.inputs.append({0, "Right"});
device.inputs.append({0, "1"});
device.inputs.append({0, "2"});
controllerPort1.devices.append(device);
controllerPort2.devices.append(device);
}
{ Device device{ID::Device::MasterSystemControls, "Controls"};
device.inputs.append({0, "Reset"});
device.inputs.append({0, "Pause"});
hardware.devices.append(device);
}
ports.append(move(controllerPort1));
ports.append(move(controllerPort2));
ports.append(move(hardware));
information.extension = "ms";
return information;
}
auto MasterSystemInterface::videoInformation() -> VideoInformation {
VideoInformation vi;
vi.width = 256;
vi.height = 240;
vi.internalWidth = 256;
vi.internalHeight = 240;
vi.aspectCorrection = 8.0 / 7.0;
if(Region::NTSC()) vi.refreshRate = (system.colorburst() * 15.0 / 5.0) / (262.0 * 684.0);
if(Region::PAL()) vi.refreshRate = (system.colorburst() * 15.0 / 5.0) / (312.0 * 684.0);
return vi;
auto MasterSystemInterface::displays() -> vector<Display> {
Display display;
display.type = Display::Type::CRT;
display.colors = 1 << 6;
display.width = 256;
display.height = 240;
display.internalWidth = 256;
display.internalHeight = 240;
display.aspectCorrection = 8.0 / 7.0;
if(Region::NTSC()) display.refreshRate = (system.colorburst() * 15.0 / 5.0) / (262.0 * 684.0);
if(Region::PAL()) display.refreshRate = (system.colorburst() * 15.0 / 5.0) / (312.0 * 684.0);
return {display};
}
auto MasterSystemInterface::videoColors() -> uint32 {
return 1 << 6;
}
auto MasterSystemInterface::videoColor(uint32 color) -> uint64 {
auto MasterSystemInterface::color(uint32 color) -> uint64 {
uint2 B = color >> 4;
uint2 G = color >> 2;
uint2 R = color >> 0;
@ -64,9 +32,62 @@ auto MasterSystemInterface::videoColor(uint32 color) -> uint64 {
return r << 32 | g << 16 | b << 0;
}
auto MasterSystemInterface::load(uint id) -> bool {
if(id == ID::MasterSystem) return system.load(this, System::Model::MasterSystem);
return false;
auto MasterSystemInterface::ports() -> vector<Port> { return {
{ID::Port::Controller1, "Controller Port 1"},
{ID::Port::Controller2, "Controller Port 2"},
{ID::Port::Hardware, "Hardware" }};
}
auto MasterSystemInterface::devices(uint port) -> vector<Device> {
if(port == ID::Port::Controller1) return {
{ID::Device::None, "None" },
{ID::Device::Gamepad, "Gamepad"}
};
if(port == ID::Port::Controller2) return {
{ID::Device::None, "None" },
{ID::Device::Gamepad, "Gamepad"}
};
if(port == ID::Port::Hardware) return {
{ID::Device::MasterSystemControls, "Controls"}
};
return {};
}
auto MasterSystemInterface::inputs(uint device) -> vector<Input> {
using Type = Input::Type;
if(device == ID::Device::None) return {
};
if(device == ID::Device::Gamepad) return {
{Type::Hat, "Up" },
{Type::Hat, "Down" },
{Type::Hat, "Left" },
{Type::Hat, "Right"},
{Type::Button, "1" },
{Type::Button, "2" }
};
if(device == ID::Device::MasterSystemControls) return {
{Type::Control, "Reset"},
{Type::Control, "Power"}
};
return {};
}
auto MasterSystemInterface::load() -> bool {
return system.load(this, System::Model::MasterSystem);
}
auto MasterSystemInterface::connected(uint port) -> uint {
if(port == ID::Port::Controller1) return settings.controllerPort1;
if(port == ID::Port::Controller2) return settings.controllerPort2;
if(port == ID::Port::Hardware) return ID::Device::MasterSystemControls;
return 0;
}
auto MasterSystemInterface::connect(uint port, uint device) -> void {

View File

@ -3,12 +3,10 @@ auto System::serializeInit() -> void {
uint signature = 0;
char version[16] = {0};
char hash[64] = {0};
char description[512] = {0};
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
serializeAll(s);
@ -20,14 +18,11 @@ auto System::serialize() -> serializer {
uint signature = 0x31545342;
char version[16] = {0};
char hash[64] = {0};
char description[512] = {0};
memory::copy(&version, (const char*)Emulator::SerializerVersion, Emulator::SerializerVersion.size());
memory::copy(&hash, (const char*)cartridge.sha256(), 64);
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
serializeAll(s);
@ -37,12 +32,10 @@ auto System::serialize() -> serializer {
auto System::unserialize(serializer& s) -> bool {
uint signature = 0;
char version[16] = {0};
char hash[64] = {0};
char description[512] = {0};
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
if(signature != 0x31545342) return false;

View File

@ -9,13 +9,13 @@ auto Cartridge::load() -> bool {
if(Model::PCEngine()) {
if(auto loaded = platform->load(ID::PCEngine, "PC Engine", "pce")) {
information.pathID = loaded.pathID();
information.pathID = loaded.pathID;
} else return false;
}
if(Model::SuperGrafx()) {
if(auto loaded = platform->load(ID::SuperGrafx, "SuperGrafx", "sg")) {
information.pathID = loaded.pathID();
information.pathID = loaded.pathID;
} else return false;
}

View File

@ -1,6 +1,6 @@
struct Cartridge {
auto pathID() const -> uint { return information.pathID; }
auto sha256() const -> string { return information.sha256; }
auto hash() const -> string { return information.sha256; }
auto manifest() const -> string { return information.manifest; }
auto title() const -> string { return information.title; }

View File

@ -7,54 +7,20 @@ Settings settings;
#include "pc-engine.cpp"
#include "supergrafx.cpp"
Interface::Interface() {
information.overscan = true;
Port controllerPort{ID::Port::Controller, "Controller Port"};
{ Device device{ID::Device::None, "None"};
controllerPort.devices.append(device);
}
{ Device device{ID::Device::Gamepad, "Gamepad"};
device.inputs.append({0, "Up"});
device.inputs.append({0, "Down"});
device.inputs.append({0, "Left"});
device.inputs.append({0, "Right"});
device.inputs.append({0, "II"});
device.inputs.append({0, "I"});
device.inputs.append({0, "Select"});
device.inputs.append({0, "Run"});
controllerPort.devices.append(device);
}
ports.append(move(controllerPort));
auto Interface::displays() -> vector<Display> {
Display display;
display.type = Display::Type::CRT;
display.colors = 1 << 9;
display.width = 280;
display.height = 240;
display.internalWidth = 1120;
display.internalHeight = 240;
display.aspectCorrection = 8.0 / 7.0;
display.refreshRate = (system.colorburst() * 6.0) / (262.0 * 1365.0);
return {display};
}
auto Interface::manifest() -> string {
return cartridge.manifest();
}
auto Interface::title() -> string {
return cartridge.title();
}
auto Interface::videoInformation() -> VideoInformation {
VideoInformation vi;
vi.width = 280;
vi.height = 240;
vi.internalWidth = 1120;
vi.internalHeight = 240;
vi.aspectCorrection = 8.0 / 7.0;
vi.refreshRate = (system.colorburst() * 6.0) / (262.0 * 1365.0);
return vi;
}
auto Interface::videoColors() -> uint32 {
return 1 << 9;
}
auto Interface::videoColor(uint32 color) -> uint64 {
auto Interface::color(uint32 color) -> uint64 {
uint3 B = color.bits(0,2);
uint3 R = color.bits(3,5);
uint3 G = color.bits(6,8);
@ -70,8 +36,16 @@ auto Interface::loaded() -> bool {
return system.loaded();
}
auto Interface::sha256() -> string {
return cartridge.sha256();
auto Interface::hashes() -> vector<string> {
return {cartridge.hash()};
}
auto Interface::manifests() -> vector<string> {
return {cartridge.manifest()};
}
auto Interface::titles() -> vector<string> {
return {cartridge.title()};
}
auto Interface::save() -> void {
@ -83,6 +57,35 @@ auto Interface::unload() -> void {
system.unload();
}
auto Interface::ports() -> vector<Port> { return {
{ID::Port::Controller, "Controller"}};
}
auto Interface::devices(uint port) -> vector<Device> {
if(port == ID::Port::Controller) return {
{ID::Device::Gamepad, "Gamepad"}
};
return {};
}
auto Interface::inputs(uint device) -> vector<Input> {
using Type = Input::Type;
if(device == ID::Device::Gamepad) return {
{Type::Hat, "Up" },
{Type::Hat, "Down" },
{Type::Hat, "Left" },
{Type::Hat, "Right" },
{Type::Button, "II" },
{Type::Button, "I" },
{Type::Control, "Select"},
{Type::Control, "Run" }
};
return {};
}
auto Interface::connected(uint port) -> uint {
if(port == ID::Port::Controller) return settings.controllerPort;
return 0;
@ -109,7 +112,7 @@ auto Interface::unserialize(serializer& s) -> bool {
return system.unserialize(s);
}
auto Interface::cheatSet(const string_vector& list) -> void {
auto Interface::cheats(const vector<string>& list) -> void {
cheat.assign(list);
}

View File

@ -1,3 +1,5 @@
#if defined(CORE_PCE)
namespace PCEngine {
struct ID {
@ -18,20 +20,20 @@ struct ID {
};
struct Interface : Emulator::Interface {
Interface();
auto manifest() -> string override;
auto title() -> string override;
auto videoInformation() -> VideoInformation override;
auto videoColors() -> uint32 override;
auto videoColor(uint32 color) -> uint64 override;
auto displays() -> vector<Display> override;
auto color(uint32 color) -> uint64 override;
auto loaded() -> bool override;
auto sha256() -> string override;
auto hashes() -> vector<string> override;
auto manifests() -> vector<string> override;
auto titles() -> vector<string> override;
auto save() -> void override;
auto unload() -> void override;
auto ports() -> vector<Port> override;
auto devices(uint port) -> vector<Device> override;
auto inputs(uint device) -> vector<Input> override;
auto connected(uint port) -> uint override;
auto connect(uint port, uint device) -> void override;
auto power() -> void override;
@ -40,7 +42,7 @@ struct Interface : Emulator::Interface {
auto serialize() -> serializer override;
auto unserialize(serializer&) -> bool override;
auto cheatSet(const string_vector&) -> void override;
auto cheats(const vector<string>& list) -> void override;
auto cap(const string& name) -> bool override;
auto get(const string& name) -> any override;
@ -48,15 +50,15 @@ struct Interface : Emulator::Interface {
};
struct PCEngineInterface : Interface {
PCEngineInterface();
auto information() -> Information override;
auto load(uint id) -> bool override;
auto load() -> bool override;
};
struct SuperGrafxInterface : Interface {
SuperGrafxInterface();
auto information() -> Information override;
auto load(uint id) -> bool override;
auto load() -> bool override;
};
struct Settings {
@ -66,3 +68,5 @@ struct Settings {
extern Settings settings;
}
#endif

View File

@ -1,11 +1,11 @@
PCEngineInterface::PCEngineInterface() {
auto PCEngineInterface::information() -> Information {
Information information;
information.manufacturer = "NEC";
information.name = "PC Engine";
media.append({ID::PCEngine, "PC Engine", "pce"});
information.extension = "pce";
return information;
}
auto PCEngineInterface::load(uint id) -> bool {
if(id == ID::PCEngine) return system.load(this, System::Model::PCEngine);
return false;
auto PCEngineInterface::load() -> bool {
return system.load(this, System::Model::PCEngine);
}

View File

@ -1,11 +1,11 @@
SuperGrafxInterface::SuperGrafxInterface() {
auto SuperGrafxInterface::information() -> Information {
Information information;
information.manufacturer = "NEC";
information.name = "SuperGrafx";
media.append({ID::SuperGrafx, "SuperGrafx", "sg"});
information.extension = "sg";
return information;
}
auto SuperGrafxInterface::load(uint id) -> bool {
if(id == ID::SuperGrafx) return system.load(this, System::Model::SuperGrafx);
return false;
auto SuperGrafxInterface::load() -> bool {
return system.load(this, System::Model::SuperGrafx);
}

View File

@ -3,12 +3,10 @@ auto System::serializeInit() -> void {
uint signature = 0;
char version[16] = {0};
char hash[64] = {0};
char description[512] = {0};
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
serializeAll(s);
@ -20,14 +18,11 @@ auto System::serialize() -> serializer {
uint signature = 0x31545342;
char version[16] = {0};
char hash[64] = {0};
char description[512] = {0};
memory::copy(&version, (const char*)Emulator::SerializerVersion, Emulator::SerializerVersion.size());
memory::copy(&hash, (const char*)cartridge.sha256(), 64);
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
serializeAll(s);
@ -37,12 +32,10 @@ auto System::serialize() -> serializer {
auto System::unserialize(serializer& s) -> bool {
uint signature = 0;
char version[16] = {0};
char hash[64] = {0};
char description[512] = {0};
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
if(signature != 0x31545342) return false;

View File

@ -25,6 +25,8 @@ auto VDC::read(uint2 addr) -> uint8 {
return data;
}
}
return 0x00;
}
auto VDC::write(uint2 addr, uint8 data) -> void {

View File

@ -62,7 +62,7 @@ auto HuC6280::disassemble(uint16 pc) -> string {
uint8 opcode = readByte();
#define op(id, name, ...) case id: o = {name, " ", string_vector{__VA_ARGS__}.merge(",")}; break;
#define op(id, name, ...) case id: o = {name, " ", vector<string>{__VA_ARGS__}.merge(",")}; break;
string o;
if(T == 1) switch(opcode) {

View File

@ -48,7 +48,7 @@ auto Z80::disassemble(uint16 pc) -> string {
return s;
}
#define op(id, name, ...) case id: return {name, " ", string_vector{__VA_ARGS__}.merge(",")};
#define op(id, name, ...) case id: return {name, " ", vector<string>{__VA_ARGS__}.merge(",")};
#define N string{"$", hex(byte(), 2L)}
#define IN string{"(", N, ")"}

View File

@ -7,23 +7,34 @@ namespace SuperFamicom {
#include "serialization.cpp"
Cartridge cartridge;
auto Cartridge::manifest() const -> string {
string manifest = BML::serialize(game.document);
manifest.append("\n", BML::serialize(board));
if(slotGameBoy.document) manifest.append("\n", BML::serialize(slotGameBoy.document));
if(slotBSMemory.document) manifest.append("\n", BML::serialize(slotBSMemory.document));
if(slotSufamiTurboA.document) manifest.append("\n", BML::serialize(slotSufamiTurboA.document));
if(slotSufamiTurboB.document) manifest.append("\n", BML::serialize(slotSufamiTurboB.document));
return manifest;
auto Cartridge::hashes() const -> vector<string> {
vector<string> hashes;
hashes.append(game.sha256);
if(slotGameBoy.sha256) hashes.append(slotGameBoy.sha256);
if(slotBSMemory.sha256) hashes.append(slotBSMemory.sha256);
if(slotSufamiTurboA.sha256) hashes.append(slotSufamiTurboA.sha256);
if(slotSufamiTurboB.sha256) hashes.append(slotSufamiTurboB.sha256);
return hashes;
}
auto Cartridge::title() const -> string {
auto label = game.label;
if(slotGameBoy.label) label.append(" + ", slotGameBoy.label);
if(slotBSMemory.label) label.append(" + ", slotBSMemory.label);
if(slotSufamiTurboA.label) label.append(" + ", slotSufamiTurboA.label);
if(slotSufamiTurboB.label) label.append(" + ", slotSufamiTurboB.label);
return label;
auto Cartridge::manifests() const -> vector<string> {
vector<string> manifests;
manifests.append(string{BML::serialize(game.document), "\n", BML::serialize(board)});
if(slotGameBoy.document) manifests.append(BML::serialize(slotGameBoy.document));
if(slotBSMemory.document) manifests.append(BML::serialize(slotBSMemory.document));
if(slotSufamiTurboA.document) manifests.append(BML::serialize(slotSufamiTurboA.document));
if(slotSufamiTurboB.document) manifests.append(BML::serialize(slotSufamiTurboB.document));
return manifests;
}
auto Cartridge::titles() const -> vector<string> {
vector<string> titles;
titles.append(game.label);
if(slotGameBoy.label) titles.append(slotGameBoy.label);
if(slotBSMemory.label) titles.append(slotBSMemory.label);
if(slotSufamiTurboA.label) titles.append(slotSufamiTurboA.label);
if(slotSufamiTurboB.label) titles.append(slotSufamiTurboB.label);
return titles;
}
auto Cartridge::load() -> bool {
@ -36,8 +47,8 @@ auto Cartridge::load() -> bool {
slotSufamiTurboB = {};
if(auto loaded = platform->load(ID::SuperFamicom, "Super Famicom", "sfc", {"Auto", "NTSC", "PAL"})) {
information.pathID = loaded.pathID();
information.region = loaded.option();
information.pathID = loaded.pathID;
information.region = loaded.option;
} else return false;
if(auto fp = platform->open(ID::SuperFamicom, "manifest.bml", File::Read, File::Required)) {
@ -93,9 +104,9 @@ auto Cartridge::load() -> bool {
}
auto Cartridge::loadGameBoy() -> bool {
#if defined(SFC_SUPERGAMEBOY)
#if defined(CORE_GB)
//invoked from ICD::load()
information.sha256 = GameBoy::cartridge.sha256();
information.sha256 = GameBoy::cartridge.hash();
slotGameBoy.load(GameBoy::cartridge.manifest());
loadCartridgeGameBoy(slotGameBoy.document);
return true;

View File

@ -1,9 +1,10 @@
struct Cartridge {
auto pathID() const -> uint { return information.pathID; }
auto region() const -> string { return information.region; }
auto sha256() const -> string { return information.sha256; }
auto manifest() const -> string;
auto title() const -> string;
auto hashes() const -> vector<string>;
auto manifests() const -> vector<string>;
auto titles() const -> vector<string>;
auto load() -> bool;
auto save() -> void;

View File

@ -211,7 +211,7 @@ auto Cartridge::loadBSMemory(Markup::Node node) -> void {
has.BSMemorySlot = true;
if(auto loaded = platform->load(ID::BSMemory, "BS Memory", "bs")) {
bsmemory.pathID = loaded.pathID();
bsmemory.pathID = loaded.pathID;
loadBSMemory();
for(auto map : node.find("map")) {
@ -225,7 +225,7 @@ auto Cartridge::loadSufamiTurboA(Markup::Node node) -> void {
has.SufamiTurboSlotA = true;
if(auto loaded = platform->load(ID::SufamiTurboA, "Sufami Turbo", "st")) {
sufamiturboA.pathID = loaded.pathID();
sufamiturboA.pathID = loaded.pathID;
loadSufamiTurboA();
for(auto map : node.find("rom/map")) {
@ -243,7 +243,7 @@ auto Cartridge::loadSufamiTurboB(Markup::Node node) -> void {
has.SufamiTurboSlotB = true;
if(auto loaded = platform->load(ID::SufamiTurboB, "Sufami Turbo", "st")) {
sufamiturboB.pathID = loaded.pathID();
sufamiturboB.pathID = loaded.pathID;
loadSufamiTurboB();
for(auto map : node.find("rom/map")) {

View File

@ -130,6 +130,8 @@ auto Justifier::data() -> uint2 {
case 30: return 0;
case 31: return 0;
}
unreachable;
}
auto Justifier::latch(bool data) -> void {

View File

@ -118,6 +118,8 @@ auto SuperScope::data() -> uint2 {
case 6: return offscreen;
case 7: return 0; //noise (1 = yes)
}
unreachable;
}
auto SuperScope::latch(bool data) -> void {

View File

@ -85,8 +85,8 @@ auto EpsonRTC::power() -> void {
holdtick = 0;
}
auto EpsonRTC::sync() -> void {
time_t systime = time(0);
auto EpsonRTC::synchronize(uint64 timestamp) -> void {
time_t systime = timestamp;
tm* timeinfo = localtime(&systime);
uint second = min(59, timeinfo->tm_sec);

View File

@ -1,12 +1,14 @@
//Epson RTC-4513 Real-Time Clock
struct EpsonRTC : Thread {
using Thread::synchronize;
static auto Enter() -> void;
auto main() -> void;
auto initialize() -> void;
auto power() -> void;
auto sync() -> void;
auto synchronize(uint64 timestamp) -> void;
auto read(uint24 addr, uint8 data) -> uint8;
auto write(uint24 addr, uint8 data) -> void;

View File

@ -4,7 +4,7 @@ namespace SuperFamicom {
ICD icd;
#if defined(SFC_SUPERGAMEBOY)
#if defined(CORE_GB)
#include "platform.cpp"
#include "interface.cpp"

View File

@ -1,4 +1,4 @@
#if defined(SFC_SUPERGAMEBOY)
#if defined(CORE_GB)
struct ICD : Emulator::Platform, GameBoy::SuperGameBoyInterface, Thread {
shared_pointer<Emulator::Stream> stream;

View File

@ -123,6 +123,8 @@ auto MSU1::readIO(uint24 addr, uint8) -> uint8 {
case 0x2006: return 'U';
case 0x2007: return '1';
}
unreachable;
}
auto MSU1::writeIO(uint24 addr, uint8 data) -> void {

View File

@ -242,6 +242,7 @@ auto SA1::bitmapRead(uint addr, uint8 data) -> uint8 {
case 3: return (bwram.read(addr) >> 6) & 3;
}
}
unreachable;
}
auto SA1::bitmapWrite(uint addr, uint8 data) -> void {

View File

@ -253,6 +253,8 @@ auto SDD1::Decompressor::OL::decompress() -> uint8 {
}
return r1;
}
return 0; //unreachable?
}
//core

View File

@ -35,8 +35,8 @@ auto SharpRTC::power() -> void {
index = -1;
}
auto SharpRTC::sync() -> void {
time_t systime = time(0);
auto SharpRTC::synchronize(uint64 timestamp) -> void {
time_t systime = timestamp;
tm* timeinfo = localtime(&systime);
second = min(59, timeinfo->tm_sec);

View File

@ -1,10 +1,12 @@
struct SharpRTC : Thread {
using Thread::synchronize;
static auto Enter() -> void;
auto main() -> void;
auto initialize() -> void;
auto power() -> void;
auto sync() -> void;
auto synchronize(uint64 timestamp) -> void;
auto read(uint24 addr, uint8 data) -> uint8;
auto write(uint24 addr, uint8 data) -> void;

View File

@ -30,7 +30,7 @@ private:
function<uint8 ()>, //read
function<void (uint8)> //write
)> linkInit;
function<void (string_vector)> linkMain;
function<void (vector<string>)> linkMain;
vector<uint8> snesBuffer; //SNES -> Link
vector<uint8> linkBuffer; //Link -> SNES

View File

@ -2,38 +2,31 @@
namespace SuperFamicom {
#define returns(T) T { return ([&] { struct With : T { With() {
#define $ }}; return With(); })(); }
Settings settings;
auto Interface::information() -> returns(Information) {
manufacturer = "Nintendo";
name = "Super Famicom";
extension = "sfc";
resettable = true;
}$
auto Interface::manifest() -> string {
return cartridge.manifest();
auto Interface::information() -> Information {
Information information;
information.manufacturer = "Nintendo";
information.name = "Super Famicom";
information.extension = "sfc";
information.resettable = true;
return information;
}
auto Interface::title() -> string {
return cartridge.title();
auto Interface::displays() -> vector<Display> {
Display display;
display.type = Display::Type::CRT;
display.colors = 1 << 19;
display.width = 256;
display.height = 240;
display.internalWidth = 512;
display.internalHeight = 480;
display.aspectCorrection = 8.0 / 7.0;
if(Region::NTSC()) display.refreshRate = system.cpuFrequency() / (262.0 * 1364.0);
if(Region::PAL()) display.refreshRate = system.cpuFrequency() / (312.0 * 1364.0);
return {display};
}
auto Interface::display() -> returns(Display) {
type = Display::Type::CRT;
colors = 1 << 19;
width = 256;
height = 240;
internalWidth = 512;
internalHeight = 480;
aspectCorrection = 8.0 / 7.0;
if(Region::NTSC()) refreshRate = system.cpuFrequency() / (262.0 * 1364.0);
if(Region::PAL()) refreshRate = system.cpuFrequency() / (312.0 * 1364.0);
}$
auto Interface::color(uint32 color) -> uint64 {
uint r = color.bits( 0, 4);
uint g = color.bits( 5, 9);
@ -66,8 +59,16 @@ auto Interface::loaded() -> bool {
return system.loaded();
}
auto Interface::sha256() -> string {
return cartridge.sha256();
auto Interface::hashes() -> vector<string> {
return cartridge.hashes();
}
auto Interface::manifests() -> vector<string> {
return cartridge.manifests();
}
auto Interface::titles() -> vector<string> {
return cartridge.titles();
}
auto Interface::load() -> bool {
@ -229,9 +230,10 @@ auto Interface::rtc() -> bool {
return false;
}
auto Interface::rtcSynchronize() -> void {
if(cartridge.has.EpsonRTC) epsonrtc.sync();
if(cartridge.has.SharpRTC) sharprtc.sync();
auto Interface::synchronize(uint64 timestamp) -> void {
if(!timestamp) timestamp = chrono::timestamp();
if(cartridge.has.EpsonRTC) epsonrtc.synchronize(timestamp);
if(cartridge.has.SharpRTC) sharprtc.synchronize(timestamp);
}
auto Interface::serialize() -> serializer {
@ -243,9 +245,9 @@ auto Interface::unserialize(serializer& s) -> bool {
return system.unserialize(s);
}
auto Interface::cheatSet(const string_vector& list) -> void {
auto Interface::cheats(const vector<string>& list) -> void {
cheat.reset();
#if defined(SFC_SUPERGAMEBOY)
#if defined(CORE_GB)
if(cartridge.has.ICD) return GameBoy::cheat.assign(list);
#endif
cheat.assign(list);
@ -307,7 +309,4 @@ auto Interface::set(const string& name, const any& value) -> bool {
return false;
}
#undef returns
#undef $
}

View File

@ -1,3 +1,5 @@
#if defined(CORE_SFC)
namespace SuperFamicom {
struct ID {
@ -31,17 +33,15 @@ struct ID {
};
struct Interface : Emulator::Interface {
using Emulator::Interface::load;
auto information() -> Information;
auto manifest() -> string override;
auto title() -> string override;
auto display() -> Display override;
auto displays() -> vector<Display> override;
auto color(uint32 color) -> uint64 override;
auto loaded() -> bool override;
auto sha256() -> string override;
auto hashes() -> vector<string> override;
auto manifests() -> vector<string> override;
auto titles() -> vector<string> override;
auto load() -> bool override;
auto save() -> void override;
auto unload() -> void override;
@ -57,12 +57,12 @@ struct Interface : Emulator::Interface {
auto run() -> void override;
auto rtc() -> bool override;
auto rtcSynchronize() -> void override;
auto synchronize(uint64 timestamp) -> void override;
auto serialize() -> serializer override;
auto unserialize(serializer&) -> bool override;
auto cheatSet(const string_vector&) -> void override;
auto cheats(const vector<string>&) -> void override;
auto cap(const string& name) -> bool override;
auto get(const string& name) -> any override;
@ -88,3 +88,5 @@ struct Settings {
extern Settings settings;
}
#endif

View File

@ -16,7 +16,7 @@
#include <processor/upd96050/upd96050.hpp>
#include <processor/wdc65816/wdc65816.hpp>
#if defined(SFC_SUPERGAMEBOY)
#if defined(CORE_GB)
#include <gb/gb.hpp>
#endif

View File

@ -3,14 +3,11 @@ auto System::serialize() -> serializer {
uint signature = 0x31545342;
char version[16] = {};
char hash[64] = {};
char description[512] = {};
memory::copy(&version, (const char*)Emulator::SerializerVersion, Emulator::SerializerVersion.size());
memory::copy(&hash, (const char*)cartridge.sha256(), 64);
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
s.boolean(hacks.fastPPU);
@ -23,12 +20,10 @@ auto System::serialize() -> serializer {
auto System::unserialize(serializer& s) -> bool {
uint signature = 0;
char version[16] = {};
char hash[64] = {};
char description[512] = {};
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
if(signature != 0x31545342) return false;
@ -92,12 +87,10 @@ auto System::serializeInit() -> void {
uint signature = 0;
char version[16] = {};
char hash[64] = {};
char description[512] = {};
s.integer(signature);
s.array(version);
s.array(hash);
s.array(description);
s.boolean(hacks.fastPPU);

View File

@ -1,5 +1,5 @@
database
revision: 2018-06-25
revision: 2018-07-25
//Boards (Production)
@ -565,7 +565,7 @@ board: SHVC-YJ0N-01
//Boards (Generic)
database
revision: 2018-06-25
revision: 2018-07-25
board: ARM-LOROM-RAM
memory type=ROM content=Program
@ -768,18 +768,18 @@ board: LOROM
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
board: LOROM-RAM
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: LOROM-RAM#A
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-ffff mask=0x8000
board: LOROM-RAM#B
memory type=ROM content=Program
map address=00-7d,80-ff:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
board: NEC-HIROM
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff
@ -814,6 +814,18 @@ board: NEC-LOROM
memory type=RAM content=Data architecture=uPD7725
oscillator
board: NEC-LOROM-RAM
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
processor architecture=uPD7725
map address=60-6f,e0-ef:0000-7fff mask=0x3fff
memory type=ROM content=Program architecture=uPD7725
memory type=ROM content=Data architecture=uPD7725
memory type=RAM content=Data architecture=uPD7725
oscillator
board: NEC-LOROM-RAM#A
memory type=ROM content=Program
map address=00-1f,80-9f:8000-ffff mask=0x8000
@ -826,18 +838,6 @@ board: NEC-LOROM-RAM#A
memory type=RAM content=Data architecture=uPD7725
oscillator
board: NEC-LOROM-RAM#B
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000
memory type=RAM content=Save
map address=70-7d,f0-ff:0000-7fff mask=0x8000
processor architecture=uPD7725
map address=60-6f,e0-ef:0000-7fff mask=0x3fff
memory type=ROM content=Program architecture=uPD7725
memory type=ROM content=Data architecture=uPD7725
memory type=RAM content=Data architecture=uPD7725
oscillator
board: OBC1-LOROM-RAM
memory type=ROM content=Program
map address=00-3f,80-bf:8000-ffff mask=0x8000

View File

@ -1,9 +1,4 @@
name := bsnes
flags += -DSFC_SUPERGAMEBOY
include sfc/GNUmakefile
include gb/GNUmakefile
include processor/GNUmakefile
hiro.path := ../hiro
hiro.resource := $(ui)/resource/bsnes.rc

View File

@ -19,7 +19,7 @@ auto locate(string name) -> string {
}
#include <nall/main.hpp>
auto nall::main(string_vector arguments) -> void {
auto nall::main(vector<string> arguments) -> void {
string locale; // = "日本語";
for(auto argument : arguments) {
if(argument.beginsWith("--locale=")) {

View File

@ -132,7 +132,7 @@ Presentation::Presentation() {
aboutWindow->setCentered(*this).setVisible().setFocused();
});
viewport.setDroppable().onDrop([&](string_vector locations) {
viewport.setDroppable().onDrop([&](vector<string> locations) {
program->gameQueue = locations;
program->load();
setFocused();

View File

@ -6,15 +6,18 @@ auto Program::load() -> void {
screenshot = {};
frameAdvance = false;
if(!verified() && settingsWindow->advanced.warnOnUnverifiedGames.checked()) {
//todo: MessageDialog crashes with GTK+; unsure the reason why this happens
//once MessageDialog functions, add an "Always" option
if(MessageWindow(
"Warning: this game image is unverified. Running it *may* be a security risk.\n\n"
auto response = MessageDialog(
"Warning: this game image is unverified.\n"
"Running it *may* be a security risk.\n\n"
"Do you wish to run the game anyway?"
).setParent(*presentation).question() == MessageWindow::Response::No) {
).setParent(*presentation).question({"Always", "Yes", "No"});
if(response == "No") {
emulator->unload();
return showMessage("Game loading cancelled");
}
if(response == "Always") {
settingsWindow->advanced.warnOnUnverifiedGames.setChecked(false).doToggle();
}
}
hackCompatibility();
emulator->power();
@ -25,7 +28,7 @@ auto Program::load() -> void {
verified() ? "Verified game loaded" : "Game loaded",
appliedPatch() ? " and patch applied" : ""
});
presentation->setTitle(emulator->title());
presentation->setTitle(emulator->titles().merge(" + "));
presentation->resetSystem.setEnabled(true);
presentation->unloadGame.setEnabled(true);
presentation->toolsMenu.setVisible(true);
@ -38,10 +41,10 @@ auto Program::load() -> void {
toolsWindow->manifestViewer.loadManifest();
string locations = superFamicom.location;
if(auto location = gameBoy.location) locations.append("|", location);
if(auto location = bsMemory.location) locations.append("|", location);
if(auto location = sufamiTurboA.location) locations.append("|", location);
if(auto location = sufamiTurboB.location) locations.append("|", location);
if(auto& location = gameBoy.location) locations.append("|", location);
if(auto& location = bsMemory.location) locations.append("|", location);
if(auto& location = sufamiTurboA.location) locations.append("|", location);
if(auto& location = sufamiTurboB.location) locations.append("|", location);
presentation->addRecentGame(locations);
updateVideoPalette();
@ -75,9 +78,9 @@ auto Program::loadSuperFamicom(string location) -> bool {
rom.append(file::read({location, "program.rom"}));
rom.append(file::read({location, "data.rom"}));
rom.append(file::read({location, "expansion.rom"}));
for(auto filename : directory::files(location, "*.boot.rom" )) rom.append(file::read({location, filename}));
for(auto filename : directory::files(location, "*.program.rom")) rom.append(file::read({location, filename}));
for(auto filename : directory::files(location, "*.data.rom" )) rom.append(file::read({location, filename}));
for(auto& filename : directory::files(location, "*.boot.rom" )) rom.append(file::read({location, filename}));
for(auto& filename : directory::files(location, "*.program.rom")) rom.append(file::read({location, filename}));
for(auto& filename : directory::files(location, "*.data.rom" )) rom.append(file::read({location, filename}));
} else {
manifest = file::read({Location::notsuffix(location), ".bml"});
rom = loadFile(location);

View File

@ -103,7 +103,7 @@ auto Program::open(uint id, string name, vfs::file::mode mode, bool required) ->
return result;
}
auto Program::load(uint id, string name, string type, string_vector options) -> Emulator::Platform::Load {
auto Program::load(uint id, string name, string type, vector<string> options) -> Emulator::Platform::Load {
BrowserDialog dialog;
dialog.setParent(*presentation);
dialog.setOptions(options);
@ -196,7 +196,7 @@ auto Program::load(uint id, string name, string type, string_vector options) ->
return {};
}
auto Program::videoRefresh(const uint32* data, uint pitch, uint width, uint height) -> void {
auto Program::videoRefresh(uint display, const uint32* data, uint pitch, uint width, uint height) -> void {
uint32_t* output;
uint length;

View File

@ -13,7 +13,7 @@
#include "hacks.cpp"
unique_pointer<Program> program;
Program::Program(string_vector arguments) {
Program::Program(vector<string> arguments) {
program = this;
Emulator::platform = this;
@ -89,5 +89,5 @@ auto Program::quit() -> void {
video.reset();
audio.reset();
input.reset();
Application::quit();
Application::kill();
}

View File

@ -2,14 +2,14 @@ struct Program : Emulator::Platform {
Application::Namespace tr{"Program"};
//program.cpp
Program(string_vector arguments);
Program(vector<string> arguments);
auto main() -> void;
auto quit() -> void;
//platform.cpp
auto open(uint id, string name, vfs::file::mode mode, bool required) -> vfs::shared::file override;
auto load(uint id, string name, string type, string_vector options = {}) -> Emulator::Platform::Load override;
auto videoRefresh(const uint32* data, uint pitch, uint width, uint height) -> void override;
auto load(uint id, string name, string type, vector<string> options = {}) -> Emulator::Platform::Load override;
auto videoRefresh(uint display, const uint32* data, uint pitch, uint width, uint height) -> void override;
auto audioSample(const double* samples, uint channels) -> void override;
auto inputPoll(uint port, uint device, uint input) -> int16 override;
auto inputRumble(uint port, uint device, uint input, bool enable) -> void override;
@ -49,7 +49,7 @@ struct Program : Emulator::Platform {
auto screenshotPath() -> string;
//states.cpp
auto managedStates() -> string_vector;
auto managedStates() -> vector<string>;
auto loadState(string filename) -> bool;
auto saveState(string filename) -> bool;
auto saveUndoState() -> bool;
@ -124,7 +124,7 @@ public:
vector<uint8_t> program;
} sufamiTurboA, sufamiTurboB;
string_vector gameQueue;
vector<string> gameQueue;
struct Screenshot {
const uint32* data = nullptr;

View File

@ -1,4 +1,4 @@
auto Program::managedStates() -> string_vector {
auto Program::managedStates() -> vector<string> {
if(!emulator->loaded()) return {};
if(gamePath().endsWith("/")) {
@ -6,7 +6,7 @@ auto Program::managedStates() -> string_vector {
} else {
Decode::ZIP input;
if(input.open(statePath())) {
string_vector filenames;
vector<string> filenames;
for(auto& file : input.file) {
if(file.name.match("managed/*.bst")) filenames.append(file.name.trimLeft("managed/", 1L));
}

View File

@ -863,8 +863,8 @@ const nall::vector<uint8_t> Manifest = { //size: 334
115,112,10,32,32,32,32,114,97,109,32,110,97,109,101,61,97,112,117,46,114,97,109,32,115,105,122,101,61,48,120,49,
48,48,48,48,32,118,111,108,97,116,105,108,101,10,
};
const nall::vector<uint8_t> Boards = { //size: 30186
100,97,116,97,98,97,115,101,10,32,32,114,101,118,105,115,105,111,110,58,32,50,48,49,56,45,48,54,45,50,53,10,
const nall::vector<uint8_t> Boards = { //size: 30182
100,97,116,97,98,97,115,101,10,32,32,114,101,118,105,115,105,111,110,58,32,50,48,49,56,45,48,55,45,50,53,10,
10,47,47,66,111,97,114,100,115,32,40,80,114,111,100,117,99,116,105,111,110,41,10,10,100,97,116,97,98,97,115,101,
10,32,32,114,101,118,105,115,105,111,110,58,32,50,48,49,56,45,48,53,45,49,54,10,10,98,111,97,114,100,58,32,
66,65,78,68,65,73,45,80,84,45,57,50,51,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,
@ -1437,7 +1437,7 @@ const nall::vector<uint8_t> Boards = { //size: 30186
32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,
32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,
102,102,102,102,10,10,47,47,66,111,97,114,100,115,32,40,71,101,110,101,114,105,99,41,10,10,100,97,116,97,98,97,
115,101,10,32,32,114,101,118,105,115,105,111,110,58,32,50,48,49,56,45,48,54,45,50,53,10,10,98,111,97,114,100,
115,101,10,32,32,114,101,118,105,115,105,111,110,58,32,50,48,49,56,45,48,55,45,50,53,10,10,98,111,97,114,100,
58,32,65,82,77,45,76,79,82,79,77,45,82,65,77,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,
77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,
115,61,48,48,45,55,100,44,56,48,45,102,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,
@ -1651,51 +1651,65 @@ const nall::vector<uint8_t> Boards = { //size: 30186
108,97,116,111,114,10,10,98,111,97,114,100,58,32,76,79,82,79,77,10,32,32,109,101,109,111,114,121,32,116,121,112,
101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,
100,114,101,115,115,61,48,48,45,55,100,44,56,48,45,102,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,
61,48,120,56,48,48,48,10,10,98,111,97,114,100,58,32,76,79,82,79,77,45,82,65,77,35,65,10,32,32,109,101,
61,48,120,56,48,48,48,10,10,98,111,97,114,100,58,32,76,79,82,79,77,45,82,65,77,10,32,32,109,101,109,111,
114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,
109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,55,100,44,56,48,45,102,102,58,56,48,48,48,45,102,102,102,
102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,
99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,
55,100,44,102,48,45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,10,
98,111,97,114,100,58,32,76,79,82,79,77,45,82,65,77,35,65,10,32,32,109,101,109,111,114,121,32,116,121,112,101,
61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,
114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,
48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,
61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,
102,58,48,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,10,98,111,97,114,100,58,32,
78,69,67,45,72,73,82,79,77,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,
101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,
102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,
115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,112,114,111,99,101,115,
115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,97,112,
32,97,100,100,114,101,115,115,61,48,48,45,49,102,44,56,48,45,57,102,58,54,48,48,48,45,55,102,102,102,32,109,
97,115,107,61,48,120,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,
110,116,101,110,116,61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,
50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,68,
97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,101,109,
111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,
101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,111,115,99,105,108,108,97,116,111,114,10,10,98,
111,97,114,100,58,32,78,69,67,45,72,73,82,79,77,45,82,65,77,10,32,32,109,101,109,111,114,121,32,116,121,112,
101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,
100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,
109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,102,102,102,
102,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,
10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,54,48,48,
48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,32,32,112,114,111,99,101,115,115,111,114,32,97,
114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,97,112,32,97,100,100,114,
101,115,115,61,48,48,45,49,102,44,56,48,45,57,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,
120,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,
61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,
32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,
114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,
121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,
101,61,117,80,68,55,55,50,53,10,32,32,32,32,111,115,99,105,108,108,97,116,111,114,10,10,98,111,97,114,100,58,
32,78,69,67,45,76,79,82,79,77,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,
116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,
49,102,44,56,48,45,57,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,
32,112,114,111,99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,
32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,51,48,45,51,102,44,98,48,45,98,102,58,56,48,48,48,
45,102,102,102,102,32,109,97,115,107,61,48,120,51,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,
101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99,116,117,
114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,
111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,
10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116,
97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,111,115,99,105,108,
108,97,116,111,114,10,10,98,111,97,114,100,58,32,78,69,67,45,76,79,82,79,77,45,82,65,77,10,32,32,109,101,
109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,
32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,
102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,
77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,
48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,
10,10,98,111,97,114,100,58,32,76,79,82,79,77,45,82,65,77,35,66,10,32,32,109,101,109,111,114,121,32,116,121,
112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,
100,100,114,101,115,115,61,48,48,45,55,100,44,56,48,45,102,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,
107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,
110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,44,102,48,
45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,10,98,111,97,114,100,
58,32,78,69,67,45,72,73,82,79,77,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,
110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,
45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,109,97,112,32,97,100,100,114,
101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,112,114,111,99,
101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,
97,112,32,97,100,100,114,101,115,115,61,48,48,45,49,102,44,56,48,45,57,102,58,54,48,48,48,45,55,102,102,102,
32,109,97,115,107,61,48,120,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,
99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,
55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,
61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,
101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,
105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,111,115,99,105,108,108,97,116,111,114,10,
10,98,111,97,114,100,58,32,78,69,67,45,72,73,82,79,77,45,82,65,77,10,32,32,109,101,109,111,114,121,32,116,
121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,
97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,
32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,55,100,44,99,48,45,102,102,58,48,48,48,48,45,102,
102,102,102,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,
118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,54,
48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,32,32,112,114,111,99,101,115,115,111,114,
32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,97,112,32,97,100,
100,114,101,115,115,61,48,48,45,49,102,44,56,48,45,57,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,
61,48,120,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,
110,116,61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,
32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,68,97,116,97,
32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,
32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,
117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,111,115,99,105,108,108,97,116,111,114,10,10,98,111,97,114,
100,58,32,78,69,67,45,76,79,82,79,77,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,
111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,
48,45,49,102,44,56,48,45,57,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,
48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,
10,32,32,112,114,111,99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,
53,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,51,48,45,51,102,44,98,48,45,98,102,58,56,48,
48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,51,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,
53,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,54,48,45,54,102,44,101,48,45,101,102,58,48,48,
48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,51,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,
121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99,
116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,
32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,
@ -1715,99 +1729,85 @@ const nall::vector<uint8_t> Boards = { //size: 30186
61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,109,
101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,97,114,99,104,
105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,111,115,99,105,108,108,97,116,111,114,10,
10,98,111,97,114,100,58,32,78,69,67,45,76,79,82,79,77,45,82,65,77,35,66,10,32,32,109,101,109,111,114,121,
32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,
112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,
109,97,115,107,61,48,120,56,48,48,48,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,
110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,
44,102,48,45,102,102,58,48,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,112,
114,111,99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,
32,32,109,97,112,32,97,100,100,114,101,115,115,61,54,48,45,54,102,44,101,48,45,101,102,58,48,48,48,48,45,55,
102,102,102,32,109,97,115,107,61,48,120,51,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,
82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,32,97,114,99,104,105,116,101,99,116,117,114,101,
61,117,80,68,55,55,50,53,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,
116,101,110,116,61,68,97,116,97,32,97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,
32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,68,97,116,97,32,
97,114,99,104,105,116,101,99,116,117,114,101,61,117,80,68,55,55,50,53,10,32,32,32,32,111,115,99,105,108,108,97,
116,111,114,10,10,98,111,97,114,100,58,32,79,66,67,49,45,76,79,82,79,77,45,82,65,77,10,32,32,109,101,109,
111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,
32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,
102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,112,114,111,99,101,115,115,111,114,32,105,100,101,110,116,
105,102,105,101,114,61,79,66,67,49,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,
44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,32,32,32,
32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,49,44,102,48,45,102,49,58,54,48,48,48,45,55,102,
102,102,44,101,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,32,32,32,32,109,101,109,
111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,10,98,111,97,114,100,
58,32,83,65,49,45,82,65,77,10,32,32,112,114,111,99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,
114,101,61,87,54,53,67,56,49,54,83,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,
102,44,56,48,45,98,102,58,50,50,48,48,45,50,51,102,102,10,32,32,32,32,109,99,117,10,32,32,32,32,32,32,
109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,
102,32,109,97,115,107,61,48,120,52,48,56,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,
115,61,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,
121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,101,109,111,
114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109,
97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,
32,115,105,122,101,61,48,120,50,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,
48,45,52,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,
65,77,32,99,111,110,116,101,110,116,61,73,110,116,101,114,110,97,108,10,32,32,32,32,32,32,109,97,112,32,97,100,
100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,51,48,48,48,45,51,55,102,102,32,115,105,122,101,
61,48,120,56,48,48,10,10,98,111,97,114,100,58,32,83,68,68,49,10,32,32,112,114,111,99,101,115,115,111,114,32,
105,100,101,110,116,105,102,105,101,114,61,83,68,68,49,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,
48,48,45,51,102,44,56,48,45,98,102,58,52,56,48,48,45,52,56,48,102,10,32,32,32,32,109,99,117,10,32,32,
32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,
45,102,102,102,102,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,45,102,102,58,48,48,
48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,
110,116,101,110,116,61,80,114,111,103,114,97,109,10,10,98,111,97,114,100,58,32,83,68,68,49,45,82,65,77,10,32,
32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,
32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,
102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,
55,48,45,55,51,58,48,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,112,114,
111,99,101,115,115,111,114,32,105,100,101,110,116,105,102,105,101,114,61,83,68,68,49,10,32,32,32,32,109,97,112,32,
97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,52,56,48,48,45,52,56,48,102,10,32,32,
32,32,109,99,117,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,
45,98,102,58,56,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,
99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,
101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,10,98,111,97,114,100,58,32,83,80,
67,55,49,49,48,45,82,65,77,10,32,32,112,114,111,99,101,115,115,111,114,32,105,100,101,110,116,105,102,105,101,114,
61,83,80,67,55,49,49,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,
48,45,98,102,58,52,56,48,48,45,52,56,51,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,53,
48,44,53,56,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,109,99,117,10,32,32,32,32,32,32,109,97,112,
10,98,111,97,114,100,58,32,79,66,67,49,45,76,79,82,79,77,45,82,65,77,10,32,32,109,101,109,111,114,121,32,
116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,
32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,
97,115,107,61,48,120,56,48,48,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,
48,45,102,102,58,48,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,99,48,48,48,48,48,10,32,32,32,
32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,
97,109,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,
61,68,97,116,97,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,
116,61,83,97,118,101,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,
48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,10,98,111,97,114,
100,58,32,83,80,67,55,49,49,48,45,82,65,77,45,69,80,83,79,78,82,84,67,10,32,32,112,114,111,99,101,115,
115,111,114,32,105,100,101,110,116,105,102,105,101,114,61,83,80,67,55,49,49,48,10,32,32,32,32,109,97,112,32,97,
100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,52,56,48,48,45,52,56,51,102,10,32,32,32,
32,109,97,112,32,97,100,100,114,101,115,115,61,53,48,44,53,56,58,48,48,48,48,45,102,102,102,102,10,32,32,32,
32,109,99,117,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,
98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,48,48,10,32,32,32,32,32,
32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,32,109,97,115,
107,61,48,120,99,48,48,48,48,48,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,
32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,
112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,68,97,116,97,10,32,32,32,32,109,101,109,111,114,121,32,116,
97,115,107,61,48,120,56,48,48,48,10,32,32,112,114,111,99,101,115,115,111,114,32,105,100,101,110,116,105,102,105,101,
114,61,79,66,67,49,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,
98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,32,32,32,32,109,97,112,
32,97,100,100,114,101,115,115,61,55,48,45,55,49,44,102,48,45,102,49,58,54,48,48,48,45,55,102,102,102,44,101,
48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,32,32,32,32,109,101,109,111,114,121,32,
116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,10,98,111,97,114,100,58,32,83,65,
49,45,82,65,77,10,32,32,112,114,111,99,101,115,115,111,114,32,97,114,99,104,105,116,101,99,116,117,114,101,61,87,
54,53,67,56,49,54,83,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,
45,98,102,58,50,50,48,48,45,50,51,102,102,10,32,32,32,32,109,99,117,10,32,32,32,32,32,32,109,97,112,32,
97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,
115,107,61,48,120,52,48,56,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,
45,102,102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,
82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,101,109,111,114,121,32,116,
121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109,97,112,32,97,
100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,
107,61,48,120,101,48,48,48,10,32,32,114,116,99,32,109,97,110,117,102,97,99,116,117,114,101,114,61,69,112,115,111,
110,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,52,56,
52,48,45,52,56,52,50,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,84,67,32,99,111,110,116,
101,110,116,61,84,105,109,101,32,109,97,110,117,102,97,99,116,117,114,101,114,61,69,112,115,111,110,10,10,98,111,97,
114,100,58,32,83,84,45,76,79,82,79,77,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,
111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,
48,45,49,102,44,56,48,45,57,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,
100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,115,105,122,
101,61,48,120,50,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,52,102,
58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,
111,110,116,101,110,116,61,73,110,116,101,114,110,97,108,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,
115,61,48,48,45,51,102,44,56,48,45,98,102,58,51,48,48,48,45,51,55,102,102,32,115,105,122,101,61,48,120,56,
48,48,10,10,98,111,97,114,100,58,32,83,68,68,49,10,32,32,112,114,111,99,101,115,115,111,114,32,105,100,101,110,
116,105,102,105,101,114,61,83,68,68,49,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,
102,44,56,48,45,98,102,58,52,56,48,48,45,52,56,48,102,10,32,32,32,32,109,99,117,10,32,32,32,32,32,32,
109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,
102,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,45,102,102,58,48,48,48,48,45,102,
102,102,102,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,
116,61,80,114,111,103,114,97,109,10,10,98,111,97,114,100,58,32,83,68,68,49,45,82,65,77,10,32,32,109,101,109,
111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,109,97,
112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,
109,97,115,107,61,48,120,101,48,48,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,
51,58,48,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,112,114,111,99,101,115,
115,111,114,32,105,100,101,110,116,105,102,105,101,114,61,83,68,68,49,10,32,32,32,32,109,97,112,32,97,100,100,114,
101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,52,56,48,48,45,52,56,48,102,10,32,32,32,32,109,99,
117,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,
56,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,45,102,
102,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,
77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,10,98,111,97,114,100,58,32,83,80,67,55,49,49,
48,45,82,65,77,10,32,32,112,114,111,99,101,115,115,111,114,32,105,100,101,110,116,105,102,105,101,114,61,83,80,67,
55,49,49,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,
58,52,56,48,48,45,52,56,51,102,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,53,48,44,53,56,
58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,109,99,117,10,32,32,32,32,32,32,109,97,112,32,97,100,100,
114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,
48,120,56,48,48,48,48,48,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,99,48,45,102,102,
58,48,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,99,48,48,48,48,48,10,32,32,32,32,32,32,109,
101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,80,114,111,103,114,97,109,10,32,
32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,110,116,61,68,97,116,
97,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,65,77,32,99,111,110,116,101,110,116,61,83,97,
118,101,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,
58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,101,48,48,48,10,10,98,111,97,114,100,58,32,83,
80,67,55,49,49,48,45,82,65,77,45,69,80,83,79,78,82,84,67,10,32,32,112,114,111,99,101,115,115,111,114,32,
105,100,101,110,116,105,102,105,101,114,61,83,80,67,55,49,49,48,10,32,32,32,32,109,97,112,32,97,100,100,114,101,
115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,52,56,48,48,45,52,56,51,102,10,32,32,32,32,109,97,112,
32,97,100,100,114,101,115,115,61,53,48,44,53,56,58,48,48,48,48,45,102,102,102,102,10,32,32,32,32,109,99,117,
10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,56,
48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,48,48,10,32,32,32,32,32,32,109,97,112,
32,97,100,100,114,101,115,115,61,99,48,45,102,102,58,48,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,
99,48,48,48,48,48,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,
116,101,110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,
79,77,32,99,111,110,116,101,110,116,61,68,97,116,97,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,
82,65,77,32,99,111,110,116,101,110,116,61,83,97,118,101,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,
115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,54,48,48,48,45,55,102,102,102,32,109,97,115,107,61,48,120,
101,48,48,48,10,32,32,114,116,99,32,109,97,110,117,102,97,99,116,117,114,101,114,61,69,112,115,111,110,10,32,32,
32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,51,102,44,56,48,45,98,102,58,52,56,52,48,45,52,
56,52,50,10,32,32,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,84,67,32,99,111,110,116,101,110,116,61,
84,105,109,101,32,109,97,110,117,102,97,99,116,117,114,101,114,61,69,112,115,111,110,10,10,98,111,97,114,100,58,32,
83,84,45,76,79,82,79,77,10,32,32,109,101,109,111,114,121,32,116,121,112,101,61,82,79,77,32,99,111,110,116,101,
110,116,61,80,114,111,103,114,97,109,10,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,48,48,45,49,102,
44,56,48,45,57,102,58,56,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,115,
108,111,116,32,116,121,112,101,61,83,117,102,97,109,105,84,117,114,98,111,10,32,32,32,32,114,111,109,10,32,32,32,
32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,56,48,48,48,45,
102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,114,97,109,10,32,32,32,32,32,32,109,
97,112,32,97,100,100,114,101,115,115,61,54,48,45,54,102,44,101,48,45,101,102,58,48,48,48,48,45,102,102,102,102,
10,32,32,115,108,111,116,32,116,121,112,101,61,83,117,102,97,109,105,84,117,114,98,111,10,32,32,32,32,114,111,109,
10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,50,48,45,51,102,44,97,48,45,98,102,58,56,
10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,53,102,44,99,48,45,100,102,58,48,
48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,114,97,109,10,32,32,32,
32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,54,48,45,54,102,44,101,48,45,101,102,58,48,48,48,48,45,
102,102,102,102,10,32,32,115,108,111,116,32,116,121,112,101,61,83,117,102,97,109,105,84,117,114,98,111,10,32,32,32,
32,114,111,109,10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,52,48,45,53,102,44,99,48,45,
100,102,58,48,48,48,48,45,102,102,102,102,32,109,97,115,107,61,48,120,56,48,48,48,10,32,32,32,32,114,97,109,
10,32,32,32,32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,
48,48,48,45,102,102,102,102,10,10,
32,32,32,109,97,112,32,97,100,100,114,101,115,115,61,55,48,45,55,100,44,102,48,45,102,102,58,48,48,48,48,45,
102,102,102,102,10,10,
};
const nall::vector<uint8_t> IPLROM = { //size: 64
205,239,189,232,0,198,29,208,252,143,170,244,143,187,245,120,204,244,208,251,47,25,235,244,208,252,126,244,208,11,228,245,

View File

@ -18,7 +18,7 @@ CheatDatabase::CheatDatabase() {
}
auto CheatDatabase::findCheats() -> void {
auto sha256 = emulator->sha256();
auto sha256 = emulator->hashes()[0];
auto document = BML::unserialize(string::read(locate("cheats.bml")));
for(auto game : document.find("cartridge")) {
@ -232,11 +232,11 @@ auto CheatEditor::saveCheats() -> void {
}
auto CheatEditor::synchronizeCodes() -> void {
string_vector codes;
vector<string> codes;
if(enableCheats.checked()) {
for(auto& cheat : cheats) {
if(cheat.enable) codes.append(cheat.code);
}
}
emulator->cheatSet(codes);
emulator->cheats(codes);
}

View File

@ -14,7 +14,7 @@ auto ManifestViewer::loadManifest() -> void {
return;
}
manifestView.setText(emulator->manifest());
manifestView.setText(emulator->manifests().merge("\n"));
verifiedIcon.setIcon(program->verified() ? Icon::Emblem::Program : Icon::Emblem::Binary);
verifiedLabel.setText(program->verified() ? "Verified" : "Unverified");
}

View File

@ -1,15 +1,4 @@
name := higan
flags += -DSFC_SUPERGAMEBOY
include fc/GNUmakefile
include sfc/GNUmakefile
#include ms/GNUmakefile
include md/GNUmakefile
#include pce/GNUmakefile
include gb/GNUmakefile
include gba/GNUmakefile
#include ws/GNUmakefile
include processor/GNUmakefile
hiro.path := ../hiro
hiro.resource := $(ui)/resource/higan.rc

View File

@ -13,9 +13,9 @@ auto locate(string name) -> string {
}
#include <nall/main.hpp>
auto nall::main(string_vector args) -> void {
auto nall::main(vector<string> arguments) -> void {
Application::setName("higan");
Application::setScreenSaver(false);
new Program(args);
new Program(arguments);
Application::run();
}

View File

@ -286,7 +286,7 @@ auto Presentation::resizeViewport(bool resizeWindow) -> void {
double emulatorHeight = 240;
double aspectCorrection = 1.0;
if(emulator) {
auto display = emulator->display();
auto display = emulator->displays()[0];
emulatorWidth = display.width;
emulatorHeight = display.height;
aspectCorrection = display.aspectCorrection;

View File

@ -33,7 +33,7 @@ auto Program::load(Emulator::Interface& interface) -> void {
updateAudioEffects();
presentation->resizeViewport();
presentation->setTitle(emulator->title());
presentation->setTitle(emulator->titles().merge(" + "));
presentation->systemMenu.setText(information.name).setVisible(true);
presentation->toolsMenu.setVisible(true);
toolsManager->cheatEditor.loadCheats();

View File

@ -23,7 +23,7 @@ auto Program::open(uint id, string name, vfs::file::mode mode, bool required) ->
return {};
}
auto Program::load(uint id, string name, string type, string_vector options) -> Emulator::Platform::Load {
auto Program::load(uint id, string name, string type, vector<string> options) -> Emulator::Platform::Load {
string location, option;
if(gameQueue) {
auto entry = gameQueue.takeLeft().split("|", 1L);
@ -50,13 +50,13 @@ auto Program::load(uint id, string name, string type, string_vector options) ->
return {pathID, option};
}
auto Program::videoRefresh(const uint32* data, uint pitch, uint width, uint height) -> void {
auto Program::videoRefresh(uint displayID, const uint32* data, uint pitch, uint width, uint height) -> void {
uint32_t* output;
uint length;
pitch >>= 2;
auto display = emulator->display();
auto display = emulator->displays()[displayID];
if(display.type == Emulator::Interface::Display::Type::CRT) {
uint overscanHorizontal = settings["Video/Overscan/Horizontal"].natural();
uint overscanVertical = settings["Video/Overscan/Vertical"].natural();

View File

@ -1,35 +1,62 @@
#include "../higan.hpp"
#include <fc/interface/interface.hpp>
#include <sfc/interface/interface.hpp>
//#include <ms/interface/interface.hpp>
#include <ms/interface/interface.hpp>
#include <md/interface/interface.hpp>
//#include <pce/interface/interface.hpp>
#include <pce/interface/interface.hpp>
#include <gb/interface/interface.hpp>
#include <gba/interface/interface.hpp>
//#include <ws/interface/interface.hpp>
#include <ws/interface/interface.hpp>
#include "platform.cpp"
#include "game.cpp"
#include "state.cpp"
#include "utility.cpp"
unique_pointer<Program> program;
Program::Program(string_vector args) {
Program::Program(vector<string> arguments) {
program = this;
Emulator::platform = this;
#ifdef CORE_FC
emulators.append(new Famicom::Interface);
#endif
#ifdef CORE_SFC
emulators.append(new SuperFamicom::Interface);
// emulators.append(new MasterSystem::MasterSystemInterface);
#endif
#ifdef CORE_MS
emulators.append(new MasterSystem::MasterSystemInterface);
#endif
#ifdef CORE_MD
emulators.append(new MegaDrive::Interface);
// emulators.append(new PCEngine::PCEngineInterface);
// emulators.append(new PCEngine::SuperGrafxInterface);
#endif
#ifdef CORE_PCE
emulators.append(new PCEngine::PCEngineInterface);
#endif
#ifdef CORE_PCE
emulators.append(new PCEngine::SuperGrafxInterface);
#endif
#ifdef CORE_GB
emulators.append(new GameBoy::GameBoyInterface);
#endif
#ifdef CORE_GB
emulators.append(new GameBoy::GameBoyColorInterface);
#endif
#ifdef CORE_GBA
emulators.append(new GameBoyAdvance::Interface);
// emulators.append(new MasterSystem::GameGearInterface);
// emulators.append(new WonderSwan::WonderSwanInterface);
// emulators.append(new WonderSwan::WonderSwanColorInterface);
// emulators.append(new WonderSwan::PocketChallengeV2Interface);
#endif
#ifdef CORE_MS
emulators.append(new MasterSystem::GameGearInterface);
#endif
#ifdef CORE_WS
emulators.append(new WonderSwan::WonderSwanInterface);
#endif
#ifdef CORE_WS
emulators.append(new WonderSwan::WonderSwanColorInterface);
#endif
#ifdef CORE_WS
emulators.append(new WonderSwan::PocketChallengeV2Interface);
#endif
new Presentation;
presentation->setVisible();
@ -62,8 +89,8 @@ Program::Program(string_vector args) {
updateAudioDriver();
updateAudioEffects();
args.takeLeft(); //ignore program location in argument parsing
for(auto& argument : args) {
arguments.takeLeft(); //ignore program location in argument parsing
for(auto& argument : arguments) {
if(argument == "--fullscreen") {
presentation->toggleFullScreen();
} else if(directory::exists(argument.split("|", 1L).right())) {
@ -113,5 +140,5 @@ auto Program::quit() -> void {
video.reset();
audio.reset();
input.reset();
Application::quit();
Application::kill();
}

View File

@ -1,14 +1,14 @@
struct Program : Emulator::Platform {
//program.cpp
Program(string_vector args);
Program(vector<string> arguments);
auto main() -> void;
auto quit() -> void;
//platform.cpp
auto path(uint id) -> string override;
auto open(uint id, string name, vfs::file::mode mode, bool required) -> vfs::shared::file override;
auto load(uint id, string name, string type, string_vector options = {}) -> Emulator::Platform::Load override;
auto videoRefresh(const uint32* data, uint pitch, uint width, uint height) -> void override;
auto load(uint id, string name, string type, vector<string> options = {}) -> Emulator::Platform::Load override;
auto videoRefresh(uint display, const uint32* data, uint pitch, uint width, uint height) -> void override;
auto audioSample(const double* samples, uint channels) -> void override;
auto inputPoll(uint port, uint device, uint input) -> int16 override;
auto inputRumble(uint port, uint device, uint input, bool enable) -> void override;

View File

@ -17,7 +17,7 @@ CheatDatabase::CheatDatabase() {
auto CheatDatabase::findCodes() -> void {
if(!emulator) return;
auto sha256 = emulator->sha256();
auto sha256 = emulator->hashes().left();
auto contents = string::read(locate("cheats.bml"));
auto document = BML::unserialize(contents);

View File

@ -100,13 +100,13 @@ auto CheatEditor::doErase() -> void {
auto CheatEditor::synchronizeCodes() -> void {
if(!emulator) return;
string_vector codes;
vector<string> codes;
for(auto& cheat : cheats) {
if(!cheat.enabled || !cheat.code) continue;
codes.append(cheat.code);
}
emulator->cheatSet(codes);
emulator->cheats(codes);
}
//returns true if code was added
@ -136,7 +136,7 @@ auto CheatEditor::loadCheats() -> void {
auto CheatEditor::saveCheats() -> void {
if(!emulator) return;
string document = {"cartridge sha256:", emulator->sha256(), "\n"};
string document = {"cartridge sha256:", emulator->hashes().left(), "\n"};
uint count = 0;
for(auto& cheat : cheats) {
if(!cheat.code && !cheat.description) continue;

Some files were not shown because too many files have changed in this diff Show More