diff --git a/Dist/git_hook_shim.sh b/Dist/git_hook_shim.sh
index 6ad95f267d7..102fc9b662a 100755
--- a/Dist/git_hook_shim.sh
+++ b/Dist/git_hook_shim.sh
@@ -1,8 +1,12 @@
#!/bin/sh
-set -e
+kind="$(basename "$0")"
pwsh="$(command -v pwsh)"
if [ -z "$pwsh" ]; then pwsh="$(command -v dotnet) pwsh"; fi
-if ! ("$pwsh" -v >/dev/null 2>/dev/null); then exit 0; fi
-kind="$(basename "$0")"
-"$pwsh" "./Dist/git_hooks/$kind.ps1" "$@"
-if [ -e "./Dist/git_hooks/$kind.local.ps1" ]; then "$pwsh" "./Dist/git_hooks/$kind.local.ps1" "$@"; fi
+if ! ("$pwsh" -v >/dev/null 2>/dev/null); then
+ printf "pwsh not found in PATH; skipping %s hook\n" "$kind"
+ exit 0
+fi
+if [ -e "./Dist/git_hooks/$kind.ps1" ]; then
+ "$pwsh" "./Dist/git_hooks/$kind.ps1" "$@" || exit $?
+ if [ -e "./Dist/git_hooks/$kind.local.ps1" ]; then "$pwsh" "./Dist/git_hooks/$kind.local.ps1" "$@" || exit $?; fi
+fi
diff --git a/Dist/install_git_hooks.ps1 b/Dist/install_git_hooks.ps1
index 82ebc335b9c..370bc20171d 100755
--- a/Dist/install_git_hooks.ps1
+++ b/Dist/install_git_hooks.ps1
@@ -12,7 +12,7 @@ if (Test-Path $targetDir -PathType Container) { # is Git repo
#TODO use symlinks on Linux
} elseif ((Get-FileHash $target).Hash -ne $shimChecksum) { # files differ
$head = Get-Content $target -TotalCount 3
- echo "[$PSCommandFilename] found existing Git hook $hook, please resolve conflict manually"
+ echo "[$PSCommandFilename] found existing Git hook $hook, please resolve conflict manually (ignore if checking out older commits)"
exit 1
}
# else no-op
diff --git a/src/BizHawk.Client.Common/Api/Classes/MemoryApi.cs b/src/BizHawk.Client.Common/Api/Classes/MemoryApi.cs
index 5ce463ff57e..22e3ef1efaf 100644
--- a/src/BizHawk.Client.Common/Api/Classes/MemoryApi.cs
+++ b/src/BizHawk.Client.Common/Api/Classes/MemoryApi.cs
@@ -3,6 +3,7 @@
using System.Linq;
using BizHawk.Common;
+using BizHawk.Common.NumberExtensions;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.Common
@@ -287,7 +288,7 @@ public float ReadFloat(long addr, string domain = null)
LogCallback($"Warning: Attempted read {addr} outside memory size of {d.Size}");
return default;
}
- return BitConverter.ToSingle(BitConverter.GetBytes(d.PeekUint(addr, _isBigEndian)), 0);
+ return NumberExtensions.ReinterpretAsF32(d.PeekUint(addr, _isBigEndian));
}
public void WriteFloat(long addr, double value, string domain = null)
@@ -303,7 +304,7 @@ public void WriteFloat(long addr, double value, string domain = null)
LogCallback($"Warning: Attempted write {addr} outside memory size of {d.Size}");
return;
}
- d.PokeUint(addr, BitConverter.ToUInt32(BitConverter.GetBytes((float) value), 0), _isBigEndian);
+ d.PokeUint(addr, NumberExtensions.ReinterpretAsUInt32((float) value), _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 33a37a2c939..05162aa1572 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; }
- long Previous { get; } // do not store sign extended variables in here.
- long Current { get; }
+ uint Previous { get; }
+ uint Current { get; }
int ChangeCount { get; }
void ClearChangeCount();
void SetPreviousToCurrent();
@@ -35,8 +35,8 @@ public void SetPreviousToCurrent()
_previous = _current;
}
- public long Previous => _previous;
- public long Current => _current;
+ public uint Previous => _previous;
+ public uint Current => _current;
public int ChangeCount { get; private set; }
@@ -87,8 +87,8 @@ public void SetPreviousToCurrent()
_previous = _current;
}
- public long Previous => _previous;
- public long Current => _current;
+ public uint Previous => _previous;
+ public uint Current => _current;
public int ChangeCount { get; private set; }
@@ -139,8 +139,8 @@ public void SetPreviousToCurrent()
_previous = _current;
}
- public long Previous => _previous;
- public long Current => _current;
+ public uint Previous => _previous;
+ public uint 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 5e4d0ebe806..6a762d877b5 100644
--- a/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs
+++ b/src/BizHawk.Client.Common/tools/RamSearchEngine/RamSearchEngine.cs
@@ -1,24 +1,17 @@
using System;
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 = [ ];
@@ -39,7 +32,7 @@ public RamSearchEngine(SearchEngineSettings settings, IMemoryDomains memoryDomai
};
}
- public RamSearchEngine(SearchEngineSettings settings, IMemoryDomains memoryDomains, Compare compareTo, long? compareValue, int? differentBy)
+ public RamSearchEngine(SearchEngineSettings settings, IMemoryDomains memoryDomains, Compare compareTo, uint? compareValue, uint? differentBy)
: this(settings, memoryDomains)
{
_compareTo = compareTo;
@@ -157,7 +150,7 @@ public Compare CompareTo
}
}
- public long? CompareValue { get; set; }
+ public uint? CompareValue { get; set; }
public ComparisonOperator Operator { get; set; }
@@ -165,7 +158,7 @@ public Compare CompareTo
/// 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 int? DifferentBy { get; set; }
+ public uint? DifferentBy { get; set; }
public void Update(bool updatePrevious)
{
@@ -319,7 +312,7 @@ private IEnumerable ComparePrevious(IEnumerable watchLis
case ComparisonOperator.LessThanEqual:
return watchList.Where(w => SignExtendAsNeeded(w.Current) <= SignExtendAsNeeded(w.Previous));
case ComparisonOperator.DifferentBy:
- if (DifferentBy is not int differentBy) throw new InvalidOperationException();
+ if (DifferentBy is not uint differentBy) throw new InvalidOperationException();
return watchList.Where(w =>
differentBy == Math.Abs(SignExtendAsNeeded(w.Current) - SignExtendAsNeeded(w.Previous)));
}
@@ -350,7 +343,7 @@ private IEnumerable ComparePrevious(IEnumerable watchLis
return val < prev || val.HawkFloatEquality(prev);
});
case ComparisonOperator.DifferentBy:
- if (DifferentBy is not int differentBy) throw new InvalidOperationException();
+ if (DifferentBy is not uint differentBy) throw new InvalidOperationException();
var differentByF = ReinterpretAsF32(differentBy);
return watchList.Where(w => Math.Abs(ReinterpretAsF32(w.Current) - ReinterpretAsF32(w.Previous))
.HawkFloatEquality(differentByF));
@@ -359,7 +352,7 @@ private IEnumerable ComparePrevious(IEnumerable watchLis
private IEnumerable CompareSpecificValue(IEnumerable watchList)
{
- if (CompareValue is not long compareValue) throw new InvalidOperationException();
+ if (CompareValue is not uint compareValue) throw new InvalidOperationException();
if (_settings.Type is not WatchDisplayType.Float)
{
switch (Operator)
@@ -378,7 +371,7 @@ private IEnumerable CompareSpecificValue(IEnumerable wat
case ComparisonOperator.LessThanEqual:
return watchList.Where(w => SignExtendAsNeeded(w.Current) <= SignExtendAsNeeded(compareValue));
case ComparisonOperator.DifferentBy:
- if (DifferentBy is not int differentBy) throw new InvalidOperationException();
+ if (DifferentBy is not uint differentBy) throw new InvalidOperationException();
return watchList.Where(w =>
differentBy == Math.Abs(SignExtendAsNeeded(w.Current) - SignExtendAsNeeded(compareValue)));
}
@@ -408,7 +401,7 @@ private IEnumerable CompareSpecificValue(IEnumerable wat
return val < compareValueF || val.HawkFloatEquality(compareValueF);
});
case ComparisonOperator.DifferentBy:
- if (DifferentBy is not int differentBy) throw new InvalidOperationException();
+ if (DifferentBy is not uint differentBy) throw new InvalidOperationException();
var differentByF = ReinterpretAsF32(differentBy);
return watchList.Where(w => Math.Abs(ReinterpretAsF32(w.Current) - compareValueF)
.HawkFloatEquality(differentByF));
@@ -417,7 +410,7 @@ private IEnumerable CompareSpecificValue(IEnumerable wat
private IEnumerable CompareSpecificAddress(IEnumerable watchList)
{
- if (CompareValue is not long compareValue) throw new InvalidOperationException();
+ if (CompareValue is not uint compareValue) throw new InvalidOperationException();
switch (Operator)
{
default:
@@ -434,14 +427,14 @@ private IEnumerable CompareSpecificAddress(IEnumerable w
case ComparisonOperator.LessThanEqual:
return watchList.Where(w => w.Address <= compareValue);
case ComparisonOperator.DifferentBy:
- if (DifferentBy is not int differentBy) throw new InvalidOperationException();
+ if (DifferentBy is not uint differentBy) throw new InvalidOperationException();
return watchList.Where(w => Math.Abs(w.Address - compareValue) == differentBy);
}
}
private IEnumerable CompareChanges(IEnumerable watchList)
{
- if (CompareValue is not long compareValue) throw new InvalidOperationException();
+ if (CompareValue is not uint compareValue) throw new InvalidOperationException();
switch (Operator)
{
default:
@@ -458,14 +451,14 @@ private IEnumerable CompareChanges(IEnumerable watchList
case ComparisonOperator.LessThanEqual:
return watchList.Where(w => w.ChangeCount <= compareValue);
case ComparisonOperator.DifferentBy:
- if (DifferentBy is not int differentBy) throw new InvalidOperationException();
+ if (DifferentBy is not uint differentBy) throw new InvalidOperationException();
return watchList.Where(w => Math.Abs(w.ChangeCount - compareValue) == differentBy);
}
}
private IEnumerable CompareDifference(IEnumerable watchList)
{
- if (CompareValue is not long compareValue) throw new InvalidCastException(); //TODO typo for IOE?
+ if (CompareValue is not uint compareValue) throw new InvalidCastException(); //TODO typo for IOE?
if (_settings.Type is not WatchDisplayType.Float)
{
switch (Operator)
@@ -484,9 +477,9 @@ private IEnumerable CompareDifference(IEnumerable watchL
case ComparisonOperator.LessThanEqual:
return watchList.Where(w => SignExtendAsNeeded(w.Current) - SignExtendAsNeeded(w.Previous) <= compareValue);
case ComparisonOperator.DifferentBy:
- if (DifferentBy is not int differentBy) throw new InvalidOperationException();
+ if (DifferentBy is not uint differentBy) throw new InvalidOperationException();
return watchList.Where(w =>
- differentBy == Math.Abs(SignExtendAsNeeded(w.Current) - SignExtendAsNeeded(w.Previous) - compareValue));
+ differentBy == Math.Abs(Math.Abs(SignExtendAsNeeded(w.Current) - SignExtendAsNeeded(w.Previous)) - compareValue));
}
}
var compareValueF = ReinterpretAsF32(compareValue);
@@ -514,7 +507,7 @@ private IEnumerable CompareDifference(IEnumerable watchL
return diff < compareValueF || diff.HawkFloatEquality(compareValueF);
});
case ComparisonOperator.DifferentBy:
- if (DifferentBy is not int differentBy) throw new InvalidOperationException();
+ if (DifferentBy is not uint 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 6c9645ba5e2..bc5f4df3a77 100644
--- a/src/BizHawk.Client.Common/tools/Watch/DWordWatch.cs
+++ b/src/BizHawk.Client.Common/tools/Watch/DWordWatch.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
+using BizHawk.Common.NumberExtensions;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.Common
@@ -84,7 +85,7 @@ public override bool Poke(string value)
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 => BitConverter.ToUInt32(BitConverter.GetBytes(float.Parse(value, NumberFormatInfo.InvariantInfo)), 0),
+ WatchDisplayType.Float => NumberExtensions.ReinterpretAsUInt32(float.Parse(value, NumberFormatInfo.InvariantInfo)),
_ => 0
};
@@ -133,8 +134,7 @@ public string FormatValue(uint val)
{
string FormatFloat()
{
- var bytes = BitConverter.GetBytes(val);
- var _float = BitConverter.ToSingle(bytes, 0);
+ var _float = NumberExtensions.ReinterpretAsF32(val);
return _float.ToString(NumberFormatInfo.InvariantInfo);
}
diff --git a/src/BizHawk.Client.EmuHawk/CustomControls/HexTextBox.cs b/src/BizHawk.Client.EmuHawk/CustomControls/HexTextBox.cs
index 7196a110b8f..f1c313c0b81 100644
--- a/src/BizHawk.Client.EmuHawk/CustomControls/HexTextBox.cs
+++ b/src/BizHawk.Client.EmuHawk/CustomControls/HexTextBox.cs
@@ -11,8 +11,8 @@ namespace BizHawk.Client.EmuHawk
public interface INumberBox
{
bool Nullable { get; }
- int? ToRawInt();
- void SetFromRawInt(int? rawInt);
+ uint? ToRawUInt();
+ void SetFromRawUInt(uint? rawUInt);
}
public class HexTextBox : ClipboardEventTextBox, INumberBox
@@ -86,7 +86,7 @@ protected override void OnKeyDown(KeyEventArgs e)
{
if (Text.IsHex() && !string.IsNullOrEmpty(_addressFormatStr))
{
- var val = (uint)ToRawInt();
+ var val = ToRawUInt();
if (val == GetMax())
{
@@ -104,7 +104,7 @@ protected override void OnKeyDown(KeyEventArgs e)
{
if (Text.IsHex() && !string.IsNullOrEmpty(_addressFormatStr))
{
- var val = (uint)ToRawInt();
+ var val = ToRawUInt();
if (val == 0)
{
val = (uint)GetMax(); // int to long todo
@@ -147,7 +147,7 @@ protected override void OnPaste(PasteEventArgs e)
base.OnPaste(e);
}
- public int? ToRawInt()
+ public uint? ToRawUInt()
{
if (string.IsNullOrWhiteSpace(Text))
{
@@ -159,10 +159,10 @@ protected override void OnPaste(PasteEventArgs e)
return 0;
}
- return int.Parse(Text, NumberStyles.HexNumber);
+ return uint.Parse(Text, NumberStyles.HexNumber);
}
- public void SetFromRawInt(int? val)
+ public void SetFromRawUInt(uint? val)
{
Text = val.HasValue ? string.Format(_addressFormatStr, val) : "";
}
@@ -231,7 +231,7 @@ protected override void OnKeyDown(KeyEventArgs e)
{
if (Text.IsHex())
{
- var val = (uint)ToRawInt();
+ var val = ToRawUInt().Value;
if (val == uint.MaxValue)
{
val = 0;
@@ -248,7 +248,7 @@ protected override void OnKeyDown(KeyEventArgs e)
{
if (Text.IsHex())
{
- var val = (uint)ToRawInt();
+ var val = ToRawUInt().Value;
if (val == 0)
{
@@ -280,7 +280,7 @@ protected override void OnTextChanged(EventArgs e)
base.OnTextChanged(e);
}
- public int? ToRawInt()
+ public uint? ToRawUInt()
{
if (string.IsNullOrWhiteSpace(Text) || !Text.IsHex())
{
@@ -292,10 +292,10 @@ protected override void OnTextChanged(EventArgs e)
return 0;
}
- return (int)uint.Parse(Text);
+ return uint.Parse(Text);
}
- public void SetFromRawInt(int? val)
+ public void SetFromRawUInt(uint? val)
{
Text = val?.ToString() ?? "";
}
diff --git a/src/BizHawk.Client.EmuHawk/movie/PlayMovie.cs b/src/BizHawk.Client.EmuHawk/movie/PlayMovie.cs
index 93440700ea7..df93e2ba480 100644
--- a/src/BizHawk.Client.EmuHawk/movie/PlayMovie.cs
+++ b/src/BizHawk.Client.EmuHawk/movie/PlayMovie.cs
@@ -594,7 +594,7 @@ private void Ok_Click(object sender, EventArgs e)
if (StopOnFrameCheckbox.Checked)
{
if (LastFrameCheckbox.Checked) _mainForm.PauseOnFrame = _movieSession.Movie.InputLogLength;
- else if (StopOnFrameTextBox.ToRawInt() is int i) _mainForm.PauseOnFrame = i;
+ else if (StopOnFrameTextBox.ToRawUInt() is uint i) _mainForm.PauseOnFrame = (int)i;
}
Close();
}
diff --git a/src/BizHawk.Client.EmuHawk/tools/Cheats/CheatEdit.cs b/src/BizHawk.Client.EmuHawk/tools/Cheats/CheatEdit.cs
index 8f1e470b1d3..19081fe1276 100644
--- a/src/BizHawk.Client.EmuHawk/tools/Cheats/CheatEdit.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/Cheats/CheatEdit.cs
@@ -94,7 +94,7 @@ private void SetFormToCheat()
CheckFormState();
if (!_cheat.Compare.HasValue)
{
- CompareBox.Text = ""; // Necessary hack until WatchValueBox.ToRawInt() becomes nullable
+ CompareBox.Text = ""; // Necessary hack until WatchValueBox.ToRawUInt() becomes nullable
}
_loading = false;
@@ -133,7 +133,7 @@ private void SetFormToDefault()
SetTypeSelected(WatchDisplayType.Hex);
CheckFormState();
- CompareBox.Text = ""; // TODO: A needed hack until WatchValueBox.ToRawInt() becomes nullable
+ CompareBox.Text = ""; // TODO: A needed hack until WatchValueBox.ToRawUInt() becomes nullable
_loading = false;
}
@@ -311,7 +311,7 @@ public void ClearForm()
public Cheat GetCheat()
{
var domain = MemoryDomains[DomainDropDown.SelectedItem.ToString()]!;
- var address = AddressBox.ToRawInt().Value;
+ var address = AddressBox.ToRawUInt().Value;
if (address < domain.Size)
{
var watch = Watch.GenerateWatch(
@@ -334,11 +334,11 @@ public Cheat GetCheat()
_ => Cheat.CompareType.None
};
- var compare = CompareBox.ToRawInt();
+ var compare = CompareBox.ToRawUInt();
return new Cheat(
watch,
- value: ValueBox.ToRawInt().Value,
- compare: compare,
+ value: (int)ValueBox.ToRawUInt().Value,
+ compare: (int?)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 eec013cd2a0..c07c02b039e 100644
--- a/src/BizHawk.Client.EmuHawk/tools/Debugger/AddBreakpointDialog.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/Debugger/AddBreakpointDialog.cs
@@ -101,13 +101,13 @@ public MemoryCallbackType BreakType
public uint Address
{
- get => (uint)AddressBox.ToRawInt().Value & AddressMask;
+ get => AddressBox.ToRawUInt().Value & AddressMask;
set => AddressBox.SetFromLong(value & AddressMask);
}
public uint AddressMask
{
- get => (uint)AddressMaskBox.ToRawInt().Value;
+ get => AddressMaskBox.ToRawUInt().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 2b4b3fba8e3..172fc491b42 100644
--- a/src/BizHawk.Client.EmuHawk/tools/Debugger/GenericDebugger.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/Debugger/GenericDebugger.cs
@@ -119,7 +119,7 @@ Control GenCPUPicker()
var pc = PCRegister;
SeekToBox.Nullable = false;
SeekToBox.SetHexProperties((long)Math.Pow(2, pc.BitSize));
- SeekToBox.SetFromRawInt(0);
+ SeekToBox.SetFromRawUInt(0);
}
else
{
@@ -264,7 +264,7 @@ public void DisableCancelSeekBtn()
private void SeekToBtn_Click(object sender, EventArgs e)
{
CancelSeekBtn.Enabled = true;
- var pcVal = (uint)(SeekToBox.ToRawInt() ?? 0);
+ var pcVal = SeekToBox.ToRawUInt() ?? 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 25127ef6d06..84f3b75e038 100644
--- a/src/BizHawk.Client.EmuHawk/tools/TAStudio/FramesPrompt.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/TAStudio/FramesPrompt.cs
@@ -18,7 +18,7 @@ public FramesPrompt(string headMessage, string bodyMessage)
this.label1.Text = bodyMessage;
}
- public int Frames => NumFramesBox.ToRawInt() ?? 0;
+ public int Frames => (int)(NumFramesBox.ToRawUInt() ?? 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 a5be0de254c..a017384500f 100644
--- a/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/Watch/RamSearch.cs
@@ -422,7 +422,7 @@ private void ToggleSearchDependentToolBarItems()
WatchListView.AnyRowsSelected && _searches.Domain.Writable;
}
- private long? CompareToValue
+ private uint? CompareToValue
{
get
{
@@ -433,29 +433,29 @@ private long? CompareToValue
if (SpecificValueRadio.Checked)
{
- return (long)SpecificValueBox.ToRawInt() & 0x00000000FFFFFFFF;
+ return SpecificValueBox.ToRawUInt();
}
if (SpecificAddressRadio.Checked)
{
- return SpecificAddressBox.ToRawInt();
+ return SpecificAddressBox.ToRawUInt();
}
if (NumberOfChangesRadio.Checked)
{
- return NumberOfChangesBox.ToRawInt();
+ return NumberOfChangesBox.ToRawUInt();
}
if (DifferenceRadio.Checked)
{
- return DifferenceBox.ToRawInt();
+ return DifferenceBox.ToRawUInt();
}
return null;
}
}
- private int? DifferentByValue => DifferentByRadio.Checked ? DifferentByBox.ToRawInt() : null;
+ private uint? DifferentByValue => DifferentByRadio.Checked ? DifferentByBox.ToRawUInt() : null;
private ComparisonOperator Operator
{
@@ -738,7 +738,7 @@ private void SetCompareTo(Compare comp)
WatchListView.Refresh();
}
- private void SetCompareValue(int? value)
+ private void SetCompareValue(uint? value)
{
_searches.CompareValue = value;
WatchListView.Refresh();
@@ -1446,7 +1446,7 @@ private void SpecificValueRadio_Click(object sender, EventArgs e)
SpecificAddressBox.ResetText();
}
- _searches.CompareValue = SpecificValueBox.ToRawInt();
+ _searches.CompareValue = SpecificValueBox.ToRawUInt();
if (Focused)
{
@@ -1468,7 +1468,7 @@ private void SpecificAddressRadio_Click(object sender, EventArgs e)
SpecificAddressBox.ResetText();
}
- _searches.CompareValue = SpecificAddressBox.ToRawInt();
+ _searches.CompareValue = SpecificAddressBox.ToRawUInt();
if (Focused)
{
@@ -1490,7 +1490,7 @@ private void NumberOfChangesRadio_Click(object sender, EventArgs e)
NumberOfChangesBox.ResetText();
}
- _searches.CompareValue = NumberOfChangesBox.ToRawInt();
+ _searches.CompareValue = NumberOfChangesBox.ToRawUInt();
if (Focused)
{
@@ -1512,7 +1512,7 @@ private void DifferenceRadio_Click(object sender, EventArgs e)
DifferenceBox.ResetText();
}
- _searches.CompareValue = DifferenceBox.ToRawInt();
+ _searches.CompareValue = DifferenceBox.ToRawUInt();
if (Focused)
{
@@ -1524,7 +1524,7 @@ private void DifferenceRadio_Click(object sender, EventArgs e)
private void CompareToValue_TextChanged(object sender, EventArgs e)
{
- SetCompareValue(((INumberBox)sender).ToRawInt());
+ SetCompareValue(((INumberBox)sender).ToRawUInt());
}
private void EqualToRadio_Click(object sender, EventArgs e)
@@ -1572,7 +1572,7 @@ private void DifferentByRadio_Click(object sender, EventArgs e)
DifferentByBox.ResetText();
}
- _searches.DifferentBy = DifferenceBox.ToRawInt();
+ _searches.DifferentBy = DifferenceBox.ToRawUInt();
if (Focused)
{
@@ -1584,7 +1584,7 @@ private void DifferentByRadio_Click(object sender, EventArgs e)
private void DifferentByBox_TextChanged(object sender, EventArgs e)
{
- _searches.DifferentBy = !string.IsNullOrWhiteSpace(DifferentByBox.Text) ? DifferentByBox.ToRawInt() : null;
+ _searches.DifferentBy = !string.IsNullOrWhiteSpace(DifferentByBox.Text) ? DifferentByBox.ToRawUInt() : null;
WatchListView.Refresh();
}
diff --git a/src/BizHawk.Client.EmuHawk/tools/Watch/WatchEditor.cs b/src/BizHawk.Client.EmuHawk/tools/Watch/WatchEditor.cs
index 7b20ab3490d..316485c51fd 100644
--- a/src/BizHawk.Client.EmuHawk/tools/Watch/WatchEditor.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/Watch/WatchEditor.cs
@@ -276,7 +276,7 @@ private void DoEdit()
Watches[i] = Watch.GenerateWatch(
Watches[i].Domain,
- Watches.Count == 1 ? AddressBox.ToRawInt() ?? 0 : Watches[i].Address,
+ Watches.Count == 1 ? AddressBox.ToRawUInt() ?? 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 79263daff92..0566345dd99 100644
--- a/src/BizHawk.Client.EmuHawk/tools/Watch/WatchValueBox.cs
+++ b/src/BizHawk.Client.EmuHawk/tools/Watch/WatchValueBox.cs
@@ -56,10 +56,10 @@ public WatchDisplayType Type
get => _type;
set
{
- var val = ToRawInt();
+ var val = ToRawUInt();
_type = value;
SetMaxLength();
- SetFromRawInt(val);
+ SetFromRawUInt(val);
}
}
@@ -197,7 +197,7 @@ protected override void OnKeyDown(KeyEventArgs e)
{
default:
case WatchDisplayType.Signed:
- int val = ToRawInt() ?? 0;
+ int val = (int)(ToRawUInt() ?? 0);
if (val == MaxSignedInt)
{
val = MinSignedInt;
@@ -210,7 +210,7 @@ protected override void OnKeyDown(KeyEventArgs e)
Text = val.ToString();
break;
case WatchDisplayType.Unsigned:
- var uval = (uint)(ToRawInt() ?? 0);
+ var uval = ToRawUInt() ?? 0;
if (uval == MaxUnsignedInt)
{
uval = 0;
@@ -223,7 +223,7 @@ protected override void OnKeyDown(KeyEventArgs e)
Text = uval.ToString();
break;
case WatchDisplayType.Binary:
- var bVal = (uint)(ToRawInt() ?? 0);
+ var bVal = ToRawUInt() ?? 0;
if (bVal == MaxUnsignedInt)
{
bVal = 0;
@@ -237,7 +237,7 @@ protected override void OnKeyDown(KeyEventArgs e)
Text = Convert.ToString(bVal, 2).PadLeft(numBits, '0');
break;
case WatchDisplayType.Hex:
- var hexVal = (uint)(ToRawInt() ?? 0);
+ var hexVal = ToRawUInt() ?? 0;
if (hexVal == MaxUnsignedInt)
{
hexVal = 0;
@@ -309,7 +309,7 @@ protected override void OnKeyDown(KeyEventArgs e)
{
default:
case WatchDisplayType.Signed:
- int val = ToRawInt() ?? 0;
+ int val = (int)(ToRawUInt() ?? 0);
if (val == MinSignedInt)
{
val = MaxSignedInt;
@@ -322,7 +322,7 @@ protected override void OnKeyDown(KeyEventArgs e)
Text = val.ToString();
break;
case WatchDisplayType.Unsigned:
- var uval = (uint)(ToRawInt() ?? 0);
+ var uval = ToRawUInt() ?? 0;
if (uval == 0)
{
uval = MaxUnsignedInt;
@@ -335,7 +335,7 @@ protected override void OnKeyDown(KeyEventArgs e)
Text = uval.ToString();
break;
case WatchDisplayType.Binary:
- var bVal = (uint)(ToRawInt() ?? 0);
+ var bVal = ToRawUInt() ?? 0;
if (bVal == 0)
{
bVal = MaxUnsignedInt;
@@ -349,7 +349,7 @@ protected override void OnKeyDown(KeyEventArgs e)
Text = Convert.ToString(bVal, 2).PadLeft(numBits, '0');
break;
case WatchDisplayType.Hex:
- var hexVal = (uint)(ToRawInt() ?? 0);
+ var hexVal = ToRawUInt() ?? 0;
if (hexVal == 0)
{
hexVal = MaxUnsignedInt;
@@ -445,21 +445,21 @@ protected override void OnPaste(PasteEventArgs e)
base.OnPaste(e);
}
- public int? ToRawInt()
+ public uint? ToRawUInt()
{
try
{
return _type switch
{
- 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)
+ 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)
};
}
catch
@@ -470,7 +470,7 @@ protected override void OnPaste(PasteEventArgs e)
return Nullable ? null : 0;
}
- public void SetFromRawInt(int? val)
+ public void SetFromRawUInt(uint? val)
{
if (val.HasValue)
{
@@ -481,11 +481,11 @@ public void SetFromRawInt(int? val)
Text = val.Value.ToString();
break;
case WatchDisplayType.Unsigned:
- var uval = (uint)val.Value;
+ var uval = val.Value;
Text = uval.ToString();
break;
case WatchDisplayType.Binary:
- var bVal = (uint)val.Value;
+ var bVal = val.Value;
var numBits = ((int)ByteSize) * 8;
Text = Convert.ToString(bVal, 2).PadLeft(numBits, '0');
break;
@@ -502,8 +502,7 @@ public void SetFromRawInt(int? val)
Text = (val.Value / 65536.0).ToString("F5", NumberFormatInfo.InvariantInfo);
break;
case WatchDisplayType.Float:
- var bytes = BitConverter.GetBytes(val.Value);
- float _float = BitConverter.ToSingle(bytes, 0);
+ float _float = NumberExtensions.ReinterpretAsF32(val.Value);
Text = _float.ToString("F6", NumberFormatInfo.InvariantInfo);
break;
}
diff --git a/src/BizHawk.Common/Extensions/NumberExtensions.cs b/src/BizHawk.Common/Extensions/NumberExtensions.cs
index 204e723489c..237d002bd48 100644
--- a/src/BizHawk.Common/Extensions/NumberExtensions.cs
+++ b/src/BizHawk.Common/Extensions/NumberExtensions.cs
@@ -1,5 +1,6 @@
using System;
using System.Linq;
+using System.Runtime.CompilerServices;
namespace BizHawk.Common.NumberExtensions
{
@@ -144,5 +145,11 @@ public static void RotateRightU8(ref byte b, int shift)
/// 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 e4f17db3fbd..527b29bcfa2 100644
--- a/src/BizHawk.Tests/Common/ConversionTests.cs
+++ b/src/BizHawk.Tests/Common/ConversionTests.cs
@@ -1,41 +1,25 @@
-using System;
-using System.Buffers.Binary;
-using System.Runtime.CompilerServices;
+using BizHawk.Common.NumberExtensions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace BizHawk.Tests.Common;
-// test for RamSearchEngine.ReinterpretAsF32
[TestClass]
public class ConversionTests
{
- private static float ReinterpretAsF32Unsafe(long l)
+ [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)
{
- return Unsafe.As(ref l);
- }
+ float converted = NumberExtensions.ReinterpretAsF32(input);
- private static readonly byte[] ScratchSpace = new byte[8];
+ Assert.AreEqual(expected, converted);
- private static float ReinterpretAsF32BitConverter(long l)
- {
- BinaryPrimitives.WriteInt64LittleEndian(ScratchSpace, l);
- return BitConverter.ToSingle(ScratchSpace, startIndex: 0);
- }
-
- [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);
+ uint restoredInput = NumberExtensions.ReinterpretAsUInt32(converted);
- Assert.AreEqual(expected, f32BitConverter);
- Assert.AreEqual(expected, f32Unsafe);
+ Assert.AreEqual(input, restoredInput);
}
}