Skip to content

Commit 34abdc9

Browse files
committed
make savestates on markers optional, per marker
1 parent 7213734 commit 34abdc9

10 files changed

Lines changed: 116 additions & 34 deletions

File tree

src/BizHawk.Client.Common/movie/tasproj/TasBranch.cs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -252,17 +252,7 @@ public void Load(ZipStateLoader bl, ITasMovie movie)
252252
});
253253

254254
b.Markers = new TasMovieMarkerList(movie);
255-
bl.GetLump(nmarkers, abort: false, tr =>
256-
{
257-
string line;
258-
while ((line = tr.ReadLine()) != null)
259-
{
260-
if (!string.IsNullOrWhiteSpace(line))
261-
{
262-
b.Markers.Add(new TasMovieMarker(line));
263-
}
264-
}
265-
});
255+
bl.GetLump(nmarkers, abort: false, b.Markers.LoadFromFile);
266256

267257
bl.GetLump(nusertext, abort: false, tr =>
268258
{

src/BizHawk.Client.Common/movie/tasproj/TasMovie.IO.cs

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,7 @@ private void LoadTasprojExtras(ZipStateLoader bl)
8484
{
8585
bl.GetLump(BinaryStateLump.LagLog, abort: false, tr => LagLog.Load(tr));
8686

87-
bl.GetLump(BinaryStateLump.Markers, abort: false, tr =>
88-
{
89-
string line;
90-
while ((line = tr.ReadLine()) != null)
91-
{
92-
if (!string.IsNullOrWhiteSpace(line))
93-
{
94-
Markers.Add(new TasMovieMarker(line));
95-
}
96-
}
97-
});
87+
bl.GetLump(BinaryStateLump.Markers, abort: false, Markers.LoadFromFile);
9888

9989
bl.GetLump(BinaryStateLump.ClientSettings, abort: false, tr =>
10090
{

src/BizHawk.Client.Common/movie/tasproj/TasMovie.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ public bool IsReserved(int frame)
326326
// Why the frame before?
327327
// because we always navigate to the frame before and emulate 1 frame so that we ensure a proper frame buffer on the screen
328328
// users want instant navigation to markers, so to do this, we need to reserve the frame before the marker, not the marker itself
329-
return Markers.Exists(m => m.Frame - 1 == frame)
329+
return Markers.Exists(m => m.WantsState && m.Frame - 1 == frame)
330330
|| Branches.Any(b => b.Frame == frame); // Branches should already be in the reserved list, but it doesn't hurt to check
331331
}
332332

src/BizHawk.Client.Common/movie/tasproj/TasMovieMarker.cs

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Collections.Generic;
22
using System.Collections.Specialized;
33
using System.Diagnostics;
4+
using System.IO;
45
using System.Linq;
56
using System.Text;
67
using BizHawk.Common.CollectionExtensions;
@@ -22,18 +23,32 @@ public TasMovieMarker(int frame, string message = "")
2223
/// <summary>
2324
/// Initializes a new instance of the <see cref="TasMovieMarker"/> class from a line of text
2425
/// </summary>
25-
public TasMovieMarker(string line)
26+
public TasMovieMarker(string line, int version)
2627
{
2728
var split = line.Split('\t');
2829
Frame = int.Parse(split[0]);
29-
Message = split[1];
30+
if (version == 1)
31+
{
32+
Message = split[1];
33+
}
34+
else if (version == 2)
35+
{
36+
WantsState = bool.Parse(split[1]);
37+
Message = split[2];
38+
}
39+
else
40+
{
41+
throw new Exception("Invalid version.");
42+
}
3043
}
3144

3245
public int Frame { get; private set; }
3346

3447
public string Message { get; set; }
3548

36-
public override string ToString() => Frame.ToString() + '\t' + Message;
49+
public bool WantsState { get; set; } = true;
50+
51+
public override string ToString() => $"{Frame}\t{WantsState}\t{Message}";
3752

3853
public override int GetHashCode() => Frame.GetHashCode();
3954

@@ -111,6 +126,7 @@ private void OnListChanged(NotifyCollectionChangedAction action)
111126
public override string ToString()
112127
{
113128
var sb = new StringBuilder();
129+
sb.AppendLine("2"); // version
114130
foreach (var marker in this)
115131
{
116132
sb.AppendLine(marker.ToString());
@@ -119,6 +135,30 @@ public override string ToString()
119135
return sb.ToString();
120136
}
121137

138+
public void LoadFromFile(TextReader tr)
139+
{
140+
string line;
141+
int version = -1;
142+
while ((line = tr.ReadLine()) != null)
143+
{
144+
if (string.IsNullOrWhiteSpace(line)) continue;
145+
if (version == -1)
146+
{
147+
if (line.Contains('\t'))
148+
{
149+
version = 1;
150+
}
151+
else
152+
{
153+
version = int.Parse(line);
154+
line = tr.ReadLine();
155+
if (line == null) break;
156+
}
157+
}
158+
Add(new TasMovieMarker(line, version));
159+
}
160+
}
161+
122162
// the inherited one
123163
public new void Add(TasMovieMarker item)
124164
{

src/BizHawk.Client.EmuHawk/tools/TAStudio/MarkerControl.Designer.cs

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/BizHawk.Client.EmuHawk/tools/TAStudio/MarkerControl.cs

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1-
using System.ComponentModel;
1+
using System.ComponentModel;
22
using System.Drawing;
33
using System.Linq;
44
using System.Windows.Forms;
55

66
using BizHawk.Client.Common;
77
using BizHawk.Client.EmuHawk.Properties;
8+
using BizHawk.Emulation.Common;
89

910
namespace BizHawk.Client.EmuHawk
1011
{
1112
public partial class MarkerControl : UserControl, IDialogParent
1213
{
14+
private static string SAVESTATE_COL_NAME = "Savestate";
15+
1316
public TAStudio Tastudio { get; set; }
1417
public TasMovieMarkerList Markers => Tastudio.CurrentTasMovie.Markers;
1518

@@ -50,6 +53,7 @@ private void SetupColumns()
5053
{
5154
MarkerView.AllColumns.Clear();
5255
MarkerView.AllColumns.Add(new(name: "FrameColumn", widthUnscaled: 52, text: "Frame"));
56+
MarkerView.AllColumns.Add(new(name: SAVESTATE_COL_NAME, widthUnscaled: 24, text: "State"));
5357
MarkerView.AllColumns.Add(new(name: "LabelColumn", widthUnscaled: 125, text: string.Empty));
5458
}
5559

@@ -72,16 +76,16 @@ private void MarkerView_QueryItemBkColor(InputRoll sender, int index, RollColumn
7276
}
7377
else if (Tastudio.CurrentTasMovie.LagLog[marker.Frame + 1] is bool lagged)
7478
{
75-
if (lagged)
79+
if (column.Name == "FrameColumn")
7680
{
77-
color = column.Name == "FrameColumn"
81+
color = lagged
7882
? Tastudio.Palette.LagZone_FrameCol
79-
: Tastudio.Palette.LagZone_InputLog;
83+
: Tastudio.Palette.GreenZone_FrameCol;
8084
}
8185
else
8286
{
83-
color = column.Name == "LabelColumn"
84-
? Tastudio.Palette.GreenZone_FrameCol
87+
color = lagged
88+
? Tastudio.Palette.LagZone_InputLog
8589
: Tastudio.Palette.GreenZone_InputLog;
8690
}
8791
}
@@ -97,13 +101,26 @@ private void MarkerView_QueryItemText(InputRoll sender, int index, RollColumn co
97101
return;
98102
}
99103

104+
TasMovieMarker marker = Markers[index];
100105
if (column.Name == "FrameColumn")
101106
{
102-
text = Markers[index].Frame.ToString();
107+
text = marker.Frame.ToString();
103108
}
104109
else if (column.Name == "LabelColumn")
105110
{
106-
text = Markers[index].Message;
111+
text = marker.Message;
112+
}
113+
else if (column.Name == SAVESTATE_COL_NAME)
114+
{
115+
if (marker.WantsState)
116+
{
117+
bool hasState = marker.Frame == 0 || Tastudio.CurrentTasMovie.TasStateManager.HasState(marker.Frame - 1);
118+
text = hasState ? "✔" : "!";
119+
}
120+
else
121+
{
122+
text = "";
123+
}
107124
}
108125
}
109126

@@ -188,6 +205,7 @@ public void AddMarker(int frame, bool editText = false)
188205
{
189206
marker = new TasMovieMarker(frame);
190207
}
208+
marker.WantsState = Tastudio.Settings.StatesForMarkers;
191209

192210
UpdateValues();
193211
Markers.Add(marker);
@@ -285,5 +303,24 @@ private void MarkerView_MouseDoubleClick(object sender, EventArgs e)
285303
{
286304
if (MarkerView.AnyRowsSelected) Tastudio.GoToFrame(FirstSelectedMarker.Frame);
287305
}
306+
307+
private void MarkerView_MouseDown(object sender, MouseEventArgs e)
308+
{
309+
Cell cell = MarkerView.CurrentCell;
310+
if (cell == null || cell.RowIndex < 0 || cell.RowIndex >= Markers.Count) return;
311+
if (cell.Column.Name != SAVESTATE_COL_NAME) return;
312+
313+
TasMovieMarker marker = Markers[cell.RowIndex.Value];
314+
marker.WantsState = !marker.WantsState;
315+
if (!marker.WantsState)
316+
{
317+
Tastudio.CurrentTasMovie.TasStateManager.Unreserve(marker.Frame - 1);
318+
}
319+
else if (Tastudio.Emulator.Frame == marker.Frame - 1)
320+
{
321+
Tastudio.CurrentTasMovie.TasStateManager.Capture(marker.Frame - 1, Tastudio.Emulator.AsStatable());
322+
}
323+
Tastudio.RefreshDialog();
324+
}
288325
}
289326
}

src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudio.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ public TAStudioSettings()
143143
public int RewindStep { get; set; } = 1;
144144
public int RewindStepFast { get; set; } = 4;
145145
public bool ScrollSync { get; set; } = true;
146+
public bool StatesForMarkers { get; set; } = true;
146147
public PatternPaintModeEnum PatternPaintMode { get; set; } = TAStudioSettings.PatternPaintModeEnum.Never;
147148
public PatternSelectionEnum PatternSelection { get; set; } = TAStudioSettings.PatternSelectionEnum.Hold;
148149
public Font TasViewFont { get; set; } = new Font("Arial", 8.25F, FontStyle.Bold, GraphicsUnit.Point, 0);

src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudioSettingsForm.Designer.cs

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudioSettingsForm.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ private void TAStudioSettingsForm_Load(object sender, EventArgs e)
101101
RewindNum.Value = _settings.GeneralClientSettings.RewindStep;
102102
FastRewindNum.Value = _settings.GeneralClientSettings.RewindStepFast;
103103
ScrollSpeedNum.Value = _settings.GeneralClientSettings.ScrollSpeed;
104+
StatesForMarkersCheckbox.Checked = _settings.GeneralClientSettings.StatesForMarkers;
104105

105106
// patterns
106107
foreach (var button in _controllerDef.BoolButtons)
@@ -502,6 +503,7 @@ private void ApplyButton_Click(object sender, EventArgs e)
502503
_settings.GeneralClientSettings.MaxUndoSteps = (int)UndoCountNum.Value;
503504
_settings.GeneralClientSettings.RewindStep = (int)RewindNum.Value;
504505
_settings.GeneralClientSettings.RewindStepFast = (int)FastRewindNum.Value;
506+
_settings.GeneralClientSettings.StatesForMarkers = StatesForMarkersCheckbox.Checked;
505507

506508
if (ScrollToViewRadio.Checked) _settings.GeneralClientSettings.FollowCursorScrollMethod = "near";
507509
else if (ScrollToTopRadio.Checked) _settings.GeneralClientSettings.FollowCursorScrollMethod = "top";

src/BizHawk.Client.EmuHawk/tools/TAStudio/TAStudioSettingsForm.resx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,13 @@ And when "Recording mode" is on, the movie will be truncated at the branch frame
124124
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
125125
<value>17, 17</value>
126126
</metadata>
127+
<data name="StatesForMarkersCheckbox.ToolTip" xml:space="preserve">
128+
<value>TAStudio can automatically keep savestates for each marker.
129+
If this is enabled, new markers will have savestates enabled by default.
130+
Note: The savestate needs to be on the frame before the marker, so TAStudio
131+
can run 1 frame after loading the state to get a video frame. Thus, making a
132+
marker on the current frame will not automatically create a state.</value>
133+
</data>
127134
<data name="EditInvisibleColumnsCheckbox.ToolTip" xml:space="preserve">
128135
<value>When disabled, inputs that are not visible on the active input roll cannot be edited.
129136
This allows you to, for example, insert and delete frames on a roll with player 1's inputs

0 commit comments

Comments
 (0)