mirror of https://github.com/bsnes-emu/bsnes.git
Update to ananke v00r02 release.
byuu says: This should be basically final now. Works with all media types (nes, sfc, gb, gbc, gba, bs, st), strips headers, can use internal or external firmware, imports saves on first run. Added a custom file dialog. It seems both GTK+ and Windows XP have (un)intelligent file sorting, which puts eg "ActRaiser 2 (NA)" before "ActRaiser (NA)". So, screw 'em.
This commit is contained in:
parent
019fc1a2c6
commit
85f2e9a6d4
|
@ -8,14 +8,15 @@ all:
|
|||
$(cpp) $(flags) -fPIC -o ananke.o -c ananke.cpp
|
||||
$(cpp) $(flags) -shared -Wl,-soname,libananke.so.1 -o libananke.so ananke.o
|
||||
|
||||
resource: force
|
||||
sourcery resource/resource.bml resource/resource.cpp resource/resource.hpp
|
||||
|
||||
clean:
|
||||
-@$(call delete,*.o)
|
||||
-@$(call delete,*.so)
|
||||
|
||||
install: uninstall
|
||||
if [ ! -d ~/.config/ananke ]; then mkdir ~/.config/ananke; fi
|
||||
if [ -d ~/.config/ananke/database ]; then rm -r ~/.config/ananke/database; fi
|
||||
cp -r database ~/.config/ananke/database
|
||||
sudo cp libananke.so $(path)/libananke.so.1
|
||||
sudo ln -s $(path)/libananke.so.1 $(path)/libananke.so
|
||||
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
#include <nall/nall.hpp>
|
||||
#include <nall/beat/patch.hpp>
|
||||
#include <nall/emulation/famicom.hpp>
|
||||
#include <nall/emulation/super-famicom.hpp>
|
||||
#include <nall/emulation/game-boy.hpp>
|
||||
#include <nall/emulation/game-boy-advance.hpp>
|
||||
using namespace nall;
|
||||
|
||||
#include <phoenix/phoenix.hpp>
|
||||
using namespace phoenix;
|
||||
|
||||
namespace Database {
|
||||
#include "database/super-famicom.hpp"
|
||||
};
|
||||
|
||||
struct Ananke {
|
||||
#include "configuration.cpp"
|
||||
|
||||
|
@ -23,40 +30,72 @@ struct Ananke {
|
|||
//patch.cpp
|
||||
void applyBeatPatch(vector<uint8_t> &buffer);
|
||||
|
||||
//famicom.cpp
|
||||
void copyFamicomSaves(const string &pathname);
|
||||
string createFamicomHeuristic(vector<uint8_t> &buffer);
|
||||
string openFamicom(vector<uint8_t> &buffer);
|
||||
|
||||
//super-famicom.cpp
|
||||
void copySuperFamicomSaves(const string &pathname);
|
||||
string createSuperFamicomDatabase(vector<uint8_t> &buffer, Markup::Node &document, const string &manifest);
|
||||
string createSuperFamicomHeuristic(vector<uint8_t> &buffer);
|
||||
void createSuperFamicomHeuristicFirmware(vector<uint8_t> &buffer, const string &pathname, bool firmware_appended);
|
||||
string openSuperFamicom(vector<uint8_t> &buffer);
|
||||
|
||||
string open(string filename = "") {
|
||||
if(filename.empty()) filename = DialogWindow::fileOpen(Window::none(), config.path);
|
||||
if(filename.empty()) return "";
|
||||
|
||||
information.path = dir(filename);
|
||||
information.name = notdir(filename);
|
||||
config.path = information.path; //remember last used directory
|
||||
|
||||
vector<uint8_t> buffer;
|
||||
if(filename.endswith(".zip")) {
|
||||
information.archive = filename;
|
||||
buffer = extractROM();
|
||||
} else {
|
||||
buffer = file::read(filename);
|
||||
}
|
||||
if(buffer.size() == 0) return ""; //failed to read file
|
||||
|
||||
applyBeatPatch(buffer);
|
||||
|
||||
if(information.name.endswith(".sfc")) return openSuperFamicom(buffer);
|
||||
return "";
|
||||
}
|
||||
//game-boy.cpp
|
||||
void copyGameBoySaves(const string &pathname);
|
||||
string createGameBoyHeuristic(vector<uint8_t> &buffer);
|
||||
string openGameBoy(vector<uint8_t> &buffer);
|
||||
|
||||
//game-boy-advance.cpp
|
||||
void copyGameBoyAdvanceSaves(const string &pathname);
|
||||
string createGameBoyAdvanceHeuristic(vector<uint8_t> &buffer);
|
||||
string openGameBoyAdvance(vector<uint8_t> &buffer);
|
||||
|
||||
string open(string filename = "");
|
||||
};
|
||||
|
||||
#include "resource/resource.cpp"
|
||||
#include "file-dialog.cpp"
|
||||
#include "archive.cpp"
|
||||
#include "patch.cpp"
|
||||
#include "famicom.cpp"
|
||||
#include "super-famicom.cpp"
|
||||
#include "game-boy.cpp"
|
||||
#include "game-boy-advance.cpp"
|
||||
|
||||
FileDialog *fileDialog = nullptr;
|
||||
|
||||
string Ananke::open(string filename) {
|
||||
if(filename.empty()) {
|
||||
if(!fileDialog) fileDialog = new FileDialog;
|
||||
fileDialog->setPath(config.path);
|
||||
filename = fileDialog->open();
|
||||
}
|
||||
|
||||
if(filename.empty()) return "";
|
||||
|
||||
information.path = dir(filename);
|
||||
information.name = notdir(filename);
|
||||
config.path = information.path; //remember last used directory
|
||||
|
||||
vector<uint8_t> buffer;
|
||||
if(filename.endswith(".zip")) {
|
||||
information.archive = filename;
|
||||
buffer = extractROM();
|
||||
} else {
|
||||
buffer = file::read(filename);
|
||||
}
|
||||
if(buffer.size() == 0) return ""; //failed to read file
|
||||
|
||||
applyBeatPatch(buffer);
|
||||
|
||||
if(information.name.endswith(".fc") || information.name.endswith(".nes")) return openFamicom(buffer);
|
||||
if(information.name.endswith(".sfc") || information.name.endswith(".smc")) return openSuperFamicom(buffer);
|
||||
if(information.name.endswith(".gb") || information.name.endswith(".gbc")) return openGameBoy(buffer);
|
||||
if(information.name.endswith(".gba")) return openGameBoyAdvance(buffer);
|
||||
return "";
|
||||
}
|
||||
|
||||
extern "C" string ananke_browse(const string &filename) {
|
||||
Ananke ananke;
|
||||
|
|
|
@ -2,7 +2,12 @@ vector<uint8_t> Ananke::extractROM() {
|
|||
unzip archive;
|
||||
if(archive.open(information.archive)) {
|
||||
for(auto &file : archive.file) {
|
||||
if(file.name.endswith(".sfc")) {
|
||||
if(
|
||||
file.name.endswith(".fc") || file.name.endswith(".nes")
|
||||
|| file.name.endswith(".sfc") || file.name.endswith(".smc")
|
||||
|| file.name.endswith(".gb") || file.name.endswith(".gbc")
|
||||
|| file.name.endswith(".gba")
|
||||
) {
|
||||
information.name = notdir(file.name);
|
||||
return archive.extract(file);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,31 @@
|
|||
void Ananke::copyFamicomSaves(const string &pathname) {
|
||||
if(!file::exists({pathname, "save.ram"})) {
|
||||
if(file::exists({information.path, nall::basename(information.name), ".sav"})) {
|
||||
file::copy({information.path, nall::basename(information.name), ".srm"}, {pathname, "save.ram"});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string Ananke::createFamicomHeuristic(vector<uint8_t> &buffer) {
|
||||
string pathname = {
|
||||
userpath(), "Emulation/Famicom/",
|
||||
nall::basename(information.name),
|
||||
" (!).fc/"
|
||||
};
|
||||
directory::create(pathname);
|
||||
|
||||
FamicomCartridge info(buffer.data(), buffer.size());
|
||||
string markup = info.markup();
|
||||
if(!information.manifest.empty()) markup = information.manifest; //override with embedded beat manifest, if one exists
|
||||
|
||||
file::write({pathname, "manifest.bml"}, markup);
|
||||
file::write({pathname, "program.rom"}, buffer.data() + 16, info.prgrom);
|
||||
if(info.chrrom > 0) file::write({pathname, "character.rom"}, buffer.data() + 16 + info.prgrom, info.chrrom);
|
||||
|
||||
copyFamicomSaves(pathname);
|
||||
return pathname;
|
||||
}
|
||||
|
||||
string Ananke::openFamicom(vector<uint8_t> &buffer) {
|
||||
return createFamicomHeuristic(buffer);
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
struct FileDialog : Window {
|
||||
VerticalLayout layout;
|
||||
HorizontalLayout pathLayout;
|
||||
LineEdit pathEdit;
|
||||
Button homeButton;
|
||||
Button upButton;
|
||||
ListView fileList;
|
||||
HorizontalLayout controlLayout;
|
||||
Widget spacer;
|
||||
Button openButton;
|
||||
|
||||
string open() {
|
||||
setModal();
|
||||
setVisible();
|
||||
fileList.setFocused();
|
||||
filename = "";
|
||||
|
||||
dialogActive = true;
|
||||
while(dialogActive) {
|
||||
OS::processEvents();
|
||||
if(Keyboard::pressed(Keyboard::Scancode::Escape)) onClose();
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
void setPath(const string &path) {
|
||||
pathname = string{path}.transform("\\", "/");
|
||||
if(pathname.empty()) pathname = userpath();
|
||||
if(pathname.endswith("/") == false) pathname.append("/");
|
||||
pathEdit.setText(pathname);
|
||||
|
||||
fileList.reset();
|
||||
filenameList.reset();
|
||||
|
||||
lstring folders = directory::ifolders(pathname);
|
||||
for(auto &folder : folders) {
|
||||
fileList.append(string{folder}.rtrim<1>("/"));
|
||||
fileList.setImage(filenameList.size(), 0, {resource::folder, sizeof resource::folder});
|
||||
filenameList.append({pathname, folder});
|
||||
}
|
||||
|
||||
lstring files = directory::ifiles(pathname);
|
||||
for(auto &file : files) {
|
||||
fileList.append(file);
|
||||
fileList.setImage(filenameList.size(), 0, {resource::file, sizeof resource::file});
|
||||
filenameList.append({pathname, file});
|
||||
}
|
||||
|
||||
fileList.setSelection(0);
|
||||
fileList.setSelected();
|
||||
fileList.setFocused();
|
||||
}
|
||||
|
||||
FileDialog() {
|
||||
setGeometry({64, 64, 480, 600});
|
||||
setTitle("Load Image");
|
||||
|
||||
layout.setMargin(5);
|
||||
homeButton.setImage({resource::home, sizeof resource::home});
|
||||
upButton.setImage({resource::up, sizeof resource::up});
|
||||
openButton.setText("Open");
|
||||
|
||||
append(layout);
|
||||
layout.append(pathLayout, {~0, 0}, 5);
|
||||
pathLayout.append(pathEdit, {~0, 0}, 5);
|
||||
pathLayout.append(homeButton, {28, 28}, 5);
|
||||
pathLayout.append(upButton, {28, 28});
|
||||
layout.append(fileList, {~0, ~0}, 5);
|
||||
layout.append(controlLayout, {~0, 0});
|
||||
controlLayout.append(spacer, {~0, 0});
|
||||
controlLayout.append(openButton, {80, 0});
|
||||
|
||||
pathEdit.onActivate = [&] {
|
||||
string path = pathEdit.text();
|
||||
setPath(path);
|
||||
};
|
||||
|
||||
homeButton.onActivate = [&] {
|
||||
setPath(userpath());
|
||||
};
|
||||
|
||||
upButton.onActivate = [&] {
|
||||
setPath(parentdir(pathname));
|
||||
};
|
||||
|
||||
fileList.onActivate = openButton.onActivate = [&] {
|
||||
if(fileList.selected() == false) return;
|
||||
string name = filenameList(fileList.selection());
|
||||
if(name.empty()) return;
|
||||
|
||||
if(name.endswith("/")) return setPath(name);
|
||||
filename = name;
|
||||
onClose();
|
||||
};
|
||||
|
||||
onClose = [&] {
|
||||
dialogActive = false;
|
||||
setModal(false);
|
||||
setVisible(false);
|
||||
};
|
||||
}
|
||||
|
||||
private:
|
||||
bool dialogActive;
|
||||
string pathname;
|
||||
string filename;
|
||||
lstring filenameList;
|
||||
};
|
|
@ -0,0 +1,36 @@
|
|||
void Ananke::copyGameBoyAdvanceSaves(const string &pathname) {
|
||||
if(!file::exists({pathname, "save.ram"})) {
|
||||
if(file::exists({information.path, nall::basename(information.name), ".sav"})) {
|
||||
file::copy({information.path, nall::basename(information.name), ".sav"}, {pathname, "save.ram"});
|
||||
}
|
||||
}
|
||||
|
||||
if(!file::exists({pathname, "rtc.ram"})) {
|
||||
if(file::exists({information.path, nall::basename(information.name), ".rtc"})) {
|
||||
file::copy({information.path, nall::basename(information.name), ".rtc"}, {pathname, "rtc.ram"});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string Ananke::createGameBoyAdvanceHeuristic(vector<uint8_t> &buffer) {
|
||||
string pathname = {
|
||||
userpath(), "Emulation/Game Boy Advance/",
|
||||
nall::basename(information.name),
|
||||
" (!).gba/"
|
||||
};
|
||||
directory::create(pathname);
|
||||
|
||||
GameBoyAdvanceCartridge info(buffer.data(), buffer.size());
|
||||
string markup = info.markup;
|
||||
if(!information.manifest.empty()) markup = information.manifest; //override with embedded beat manifest, if one exists
|
||||
|
||||
file::write({pathname, "manifest.bml"}, markup);
|
||||
file::write({pathname, "program.rom"}, buffer);
|
||||
|
||||
copyGameBoyAdvanceSaves(pathname);
|
||||
return pathname;
|
||||
}
|
||||
|
||||
string Ananke::openGameBoyAdvance(vector<uint8_t> &buffer) {
|
||||
return createGameBoyAdvanceHeuristic(buffer);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
void Ananke::copyGameBoySaves(const string &pathname) {
|
||||
if(!file::exists({pathname, "save.ram"})) {
|
||||
if(file::exists({information.path, nall::basename(information.name), ".sav"})) {
|
||||
file::copy({information.path, nall::basename(information.name), ".sav"}, {pathname, "save.ram"});
|
||||
}
|
||||
}
|
||||
|
||||
if(!file::exists({pathname, "rtc.ram"})) {
|
||||
if(file::exists({information.path, nall::basename(information.name), ".rtc"})) {
|
||||
file::copy({information.path, nall::basename(information.name), ".rtc"}, {pathname, "rtc.ram"});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string Ananke::createGameBoyHeuristic(vector<uint8_t> &buffer) {
|
||||
GameBoyCartridge info(buffer.data(), buffer.size());
|
||||
|
||||
string pathname = {
|
||||
userpath(),
|
||||
"Emulation/Game Boy/",
|
||||
nall::basename(information.name),
|
||||
" (!).", (info.info.cgb ? "gbc" : "gb"), "/"
|
||||
};
|
||||
directory::create(pathname);
|
||||
|
||||
string markup = info.markup;
|
||||
if(!information.manifest.empty()) markup = information.manifest; //override with embedded beat manifest, if one exists
|
||||
|
||||
file::write({pathname, "manifest.bml"}, info.markup);
|
||||
file::write({pathname, "program.rom"}, buffer);
|
||||
|
||||
copyGameBoySaves(pathname);
|
||||
return pathname;
|
||||
}
|
||||
|
||||
string Ananke::openGameBoy(vector<uint8_t> &buffer) {
|
||||
return createGameBoyHeuristic(buffer);
|
||||
}
|
|
@ -21,9 +21,53 @@ struct directory {
|
|||
static bool create(const string &pathname, unsigned permissions = 0755); //recursive
|
||||
static bool remove(const string &pathname); //recursive
|
||||
static bool exists(const string &pathname);
|
||||
static lstring folders(const string &pathname, const string &pattern = "*");
|
||||
static lstring files(const string &pathname, const string &pattern = "*");
|
||||
static lstring contents(const string &pathname, const string &pattern = "*");
|
||||
|
||||
static lstring folders(const string &pathname, const string &pattern = "*") {
|
||||
lstring folders = directory::ufolders(pathname, pattern);
|
||||
folders.sort();
|
||||
return folders;
|
||||
}
|
||||
|
||||
static lstring files(const string &pathname, const string &pattern = "*") {
|
||||
lstring files = directory::ufiles(pathname, pattern);
|
||||
files.sort();
|
||||
return files;
|
||||
}
|
||||
|
||||
static lstring contents(const string &pathname, const string &pattern = "*") {
|
||||
lstring folders = directory::ufolders(pathname); //pattern search of contents should only filter files
|
||||
lstring files = directory::ufiles(pathname, pattern);
|
||||
folders.sort();
|
||||
files.sort();
|
||||
for(auto &file : files) folders.append(file);
|
||||
return folders;
|
||||
}
|
||||
|
||||
static lstring ifolders(const string &pathname, const string &pattern = "*") {
|
||||
lstring folders = ufolders(pathname, pattern);
|
||||
folders.isort();
|
||||
return folders;
|
||||
}
|
||||
|
||||
static lstring ifiles(const string &pathname, const string &pattern = "*") {
|
||||
lstring files = ufiles(pathname, pattern);
|
||||
files.isort();
|
||||
return files;
|
||||
}
|
||||
|
||||
static lstring icontents(const string &pathname, const string &pattern = "*") {
|
||||
lstring folders = directory::ufolders(pathname); //pattern search of contents should only filter files
|
||||
lstring files = directory::ufiles(pathname, pattern);
|
||||
folders.isort();
|
||||
files.isort();
|
||||
for(auto &file : files) folders.append(file);
|
||||
return folders;
|
||||
}
|
||||
|
||||
private:
|
||||
//internal functions; these return unsorted lists
|
||||
static lstring ufolders(const string &pathname, const string &pattern = "*");
|
||||
static lstring ufiles(const string &pathname, const string &pattern = "*");
|
||||
};
|
||||
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
|
@ -55,7 +99,7 @@ struct directory {
|
|||
return (result & FILE_ATTRIBUTE_DIRECTORY);
|
||||
}
|
||||
|
||||
inline lstring directory::folders(const string &pathname, const string &pattern) {
|
||||
inline lstring directory::ufolders(const string &pathname, const string &pattern) {
|
||||
lstring list;
|
||||
string path = pathname;
|
||||
path.transform("/", "\\");
|
||||
|
@ -81,12 +125,11 @@ struct directory {
|
|||
}
|
||||
FindClose(handle);
|
||||
}
|
||||
if(list.size() > 0) list.sort();
|
||||
for(auto &name : list) name.append("/"); //must append after sorting
|
||||
return list;
|
||||
}
|
||||
|
||||
inline lstring directory::files(const string &pathname, const string &pattern) {
|
||||
inline lstring directory::ufiles(const string &pathname, const string &pattern) {
|
||||
lstring list;
|
||||
string path = pathname;
|
||||
path.transform("/", "\\");
|
||||
|
@ -108,16 +151,8 @@ struct directory {
|
|||
}
|
||||
FindClose(handle);
|
||||
}
|
||||
if(list.size() > 0) list.sort();
|
||||
return list;
|
||||
}
|
||||
|
||||
inline lstring directory::contents(const string &pathname, const string &pattern) {
|
||||
lstring folders = directory::folders(pathname); //pattern search of contents() should only filter files
|
||||
lstring files = directory::files(pathname, pattern);
|
||||
for(auto &file : files) folders.append(file);
|
||||
return folders;
|
||||
}
|
||||
#else
|
||||
inline bool directory::create(const string &pathname, unsigned permissions) {
|
||||
string path;
|
||||
|
@ -146,7 +181,7 @@ struct directory {
|
|||
return true;
|
||||
}
|
||||
|
||||
inline lstring directory::folders(const string &pathname, const string &pattern) {
|
||||
inline lstring directory::ufolders(const string &pathname, const string &pattern) {
|
||||
lstring list;
|
||||
DIR *dp;
|
||||
struct dirent *ep;
|
||||
|
@ -161,12 +196,11 @@ struct directory {
|
|||
}
|
||||
closedir(dp);
|
||||
}
|
||||
if(list.size() > 0) list.sort();
|
||||
for(auto &name : list) name.append("/"); //must append after sorting
|
||||
return list;
|
||||
}
|
||||
|
||||
inline lstring directory::files(const string &pathname, const string &pattern) {
|
||||
inline lstring directory::ufiles(const string &pathname, const string &pattern) {
|
||||
lstring list;
|
||||
DIR *dp;
|
||||
struct dirent *ep;
|
||||
|
@ -181,16 +215,8 @@ struct directory {
|
|||
}
|
||||
closedir(dp);
|
||||
}
|
||||
if(list.size() > 0) list.sort();
|
||||
return list;
|
||||
}
|
||||
|
||||
inline lstring directory::contents(const string &pathname, const string &pattern) {
|
||||
lstring folders = directory::folders(pathname); //pattern search of contents() should only filter files
|
||||
lstring files = directory::files(pathname, pattern);
|
||||
for(auto &file : files) folders.append(file);
|
||||
return folders;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
|
@ -27,8 +27,6 @@ FamicomCartridge::FamicomCartridge(const uint8_t *data, unsigned size) {
|
|||
if(data[2] != 'S') return;
|
||||
if(data[3] != 26) return;
|
||||
|
||||
markup.append("<?xml version='1.0' encoding='UTF-8'?>\n");
|
||||
|
||||
mapper = ((data[7] >> 4) << 4) | (data[6] >> 4);
|
||||
mirror = ((data[6] & 0x08) >> 2) | (data[6] & 0x01);
|
||||
prgrom = data[4] * 0x4000;
|
||||
|
@ -36,145 +34,138 @@ FamicomCartridge::FamicomCartridge(const uint8_t *data, unsigned size) {
|
|||
prgram = 0u;
|
||||
chrram = chrrom == 0u ? 8192u : 0u;
|
||||
|
||||
markup.append("<cartridge sha256='", sha256(data, size), "'>\n");
|
||||
markup.append("cartridge\n");
|
||||
|
||||
switch(mapper) {
|
||||
default:
|
||||
markup.append(" <board type='NES-NROM-256'/>\n");
|
||||
markup.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n");
|
||||
markup.append(" board type=NES-NROM-256\n");
|
||||
markup.append(" mirror mode=", mirror == 0 ? "horizontal" : "vertical", "\n");
|
||||
break;
|
||||
|
||||
case 1:
|
||||
markup.append(" <board type='NES-SXROM'/>\n");
|
||||
markup.append(" <chip type='MMC1B2'/>\n");
|
||||
markup.append(" board type=NES-SXROM\n");
|
||||
markup.append(" chip type=MMC1B2\n");
|
||||
prgram = 8192;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
markup.append(" <board type='NES-UOROM'/>\n");
|
||||
markup.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n");
|
||||
markup.append(" board type=NES-UOROM\n");
|
||||
markup.append(" mirror mode=", mirror == 0 ? "horizontal" : "vertical", "\n");
|
||||
break;
|
||||
|
||||
case 3:
|
||||
markup.append(" <board type='NES-CNROM'/>\n");
|
||||
markup.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n");
|
||||
markup.append(" board type=NES-CNROM\n");
|
||||
markup.append(" mirror mode=", mirror == 0 ? "horizontal" : "vertical", "\n");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
//MMC3
|
||||
markup.append(" <board type='NES-TLROM'/>\n");
|
||||
markup.append(" <chip type='MMC3B'/>\n");
|
||||
markup.append(" board type=NES-TLROM\n");
|
||||
markup.append(" chip type=MMC3B\n");
|
||||
prgram = 8192;
|
||||
//MMC6
|
||||
//markup.append(" <board type='NES-HKROM'/>\n");
|
||||
//markup.append(" <chip type='MMC6'/>\n");
|
||||
//markup.append(" board type=NES-HKROM\n");
|
||||
//markup.append(" chip type=MMC6n");
|
||||
//prgram = 1024;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
markup.append(" <board type='NES-ELROM'/>\n");
|
||||
markup.append(" <chip type='MMC5'/>\n");
|
||||
markup.append(" board type=NES-ELROM\n");
|
||||
markup.append(" chip type=MMC5\n");
|
||||
prgram = 65536;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
markup.append(" <board type='NES-AOROM'/>\n");
|
||||
markup.append(" board type=NES-AOROM\n");
|
||||
break;
|
||||
|
||||
case 9:
|
||||
markup.append(" <board type='NES-PNROM'/>\n");
|
||||
markup.append(" <chip type='MMC2'/>\n");
|
||||
markup.append(" board type=NES-PNROM\n");
|
||||
markup.append(" chip type=MMC2\n");
|
||||
prgram = 8192;
|
||||
break;
|
||||
|
||||
case 10:
|
||||
markup.append(" <board type='NES-FKROM'/>\n");
|
||||
markup.append(" <chip type='MMC4'/>\n");
|
||||
markup.append(" board type=NES-FKROM\n");
|
||||
markup.append(" chip type=MMC4\n");
|
||||
prgram = 8192;
|
||||
break;
|
||||
|
||||
case 16:
|
||||
markup.append(" <board type='BANDAI-FCG'/>\n");
|
||||
markup.append(" <chip type='LZ93D50'/>\n");
|
||||
markup.append(" board type=BANDAI-FCG\n");
|
||||
markup.append(" chip type=LZ93D50\n");
|
||||
break;
|
||||
|
||||
case 21:
|
||||
case 23:
|
||||
case 25:
|
||||
//VRC4
|
||||
markup.append(" <board type='KONAMI-VRC-4'/>\n");
|
||||
markup.append(" <chip type='VRC4'>\n");
|
||||
markup.append(" <pinout a0='1' a1='0'/>\n");
|
||||
markup.append(" </chip>\n");
|
||||
markup.append(" board type=KONAMI-VRC-4\n");
|
||||
markup.append(" chip type=VRC4\n");
|
||||
markup.append(" pinout a0=1 a1=0\n");
|
||||
prgram = 8192;
|
||||
break;
|
||||
|
||||
case 22:
|
||||
//VRC2
|
||||
markup.append(" <board type='KONAMI-VRC-2'/>\n");
|
||||
markup.append(" <chip type='VRC2'>\n");
|
||||
markup.append(" <pinout a0='0' a1='1'/>\n");
|
||||
markup.append(" </chip>\n");
|
||||
markup.append(" board type=KONAMI-VRC-2\n");
|
||||
markup.append(" chip type=VRC2\n");
|
||||
markup.append(" pinout a0=0 a1=1\n");
|
||||
break;
|
||||
|
||||
case 24:
|
||||
markup.append(" <board type='KONAMI-VRC-6'/>\n");
|
||||
markup.append(" <chip type='VRC6'/>\n");
|
||||
markup.append(" board type=KONAMI-VRC-6\n");
|
||||
markup.append(" chip type=VRC6\n");
|
||||
break;
|
||||
|
||||
case 26:
|
||||
markup.append(" <board type='KONAMI-VRC-6'/>\n");
|
||||
markup.append(" <chip type='VRC6'/>\n");
|
||||
markup.append(" board type=KONAMI-VRC-6\n");
|
||||
markup.append(" chip type=VRC6\n");
|
||||
prgram = 8192;
|
||||
break;
|
||||
|
||||
case 34:
|
||||
markup.append(" <board type='NES-BNROM'/>\n");
|
||||
markup.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n");
|
||||
markup.append(" board type=NES-BNROM\n");
|
||||
markup.append(" mirror mode=", mirror == 0 ? "horizontal" : "vertical", "\n");
|
||||
break;
|
||||
|
||||
case 66:
|
||||
markup.append(" <board type='NES-GNROM'/>\n");
|
||||
markup.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n");
|
||||
markup.append(" board type=NES-GNROM\n");
|
||||
markup.append(" mirror mode=", mirror == 0 ? "horizontal" : "vertical", "\n");
|
||||
break;
|
||||
|
||||
case 69:
|
||||
markup.append(" <board type='SUNSOFT-5B'/>\n");
|
||||
markup.append(" <chip type='5B'/>\n");
|
||||
markup.append(" board type=SUNSOFT-5B\n");
|
||||
markup.append(" chip type=5B\n");
|
||||
prgram = 8192;
|
||||
break;
|
||||
|
||||
case 73:
|
||||
markup.append(" <board type='KONAMI-VRC-3'/>\n");
|
||||
markup.append(" <chip type='VRC3'/>\n");
|
||||
markup.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n");
|
||||
markup.append(" board type=KONAMI-VRC-3\n");
|
||||
markup.append(" chip type=VRC3\n");
|
||||
markup.append(" mirror mode=", mirror == 0 ? "horizontal" : "vertical", "\n");
|
||||
prgram = 8192;
|
||||
break;
|
||||
|
||||
case 75:
|
||||
markup.append(" <board type='KONAMI-VRC-1'/>\n");
|
||||
markup.append(" <chip type='VRC1'/>\n");
|
||||
markup.append(" board type=KONAMI-VRC-1\n");
|
||||
markup.append(" chip type=VRC1\n");
|
||||
break;
|
||||
|
||||
case 85:
|
||||
markup.append(" <board type='KONAMI-VRC-7/'>\n");
|
||||
markup.append(" <chip type='VRC7'/>\n");
|
||||
markup.append(" board type=KONAMI-VRC-7\n");
|
||||
markup.append(" chip type=VRC7\n");
|
||||
prgram = 8192;
|
||||
break;
|
||||
}
|
||||
|
||||
markup.append(" <prg>\n");
|
||||
if(prgrom) markup.append(" <rom name='program.rom' size='0x", hex(prgrom), "'/>\n");
|
||||
if(prgram) markup.append(" <ram name='save.ram' size='0x", hex(prgram), "'/>\n");
|
||||
markup.append(" </prg>\n");
|
||||
markup.append(" prg\n");
|
||||
if(prgrom) markup.append(" rom name=program.rom size=0x", hex(prgrom), "\n");
|
||||
if(prgram) markup.append(" ram name=save.ram size=0x", hex(prgram), "\n");
|
||||
|
||||
markup.append(" <chr>\n");
|
||||
if(chrrom) markup.append(" <rom name='character.rom' size='0x", hex(chrrom), "'/>\n");
|
||||
if(chrram) markup.append(" <ram size='0x", hex(chrram), "'/>\n");
|
||||
markup.append(" </chr>\n");
|
||||
|
||||
markup.append("</cartridge>\n");
|
||||
markup.transform("'", "\"");
|
||||
markup.append(" chr\n");
|
||||
if(chrrom) markup.append(" rom name=character.rom size=0x", hex(chrrom), "\n");
|
||||
if(chrram) markup.append(" ram size=0x", hex(chrram), "\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -46,21 +46,16 @@ GameBoyAdvanceCartridge::GameBoyAdvanceCartridge(const uint8_t *data, unsigned s
|
|||
identifiers = list.concatenate(",");
|
||||
|
||||
markup = "";
|
||||
|
||||
markup.append("<?xml version='1.0' encoding='UTF-8'?>\n");
|
||||
markup.append("<cartridge sha256='", sha256(data, size), "'>\n");
|
||||
markup.append(" <rom name='program.rom' size='0x", hex(size), "'/>\n");
|
||||
markup.append("cartridge\n");
|
||||
markup.append(" rom name=program.rom size=0x", hex(size), "\n");
|
||||
if(0);
|
||||
else if(identifiers.beginswith("SRAM_V" )) markup.append(" <ram name='save.ram' type='SRAM' size='0x8000'/>\n");
|
||||
else if(identifiers.beginswith("SRAM_F_V" )) markup.append(" <ram name='save.ram' type='FRAM' size='0x8000'/>\n");
|
||||
else if(identifiers.beginswith("EEPROM_V" )) markup.append(" <ram name='save.ram' type='EEPROM' size='0x0'/>\n");
|
||||
else if(identifiers.beginswith("FLASH_V" )) markup.append(" <ram name='save.ram' type='FlashROM' size='0x10000'/>\n");
|
||||
else if(identifiers.beginswith("FLASH512_V")) markup.append(" <ram name='save.ram' type='FlashROM' size='0x10000'/>\n");
|
||||
else if(identifiers.beginswith("FLASH1M_V" )) markup.append(" <ram name='save.ram' type='FlashROM' size='0x20000'/>\n");
|
||||
if(identifiers.empty() == false) markup.append(" <!-- detected: ", identifiers, " -->\n");
|
||||
|
||||
markup.append("</cartridge>\n");
|
||||
markup.transform("'", "\"");
|
||||
else if(identifiers.beginswith("SRAM_V" )) markup.append(" ram name=save.ram type=SRAM size=0x8000\n");
|
||||
else if(identifiers.beginswith("SRAM_F_V" )) markup.append(" ram name=save.ram type=FRAM size=0x8000\n");
|
||||
else if(identifiers.beginswith("EEPROM_V" )) markup.append(" ram name=save.ram type=EEPROM size=0x0\n");
|
||||
else if(identifiers.beginswith("FLASH_V" )) markup.append(" ram name=save.ram type=FlashROM size=0x10000\n");
|
||||
else if(identifiers.beginswith("FLASH512_V")) markup.append(" ram name=save.ram type=FlashROM size=0x10000\n");
|
||||
else if(identifiers.beginswith("FLASH1M_V" )) markup.append(" ram name=save.ram type=FlashROM size=0x20000\n");
|
||||
//if(identifiers.empty() == false) markup.append(" #detected: ", identifiers, "\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -108,13 +108,11 @@ GameBoyCartridge::GameBoyCartridge(uint8_t *romdata, unsigned romsize) {
|
|||
|
||||
if(info.mapper == "MBC2") info.ramsize = 512; //512 x 4-bit
|
||||
|
||||
markup = "<?xml version='1.0' encoding='UTF-8'?>\n";
|
||||
markup.append("<cartridge>\n");
|
||||
markup.append(" <board type='", info.mapper, "'/>\n");
|
||||
markup.append(" <rom name='program.rom' size='0x", hex(romsize), "'/>\n");
|
||||
if(info.ramsize > 0) markup.append(" <ram name='save.ram' size='0x", hex(info.ramsize), "'/>\n");
|
||||
markup.append("</cartridge>\n");
|
||||
markup.transform("'", "\"");
|
||||
markup = "";
|
||||
markup.append("cartridge\n");
|
||||
markup.append(" board type=", info.mapper, "\n");
|
||||
markup.append(" rom name=program.rom size=0x", hex(romsize), "\n");
|
||||
if(info.ramsize > 0) markup.append(" ram name=save.ram size=0x", hex(info.ramsize), "\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -76,10 +76,11 @@ struct SuperFamicomCartridge {
|
|||
DSP1HiROM,
|
||||
};
|
||||
|
||||
bool loaded; //is a base cartridge inserted?
|
||||
unsigned crc32; //crc32 of all cartridges (base+slot(s))
|
||||
bool loaded; //is a base cartridge inserted?
|
||||
unsigned crc32; //crc32 of all cartridges (base+slot(s))
|
||||
unsigned rom_size;
|
||||
unsigned ram_size;
|
||||
bool firmware_appended; //true if firmware is appended to end of ROM data
|
||||
|
||||
Mode mode;
|
||||
Type type;
|
||||
|
@ -106,6 +107,8 @@ struct SuperFamicomCartridge {
|
|||
};
|
||||
|
||||
SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size) {
|
||||
firmware_appended = false;
|
||||
|
||||
//skip copier header
|
||||
if((size & 0x7fff) == 512) data += 512, size -= 512;
|
||||
|
||||
|
@ -122,35 +125,49 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
|
|||
const char *range = (rom_size > 0x200000) || (ram_size > 32 * 1024) ? "0000-7fff" : "0000-ffff";
|
||||
markup.append("cartridge region=", region == NTSC ? "NTSC" : "PAL", "\n");
|
||||
|
||||
if(type == TypeSuperGameBoy1Bios || type == TypeSuperGameBoy2Bios) markup.append(
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" map id=rom address=00-7f,80-ff:8000-ffff\n"
|
||||
" icd2 revision=1\n"
|
||||
" rom name=boot.rom size=0x100\n"
|
||||
" map id=io address=00-3f,80-bf:6000-7fff\n"
|
||||
);
|
||||
if(type == TypeSuperGameBoy1Bios || type == TypeSuperGameBoy2Bios) {
|
||||
markup.append(
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" map id=rom address=00-7f,80-ff:8000-ffff\n"
|
||||
" icd2 revision=1\n"
|
||||
" rom name=boot.rom size=0x100\n"
|
||||
" map id=io address=00-3f,80-bf:6000-7fff\n"
|
||||
);
|
||||
if((rom_size & 0x7fff) == 0x100) {
|
||||
firmware_appended = true;
|
||||
rom_size -= 0x100;
|
||||
}
|
||||
}
|
||||
|
||||
else if(has_cx4) markup.append(
|
||||
" hitachidsp model=HG51B169 frequency=20000000\n"
|
||||
" rom id=program name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" rom id=data name=cx4.data.rom size=0xc00\n"
|
||||
" ram id=data size=0xc00\n"
|
||||
" map id=io address=00-3f,80-bf:6000-7fff\n"
|
||||
" map id=rom address=00-7f,80-ff:8000-ffff mask=0x8000\n"
|
||||
" map id=ram address=70-77:0000-7fff\n"
|
||||
);
|
||||
else if(has_cx4) {
|
||||
markup.append(
|
||||
" hitachidsp model=HG51B169 frequency=20000000\n"
|
||||
" rom id=program name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" rom id=data name=cx4.data.rom size=0xc00\n"
|
||||
" ram id=data size=0xc00\n"
|
||||
" map id=io address=00-3f,80-bf:6000-7fff\n"
|
||||
" map id=rom address=00-7f,80-ff:8000-ffff mask=0x8000\n"
|
||||
" map id=ram address=70-77:0000-7fff\n"
|
||||
);
|
||||
if((rom_size & 0x7fff) == 0xc00) {
|
||||
firmware_appended = true;
|
||||
rom_size -= 0xc00;
|
||||
}
|
||||
}
|
||||
|
||||
else if(has_spc7110) markup.append(
|
||||
" spc7110\n"
|
||||
" rom id=program name=program.rom size=0x100000\n"
|
||||
" rom id=data name=data.rom size=0x", hex(rom_size - 0x100000), "\n"
|
||||
" ram name=save.ram size=0x", hex(ram_size), "\n"
|
||||
" map id=io address=00-3f,80-bf:4800-483f\n"
|
||||
" map id=io address=50:0000-ffff\n"
|
||||
" map id=rom address=00-3f,80-bf:8000-ffff\n"
|
||||
" map id=rom address=c0-ff:0000-ffff\n"
|
||||
" map id=ram address=00-3f,80-bf:6000-7fff mask=0xe000\n"
|
||||
);
|
||||
else if(has_spc7110) {
|
||||
markup.append(
|
||||
" spc7110\n"
|
||||
" rom id=program name=program.rom size=0x100000\n"
|
||||
" rom id=data name=data.rom size=0x", hex(rom_size - 0x100000), "\n"
|
||||
" ram name=save.ram size=0x", hex(ram_size), "\n"
|
||||
" map id=io address=00-3f,80-bf:4800-483f\n"
|
||||
" map id=io address=50:0000-ffff\n"
|
||||
" map id=rom address=00-3f,80-bf:8000-ffff\n"
|
||||
" map id=rom address=c0-ff:0000-ffff\n"
|
||||
" map id=ram address=00-3f,80-bf:6000-7fff mask=0xe000\n"
|
||||
);
|
||||
}
|
||||
|
||||
else if(has_sdd1) {
|
||||
markup.append(
|
||||
|
@ -280,69 +297,83 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
|
|||
);
|
||||
}
|
||||
|
||||
else if(mapper == BSCLoROM) markup.append(
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" ram name=save.ram size=0x", hex(ram_size), "\n"
|
||||
" map id=rom address=00-1f:8000-ffff offset=0x000000 mask=0x8000\n"
|
||||
" map id=rom address=20-3f:8000-ffff offset=0x100000 mask=0x8000\n"
|
||||
" map id=rom address=80-9f:8000-ffff offset=0x200000 mask=0x8000\n"
|
||||
" map id=rom address=a0-bf:8000-ffff offset=0x100000 mask=0x8000\n"
|
||||
" map id=ram address=70-7f,f0-ff:0000-7fff\n"
|
||||
" bsxslot\n"
|
||||
" map id=rom address=c0-ef:0000-ffff\n"
|
||||
);
|
||||
else if(mapper == BSCLoROM) {
|
||||
markup.append(
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" ram name=save.ram size=0x", hex(ram_size), "\n"
|
||||
" map id=rom address=00-1f:8000-ffff offset=0x000000 mask=0x8000\n"
|
||||
" map id=rom address=20-3f:8000-ffff offset=0x100000 mask=0x8000\n"
|
||||
" map id=rom address=80-9f:8000-ffff offset=0x200000 mask=0x8000\n"
|
||||
" map id=rom address=a0-bf:8000-ffff offset=0x100000 mask=0x8000\n"
|
||||
" map id=ram address=70-7f,f0-ff:0000-7fff\n"
|
||||
" bsxslot\n"
|
||||
" map id=rom address=c0-ef:0000-ffff\n"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == BSCHiROM) markup.append(
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" ram name=save.ram size=0x", hex(ram_size), "\n"
|
||||
" map id=rom address=00-1f,80-9f:8000-ffff\n"
|
||||
" map id=rom address=40-5f,c0-df:0000-ffff\n"
|
||||
" map id=ram address=20-3f,a0-bf:6000-7fff\n"
|
||||
" bsxslot\n"
|
||||
" map id=rom address=20-3f,a0-bf:8000-ffff\n"
|
||||
" map id=rom address=60-7f,e0-ff:0000-ffff\n"
|
||||
);
|
||||
else if(mapper == BSCHiROM) {
|
||||
markup.append(
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" ram name=save.ram size=0x", hex(ram_size), "\n"
|
||||
" map id=rom address=00-1f,80-9f:8000-ffff\n"
|
||||
" map id=rom address=40-5f,c0-df:0000-ffff\n"
|
||||
" map id=ram address=20-3f,a0-bf:6000-7fff\n"
|
||||
" bsxslot\n"
|
||||
" map id=rom address=20-3f,a0-bf:8000-ffff\n"
|
||||
" map id=rom address=60-7f,e0-ff:0000-ffff\n"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == BSXROM) markup.append(
|
||||
" bsx\n"
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" ram id=save name=save.ram size=0x", hex(ram_size), "\n"
|
||||
" ram id=download name=bsx.ram size=0x40000\n"
|
||||
" map id=io address=00-3f,80-bf:5000-5fff\n"
|
||||
" map id=rom address=00-3f,80-bf:8000-ffff\n"
|
||||
" map id=rom address=40-7f,c0-ff:0000-ffff\n"
|
||||
" map id=ram address=20-3f:6000-7fff\n"
|
||||
);
|
||||
else if(mapper == BSXROM) {
|
||||
markup.append(
|
||||
" bsx\n"
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" ram id=save name=save.ram size=0x", hex(ram_size), "\n"
|
||||
" ram id=download name=bsx.ram size=0x40000\n"
|
||||
" map id=io address=00-3f,80-bf:5000-5fff\n"
|
||||
" map id=rom address=00-3f,80-bf:8000-ffff\n"
|
||||
" map id=rom address=40-7f,c0-ff:0000-ffff\n"
|
||||
" map id=ram address=20-3f:6000-7fff\n"
|
||||
);
|
||||
}
|
||||
|
||||
else if(mapper == STROM) markup.append(
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" map id=rom address='00-1f,80-9f:8000-ffff mask=0x8000\n"
|
||||
" sufamiturbo\n"
|
||||
" slot id=A\n"
|
||||
" map id=rom address=20-3f,a0-bf:8000-ffff mask=0x8000\n"
|
||||
" map id=ram address=60-63,e0-e3:8000-ffff\n"
|
||||
" slot id=B\n"
|
||||
" map id=rom address=40-5f,c0-df:8000-ffff mask=0x8000\n"
|
||||
" map id=ram address=70-73,f0-f3:8000-ffff\n"
|
||||
);
|
||||
else if(mapper == STROM) {
|
||||
markup.append(
|
||||
" rom name=program.rom size=0x", hex(rom_size), "\n"
|
||||
" map id=rom address='00-1f,80-9f:8000-ffff mask=0x8000\n"
|
||||
" sufamiturbo\n"
|
||||
" slot id=A\n"
|
||||
" map id=rom address=20-3f,a0-bf:8000-ffff mask=0x8000\n"
|
||||
" map id=ram address=60-63,e0-e3:8000-ffff\n"
|
||||
" slot id=B\n"
|
||||
" map id=rom address=40-5f,c0-df:8000-ffff mask=0x8000\n"
|
||||
" map id=ram address=70-73,f0-f3:8000-ffff\n"
|
||||
);
|
||||
}
|
||||
|
||||
if(has_spc7110rtc) markup.append(
|
||||
" epsonrtc\n"
|
||||
" ram name=rtc.ram size=0x10\n"
|
||||
" map id=io address=00-3f,80-bf:4840-4842\n"
|
||||
);
|
||||
if(has_spc7110rtc) {
|
||||
markup.append(
|
||||
" epsonrtc\n"
|
||||
" ram name=rtc.ram size=0x10\n"
|
||||
" map id=io address=00-3f,80-bf:4840-4842\n"
|
||||
);
|
||||
}
|
||||
|
||||
if(has_srtc) markup.append(
|
||||
" sharprtc\n"
|
||||
" ram name=rtc.ram size=0x10\n"
|
||||
" map id=io address=00-3f,80-bf:2800-2801\n"
|
||||
);
|
||||
if(has_srtc) {
|
||||
markup.append(
|
||||
" sharprtc\n"
|
||||
" ram name=rtc.ram size=0x10\n"
|
||||
" map id=io address=00-3f,80-bf:2800-2801\n"
|
||||
);
|
||||
}
|
||||
|
||||
if(has_obc1) markup.append(
|
||||
" obc1\n"
|
||||
" ram name=save.ram size=0x2000\n"
|
||||
" map id=io address=00-3f,80-bf:6000-7fff\n"
|
||||
);
|
||||
if(has_obc1) {
|
||||
markup.append(
|
||||
" obc1\n"
|
||||
" ram name=save.ram size=0x2000\n"
|
||||
" map id=io address=00-3f,80-bf:6000-7fff\n"
|
||||
);
|
||||
}
|
||||
|
||||
if(has_dsp1) {
|
||||
markup.append(
|
||||
|
@ -360,57 +391,97 @@ SuperFamicomCartridge::SuperFamicomCartridge(const uint8_t *data, unsigned size)
|
|||
if(dsp1_mapper == DSP1HiROM) markup.append(
|
||||
" map id=io address=00-1f,80-9f:6000-7fff select=0x1000\n"
|
||||
);
|
||||
if((size & 0x7fff) == 0x2000) {
|
||||
firmware_appended = true;
|
||||
rom_size -= 0x2000;
|
||||
}
|
||||
}
|
||||
|
||||
if(has_dsp2) markup.append(
|
||||
" necdsp model=uPD7725 frequency=8000000\n"
|
||||
" rom id=program name=dsp2.program.rom size=0x1800\n"
|
||||
" rom id=data name=dsp2.data.rom size=0x800\n"
|
||||
" ram id=data size=0x200\n"
|
||||
" map id=io address=20-3f,a0-bf:8000-ffff select=0x4000\n"
|
||||
);
|
||||
if(has_dsp2) {
|
||||
markup.append(
|
||||
" necdsp model=uPD7725 frequency=8000000\n"
|
||||
" rom id=program name=dsp2.program.rom size=0x1800\n"
|
||||
" rom id=data name=dsp2.data.rom size=0x800\n"
|
||||
" ram id=data size=0x200\n"
|
||||
" map id=io address=20-3f,a0-bf:8000-ffff select=0x4000\n"
|
||||
);
|
||||
if((size & 0x7fff) == 0x2000) {
|
||||
firmware_appended = true;
|
||||
rom_size -= 0x2000;
|
||||
}
|
||||
}
|
||||
|
||||
if(has_dsp3) markup.append(
|
||||
" necdsp model=uPD7725 frequency=8000000\n"
|
||||
" rom id=program name=dsp3.program.rom size=0x1800\n"
|
||||
" rom id=data name=dsp3.data.rom size=0x800\n"
|
||||
" ram id=data size=0x200\n"
|
||||
" map id=io address=20-3f,a0-bf:8000-ffff select=0x4000\n"
|
||||
);
|
||||
if(has_dsp3) {
|
||||
markup.append(
|
||||
" necdsp model=uPD7725 frequency=8000000\n"
|
||||
" rom id=program name=dsp3.program.rom size=0x1800\n"
|
||||
" rom id=data name=dsp3.data.rom size=0x800\n"
|
||||
" ram id=data size=0x200\n"
|
||||
" map id=io address=20-3f,a0-bf:8000-ffff select=0x4000\n"
|
||||
);
|
||||
if((size & 0x7fff) == 0x2000) {
|
||||
firmware_appended = true;
|
||||
rom_size -= 0x2000;
|
||||
}
|
||||
}
|
||||
|
||||
if(has_dsp4) markup.append(
|
||||
" necdsp model=uPD7725 frequency=8000000\n"
|
||||
" rom id=program name=dsp4.program.rom size=0x1800\n"
|
||||
" rom id=data name=dsp4.data.rom size=0x800\n"
|
||||
" ram id=data size=0x200\n"
|
||||
" map address=30-3f,b0-bf:8000-ffff select=0x4000\n"
|
||||
);
|
||||
if(has_dsp4) {
|
||||
markup.append(
|
||||
" necdsp model=uPD7725 frequency=8000000\n"
|
||||
" rom id=program name=dsp4.program.rom size=0x1800\n"
|
||||
" rom id=data name=dsp4.data.rom size=0x800\n"
|
||||
" ram id=data size=0x200\n"
|
||||
" map address=30-3f,b0-bf:8000-ffff select=0x4000\n"
|
||||
);
|
||||
if((size & 0x7fff) == 0x2000) {
|
||||
firmware_appended = true;
|
||||
rom_size -= 0x2000;
|
||||
}
|
||||
}
|
||||
|
||||
if(has_st010) markup.append(
|
||||
" necdsp model=uPD96050 frequency=11000000\n"
|
||||
" rom id=program name=st010.program.rom size=0xc000\n"
|
||||
" rom id=data name=st010.data.rom size=0x1000\n"
|
||||
" ram id=data name=save.ram size=0x1000\n"
|
||||
" map id=io address=60-67,e0-e7:0000-3fff select=0x0001\n"
|
||||
" map id=ram address=68-6f,e8-ef:0000-7fff\n"
|
||||
);
|
||||
if(has_st010) {
|
||||
markup.append(
|
||||
" necdsp model=uPD96050 frequency=11000000\n"
|
||||
" rom id=program name=st010.program.rom size=0xc000\n"
|
||||
" rom id=data name=st010.data.rom size=0x1000\n"
|
||||
" ram id=data name=save.ram size=0x1000\n"
|
||||
" map id=io address=60-67,e0-e7:0000-3fff select=0x0001\n"
|
||||
" map id=ram address=68-6f,e8-ef:0000-7fff\n"
|
||||
);
|
||||
if((size & 0xffff) == 0xd000) {
|
||||
firmware_appended = true;
|
||||
rom_size -= 0xd000;
|
||||
}
|
||||
}
|
||||
|
||||
if(has_st011) markup.append(
|
||||
" necdsp model=uPD96050 frequency=15000000\n"
|
||||
" rom id=program name=st011.program.rom size=0xc000\n"
|
||||
" rom id=data name=st011.data.rom size=0x1000\n"
|
||||
" ram id=data name=save.ram size=0x1000\n"
|
||||
" map id=io address=60-67,e0-e7:0000-3fff select=0x0001\n"
|
||||
" map id=ram address=68-6f,e8-ef:0000-7fff\n"
|
||||
);
|
||||
if(has_st011) {
|
||||
markup.append(
|
||||
" necdsp model=uPD96050 frequency=15000000\n"
|
||||
" rom id=program name=st011.program.rom size=0xc000\n"
|
||||
" rom id=data name=st011.data.rom size=0x1000\n"
|
||||
" ram id=data name=save.ram size=0x1000\n"
|
||||
" map id=io address=60-67,e0-e7:0000-3fff select=0x0001\n"
|
||||
" map id=ram address=68-6f,e8-ef:0000-7fff\n"
|
||||
);
|
||||
if((size & 0xffff) == 0xd000) {
|
||||
firmware_appended = true;
|
||||
rom_size -= 0xd000;
|
||||
}
|
||||
}
|
||||
|
||||
if(has_st018) markup.append(
|
||||
" armdsp frequency=21477272\n"
|
||||
" rom id=program name=st018.program.rom size=0x20000\n"
|
||||
" rom id=data name=st018.data.rom size=0x8000\n"
|
||||
" ram name=save.ram size=0x4000\n"
|
||||
" map id=io address=00-3f,80-bf:3800-38ff\n"
|
||||
);
|
||||
if(has_st018) {
|
||||
markup.append(
|
||||
" armdsp frequency=21477272\n"
|
||||
" rom id=program name=st018.program.rom size=0x20000\n"
|
||||
" rom id=data name=st018.data.rom size=0x8000\n"
|
||||
" ram name=save.ram size=0x4000\n"
|
||||
" map id=io address=00-3f,80-bf:3800-38ff\n"
|
||||
);
|
||||
if((size & 0x3ffff) == 0x28000) {
|
||||
firmware_appended = true;
|
||||
rom_size -= 0x28000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SuperFamicomCartridge::read_header(const uint8_t *data, unsigned size) {
|
||||
|
@ -464,6 +535,7 @@ void SuperFamicomCartridge::read_header(const uint8_t *data, unsigned size) {
|
|||
|
||||
ram_size = 1024 << (data[index + RamSize] & 7);
|
||||
if(ram_size == 1024) ram_size = 0; //no RAM present
|
||||
if(rom_size == 0 && ram_size) ram_size = 0; //fix for Bazooka Blitzkrieg's malformed header (swapped ROM and RAM sizes)
|
||||
|
||||
//0, 1, 13 = NTSC; 2 - 12 = PAL
|
||||
region = (regionid <= 1 || regionid >= 13) ? NTSC : PAL;
|
||||
|
|
|
@ -119,6 +119,7 @@ namespace nall {
|
|||
inline optional<unsigned> find(const char*) const;
|
||||
inline string concatenate(const char*) const;
|
||||
inline void append() {}
|
||||
inline void isort();
|
||||
template<typename... Args> inline void append(const string&, Args&&...);
|
||||
|
||||
template<unsigned Limit = 0> inline lstring& split(const char*, const char*);
|
||||
|
|
|
@ -151,6 +151,12 @@ template<typename... Args> void lstring::append(const string &data, Args&&... ar
|
|||
append(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
void lstring::isort() {
|
||||
nall::sort(pool, objectsize, [](const string &x, const string &y) {
|
||||
return istrcmp(x, y) < 0;
|
||||
});
|
||||
}
|
||||
|
||||
bool lstring::operator==(const lstring &source) const {
|
||||
if(this == &source) return true;
|
||||
if(size() != source.size()) return false;
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 844 B |
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
After Width: | Height: | Size: 606 B |
|
@ -0,0 +1,5 @@
|
|||
resource name=resource
|
||||
binary id=home name=home.png
|
||||
binary id=up name=up.png
|
||||
binary id=folder name=folder.png
|
||||
binary id=file name=file.png
|
|
@ -0,0 +1,119 @@
|
|||
namespace resource {
|
||||
|
||||
const uint8_t home[606] = {
|
||||
137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255,
|
||||
97,0,0,0,6,98,75,71,68,0,0,0,0,0,0,249,67,187,127,0,0,0,9,112,72,89,115,0,0,13,215,0,
|
||||
0,13,215,1,66,40,155,120,0,0,0,7,116,73,77,69,7,213,10,14,20,37,19,83,42,210,59,0,0,1,235,73,
|
||||
68,65,84,56,203,149,147,191,107,83,81,20,128,191,123,251,222,75,211,64,242,36,160,85,135,100,81,123,19,104,85,172,
|
||||
17,92,28,140,66,19,167,135,212,74,39,145,162,163,24,92,58,180,110,193,169,254,24,234,212,37,139,245,199,96,19,240,
|
||||
15,240,63,16,121,91,92,196,90,219,240,98,81,137,33,121,215,33,246,217,151,80,33,103,186,92,206,247,221,115,14,231,
|
||||
194,1,225,41,85,172,128,174,128,246,148,122,200,48,177,7,123,74,105,79,169,61,73,113,104,120,177,56,163,203,55,111,
|
||||
252,87,34,250,225,154,235,110,20,148,98,253,220,89,182,39,78,113,228,240,56,39,188,38,83,107,107,212,92,151,130,82,
|
||||
215,14,185,110,117,64,176,31,126,83,156,97,247,248,49,148,202,50,22,141,210,106,181,24,219,252,74,182,92,30,144,136,
|
||||
126,184,122,251,22,157,100,146,116,42,77,42,149,2,64,107,104,183,219,236,214,235,156,44,149,66,18,177,31,126,247,160,
|
||||
68,199,48,201,229,46,96,219,118,208,154,214,26,0,223,247,249,185,181,69,114,110,46,144,136,10,232,130,82,188,127,84,
|
||||
198,107,54,57,63,157,35,30,143,35,132,8,9,124,223,15,206,134,16,140,230,243,212,92,23,3,184,3,172,78,157,62,
|
||||
195,253,210,61,54,170,111,3,240,201,202,51,86,30,63,69,139,17,116,167,133,48,70,209,221,223,44,47,45,209,238,165,
|
||||
204,202,121,120,190,48,153,33,17,79,0,160,212,4,153,140,34,155,205,244,94,20,146,145,244,149,222,196,83,121,144,22,
|
||||
90,107,22,38,51,204,195,186,236,239,211,178,44,76,211,196,48,140,224,254,75,227,7,0,31,234,59,116,187,126,144,11,
|
||||
48,32,144,82,34,165,196,146,159,1,232,96,241,241,83,3,128,111,222,47,58,34,18,90,36,99,96,179,254,14,207,231,
|
||||
40,0,151,46,78,115,53,26,67,234,113,46,75,147,237,77,66,21,24,253,21,252,155,126,239,165,239,222,14,162,217,56,
|
||||
112,245,3,65,36,18,193,182,109,18,137,4,2,137,16,16,139,197,112,28,103,0,178,44,43,252,23,174,207,58,175,0,
|
||||
135,225,98,245,229,139,215,119,255,0,86,248,213,163,133,187,128,26,0,0,0,0,73,69,78,68,174,66,96,130,
|
||||
};
|
||||
|
||||
const uint8_t up[652] = {
|
||||
137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,16,0,0,0,16,8,6,0,0,0,31,243,255,
|
||||
97,0,0,0,4,115,66,73,84,8,8,8,8,124,8,100,136,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,
|
||||
101,0,119,119,119,46,105,110,107,115,99,97,112,101,46,111,114,103,155,238,60,26,0,0,2,30,73,68,65,84,56,141,
|
||||
149,147,79,104,19,65,20,198,191,55,187,51,217,141,133,122,104,76,255,209,130,4,237,193,64,42,168,208,213,138,104,68,
|
||||
98,69,45,20,114,107,74,201,73,144,98,22,193,171,199,82,145,160,23,15,69,79,30,165,66,241,226,77,42,94,68,80,
|
||||
208,67,41,180,42,149,148,52,137,166,154,38,217,217,25,15,81,172,33,169,246,29,223,251,230,199,124,223,155,33,173,53,
|
||||
218,213,201,155,124,30,0,150,102,189,233,118,26,214,110,224,184,60,221,223,21,73,246,117,29,76,58,46,79,239,9,224,
|
||||
184,60,26,16,251,178,87,206,76,6,199,70,147,193,128,8,102,29,151,71,255,11,224,184,188,3,132,197,137,115,211,214,
|
||||
150,151,199,150,183,137,248,200,37,11,132,69,199,229,29,255,4,16,225,209,232,112,162,167,55,52,72,159,75,31,240,177,
|
||||
244,30,157,157,157,20,27,58,209,13,194,195,93,1,142,203,211,253,7,34,137,179,71,199,249,74,254,13,12,198,97,50,
|
||||
142,87,107,11,136,13,29,23,161,253,61,137,230,60,216,142,195,81,193,237,108,42,225,218,235,229,101,104,242,32,132,137,
|
||||
58,125,199,54,21,241,46,255,28,23,78,95,13,154,166,248,43,15,182,211,247,212,88,198,82,228,161,34,75,16,1,1,
|
||||
30,224,40,203,117,8,219,64,65,174,162,168,86,113,254,212,69,139,216,159,60,216,111,223,241,99,227,221,135,250,98,148,
|
||||
175,172,193,228,6,56,55,80,81,5,84,141,175,16,54,131,176,25,150,191,189,64,184,55,68,71,14,15,135,137,53,242,
|
||||
160,145,140,153,30,232,142,100,111,76,220,177,5,15,64,65,194,135,135,215,185,5,188,45,60,131,100,21,16,35,36,6,
|
||||
50,208,90,67,41,160,94,175,225,241,211,249,74,177,180,57,99,18,67,234,83,110,197,158,185,119,185,225,137,163,122,247,
|
||||
250,19,171,44,115,240,141,109,112,193,192,76,130,193,9,115,15,110,87,101,77,91,191,236,7,137,33,101,46,205,122,78,
|
||||
211,38,180,214,10,165,250,23,48,131,96,112,6,30,104,64,100,77,91,47,231,60,218,245,29,0,128,210,62,126,212,139,
|
||||
141,43,251,26,178,174,160,85,235,63,99,182,106,250,74,162,90,219,134,50,53,160,21,124,73,240,189,61,0,164,47,17,
|
||||
31,188,6,98,0,49,2,17,246,0,32,108,220,186,63,25,110,37,38,194,70,115,239,39,48,247,197,219,182,208,154,34,
|
||||
0,0,0,0,73,69,78,68,174,66,96,130,
|
||||
};
|
||||
|
||||
const uint8_t folder[1176] = {
|
||||
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,0,9,112,72,89,115,0,0,13,215,0,0,13,
|
||||
215,1,66,40,155,120,0,0,0,25,116,69,88,116,83,111,102,116,119,97,114,101,0,119,119,119,46,105,110,107,115,99,
|
||||
97,112,101,46,111,114,103,155,238,60,26,0,0,4,21,73,68,65,84,88,133,237,151,61,111,28,69,24,199,127,51,187,
|
||||
119,123,175,246,57,145,48,9,5,86,148,194,31,0,9,5,33,83,110,149,130,26,137,2,90,58,62,64,36,62,64,74,
|
||||
132,68,133,104,161,67,72,167,64,23,201,138,2,138,210,69,194,198,196,40,22,198,247,186,119,222,151,153,157,25,138,123,
|
||||
201,58,119,142,19,114,82,40,248,75,143,118,118,118,247,121,126,243,60,51,179,187,34,12,67,94,167,228,107,141,254,95,
|
||||
0,240,1,110,220,184,225,43,165,126,54,198,188,119,209,3,66,136,220,90,251,249,195,135,15,191,92,25,64,154,166,91,
|
||||
149,74,229,157,155,55,111,250,73,146,224,156,3,192,90,11,48,63,159,182,253,59,119,238,220,222,222,222,254,254,209,163,
|
||||
71,199,43,1,80,74,101,213,106,213,29,29,29,209,233,116,112,206,45,53,0,33,4,155,155,155,249,193,193,193,71,192,
|
||||
237,149,0,104,173,211,44,203,196,165,75,27,24,99,176,214,158,9,92,204,132,16,130,106,181,90,63,60,60,252,98,123,
|
||||
123,251,214,172,127,153,156,115,218,90,251,241,222,222,222,143,207,5,0,178,44,203,188,78,167,75,167,211,153,3,204,142,
|
||||
179,32,197,64,91,91,91,245,70,163,65,179,217,68,8,129,16,2,0,41,229,188,29,69,17,247,238,221,187,5,60,31,
|
||||
224,242,229,203,105,191,223,247,54,54,90,104,173,23,0,150,149,98,166,56,142,1,230,16,69,139,227,24,99,76,237,188,
|
||||
224,115,128,221,221,93,117,237,218,53,217,235,245,230,25,0,150,130,204,178,81,212,108,196,197,224,82,202,25,64,229,66,
|
||||
0,0,99,140,109,54,215,100,154,102,220,63,180,220,221,63,27,228,188,58,63,171,25,204,228,153,22,206,93,185,206,219,
|
||||
31,232,226,61,158,39,190,93,255,253,155,79,206,0,56,231,116,183,219,245,187,221,46,143,59,13,62,253,240,93,174,191,
|
||||
181,81,112,54,61,62,47,250,18,200,105,207,60,206,147,206,152,175,190,187,255,254,236,188,152,1,221,104,212,171,90,107,
|
||||
212,31,146,102,181,204,254,223,99,162,56,159,140,108,233,104,207,35,17,11,77,1,52,42,62,42,211,8,65,103,118,121,
|
||||
190,21,27,99,116,191,63,160,219,237,18,103,150,122,181,132,53,147,27,228,212,193,179,134,59,207,220,83,179,19,179,214,
|
||||
145,100,134,52,203,193,137,249,6,86,44,65,86,169,4,180,90,45,50,35,168,5,37,172,83,120,114,53,175,139,113,154,
|
||||
83,111,250,140,134,57,214,186,39,11,0,121,158,171,40,26,209,239,15,208,230,13,170,129,143,115,14,79,158,155,231,23,
|
||||
147,131,81,170,209,185,37,240,37,113,170,173,49,249,209,2,128,49,38,43,151,75,84,155,27,172,213,202,56,64,10,177,
|
||||
188,248,47,40,227,28,163,84,147,91,135,231,9,130,178,199,105,146,41,33,196,201,2,128,181,54,27,141,198,28,15,20,
|
||||
235,245,75,232,220,190,210,232,51,109,137,51,3,78,224,79,253,148,61,201,232,84,229,130,167,147,176,152,129,212,247,125,
|
||||
188,32,160,73,153,76,217,11,131,76,230,152,195,186,201,62,97,236,196,84,110,151,173,72,156,131,193,40,181,185,115,139,
|
||||
0,214,218,100,60,30,211,25,248,84,90,101,162,68,147,233,233,75,8,200,141,69,27,135,206,45,185,153,110,203,47,153,
|
||||
149,68,25,134,227,196,19,210,91,90,130,84,8,129,12,26,148,74,62,163,68,19,37,154,84,25,148,182,47,29,108,153,
|
||||
226,44,231,52,209,62,231,148,32,142,227,83,122,81,133,74,13,30,159,196,12,99,189,212,209,191,145,0,134,177,66,25,
|
||||
83,250,245,234,94,47,124,252,12,128,181,54,6,129,245,107,100,185,37,138,53,74,95,60,15,94,84,82,10,78,134,9,
|
||||
82,200,56,220,221,157,59,62,51,7,146,36,33,74,12,87,175,4,84,3,143,160,188,186,111,86,41,4,105,170,144,82,
|
||||
12,139,253,197,18,36,0,154,18,235,85,143,122,105,21,85,127,42,231,28,253,36,65,88,59,88,0,104,183,219,98,103,
|
||||
103,199,68,177,98,112,234,248,243,100,136,236,190,226,14,184,68,199,199,67,155,36,195,7,187,237,118,45,12,195,120,14,
|
||||
0,120,81,20,253,244,203,161,248,76,173,227,255,182,255,202,31,187,103,228,192,2,88,157,30,28,63,248,225,235,226,53,
|
||||
49,251,53,107,183,219,205,96,109,237,205,90,208,218,116,56,41,133,92,201,18,200,141,49,42,75,107,185,16,121,62,58,
|
||||
233,1,127,133,97,216,91,0,152,66,72,32,96,146,153,124,21,0,83,5,64,10,168,48,12,207,44,45,241,255,207,233,
|
||||
235,6,248,7,188,50,165,151,203,8,55,43,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,
|
||||
48,24,197,127,182,227,56,81,39,116,36,132,0,169,167,226,2,101,209,93,239,192,150,37,171,46,43,245,4,92,164,183,
|
||||
40,82,89,21,36,134,84,76,18,59,44,90,91,142,243,103,50,21,59,62,201,138,227,120,236,247,189,247,252,37,3,255,
|
||||
123,136,116,224,234,234,234,67,150,101,55,64,165,148,66,74,137,115,14,107,109,104,93,215,133,107,220,95,26,3,118,93,
|
||||
215,125,188,185,185,249,26,239,151,141,16,9,113,125,113,113,81,61,247,195,120,223,247,131,121,241,253,202,126,117,121,121,
|
||||
121,13,44,3,176,214,110,1,110,111,111,17,66,32,165,12,87,41,37,74,41,148,82,8,33,80,74,177,221,110,209,90,
|
||||
15,158,167,125,33,4,251,253,158,166,105,182,233,126,50,29,232,251,30,33,68,104,64,88,208,55,207,78,215,117,24,99,
|
||||
70,191,247,109,77,140,24,112,206,133,13,98,6,210,38,165,164,40,138,48,127,42,60,16,159,200,20,168,17,3,206,185,
|
||||
17,11,177,4,49,40,231,28,77,211,28,204,114,137,141,17,0,107,109,232,207,177,224,159,41,165,208,90,31,100,97,9,
|
||||
200,36,3,233,230,233,189,181,150,60,207,41,203,146,186,174,233,186,46,204,91,202,124,21,0,207,192,156,9,1,140,49,
|
||||
20,69,65,93,215,100,89,70,158,231,3,173,231,50,127,17,128,88,123,127,239,105,55,198,96,140,161,109,219,85,174,95,
|
||||
13,96,202,132,41,35,62,218,182,5,240,213,110,113,211,163,25,72,179,23,66,208,52,13,90,235,80,92,252,243,199,199,
|
||||
199,229,244,97,210,172,7,37,136,93,47,165,164,170,42,178,44,67,8,193,201,201,73,232,151,101,57,152,63,197,194,139,
|
||||
37,136,77,168,181,198,90,27,42,97,215,117,97,222,210,113,92,205,128,215,50,205,222,103,16,75,226,156,11,12,120,64,
|
||||
62,203,41,38,142,146,32,213,190,239,123,172,181,225,69,228,105,143,193,214,117,141,115,110,86,134,163,0,196,11,11,33,
|
||||
200,178,140,170,170,6,115,235,186,14,114,120,79,40,165,70,155,28,205,64,74,181,7,32,165,28,248,195,24,67,158,231,
|
||||
1,172,82,106,117,89,158,5,144,158,231,212,7,113,40,165,6,12,120,169,210,170,184,20,171,142,161,47,54,177,254,254,
|
||||
236,123,205,227,58,177,219,237,86,3,152,250,34,26,80,37,132,96,179,217,80,150,229,200,96,155,205,6,173,245,96,190,
|
||||
49,38,48,177,6,196,162,9,189,15,178,44,27,140,123,96,109,219,142,36,136,95,90,107,98,214,3,177,9,211,240,99,
|
||||
190,8,77,197,161,162,52,11,32,149,96,238,37,3,79,18,164,0,60,232,135,135,135,17,107,171,1,132,135,82,6,157,
|
||||
227,240,0,119,187,221,8,160,63,5,167,167,167,65,138,163,62,201,226,5,189,235,167,88,232,251,30,173,245,36,56,95,
|
||||
71,252,247,229,82,164,167,160,146,82,254,234,251,254,213,217,217,89,24,156,211,185,40,138,197,197,211,242,155,231,249,14,
|
||||
120,7,252,4,246,41,128,10,120,115,127,127,255,249,252,252,252,19,80,46,174,190,50,242,60,167,105,26,132,16,127,238,
|
||||
238,238,190,0,239,1,5,124,7,92,156,90,14,188,5,94,3,91,192,60,79,252,23,241,135,167,100,107,224,7,240,13,
|
||||
248,13,19,127,78,159,55,46,158,1,173,43,103,135,195,1,45,79,180,239,129,96,140,191,182,58,238,12,241,249,173,246,
|
||||
0,0,0,0,73,69,78,68,174,66,96,130,
|
||||
};
|
||||
|
||||
};
|
|
@ -0,0 +1,6 @@
|
|||
namespace resource {
|
||||
extern const uint8_t home[606];
|
||||
extern const uint8_t up[652];
|
||||
extern const uint8_t folder[1176];
|
||||
extern const uint8_t file[844];
|
||||
};
|
Binary file not shown.
After Width: | Height: | Size: 652 B |
|
@ -1,3 +1,17 @@
|
|||
void Ananke::copySuperFamicomSaves(const string &pathname) {
|
||||
if(!file::exists({pathname, "save.ram"})) {
|
||||
if(file::exists({information.path, nall::basename(information.name), ".srm"})) {
|
||||
file::copy({information.path, nall::basename(information.name), ".srm"}, {pathname, "save.ram"});
|
||||
}
|
||||
}
|
||||
|
||||
if(!file::exists({pathname, "rtc.ram"})) {
|
||||
if(file::exists({information.path, nall::basename(information.name), ".rtc"})) {
|
||||
file::copy({information.path, nall::basename(information.name), ".rtc"}, {pathname, "rtc.ram"});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string Ananke::createSuperFamicomDatabase(vector<uint8_t> &buffer, Markup::Node &document, const string &manifest) {
|
||||
string pathname = {
|
||||
userpath(), "Emulation/Super Famicom/",
|
||||
|
@ -8,7 +22,7 @@ string Ananke::createSuperFamicomDatabase(vector<uint8_t> &buffer, Markup::Node
|
|||
};
|
||||
directory::create(pathname);
|
||||
|
||||
//strip "release" root node from database entry
|
||||
//strip "release" root node from database entry (since a single game manifest isn't part of a database)
|
||||
string markup = manifest;
|
||||
markup.replace("\n ", "\n");
|
||||
markup.replace("information", "\ninformation");
|
||||
|
@ -25,6 +39,7 @@ string Ananke::createSuperFamicomDatabase(vector<uint8_t> &buffer, Markup::Node
|
|||
offset += size;
|
||||
}
|
||||
|
||||
copySuperFamicomSaves(pathname);
|
||||
return pathname;
|
||||
}
|
||||
|
||||
|
@ -32,7 +47,7 @@ string Ananke::createSuperFamicomHeuristic(vector<uint8_t> &buffer) {
|
|||
string pathname = {
|
||||
userpath(), "Emulation/Super Famicom/",
|
||||
nall::basename(information.name),
|
||||
" (unverified).sfc/"
|
||||
" (!).sfc/"
|
||||
};
|
||||
directory::create(pathname);
|
||||
|
||||
|
@ -41,17 +56,36 @@ string Ananke::createSuperFamicomHeuristic(vector<uint8_t> &buffer) {
|
|||
SuperFamicomCartridge info(buffer.data(), buffer.size());
|
||||
string markup = info.markup;
|
||||
if(!information.manifest.empty()) markup = information.manifest; //override with embedded beat manifest, if one exists
|
||||
information.manifest = markup; //save for use with firmware routine below
|
||||
|
||||
file::write({pathname, "manifest.bml"}, markup);
|
||||
|
||||
if(!markup.position("spc7110")) {
|
||||
file::write({pathname, "program.rom"}, buffer);
|
||||
file::write({pathname, "program.rom"}, buffer.data(), info.rom_size);
|
||||
} else {
|
||||
file::write({pathname, "program.rom"}, buffer.data(), 0x100000);
|
||||
file::write({pathname, "data.rom"}, buffer.data() + 0x100000, buffer.size() - 0x100000);
|
||||
file::write({pathname, "data.rom"}, buffer.data() + 0x100000, info.rom_size - 0x100000);
|
||||
}
|
||||
|
||||
auto copyFirmware = [&](const string &name, unsigned programSize, unsigned dataSize) {
|
||||
createSuperFamicomHeuristicFirmware(buffer, pathname, info.firmware_appended);
|
||||
copySuperFamicomSaves(pathname);
|
||||
|
||||
return pathname;
|
||||
}
|
||||
|
||||
void Ananke::createSuperFamicomHeuristicFirmware(vector<uint8_t> &buffer, const string &pathname, bool firmware_appended) {
|
||||
auto copyFirmwareInternal = [&](const string &name, unsigned programSize, unsigned dataSize) {
|
||||
//firmware appended directly onto .sfc file
|
||||
unsigned programOffset = buffer.size() - programSize - dataSize;
|
||||
unsigned dataOffset = buffer.size() - dataSize;
|
||||
|
||||
string basename = nall::basename(name);
|
||||
if(programSize) file::write({pathname, basename, ".program.rom"}, buffer.data() + programOffset, programSize);
|
||||
if(dataSize) file::write({pathname, basename, ".data.rom"}, buffer.data() + dataOffset, dataSize);
|
||||
};
|
||||
|
||||
auto copyFirmwareExternal = [&](const string &name, unsigned programSize, unsigned dataSize) {
|
||||
//firmware stored in external file
|
||||
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) {
|
||||
|
@ -67,6 +101,12 @@ string Ananke::createSuperFamicomHeuristic(vector<uint8_t> &buffer) {
|
|||
if(dataSize) file::write({pathname, basename, ".data.rom"}, buffer.data() + programSize, dataSize);
|
||||
};
|
||||
|
||||
auto copyFirmware = [&](const string &name, unsigned programSize, unsigned dataSize) {
|
||||
if(firmware_appended == 1) copyFirmwareInternal(name, programSize, dataSize);
|
||||
if(firmware_appended == 0) copyFirmwareExternal(name, programSize, dataSize);
|
||||
};
|
||||
|
||||
string markup = information.manifest;
|
||||
if(markup.position("dsp1.program.rom" )) copyFirmware("dsp1.rom", 0x001800, 0x000800);
|
||||
if(markup.position("dsp1b.program.rom")) copyFirmware("dsp1b.rom", 0x001800, 0x000800);
|
||||
if(markup.position("dsp2.program.rom" )) copyFirmware("dsp2.rom", 0x001800, 0x000800);
|
||||
|
@ -76,14 +116,13 @@ string Ananke::createSuperFamicomHeuristic(vector<uint8_t> &buffer) {
|
|||
if(markup.position("st011.program.rom")) copyFirmware("st011.rom", 0x00c000, 0x001000);
|
||||
if(markup.position("st018.program.rom")) copyFirmware("st018.rom", 0x020000, 0x008000);
|
||||
if(markup.position("cx4.data.rom" )) copyFirmware("cx4.rom", 0x000000, 0x000c00);
|
||||
|
||||
return pathname;
|
||||
}
|
||||
|
||||
string Ananke::openSuperFamicom(vector<uint8_t> &buffer) {
|
||||
string sha256 = nall::sha256(buffer.data(), buffer.size());
|
||||
|
||||
string databaseText = string::read({configpath(), "ananke/database/Super Famicom.bml"}).rtrim("\n");
|
||||
if(databaseText.empty()) databaseText = string{Database::SuperFamicom}.strip();
|
||||
lstring databaseItem = databaseText.split("\n\n");
|
||||
|
||||
for(auto &item : databaseItem) {
|
||||
|
|
Loading…
Reference in New Issue