Update to v087r29 release.

byuu says:

Changelog:
- revised NES XML tag nesting
- program.rom is going to refer to PRG+CHR combined. Split is going to
  have to use different file names
- slot loader is gone (good riddance!)
- "Cartridge -> Load Game Boy Advance Cartridge ..." has become "Load ->
  Game Boy Advance ..."
- Load Satellaview Slotted Cartridge is gone. If you load an SNES
  cartridge and it sees <bsx><slot>, it asks if you want to load a BS-X
  data pack
- If you load a Sufami Turbo cartridge with <cartridge linkable="true">,
  it asks if you want to link in another Sufami Turbo cartridge
- if you try and load the same exact Sufami Turbo cartridge in both
  slots, it yells at you for being an idiot :P
This commit is contained in:
Tim Allen 2012-04-20 22:48:09 +10:00
parent a454e9d927
commit 4c29e6fbab
39 changed files with 192 additions and 400 deletions

View File

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

View File

@ -26,8 +26,9 @@ namespace nall {
return *this; return *this;
} }
any() : container(0) {} any() : container(nullptr) {}
template<typename T> any(const T& value_) : container(0) { operator=(value_); } ~any() { if(container) delete container; }
template<typename T> any(const T& value_) : container(nullptr) { operator=(value_); }
private: private:
struct placeholder { struct placeholder {
@ -59,12 +60,12 @@ namespace nall {
} }
template<typename T> T* any_cast(any *value) { template<typename T> T* any_cast(any *value) {
if(!value || value->type() != typeid(T)) return 0; if(!value || value->type() != typeid(T)) return nullptr;
return &static_cast<any::holder<T>*>(value->container)->value; return &static_cast<any::holder<T>*>(value->container)->value;
} }
template<typename T> const T* any_cast(const any *value) { template<typename T> const T* any_cast(const any *value) {
if(!value || value->type() != typeid(T)) return 0; if(!value || value->type() != typeid(T)) return nullptr;
return &static_cast<any::holder<T>*>(value->container)->value; return &static_cast<any::holder<T>*>(value->container)->value;
} }
} }

View File

@ -37,6 +37,14 @@ struct zip {
file.reset(); file.reset();
const uint8_t *footer = data + size - 22; const uint8_t *footer = data + size - 22;
while(true) {
if(footer <= data + 22) return false;
if(read(footer, 4) == 0x06054b50) {
unsigned commentlength = read(footer + 20, 2);
if(footer + 22 + commentlength == data + size) break;
}
footer--;
}
const uint8_t *directory = data + read(footer + 16, 4); const uint8_t *directory = data + read(footer + 16, 4);
while(true) { while(true) {

View File

@ -111,7 +111,7 @@ void serialize(serializer &s) {
s.integer(irq_latch); s.integer(irq_latch);
} }
BandaiFCG(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) { BandaiFCG(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size) {
} }
}; };

View File

