some work on the zapper movie recording, but it is not finished and a lot will have to be scrapped. there was some useful refactoring in here though so i am checking it in

This commit is contained in:
zeromus 2008-06-06 08:23:12 +00:00
parent ab82d07be8
commit a4fb078f3c
7 changed files with 115 additions and 122 deletions

View File

@ -1238,17 +1238,17 @@ std::fstream* FCEUD_UTF8_fstream(const char *n, const char *m)
} }
std::ios_base::openmode mode = std::ios_base::binary; std::ios_base::openmode mode = std::ios_base::binary;
if(!strcmp(m,"r")) if(!strcmp(m,"r") || !strcmp(m,"rb"))
mode |= std::ios_base::in; mode |= std::ios_base::in;
else if(!strcmp(m,"w")) else if(!strcmp(m,"w") || !strcmp(m,"wb"))
mode |= std::ios_base::out | std::ios_base::trunc; mode |= std::ios_base::out | std::ios_base::trunc;
else if(!strcmp(m,"a")) else if(!strcmp(m,"a") || !strcmp(m,"ab"))
mode |= std::ios_base::out | std::ios_base::app; mode |= std::ios_base::out | std::ios_base::app;
else if(!strcmp(m,"r+")) else if(!strcmp(m,"r+") || !strcmp(m,"r+b"))
mode |= std::ios_base::in | std::ios_base::out; mode |= std::ios_base::in | std::ios_base::out;
else if(!strcmp(m,"w+")) else if(!strcmp(m,"w+") || !strcmp(m,"w+b"))
mode |= std::ios_base::in | std::ios_base::out | std::ios_base::trunc; mode |= std::ios_base::in | std::ios_base::out | std::ios_base::trunc;
else if(!strcmp(m,"a+")) else if(!strcmp(m,"a+") || !strcmp(m,"a+b"))
mode |= std::ios_base::in | std::ios_base::out | std::ios_base::app; mode |= std::ios_base::in | std::ios_base::out | std::ios_base::app;
return new std::fstream(n,mode); return new std::fstream(n,mode);

View File

@ -7,6 +7,8 @@
#include "../../movie.h" #include "../../movie.h"
#include "../../utils/xstring.h" #include "../../utils/xstring.h"
using namespace std;
//to change header font //to change header font
//http://forums.devx.com/archive/index.php/t-37234.html //http://forums.devx.com/archive/index.php/t-37234.html
@ -306,9 +308,10 @@ static void Export()
ofn.lpstrInitialDir=FCEU_GetPath(FCEUMKF_MOVIE); ofn.lpstrInitialDir=FCEU_GetPath(FCEUMKF_MOVIE);
if(GetSaveFileName(&ofn)) if(GetSaveFileName(&ofn))
{ {
FILE* outf = fopen(ofn.lpstrFile,"wb"); fstream* osRecordingMovie = FCEUD_UTF8_fstream(ofn.lpstrFile, "wb");
currMovieData.dump(outf); currMovieData.dump(osRecordingMovie);
fclose(outf); osRecordingMovie->close();
delete osRecordingMovie;
} }
} }

View File

@ -30,6 +30,7 @@
#include "netplay.h" #include "netplay.h"
#include "movie.h" #include "movie.h"
#include "state.h" #include "state.h"
#include "input/zapper.h"
#include "input.h" #include "input.h"
#include "vsuni.h" #include "vsuni.h"
@ -286,7 +287,7 @@ void FCEU_UpdateInput(void)
if(FCEUnetplay) if(FCEUnetplay)
NetplayUpdate(joy); NetplayUpdate(joy);
FCEUMOV_AddJoy(joy, BotMode); FCEUMOV_AddInputState(ZD, joy, BotMode);
if(GameInfo->type==GIT_VSUNI) if(GameInfo->type==GIT_VSUNI)
FCEU_VSUniSwap(&joy[0],&joy[1]); FCEU_VSUniSwap(&joy[0],&joy[1]);

View File

