diff --git a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs index eadce03a53..9b3c6d9d5c 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/NES/NES.cs @@ -211,7 +211,6 @@ namespace BizHawk.Emulation.Consoles.Nintendo value <<= 1; value |= nes.Controller.IsPressed(str) ? 1 : 0; } - //Console.WriteLine("STROBE"); } public override void Write(int value) { diff --git a/BizHawk.Emulation/Interfaces/IController.cs b/BizHawk.Emulation/Interfaces/IController.cs index eab629fa0f..3a930f4e9b 100644 --- a/BizHawk.Emulation/Interfaces/IController.cs +++ b/BizHawk.Emulation/Interfaces/IController.cs @@ -13,10 +13,14 @@ namespace BizHawk { ControllerDefinition Type { get; } + //TODO - it is obnoxious for this to be here. must be removed. bool this[string button] { get; } + //TODO - this can stay but it needs to be changed to go through the float bool IsPressed(string button); - float GetFloat(string name); + float GetFloat(string name); + + //TODO - why does this have a frame argument. must be removed. void UpdateControls(int frame); } } diff --git a/BizHawk.MultiClient/BizHawk.MultiClient.csproj b/BizHawk.MultiClient/BizHawk.MultiClient.csproj index 96edcdea23..1d1ca7962f 100644 --- a/BizHawk.MultiClient/BizHawk.MultiClient.csproj +++ b/BizHawk.MultiClient/BizHawk.MultiClient.csproj @@ -138,6 +138,7 @@ + diff --git a/BizHawk.MultiClient/Global.cs b/BizHawk.MultiClient/Global.cs index b962850a74..0982714b3b 100644 --- a/BizHawk.MultiClient/Global.cs +++ b/BizHawk.MultiClient/Global.cs @@ -21,7 +21,31 @@ namespace BizHawk.MultiClient public static Controller TI83Controls; public static Controller NESControls; public static Controller GBControls; - public static Controller ActiveController; public static Controller NullControls; + + //TODO should have one of these per movie!!!! should not be global. + public static MovieControllerAdapter MovieControllerAdapter = new MovieControllerAdapter(); + public static CopyControllerAdapter MovieInputSourceAdapter = new CopyControllerAdapter(); + + public static MultitrackRewiringControllerAdapter MultitrackRewiringControllerAdapter = new MultitrackRewiringControllerAdapter(); + + //user -> ActiveController -> TurboAdapter(TBD) -> Lua(?) -> MultitrackRewiringControllerAdapter -> MovieInputSourceAdapter -> MovieInputController -> 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 string GetOutputControllersAsMnemonic() + { + MnemonicsGenerator mg = new MnemonicsGenerator(); + mg.SetSource(Global.ControllerOutput); + return mg.GetControllersAsMnemonic(); + } + + //TODO - wtf is this being used for + public static bool MovieMode; } } \ No newline at end of file diff --git a/BizHawk.MultiClient/HawkFile.cs b/BizHawk.MultiClient/HawkFile.cs index 9d6c17b9ef..a4551fb846 100644 --- a/BizHawk.MultiClient/HawkFile.cs +++ b/BizHawk.MultiClient/HawkFile.cs @@ -101,6 +101,11 @@ namespace BizHawk.MultiClient } } + /// + /// these extensions won't even be tried as archives (removes spurious archive detects since some of the signatures are pretty damn weak) + /// + public string[] NonArchiveExtensions = new string[] { }; + //--- bool exists; bool rootExists; @@ -110,8 +115,14 @@ namespace BizHawk.MultiClient SevenZip.SevenZipExtractor extractor; List archiveItems; - public HawkFile(string path) + public HawkFile() { + } + + public void Open(string path) + { + if (rootPath != null) throw new InvalidOperationException("Don't reopen a HawkFile."); + string autobind = null; bool isArchivePath = IsCanonicalArchivePath(path); if (isArchivePath) @@ -160,6 +171,11 @@ namespace BizHawk.MultiClient } } + public HawkFile(string path) + { + Open(path); + } + /// /// is the supplied path a canonical name including an archive? /// @@ -312,6 +328,10 @@ namespace BizHawk.MultiClient SevenZip.FileChecker.ThrowExceptions = false; int offset; bool isExecutable; + foreach(string ext in NonArchiveExtensions) + if(Path.GetExtension(path).Substring(1).ToLower() == ext.ToLower()) + return; + if (SevenZip.FileChecker.CheckSignature(path, out offset, out isExecutable) != SevenZip.InArchiveFormat.None) { extractor = new SevenZip.SevenZipExtractor(path); @@ -339,4 +359,4 @@ namespace BizHawk.MultiClient rootStream = null; } } -} \ No newline at end of file +} diff --git a/BizHawk.MultiClient/Input/ControllerBinding.cs b/BizHawk.MultiClient/Input/ControllerBinding.cs index 489a44413c..27f82eec3c 100644 --- a/BizHawk.MultiClient/Input/ControllerBinding.cs +++ b/BizHawk.MultiClient/Input/ControllerBinding.cs @@ -14,18 +14,6 @@ namespace BizHawk.MultiClient private List removeFromForcePressedButtons = new List(); private List programmaticallyPressedButtons = new List(); - private bool movieMode; - public bool MovieMode - { - get { return movieMode; } - set - { - movieMode = value; - if (value == false) - programmaticallyPressedButtons.Clear(); - } - } - public Controller(ControllerDefinition definition) { type = definition; @@ -66,10 +54,6 @@ namespace BizHawk.MultiClient public bool IsPressed(string button) { - if (MovieMode) - { - return programmaticallyPressedButtons.Contains(button); - } if (forcePressedButtons.Contains(button)) { removeFromForcePressedButtons.Add(button); @@ -154,360 +138,6 @@ namespace BizHawk.MultiClient forcePressedButtons.Add(button); } - public string GetControllersAsMnemonic() - { - StringBuilder input = new StringBuilder("|"); - - if (type.Name == "SMS Controller") - { - input.Append(IsPressed("P1 Up") ? "U" : "."); - input.Append(IsPressed("P1 Down") ? "D" : "."); - input.Append(IsPressed("P1 Left") ? "L" : "."); - input.Append(IsPressed("P1 Right") ? "R" : "."); - input.Append(IsPressed("P1 B1") ? "1" : "."); - input.Append(IsPressed("P1 B2") ? "2" : "."); - input.Append("|"); - input.Append(IsPressed("P2 Up") ? "U" : "."); - input.Append(IsPressed("P2 Down") ? "D" : "."); - input.Append(IsPressed("P2 Left") ? "L" : "."); - input.Append(IsPressed("P2 Right") ? "R" : "."); - input.Append(IsPressed("P2 B1") ? "1" : "."); - input.Append(IsPressed("P2 B2") ? "2" : "."); - input.Append("|"); - input.Append(IsPressed("Pause") ? "P" : "."); - input.Append(IsPressed("Reset") ? "R" : "."); - input.Append("|"); - return input.ToString(); - } - - if (type.Name == "PC Engine Controller") - { - input.Append("."); //TODO: reset goes here - the turbografx DOES NOT HAVE A RESET BUTTON. but I assume this is for pcejin movie file compatibility, which is a fools errand anyway......... I'll leave it for now, but marked for deletion - input.Append("|"); - for (int player = 1; player < 6; player++) - { - input.Append(IsPressed("P" + player.ToString() + " Up") ? "U" : "."); - input.Append(IsPressed("P" + player.ToString() + " Down") ? "D" : "."); - input.Append(IsPressed("P" + player.ToString() + " Left") ? "L" : "."); - input.Append(IsPressed("P" + player.ToString() + " Right") ? "R" : "."); - input.Append(IsPressed("P" + player.ToString() + " B1") ? "1" : "."); - input.Append(IsPressed("P" + player.ToString() + " B2") ? "2" : "."); - input.Append(IsPressed("P" + player.ToString() + " Run") ? "R" : "."); - input.Append(IsPressed("P" + player.ToString() + " Select") ? "S" : "."); - input.Append("|"); - - } - return input.ToString(); - } - - if (type.Name == "Gameboy Controller") - { - input.Append("|"); - input.Append(IsPressed("Right") ? "R" : "."); - input.Append(IsPressed("Left") ? "L" : "."); - input.Append(IsPressed("Down") ? "D" : "."); - input.Append(IsPressed("Up") ? "U" : "."); - input.Append(IsPressed("Start") ? "S" : "."); - input.Append(IsPressed("Select") ? "s" : "."); - input.Append(IsPressed("B") ? "B" : "."); - input.Append(IsPressed("A") ? "A" : "."); - } - - if (type.Name == "NES Controls") - { - input.Append(IsPressed("Reset") ? "r" : "."); - input.Append("|"); - for (int player = 1; player <= 2; player++) - { - input.Append(IsPressed("P" + player.ToString() + " Right") ? "R" : "."); - input.Append(IsPressed("P" + player.ToString() + " Left") ? "L" : "."); - input.Append(IsPressed("P" + player.ToString() + " Down") ? "D" : "."); - input.Append(IsPressed("P" + player.ToString() + " Up") ? "U" : "."); - input.Append(IsPressed("P" + player.ToString() + " Start") ? "S" : "."); - input.Append(IsPressed("P" + player.ToString() + " Select") ? "s" : "."); - input.Append(IsPressed("P" + player.ToString() + " B") ? "B" : "."); - input.Append(IsPressed("P" + player.ToString() + " A") ? "A" : "."); - input.Append("|"); - } - return input.ToString(); - } - - if (type.Name == "TI83 Controls") - { - input.Append(IsPressed("0") ? "0" : "."); - input.Append(IsPressed("1") ? "1" : "."); - input.Append(IsPressed("2") ? "2" : "."); - input.Append(IsPressed("3") ? "3" : "."); - input.Append(IsPressed("4") ? "4" : "."); - input.Append(IsPressed("5") ? "5" : "."); - input.Append(IsPressed("6") ? "6" : "."); - input.Append(IsPressed("7") ? "7" : "."); - input.Append(IsPressed("8") ? "8" : "."); - input.Append(IsPressed("9") ? "9" : "."); - input.Append(IsPressed("DOT") ? "`" : "."); - input.Append(IsPressed("ON") ? "O" : "."); - input.Append(IsPressed("ENTER") ? "=" : "."); - input.Append(IsPressed("UP") ? "U" : "."); - input.Append(IsPressed("DOWN") ? "D" : "."); - input.Append(IsPressed("LEFT") ? "L" : "."); - input.Append(IsPressed("RIGHT") ? "R" : "."); - input.Append(IsPressed("PLUS") ? "+" : "."); - input.Append(IsPressed("MINUS") ? "_" : "."); - input.Append(IsPressed("MULTIPLY") ? "*" : "."); - input.Append(IsPressed("DIVIDE") ? "/" : "."); - input.Append(IsPressed("CLEAR") ? "c" : "."); - input.Append(IsPressed("EXP") ? "^" : "."); - input.Append(IsPressed("DASH") ? "-" : "."); - input.Append(IsPressed("PARAOPEN") ? "(" : "."); - input.Append(IsPressed("PARACLOSE") ? ")" : "."); - input.Append(IsPressed("TAN") ? "T" : "."); - input.Append(IsPressed("VARS") ? "V" : "."); - input.Append(IsPressed("COS") ? "C" : "."); - input.Append(IsPressed("PRGM") ? "P" : "."); - input.Append(IsPressed("STAT") ? "s" : "."); - input.Append(IsPressed("MATRIX") ? "m" : "."); - input.Append(IsPressed("X") ? "X" : "."); - input.Append(IsPressed("STO") ? ">" : "."); - input.Append(IsPressed("LN") ? "n" : "."); - input.Append(IsPressed("LOG") ? "L" : "."); - input.Append(IsPressed("SQUARED") ? "2" : "."); - input.Append(IsPressed("NEG1") ? "1" : "."); - input.Append(IsPressed("MATH") ? "H" : "."); - input.Append(IsPressed("ALPHA") ? "A" : "."); - input.Append(IsPressed("GRAPH") ? "G" : "."); - input.Append(IsPressed("TRACE") ? "t" : "."); - input.Append(IsPressed("ZOOM") ? "Z" : "."); - input.Append(IsPressed("WINDOW") ? "W" : "."); - input.Append(IsPressed("Y") ? "Y" : "."); - input.Append(IsPressed("2ND") ? "&" : "."); - input.Append(IsPressed("MODE") ? "O" : "."); - input.Append(IsPressed("DEL") ? "D" : "."); - input.Append(IsPressed("COMMA") ? "," : "."); - input.Append(IsPressed("SIN") ? "S" : "."); - input.Append("|.|"); //TODO: perhaps ON should go here? - return input.ToString(); - } - return "?"; - } - - public void SetControllersAsMnemonic(string mnemonic) - { - MovieMode = true; - programmaticallyPressedButtons.Clear(); - - if (type.Name == "SMS Controller") - { - if (mnemonic[1] != '.') programmaticallyPressedButtons.Add("P1 Up"); - if (mnemonic[2] != '.') programmaticallyPressedButtons.Add("P1 Down"); - if (mnemonic[3] != '.') programmaticallyPressedButtons.Add("P1 Left"); - if (mnemonic[4] != '.') programmaticallyPressedButtons.Add("P1 Right"); - if (mnemonic[5] != '.') programmaticallyPressedButtons.Add("P1 B1"); - if (mnemonic[6] != '.') programmaticallyPressedButtons.Add("P1 B2"); - - if (mnemonic[8] != '.') programmaticallyPressedButtons.Add("P2 Up"); - if (mnemonic[9] != '.') programmaticallyPressedButtons.Add("P2 Down"); - if (mnemonic[10] != '.') programmaticallyPressedButtons.Add("P2 Left"); - if (mnemonic[11] != '.') programmaticallyPressedButtons.Add("P2 Right"); - if (mnemonic[12] != '.') programmaticallyPressedButtons.Add("P2 B1"); - if (mnemonic[13] != '.') programmaticallyPressedButtons.Add("P2 B2"); - - if (mnemonic[15] != '.') programmaticallyPressedButtons.Add("Pause"); - if (mnemonic[16] != '.') programmaticallyPressedButtons.Add("Reset"); - } - - if (type.Name == "PC Engine Controller") - { - if (!Global.MainForm.UserMovie.MultiTrack.isActive || (Global.MainForm.UserMovie.GetMovieMode() == MOVIEMODE.PLAY)) - { - for (int i = 1; i < 6; i++) - { - if (mnemonic.Length < (1 + i * 9)) return; - if (mnemonic[(i - 1) * 9 + 3] != '.') programmaticallyPressedButtons.Add("P" + i + " Up"); - if (mnemonic[(i - 1) * 9 + 4] != '.') programmaticallyPressedButtons.Add("P" + i + " Down"); - if (mnemonic[(i - 1) * 9 + 5] != '.') programmaticallyPressedButtons.Add("P" + i + " Left"); - if (mnemonic[(i - 1) * 9 + 6] != '.') programmaticallyPressedButtons.Add("P" + i + " Right"); - if (mnemonic[(i - 1) * 9 + 7] != '.') programmaticallyPressedButtons.Add("P" + i + " B1"); - if (mnemonic[(i - 1) * 9 + 8] != '.') programmaticallyPressedButtons.Add("P" + i + " B2"); - if (mnemonic[(i - 1) * 9 + 9] != '.') programmaticallyPressedButtons.Add("P" + i + " Run"); - if (mnemonic[(i - 1) * 9 + 10] != '.') programmaticallyPressedButtons.Add("P" + i + " Select"); - } - } - else - { - for (int i = 1; i < 6; i++) - { - if ((Global.MainForm.UserMovie.MultiTrack.CurrentPlayer == i) || Global.MainForm.UserMovie.MultiTrack.RecordAll) - { - if (IsPressedActually("P1 Up")) programmaticallyPressedButtons.Add("P" + i + " Up"); - if (IsPressedActually("P1 Down")) programmaticallyPressedButtons.Add("P" + i + " Down"); - if (IsPressedActually("P1 Left")) programmaticallyPressedButtons.Add("P" + i + " Left"); - if (IsPressedActually("P1 Right")) programmaticallyPressedButtons.Add("P" + i + " Right"); - if (IsPressedActually("P1 B1")) programmaticallyPressedButtons.Add("P" + i + " B1"); - if (IsPressedActually("P1 B2")) programmaticallyPressedButtons.Add("P" + i + " B2"); - if (IsPressedActually("P1 Run")) programmaticallyPressedButtons.Add("P" + i + " Run"); - if (IsPressedActually("P1 Select")) programmaticallyPressedButtons.Add("P" + i + " Select"); - } - else - { - if (mnemonic.Length >= (1 + i * 9)) - { - if (mnemonic[(i - 1) * 9 + 3] != '.') programmaticallyPressedButtons.Add("P" + i + " Up"); - if (mnemonic[(i - 1) * 9 + 4] != '.') programmaticallyPressedButtons.Add("P" + i + " Down"); - if (mnemonic[(i - 1) * 9 + 5] != '.') programmaticallyPressedButtons.Add("P" + i + " Left"); - if (mnemonic[(i - 1) * 9 + 6] != '.') programmaticallyPressedButtons.Add("P" + i + " Right"); - if (mnemonic[(i - 1) * 9 + 7] != '.') programmaticallyPressedButtons.Add("P" + i + " B1"); - if (mnemonic[(i - 1) * 9 + 8] != '.') programmaticallyPressedButtons.Add("P" + i + " B2"); - if (mnemonic[(i - 1) * 9 + 9] != '.') programmaticallyPressedButtons.Add("P" + i + " Run"); - if (mnemonic[(i - 1) * 9 + 10] != '.') programmaticallyPressedButtons.Add("P" + i + " Select"); - } - } - } - } - } - - if (type.Name == "NES Controls") - { - if (mnemonic.Length < 10) return; - if (mnemonic[1] != '.' && mnemonic[1] != '0') programmaticallyPressedButtons.Add("Reset"); - if (mnemonic[3] != '.') programmaticallyPressedButtons.Add("P1 Right"); - if (mnemonic[4] != '.') programmaticallyPressedButtons.Add("P1 Left"); - if (mnemonic[5] != '.') programmaticallyPressedButtons.Add("P1 Down"); - if (mnemonic[6] != '.') programmaticallyPressedButtons.Add("P1 Up"); - if (mnemonic[7] != '.') programmaticallyPressedButtons.Add("P1 Start"); - if (mnemonic[8] != '.') programmaticallyPressedButtons.Add("P1 Select"); - if (mnemonic[9] != '.') programmaticallyPressedButtons.Add("P1 B"); - if (mnemonic[10] != '.') programmaticallyPressedButtons.Add("P1 A"); - - if (mnemonic.Length < 20) return; - if (mnemonic[12] != '.') programmaticallyPressedButtons.Add("P2 Right"); - if (mnemonic[13] != '.') programmaticallyPressedButtons.Add("P2 Left"); - if (mnemonic[14] != '.') programmaticallyPressedButtons.Add("P2 Down"); - if (mnemonic[15] != '.') programmaticallyPressedButtons.Add("P2 Up"); - if (mnemonic[16] != '.') programmaticallyPressedButtons.Add("P2 Start"); - if (mnemonic[17] != '.') programmaticallyPressedButtons.Add("P2 Select"); - if (mnemonic[18] != '.') programmaticallyPressedButtons.Add("P2 B"); - if (mnemonic[19] != '.') programmaticallyPressedButtons.Add("P2 A"); - } - - if (type.Name == "Gameboy Controller") - { - if (mnemonic.Length < 10) return; - //if (mnemonic[1] != '.' && mnemonic[1] != '0') programmaticallyPressedButtons.Add("Reset"); - if (mnemonic[3] != '.') programmaticallyPressedButtons.Add("P1 Right"); - if (mnemonic[4] != '.') programmaticallyPressedButtons.Add("P1 Left"); - if (mnemonic[5] != '.') programmaticallyPressedButtons.Add("P1 Down"); - if (mnemonic[6] != '.') programmaticallyPressedButtons.Add("P1 Up"); - if (mnemonic[7] != '.') programmaticallyPressedButtons.Add("P1 Start"); - if (mnemonic[8] != '.') programmaticallyPressedButtons.Add("P1 Select"); - if (mnemonic[9] != '.') programmaticallyPressedButtons.Add("P1 B"); - if (mnemonic[10] != '.') programmaticallyPressedButtons.Add("P1 A"); - } - - if (type.Name == "TI83 Controls") - { - if (mnemonic.Length < 50) return; - - if (mnemonic[1] != '.') - programmaticallyPressedButtons.Add("0"); - if (mnemonic[2] != '.') - programmaticallyPressedButtons.Add("1"); - if (mnemonic[3] != '.') - programmaticallyPressedButtons.Add("2"); - if (mnemonic[4] != '.') - programmaticallyPressedButtons.Add("3"); - if (mnemonic[5] != '.') - programmaticallyPressedButtons.Add("4"); - if (mnemonic[6] != '.') - programmaticallyPressedButtons.Add("5"); - if (mnemonic[7] != '.') - programmaticallyPressedButtons.Add("6"); - if (mnemonic[8] != '.') - programmaticallyPressedButtons.Add("7"); - if (mnemonic[9] != '.') - programmaticallyPressedButtons.Add("8"); - if (mnemonic[10] != '.') - programmaticallyPressedButtons.Add("9"); - if (mnemonic[11] != '.') - programmaticallyPressedButtons.Add("DOT"); - if (mnemonic[12] != '.') - programmaticallyPressedButtons.Add("ON"); - if (mnemonic[13] != '.') - programmaticallyPressedButtons.Add("ENTER"); - if (mnemonic[14] != '.') - programmaticallyPressedButtons.Add("UP"); - if (mnemonic[15] != '.') - programmaticallyPressedButtons.Add("DOWN"); - if (mnemonic[16] != '.') - programmaticallyPressedButtons.Add("LEFT"); - if (mnemonic[17] != '.') - programmaticallyPressedButtons.Add("RIGHT"); - if (mnemonic[18] != '.') - programmaticallyPressedButtons.Add("PLUS"); - if (mnemonic[19] != '.') - programmaticallyPressedButtons.Add("MINUS"); - if (mnemonic[20] != '.') - programmaticallyPressedButtons.Add("MULTIPLY"); - if (mnemonic[21] != '.') - programmaticallyPressedButtons.Add("DIVIDE"); - if (mnemonic[22] != '.') - programmaticallyPressedButtons.Add("CLEAR"); - if (mnemonic[23] != '.') - programmaticallyPressedButtons.Add("EXP"); - if (mnemonic[24] != '.') - programmaticallyPressedButtons.Add("DASH"); - if (mnemonic[25] != '.') - programmaticallyPressedButtons.Add("PARAOPEN"); - if (mnemonic[26] != '.') - programmaticallyPressedButtons.Add("PARACLOSE"); - if (mnemonic[27] != '.') - programmaticallyPressedButtons.Add("TAN"); - if (mnemonic[28] != '.') - programmaticallyPressedButtons.Add("VARS"); - if (mnemonic[29] != '.') - programmaticallyPressedButtons.Add("COS"); - if (mnemonic[30] != '.') - programmaticallyPressedButtons.Add("PGRM"); - if (mnemonic[31] != '.') - programmaticallyPressedButtons.Add("STAT"); - if (mnemonic[32] != '.') - programmaticallyPressedButtons.Add("MATRIX"); - if (mnemonic[33] != '.') - programmaticallyPressedButtons.Add("X"); - if (mnemonic[34] != '.') - programmaticallyPressedButtons.Add("STO"); - if (mnemonic[35] != '.') - programmaticallyPressedButtons.Add("LN"); - if (mnemonic[36] != '.') - programmaticallyPressedButtons.Add("LOG"); - if (mnemonic[37] != '.') - programmaticallyPressedButtons.Add("SQUARED"); - if (mnemonic[38] != '.') - programmaticallyPressedButtons.Add("NEG"); - if (mnemonic[39] != '.') - programmaticallyPressedButtons.Add("MATH"); - if (mnemonic[40] != '.') - programmaticallyPressedButtons.Add("ALPHA"); - if (mnemonic[41] != '.') - programmaticallyPressedButtons.Add("GRAPH"); - if (mnemonic[42] != '.') - programmaticallyPressedButtons.Add("TRACE"); - if (mnemonic[43] != '.') - programmaticallyPressedButtons.Add("ZOOM"); - if (mnemonic[44] != '.') - programmaticallyPressedButtons.Add("WINDOW"); - if (mnemonic[45] != '.') - programmaticallyPressedButtons.Add("Y"); - if (mnemonic[46] != '.') - programmaticallyPressedButtons.Add("2ND"); - if (mnemonic[47] != '.') - programmaticallyPressedButtons.Add("MODE"); - if (mnemonic[48] != '.') - programmaticallyPressedButtons.Add("DEL"); - if (mnemonic[49] != '.') - programmaticallyPressedButtons.Add("COMMA"); - if (mnemonic[50] != '.') - programmaticallyPressedButtons.Add("SIN"); - } - } + } } \ No newline at end of file diff --git a/BizHawk.MultiClient/MainForm.MenuItems.cs b/BizHawk.MultiClient/MainForm.MenuItems.cs index 16445c4fd9..a0b232bc66 100644 --- a/BizHawk.MultiClient/MainForm.MenuItems.cs +++ b/BizHawk.MultiClient/MainForm.MenuItems.cs @@ -145,7 +145,7 @@ namespace BizHawk.MultiClient if (UserMovie.GetMovieMode() != MOVIEMODE.INACTIVE) { UserMovie.StopMovie(); - Global.ActiveController.MovieMode = false; + Global.MovieMode = false; Global.RenderPanel.AddMessage(message); } } diff --git a/BizHawk.MultiClient/MainForm.cs b/BizHawk.MultiClient/MainForm.cs index 8caa2ca2cf..8682e3f23b 100644 --- a/BizHawk.MultiClient/MainForm.cs +++ b/BizHawk.MultiClient/MainForm.cs @@ -752,20 +752,37 @@ namespace BizHawk.MultiClient Global.ActiveController = Global.NullControls; break; } - Global.Emulator.Controller = Global.ActiveController; - Global.ActiveController.MovieMode = false; + + RewireInputChain(); + Global.MovieMode = false; + } + + void RewireInputChain() + { + //insert turbo and lua here? + Global.MultitrackRewiringControllerAdapter.Source = Global.ActiveController; + Global.MovieInputSourceAdapter.Source = Global.MultitrackRewiringControllerAdapter; + Global.MovieControllerAdapter.SetSource(Global.MovieInputSourceAdapter); + Global.ControllerOutput = Global.MovieControllerAdapter; + Global.Emulator.Controller = Global.ControllerOutput; } public bool LoadRom(string path) { - using (var file = new HawkFile(path)) + using (var file = new HawkFile()) { + string[] romExtensions = new string[] { "SMS", "PCE", "SGX", "GG", "SG", "BIN", "SMD", "GB", "NES", "ROM" }; + + //lets not use this unless we need to + //file.NonArchiveExtensions = romExtensions; + file.Open(path); + //if the provided file doesnt even exist, give up! if (!file.Exists) return false; //try binding normal rom extensions first if (!file.IsBound) - file.BindSoleItemOf("SMS", "PCE", "SGX", "GG", "SG", "BIN", "SMD", "GB", "NES", "ROM"); + file.BindSoleItemOf(romExtensions); //if we have an archive and need to bind something, then pop the dialog if (file.IsArchive && !file.IsBound) @@ -1150,8 +1167,8 @@ namespace BizHawk.MultiClient } if (Global.ClientControls["Toggle MultiTrack"]) { - Global.MainForm.UserMovie.MultiTrack.isActive = !Global.MainForm.UserMovie.MultiTrack.isActive; - if (Global.MainForm.UserMovie.MultiTrack.isActive) + Global.MainForm.UserMovie.MultiTrack.IsActive = !Global.MainForm.UserMovie.MultiTrack.IsActive; + if (Global.MainForm.UserMovie.MultiTrack.IsActive) { Global.RenderPanel.AddMessage("MultiTrack Enabled"); Global.RenderPanel.MT = "Recording None"; @@ -1240,7 +1257,7 @@ namespace BizHawk.MultiClient } } - wasPressed = (TAStudio1.Engaged) ? TAStudio1.GetMnemonic() : Global.ActiveController.GetControllersAsMnemonic(); + wasPressed = Global.GetOutputControllersAsMnemonic(); PressFrameAdvance = false; } else @@ -1306,33 +1323,59 @@ namespace BizHawk.MultiClient else if (!Global.Config.MuteFrameAdvance) genSound = true; + + if (UserMovie.GetMovieMode() != MOVIEMODE.INACTIVE) + { + UserMovie.LatchInputFromLog(); + } + + if (UserMovie.GetMovieMode() == MOVIEMODE.RECORD) + { + UserMovie.LatchInputFromPlayer(); + UserMovie.CommitFrame(); + } + + if (UserMovie.GetMovieMode() == MOVIEMODE.PLAY && UserMovie.MultiTrack.IsActive) + { + UserMovie.LatchMultitrackPlayerInput(); + UserMovie.CommitFrame(); + } + + if (UserMovie.GetMovieMode() == MOVIEMODE.INACTIVE) + { + UserMovie.LatchInputFromPlayer(); + } + if (UserMovie.GetMovieMode() == MOVIEMODE.PLAY) { if (UserMovie.GetMovieLength() == Global.Emulator.Frame) { UserMovie.SetMovieFinished(); - Global.ActiveController.MovieMode = false; - } - else - { - Global.ActiveController.SetControllersAsMnemonic(UserMovie.GetInputFrame(Global.Emulator.Frame)); + Global.MovieMode = false; } } - if (UserMovie.GetMovieMode() == MOVIEMODE.FINISHED) - { - if (UserMovie.GetMovieLength() > Global.Emulator.Frame) - { - UserMovie.StartPlayback(); - Global.ActiveController.SetControllersAsMnemonic(UserMovie.GetInputFrame(Global.Emulator.Frame)); - } - } - if (UserMovie.GetMovieMode() == MOVIEMODE.RECORD && UserMovie.MultiTrack.isActive) - { - Global.ActiveController.SetControllersAsMnemonic(UserMovie.GetInputFrame(Global.Emulator.Frame-1)); - //Console.WriteLine("Out: " + UserMovie.GetInputFrame(Global.Emulator.Frame)); - } + //if (UserMovie.GetMovieMode() == MOVIEMODE.FINISHED) + //{ + // if (UserMovie.GetMovieLength() > Global.Emulator.Frame) + // { + // UserMovie.StartPlayback(); + // Global.MovieControllerAdapter.SetControllersAsMnemonic(UserMovie.GetInputFrame(Global.Emulator.Frame)); + // } + //} + //if (UserMovie.GetMovieMode() == MOVIEMODE.RECORD && UserMovie.MultiTrack.isActive) + //{ + // Global.MovieControllerAdapter.SetControllersAsMnemonic(UserMovie.GetInputFrame(Global.Emulator.Frame-1)); + // //Console.WriteLine("Out: " + UserMovie.GetInputFrame(Global.Emulator.Frame)); + //} + + //TODO multitrack + + + //======================================= Global.Emulator.FrameAdvance(!throttle.skipnextframe); + //======================================= + RamWatch1.UpdateValues(); RamSearch1.UpdateValues(); HexEditor1.UpdateValues(); @@ -1340,13 +1383,6 @@ namespace BizHawk.MultiClient NESPPU1.UpdateValues(); TAStudio1.UpdateValues(); - if (UserMovie.GetMovieMode() == MOVIEMODE.RECORD) - { - UserMovie.GetMnemonic(); - //Console.WriteLine("In: " + UserMovie.GetInputFrame(Global.Emulator.Frame)); - } - else if (InputLog.GetMovieMode() == MOVIEMODE.RECORD) - InputLog.GetMnemonic(); } if (genSound) @@ -1440,12 +1476,12 @@ namespace BizHawk.MultiClient { UserMovie.WriteMovie(); UserMovie.StartPlayback(); - Global.ActiveController.MovieMode = true; + Global.MovieMode = true; } } else { - Global.ActiveController.MovieMode = false; + Global.MovieMode = false; UserMovie.LoadLogFromSavestateText(reader); } } @@ -1460,7 +1496,7 @@ namespace BizHawk.MultiClient else { UserMovie.StartNewRecording(); - Global.ActiveController.MovieMode = false; + Global.MovieMode = false; UserMovie.LoadLogFromSavestateText(reader); } } @@ -1471,7 +1507,7 @@ namespace BizHawk.MultiClient { if (Global.Emulator.Frame > UserMovie.GetMovieLength()) { - Global.ActiveController.MovieMode = false; + Global.MovieMode = false; //Post movie savestate //There is no movie data to load, and the movie will stay in movie finished mode //So do nothing @@ -1480,7 +1516,7 @@ namespace BizHawk.MultiClient { int x = UserMovie.CheckTimeLines(reader); UserMovie.StartPlayback(); - Global.ActiveController.MovieMode = true; + Global.MovieMode = true; //if (x >= 0) // MessageBox.Show("Savestate input log does not match the movie at frame " + (x+1).ToString() + "!", "Timeline error", MessageBoxButtons.OK); //TODO: replace with a not annoying message once savestate logic is running smoothly } @@ -1489,7 +1525,7 @@ namespace BizHawk.MultiClient { if (Global.Emulator.Frame > UserMovie.GetMovieLength()) { - Global.ActiveController.MovieMode = false; + Global.MovieMode = false; //Post movie savestate //There is no movie data to load, and the movie will stay in movie finished mode //So do nothing @@ -1497,7 +1533,7 @@ namespace BizHawk.MultiClient else { UserMovie.StartNewRecording(); - Global.ActiveController.MovieMode = false; + Global.MovieMode = false; UserMovie.LoadLogFromSavestateText(reader); } } diff --git a/BizHawk.MultiClient/PlayMovie.cs b/BizHawk.MultiClient/PlayMovie.cs index ec21fc2a71..95cc13cf64 100644 --- a/BizHawk.MultiClient/PlayMovie.cs +++ b/BizHawk.MultiClient/PlayMovie.cs @@ -92,18 +92,20 @@ namespace BizHawk.MultiClient private void AddMovieToList(string filename) { - var file = new HawkFile(filename); - if (!file.Exists) - return; - else + using (var file = new HawkFile(filename)) { - PreLoadMovieFile(file); - MovieView.ItemCount = MovieList.Count; - UpdateList(); - MovieView.SelectedIndices.Clear(); - MovieView.setSelection(MovieList.Count - 1); - sortReverse = false; - sortedCol = ""; + if (!file.Exists) + return; + else + { + PreLoadMovieFile(file); + MovieView.ItemCount = MovieList.Count; + UpdateList(); + MovieView.SelectedIndices.Clear(); + MovieView.setSelection(MovieList.Count - 1); + sortReverse = false; + sortedCol = ""; + } } } @@ -150,6 +152,8 @@ namespace BizHawk.MultiClient private void MovieView_SelectedIndexChanged(object sender, EventArgs e) { DetailsView.Items.Clear(); + if (MovieView.SelectedIndices.Count < 1) return; + int x = MovieView.SelectedIndices[0]; Dictionary h = MovieList[x].GetHeaderInfo(); diff --git a/BizHawk.MultiClient/RenderPanel.cs b/BizHawk.MultiClient/RenderPanel.cs index 3112c99df9..45f9f54581 100644 --- a/BizHawk.MultiClient/RenderPanel.cs +++ b/BizHawk.MultiClient/RenderPanel.cs @@ -354,7 +354,7 @@ namespace BizHawk.MultiClient input = MakeInputDisplay(); MessageFont.DrawString(null, input, x, y, c); } - if (Global.MainForm.UserMovie.MultiTrack.isActive) + if (Global.MainForm.UserMovie.MultiTrack.IsActive) { MessageFont.DrawString(null, MT, Global.Config.DispFPSx + 1, //TODO: Multitrack position variables Global.Config.DispFPSy + 1, new Color4(Color.Black)); @@ -486,7 +486,7 @@ namespace BizHawk.MultiClient public string MakeInputDisplay() { - string tmp = Global.ActiveController.GetControllersAsMnemonic(); + string tmp = Global.GetOutputControllersAsMnemonic(); tmp = tmp.Replace(".", " "); tmp = tmp.Replace("|", ""); return tmp; diff --git a/BizHawk.MultiClient/config/HotkeyWindow.cs b/BizHawk.MultiClient/config/HotkeyWindow.cs index 5cc4945aa8..0cd9d4f6cb 100644 --- a/BizHawk.MultiClient/config/HotkeyWindow.cs +++ b/BizHawk.MultiClient/config/HotkeyWindow.cs @@ -177,7 +177,7 @@ namespace BizHawk.MultiClient.tools private void hotkeyTabs_SelectedIndexChanged(object sender, EventArgs e) { - hotkeyTabs.TabPages[hotkeyTabs.SelectedIndex].Controls[0].Focus(); + //hotkeyTabs.TabPages[hotkeyTabs.SelectedIndex].Controls[0].Focus(); } private void HotkeyWindow_Load(object sender, EventArgs e) diff --git a/BizHawk.MultiClient/movie/InputAdapters.cs b/BizHawk.MultiClient/movie/InputAdapters.cs new file mode 100644 index 0000000000..4243bf429d --- /dev/null +++ b/BizHawk.MultiClient/movie/InputAdapters.cs @@ -0,0 +1,504 @@ +using System; +using System.Text; +using System.Collections.Generic; + +namespace BizHawk.MultiClient +{ + public class MnemonicsGenerator + { + IController Source; + public void SetSource(IController source) + { + Source = source; + ControlType = source.Type.Name; + } + string ControlType; + + bool IsBasePressed(string name) { + bool ret = Source.IsPressed(name); + if(ret) + { + //int zzz=9; + } + return ret; + } + + public string GetControllersAsMnemonic() + { + StringBuilder input = new StringBuilder("|"); + + if (ControlType == "SMS Controller") + { + input.Append(IsBasePressed("P1 Up") ? "U" : "."); + input.Append(IsBasePressed("P1 Down") ? "D" : "."); + input.Append(IsBasePressed("P1 Left") ? "L" : "."); + input.Append(IsBasePressed("P1 Right") ? "R" : "."); + input.Append(IsBasePressed("P1 B1") ? "1" : "."); + input.Append(IsBasePressed("P1 B2") ? "2" : "."); + input.Append("|"); + input.Append(IsBasePressed("P2 Up") ? "U" : "."); + input.Append(IsBasePressed("P2 Down") ? "D" : "."); + input.Append(IsBasePressed("P2 Left") ? "L" : "."); + input.Append(IsBasePressed("P2 Right") ? "R" : "."); + input.Append(IsBasePressed("P2 B1") ? "1" : "."); + input.Append(IsBasePressed("P2 B2") ? "2" : "."); + input.Append("|"); + input.Append(IsBasePressed("Pause") ? "P" : "."); + input.Append(IsBasePressed("Reset") ? "R" : "."); + input.Append("|"); + return input.ToString(); + } + + if (ControlType == "PC Engine Controller") + { + input.Append("."); //TODO: reset goes here - the turbografx DOES NOT HAVE A RESET BUTTON. but I assume this is for pcejin movie file compatibility, which is a fools errand anyway......... I'll leave it for now, but marked for deletion + input.Append("|"); + for (int player = 1; player < 6; player++) + { + input.Append(IsBasePressed("P" + player.ToString() + " Up") ? "U" : "."); + input.Append(IsBasePressed("P" + player.ToString() + " Down") ? "D" : "."); + input.Append(IsBasePressed("P" + player.ToString() + " Left") ? "L" : "."); + input.Append(IsBasePressed("P" + player.ToString() + " Right") ? "R" : "."); + input.Append(IsBasePressed("P" + player.ToString() + " B1") ? "1" : "."); + input.Append(IsBasePressed("P" + player.ToString() + " B2") ? "2" : "."); + input.Append(IsBasePressed("P" + player.ToString() + " Run") ? "R" : "."); + input.Append(IsBasePressed("P" + player.ToString() + " Select") ? "S" : "."); + input.Append("|"); + + } + return input.ToString(); + } + + if (ControlType == "Gameboy Controller") + { + input.Append("|"); + input.Append(IsBasePressed("Right") ? "R" : "."); + input.Append(IsBasePressed("Left") ? "L" : "."); + input.Append(IsBasePressed("Down") ? "D" : "."); + input.Append(IsBasePressed("Up") ? "U" : "."); + input.Append(IsBasePressed("Start") ? "S" : "."); + input.Append(IsBasePressed("Select") ? "s" : "."); + input.Append(IsBasePressed("B") ? "B" : "."); + input.Append(IsBasePressed("A") ? "A" : "."); + } + + if (ControlType == "NES Controls") + { + input.Append(IsBasePressed("Reset") ? "r" : "."); + input.Append("|"); + for (int player = 1; player <= 2; player++) + { + input.Append(IsBasePressed("P" + player.ToString() + " Right") ? "R" : "."); + input.Append(IsBasePressed("P" + player.ToString() + " Left") ? "L" : "."); + input.Append(IsBasePressed("P" + player.ToString() + " Down") ? "D" : "."); + input.Append(IsBasePressed("P" + player.ToString() + " Up") ? "U" : "."); + input.Append(IsBasePressed("P" + player.ToString() + " Start") ? "S" : "."); + input.Append(IsBasePressed("P" + player.ToString() + " Select") ? "s" : "."); + input.Append(IsBasePressed("P" + player.ToString() + " B") ? "B" : "."); + input.Append(IsBasePressed("P" + player.ToString() + " A") ? "A" : "."); + input.Append("|"); + } + return input.ToString(); + } + + if (ControlType == "TI83 Controls") + { + input.Append(IsBasePressed("0") ? "0" : "."); + input.Append(IsBasePressed("1") ? "1" : "."); + input.Append(IsBasePressed("2") ? "2" : "."); + input.Append(IsBasePressed("3") ? "3" : "."); + input.Append(IsBasePressed("4") ? "4" : "."); + input.Append(IsBasePressed("5") ? "5" : "."); + input.Append(IsBasePressed("6") ? "6" : "."); + input.Append(IsBasePressed("7") ? "7" : "."); + input.Append(IsBasePressed("8") ? "8" : "."); + input.Append(IsBasePressed("9") ? "9" : "."); + input.Append(IsBasePressed("DOT") ? "`" : "."); + input.Append(IsBasePressed("ON") ? "O" : "."); + input.Append(IsBasePressed("ENTER") ? "=" : "."); + input.Append(IsBasePressed("UP") ? "U" : "."); + input.Append(IsBasePressed("DOWN") ? "D" : "."); + input.Append(IsBasePressed("LEFT") ? "L" : "."); + input.Append(IsBasePressed("RIGHT") ? "R" : "."); + input.Append(IsBasePressed("PLUS") ? "+" : "."); + input.Append(IsBasePressed("MINUS") ? "_" : "."); + input.Append(IsBasePressed("MULTIPLY") ? "*" : "."); + input.Append(IsBasePressed("DIVIDE") ? "/" : "."); + input.Append(IsBasePressed("CLEAR") ? "c" : "."); + input.Append(IsBasePressed("EXP") ? "^" : "."); + input.Append(IsBasePressed("DASH") ? "-" : "."); + input.Append(IsBasePressed("PARAOPEN") ? "(" : "."); + input.Append(IsBasePressed("PARACLOSE") ? ")" : "."); + input.Append(IsBasePressed("TAN") ? "T" : "."); + input.Append(IsBasePressed("VARS") ? "V" : "."); + input.Append(IsBasePressed("COS") ? "C" : "."); + input.Append(IsBasePressed("PRGM") ? "P" : "."); + input.Append(IsBasePressed("STAT") ? "s" : "."); + input.Append(IsBasePressed("MATRIX") ? "m" : "."); + input.Append(IsBasePressed("X") ? "X" : "."); + input.Append(IsBasePressed("STO") ? ">" : "."); + input.Append(IsBasePressed("LN") ? "n" : "."); + input.Append(IsBasePressed("LOG") ? "L" : "."); + input.Append(IsBasePressed("SQUARED") ? "2" : "."); + input.Append(IsBasePressed("NEG1") ? "1" : "."); + input.Append(IsBasePressed("MATH") ? "H" : "."); + input.Append(IsBasePressed("ALPHA") ? "A" : "."); + input.Append(IsBasePressed("GRAPH") ? "G" : "."); + input.Append(IsBasePressed("TRACE") ? "t" : "."); + input.Append(IsBasePressed("ZOOM") ? "Z" : "."); + input.Append(IsBasePressed("WINDOW") ? "W" : "."); + input.Append(IsBasePressed("Y") ? "Y" : "."); + input.Append(IsBasePressed("2ND") ? "&" : "."); + input.Append(IsBasePressed("MODE") ? "O" : "."); + input.Append(IsBasePressed("DEL") ? "D" : "."); + input.Append(IsBasePressed("COMMA") ? "," : "."); + input.Append(IsBasePressed("SIN") ? "S" : "."); + input.Append("|.|"); //TODO: perhaps ON should go here? + return input.ToString(); + } + return "?"; + } + } + + /// + /// just copies source to sink, or returns whatever a NullController would if it is disconnected. useful for immovable hardpoints. + /// + public class CopyControllerAdapter : IController + { + public IController Source; + NullController _null = new NullController(); + + IController Curr { get { + if(Source == null) return _null; + else return Source; + } + } + + public ControllerDefinition Type { get { return Curr.Type; } } + public bool this[string button] { get { return Curr[button]; } } + public bool IsPressed(string button) { return Curr.IsPressed(button); } + public float GetFloat(string name) { return Curr.GetFloat(name); } + public void UpdateControls(int frame) { Curr.UpdateControls(frame); } + } + + class ButtonNameParser + { + ButtonNameParser() + { + } + + public static ButtonNameParser Parse(string button) + { + //see if we're being asked for a button that we know how to rewire + string[] parts = button.Split(' '); + if (parts.Length < 2) return null; + if (parts[0][0] != 'P') return null; + int player = 0; + if (!int.TryParse(parts[0].Substring(1), out player)) + return null; + var bnp = new ButtonNameParser(); + bnp.PlayerNum = player; + bnp.ButtonPart = button.Substring(parts[0].Length + 1); + return bnp; + } + + public int PlayerNum; + public string ButtonPart; + + public override string ToString() + { + return string.Format("P{0} {1}", PlayerNum, ButtonPart); + } + } + + /// + /// rewires player1 controls to playerN + /// + public class MultitrackRewiringControllerAdapter : IController + { + public IController Source; + public int PlayerSource = 1; + public int PlayerTargetMask = 0; + + public ControllerDefinition Type { get { return Source.Type; } } + public bool this[string button] { get { return this.IsPressed(button); } } + public float GetFloat(string name) { return Source.GetFloat(name); } + public void UpdateControls(int frame) { Source.UpdateControls(frame); } + + public bool IsPressed(string button) + { + //do we even have a source? + if(PlayerSource == -1) return Source.IsPressed(button); + + //see if we're being asked for a button that we know how to rewire + ButtonNameParser bnp = ButtonNameParser.Parse(button); + if(bnp == null) return Source.IsPressed(button); + + //ok, this looks like a normal `P1 Button` type thing. we can handle it + //were we supposed to replace this one? + int foundPlayerMask = (1 << bnp.PlayerNum); + if((PlayerTargetMask & foundPlayerMask)==0) return Source.IsPressed(button); + //ok, we were. swap out the source player and then grab his button + bnp.PlayerNum = PlayerSource; + return Source.IsPressed(bnp.ToString()); + } + } + + public class MovieControllerAdapter : IController + { + public MovieControllerAdapter() + { + //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 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); } + //-------- + + Dictionary MyBoolButtons = new Dictionary(); + + void Force(string button, bool state) + { + MyBoolButtons[button] = state; + } + + string ControlType { get { return Type.Name; } } + + class MnemonicChecker + { + public MnemonicChecker(string _m) + { + m = _m; + } + string m; + public bool this[int c] + { + get { return m[c] != '.'; } + } + } + + + /// + /// latches one player from the source + /// + public void LatchPlayerFromSource(int playerNum) + { + foreach (string button in Source.Type.BoolButtons) + { + ButtonNameParser bnp = ButtonNameParser.Parse(button); + if (bnp == null) continue; + if (bnp.PlayerNum != playerNum) continue; + bool val = Source[button]; + MyBoolButtons[button] = val; + } + } + + /// + /// latches all buttons from the upstream source + /// + public void LatchFromSource() + { + foreach (string button in Type.BoolButtons) + { + MyBoolButtons[button] = Source[button]; + } + } + + /// + /// latches all buttons from the supplied mnemonic string + /// + public void SetControllersAsMnemonic(string mnemonic) + { + MnemonicChecker c = new MnemonicChecker(mnemonic); + + MyBoolButtons.Clear(); + + if (ControlType == "SMS Controller") + { + Force("P1 Up", c[1]); + Force("P1 Down", c[2]); + Force("P1 Left", c[3]); + Force("P1 Right", c[4]); + Force("P1 B1", c[5]); + Force("P1 B2", c[6]); + + Force("P2 Up", c[8]); + Force("P2 Down", c[9]); + Force("P2 Left", c[10]); + Force("P2 Right", c[11]); + Force("P2 B1", c[12]); + Force("P2 B2", c[13]); + + Force("Pause",c[15]); + Force("Reset",c[16]); + } + + if (ControlType == "PC Engine Controller") + { + for (int i = 1; i < 6; i++) + { + int playerNum = i; + int srcindex = (playerNum - 1) * 9; + Force("P" + i + " Up", c[srcindex + 3]); + Force("P" + i + " Down", c[srcindex + 4]); + Force("P" + i + " Left", c[srcindex + 5]); + Force("P" + i + " Right", c[srcindex + 6]); + Force("P" + i + " B1", c[srcindex + 7]); + Force("P" + i + " B2", c[srcindex + 8]); + Force("P" + i + " Run", c[srcindex + 9]); + Force("P" + i + " Select", c[srcindex + 10]); + } + } + + if (ControlType == "NES Controls") + { + if (mnemonic.Length < 10) return; + Force("Reset", mnemonic[1] != '.' && mnemonic[1] != '0'); + int ctr = 3; + Force("P1 Right",c[ctr++]); + Force("P1 Left", c[ctr++]); + Force("P1 Down", c[ctr++]); + Force("P1 Up", c[ctr++]); + Force("P1 Start", c[ctr++]); + Force("P1 Select", c[ctr++]); + Force("P1 B", c[ctr++]); + Force("P1 A", c[ctr++]); + + if (mnemonic.Length < 20) return; + ctr = 12; + Force("P2 Right",c[ctr++]); + Force("P2 Left", c[ctr++]); + Force("P2 Down", c[ctr++]); + Force("P2 Up", c[ctr++]); + Force("P2 Start", c[ctr++]); + Force("P2 Select", c[ctr++]); + Force("P2 B", c[ctr++]); + Force("P2 A", c[ctr++]); + } + + + if (ControlType == "Gameboy Controller") + { + if (mnemonic.Length < 10) return; + //if (mnemonic[1] != '.' && mnemonic[1] != '0') programmaticallyPressedButtons.Add("Reset"); + int ctr = 3; + Force("P1 Right", c[ctr++]); + Force("P1 Left", c[ctr++]); + Force("P1 Down", c[ctr++]); + Force("P1 Up", c[ctr++]); + Force("P1 Start", c[ctr++]); + Force("P1 Select", c[ctr++]); + Force("P1 B", c[ctr++]); + Force("P1 A", c[ctr++]); + } + + if (ControlType == "TI83 Controls") + { + if (mnemonic.Length < 50) return; + int ctr = 1; + + Force("0",c[ctr++]); + Force("1", c[ctr++]); + Force("2", c[ctr++]); + Force("3", c[ctr++]); + Force("4", c[ctr++]); + Force("5", c[ctr++]); + Force("6", c[ctr++]); + Force("7", c[ctr++]); + Force("8", c[ctr++]); + Force("9", c[ctr++]); + Force("DOT", c[ctr++]); + Force("ON", c[ctr++]); + Force("ENTER", c[ctr++]); + Force("UP", c[ctr++]); + Force("DOWN", c[ctr++]); + Force("LEFT", c[ctr++]); + Force("RIGHT", c[ctr++]); + Force("PLUS", c[ctr++]); + Force("MINUS", c[ctr++]); + Force("MULTIPLY", c[ctr++]); + Force("DIVIDE", c[ctr++]); + Force("CLEAR", c[ctr++]); + Force("EXP", c[ctr++]); + Force("DASH", c[ctr++]); + Force("PARAOPEN", c[ctr++]); + Force("PARACLOSE", c[ctr++]); + Force("TAN", c[ctr++]); + Force("VARS", c[ctr++]); + Force("COS", c[ctr++]); + Force("PGRM", c[ctr++]); + Force("STAT", c[ctr++]); + Force("MATRIX", c[ctr++]); + Force("X", c[ctr++]); + Force("STO", c[ctr++]); + Force("LN", c[ctr++]); + Force("LOG", c[ctr++]); + Force("SQUARED", c[ctr++]); + Force("NEG", c[ctr++]); + Force("MATH", c[ctr++]); + Force("ALPHA", c[ctr++]); + Force("GRAPH", c[ctr++]); + Force("TRACE", c[ctr++]); + Force("ZOOM", c[ctr++]); + Force("WINDOW", c[ctr++]); + Force("Y", c[ctr++]); + Force("2ND", c[ctr++]); + Force("MODE", c[ctr++]); + Force("DEL", c[ctr++]); + Force("COMMA", c[ctr++]); + Force("SIN", c[ctr++]); + } + } + } + + //not being used.. + + ///// + ///// adapts an IController to force some buttons to a different state. + ///// unforced button states will flow through to the adaptee + ///// + //public class ForceControllerAdapter : IController + //{ + // public IController Controller; + + // public Dictionary Forces = new Dictionary(); + // public void Clear() + // { + // Forces.Clear(); + // } + + + // public ControllerDefinition Type { get { return Controller.Type; } } + + // public bool this[string button] { get { return IsPressed(button); } } + + // public bool IsPressed(string button) + // { + // if (Forces.ContainsKey(button)) + // return Forces[button]; + // else return Controller.IsPressed(button); + // } + + // public float GetFloat(string name) + // { + // return Controller.GetFloat(name); //TODO! + // } + + // public void UpdateControls(int frame) + // { + // Controller.UpdateControls(frame); + // } + //} +} \ No newline at end of file diff --git a/BizHawk.MultiClient/movie/Movie.cs b/BizHawk.MultiClient/movie/Movie.cs index 32c84af152..7c0f5cd879 100644 --- a/BizHawk.MultiClient/movie/Movie.cs +++ b/BizHawk.MultiClient/movie/Movie.cs @@ -87,29 +87,54 @@ namespace BizHawk.MultiClient return MovieMode; } - public void GetMnemonic() + public void LatchMultitrackPlayerInput() { - if (MultiTrack.isActive) + if (MultiTrack.IsActive) { - if (MovieMode == MOVIEMODE.RECORD) - { - - if (Global.Emulator.Frame < Log.Length()) - Log.ReplaceFrameAt(Global.ActiveController.GetControllersAsMnemonic(), Global.Emulator.Frame); - else - Log.AddFrame(Global.ActiveController.GetControllersAsMnemonic()); - } + Global.MultitrackRewiringControllerAdapter.PlayerSource = 1; + Global.MultitrackRewiringControllerAdapter.PlayerTargetMask = 1 << (MultiTrack.CurrentPlayer); + if (MultiTrack.RecordAll) Global.MultitrackRewiringControllerAdapter.PlayerTargetMask = unchecked((int)0xFFFFFFFF); } - else - if (MovieMode == MOVIEMODE.RECORD) - { + else Global.MultitrackRewiringControllerAdapter.PlayerSource = -1; - if (Global.Emulator.Frame < Log.Length()) - { - Log.Truncate(Global.Emulator.Frame); - } - Log.AddFrame(Global.ActiveController.GetControllersAsMnemonic()); - } + 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) + //{ + //} + //else + // if (Global.Emulator.Frame < Log.Length()) + // { + // Log.Truncate(Global.Emulator.Frame); + // } + + //REMOVED TRUNCATION!!!! + //WHY DO IT HERE??? DO IT WHEN WE LOAD THE SAVESTATE IN READ+WRITE MODE! JESUS + + MnemonicsGenerator mg = new MnemonicsGenerator(); + mg.SetSource(Global.MovieInputSourceAdapter); + Log.SetFrameAt(Global.Emulator.Frame, mg.GetControllersAsMnemonic()); } public string GetInputFrame(int frame) @@ -129,7 +154,7 @@ namespace BizHawk.MultiClient public void InsertFrame(string record, int frame) { - Log.AddFrameAt(record, frame); + Log.SetFrameAt(frame, record); } public void WriteMovie() @@ -371,7 +396,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 (!MultiTrack.IsActive) { if (Global.Config.EnableBackupMovies && MakeBackup && Log.Length() > 0) { @@ -402,7 +427,7 @@ namespace BizHawk.MultiClient if (line == "[/Input]") break; if (line[0] == '|') { - Log.ReplaceFrameAt(line, i); + Log.SetFrameAt(i,line); i++; } } diff --git a/BizHawk.MultiClient/movie/MovieConvert.cs b/BizHawk.MultiClient/movie/MovieConvert.cs index 2e415ffa31..5c9dc233df 100644 --- a/BizHawk.MultiClient/movie/MovieConvert.cs +++ b/BizHawk.MultiClient/movie/MovieConvert.cs @@ -80,6 +80,7 @@ namespace BizHawk.MultiClient if ((int)(flags[0] & 4) > 0) pal = true; + m.SetHeaderLine("SyncHack", movieSyncHackOn.ToString()); m.SetHeaderLine("PAL", pal.ToString()); //Power on vs reset diff --git a/BizHawk.MultiClient/movie/MovieLog.cs b/BizHawk.MultiClient/movie/MovieLog.cs index a17ae80ab5..bf401d3017 100644 --- a/BizHawk.MultiClient/movie/MovieLog.cs +++ b/BizHawk.MultiClient/movie/MovieLog.cs @@ -39,7 +39,7 @@ namespace BizHawk.MultiClient { MovieRecords.Add(frame); } - public void ReplaceFrameAt(string frame, int frameNum) + public void SetFrameAt(int frameNum, string frame) { if (MovieRecords.Count > frameNum) MovieRecords[frameNum] = frame; diff --git a/BizHawk.MultiClient/movie/MultitrackRecording.cs b/BizHawk.MultiClient/movie/MultitrackRecording.cs index 415eb089d2..725e0c37ed 100644 --- a/BizHawk.MultiClient/movie/MultitrackRecording.cs +++ b/BizHawk.MultiClient/movie/MultitrackRecording.cs @@ -7,12 +7,12 @@ namespace BizHawk.MultiClient { public class MultitrackRecording { - public bool isActive; + public bool IsActive; public int CurrentPlayer; public bool RecordAll; public MultitrackRecording() { - isActive = false; + IsActive = false; CurrentPlayer = 0; RecordAll = false; }