@ -86,14 +86,16 @@ void Board::serialize(serializer &s) {
if(chrram.size) s.array(chrram.data, chrram.size); if(chrram.size) s.array(chrram.data, chrram.size);
} }
Board::Board(XML::Node &board, const uint8_t *data, unsigned size) { Board::Board(XML::Document &document, const uint8_t *data, unsigned size) {
information.type = board["type"].data; auto &cartridge = document["cartridge"];
information.battery = board["prg"]["battery"].data == "true";
prgrom.size = numeral(board["prg"]["rom"].data); information.type = cartridge["board"]["type"].data;
prgram.size = numeral(board["prg"]["ram"].data); information.battery = cartridge["prg"]["ram"]["nonvolatile"].data == "true";
chrrom.size = numeral(board["chr"]["rom"].data);
chrram.size = numeral(board["chr"]["ram"].data); prgrom.size = numeral(cartridge["prg"]["rom"]["size"].data);
prgram.size = numeral(cartridge["prg"]["ram"]["size"].data);
chrrom.size = numeral(cartridge["chr"]["rom"]["size"].data);
chrram.size = numeral(cartridge["chr"]["ram"]["size"].data);
if(prgrom.size) prgrom.data = new uint8[prgrom.size](); if(prgrom.size) prgrom.data = new uint8[prgrom.size]();
if(prgram.size) prgram.data = new uint8[prgram.size](); if(prgram.size) prgram.data = new uint8[prgram.size]();
@ -112,55 +114,54 @@ Board::~Board() {
Board* Board::load(const string &markup, const uint8_t *data, unsigned size) { Board* Board::load(const string &markup, const uint8_t *data, unsigned size) {
XML::Document document(markup); XML::Document document(markup);
auto &board = document["cartridge"]["board"]; string type = document["cartridge"]["board"]["type"].data;
string type = board["type"].data;
if(type == "BANDAI-FCG") return new BandaiFCG(board, data, size); if(type == "BANDAI-FCG") return new BandaiFCG(document, data, size);
if(type == "KONAMI-VRC-1") return new KonamiVRC1(board, data, size); if(type == "KONAMI-VRC-1") return new KonamiVRC1(document, data, size);
if(type == "KONAMI-VRC-2") return new KonamiVRC2(board, data, size); if(type == "KONAMI-VRC-2") return new KonamiVRC2(document, data, size);
if(type == "KONAMI-VRC-3") return new KonamiVRC3(board, data, size); if(type == "KONAMI-VRC-3") return new KonamiVRC3(document, data, size);
if(type == "KONAMI-VRC-4") return new KonamiVRC4(board, data, size); if(type == "KONAMI-VRC-4") return new KonamiVRC4(document, data, size);
if(type == "KONAMI-VRC-6") return new KonamiVRC6(board, data, size); if(type == "KONAMI-VRC-6") return new KonamiVRC6(document, data, size);
if(type == "KONAMI-VRC-7") return new KonamiVRC7(board, data, size); if(type == "KONAMI-VRC-7") return new KonamiVRC7(document, data, size);
if(type == "NES-AMROM" ) return new NES_AxROM(board, data, size); if(type == "NES-AMROM" ) return new NES_AxROM(document, data, size);
if(type == "NES-ANROM" ) return new NES_AxROM(board, data, size); if(type == "NES-ANROM" ) return new NES_AxROM(document, data, size);
if(type == "NES-AN1ROM" ) return new NES_AxROM(board, data, size); if(type == "NES-AN1ROM" ) return new NES_AxROM(document, data, size);
if(type == "NES-AOROM" ) return new NES_AxROM(board, data, size); if(type == "NES-AOROM" ) return new NES_AxROM(document, data, size);
if(type == "NES-BNROM" ) return new NES_BNROM(board, data, size); if(type == "NES-BNROM" ) return new NES_BNROM(document, data, size);
if(type == "NES-CNROM" ) return new NES_CNROM(board, data, size); if(type == "NES-CNROM" ) return new NES_CNROM(document, data, size);
if(type == "NES-EKROM" ) return new NES_ExROM(board, data, size); if(type == "NES-EKROM" ) return new NES_ExROM(document, data, size);
if(type == "NES-ELROM" ) return new NES_ExROM(board, data, size); if(type == "NES-ELROM" ) return new NES_ExROM(document, data, size);
if(type == "NES-ETROM" ) return new NES_ExROM(board, data, size); if(type == "NES-ETROM" ) return new NES_ExROM(document, data, size);
if(type == "NES-EWROM" ) return new NES_ExROM(board, data, size); if(type == "NES-EWROM" ) return new NES_ExROM(document, data, size);
if(type == "NES-FJROM" ) return new NES_FxROM(board, data, size); if(type == "NES-FJROM" ) return new NES_FxROM(document, data, size);
if(type == "NES-FKROM" ) return new NES_FxROM(board, data, size); if(type == "NES-FKROM" ) return new NES_FxROM(document, data, size);
if(type == "NES-GNROM" ) return new NES_GxROM(board, data, size); if(type == "NES-GNROM" ) return new NES_GxROM(document, data, size);
if(type == "NES-MHROM" ) return new NES_GxROM(board, data, size); if(type == "NES-MHROM" ) return new NES_GxROM(document, data, size);
if(type == "NES-HKROM" ) return new NES_HKROM(board, data, size); if(type == "NES-HKROM" ) return new NES_HKROM(document, data, size);
if(type == "NES-NROM-128") return new NES_NROM(board, data, size); if(type == "NES-NROM-128") return new NES_NROM(document, data, size);
if(type == "NES-NROM-256") return new NES_NROM(board, data, size); if(type == "NES-NROM-256") return new NES_NROM(document, data, size);
if(type == "NES-PEEOROM" ) return new NES_PxROM(board, data, size); if(type == "NES-PEEOROM" ) return new NES_PxROM(document, data, size);
if(type == "NES-PNROM" ) return new NES_PxROM(board, data, size); if(type == "NES-PNROM" ) return new NES_PxROM(document, data, size);
if(type == "NES-SNROM" ) return new NES_SxROM(board, data, size); if(type == "NES-SNROM" ) return new NES_SxROM(document, data, size);
if(type == "NES-SXROM" ) return new NES_SxROM(board, data, size); if(type == "NES-SXROM" ) return new NES_SxROM(document, data, size);
if(type == "NES-TLROM" ) return new NES_TxROM(board, data, size); if(type == "NES-TLROM" ) return new NES_TxROM(document, data, size);
if(type == "NES-UNROM" ) return new NES_UxROM(board, data, size); if(type == "NES-UNROM" ) return new NES_UxROM(document, data, size);
if(type == "NES-UOROM" ) return new NES_UxROM(board, data, size); if(type == "NES-UOROM" ) return new NES_UxROM(document, data, size);
if(type == "SUNSOFT-5B" ) return new Sunsoft5B(board, data, size); if(type == "SUNSOFT-5B" ) return new Sunsoft5B(document, data, size);
return nullptr; return nullptr;
} }

View File

@ -31,7 +31,7 @@ struct Board {
virtual void reset(); virtual void reset();
virtual void serialize(serializer&); virtual void serialize(serializer&);
Board(XML::Node &board, const uint8_t *data, unsigned size); Board(XML::Document &document, const uint8_t *data, unsigned size);
virtual ~Board(); virtual ~Board();
static Board* load(const string &markup, const uint8_t *data, unsigned size); static Board* load(const string &markup, const uint8_t *data, unsigned size);

View File

@ -34,7 +34,7 @@ void serialize(serializer &s) {
vrc1.serialize(s); vrc1.serialize(s);
} }
KonamiVRC1(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size), vrc1(*this) { KonamiVRC1(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size), vrc1(*this) {
} }
}; };

View File

@ -49,9 +49,9 @@ void serialize(serializer &s) {
vrc2.serialize(s); vrc2.serialize(s);
} }
KonamiVRC2(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size), vrc2(*this) { KonamiVRC2(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size), vrc2(*this) {
settings.pinout.a0 = 1 << decimal(board["chip"]["pinout"]["a0"].data); settings.pinout.a0 = 1 << decimal(document["cartridge"]["chip"]["pinout"]["a0"].data);
settings.pinout.a1 = 1 << decimal(board["chip"]["pinout"]["a1"].data); settings.pinout.a1 = 1 << decimal(document["cartridge"]["chip"]["pinout"]["a1"].data);
} }
}; };

