rlm@1: #ifndef VBA_MOVIE_H rlm@1: #define VBA_MOVIE_H rlm@1: rlm@1: #if _MSC_VER > 1000 rlm@1: #pragma once rlm@1: #endif // _MSC_VER > 1000 rlm@1: rlm@1: #include rlm@1: #include rlm@1: rlm@1: #include "../Port.h" rlm@1: rlm@1: #define ZLIB rlm@1: ///#ifdef ZLIB rlm@1: #ifndef WIN32 rlm@1: #include "zlib.h" rlm@1: #endif rlm@1: rlm@1: #ifndef MOVIE_SUCCESS rlm@1: # define MOVIE_SUCCESS 1 rlm@1: # define MOVIE_NOTHING 0 rlm@1: # define MOVIE_WRONG_FORMAT (-1) rlm@1: # define MOVIE_WRONG_VERSION (-2) rlm@1: # define MOVIE_FILE_NOT_FOUND (-3) rlm@1: # define MOVIE_NOT_FROM_THIS_MOVIE (-4) rlm@1: # define MOVIE_NOT_FROM_A_MOVIE (-5) rlm@1: # define MOVIE_SNAPSHOT_INCONSISTENT (-6) rlm@1: # define MOVIE_UNKNOWN_ERROR (-7) rlm@1: #endif rlm@1: rlm@1: #define VBM_MAGIC (0x1a4D4256) // VBM0x1a rlm@1: #define VBM_VERSION (1) rlm@1: #define VBM_HEADER_SIZE (64) rlm@1: #define CONTROLLER_DATA_SIZE (2) rlm@1: #define BUFFER_GROWTH_SIZE (4096) rlm@1: #define MOVIE_METADATA_SIZE (192) rlm@1: #define MOVIE_METADATA_AUTHOR_SIZE (64) rlm@1: rlm@1: // revision 1 uses (?) insted of (!) as reset rlm@1: #define VBM_REVISION (1) rlm@1: rlm@1: #define MOVIE_START_FROM_SNAPSHOT (1<<0) rlm@1: #define MOVIE_START_FROM_SRAM (1<<1) rlm@1: rlm@1: #define MOVIE_CONTROLLER(i) (1<<(i)) rlm@1: #define MOVIE_CONTROLLERS_ANY_MASK (MOVIE_CONTROLLER(0)|MOVIE_CONTROLLER(1)|MOVIE_CONTROLLER(2)|MOVIE_CONTROLLER(3)) rlm@1: #define MOVIE_NUM_OF_POSSIBLE_CONTROLLERS (4) rlm@1: rlm@1: #define MOVIE_TYPE_GBA (1<<0) rlm@1: #define MOVIE_TYPE_GBC (1<<1) rlm@1: #define MOVIE_TYPE_SGB (1<<2) rlm@1: rlm@1: #define MOVIE_SETTING_USEBIOSFILE (1<<0) rlm@1: #define MOVIE_SETTING_SKIPBIOSFILE (1<<1) rlm@1: #define MOVIE_SETTING_RTCENABLE (1<<2) rlm@1: #define MOVIE_SETTING_GBINPUTHACK (1<<3) rlm@1: #define MOVIE_SETTING_LAGHACK (1<<4) rlm@1: #define MOVIE_SETTING_GBCFF55FIX (1<<5) rlm@1: #define MOVIE_SETTING_GBECHORAMFIX (1<<6) rlm@1: rlm@1: #define STREAM gzFile rlm@1: /*#define READ_STREAM(p,l,s) gzread (s,p,l) rlm@1: #define WRITE_STREAM(p,l,s) gzwrite (s,p,l) rlm@1: #define OPEN_STREAM(f,m) gzopen (f,m) rlm@1: #define REOPEN_STREAM(f,m) gzdopen (f,m) rlm@1: #define FIND_STREAM(f) gztell(f) rlm@1: #define REVERT_STREAM(f,o,s) gzseek(f,o,s) rlm@1: #define CLOSE_STREAM(s) gzclose (s) rlm@1: #else rlm@1: #define STREAM FILE * rlm@1: #define READ_STREAM(p,l,s) fread (p,1,l,s) rlm@1: #define WRITE_STREAM(p,l,s) fwrite (p,1,l,s) rlm@1: #define OPEN_STREAM(f,m) fopen (f,m) rlm@1: #define REOPEN_STREAM(f,m) fdopen (f,m) rlm@1: #define FIND_STREAM(f) ftell(f) rlm@1: #define REVERT_STREAM(f,o,s) fseek(f,o,s) rlm@1: #define CLOSE_STREAM(s) fclose (s) rlm@1: #endif*/ rlm@1: rlm@1: enum MovieState rlm@1: { rlm@1: MOVIE_STATE_NONE = 0, rlm@1: MOVIE_STATE_PLAY, rlm@1: MOVIE_STATE_RECORD, rlm@1: MOVIE_STATE_END rlm@1: }; rlm@1: rlm@1: struct SMovieFileHeader rlm@1: { rlm@1: uint32 magic; // VBM0x1a rlm@1: uint32 version; // 1 rlm@1: int32 uid; // used to match savestates to a particular movie rlm@1: uint32 length_frames; rlm@1: uint32 rerecord_count; rlm@1: uint8 startFlags; rlm@1: uint8 controllerFlags; rlm@1: uint8 typeFlags; rlm@1: uint8 optionFlags; rlm@1: uint32 saveType; // emulator setting value rlm@1: uint32 flashSize; // emulator setting value rlm@1: uint32 gbEmulatorType; // emulator setting value rlm@1: char romTitle [12]; rlm@1: uint8 minorVersion; // minor version/revision of the current movie version rlm@1: uint8 romCRC; // the CRC of the ROM used while recording rlm@1: uint16 romOrBiosChecksum; // the Checksum of the ROM used while recording, or a CRC of the BIOS if GBA rlm@1: uint32 romGameCode; // the Game Code of the ROM used while recording, or "\0\0\0\0" if not GBA rlm@1: uint32 offset_to_savestate; // offset to the savestate or SRAM inside file, set to 0 if unused rlm@1: uint32 offset_to_controller_data; // offset to the controller data inside file rlm@1: }; rlm@1: rlm@1: struct SMovie rlm@1: { rlm@1: enum MovieState state; rlm@1: char filename[/*_MAX_PATH*/ 260]; // FIXME: should use a string instead rlm@1: FILE* file; rlm@1: uint8 readOnly; rlm@1: int32 pauseFrame; // FIXME: byte size rlm@1: rlm@1: SMovieFileHeader header; rlm@1: char authorInfo[MOVIE_METADATA_SIZE]; rlm@1: rlm@1: uint32 currentFrame; // should == length_frame when recording, and be < length_frames when playing rlm@1: uint32 bytesPerFrame; rlm@1: uint8* inputBuffer; rlm@1: uint32 inputBufferSize; rlm@1: uint8* inputBufferPtr; rlm@1: rlm@1: // bool8 doesn't make much sense if it is meant to solve any portability problem, rlm@1: // because there's no guarantee that true == 1 and false == 0 (or TRUE == 1 and FALSE == 0) on all platforms. rlm@1: // while using user-defined boolean types might impact on performance. rlm@1: // the more reliable (and faster!) way to maintain cross-platform I/O compatibility is rlm@1: // to manually map from/to built-in boolean types to/from fixed-sized types value by value ONLY when doing I/O rlm@1: // e.g. bool(true) <-> u8(1) and <-> bool(false) <-> u8(0), BOOL(TRUE) <-> s32(-1) and BOOL(FALSE) <-> s32(0) etc. rlm@1: bool8 RecordedThisSession; rlm@1: }; rlm@1: rlm@1: // methods used by the user-interface code rlm@1: int VBAMovieOpen(const char *filename, bool8 read_only); rlm@1: int VBAMovieCreate(const char *filename, const char *authorInfo, uint8 startFlags, uint8 controllerFlags, uint8 typeFlags); rlm@1: int VBAMovieGetInfo(const char *filename, SMovie*info); rlm@1: void VBAMovieGetRomInfo(const SMovie &movieInfo, char romTitle[12], uint32 &romGameCode, uint16 &checksum, uint8 &crc); rlm@1: void VBAMovieStop(bool8 suppress_message); rlm@1: const char *VBAChooseMovieFilename(bool8 read_only); rlm@1: rlm@1: // methods used by the emulation rlm@1: void VBAMovieInit(); rlm@1: void VBAMovieUpdateState(); rlm@1: void VBAMovieRead(int controllerNum = 0, bool sensor = false); rlm@1: void VBAMovieWrite(int controllerNum = 0, bool sensor = false); rlm@1: void VBAUpdateButtonPressDisplay(); rlm@1: void VBAUpdateFrameCountDisplay(); rlm@1: //bool8 VBAMovieRewind (uint32 at_frame); rlm@1: void VBAMovieFreeze(uint8 **buf, uint32 *size); rlm@1: int VBAMovieUnfreeze(const uint8 *buf, uint32 size); rlm@1: void VBAMovieRestart(); rlm@1: rlm@1: // accessor functions rlm@1: bool8 VBAMovieActive(); rlm@1: bool8 VBAMovieLoading(); rlm@1: bool8 VBAMoviePlaying(); rlm@1: bool8 VBAMovieRecording(); rlm@1: // the following accessors return 0/false if !VBAMovieActive() rlm@1: uint8 VBAMovieReadOnly(); rlm@1: uint32 VBAMovieGetVersion(); rlm@1: uint32 VBAMovieGetMinorVersion(); rlm@1: uint32 VBAMovieGetId(); rlm@1: uint32 VBAMovieGetLength(); rlm@1: uint32 VBAMovieGetFrameCounter(); rlm@1: uint32 VBAMovieGetState(); rlm@1: uint32 VBAMovieGetRerecordCount (); rlm@1: uint32 VBAMovieSetRerecordCount (uint32 newRerecordCount); rlm@1: std::string VBAMovieGetAuthorInfo(); rlm@1: std::string VBAMovieGetFilename(); rlm@1: rlm@1: uint16 VBAMovieGetCurrentInputOf(int controllerNum, bool normalOnly = true); rlm@1: void VBAMovieSignalReset(); rlm@1: void VBAMovieResetIfRequested(); rlm@1: void VBAMovieSetMetadata(const char *info); rlm@1: void VBAMovieToggleReadOnly(); rlm@1: bool VBAMovieEnded(); rlm@1: bool VBAMovieAllowsRerecording(); rlm@1: bool VBAMovieSwitchToPlaying(); rlm@1: bool VBAMovieSwitchToRecording(); rlm@1: int VBAMovieGetPauseAt(); rlm@1: void VBAMovieSetPauseAt(int at); rlm@1: int VBAMovieConvertCurrent(); rlm@1: bool VBAMovieTuncateAtCurrentFrame(); rlm@1: bool VBAMovieFixHeader(); rlm@1: rlm@1: #endif // VBA_MOVIE_H