dont read every archive file when scanning for replay. scan them, though, and look only for *.fm2
This commit is contained in:
parent
8da54eff69
commit
4bd3881f1b
|
@ -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};
|
||||
|
|
|
@ -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);
|
||||
|
|
12
src/file.h
12
src/file.h
|
@ -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; }
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue