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 "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
@ -132,6 +131,8 @@ BEGIN
MENUITEM "&Alternate A and B", MENU_ALTERNATE_AB
MENUITEM SEPARATOR
MENUITEM "Use &External Input", MENU_EXTERNAL_INPUT
MENUITEM SEPARATOR
MENUITEM "Convert FCM...", MENU_CONVERT_MOVIE
END
POPUP "&Debug"
BEGIN

View File

@ -29,8 +29,8 @@
#include "wave.h"
#include "input.h"
#include "video.h"
#include "../../input.h"
#include "../../fceu.h"
#include "input.h"
#include "fceu.h"
#include "memwatch.h"
#include "ppuview.h"
@ -55,6 +55,7 @@
#include "gui.h"
#include "help.h"
#include "movie.h"
#include "utils/xstring.h"
#include <fstream>
@ -133,6 +134,7 @@ static void ConvertFCM(HWND hwndOwner)
{
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)
{
//multiselect
@ -150,17 +152,29 @@ static void ConvertFCM(HWND hwndOwner)
todo.push_back(ofn.lpstrFile);
}
SetCursor(LoadCursor(0,IDC_WAIT));
//convert each movie
int okcount = 0;
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)
EFCM_CONVERTRESULT result = convert_fcm(md, infname);
if(result==FCM_CONVERTRESULT_SUCCESS)
{
okcount++;
std::fstream* outf = FCEUD_UTF8_fstream(outname, "wb");
md.dump(outf,false);
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 << "port2 " << ports[2] << endl;
for(int i=0;i<comments.size();i++)
*os << "comment " << comments[i] << endl;
if(binary)
*os << "binary 1" << endl;

View File

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

View File

@ -1,9 +1,11 @@
#include "types.h"
#include "fceu.h"
#include "driver.h"
#include "netplay.h"
#include "oldmovie.h"
#include "movie.h"
#include "utils/xstring.h"
#include <fstream>
@ -42,6 +44,7 @@ using namespace std;
//-------
static uint8 joop[4];
static uint8 joopcmd;
static uint32 framets = 0;
static uint32 frameptr = 0;
static uint8* moviedata = NULL;
@ -54,8 +57,6 @@ 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);
@ -442,7 +443,7 @@ static int movie_readchar()
}
static void FCEUMOV_AddJoy()
static void _addjoy()
{
while(nextts == framets || nextd == -1)
{
@ -453,8 +454,10 @@ static void FCEUMOV_AddJoy()
{
if(nextd&0x80)
{
//puts("Egads");
//FCEU_DoSimpleCommand(nextd&0x1F);
int command = nextd&0x1F;
if(command = FCEUNPCMD_RESET)
joopcmd = MOVIECMD_RESET;
}
else
joop[(nextd >> 3)&0x3] ^= 1 << (nextd&0x7);
@ -500,6 +503,7 @@ EFCM_CONVERTRESULT convert_fcm(MovieData& md, std::string fname)
uint32 framecount;
uint32 rerecord_count;
int movieConvertOffset1=0, movieConvertOffset2=0,movieSyncHackOn=0;
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(&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);
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;
//}
if(flags[0] & MOVIE_FLAG_PAL)
md.palFlag = true;
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?
//ResetInputTypes();
@ -589,6 +593,7 @@ EFCM_CONVERTRESULT convert_fcm(MovieData& md, std::string fname)
//prepare output structure
md.rerecordCount = rerecord_count;
md.records.resize(framecount);
md.guid.newGuid();
//begin decoding.
//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};
for(uint32 i=0;i<framecount;i++)
{
FCEUMOV_AddJoy();
md.records[i].commands = 0;
joopcmd = 0;
if(i==0 && initreset)
joopcmd = MOVIECMD_RESET;
_addjoy();
md.records[i].commands = joopcmd;
for(int j=0;j<4;j++) {
joymask[j] |= joop[j];
md.records[i].joysticks[j] = joop[j];
@ -613,7 +621,7 @@ EFCM_CONVERTRESULT convert_fcm(MovieData& md, std::string fname)
else
{
md.fourscore = false;
md.ports[0] = md.ports[1] = SI_GAMEPAD ;
md.ports[0] = md.ports[1] = SI_GAMEPAD;
}
free(moviedata);

View File

@ -9,8 +9,22 @@ enum EFCM_CONVERTRESULT
FCM_CONVERTRESULT_FAILOPEN,
FCM_CONVERTRESULT_OLDVERSION,
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);
#endif

View File

@ -470,3 +470,16 @@ std::string stditoa(int n)
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 readNullTerminatedAscii(std::istream* is);
//extracts a decimal uint from an istream
template<typename T> T templateIntegerDecFromIstream(std::istream* is)
{