diff --git a/BizHawk.Client.Common/inputAdapters/AutoPattern.cs b/BizHawk.Client.Common/inputAdapters/AutoPattern.cs index ca63dcaea9..f39536e7a1 100644 --- a/BizHawk.Client.Common/inputAdapters/AutoPattern.cs +++ b/BizHawk.Client.Common/inputAdapters/AutoPattern.cs @@ -7,48 +7,53 @@ namespace BizHawk.Client.Common { public class AutoPatternBool { - public bool SkipsLag = true; - private bool[] _pattern; - private int _index; + public readonly bool SkipsLag = true; + public readonly bool[] Pattern; + public readonly int Loop = 0; + private int _index = 0; /// /// Autohold. /// public AutoPatternBool() { - SkipsLag = true; - _index = 0; - _pattern = new bool[] { true }; + Pattern = new bool[] { true }; } /// /// Simple on/off pattern. /// /// /// - public AutoPatternBool(int on, int off, bool skip_lag = true, int offset = 0) + public AutoPatternBool(int on, int off, bool skip_lag = true, int offset = 0, int loop = 0) { SkipsLag = skip_lag; _index = offset; - _pattern = new bool[on + off]; + Pattern = new bool[on + off]; + Loop = loop; for (int i = 0; i < on; i++) - _pattern[i] = true; + Pattern[i] = true; } - public AutoPatternBool(bool[] pattern, bool skip_lag = true, int offset = 0) + public AutoPatternBool(bool[] pattern, bool skip_lag = true, int offset = 0, int loop = 0) { SkipsLag = skip_lag; - _pattern = pattern; + Pattern = pattern; _index = offset; + Loop = loop; } /// /// Gets the next value and increments index. /// /// - public bool GetNextValue() + public bool GetNextValue(bool isLag = false) { - bool ret = _pattern[_index]; - _index++; - _index = _index % _pattern.Length; + bool ret = Pattern[_index]; + if (!isLag || !SkipsLag) + { + _index++; + if (_index == Pattern.Length) + _index = Loop; + } return ret; } @@ -58,13 +63,17 @@ namespace BizHawk.Client.Common /// /// public bool PeekNextValue() - { return _pattern[_index]; } + { return Pattern[_index]; } + + public void Reset() + { _index = 0; } } public class AutoPatternFloat { - public bool SkipsLag = true; - private float[] _pattern; + public readonly bool SkipsLag = true; + public readonly float[] Pattern; + public readonly int Loop = 0; private int _index; /// @@ -72,39 +81,43 @@ namespace BizHawk.Client.Common /// public AutoPatternFloat() { - SkipsLag = true; - _pattern = new float[] { 0f }; - _index = 0; + Pattern = new float[] { 0f }; } /// /// Sinple on/off pattern, using the given values as on/off. /// - public AutoPatternFloat(float valueOn, int on, float valueOff, int off, bool skip_lag = true, int offset = 0) + public AutoPatternFloat(float valueOn, int on, float valueOff, int off, bool skip_lag = true, int offset = 0, int loop = 0) { SkipsLag = skip_lag; _index = offset; - _pattern = new float[on + off]; + Loop = loop; + Pattern = new float[on + off]; for (int i = 0; i < on; i++) - _pattern[i] = valueOn; - for (int i = on; i < _pattern.Length; i++) - _pattern[i] = valueOff; + Pattern[i] = valueOn; + for (int i = on; i < Pattern.Length; i++) + Pattern[i] = valueOff; } - public AutoPatternFloat(float[] pattern, bool skip_lag = true, int offset = 0) + public AutoPatternFloat(float[] pattern, bool skip_lag = true, int offset = 0, int loop = 0) { SkipsLag = skip_lag; - _pattern = pattern; + Pattern = pattern; _index = offset; + Loop = loop; } /// /// Gets the next value and increments index. /// /// - public float GetNextValue() + public float GetNextValue(bool isLag = false) { - float ret = _pattern[_index]; - _index++; - _index = _index % _pattern.Length; + float ret = Pattern[_index]; + if (!isLag || !SkipsLag) + { + _index++; + if (_index == Pattern.Length) + _index = Loop; + } return ret; } @@ -114,6 +127,9 @@ namespace BizHawk.Client.Common /// /// public float PeekNextValue() - { return _pattern[_index]; } + { return Pattern[_index]; } + + public void Reset() + { _index = 0; } } } diff --git a/BizHawk.Client.Common/inputAdapters/InputAdapters.cs b/BizHawk.Client.Common/inputAdapters/InputAdapters.cs index 72e287fb27..9d616c7ffc 100644 --- a/BizHawk.Client.Common/inputAdapters/InputAdapters.cs +++ b/BizHawk.Client.Common/inputAdapters/InputAdapters.cs @@ -383,7 +383,7 @@ namespace BizHawk.Client.Common private List _justPressed = new List(); } - /// SuuperW: I'm leaving the old class in case I accidentally screwed something up. + /// SuuperW: Old code commented //public class AutoFireStickyXorAdapter : IController, ISticky //{ // public int On { get; set; } @@ -536,6 +536,8 @@ namespace BizHawk.Client.Common //} public class AutoFireStickyXorAdapter : IController, ISticky { + // TODO: Change the AutoHold adapter to be one of these, with an 'Off' value of 0? + // Probably would have slightly lower performance, but it seems weird to have such a similar class that is only used once. private int On; private int Off; public void SetOnOffPatternFromConfig() @@ -583,7 +585,7 @@ namespace BizHawk.Client.Common public float GetFloat(string name) { if (_floatPatterns.ContainsKey(name)) - return _floatPatterns[name].GetNextValue(); + return _floatPatterns[name].PeekNextValue(); if (Source == null) return 0; @@ -603,8 +605,11 @@ namespace BizHawk.Client.Common var source = Source[button]; bool patternValue = false; if (_boolPatterns.ContainsKey(button)) - patternValue = _boolPatterns[button].GetNextValue(); + { // I can't figure a way to determine right here if it should Peek or Get. + patternValue = _boolPatterns[button].PeekNextValue(); + } source ^= patternValue; + return source; } } @@ -662,6 +667,14 @@ namespace BizHawk.Client.Common _floatPatterns.Clear(); } + public void IncrementLoops(bool lagged) + { + for (int i = 0; i < _boolPatterns.Count; i++) + _boolPatterns.ElementAt(i).Value.GetNextValue(lagged); + for (int i = 0; i < _floatPatterns.Count; i++) + _floatPatterns.ElementAt(i).Value.GetNextValue(lagged); + } + // SuuperW: What does this even do? I set a breakpoint inside the loop and it wasn't reached. private WorkingDictionary _toggledButtons = new WorkingDictionary(); private List _justPressed = new List(); diff --git a/BizHawk.Client.Common/movie/bk2/Bk2ControllerAdapter.cs b/BizHawk.Client.Common/movie/bk2/Bk2ControllerAdapter.cs index fbe23463a5..72cc269909 100644 --- a/BizHawk.Client.Common/movie/bk2/Bk2ControllerAdapter.cs +++ b/BizHawk.Client.Common/movie/bk2/Bk2ControllerAdapter.cs @@ -133,7 +133,7 @@ namespace BizHawk.Client.Common { foreach (var button in Type.BoolButtons) { - MyBoolButtons[button] = source[button]; + MyBoolButtons[button] = source.IsPressed(button); } foreach (var name in Type.FloatControls) diff --git a/BizHawk.Client.Common/movie/tasproj/TasMovie.Editing.cs b/BizHawk.Client.Common/movie/tasproj/TasMovie.Editing.cs index 11a7ad3a2b..a507c33e73 100644 --- a/BizHawk.Client.Common/movie/tasproj/TasMovie.Editing.cs +++ b/BizHawk.Client.Common/movie/tasproj/TasMovie.Editing.cs @@ -318,6 +318,9 @@ namespace BizHawk.Client.Common ChangeLog.SetGeneralRedo(); if (endBatch) ChangeLog.EndBatch(); + + if (Global.Emulator.Frame < _log.Count) // Don't stay in recording mode? Fixes TAStudio recording after paint inserting. + this.SwitchToPlay(); } public void ToggleBoolState(int frame, string buttonName) { diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj index 751a428a5f..40ea65e64f 100644 --- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj +++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj @@ -927,6 +927,12 @@ Component + + Form + + + PatternsForm.cs + TAStudio.cs Form @@ -1381,6 +1387,9 @@ MarkerControl.cs + + PatternsForm.cs + PlaybackBox.cs diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index 6e7600a123..8e46666f2a 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -2814,6 +2814,7 @@ namespace BizHawk.Client.EmuHawk { Global.AutoFireController.IncrementStarts(); } + Global.AutofireStickyXORAdapter.IncrementLoops(IsLagFrame); PressFrameAdvance = false; diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/PatternsForm.Designer.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/PatternsForm.Designer.cs new file mode 100644 index 0000000000..fe80b39e8a --- /dev/null +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/PatternsForm.Designer.cs @@ -0,0 +1,196 @@ +namespace BizHawk.Client.EmuHawk +{ + partial class PatternsForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.ButtonBox = new System.Windows.Forms.ComboBox(); + this.PatternList = new System.Windows.Forms.ListBox(); + this.InsertButton = new System.Windows.Forms.Button(); + this.DeleteButton = new System.Windows.Forms.Button(); + this.LagBox = new System.Windows.Forms.CheckBox(); + this.label1 = new System.Windows.Forms.Label(); + this.ValueNum = new System.Windows.Forms.NumericUpDown(); + this.CountNum = new System.Windows.Forms.NumericUpDown(); + this.label2 = new System.Windows.Forms.Label(); + this.OnOffBox = new System.Windows.Forms.CheckBox(); + ((System.ComponentModel.ISupportInitialize)(this.ValueNum)).BeginInit(); + ((System.ComponentModel.ISupportInitialize)(this.CountNum)).BeginInit(); + this.SuspendLayout(); + // + // ButtonBox + // + this.ButtonBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.ButtonBox.FormattingEnabled = true; + this.ButtonBox.Location = new System.Drawing.Point(12, 12); + this.ButtonBox.Name = "ButtonBox"; + this.ButtonBox.Size = new System.Drawing.Size(169, 21); + this.ButtonBox.TabIndex = 0; + this.ButtonBox.SelectedIndexChanged += new System.EventHandler(this.ButtonBox_SelectedIndexChanged); + // + // PatternList + // + this.PatternList.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left))); + this.PatternList.FormattingEnabled = true; + this.PatternList.Items.AddRange(new object[] { + "0: On\t(x1)", + "1: Off\t(x1)", + "Loop to 0"}); + this.PatternList.Location = new System.Drawing.Point(12, 39); + this.PatternList.Name = "PatternList"; + this.PatternList.Size = new System.Drawing.Size(169, 134); + this.PatternList.TabIndex = 1; + this.PatternList.SelectedIndexChanged += new System.EventHandler(this.PatternList_SelectedIndexChanged); + // + // InsertButton + // + this.InsertButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.InsertButton.Location = new System.Drawing.Point(12, 207); + this.InsertButton.Name = "InsertButton"; + this.InsertButton.Size = new System.Drawing.Size(57, 23); + this.InsertButton.TabIndex = 2; + this.InsertButton.Text = "Insert"; + this.InsertButton.UseVisualStyleBackColor = true; + this.InsertButton.Click += new System.EventHandler(this.InsertButton_Click); + // + // DeleteButton + // + this.DeleteButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.DeleteButton.Location = new System.Drawing.Point(124, 207); + this.DeleteButton.Name = "DeleteButton"; + this.DeleteButton.Size = new System.Drawing.Size(57, 23); + this.DeleteButton.TabIndex = 2; + this.DeleteButton.Text = "Delete"; + this.DeleteButton.UseVisualStyleBackColor = true; + this.DeleteButton.Click += new System.EventHandler(this.DeleteButton_Click); + // + // LagBox + // + this.LagBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.LagBox.AutoSize = true; + this.LagBox.Checked = true; + this.LagBox.CheckState = System.Windows.Forms.CheckState.Checked; + this.LagBox.Location = new System.Drawing.Point(12, 236); + this.LagBox.Name = "LagBox"; + this.LagBox.Size = new System.Drawing.Size(132, 17); + this.LagBox.TabIndex = 3; + this.LagBox.Text = "Account for lag frames"; + this.LagBox.UseVisualStyleBackColor = true; + this.LagBox.CheckedChanged += new System.EventHandler(this.LagBox_CheckedChanged); + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(9, 181); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(37, 13); + this.label1.TabIndex = 4; + this.label1.Text = "Value:"; + // + // ValueNum + // + this.ValueNum.Location = new System.Drawing.Point(48, 179); + this.ValueNum.Name = "ValueNum"; + this.ValueNum.Size = new System.Drawing.Size(51, 20); + this.ValueNum.TabIndex = 5; + this.ValueNum.Visible = false; + this.ValueNum.ValueChanged += new System.EventHandler(this.ValueNum_ValueChanged); + // + // CountNum + // + this.CountNum.Location = new System.Drawing.Point(143, 179); + this.CountNum.Name = "CountNum"; + this.CountNum.Size = new System.Drawing.Size(38, 20); + this.CountNum.TabIndex = 5; + this.CountNum.Value = new decimal(new int[] { + 1, + 0, + 0, + 0}); + this.CountNum.ValueChanged += new System.EventHandler(this.CountNum_ValueChanged); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(103, 181); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(38, 13); + this.label2.TabIndex = 4; + this.label2.Text = "Count:"; + // + // OnOffBox + // + this.OnOffBox.AutoSize = true; + this.OnOffBox.Location = new System.Drawing.Point(48, 180); + this.OnOffBox.Name = "OnOffBox"; + this.OnOffBox.Size = new System.Drawing.Size(15, 14); + this.OnOffBox.TabIndex = 6; + this.OnOffBox.UseVisualStyleBackColor = true; + this.OnOffBox.CheckedChanged += new System.EventHandler(this.OnOffBox_CheckedChanged); + // + // PatternsForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.ClientSize = new System.Drawing.Size(193, 258); + this.Controls.Add(this.OnOffBox); + this.Controls.Add(this.CountNum); + this.Controls.Add(this.ValueNum); + this.Controls.Add(this.label2); + this.Controls.Add(this.label1); + this.Controls.Add(this.LagBox); + this.Controls.Add(this.DeleteButton); + this.Controls.Add(this.InsertButton); + this.Controls.Add(this.PatternList); + this.Controls.Add(this.ButtonBox); + this.MaximumSize = new System.Drawing.Size(209, 9999); + this.MinimumSize = new System.Drawing.Size(209, 34); + this.Name = "PatternsForm"; + this.Text = "Patterns Options"; + this.Load += new System.EventHandler(this.PatternsForm_Load); + ((System.ComponentModel.ISupportInitialize)(this.ValueNum)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.CountNum)).EndInit(); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.ComboBox ButtonBox; + private System.Windows.Forms.ListBox PatternList; + private System.Windows.Forms.Button InsertButton; + private System.Windows.Forms.Button DeleteButton; + private System.Windows.Forms.CheckBox LagBox; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.NumericUpDown ValueNum; + private System.Windows.Forms.NumericUpDown CountNum; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.CheckBox OnOffBox; + } +} \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/PatternsForm.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/PatternsForm.cs new file mode 100644 index 0000000000..3dce9909ec --- /dev/null +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/PatternsForm.cs @@ -0,0 +1,270 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Windows.Forms; + +using BizHawk.Client.Common; + +namespace BizHawk.Client.EmuHawk +{ + public partial class PatternsForm : Form + { + private TAStudio tastudio; + + public PatternsForm(TAStudio owner) + { + InitializeComponent(); + tastudio = owner; + + foreach (var button in Global.MovieSession.MovieControllerAdapter.Type.BoolButtons) + ButtonBox.Items.Add(button); + foreach (var button in Global.MovieSession.MovieControllerAdapter.Type.FloatControls) + ButtonBox.Items.Add(button); + ButtonBox.Items.Add("Default bool Auto-Fire"); + ButtonBox.Items.Add("Default float Auto-Fire"); + } + + private void PatternsForm_Load(object sender, EventArgs e) + { + ButtonBox.SelectedIndex = 0; + } + + List counts = new List(); + List values = new List(); + int loopAt; + string selectedButton { get { return ButtonBox.Text; } } + bool isBool { get { return selectedButton == "Default bool Auto-Fire" || Global.MovieSession.MovieControllerAdapter.Type.BoolButtons.Contains(selectedButton); } } + + private void ButtonBox_SelectedIndexChanged(object sender, EventArgs e) + { + GetPattern(); + UpdateDisplay(); + + if (isBool) + { + OnOffBox.Visible = true; + ValueNum.Visible = false; + } + else + { + ValueNum.Visible = true; + OnOffBox.Visible = false; + } + CountNum.Value = counts[0]; + } + + private void PatternList_SelectedIndexChanged(object sender, EventArgs e) + { + if (!_updating) + UpdateDisplay(); + } + + private void InsertButton_Click(object sender, EventArgs e) + { + counts.Insert(PatternList.SelectedIndex, 1); + string defaultStr = "false"; + if (!isBool) + defaultStr = "0"; + values.Insert(PatternList.SelectedIndex, defaultStr); + + UpdatePattern(); + UpdateDisplay(); + } + + private void DeleteButton_Click(object sender, EventArgs e) + { + counts.RemoveAt(PatternList.SelectedIndex); + values.RemoveAt(PatternList.SelectedIndex); + UpdatePattern(); + UpdateDisplay(); + } + + private void LagBox_CheckedChanged(object sender, EventArgs e) + { + UpdatePattern(); + } + + private void ValueNum_ValueChanged(object sender, EventArgs e) + { + if (_updating || PatternList.SelectedIndex == -1 || PatternList.SelectedIndex >= counts.Count) + return; + + values[PatternList.SelectedIndex] = ValueNum.Value.ToString(); + UpdatePattern(); + UpdateDisplay(); + } + private void OnOffBox_CheckedChanged(object sender, EventArgs e) + { + if (_updating || PatternList.SelectedIndex == -1 || PatternList.SelectedIndex >= counts.Count) + return; + + values[PatternList.SelectedIndex] = OnOffBox.Checked.ToString(); + UpdatePattern(); + UpdateDisplay(); + } + private void CountNum_ValueChanged(object sender, EventArgs e) + { + if (_updating || PatternList.SelectedIndex == -1 || PatternList.SelectedIndex > counts.Count) + return; + + if (PatternList.SelectedIndex == counts.Count) + loopAt = (int)CountNum.Value; + else + counts[PatternList.SelectedIndex] = (int)CountNum.Value; + UpdatePattern(); + UpdateDisplay(); + } + + private bool _updating = false; + private void UpdateDisplay() + { + _updating = true; + PatternList.SuspendLayout(); + + int oldIndex = PatternList.SelectedIndex; + if (oldIndex == -1) + oldIndex = 0; + + PatternList.Items.Clear(); + int index = 0; + for (int i = 0; i < counts.Count; i++) + { + string str = index.ToString() + ": "; + if (isBool) + str += values[i][0] == 'T' ? "On" : "Off"; + else + str += values[i].ToString(); + + PatternList.Items.Add(str + ("\t(x" + counts[i] + ")")); + index += counts[i]; + } + PatternList.Items.Add("Loop to: " + loopAt); + + if (oldIndex >= PatternList.Items.Count) + oldIndex = PatternList.Items.Count - 1; + PatternList.SelectedIndex = oldIndex; + + if (PatternList.SelectedIndex != -1 && PatternList.SelectedIndex < values.Count) + { + index = Global.MovieSession.MovieControllerAdapter.Type.BoolButtons.IndexOf(selectedButton); + if (selectedButton == "Default bool Auto-Fire") + index = tastudio.BoolPatterns.Length + 1; + if (index != -1) + { + LagBox.Checked = tastudio.BoolPatterns[index].SkipsLag; + OnOffBox.Checked = values[PatternList.SelectedIndex][0] == 'T'; + CountNum.Value = (decimal)counts[PatternList.SelectedIndex]; + } + else + { + if (selectedButton == "Default float Auto-Fire") + index = tastudio.FloatPatterns.Length + 1; + else + index = Global.MovieSession.MovieControllerAdapter.Type.FloatControls.IndexOf(selectedButton); + + LagBox.Checked = tastudio.FloatPatterns[index].SkipsLag; + ValueNum.Value = Convert.ToDecimal(values[PatternList.SelectedIndex]); + CountNum.Value = (decimal)counts[PatternList.SelectedIndex]; + } + } + else if (PatternList.SelectedIndex == values.Count) + CountNum.Value = (decimal)loopAt; + + PatternList.ResumeLayout(); + _updating = false; + } + + private void UpdatePattern() + { + int index = Global.MovieSession.MovieControllerAdapter.Type.BoolButtons.IndexOf(selectedButton); + if (selectedButton == "Default bool Auto-Fire") + index = tastudio.BoolPatterns.Length + 1; + if (index != -1) + { + List p = new List(); + for (int i = 0; i < counts.Count; i++) + { + for (int c = 0; c < counts[i]; c++) + p.Add(Convert.ToBoolean(values[i])); + } + tastudio.BoolPatterns[index] = new AutoPatternBool(p.ToArray(), LagBox.Checked, 0, loopAt); + } + else + { + if (selectedButton == "Default float Auto-Fire") + index = tastudio.FloatPatterns.Length + 1; + else + index = Global.MovieSession.MovieControllerAdapter.Type.FloatControls.IndexOf(selectedButton); + List p = new List(); + for (int i = 0; i < counts.Count; i++) + { + for (int c = 0; c < counts[i]; c++) + p.Add(Convert.ToSingle(values[i])); + } + tastudio.FloatPatterns[index] = new AutoPatternFloat(p.ToArray(), LagBox.Checked, 0, loopAt); + } + + tastudio.UpdateAutoFire(selectedButton, null); + } + + private void GetPattern() + { + int index = Global.MovieSession.MovieControllerAdapter.Type.BoolButtons.IndexOf(selectedButton); + if (selectedButton == "Default bool Auto-Fire") + index = tastudio.BoolPatterns.Length + 1; + if (index != -1) + { + bool[] p = tastudio.BoolPatterns[index].Pattern; + bool lastValue = p[0]; + counts.Clear(); + values.Clear(); + counts.Add(1); + values.Add(lastValue.ToString()); + for (int i = 1; i < p.Length; i++) + { + if (p[i] == lastValue) + counts[counts.Count - 1]++; + else + { + counts.Add(1); + values.Add(p[i].ToString()); + lastValue = p[i]; + } + } + loopAt = tastudio.BoolPatterns[index].Loop; + } + else + { + if (selectedButton == "Default float Auto-Fire") + index = tastudio.FloatPatterns.Length + 1; + else + index = Global.MovieSession.MovieControllerAdapter.Type.FloatControls.IndexOf(selectedButton); + float[] p = tastudio.FloatPatterns[index].Pattern; + float lastValue = p[0]; + counts.Clear(); + values.Clear(); + counts.Add(1); + values.Add(lastValue.ToString()); + for (int i = 1; i < p.Length; i++) + { + if (p[i] == lastValue) + counts[counts.Count - 1]++; + else + { + counts.Add(1); + values.Add(p[i].ToString()); + lastValue = p[i]; + } + } + loopAt = tastudio.FloatPatterns[index].Loop; + } + } + + + + } +} diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/PatternsForm.resx b/BizHawk.Client.EmuHawk/tools/TAStudio/PatternsForm.resx new file mode 100644 index 0000000000..29dcb1b3a3 --- /dev/null +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/PatternsForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Designer.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Designer.cs index 1f870731cd..fd40f068ec 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Designer.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.Designer.cs @@ -60,13 +60,13 @@ namespace BizHawk.Client.EmuHawk this.PasteMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.PasteInsertMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.CutMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator8 = new System.Windows.Forms.ToolStripSeparator(); this.ClearMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.DeleteFramesMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.CloneMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.InsertFrameMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.InsertNumFramesMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator(); - this.toolStripSeparator8 = new System.Windows.Forms.ToolStripSeparator(); this.TruncateMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.ClearGreenzoneMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.GreenzoneICheckSeparator = new System.Windows.Forms.ToolStripSeparator(); @@ -87,6 +87,15 @@ namespace BizHawk.Client.EmuHawk this.OsdInBranchScreenshotsMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.toolStripSeparator14 = new System.Windows.Forms.ToolStripSeparator(); this.AutopauseAtEndOfMovieMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.sepToolStripMenuItem = new System.Windows.Forms.ToolStripSeparator(); + this.autoHoldFireToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.keepSetPatternsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.sepToolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator(); + this.autoHoldToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.autoFireToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.customPatternToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.setpToolStripMenuItem = new System.Windows.Forms.ToolStripSeparator(); + this.setCustomsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.MetaSubMenu = new System.Windows.Forms.ToolStripMenuItem(); this.HeaderMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.StateHistorySettingsMenuItem = new System.Windows.Forms.ToolStripMenuItem(); @@ -276,13 +285,13 @@ namespace BizHawk.Client.EmuHawk this.PasteMenuItem, this.PasteInsertMenuItem, this.CutMenuItem, + this.toolStripSeparator8, this.ClearMenuItem, this.DeleteFramesMenuItem, this.CloneMenuItem, this.InsertFrameMenuItem, this.InsertNumFramesMenuItem, this.toolStripSeparator6, - this.toolStripSeparator8, this.TruncateMenuItem, this.ClearGreenzoneMenuItem, this.GreenzoneICheckSeparator, @@ -408,6 +417,11 @@ namespace BizHawk.Client.EmuHawk this.CutMenuItem.Text = "&Cut"; this.CutMenuItem.Click += new System.EventHandler(this.CutMenuItem_Click); // + // toolStripSeparator8 + // + this.toolStripSeparator8.Name = "toolStripSeparator8"; + this.toolStripSeparator8.Size = new System.Drawing.Size(279, 6); + // // ClearMenuItem // this.ClearMenuItem.Name = "ClearMenuItem"; @@ -456,11 +470,6 @@ namespace BizHawk.Client.EmuHawk this.toolStripSeparator6.Name = "toolStripSeparator6"; this.toolStripSeparator6.Size = new System.Drawing.Size(279, 6); // - // toolStripSeparator8 - // - this.toolStripSeparator8.Name = "toolStripSeparator8"; - this.toolStripSeparator8.Size = new System.Drawing.Size(279, 6); - // // TruncateMenuItem // this.TruncateMenuItem.Name = "TruncateMenuItem"; @@ -506,7 +515,9 @@ namespace BizHawk.Client.EmuHawk this.BranchesRestoreEntireMovieMenuItem, this.OsdInBranchScreenshotsMenuItem, this.toolStripSeparator14, - this.AutopauseAtEndOfMovieMenuItem}); + this.AutopauseAtEndOfMovieMenuItem, + this.sepToolStripMenuItem, + this.autoHoldFireToolStripMenuItem}); this.ConfigSubMenu.Name = "ConfigSubMenu"; this.ConfigSubMenu.Size = new System.Drawing.Size(55, 20); this.ConfigSubMenu.Text = "&Config"; @@ -610,6 +621,75 @@ namespace BizHawk.Client.EmuHawk this.AutopauseAtEndOfMovieMenuItem.Text = "Autopause at end of Movie"; this.AutopauseAtEndOfMovieMenuItem.Click += new System.EventHandler(this.AutopauseAtEndMenuItem_Click); // + // sepToolStripMenuItem + // + this.sepToolStripMenuItem.Name = "sepToolStripMenuItem"; + this.sepToolStripMenuItem.Size = new System.Drawing.Size(285, 6); + // + // autoHoldFireToolStripMenuItem + // + this.autoHoldFireToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.keepSetPatternsToolStripMenuItem, + this.sepToolStripMenuItem1, + this.autoHoldToolStripMenuItem, + this.autoFireToolStripMenuItem, + this.customPatternToolStripMenuItem, + this.setpToolStripMenuItem, + this.setCustomsToolStripMenuItem}); + this.autoHoldFireToolStripMenuItem.Name = "autoHoldFireToolStripMenuItem"; + this.autoHoldFireToolStripMenuItem.Size = new System.Drawing.Size(288, 22); + this.autoHoldFireToolStripMenuItem.Text = "Auto Hold/Fire"; + // + // keepSetPatternsToolStripMenuItem + // + this.keepSetPatternsToolStripMenuItem.CheckOnClick = true; + this.keepSetPatternsToolStripMenuItem.Name = "keepSetPatternsToolStripMenuItem"; + this.keepSetPatternsToolStripMenuItem.Size = new System.Drawing.Size(164, 22); + this.keepSetPatternsToolStripMenuItem.Text = "Keep set patterns"; + // + // sepToolStripMenuItem1 + // + this.sepToolStripMenuItem1.Name = "sepToolStripMenuItem1"; + this.sepToolStripMenuItem1.Size = new System.Drawing.Size(161, 6); + // + // autoHoldToolStripMenuItem + // + this.autoHoldToolStripMenuItem.Checked = true; + this.autoHoldToolStripMenuItem.CheckOnClick = true; + this.autoHoldToolStripMenuItem.CheckState = System.Windows.Forms.CheckState.Checked; + this.autoHoldToolStripMenuItem.Name = "autoHoldToolStripMenuItem"; + this.autoHoldToolStripMenuItem.Size = new System.Drawing.Size(164, 22); + this.autoHoldToolStripMenuItem.Text = "Auto-Hold"; + this.autoHoldToolStripMenuItem.CheckedChanged += new System.EventHandler(this.autoHoldToolStripMenuItem_CheckedChanged); + // + // autoFireToolStripMenuItem + // + this.autoFireToolStripMenuItem.CheckOnClick = true; + this.autoFireToolStripMenuItem.Name = "autoFireToolStripMenuItem"; + this.autoFireToolStripMenuItem.Size = new System.Drawing.Size(164, 22); + this.autoFireToolStripMenuItem.Text = "Auto-Fire"; + this.autoFireToolStripMenuItem.CheckedChanged += new System.EventHandler(this.autoFireToolStripMenuItem_CheckedChanged); + // + // customPatternToolStripMenuItem + // + this.customPatternToolStripMenuItem.CheckOnClick = true; + this.customPatternToolStripMenuItem.Name = "customPatternToolStripMenuItem"; + this.customPatternToolStripMenuItem.Size = new System.Drawing.Size(164, 22); + this.customPatternToolStripMenuItem.Text = "Custom Pattern"; + this.customPatternToolStripMenuItem.CheckedChanged += new System.EventHandler(this.customPatternToolStripMenuItem_CheckedChanged); + // + // setpToolStripMenuItem + // + this.setpToolStripMenuItem.Name = "setpToolStripMenuItem"; + this.setpToolStripMenuItem.Size = new System.Drawing.Size(161, 6); + // + // setCustomsToolStripMenuItem + // + this.setCustomsToolStripMenuItem.Name = "setCustomsToolStripMenuItem"; + this.setCustomsToolStripMenuItem.Size = new System.Drawing.Size(164, 22); + this.setCustomsToolStripMenuItem.Text = "Set Customs..."; + this.setCustomsToolStripMenuItem.Click += new System.EventHandler(this.setCustomsToolStripMenuItem_Click); + // // MetaSubMenu // this.MetaSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -1245,5 +1325,14 @@ namespace BizHawk.Client.EmuHawk private System.Windows.Forms.ToolStripMenuItem pasteInsertToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem cutToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem showUndoHistoryToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator sepToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem autoHoldFireToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem keepSetPatternsToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator sepToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem autoHoldToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem autoFireToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem customPatternToolStripMenuItem; + private System.Windows.Forms.ToolStripSeparator setpToolStripMenuItem; + private System.Windows.Forms.ToolStripMenuItem setCustomsToolStripMenuItem; } } \ No newline at end of file diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs index d419398c3c..b4bde4169c 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.ListView.cs @@ -57,6 +57,12 @@ namespace BizHawk.Client.EmuHawk public static Color Marker_FrameCol = Color.FromArgb(0xF7FFC9); public static Color AnalogEdit_Col = Color.FromArgb(0x909070); // SuuperW: When editing an analog value, it will be a gray color. + private Emulation.Common.ControllerDefinition controllerType + { get { return Global.MovieSession.MovieControllerAdapter.Type; } } + + public AutoPatternBool[] BoolPatterns; + public AutoPatternFloat[] FloatPatterns; + #region Query callbacks private void TasView_QueryItemIcon(int index, InputRoll.RollColumn column, ref Bitmap bitmap) @@ -245,10 +251,44 @@ namespace BizHawk.Client.EmuHawk { e.Column.Emphasis ^= true; - Global.StickyXORAdapter.SetSticky(e.Column.Name, e.Column.Emphasis); + UpdateAutoFire(e.Column.Name, e.Column.Emphasis); RefreshTasView(); } + private void UpdateAutoFire() + { + for (int i = 2; i < TasView.AllColumns.Count; i++) + UpdateAutoFire(TasView.AllColumns[i].Name, TasView.AllColumns[i].Emphasis); + } + public void UpdateAutoFire(string button, bool? isOn) + { + if (!isOn.HasValue) // No value means don't change whether it's on or off. + isOn = TasView.AllColumns.Find(c => c.Name == button).Emphasis; + + int index = 0; + if (autoHoldToolStripMenuItem.Checked) index = 1; + if (autoFireToolStripMenuItem.Checked) index = 2; + if (controllerType.BoolButtons.Contains(button)) + { + if (index == 0) + index = controllerType.BoolButtons.IndexOf(button); + else + index += controllerType.BoolButtons.Count - 1; + AutoPatternBool p = BoolPatterns[index]; + Global.AutofireStickyXORAdapter.SetSticky(button, isOn.Value, p); + } + else + { + if (index == 0) + index = controllerType.FloatControls.IndexOf(button); + else + index += controllerType.FloatControls.Count - 1; + float? value = null; + if (isOn.Value) value = 0f; + AutoPatternFloat p = FloatPatterns[index]; + Global.AutofireStickyXORAdapter.SetFloat(button, value, p); + } + } private void TasView_ColumnReordered(object sender, InputRoll.ColumnReorderedEventArgs e) { diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs index 55eba0fbfc..6b0e8bda92 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.MenuItems.cs @@ -161,6 +161,7 @@ namespace BizHawk.Client.EmuHawk private void showUndoHistoryToolStripMenuItem_Click(object sender, EventArgs e) { undoForm = new UndoHistoryForm(this); + undoForm.Owner = this; undoForm.Show(); undoForm.UpdateValues(); } @@ -628,6 +629,48 @@ namespace BizHawk.Client.EmuHawk Settings.AutoPause ^= true; } + private void autoHoldToolStripMenuItem_CheckedChanged(object sender, EventArgs e) + { + if (autoHoldToolStripMenuItem.Checked) + { + autoFireToolStripMenuItem.Checked = false; + customPatternToolStripMenuItem.Checked = false; + + if (!keepSetPatternsToolStripMenuItem.Checked) + UpdateAutoFire(); + } + } + private void autoFireToolStripMenuItem_CheckedChanged(object sender, EventArgs e) + { + if (autoFireToolStripMenuItem.Checked) + { + autoHoldToolStripMenuItem.Checked = false; + customPatternToolStripMenuItem.Checked = false; + + if (!keepSetPatternsToolStripMenuItem.Checked) + UpdateAutoFire(); + } + } + private void customPatternToolStripMenuItem_CheckedChanged(object sender, EventArgs e) + { + if (customPatternToolStripMenuItem.Checked) + { + autoHoldToolStripMenuItem.Checked = false; + autoFireToolStripMenuItem.Checked = false; + + if (!keepSetPatternsToolStripMenuItem.Checked) + UpdateAutoFire(); + } + } + private void setCustomsToolStripMenuItem_Click(object sender, EventArgs e) + { + // Exceptions in PatternsForm are not caught by the debugger, I have no idea why. + // Exceptions in UndoForm are caught, which makes it weirder. + PatternsForm pForm = new PatternsForm(this); + pForm.Owner = this; + pForm.Show(); + } + #endregion #region Metadata diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs index d2e3f2e6fa..4b9b6f9b4c 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs @@ -349,6 +349,33 @@ namespace BizHawk.Client.EmuHawk AddColumn(kvp.Key, kvp.Value, 20 * kvp.Value.Length); } + + int bStart = 0; + int fStart = 0; + if (BoolPatterns == null) + { + BoolPatterns = new AutoPatternBool[controllerType.BoolButtons.Count + 2]; + FloatPatterns = new AutoPatternFloat[controllerType.FloatControls.Count + 2]; + } + else + { + bStart = BoolPatterns.Length - 2; + fStart = FloatPatterns.Length - 2; + Array.Resize(ref BoolPatterns, controllerType.BoolButtons.Count + 2); + Array.Resize(ref FloatPatterns, controllerType.FloatControls.Count + 2); + } + + for (int i = bStart; i < BoolPatterns.Length - 2; i++) + BoolPatterns[i] = new AutoPatternBool(1, 1); + BoolPatterns[BoolPatterns.Length - 2] = new AutoPatternBool(1, 0); + BoolPatterns[BoolPatterns.Length - 1] = new AutoPatternBool( + Global.Config.AutofireOn, Global.Config.AutofireOff); + + for (int i = fStart; i < FloatPatterns.Length - 2; i++) + FloatPatterns[i] = new AutoPatternFloat(new float[] { 1f }); + FloatPatterns[FloatPatterns.Length - 2] = new AutoPatternFloat(new float[] { 1f }); + FloatPatterns[FloatPatterns.Length - 1] = new AutoPatternFloat( + 1f, Global.Config.AutofireOn, 0f, Global.Config.AutofireOff); } public void AddColumn(string columnName, string columnText, int columnWidth) @@ -744,7 +771,6 @@ namespace BizHawk.Client.EmuHawk MarkerControl.RemoveMarker(); } - // TODO: Move AddMarkerChange calls to TasMovieMarker.cs public void AddMarker(int markerFrame, string message) { TasMovieMarker marker = new TasMovieMarker(markerFrame, message); diff --git a/BizHawk.Client.EmuHawk/tools/TAStudio/UndoHistoryForm.Designer.cs b/BizHawk.Client.EmuHawk/tools/TAStudio/UndoHistoryForm.Designer.cs index 2d89b9d493..f4290b4d00 100644 --- a/BizHawk.Client.EmuHawk/tools/TAStudio/UndoHistoryForm.Designer.cs +++ b/BizHawk.Client.EmuHawk/tools/TAStudio/UndoHistoryForm.Designer.cs @@ -211,7 +211,7 @@ this.Controls.Add(this.UndoButton); this.Controls.Add(this.HistoryView); this.Name = "UndoHistoryForm"; - this.Text = "UndoHistoryForm"; + this.Text = "Undo History"; this.RightClickMenu.ResumeLayout(false); ((System.ComponentModel.ISupportInitialize)(this.MaxStepsNum)).EndInit(); this.ResumeLayout(false);