2013-09-14 19:07:11 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace BizHawk.MultiClient
|
|
|
|
|
{
|
|
|
|
|
class RamSearchEngine
|
|
|
|
|
{
|
2013-09-21 14:09:37 +00:00
|
|
|
|
public enum ComparisonOperator { Equal, GreaterThan, GreaterThanEqual, LessThan, LessThanEqual, NotEqual, DifferentBy };
|
2013-09-20 01:18:55 +00:00
|
|
|
|
private List<IMiniWatch> _watchList = new List<IMiniWatch>();
|
2013-09-16 01:24:06 +00:00
|
|
|
|
private Settings _settings;
|
2013-09-14 19:07:11 +00:00
|
|
|
|
|
2013-09-21 14:09:37 +00:00
|
|
|
|
public ComparisonOperator Operator;
|
|
|
|
|
public int? DifferentBy;
|
|
|
|
|
|
2013-09-14 19:07:11 +00:00
|
|
|
|
#region Constructors
|
2013-09-16 01:24:06 +00:00
|
|
|
|
|
|
|
|
|
public RamSearchEngine(Settings settings)
|
2013-09-14 19:07:11 +00:00
|
|
|
|
{
|
2013-09-16 01:24:06 +00:00
|
|
|
|
_settings = settings;
|
2013-09-14 19:07:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2013-09-14 23:30:23 +00:00
|
|
|
|
#region Initialize, Manipulate
|
|
|
|
|
|
|
|
|
|
public void Start()
|
|
|
|
|
{
|
2013-09-19 23:45:29 +00:00
|
|
|
|
_watchList.Clear();
|
|
|
|
|
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-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
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Count
|
|
|
|
|
{
|
2013-09-21 14:09:37 +00:00
|
|
|
|
get { return _watchList.Count; }
|
2013-09-14 19:07:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string DomainName
|
|
|
|
|
{
|
2013-09-16 01:24:06 +00:00
|
|
|
|
get { return _settings.Domain.Name; }
|
2013-09-14 19:07:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
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-21 14:09:37 +00:00
|
|
|
|
watch.Update(_settings.PreviousType, _settings.Domain);
|
2013-09-20 01:18:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/*TODO*/
|
|
|
|
|
}
|
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-20 15:33:46 +00:00
|
|
|
|
if (_settings.Mode == Settings.SearchMode.Fast)
|
|
|
|
|
{
|
|
|
|
|
if (type == Watch.PreviousType.LastFrame || type == Watch.PreviousType.LastChange)
|
|
|
|
|
{
|
|
|
|
|
throw new InvalidOperationException();
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-09-21 14:09:37 +00:00
|
|
|
|
|
2013-09-20 01:18:55 +00:00
|
|
|
|
_settings.PreviousType = type;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-14 23:30:23 +00:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Comparisons
|
|
|
|
|
|
2013-09-21 14:09:37 +00:00
|
|
|
|
public void ComparePrevious()
|
2013-09-14 23:30:23 +00:00
|
|
|
|
{
|
2013-09-21 14:09:37 +00:00
|
|
|
|
switch (Operator)
|
|
|
|
|
{
|
|
|
|
|
case ComparisonOperator.Equal:
|
|
|
|
|
_watchList = _watchList.Where(x => x.Previous == GetValue(x.Address)).ToList();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2013-09-14 23:30:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-21 14:09:37 +00:00
|
|
|
|
public void CompareSpecificValue(int val)
|
2013-09-14 23:30:23 +00:00
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-21 14:09:37 +00:00
|
|
|
|
public void CompareSpecificAddress(int addr)
|
2013-09-14 23:30:23 +00:00
|
|
|
|
{
|
2013-09-21 14:09:37 +00:00
|
|
|
|
|
2013-09-14 23:30:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-21 14:09:37 +00:00
|
|
|
|
public void CompareChanges(int changes)
|
2013-09-14 23:30:23 +00:00
|
|
|
|
{
|
2013-09-21 14:09:37 +00:00
|
|
|
|
|
2013-09-14 23:30:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-09-21 14:09:37 +00:00
|
|
|
|
public void CompareDifference()
|
2013-09-14 23:30:23 +00:00
|
|
|
|
{
|
2013-09-21 14:09:37 +00:00
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
private int GetValue(int addr)
|
|
|
|
|
{
|
|
|
|
|
switch (_settings.Size)
|
|
|
|
|
{
|
|
|
|
|
default:
|
|
|
|
|
case Watch.WatchSize.Byte:
|
|
|
|
|
return _settings.Domain.PeekByte(addr);
|
|
|
|
|
case Watch.WatchSize.Word:
|
|
|
|
|
if (_settings.BigEndian)
|
|
|
|
|
{
|
|
|
|
|
return (ushort)((_settings.Domain.PeekByte(addr) << 8) | (_settings.Domain.PeekByte(addr + 1)));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return (ushort)((_settings.Domain.PeekByte(addr)) | (_settings.Domain.PeekByte(addr + 1) << 8));
|
|
|
|
|
}
|
|
|
|
|
case Watch.WatchSize.DWord:
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
private interface IMiniWatch
|
2013-09-19 23:45:29 +00:00
|
|
|
|
{
|
|
|
|
|
int Address { get; }
|
2013-09-20 01:18:55 +00:00
|
|
|
|
int Previous { get; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private interface IMiniWatchDetails
|
|
|
|
|
{
|
|
|
|
|
int ChangeCount { get; }
|
2013-09-21 14:09:37 +00:00
|
|
|
|
void Update(Watch.PreviousType type, MemoryDomain domain);
|
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-20 01:18:55 +00:00
|
|
|
|
_previous = domain.PeekByte(addr);
|
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-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;
|
|
|
|
|
if (bigEndian)
|
|
|
|
|
{
|
2013-09-20 01:18:55 +00:00
|
|
|
|
_previous = (ushort)((domain.PeekByte(addr) << 8) | (domain.PeekByte(addr + 1)));
|
2013-09-19 23:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2013-09-20 01:18:55 +00:00
|
|
|
|
_previous = (ushort)((domain.PeekByte(addr)) | (domain.PeekByte(addr + 1) << 8));
|
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-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;
|
|
|
|
|
|
|
|
|
|
if (bigEndian)
|
|
|
|
|
{
|
2013-09-20 01:18:55 +00:00
|
|
|
|
_previous = (uint)((domain.PeekByte(addr) << 24)
|
|
|
|
|
| (domain.PeekByte(addr + 1) << 16)
|
|
|
|
|
| (domain.PeekByte(addr + 2) << 8)
|
|
|
|
|
| (domain.PeekByte(addr + 3) << 0));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_previous = (uint)((domain.PeekByte(addr) << 0)
|
|
|
|
|
| (domain.PeekByte(addr + 1) << 8)
|
|
|
|
|
| (domain.PeekByte(addr + 2) << 16)
|
|
|
|
|
| (domain.PeekByte(addr + 3) << 24));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Previous
|
|
|
|
|
{
|
2013-09-21 14:09:37 +00:00
|
|
|
|
get { return (int)_previous; }
|
2013-09-20 01:18:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private class MiniByteWatchDetailed : IMiniWatch, IMiniWatchDetails
|
|
|
|
|
{
|
|
|
|
|
public int Address { get; private set; }
|
|
|
|
|
private byte _previous;
|
|
|
|
|
int _changecount = 0;
|
|
|
|
|
|
|
|
|
|
public MiniByteWatchDetailed(MemoryDomain domain, int addr)
|
|
|
|
|
{
|
|
|
|
|
Address = addr;
|
|
|
|
|
_previous = domain.PeekByte(addr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Previous
|
|
|
|
|
{
|
|
|
|
|
get { return _previous; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int ChangeCount
|
|
|
|
|
{
|
|
|
|
|
get { return _changecount; }
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-21 14:09:37 +00:00
|
|
|
|
public void Update(Watch.PreviousType type, MemoryDomain domain)
|
2013-09-20 01:18:55 +00:00
|
|
|
|
{
|
2013-09-21 14:09:37 +00:00
|
|
|
|
byte value = domain.PeekByte(Address);
|
|
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case Watch.PreviousType.Original:
|
|
|
|
|
if (value != Previous)
|
|
|
|
|
{
|
|
|
|
|
_changecount++;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Watch.PreviousType.LastSearch:
|
|
|
|
|
if (value != _previous)
|
|
|
|
|
{
|
|
|
|
|
_changecount++;
|
|
|
|
|
_previous = value;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Watch.PreviousType.LastFrame:
|
|
|
|
|
value = domain.PeekByte(Address);
|
|
|
|
|
if (value != Previous)
|
|
|
|
|
{
|
|
|
|
|
_changecount++;
|
|
|
|
|
}
|
|
|
|
|
_previous = value;
|
|
|
|
|
break;
|
|
|
|
|
case Watch.PreviousType.LastChange:
|
|
|
|
|
//TODO: this feature requires yet another variable, ugh
|
|
|
|
|
if (value != Previous)
|
|
|
|
|
{
|
|
|
|
|
_changecount++;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2013-09-20 01:18:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private class MiniWordWatchDetailed : IMiniWatch, IMiniWatchDetails
|
|
|
|
|
{
|
|
|
|
|
public int Address { get; private set; }
|
|
|
|
|
private ushort _previous;
|
|
|
|
|
int _changecount = 0;
|
|
|
|
|
|
|
|
|
|
public MiniWordWatchDetailed(MemoryDomain domain, int addr, bool bigEndian)
|
|
|
|
|
{
|
|
|
|
|
Address = addr;
|
|
|
|
|
if (bigEndian)
|
|
|
|
|
{
|
|
|
|
|
_previous = (ushort)((domain.PeekByte(addr) << 8) | (domain.PeekByte(addr + 1)));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_previous = (ushort)((domain.PeekByte(addr)) | (domain.PeekByte(addr + 1) << 8));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int Previous
|
|
|
|
|
{
|
|
|
|
|
get { return _previous; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int ChangeCount
|
|
|
|
|
{
|
|
|
|
|
get { return _changecount; }
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-21 14:09:37 +00:00
|
|
|
|
public void Update(Watch.PreviousType type, MemoryDomain domain)
|
2013-09-20 01:18:55 +00:00
|
|
|
|
{
|
2013-09-21 14:09:37 +00:00
|
|
|
|
ushort value;
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case Watch.PreviousType.LastChange:
|
|
|
|
|
break;
|
|
|
|
|
case Watch.PreviousType.LastFrame:
|
|
|
|
|
value = domain.PeekByte(Address); //TODO: need big endian passed in
|
|
|
|
|
if (value != Previous)
|
|
|
|
|
{
|
|
|
|
|
_changecount++;
|
|
|
|
|
_previous = value;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
2013-09-20 01:18:55 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class MiniDWordWatchDetailed : IMiniWatch, IMiniWatchDetails
|
|
|
|
|
{
|
|
|
|
|
public int Address { get; private set; }
|
|
|
|
|
private uint _previous;
|
|
|
|
|
int _changecount = 0;
|
|
|
|
|
|
|
|
|
|
public MiniDWordWatchDetailed(MemoryDomain domain, int addr, bool bigEndian)
|
|
|
|
|
{
|
|
|
|
|
Address = addr;
|
|
|
|
|
|
|
|
|
|
if (bigEndian)
|
|
|
|
|
{
|
|
|
|
|
_previous = (uint)((domain.PeekByte(addr) << 24)
|
2013-09-19 23:45:29 +00:00
|
|
|
|
| (domain.PeekByte(addr + 1) << 16)
|
|
|
|
|
| (domain.PeekByte(addr + 2) << 8)
|
|
|
|
|
| (domain.PeekByte(addr + 3) << 0));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2013-09-20 01:18:55 +00:00
|
|
|
|
_previous = (uint)((domain.PeekByte(addr) << 0)
|
2013-09-19 23:45:29 +00:00
|
|
|
|
| (domain.PeekByte(addr + 1) << 8)
|
|
|
|
|
| (domain.PeekByte(addr + 2) << 16)
|
|
|
|
|
| (domain.PeekByte(addr + 3) << 24));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-20 01:18:55 +00:00
|
|
|
|
public int Previous
|
|
|
|
|
{
|
|
|
|
|
get { return (int)_previous; }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int ChangeCount
|
|
|
|
|
{
|
|
|
|
|
get { return _changecount; }
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-21 14:09:37 +00:00
|
|
|
|
public void Update(Watch.PreviousType type, MemoryDomain domain)
|
2013-09-19 23:45:29 +00:00
|
|
|
|
{
|
2013-09-21 14:09:37 +00:00
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case Watch.PreviousType.LastChange:
|
|
|
|
|
break;
|
|
|
|
|
case Watch.PreviousType.LastFrame:
|
|
|
|
|
break;
|
|
|
|
|
}
|
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
|
|
|
|
}
|
|
|
|
|
}
|