take a stab at fixing the ram/streaming option so that there arent split codepaths everywhere. homebrew that is eligible for DLDI patching now switches entirely to load from memory, because we lack the facilities to patch the DLDI in flight (although we now have a point to hook it into). really, all this code should be torched, but it's less of a mess now.
This commit is contained in:
parent
e332e3df26
commit
c365617ff7
|
@ -505,36 +505,45 @@ bool GameInfo::loadROM(std::string fname, u32 type)
|
|||
reader->Read(fROM, &secureArea[0], 0x4000);
|
||||
}
|
||||
|
||||
if (CommonSettings.loadToMemory)
|
||||
//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);
|
||||
|
||||
romdata = new u8[romsize + 4];
|
||||
if (reader->Read(fROM, romdata, romsize) != romsize)
|
||||
romdataForReader = new u8[romsize];
|
||||
if (reader->Read(fROM, romdataForReader, romsize) != romsize)
|
||||
{
|
||||
delete [] romdata; romdata = NULL;
|
||||
delete [] romdataForReader; romdataForReader = NULL;
|
||||
romsize = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(hasRomBanner())
|
||||
{
|
||||
memcpy(&banner, romdata + header.IconOff, sizeof(RomBanner));
|
||||
|
||||
banner.version = LE_TO_LOCAL_16(banner.version);
|
||||
banner.crc16 = LE_TO_LOCAL_16(banner.crc16);
|
||||
|
||||
for(size_t i = 0; i < ARRAY_SIZE(banner.palette); i++)
|
||||
{
|
||||
banner.palette[i] = LE_TO_LOCAL_16(banner.palette[i]);
|
||||
}
|
||||
}
|
||||
|
||||
_isDSiEnhanced = (LE_TO_LOCAL_32(*(u32*)(romdata + 0x180) == 0x8D898581U) && LE_TO_LOCAL_32(*(u32*)(romdata + 0x184) == 0x8C888480U));
|
||||
reader->DeInit(fROM); fROM = NULL;
|
||||
return true;
|
||||
reader->DeInit(fROM);
|
||||
fROM = NULL;
|
||||
reader = MemROMReaderRead_TrueInit(romdataForReader, romsize);
|
||||
fROM = reader->Init(NULL);
|
||||
}
|
||||
|
||||
if(hasRomBanner())
|
||||
{
|
||||
reader->Seek(fROM, header.IconOff, SEEK_SET);
|
||||
reader->Read(fROM, &banner, sizeof(RomBanner));
|
||||
|
||||
banner.version = LE_TO_LOCAL_16(banner.version);
|
||||
banner.crc16 = LE_TO_LOCAL_16(banner.crc16);
|
||||
|
||||
for(size_t i = 0; i < ARRAY_SIZE(banner.palette); i++)
|
||||
{
|
||||
banner.palette[i] = LE_TO_LOCAL_16(banner.palette[i]);
|
||||
}
|
||||
}
|
||||
|
||||
_isDSiEnhanced = ((readROM(0x180) == 0x8D898581U) && (readROM(0x184) == 0x8C888480U));
|
||||
if (hasRomBanner())
|
||||
{
|
||||
|
@ -561,14 +570,15 @@ bool GameInfo::loadROM(std::string fname, u32 type)
|
|||
|
||||
void GameInfo::closeROM()
|
||||
{
|
||||
if (fROM)
|
||||
if (reader)
|
||||
reader->DeInit(fROM);
|
||||
|
||||
if (romdata)
|
||||
delete [] romdata;
|
||||
if (romdataForReader)
|
||||
delete [] romdataForReader;
|
||||
|
||||
fROM = NULL;
|
||||
romdata = NULL;
|
||||
reader = NULL;
|
||||
romdataForReader = NULL;
|
||||
romsize = 0;
|
||||
lastReadPos = 0xFFFFFFFF;
|
||||
}
|
||||
|
@ -577,36 +587,10 @@ u32 GameInfo::readROM(u32 pos)
|
|||
{
|
||||
u32 num;
|
||||
u32 data;
|
||||
if (!romdata)
|
||||
{
|
||||
if (lastReadPos != pos)
|
||||
reader->Seek(fROM, pos + headerOffset, SEEK_SET);
|
||||
num = reader->Read(fROM, &data, 4);
|
||||
lastReadPos = (pos + num);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(pos + 4 <= romsize)
|
||||
{
|
||||
//fast path
|
||||
data = LE_TO_LOCAL_32(*(u32*)(romdata + pos));
|
||||
num = 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = 0;
|
||||
num = 0;
|
||||
for(int i=0;i<4;i++)
|
||||
{
|
||||
if(pos >= romsize)
|
||||
break;
|
||||
data |= (romdata[pos]<<(i*8));
|
||||
pos++;
|
||||
num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lastReadPos != pos)
|
||||
reader->Seek(fROM, pos + headerOffset, SEEK_SET);
|
||||
num = reader->Read(fROM, &data, 4);
|
||||
lastReadPos = (pos + num);
|
||||
|
||||
//in case we didn't read enough data, pad the remainder with 0xFF
|
||||
u32 pad = 0;
|
||||
|
@ -669,8 +653,16 @@ static int rom_init_path(const char *filename, const char *physicalName, const c
|
|||
return 1;
|
||||
}
|
||||
|
||||
struct LastRom {
|
||||
std::string filename, physicalName, logicalFilename;
|
||||
} lastRom;
|
||||
|
||||
int NDS_LoadROM(const char *filename, const char *physicalName, const char *logicalFilename)
|
||||
{
|
||||
lastRom.filename = filename;
|
||||
lastRom.physicalName = physicalName;
|
||||
lastRom.logicalFilename = logicalFilename;
|
||||
|
||||
int ret;
|
||||
char buf[MAX_PATH];
|
||||
|
||||
|
@ -693,10 +685,15 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
|
|||
|
||||
gameInfo.populate();
|
||||
|
||||
if (CommonSettings.loadToMemory)
|
||||
gameInfo.crc = crc32(0, (u8*)gameInfo.romdata, gameInfo.romsize);
|
||||
else
|
||||
gameInfo.crc = 0;
|
||||
//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;
|
||||
for(;;) {
|
||||
u8 buf[4096];
|
||||
int read = gameInfo.reader->Read(gameInfo.fROM,buf,4096);
|
||||
if(read == 0) break;
|
||||
gameInfo.crc = crc32(gameInfo.crc, buf, read);
|
||||
}
|
||||
|
||||
gameInfo.chipID = 0xC2; // The Manufacturer ID is defined by JEDEC (C2h = Macronix)
|
||||
if (!gameInfo.isHomebrew())
|
||||
|
@ -720,8 +717,7 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
|
|||
}
|
||||
|
||||
INFO("\nROM game code: %c%c%c%c\n", gameInfo.header.gameCode[0], gameInfo.header.gameCode[1], gameInfo.header.gameCode[2], gameInfo.header.gameCode[3]);
|
||||
if (gameInfo.crc)
|
||||
INFO("ROM crc: %08X\n", gameInfo.crc);
|
||||
INFO("ROM crc: %08X\n", gameInfo.crc);
|
||||
if (!gameInfo.isHomebrew())
|
||||
{
|
||||
INFO("ROM serial: %s\n", gameInfo.ROMserial);
|
||||
|
@ -762,14 +758,11 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
|
|||
//for homebrew, try auto-patching DLDI. should be benign if there is no DLDI or if it fails
|
||||
if(gameInfo.isHomebrew())
|
||||
{
|
||||
if(!CommonSettings.loadToMemory)
|
||||
msgbox->warn("Sorry.. right now, you can't use the default (stream rom from disk) with homebrew due to a bug with DLDI-autopatching");
|
||||
else if (slot1_GetCurrentType() == NDS_SLOT1_R4)
|
||||
DLDI::tryPatch((void*)gameInfo.romdata, gameInfo.romsize, 1);
|
||||
else
|
||||
if (slot2_GetCurrentType() == NDS_SLOT2_CFLASH)
|
||||
DLDI::tryPatch((void*)gameInfo.romdata, gameInfo.romsize, 0);
|
||||
|
||||
//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)
|
||||
|
@ -2510,6 +2503,15 @@ bool NDS_FakeBoot()
|
|||
bool _HACK_DONT_STOPMOVIE = false;
|
||||
void NDS_Reset()
|
||||
{
|
||||
//reload last paths if needed
|
||||
if(!gameInfo.reader)
|
||||
{
|
||||
LastRom stash = lastRom;
|
||||
NDS_LoadROM(stash.filename.c_str(), stash.physicalName.c_str(), stash.logicalFilename.c_str());
|
||||
//yeah, great. LoadROM calls NDS_Reset. Geeze.
|
||||
return;
|
||||
}
|
||||
|
||||
PrepareLogfiles();
|
||||
|
||||
CommonSettings.gamehacks.apply();
|
||||
|
|
|
@ -317,7 +317,7 @@ struct GameInfo
|
|||
{
|
||||
void *fROM;
|
||||
ROMReader_struct *reader;
|
||||
u8 *romdata;
|
||||
u8 *romdataForReader;
|
||||
u32 romsize;
|
||||
u32 cardSize;
|
||||
u32 mask;
|
||||
|
@ -336,7 +336,7 @@ struct GameInfo
|
|||
const RomBanner& getRomBanner();
|
||||
|
||||
GameInfo() : fROM(NULL),
|
||||
romdata(NULL),
|
||||
romdataForReader(NULL),
|
||||
crc(0),
|
||||
chipID(0x00000FC2),
|
||||
romsize(0),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright 2007 Guillaume Duhamel
|
||||
Copyright 2007-2012 DeSmuME team
|
||||
Copyright 2007-2017 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -55,6 +55,7 @@ void STDROMReaderDeInit(void *);
|
|||
u32 STDROMReaderSize(void *);
|
||||
int STDROMReaderSeek(void *, int, int);
|
||||
int STDROMReaderRead(void *, void *, u32);
|
||||
int STDROMReaderWrite(void *, void *, u32);
|
||||
|
||||
ROMReader_struct STDROMReader =
|
||||
{
|
||||
|
@ -64,7 +65,8 @@ ROMReader_struct STDROMReader =
|
|||
STDROMReaderDeInit,
|
||||
STDROMReaderSize,
|
||||
STDROMReaderSeek,
|
||||
STDROMReaderRead
|
||||
STDROMReaderRead,
|
||||
STDROMReaderWrite
|
||||
};
|
||||
|
||||
void * STDROMReaderInit(const char * filename)
|
||||
|
@ -91,7 +93,7 @@ u32 STDROMReaderSize(void * file)
|
|||
{
|
||||
u32 size;
|
||||
|
||||
if (!file) return 0 ;
|
||||
if (!file) return 0;
|
||||
|
||||
fseek((FILE*)file, 0, SEEK_END);
|
||||
size = ftell((FILE*)file);
|
||||
|
@ -102,22 +104,29 @@ u32 STDROMReaderSize(void * file)
|
|||
|
||||
int STDROMReaderSeek(void * file, int offset, int whence)
|
||||
{
|
||||
if (!file) return 0 ;
|
||||
if (!file) return 0;
|
||||
return fseek((FILE*)file, offset, whence);
|
||||
}
|
||||
|
||||
int STDROMReaderRead(void * file, void * buffer, u32 size)
|
||||
{
|
||||
if (!file) return 0 ;
|
||||
if (!file) return 0;
|
||||
return fread(buffer, 1, size, (FILE*)file);
|
||||
}
|
||||
|
||||
int STDROMReaderWrite(void *, void *, u32)
|
||||
{
|
||||
//not supported, for now
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBZ
|
||||
void * GZIPROMReaderInit(const char * filename);
|
||||
void GZIPROMReaderDeInit(void *);
|
||||
u32 GZIPROMReaderSize(void *);
|
||||
int GZIPROMReaderSeek(void *, int, int);
|
||||
int GZIPROMReaderRead(void *, void *, u32);
|
||||
int GZIPROMReaderWrite(void *, void *, u32);
|
||||
|
||||
ROMReader_struct GZIPROMReader =
|
||||
{
|
||||
|
@ -127,7 +136,8 @@ ROMReader_struct GZIPROMReader =
|
|||
GZIPROMReaderDeInit,
|
||||
GZIPROMReaderSize,
|
||||
GZIPROMReaderSeek,
|
||||
GZIPROMReaderRead
|
||||
GZIPROMReaderRead,
|
||||
GZIPROMReaderWrite
|
||||
};
|
||||
|
||||
void * GZIPROMReaderInit(const char * filename)
|
||||
|
@ -164,6 +174,12 @@ int GZIPROMReaderRead(void * file, void * buffer, u32 size)
|
|||
{
|
||||
return gzread((gzFile)file, buffer, size);
|
||||
}
|
||||
|
||||
int GZIPROMReaderWrite(void *, void *, u32)
|
||||
{
|
||||
//not supported, ever
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBZZIP
|
||||
|
@ -172,6 +188,7 @@ void ZIPROMReaderDeInit(void *);
|
|||
u32 ZIPROMReaderSize(void *);
|
||||
int ZIPROMReaderSeek(void *, int, int);
|
||||
int ZIPROMReaderRead(void *, void *, u32);
|
||||
int ZIPROMReaderWrite(void *, void *, u32);
|
||||
|
||||
ROMReader_struct ZIPROMReader =
|
||||
{
|
||||
|
@ -182,6 +199,7 @@ ROMReader_struct ZIPROMReader =
|
|||
ZIPROMReaderSize,
|
||||
ZIPROMReaderSeek,
|
||||
ZIPROMReaderRead
|
||||
ZIPROMReaderWrite
|
||||
};
|
||||
|
||||
void * ZIPROMReaderInit(const char * filename)
|
||||
|
@ -230,4 +248,95 @@ int ZIPROMReaderRead(void * file, void * buffer, u32 size)
|
|||
return zzip_read((ZZIP_FILE*)file, buffer, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
int ZIPROMReaderWrite(void *, void *, u32)
|
||||
{
|
||||
//not supported ever
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct {
|
||||
void* buf;
|
||||
int len;
|
||||
int pos;
|
||||
} mem;
|
||||
|
||||
void * MemROMReaderInit(const char * filename)
|
||||
{
|
||||
return NULL; //dummy
|
||||
}
|
||||
|
||||
void MemROMReaderDeInit(void *)
|
||||
{
|
||||
//nothing to do
|
||||
}
|
||||
u32 MemROMReaderSize(void *)
|
||||
{
|
||||
return (u32)mem.len;
|
||||
}
|
||||
int MemROMReaderSeek(void * file, int offset, int whence)
|
||||
{
|
||||
switch(whence) {
|
||||
case SEEK_SET:
|
||||
mem.pos = offset;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
mem.pos += offset;
|
||||
break;
|
||||
case SEEK_END:
|
||||
mem.pos = mem.len + offset;
|
||||
break;
|
||||
}
|
||||
return mem.pos;
|
||||
}
|
||||
|
||||
int MemROMReaderRead(void * file, void * buffer, u32 size)
|
||||
{
|
||||
if(mem.pos<0) return 0;
|
||||
|
||||
int todo = (int)size;
|
||||
int remain = mem.len - mem.pos;
|
||||
if(remain<todo)
|
||||
todo = remain;
|
||||
|
||||
if(todo==1) *(u8*)buffer = ((u8*)mem.buf)[mem.pos];
|
||||
else memcpy(buffer,(u8*)mem.buf + mem.pos, todo);
|
||||
mem.pos += todo;
|
||||
return todo;
|
||||
}
|
||||
|
||||
int MemROMReaderWrite(void * file, void * buffer, u32 size)
|
||||
{
|
||||
if(mem.pos<0) return 0;
|
||||
|
||||
int todo = (int)size;
|
||||
int remain = mem.len - mem.pos;
|
||||
if(remain<todo)
|
||||
todo = remain;
|
||||
|
||||
if(todo==1) *(u8*)buffer = ((u8*)mem.buf)[mem.pos];
|
||||
else memcpy((u8*)mem.buf + mem.pos,buffer, todo);
|
||||
mem.pos += todo;
|
||||
return todo;
|
||||
}
|
||||
|
||||
static ROMReader_struct MemROMReader =
|
||||
{
|
||||
ROMREADER_MEM,
|
||||
"Memory ROM Reader",
|
||||
MemROMReaderInit,
|
||||
MemROMReaderDeInit,
|
||||
MemROMReaderSize,
|
||||
MemROMReaderSeek,
|
||||
MemROMReaderRead,
|
||||
MemROMReaderWrite,
|
||||
};
|
||||
|
||||
ROMReader_struct * MemROMReaderRead_TrueInit(void* buf, int length)
|
||||
{
|
||||
mem.buf = buf;
|
||||
mem.len = length;
|
||||
mem.pos = 0;
|
||||
return &MemROMReader;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2007 Guillaume Duhamel
|
||||
Copyright (C) 2007 DeSmuME team
|
||||
Copyright (C) 2007-20017 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -27,6 +27,7 @@
|
|||
#define ROMREADER_STD 0
|
||||
#define ROMREADER_GZIP 1
|
||||
#define ROMREADER_ZIP 2
|
||||
#define ROMREADER_MEM 3
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -37,6 +38,7 @@ typedef struct
|
|||
u32 (*Size)(void * file);
|
||||
int (*Seek)(void * file, int offset, int whence);
|
||||
int (*Read)(void * file, void * buffer, u32 size);
|
||||
int (*Write)(void * file, void * buffer, u32 size);
|
||||
} ROMReader_struct;
|
||||
|
||||
extern ROMReader_struct STDROMReader;
|
||||
|
@ -48,3 +50,4 @@ extern ROMReader_struct ZIPROMReader;
|
|||
#endif
|
||||
|
||||
ROMReader_struct * ROMReaderInit(char ** filename);
|
||||
ROMReader_struct * MemROMReaderRead_TrueInit(void* buf, int length);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2013-2016 DeSmuME team
|
||||
Copyright (C) 2013-2017 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -60,15 +60,10 @@ public:
|
|||
fpROM = NULL;
|
||||
fs = NULL;
|
||||
|
||||
if (!CommonSettings.loadToMemory)
|
||||
{
|
||||
printf("NitroFS: change load type to \"Load to RAM\"\n");
|
||||
return;
|
||||
}
|
||||
pathData = path.getpath(path.SLOT1D) + path.GetRomNameWithoutExtension();
|
||||
printf("Path to Slot1 data: %s\n", pathData.c_str());
|
||||
|
||||
fs = new FS_NITRO(gameInfo.romdata);
|
||||
fs = new FS_NITRO();
|
||||
fs->rebuildFAT(pathData);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2013-2016 DeSmuME team
|
||||
Copyright (C) 2013-2017 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -91,7 +91,8 @@ void refreshQView(HWND hWnd, u16 id)
|
|||
u32 len = std::min<u32>(sizeof(buf), fs->getFileSizeById(id));
|
||||
u32 start = fs->getStartAddrById(id);
|
||||
|
||||
memcpy(&buf[0], &gameInfo.romdata[start], len);
|
||||
gameInfo.reader->Seek(gameInfo.fROM, start, SEEK_SET);
|
||||
gameInfo.reader->Read(gameInfo.fROM, &buf[0], len);
|
||||
|
||||
for (u32 i = 0; i < len; i++)
|
||||
if (buf[i] < 0x20) buf[i] = 0x20;
|
||||
|
@ -108,7 +109,7 @@ BOOL CALLBACK ViewFSNitroProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
|
|||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
fs = new FS_NITRO(gameInfo.romdata);
|
||||
fs = new FS_NITRO();
|
||||
|
||||
if (!fs)
|
||||
{
|
||||
|
|
|
@ -5693,11 +5693,6 @@ DOKEYDOWN:
|
|||
return 0;
|
||||
|
||||
case ID_TOOLS_VIEWFSNITRO:
|
||||
if (!CommonSettings.loadToMemory)
|
||||
{
|
||||
msgbox->error("Change ROM loading mode to \"Load entirely to RAM\"");
|
||||
return 0;
|
||||
}
|
||||
ViewFSNitro->open();
|
||||
return 0;
|
||||
//========================================================== Tools end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
Copyright (C) 2006 yopyop
|
||||
Copyright (C) 2006-2016 DeSmuME team
|
||||
Copyright (C) 2006-2017 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -81,10 +81,6 @@ u8 memRead8 (MemRegionType regionType, HWAddressType address)
|
|||
case MEMVIEW_FIRMWARE:
|
||||
value = MMU.fw.data[address];
|
||||
return value;
|
||||
case MEMVIEW_ROM:
|
||||
if (address < gameInfo.romsize)
|
||||
value = gameInfo.romdata[address];
|
||||
return value;
|
||||
case MEMVIEW_FULL:
|
||||
MMU_DumpMemBlock(0, address, 1, &value);
|
||||
return value;
|
||||
|
@ -92,69 +88,6 @@ u8 memRead8 (MemRegionType regionType, HWAddressType address)
|
|||
return 0;
|
||||
}
|
||||
|
||||
u16 memRead16 (MemRegionType regionType, HWAddressType address)
|
||||
{
|
||||
MemViewRegion& region = s_memoryRegions[regionType];
|
||||
if (address < region.hardwareAddress || (address + 1) >= (region.hardwareAddress + region.size))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 value = 0;
|
||||
switch (regionType)
|
||||
{
|
||||
case MEMVIEW_ARM9:
|
||||
MMU_DumpMemBlock(ARMCPU_ARM9, address, 2, (u8*)&value);
|
||||
return value;
|
||||
case MEMVIEW_ARM7:
|
||||
MMU_DumpMemBlock(ARMCPU_ARM7, address, 2, (u8*)&value);
|
||||
return value;
|
||||
case MEMVIEW_FIRMWARE:
|
||||
value = *(u16*)(&MMU.fw.data[address]);
|
||||
return value;
|
||||
case MEMVIEW_ROM:
|
||||
if (address < (gameInfo.romsize - 2))
|
||||
value = T1ReadWord(gameInfo.romdata, address);
|
||||
return value;
|
||||
case MEMVIEW_FULL:
|
||||
MMU_DumpMemBlock(0, address, 2, (u8*)&value);
|
||||
return value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 memRead32 (MemRegionType regionType, HWAddressType address)
|
||||
{
|
||||
MemViewRegion& region = s_memoryRegions[regionType];
|
||||
if (address < region.hardwareAddress || (address + 3) >= (region.hardwareAddress + region.size))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 value = 0;
|
||||
switch (regionType)
|
||||
{
|
||||
case MEMVIEW_ARM9:
|
||||
MMU_DumpMemBlock(ARMCPU_ARM9, address, 4, (u8*)&value);
|
||||
return value;
|
||||
case MEMVIEW_ARM7:
|
||||
MMU_DumpMemBlock(ARMCPU_ARM7, address, 4, (u8*)&value);
|
||||
return value;
|
||||
case MEMVIEW_FIRMWARE:
|
||||
value = *(u32*)(&MMU.fw.data[address]);
|
||||
return value;
|
||||
case MEMVIEW_ROM:
|
||||
if (address < (gameInfo.romsize - 4))
|
||||
value = T1ReadLong(gameInfo.romdata, address);
|
||||
|
||||
return value;
|
||||
case MEMVIEW_FULL:
|
||||
MMU_DumpMemBlock(0, address, 4, (u8*)&value);
|
||||
return value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void memRead(u8* buffer, MemRegionType regionType, HWAddressType address, size_t size)
|
||||
{
|
||||
switch (regionType)
|
||||
|
@ -165,6 +98,10 @@ void memRead(u8* buffer, MemRegionType regionType, HWAddressType address, size_t
|
|||
case MEMVIEW_ARM7:
|
||||
MMU_DumpMemBlock(ARMCPU_ARM7, address, size, buffer);
|
||||
break;
|
||||
case MEMVIEW_ROM:
|
||||
gameInfo.reader->Seek(gameInfo.fROM, address, SEEK_SET);
|
||||
gameInfo.reader->Read(gameInfo.fROM, buffer, size);
|
||||
break;
|
||||
default:
|
||||
for (size_t i = 0; i < size; i++)
|
||||
{
|
||||
|
@ -199,7 +136,8 @@ void memWrite8(MemRegionType regionType, HWAddressType address, u8 value)
|
|||
MMU.fw.data[address] = value;
|
||||
break;
|
||||
case MEMVIEW_ROM:
|
||||
gameInfo.romdata[address] = value;
|
||||
gameInfo.reader->Seek(gameInfo.fROM, address, SEEK_SET);
|
||||
gameInfo.reader->Write(gameInfo.fROM, &value, 1);
|
||||
break;
|
||||
case MEMVIEW_FULL:
|
||||
MMU_write8(ARMCPU_ARM9, address, value);
|
||||
|
@ -222,7 +160,8 @@ void memWrite16(MemRegionType regionType, HWAddressType address, u16 value)
|
|||
*((u16*)&MMU.fw.data[address]) = value;
|
||||
break;
|
||||
case MEMVIEW_ROM:
|
||||
*((u16*)&gameInfo.romdata[address]) = value;
|
||||
gameInfo.reader->Seek(gameInfo.fROM, address, SEEK_SET);
|
||||
gameInfo.reader->Write(gameInfo.fROM, &value, 2);
|
||||
break;
|
||||
case MEMVIEW_FULL:
|
||||
MMU_write16(ARMCPU_ARM9, address, value);
|
||||
|
@ -245,7 +184,8 @@ void memWrite32(MemRegionType regionType, HWAddressType address, u32 value)
|
|||
*((u32*)&MMU.fw.data[address]) = value;
|
||||
break;
|
||||
case MEMVIEW_ROM:
|
||||
*((u32*)&gameInfo.romdata[address]) = value;
|
||||
gameInfo.reader->Seek(gameInfo.fROM, address, SEEK_SET);
|
||||
gameInfo.reader->Write(gameInfo.fROM, &value, 4);
|
||||
break;
|
||||
case MEMVIEW_FULL:
|
||||
MMU_write32(ARMCPU_ARM9, address, value);
|
||||
|
@ -274,8 +214,7 @@ CMemView::CMemView(MemRegionType memRegion, u32 start_address)
|
|||
s_memoryRegions.push_back(s_arm7Region);
|
||||
s_memoryRegions.push_back(s_firmwareRegion);
|
||||
s_memoryRegions.push_back(s_fullRegion);
|
||||
if (CommonSettings.loadToMemory)
|
||||
s_memoryRegions.push_back(s_RomRegion);
|
||||
s_memoryRegions.push_back(s_RomRegion);
|
||||
}
|
||||
|
||||
PostInitialize();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2013-2016 DeSmuME team
|
||||
Copyright (C) 2013-2017 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -22,8 +22,9 @@
|
|||
#include "types.h"
|
||||
#include "fsnitro.h"
|
||||
#include "file/file_path.h"
|
||||
#include "NDSSystem.h"
|
||||
|
||||
FS_NITRO::FS_NITRO(u8 *cart_rom)
|
||||
FS_NITRO::FS_NITRO()
|
||||
{
|
||||
inited = false;
|
||||
numDirs = numFiles = numOverlay7 = numOverlay9 = currentID =0;
|
||||
|
@ -32,9 +33,9 @@ FS_NITRO::FS_NITRO(u8 *cart_rom)
|
|||
ovr9 = NULL;
|
||||
ovr7 = NULL;
|
||||
|
||||
if (!cart_rom) return;
|
||||
|
||||
rom = cart_rom;
|
||||
u8 rom[256];
|
||||
gameInfo.reader->Seek(gameInfo.fROM, 0, SEEK_SET);
|
||||
gameInfo.reader->Read(gameInfo.fROM, rom, 256);
|
||||
|
||||
FNameTblOff = *(u32*)(rom + 0x40);
|
||||
FNameTblSize = *(u32*)(rom + 0x44);
|
||||
|
@ -62,7 +63,8 @@ FS_NITRO::FS_NITRO(u8 *cart_rom)
|
|||
if (FATOff < 0x8000) return;
|
||||
if (FATSize == 0) return;
|
||||
|
||||
numDirs = *(u16*)(rom + FNameTblOff + 6);
|
||||
gameInfo.reader->Seek(gameInfo.fROM, FNameTblOff + 6, SEEK_SET);
|
||||
gameInfo.reader->Read(gameInfo.fROM, &numDirs, 2);
|
||||
numFiles = FATSize / 8;
|
||||
|
||||
if (numFiles == 0 || numDirs == 0)
|
||||
|
@ -140,12 +142,12 @@ bool FS_NITRO::loadFileTables()
|
|||
fnt = new FNT_NITRO[numDirs];
|
||||
|
||||
// ========= FAT (File Allocation Table)
|
||||
u32 *_FAT = (u32*)(rom + FATOff);
|
||||
for (u32 i = 0; i < numFiles; i++)
|
||||
{
|
||||
const u32 ofs = (i * 2);
|
||||
fat[i].start = *(_FAT + ofs);
|
||||
fat[i].end = *(_FAT + ofs + 1);
|
||||
gameInfo.reader->Seek(gameInfo.fROM, FATOff + ofs, SEEK_SET);
|
||||
gameInfo.reader->Read(gameInfo.fROM, &fat[i].start, 4);
|
||||
gameInfo.reader->Read(gameInfo.fROM, &fat[i].end, 4);
|
||||
fat[i].size = fat[i].end - fat[i].start;
|
||||
fat[i].sizeFile = fat[i].size;
|
||||
fat[i].isOverlay = false;
|
||||
|
@ -154,7 +156,9 @@ bool FS_NITRO::loadFileTables()
|
|||
// ========= Overlays ARM9
|
||||
if (numOverlay9)
|
||||
{
|
||||
memcpy(ovr9, (rom + ARM9OverlayOff), ARM9OverlaySize);
|
||||
gameInfo.reader->Seek(gameInfo.fROM, ARM9OverlayOff, SEEK_SET);
|
||||
gameInfo.reader->Read(gameInfo.fROM, ovr9, ARM9OverlaySize);
|
||||
|
||||
for (u32 i = 0 ; i < numOverlay9; i++)
|
||||
{
|
||||
char buf[129] = {0};
|
||||
|
@ -168,7 +172,9 @@ bool FS_NITRO::loadFileTables()
|
|||
// ========= Overlays ARM7
|
||||
if (numOverlay7)
|
||||
{
|
||||
memcpy(ovr7, (rom + ARM7OverlayOff), ARM7OverlaySize);
|
||||
gameInfo.reader->Seek(gameInfo.fROM, ARM7OverlayOff, SEEK_SET);
|
||||
gameInfo.reader->Read(gameInfo.fROM, ovr7, ARM7OverlaySize);
|
||||
|
||||
for (u32 i = 0 ; i < numOverlay7; i++)
|
||||
{
|
||||
char buf[129] = {0};
|
||||
|
@ -180,23 +186,24 @@ bool FS_NITRO::loadFileTables()
|
|||
}
|
||||
|
||||
// ========= FNT (File Names Table)
|
||||
u8 *_FNT = (u8*)(rom + FNameTblOff);
|
||||
gameInfo.reader->Seek(gameInfo.fROM, FNameTblOff, SEEK_SET);
|
||||
for (u32 i = 0; i < numDirs; i++)
|
||||
{
|
||||
memcpy(&fnt[i], _FNT, 8);
|
||||
gameInfo.reader->Read(gameInfo.fROM, &fnt[i], 8);
|
||||
//printf("FNT %04Xh: sub:%08Xh, 1st ID:%04xh, parentID:%04Xh\n", i, fnt[i].offset, fnt[i].firstID, fnt[i].parentID);
|
||||
_FNT += 8;
|
||||
}
|
||||
|
||||
// ========= Read file structure
|
||||
u8 *sub = (u8*)(rom + FNameTblOff + fnt[0].offset);
|
||||
u8 *_end = (u8*)(rom + FNameTblOff + FNameTblSize - 1);
|
||||
//u8 *sub = (u8*)(rom + FNameTblOff + fnt[0].offset);
|
||||
//u8 *_end = (u8*)(rom + FNameTblOff + FNameTblSize - 1);
|
||||
u32 subptr = FNameTblOff + fnt[0].offset;
|
||||
u32 _endptr = FNameTblOff + FNameTblSize - 1;
|
||||
u16 fileCount = fnt[0].firstID;
|
||||
u16 fntID = 0xF000;
|
||||
uintptr_t *store = new uintptr_t[numDirs];
|
||||
uintptr_t *store = new u32[numDirs];
|
||||
|
||||
if (!store) return false;
|
||||
memset(store, 0, sizeof(uintptr_t) * numDirs);
|
||||
memset(store, 0, sizeof(u32) * numDirs);
|
||||
|
||||
fnt[0].filename = path_default_slash();
|
||||
fnt[0].parentID = 0xF000;
|
||||
|
@ -205,13 +212,17 @@ bool FS_NITRO::loadFileTables()
|
|||
|
||||
while (true)
|
||||
{
|
||||
u8 len = (sub[0] & 0x7F);
|
||||
FNT_TYPES type = getFNTType(sub[0]);
|
||||
u8 sub;
|
||||
gameInfo.reader->Seek(gameInfo.fROM, subptr, SEEK_SET);
|
||||
gameInfo.reader->Read(gameInfo.fROM, &sub, 1);
|
||||
|
||||
u8 len = (sub & 0x7F);
|
||||
FNT_TYPES type = getFNTType(sub);
|
||||
|
||||
if (type == FS_END_SUBTABLE)
|
||||
{
|
||||
//printf("********** End Subdir (%04Xh, parent %04X)\n", fntID, fnt[fntID & 0x0FFF].parentID);
|
||||
sub = (u8*)store[fntID & 0x0FFF];
|
||||
subptr = store[fntID & 0x0FFF];
|
||||
fntID = fnt[fntID & 0x0FFF].parentID;
|
||||
continue;
|
||||
}
|
||||
|
@ -220,14 +231,17 @@ bool FS_NITRO::loadFileTables()
|
|||
{
|
||||
//printf("********** Subdir Entry\n");
|
||||
char buf[129] = {0};
|
||||
memcpy(buf, (sub + 1), len); buf[len] = 0;
|
||||
sub += (len + 1);
|
||||
fntID = (*(u16*)sub);
|
||||
sub += 2;
|
||||
gameInfo.reader->Seek(gameInfo.fROM, subptr + 1, SEEK_SET);
|
||||
gameInfo.reader->Read(gameInfo.fROM, buf, len);
|
||||
buf[len] = 0;
|
||||
subptr += (len + 1);
|
||||
gameInfo.reader->Seek(gameInfo.fROM, subptr, SEEK_SET);
|
||||
gameInfo.reader->Read(gameInfo.fROM, &fntID, 2);
|
||||
subptr += 2;
|
||||
|
||||
u32 id = (fntID & 0x0FFF);
|
||||
store[id] = (uintptr_t)sub;
|
||||
sub = (u8*)(rom + FNameTblOff + fnt[id].offset);
|
||||
store[id] = subptr;
|
||||
subptr = FNameTblOff + fnt[id].offset;
|
||||
fnt[id].filename = buf;
|
||||
|
||||
//printf("FNT %04X: Sub:%08Xh, 1st ID:%04xh, parentID:%04Xh <%s>\n", fntID, fnt[id].offset, fnt[id].firstID, fnt[id].parentID, buf);
|
||||
|
@ -238,11 +252,13 @@ bool FS_NITRO::loadFileTables()
|
|||
{
|
||||
//printf("********** File Entry\n");
|
||||
char buf[129] = {0};
|
||||
memcpy(buf, (sub + 1), len); buf[len] = 0;
|
||||
gameInfo.reader->Seek(gameInfo.fROM, subptr + 1, SEEK_SET);
|
||||
gameInfo.reader->Read(gameInfo.fROM, buf, len);
|
||||
buf[len] = 0;
|
||||
fat[fileCount].filename = buf;
|
||||
fat[fileCount].parentID = fntID;
|
||||
//printf("ID:%04Xh, len %03d, type %d, parentID %04X, filename: %s\n", fileCount, len, (u32)type, fntID, fat[fileCount].filename);
|
||||
sub += (len + 1);
|
||||
subptr += (len + 1);
|
||||
fileCount++;
|
||||
|
||||
if (fileCount >= numFiles) break;
|
||||
|
@ -272,8 +288,6 @@ bool FS_NITRO::rebuildFAT(u32 addr, u32 size, std::string pathData)
|
|||
const u32 endID = startID + (size / 8);
|
||||
//printf("Start rebuild FAT (start ID:%04Xh)\n", startID);
|
||||
|
||||
u8 *romFAT = (u8*)(rom + addr);
|
||||
|
||||
for (u32 i = startID; i < endID; i++)
|
||||
{
|
||||
if (i >= numFiles) break;
|
||||
|
@ -467,7 +481,19 @@ bool FS_NITRO::extract(u16 id, std::string to)
|
|||
FILE *fp = fopen(to.c_str(), "wb");
|
||||
if (fp)
|
||||
{
|
||||
fwrite((rom + fat[id].start), 1, fat[id].size, fp);
|
||||
u32 remain = fat[id].size;
|
||||
u32 dstofs = 0;
|
||||
gameInfo.reader->Seek(gameInfo.fROM, fat[id].start, SEEK_SET);
|
||||
while(remain>0) {
|
||||
u8 tmp[4096];
|
||||
u32 todo = remain;
|
||||
if(todo>4096) todo=4096;
|
||||
int done = gameInfo.reader->Read(gameInfo.fROM, tmp, todo);
|
||||
if(done != todo) break; //panic
|
||||
fwrite(tmp, 1, done, fp);
|
||||
dstofs += done;
|
||||
remain -= done;
|
||||
}
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (C) 2013-2016 DeSmuME team
|
||||
Copyright (C) 2013-2017 DeSmuME team
|
||||
|
||||
This file is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -118,7 +118,6 @@ private:
|
|||
|
||||
u32 currentID;
|
||||
|
||||
u8 *rom;
|
||||
FAT_NITRO *fat;
|
||||
FNT_NITRO *fnt;
|
||||
OVR_NITRO *ovr9;
|
||||
|
@ -131,7 +130,7 @@ private:
|
|||
void destroy();
|
||||
|
||||
public:
|
||||
FS_NITRO(u8 *cart_rom);
|
||||
FS_NITRO();
|
||||
~FS_NITRO();
|
||||
|
||||
bool getFileIdByAddr(u32 addr, u16 &id);
|
||||
|
|
Loading…
Reference in New Issue