A round of code cleanup on Rewind and some other misc things in Client.Common
This commit is contained in:
parent
134783ff36
commit
16f7c7fcdc
BizHawk.Client.Common
|
@ -1,4 +1,5 @@
|
|||
using System.Collections;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
@ -7,8 +8,8 @@ namespace BizHawk.Client.Common
|
|||
[Newtonsoft.Json.JsonObject]
|
||||
public class RecentFiles : IEnumerable
|
||||
{
|
||||
public int MAX_RECENT_FILES { get; private set; } //Maximum number of files
|
||||
public List<string> recentlist { get; private set; } //List of recent files
|
||||
public int MAX_RECENT_FILES { get; private set; } // Maximum number of files
|
||||
public List<string> recentlist { get; private set; } // List of recent files
|
||||
|
||||
public bool AutoLoad = false;
|
||||
|
||||
|
@ -46,13 +47,14 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public void Add(string newFile)
|
||||
{
|
||||
for (int x = 0; x < recentlist.Count; x++)
|
||||
for (int i = 0; i < recentlist.Count; i++)
|
||||
{
|
||||
if (string.Compare(newFile, recentlist[x]) == 0)
|
||||
if (String.Compare(newFile, recentlist[i], StringComparison.CurrentCultureIgnoreCase) == 0)
|
||||
{
|
||||
recentlist.Remove(newFile); //intentionally keeps iterating after this to remove duplicate instances, though those should never exist in the first place
|
||||
recentlist.Remove(newFile); // intentionally keeps iterating after this to remove duplicate instances, though those should never exist in the first place
|
||||
}
|
||||
}
|
||||
|
||||
recentlist.Insert(0, newFile);
|
||||
if (recentlist.Count > MAX_RECENT_FILES)
|
||||
{
|
||||
|
@ -62,15 +64,16 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public bool Remove(string newFile)
|
||||
{
|
||||
bool removed = false;
|
||||
for (int x = 0; x < recentlist.Count; x++)
|
||||
var removed = false;
|
||||
for (int i = 0; i < recentlist.Count; i++)
|
||||
{
|
||||
if (string.Compare(newFile, recentlist[x]) == 0)
|
||||
if (String.Compare(newFile, recentlist[i], StringComparison.CurrentCultureIgnoreCase) == 0)
|
||||
{
|
||||
recentlist.Remove(newFile); //intentionally keeps iterating after this to remove duplicate instances, though those should never exist in the first place
|
||||
recentlist.Remove(newFile); // intentionally keeps iterating after this to remove duplicate instances, though those should never exist in the first place
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
|
||||
return removed;
|
||||
}
|
||||
|
||||
|
@ -89,7 +92,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public bool Deterministic { get; private set; }
|
||||
|
||||
public class RomErrorArgs
|
||||
public class RomErrorArgs : EventArgs
|
||||
{
|
||||
// TODO: think about naming here, what to pass, a lot of potential good information about what went wrong could go here!
|
||||
public RomErrorArgs(string message, string systemId)
|
||||
|
@ -78,7 +78,7 @@ namespace BizHawk.Client.Common
|
|||
public string AttemptedCoreLoad { get; private set; }
|
||||
}
|
||||
|
||||
public class SettingsLoadArgs
|
||||
public class SettingsLoadArgs : EventArgs
|
||||
{
|
||||
public object Settings { get; set; }
|
||||
public Type Core { get; private set; }
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
|
@ -13,10 +13,11 @@ namespace BizHawk.Client.Common
|
|||
// which will kill N64 for sure...
|
||||
public static bool IsThreaded = false;
|
||||
|
||||
private readonly ConcurrentQueue<Job> Jobs = new ConcurrentQueue<Job>();
|
||||
private EventWaitHandle _ewh, _ewh2;
|
||||
private Thread _thread;
|
||||
private Rewinder _rewinder;
|
||||
private readonly ConcurrentQueue<Job> _jobs = new ConcurrentQueue<Job>();
|
||||
private readonly EventWaitHandle _ewh;
|
||||
private readonly EventWaitHandle _ewh2;
|
||||
private readonly Thread _thread;
|
||||
private readonly Rewinder _rewinder;
|
||||
|
||||
public RewindThreader(Rewinder rewinder, bool isThreaded)
|
||||
{
|
||||
|
@ -27,8 +28,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_ewh = new EventWaitHandle(false, EventResetMode.AutoReset);
|
||||
_ewh2 = new EventWaitHandle(false, EventResetMode.AutoReset);
|
||||
_thread = new Thread(ThreadProc);
|
||||
_thread.IsBackground = true;
|
||||
_thread = new Thread(ThreadProc) { IsBackground = true };
|
||||
_thread.Start();
|
||||
}
|
||||
}
|
||||
|
@ -40,9 +40,8 @@ namespace BizHawk.Client.Common
|
|||
return;
|
||||
}
|
||||
|
||||
var job = new Job();
|
||||
job.Type = JobType.Abort;
|
||||
Jobs.Enqueue(job);
|
||||
var job = new Job { Type = JobType.Abort };
|
||||
_jobs.Enqueue(job);
|
||||
_ewh.Set();
|
||||
|
||||
_thread.Join();
|
||||
|
@ -50,15 +49,49 @@ namespace BizHawk.Client.Common
|
|||
_ewh2.Dispose();
|
||||
}
|
||||
|
||||
void ThreadProc()
|
||||
public void Rewind(int frames)
|
||||
{
|
||||
for (; ; )
|
||||
if (!IsThreaded)
|
||||
{
|
||||
_rewinder._RunRewind(frames);
|
||||
return;
|
||||
}
|
||||
|
||||
var job = new Job
|
||||
{
|
||||
Type = JobType.Rewind,
|
||||
Frames = frames
|
||||
};
|
||||
_jobs.Enqueue(job);
|
||||
_ewh.Set();
|
||||
_ewh2.WaitOne();
|
||||
}
|
||||
|
||||
public void Capture(byte[] coreSavestate)
|
||||
{
|
||||
if (!IsThreaded)
|
||||
{
|
||||
_rewinder.RunCapture(coreSavestate);
|
||||
return;
|
||||
}
|
||||
|
||||
var job = new Job
|
||||
{
|
||||
Type = JobType.Capture,
|
||||
CoreState = coreSavestate
|
||||
};
|
||||
DoSafeEnqueue(job);
|
||||
}
|
||||
|
||||
private void ThreadProc()
|
||||
{
|
||||
for (;; )
|
||||
{
|
||||
_ewh.WaitOne();
|
||||
while (Jobs.Count != 0)
|
||||
while (_jobs.Count != 0)
|
||||
{
|
||||
Job job = null;
|
||||
if (Jobs.TryDequeue(out job))
|
||||
Job job;
|
||||
if (_jobs.TryDequeue(out job))
|
||||
{
|
||||
if (job.Type == JobType.Abort)
|
||||
{
|
||||
|
@ -80,59 +113,29 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
public void Rewind(int frames)
|
||||
private void DoSafeEnqueue(Job job)
|
||||
{
|
||||
if (!IsThreaded)
|
||||
{
|
||||
_rewinder._RunRewind(frames);
|
||||
return;
|
||||
}
|
||||
|
||||
var job = new Job();
|
||||
job.Type = JobType.Rewind;
|
||||
job.Frames = frames;
|
||||
Jobs.Enqueue(job);
|
||||
_ewh.Set();
|
||||
_ewh2.WaitOne();
|
||||
}
|
||||
|
||||
void DoSafeEnqueue(Job job)
|
||||
{
|
||||
Jobs.Enqueue(job);
|
||||
_jobs.Enqueue(job);
|
||||
_ewh.Set();
|
||||
|
||||
//just in case... we're getting really behind.. slow it down here
|
||||
//if this gets backed up too much, then the rewind will seem to malfunction since it requires all the captures in the queue to complete first
|
||||
while (Jobs.Count > 15)
|
||||
// just in case... we're getting really behind.. slow it down here
|
||||
// if this gets backed up too much, then the rewind will seem to malfunction since it requires all the captures in the queue to complete first
|
||||
while (_jobs.Count > 15)
|
||||
{
|
||||
Thread.Sleep(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void Capture(byte[] coreSavestate)
|
||||
{
|
||||
if (!IsThreaded)
|
||||
{
|
||||
_rewinder.RunCapture(coreSavestate);
|
||||
return;
|
||||
}
|
||||
|
||||
var job = new Job();
|
||||
job.Type = JobType.Capture;
|
||||
job.CoreState = coreSavestate;
|
||||
DoSafeEnqueue(job);
|
||||
}
|
||||
|
||||
private enum JobType
|
||||
{
|
||||
Capture, Rewind, Abort
|
||||
}
|
||||
|
||||
private class Job
|
||||
private sealed class Job
|
||||
{
|
||||
public JobType Type;
|
||||
public byte[] CoreState;
|
||||
public int Frames;
|
||||
public JobType Type { get; set; }
|
||||
public byte[] CoreState { get; set; }
|
||||
public int Frames { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,79 +5,81 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
public class Rewinder
|
||||
{
|
||||
public bool RewindActive = true;
|
||||
public Rewinder()
|
||||
{
|
||||
RewindActive = true;
|
||||
}
|
||||
|
||||
private StreamBlobDatabase RewindBuffer;
|
||||
private RewindThreader RewindThread;
|
||||
private byte[] LastState;
|
||||
private bool RewindImpossible;
|
||||
private int RewindFrequency = 1;
|
||||
private bool RewindDeltaEnable = false;
|
||||
private byte[] RewindFellationBuf;
|
||||
private byte[] TempBuf = new byte[0];
|
||||
private StreamBlobDatabase _rewindBuffer;
|
||||
private RewindThreader _rewindThread;
|
||||
private byte[] _lastState;
|
||||
private bool _rewindImpossible;
|
||||
private int _rewindFrequency = 1;
|
||||
private bool _rewindDeltaEnable;
|
||||
private byte[] _rewindFellationBuf;
|
||||
private byte[] _tempBuf = new byte[0];
|
||||
|
||||
public Action<string> MessageCallback;
|
||||
public Action<string> MessageCallback { get; set; }
|
||||
public bool RewindActive { get; set; }
|
||||
|
||||
// TODO: make RewindBuf never be null
|
||||
public float FullnessRatio
|
||||
{
|
||||
get { return RewindBuffer.FullnessRatio; }
|
||||
get { return _rewindBuffer.FullnessRatio; }
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get { return RewindBuffer != null ? RewindBuffer.Count : 0; }
|
||||
get { return _rewindBuffer != null ? _rewindBuffer.Count : 0; }
|
||||
}
|
||||
|
||||
public long Size
|
||||
{
|
||||
get { return RewindBuffer != null ? RewindBuffer.Size : 0; }
|
||||
get { return _rewindBuffer != null ? _rewindBuffer.Size : 0; }
|
||||
}
|
||||
|
||||
public int BufferCount
|
||||
{
|
||||
get { return RewindBuffer != null ? RewindBuffer.Count : 0; }
|
||||
get { return _rewindBuffer != null ? _rewindBuffer.Count : 0; }
|
||||
}
|
||||
|
||||
public bool HasBuffer
|
||||
{
|
||||
get { return RewindBuffer != null; }
|
||||
get { return _rewindBuffer != null; }
|
||||
}
|
||||
|
||||
// TOOD: this should not be parameterless?! It is only possible due to passing a static context in
|
||||
public void CaptureRewindState()
|
||||
{
|
||||
if (RewindImpossible)
|
||||
if (_rewindImpossible)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (LastState == null)
|
||||
if (_lastState == null)
|
||||
{
|
||||
DoRewindSettings();
|
||||
}
|
||||
|
||||
|
||||
//log a frame
|
||||
if (LastState != null && Global.Emulator.Frame % RewindFrequency == 0)
|
||||
// log a frame
|
||||
if (_lastState != null && Global.Emulator.Frame % _rewindFrequency == 0)
|
||||
{
|
||||
byte[] CurrentState = Global.Emulator.SaveStateBinary();
|
||||
RewindThread.Capture(CurrentState);
|
||||
_rewindThread.Capture(Global.Emulator.SaveStateBinary());
|
||||
}
|
||||
}
|
||||
|
||||
public void DoRewindSettings()
|
||||
{
|
||||
// This is the first frame. Capture the state, and put it in LastState for future deltas to be compared against.
|
||||
LastState = (byte[])Global.Emulator.SaveStateBinary().Clone();
|
||||
_lastState = (byte[])Global.Emulator.SaveStateBinary().Clone();
|
||||
|
||||
int state_size = 0;
|
||||
if (LastState.Length >= Global.Config.Rewind_LargeStateSize)
|
||||
int state_size;
|
||||
if (_lastState.Length >= Global.Config.Rewind_LargeStateSize)
|
||||
{
|
||||
SetRewindParams(Global.Config.RewindEnabledLarge, Global.Config.RewindFrequencyLarge);
|
||||
state_size = 3;
|
||||
}
|
||||
else if (LastState.Length >= Global.Config.Rewind_MediumStateSize)
|
||||
else if (_lastState.Length >= Global.Config.Rewind_MediumStateSize)
|
||||
{
|
||||
SetRewindParams(Global.Config.RewindEnabledMedium, Global.Config.RewindFrequencyMedium);
|
||||
state_size = 2;
|
||||
|
@ -88,7 +90,7 @@ namespace BizHawk.Client.Common
|
|||
state_size = 1;
|
||||
}
|
||||
|
||||
bool rewind_enabled = false;
|
||||
var rewind_enabled = false;
|
||||
if (state_size == 1)
|
||||
{
|
||||
rewind_enabled = Global.Config.RewindEnabledSmall;
|
||||
|
@ -102,31 +104,31 @@ namespace BizHawk.Client.Common
|
|||
rewind_enabled = Global.Config.RewindEnabledLarge;
|
||||
}
|
||||
|
||||
RewindDeltaEnable = Global.Config.Rewind_UseDelta;
|
||||
_rewindDeltaEnable = Global.Config.Rewind_UseDelta;
|
||||
|
||||
if (rewind_enabled)
|
||||
{
|
||||
long cap = Global.Config.Rewind_BufferSize * (long)1024 * (long)1024;
|
||||
var cap = Global.Config.Rewind_BufferSize * (long)1024 * 1024;
|
||||
|
||||
if (RewindBuffer != null)
|
||||
if (_rewindBuffer != null)
|
||||
{
|
||||
RewindBuffer.Dispose();
|
||||
_rewindBuffer.Dispose();
|
||||
}
|
||||
|
||||
RewindBuffer = new StreamBlobDatabase(Global.Config.Rewind_OnDisk, cap, BufferManage);
|
||||
_rewindBuffer = new StreamBlobDatabase(Global.Config.Rewind_OnDisk, cap, BufferManage);
|
||||
|
||||
if (RewindThread != null)
|
||||
if (_rewindThread != null)
|
||||
{
|
||||
RewindThread.Dispose();
|
||||
_rewindThread.Dispose();
|
||||
}
|
||||
|
||||
RewindThread = new RewindThreader(this, Global.Config.Rewind_IsThreaded);
|
||||
_rewindThread = new RewindThreader(this, Global.Config.Rewind_IsThreaded);
|
||||
}
|
||||
}
|
||||
|
||||
public void Rewind(int frames)
|
||||
{
|
||||
RewindThread.Rewind(frames);
|
||||
_rewindThread.Rewind(frames);
|
||||
}
|
||||
|
||||
// TODO remove me
|
||||
|
@ -134,12 +136,12 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
for (int i = 0; i < frames; i++)
|
||||
{
|
||||
if (RewindBuffer.Count == 0 || (Global.MovieSession.Movie.IsActive && Global.MovieSession.Movie.InputLogLength == 0))
|
||||
if (_rewindBuffer.Count == 0 || (Global.MovieSession.Movie.IsActive && Global.MovieSession.Movie.InputLogLength == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (LastState.Length < 0x10000)
|
||||
if (_lastState.Length < 0x10000)
|
||||
{
|
||||
Rewind64K();
|
||||
}
|
||||
|
@ -153,16 +155,9 @@ namespace BizHawk.Client.Common
|
|||
// TODO: only run by RewindThreader, refactor
|
||||
public void RunCapture(byte[] coreSavestate)
|
||||
{
|
||||
if (RewindDeltaEnable)
|
||||
if (_rewindDeltaEnable)
|
||||
{
|
||||
if (LastState.Length <= 0x10000)
|
||||
{
|
||||
CaptureRewindStateDelta(coreSavestate, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
CaptureRewindStateDelta(coreSavestate, false);
|
||||
}
|
||||
CaptureRewindStateDelta(coreSavestate, _lastState.Length <= 0x10000);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -172,13 +167,13 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public void ResetRewindBuffer()
|
||||
{
|
||||
if (RewindBuffer != null)
|
||||
if (_rewindBuffer != null)
|
||||
{
|
||||
RewindBuffer.Clear();
|
||||
_rewindBuffer.Clear();
|
||||
}
|
||||
|
||||
RewindImpossible = false;
|
||||
LastState = null;
|
||||
_rewindImpossible = false;
|
||||
_lastState = null;
|
||||
}
|
||||
|
||||
private void DoMessage(string message)
|
||||
|
@ -196,17 +191,17 @@ namespace BizHawk.Client.Common
|
|||
DoMessage("Rewind " + (enabled ? "Enabled" : "Disabled"));
|
||||
}
|
||||
|
||||
if (RewindFrequency != frequency && enabled)
|
||||
if (_rewindFrequency != frequency && enabled)
|
||||
{
|
||||
DoMessage("Rewind frequency set to " + frequency);
|
||||
}
|
||||
|
||||
RewindActive = enabled;
|
||||
RewindFrequency = frequency;
|
||||
_rewindFrequency = frequency;
|
||||
|
||||
if (!RewindActive)
|
||||
{
|
||||
LastState = null;
|
||||
_lastState = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,69 +209,69 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
if (allocate)
|
||||
{
|
||||
//if we have an appropriate buffer free, return it
|
||||
if (RewindFellationBuf != null && RewindFellationBuf.LongLength == size)
|
||||
// if we have an appropriate buffer free, return it
|
||||
if (_rewindFellationBuf != null && _rewindFellationBuf.LongLength == size)
|
||||
{
|
||||
byte[] ret = RewindFellationBuf;
|
||||
RewindFellationBuf = null;
|
||||
var ret = _rewindFellationBuf;
|
||||
_rewindFellationBuf = null;
|
||||
return ret;
|
||||
}
|
||||
//otherwise, allocate it
|
||||
|
||||
// otherwise, allocate it
|
||||
return new byte[size];
|
||||
}
|
||||
else
|
||||
{
|
||||
RewindFellationBuf = inbuf;
|
||||
_rewindFellationBuf = inbuf;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void CaptureRewindStateNonDelta(byte[] CurrentState)
|
||||
private void CaptureRewindStateNonDelta(byte[] currentState)
|
||||
{
|
||||
long offset = RewindBuffer.Enqueue(0, CurrentState.Length + 1);
|
||||
Stream stream = RewindBuffer.Stream;
|
||||
long offset = _rewindBuffer.Enqueue(0, currentState.Length + 1);
|
||||
var stream = _rewindBuffer.Stream;
|
||||
stream.Position = offset;
|
||||
|
||||
//write the header for a non-delta frame
|
||||
stream.WriteByte(1); //i.e. true
|
||||
stream.Write(CurrentState, 0, CurrentState.Length);
|
||||
// write the header for a non-delta frame
|
||||
stream.WriteByte(1); // i.e. true
|
||||
stream.Write(currentState, 0, currentState.Length);
|
||||
}
|
||||
|
||||
private void CaptureRewindStateDelta(byte[] CurrentState, bool isSmall)
|
||||
private void CaptureRewindStateDelta(byte[] currentState, bool isSmall)
|
||||
{
|
||||
//in case the state sizes mismatch, capture a full state rather than trying to do anything clever
|
||||
if (CurrentState.Length != LastState.Length)
|
||||
// in case the state sizes mismatch, capture a full state rather than trying to do anything clever
|
||||
if (currentState.Length != _lastState.Length)
|
||||
{
|
||||
CaptureRewindStateNonDelta(CurrentState);
|
||||
CaptureRewindStateNonDelta(currentState);
|
||||
return;
|
||||
}
|
||||
|
||||
int beginChangeSequence = -1;
|
||||
bool inChangeSequence = false;
|
||||
MemoryStream ms;
|
||||
var beginChangeSequence = -1;
|
||||
var inChangeSequence = false;
|
||||
|
||||
// try to set up the buffer in advance so we dont ever have exceptions in here
|
||||
if (TempBuf.Length < CurrentState.Length)
|
||||
if (_tempBuf.Length < currentState.Length)
|
||||
{
|
||||
TempBuf = new byte[CurrentState.Length * 2];
|
||||
_tempBuf = new byte[currentState.Length * 2];
|
||||
}
|
||||
|
||||
ms = new MemoryStream(TempBuf, 0, TempBuf.Length, true, true);
|
||||
var ms = new MemoryStream(_tempBuf, 0, _tempBuf.Length, true, true);
|
||||
RETRY:
|
||||
try
|
||||
{
|
||||
var writer = new BinaryWriter(ms);
|
||||
writer.Write(false); // delta state
|
||||
for (int i = 0; i < CurrentState.Length; i++)
|
||||
for (int i = 0; i < currentState.Length; i++)
|
||||
{
|
||||
if (inChangeSequence == false)
|
||||
{
|
||||
if (i >= LastState.Length)
|
||||
if (i >= _lastState.Length)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CurrentState[i] == LastState[i])
|
||||
if (currentState[i] == _lastState[i])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -286,7 +281,7 @@ namespace BizHawk.Client.Common
|
|||
continue;
|
||||
}
|
||||
|
||||
if (i - beginChangeSequence == 254 || i == CurrentState.Length - 1)
|
||||
if (i - beginChangeSequence == 254 || i == currentState.Length - 1)
|
||||
{
|
||||
writer.Write((byte)(i - beginChangeSequence + 1));
|
||||
if (isSmall)
|
||||
|
@ -298,12 +293,12 @@ namespace BizHawk.Client.Common
|
|||
writer.Write(beginChangeSequence);
|
||||
}
|
||||
|
||||
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence + 1);
|
||||
writer.Write(_lastState, beginChangeSequence, i - beginChangeSequence + 1);
|
||||
inChangeSequence = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CurrentState[i] == LastState[i])
|
||||
if (currentState[i] == _lastState[i])
|
||||
{
|
||||
writer.Write((byte)(i - beginChangeSequence));
|
||||
if (isSmall)
|
||||
|
@ -315,30 +310,30 @@ namespace BizHawk.Client.Common
|
|||
writer.Write(beginChangeSequence);
|
||||
}
|
||||
|
||||
writer.Write(LastState, beginChangeSequence, i - beginChangeSequence);
|
||||
writer.Write(_lastState, beginChangeSequence, i - beginChangeSequence);
|
||||
inChangeSequence = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NotSupportedException)
|
||||
{
|
||||
//ok... we had an exception after all
|
||||
//if we did actually run out of room in the memorystream, then try it again with a bigger buffer
|
||||
TempBuf = new byte[TempBuf.Length * 2];
|
||||
// ok... we had an exception after all
|
||||
// if we did actually run out of room in the memorystream, then try it again with a bigger buffer
|
||||
_tempBuf = new byte[_tempBuf.Length * 2];
|
||||
goto RETRY;
|
||||
}
|
||||
|
||||
if (LastState != null && LastState.Length == CurrentState.Length)
|
||||
if (_lastState != null && _lastState.Length == currentState.Length)
|
||||
{
|
||||
Buffer.BlockCopy(CurrentState, 0, LastState, 0, LastState.Length);
|
||||
Buffer.BlockCopy(currentState, 0, _lastState, 0, _lastState.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
LastState = (byte[])CurrentState.Clone();
|
||||
_lastState = (byte[])currentState.Clone();
|
||||
}
|
||||
|
||||
var seg = new ArraySegment<byte>(TempBuf, 0, (int)ms.Position);
|
||||
RewindBuffer.Push(seg);
|
||||
var seg = new ArraySegment<byte>(_tempBuf, 0, (int)ms.Position);
|
||||
_rewindBuffer.Push(seg);
|
||||
}
|
||||
|
||||
private void RewindLarge()
|
||||
|
@ -353,23 +348,21 @@ namespace BizHawk.Client.Common
|
|||
|
||||
private void RewindDelta(bool isSmall)
|
||||
{
|
||||
var ms = RewindBuffer.PopMemoryStream();
|
||||
var ms = _rewindBuffer.PopMemoryStream();
|
||||
var reader = new BinaryReader(ms);
|
||||
bool fullstate = reader.ReadBoolean();
|
||||
var fullstate = reader.ReadBoolean();
|
||||
if (fullstate)
|
||||
{
|
||||
Global.Emulator.LoadStateBinary(reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
var output = new MemoryStream(LastState);
|
||||
var output = new MemoryStream(_lastState);
|
||||
while (ms.Position < ms.Length - 1)
|
||||
{
|
||||
byte len = reader.ReadByte();
|
||||
int offset;
|
||||
if(isSmall)
|
||||
offset = reader.ReadUInt16();
|
||||
else offset = reader.ReadInt32();
|
||||
var len = reader.ReadByte();
|
||||
int offset = isSmall ? reader.ReadUInt16() : reader.ReadInt32();
|
||||
|
||||
output.Position = offset;
|
||||
output.Write(ms.GetBuffer(), (int)ms.Position, len);
|
||||
ms.Position += len;
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
{
|
||||
|
@ -25,7 +23,7 @@ namespace BizHawk.Client.Common
|
|||
_mCapacity = capacity;
|
||||
if (onDisk)
|
||||
{
|
||||
var path = Path.Combine(System.IO.Path.GetTempPath(), "bizhawk.rewindbuf-pid" + System.Diagnostics.Process.GetCurrentProcess().Id + "-" + Guid.NewGuid().ToString());
|
||||
var path = Path.Combine(Path.GetTempPath(), "bizhawk.rewindbuf-pid" + System.Diagnostics.Process.GetCurrentProcess().Id + "-" + Guid.NewGuid());
|
||||
|
||||
// I checked the DeleteOnClose operation to make sure it cleans up when the process is aborted, and it seems to.
|
||||
// Otherwise we would have a more complex tempfile management problem here.
|
||||
|
@ -40,7 +38,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the amount of the buffer that's used
|
||||
/// Gets the amount of the buffer that's used
|
||||
/// </summary>
|
||||
public long Size { get { return _mSize; } }
|
||||
|
||||
|
@ -50,12 +48,12 @@ namespace BizHawk.Client.Common
|
|||
public float FullnessRatio { get { return (float)((double)Size / (double)_mCapacity); } }
|
||||
|
||||
/// <summary>
|
||||
/// the number of frames stored here
|
||||
/// Gets the number of frames stored here
|
||||
/// </summary>
|
||||
public int Count { get { return _mBookmarks.Count; } }
|
||||
|
||||
/// <summary>
|
||||
/// The underlying stream to
|
||||
/// Gets the underlying stream to
|
||||
/// </summary>
|
||||
public Stream Stream { get { return _mStream; } }
|
||||
|
||||
|
@ -141,7 +139,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
CLEANUP:
|
||||
// while the head impinges on tail items, discard them
|
||||
for (; ; )
|
||||
for (;;)
|
||||
{
|
||||
if (_mTail == null)
|
||||
{
|
||||
|
@ -150,12 +148,15 @@ namespace BizHawk.Client.Common
|
|||
|
||||
if (_mHead.Value.EndExclusive > _mTail.Value.Index && _mHead.Value.Index <= _mTail.Value.Index)
|
||||
{
|
||||
LinkedListNode<ListItem> nextTail = _mTail.Next;
|
||||
var nextTail = _mTail.Next;
|
||||
_mSize -= _mTail.Value.Length;
|
||||
_mBookmarks.Remove(_mTail);
|
||||
_mTail = nextTail;
|
||||
}
|
||||
else break;
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return _mHead.Value.Index;
|
||||
|
@ -177,12 +178,7 @@ namespace BizHawk.Client.Common
|
|||
_mTail = null;
|
||||
}
|
||||
|
||||
_mHead = nextHead;
|
||||
|
||||
if (_mHead == null)
|
||||
{
|
||||
_mHead = _mBookmarks.Last;
|
||||
}
|
||||
_mHead = nextHead ?? _mBookmarks.Last;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -196,18 +192,14 @@ namespace BizHawk.Client.Common
|
|||
|
||||
var ret = _mTail.Value;
|
||||
_mSize -= ret.Length;
|
||||
LinkedListNode<ListItem> nextTail = _mTail.Next;
|
||||
var nextTail = _mTail.Next;
|
||||
_mBookmarks.Remove(_mTail);
|
||||
if (_mTail == _mHead)
|
||||
{
|
||||
_mHead = null;
|
||||
}
|
||||
|
||||
_mTail = nextTail;
|
||||
if (_mTail == null)
|
||||
{
|
||||
_mTail = _mBookmarks.First;
|
||||
}
|
||||
_mTail = nextTail ?? _mBookmarks.First;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -222,7 +214,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
int ts = _mTail.Value.Timestamp;
|
||||
LinkedListNode<ListItem> curr = _mTail;
|
||||
for (; ; )
|
||||
for (;;)
|
||||
{
|
||||
if (curr == null)
|
||||
{
|
||||
|
|
|
@ -18,12 +18,13 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return _changes;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_changes = value;
|
||||
if (value)
|
||||
{
|
||||
CheatChanged(Cheat.Separator); //Pass a dummy, no cheat invoked this change
|
||||
CheatChanged(Cheat.Separator); // Pass a dummy, no cheat invoked this change
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,10 +50,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public void Pulse()
|
||||
{
|
||||
foreach(var cheat in _cheatList)
|
||||
{
|
||||
cheat.Pulse();
|
||||
}
|
||||
_cheatList.ForEach(cheat => cheat.Pulse());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -106,7 +104,6 @@ namespace BizHawk.Client.Common
|
|||
if (cheat.IsSeparator)
|
||||
{
|
||||
_cheatList.Add(cheat);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -115,6 +112,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_cheatList.Remove(Global.CheatList.FirstOrDefault(x => x.Domain == cheat.Domain && x.Address == cheat.Address));
|
||||
}
|
||||
|
||||
_cheatList.Add(cheat);
|
||||
}
|
||||
|
||||
|
@ -138,7 +136,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public bool Remove(Cheat c)
|
||||
{
|
||||
bool result = _cheatList.Remove(c);
|
||||
var result = _cheatList.Remove(c);
|
||||
if (result)
|
||||
{
|
||||
Changes = true;
|
||||
|
@ -152,7 +150,6 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public bool Remove(Watch w)
|
||||
{
|
||||
|
||||
var cheat = _cheatList.FirstOrDefault(x => x.Domain == w.Domain && x.Address == w.Address);
|
||||
if (cheat != null)
|
||||
{
|
||||
|
@ -184,6 +181,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_cheatList.Remove(cheat);
|
||||
}
|
||||
|
||||
Changes = true;
|
||||
}
|
||||
|
||||
|
@ -254,15 +252,15 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
try
|
||||
{
|
||||
FileInfo file = new FileInfo(path);
|
||||
var file = new FileInfo(path);
|
||||
if (file.Directory != null && !file.Directory.Exists)
|
||||
{
|
||||
file.Directory.Create();
|
||||
}
|
||||
|
||||
using (StreamWriter sw = new StreamWriter(path))
|
||||
using (var sw = new StreamWriter(path))
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
var sb = new StringBuilder();
|
||||
|
||||
foreach (var cheat in _cheatList)
|
||||
{
|
||||
|
@ -272,7 +270,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
else
|
||||
{
|
||||
//Set to hex for saving
|
||||
// Set to hex for saving
|
||||
cheat.SetType(Watch.DisplayType.Hex);
|
||||
|
||||
sb
|
||||
|
@ -316,7 +314,7 @@ namespace BizHawk.Client.Common
|
|||
_currentFileName = path;
|
||||
}
|
||||
|
||||
using (StreamReader sr = file.OpenText())
|
||||
using (var sr = file.OpenText())
|
||||
{
|
||||
if (!append)
|
||||
{
|
||||
|
@ -335,15 +333,18 @@ namespace BizHawk.Client.Common
|
|||
else
|
||||
{
|
||||
int? compare;
|
||||
Watch.WatchSize size = Watch.WatchSize.Byte;
|
||||
Watch.DisplayType type = Watch.DisplayType.Hex;
|
||||
bool BIGENDIAN = false;
|
||||
var size = Watch.WatchSize.Byte;
|
||||
var type = Watch.DisplayType.Hex;
|
||||
var bigendian = false;
|
||||
|
||||
if (s.Length < 6)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (s.Length < 6) continue;
|
||||
string[] vals = s.Split('\t');
|
||||
int ADDR = Int32.Parse(vals[0], NumberStyles.HexNumber);
|
||||
int value = Int32.Parse(vals[1], NumberStyles.HexNumber);
|
||||
var vals = s.Split('\t');
|
||||
var address = Int32.Parse(vals[0], NumberStyles.HexNumber);
|
||||
var value = Int32.Parse(vals[1], NumberStyles.HexNumber);
|
||||
|
||||
if (vals[2] == "N")
|
||||
{
|
||||
|
@ -353,28 +354,29 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
compare = Int32.Parse(vals[2], NumberStyles.HexNumber);
|
||||
}
|
||||
MemoryDomain domain = Global.Emulator.MemoryDomains[vals[3]];
|
||||
bool ENABLED = vals[4] == "1";
|
||||
string name = vals[5];
|
||||
|
||||
//For backwards compatibility, don't assume these values exist
|
||||
var domain = Global.Emulator.MemoryDomains[vals[3]];
|
||||
var enabled = vals[4] == "1";
|
||||
var name = vals[5];
|
||||
|
||||
// For backwards compatibility, don't assume these values exist
|
||||
if (vals.Length > 6)
|
||||
{
|
||||
size = Watch.SizeFromChar(vals[6][0]);
|
||||
type = Watch.DisplayTypeFromChar(vals[7][0]);
|
||||
BIGENDIAN = vals[8] == "1";
|
||||
bigendian = vals[8] == "1";
|
||||
}
|
||||
|
||||
Watch w = Watch.GenerateWatch(
|
||||
var watch = Watch.GenerateWatch(
|
||||
domain,
|
||||
ADDR,
|
||||
address,
|
||||
size,
|
||||
type,
|
||||
name,
|
||||
BIGENDIAN
|
||||
bigendian
|
||||
);
|
||||
|
||||
Add(new Cheat(w, value, compare, !Global.Config.DisableCheatsOnLoad && ENABLED));
|
||||
Add(new Cheat(watch, value, compare, !Global.Config.DisableCheatsOnLoad && enabled));
|
||||
}
|
||||
}
|
||||
catch
|
||||
|
@ -412,6 +414,7 @@ namespace BizHawk.Client.Common
|
|||
.ThenBy(x => x.Address ?? 0)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
case ADDRESS:
|
||||
if (reverse)
|
||||
|
@ -428,6 +431,7 @@ namespace BizHawk.Client.Common
|
|||
.ThenBy(x => x.Name)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
case VALUE:
|
||||
if (reverse)
|
||||
|
@ -446,6 +450,7 @@ namespace BizHawk.Client.Common
|
|||
.ThenBy(x => x.Address ?? 0)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
case COMPARE:
|
||||
if (reverse)
|
||||
|
@ -464,6 +469,7 @@ namespace BizHawk.Client.Common
|
|||
.ThenBy(x => x.Address ?? 0)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
case ON:
|
||||
if (reverse)
|
||||
|
@ -482,6 +488,7 @@ namespace BizHawk.Client.Common
|
|||
.ThenBy(x => x.Address ?? 0)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
case DOMAIN:
|
||||
if (reverse)
|
||||
|
@ -500,6 +507,7 @@ namespace BizHawk.Client.Common
|
|||
.ThenBy(x => x.Address ?? 0)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
case SIZE:
|
||||
if (reverse)
|
||||
|
@ -518,6 +526,7 @@ namespace BizHawk.Client.Common
|
|||
.ThenBy(x => x.Address ?? 0)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
case ENDIAN:
|
||||
if (reverse)
|
||||
|
@ -536,6 +545,7 @@ namespace BizHawk.Client.Common
|
|||
.ThenBy(x => x.Address ?? 0)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
case TYPE:
|
||||
if (reverse)
|
||||
|
@ -554,11 +564,12 @@ namespace BizHawk.Client.Common
|
|||
.ThenBy(x => x.Address ?? 0)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public class CheatListEventArgs
|
||||
public class CheatListEventArgs : EventArgs
|
||||
{
|
||||
public CheatListEventArgs(Cheat c)
|
||||
{
|
||||
|
@ -579,6 +590,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
Changed(this, new CheatListEventArgs(sender as Cheat));
|
||||
}
|
||||
|
||||
_changes = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
public class RamSearchEngine
|
||||
{
|
||||
public enum ComparisonOperator { Equal, GreaterThan, GreaterThanEqual, LessThan, LessThanEqual, NotEqual, DifferentBy };
|
||||
public enum ComparisonOperator { Equal, GreaterThan, GreaterThanEqual, LessThan, LessThanEqual, NotEqual, DifferentBy }
|
||||
public enum Compare { Previous, SpecificValue, SpecificAddress, Changes, Difference }
|
||||
|
||||
private int? _differentBy;
|
||||
|
@ -72,14 +72,14 @@ namespace BizHawk.Client.Common
|
|||
case Watch.WatchSize.Word:
|
||||
if (_settings.Mode == Settings.SearchMode.Detailed)
|
||||
{
|
||||
for (int i = 0; i < domain.Size; i += (_settings.CheckMisAligned ? 1 : 2))
|
||||
for (int i = 0; i < domain.Size; i += _settings.CheckMisAligned ? 1 : 2)
|
||||
{
|
||||
_watchList.Add(new MiniWordWatchDetailed(domain, i, _settings.BigEndian));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < domain.Size; i += (_settings.CheckMisAligned ? 1 : 2))
|
||||
for (int i = 0; i < domain.Size; i += _settings.CheckMisAligned ? 1 : 2)
|
||||
{
|
||||
_watchList.Add(new MiniWordWatch(domain, i, _settings.BigEndian));
|
||||
}
|
||||
|
@ -89,14 +89,14 @@ namespace BizHawk.Client.Common
|
|||
case Watch.WatchSize.DWord:
|
||||
if (_settings.Mode == Settings.SearchMode.Detailed)
|
||||
{
|
||||
for (int i = 0; i < domain.Size; i += (_settings.CheckMisAligned ? 1 : 4))
|
||||
for (int i = 0; i < domain.Size; i += _settings.CheckMisAligned ? 1 : 4)
|
||||
{
|
||||
_watchList.Add(new MiniDWordWatchDetailed(domain, i, _settings.BigEndian));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < domain.Size; i += (_settings.CheckMisAligned ? 1 : 4))
|
||||
for (int i = 0; i < domain.Size; i += _settings.CheckMisAligned ? 1 : 4)
|
||||
{
|
||||
_watchList.Add(new MiniDWordWatch(domain, i, _settings.BigEndian));
|
||||
}
|
||||
|
@ -219,7 +219,11 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public Compare CompareTo
|
||||
{
|
||||
get { return _compareTo; }
|
||||
get
|
||||
{
|
||||
return _compareTo;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (CanDoCompareType(value))
|
||||
|
@ -310,7 +314,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
if (_settings.Mode == Settings.SearchMode.Detailed)
|
||||
{
|
||||
foreach (IMiniWatchDetails watch in _watchList.Cast<IMiniWatchDetails>())
|
||||
foreach (var watch in _watchList.Cast<IMiniWatchDetails>())
|
||||
{
|
||||
watch.ClearChangeCount();
|
||||
}
|
||||
|
@ -334,45 +338,66 @@ namespace BizHawk.Client.Common
|
|||
_watchList.Clear();
|
||||
}
|
||||
|
||||
switch(_settings.Size)
|
||||
switch (_settings.Size)
|
||||
{
|
||||
default:
|
||||
case Watch.WatchSize.Byte:
|
||||
if (_settings.Mode == Settings.SearchMode.Detailed)
|
||||
{
|
||||
foreach(var addr in addresses) { _watchList.Add(new MiniByteWatchDetailed(_settings.Domain, addr)); }
|
||||
foreach (var addr in addresses)
|
||||
{
|
||||
_watchList.Add(new MiniByteWatchDetailed(_settings.Domain, addr));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach(var addr in addresses) { _watchList.Add(new MiniByteWatch(_settings.Domain, addr)); }
|
||||
foreach (var addr in addresses)
|
||||
{
|
||||
_watchList.Add(new MiniByteWatch(_settings.Domain, addr));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case Watch.WatchSize.Word:
|
||||
if (_settings.Mode == Settings.SearchMode.Detailed)
|
||||
{
|
||||
foreach (var addr in addresses) { _watchList.Add(new MiniWordWatchDetailed(_settings.Domain, addr, _settings.BigEndian)); }
|
||||
foreach (var addr in addresses)
|
||||
{
|
||||
_watchList.Add(new MiniWordWatchDetailed(_settings.Domain, addr, _settings.BigEndian));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var addr in addresses) { _watchList.Add(new MiniWordWatch(_settings.Domain, addr, _settings.BigEndian)); }
|
||||
foreach (var addr in addresses)
|
||||
{
|
||||
_watchList.Add(new MiniWordWatch(_settings.Domain, addr, _settings.BigEndian));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case Watch.WatchSize.DWord:
|
||||
if (_settings.Mode == Settings.SearchMode.Detailed)
|
||||
{
|
||||
foreach (var addr in addresses) { _watchList.Add(new MiniDWordWatchDetailed(_settings.Domain, addr, _settings.BigEndian)); }
|
||||
foreach (var addr in addresses)
|
||||
{
|
||||
_watchList.Add(new MiniDWordWatchDetailed(_settings.Domain, addr, _settings.BigEndian));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var addr in addresses) { _watchList.Add(new MiniDWordWatch(_settings.Domain, addr, _settings.BigEndian)); }
|
||||
foreach (var addr in addresses)
|
||||
{
|
||||
_watchList.Add(new MiniDWordWatch(_settings.Domain, addr, _settings.BigEndian));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void Sort(string column, bool reverse)
|
||||
{
|
||||
switch(column)
|
||||
switch (column)
|
||||
{
|
||||
case WatchList.ADDRESS:
|
||||
if (reverse)
|
||||
|
@ -383,6 +408,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_watchList = _watchList.OrderBy(x => x.Address).ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
case WatchList.VALUE:
|
||||
if (reverse)
|
||||
|
@ -393,6 +419,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_watchList = _watchList.OrderBy(x => GetValue(x.Address)).ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
case WatchList.PREV:
|
||||
if (reverse)
|
||||
|
@ -403,6 +430,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_watchList = _watchList.OrderBy(x => x.Previous).ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
case WatchList.CHANGES:
|
||||
if (_settings.Mode == Settings.SearchMode.Detailed)
|
||||
|
@ -422,6 +450,7 @@ namespace BizHawk.Client.Common
|
|||
.Cast<IMiniWatch>().ToList();
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case WatchList.DIFF:
|
||||
if (reverse)
|
||||
|
@ -432,6 +461,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_watchList = _watchList.OrderBy(x => (GetValue(x.Address) - x.Previous)).ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -507,7 +537,6 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -523,7 +552,7 @@ namespace BizHawk.Client.Common
|
|||
case ComparisonOperator.NotEqual:
|
||||
return watchList.Where(x => GetValue(x.Address) != _compareValue.Value);
|
||||
case ComparisonOperator.GreaterThan:
|
||||
return watchList.Where(x => GetValue(x.Address) > _compareValue.Value);
|
||||
return watchList.Where(x => GetValue(x.Address) > _compareValue.Value);
|
||||
case ComparisonOperator.GreaterThanEqual:
|
||||
return watchList.Where(x => GetValue(x.Address) >= _compareValue.Value);
|
||||
case ComparisonOperator.LessThan:
|
||||
|
@ -695,6 +724,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return theByte;
|
||||
}
|
||||
|
||||
case Watch.WatchSize.Word:
|
||||
var theWord = _settings.Domain.PeekWord(addr, _settings.BigEndian);
|
||||
if (_settings.Type == Watch.DisplayType.Signed)
|
||||
|
@ -705,6 +735,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return theWord;
|
||||
}
|
||||
|
||||
case Watch.WatchSize.DWord:
|
||||
var theDWord = _settings.Domain.PeekDWord(addr, _settings.BigEndian);
|
||||
if (_settings.Type == Watch.DisplayType.Signed)
|
||||
|
@ -749,7 +780,7 @@ namespace BizHawk.Client.Common
|
|||
void Update(Watch.PreviousType type, MemoryDomain domain, bool bigendian);
|
||||
}
|
||||
|
||||
private class MiniByteWatch : IMiniWatch
|
||||
private sealed class MiniByteWatch : IMiniWatch
|
||||
{
|
||||
public int Address { get; private set; }
|
||||
private byte _previous;
|
||||
|
@ -771,7 +802,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
private class MiniWordWatch : IMiniWatch
|
||||
private sealed class MiniWordWatch : IMiniWatch
|
||||
{
|
||||
public int Address { get; private set; }
|
||||
private ushort _previous;
|
||||
|
@ -793,7 +824,7 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
}
|
||||
|
||||
public class MiniDWordWatch : IMiniWatch
|
||||
public sealed class MiniDWordWatch : IMiniWatch
|
||||
{
|
||||
public int Address { get; private set; }
|
||||
private uint _previous;
|
||||
|
@ -818,8 +849,9 @@ namespace BizHawk.Client.Common
|
|||
private sealed class MiniByteWatchDetailed : IMiniWatch, IMiniWatchDetails
|
||||
{
|
||||
public int Address { get; private set; }
|
||||
|
||||
private byte _previous;
|
||||
int _changecount;
|
||||
private int _changecount;
|
||||
|
||||
public MiniByteWatchDetailed(MemoryDomain domain, int addr)
|
||||
{
|
||||
|
@ -844,7 +876,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public void Update(Watch.PreviousType type, MemoryDomain domain, bool bigendian)
|
||||
{
|
||||
byte value = domain.PeekByte(Address);
|
||||
var value = domain.PeekByte(Address);
|
||||
if (value != Previous)
|
||||
{
|
||||
_changecount++;
|
||||
|
@ -870,8 +902,9 @@ namespace BizHawk.Client.Common
|
|||
private sealed class MiniWordWatchDetailed : IMiniWatch, IMiniWatchDetails
|
||||
{
|
||||
public int Address { get; private set; }
|
||||
|
||||
private ushort _previous;
|
||||
int _changecount;
|
||||
private int _changecount;
|
||||
|
||||
public MiniWordWatchDetailed(MemoryDomain domain, int addr, bool bigEndian)
|
||||
{
|
||||
|
@ -896,11 +929,12 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public void Update(Watch.PreviousType type, MemoryDomain domain, bool bigendian)
|
||||
{
|
||||
ushort value = domain.PeekWord(Address, bigendian);
|
||||
var value = domain.PeekWord(Address, bigendian);
|
||||
if (value != Previous)
|
||||
{
|
||||
_changecount++;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Watch.PreviousType.Original:
|
||||
|
@ -921,8 +955,9 @@ namespace BizHawk.Client.Common
|
|||
public sealed class MiniDWordWatchDetailed : IMiniWatch, IMiniWatchDetails
|
||||
{
|
||||
public int Address { get; private set; }
|
||||
|
||||
private uint _previous;
|
||||
int _changecount;
|
||||
private int _changecount;
|
||||
|
||||
public MiniDWordWatchDetailed(MemoryDomain domain, int addr, bool bigEndian)
|
||||
{
|
||||
|
@ -947,11 +982,12 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public void Update(Watch.PreviousType type, MemoryDomain domain, bool bigendian)
|
||||
{
|
||||
uint value = domain.PeekDWord(Address, bigendian);
|
||||
var value = domain.PeekDWord(Address, bigendian);
|
||||
if (value != Previous)
|
||||
{
|
||||
_changecount++;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case Watch.PreviousType.Original:
|
||||
|
@ -974,15 +1010,15 @@ namespace BizHawk.Client.Common
|
|||
/*Require restart*/
|
||||
public enum SearchMode { Fast, Detailed }
|
||||
|
||||
public SearchMode Mode;
|
||||
public MemoryDomain Domain;
|
||||
public Watch.WatchSize Size;
|
||||
public bool CheckMisAligned;
|
||||
public SearchMode Mode { get; set; }
|
||||
public MemoryDomain Domain { get; set; }
|
||||
public Watch.WatchSize Size { get; set; }
|
||||
public bool CheckMisAligned { get; set; }
|
||||
|
||||
/*Can be changed mid-search*/
|
||||
public Watch.DisplayType Type;
|
||||
public bool BigEndian;
|
||||
public Watch.PreviousType PreviousType;
|
||||
public Watch.DisplayType Type { get; set; }
|
||||
public bool BigEndian { get; set; }
|
||||
public Watch.PreviousType PreviousType { get; set; }
|
||||
|
||||
public Settings()
|
||||
{
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
@ -9,9 +9,9 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
public abstract class Watch
|
||||
{
|
||||
public enum WatchSize { Byte = 1, Word = 2, DWord = 4, Separator = 0 };
|
||||
public enum DisplayType { Separator, Signed, Unsigned, Hex, Binary, FixedPoint_12_4, FixedPoint_20_12, Float };
|
||||
public enum PreviousType { Original = 0, LastSearch = 1, LastFrame = 2, LastChange = 3 };
|
||||
public enum WatchSize { Byte = 1, Word = 2, DWord = 4, Separator = 0 }
|
||||
public enum DisplayType { Separator, Signed, Unsigned, Hex, Binary, FixedPoint_12_4, FixedPoint_20_12, Float }
|
||||
public enum PreviousType { Original = 0, LastSearch = 1, LastFrame = 2, LastChange = 3 }
|
||||
|
||||
public static string DisplayTypeToString(DisplayType type)
|
||||
{
|
||||
|
@ -161,11 +161,11 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
if (_domain != null)
|
||||
{
|
||||
return "X" + IntHelpers.GetNumDigits(_domain.Size - 1).ToString();
|
||||
return "X" + IntHelpers.GetNumDigits(this._domain.Size - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "";
|
||||
return String.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -350,6 +350,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_type = type;
|
||||
}
|
||||
|
||||
_bigEndian = bigEndian;
|
||||
if (notes != null)
|
||||
{
|
||||
|
@ -452,6 +453,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
case DisplayType.Signed:
|
||||
if (InputValidate.IsValidSignedNumber(value))
|
||||
|
@ -462,6 +464,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
case DisplayType.Hex:
|
||||
if (InputValidate.IsValidHexNumber(value))
|
||||
|
@ -472,6 +475,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
case DisplayType.Binary:
|
||||
if (InputValidate.IsValidBinaryNumber(value))
|
||||
|
@ -482,6 +486,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -498,8 +503,8 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
get
|
||||
{
|
||||
string diff = String.Empty;
|
||||
int diffVal = _value - _previous;
|
||||
var diff = String.Empty;
|
||||
var diffVal = _value - _previous;
|
||||
if (diffVal > 0)
|
||||
{
|
||||
diff = "+";
|
||||
|
@ -508,6 +513,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
diff = "-";
|
||||
}
|
||||
|
||||
return diff + FormatValue((byte)(_previous - _value));
|
||||
}
|
||||
}
|
||||
|
@ -526,6 +532,7 @@ namespace BizHawk.Client.Common
|
|||
_previous = _value;
|
||||
_changecount++;
|
||||
}
|
||||
|
||||
break;
|
||||
case PreviousType.LastFrame:
|
||||
_previous = _value;
|
||||
|
@ -534,6 +541,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_changecount++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -554,6 +562,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_type = type;
|
||||
}
|
||||
|
||||
_bigEndian = bigEndian;
|
||||
|
||||
if (notes != null)
|
||||
|
@ -627,7 +636,7 @@ namespace BizHawk.Client.Common
|
|||
case DisplayType.Hex:
|
||||
return val.ToHexString(4);
|
||||
case DisplayType.FixedPoint_12_4:
|
||||
return String.Format("{0:F4}", (val / 16.0));
|
||||
return String.Format("{0:F4}", val / 16.0);
|
||||
case DisplayType.Binary:
|
||||
return Convert.ToString(val, 2).PadLeft(16, '0').Insert(8, " ").Insert(4, " ").Insert(14, " ");
|
||||
}
|
||||
|
@ -649,6 +658,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
case DisplayType.Signed:
|
||||
if (InputValidate.IsValidSignedNumber(value))
|
||||
|
@ -659,6 +669,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
case DisplayType.Hex:
|
||||
if (InputValidate.IsValidHexNumber(value))
|
||||
|
@ -669,6 +680,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
case DisplayType.Binary:
|
||||
if (InputValidate.IsValidBinaryNumber(value))
|
||||
|
@ -679,6 +691,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
case DisplayType.FixedPoint_12_4:
|
||||
if (InputValidate.IsValidFixedPointNumber(value))
|
||||
|
@ -689,8 +702,10 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
PokeWord(val);
|
||||
return true;
|
||||
}
|
||||
|
@ -720,6 +735,7 @@ namespace BizHawk.Client.Common
|
|||
_previous = temp;
|
||||
_changecount++;
|
||||
}
|
||||
|
||||
break;
|
||||
case PreviousType.LastFrame:
|
||||
_previous = _value;
|
||||
|
@ -728,6 +744,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_changecount++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -748,6 +765,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_type = type;
|
||||
}
|
||||
|
||||
_bigEndian = bigEndian;
|
||||
|
||||
if (notes != null)
|
||||
|
@ -823,10 +841,10 @@ namespace BizHawk.Client.Common
|
|||
case DisplayType.Hex:
|
||||
return val.ToHexString(8);
|
||||
case DisplayType.FixedPoint_20_12:
|
||||
return String.Format("{0:0.######}", (val / 4096.0));
|
||||
return String.Format("{0:0.######}", val / 4096.0);
|
||||
case DisplayType.Float:
|
||||
byte[] bytes = BitConverter.GetBytes(val);
|
||||
float _float = BitConverter.ToSingle(bytes, 0);
|
||||
var bytes = BitConverter.GetBytes(val);
|
||||
var _float = BitConverter.ToSingle(bytes, 0);
|
||||
return String.Format("{0:0.######}", _float);
|
||||
}
|
||||
}
|
||||
|
@ -847,6 +865,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
case DisplayType.Signed:
|
||||
if (InputValidate.IsValidSignedNumber(value))
|
||||
|
@ -857,6 +876,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
case DisplayType.Hex:
|
||||
if (InputValidate.IsValidHexNumber(value))
|
||||
|
@ -867,6 +887,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
case DisplayType.FixedPoint_20_12:
|
||||
if (InputValidate.IsValidFixedPointNumber(value))
|
||||
|
@ -877,19 +898,22 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
case DisplayType.Float:
|
||||
if (InputValidate.IsValidDecimalNumber(value))
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(float.Parse(value));
|
||||
var bytes = BitConverter.GetBytes(float.Parse(value));
|
||||
val = BitConverter.ToUInt32(bytes, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
PokeDWord(val);
|
||||
return true;
|
||||
}
|
||||
|
@ -918,6 +942,7 @@ namespace BizHawk.Client.Common
|
|||
_previous = _value;
|
||||
_changecount++;
|
||||
}
|
||||
|
||||
break;
|
||||
case PreviousType.LastFrame:
|
||||
_previous = _value;
|
||||
|
@ -926,6 +951,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
_changecount++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace BizHawk.Client.Common
|
|||
public const string DOMAIN = "DomainColumn";
|
||||
public const string NOTES = "NotesColumn";
|
||||
|
||||
public enum WatchPrevDef { LastSearch, Original, LastFrame, LastChange };
|
||||
public enum WatchPrevDef { LastSearch, Original, LastFrame, LastChange }
|
||||
|
||||
private List<Watch> _watchList = new List<Watch>();
|
||||
private MemoryDomain _domain;
|
||||
|
@ -86,6 +86,7 @@ namespace BizHawk.Client.Common
|
|||
.ThenBy(x => x.BigEndian)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
case VALUE:
|
||||
if (reverse)
|
||||
|
@ -108,8 +109,9 @@ namespace BizHawk.Client.Common
|
|||
.ThenBy(x => x.BigEndian)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
case PREV: //Note: these only work if all entries are detailed objects!
|
||||
case PREV: // Note: these only work if all entries are detailed objects!
|
||||
if (reverse)
|
||||
{
|
||||
_watchList = _watchList
|
||||
|
@ -128,6 +130,7 @@ namespace BizHawk.Client.Common
|
|||
.ThenBy(x => x.Type)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
case DIFF:
|
||||
if (reverse)
|
||||
|
@ -148,6 +151,7 @@ namespace BizHawk.Client.Common
|
|||
.ThenBy(x => x.Type)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
case CHANGES:
|
||||
if (reverse)
|
||||
|
@ -168,6 +172,7 @@ namespace BizHawk.Client.Common
|
|||
.ThenBy(x => x.Type)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
case DOMAIN:
|
||||
if (reverse)
|
||||
|
@ -190,6 +195,7 @@ namespace BizHawk.Client.Common
|
|||
.ThenBy(x => x.BigEndian)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
case NOTES:
|
||||
if (reverse)
|
||||
|
@ -210,6 +216,7 @@ namespace BizHawk.Client.Common
|
|||
.ThenBy(x => x.Type)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +227,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
if (_domain != null)
|
||||
{
|
||||
return "{0:X" + IntHelpers.GetNumDigits(_domain.Size - 1).ToString() + "}";
|
||||
return "{0:X" + IntHelpers.GetNumDigits(this._domain.Size - 1) + "}";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -260,11 +267,12 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public bool Remove(Watch watch)
|
||||
{
|
||||
bool result = _watchList.Remove(watch);
|
||||
var result = _watchList.Remove(watch);
|
||||
if (result)
|
||||
{
|
||||
Changes = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -317,7 +325,7 @@ namespace BizHawk.Client.Common
|
|||
|
||||
public bool Load(string path, bool append)
|
||||
{
|
||||
bool result = LoadFile(path, append);
|
||||
var result = LoadFile(path, append);
|
||||
|
||||
if (result)
|
||||
{
|
||||
|
@ -339,7 +347,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
if (!String.IsNullOrWhiteSpace(CurrentFileName))
|
||||
{
|
||||
LoadFile(CurrentFileName, append:false);
|
||||
LoadFile(CurrentFileName, append: false);
|
||||
Changes = false;
|
||||
}
|
||||
}
|
||||
|
@ -351,22 +359,22 @@ namespace BizHawk.Client.Common
|
|||
return false;
|
||||
}
|
||||
|
||||
using (StreamWriter sw = new StreamWriter(CurrentFileName))
|
||||
using (var sw = new StreamWriter(CurrentFileName))
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
var sb = new StringBuilder();
|
||||
sb
|
||||
.Append("Domain ").AppendLine(_domain.Name)
|
||||
.Append("SystemID ").AppendLine(Global.Emulator.SystemId);
|
||||
|
||||
foreach (Watch w in _watchList)
|
||||
foreach (var watch in _watchList)
|
||||
{
|
||||
sb
|
||||
.Append(String.Format(AddressFormatStr, w.Address ?? 0)).Append('\t')
|
||||
.Append(w.SizeAsChar).Append('\t')
|
||||
.Append(w.TypeAsChar).Append('\t')
|
||||
.Append(w.BigEndian ? '1' : '0').Append('\t')
|
||||
.Append(w.DomainName).Append('\t')
|
||||
.Append(w.Notes)
|
||||
.Append(String.Format(AddressFormatStr, watch.Address ?? 0)).Append('\t')
|
||||
.Append(watch.SizeAsChar).Append('\t')
|
||||
.Append(watch.TypeAsChar).Append('\t')
|
||||
.Append(watch.BigEndian ? '1' : '0').Append('\t')
|
||||
.Append(watch.DomainName).Append('\t')
|
||||
.Append(watch.Notes)
|
||||
.AppendLine();
|
||||
}
|
||||
|
||||
|
@ -393,12 +401,16 @@ namespace BizHawk.Client.Common
|
|||
|
||||
private bool LoadFile(string path, bool append)
|
||||
{
|
||||
string domain = String.Empty;
|
||||
var domain = String.Empty;
|
||||
var file = new FileInfo(path);
|
||||
if (file.Exists == false) return false;
|
||||
bool isBizHawkWatch = true; //Hack to support .wch files from other emulators
|
||||
bool isOldBizHawkWatch = false;
|
||||
using (StreamReader sr = file.OpenText())
|
||||
if (file.Exists == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var isBizHawkWatch = true; // Hack to support .wch files from other emulators
|
||||
var isOldBizHawkWatch = false;
|
||||
using (var sr = file.OpenText())
|
||||
{
|
||||
string line;
|
||||
|
||||
|
@ -409,8 +421,8 @@ namespace BizHawk.Client.Common
|
|||
|
||||
while ((line = sr.ReadLine()) != null)
|
||||
{
|
||||
//.wch files from other emulators start with a number representing the number of watch, that line can be discarded here
|
||||
//Any properly formatted line couldn't possibly be this short anyway, this also takes care of any garbage lines that might be in a file
|
||||
// .wch files from other emulators start with a number representing the number of watch, that line can be discarded here
|
||||
// Any properly formatted line couldn't possibly be this short anyway, this also takes care of any garbage lines that might be in a file
|
||||
if (line.Length < 5)
|
||||
{
|
||||
isBizHawkWatch = false;
|
||||
|
@ -428,38 +440,35 @@ namespace BizHawk.Client.Common
|
|||
continue;
|
||||
}
|
||||
|
||||
int numColumns = StringHelpers.HowMany(line, '\t');
|
||||
var numColumns = StringHelpers.HowMany(line, '\t');
|
||||
int startIndex;
|
||||
if (numColumns == 5)
|
||||
{
|
||||
//If 5, then this is a post 1.0.5 .wch file
|
||||
// If 5, then this is a post 1.0.5 .wch file
|
||||
if (isBizHawkWatch)
|
||||
{
|
||||
//Do nothing here
|
||||
// Do nothing here
|
||||
}
|
||||
else
|
||||
{
|
||||
startIndex = line.IndexOf('\t') + 1;
|
||||
line = line.Substring(startIndex, line.Length - startIndex); //5 digit value representing the watch position number
|
||||
line = line.Substring(startIndex, line.Length - startIndex); // 5 digit value representing the watch position number
|
||||
}
|
||||
}
|
||||
else if (numColumns == 4)
|
||||
{
|
||||
isOldBizHawkWatch = true;
|
||||
}
|
||||
else //4 is 1.0.5 and earlier
|
||||
else // 4 is 1.0.5 and earlier
|
||||
{
|
||||
continue; //If not 4, something is wrong with this line, ignore it
|
||||
continue; // If not 4, something is wrong with this line, ignore it
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Temporary, rename if kept
|
||||
// Temporary, rename if kept
|
||||
int addr;
|
||||
bool bigEndian;
|
||||
MemoryDomain memDomain = Global.Emulator.MemoryDomains.MainMemory;
|
||||
var memDomain = Global.Emulator.MemoryDomains.MainMemory;
|
||||
|
||||
string temp = line.Substring(0, line.IndexOf('\t'));
|
||||
var temp = line.Substring(0, line.IndexOf('\t'));
|
||||
try
|
||||
{
|
||||
addr = Int32.Parse(temp, NumberStyles.HexNumber);
|
||||
|
@ -470,16 +479,15 @@ namespace BizHawk.Client.Common
|
|||
}
|
||||
|
||||
startIndex = line.IndexOf('\t') + 1;
|
||||
line = line.Substring(startIndex, line.Length - startIndex); //Type
|
||||
Watch.WatchSize size = Watch.SizeFromChar(line[0]);
|
||||
|
||||
line = line.Substring(startIndex, line.Length - startIndex); // Type
|
||||
var size = Watch.SizeFromChar(line[0]);
|
||||
|
||||
startIndex = line.IndexOf('\t') + 1;
|
||||
line = line.Substring(startIndex, line.Length - startIndex); //Signed
|
||||
Watch.DisplayType type = Watch.DisplayTypeFromChar(line[0]);
|
||||
line = line.Substring(startIndex, line.Length - startIndex); // Signed
|
||||
var type = Watch.DisplayTypeFromChar(line[0]);
|
||||
|
||||
startIndex = line.IndexOf('\t') + 1;
|
||||
line = line.Substring(startIndex, line.Length - startIndex); //Endian
|
||||
line = line.Substring(startIndex, line.Length - startIndex); // Endian
|
||||
try
|
||||
{
|
||||
startIndex = Int16.Parse(line[0].ToString());
|
||||
|
@ -488,25 +496,19 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
continue;
|
||||
}
|
||||
if (startIndex == 0)
|
||||
{
|
||||
bigEndian = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bigEndian = true;
|
||||
}
|
||||
|
||||
var bigEndian = startIndex != 0;
|
||||
|
||||
if (isBizHawkWatch && !isOldBizHawkWatch)
|
||||
{
|
||||
startIndex = line.IndexOf('\t') + 1;
|
||||
line = line.Substring(startIndex, line.Length - startIndex); //Domain
|
||||
line = line.Substring(startIndex, line.Length - startIndex); // Domain
|
||||
temp = line.Substring(0, line.IndexOf('\t'));
|
||||
memDomain = Global.Emulator.MemoryDomains[temp] ?? Global.Emulator.MemoryDomains.MainMemory;
|
||||
}
|
||||
|
||||
startIndex = line.IndexOf('\t') + 1;
|
||||
string notes = line.Substring(startIndex, line.Length - startIndex);
|
||||
var notes = line.Substring(startIndex, line.Length - startIndex);
|
||||
|
||||
_watchList.Add(
|
||||
Watch.GenerateWatch(
|
||||
|
@ -531,6 +533,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
Changes = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue