win32: load archives without temp files

This commit is contained in:
p989 2009-07-19 21:42:15 +00:00
parent 488fc951d0
commit 2a90946ff5
6 changed files with 142 additions and 13 deletions

View File

@ -730,7 +730,136 @@ void GameInfo::populate()
memset(ROMserial+19, '\0', 1);
}
}
#ifdef WIN32
#include "memorystream.h"
#include <fstream>
static std::vector<char> buffer;
static std::vector<char> v;
static void loadrom(std::vector<char>* buf, std::string fname) {
memorystream ms(buf);
std::ostream* os = (std::ostream*)&ms;
std::ifstream fl(fname.c_str());
if (!fl.is_open())
return;
fl.seekg( 0, std::ios::end );
int size = fl.tellg();
std::filebuf fb;
fb.open (fname.c_str(), std::ios::in | std::ios::binary);
std::istream is(&fb);
char *buffer = new char[size];
is.read(buffer, size);
ms.write((char*)buffer,size);
fb.close();
ms.trim();
gameInfo.romdata = &buffer[0];
}
int NDS_LoadROM(const char *filename, const char *logicalFilename)
{
int type;
u32 mask;
char buf[MAX_PATH];
if (filename == NULL)
return -1;
path.init(filename);
if ( path.isdsgba(path.path)) {
type = ROM_DSGBA;
loadrom(&buffer, path.path);
gameInfo.romsize = buffer.size();
}
else if ( !strcasecmp(path.extension().c_str(), "nds")) {
loadrom(&buffer, path.path);
gameInfo.romsize = buffer.size();
type = ROM_NDS;
}
//ds.gba in archives, it's already been loaded into memory at this point
else if (path.isdsgba(std::string(logicalFilename))) {
std::vector<char> v(gameInfo.romdata, gameInfo.romdata + gameInfo.romsize);
v.erase(v.begin(),v.begin()+DSGBA_LOADER_SIZE);
buffer.assign( v.begin(), v.end() );
gameInfo.romdata = &buffer[0];
gameInfo.romsize = buffer.size();
}
if(type == ROM_DSGBA)
{
buffer.erase(buffer.begin(),buffer.begin()+DSGBA_LOADER_SIZE);
gameInfo.romdata = &buffer[0];
gameInfo.romsize = buffer.size();
}
//check that size is at least the size of the header
if (gameInfo.romsize < 352+160) {
return -1;
}
//zero 25-dec-08 - this used to yield a mask which was 2x large
//mask = size;
mask = gameInfo.romsize-1;
mask |= (mask >>1);
mask |= (mask >>2);
mask |= (mask >>4);
mask |= (mask >>8);
mask |= (mask >>16);
//decrypt if necessary..
//but this is untested and suspected to fail on big endian, so lets not support this on big endian
#ifndef WORDS_BIGENDIAN
bool okRom = DecryptSecureArea((u8*)gameInfo.romdata,gameInfo.romsize);
if(!okRom) {
printf("Specified file is not a valid rom\n");
return -1;
}
#endif
cheatsSearchClose();
MMU_unsetRom();
NDS_SetROM((u8*)gameInfo.romdata, mask);
NDS_Reset();
memset(buf, 0, MAX_PATH);
path.getpathnoext(path.BATTERY, buf);
strcat(buf, ".dsv"); // DeSmuME memory card :)
MMU_new.backupDevice.load_rom(buf);
memset(buf, 0, MAX_PATH);
path.getpathnoext(path.CHEATS, buf);
strcat(buf, ".dct"); // DeSmuME cheat :)
cheatsInit(buf);
gameInfo.populate();
gameInfo.crc = crc32(0,(u8*)gameInfo.romdata,gameInfo.romsize);
INFO("\nROM crc: %08X\n\n", gameInfo.crc);
INFO("\nROM serial: %s\n", gameInfo.ROMserial);
return 1;
}
#else
int NDS_LoadROM(const char *filename, const char *logicalFilename)
{
int ret;
@ -847,7 +976,7 @@ int NDS_LoadROM(const char *filename, const char *logicalFilename)
return ret;
}
#endif
void NDS_FreeROM(void)
{
if (MMU.CART_ROM != MMU.UNUSED_RAM)

View File

@ -280,6 +280,8 @@ struct GameInfo
NDS_header header;
char ROMserial[20];
void populate();
char* romdata;
int romsize;
};
extern GameInfo gameInfo;

View File

@ -347,8 +347,7 @@ public:
else return RomName;
}
bool isdsgba() {
std::string str = path;
bool isdsgba(std::string str) {
int x = str.find_last_of(".");
if (x > 0)
str = str.substr(x-2);
@ -358,4 +357,4 @@ public:
}
};
extern PathInfo path;
extern PathInfo path;

View File

@ -351,7 +351,11 @@ int ArchiveFile::ExtractItem(int index, const char* outFilename) const
InFileStream* ifs = new InFileStream(m_filename);
if(SUCCEEDED(object->Open(ifs,0,0)))
{
OutStream* os = new OutStream(index, outFilename);
if(gameInfo.romdata != NULL)
delete[] gameInfo.romdata;
gameInfo.romdata = new char[rv];
gameInfo.romsize = rv;
OutStream* os = new OutStream(index, gameInfo.romdata, rv);
const UInt32 indices [1] = {index};
hr = object->Extract(indices, 1, 0, os);
object->Close();

View File

@ -1,6 +1,8 @@
#ifndef _7ZIP_DEC_HEADER
#define _7ZIP_DEC_HEADER
#include "NDSSystem.h"
// 7zip file extraction
// NOTE: if you want to add support for opening files within archives to some part of Gens,
// consider using the higher-level interface provided by OpenArchive.h instead

View File

@ -2094,13 +2094,6 @@ void OpenRecentROM(int listNum)
static BOOL OpenCore(const char* filename)
{
if(!strcmp(getExtension(filename).c_str(), "gz") || !strcmp(getExtension(filename).c_str(), "nds.gz")) {
if(LoadROM(filename,filename)) {
NDS_UnPause();
return FALSE;
}
}
char LogicalName[1024], PhysicalName[1024];
const char* s_nonRomExtensions [] = {"txt", "nfo", "htm", "html", "jpg", "jpeg", "png", "bmp", "gif", "mp3", "wav", "lnk", "exe", "bat", "gmv", "gm2", "lua", "luasav", "sav", "srm", "brm", "cfg", "wch", "gs*"};
@ -2108,7 +2101,7 @@ static BOOL OpenCore(const char* filename)
if(!ObtainFile(filename, LogicalName, PhysicalName, "rom", s_nonRomExtensions, ARRAY_SIZE(s_nonRomExtensions)))
return FALSE;
if(LoadROM(PhysicalName, LogicalName))
if(LoadROM(filename, LogicalName))
{
romloaded = TRUE;
NDS_UnPause();