better movie conversion

This commit is contained in:
zeromus 2008-06-22 22:25:30 +00:00
parent 851ef0d7fb
commit a91d2c414e
8 changed files with 89 additions and 33 deletions

View File

@ -49,7 +49,6 @@ BEGIN
MENUITEM "Record Movie...", MENU_RECORD_MOVIE MENUITEM "Record Movie...", MENU_RECORD_MOVIE
MENUITEM "Replay Movie...", MENU_REPLAY_MOVIE MENUITEM "Replay Movie...", MENU_REPLAY_MOVIE
MENUITEM "Stop Movie", MENU_STOP_MOVIE MENUITEM "Stop Movie", MENU_STOP_MOVIE
MENUITEM "Convert FCM...", MENU_CONVERT_MOVIE
MENUITEM SEPARATOR MENUITEM SEPARATOR
MENUITEM "Record AVI...", MENU_RECORD_AVI MENUITEM "Record AVI...", MENU_RECORD_AVI
MENUITEM "Stop AVI", MENU_STOP_AVI MENUITEM "Stop AVI", MENU_STOP_AVI
@ -132,6 +131,8 @@ BEGIN
MENUITEM "&Alternate A and B", MENU_ALTERNATE_AB MENUITEM "&Alternate A and B", MENU_ALTERNATE_AB
MENUITEM SEPARATOR MENUITEM SEPARATOR
MENUITEM "Use &External Input", MENU_EXTERNAL_INPUT MENUITEM "Use &External Input", MENU_EXTERNAL_INPUT
MENUITEM SEPARATOR
MENUITEM "Convert FCM...", MENU_CONVERT_MOVIE
END END
POPUP "&Debug" POPUP "&Debug"
BEGIN BEGIN

View File

@ -29,8 +29,8 @@
#include "wave.h" #include "wave.h"
#include "input.h" #include "input.h"
#include "video.h" #include "video.h"
#include "../../input.h" #include "input.h"
#include "../../fceu.h" #include "fceu.h"
#include "memwatch.h" #include "memwatch.h"
#include "ppuview.h" #include "ppuview.h"
@ -55,6 +55,7 @@
#include "gui.h" #include "gui.h"
#include "help.h" #include "help.h"
#include "movie.h" #include "movie.h"
#include "utils/xstring.h"
#include <fstream> #include <fstream>
@ -133,6 +134,7 @@ static void ConvertFCM(HWND hwndOwner)
{ {
std::vector<std::string> todo; std::vector<std::string> todo;
//build a list of movies to convert. this might be one, or it might be many, depending on what the user selected
if(ofn.nFileExtension==0) if(ofn.nFileExtension==0)
{ {
//multiselect //multiselect
@ -150,17 +152,29 @@ static void ConvertFCM(HWND hwndOwner)
todo.push_back(ofn.lpstrFile); todo.push_back(ofn.lpstrFile);
} }
SetCursor(LoadCursor(0,IDC_WAIT));
//convert each movie
int okcount = 0;
for(uint32 i=0;i<todo.size();i++) for(uint32 i=0;i<todo.size();i++)
{ {
std::string infname = todo[i]; std::string infname = todo[i];
std::string outname = infname + ".fm2"; std::string outname = infname + ".fm2";
MovieData md; MovieData md;
if(convert_fcm(md, infname)==FCM_CONVERTRESULT_SUCCESS) EFCM_CONVERTRESULT result = convert_fcm(md, infname);
if(result==FCM_CONVERTRESULT_SUCCESS)
{ {
okcount++;
std::fstream* outf = FCEUD_UTF8_fstream(outname, "wb"); std::fstream* outf = FCEUD_UTF8_fstream(outname, "wb");
md.dump(outf,false); md.dump(outf,false);
delete outf; delete outf;
} else {
std::string msg = "Failure converting " + infname + "\r\n\r\n" + EFCM_CONVERTRESULT_message(result);
MessageBox(hwndOwner,msg.c_str(),"Failure converting fcm", 0);
} }
std::string okmsg = "Converted " + stditoa(okcount) + " movie(s). There were " + stditoa(todo.size()-okcount) + " failure(s).";
MessageBox(hwndOwner,okmsg.c_str(),"FCM Conversion results", 0);
} }
} }

View File

@ -339,6 +339,9 @@ int MovieData::dump(std::ostream *os, bool binary)
*os << "port1 " << ports[1] << endl; *os << "port1 " << ports[1] << endl;
*os << "port2 " << ports[2] << endl; *os << "port2 " << ports[2] << endl;
for(int i=0;i<comments.size();i++)
*os << "comment " << comments[i] << endl;
if(binary) if(binary)
*os << "binary 1" << endl; *os << "binary 1" << endl;

View File

@ -119,6 +119,7 @@ public:
std::string romFilename; std::string romFilename;
std::vector<char> savestate; std::vector<char> savestate;
std::vector<MovieRecord> records; std::vector<MovieRecord> records;
std::vector<std::string> comments;
//this is the RERECORD COUNT. please rename variable. //this is the RERECORD COUNT. please rename variable.
int rerecordCount; int rerecordCount;
FCEU_Guid guid; FCEU_Guid guid;

View File

@ -1,9 +1,11 @@
#include "types.h" #include "types.h"
#include "fceu.h" #include "fceu.h"
#include "driver.h" #include "driver.h"
#include "netplay.h"
#include "oldmovie.h" #include "oldmovie.h"
#include "movie.h" #include "movie.h"
#include "utils/xstring.h"
#include <fstream> #include <fstream>
@ -42,6 +44,7 @@ using namespace std;
//------- //-------
static uint8 joop[4]; static uint8 joop[4];
static uint8 joopcmd;
static uint32 framets = 0; static uint32 framets = 0;
static uint32 frameptr = 0; static uint32 frameptr = 0;
static uint8* moviedata = NULL; static uint8* moviedata = NULL;
@ -54,8 +57,6 @@ static uint32 nextts = 0;
static int32 nextd = 0; static int32 nextd = 0;
static int movieConvertOffset1=0, movieConvertOffset2=0,movieSyncHackOn=0;
//backwards compat //backwards compat
static void FCEUI_LoadMovie_v1(char *fname, int _read_only); static void FCEUI_LoadMovie_v1(char *fname, int _read_only);
@ -442,7 +443,7 @@ static int movie_readchar()
} }
static void FCEUMOV_AddJoy() static void _addjoy()
{ {
while(nextts == framets || nextd == -1) while(nextts == framets || nextd == -1)
{ {
@ -453,8 +454,10 @@ static void FCEUMOV_AddJoy()
{ {
if(nextd&0x80) if(nextd&0x80)
{ {
//puts("Egads");
//FCEU_DoSimpleCommand(nextd&0x1F); //FCEU_DoSimpleCommand(nextd&0x1F);
int command = nextd&0x1F;
if(command = FCEUNPCMD_RESET)
joopcmd = MOVIECMD_RESET;
} }
else else
joop[(nextd >> 3)&0x3] ^= 1 << (nextd&0x7); joop[(nextd >> 3)&0x3] ^= 1 << (nextd&0x7);
@ -500,6 +503,7 @@ EFCM_CONVERTRESULT convert_fcm(MovieData& md, std::string fname)
uint32 framecount; uint32 framecount;
uint32 rerecord_count; uint32 rerecord_count;
int movieConvertOffset1=0, movieConvertOffset2=0,movieSyncHackOn=0;
ifstream* fp = (ifstream*)FCEUD_UTF8_fstream(fname, "rb"); ifstream* fp = (ifstream*)FCEUD_UTF8_fstream(fname, "rb");
@ -543,35 +547,35 @@ EFCM_CONVERTRESULT convert_fcm(MovieData& md, std::string fname)
read32le(&savestate_offset, fp); read32le(&savestate_offset, fp);
read32le(&firstframeoffset, fp); read32le(&firstframeoffset, fp);
//read header values
fp->read((char*)&md.romChecksum,16);
read32le((uint32*)&md.emuVersion,fp);
md.romFilename = readNullTerminatedAscii(fp);
md.comments.push_back("author " + readNullTerminatedAscii(fp));
// FCEU_PrintError("flags[0] & MOVIE_FLAG_NOSYNCHACK=%d",flags[0] & MOVIE_FLAG_NOSYNCHACK); // FCEU_PrintError("flags[0] & MOVIE_FLAG_NOSYNCHACK=%d",flags[0] & MOVIE_FLAG_NOSYNCHACK);
if(flags[0] & MOVIE_FLAG_NOSYNCHACK) if(flags[0] & MOVIE_FLAG_NOSYNCHACK)
movieSyncHackOn=0; movieSyncHackOn=0;
else else
movieSyncHackOn=1; movieSyncHackOn=1;
//if(flags[0] & MOVIE_FLAG_PAL) if(flags[0] & MOVIE_FLAG_PAL)
//if(flags[0] & MOVIE_FLAG_FROM_POWERON) md.palFlag = true;
//{
// //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;
//}
bool initreset = false;
if(flags[0] & MOVIE_FLAG_FROM_POWERON)
{
//don't need to load a savestate
}
else if(flags[0] & MOVIE_FLAG_FROM_RESET)
{
initreset = true;
}
else
{
return FCM_CONVERTRESULT_STARTFROMSAVESTATENOTSUPPORTED;
}
//analyze input types? //analyze input types?
//ResetInputTypes(); //ResetInputTypes();
@ -589,6 +593,7 @@ EFCM_CONVERTRESULT convert_fcm(MovieData& md, std::string fname)
//prepare output structure //prepare output structure
md.rerecordCount = rerecord_count; md.rerecordCount = rerecord_count;
md.records.resize(framecount); md.records.resize(framecount);
md.guid.newGuid();
//begin decoding. //begin decoding.
//joymask is used to look for any joystick that has input. //joymask is used to look for any joystick that has input.
@ -596,8 +601,11 @@ EFCM_CONVERTRESULT convert_fcm(MovieData& md, std::string fname)
uint8 joymask[4] = {0,0,0,0}; uint8 joymask[4] = {0,0,0,0};
for(uint32 i=0;i<framecount;i++) for(uint32 i=0;i<framecount;i++)
{ {
FCEUMOV_AddJoy(); joopcmd = 0;
md.records[i].commands = 0; if(i==0 && initreset)
joopcmd = MOVIECMD_RESET;
_addjoy();
md.records[i].commands = joopcmd;
for(int j=0;j<4;j++) { for(int j=0;j<4;j++) {
joymask[j] |= joop[j]; joymask[j] |= joop[j];
md.records[i].joysticks[j] = joop[j]; md.records[i].joysticks[j] = joop[j];

View File

@ -9,8 +9,22 @@ enum EFCM_CONVERTRESULT
FCM_CONVERTRESULT_FAILOPEN, FCM_CONVERTRESULT_FAILOPEN,
FCM_CONVERTRESULT_OLDVERSION, FCM_CONVERTRESULT_OLDVERSION,
FCM_CONVERTRESULT_UNSUPPORTEDVERSION, FCM_CONVERTRESULT_UNSUPPORTEDVERSION,
FCM_CONVERTRESULT_STARTFROMSAVESTATENOTSUPPORTED,
}; };
inline const char * EFCM_CONVERTRESULT_message(EFCM_CONVERTRESULT e)
{
static const char * errmsg[] = {
"Success",
"Failed to open input file",
"This is a 'version 1' movie file. These are not supported yet.",
"This is an unsupported ancient version",
"Movies starting from savestates are not supported"
};
return errmsg[e];
}
EFCM_CONVERTRESULT convert_fcm(MovieData& md, std::string fname); EFCM_CONVERTRESULT convert_fcm(MovieData& md, std::string fname);
#endif #endif

View File

@ -470,3 +470,16 @@ std::string stditoa(int n)
return tempbuf; return tempbuf;
} }
std::string readNullTerminatedAscii(std::istream* is)
{
std::string ret;
ret.reserve(50);
for(;;)
{
int c = is->get();
if(c == 0) break;
else ret += (char)c;
}
return ret;
}

View File

@ -57,6 +57,8 @@ char *U16ToHexStr(uint16 a);
std::string stditoa(int n); std::string stditoa(int n);
std::string readNullTerminatedAscii(std::istream* is);
//extracts a decimal uint from an istream //extracts a decimal uint from an istream
template<typename T> T templateIntegerDecFromIstream(std::istream* is) template<typename T> T templateIntegerDecFromIstream(std::istream* is)
{ {