Change ToRawInt to ToRawUInt
I firmly believe this has advantages. Don't ask me which. Also move ReinterpretAsF32 to BizHawk.Common and use it more
This commit is contained in:
parent
a329d076f0
commit
542e043261
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
|
||||
using BizHawk.Common;
|
||||
using BizHawk.Common.NumberExtensions;
|
||||
using BizHawk.Emulation.Common;
|
||||
|
||||
namespace BizHawk.Client.Common
|
||||
|
@ -287,7 +288,7 @@ namespace BizHawk.Client.Common
|
|||
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 @@ namespace BizHawk.Client.Common
|
|||
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);
|
||||
|
|
|
@ -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 @@ namespace BizHawk.Client.Common.RamSearchEngine
|
|||
_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 @@ namespace BizHawk.Client.Common.RamSearchEngine
|
|||
_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 @@ namespace BizHawk.Client.Common.RamSearchEngine
|
|||
_previous = _current;
|
||||
}
|
||||
|
||||
public long Previous => _previous;
|
||||
public long Current => _current;
|
||||
public uint Previous => _previous;
|
||||
public uint Current => _current;
|
||||
|
||||
public int ChangeCount { get; private set; }
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
/// <remarks>TODO move to BizHawk.Common</remarks>
|
||||
private static float ReinterpretAsF32(long l)
|
||||
{
|
||||
return Unsafe.As<long, float>(ref l);
|
||||
}
|
||||
|
||||
private Compare _compareTo = Compare.Previous;
|
||||
|
||||
private IMiniWatch[] _watchList = [ ];
|
||||
|
@ -39,7 +32,7 @@ namespace BizHawk.Client.Common.RamSearchEngine
|
|||
};
|
||||
}
|
||||
|
||||
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 @@ namespace BizHawk.Client.Common.RamSearchEngine
|
|||
}
|
||||
}
|
||||
|
||||
public long? CompareValue { get; set; }
|
||||
public uint? CompareValue { get; set; }
|
||||
|
||||
public ComparisonOperator Operator { get; set; }
|
||||
|
||||
|
@ -165,7 +158,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.<br/>
|
||||
/// it already supported floats by way of reinterpret-cast, it just wasn't implemented correctly on this side --yoshi
|
||||
/// </remarks>
|
||||
public int? DifferentBy { get; set; }
|
||||
public uint? DifferentBy { get; set; }
|
||||
|
||||
public void Update(bool updatePrevious)
|
||||
{
|
||||
|
@ -319,7 +312,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 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 @@ namespace BizHawk.Client.Common.RamSearchEngine
|
|||
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 @@ namespace BizHawk.Client.Common.RamSearchEngine
|
|||
|
||||
private IEnumerable<IMiniWatch> CompareSpecificValue(IEnumerable<IMiniWatch> 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 @@ namespace BizHawk.Client.Common.RamSearchEngine
|
|||
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 @@ namespace BizHawk.Client.Common.RamSearchEngine
|
|||
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 @@ namespace BizHawk.Client.Common.RamSearchEngine
|
|||
|
||||
private IEnumerable<IMiniWatch> CompareSpecificAddress(IEnumerable<IMiniWatch> 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 @@ namespace BizHawk.Client.Common.RamSearchEngine
|
|||
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<IMiniWatch> CompareChanges(IEnumerable<IMiniWatch> 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 @@ namespace BizHawk.Client.Common.RamSearchEngine
|
|||
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<IMiniWatch> CompareDifference(IEnumerable<IMiniWatch> 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 @@ 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 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 @@ namespace BizHawk.Client.Common.RamSearchEngine
|
|||
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));
|
||||
|
|
|
@ -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 @@ 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 => BitConverter.ToUInt32(BitConverter.GetBytes(float.Parse(value, NumberFormatInfo.InvariantInfo)), 0),
|
||||
WatchDisplayType.Float => NumberExtensions.ReinterpretAsUInt32(float.Parse(value, NumberFormatInfo.InvariantInfo)),
|
||||
_ => 0
|
||||
};
|
||||
|
||||
|
@ -133,8 +134,7 @@ namespace BizHawk.Client.Common
|
|||
{
|
||||
string FormatFloat()
|
||||
{
|
||||
var bytes = BitConverter.GetBytes(val);
|
||||
var _float = BitConverter.ToSingle(bytes, 0);
|
||||
var _float = NumberExtensions.ReinterpretAsF32(val);
|
||||
return _float.ToString(NumberFormatInfo.InvariantInfo);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
if (Text.IsHex() && !string.IsNullOrEmpty(_addressFormatStr))
|
||||
{
|
||||
var val = (uint)ToRawInt();
|
||||
var val = ToRawUInt();
|
||||
|
||||
if (val == GetMax())
|
||||
{
|
||||
|
@ -104,7 +104,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
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 @@ namespace BizHawk.Client.EmuHawk
|
|||
base.OnPaste(e);
|
||||
}
|
||||
|
||||
public int? ToRawInt()
|
||||
public uint? ToRawUInt()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Text))
|
||||
{
|
||||
|
@ -159,10 +159,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
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 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
if (Text.IsHex())
|
||||
{
|
||||
var val = (uint)ToRawInt();
|
||||
var val = ToRawUInt().Value;
|
||||
if (val == uint.MaxValue)
|
||||
{
|
||||
val = 0;
|
||||
|
@ -248,7 +248,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
if (Text.IsHex())
|
||||
{
|
||||
var val = (uint)ToRawInt();
|
||||
var val = ToRawUInt().Value;
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
|
@ -280,7 +280,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
base.OnTextChanged(e);
|
||||
}
|
||||
|
||||
public int? ToRawInt()
|
||||
public uint? ToRawUInt()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Text) || !Text.IsHex())
|
||||
{
|
||||
|
@ -292,10 +292,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
return 0;
|
||||
}
|
||||
|
||||
return (int)uint.Parse(Text);
|
||||
return uint.Parse(Text);
|
||||
}
|
||||
|
||||
public void SetFromRawInt(int? val)
|
||||
public void SetFromRawUInt(uint? val)
|
||||
{
|
||||
Text = val?.ToString() ?? "";
|
||||
}
|
||||
|
|
|
@ -594,7 +594,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
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();
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
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 @@ namespace BizHawk.Client.EmuHawk
|
|||
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 @@ namespace BizHawk.Client.EmuHawk
|
|||
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 @@ namespace BizHawk.Client.EmuHawk
|
|||
_ => 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);
|
||||
}
|
||||
|
|
|
@ -101,13 +101,13 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
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 @@ namespace BizHawk.Client.EmuHawk
|
|||
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();
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
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)
|
||||
{
|
||||
|
|
|
@ -422,7 +422,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
WatchListView.AnyRowsSelected && _searches.Domain.Writable;
|
||||
}
|
||||
|
||||
private long? CompareToValue
|
||||
private uint? CompareToValue
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -433,29 +433,29 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
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 @@ namespace BizHawk.Client.EmuHawk
|
|||
WatchListView.Refresh();
|
||||
}
|
||||
|
||||
private void SetCompareValue(int? value)
|
||||
private void SetCompareValue(uint? value)
|
||||
{
|
||||
_searches.CompareValue = value;
|
||||
WatchListView.Refresh();
|
||||
|
@ -1446,7 +1446,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
SpecificAddressBox.ResetText();
|
||||
}
|
||||
|
||||
_searches.CompareValue = SpecificValueBox.ToRawInt();
|
||||
_searches.CompareValue = SpecificValueBox.ToRawUInt();
|
||||
|
||||
if (Focused)
|
||||
{
|
||||
|
@ -1468,7 +1468,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
SpecificAddressBox.ResetText();
|
||||
}
|
||||
|
||||
_searches.CompareValue = SpecificAddressBox.ToRawInt();
|
||||
_searches.CompareValue = SpecificAddressBox.ToRawUInt();
|
||||
|
||||
if (Focused)
|
||||
{
|
||||
|
@ -1490,7 +1490,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
NumberOfChangesBox.ResetText();
|
||||
}
|
||||
|
||||
_searches.CompareValue = NumberOfChangesBox.ToRawInt();
|
||||
_searches.CompareValue = NumberOfChangesBox.ToRawUInt();
|
||||
|
||||
if (Focused)
|
||||
{
|
||||
|
@ -1512,7 +1512,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
DifferenceBox.ResetText();
|
||||
}
|
||||
|
||||
_searches.CompareValue = DifferenceBox.ToRawInt();
|
||||
_searches.CompareValue = DifferenceBox.ToRawUInt();
|
||||
|
||||
if (Focused)
|
||||
{
|
||||
|
@ -1524,7 +1524,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
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 @@ namespace BizHawk.Client.EmuHawk
|
|||
DifferentByBox.ResetText();
|
||||
}
|
||||
|
||||
_searches.DifferentBy = DifferenceBox.ToRawInt();
|
||||
_searches.DifferentBy = DifferenceBox.ToRawUInt();
|
||||
|
||||
if (Focused)
|
||||
{
|
||||
|
@ -1584,7 +1584,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -276,7 +276,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
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,
|
||||
|
|
|
@ -56,10 +56,10 @@ namespace BizHawk.Client.EmuHawk
|
|||
get => _type;
|
||||
set
|
||||
{
|
||||
var val = ToRawInt();
|
||||
var val = ToRawUInt();
|
||||
_type = value;
|
||||
SetMaxLength();
|
||||
SetFromRawInt(val);
|
||||
SetFromRawUInt(val);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -197,7 +197,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
default:
|
||||
case WatchDisplayType.Signed:
|
||||
int val = ToRawInt() ?? 0;
|
||||
int val = (int)(ToRawUInt() ?? 0);
|
||||
if (val == MaxSignedInt)
|
||||
{
|
||||
val = MinSignedInt;
|
||||
|
@ -210,7 +210,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
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 @@ namespace BizHawk.Client.EmuHawk
|
|||
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 @@ namespace BizHawk.Client.EmuHawk
|
|||
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 @@ namespace BizHawk.Client.EmuHawk
|
|||
{
|
||||
default:
|
||||
case WatchDisplayType.Signed:
|
||||
int val = ToRawInt() ?? 0;
|
||||
int val = (int)(ToRawUInt() ?? 0);
|
||||
if (val == MinSignedInt)
|
||||
{
|
||||
val = MaxSignedInt;
|
||||
|
@ -322,7 +322,7 @@ namespace BizHawk.Client.EmuHawk
|
|||
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 @@ namespace BizHawk.Client.EmuHawk
|
|||
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 @@ namespace BizHawk.Client.EmuHawk
|
|||
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 @@ namespace BizHawk.Client.EmuHawk
|
|||
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 @@ namespace BizHawk.Client.EmuHawk
|
|||
return Nullable ? null : 0;
|
||||
}
|
||||
|
||||
public void SetFromRawInt(int? val)
|
||||
public void SetFromRawUInt(uint? val)
|
||||
{
|
||||
if (val.HasValue)
|
||||
{
|
||||
|
@ -481,11 +481,11 @@ namespace BizHawk.Client.EmuHawk
|
|||
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 @@ namespace BizHawk.Client.EmuHawk
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace BizHawk.Common.NumberExtensions
|
||||
{
|
||||
|
@ -144,5 +145,11 @@ namespace BizHawk.Common.NumberExtensions
|
|||
|
||||
/// <remarks>don't use this in cores without picking a suitable ε</remarks>
|
||||
public static bool HawkFloatEquality(this float f, float other, float ε = ReallySmallNumber) => Math.Abs(other - f) < ε;
|
||||
|
||||
/// <summary> Reinterprets the byte representation of <paramref name="value"/> as a float</summary>
|
||||
public static float ReinterpretAsF32(uint value) => Unsafe.As<uint, float>(ref value);
|
||||
|
||||
/// <summary> Reinterprets the byte representation of <paramref name="value"/> as a uint</summary>
|
||||
public static uint ReinterpretAsUInt32(float value) => Unsafe.As<float, uint>(ref value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
return Unsafe.As<long, float>(ref l);
|
||||
}
|
||||
|
||||
private static readonly byte[] ScratchSpace = new byte[8];
|
||||
|
||||
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)
|
||||
[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)
|
||||
{
|
||||
float f32BitConverter = ReinterpretAsF32BitConverter(input);
|
||||
float f32Unsafe = ReinterpretAsF32Unsafe(input);
|
||||
float converted = NumberExtensions.ReinterpretAsF32(input);
|
||||
|
||||
Assert.AreEqual(expected, f32BitConverter);
|
||||
Assert.AreEqual(expected, f32Unsafe);
|
||||
Assert.AreEqual(expected, converted);
|
||||
|
||||
uint restoredInput = NumberExtensions.ReinterpretAsUInt32(converted);
|
||||
|
||||
Assert.AreEqual(input, restoredInput);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue