2011-09-13 17:50:18 +03:00
|
|
|
#ifndef _moviefile__hpp__included__
|
|
|
|
#define _moviefile__hpp__included__
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <map>
|
2012-09-08 19:44:45 +03:00
|
|
|
#include "core/controllerframe.hpp"
|
2014-06-08 14:24:57 +03:00
|
|
|
#include "core/rom-small.hpp"
|
2012-09-08 19:44:45 +03:00
|
|
|
#include "core/subtitles.hpp"
|
2014-06-08 14:24:57 +03:00
|
|
|
#include "interface/romtype.hpp"
|
2014-02-02 18:35:36 +02:00
|
|
|
#include "library/rrdata.hpp"
|
2013-11-03 16:13:04 +02:00
|
|
|
#include "library/zip.hpp"
|
2011-09-13 17:50:18 +03:00
|
|
|
|
2014-06-08 14:24:57 +03:00
|
|
|
class loaded_rom;
|
|
|
|
|
2015-04-14 15:39:50 +03:00
|
|
|
/**
|
|
|
|
* Dynamic state parts of movie file.
|
|
|
|
*/
|
|
|
|
struct dynamic_state
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Ctor.
|
|
|
|
*/
|
|
|
|
dynamic_state();
|
|
|
|
/**
|
|
|
|
* Contents of SRAM on time of savestate (if is_savestate is true).
|
|
|
|
*/
|
|
|
|
std::map<std::string, std::vector<char>> sram;
|
|
|
|
/**
|
|
|
|
* Core savestate (if is_savestate is true).
|
|
|
|
*/
|
|
|
|
std::vector<char> savestate; //Savestate to load (if is_savestate is true).
|
|
|
|
/**
|
|
|
|
* Host memory (if is_savestate is true).
|
|
|
|
*/
|
|
|
|
std::vector<char> host_memory;
|
|
|
|
/**
|
|
|
|
* Screenshot (if is_savestate is true).
|
|
|
|
*/
|
|
|
|
std::vector<char> screenshot;
|
|
|
|
/**
|
|
|
|
* Current frame (if is_savestate is true).
|
|
|
|
*/
|
|
|
|
uint64_t save_frame;
|
|
|
|
/**
|
|
|
|
* Number of lagged frames (if is_savestate is true).
|
|
|
|
*/
|
|
|
|
uint64_t lagged_frames;
|
|
|
|
/**
|
|
|
|
* Poll counters (if is_savestate is true).
|
|
|
|
*/
|
|
|
|
std::vector<uint32_t> pollcounters;
|
|
|
|
/**
|
|
|
|
* Poll flag.
|
|
|
|
*/
|
|
|
|
unsigned poll_flag;
|
|
|
|
/**
|
|
|
|
* Current RTC second.
|
|
|
|
*/
|
|
|
|
int64_t rtc_second;
|
|
|
|
/**
|
|
|
|
* Current RTC subsecond.
|
|
|
|
*/
|
|
|
|
int64_t rtc_subsecond;
|
|
|
|
/**
|
|
|
|
* Active macros at savestate.
|
|
|
|
*/
|
|
|
|
std::map<std::string, uint64_t> active_macros;
|
2015-04-25 15:51:18 +03:00
|
|
|
/**
|
|
|
|
* Clear the state to power-on defaults.
|
|
|
|
*/
|
|
|
|
void clear(int64_t sec, int64_t ssec, const std::map<std::string, std::vector<char>>& initsram);
|
|
|
|
/**
|
|
|
|
* Swap the dynamic state with another.
|
|
|
|
*/
|
|
|
|
void swap(dynamic_state& s) throw();
|
2015-04-14 15:39:50 +03:00
|
|
|
};
|
|
|
|
|
2011-09-13 17:50:18 +03:00
|
|
|
/**
|
|
|
|
* This structure gives parsed representationg of movie file, as result of decoding or for encoding.
|
|
|
|
*/
|
|
|
|
struct moviefile
|
|
|
|
{
|
2013-08-25 17:32:56 +03:00
|
|
|
/**
|
|
|
|
* Brief information
|
|
|
|
*/
|
|
|
|
struct brief_info
|
|
|
|
{
|
2013-09-22 17:39:52 +03:00
|
|
|
brief_info() { current_frame = 0; rerecords = 0; }
|
2013-08-25 17:32:56 +03:00
|
|
|
brief_info(const std::string& filename);
|
|
|
|
std::string sysregion;
|
|
|
|
std::string corename;
|
|
|
|
std::string projectid;
|
2013-09-14 16:29:58 +03:00
|
|
|
std::string hash[ROM_SLOT_COUNT];
|
|
|
|
std::string hashxml[ROM_SLOT_COUNT];
|
|
|
|
std::string hint[ROM_SLOT_COUNT];
|
2013-08-25 17:32:56 +03:00
|
|
|
uint64_t current_frame;
|
|
|
|
uint64_t rerecords;
|
|
|
|
private:
|
2014-02-05 01:11:21 +02:00
|
|
|
void load(zip::reader& r);
|
2014-04-10 20:51:43 +03:00
|
|
|
void binary_io(int s);
|
2013-08-25 17:32:56 +03:00
|
|
|
};
|
2014-02-04 21:16:38 +02:00
|
|
|
/**
|
|
|
|
* Extract branches.
|
|
|
|
*/
|
|
|
|
struct branch_extractor
|
|
|
|
{
|
|
|
|
branch_extractor(const std::string& filename);
|
|
|
|
virtual ~branch_extractor();
|
|
|
|
virtual std::set<std::string> enumerate() { return real->enumerate(); }
|
2014-11-10 05:13:34 +02:00
|
|
|
virtual void read(const std::string& name, portctrl::frame_vector& v) { real->read(name, v); }
|
2014-02-04 21:16:38 +02:00
|
|
|
protected:
|
|
|
|
branch_extractor() { real = NULL; }
|
|
|
|
private:
|
|
|
|
branch_extractor* real;
|
|
|
|
};
|
2015-02-12 01:40:36 +02:00
|
|
|
/**
|
|
|
|
* Extract SRAMs.
|
|
|
|
*/
|
|
|
|
struct sram_extractor
|
|
|
|
{
|
|
|
|
sram_extractor(const std::string& filename);
|
|
|
|
virtual ~sram_extractor();
|
|
|
|
virtual std::set<std::string> enumerate() { return real->enumerate(); }
|
|
|
|
virtual void read(const std::string& name, std::vector<char>& v) { real->read(name, v); }
|
|
|
|
protected:
|
|
|
|
sram_extractor() { real = NULL; }
|
|
|
|
private:
|
|
|
|
sram_extractor* real;
|
|
|
|
};
|
|
|
|
/**
|
|
|
|
* Identify if file is movie/savestate file or not.
|
|
|
|
*/
|
|
|
|
static bool is_movie_or_savestate(const std::string& filename);
|
2011-09-13 17:50:18 +03:00
|
|
|
/**
|
|
|
|
* This constructor construct movie structure with default settings.
|
|
|
|
*
|
2011-09-16 21:09:22 +03:00
|
|
|
* throws std::bad_alloc: Not enough memory.
|
2011-09-13 17:50:18 +03:00
|
|
|
*/
|
|
|
|
moviefile() throw(std::bad_alloc);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This constructor loads a movie/savestate file and fills structure accordingly.
|
|
|
|
*
|
2011-09-16 21:09:22 +03:00
|
|
|
* parameter filename: The file to load.
|
2013-01-11 22:31:13 +02:00
|
|
|
* parameter romtype: Type of ROM.
|
2011-09-16 21:09:22 +03:00
|
|
|
* throws std::bad_alloc: Not enough memory.
|
|
|
|
* throws std::runtime_error: Can't load the movie file
|
2011-09-13 17:50:18 +03:00
|
|
|
*/
|
2013-01-11 22:31:13 +02:00
|
|
|
moviefile(const std::string& filename, core_type& romtype) throw(std::bad_alloc, std::runtime_error);
|
2011-09-13 17:50:18 +03:00
|
|
|
|
2014-02-04 21:16:38 +02:00
|
|
|
/**
|
|
|
|
* Fill a stub movie with specified loaded ROM.
|
|
|
|
*
|
|
|
|
* Parameter rom: The rom.
|
|
|
|
* Parameter settings: The settings.
|
|
|
|
* Parameter rtc_sec: The RTC seconds value.
|
|
|
|
* Parameter rtc_subsec: The RTC subseconds value.
|
|
|
|
*/
|
|
|
|
moviefile(loaded_rom& rom, std::map<std::string, std::string>& c_settings, uint64_t rtc_sec,
|
|
|
|
uint64_t rtc_subsec);
|
|
|
|
|
2011-09-13 17:50:18 +03:00
|
|
|
/**
|
|
|
|
* Reads this movie structure and saves it into file.
|
|
|
|
*
|
2011-09-16 21:09:22 +03:00
|
|
|
* parameter filename: The file to save to.
|
|
|
|
* parameter compression: The compression level 0-9. 0 is uncompressed.
|
2013-07-29 22:16:23 +03:00
|
|
|
* parameter binary: Save in binary form if true.
|
2014-02-02 18:35:36 +02:00
|
|
|
* parameter rrd: The rerecords data.
|
2011-09-16 21:09:22 +03:00
|
|
|
* throws std::bad_alloc: Not enough memory.
|
|
|
|
* throws std::runtime_error: Can't save the movie file.
|
2011-09-13 17:50:18 +03:00
|
|
|
*/
|
2015-04-25 15:51:18 +03:00
|
|
|
void save(const std::string& filename, unsigned compression, bool binary, rrdata_set& rrd, bool as_state)
|
2014-02-02 18:35:36 +02:00
|
|
|
throw(std::bad_alloc, std::runtime_error);
|
2013-11-03 16:13:04 +02:00
|
|
|
/**
|
|
|
|
* Reads this movie structure and saves it to stream (uncompressed ZIP).
|
|
|
|
*/
|
2015-04-25 15:51:18 +03:00
|
|
|
void save(std::ostream& outstream, rrdata_set& rrd, bool as_state) throw(std::bad_alloc, std::runtime_error);
|
2011-09-18 17:27:03 +03:00
|
|
|
/**
|
|
|
|
* Force loading as corrupt.
|
|
|
|
*/
|
|
|
|
bool force_corrupt;
|
2011-09-13 17:50:18 +03:00
|
|
|
/**
|
2011-09-16 21:09:22 +03:00
|
|
|
* What is the ROM type and region?
|
2011-09-13 17:50:18 +03:00
|
|
|
*/
|
2012-07-09 18:11:32 +03:00
|
|
|
core_sysregion* gametype;
|
2011-09-13 17:50:18 +03:00
|
|
|
/**
|
2013-01-05 09:19:09 +02:00
|
|
|
* Settings.
|
2011-09-13 17:50:18 +03:00
|
|
|
*/
|
2013-01-05 09:19:09 +02:00
|
|
|
std::map<std::string, std::string> settings;
|
2011-09-13 17:50:18 +03:00
|
|
|
/**
|
2011-09-16 21:09:22 +03:00
|
|
|
* Emulator Core version string.
|
2011-09-13 17:50:18 +03:00
|
|
|
*/
|
|
|
|
std::string coreversion;
|
|
|
|
/**
|
2011-09-16 21:09:22 +03:00
|
|
|
* Name of the game
|
2011-09-13 17:50:18 +03:00
|
|
|
*/
|
|
|
|
std::string gamename;
|
|
|
|
/**
|
2011-09-16 21:09:22 +03:00
|
|
|
* Project ID (used to identify if two movies are from the same project).
|
2011-09-13 17:50:18 +03:00
|
|
|
*/
|
|
|
|
std::string projectid;
|
|
|
|
/**
|
2011-09-16 21:09:22 +03:00
|
|
|
* Rerecord count (only saved).
|
2011-09-13 17:50:18 +03:00
|
|
|
*/
|
|
|
|
std::string rerecords;
|
2013-11-10 13:24:36 +02:00
|
|
|
/**
|
|
|
|
* Rerecord count (memory saves only).
|
|
|
|
*/
|
|
|
|
uint64_t rerecords_mem;
|
2011-09-13 17:50:18 +03:00
|
|
|
/**
|
2012-07-09 18:11:32 +03:00
|
|
|
* SHA-256 of ROM (empty string if none).
|
2011-09-13 17:50:18 +03:00
|
|
|
*/
|
2013-09-14 12:26:57 +03:00
|
|
|
std::string romimg_sha256[ROM_SLOT_COUNT];
|
2011-09-13 17:50:18 +03:00
|
|
|
/**
|
2012-07-09 18:11:32 +03:00
|
|
|
* SHA-256 of ROM XML (empty string if none).
|
2011-09-13 17:50:18 +03:00
|
|
|
*/
|
2013-09-14 12:26:57 +03:00
|
|
|
std::string romxml_sha256[ROM_SLOT_COUNT];
|
2013-09-14 16:29:58 +03:00
|
|
|
/**
|
|
|
|
* ROM name hint (empty string if none).
|
|
|
|
*/
|
|
|
|
std::string namehint[ROM_SLOT_COUNT];
|
2011-09-13 17:50:18 +03:00
|
|
|
/**
|
2011-09-16 21:09:22 +03:00
|
|
|
* Authors of the run, first in each pair is full name, second is nickname.
|
2011-09-13 17:50:18 +03:00
|
|
|
*/
|
|
|
|
std::vector<std::pair<std::string, std::string>> authors;
|
|
|
|
/**
|
2011-09-16 21:09:22 +03:00
|
|
|
* Contents of SRAM on time of initial powerup.
|
2011-09-13 17:50:18 +03:00
|
|
|
*/
|
|
|
|
std::map<std::string, std::vector<char>> movie_sram;
|
2013-08-27 02:11:59 +03:00
|
|
|
/**
|
|
|
|
* Contents of RAM on time of initial powerup.
|
|
|
|
*/
|
|
|
|
std::map<std::string, std::vector<char>> ramcontent;
|
2012-07-20 00:23:40 +03:00
|
|
|
/**
|
|
|
|
* Anchoring core savestate (if not empty).
|
|
|
|
*/
|
|
|
|
std::vector<char> anchor_savestate;
|
2011-09-19 21:45:35 +03:00
|
|
|
/**
|
|
|
|
* Compressed rrdata.
|
|
|
|
*/
|
|
|
|
std::vector<char> c_rrdata;
|
2011-09-13 17:50:18 +03:00
|
|
|
/**
|
2014-02-04 21:16:38 +02:00
|
|
|
* Input for each (sub)frame (points to active branch).
|
|
|
|
*/
|
2014-11-10 05:13:34 +02:00
|
|
|
portctrl::frame_vector* input;
|
2014-02-04 21:16:38 +02:00
|
|
|
/**
|
|
|
|
* Branches.
|
2011-09-13 17:50:18 +03:00
|
|
|
*/
|
2014-11-10 05:13:34 +02:00
|
|
|
std::map<std::string, portctrl::frame_vector> branches;
|
2011-09-24 21:05:56 +03:00
|
|
|
/**
|
|
|
|
* Movie starting RTC second.
|
|
|
|
*/
|
|
|
|
int64_t movie_rtc_second;
|
|
|
|
/**
|
|
|
|
* Movie starting RTC subsecond.
|
|
|
|
*/
|
|
|
|
int64_t movie_rtc_subsecond;
|
2012-04-21 10:48:59 +03:00
|
|
|
/**
|
|
|
|
* Start paused flag.
|
|
|
|
*/
|
|
|
|
bool start_paused;
|
2012-08-24 20:24:18 +03:00
|
|
|
/**
|
|
|
|
* Lazy project create flag.
|
|
|
|
*/
|
|
|
|
bool lazy_project_create;
|
2012-09-08 19:44:45 +03:00
|
|
|
/**
|
|
|
|
* Subtitles.
|
|
|
|
*/
|
|
|
|
std::map<moviefile_subtiming, std::string> subtitles;
|
2013-06-12 22:15:25 +03:00
|
|
|
/**
|
2015-04-14 15:39:50 +03:00
|
|
|
* Dynamic state.
|
2013-06-12 22:15:25 +03:00
|
|
|
*/
|
2015-04-14 15:39:50 +03:00
|
|
|
dynamic_state dyn;
|
2011-09-13 17:50:18 +03:00
|
|
|
/**
|
2011-09-16 21:09:22 +03:00
|
|
|
* Get number of frames in movie.
|
2011-09-13 17:50:18 +03:00
|
|
|
*
|
2011-09-16 21:09:22 +03:00
|
|
|
* returns: Number of frames.
|
2011-09-13 17:50:18 +03:00
|
|
|
*/
|
|
|
|
uint64_t get_frame_count() throw();
|
|
|
|
/**
|
2011-09-16 21:09:22 +03:00
|
|
|
* Get length of the movie
|
2011-09-13 17:50:18 +03:00
|
|
|
*
|
2014-04-21 21:46:29 +03:00
|
|
|
* returns: Length of the movie in milliseconds.
|
2011-09-13 17:50:18 +03:00
|
|
|
*/
|
2012-07-20 00:23:40 +03:00
|
|
|
uint64_t get_movie_length() throw();
|
2013-11-11 01:49:06 +02:00
|
|
|
/**
|
|
|
|
* Return reference to memory slot.
|
|
|
|
*/
|
2014-02-02 18:35:36 +02:00
|
|
|
static moviefile*& memref(const std::string& slot);
|
2014-02-04 21:16:38 +02:00
|
|
|
|
2014-02-02 18:35:36 +02:00
|
|
|
/**
|
|
|
|
* Copy data.
|
|
|
|
*/
|
|
|
|
void copy_fields(const moviefile& mv);
|
2014-02-04 21:16:38 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Create a default branch.
|
|
|
|
*/
|
2014-11-10 05:13:34 +02:00
|
|
|
void create_default_branch(portctrl::type_set& ports);
|
2014-02-04 21:16:38 +02:00
|
|
|
/**
|
|
|
|
* Get name of current branch.
|
|
|
|
*/
|
|
|
|
const std::string& current_branch();
|
|
|
|
/**
|
|
|
|
* Fork a branch.
|
|
|
|
*/
|
|
|
|
void fork_branch(const std::string& oldname, const std::string& newname);
|
|
|
|
/**
|
|
|
|
* Fixup input pointer post-copy.
|
|
|
|
*/
|
|
|
|
void fixup_current_branch(const moviefile& mv);
|
2015-04-25 15:51:18 +03:00
|
|
|
/**
|
|
|
|
* Clear the dynamic state to power-on defaults.
|
|
|
|
*/
|
|
|
|
void clear_dynstate();
|
2013-07-29 22:16:23 +03:00
|
|
|
private:
|
2014-02-02 18:35:36 +02:00
|
|
|
moviefile(const moviefile&);
|
|
|
|
moviefile& operator=(const moviefile&);
|
2015-04-25 15:51:18 +03:00
|
|
|
void binary_io(int stream, rrdata_set& rrd, bool as_state) throw(std::bad_alloc, std::runtime_error);
|
2014-04-10 20:51:43 +03:00
|
|
|
void binary_io(int stream, struct core_type& romtype) throw(std::bad_alloc, std::runtime_error);
|
2015-04-25 15:51:18 +03:00
|
|
|
void save(zip::writer& w, rrdata_set& rrd, bool as_state) throw(std::bad_alloc, std::runtime_error);
|
2014-02-05 01:11:21 +02:00
|
|
|
void load(zip::reader& r, core_type& romtype) throw(std::bad_alloc, std::runtime_error);
|
2011-09-13 17:50:18 +03:00
|
|
|
};
|
|
|
|
|
2014-02-02 18:35:36 +02:00
|
|
|
void emerg_save_movie(const moviefile& mv, rrdata_set& rrd);
|
2013-11-30 13:55:07 +02:00
|
|
|
|
2011-09-13 17:50:18 +03:00
|
|
|
#endif
|