core:
- add streaming ROM data from disk. I was broke all ports except windows, on linux/mac ports need fix rom_init_path in NDSSystem.cpp but i can't test this;
This commit is contained in:
parent
76de7fc3ec
commit
8edec83002
|
@ -908,8 +908,6 @@ void MMU_Init(void)
|
|||
|
||||
memset(&MMU, 0, sizeof(MMU_struct));
|
||||
|
||||
MMU.CART_ROM = MMU.UNUSED_RAM;
|
||||
|
||||
//MMU.DTCMRegion = 0x027C0000;
|
||||
//even though apps may change dtcm immediately upon startup, this is the correct hardware starting value:
|
||||
MMU.DTCMRegion = 0x08000000;
|
||||
|
@ -1056,16 +1054,6 @@ void SetupMMU(bool debugConsole, bool dsi) {
|
|||
_MMU_MAIN_MEM_MASK32 = _MMU_MAIN_MEM_MASK & ~3;
|
||||
}
|
||||
|
||||
void MMU_setRom(u8 * rom, u32 mask)
|
||||
{
|
||||
MMU.CART_ROM = rom;
|
||||
}
|
||||
|
||||
void MMU_unsetRom()
|
||||
{
|
||||
MMU.CART_ROM=MMU.UNUSED_RAM;
|
||||
}
|
||||
|
||||
static void execsqrt() {
|
||||
u32 ret;
|
||||
u8 mode = MMU_new.sqrt.mode;
|
||||
|
|
|
@ -406,9 +406,6 @@ struct MMU_struct
|
|||
//32KB of shared WRAM - can be switched between ARM7 & ARM9 in two blocks
|
||||
u8 SWIRAM[0x8000];
|
||||
|
||||
//Card rom & ram
|
||||
u8 * CART_ROM;
|
||||
|
||||
//Unused ram
|
||||
u8 UNUSED_RAM[4];
|
||||
|
||||
|
@ -546,9 +543,6 @@ void MMU_DeInit(void);
|
|||
|
||||
void MMU_Reset( void);
|
||||
|
||||
void MMU_setRom(u8 * rom, u32 mask);
|
||||
void MMU_unsetRom( void);
|
||||
|
||||
void print_memory_profiling( void);
|
||||
|
||||
// Memory reading/writing (old)
|
||||
|
|
|
@ -153,10 +153,9 @@ int NDS_Init( void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void NDS_DeInit(void) {
|
||||
if(MMU.CART_ROM != MMU.UNUSED_RAM)
|
||||
NDS_FreeROM();
|
||||
|
||||
void NDS_DeInit(void)
|
||||
{
|
||||
gameInfo.closeROM();
|
||||
SPU_DeInit();
|
||||
Screen_DeInit();
|
||||
MMU_DeInit();
|
||||
|
@ -191,23 +190,11 @@ void NDS_DeInit(void) {
|
|||
#endif
|
||||
}
|
||||
|
||||
BOOL NDS_SetROM(u8 * rom, u32 mask)
|
||||
{
|
||||
MMU_setRom(rom, mask);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NDS_header * NDS_getROMHeader(void)
|
||||
{
|
||||
if(MMU.CART_ROM == MMU.UNUSED_RAM) return NULL;
|
||||
NDS_header * header = new NDS_header;
|
||||
|
||||
//copy all data blindly, but not entirely blindly.. in case the header is smaller than normal, we dont want to read junk data
|
||||
//(we memset to 0xFF since thats likely to be what gets read from the invalid area)
|
||||
memset(header,0xFF,sizeof(NDS_header));
|
||||
int todo = std::min<u32>(gameInfo.romsize,sizeof(NDS_header));
|
||||
memcpy(header,MMU.CART_ROM,todo);
|
||||
memcpy(header, &gameInfo.header, sizeof(gameInfo.header));
|
||||
|
||||
//endian swap necessary fields. It would be better if we made accessors for these. I wonder if you could make a macro for a field accessor that would take the bitsize and do the swap on the fly
|
||||
struct FieldSwap {
|
||||
|
@ -245,6 +232,9 @@ NDS_header * NDS_getROMHeader(void)
|
|||
{ offsetof(NDS_header,endROMoffset), 4},
|
||||
{ offsetof(NDS_header,HeaderSize), 4},
|
||||
|
||||
{ offsetof(NDS_header, ARM9module), 4},
|
||||
{ offsetof(NDS_header, ARM7module), 4},
|
||||
|
||||
{ offsetof(NDS_header,logoCRC16), 2},
|
||||
{ offsetof(NDS_header,headerCRC16), 2},
|
||||
};
|
||||
|
@ -339,14 +329,7 @@ bool GameInfo::hasRomBanner()
|
|||
|
||||
const RomBanner& GameInfo::getRomBanner()
|
||||
{
|
||||
//we may not have a valid banner. return a default one
|
||||
if(!hasRomBanner())
|
||||
{
|
||||
static RomBanner defaultBanner(true);
|
||||
return defaultBanner;
|
||||
}
|
||||
|
||||
return *(RomBanner*)(romdata+header.IconOff);
|
||||
return banner;
|
||||
}
|
||||
|
||||
void GameInfo::populate()
|
||||
|
@ -440,31 +423,105 @@ void GameInfo::populate()
|
|||
|
||||
}
|
||||
|
||||
bool GameInfo::isDSiEnhanced()
|
||||
{
|
||||
return ((*(u32*)(romdata + 0x180) == 0x8D898581U) && (*(u32*)(romdata + 0x184) == 0x8C888480U));
|
||||
}
|
||||
|
||||
#ifdef _WINDOWS
|
||||
|
||||
static std::vector<char> buffer;
|
||||
static std::vector<char> v;
|
||||
|
||||
static void loadrom(std::string fname) {
|
||||
FILE* inf = fopen(fname.c_str(),"rb");
|
||||
if(!inf) return;
|
||||
bool GameInfo::loadROM(std::string fname)
|
||||
{
|
||||
printf("ROM %s\n", CommonSettings.loadToMemory?"loaded to RAM":"stream from disk");
|
||||
|
||||
fseek(inf,0,SEEK_END);
|
||||
int size = ftell(inf);
|
||||
fseek(inf,0,SEEK_SET);
|
||||
closeROM();
|
||||
|
||||
gameInfo.resize(size);
|
||||
fROM = fopen(fname.c_str(), "rb");
|
||||
if (!fROM) return false;
|
||||
|
||||
gameInfo.loadRom(inf);
|
||||
fseek(fROM, 0, SEEK_END);
|
||||
romsize = ftell(fROM);
|
||||
fseek(fROM, 0, SEEK_SET);
|
||||
|
||||
gameInfo.fillGap();
|
||||
bool res = (fread(&header, 1, sizeof(header), fROM) == sizeof(header));
|
||||
|
||||
fclose(inf);
|
||||
if (res)
|
||||
{
|
||||
cardSize = (128 * 1024) << header.cardSize;
|
||||
mask = (cardSize - 1);
|
||||
mask |= (mask >>1);
|
||||
mask |= (mask >>2);
|
||||
mask |= (mask >>4);
|
||||
mask |= (mask >>8);
|
||||
mask |= (mask >>16);
|
||||
|
||||
fseek(fROM, 0x4000, SEEK_SET);
|
||||
fread(&secureArea[0], 1, 0x4000, fROM);
|
||||
|
||||
if (CommonSettings.loadToMemory)
|
||||
{
|
||||
fseek(fROM, 0, SEEK_SET);
|
||||
|
||||
romdata = new u8[romsize + 4];
|
||||
if (fread(romdata, 1, romsize, fROM) != romsize)
|
||||
{
|
||||
delete [] romdata; romdata = NULL;
|
||||
romsize = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(hasRomBanner())
|
||||
memcpy(&banner, romdata + header.IconOff, sizeof(RomBanner));
|
||||
|
||||
_isDSiEnhanced = ((*(u32*)(romdata + 0x180) == 0x8D898581U) && (*(u32*)(romdata + 0x184) == 0x8C888480U));
|
||||
fclose(fROM); fROM = NULL;
|
||||
return true;
|
||||
}
|
||||
_isDSiEnhanced = ((readROM(0x180) == 0x8D898581U) && (readROM(0x184) == 0x8C888480U));
|
||||
if (hasRomBanner())
|
||||
{
|
||||
fseek(fROM, header.IconOff, SEEK_SET);
|
||||
fread(&banner, 1, sizeof(RomBanner), fROM);
|
||||
}
|
||||
fseek(fROM, 0, SEEK_SET);
|
||||
lastReadPos = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
romsize = 0;
|
||||
fclose(fROM); fROM = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
void GameInfo::closeROM()
|
||||
{
|
||||
if (fROM)
|
||||
fclose(fROM);
|
||||
|
||||
if (romdata)
|
||||
delete [] romdata;
|
||||
|
||||
fROM = NULL;
|
||||
romdata = NULL;
|
||||
romsize = 0;
|
||||
lastReadPos = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
u32 GameInfo::readROM(u32 pos)
|
||||
{
|
||||
if ((pos < 0x8000) && (pos >= 0x4000))
|
||||
return *(u32*)(secureArea + (pos - 0x4000));
|
||||
|
||||
if (!romdata)
|
||||
{
|
||||
u32 data;
|
||||
if (lastReadPos != pos)
|
||||
fseek(fROM, pos, SEEK_SET);
|
||||
u32 num = fread(&data, 1, 4, fROM);
|
||||
lastReadPos = (pos + num);
|
||||
return data;
|
||||
}
|
||||
else
|
||||
return *(u32*)(romdata + pos);
|
||||
}
|
||||
|
||||
static int rom_init_path(const char *filename, const char *physicalName, const char *logicalFilename)
|
||||
|
@ -475,11 +532,11 @@ static int rom_init_path(const char *filename, const char *physicalName, const c
|
|||
|
||||
if ( path.isdsgba(path.path)) {
|
||||
type = ROM_DSGBA;
|
||||
loadrom(path.path);
|
||||
gameInfo.loadROM(path.path);
|
||||
}
|
||||
else if ( !strcasecmp(path.extension().c_str(), "nds")) {
|
||||
type = ROM_NDS;
|
||||
loadrom(physicalName ? physicalName : path.path); //n.b. this does nothing if the file can't be found (i.e. if it was an extracted tempfile)...
|
||||
gameInfo.loadROM(physicalName ? physicalName : path.path); //n.b. this does nothing if the file can't be found (i.e. if it was an extracted tempfile)...
|
||||
//...but since the data was extracted to gameInfo then it is ok
|
||||
}
|
||||
//ds.gba in archives, it's already been loaded into memory at this point
|
||||
|
@ -488,14 +545,17 @@ static int rom_init_path(const char *filename, const char *physicalName, const c
|
|||
} else {
|
||||
//well, try to load it as an nds rom anyway
|
||||
type = ROM_NDS;
|
||||
loadrom(physicalName ? physicalName : path.path);
|
||||
gameInfo.loadROM(physicalName ? physicalName : path.path);
|
||||
}
|
||||
|
||||
// TODO: !!!!!
|
||||
#if 0
|
||||
if(type == ROM_DSGBA)
|
||||
{
|
||||
std::vector<char> v(gameInfo.romdata + DSGBA_LOADER_SIZE, gameInfo.romdata + gameInfo.romsize);
|
||||
gameInfo.loadData(&v[0],gameInfo.romsize - DSGBA_LOADER_SIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
//check that size is at least the size of the header
|
||||
if (gameInfo.romsize < 352) {
|
||||
|
@ -555,6 +615,7 @@ static int rom_init_path(const char *filename, const char *physicalName, const c
|
|||
|
||||
// Make sure old ROM is freed first(at least this way we won't be eating
|
||||
// up a ton of ram before the old ROM is freed)
|
||||
|
||||
if(MMU.CART_ROM != MMU.UNUSED_RAM)
|
||||
NDS_FreeROM();
|
||||
|
||||
|
@ -585,17 +646,19 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
|
|||
|
||||
|
||||
//check whether this rom is any kind of valid
|
||||
if(!CheckValidRom((u8*)gameInfo.romdata,gameInfo.romsize))
|
||||
if(!CheckValidRom((u8*)&gameInfo.header, gameInfo.secureArea))
|
||||
{
|
||||
printf("Specified file is not a valid rom\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
MMU_unsetRom();
|
||||
NDS_SetROM((u8*)gameInfo.romdata, gameInfo.mask);
|
||||
|
||||
gameInfo.populate();
|
||||
gameInfo.crc = crc32(0,(u8*)gameInfo.romdata,gameInfo.romsize);
|
||||
|
||||
|
||||
if (CommonSettings.loadToMemory)
|
||||
gameInfo.crc = crc32(0, (u8*)gameInfo.romdata, gameInfo.romsize);
|
||||
else
|
||||
gameInfo.crc = 0;
|
||||
|
||||
gameInfo.chipID = 0xC2; // The Manufacturer ID is defined by JEDEC (C2h = Macronix)
|
||||
gameInfo.chipID |= ((((128 << gameInfo.header.cardSize) / 1024) - 1) << 8); // Chip size in megabytes minus 1
|
||||
|
@ -623,9 +686,6 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
|
|||
if (gameInfo.isDSiEnhanced()) INFO("ROM DSi Enhanced\n");
|
||||
INFO("ROM developer: %s\n", getDeveloperNameByID(gameInfo.header.makerCode).c_str());
|
||||
|
||||
//crazymax: how would it have got whacked? dont think we need this
|
||||
//gameInfo.storeSecureArea();
|
||||
|
||||
#if 1
|
||||
u32 mask = gameInfo.header.endROMoffset - 1;
|
||||
mask |= (mask >> 1);
|
||||
|
@ -636,7 +696,7 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
|
|||
|
||||
printf("======================================================================\n");
|
||||
printf("card size %10u (%08Xh) mask %08Xh\n", gameInfo.cardSize, gameInfo.cardSize, gameInfo.mask);
|
||||
printf("file size %10u (%08Xh) mask %08Xh\n", gameInfo.romsize, gameInfo.romsize, gameInfo.filemask);
|
||||
printf("file size %10u (%08Xh)\n", gameInfo.romsize, gameInfo.romsize);
|
||||
printf("endROMoffset %10u (%08Xh) mask %08Xh\n", gameInfo.header.endROMoffset, gameInfo.header.endROMoffset, mask);
|
||||
printf("======================================================================\n");
|
||||
#endif
|
||||
|
@ -672,7 +732,7 @@ 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)
|
||||
if(gameInfo.isHomebrew && CommonSettings.loadToMemory)
|
||||
DLDI::tryPatch((void*)gameInfo.romdata, gameInfo.romsize);
|
||||
|
||||
if (cheats != NULL)
|
||||
|
@ -691,11 +751,7 @@ int NDS_LoadROM(const char *filename, const char *physicalName, const char *logi
|
|||
void NDS_FreeROM(void)
|
||||
{
|
||||
FCEUI_StopMovie();
|
||||
if ((u8*)MMU.CART_ROM == (u8*)gameInfo.romdata)
|
||||
gameInfo.romdata = NULL;
|
||||
if (MMU.CART_ROM != MMU.UNUSED_RAM)
|
||||
delete [] MMU.CART_ROM;
|
||||
MMU_unsetRom();
|
||||
gameInfo.closeROM();
|
||||
}
|
||||
|
||||
u32 NDS_ImportSaveSize(const char *filename)
|
||||
|
@ -2505,7 +2561,7 @@ bool NDS_LegitBoot()
|
|||
|
||||
//since firmware only boots encrypted roms, we have to make sure it's encrypted first
|
||||
//this has not been validated on big endian systems. it almost positively doesn't work.
|
||||
EncryptSecureArea((u8*)gameInfo.romdata,gameInfo.romsize);
|
||||
EncryptSecureArea((u8*)&gameInfo.header, (u8*)gameInfo.secureArea);
|
||||
|
||||
//boot processors from their bios entrypoints
|
||||
armcpu_init(&NDS_ARM7, 0x00000000);
|
||||
|
@ -2548,7 +2604,7 @@ bool NDS_FakeBoot()
|
|||
|
||||
//since we're bypassing the code to decrypt the secure area, we need to make sure its decrypted first
|
||||
//this has not been validated on big endian systems. it almost positively doesn't work.
|
||||
bool okRom = DecryptSecureArea((u8*)gameInfo.romdata,gameInfo.romsize);
|
||||
bool okRom = DecryptSecureArea((u8*)&gameInfo.header, (u8*)gameInfo.secureArea);
|
||||
|
||||
if(!okRom) {
|
||||
printf("Specified file is not a valid rom\n");
|
||||
|
@ -2578,7 +2634,8 @@ bool NDS_FakeBoot()
|
|||
u32 dst = header->ARM9cpy;
|
||||
for(u32 i = 0; i < (header->ARM9binSize>>2); ++i)
|
||||
{
|
||||
_MMU_write32<ARMCPU_ARM9>(dst, T1ReadLong(MMU.CART_ROM, src));
|
||||
_MMU_write32<ARMCPU_ARM9>(dst, gameInfo.readROM(src));
|
||||
|
||||
dst += 4;
|
||||
src += 4;
|
||||
}
|
||||
|
@ -2588,7 +2645,8 @@ bool NDS_FakeBoot()
|
|||
dst = header->ARM7cpy;
|
||||
for(u32 i = 0; i < (header->ARM7binSize>>2); ++i)
|
||||
{
|
||||
_MMU_write32<ARMCPU_ARM7>(dst, T1ReadLong(MMU.CART_ROM, src));
|
||||
_MMU_write32<ARMCPU_ARM7>(dst, gameInfo.readROM(src));
|
||||
|
||||
dst += 4;
|
||||
src += 4;
|
||||
}
|
||||
|
@ -2613,13 +2671,13 @@ bool NDS_FakeBoot()
|
|||
if(nds.Is_DSI())
|
||||
{
|
||||
//dsi needs this copied later in memory. there are probably a number of things that get copied to a later location in memory.. thats where the NDS consoles tend to stash stuff.
|
||||
for (int i = 0; i < ((0x170)/4); i++)
|
||||
_MMU_write32<ARMCPU_ARM9>(0x02FFFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i]));
|
||||
for (int i = 0; i < (0x170); i+=4)
|
||||
_MMU_write32<ARMCPU_ARM9>(0x027FFE00 + i, LE_TO_LOCAL_32(gameInfo.readROM(i)));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < ((0x170)/4); i++)
|
||||
_MMU_write32<ARMCPU_ARM9>(0x027FFE00+i*4, LE_TO_LOCAL_32(((u32*)MMU.CART_ROM)[i]));
|
||||
for (int i = 0; i < (0x170); i+=4)
|
||||
_MMU_write32<ARMCPU_ARM9>(0x027FFE00 + i, LE_TO_LOCAL_32(gameInfo.readROM(i)));
|
||||
}
|
||||
|
||||
//the firmware will be booting to these entrypoint addresses via BX (well, the arm9 at least; is unverified for the arm7)
|
||||
|
|
|
@ -297,7 +297,7 @@ NDS_header * NDS_getROMHeader(void);
|
|||
|
||||
struct RomBanner
|
||||
{
|
||||
RomBanner(bool defaultInit);
|
||||
RomBanner(bool defaultInit = true);
|
||||
u16 version; //Version (0001h)
|
||||
u16 crc16; //CRC16 across entries 020h..83Fh
|
||||
u8 reserved[0x1C]; //Reserved (zero-filled)
|
||||
|
@ -322,102 +322,48 @@ struct RomBanner
|
|||
|
||||
struct GameInfo
|
||||
{
|
||||
GameInfo() : romdata(NULL),
|
||||
FILE *fROM;
|
||||
u8 *romdata;
|
||||
u32 romsize;
|
||||
u32 cardSize;
|
||||
u32 mask;
|
||||
u32 crc;
|
||||
u32 chipID;
|
||||
u32 lastReadPos;
|
||||
char ROMserial[20];
|
||||
char ROMname[20];
|
||||
bool _isDSiEnhanced;
|
||||
bool isHomebrew;
|
||||
NDS_header header;
|
||||
//a copy of the pristine secure area from the rom
|
||||
u8 secureArea[0x4000];
|
||||
RomBanner banner;
|
||||
const RomBanner& getRomBanner();
|
||||
|
||||
GameInfo() : fROM(NULL),
|
||||
romdata(NULL),
|
||||
crc(0),
|
||||
chipID(0x00000FC2),
|
||||
romsize(0),
|
||||
cardSize(0),
|
||||
allocatedSize(0),
|
||||
mask(0),
|
||||
filemask(0)
|
||||
lastReadPos(0xFFFFFFFF),
|
||||
_isDSiEnhanced(false)
|
||||
{
|
||||
memset(&header, 0, sizeof(header));
|
||||
memset(&ROMserial[0], 0, sizeof(ROMserial));
|
||||
memset(&ROMname[0], 0, sizeof(ROMname));
|
||||
memset(&secureArea[0], 0, sizeof(secureArea));
|
||||
}
|
||||
|
||||
void loadData(char* buf, int size)
|
||||
{
|
||||
resize(size);
|
||||
memcpy(romdata,buf,size);
|
||||
romsize = (u32)size;
|
||||
fillGap();
|
||||
}
|
||||
~GameInfo() { closeROM(); }
|
||||
|
||||
void storeSecureArea()
|
||||
{
|
||||
if ((header.ARM9src >= 0x4000) && (header.ARM9src < 0x8000))
|
||||
memcpy(&secureArea[0], &romdata[header.ARM9src], 0x8000 - header.ARM9src);
|
||||
}
|
||||
|
||||
void restoreSecureArea()
|
||||
{
|
||||
if ((header.ARM9src >= 0x4000) && (header.ARM9src < 0x8000))
|
||||
memcpy(&romdata[header.ARM9src], &secureArea[0], 0x8000 - header.ARM9src);
|
||||
}
|
||||
|
||||
void fillGap()
|
||||
{
|
||||
memset(romdata+romsize,0xFF,allocatedSize-romsize);
|
||||
}
|
||||
|
||||
void resize(int size) {
|
||||
if(romdata != NULL) delete[] romdata;
|
||||
|
||||
//calculate the necessary mask for the requested size
|
||||
filemask = (size - 1);
|
||||
filemask |= (filemask >>1);
|
||||
filemask |= (filemask >>2);
|
||||
filemask |= (filemask >>4);
|
||||
filemask |= (filemask >>8);
|
||||
filemask |= (filemask >>16);
|
||||
|
||||
//now, we actually need to over-allocate, because bytes from anywhere protected by that mask
|
||||
//could be read from the rom
|
||||
allocatedSize = (filemask + 4);
|
||||
|
||||
romdata = new char[allocatedSize];
|
||||
romsize = size;
|
||||
}
|
||||
|
||||
bool loadRom(FILE *fp)
|
||||
{
|
||||
bool res = (fread(romdata, 1, romsize, fp) == romsize);
|
||||
if (res)
|
||||
{
|
||||
cardSize = (128 * 1024) << romdata[0x14];
|
||||
mask = (cardSize - 1);
|
||||
mask |= (mask >>1);
|
||||
mask |= (mask >>2);
|
||||
mask |= (mask >>4);
|
||||
mask |= (mask >>8);
|
||||
mask |= (mask >>16);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isDSiEnhanced();
|
||||
u32 crc;
|
||||
u32 chipID;
|
||||
NDS_header header;
|
||||
char ROMserial[20];
|
||||
char ROMname[20];
|
||||
//char ROMfullName[7][0x100];
|
||||
bool loadROM(std::string fname);
|
||||
void closeROM();
|
||||
u32 readROM(u32 pos);
|
||||
void populate();
|
||||
char* romdata;
|
||||
u32 romsize;
|
||||
u32 cardSize;
|
||||
u32 allocatedSize;
|
||||
u32 mask;
|
||||
u32 filemask;
|
||||
const RomBanner& getRomBanner();
|
||||
bool isDSiEnhanced() { return _isDSiEnhanced; };
|
||||
bool hasRomBanner();
|
||||
bool isHomebrew;
|
||||
|
||||
//a copy of the pristine secure area from the rom
|
||||
u8 secureArea[0x4000];
|
||||
};
|
||||
|
||||
typedef struct TSCalInfo
|
||||
|
@ -551,6 +497,7 @@ extern struct TCommonSettings {
|
|||
, GFX3D_Zelda_Shadow_Depth_Hack(0)
|
||||
, GFX3D_Renderer_Multisample(false)
|
||||
, jit_max_block_size(100)
|
||||
, loadToMemory(true)
|
||||
, UseExtBIOS(false)
|
||||
, SWIFromBIOS(false)
|
||||
, PatchSWI3(false)
|
||||
|
@ -604,6 +551,8 @@ extern struct TCommonSettings {
|
|||
int GFX3D_Zelda_Shadow_Depth_Hack;
|
||||
bool GFX3D_Renderer_Multisample;
|
||||
|
||||
bool loadToMemory;
|
||||
|
||||
bool UseExtBIOS;
|
||||
char ARM9BIOS[256];
|
||||
char ARM7BIOS[256];
|
||||
|
|
|
@ -51,17 +51,23 @@ public:
|
|||
|
||||
virtual void connect()
|
||||
{
|
||||
if (!MMU.CART_ROM) return;
|
||||
protocol.reset(this);
|
||||
protocol.chipId = gameInfo.chipID;
|
||||
protocol.gameCode = T1ReadLong((u8*)gameInfo.header.gameCode,0);
|
||||
|
||||
curr_file_id = 0xFFFF;
|
||||
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());
|
||||
|
||||
curr_file_id = 0xFFFF;
|
||||
fpROM = NULL;
|
||||
fs = new FS_NITRO(MMU.CART_ROM);
|
||||
fs = new FS_NITRO(gameInfo.romdata);
|
||||
fs->rebuildFAT(pathData);
|
||||
}
|
||||
|
||||
|
@ -113,13 +119,13 @@ public:
|
|||
u16 file_id = 0xFFFF; u32 offset = 0;
|
||||
bool bFromFile = false;
|
||||
|
||||
if (fs->isFAT(protocol.address))
|
||||
if (fs && fs->isFAT(protocol.address))
|
||||
{
|
||||
fs->rebuildFAT(protocol.address, protocol.length, pathData);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fs->getFileIdByAddr(protocol.address, file_id, offset))
|
||||
if (fs && fs->getFileIdByAddr(protocol.address, file_id, offset))
|
||||
{
|
||||
if (file_id != curr_file_id)
|
||||
{
|
||||
|
@ -178,7 +184,7 @@ private:
|
|||
|
||||
u32 address = rom.getAddress();
|
||||
|
||||
if (fs->isFAT(address))
|
||||
if (fs && fs->isFAT(address))
|
||||
{
|
||||
u32 res = fs->getFATRecord(address);
|
||||
if (res != 0xFFFFFFFF)
|
||||
|
|
|
@ -32,7 +32,7 @@ u32 Slot1Comp_Rom::read()
|
|||
{
|
||||
case eSlot1Operation_00_ReadHeader_Unencrypted:
|
||||
{
|
||||
u32 ret = T1ReadLong(MMU.CART_ROM, address);
|
||||
u32 ret = gameInfo.readROM(address);
|
||||
address = (address + 4) & 0xFFF;
|
||||
return ret;
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ u32 Slot1Comp_Rom::read()
|
|||
{
|
||||
//see B7 for details
|
||||
address &= gameInfo.mask; //sanity check
|
||||
u32 ret = T1ReadLong(MMU.CART_ROM, address);
|
||||
u32 ret = gameInfo.readROM(address);
|
||||
address = (address&~0xFFF) + ((address+4)&0xFFF);
|
||||
return ret;
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ u32 Slot1Comp_Rom::read()
|
|||
}
|
||||
|
||||
//actually read from the ROM provider
|
||||
u32 ret = T1ReadLong(MMU.CART_ROM, address);
|
||||
u32 ret = gameInfo.readROM(address);
|
||||
|
||||
//"However, the datastream wraps to the begin of the current 4K block when address+length crosses a 4K boundary (1000h bytes)"
|
||||
address = (address&~0xFFF) + ((address+4)&0xFFF);
|
||||
|
|
|
@ -33,6 +33,7 @@ int _commandline_linux_nojoy = 0;
|
|||
|
||||
CommandLine::CommandLine()
|
||||
: is_cflash_configured(false)
|
||||
, _load_to_memory(-1)
|
||||
, error(NULL)
|
||||
, ctx(g_option_context_new (""))
|
||||
, _play_movie_file(0)
|
||||
|
@ -80,6 +81,7 @@ void CommandLine::loadCommonOptions()
|
|||
//but also see the gtk port for an example of how to combine this with other options
|
||||
//(you may need to use ifdefs to cause options to be entered in the desired order)
|
||||
static const GOptionEntry options[] = {
|
||||
{ "load-type", 0, 0, G_OPTION_ARG_INT, &_load_to_memory, "Load ROM type, 0 - stream from disk, 1 - to RAM (default 1)", "LOAD_TYPE"},
|
||||
{ "load-slot", 0, 0, G_OPTION_ARG_INT, &load_slot, "Loads savegame from slot NUM", "NUM"},
|
||||
{ "play-movie", 0, 0, G_OPTION_ARG_FILENAME, &_play_movie_file, "Specifies a dsm format movie to play", "PATH_TO_PLAY_MOVIE"},
|
||||
{ "record-movie", 0, 0, G_OPTION_ARG_FILENAME, &_record_movie_file, "Specifies a path to a new dsm format movie", "PATH_TO_RECORD_MOVIE"},
|
||||
|
@ -143,6 +145,7 @@ bool CommandLine::parse(int argc,char **argv)
|
|||
if(_slot1_fat_dir) slot1_fat_dir = _slot1_fat_dir;
|
||||
if(_slot1) slot1 = _slot1; slot1 = strtoupper(slot1);
|
||||
if(_console_type) console_type = _console_type;
|
||||
if(_load_to_memory != -1) CommonSettings.loadToMemory = (_load_to_memory == 1)?true:false;
|
||||
if(_play_movie_file) play_movie_file = _play_movie_file;
|
||||
if(_record_movie_file) record_movie_file = _record_movie_file;
|
||||
if(_cflash_image) cflash_image = _cflash_image;
|
||||
|
@ -210,6 +213,11 @@ bool CommandLine::validate()
|
|||
}
|
||||
}
|
||||
|
||||
if (_load_to_memory < -1 || _load_to_memory > 1) {
|
||||
g_printerr("Invalid parameter (0 - stream from disk, 1 - from RAM)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (load_slot < -1 || load_slot > 10) {
|
||||
g_printerr("I only know how to load from slots 0-10; -1 means 'do not load savegame' and is default\n");
|
||||
return false;
|
||||
|
|
|
@ -85,6 +85,7 @@ private:
|
|||
char* _cflash_path;
|
||||
char* _gbaslot_rom;
|
||||
char* _bios_arm9, *_bios_arm7;
|
||||
int _load_to_memory;
|
||||
int _bios_swi;
|
||||
int _spu_advanced;
|
||||
int _num_cores;
|
||||
|
|
|
@ -487,12 +487,12 @@ static void encrypt_arm9(u32 cardheader_gamecode, unsigned char *data)
|
|||
//0x0200 - 0x3FFF : typically, nothing is stored here. on retail cards, you can't read from that area anyway, but im not sure if that's done in the game card or the GC bus controller on the system
|
||||
//0x4000 - 0x7FFF : secure area (details in gbatek)
|
||||
|
||||
bool DecryptSecureArea(u8 *romdata, long romlen)
|
||||
bool DecryptSecureArea(u8 *romheader, u8 *secure)
|
||||
{
|
||||
//this looks like it will only work on little endian hosts
|
||||
Header* header = (Header*)romdata;
|
||||
Header* header = (Header*)romheader;
|
||||
|
||||
int romType = DetectRomType(*header,(char*)romdata);
|
||||
int romType = DetectRomType(*header, (char*)secure);
|
||||
|
||||
if(romType == ROMTYPE_INVALID)
|
||||
return false;
|
||||
|
@ -512,7 +512,7 @@ bool DecryptSecureArea(u8 *romdata, long romlen)
|
|||
//// write secure 0x800
|
||||
//memcpy(romdata+0x4000,data,0x800);
|
||||
|
||||
decrypt_arm9(*(u32 *)header->gamecode, romdata+0x4000);
|
||||
decrypt_arm9(*(u32 *)header->gamecode, secure);
|
||||
|
||||
printf("Decrypted.\n");
|
||||
}
|
||||
|
@ -524,12 +524,12 @@ bool DecryptSecureArea(u8 *romdata, long romlen)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool EncryptSecureArea(u8 *romdata, long romlen)
|
||||
bool EncryptSecureArea(u8 *romheader, u8 *secure)
|
||||
{
|
||||
//this looks like it will only work on little endian hosts
|
||||
Header* header = (Header*)romdata;
|
||||
Header* header = (Header*)romheader;
|
||||
|
||||
int romType = DetectRomType(*header,(char*)romdata);
|
||||
int romType = DetectRomType(*header, (char*)secure);
|
||||
|
||||
if(romType == ROMTYPE_INVALID)
|
||||
return false;
|
||||
|
@ -544,7 +544,7 @@ bool EncryptSecureArea(u8 *romdata, long romlen)
|
|||
//// write secure 0x800
|
||||
//memcpy(romdata+0x4000,data,0x800);
|
||||
|
||||
encrypt_arm9(*(u32 *)header->gamecode, romdata+0x4000);
|
||||
encrypt_arm9(*(u32 *)header->gamecode, secure);
|
||||
|
||||
printf("Encrypted.\n");
|
||||
}
|
||||
|
@ -552,11 +552,11 @@ bool EncryptSecureArea(u8 *romdata, long romlen)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CheckValidRom(u8 *romdata, long romlen)
|
||||
bool CheckValidRom(u8 *header, u8 *secure)
|
||||
{
|
||||
Header* header = (Header*)romdata;
|
||||
Header* hdr = (Header*)header;
|
||||
|
||||
int romType = DetectRomType(*header,(char*)romdata);
|
||||
int romType = DetectRomType(*hdr, (char*)secure);
|
||||
|
||||
return (romType != ROMTYPE_INVALID);
|
||||
}
|
|
@ -24,12 +24,12 @@
|
|||
extern const unsigned char arm7_key[];
|
||||
|
||||
//decrypts the secure area of a rom (or does nothing if it is already decrypted)
|
||||
bool DecryptSecureArea(u8 *romdata, long romlen);
|
||||
bool DecryptSecureArea(u8 *romheader, u8 *secure);
|
||||
|
||||
//encrypts the secure area of a rom (or does nothing if it is already encrypted)
|
||||
bool EncryptSecureArea(u8 *romdata, long romlen);
|
||||
bool EncryptSecureArea(u8 *romheader, u8 *secure);
|
||||
|
||||
//since we have rom-type detection heuristics here, this module is responsible for checking whether a rom is valid
|
||||
bool CheckValidRom(u8 *romdata, long romlen);
|
||||
bool CheckValidRom(u8 *header, u8 *secure);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -66,9 +66,9 @@
|
|||
/*
|
||||
* DetectRomType
|
||||
*/
|
||||
int DetectRomType(const Header& header, char* romdata)
|
||||
int DetectRomType(const Header& header, char* secure)
|
||||
{
|
||||
unsigned int * data = (unsigned int*)(romdata + 0x4000);
|
||||
unsigned int * data = (unsigned int*)(secure);
|
||||
|
||||
//this is attempting to check for an utterly invalid nds header
|
||||
if(header.unitcode < 0 && header.unitcode > 3) return ROMTYPE_INVALID;
|
||||
|
@ -76,8 +76,9 @@ int DetectRomType(const Header& header, char* romdata)
|
|||
if (header.arm9_rom_offset < 0x4000) return ROMTYPE_HOMEBREW;
|
||||
if (data[0] == 0x00000000 && data[1] == 0x00000000) return ROMTYPE_MULTIBOOT;
|
||||
if (data[0] == 0xE7FFDEFF && data[1] == 0xE7FFDEFF) return ROMTYPE_NDSDUMPED;
|
||||
for (int i=0x200; i<0x4000; i++)
|
||||
if (romdata[i]) return ROMTYPE_MASKROM; // found something odd ;)
|
||||
//TODO
|
||||
//for (int i=0x200; i<0x4000; i++)
|
||||
// if (romdata[i]) return ROMTYPE_MASKROM; // found something odd ;)
|
||||
return ROMTYPE_ENCRSECURE;
|
||||
}
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ unsigned short CalcLogoCRC(Header &header);
|
|||
void FixHeaderCRC(char *ndsfilename);
|
||||
void ShowInfo(char *ndsfilename);
|
||||
int HashAndCompareWithList(char *filename, unsigned char sha1[]);
|
||||
int DetectRomType(const Header& header, char* romdata);
|
||||
int DetectRomType(const Header& header, char* secure);
|
||||
unsigned short CalcSecureAreaCRC(bool encrypt);
|
||||
|
||||
#define ROMTYPE_HOMEBREW 0
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "fsnitroView.h"
|
||||
#include "CWindow.h"
|
||||
#include "../MMU.h"
|
||||
#include "../NDSSystem.h"
|
||||
#include "../path.h"
|
||||
#include "../utils/fsnitro.h"
|
||||
#include "memView.h"
|
||||
|
@ -87,7 +88,7 @@ void refreshQView(HWND hWnd, u16 id)
|
|||
u32 len = std::min<u32>(sizeof(buf), fs->getFileSizeById(id));
|
||||
u32 start = fs->getStartAddrById(id);
|
||||
|
||||
memcpy(&buf[0], &MMU.CART_ROM[start], len);
|
||||
memcpy(&buf[0], &gameInfo.romdata[start], len);
|
||||
|
||||
for (u32 i = 0; i < len; i++)
|
||||
if (buf[i] < 0x20) buf[i] = 0x20;
|
||||
|
@ -104,7 +105,8 @@ BOOL CALLBACK ViewFSNitroProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
|
|||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
fs = new FS_NITRO(MMU.CART_ROM);
|
||||
fs = new FS_NITRO(gameInfo.romdata);
|
||||
|
||||
if (!fs)
|
||||
{
|
||||
msgbox->error("Error reading FS from ROM");
|
||||
|
|
|
@ -110,82 +110,81 @@ LRESULT GInfo_Paint(HWND hDlg, WPARAM wParam, LPARAM lParam)
|
|||
|
||||
//TODO - pull this from the header, not straight out of the rom (yuck!)
|
||||
|
||||
memcpy(text, MMU.CART_ROM, 12);
|
||||
memcpy(text, (u8*)&gameInfo.header, 12);
|
||||
text[12] = '\0';
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_GAMETITLE), text);
|
||||
|
||||
memcpy(text, (MMU.CART_ROM+0xC), 4);
|
||||
memcpy(text, ((u8*)&gameInfo.header+0xC), 4);
|
||||
text[4] = '\0';
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_GAMECODE), text);
|
||||
|
||||
memcpy(text, (MMU.CART_ROM+0x10), 2);
|
||||
memcpy(text, ((u8*)&gameInfo.header+0x10), 2);
|
||||
text[2] = '\0';
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_MAKERCODE), text);
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_SDEVELOPER), getDeveloperNameByID(T1ReadWord(MMU.CART_ROM, 0x10)).c_str());
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_SDEVELOPER), getDeveloperNameByID(T1ReadWord((u8*)&gameInfo.header, 0x10)).c_str());
|
||||
|
||||
val = T1ReadByte(MMU.CART_ROM, 0x14);
|
||||
val = T1ReadByte((u8*)&gameInfo.header, 0x14);
|
||||
sprintf(text, "%i kilobytes", (0x80 << val));
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_CHIPSIZE), text);
|
||||
|
||||
|
||||
val = T1ReadLong(MMU.CART_ROM, 0x20);
|
||||
val = T1ReadLong((u8*)&gameInfo.header, 0x20);
|
||||
sprintf(text, "0x%08X", val);
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_ARM9ROM), text);
|
||||
|
||||
val = T1ReadLong(MMU.CART_ROM, 0x24);
|
||||
val = T1ReadLong((u8*)&gameInfo.header, 0x24);
|
||||
sprintf(text, "0x%08X", val);
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_ARM9ENTRY), text);
|
||||
|
||||
val = T1ReadLong(MMU.CART_ROM, 0x28);
|
||||
val = T1ReadLong((u8*)&gameInfo.header, 0x28);
|
||||
sprintf(text, "0x%08X", val);
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_ARM9START), text);
|
||||
|
||||
val = T1ReadLong(MMU.CART_ROM, 0x2C);
|
||||
val = T1ReadLong((u8*)&gameInfo.header, 0x2C);
|
||||
sprintf(text, "%i bytes", val);
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_ARM9SIZE), text);
|
||||
|
||||
val = T1ReadLong(MMU.CART_ROM, 0x30);
|
||||
val = T1ReadLong((u8*)&gameInfo.header, 0x30);
|
||||
sprintf(text, "0x%08X", val);
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_ARM7ROM), text);
|
||||
|
||||
val = T1ReadLong(MMU.CART_ROM, 0x34);
|
||||
val = T1ReadLong((u8*)&gameInfo.header, 0x34);
|
||||
sprintf(text, "0x%08X", val);
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_ARM7ENTRY), text);
|
||||
|
||||
val = T1ReadLong(MMU.CART_ROM, 0x38);
|
||||
val = T1ReadLong((u8*)&gameInfo.header, 0x38);
|
||||
sprintf(text, "0x%08X", val);
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_ARM7START), text);
|
||||
|
||||
val = T1ReadLong(MMU.CART_ROM, 0x3C);
|
||||
val = T1ReadLong((u8*)&gameInfo.header, 0x3C);
|
||||
sprintf(text, "%i bytes", val);
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_ARM7SIZE), text);
|
||||
|
||||
|
||||
val = T1ReadLong(MMU.CART_ROM, 0x40);
|
||||
val = T1ReadLong((u8*)&gameInfo.header, 0x40);
|
||||
sprintf(text, "0x%08X", val);
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_FNTOFS), text);
|
||||
|
||||
val = T1ReadLong(MMU.CART_ROM, 0x44);
|
||||
val = T1ReadLong((u8*)&gameInfo.header, 0x44);
|
||||
sprintf(text, "%i bytes", val);
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_FNTSIZE), text);
|
||||
|
||||
val = T1ReadLong(MMU.CART_ROM, 0x48);
|
||||
val = T1ReadLong((u8*)&gameInfo.header, 0x48);
|
||||
sprintf(text, "0x%08X", val);
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_FATOFS), text);
|
||||
|
||||
val = T1ReadLong(MMU.CART_ROM, 0x4C);
|
||||
val = T1ReadLong((u8*)&gameInfo.header, 0x4C);
|
||||
sprintf(text, "%i bytes", val);
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_FATSIZE), text);
|
||||
|
||||
icontitleOffset = T1ReadLong(MMU.CART_ROM, 0x68);
|
||||
icontitleOffset = T1ReadLong((u8*)&gameInfo.header, 0x68);
|
||||
sprintf(text, "0x%08X", icontitleOffset);
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_ICONTITLEOFS), text);
|
||||
|
||||
val = T1ReadLong(MMU.CART_ROM, 0x80);
|
||||
val = T1ReadLong((u8*)&gameInfo.header, 0x80);
|
||||
sprintf(text, "0x%08X", val);
|
||||
SetWindowText(GetDlgItem(hDlg, IDC_GI_USEDROMSIZE), text);
|
||||
|
||||
|
||||
EndPaint(hDlg, &ps);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -2935,10 +2935,11 @@ int _main()
|
|||
|
||||
msgbox = &msgBoxWnd;
|
||||
|
||||
char text[80];
|
||||
char text[80] = {0};
|
||||
|
||||
path.ReadPathSettings();
|
||||
|
||||
CommonSettings.loadToMemory = GetPrivateProfileBool("General", "loadType", true, IniName);
|
||||
CommonSettings.cheatsDisable = GetPrivateProfileBool("General", "cheatsDisable", false, IniName);
|
||||
CommonSettings.autodetectBackupMethod = GetPrivateProfileInt("General", "autoDetectMethod", 0, IniName);
|
||||
|
||||
|
@ -3975,11 +3976,10 @@ void CloseRom()
|
|||
{
|
||||
StopAllLuaScripts();
|
||||
// cheatsSearchClose();
|
||||
NDS_FreeROM();
|
||||
romloaded = false;
|
||||
execute = false;
|
||||
Hud.resetTransient();
|
||||
NDS_Reset();
|
||||
NDS_FreeROM();
|
||||
|
||||
// clear screen so the last frame we rendered doesn't stick around
|
||||
// (TODO: maybe NDS_Reset should do this?)
|
||||
|
@ -4151,7 +4151,7 @@ void ScreenshotToClipboard(bool extraInfo)
|
|||
int exHeight = 0;
|
||||
if(extraInfo)
|
||||
{
|
||||
exHeight = (14 * (twolinever ? 7:6));
|
||||
exHeight = (14 * (twolinever ? 8:7));
|
||||
}
|
||||
|
||||
HDC hScreenDC = GetDC(NULL);
|
||||
|
@ -4196,21 +4196,19 @@ void ScreenshotToClipboard(bool extraInfo)
|
|||
else
|
||||
TextOut(hMemDC, 0, 384 + 14, nameandver, strlen(nameandver));
|
||||
|
||||
char str[32];
|
||||
memcpy(&str[0], &MMU.CART_ROM[0], 12); str[12] = '\0';
|
||||
int titlelen = strlen(str);
|
||||
str[titlelen] = ' ';
|
||||
memcpy(&str[titlelen+1], &MMU.CART_ROM[12], 6); str[titlelen+1+6] = '\0';
|
||||
TextOut(hMemDC, 8, 384 + 14 * (twolinever ? 3:2), str, strlen(str));
|
||||
char str[32] = {0};
|
||||
TextOut(hMemDC, 8, 384 + 14 * (twolinever ? 3:2), gameInfo.ROMname, strlen(gameInfo.ROMname));
|
||||
TextOut(hMemDC, 8, 384 + 14 * (twolinever ? 4:3), gameInfo.ROMserial, strlen(gameInfo.ROMserial));
|
||||
|
||||
|
||||
sprintf(str, "CPU: %s", CommonSettings.use_jit ? "JIT":"Interpreter");
|
||||
TextOut(hMemDC, 8, 384 + 14 * (twolinever ? 4:3), str, strlen(str));
|
||||
|
||||
sprintf(str, "FPS: %i/%i (%02d%%/%02d%%) | %s", mainLoopData.fps, mainLoopData.fps3d, Hud.cpuload[0], Hud.cpuload[1], paused ? "Paused":"Running");
|
||||
TextOut(hMemDC, 8, 384 + 14 * (twolinever ? 5:4), str, strlen(str));
|
||||
|
||||
sprintf(str, "3D Render: %s", core3DList[cur3DCore]->name);
|
||||
sprintf(str, "FPS: %i/%i (%02d%%/%02d%%) | %s", mainLoopData.fps, mainLoopData.fps3d, Hud.cpuload[0], Hud.cpuload[1], paused ? "Paused":"Running");
|
||||
TextOut(hMemDC, 8, 384 + 14 * (twolinever ? 6:5), str, strlen(str));
|
||||
|
||||
sprintf(str, "3D Render: %s", core3DList[cur3DCore]->name);
|
||||
TextOut(hMemDC, 8, 384 + 14 * (twolinever ? 7:6), str, strlen(str));
|
||||
}
|
||||
|
||||
OpenClipboard(NULL);
|
||||
|
@ -4404,6 +4402,9 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
|
||||
DesEnableMenuItem(mainMenu, IDC_BACKGROUNDINPUT, !lostFocusPause);
|
||||
|
||||
DesEnableMenuItem(mainMenu, ID_LOADTORAM, !romloaded);
|
||||
DesEnableMenuItem(mainMenu, ID_STREAMFROMDISK, !romloaded);
|
||||
|
||||
//Update savestate slot items based on ROM loaded
|
||||
for (int x = 0; x < 10; x++)
|
||||
{
|
||||
|
@ -4556,6 +4557,10 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
|
|||
DesEnableMenuItem(mainMenu, IDM_SCREENSEP_COLORBLACK, false);
|
||||
}
|
||||
|
||||
// load type
|
||||
MainWindow->checkMenu(ID_STREAMFROMDISK, ((CommonSettings.loadToMemory == false)));
|
||||
MainWindow->checkMenu(ID_LOADTORAM, ((CommonSettings.loadToMemory == true)));
|
||||
|
||||
// Tools
|
||||
MainWindow->checkMenu(IDM_CONSOLE_ALWAYS_ON_TOP, gConsoleTopmost);
|
||||
|
||||
|
@ -5585,6 +5590,11 @@ DOKEYDOWN:
|
|||
return 0;
|
||||
|
||||
case ID_TOOLS_VIEWFSNITRO:
|
||||
if (!CommonSettings.loadToMemory)
|
||||
{
|
||||
msgbox->error("Change load type to \"Load to RAM\"");
|
||||
return 0;
|
||||
}
|
||||
ViewFSNitro->open();
|
||||
return 0;
|
||||
//========================================================== Tools end
|
||||
|
@ -5800,6 +5810,16 @@ DOKEYDOWN:
|
|||
ResetGame();
|
||||
return 0;
|
||||
|
||||
case ID_STREAMFROMDISK:
|
||||
CommonSettings.loadToMemory = false;
|
||||
WritePrivateProfileBool("General", "loadType", CommonSettings.loadToMemory, IniName);
|
||||
return 0;
|
||||
|
||||
case ID_LOADTORAM:
|
||||
CommonSettings.loadToMemory = true;
|
||||
WritePrivateProfileBool("General", "loadType", CommonSettings.loadToMemory, IniName);
|
||||
return 0;
|
||||
|
||||
case IDM_3DCONFIG:
|
||||
{
|
||||
bool tpaused = false;
|
||||
|
|
|
@ -82,7 +82,7 @@ u8 memRead8 (MemRegionType regionType, HWAddressType address)
|
|||
return value;
|
||||
case MEMVIEW_ROM:
|
||||
if (address < gameInfo.romsize)
|
||||
value = MMU.CART_ROM[address];
|
||||
value = gameInfo.romdata[address];
|
||||
return value;
|
||||
case MEMVIEW_FULL:
|
||||
MMU_DumpMemBlock(0, address, 1, &value);
|
||||
|
@ -113,7 +113,7 @@ u16 memRead16 (MemRegionType regionType, HWAddressType address)
|
|||
return value;
|
||||
case MEMVIEW_ROM:
|
||||
if (address < (gameInfo.romsize - 2))
|
||||
value = T1ReadWord(MMU.CART_ROM, address);
|
||||
value = T1ReadWord(gameInfo.romdata, address);
|
||||
return value;
|
||||
case MEMVIEW_FULL:
|
||||
MMU_DumpMemBlock(0, address, 2, (u8*)&value);
|
||||
|
@ -144,7 +144,8 @@ u32 memRead32 (MemRegionType regionType, HWAddressType address)
|
|||
return value;
|
||||
case MEMVIEW_ROM:
|
||||
if (address < (gameInfo.romsize - 4))
|
||||
value = T1ReadLong(MMU.CART_ROM, address);
|
||||
value = T1ReadLong(gameInfo.romdata, address);
|
||||
|
||||
return value;
|
||||
case MEMVIEW_FULL:
|
||||
MMU_DumpMemBlock(0, address, 4, (u8*)&value);
|
||||
|
@ -197,7 +198,7 @@ void memWrite8(MemRegionType regionType, HWAddressType address, u8 value)
|
|||
MMU.fw.data[address] = value;
|
||||
break;
|
||||
case MEMVIEW_ROM:
|
||||
MMU.CART_ROM[address] = value;
|
||||
gameInfo.romdata[address] = value;
|
||||
break;
|
||||
case MEMVIEW_FULL:
|
||||
MMU_write8(ARMCPU_ARM9, address, value);
|
||||
|
@ -220,7 +221,7 @@ void memWrite16(MemRegionType regionType, HWAddressType address, u16 value)
|
|||
*((u16*)&MMU.fw.data[address]) = value;
|
||||
break;
|
||||
case MEMVIEW_ROM:
|
||||
*((u16*)&MMU.CART_ROM[address]) = value;
|
||||
*((u16*)&gameInfo.romdata[address]) = value;
|
||||
break;
|
||||
case MEMVIEW_FULL:
|
||||
MMU_write16(ARMCPU_ARM9, address, value);
|
||||
|
@ -243,7 +244,7 @@ void memWrite32(MemRegionType regionType, HWAddressType address, u32 value)
|
|||
*((u32*)&MMU.fw.data[address]) = value;
|
||||
break;
|
||||
case MEMVIEW_ROM:
|
||||
*((u32*)&MMU.CART_ROM[address]) = value;
|
||||
*((u32*)&gameInfo.romdata[address]) = value;
|
||||
break;
|
||||
case MEMVIEW_FULL:
|
||||
MMU_write32(ARMCPU_ARM9, address, value);
|
||||
|
@ -271,8 +272,9 @@ CMemView::CMemView(MemRegionType memRegion, u32 start_address)
|
|||
s_memoryRegions.push_back(s_arm9Region);
|
||||
s_memoryRegions.push_back(s_arm7Region);
|
||||
s_memoryRegions.push_back(s_firmwareRegion);
|
||||
s_memoryRegions.push_back(s_RomRegion);
|
||||
s_memoryRegions.push_back(s_fullRegion);
|
||||
if (CommonSettings.loadToMemory)
|
||||
s_memoryRegions.push_back(s_RomRegion);
|
||||
}
|
||||
|
||||
PostInitialize();
|
||||
|
|
|
@ -934,8 +934,11 @@
|
|||
#define IDC_VIEW_PADTOINTEGER 40107
|
||||
#define ID_TOOLS_VIEWFSNITRO 40108
|
||||
#define ID_EXTRACTFILE 40109
|
||||
#define ID_CONFIG_LOADROMTYPE 40109
|
||||
#define ID_EXTRACTALL 40110
|
||||
#define ID_LOADTORAM 40110
|
||||
#define ID_CLOSE 40111
|
||||
#define ID_STREAMFROMDISK 40111
|
||||
#define ID_FSNITRO_VIEW 40112
|
||||
#define ID_LABEL_HK3b 44670
|
||||
#define ID_LABEL_HK3c 44671
|
||||
|
@ -1043,7 +1046,7 @@
|
|||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NO_MFC 1
|
||||
#define _APS_NEXT_RESOURCE_VALUE 128
|
||||
#define _APS_NEXT_COMMAND_VALUE 40109
|
||||
#define _APS_NEXT_COMMAND_VALUE 40111
|
||||
#define _APS_NEXT_CONTROL_VALUE 1057
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue