diff --git a/src/BizHawk.Bizware.Graphics/BitmapBuffer.cs b/src/BizHawk.Bizware.Graphics/BitmapBuffer.cs index df8a1fcdaf..d10795f6d4 100644 --- a/src/BizHawk.Bizware.Graphics/BitmapBuffer.cs +++ b/src/BizHawk.Bizware.Graphics/BitmapBuffer.cs @@ -1,6 +1,7 @@ // TODO - introduce Trim for ArtManager // TODO - add a small buffer reuse manager.. small images can be stored in larger buffers which we happen to have held. use a timer to wait to free it until some time has passed +using System.Buffers.Binary; using System.Diagnostics; using System.Drawing; using System.Drawing.Drawing2D; @@ -468,8 +469,13 @@ namespace BizHawk.Bizware.Graphics r = (r * a) >> 8; g = (g * a) >> 8; b = (b * a) >> 8; - srcVal = b | (g << 8) | (r << 16) | (a << 24); - return srcVal; + return BinaryPrimitives.ReadInt32BigEndian(unchecked(stackalloc byte[] + { + (byte) a, + (byte) r, + (byte) g, + (byte) b, + })); } /// diff --git a/src/BizHawk.Client.EmuHawk/AVOut/AviWriter.cs b/src/BizHawk.Client.EmuHawk/AVOut/AviWriter.cs index ae16339af6..eb623727c9 100644 --- a/src/BizHawk.Client.EmuHawk/AVOut/AviWriter.cs +++ b/src/BizHawk.Client.EmuHawk/AVOut/AviWriter.cs @@ -640,13 +640,6 @@ namespace BizHawk.Client.EmuHawk /// unmanaged call failed public void OpenFile(string destPath, Parameters parameters, CodecToken videoCodecToken) { - static int mmioFOURCC(string str) => ( - (byte)str[0] | - ((byte)str[1] << 8) | - ((byte)str[2] << 16) | - ((byte)str[3] << 24) - ); - this._parameters = parameters; this._currVideoCodecToken = videoCodecToken; @@ -670,7 +663,7 @@ namespace BizHawk.Client.EmuHawk var vidstream_header = default(AVIWriterImports.AVISTREAMINFOW); var bmih = default(AVIWriterImports.BITMAPINFOHEADER); parameters.PopulateBITMAPINFOHEADER24(ref bmih); - vidstream_header.fccType = mmioFOURCC("vids"); + vidstream_header.fccType = /*BinaryPrimitives.ReadInt32LittleEndian("vids"u8)*/0x73646976; vidstream_header.dwRate = parameters.fps; vidstream_header.dwScale = parameters.fps_scale; vidstream_header.dwSuggestedBufferSize = (int)bmih.biSizeImage; @@ -687,7 +680,7 @@ namespace BizHawk.Client.EmuHawk var audstream_header = default(AVIWriterImports.AVISTREAMINFOW); var wfex = default(AVIWriterImports.WAVEFORMATEX); parameters.PopulateWAVEFORMATEX(ref wfex); - audstream_header.fccType = mmioFOURCC("auds"); + audstream_header.fccType = /*BinaryPrimitives.ReadInt32LittleEndian("auds"u8)*/0x73647561; audstream_header.dwQuality = -1; audstream_header.dwScale = wfex.nBlockAlign; audstream_header.dwRate = (int)wfex.nAvgBytesPerSec; diff --git a/src/BizHawk.Client.EmuHawk/RetroAchievements/RCheevos.cs b/src/BizHawk.Client.EmuHawk/RetroAchievements/RCheevos.cs index fb9b25fe90..1bce64e241 100644 --- a/src/BizHawk.Client.EmuHawk/RetroAchievements/RCheevos.cs +++ b/src/BizHawk.Client.EmuHawk/RetroAchievements/RCheevos.cs @@ -1,3 +1,4 @@ +using System.Buffers.Binary; using System.IO; using System.Linq; using System.Runtime.InteropServices; @@ -660,7 +661,13 @@ namespace BizHawk.Client.EmuHawk { 1 => Peek(address), 2 => Peek(address) | (Peek(address + 1) << 8), - 4 => Peek(address) | (Peek(address + 1) << 8) | (Peek(address + 2) << 16) | (Peek(address + 3) << 24), + 4 => BinaryPrimitives.ReadUInt32LittleEndian(unchecked(stackalloc byte[] + { + (byte) Peek(address), + (byte) Peek(address + 1), + (byte) Peek(address + 2), + (byte) Peek(address + 3), + })), _ => throw new InvalidOperationException($"Requested {num_bytes} in {nameof(PeekCallback)}"), }; diff --git a/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.GameVerification.cs b/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.GameVerification.cs index 58bfac9ee1..7a4a20c41e 100644 --- a/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.GameVerification.cs +++ b/src/BizHawk.Client.EmuHawk/RetroAchievements/RetroAchievements.GameVerification.cs @@ -75,8 +75,8 @@ namespace BizHawk.Client.EmuHawk var slba = FirstDataTrackLBA(); dsr.ReadLBA_2048(slba + 1, buf2048, 0); bitsToHash.Add(new(buf2048, offset: 0, count: 128)); - var bootSector = (buf2048[35] << 24) | (buf2048[34] << 16) | (buf2048[33] << 8) | buf2048[32]; - var numSectors = (buf2048[39] << 24) | (buf2048[38] << 16) | (buf2048[37] << 8) | buf2048[36]; + var bootSector = BinaryPrimitives.ReadInt32LittleEndian(buf2048.AsSpan(start: 32)); + var numSectors = BinaryPrimitives.ReadInt32LittleEndian(buf2048.AsSpan(start: 36)); for (var i = 0; i < numSectors; i++) { dsr.ReadLBA_2048(slba + bootSector + i, buf2048, 0); @@ -103,7 +103,7 @@ namespace BizHawk.Client.EmuHawk } else { - var directoryRecordLength = (uint)((buf2048[169] << 24) | (buf2048[168] << 16) | (buf2048[167] << 8) | buf2048[166]); + var directoryRecordLength = BinaryPrimitives.ReadUInt32LittleEndian(buf2048.AsSpan(start: 166)); numSectors = (int)(directoryRecordLength / logicalBlockSize); } } @@ -133,7 +133,7 @@ namespace BizHawk.Client.EmuHawk var fn = Encoding.ASCII.GetString(buf2048, index + 33, filename.Length); if (filename.EqualsIgnoreCase(fn)) { - filesize = (buf2048[index + 13] << 24) | (buf2048[index + 12] << 16) | (buf2048[index + 11] << 8) | buf2048[index + 10]; + filesize = BinaryPrimitives.ReadInt32LittleEndian(buf2048.AsSpan(start: index + 10)); return (buf2048[index + 4] << 16) | (buf2048[index + 3] << 8) | buf2048[index + 2]; } } @@ -203,7 +203,7 @@ namespace BizHawk.Client.EmuHawk if ("PS-X EXE" == Encoding.ASCII.GetString(buf2048, 0, 8)) { - exeSize = ((buf2048[31] << 24) | (buf2048[30] << 16) | (buf2048[29] << 8) | buf2048[28]) + 2048; + exeSize = BinaryPrimitives.ReadInt32LittleEndian(buf2048.AsSpan(start: 28)) + 2048; } bitsToHash.Add(new(buf2048, offset: 0, count: Math.Min(2048, exeSize))); diff --git a/src/BizHawk.Common/Colors.cs b/src/BizHawk.Common/Colors.cs index a770e3e334..4149e3b897 100644 --- a/src/BizHawk.Common/Colors.cs +++ b/src/BizHawk.Common/Colors.cs @@ -1,11 +1,14 @@ -namespace BizHawk.Common +using System.Buffers.Binary; + +namespace BizHawk.Common { #pragma warning disable MA0104 // unlikely to conflict with System.Windows.Media.Colors public static class Colors #pragma warning restore MA0104 { /// This is just Color.FromArgb(alpha, red, green, blue).ToArgb() with extra steps. - public static int ARGB(byte red, byte green, byte blue, byte alpha = 0xFF) => unchecked((int) ((uint) (alpha << 24) | (uint) (red << 16) | (uint) (green << 8) | blue)); + public static int ARGB(byte red, byte green, byte blue, byte alpha = 0xFF) + => BinaryPrimitives.ReadInt32BigEndian(stackalloc byte[] { alpha, red, green, blue }); #if false public static int Luminosity(byte lum) => ARGB(lum, lum, lum); diff --git a/src/BizHawk.Emulation.Common/Base Implementations/MemoryDomain.cs b/src/BizHawk.Emulation.Common/Base Implementations/MemoryDomain.cs index bca3ed177e..78abca3fa8 100644 --- a/src/BizHawk.Emulation.Common/Base Implementations/MemoryDomain.cs +++ b/src/BizHawk.Emulation.Common/Base Implementations/MemoryDomain.cs @@ -1,5 +1,7 @@ #nullable disable +using System.Buffers.Binary; + using BizHawk.Common; namespace BizHawk.Emulation.Common @@ -46,18 +48,16 @@ namespace BizHawk.Emulation.Common public virtual uint PeekUint(long addr, bool bigEndian) { - if (bigEndian) + ReadOnlySpan scratch = stackalloc byte[] { - return (uint)((PeekByte(addr) << 24) - | (PeekByte(addr + 1) << 16) - | (PeekByte(addr + 2) << 8) - | (PeekByte(addr + 3) << 0)); - } - - return (uint)((PeekByte(addr) << 0) - | (PeekByte(addr + 1) << 8) - | (PeekByte(addr + 2) << 16) - | (PeekByte(addr + 3) << 24)); + PeekByte(addr), + PeekByte(addr + 1), + PeekByte(addr + 2), + PeekByte(addr + 3), + }; + return bigEndian + ? BinaryPrimitives.ReadUInt32BigEndian(scratch) + : BinaryPrimitives.ReadUInt32LittleEndian(scratch); } public virtual void PokeUshort(long addr, ushort val, bool bigEndian) diff --git a/src/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/CartridgeDevice.cs b/src/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/CartridgeDevice.cs index 8347073a53..9a397dbed2 100644 --- a/src/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/CartridgeDevice.cs +++ b/src/BizHawk.Emulation.Cores/Computers/Commodore64/Cartridge/CartridgeDevice.cs @@ -1,3 +1,4 @@ +using System.Buffers.Binary; using System.Collections.Generic; using System.IO; using System.Linq; @@ -136,12 +137,13 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Cartridge } private static int ReadCRTInt(BinaryReader reader) - { - return (reader.ReadByte() << 24) | - (reader.ReadByte() << 16) | - (reader.ReadByte() << 8) | - reader.ReadByte(); - } + => BinaryPrimitives.ReadInt32BigEndian(stackalloc byte[] + { + reader.ReadByte(), + reader.ReadByte(), + reader.ReadByte(), + reader.ReadByte(), + }); protected bool pinExRom; diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/SNESGraphicsDecoder.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/SNESGraphicsDecoder.cs index f89217476d..2d59205968 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/SNESGraphicsDecoder.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/BSNES/SNESGraphicsDecoder.cs @@ -1,3 +1,4 @@ +using System.Buffers.Binary; using System.Drawing; using BizHawk.Emulation.Cores.Nintendo.SNES; using static BizHawk.Emulation.Cores.Nintendo.BSNES.BsnesApi.SNES_REGISTER; @@ -20,7 +21,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES private readonly short[] directColorTable = new short[256]; private void generate_palette() { - const int a = 0xFF; + Span scratch = stackalloc byte[4]; + scratch[0] = 0xFF; for (int color = 0; color < 32768; color++) { int r = (color >> 10) & 31; int g = (color >> 5) & 31; @@ -30,7 +32,13 @@ namespace BizHawk.Emulation.Cores.Nintendo.BSNES g = g << 3 | g >> 2; g = g << 8 | g << 0; b = b << 3 | b >> 2; b = b << 8 | b << 0; - palette[color] = a << 24 | b >> 8 << 16 | g >> 8 << 8 | r >> 8 << 0; + unchecked + { + scratch[1] = (byte) (b >> 8); + scratch[2] = (byte) (g >> 8); + scratch[3] = (byte) (r >> 8); + } + palette[color] = BinaryPrimitives.ReadInt32BigEndian(scratch); } } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/ArmV4Disassembler.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/ArmV4Disassembler.cs index cedcfe5173..743e22e05e 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/ArmV4Disassembler.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/GBA/ArmV4Disassembler.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System.Buffers.Binary; +using System.Collections.Generic; using BizHawk.BizInvoke; using BizHawk.Common; @@ -35,11 +36,14 @@ namespace BizHawk.Emulation.Cores.Nintendo.GBA else { addr &= unchecked((uint)~3); - int op = m.PeekByte((int)addr) - | m.PeekByte((int)addr + 1) << 8 - | m.PeekByte((int)addr + 2) << 16 - | m.PeekByte((int)addr + 3) << 24; - string ret = _libdarm.DisassembleStuff(addr, (uint)op); + var op = BinaryPrimitives.ReadUInt32LittleEndian(stackalloc byte[] + { + m.PeekByte(addr), + m.PeekByte(addr + 1L), + m.PeekByte(addr + 2L), + m.PeekByte(addr + 3L), + }); + var ret = _libdarm.DisassembleStuff(addr, op); length = 4; return ret; } diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GBColors.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GBColors.cs index 651b27abfb..8a49946830 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GBColors.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/Gameboy/GBColors.cs @@ -1,3 +1,5 @@ +using BizHawk.Common; + namespace BizHawk.Emulation.Cores.Nintendo.Gameboy { public static class GBColors @@ -69,9 +71,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.Gameboy } public int ToARGB32() - { - return b | g << 8 | r << 16 | 255 << 24; - } + => unchecked(Colors.ARGB(red: (byte) r, green: (byte) g, blue: (byte) b)); } // sameboy's "emulate hardware" color conversion diff --git a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/NDSDisassembler.cs b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/NDSDisassembler.cs index 7ee3c86d1a..56c3bc3a20 100644 --- a/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/NDSDisassembler.cs +++ b/src/BizHawk.Emulation.Cores/Consoles/Nintendo/NDS/NDSDisassembler.cs @@ -1,3 +1,4 @@ +using System.Buffers.Binary; using System.Collections.Generic; using System.Text; @@ -49,10 +50,13 @@ namespace BizHawk.Emulation.Cores.Consoles.Nintendo.NDS else { addr &= ~3u; - var op = m.PeekByte(addr) - | (uint)m.PeekByte(addr + 1) << 8 - | (uint)m.PeekByte(addr + 2) << 16 - | (uint)m.PeekByte(addr + 3) << 24; + var op = BinaryPrimitives.ReadUInt32LittleEndian(stackalloc byte[] + { + m.PeekByte(addr), + m.PeekByte(addr + 1), + m.PeekByte(addr + 2), + m.PeekByte(addr + 3), + }); _core.GetDisassembly(type, op, ret); length = 4; } diff --git a/src/BizHawk.Emulation.DiscSystem/DiscHasher.cs b/src/BizHawk.Emulation.DiscSystem/DiscHasher.cs index 8e35e2e8b4..3799572dc7 100644 --- a/src/BizHawk.Emulation.DiscSystem/DiscHasher.cs +++ b/src/BizHawk.Emulation.DiscSystem/DiscHasher.cs @@ -1,5 +1,6 @@ #nullable enable +using System.Buffers.Binary; using System.Collections.Generic; using System.Text; using BizHawk.Common; @@ -158,8 +159,7 @@ namespace BizHawk.Emulation.DiscSystem { if (_jaguarHeader == Encoding.ASCII.GetString(buf2352, j, 32 - 1)) { - bootLen = (buf2352[j + bootLenOffset + 0] << 24) | (buf2352[j + bootLenOffset + 1] << 16) | - (buf2352[j + bootLenOffset + 2] << 8) | buf2352[j + bootLenOffset + 3]; + bootLen = BinaryPrimitives.ReadInt32BigEndian(buf2352.AsSpan(start: bootLenOffset + j)); bootLba = startLba + i; bootOff = j + bootLenOffset + 4; // byteswapped = false; @@ -171,8 +171,9 @@ namespace BizHawk.Emulation.DiscSystem { if (_jaguarBSHeader == Encoding.ASCII.GetString(buf2352, j, 32 - 2)) { - bootLen = (buf2352[j + bootLenOffset + 1] << 24) | (buf2352[j + bootLenOffset + 0] << 16) | - (buf2352[j + bootLenOffset + 3] << 8) | buf2352[j + bootLenOffset + 2]; + var slice = buf2352.AsSpan(start: bootLenOffset + j, length: sizeof(int)).ToArray(); + EndiannessUtils.MutatingByteSwap16(slice); + bootLen = BinaryPrimitives.ReadInt32BigEndian(slice); bootLba = startLba + i; bootOff = j + bootLenOffset + 4; byteswapped = true;