dont read every archive file when scanning for replay. scan them, though, and look only for *.fm2

This commit is contained in:
zeromus 2008-08-17 19:02:19 +00:00
parent 8da54eff69
commit 4bd3881f1b
3 changed files with 89 additions and 39 deletions

View File

@ -15,6 +15,8 @@
#include "driver.h"
#include "main.h"
static FCEUARCHIVEFILEINFO *currFileSelectorContext;
DEFINE_GUID(CLSID_CFormat_07,0x23170F69,0x40C1,0x278A,0x10,0x00,0x00,0x01,0x10,0x07,0x00,0x00);
class OutStream : public IArchiveExtractCallback
@ -280,17 +282,6 @@ public:
}
};
struct FileSelectorContext
{
struct Item
{
std::string name;
uint32 size, index;
};
std::vector<Item> items;
} *currFileSelectorContext;
static BOOL CALLBACK ArchiveFileSelectorCallback(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
@ -436,14 +427,53 @@ ArchiveScanRecord FCEUD_ScanArchive(std::string fname)
if (SUCCEEDED(object->Open(&ifs,0,0)))
{
uint32 numFiles;
if (SUCCEEDED(object->GetNumberOfItems(&numFiles)))
{
ArchiveScanRecord asr(matchingFormat,(int)numFiles);
//scan the filename of each item
for(uint32 i=0;i<numFiles;i++)
{
FCEUARCHIVEFILEINFO::Item item;
item.index = i;
PROPVARIANT prop;
prop.vt = VT_EMPTY;
if (FAILED(object->GetProperty( i, kpidSize, &prop )) || prop.vt != VT_UI8 || !prop.uhVal.LowPart || prop.uhVal.HighPart)
goto bomb;
item.size = prop.uhVal.LowPart;
if (FAILED(object->GetProperty( i, kpidPath, &prop )) || prop.vt != VT_BSTR || prop.bstrVal == NULL)
goto bomb;
std::wstring tempfname = prop.bstrVal;
int buflen = tempfname.size()*2;
char* buf = new char[buflen];
int ret = WideCharToMultiByte(CP_ACP,0,tempfname.c_str(),tempfname.size(),buf,buflen,0,0);
if(ret == 0) {
delete[] buf;
::VariantClear( reinterpret_cast<VARIANTARG*>(&prop) );
continue;
}
buf[ret] = 0;
item.name = buf;
delete[] buf;
::VariantClear( reinterpret_cast<VARIANTARG*>(&prop) );
asr.files.items.push_back(item);
}
object->Release();
return ArchiveScanRecord(matchingFormat,(int)numFiles);
return asr;
}
}
}
bomb:
object->Release();
return ArchiveScanRecord();
@ -451,6 +481,8 @@ ArchiveScanRecord FCEUD_ScanArchive(std::string fname)
extern HWND hAppWnd;
//TODO - factor out the filesize and name extraction code from below (it is already done once above)
static FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename, int innerIndex)
{
FCEUFILE* fp = 0;
@ -479,12 +511,12 @@ static FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, s
uint32 numFiles;
if (SUCCEEDED(object->GetNumberOfItems(&numFiles)))
{
FileSelectorContext fileSelectorContext;
FCEUARCHIVEFILEINFO fileSelectorContext;
currFileSelectorContext = &fileSelectorContext;
for(uint32 i=0;i<numFiles;i++)
{
FileSelectorContext::Item item;
FCEUARCHIVEFILEINFO::Item item;
item.index = i;
PROPVARIANT prop;
@ -509,19 +541,7 @@ static FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, s
}
else
{
std::wstring tempfname = prop.bstrVal;
int buflen = tempfname.size()*2;
char* buf = new char[buflen];
int ret = WideCharToMultiByte(CP_ACP,0,tempfname.c_str(),tempfname.size(),buf,buflen,0,0);
if(ret == 0) {
delete[] buf;
::VariantClear( reinterpret_cast<VARIANTARG*>(&prop) );
continue;
}
buf[ret] = 0;
item.name = buf;
delete[] buf;
}
::VariantClear( reinterpret_cast<VARIANTARG*>(&prop) );
@ -548,7 +568,7 @@ static FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, s
if(ret != LB_ERR)
{
FileSelectorContext::Item& item = fileSelectorContext.items[ret];
FCEUARCHIVEFILEINFO::Item& item = fileSelectorContext.items[ret];
memorystream* ms = new memorystream(item.size);
OutStream outStream( item.index, ms->buf(), item.size);
const uint32 indices[1] = {item.index};

View File

@ -399,6 +399,21 @@ void HandleScan(HWND hwndDlg, FCEUFILE* file, int& i)
SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_INSERTSTRING, i++, (LPARAM)relative);
}
//TODO - dont we already have another function that can do this
std::string getExtension(const char* input) {
char buf[1024];
strcpy(buf,input);
char* dot=strrchr(buf,'.');
if(!dot)
return "";
char ext [512];
strcpy(ext, dot+1);
int k, extlen=strlen(ext);
for(k=0;k<extlen;k++)
ext[k]=tolower(ext[k]);
return ext;
}
BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
@ -465,21 +480,16 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
continue;
//TODO - a big copy/pasted block below. factor out extension extractor or use another one
// filter out everything that's not an extension we like *.fm2
// (because FindFirstFile is too dumb to do that)
{
char* dot=strrchr(wfd.cFileName,'.');
if(!dot)
continue;
char ext [512];
strcpy(ext, dot+1);
int k, extlen=strlen(ext);
for(k=0;k<extlen;k++)
ext[k]=tolower(ext[k]);
if(stricmp(ext,"fm2"))
if(stricmp(ext,"zip"))
if(stricmp(ext,"rar"))
if(stricmp(ext,"7z"))
std::string ext = getExtension(wfd.cFileName);
if(ext != "fm2")
if(ext != "zip")
if(ext != "rar")
if(ext != "7z")
continue;
}
@ -491,6 +501,9 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
ArchiveScanRecord asr = FCEUD_ScanArchive(filename);
if(asr.numFiles>1) {
for(int i=0;i<asr.numFiles;i++) {
std::string ext = getExtension(asr.files.items[i].name.c_str());
if(ext != "fm2")
continue;
FCEUFILE* fp = FCEU_fopen(filename,0,"rb",0,i);
if(fp) {
HandleScan(hwndDlg,fp, items);
@ -499,6 +512,11 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
}
} else
{
if(asr.numFiles == 1) {
std::string ext = getExtension(asr.files.items[0].name.c_str());
if(ext != "fm2")
continue;
}
FCEUFILE* fp = FCEU_fopen(filename,0,"rb",0);
if(fp) {
HandleScan(hwndDlg,fp ,items);

View File

@ -71,6 +71,16 @@ struct FCEUFILE {
}
};
struct FCEUARCHIVEFILEINFO
{
struct Item
{
std::string name;
uint32 size, index;
};
std::vector<Item> items;
};
struct FileBaseInfo {
std::string filebase, filebasedirectory, ext;
FileBaseInfo() {}
@ -97,6 +107,8 @@ struct ArchiveScanRecord
int type;
int numFiles;
FCEUARCHIVEFILEINFO files;
bool isArchive() { return type != -1; }
};