dolphin/Source/Core/DolphinQt/Settings/GameCubePane.cpp

412 lines
11 KiB
C++
Raw Normal View History

2018-01-04 00:41:31 +00:00
// Copyright 2018 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
2018-07-06 22:40:15 +00:00
#include "DolphinQt/Settings/GameCubePane.h"
2018-01-04 00:41:31 +00:00
#include <QCheckBox>
#include <QComboBox>
#include <QFileDialog>
#include <QFileInfo>
#include <QGridLayout>
#include <QGroupBox>
#include <QLabel>
#include <QMessageBox>
#include <QPushButton>
#include <QVBoxLayout>
#include "Common/CommonPaths.h"
#include "Common/Config/Config.h"
2018-01-04 00:41:31 +00:00
#include "Common/FileUtil.h"
2018-05-28 01:48:04 +00:00
#include "Core/Config/MainSettings.h"
2018-01-04 00:41:31 +00:00
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/HW/EXI/EXI.h"
#include "Core/HW/GCMemcard/GCMemcard.h"
2018-05-28 01:48:04 +00:00
2018-07-06 22:40:15 +00:00
#include "DolphinQt/Config/Mapping/MappingWindow.h"
2018-01-04 00:41:31 +00:00
constexpr int SLOT_A_INDEX = 0;
constexpr int SLOT_B_INDEX = 1;
constexpr int SLOT_SP1_INDEX = 2;
2018-01-04 00:41:31 +00:00
constexpr int SLOT_COUNT = 3;
enum ExpansionSelection
{
EXP_NOTHING = 0,
EXP_DUMMY = 1,
EXP_MEMORYCARD = 2,
EXP_BROADBAND = 2,
EXP_GCI_FOLDER = 3,
EXP_GECKO = 4,
EXP_AGP = 5,
EXP_MICROPHONE = 6
};
2018-01-04 00:41:31 +00:00
GameCubePane::GameCubePane()
{
CreateWidgets();
LoadSettings();
ConnectWidgets();
2018-01-04 00:41:31 +00:00
}
void GameCubePane::CreateWidgets()
{
QVBoxLayout* layout = new QVBoxLayout;
// IPL Settings
QGroupBox* ipl_box = new QGroupBox(tr("IPL Settings"));
QGridLayout* ipl_layout = new QGridLayout;
ipl_box->setLayout(ipl_layout);
m_skip_main_menu = new QCheckBox(tr("Skip Main Menu"));
m_override_language_ntsc = new QCheckBox(tr("Override Language on NTSC Games"));
m_language_combo = new QComboBox;
// Add languages
for (const auto& language :
{tr("English"), tr("German"), tr("French"), tr("Spanish"), tr("Italian"), tr("Dutch")})
m_language_combo->addItem(language);
ipl_layout->addWidget(m_skip_main_menu, 0, 0);
ipl_layout->addWidget(new QLabel(tr("System Language:")), 1, 0);
ipl_layout->addWidget(m_language_combo, 1, 1);
ipl_layout->addWidget(m_override_language_ntsc, 2, 0);
// Device Settings
QGroupBox* device_box = new QGroupBox(tr("Device Settings"));
QGridLayout* device_layout = new QGridLayout;
device_box->setLayout(device_layout);
m_slot_combos[0] = new QComboBox;
m_slot_combos[1] = new QComboBox;
m_slot_combos[2] = new QComboBox;
m_slot_buttons[0] = new QPushButton(tr("..."));
m_slot_buttons[1] = new QPushButton(tr("..."));
m_slot_buttons[0]->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_slot_buttons[1]->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
const QString i10n_nothing = tr("<Nothing>");
const QString i10n_dummy = tr("Dummy");
// Add slot devices
for (const auto& device : {i10n_nothing, i10n_dummy, tr("Memory Card"), tr("GCI Folder"),
tr("USB Gecko"), tr("Advance Game Port"), tr("Microphone")})
{
m_slot_combos[0]->addItem(device);
m_slot_combos[1]->addItem(device);
}
// Add SP1 devices
for (const auto& device : {i10n_nothing, i10n_dummy, tr("Broadband Adapter")})
{
m_slot_combos[2]->addItem(device);
}
device_layout->addWidget(new QLabel(tr("Slot A:")), 0, 0);
device_layout->addWidget(m_slot_combos[0], 0, 1);
device_layout->addWidget(m_slot_buttons[0], 0, 2);
device_layout->addWidget(new QLabel(tr("Slot B:")), 1, 0);
device_layout->addWidget(m_slot_combos[1], 1, 1);
device_layout->addWidget(m_slot_buttons[1], 1, 2);
device_layout->addWidget(new QLabel(tr("SP1:")), 2, 0);
device_layout->addWidget(m_slot_combos[2], 2, 1);
layout->addWidget(ipl_box);
layout->addWidget(device_box);
2018-03-24 17:18:17 +00:00
layout->addStretch();
2018-01-04 00:41:31 +00:00
setLayout(layout);
}
void GameCubePane::ConnectWidgets()
{
// IPL Settings
connect(m_skip_main_menu, &QCheckBox::stateChanged, this, &GameCubePane::SaveSettings);
connect(m_language_combo, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &GameCubePane::SaveSettings);
connect(m_override_language_ntsc, &QCheckBox::stateChanged, this, &GameCubePane::SaveSettings);
// Device Settings
for (int i = 0; i < SLOT_COUNT; i++)
{
connect(m_slot_combos[i],
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
&GameCubePane::SaveSettings);
if (i <= SLOT_B_INDEX)
{
connect(m_slot_buttons[i], &QPushButton::pressed, this, [this, i] { OnConfigPressed(i); });
}
}
}
void GameCubePane::OnConfigPressed(int slot)
{
QString filter;
bool memcard = false;
switch (m_slot_combos[slot]->currentIndex())
{
// Memory card
case 2:
filter = tr("GameCube Memory Cards (*.raw *.gcp)");
2018-01-04 00:41:31 +00:00
memcard = true;
break;
// Advance Game Port
case 5:
filter = tr("Game Boy Advance Carts (*.gba)");
memcard = false;
break;
// Microphone
case 6:
MappingWindow(this, MappingWindow::Type::MAPPING_GC_MICROPHONE, slot).exec();
return;
}
QString filename = QFileDialog::getSaveFileName(
this, tr("Choose a file to open"), QString::fromStdString(File::GetUserPath(D_GCUSER_IDX)),
filter, 0, QFileDialog::DontConfirmOverwrite);
2018-01-04 00:41:31 +00:00
if (filename.isEmpty())
2018-01-04 00:41:31 +00:00
return;
2018-02-02 11:28:57 +00:00
QString path_abs = QFileInfo(filename).absoluteFilePath();
2018-01-04 00:41:31 +00:00
// Memcard validity checks
if (memcard)
{
if (File::Exists(filename.toStdString()))
2018-01-04 00:41:31 +00:00
{
GCMemcard mc(filename.toStdString());
if (!mc.IsValid())
{
QMessageBox::critical(this, tr("Error"),
tr("Cannot use that file as a memory card.\n%1\n"
"is not a valid GameCube memory card file")
.arg(filename));
return;
}
2018-01-04 00:41:31 +00:00
}
2018-02-02 11:28:57 +00:00
bool other_slot_memcard =
m_slot_combos[slot == 0 ? SLOT_B_INDEX : SLOT_A_INDEX]->currentIndex() == EXP_MEMORYCARD;
2018-01-04 00:41:31 +00:00
2018-02-02 11:28:57 +00:00
if (other_slot_memcard)
2018-01-04 00:41:31 +00:00
{
2018-02-02 11:28:57 +00:00
QString path_b =
QFileInfo(QString::fromStdString(slot == 0 ? Config::Get(Config::MAIN_MEMCARD_B_PATH) :
Config::Get(Config::MAIN_MEMCARD_A_PATH)))
2018-02-02 11:28:57 +00:00
.absoluteFilePath();
if (path_abs == path_b)
{
QMessageBox::critical(this, tr("Error"), tr("The same file can't be used in both slots."));
return;
}
2018-01-04 00:41:31 +00:00
}
}
QString path_old;
if (memcard)
{
path_old =
QFileInfo(QString::fromStdString(slot == 0 ? Config::Get(Config::MAIN_MEMCARD_A_PATH) :
Config::Get(Config::MAIN_MEMCARD_B_PATH)))
.absoluteFilePath();
}
else
{
path_old = QFileInfo(QString::fromStdString(slot == 0 ? SConfig::GetInstance().m_strGbaCartA :
SConfig::GetInstance().m_strGbaCartB))
.absoluteFilePath();
}
2018-01-04 00:41:31 +00:00
if (memcard)
{
if (slot == SLOT_A_INDEX)
{
Config::SetBase(Config::MAIN_MEMCARD_A_PATH, path_abs.toStdString());
2018-01-04 00:41:31 +00:00
}
else
{
Config::SetBase(Config::MAIN_MEMCARD_B_PATH, path_abs.toStdString());
2018-01-04 00:41:31 +00:00
}
}
else
{
if (slot == SLOT_A_INDEX)
{
SConfig::GetInstance().m_strGbaCartA = path_abs.toStdString();
}
else
{
SConfig::GetInstance().m_strGbaCartB = path_abs.toStdString();
}
}
if (Core::IsRunning() && path_abs != path_old)
{
ExpansionInterface::ChangeDevice(
// SlotB is on channel 1, slotA and SP1 are on 0
slot,
// The device enum to change to
memcard ? ExpansionInterface::EXIDEVICE_MEMORYCARD : ExpansionInterface::EXIDEVICE_AGP,
// SP1 is device 2, slots are device 0
0);
}
2018-01-04 00:41:31 +00:00
}
void GameCubePane::LoadSettings()
{
const SConfig& params = SConfig::GetInstance();
// IPL Settings
m_skip_main_menu->setChecked(params.bHLE_BS2);
m_language_combo->setCurrentIndex(params.SelectedLanguage);
m_override_language_ntsc->setChecked(params.bOverrideGCLanguage);
bool have_menu = false;
for (const std::string& dir : {USA_DIR, JAP_DIR, EUR_DIR})
{
const auto path = DIR_SEP + dir + DIR_SEP GC_IPL;
2018-01-04 00:41:31 +00:00
if (File::Exists(File::GetUserPath(D_GCUSER_IDX) + path) ||
File::Exists(File::GetSysDirectory() + GC_SYS_DIR + path))
2018-01-04 00:41:31 +00:00
{
have_menu = true;
break;
}
}
m_skip_main_menu->setEnabled(have_menu);
m_skip_main_menu->setToolTip(have_menu ? QStringLiteral("") :
tr("Put Main Menu roms in User/GC/{region}."));
// Device Settings
for (int i = 0; i < SLOT_COUNT; i++)
{
int index = EXP_NOTHING;
2018-01-04 00:41:31 +00:00
switch (SConfig::GetInstance().m_EXIDevice[i])
{
case ExpansionInterface::EXIDEVICE_NONE:
index = EXP_NOTHING;
2018-01-04 00:41:31 +00:00
break;
case ExpansionInterface::EXIDEVICE_DUMMY:
index = EXP_DUMMY;
2018-01-04 00:41:31 +00:00
break;
case ExpansionInterface::EXIDEVICE_MEMORYCARD:
index = EXP_MEMORYCARD;
break;
case ExpansionInterface::EXIDEVICE_ETH:
index = EXP_BROADBAND;
2018-01-04 00:41:31 +00:00
break;
case ExpansionInterface::EXIDEVICE_MEMORYCARDFOLDER:
index = EXP_GCI_FOLDER;
2018-01-04 00:41:31 +00:00
break;
case ExpansionInterface::EXIDEVICE_GECKO:
index = EXP_GECKO;
2018-01-04 00:41:31 +00:00
break;
case ExpansionInterface::EXIDEVICE_AGP:
index = EXP_AGP;
2018-01-04 00:41:31 +00:00
break;
case ExpansionInterface::EXIDEVICE_MIC:
index = EXP_MICROPHONE;
2018-01-04 00:41:31 +00:00
break;
default:
break;
}
if (i <= SLOT_B_INDEX)
{
bool has_config = (index == EXP_MEMORYCARD || index > EXP_GECKO);
2018-01-04 00:41:31 +00:00
m_slot_buttons[i]->setEnabled(has_config);
}
m_slot_combos[i]->setCurrentIndex(index);
}
}
void GameCubePane::SaveSettings()
{
SConfig& params = SConfig::GetInstance();
// IPL Settings
params.bHLE_BS2 = m_skip_main_menu->isChecked();
Config::SetBaseOrCurrent(Config::MAIN_SKIP_IPL, m_skip_main_menu->isChecked());
2018-01-04 00:41:31 +00:00
params.SelectedLanguage = m_language_combo->currentIndex();
Config::SetBaseOrCurrent(Config::MAIN_GC_LANGUAGE, m_language_combo->currentIndex());
2018-01-04 00:41:31 +00:00
params.bOverrideGCLanguage = m_override_language_ntsc->isChecked();
Config::SetBaseOrCurrent(Config::MAIN_OVERRIDE_GC_LANGUAGE,
m_override_language_ntsc->isChecked());
2018-01-04 00:41:31 +00:00
for (int i = 0; i < SLOT_COUNT; i++)
{
auto dev = SConfig::GetInstance().m_EXIDevice[i];
2018-01-04 00:41:31 +00:00
int index = m_slot_combos[i]->currentIndex();
switch (index)
{
case EXP_NOTHING:
2018-01-04 00:41:31 +00:00
dev = ExpansionInterface::EXIDEVICE_NONE;
break;
case EXP_DUMMY:
2018-01-04 00:41:31 +00:00
dev = ExpansionInterface::EXIDEVICE_DUMMY;
break;
case EXP_MEMORYCARD:
if (i == SLOT_SP1_INDEX)
dev = ExpansionInterface::EXIDEVICE_ETH;
else
dev = ExpansionInterface::EXIDEVICE_MEMORYCARD;
2018-01-04 00:41:31 +00:00
break;
case EXP_GCI_FOLDER:
2018-01-04 00:41:31 +00:00
dev = ExpansionInterface::EXIDEVICE_MEMORYCARDFOLDER;
break;
case EXP_GECKO:
2018-01-04 00:41:31 +00:00
dev = ExpansionInterface::EXIDEVICE_GECKO;
break;
case EXP_AGP:
2018-01-04 00:41:31 +00:00
dev = ExpansionInterface::EXIDEVICE_AGP;
break;
case EXP_MICROPHONE:
2018-01-04 00:41:31 +00:00
dev = ExpansionInterface::EXIDEVICE_MIC;
break;
}
if (Core::IsRunning() && SConfig::GetInstance().m_EXIDevice[i] != dev)
{
ExpansionInterface::ChangeDevice(
// SlotB is on channel 1, slotA and SP1 are on 0
(i == 1) ? 1 : 0,
// The device enum to change to
dev,
// SP1 is device 2, slots are device 0
(i == 2) ? 2 : 0);
2018-01-04 00:41:31 +00:00
}
SConfig::GetInstance().m_EXIDevice[i] = dev;
switch (i)
{
case SLOT_A_INDEX:
Config::SetBaseOrCurrent(Config::MAIN_SLOT_A, dev);
break;
case SLOT_B_INDEX:
Config::SetBaseOrCurrent(Config::MAIN_SLOT_B, dev);
break;
case SLOT_SP1_INDEX:
Config::SetBaseOrCurrent(Config::MAIN_SERIAL_PORT_1, dev);
break;
}
2018-01-04 00:41:31 +00:00
}
LoadSettings();
}