Add config option for rewinds every fixed number of frames. (#2893)
* wip consistent rewind intervals. In Bizhawk 2.3, rewinds were always made in fixed intervals. With the new rewinder, the rewind intervals vary depending on the save state size. (This is especially pronounced with delta compression.) While this is good for TAStudio, it is awful for regular playing / TASing. * clean up rewind config gui a bit. Use radio buttons to make it clear that only the numeric input field of the selected option is being used. * use more precise variable names. * minor whitespace cleanup * don't use fixed rewind intervals by default. This avoid suddenly changing the rewind behaviour when updating from previous recent versions of Bizhawk.
This commit is contained in:
parent
158451a68e
commit
94f9016c6f
|
@ -19,11 +19,21 @@
|
|||
/// </summary>
|
||||
long BufferSize { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies whether TargetFrameLength or TargetRewindInterval is used.
|
||||
/// </summary>
|
||||
public bool UseFixedRewindInterval { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Desired frame length (number of emulated frames you can go back before running out of buffer)
|
||||
/// </summary>
|
||||
int TargetFrameLength { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Desired rewind interval (number of emulated frames you can go back per rewind)
|
||||
/// </summary>
|
||||
int TargetRewindInterval { get; }
|
||||
|
||||
public enum BackingStoreType
|
||||
{
|
||||
Memory,
|
||||
|
@ -39,7 +49,9 @@
|
|||
public bool UseDelta { get; set; }
|
||||
public bool Enabled { get; set; } = true;
|
||||
public long BufferSize { get; set; } = 512; // in mb
|
||||
public bool UseFixedRewindInterval { get; set; } = false;
|
||||
public int TargetFrameLength { get; set; } = 600;
|
||||
public int TargetRewindInterval { get; set; } = 5;
|
||||
public IRewindSettings.BackingStoreType BackingStore { get; set; } = IRewindSettings.BackingStoreType.Memory;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,135 +1,138 @@
|
|||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
public class ZwinderStateManagerSettings
|
||||
{
|
||||
public ZwinderStateManagerSettings() { }
|
||||
|
||||
public ZwinderStateManagerSettings(ZwinderStateManagerSettings settings)
|
||||
{
|
||||
CurrentUseCompression = settings.CurrentUseCompression;
|
||||
CurrentBufferSize = settings.CurrentBufferSize;
|
||||
CurrentTargetFrameLength = settings.CurrentTargetFrameLength;
|
||||
CurrentStoreType = settings.CurrentStoreType;
|
||||
|
||||
RecentUseCompression = settings.RecentUseCompression;
|
||||
RecentBufferSize = settings.RecentBufferSize;
|
||||
RecentTargetFrameLength = settings.RecentTargetFrameLength;
|
||||
RecentStoreType = settings.RecentStoreType;
|
||||
|
||||
GapsUseCompression = settings.GapsUseCompression;
|
||||
GapsBufferSize = settings.GapsBufferSize;
|
||||
GapsTargetFrameLength = settings.GapsTargetFrameLength;
|
||||
GapsStoreType = settings.GapsStoreType;
|
||||
|
||||
AncientStateInterval = settings.AncientStateInterval;
|
||||
AncientStoreType = settings.AncientStoreType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Buffer settings when navigating near now
|
||||
/// </summary>
|
||||
[DisplayName("Current - Use Compression.")]
|
||||
[Description("The Current buffer is the primary buffer used near the last edited frame. This should be the largest buffer to ensure minimal gaps during editing.")]
|
||||
public bool CurrentUseCompression { get; set; }
|
||||
|
||||
[DisplayName("Current - Buffer Size")]
|
||||
[Description("Max amount of buffer space to use in MB.\n\nThe Current buffer is the primary buffer used near the last edited frame. This should be the largest buffer to ensure minimal gaps during editing.")]
|
||||
[TypeConverter(typeof(IntConverter)), Range(64, 32768)]
|
||||
public int CurrentBufferSize { get; set; } = 256;
|
||||
|
||||
[DisplayName("Current - Target Frame Length")]
|
||||
[Description("Desired frame length (number of emulated frames you can go back before running out of buffer)\n\nThe Current buffer is the primary buffer used near the last edited frame. This should be the largest buffer to ensure minimal gaps during editing.")]
|
||||
[TypeConverter(typeof(IntConverter)), Range(1, int.MaxValue)]
|
||||
public int CurrentTargetFrameLength { get; set; } = 500;
|
||||
|
||||
[DisplayName("Current - Storage Type")]
|
||||
[Description("Where to keep the buffer.")]
|
||||
public IRewindSettings.BackingStoreType CurrentStoreType { get; set; } = IRewindSettings.BackingStoreType.Memory;
|
||||
|
||||
/// <summary>
|
||||
/// Buffer settings when navigating directly before the Current buffer
|
||||
/// </summary>
|
||||
[DisplayName("Recent - Use Compression")]
|
||||
[Description("The Recent buffer is where the current frames decay as the buffer fills up. The goal of this buffer is to maximize the amount of movie that can be fairly quickly navigated to. Therefore, a high target frame length is ideal here.")]
|
||||
public bool RecentUseCompression { get; set; }
|
||||
|
||||
[DisplayName("Recent - Buffer Size")]
|
||||
[Description("Max amount of buffer space to use in MB.\n\nThe Recent buffer is where the current frames decay as the buffer fills up. The goal of this buffer is to maximize the amount of movie that can be fairly quickly navigated to. Therefore, a high target frame length is ideal here.")]
|
||||
[TypeConverter(typeof(IntConverter)), Range(64, 32768)]
|
||||
public int RecentBufferSize { get; set; } = 128;
|
||||
|
||||
[DisplayName("Recent - Target Frame Length")]
|
||||
[Description("Desired frame length (number of emulated frames you can go back before running out of buffer).\n\nThe Recent buffer is where the current frames decay as the buffer fills up. The goal of this buffer is to maximize the amount of movie that can be fairly quickly navigated to. Therefore, a high target frame length is ideal here.")]
|
||||
[TypeConverter(typeof(IntConverter)), Range(1, int.MaxValue)]
|
||||
public int RecentTargetFrameLength { get; set; } = 2000;
|
||||
|
||||
[DisplayName("Recent - Storage Type")]
|
||||
[Description("Where to keep the buffer.")]
|
||||
public IRewindSettings.BackingStoreType RecentStoreType { get; set; } = IRewindSettings.BackingStoreType.Memory;
|
||||
|
||||
/// <summary>
|
||||
/// Priority States for special use cases
|
||||
/// </summary>
|
||||
[DisplayName("Gaps - Use Compression")]
|
||||
[Description("The Gap buffer is used for temporary storage when replaying older segment of the run without editing. It is used to 're-greenzone' large gaps while navigating around in an older area of the movie. This buffer can be small, and a similar size to target frame length ratio as current is ideal.")]
|
||||
public bool GapsUseCompression { get; set; }
|
||||
|
||||
[DisplayName("Gaps - Buffer Size")]
|
||||
[Description("Max amount of buffer space to use in MB\n\nThe Gap buffer is used for temporary storage when replaying older segment of the run without editing. It is used to 're-greenzone' large gaps while navigating around in an older area of the movie. This buffer can be small, and a similar size to target frame length ratio as current is ideal.")]
|
||||
[TypeConverter(typeof(IntConverter)), Range(64, 32768)]
|
||||
public int GapsBufferSize { get; set; } = 64;
|
||||
|
||||
[DisplayName("Gaps - Target Frame Length")]
|
||||
[Description("Desired frame length (number of emulated frames you can go back before running out of buffer)\n\nThe Gap buffer is used for temporary storage when replaying older segment of the run without editing. It is used to 're-greenzone' large gaps while navigating around in an older area of the movie. This buffer can be small, and a similar size to target frame length ratio as current is ideal.")]
|
||||
[TypeConverter(typeof(IntConverter)), Range(1, int.MaxValue)]
|
||||
public int GapsTargetFrameLength { get; set; } = 125;
|
||||
|
||||
[DisplayName("Gaps - Storage Type")]
|
||||
[Description("Where to keep the buffer.")]
|
||||
public IRewindSettings.BackingStoreType GapsStoreType { get; set; } = IRewindSettings.BackingStoreType.Memory;
|
||||
|
||||
[DisplayName("Ancient State Interval")]
|
||||
[Description("Once both the Current and Recent buffers have filled, some states are put into reserved to ensure there is always a state somewhat near a desired frame to navigate to. These states never decay but are invalidated. This number should be as high as possible without being overly cumbersome to replay this many frames.")]
|
||||
[TypeConverter(typeof(IntConverter)), Range(1, int.MaxValue)]
|
||||
public int AncientStateInterval { get; set; } = 5000;
|
||||
|
||||
[DisplayName("Ancient - Storage Type")]
|
||||
[Description("Where to keep the reserved states.")]
|
||||
public IRewindSettings.BackingStoreType AncientStoreType { get; set; } = IRewindSettings.BackingStoreType.Memory;
|
||||
|
||||
// Just to simplify some other code.
|
||||
public RewindConfig Current()
|
||||
{
|
||||
return new RewindConfig
|
||||
{
|
||||
UseCompression = CurrentUseCompression,
|
||||
BufferSize = CurrentBufferSize,
|
||||
TargetFrameLength = CurrentTargetFrameLength,
|
||||
BackingStore = CurrentStoreType
|
||||
};
|
||||
}
|
||||
public RewindConfig Recent()
|
||||
{
|
||||
return new RewindConfig
|
||||
{
|
||||
UseCompression = RecentUseCompression,
|
||||
BufferSize = RecentBufferSize,
|
||||
TargetFrameLength = RecentTargetFrameLength,
|
||||
BackingStore = RecentStoreType
|
||||
};
|
||||
}
|
||||
public RewindConfig GapFiller()
|
||||
{
|
||||
return new RewindConfig
|
||||
{
|
||||
UseCompression = GapsUseCompression,
|
||||
BufferSize = GapsBufferSize,
|
||||
TargetFrameLength = GapsTargetFrameLength,
|
||||
BackingStore = GapsStoreType
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
public class ZwinderStateManagerSettings
|
||||
{
|
||||
public ZwinderStateManagerSettings() { }
|
||||
|
||||
public ZwinderStateManagerSettings(ZwinderStateManagerSettings settings)
|
||||
{
|
||||
CurrentUseCompression = settings.CurrentUseCompression;
|
||||
CurrentBufferSize = settings.CurrentBufferSize;
|
||||
CurrentTargetFrameLength = settings.CurrentTargetFrameLength;
|
||||
CurrentStoreType = settings.CurrentStoreType;
|
||||
|
||||
RecentUseCompression = settings.RecentUseCompression;
|
||||
RecentBufferSize = settings.RecentBufferSize;
|
||||
RecentTargetFrameLength = settings.RecentTargetFrameLength;
|
||||
RecentStoreType = settings.RecentStoreType;
|
||||
|
||||
GapsUseCompression = settings.GapsUseCompression;
|
||||
GapsBufferSize = settings.GapsBufferSize;
|
||||
GapsTargetFrameLength = settings.GapsTargetFrameLength;
|
||||
GapsStoreType = settings.GapsStoreType;
|
||||
|
||||
AncientStateInterval = settings.AncientStateInterval;
|
||||
AncientStoreType = settings.AncientStoreType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Buffer settings when navigating near now
|
||||
/// </summary>
|
||||
[DisplayName("Current - Use Compression.")]
|
||||
[Description("The Current buffer is the primary buffer used near the last edited frame. This should be the largest buffer to ensure minimal gaps during editing.")]
|
||||
public bool CurrentUseCompression { get; set; }
|
||||
|
||||
[DisplayName("Current - Buffer Size")]
|
||||
[Description("Max amount of buffer space to use in MB.\n\nThe Current buffer is the primary buffer used near the last edited frame. This should be the largest buffer to ensure minimal gaps during editing.")]
|
||||
[TypeConverter(typeof(IntConverter)), Range(64, 32768)]
|
||||
public int CurrentBufferSize { get; set; } = 256;
|
||||
|
||||
[DisplayName("Current - Target Frame Length")]
|
||||
[Description("Desired frame length (number of emulated frames you can go back before running out of buffer)\n\nThe Current buffer is the primary buffer used near the last edited frame. This should be the largest buffer to ensure minimal gaps during editing.")]
|
||||
[TypeConverter(typeof(IntConverter)), Range(1, int.MaxValue)]
|
||||
public int CurrentTargetFrameLength { get; set; } = 500;
|
||||
|
||||
[DisplayName("Current - Storage Type")]
|
||||
[Description("Where to keep the buffer.")]
|
||||
public IRewindSettings.BackingStoreType CurrentStoreType { get; set; } = IRewindSettings.BackingStoreType.Memory;
|
||||
|
||||
/// <summary>
|
||||
/// Buffer settings when navigating directly before the Current buffer
|
||||
/// </summary>
|
||||
[DisplayName("Recent - Use Compression")]
|
||||
[Description("The Recent buffer is where the current frames decay as the buffer fills up. The goal of this buffer is to maximize the amount of movie that can be fairly quickly navigated to. Therefore, a high target frame length is ideal here.")]
|
||||
public bool RecentUseCompression { get; set; }
|
||||
|
||||
[DisplayName("Recent - Buffer Size")]
|
||||
[Description("Max amount of buffer space to use in MB.\n\nThe Recent buffer is where the current frames decay as the buffer fills up. The goal of this buffer is to maximize the amount of movie that can be fairly quickly navigated to. Therefore, a high target frame length is ideal here.")]
|
||||
[TypeConverter(typeof(IntConverter)), Range(64, 32768)]
|
||||
public int RecentBufferSize { get; set; } = 128;
|
||||
|
||||
[DisplayName("Recent - Target Frame Length")]
|
||||
[Description("Desired frame length (number of emulated frames you can go back before running out of buffer).\n\nThe Recent buffer is where the current frames decay as the buffer fills up. The goal of this buffer is to maximize the amount of movie that can be fairly quickly navigated to. Therefore, a high target frame length is ideal here.")]
|
||||
[TypeConverter(typeof(IntConverter)), Range(1, int.MaxValue)]
|
||||
public int RecentTargetFrameLength { get; set; } = 2000;
|
||||
|
||||
[DisplayName("Recent - Storage Type")]
|
||||
[Description("Where to keep the buffer.")]
|
||||
public IRewindSettings.BackingStoreType RecentStoreType { get; set; } = IRewindSettings.BackingStoreType.Memory;
|
||||
|
||||
/// <summary>
|
||||
/// Priority States for special use cases
|
||||
/// </summary>
|
||||
[DisplayName("Gaps - Use Compression")]
|
||||
[Description("The Gap buffer is used for temporary storage when replaying older segment of the run without editing. It is used to 're-greenzone' large gaps while navigating around in an older area of the movie. This buffer can be small, and a similar size to target frame length ratio as current is ideal.")]
|
||||
public bool GapsUseCompression { get; set; }
|
||||
|
||||
[DisplayName("Gaps - Buffer Size")]
|
||||
[Description("Max amount of buffer space to use in MB\n\nThe Gap buffer is used for temporary storage when replaying older segment of the run without editing. It is used to 're-greenzone' large gaps while navigating around in an older area of the movie. This buffer can be small, and a similar size to target frame length ratio as current is ideal.")]
|
||||
[TypeConverter(typeof(IntConverter)), Range(64, 32768)]
|
||||
public int GapsBufferSize { get; set; } = 64;
|
||||
|
||||
[DisplayName("Gaps - Target Frame Length")]
|
||||
[Description("Desired frame length (number of emulated frames you can go back before running out of buffer)\n\nThe Gap buffer is used for temporary storage when replaying older segment of the run without editing. It is used to 're-greenzone' large gaps while navigating around in an older area of the movie. This buffer can be small, and a similar size to target frame length ratio as current is ideal.")]
|
||||
[TypeConverter(typeof(IntConverter)), Range(1, int.MaxValue)]
|
||||
public int GapsTargetFrameLength { get; set; } = 125;
|
||||
|
||||
[DisplayName("Gaps - Storage Type")]
|
||||
[Description("Where to keep the buffer.")]
|
||||
public IRewindSettings.BackingStoreType GapsStoreType { get; set; } = IRewindSettings.BackingStoreType.Memory;
|
||||
|
||||
[DisplayName("Ancient State Interval")]
|
||||
[Description("Once both the Current and Recent buffers have filled, some states are put into reserved to ensure there is always a state somewhat near a desired frame to navigate to. These states never decay but are invalidated. This number should be as high as possible without being overly cumbersome to replay this many frames.")]
|
||||
[TypeConverter(typeof(IntConverter)), Range(1, int.MaxValue)]
|
||||
public int AncientStateInterval { get; set; } = 5000;
|
||||
|
||||
[DisplayName("Ancient - Storage Type")]
|
||||
[Description("Where to keep the reserved states.")]
|
||||
public IRewindSettings.BackingStoreType AncientStoreType { get; set; } = IRewindSettings.BackingStoreType.Memory;
|
||||
|
||||
// Just to simplify some other code.
|
||||
public RewindConfig Current()
|
||||
{
|
||||
return new RewindConfig
|
||||
{
|
||||
UseCompression = CurrentUseCompression,
|
||||
BufferSize = CurrentBufferSize,
|
||||
UseFixedRewindInterval = false,
|
||||
TargetFrameLength = CurrentTargetFrameLength,
|
||||
BackingStore = CurrentStoreType
|
||||
};
|
||||
}
|
||||
public RewindConfig Recent()
|
||||
{
|
||||
return new RewindConfig
|
||||
{
|
||||
UseCompression = RecentUseCompression,
|
||||
BufferSize = RecentBufferSize,
|
||||
UseFixedRewindInterval = false,
|
||||
TargetFrameLength = RecentTargetFrameLength,
|
||||
BackingStore = RecentStoreType
|
||||
};
|
||||
}
|
||||
public RewindConfig GapFiller()
|
||||
{
|
||||
return new RewindConfig
|
||||
{
|
||||
UseCompression = GapsUseCompression,
|
||||
BufferSize = GapsBufferSize,
|
||||
UseFixedRewindInterval = false,
|
||||
TargetFrameLength = GapsTargetFrameLength,
|
||||
BackingStore = GapsStoreType
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,16 @@ namespace BizHawk.Client.Common
|
|||
default:
|
||||
throw new ArgumentException("Unsupported store type for ZwinderBuffer.");
|
||||
}
|
||||
_targetFrameLength = settings.TargetFrameLength;
|
||||
if (settings.UseFixedRewindInterval)
|
||||
{
|
||||
_fixedRewindInterval = true;
|
||||
_targetRewindInterval = settings.TargetRewindInterval;
|
||||
}
|
||||
else
|
||||
{
|
||||
_fixedRewindInterval = false;
|
||||
_targetFrameLength = settings.TargetFrameLength;
|
||||
}
|
||||
_states = new StateInfo[STATEMASK + 1];
|
||||
_useCompression = settings.UseCompression;
|
||||
}
|
||||
|
@ -98,7 +107,9 @@ namespace BizHawk.Client.Common
|
|||
|
||||
private readonly long _sizeMask;
|
||||
|
||||
private readonly bool _fixedRewindInterval;
|
||||
private readonly int _targetFrameLength;
|
||||
private readonly int _targetRewindInterval;
|
||||
|
||||
private struct StateInfo
|
||||
{
|
||||
|
@ -129,6 +140,11 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return 1; // shrug
|
||||
}
|
||||
|
||||
if (_fixedRewindInterval)
|
||||
{
|
||||
return _targetRewindInterval;
|
||||
}
|
||||
|
||||
// assume that the most recent state size is representative of stuff
|
||||
var sizeRatio = Size / (float)_states[HeadStateIndex].Size;
|
||||
|
@ -144,7 +160,8 @@ namespace BizHawk.Client.Common
|
|||
long size = 1L << (int)Math.Floor(Math.Log(targetSize, 2));
|
||||
return Size == size &&
|
||||
_useCompression == settings.UseCompression &&
|
||||
_targetFrameLength == settings.TargetFrameLength &&
|
||||
_fixedRewindInterval == settings.UseFixedRewindInterval &&
|
||||
(_fixedRewindInterval ? _targetRewindInterval == settings.TargetRewindInterval : _targetFrameLength == settings.TargetFrameLength) &&
|
||||
_backingStoreType == settings.BackingStore;
|
||||
}
|
||||
|
||||
|
@ -160,7 +177,7 @@ namespace BizHawk.Client.Common
|
|||
// not much we can say here, so just take a state
|
||||
return true;
|
||||
}
|
||||
return frameDiff >= ComputeIdealRewindInterval();
|
||||
return frameDiff >= ComputeIdealRewindInterval();
|
||||
}
|
||||
|
||||
private bool ShouldCapture(int frame)
|
||||
|
@ -349,7 +366,9 @@ namespace BizHawk.Client.Common
|
|||
ret = new ZwinderBuffer(new RewindConfig
|
||||
{
|
||||
BufferSize = (int)(size >> 20),
|
||||
UseFixedRewindInterval = false,
|
||||
TargetFrameLength = targetFrameLength,
|
||||
TargetRewindInterval = 5,
|
||||
UseCompression = useCompression
|
||||
});
|
||||
if (ret.Size != size || ret._sizeMask != sizeMask)
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
this.labelEx1 = new BizHawk.WinForms.Controls.LabelEx();
|
||||
this.cbDeltaCompression = new System.Windows.Forms.CheckBox();
|
||||
this.TargetFrameLengthNumeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.label2 = new BizHawk.WinForms.Controls.LocLabelEx();
|
||||
this.TargetRewindIntervalNumeric = new System.Windows.Forms.NumericUpDown();
|
||||
this.EstTimeLabel = new BizHawk.WinForms.Controls.LocLabelEx();
|
||||
this.label11 = new BizHawk.WinForms.Controls.LocLabelEx();
|
||||
this.ApproxFramesLabel = new BizHawk.WinForms.Controls.LocLabelEx();
|
||||
|
@ -73,10 +73,13 @@
|
|||
this.label16 = new BizHawk.WinForms.Controls.LocLabelEx();
|
||||
this.BackupSavestatesCheckbox = new System.Windows.Forms.CheckBox();
|
||||
this.label12 = new BizHawk.WinForms.Controls.LocLabelEx();
|
||||
this.TargetFrameLengthRadioButton = new System.Windows.Forms.RadioButton();
|
||||
this.TargetRewindIntervalRadioButton = new System.Windows.Forms.RadioButton();
|
||||
((System.ComponentModel.ISupportInitialize)(this.BufferSizeUpDown)).BeginInit();
|
||||
this.groupBox4.SuspendLayout();
|
||||
this.locSingleRowFLP1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.TargetFrameLengthNumeric)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.TargetRewindIntervalNumeric)).BeginInit();
|
||||
this.groupBox6.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBarCompression)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.nudCompression)).BeginInit();
|
||||
|
@ -120,9 +123,9 @@
|
|||
// UseCompression
|
||||
//
|
||||
this.UseCompression.AutoSize = true;
|
||||
this.UseCompression.Location = new System.Drawing.Point(15, 170);
|
||||
this.UseCompression.Location = new System.Drawing.Point(15, 194);
|
||||
this.UseCompression.Name = "UseCompression";
|
||||
this.UseCompression.Size = new System.Drawing.Size(306, 17);
|
||||
this.UseCompression.Size = new System.Drawing.Size(324, 17);
|
||||
this.UseCompression.TabIndex = 5;
|
||||
this.UseCompression.Text = "Use zlib compression (economizes buffer usage at cost of CPU)";
|
||||
this.UseCompression.UseVisualStyleBackColor = true;
|
||||
|
@ -136,25 +139,25 @@
|
|||
//
|
||||
// BufferSizeUpDown
|
||||
//
|
||||
this.BufferSizeUpDown.Location = new System.Drawing.Point(0, 0);
|
||||
this.BufferSizeUpDown.Location = new System.Drawing.Point(25, 3);
|
||||
this.BufferSizeUpDown.Maximum = new decimal(new int[] {
|
||||
15,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
15,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.BufferSizeUpDown.Minimum = new decimal(new int[] {
|
||||
6,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
6,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.BufferSizeUpDown.Name = "BufferSizeUpDown";
|
||||
this.BufferSizeUpDown.Size = new System.Drawing.Size(52, 20);
|
||||
this.BufferSizeUpDown.TabIndex = 8;
|
||||
this.BufferSizeUpDown.Value = new decimal(new int[] {
|
||||
9,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
9,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.BufferSizeUpDown.ValueChanged += new System.EventHandler(this.BufferSizeUpDown_ValueChanged);
|
||||
//
|
||||
// label3
|
||||
|
@ -189,10 +192,12 @@
|
|||
//
|
||||
// groupBox4
|
||||
//
|
||||
this.groupBox4.Controls.Add(this.TargetRewindIntervalRadioButton);
|
||||
this.groupBox4.Controls.Add(this.TargetFrameLengthRadioButton);
|
||||
this.groupBox4.Controls.Add(this.locSingleRowFLP1);
|
||||
this.groupBox4.Controls.Add(this.cbDeltaCompression);
|
||||
this.groupBox4.Controls.Add(this.TargetFrameLengthNumeric);
|
||||
this.groupBox4.Controls.Add(this.label2);
|
||||
this.groupBox4.Controls.Add(this.TargetRewindIntervalNumeric);
|
||||
this.groupBox4.Controls.Add(this.UseCompression);
|
||||
this.groupBox4.Controls.Add(this.RewindEnabledBox);
|
||||
this.groupBox4.Controls.Add(this.label3);
|
||||
|
@ -208,7 +213,7 @@
|
|||
this.groupBox4.Controls.Add(this.StateSizeLabel);
|
||||
this.groupBox4.Location = new System.Drawing.Point(12, 12);
|
||||
this.groupBox4.Name = "groupBox4";
|
||||
this.groupBox4.Size = new System.Drawing.Size(371, 218);
|
||||
this.groupBox4.Size = new System.Drawing.Size(371, 248);
|
||||
this.groupBox4.TabIndex = 2;
|
||||
this.groupBox4.TabStop = false;
|
||||
this.groupBox4.Text = "RewindSettings";
|
||||
|
@ -244,40 +249,56 @@
|
|||
// cbDeltaCompression
|
||||
//
|
||||
this.cbDeltaCompression.AutoSize = true;
|
||||
this.cbDeltaCompression.Location = new System.Drawing.Point(15, 193);
|
||||
this.cbDeltaCompression.Location = new System.Drawing.Point(15, 217);
|
||||
this.cbDeltaCompression.Name = "cbDeltaCompression";
|
||||
this.cbDeltaCompression.Size = new System.Drawing.Size(149, 17);
|
||||
this.cbDeltaCompression.Size = new System.Drawing.Size(332, 17);
|
||||
this.cbDeltaCompression.TabIndex = 35;
|
||||
this.cbDeltaCompression.Text = "Use delta compression (economizes buffer usage at cost of CPU)";
|
||||
this.cbDeltaCompression.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// TargetFrameLengthNumeric
|
||||
//
|
||||
this.TargetFrameLengthNumeric.Location = new System.Drawing.Point(125, 135);
|
||||
this.TargetFrameLengthNumeric.Location = new System.Drawing.Point(146, 138);
|
||||
this.TargetFrameLengthNumeric.Maximum = new decimal(new int[] {
|
||||
500000,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
500000,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.TargetFrameLengthNumeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.TargetFrameLengthNumeric.Name = "TargetFrameLengthNumeric";
|
||||
this.TargetFrameLengthNumeric.Size = new System.Drawing.Size(52, 20);
|
||||
this.TargetFrameLengthNumeric.TabIndex = 21;
|
||||
this.TargetFrameLengthNumeric.Value = new decimal(new int[] {
|
||||
600,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
600,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// label2
|
||||
// TargetRewindIntervalNumeric
|
||||
//
|
||||
this.label2.Location = new System.Drawing.Point(12, 138);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Text = "Desired frame length:";
|
||||
this.TargetRewindIntervalNumeric.Location = new System.Drawing.Point(231, 162);
|
||||
this.TargetRewindIntervalNumeric.Maximum = new decimal(new int[] {
|
||||
500000,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.TargetRewindIntervalNumeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.TargetRewindIntervalNumeric.Name = "TargetRewindIntervalNumeric";
|
||||
this.TargetRewindIntervalNumeric.Size = new System.Drawing.Size(52, 20);
|
||||
this.TargetRewindIntervalNumeric.TabIndex = 21;
|
||||
this.TargetRewindIntervalNumeric.Value = new decimal(new int[] {
|
||||
5,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// EstTimeLabel
|
||||
//
|
||||
|
@ -365,7 +386,7 @@
|
|||
this.trackBarCompression.Location = new System.Drawing.Point(22, 37);
|
||||
this.trackBarCompression.Maximum = 9;
|
||||
this.trackBarCompression.Name = "trackBarCompression";
|
||||
this.trackBarCompression.Size = new System.Drawing.Size(157, 42);
|
||||
this.trackBarCompression.Size = new System.Drawing.Size(157, 45);
|
||||
this.trackBarCompression.TabIndex = 1;
|
||||
this.toolTip1.SetToolTip(this.trackBarCompression, "0 = None; 9 = Maximum");
|
||||
this.trackBarCompression.Value = 1;
|
||||
|
@ -375,18 +396,18 @@
|
|||
//
|
||||
this.nudCompression.Location = new System.Drawing.Point(185, 37);
|
||||
this.nudCompression.Maximum = new decimal(new int[] {
|
||||
9,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
9,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudCompression.Name = "nudCompression";
|
||||
this.nudCompression.Size = new System.Drawing.Size(52, 20);
|
||||
this.nudCompression.TabIndex = 2;
|
||||
this.nudCompression.Value = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudCompression.ValueChanged += new System.EventHandler(this.NudCompression_ValueChanged);
|
||||
//
|
||||
// groupBox7
|
||||
|
@ -429,23 +450,23 @@
|
|||
//
|
||||
this.BigScreenshotNumeric.Location = new System.Drawing.Point(212, 267);
|
||||
this.BigScreenshotNumeric.Maximum = new decimal(new int[] {
|
||||
8192,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
8192,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.BigScreenshotNumeric.Minimum = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.BigScreenshotNumeric.Name = "BigScreenshotNumeric";
|
||||
this.BigScreenshotNumeric.Size = new System.Drawing.Size(58, 20);
|
||||
this.BigScreenshotNumeric.TabIndex = 32;
|
||||
this.BigScreenshotNumeric.Value = new decimal(new int[] {
|
||||
128,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
128,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// LowResLargeScreenshotsCheckbox
|
||||
//
|
||||
|
@ -508,6 +529,28 @@
|
|||
this.label12.Name = "label12";
|
||||
this.label12.Text = "Compression Level";
|
||||
//
|
||||
// TargetFrameLengthRadioButton
|
||||
//
|
||||
this.TargetFrameLengthRadioButton.AutoSize = true;
|
||||
this.TargetFrameLengthRadioButton.Location = new System.Drawing.Point(15, 138);
|
||||
this.TargetFrameLengthRadioButton.Name = "TargetFrameLengthRadioButton";
|
||||
this.TargetFrameLengthRadioButton.Size = new System.Drawing.Size(125, 17);
|
||||
this.TargetFrameLengthRadioButton.TabIndex = 48;
|
||||
this.TargetFrameLengthRadioButton.TabStop = true;
|
||||
this.TargetFrameLengthRadioButton.Text = "Desired frame length:";
|
||||
this.TargetFrameLengthRadioButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// TargetRewindIntervalRadioButton
|
||||
//
|
||||
this.TargetRewindIntervalRadioButton.AutoSize = true;
|
||||
this.TargetRewindIntervalRadioButton.Location = new System.Drawing.Point(15, 162);
|
||||
this.TargetRewindIntervalRadioButton.Name = "TargetRewindIntervalRadioButton";
|
||||
this.TargetRewindIntervalRadioButton.Size = new System.Drawing.Size(210, 17);
|
||||
this.TargetRewindIntervalRadioButton.TabIndex = 49;
|
||||
this.TargetRewindIntervalRadioButton.TabStop = true;
|
||||
this.TargetRewindIntervalRadioButton.Text = "Rewinds every fixed number of frames: ";
|
||||
this.TargetRewindIntervalRadioButton.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// RewindConfig
|
||||
//
|
||||
this.AcceptButton = this.OK;
|
||||
|
@ -532,6 +575,7 @@
|
|||
this.locSingleRowFLP1.ResumeLayout(false);
|
||||
this.locSingleRowFLP1.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.TargetFrameLengthNumeric)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.TargetRewindIntervalNumeric)).EndInit();
|
||||
this.groupBox6.ResumeLayout(false);
|
||||
this.groupBox6.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.trackBarCompression)).EndInit();
|
||||
|
@ -583,11 +627,13 @@
|
|||
private System.Windows.Forms.CheckBox BackupSavestatesCheckbox;
|
||||
private BizHawk.WinForms.Controls.LocLabelEx label20;
|
||||
private System.Windows.Forms.NumericUpDown TargetFrameLengthNumeric;
|
||||
private BizHawk.WinForms.Controls.LocLabelEx label2;
|
||||
private System.Windows.Forms.NumericUpDown TargetRewindIntervalNumeric;
|
||||
private System.Windows.Forms.CheckBox cbDeltaCompression;
|
||||
private WinForms.Controls.LocSingleRowFLP locSingleRowFLP1;
|
||||
private WinForms.Controls.LabelEx labelEx3;
|
||||
private WinForms.Controls.LabelEx labelEx2;
|
||||
private WinForms.Controls.LabelEx labelEx1;
|
||||
private System.Windows.Forms.RadioButton TargetFrameLengthRadioButton;
|
||||
private System.Windows.Forms.RadioButton TargetRewindIntervalRadioButton;
|
||||
}
|
||||
}
|
|
@ -49,7 +49,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
UseCompression.Checked = _config.Rewind.UseCompression;
|
||||
cbDeltaCompression.Checked = _config.Rewind.UseDelta;
|
||||
BufferSizeUpDown.Value = Math.Max((decimal) Math.Log(_config.Rewind.BufferSize, 2), BufferSizeUpDown.Minimum);
|
||||
TargetFrameLengthRadioButton.Checked = !_config.Rewind.UseFixedRewindInterval;
|
||||
TargetRewindIntervalRadioButton.Checked = _config.Rewind.UseFixedRewindInterval;
|
||||
TargetFrameLengthNumeric.Value = Math.Max(_config.Rewind.TargetFrameLength, TargetFrameLengthNumeric.Minimum);
|
||||
TargetRewindIntervalNumeric.Value = Math.Max(_config.Rewind.TargetRewindInterval, TargetRewindIntervalNumeric.Minimum);
|
||||
StateSizeLabel.Text = FormatKB(_avgStateSize);
|
||||
CalculateEstimates();
|
||||
|
||||
|
@ -111,7 +114,9 @@ namespace BizHawk.Client.EmuHawk
|
|||
_config.Rewind.UseCompression = PutRewindSetting(_config.Rewind.UseCompression, UseCompression.Checked);
|
||||
_config.Rewind.Enabled = PutRewindSetting(_config.Rewind.Enabled, RewindEnabledBox.Checked);
|
||||
_config.Rewind.BufferSize = PutRewindSetting(_config.Rewind.BufferSize, 1L << (int) BufferSizeUpDown.Value);
|
||||
_config.Rewind.UseFixedRewindInterval = PutRewindSetting(_config.Rewind.UseFixedRewindInterval, TargetRewindIntervalRadioButton.Checked);
|
||||
_config.Rewind.TargetFrameLength = PutRewindSetting(_config.Rewind.TargetFrameLength, (int)TargetFrameLengthNumeric.Value);
|
||||
_config.Rewind.TargetRewindInterval = PutRewindSetting(_config.Rewind.TargetRewindInterval, (int)TargetRewindIntervalNumeric.Value);
|
||||
_config.Rewind.UseDelta = PutRewindSetting(_config.Rewind.UseDelta, cbDeltaCompression.Checked);
|
||||
|
||||
// These settings are not used by DoRewindSettings
|
||||
|
|
Loading…
Reference in New Issue