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