mirror of https://github.com/bsnes-emu/bsnes.git
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:
parent
f1a4576ac4
commit
22bd4b9277
|
@ -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
|
||||
|
|
|
@ -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("+")) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 $
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 $
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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 $
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -101,6 +101,8 @@ auto PPU::readOAM(uint mode, uint32 addr) -> uint32 {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
unreachable;
|
||||
}
|
||||
|
||||
auto PPU::writeOAM(uint mode, uint32 addr, uint32 word) -> void {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -5,40 +5,147 @@ 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;
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
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(), memory.name(), File::Read, File::Required)) {
|
||||
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;
|
||||
|
||||
//todo: handle mode, offset in Emulator::Game::Memory
|
||||
if(auto memory = document["game/board/memory(type=RAM,content=Save)"]) {
|
||||
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;
|
||||
|
@ -48,38 +155,46 @@ auto Cartridge::load() -> bool {
|
|||
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)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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)) {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,42 +1,70 @@
|
|||
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;
|
||||
};
|
||||
|
||||
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;
|
||||
uint6 bank[8];
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 $
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -25,6 +25,8 @@ auto VDC::read(uint2 addr) -> uint8 {
|
|||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
auto VDC::write(uint2 addr, uint8 data) -> void {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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, ")"}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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")) {
|
||||
|
|
|
@ -130,6 +130,8 @@ auto Justifier::data() -> uint2 {
|
|||
case 30: return 0;
|
||||
case 31: return 0;
|
||||
}
|
||||
|
||||
unreachable;
|
||||
}
|
||||
|
||||
auto Justifier::latch(bool data) -> void {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace SuperFamicom {
|
|||
|
||||
ICD icd;
|
||||
|
||||
#if defined(SFC_SUPERGAMEBOY)
|
||||
#if defined(CORE_GB)
|
||||
|
||||
#include "platform.cpp"
|
||||
#include "interface.cpp"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#if defined(SFC_SUPERGAMEBOY)
|
||||
#if defined(CORE_GB)
|
||||
|
||||
struct ICD : Emulator::Platform, GameBoy::SuperGameBoyInterface, Thread {
|
||||
shared_pointer<Emulator::Stream> stream;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -253,6 +253,8 @@ auto SDD1::Decompressor::OL::decompress() -> uint8 {
|
|||
}
|
||||
return r1;
|
||||
}
|
||||
|
||||
return 0; //unreachable?
|
||||
}
|
||||
|
||||
//core
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 $
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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=")) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue