Attempt to fix detection issues

This commit is contained in:
Matt Nadareski
2026-05-14 20:08:32 -04:00
parent 249c51933b
commit d3c9849908
3 changed files with 43 additions and 42 deletions

View File

@@ -65,5 +65,13 @@ namespace SabreTools.Data.Extensions
/// </summary>
public static bool IsGameCubeTitleType(this char c)
=> c == 'G' || c == 'D' || c == 'R';
/// <summary>
/// Returns true if the byte is a known Nintendo disc title type code
/// (first byte of the 6-char GameId, e.g. 'G'=GameCube, 'R'=GameCube,
/// 'D'=GameCube demo, 'S'=Wii, 'F'=Wii channel)
/// </summary>
public static bool IsNintendoDiscTitleType(this byte b)
=> b == 'G' || b == 'D' || b == 'R' || b == 'S' || b == 'F';
}
}

View File

@@ -34,6 +34,8 @@ namespace SabreTools.Serialization.Readers
// Determine platform from magic words; fall back to GameId prefix for
// GC discs that omit the magic word (e.g. some redump/scene ISOs)
Platform platform = disc.Header.GetPlatform();
if (platform == Platform.Unknown)
return null;
// Parse Wii-specific structures
if (platform == Platform.Wii)

View File

@@ -1,5 +1,6 @@
using System;
using System.IO;
using SabreTools.Data.Extensions;
using SabreTools.IO.Extensions;
using SabreTools.Matching;
using SabreTools.Numerics.Extensions;
@@ -541,36 +542,6 @@ namespace SabreTools.Wrappers
#endregion
#region NintendoDisc
// Wii disc magic at offset 0x018 (0x5D1C9EA3 stored big-endian on disc)
if (magic.Length > 0x1B && magic[0x18] == 0x5D && magic[0x19] == 0x1C && magic[0x1A] == 0x9E && magic[0x1B] == 0xA3)
return WrapperType.NintendoDisc;
// GameCube disc magic at offset 0x01C (0xC2339F3D stored big-endian on disc)
if (magic.Length > 0x1F && magic[0x1C] == 0xC2 && magic[0x1D] == 0x33 && magic[0x1E] == 0x9F && magic[0x1F] == 0x3D)
return WrapperType.NintendoDisc;
// GameCube/Wii disc by GameId prefix: first byte is a known title type code,
// bytes 1-2 are ASCII letters (region + developer), bytes 3-4 are ASCII digits or letters (title code),
// byte 5 is an ASCII digit (disc number). Covers redump ISOs that lack magic words.
if (magic.Length > 5
&& IsNintendoDiscTitleType(magic[0])
&& magic[1] >= 0x41 && magic[1] <= 0x5A // A-Z
&& ((magic[2] >= 0x30 && magic[2] <= 0x39) || (magic[2] >= 0x41 && magic[2] <= 0x5A)) // 0-9 or A-Z
&& ((magic[3] >= 0x30 && magic[3] <= 0x39) || (magic[3] >= 0x41 && magic[3] <= 0x5A)) // 0-9 or A-Z
&& ((magic[4] >= 0x30 && magic[4] <= 0x39) || (magic[4] >= 0x41 && magic[4] <= 0x5A)) // 0-9 or A-Z
&& magic[5] >= 0x30 && magic[5] <= 0x39 // 0-9
&& (extension.Equals("iso", StringComparison.OrdinalIgnoreCase)
|| extension.Equals("gcm", StringComparison.OrdinalIgnoreCase)))
return WrapperType.NintendoDisc;
// .gcm files are always GameCube disc images
if (extension.Equals("gcm", StringComparison.OrdinalIgnoreCase))
return WrapperType.NintendoDisc;
#endregion
#region ISO9660
if (extension.Equals("iso", StringComparison.OrdinalIgnoreCase))
@@ -658,6 +629,38 @@ namespace SabreTools.Wrappers
#endregion
#region NintendoDisc
// Wii disc magic at offset 0x018 (0x5D1C9EA3 stored big-endian on disc)
if (magic.Length > 0x1B && magic[0x18] == 0x5D && magic[0x19] == 0x1C && magic[0x1A] == 0x9E && magic[0x1B] == 0xA3)
return WrapperType.NintendoDisc;
// GameCube disc magic at offset 0x01C (0xC2339F3D stored big-endian on disc)
if (magic.Length > 0x1F && magic[0x1C] == 0xC2 && magic[0x1D] == 0x33 && magic[0x1E] == 0x9F && magic[0x1F] == 0x3D)
return WrapperType.NintendoDisc;
// GameCube/Wii disc by GameId prefix: first byte is a known title type code,
// bytes 1-2 are ASCII letters (region + developer), bytes 3-4 are ASCII digits or letters (title code),
// byte 5 is an ASCII digit (disc number). Covers redump ISOs that lack magic words.
if (magic.Length > 5
&& magic[0].IsNintendoDiscTitleType()
&& magic[1] >= 'A' && magic[1] <= 'Z'
&& ((magic[2] >= '0' && magic[2] <= '9') || (magic[2] >= 'A' && magic[2] <= 'Z'))
&& ((magic[3] >= '0' && magic[3] <= '9') || (magic[3] >= 'A' && magic[3] <= 'Z'))
&& ((magic[4] >= '0' && magic[4] <= '9') || (magic[4] >= 'A' && magic[4] <= 'Z'))
&& magic[5] >= '0' && magic[5] <= '9'
&& (extension.Equals("iso", StringComparison.OrdinalIgnoreCase)
|| extension.Equals("gcm", StringComparison.OrdinalIgnoreCase)))
{
return WrapperType.NintendoDisc;
}
// .gcm files are always GameCube disc images
if (extension.Equals("gcm", StringComparison.OrdinalIgnoreCase))
return WrapperType.NintendoDisc;
#endregion
#region Nitro
// DS cart image
@@ -1186,17 +1189,5 @@ namespace SabreTools.Wrappers
// We couldn't find a supported match
return WrapperType.UNKNOWN;
}
/// <summary>
/// Returns true if the byte is a known Nintendo disc title type code
/// (first byte of the 6-char GameId, e.g. 'G'=GameCube, 'R'=GameCube,
/// 'D'=GameCube demo, 'S'=Wii, 'F'=Wii channel)
/// </summary>
private static bool IsNintendoDiscTitleType(byte b)
{
// Standard GameCube and Wii title type prefixes used by Nintendo and licensees
return b == (byte)'G' || b == (byte)'D' || b == (byte)'R'
|| b == (byte)'S' || b == (byte)'F';
}
}
}