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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
GameInfo info = {};
|
||||
|
|
|
@ -20,4 +20,5 @@ private:
|
|||
public:
|
||||
static void InitializeInputDevices(string inputType, GameSystem system);
|
||||
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()
|
||||
{
|
||||
return (Byte6 & 0x02) == 0x02;
|
||||
|
@ -130,9 +120,13 @@ struct NESHeader
|
|||
uint32_t GetPrgSize()
|
||||
{
|
||||
if(GetRomHeaderVersion() == RomHeaderVersion::Nes2_0) {
|
||||
return (((Byte9 & 0x0F) << 4) | GetPrgCount()) * 0x4000;
|
||||
return (((Byte9 & 0x0F) << 4) | PrgCount) * 0x4000;
|
||||
} 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)
|
||||
{
|
||||
size_t calculatedLength = sizeof(NESHeader) + 0x4000 * GetPrgCount();
|
||||
size_t calculatedLength = sizeof(NESHeader) + GetPrgSize();
|
||||
while(calculatedLength > romLength) {
|
||||
Byte9 = 0;
|
||||
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) {
|
||||
Byte9 = 0;
|
||||
ChrCount--;
|
||||
calculatedLength = sizeof(NESHeader) + 0x4000 * GetPrgCount() + 0x2000 * ChrCount;
|
||||
calculatedLength = sizeof(NESHeader) + GetPrgSize() + GetChrSize();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -252,7 +248,7 @@ struct GameInfo
|
|||
string Board;
|
||||
string Pcb;
|
||||
string Chip;
|
||||
uint8_t MapperID;
|
||||
uint16_t MapperID;
|
||||
uint32_t PrgRomSize;
|
||||
uint32_t ChrRomSize;
|
||||
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) {
|
||||
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) {
|
||||
FdsLoader loader;
|
||||
_romData = loader.LoadRom(fileData, _filename);
|
||||
|
@ -127,8 +127,14 @@ bool RomLoader::LoadFromMemory(uint8_t* buffer, size_t length, string romName)
|
|||
UnifLoader loader;
|
||||
_romData = loader.LoadRom(fileData);
|
||||
} else {
|
||||
MessageManager::Log("Invalid rom file.");
|
||||
_romData.Error = true;
|
||||
NESHeader header = { };
|
||||
if(GameDatabase::GetiNesHeader(crc, header)) {
|
||||
iNesLoader loader;
|
||||
_romData = loader.LoadRom(fileData, &header);
|
||||
} else {
|
||||
MessageManager::Log("Invalid rom file.");
|
||||
_romData.Error = true;
|
||||
}
|
||||
}
|
||||
|
||||
_romData.Crc32 = crc;
|
||||
|
@ -175,7 +181,7 @@ bool RomLoader::LoadFile(string filename, istream *filestream, string ipsFilenam
|
|||
} else if(memcmp(header, "7z", 2) == 0) {
|
||||
SZReader reader;
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -4,16 +4,20 @@
|
|||
#include "GameDatabase.h"
|
||||
#include "EmulationSettings.h"
|
||||
|
||||
RomData iNesLoader::LoadRom(vector<uint8_t>& romFile)
|
||||
RomData iNesLoader::LoadRom(vector<uint8_t>& romFile, NESHeader *preloadedHeader)
|
||||
{
|
||||
RomData romData;
|
||||
|
||||
uint8_t* buffer = romFile.data();
|
||||
NESHeader header;
|
||||
memcpy((char*)&header, buffer, sizeof(NESHeader));
|
||||
buffer += sizeof(NESHeader);
|
||||
|
||||
header.SanitizeHeader(romFile.size());
|
||||
uint8_t* buffer = romFile.data();
|
||||
if(preloadedHeader) {
|
||||
header = *preloadedHeader;
|
||||
header.SanitizeHeader(romFile.size() + sizeof(NESHeader));
|
||||
} else {
|
||||
memcpy((char*)&header, buffer, sizeof(NESHeader));
|
||||
buffer += sizeof(NESHeader);
|
||||
header.SanitizeHeader(romFile.size());
|
||||
}
|
||||
|
||||
romData.Format = RomFormat::iNes;
|
||||
|
||||
|
|
|
@ -5,5 +5,5 @@
|
|||
class iNesLoader
|
||||
{
|
||||
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
|
||||
#
|
||||
# Generated on 22/02/2017 using:
|
||||
# Generated on 18/03/2017 using:
|
||||
# -NesCartDB (dated 2016-08-20)
|
||||
# -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,,
|
||||
0E1683C5,Famicom,TAITO-X1-005,P3-034A,X1-005,80,128,128,,0,0,1,,
|
||||
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,,
|
||||
0EAA7515,Famicom,,,,2,128,,8,0,0,0,v,
|
||||
0EC6C023,NesNtsc,NES-EKROM,NES-EKROM-01,MMC5,5,256,256,,0,8,1,,
|
||||
|
|
Loading…
Add table
Reference in a new issue