Add ability to load a ROM from a byte array instead of a file.
This commit is contained in:
parent
d0b31758fc
commit
e34c8fd52c
|
@ -401,21 +401,8 @@ void GameInfo::populate()
|
|||
}*/
|
||||
}
|
||||
|
||||
bool GameInfo::loadROM(std::string fname, u32 type)
|
||||
bool GameInfo::loadROM(u32 type)
|
||||
{
|
||||
//printf("ROM %s\n", CommonSettings.loadToMemory?"loaded to RAM":"stream from disk");
|
||||
|
||||
closeROM();
|
||||
|
||||
char *noext = strdup(fname.c_str());
|
||||
reader = ROMReaderInit(&noext); free(noext);
|
||||
fROM = reader->Init(fname.c_str());
|
||||
if (!fROM) return false;
|
||||
|
||||
headerOffset = (type == ROM_DSGBA)?DSGBA_LOADER_SIZE:0;
|
||||
romsize = reader->Size(fROM) - headerOffset;
|
||||
reader->Seek(fROM, headerOffset, SEEK_SET);
|
||||
|
||||
bool res = (reader->Read(fROM, &header, sizeof(header)) == sizeof(header));
|
||||
|
||||
if (res)
|
||||
|
@ -511,31 +498,6 @@ bool GameInfo::loadROM(std::string fname, u32 type)
|
|||
reader->Read(fROM, &secureArea[0], 0x4000);
|
||||
}
|
||||
|
||||
//for now, we have to do this, because the DLDI patching requires it
|
||||
bool loadToMemory = CommonSettings.loadToMemory;
|
||||
if(isHomebrew())
|
||||
loadToMemory = true;
|
||||
|
||||
//convert to an in-memory reader around a pre-read buffer if that's what's requested
|
||||
if (loadToMemory)
|
||||
{
|
||||
reader->Seek(fROM, headerOffset, SEEK_SET);
|
||||
|
||||
romdataForReader = new u8[romsize];
|
||||
if (reader->Read(fROM, romdataForReader, romsize) != romsize)
|
||||
{
|
||||
delete [] romdataForReader; romdataForReader = NULL;
|
||||
romsize = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
reader->DeInit(fROM);
|
||||
fROM = NULL;
|
||||
reader = MemROMReaderRead_TrueInit(romdataForReader, romsize);
|
||||
fROM = reader->Init(NULL);
|
||||
}
|
||||
|
||||
if (hasRomBanner())
|
||||
{
|
||||
reader->Seek(fROM, header.IconOff, SEEK_SET);
|
||||
|
@ -571,6 +533,63 @@ bool GameInfo::loadROM(std::string fname, u32 type)
|
|||
romsize = 0;
|
||||
reader->DeInit(fROM); fROM = NULL;
|
||||
return false;
|
||||
|
||||
}
|
||||
bool GameInfo::loadROM(std::string fname, u32 type)
|
||||
{
|
||||
//printf("ROM %s\n", CommonSettings.loadToMemory?"loaded to RAM":"stream from disk");
|
||||
|
||||
closeROM();
|
||||
|
||||
char *noext = strdup(fname.c_str());
|
||||
reader = ROMReaderInit(&noext); free(noext);
|
||||
fROM = reader->Init(fname.c_str());
|
||||
if (!fROM) return false;
|
||||
|
||||
headerOffset = (type == ROM_DSGBA) ? DSGBA_LOADER_SIZE : 0;
|
||||
romsize = reader->Size(fROM) - headerOffset;
|
||||
reader->Seek(fROM, headerOffset, SEEK_SET);
|
||||
|
||||
//for now, we have to do this, because the DLDI patching requires it
|
||||
bool loadToMemory = CommonSettings.loadToMemory;
|
||||
if (isHomebrew())
|
||||
loadToMemory = true;
|
||||
|
||||
//convert to an in-memory reader around a pre-read buffer if that's what's requested
|
||||
if (loadToMemory)
|
||||
{
|
||||
reader->Seek(fROM, headerOffset, SEEK_SET);
|
||||
|
||||
romdataForReader = new u8[romsize];
|
||||
if (reader->Read(fROM, romdataForReader, romsize) != romsize)
|
||||
{
|
||||
delete[] romdataForReader; romdataForReader = NULL;
|
||||
romsize = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
reader->DeInit(fROM);
|
||||
fROM = NULL;
|
||||
reader = MemROMReaderRead_TrueInit(romdataForReader, romsize);
|
||||
fROM = reader->Init(NULL);
|
||||
}
|
||||
|
||||
return loadROM(type);
|
||||
}
|
||||
bool GameInfo::loadROM(u8* file, s32 fileSize)
|
||||
{
|
||||
closeROM();
|
||||
|
||||
// create memory stream
|
||||
reader = MemROMReaderRead_TrueInit(file, fileSize);
|
||||
fROM = reader->Init(NULL);
|
||||
|
||||
headerOffset = 0;
|
||||
romsize = reader->Size(fROM) - headerOffset;
|
||||
reader->Seek(fROM, headerOffset, SEEK_SET);
|
||||
|
||||
return loadROM(ROM_NDS);
|
||||
}
|
||||
|
||||
void GameInfo::closeROM()
|
||||
|
@ -667,45 +686,17 @@ struct LastRom {
|
|||
std::string filename, physicalName, logicalFilename;
|
||||
} lastRom;
|
||||
|
||||
int NDS_LoadROM(const char *filename, const char *physicalName, const char *logicalFilename)
|
||||
void LoadGameInfo()
|
||||
{
|
||||
lastRom.filename = filename;
|
||||
lastRom.physicalName = physicalName ? physicalName : "";
|
||||
lastRom.logicalFilename = logicalFilename ? logicalFilename : "";
|
||||
|
||||
int ret;
|
||||
char buf[MAX_PATH];
|
||||
|
||||
if (filename == NULL)
|
||||
return -1;
|
||||
|
||||
ret = rom_init_path(filename, physicalName, logicalFilename);
|
||||
if (ret < 1)
|
||||
return ret;
|
||||
|
||||
if (cheatSearch)
|
||||
cheatSearch->close();
|
||||
FCEUI_StopMovie();
|
||||
|
||||
if (!gameInfo.ValidateHeader())
|
||||
{
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
gameInfo.populate();
|
||||
|
||||
//run crc over the whole buffer (chunk at a time, to avoid coding a streaming crc
|
||||
gameInfo.reader->Seek(gameInfo.fROM, 0, SEEK_SET);
|
||||
gameInfo.crc = 0;
|
||||
bool first = true;
|
||||
for (;;) {
|
||||
u8 buf[4096];
|
||||
int read = gameInfo.reader->Read(gameInfo.fROM, buf, 4096);
|
||||
if (read == 0) break;
|
||||
if(first && read >= 512)
|
||||
gameInfo.crcForCheatsDb = ~crc32(0, buf, 512);
|
||||
first = false;
|
||||
gameInfo.crc = crc32(gameInfo.crc, buf, read);
|
||||
}
|
||||
|
||||
|
@ -743,6 +734,43 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
|
|||
const char *makerName = Database::MakerNameForMakerCode(gameInfo.header.makerCode, true);
|
||||
INFO("ROM developer: %s\n", ((gameInfo.header.makerCode == 0) && gameInfo.isHomebrew()) ? "Homebrew" : makerName);
|
||||
|
||||
//for homebrew, try auto-patching DLDI. should be benign if there is no DLDI or if it fails
|
||||
if (gameInfo.isHomebrew())
|
||||
{
|
||||
//note: gameInfo.romdataForReader is safe here because we made sure to load the rom into memory for isHomebrew
|
||||
if (slot1_GetCurrentType() == NDS_SLOT1_R4)
|
||||
DLDI::tryPatch((void*)gameInfo.romdataForReader, gameInfo.romsize, 1);
|
||||
else if (slot2_GetCurrentType() == NDS_SLOT2_CFLASH)
|
||||
DLDI::tryPatch((void*)gameInfo.romdataForReader, gameInfo.romsize, 0);
|
||||
}
|
||||
}
|
||||
int NDS_LoadROM(const char *filename, const char *physicalName, const char *logicalFilename)
|
||||
{
|
||||
lastRom.filename = filename;
|
||||
lastRom.physicalName = physicalName ? physicalName : "";
|
||||
lastRom.logicalFilename = logicalFilename ? logicalFilename : "";
|
||||
|
||||
int ret;
|
||||
char buf[MAX_PATH];
|
||||
|
||||
if (filename == NULL)
|
||||
return -1;
|
||||
|
||||
ret = rom_init_path(filename, physicalName, logicalFilename);
|
||||
if (ret < 1)
|
||||
return ret;
|
||||
|
||||
if (cheatSearch)
|
||||
cheatSearch->close();
|
||||
FCEUI_StopMovie();
|
||||
|
||||
if (!gameInfo.ValidateHeader())
|
||||
{
|
||||
ret = -1;
|
||||
return ret;
|
||||
}
|
||||
LoadGameInfo();
|
||||
|
||||
buf[0] = gameInfo.header.gameCode[0];
|
||||
buf[1] = gameInfo.header.gameCode[1];
|
||||
buf[2] = gameInfo.header.gameCode[2];
|
||||
|
@ -769,16 +797,6 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
|
|||
}
|
||||
printf("\n");
|
||||
|
||||
//for homebrew, try auto-patching DLDI. should be benign if there is no DLDI or if it fails
|
||||
if(gameInfo.isHomebrew())
|
||||
{
|
||||
//note: gameInfo.romdataForReader is safe here because we made sure to load the rom into memory for isHomebrew
|
||||
if (slot1_GetCurrentType() == NDS_SLOT1_R4)
|
||||
DLDI::tryPatch((void*)gameInfo.romdataForReader, gameInfo.romsize, 1);
|
||||
else if (slot2_GetCurrentType() == NDS_SLOT2_CFLASH)
|
||||
DLDI::tryPatch((void*)gameInfo.romdataForReader, gameInfo.romsize, 0);
|
||||
}
|
||||
|
||||
if (cheats != NULL)
|
||||
{
|
||||
memset(buf, 0, MAX_PATH);
|
||||
|
@ -792,6 +810,20 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
|
|||
|
||||
return ret;
|
||||
}
|
||||
int NDS_LoadROM(u8* file, int fileSize)
|
||||
{
|
||||
gameInfo.loadROM(file, fileSize);
|
||||
gameInfo.romType = ROM_NDS;
|
||||
|
||||
if (!gameInfo.ValidateHeader())
|
||||
return -1;
|
||||
// I'm not sure all this is necessary/wanted here.
|
||||
LoadGameInfo();
|
||||
|
||||
NDS_Reset();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void NDS_FreeROM(void)
|
||||
{
|
||||
|
|
|
@ -373,6 +373,8 @@ struct GameInfo
|
|||
bool IsCode(const char* code) const;
|
||||
|
||||
bool loadROM(std::string fname, u32 type = ROM_NDS);
|
||||
bool loadROM(u8* file, s32 fileSize);
|
||||
bool loadROM(u32 type);
|
||||
void closeROM();
|
||||
u32 readROM(u32 pos);
|
||||
bool ValidateHeader();
|
||||
|
@ -465,6 +467,7 @@ void NDS_suspendProcessingInput(bool suspend);
|
|||
|
||||
|
||||
int NDS_LoadROM(const char *filename, const char* physicalFilename=0, const char* logicalFilename=0);
|
||||
int NDS_LoadROM(u8* file, int fileSize);
|
||||
void NDS_FreeROM(void);
|
||||
void NDS_Reset();
|
||||
|
||||
|
|
|
@ -65,3 +65,8 @@ DLL int GetFrameCount()
|
|||
{
|
||||
return currFrameCounter;
|
||||
}
|
||||
|
||||
DLL bool LoadROM(u8* file, int fileSize)
|
||||
{
|
||||
return (NDS_LoadROM(file, fileSize) > 0);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue