add "record from sram" (to fix SF bug #828)
This commit is contained in:
parent
166e7a8ad9
commit
e3b7197128
|
@ -76,6 +76,8 @@ uint8 geniech[3];
|
|||
|
||||
uint32 genieaddr[3];
|
||||
|
||||
CartInfo *currCartInfo;
|
||||
|
||||
static INLINE void setpageptr(int s, uint32 A, uint8 *p, int ram) {
|
||||
uint32 AB = A >> 11;
|
||||
int x;
|
||||
|
|
|
@ -25,6 +25,8 @@ typedef struct {
|
|||
// other code in the future.
|
||||
} CartInfo;
|
||||
|
||||
extern CartInfo *currCartInfo;
|
||||
|
||||
void FCEU_SaveGameSave(CartInfo *LocalHWInfo);
|
||||
void FCEU_LoadGameSave(CartInfo *LocalHWInfo);
|
||||
void FCEU_ClearGameSave(CartInfo *LocalHWInfo);
|
||||
|
|
|
@ -851,6 +851,7 @@ static BOOL CALLBACK RecordDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP
|
|||
|
||||
SendDlgItemMessage(hwndDlg, IDC_COMBO_RECORDFROM, CB_INSERTSTRING, i++, (LPARAM)"Start");
|
||||
SendDlgItemMessage(hwndDlg, IDC_COMBO_RECORDFROM, CB_INSERTSTRING, i++, (LPARAM)"Now");
|
||||
SendDlgItemMessage(hwndDlg, IDC_COMBO_RECORDFROM, CB_INSERTSTRING, i++, (LPARAM)"SaveRam");
|
||||
|
||||
memset(&wfd, 0, sizeof(wfd));
|
||||
hFind = FindFirstFile(findGlob, &wfd);
|
||||
|
@ -941,7 +942,7 @@ static BOOL CALLBACK RecordDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP
|
|||
// convert Unicode wstring to UTF8 char* string
|
||||
WideCharToMultiByte(CP_UTF8, 0, (p->authorName).c_str(), -1, taseditorConfig.lastAuthorName, AUTHOR_NAME_MAX_LEN, 0, 0);
|
||||
|
||||
if (lIndex >= 2)
|
||||
if (lIndex >= 3)
|
||||
p->szSavestateFilename = GetSavePath(hwndDlg);
|
||||
EndDialog(hwndDlg, 1);
|
||||
}
|
||||
|
@ -983,11 +984,11 @@ void FCEUD_MovieRecordTo()
|
|||
if (!GameInfo) return;
|
||||
static struct CreateMovieParameters p;
|
||||
p.szFilename = strdup(FCEU_MakeFName(FCEUMKF_MOVIE,0,0).c_str());
|
||||
if(p.recordFrom >= 2) p.recordFrom=1;
|
||||
if(p.recordFrom >= 3) p.recordFrom=1;
|
||||
|
||||
if(DialogBoxParam(fceu_hInstance, "IDD_RECORDINP", hAppWnd, RecordDialogProc, (LPARAM)&p))
|
||||
{
|
||||
if(p.recordFrom >= 2)
|
||||
if(p.recordFrom >= 3)
|
||||
{
|
||||
// attempt to load the savestate
|
||||
// FIXME: pop open a messagebox if this fails
|
||||
|
@ -1006,6 +1007,7 @@ void FCEUD_MovieRecordTo()
|
|||
|
||||
EMOVIE_FLAG flags = MOVIE_FLAG_NONE;
|
||||
if(p.recordFrom == 0) flags = MOVIE_FLAG_FROM_POWERON;
|
||||
if(p.recordFrom == 2) flags = MOVIE_FLAG_FROM_SAVERAM;
|
||||
FCEUI_SaveMovie(p.szFilename.c_str(), flags, p.authorName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -907,6 +907,7 @@ int iNESLoad(const char *name, FCEUFILE *fp, int OverwriteVidMode) {
|
|||
}
|
||||
|
||||
GameInterface = iNESGI;
|
||||
currCartInfo = &iNESCart;
|
||||
FCEU_printf("\n");
|
||||
|
||||
// since apparently the iNES format doesn't store this information,
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "file.h"
|
||||
#include "video.h"
|
||||
#include "movie.h"
|
||||
#include "cart.h"
|
||||
#include "fds.h"
|
||||
#include "vsuni.h"
|
||||
#ifdef _S9XLUA_H
|
||||
|
@ -461,6 +462,16 @@ void MovieData::installValue(std::string& key, std::string& val)
|
|||
StringToBytes(val,&savestate[0],len); // decodes either base64 or hex
|
||||
}
|
||||
}
|
||||
else if(key == "saveram")
|
||||
{
|
||||
int len = Base64StringToBytesLength(val);
|
||||
if(len == -1) len = HexStringToBytesLength(val); // wasn't base64, try hex
|
||||
if(len >= 1)
|
||||
{
|
||||
saveram.resize(len);
|
||||
StringToBytes(val,&saveram[0],len); // decodes either base64 or hex
|
||||
}
|
||||
}
|
||||
else if (key == "length")
|
||||
{
|
||||
installInt(val, loadFrameCount);
|
||||
|
@ -499,6 +510,9 @@ int MovieData::dump(EMUFILE *os, bool binary)
|
|||
if(savestate.size())
|
||||
os->fprintf("savestate %s\n" , BytesToString(&savestate[0],savestate.size()).c_str() );
|
||||
|
||||
if(saveram.size())
|
||||
os->fprintf("saveram %s\n" , BytesToString(&saveram[0],saveram.size()).c_str() );
|
||||
|
||||
if (this->loadFrameCount >= 0)
|
||||
os->fprintf("length %d\n" , this->loadFrameCount);
|
||||
|
||||
|
@ -778,6 +792,8 @@ void FCEUI_StopMovie()
|
|||
#endif
|
||||
}
|
||||
|
||||
bool bogorf;
|
||||
|
||||
void poweron(bool shouldDisableBatteryLoading)
|
||||
{
|
||||
//// make a for-movie-recording power-on clear the game's save data, too
|
||||
|
@ -802,9 +818,9 @@ void poweron(bool shouldDisableBatteryLoading)
|
|||
//suppressAddPowerCommand=0;
|
||||
|
||||
extern int disableBatteryLoading;
|
||||
disableBatteryLoading = 1;
|
||||
if(!bogorf) disableBatteryLoading = 1;
|
||||
PowerNES();
|
||||
disableBatteryLoading = 0;
|
||||
if(!bogorf) disableBatteryLoading = 0;
|
||||
}
|
||||
|
||||
void FCEUMOV_CreateCleanMovie()
|
||||
|
@ -846,6 +862,59 @@ void MovieData::dumpSavestateTo(std::vector<uint8>* buf, int compressionLevel)
|
|||
ms.trim();
|
||||
}
|
||||
|
||||
bool MovieData::loadSaveramFrom(std::vector<uint8>* buf)
|
||||
{
|
||||
EMUFILE_MEMORY ms(buf);
|
||||
|
||||
bool hasBattery = !!ms.read32le();
|
||||
if(hasBattery != !!currCartInfo->battery)
|
||||
{
|
||||
FCEU_PrintError("movie battery load mismatch 1");
|
||||
return false;
|
||||
}
|
||||
|
||||
for(int i=0;i<4;i++)
|
||||
{
|
||||
int len = ms.read32le();
|
||||
|
||||
if(!currCartInfo->SaveGame[i] && len!=0)
|
||||
{
|
||||
FCEU_PrintError("movie battery load mismatch 2");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(currCartInfo->SaveGameLen[i] != len)
|
||||
{
|
||||
FCEU_PrintError("movie battery load mismatch 3");
|
||||
return false;
|
||||
}
|
||||
|
||||
ms.fread(currCartInfo->SaveGame[i], len);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void MovieData::dumpSaveramTo(std::vector<uint8>* buf, int compressionLevel)
|
||||
{
|
||||
EMUFILE_MEMORY ms(buf);
|
||||
|
||||
ms.write32le(currCartInfo->battery?1:0);
|
||||
for(int i=0;i<4;i++)
|
||||
{
|
||||
if(!currCartInfo->SaveGame[i])
|
||||
{
|
||||
ms.write32le((u32)0);
|
||||
continue;
|
||||
}
|
||||
|
||||
ms.write32le(currCartInfo->SaveGameLen[i]);
|
||||
ms.fwrite(currCartInfo->SaveGame[i], currCartInfo->SaveGameLen[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//begin playing an existing movie
|
||||
bool FCEUI_LoadMovie(const char *fname, bool _read_only, int _pauseframe)
|
||||
{
|
||||
|
@ -901,7 +970,14 @@ bool FCEUI_LoadMovie(const char *fname, bool _read_only, int _pauseframe)
|
|||
movieFromPoweron = false;
|
||||
bool success = MovieData::loadSavestateFrom(&currMovieData.savestate);
|
||||
if(!success) return true; //adelikat: I guess return true here? False is only for a bad movie filename, if it got this far the file was good?
|
||||
} else {
|
||||
}
|
||||
else if(currMovieData.saveram.size())
|
||||
{
|
||||
movieFromPoweron = true;
|
||||
bool success = MovieData::loadSaveramFrom(&currMovieData.saveram);
|
||||
if(!success) return true; //adelikat: I guess return true here? False is only for a bad movie filename, if it got this far the file was good?
|
||||
}
|
||||
else {
|
||||
movieFromPoweron = true;
|
||||
}
|
||||
|
||||
|
@ -981,7 +1057,15 @@ void FCEUI_SaveMovie(const char *fname, EMOVIE_FLAG flags, std::wstring author)
|
|||
movieFromPoweron = true;
|
||||
poweron(true);
|
||||
}
|
||||
else
|
||||
else if(flags & MOVIE_FLAG_FROM_SAVERAM)
|
||||
{
|
||||
movieFromPoweron = true;
|
||||
MovieData::dumpSaveramTo(&currMovieData.saveram,Z_NO_COMPRESSION); //i guess with this there's a chance someone could hack the file, at least, so maybe it's helpfu
|
||||
bogorf = true;
|
||||
poweron(false);
|
||||
bogorf = false;
|
||||
}
|
||||
else //from savestate
|
||||
{
|
||||
movieFromPoweron = false;
|
||||
MovieData::dumpSavestateTo(&currMovieData.savestate,Z_BEST_COMPRESSION);
|
||||
|
|
10
src/movie.h
10
src/movie.h
|
@ -23,13 +23,15 @@ enum EMOVIE_FLAG
|
|||
|
||||
MOVIE_FLAG_PAL = (1<<2),
|
||||
|
||||
//movie was recorded from poweron. the alternative is from a savestate (or from reset)
|
||||
//movie was recorded from poweron. the alternative is from a savestate (or from reset). OR from saveram.
|
||||
MOVIE_FLAG_FROM_POWERON = (1<<3),
|
||||
|
||||
// set in newer version, used for old movie compatibility
|
||||
//TODO - only use this flag to print a warning that the sync might be bad
|
||||
//so that we can get rid of the sync hack code
|
||||
MOVIE_FLAG_NOSYNCHACK = (1<<4)
|
||||
MOVIE_FLAG_NOSYNCHACK = (1<<4),
|
||||
|
||||
MOVIE_FLAG_FROM_SAVERAM = (1<<5)
|
||||
};
|
||||
|
||||
typedef struct
|
||||
|
@ -178,6 +180,7 @@ public:
|
|||
MD5DATA romChecksum;
|
||||
std::string romFilename;
|
||||
std::vector<uint8> savestate;
|
||||
std::vector<uint8> saveram;
|
||||
std::vector<MovieRecord> records;
|
||||
std::vector<std::wstring> comments;
|
||||
std::vector<std::string> subtitles;
|
||||
|
@ -241,6 +244,9 @@ public:
|
|||
static bool loadSavestateFrom(std::vector<uint8>* buf);
|
||||
static void dumpSavestateTo(std::vector<uint8>* buf, int compressionLevel);
|
||||
|
||||
static bool loadSaveramFrom(std::vector<uint8>* buf);
|
||||
static void dumpSaveramTo(std::vector<uint8>* buf, int compressionLevel);
|
||||
|
||||
private:
|
||||
void installInt(std::string& val, int& var)
|
||||
{
|
||||
|
|
|
@ -618,6 +618,7 @@ int UNIFLoad(const char *name, FCEUFILE *fp) {
|
|||
|
||||
strcpy(LoadedRomFName, name); //For the debugger list
|
||||
GameInterface = UNIFGI;
|
||||
currCartInfo = &UNIFCart;
|
||||
return 1;
|
||||
|
||||
aborto:
|
||||
|
|
Loading…
Reference in New Issue