mirror of https://github.com/bsnes-emu/bsnes.git
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)
This commit is contained in:
parent
65c4011bec
commit
bbc33fe05f
|
@ -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);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
string Ananke::createBsxSatellaviewDatabase(vector<uint8_t> &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<uint8_t> &buffer, Markup::Nod
|
|||
|
||||
string Ananke::createBsxSatellaviewHeuristic(vector<uint8_t> &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"
|
||||
|
|
|
@ -8,11 +8,12 @@ void Ananke::copyFamicomSaves(const string &pathname) {
|
|||
|
||||
string Ananke::createFamicomHeuristic(vector<uint8_t> &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();
|
||||
|
|
|
@ -14,11 +14,12 @@ void Ananke::copyGameBoyAdvanceSaves(const string &pathname) {
|
|||
|
||||
string Ananke::createGameBoyAdvanceHeuristic(vector<uint8_t> &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;
|
||||
|
|
|
@ -16,12 +16,12 @@ string Ananke::createGameBoyHeuristic(vector<uint8_t> &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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace nall {
|
|||
|
||||
struct thread {
|
||||
thread(function<void ()> 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<void ()> 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<void ()> 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<void ()> 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) {
|
||||
|
|
|
@ -8,7 +8,7 @@ void Ananke::copySufamiTurboSaves(const string &pathname) {
|
|||
|
||||
string Ananke::createSufamiTurboDatabase(vector<uint8_t> &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<uint8_t> &buffer, Markup::Node &
|
|||
|
||||
string Ananke::createSufamiTurboHeuristic(vector<uint8_t> &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",
|
||||
|
|
|
@ -14,7 +14,7 @@ void Ananke::copySuperFamicomSaves(const string &pathname) {
|
|||
|
||||
string Ananke::createSuperFamicomDatabase(vector<uint8_t> &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<uint8_t> &buffer, Markup::Node
|
|||
|
||||
string Ananke::createSuperFamicomHeuristic(vector<uint8_t> &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<uint8_t> &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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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() {}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -5,7 +5,7 @@ struct Cartridge : Thread, property<Cartridge> {
|
|||
static void Main();
|
||||
void main();
|
||||
|
||||
void load(const string &manifest);
|
||||
void load();
|
||||
void unload();
|
||||
|
||||
void power();
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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<uint8>(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);
|
||||
|
|
|
@ -54,7 +54,7 @@ struct Cartridge : MMIO, property<Cartridge> {
|
|||
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);
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -21,7 +21,7 @@ struct Cartridge : property<Cartridge> {
|
|||
};
|
||||
vector<Media> memory;
|
||||
|
||||
void load(const string &manifest);
|
||||
void load();
|
||||
void unload();
|
||||
void power();
|
||||
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <nall/stdint.hpp>
|
||||
#include <nall/stream.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/thread.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
#include <nall/unzip.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
|
|
@ -5,12 +5,6 @@
|
|||
//example: property<owner>::readonly<type> 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<foo>::readonly<bool> x;
|
||||
|
@ -50,8 +44,6 @@
|
|||
|
||||
namespace nall {
|
||||
template<typename C> struct property {
|
||||
template<typename T> struct traits { typedef T type; };
|
||||
|
||||
template<typename T> 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<C>::type;
|
||||
friend C;
|
||||
};
|
||||
|
||||
template<typename T> struct writeonly {
|
||||
|
@ -73,7 +65,7 @@ namespace nall {
|
|||
T* operator->() { return &value; }
|
||||
operator T&() { return value; }
|
||||
T value;
|
||||
friend class traits<C>::type;
|
||||
friend C;
|
||||
};
|
||||
|
||||
template<typename T> struct readwrite {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <nall/string/cstring.hpp>
|
||||
#include <nall/string/datetime.hpp>
|
||||
#include <nall/string/filename.hpp>
|
||||
#include <nall/string/format.hpp>
|
||||
#include <nall/string/math-fixed-point.hpp>
|
||||
#include <nall/string/math-floating-point.hpp>
|
||||
#include <nall/string/platform.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<typename... Args> 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<unsigned limit = 0> inline string& ltrim(const char *key = " ");
|
||||
template<unsigned limit = 0> 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<signed precision = 0, char padchar = ' '> inline string format(const string &value);
|
||||
template<signed precision = 0, char padchar = '0'> inline string hex(uintmax_t value);
|
||||
template<signed precision = 0, char padchar = '0'> inline string octal(uintmax_t value);
|
||||
template<signed precision = 0, char padchar = '0'> 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<unsigned length = 0, char padding = ' '> inline string integer(intmax_t value);
|
||||
template<unsigned length = 0, char padding = ' '> inline string linteger(intmax_t value);
|
||||
template<unsigned length = 0, char padding = ' '> inline string decimal(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = ' '> inline string ldecimal(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string hex(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string binary(uintmax_t value);
|
||||
inline unsigned fp(char *str, long double value);
|
||||
inline string fp(long double value);
|
||||
|
||||
|
|
|
@ -12,11 +12,18 @@ static void istring(string &output, const T &value, Args&&... args) {
|
|||
}
|
||||
|
||||
void string::reserve(unsigned size_) {
|
||||
if(size_ > size) {
|
||||
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 {
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
#ifdef NALL_STRING_INTERNAL_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
template<signed precision, char padchar> 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<signed precision, char padchar> 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<precision, padchar>(buffer);
|
||||
}
|
||||
|
||||
template<signed precision, char padchar> 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<precision, padchar>(buffer);
|
||||
}
|
||||
|
||||
template<signed precision, char padchar> 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<precision, padchar>(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -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
|
||||
|
|
|
@ -201,50 +201,6 @@ template<unsigned length_, char padding> string ldecimal(uintmax_t value) {
|
|||
return (const char*)result;
|
||||
}
|
||||
|
||||
template<unsigned length_, char padding> 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<unsigned length_, char padding> 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.
|
||||
|
|
|
@ -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<unsigned limit> string& string::ltrim(const char *key) { nall::ltrim<limit>(data, key); return *this; }
|
||||
template<unsigned limit> string& string::rtrim(const char *key) { nall::rtrim<limit>(data, key); return *this; }
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
#ifndef NALL_THREAD_HPP
|
||||
#define NALL_THREAD_HPP
|
||||
|
||||
#include <nall/platform.hpp>
|
||||
#include <nall/function.hpp>
|
||||
#include <nall/intrinsics.hpp>
|
||||
|
||||
#if defined(PLATFORM_X) || defined(PLATFORM_OSX)
|
||||
#include <pthread.h>
|
||||
|
||||
namespace nall {
|
||||
void* thread_entry_point(void*);
|
||||
|
||||
struct thread {
|
||||
thread(function<void ()> 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<void ()> 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<void ()> 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<void ()> 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
|
|
@ -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 :=
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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/)
|
||||
|
|
|
@ -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.markup.cartridge = "";
|
||||
information.markup.gameBoy = "";
|
||||
information.markup.satellaview = "";
|
||||
information.markup.sufamiTurboA = "";
|
||||
information.markup.sufamiTurboB = "";
|
||||
|
||||
information.title.cartridge = "";
|
||||
information.title.gameBoy = "";
|
||||
information.title.satellaview = "";
|
||||
information.title.sufamiTurboA = "";
|
||||
information.title.sufamiTurboB = "";
|
||||
|
||||
parse_markup(information.markup = manifest);
|
||||
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<uint8>(size, 0xff), size);
|
||||
interface->loadRequest(ID::BsxFlashROM, rom["name"].data);
|
||||
satellaviewcartridge.memory.map(allocate<uint8>(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<uint8>(size, 0xff), size);
|
||||
sufamiturboA.rom.map(allocate<uint8>(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<uint8>(size, 0xff), size);
|
||||
sufamiturboA.ram.map(allocate<uint8>(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<uint8>(size, 0xff), size);
|
||||
sufamiturboB.rom.map(allocate<uint8>(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<uint8>(size, 0xff), size);
|
||||
sufamiturboB.ram.map(allocate<uint8>(size, 0xff), size);
|
||||
interface->loadRequest(ID::SufamiTurboSlotBRAM, ram["name"].data);
|
||||
memory.append({ID::SufamiTurboSlotBRAM, ram["name"].data});
|
||||
}
|
||||
|
|
|
@ -61,7 +61,14 @@ struct Cartridge : property<Cartridge> {
|
|||
vector<Memory> 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<Cartridge> {
|
|||
|
||||
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> {
|
|||
~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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -4,5 +4,4 @@
|
|||
namespace SuperFamicom {
|
||||
#include "satellaview/satellaview.cpp"
|
||||
#include "cartridge/cartridge.cpp"
|
||||
#include "flash/flash.cpp"
|
||||
}
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
#include "satellaview/satellaview.hpp"
|
||||
#include "cartridge/cartridge.hpp"
|
||||
#include "flash/flash.hpp"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ struct Coprocessor : Thread {
|
|||
|
||||
#include <sfc/chip/icd2/icd2.hpp>
|
||||
#include <sfc/chip/bsx/bsx.hpp>
|
||||
#include <sfc/chip/sufamiturbo/sufamiturbo.hpp>
|
||||
#include <sfc/chip/nss/nss.hpp>
|
||||
#include <sfc/chip/event/event.hpp>
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
|
@ -1,19 +0,0 @@
|
|||
#include <sfc/sfc.hpp>
|
||||
|
||||
#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();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
struct SufamiTurbo {
|
||||
struct Slot {
|
||||
MappedRAM rom;
|
||||
MappedRAM ram;
|
||||
} slotA, slotB;
|
||||
|
||||
void load();
|
||||
void unload();
|
||||
void serialize(serializer&);
|
||||
};
|
||||
|
||||
extern SufamiTurbo sufamiturbo;
|
|
@ -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() {
|
||||
|
@ -376,9 +388,9 @@ Interface::Interface() {
|
|||
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, "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"};
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ namespace SuperFamicom {
|
|||
#include <sfc/controller/controller.hpp>
|
||||
#include <sfc/system/system.hpp>
|
||||
#include <sfc/chip/chip.hpp>
|
||||
#include <sfc/slot/slot.hpp>
|
||||
#include <sfc/cartridge/cartridge.hpp>
|
||||
#include <sfc/cheat/cheat.hpp>
|
||||
#include <sfc/interface/interface.hpp>
|
||||
|
|
25
higan/sfc/chip/bsx/flash/flash.cpp → higan/sfc/slot/satellaview/satellaview.cpp
Executable file → Normal file
25
higan/sfc/chip/bsx/flash/flash.cpp → higan/sfc/slot/satellaview/satellaview.cpp
Executable file → Normal file
|
@ -1,24 +1,27 @@
|
|||
#ifdef BSX_CPP
|
||||
#include <sfc/sfc.hpp>
|
||||
|
||||
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<uint8>(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
|
||||
}
|
4
higan/sfc/chip/bsx/flash/flash.hpp → higan/sfc/slot/satellaview/satellaview.hpp
Executable file → Normal file
4
higan/sfc/chip/bsx/flash/flash.hpp → higan/sfc/slot/satellaview/satellaview.hpp
Executable file → Normal file
|
@ -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;
|
|
@ -0,0 +1,2 @@
|
|||
#include <sfc/slot/satellaview/satellaview.hpp>
|
||||
#include <sfc/slot/sufamiturbo/sufamiturbo.hpp>
|
|
@ -0,0 +1,7 @@
|
|||
#ifdef SUFAMITURBO_CPP
|
||||
|
||||
void SufamiTurboCartridge::serialize(serializer &s) {
|
||||
s.array(ram.data(), ram.size());
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,18 @@
|
|||
#include <sfc/sfc.hpp>
|
||||
|
||||
#define SUFAMITURBO_CPP
|
||||
namespace SuperFamicom {
|
||||
|
||||
#include "serialization.cpp"
|
||||
SufamiTurboCartridge sufamiturboA;
|
||||
SufamiTurboCartridge sufamiturboB;
|
||||
|
||||
void SufamiTurboCartridge::load() {
|
||||
}
|
||||
|
||||
void SufamiTurboCartridge::unload() {
|
||||
rom.reset();
|
||||
ram.reset();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
struct SufamiTurboCartridge {
|
||||
MappedRAM rom;
|
||||
MappedRAM ram;
|
||||
|
||||
void load();
|
||||
void unload();
|
||||
void serialize(serializer&);
|
||||
};
|
||||
|
||||
extern SufamiTurboCartridge sufamiturboA;
|
||||
extern SufamiTurboCartridge sufamiturboB;
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -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];
|
||||
};
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
|
@ -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);
|
||||
};
|
||||
}
|
|
@ -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;
|
|
@ -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(); };
|
||||
}
|
|
@ -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;
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace nall {
|
|||
|
||||
struct thread {
|
||||
thread(function<void ()> 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<void ()> 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<void ()> 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<void ()> 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) {
|
||||
|
|
|
@ -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});
|
||||
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});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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];
|
||||
};
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
Loading…
Reference in New Issue