-
Notifications
You must be signed in to change notification settings - Fork 10
/
movie.h
324 lines (266 loc) · 8.78 KB
/
movie.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
#ifndef __MOVIE_H_
#define __MOVIE_H_
#include "input/zapper.h"
#include "utils/guid.h"
#include "utils/md5.h"
#include <vector>
#include <map>
#include <string>
#include <ostream>
#include <cstdlib>
struct FCEUFILE;
enum EMOVIE_FLAG
{
MOVIE_FLAG_NONE = 0,
//an ARCHAIC flag which means the movie was recorded from a soft reset.
//WHY would you do this?? do not create any new movies with this flag
MOVIE_FLAG_FROM_RESET = (1<<1),
MOVIE_FLAG_PAL = (1<<2),
//movie was recorded from poweron. the alternative is from a savestate (or from reset). OR from saveram.
MOVIE_FLAG_FROM_POWERON = (1<<3),
// set in newer version, used for old movie compatibility
//TODO - only use this flag to print a warning that the sync might be bad
//so that we can get rid of the sync hack code
MOVIE_FLAG_NOSYNCHACK = (1<<4),
MOVIE_FLAG_FROM_SAVERAM = (1<<5)
};
typedef struct
{
int movie_version; // version of the movie format in the file
uint32 num_frames;
uint32 rerecord_count;
bool poweron, pal, nosynchack, ppuflag;
bool reset; //mbg 6/21/08 - this flag isnt used anymore.. but maybe one day we can scan it out of the first record in the movie file
uint32 emu_version_used; // 9813 = 0.98.13
MD5DATA md5_of_rom_used;
std::string name_of_rom_used;
int RAMInitOption, RAMInitSeed;
std::vector<std::wstring> comments;
std::vector<std::string> subtitles;
} MOVIE_INFO;
void FCEUMOV_AddInputState();
void FCEUMOV_AddCommand(int cmd);
void FCEU_DrawMovies(uint8 *);
void FCEU_DrawLagCounter(uint8 *);
enum EMOVIEMODE
{
MOVIEMODE_INACTIVE = 1,
MOVIEMODE_RECORD = 2,
MOVIEMODE_PLAY = 4,
MOVIEMODE_TASEDITOR = 8,
MOVIEMODE_FINISHED = 16
};
enum EMOVIERECORDMODE
{
MOVIE_RECORD_MODE_TRUNCATE = 0,
MOVIE_RECORD_MODE_OVERWRITE = 1,
MOVIE_RECORD_MODE_INSERT = 2,
//MOVIE_RECORD_MODE_XOR = 3,
MOVIE_RECORD_MODE_MAX
};
enum EMOVIECMD
{
MOVIECMD_RESET = 1,
MOVIECMD_POWER = 2,
MOVIECMD_FDS_INSERT = 4,
MOVIECMD_FDS_SELECT = 8,
MOVIECMD_VS_INSERTCOIN = 16,
MOVIECMD_VS_INSERTCOIN2 = 32,
MOVIECMD_VS_SERVICE = 64
};
EMOVIEMODE FCEUMOV_Mode();
bool FCEUMOV_Mode(EMOVIEMODE modemask);
bool FCEUMOV_Mode(int modemask);
inline bool FCEUMOV_IsPlaying() { return (FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_FINISHED)); }
inline bool FCEUMOV_IsRecording() { return FCEUMOV_Mode(MOVIEMODE_RECORD); }
inline bool FCEUMOV_IsFinished() { return FCEUMOV_Mode(MOVIEMODE_FINISHED);}
inline bool FCEUMOV_IsLoaded() { return (FCEUMOV_Mode(MOVIEMODE_PLAY|MOVIEMODE_RECORD|MOVIEMODE_FINISHED)); }
bool FCEUMOV_ShouldPause(void);
int FCEUMOV_GetFrame(void);
int FCEUI_GetLagCount(void);
bool FCEUI_GetLagged(void);
void FCEUI_SetLagFlag(bool value);
int FCEUMOV_WriteState(EMUFILE* os);
bool FCEUMOV_ReadState(EMUFILE* is, uint32 size);
void FCEUMOV_PreLoad();
bool FCEUMOV_PostLoad();
void FCEUMOV_IncrementRerecordCount();
bool FCEUMOV_FromPoweron();
void FCEUMOV_CreateCleanMovie();
void FCEUMOV_ClearCommands();
class MovieData;
class MovieRecord
{
public:
MovieRecord();
ValueArray<uint8,4> joysticks;
struct {
uint8 x,y,b,bogo;
uint64 zaphit;
} zappers[2];
//misc commands like reset, etc.
//small now to save space; we might need to support more commands later.
//the disk format will support up to 64bit if necessary
uint8 commands;
bool command_reset() { return (commands & MOVIECMD_RESET) != 0; }
bool command_power() { return (commands & MOVIECMD_POWER) != 0; }
bool command_fds_insert() { return (commands & MOVIECMD_FDS_INSERT) != 0; }
bool command_fds_select() { return (commands & MOVIECMD_FDS_SELECT) != 0; }
bool command_vs_insertcoin() { return (commands & MOVIECMD_VS_INSERTCOIN) != 0; }
bool command_vs_insertcoin2() { return (commands & MOVIECMD_VS_INSERTCOIN2) != 0; }
bool command_vs_service() { return (commands & MOVIECMD_VS_SERVICE) != 0; }
void toggleBit(int joy, int bit)
{
joysticks[joy] ^= mask(bit);
}
void setBit(int joy, int bit)
{
joysticks[joy] |= mask(bit);
}
void clearBit(int joy, int bit)
{
joysticks[joy] &= ~mask(bit);
}
void setBitValue(int joy, int bit, bool val)
{
if(val) setBit(joy,bit);
else clearBit(joy,bit);
}
bool checkBit(int joy, int bit)
{
return (joysticks[joy] & mask(bit))!=0;
}
bool Compare(MovieRecord& compareRec);
void Clone(MovieRecord& sourceRec);
void clear();
void parse(MovieData* md, EMUFILE* is);
bool parseBinary(MovieData* md, EMUFILE* is);
void dump(MovieData* md, EMUFILE* os, int index);
void dumpBinary(MovieData* md, EMUFILE* os, int index);
void parseJoy(EMUFILE* is, uint8& joystate);
void dumpJoy(EMUFILE* os, uint8 joystate);
static const char mnemonics[8];
private:
int mask(int bit) { return 1<<bit; }
};
class MovieData
{
public:
MovieData();
// Default Values: MovieData::MovieData()
int version;
int emuVersion;
int fds;
//todo - somehow force mutual exclusion for poweron and reset (with an error in the parser)
bool palFlag;
bool PPUflag;
MD5DATA romChecksum;
std::string romFilename;
std::vector<uint8> savestate;
std::vector<uint8> saveram;
std::vector<MovieRecord> records;
std::vector<std::wstring> comments;
std::vector<std::string> subtitles;
//this is the RERECORD COUNT. please rename variable.
int rerecordCount;
FCEU_Guid guid;
//was the frame data stored in binary?
bool binaryFlag;
// TAS Editor project files contain additional data after input
int loadFrameCount;
//which ports are defined for the movie
int ports[3];
//whether fourscore is enabled
bool fourscore;
//whether microphone is enabled
bool microphone;
int getNumRecords() { return static_cast<int>( records.size() ); }
int RAMInitOption, RAMInitSeed;
class TDictionary : public std::map<std::string,std::string>
{
public:
bool containsKey(std::string key)
{
return find(key) != end();
}
void tryInstallBool(std::string key, bool& val)
{
if(containsKey(key))
val = atoi(operator [](key).c_str())!=0;
}
void tryInstallString(std::string key, std::string& val)
{
if(containsKey(key))
val = operator [](key);
}
void tryInstallInt(std::string key, int& val)
{
if(containsKey(key))
val = atoi(operator [](key).c_str());
}
};
void truncateAt(int frame);
void installValue(std::string& key, std::string& val);
int dump(EMUFILE* os, bool binary, bool seekToCurrFramePos = false);
void clearRecordRange(int start, int len);
void eraseRecords(int at, int frames = 1);
void insertEmpty(int at, int frames);
void cloneRegion(int at, int frames);
static bool loadSavestateFrom(std::vector<uint8>* buf);
static void dumpSavestateTo(std::vector<uint8>* buf, int compressionLevel);
static bool loadSaveramFrom(std::vector<uint8>* buf);
static void dumpSaveramTo(std::vector<uint8>* buf, int compressionLevel);
private:
void installInt(std::string& val, int& var)
{
var = atoi(val.c_str());
}
void installBool(std::string& val, bool& var)
{
var = atoi(val.c_str())!=0;
}
};
extern EMOVIEMODE movieMode;
extern MovieData currMovieData;
extern int currFrameCounter;
extern std::string curMovieFilename;
extern bool subtitlesOnAVI;
extern bool freshMovie;
extern bool movie_readonly;
extern bool autoMovieBackup;
extern bool fullSaveStateLoads;
extern int movieRecordMode;
extern int input_display;
//--------------------------------------------------
void FCEUI_MakeBackupMovie(bool dispMessage);
void FCEUI_CreateMovieFile(std::string fn);
void FCEUI_SaveMovie(const char *fname, EMOVIE_FLAG flags, std::wstring author);
bool FCEUI_LoadMovie(const char *fname, bool read_only, int _stopframe);
void FCEUI_MoviePlayFromBeginning(void);
void FCEUI_StopMovie(void);
bool FCEUI_MovieGetInfo(FCEUFILE* fp, MOVIE_INFO& info, bool skipFrameCount = false);
//char* FCEUI_MovieGetCurrentName(int addSlotNumber);
void FCEUI_MovieToggleReadOnly(void);
void FCEUI_MovieToggleRecording();
void FCEUI_MovieInsertFrame();
void FCEUI_MovieDeleteFrame();
void FCEUI_MovieTruncate();
void FCEUI_MovieNextRecordMode();
void FCEUI_MoviePrevRecordMode();
void FCEUI_MovieRecordModeTruncate();
void FCEUI_MovieRecordModeOverwrite();
void FCEUI_MovieRecordModeInsert();
bool FCEUI_GetMovieToggleReadOnly();
void FCEUI_SetMovieToggleReadOnly(bool which);
int FCEUI_GetMovieLength();
int FCEUI_GetMovieRerecordCount();
std::string FCEUI_GetMovieName(void);
void FCEUI_MovieToggleFrameDisplay();
void FCEUI_MovieToggleRerecordDisplay();
void FCEUI_ToggleInputDisplay(void);
void LoadSubtitles(MovieData &);
void ProcessSubtitles(void);
void FCEU_DisplaySubtitles(const char *format, ...);
void poweron(bool shouldDisableBatteryLoading);
bool LoadFM2(MovieData& movieData, EMUFILE* fp, int size, bool stopAfterHeader);
#endif //__MOVIE_H_