From 5544ab0b8a91bb6afd68cd90658fa2b732c90970 Mon Sep 17 00:00:00 2001 From: Matt Nadareski Date: Sat, 21 Mar 2026 20:09:10 -0400 Subject: [PATCH] Add majority of data extensions tests, fix minor issues --- .../Atari7800CartExtensionsTests.cs | 141 ++++++++++++ .../AtariLynxCartExtensionsTests.cs | 18 ++ .../CDROMExtensionsTests.cs | 65 ++++++ .../CFBExtensionsTests.cs | 17 ++ .../ISO9660ExtensionsTests.cs | 138 ++++++++++++ .../InstallShieldCabinetExtensionsTests.cs | 156 +++++++++++++ .../NESCartExtensionsTests.cs | 206 ++++++++++++++++++ .../NewExecutableExtensionsTests.cs | 61 ++++++ .../WiseScriptExtensionsTests.cs | 59 +++++ .../XZExtensionsTests.cs | 20 ++ .../XboxExecutableExtensionsTests.cs | 17 ++ .../Atari7800CartExtensions.cs | 10 +- .../NESCartExtensions.cs | 6 +- .../PortableExecutableExtensions.cs | 1 + .../XboxExecutableExtensions.cs | 2 +- SabreTools.Wrappers/XboxExecutable.cs | 4 +- 16 files changed, 910 insertions(+), 11 deletions(-) create mode 100644 SabreTools.Data.Extensions.Test/Atari7800CartExtensionsTests.cs create mode 100644 SabreTools.Data.Extensions.Test/AtariLynxCartExtensionsTests.cs create mode 100644 SabreTools.Data.Extensions.Test/CDROMExtensionsTests.cs create mode 100644 SabreTools.Data.Extensions.Test/CFBExtensionsTests.cs create mode 100644 SabreTools.Data.Extensions.Test/ISO9660ExtensionsTests.cs create mode 100644 SabreTools.Data.Extensions.Test/InstallShieldCabinetExtensionsTests.cs create mode 100644 SabreTools.Data.Extensions.Test/NESCartExtensionsTests.cs create mode 100644 SabreTools.Data.Extensions.Test/NewExecutableExtensionsTests.cs create mode 100644 SabreTools.Data.Extensions.Test/WiseScriptExtensionsTests.cs create mode 100644 SabreTools.Data.Extensions.Test/XZExtensionsTests.cs create mode 100644 SabreTools.Data.Extensions.Test/XboxExecutableExtensionsTests.cs diff --git a/SabreTools.Data.Extensions.Test/Atari7800CartExtensionsTests.cs b/SabreTools.Data.Extensions.Test/Atari7800CartExtensionsTests.cs new file mode 100644 index 00000000..88aeed71 --- /dev/null +++ b/SabreTools.Data.Extensions.Test/Atari7800CartExtensionsTests.cs @@ -0,0 +1,141 @@ +using SabreTools.Data.Models.Atari7800; +using Xunit; + +namespace SabreTools.Data.Extensions.Test +{ + public class Atari7800CartExtensionsTests + { + [Theory] + [InlineData((AudioDevice)0, "POKEY - none, No YM2151 @460, No COVOX @430, No ADPCM Audio Stream @420")] + // POKEY + [InlineData(AudioDevice.Pokey440, "POKEY - @440, No YM2151 @460, No COVOX @430, No ADPCM Audio Stream @420")] + [InlineData(AudioDevice.Pokey450, "POKEY - @450, No YM2151 @460, No COVOX @430, No ADPCM Audio Stream @420")] + [InlineData(AudioDevice.Pokey450Plus440, "POKEY - @450+@440, No YM2151 @460, No COVOX @430, No ADPCM Audio Stream @420")] + [InlineData(AudioDevice.Pokey800, "POKEY - @800, No YM2151 @460, No COVOX @430, No ADPCM Audio Stream @420")] + [InlineData(AudioDevice.Pokey4000, "POKEY - @4000, No YM2151 @460, No COVOX @430, No ADPCM Audio Stream @420")] + [InlineData((AudioDevice)0x0007, "Unknown 7, No YM2151 @460, No COVOX @430, No ADPCM Audio Stream @420")] + // YM2151 + [InlineData(AudioDevice.YM2151460, "POKEY - none, YM2151 @460, No COVOX @430, No ADPCM Audio Stream @420")] + // COVOX + [InlineData(AudioDevice.COVOX430, "POKEY - none, No YM2151 @460, COVOX @430, No ADPCM Audio Stream @420")] + // ADPCM + [InlineData(AudioDevice.ADPCMAudioStream420, "POKEY - none, No YM2151 @460, No COVOX @430, ADPCM Audio Stream @420")] + public void FromAudioDeviceTest(AudioDevice audio, string expected) + { + string actual = audio.FromAudioDevice(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData((CartType)0, "N/A")] + [InlineData(CartType.PokeyAt4000, "pokey at $4000")] + [InlineData(CartType.SupergameBankSwitched, "supergame bank switched")] + [InlineData(CartType.SupergameRamAt4000, "supergame ram at $4000")] + [InlineData(CartType.RomAt4000, "rom at $4000")] + [InlineData(CartType.Bank6At4000, "bank 6 at $4000")] + [InlineData(CartType.BankedRam, "banked ram")] + [InlineData(CartType.PokeyAt450, "pokey at $450")] + [InlineData(CartType.MirrorRamAt4000, "mirror ram at $4000")] + [InlineData(CartType.ActivisionBanking, "activision banking")] + [InlineData(CartType.AbsoluteBanking, "absolute banking")] + [InlineData(CartType.PokeyAt440, "pokey at $440")] + [InlineData(CartType.Ym2151At460461, "ym2151 at $460/$461")] + [InlineData(CartType.Souper, "souper")] + [InlineData(CartType.Banksets, "banksets")] + [InlineData(CartType.HaltBankedRam, "halt banked ram")] + [InlineData(CartType.PokeyAt800, "pokey@800")] + public void FromCartTypeTest(CartType type, string expected) + { + string actual = type.FromCartType(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(ControllerType.None, "none")] + [InlineData(ControllerType.Joystick, "7800 joystick")] + [InlineData(ControllerType.Lightgun, "lightgun")] + [InlineData(ControllerType.Paddle, "paddle")] + [InlineData(ControllerType.Trakball, "trakball")] + [InlineData(ControllerType.VcsJoystick, "2600 joystick")] + [InlineData(ControllerType.VcsDriving, "2600 driving")] + [InlineData(ControllerType.VcsKeypad, "2600 keypad")] + [InlineData(ControllerType.STMouse, "ST mouse")] + [InlineData(ControllerType.AmigaMouse, "Amiga mouse")] + [InlineData(ControllerType.AtariVoxSaveKey, "AtariVox/SaveKey")] + [InlineData(ControllerType.SNES2Atari, "SNES2Atari")] + [InlineData(ControllerType.Mega7800, "Mega7800")] + public void FromControllerTypeTest(ControllerType type, string expected) + { + string actual = type.FromControllerType(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(Interrupt.None, "None")] + [InlineData(Interrupt.Pokey1, "POKEY 1 (@450 | @800 | @4000)")] + [InlineData(Interrupt.Pokey2, "POKEY 2 (@440)")] + [InlineData(Interrupt.YM2151, "YM2151")] + public void FromInterruptTest(Interrupt interrupt, string expected) + { + string actual = interrupt.FromInterrupt(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(Mapper.Linear, "Linear")] + [InlineData(Mapper.SuperGame, "SuperGame")] + [InlineData(Mapper.Activision, "Activision")] + [InlineData(Mapper.Absolute, "Absolute")] + [InlineData(Mapper.Souper, "Souper")] + public void FromMapperTest(Mapper mapper, string expected) + { + string actual = mapper.FromMapper(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(MapperOptions.SuperGameNone, "Option at @4000 - none, Standard ROM")] + [InlineData(MapperOptions.SuperGame16KRAM, "Option at @4000 - 16K RAM, Standard ROM")] + [InlineData(MapperOptions.SuperGame8KEXRAMA8, "Option at @4000 - 8K EXRAM/A8, Standard ROM")] + [InlineData(MapperOptions.SuperGame32KEXRAMM2, "Option at @4000 - 32K EXRAM/M2, Standard ROM")] + [InlineData(MapperOptions.SuperGameEXROM, "Option at @4000 - EXROM, Standard ROM")] + [InlineData(MapperOptions.SuperGameEXFIX, "Option at @4000 - EXFIX, Standard ROM")] + [InlineData(MapperOptions.SuperGame32KEXRAMX2, "Option at @4000 - 32k EXRAM/X2, Standard ROM")] + [InlineData(MapperOptions.BanksetRom, "Option at @4000 - none, Bankset ROM")] + public void FromMapperOptionsTest(MapperOptions options, string expected) + { + string actual = options.FromMapperOptions(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(SaveDevice.None, "None")] + [InlineData(SaveDevice.HSC, "HSC")] + [InlineData(SaveDevice.SaveKeyAtariVox, "SaveKey/AtariVox")] + public void FromSaveDeviceTest(SaveDevice device, string expected) + { + string actual = device.FromSaveDevice(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(SlotPassthroughDevice.None, "None")] + [InlineData(SlotPassthroughDevice.XM, "XM")] + public void FromSlotPassthroughDeviceTest(SlotPassthroughDevice device, string expected) + { + string actual = device.FromSlotPassthroughDevice(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData((TVType)0, "NTSC, Component, Single-region")] + [InlineData(TVType.PAL, "PAL, Component, Single-region")] + [InlineData(TVType.Composite, "NTSC, Composite, Single-region")] + [InlineData(TVType.MultiRegion, "NTSC, Component, Multi-region")] + public void FromTVTypeTest(TVType type, string expected) + { + string actual = type.FromTVType(); + Assert.Equal(expected, actual); + } + } +} diff --git a/SabreTools.Data.Extensions.Test/AtariLynxCartExtensionsTests.cs b/SabreTools.Data.Extensions.Test/AtariLynxCartExtensionsTests.cs new file mode 100644 index 00000000..9383b472 --- /dev/null +++ b/SabreTools.Data.Extensions.Test/AtariLynxCartExtensionsTests.cs @@ -0,0 +1,18 @@ +using SabreTools.Data.Models.AtariLynx; +using Xunit; + +namespace SabreTools.Data.Extensions.Test +{ + public class AtariLynxCartExtensionsTests + { + [Theory] + [InlineData(Rotation.NoRotation, "No rotation (horizontal, buttons right)")] + [InlineData(Rotation.RotateLeft, "Rotate left (vertical, buttons down)")] + [InlineData(Rotation.RotateRight, "Rotate right (vertical, buttons up)")] + public void FromRotationTest(Rotation rotation, string expected) + { + string actual = rotation.FromRotation(); + Assert.Equal(expected, actual); + } + } +} diff --git a/SabreTools.Data.Extensions.Test/CDROMExtensionsTests.cs b/SabreTools.Data.Extensions.Test/CDROMExtensionsTests.cs new file mode 100644 index 00000000..f9fb6aa1 --- /dev/null +++ b/SabreTools.Data.Extensions.Test/CDROMExtensionsTests.cs @@ -0,0 +1,65 @@ +using System.IO; +using SabreTools.Data.Models.CDROM; +using Xunit; + +namespace SabreTools.Data.Extensions.Test +{ + public class CDROMExtensionsTests + { + [Theory] + [InlineData(new byte[0], SectorMode.UNKNOWN)] + [InlineData(new byte[] { 0x00 }, SectorMode.MODE0)] + [InlineData(new byte[] { 0x01 }, SectorMode.MODE1)] + [InlineData(new byte[] { 0x02 }, SectorMode.UNKNOWN)] + [InlineData(new byte[] { 0x02, 0x00, 0x00, 0x00 }, SectorMode.MODE2_FORM1)] + [InlineData(new byte[] { 0x02, 0x00, 0x00, 0x20 }, SectorMode.MODE2_FORM2)] + [InlineData(new byte[] { 0x03 }, SectorMode.UNKNOWN)] + public void GetSectorModeTest(byte[] bytes, SectorMode expected) + { + var stream = new MemoryStream(bytes); + SectorMode actual = stream.GetSectorMode(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(SectorMode.UNKNOWN, 2336)] + [InlineData(SectorMode.MODE0, 2336)] + [InlineData(SectorMode.MODE1, 2048)] + [InlineData(SectorMode.MODE2, 2336)] + [InlineData(SectorMode.MODE2_FORM1, 2048)] + [InlineData(SectorMode.MODE2_FORM2, 2324)] + public void GetUserDataSizeTest(SectorMode mode, long expected) + { + long actual = mode.GetUserDataSize(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(SectorMode.UNKNOWN, 2064)] + [InlineData(SectorMode.MODE0, 2064)] + [InlineData(SectorMode.MODE1, 2064)] + [InlineData(SectorMode.MODE2, 2064)] + [InlineData(SectorMode.MODE2_FORM1, 2072)] + [InlineData(SectorMode.MODE2_FORM2, 2072)] + public void GetUserDataEndTest(SectorMode mode, long expected) + { + long actual = mode.GetUserDataEnd(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(SectorMode.UNKNOWN, 16)] + [InlineData(SectorMode.MODE0, 16)] + [InlineData(SectorMode.MODE1, 16)] + [InlineData(SectorMode.MODE2, 16)] + [InlineData(SectorMode.MODE2_FORM1, 24)] + [InlineData(SectorMode.MODE2_FORM2, 24)] + public void GetUserDataStart(SectorMode mode, long expected) + { + long actual = mode.GetUserDataStart(); + Assert.Equal(expected, actual); + } + + // TODO: Figure out how to add ISO9660Stream tests + } +} diff --git a/SabreTools.Data.Extensions.Test/CFBExtensionsTests.cs b/SabreTools.Data.Extensions.Test/CFBExtensionsTests.cs new file mode 100644 index 00000000..15efa0d8 --- /dev/null +++ b/SabreTools.Data.Extensions.Test/CFBExtensionsTests.cs @@ -0,0 +1,17 @@ +using Xunit; + +namespace SabreTools.Data.Extensions.Test +{ + public class CFBExtensionsTests + { + [Theory] + [InlineData(null, null)] + [InlineData(new byte[0], "")] + // TODO: Create more artifical tests + public void DecodeStreamNameTest(byte[]? bytes, string? expected) + { + string? actual = bytes.DecodeStreamName(); + Assert.Equal(expected, actual); + } + } +} diff --git a/SabreTools.Data.Extensions.Test/ISO9660ExtensionsTests.cs b/SabreTools.Data.Extensions.Test/ISO9660ExtensionsTests.cs new file mode 100644 index 00000000..22c57865 --- /dev/null +++ b/SabreTools.Data.Extensions.Test/ISO9660ExtensionsTests.cs @@ -0,0 +1,138 @@ +using SabreTools.Data.Models.ISO9660; +using SabreTools.Numerics; +using Xunit; + +namespace SabreTools.Data.Extensions.Test +{ + public class ISO9660ExtensionsTests + { + [Fact] + public void GetLogicalBlockSize_Generic_SectorLength() + { + VolumeDescriptor vd = new GenericVolumeDescriptor(); + short sectorLength = 4096; + short actual = vd.GetLogicalBlockSize(sectorLength); + Assert.Equal(sectorLength, actual); + } + + [Fact] + public void GetLogicalBlockSize_PVD_ValidBothEndian_ValidBlockSize_BlockSize() + { + VolumeDescriptor vd = new PrimaryVolumeDescriptor + { + LogicalBlockSize = new BothInt16(2048, 2048) + }; + short sectorLength = 4096; + short actual = vd.GetLogicalBlockSize(sectorLength); + Assert.Equal(2048, actual); + } + + [Fact] + public void GetLogicalBlockSize_PVD_ValidBothEndian_InvalidBlockSize_SectorLength() + { + VolumeDescriptor vd = new PrimaryVolumeDescriptor + { + LogicalBlockSize = new BothInt16(2352, 2352) + }; + short sectorLength = 4096; + short actual = vd.GetLogicalBlockSize(sectorLength); + Assert.Equal(4096, actual); + } + + [Fact] + public void GetLogicalBlockSize_PVD_InvalidBothEndian_ValidLE_LEValue() + { + VolumeDescriptor vd = new PrimaryVolumeDescriptor + { + LogicalBlockSize = new BothInt16(2048, -1) + }; + short sectorLength = 4096; + short actual = vd.GetLogicalBlockSize(sectorLength); + Assert.Equal(2048, actual); + } + + [Fact] + public void GetLogicalBlockSize_PVD_InvalidBothEndian_ValidBE_BEValue() + { + VolumeDescriptor vd = new PrimaryVolumeDescriptor + { + LogicalBlockSize = new BothInt16(-1, 2048) + }; + short sectorLength = 4096; + short actual = vd.GetLogicalBlockSize(sectorLength); + Assert.Equal(2048, actual); + } + + [Fact] + public void GetLogicalBlockSize_PVD_InvalidBothEndian_BothInvalid_SectorLength() + { + VolumeDescriptor vd = new PrimaryVolumeDescriptor + { + LogicalBlockSize = new BothInt16(-1, -2) + }; + short sectorLength = 4096; + short actual = vd.GetLogicalBlockSize(sectorLength); + Assert.Equal(sectorLength, actual); + } + + [Fact] + public void GetLogicalBlockSize_SVD_ValidBothEndian_ValidBlockSize_BlockSize() + { + VolumeDescriptor vd = new SupplementaryVolumeDescriptor + { + LogicalBlockSize = new BothInt16(2048, 2048) + }; + short sectorLength = 4096; + short actual = vd.GetLogicalBlockSize(sectorLength); + Assert.Equal(2048, actual); + } + + [Fact] + public void GetLogicalBlockSize_SVD_ValidBothEndian_InvalidBlockSize_SectorLength() + { + VolumeDescriptor vd = new SupplementaryVolumeDescriptor + { + LogicalBlockSize = new BothInt16(2352, 2352) + }; + short sectorLength = 4096; + short actual = vd.GetLogicalBlockSize(sectorLength); + Assert.Equal(4096, actual); + } + + [Fact] + public void GetLogicalBlockSize_SVD_InvalidBothEndian_ValidLE_LEValue() + { + VolumeDescriptor vd = new SupplementaryVolumeDescriptor + { + LogicalBlockSize = new BothInt16(2048, -1) + }; + short sectorLength = 4096; + short actual = vd.GetLogicalBlockSize(sectorLength); + Assert.Equal(2048, actual); + } + + [Fact] + public void GetLogicalBlockSize_SVD_InvalidBothEndian_ValidBE_BEValue() + { + VolumeDescriptor vd = new SupplementaryVolumeDescriptor + { + LogicalBlockSize = new BothInt16(-1, 2048) + }; + short sectorLength = 4096; + short actual = vd.GetLogicalBlockSize(sectorLength); + Assert.Equal(2048, actual); + } + + [Fact] + public void GetLogicalBlockSize_SVD_InvalidBothEndian_BothInvalid_SectorLength() + { + VolumeDescriptor vd = new SupplementaryVolumeDescriptor + { + LogicalBlockSize = new BothInt16(-1, -2) + }; + short sectorLength = 4096; + short actual = vd.GetLogicalBlockSize(sectorLength); + Assert.Equal(sectorLength, actual); + } + } +} diff --git a/SabreTools.Data.Extensions.Test/InstallShieldCabinetExtensionsTests.cs b/SabreTools.Data.Extensions.Test/InstallShieldCabinetExtensionsTests.cs new file mode 100644 index 00000000..80b662c9 --- /dev/null +++ b/SabreTools.Data.Extensions.Test/InstallShieldCabinetExtensionsTests.cs @@ -0,0 +1,156 @@ +using SabreTools.Data.Models.InstallShieldCabinet; +using Xunit; + +namespace SabreTools.Data.Extensions.Test +{ + public class InstallShieldCabinetExtensionsTests + { + #region IsCompressed + + [Fact] + public void IsCompressed_Null_True() + { + FileDescriptor? fd = null; + bool actual = fd.IsCompressed(); + Assert.True(actual); + } + + [Fact] + public void IsCompressed_Compressed_True() + { + FileDescriptor? fd = new FileDescriptor { Flags = FileFlags.FILE_COMPRESSED }; + bool actual = fd.IsCompressed(); + Assert.True(actual); + } + + [Fact] + public void IsCompressed_NotCompressed_False() + { + FileDescriptor? fd = new FileDescriptor { Flags = 0 }; + bool actual = fd.IsCompressed(); + Assert.False(actual); + } + + #endregion + + #region IsInvalid + + [Fact] + public void IsInvalid_Null_True() + { + FileDescriptor? fd = null; + bool actual = fd.IsInvalid(); + Assert.True(actual); + } + + [Fact] + public void IsInvalid_Invalid_True() + { + FileDescriptor? fd = new FileDescriptor { Flags = FileFlags.FILE_INVALID }; + bool actual = fd.IsInvalid(); + Assert.True(actual); + } + + [Fact] + public void IsInvalid_Valid_False() + { + FileDescriptor? fd = new FileDescriptor { Flags = 0 }; + bool actual = fd.IsInvalid(); + Assert.False(actual); + } + + #endregion + + #region IsObfuscated + + [Fact] + public void IsObfuscated_Null_False() + { + FileDescriptor? fd = null; + bool actual = fd.IsObfuscated(); + Assert.False(actual); + } + + [Fact] + public void IsObfuscated_Obfuscated_True() + { + FileDescriptor? fd = new FileDescriptor { Flags = FileFlags.FILE_OBFUSCATED }; + bool actual = fd.IsObfuscated(); + Assert.True(actual); + } + + [Fact] + public void IsObfuscated_NotObfuscated_False() + { + FileDescriptor? fd = new FileDescriptor { Flags = 0 }; + bool actual = fd.IsObfuscated(); + Assert.False(actual); + } + + #endregion + + #region IsSplit + + [Fact] + public void IsSplit_Null_False() + { + FileDescriptor? fd = null; + bool actual = fd.IsSplit(); + Assert.False(actual); + } + + [Fact] + public void IsSplit_Split_True() + { + FileDescriptor? fd = new FileDescriptor { Flags = FileFlags.FILE_SPLIT }; + bool actual = fd.IsSplit(); + Assert.True(actual); + } + + [Fact] + public void IsSplit_NotSplitFalse() + { + FileDescriptor? fd = new FileDescriptor { Flags = 0 }; + bool actual = fd.IsSplit(); + Assert.False(actual); + } + + #endregion + + #region GetMajorVersion + + [Fact] + public void GetMajorVersion_NullCabinet_NegativeOne() + { + Cabinet? cabinet = null; + int actual = cabinet.GetMajorVersion(); + Assert.Equal(-1, actual); + } + + [Fact] + public void GetMajorVersion_NullHeader_NegativeOne() + { + CommonHeader? cabinet = null; + int actual = cabinet.GetMajorVersion(); + Assert.Equal(-1, actual); + } + + [Theory] + [InlineData(0x00000000, 0)] + [InlineData(0x00000004, 4)] + [InlineData(0x01000000, 0)] + [InlineData(0x01004000, 4)] + [InlineData(0x02000000, 0)] + [InlineData(0x02000190, 4)] + [InlineData(0x04000000, 0)] + [InlineData(0x04000190, 4)] + public void GetMajorVersionTest(uint version, int expected) + { + CommonHeader? cabinet = new CommonHeader { Version = version }; + int actual = cabinet.GetMajorVersion(); + Assert.Equal(expected, actual); + } + + #endregion + } +} diff --git a/SabreTools.Data.Extensions.Test/NESCartExtensionsTests.cs b/SabreTools.Data.Extensions.Test/NESCartExtensionsTests.cs new file mode 100644 index 00000000..491def8e --- /dev/null +++ b/SabreTools.Data.Extensions.Test/NESCartExtensionsTests.cs @@ -0,0 +1,206 @@ +using SabreTools.Data.Models.NES; +using Xunit; + +namespace SabreTools.Data.Extensions.Test +{ + public class NESCartExtensionsTests + { + [Theory] + [InlineData(ConsoleType.StandardSystem, "Nintendo Entertainment System/Family Computer")] + [InlineData(ConsoleType.VSUnisystem, "VS Unisystem")] + [InlineData(ConsoleType.PlayChoice10, "PlayChoice-10 (8 KB of Hint Screen data stored after CHR data)")] + [InlineData(ConsoleType.ExtendedConsoleType, "Extended Console Type")] + public void FromConsoleTypeTest(ConsoleType type, string expected) + { + string actual = type.FromConsoleType(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(CPUPPUTiming.RP2C02, "RP2C02 (NTSC NES)")] + [InlineData(CPUPPUTiming.RP2C07, "RP2C07 (Licensed PAL NES)")] + [InlineData(CPUPPUTiming.MultipleRegion, "Multiple-region")] + [InlineData(CPUPPUTiming.UA6538, "UA6538 (Dendy)")] + public void FromCPUPPUTimingTest(CPUPPUTiming timing, string expected) + { + string actual = timing.FromCPUPPUTiming(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(DefaultExpansionDevice.Unspecified, "Unspecified")] + [InlineData(DefaultExpansionDevice.StandardControllers, "Standard NES/Famicom controllers")] + [InlineData(DefaultExpansionDevice.NESFourScore, "NES Four Score/Satellite with two additional standard controllers")] + [InlineData(DefaultExpansionDevice.FamicomFourPlayersAdapter, "Famicom Four Players Adapter with two additional standard controllers using the 'simple' protocol")] + [InlineData(DefaultExpansionDevice.VsSystem4016, "Vs. System (1P via $4016)")] + [InlineData(DefaultExpansionDevice.VsSystem4017, "Vs. System (1P via $4017)")] + [InlineData(DefaultExpansionDevice.Reserved06, "Reserved (0x06)")] + [InlineData(DefaultExpansionDevice.VsZapper, "Vs. Zapper")] + [InlineData(DefaultExpansionDevice.Zapper4017, "Zapper ($4017)")] + [InlineData(DefaultExpansionDevice.TwoZappers, "Two Zappers")] + [InlineData(DefaultExpansionDevice.BandaiHyperShotLightgun, "Bandai Hyper Shot Lightgun")] + [InlineData(DefaultExpansionDevice.PowerPadSideA, "Power Pad Side A")] + [InlineData(DefaultExpansionDevice.PowerPadSideB, "Power Pad Side B")] + [InlineData(DefaultExpansionDevice.FamilyTrainerSideA, "Family Trainer Side A")] + [InlineData(DefaultExpansionDevice.FamilyTrainerSideB, "Family Trainer Side B")] + [InlineData(DefaultExpansionDevice.ArkanoidVausControllerNES, "Arkanoid Vaus Controller (NES)")] + [InlineData(DefaultExpansionDevice.ArkanoidVausControllerFamicom, "Arkanoid Vaus Controller (Famicom)")] + [InlineData(DefaultExpansionDevice.TwoVausControllersPlusFamicomDataRecorder, "Two Vaus Controllers plus Famicom Data Recorder")] + [InlineData(DefaultExpansionDevice.KonamiHyperShotController, "Konami Hyper Shot Controller")] + [InlineData(DefaultExpansionDevice.CoconutsPachinkoController, "Coconuts Pachinko Controller")] + [InlineData(DefaultExpansionDevice.ExcitingBoxingPunchingBag, "Exciting Boxing Punching Bag (Blowup Doll)")] + [InlineData(DefaultExpansionDevice.JissenMahjongController, "Jissen Mahjong Controller")] + [InlineData(DefaultExpansionDevice.YonezawaPartyTap, "米澤 (Yonezawa) Party Tap")] + [InlineData(DefaultExpansionDevice.OekaKidsTablet, "Oeka Kids Tablet")] + [InlineData(DefaultExpansionDevice.SunsoftBarcodeBattler, "Sunsoft Barcode Battler")] + [InlineData(DefaultExpansionDevice.MiraclePianoKeyboard, "Miracle Piano Keyboard")] + [InlineData(DefaultExpansionDevice.PokkunMoguraaTapTapMat, "Pokkun Moguraa Tap-tap Mat (Whack-a-Mole Mat and Mallet)")] + [InlineData(DefaultExpansionDevice.TopRider, "Top Rider (Inflatable Bicycle)")] + [InlineData(DefaultExpansionDevice.DoubleFisted, "Double-Fisted (Requires or allows use of two controllers by one player)")] + [InlineData(DefaultExpansionDevice.Famicom3DSystem, "Famicom 3D System")] + [InlineData(DefaultExpansionDevice.DoremikkoKeyboard, "Doremikko Keyboard")] + [InlineData(DefaultExpansionDevice.ROBGyromite, "R.O.B. Gyromite")] + [InlineData(DefaultExpansionDevice.FamicomDataRecorder, "Famicom Data Recorder ('silent' keyboard)")] + [InlineData(DefaultExpansionDevice.ASCIITurboFile, "ASCII Turbo File")] + [InlineData(DefaultExpansionDevice.IGSStorageBattleBox, "IGS Storage Battle Box")] + [InlineData(DefaultExpansionDevice.FamilyBASICKeyboardPlusFamicomDataRecorder, "Family BASIC Keyboard plus Famicom Data Recorder")] + [InlineData(DefaultExpansionDevice.DongdaPECKeyboard, "东达 (Dōngdá) PEC Keyboard")] + [InlineData(DefaultExpansionDevice.BitCorpBit79Keyboard, "普澤 (Pǔzé, a.k.a. Bit Corp.) Bit-79 Keyboard")] + [InlineData(DefaultExpansionDevice.SuborKeyboard, "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard")] + [InlineData(DefaultExpansionDevice.SuborKeyboardPlusMacroWinnersMouse, "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus Macro Winners Mouse")] + [InlineData(DefaultExpansionDevice.SuborKeyboardPlusSuborMouse4016, "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus Subor Mouse via $4016")] + [InlineData(DefaultExpansionDevice.SNESMouse4016, "SNES Mouse ($4016)")] + [InlineData(DefaultExpansionDevice.Multicart, "Multicart")] + [InlineData(DefaultExpansionDevice.TwoSNESControllers, "Two SNES controllers replacing the two standard NES controllers")] + [InlineData(DefaultExpansionDevice.RacerMateBicycle, "RacerMate Bicycle")] + [InlineData(DefaultExpansionDevice.UForce, "U-Force")] + [InlineData(DefaultExpansionDevice.ROBStackUp, "R.O.B. Stack-Up")] + [InlineData(DefaultExpansionDevice.CityPatrolmanLightgun, "City Patrolman Lightgun")] + [InlineData(DefaultExpansionDevice.SharpC1CassetteInterface, "Sharp C1 Cassette Interface")] + [InlineData(DefaultExpansionDevice.StandardControllerWithSwappedInputs, "Standard Controller with swapped Left-Right/Up-Down/B-A")] + [InlineData(DefaultExpansionDevice.ExcaliburSudokuPad, "Excalibur Sudoku Pad")] + [InlineData(DefaultExpansionDevice.ABLPinball, "ABL Pinball")] + [InlineData(DefaultExpansionDevice.GoldenNuggetCasinoExtraButtons, "Golden Nugget Casino extra buttons")] + [InlineData(DefaultExpansionDevice.KedaKeyboard, "科达 (Kēdá) Keyboard")] + [InlineData(DefaultExpansionDevice.SuborKeyboardPlusSuborMouse4017, "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus Subor Mouse via $4017")] + [InlineData(DefaultExpansionDevice.PortTestController, "Port test controller")] + [InlineData(DefaultExpansionDevice.BandaiMultiGamePlayerGamepad, "Bandai Multi Game Player Gamepad buttons")] + [InlineData(DefaultExpansionDevice.VenomTVDanceMat, "Venom TV Dance Mat")] + [InlineData(DefaultExpansionDevice.LGTVRemoteControl, "LG TV Remote Control")] + [InlineData(DefaultExpansionDevice.FamicomNetworkController, "Famicom Network Controller")] + [InlineData(DefaultExpansionDevice.KingFishingController, "King Fishing Controller")] + [InlineData(DefaultExpansionDevice.CroakyKaraokeController, "Croaky Karaoke Controller")] + [InlineData(DefaultExpansionDevice.KingwonKeyboard, "科王 (Kēwáng, a.k.a. Kingwon) Keyboard")] + [InlineData(DefaultExpansionDevice.ZechengKeyboard, "泽诚 (Zéchéng) Keyboard")] + [InlineData(DefaultExpansionDevice.SuborKeyboardPlusL90RotatedPS2Mouse4017, "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus L90-rotated PS/2 mouse in $4017")] + [InlineData(DefaultExpansionDevice.PS2KeyboardInUM6578PS2PortPS2Mouse4017, "PS/2 Keyboard in UM6578 PS/2 port, PS/2 Mouse via $4017")] + [InlineData(DefaultExpansionDevice.PS2MouseInUM6578PS2Port, "PS/2 Mouse in UM6578 PS/2 port")] + [InlineData(DefaultExpansionDevice.YuxingMouse4016, "裕兴 (Yùxìng) Mouse via $4016")] + [InlineData(DefaultExpansionDevice.SuborKeyboardPlusYuxingMouse4016, "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus 裕兴 (Yùxìng) Mouse mouse in $4016")] + [InlineData(DefaultExpansionDevice.GigggleTVPump, "Gigggle TV Pump")] + [InlineData(DefaultExpansionDevice.BBKKeyboardPlusR90RotatedPS2Mouse4017, "步步高 (Bùbùgāo, a.k.a. BBK) Keyboard plus R90-rotated PS/2 mouse in $4017")] + [InlineData(DefaultExpansionDevice.MagicalCooking, "Magical Cooking")] + [InlineData(DefaultExpansionDevice.SNESMouse4017, "SNES Mouse ($4017)")] + [InlineData(DefaultExpansionDevice.Zapper4016, "Zapper ($4016)")] + [InlineData(DefaultExpansionDevice.ArkanoidVausControllerPrototype, "Arkanoid Vaus Controller (Prototype)")] + [InlineData(DefaultExpansionDevice.TVMahjongGameController, "TV 麻雀 Game (TV Mahjong Game) Controller")] + [InlineData(DefaultExpansionDevice.MahjongGekitouDensetsuController, "麻雀激闘伝説 (Mahjong Gekitou Densetsu) Controller")] + [InlineData(DefaultExpansionDevice.SuborKeyboardPlusXInvertedPS2Mouse4017, "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus X-inverted PS/2 mouse in $4017")] + [InlineData(DefaultExpansionDevice.IBMPCXTKeyboard, "IBM PC/XT Keyboard")] + [InlineData(DefaultExpansionDevice.SuborKeyboardPlusMegaBookMouse, "小霸王 (Xiǎobàwáng, a.k.a. Subor) Keyboard plus Mega Book Mouse")] + public void FromDefaultExpansionDeviceTest(DefaultExpansionDevice device, string expected) + { + string actual = device.FromDefaultExpansionDevice(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(ExtendedConsoleType.RegularSystem, "Regular NES/Famicom/Dendy")] + [InlineData(ExtendedConsoleType.NintendoVsSystem, "Nintendo Vs. System")] + [InlineData(ExtendedConsoleType.Playchoice10, "Playchoice 10")] + [InlineData(ExtendedConsoleType.RegularFamicloneDecimalMode, "Regular Famiclone, but with CPU that supports Decimal Mode")] + [InlineData(ExtendedConsoleType.RegularNESWithEPSM, "Regular NES/Famicom with EPSM module or plug-through cartridge")] + [InlineData(ExtendedConsoleType.VRTechnologyVT01, "V.R. Technology VT01 with red/cyan STN palette")] + [InlineData(ExtendedConsoleType.VRTechnologyVT02, "V.R. Technology VT02")] + [InlineData(ExtendedConsoleType.VRTechnologyVT03, "V.R. Technology VT03")] + [InlineData(ExtendedConsoleType.VRTechnologyVT09, "V.R. Technology VT09")] + [InlineData(ExtendedConsoleType.VRTechnologyVT32, "V.R. Technology VT32")] + [InlineData(ExtendedConsoleType.VRTechnologyVT369, "V.R. Technology VT369")] + [InlineData(ExtendedConsoleType.UMCUM6578, "UMC UM6578")] + [InlineData(ExtendedConsoleType.FamicomNetworkSystem, "Famicom Network System")] + [InlineData(ExtendedConsoleType.ReservedD, "Reserved (0x0D)")] + [InlineData(ExtendedConsoleType.ReservedE, "Reserved (0x0E)")] + [InlineData(ExtendedConsoleType.ReservedF, "Reserved (0x0F)")] + public void FromExtendedConsoleTypeTest(ExtendedConsoleType type, string expected) + { + string actual = type.FromExtendedConsoleType(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(NametableArrangement.Vertical, "Vertical")] + [InlineData(NametableArrangement.Horizontal, "Horizontal")] + public void FromNametableArrangementTest(NametableArrangement arrangement, string expected) + { + string actual = arrangement.FromNametableArrangement(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(TVSystem.NTSC, "NTSC")] + [InlineData(TVSystem.PAL, "PAL")] + public void FromTVSystemTest(TVSystem system, string expected) + { + string actual = system.FromTVSystem(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(TVSystemExtended.NTSC, "NTSC")] + [InlineData(TVSystemExtended.DualCompatible1, "Dual-compatible (0x01)")] + [InlineData(TVSystemExtended.PAL, "PAL")] + [InlineData(TVSystemExtended.DualCompatible3, "Dual-compatible (0x03)")] + public void FromTVSystemExtendedTest(TVSystemExtended system, string expected) + { + string actual = system.FromTVSystemExtended(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(VsHardwareType.VsUnisystem, "Vs. Unisystem (normal)")] + [InlineData(VsHardwareType.VsUnisystemRBIBaseballProtection, "Vs. Unisystem (RBI Baseball protection)")] + [InlineData(VsHardwareType.VsUnisystemTKOBoxingProtection, "Vs. Unisystem (TKO Boxing protection)")] + [InlineData(VsHardwareType.VsUnisystemSuperXeviousProtection, "Vs. Unisystem (Super Xevious protection)")] + [InlineData(VsHardwareType.VsUnisystemVsIceClimberJapanProtection, "Vs. Unisystem (Vs. Ice Climber Japan protection)")] + [InlineData(VsHardwareType.VsDualSystem, "Vs. Dual System (normal)")] + [InlineData(VsHardwareType.VsDualSystemRaidOnBungelingBayProtection, "Vs. Dual System (Raid on Bungeling Bay protection)")] + public void FromVsHardwareTypeTest(VsHardwareType type, string expected) + { + string actual = type.FromVsHardwareType(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(VsSystemType.AnyRP2C03RC2C03Variant, "Any RP2C03/RC2C03 variant")] + [InlineData(VsSystemType.Reserved1, "Reserved (0x01)")] + [InlineData(VsSystemType.RP2C040001, "RP2C04-0001")] + [InlineData(VsSystemType.RP2C040002, "RP2C04-0002")] + [InlineData(VsSystemType.RP2C040003, "RP2C04-0003")] + [InlineData(VsSystemType.RP2C040004, "RP2C04-0004")] + [InlineData(VsSystemType.Reserved6, "Reserved (0x06)")] + [InlineData(VsSystemType.Reserved7, "Reserved (0x07)")] + [InlineData(VsSystemType.RC2C0501, "RC2C05-01 (signature unknown)")] + [InlineData(VsSystemType.RC2C0502, "RC2C05-02 ($2002 AND $3F =$3D)")] + [InlineData(VsSystemType.RC2C0503, "RC2C05-03 ($2002 AND $1F =$1C)")] + [InlineData(VsSystemType.RC2C0504, "RC2C05-04 ($2002 AND $1F =$1B)")] + [InlineData(VsSystemType.ReservedC, "Reserved (0x0C)")] + [InlineData(VsSystemType.ReservedD, "Reserved (0x0D)")] + [InlineData(VsSystemType.ReservedE, "Reserved (0x0E)")] + [InlineData(VsSystemType.ReservedF, "Reserved (0x0F)")] + public void FromVsSystemTypeTest(VsSystemType type, string expected) + { + string actual = type.FromVsSystemType(); + Assert.Equal(expected, actual); + } + } +} diff --git a/SabreTools.Data.Extensions.Test/NewExecutableExtensionsTests.cs b/SabreTools.Data.Extensions.Test/NewExecutableExtensionsTests.cs new file mode 100644 index 00000000..73d198c2 --- /dev/null +++ b/SabreTools.Data.Extensions.Test/NewExecutableExtensionsTests.cs @@ -0,0 +1,61 @@ +using SabreTools.Data.Models.NewExecutable; +using Xunit; + +namespace SabreTools.Data.Extensions.Test +{ + public class NewExecutableExtensionsTests + { + #region IsIntegerType + + [Fact] + public void IsIntegerType_RTIE_HighBitSet_True() + { + var entry = new ResourceTypeInformationEntry { TypeID = 0xFFFF }; + bool actual = entry.IsIntegerType(); + Assert.True(actual); + } + + [Fact] + public void IsIntegerType_RTIE_HighBitClear_False() + { + var entry = new ResourceTypeInformationEntry { TypeID = 0x0000 }; + bool actual = entry.IsIntegerType(); + Assert.False(actual); + } + + [Fact] + public void IsIntegerType_RTRE_HighBitSet_True() + { + var entry = new ResourceTypeResourceEntry { ResourceID = 0xFFFF }; + bool actual = entry.IsIntegerType(); + Assert.True(actual); + } + + [Fact] + public void IsIntegerType_RTRE_HighBitClear_False() + { + var entry = new ResourceTypeResourceEntry { ResourceID = 0x0000 }; + bool actual = entry.IsIntegerType(); + Assert.False(actual); + } + + #endregion + + #region GetEntryType + + [Theory] + [InlineData(0x00, SegmentEntryType.Unused)] + [InlineData(0x01, SegmentEntryType.FixedSegment)] + [InlineData(0xAA, SegmentEntryType.FixedSegment)] + [InlineData(0xFE, SegmentEntryType.FixedSegment)] + [InlineData(0xFF, SegmentEntryType.MoveableSegment)] + public void GetEntryTypeTest(byte segmentIndicator, SegmentEntryType expected) + { + var entry = new EntryTableBundle { SegmentIndicator = segmentIndicator }; + SegmentEntryType actual = entry.GetEntryType(); + Assert.Equal(expected, actual); + } + + #endregion + } +} diff --git a/SabreTools.Data.Extensions.Test/WiseScriptExtensionsTests.cs b/SabreTools.Data.Extensions.Test/WiseScriptExtensionsTests.cs new file mode 100644 index 00000000..d21e7e6e --- /dev/null +++ b/SabreTools.Data.Extensions.Test/WiseScriptExtensionsTests.cs @@ -0,0 +1,59 @@ +using Xunit; + +namespace SabreTools.Data.Extensions.Test +{ + public class WiseScriptExtensionsTests + { + [Theory] + // Defined functions + [InlineData("f0", "Add Directory to PATH")] + [InlineData("f1", "Add to AUTOEXEC.BAT")] + [InlineData("f2", "Add to CONFIG.SYS")] + [InlineData("f3", "Add to SYSTEM.INI")] + [InlineData("f8", "Read INI Value")] + [InlineData("f9", "Get Registry Key Value")] + [InlineData("f10", "Register Font")] + [InlineData("f11", "Win32 System Directory")] + [InlineData("f12", "Check Configuration")] + [InlineData("f13", "Search for File")] + [InlineData("f15", "Read/Write Binary File")] + [InlineData("f16", "Set Variable")] + [InlineData("f17", "Get Environment Variable")] + [InlineData("f19", "Check if File/Dir Exists")] + [InlineData("f20", "Set File Attributes")] + [InlineData("f21", "Set Files/Buffers")] + [InlineData("f22", "Find File in Path")] + [InlineData("f23", "Check Disk Space")] + [InlineData("f25", "Insert Line Into Text File")] + [InlineData("f27", "Parse String")] + [InlineData("f28", "Exit Installation")] + [InlineData("f29", "Self-Register OCXs/DLLs")] + [InlineData("f30", "Install DirectX Components")] + [InlineData("f31", "Wizard Block")] + [InlineData("f33", "Read/Update Text File")] + [InlineData("f34", "Post to HTTP Server")] + [InlineData("f35", "Prompt for Filename")] + [InlineData("f36", "Start/Stop Service")] + [InlineData("f38", "Check HTTP Connection")] + // Undefined functions + [InlineData("f4", "UNDEFINED f4")] + [InlineData("f5", "UNDEFINED f5")] + [InlineData("f6", "UNDEFINED f6")] + [InlineData("f7", "UNDEFINED f7")] + [InlineData("f14", "UNDEFINED f14")] + [InlineData("f18", "UNDEFINED f18")] + [InlineData("f24", "UNDEFINED f24")] + [InlineData("f26", "UNDEFINED f26")] + [InlineData("f32", "UNDEFINED f32")] + [InlineData("f37", "UNDEFINED f37")] + // External DLL + [InlineData(null, null)] + [InlineData("f99", "UNDEFINED f99")] + [InlineData("func", "External: func")] + public void FromWiseFunctionIdTest(string? functionId, string? expected) + { + string? actual = functionId.FromWiseFunctionId(); + Assert.Equal(expected, actual); + } + } +} diff --git a/SabreTools.Data.Extensions.Test/XZExtensionsTests.cs b/SabreTools.Data.Extensions.Test/XZExtensionsTests.cs new file mode 100644 index 00000000..38ff8d6f --- /dev/null +++ b/SabreTools.Data.Extensions.Test/XZExtensionsTests.cs @@ -0,0 +1,20 @@ +using System.Linq; +using Xunit; + +namespace SabreTools.Data.Extensions.Test +{ + public class XZExtensionsTests + { + [Fact] + public void VariableLengthIntegerTest() + { + ulong expected = 123456789; + byte[] encoded = expected.EncodeVariableLength(); + Assert.True(encoded.SequenceEqual([0x95, 0x9A, 0xEF, 0x3A])); + + ulong actual = encoded.DecodeVariableLength(maxSize: 16, out int length); + Assert.Equal(expected, actual); + Assert.Equal(4, length); + } + } +} diff --git a/SabreTools.Data.Extensions.Test/XboxExecutableExtensionsTests.cs b/SabreTools.Data.Extensions.Test/XboxExecutableExtensionsTests.cs new file mode 100644 index 00000000..a0dea77b --- /dev/null +++ b/SabreTools.Data.Extensions.Test/XboxExecutableExtensionsTests.cs @@ -0,0 +1,17 @@ +using Xunit; + +namespace SabreTools.Data.Extensions.Test +{ + public class XboxExecutableExtensionsTests + { + [Theory] + [InlineData(0x00000000, "0000-000")] + [InlineData(0x4142000F, "AB-015")] + [InlineData(0x3132F000, "12-61440")] + public void ToFormattedXBETitleIDTest(uint value, string expected) + { + string actual = value.ToFormattedXBETitleID(); + Assert.Equal(expected, actual); + } + } +} diff --git a/SabreTools.Data.Extensions/Atari7800CartExtensions.cs b/SabreTools.Data.Extensions/Atari7800CartExtensions.cs index 6663010c..34a0e1f8 100644 --- a/SabreTools.Data.Extensions/Atari7800CartExtensions.cs +++ b/SabreTools.Data.Extensions/Atari7800CartExtensions.cs @@ -12,7 +12,7 @@ namespace SabreTools.Data.Extensions { string[] devices = new string[4]; - byte pokey = (byte)((byte)audio & 0x0F); + byte pokey = (byte)((byte)audio & 0x07); devices[0] = pokey switch { 0 => "POKEY - none", @@ -24,7 +24,7 @@ namespace SabreTools.Data.Extensions _ => $"Unknown {pokey}", }; - byte ym2151 = (byte)(((byte)audio >> 1) & 0x01); + byte ym2151 = (byte)(((byte)audio >> 3) & 0x01); devices[1] = ym2151 switch { 0 => "No YM2151 @460", @@ -32,7 +32,7 @@ namespace SabreTools.Data.Extensions _ => $"Unknown {ym2151}", }; - byte covox = (byte)(((byte)audio >> 2) & 0x01); + byte covox = (byte)(((byte)audio >> 4) & 0x01); devices[2] = covox switch { 0 => "No COVOX @430", @@ -40,7 +40,7 @@ namespace SabreTools.Data.Extensions _ => $"Unknown {covox}", }; - byte adpcm = (byte)(((byte)audio >> 3) & 0x01); + byte adpcm = (byte)(((byte)audio >> 5) & 0x01); devices[3] = adpcm switch { 0 => "No ADPCM Audio Stream @420", @@ -239,7 +239,7 @@ namespace SabreTools.Data.Extensions { string[] romOptions = new string[2]; - byte option4000 = (byte)((byte)options & 0x0F); + byte option4000 = (byte)((byte)options & 0x07); romOptions[0] = option4000 switch { 0 => "Option at @4000 - none", diff --git a/SabreTools.Data.Extensions/NESCartExtensions.cs b/SabreTools.Data.Extensions/NESCartExtensions.cs index 13ef8b59..42a39704 100644 --- a/SabreTools.Data.Extensions/NESCartExtensions.cs +++ b/SabreTools.Data.Extensions/NESCartExtensions.cs @@ -155,13 +155,13 @@ namespace SabreTools.Data.Extensions /// /// Convert a value to string /// - public static string FromNametableArrangement(this NametableArrangement type) + public static string FromNametableArrangement(this NametableArrangement arrangement) { - return type switch + return arrangement switch { NametableArrangement.Vertical => "Vertical", NametableArrangement.Horizontal => "Horizontal", - _ => $"Unknown {(byte)type}", + _ => $"Unknown {(byte)arrangement}", }; } diff --git a/SabreTools.Data.Extensions/PortableExecutableExtensions.cs b/SabreTools.Data.Extensions/PortableExecutableExtensions.cs index 622e9959..186f7165 100644 --- a/SabreTools.Data.Extensions/PortableExecutableExtensions.cs +++ b/SabreTools.Data.Extensions/PortableExecutableExtensions.cs @@ -3,6 +3,7 @@ using SabreTools.Data.Models.COFF; namespace SabreTools.Data.Extensions { + // TODO: Add tests public static class PortableExecutableExtensions { /// diff --git a/SabreTools.Data.Extensions/XboxExecutableExtensions.cs b/SabreTools.Data.Extensions/XboxExecutableExtensions.cs index f9d5ca4e..28d66b8e 100644 --- a/SabreTools.Data.Extensions/XboxExecutableExtensions.cs +++ b/SabreTools.Data.Extensions/XboxExecutableExtensions.cs @@ -8,7 +8,7 @@ namespace SabreTools.Data.Extensions /// /// Convert a UInt32 to a formatted XBE title ID /// - public static string? ToFormattedXBETitleID(this uint value) + public static string ToFormattedXBETitleID(this uint value) { // Convert to a byte array byte[] data = BitConverter.GetBytes(value); diff --git a/SabreTools.Wrappers/XboxExecutable.cs b/SabreTools.Wrappers/XboxExecutable.cs index 9874e2e7..f9b974af 100644 --- a/SabreTools.Wrappers/XboxExecutable.cs +++ b/SabreTools.Wrappers/XboxExecutable.cs @@ -29,7 +29,7 @@ namespace SabreTools.Wrappers if (AlternativeTitleIDs is null) return null; - return Array.ConvertAll(AlternativeTitleIDs, ba => ba.ToFormattedXBETitleID() ?? "[NULL]"); + return Array.ConvertAll(AlternativeTitleIDs, ba => ba.ToFormattedXBETitleID()); } } @@ -74,7 +74,7 @@ namespace SabreTools.Wrappers public uint TitleID => Certificate?.TitleID ?? 0; /// - public string? TitleIDString => TitleID.ToFormattedXBETitleID(); + public string TitleIDString => TitleID.ToFormattedXBETitleID(); /// public string? TitleName