diff --git a/BizHawk.MultiClient/BizHawk.MultiClient.csproj b/BizHawk.MultiClient/BizHawk.MultiClient.csproj
index b26418e494..2007dfabff 100644
--- a/BizHawk.MultiClient/BizHawk.MultiClient.csproj
+++ b/BizHawk.MultiClient/BizHawk.MultiClient.csproj
@@ -179,6 +179,7 @@
+
diff --git a/BizHawk.MultiClient/Global.cs b/BizHawk.MultiClient/Global.cs
index 565dbe0233..3187e6f8a3 100644
--- a/BizHawk.MultiClient/Global.cs
+++ b/BizHawk.MultiClient/Global.cs
@@ -22,22 +22,29 @@ namespace BizHawk.MultiClient
public static Controller GBControls;
public static Controller NullControls;
- //TODO should have one of these per movie!!!! should not be global.
- public static MovieControllerAdapter MovieControllerAdapter = new MovieControllerAdapter();
+ //the movie will be spliced inbetween these if it is present
public static CopyControllerAdapter MovieInputSourceAdapter = new CopyControllerAdapter();
+ public static CopyControllerAdapter MovieOutputAdapter = new CopyControllerAdapter();
+ ///
+ /// the global MovieSession can use this to deal with multitrack player remapping (should this be here? maybe it should be in MovieSession)
+ ///
public static MultitrackRewiringControllerAdapter MultitrackRewiringControllerAdapter = new MultitrackRewiringControllerAdapter();
+
+ public static MovieSession MovieSession = new MovieSession();
+
+
//dont take my word for it, since the final word is actually in RewireInputChain, but here is a guide...
//user -> Input -> ActiveController -> UDLR -> StickyXORPlayerInputAdapter -> TurboAdapter(TBD) -> Lua(?TBD?) -> ..
- //.. -> MultitrackRewiringControllerAdapter -> MovieInputSourceAdapter -> MovieInputController -> ControllerOutput(1) -> Game
+ //.. -> MultitrackRewiringControllerAdapter -> MovieInputSourceAdapter -> (MovieSession) -> MovieOutputAdapter -> ControllerOutput(1) -> Game
//(1)->Input Display
//the original source controller, bound to the user, sort of the "input" port for the chain, i think
public static Controller ActiveController;
//the "output" port for the controller chain.
- public static IController ControllerOutput;
+ public static CopyControllerAdapter ControllerOutput = new CopyControllerAdapter();
//input state which has been destined for game controller inputs are coalesced here
public static InputCoalescer ControllerInputCoalescer = new InputCoalescer();
@@ -56,6 +63,8 @@ namespace BizHawk.MultiClient
///
public static ClickyVirtualPadController ClickyVirtualPadController = new ClickyVirtualPadController();
+ public static SimpleController MovieOutputController = new SimpleController();
+
public static Controller ClientControls;
public static string GetOutputControllersAsMnemonic()
@@ -68,6 +77,8 @@ namespace BizHawk.MultiClient
//TODO - wtf is this being used for
public static bool MovieMode;
+
+
public static CoreAccessor PsxCoreLibrary = new CoreAccessor(new Win32LibAccessor("PsxHawk.Core.dll"));
}
diff --git a/BizHawk.MultiClient/Input/Input.cs b/BizHawk.MultiClient/Input/Input.cs
index 2ee1846484..c5f8ac7715 100644
--- a/BizHawk.MultiClient/Input/Input.cs
+++ b/BizHawk.MultiClient/Input/Input.cs
@@ -164,7 +164,14 @@ namespace BizHawk.MultiClient
ModifierKey _Modifiers;
List _NewEvents = new List();
- //TODO - maybe need clearevents for various purposes. perhaps when returning from modal dialogs?
+ //do we need this?
+ public void ClearEvents()
+ {
+ lock (this)
+ {
+ InputEvents.Clear();
+ }
+ }
Queue InputEvents = new Queue();
public InputEvent DequeueEvent()
@@ -211,7 +218,7 @@ namespace BizHawk.MultiClient
HandleButton(jname + "B" + (b + 1), pad.Buttons[b]);
}
- bool swallow = (Global.Config.AcceptBackgroundInput == false && Form.ActiveForm == null);
+ bool swallow = !Global.MainForm.AllowInput;
foreach (var ie in _NewEvents)
{
diff --git a/BizHawk.MultiClient/MainForm.Movie.cs b/BizHawk.MultiClient/MainForm.Movie.cs
index d24e49d594..4a5c99d510 100644
--- a/BizHawk.MultiClient/MainForm.Movie.cs
+++ b/BizHawk.MultiClient/MainForm.Movie.cs
@@ -15,8 +15,11 @@ namespace BizHawk.MultiClient
public void StartNewMovie(Movie m, bool record)
{
+ Global.MovieSession = new MovieSession();
+ Global.MovieSession.Movie = m;
+ UserMovie = m; //TODO - maybe get rid of UserMovie?
+ RewireInputChain();
- UserMovie = m;
LoadRom(Global.MainForm.CurrentlyOpenRom);
UserMovie.LoadMovie();
Global.Config.RecentMovies.Add(m.Filename);
diff --git a/BizHawk.MultiClient/MainForm.cs b/BizHawk.MultiClient/MainForm.cs
index d60aa4fd3d..51733c0353 100644
--- a/BizHawk.MultiClient/MainForm.cs
+++ b/BizHawk.MultiClient/MainForm.cs
@@ -791,9 +791,16 @@ namespace BizHawk.MultiClient
Global.MultitrackRewiringControllerAdapter.Source = Global.StickyXORAdapter;
Global.MovieInputSourceAdapter.Source = Global.MultitrackRewiringControllerAdapter;
- Global.MovieControllerAdapter.SetSource(Global.MovieInputSourceAdapter);
- Global.ControllerOutput = Global.MovieControllerAdapter;
+ Global.ControllerOutput.Source = Global.MovieOutputAdapter;
Global.Emulator.Controller = Global.ControllerOutput;
+
+ Global.MovieSession.MovieControllerAdapter.Type = Global.MovieInputSourceAdapter.Type;
+
+ //splice the movie session before MovieOutputAdapter if it is doing anything
+ if (Global.MovieSession.Movie != null)
+ Global.MovieOutputAdapter.Source = Global.MovieSession.MovieControllerAdapter;
+ else
+ Global.MovieOutputAdapter.Source = Global.MovieInputSourceAdapter;
}
public bool LoadRom(string path)
@@ -1039,6 +1046,27 @@ namespace BizHawk.MultiClient
UpdateStatusSlots();
}
+ ///
+ /// Controls whether the app generates input events. should be turned off for most modal dialogs
+ ///
+ public bool AllowInput
+ {
+ get
+ {
+ //the main form gets input
+ if (Form.ActiveForm == this) return true;
+
+ //modals that need to capture input for binding purposes get input, of course
+ if (Form.ActiveForm is InputConfig) return true;
+ if (Form.ActiveForm is tools.HotkeyWindow) return true;
+
+ //if no form is active on this process, then the background input setting applies
+ if (Form.ActiveForm == null && Global.Config.AcceptBackgroundInput) return true;
+
+ return false;
+ }
+ }
+
public void ProcessInput()
{
for(;;)
@@ -1093,6 +1121,7 @@ namespace BizHawk.MultiClient
bool handled = false;
if (ie.EventType == Input.InputEventType.Press)
{
+ Console.WriteLine(ie);
foreach (var trigger in triggers)
{
handled |= CheckHotkey(trigger);
@@ -1244,52 +1273,52 @@ namespace BizHawk.MultiClient
case "Toggle MultiTrack":
{
- Global.MainForm.UserMovie.MultiTrack.IsActive = !Global.MainForm.UserMovie.MultiTrack.IsActive;
- if (Global.MainForm.UserMovie.MultiTrack.IsActive)
+ Global.MovieSession.MultiTrack.IsActive = !Global.MovieSession.MultiTrack.IsActive;
+ if (Global.MovieSession.MultiTrack.IsActive)
{
Global.RenderPanel.AddMessage("MultiTrack Enabled");
Global.RenderPanel.MT = "Recording None";
}
else
Global.RenderPanel.AddMessage("MultiTrack Disabled");
- Global.MainForm.UserMovie.MultiTrack.RecordAll = false;
- Global.MainForm.UserMovie.MultiTrack.CurrentPlayer = 0;
+ Global.MovieSession.MultiTrack.RecordAll = false;
+ Global.MovieSession.MultiTrack.CurrentPlayer = 0;
break;
}
case "Increment Player":
{
- Global.MainForm.UserMovie.MultiTrack.CurrentPlayer++;
- Global.MainForm.UserMovie.MultiTrack.RecordAll = false;
- if (Global.MainForm.UserMovie.MultiTrack.CurrentPlayer > 5) //TODO: Replace with console's maximum or current maximum players??!
+ Global.MovieSession.MultiTrack.CurrentPlayer++;
+ Global.MovieSession.MultiTrack.RecordAll = false;
+ if (Global.MovieSession.MultiTrack.CurrentPlayer > 5) //TODO: Replace with console's maximum or current maximum players??!
{
- Global.MainForm.UserMovie.MultiTrack.CurrentPlayer = 1;
+ Global.MovieSession.MultiTrack.CurrentPlayer = 1;
}
- Global.RenderPanel.MT = "Recording Player " + Global.MainForm.UserMovie.MultiTrack.CurrentPlayer.ToString();
+ Global.RenderPanel.MT = "Recording Player " + Global.MovieSession.MultiTrack.CurrentPlayer.ToString();
break;
}
case "Decrement Player":
{
- Global.MainForm.UserMovie.MultiTrack.CurrentPlayer--;
- Global.MainForm.UserMovie.MultiTrack.RecordAll = false;
- if (Global.MainForm.UserMovie.MultiTrack.CurrentPlayer < 1)
+ Global.MovieSession.MultiTrack.CurrentPlayer--;
+ Global.MovieSession.MultiTrack.RecordAll = false;
+ if (Global.MovieSession.MultiTrack.CurrentPlayer < 1)
{
- Global.MainForm.UserMovie.MultiTrack.CurrentPlayer = 5;//TODO: Replace with console's maximum or current maximum players??!
+ Global.MovieSession.MultiTrack.CurrentPlayer = 5;//TODO: Replace with console's maximum or current maximum players??!
}
- Global.RenderPanel.MT = "Recording Player " + Global.MainForm.UserMovie.MultiTrack.CurrentPlayer.ToString();
+ Global.RenderPanel.MT = "Recording Player " + Global.MovieSession.MultiTrack.CurrentPlayer.ToString();
break;
}
case "Record All":
{
- Global.MainForm.UserMovie.MultiTrack.CurrentPlayer = 0;
- Global.MainForm.UserMovie.MultiTrack.RecordAll = true;
+ Global.MovieSession.MultiTrack.CurrentPlayer = 0;
+ Global.MovieSession.MultiTrack.RecordAll = true;
Global.RenderPanel.MT = "Recording All";
break;
}
case "Record None":
{
- Global.MainForm.UserMovie.MultiTrack.CurrentPlayer = 0;
- Global.MainForm.UserMovie.MultiTrack.RecordAll = false;
+ Global.MovieSession.MultiTrack.CurrentPlayer = 0;
+ Global.MovieSession.MultiTrack.RecordAll = false;
Global.RenderPanel.MT = "Recording None";
break;
}
@@ -1312,6 +1341,7 @@ namespace BizHawk.MultiClient
throttle.Step(true, -1);
}
+
void StepRunLoop_Core()
{
bool runFrame = false;
@@ -1407,27 +1437,35 @@ namespace BizHawk.MultiClient
else if (!Global.Config.MuteFrameAdvance)
genSound = true;
+ MovieSession session = Global.MovieSession;
+
+ if (UserMovie.Mode == MOVIEMODE.FINISHED)
+ {
+ //todo - a better way of ending
+ StopMovie();
+ }
+
if (UserMovie.Mode != MOVIEMODE.INACTIVE)
{
- UserMovie.LatchInputFromLog();
+ session.LatchInputFromLog();
}
if (UserMovie.Mode == MOVIEMODE.RECORD)
{
- if (UserMovie.MultiTrack.IsActive)
+ if (session.MultiTrack.IsActive)
{
- UserMovie.LatchMultitrackPlayerInput();
+ session.LatchMultitrackPlayerInput(Global.MovieInputSourceAdapter, Global.MultitrackRewiringControllerAdapter);
}
else
{
- UserMovie.LatchInputFromPlayer();
+ session.LatchInputFromPlayer(Global.MovieInputSourceAdapter);
}
- UserMovie.CommitFrame();
+ session.Movie.CommitFrame(Global.Emulator.Frame, Global.MovieInputSourceAdapter);
}
if (UserMovie.Mode == MOVIEMODE.INACTIVE)
{
- UserMovie.LatchInputFromPlayer();
+ session.LatchInputFromPlayer(Global.MovieInputSourceAdapter);
}
if (UserMovie.Mode == MOVIEMODE.PLAY)
@@ -1439,22 +1477,22 @@ namespace BizHawk.MultiClient
}
}
- if (UserMovie.Mode == MOVIEMODE.FINISHED)
- {
- if (UserMovie.Length() > Global.Emulator.Frame)
- {
- UserMovie.StartPlayback();
- Global.MovieControllerAdapter.SetControllersAsMnemonic(UserMovie.GetInputFrame(Global.Emulator.Frame));
- }
- }
- if (UserMovie.Mode == MOVIEMODE.RECORD && UserMovie.MultiTrack.IsActive)
- {
- Global.MovieControllerAdapter.SetControllersAsMnemonic(UserMovie.GetInputFrame(Global.Emulator.Frame-1));
- Console.WriteLine("Out: " + UserMovie.GetInputFrame(Global.Emulator.Frame));
- }
- //TODO multitrack
+ //TODO ZERO - I DONT LIKE THIS. INSPECT IT LATER.
+ //if (UserMovie.Mode == MOVIEMODE.FINISHED)
+ //{
+ // if (UserMovie.Length() > Global.Emulator.Frame)
+ // {
+ // UserMovie.StartPlayback();
+ // Global.MovieSession.MovieControllerAdapter.SetControllersAsMnemonic(UserMovie.GetInputFrame(Global.Emulator.Frame));
+ // }
+ //}
+ //if (UserMovie.Mode == MOVIEMODE.RECORD && Global.MovieSession.MultiTrack.IsActive)
+ //{
+ // Global.MovieSession.MovieControllerAdapter.SetControllersAsMnemonic(UserMovie.GetInputFrame(Global.Emulator.Frame-1));
+ // Console.WriteLine("Out: " + UserMovie.GetInputFrame(Global.Emulator.Frame));
+ //}
//=======================================
Global.Emulator.FrameAdvance(!throttle.skipnextframe);
@@ -1611,7 +1649,8 @@ namespace BizHawk.MultiClient
}
else
{
- UserMovie.StartNewRecording();
+ //QUESTIONABLE - control whether the movie gets truncated here?
+ UserMovie.StartNewRecording(!Global.MovieSession.MultiTrack.IsActive);
SetMainformMovieInfo();
Global.MovieMode = false;
UserMovie.LoadLogFromSavestateText(reader);
diff --git a/BizHawk.MultiClient/RenderPanel.cs b/BizHawk.MultiClient/RenderPanel.cs
index e11fa77de5..5da225eaad 100644
--- a/BizHawk.MultiClient/RenderPanel.cs
+++ b/BizHawk.MultiClient/RenderPanel.cs
@@ -351,7 +351,7 @@ namespace BizHawk.MultiClient
MessageFont.DrawString(null, input, x + 1, y + 1, Color.Black);
MessageFont.DrawString(null, input, x, y, c);
}
- if (Global.MainForm.UserMovie.MultiTrack.IsActive)
+ if (Global.MovieSession.MultiTrack.IsActive)
{
MessageFont.DrawString(null, MT, Global.Config.DispFPSx + 1, //TODO: Multitrack position variables
Global.Config.DispFPSy + 1, new Color4(Color.Black));
diff --git a/BizHawk.MultiClient/movie/InputAdapters.cs b/BizHawk.MultiClient/movie/InputAdapters.cs
index 1859eb129a..433aa7e90d 100644
--- a/BizHawk.MultiClient/movie/InputAdapters.cs
+++ b/BizHawk.MultiClient/movie/InputAdapters.cs
@@ -384,25 +384,17 @@ namespace BizHawk.MultiClient
//OutputController = new ForceControllerAdapter();
}
- IController Source;
-
- public void SetSource(IController source)
- {
- //OutputController.Controller = source;
- Source = source;
- }
-
//IController implementation:
- public ControllerDefinition Type { get { return Source.Type; } }
+ public ControllerDefinition Type { get; set; }
public bool this[string button] { get { return MyBoolButtons[button]; } }
public bool IsPressed(string button) { return MyBoolButtons[button]; }
- public float GetFloat(string name) { return Source.GetFloat(name); }
- public void UpdateControls(int frame) { Source.UpdateControls(frame); }
+ public float GetFloat(string name) { return 0; }
+ public void UpdateControls(int frame) { }
//--------
- Dictionary MyBoolButtons = new Dictionary();
+ WorkingDictionary MyBoolButtons = new WorkingDictionary();
- void Force(string button, bool state)
+ void Force(string button, bool state)
{
MyBoolButtons[button] = state;
}
@@ -426,29 +418,31 @@ namespace BizHawk.MultiClient
///
/// latches one player from the source
///
- public void LatchPlayerFromSource(int playerNum)
+ public void LatchPlayerFromSource(IController playerSource, int playerNum)
{
- foreach (string button in Source.Type.BoolButtons)
+ foreach (string button in playerSource.Type.BoolButtons)
{
ButtonNameParser bnp = ButtonNameParser.Parse(button);
if (bnp == null) continue;
if (bnp.PlayerNum != playerNum) continue;
- bool val = Source[button];
+ bool val = playerSource[button];
MyBoolButtons[button] = val;
}
}
+
///
- /// latches all buttons from the upstream source
+ /// latches all buttons from the provided source
///
- public void LatchFromSource()
+ public void LatchFromSource(IController source)
{
foreach (string button in Type.BoolButtons)
{
- MyBoolButtons[button] = Source[button];
+ MyBoolButtons[button] = source[button];
}
}
+
///
/// latches all buttons from the supplied mnemonic string
///
diff --git a/BizHawk.MultiClient/movie/Movie.cs b/BizHawk.MultiClient/movie/Movie.cs
index e18b08b507..c777603553 100644
--- a/BizHawk.MultiClient/movie/Movie.cs
+++ b/BizHawk.MultiClient/movie/Movie.cs
@@ -14,7 +14,6 @@ namespace BizHawk.MultiClient
public MovieHeader Header = new MovieHeader();
public SubtitleList Subtitles = new SubtitleList();
- public MultitrackRecording MultiTrack = new MultitrackRecording();
public bool MakeBackup = true; //make backup before altering movie
public bool IsText { get; private set; }
@@ -91,7 +90,8 @@ namespace BizHawk.MultiClient
Mode = MOVIEMODE.INACTIVE;
}
- public void StartNewRecording()
+ public void StartNewRecording() { StartNewRecording(true); }
+ public void StartNewRecording(bool truncate)
{
Mode = MOVIEMODE.RECORD;
if (Global.Config.EnableBackupMovies && MakeBackup && Log.Length() > 0)
@@ -99,7 +99,7 @@ namespace BizHawk.MultiClient
WriteBackup();
MakeBackup = false;
}
- Log.Clear();
+ if(truncate) Log.Clear();
}
public void StartPlayback()
@@ -107,55 +107,21 @@ namespace BizHawk.MultiClient
Mode = MOVIEMODE.PLAY;
}
- public void LatchMultitrackPlayerInput()
+ public void CommitFrame(int frameNum, IController source)
{
- if (MultiTrack.IsActive)
- {
- Global.MultitrackRewiringControllerAdapter.PlayerSource = 1;
- Global.MultitrackRewiringControllerAdapter.PlayerTargetMask = 1 << (MultiTrack.CurrentPlayer);
- if (MultiTrack.RecordAll) Global.MultitrackRewiringControllerAdapter.PlayerTargetMask = unchecked((int)0xFFFFFFFF);
- }
- else Global.MultitrackRewiringControllerAdapter.PlayerSource = -1;
-
- if (MultiTrack.RecordAll)
- Global.MovieControllerAdapter.LatchFromSource();
- else
- Global.MovieControllerAdapter.LatchPlayerFromSource(MultiTrack.CurrentPlayer);
- }
-
- public void LatchInputFromPlayer()
- {
- Global.MovieControllerAdapter.LatchFromSource();
- }
-
- ///
- /// latch input from the log, if available
- ///
- public void LatchInputFromLog()
- {
- string loggedFrame = GetInputFrame(Global.Emulator.Frame);
- if(loggedFrame != "")
- Global.MovieControllerAdapter.SetControllersAsMnemonic(loggedFrame);
- }
-
- public void CommitFrame()
- {
- //if (MultiTrack.IsActive)
+ //if (Global.Emulator.Frame < Log.Length())
//{
+ // Log.Truncate(Global.Emulator.Frame);
//}
- //else
- // if (Global.Emulator.Frame < Log.Length())
- // {
- // Log.Truncate(Global.Emulator.Frame);
- // }
//Note: Truncation here instead of loadstate will make VBA style loadstates
//(Where an entire movie is loaded then truncated on the next frame
//this allows users to restore a movie with any savestate from that "timeline"
MnemonicsGenerator mg = new MnemonicsGenerator();
- mg.SetSource(Global.MovieInputSourceAdapter);
- Log.SetFrameAt(Global.Emulator.Frame, mg.GetControllersAsMnemonic());
+
+ mg.SetSource(source);
+ Log.SetFrameAt(frameNum, mg.GetControllersAsMnemonic());
}
public string GetInputFrame(int frame)
@@ -420,7 +386,7 @@ namespace BizHawk.MultiClient
public void LoadLogFromSavestateText(TextReader reader)
{
//We are in record mode so replace the movie log with the one from the savestate
- if (!MultiTrack.IsActive)
+ if (!Global.MovieSession.MultiTrack.IsActive)
{
if (Global.Config.EnableBackupMovies && MakeBackup && Log.Length() > 0)
{
diff --git a/BizHawk.MultiClient/movie/MovieSession.cs b/BizHawk.MultiClient/movie/MovieSession.cs
new file mode 100644
index 0000000000..29051a10b9
--- /dev/null
+++ b/BizHawk.MultiClient/movie/MovieSession.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Text;
+using System.Threading;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Windows.Forms;
+using BizHawk.Core;
+using BizHawk.Emulation.Consoles.Sega;
+using BizHawk.Emulation.Consoles.TurboGrafx;
+using BizHawk.Emulation.Consoles.Calculator;
+using BizHawk.Emulation.Consoles.Gameboy;
+using BizHawk.Emulation.Consoles.Nintendo;
+
+namespace BizHawk.MultiClient
+{
+
+ public class MovieSession
+ {
+ public MultitrackRecording MultiTrack = new MultitrackRecording();
+ public Movie Movie;
+ public MovieControllerAdapter MovieControllerAdapter = new MovieControllerAdapter();
+
+ public void LatchMultitrackPlayerInput(IController playerSource, MultitrackRewiringControllerAdapter rewiredSource)
+ {
+ if (MultiTrack.IsActive)
+ {
+ rewiredSource.PlayerSource = 1;
+ rewiredSource.PlayerTargetMask = 1 << (MultiTrack.CurrentPlayer);
+ if (MultiTrack.RecordAll) rewiredSource.PlayerTargetMask = unchecked((int)0xFFFFFFFF);
+ }
+ else rewiredSource.PlayerSource = -1;
+
+ MovieControllerAdapter.LatchPlayerFromSource(rewiredSource, MultiTrack.CurrentPlayer);
+ }
+
+ public void LatchInputFromPlayer(IController source)
+ {
+ MovieControllerAdapter.LatchFromSource(source);
+ }
+
+ ///
+ /// latch input from the input log, if available
+ ///
+ public void LatchInputFromLog()
+ {
+ string loggedFrame = Movie.GetInputFrame(Global.Emulator.Frame);
+ if (loggedFrame != "")
+ MovieControllerAdapter.SetControllersAsMnemonic(loggedFrame);
+ }
+ }
+
+}
\ No newline at end of file