TAStudio:
-Moved Toggle/SetStates from TasMovie.cs to TasMovie.Editing.cs -bugfix: Yet another bug in setting LastVisibleFrame -Removed unused declaration -Fixed MarkerControl to not mess up display when a deleted marker is still selected. -feature: Basic undo/redo history functions seem to work. (Ctrl+Z/Y in TasView)
This commit is contained in:
parent
5aed8f8224
commit
cf081ce1fc
|
@ -152,6 +152,7 @@
|
|||
<Compile Include="movie\bk2\Bk2Movie.HeaderApi.cs">
|
||||
<DependentUpon>Bk2Movie.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="movie\tasproj\TasMovie.History.cs" />
|
||||
<Compile Include="movie\bk2\Bk2Movie.InputLog.cs">
|
||||
<DependentUpon>Bk2Movie.cs</DependentUpon>
|
||||
</Compile>
|
||||
|
|
|
@ -110,6 +110,8 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_log.RemoveRange(frame, _log.Count - frame);
|
||||
Changes = true;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,18 +11,26 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
public partial class TasMovie
|
||||
{
|
||||
public TasMovieChangeLog ChangeLog;
|
||||
|
||||
public override void RecordFrame(int frame, IController source)
|
||||
{
|
||||
ChangeLog.AddGeneralUndo(frame, frame);
|
||||
|
||||
base.RecordFrame(frame, source);
|
||||
|
||||
LagLog.RemoveFrom(frame);
|
||||
LagLog[frame] = Global.Emulator.AsInputPollable().IsLagFrame;
|
||||
|
||||
StateManager.Capture();
|
||||
|
||||
ChangeLog.SetGeneralRedo();
|
||||
}
|
||||
|
||||
public override void Truncate(int frame)
|
||||
{
|
||||
ChangeLog.AddGeneralUndo(frame, InputLogLength - 1);
|
||||
|
||||
if (frame < _log.Count - 1)
|
||||
{
|
||||
Changes = true;
|
||||
|
@ -33,24 +41,45 @@ namespace BizHawk.Client.Common
|
|||
LagLog.RemoveFrom(frame);
|
||||
StateManager.Invalidate(frame);
|
||||
Markers.TruncateAt(frame);
|
||||
|
||||
ChangeLog.SetGeneralRedo();
|
||||
}
|
||||
|
||||
public override void PokeFrame(int frame, IController source)
|
||||
{
|
||||
ChangeLog.AddGeneralUndo(frame, frame);
|
||||
|
||||
base.PokeFrame(frame, source);
|
||||
InvalidateAfter(frame);
|
||||
|
||||
ChangeLog.SetGeneralRedo();
|
||||
}
|
||||
public void SetFrame(int frame, string source)
|
||||
{
|
||||
ChangeLog.AddGeneralUndo(frame, frame);
|
||||
|
||||
base.SetFrameAt(frame, source);
|
||||
InvalidateAfter(frame);
|
||||
|
||||
ChangeLog.SetGeneralRedo();
|
||||
}
|
||||
|
||||
public override void ClearFrame(int frame)
|
||||
{
|
||||
ChangeLog.AddGeneralUndo(frame, frame);
|
||||
|
||||
base.ClearFrame(frame);
|
||||
InvalidateAfter(frame);
|
||||
|
||||
ChangeLog.SetGeneralRedo();
|
||||
}
|
||||
|
||||
public void RemoveFrames(int[] frames)
|
||||
{
|
||||
if (frames.Any())
|
||||
{
|
||||
ChangeLog.AddGeneralUndo(frames.Min(), frames.Max());
|
||||
|
||||
var invalidateAfter = frames.Min(x => x);
|
||||
foreach (var frame in frames.OrderByDescending(x => x)) // Removin them in reverse order allows us to remove by index;
|
||||
{
|
||||
|
@ -59,18 +88,26 @@ namespace BizHawk.Client.Common
|
|||
|
||||
Changes = true;
|
||||
InvalidateAfter(invalidateAfter);
|
||||
|
||||
ChangeLog.SetGeneralRedo();
|
||||
}
|
||||
}
|
||||
|
||||
public void InsertInput(int frame, IEnumerable<string> inputLog)
|
||||
{
|
||||
ChangeLog.AddGeneralUndo(frame, frame + inputLog.Count() - 1);
|
||||
|
||||
_log.InsertRange(frame, inputLog);
|
||||
Changes = true;
|
||||
InvalidateAfter(frame);
|
||||
|
||||
ChangeLog.SetGeneralRedo();
|
||||
}
|
||||
|
||||
public void InsertInput(int frame, IEnumerable<IController> inputStates)
|
||||
{
|
||||
ChangeLog.AddGeneralUndo(frame, frame + inputStates.Count() - 1);
|
||||
|
||||
var lg = LogGeneratorInstance();
|
||||
|
||||
var inputLog = new List<string>();
|
||||
|
@ -82,10 +119,14 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
|
||||
InsertInput(frame, inputLog);
|
||||
|
||||
ChangeLog.SetGeneralRedo();
|
||||
}
|
||||
|
||||
public void CopyOverInput(int frame, IEnumerable<IController> inputStates)
|
||||
{
|
||||
ChangeLog.AddGeneralUndo(frame, frame + inputStates.Count() - 1);
|
||||
|
||||
var lg = LogGeneratorInstance();
|
||||
var states = inputStates.ToList();
|
||||
for (int i = 0; i < states.Count; i++)
|
||||
|
@ -96,10 +137,14 @@ namespace BizHawk.Client.Common
|
|||
|
||||
Changes = true;
|
||||
InvalidateAfter(frame);
|
||||
|
||||
ChangeLog.SetGeneralRedo();
|
||||
}
|
||||
|
||||
public void InsertEmptyFrame(int frame, int count = 1)
|
||||
{
|
||||
ChangeLog.AddGeneralUndo(frame, frame + count - 1);
|
||||
|
||||
var lg = LogGeneratorInstance();
|
||||
lg.SetSource(Global.MovieSession.MovieControllerInstance());
|
||||
|
||||
|
@ -110,6 +155,134 @@ namespace BizHawk.Client.Common
|
|||
|
||||
Changes = true;
|
||||
InvalidateAfter(frame - 1);
|
||||
|
||||
ChangeLog.SetGeneralRedo();
|
||||
}
|
||||
|
||||
public void ToggleBoolState(int frame, string buttonName)
|
||||
{
|
||||
if (frame < _log.Count)
|
||||
{
|
||||
var adapter = GetInputState(frame) as Bk2ControllerAdapter;
|
||||
adapter[buttonName] = !adapter.IsPressed(buttonName);
|
||||
|
||||
var lg = LogGeneratorInstance();
|
||||
lg.SetSource(adapter);
|
||||
_log[frame] = lg.GenerateLogEntry();
|
||||
Changes = true;
|
||||
InvalidateAfter(frame);
|
||||
|
||||
ChangeLog.AddBoolToggle(frame, buttonName, !adapter[buttonName]);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetBoolState(int frame, string buttonName, bool val)
|
||||
{
|
||||
if (frame < _log.Count)
|
||||
{
|
||||
var adapter = GetInputState(frame) as Bk2ControllerAdapter;
|
||||
var old = adapter[buttonName];
|
||||
adapter[buttonName] = val;
|
||||
|
||||
var lg = LogGeneratorInstance();
|
||||
lg.SetSource(adapter);
|
||||
_log[frame] = lg.GenerateLogEntry();
|
||||
|
||||
if (old != val)
|
||||
{
|
||||
InvalidateAfter(frame);
|
||||
Changes = true;
|
||||
ChangeLog.AddBoolToggle(frame, buttonName, old);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void SetBoolStates(int frame, int count, string buttonName, bool val)
|
||||
{
|
||||
if (frame < _log.Count)
|
||||
{
|
||||
if (frame + count >= _log.Count)
|
||||
count = _log.Count - frame - 1;
|
||||
|
||||
ChangeLog.AddGeneralUndo(frame, frame + count - 1);
|
||||
|
||||
int changed = -1;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var adapter = GetInputState(frame + i) as Bk2ControllerAdapter;
|
||||
bool old = adapter[buttonName];
|
||||
adapter[buttonName] = val;
|
||||
|
||||
var lg = LogGeneratorInstance();
|
||||
lg.SetSource(adapter);
|
||||
_log[frame + i] = lg.GenerateLogEntry();
|
||||
|
||||
if (changed == -1 && old != val)
|
||||
changed = frame + i;
|
||||
}
|
||||
|
||||
if (changed != -1)
|
||||
{
|
||||
InvalidateAfter(changed);
|
||||
Changes = true;
|
||||
}
|
||||
|
||||
ChangeLog.SetGeneralRedo();
|
||||
}
|
||||
}
|
||||
|
||||
public void SetFloatState(int frame, string buttonName, float val)
|
||||
{
|
||||
if (frame < _log.Count)
|
||||
{
|
||||
var adapter = GetInputState(frame) as Bk2ControllerAdapter;
|
||||
var old = adapter.GetFloat(buttonName);
|
||||
adapter.SetFloat(buttonName, val);
|
||||
|
||||
var lg = LogGeneratorInstance();
|
||||
lg.SetSource(adapter);
|
||||
_log[frame] = lg.GenerateLogEntry();
|
||||
|
||||
if (old != val)
|
||||
{
|
||||
InvalidateAfter(frame);
|
||||
Changes = true;
|
||||
ChangeLog.AddFloatChange(frame, buttonName, old, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void SetFloatStates(int frame, int count, string buttonName, float val)
|
||||
{
|
||||
if (frame < _log.Count)
|
||||
{
|
||||
if (frame + count >= _log.Count)
|
||||
count = _log.Count - frame - 1;
|
||||
|
||||
ChangeLog.AddGeneralUndo(frame, frame + count - 1);
|
||||
|
||||
int changed = -1;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
var adapter = GetInputState(frame + i) as Bk2ControllerAdapter;
|
||||
float old = adapter.GetFloat(buttonName);
|
||||
adapter.SetFloat(buttonName, val);
|
||||
|
||||
var lg = LogGeneratorInstance();
|
||||
lg.SetSource(adapter);
|
||||
_log[frame + i] = lg.GenerateLogEntry();
|
||||
|
||||
if (changed == -1 && old != val)
|
||||
changed = frame + i;
|
||||
}
|
||||
|
||||
if (changed != -1)
|
||||
{
|
||||
InvalidateAfter(changed);
|
||||
Changes = true;
|
||||
}
|
||||
|
||||
ChangeLog.SetGeneralRedo();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,8 @@ namespace BizHawk.Client.Common
|
|||
|
||||
private BackgroundWorker _progressReportWorker = null;
|
||||
|
||||
public TasMovie(string path, bool startsFromSavestate = false, BackgroundWorker progressReportWorker = null) : base(path)
|
||||
public TasMovie(string path, bool startsFromSavestate = false, BackgroundWorker progressReportWorker = null)
|
||||
: base(path)
|
||||
{
|
||||
// TODO: how to call the default constructor AND the base(path) constructor? And is base(path) calling base() ?
|
||||
_progressReportWorker = progressReportWorker;
|
||||
|
@ -33,6 +34,8 @@ namespace BizHawk.Client.Common
|
|||
throw new InvalidOperationException("Cannot create a TasMovie against a core that does not implement IStatable");
|
||||
}
|
||||
|
||||
ChangeLog = new TasMovieChangeLog(this);
|
||||
|
||||
StateManager = new TasStateManager(this);
|
||||
Header[HeaderKeys.MOVIEVERSION] = "BizHawk v2.0 Tasproj v1.0";
|
||||
Markers = new TasMovieMarkerList(this);
|
||||
|
@ -49,6 +52,8 @@ namespace BizHawk.Client.Common
|
|||
throw new InvalidOperationException("Cannot create a TasMovie against a core that does not implement IStatable");
|
||||
}
|
||||
|
||||
ChangeLog = new TasMovieChangeLog(this);
|
||||
|
||||
StateManager = new TasStateManager(this);
|
||||
Header[HeaderKeys.MOVIEVERSION] = "BizHawk v2.0 Tasproj v1.0";
|
||||
Markers = new TasMovieMarkerList(this);
|
||||
|
@ -134,6 +139,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
ClearTasprojExtras();
|
||||
Markers.Add(0, StartsFromSavestate ? "Savestate" : "Power on");
|
||||
ChangeLog = new TasMovieChangeLog(this);
|
||||
|
||||
base.StartNewRecording();
|
||||
}
|
||||
|
@ -197,61 +203,6 @@ namespace BizHawk.Client.Common
|
|||
return "!";
|
||||
}
|
||||
|
||||
public void ToggleBoolState(int frame, string buttonName)
|
||||
{
|
||||
if (frame < _log.Count)
|
||||
{
|
||||
var adapter = GetInputState(frame) as Bk2ControllerAdapter;
|
||||
adapter[buttonName] = !adapter.IsPressed(buttonName);
|
||||
|
||||
var lg = LogGeneratorInstance();
|
||||
lg.SetSource(adapter);
|
||||
_log[frame] = lg.GenerateLogEntry();
|
||||
Changes = true;
|
||||
InvalidateAfter(frame);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetBoolState(int frame, string buttonName, bool val)
|
||||
{
|
||||
if (frame < _log.Count)
|
||||
{
|
||||
var adapter = GetInputState(frame) as Bk2ControllerAdapter;
|
||||
var old = adapter[buttonName];
|
||||
adapter[buttonName] = val;
|
||||
|
||||
var lg = LogGeneratorInstance();
|
||||
lg.SetSource(adapter);
|
||||
_log[frame] = lg.GenerateLogEntry();
|
||||
|
||||
if (old != val)
|
||||
{
|
||||
InvalidateAfter(frame);
|
||||
Changes = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetFloatState(int frame, string buttonName, float val)
|
||||
{
|
||||
if (frame < _log.Count)
|
||||
{
|
||||
var adapter = GetInputState(frame) as Bk2ControllerAdapter;
|
||||
var old = adapter.GetFloat(buttonName);
|
||||
adapter.SetFloat(buttonName, val);
|
||||
|
||||
var lg = LogGeneratorInstance();
|
||||
lg.SetSource(adapter);
|
||||
_log[frame] = lg.GenerateLogEntry();
|
||||
|
||||
if (old != val)
|
||||
{
|
||||
InvalidateAfter(frame);
|
||||
Changes = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool BoolIsPressed(int frame, string buttonName)
|
||||
{
|
||||
return ((Bk2ControllerAdapter)GetInputState(frame))
|
||||
|
@ -333,7 +284,7 @@ namespace BizHawk.Client.Common
|
|||
public void CopyLog(IEnumerable<string> log)
|
||||
{
|
||||
_log.Clear();
|
||||
foreach(var entry in log)
|
||||
foreach (var entry in log)
|
||||
{
|
||||
_log.Add(entry);
|
||||
}
|
||||
|
@ -469,7 +420,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
else if (line.StartsWith("|"))
|
||||
{
|
||||
SetFrameAt(i, line);
|
||||
SetFrame(i, line);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,11 +12,9 @@ namespace BizHawk.Client.Common
|
|||
/// </summary>
|
||||
public class TasMovieMarker
|
||||
{
|
||||
private int _frame;
|
||||
|
||||
public TasMovieMarker(int frame, string message = "")
|
||||
{
|
||||
_frame = frame;
|
||||
Frame = frame;
|
||||
Message = message;
|
||||
}
|
||||
|
||||
|
@ -26,14 +24,11 @@ namespace BizHawk.Client.Common
|
|||
public TasMovieMarker(string line)
|
||||
{
|
||||
var split = line.Split('\t');
|
||||
_frame = int.Parse(split[0]);
|
||||
Frame = int.Parse(split[0]);
|
||||
Message = split[1];
|
||||
}
|
||||
|
||||
public virtual int Frame
|
||||
{
|
||||
get { return _frame; }
|
||||
}
|
||||
public virtual int Frame { get; set; }
|
||||
|
||||
public virtual string Message { get; set; }
|
||||
|
||||
|
|
|
@ -607,9 +607,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
FirstVisibleRow -= Math.Sign(lastVisible - value);
|
||||
SetLagFramesArray();
|
||||
lastVisible = LastFullyVisibleRow;
|
||||
} while ((lastVisible - value < 0 || lastVisible - value > lagFrames[VisibleRows]) && FirstVisibleRow != 0);
|
||||
|
||||
System.Diagnostics.Debug.Print("Jumped to: " + value + " (" + LastFullyVisibleRow + ")");
|
||||
} while ((lastVisible - value < 0 || lastVisible - value > lagFrames[VisibleRows - HalfRow]) && FirstVisibleRow != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
color = TAStudio.Marker_FrameCol;
|
||||
}
|
||||
else if (index < Tastudio.CurrentTasMovie.InputLogLength)
|
||||
else if (index < Tastudio.CurrentTasMovie.Markers.Count)
|
||||
{
|
||||
var marker = Tastudio.CurrentTasMovie.Markers[index];
|
||||
var record = Tastudio.CurrentTasMovie[marker.Frame];
|
||||
|
@ -77,7 +77,8 @@ namespace BizHawk.Client.EmuHawk
|
|||
color = Color.White;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
color = Color.White;
|
||||
}
|
||||
|
||||
private void MarkerView_QueryItemText(int index, InputRoll.RollColumn column, out string text)
|
||||
|
@ -120,7 +121,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void RemoveBtn_Click(object sender, EventArgs e)
|
||||
{
|
||||
SelectedMarkers.ForEach(i => Tastudio.CurrentTasMovie.Markers.Remove(i));
|
||||
SelectedMarkers.ForEach(i => Tastudio.RemoveMarker(i));
|
||||
MarkerInputRoll.DeselectAll();
|
||||
Tastudio.RefreshDialog();
|
||||
MarkerView_SelectedIndexChanged(sender, e);
|
||||
|
|
|
@ -1180,6 +1180,5 @@ namespace BizHawk.Client.EmuHawk
|
|||
private System.Windows.Forms.ToolStripMenuItem HideLagFrames0;
|
||||
private System.Windows.Forms.ToolStripMenuItem HideLagFrames1;
|
||||
private System.Windows.Forms.ToolStripMenuItem HideLagFrames2;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
|
||||
}
|
||||
}
|
|
@ -539,6 +539,16 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
TasView.HorizontalOrientation ^= true;
|
||||
}
|
||||
else if (e.Control && !e.Alt && !e.Shift && e.KeyCode == Keys.Z) // Ctrl + Z
|
||||
{
|
||||
if (CurrentTasMovie.ChangeLog.Undo() < Emulator.Frame)
|
||||
GoToFrame(CurrentTasMovie.ChangeLog.PreviousUndoFrame);
|
||||
}
|
||||
else if (e.Control && !e.Alt && !e.Shift && e.KeyCode == Keys.Y) // Ctrl + Y
|
||||
{
|
||||
if (CurrentTasMovie.ChangeLog.Redo() < Emulator.Frame)
|
||||
GoToFrame(CurrentTasMovie.ChangeLog.PreviousRedoFrame);
|
||||
}
|
||||
|
||||
// SuuperW: Float Editing
|
||||
if (_floatEditRow != -1)
|
||||
|
@ -620,7 +630,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
}
|
||||
}
|
||||
|
||||
TasView.Refresh();
|
||||
RefreshDialog();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -429,7 +429,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
if (result == DialogResult.OK)
|
||||
{
|
||||
CurrentTasMovie.Markers.Add(markerFrame, i.PromptText);
|
||||
AddMarker(markerFrame, i.PromptText);
|
||||
MarkerControl.UpdateValues();
|
||||
}
|
||||
}
|
||||
|
@ -449,7 +449,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
if (result == DialogResult.OK)
|
||||
{
|
||||
marker.Message = i.PromptText;
|
||||
EditMarker(marker, i.PromptText);
|
||||
MarkerControl.UpdateValues();
|
||||
}
|
||||
}
|
||||
|
@ -744,5 +744,22 @@ namespace BizHawk.Client.EmuHawk
|
|||
MarkerControl.RemoveMarker();
|
||||
}
|
||||
|
||||
public void AddMarker(int markerFrame, string message)
|
||||
{
|
||||
TasMovieMarker marker = new TasMovieMarker(markerFrame, message);
|
||||
CurrentTasMovie.Markers.Add(marker);
|
||||
CurrentTasMovie.ChangeLog.AddMarkerChange(marker);
|
||||
}
|
||||
public void RemoveMarker(TasMovieMarker marker)
|
||||
{
|
||||
CurrentTasMovie.Markers.Remove(marker);
|
||||
CurrentTasMovie.ChangeLog.AddMarkerChange(null, marker.Frame, marker.Message);
|
||||
}
|
||||
public void EditMarker(TasMovieMarker marker, string message)
|
||||
{
|
||||
string old = marker.Message;
|
||||
marker.Message = message;
|
||||
CurrentTasMovie.ChangeLog.AddMarkerChange(marker, marker.Frame, old);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue