2013-09-14 19:07:11 +00:00
|
|
|
|
using System;
|
2013-09-22 01:53:20 +00:00
|
|
|
|
using System.Collections;
|
2013-09-14 19:07:11 +00:00
|
|
|
|
using System.Collections.Generic;
|
2013-09-22 12:50:47 +00:00
|
|
|
|
using System.IO;
|
2013-09-14 19:07:11 +00:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace BizHawk.MultiClient
|
|
|
|
|
{
|
2013-09-25 04:07:41 +00:00
|
|
|
|
public class RamSearchEngine
|
2013-09-14 19:07:11 +00:00
|
|
|
|
{
|
2013-09-21 14:09:37 +00:00
|
|
|
|
public enum ComparisonOperator { Equal, GreaterThan, GreaterThanEqual, LessThan, LessThanEqual, NotEqual, DifferentBy };
|
2013-09-21 23:55:17 +00:00
|
|
|
|
public enum Compare { Previous, SpecificValue, SpecificAddress, Changes, Difference }
|
2013-09-29 18:19:47 +00:00
|
|
|
|
|
|
|
|
|
private int? _differentBy = null;
|
|
|
|
|
private Compare _compareTo = Compare.Previous;
|
|
|
|
|
private long? _compareValue = null;
|
|
|
|
|
private ComparisonOperator _operator = ComparisonOperator.Equal;
|
2013-09-21 14:09:37 +00:00
|
|
|
|
|
2013-09-25 04:07:41 +00:00
|
|
|
|
private List<IMiniWatch> _watchList = new List<IMiniWatch>();
|
2013-09-29 19:41:03 +00:00
|
|
|
|
private Settings _settings = new Settings();
|
2013-09-25 04:07:41 +00:00
|
|
|
|
private WatchHistory _history = new WatchHistory(true);
|
2013-09-26 01:09:08 +00:00
|
|
|
|
private bool _keepHistory = true;
|
2013-09-16 01:24:06 +00:00
|
|
|
|
|
|
|
|
|
public RamSearchEngine(Settings settings)
|
2013-09-14 19:07:11 +00:00
|
|
|
|
{
|
2013-09-29 19:41:03 +00:00
|
|
|
|
_settings.Mode = settings.Mode;
|
|
|
|
|
_settings.Domain = settings.Domain;
|
|
|
|
|
_settings.Size = settings.Size;
|
|
|
|
|
_settings.CheckMisAligned = settings.CheckMisAligned;
|
|
|
|
|
_settings.Type = settings.Type;
|
|
|
|
|
_settings.BigEndian = settings.BigEndian;
|
|
|
|
|
_settings.PreviousType = settings.PreviousType;
|
2013-09-14 19:07:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-22 01:53:20 +00:00
|
|
|
|
#region API
|
2013-09-14 23:30:23 +00:00
|
|
|
|
|
|
|
|
|
public void Start()
|
|
|
|
|
{
|
2013-09-19 23:45:29 +00:00
|
|
|
|
_watchList.Clear();
|
2013-09-25 04:07:41 +00:00
|
|
|
|
_history.Clear();
|
2013-09-19 23:45:29 +00:00
|
|
|
|
switch (_settings.Size)
|
2013-09-14 23:30:23 +00:00
|
|
|
|
{
|
2013-09-19 23:45:29 +00:00
|
|
|
|
default:
|
|
|
|
|
case Watch.WatchSize.Byte:
|
2013-09-20 01:18:55 +00:00
|
|
|
|
if (_settings.Mode == Settings.SearchMode.Detailed)
|
2013-09-19 23:45:29 +00:00
|
|
|
|
{
|
2013-09-20 01:18:55 +00:00
|
|
|
|
for (int i = 0; i < _settings.Domain.Size; i++)
|
|
|
|
|
{
|
|
|
|
|
_watchList.Add(new MiniByteWatchDetailed(_settings.Domain, i));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < _settings.Domain.Size; i++)
|
|
|
|
|
{
|
|
|
|
|
_watchList.Add(new MiniByteWatch(_settings.Domain, i));
|
|
|
|
|
}
|
2013-09-19 23:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Watch.WatchSize.Word:
|
2013-09-20 01:18:55 +00:00
|
|
|
|
if (_settings.Mode == Settings.SearchMode.Detailed)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < _settings.Domain.Size; i += (_settings.CheckMisAligned ? 1 : 2))
|
|
|
|
|
{
|
|
|
|
|
_watchList.Add(new MiniWordWatchDetailed(_settings.Domain, i, _settings.BigEndian));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
2013-09-19 23:45:29 +00:00
|
|
|
|
{
|
2013-09-20 01:18:55 +00:00
|
|
|
|
for (int i = 0; i < _settings.Domain.Size; i += (_settings.CheckMisAligned ? 1 : 2))
|
|
|
|
|
{
|
|
|
|
|
_watchList.Add(new MiniWordWatch(_settings.Domain, i, _settings.BigEndian));
|
|
|
|
|
}
|
2013-09-19 23:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Watch.WatchSize.DWord:
|
2013-09-20 01:18:55 +00:00
|
|
|
|
if (_settings.Mode == Settings.SearchMode.Detailed)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < _settings.Domain.Size; i += (_settings.CheckMisAligned ? 1 : 4))
|
|
|
|
|
{
|
|
|
|
|
_watchList.Add(new MiniDWordWatchDetailed(_settings.Domain, i, _settings.BigEndian));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
2013-09-19 23:45:29 +00:00
|
|
|
|
{
|
2013-09-20 01:18:55 +00:00
|
|
|
|
for (int i = 0; i < _settings.Domain.Size; i += (_settings.CheckMisAligned ? 1 : 4))
|
|
|
|
|
{
|
|
|
|
|
_watchList.Add(new MiniDWordWatch(_settings.Domain, i, _settings.BigEndian));
|
|
|
|
|
}
|
2013-09-19 23:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
2013-09-14 23:30:23 +00:00
|
|
|
|
}
|
2013-09-25 04:07:41 +00:00
|
|
|
|
|
2013-09-26 01:09:08 +00:00
|
|
|
|
if (_keepHistory)
|
|
|
|
|
{
|
|
|
|
|
_history.AddState(_watchList);
|
|
|
|
|
}
|
2013-09-14 23:30:23 +00:00
|
|
|
|
}
|
2013-09-14 19:07:11 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Exposes the current watch state based on index
|
|
|
|
|
/// </summary>
|
|
|
|
|
public Watch this[int index]
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
2013-09-20 01:18:55 +00:00
|
|
|
|
if (_settings.Mode == Settings.SearchMode.Detailed)
|
|
|
|
|
{
|
|
|
|
|
return Watch.GenerateWatch(
|
|
|
|
|
_settings.Domain,
|
|
|
|
|
_watchList[index].Address,
|
|
|
|
|
_settings.Size,
|
|
|
|
|
_settings.Type,
|
|
|
|
|
_settings.BigEndian,
|
|
|
|
|
_watchList[index].Previous,
|
|
|
|
|
(_watchList[index] as IMiniWatchDetails).ChangeCount
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return Watch.GenerateWatch(
|
|
|
|
|
_settings.Domain,
|
|
|
|
|
_watchList[index].Address,
|
|
|
|
|
_settings.Size,
|
|
|
|
|
_settings.Type,
|
|
|
|
|
_settings.BigEndian,
|
|
|
|
|
_watchList[index].Previous,
|
|
|
|
|
0
|
|
|
|
|
);
|
|
|
|
|
}
|
2013-09-14 19:07:11 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-22 01:53:20 +00:00
|
|
|
|
public int DoSearch()
|
2013-09-21 23:55:17 +00:00
|
|
|
|
{
|
2013-09-22 01:53:20 +00:00
|
|
|
|
int before = _watchList.Count;
|
2013-09-25 04:07:41 +00:00
|
|
|
|
|
2013-09-29 18:19:47 +00:00
|
|
|
|
switch (_compareTo)
|
2013-09-21 23:55:17 +00:00
|
|
|
|
{
|
|
|
|
|
default:
|
|
|
|
|
case RamSearchEngine.Compare.Previous:
|
2013-09-25 01:30:27 +00:00
|
|
|
|
_watchList = ComparePrevious(_watchList).ToList();
|
2013-09-21 23:55:17 +00:00
|
|
|
|
break;
|
|
|
|
|
case RamSearchEngine.Compare.SpecificValue:
|
2013-09-25 01:30:27 +00:00
|
|
|
|
_watchList = CompareSpecificValue(_watchList).ToList();
|
2013-09-21 23:55:17 +00:00
|
|
|
|
break;
|
|
|
|
|
case RamSearchEngine.Compare.SpecificAddress:
|
2013-09-25 01:30:27 +00:00
|
|
|
|
_watchList = CompareSpecificAddress(_watchList).ToList();
|
2013-09-21 23:55:17 +00:00
|
|
|
|
break;
|
|
|
|
|
case RamSearchEngine.Compare.Changes:
|
2013-09-25 01:30:27 +00:00
|
|
|
|
_watchList = CompareChanges(_watchList).ToList();
|
2013-09-21 23:55:17 +00:00
|
|
|
|
break;
|
|
|
|
|
case RamSearchEngine.Compare.Difference:
|
2013-09-25 01:30:27 +00:00
|
|
|
|
_watchList = CompareDifference(_watchList).ToList();
|
2013-09-22 17:00:05 +00:00
|
|
|
|
break;
|
2013-09-21 23:55:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (_settings.PreviousType == Watch.PreviousType.LastSearch)
|
|
|
|
|
{
|
2013-09-22 01:53:20 +00:00
|
|
|
|
SetPrevousToCurrent();
|
2013-09-21 23:55:17 +00:00
|
|
|
|
}
|
2013-09-22 01:53:20 +00:00
|
|
|
|
|
2013-09-26 01:09:08 +00:00
|
|
|
|
if (_keepHistory)
|
|
|
|
|
{
|
|
|
|
|
_history.AddState(_watchList);
|
|
|
|
|
}
|
2013-09-25 04:07:41 +00:00
|
|
|
|
|
2013-09-22 01:53:20 +00:00
|
|
|
|
return before - _watchList.Count;
|
2013-09-21 23:55:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-23 16:51:35 +00:00
|
|
|
|
public bool Preview(int address)
|
|
|
|
|
{
|
2013-10-07 01:40:45 +00:00
|
|
|
|
var listOfOne = new List<IMiniWatch>() { _watchList.FirstOrDefault(x => x.Address == address) };
|
2013-09-29 18:19:47 +00:00
|
|
|
|
switch (_compareTo)
|
2013-09-25 01:30:27 +00:00
|
|
|
|
{
|
|
|
|
|
default:
|
|
|
|
|
case RamSearchEngine.Compare.Previous:
|
2013-10-07 01:40:45 +00:00
|
|
|
|
return ComparePrevious(listOfOne).Count() == 0;
|
2013-09-25 01:30:27 +00:00
|
|
|
|
case RamSearchEngine.Compare.SpecificValue:
|
2013-10-07 01:40:45 +00:00
|
|
|
|
return CompareSpecificValue(listOfOne).Count() == 0;
|
2013-09-25 01:30:27 +00:00
|
|
|
|
case RamSearchEngine.Compare.SpecificAddress:
|
2013-10-07 01:40:45 +00:00
|
|
|
|
return CompareSpecificAddress(listOfOne).Count() == 0;
|
2013-09-25 01:30:27 +00:00
|
|
|
|
case RamSearchEngine.Compare.Changes:
|
2013-10-07 01:40:45 +00:00
|
|
|
|
return CompareChanges(listOfOne).Count() == 0;
|
2013-09-25 01:30:27 +00:00
|
|
|
|
case RamSearchEngine.Compare.Difference:
|
2013-10-07 01:40:45 +00:00
|
|
|
|
return CompareDifference(listOfOne).Count() == 0;
|
2013-09-25 01:30:27 +00:00
|
|
|
|
}
|
2013-09-23 16:51:35 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-14 19:07:11 +00:00
|
|
|
|
public int Count
|
|
|
|
|
{
|
2013-09-21 14:09:37 +00:00
|
|
|
|
get { return _watchList.Count; }
|
2013-09-14 19:07:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-29 19:41:03 +00:00
|
|
|
|
public Settings.SearchMode Mode { get { return _settings.Mode; } }
|
|
|
|
|
|
2013-09-29 16:09:48 +00:00
|
|
|
|
public MemoryDomain Domain
|
2013-09-14 19:07:11 +00:00
|
|
|
|
{
|
2013-09-29 16:09:48 +00:00
|
|
|
|
get { return _settings.Domain; }
|
2013-09-14 19:07:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-29 18:19:47 +00:00
|
|
|
|
public Compare CompareTo
|
|
|
|
|
{
|
|
|
|
|
get { return _compareTo; }
|
2013-09-29 18:52:11 +00:00
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
if (CanDoCompareType(value))
|
|
|
|
|
{
|
|
|
|
|
_compareTo = value;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-09-29 18:19:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public long? CompareValue
|
|
|
|
|
{
|
|
|
|
|
get { return _compareValue; }
|
|
|
|
|
set { _compareValue = value; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ComparisonOperator Operator
|
|
|
|
|
{
|
|
|
|
|
get { return _operator; }
|
|
|
|
|
set { _operator = value; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int? DifferentBy
|
|
|
|
|
{
|
|
|
|
|
get { return _differentBy; }
|
|
|
|
|
set { _differentBy = value; }
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-14 23:30:23 +00:00
|
|
|
|
public void Update()
|
|
|
|
|
{
|
2013-09-20 01:18:55 +00:00
|
|
|
|
if (_settings.Mode == Settings.SearchMode.Detailed)
|
|
|
|
|
{
|
2013-09-21 14:09:37 +00:00
|
|
|
|
foreach (IMiniWatchDetails watch in _watchList)
|
2013-09-20 01:18:55 +00:00
|
|
|
|
{
|
2013-09-29 19:17:41 +00:00
|
|
|
|
watch.Update(_settings.PreviousType, _settings.Domain, _settings.BigEndian);
|
2013-09-20 01:18:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2013-09-22 17:00:05 +00:00
|
|
|
|
return;
|
2013-09-20 01:18:55 +00:00
|
|
|
|
}
|
2013-09-14 23:30:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-19 23:45:29 +00:00
|
|
|
|
public void SetType(Watch.DisplayType type)
|
|
|
|
|
{
|
|
|
|
|
if (Watch.AvailableTypes(_settings.Size).Contains(type))
|
|
|
|
|
{
|
|
|
|
|
_settings.Type = type;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetEndian(bool bigendian)
|
|
|
|
|
{
|
|
|
|
|
_settings.BigEndian = bigendian;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-20 01:18:55 +00:00
|
|
|
|
public void SetPreviousType(Watch.PreviousType type)
|
|
|
|
|
{
|
2013-09-29 21:15:47 +00:00
|
|
|
|
if (type == Watch.PreviousType.LastChange)
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-20 15:33:46 +00:00
|
|
|
|
if (_settings.Mode == Settings.SearchMode.Fast)
|
|
|
|
|
{
|
2013-09-29 21:15:47 +00:00
|
|
|
|
if (type == Watch.PreviousType.LastFrame)
|
2013-09-20 15:33:46 +00:00
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-09-21 14:09:37 +00:00
|
|
|
|
|
2013-09-20 01:18:55 +00:00
|
|
|
|
_settings.PreviousType = type;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-22 01:53:20 +00:00
|
|
|
|
public void SetPrevousToCurrent()
|
|
|
|
|
{
|
|
|
|
|
_watchList.ForEach(x => x.SetPreviousToCurrent(_settings.Domain, _settings.BigEndian));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ClearChangeCounts()
|
|
|
|
|
{
|
|
|
|
|
if (_settings.Mode == Settings.SearchMode.Detailed)
|
|
|
|
|
{
|
|
|
|
|
foreach (IMiniWatchDetails watch in _watchList.Cast<IMiniWatchDetails>())
|
|
|
|
|
{
|
|
|
|
|
watch.ClearChangeCount();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-22 13:30:18 +00:00
|
|
|
|
public void RemoveRange(List<int> addresses)
|
2013-09-22 01:53:20 +00:00
|
|
|
|
{
|
|
|
|
|
_watchList = _watchList.Where(x => !addresses.Contains(x.Address)).ToList();
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-22 12:50:47 +00:00
|
|
|
|
public void AddRange(List<int> addresses, bool append)
|
|
|
|
|
{
|
|
|
|
|
if (!append)
|
|
|
|
|
{
|
|
|
|
|
_watchList.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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)); }
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
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)); }
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
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)); }
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
foreach (var addr in addresses) { _watchList.Add(new MiniDWordWatch(_settings.Domain, addr, _settings.BigEndian)); }
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-26 01:39:12 +00:00
|
|
|
|
public void Sort(string column, bool reverse)
|
|
|
|
|
{
|
|
|
|
|
switch(column)
|
|
|
|
|
{
|
2013-09-28 01:24:45 +00:00
|
|
|
|
case RamSearch.ADDRESS:
|
2013-09-26 01:39:12 +00:00
|
|
|
|
if (reverse)
|
|
|
|
|
{
|
|
|
|
|
_watchList = _watchList.OrderByDescending(x => x.Address).ToList();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_watchList = _watchList.OrderBy(x => x.Address).ToList();
|
|
|
|
|
}
|
|
|
|
|
break;
|
2013-09-28 01:24:45 +00:00
|
|
|
|
case RamSearch.VALUE:
|
2013-09-26 01:39:12 +00:00
|
|
|
|
if (reverse)
|
|
|
|
|
{
|
|
|
|
|
_watchList = _watchList.OrderByDescending(x => GetValue(x.Address)).ToList();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_watchList = _watchList.OrderBy(x => GetValue(x.Address)).ToList();
|
|
|
|
|
}
|
|
|
|
|
break;
|
2013-09-28 01:24:45 +00:00
|
|
|
|
case RamSearch.PREV:
|
2013-09-26 01:39:12 +00:00
|
|
|
|
if (reverse)
|
|
|
|
|
{
|
|
|
|
|
_watchList = _watchList.OrderByDescending(x => x.Previous).ToList();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_watchList = _watchList.OrderBy(x => x.Previous).ToList();
|
|
|
|
|
}
|
|
|
|
|
break;
|
2013-09-28 01:24:45 +00:00
|
|
|
|
case RamSearch.CHANGES:
|
2013-09-26 01:39:12 +00:00
|
|
|
|
if (_settings.Mode == Settings.SearchMode.Detailed)
|
|
|
|
|
{
|
|
|
|
|
if (reverse)
|
|
|
|
|
{
|
|
|
|
|
_watchList = _watchList
|
|
|
|
|
.Cast<IMiniWatchDetails>()
|
|
|
|
|
.OrderByDescending(x => x.ChangeCount)
|
|
|
|
|
.Cast<IMiniWatch>().ToList();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_watchList = _watchList
|
|
|
|
|
.Cast<IMiniWatchDetails>()
|
|
|
|
|
.OrderBy(x => x.ChangeCount)
|
|
|
|
|
.Cast<IMiniWatch>().ToList();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
2013-09-28 01:24:45 +00:00
|
|
|
|
case RamSearch.DIFF:
|
2013-09-26 01:39:12 +00:00
|
|
|
|
if (reverse)
|
|
|
|
|
{
|
|
|
|
|
_watchList = _watchList.OrderByDescending(x => (GetValue(x.Address) - x.Previous)).ToList();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_watchList = _watchList.OrderBy(x => (GetValue(x.Address) - x.Previous)).ToList();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-25 04:07:41 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Undo API
|
2013-09-26 01:09:08 +00:00
|
|
|
|
|
|
|
|
|
public bool UndoEnabled
|
|
|
|
|
{
|
|
|
|
|
get { return _keepHistory; }
|
|
|
|
|
set { _keepHistory = value; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool CanUndo
|
|
|
|
|
{
|
|
|
|
|
get { return _keepHistory && _history.CanUndo; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool CanRedo
|
|
|
|
|
{
|
|
|
|
|
get { return _keepHistory && _history.CanRedo; }
|
|
|
|
|
}
|
2013-09-25 04:07:41 +00:00
|
|
|
|
|
|
|
|
|
public void ClearHistory()
|
|
|
|
|
{
|
|
|
|
|
_history.Clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Undo()
|
|
|
|
|
{
|
2013-09-26 01:09:08 +00:00
|
|
|
|
if (_keepHistory)
|
|
|
|
|
{
|
|
|
|
|
_watchList = _history.Undo();
|
|
|
|
|
}
|
2013-09-25 04:07:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void Redo()
|
|
|
|
|
{
|
2013-09-26 01:09:08 +00:00
|
|
|
|
if (_keepHistory)
|
|
|
|
|
{
|
|
|
|
|
_watchList = _history.Redo();
|
|
|
|
|
}
|
2013-09-25 04:07:41 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-14 23:30:23 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Comparisons
|
|
|
|
|
|
2013-09-25 01:30:27 +00:00
|
|
|
|
private IEnumerable<IMiniWatch> ComparePrevious(IEnumerable<IMiniWatch> watchList)
|
2013-09-14 23:30:23 +00:00
|
|
|
|
{
|
2013-09-29 18:19:47 +00:00
|
|
|
|
switch (_operator)
|
2013-09-21 14:09:37 +00:00
|
|
|
|
{
|
2013-09-25 01:30:27 +00:00
|
|
|
|
default:
|
2013-09-21 14:09:37 +00:00
|
|
|
|
case ComparisonOperator.Equal:
|
2013-09-25 01:30:27 +00:00
|
|
|
|
return watchList.Where(x => GetValue(x.Address) == x.Previous);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.NotEqual:
|
2013-09-25 01:30:27 +00:00
|
|
|
|
return watchList.Where(x => GetValue(x.Address) != x.Previous);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.GreaterThan:
|
2013-09-25 01:30:27 +00:00
|
|
|
|
return watchList.Where(x => GetValue(x.Address) > x.Previous);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.GreaterThanEqual:
|
2013-09-25 01:30:27 +00:00
|
|
|
|
return watchList.Where(x => GetValue(x.Address) >= x.Previous);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.LessThan:
|
2013-09-25 01:30:27 +00:00
|
|
|
|
return watchList.Where(x => GetValue(x.Address) < x.Previous);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.LessThanEqual:
|
2013-09-25 01:30:27 +00:00
|
|
|
|
return watchList.Where(x => GetValue(x.Address) <= x.Previous);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.DifferentBy:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
if (_differentBy.HasValue)
|
2013-09-21 23:55:17 +00:00
|
|
|
|
{
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => (GetValue(x.Address) + _differentBy.Value == x.Previous) || (GetValue(x.Address) - _differentBy.Value == x.Previous));
|
2013-09-21 23:55:17 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
}
|
2013-09-25 01:30:27 +00:00
|
|
|
|
|
2013-09-21 14:09:37 +00:00
|
|
|
|
}
|
2013-09-14 23:30:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-25 01:30:27 +00:00
|
|
|
|
private IEnumerable<IMiniWatch> CompareSpecificValue(IEnumerable<IMiniWatch> watchList)
|
2013-09-14 23:30:23 +00:00
|
|
|
|
{
|
2013-09-29 18:19:47 +00:00
|
|
|
|
if (_compareValue.HasValue)
|
2013-09-21 23:55:17 +00:00
|
|
|
|
{
|
2013-09-29 18:19:47 +00:00
|
|
|
|
switch (_operator)
|
2013-09-21 23:55:17 +00:00
|
|
|
|
{
|
2013-09-25 01:30:27 +00:00
|
|
|
|
default:
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.Equal:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => GetValue(x.Address) == _compareValue.Value);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.NotEqual:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => GetValue(x.Address) != _compareValue.Value);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.GreaterThan:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => GetValue(x.Address) > _compareValue.Value);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.GreaterThanEqual:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => GetValue(x.Address) >= _compareValue.Value);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.LessThan:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => GetValue(x.Address) < _compareValue.Value);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.LessThanEqual:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => GetValue(x.Address) <= _compareValue.Value);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.DifferentBy:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
if (_differentBy.HasValue)
|
2013-09-21 23:55:17 +00:00
|
|
|
|
{
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => (GetValue(x.Address) + _differentBy.Value == _compareValue.Value) || (GetValue(x.Address) - _differentBy.Value == _compareValue.Value));
|
2013-09-21 23:55:17 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
}
|
2013-09-14 23:30:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-25 01:30:27 +00:00
|
|
|
|
private IEnumerable<IMiniWatch> CompareSpecificAddress(IEnumerable<IMiniWatch> watchList)
|
2013-09-14 23:30:23 +00:00
|
|
|
|
{
|
2013-09-29 18:19:47 +00:00
|
|
|
|
if (_compareValue.HasValue)
|
2013-09-21 23:55:17 +00:00
|
|
|
|
{
|
2013-09-29 18:19:47 +00:00
|
|
|
|
switch (_operator)
|
2013-09-21 23:55:17 +00:00
|
|
|
|
{
|
2013-09-25 01:30:27 +00:00
|
|
|
|
default:
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.Equal:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => x.Address == _compareValue.Value);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.NotEqual:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => x.Address != _compareValue.Value);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.GreaterThan:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => x.Address > _compareValue.Value);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.GreaterThanEqual:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => x.Address >= _compareValue.Value);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.LessThan:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => x.Address < _compareValue.Value);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.LessThanEqual:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => x.Address <= _compareValue.Value);
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.DifferentBy:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
if (_differentBy.HasValue)
|
2013-09-21 23:55:17 +00:00
|
|
|
|
{
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => (x.Address + _differentBy.Value == _compareValue.Value) || (x.Address - _differentBy.Value == _compareValue.Value));
|
2013-09-21 23:55:17 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
}
|
2013-09-14 23:30:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-25 01:30:27 +00:00
|
|
|
|
private IEnumerable<IMiniWatch> CompareChanges(IEnumerable<IMiniWatch> watchList)
|
2013-09-14 23:30:23 +00:00
|
|
|
|
{
|
2013-09-29 18:19:47 +00:00
|
|
|
|
if (_settings.Mode == Settings.SearchMode.Detailed && _compareValue.HasValue)
|
2013-09-21 23:55:17 +00:00
|
|
|
|
{
|
2013-09-29 18:19:47 +00:00
|
|
|
|
switch (_operator)
|
2013-09-21 23:55:17 +00:00
|
|
|
|
{
|
2013-09-25 01:30:27 +00:00
|
|
|
|
default:
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.Equal:
|
2013-09-25 01:30:27 +00:00
|
|
|
|
return watchList
|
2013-09-22 15:54:31 +00:00
|
|
|
|
.Cast<IMiniWatchDetails>()
|
2013-09-29 18:19:47 +00:00
|
|
|
|
.Where(x => x.ChangeCount == _compareValue.Value)
|
2013-09-25 01:30:27 +00:00
|
|
|
|
.Cast<IMiniWatch>();
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.NotEqual:
|
2013-09-25 01:30:27 +00:00
|
|
|
|
return watchList
|
2013-09-22 15:54:31 +00:00
|
|
|
|
.Cast<IMiniWatchDetails>()
|
2013-09-29 18:19:47 +00:00
|
|
|
|
.Where(x => x.ChangeCount != _compareValue.Value)
|
2013-09-25 01:30:27 +00:00
|
|
|
|
.Cast<IMiniWatch>();
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.GreaterThan:
|
2013-09-25 01:30:27 +00:00
|
|
|
|
return watchList
|
2013-09-22 15:54:31 +00:00
|
|
|
|
.Cast<IMiniWatchDetails>()
|
2013-09-29 18:19:47 +00:00
|
|
|
|
.Where(x => x.ChangeCount > _compareValue.Value)
|
2013-09-25 01:30:27 +00:00
|
|
|
|
.Cast<IMiniWatch>();
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.GreaterThanEqual:
|
2013-09-25 01:30:27 +00:00
|
|
|
|
return watchList
|
2013-09-22 15:54:31 +00:00
|
|
|
|
.Cast<IMiniWatchDetails>()
|
2013-09-29 18:19:47 +00:00
|
|
|
|
.Where(x => x.ChangeCount >= _compareValue.Value)
|
2013-09-25 01:30:27 +00:00
|
|
|
|
.Cast<IMiniWatch>();
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.LessThan:
|
2013-09-25 01:30:27 +00:00
|
|
|
|
return watchList
|
2013-09-22 15:54:31 +00:00
|
|
|
|
.Cast<IMiniWatchDetails>()
|
2013-09-29 18:19:47 +00:00
|
|
|
|
.Where(x => x.ChangeCount < _compareValue.Value)
|
2013-09-25 01:30:27 +00:00
|
|
|
|
.Cast<IMiniWatch>();
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.LessThanEqual:
|
2013-09-25 01:30:27 +00:00
|
|
|
|
return watchList
|
2013-09-22 15:54:31 +00:00
|
|
|
|
.Cast<IMiniWatchDetails>()
|
2013-09-29 18:19:47 +00:00
|
|
|
|
.Where(x => x.ChangeCount <= _compareValue.Value)
|
2013-09-25 01:30:27 +00:00
|
|
|
|
.Cast<IMiniWatch>();
|
2013-09-21 23:55:17 +00:00
|
|
|
|
case ComparisonOperator.DifferentBy:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
if (_differentBy.HasValue)
|
2013-09-21 23:55:17 +00:00
|
|
|
|
{
|
2013-09-25 01:30:27 +00:00
|
|
|
|
return watchList
|
2013-09-22 15:54:31 +00:00
|
|
|
|
.Cast<IMiniWatchDetails>()
|
2013-09-29 18:19:47 +00:00
|
|
|
|
.Where(x => (x.ChangeCount + _differentBy.Value == _compareValue.Value) || (x.ChangeCount - _differentBy.Value == _compareValue.Value))
|
2013-09-25 01:30:27 +00:00
|
|
|
|
.Cast<IMiniWatch>();
|
2013-09-21 23:55:17 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidCastException();
|
|
|
|
|
}
|
2013-09-14 23:30:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-25 01:30:27 +00:00
|
|
|
|
private IEnumerable<IMiniWatch> CompareDifference(IEnumerable<IMiniWatch> watchList)
|
2013-09-14 23:30:23 +00:00
|
|
|
|
{
|
2013-09-29 18:19:47 +00:00
|
|
|
|
if (_compareValue.HasValue)
|
2013-09-22 15:54:31 +00:00
|
|
|
|
{
|
2013-09-29 18:19:47 +00:00
|
|
|
|
switch (_operator)
|
2013-09-22 15:54:31 +00:00
|
|
|
|
{
|
2013-09-25 01:30:27 +00:00
|
|
|
|
default:
|
2013-09-22 15:54:31 +00:00
|
|
|
|
case ComparisonOperator.Equal:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => (GetValue(x.Address) - x.Previous) == _compareValue.Value);
|
2013-09-22 15:54:31 +00:00
|
|
|
|
case ComparisonOperator.NotEqual:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => (GetValue(x.Address) - x.Previous) != _compareValue.Value);
|
2013-09-22 15:54:31 +00:00
|
|
|
|
case ComparisonOperator.GreaterThan:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => (GetValue(x.Address) - x.Previous) > _compareValue.Value);
|
2013-09-22 15:54:31 +00:00
|
|
|
|
case ComparisonOperator.GreaterThanEqual:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => (GetValue(x.Address) - x.Previous) >= _compareValue.Value);
|
2013-09-22 15:54:31 +00:00
|
|
|
|
case ComparisonOperator.LessThan:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => (GetValue(x.Address) - x.Previous) < _compareValue.Value);
|
2013-09-22 15:54:31 +00:00
|
|
|
|
case ComparisonOperator.LessThanEqual:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => (GetValue(x.Address) - x.Previous) <= _compareValue.Value);
|
2013-09-22 15:54:31 +00:00
|
|
|
|
case ComparisonOperator.DifferentBy:
|
2013-09-29 18:19:47 +00:00
|
|
|
|
if (_differentBy.HasValue)
|
2013-09-22 15:54:31 +00:00
|
|
|
|
{
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return watchList.Where(x => (GetValue(x.Address) - x.Previous + _differentBy.Value == _compareValue) || (GetValue(x.Address) - x.Previous - _differentBy.Value == x.Previous));
|
2013-09-22 15:54:31 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidCastException();
|
|
|
|
|
}
|
2013-09-14 23:30:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-14 19:07:11 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Private parts
|
2013-09-21 14:09:37 +00:00
|
|
|
|
|
2013-09-29 18:19:47 +00:00
|
|
|
|
private long GetValue(int addr)
|
2013-09-21 14:09:37 +00:00
|
|
|
|
{
|
|
|
|
|
switch (_settings.Size)
|
|
|
|
|
{
|
|
|
|
|
default:
|
|
|
|
|
case Watch.WatchSize.Byte:
|
2013-09-28 00:10:06 +00:00
|
|
|
|
var theByte = _settings.Domain.PeekByte(addr);
|
2013-09-28 18:02:08 +00:00
|
|
|
|
if (_settings.Type == Watch.DisplayType.Signed)
|
|
|
|
|
{
|
|
|
|
|
return (sbyte)theByte;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return theByte;
|
|
|
|
|
}
|
2013-09-21 14:09:37 +00:00
|
|
|
|
case Watch.WatchSize.Word:
|
2013-09-28 00:10:06 +00:00
|
|
|
|
var theWord = _settings.Domain.PeekWord(addr, _settings.BigEndian ? Endian.Big : Endian.Little);
|
2013-09-28 18:02:08 +00:00
|
|
|
|
if (_settings.Type == Watch.DisplayType.Signed)
|
|
|
|
|
{
|
|
|
|
|
return (short)theWord;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return theWord;
|
|
|
|
|
}
|
2013-09-21 14:09:37 +00:00
|
|
|
|
case Watch.WatchSize.DWord:
|
2013-09-28 00:10:06 +00:00
|
|
|
|
var theDWord = _settings.Domain.PeekDWord(addr, _settings.BigEndian ? Endian.Big : Endian.Little);
|
2013-09-28 18:02:08 +00:00
|
|
|
|
if (_settings.Type == Watch.DisplayType.Signed)
|
|
|
|
|
{
|
|
|
|
|
return (int)theDWord;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2013-09-29 18:19:47 +00:00
|
|
|
|
return (uint)theDWord;
|
2013-09-28 18:02:08 +00:00
|
|
|
|
}
|
2013-09-21 14:09:37 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-29 18:52:11 +00:00
|
|
|
|
private bool CanDoCompareType(Compare compareType)
|
|
|
|
|
{
|
|
|
|
|
switch (_settings.Mode)
|
|
|
|
|
{
|
|
|
|
|
default:
|
|
|
|
|
case Settings.SearchMode.Detailed:
|
|
|
|
|
return true;
|
|
|
|
|
case Settings.SearchMode.Fast:
|
|
|
|
|
return !(compareType == Compare.Changes);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-14 19:07:11 +00:00
|
|
|
|
#endregion
|
2013-09-16 01:24:06 +00:00
|
|
|
|
|
|
|
|
|
#region Classes
|
2013-09-20 01:18:55 +00:00
|
|
|
|
|
2013-09-25 04:07:41 +00:00
|
|
|
|
public interface IMiniWatch
|
2013-09-19 23:45:29 +00:00
|
|
|
|
{
|
|
|
|
|
int Address { get; }
|
2013-09-20 01:18:55 +00:00
|
|
|
|
int Previous { get; }
|
2013-09-21 23:55:17 +00:00
|
|
|
|
void SetPreviousToCurrent(MemoryDomain domain, bool bigendian);
|
2013-09-20 01:18:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private interface IMiniWatchDetails
|
|
|
|
|
{
|
|
|
|
|
int ChangeCount { get; }
|
2013-09-22 15:54:31 +00:00
|
|
|
|
|
2013-09-22 01:53:20 +00:00
|
|
|
|
void ClearChangeCount();
|
2013-09-29 19:17:41 +00:00
|
|
|
|
void Update(Watch.PreviousType type, MemoryDomain domain, bool bigendian);
|
2013-09-19 23:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-20 01:18:55 +00:00
|
|
|
|
private class MiniByteWatch : IMiniWatch
|
2013-09-19 23:45:29 +00:00
|
|
|
|
{
|
|
|
|
|
public int Address { get; private set; }
|
2013-09-20 01:18:55 +00:00
|
|
|
|
private byte _previous;
|
2013-09-19 23:45:29 +00:00
|
|
|
|
|
|
|
|
|
public MiniByteWatch(MemoryDomain domain, int addr)
|
|
|
|
|
{
|
|
|
|
|
Address = addr;
|
2013-09-21 23:55:17 +00:00
|
|
|
|
SetPreviousToCurrent(domain, false);
|
2013-09-19 23:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-20 01:18:55 +00:00
|
|
|
|
public int Previous
|
2013-09-19 23:45:29 +00:00
|
|
|
|
{
|
2013-09-20 01:18:55 +00:00
|
|
|
|
get { return _previous; }
|
2013-09-19 23:45:29 +00:00
|
|
|
|
}
|
2013-09-21 23:55:17 +00:00
|
|
|
|
|
|
|
|
|
public void SetPreviousToCurrent(MemoryDomain domain, bool bigendian)
|
|
|
|
|
{
|
|
|
|
|
_previous = domain.PeekByte(Address);
|
|
|
|
|
}
|
2013-09-19 23:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-20 01:18:55 +00:00
|
|
|
|
private class MiniWordWatch : IMiniWatch
|
2013-09-19 23:45:29 +00:00
|
|
|
|
{
|
|
|
|
|
public int Address { get; private set; }
|
2013-09-20 01:18:55 +00:00
|
|
|
|
private ushort _previous;
|
2013-09-19 23:45:29 +00:00
|
|
|
|
|
|
|
|
|
public MiniWordWatch(MemoryDomain domain, int addr, bool bigEndian)
|
|
|
|
|
{
|
|
|
|
|
Address = addr;
|
2013-09-21 23:55:17 +00:00
|
|
|
|
SetPreviousToCurrent(domain, bigEndian);
|
2013-09-19 23:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-20 01:18:55 +00:00
|
|
|
|
public int Previous
|
2013-09-19 23:45:29 +00:00
|
|
|
|
{
|
2013-09-20 01:18:55 +00:00
|
|
|
|
get { return _previous; }
|
2013-09-19 23:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-21 23:55:17 +00:00
|
|
|
|
public void SetPreviousToCurrent(MemoryDomain domain, bool bigendian)
|
|
|
|
|
{
|
|
|
|
|
_previous = domain.PeekWord(Address, bigendian ? Endian.Big : Endian.Little);
|
|
|
|
|
}
|
2013-09-19 23:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-20 01:18:55 +00:00
|
|
|
|
public class MiniDWordWatch : IMiniWatch
|
2013-09-19 23:45:29 +00:00
|
|
|
|
{
|
|
|
|
|
public int Address { get; private set; }
|
2013-09-20 01:18:55 +00:00
|
|
|
|
private uint _previous;
|
2013-09-19 23:45:29 +00:00
|
|
|
|
|
|
|
|
|
public MiniDWordWatch(MemoryDomain domain, int addr, bool bigEndian)
|
|
|
|
|
{
|
|
|
|
|
Address = addr;
|
2013-09-21 23:55:17 +00:00
|
|
|
|
SetPreviousToCurrent(domain, bigEndian);
|
2013-09-20 01:18:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Previous
|
|
|
|
|
{
|
2013-09-21 14:09:37 +00:00
|
|
|
|
get { return (int)_previous; }
|
2013-09-20 01:18:55 +00:00
|
|
|
|
}
|
2013-09-21 23:55:17 +00:00
|
|
|
|
|
|
|
|
|
public void SetPreviousToCurrent(MemoryDomain domain, bool bigendian)
|
|
|
|
|
{
|
|
|
|
|
_previous = domain.PeekDWord(Address, bigendian ? Endian.Big : Endian.Little);
|
|
|
|
|
}
|
2013-09-20 01:18:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-21 23:55:17 +00:00
|
|
|
|
private sealed class MiniByteWatchDetailed : IMiniWatch, IMiniWatchDetails
|
2013-09-20 01:18:55 +00:00
|
|
|
|
{
|
|
|
|
|
public int Address { get; private set; }
|
|
|
|
|
private byte _previous;
|
|
|
|
|
int _changecount = 0;
|
|
|
|
|
|
|
|
|
|
public MiniByteWatchDetailed(MemoryDomain domain, int addr)
|
|
|
|
|
{
|
|
|
|
|
Address = addr;
|
2013-09-21 23:55:17 +00:00
|
|
|
|
SetPreviousToCurrent(domain, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetPreviousToCurrent(MemoryDomain domain, bool bigendian)
|
|
|
|
|
{
|
|
|
|
|
_previous = domain.PeekByte(Address);
|
2013-09-20 01:18:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Previous
|
|
|
|
|
{
|
|
|
|
|
get { return _previous; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int ChangeCount
|
|
|
|
|
{
|
|
|
|
|
get { return _changecount; }
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-29 19:17:41 +00:00
|
|
|
|
public void Update(Watch.PreviousType type, MemoryDomain domain, bool bigendian)
|
2013-09-20 01:18:55 +00:00
|
|
|
|
{
|
2013-09-21 14:09:37 +00:00
|
|
|
|
byte value = domain.PeekByte(Address);
|
2013-09-29 19:17:41 +00:00
|
|
|
|
if (value != Previous)
|
|
|
|
|
{
|
|
|
|
|
_changecount++;
|
|
|
|
|
}
|
2013-09-21 14:09:37 +00:00
|
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case Watch.PreviousType.Original:
|
|
|
|
|
case Watch.PreviousType.LastSearch:
|
|
|
|
|
break;
|
|
|
|
|
case Watch.PreviousType.LastFrame:
|
|
|
|
|
_previous = value;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2013-09-20 01:18:55 +00:00
|
|
|
|
}
|
2013-09-22 01:53:20 +00:00
|
|
|
|
|
|
|
|
|
public void ClearChangeCount()
|
|
|
|
|
{
|
|
|
|
|
_changecount = 0;
|
|
|
|
|
}
|
2013-09-20 01:18:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-21 23:55:17 +00:00
|
|
|
|
private sealed class MiniWordWatchDetailed : IMiniWatch, IMiniWatchDetails
|
2013-09-20 01:18:55 +00:00
|
|
|
|
{
|
|
|
|
|
public int Address { get; private set; }
|
|
|
|
|
private ushort _previous;
|
|
|
|
|
int _changecount = 0;
|
|
|
|
|
|
|
|
|
|
public MiniWordWatchDetailed(MemoryDomain domain, int addr, bool bigEndian)
|
|
|
|
|
{
|
|
|
|
|
Address = addr;
|
2013-09-21 23:55:17 +00:00
|
|
|
|
SetPreviousToCurrent(domain, bigEndian);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SetPreviousToCurrent(MemoryDomain domain, bool bigendian)
|
|
|
|
|
{
|
|
|
|
|
_previous = domain.PeekWord(Address, bigendian ? Endian.Big : Endian.Little);
|
2013-09-20 01:18:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Previous
|
|
|
|
|
{
|
|
|
|
|
get { return _previous; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int ChangeCount
|
|
|
|
|
{
|
|
|
|
|
get { return _changecount; }
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-29 19:17:41 +00:00
|
|
|
|
public void Update(Watch.PreviousType type, MemoryDomain domain, bool bigendian)
|
2013-09-20 01:18:55 +00:00
|
|
|
|
{
|
2013-09-29 19:17:41 +00:00
|
|
|
|
ushort value = domain.PeekWord(Address, bigendian ? Endian.Big : Endian.Little);
|
|
|
|
|
if (value != Previous)
|
|
|
|
|
{
|
|
|
|
|
_changecount++;
|
|
|
|
|
}
|
2013-09-21 14:09:37 +00:00
|
|
|
|
switch (type)
|
|
|
|
|
{
|
2013-09-29 19:17:41 +00:00
|
|
|
|
case Watch.PreviousType.Original:
|
|
|
|
|
case Watch.PreviousType.LastSearch:
|
2013-09-21 14:09:37 +00:00
|
|
|
|
break;
|
|
|
|
|
case Watch.PreviousType.LastFrame:
|
2013-09-29 19:17:41 +00:00
|
|
|
|
_previous = value;
|
|
|
|
|
break;
|
2013-09-21 14:09:37 +00:00
|
|
|
|
}
|
2013-09-20 01:18:55 +00:00
|
|
|
|
}
|
2013-09-22 01:53:20 +00:00
|
|
|
|
|
|
|
|
|
public void ClearChangeCount()
|
|
|
|
|
{
|
|
|
|
|
_changecount = 0;
|
|
|
|
|
}
|
2013-09-20 01:18:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-21 23:55:17 +00:00
|
|
|
|
public sealed class MiniDWordWatchDetailed : IMiniWatch, IMiniWatchDetails
|
2013-09-20 01:18:55 +00:00
|
|
|
|
{
|
|
|
|
|
public int Address { get; private set; }
|
|
|
|
|
private uint _previous;
|
|
|
|
|
int _changecount = 0;
|
|
|
|
|
|
|
|
|
|
public MiniDWordWatchDetailed(MemoryDomain domain, int addr, bool bigEndian)
|
|
|
|
|
{
|
|
|
|
|
Address = addr;
|
2013-09-21 23:55:17 +00:00
|
|
|
|
SetPreviousToCurrent(domain, bigEndian);
|
|
|
|
|
}
|
2013-09-20 01:18:55 +00:00
|
|
|
|
|
2013-09-21 23:55:17 +00:00
|
|
|
|
public void SetPreviousToCurrent(MemoryDomain domain, bool bigendian)
|
|
|
|
|
{
|
|
|
|
|
_previous = domain.PeekDWord(Address, bigendian ? Endian.Big : Endian.Little);
|
2013-09-19 23:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-20 01:18:55 +00:00
|
|
|
|
public int Previous
|
|
|
|
|
{
|
|
|
|
|
get { return (int)_previous; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int ChangeCount
|
|
|
|
|
{
|
|
|
|
|
get { return _changecount; }
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-29 19:17:41 +00:00
|
|
|
|
public void Update(Watch.PreviousType type, MemoryDomain domain, bool bigendian)
|
2013-09-19 23:45:29 +00:00
|
|
|
|
{
|
2013-09-29 19:17:41 +00:00
|
|
|
|
uint value = domain.PeekDWord(Address, bigendian ? Endian.Big : Endian.Little);
|
|
|
|
|
if (value != Previous)
|
|
|
|
|
{
|
|
|
|
|
_changecount++;
|
|
|
|
|
}
|
2013-09-21 14:09:37 +00:00
|
|
|
|
switch (type)
|
|
|
|
|
{
|
2013-09-29 19:17:41 +00:00
|
|
|
|
case Watch.PreviousType.Original:
|
|
|
|
|
case Watch.PreviousType.LastSearch:
|
2013-09-21 14:09:37 +00:00
|
|
|
|
break;
|
|
|
|
|
case Watch.PreviousType.LastFrame:
|
2013-09-29 19:17:41 +00:00
|
|
|
|
_previous = value;
|
|
|
|
|
break;
|
2013-09-21 14:09:37 +00:00
|
|
|
|
}
|
2013-09-19 23:45:29 +00:00
|
|
|
|
}
|
2013-09-22 01:53:20 +00:00
|
|
|
|
|
|
|
|
|
public void ClearChangeCount()
|
|
|
|
|
{
|
|
|
|
|
_changecount = 0;
|
|
|
|
|
}
|
2013-09-19 23:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-16 01:24:06 +00:00
|
|
|
|
public class Settings
|
|
|
|
|
{
|
|
|
|
|
/*Require restart*/
|
|
|
|
|
public enum SearchMode { Fast, Detailed }
|
2013-09-21 14:09:37 +00:00
|
|
|
|
|
2013-09-16 01:24:06 +00:00
|
|
|
|
public SearchMode Mode = SearchMode.Detailed;
|
|
|
|
|
public MemoryDomain Domain = Global.Emulator.MainMemory;
|
|
|
|
|
public Watch.WatchSize Size = Watch.WatchSize.Byte;
|
|
|
|
|
public bool CheckMisAligned = false;
|
|
|
|
|
|
|
|
|
|
/*Can be changed mid-search*/
|
|
|
|
|
public Watch.DisplayType Type = Watch.DisplayType.Unsigned;
|
|
|
|
|
public bool BigEndian = false;
|
2013-09-20 01:18:55 +00:00
|
|
|
|
public Watch.PreviousType PreviousType = Watch.PreviousType.LastSearch;
|
2013-09-16 01:24:06 +00:00
|
|
|
|
}
|
2013-09-20 01:18:55 +00:00
|
|
|
|
|
2013-09-16 01:24:06 +00:00
|
|
|
|
#endregion
|
2013-09-14 19:07:11 +00:00
|
|
|
|
}
|
|
|
|
|
}
|