From 0f22ef2ad05fe8f72f06fcb2b6a932008eba69a4 Mon Sep 17 00:00:00 2001 From: YoshiRulz Date: Thu, 15 Aug 2024 01:51:08 +1000 Subject: [PATCH] Revert "Change ToRawInt to ToRawUInt" This reverts commit 542e043261012f6271cadbcd2251f073a31cbd3e. --- .../Api/Classes/MemoryApi.cs | 5 +- .../tools/RamSearchEngine/IMiniWatch.cs | 16 +++--- .../tools/RamSearchEngine/RamSearchEngine.cs | 41 +++++++++------- .../tools/Watch/DWordWatch.cs | 6 +-- .../CustomControls/HexTextBox.cs | 24 ++++----- src/BizHawk.Client.EmuHawk/movie/PlayMovie.cs | 2 +- .../tools/Cheats/CheatEdit.cs | 12 ++--- .../tools/Debugger/AddBreakpointDialog.cs | 4 +- .../tools/Debugger/GenericDebugger.cs | 4 +- .../tools/TAStudio/FramesPrompt.cs | 2 +- .../tools/Watch/RamSearch.cs | 28 +++++------ .../tools/Watch/WatchEditor.cs | 2 +- .../tools/Watch/WatchValueBox.cs | 49 ++++++++++--------- .../Extensions/NumberExtensions.cs | 6 --- src/BizHawk.Tests/Common/ConversionTests.cs | 39 ++++++++++----- 15 files changed, 128 insertions(+), 112 deletions(-) diff --git a/src/BizHawk.Client.Common/Api/Classes/MemoryApi.cs b/src/BizHawk.Client.Common/Api/Classes/MemoryApi.cs index f20daba70a..c77b841cbb 100644 --- a/src/BizHawk.Client.Common/Api/Classes/MemoryApi.cs +++ b/src/BizHawk.Client.Common/Api/Classes/MemoryApi.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using BizHawk.Common; -using BizHawk.Common.NumberExtensions; using BizHawk.Emulation.Common; namespace BizHawk.Client.Common @@ -288,7 +287,7 @@ namespace BizHawk.Client.Common LogCallback($"Warning: Attempted read {addr} outside memory size of {d.Size}"); return default; } - return NumberExtensions.ReinterpretAsF32(d.PeekUint(addr, _isBigEndian)); + return BitConverter.ToSingle(BitConverter.GetBytes(d.PeekUint(addr, _isBigEndian)), 0); } public void WriteFloat(long addr, double value, string domain = null) @@ -304,7 +303,7 @@ namespace BizHawk.Client.Common LogCallback($"Warning: Attempted write {addr} outside memory size of {d.Size}"); return; } - d.PokeUint(addr, NumberExtensions.ReinterpretAsUInt32((float) value), _isBigEndian); + d.PokeUint(addr, BitConverter.ToUInt32(BitConverter.GetBytes((float) value), 0), _isBigEndian); } public int ReadS8(long addr, string domain = null) => (sbyte) ReadUnsigned(addr, 1, domain); diff --git a/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatch.cs b/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatch.cs index 05162aa157..33a37a2c93 100644 --- a/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatch.cs +++ b/src/BizHawk.Client.Common/tools/RamSearchEngine/IMiniWatch.cs @@ -8,8 +8,8 @@ namespace BizHawk.Client.Common.RamSearchEngine internal interface IMiniWatch { long Address { get; } - uint Previous { get; } - uint Current { get; } + long Previous { get; } // do not store sign extended variables in here. + long Current { get; } int ChangeCount { get; } void ClearChangeCount(); void SetPreviousToCurrent(); @@ -35,8 +35,8 @@ namespace BizHawk.Client.Common.RamSearchEngine _previous = _current; } - public uint Previous => _previous; - public uint Current => _current; + public long Previous => _previous; + public long Current => _current; public int ChangeCount { get; private set; } @@ -87,8 +87,8 @@ namespace BizHawk.Client.Common.RamSearchEngine _previous = _current; } - public uint Previous => _previous; - public uint Current => _current; + public long Previous => _previous; + public long Current => _current; public int ChangeCount { get; private set; } @@ -139,8 +139,8 @@ namespace BizHawk.Client.Common.RamSearchEngine _previous = _current; } - public uint Previous => _previous; - public uint Current => _current; + public long Previous => _previous; + public long Current => _current; public int ChangeCount { get; private set; } diff --git a/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs b/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs index 5039a292b4..4e922c8a9d 100644 --- a/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs +++ b/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs @@ -1,16 +1,23 @@ using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using BizHawk.Common; using BizHawk.Common.CollectionExtensions; using BizHawk.Common.NumberExtensions; using BizHawk.Emulation.Common; -using static BizHawk.Common.NumberExtensions.NumberExtensions; +// ReSharper disable PossibleInvalidCastExceptionInForeachLoop namespace BizHawk.Client.Common.RamSearchEngine { public class RamSearchEngine { + /// TODO move to BizHawk.Common + private static float ReinterpretAsF32(long l) + { + return Unsafe.As(ref l); + } + private Compare _compareTo = Compare.Previous; private IMiniWatch[] _watchList = [ ]; @@ -31,7 +38,7 @@ namespace BizHawk.Client.Common.RamSearchEngine }; } - public RamSearchEngine(SearchEngineSettings settings, IMemoryDomains memoryDomains, Compare compareTo, uint? compareValue, uint? differentBy) + public RamSearchEngine(SearchEngineSettings settings, IMemoryDomains memoryDomains, Compare compareTo, long? compareValue, int? differentBy) : this(settings, memoryDomains) { _compareTo = compareTo; @@ -149,7 +156,7 @@ namespace BizHawk.Client.Common.RamSearchEngine } } - public uint? CompareValue { get; set; } + public long? CompareValue { get; set; } public ComparisonOperator Operator { get; set; } @@ -157,7 +164,7 @@ namespace BizHawk.Client.Common.RamSearchEngine /// zero 07-sep-2014 - this isn't ideal. but don't bother changing it (to a long, for instance) until it can support floats. maybe store it as a double here.
/// it already supported floats by way of reinterpret-cast, it just wasn't implemented correctly on this side --yoshi /// - public uint? DifferentBy { get; set; } + public int? DifferentBy { get; set; } public void Update(bool updatePrevious) { @@ -311,7 +318,7 @@ namespace BizHawk.Client.Common.RamSearchEngine case ComparisonOperator.LessThanEqual: return watchList.Where(w => SignExtendAsNeeded(w.Current) <= SignExtendAsNeeded(w.Previous)); case ComparisonOperator.DifferentBy: - if (DifferentBy is not uint differentBy) throw new InvalidOperationException(); + if (DifferentBy is not int differentBy) throw new InvalidOperationException(); return watchList.Where(w => differentBy == Math.Abs(SignExtendAsNeeded(w.Current) - SignExtendAsNeeded(w.Previous))); } @@ -342,7 +349,7 @@ namespace BizHawk.Client.Common.RamSearchEngine return val < prev || val.HawkFloatEquality(prev); }); case ComparisonOperator.DifferentBy: - if (DifferentBy is not uint differentBy) throw new InvalidOperationException(); + if (DifferentBy is not int differentBy) throw new InvalidOperationException(); var differentByF = ReinterpretAsF32(differentBy); return watchList.Where(w => Math.Abs(ReinterpretAsF32(w.Current) - ReinterpretAsF32(w.Previous)) .HawkFloatEquality(differentByF)); @@ -351,7 +358,7 @@ namespace BizHawk.Client.Common.RamSearchEngine private IEnumerable CompareSpecificValue(IEnumerable watchList) { - if (CompareValue is not uint compareValue) throw new InvalidOperationException(); + if (CompareValue is not long compareValue) throw new InvalidOperationException(); if (_settings.Type is not WatchDisplayType.Float) { switch (Operator) @@ -370,7 +377,7 @@ namespace BizHawk.Client.Common.RamSearchEngine case ComparisonOperator.LessThanEqual: return watchList.Where(w => SignExtendAsNeeded(w.Current) <= SignExtendAsNeeded(compareValue)); case ComparisonOperator.DifferentBy: - if (DifferentBy is not uint differentBy) throw new InvalidOperationException(); + if (DifferentBy is not int differentBy) throw new InvalidOperationException(); return watchList.Where(w => differentBy == Math.Abs(SignExtendAsNeeded(w.Current) - SignExtendAsNeeded(compareValue))); } @@ -400,7 +407,7 @@ namespace BizHawk.Client.Common.RamSearchEngine return val < compareValueF || val.HawkFloatEquality(compareValueF); }); case ComparisonOperator.DifferentBy: - if (DifferentBy is not uint differentBy) throw new InvalidOperationException(); + if (DifferentBy is not int differentBy) throw new InvalidOperationException(); var differentByF = ReinterpretAsF32(differentBy); return watchList.Where(w => Math.Abs(ReinterpretAsF32(w.Current) - compareValueF) .HawkFloatEquality(differentByF)); @@ -409,7 +416,7 @@ namespace BizHawk.Client.Common.RamSearchEngine private IEnumerable CompareSpecificAddress(IEnumerable watchList) { - if (CompareValue is not uint compareValue) throw new InvalidOperationException(); + if (CompareValue is not long compareValue) throw new InvalidOperationException(); switch (Operator) { default: @@ -426,14 +433,14 @@ namespace BizHawk.Client.Common.RamSearchEngine case ComparisonOperator.LessThanEqual: return watchList.Where(w => w.Address <= compareValue); case ComparisonOperator.DifferentBy: - if (DifferentBy is not uint differentBy) throw new InvalidOperationException(); + if (DifferentBy is not int differentBy) throw new InvalidOperationException(); return watchList.Where(w => Math.Abs(w.Address - compareValue) == differentBy); } } private IEnumerable CompareChanges(IEnumerable watchList) { - if (CompareValue is not uint compareValue) throw new InvalidOperationException(); + if (CompareValue is not long compareValue) throw new InvalidOperationException(); switch (Operator) { default: @@ -450,14 +457,14 @@ namespace BizHawk.Client.Common.RamSearchEngine case ComparisonOperator.LessThanEqual: return watchList.Where(w => w.ChangeCount <= compareValue); case ComparisonOperator.DifferentBy: - if (DifferentBy is not uint differentBy) throw new InvalidOperationException(); + if (DifferentBy is not int differentBy) throw new InvalidOperationException(); return watchList.Where(w => Math.Abs(w.ChangeCount - compareValue) == differentBy); } } private IEnumerable CompareDifference(IEnumerable watchList) { - if (CompareValue is not uint compareValue) throw new InvalidCastException(); //TODO typo for IOE? + if (CompareValue is not long compareValue) throw new InvalidCastException(); //TODO typo for IOE? if (_settings.Type is not WatchDisplayType.Float) { switch (Operator) @@ -476,9 +483,9 @@ namespace BizHawk.Client.Common.RamSearchEngine case ComparisonOperator.LessThanEqual: return watchList.Where(w => SignExtendAsNeeded(w.Current) - SignExtendAsNeeded(w.Previous) <= compareValue); case ComparisonOperator.DifferentBy: - if (DifferentBy is not uint differentBy) throw new InvalidOperationException(); + if (DifferentBy is not int differentBy) throw new InvalidOperationException(); return watchList.Where(w => - differentBy == Math.Abs(Math.Abs(SignExtendAsNeeded(w.Current) - SignExtendAsNeeded(w.Previous)) - compareValue)); + differentBy == Math.Abs(SignExtendAsNeeded(w.Current) - SignExtendAsNeeded(w.Previous) - compareValue)); } } var compareValueF = ReinterpretAsF32(compareValue); @@ -506,7 +513,7 @@ namespace BizHawk.Client.Common.RamSearchEngine return diff < compareValueF || diff.HawkFloatEquality(compareValueF); }); case ComparisonOperator.DifferentBy: - if (DifferentBy is not uint differentBy) throw new InvalidOperationException(); + if (DifferentBy is not int differentBy) throw new InvalidOperationException(); var differentByF = ReinterpretAsF32(differentBy); return watchList.Where(w => Math.Abs(ReinterpretAsF32(w.Current) - ReinterpretAsF32(w.Previous) - compareValueF) .HawkFloatEquality(differentByF)); diff --git a/src/BizHawk.Client.Common/tools/Watch/DWordWatch.cs b/src/BizHawk.Client.Common/tools/Watch/DWordWatch.cs index f02d906d42..558a47e691 100644 --- a/src/BizHawk.Client.Common/tools/Watch/DWordWatch.cs +++ b/src/BizHawk.Client.Common/tools/Watch/DWordWatch.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Globalization; -using BizHawk.Common.NumberExtensions; using BizHawk.Emulation.Common; namespace BizHawk.Client.Common @@ -80,7 +79,7 @@ namespace BizHawk.Client.Common WatchDisplayType.Hex => uint.Parse(value, NumberStyles.HexNumber), WatchDisplayType.FixedPoint_20_12 => (uint)(double.Parse(value, NumberFormatInfo.InvariantInfo) * 4096.0), WatchDisplayType.FixedPoint_16_16 => (uint)(double.Parse(value, NumberFormatInfo.InvariantInfo) * 65536.0), - WatchDisplayType.Float => NumberExtensions.ReinterpretAsUInt32(float.Parse(value, NumberFormatInfo.InvariantInfo)), + WatchDisplayType.Float => BitConverter.ToUInt32(BitConverter.GetBytes(float.Parse(value, NumberFormatInfo.InvariantInfo)), 0), _ => 0 }; @@ -129,7 +128,8 @@ namespace BizHawk.Client.Common { string FormatFloat() { - var _float = NumberExtensions.ReinterpretAsF32(val); + var bytes = BitConverter.GetBytes(val); + var _float = BitConverter.ToSingle(bytes, 0); return _float.ToString(NumberFormatInfo.InvariantInfo); } diff --git a/src/BizHawk.Client.EmuHawk/CustomControls/HexTextBox.cs b/src/BizHawk.Client.EmuHawk/CustomControls/HexTextBox.cs index 4573ddd482..bd3a40636b 100644 --- a/src/BizHawk.Client.EmuHawk/CustomControls/HexTextBox.cs +++ b/src/BizHawk.Client.EmuHawk/CustomControls/HexTextBox.cs @@ -10,8 +10,8 @@ namespace BizHawk.Client.EmuHawk public interface INumberBox { bool Nullable { get; } - uint? ToRawUInt(); - void SetFromRawUInt(uint? rawUInt); + int? ToRawInt(); + void SetFromRawInt(int? rawInt); } public class HexTextBox : ClipboardEventTextBox, INumberBox @@ -85,7 +85,7 @@ namespace BizHawk.Client.EmuHawk { if (Text.IsHex() && !string.IsNullOrEmpty(_addressFormatStr)) { - var val = ToRawUInt(); + var val = (uint)ToRawInt(); if (val == GetMax()) { @@ -103,7 +103,7 @@ namespace BizHawk.Client.EmuHawk { if (Text.IsHex() && !string.IsNullOrEmpty(_addressFormatStr)) { - var val = ToRawUInt(); + var val = (uint)ToRawInt(); if (val == 0) { val = (uint)GetMax(); // int to long todo @@ -146,7 +146,7 @@ namespace BizHawk.Client.EmuHawk base.OnPaste(e); } - public uint? ToRawUInt() + public int? ToRawInt() { if (string.IsNullOrWhiteSpace(Text)) { @@ -158,10 +158,10 @@ namespace BizHawk.Client.EmuHawk return 0; } - return uint.Parse(Text, NumberStyles.HexNumber); + return int.Parse(Text, NumberStyles.HexNumber); } - public void SetFromRawUInt(uint? val) + public void SetFromRawInt(int? val) { Text = val.HasValue ? string.Format(_addressFormatStr, val) : ""; } @@ -230,7 +230,7 @@ namespace BizHawk.Client.EmuHawk { if (Text.IsHex()) { - var val = ToRawUInt().Value; + var val = (uint)ToRawInt(); if (val == uint.MaxValue) { val = 0; @@ -247,7 +247,7 @@ namespace BizHawk.Client.EmuHawk { if (Text.IsHex()) { - var val = ToRawUInt().Value; + var val = (uint)ToRawInt(); if (val == 0) { @@ -279,7 +279,7 @@ namespace BizHawk.Client.EmuHawk base.OnTextChanged(e); } - public uint? ToRawUInt() + public int? ToRawInt() { if (string.IsNullOrWhiteSpace(Text) || !Text.IsHex()) { @@ -291,10 +291,10 @@ namespace BizHawk.Client.EmuHawk return 0; } - return uint.Parse(Text); + return (int)uint.Parse(Text); } - public void SetFromRawUInt(uint? val) + public void SetFromRawInt(int? val) { Text = val?.ToString() ?? ""; } diff --git a/src/BizHawk.Client.EmuHawk/movie/PlayMovie.cs b/src/BizHawk.Client.EmuHawk/movie/PlayMovie.cs index 7a01d3aca3..d3e8603cce 100644 --- a/src/BizHawk.Client.EmuHawk/movie/PlayMovie.cs +++ b/src/BizHawk.Client.EmuHawk/movie/PlayMovie.cs @@ -593,7 +593,7 @@ namespace BizHawk.Client.EmuHawk if (StopOnFrameCheckbox.Checked) { if (LastFrameCheckbox.Checked) _mainForm.PauseOnFrame = _movieSession.Movie.InputLogLength; - else if (StopOnFrameTextBox.ToRawUInt() is uint i) _mainForm.PauseOnFrame = (int)i; + else if (StopOnFrameTextBox.ToRawInt() is int i) _mainForm.PauseOnFrame = i; } Close(); } diff --git a/src/BizHawk.Client.EmuHawk/tools/Cheats/CheatEdit.cs b/src/BizHawk.Client.EmuHawk/tools/Cheats/CheatEdit.cs index 040e2a10a1..7b8ec3bdeb 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Cheats/CheatEdit.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Cheats/CheatEdit.cs @@ -93,7 +93,7 @@ namespace BizHawk.Client.EmuHawk CheckFormState(); if (!_cheat.Compare.HasValue) { - CompareBox.Text = ""; // Necessary hack until WatchValueBox.ToRawUInt() becomes nullable + CompareBox.Text = ""; // Necessary hack until WatchValueBox.ToRawInt() becomes nullable } _loading = false; @@ -132,7 +132,7 @@ namespace BizHawk.Client.EmuHawk SetTypeSelected(WatchDisplayType.Hex); CheckFormState(); - CompareBox.Text = ""; // TODO: A needed hack until WatchValueBox.ToRawUInt() becomes nullable + CompareBox.Text = ""; // TODO: A needed hack until WatchValueBox.ToRawInt() becomes nullable _loading = false; } @@ -310,7 +310,7 @@ namespace BizHawk.Client.EmuHawk public Cheat GetCheat() { var domain = MemoryDomains[DomainDropDown.SelectedItem.ToString()]!; - var address = AddressBox.ToRawUInt().Value; + var address = AddressBox.ToRawInt().Value; if (address < domain.Size) { var watch = Watch.GenerateWatch( @@ -333,11 +333,11 @@ namespace BizHawk.Client.EmuHawk _ => Cheat.CompareType.None }; - var compare = CompareBox.ToRawUInt(); + var compare = CompareBox.ToRawInt(); return new Cheat( watch, - value: (int)ValueBox.ToRawUInt().Value, - compare: (int?)compare, + value: ValueBox.ToRawInt().Value, + compare: compare, enabled: true, comparisonType); } diff --git a/src/BizHawk.Client.EmuHawk/tools/Debugger/AddBreakpointDialog.cs b/src/BizHawk.Client.EmuHawk/tools/Debugger/AddBreakpointDialog.cs index 08930db061..38eda9d704 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Debugger/AddBreakpointDialog.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Debugger/AddBreakpointDialog.cs @@ -100,13 +100,13 @@ namespace BizHawk.Client.EmuHawk public uint Address { - get => AddressBox.ToRawUInt().Value & AddressMask; + get => (uint)AddressBox.ToRawInt().Value & AddressMask; set => AddressBox.SetFromLong(value & AddressMask); } public uint AddressMask { - get => AddressMaskBox.ToRawUInt().Value; + get => (uint)AddressMaskBox.ToRawInt().Value; set => AddressMaskBox.SetFromLong(value); } diff --git a/src/BizHawk.Client.EmuHawk/tools/Debugger/GenericDebugger.cs b/src/BizHawk.Client.EmuHawk/tools/Debugger/GenericDebugger.cs index 9a991d001d..a668b5480a 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Debugger/GenericDebugger.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Debugger/GenericDebugger.cs @@ -118,7 +118,7 @@ namespace BizHawk.Client.EmuHawk var pc = PCRegister; SeekToBox.Nullable = false; SeekToBox.SetHexProperties((long)Math.Pow(2, pc.BitSize)); - SeekToBox.SetFromRawUInt(0); + SeekToBox.SetFromRawInt(0); } else { @@ -263,7 +263,7 @@ namespace BizHawk.Client.EmuHawk private void SeekToBtn_Click(object sender, EventArgs e) { CancelSeekBtn.Enabled = true; - var pcVal = SeekToBox.ToRawUInt() ?? 0; + var pcVal = (uint)(SeekToBox.ToRawInt() ?? 0); var pcBitSize = PCRegister.BitSize; BreakPointControl1.RemoveCurrentSeek(); diff --git a/src/BizHawk.Client.EmuHawk/tools/TAStudio/FramesPrompt.cs b/src/BizHawk.Client.EmuHawk/tools/TAStudio/FramesPrompt.cs index be350c264f..32449a7d09 100644 --- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/FramesPrompt.cs +++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/FramesPrompt.cs @@ -17,7 +17,7 @@ namespace BizHawk.Client.EmuHawk this.label1.Text = bodyMessage; } - public int Frames => (int)(NumFramesBox.ToRawUInt() ?? 0); + public int Frames => NumFramesBox.ToRawInt() ?? 0; private void FramesPrompt_Load(object sender, EventArgs e) { diff --git a/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs b/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs index f6166455af..bd7edbd18d 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs @@ -421,7 +421,7 @@ namespace BizHawk.Client.EmuHawk WatchListView.AnyRowsSelected && _searches.Domain.Writable; } - private uint? CompareToValue + private long? CompareToValue { get { @@ -432,29 +432,29 @@ namespace BizHawk.Client.EmuHawk if (SpecificValueRadio.Checked) { - return SpecificValueBox.ToRawUInt(); + return (long)SpecificValueBox.ToRawInt() & 0x00000000FFFFFFFF; } if (SpecificAddressRadio.Checked) { - return SpecificAddressBox.ToRawUInt(); + return SpecificAddressBox.ToRawInt(); } if (NumberOfChangesRadio.Checked) { - return NumberOfChangesBox.ToRawUInt(); + return NumberOfChangesBox.ToRawInt(); } if (DifferenceRadio.Checked) { - return DifferenceBox.ToRawUInt(); + return DifferenceBox.ToRawInt(); } return null; } } - private uint? DifferentByValue => DifferentByRadio.Checked ? DifferentByBox.ToRawUInt() : null; + private int? DifferentByValue => DifferentByRadio.Checked ? DifferentByBox.ToRawInt() : null; private ComparisonOperator Operator { @@ -737,7 +737,7 @@ namespace BizHawk.Client.EmuHawk WatchListView.Refresh(); } - private void SetCompareValue(uint? value) + private void SetCompareValue(int? value) { _searches.CompareValue = value; WatchListView.Refresh(); @@ -1441,7 +1441,7 @@ namespace BizHawk.Client.EmuHawk SpecificAddressBox.ResetText(); } - _searches.CompareValue = SpecificValueBox.ToRawUInt(); + _searches.CompareValue = SpecificValueBox.ToRawInt(); if (Focused) { @@ -1463,7 +1463,7 @@ namespace BizHawk.Client.EmuHawk SpecificAddressBox.ResetText(); } - _searches.CompareValue = SpecificAddressBox.ToRawUInt(); + _searches.CompareValue = SpecificAddressBox.ToRawInt(); if (Focused) { @@ -1485,7 +1485,7 @@ namespace BizHawk.Client.EmuHawk NumberOfChangesBox.ResetText(); } - _searches.CompareValue = NumberOfChangesBox.ToRawUInt(); + _searches.CompareValue = NumberOfChangesBox.ToRawInt(); if (Focused) { @@ -1507,7 +1507,7 @@ namespace BizHawk.Client.EmuHawk DifferenceBox.ResetText(); } - _searches.CompareValue = DifferenceBox.ToRawUInt(); + _searches.CompareValue = DifferenceBox.ToRawInt(); if (Focused) { @@ -1519,7 +1519,7 @@ namespace BizHawk.Client.EmuHawk private void CompareToValue_TextChanged(object sender, EventArgs e) { - SetCompareValue(((INumberBox)sender).ToRawUInt()); + SetCompareValue(((INumberBox)sender).ToRawInt()); } private void EqualToRadio_Click(object sender, EventArgs e) @@ -1567,7 +1567,7 @@ namespace BizHawk.Client.EmuHawk DifferentByBox.ResetText(); } - _searches.DifferentBy = DifferenceBox.ToRawUInt(); + _searches.DifferentBy = DifferenceBox.ToRawInt(); if (Focused) { @@ -1579,7 +1579,7 @@ namespace BizHawk.Client.EmuHawk private void DifferentByBox_TextChanged(object sender, EventArgs e) { - _searches.DifferentBy = !string.IsNullOrWhiteSpace(DifferentByBox.Text) ? DifferentByBox.ToRawUInt() : null; + _searches.DifferentBy = !string.IsNullOrWhiteSpace(DifferentByBox.Text) ? DifferentByBox.ToRawInt() : null; WatchListView.Refresh(); } diff --git a/src/BizHawk.Client.EmuHawk/tools/Watch/WatchEditor.cs b/src/BizHawk.Client.EmuHawk/tools/Watch/WatchEditor.cs index 92550e0807..e0dd13a435 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Watch/WatchEditor.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Watch/WatchEditor.cs @@ -275,7 +275,7 @@ namespace BizHawk.Client.EmuHawk Watches[i] = Watch.GenerateWatch( Watches[i].Domain, - Watches.Count == 1 ? AddressBox.ToRawUInt() ?? 0 : Watches[i].Address, + Watches.Count == 1 ? AddressBox.ToRawInt() ?? 0 : Watches[i].Address, size, _changedDisplayType ? displayType : Watches[i].Type, Watches[i].BigEndian, diff --git a/src/BizHawk.Client.EmuHawk/tools/Watch/WatchValueBox.cs b/src/BizHawk.Client.EmuHawk/tools/Watch/WatchValueBox.cs index 560bc4b99a..7cddd85f2b 100644 --- a/src/BizHawk.Client.EmuHawk/tools/Watch/WatchValueBox.cs +++ b/src/BizHawk.Client.EmuHawk/tools/Watch/WatchValueBox.cs @@ -55,10 +55,10 @@ namespace BizHawk.Client.EmuHawk get => _type; set { - var val = ToRawUInt(); + var val = ToRawInt(); _type = value; SetMaxLength(); - SetFromRawUInt(val); + SetFromRawInt(val); } } @@ -196,7 +196,7 @@ namespace BizHawk.Client.EmuHawk { default: case WatchDisplayType.Signed: - int val = (int)(ToRawUInt() ?? 0); + int val = ToRawInt() ?? 0; if (val == MaxSignedInt) { val = MinSignedInt; @@ -209,7 +209,7 @@ namespace BizHawk.Client.EmuHawk Text = val.ToString(); break; case WatchDisplayType.Unsigned: - var uval = ToRawUInt() ?? 0; + var uval = (uint)(ToRawInt() ?? 0); if (uval == MaxUnsignedInt) { uval = 0; @@ -222,7 +222,7 @@ namespace BizHawk.Client.EmuHawk Text = uval.ToString(); break; case WatchDisplayType.Binary: - var bVal = ToRawUInt() ?? 0; + var bVal = (uint)(ToRawInt() ?? 0); if (bVal == MaxUnsignedInt) { bVal = 0; @@ -236,7 +236,7 @@ namespace BizHawk.Client.EmuHawk Text = Convert.ToString(bVal, 2).PadLeft(numBits, '0'); break; case WatchDisplayType.Hex: - var hexVal = ToRawUInt() ?? 0; + var hexVal = (uint)(ToRawInt() ?? 0); if (hexVal == MaxUnsignedInt) { hexVal = 0; @@ -308,7 +308,7 @@ namespace BizHawk.Client.EmuHawk { default: case WatchDisplayType.Signed: - int val = (int)(ToRawUInt() ?? 0); + int val = ToRawInt() ?? 0; if (val == MinSignedInt) { val = MaxSignedInt; @@ -321,7 +321,7 @@ namespace BizHawk.Client.EmuHawk Text = val.ToString(); break; case WatchDisplayType.Unsigned: - var uval = ToRawUInt() ?? 0; + var uval = (uint)(ToRawInt() ?? 0); if (uval == 0) { uval = MaxUnsignedInt; @@ -334,7 +334,7 @@ namespace BizHawk.Client.EmuHawk Text = uval.ToString(); break; case WatchDisplayType.Binary: - var bVal = ToRawUInt() ?? 0; + var bVal = (uint)(ToRawInt() ?? 0); if (bVal == 0) { bVal = MaxUnsignedInt; @@ -348,7 +348,7 @@ namespace BizHawk.Client.EmuHawk Text = Convert.ToString(bVal, 2).PadLeft(numBits, '0'); break; case WatchDisplayType.Hex: - var hexVal = ToRawUInt() ?? 0; + var hexVal = (uint)(ToRawInt() ?? 0); if (hexVal == 0) { hexVal = MaxUnsignedInt; @@ -444,21 +444,21 @@ namespace BizHawk.Client.EmuHawk base.OnPaste(e); } - public uint? ToRawUInt() + public int? ToRawInt() { try { return _type switch { - WatchDisplayType.Signed => (uint)int.Parse(Text), - WatchDisplayType.Unsigned => uint.Parse(Text), - WatchDisplayType.Binary => Convert.ToUInt32(Text, 2), - WatchDisplayType.Hex => uint.Parse(Text, NumberStyles.HexNumber), - WatchDisplayType.FixedPoint_12_4 => (uint)(double.Parse(Text, NumberFormatInfo.InvariantInfo) * 16.0), - WatchDisplayType.FixedPoint_20_12 => (uint)(double.Parse(Text, NumberFormatInfo.InvariantInfo) * 4096.0), - WatchDisplayType.FixedPoint_16_16 => (uint)(double.Parse(Text, NumberFormatInfo.InvariantInfo) * 65536.0), - WatchDisplayType.Float => NumberExtensions.ReinterpretAsUInt32(float.Parse(Text, NumberFormatInfo.InvariantInfo)), - _ => uint.Parse(Text) + WatchDisplayType.Signed => int.Parse(Text), + WatchDisplayType.Unsigned => (int)uint.Parse(Text), + WatchDisplayType.Binary => Convert.ToInt32(Text, 2), + WatchDisplayType.Hex => int.Parse(Text, NumberStyles.HexNumber), + WatchDisplayType.FixedPoint_12_4 => (int)(double.Parse(Text, NumberFormatInfo.InvariantInfo) * 16.0), + WatchDisplayType.FixedPoint_20_12 => (int)(double.Parse(Text, NumberFormatInfo.InvariantInfo) * 4096.0), + WatchDisplayType.FixedPoint_16_16 => (int)(double.Parse(Text, NumberFormatInfo.InvariantInfo) * 65536.0), + WatchDisplayType.Float => BitConverter.ToInt32(BitConverter.GetBytes(float.Parse(Text, NumberFormatInfo.InvariantInfo)), 0), + _ => int.Parse(Text) }; } catch @@ -469,7 +469,7 @@ namespace BizHawk.Client.EmuHawk return Nullable ? null : 0; } - public void SetFromRawUInt(uint? val) + public void SetFromRawInt(int? val) { if (val.HasValue) { @@ -480,11 +480,11 @@ namespace BizHawk.Client.EmuHawk Text = val.Value.ToString(); break; case WatchDisplayType.Unsigned: - var uval = val.Value; + var uval = (uint)val.Value; Text = uval.ToString(); break; case WatchDisplayType.Binary: - var bVal = val.Value; + var bVal = (uint)val.Value; var numBits = ((int)ByteSize) * 8; Text = Convert.ToString(bVal, 2).PadLeft(numBits, '0'); break; @@ -501,7 +501,8 @@ namespace BizHawk.Client.EmuHawk Text = (val.Value / 65536.0).ToString("F5", NumberFormatInfo.InvariantInfo); break; case WatchDisplayType.Float: - float _float = NumberExtensions.ReinterpretAsF32(val.Value); + var bytes = BitConverter.GetBytes(val.Value); + float _float = BitConverter.ToSingle(bytes, 0); Text = _float.ToString("F6", NumberFormatInfo.InvariantInfo); break; } diff --git a/src/BizHawk.Common/Extensions/NumberExtensions.cs b/src/BizHawk.Common/Extensions/NumberExtensions.cs index 0f236461f2..2afcd6353c 100644 --- a/src/BizHawk.Common/Extensions/NumberExtensions.cs +++ b/src/BizHawk.Common/Extensions/NumberExtensions.cs @@ -155,11 +155,5 @@ namespace BizHawk.Common.NumberExtensions /// don't use this in cores without picking a suitable ε public static bool HawkFloatEquality(this float f, float other, float ε = ReallySmallNumber) => Math.Abs(other - f) < ε; - - /// Reinterprets the byte representation of as a float - public static float ReinterpretAsF32(uint value) => Unsafe.As(ref value); - - /// Reinterprets the byte representation of as a uint - public static uint ReinterpretAsUInt32(float value) => Unsafe.As(ref value); } } diff --git a/src/BizHawk.Tests/Common/ConversionTests.cs b/src/BizHawk.Tests/Common/ConversionTests.cs index 04d3d5a7a6..c05d5c5662 100644 --- a/src/BizHawk.Tests/Common/ConversionTests.cs +++ b/src/BizHawk.Tests/Common/ConversionTests.cs @@ -1,24 +1,39 @@ -using BizHawk.Common.NumberExtensions; +using System.Buffers.Binary; +using System.Runtime.CompilerServices; namespace BizHawk.Tests.Common; +// test for RamSearchEngine.ReinterpretAsF32 [TestClass] public class ConversionTests { - [TestMethod] - [DataRow(0U, 0)] - [DataRow(1U, 1.401298E-45F)] - [DataRow(1109917696U, 42)] - [DataRow(1123477881U, 123.456F)] - [DataRow(3212836864U, -1)] - public void TestReinterpretAsF32(uint input, float expected) + private static float ReinterpretAsF32Unsafe(long l) { - float converted = NumberExtensions.ReinterpretAsF32(input); + return Unsafe.As(ref l); + } - Assert.AreEqual(expected, converted); + private static readonly byte[] ScratchSpace = new byte[8]; - uint restoredInput = NumberExtensions.ReinterpretAsUInt32(converted); + private static float ReinterpretAsF32BitConverter(long l) + { + BinaryPrimitives.WriteInt64LittleEndian(ScratchSpace, l); + return BitConverter.ToSingle(ScratchSpace, startIndex: 0); + } - Assert.AreEqual(input, restoredInput); + [TestMethod] + [DoNotParallelize] // old implementation is not thread safe + [DataRow(0, 0)] + [DataRow(1, 1.401298E-45F)] + [DataRow(1109917696, 42)] + [DataRow(1123477881, 123.456F)] + [DataRow(3212836864, -1)] + [DataRow(0x7fffffffbf800000, -1)] + public void TestReinterpretAsF32(long input, float expected) + { + float f32BitConverter = ReinterpretAsF32BitConverter(input); + float f32Unsafe = ReinterpretAsF32Unsafe(input); + + Assert.AreEqual(expected, f32BitConverter); + Assert.AreEqual(expected, f32Unsafe); } }