@ -22,16 +22,9 @@
#include <stdlib.h> #include <stdlib.h>
#include "share.h" #include "share.h"
#include "zapper.h"
typedef struct { ZAPPER ZD[2];
uint32 mzx,mzy,mzb;
int zap_readbit;
int bogo;
int zappo;
uint64 zaphit;
} ZAPPER;
static ZAPPER ZD[2];
static void ZapperFrapper(int w, uint8 *bg, uint8 *spr, uint32 linets, int final) static void ZapperFrapper(int w, uint8 *bg, uint8 *spr, uint32 linets, int final)
{ {

15
src/input/zapper.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef _ZAPPER_H_
#define _ZAPPER_H_
struct ZAPPER
{
uint32 mzx,mzy,mzb;
int zap_readbit;
int bogo;
int zappo;
uint64 zaphit;
};
extern ZAPPER ZD[2];
#endif

View File

@ -3,6 +3,7 @@
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <zlib.h> #include <zlib.h>
#include <iomanip>
#ifdef WIN32 #ifdef WIN32
#include <windows.h> #include <windows.h>
@ -51,7 +52,8 @@ bool suppressMovieStop=false;
EMOVIEMODE movieMode = MOVIEMODE_INACTIVE; EMOVIEMODE movieMode = MOVIEMODE_INACTIVE;
//this should not be set unless we are in MOVIEMODE_RECORD! //this should not be set unless we are in MOVIEMODE_RECORD!
FILE* fpRecordingMovie = 0; //FILE* fpRecordingMovie = 0;
fstream* osRecordingMovie = 0;
int currFrameCounter; int currFrameCounter;
uint32 cur_input_display = 0; uint32 cur_input_display = 0;
@ -120,49 +122,17 @@ void MovieRecord::dump(std::ostream* os, int index)
} }
//separate the joysticks //separate the joysticks
if(i != 3) os->put('|'); os->put('|');
} }
//write the zapper state
*os << setw(3) << setfill('0') << (int)zappers[0].x << ' ' << setw(3) << setfill('0') << (int)zappers[0].y << setw(1) << ' ' << (int)zappers[0].b << '|';
*os << setw(3) << setfill('0') << (int)zappers[1].x << ' ' << setw(3) << setfill('0') << (int)zappers[1].y << setw(1) << ' ' << (int)zappers[1].b;
//each frame is on a new line //each frame is on a new line
os->put('\n'); os->put('\n');
} }
void MovieRecord::dump(FILE* fp, 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);
fputc('|',fp);
//for each joystick
for(int i=0;i<4;i++)
{
//these are mnemonics for each joystick bit.
//since we usually use the regular joypad, these will be more helpful.
//but any character other than ' ' should count as a set bit
//maybe other input types will need to be encoded another way..
for(int bit=7;bit>=0;bit--)
{
uint8 &joystate = joysticks[i];
int bitmask = (1<<bit);
char mnemonic = mnemonics[bit];
//if the bit is set write the mnemonic
if(joystate & bitmask)
fputc(mnemonic,fp);
else //otherwise write a space
fputc(' ',fp);
}
//separate the joysticks
if(i != 3) fputc('|',fp);
}
//each frame is on a new line
fputc('\n',fp);
}
MovieData::MovieData() MovieData::MovieData()
: version(MOVIE_VERSION) : version(MOVIE_VERSION)
, emuVersion(FCEU_VERSION_NUMERIC) , emuVersion(FCEU_VERSION_NUMERIC)
@ -223,23 +193,6 @@ void MovieData::dump(std::ostream *os)
records[i].dump(os,i); records[i].dump(os,i);
} }
void MovieData::dump(FILE *fp)
{
fprintf(fp,"version %d\n", version);
fprintf(fp,"emuVersion %d\n", emuVersion);
fprintf(fp,"recordCount %d\n", recordCount);
fprintf(fp,"palFlag %d\n", palFlag?1:0);
fprintf(fp,"poweronFlag %d\n", poweronFlag?1:0);
fprintf(fp,"resetFlag %d\n", resetFlag?1:0);
fprintf(fp,"romFilename %s\n", romFilename.c_str());
fprintf(fp,"romChecksum %s\n", BytesToString(romChecksum.data,MD5DATA::size).c_str());
fprintf(fp,"guid %s\n", guid.toString().c_str());
if(savestate.size() != 0)
fprintf(fp,"savestate %s\n", BytesToString(&savestate[0],savestate.size()).c_str());
for(int i=0;i<(int)records.size();i++)
records[i].dump(fp,i);
}
int MovieData::dumpLen() int MovieData::dumpLen()
{ {
memorystream ms; memorystream ms;
@ -288,7 +241,7 @@ void LoadFM2(MovieData& movieData, FILE *fp)
std::string key,value; std::string key,value;
enum { enum {
NEWLINE, KEY, SEPARATOR, VALUE, RECORD NEWLINE, KEY, SEPARATOR, VALUE, RECORD, COMMENT
} state = NEWLINE; } state = NEWLINE;
bool bail = false; bool bail = false;
for(;;) for(;;)
@ -312,7 +265,8 @@ void LoadFM2(MovieData& movieData, FILE *fp)
value = ""; value = "";
goto dokey; goto dokey;
break; break;
case RECORD: { case RECORD:
{
dorecord: dorecord:
MovieRecord record; MovieRecord record;
//for each joystick //for each joystick
@ -331,10 +285,22 @@ void LoadFM2(MovieData& movieData, FILE *fp)
//eat the separator (a pipe or a newline) //eat the separator (a pipe or a newline)
fgetc(fp); fgetc(fp);
} }
//crappy parser
char tmp[4] = {0,0,0,0};
fread(tmp,1,3,fp); record.zappers[0].x = atoi(tmp); fgetc(fp);
fread(tmp,1,3,fp); record.zappers[0].y = atoi(tmp); fgetc(fp);
tmp[1] = 0;
fread(tmp,1,1,fp); record.zappers[0].b = atoi(tmp); fgetc(fp);
fread(tmp,1,3,fp); record.zappers[1].x = atoi(tmp); fgetc(fp);
fread(tmp,1,3,fp); record.zappers[1].y = atoi(tmp); fgetc(fp);
tmp[1] = 0;
fread(tmp,1,1,fp); record.zappers[1].b = atoi(tmp); fgetc(fp);
movieData.records.push_back(record); movieData.records.push_back(record);
state = NEWLINE; state = NEWLINE;
break; break;
} }
case KEY: case KEY:
dokey: //dookie dokey: //dookie
state = KEY; state = KEY;
@ -383,8 +349,9 @@ void StopRecording()
FCEU_DispMessage("Movie recording stopped."); FCEU_DispMessage("Movie recording stopped.");
movieMode = MOVIEMODE_INACTIVE; movieMode = MOVIEMODE_INACTIVE;
fclose(fpRecordingMovie); //fclose(fpRecordingMovie);
fpRecordingMovie = 0; //fpRecordingMovie = 0;
osRecordingMovie = 0;
} }
@ -404,21 +371,22 @@ void FCEUI_StopMovie()
void ParseGIInput(FCEUGI *GI); //mbg merge 7/17/06 - had to add. gross. void ParseGIInput(FCEUGI *GI); //mbg merge 7/17/06 - had to add. gross.
void InitOtherInput(void); //mbg merge 7/17/06 - had to add. gross. void InitOtherInput(void); //mbg merge 7/17/06 - had to add. gross.
//TODO - i dont think some of this like gametype and cspec are necessary
static void ResetInputTypes() static void ResetInputTypes()
{ {
#ifdef WIN32 //#ifdef WIN32
extern int UsrInputType[3]; // extern int UsrInputType[3];
UsrInputType[0] = SI_GAMEPAD; // UsrInputType[0] = SI_GAMEPAD;
UsrInputType[1] = SI_GAMEPAD; // UsrInputType[1] = SI_GAMEPAD;
UsrInputType[2] = SIFC_NONE; // UsrInputType[2] = SIFC_NONE;
//
ParseGIInput(NULL/*GameInfo*/); // ParseGIInput(NULL/*GameInfo*/);
extern int cspec, gametype; // extern int cspec, gametype;
cspec=GameInfo->cspecial; // cspec=GameInfo->cspecial;
gametype=GameInfo->type; // gametype=GameInfo->type;
//
InitOtherInput(); // InitOtherInput();
#endif //#endif
} }
@ -565,14 +533,23 @@ void FCEUI_LoadMovie(char *fname, bool _read_only, int _pauseframe)
static void closeRecordingMovie() static void closeRecordingMovie()
{ {
if(fpRecordingMovie) //if(fpRecordingMovie)
fclose(fpRecordingMovie); // fclose(fpRecordingMovie);
if(osRecordingMovie)
{
osRecordingMovie->close();
delete osRecordingMovie;
}
} }
static void openRecordingMovie(const char* fname) static void openRecordingMovie(const char* fname)
{ {
fpRecordingMovie = FCEUD_UTF8fopen(fname, "wb"); //fpRecordingMovie = FCEUD_UTF8fopen(fname, "wb");
if(!fpRecordingMovie) //if(!fpRecordingMovie)
// FCEU_PrintError("Error opening movie output file: %s",fname);
osRecordingMovie = FCEUD_UTF8_fstream(fname, "wb");
if(!osRecordingMovie)
FCEU_PrintError("Error opening movie output file: %s",fname); FCEU_PrintError("Error opening movie output file: %s",fname);
strcpy(curMovieFilename, fname); strcpy(curMovieFilename, fname);
} }
@ -611,7 +588,7 @@ void FCEUI_SaveMovie(char *fname, uint8 flags)
} }
//we are going to go ahead and dump the header. from now on we will only be appending frames //we are going to go ahead and dump the header. from now on we will only be appending frames
currMovieData.dump(fpRecordingMovie); currMovieData.dump(osRecordingMovie);
//todo - think about this //todo - think about this
ResetInputTypes(); ResetInputTypes();
@ -631,7 +608,7 @@ void FCEUI_SaveMovie(char *fname, uint8 flags)
//the main interaction point between the emulator and the movie system. //the main interaction point between the emulator and the movie system.
//either dumps the current joystick state or loads one state from the movie //either dumps the current joystick state or loads one state from the movie
void FCEUMOV_AddJoy(uint8 *js, int SkipFlush) void FCEUMOV_AddInputState(ZAPPER (&zappers)[2], uint8 (&js)[4], int SkipFlush)
{ {
//todo - for tasedit, either dump or load depending on whether input recording is enabled //todo - for tasedit, either dump or load depending on whether input recording is enabled
//or something like that //or something like that
@ -650,6 +627,13 @@ void FCEUMOV_AddJoy(uint8 *js, int SkipFlush)
MovieRecord& mr = currMovieData.records[currFrameCounter]; MovieRecord& mr = currMovieData.records[currFrameCounter];
for(int i=0;i<4;i++) for(int i=0;i<4;i++)
js[i] = mr.joysticks[i]; js[i] = mr.joysticks[i];
for(int i=0;i<2;i++)
{
zappers[i].mzx = mr.zappers[i].x;
zappers[i].mzy = mr.zappers[i].y;
zappers[i].mzb = mr.zappers[i].b;
}
} }
//if we are on the last frame, then pause the emulator if the player requested it //if we are on the last frame, then pause the emulator if the player requested it
@ -677,7 +661,16 @@ void FCEUMOV_AddJoy(uint8 *js, int SkipFlush)
for(int i=0;i<4;i++) for(int i=0;i<4;i++)
mr.joysticks[i] = js[i]; mr.joysticks[i] = js[i];
mr.dump(fpRecordingMovie,currMovieData.records.size()); //printf("%d %d %d\n",zappers[1].mzx,zappers[1].mzy,zappers[1].mzb);
for(int i=0;i<2;i++)
{
mr.zappers[i].x = zappers[i].mzx;
mr.zappers[i].y = zappers[i].mzy;
mr.zappers[i].b = zappers[i].mzb;
}
mr.dump(osRecordingMovie,currMovieData.records.size());
currMovieData.records.push_back(mr); currMovieData.records.push_back(mr);
} }
@ -730,22 +723,6 @@ int FCEUMOV_WriteState(std::ostream* os)
else return 0; else return 0;
} }
int FCEUMOV_WriteState(FILE* st)
{
//we are supposed to dump the movie data into the savestate
if(movieMode == MOVIEMODE_RECORD || movieMode == MOVIEMODE_PLAY)
{
int todo = currMovieData.dumpLen();
if(st)
currMovieData.dump(st);
return todo;
}
else return 0;
}
static bool load_successful; static bool load_successful;
bool FCEUMOV_ReadState(FILE* st, uint32 size) bool FCEUMOV_ReadState(FILE* st, uint32 size)
@ -816,7 +793,7 @@ bool FCEUMOV_ReadState(FILE* st, uint32 size)
currMovieData.recordCount++; currMovieData.recordCount++;
openRecordingMovie(curMovieFilename); openRecordingMovie(curMovieFilename);
currMovieData.dump(fpRecordingMovie); currMovieData.dump(osRecordingMovie);
movieMode = MOVIEMODE_RECORD; movieMode = MOVIEMODE_RECORD;
} }
} }

