-
Notifications
You must be signed in to change notification settings - Fork 2.6k
/
GameCubeConfigPane.cpp
385 lines (332 loc) · 13.1 KB
/
GameCubeConfigPane.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
// Copyright 2015 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <string>
#include <wx/button.h>
#include <wx/checkbox.h>
#include <wx/choice.h>
#include <wx/filedlg.h>
#include <wx/filename.h>
#include <wx/gbsizer.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include "Common/CommonPaths.h"
#include "Common/FileUtil.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
#include "Core/NetPlayProto.h"
#include "Core/HW/EXI.h"
#include "Core/HW/GCMemcard.h"
#include "DolphinWX/WxUtils.h"
#include "DolphinWX/Config/ConfigMain.h"
#include "DolphinWX/Config/GameCubeConfigPane.h"
#define DEV_NONE_STR _trans("<Nothing>")
#define DEV_DUMMY_STR _trans("Dummy")
#define EXIDEV_MEMCARD_STR _trans("Memory Card")
#define EXIDEV_MEMDIR_STR _trans("GCI Folder")
#define EXIDEV_MIC_STR _trans("Mic")
#define EXIDEV_BBA_STR "BBA"
#define EXIDEV_AGP_STR "Advance Game Port"
#define EXIDEV_AM_BB_STR _trans("AM-Baseboard")
#define EXIDEV_GECKO_STR "USBGecko"
GameCubeConfigPane::GameCubeConfigPane(wxWindow* parent, wxWindowID id)
: wxPanel(parent, id)
{
InitializeGUI();
LoadGUIValues();
RefreshGUI();
}
void GameCubeConfigPane::InitializeGUI()
{
m_ipl_language_strings.Add(_("English"));
m_ipl_language_strings.Add(_("German"));
m_ipl_language_strings.Add(_("French"));
m_ipl_language_strings.Add(_("Spanish"));
m_ipl_language_strings.Add(_("Italian"));
m_ipl_language_strings.Add(_("Dutch"));
m_system_lang_choice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_ipl_language_strings);
m_system_lang_choice->SetToolTip(_("Sets the GameCube system language."));
m_system_lang_choice->Bind(wxEVT_CHOICE, &GameCubeConfigPane::OnSystemLanguageChange, this);
m_override_lang_checkbox = new wxCheckBox(this, wxID_ANY, _("Override Language on NTSC Games"));
m_override_lang_checkbox->SetToolTip(_("Lets the system language be set to values that games were not designed for. This can allow the use of extra translations for a few games, but can also lead to text display issues."));
m_override_lang_checkbox->Bind(wxEVT_CHECKBOX, &GameCubeConfigPane::OnOverrideLanguageCheckBoxChanged, this);
m_skip_bios_checkbox = new wxCheckBox(this, wxID_ANY, _("Skip BIOS"));
m_skip_bios_checkbox->Bind(wxEVT_CHECKBOX, &GameCubeConfigPane::OnSkipBiosCheckBoxChanged, this);
if (!File::Exists(File::GetUserPath(D_GCUSER_IDX) + DIR_SEP + USA_DIR + DIR_SEP GC_IPL) &&
!File::Exists(File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + USA_DIR + DIR_SEP GC_IPL) &&
!File::Exists(File::GetUserPath(D_GCUSER_IDX) + DIR_SEP + JAP_DIR + DIR_SEP GC_IPL) &&
!File::Exists(File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + JAP_DIR + DIR_SEP GC_IPL) &&
!File::Exists(File::GetUserPath(D_GCUSER_IDX) + DIR_SEP + EUR_DIR + DIR_SEP GC_IPL) &&
!File::Exists(File::GetSysDirectory() + GC_SYS_DIR + DIR_SEP + EUR_DIR + DIR_SEP GC_IPL))
{
m_skip_bios_checkbox->Disable();
m_skip_bios_checkbox->SetToolTip(_("Put BIOS roms in User/GC/{region}."));
}
// Device settings
// EXI Devices
wxStaticText* GCEXIDeviceText[3] = {
new wxStaticText(this, wxID_ANY, _("Slot A")),
new wxStaticText(this, wxID_ANY, _("Slot B")),
new wxStaticText(this, wxID_ANY, "SP1"),
};
m_exi_devices[0] = new wxChoice(this, wxID_ANY);
m_exi_devices[0]->Bind(wxEVT_CHOICE, &GameCubeConfigPane::OnSlotAChanged, this);
m_exi_devices[1] = new wxChoice(this, wxID_ANY);
m_exi_devices[1]->Bind(wxEVT_CHOICE, &GameCubeConfigPane::OnSlotBChanged, this);
m_exi_devices[2] = new wxChoice(this, wxID_ANY);
m_exi_devices[2]->Bind(wxEVT_CHOICE, &GameCubeConfigPane::OnSP1Changed, this);
m_exi_devices[2]->SetToolTip(_("Serial Port 1 - This is the port which devices such as the net adapter use."));
m_memcard_path[0] = new wxButton(this, wxID_ANY, "...", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
m_memcard_path[0]->Bind(wxEVT_BUTTON, &GameCubeConfigPane::OnSlotAButtonClick, this);
m_memcard_path[1] = new wxButton(this, wxID_ANY, "...", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
m_memcard_path[1]->Bind(wxEVT_BUTTON, &GameCubeConfigPane::OnSlotBButtonClick, this);
// Populate the GameCube page
wxGridBagSizer* const sGamecubeIPLSettings = new wxGridBagSizer();
sGamecubeIPLSettings->Add(m_skip_bios_checkbox, wxGBPosition(0, 0), wxGBSpan(1, 2), wxALL, 5);
sGamecubeIPLSettings->Add(new wxStaticText(this, wxID_ANY, _("System Language:")),
wxGBPosition(1, 0), wxDefaultSpan, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT | wxBOTTOM, 5);
sGamecubeIPLSettings->Add(m_system_lang_choice, wxGBPosition(1, 1), wxDefaultSpan, wxLEFT | wxRIGHT | wxBOTTOM, 5);
sGamecubeIPLSettings->Add(m_override_lang_checkbox, wxGBPosition(2, 0), wxGBSpan(1, 2), wxALL, 5);
wxStaticBoxSizer* const sbGamecubeIPLSettings = new wxStaticBoxSizer(wxVERTICAL, this, _("IPL Settings"));
sbGamecubeIPLSettings->Add(sGamecubeIPLSettings);
wxStaticBoxSizer* const sbGamecubeDeviceSettings = new wxStaticBoxSizer(wxVERTICAL, this, _("Device Settings"));
wxGridBagSizer* const sbGamecubeEXIDevSettings = new wxGridBagSizer(10, 10);
for (int i = 0; i < 3; ++i)
{
sbGamecubeEXIDevSettings->Add(GCEXIDeviceText[i], wxGBPosition(i, 0), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
sbGamecubeEXIDevSettings->Add(m_exi_devices[i], wxGBPosition(i, 1), wxGBSpan(1, (i < 2) ? 1 : 2), wxALIGN_CENTER_VERTICAL);
if (i < 2)
sbGamecubeEXIDevSettings->Add(m_memcard_path[i], wxGBPosition(i, 2), wxDefaultSpan, wxALIGN_CENTER_VERTICAL);
if (NetPlay::IsNetPlayRunning())
m_exi_devices[i]->Disable();
}
sbGamecubeDeviceSettings->Add(sbGamecubeEXIDevSettings, 0, wxALL, 5);
wxBoxSizer* const main_sizer = new wxBoxSizer(wxVERTICAL);
main_sizer->Add(sbGamecubeIPLSettings, 0, wxEXPAND | wxALL, 5);
main_sizer->Add(sbGamecubeDeviceSettings, 0, wxEXPAND | wxALL, 5);
SetSizer(main_sizer);
}
void GameCubeConfigPane::LoadGUIValues()
{
const SConfig& startup_params = SConfig::GetInstance();
m_system_lang_choice->SetSelection(startup_params.SelectedLanguage);
m_skip_bios_checkbox->SetValue(startup_params.bHLE_BS2);
m_override_lang_checkbox->SetValue(startup_params.bOverrideGCLanguage);
wxArrayString slot_devices;
slot_devices.Add(_(DEV_NONE_STR));
slot_devices.Add(_(DEV_DUMMY_STR));
slot_devices.Add(_(EXIDEV_MEMCARD_STR));
slot_devices.Add(_(EXIDEV_MEMDIR_STR));
slot_devices.Add(_(EXIDEV_GECKO_STR));
slot_devices.Add(_(EXIDEV_AGP_STR));
#if HAVE_PORTAUDIO
slot_devices.Add(_(EXIDEV_MIC_STR));
#endif
wxArrayString sp1_devices;
sp1_devices.Add(_(DEV_NONE_STR));
sp1_devices.Add(_(DEV_DUMMY_STR));
sp1_devices.Add(_(EXIDEV_BBA_STR));
sp1_devices.Add(_(EXIDEV_AM_BB_STR));
for (int i = 0; i < 3; ++i)
{
bool isMemcard = false;
// Add strings to the wxChoice list, the third wxChoice is the SP1 slot
if (i == 2)
m_exi_devices[i]->Append(sp1_devices);
else
m_exi_devices[i]->Append(slot_devices);
switch (SConfig::GetInstance().m_EXIDevice[i])
{
case EXIDEVICE_NONE:
m_exi_devices[i]->SetStringSelection(slot_devices[0]);
break;
case EXIDEVICE_MEMORYCARD:
isMemcard = m_exi_devices[i]->SetStringSelection(slot_devices[2]);
break;
case EXIDEVICE_MEMORYCARDFOLDER:
m_exi_devices[i]->SetStringSelection(slot_devices[3]);
break;
case EXIDEVICE_GECKO:
m_exi_devices[i]->SetStringSelection(slot_devices[4]);
break;
case EXIDEVICE_AGP:
isMemcard = m_exi_devices[i]->SetStringSelection(slot_devices[5]);
break;
case EXIDEVICE_MIC:
m_exi_devices[i]->SetStringSelection(slot_devices[6]);
break;
case EXIDEVICE_ETH:
m_exi_devices[i]->SetStringSelection(sp1_devices[2]);
break;
case EXIDEVICE_AM_BASEBOARD:
m_exi_devices[i]->SetStringSelection(sp1_devices[3]);
break;
case EXIDEVICE_DUMMY:
default:
m_exi_devices[i]->SetStringSelection(slot_devices[1]);
break;
}
if (!isMemcard && i < 2)
m_memcard_path[i]->Disable();
}
}
void GameCubeConfigPane::RefreshGUI()
{
if (Core::IsRunning())
{
m_system_lang_choice->Disable();
m_override_lang_checkbox->Disable();
m_skip_bios_checkbox->Disable();
}
}
void GameCubeConfigPane::OnSystemLanguageChange(wxCommandEvent& event)
{
SConfig::GetInstance().SelectedLanguage = m_system_lang_choice->GetSelection();
AddPendingEvent(wxCommandEvent(wxDOLPHIN_CFG_REFRESH_LIST));
}
void GameCubeConfigPane::OnOverrideLanguageCheckBoxChanged(wxCommandEvent& event)
{
SConfig::GetInstance().bOverrideGCLanguage = m_override_lang_checkbox->IsChecked();
AddPendingEvent(wxCommandEvent(wxDOLPHIN_CFG_REFRESH_LIST));
}
void GameCubeConfigPane::OnSkipBiosCheckBoxChanged(wxCommandEvent& event)
{
SConfig::GetInstance().bHLE_BS2 = m_skip_bios_checkbox->IsChecked();
}
void GameCubeConfigPane::OnSlotAChanged(wxCommandEvent& event)
{
ChooseEXIDevice(event.GetString(), 0);
}
void GameCubeConfigPane::OnSlotBChanged(wxCommandEvent& event)
{
ChooseEXIDevice(event.GetString(), 1);
}
void GameCubeConfigPane::OnSP1Changed(wxCommandEvent& event)
{
ChooseEXIDevice(event.GetString(), 2);
}
void GameCubeConfigPane::OnSlotAButtonClick(wxCommandEvent& event)
{
ChooseSlotPath(true, SConfig::GetInstance().m_EXIDevice[0]);
}
void GameCubeConfigPane::OnSlotBButtonClick(wxCommandEvent& event)
{
ChooseSlotPath(false, SConfig::GetInstance().m_EXIDevice[1]);
}
void GameCubeConfigPane::ChooseEXIDevice(const wxString& deviceName, int deviceNum)
{
TEXIDevices tempType;
if (!deviceName.compare(_(EXIDEV_MEMCARD_STR)))
tempType = EXIDEVICE_MEMORYCARD;
else if (!deviceName.compare(_(EXIDEV_MEMDIR_STR)))
tempType = EXIDEVICE_MEMORYCARDFOLDER;
else if (!deviceName.compare(_(EXIDEV_MIC_STR)))
tempType = EXIDEVICE_MIC;
else if (!deviceName.compare(EXIDEV_BBA_STR))
tempType = EXIDEVICE_ETH;
else if (!deviceName.compare(EXIDEV_AGP_STR))
tempType = EXIDEVICE_AGP;
else if (!deviceName.compare(_(EXIDEV_AM_BB_STR)))
tempType = EXIDEVICE_AM_BASEBOARD;
else if (!deviceName.compare(EXIDEV_GECKO_STR))
tempType = EXIDEVICE_GECKO;
else if (!deviceName.compare(_(DEV_NONE_STR)))
tempType = EXIDEVICE_NONE;
else
tempType = EXIDEVICE_DUMMY;
// Gray out the memcard path button if we're not on a memcard or AGP
if (tempType == EXIDEVICE_MEMORYCARD || tempType == EXIDEVICE_AGP)
m_memcard_path[deviceNum]->Enable();
else if (deviceNum == 0 || deviceNum == 1)
m_memcard_path[deviceNum]->Disable();
SConfig::GetInstance().m_EXIDevice[deviceNum] = tempType;
if (Core::IsRunning())
{
// Change plugged device! :D
ExpansionInterface::ChangeDevice(
(deviceNum == 1) ? 1 : 0, // SlotB is on channel 1, slotA and SP1 are on 0
tempType, // The device enum to change to
(deviceNum == 2) ? 2 : 0); // SP1 is device 2, slots are device 0
}
}
void GameCubeConfigPane::ChooseSlotPath(bool is_slot_a, TEXIDevices device_type)
{
bool memcard = (device_type == EXIDEVICE_MEMORYCARD);
std::string path;
std::string cardname;
std::string ext;
std::string pathA = SConfig::GetInstance().m_strMemoryCardA;
std::string pathB = SConfig::GetInstance().m_strMemoryCardB;
if (!memcard)
{
pathA = SConfig::GetInstance().m_strGbaCartA;
pathB = SConfig::GetInstance().m_strGbaCartB;
}
SplitPath(is_slot_a ? pathA : pathB, &path, &cardname, &ext);
std::string filename = WxStrToStr(wxFileSelector(
_("Choose a file to open"),
StrToWxStr(path),
StrToWxStr(cardname),
StrToWxStr(ext),
memcard ? _("GameCube Memory Cards (*.raw,*.gcp)") + "|*.raw;*.gcp" : _("Game Boy Advance Carts (*.gba)") + "|*.gba"));
if (!filename.empty())
{
if (File::Exists(filename))
{
if (memcard)
{
GCMemcard memorycard(filename);
if (!memorycard.IsValid())
{
WxUtils::ShowErrorDialog(wxString::Format(_("Cannot use that file as a memory card.\n%s\n" \
"is not a valid GameCube memory card file"), filename.c_str()));
return;
}
}
}
wxFileName newFilename(filename);
newFilename.MakeAbsolute();
filename = newFilename.GetFullPath();
#ifdef _WIN32
// If the Memory Card file is within the Exe dir, we can assume that the user wants it to be stored relative
// to the executable, so it stays set correctly when the probably portable Exe dir is moved.
// TODO: Replace this with a cleaner, non-wx solution once std::filesystem is standard
std::string exeDir = File::GetExeDirectory() + '\\';
if (wxString(filename).Lower().StartsWith(wxString(exeDir).Lower()))
filename.erase(0, exeDir.size());
std::replace(filename.begin(), filename.end(), '\\', '/');
#endif
// also check that the path isn't used for the other memcard...
wxFileName otherFilename(is_slot_a ? pathB : pathA);
otherFilename.MakeAbsolute();
if (newFilename.GetFullPath().compare(otherFilename.GetFullPath()) != 0)
{
if (memcard)
{
if (is_slot_a)
SConfig::GetInstance().m_strMemoryCardA = filename;
else
SConfig::GetInstance().m_strMemoryCardB = filename;
}
else
{
if (is_slot_a)
SConfig::GetInstance().m_strGbaCartA = filename;
else
SConfig::GetInstance().m_strGbaCartB = filename;
}
if (Core::IsRunning())
{
// Change memcard to the new file
ExpansionInterface::ChangeDevice(
is_slot_a ? 0 : 1, // SlotA: channel 0, SlotB channel 1
device_type,
0); // SP1 is device 2, slots are device 0
}
}
else
{
WxUtils::ShowErrorDialog(_("Are you trying to use the same file in both slots?"));
}
}
}