/** * <summary>Performs a bitwise shift to the left on a <see cref="ulong"/> with wraparound. * <para>The <paramref name="positions"/> parameter is clamped to the range * 0 to 63 inclusive.</para></summary> * <param name="number">The value to shift.</param> * <param name="positions">How many positions to shift.</param> * <seealso cref="https://docs.microsoft.com/en-us/dotnet/api/system.object.gethashcode?view=netframework-4.7.2"/> */ public static ulong BitShiftLeft(ulong number, ulong positions) { // Ensure: 0 <= positions <= 63 positions = positions.Clamp(0, Bits64 - 1); int intPos = (int)positions; // Preserve the bits to be discarded ulong wrapped = number >> (Bits64 - intPos); // Shift and wrap the discarded bits return((number << intPos) | wrapped); }
public void ClampULongTest() { for (ulong i = 0; i < 40; i++) { for (ulong j = 0; j < 40; j++) { for (ulong k = 0; k < 60; k++) { if (i < j) { var l = k.Clamp(i, j); Assert.GreaterOrEqual(l, i); Assert.LessOrEqual(l, j); } else { var l = k.Clamp(j, i); Assert.GreaterOrEqual(l, j); Assert.LessOrEqual(l, i); } } } } }
public void Render <T>(T data, List <EntryRange> ranges, int i, ulong addressMin, ulong addressMax, Func <Color32, Color32> func) where T : CachedSnapshot.ISortedEntriesCache { for (int j = ranges[i].Begin; j < ranges[i].End; ++j) { ulong addr = (ulong)data.Address(j); ulong size = (ulong)data.Size(j); ulong stripAddrBegin = addr.Clamp(addressMin, addressMax); ulong stripAddrEnd = (addr + size).Clamp(addressMin, addressMax); if (stripAddrBegin != stripAddrEnd) { RenderStrip(m_Groups[i], stripAddrBegin, stripAddrEnd, func); } } }
public static ushort GetChannelTimer(ushort baseTimer, int pitch) { int remainder = 0; int pitchTableIndex = -pitch; // Positive pitch: while (pitchTableIndex < 0) { remainder--; pitchTableIndex += 768; } // Negative pitch: while (pitchTableIndex >= 768) { remainder++; pitchTableIndex -= 768; } ulong timer = (PitchTable[pitchTableIndex] + 0x10000uL) * baseTimer; remainder -= 0x10; if (remainder <= 0) { timer >>= -remainder; } else { if (remainder >= 0x20) { return(0xFF); } if ((timer & (ulong.MaxValue << (0x20 - remainder))) != 0) { return(ushort.MaxValue); } timer <<= remainder; } return((ushort)timer.Clamp(0x10uL, ushort.MaxValue)); }
public void RenderDiff <T>(T data0, List <EntryRange> ranges0, T data1, List <EntryRange> ranges1, int i, ulong addressMin, ulong addressMax) where T : CachedSnapshot.ISortedEntriesCache { MemoryGroup group = m_Groups[i]; int index0 = ranges0[i].Begin; int lastIndex0 = ranges0[i].End; while (index0 < lastIndex0 && data0.Address(index0) + data0.Size(index0) <= addressMin) { index0++; } int index1 = ranges1[i].Begin; int lastIndex1 = ranges1[i].End; while (index1 < lastIndex1 && data1.Address(index1) + data1.Size(index1) <= addressMin) { index1++; } while (index0 < lastIndex0 || index1 < lastIndex1) { ulong addr0 = index0 < lastIndex0?data0.Address(index0) : addressMax; ulong addr1 = index1 < lastIndex1?data1.Address(index1) : addressMax; if (addr0 >= addressMax && addr1 >= addressMax) { // There is no need to process entries anymore because I assuming they are sorted. return; } ulong size0 = index0 < lastIndex0?data0.Size(index0) : 0; ulong size1 = index1 < lastIndex1?data1.Size(index1) : 0; if (addr0 == addr1 && size0 == size1) { ulong stripAddrBegin = addr0.Clamp(addressMin, addressMax); ulong stripAddrEnd = (addr0 + size0).Clamp(addressMin, addressMax); if (stripAddrBegin != stripAddrEnd) { RenderStrip(group, stripAddrBegin, stripAddrEnd, (Color32 c) => Add(c, new Color32(0x00, 0x00, 0x0F, 0x00))); } index0++; index1++; } else { if (addr0 < addr1 || (addr0 == addr1 && size0 != size1)) { ulong stripAddrBegin = addr0.Clamp(addressMin, addressMax); ulong stripAddrEnd = (addr0 + size0).Clamp(addressMin, addressMax); if (stripAddrBegin != stripAddrEnd) { RenderStrip(group, stripAddrBegin, stripAddrEnd, (Color32 c) => Add(c, new Color32(0x0F, 0x00, 0x00, 0x00))); } index0++; } if (addr0 > addr1 || (addr0 == addr1 && size0 != size1)) { ulong stripAddrBegin = addr1.Clamp(addressMin, addressMax); ulong stripAddrEnd = (addr1 + size1).Clamp(addressMin, addressMax); if (stripAddrBegin != stripAddrEnd) { RenderStrip(group, stripAddrBegin, stripAddrEnd, (Color32 c) => Add(c, new Color32(0x00, 0x0F, 0x00, 0x00))); } index1++; } } } }