Fix DSiWare detection (#1969)

- According to GBATek, all DSiWare games have a high title ID of 0x00030004
- Some homebrew apps set the Unitcode bits to DSi mode to enable support of DSi features
This commit is contained in:
Jesse Talavera 2024-02-01 08:36:35 -05:00 committed by GitHub
parent 7dd4152d67
commit d48e5f2da0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 6 additions and 3 deletions

View File

@ -39,6 +39,8 @@ enum RegionMask : u32
RegionFree = 0xFFFFFFFF, RegionFree = 0xFFFFFFFF,
}; };
constexpr u32 DSiWareTitleIDHigh = 0x00030004;
// Consult GBATEK for info on what these are // Consult GBATEK for info on what these are
struct NDSHeader struct NDSHeader
{ {
@ -198,8 +200,9 @@ struct NDSHeader
u8 HeaderSignature[128]; // RSA-SHA1 across 0x000..0xDFF u8 HeaderSignature[128]; // RSA-SHA1 across 0x000..0xDFF
/// @return \c true if this header represents a DSi title /// @return \c true if this header represents a title
/// (either a physical cartridge or a DSiWare title). /// that is DSi-exclusive (including DSiWare)
/// or DSi-enhanced (including cartridges).
[[nodiscard]] bool IsDSi() const { return (UnitCode & 0x02) != 0; } [[nodiscard]] bool IsDSi() const { return (UnitCode & 0x02) != 0; }
[[nodiscard]] u32 GameCodeAsU32() const { [[nodiscard]] u32 GameCodeAsU32() const {
return (u32)GameCode[3] << 24 | return (u32)GameCode[3] << 24 |
@ -213,7 +216,7 @@ struct NDSHeader
} }
/// @return \c true if this header represents a DSiWare title. /// @return \c true if this header represents a DSiWare title.
[[nodiscard]] bool IsDSiWare() const { return IsDSi() && DSiRegionStart == 0; } [[nodiscard]] bool IsDSiWare() const { return IsDSi() && DSiTitleIDHigh == DSiWareTitleIDHigh; }
}; };
static_assert(sizeof(NDSHeader) == 4096, "NDSHeader is not 4096 bytes!"); static_assert(sizeof(NDSHeader) == 4096, "NDSHeader is not 4096 bytes!");