using System; using System.IO; using BizHawk.Emulation.Common; namespace BizHawk.Client.Common { // TODO: message callback / event handler // TODO: consider other event handlers, switching modes? public interface IMovie { #region Status bool IsCountingRerecords { get; set; } bool IsActive { get; } bool IsPlaying { get; } bool IsRecording { get; } bool IsFinished { get; } bool Changes { get; } #endregion #region Properties /// /// Gets the total number of frames that count towards the completion time of the movie /// Possibly (but unlikely different from InputLogLength (could be infinity, or maybe an implementation automatically discounts empty frames at the end of a movie, etc) /// double FrameCount { get; } /// /// Gets the Fps used to calculate the time of the movie /// double Fps { get; } /// /// Gets the time calculation based on FrameCount and Fps /// TimeSpan Time { get; } /// /// Gets the actual length of the input log, should only be used by code that iterates or needs a real length /// int InputLogLength { get; } /// /// Returns the file extension for this implementation /// string PreferredExtension { get; } IMovieHeader Header { get; } #endregion #region File Handling API // Filename of the movie, settable by the client string Filename { get; set; } /// /// Tells the movie to load the contents of Filename /// /// Return whether or not the file was successfully loaded bool Load(); /// /// Instructs the movie to save the current contents to Filename /// void Save(); /// /// Extracts the current input log from the user. /// This is provided as the means for putting the input log into savestates, /// for the purpose of out of order savestate loading (known as "bullet-proof rerecording") /// /// returns a string represntation of the input log in its current state string GetInputLog(); /// /// Compares the input log inside reader with the movie's current input to see if the reader's input belongs to the same timeline, /// in other words, if reader's input is completely contained in the movie's input, then it is considered in the same timeline /// /// The reader containing the contents of the input log /// Returns an error message, if any /// Returns whether or not the input log in reader is in the same timeline as the movie bool CheckTimeLines(TextReader reader, out string errorMessage); /// /// Takes reader and extracts the input log, then replaces the movies input log with it /// /// The reader containing the contents of the input log /// Returns an error message, if any /// bool ExtractInputLog(TextReader reader, out string errorMessage); #endregion #region Mode Handling API /// /// Tells the movie to start recording from the beginning. /// void StartNewRecording(); /// /// Tells the movie to start playback from the beginning /// void StartNewPlayback(); /// /// Sets the movie to inactive (note that it will still be in memory) /// The saveChanges flag will tell the movie to save its contents to disk /// /// if true, will save to disk void Stop(bool saveChanges = true); /// /// Switches to record mode /// void SwitchToRecord(); /// /// Switches to playback mode /// void SwitchToPlay(); #endregion #region Editing API /// /// Replaces the given frame's input with an empty frame /// void ClearFrame(int frame); /// /// Adds the given input to the movie /// Note: this edits the input log without the normal movie recording logic applied /// void AppendFrame(IController source); /// /// Replaces the input at the given frame with the given input /// Note: this edits the input log without the normal movie recording logic applied /// void PokeFrame(int frame, IController source); /// /// Records the given input into the given frame, /// This is subject to normal movie recording logic /// void RecordFrame(int frame, IController source); /// /// Instructs the movie to remove all input from its input log after frame, /// AFter truncating, frame will be the last frame of input in the movie's input log /// /// The frame at which to truncate void Truncate(int frame); /// /// Gets a single frame of input from the movie at the given frame /// The input will be in the same format as represented in the input log when saved as a file /// /// The frame of input to be retrieved /// string GetInput(int frame); #endregion } }