From f9e174fd2d4555dbe46550e3390be4f31a0b7bc4 Mon Sep 17 00:00:00 2001 From: scrimpeh Date: Wed, 24 Jun 2020 19:35:05 +0200 Subject: [PATCH] ram search - incorporate domain checking --- .../tools/RamSearchEngine/IMiniWatch.cs | 58 +++++++++++++++++-- .../RamSearchEngine/IMiniWatchDetails.cs | 27 +++++++-- .../tools/RamSearchEngine/RamSearchEngine.cs | 10 ++-- .../tools/Watch/RamSearch.cs | 2 +- 4 files changed, 79 insertions(+), 18 deletions(-) diff --git a/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatch.cs b/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatch.cs index 044d64ea6d..6ae499b971 100644 --- a/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatch.cs +++ b/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatch.cs @@ -11,6 +11,7 @@ namespace BizHawk.Client.Common.RamSearchEngine long Address { get; } long Previous { get; } // do not store sign extended variables in here. void SetPreviousToCurrent(MemoryDomain domain, bool bigEndian); + bool IsValid(MemoryDomain domain); } internal sealed class MiniByteWatch : IMiniWatch @@ -21,14 +22,29 @@ namespace BizHawk.Client.Common.RamSearchEngine public MiniByteWatch(MemoryDomain domain, long addr) { Address = addr; - _previous = domain.PeekByte(Address % domain.Size); + _previous = GetByte(Address, domain); } public long Previous => _previous; public void SetPreviousToCurrent(MemoryDomain domain, bool bigEndian) { - _previous = domain.PeekByte(Address % domain.Size); + _previous = GetByte(Address, domain); + } + + public bool IsValid(MemoryDomain domain) + { + return Address < domain.Size; + } + + public static byte GetByte(long address, MemoryDomain domain) + { + if (address >= domain.Size) + { + return 0; + } + + return domain.PeekByte(address); } } @@ -40,14 +56,29 @@ namespace BizHawk.Client.Common.RamSearchEngine public MiniWordWatch(MemoryDomain domain, long addr, bool bigEndian) { Address = addr; - _previous = domain.PeekUshort(Address % domain.Size, bigEndian); + _previous = GetUshort(Address, domain, bigEndian); } public long Previous => _previous; public void SetPreviousToCurrent(MemoryDomain domain, bool bigEndian) { - _previous = domain.PeekUshort(Address, bigEndian); + _previous = GetUshort(Address, domain, bigEndian); + } + + public bool IsValid(MemoryDomain domain) + { + return Address < (domain.Size - 1); + } + + public static ushort GetUshort(long address, MemoryDomain domain, bool bigEndian) + { + if (address >= (domain.Size - 1)) + { + return 0; + } + + return domain.PeekUshort(address, bigEndian); } } @@ -59,14 +90,29 @@ namespace BizHawk.Client.Common.RamSearchEngine public MiniDWordWatch(MemoryDomain domain, long addr, bool bigEndian) { Address = addr; - _previous = domain.PeekUint(Address % domain.Size, bigEndian); + _previous = GetUint(Address, domain, bigEndian); } public long Previous => _previous; public void SetPreviousToCurrent(MemoryDomain domain, bool bigEndian) { - _previous = domain.PeekUint(Address, bigEndian); + _previous = GetUint(Address, domain, bigEndian); + } + + public bool IsValid(MemoryDomain domain) + { + return Address < (domain.Size - 3); + } + + public static uint GetUint(long address, MemoryDomain domain, bool bigEndian) + { + if (address >= (domain.Size - 3)) + { + return 0; + } + + return domain.PeekUint(address, bigEndian); } } } diff --git a/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatchDetails.cs b/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatchDetails.cs index 2e455238ae..4b713a5306 100644 --- a/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatchDetails.cs +++ b/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatchDetails.cs @@ -30,7 +30,7 @@ namespace BizHawk.Client.Common.RamSearchEngine public void SetPreviousToCurrent(MemoryDomain domain, bool bigEndian) { - _previous = _prevFrame = domain.PeekByte(Address % domain.Size); + _previous = _prevFrame = MiniByteWatch.GetByte(Address, domain); } public long Previous => _previous; @@ -39,7 +39,7 @@ namespace BizHawk.Client.Common.RamSearchEngine public void Update(PreviousType type, MemoryDomain domain, bool bigEndian) { - var value = domain.PeekByte(Address % domain.Size); + var value = MiniByteWatch.GetByte(Address, domain); if (value != _prevFrame) { @@ -67,6 +67,11 @@ namespace BizHawk.Client.Common.RamSearchEngine } public void ClearChangeCount() => ChangeCount = 0; + + public bool IsValid(MemoryDomain domain) + { + return Address < domain.Size; + } } internal sealed class MiniWordWatchDetailed : IMiniWatchDetails @@ -84,7 +89,7 @@ namespace BizHawk.Client.Common.RamSearchEngine public void SetPreviousToCurrent(MemoryDomain domain, bool bigEndian) { - _previous = _prevFrame = domain.PeekUshort(Address % domain.Size, bigEndian); + _previous = _prevFrame = MiniWordWatch.GetUshort(Address, domain, bigEndian); } public long Previous => _previous; @@ -93,7 +98,7 @@ namespace BizHawk.Client.Common.RamSearchEngine public void Update(PreviousType type, MemoryDomain domain, bool bigEndian) { - var value = domain.PeekUshort(Address % domain.Size, bigEndian); + var value = MiniWordWatch.GetUshort(Address, domain, bigEndian); if (value != Previous) { ChangeCount++; @@ -120,6 +125,11 @@ namespace BizHawk.Client.Common.RamSearchEngine } public void ClearChangeCount() => ChangeCount = 0; + + public bool IsValid(MemoryDomain domain) + { + return Address < (domain.Size - 1); + } } internal sealed class MiniDWordWatchDetailed : IMiniWatchDetails @@ -137,7 +147,7 @@ namespace BizHawk.Client.Common.RamSearchEngine public void SetPreviousToCurrent(MemoryDomain domain, bool bigEndian) { - _previous = _prevFrame = domain.PeekUint(Address % domain.Size, bigEndian); + _previous = _prevFrame = MiniDWordWatch.GetUint(Address, domain, bigEndian); } public long Previous => (int)_previous; @@ -146,7 +156,7 @@ namespace BizHawk.Client.Common.RamSearchEngine public void Update(PreviousType type, MemoryDomain domain, bool bigEndian) { - var value = domain.PeekUint(Address % domain.Size, bigEndian); + var value = MiniDWordWatch.GetUint(Address, domain, bigEndian); if (value != Previous) { ChangeCount++; @@ -173,5 +183,10 @@ namespace BizHawk.Client.Common.RamSearchEngine } public void ClearChangeCount() => ChangeCount = 0; + + public bool IsValid(MemoryDomain domain) + { + return Address < (domain.Size - 3); + } } } diff --git a/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs b/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs index bf8d5f2c17..67ae53a440 100644 --- a/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs +++ b/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs @@ -42,7 +42,7 @@ namespace BizHawk.Client.Common.RamSearchEngine } public IEnumerable OutOfRangeAddress => _watchList - .Where(watch => watch.Address >= Domain.Size) + .Where(watch => !watch.IsValid(Domain)) .Select(watch => watch.Address); public void Start() @@ -610,10 +610,10 @@ namespace BizHawk.Client.Common.RamSearchEngine // do not return sign extended variables from here. return _settings.Size switch { - WatchSize.Byte => _settings.Domain.PeekByte(addr % Domain.Size), - WatchSize.Word => _settings.Domain.PeekUshort(addr % Domain.Size, _settings.BigEndian), - WatchSize.DWord => _settings.Domain.PeekUint(addr % Domain.Size, _settings.BigEndian), - _ => _settings.Domain.PeekByte(addr % Domain.Size) + WatchSize.Byte => MiniByteWatch.GetByte(addr, Domain), + WatchSize.Word => MiniWordWatch.GetUshort(addr, Domain, _settings.BigEndian), + WatchSize.DWord => MiniDWordWatch.GetUint(addr, Domain, _settings.BigEndian), + _ => MiniByteWatch.GetByte(addr, Domain) }; } diff --git a/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs b/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs index 4f83df1c9d..6cf993c915 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs @@ -196,7 +196,7 @@ namespace BizHawk.Client.EmuHawk var isCheat = MainForm.CheatList.IsActive(_settings.Domain, _searches[index].Address); var isWeeded = Settings.PreviewMode && !_forcePreviewClear && _searches.Preview(_searches[index].Address); - if (_searches[index].Address >= _searches[index].Domain.Size) + if (!_searches[index].IsValid) { nextColor = Color.PeachPuff; }