first attempt - support loading movies from archives.
This commit is contained in:
parent
9d0e6ecb9e
commit
3a0b893662
|
@ -451,7 +451,7 @@ ArchiveScanRecord FCEUD_ScanArchive(std::string fname)
|
|||
|
||||
extern HWND hAppWnd;
|
||||
|
||||
FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename)
|
||||
FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename, int innerIndex)
|
||||
{
|
||||
FCEUFILE* fp = 0;
|
||||
|
||||
|
@ -530,10 +530,10 @@ FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::str
|
|||
|
||||
//try to load the file directly if we're in autopilot
|
||||
int ret = LB_ERR;
|
||||
if(innerFilename)
|
||||
if(innerFilename || innerIndex != -1)
|
||||
{
|
||||
for(uint32 i=0;i<fileSelectorContext.items.size();i++)
|
||||
if(fileSelectorContext.items[i].name == *innerFilename)
|
||||
if(i == (uint32)innerIndex || (innerFilename && fileSelectorContext.items[i].name == *innerFilename))
|
||||
{
|
||||
ret = i;
|
||||
break;
|
||||
|
@ -559,6 +559,7 @@ FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::str
|
|||
fp = new FCEUFILE();
|
||||
fp->archiveFilename = fname;
|
||||
fp->filename = fileSelectorContext.items[ret].name;
|
||||
fp->fullFilename = fp->archiveFilename + "|" + fp->filename;
|
||||
fp->archiveIndex = ret;
|
||||
fp->mode = FCEUFILE::READ;
|
||||
fp->size = fileSelectorContext.items[ret].size;
|
||||
|
@ -579,4 +580,14 @@ FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::str
|
|||
}
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
FCEUFILE* FCEUD_OpenArchiveIndex(ArchiveScanRecord& asr, std::string& fname, int innerIndex)
|
||||
{
|
||||
return FCEUD_OpenArchive(asr, fname, 0, innerIndex);
|
||||
}
|
||||
|
||||
FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename)
|
||||
{
|
||||
return FCEUD_OpenArchive(asr, fname, innerFilename, -1);
|
||||
}
|
|
@ -12,6 +12,8 @@ void initArchiveSystem();
|
|||
//if you want to autopilot this, pass in an innerfilename to try and automatically load
|
||||
FCEUFILE* FCEUD_OpenArchive(ArchiveScanRecord& asr, std::string& fname, std::string* innerFilename);
|
||||
|
||||
FCEUFILE* FCEUD_OpenArchiveIndex(ArchiveScanRecord& asr, std::string& fname, int innerIndex);
|
||||
|
||||
//scans a file to see if it is an archive you can handle
|
||||
ArchiveScanRecord FCEUD_ScanArchive(std::string fname);
|
||||
|
||||
|
|
|
@ -644,7 +644,11 @@ int main(int argc,char *argv[])
|
|||
|
||||
if(GameInfo && MovieToLoad)
|
||||
{
|
||||
FCEUI_LoadMovie(MovieToLoad, replayReadOnlySetting!=0, false, replayStopFrameSetting!=0);
|
||||
//switch to readonly mode if the file is an archive
|
||||
if(FCEU_isFileInArchive(MovieToLoad))
|
||||
replayReadOnlySetting = true;
|
||||
|
||||
FCEUI_LoadMovie(MovieToLoad, replayReadOnlySetting, false, replayStopFrameSetting!=0);
|
||||
free(MovieToLoad);
|
||||
MovieToLoad = NULL;
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "main.h"
|
||||
#include "window.h"
|
||||
#include "movie.h"
|
||||
#include "archive.h"
|
||||
|
||||
// Used when deciding to automatically make the stop movie checkbox checked
|
||||
static bool stopframeWasEditedByUser = false;
|
||||
|
@ -115,7 +116,11 @@ void UpdateReplayDialog(HWND hwndDlg)
|
|||
{
|
||||
MOVIE_INFO info;
|
||||
|
||||
if(FCEUI_MovieGetInfo(fn, &info, false))
|
||||
FCEUFILE* fp = FCEU_fopen(fn,0,"rb",0);
|
||||
bool isarchive = FCEU_isFileInArchive(fn);
|
||||
bool ismovie = FCEUI_MovieGetInfo(fp, &info, false);
|
||||
delete fp;
|
||||
if(ismovie)
|
||||
{
|
||||
char tmp[256];
|
||||
uint32 div;
|
||||
|
@ -139,6 +144,12 @@ void UpdateReplayDialog(HWND hwndDlg)
|
|||
|
||||
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_RECORDEDFROM),info.poweron ? "Power-On" : (info.reset?"Soft-Reset":"Savestate"));
|
||||
|
||||
if(isarchive) {
|
||||
EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK_READONLY),FALSE);
|
||||
Button_SetCheck(GetDlgItem(hwndDlg,IDC_CHECK_READONLY),BST_CHECKED);
|
||||
} else
|
||||
EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK_READONLY),TRUE);
|
||||
|
||||
//-----------
|
||||
//mbg 5/26/08 - getting rid of old movie formats
|
||||
|
||||
|
@ -321,6 +332,54 @@ BOOL CALLBACK ReplayMetadataDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, L
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
extern char FileBase[];
|
||||
|
||||
void HandleScan(HWND hwndDlg, FCEUFILE* file, int& i)
|
||||
{
|
||||
MOVIE_INFO info;
|
||||
|
||||
bool scanok = FCEUI_MovieGetInfo(file, &info, true);
|
||||
if(!scanok)
|
||||
return;
|
||||
|
||||
//------------
|
||||
//attempt to match the movie with the rom
|
||||
//first, try matching md5
|
||||
//then try matching base name
|
||||
char md51 [256];
|
||||
char md52 [256];
|
||||
strcpy(md51, md5_asciistr(GameInfo->MD5));
|
||||
strcpy(md52, md5_asciistr(info.md5_of_rom_used));
|
||||
if(strcmp(md51, md52))
|
||||
{
|
||||
unsigned int k, count1=0, count2=0; //mbg merge 7/17/06 changed to uint
|
||||
for(k=0;k<strlen(md51);k++) count1 += md51[k]-'0';
|
||||
for(k=0;k<strlen(md52);k++) count2 += md52[k]-'0';
|
||||
if(count1 && count2)
|
||||
return;
|
||||
|
||||
const char* tlen1=strstr(file->filename.c_str(), " (");
|
||||
const char* tlen2=strstr(FileBase, " (");
|
||||
int tlen3=tlen1?(int)(tlen1-file->filename.c_str()):file->filename.size();
|
||||
int tlen4=tlen2?(int)(tlen2-FileBase):strlen(FileBase);
|
||||
int len=MAX(0,MIN(tlen3,tlen4));
|
||||
if(strnicmp(file->filename.c_str(), FileBase, len))
|
||||
{
|
||||
char temp[512];
|
||||
strcpy(temp,FileBase);
|
||||
temp[len]='\0';
|
||||
if(!strstr(file->filename.c_str(), temp))
|
||||
return;
|
||||
}
|
||||
}
|
||||
//-------------
|
||||
//if we get here, then we had a match
|
||||
|
||||
char relative[MAX_PATH];
|
||||
AbsoluteToRelative(relative, file->fullFilename.c_str(), BaseDirectory.c_str());
|
||||
SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_INSERTSTRING, i++, (LPARAM)relative);
|
||||
}
|
||||
|
||||
BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(uMsg)
|
||||
|
@ -345,9 +404,9 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
char* findGlob[2] = {strdup(FCEU_MakeFName(FCEUMKF_MOVIEGLOB, 0, 0).c_str()),
|
||||
strdup(FCEU_MakeFName(FCEUMKF_MOVIEGLOB2, 0, 0).c_str())};
|
||||
|
||||
int i=0, j=0;
|
||||
int items=0;
|
||||
|
||||
for(j=0;j<2;j++)
|
||||
for(int j=0;j<2;j++)
|
||||
{
|
||||
char* temp=0;
|
||||
do {
|
||||
|
@ -364,7 +423,7 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
// FCEU_PrintError(findGlob[0]);
|
||||
// FCEU_PrintError(findGlob[1]);
|
||||
|
||||
for(j=0;j<2;j++)
|
||||
for(int j=0;j<2;j++)
|
||||
{
|
||||
// if the two directories are the same, only look through one of them to avoid adding everything twice
|
||||
if(j==1 && !strnicmp(findGlob[0],findGlob[1],MAX(strlen(findGlob[0]),strlen(findGlob[1]))-6))
|
||||
|
@ -374,7 +433,6 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
strcpy(globBase,findGlob[j]);
|
||||
globBase[strlen(globBase)-5]='\0';
|
||||
|
||||
extern char FileBase[];
|
||||
//char szFindPath[512]; //mbg merge 7/17/06 removed
|
||||
WIN32_FIND_DATA wfd;
|
||||
HANDLE hFind;
|
||||
|
@ -388,7 +446,7 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
continue;
|
||||
|
||||
// filter out everything that's not *.fm2
|
||||
// filter out everything that's not an extension we like *.fm2
|
||||
// (because FindFirstFile is too dumb to do that)
|
||||
{
|
||||
char* dot=strrchr(wfd.cFileName,'.');
|
||||
|
@ -399,56 +457,36 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
int k, extlen=strlen(ext);
|
||||
for(k=0;k<extlen;k++)
|
||||
ext[k]=tolower(ext[k]);
|
||||
if(strcmp(ext,"fm2"))
|
||||
continue;
|
||||
if(stricmp(ext,"fm2"))
|
||||
if(stricmp(ext,"zip"))
|
||||
if(stricmp(ext,"rar"))
|
||||
if(stricmp(ext,"7z"))
|
||||
continue;
|
||||
}
|
||||
|
||||
MOVIE_INFO info;
|
||||
|
||||
char filename [512];
|
||||
sprintf(filename, "%s%s", globBase, wfd.cFileName);
|
||||
|
||||
char* dot = strrchr(filename, '.');
|
||||
|
||||
if(!FCEUI_MovieGetInfo(filename, &info, true))
|
||||
continue;
|
||||
|
||||
//------------
|
||||
//attempt to match the movie with the rom
|
||||
//first, try matching md5
|
||||
//then try matching base name
|
||||
char md51 [256];
|
||||
char md52 [256];
|
||||
strcpy(md51, md5_asciistr(GameInfo->MD5));
|
||||
strcpy(md52, md5_asciistr(info.md5_of_rom_used));
|
||||
if(strcmp(md51, md52))
|
||||
ArchiveScanRecord asr = FCEUD_ScanArchive(filename);
|
||||
if(asr.numFiles>1) {
|
||||
for(int i=0;i<asr.numFiles;i++) {
|
||||
FCEUFILE* fp = FCEU_fopen(filename,0,"rb",0,i);
|
||||
if(fp) {
|
||||
HandleScan(hwndDlg,fp, items);
|
||||
delete fp;
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
unsigned int k, count1=0, count2=0; //mbg merge 7/17/06 changed to uint
|
||||
for(k=0;k<strlen(md51);k++) count1 += md51[k]-'0';
|
||||
for(k=0;k<strlen(md52);k++) count2 += md52[k]-'0';
|
||||
if(count1 && count2)
|
||||
continue;
|
||||
|
||||
char* tlen1=strstr(wfd.cFileName, " (");
|
||||
char* tlen2=strstr(FileBase, " (");
|
||||
int tlen3=tlen1?(int)(tlen1-wfd.cFileName):strlen(wfd.cFileName);
|
||||
int tlen4=tlen2?(int)(tlen2-FileBase):strlen(FileBase);
|
||||
int len=MAX(0,MIN(tlen3,tlen4));
|
||||
if(strnicmp(wfd.cFileName, FileBase, len))
|
||||
{
|
||||
char temp[512];
|
||||
strcpy(temp,FileBase);
|
||||
temp[len]='\0';
|
||||
if(!strstr(wfd.cFileName, temp))
|
||||
continue;
|
||||
FCEUFILE* fp = FCEU_fopen(filename,0,"rb",0);
|
||||
if(fp) {
|
||||
HandleScan(hwndDlg,fp ,items);
|
||||
delete fp;
|
||||
}
|
||||
}
|
||||
//-------------
|
||||
//if we get here, then we had a match
|
||||
|
||||
char relative[MAX_PATH];
|
||||
AbsoluteToRelative(relative, filename, BaseDirectory.c_str());
|
||||
SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_INSERTSTRING, i++, (LPARAM)relative);
|
||||
} while(FindNextFile(hFind, &wfd));
|
||||
FindClose(hFind);
|
||||
}
|
||||
|
@ -457,9 +495,9 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
free(findGlob[0]);
|
||||
free(findGlob[1]);
|
||||
|
||||
if(i>0)
|
||||
SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_SETCURSEL, i-1, 0);
|
||||
SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_INSERTSTRING, i++, (LPARAM)"Browse...");
|
||||
if(items>0)
|
||||
SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_SETCURSEL, items-1, 0);
|
||||
SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_INSERTSTRING, items++, (LPARAM)"Browse...");
|
||||
|
||||
UpdateReplayDialog(hwndDlg);
|
||||
}
|
||||
|
@ -520,7 +558,7 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
memset(&ofn, 0, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hwndDlg;
|
||||
ofn.lpstrFilter = "FCEUX Movie Files (*.fm2)\0*.fm2\0All files(*.*)\0*.*\0\0";
|
||||
ofn.lpstrFilter = "FCEUX Movie Files (*.fm2)\0*.fm2\0Archive files(*.zip,*.rar,*.7z)\0*.zip;*.rar;*.7z\0All files(*.*)\0*.*\0\0";
|
||||
ofn.lpstrFile = szFile;
|
||||
ofn.nMaxFile = sizeof(szFile);
|
||||
ofn.lpstrInitialDir = pn;
|
||||
|
@ -530,9 +568,17 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
|
||||
if(GetOpenFileName(&ofn))
|
||||
{
|
||||
char relative[MAX_PATH];
|
||||
char relative[MAX_PATH*2];
|
||||
AbsoluteToRelative(relative, szFile, BaseDirectory.c_str());
|
||||
|
||||
ArchiveScanRecord asr = FCEUD_ScanArchive(relative);
|
||||
FCEUFILE* fp = FCEU_fopen(relative,0,"rb",0);
|
||||
if(!fp) {
|
||||
delete fp;
|
||||
goto abort;
|
||||
}
|
||||
strcpy(relative,fp->fullFilename.c_str());
|
||||
|
||||
LONG lOtherIndex = SendDlgItemMessage(hwndDlg, IDC_COMBO_FILENAME, CB_FINDSTRING, (WPARAM)-1, (LPARAM)relative);
|
||||
if(lOtherIndex != CB_ERR)
|
||||
{
|
||||
|
@ -547,6 +593,7 @@ BOOL CALLBACK ReplayDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lP
|
|||
SetFocus(GetDlgItem(hwndDlg, IDC_COMBO_FILENAME));
|
||||
UpdateReplayDialog(hwndDlg);
|
||||
}
|
||||
abort:
|
||||
|
||||
free(pn);
|
||||
}
|
||||
|
|
23
src/file.cpp
23
src/file.cpp
|
@ -230,7 +230,7 @@ void FCEU_SplitArchiveFilename(std::string src, std::string& archive, std::strin
|
|||
}
|
||||
}
|
||||
|
||||
FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext)
|
||||
FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext, int index)
|
||||
{
|
||||
FILE *ipsfile=0;
|
||||
FCEUFILE *fceufp=0;
|
||||
|
@ -264,6 +264,7 @@ FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext
|
|||
}
|
||||
fceufp = new FCEUFILE();
|
||||
fceufp->filename = fileToOpen;
|
||||
fceufp->fullFilename = fileToOpen;
|
||||
fceufp->archiveIndex = -1;
|
||||
fceufp->stream = (std::iostream*)fp;
|
||||
FCEU_fseek(fceufp,0,SEEK_END);
|
||||
|
@ -275,7 +276,10 @@ FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext
|
|||
{
|
||||
//open an archive file
|
||||
if(archive == "")
|
||||
fceufp = FCEUD_OpenArchive(asr, fileToOpen, 0);
|
||||
if(index != -1)
|
||||
fceufp = FCEUD_OpenArchiveIndex(asr, fileToOpen, index);
|
||||
else
|
||||
fceufp = FCEUD_OpenArchive(asr, fileToOpen, 0);
|
||||
else
|
||||
fceufp = FCEUD_OpenArchive(asr, archive, &fname);
|
||||
return fceufp;
|
||||
|
@ -289,6 +293,7 @@ FCEUFILE * FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext
|
|||
}
|
||||
fceufp = new FCEUFILE();
|
||||
fceufp->filename = fileToOpen;
|
||||
fceufp->filename = fileToOpen;
|
||||
fceufp->archiveIndex = -1;
|
||||
fceufp->stream = (std::iostream*)fp;
|
||||
FCEU_fseek(fceufp,0,SEEK_END);
|
||||
|
@ -642,7 +647,8 @@ std::string FCEU_MakeFName(int type, int id1, char *cd1)
|
|||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
//convert | to . for archive filenames.
|
||||
return mass_replace(ret,"|",".");
|
||||
}
|
||||
|
||||
void GetFileBase(const char *f)
|
||||
|
@ -684,3 +690,14 @@ void GetFileBase(const char *f)
|
|||
FileExt[0]=0;
|
||||
}
|
||||
}
|
||||
|
||||
bool FCEU_isFileInArchive(const char *path)
|
||||
{
|
||||
bool isarchive = false;
|
||||
FCEUFILE* fp = FCEU_fopen(path,0,"rb",0,0);
|
||||
if(fp) {
|
||||
isarchive = fp->isArchive();
|
||||
delete fp;
|
||||
}
|
||||
return isarchive;
|
||||
}
|
14
src/file.h
14
src/file.h
|
@ -6,8 +6,7 @@
|
|||
#include "types.h"
|
||||
|
||||
struct FCEUFILE {
|
||||
//void *fp; // FILE* or ptr to ZIPWRAP
|
||||
//uint32 type; // 0=normal file, 1=gzip, 2=zip
|
||||
//the stream you can use to access the data
|
||||
std::iostream *stream;
|
||||
|
||||
//the name of the file, or the logical name of the file within the archive
|
||||
|
@ -16,6 +15,9 @@ struct FCEUFILE {
|
|||
//the filename of the archive (maybe "" if it is not in an archive)
|
||||
std::string archiveFilename;
|
||||
|
||||
//a the path to the filename, possibly using | to get into the archive
|
||||
std::string fullFilename;
|
||||
|
||||
//the number of files that were in the archive
|
||||
int archiveCount;
|
||||
|
||||
|
@ -25,6 +27,9 @@ struct FCEUFILE {
|
|||
//the size of the file
|
||||
int size;
|
||||
|
||||
//whether the file is contained in an archive
|
||||
bool isArchive() { return archiveCount > 0; }
|
||||
|
||||
FCEUFILE()
|
||||
: stream(0)
|
||||
, archiveCount(-1)
|
||||
|
@ -53,10 +58,13 @@ struct ArchiveScanRecord
|
|||
}
|
||||
int type;
|
||||
int numFiles;
|
||||
|
||||
bool isArchive() { return type != -1; }
|
||||
};
|
||||
|
||||
|
||||
FCEUFILE *FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext);
|
||||
FCEUFILE *FCEU_fopen(const char *path, const char *ipsfn, char *mode, char *ext, int index=-1);
|
||||
bool FCEU_isFileInArchive(const char *path);
|
||||
int FCEU_fclose(FCEUFILE*);
|
||||
uint64 FCEU_fread(void *ptr, size_t size, size_t nmemb, FCEUFILE*);
|
||||
uint64 FCEU_fwrite(void *ptr, size_t size, size_t nmemb, FCEUFILE*);
|
||||
|
|
|
@ -456,13 +456,20 @@ static void LoadFM2_binarychunk(MovieData& movieData, std::istream* fp, int size
|
|||
{
|
||||
movieData.records[i].parseBinary(&movieData,fp);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//yuck... another custom text parser.
|
||||
static void LoadFM2(MovieData& movieData, std::istream* fp, int size, bool stopAfterHeader)
|
||||
static bool LoadFM2(MovieData& movieData, std::istream* fp, int size, bool stopAfterHeader)
|
||||
{
|
||||
//movie must start with "version 3"
|
||||
char buf[9];
|
||||
std::ios::pos_type curr = fp->tellg();
|
||||
fp->read(buf,9);
|
||||
if(fp->fail()) return false;
|
||||
if(memcmp(buf,"version 3",9))
|
||||
return false;
|
||||
fp->seekg(curr);
|
||||
|
||||
std::string key,value;
|
||||
enum {
|
||||
NEWLINE, KEY, SEPARATOR, VALUE, RECORD, COMMENT
|
||||
|
@ -482,7 +489,7 @@ static void LoadFM2(MovieData& movieData, std::istream* fp, int size, bool stopA
|
|||
if(isrecchar && movieData.binaryFlag && !stopAfterHeader)
|
||||
{
|
||||
LoadFM2_binarychunk(movieData, fp, size);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
switch(state)
|
||||
{
|
||||
|
@ -499,7 +506,7 @@ static void LoadFM2(MovieData& movieData, std::istream* fp, int size, bool stopA
|
|||
case RECORD:
|
||||
{
|
||||
dorecord:
|
||||
if (stopAfterHeader) return;
|
||||
if (stopAfterHeader) return true;
|
||||
int currcount = movieData.records.size();
|
||||
movieData.records.resize(currcount+1);
|
||||
int preparse = fp->tellg();
|
||||
|
@ -541,6 +548,8 @@ static void LoadFM2(MovieData& movieData, std::istream* fp, int size, bool stopA
|
|||
done: ;
|
||||
if(bail) break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void closeRecordingMovie()
|
||||
|
@ -691,10 +700,14 @@ void FCEUI_LoadMovie(const char *fname, bool _read_only, bool tasedit, int _paus
|
|||
currMovieData = MovieData();
|
||||
|
||||
strcpy(curMovieFilename, fname);
|
||||
std::fstream* fp = FCEUD_UTF8_fstream(fname, "rb");
|
||||
FCEUFILE *fp = FCEU_fopen(fname,0,"rb",0);
|
||||
if (!fp) return;
|
||||
LoadFM2(currMovieData, fp, INT_MAX, false);
|
||||
fp->close();
|
||||
if(fp->isArchive() && !_read_only) {
|
||||
FCEU_PrintError("Cannot open a movie in read+write from an archive.");
|
||||
return;
|
||||
}
|
||||
|
||||
LoadFM2(currMovieData, fp->stream, INT_MAX, false);
|
||||
delete fp;
|
||||
|
||||
//fully reload the game to reinitialize everything before playing any movie
|
||||
|
@ -937,6 +950,14 @@ bool FCEUMOV_ReadState(std::istream* is, uint32 size)
|
|||
{
|
||||
load_successful = false;
|
||||
|
||||
//a little rule: cant load states in read+write mode with a movie from an archive.
|
||||
//so we are going to switch it to readonly mode in that case
|
||||
if(!movie_readonly && FCEU_isFileInArchive(curMovieFilename)) {
|
||||
FCEU_PrintError("Cannot loadstate in Read+Write with movie from archive. Movie is now Read-Only.");
|
||||
movie_readonly = true;
|
||||
}
|
||||
|
||||
|
||||
////write the state to disk so we can reload
|
||||
//std::vector<char> buf(size);
|
||||
//fread(&buf[0],1,size,st);
|
||||
|
@ -1081,13 +1102,11 @@ void FCEUI_MoviePlayFromBeginning(void)
|
|||
}
|
||||
|
||||
|
||||
bool FCEUI_MovieGetInfo(const std::string& fname, MOVIE_INFO* info, bool skipFrameCount)
|
||||
bool FCEUI_MovieGetInfo(FCEUFILE* fp, MOVIE_INFO* /* [in, out] */ info, bool skipFrameCount)
|
||||
{
|
||||
MovieData md;
|
||||
std::fstream* fp = FCEUD_UTF8_fstream(fname, "rb");
|
||||
if(!fp) return false;
|
||||
LoadFM2(md, fp, INT_MAX, skipFrameCount);
|
||||
delete fp;
|
||||
if(!LoadFM2(md, fp->stream, INT_MAX, skipFrameCount))
|
||||
return false;
|
||||
|
||||
info->movie_version = md.version;
|
||||
info->poweron = md.savestate.size()==0;
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include "input/zapper.h"
|
||||
#include "utils/guid.h"
|
||||
|
||||
struct FCEUFILE;
|
||||
|
||||
enum EMOVIE_FLAG
|
||||
{
|
||||
MOVIE_FLAG_NONE = 0,
|
||||
|
@ -232,7 +234,7 @@ void FCEUI_SaveMovie(const char *fname, EMOVIE_FLAG flags);
|
|||
void FCEUI_LoadMovie(const char *fname, bool read_only, bool tasedit, int _stopframe);
|
||||
void FCEUI_MoviePlayFromBeginning(void);
|
||||
void FCEUI_StopMovie(void);
|
||||
bool FCEUI_MovieGetInfo(const std::string& fname, MOVIE_INFO* /* [in, out] */ info, bool skipFrameCount = false);
|
||||
bool FCEUI_MovieGetInfo(FCEUFILE* fp, MOVIE_INFO* /* [in, out] */ info, bool skipFrameCount = false);
|
||||
char* FCEUI_MovieGetCurrentName(int addSlotNumber);
|
||||
void FCEUI_MovieToggleReadOnly(void);
|
||||
bool FCEUI_GetMovieToggleReadOnly();
|
||||
|
|
|
@ -565,3 +565,13 @@ std::string readNullTerminatedAscii(std::istream* is)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// replace all instances of victim with replacement
|
||||
std::string mass_replace(const std::string &source, const std::string &victim, const std::string &replacement)
|
||||
{
|
||||
std::string answer = source;
|
||||
std::string::size_type j = 0;
|
||||
while ((j = answer.find(victim, j)) != std::string::npos )
|
||||
answer.replace(j, victim.length(), replacement);
|
||||
return answer;
|
||||
}
|
||||
|
|
|
@ -113,3 +113,6 @@ template<typename T, int DIGITS, bool PAD> void putdec(std::ostream* os, T dec)
|
|||
else
|
||||
os->write(temp,DIGITS);
|
||||
}
|
||||
|
||||
|
||||
std::string mass_replace(const std::string &source, const std::string &victim, const std::string &replacement);
|
Loading…
Reference in New Issue