batch fcm->fm2 convert rough draft (look in the file menu)
the headers arent output fully correct.. and there is no error reporting.. but it works.
This commit is contained in:
parent
69bc4b3f72
commit
67c4a6d6ab
|
@ -202,7 +202,7 @@ void UpdateReplayDialog(HWND hwndDlg)
|
|||
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_UNDOCOUNT),"");
|
||||
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_ROMUSED),"");
|
||||
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_ROMCHECKSUM),"");
|
||||
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_RECORDEDFROM),"Nothing (invalid movie)");
|
||||
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_RECORDEDFROM),"");
|
||||
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_EMULATORUSED),"");
|
||||
SetWindowText(GetDlgItem(hwndDlg,IDC_LABEL_CURRCHECKSUM),md5_asciistr(GameInfo->MD5));
|
||||
SetDlgItemText(hwndDlg,IDC_EDIT_STOPFRAME,"");
|
||||
|
@ -313,7 +313,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 *.fcm, *.fm2
|
||||
// filter out everything that's not *.fm2
|
||||
// (because FindFirstFile is too dumb to do that)
|
||||
{
|
||||
char* dot=strrchr(wfd.cFileName,'.');
|
||||
|
@ -324,7 +324,7 @@ 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,"fcm") && strcmp(ext,"fm2"))
|
||||
if(strcmp(ext,"fm2"))
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -442,7 +442,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 = "Supported Movie Files (*.fcm|*.fm2)\0*.fcm;*.fm2\0FCEUX Movie Files (*.fm2)\0*.fm2\0FCEU Movie Files (*.fcm)\0*.fcm\0All files(*.*)\0*.*\0\0";
|
||||
ofn.lpstrFilter = "FCEUX Movie Files (*.fm2)\0*.fm2\0All files(*.*)\0*.*\0\0";
|
||||
ofn.lpstrFile = szFile;
|
||||
ofn.nMaxFile = sizeof(szFile);
|
||||
ofn.lpstrInitialDir = pn;
|
||||
|
@ -696,7 +696,7 @@ static BOOL CALLBACK RecordDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LP
|
|||
memset(&ofn, 0, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hwndDlg;
|
||||
ofn.lpstrFilter = "FCEUX Movie File (*.fm2)\0*.fm2\0FCEU Movie File(*.fcm)\0*.fcm\0All files(*.*)\0*.*\0\0";
|
||||
ofn.lpstrFilter = "FCEUX Movie File (*.fm2)\0*.fm2\0All files(*.*)\0*.*\0\0";
|
||||
ofn.lpstrFile = szChoice;
|
||||
ofn.lpstrDefExt = "fm2";
|
||||
ofn.nMaxFile = MAX_PATH;
|
||||
|
|
|
@ -49,6 +49,7 @@ BEGIN
|
|||
MENUITEM "Record Movie...", MENU_RECORD_MOVIE
|
||||
MENUITEM "Replay Movie...", MENU_REPLAY_MOVIE
|
||||
MENUITEM "Stop Movie", MENU_STOP_MOVIE
|
||||
MENUITEM "Convert FCM...", MENU_CONVERT_MOVIE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Record AVI...", MENU_RECORD_AVI
|
||||
MENUITEM "Stop AVI", MENU_STOP_AVI
|
||||
|
|
|
@ -523,6 +523,8 @@
|
|||
#define ID_ 40146
|
||||
#define MENU_DISPLAY_BG 40147
|
||||
#define MENU_DISPLAY_OBJ 40148
|
||||
#define ID_FILE_CONVERTMOVIE 40149
|
||||
#define MENU_CONVERT_MOVIE 40150
|
||||
#define MW_ValueLabel2 65423
|
||||
#define MW_ValueLabel1 65426
|
||||
#define GUI_BOT_DEBUG 65436
|
||||
|
@ -533,7 +535,7 @@
|
|||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 114
|
||||
#define _APS_NEXT_COMMAND_VALUE 40149
|
||||
#define _APS_NEXT_COMMAND_VALUE 40151
|
||||
#define _APS_NEXT_CONTROL_VALUE 1132
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#include "throttle.h"
|
||||
#include "monitor.h"
|
||||
#include "tasedit.h"
|
||||
#include "oldmovie.h"
|
||||
#include "movie.h"
|
||||
|
||||
#include "guiconfig.h"
|
||||
#include "timing.h"
|
||||
|
@ -54,6 +56,8 @@
|
|||
#include "help.h"
|
||||
#include "movie.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
// Extern variables
|
||||
|
||||
extern FCEUGI *GameInfo;
|
||||
|
@ -108,6 +112,61 @@ static int vchanged = 0;
|
|||
|
||||
// Internal functions
|
||||
|
||||
static void ConvertFCM(HWND hwndOwner)
|
||||
{
|
||||
std::string initdir = FCEU_GetPath(FCEUMKF_MOVIE);
|
||||
|
||||
OPENFILENAME ofn;
|
||||
memset(&ofn, 0, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = hwndOwner;
|
||||
ofn.lpstrFilter = "FCEU <2.0 Movie Files (*.fcm)\0*.fcm\0All files(*.*)\0*.*\0\0";
|
||||
ofn.lpstrFile = new char[640*1024]; //640K should be enough for anyone
|
||||
ofn.lpstrFile[0] = 0;
|
||||
ofn.nMaxFile = 640*1024;
|
||||
ofn.lpstrInitialDir = initdir.c_str();
|
||||
ofn.Flags = OFN_NOCHANGEDIR | OFN_HIDEREADONLY | OFN_ALLOWMULTISELECT | OFN_EXPLORER;
|
||||
ofn.lpstrDefExt = "fcm";
|
||||
ofn.lpstrTitle = "Select old movie(s) for conversion";
|
||||
|
||||
if(GetOpenFileName(&ofn))
|
||||
{
|
||||
std::vector<std::string> todo;
|
||||
|
||||
if(ofn.nFileExtension==0)
|
||||
{
|
||||
//multiselect
|
||||
std::string dir = ofn.lpstrFile;
|
||||
char* cp = ofn.lpstrFile + dir.size() + 1;
|
||||
while(*cp)
|
||||
{
|
||||
std::string fname = cp;
|
||||
todo.push_back(dir + "/" + fname);
|
||||
cp += fname.size() + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
todo.push_back(ofn.lpstrFile);
|
||||
}
|
||||
|
||||
for(uint32 i=0;i<todo.size();i++)
|
||||
{
|
||||
std::string infname = todo[i];
|
||||
std::string outname = infname + ".fm2";
|
||||
MovieData md;
|
||||
if(convert_fcm(md, infname)==FCM_CONVERTRESULT_SUCCESS)
|
||||
{
|
||||
std::fstream* outf = FCEUD_UTF8_fstream(outname, "wb");
|
||||
md.dump(outf,false);
|
||||
delete outf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete[] ofn.lpstrFile;
|
||||
}
|
||||
|
||||
void CalcWindowSize(RECT *al)
|
||||
{
|
||||
al->left = 0;
|
||||
|
@ -993,6 +1052,11 @@ LRESULT FAR PASCAL AppWndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
|
|||
}
|
||||
break;
|
||||
|
||||
case MENU_CONVERT_MOVIE:
|
||||
ConvertFCM(hWnd);
|
||||
break;
|
||||
|
||||
|
||||
case MENU_SAVE_STATE:
|
||||
// Save state as menu was selected
|
||||
FCEUD_SaveStateAs();
|
||||
|
|
654
src/movie.cpp
654
src/movie.cpp
|
@ -7,10 +7,6 @@
|
|||
#include <fstream>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "types.h"
|
||||
#include "utils/endian.h"
|
||||
#include "palette.h"
|
||||
|
@ -29,7 +25,7 @@
|
|||
using namespace std;
|
||||
|
||||
|
||||
#define MOVIE_VERSION 3 // still at 2 since the format itself is still compatible - to detect which version the movie was made with, check the fceu version stored in the movie header (e.g against FCEU_VERSION_NUMERIC)
|
||||
#define MOVIE_VERSION 3
|
||||
|
||||
extern char FileBase[];
|
||||
extern int EmulationPaused;
|
||||
|
@ -234,11 +230,6 @@ void MovieRecord::dumpBinary(MovieData* md, std::ostream* os, int index)
|
|||
|
||||
void MovieRecord::dump(MovieData* md, std::ostream* os, int index)
|
||||
{
|
||||
//todo: if we want frame numbers in the output (which we dont since we couldnt cut and paste in movies)
|
||||
//but someone would need to change the parser to ignore it
|
||||
//fputc('|',fp);
|
||||
//fprintf(fp,"%08d",index);
|
||||
|
||||
//dump the misc commands
|
||||
//*os << '|' << setw(1) << (int)commands;
|
||||
os->put('|');
|
||||
|
@ -284,7 +275,7 @@ MovieData::MovieData()
|
|||
, emuVersion(FCEU_VERSION_NUMERIC)
|
||||
, palFlag(false)
|
||||
, binaryFlag(false)
|
||||
, recordCount(1)
|
||||
, rerecordCount(1)
|
||||
, greenZoneCount(0)
|
||||
{
|
||||
memset(&romChecksum,0,sizeof(MD5DATA));
|
||||
|
@ -302,8 +293,8 @@ void MovieData::installValue(std::string& key, std::string& val)
|
|||
installInt(val,version);
|
||||
else if(key == "emuVersion")
|
||||
installInt(val,emuVersion);
|
||||
else if(key == "recordCount")
|
||||
installInt(val,recordCount);
|
||||
else if(key == "rerecordCount")
|
||||
installInt(val,rerecordCount);
|
||||
else if(key == "palFlag")
|
||||
installBool(val,palFlag);
|
||||
else if(key == "romFilename")
|
||||
|
@ -338,7 +329,7 @@ int MovieData::dump(std::ostream *os, bool binary)
|
|||
int start = os->tellp();
|
||||
*os << "version " << version << endl;
|
||||
*os << "emuVersion " << emuVersion << endl;
|
||||
*os << "recordCount " << recordCount << endl;
|
||||
*os << "rerecordCount " << rerecordCount << endl;
|
||||
*os << "palFlag " << (palFlag?1:0) << endl;
|
||||
*os << "romFilename " << romFilename << endl;
|
||||
*os << "romChecksum " << BytesToString(romChecksum.data,MD5DATA::size) << endl;
|
||||
|
@ -521,23 +512,30 @@ static void LoadFM2(MovieData& movieData, std::istream* fp, int size, bool stopA
|
|||
}
|
||||
}
|
||||
|
||||
static void closeRecordingMovie()
|
||||
{
|
||||
if(osRecordingMovie)
|
||||
{
|
||||
delete osRecordingMovie;
|
||||
osRecordingMovie = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// Stop movie playback.
|
||||
void StopPlayback()
|
||||
static void StopPlayback()
|
||||
{
|
||||
FCEU_DispMessageOnMovie("Movie playback stopped.");
|
||||
movieMode = MOVIEMODE_INACTIVE;
|
||||
}
|
||||
|
||||
/// Stop movie recording
|
||||
void StopRecording()
|
||||
static void StopRecording()
|
||||
{
|
||||
FCEU_DispMessage("Movie recording stopped.");
|
||||
|
||||
movieMode = MOVIEMODE_INACTIVE;
|
||||
//fclose(fpRecordingMovie);
|
||||
//fpRecordingMovie = 0;
|
||||
osRecordingMovie = 0;
|
||||
|
||||
closeRecordingMovie();
|
||||
}
|
||||
|
||||
|
||||
|
@ -654,11 +652,8 @@ void FCEUI_LoadMovie(char *fname, bool _read_only, bool tasedit, int _pauseframe
|
|||
fp->close();
|
||||
delete fp;
|
||||
|
||||
// fully reload the game to reinitialize everything before playing any movie
|
||||
// to try fixing nondeterministic playback of some games
|
||||
{
|
||||
poweron(true);
|
||||
}
|
||||
//fully reload the game to reinitialize everything before playing any movie
|
||||
poweron(true);
|
||||
|
||||
//WE NEED TO LOAD A SAVESTATE
|
||||
if(currMovieData.savestate.size() != 0)
|
||||
|
@ -699,15 +694,6 @@ void FCEUI_LoadMovie(char *fname, bool _read_only, bool tasedit, int _pauseframe
|
|||
}
|
||||
}
|
||||
|
||||
static void closeRecordingMovie()
|
||||
{
|
||||
if(osRecordingMovie)
|
||||
{
|
||||
delete osRecordingMovie;
|
||||
osRecordingMovie = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void openRecordingMovie(const char* fname)
|
||||
{
|
||||
osRecordingMovie = FCEUD_UTF8_fstream(fname, "wb");
|
||||
|
@ -925,7 +911,7 @@ bool FCEUMOV_ReadState(std::istream* is, uint32 size)
|
|||
//truncate before we copy, just to save some time
|
||||
tempMovieData.truncateAt(currFrameCounter);
|
||||
currMovieData = tempMovieData;
|
||||
currMovieData.recordCount++;
|
||||
currMovieData.rerecordCount++;
|
||||
|
||||
openRecordingMovie(curMovieFilename);
|
||||
currMovieData.dump(osRecordingMovie, false);
|
||||
|
@ -1026,605 +1012,7 @@ bool FCEUI_MovieGetInfo(const std::string& fname, MOVIE_INFO* info, bool skipFra
|
|||
info->md5_of_rom_used_present = 1;
|
||||
info->emu_version_used = md.emuVersion;
|
||||
info->name_of_rom_used = md.romFilename;
|
||||
info->rerecord_count = md.recordCount;
|
||||
info->rerecord_count = md.rerecordCount;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//int FCEUI_IsMovieActive(void)
|
||||
//{
|
||||
// //this is a lame method. we should change all the fceu code that uses it to call the
|
||||
// //IsRecording or IsPlaying methods
|
||||
// //return > 0 for recording, < 0 for playback
|
||||
// if(FCEUMOV_IsRecording()) return 1;
|
||||
// else if(FCEUMOV_IsPlaying()) return -1;
|
||||
// else return 0;
|
||||
//}
|
||||
|
||||
|
||||
//struct MovieHeader
|
||||
//{
|
||||
//uint32 magic; // +0
|
||||
//uint32 version=2; // +4
|
||||
//uint8 flags[4]; // +8
|
||||
//uint32 length_frames; // +12
|
||||
//uint32 rerecord_count; // +16
|
||||
//uint32 movie_data_size; // +20
|
||||
//uint32 offset_to_savestate; // +24, should be 4-byte-aligned
|
||||
//uint32 offset_to_movie_data; // +28, should be 4-byte-aligned
|
||||
//uint8 md5_of_rom_used[16]; // +32
|
||||
//uint32 version_of_emu_used // +48
|
||||
//char name_of_rom_used[] // +52, utf-8, null-terminated
|
||||
//char metadata[]; // utf-8, null-terminated
|
||||
//uint8 padding[];
|
||||
//uint8 savestate[]; // always present, even in a "from reset" recording
|
||||
//uint8 padding[]; // used for byte-alignment
|
||||
//uint8 movie_data[];
|
||||
//}
|
||||
|
||||
|
||||
// backwards compat
|
||||
//static void FCEUI_LoadMovie_v1(char *fname, int _read_only);
|
||||
//static int FCEUI_MovieGetInfo_v1(const char* fname, MOVIE_INFO* info);
|
||||
//
|
||||
//#define MOVIE_MAGIC 0x1a4d4346 // FCM\x1a
|
||||
//
|
||||
//int _old_FCEUI_MovieGetInfo(const char* fname, MOVIE_INFO* info)
|
||||
//{
|
||||
// //mbg: wtf?
|
||||
// //MovieFlushHeader();
|
||||
//
|
||||
// // main get info part of function
|
||||
// {
|
||||
// uint32 magic;
|
||||
// uint32 version;
|
||||
// uint8 _flags[4];
|
||||
//
|
||||
// FILE* fp = FCEUD_UTF8fopen(fname, "rb");
|
||||
// if(!fp)
|
||||
// return 0;
|
||||
//
|
||||
// read32le(&magic, fp);
|
||||
// if(magic != MOVIE_MAGIC)
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// read32le(&version, fp);
|
||||
// if(version != MOVIE_VERSION)
|
||||
// {
|
||||
// fclose(fp);
|
||||
// if(version == 1)
|
||||
// return FCEUI_MovieGetInfo_v1(fname, info);
|
||||
// else
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// info->movie_version = MOVIE_VERSION;
|
||||
//
|
||||
// fread(_flags, 1, 4, fp);
|
||||
//
|
||||
// info->flags = _flags[0];
|
||||
// read32le(&info->num_frames, fp);
|
||||
// read32le(&info->rerecord_count, fp);
|
||||
//
|
||||
// if(access(fname, W_OK))
|
||||
// info->read_only = 1;
|
||||
// else
|
||||
// info->read_only = 0;
|
||||
//
|
||||
// fseek(fp, 12, SEEK_CUR); // skip movie_data_size, offset_to_savestate, and offset_to_movie_data
|
||||
//
|
||||
// fread(&info->md5_of_rom_used, 1, 16, fp);
|
||||
// info->md5_of_rom_used_present = 1;
|
||||
//
|
||||
// read32le(&info->emu_version_used, fp);
|
||||
//
|
||||
// // I probably could have planned this better...
|
||||
// {
|
||||
// char str[256];
|
||||
// size_t r;
|
||||
// uint32 p; //mbg merge 7/17/06 change to uint32
|
||||
// int p2=0;
|
||||
// char last_c=32;
|
||||
//
|
||||
// if(info->name_of_rom_used && info->name_of_rom_used_size)
|
||||
// info->name_of_rom_used[0]='\0';
|
||||
//
|
||||
// r=fread(str, 1, 256, fp);
|
||||
// while(r > 0)
|
||||
// {
|
||||
// for(p=0; p<r && last_c != '\0'; ++p)
|
||||
// {
|
||||
// if(info->name_of_rom_used && info->name_of_rom_used_size && (p2 < info->name_of_rom_used_size-1))
|
||||
// {
|
||||
// info->name_of_rom_used[p2]=str[p];
|
||||
// p2++;
|
||||
// last_c=str[p];
|
||||
// }
|
||||
// }
|
||||
// if(p<r)
|
||||
// {
|
||||
// memmove(str, str+p, r-p);
|
||||
// r -= p;
|
||||
// break;
|
||||
// }
|
||||
// r=fread(str, 1, 256, fp);
|
||||
// }
|
||||
//
|
||||
// p2=0;
|
||||
// last_c=32;
|
||||
//
|
||||
// if(info->metadata && info->metadata_size)
|
||||
// info->metadata[0]='\0';
|
||||
//
|
||||
// while(r > 0)
|
||||
// {
|
||||
// for(p=0; p<r && last_c != '\0'; ++p)
|
||||
// {
|
||||
// if(info->metadata && info->metadata_size && (p2 < info->metadata_size-1))
|
||||
// {
|
||||
// info->metadata[p2]=str[p];
|
||||
// p2++;
|
||||
// last_c=str[p];
|
||||
// }
|
||||
// }
|
||||
// if(p != r)
|
||||
// break;
|
||||
// r=fread(str, 1, 256, fp);
|
||||
// }
|
||||
//
|
||||
// if(r<=0)
|
||||
// {
|
||||
// // somehow failed to read romname and metadata
|
||||
// fclose(fp);
|
||||
// return 0;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // check what hacks are necessary
|
||||
// fseek(fp, 24, SEEK_SET); // offset_to_savestate offset
|
||||
// uint32 temp_savestate_offset;
|
||||
// read32le(&temp_savestate_offset, fp);
|
||||
// if(temp_savestate_offset != 0xFFFFFFFF)
|
||||
// {
|
||||
// if(fseek(fp, temp_savestate_offset, SEEK_SET))
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// //don't really load, just load to find what's there then load backup
|
||||
// if(!FCEUSS_LoadFP(fp,SSLOADPARAM_DUMMY)) return 0;
|
||||
// }
|
||||
//
|
||||
// fclose(fp);
|
||||
// return 1;
|
||||
// }
|
||||
//}
|
||||
/*
|
||||
Backwards compat
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
struct MovieHeader_v1
|
||||
{
|
||||
uint32 magic;
|
||||
uint32 version=1;
|
||||
uint8 flags[4];
|
||||
uint32 length_frames;
|
||||
uint32 rerecord_count;
|
||||
uint32 movie_data_size;
|
||||
uint32 offset_to_savestate;
|
||||
uint32 offset_to_movie_data;
|
||||
uint16 metadata_ucs2[]; // ucs-2, ick! sizeof(metadata) = offset_to_savestate - MOVIE_HEADER_SIZE
|
||||
}
|
||||
*/
|
||||
//
|
||||
//#define MOVIE_V1_HEADER_SIZE 32
|
||||
//
|
||||
//static void FCEUI_LoadMovie_v1(char *fname, int _read_only)
|
||||
//{
|
||||
// FILE *fp;
|
||||
// char *fn = NULL;
|
||||
//
|
||||
// FCEUI_StopMovie();
|
||||
//
|
||||
// if(!fname)
|
||||
// fname = fn = FCEU_MakeFName(FCEUMKF_MOVIE,0,0);
|
||||
//
|
||||
// // check movie_readonly
|
||||
// movie_readonly = _read_only;
|
||||
// if(access(fname, W_OK))
|
||||
// movie_readonly = 2;
|
||||
//
|
||||
// fp = FCEUD_UTF8fopen(fname, (movie_readonly>=2) ? "rb" : "r+b");
|
||||
//
|
||||
// if(fn)
|
||||
// {
|
||||
// free(fn);
|
||||
// fname = NULL;
|
||||
// }
|
||||
//
|
||||
// if(!fp) return;
|
||||
//
|
||||
// // read header
|
||||
// {
|
||||
// uint32 magic;
|
||||
// uint32 version;
|
||||
// uint8 flags[4];
|
||||
// uint32 fc;
|
||||
//
|
||||
// read32le(&magic, fp);
|
||||
// if(magic != MOVIE_MAGIC)
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// read32le(&version, fp);
|
||||
// if(version != 1)
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// fread(flags, 1, 4, fp);
|
||||
// read32le(&fc, fp);
|
||||
// read32le(&rerecord_count, fp);
|
||||
// read32le(&moviedatasize, fp);
|
||||
// read32le(&savestate_offset, fp);
|
||||
// read32le(&firstframeoffset, fp);
|
||||
// if(fseek(fp, savestate_offset, SEEK_SET))
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if(flags[0] & MOVIE_FLAG_NOSYNCHACK)
|
||||
// movieSyncHackOn=0;
|
||||
// else
|
||||
// movieSyncHackOn=1;
|
||||
// }
|
||||
//
|
||||
// // fully reload the game to reinitialize everything before playing any movie
|
||||
// // to try fixing nondeterministic playback of some games
|
||||
// {
|
||||
// extern char lastLoadedGameName [2048];
|
||||
// extern int disableBatteryLoading, suppressAddPowerCommand;
|
||||
// suppressAddPowerCommand=1;
|
||||
// suppressMovieStop=true;
|
||||
// {
|
||||
// FCEUGI * gi = FCEUI_LoadGame(lastLoadedGameName, 0);
|
||||
// if(!gi)
|
||||
// PowerNES();
|
||||
// }
|
||||
// suppressMovieStop=false;
|
||||
// suppressAddPowerCommand=0;
|
||||
// }
|
||||
//
|
||||
// if(!FCEUSS_LoadFP(fp,SSLOADPARAM_BACKUP)) return;
|
||||
//
|
||||
// ResetInputTypes();
|
||||
//
|
||||
// fseek(fp, firstframeoffset, SEEK_SET);
|
||||
// moviedata = (uint8*)realloc(moviedata, moviedatasize);
|
||||
// fread(moviedata, 1, moviedatasize, fp);
|
||||
//
|
||||
// framecount = 0; // movies start at frame 0!
|
||||
// frameptr = 0;
|
||||
// current = 0;
|
||||
// slots = fp;
|
||||
//
|
||||
// memset(joop,0,sizeof(joop));
|
||||
// current = -1 - current;
|
||||
// framets=0;
|
||||
// nextts=0;
|
||||
// nextd = -1;
|
||||
// FCEU_DispMessage("Movie playback started.");
|
||||
//}
|
||||
//
|
||||
//static int FCEUI_MovieGetInfo_v1(const char* fname, MOVIE_INFO* info)
|
||||
//{
|
||||
// uint32 magic;
|
||||
// uint32 version;
|
||||
// uint8 _flags[4];
|
||||
// uint32 savestateoffset;
|
||||
// uint8 tmp[MOVIE_MAX_METADATA<<1];
|
||||
// int metadata_length;
|
||||
//
|
||||
// FILE* fp = FCEUD_UTF8fopen(fname, "rb");
|
||||
// if(!fp)
|
||||
// return 0;
|
||||
//
|
||||
// read32le(&magic, fp);
|
||||
// if(magic != MOVIE_MAGIC)
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// read32le(&version, fp);
|
||||
// if(version != 1)
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// info->movie_version = 1;
|
||||
// info->emu_version_used = 0; // unknown
|
||||
//
|
||||
// fread(_flags, 1, 4, fp);
|
||||
//
|
||||
// info->flags = _flags[0];
|
||||
// read32le(&info->num_frames, fp);
|
||||
// read32le(&info->rerecord_count, fp);
|
||||
//
|
||||
// if(access(fname, W_OK))
|
||||
// info->read_only = 1;
|
||||
// else
|
||||
// info->read_only = 0;
|
||||
//
|
||||
// fseek(fp, 4, SEEK_CUR);
|
||||
// read32le(&savestateoffset, fp);
|
||||
//
|
||||
// metadata_length = (int)savestateoffset - MOVIE_V1_HEADER_SIZE;
|
||||
// if(metadata_length > 0)
|
||||
// {
|
||||
// //int i; //mbg merge 7/17/06 removed
|
||||
//
|
||||
// metadata_length >>= 1;
|
||||
// if(metadata_length >= MOVIE_MAX_METADATA)
|
||||
// metadata_length = MOVIE_MAX_METADATA-1;
|
||||
//
|
||||
// fseek(fp, MOVIE_V1_HEADER_SIZE, SEEK_SET);
|
||||
// fread(tmp, 1, metadata_length<<1, fp);
|
||||
// }
|
||||
//
|
||||
// // turn old ucs2 metadata into utf8
|
||||
// if(info->metadata && info->metadata_size)
|
||||
// {
|
||||
// char* ptr=info->metadata;
|
||||
// char* ptr_end=info->metadata+info->metadata_size-1;
|
||||
// int c_ptr=0;
|
||||
// while(ptr<ptr_end && c_ptr<metadata_length)
|
||||
// {
|
||||
// uint16 c=(tmp[c_ptr<<1] | (tmp[(c_ptr<<1)+1] << 8));
|
||||
// //mbg merge 7/17/06 changed to if..elseif
|
||||
// if(c<=0x7f)
|
||||
// *ptr++ = (char)(c&0x7f);
|
||||
// else if(c<=0x7FF)
|
||||
// if(ptr+1>=ptr_end)
|
||||
// ptr_end=ptr;
|
||||
// else
|
||||
// {
|
||||
// *ptr++=(0xc0 | (c>>6));
|
||||
// *ptr++=(0x80 | (c & 0x3f));
|
||||
// }
|
||||
// else
|
||||
// if(ptr+2>=ptr_end)
|
||||
// ptr_end=ptr;
|
||||
// else
|
||||
// {
|
||||
// *ptr++=(0xe0 | (c>>12));
|
||||
// *ptr++=(0x80 | ((c>>6) & 0x3f));
|
||||
// *ptr++=(0x80 | (c & 0x3f));
|
||||
// }
|
||||
//
|
||||
// c_ptr++;
|
||||
// }
|
||||
// *ptr='\0';
|
||||
// }
|
||||
//
|
||||
// // md5 info not available from v1
|
||||
// info->md5_of_rom_used_present = 0;
|
||||
// // rom name used for the movie not available from v1
|
||||
// if(info->name_of_rom_used && info->name_of_rom_used_size)
|
||||
// info->name_of_rom_used[0] = '\0';
|
||||
//
|
||||
// // check what hacks are necessary
|
||||
// fseek(fp, 24, SEEK_SET); // offset_to_savestate offset
|
||||
// uint32 temp_savestate_offset;
|
||||
// read32le(&temp_savestate_offset, fp);
|
||||
// if(fseek(fp, temp_savestate_offset, SEEK_SET))
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return 0;
|
||||
// }
|
||||
// if(!FCEUSS_LoadFP(fp,SSLOADPARAM_DUMMY)) return 0; // 2 -> don't really load, just load to find what's there then load backup
|
||||
//
|
||||
//
|
||||
// fclose(fp);
|
||||
// return 1;
|
||||
//}
|
||||
|
||||
|
||||
//
|
||||
//// PlayMovie / MoviePlay function
|
||||
//void _old_FCEUI_LoadMovie(char *fname, int _read_only, int _stopframe)
|
||||
//{
|
||||
// char buffer [512];
|
||||
// //fname = (char*)convertToFCM(fname,buffer);
|
||||
//
|
||||
// FILE *fp;
|
||||
// char *fn = NULL;
|
||||
//
|
||||
// FCEUI_StopMovie();
|
||||
//
|
||||
// if(!fname)
|
||||
// fname = fn = FCEU_MakeFName(FCEUMKF_MOVIE,0,0);
|
||||
//
|
||||
// char origname[512];
|
||||
// strcpy(origname,fname);
|
||||
//
|
||||
// pauseframe = _stopframe;
|
||||
//
|
||||
// // check movie_readonly
|
||||
// movie_readonly = _read_only;
|
||||
// if(access(fname, W_OK))
|
||||
// movie_readonly = 2;
|
||||
//
|
||||
// fp = FCEUD_UTF8fopen(fname, (movie_readonly>=2) ? "rb" : "r+b");
|
||||
//
|
||||
// if(fn)
|
||||
// {
|
||||
// free(fn);
|
||||
// fname = NULL;
|
||||
// }
|
||||
//
|
||||
// if(!fp) return;
|
||||
//
|
||||
// // read header
|
||||
//
|
||||
// uint32 magic;
|
||||
// uint32 version;
|
||||
// uint8 flags[4];
|
||||
//
|
||||
// read32le(&magic, fp);
|
||||
// if(magic != MOVIE_MAGIC)
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return;
|
||||
// }
|
||||
// //DEBUG_COMPARE_RAM(__LINE__);
|
||||
//
|
||||
// read32le(&version, fp);
|
||||
// if(version == 1)
|
||||
// {
|
||||
// // attempt to load previous version's format
|
||||
// fclose(fp);
|
||||
// FCEUI_LoadMovie_v1(fname, _read_only);
|
||||
// return;
|
||||
// }
|
||||
// else if(version == MOVIE_VERSION)
|
||||
// {}
|
||||
// else
|
||||
// {
|
||||
// // unsupported version
|
||||
// fclose(fp);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// fread(flags, 1, 4, fp);
|
||||
// read32le(&framecount, fp);
|
||||
// read32le(&rerecord_count, fp);
|
||||
// read32le(&moviedatasize, fp);
|
||||
// read32le(&savestate_offset, fp);
|
||||
// read32le(&firstframeoffset, fp);
|
||||
//
|
||||
// // FCEU_PrintError("flags[0] & MOVIE_FLAG_NOSYNCHACK=%d",flags[0] & MOVIE_FLAG_NOSYNCHACK);
|
||||
// if(flags[0] & MOVIE_FLAG_NOSYNCHACK)
|
||||
// movieSyncHackOn=0;
|
||||
// else
|
||||
// movieSyncHackOn=1;
|
||||
//
|
||||
// if(flags[0] & MOVIE_FLAG_PAL)
|
||||
// {
|
||||
// FCEUI_SetVidSystem(1);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// FCEUI_SetVidSystem(0);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// // fully reload the game to reinitialize everything before playing any movie
|
||||
// // to try fixing nondeterministic playback of some games
|
||||
// {
|
||||
// extern char lastLoadedGameName [2048];
|
||||
// extern int disableBatteryLoading, suppressAddPowerCommand;
|
||||
// suppressAddPowerCommand=1;
|
||||
// suppressMovieStop=true;
|
||||
// {
|
||||
// FCEUGI * gi = FCEUI_LoadGame(lastLoadedGameName, 0);
|
||||
// if(!gi)
|
||||
// PowerNES();
|
||||
// }
|
||||
// suppressMovieStop=false;
|
||||
// suppressAddPowerCommand=0;
|
||||
// }
|
||||
//
|
||||
// if(flags[0] & MOVIE_FLAG_FROM_POWERON)
|
||||
// {
|
||||
// //don't need to load a savestate
|
||||
// //there shouldn't be a savestate!
|
||||
// if(savestate_offset != 0xFFFFFFFF)
|
||||
// FCEU_PrintError("Savestate found in a start-from-poweron movie!");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// if(savestate_offset == 0xFFFFFFFF)
|
||||
// FCEU_PrintError("No savestate found in a start-from-savestate movie!");
|
||||
//
|
||||
// if(fseek(fp, savestate_offset, SEEK_SET))
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if(!FCEUSS_LoadFP(fp,SSLOADPARAM_BACKUP))
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if(flags[0] & MOVIE_FLAG_PAL)
|
||||
// {
|
||||
// FCEUI_SetVidSystem(1);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// FCEUI_SetVidSystem(0);
|
||||
// }
|
||||
// ResetInputTypes();
|
||||
//
|
||||
// fseek(fp, firstframeoffset, SEEK_SET);
|
||||
// moviedata = (uint8*)realloc(moviedata, moviedatasize);
|
||||
// fread(moviedata, 1, moviedatasize, fp);
|
||||
//
|
||||
// framecount = 0; // movies start at frame 0!
|
||||
// frameptr = 0;
|
||||
// current = 0;
|
||||
// slots = fp;
|
||||
//
|
||||
// memset(joop,0,sizeof(joop));
|
||||
// current = -1 - current;
|
||||
// framets=0;
|
||||
// nextts=0;
|
||||
// nextd = -1;
|
||||
//
|
||||
// FCEU_DispMessage("Movie playback started.");
|
||||
//
|
||||
// strcpy(curMovieFilename, origname);
|
||||
//}
|
||||
|
||||
|
||||
//static void DoEncode(int joy, int button, int dummy)
|
||||
//{
|
||||
// uint8 d;
|
||||
//
|
||||
// d = 0;
|
||||
//
|
||||
// if(framets >= 65536)
|
||||
// d = 3 << 5;
|
||||
// else if(framets >= 256)
|
||||
// d = 2 << 5;
|
||||
// else if(framets > 0)
|
||||
// d = 1 << 5;
|
||||
//
|
||||
// if(dummy) d|=0x80;
|
||||
//
|
||||
// d |= joy << 3;
|
||||
// d |= button;
|
||||
//
|
||||
// movie_writechar(d);
|
||||
// //printf("Wr: %02x, %d\n",d,slots[current-1]);
|
||||
// while(framets)
|
||||
// {
|
||||
// movie_writechar(framets & 0xff);
|
||||
// //printf("Wrts: %02x\n",framets & 0xff);
|
||||
// framets >>= 8;
|
||||
// }
|
||||
//}
|
||||
|
|
|
@ -120,7 +120,7 @@ public:
|
|||
std::vector<char> savestate;
|
||||
std::vector<MovieRecord> records;
|
||||
//this is the RERECORD COUNT. please rename variable.
|
||||
int recordCount;
|
||||
int rerecordCount;
|
||||
FCEU_Guid guid;
|
||||
|
||||
//was the frame data stored in binary?
|
||||
|
|
|
@ -0,0 +1,623 @@
|
|||
#include "types.h"
|
||||
#include "fceu.h"
|
||||
#include "driver.h"
|
||||
|
||||
#include "oldmovie.h"
|
||||
#include "movie.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// FCM\x1a
|
||||
#define MOVIE_MAGIC 0x1a4d4346
|
||||
|
||||
// still at 2 since the format itself is still compatible
|
||||
// to detect which version the movie was made with, check the fceu version stored in the movie header
|
||||
// (e.g against FCEU_VERSION_NUMERIC)
|
||||
#define MOVIE_VERSION 2
|
||||
|
||||
//-------
|
||||
//this is just supposed to be a comment describing the disk format
|
||||
//---
|
||||
//struct MovieHeader
|
||||
//{
|
||||
//uint32 magic; // +0
|
||||
//uint32 version=2; // +4
|
||||
//uint8 flags[4]; // +8
|
||||
//uint32 length_frames; // +12
|
||||
//uint32 rerecord_count; // +16
|
||||
//uint32 movie_data_size; // +20
|
||||
//uint32 offset_to_savestate; // +24, should be 4-byte-aligned
|
||||
//uint32 offset_to_movie_data; // +28, should be 4-byte-aligned
|
||||
//uint8 md5_of_rom_used[16]; // +32
|
||||
//uint32 version_of_emu_used // +48
|
||||
//char name_of_rom_used[] // +52, utf-8, null-terminated
|
||||
//char metadata[]; // utf-8, null-terminated
|
||||
//uint8 padding[];
|
||||
//uint8 savestate[]; // always present, even in a "from reset" recording
|
||||
//uint8 padding[]; // used for byte-alignment
|
||||
//uint8 movie_data[];
|
||||
//};
|
||||
//-------
|
||||
|
||||
static uint8 joop[4];
|
||||
static uint32 framets = 0;
|
||||
static uint32 frameptr = 0;
|
||||
static uint8* moviedata = NULL;
|
||||
static uint32 moviedatasize = 0;
|
||||
static uint32 firstframeoffset = 0;
|
||||
static uint32 savestate_offset = 0;
|
||||
|
||||
//Cache variables used for playback.
|
||||
static uint32 nextts = 0;
|
||||
static int32 nextd = 0;
|
||||
|
||||
|
||||
static int movieConvertOffset1=0, movieConvertOffset2=0,movieSyncHackOn=0;
|
||||
|
||||
|
||||
//backwards compat
|
||||
static void FCEUI_LoadMovie_v1(char *fname, int _read_only);
|
||||
//static int FCEUI_MovieGetInfo_v1(const char* fname, MOVIE_INFO* info);
|
||||
|
||||
//int _old_FCEUI_MovieGetInfo(const char* fname, MOVIE_INFO* info)
|
||||
//{
|
||||
// //mbg: wtf?
|
||||
// //MovieFlushHeader();
|
||||
//
|
||||
// // main get info part of function
|
||||
// {
|
||||
// uint32 magic;
|
||||
// uint32 version;
|
||||
// uint8 _flags[4];
|
||||
//
|
||||
// FILE* fp = FCEUD_UTF8fopen(fname, "rb");
|
||||
// if(!fp)
|
||||
// return 0;
|
||||
//
|
||||
// read32le(&magic, fp);
|
||||
// if(magic != MOVIE_MAGIC)
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// read32le(&version, fp);
|
||||
// if(version != MOVIE_VERSION)
|
||||
// {
|
||||
// fclose(fp);
|
||||
// if(version == 1)
|
||||
// return FCEUI_MovieGetInfo_v1(fname, info);
|
||||
// else
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// info->movie_version = MOVIE_VERSION;
|
||||
//
|
||||
// fread(_flags, 1, 4, fp);
|
||||
//
|
||||
// info->flags = _flags[0];
|
||||
// read32le(&info->num_frames, fp);
|
||||
// read32le(&info->rerecord_count, fp);
|
||||
//
|
||||
// if(access(fname, W_OK))
|
||||
// info->read_only = 1;
|
||||
// else
|
||||
// info->read_only = 0;
|
||||
//
|
||||
// fseek(fp, 12, SEEK_CUR); // skip movie_data_size, offset_to_savestate, and offset_to_movie_data
|
||||
//
|
||||
// fread(&info->md5_of_rom_used, 1, 16, fp);
|
||||
// info->md5_of_rom_used_present = 1;
|
||||
//
|
||||
// read32le(&info->emu_version_used, fp);
|
||||
//
|
||||
// // I probably could have planned this better...
|
||||
// {
|
||||
// char str[256];
|
||||
// size_t r;
|
||||
// uint32 p; //mbg merge 7/17/06 change to uint32
|
||||
// int p2=0;
|
||||
// char last_c=32;
|
||||
//
|
||||
// if(info->name_of_rom_used && info->name_of_rom_used_size)
|
||||
// info->name_of_rom_used[0]='\0';
|
||||
//
|
||||
// r=fread(str, 1, 256, fp);
|
||||
// while(r > 0)
|
||||
// {
|
||||
// for(p=0; p<r && last_c != '\0'; ++p)
|
||||
// {
|
||||
// if(info->name_of_rom_used && info->name_of_rom_used_size && (p2 < info->name_of_rom_used_size-1))
|
||||
// {
|
||||
// info->name_of_rom_used[p2]=str[p];
|
||||
// p2++;
|
||||
// last_c=str[p];
|
||||
// }
|
||||
// }
|
||||
// if(p<r)
|
||||
// {
|
||||
// memmove(str, str+p, r-p);
|
||||
// r -= p;
|
||||
// break;
|
||||
// }
|
||||
// r=fread(str, 1, 256, fp);
|
||||
// }
|
||||
//
|
||||
// p2=0;
|
||||
// last_c=32;
|
||||
//
|
||||
// if(info->metadata && info->metadata_size)
|
||||
// info->metadata[0]='\0';
|
||||
//
|
||||
// while(r > 0)
|
||||
// {
|
||||
// for(p=0; p<r && last_c != '\0'; ++p)
|
||||
// {
|
||||
// if(info->metadata && info->metadata_size && (p2 < info->metadata_size-1))
|
||||
// {
|
||||
// info->metadata[p2]=str[p];
|
||||
// p2++;
|
||||
// last_c=str[p];
|
||||
// }
|
||||
// }
|
||||
// if(p != r)
|
||||
// break;
|
||||
// r=fread(str, 1, 256, fp);
|
||||
// }
|
||||
//
|
||||
// if(r<=0)
|
||||
// {
|
||||
// // somehow failed to read romname and metadata
|
||||
// fclose(fp);
|
||||
// return 0;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // check what hacks are necessary
|
||||
// fseek(fp, 24, SEEK_SET); // offset_to_savestate offset
|
||||
// uint32 temp_savestate_offset;
|
||||
// read32le(&temp_savestate_offset, fp);
|
||||
// if(temp_savestate_offset != 0xFFFFFFFF)
|
||||
// {
|
||||
// if(fseek(fp, temp_savestate_offset, SEEK_SET))
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// //don't really load, just load to find what's there then load backup
|
||||
// if(!FCEUSS_LoadFP(fp,SSLOADPARAM_DUMMY)) return 0;
|
||||
// }
|
||||
//
|
||||
// fclose(fp);
|
||||
// return 1;
|
||||
// }
|
||||
//}
|
||||
/*
|
||||
Backwards compat
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
struct MovieHeader_v1
|
||||
{
|
||||
uint32 magic;
|
||||
uint32 version=1;
|
||||
uint8 flags[4];
|
||||
uint32 length_frames;
|
||||
uint32 rerecord_count;
|
||||
uint32 movie_data_size;
|
||||
uint32 offset_to_savestate;
|
||||
uint32 offset_to_movie_data;
|
||||
uint16 metadata_ucs2[]; // ucs-2, ick! sizeof(metadata) = offset_to_savestate - MOVIE_HEADER_SIZE
|
||||
}
|
||||
*/
|
||||
|
||||
#define MOVIE_V1_HEADER_SIZE 32
|
||||
|
||||
//static void FCEUI_LoadMovie_v1(char *fname, int _read_only)
|
||||
//{
|
||||
// FILE *fp;
|
||||
// char *fn = NULL;
|
||||
//
|
||||
// FCEUI_StopMovie();
|
||||
//
|
||||
// if(!fname)
|
||||
// fname = fn = FCEU_MakeFName(FCEUMKF_MOVIE,0,0);
|
||||
//
|
||||
// // check movie_readonly
|
||||
// movie_readonly = _read_only;
|
||||
// if(access(fname, W_OK))
|
||||
// movie_readonly = 2;
|
||||
//
|
||||
// fp = FCEUD_UTF8fopen(fname, (movie_readonly>=2) ? "rb" : "r+b");
|
||||
//
|
||||
// if(fn)
|
||||
// {
|
||||
// free(fn);
|
||||
// fname = NULL;
|
||||
// }
|
||||
//
|
||||
// if(!fp) return;
|
||||
//
|
||||
// // read header
|
||||
// {
|
||||
// uint32 magic;
|
||||
// uint32 version;
|
||||
// uint8 flags[4];
|
||||
// uint32 fc;
|
||||
//
|
||||
// read32le(&magic, fp);
|
||||
// if(magic != MOVIE_MAGIC)
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// read32le(&version, fp);
|
||||
// if(version != 1)
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// fread(flags, 1, 4, fp);
|
||||
// read32le(&fc, fp);
|
||||
// read32le(&rerecord_count, fp);
|
||||
// read32le(&moviedatasize, fp);
|
||||
// read32le(&savestate_offset, fp);
|
||||
// read32le(&firstframeoffset, fp);
|
||||
// if(fseek(fp, savestate_offset, SEEK_SET))
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if(flags[0] & MOVIE_FLAG_NOSYNCHACK)
|
||||
// movieSyncHackOn=0;
|
||||
// else
|
||||
// movieSyncHackOn=1;
|
||||
// }
|
||||
//
|
||||
// // fully reload the game to reinitialize everything before playing any movie
|
||||
// // to try fixing nondeterministic playback of some games
|
||||
// {
|
||||
// extern char lastLoadedGameName [2048];
|
||||
// extern int disableBatteryLoading, suppressAddPowerCommand;
|
||||
// suppressAddPowerCommand=1;
|
||||
// suppressMovieStop=true;
|
||||
// {
|
||||
// FCEUGI * gi = FCEUI_LoadGame(lastLoadedGameName, 0);
|
||||
// if(!gi)
|
||||
// PowerNES();
|
||||
// }
|
||||
// suppressMovieStop=false;
|
||||
// suppressAddPowerCommand=0;
|
||||
// }
|
||||
//
|
||||
// if(!FCEUSS_LoadFP(fp,SSLOADPARAM_BACKUP)) return;
|
||||
//
|
||||
// ResetInputTypes();
|
||||
//
|
||||
// fseek(fp, firstframeoffset, SEEK_SET);
|
||||
// moviedata = (uint8*)realloc(moviedata, moviedatasize);
|
||||
// fread(moviedata, 1, moviedatasize, fp);
|
||||
//
|
||||
// framecount = 0; // movies start at frame 0!
|
||||
// frameptr = 0;
|
||||
// current = 0;
|
||||
// slots = fp;
|
||||
//
|
||||
// memset(joop,0,sizeof(joop));
|
||||
// current = -1 - current;
|
||||
// framets=0;
|
||||
// nextts=0;
|
||||
// nextd = -1;
|
||||
// FCEU_DispMessage("Movie playback started.");
|
||||
//}
|
||||
//
|
||||
//static int FCEUI_MovieGetInfo_v1(const char* fname, MOVIE_INFO* info)
|
||||
//{
|
||||
// uint32 magic;
|
||||
// uint32 version;
|
||||
// uint8 _flags[4];
|
||||
// uint32 savestateoffset;
|
||||
// uint8 tmp[MOVIE_MAX_METADATA<<1];
|
||||
// int metadata_length;
|
||||
//
|
||||
// FILE* fp = FCEUD_UTF8fopen(fname, "rb");
|
||||
// if(!fp)
|
||||
// return 0;
|
||||
//
|
||||
// read32le(&magic, fp);
|
||||
// if(magic != MOVIE_MAGIC)
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// read32le(&version, fp);
|
||||
// if(version != 1)
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
// info->movie_version = 1;
|
||||
// info->emu_version_used = 0; // unknown
|
||||
//
|
||||
// fread(_flags, 1, 4, fp);
|
||||
//
|
||||
// info->flags = _flags[0];
|
||||
// read32le(&info->num_frames, fp);
|
||||
// read32le(&info->rerecord_count, fp);
|
||||
//
|
||||
// if(access(fname, W_OK))
|
||||
// info->read_only = 1;
|
||||
// else
|
||||
// info->read_only = 0;
|
||||
//
|
||||
// fseek(fp, 4, SEEK_CUR);
|
||||
// read32le(&savestateoffset, fp);
|
||||
//
|
||||
// metadata_length = (int)savestateoffset - MOVIE_V1_HEADER_SIZE;
|
||||
// if(metadata_length > 0)
|
||||
// {
|
||||
// //int i; //mbg merge 7/17/06 removed
|
||||
//
|
||||
// metadata_length >>= 1;
|
||||
// if(metadata_length >= MOVIE_MAX_METADATA)
|
||||
// metadata_length = MOVIE_MAX_METADATA-1;
|
||||
//
|
||||
// fseek(fp, MOVIE_V1_HEADER_SIZE, SEEK_SET);
|
||||
// fread(tmp, 1, metadata_length<<1, fp);
|
||||
// }
|
||||
//
|
||||
// // turn old ucs2 metadata into utf8
|
||||
// if(info->metadata && info->metadata_size)
|
||||
// {
|
||||
// char* ptr=info->metadata;
|
||||
// char* ptr_end=info->metadata+info->metadata_size-1;
|
||||
// int c_ptr=0;
|
||||
// while(ptr<ptr_end && c_ptr<metadata_length)
|
||||
// {
|
||||
// uint16 c=(tmp[c_ptr<<1] | (tmp[(c_ptr<<1)+1] << 8));
|
||||
// //mbg merge 7/17/06 changed to if..elseif
|
||||
// if(c<=0x7f)
|
||||
// *ptr++ = (char)(c&0x7f);
|
||||
// else if(c<=0x7FF)
|
||||
// if(ptr+1>=ptr_end)
|
||||
// ptr_end=ptr;
|
||||
// else
|
||||
// {
|
||||
// *ptr++=(0xc0 | (c>>6));
|
||||
// *ptr++=(0x80 | (c & 0x3f));
|
||||
// }
|
||||
// else
|
||||
// if(ptr+2>=ptr_end)
|
||||
// ptr_end=ptr;
|
||||
// else
|
||||
// {
|
||||
// *ptr++=(0xe0 | (c>>12));
|
||||
// *ptr++=(0x80 | ((c>>6) & 0x3f));
|
||||
// *ptr++=(0x80 | (c & 0x3f));
|
||||
// }
|
||||
//
|
||||
// c_ptr++;
|
||||
// }
|
||||
// *ptr='\0';
|
||||
// }
|
||||
//
|
||||
// // md5 info not available from v1
|
||||
// info->md5_of_rom_used_present = 0;
|
||||
// // rom name used for the movie not available from v1
|
||||
// if(info->name_of_rom_used && info->name_of_rom_used_size)
|
||||
// info->name_of_rom_used[0] = '\0';
|
||||
//
|
||||
// // check what hacks are necessary
|
||||
// fseek(fp, 24, SEEK_SET); // offset_to_savestate offset
|
||||
// uint32 temp_savestate_offset;
|
||||
// read32le(&temp_savestate_offset, fp);
|
||||
// if(fseek(fp, temp_savestate_offset, SEEK_SET))
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return 0;
|
||||
// }
|
||||
// if(!FCEUSS_LoadFP(fp,SSLOADPARAM_DUMMY)) return 0; // 2 -> don't really load, just load to find what's there then load backup
|
||||
//
|
||||
//
|
||||
// fclose(fp);
|
||||
// return 1;
|
||||
//}
|
||||
|
||||
static int movie_readchar()
|
||||
{
|
||||
if(frameptr >= moviedatasize)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return (int)(moviedata[frameptr++]);
|
||||
}
|
||||
|
||||
|
||||
static void FCEUMOV_AddJoy()
|
||||
{
|
||||
while(nextts == framets || nextd == -1)
|
||||
{
|
||||
int tmp,ti;
|
||||
uint8 d;
|
||||
|
||||
if(nextd != -1)
|
||||
{
|
||||
if(nextd&0x80)
|
||||
{
|
||||
//puts("Egads");
|
||||
//FCEU_DoSimpleCommand(nextd&0x1F);
|
||||
}
|
||||
else
|
||||
joop[(nextd >> 3)&0x3] ^= 1 << (nextd&0x7);
|
||||
}
|
||||
|
||||
|
||||
tmp = movie_readchar();
|
||||
d = tmp;
|
||||
|
||||
if(tmp < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
nextts = 0;
|
||||
tmp >>= 5;
|
||||
tmp &= 0x3;
|
||||
ti=0;
|
||||
|
||||
int tmpfix = tmp;
|
||||
while(tmp--) { nextts |= movie_readchar() << (ti * 8); ti++; }
|
||||
|
||||
// This fixes a bug in movies recorded before version 0.98.11
|
||||
// It's probably not necessary, but it may keep away CRAZY PEOPLE who recorded
|
||||
// movies on <= 0.98.10 and don't work on playback.
|
||||
if(tmpfix == 1 && !nextts)
|
||||
{nextts |= movie_readchar()<<8; }
|
||||
else if(tmpfix == 2 && !nextts) {nextts |= movie_readchar()<<16; }
|
||||
|
||||
if(nextd != -1)
|
||||
framets = 0;
|
||||
nextd = d;
|
||||
}
|
||||
|
||||
framets++;
|
||||
}
|
||||
|
||||
|
||||
EFCM_CONVERTRESULT convert_fcm(MovieData& md, std::string fname)
|
||||
{
|
||||
//convert EVEN OLDER movies to fcm
|
||||
//fname = (char*)convertToFCM(fname,buffer);
|
||||
|
||||
uint32 framecount;
|
||||
uint32 rerecord_count;
|
||||
|
||||
|
||||
ifstream* fp = (ifstream*)FCEUD_UTF8_fstream(fname, "rb");
|
||||
if(!fp) false;
|
||||
|
||||
// read header
|
||||
uint32 magic;
|
||||
uint32 version;
|
||||
uint8 flags[4];
|
||||
|
||||
read32le(&magic, fp);
|
||||
if(magic != MOVIE_MAGIC)
|
||||
{
|
||||
delete fp;
|
||||
return FCM_CONVERTRESULT_FAILOPEN;
|
||||
}
|
||||
|
||||
read32le(&version, fp);
|
||||
if(version == 1)
|
||||
{
|
||||
// attempt to load previous version's format
|
||||
//TODO
|
||||
delete fp;
|
||||
//FCEUI_LoadMovie_v1(fname, _read_only);
|
||||
return FCM_CONVERTRESULT_OLDVERSION;
|
||||
}
|
||||
else if(version == MOVIE_VERSION)
|
||||
{}
|
||||
else
|
||||
{
|
||||
// unsupported version
|
||||
delete fp;
|
||||
return FCM_CONVERTRESULT_UNSUPPORTEDVERSION;
|
||||
}
|
||||
|
||||
|
||||
fp->read((char*)&flags,4);
|
||||
read32le(&framecount, fp);
|
||||
read32le(&rerecord_count, fp);
|
||||
read32le(&moviedatasize, fp);
|
||||
read32le(&savestate_offset, fp);
|
||||
read32le(&firstframeoffset, fp);
|
||||
|
||||
// FCEU_PrintError("flags[0] & MOVIE_FLAG_NOSYNCHACK=%d",flags[0] & MOVIE_FLAG_NOSYNCHACK);
|
||||
if(flags[0] & MOVIE_FLAG_NOSYNCHACK)
|
||||
movieSyncHackOn=0;
|
||||
else
|
||||
movieSyncHackOn=1;
|
||||
|
||||
//if(flags[0] & MOVIE_FLAG_PAL)
|
||||
//if(flags[0] & MOVIE_FLAG_FROM_POWERON)
|
||||
//{
|
||||
// //don't need to load a savestate
|
||||
// //there shouldn't be a savestate!
|
||||
// if(savestate_offset != 0xFFFFFFFF)
|
||||
// FCEU_PrintError("Savestate found in a start-from-poweron movie!");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// if(savestate_offset == 0xFFFFFFFF)
|
||||
// FCEU_PrintError("No savestate found in a start-from-savestate movie!");
|
||||
|
||||
// if(fseek(fp, savestate_offset, SEEK_SET))
|
||||
// {
|
||||
// fclose(fp);
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if(!FCEUSS_LoadFP(fp,SSLOADPARAM_BACKUP))
|
||||
// return;
|
||||
//}
|
||||
|
||||
|
||||
//analyze input types?
|
||||
//ResetInputTypes();
|
||||
|
||||
fp->seekg(firstframeoffset,ios::beg);
|
||||
moviedata = (uint8*)realloc(moviedata, moviedatasize);
|
||||
fp->read((char*)moviedata,moviedatasize);
|
||||
|
||||
frameptr = 0;
|
||||
memset(joop,0,sizeof(joop));
|
||||
framets=0;
|
||||
nextts=0;
|
||||
nextd = -1;
|
||||
|
||||
//prepare output structure
|
||||
md.rerecordCount = rerecord_count;
|
||||
md.records.resize(framecount);
|
||||
|
||||
//begin decoding.
|
||||
//joymask is used to look for any joystick that has input.
|
||||
//if joysticks 3 or 4 have input then we will enable fourscore
|
||||
uint8 joymask[4] = {0,0,0,0};
|
||||
for(uint32 i=0;i<framecount;i++)
|
||||
{
|
||||
FCEUMOV_AddJoy();
|
||||
md.records[i].commands = 0;
|
||||
for(int j=0;j<4;j++) {
|
||||
joymask[j] |= joop[j];
|
||||
md.records[i].joysticks[j] = joop[j];
|
||||
}
|
||||
}
|
||||
|
||||
md.ports[2] = SIS_NONE;
|
||||
if(joymask[2] || joymask[3])
|
||||
{
|
||||
md.fourscore = true;
|
||||
md.ports[0] = md.ports[1] = SI_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
md.fourscore = false;
|
||||
md.ports[0] = md.ports[1] = SI_GAMEPAD ;
|
||||
}
|
||||
|
||||
free(moviedata);
|
||||
moviedata = 0;
|
||||
|
||||
return FCM_CONVERTRESULT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef _OLDMOVIE_H_
|
||||
#define _OLDMOVIE_H_
|
||||
|
||||
#include "movie.h"
|
||||
|
||||
enum EFCM_CONVERTRESULT
|
||||
{
|
||||
FCM_CONVERTRESULT_SUCCESS,
|
||||
FCM_CONVERTRESULT_FAILOPEN,
|
||||
FCM_CONVERTRESULT_OLDVERSION,
|
||||
FCM_CONVERTRESULT_UNSUPPORTEDVERSION,
|
||||
};
|
||||
|
||||
EFCM_CONVERTRESULT convert_fcm(MovieData& md, std::string fname);
|
||||
|
||||
#endif
|
|
@ -1579,6 +1579,10 @@
|
|||
RelativePath="..\src\nsf.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\oldmovie.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\palette.h"
|
||||
>
|
||||
|
@ -2321,6 +2325,10 @@
|
|||
RelativePath="..\src\nsf.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\oldmovie.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\palette.cpp"
|
||||
>
|
||||
|
|
Loading…
Reference in New Issue