From bbc33fe05f1d9de7fd85a0577ab974b1bc31231c Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Mon, 21 Jan 2013 23:27:15 +1100 Subject: [PATCH] Update to higan v092r01, ananke v02r01 and purify v03r01 releases. byuu says: higan changelog: - compiler is set to g++-4.7, subst(cc,++) rule is gone, C files compile with $(compiler) -x c - make throws an error when you specify an invalid profile or compile on an unsupported platform (instead of hanging forever) - added unverified.png to resources (causes too big of a speed hit to actually check for folder/unverified file ... so disabled for now) - fixed default browser paths for Game Boy, Sufami Turbo and BS-X Satellaview (have to delete paths.cfg to see this) - browser home button seeks to configpath()/higan/library.cfg - settings->driver is now settings->advanced, and it adds game library path setting and profile information - emulation cores now load manifest files internally, manifest.bml is not required for a game folder to be recognized by higan as such - BS-X Satellaview and Sufami Turbo slot cartridge handling moved out of sfc/chip and into sfc/slot - Video::StartFullScreen only sets fullscreen when a game is specified on the command-line purify and ananke changelog: - library output path shown in purify window - added button to change library path - squelch firmware warning windows to prevent multi-threading crash, but only via purify (they show up in higan still) --- ananke/ananke.cpp | 9 ++ ananke/bsx-satellaview.cpp | 7 +- ananke/famicom.cpp | 5 +- ananke/game-boy-advance.cpp | 5 +- ananke/game-boy.cpp | 6 +- ananke/nall/Makefile | 10 +- ananke/nall/file.hpp | 8 ++ ananke/nall/stream/stream.hpp | 9 ++ ananke/nall/string/base.hpp | 1 + ananke/nall/string/platform.hpp | 22 +++- ananke/nall/thread.hpp | 36 +++++ ananke/sufami-turbo.cpp | 7 +- ananke/super-famicom.cpp | 12 +- higan/Makefile | 6 +- higan/emulator/emulator.hpp | 2 +- higan/emulator/interface.hpp | 4 +- higan/fc/cartridge/cartridge.cpp | 6 +- higan/fc/cartridge/cartridge.hpp | 2 +- higan/fc/interface/interface.cpp | 9 +- higan/fc/interface/interface.hpp | 5 +- higan/gb/cartridge/cartridge.cpp | 12 +- higan/gb/cartridge/cartridge.hpp | 2 +- higan/gb/interface/interface.cpp | 13 +- higan/gb/interface/interface.hpp | 8 +- higan/gba/cartridge/cartridge.cpp | 7 +- higan/gba/cartridge/cartridge.hpp | 2 +- higan/gba/interface/interface.cpp | 9 +- higan/gba/interface/interface.hpp | 6 +- higan/nall/Makefile | 15 ++- higan/nall/file.hpp | 8 ++ higan/nall/nall.hpp | 1 + higan/nall/property.hpp | 12 +- higan/nall/stream/stream.hpp | 9 ++ higan/nall/string.hpp | 1 + higan/nall/string/base.hpp | 13 +- higan/nall/string/core.hpp | 17 ++- higan/nall/string/format.hpp | 73 +++++++++++ higan/nall/string/platform.hpp | 22 +++- higan/nall/string/utility.hpp | 44 ------- higan/nall/string/wrapper.hpp | 5 + higan/nall/thread.hpp | 123 ++++++++++++++++++ higan/phoenix/Makefile | 5 - higan/ruby/Makefile | 5 - higan/sfc/Makefile | 9 +- higan/sfc/cartridge/cartridge.cpp | 64 +++++---- higan/sfc/cartridge/cartridge.hpp | 22 +++- higan/sfc/cartridge/markup.cpp | 8 +- higan/sfc/chip/bsx/bsx.cpp | 1 - higan/sfc/chip/bsx/bsx.hpp | 1 - higan/sfc/chip/bsx/cartridge/cartridge.cpp | 2 +- higan/sfc/chip/chip.hpp | 1 - higan/sfc/chip/msu1/msu1.cpp | 4 +- higan/sfc/chip/sufamiturbo/serialization.cpp | 8 -- higan/sfc/chip/sufamiturbo/sufamiturbo.cpp | 19 --- higan/sfc/chip/sufamiturbo/sufamiturbo.hpp | 12 -- higan/sfc/interface/interface.cpp | 56 ++++---- higan/sfc/interface/interface.hpp | 20 ++- higan/sfc/sfc.hpp | 1 + .../satellaview/satellaview.cpp} | 25 ++-- .../satellaview/satellaview.hpp} | 4 +- higan/sfc/slot/slot.hpp | 2 + higan/sfc/slot/sufamiturbo/serialization.cpp | 7 + higan/sfc/slot/sufamiturbo/sufamiturbo.cpp | 18 +++ higan/sfc/slot/sufamiturbo/sufamiturbo.hpp | 11 ++ higan/sfc/system/serialization.cpp | 2 +- higan/sfc/system/system.cpp | 14 +- higan/target-ethos/ethos.cpp | 4 +- higan/target-ethos/general/browser.cpp | 12 +- higan/target-ethos/resource/resource.bml | 1 + higan/target-ethos/resource/resource.cpp | 56 ++++++++ higan/target-ethos/resource/resource.hpp | 1 + higan/target-ethos/resource/unverified.png | Bin 0 -> 1675 bytes higan/target-ethos/settings/advanced.cpp | 81 ++++++++++++ higan/target-ethos/settings/advanced.hpp | 23 ++++ higan/target-ethos/settings/driver.cpp | 42 ------ higan/target-ethos/settings/driver.hpp | 14 -- higan/target-ethos/settings/settings.cpp | 10 +- higan/target-ethos/settings/settings.hpp | 2 +- higan/target-ethos/utility/utility.cpp | 5 +- purify/nall/Makefile | 10 +- purify/nall/file.hpp | 8 ++ purify/nall/stream/stream.hpp | 9 ++ purify/nall/string/base.hpp | 1 + purify/nall/string/platform.hpp | 22 +++- purify/nall/thread.hpp | 36 +++++ purify/purify.cpp | 40 +++++- purify/resource/resource.bml | 1 + purify/resource/resource.cpp | 56 ++++++++ purify/resource/resource.hpp | 1 + purify/resource/unverified.png | Bin 0 -> 1675 bytes 90 files changed, 962 insertions(+), 367 deletions(-) create mode 100644 higan/nall/string/format.hpp create mode 100644 higan/nall/thread.hpp delete mode 100755 higan/sfc/chip/sufamiturbo/serialization.cpp delete mode 100755 higan/sfc/chip/sufamiturbo/sufamiturbo.cpp delete mode 100755 higan/sfc/chip/sufamiturbo/sufamiturbo.hpp rename higan/sfc/{chip/bsx/flash/flash.cpp => slot/satellaview/satellaview.cpp} (82%) mode change 100755 => 100644 rename higan/sfc/{chip/bsx/flash/flash.hpp => slot/satellaview/satellaview.hpp} (81%) mode change 100755 => 100644 create mode 100644 higan/sfc/slot/slot.hpp create mode 100644 higan/sfc/slot/sufamiturbo/serialization.cpp create mode 100644 higan/sfc/slot/sufamiturbo/sufamiturbo.cpp create mode 100644 higan/sfc/slot/sufamiturbo/sufamiturbo.hpp create mode 100644 higan/target-ethos/resource/unverified.png create mode 100644 higan/target-ethos/settings/advanced.cpp create mode 100644 higan/target-ethos/settings/advanced.hpp delete mode 100755 higan/target-ethos/settings/driver.cpp delete mode 100755 higan/target-ethos/settings/driver.hpp create mode 100644 purify/resource/unverified.png diff --git a/ananke/ananke.cpp b/ananke/ananke.cpp index 75a1f4f6..326e8b0c 100644 --- a/ananke/ananke.cpp +++ b/ananke/ananke.cpp @@ -17,6 +17,9 @@ namespace Database { struct Ananke { #include "configuration.cpp" + string libraryPath; + + Ananke(); struct Information { string path; //path to selected file @@ -89,6 +92,12 @@ struct Ananke { FileDialog *fileDialog = nullptr; +Ananke::Ananke() { + libraryPath = string::read({configpath(), "higan/library.cfg"}).strip(); + if(libraryPath.empty()) libraryPath = {userpath(), "Emulation/"}; + if(libraryPath.endswith("/") == false) libraryPath.append("/"); +} + bool Ananke::supported(const string &filename) { string extension = nall::extension(filename); diff --git a/ananke/bsx-satellaview.cpp b/ananke/bsx-satellaview.cpp index 8e37925f..cee3a3f4 100644 --- a/ananke/bsx-satellaview.cpp +++ b/ananke/bsx-satellaview.cpp @@ -1,6 +1,6 @@ string Ananke::createBsxSatellaviewDatabase(vector &buffer, Markup::Node &document, const string &manifest) { string pathname = { - userpath(), "Emulation/BS-X Satellaview/", + libraryPath, "BS-X Satellaview/", document["release/information/name"].text(), " (", document["release/information/region"].text(), ")", " (", document["release/information/revision"].text(), ")", @@ -22,11 +22,12 @@ string Ananke::createBsxSatellaviewDatabase(vector &buffer, Markup::Nod string Ananke::createBsxSatellaviewHeuristic(vector &buffer) { string pathname = { - userpath(), "Emulation/BS-X Satellaview/", + libraryPath, "BS-X Satellaview/", nall::basename(information.name), - " (!).bs/" + ".bs/" }; directory::create(pathname); + file::create({pathname, "unverified"}); file::write({pathname, "manifest.bml"}, { "cartridge\n" diff --git a/ananke/famicom.cpp b/ananke/famicom.cpp index 6bcd6f20..0ab66577 100644 --- a/ananke/famicom.cpp +++ b/ananke/famicom.cpp @@ -8,11 +8,12 @@ void Ananke::copyFamicomSaves(const string &pathname) { string Ananke::createFamicomHeuristic(vector &buffer) { string pathname = { - userpath(), "Emulation/Famicom/", + libraryPath, "Famicom/", nall::basename(information.name), - " (!).fc/" + ".fc/" }; directory::create(pathname); + file::create({pathname, "unverified"}); FamicomCartridge info(buffer.data(), buffer.size()); string markup = info.markup(); diff --git a/ananke/game-boy-advance.cpp b/ananke/game-boy-advance.cpp index b78112d4..7d1da2e4 100644 --- a/ananke/game-boy-advance.cpp +++ b/ananke/game-boy-advance.cpp @@ -14,11 +14,12 @@ void Ananke::copyGameBoyAdvanceSaves(const string &pathname) { string Ananke::createGameBoyAdvanceHeuristic(vector &buffer) { string pathname = { - userpath(), "Emulation/Game Boy Advance/", + libraryPath, "Game Boy Advance/", nall::basename(information.name), - " (!).gba/" + ".gba/" }; directory::create(pathname); + file::create({pathname, "unverified"}); GameBoyAdvanceCartridge info(buffer.data(), buffer.size()); string markup = info.markup; diff --git a/ananke/game-boy.cpp b/ananke/game-boy.cpp index c52d9107..639b72d2 100644 --- a/ananke/game-boy.cpp +++ b/ananke/game-boy.cpp @@ -16,12 +16,12 @@ string Ananke::createGameBoyHeuristic(vector &buffer) { GameBoyCartridge info(buffer.data(), buffer.size()); string pathname = { - userpath(), - "Emulation/Game Boy", (info.info.cgb ? " Color" : ""), "/", + libraryPath, "Game Boy", (info.info.cgb ? " Color" : ""), "/", nall::basename(information.name), - " (!).", (info.info.cgb ? "gbc" : "gb"), "/" + ".", (info.info.cgb ? "gbc" : "gb"), "/" }; directory::create(pathname); + file::create({pathname, "unverified"}); string markup = info.markup; markup.append("\ninformation\n title: ", nall::basename(information.name), "\n"); diff --git a/ananke/nall/Makefile b/ananke/nall/Makefile index 9929d101..f422f49d 100644 --- a/ananke/nall/Makefile +++ b/ananke/nall/Makefile @@ -36,16 +36,16 @@ endif ifeq ($(compiler),) ifeq ($(platform),win) - compiler := gcc + compiler := g++ else ifeq ($(platform),osx) - compiler := gcc-mp-4.7 + compiler := g++-mp-4.7 else - compiler := gcc-4.7 + compiler := g++-4.7 endif endif -c := $(compiler) -std=gnu99 -cpp := $(subst cc,++,$(compiler)) -std=gnu++11 +c := $(compiler) -x c -std=gnu99 +cpp := $(compiler) -std=gnu++11 ifeq ($(arch),x86) c := $(c) -m32 diff --git a/ananke/nall/file.hpp b/ananke/nall/file.hpp index be9fc086..80b918a8 100644 --- a/ananke/nall/file.hpp +++ b/ananke/nall/file.hpp @@ -98,6 +98,14 @@ namespace nall { return true; } + static bool create(const string &filename) { + //create an empty file (will replace existing files) + file fp; + if(fp.open(filename, mode::write) == false) return false; + fp.close(); + return true; + } + static string sha256(const string &filename) { auto buffer = read(filename); return nall::sha256(buffer.data(), buffer.size()); diff --git a/ananke/nall/stream/stream.hpp b/ananke/nall/stream/stream.hpp index 9d937729..043eecba 100644 --- a/ananke/nall/stream/stream.hpp +++ b/ananke/nall/stream/stream.hpp @@ -48,6 +48,15 @@ struct stream { while(length--) *data++ = read(); } + string text() const { + string buffer; + buffer.resize(size() + 1); + buffer[size()] = 0; + seek(0); + read((uint8_t*)buffer(), size()); + return buffer; + } + void writel(uintmax_t data, unsigned length = 1) const { while(length--) { write(data); diff --git a/ananke/nall/string/base.hpp b/ananke/nall/string/base.hpp index abf21735..d5f85ca4 100644 --- a/ananke/nall/string/base.hpp +++ b/ananke/nall/string/base.hpp @@ -23,6 +23,7 @@ namespace nall { struct string { inline static string read(const string &filename); + inline static string date(); inline static string time(); inline static string datetime(); diff --git a/ananke/nall/string/platform.hpp b/ananke/nall/string/platform.hpp index 5c44a313..90b6d6b8 100644 --- a/ananke/nall/string/platform.hpp +++ b/ananke/nall/string/platform.hpp @@ -33,11 +33,13 @@ string realpath(const string &name) { return result; } +// /home/username/ +// c:/users/username/ string userpath() { string result; #ifdef _WIN32 wchar_t path[PATH_MAX] = L""; - SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, path); + SHGetFolderPathW(0, CSIDL_PROFILE | CSIDL_FLAG_CREATE, 0, 0, path); result = (const char*)utf8_t(path); result.transform("\\", "/"); #else @@ -51,20 +53,30 @@ string userpath() { return result; } +// /home/username/.config/ +// c:/users/username/appdata/roaming/ string configpath() { + string result; #ifdef _WIN32 - return userpath(); + wchar_t path[PATH_MAX] = L""; + SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, path); + result = (const char*)utf8_t(path); + result.transform("\\", "/"); #else - return {userpath(), ".config/"}; + result = {userpath(), ".config/"}; #endif + if(result.empty()) result = "."; + if(result.endswith("/") == false) result.append("/"); + return result; } string temppath() { #ifdef _WIN32 wchar_t path[PATH_MAX] = L""; GetTempPathW(PATH_MAX, path); -//path.transform("\\", "/"); - return (const char*)utf8_t(path); + string result = (const char*)utf8_t(path); + result.transform("\\", "/"); + return result; #else return "/tmp/"; #endif diff --git a/ananke/nall/thread.hpp b/ananke/nall/thread.hpp index 3368d15d..de894f2d 100644 --- a/ananke/nall/thread.hpp +++ b/ananke/nall/thread.hpp @@ -13,6 +13,7 @@ namespace nall { struct thread { thread(function entryPoint) : entryPoint(entryPoint), completed(false), dead(false) { + initialize(); pthread_create(&pthread, NULL, thread_entry_point, (void*)this); } @@ -30,11 +31,28 @@ namespace nall { pthread_join(pthread, NULL); } + static bool primary() { + initialize(); + return pthread_equal(primaryThread(), pthread_self()); + } + private: pthread_t pthread; function entryPoint; volatile bool completed, dead; friend void* thread_entry_point(void*); + + static void initialize() { + static bool initialized = false; + if(initialized) return; + initialized = true; + primaryThread() = pthread_self(); + } + + static pthread_t& primaryThread() { + static pthread_t thread; + return thread; + } }; void* thread_entry_point(void *parameter) { @@ -50,6 +68,7 @@ namespace nall { struct thread { thread(function entryPoint) : entryPoint(entryPoint), completed(false), dead(false) { + initialize(); hthread = CreateThread(NULL, 0, thread_entry_point, (void*)this, 0, NULL); } @@ -68,11 +87,28 @@ namespace nall { CloseHandle(hthread); } + static bool primary() { + initialize(); + return primaryThread() == GetCurrentThreadId(); + } + private: HANDLE hthread; function entryPoint; volatile bool completed, dead; friend DWORD WINAPI thread_entry_point(LPVOID); + + static void initialize() { + static bool initialized = false; + if(initialized) return; + initialized = true; + primaryThread() = GetCurrentThreadId(); + } + + static DWORD& primaryThread() { + static DWORD thread; + return thread; + } }; inline DWORD WINAPI thread_entry_point(LPVOID parameter) { diff --git a/ananke/sufami-turbo.cpp b/ananke/sufami-turbo.cpp index 44f9f48b..6440bf7c 100644 --- a/ananke/sufami-turbo.cpp +++ b/ananke/sufami-turbo.cpp @@ -8,7 +8,7 @@ void Ananke::copySufamiTurboSaves(const string &pathname) { string Ananke::createSufamiTurboDatabase(vector &buffer, Markup::Node &document, const string &manifest) { string pathname = { - userpath(), "Emulation/Sufami Turbo/", + libraryPath, "Sufami Turbo/", document["release/information/name"].text(), " (", document["release/information/region"].text(), ")", " (", document["release/information/revision"].text(), ")", @@ -31,11 +31,12 @@ string Ananke::createSufamiTurboDatabase(vector &buffer, Markup::Node & string Ananke::createSufamiTurboHeuristic(vector &buffer) { string pathname = { - userpath(), "Emulation/Sufami Turbo/", + libraryPath, "Sufami Turbo/", nall::basename(information.name), - " (!).st/" + ".st/" }; directory::create(pathname); + file::create({pathname, "unverified"}); file::write({pathname, "manifest.bml"}, { "cartridge\n", diff --git a/ananke/super-famicom.cpp b/ananke/super-famicom.cpp index e0c8db35..4b8937aa 100644 --- a/ananke/super-famicom.cpp +++ b/ananke/super-famicom.cpp @@ -14,7 +14,7 @@ void Ananke::copySuperFamicomSaves(const string &pathname) { string Ananke::createSuperFamicomDatabase(vector &buffer, Markup::Node &document, const string &manifest) { string pathname = { - userpath(), "Emulation/Super Famicom/", + libraryPath, "Super Famicom/", document["release/information/name"].text(), " (", document["release/information/region"].text(), ")", " (", document["release/information/revision"].text(), ")", @@ -45,11 +45,12 @@ string Ananke::createSuperFamicomDatabase(vector &buffer, Markup::Node string Ananke::createSuperFamicomHeuristic(vector &buffer) { string pathname = { - userpath(), "Emulation/Super Famicom/", + libraryPath, "Super Famicom/", nall::basename(information.name), - " (!).sfc/" + ".sfc/" }; directory::create(pathname); + file::create({pathname, "unverified"}); if((buffer.size() & 0x7fff) == 512) buffer.remove(0, 512); //strip copier header, if present @@ -88,8 +89,9 @@ void Ananke::createSuperFamicomHeuristicFirmware(vector &buffer, const auto buffer = file::read({information.path, name}); //try and read from the containing directory if(buffer.size() == 0) buffer = extractFile(name); //try and read from the containing archive, if one exists if(buffer.size() == 0) { - MessageWindow::critical(Window::none(), { - "Error: required firmware ", name, " not found. Game will not be playable!\n\n", + if(thread::primary()) MessageWindow::critical(Window::none(), { + "Error: ", information.name, "\n\n", + "Required firmware ", name, " not found. Game will not be playable!\n\n", "You must obtain this file, and place it in the same folder as this game." }); return; diff --git a/higan/Makefile b/higan/Makefile index 73b1a562..4e189d88 100755 --- a/higan/Makefile +++ b/higan/Makefile @@ -10,12 +10,10 @@ profile := accuracy target := ethos # options += debugger -# arch := win32 +# arch := x86 # console := true # compiler -c := $(compiler) -std=gnu99 -cpp := $(subst cc,++,$(compiler)) -std=gnu++0x flags := -I. -O3 -fomit-frame-pointer link := -s objects := libco @@ -48,7 +46,7 @@ else ifeq ($(platform),win) link += -mthreads -luuid -lkernel32 -luser32 -lgdi32 -lcomctl32 -lcomdlg32 -lshell32 -lole32 -lws2_32 link += -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc else - unknown_platform: help; + $(error unsupported platform.) endif ui := target-$(target) diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index 644e6571..00cbf2c3 100755 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -3,7 +3,7 @@ namespace Emulator { static const char Name[] = "higan"; - static const char Version[] = "092"; + static const char Version[] = "092.01"; static const char Author[] = "byuu"; static const char License[] = "GPLv3"; } diff --git a/higan/emulator/interface.hpp b/higan/emulator/interface.hpp index 1d5e7ff3..afc93d89 100755 --- a/higan/emulator/interface.hpp +++ b/higan/emulator/interface.hpp @@ -83,9 +83,9 @@ struct Interface { virtual bool loaded() { return false; } virtual string sha256() { return ""; } virtual unsigned group(unsigned id) = 0; - virtual void load(unsigned id, const string &manifest) {} + virtual void load(unsigned id) {} virtual void save() {} - virtual void load(unsigned id, const stream &memory, const string &markup = "") {} + virtual void load(unsigned id, const stream &memory) {} virtual void save(unsigned id, const stream &memory) {} virtual void unload() {} diff --git a/higan/fc/cartridge/cartridge.cpp b/higan/fc/cartridge/cartridge.cpp index be2a45e1..6c980fe2 100755 --- a/higan/fc/cartridge/cartridge.cpp +++ b/higan/fc/cartridge/cartridge.cpp @@ -18,10 +18,10 @@ void Cartridge::main() { board->main(); } -void Cartridge::load(const string &manifest) { - information.markup = manifest; +void Cartridge::load() { + interface->loadRequest(ID::Manifest, "manifest.bml"); - Board::load(manifest); //this call will set Cartridge::board if successful + Board::load(information.markup); //this call will set Cartridge::board if successful if(board == nullptr) return; sha256_ctx sha; diff --git a/higan/fc/cartridge/cartridge.hpp b/higan/fc/cartridge/cartridge.hpp index ff933533..4c0c50cd 100755 --- a/higan/fc/cartridge/cartridge.hpp +++ b/higan/fc/cartridge/cartridge.hpp @@ -5,7 +5,7 @@ struct Cartridge : Thread, property { static void Main(); void main(); - void load(const string &manifest); + void load(); void unload(); void power(); diff --git a/higan/fc/interface/interface.cpp b/higan/fc/interface/interface.cpp index 52d32633..00dd7315 100755 --- a/higan/fc/interface/interface.cpp +++ b/higan/fc/interface/interface.cpp @@ -26,6 +26,7 @@ string Interface::sha256() { unsigned Interface::group(unsigned id) { switch(id) { + case ID::Manifest: case ID::ProgramROM: case ID::ProgramRAM: case ID::CharacterROM: @@ -36,8 +37,8 @@ unsigned Interface::group(unsigned id) { throw; } -void Interface::load(unsigned id, const string &manifest) { - cartridge.load(manifest); +void Interface::load(unsigned id) { + cartridge.load(); } void Interface::save() { @@ -46,7 +47,9 @@ void Interface::save() { } } -void Interface::load(unsigned id, const stream &stream, const string &manifest) { +void Interface::load(unsigned id, const stream &stream) { + if(id == ID::Manifest) cartridge.information.markup = stream.text(); + if(id == ID::ProgramROM) { stream.read(cartridge.board->prgrom.data, min(cartridge.board->prgrom.size, stream.size())); } diff --git a/higan/fc/interface/interface.hpp b/higan/fc/interface/interface.hpp index 58a0fc10..1aac639e 100755 --- a/higan/fc/interface/interface.hpp +++ b/higan/fc/interface/interface.hpp @@ -9,6 +9,7 @@ struct ID { }; enum : unsigned { + Manifest, ProgramROM, ProgramRAM, CharacterROM, @@ -29,9 +30,9 @@ struct Interface : Emulator::Interface { bool loaded(); string sha256(); unsigned group(unsigned id); - void load(unsigned id, const string &manifest); + void load(unsigned id); void save(); - void load(unsigned id, const stream &stream, const string &manifest = ""); + void load(unsigned id, const stream &stream); void save(unsigned id, const stream &stream); void unload(); diff --git a/higan/gb/cartridge/cartridge.cpp b/higan/gb/cartridge/cartridge.cpp index f2d31fac..342ba121 100755 --- a/higan/gb/cartridge/cartridge.cpp +++ b/higan/gb/cartridge/cartridge.cpp @@ -18,8 +18,12 @@ string Cartridge::title() { return information.title; } -void Cartridge::load(System::Revision revision, const string &manifest) { - information.markup = manifest; +void Cartridge::load(System::Revision revision) { + system.load(revision); + if(revision != System::Revision::SuperGameBoy) { + interface->loadRequest(ID::Manifest, "manifest.bml"); + } + information.mapper = Mapper::Unknown; information.ram = false; information.battery = false; @@ -29,7 +33,7 @@ void Cartridge::load(System::Revision revision, const string &manifest) { information.romsize = 0; information.ramsize = 0; - auto document = Markup::Document(manifest); + auto document = Markup::Document(information.markup); information.title = document["information/title"].text(); auto mapperid = document["cartridge/board/type"].text(); @@ -54,8 +58,6 @@ void Cartridge::load(System::Revision revision, const string &manifest) { ramsize = numeral(ram["size"].data); ramdata = allocate(ramsize, 0xff); - system.load(revision); - //Super Game Boy core loads memory from Super Famicom core if(revision != System::Revision::SuperGameBoy) { if(rom["name"].exists()) interface->loadRequest(ID::ROM, rom["name"].data); diff --git a/higan/gb/cartridge/cartridge.hpp b/higan/gb/cartridge/cartridge.hpp index 2d4736f3..86ab4bde 100755 --- a/higan/gb/cartridge/cartridge.hpp +++ b/higan/gb/cartridge/cartridge.hpp @@ -54,7 +54,7 @@ struct Cartridge : MMIO, property { MMIO *mapper; bool bootrom_enable; - void load(System::Revision revision, const string &manifest); + void load(System::Revision revision); void unload(); uint8 rom_read(unsigned addr); diff --git a/higan/gb/interface/interface.cpp b/higan/gb/interface/interface.cpp index ec831b89..a4f3a45b 100755 --- a/higan/gb/interface/interface.cpp +++ b/higan/gb/interface/interface.cpp @@ -38,6 +38,7 @@ unsigned Interface::group(unsigned id) { case ID::SuperGameBoyBootROM: case ID::GameBoyColorBootROM: return 0; + case ID::Manifest: case ID::ROM: case ID::RAM: if(system.revision() == System::Revision::GameBoy) return ID::GameBoy; @@ -49,10 +50,10 @@ unsigned Interface::group(unsigned id) { throw; } -void Interface::load(unsigned id, const string &manifest) { - if(id == ID::GameBoy) cartridge.load(System::Revision::GameBoy, manifest); - if(id == ID::SuperGameBoy) cartridge.load(System::Revision::SuperGameBoy, manifest); - if(id == ID::GameBoyColor) cartridge.load(System::Revision::GameBoyColor, manifest); +void Interface::load(unsigned id) { + if(id == ID::GameBoy) cartridge.load(System::Revision::GameBoy); + if(id == ID::SuperGameBoy) cartridge.load(System::Revision::SuperGameBoy); + if(id == ID::GameBoyColor) cartridge.load(System::Revision::GameBoyColor); } void Interface::save() { @@ -61,7 +62,7 @@ void Interface::save() { } } -void Interface::load(unsigned id, const stream &stream, const string &manifest) { +void Interface::load(unsigned id, const stream &stream) { if(id == ID::GameBoyBootROM) { stream.read(system.bootROM.dmg, min( 256u, stream.size())); } @@ -74,6 +75,8 @@ void Interface::load(unsigned id, const stream &stream, const string &manifest) stream.read(system.bootROM.cgb, min(2048u, stream.size())); } + if(id == ID::Manifest) cartridge.information.markup = stream.text(); + if(id == ID::ROM) { stream.read(cartridge.romdata, min(cartridge.romsize, stream.size())); } diff --git a/higan/gb/interface/interface.hpp b/higan/gb/interface/interface.hpp index 99ad5b29..23654476 100755 --- a/higan/gb/interface/interface.hpp +++ b/higan/gb/interface/interface.hpp @@ -14,8 +14,8 @@ struct ID { GameBoyBootROM, SuperGameBoyBootROM, GameBoyColorBootROM, - GameBoyROM, - GameBoyColorROM, + + Manifest, ROM, RAM, }; @@ -42,9 +42,9 @@ struct Interface : Emulator::Interface { bool loaded(); string sha256(); unsigned group(unsigned id); - void load(unsigned id, const string &manifest); + void load(unsigned id); void save(); - void load(unsigned id, const stream &stream, const string &manifest = ""); + void load(unsigned id, const stream &stream); void save(unsigned id, const stream &stream); void unload(); diff --git a/higan/gba/cartridge/cartridge.cpp b/higan/gba/cartridge/cartridge.cpp index a3042614..e2d787d3 100755 --- a/higan/gba/cartridge/cartridge.cpp +++ b/higan/gba/cartridge/cartridge.cpp @@ -11,9 +11,10 @@ string Cartridge::title() { return information.title; } -void Cartridge::load(const string &manifest) { - information.markup = manifest; - auto document = Markup::Document(manifest); +void Cartridge::load() { + interface->loadRequest(ID::Manifest, "manifest.bml"); + + auto document = Markup::Document(information.markup); information.title = document["information/title"].text(); unsigned rom_size = 0; diff --git a/higan/gba/cartridge/cartridge.hpp b/higan/gba/cartridge/cartridge.hpp index 141b5c78..9defbf0d 100755 --- a/higan/gba/cartridge/cartridge.hpp +++ b/higan/gba/cartridge/cartridge.hpp @@ -21,7 +21,7 @@ struct Cartridge : property { }; vector memory; - void load(const string &manifest); + void load(); void unload(); void power(); diff --git a/higan/gba/interface/interface.cpp b/higan/gba/interface/interface.cpp index cc2920ed..aa8edb3c 100755 --- a/higan/gba/interface/interface.cpp +++ b/higan/gba/interface/interface.cpp @@ -24,6 +24,7 @@ unsigned Interface::group(unsigned id) { switch(id) { case ID::BIOS: return ID::System; + case ID::Manifest: case ID::ROM: case ID::RAM: case ID::EEPROM: @@ -34,8 +35,8 @@ unsigned Interface::group(unsigned id) { throw; } -void Interface::load(unsigned id, const string &manifest) { - cartridge.load(manifest); +void Interface::load(unsigned id) { + cartridge.load(); } void Interface::save() { @@ -44,11 +45,13 @@ void Interface::save() { } } -void Interface::load(unsigned id, const stream &stream, const string &manifest) { +void Interface::load(unsigned id, const stream &stream) { if(id == ID::BIOS) { stream.read(bios.data, min(bios.size, stream.size())); } + if(id == ID::Manifest) cartridge.information.markup = stream.text(); + if(id == ID::ROM) { stream.read(cartridge.rom.data, min(cartridge.rom.size, stream.size())); } diff --git a/higan/gba/interface/interface.hpp b/higan/gba/interface/interface.hpp index 0483e07b..675953f8 100755 --- a/higan/gba/interface/interface.hpp +++ b/higan/gba/interface/interface.hpp @@ -10,6 +10,8 @@ struct ID { enum : unsigned { BIOS, + + Manifest, ROM, RAM, EEPROM, @@ -28,9 +30,9 @@ struct Interface : Emulator::Interface { bool loaded(); unsigned group(unsigned id); - void load(unsigned id, const string &manifest); + void load(unsigned id); void save(); - void load(unsigned id, const stream &stream, const string &manifest = ""); + void load(unsigned id, const stream &stream); void save(unsigned id, const stream &stream); void unload(); diff --git a/higan/nall/Makefile b/higan/nall/Makefile index bbc4b029..f422f49d 100755 --- a/higan/nall/Makefile +++ b/higan/nall/Makefile @@ -36,16 +36,21 @@ endif ifeq ($(compiler),) ifeq ($(platform),win) - compiler := gcc + compiler := g++ else ifeq ($(platform),osx) - compiler := gcc-mp-4.7 + compiler := g++-mp-4.7 else - compiler := gcc-4.7 + compiler := g++-4.7 endif endif -c := $(compiler) -std=gnu99 -cpp := $(subst cc,++,$(compiler)) -std=gnu++0x +c := $(compiler) -x c -std=gnu99 +cpp := $(compiler) -std=gnu++11 + +ifeq ($(arch),x86) + c := $(c) -m32 + cpp := $(cpp) -m32 +endif ifeq ($(prefix),) prefix := /usr/local diff --git a/higan/nall/file.hpp b/higan/nall/file.hpp index be9fc086..80b918a8 100755 --- a/higan/nall/file.hpp +++ b/higan/nall/file.hpp @@ -98,6 +98,14 @@ namespace nall { return true; } + static bool create(const string &filename) { + //create an empty file (will replace existing files) + file fp; + if(fp.open(filename, mode::write) == false) return false; + fp.close(); + return true; + } + static string sha256(const string &filename) { auto buffer = read(filename); return nall::sha256(buffer.data(), buffer.size()); diff --git a/higan/nall/nall.hpp b/higan/nall/nall.hpp index 06040fac..a7887695 100755 --- a/higan/nall/nall.hpp +++ b/higan/nall/nall.hpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/higan/nall/property.hpp b/higan/nall/property.hpp index 665afcad..1ddb5c9b 100755 --- a/higan/nall/property.hpp +++ b/higan/nall/property.hpp @@ -5,12 +5,6 @@ //example: property::readonly implies that only owner has full //access to type; and all other code has readonly access. // -//this code relies on extended friend semantics from C++0x to work, as it -//declares a friend class via a template paramter. it also exploits a bug in -//G++ 4.x to work even in C++98 mode. -// -//if compiling elsewhere, simply remove the friend class and private semantics - //property can be used either of two ways: //struct foo { // property::readonly x; @@ -50,8 +44,6 @@ namespace nall { template struct property { - template struct traits { typedef T type; }; - template struct readonly { const T* operator->() const { return &value; } const T& operator()() const { return value; } @@ -61,7 +53,7 @@ namespace nall { operator T&() { return value; } const T& operator=(const T& value_) { return value = value_; } T value; - friend class traits::type; + friend C; }; template struct writeonly { @@ -73,7 +65,7 @@ namespace nall { T* operator->() { return &value; } operator T&() { return value; } T value; - friend class traits::type; + friend C; }; template struct readwrite { diff --git a/higan/nall/stream/stream.hpp b/higan/nall/stream/stream.hpp index 9d937729..043eecba 100755 --- a/higan/nall/stream/stream.hpp +++ b/higan/nall/stream/stream.hpp @@ -48,6 +48,15 @@ struct stream { while(length--) *data++ = read(); } + string text() const { + string buffer; + buffer.resize(size() + 1); + buffer[size()] = 0; + seek(0); + read((uint8_t*)buffer(), size()); + return buffer; + } + void writel(uintmax_t data, unsigned length = 1) const { while(length--) { write(data); diff --git a/higan/nall/string.hpp b/higan/nall/string.hpp index 82c1bbb1..82b7cde4 100755 --- a/higan/nall/string.hpp +++ b/higan/nall/string.hpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include diff --git a/higan/nall/string/base.hpp b/higan/nall/string/base.hpp index 85645c7f..d5f85ca4 100755 --- a/higan/nall/string/base.hpp +++ b/higan/nall/string/base.hpp @@ -23,11 +23,14 @@ namespace nall { struct string { inline static string read(const string &filename); + inline static string date(); inline static string time(); inline static string datetime(); inline void reserve(unsigned); + inline void resize(unsigned); + inline void clear(char); inline bool empty() const; template inline string& assign(Args&&... args); @@ -64,6 +67,7 @@ namespace nall { inline string& qlower(); inline string& qupper(); inline string& transform(const char *before, const char *after); + inline string& reverse(); template inline string& ltrim(const char *key = " "); template inline string& rtrim(const char *key = " "); @@ -159,6 +163,12 @@ namespace nall { inline char* qstrupper(char *str); inline char* strtr(char *dest, const char *before, const char *after); + //format.hpp + template inline string format(const string &value); + template inline string hex(uintmax_t value); + template inline string octal(uintmax_t value); + template inline string binary(uintmax_t value); + //math.hpp inline bool strint(const char *str, int &result); inline bool strmath(const char *str, int &result); @@ -200,12 +210,11 @@ namespace nall { inline char* integer(char *result, intmax_t value); inline char* decimal(char *result, uintmax_t value); + //these functions are deprecated, use format() instead: template inline string integer(intmax_t value); template inline string linteger(intmax_t value); template inline string decimal(uintmax_t value); template inline string ldecimal(uintmax_t value); - template inline string hex(uintmax_t value); - template inline string binary(uintmax_t value); inline unsigned fp(char *str, long double value); inline string fp(long double value); diff --git a/higan/nall/string/core.hpp b/higan/nall/string/core.hpp index d843e2fd..64c9250d 100755 --- a/higan/nall/string/core.hpp +++ b/higan/nall/string/core.hpp @@ -12,11 +12,18 @@ static void istring(string &output, const T &value, Args&&... args) { } void string::reserve(unsigned size_) { - if(size_ > size) { - size = size_; - data = (char*)realloc(data, size + 1); - data[size] = 0; - } + if(size_ > size) resize(size_); +} + +void string::resize(unsigned size_) { + size = size_; + data = (char*)realloc(data, size + 1); + data[size] = 0; +} + +void string::clear(char c) { + for(unsigned n = 0; n < size; n++) data[n] = c; + data[size] = 0; } bool string::empty() const { diff --git a/higan/nall/string/format.hpp b/higan/nall/string/format.hpp new file mode 100644 index 00000000..599021d1 --- /dev/null +++ b/higan/nall/string/format.hpp @@ -0,0 +1,73 @@ +#ifdef NALL_STRING_INTERNAL_HPP + +namespace nall { + +template string format(const string &value) { + if(precision == 0) return value; + + bool padright = precision >= 0; + unsigned padding = abs(precision); + + unsigned length = value.length(); + if(padding <= length) { + if(padright) return substr(value, length - padding); + else return substr(value, 0, padding); + } + + string buffer; + buffer.resize(padding); + buffer.clear(padchar); + + memcpy(buffer() + (padright ? padding - length : 0), value, length); + return buffer; +} + +template string hex(uintmax_t value) { + string buffer; + buffer.resize(sizeof(uintmax_t) * 2); + + unsigned size = 0; + do { + unsigned n = value & 15; + buffer[size++] = n < 10 ? '0' + n : 'a' + n - 10; + value >>= 4; + } while(value); + buffer[size] = 0; + buffer.reverse(); + + return format(buffer); +} + +template string octal(uintmax_t value) { + string buffer; + buffer.resize(sizeof(uintmax_t) * 3); + + unsigned size = 0; + do { + buffer[size++] = '0' + (value & 7); + value >>= 3; + } while(value); + buffer[size] = 0; + buffer.reverse(); + + return format(buffer); +} + +template string binary(uintmax_t value) { + string buffer; + buffer.resize(sizeof(uintmax_t) * 8); + + unsigned size = 0; + do { + buffer[size++] = '0' + (value & 1); + value >>= 1; + } while(value); + buffer[size] = 0; + buffer.reverse(); + + return format(buffer); +} + +} + +#endif diff --git a/higan/nall/string/platform.hpp b/higan/nall/string/platform.hpp index 5c44a313..90b6d6b8 100755 --- a/higan/nall/string/platform.hpp +++ b/higan/nall/string/platform.hpp @@ -33,11 +33,13 @@ string realpath(const string &name) { return result; } +// /home/username/ +// c:/users/username/ string userpath() { string result; #ifdef _WIN32 wchar_t path[PATH_MAX] = L""; - SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, path); + SHGetFolderPathW(0, CSIDL_PROFILE | CSIDL_FLAG_CREATE, 0, 0, path); result = (const char*)utf8_t(path); result.transform("\\", "/"); #else @@ -51,20 +53,30 @@ string userpath() { return result; } +// /home/username/.config/ +// c:/users/username/appdata/roaming/ string configpath() { + string result; #ifdef _WIN32 - return userpath(); + wchar_t path[PATH_MAX] = L""; + SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, path); + result = (const char*)utf8_t(path); + result.transform("\\", "/"); #else - return {userpath(), ".config/"}; + result = {userpath(), ".config/"}; #endif + if(result.empty()) result = "."; + if(result.endswith("/") == false) result.append("/"); + return result; } string temppath() { #ifdef _WIN32 wchar_t path[PATH_MAX] = L""; GetTempPathW(PATH_MAX, path); -//path.transform("\\", "/"); - return (const char*)utf8_t(path); + string result = (const char*)utf8_t(path); + result.transform("\\", "/"); + return result; #else return "/tmp/"; #endif diff --git a/higan/nall/string/utility.hpp b/higan/nall/string/utility.hpp index 0225e4fe..657383f8 100755 --- a/higan/nall/string/utility.hpp +++ b/higan/nall/string/utility.hpp @@ -201,50 +201,6 @@ template string ldecimal(uintmax_t value) { return (const char*)result; } -template string hex(uintmax_t value) { - char buffer[64]; - unsigned size = 0; - - do { - unsigned n = value & 15; - buffer[size++] = n < 10 ? '0' + n : 'a' + n - 10; - value >>= 4; - } while(value); - - unsigned length = (length_ == 0 ? size : length_); - char result[length + 1]; - memset(result, padding, length); - result[length] = 0; - - for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) { - result[x] = buffer[y]; - } - - return (const char*)result; -} - -template string binary(uintmax_t value) { - char buffer[256]; - unsigned size = 0; - - do { - unsigned n = value & 1; - buffer[size++] = '0' + n; - value >>= 1; - } while(value); - - unsigned length = (length_ == 0 ? size : length_); - char result[length + 1]; - memset(result, padding, length); - result[length] = 0; - - for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) { - result[x] = buffer[y]; - } - - return (const char*)result; -} - //using sprintf is certainly not the most ideal method to convert //a double to a string ... but attempting to parse a double by //hand, digit-by-digit, results in subtle rounding errors. diff --git a/higan/nall/string/wrapper.hpp b/higan/nall/string/wrapper.hpp index 9d62915b..08aa98b3 100755 --- a/higan/nall/string/wrapper.hpp +++ b/higan/nall/string/wrapper.hpp @@ -27,6 +27,11 @@ string& string::upper() { nall::strupper(data); return *this; } string& string::qlower() { nall::qstrlower(data); return *this; } string& string::qupper() { nall::qstrupper(data); return *this; } string& string::transform(const char *before, const char *after) { nall::strtr(data, before, after); return *this; } +string& string::reverse() { + unsigned length = strlen(data), pivot = length >> 1; + for(signed x = 0, y = length - 1; x < pivot && y >= 0; x++, y--) std::swap(data[x], data[y]); + return *this; +} template string& string::ltrim(const char *key) { nall::ltrim(data, key); return *this; } template string& string::rtrim(const char *key) { nall::rtrim(data, key); return *this; } diff --git a/higan/nall/thread.hpp b/higan/nall/thread.hpp new file mode 100644 index 00000000..de894f2d --- /dev/null +++ b/higan/nall/thread.hpp @@ -0,0 +1,123 @@ +#ifndef NALL_THREAD_HPP +#define NALL_THREAD_HPP + +#include +#include +#include + +#if defined(PLATFORM_X) || defined(PLATFORM_OSX) + #include + +namespace nall { + void* thread_entry_point(void*); + + struct thread { + thread(function entryPoint) : entryPoint(entryPoint), completed(false), dead(false) { + initialize(); + pthread_create(&pthread, NULL, thread_entry_point, (void*)this); + } + + ~thread() { + join(); + } + + bool active() const { + return completed == false; + } + + void join() { + if(dead) return; + dead = true; + pthread_join(pthread, NULL); + } + + static bool primary() { + initialize(); + return pthread_equal(primaryThread(), pthread_self()); + } + + private: + pthread_t pthread; + function entryPoint; + volatile bool completed, dead; + friend void* thread_entry_point(void*); + + static void initialize() { + static bool initialized = false; + if(initialized) return; + initialized = true; + primaryThread() = pthread_self(); + } + + static pthread_t& primaryThread() { + static pthread_t thread; + return thread; + } + }; + + void* thread_entry_point(void *parameter) { + thread *context = (thread*)parameter; + context->entryPoint(); + context->completed = true; + pthread_exit(0); + } +} +#elif defined(PLATFORM_WIN) +namespace nall { + inline DWORD WINAPI thread_entry_point(LPVOID); + + struct thread { + thread(function entryPoint) : entryPoint(entryPoint), completed(false), dead(false) { + initialize(); + hthread = CreateThread(NULL, 0, thread_entry_point, (void*)this, 0, NULL); + } + + ~thread() { + join(); + } + + bool active() const { + return completed == false; + } + + void join() { + if(dead) return; + dead = true; + WaitForSingleObject(hthread, INFINITE); + CloseHandle(hthread); + } + + static bool primary() { + initialize(); + return primaryThread() == GetCurrentThreadId(); + } + + private: + HANDLE hthread; + function entryPoint; + volatile bool completed, dead; + friend DWORD WINAPI thread_entry_point(LPVOID); + + static void initialize() { + static bool initialized = false; + if(initialized) return; + initialized = true; + primaryThread() = GetCurrentThreadId(); + } + + static DWORD& primaryThread() { + static DWORD thread; + return thread; + } + }; + + inline DWORD WINAPI thread_entry_point(LPVOID parameter) { + thread *context = (thread*)parameter; + context->entryPoint(); + context->completed = true; + return 0; + } +} +#endif + +#endif diff --git a/higan/phoenix/Makefile b/higan/phoenix/Makefile index b98ccfdd..d1c9d981 100755 --- a/higan/phoenix/Makefile +++ b/higan/phoenix/Makefile @@ -15,11 +15,6 @@ ifeq ($(platform),x) else ifeq ($(platform),win) phoenixflags := -DPHOENIX_WINDOWS phoenixlink := -lkernel32 -luser32 -lgdi32 -ladvapi32 -lole32 -lcomctl32 -lcomdlg32 -lshlwapi - - ifeq ($(arch),win32) - phoenixflags := -m32 $(phoenixflags) - phoenixlink := -m32 $(phoenixlink) - endif else phoenixflags := -DPHOENIX_REFERENCE phoenixlink := diff --git a/higan/ruby/Makefile b/higan/ruby/Makefile index 6a9572b5..c651cacc 100755 --- a/higan/ruby/Makefile +++ b/higan/ruby/Makefile @@ -23,9 +23,4 @@ else ifeq ($(platform),osx) rubylink += $(if $(findstring audio.openal,$(ruby)),-framework OpenAL) else ifeq ($(platform),win) rubylink += $(if $(findstring audio.openal,$(ruby)),-lopenal32) - - ifeq ($(arch),win32) - rubyflags := -m32 $(rubyflags) - rubylink := -m32 $(rubylink) - endif endif diff --git a/higan/sfc/Makefile b/higan/sfc/Makefile index a5cc6ec9..2bc987e6 100755 --- a/higan/sfc/Makefile +++ b/higan/sfc/Makefile @@ -1,12 +1,13 @@ sfc_objects := sfc-interface sfc-system sfc-controller sfc_objects += sfc-cartridge sfc-cheat sfc_objects += sfc-memory sfc-cpu sfc-smp sfc-dsp sfc-ppu -sfc_objects += sfc-icd2 sfc-bsx sfc-sufamiturbo sfc-nss sfc-event +sfc_objects += sfc-icd2 sfc-bsx sfc-nss sfc-event sfc_objects += sfc-sa1 sfc-superfx sfc_objects += sfc-armdsp sfc-hitachidsp sfc-necdsp sfc_objects += sfc-epsonrtc sfc-sharprtc sfc_objects += sfc-spc7110 sfc-sdd1 sfc-obc1 sfc_objects += sfc-hsu1 sfc-msu1 +sfc_objects += sfc-satellaview sfc-sufamiturbo objects += $(sfc_objects) ifeq ($(profile),accuracy) @@ -27,6 +28,8 @@ else ifeq ($(profile),performance) sfcsmp := $(sfc)/alt/smp sfcdsp := $(sfc)/alt/dsp sfcppu := $(sfc)/alt/ppu-performance +else + $(error unknown profile.) endif obj/sfc-interface.o: $(sfc)/interface/interface.cpp $(call rwildcard,$(sfc)/interface) @@ -42,7 +45,6 @@ obj/sfc-ppu.o: $(sfcppu)/ppu.cpp $(call rwildcard,$(sfcppu)/) obj/sfc-icd2.o: $(sfc)/chip/icd2/icd2.cpp $(call rwildcard,$(sfc)/chip/icd2/) obj/sfc-bsx.o: $(sfc)/chip/bsx/bsx.cpp $(call rwildcard,$(sfc)/chip/bsx/) -obj/sfc-sufamiturbo.o: $(sfc)/chip/sufamiturbo/sufamiturbo.cpp $(sfc)/chip/sufamiturbo/* obj/sfc-nss.o: $(sfc)/chip/nss/nss.cpp $(call rwildcard,$(sfc)/chip/nss/) obj/sfc-event.o: $(sfc)/chip/event/event.cpp $(call rwildcard,$(sfc)/chip/event/) @@ -62,3 +64,6 @@ obj/sfc-obc1.o: $(sfc)/chip/obc1/obc1.cpp $(sfc)/chip/obc1/* obj/sfc-hsu1.o: $(sfc)/chip/hsu1/hsu1.cpp $(sfc)/chip/hsu1/* obj/sfc-msu1.o: $(sfc)/chip/msu1/msu1.cpp $(sfc)/chip/msu1/* + +obj/sfc-satellaview.o: $(sfc)/slot/satellaview/satellaview.cpp $(call rwildcard,$(sfc)/slot/satellaview/) +obj/sfc-sufamiturbo.o: $(sfc)/slot/sufamiturbo/sufamiturbo.cpp $(call rwildcard,$(sfc)/slot/sufamiturbo/) diff --git a/higan/sfc/cartridge/cartridge.cpp b/higan/sfc/cartridge/cartridge.cpp index 38014fae..ac784fd6 100755 --- a/higan/sfc/cartridge/cartridge.cpp +++ b/higan/sfc/cartridge/cartridge.cpp @@ -27,7 +27,7 @@ string Cartridge::title() { return information.title.cartridge; } -void Cartridge::load(const string &manifest) { +void Cartridge::load() { region = Region::NTSC; has_gb_slot = false; @@ -49,13 +49,20 @@ void Cartridge::load(const string &manifest) { has_hsu1 = false; has_msu1 = false; - information.title.cartridge = ""; - information.title.gameBoy = ""; - information.title.satellaview = ""; - information.title.sufamiTurboA = ""; - information.title.sufamiTurboB = ""; + information.markup.cartridge = ""; + information.markup.gameBoy = ""; + information.markup.satellaview = ""; + information.markup.sufamiTurboA = ""; + information.markup.sufamiTurboB = ""; - parse_markup(information.markup = manifest); + information.title.cartridge = ""; + information.title.gameBoy = ""; + information.title.satellaview = ""; + information.title.sufamiTurboA = ""; + information.title.sufamiTurboB = ""; + + interface->loadRequest(ID::Manifest, "manifest.bml"); + parse_markup(information.markup.cartridge); //Super Game Boy if(cartridge.has_gb_slot()) { @@ -64,7 +71,7 @@ void Cartridge::load(const string &manifest) { //Broadcast Satellaview else if(cartridge.has_bs_cart() && cartridge.has_bs_slot()) { - sha256 = nall::sha256(bsxflash.memory.data(), bsxflash.memory.size()); + sha256 = nall::sha256(satellaviewcartridge.memory.data(), satellaviewcartridge.memory.size()); } //Sufami Turbo @@ -72,8 +79,8 @@ void Cartridge::load(const string &manifest) { sha256_ctx sha; uint8_t hash[32]; sha256_init(&sha); - sha256_chunk(&sha, sufamiturbo.slotA.rom.data(), sufamiturbo.slotA.rom.size()); - sha256_chunk(&sha, sufamiturbo.slotB.rom.data(), sufamiturbo.slotB.rom.size()); + sha256_chunk(&sha, sufamiturboA.rom.data(), sufamiturboA.rom.size()); + sha256_chunk(&sha, sufamiturboB.rom.data(), sufamiturboB.rom.size()); sha256_final(&sha); sha256_hash(&sha, hash); string result; @@ -118,37 +125,41 @@ void Cartridge::load(const string &manifest) { loaded = true; } -void Cartridge::load_super_game_boy(const string &manifest) { - auto document = Markup::Document(manifest); +void Cartridge::load_super_game_boy() { + interface->loadRequest(ID::SuperGameBoyManifest, "manifest.bml"); + auto document = Markup::Document(information.markup.gameBoy); information.title.gameBoy = document["information/title"].text(); auto rom = document["cartridge/rom"]; auto ram = document["cartridge/ram"]; - GameBoy::cartridge.load(GameBoy::System::Revision::SuperGameBoy, manifest); + GameBoy::cartridge.information.markup = information.markup.gameBoy; + GameBoy::cartridge.load(GameBoy::System::Revision::SuperGameBoy); if(rom["name"].exists()) interface->loadRequest(ID::SuperGameBoyROM, rom["name"].data); if(ram["name"].exists()) interface->loadRequest(ID::SuperGameBoyRAM, ram["name"].data); if(ram["name"].exists()) memory.append({ID::SuperGameBoyRAM, ram["name"].data}); } -void Cartridge::load_satellaview(const string &manifest) { - auto document = Markup::Document(manifest); +void Cartridge::load_satellaview() { + interface->loadRequest(ID::SatellaviewManifest, "manifest.bml"); + auto document = Markup::Document(information.markup.satellaview); information.title.satellaview = document["information/title"].text(); auto rom = document["cartridge/rom"]; if(rom["name"].exists()) { unsigned size = numeral(rom["size"].data); - bsxflash.memory.map(allocate(size, 0xff), size); - interface->loadRequest(ID::BsxFlashROM, rom["name"].data); + satellaviewcartridge.memory.map(allocate(size, 0xff), size); + interface->loadRequest(ID::SatellaviewROM, rom["name"].data); - bsxflash.readonly = (rom["type"].text() == "MaskROM"); + satellaviewcartridge.readonly = (rom["type"].text() == "MaskROM"); } } -void Cartridge::load_sufami_turbo_a(const string &manifest) { - auto document = Markup::Document(manifest); +void Cartridge::load_sufami_turbo_a() { + interface->loadRequest(ID::SufamiTurboSlotAManifest, "manifest.bml"); + auto document = Markup::Document(information.markup.sufamiTurboA); information.title.sufamiTurboA = document["information/title"].text(); auto rom = document["cartridge/rom"]; @@ -156,13 +167,13 @@ void Cartridge::load_sufami_turbo_a(const string &manifest) { if(rom["name"].exists()) { unsigned size = numeral(rom["size"].data); - sufamiturbo.slotA.rom.map(allocate(size, 0xff), size); + sufamiturboA.rom.map(allocate(size, 0xff), size); interface->loadRequest(ID::SufamiTurboSlotAROM, rom["name"].data); } if(ram["name"].exists()) { unsigned size = numeral(ram["size"].data); - sufamiturbo.slotA.ram.map(allocate(size, 0xff), size); + sufamiturboA.ram.map(allocate(size, 0xff), size); interface->loadRequest(ID::SufamiTurboSlotARAM, ram["name"].data); memory.append({ID::SufamiTurboSlotARAM, ram["name"].data}); } @@ -172,8 +183,9 @@ void Cartridge::load_sufami_turbo_a(const string &manifest) { } } -void Cartridge::load_sufami_turbo_b(const string &manifest) { - auto document = Markup::Document(manifest); +void Cartridge::load_sufami_turbo_b() { + interface->loadRequest(ID::SufamiTurboSlotBManifest, "manifest.bml"); + auto document = Markup::Document(information.markup.sufamiTurboB); information.title.sufamiTurboB = document["information/title"].text(); auto rom = document["cartridge/rom"]; @@ -181,13 +193,13 @@ void Cartridge::load_sufami_turbo_b(const string &manifest) { if(rom["name"].exists()) { unsigned size = numeral(rom["size"].data); - sufamiturbo.slotB.rom.map(allocate(size, 0xff), size); + sufamiturboB.rom.map(allocate(size, 0xff), size); interface->loadRequest(ID::SufamiTurboSlotBROM, rom["name"].data); } if(ram["name"].exists()) { unsigned size = numeral(ram["size"].data); - sufamiturbo.slotB.ram.map(allocate(size, 0xff), size); + sufamiturboB.ram.map(allocate(size, 0xff), size); interface->loadRequest(ID::SufamiTurboSlotBRAM, ram["name"].data); memory.append({ID::SufamiTurboSlotBRAM, ram["name"].data}); } diff --git a/higan/sfc/cartridge/cartridge.hpp b/higan/sfc/cartridge/cartridge.hpp index 5dbf9df4..57ba483b 100755 --- a/higan/sfc/cartridge/cartridge.hpp +++ b/higan/sfc/cartridge/cartridge.hpp @@ -61,7 +61,14 @@ struct Cartridge : property { vector memory; struct Information { - string markup; + struct Markup { + string cartridge; + string gameBoy; + string satellaview; + string sufamiTurboA; + string sufamiTurboB; + } markup; + struct Title { string cartridge; string gameBoy; @@ -73,11 +80,7 @@ struct Cartridge : property { string title(); - void load(const string &manifest); - void load_super_game_boy(const string &manifest); - void load_satellaview(const string &manifest); - void load_sufami_turbo_a(const string &manifest); - void load_sufami_turbo_b(const string &manifest); + void load(); void unload(); void serialize(serializer&); @@ -85,6 +88,11 @@ struct Cartridge : property { ~Cartridge(); private: + void load_super_game_boy(); + void load_satellaview(); + void load_sufami_turbo_a(); + void load_sufami_turbo_b(); + void parse_markup(const char*); void parse_markup_map(Mapping&, Markup::Node); void parse_markup_memory(MappedRAM&, Markup::Node, unsigned id, bool writable); @@ -108,6 +116,8 @@ private: void parse_markup_obc1(Markup::Node); void parse_markup_hsu1(Markup::Node); void parse_markup_msu1(Markup::Node); + + friend class Interface; }; extern Cartridge cartridge; diff --git a/higan/sfc/cartridge/markup.cpp b/higan/sfc/cartridge/markup.cpp index 6e53b78d..b9518a15 100755 --- a/higan/sfc/cartridge/markup.cpp +++ b/higan/sfc/cartridge/markup.cpp @@ -135,9 +135,9 @@ void Cartridge::parse_markup_bsxslot(Markup::Node root) { if(node.name != "map") continue; if(node["id"].data == "rom") { - if(bsxflash.memory.size() == 0) continue; + if(satellaviewcartridge.memory.size() == 0) continue; - Mapping m(bsxflash); + Mapping m(satellaviewcartridge); parse_markup_map(m, node); mapping.append(m); } @@ -159,7 +159,7 @@ void Cartridge::parse_markup_sufamiturbo(Markup::Node root) { if(node.name != "map") continue; if(node["id"].data == "rom") { - SuperFamicom::Memory &memory = slotid == 0 ? sufamiturbo.slotA.rom : sufamiturbo.slotB.rom; + SuperFamicom::Memory &memory = slotid == 0 ? sufamiturboA.rom : sufamiturboB.rom; if(memory.size() == 0) continue; Mapping m(memory); @@ -169,7 +169,7 @@ void Cartridge::parse_markup_sufamiturbo(Markup::Node root) { } if(node["id"].data == "ram") { - SuperFamicom::Memory &memory = slotid == 0 ? sufamiturbo.slotA.ram : sufamiturbo.slotB.ram; + SuperFamicom::Memory &memory = slotid == 0 ? sufamiturboA.ram : sufamiturboB.ram; if(memory.size() == 0) continue; Mapping m(memory); diff --git a/higan/sfc/chip/bsx/bsx.cpp b/higan/sfc/chip/bsx/bsx.cpp index 2a384db0..bf0d9c03 100755 --- a/higan/sfc/chip/bsx/bsx.cpp +++ b/higan/sfc/chip/bsx/bsx.cpp @@ -4,5 +4,4 @@ namespace SuperFamicom { #include "satellaview/satellaview.cpp" #include "cartridge/cartridge.cpp" - #include "flash/flash.cpp" } diff --git a/higan/sfc/chip/bsx/bsx.hpp b/higan/sfc/chip/bsx/bsx.hpp index 5f3895bd..dd761a05 100755 --- a/higan/sfc/chip/bsx/bsx.hpp +++ b/higan/sfc/chip/bsx/bsx.hpp @@ -1,3 +1,2 @@ #include "satellaview/satellaview.hpp" #include "cartridge/cartridge.hpp" -#include "flash/flash.hpp" diff --git a/higan/sfc/chip/bsx/cartridge/cartridge.cpp b/higan/sfc/chip/bsx/cartridge/cartridge.cpp index b11bb6f0..c025e36a 100755 --- a/higan/sfc/chip/bsx/cartridge/cartridge.cpp +++ b/higan/sfc/chip/bsx/cartridge/cartridge.cpp @@ -80,7 +80,7 @@ uint8 BSXCartridge::mcu_access(bool write, unsigned addr, uint8 data) { || ((addr & 0x400000) == 0x400000) //$40-7f|c0-ff:0000-ffff ) { if(r02 == 0) addr = ((addr & 0x7f0000) >> 1) | (addr & 0x7fff); - Memory &memory = (r01 == 0 ? (Memory&)bsxflash : (Memory&)psram); + Memory &memory = (r01 == 0 ? (Memory&)satellaviewcartridge : (Memory&)psram); return memory_access(write, memory, addr & 0x7fffff, data); } diff --git a/higan/sfc/chip/chip.hpp b/higan/sfc/chip/chip.hpp index 6d7637a7..de691961 100755 --- a/higan/sfc/chip/chip.hpp +++ b/higan/sfc/chip/chip.hpp @@ -5,7 +5,6 @@ struct Coprocessor : Thread { #include #include -#include #include #include diff --git a/higan/sfc/chip/msu1/msu1.cpp b/higan/sfc/chip/msu1/msu1.cpp index 4d50c338..7882ea05 100755 --- a/higan/sfc/chip/msu1/msu1.cpp +++ b/higan/sfc/chip/msu1/msu1.cpp @@ -87,7 +87,7 @@ void MSU1::reset() { void MSU1::data_open() { if(datafile.open()) datafile.close(); - auto document = Markup::Document(cartridge.information.markup); + auto document = Markup::Document(cartridge.information.markup.cartridge); string name = document["cartridge/msu1/rom/name"].data; if(name.empty()) name = "msu1.rom"; if(datafile.open({interface->path(ID::SuperFamicom), name}, file::mode::read)) { @@ -97,7 +97,7 @@ void MSU1::data_open() { void MSU1::audio_open() { if(audiofile.open()) audiofile.close(); - auto document = Markup::Document(cartridge.information.markup); + auto document = Markup::Document(cartridge.information.markup.cartridge); string name = {"track-", mmio.audio_track, ".pcm"}; for(auto &track : document.find("cartridge/msu1/track")) { if(numeral(track["number"].data) != mmio.audio_track) continue; diff --git a/higan/sfc/chip/sufamiturbo/serialization.cpp b/higan/sfc/chip/sufamiturbo/serialization.cpp deleted file mode 100755 index 511207ad..00000000 --- a/higan/sfc/chip/sufamiturbo/serialization.cpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifdef SUFAMITURBO_CPP - -void SufamiTurbo::serialize(serializer &s) { - s.array(slotA.ram.data(), slotA.ram.size()); - s.array(slotB.ram.data(), slotB.ram.size()); -} - -#endif diff --git a/higan/sfc/chip/sufamiturbo/sufamiturbo.cpp b/higan/sfc/chip/sufamiturbo/sufamiturbo.cpp deleted file mode 100755 index ac7236d2..00000000 --- a/higan/sfc/chip/sufamiturbo/sufamiturbo.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include - -#define SUFAMITURBO_CPP -namespace SuperFamicom { - -#include "serialization.cpp" -SufamiTurbo sufamiturbo; - -void SufamiTurbo::load() { -} - -void SufamiTurbo::unload() { - slotA.rom.reset(); - slotA.ram.reset(); - slotB.rom.reset(); - slotB.ram.reset(); -} - -} diff --git a/higan/sfc/chip/sufamiturbo/sufamiturbo.hpp b/higan/sfc/chip/sufamiturbo/sufamiturbo.hpp deleted file mode 100755 index ccc83a67..00000000 --- a/higan/sfc/chip/sufamiturbo/sufamiturbo.hpp +++ /dev/null @@ -1,12 +0,0 @@ -struct SufamiTurbo { - struct Slot { - MappedRAM rom; - MappedRAM ram; - } slotA, slotB; - - void load(); - void unload(); - void serialize(serializer&); -}; - -extern SufamiTurbo sufamiturbo; diff --git a/higan/sfc/interface/interface.cpp b/higan/sfc/interface/interface.cpp index 9c7f47fc..10923a2a 100755 --- a/higan/sfc/interface/interface.cpp +++ b/higan/sfc/interface/interface.cpp @@ -31,6 +31,7 @@ unsigned Interface::group(unsigned id) { switch(id) { case ID::IPLROM: return 0; + case ID::Manifest: case ID::ROM: case ID::RAM: case ID::EventROM0: @@ -70,17 +71,21 @@ unsigned Interface::group(unsigned id) { case ID::BsxPSRAM: return 1; case ID::SuperGameBoy: + case ID::SuperGameBoyManifest: case ID::SuperGameBoyROM: case ID::SuperGameBoyRAM: return 2; case ID::Satellaview: - case ID::BsxFlashROM: + case ID::SatellaviewManifest: + case ID::SatellaviewROM: return 3; case ID::SufamiTurboSlotA: + case ID::SufamiTurboSlotAManifest: case ID::SufamiTurboSlotAROM: case ID::SufamiTurboSlotARAM: return 4; case ID::SufamiTurboSlotB: + case ID::SufamiTurboSlotBManifest: case ID::SufamiTurboSlotBROM: case ID::SufamiTurboSlotBRAM: return 5; @@ -89,12 +94,12 @@ unsigned Interface::group(unsigned id) { throw; } -void Interface::load(unsigned id, const string &manifest) { - if(id == ID::SuperFamicom) cartridge.load(manifest); - if(id == ID::SuperGameBoy) cartridge.load_super_game_boy(manifest); - if(id == ID::Satellaview) cartridge.load_satellaview(manifest); - if(id == ID::SufamiTurboSlotA) cartridge.load_sufami_turbo_a(manifest); - if(id == ID::SufamiTurboSlotB) cartridge.load_sufami_turbo_b(manifest); +void Interface::load(unsigned id) { + if(id == ID::SuperFamicom) cartridge.load(); + if(id == ID::SuperGameBoy) cartridge.load_super_game_boy(); + if(id == ID::Satellaview) cartridge.load_satellaview(); + if(id == ID::SufamiTurboSlotA) cartridge.load_sufami_turbo_a(); + if(id == ID::SufamiTurboSlotB) cartridge.load_sufami_turbo_b(); } void Interface::save() { @@ -103,11 +108,12 @@ void Interface::save() { } } -void Interface::load(unsigned id, const stream &stream, const string &manifest) { +void Interface::load(unsigned id, const stream &stream) { if(id == ID::IPLROM) { stream.read(smp.iplrom, min(64u, stream.size())); } + if(id == ID::Manifest) cartridge.information.markup.cartridge = stream.text(); if(id == ID::ROM) cartridge.rom.read(stream); if(id == ID::RAM) cartridge.ram.read(stream); @@ -187,6 +193,12 @@ void Interface::load(unsigned id, const stream &stream, const string &manifest) stream.read(GameBoy::system.bootROM.sgb, min(stream.size(), 256u)); } + if(id == ID::BsxROM) bsxcartridge.rom.read(stream); + if(id == ID::BsxRAM) bsxcartridge.ram.read(stream); + if(id == ID::BsxPSRAM) bsxcartridge.psram.read(stream); + + if(id == ID::SuperGameBoyManifest) cartridge.information.markup.gameBoy = stream.text(); + if(id == ID::SuperGameBoyROM) { stream.read(GameBoy::cartridge.romdata, min(GameBoy::cartridge.romsize, stream.size())); } @@ -195,16 +207,16 @@ void Interface::load(unsigned id, const stream &stream, const string &manifest) stream.read(GameBoy::cartridge.ramdata, min(GameBoy::cartridge.ramsize, stream.size())); } - if(id == ID::BsxFlashROM) bsxflash.memory.read(stream); - if(id == ID::BsxROM) bsxcartridge.rom.read(stream); - if(id == ID::BsxRAM) bsxcartridge.ram.read(stream); - if(id == ID::BsxPSRAM) bsxcartridge.psram.read(stream); + if(id == ID::SatellaviewManifest) cartridge.information.markup.satellaview = stream.text(); + if(id == ID::SatellaviewROM) satellaviewcartridge.memory.read(stream); - if(id == ID::SufamiTurboSlotAROM) sufamiturbo.slotA.rom.read(stream); - if(id == ID::SufamiTurboSlotBROM) sufamiturbo.slotB.rom.read(stream); + if(id == ID::SufamiTurboSlotAManifest) cartridge.information.markup.sufamiTurboA = stream.text(); + if(id == ID::SufamiTurboSlotAROM) sufamiturboA.rom.read(stream); + if(id == ID::SufamiTurboSlotBROM) sufamiturboB.rom.read(stream); - if(id == ID::SufamiTurboSlotARAM) sufamiturbo.slotA.ram.read(stream); - if(id == ID::SufamiTurboSlotBRAM) sufamiturbo.slotB.ram.read(stream); + if(id == ID::SufamiTurboSlotBManifest) cartridge.information.markup.sufamiTurboB = stream.text(); + if(id == ID::SufamiTurboSlotARAM) sufamiturboA.ram.read(stream); + if(id == ID::SufamiTurboSlotBRAM) sufamiturboB.ram.read(stream); } void Interface::save(unsigned id, const stream &stream) { @@ -251,8 +263,8 @@ void Interface::save(unsigned id, const stream &stream) { if(id == ID::BsxRAM) stream.write(bsxcartridge.ram.data(), bsxcartridge.ram.size()); if(id == ID::BsxPSRAM) stream.write(bsxcartridge.psram.data(), bsxcartridge.psram.size()); - if(id == ID::SufamiTurboSlotARAM) stream.write(sufamiturbo.slotA.ram.data(), sufamiturbo.slotA.ram.size()); - if(id == ID::SufamiTurboSlotBRAM) stream.write(sufamiturbo.slotB.ram.data(), sufamiturbo.slotB.ram.size()); + if(id == ID::SufamiTurboSlotARAM) stream.write(sufamiturboA.ram.data(), sufamiturboA.ram.size()); + if(id == ID::SufamiTurboSlotBRAM) stream.write(sufamiturboB.ram.data(), sufamiturboB.ram.size()); } void Interface::unload() { @@ -375,10 +387,10 @@ Interface::Interface() { information.capability.states = true; information.capability.cheats = true; - media.append({ID::SuperFamicom, "Super Famicom", "sfc", true }); - media.append({ID::SuperFamicom, "Super Famicom", "gb", false}); - media.append({ID::SuperFamicom, "Super Famicom", "bs", false}); - media.append({ID::SuperFamicom, "Super Famicom", "st", false}); + media.append({ID::SuperFamicom, "Super Famicom", "sfc", true }); + media.append({ID::SuperFamicom, "Game Boy", "gb", false}); + media.append({ID::SuperFamicom, "BS-X Satellaview", "bs", false}); + media.append({ID::SuperFamicom, "Sufami Turbo", "st", false}); { Device device{0, ID::Port1 | ID::Port2, "Controller"}; diff --git a/higan/sfc/interface/interface.hpp b/higan/sfc/interface/interface.hpp index 001636fe..a26a070f 100755 --- a/higan/sfc/interface/interface.hpp +++ b/higan/sfc/interface/interface.hpp @@ -15,6 +15,7 @@ struct ID { //memory (files) IPLROM, + Manifest, ROM, RAM, @@ -61,17 +62,24 @@ struct ID { OBC1RAM, SuperGameBoyBootROM, - SuperGameBoyROM, - SuperGameBoyRAM, - BsxFlashROM, BsxROM, BsxRAM, BsxPSRAM, + SuperGameBoyManifest, + SuperGameBoyROM, + SuperGameBoyRAM, + + SatellaviewManifest, + SatellaviewROM, + + SufamiTurboSlotAManifest, SufamiTurboSlotAROM, - SufamiTurboSlotBROM, SufamiTurboSlotARAM, + + SufamiTurboSlotBManifest, + SufamiTurboSlotBROM, SufamiTurboSlotBRAM, //controller ports @@ -88,9 +96,9 @@ struct Interface : Emulator::Interface { bool loaded(); string sha256(); unsigned group(unsigned id); - void load(unsigned id, const string &manifest); + void load(unsigned id); void save(); - void load(unsigned id, const stream &stream, const string &markup = ""); + void load(unsigned id, const stream &stream); void save(unsigned id, const stream &stream); void unload(); diff --git a/higan/sfc/sfc.hpp b/higan/sfc/sfc.hpp index f261865d..3219e28e 100755 --- a/higan/sfc/sfc.hpp +++ b/higan/sfc/sfc.hpp @@ -66,6 +66,7 @@ namespace SuperFamicom { #include #include #include + #include #include #include #include diff --git a/higan/sfc/chip/bsx/flash/flash.cpp b/higan/sfc/slot/satellaview/satellaview.cpp old mode 100755 new mode 100644 similarity index 82% rename from higan/sfc/chip/bsx/flash/flash.cpp rename to higan/sfc/slot/satellaview/satellaview.cpp index 1a3a1f77..5d2a6136 --- a/higan/sfc/chip/bsx/flash/flash.cpp +++ b/higan/sfc/slot/satellaview/satellaview.cpp @@ -1,24 +1,27 @@ -#ifdef BSX_CPP +#include -BSXFlash bsxflash; +#define SATELLAVIEW_CARTRIDGE_CPP +namespace SuperFamicom { -void BSXFlash::init() { +SatellaviewCartridge satellaviewcartridge; + +void SatellaviewCartridge::init() { } -void BSXFlash::load() { +void SatellaviewCartridge::load() { if(memory.size() == 0) { memory.map(allocate(1024 * 1024, 0xff), 1024 * 1024); } } -void BSXFlash::unload() { +void SatellaviewCartridge::unload() { memory.reset(); } -void BSXFlash::power() { +void SatellaviewCartridge::power() { } -void BSXFlash::reset() { +void SatellaviewCartridge::reset() { regs.command = 0; regs.write_old = 0x00; regs.write_new = 0x00; @@ -29,11 +32,11 @@ void BSXFlash::reset() { memory.write_protect(!regs.write_enable); } -unsigned BSXFlash::size() const { +unsigned SatellaviewCartridge::size() const { return memory.size(); } -uint8 BSXFlash::read(unsigned addr) { +uint8 SatellaviewCartridge::read(unsigned addr) { if(readonly) return memory.read(bus.mirror(addr, memory.size())); if(addr == 0x0002) { @@ -62,7 +65,7 @@ uint8 BSXFlash::read(unsigned addr) { return memory.read(addr); } -void BSXFlash::write(unsigned addr, uint8 data) { +void SatellaviewCartridge::write(unsigned addr, uint8 data) { if(readonly) return; if((addr & 0xff0000) == 0) { @@ -118,4 +121,4 @@ void BSXFlash::write(unsigned addr, uint8 data) { } } -#endif +} diff --git a/higan/sfc/chip/bsx/flash/flash.hpp b/higan/sfc/slot/satellaview/satellaview.hpp old mode 100755 new mode 100644 similarity index 81% rename from higan/sfc/chip/bsx/flash/flash.hpp rename to higan/sfc/slot/satellaview/satellaview.hpp index 1a0d467a..e1b8ffa0 --- a/higan/sfc/chip/bsx/flash/flash.hpp +++ b/higan/sfc/slot/satellaview/satellaview.hpp @@ -1,4 +1,4 @@ -struct BSXFlash : Memory { +struct SatellaviewCartridge : Memory { MappedRAM memory; bool readonly; @@ -24,4 +24,4 @@ private: } regs; }; -extern BSXFlash bsxflash; +extern SatellaviewCartridge satellaviewcartridge; diff --git a/higan/sfc/slot/slot.hpp b/higan/sfc/slot/slot.hpp new file mode 100644 index 00000000..43d4c2c7 --- /dev/null +++ b/higan/sfc/slot/slot.hpp @@ -0,0 +1,2 @@ +#include +#include diff --git a/higan/sfc/slot/sufamiturbo/serialization.cpp b/higan/sfc/slot/sufamiturbo/serialization.cpp new file mode 100644 index 00000000..3589f011 --- /dev/null +++ b/higan/sfc/slot/sufamiturbo/serialization.cpp @@ -0,0 +1,7 @@ +#ifdef SUFAMITURBO_CPP + +void SufamiTurboCartridge::serialize(serializer &s) { + s.array(ram.data(), ram.size()); +} + +#endif diff --git a/higan/sfc/slot/sufamiturbo/sufamiturbo.cpp b/higan/sfc/slot/sufamiturbo/sufamiturbo.cpp new file mode 100644 index 00000000..cfee0940 --- /dev/null +++ b/higan/sfc/slot/sufamiturbo/sufamiturbo.cpp @@ -0,0 +1,18 @@ +#include + +#define SUFAMITURBO_CPP +namespace SuperFamicom { + +#include "serialization.cpp" +SufamiTurboCartridge sufamiturboA; +SufamiTurboCartridge sufamiturboB; + +void SufamiTurboCartridge::load() { +} + +void SufamiTurboCartridge::unload() { + rom.reset(); + ram.reset(); +} + +} diff --git a/higan/sfc/slot/sufamiturbo/sufamiturbo.hpp b/higan/sfc/slot/sufamiturbo/sufamiturbo.hpp new file mode 100644 index 00000000..061dbe2f --- /dev/null +++ b/higan/sfc/slot/sufamiturbo/sufamiturbo.hpp @@ -0,0 +1,11 @@ +struct SufamiTurboCartridge { + MappedRAM rom; + MappedRAM ram; + + void load(); + void unload(); + void serialize(serializer&); +}; + +extern SufamiTurboCartridge sufamiturboA; +extern SufamiTurboCartridge sufamiturboB; diff --git a/higan/sfc/system/serialization.cpp b/higan/sfc/system/serialization.cpp index 66231c92..1f91b6de 100755 --- a/higan/sfc/system/serialization.cpp +++ b/higan/sfc/system/serialization.cpp @@ -59,7 +59,6 @@ void System::serialize_all(serializer &s) { if(cartridge.has_gb_slot()) icd2.serialize(s); if(cartridge.has_bs_cart()) bsxcartridge.serialize(s); - if(cartridge.has_st_slots()) sufamiturbo.serialize(s); if(cartridge.has_event()) event.serialize(s); if(cartridge.has_sa1()) sa1.serialize(s); if(cartridge.has_superfx()) superfx.serialize(s); @@ -73,6 +72,7 @@ void System::serialize_all(serializer &s) { if(cartridge.has_obc1()) obc1.serialize(s); if(cartridge.has_hsu1()) hsu1.serialize(s); if(cartridge.has_msu1()) msu1.serialize(s); + if(cartridge.has_st_slots()) sufamiturboA.serialize(s), sufamiturboB.serialize(s); } //perform dry-run state save: diff --git a/higan/sfc/system/system.cpp b/higan/sfc/system/system.cpp index f704158b..a69812b2 100755 --- a/higan/sfc/system/system.cpp +++ b/higan/sfc/system/system.cpp @@ -67,7 +67,6 @@ void System::init() { bsxsatellaview.init(); icd2.init(); bsxcartridge.init(); - bsxflash.init(); nss.init(); event.init(); sa1.init(); @@ -82,6 +81,7 @@ void System::init() { obc1.init(); hsu1.init(); msu1.init(); + satellaviewcartridge.init(); video.init(); audio.init(); @@ -122,8 +122,6 @@ void System::load() { if(expansion() == ExpansionPortDevice::BSX) bsxsatellaview.load(); if(cartridge.has_gb_slot()) icd2.load(); if(cartridge.has_bs_cart()) bsxcartridge.load(); - if(cartridge.has_bs_slot()) bsxflash.load(); - if(cartridge.has_st_slots()) sufamiturbo.load(); if(cartridge.has_nss_dip()) nss.load(); if(cartridge.has_event()) event.load(); if(cartridge.has_sa1()) sa1.load(); @@ -138,6 +136,8 @@ void System::load() { if(cartridge.has_obc1()) obc1.load(); if(cartridge.has_hsu1()) hsu1.load(); if(cartridge.has_msu1()) msu1.load(); + if(cartridge.has_bs_slot()) satellaviewcartridge.load(); + if(cartridge.has_st_slots()) sufamiturboA.load(), sufamiturboB.load(); serialize_init(); cheat.init(); @@ -147,8 +147,6 @@ void System::unload() { if(expansion() == ExpansionPortDevice::BSX) bsxsatellaview.unload(); if(cartridge.has_gb_slot()) icd2.unload(); if(cartridge.has_bs_cart()) bsxcartridge.unload(); - if(cartridge.has_bs_slot()) bsxflash.unload(); - if(cartridge.has_st_slots()) sufamiturbo.unload(); if(cartridge.has_nss_dip()) nss.unload(); if(cartridge.has_event()) event.unload(); if(cartridge.has_sa1()) sa1.unload(); @@ -163,6 +161,8 @@ void System::unload() { if(cartridge.has_obc1()) obc1.unload(); if(cartridge.has_hsu1()) hsu1.unload(); if(cartridge.has_msu1()) msu1.unload(); + if(cartridge.has_bs_slot()) satellaviewcartridge.unload(); + if(cartridge.has_st_slots()) sufamiturboA.unload(), sufamiturboB.unload(); } void System::power() { @@ -176,7 +176,6 @@ void System::power() { if(expansion() == ExpansionPortDevice::BSX) bsxsatellaview.power(); if(cartridge.has_gb_slot()) icd2.power(); if(cartridge.has_bs_cart()) bsxcartridge.power(); - if(cartridge.has_bs_slot()) bsxflash.power(); if(cartridge.has_nss_dip()) nss.power(); if(cartridge.has_event()) event.power(); if(cartridge.has_sa1()) sa1.power(); @@ -191,6 +190,7 @@ void System::power() { if(cartridge.has_obc1()) obc1.power(); if(cartridge.has_hsu1()) hsu1.power(); if(cartridge.has_msu1()) msu1.power(); + if(cartridge.has_bs_slot()) satellaviewcartridge.power(); reset(); } @@ -204,7 +204,6 @@ void System::reset() { if(expansion() == ExpansionPortDevice::BSX) bsxsatellaview.reset(); if(cartridge.has_gb_slot()) icd2.reset(); if(cartridge.has_bs_cart()) bsxcartridge.reset(); - if(cartridge.has_bs_slot()) bsxflash.reset(); if(cartridge.has_nss_dip()) nss.reset(); if(cartridge.has_event()) event.reset(); if(cartridge.has_sa1()) sa1.reset(); @@ -219,6 +218,7 @@ void System::reset() { if(cartridge.has_obc1()) obc1.reset(); if(cartridge.has_hsu1()) hsu1.reset(); if(cartridge.has_msu1()) msu1.reset(); + if(cartridge.has_bs_slot()) satellaviewcartridge.reset(); if(cartridge.has_gb_slot()) cpu.coprocessors.append(&icd2); if(cartridge.has_event()) cpu.coprocessors.append(&event); diff --git a/higan/target-ethos/ethos.cpp b/higan/target-ethos/ethos.cpp index 84547d94..4c7ba66d 100755 --- a/higan/target-ethos/ethos.cpp +++ b/higan/target-ethos/ethos.cpp @@ -79,7 +79,7 @@ Application::Application(int argc, char **argv) { hotkeySettings = new HotkeySettings; timingSettings = new TimingSettings; serverSettings = new ServerSettings; - driverSettings = new DriverSettings; + advancedSettings = new AdvancedSettings; settings = new Settings; cheatDatabase = new CheatDatabase; cheatEditor = new CheatEditor; @@ -106,7 +106,7 @@ Application::Application(int argc, char **argv) { utility->synchronizeRuby(); utility->updateShader(); - if(config->video.startFullScreen) utility->toggleFullScreen(); + if(config->video.startFullScreen && argc >= 2) utility->toggleFullScreen(); OS::processEvents(); if(argc >= 2) utility->loadMedia(argv[1]); diff --git a/higan/target-ethos/general/browser.cpp b/higan/target-ethos/general/browser.cpp index d0663f6a..e84bb832 100755 --- a/higan/target-ethos/general/browser.cpp +++ b/higan/target-ethos/general/browser.cpp @@ -28,7 +28,10 @@ Browser::Browser() { }; homeButton.onActivate = [&] { - setPath({userpath(), "Emulation/"}); + string libraryPath = string::read({configpath(), "higan/library.cfg"}).strip(); + if(libraryPath.empty()) libraryPath = {userpath(), "Emulation/"}; + if(libraryPath.endswith("/") == false) libraryPath.append("/"); + setPath(libraryPath); }; upButton.onActivate = [&] { @@ -164,7 +167,12 @@ void Browser::setPath(const string &path, unsigned selection) { string name = filename; name.rtrim<1>(suffix); fileList.append(name); - fileList.setImage(filenameList.size(), 0, {resource::game, sizeof resource::game}); + if(1 || file::exists({path, filename, "unverified"}) == false) { + fileList.setImage(filenameList.size(), 0, {resource::game, sizeof resource::game}); + } else { + //disabled for now due to performance penalty + fileList.setImage(filenameList.size(), 0, {resource::unverified, sizeof resource::unverified}); + } filenameList.append(filename); } } diff --git a/higan/target-ethos/resource/resource.bml b/higan/target-ethos/resource/resource.bml index 73ecec7a..763b03a6 100644 --- a/higan/target-ethos/resource/resource.bml +++ b/higan/target-ethos/resource/resource.bml @@ -3,3 +3,4 @@ resource name=resource binary id=up name=up.png binary id=folder name=folder.png binary id=game name=game.png + binary id=unverified name=unverified.png diff --git a/higan/target-ethos/resource/resource.cpp b/higan/target-ethos/resource/resource.cpp index 9a0c0559..f0f42c04 100755 --- a/higan/target-ethos/resource/resource.cpp +++ b/higan/target-ethos/resource/resource.cpp @@ -136,4 +136,60 @@ const uint8_t game[1490] = { 63,107,9,247,71,127,0,0,0,0,73,69,78,68,174,66,96,130, }; +const uint8_t unverified[1675] = { + 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0,0,115,122,122, + 244,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,6,66,73,68,65,84,88,133,229,151,217,115,84, + 85,30,199,191,231,119,238,146,78,210,183,59,107,147,116,167,151,132,152,72,132,208,128,27,13,9,104,160,28,202,146,161, + 3,79,83,214,164,242,52,207,62,251,224,195,252,13,62,88,53,37,102,134,69,12,250,162,165,14,58,162,65,81,17,179, + 66,7,59,91,111,233,108,244,96,210,33,73,247,237,123,231,161,23,110,98,2,1,103,158,230,86,253,234,156,170,123,239, + 249,124,206,249,253,234,87,117,128,255,247,135,253,158,159,143,118,116,119,106,76,239,37,157,94,253,234,139,191,125,242,36, + 107,208,239,129,103,152,126,94,177,213,32,67,218,135,109,199,186,78,60,201,58,252,73,225,26,99,231,188,190,131,242,169, + 147,29,88,211,56,159,137,70,207,184,234,247,254,28,154,24,8,254,79,5,142,118,116,119,106,132,243,222,67,62,217,225, + 170,195,59,189,223,224,224,179,45,40,85,20,30,143,68,30,91,226,177,4,142,118,116,119,130,211,133,87,94,123,69,42, + 171,182,225,131,43,55,161,105,192,157,169,89,28,122,174,5,102,197,194,167,195,225,199,146,216,182,64,91,71,151,159,56, + 191,248,122,215,105,241,233,150,167,240,246,197,175,0,157,65,32,2,17,67,48,52,7,223,129,93,48,91,44,60,22,10, + 159,113,55,236,187,25,26,239,31,251,175,8,180,117,116,249,193,232,194,159,94,247,75,45,45,77,24,15,207,195,251,180, + 19,7,118,185,112,247,94,18,43,171,105,16,99,24,11,207,227,57,111,19,20,139,149,71,67,83,219,146,120,164,64,91, + 71,151,159,49,186,112,224,240,33,105,207,158,102,68,226,255,6,24,64,44,187,243,249,68,18,139,75,171,16,56,129,24, + 195,100,100,1,251,91,159,202,74,132,31,45,241,80,129,60,124,223,33,159,84,235,172,67,96,124,6,85,21,102,16,17, + 194,211,119,241,237,207,227,152,187,187,4,129,19,4,226,16,136,192,115,239,188,187,119,66,177,150,241,72,40,116,198,221, + 224,221,82,98,203,62,208,126,172,251,20,35,186,224,245,249,164,29,14,59,62,191,54,130,180,154,1,39,2,103,12,137, + 123,247,113,127,37,5,81,224,16,57,135,40,80,97,78,68,184,118,115,12,110,143,27,190,246,118,137,129,125,212,126,188, + 251,15,219,22,104,63,214,125,10,76,191,232,61,152,133,255,235,251,81,112,70,133,99,38,202,206,69,158,135,103,71,129, + 19,132,220,156,51,194,15,131,147,112,215,123,224,59,210,38,211,22,18,191,73,65,30,190,247,69,159,84,227,112,224,155, + 159,126,1,129,65,224,4,119,109,5,170,203,205,32,98,208,52,29,43,43,41,168,25,173,112,244,198,84,8,156,192,25, + 97,110,97,17,187,154,60,80,172,86,33,58,21,58,237,118,183,254,52,53,57,48,182,169,192,145,227,93,127,4,195,251, + 173,47,100,119,254,93,255,120,1,46,16,161,209,85,13,171,82,12,98,12,101,74,49,26,221,54,164,83,42,150,150,215, + 10,223,100,225,188,48,231,68,88,72,36,209,220,232,130,181,204,42,132,67,225,51,70,137,7,41,120,235,45,210,117,246, + 81,149,221,37,181,182,54,227,198,208,36,56,123,144,87,145,115,216,42,20,112,198,178,117,64,12,196,24,86,83,234,186, + 111,178,115,130,73,22,81,91,109,133,44,8,224,140,16,28,159,197,97,223,126,212,185,93,178,78,236,211,223,158,192,213, + 171,122,125,189,119,96,121,121,209,207,4,19,111,110,116,98,62,177,84,200,125,185,165,4,205,245,59,64,68,88,76,174, + 224,202,181,0,198,166,230,145,74,169,133,221,154,100,17,12,217,230,100,171,84,240,236,30,55,146,203,107,72,165,51,216, + 183,219,133,196,92,28,125,125,215,83,200,104,175,230,79,96,93,10,166,38,6,238,120,26,90,71,102,98,81,191,217,98, + 229,77,13,78,220,189,151,4,39,194,174,134,26,84,150,149,130,17,67,40,150,192,226,210,202,131,156,115,66,133,181,4, + 109,207,55,98,109,85,133,36,114,212,213,150,67,49,155,80,93,105,198,254,221,78,68,67,97,156,59,255,97,42,147,86, + 79,94,253,242,236,103,91,22,225,212,248,192,168,167,161,117,36,30,139,250,45,214,50,190,211,227,192,210,242,26,246,63, + 227,130,32,16,136,17,130,147,179,80,85,173,80,108,2,113,232,58,208,224,172,66,173,205,10,103,109,5,44,102,19,136, + 8,149,229,165,24,25,30,197,63,206,93,78,111,132,111,42,96,148,152,142,70,252,86,107,57,63,122,112,55,100,89,0, + 67,182,251,217,42,21,36,147,107,40,41,150,80,95,87,133,213,149,20,158,105,178,67,49,155,10,29,146,136,80,102,41, + 198,224,208,109,244,252,253,114,58,147,86,95,219,8,223,82,96,189,68,180,179,185,201,195,157,142,26,164,83,42,136,8, + 178,40,64,18,57,100,81,64,131,179,26,110,71,37,148,210,34,16,35,176,28,220,170,152,48,56,20,64,79,207,229,116, + 38,157,222,20,254,80,129,188,132,171,222,59,50,60,28,232,116,56,106,72,42,50,97,240,86,12,153,140,134,88,252,30, + 150,146,171,112,218,203,193,11,13,42,11,87,204,121,120,239,67,225,143,20,0,128,208,68,255,168,211,179,119,100,104,232, + 182,159,139,197,188,178,170,28,247,151,83,80,211,26,154,118,238,128,82,106,2,203,117,71,34,6,115,105,81,246,216,123, + 122,211,170,150,57,249,245,23,239,110,9,223,150,64,78,34,104,119,182,4,98,145,200,201,138,138,42,254,114,219,30,216, + 119,88,97,46,41,42,180,102,34,134,210,146,34,12,15,7,240,94,79,111,122,117,109,229,116,223,151,239,253,51,183,132, + 254,36,2,4,64,2,80,4,64,14,79,14,133,170,108,158,224,108,60,126,130,139,37,188,169,209,9,77,211,11,69,87, + 82,44,99,104,56,128,119,123,46,169,139,191,46,252,249,135,190,75,87,1,8,57,70,190,225,105,219,21,16,1,200,27, + 99,58,18,8,91,202,107,39,98,177,217,227,110,151,157,219,107,170,161,105,58,138,77,89,248,217,158,75,234,194,124,244, + 47,253,63,126,220,103,128,231,5,8,217,107,128,110,60,145,205,4,120,78,64,50,68,65,98,102,58,24,43,85,42,38, + 127,25,139,190,228,114,216,169,206,97,195,224,208,109,156,237,185,164,198,167,39,222,24,233,191,114,61,7,55,66,141,247, + 15,29,64,230,81,2,66,78,66,200,9,228,133,100,0,242,220,204,68,188,200,100,14,7,39,166,219,18,137,69,250,248, + 211,43,153,104,248,206,155,163,195,95,223,48,64,141,64,45,23,25,195,184,165,128,102,176,231,134,49,47,198,1,136,11, + 115,161,184,44,149,196,18,191,174,30,142,132,110,253,53,24,184,126,99,3,72,221,16,105,67,20,82,240,176,171,89,190, + 14,36,195,104,12,209,32,152,223,101,30,144,218,16,107,134,113,93,33,110,231,110,152,79,135,132,245,169,201,195,141,133, + 149,49,236,222,40,179,110,215,143,43,176,217,63,70,120,126,141,141,185,222,214,243,31,50,77,124,34,176,20,164,223,0, + 0,0,0,73,69,78,68,174,66,96,130, +}; + }; diff --git a/higan/target-ethos/resource/resource.hpp b/higan/target-ethos/resource/resource.hpp index 53df5c29..5d908b05 100755 --- a/higan/target-ethos/resource/resource.hpp +++ b/higan/target-ethos/resource/resource.hpp @@ -3,4 +3,5 @@ namespace resource { extern const uint8_t up[652]; extern const uint8_t folder[1176]; extern const uint8_t game[1490]; + extern const uint8_t unverified[1675]; }; diff --git a/higan/target-ethos/resource/unverified.png b/higan/target-ethos/resource/unverified.png new file mode 100644 index 0000000000000000000000000000000000000000..8a150b847114e2468c61b01cf0119c7fbca15f11 GIT binary patch literal 1675 zcmV;626Xv}P)hA?9>>4uckYr-(ziQnlXRz-gqTQ#(105a322}k%95c2 zPgB;U@-)vr`{2X;4L(>kC1!?24Emy_4mzSiQ4zC32RmDD>1_01(jiIr?R)2;7j9w# z0cW1(R{iRns(bJGe9rm(>Q{Au|M!Reo}Z6)ba!e@?j~n0{Wd z)gVLKhi%8YPCUsv{7K;&W9PiSgYv199az&ipNU4#xa#-*9GVyi{!aytc64`Yg!A4* zKH1@_!#lm-;NY_@C{+|5k3=3@;;{sdc64`w(}h=Fdqpa%w&8;-H=$|3ovB$Idaea# z#lok<;m4BLwm@4)m!CMl_zPJb#(c`=)#{~_e(7;O&AZ)!~3)o2X?t|_g)e!t7#Bp7z@wiId2mbi#Rdydg!|1jGBSFJyQAUH^CiE)b#7RSm0B z3}OsrN--MUHl$N3mX_BF-(=yuFy};ANF>qR=z_J(DuhGfGe(IADR}EG(slMxmE9$^ zwl?F&&?Go}kXMm&*eVoo#@a!HplFMsIr8C&K+l9nj9DRM)Q^;tq=1*W<3Z^Co?sytnM`mJCzu98t zO$|=my_WDu@WOC_oZ9WKlqavl?zkC6v-45F@Z0+^U!`I21rn&*gL`o!%7w zP=UOJtKK^@JRInBIBG~LGGXvm44I6ESo|KAlB;mq%fSl`DhpT4d3f(b;g1vmfY3z$ zsME7|WN7HNpNqx3vZ@^Sms3#F8k%ds-bB*icMMg*`7=4!hG~E{Xc%(XMpDg z2-$0ZZak6A1b9wBGDJaQW;z%vRVpTb8H>K;a@eWPVZ-3iZJh17q{gQw-Wch>ayrrQ#UMf&*DE178c&YPpdU*9l5jX*6I z8N;}xfM&4ghA}V30f-B8p|~uS#1g-*9*%@={WTc4eq#ej-4JO*6jJc8t69DdB*SP7 z(IA-LWgd{)5Nn2UT_JAgZkSJpg!QS(!;OWNG3?$bvu@XqE3nx=MtFXWjk(^|^B*!z Vd?K(Eq~8Dl002ovPDHLkV1lXf8uI`E literal 0 HcmV?d00001 diff --git a/higan/target-ethos/settings/advanced.cpp b/higan/target-ethos/settings/advanced.cpp new file mode 100644 index 00000000..3d3973f9 --- /dev/null +++ b/higan/target-ethos/settings/advanced.cpp @@ -0,0 +1,81 @@ +AdvancedSettings *advancedSettings = nullptr; + +AdvancedSettings::AdvancedSettings() { + driverTitle.setFont(application->titleFont); + driverTitle.setText("Driver Selection"); + videoLabel.setText("Video:"); + audioLabel.setText("Audio:"); + inputLabel.setText("Input:"); + libraryTitle.setFont(application->titleFont); + libraryTitle.setText("Game Library Path"); + libraryLabel.setText("Path:"); + libraryPath.setEditable(false); + string path = string::read({configpath(), "higan/library.cfg"}).strip().transform("\\", "/"); + if(path.empty()) path = {userpath(), "Emulation/"}; + if(path.endswith("/") == false) path.append("/"); + libraryPath.setText(path); + libraryBrowse.setText("Browse ..."); + infoLabel.setFont(application->boldFont); + string profile; + #if defined(PROFILE_ACCURACY) + profile = "Accuracy"; + #elif defined(PROFILE_BALANCED) + profile = "Balanced"; + #elif defined(PROFILE_PERFORMANCE) + profile = "Performance"; + #endif + infoLabel.setText({ + Emulator::Name, " v", Emulator::Version, "\n", + " ", profile, " Profile\n", + " Author: byuu\n", + " Website: http://byuu.org/\n", + " License: GPLv3" + }); + + lstring list; + + list.split(";", video.driver_list()); + for(unsigned n = 0; n < list.size(); n++) { + videoDriver.append(list[n]); + if(list[n] == config->video.driver) videoDriver.setSelection(n); + } + + list.split(";", audio.driver_list()); + for(unsigned n = 0; n < list.size(); n++) { + audioDriver.append(list[n]); + if(list[n] == config->audio.driver) audioDriver.setSelection(n); + } + + list.split(";", input.driver_list()); + for(unsigned n = 0; n < list.size(); n++) { + inputDriver.append(list[n]); + if(list[n] == config->input.driver) inputDriver.setSelection(n); + } + + append(driverTitle, {~0, 0}, 5); + append(driverLayout, {~0, 0}, 15); + driverLayout.append(videoLabel, {0, 0}, 5); + driverLayout.append(videoDriver, {~0, 0}, 5); + driverLayout.append(audioLabel, {0, 0}, 5); + driverLayout.append(audioDriver, {~0, 0}, 5); + driverLayout.append(inputLabel, {0, 0}, 5); + driverLayout.append(inputDriver, {~0, 0}); + append(libraryTitle, {~0, 0}, 5); + append(libraryLayout, {~0, 0}, 15); + libraryLayout.append(libraryLabel, {0, 0}, 5); + libraryLayout.append(libraryPath, {~0, 0}, 5); + libraryLayout.append(libraryBrowse, {80, 0}); + append(spacer, {~0, ~0}); + append(infoLabel, {~0, 0}); + + videoDriver.onChange = [&] { config->video.driver = videoDriver.text(); }; + audioDriver.onChange = [&] { config->audio.driver = audioDriver.text(); }; + inputDriver.onChange = [&] { config->input.driver = inputDriver.text(); }; + + libraryBrowse.onActivate = [&] { + string path = DialogWindow::folderSelect(Window::none(), userpath()); + if(path.empty()) return; + file::write({configpath(), "higan/library.cfg"}, path); + libraryPath.setText(path); + }; +} diff --git a/higan/target-ethos/settings/advanced.hpp b/higan/target-ethos/settings/advanced.hpp new file mode 100644 index 00000000..c6d86c0d --- /dev/null +++ b/higan/target-ethos/settings/advanced.hpp @@ -0,0 +1,23 @@ +struct AdvancedSettings : SettingsLayout { + Label driverTitle; + HorizontalLayout driverLayout; + Label videoLabel; + ComboBox videoDriver; + Label audioLabel; + ComboBox audioDriver; + Label inputLabel; + ComboBox inputDriver; + + Label libraryTitle; + HorizontalLayout libraryLayout; + Label libraryLabel; + LineEdit libraryPath; + Button libraryBrowse; + + Widget spacer; + Label infoLabel; + + AdvancedSettings(); +}; + +extern AdvancedSettings *advancedSettings; diff --git a/higan/target-ethos/settings/driver.cpp b/higan/target-ethos/settings/driver.cpp deleted file mode 100755 index 324f334a..00000000 --- a/higan/target-ethos/settings/driver.cpp +++ /dev/null @@ -1,42 +0,0 @@ -DriverSettings *driverSettings = nullptr; - -DriverSettings::DriverSettings() { - title.setFont(application->titleFont); - title.setText("Driver Configuration"); - videoLabel.setText("Video:"); - audioLabel.setText("Audio:"); - inputLabel.setText("Input:"); - - lstring list; - - list.split(";", video.driver_list()); - for(unsigned n = 0; n < list.size(); n++) { - videoDriver.append(list[n]); - if(list[n] == config->video.driver) videoDriver.setSelection(n); - } - - list.split(";", audio.driver_list()); - for(unsigned n = 0; n < list.size(); n++) { - audioDriver.append(list[n]); - if(list[n] == config->audio.driver) audioDriver.setSelection(n); - } - - list.split(";", input.driver_list()); - for(unsigned n = 0; n < list.size(); n++) { - inputDriver.append(list[n]); - if(list[n] == config->input.driver) inputDriver.setSelection(n); - } - - append(title, {~0, 0}, 5); - append(driverLayout, {~0, 0}); - driverLayout.append(videoLabel, {0, 0}, 5); - driverLayout.append(videoDriver, {~0, 0}, 5); - driverLayout.append(audioLabel, {0, 0}, 5); - driverLayout.append(audioDriver, {~0, 0}, 5); - driverLayout.append(inputLabel, {0, 0}, 5); - driverLayout.append(inputDriver, {~0, 0}); - - videoDriver.onChange = [&] { config->video.driver = videoDriver.text(); }; - audioDriver.onChange = [&] { config->audio.driver = audioDriver.text(); }; - inputDriver.onChange = [&] { config->input.driver = inputDriver.text(); }; -} diff --git a/higan/target-ethos/settings/driver.hpp b/higan/target-ethos/settings/driver.hpp deleted file mode 100755 index aa847d4c..00000000 --- a/higan/target-ethos/settings/driver.hpp +++ /dev/null @@ -1,14 +0,0 @@ -struct DriverSettings : SettingsLayout { - Label title; - HorizontalLayout driverLayout; - Label videoLabel; - ComboBox videoDriver; - Label audioLabel; - ComboBox audioDriver; - Label inputLabel; - ComboBox inputDriver; - - DriverSettings(); -}; - -extern DriverSettings *driverSettings; diff --git a/higan/target-ethos/settings/settings.cpp b/higan/target-ethos/settings/settings.cpp index ec06f9cf..d2e7578f 100755 --- a/higan/target-ethos/settings/settings.cpp +++ b/higan/target-ethos/settings/settings.cpp @@ -5,7 +5,7 @@ #include "hotkey.cpp" #include "timing.cpp" #include "server.cpp" -#include "driver.cpp" +#include "advanced.cpp" Settings *settings = nullptr; void SettingsLayout::append(Sizable &sizable, const Size &size, unsigned spacing) { @@ -33,7 +33,7 @@ Settings::Settings() { panelList.append("Hotkeys"); panelList.append("Timing"); panelList.append("Server"); - panelList.append("Driver"); + panelList.append("Advanced"); append(layout); layout.append(panelList, {120, ~0}, 5); @@ -43,7 +43,7 @@ Settings::Settings() { append(*hotkeySettings); append(*timingSettings); append(*serverSettings); - append(*driverSettings); + append(*advancedSettings); onClose = [&] { timingSettings->analysis.stop = true; @@ -63,7 +63,7 @@ void Settings::panelChanged() { hotkeySettings->setVisible(false); timingSettings->setVisible(false); serverSettings->setVisible(false); - driverSettings->setVisible(false); + advancedSettings->setVisible(false); if(panelList.selected() == false) return; switch(panelList.selection()) { @@ -73,6 +73,6 @@ void Settings::panelChanged() { case 3: return hotkeySettings->setVisible(); case 4: return timingSettings->setVisible(); case 5: return serverSettings->setVisible(); - case 6: return driverSettings->setVisible(); + case 6: return advancedSettings->setVisible(); } } diff --git a/higan/target-ethos/settings/settings.hpp b/higan/target-ethos/settings/settings.hpp index 40a24481..cae5a316 100755 --- a/higan/target-ethos/settings/settings.hpp +++ b/higan/target-ethos/settings/settings.hpp @@ -12,7 +12,7 @@ struct SettingsLayout : HorizontalLayout { #include "hotkey.hpp" #include "timing.hpp" #include "server.hpp" -#include "driver.hpp" +#include "advanced.hpp" struct Settings : Window { HorizontalLayout layout; diff --git a/higan/target-ethos/utility/utility.cpp b/higan/target-ethos/utility/utility.cpp index 97497b2a..5cc9a3f0 100755 --- a/higan/target-ethos/utility/utility.cpp +++ b/higan/target-ethos/utility/utility.cpp @@ -41,7 +41,6 @@ void Utility::loadMedia(string pathname) { void Utility::loadMedia(Emulator::Interface *emulator, Emulator::Interface::Media &media) { string pathname = browser->select({"Load ", media.name}, media.type); if(!directory::exists(pathname)) return; - if(!file::exists({pathname, "manifest.bml"})) return; return loadMedia(emulator, media, pathname); } @@ -53,7 +52,7 @@ void Utility::loadMedia(Emulator::Interface *emulator, Emulator::Interface::Medi path(media.id) = pathname; this->pathname.append(pathname); - system().load(media.id, string::read({pathname, "manifest.bml"})); + system().load(media.id); system().power(); presentation->setSystemName(media.name); @@ -67,7 +66,7 @@ void Utility::loadRequest(unsigned id, const string &name, const string &type) { path(id) = pathname; this->pathname.append(pathname); - system().load(id, string::read({pathname, "manifest.bml"})); + system().load(id); } //request from emulation core to load non-volatile media file diff --git a/purify/nall/Makefile b/purify/nall/Makefile index 9929d101..f422f49d 100644 --- a/purify/nall/Makefile +++ b/purify/nall/Makefile @@ -36,16 +36,16 @@ endif ifeq ($(compiler),) ifeq ($(platform),win) - compiler := gcc + compiler := g++ else ifeq ($(platform),osx) - compiler := gcc-mp-4.7 + compiler := g++-mp-4.7 else - compiler := gcc-4.7 + compiler := g++-4.7 endif endif -c := $(compiler) -std=gnu99 -cpp := $(subst cc,++,$(compiler)) -std=gnu++11 +c := $(compiler) -x c -std=gnu99 +cpp := $(compiler) -std=gnu++11 ifeq ($(arch),x86) c := $(c) -m32 diff --git a/purify/nall/file.hpp b/purify/nall/file.hpp index be9fc086..80b918a8 100644 --- a/purify/nall/file.hpp +++ b/purify/nall/file.hpp @@ -98,6 +98,14 @@ namespace nall { return true; } + static bool create(const string &filename) { + //create an empty file (will replace existing files) + file fp; + if(fp.open(filename, mode::write) == false) return false; + fp.close(); + return true; + } + static string sha256(const string &filename) { auto buffer = read(filename); return nall::sha256(buffer.data(), buffer.size()); diff --git a/purify/nall/stream/stream.hpp b/purify/nall/stream/stream.hpp index 9d937729..043eecba 100644 --- a/purify/nall/stream/stream.hpp +++ b/purify/nall/stream/stream.hpp @@ -48,6 +48,15 @@ struct stream { while(length--) *data++ = read(); } + string text() const { + string buffer; + buffer.resize(size() + 1); + buffer[size()] = 0; + seek(0); + read((uint8_t*)buffer(), size()); + return buffer; + } + void writel(uintmax_t data, unsigned length = 1) const { while(length--) { write(data); diff --git a/purify/nall/string/base.hpp b/purify/nall/string/base.hpp index abf21735..d5f85ca4 100644 --- a/purify/nall/string/base.hpp +++ b/purify/nall/string/base.hpp @@ -23,6 +23,7 @@ namespace nall { struct string { inline static string read(const string &filename); + inline static string date(); inline static string time(); inline static string datetime(); diff --git a/purify/nall/string/platform.hpp b/purify/nall/string/platform.hpp index 5c44a313..90b6d6b8 100644 --- a/purify/nall/string/platform.hpp +++ b/purify/nall/string/platform.hpp @@ -33,11 +33,13 @@ string realpath(const string &name) { return result; } +// /home/username/ +// c:/users/username/ string userpath() { string result; #ifdef _WIN32 wchar_t path[PATH_MAX] = L""; - SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, path); + SHGetFolderPathW(0, CSIDL_PROFILE | CSIDL_FLAG_CREATE, 0, 0, path); result = (const char*)utf8_t(path); result.transform("\\", "/"); #else @@ -51,20 +53,30 @@ string userpath() { return result; } +// /home/username/.config/ +// c:/users/username/appdata/roaming/ string configpath() { + string result; #ifdef _WIN32 - return userpath(); + wchar_t path[PATH_MAX] = L""; + SHGetFolderPathW(0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, 0, 0, path); + result = (const char*)utf8_t(path); + result.transform("\\", "/"); #else - return {userpath(), ".config/"}; + result = {userpath(), ".config/"}; #endif + if(result.empty()) result = "."; + if(result.endswith("/") == false) result.append("/"); + return result; } string temppath() { #ifdef _WIN32 wchar_t path[PATH_MAX] = L""; GetTempPathW(PATH_MAX, path); -//path.transform("\\", "/"); - return (const char*)utf8_t(path); + string result = (const char*)utf8_t(path); + result.transform("\\", "/"); + return result; #else return "/tmp/"; #endif diff --git a/purify/nall/thread.hpp b/purify/nall/thread.hpp index 3368d15d..de894f2d 100644 --- a/purify/nall/thread.hpp +++ b/purify/nall/thread.hpp @@ -13,6 +13,7 @@ namespace nall { struct thread { thread(function entryPoint) : entryPoint(entryPoint), completed(false), dead(false) { + initialize(); pthread_create(&pthread, NULL, thread_entry_point, (void*)this); } @@ -30,11 +31,28 @@ namespace nall { pthread_join(pthread, NULL); } + static bool primary() { + initialize(); + return pthread_equal(primaryThread(), pthread_self()); + } + private: pthread_t pthread; function entryPoint; volatile bool completed, dead; friend void* thread_entry_point(void*); + + static void initialize() { + static bool initialized = false; + if(initialized) return; + initialized = true; + primaryThread() = pthread_self(); + } + + static pthread_t& primaryThread() { + static pthread_t thread; + return thread; + } }; void* thread_entry_point(void *parameter) { @@ -50,6 +68,7 @@ namespace nall { struct thread { thread(function entryPoint) : entryPoint(entryPoint), completed(false), dead(false) { + initialize(); hthread = CreateThread(NULL, 0, thread_entry_point, (void*)this, 0, NULL); } @@ -68,11 +87,28 @@ namespace nall { CloseHandle(hthread); } + static bool primary() { + initialize(); + return primaryThread() == GetCurrentThreadId(); + } + private: HANDLE hthread; function entryPoint; volatile bool completed, dead; friend DWORD WINAPI thread_entry_point(LPVOID); + + static void initialize() { + static bool initialized = false; + if(initialized) return; + initialized = true; + primaryThread() = GetCurrentThreadId(); + } + + static DWORD& primaryThread() { + static DWORD thread; + return thread; + } }; inline DWORD WINAPI thread_entry_point(LPVOID parameter) { diff --git a/purify/purify.cpp b/purify/purify.cpp index 18c9f519..698ee8d6 100644 --- a/purify/purify.cpp +++ b/purify/purify.cpp @@ -16,10 +16,12 @@ struct Application : Window { Button browseButton; ListView fileList; ProgressBar progressBar; + Label libraryPath; HorizontalLayout controlLayout; Button selectAllButton; Button unselectAllButton; Widget spacer; + Button setPathButton; Button purifyButton; lstring filenameList; @@ -41,15 +43,20 @@ Application::Application() { exit(0); } + string path = string::read({configpath(), "higan/library.cfg"}).strip(); + if(path.empty()) path = {userpath(), "Emulation/"}; + setFrameGeometry({64, 64, 720, 480}); - setTitle("purify v03"); + setTitle("purify v03.01"); layout.setMargin(5); pathLabel.setText("Path:"); browseButton.setText("Browse ..."); fileList.setCheckable(true); + libraryPath.setText({"Library Path: ", path}); selectAllButton.setText("Select All"); unselectAllButton.setText("Unselect All"); + setPathButton.setText("Set Path ..."); purifyButton.setText("Purify"); append(layout); @@ -59,11 +66,13 @@ Application::Application() { pathLayout.append(browseButton, {80, 0}); layout.append(fileList, {~0, ~0}, 5); layout.append(progressBar, {~0, 0}, 5); + layout.append(libraryPath, {~0, 0}, 5); layout.append(controlLayout, {~0, 0}); controlLayout.append(selectAllButton, {100, 0}, 5); controlLayout.append(unselectAllButton, {100, 0}, 5); controlLayout.append(spacer, {~0, 0}); - controlLayout.append(purifyButton, {80, 0}); + controlLayout.append(setPathButton, {100, 0}, 5); + controlLayout.append(purifyButton, {100, 0}); setVisible(); @@ -87,11 +96,24 @@ Application::Application() { for(unsigned n = 0; n < filenameList.size(); n++) fileList.setChecked(n, false); }; + setPathButton.onActivate = [&] { + string path = DialogWindow::folderSelect(*this, userpath()); + if(path.empty()) return; + + directory::create({configpath(), "higan/"}); + file::write({configpath(), "higan/library.cfg"}, path); + libraryPath.setText({"Library Path: ", path}); + }; + purifyButton.onActivate = {&Application::purify, this}; } void Application::scanPath() { string path = pathEdit.text(); + path.transform("\\", "/"); + if(path.endswith("/") == false) path.append("/"); + pathEdit.setText(path); + fileList.reset(); filenameList.reset(); scanPath(path, path); @@ -117,7 +139,11 @@ void Application::scanPath(const string &path, const string &basepath) { ) { fileList.append(string{path, file}.ltrim<1>(basepath).rtrim<1>("/")); filenameList.append({path, file}); - fileList.setImage(filenameList.size() - 1, 0, {resource::game, sizeof resource::game}); + if(file::exists({path, file, "unverified"}) == false) { + fileList.setImage(filenameList.size() - 1, 0, {resource::game, sizeof resource::game}); + } else { + fileList.setImage(filenameList.size() - 1, 0, {resource::unverified, sizeof resource::unverified}); + } } else if( file.endswith(".fc") || file.endswith(".nes") || file.endswith(".sfc") || file.endswith(".smc") @@ -125,14 +151,14 @@ void Application::scanPath(const string &path, const string &basepath) { || file.endswith(".gb") || file.endswith(".gbc") || file.endswith(".gba") - || file.endswith(".bpa") || file.endswith(".zip") + || file.endswith(".zip") ) { fileList.append(string{path, file}.ltrim<1>(basepath)); filenameList.append({path, file}); - if(file.endswith(".bpa") || file.endswith(".zip")) { - fileList.setImage(filenameList.size() - 1, 0, {resource::archive, sizeof resource::archive}); - } else { + if(file.endswith(".zip") == false) { fileList.setImage(filenameList.size() - 1, 0, {resource::file, sizeof resource::file}); + } else { + fileList.setImage(filenameList.size() - 1, 0, {resource::archive, sizeof resource::archive}); } } } diff --git a/purify/resource/resource.bml b/purify/resource/resource.bml index 3ad4331b..20a4694f 100644 --- a/purify/resource/resource.bml +++ b/purify/resource/resource.bml @@ -1,4 +1,5 @@ resource name=resource binary id=game name=game.png + binary id=unverified name=unverified.png binary id=file name=file.png binary id=archive name=archive.png diff --git a/purify/resource/resource.cpp b/purify/resource/resource.cpp index 274c56de..b74d745e 100644 --- a/purify/resource/resource.cpp +++ b/purify/resource/resource.cpp @@ -50,6 +50,62 @@ const uint8_t game[1490] = { 63,107,9,247,71,127,0,0,0,0,73,69,78,68,174,66,96,130, }; +const uint8_t unverified[1675] = { + 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0,0,115,122,122, + 244,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,6,66,73,68,65,84,88,133,229,151,217,115,84, + 85,30,199,191,231,119,238,146,78,210,183,59,107,147,116,167,151,132,152,72,132,208,128,27,13,9,104,160,28,202,146,161, + 3,79,83,214,164,242,52,207,62,251,224,195,252,13,62,88,53,37,102,134,69,12,250,162,165,14,58,162,65,81,17,179, + 66,7,59,91,111,233,108,244,96,210,33,73,247,237,123,231,161,23,110,98,2,1,103,158,230,86,253,234,156,170,123,239, + 249,124,206,249,253,234,87,117,128,255,247,135,253,158,159,143,118,116,119,106,76,239,37,157,94,253,234,139,191,125,242,36, + 107,208,239,129,103,152,126,94,177,213,32,67,218,135,109,199,186,78,60,201,58,252,73,225,26,99,231,188,190,131,242,169, + 147,29,88,211,56,159,137,70,207,184,234,247,254,28,154,24,8,254,79,5,142,118,116,119,106,132,243,222,67,62,217,225, + 170,195,59,189,223,224,224,179,45,40,85,20,30,143,68,30,91,226,177,4,142,118,116,119,130,211,133,87,94,123,69,42, + 171,182,225,131,43,55,161,105,192,157,169,89,28,122,174,5,102,197,194,167,195,225,199,146,216,182,64,91,71,151,159,56, + 191,248,122,215,105,241,233,150,167,240,246,197,175,0,157,65,32,2,17,67,48,52,7,223,129,93,48,91,44,60,22,10, + 159,113,55,236,187,25,26,239,31,251,175,8,180,117,116,249,193,232,194,159,94,247,75,45,45,77,24,15,207,195,251,180, + 19,7,118,185,112,247,94,18,43,171,105,16,99,24,11,207,227,57,111,19,20,139,149,71,67,83,219,146,120,164,64,91, + 71,151,159,49,186,112,224,240,33,105,207,158,102,68,226,255,6,24,64,44,187,243,249,68,18,139,75,171,16,56,129,24, + 195,100,100,1,251,91,159,202,74,132,31,45,241,80,129,60,124,223,33,159,84,235,172,67,96,124,6,85,21,102,16,17, + 194,211,119,241,237,207,227,152,187,187,4,129,19,4,226,16,136,192,115,239,188,187,119,66,177,150,241,72,40,116,198,221, + 224,221,82,98,203,62,208,126,172,251,20,35,186,224,245,249,164,29,14,59,62,191,54,130,180,154,1,39,2,103,12,137, + 123,247,113,127,37,5,81,224,16,57,135,40,80,97,78,68,184,118,115,12,110,143,27,190,246,118,137,129,125,212,126,188, + 251,15,219,22,104,63,214,125,10,76,191,232,61,152,133,255,235,251,81,112,70,133,99,38,202,206,69,158,135,103,71,129, + 19,132,220,156,51,194,15,131,147,112,215,123,224,59,210,38,211,22,18,191,73,65,30,190,247,69,159,84,227,112,224,155, + 159,126,1,129,65,224,4,119,109,5,170,203,205,32,98,208,52,29,43,43,41,168,25,173,112,244,198,84,8,156,192,25, + 97,110,97,17,187,154,60,80,172,86,33,58,21,58,237,118,183,254,52,53,57,48,182,169,192,145,227,93,127,4,195,251, + 173,47,100,119,254,93,255,120,1,46,16,161,209,85,13,171,82,12,98,12,101,74,49,26,221,54,164,83,42,150,150,215, + 10,223,100,225,188,48,231,68,88,72,36,209,220,232,130,181,204,42,132,67,225,51,70,137,7,41,120,235,45,210,117,246, + 81,149,221,37,181,182,54,227,198,208,36,56,123,144,87,145,115,216,42,20,112,198,178,117,64,12,196,24,86,83,234,186, + 111,178,115,130,73,22,81,91,109,133,44,8,224,140,16,28,159,197,97,223,126,212,185,93,178,78,236,211,223,158,192,213, + 171,122,125,189,119,96,121,121,209,207,4,19,111,110,116,98,62,177,84,200,125,185,165,4,205,245,59,64,68,88,76,174, + 224,202,181,0,198,166,230,145,74,169,133,221,154,100,17,12,217,230,100,171,84,240,236,30,55,146,203,107,72,165,51,216, + 183,219,133,196,92,28,125,125,215,83,200,104,175,230,79,96,93,10,166,38,6,238,120,26,90,71,102,98,81,191,217,98, + 229,77,13,78,220,189,151,4,39,194,174,134,26,84,150,149,130,17,67,40,150,192,226,210,202,131,156,115,66,133,181,4, + 109,207,55,98,109,85,133,36,114,212,213,150,67,49,155,80,93,105,198,254,221,78,68,67,97,156,59,255,97,42,147,86, + 79,94,253,242,236,103,91,22,225,212,248,192,168,167,161,117,36,30,139,250,45,214,50,190,211,227,192,210,242,26,246,63, + 227,130,32,16,136,17,130,147,179,80,85,173,80,108,2,113,232,58,208,224,172,66,173,205,10,103,109,5,44,102,19,136, + 8,149,229,165,24,25,30,197,63,206,93,78,111,132,111,42,96,148,152,142,70,252,86,107,57,63,122,112,55,100,89,0, + 67,182,251,217,42,21,36,147,107,40,41,150,80,95,87,133,213,149,20,158,105,178,67,49,155,10,29,146,136,80,102,41, + 198,224,208,109,244,252,253,114,58,147,86,95,219,8,223,82,96,189,68,180,179,185,201,195,157,142,26,164,83,42,136,8, + 178,40,64,18,57,100,81,64,131,179,26,110,71,37,148,210,34,16,35,176,28,220,170,152,48,56,20,64,79,207,229,116, + 38,157,222,20,254,80,129,188,132,171,222,59,50,60,28,232,116,56,106,72,42,50,97,240,86,12,153,140,134,88,252,30, + 150,146,171,112,218,203,193,11,13,42,11,87,204,121,120,239,67,225,143,20,0,128,208,68,255,168,211,179,119,100,104,232, + 182,159,139,197,188,178,170,28,247,151,83,80,211,26,154,118,238,128,82,106,2,203,117,71,34,6,115,105,81,246,216,123, + 122,211,170,150,57,249,245,23,239,110,9,223,150,64,78,34,104,119,182,4,98,145,200,201,138,138,42,254,114,219,30,216, + 119,88,97,46,41,42,180,102,34,134,210,146,34,12,15,7,240,94,79,111,122,117,109,229,116,223,151,239,253,51,183,132, + 254,36,2,4,64,2,80,4,64,14,79,14,133,170,108,158,224,108,60,126,130,139,37,188,169,209,9,77,211,11,69,87, + 82,44,99,104,56,128,119,123,46,169,139,191,46,252,249,135,190,75,87,1,8,57,70,190,225,105,219,21,16,1,200,27, + 99,58,18,8,91,202,107,39,98,177,217,227,110,151,157,219,107,170,161,105,58,138,77,89,248,217,158,75,234,194,124,244, + 47,253,63,126,220,103,128,231,5,8,217,107,128,110,60,145,205,4,120,78,64,50,68,65,98,102,58,24,43,85,42,38, + 127,25,139,190,228,114,216,169,206,97,195,224,208,109,156,237,185,164,198,167,39,222,24,233,191,114,61,7,55,66,141,247, + 15,29,64,230,81,2,66,78,66,200,9,228,133,100,0,242,220,204,68,188,200,100,14,7,39,166,219,18,137,69,250,248, + 211,43,153,104,248,206,155,163,195,95,223,48,64,141,64,45,23,25,195,184,165,128,102,176,231,134,49,47,198,1,136,11, + 115,161,184,44,149,196,18,191,174,30,142,132,110,253,53,24,184,126,99,3,72,221,16,105,67,20,82,240,176,171,89,190, + 14,36,195,104,12,209,32,152,223,101,30,144,218,16,107,134,113,93,33,110,231,110,152,79,135,132,245,169,201,195,141,133, + 149,49,236,222,40,179,110,215,143,43,176,217,63,70,120,126,141,141,185,222,214,243,31,50,77,124,34,176,20,164,223,0, + 0,0,0,73,69,78,68,174,66,96,130, +}; + const uint8_t file[844] = { 137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,32,0,0,0,32,8,6,0,0,0,115,122,122, 244,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,3,3,73,68,65,84,88,133,229,151,79,110,212, diff --git a/purify/resource/resource.hpp b/purify/resource/resource.hpp index 7e49e44f..512a061a 100644 --- a/purify/resource/resource.hpp +++ b/purify/resource/resource.hpp @@ -1,5 +1,6 @@ namespace resource { extern const uint8_t game[1490]; + extern const uint8_t unverified[1675]; extern const uint8_t file[844]; extern const uint8_t archive[1067]; }; diff --git a/purify/resource/unverified.png b/purify/resource/unverified.png new file mode 100644 index 0000000000000000000000000000000000000000..8a150b847114e2468c61b01cf0119c7fbca15f11 GIT binary patch literal 1675 zcmV;626Xv}P)hA?9>>4uckYr-(ziQnlXRz-gqTQ#(105a322}k%95c2 zPgB;U@-)vr`{2X;4L(>kC1!?24Emy_4mzSiQ4zC32RmDD>1_01(jiIr?R)2;7j9w# z0cW1(R{iRns(bJGe9rm(>Q{Au|M!Reo}Z6)ba!e@?j~n0{Wd z)gVLKhi%8YPCUsv{7K;&W9PiSgYv199az&ipNU4#xa#-*9GVyi{!aytc64`Yg!A4* zKH1@_!#lm-;NY_@C{+|5k3=3@;;{sdc64`w(}h=Fdqpa%w&8;-H=$|3ovB$Idaea# z#lok<;m4BLwm@4)m!CMl_zPJb#(c`=)#{~_e(7;O&AZ)!~3)o2X?t|_g)e!t7#Bp7z@wiId2mbi#Rdydg!|1jGBSFJyQAUH^CiE)b#7RSm0B z3}OsrN--MUHl$N3mX_BF-(=yuFy};ANF>qR=z_J(DuhGfGe(IADR}EG(slMxmE9$^ zwl?F&&?Go}kXMm&*eVoo#@a!HplFMsIr8C&K+l9nj9DRM)Q^;tq=1*W<3Z^Co?sytnM`mJCzu98t zO$|=my_WDu@WOC_oZ9WKlqavl?zkC6v-45F@Z0+^U!`I21rn&*gL`o!%7w zP=UOJtKK^@JRInBIBG~LGGXvm44I6ESo|KAlB;mq%fSl`DhpT4d3f(b;g1vmfY3z$ zsME7|WN7HNpNqx3vZ@^Sms3#F8k%ds-bB*icMMg*`7=4!hG~E{Xc%(XMpDg z2-$0ZZak6A1b9wBGDJaQW;z%vRVpTb8H>K;a@eWPVZ-3iZJh17q{gQw-Wch>ayrrQ#UMf&*DE178c&YPpdU*9l5jX*6I z8N;}xfM&4ghA}V30f-B8p|~uS#1g-*9*%@={WTc4eq#ej-4JO*6jJc8t69DdB*SP7 z(IA-LWgd{)5Nn2UT_JAgZkSJpg!QS(!;OWNG3?$bvu@XqE3nx=MtFXWjk(^|^B*!z Vd?K(Eq~8Dl002ovPDHLkV1lXf8uI`E literal 0 HcmV?d00001