Added Triforce support
This commit is contained in:
@@ -42,6 +42,7 @@ static constexpr std::array s_gc_types = {
|
||||
#endif
|
||||
SIDeviceName{SerialInterface::SIDEVICE_GC_GBA, _trans("GBA (TCP)")},
|
||||
SIDeviceName{SerialInterface::SIDEVICE_GC_KEYBOARD, _trans("Keyboard Controller")},
|
||||
SIDeviceName{SerialInterface::SIDEVICE_AM_BASEBOARD, _trans("Triforce Baseboard")},
|
||||
};
|
||||
|
||||
static std::optional<int> ToGCMenuIndex(const SerialInterface::SIDevices sidevice)
|
||||
@@ -132,6 +133,7 @@ void GamecubeControllersWidget::OnGCPadConfigure(size_t index)
|
||||
case SerialInterface::SIDEVICE_NONE:
|
||||
case SerialInterface::SIDEVICE_GC_GBA:
|
||||
return;
|
||||
case SerialInterface::SIDEVICE_AM_BASEBOARD:
|
||||
case SerialInterface::SIDEVICE_GC_CONTROLLER:
|
||||
type = MappingWindow::Type::MAPPING_GCPAD;
|
||||
break;
|
||||
|
||||
@@ -122,12 +122,6 @@ QGroupBox* InfoWidget::CreateGameDetails()
|
||||
m_game.GetMakerID() + ")");
|
||||
|
||||
layout->addRow(tr("Name:"), internal_name);
|
||||
if (m_game.GetPlatform() == DiscIO::Platform::Triforce)
|
||||
{
|
||||
const auto triforce_id_string = QString::fromStdString(m_game.GetTriforceID());
|
||||
auto* const triforce_id = CreateValueDisplay(triforce_id_string);
|
||||
layout->addRow(tr("Triforce ID:"), triforce_id);
|
||||
}
|
||||
layout->addRow(tr("Game ID:"), game_id);
|
||||
layout->addRow(tr("Country:"), country);
|
||||
layout->addRow(tr("Maker:"), maker);
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
|
||||
#include "Core/HW/GCPad.h"
|
||||
#include "Core/HW/GCPadEmu.h"
|
||||
#include "Core/HW/SI/SI.h"
|
||||
#include "Core/HW/SI/SI_DeviceAMBaseboard.h"
|
||||
|
||||
#include "Core/Config/MainSettings.h"
|
||||
|
||||
#include "InputCommon/InputConfig.h"
|
||||
|
||||
@@ -22,8 +26,15 @@ void GCPadEmu::CreateMainLayout()
|
||||
|
||||
layout->addWidget(CreateGroupBox(tr("Buttons"), Pad::GetGroup(GetPort(), PadGroup::Buttons)), 0,
|
||||
0);
|
||||
layout->addWidget(CreateGroupBox(tr("D-Pad"), Pad::GetGroup(GetPort(), PadGroup::DPad)), 1, 0, -1,
|
||||
1);
|
||||
layout->addWidget(CreateGroupBox(tr("D-Pad"), Pad::GetGroup(GetPort(), PadGroup::DPad)), 1, 0);
|
||||
|
||||
if (Config::Get(Config::GetInfoForSIDevice(0)) ==
|
||||
SerialInterface::SIDevices::SIDEVICE_AM_BASEBOARD)
|
||||
{
|
||||
layout->addWidget(CreateGroupBox(tr("Triforce"), Pad::GetGroup(GetPort(), PadGroup::Triforce)),
|
||||
2, 0);
|
||||
}
|
||||
|
||||
layout->addWidget(
|
||||
CreateGroupBox(tr("Control Stick"), Pad::GetGroup(GetPort(), PadGroup::MainStick)), 0, 1, -1,
|
||||
1);
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
#include "Common/IniFile.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
#include "Core/HW/SI/SI.h"
|
||||
#include "Core/HW/SI/SI_DeviceAMBaseboard.h"
|
||||
|
||||
#include "DolphinQt/Config/Mapping/FreeLookGeneral.h"
|
||||
#include "DolphinQt/Config/Mapping/FreeLookRotation.h"
|
||||
#include "DolphinQt/Config/Mapping/GBAPadEmu.h"
|
||||
@@ -458,8 +461,17 @@ void MappingWindow::SetMappingType(MappingWindow::Type type)
|
||||
case Type::MAPPING_GC_DANCEMAT:
|
||||
case Type::MAPPING_GCPAD:
|
||||
widget = new GCPadEmu(this);
|
||||
setWindowTitle(tr("GameCube Controller at Port %1").arg(GetPort() + 1));
|
||||
AddWidget(tr("GameCube Controller"), widget);
|
||||
if (Config::Get(Config::GetInfoForSIDevice(GetPort())) ==
|
||||
SerialInterface::SIDevices::SIDEVICE_AM_BASEBOARD)
|
||||
{
|
||||
setWindowTitle(tr("Triforce Baseboard at Port %1").arg(GetPort() + 1));
|
||||
AddWidget(tr("Triforce Baseboard"), widget);
|
||||
}
|
||||
else
|
||||
{
|
||||
setWindowTitle(tr("GameCube Controller at Port %1").arg(GetPort() + 1));
|
||||
AddWidget(tr("GameCube Controller"), widget);
|
||||
}
|
||||
break;
|
||||
case Type::MAPPING_GC_MICROPHONE:
|
||||
widget = new GCMicrophone(this);
|
||||
|
||||
@@ -250,7 +250,12 @@ MainWindow::MainWindow(Core::System& system, std::unique_ptr<BootParameters> boo
|
||||
});
|
||||
#endif
|
||||
|
||||
connect(m_cheats_manager, &CheatsManager::OpenGeneralSettings, this,
|
||||
&MainWindow::ShowGeneralWindow);
|
||||
|
||||
#ifdef USE_RETRO_ACHIEVEMENTS
|
||||
connect(m_cheats_manager, &CheatsManager::OpenAchievementSettings, this,
|
||||
&MainWindow::ShowAchievementSettings);
|
||||
connect(m_game_list, &GameList::OpenAchievementSettings, this,
|
||||
&MainWindow::ShowAchievementSettings);
|
||||
#endif // USE_RETRO_ACHIEVEMENTS
|
||||
@@ -511,6 +516,8 @@ void MainWindow::CreateComponents()
|
||||
});
|
||||
connect(m_breakpoint_widget, &BreakpointWidget::ShowMemory, m_memory_widget,
|
||||
&MemoryWidget::SetAddress);
|
||||
connect(m_cheats_manager, &CheatsManager::ShowMemory, m_memory_widget, &MemoryWidget::SetAddress);
|
||||
connect(m_cheats_manager, &CheatsManager::RequestWatch, request_watch);
|
||||
}
|
||||
|
||||
void MainWindow::ConnectMenuBar()
|
||||
@@ -1151,6 +1158,43 @@ void MainWindow::StartGame(std::unique_ptr<BootParameters>&& parameters)
|
||||
if (!NKitWarningDialog::ShowUnlessDisabled())
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
When booting Triforce games, we need to ensure that the hardware is set up correctly.
|
||||
*/
|
||||
const auto volume_type =
|
||||
std::get<BootParameters::Disc>(parameters->parameters).volume->GetVolumeType();
|
||||
|
||||
const bool triforce_hardware_sp1 =
|
||||
Config::Get(Config::MAIN_SERIAL_PORT_1) == ExpansionInterface::EXIDeviceType::Baseboard;
|
||||
const bool triforce_hardware_port_1 = Config::Get(Config::GetInfoForSIDevice(0)) ==
|
||||
SerialInterface::SIDevices::SIDEVICE_AM_BASEBOARD;
|
||||
|
||||
if (volume_type == DiscIO::Platform::Triforce)
|
||||
{
|
||||
if (!triforce_hardware_sp1 || !triforce_hardware_port_1)
|
||||
{
|
||||
ModalMessageBox::critical(
|
||||
this, tr("Error"),
|
||||
tr("To boot a Triforce game, SP1 and Port 1 must be set to Triforce Baseboard."),
|
||||
QMessageBox::Ok);
|
||||
HideRenderWidget();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Some Triforce tools don't include a boot.id file, but they can still be launched.
|
||||
*/
|
||||
if (triforce_hardware_sp1 || triforce_hardware_port_1)
|
||||
{
|
||||
ModalMessageBox::warning(
|
||||
this, tr("Warning"),
|
||||
tr("Non-Triforce games cannot be booted with Triforce hardware attached."),
|
||||
QMessageBox::Ok);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we're running, only start a new game once we've stopped the last.
|
||||
|
||||
@@ -319,6 +319,9 @@ void MenuBar::AddToolsMenu()
|
||||
m_pal_ipl =
|
||||
gc_ipl->addAction(tr("PAL"), this, [this] { emit BootGameCubeIPL(DiscIO::Region::PAL); });
|
||||
|
||||
m_dev_ipl = gc_ipl->addAction(tr("Triforce"), this,
|
||||
[this] { emit BootGameCubeIPL(DiscIO::Region::Unknown); });
|
||||
|
||||
tools_menu->addAction(tr("Memory Card Manager"), this, [this] { emit ShowMemcardManager(); });
|
||||
|
||||
tools_menu->addSeparator();
|
||||
@@ -1091,6 +1094,7 @@ void MenuBar::UpdateToolsMenu(const Core::State state)
|
||||
m_ntscj_ipl->setEnabled(is_uninitialized && File::Exists(Config::GetBootROMPath(JAP_DIR)));
|
||||
m_ntscu_ipl->setEnabled(is_uninitialized && File::Exists(Config::GetBootROMPath(USA_DIR)));
|
||||
m_pal_ipl->setEnabled(is_uninitialized && File::Exists(Config::GetBootROMPath(EUR_DIR)));
|
||||
m_dev_ipl->setEnabled(is_uninitialized && File::Exists(Config::GetBootROMPath(DEV_DIR)));
|
||||
m_wad_install_action->setEnabled(is_uninitialized);
|
||||
m_import_backup->setEnabled(is_uninitialized);
|
||||
m_check_nand->setEnabled(is_uninitialized);
|
||||
|
||||
@@ -227,6 +227,7 @@ private:
|
||||
QAction* m_ntscj_ipl;
|
||||
QAction* m_ntscu_ipl;
|
||||
QAction* m_pal_ipl;
|
||||
QAction* m_dev_ipl;
|
||||
QMenu* m_manage_nand_menu;
|
||||
QAction* m_import_backup;
|
||||
QAction* m_check_nand;
|
||||
|
||||
@@ -151,6 +151,7 @@ void GameCubePane::CreateWidgets()
|
||||
EXIDeviceType::EthernetIPC,
|
||||
#endif
|
||||
EXIDeviceType::ModemTapServer,
|
||||
EXIDeviceType::Baseboard,
|
||||
})
|
||||
{
|
||||
m_slot_combos[ExpansionInterface::Slot::SP1]->addItem(tr(fmt::format("{:n}", device).c_str()),
|
||||
@@ -418,6 +419,10 @@ void GameCubePane::OnConfigPressed(ExpansionInterface::Slot slot)
|
||||
dialog.exec();
|
||||
return;
|
||||
}
|
||||
case ExpansionInterface::EXIDeviceType::Baseboard:
|
||||
{
|
||||
return;
|
||||
}
|
||||
default:
|
||||
PanicAlertFmt("Unknown settings pressed for {}", device);
|
||||
return;
|
||||
@@ -452,19 +457,23 @@ bool GameCubePane::SetMemcard(ExpansionInterface::Slot slot, const QString& file
|
||||
const std::string jp_path = Config::GetMemcardPath(raw_path, slot, DiscIO::Region::NTSC_J);
|
||||
const std::string us_path = Config::GetMemcardPath(raw_path, slot, DiscIO::Region::NTSC_U);
|
||||
const std::string eu_path = Config::GetMemcardPath(raw_path, slot, DiscIO::Region::PAL);
|
||||
const bool raw_path_valid = raw_path == jp_path || raw_path == us_path || raw_path == eu_path;
|
||||
const std::string dv_path = Config::GetMemcardPath(raw_path, slot, DiscIO::Region::DEV);
|
||||
const bool raw_path_valid =
|
||||
raw_path == jp_path || raw_path == us_path || raw_path == eu_path || raw_path == dv_path;
|
||||
|
||||
if (!raw_path_valid)
|
||||
{
|
||||
// TODO: We could try to autodetect the card region here and offer automatic renaming.
|
||||
ModalMessageBox::critical(this, tr("Error"),
|
||||
tr("The filename %1 does not conform to Dolphin's region code format "
|
||||
"for memory cards. Please rename this file to either %2, %3, or "
|
||||
"%4, matching the region of the save files that are on it.")
|
||||
.arg(QString::fromStdString(PathToFileName(raw_path)))
|
||||
.arg(QString::fromStdString(PathToFileName(us_path)))
|
||||
.arg(QString::fromStdString(PathToFileName(eu_path)))
|
||||
.arg(QString::fromStdString(PathToFileName(jp_path))));
|
||||
ModalMessageBox::critical(
|
||||
this, tr("Error"),
|
||||
tr("The filename %1 does not conform to Dolphin's region code format "
|
||||
"for memory cards. Please rename this file to either %2, %3, %4, or "
|
||||
"%5, matching the region of the save files that are on it.")
|
||||
.arg(QString::fromStdString(PathToFileName(raw_path)))
|
||||
.arg(QString::fromStdString(PathToFileName(us_path)))
|
||||
.arg(QString::fromStdString(PathToFileName(eu_path)))
|
||||
.arg(QString::fromStdString(PathToFileName(jp_path)))
|
||||
.arg(QString::fromStdString(PathToFileName(dv_path))));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -556,8 +565,9 @@ bool GameCubePane::SetGCIFolder(ExpansionInterface::Slot slot, const QString& pa
|
||||
const std::string default_jp_path = Config::GetGCIFolderPath("", slot, DiscIO::Region::NTSC_J);
|
||||
const std::string default_us_path = Config::GetGCIFolderPath("", slot, DiscIO::Region::NTSC_U);
|
||||
const std::string default_eu_path = Config::GetGCIFolderPath("", slot, DiscIO::Region::PAL);
|
||||
const bool is_default_path =
|
||||
raw_path == default_jp_path || raw_path == default_us_path || raw_path == default_eu_path;
|
||||
const std::string default_dv_path = Config::GetGCIFolderPath("", slot, DiscIO::Region::DEV);
|
||||
const bool is_default_path = raw_path == default_jp_path || raw_path == default_us_path ||
|
||||
raw_path == default_eu_path || raw_path == default_dv_path;
|
||||
|
||||
bool path_changed;
|
||||
if (is_default_path)
|
||||
@@ -574,7 +584,9 @@ bool GameCubePane::SetGCIFolder(ExpansionInterface::Slot slot, const QString& pa
|
||||
const std::string jp_path = Config::GetGCIFolderPath(raw_path, slot, DiscIO::Region::NTSC_J);
|
||||
const std::string us_path = Config::GetGCIFolderPath(raw_path, slot, DiscIO::Region::NTSC_U);
|
||||
const std::string eu_path = Config::GetGCIFolderPath(raw_path, slot, DiscIO::Region::PAL);
|
||||
const bool raw_path_valid = raw_path == jp_path || raw_path == us_path || raw_path == eu_path;
|
||||
const std::string dv_path = Config::GetGCIFolderPath(raw_path, slot, DiscIO::Region::DEV);
|
||||
const bool raw_path_valid =
|
||||
raw_path == jp_path || raw_path == us_path || raw_path == eu_path || raw_path == dv_path;
|
||||
|
||||
if (!raw_path_valid)
|
||||
{
|
||||
@@ -582,12 +594,13 @@ bool GameCubePane::SetGCIFolder(ExpansionInterface::Slot slot, const QString& pa
|
||||
ModalMessageBox::critical(
|
||||
this, tr("Error"),
|
||||
tr("The folder %1 does not conform to Dolphin's region code format "
|
||||
"for GCI folders. Please rename this folder to either %2, %3, or "
|
||||
"%4, matching the region of the save files that are in it.")
|
||||
"for GCI folders. Please rename this folder to either %2, %3, %4, or "
|
||||
"%5, matching the region of the save files that are in it.")
|
||||
.arg(QString::fromStdString(PathToFileName(raw_path)))
|
||||
.arg(QString::fromStdString(PathToFileName(us_path)))
|
||||
.arg(QString::fromStdString(PathToFileName(eu_path)))
|
||||
.arg(QString::fromStdString(PathToFileName(jp_path))));
|
||||
.arg(QString::fromStdString(PathToFileName(jp_path)))
|
||||
.arg(QString::fromStdString(PathToFileName(dv_path))));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user