View File

@ -6,7 +6,9 @@
#include <string> #include <string>
#include <ostream> #include <ostream>
void FCEUMOV_AddJoy(uint8 *, int SkipFlush); #include "input/zapper.h"
void FCEUMOV_AddInputState(ZAPPER (&zappers)[2], uint8 (&js)[4], int SkipFlush);
void FCEUMOV_AddCommand(int cmd); void FCEUMOV_AddCommand(int cmd);
void FCEU_DrawMovies(uint8 *); void FCEU_DrawMovies(uint8 *);
@ -25,7 +27,7 @@ bool FCEUMOV_Mode(int modemask);
bool FCEUMOV_ShouldPause(void); bool FCEUMOV_ShouldPause(void);
int FCEUMOV_GetFrame(void); int FCEUMOV_GetFrame(void);
int FCEUMOV_WriteState(FILE* st); //int FCEUMOV_WriteState(FILE* st);
int FCEUMOV_WriteState(std::ostream* os); int FCEUMOV_WriteState(std::ostream* os);
bool FCEUMOV_ReadState(FILE* st, uint32 size); bool FCEUMOV_ReadState(FILE* st, uint32 size);
void FCEUMOV_PreLoad(); void FCEUMOV_PreLoad();
@ -40,6 +42,10 @@ class MovieRecord
public: public:
ValueArray<uint8,4> joysticks; ValueArray<uint8,4> joysticks;
struct {
uint8 x,y,b;
} zappers[2];
void toggleBit(int joy, int bit) void toggleBit(int joy, int bit)
{ {
joysticks[joy] ^= mask(bit); joysticks[joy] ^= mask(bit);
@ -73,7 +79,6 @@ public:
//a waste of memory in lots of cases.. maybe make it a pointer later? //a waste of memory in lots of cases.. maybe make it a pointer later?
std::vector<char> savestate; std::vector<char> savestate;
void dump(FILE* fp, int index);
void dump(std::ostream* os, int index); void dump(std::ostream* os, int index);
static const char mnemonics[8]; static const char mnemonics[8];
@ -138,7 +143,6 @@ public:
void truncateAt(int frame); void truncateAt(int frame);
void installDictionary(TDictionary& dictionary); void installDictionary(TDictionary& dictionary);
void dump(FILE *fp);
void dump(std::ostream* os); void dump(std::ostream* os);
int dumpLen(); int dumpLen();
void clearRecordRange(int start, int len); void clearRecordRange(int start, int len);