Headerless rom support (when found in built-in game database)
This commit is contained in:
parent
5fc0df4155
commit
4d96c13334
7 changed files with 107 additions and 29 deletions
|
@ -226,6 +226,76 @@ uint8_t GameDatabase::GetSubMapper(GameInfo &info)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GameDatabase::GetiNesHeader(uint32_t romCrc, NESHeader &nesHeader)
|
||||||
|
{
|
||||||
|
GameInfo info = {};
|
||||||
|
InitDatabase();
|
||||||
|
auto result = _gameDatabase.find(romCrc);
|
||||||
|
if(result != _gameDatabase.end()) {
|
||||||
|
MessageManager::Log("[DB] Headerless ROM file found - using game database data.");
|
||||||
|
|
||||||
|
info = result->second;
|
||||||
|
|
||||||
|
nesHeader.Byte9 = 0;
|
||||||
|
if(info.PrgRomSize > 4096) {
|
||||||
|
uint16_t prgSize = info.PrgRomSize / 16;
|
||||||
|
nesHeader.PrgCount = prgSize & 0xFF;
|
||||||
|
nesHeader.Byte9 |= (prgSize & 0xF00) >> 8;
|
||||||
|
} else {
|
||||||
|
nesHeader.PrgCount = info.PrgRomSize / 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(info.ChrRomSize > 2048) {
|
||||||
|
uint16_t chrSize = info.ChrRomSize / 8;
|
||||||
|
nesHeader.ChrCount = chrSize & 0xFF;
|
||||||
|
nesHeader.Byte9 |= (chrSize & 0xF00) >> 4;
|
||||||
|
} else {
|
||||||
|
nesHeader.ChrCount = info.ChrRomSize / 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
nesHeader.Byte6 = (info.MapperID & 0x0F) << 4;
|
||||||
|
if(info.HasBattery) {
|
||||||
|
nesHeader.Byte6 |= 0x02;
|
||||||
|
}
|
||||||
|
if(info.Mirroring.compare("v") == 0) {
|
||||||
|
nesHeader.Byte6 |= 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
nesHeader.Byte7 = (info.MapperID & 0xF0);
|
||||||
|
GameSystem system = GetGameSystem(info.System);
|
||||||
|
if(system == GameSystem::Playchoice) {
|
||||||
|
nesHeader.Byte7 |= 0x02;
|
||||||
|
} else if(system == GameSystem::VsUniSystem) {
|
||||||
|
nesHeader.Byte7 |= 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Don't set this, otherwise the header will be used over the game DB data
|
||||||
|
//nesHeader.Byte7 |= 0x08; //NES 2.0 marker
|
||||||
|
|
||||||
|
nesHeader.Byte8 = ((GetSubMapper(info) & 0x0F) << 4) | ((info.MapperID & 0xF00) >> 8);
|
||||||
|
|
||||||
|
nesHeader.Byte10 = 0;
|
||||||
|
if(info.SaveRamSize > 0) {
|
||||||
|
nesHeader.Byte10 |= ((int)log2(info.SaveRamSize * 1024) - 6) << 4;
|
||||||
|
}
|
||||||
|
if(info.WorkRamSize > 0) {
|
||||||
|
nesHeader.Byte10 |= ((int)log2(info.WorkRamSize * 1024) - 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
nesHeader.Byte11 = 0;
|
||||||
|
if(info.ChrRamSize > 0) {
|
||||||
|
nesHeader.Byte11 |= ((int)log2(info.ChrRamSize * 1024) - 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
nesHeader.Byte12 = system == GameSystem::NesPal ? 0x01 : 0;
|
||||||
|
nesHeader.Byte13 = 0; //VS PPU variant
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void GameDatabase::SetGameInfo(uint32_t romCrc, RomData &romData, bool updateRomData)
|
void GameDatabase::SetGameInfo(uint32_t romCrc, RomData &romData, bool updateRomData)
|
||||||
{
|
{
|
||||||
GameInfo info = {};
|
GameInfo info = {};
|
||||||
|
|
|
@ -20,4 +20,5 @@ private:
|
||||||
public:
|
public:
|
||||||
static void InitializeInputDevices(string inputType, GameSystem system);
|
static void InitializeInputDevices(string inputType, GameSystem system);
|
||||||
static void SetGameInfo(uint32_t romCrc, RomData &romData, bool updateRomData);
|
static void SetGameInfo(uint32_t romCrc, RomData &romData, bool updateRomData);
|
||||||
|
static bool GetiNesHeader(uint32_t romCrc, NESHeader &nesHeader);
|
||||||
};
|
};
|
|
@ -69,16 +69,6 @@ struct NESHeader
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t GetPrgCount()
|
|
||||||
{
|
|
||||||
if(PrgCount == 0) {
|
|
||||||
//0 prg banks is a special value meaning 256 banks
|
|
||||||
return 256;
|
|
||||||
} else {
|
|
||||||
return PrgCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HasBattery()
|
bool HasBattery()
|
||||||
{
|
{
|
||||||
return (Byte6 & 0x02) == 0x02;
|
return (Byte6 & 0x02) == 0x02;
|
||||||
|
@ -130,9 +120,13 @@ struct NESHeader
|
||||||
uint32_t GetPrgSize()
|
uint32_t GetPrgSize()
|
||||||
{
|
{
|
||||||
if(GetRomHeaderVersion() == RomHeaderVersion::Nes2_0) {
|
if(GetRomHeaderVersion() == RomHeaderVersion::Nes2_0) {
|
||||||
return (((Byte9 & 0x0F) << 4) | GetPrgCount()) * 0x4000;
|
return (((Byte9 & 0x0F) << 4) | PrgCount) * 0x4000;
|
||||||
} else {
|
} else {
|
||||||
return GetPrgCount() * 0x4000;
|
if(PrgCount == 0) {
|
||||||
|
return 256 * 0x4000; //0 is a special value and means 256
|
||||||
|
} else {
|
||||||
|
return PrgCount * 0x4000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,16 +199,18 @@ struct NESHeader
|
||||||
|
|
||||||
void SanitizeHeader(size_t romLength)
|
void SanitizeHeader(size_t romLength)
|
||||||
{
|
{
|
||||||
size_t calculatedLength = sizeof(NESHeader) + 0x4000 * GetPrgCount();
|
size_t calculatedLength = sizeof(NESHeader) + GetPrgSize();
|
||||||
while(calculatedLength > romLength) {
|
while(calculatedLength > romLength) {
|
||||||
|
Byte9 = 0;
|
||||||
PrgCount--;
|
PrgCount--;
|
||||||
calculatedLength = sizeof(NESHeader) + 0x4000 * GetPrgCount();
|
calculatedLength = sizeof(NESHeader) + GetPrgSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
calculatedLength = sizeof(NESHeader) + 0x4000 * GetPrgCount() + 0x2000 * ChrCount;
|
calculatedLength = sizeof(NESHeader) + GetPrgSize() + GetChrSize();
|
||||||
while(calculatedLength > romLength) {
|
while(calculatedLength > romLength) {
|
||||||
|
Byte9 = 0;
|
||||||
ChrCount--;
|
ChrCount--;
|
||||||
calculatedLength = sizeof(NESHeader) + 0x4000 * GetPrgCount() + 0x2000 * ChrCount;
|
calculatedLength = sizeof(NESHeader) + GetPrgSize() + GetChrSize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -252,7 +248,7 @@ struct GameInfo
|
||||||
string Board;
|
string Board;
|
||||||
string Pcb;
|
string Pcb;
|
||||||
string Chip;
|
string Chip;
|
||||||
uint8_t MapperID;
|
uint16_t MapperID;
|
||||||
uint32_t PrgRomSize;
|
uint32_t PrgRomSize;
|
||||||
uint32_t ChrRomSize;
|
uint32_t ChrRomSize;
|
||||||
uint32_t ChrRamSize;
|
uint32_t ChrRamSize;
|
||||||
|
|
|
@ -113,7 +113,7 @@ bool RomLoader::LoadFromMemory(uint8_t* buffer, size_t length, string romName)
|
||||||
|
|
||||||
if(memcmp(buffer, "NES\x1a", 4) == 0) {
|
if(memcmp(buffer, "NES\x1a", 4) == 0) {
|
||||||
iNesLoader loader;
|
iNesLoader loader;
|
||||||
_romData = loader.LoadRom(fileData);
|
_romData = loader.LoadRom(fileData, nullptr);
|
||||||
} else if(memcmp(buffer, "FDS\x1a", 4) == 0 || memcmp(buffer, "\x1*NINTENDO-HVC*", 15) == 0) {
|
} else if(memcmp(buffer, "FDS\x1a", 4) == 0 || memcmp(buffer, "\x1*NINTENDO-HVC*", 15) == 0) {
|
||||||
FdsLoader loader;
|
FdsLoader loader;
|
||||||
_romData = loader.LoadRom(fileData, _filename);
|
_romData = loader.LoadRom(fileData, _filename);
|
||||||
|
@ -127,8 +127,14 @@ bool RomLoader::LoadFromMemory(uint8_t* buffer, size_t length, string romName)
|
||||||
UnifLoader loader;
|
UnifLoader loader;
|
||||||
_romData = loader.LoadRom(fileData);
|
_romData = loader.LoadRom(fileData);
|
||||||
} else {
|
} else {
|
||||||
MessageManager::Log("Invalid rom file.");
|
NESHeader header = { };
|
||||||
_romData.Error = true;
|
if(GameDatabase::GetiNesHeader(crc, header)) {
|
||||||
|
iNesLoader loader;
|
||||||
|
_romData = loader.LoadRom(fileData, &header);
|
||||||
|
} else {
|
||||||
|
MessageManager::Log("Invalid rom file.");
|
||||||
|
_romData.Error = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_romData.Crc32 = crc;
|
_romData.Crc32 = crc;
|
||||||
|
@ -175,7 +181,7 @@ bool RomLoader::LoadFile(string filename, istream *filestream, string ipsFilenam
|
||||||
} else if(memcmp(header, "7z", 2) == 0) {
|
} else if(memcmp(header, "7z", 2) == 0) {
|
||||||
SZReader reader;
|
SZReader reader;
|
||||||
return LoadFromArchive(*input, reader, archiveFileIndex);
|
return LoadFromArchive(*input, reader, archiveFileIndex);
|
||||||
} else if(memcmp(header, "NES\x1a", 4) == 0 || memcmp(header, "NESM\x1a", 5) == 0 || memcmp(header, "NSFE", 4) == 0 || memcmp(header, "FDS\x1a", 4) == 0 || memcmp(header, "\x1*NINTENDO-HVC*", 15) == 0 || memcmp(header, "UNIF", 4) == 0) {
|
} else {
|
||||||
if(archiveFileIndex > 0) {
|
if(archiveFileIndex > 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,20 @@
|
||||||
#include "GameDatabase.h"
|
#include "GameDatabase.h"
|
||||||
#include "EmulationSettings.h"
|
#include "EmulationSettings.h"
|
||||||
|
|
||||||
RomData iNesLoader::LoadRom(vector<uint8_t>& romFile)
|
RomData iNesLoader::LoadRom(vector<uint8_t>& romFile, NESHeader *preloadedHeader)
|
||||||
{
|
{
|
||||||
RomData romData;
|
RomData romData;
|
||||||
|
|
||||||
uint8_t* buffer = romFile.data();
|
|
||||||
NESHeader header;
|
NESHeader header;
|
||||||
memcpy((char*)&header, buffer, sizeof(NESHeader));
|
uint8_t* buffer = romFile.data();
|
||||||
buffer += sizeof(NESHeader);
|
if(preloadedHeader) {
|
||||||
|
header = *preloadedHeader;
|
||||||
header.SanitizeHeader(romFile.size());
|
header.SanitizeHeader(romFile.size() + sizeof(NESHeader));
|
||||||
|
} else {
|
||||||
|
memcpy((char*)&header, buffer, sizeof(NESHeader));
|
||||||
|
buffer += sizeof(NESHeader);
|
||||||
|
header.SanitizeHeader(romFile.size());
|
||||||
|
}
|
||||||
|
|
||||||
romData.Format = RomFormat::iNes;
|
romData.Format = RomFormat::iNes;
|
||||||
|
|
||||||
|
|
|
@ -5,5 +5,5 @@
|
||||||
class iNesLoader
|
class iNesLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RomData LoadRom(vector<uint8_t>& romFile);
|
RomData LoadRom(vector<uint8_t>& romFile, NESHeader *preloadedHeader);
|
||||||
};
|
};
|
|
@ -4,7 +4,7 @@
|
||||||
#
|
#
|
||||||
# Automatically generated database based on Nestopia's DB and NesCartDB
|
# Automatically generated database based on Nestopia's DB and NesCartDB
|
||||||
#
|
#
|
||||||
# Generated on 22/02/2017 using:
|
# Generated on 18/03/2017 using:
|
||||||
# -NesCartDB (dated 2016-08-20)
|
# -NesCartDB (dated 2016-08-20)
|
||||||
# -Nestopia UE's latest DB (dated 2015-10-22)
|
# -Nestopia UE's latest DB (dated 2015-10-22)
|
||||||
#
|
#
|
||||||
|
@ -177,6 +177,7 @@
|
||||||
0DC53188,Famicom,HVC-SGROM,HVC-SGROM-03,MMC1A,1,256,,8,0,0,0,,
|
0DC53188,Famicom,HVC-SGROM,HVC-SGROM-03,MMC1A,1,256,,8,0,0,0,,
|
||||||
0E1683C5,Famicom,TAITO-X1-005,P3-034A,X1-005,80,128,128,,0,0,1,,
|
0E1683C5,Famicom,TAITO-X1-005,P3-034A,X1-005,80,128,128,,0,0,1,,
|
||||||
0E197A5E,Famicom,,,,0,32,8,,0,0,0,h,
|
0E197A5E,Famicom,,,,0,32,8,,0,0,0,h,
|
||||||
|
0E76E4C1,Famicom,,,,190,256,128,,0,0,0,,
|
||||||
0E997CF6,Famicom,HVC-SNROM,HVC-SNROM-08,MMC1B2,1,256,,8,0,8,1,,
|
0E997CF6,Famicom,HVC-SNROM,HVC-SNROM-08,MMC1B2,1,256,,8,0,8,1,,
|
||||||
0EAA7515,Famicom,,,,2,128,,8,0,0,0,v,
|
0EAA7515,Famicom,,,,2,128,,8,0,0,0,v,
|
||||||
0EC6C023,NesNtsc,NES-EKROM,NES-EKROM-01,MMC5,5,256,256,,0,8,1,,
|
0EC6C023,NesNtsc,NES-EKROM,NES-EKROM-01,MMC5,5,256,256,,0,8,1,,
|
||||||
|
|
Loading…
Add table
Reference in a new issue