mirror of
https://github.com/dborth/fceugx.git
synced 2024-11-01 15:05:05 +01:00
678 lines
15 KiB
C++
678 lines
15 KiB
C++
#include "version.h"
|
|
#include "types.h"
|
|
#include "fceu.h"
|
|
#include "driver.h"
|
|
#include "netplay.h"
|
|
|
|
#include "oldmovie.h"
|
|
#include "movie.h"
|
|
#include "utils/xstring.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 uint8 joopcmd;
|
|
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;
|
|
|
|
// turn old ucs2 metadata into utf8
|
|
void convert_metadata(char* metadata, int metadata_size, uint8* tmp, int metadata_length)
|
|
{
|
|
char* ptr=metadata;
|
|
char* ptr_end=metadata+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';
|
|
}
|
|
|
|
//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.",0);
|
|
//}
|
|
//
|
|
//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 _addjoy()
|
|
{
|
|
while(nextts == framets || nextd == -1)
|
|
{
|
|
int tmp,ti;
|
|
uint8 d;
|
|
|
|
if(nextd != -1)
|
|
{
|
|
if(nextd&0x80)
|
|
{
|
|
//FCEU_DoSimpleCommand(nextd&0x1F);
|
|
int command = nextd&0x1F;
|
|
if(command == FCEUNPCMD_RESET)
|
|
joopcmd = MOVIECMD_RESET;
|
|
if(command == FCEUNPCMD_POWER)
|
|
joopcmd = MOVIECMD_POWER;
|
|
}
|
|
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;
|
|
int movieConvertOffset1=0, movieConvertOffset2=0,movieSyncHackOn=0;
|
|
|
|
|
|
EMUFILE* fp = FCEUD_UTF8_fstream(fname, "rb");
|
|
if(!fp) return FCM_CONVERTRESULT_FAILOPEN;
|
|
|
|
// read header
|
|
uint32 magic = 0;
|
|
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->fread((char*)&flags,4);
|
|
read32le(&framecount, fp);
|
|
read32le(&rerecord_count, fp);
|
|
read32le(&moviedatasize, fp);
|
|
read32le(&savestate_offset, fp);
|
|
read32le(&firstframeoffset, fp);
|
|
|
|
//read header values
|
|
fp->fread((char*)&md.romChecksum,16);
|
|
read32le((uint32*)&md.emuVersion,fp);
|
|
|
|
md.romFilename = readNullTerminatedAscii(fp);
|
|
|
|
md.comments.push_back(L"author " + mbstowcs(readNullTerminatedAscii(fp)));
|
|
|
|
//int metadata_length = savestate_offset - MOVIE_V1_HEADER_SIZE;
|
|
//uint8* metadata = new uint8[metadata_length];
|
|
//char* wcmetadata = new char[metadata_length*4]; //seems to me like we support the worst case
|
|
//fp->read((char*)metadata,metadata_length);
|
|
//convert_metadata(wcmetadata,metadata_length*4,metadata,metadata_length);
|
|
//md.comments.push_back(L"author " + (std::wstring)(wchar_t*)wcmetadata);
|
|
|
|
// 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)
|
|
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
|
|
{
|
|
delete fp;
|
|
return FCM_CONVERTRESULT_STARTFROMSAVESTATENOTSUPPORTED;
|
|
}
|
|
|
|
//analyze input types?
|
|
//ResetInputTypes();
|
|
|
|
fp->fseek(firstframeoffset,SEEK_SET);
|
|
moviedata = (uint8*)realloc(moviedata, moviedatasize);
|
|
fp->fread((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);
|
|
md.guid.newGuid();
|
|
|
|
//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++)
|
|
{
|
|
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];
|
|
}
|
|
}
|
|
|
|
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;
|
|
|
|
delete fp;
|
|
return FCM_CONVERTRESULT_SUCCESS;
|
|
}
|