View File

@ -50,8 +50,8 @@ void serialize(serializer &s) {
vrc3.serialize(s); vrc3.serialize(s);
} }
KonamiVRC3(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size), vrc3(*this) { KonamiVRC3(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size), vrc3(*this) {
settings.mirror = board["mirror"]["mode"].data == "vertical" ? 1 : 0; settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
} }
}; };

View File

@ -53,9 +53,9 @@ void serialize(serializer &s) {
vrc4.serialize(s); vrc4.serialize(s);
} }
KonamiVRC4(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size), vrc4(*this) { KonamiVRC4(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size), vrc4(*this) {
settings.pinout.a0 = 1 << decimal(board["chip"]["pinout"]["a0"].data); settings.pinout.a0 = 1 << decimal(document["cartridge"]["chip"]["pinout"]["a0"].data);
settings.pinout.a1 = 1 << decimal(board["chip"]["pinout"]["a1"].data); settings.pinout.a1 = 1 << decimal(document["cartridge"]["chip"]["pinout"]["a1"].data);
} }
}; };

View File

@ -36,7 +36,7 @@ void main() { vrc6.main(); }
void power() { vrc6.power(); } void power() { vrc6.power(); }
void reset() { vrc6.reset(); } void reset() { vrc6.reset(); }
KonamiVRC6(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size), vrc6(*this) { KonamiVRC6(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size), vrc6(*this) {
} }
}; };

View File

@ -41,7 +41,7 @@ void serialize(serializer &s) {
vrc7.serialize(s); vrc7.serialize(s);
} }
KonamiVRC7(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size), vrc7(*this) { KonamiVRC7(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size), vrc7(*this) {
} }
}; };

View File

@ -45,7 +45,7 @@ void serialize(serializer &s) {
s.integer(mirror_select); s.integer(mirror_select);
} }
NES_AxROM(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) { NES_AxROM(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size) {
} }
}; };

View File

@ -45,8 +45,8 @@ void serialize(serializer &s) {
s.integer(prg_bank); s.integer(prg_bank);
} }
NES_BNROM(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) { NES_BNROM(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size) {
settings.mirror = board["mirror"]["mode"].data == "vertical" ? 1 : 0; settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
} }
}; };

View File

@ -47,8 +47,8 @@ void serialize(serializer &s) {
s.integer(chr_bank); s.integer(chr_bank);
} }
NES_CNROM(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) { NES_CNROM(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size) {
settings.mirror = board["mirror"]["mode"].data == "vertical" ? 1 : 0; settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
} }
}; };

View File

@ -46,7 +46,7 @@ void serialize(serializer &s) {
mmc5.serialize(s); mmc5.serialize(s);
} }
NES_ExROM(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size), mmc5(*this) { NES_ExROM(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size), mmc5(*this) {
revision = Revision::ELROM; revision = Revision::ELROM;
} }

View File

@ -84,7 +84,7 @@ void serialize(serializer &s) {
s.array(latch); s.array(latch);
} }
NES_FxROM(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) { NES_FxROM(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size) {
revision = Revision::FKROM; revision = Revision::FKROM;
} }

View File

@ -54,8 +54,8 @@ void serialize(serializer &s) {
s.integer(chr_bank); s.integer(chr_bank);
} }
NES_GxROM(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) { NES_GxROM(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size) {
settings.mirror = board["mirror"]["mode"].data == "vertical" ? 1 : 0; settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
} }
}; };

View File

@ -42,7 +42,7 @@ void serialize(serializer &s) {
mmc6.serialize(s); mmc6.serialize(s);
} }
NES_HKROM(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size), mmc6(*this) { NES_HKROM(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size), mmc6(*this) {
} }
}; };

View File

@ -36,8 +36,8 @@ void serialize(serializer &s) {
Board::serialize(s); Board::serialize(s);
} }
NES_NROM(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) { NES_NROM(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size) {
settings.mirror = board["mirror"]["mode"].data == "vertical" ? 1 : 0; settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
} }
}; };

View File

@ -90,7 +90,7 @@ void serialize(serializer &s) {
s.array(latch); s.array(latch);
} }
NES_PxROM(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) { NES_PxROM(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size) {
revision = Revision::PNROM; revision = Revision::PNROM;
} }

View File

@ -94,7 +94,7 @@ void serialize(serializer &s) {
mmc1.serialize(s); mmc1.serialize(s);
} }
NES_SxROM(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size), mmc1(*this) { NES_SxROM(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size), mmc1(*this) {
revision = Revision::SXROM; revision = Revision::SXROM;
} }

View File

@ -60,7 +60,7 @@ void serialize(serializer &s) {
mmc3.serialize(s); mmc3.serialize(s);
} }
NES_TxROM(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size), mmc3(*this) { NES_TxROM(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size), mmc3(*this) {
revision = Revision::TLROM; revision = Revision::TLROM;
} }

View File

@ -48,8 +48,8 @@ void serialize(serializer &s) {
s.integer(prg_bank); s.integer(prg_bank);
} }
NES_UxROM(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) { NES_UxROM(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size) {
settings.mirror = board["mirror"]["mode"].data == "vertical" ? 1 : 0; settings.mirror = document["cartridge"]["mirror"]["mode"].data == "vertical" ? 1 : 0;
} }
}; };

