Update to v086r02 release.

byuu says:

Fixed Super Game Boy RAM saving and loading. It plainly wasn't hooked up
at all. Was apparently hard-coded before it became a multi-emulator.
I also fixed a crashing issue when loading Satellaview-slotted or
Satellaview games without specifying the sub-cart, wasn't setting
has_bsx_slot = true, so the raw memory wasn't being allocated internally
when it wasn't mapped in. Of course a better fix would be to just not
physically map the ranges if the things aren't present. Kind of a lazy
hack to map blank cartridges there, but oh well.  Oh, fixed title
displays as well; and did the best I could for now with regards to
multi-file path saving.
This commit is contained in:
Tim Allen 2012-02-16 23:48:05 +11:00
parent a37ce1cb2f
commit 6cfb9e89e7
9 changed files with 89 additions and 32 deletions

View File

@ -1,7 +1,7 @@
#ifndef BASE_HPP
#define BASE_HPP
const char Version[] = "086.01";
const char Version[] = "086.02";
#include <nall/platform.hpp>
#include <nall/algorithm.hpp>

View File

@ -34,7 +34,7 @@ void Cartridge::load(Mode cartridge_mode, const char *markup) {
nvram.reset();
parse_markup(markup);
//print(markup, "\n\n");
print(markup, "\n\n");
if(ram_size > 0) {
ram.map(allocate<uint8>(ram_size, 0xff), ram_size);

View File

@ -334,6 +334,7 @@ void Cartridge::parse_markup_hitachidsp(XML::Node &root) {
void Cartridge::parse_markup_bsx(XML::Node &root) {
if(root.exists() == false) return;
if(mode != Mode::BsxSlotted && mode != Mode::Bsx) return;
has_bsx_slot = true;
for(auto &node : root["slot"]) {
if(node.name != "map") continue;

View File

@ -16,11 +16,13 @@ bool InterfaceGameBoy::loadCartridge(GameBoy::System::Revision revision, const s
interface->base = { true, filename };
} else {
if(file::read(filename, data, size) == false) return false;
interface->base.name = { false, nall::basename(filename) };
interface->base = { false, nall::basename(filename) };
}
interface->unloadCartridge();
//interface->applyPatch(interface->baseName, data, size);
interface->game = interface->base;
interface->cartridgeTitle = interface->base.title();
interface->applyPatch(interface->base, data, size);
string markup;
markup.readfile(interface->base.filename("manifest.xml", ".xml"));

View File

@ -28,6 +28,17 @@ string CartridgePath::filename(const string &folderName, const string &fileName)
return { name, fileName };
}
string CartridgePath::title() const {
if(name.empty()) return "";
if(folder) {
string title = name;
title.rtrim<1>("/");
title = notdir(nall::basename(title));
return title;
}
return notdir(nall::basename(name));
}
void Interface::bindControllers() {
switch(mode()) {
case Mode::NES:
@ -85,10 +96,10 @@ void Interface::loadCartridge(Mode mode) {
}
bindControllers();
cheatEditor->load(base.filename("cheats.xml", ".cht"));
stateManager->load(base.filename("states.bsa", ".bsa"), 0u);
cheatEditor->load(game.filename("cheats.xml", ".cht"));
stateManager->load(game.filename("states.bsa", ".bsa"), 0u);
dipSwitches->load();
utility->showMessage({ "Loaded ", notdir(baseName) });
utility->showMessage({ "Loaded ", cartridgeTitle });
}
bool Interface::loadCartridge(const string &filename) {
@ -103,8 +114,8 @@ bool Interface::loadCartridge(const string &filename) {
void Interface::unloadCartridge() {
if(cartridgeLoaded() == false) return;
cheatDatabase->setVisible(false);
cheatEditor->save(base.filename("cheats.xml", ".cht"));
stateManager->save(base.filename("states.bsa", ".bsa"), 0u);
cheatEditor->save(game.filename("cheats.xml", ".cht"));
stateManager->save(game.filename("states.bsa", ".bsa"), 0u);
setCheatCodes();
switch(mode()) {
@ -113,7 +124,7 @@ void Interface::unloadCartridge() {
case Mode::GameBoy: gameBoy.unloadCartridge(); break;
}
interface->baseName = "";
cartridgeTitle = "";
utility->setMode(mode = Mode::None);
}
@ -145,7 +156,7 @@ bool Interface::unserialize(serializer &s) {
}
bool Interface::saveState(unsigned slot) {
string filename = base.filename({ "state-", slot, ".bst" }, { "-", slot, ".bst" });
string filename = game.filename({ "state-", slot, ".bst" }, { "-", slot, ".bst" });
serializer s = serialize();
bool result = file::write(filename, s.data(), s.size());
utility->showMessage(result == true ? string{ "Saved state ", slot } : "Failed to save state");
@ -153,7 +164,7 @@ bool Interface::saveState(unsigned slot) {
}
bool Interface::loadState(unsigned slot) {
string filename = base.filename({ "state-", slot, ".bst" }, { "-", slot, ".bst" });
string filename = game.filename({ "state-", slot, ".bst" }, { "-", slot, ".bst" });
uint8_t *data;
unsigned size;
if(file::read(filename, data, size) == false) {
@ -193,8 +204,8 @@ Interface::Interface() : core(nullptr) {
//internal
bool Interface::applyPatch(const string &filename, uint8_t *&data, unsigned &size) {
string patchname = { nall::basename(filename), ".bps" };
bool Interface::applyPatch(CartridgePath &filepath, uint8_t *&data, unsigned &size) {
string patchname = filepath.filename("patch.bps", ".bps");
if(file::exists(patchname) == false) return false;
bpspatch bps;

View File

@ -13,6 +13,7 @@ struct CartridgePath {
bool folder;
string name;
string filename(const string &folderName, const string &fileName) const;
string title() const;
};
#include "nes/nes.hpp"
@ -61,14 +62,13 @@ struct Interface : property<Interface> {
Interface();
bool applyPatch(const string &filename, uint8_t *&data, unsigned &size);
bool applyPatch(CartridgePath &filepath, uint8_t *&data, unsigned &size);
void videoRefresh(const uint32_t *input, unsigned inputPitch, unsigned width, unsigned height);
CartridgePath base;
vector<CartridgePath> slot;
//deprecated
string baseName; // = "/path/to/cartridge" (no extension)
CartridgePath base; //base cartridge connected to emulated system
CartridgePath slot[2]; //slot cartridges connected to base cartridge
CartridgePath game; //where to store resources (cheats.xml, states.bsa, ...)
string cartridgeTitle; //combined name of game ([base] + [slot ...])
InterfaceCore *core;
InterfaceNES nes;

View File

@ -48,7 +48,9 @@ bool InterfaceNES::loadCartridge(const string &filename) {
}
interface->unloadCartridge();
//interface->applyPatch(interface->base.filename("patch.bps", ".bps"), data, size);
interface->game = interface->base;
interface->cartridgeTitle = interface->base.title();
interface->applyPatch(interface->base, data, size);
string markup;
markup.readfile(interface->base.filename("manifest.xml", ".xml"));

View File

@ -31,6 +31,7 @@ bool InterfaceSNES::cartridgeLoaded() {
}
bool InterfaceSNES::loadCartridge(const string &filename, CartridgePath &cartridge, uint8_t *&data, unsigned &size) {
data = nullptr, size = 0u;
auto backup = cartridge;
string suffix;
if(filename.endswith("/")) {
@ -43,7 +44,7 @@ bool InterfaceSNES::loadCartridge(const string &filename, CartridgePath &cartrid
cartridge = backup;
return false;
}
//interface->applyPatch(filename, data, size);
interface->applyPatch(cartridge, data, size);
return true;
}
@ -51,7 +52,10 @@ bool InterfaceSNES::loadCartridge(string basename) {
uint8_t *data;
unsigned size;
if(loadCartridge(basename, interface->base, data, size) == false) return false;
interface->unloadCartridge();
interface->game = interface->base;
interface->cartridgeTitle = interface->base.title();
string markup;
markup.readfile(interface->base.filename("manifest.xml", ".xml"));
@ -73,8 +77,12 @@ bool InterfaceSNES::loadSatellaviewSlottedCartridge(string basename, string slot
uint8_t *data[2];
unsigned size[2];
if(loadCartridge(basename, interface->base, data[0], size[0]) == false) return false;
loadCartridge(slotname, interface->slot(0), data[1], size[1]);
loadCartridge(slotname, interface->slot[0], data[1], size[1]);
interface->unloadCartridge();
interface->game = !data[1] ? interface->base : interface->slot[0]; //TODO: subfolder for folders; concatenation for files
interface->cartridgeTitle = interface->base.title();
if(data[1]) interface->cartridgeTitle.append(" + ", interface->slot[0].title());
string markup;
markup.readfile(interface->base.filename("manifest.xml", ".xml"));
@ -98,8 +106,12 @@ bool InterfaceSNES::loadSatellaviewCartridge(string basename, string slotname) {
uint8_t *data[2];
unsigned size[2];
if(loadCartridge(basename, interface->base, data[0], size[0]) == false) return false;
loadCartridge(slotname, interface->slot(0), data[1], size[1]);
loadCartridge(slotname, interface->slot[0], data[1], size[1]);
interface->unloadCartridge();
interface->game = !data[1] ? interface->base : interface->slot[0];
interface->cartridgeTitle = interface->base.title();
if(data[1]) interface->cartridgeTitle = interface->slot[0].title();
string markup;
markup.readfile(interface->base.filename("manifest.xml", ".xml"));
@ -123,9 +135,17 @@ bool InterfaceSNES::loadSufamiTurboCartridge(string basename, string slotAname,
uint8_t *data[3];
unsigned size[3];
if(loadCartridge(basename, interface->base, data[0], size[0]) == false) return false;
loadCartridge(slotAname, interface->slot(0), data[1], size[1]);
loadCartridge(slotBname, interface->slot(1), data[2], size[2]);
loadCartridge(slotAname, interface->slot[0], data[1], size[1]);
loadCartridge(slotBname, interface->slot[1], data[2], size[2]);
interface->unloadCartridge();
interface->game = !data[1] ? interface->base : interface->slot[0]; //TODO: subfolder for folders; concatenation for files
interface->cartridgeTitle = interface->base.title();
if( data[1] && !data[2]) interface->cartridgeTitle = interface->slot[0].title();
if(!data[1] && data[2]) interface->cartridgeTitle = interface->slot[1].title();
if( data[1] && data[2]) interface->cartridgeTitle = {
interface->slot[0].title(), " + ", interface->slot[1].title()
};
string markup;
markup.readfile(interface->base.filename("manifest.xml", ".xml"));
@ -151,8 +171,12 @@ bool InterfaceSNES::loadSuperGameBoyCartridge(string basename, string slotname)
uint8_t *data[2];
unsigned size[2];
if(loadCartridge(basename, interface->base, data[0], size[0]) == false) return false;
loadCartridge(slotname, interface->slot(0), data[1], size[1]);
loadCartridge(slotname, interface->slot[0], data[1], size[1]);
interface->unloadCartridge();
interface->game = !data[1] ? interface->base : interface->slot[0];
interface->cartridgeTitle = interface->base.title();
if(data[1]) interface->cartridgeTitle = interface->slot[0].title();
string markup;
markup.readfile(interface->base.filename("manifest.xml", ".xml"));
@ -179,8 +203,6 @@ bool InterfaceSNES::loadSuperGameBoyCartridge(string basename, string slotname)
void InterfaceSNES::unloadCartridge() {
saveMemory();
SNES::cartridge.unload();
interface->base.name = "";
interface->slot.reset();
}
void InterfaceSNES::power() {
@ -225,6 +247,17 @@ void InterfaceSNES::loadMemory() {
delete[] data;
}
}
if(SNES::cartridge.mode() == SNES::Cartridge::Mode::SuperGameBoy) {
if(GameBoy::cartridge.ramsize) {
uint8_t *data;
unsigned size;
if(file::read(interface->slot[0].filename("program.ram", ".sav"), data, size)) {
memcpy(GameBoy::cartridge.ramdata, data, min(GameBoy::cartridge.ramsize, size));
delete[] data;
}
}
}
}
void InterfaceSNES::saveMemory() {
@ -236,6 +269,14 @@ void InterfaceSNES::saveMemory() {
file::write(filename, memory.data, memory.size);
}
if(SNES::cartridge.mode() == SNES::Cartridge::Mode::SuperGameBoy) {
if(GameBoy::cartridge.ramsize) {
file::write(interface->slot[0].filename("program.ram", ".sav"),
GameBoy::cartridge.ramdata, GameBoy::cartridge.ramsize
);
}
}
}
serializer InterfaceSNES::serialize() {

View File

@ -17,13 +17,13 @@ void Utility::setMode(Interface::Mode mode) {
}
else if(mode == Interface::Mode::NES) {
mainWindow->setTitle(notdir(interface->baseName));
mainWindow->setTitle(interface->cartridgeTitle);
mainWindow->nesMenu.setVisible(true);
dspaudio.setChannels(1);
}
else if(mode == Interface::Mode::SNES) {
mainWindow->setTitle(notdir(interface->baseName));
mainWindow->setTitle(interface->cartridgeTitle);
mainWindow->snesMenu.setVisible(true);
dspaudio.setChannels(2);
}
@ -32,7 +32,7 @@ void Utility::setMode(Interface::Mode mode) {
mainWindow->gameBoyMenu.setText(
GameBoy::system.cgb() == false ? "Game Boy" : "Game Boy Color"
);
mainWindow->setTitle(notdir(interface->baseName));
mainWindow->setTitle(interface->cartridgeTitle);
mainWindow->gameBoyMenu.setVisible(true);
dspaudio.setChannels(2);
}