From 494e2c05c217c6ba80ceecba7c3d7ce339ea55a9 Mon Sep 17 00:00:00 2001 From: Zopolis4 Date: Wed, 21 Jul 2021 02:18:44 +1000 Subject: [PATCH 1/7] Adding support for detecting .bin images --- .../dolphinemu/utils/FileBrowserHelper.java | 4 ++-- Source/Core/Core/Boot/Boot.cpp | 3 ++- Source/Core/DolphinQt/GameList/GameTracker.cpp | 14 +++++++------- Source/Core/DolphinQt/Info.plist.in | 1 + Source/Core/DolphinQt/MainWindow.cpp | 2 +- Source/Core/DolphinQt/Settings/PathPane.cpp | 2 +- Source/Core/UICommon/GameFileCache.cpp | 6 +++--- 7 files changed, 17 insertions(+), 15 deletions(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java index c7401c2bc5..f13578d7ae 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java @@ -30,8 +30,8 @@ import java.util.Set; public final class FileBrowserHelper { public static final HashSet GAME_EXTENSIONS = new HashSet<>(Arrays.asList( - "gcm", "tgc", "iso", "ciso", "gcz", "wbfs", "wia", "rvz", "nfs", "wad", "dol", "elf", - "json")); + "gcm", "tgc", "bin", "iso", "ciso", "gcz", "wbfs", "wia", "rvz", "nfs", "wad", "dol", + "elf", "json")); public static final HashSet GAME_LIKE_EXTENSIONS = new HashSet<>(GAME_EXTENSIONS); diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index 1340d19c84..4e08ccfd12 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -236,7 +236,8 @@ std::unique_ptr BootParameters::GenerateFromFile(std::vector disc_image_extensions = { - {".gcm", ".iso", ".tgc", ".wbfs", ".ciso", ".gcz", ".wia", ".rvz", ".nfs", ".dol", ".elf"}}; + {".gcm", ".bin", ".iso", ".tgc", ".wbfs", ".ciso", ".gcz", ".wia", ".rvz", ".nfs", ".dol", + ".elf"}}; if (disc_image_extensions.contains(extension)) { std::unique_ptr disc = DiscIO::CreateDisc(path); diff --git a/Source/Core/DolphinQt/GameList/GameTracker.cpp b/Source/Core/DolphinQt/GameList/GameTracker.cpp index 9428729997..6031d37a32 100644 --- a/Source/Core/DolphinQt/GameList/GameTracker.cpp +++ b/Source/Core/DolphinQt/GameList/GameTracker.cpp @@ -22,13 +22,13 @@ // NOTE: Qt likes to be case-sensitive here even though it shouldn't be thus this ugly regex hack static const QStringList game_filters{ - QStringLiteral("*.[gG][cC][mM]"), QStringLiteral("*.[iI][sS][oO]"), - QStringLiteral("*.[tT][gG][cC]"), QStringLiteral("*.[cC][iI][sS][oO]"), - QStringLiteral("*.[gG][cC][zZ]"), QStringLiteral("*.[wW][bB][fF][sS]"), - QStringLiteral("*.[wW][iI][aA]"), QStringLiteral("*.[rR][vV][zZ]"), - QStringLiteral("hif_000000.nfs"), QStringLiteral("*.[wW][aA][dD]"), - QStringLiteral("*.[eE][lL][fF]"), QStringLiteral("*.[dD][oO][lL]"), - QStringLiteral("*.[jJ][sS][oO][nN]")}; + QStringLiteral("*.[gG][cC][mM]"), QStringLiteral("*.[bB][iI][nN]"), + QStringLiteral("*.[iI][sS][oO]"), QStringLiteral("*.[tT][gG][cC]"), + QStringLiteral("*.[cC][iI][sS][oO]"), QStringLiteral("*.[gG][cC][zZ]"), + QStringLiteral("*.[wW][bB][fF][sS]"), QStringLiteral("*.[wW][iI][aA]"), + QStringLiteral("*.[rR][vV][zZ]"), QStringLiteral("hif_000000.nfs"), + QStringLiteral("*.[wW][aA][dD]"), QStringLiteral("*.[eE][lL][fF]"), + QStringLiteral("*.[dD][oO][lL]"), QStringLiteral("*.[jJ][sS][oO][nN]")}; GameTracker::GameTracker(QObject* parent) : QFileSystemWatcher(parent) { diff --git a/Source/Core/DolphinQt/Info.plist.in b/Source/Core/DolphinQt/Info.plist.in index ddd2ed4182..0550533969 100644 --- a/Source/Core/DolphinQt/Info.plist.in +++ b/Source/Core/DolphinQt/Info.plist.in @@ -7,6 +7,7 @@ CFBundleTypeExtensions + bin ciso dol elf diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp index 93ad16a59e..6cb0a39a06 100644 --- a/Source/Core/DolphinQt/MainWindow.cpp +++ b/Source/Core/DolphinQt/MainWindow.cpp @@ -787,7 +787,7 @@ QStringList MainWindow::PromptFileNames() QStringList paths = DolphinFileDialog::getOpenFileNames( this, tr("Select a File"), settings.value(QStringLiteral("mainwindow/lastdir"), QString{}).toString(), - QStringLiteral("%1 (*.elf *.dol *.gcm *.iso *.tgc *.wbfs *.ciso *.gcz *.wia *.rvz " + QStringLiteral("%1 (*.elf *.dol *.gcm *.bin *.iso *.tgc *.wbfs *.ciso *.gcz *.wia *.rvz " "hif_000000.nfs *.wad *.dff *.m3u *.json);;%2 (*)") .arg(tr("All GC/Wii files")) .arg(tr("All Files"))); diff --git a/Source/Core/DolphinQt/Settings/PathPane.cpp b/Source/Core/DolphinQt/Settings/PathPane.cpp index 8d91e31d50..bcbcbf3248 100644 --- a/Source/Core/DolphinQt/Settings/PathPane.cpp +++ b/Source/Core/DolphinQt/Settings/PathPane.cpp @@ -45,7 +45,7 @@ void PathPane::BrowseDefaultGame() { QString file = QDir::toNativeSeparators(DolphinFileDialog::getOpenFileName( this, tr("Select a Game"), Settings::Instance().GetDefaultGame(), - QStringLiteral("%1 (*.elf *.dol *.gcm *.iso *.tgc *.wbfs *.ciso *.gcz *.wia *.rvz " + QStringLiteral("%1 (*.elf *.dol *.gcm *.bin *.iso *.tgc *.wbfs *.ciso *.gcz *.wia *.rvz " "hif_000000.nfs *.wad *.m3u *.json);;%2 (*)") .arg(tr("All GC/Wii files")) .arg(tr("All Files")))); diff --git a/Source/Core/UICommon/GameFileCache.cpp b/Source/Core/UICommon/GameFileCache.cpp index 90dd0c63fc..f72f47c11e 100644 --- a/Source/Core/UICommon/GameFileCache.cpp +++ b/Source/Core/UICommon/GameFileCache.cpp @@ -26,14 +26,14 @@ namespace UICommon { -static constexpr u32 CACHE_REVISION = 25; // Last changed in PR 12702 +static constexpr u32 CACHE_REVISION = 26; // Last changed in PR 10084 std::vector FindAllGamePaths(const std::vector& directories_to_scan, bool recursive_scan) { static const std::vector search_extensions = { - ".gcm", ".tgc", ".iso", ".ciso", ".gcz", ".wbfs", ".wia", - ".rvz", ".nfs", ".wad", ".dol", ".elf", ".json"}; + ".gcm", ".tgc", ".bin", ".iso", ".ciso", ".gcz", ".wbfs", + ".wia", ".rvz", ".nfs", ".wad", ".dol", ".elf", ".json"}; // TODO: We could process paths iteratively as they are found return Common::DoFileSearch(directories_to_scan, search_extensions, recursive_scan); From 71f654cdc45ecb44e455ce35d8be910732aa6f7c Mon Sep 17 00:00:00 2001 From: Zopolis4 Date: Tue, 10 Aug 2021 07:49:34 +1000 Subject: [PATCH 2/7] Add Triforce platform and preliminary boot.id parsing --- Data/Sys/Resources/Platform_Triforce.png | Bin 0 -> 2396 bytes Data/Sys/Resources/Platform_Triforce@2x.png | Bin 0 -> 4176 bytes Data/Sys/Resources/Platform_Triforce@4x.png | Bin 0 -> 8404 bytes Source/Core/Core/Config/MainSettings.cpp | 1 + Source/Core/Core/Config/MainSettings.h | 1 + Source/Core/DiscIO/Enums.cpp | 3 ++- Source/Core/DiscIO/Enums.h | 1 + Source/Core/DiscIO/VolumeGC.cpp | 22 ++++++++++++++++-- Source/Core/DiscIO/VolumeGC.h | 2 ++ Source/Core/DiscIO/VolumeVerifier.cpp | 8 +++++++ Source/Core/DiscIO/VolumeVerifier.h | 1 + Source/Core/DolphinQt/Config/InfoWidget.cpp | 1 + .../Core/DolphinQt/GameList/GameListModel.cpp | 2 ++ Source/Core/DolphinQt/MenuBar.cpp | 1 + Source/Core/DolphinQt/Resources.cpp | 2 +- 15 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 Data/Sys/Resources/Platform_Triforce.png create mode 100644 Data/Sys/Resources/Platform_Triforce@2x.png create mode 100644 Data/Sys/Resources/Platform_Triforce@4x.png diff --git a/Data/Sys/Resources/Platform_Triforce.png b/Data/Sys/Resources/Platform_Triforce.png new file mode 100644 index 0000000000000000000000000000000000000000..e6a3b26b765709a41fe2efd8aa0d45d237d09e2b GIT binary patch literal 2396 zcmbVO2~-nj9v=<`AtK^8hD^s zSYfT!qgFtuLIo=x53Q?3wyV?@q_njtRvxxMkrt`aQee@Ya6P-v-M;Od-+bTi`~C0# zo82){;SP37>;M38h>TFivTx9Q+sL{?p%9!oxU4w6It7kZzC0t0 z{Zeq#7>0r&$Y3z=4Prj2PlbeXxf~LRAd!g2B6xHb!5~H+K`)|Q$RI3hods|nknIG6v8x^79$v%#R})J zR2s>UbQ<|zsOOe{BY^d-N;N0rxw>ezb0TOaER!{3#v#u|({Wi82E}4DnW0CquuN9X zk zhmYfGSSm&(LMf8MlVg4vkBy zwm3c8%M{y|ECK+l!ANCrTteZGZ$}rsz3GK(<^6Yax<@Da=xYt;H^=RD57`J;?GZn29li4KazEZv zZX18LD8H|1+Y$QW%`qK6U^LeGN$cqy=O;u>=5vRIsr2soi4O`)S9=bDg>|+?r#nL& z-E!PA(XzIouM>^6kH=l&$7MOzJ{zv#EnZoA%ZBudv4ujH&!AHUdEeI`EIeS_m;c4z zIl9`9Gd!;{mOvF=1U|CBcA~p3tYCi4Z>4j6kvL76N@ctC!xaZAFXnx_z!lvS-#~;U9I`OJV zI^FhXtmh|Pn`vH7>%S%oKA&`QH-Q#l@T2^eunx<#Bn;~x29eyfZy*kU=y;c^oF)g zTwd7IOpx7hT2>uU!+Zd++)A{zW$C zTNBM0+xL$v`*bHQj&%hB>0q6;-(QoU*VZh3d2n2GrSxMfpEn9nt50seTjxV0YsoS$ zXJX&Tnu^BNbw0w@>dPCxdF`rmvQycm@kYl-V7;@f!iKL-_X zkCS#(E+G>pe_ zx)Xk>T&wZ@Zd6-)XZPs~H8DE|w&YfQL^KWD*JXc)LSG>xF6!VDS)JO248U_PJbn1U<>ddCLZw|S5G|0gmm KN_i?IDgWP+yN^Hs literal 0 HcmV?d00001 diff --git a/Data/Sys/Resources/Platform_Triforce@2x.png b/Data/Sys/Resources/Platform_Triforce@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..3efae35bd5741a0924ef40687cf3437212174fa4 GIT binary patch literal 4176 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 literal 0 HcmV?d00001 diff --git a/Source/Core/Core/Config/MainSettings.cpp b/Source/Core/Core/Config/MainSettings.cpp index 37f2a6054e..7af0fd2766 100644 --- a/Source/Core/Core/Config/MainSettings.cpp +++ b/Source/Core/Core/Config/MainSettings.cpp @@ -437,6 +437,7 @@ const Info MAIN_GAMELIST_LIST_WAD{{System::Main, "GameList", "ListWad"}, t const Info MAIN_GAMELIST_LIST_ELF_DOL{{System::Main, "GameList", "ListElfDol"}, true}; const Info MAIN_GAMELIST_LIST_WII{{System::Main, "GameList", "ListWii"}, true}; const Info MAIN_GAMELIST_LIST_GC{{System::Main, "GameList", "ListGC"}, true}; +const Info MAIN_GAMELIST_LIST_TRI{{System::Main, "GameList", "ListTriforce"}, true}; const Info MAIN_GAMELIST_LIST_JPN{{System::Main, "GameList", "ListJap"}, true}; const Info MAIN_GAMELIST_LIST_PAL{{System::Main, "GameList", "ListPal"}, true}; const Info MAIN_GAMELIST_LIST_USA{{System::Main, "GameList", "ListUsa"}, true}; diff --git a/Source/Core/Core/Config/MainSettings.h b/Source/Core/Core/Config/MainSettings.h index 51aa7ec8aa..344263ba10 100644 --- a/Source/Core/Core/Config/MainSettings.h +++ b/Source/Core/Core/Config/MainSettings.h @@ -269,6 +269,7 @@ extern const Info MAIN_GAMELIST_LIST_WAD; extern const Info MAIN_GAMELIST_LIST_ELF_DOL; extern const Info MAIN_GAMELIST_LIST_WII; extern const Info MAIN_GAMELIST_LIST_GC; +extern const Info MAIN_GAMELIST_LIST_TRI; extern const Info MAIN_GAMELIST_LIST_JPN; extern const Info MAIN_GAMELIST_LIST_PAL; extern const Info MAIN_GAMELIST_LIST_USA; diff --git a/Source/Core/DiscIO/Enums.cpp b/Source/Core/DiscIO/Enums.cpp index 2d6f22d164..28487d346e 100644 --- a/Source/Core/DiscIO/Enums.cpp +++ b/Source/Core/DiscIO/Enums.cpp @@ -139,7 +139,8 @@ std::string GetName(Region region, bool translate) bool IsDisc(Platform volume_type) { - return volume_type == Platform::GameCubeDisc || volume_type == Platform::WiiDisc; + return volume_type == Platform::GameCubeDisc || volume_type == Platform::Triforce || + volume_type == Platform::WiiDisc; } bool IsWii(Platform volume_type) diff --git a/Source/Core/DiscIO/Enums.h b/Source/Core/DiscIO/Enums.h index 4881a8d980..9b5e274de9 100644 --- a/Source/Core/DiscIO/Enums.h +++ b/Source/Core/DiscIO/Enums.h @@ -15,6 +15,7 @@ namespace DiscIO enum class Platform { GameCubeDisc = 0, + Triforce, WiiDisc, WiiWAD, ELFOrDOL, diff --git a/Source/Core/DiscIO/VolumeGC.cpp b/Source/Core/DiscIO/VolumeGC.cpp index 8a95e0bb31..ebd005f158 100644 --- a/Source/Core/DiscIO/VolumeGC.cpp +++ b/Source/Core/DiscIO/VolumeGC.cpp @@ -29,7 +29,8 @@ namespace DiscIO { -VolumeGC::VolumeGC(std::unique_ptr reader) : m_reader(std::move(reader)) +VolumeGC::VolumeGC(std::unique_ptr reader) + : m_reader(std::move(reader)), m_is_triforce(false) { ASSERT(m_reader); @@ -39,6 +40,20 @@ VolumeGC::VolumeGC(std::unique_ptr reader) : m_reader(std::move(read }; m_converted_banner = [this] { return LoadBannerFile(); }; + + constexpr u32 BTID_MAGIC = 0x44495442; + auto tmp_fs = GetFileSystem(PARTITION_NONE); + if (tmp_fs) + { + std::unique_ptr file_info = tmp_fs->FindFileInfo("boot.id"); + if (!file_info) + return; + u32 triforce_magic; // "BTID" + const u64 file_size = ReadFile(*this, PARTITION_NONE, file_info.get(), + reinterpret_cast(&triforce_magic), sizeof(triforce_magic)); + if (file_size >= 4 && triforce_magic == BTID_MAGIC) + m_is_triforce = true; + } } VolumeGC::~VolumeGC() = default; @@ -139,7 +154,10 @@ const BlobReader& VolumeGC::GetBlobReader() const Platform VolumeGC::GetVolumeType() const { - return Platform::GameCubeDisc; + if (m_is_triforce) + return Platform::Triforce; + else + return Platform::GameCubeDisc; } bool VolumeGC::IsDatelDisc() const diff --git a/Source/Core/DiscIO/VolumeGC.h b/Source/Core/DiscIO/VolumeGC.h index d877bc7719..1c8297defb 100644 --- a/Source/Core/DiscIO/VolumeGC.h +++ b/Source/Core/DiscIO/VolumeGC.h @@ -103,6 +103,8 @@ private: Common::Lazy> m_file_system; std::unique_ptr m_reader; + + bool m_is_triforce; }; } // namespace DiscIO diff --git a/Source/Core/DiscIO/VolumeVerifier.cpp b/Source/Core/DiscIO/VolumeVerifier.cpp index 414e4ae3a1..bbe02e7d22 100644 --- a/Source/Core/DiscIO/VolumeVerifier.cpp +++ b/Source/Core/DiscIO/VolumeVerifier.cpp @@ -402,6 +402,7 @@ void VolumeVerifier::Start() m_is_tgc = m_volume.GetBlobType() == BlobType::TGC; m_is_datel = m_volume.IsDatelDisc(); + m_is_triforce = m_volume.GetVolumeType() == Platform::Triforce; m_is_not_retail = (m_volume.GetVolumeType() == Platform::WiiDisc && !m_volume.HasWiiHashes()) || IsDebugSigned(); @@ -1373,6 +1374,13 @@ void VolumeVerifier::Finish() return; } + if (m_is_triforce) + { + m_result.summary_text = + Common::GetStringT("Dolphin is currently unable to verify Triforce games."); + return; + } + if (m_result.redump.status == RedumpVerifier::Status::BadDump && highest_severity <= Severity::Low) { diff --git a/Source/Core/DiscIO/VolumeVerifier.h b/Source/Core/DiscIO/VolumeVerifier.h index 934e60b7b1..7a5c342e1b 100644 --- a/Source/Core/DiscIO/VolumeVerifier.h +++ b/Source/Core/DiscIO/VolumeVerifier.h @@ -165,6 +165,7 @@ private: Result m_result; bool m_is_tgc = false; bool m_is_datel = false; + bool m_is_triforce = false; bool m_is_not_retail = false; bool m_redump_verification; diff --git a/Source/Core/DolphinQt/Config/InfoWidget.cpp b/Source/Core/DolphinQt/Config/InfoWidget.cpp index a13b31ea34..1cddafcd0c 100644 --- a/Source/Core/DolphinQt/Config/InfoWidget.cpp +++ b/Source/Core/DolphinQt/Config/InfoWidget.cpp @@ -93,6 +93,7 @@ QGroupBox* InfoWidget::CreateGameDetails() const QString game_name = QString::fromStdString(m_game.GetInternalName()); bool is_disc_based = m_game.GetPlatform() == DiscIO::Platform::GameCubeDisc || + m_game.GetPlatform() == DiscIO::Platform::Triforce || m_game.GetPlatform() == DiscIO::Platform::WiiDisc; QLineEdit* internal_name = diff --git a/Source/Core/DolphinQt/GameList/GameListModel.cpp b/Source/Core/DolphinQt/GameList/GameListModel.cpp index c8c1d8b165..42a911ce49 100644 --- a/Source/Core/DolphinQt/GameList/GameListModel.cpp +++ b/Source/Core/DolphinQt/GameList/GameListModel.cpp @@ -303,6 +303,8 @@ bool GameListModel::ShouldDisplayGameListItem(int index) const { case DiscIO::Platform::GameCubeDisc: return Config::Get(Config::MAIN_GAMELIST_LIST_GC); + case DiscIO::Platform::Triforce: + return Config::Get(Config::MAIN_GAMELIST_LIST_TRI); case DiscIO::Platform::WiiDisc: return Config::Get(Config::MAIN_GAMELIST_LIST_WII); case DiscIO::Platform::WiiWAD: diff --git a/Source/Core/DolphinQt/MenuBar.cpp b/Source/Core/DolphinQt/MenuBar.cpp index 24c6cc2d04..a4e2b17c0d 100644 --- a/Source/Core/DolphinQt/MenuBar.cpp +++ b/Source/Core/DolphinQt/MenuBar.cpp @@ -726,6 +726,7 @@ void MenuBar::AddShowPlatformsMenu(QMenu* view_menu) static const QMap*> platform_map{ {tr("Show Wii"), &Config::MAIN_GAMELIST_LIST_WII}, {tr("Show GameCube"), &Config::MAIN_GAMELIST_LIST_GC}, + {tr("Show Triforce"), &Config::MAIN_GAMELIST_LIST_TRI}, {tr("Show WAD"), &Config::MAIN_GAMELIST_LIST_WAD}, {tr("Show ELF/DOL"), &Config::MAIN_GAMELIST_LIST_ELF_DOL}}; diff --git a/Source/Core/DolphinQt/Resources.cpp b/Source/Core/DolphinQt/Resources.cpp index 84fbcc8df8..015074142d 100644 --- a/Source/Core/DolphinQt/Resources.cpp +++ b/Source/Core/DolphinQt/Resources.cpp @@ -80,7 +80,7 @@ void Resources::Init() m_svg_supported = QImageReader::supportedImageFormats().contains("svg"); for (std::string_view platform : - {"Platform_Gamecube", "Platform_Wii", "Platform_Wad", "Platform_File"}) + {"Platform_Gamecube", "Platform_Triforce", "Platform_Wii", "Platform_Wad", "Platform_File"}) { m_platforms.append(GetResourceIcon(platform)); } From 8d94d25203b5b03d1fd9d6408b2aca3d71df1a14 Mon Sep 17 00:00:00 2001 From: Zopolis4 Date: Fri, 17 Dec 2021 18:56:48 +1100 Subject: [PATCH 3/7] Implement Triforce ID parsing --- Data/Sys/triforcetdb-en.txt | 10 +++++++ Source/Core/Core/ConfigManager.cpp | 27 ++++++++++++------ Source/Core/Core/ConfigManager.h | 5 +++- Source/Core/Core/TitleDatabase.cpp | 31 +++++++++++++++++++-- Source/Core/Core/TitleDatabase.h | 5 +++- Source/Core/DiscIO/Volume.h | 1 + Source/Core/DiscIO/VolumeGC.cpp | 17 +++++++++-- Source/Core/DiscIO/VolumeGC.h | 9 ++++++ Source/Core/DolphinQt/Config/InfoWidget.cpp | 4 +++ Source/Core/UICommon/GameFile.cpp | 5 +++- Source/Core/UICommon/GameFile.h | 2 ++ 11 files changed, 99 insertions(+), 17 deletions(-) create mode 100644 Data/Sys/triforcetdb-en.txt diff --git a/Data/Sys/triforcetdb-en.txt b/Data/Sys/triforcetdb-en.txt new file mode 100644 index 0000000000..a397bb0419 --- /dev/null +++ b/Data/Sys/triforcetdb-en.txt @@ -0,0 +1,10 @@ +TITLES = (type: Triforce language: EN version: 20210908) +S000 = Triforce Firmware Update For Compact Flash Box (4.01) +SBEY = Virtua Striker 2002 +SBFX = The Key Of Avalon +SBGG = F-Zero AX +SBHZ = Virtua Striker 4 (Asia) +SBJA = Virtua Striker 4 (Export) +SBJN = The Key Of Avalon 2.5: War of the Key +SBLK = Virtua Striker 4 Ver.2006 (Japan) +SBLL = Virtua Striker 4 Ver.2006 (Export) diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index 9101df907a..a480c7622d 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -126,6 +126,12 @@ const std::string SConfig::GetTitleDescription() const return m_title_description; } +std::string SConfig::GetTriforceID() const +{ + std::lock_guard lock(m_metadata_lock); + return m_triforce_id; +} + u64 SConfig::GetTitleID() const { std::lock_guard lock(m_metadata_lock); @@ -141,7 +147,7 @@ u16 SConfig::GetRevision() const void SConfig::ResetRunningGameMetadata() { std::lock_guard lock(m_metadata_lock); - SetRunningGameMetadata("00000000", "", 0, 0, DiscIO::Region::Unknown); + SetRunningGameMetadata("00000000", "", "", 0, 0, DiscIO::Region::Unknown); } void SConfig::SetRunningGameMetadata(const DiscIO::Volume& volume, @@ -150,14 +156,14 @@ void SConfig::SetRunningGameMetadata(const DiscIO::Volume& volume, std::lock_guard lock(m_metadata_lock); if (partition == volume.GetGamePartition()) { - SetRunningGameMetadata(volume.GetGameID(), volume.GetGameTDBID(), + SetRunningGameMetadata(volume.GetGameID(), volume.GetGameTDBID(), volume.GetTriforceID(), volume.GetTitleID().value_or(0), volume.GetRevision().value_or(0), volume.GetRegion()); } else { SetRunningGameMetadata(volume.GetGameID(partition), volume.GetGameTDBID(partition), - volume.GetTitleID(partition).value_or(0), + volume.GetTriforceID(), volume.GetTitleID(partition).value_or(0), volume.GetRevision(partition).value_or(0), volume.GetRegion()); } } @@ -175,25 +181,28 @@ void SConfig::SetRunningGameMetadata(const IOS::ES::TMDReader& tmd, DiscIO::Plat !Core::System::GetInstance().GetDVDInterface().UpdateRunningGameMetadata(tmd_title_id)) { // If not launching a disc game, just read everything from the TMD. - SetRunningGameMetadata(tmd.GetGameID(), tmd.GetGameTDBID(), tmd_title_id, tmd.GetTitleVersion(), - tmd.GetRegion()); + SetRunningGameMetadata(tmd.GetGameID(), tmd.GetGameTDBID(), "", tmd_title_id, + tmd.GetTitleVersion(), tmd.GetRegion()); } } void SConfig::SetRunningGameMetadata(const std::string& game_id) { std::lock_guard lock(m_metadata_lock); - SetRunningGameMetadata(game_id, "", 0, 0, DiscIO::Region::Unknown); + SetRunningGameMetadata(game_id, "", "", 0, 0, DiscIO::Region::Unknown); } void SConfig::SetRunningGameMetadata(const std::string& game_id, const std::string& gametdb_id, - u64 title_id, u16 revision, DiscIO::Region region) + std::string triforce_id, u64 title_id, u16 revision, + DiscIO::Region region) { std::lock_guard lock(m_metadata_lock); const bool was_changed = m_game_id != game_id || m_gametdb_id != gametdb_id || - m_title_id != title_id || m_revision != revision; + m_triforce_id != triforce_id || m_title_id != title_id || + m_revision != revision; m_game_id = game_id; m_gametdb_id = gametdb_id; + m_triforce_id = triforce_id; m_title_id = title_id; m_revision = revision; @@ -226,7 +235,7 @@ void SConfig::SetRunningGameMetadata(const std::string& game_id, const std::stri const Core::TitleDatabase title_database; auto& system = Core::System::GetInstance(); const DiscIO::Language language = GetLanguageAdjustedForRegion(system.IsWii(), region); - m_title_name = title_database.GetTitleName(m_gametdb_id, language); + m_title_name = title_database.GetTitleName(m_gametdb_id, m_triforce_id, language); m_title_description = title_database.Describe(m_gametdb_id, language); NOTICE_LOG_FMT(CORE, "Active title: {}", m_title_description); Host_TitleChanged(); diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h index 84be081b64..f441cd888b 100644 --- a/Source/Core/Core/ConfigManager.h +++ b/Source/Core/Core/ConfigManager.h @@ -67,6 +67,7 @@ struct SConfig const std::string GetGameTDBID() const; const std::string GetTitleName() const; const std::string GetTitleDescription() const; + std::string GetTriforceID() const; u64 GetTitleID() const; u16 GetRevision() const; void ResetRunningGameMetadata(); @@ -121,13 +122,15 @@ private: static void ReloadTextures(Core::System& system); void SetRunningGameMetadata(const std::string& game_id, const std::string& gametdb_id, - u64 title_id, u16 revision, DiscIO::Region region); + std::string triforce_id, u64 title_id, u16 revision, + DiscIO::Region region); static SConfig* m_Instance; mutable std::recursive_mutex m_metadata_lock; std::string m_game_id; std::string m_gametdb_id; + std::string m_triforce_id; std::string m_title_name; std::string m_title_description; u64 m_title_id; diff --git a/Source/Core/Core/TitleDatabase.cpp b/Source/Core/Core/TitleDatabase.cpp index 391a0dc044..4609cfddb1 100644 --- a/Source/Core/Core/TitleDatabase.cpp +++ b/Source/Core/Core/TitleDatabase.cpp @@ -56,6 +56,9 @@ void TitleDatabase::AddLazyMap(DiscIO::Language language, const std::string& lan m_title_maps[language] = [language_code]() -> Map { return LoadMap(File::GetSysDirectory() + "wiitdb-" + language_code + ".txt"); }; + m_triforce_title_maps[language] = [language_code]() -> Map { + return LoadMap(File::GetSysDirectory() + "triforcetdb-" + language_code + ".txt"); + }; } TitleDatabase::TitleDatabase() @@ -91,8 +94,32 @@ TitleDatabase::TitleDatabase() TitleDatabase::~TitleDatabase() = default; const std::string& TitleDatabase::GetTitleName(const std::string& gametdb_id, + const std::string& triforce_id, DiscIO::Language language) const { + if (triforce_id != "") + { + const Map& map = *m_triforce_title_maps.at(DiscIO::Language::English); + auto it = map.find(triforce_id); + if (it != map.end()) + return it->second; + + // This code has been commented out as there is currently only a english title map, and all + // Triforce games are detected as Japanese. + + // if (language != DiscIO::Language::English) + //{ + // const Map& english_triforce_map = *m_triforce_title_maps.at(DiscIO::Language::English); + // it = english_triforce_map.find(triforce_id); + // if (it != english_triforce_map.end()) + // return it->second; + //} + + // it = m_base_map.find(triforce_id); + // if (it != m_base_map.end()) + // return it->second; + } + auto it = m_user_title_map.find(gametdb_id); if (it != m_user_title_map.end()) return it->second; @@ -125,12 +152,12 @@ const std::string& TitleDatabase::GetChannelName(u64 title_id, DiscIO::Language const std::string id{ {static_cast((title_id >> 24) & 0xff), static_cast((title_id >> 16) & 0xff), static_cast((title_id >> 8) & 0xff), static_cast(title_id & 0xff)}}; - return GetTitleName(id, language); + return GetTitleName(id, "", language); } std::string TitleDatabase::Describe(const std::string& gametdb_id, DiscIO::Language language) const { - const std::string& title_name = GetTitleName(gametdb_id, language); + const std::string& title_name = GetTitleName(gametdb_id, "", language); if (title_name.empty()) return gametdb_id; return fmt::format("{} ({})", title_name, gametdb_id); diff --git a/Source/Core/Core/TitleDatabase.h b/Source/Core/Core/TitleDatabase.h index 2d26477bea..dff9a56dfe 100644 --- a/Source/Core/Core/TitleDatabase.h +++ b/Source/Core/Core/TitleDatabase.h @@ -25,7 +25,8 @@ public: // Get a user friendly title name for a GameTDB ID. // This falls back to returning an empty string if none could be found. - const std::string& GetTitleName(const std::string& gametdb_id, DiscIO::Language language) const; + const std::string& GetTitleName(const std::string& gametdb_id, const std::string& triforce_id, + DiscIO::Language language) const; // Same as above, but takes a title ID instead of a GameTDB ID, and only works for channels. const std::string& GetChannelName(u64 title_id, DiscIO::Language language) const; @@ -38,6 +39,8 @@ private: std::unordered_map>> m_title_maps; + std::unordered_map>> + m_triforce_title_maps; std::unordered_map m_base_map; std::unordered_map m_user_title_map; }; diff --git a/Source/Core/DiscIO/Volume.h b/Source/Core/DiscIO/Volume.h index 838ae28984..a7273b0f0e 100644 --- a/Source/Core/DiscIO/Volume.h +++ b/Source/Core/DiscIO/Volume.h @@ -96,6 +96,7 @@ public: } virtual std::string GetGameID(const Partition& partition = PARTITION_NONE) const = 0; virtual std::string GetGameTDBID(const Partition& partition = PARTITION_NONE) const = 0; + virtual std::string GetTriforceID() const { return ""; } virtual std::string GetMakerID(const Partition& partition = PARTITION_NONE) const = 0; virtual std::optional GetRevision(const Partition& partition = PARTITION_NONE) const = 0; virtual std::string GetInternalName(const Partition& partition = PARTITION_NONE) const = 0; diff --git a/Source/Core/DiscIO/VolumeGC.cpp b/Source/Core/DiscIO/VolumeGC.cpp index ebd005f158..8cc255570a 100644 --- a/Source/Core/DiscIO/VolumeGC.cpp +++ b/Source/Core/DiscIO/VolumeGC.cpp @@ -48,11 +48,14 @@ VolumeGC::VolumeGC(std::unique_ptr reader) std::unique_ptr file_info = tmp_fs->FindFileInfo("boot.id"); if (!file_info) return; - u32 triforce_magic; // "BTID" + BootID triforce_header; const u64 file_size = ReadFile(*this, PARTITION_NONE, file_info.get(), - reinterpret_cast(&triforce_magic), sizeof(triforce_magic)); - if (file_size >= 4 && triforce_magic == BTID_MAGIC) + reinterpret_cast(&triforce_header), sizeof(BootID)); + if (file_size >= 4 && triforce_header.magic == BTID_MAGIC) + { m_is_triforce = true; + m_triforce_id = triforce_header.id; + } } } @@ -90,6 +93,14 @@ std::string VolumeGC::GetGameTDBID(const Partition& partition) const return GetGameID(partition); } +std::string VolumeGC::GetTriforceID() const +{ + if (m_is_triforce) + return (std::string(m_triforce_id.data(), m_triforce_id.size())); + else + return ""; +} + Region VolumeGC::GetRegion() const { return RegionCodeToRegion(m_reader->ReadSwapped(0x458)); diff --git a/Source/Core/DiscIO/VolumeGC.h b/Source/Core/DiscIO/VolumeGC.h index 1c8297defb..5cf4ea0eed 100644 --- a/Source/Core/DiscIO/VolumeGC.h +++ b/Source/Core/DiscIO/VolumeGC.h @@ -34,6 +34,7 @@ public: const Partition& partition = PARTITION_NONE) const override; const FileSystem* GetFileSystem(const Partition& partition = PARTITION_NONE) const override; std::string GetGameTDBID(const Partition& partition = PARTITION_NONE) const override; + std::string GetTriforceID() const override; std::map GetShortNames() const override; std::map GetLongNames() const override; std::map GetShortMakers() const override; @@ -76,6 +77,13 @@ private: // (only one for BNR1 type) }; + struct BootID + { + u32 magic; // "BTID" + u32 padding[11]; + std::array id; + }; + struct ConvertedGCBanner { ConvertedGCBanner(); @@ -105,6 +113,7 @@ private: std::unique_ptr m_reader; bool m_is_triforce; + std::array m_triforce_id; }; } // namespace DiscIO diff --git a/Source/Core/DolphinQt/Config/InfoWidget.cpp b/Source/Core/DolphinQt/Config/InfoWidget.cpp index 1cddafcd0c..6a41b7de12 100644 --- a/Source/Core/DolphinQt/Config/InfoWidget.cpp +++ b/Source/Core/DolphinQt/Config/InfoWidget.cpp @@ -106,11 +106,13 @@ QGroupBox* InfoWidget::CreateGameDetails() .arg(m_game.GetRevision())); QString game_id_string = QString::fromStdString(m_game.GetGameID()); + QString triforce_id_string = QString::fromStdString(m_game.GetTriforceID()); if (const u64 title_id = m_game.GetTitleID()) game_id_string += QStringLiteral(" (%1)").arg(title_id, 16, 16, QLatin1Char('0')); QLineEdit* game_id = CreateValueDisplay(game_id_string); + QLineEdit* triforce_id = CreateValueDisplay(triforce_id_string); QLineEdit* country = CreateValueDisplay(DiscIO::GetName(m_game.GetCountry(), true)); @@ -121,6 +123,8 @@ QGroupBox* InfoWidget::CreateGameDetails() m_game.GetMakerID() + ")"); layout->addRow(tr("Name:"), internal_name); + if (m_game.GetPlatform() == DiscIO::Platform::Triforce) + layout->addRow(tr("Triforce ID:"), triforce_id); layout->addRow(tr("Game ID:"), game_id); layout->addRow(tr("Country:"), country); layout->addRow(tr("Maker:"), maker); diff --git a/Source/Core/UICommon/GameFile.cpp b/Source/Core/UICommon/GameFile.cpp index b35349b8b0..66fb5a3a57 100644 --- a/Source/Core/UICommon/GameFile.cpp +++ b/Source/Core/UICommon/GameFile.cpp @@ -131,6 +131,7 @@ GameFile::GameFile(std::string path) : m_file_path(std::move(path)) m_internal_name = volume->GetInternalName(); m_game_id = volume->GetGameID(); m_gametdb_id = volume->GetGameTDBID(); + m_triforce_id = volume->GetTriforceID(); m_title_id = volume->GetTitleID().value_or(0); m_maker_id = volume->GetMakerID(); m_revision = volume->GetRevision().value_or(0); @@ -311,6 +312,7 @@ void GameFile::DoState(PointerWrap& p) p.Do(m_internal_name); p.Do(m_game_id); p.Do(m_gametdb_id); + p.Do(m_triforce_id); p.Do(m_title_id); p.Do(m_maker_id); @@ -499,7 +501,8 @@ const std::string& GameFile::GetName(const Core::TitleDatabase& title_database) if (IsModDescriptor()) return GetName(Variant::LongAndPossiblyCustom); - const std::string& database_name = title_database.GetTitleName(m_gametdb_id, GetConfigLanguage()); + const std::string& database_name = + title_database.GetTitleName(m_gametdb_id, m_triforce_id, GetConfigLanguage()); return database_name.empty() ? GetName(Variant::LongAndPossiblyCustom) : database_name; } diff --git a/Source/Core/UICommon/GameFile.h b/Source/Core/UICommon/GameFile.h index e43950143b..f015fa9725 100644 --- a/Source/Core/UICommon/GameFile.h +++ b/Source/Core/UICommon/GameFile.h @@ -76,6 +76,7 @@ public: const std::string& GetInternalName() const { return m_internal_name; } const std::string& GetGameID() const { return m_game_id; } const std::string& GetGameTDBID() const { return m_gametdb_id; } + std::string GetTriforceID() const { return m_triforce_id; } u64 GetTitleID() const { return m_title_id; } const std::string& GetMakerID() const { return m_maker_id; } u16 GetRevision() const { return m_revision; } @@ -159,6 +160,7 @@ private: std::string m_internal_name; std::string m_game_id; std::string m_gametdb_id; + std::string m_triforce_id; u64 m_title_id{}; std::string m_maker_id; From 2baa09d5b417e08e5092dedb85bc055c0fddd8be Mon Sep 17 00:00:00 2001 From: Zopolis4 Date: Mon, 23 Aug 2021 20:41:22 +1000 Subject: [PATCH 4/7] Implement endian swapping and lazy decryption of Triforce DI commands --- Source/Core/Core/Boot/Boot_BS2Emu.cpp | 7 +++++++ Source/Core/Core/HW/DVD/DVDInterface.cpp | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/Source/Core/Core/Boot/Boot_BS2Emu.cpp b/Source/Core/Core/Boot/Boot_BS2Emu.cpp index baf2079677..884a11bd87 100644 --- a/Source/Core/Core/Boot/Boot_BS2Emu.cpp +++ b/Source/Core/Core/Boot/Boot_BS2Emu.cpp @@ -227,6 +227,13 @@ bool CBoot::RunApploader(Core::System& system, const Core::CPUThreadGuard& guard ppc_state.pc = ppc_state.gpr[3]; branch_watch.SetRecordingActive(guard, resume_branch_watch); + // Blank out session key (https://debugmo.de/2008/05/part-2-dumping-the-media-board/) + if (volume.GetVolumeType() == DiscIO::Platform::Triforce) + { + auto& memory = system.GetMemory(); + + memory.Memset(0, 0, 12); + } return true; } diff --git a/Source/Core/Core/HW/DVD/DVDInterface.cpp b/Source/Core/Core/HW/DVD/DVDInterface.cpp index babb500902..f6e7954b02 100644 --- a/Source/Core/Core/HW/DVD/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVD/DVDInterface.cpp @@ -753,6 +753,15 @@ void DVDInterface::ExecuteCommand(ReplyType reply_type) DIInterruptType interrupt_type = DIInterruptType::TCINT; bool command_handled_by_thread = false; + // Swaps endian of Triforce DI commands, and zeroes out random bytes to prevent unknown read + // subcommand errors + auto& dvd_thread = m_system.GetDVDThread(); + if (dvd_thread.GetDiscType() == DiscIO::Platform::Triforce) + { + // TODO(C++23): Use std::byteswap and a bitwise AND for increased clarity + m_DICMDBUF[0] <<= 24; + } + // DVDLowRequestError needs access to the error code set by the previous command if (static_cast(m_DICMDBUF[0] >> 24) != DICommand::RequestError) SetDriveError(DriveError::None); From 660232a12c03698c9df3114046da3a45fdd9806f Mon Sep 17 00:00:00 2001 From: Zopolis4 Date: Sun, 7 Nov 2021 03:19:59 +1100 Subject: [PATCH 5/7] Preliminary implementation of the Triforce Baseboard --- Source/Core/Core/CMakeLists.txt | 2 + Source/Core/Core/ConfigManager.cpp | 2 + Source/Core/Core/HW/EXI/EXI.cpp | 13 +++++ Source/Core/Core/HW/EXI/EXI.h | 1 + Source/Core/Core/HW/EXI/EXI_Device.cpp | 6 +- Source/Core/Core/HW/EXI/EXI_Device.h | 6 +- .../Core/Core/HW/EXI/EXI_DeviceBaseboard.cpp | 57 +++++++++++++++++++ Source/Core/Core/HW/EXI/EXI_DeviceBaseboard.h | 27 +++++++++ Source/Core/Core/State.cpp | 2 +- Source/Core/Core/System.h | 3 + Source/Core/DolphinLib.props | 2 + 11 files changed, 115 insertions(+), 6 deletions(-) create mode 100644 Source/Core/Core/HW/EXI/EXI_DeviceBaseboard.cpp create mode 100644 Source/Core/Core/HW/EXI/EXI_DeviceBaseboard.h diff --git a/Source/Core/Core/CMakeLists.txt b/Source/Core/Core/CMakeLists.txt index b4437747e8..09b69a620e 100644 --- a/Source/Core/Core/CMakeLists.txt +++ b/Source/Core/Core/CMakeLists.txt @@ -203,6 +203,8 @@ add_library(core HW/EXI/EXI_DeviceAD16.h HW/EXI/EXI_DeviceAGP.cpp HW/EXI/EXI_DeviceAGP.h + HW/EXI/EXI_DeviceBaseboard.cpp + HW/EXI/EXI_DeviceBaseboard.h HW/EXI/EXI_DeviceDummy.cpp HW/EXI/EXI_DeviceDummy.h HW/EXI/EXI_DeviceEthernet.cpp diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index a480c7622d..e005e78341 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -307,6 +307,7 @@ void SConfig::LoadDefaults() auto& system = Core::System::GetInstance(); system.SetIsWii(false); + system.SetIsTriforce(false); ResetRunningGameMetadata(); } @@ -330,6 +331,7 @@ struct SetGameMetadata { *region = disc.volume->GetRegion(); system.SetIsWii(disc.volume->GetVolumeType() == DiscIO::Platform::WiiDisc); + system.SetIsTriforce(disc.volume->GetVolumeType() == DiscIO::Platform::Triforce); config->m_disc_booted_from_game_list = true; config->SetRunningGameMetadata(*disc.volume, disc.volume->GetGamePartition()); return true; diff --git a/Source/Core/Core/HW/EXI/EXI.cpp b/Source/Core/Core/HW/EXI/EXI.cpp index 303191c574..d676dc4845 100644 --- a/Source/Core/Core/HW/EXI/EXI.cpp +++ b/Source/Core/Core/HW/EXI/EXI.cpp @@ -66,6 +66,18 @@ void ExpansionInterfaceManager::AddMemoryCard(Slot slot) m_channels[SlotToEXIChannel(slot)]->AddDevice(memorycard_device, SlotToEXIDevice(slot)); } +void ExpansionInterfaceManager::AddSP1Device() +{ + EXIDeviceType sp1_device = EXIDeviceType::Baseboard; + auto& system = Core::System::GetInstance(); + if (system.IsTriforce()) + { + sp1_device = Config::Get(Config::MAIN_SERIAL_PORT_1); + } + + m_channels[0]->AddDevice(sp1_device, SlotToEXIDevice(Slot::SP1)); +} + u8 SlotToEXIChannel(Slot slot) { switch (slot) @@ -145,6 +157,7 @@ void ExpansionInterfaceManager::Init(const Sram* override_sram) AddMemoryCard(slot); m_channels[0]->AddDevice(EXIDeviceType::MaskROM, 1); + AddSP1Device(); m_channels[SlotToEXIChannel(Slot::SP1)]->AddDevice(Config::Get(Config::MAIN_SERIAL_PORT_1), SlotToEXIDevice(Slot::SP1)); m_channels[SlotToEXIChannel(Slot::SP2)]->AddDevice(Config::Get(Config::MAIN_SERIAL_PORT_2), diff --git a/Source/Core/Core/HW/EXI/EXI.h b/Source/Core/Core/HW/EXI/EXI.h index 7ded905b98..f0ea5fbfb5 100644 --- a/Source/Core/Core/HW/EXI/EXI.h +++ b/Source/Core/Core/HW/EXI/EXI.h @@ -89,6 +89,7 @@ public: private: void AddMemoryCard(Slot slot); + void AddSP1Device(); static void ChangeDeviceCallback(Core::System& system, u64 userdata, s64 cycles_late); static void UpdateInterruptsCallback(Core::System& system, u64 userdata, s64 cycles_late); diff --git a/Source/Core/Core/HW/EXI/EXI_Device.cpp b/Source/Core/Core/HW/EXI/EXI_Device.cpp index 6c416d5387..ac92c7b723 100644 --- a/Source/Core/Core/HW/EXI/EXI_Device.cpp +++ b/Source/Core/Core/HW/EXI/EXI_Device.cpp @@ -9,6 +9,7 @@ #include "Common/MsgHandler.h" #include "Core/HW/EXI/EXI_DeviceAD16.h" #include "Core/HW/EXI/EXI_DeviceAGP.h" +#include "Core/HW/EXI/EXI_DeviceBaseboard.h" #include "Core/HW/EXI/EXI_DeviceDummy.h" #include "Core/HW/EXI/EXI_DeviceEthernet.h" #include "Core/HW/EXI/EXI_DeviceGecko.h" @@ -171,7 +172,10 @@ std::unique_ptr EXIDevice_Create(Core::System& system, const EXIDevi result = std::make_unique(system, slot); break; - case EXIDeviceType::AMBaseboard: + case EXIDeviceType::Baseboard: + result = std::make_unique(system); + break; + case EXIDeviceType::None: default: result = std::make_unique(system); diff --git a/Source/Core/Core/HW/EXI/EXI_Device.h b/Source/Core/Core/HW/EXI/EXI_Device.h index db74306df0..25263af425 100644 --- a/Source/Core/Core/HW/EXI/EXI_Device.h +++ b/Source/Core/Core/HW/EXI/EXI_Device.h @@ -30,9 +30,7 @@ enum class EXIDeviceType : int AD16, Microphone, Ethernet, - // Was used for Triforce in the past, but the implementation is no longer in Dolphin. - // It's kept here so that values below will stay constant. - AMBaseboard, + Baseboard, Gecko, // Only used when creating a device by EXIDevice_Create. // Converted to MemoryCard internally. @@ -98,7 +96,7 @@ struct fmt::formatter _trans("AD16"), _trans("Microphone"), _trans("Broadband Adapter (TAP)"), - _trans("Triforce AM Baseboard"), + _trans("Triforce Baseboard"), _trans("USB Gecko"), _trans("GCI Folder"), _trans("Advance Game Port"), diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceBaseboard.cpp b/Source/Core/Core/HW/EXI/EXI_DeviceBaseboard.cpp new file mode 100644 index 0000000000..a9200ac85a --- /dev/null +++ b/Source/Core/Core/HW/EXI/EXI_DeviceBaseboard.cpp @@ -0,0 +1,57 @@ +// Copyright 2013 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "Core/HW/EXI/EXI_DeviceBaseboard.h" + +#include "Common/Assert.h" +#include "Common/ChunkFile.h" +#include "Common/CommonTypes.h" +#include "Common/Logging/Log.h" + +namespace ExpansionInterface +{ +CEXIBaseboard::CEXIBaseboard(Core::System& system) : IEXIDevice(system) +{ +} + +void CEXIBaseboard::SetCS(int cs) +{ + if (cs) + m_position = 0; +} + +bool CEXIBaseboard::IsPresent() const +{ + return true; +} + +void CEXIBaseboard::TransferByte(u8& byte) +{ + if (m_position == 0) + { + m_command = byte; + } + else + { + switch (m_command) + { + case 0x00: + { + static constexpr std::array ID = {0x06, 0x04, 0x10, 0x00}; + byte = ID[(m_position - 2) & 3]; + break; + } + default: + ERROR_LOG_FMT(EXPANSIONINTERFACE, "EXI BASEBOARD: Unhandled command {:#x} {:#x}", m_command, + m_position); + } + } + m_position++; +} + +void CEXIBaseboard::DoState(PointerWrap& p) +{ + p.Do(m_position); + p.Do(m_command); +} +} // namespace ExpansionInterface diff --git a/Source/Core/Core/HW/EXI/EXI_DeviceBaseboard.h b/Source/Core/Core/HW/EXI/EXI_DeviceBaseboard.h new file mode 100644 index 0000000000..4c534428c9 --- /dev/null +++ b/Source/Core/Core/HW/EXI/EXI_DeviceBaseboard.h @@ -0,0 +1,27 @@ +// Copyright 2013 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "Core/HW/EXI/EXI_Device.h" + +class PointerWrap; + +namespace ExpansionInterface +{ +class CEXIBaseboard : public IEXIDevice +{ +public: + CEXIBaseboard(Core::System& system); + void SetCS(int cs) override; + bool IsPresent() const override; + void DoState(PointerWrap& p) override; + +private: + // STATE_TO_SAVE + u32 m_position = 0; + u32 m_command = 0; + + void TransferByte(u8& byte) override; +}; +} // namespace ExpansionInterface diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index 44465b3f42..9620cfccd4 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -99,7 +99,7 @@ static size_t s_state_writes_in_queue; static std::condition_variable s_state_write_queue_is_empty; // Don't forget to increase this after doing changes on the savestate system -constexpr u32 STATE_VERSION = 172; // Last changed in PR 13385 +constexpr u32 STATE_VERSION = 173; // Last changed in PR 10084 // Increase this if the StateExtendedHeader definition changes constexpr u32 EXTENDED_HEADER_VERSION = 1; // Last changed in PR 12217 diff --git a/Source/Core/Core/System.h b/Source/Core/Core/System.h index 9ec8391ff0..0ab86e658d 100644 --- a/Source/Core/Core/System.h +++ b/Source/Core/Core/System.h @@ -141,10 +141,12 @@ public: bool IsMMUMode() const { return m_mmu_enabled; } bool IsPauseOnPanicMode() const { return m_pause_on_panic_enabled; } bool IsMIOS() const { return m_is_mios; } + bool IsTriforce() const { return m_is_triforce; } bool IsWii() const { return m_is_wii; } bool IsBranchWatchIgnoreApploader() { return m_branch_watch_ignore_apploader; } void SetIsMIOS(bool is_mios) { m_is_mios = is_mios; } + void SetIsTriforce(bool is_triforce) { m_is_triforce = is_triforce; } void SetIsWii(bool is_wii) { m_is_wii = is_wii; } void SetIsBranchWatchIgnoreApploader(bool enable) { m_branch_watch_ignore_apploader = enable; } @@ -205,6 +207,7 @@ private: bool m_mmu_enabled = false; bool m_pause_on_panic_enabled = false; bool m_is_mios = false; + bool m_is_triforce = false; bool m_is_wii = false; bool m_branch_watch_ignore_apploader = false; }; diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index 388367afd1..4c7764202d 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -281,6 +281,7 @@ + @@ -948,6 +949,7 @@ + From 2238967d93007a9ccff49fec3a9d9f0e6aa000cc Mon Sep 17 00:00:00 2001 From: Zopolis4 Date: Sun, 22 Jan 2023 21:02:05 +1100 Subject: [PATCH 6/7] Add Triforce IPL hash --- Source/Core/Core/Boot/Boot.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp index 4e08ccfd12..e95984f122 100644 --- a/Source/Core/Core/Boot/Boot.cpp +++ b/Source/Core/Core/Boot/Boot.cpp @@ -407,6 +407,7 @@ bool CBoot::Load_BS2(Core::System& system, const std::string& boot_rom_filename) constexpr u32 PAL_v1_0 = 0x4F319F43; // DOL-101(EUR) (PAL Revision 1.2) constexpr u32 PAL_v1_2 = 0xAD1B7F16; + constexpr u32 Triforce = 0xD1883221; // The Triforce's special IPL // Load the IPL ROM dump, limited to 2MiB which is the size of the official IPLs. constexpr size_t max_ipl_size = 2 * 1024 * 1024; @@ -424,6 +425,7 @@ bool CBoot::Load_BS2(Core::System& system, const std::string& boot_rom_filename) const u32 ipl_hash = Common::ComputeCRC32(data.data(), data.size()); bool known_ipl = false; bool pal_ipl = false; + bool triforce_ipl = false; switch (ipl_hash) { case NTSC_v1_0: @@ -438,6 +440,9 @@ bool CBoot::Load_BS2(Core::System& system, const std::string& boot_rom_filename) pal_ipl = true; known_ipl = true; break; + case Triforce: + known_ipl = true; + triforce_ipl = true; default: PanicAlertFmtT("The IPL file is not a known good dump. (CRC32: {0:x})", ipl_hash); break; From 89fdc0b9e0db9b65b7ba81b8ee33114415e8666c Mon Sep 17 00:00:00 2001 From: Zopolis4 Date: Tue, 28 Sep 2021 10:48:24 +1000 Subject: [PATCH 7/7] Fix Triforce GameINIs --- Data/Sys/ApprovedInis.json | 4 ---- Data/Sys/GameSettings/GVS.ini | 7 ++++++- Data/Sys/GameSettings/GVS46E.ini | 18 ------------------ Data/Sys/GameSettings/GVS46J.ini | 18 ------------------ Data/Sys/GameSettings/RELJAB.ini | 18 ------------------ Source/Core/Core/AchievementManager.h | 4 ++-- 6 files changed, 8 insertions(+), 61 deletions(-) delete mode 100644 Data/Sys/GameSettings/GVS46E.ini delete mode 100644 Data/Sys/GameSettings/GVS46J.ini delete mode 100644 Data/Sys/GameSettings/RELJAB.ini diff --git a/Data/Sys/ApprovedInis.json b/Data/Sys/ApprovedInis.json index 9d3b37c8d9..a73ed032f0 100644 --- a/Data/Sys/ApprovedInis.json +++ b/Data/Sys/ApprovedInis.json @@ -932,10 +932,6 @@ "title": "Region Select", "AD12237401ABE9FE4A545AADB5C5AE10355E2076": "RSAPatch" }, - "RELJAB": { - "title": "SegaBoot", - "130F3594CAB57B85616F95C7126F4748AAC5867D": "DI Seed Blanker" - }, "RGQE70": { "title": "Ghostbusters", "5F4CF8D4DA19A0FF74FF9EB925AC0236069BFD59": "crashfix" diff --git a/Data/Sys/GameSettings/GVS.ini b/Data/Sys/GameSettings/GVS.ini index 780267fa56..90641b1723 100644 --- a/Data/Sys/GameSettings/GVS.ini +++ b/Data/Sys/GameSettings/GVS.ini @@ -1,4 +1,5 @@ -# GVSE8P, GVSP8P - Virtua Striker 3 ver. 2002 +# GVSP8P, GVSE8P, GVSJ8P - Virtua Striker 2002 (GC) +# GVSJ8P - Virtua Striker 2002 (Triforce), Virtua Striker 4, Virtua Striker 4 ver. 2006 [Core] # Values set here will override the main Dolphin settings. @@ -10,3 +11,7 @@ FPRF = True [ActionReplay] # Add action replay cheats here. +[Video] +# Add memory patches to be applied every frame here. + +[Video_Settings] diff --git a/Data/Sys/GameSettings/GVS46E.ini b/Data/Sys/GameSettings/GVS46E.ini deleted file mode 100644 index 40061416f8..0000000000 --- a/Data/Sys/GameSettings/GVS46E.ini +++ /dev/null @@ -1,18 +0,0 @@ -# GVS46E, GVS46J - Virtua Striker 4 ver. 2006 -# Because Triforce games have weird IDs, properties are inherited from GVS.ini (Virtua Striker 3 ver. 2002)! - -[Core] -# Values set here will override the main Dolphin settings. -FPRF = True - -[OnFrame] -# Add memory patches to be applied every frame here. - -[ActionReplay] -# Add action replay cheats here. - -[Video] -# Add memory patches to be applied every frame here. - -[Video_Settings] - diff --git a/Data/Sys/GameSettings/GVS46J.ini b/Data/Sys/GameSettings/GVS46J.ini deleted file mode 100644 index 40061416f8..0000000000 --- a/Data/Sys/GameSettings/GVS46J.ini +++ /dev/null @@ -1,18 +0,0 @@ -# GVS46E, GVS46J - Virtua Striker 4 ver. 2006 -# Because Triforce games have weird IDs, properties are inherited from GVS.ini (Virtua Striker 3 ver. 2002)! - -[Core] -# Values set here will override the main Dolphin settings. -FPRF = True - -[OnFrame] -# Add memory patches to be applied every frame here. - -[ActionReplay] -# Add action replay cheats here. - -[Video] -# Add memory patches to be applied every frame here. - -[Video_Settings] - diff --git a/Data/Sys/GameSettings/RELJAB.ini b/Data/Sys/GameSettings/RELJAB.ini deleted file mode 100644 index 872c654b6e..0000000000 --- a/Data/Sys/GameSettings/RELJAB.ini +++ /dev/null @@ -1,18 +0,0 @@ -# RELJAB - SegaBoot - -[Core] -# Values set here will override the main Dolphin settings. - -[OnFrame] -# Add memory patches to be applied every frame here. -$DI Seed Blanker -0x80000000:dword:0x00000000 -0x80000004:dword:0x00000000 -0x80000008:dword:0x00000000 - -[Patches_RetroAchievements_Verified] -$DI Seed Blanker - -[ActionReplay] -# Add action replay cheats here. - diff --git a/Source/Core/Core/AchievementManager.h b/Source/Core/Core/AchievementManager.h index f46b7e9da3..dfa6bb535e 100644 --- a/Source/Core/Core/AchievementManager.h +++ b/Source/Core/Core/AchievementManager.h @@ -80,8 +80,8 @@ public: static constexpr std::string_view BLUE = "#0B71C1"; static constexpr std::string_view APPROVED_LIST_FILENAME = "ApprovedInis.json"; static const inline Common::SHA1::Digest APPROVED_LIST_HASH = { - 0x4F, 0x45, 0xB7, 0xA3, 0xC4, 0x6E, 0xAF, 0x80, 0x58, 0xA5, - 0x53, 0x99, 0xF8, 0x05, 0xC3, 0x83, 0x22, 0xA4, 0x5F, 0x65}; + 0xE1, 0x29, 0xD1, 0x33, 0x4D, 0xF2, 0xF8, 0xA8, 0x4E, 0xCA, + 0xF6, 0x87, 0xE6, 0xEC, 0xEC, 0xB3, 0x18, 0x69, 0x34, 0x45}; struct LeaderboardEntry {