diff --git a/Core/PCE/PceConsole.cpp b/Core/PCE/PceConsole.cpp index 838006458..acf69b19e 100644 --- a/Core/PCE/PceConsole.cpp +++ b/Core/PCE/PceConsole.cpp @@ -62,6 +62,10 @@ LoadRomResult PceConsole::LoadRom(VirtualFile& romFile) return LoadRomResult::Failure; } + if(consoleType == PceConsoleType::Auto && IsSuperGrafxCd(disc)) { + consoleType = PceConsoleType::SuperGrafx; + } + _cdrom.reset(new PceCdRom(_emu, this, disc)); _romFormat = RomFormat::PceCdRom; cdromUnitEnabled = true; @@ -136,6 +140,9 @@ LoadRomResult PceConsole::LoadRom(VirtualFile& romFile) MessageManager::Log("-----------------"); MessageManager::Log("Loaded: " + romFile.GetFileName()); + if(consoleType == PceConsoleType::SuperGrafx && cfg.ConsoleType == PceConsoleType::Auto) { + MessageManager::Log("Enabled SuperGrafx mode (auto-detect)"); + } MessageManager::Log("-----------------"); return LoadRomResult::Success; @@ -161,6 +168,25 @@ bool PceConsole::IsPopulousCard(uint32_t crc32) return crc32 == 0x083C956A; } +bool PceConsole::IsSuperGrafxCd(DiscInfo& disc) +{ + int32_t track = disc.GetFirstDataTrack(); + if(track < 0) { + return false; + } + + int32_t sector = disc.GetTrackFirstSector(track); + if(sector < 0) { + return false; + } + + //Check for custom homebrew marker to automatically enable SuperGrafx mode for CD games + //This should be in the 2nd sector of the first data track, at offset 0x80 + vector sectorData; + disc.ReadDataSector(sector + 1, sectorData); + return memcmp(sectorData.data() + 0x80, "(for SuperGRAFX)", 16) == 0; +} + bool PceConsole::IsSuperGrafxCard(uint32_t crc32) { //These are the 5 SuperGrafx-exclusive games diff --git a/Core/PCE/PceConsole.h b/Core/PCE/PceConsole.h index 39df74e3d..b8423db33 100644 --- a/Core/PCE/PceConsole.h +++ b/Core/PCE/PceConsole.h @@ -38,6 +38,7 @@ class PceConsole final : public IConsole RomFormat _romFormat = RomFormat::Pce; static bool IsPopulousCard(uint32_t crc32); + static bool IsSuperGrafxCd(DiscInfo& disc); static bool IsSuperGrafxCard(uint32_t crc32); bool LoadHesFile(VirtualFile& hesFile); diff --git a/Core/Shared/CdReader.h b/Core/Shared/CdReader.h index d123b73f5..f6263a1e6 100644 --- a/Core/Shared/CdReader.h +++ b/Core/Shared/CdReader.h @@ -96,6 +96,16 @@ struct DiscInfo return -1; } + int32_t GetFirstDataTrack() + { + for(size_t i = 0; i < Tracks.size(); i++) { + if(Tracks[i].Format != TrackFormat::Audio) { + return (int32_t)i; + } + } + return -1; + } + int32_t GetTrackFirstSector(int32_t track) { if(track < Tracks.size()) { @@ -135,6 +145,7 @@ struct DiscInfo uint32_t byteOffset = trk.FileOffset + (sector - trk.FirstSector) * sectorSize; if(!Files[trk.FileIndex].ReadChunk(outData, byteOffset + sectorHeaderSize, 2048)) { LogDebug("Invalid read offsets"); + outData.insert(outData.end(), 2048, 0); } } }