View File

@ -220,7 +220,7 @@ void serialize(serializer &s) {
pulse[2].serialize(s); pulse[2].serialize(s);
} }
Sunsoft5B(XML::Node &board, const uint8_t *data, unsigned size) : Board(board, data, size) { Sunsoft5B(XML::Document &document, const uint8_t *data, unsigned size) : Board(document, data, size) {
} }
}; };

View File

@ -20,8 +20,6 @@ void Cartridge::load(const string &markup, const uint8_t *data, unsigned size) {
sha256 = nall::sha256(data, size); sha256 = nall::sha256(data, size);
board = Board::load(markup, data, size); board = Board::load(markup, data, size);
} else { } else {
//unsigned crc32 = crc32_calculate(data + 16, size - 16);
//print(hex<8>(crc32), "\n");
sha256 = nall::sha256(data + 16, size - 16); sha256 = nall::sha256(data + 16, size - 16);
board = Board::load(!markup.empty() ? markup : iNES(data, size), data + 16, size - 16); board = Board::load(!markup.empty() ? markup : iNES(data, size), data + 16, size - 16);
} }

View File

@ -21,61 +21,61 @@ static string iNES(const uint8_t *data, unsigned size) {
switch(mapper) { switch(mapper) {
default: default:
output.append(" <board type='NES-NROM-256'>\n"); output.append(" <board type='NES-NROM-256'/>\n");
output.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n"); output.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n");
break; break;
case 1: case 1:
output.append(" <board type='NES-SXROM'>\n"); output.append(" <board type='NES-SXROM'/>\n");
output.append(" <chip type='MMC1B2'/>\n"); output.append(" <chip type='MMC1B2'/>\n");
prgram = 8192; prgram = 8192;
break; break;
case 2: case 2:
output.append(" <board type='NES-UOROM'>\n"); output.append(" <board type='NES-UOROM'/>\n");
output.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n"); output.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n");
break; break;
case 3: case 3:
output.append(" <board type='NES-CNROM'>\n"); output.append(" <board type='NES-CNROM'/>\n");
output.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n"); output.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n");
break; break;
case 4: case 4:
//MMC3 //MMC3
output.append(" <board type='NES-TLROM'>\n"); output.append(" <board type='NES-TLROM'/>\n");
output.append(" <chip type='MMC3B'/>\n"); output.append(" <chip type='MMC3B'/>\n");
prgram = 8192; prgram = 8192;
//MMC6 //MMC6
//output.append(" <board type='NES-HKROM'>\n"); //output.append(" <board type='NES-HKROM'/>\n");
//output.append(" <chip type='MMC6'/>\n"); //output.append(" <chip type='MMC6'/>\n");
//prgram = 1024; //prgram = 1024;
break; break;
case 5: case 5:
output.append(" <board type='NES-ELROM'>\n"); output.append(" <board type='NES-ELROM'/>\n");
output.append(" <chip type='MMC5'/>\n"); output.append(" <chip type='MMC5'/>\n");
prgram = 65536; prgram = 65536;
break; break;
case 7: case 7:
output.append(" <board type='NES-AOROM'>\n"); output.append(" <board type='NES-AOROM'/>\n");
break; break;
case 9: case 9:
output.append(" <board type='NES-PNROM'>\n"); output.append(" <board type='NES-PNROM'/>\n");
output.append(" <chip type='MMC2'/>\n"); output.append(" <chip type='MMC2'/>\n");
prgram = 8192; prgram = 8192;
break; break;
case 10: case 10:
output.append(" <board type='NES-FKROM'>\n"); output.append(" <board type='NES-FKROM'/>\n");
output.append(" <chip type='MMC4'/>\n"); output.append(" <chip type='MMC4'/>\n");
prgram = 8192; prgram = 8192;
break; break;
case 16: case 16:
output.append(" <board type='BANDAI-FCG'>\n"); output.append(" <board type='BANDAI-FCG'/>\n");
output.append(" <chip type='LZ93D50'/>\n"); output.append(" <chip type='LZ93D50'/>\n");
break; break;
@ -83,7 +83,7 @@ static string iNES(const uint8_t *data, unsigned size) {
case 23: case 23:
case 25: case 25:
//VRC4 //VRC4
output.append(" <board type='KONAMI-VRC-4'>\n"); output.append(" <board type='KONAMI-VRC-4'/>\n");
output.append(" <chip type='VRC4'>\n"); output.append(" <chip type='VRC4'>\n");
output.append(" <pinout a0='1' a1='0'/>\n"); output.append(" <pinout a0='1' a1='0'/>\n");
output.append(" </chip>\n"); output.append(" </chip>\n");
@ -92,62 +92,67 @@ static string iNES(const uint8_t *data, unsigned size) {
case 22: case 22:
//VRC2 //VRC2
output.append(" <board type='KONAMI-VRC-2'>\n"); output.append(" <board type='KONAMI-VRC-2'/>\n");
output.append(" <chip type='VRC2'>\n"); output.append(" <chip type='VRC2'>\n");
output.append(" <pinout a0='0' a1='1'/>\n"); output.append(" <pinout a0='0' a1='1'/>\n");
output.append(" </chip>\n"); output.append(" </chip>\n");
break; break;
case 24: case 24:
output.append(" <board type='KONAMI-VRC-6'>\n"); output.append(" <board type='KONAMI-VRC-6'/>\n");
output.append(" <chip type='VRC6'/>\n"); output.append(" <chip type='VRC6'/>\n");
break; break;
case 26: case 26:
output.append(" <board type='KONAMI-VRC-6'>\n"); output.append(" <board type='KONAMI-VRC-6'/>\n");
output.append(" <chip type='VRC6'/>\n"); output.append(" <chip type='VRC6'/>\n");
prgram = 8192; prgram = 8192;
break; break;
case 34: case 34:
output.append(" <board type='NES-BNROM'>\n"); output.append(" <board type='NES-BNROM'/>\n");
output.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n"); output.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n");
break; break;
case 66: case 66:
output.append(" <board type='NES-GNROM'>\n"); output.append(" <board type='NES-GNROM'/>\n");
output.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n"); output.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n");
break; break;
case 69: case 69:
output.append(" <board type='SUNSOFT-5B'>\n"); output.append(" <board type='SUNSOFT-5B'/>\n");
output.append(" <chip type='5B'/>\n"); output.append(" <chip type='5B'/>\n");
prgram = 8192; prgram = 8192;
break; break;
case 73: case 73:
output.append(" <board type='KONAMI-VRC-3'>\n"); output.append(" <board type='KONAMI-VRC-3'/>\n");
output.append(" <chip type='VRC3'/>\n"); output.append(" <chip type='VRC3'/>\n");
output.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n"); output.append(" <mirror mode='", mirror == 0 ? "horizontal" : "vertical", "'/>\n");
prgram = 8192; prgram = 8192;
break; break;
case 75: case 75:
output.append(" <board type='KONAMI-VRC-1'>\n"); output.append(" <board type='KONAMI-VRC-1'/>\n");
output.append(" <chip type='VRC1'/>\n"); output.append(" <chip type='VRC1'/>\n");
break; break;
case 85: case 85:
output.append(" <board type='KONAMI-VRC-7'>\n"); output.append(" <board type='KONAMI-VRC-7/'>\n");
output.append(" <chip type='VRC7'/>\n"); output.append(" <chip type='VRC7'/>\n");
prgram = 8192; prgram = 8192;
break; break;
} }
output.append( output.append(
" <prg rom='0x", hex(prgrom), "' ram='0x", hex(prgram), "'/>\n" " <prg>\n"
" <chr rom='0x", hex(chrrom), "' ram='0x", hex(chrram), "'/>\n" " <rom size='0x", hex(prgrom), "'/>\n"
" </board>\n" " <ram size='0x", hex(prgram), "' nonvolatile='true'/>\n"
" </prg>\n"
" <chr>\n"
" <rom size='0x", hex(chrrom), "'/>\n"
" <ram size='0x", hex(chrram), "'/>\n"
" </chr>\n"
"</cartridge>\n" "</cartridge>\n"
); );

