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 "driver.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
|
static FCEUARCHIVEFILEINFO *currFileSelectorContext;
|
||||||
|
|
||||||
DEFINE_GUID(CLSID_CFormat_07,0x23170F69,0x40C1,0x278A,0x10,0x00,0x00,0x01,0x10,0x07,0x00,0x00);
|
DEFINE_GUID(CLSID_CFormat_07,0x23170F69,0x40C1,0x278A,0x10,0x00,0x00,0x01,0x10,0x07,0x00,0x00);
|
||||||
|
|
||||||
class OutStream : public IArchiveExtractCallback
|
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)
|
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)))
|
if (SUCCEEDED(object->Open(&ifs,0,0)))
|
||||||
{
|
{
|
||||||
uint32 numFiles;
|
uint32 numFiles;
|
||||||
|
|
||||||
if (SUCCEEDED(object->GetNumberOfItems(&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();
|
object->Release();
|
||||||
return ArchiveScanRecord(matchingFormat,(int)numFiles);
|
return asr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bomb:
|
||||||
object->Release();
|
object->Release();
|
||||||
|
|
||||||
return ArchiveScanRecord();
|
return ArchiveScanRecord();
|
||||||
|
@ -451,6 +481,8 @@ ArchiveScanRecord FCEUD_ScanArchive(std::string fname)
|
||||||
|
|
||||||
extern HWND hAppWnd;
|
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)
|
static FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename, int innerIndex)
|
||||||
{
|
{
|
||||||
FCEUFILE* fp = 0;
|
FCEUFILE* fp = 0;
|
||||||
|
@ -479,12 +511,12 @@ static FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, s
|
||||||
uint32 numFiles;
|
uint32 numFiles;
|
||||||
if (SUCCEEDED(object->GetNumberOfItems(&numFiles)))
|
if (SUCCEEDED(object->GetNumberOfItems(&numFiles)))
|
||||||
{
|
{
|
||||||
FileSelectorContext fileSelectorContext;
|
FCEUARCHIVEFILEINFO fileSelectorContext;
|
||||||
currFileSelectorContext = &fileSelectorContext;
|
currFileSelectorContext = &fileSelectorContext;
|
||||||
|
|
||||||
for(uint32 i=0;i<numFiles;i++)
|
for(uint32 i=0;i<numFiles;i++)
|
||||||
{
|
{
|
||||||
FileSelectorContext::Item item;
|
FCEUARCHIVEFILEINFO::Item item;
|
||||||
item.index = i;
|
item.index = i;
|
||||||
|
|
||||||
PROPVARIANT prop;
|
PROPVARIANT prop;
|
||||||
|
@ -509,19 +541,7 @@ static FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, s
|
||||||
}
|
}
|
||||||
else
|
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) );
|
::VariantClear( reinterpret_cast<VARIANTARG*>(&prop) );
|
||||||
|
@ -548,7 +568,7 @@ static FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, s
|
||||||
|
|
||||||
if(ret != LB_ERR)
|
if(ret != LB_ERR)
|
||||||
{
|
{
|
||||||
FileSelectorContext::Item& item = fileSelectorContext.items[ret];
|
FCEUARCHIVEFILEINFO::Item& item = fileSelectorContext.items[ret];
|
||||||
memorystream* ms = new memorystream(item.size);
|
memorystream* ms = new memorystream(item.size);
|
||||||
OutStream outStream( item.index, ms->buf(), item.size);
|
OutStream outStream( item.index, ms->buf(), item.size);
|
||||||
const uint32 indices[1] = {item.index};
|
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);
|
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)
|
BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
switch(uMsg)
|
switch(uMsg)
|
||||||
|
@ -465,21 +480,16 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
|
||||||
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
continue;
|
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
|
// filter out everything that's not an extension we like *.fm2
|
||||||
// (because FindFirstFile is too dumb to do that)
|
// (because FindFirstFile is too dumb to do that)
|
||||||
{
|
{
|
||||||
char* dot=strrchr(wfd.cFileName,'.');
|
std::string ext = getExtension(wfd.cFileName);
|
||||||
if(!dot)
|
if(ext != "fm2")
|
||||||
continue;
|
if(ext != "zip")
|
||||||
char ext [512];
|
if(ext != "rar")
|
||||||
strcpy(ext, dot+1);
|
if(ext != "7z")
|
||||||
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"))
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,6 +501,9 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
|
||||||
ArchiveScanRecord asr = FCEUD_ScanArchive(filename);
|
ArchiveScanRecord asr = FCEUD_ScanArchive(filename);
|
||||||
if(asr.numFiles>1) {
|
if(asr.numFiles>1) {
|
||||||
for(int i=0;i<asr.numFiles;i++) {
|
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);
|
FCEUFILE* fp = FCEU_fopen(filename,0,"rb",0,i);
|
||||||
if(fp) {
|
if(fp) {
|
||||||
HandleScan(hwndDlg,fp, items);
|
HandleScan(hwndDlg,fp, items);
|
||||||
|
@ -499,6 +512,11 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
|
||||||
}
|
}
|
||||||
} else
|
} 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);
|
FCEUFILE* fp = FCEU_fopen(filename,0,"rb",0);
|
||||||
if(fp) {
|
if(fp) {
|
||||||
HandleScan(hwndDlg,fp ,items);
|
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 {
|
struct FileBaseInfo {
|
||||||
std::string filebase, filebasedirectory, ext;
|
std::string filebase, filebasedirectory, ext;
|
||||||
FileBaseInfo() {}
|
FileBaseInfo() {}
|
||||||
|
@ -97,6 +107,8 @@ struct ArchiveScanRecord
|
||||||
int type;
|
int type;
|
||||||
int numFiles;
|
int numFiles;
|
||||||
|
|
||||||
|
FCEUARCHIVEFILEINFO files;
|
||||||
|
|
||||||
bool isArchive() { return type != -1; }
|
bool isArchive() { return type != -1; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue