fuck this shit
This commit is contained in:
+15
-13
@@ -22,26 +22,28 @@ void Core::Reset() {
|
|||||||
|
|
||||||
void Core::LoadTAS(const fs::path &path) const { mem->mmio.si.pif.movie.Load(path); }
|
void Core::LoadTAS(const fs::path &path) const { mem->mmio.si.pif.movie.Load(path); }
|
||||||
|
|
||||||
void Core::LoadROM(const std::string &rom_) {
|
void Core::LoadROM(const std::string &romFilename) {
|
||||||
Stop();
|
Stop();
|
||||||
rom = rom_;
|
romPath = romFilename;
|
||||||
|
|
||||||
std::string archive_types[] = {".zip", ".7z", ".rar", ".tar"};
|
std::string archive_types[] = {".zip", ".7z", ".rar", ".tar"};
|
||||||
|
|
||||||
auto extension = fs::path(rom).extension().string();
|
auto extension = fs::path(romPath).extension().string();
|
||||||
const bool isArchive = std::ranges::any_of(archive_types, [&extension](const auto &e) { return e == extension; });
|
const bool isArchive = std::ranges::any_of(archive_types, [&extension](const auto &e) { return e == extension; });
|
||||||
|
|
||||||
mem->LoadROM(isArchive, rom);
|
auto rom = Mem::LoadROM(isArchive, romPath);
|
||||||
GameDB::match();
|
GameDB::match(rom);
|
||||||
if (mem->rom.gameNameDB.empty()) {
|
mem->rom = rom;
|
||||||
mem->rom.gameNameDB = fs::path(rom).stem().string();
|
if (rom.gameNameDB.empty()) {
|
||||||
|
rom.gameNameDB = fs::path(romPath).stem().string();
|
||||||
|
mem->rom.gameNameDB = rom.gameNameDB;
|
||||||
}
|
}
|
||||||
mem->mmio.vi.isPal = mem->IsROMPAL();
|
mem->mmio.vi.isPal = Mem::IsROMPAL(rom);
|
||||||
mem->mmio.si.pif.InitDevices(mem->saveType);
|
mem->mmio.si.pif.InitDevices(mem->rom.saveType);
|
||||||
mem->mmio.si.pif.mempakPath = rom;
|
mem->mmio.si.pif.mempakPath = romPath;
|
||||||
mem->mmio.si.pif.LoadEeprom(mem->saveType, rom);
|
mem->mmio.si.pif.LoadEeprom(mem->rom.saveType, romPath);
|
||||||
mem->flash.Load(mem->saveType, rom);
|
mem->flash.Load(mem->rom.saveType, romPath);
|
||||||
mem->LoadSRAM(mem->saveType, rom);
|
mem->LoadSRAM(mem->rom.saveType, romPath);
|
||||||
mem->mmio.si.pif.Execute();
|
mem->mmio.si.pif.Execute();
|
||||||
pause = false;
|
pause = false;
|
||||||
romLoaded = true;
|
romLoaded = true;
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ struct Core {
|
|||||||
int slot = 0;
|
int slot = 0;
|
||||||
size_t memSize{}, cpuSize{}, verSize{};
|
size_t memSize{}, cpuSize{}, verSize{};
|
||||||
CPUType cpuType;
|
CPUType cpuType;
|
||||||
std::string rom;
|
std::string romPath;
|
||||||
std::set<s64> breakpoints{};
|
std::set<s64> breakpoints{};
|
||||||
std::unique_ptr<Mem> mem = std::make_unique<Mem>();
|
std::unique_ptr<Mem> mem = std::make_unique<Mem>();
|
||||||
Registers regs;
|
Registers regs;
|
||||||
|
|||||||
+79
-29
@@ -2,38 +2,88 @@
|
|||||||
#include <Core.hpp>
|
#include <Core.hpp>
|
||||||
|
|
||||||
namespace n64 {
|
namespace n64 {
|
||||||
void GameDB::match() {
|
const char *regionCodeToReadable(char r) {
|
||||||
n64::Mem& mem = n64::Core::GetMem();
|
switch (r) {
|
||||||
const ROM &rom = mem.rom;
|
case 0:
|
||||||
for (const auto &[code, regions, saveType, name] : gamedb) {
|
return "Region-free";
|
||||||
const bool matches_code = code == rom.code;
|
case 'A':
|
||||||
bool matches_region = false;
|
return "All regions";
|
||||||
|
case 'B':
|
||||||
|
return "Brazil";
|
||||||
|
case 'C':
|
||||||
|
return "China";
|
||||||
|
case 'D':
|
||||||
|
return "Germany";
|
||||||
|
case 'E':
|
||||||
|
return "North America";
|
||||||
|
case 'F':
|
||||||
|
return "France";
|
||||||
|
case 'G':
|
||||||
|
return "Gateway 64 (NTSC)";
|
||||||
|
case 'H':
|
||||||
|
return "Netherlands";
|
||||||
|
case 'I':
|
||||||
|
return "Italy";
|
||||||
|
case 'J':
|
||||||
|
return "Japan";
|
||||||
|
case 'K':
|
||||||
|
return "Korea";
|
||||||
|
case 'L':
|
||||||
|
return "Gateway 64 (PAL)";
|
||||||
|
case 'N':
|
||||||
|
return "Canada";
|
||||||
|
case 'S':
|
||||||
|
return "Spain";
|
||||||
|
case 'U':
|
||||||
|
return "Australia";
|
||||||
|
case 'W':
|
||||||
|
return "Scandinavia";
|
||||||
|
case 'P':
|
||||||
|
case 'X':
|
||||||
|
case 'Y':
|
||||||
|
case 'Z':
|
||||||
|
return "Europe";
|
||||||
|
default:
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int j = 0; j < regions.size() && !matches_region; j++) {
|
std::string GameDB::match(ROM &rom) {
|
||||||
if (regions[j] == rom.header.countryCode[0]) {
|
std::string result = "";
|
||||||
matches_region = true;
|
|
||||||
}
|
for (const auto &[code, regions, saveType, name] : gamedb) {
|
||||||
|
bool matches_region = false;
|
||||||
|
|
||||||
|
if (code == rom.code) {
|
||||||
|
for (int j = 0; j < regions.size(); j++) {
|
||||||
|
if (j == regions.size() - 1)
|
||||||
|
result += regionCodeToReadable(regions[j]);
|
||||||
|
else
|
||||||
|
result += std::string(regionCodeToReadable(regions[j])) + ", ";
|
||||||
|
|
||||||
|
if (regions[j] == rom.header.countryCode[0])
|
||||||
|
matches_region = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matches_region) {
|
||||||
|
rom.saveType = saveType;
|
||||||
|
rom.gameNameDB = name;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
info("Matched code for {}, but not region! Game supposedly exists in regions [{}] but this image has "
|
||||||
|
"region {}",
|
||||||
|
name, regions, rom.header.countryCode[0]);
|
||||||
|
rom.saveType = saveType;
|
||||||
|
rom.gameNameDB = name;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matches_code) {
|
info("Did not match any Game DB entries. Code: {} Region: {}", rom.code, rom.header.countryCode[0]);
|
||||||
if (matches_region) {
|
|
||||||
mem.saveType = saveType;
|
|
||||||
mem.rom.gameNameDB = name;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
warn(
|
rom.gameNameDB = "";
|
||||||
"Matched code for {}, but not region! Game supposedly exists in regions [{}] but this image has region {}",
|
rom.saveType = SAVE_NONE;
|
||||||
name, regions, rom.header.countryCode[0]);
|
return "Unknown";
|
||||||
mem.saveType = saveType;
|
|
||||||
mem.rom.gameNameDB = name;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
warn("Did not match any Game DB entries. Code: {} Region: {}", mem.rom.code, mem.rom.header.countryCode[0]);
|
|
||||||
|
|
||||||
mem.rom.gameNameDB = "";
|
|
||||||
mem.saveType = SAVE_NONE;
|
|
||||||
}
|
}
|
||||||
} // namespace n64
|
} // namespace n64
|
||||||
|
|||||||
+190
-189
@@ -3,201 +3,202 @@
|
|||||||
|
|
||||||
namespace n64 {
|
namespace n64 {
|
||||||
enum SaveType { SAVE_NONE, SAVE_EEPROM_4k, SAVE_EEPROM_16k, SAVE_FLASH_1m, SAVE_SRAM_256k };
|
enum SaveType { SAVE_NONE, SAVE_EEPROM_4k, SAVE_EEPROM_16k, SAVE_FLASH_1m, SAVE_SRAM_256k };
|
||||||
|
struct ROM;
|
||||||
|
|
||||||
struct GameDBEntry {
|
struct GameDBEntry {
|
||||||
std::string code;
|
std::string code;
|
||||||
std::string regions;
|
std::string regions;
|
||||||
SaveType saveType;
|
SaveType saveType;
|
||||||
const char *name;
|
const char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace GameDB {
|
namespace GameDB {
|
||||||
void match();
|
std::string match(ROM &);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const GameDBEntry gamedb[] = {
|
static const GameDBEntry gamedb[] = {
|
||||||
{"NNM", "E", SAVE_NONE, "Namco Museum 64"},
|
{"NNM", "E", SAVE_NONE, "Namco Museum 64"},
|
||||||
{"NDM", "E", SAVE_NONE, "Doom 64"},
|
{"NDM", "E", SAVE_NONE, "Doom 64"},
|
||||||
{"NGN", "E", SAVE_EEPROM_4k, "GoldenEye 007"},
|
{"NGN", "E", SAVE_EEPROM_4k, "GoldenEye 007"},
|
||||||
// Copied from CEN64 with small edits: https://github.com/n64dev/cen64/blob/master/device/cart_db.c
|
// Copied from CEN64 with small edits: https://github.com/n64dev/cen64/blob/master/device/cart_db.c
|
||||||
{"CFZ", "EJ", SAVE_SRAM_256k, "F-Zero X (NTSC)"},
|
{"CFZ", "EJ", SAVE_SRAM_256k, "F-Zero X (NTSC)"},
|
||||||
{"CLB", "EJ", SAVE_EEPROM_4k, "Mario Party (NTSC)"},
|
{"CLB", "EJ", SAVE_EEPROM_4k, "Mario Party (NTSC)"},
|
||||||
{"CP2", "J", SAVE_FLASH_1m, "Pokémon Stadium 2 (Japan)"},
|
{"CP2", "J", SAVE_FLASH_1m, "Pokémon Stadium 2 (Japan)"},
|
||||||
{"CPS", "J", SAVE_SRAM_256k, "Pokémon Stadium (Japan)"},
|
{"CPS", "J", SAVE_SRAM_256k, "Pokémon Stadium (Japan)"},
|
||||||
{"CZL", "EJ", SAVE_SRAM_256k, "Legend of Zelda: Ocarina of Time (NTSC)"},
|
{"CZL", "EJ", SAVE_SRAM_256k, "Legend of Zelda: Ocarina of Time (NTSC)"},
|
||||||
{"N3D", "J", SAVE_EEPROM_16k, "Doraemon 3: Nobita no Machi SOS!"},
|
{"N3D", "J", SAVE_EEPROM_16k, "Doraemon 3: Nobita no Machi SOS!"},
|
||||||
{"N3H", "J", SAVE_SRAM_256k, "Ganbare! Nippon! Olympics 2000"},
|
{"N3H", "J", SAVE_SRAM_256k, "Ganbare! Nippon! Olympics 2000"},
|
||||||
{"NA2", "J", SAVE_SRAM_256k, "Virtual Pro Wrestling 2"},
|
{"NA2", "J", SAVE_SRAM_256k, "Virtual Pro Wrestling 2"},
|
||||||
{"NAB", "JP", SAVE_EEPROM_4k, "Air Boarder 64"},
|
{"NAB", "JP", SAVE_EEPROM_4k, "Air Boarder 64"},
|
||||||
{"NAD", "E", SAVE_EEPROM_4k, "Worms Armageddon (USA)"},
|
{"NAD", "E", SAVE_EEPROM_4k, "Worms Armageddon (USA)"},
|
||||||
{"NAF", "J", SAVE_FLASH_1m, "Doubutsu no Mori"},
|
{"NAF", "J", SAVE_FLASH_1m, "Doubutsu no Mori"},
|
||||||
{"NAG", "EJP", SAVE_EEPROM_4k, "AeroGauge"},
|
{"NAG", "EJP", SAVE_EEPROM_4k, "AeroGauge"},
|
||||||
{"NAL", "EJPU", SAVE_SRAM_256k, "Super Smash Bros"},
|
{"NAL", "EJPU", SAVE_SRAM_256k, "Super Smash Bros"},
|
||||||
{"NB5", "J", SAVE_SRAM_256k, "Biohazard 2"},
|
{"NB5", "J", SAVE_SRAM_256k, "Biohazard 2"},
|
||||||
{"NB6", "J", SAVE_EEPROM_4k, "Super B-Daman: Battle Phoenix 64"},
|
{"NB6", "J", SAVE_EEPROM_4k, "Super B-Daman: Battle Phoenix 64"},
|
||||||
{"NB7", "EJPU", SAVE_EEPROM_16k, "Banjo-Tooie"},
|
{"NB7", "EJPU", SAVE_EEPROM_16k, "Banjo-Tooie"},
|
||||||
{"NBC", "EJP", SAVE_EEPROM_4k, "Blast Corps"},
|
{"NBC", "EJP", SAVE_EEPROM_4k, "Blast Corps"},
|
||||||
{"NBD", "EJP", SAVE_EEPROM_4k, "Bomberman Hero"},
|
{"NBD", "EJP", SAVE_EEPROM_4k, "Bomberman Hero"},
|
||||||
{"NBH", "EP", SAVE_EEPROM_4k, "Body Harvest"},
|
{"NBH", "EP", SAVE_EEPROM_4k, "Body Harvest"},
|
||||||
{"NBK", "EJP", SAVE_EEPROM_4k, "Banjo-Kazooie"},
|
{"NBK", "EJP", SAVE_EEPROM_4k, "Banjo-Kazooie"},
|
||||||
{"NBM", "EJP", SAVE_EEPROM_4k, "Bomberman 64"},
|
{"NBM", "EJP", SAVE_EEPROM_4k, "Bomberman 64"},
|
||||||
{"NBN", "J", SAVE_EEPROM_4k, "Bakuretsu Muteki Bangaioh"},
|
{"NBN", "J", SAVE_EEPROM_4k, "Bakuretsu Muteki Bangaioh"},
|
||||||
{"NBV", "EJ", SAVE_EEPROM_4k, "Bomberman 64: The Second Attack!"},
|
{"NBV", "EJ", SAVE_EEPROM_4k, "Bomberman 64: The Second Attack!"},
|
||||||
{"NCC", "DEP", SAVE_FLASH_1m, "Command & Conquer"},
|
{"NCC", "DEP", SAVE_FLASH_1m, "Command & Conquer"},
|
||||||
{"NCG", "J", SAVE_EEPROM_4k, "Choro Q 64 2: Hacha-Mecha Grand Prix Race"},
|
{"NCG", "J", SAVE_EEPROM_4k, "Choro Q 64 2: Hacha-Mecha Grand Prix Race"},
|
||||||
{"NCH", "EP", SAVE_EEPROM_4k, "Chopper Attack"},
|
{"NCH", "EP", SAVE_EEPROM_4k, "Chopper Attack"},
|
||||||
{"NCK", "E", SAVE_FLASH_1m, "NBA Courtside 2"},
|
{"NCK", "E", SAVE_FLASH_1m, "NBA Courtside 2"},
|
||||||
{"NCR", "EJP", SAVE_EEPROM_4k, "Penny Racers"},
|
{"NCR", "EJP", SAVE_EEPROM_4k, "Penny Racers"},
|
||||||
{"NCT", "EJP", SAVE_EEPROM_4k, "Chameleon Twist"},
|
{"NCT", "EJP", SAVE_EEPROM_4k, "Chameleon Twist"},
|
||||||
{"NCU", "EP", SAVE_EEPROM_4k, "Cruis'n USA"},
|
{"NCU", "EP", SAVE_EEPROM_4k, "Cruis'n USA"},
|
||||||
{"NCW", "EP", SAVE_EEPROM_16k, "Cruis'n World"},
|
{"NCW", "EP", SAVE_EEPROM_16k, "Cruis'n World"},
|
||||||
{"NCX", "J", SAVE_EEPROM_4k, "Custom Robo"},
|
{"NCX", "J", SAVE_EEPROM_4k, "Custom Robo"},
|
||||||
{"NCZ", "J", SAVE_EEPROM_16k, "Custom Robo V2"},
|
{"NCZ", "J", SAVE_EEPROM_16k, "Custom Robo V2"},
|
||||||
{"ND2", "J", SAVE_EEPROM_16k, "Doraemon 2: Nobita to Hikari no Shinden"},
|
{"ND2", "J", SAVE_EEPROM_16k, "Doraemon 2: Nobita to Hikari no Shinden"},
|
||||||
{"ND3", "J", SAVE_EEPROM_16k, "Akumajou Dracula Mokushiroku"},
|
{"ND3", "J", SAVE_EEPROM_16k, "Akumajou Dracula Mokushiroku"},
|
||||||
{"ND4", "J", SAVE_EEPROM_16k, "Akumajou Dracula Mokushiroku Gaiden: Legend of Cornell"},
|
{"ND4", "J", SAVE_EEPROM_16k, "Akumajou Dracula Mokushiroku Gaiden: Legend of Cornell"},
|
||||||
{"ND6", "J", SAVE_EEPROM_16k, "Densha de Go! 64"},
|
{"ND6", "J", SAVE_EEPROM_16k, "Densha de Go! 64"},
|
||||||
{"NDA", "J", SAVE_FLASH_1m, "Derby Stallion 64"},
|
{"NDA", "J", SAVE_FLASH_1m, "Derby Stallion 64"},
|
||||||
{"NDK", "J", SAVE_EEPROM_4k, "Space Dynamites"},
|
{"NDK", "J", SAVE_EEPROM_4k, "Space Dynamites"},
|
||||||
{"NDO", "EJP", SAVE_EEPROM_16k, "Donkey Kong 64"},
|
{"NDO", "EJP", SAVE_EEPROM_16k, "Donkey Kong 64"},
|
||||||
{"NDP", "E", SAVE_FLASH_1m, "Dinosaur Planet"},
|
{"NDP", "E", SAVE_FLASH_1m, "Dinosaur Planet"},
|
||||||
{"NDR", "J", SAVE_EEPROM_4k, "Doraemon: Nobita to 3tsu no Seireiseki"},
|
{"NDR", "J", SAVE_EEPROM_4k, "Doraemon: Nobita to 3tsu no Seireiseki"},
|
||||||
{"NDU", "EP", SAVE_EEPROM_4k, "Duck Dodgers"},
|
{"NDU", "EP", SAVE_EEPROM_4k, "Duck Dodgers"},
|
||||||
{"NDY", "EJP", SAVE_EEPROM_4k, "Diddy Kong Racing"},
|
{"NDY", "EJP", SAVE_EEPROM_4k, "Diddy Kong Racing"},
|
||||||
{"NEA", "EP", SAVE_EEPROM_4k, "PGA European Tour"},
|
{"NEA", "EP", SAVE_EEPROM_4k, "PGA European Tour"},
|
||||||
{"NEP", "EJP", SAVE_EEPROM_16k, "Star Wars Episode I: Racer"},
|
{"NEP", "EJP", SAVE_EEPROM_16k, "Star Wars Episode I: Racer"},
|
||||||
{"NER", "E", SAVE_EEPROM_4k, "AeroFighters Assault (USA)"},
|
{"NER", "E", SAVE_EEPROM_4k, "AeroFighters Assault (USA)"},
|
||||||
{"NEV", "J", SAVE_EEPROM_16k, "Neon Genesis Evangelion"},
|
{"NEV", "J", SAVE_EEPROM_16k, "Neon Genesis Evangelion"},
|
||||||
{"NF2", "P", SAVE_EEPROM_4k, "F-1 World Grand Prix II"},
|
{"NF2", "P", SAVE_EEPROM_4k, "F-1 World Grand Prix II"},
|
||||||
{"NFG", "E", SAVE_EEPROM_4k, "Fighter Destiny 2"},
|
{"NFG", "E", SAVE_EEPROM_4k, "Fighter Destiny 2"},
|
||||||
{"NFH", "EP", SAVE_EEPROM_4k, "Bass Hunter 64"},
|
{"NFH", "EP", SAVE_EEPROM_4k, "Bass Hunter 64"},
|
||||||
{"NFU", "EP", SAVE_EEPROM_16k, "Conker's Bad Fur Day"},
|
{"NFU", "EP", SAVE_EEPROM_16k, "Conker's Bad Fur Day"},
|
||||||
{"NFW", "DEFJP", SAVE_EEPROM_4k, "F-1 World Grand Prix"},
|
{"NFW", "DEFJP", SAVE_EEPROM_4k, "F-1 World Grand Prix"},
|
||||||
{"NFX", "EJPU", SAVE_EEPROM_4k, "Star Fox 64"},
|
{"NFX", "EJPU", SAVE_EEPROM_4k, "Star Fox 64"},
|
||||||
{"NFY", "J", SAVE_EEPROM_4k, "Kakutou Denshou: F-Cup Maniax"},
|
{"NFY", "J", SAVE_EEPROM_4k, "Kakutou Denshou: F-Cup Maniax"},
|
||||||
{"NFZ", "P", SAVE_SRAM_256k, "F-Zero X (PAL)"},
|
{"NFZ", "P", SAVE_SRAM_256k, "F-Zero X (PAL)"},
|
||||||
{"NG6", "J", SAVE_SRAM_256k, "Ganbare Goemon: Dero Dero Douchuu Obake Tenkomori"},
|
{"NG6", "J", SAVE_SRAM_256k, "Ganbare Goemon: Dero Dero Douchuu Obake Tenkomori"},
|
||||||
{"NGC", "EP", SAVE_EEPROM_16k, "GT 64: Championship Edition"},
|
{"NGC", "EP", SAVE_EEPROM_16k, "GT 64: Championship Edition"},
|
||||||
{"NGE", "EJP", SAVE_EEPROM_4k, "GoldenEye 007"},
|
{"NGE", "EJP", SAVE_EEPROM_4k, "GoldenEye 007"},
|
||||||
{"NGL", "J", SAVE_EEPROM_4k, "Getter Love!!"},
|
{"NGL", "J", SAVE_EEPROM_4k, "Getter Love!!"},
|
||||||
{"NGP", "J", SAVE_SRAM_256k, "Goemon: Mononoke Sugoroku"},
|
{"NGP", "J", SAVE_SRAM_256k, "Goemon: Mononoke Sugoroku"},
|
||||||
{"NGT", "J", SAVE_EEPROM_16k, "City-Tour GP: Zen-Nihon GT Senshuken"},
|
{"NGT", "J", SAVE_EEPROM_16k, "City-Tour GP: Zen-Nihon GT Senshuken"},
|
||||||
{"NGU", "J", SAVE_EEPROM_4k, "Tsumi to Batsu: Hoshi no Keishousha"},
|
{"NGU", "J", SAVE_EEPROM_4k, "Tsumi to Batsu: Hoshi no Keishousha"},
|
||||||
{"NGV", "EP", SAVE_EEPROM_4k, "Glover"},
|
{"NGV", "EP", SAVE_EEPROM_4k, "Glover"},
|
||||||
{"NHA", "J", SAVE_EEPROM_4k, "Bomber Man 64 (Japan)"},
|
{"NHA", "J", SAVE_EEPROM_4k, "Bomber Man 64 (Japan)"},
|
||||||
{"NHF", "J", SAVE_EEPROM_4k, "64 Hanafuda: Tenshi no Yakusoku"},
|
{"NHF", "J", SAVE_EEPROM_4k, "64 Hanafuda: Tenshi no Yakusoku"},
|
||||||
{"NHP", "J", SAVE_EEPROM_4k, "Heiwa Pachinko World 64"},
|
{"NHP", "J", SAVE_EEPROM_4k, "Heiwa Pachinko World 64"},
|
||||||
{"NHY", "J", SAVE_SRAM_256k, "Hybrid Heaven (Japan)"},
|
{"NHY", "J", SAVE_SRAM_256k, "Hybrid Heaven (Japan)"},
|
||||||
{"NIB", "J", SAVE_SRAM_256k, "Itoi Shigesato no Bass Tsuri No. 1 Kettei Ban!"},
|
{"NIB", "J", SAVE_SRAM_256k, "Itoi Shigesato no Bass Tsuri No. 1 Kettei Ban!"},
|
||||||
{"NIC", "E", SAVE_EEPROM_4k, "Indy Racing 2000"},
|
{"NIC", "E", SAVE_EEPROM_4k, "Indy Racing 2000"},
|
||||||
{"NIJ", "EP", SAVE_EEPROM_4k, "Indiana Jones and the Infernal Machine"},
|
{"NIJ", "EP", SAVE_EEPROM_4k, "Indiana Jones and the Infernal Machine"},
|
||||||
{"NIM", "J", SAVE_EEPROM_16k, "Ide Yosuke no Mahjong Juku"},
|
{"NIM", "J", SAVE_EEPROM_16k, "Ide Yosuke no Mahjong Juku"},
|
||||||
{"NIR", "J", SAVE_EEPROM_4k, "Utchan Nanchan no Hono no Challenger: Denryuu Ira Ira Bou"},
|
{"NIR", "J", SAVE_EEPROM_4k, "Utchan Nanchan no Hono no Challenger: Denryuu Ira Ira Bou"},
|
||||||
{"NJ5", "J", SAVE_SRAM_256k, "Jikkyou Powerful Pro Yakyuu 5"},
|
{"NJ5", "J", SAVE_SRAM_256k, "Jikkyou Powerful Pro Yakyuu 5"},
|
||||||
{"NJD", "E", SAVE_FLASH_1m, "Jet Force Gemini (Kiosk Demo)"},
|
{"NJD", "E", SAVE_FLASH_1m, "Jet Force Gemini (Kiosk Demo)"},
|
||||||
{"NJF", "EJP", SAVE_FLASH_1m, "Jet Force Gemini"},
|
{"NJF", "EJP", SAVE_FLASH_1m, "Jet Force Gemini"},
|
||||||
{"NJG", "J", SAVE_SRAM_256k, "Jinsei Game 64"},
|
{"NJG", "J", SAVE_SRAM_256k, "Jinsei Game 64"},
|
||||||
{"NJM", "EP", SAVE_EEPROM_4k, "Earthworm Jim 3D"},
|
{"NJM", "EP", SAVE_EEPROM_4k, "Earthworm Jim 3D"},
|
||||||
{"NK2", "EJP", SAVE_EEPROM_4k, "Snowboard Kids 2"},
|
{"NK2", "EJP", SAVE_EEPROM_4k, "Snowboard Kids 2"},
|
||||||
{"NK4", "EJP", SAVE_EEPROM_16k, "Kirby 64: The Crystal Shards"},
|
{"NK4", "EJP", SAVE_EEPROM_16k, "Kirby 64: The Crystal Shards"},
|
||||||
{"NKA", "DEFJP", SAVE_EEPROM_4k, "Fighters Destiny"},
|
{"NKA", "DEFJP", SAVE_EEPROM_4k, "Fighters Destiny"},
|
||||||
{"NKG", "EP", SAVE_SRAM_256k, "MLB featuring Ken Griffey Jr."},
|
{"NKG", "EP", SAVE_SRAM_256k, "MLB featuring Ken Griffey Jr."},
|
||||||
{"NKI", "EP", SAVE_EEPROM_4k, "Killer Instinct Gold"},
|
{"NKI", "EP", SAVE_EEPROM_4k, "Killer Instinct Gold"},
|
||||||
{"NKJ", "E", SAVE_FLASH_1m, "Ken Griffey Jr.'s Slugfest"},
|
{"NKJ", "E", SAVE_FLASH_1m, "Ken Griffey Jr.'s Slugfest"},
|
||||||
{"NKT", "EJP", SAVE_EEPROM_4k, "Mario Kart 64"},
|
{"NKT", "EJP", SAVE_EEPROM_4k, "Mario Kart 64"},
|
||||||
{"NLB", "P", SAVE_EEPROM_4k, "Mario Party (PAL)"},
|
{"NLB", "P", SAVE_EEPROM_4k, "Mario Party (PAL)"},
|
||||||
{"NLL", "J", SAVE_EEPROM_4k, "Last Legion UX"},
|
{"NLL", "J", SAVE_EEPROM_4k, "Last Legion UX"},
|
||||||
{"NLR", "EJP", SAVE_EEPROM_4k, "Lode Runner 3D"},
|
{"NLR", "EJP", SAVE_EEPROM_4k, "Lode Runner 3D"},
|
||||||
{"NM6", "E", SAVE_FLASH_1m, "Mega Man 64"},
|
{"NM6", "E", SAVE_FLASH_1m, "Mega Man 64"},
|
||||||
{"NM8", "EJP", SAVE_EEPROM_16k, "Mario Tennis"},
|
{"NM8", "EJP", SAVE_EEPROM_16k, "Mario Tennis"},
|
||||||
{"NMF", "EJP", SAVE_SRAM_256k, "Mario Golf"},
|
{"NMF", "EJP", SAVE_SRAM_256k, "Mario Golf"},
|
||||||
{"NMG", "DEP", SAVE_EEPROM_4k, "Monaco Grand Prix"},
|
{"NMG", "DEP", SAVE_EEPROM_4k, "Monaco Grand Prix"},
|
||||||
{"NMI", "DEFIPS", SAVE_EEPROM_4k, "Mission: Impossible"},
|
{"NMI", "DEFIPS", SAVE_EEPROM_4k, "Mission: Impossible"},
|
||||||
{"NML", "EJP", SAVE_EEPROM_4k, "Mickey's Speedway USA"},
|
{"NML", "EJP", SAVE_EEPROM_4k, "Mickey's Speedway USA"},
|
||||||
{"NMO", "E", SAVE_EEPROM_4k, "Monopoly"},
|
{"NMO", "E", SAVE_EEPROM_4k, "Monopoly"},
|
||||||
{"NMQ", "EJP", SAVE_FLASH_1m, "Paper Mario"},
|
{"NMQ", "EJP", SAVE_FLASH_1m, "Paper Mario"},
|
||||||
{"NMR", "EJP", SAVE_EEPROM_4k, "Multi Racing Championship"},
|
{"NMR", "EJP", SAVE_EEPROM_4k, "Multi Racing Championship"},
|
||||||
{"NMS", "J", SAVE_EEPROM_4k, "Morita Shougi 64"},
|
{"NMS", "J", SAVE_EEPROM_4k, "Morita Shougi 64"},
|
||||||
{"NMU", "E", SAVE_EEPROM_4k, "Big Mountain 2000"},
|
{"NMU", "E", SAVE_EEPROM_4k, "Big Mountain 2000"},
|
||||||
{"NMV", "EJP", SAVE_EEPROM_16k, "Mario Party 3"},
|
{"NMV", "EJP", SAVE_EEPROM_16k, "Mario Party 3"},
|
||||||
{"NMW", "EJP", SAVE_EEPROM_4k, "Mario Party 2"},
|
{"NMW", "EJP", SAVE_EEPROM_4k, "Mario Party 2"},
|
||||||
{"NMX", "EJP", SAVE_EEPROM_16k, "Excitebike 64"},
|
{"NMX", "EJP", SAVE_EEPROM_16k, "Excitebike 64"},
|
||||||
{"NN6", "E", SAVE_EEPROM_4k, "Dr. Mario 64"},
|
{"NN6", "E", SAVE_EEPROM_4k, "Dr. Mario 64"},
|
||||||
{"NNA", "EP", SAVE_EEPROM_4k, "Star Wars Episode I: Battle for Naboo"},
|
{"NNA", "EP", SAVE_EEPROM_4k, "Star Wars Episode I: Battle for Naboo"},
|
||||||
{"NNB", "EP", SAVE_EEPROM_16k, "Kobe Bryant in NBA Courtside"},
|
{"NNB", "EP", SAVE_EEPROM_16k, "Kobe Bryant in NBA Courtside"},
|
||||||
{"NOB", "EJ", SAVE_SRAM_256k, "Ogre Battle 64: Person of Lordly Caliber"},
|
{"NOB", "EJ", SAVE_SRAM_256k, "Ogre Battle 64: Person of Lordly Caliber"},
|
||||||
{"NOS", "J", SAVE_EEPROM_4k, "64 Oozumou"},
|
{"NOS", "J", SAVE_EEPROM_4k, "64 Oozumou"},
|
||||||
{"NP2", "J", SAVE_EEPROM_4k, "Chou Kuukan Nighter Pro Yakyuu King 2"},
|
{"NP2", "J", SAVE_EEPROM_4k, "Chou Kuukan Nighter Pro Yakyuu King 2"},
|
||||||
{"NP3", "DEFIJPS", SAVE_FLASH_1m, "Pokémon Stadium 2"},
|
{"NP3", "DEFIJPS", SAVE_FLASH_1m, "Pokémon Stadium 2"},
|
||||||
{"NP6", "J", SAVE_SRAM_256k, "Jikkyou Powerful Pro Yakyuu 6"},
|
{"NP6", "J", SAVE_SRAM_256k, "Jikkyou Powerful Pro Yakyuu 6"},
|
||||||
{"NPA", "J", SAVE_SRAM_256k, "Jikkyou Powerful Pro Yakyuu 2000"},
|
{"NPA", "J", SAVE_SRAM_256k, "Jikkyou Powerful Pro Yakyuu 2000"},
|
||||||
{"NPD", "EJP", SAVE_EEPROM_16k, "Perfect Dark"},
|
{"NPD", "EJP", SAVE_EEPROM_16k, "Perfect Dark"},
|
||||||
{"NPE", "J", SAVE_SRAM_256k, "Jikkyou Powerful Pro Yakyuu Basic Ban 2001"},
|
{"NPE", "J", SAVE_SRAM_256k, "Jikkyou Powerful Pro Yakyuu Basic Ban 2001"},
|
||||||
{"NPF", "DEFIJPSU", SAVE_FLASH_1m, "Pokémon Snap"},
|
{"NPF", "DEFIJPSU", SAVE_FLASH_1m, "Pokémon Snap"},
|
||||||
{"NPG", "EJ", SAVE_EEPROM_4k, "Hey You, Pikachu!"},
|
{"NPG", "EJ", SAVE_EEPROM_4k, "Hey You, Pikachu!"},
|
||||||
{"NPH", "E", SAVE_FLASH_1m, "Pokémon Snap Station (Kiosk Demo)"},
|
{"NPH", "E", SAVE_FLASH_1m, "Pokémon Snap Station (Kiosk Demo)"},
|
||||||
{"NPM", "P", SAVE_SRAM_256k, "Premier Manager 64"},
|
{"NPM", "P", SAVE_SRAM_256k, "Premier Manager 64"},
|
||||||
{"NPN", "DEFP", SAVE_FLASH_1m, "Pokémon Puzzle League"},
|
{"NPN", "DEFP", SAVE_FLASH_1m, "Pokémon Puzzle League"},
|
||||||
{"NPO", "DEFIPS", SAVE_FLASH_1m, "Pokémon Stadium (USA, PAL)"},
|
{"NPO", "DEFIPS", SAVE_FLASH_1m, "Pokémon Stadium (USA, PAL)"},
|
||||||
{"NPP", "J", SAVE_EEPROM_16k, "Parlor! Pro 64: Pachinko Jikki Simulation Game"},
|
{"NPP", "J", SAVE_EEPROM_16k, "Parlor! Pro 64: Pachinko Jikki Simulation Game"},
|
||||||
{"NPS", "J", SAVE_SRAM_256k, "Jikkyou J.League 1999: Perfect Striker 2"},
|
{"NPS", "J", SAVE_SRAM_256k, "Jikkyou J.League 1999: Perfect Striker 2"},
|
||||||
{"NPT", "J", SAVE_EEPROM_4k, "Puyo Puyon Party"},
|
{"NPT", "J", SAVE_EEPROM_4k, "Puyo Puyon Party"},
|
||||||
{"NPW", "EJP", SAVE_EEPROM_4k, "Pilotwings 64"},
|
{"NPW", "EJP", SAVE_EEPROM_4k, "Pilotwings 64"},
|
||||||
{"NPY", "J", SAVE_EEPROM_4k, "Puyo Puyo Sun 64"},
|
{"NPY", "J", SAVE_EEPROM_4k, "Puyo Puyo Sun 64"},
|
||||||
{"NR7", "J", SAVE_EEPROM_16k, "Robot Poncots 64: 7tsu no Umi no Caramel"},
|
{"NR7", "J", SAVE_EEPROM_16k, "Robot Poncots 64: 7tsu no Umi no Caramel"},
|
||||||
{"NRA", "J", SAVE_EEPROM_4k, "Rally '99"},
|
{"NRA", "J", SAVE_EEPROM_4k, "Rally '99"},
|
||||||
{"NRC", "EJP", SAVE_EEPROM_4k, "Top Gear Overdrive"},
|
{"NRC", "EJP", SAVE_EEPROM_4k, "Top Gear Overdrive"},
|
||||||
{"NRE", "EP", SAVE_SRAM_256k, "Resident Evil 2"},
|
{"NRE", "EP", SAVE_SRAM_256k, "Resident Evil 2"},
|
||||||
{"NRH", "J", SAVE_FLASH_1m, "Rockman Dash"},
|
{"NRH", "J", SAVE_FLASH_1m, "Rockman Dash"},
|
||||||
{"NRI", "EP", SAVE_SRAM_256k, "The New Tetris"},
|
{"NRI", "EP", SAVE_SRAM_256k, "The New Tetris"},
|
||||||
{"NRS", "EJP", SAVE_EEPROM_4k, "Star Wars: Rogue Squadron"},
|
{"NRS", "EJP", SAVE_EEPROM_4k, "Star Wars: Rogue Squadron"},
|
||||||
{"NRZ", "EP", SAVE_EEPROM_16k, "Ridge Racer 64"},
|
{"NRZ", "EP", SAVE_EEPROM_16k, "Ridge Racer 64"},
|
||||||
{"NS4", "J", SAVE_SRAM_256k, "Super Robot Taisen 64"},
|
{"NS4", "J", SAVE_SRAM_256k, "Super Robot Taisen 64"},
|
||||||
{"NS6", "EJ", SAVE_EEPROM_4k, "Star Soldier: Vanishing Earth"},
|
{"NS6", "EJ", SAVE_EEPROM_4k, "Star Soldier: Vanishing Earth"},
|
||||||
{"NSA", "JP", SAVE_EEPROM_4k, "AeroFighters Assault (PAL, Japan)"},
|
{"NSA", "JP", SAVE_EEPROM_4k, "AeroFighters Assault (PAL, Japan)"},
|
||||||
{"NSC", "EP", SAVE_EEPROM_4k, "Starshot: Space Circus Fever"},
|
{"NSC", "EP", SAVE_EEPROM_4k, "Starshot: Space Circus Fever"},
|
||||||
{"NSI", "J", SAVE_SRAM_256k, "Fushigi no Dungeon: Fuurai no Shiren 2"},
|
{"NSI", "J", SAVE_SRAM_256k, "Fushigi no Dungeon: Fuurai no Shiren 2"},
|
||||||
{"NSM", "EJP", SAVE_EEPROM_4k, "Super Mario 64"},
|
{"NSM", "EJP", SAVE_EEPROM_4k, "Super Mario 64"},
|
||||||
{"NSN", "J", SAVE_EEPROM_4k, "Snow Speeder"},
|
{"NSN", "J", SAVE_EEPROM_4k, "Snow Speeder"},
|
||||||
{"NSQ", "EP", SAVE_FLASH_1m, "StarCraft 64"},
|
{"NSQ", "EP", SAVE_FLASH_1m, "StarCraft 64"},
|
||||||
{"NSS", "J", SAVE_EEPROM_4k, "Super Robot Spirits"},
|
{"NSS", "J", SAVE_EEPROM_4k, "Super Robot Spirits"},
|
||||||
{"NSU", "EP", SAVE_EEPROM_4k, "Rocket: Robot on Wheels"},
|
{"NSU", "EP", SAVE_EEPROM_4k, "Rocket: Robot on Wheels"},
|
||||||
{"NSV", "EP", SAVE_EEPROM_4k, "SpaceStation Silicon Valley"},
|
{"NSV", "EP", SAVE_EEPROM_4k, "SpaceStation Silicon Valley"},
|
||||||
{"NSW", "EJP", SAVE_EEPROM_4k, "Star Wars: Shadows of the Empire"},
|
{"NSW", "EJP", SAVE_EEPROM_4k, "Star Wars: Shadows of the Empire"},
|
||||||
{"NT3", "J", SAVE_SRAM_256k, "Toukon Road 2"},
|
{"NT3", "J", SAVE_SRAM_256k, "Toukon Road 2"},
|
||||||
{"NT6", "J", SAVE_EEPROM_4k, "Tetris 64"},
|
{"NT6", "J", SAVE_EEPROM_4k, "Tetris 64"},
|
||||||
{"NT9", "EP", SAVE_FLASH_1m, "Tigger's Honey Hunt"},
|
{"NT9", "EP", SAVE_FLASH_1m, "Tigger's Honey Hunt"},
|
||||||
{"NTB", "J", SAVE_EEPROM_4k, "Transformers: Beast Wars Metals 64"},
|
{"NTB", "J", SAVE_EEPROM_4k, "Transformers: Beast Wars Metals 64"},
|
||||||
{"NTC", "J", SAVE_EEPROM_4k, "64 Trump Collection"},
|
{"NTC", "J", SAVE_EEPROM_4k, "64 Trump Collection"},
|
||||||
{"NTE", "AP", SAVE_SRAM_256k, "1080 Snowboarding"},
|
{"NTE", "AP", SAVE_SRAM_256k, "1080 Snowboarding"},
|
||||||
{"NTJ", "EP", SAVE_EEPROM_4k, "Tom and Jerry in Fists of Furry"},
|
{"NTJ", "EP", SAVE_EEPROM_4k, "Tom and Jerry in Fists of Furry"},
|
||||||
{"NTM", "EJP", SAVE_EEPROM_4k, "Mischief Makers"},
|
{"NTM", "EJP", SAVE_EEPROM_4k, "Mischief Makers"},
|
||||||
{"NTN", "EP", SAVE_EEPROM_4k, "All-Star Tennis 99"},
|
{"NTN", "EP", SAVE_EEPROM_4k, "All-Star Tennis 99"},
|
||||||
{"NTP", "EP", SAVE_EEPROM_4k, "Tetrisphere"},
|
{"NTP", "EP", SAVE_EEPROM_4k, "Tetrisphere"},
|
||||||
{"NTR", "JP", SAVE_EEPROM_4k, "Top Gear Rally (PAL, Japan)"},
|
{"NTR", "JP", SAVE_EEPROM_4k, "Top Gear Rally (PAL, Japan)"},
|
||||||
{"NTW", "J", SAVE_EEPROM_4k, "64 de Hakken!! Tamagotchi"},
|
{"NTW", "J", SAVE_EEPROM_4k, "64 de Hakken!! Tamagotchi"},
|
||||||
{"NTX", "EP", SAVE_EEPROM_4k, "Taz Express"},
|
{"NTX", "EP", SAVE_EEPROM_4k, "Taz Express"},
|
||||||
{"NUB", "J", SAVE_EEPROM_16k, "PD Ultraman Battle Collection 64"},
|
{"NUB", "J", SAVE_EEPROM_16k, "PD Ultraman Battle Collection 64"},
|
||||||
{"NUM", "J", SAVE_SRAM_256k, "Nushi Zuri 64: Shiokaze ni Notte"},
|
{"NUM", "J", SAVE_SRAM_256k, "Nushi Zuri 64: Shiokaze ni Notte"},
|
||||||
{"NUT", "J", SAVE_SRAM_256k, "Nushi Zuri 64"},
|
{"NUT", "J", SAVE_SRAM_256k, "Nushi Zuri 64"},
|
||||||
{"NVB", "J", SAVE_SRAM_256k, "Bass Rush: ECOGEAR PowerWorm Championship"},
|
{"NVB", "J", SAVE_SRAM_256k, "Bass Rush: ECOGEAR PowerWorm Championship"},
|
||||||
{"NVL", "EP", SAVE_EEPROM_4k, "V-Rally 99 (USA, PAL)"},
|
{"NVL", "EP", SAVE_EEPROM_4k, "V-Rally 99 (USA, PAL)"},
|
||||||
{"NVP", "J", SAVE_SRAM_256k, "Virtual Pro Wrestling 64"},
|
{"NVP", "J", SAVE_SRAM_256k, "Virtual Pro Wrestling 64"},
|
||||||
{"NVY", "J", SAVE_EEPROM_4k, "V-Rally 99 (Japan)"},
|
{"NVY", "J", SAVE_EEPROM_4k, "V-Rally 99 (Japan)"},
|
||||||
{"NW2", "EP", SAVE_SRAM_256k, "WCW/nWo Revenge"},
|
{"NW2", "EP", SAVE_SRAM_256k, "WCW/nWo Revenge"},
|
||||||
{"NW4", "EP", SAVE_FLASH_1m, "WWF No Mercy"},
|
{"NW4", "EP", SAVE_FLASH_1m, "WWF No Mercy"},
|
||||||
{"NWC", "J", SAVE_EEPROM_4k, "Wild Choppers"},
|
{"NWC", "J", SAVE_EEPROM_4k, "Wild Choppers"},
|
||||||
{"NWL", "EP", SAVE_SRAM_256k, "Waialae Country Club: True Golf Classics"},
|
{"NWL", "EP", SAVE_SRAM_256k, "Waialae Country Club: True Golf Classics"},
|
||||||
{"NWQ", "E", SAVE_EEPROM_4k, "Rally Challenge 2000"},
|
{"NWQ", "E", SAVE_EEPROM_4k, "Rally Challenge 2000"},
|
||||||
{"NWR", "EJP", SAVE_EEPROM_4k, "Wave Race 64"},
|
{"NWR", "EJP", SAVE_EEPROM_4k, "Wave Race 64"},
|
||||||
{"NWT", "J", SAVE_EEPROM_4k, "Wetrix (Japan)"},
|
{"NWT", "J", SAVE_EEPROM_4k, "Wetrix (Japan)"},
|
||||||
{"NWU", "P", SAVE_EEPROM_4k, "Worms Armageddon (PAL)"},
|
{"NWU", "P", SAVE_EEPROM_4k, "Worms Armageddon (PAL)"},
|
||||||
{"NWX", "EJP", SAVE_SRAM_256k, "WWF WrestleMania 2000"},
|
{"NWX", "EJP", SAVE_SRAM_256k, "WWF WrestleMania 2000"},
|
||||||
{"NXO", "E", SAVE_EEPROM_4k, "Cruis'n Exotica"},
|
{"NXO", "E", SAVE_EEPROM_4k, "Cruis'n Exotica"},
|
||||||
{"NYK", "J", SAVE_EEPROM_4k, "Yakouchuu II: Satsujin Kouro"},
|
{"NYK", "J", SAVE_EEPROM_4k, "Yakouchuu II: Satsujin Kouro"},
|
||||||
{"NYS", "EJP", SAVE_EEPROM_16k, "Yoshi's Story"},
|
{"NYS", "EJP", SAVE_EEPROM_16k, "Yoshi's Story"},
|
||||||
{"NYW", "EJ", SAVE_SRAM_256k, "Harvest Moon 64"},
|
{"NYW", "EJ", SAVE_SRAM_256k, "Harvest Moon 64"},
|
||||||
{"NZL", "P", SAVE_SRAM_256k, "Legend of Zelda: Ocarina of Time (PAL)"},
|
{"NZL", "P", SAVE_SRAM_256k, "Legend of Zelda: Ocarina of Time (PAL)"},
|
||||||
{"NZS", "EJP", SAVE_FLASH_1m, "Legend of Zelda: Majora's Mask"},
|
{"NZS", "EJP", SAVE_FLASH_1m, "Legend of Zelda: Majora's Mask"},
|
||||||
};
|
};
|
||||||
}
|
} // namespace n64
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ void Scheduler::HandleEvents() {
|
|||||||
break;
|
break;
|
||||||
case STOP:
|
case STOP:
|
||||||
core.Stop();
|
core.Stop();
|
||||||
core.rom = {};
|
core.romPath = {};
|
||||||
break;
|
break;
|
||||||
case RESET:
|
case RESET:
|
||||||
core.Reset();
|
core.Reset();
|
||||||
|
|||||||
@@ -90,7 +90,10 @@ FORCE_INLINE void SetROMCIC(u32 checksum, ROM &rom) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mem::LoadROM(const bool isArchive, const std::string &filename) {
|
ROM Mem::LoadROM(const bool isArchive, const std::string &filename) {
|
||||||
|
ROM rom;
|
||||||
|
rom.cart.resize(CART_SIZE);
|
||||||
|
std::ranges::fill(rom.cart, 0);
|
||||||
u32 endianness;
|
u32 endianness;
|
||||||
{
|
{
|
||||||
size_t sizeAdjusted;
|
size_t sizeAdjusted;
|
||||||
@@ -133,7 +136,8 @@ void Mem::LoadROM(const bool isArchive, const std::string &filename) {
|
|||||||
SetROMCIC(checksum, rom);
|
SetROMCIC(checksum, rom);
|
||||||
endianness = std::byteswap(ircolib::ReadAccess<u32>(rom.cart, 0));
|
endianness = std::byteswap(ircolib::ReadAccess<u32>(rom.cart, 0));
|
||||||
Util::SwapN64Rom(rom.cart, endianness);
|
Util::SwapN64Rom(rom.cart, endianness);
|
||||||
rom.pal = IsROMPAL();
|
rom.pal = IsROMPAL(rom);
|
||||||
|
return rom;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
@@ -451,7 +455,7 @@ void Mem::Write(const u32 paddr, u64 val) {
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
u32 Mem::BackupRead<u32>(const u32 addr) {
|
u32 Mem::BackupRead<u32>(const u32 addr) {
|
||||||
switch (saveType) {
|
switch (rom.saveType) {
|
||||||
case SAVE_NONE:
|
case SAVE_NONE:
|
||||||
return 0;
|
return 0;
|
||||||
case SAVE_EEPROM_4k:
|
case SAVE_EEPROM_4k:
|
||||||
@@ -469,7 +473,7 @@ u32 Mem::BackupRead<u32>(const u32 addr) {
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
u8 Mem::BackupRead<u8>(const u32 addr) {
|
u8 Mem::BackupRead<u8>(const u32 addr) {
|
||||||
switch (saveType) {
|
switch (rom.saveType) {
|
||||||
case SAVE_NONE:
|
case SAVE_NONE:
|
||||||
return 0;
|
return 0;
|
||||||
case SAVE_EEPROM_4k:
|
case SAVE_EEPROM_4k:
|
||||||
@@ -492,7 +496,7 @@ u8 Mem::BackupRead<u8>(const u32 addr) {
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
void Mem::BackupWrite<u32>(const u32 addr, const u32 val) {
|
void Mem::BackupWrite<u32>(const u32 addr, const u32 val) {
|
||||||
switch (saveType) {
|
switch (rom.saveType) {
|
||||||
case SAVE_NONE:
|
case SAVE_NONE:
|
||||||
warn("Accessing cartridge with save type SAVE_NONE in write word");
|
warn("Accessing cartridge with save type SAVE_NONE in write word");
|
||||||
break;
|
break;
|
||||||
@@ -511,7 +515,7 @@ void Mem::BackupWrite<u32>(const u32 addr, const u32 val) {
|
|||||||
|
|
||||||
template <>
|
template <>
|
||||||
void Mem::BackupWrite<u8>(const u32 addr, const u8 val) {
|
void Mem::BackupWrite<u8>(const u32 addr, const u8 val) {
|
||||||
switch (saveType) {
|
switch (rom.saveType) {
|
||||||
case SAVE_NONE:
|
case SAVE_NONE:
|
||||||
warn("Accessing cartridge with save type SAVE_NONE in write word");
|
warn("Accessing cartridge with save type SAVE_NONE in write word");
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ struct ROM {
|
|||||||
char gameNameCart[20];
|
char gameNameCart[20];
|
||||||
char code[4];
|
char code[4];
|
||||||
ROMHeader header;
|
ROMHeader header;
|
||||||
|
SaveType saveType = SAVE_NONE;
|
||||||
size_t mask;
|
size_t mask;
|
||||||
CICType cicType;
|
CICType cicType;
|
||||||
std::vector<u8> cart;
|
std::vector<u8> cart;
|
||||||
@@ -78,7 +79,7 @@ struct Mem {
|
|||||||
~Mem() = default;
|
~Mem() = default;
|
||||||
void Reset();
|
void Reset();
|
||||||
void LoadSRAM(SaveType, fs::path);
|
void LoadSRAM(SaveType, fs::path);
|
||||||
void LoadROM(bool, const std::string &);
|
static ROM LoadROM(bool, const std::string &);
|
||||||
|
|
||||||
[[nodiscard]] auto GetRDRAMPtr() -> u8 * { return mmio.rdp.rdram.data(); }
|
[[nodiscard]] auto GetRDRAMPtr() -> u8 * { return mmio.rdp.rdram.data(); }
|
||||||
|
|
||||||
@@ -119,7 +120,6 @@ struct Mem {
|
|||||||
|
|
||||||
MMIO mmio;
|
MMIO mmio;
|
||||||
ROM rom;
|
ROM rom;
|
||||||
SaveType saveType = SAVE_NONE;
|
|
||||||
Flash flash;
|
Flash flash;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -135,9 +135,9 @@ struct Mem {
|
|||||||
std::string sramPath{};
|
std::string sramPath{};
|
||||||
mio::mmap_sink saveData{};
|
mio::mmap_sink saveData{};
|
||||||
|
|
||||||
[[nodiscard]] FORCE_INLINE bool IsROMPAL() const {
|
[[nodiscard]] static FORCE_INLINE bool IsROMPAL(ROM &rom) {
|
||||||
static constexpr char pal_codes[] = {'D', 'F', 'I', 'P', 'S', 'U', 'X', 'Y'};
|
static constexpr char pal_codes[] = {'D', 'F', 'I', 'P', 'S', 'U', 'X', 'Y'};
|
||||||
return std::ranges::any_of(pal_codes, [this](char a) { return rom.cart[0x3d] == a; });
|
return std::ranges::any_of(pal_codes, [&rom](char a) { return rom.cart[0x3d] == a; });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace n64
|
} // namespace n64
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ void AI::Write(const u32 addr, const u32 val) {
|
|||||||
{
|
{
|
||||||
const u32 oldDacFreq = dac.freq;
|
const u32 oldDacFreq = dac.freq;
|
||||||
dacRate = val & 0x3FFF;
|
dacRate = val & 0x3FFF;
|
||||||
dac.freq = std::max(1.f, (float)GetVideoFrequency(mem.IsROMPAL()) / (dacRate + 1)) * 1.037;
|
dac.freq = std::max(1.f, (float)GetVideoFrequency(mem.rom.pal) / (dacRate + 1)) * 1.037;
|
||||||
dac.period = GetVideoFrequency(mem.IsROMPAL()) / dac.freq;
|
dac.period = GetVideoFrequency(mem.rom.pal) / dac.freq;
|
||||||
if (oldDacFreq != dac.freq) {
|
if (oldDacFreq != dac.freq) {
|
||||||
device.AdjustSampleRate(dac.freq);
|
device.AdjustSampleRate(dac.freq);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -507,7 +507,7 @@ void PI::DMA<false>() {
|
|||||||
n64::Mem &mem = n64::Core::GetMem();
|
n64::Mem &mem = n64::Core::GetMem();
|
||||||
const s32 len = rdLen + 1;
|
const s32 len = rdLen + 1;
|
||||||
trace("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr);
|
trace("PI DMA from RDRAM to CARTRIDGE (size: {} B, {:08X} to {:08X})", len, dramAddr, cartAddr);
|
||||||
if (mem.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < (CART_REGION_START_2_2 + 1_mb)) {
|
if (mem.rom.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < (CART_REGION_START_2_2 + 1_mb)) {
|
||||||
cartAddr = SREGION_PI_SRAM | ((cartAddr & (1_mb - 1)) << 1);
|
cartAddr = SREGION_PI_SRAM | ((cartAddr & (1_mb - 1)) << 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -535,7 +535,7 @@ void PI::DMA<true>() {
|
|||||||
const s32 len = wrLen + 1;
|
const s32 len = wrLen + 1;
|
||||||
trace("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr);
|
trace("PI DMA from CARTRIDGE to RDRAM (size: {} B, {:08X} to {:08X})", len, cartAddr, dramAddr);
|
||||||
|
|
||||||
if (mem.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < (CART_REGION_START_2_2 + 1_mb)) {
|
if (mem.rom.saveType == SAVE_FLASH_1m && cartAddr >= SREGION_PI_SRAM && cartAddr < (CART_REGION_START_2_2 + 1_mb)) {
|
||||||
cartAddr = SREGION_PI_SRAM | ((cartAddr & (1_mb - 1)) << 1);
|
cartAddr = SREGION_PI_SRAM | ((cartAddr & (1_mb - 1)) << 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -347,10 +347,10 @@ void PIF::MempakWrite(u8 *cmd, u8 *res) {
|
|||||||
|
|
||||||
void PIF::EepromRead(const u8 *cmd, u8 *res) const {
|
void PIF::EepromRead(const u8 *cmd, u8 *res) const {
|
||||||
n64::Mem &mem = n64::Core::GetMem();
|
n64::Mem &mem = n64::Core::GetMem();
|
||||||
assert(mem.saveType == SAVE_EEPROM_4k || mem.saveType == SAVE_EEPROM_16k);
|
assert(mem.rom.saveType == SAVE_EEPROM_4k || mem.rom.saveType == SAVE_EEPROM_16k);
|
||||||
if (channel == 4) {
|
if (channel == 4) {
|
||||||
const u8 offset = cmd[3];
|
const u8 offset = cmd[3];
|
||||||
if ((offset * 8) >= GetSaveSize(mem.saveType)) {
|
if ((offset * 8) >= GetSaveSize(mem.rom.saveType)) {
|
||||||
panic("Out of range EEPROM read! offset: {:02X}", offset);
|
panic("Out of range EEPROM read! offset: {:02X}", offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,10 +362,10 @@ void PIF::EepromRead(const u8 *cmd, u8 *res) const {
|
|||||||
|
|
||||||
void PIF::EepromWrite(const u8 *cmd, u8 *res) {
|
void PIF::EepromWrite(const u8 *cmd, u8 *res) {
|
||||||
n64::Mem &mem = n64::Core::GetMem();
|
n64::Mem &mem = n64::Core::GetMem();
|
||||||
assert(mem.saveType == SAVE_EEPROM_4k || mem.saveType == SAVE_EEPROM_16k);
|
assert(mem.rom.saveType == SAVE_EEPROM_4k || mem.rom.saveType == SAVE_EEPROM_16k);
|
||||||
if (channel == 4) {
|
if (channel == 4) {
|
||||||
const u8 offset = cmd[3];
|
const u8 offset = cmd[3];
|
||||||
if ((offset * 8) >= GetSaveSize(mem.saveType)) {
|
if ((offset * 8) >= GetSaveSize(mem.rom.saveType)) {
|
||||||
panic("Out of range EEPROM write! offset: {:02X}", offset);
|
panic("Out of range EEPROM write! offset: {:02X}", offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+56
-51
@@ -11,43 +11,71 @@
|
|||||||
#include <Options.hpp>
|
#include <Options.hpp>
|
||||||
#include <Scheduler.hpp>
|
#include <Scheduler.hpp>
|
||||||
|
|
||||||
|
void KaizenGui::populateRomsList(const std::string &romsPath) {
|
||||||
|
centralWidget->setCurrentWidget(romPathNotSet);
|
||||||
|
if (!romsPath.empty()) {
|
||||||
|
int i = 0;
|
||||||
|
centralWidget->setCurrentWidget(romsList);
|
||||||
|
|
||||||
|
for (const auto &file : fs::recursive_directory_iterator{romsPath}) {
|
||||||
|
if (!file.is_regular_file())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto filename = file.path().lexically_normal().string();
|
||||||
|
|
||||||
|
bool isPlain = std::ranges::any_of(std::array{".n64", ".z64", ".v64"},
|
||||||
|
[&](const std::string &ext) { return file.path().extension() == ext; });
|
||||||
|
|
||||||
|
bool isArchive =
|
||||||
|
std::ranges::any_of(std::array{".zip", ".7z", ".rar", ".tar"},
|
||||||
|
[&](const std::string &ext) { return file.path().extension() == ext; });
|
||||||
|
|
||||||
|
if (!isArchive && !isPlain)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto rom = n64::Mem::LoadROM(isArchive, filename);
|
||||||
|
auto regions = n64::GameDB::match(rom);
|
||||||
|
|
||||||
|
romsListPaths.push_back(filename);
|
||||||
|
romsList->insertRow(i);
|
||||||
|
romsList->setItem(i, 0, new QTableWidgetItem(core.mem->rom.gameNameDB.c_str()));
|
||||||
|
romsList->setItem(i, 1, new QTableWidgetItem(regions.c_str()));
|
||||||
|
romsList->setItem(i, 2, new QTableWidgetItem("Never"));
|
||||||
|
romsList->setItem(i, 3, new QTableWidgetItem("0h 0m 0s"));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentHomeWidget = centralWidget->currentWidget();
|
||||||
|
}
|
||||||
|
|
||||||
KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::UserScope) {
|
KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::UserScope) {
|
||||||
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
|
SDL_InitSubSystem(SDL_INIT_GAMEPAD);
|
||||||
|
|
||||||
hide();
|
hide();
|
||||||
|
|
||||||
auto romsNotFoundLabel = new QLabel(R"(Kaizen could not find any ROMs. Set the path in "Settings -> General")");
|
|
||||||
|
|
||||||
romsList->verticalHeader()->hide();
|
romsList->verticalHeader()->hide();
|
||||||
|
romsList->setSizePolicy({QSizePolicy::Maximum, QSizePolicy::Maximum});
|
||||||
|
romsList->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||||
romsList->setSelectionBehavior(QAbstractItemView::SelectRows);
|
romsList->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||||
romsList->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
romsList->setEditTriggers(QAbstractItemView::NoEditTriggers);
|
||||||
romsList->setSortingEnabled(true);
|
romsList->setSortingEnabled(true);
|
||||||
romsList->setColumnCount(3);
|
romsList->setColumnCount(4);
|
||||||
romsList->setHorizontalHeaderItem(0, romName);
|
romsList->setHorizontalHeaderItem(0, romName);
|
||||||
romsList->setHorizontalHeaderItem(1, romLastPlayed);
|
romsList->setHorizontalHeaderItem(1, romRegions);
|
||||||
romsList->setHorizontalHeaderItem(2, romTimePlayed);
|
romsList->setHorizontalHeaderItem(2, romLastPlayed);
|
||||||
|
romsList->setHorizontalHeaderItem(3, romTimePlayed);
|
||||||
|
|
||||||
auto romsPath = Options::GetRomsPath();
|
vulkanWidget = new RenderWidget();
|
||||||
if (!romsPath.empty()) {
|
vulkanWidget->hide();
|
||||||
int i = 0;
|
|
||||||
centralWidget->addWidget(romsList);
|
centralWidget->addWidget(vulkanWidget);
|
||||||
for (const auto &file : fs::recursive_directory_iterator{romsPath}) {
|
centralWidget->addWidget(romsList);
|
||||||
if (file.is_regular_file() &&
|
centralWidget->addWidget(romPathNotSet);
|
||||||
std::ranges::any_of(std::array{".n64", ".z64", ".v64"},
|
|
||||||
[&](const std::string &ext) { return file.path().extension() == ext; })) {
|
populateRomsList(Options::GetRomsPath());
|
||||||
romsList->insertRow(i);
|
|
||||||
romsList->setItem(i, 0, new QTableWidgetItem(file.path().stem().string().c_str()));
|
|
||||||
romsList->setItem(i, 1, new QTableWidgetItem("Never"));
|
|
||||||
romsList->setItem(i, 2, new QTableWidgetItem("0h 0m 0s"));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
centralWidget->addWidget(romsNotFoundLabel);
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(romsList, &QTableWidget::cellDoubleClicked, this, [&](int row, int) {
|
connect(romsList, &QTableWidget::cellDoubleClicked, this, [&](int row, int) {
|
||||||
auto fileToLoad = fs::path(romsPath) / romsList->item(row, 0)->text().toStdString();
|
auto fileToLoad = fs::path(Options::GetRomsPath()) / romsListPaths[row];
|
||||||
std::println("{}", fileToLoad.string());
|
std::println("{}", fileToLoad.string());
|
||||||
LoadROM(fileToLoad.string());
|
LoadROM(fileToLoad.string());
|
||||||
});
|
});
|
||||||
@@ -57,11 +85,6 @@ KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::User
|
|||||||
restoreGeometry(settings.value("geometry").toByteArray());
|
restoreGeometry(settings.value("geometry").toByteArray());
|
||||||
restoreState(settings.value("windowState").toByteArray());
|
restoreState(settings.value("windowState").toByteArray());
|
||||||
|
|
||||||
vulkanWidget = new RenderWidget();
|
|
||||||
vulkanWidget->hide();
|
|
||||||
|
|
||||||
centralWidget->addWidget(vulkanWidget);
|
|
||||||
|
|
||||||
cpuTypeLabel = new QLabel("Interpreter");
|
cpuTypeLabel = new QLabel("Interpreter");
|
||||||
if (Options::GetCpuType() == n64::CachedInterpreter)
|
if (Options::GetCpuType() == n64::CachedInterpreter)
|
||||||
cpuTypeLabel->setText("Cached Interpreter");
|
cpuTypeLabel->setText("Cached Interpreter");
|
||||||
@@ -108,7 +131,7 @@ KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::User
|
|||||||
auto open = fileMenu->addAction("Open");
|
auto open = fileMenu->addAction("Open");
|
||||||
open->setShortcut(QKeyCombination(Qt::CTRL, Qt::Key_O));
|
open->setShortcut(QKeyCombination(Qt::CTRL, Qt::Key_O));
|
||||||
connect(open, &QAction::triggered, this, [&] {
|
connect(open, &QAction::triggered, this, [&] {
|
||||||
auto originPath = romsPath.empty() ? QDir::currentPath() : romsPath.c_str();
|
auto originPath = Options::GetRomsPath().empty() ? QDir::currentPath() : Options::GetRomsPath().c_str();
|
||||||
auto fileToLoad =
|
auto fileToLoad =
|
||||||
QFileDialog::getOpenFileName(this, "Select a Nintendo 64 ROM", originPath, "N64 ROM (*.z64 *.n64 *.v64)")
|
QFileDialog::getOpenFileName(this, "Select a Nintendo 64 ROM", originPath, "N64 ROM (*.z64 *.n64 *.v64)")
|
||||||
.toStdString();
|
.toStdString();
|
||||||
@@ -123,26 +146,8 @@ KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::User
|
|||||||
auto settingsMenu = emulationMenu->addAction("Settings");
|
auto settingsMenu = emulationMenu->addAction("Settings");
|
||||||
settingsWindow = new SettingsWindow();
|
settingsWindow = new SettingsWindow();
|
||||||
connect(settingsMenu, &QAction::triggered, settingsWindow, &SettingsWindow::show);
|
connect(settingsMenu, &QAction::triggered, settingsWindow, &SettingsWindow::show);
|
||||||
connect(settingsWindow->general, &GeneralSettings::romFolderSelected, this, [&] {
|
connect(settingsWindow->general, &GeneralSettings::romFolderSelected, this,
|
||||||
romsPath = Options::GetRomsPath();
|
[&] { populateRomsList(Options::GetRomsPath()); });
|
||||||
if (!romsPath.empty()) {
|
|
||||||
int i = 0;
|
|
||||||
centralWidget->addWidget(romsList);
|
|
||||||
for (const auto &file : fs::recursive_directory_iterator{romsPath}) {
|
|
||||||
if (file.is_regular_file() &&
|
|
||||||
std::ranges::any_of(std::array{".n64", ".z64", ".v64"},
|
|
||||||
[&](const std::string &ext) { return file.path().extension() == ext; })) {
|
|
||||||
romsList->insertRow(i);
|
|
||||||
romsList->setItem(i, 0, new QTableWidgetItem(file.path().stem().string().c_str()));
|
|
||||||
romsList->setItem(i, 1, new QTableWidgetItem("Never"));
|
|
||||||
romsList->setItem(i, 2, new QTableWidgetItem("0h 0m 0s"));
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
centralWidget->addWidget(romsNotFoundLabel);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
connect(settingsWindow->cpu, &CPUSettings::cpuTypeChanged, this, [&] {
|
connect(settingsWindow->cpu, &CPUSettings::cpuTypeChanged, this, [&] {
|
||||||
core.cpuType = Options::GetCpuType();
|
core.cpuType = Options::GetCpuType();
|
||||||
@@ -185,7 +190,7 @@ KaizenGui::KaizenGui() noexcept : QMainWindow(nullptr), settings(QSettings::User
|
|||||||
emulationMenu->addAction(stop);
|
emulationMenu->addAction(stop);
|
||||||
connect(stop, &QAction::triggered, this, [&] {
|
connect(stop, &QAction::triggered, this, [&] {
|
||||||
Scheduler::GetInstance().EnqueueRelative(0, STOP);
|
Scheduler::GetInstance().EnqueueRelative(0, STOP);
|
||||||
centralWidget->setCurrentWidget(romsList);
|
centralWidget->setCurrentWidget(currentHomeWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
auto helpMenu = menuBar()->addMenu("Help");
|
auto helpMenu = menuBar()->addMenu("Help");
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ class KaizenGui final : QMainWindow {
|
|||||||
void updateKeys();
|
void updateKeys();
|
||||||
void updateAxis();
|
void updateAxis();
|
||||||
bool eventFilter(QObject *, QEvent *) override;
|
bool eventFilter(QObject *, QEvent *) override;
|
||||||
|
void populateRomsList(const std::string &);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit KaizenGui() noexcept;
|
explicit KaizenGui() noexcept;
|
||||||
@@ -32,8 +33,13 @@ class KaizenGui final : QMainWindow {
|
|||||||
bool fastForward = false;
|
bool fastForward = false;
|
||||||
bool minimized = false;
|
bool minimized = false;
|
||||||
|
|
||||||
|
std::vector<std::string> romsListPaths{};
|
||||||
|
|
||||||
|
QWidget *currentHomeWidget;
|
||||||
|
QLabel *romPathNotSet = new QLabel(R"(Kaizen could not find any ROMs. Set the path in "Settings -> General")");
|
||||||
QTableWidget *romsList = new QTableWidget();
|
QTableWidget *romsList = new QTableWidget();
|
||||||
QTableWidgetItem *romName = new QTableWidgetItem("Name");
|
QTableWidgetItem *romName = new QTableWidgetItem("Name");
|
||||||
|
QTableWidgetItem *romRegions = new QTableWidgetItem("Regions");
|
||||||
QTableWidgetItem *romLastPlayed = new QTableWidgetItem("Last played");
|
QTableWidgetItem *romLastPlayed = new QTableWidgetItem("Last played");
|
||||||
QTableWidgetItem *romTimePlayed = new QTableWidgetItem("Time played");
|
QTableWidgetItem *romTimePlayed = new QTableWidgetItem("Time played");
|
||||||
QStackedWidget *centralWidget = new QStackedWidget();
|
QStackedWidget *centralWidget = new QStackedWidget();
|
||||||
|
|||||||
+44
-15
@@ -7,32 +7,61 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Util {
|
namespace Util {
|
||||||
enum LogLevel : u8 { Trace, Debug, Warn, Info, Error, Always };
|
enum LogLevel : u8 { Trace, Debug, Info, Warn, Error, Always };
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
static constexpr auto globalLogLevel = Debug;
|
static constexpr auto globalLogLevel = Debug;
|
||||||
#else
|
#else
|
||||||
static constexpr auto globalLogLevel = Info;
|
static constexpr auto globalLogLevel = Warn;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <LogLevel messageType = Info, class... Args>
|
template <LogLevel messageType = Info, class... Args>
|
||||||
void print(const std::format_string<Args...> fmt, Args... args) {
|
void print(const std::format_string<Args...> fmt, Args... args) {
|
||||||
if (messageType >= globalLogLevel) {
|
if (messageType >= globalLogLevel) {
|
||||||
if (messageType <= Debug) {
|
if (messageType <= Debug) {
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
std::println(fmt, std::forward<Args>(args)...);
|
std::println(fmt, std::forward<Args>(args)...);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
std::println(fmt, std::forward<Args>(args)...);
|
std::println(fmt, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define panic(fmt, ...) do { Util::print<Util::Error>("[FATAL] " fmt __VA_OPT__(,) __VA_ARGS__); exit(-1); } while(0)
|
#define panic(fmt, ...) \
|
||||||
#define error(fmt, ...) do { Util::print<Util::Error>("[ERROR] " fmt __VA_OPT__(,) __VA_ARGS__); } while(0)
|
do { \
|
||||||
#define warn(fmt, ...) do { Util::print<Util::Warn>("[WARN] " fmt __VA_OPT__(,) __VA_ARGS__); } while(0)
|
Util::print<Util::Error>("[FATAL] " fmt __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
#define info(fmt, ...) do { Util::print<Util::Info>("[INFO] " fmt __VA_OPT__(,) __VA_ARGS__); } while(0)
|
exit(-1); \
|
||||||
#define debug(fmt, ...) do { Util::print<Util::Debug>("[DEBUG] " fmt __VA_OPT__(,) __VA_ARGS__); } while(0)
|
} \
|
||||||
#define trace(fmt, ...) do { Util::print<Util::Trace>("[TRACE] " fmt __VA_OPT__(,) __VA_ARGS__); } while(0)
|
while (0)
|
||||||
#define always(fmt, ...) do { Util::print<Util::Always>(fmt __VA_OPT__(,) __VA_ARGS__); } while(0)
|
#define error(fmt, ...) \
|
||||||
|
do { \
|
||||||
|
Util::print<Util::Error>("[ERROR] " fmt __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
#define warn(fmt, ...) \
|
||||||
|
do { \
|
||||||
|
Util::print<Util::Warn>("[WARN] " fmt __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
#define info(fmt, ...) \
|
||||||
|
do { \
|
||||||
|
Util::print<Util::Info>("[INFO] " fmt __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
#define debug(fmt, ...) \
|
||||||
|
do { \
|
||||||
|
Util::print<Util::Debug>("[DEBUG] " fmt __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
#define trace(fmt, ...) \
|
||||||
|
do { \
|
||||||
|
Util::print<Util::Trace>("[TRACE] " fmt __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
|
#define always(fmt, ...) \
|
||||||
|
do { \
|
||||||
|
Util::print<Util::Always>(fmt __VA_OPT__(, ) __VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
while (0)
|
||||||
} // namespace Util
|
} // namespace Util
|
||||||
|
|||||||
Reference in New Issue
Block a user