View File

@ -11,13 +11,13 @@ void SufamiTurbo::load() {
slotB.ram.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024); slotB.ram.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024);
if(slotA.rom.data()) { if(slotA.rom.data()) {
cartridge.nvram.append({ "program.ram", slotA.ram.data(), slotA.ram.size(), Cartridge::Slot::SufamiTurboA }); cartridge.nvram.append({ "save.ram", slotA.ram.data(), slotA.ram.size(), Cartridge::Slot::SufamiTurboA });
} else { } else {
slotA.rom.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024); slotA.rom.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024);
} }
if(slotB.rom.data()) { if(slotB.rom.data()) {
cartridge.nvram.append({ "program.ram", slotB.ram.data(), slotB.ram.size(), Cartridge::Slot::SufamiTurboB }); cartridge.nvram.append({ "save.ram", slotB.ram.data(), slotB.ram.size(), Cartridge::Slot::SufamiTurboB });
} else { } else {
slotB.rom.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024); slotB.rom.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024);
} }

View File

@ -37,10 +37,6 @@ Config::Config() {
append(input.driver = "", "Input::Driver"); append(input.driver = "", "Input::Driver");
append(input.focusPolicy = 1, "Input::FocusPolicy"); append(input.focusPolicy = 1, "Input::FocusPolicy");
append(path.bios.satellaview = "", "Path::BIOS::Satellaview");
append(path.bios.sufamiTurbo = "", "Path::BIOS::SufamiTurbo");
append(path.bios.superGameBoy = "", "Path::BIOS::SuperGameBoy");
append(nes.controllerPort1Device = 1, "NES::Controller::Port1"); append(nes.controllerPort1Device = 1, "NES::Controller::Port1");
append(nes.controllerPort2Device = 0, "NES::Controller::Port2"); append(nes.controllerPort2Device = 0, "NES::Controller::Port2");

View File

@ -42,14 +42,6 @@ struct Config : public configuration {
unsigned focusPolicy; unsigned focusPolicy;
} input; } input;
struct Path {
struct BIOS {
string satellaview;
string sufamiTurbo;
string superGameBoy;
} bios;
} path;
struct NES { struct NES {
unsigned controllerPort1Device; unsigned controllerPort1Device;
unsigned controllerPort2Device; unsigned controllerPort2Device;

View File

@ -151,6 +151,6 @@ bool FileBrowser::loadFolder(const string &requestedPath) {
} }
void FileBrowser::loadFile(const string &filename) { void FileBrowser::loadFile(const string &filename) {
if(callback) callback(filename);
setVisible(false); setVisible(false);
if(callback) callback(filename);
} }

View File

@ -1,5 +1,4 @@
#include "../base.hpp" #include "../base.hpp"
#include "main-window.cpp" #include "main-window.cpp"
#include "file-browser.cpp" #include "file-browser.cpp"
#include "slot-loader.cpp"
#include "dip-switches.cpp" #include "dip-switches.cpp"

View File

@ -1,4 +1,3 @@
#include "main-window.hpp" #include "main-window.hpp"
#include "file-browser.hpp" #include "file-browser.hpp"
#include "slot-loader.hpp"
#include "dip-switches.hpp" #include "dip-switches.hpp"

View File

@ -6,16 +6,15 @@ MainWindow::MainWindow() {
setBackgroundColor({ 0, 0, 0 }); setBackgroundColor({ 0, 0, 0 });
windowManager->append(this, "MainWindow"); windowManager->append(this, "MainWindow");
cartridgeMenu.setText("&Cartridge"); cartridgeMenu.setText("&Load");
cartridgeLoadNES.setText("Load &Famicom Cartridge ..."); cartridgeLoadNES.setText("&Famicom ...");
cartridgeLoadSNES.setText("Load &Super Famicom Cartridge ..."); cartridgeLoadSNES.setText("&Super Famicom ...");
cartridgeLoadGameBoy.setText("Load &Game Boy Cartridge ..."); cartridgeLoadGameBoy.setText("&Game Boy ...");
cartridgeLoadGameBoyColor.setText("Load Game Boy &Color Cartridge ..."); cartridgeLoadGameBoyColor.setText("Game Boy &Color ...");
cartridgeLoadGameBoyAdvance.setText("Load Game Boy &Advance Cartridge ..."); cartridgeLoadGameBoyAdvance.setText("Game Boy &Advance ...");
cartridgeLoadSatellaviewSlotted.setText("Load Satellaview-Slotted Cartridge ..."); cartridgeLoadSuperGameBoy.setText("Super Game Boy ...");
cartridgeLoadSatellaview.setText("Load BS-X Satellaview Cartridge ..."); cartridgeLoadSatellaview.setText("BS-X Satellaview ...");
cartridgeLoadSufamiTurbo.setText("Load Sufami Turbo Cartridge ..."); cartridgeLoadSufamiTurbo.setText("Sufami Turbo ...");
cartridgeLoadSuperGameBoy.setText("Load Super Game Boy Cartridge ...");
nesMenu.setText("&NES"); nesMenu.setText("&NES");
nesPower.setText("&Power Cycle"); nesPower.setText("&Power Cycle");
@ -110,10 +109,9 @@ MainWindow::MainWindow() {
cartridgeMenu.append(cartridgeLoadGameBoyColor); cartridgeMenu.append(cartridgeLoadGameBoyColor);
cartridgeMenu.append(cartridgeLoadGameBoyAdvance); cartridgeMenu.append(cartridgeLoadGameBoyAdvance);
cartridgeMenu.append(cartridgeSeparator); cartridgeMenu.append(cartridgeSeparator);
cartridgeMenu.append(cartridgeLoadSatellaviewSlotted); cartridgeMenu.append(cartridgeLoadSuperGameBoy);
cartridgeMenu.append(cartridgeLoadSatellaview); cartridgeMenu.append(cartridgeLoadSatellaview);
cartridgeMenu.append(cartridgeLoadSufamiTurbo); cartridgeMenu.append(cartridgeLoadSufamiTurbo);
cartridgeMenu.append(cartridgeLoadSuperGameBoy);
append(nesMenu); append(nesMenu);
nesMenu.append(nesPower); nesMenu.append(nesPower);
@ -210,7 +208,18 @@ MainWindow::MainWindow() {
cartridgeLoadSNES.onActivate = [&] { cartridgeLoadSNES.onActivate = [&] {
fileBrowser->open("Load Cartridge - Super Famicom", FileBrowser::Mode::SNES, [](string filename) { fileBrowser->open("Load Cartridge - Super Famicom", FileBrowser::Mode::SNES, [](string filename) {
string filedata;
filedata.readfile({dir(filename),"manifest.xml"});
XML::Document document(filedata);
if(document["cartridge"]["bsx"]["slot"].exists()
&& MessageWindow::question(*mainWindow, "Load BS-X Satellaview data pack?") == MessageWindow::Response::Yes) {
mainWindow->filename = filename;
fileBrowser->open("Load Cartridge - BS-X Satellaview", FileBrowser::Mode::Satellaview, [](string filename) {
interface->snes.loadSatellaviewSlottedCartridge(mainWindow->filename, filename);
});
} else {
interface->snes.loadCartridge(filename); interface->snes.loadCartridge(filename);
}
}); });
}; };
@ -232,7 +241,11 @@ MainWindow::MainWindow() {
}); });
}; };
cartridgeLoadSatellaviewSlotted.onActivate = [&] { slotLoader->loadSatellaviewSlotted(); }; cartridgeLoadSuperGameBoy.onActivate = [&] {
fileBrowser->open("Load Cartridge - Super Game Boy", FileBrowser::Mode::GameBoy, [](string filename) {
interface->snes.loadSuperGameBoyCartridge(application->path("Super Game Boy.sfc/"), filename);
});
};
cartridgeLoadSatellaview.onActivate = [&] { cartridgeLoadSatellaview.onActivate = [&] {
fileBrowser->open("Load Cartridge - BS-X Satellaview", FileBrowser::Mode::Satellaview, [](string filename) { fileBrowser->open("Load Cartridge - BS-X Satellaview", FileBrowser::Mode::Satellaview, [](string filename) {
@ -242,13 +255,22 @@ MainWindow::MainWindow() {
cartridgeLoadSufamiTurbo.onActivate = [&] { cartridgeLoadSufamiTurbo.onActivate = [&] {
fileBrowser->open("Load Cartridge - Sufami Turbo", FileBrowser::Mode::SufamiTurbo, [](string filename) { fileBrowser->open("Load Cartridge - Sufami Turbo", FileBrowser::Mode::SufamiTurbo, [](string filename) {
interface->snes.loadSufamiTurboCartridge(application->path("Sufami Turbo.sfc/"), filename, ""); string filedata;
filedata.readfile({dir(filename),"manifest.xml"});
XML::Document document(filedata);
if(document["cartridge"]["linkable"].data == "true"
&& MessageWindow::question(*mainWindow, "Load linkable cartridge?") == MessageWindow::Response::Yes) {
mainWindow->filename = filename;
fileBrowser->open("Load Cartridge - Sufami Turbo", FileBrowser::Mode::SufamiTurbo, [](string filename) {
if(mainWindow->filename == filename) {
MessageWindow::critical(*mainWindow, "It is physically impossible to have the same cartridge in two slots at the same time.");
} else {
interface->snes.loadSufamiTurboCartridge(application->path("Sufami Turbo.sfc/"), mainWindow->filename, filename);
}
}); });
}; } else {
interface->snes.loadSufamiTurboCartridge(application->path("Sufami Turbo.sfc/"), filename, "");
cartridgeLoadSuperGameBoy.onActivate = [&] { }
fileBrowser->open("Load Cartridge - Super Game Boy", FileBrowser::Mode::GameBoy, [](string filename) {
interface->snes.loadSuperGameBoyCartridge(application->path("Super Game Boy.sfc/"), filename);
}); });
}; };

View File

@ -9,10 +9,9 @@ struct MainWindow : Window {
Item cartridgeLoadGameBoyColor; Item cartridgeLoadGameBoyColor;
Item cartridgeLoadGameBoyAdvance; Item cartridgeLoadGameBoyAdvance;
Separator cartridgeSeparator; Separator cartridgeSeparator;
Item cartridgeLoadSatellaviewSlotted; Item cartridgeLoadSuperGameBoy;
Item cartridgeLoadSatellaview; Item cartridgeLoadSatellaview;
Item cartridgeLoadSufamiTurbo; Item cartridgeLoadSufamiTurbo;
Item cartridgeLoadSuperGameBoy;
Menu nesMenu; Menu nesMenu;
Item nesPower; Item nesPower;
@ -90,6 +89,7 @@ struct MainWindow : Window {
private: private:
lstring videoFilterName; lstring videoFilterName;
lstring videoShaderName; lstring videoShaderName;
string filename;
void setupVideoFilters(); void setupVideoFilters();
void setupVideoShaders(); void setupVideoShaders();

View File

@ -1,185 +0,0 @@
SlotLoader *slotLoader = nullptr;
SlotLoaderPath::SlotLoaderPath() {
browse.setText("Browse ...");
append(label, { 40, 0 }, 5);
append(path, { ~0, 0 }, 5);
append(browse, { 80, 0 }, 0);
}
SlotLoader::SlotLoader() {
layout.setMargin(5);
base.label.setText("Base:");
slot[0].label.setText("Slot:");
slot[1].label.setText("Slot:");
loadButton.setText("Load");
append(layout);
layout.append(base, { ~0, 0 }, 5);
layout.append(slot[0], { ~0, 0 }, 5);
layout.append(slot[1], { ~0, 0 }, 5);
layout.append(controlLayout, { ~0, 0 }, 0);
controlLayout.append(spacer, { ~0, 0 }, 0);
controlLayout.append(loadButton, { 80, 0 }, 0);
setGeometry({ 128, 128, 500, layout.minimumGeometry().height });
windowManager->append(this, "SlotLoader");
}
void SlotLoader::synchronize() {
loadButton.setEnabled(base.path.text() != "");
}
void SlotLoader::loadSatellaviewSlotted() {
setTitle("Load Cartridge - Satellaview-Slotted");
base.path.setText("");
slot[0].path.setText("");
slot[0].path.setEnabled(true);
slot[0].browse.setEnabled(true);
slot[1].path.setText("");
slot[1].path.setEnabled(false);
slot[1].browse.setEnabled(false);
base.browse.onActivate = [&] {
fileBrowser->open("Load Cartridge - SNES", FileBrowser::Mode::SNES, [&](const string &filename) {
base.path.setText(filename);
synchronize();
});
};
slot[0].browse.onActivate = [&] {
fileBrowser->open("Load Cartridge - Satellaview", FileBrowser::Mode::Satellaview, [&](const string &filename) {
slot[0].path.setText(filename);
synchronize();
});
};
loadButton.onActivate = [&] {
this->setVisible(false);
interface->snes.loadSatellaviewSlottedCartridge(base.path.text(), slot[0].path.text());
};
synchronize();
setVisible();
}
void SlotLoader::loadSatellaview() {
setTitle("Load Cartridge - Satellaview");
base.path.setText(config->path.bios.satellaview);
slot[0].path.setText("");
slot[0].path.setEnabled(true);
slot[0].browse.setEnabled(true);
slot[1].path.setText("");
slot[1].path.setEnabled(false);
slot[1].browse.setEnabled(false);
base.browse.onActivate = [&] {
fileBrowser->open("Load BIOS - Satellaview", FileBrowser::Mode::SNES, [&](const string &filename) {
config->path.bios.satellaview = filename;
base.path.setText(filename);
synchronize();
});
};
slot[0].browse.onActivate = [&] {
fileBrowser->open("Load Cartridge - Satellaview", FileBrowser::Mode::Satellaview, [&](const string &filename) {
slot[0].path.setText(filename);
synchronize();
});
};
loadButton.onActivate = [&] {
this->setVisible(false);
interface->snes.loadSatellaviewCartridge(base.path.text(), slot[0].path.text());
};
synchronize();
setVisible();
}
void SlotLoader::loadSufamiTurbo() {
setTitle("Load Cartridge - Sufami Turbo");
base.path.setText(config->path.bios.sufamiTurbo);
slot[0].path.setText("");
slot[0].path.setEnabled(true);
slot[0].browse.setEnabled(true);
slot[1].path.setText("");
slot[1].path.setEnabled(true);
slot[1].browse.setEnabled(true);
base.browse.onActivate = [&] {
fileBrowser->open("Load BIOS - Sufami Turbo", FileBrowser::Mode::SNES, [&](const string &filename) {
config->path.bios.sufamiTurbo = filename;
base.path.setText(filename);
synchronize();
});
};
slot[0].browse.onActivate = [&] {
fileBrowser->open("Load Cartridge - Sufami Turbo", FileBrowser::Mode::SufamiTurbo, [&](const string &filename) {
slot[0].path.setText(filename);
synchronize();
});
};
slot[1].browse.onActivate = [&] {
fileBrowser->open("Load Cartridge - Sufami Turbo", FileBrowser::Mode::SufamiTurbo, [&](const string &filename) {
slot[1].path.setText(filename);
synchronize();
});
};
loadButton.onActivate = [&] {
this->setVisible(false);
interface->snes.loadSufamiTurboCartridge(base.path.text(), slot[0].path.text(), slot[1].path.text());
};
synchronize();
setVisible();
}
void SlotLoader::loadSuperGameBoy() {
setTitle("Load Cartridge - Super Game Boy");
base.path.setText(config->path.bios.superGameBoy);
slot[0].path.setText("");
slot[0].path.setEnabled(true);
slot[0].browse.setEnabled(true);
slot[1].path.setText("");
slot[1].path.setEnabled(false);
slot[1].browse.setEnabled(false);
base.browse.onActivate = [&] {
fileBrowser->open("Load BIOS - Super Game Boy", FileBrowser::Mode::SNES, [&](const string &filename) {
config->path.bios.superGameBoy = filename;
base.path.setText(filename);
synchronize();
});
};
slot[0].browse.onActivate = [&] {
fileBrowser->open("Load Cartridge - Game Boy", FileBrowser::Mode::GameBoy, [&](const string &filename) {
slot[0].path.setText(filename);
synchronize();
});
};
loadButton.onActivate = [&] {
this->setVisible(false);
interface->snes.loadSuperGameBoyCartridge(base.path.text(), slot[0].path.text());
};
synchronize();
setVisible();
}

View File

@ -1,29 +0,0 @@
struct SlotLoaderPath : HorizontalLayout {
Label label;
LineEdit path;
Button browse;
string name;
lstring filter;
SlotLoaderPath();
};
struct SlotLoader : Window {
VerticalLayout layout;
SlotLoaderPath base;
SlotLoaderPath slot[2];
HorizontalLayout controlLayout;
Widget spacer;
Button loadButton;
void synchronize();
void loadSatellaviewSlotted();
void loadSatellaview();
void loadSufamiTurbo();
void loadSuperGameBoy();
SlotLoader();
};
extern SlotLoader *slotLoader;

View File

@ -29,24 +29,11 @@ bool InterfaceNES::loadCartridge(const string &filename) {
unsigned size; unsigned size;
if(filename.endswith("/")) { if(filename.endswith("/")) {
if(file::exists({ filename, "program.rom" }) && file::exists({ filename, "character.rom" })) { if(file::read({filename, "program.rom"}, data, size) == false) return false;
unsigned prgsize = file::size({ filename, "program.rom" }); interface->base = {true, filename};
unsigned chrsize = file::size({ filename, "character.rom" });
data = new uint8_t[size = prgsize + chrsize];
nall::file fp;
fp.open({ filename, "program.rom" }, file::mode::read);
fp.read(data, fp.size());
fp.close();
fp.open({ filename, "character.rom" }, file::mode::read);
fp.read(data + prgsize, fp.size());
fp.close();
} else {
return false;
}
interface->base = { true, filename };
} else { } else {
file::read(filename, data, size); file::read(filename, data, size);
interface->base = { false, nall::basename(filename) }; interface->base = {false, nall::basename(filename)};
} }
interface->game = interface->base; interface->game = interface->base;

View File

@ -64,7 +64,6 @@ Application::Application(int argc, char **argv) {
windowManager = new WindowManager; windowManager = new WindowManager;
mainWindow = new MainWindow; mainWindow = new MainWindow;
fileBrowser = new FileBrowser; fileBrowser = new FileBrowser;
slotLoader = new SlotLoader;
dipSwitches = new DipSwitches; dipSwitches = new DipSwitches;
settingsWindow = new SettingsWindow; settingsWindow = new SettingsWindow;
cheatDatabase = new CheatDatabase; cheatDatabase = new CheatDatabase;
@ -135,7 +134,6 @@ Application::~Application() {
delete cheatDatabase; delete cheatDatabase;
delete settingsWindow; delete settingsWindow;
delete dipSwitches; delete dipSwitches;
delete slotLoader;
delete fileBrowser; delete fileBrowser;
delete mainWindow; delete mainWindow;
delete windowManager; delete windowManager;