Move the ZTP hack to the game properties (reverted all changes from r6057 to the...
[dolphin.git] / Source / Core / DolphinWX / Src / ISOProperties.cpp
blob55500196b776ab1ef613804d822d7ebfaf105df5
1 // Copyright (C) 2003 Dolphin Project.
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0.
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License 2.0 for more details.
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
15 // Official SVN repository and contact information can be found at
16 // http://code.google.com/p/dolphin-emu/
18 #include "Common.h"
19 #include "CommonPaths.h"
20 #include "Globals.h"
22 #include "VolumeCreator.h"
23 #include "Filesystem.h"
24 #include "ISOProperties.h"
25 #include "PatchAddEdit.h"
26 #include "ARCodeAddEdit.h"
27 #include "GeckoCodeDiag.h"
28 #include "ConfigManager.h"
29 #include "StringUtil.h"
31 #include "../resources/isoprop_file.xpm"
32 #include "../resources/isoprop_folder.xpm"
33 #include "../resources/isoprop_disc.xpm"
35 struct WiiPartition
37 DiscIO::IVolume *Partition;
38 DiscIO::IFileSystem *FileSystem;
39 std::vector<const DiscIO::SFileInfo *> Files;
41 std::vector<WiiPartition> WiiDisc;
43 DiscIO::IVolume *OpenISO = NULL;
44 DiscIO::IFileSystem *pFileSystem = NULL;
46 std::vector<PatchEngine::Patch> onFrame;
47 std::vector<ActionReplay::ARCode> arCodes;
50 BEGIN_EVENT_TABLE(CISOProperties, wxDialog)
51 EVT_CLOSE(CISOProperties::OnClose)
52 EVT_BUTTON(ID_CLOSE, CISOProperties::OnCloseClick)
53 EVT_BUTTON(ID_EDITCONFIG, CISOProperties::OnEditConfig)
54 EVT_CHOICE(ID_EMUSTATE, CISOProperties::SetRefresh)
55 EVT_CHOICE(ID_EMU_ISSUES, CISOProperties::SetRefresh)
56 EVT_LISTBOX(ID_PATCHES_LIST, CISOProperties::ListSelectionChanged)
57 EVT_BUTTON(ID_EDITPATCH, CISOProperties::PatchButtonClicked)
58 EVT_BUTTON(ID_ADDPATCH, CISOProperties::PatchButtonClicked)
59 EVT_BUTTON(ID_REMOVEPATCH, CISOProperties::PatchButtonClicked)
60 EVT_LISTBOX(ID_CHEATS_LIST, CISOProperties::ListSelectionChanged)
61 EVT_BUTTON(ID_EDITCHEAT, CISOProperties::ActionReplayButtonClicked)
62 EVT_BUTTON(ID_ADDCHEAT, CISOProperties::ActionReplayButtonClicked)
63 EVT_BUTTON(ID_REMOVECHEAT, CISOProperties::ActionReplayButtonClicked)
64 EVT_MENU(IDM_BNRSAVEAS, CISOProperties::OnBannerImageSave)
65 EVT_TREE_ITEM_RIGHT_CLICK(ID_TREECTRL, CISOProperties::OnRightClickOnTree)
66 EVT_MENU(IDM_EXTRACTFILE, CISOProperties::OnExtractFile)
67 EVT_MENU(IDM_EXTRACTDIR, CISOProperties::OnExtractDir)
68 EVT_MENU(IDM_EXTRACTALL, CISOProperties::OnExtractDir)
69 EVT_MENU(IDM_EXTRACTAPPLOADER, CISOProperties::OnExtractDataFromHeader)
70 EVT_MENU(IDM_EXTRACTDOL, CISOProperties::OnExtractDataFromHeader)
71 EVT_CHOICE(ID_LANG, CISOProperties::OnChangeBannerLang)
72 END_EVENT_TABLE()
74 CISOProperties::CISOProperties(const std::string fileName, wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& position, const wxSize& size, long style)
75 : wxDialog(parent, id, title, position, size, style)
77 OpenISO = DiscIO::CreateVolumeFromFilename(fileName);
78 if (DiscIO::IsVolumeWiiDisc(OpenISO))
80 for (u32 i = 0; i < 0xFFFFFFFF; i++) // yes, technically there can be OVER NINE THOUSAND partitions...
82 WiiPartition temp;
83 if ((temp.Partition = DiscIO::CreateVolumeFromFilename(fileName, 0, i)) != NULL)
85 if ((temp.FileSystem = DiscIO::CreateFileSystem(temp.Partition)) != NULL)
87 temp.FileSystem->GetFileList(temp.Files);
88 WiiDisc.push_back(temp);
91 else
92 break;
95 else
97 // TODO : Should we add a way to browse the wad file ?
98 if (!DiscIO::IsVolumeWadFile(OpenISO))
100 GCFiles.clear();
101 pFileSystem = DiscIO::CreateFileSystem(OpenISO);
102 if (pFileSystem)
103 pFileSystem->GetFileList(GCFiles);
107 OpenGameListItem = new GameListItem(fileName);
109 bRefreshList = false;
111 CreateGUIControls(DiscIO::IsVolumeWadFile(OpenISO));
113 GameIniFile = std::string(File::GetUserPath(D_GAMECONFIG_IDX)) + (OpenISO->GetUniqueID()) + ".ini";
114 if (GameIni.Load(GameIniFile.c_str()))
115 LoadGameConfig();
116 else
118 // Will fail out if GameConfig folder doesn't exist
119 FILE *f = fopen(GameIniFile.c_str(), "w");
120 if (f)
122 fprintf(f, "# %s - %s\n", OpenISO->GetUniqueID().c_str(), OpenISO->GetName().c_str());
123 fprintf(f, "[Core] Values set here will override the main dolphin settings.\n");
124 fprintf(f, "[EmuState] The Emulation State. 1 is worst, 5 is best, 0 is not set.\n");
125 fprintf(f, "[OnFrame] Add memory patches to be applied every frame here.\n");
126 fprintf(f, "[ActionReplay] Add action replay cheats here.\n");
127 fclose(f);
129 if (GameIni.Load(GameIniFile.c_str()))
130 LoadGameConfig();
131 else
132 wxMessageBox(wxString::Format(_("Could not create %s"), wxString::From8BitData(GameIniFile.c_str()).c_str()), _("Error"), wxOK|wxICON_ERROR, this);
135 // Disk header and apploader
136 m_Name->SetValue(wxString(OpenISO->GetName().c_str(), wxConvUTF8));
137 m_GameID->SetValue(wxString(OpenISO->GetUniqueID().c_str(), wxConvUTF8));
138 switch (OpenISO->GetCountry())
140 case DiscIO::IVolume::COUNTRY_EUROPE:
141 m_Country->SetValue(wxT("EUROPE"));
142 break;
143 case DiscIO::IVolume::COUNTRY_FRANCE:
144 m_Country->SetValue(wxT("FRANCE"));
145 break;
146 case DiscIO::IVolume::COUNTRY_ITALY:
147 m_Country->SetValue(wxT("ITALY"));
148 break;
149 case DiscIO::IVolume::COUNTRY_USA:
150 m_Country->SetValue(wxT("USA"));
151 m_Lang->SetSelection(0);
152 m_Lang->Disable(); // For NTSC Games, there's no multi lang
153 break;
154 case DiscIO::IVolume::COUNTRY_JAPAN:
155 m_Country->SetValue(wxT("JAPAN"));
156 m_Lang->SetSelection(-1);
157 m_Lang->Disable(); // For NTSC Games, there's no multi lang
158 break;
159 case DiscIO::IVolume::COUNTRY_KOREA:
160 m_Country->SetValue(wxT("KOREA"));
161 break;
162 case DiscIO::IVolume::COUNTRY_TAIWAN:
163 m_Country->SetValue(wxT("TAIWAN"));
164 m_Lang->SetSelection(-1);
165 m_Lang->Disable(); // For NTSC Games, there's no multi lang
166 break;
167 case DiscIO::IVolume::COUNTRY_SDK:
168 m_Country->SetValue(wxT("No Country (SDK)"));
169 break;
170 default:
171 m_Country->SetValue(wxT("UNKNOWN"));
172 break;
174 wxString temp = _T("0x") + wxString::From8BitData(OpenISO->GetMakerID().c_str());
175 m_MakerID->SetValue(temp);
176 m_Date->SetValue(wxString::From8BitData(OpenISO->GetApploaderDate().c_str()));
177 m_FST->SetValue(wxString::Format(_T("%u"), OpenISO->GetFSTSize()));
179 // Here we set all the info to be shown (be it SJIS or Ascii) + we set the window title
180 ChangeBannerDetails((int)SConfig::GetInstance().m_InterfaceLanguage);
181 m_Banner->SetBitmap(OpenGameListItem->GetImage());
182 m_Banner->Connect(wxID_ANY, wxEVT_RIGHT_DOWN,
183 wxMouseEventHandler(CISOProperties::RightClickOnBanner), (wxObject*)NULL, this);
185 // Filesystem browser/dumper
186 if (DiscIO::IsVolumeWiiDisc(OpenISO))
188 for (u32 i = 0; i < WiiDisc.size(); i++)
190 WiiPartition partition = WiiDisc.at(i);
191 wxTreeItemId PartitionRoot = m_Treectrl->AppendItem(RootId, wxString::Format(wxT("Partition %i"), i), 0, 0, 0);
192 CreateDirectoryTree(PartitionRoot, partition.Files, 1, partition.Files.at(0)->m_FileSize);
193 if (i == 1)
194 m_Treectrl->Expand(PartitionRoot);
197 else
199 // TODO : Should we add a way to browse the wad file ?
200 if (!DiscIO::IsVolumeWadFile(OpenISO))
202 if (!GCFiles.empty())
203 CreateDirectoryTree(RootId, GCFiles, 1, GCFiles.at(0)->m_FileSize);
206 m_Treectrl->Expand(RootId);
209 CISOProperties::~CISOProperties()
211 if (!IsVolumeWiiDisc(OpenISO))
212 if (!IsVolumeWadFile(OpenISO))
213 if (pFileSystem)
214 delete pFileSystem;
215 // two vector's items are no longer valid after deleting filesystem
216 WiiDisc.clear();
217 GCFiles.clear();
218 delete OpenGameListItem;
219 delete OpenISO;
222 size_t CISOProperties::CreateDirectoryTree(wxTreeItemId& parent,
223 std::vector<const DiscIO::SFileInfo*> fileInfos,
224 const size_t _FirstIndex,
225 const size_t _LastIndex)
227 size_t CurrentIndex = _FirstIndex;
229 while (CurrentIndex < _LastIndex)
231 const DiscIO::SFileInfo *rFileInfo = fileInfos[CurrentIndex];
232 char *name = (char*)rFileInfo->m_FullPath;
234 if (rFileInfo->IsDirectory()) name[strlen(name) - 1] = '\0';
235 char *itemName = strrchr(name, DIR_SEP_CHR);
237 if(!itemName)
238 itemName = name;
239 else
240 itemName++;
242 // check next index
243 if (rFileInfo->IsDirectory())
245 wxTreeItemId item = m_Treectrl->AppendItem(parent, wxString::From8BitData(itemName), 1, 1);
246 CurrentIndex = CreateDirectoryTree(item, fileInfos, CurrentIndex + 1, (size_t)rFileInfo->m_FileSize);
248 else
250 m_Treectrl->AppendItem(parent, wxString::From8BitData(itemName), 2, 2);
251 CurrentIndex++;
255 return CurrentIndex;
258 void CISOProperties::CreateGUIControls(bool IsWad)
260 m_Close = new wxButton(this, ID_CLOSE, _("Close"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
261 EditConfig = new wxButton(this, ID_EDITCONFIG, _("Edit Config"), wxDefaultPosition, wxDefaultSize);
262 EditConfig->SetToolTip(_("This will let you Manually Edit the INI config file"));
264 // Notebook
265 m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize);
266 m_GameConfig = new wxPanel(m_Notebook, ID_GAMECONFIG, wxDefaultPosition, wxDefaultSize);
267 m_Notebook->AddPage(m_GameConfig, _("GameConfig"));
268 m_PatchPage = new wxPanel(m_Notebook, ID_PATCH_PAGE, wxDefaultPosition, wxDefaultSize);
269 m_Notebook->AddPage(m_PatchPage, _("Patches"));
270 m_CheatPage = new wxPanel(m_Notebook, ID_ARCODE_PAGE, wxDefaultPosition, wxDefaultSize);
271 m_Notebook->AddPage(m_CheatPage, _("AR Codes"));
272 m_geckocode_panel = new Gecko::CodeConfigPanel(m_Notebook);
273 m_Notebook->AddPage(m_geckocode_panel, wxT("Gecko Codes"));
274 m_Information = new wxPanel(m_Notebook, ID_INFORMATION, wxDefaultPosition, wxDefaultSize);
275 m_Notebook->AddPage(m_Information, _("Info"));
276 m_Filesystem = new wxPanel(m_Notebook, ID_FILESYSTEM, wxDefaultPosition, wxDefaultSize);
277 m_Notebook->AddPage(m_Filesystem, _("Filesystem"));
279 wxBoxSizer* sButtons;
280 sButtons = new wxBoxSizer(wxHORIZONTAL);
281 sButtons->Add(EditConfig, 0, wxALL, 5);
282 sButtons->Add(0, 0, 1, wxEXPAND, 5);
283 sButtons->Add(m_Close, 0, wxALL, 5);
286 // GameConfig editing - Overrides and emulation state
287 sbGameConfig = new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("Game-Specific Settings"));
288 OverrideText = new wxStaticText(m_GameConfig, ID_OVERRIDE_TEXT, _("These settings override core Dolphin settings.\nUndetermined means the game uses Dolphin's setting."), wxDefaultPosition, wxDefaultSize);
289 // Core
290 sbCoreOverrides = new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("Core"));
291 CPUThread = new wxCheckBox(m_GameConfig, ID_USEDUALCORE, _("Enable Dual Core"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
292 SkipIdle = new wxCheckBox(m_GameConfig, ID_IDLESKIP, _("Enable Idle Skipping"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
293 MMU = new wxCheckBox(m_GameConfig, ID_MMU, _("Enable MMU"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
294 TLBHack = new wxCheckBox(m_GameConfig, ID_TLBHACK, _("MMU Speed Hack"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
295 SMC = new wxCheckBox(m_GameConfig, ID_MMU, _("Enable self modifying code check"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
296 // Wii Console
297 sbWiiOverrides = new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("Wii Console"));
298 EnableProgressiveScan = new wxCheckBox(m_GameConfig, ID_ENABLEPROGRESSIVESCAN, _("Enable Progressive Scan"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
299 EnableWideScreen = new wxCheckBox(m_GameConfig, ID_ENABLEWIDESCREEN, _("Enable WideScreen"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
300 if (!DiscIO::IsVolumeWiiDisc(OpenISO) && !DiscIO::IsVolumeWadFile(OpenISO))
302 sbWiiOverrides->ShowItems(false);
303 EnableProgressiveScan->Hide();
304 EnableWideScreen->Hide();
306 else
308 //Progressive Scan is not used by Dolphin itself,
309 //and changing it on a per-game basis would have the side-effect of changing the SysConf,
310 //making this setting rather useless.
311 EnableProgressiveScan->Disable();
313 // Video
314 sbVideoOverrides = new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("Video"));
315 ForceFiltering = new wxCheckBox(m_GameConfig, ID_FORCEFILTERING, _("Force Filtering"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
316 EFBCopyDisable = new wxCheckBox(m_GameConfig, ID_EFBCOPYDISABLE, _("Disable Copy to EFB"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
317 EFBToTextureEnable = new wxCheckBox(m_GameConfig, ID_EFBTOTEXTUREENABLE, _("Enable EFB To Texture"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
318 SafeTextureCache = new wxCheckBox(m_GameConfig, ID_SAFETEXTURECACHE, _("Safe Texture Cache"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
319 DstAlphaPass = new wxCheckBox(m_GameConfig, ID_DSTALPHAPASS, _("Distance Alpha Pass"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
320 UseXFB = new wxCheckBox(m_GameConfig, ID_USEXFB, _("Use XFB"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
321 UseZTPSpeedupHack = new wxCheckBox(m_GameConfig, ID_USEXFB, _("ZTP hack"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
322 UseZTPSpeedupHack->SetToolTip(wxT("Enable this to speed up The Legend of Zelda: Twilight Princess. Disable for ANY other game."));
323 // Hack
324 Hacktext = new wxStaticText(m_GameConfig, ID_HACK_TEXT, _("Projection Hack for: "), wxDefaultPosition, wxDefaultSize);
325 arrayStringFor_Hack.Add(_("None"));
326 arrayStringFor_Hack.Add(_("Zelda Twilight Princess Bloom hack"));
327 arrayStringFor_Hack.Add(_("Sonic and the Black Knight"));
328 arrayStringFor_Hack.Add(_("Bleach Versus Crusade"));
329 arrayStringFor_Hack.Add(_("Skies of Arcadia"));
330 Hack = new wxChoice(m_GameConfig, ID_HACK, wxDefaultPosition, wxDefaultSize, arrayStringFor_Hack, 0, wxDefaultValidator);
332 WMTightnessText = new wxStaticText(m_GameConfig, ID_WMTIGHTNESS_TEXT, wxT("Watermark tightness: "), wxDefaultPosition, wxDefaultSize);
333 WMTightness = new wxTextCtrl(m_GameConfig, ID_WMTIGHTNESS, wxT(""), wxDefaultPosition, wxDefaultSize, 0, wxTextValidator(wxFILTER_NUMERIC));
334 WMTightness->SetToolTip(wxT("Change this if you get lots of FIFO overflow errors. Reasonable values range from 0 to 1000."));
336 // Emulation State
337 sEmuState = new wxBoxSizer(wxHORIZONTAL);
338 EmuStateText = new wxStaticText(m_GameConfig, ID_EMUSTATE_TEXT, _("Emulation State: "), wxDefaultPosition, wxDefaultSize);
339 arrayStringFor_EmuState.Add(_("Not Set"));
340 arrayStringFor_EmuState.Add(_("Broken"));
341 arrayStringFor_EmuState.Add(_("Intro"));
342 arrayStringFor_EmuState.Add(_("In Game"));
343 arrayStringFor_EmuState.Add(_("Playable"));
344 arrayStringFor_EmuState.Add(_("Perfect"));
345 EmuState = new wxChoice(m_GameConfig, ID_EMUSTATE, wxDefaultPosition, wxDefaultSize, arrayStringFor_EmuState, 0, wxDefaultValidator);
346 EmuIssues = new wxTextCtrl(m_GameConfig, ID_EMU_ISSUES, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
348 wxBoxSizer* sConfigPage;
349 sConfigPage = new wxBoxSizer(wxVERTICAL);
350 sbGameConfig->Add(OverrideText, 0, wxEXPAND|wxALL, 5);
351 sbCoreOverrides->Add(CPUThread, 0, wxEXPAND|wxLEFT, 5);
352 sbCoreOverrides->Add(SkipIdle, 0, wxEXPAND|wxLEFT, 5);
353 sbCoreOverrides->Add(MMU, 0, wxEXPAND|wxLEFT, 5);
354 sbCoreOverrides->Add(TLBHack, 0, wxEXPAND|wxLEFT, 5);
355 sbCoreOverrides->Add(SMC, 0, wxEXPAND|wxLEFT, 5);
356 sbWiiOverrides->Add(EnableProgressiveScan, 0, wxEXPAND|wxLEFT, 5);
357 sbWiiOverrides->Add(EnableWideScreen, 0, wxEXPAND|wxLEFT, 5);
358 sbVideoOverrides->Add(ForceFiltering, 0, wxEXPAND|wxLEFT, 5);
359 sbVideoOverrides->Add(EFBCopyDisable, 0, wxEXPAND|wxLEFT, 5);
360 sbVideoOverrides->Add(EFBToTextureEnable, 0, wxEXPAND|wxLEFT, 5);
361 sbVideoOverrides->Add(SafeTextureCache, 0, wxEXPAND|wxLEFT, 5);
362 sbVideoOverrides->Add(DstAlphaPass, 0, wxEXPAND|wxLEFT, 5);
363 sbVideoOverrides->Add(UseXFB, 0, wxEXPAND|wxLEFT, 5);
364 sbVideoOverrides->Add(UseZTPSpeedupHack, 0, wxEXPAND|wxLEFT, 5);
366 wxFlexGridSizer* fifosizer = new wxFlexGridSizer(2, 2, 0, 0);
367 fifosizer->Add(Hacktext, 0, wxLEFT, 5);
368 fifosizer->Add(Hack, 0, wxEXPAND|wxLEFT, 5);
369 fifosizer->Add(WMTightnessText, 0, wxLEFT, 5);
370 fifosizer->Add(WMTightness, 0, wxEXPAND|wxLEFT, 5);
371 sbVideoOverrides->Add(fifosizer);
373 sbGameConfig->Add(sbCoreOverrides, 0, wxEXPAND);
374 sbGameConfig->Add(sbWiiOverrides, 0, wxEXPAND);
375 sbGameConfig->Add(sbVideoOverrides, 0, wxEXPAND);
376 sConfigPage->Add(sbGameConfig, 0, wxEXPAND|wxALL, 5);
377 sEmuState->Add(EmuStateText, 0, wxALIGN_CENTER_VERTICAL);
378 sEmuState->Add(EmuState, 0, wxEXPAND);
379 sEmuState->Add(EmuIssues,1,wxEXPAND);
380 sConfigPage->Add(sEmuState, 0, wxEXPAND|wxALL, 5);
381 m_GameConfig->SetSizer(sConfigPage);
382 sConfigPage->Layout();
385 // Patches
386 sPatches = new wxBoxSizer(wxVERTICAL);
387 Patches = new wxCheckListBox(m_PatchPage, ID_PATCHES_LIST, wxDefaultPosition, wxDefaultSize, arrayStringFor_Patches, wxLB_HSCROLL, wxDefaultValidator);
388 sPatchButtons = new wxBoxSizer(wxHORIZONTAL);
389 EditPatch = new wxButton(m_PatchPage, ID_EDITPATCH, _("Edit..."), wxDefaultPosition, wxDefaultSize, 0);
390 AddPatch = new wxButton(m_PatchPage, ID_ADDPATCH, _("Add..."), wxDefaultPosition, wxDefaultSize, 0);
391 RemovePatch = new wxButton(m_PatchPage, ID_REMOVEPATCH, _("Remove"), wxDefaultPosition, wxDefaultSize, 0);
392 EditPatch->Enable(false);
393 RemovePatch->Enable(false);
395 wxBoxSizer* sPatchPage;
396 sPatchPage = new wxBoxSizer(wxVERTICAL);
397 sPatches->Add(Patches, 1, wxEXPAND|wxALL, 0);
398 sPatchButtons->Add(EditPatch, 0, wxEXPAND|wxALL, 0);
399 sPatchButtons->AddStretchSpacer();
400 sPatchButtons->Add(AddPatch, 0, wxEXPAND|wxALL, 0);
401 sPatchButtons->Add(RemovePatch, 0, wxEXPAND|wxALL, 0);
402 sPatches->Add(sPatchButtons, 0, wxEXPAND|wxALL, 0);
403 sPatchPage->Add(sPatches, 1, wxEXPAND|wxALL, 5);
404 m_PatchPage->SetSizer(sPatchPage);
405 sPatchPage->Layout();
408 // Action Replay Cheats
409 sCheats = new wxBoxSizer(wxVERTICAL);
410 Cheats = new wxCheckListBox(m_CheatPage, ID_CHEATS_LIST, wxDefaultPosition, wxDefaultSize, arrayStringFor_Cheats, wxLB_HSCROLL, wxDefaultValidator);
411 sCheatButtons = new wxBoxSizer(wxHORIZONTAL);
412 EditCheat = new wxButton(m_CheatPage, ID_EDITCHEAT, _("Edit..."), wxDefaultPosition, wxDefaultSize, 0);
413 AddCheat = new wxButton(m_CheatPage, ID_ADDCHEAT, _("Add..."), wxDefaultPosition, wxDefaultSize, 0);
414 RemoveCheat = new wxButton(m_CheatPage, ID_REMOVECHEAT, _("Remove"), wxDefaultPosition, wxDefaultSize, 0);
415 EditCheat->Enable(false);
416 RemoveCheat->Enable(false);
418 wxBoxSizer* sCheatPage;
419 sCheatPage = new wxBoxSizer(wxVERTICAL);
420 sCheats->Add(Cheats, 1, wxEXPAND|wxALL, 0);
421 sCheatButtons->Add(EditCheat, 0, wxEXPAND|wxALL, 0);
422 sCheatButtons->AddStretchSpacer();
423 sCheatButtons->Add(AddCheat, 0, wxEXPAND|wxALL, 0);
424 sCheatButtons->Add(RemoveCheat, 0, wxEXPAND|wxALL, 0);
425 sCheats->Add(sCheatButtons, 0, wxEXPAND|wxALL, 0);
426 sCheatPage->Add(sCheats, 1, wxEXPAND|wxALL, 5);
427 m_CheatPage->SetSizer(sCheatPage);
428 sCheatPage->Layout();
431 m_NameText = new wxStaticText(m_Information, ID_NAME_TEXT, _("Name:"), wxDefaultPosition, wxDefaultSize);
432 m_Name = new wxTextCtrl(m_Information, ID_NAME, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
433 m_GameIDText = new wxStaticText(m_Information, ID_GAMEID_TEXT, _("Game ID:"), wxDefaultPosition, wxDefaultSize);
434 m_GameID = new wxTextCtrl(m_Information, ID_GAMEID, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
435 m_CountryText = new wxStaticText(m_Information, ID_COUNTRY_TEXT, _("Country:"), wxDefaultPosition, wxDefaultSize);
436 m_Country = new wxTextCtrl(m_Information, ID_COUNTRY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
437 m_MakerIDText = new wxStaticText(m_Information, ID_MAKERID_TEXT, _("Maker ID:"), wxDefaultPosition, wxDefaultSize);
438 m_MakerID = new wxTextCtrl(m_Information, ID_MAKERID, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
439 m_DateText = new wxStaticText(m_Information, ID_DATE_TEXT, _("Date:"), wxDefaultPosition, wxDefaultSize);
440 m_Date = new wxTextCtrl(m_Information, ID_DATE, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
441 m_FSTText = new wxStaticText(m_Information, ID_FST_TEXT, _("FST Size:"), wxDefaultPosition, wxDefaultSize);
442 m_FST = new wxTextCtrl(m_Information, ID_FST, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
444 m_LangText = new wxStaticText(m_Information, ID_LANG_TEXT, _("Show Language:"), wxDefaultPosition, wxDefaultSize);
445 arrayStringFor_Lang.Add(_("English"));
446 arrayStringFor_Lang.Add(_("German"));
447 arrayStringFor_Lang.Add(_("French"));
448 arrayStringFor_Lang.Add(_("Spanish"));
449 arrayStringFor_Lang.Add(_("Italian"));
450 arrayStringFor_Lang.Add(_("Dutch"));
451 m_Lang = new wxChoice(m_Information, ID_LANG, wxDefaultPosition, wxDefaultSize, arrayStringFor_Lang, 0, wxDefaultValidator);
452 m_Lang->SetSelection((int)SConfig::GetInstance().m_InterfaceLanguage);
453 m_ShortText = new wxStaticText(m_Information, ID_SHORTNAME_TEXT, _("Short Name:"), wxDefaultPosition, wxDefaultSize);
454 m_ShortName = new wxTextCtrl(m_Information, ID_SHORTNAME, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
455 m_MakerText = new wxStaticText(m_Information, ID_MAKER_TEXT, _("Maker:"), wxDefaultPosition, wxDefaultSize);
456 m_Maker = new wxTextCtrl(m_Information, ID_MAKER, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
457 m_CommentText = new wxStaticText(m_Information, ID_COMMENT_TEXT, _("Comment:"), wxDefaultPosition, wxDefaultSize);
458 m_Comment = new wxTextCtrl(m_Information, ID_COMMENT, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY);
459 m_BannerText = new wxStaticText(m_Information, ID_BANNER_TEXT, _("Banner:"), wxDefaultPosition, wxDefaultSize);
460 m_Banner = new wxStaticBitmap(m_Information, ID_BANNER, wxNullBitmap, wxDefaultPosition, wxSize(96, 32), 0);
462 // ISO Details
463 sISODetails = new wxGridBagSizer(0, 0);
464 sISODetails->Add(m_NameText, wxGBPosition(0, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
465 sISODetails->Add(m_Name, wxGBPosition(0, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
466 sISODetails->Add(m_GameIDText, wxGBPosition(1, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
467 sISODetails->Add(m_GameID, wxGBPosition(1, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
468 sISODetails->Add(m_CountryText, wxGBPosition(2, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
469 sISODetails->Add(m_Country, wxGBPosition(2, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
470 sISODetails->Add(m_MakerIDText, wxGBPosition(3, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
471 sISODetails->Add(m_MakerID, wxGBPosition(3, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
472 sISODetails->Add(m_DateText, wxGBPosition(4, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
473 sISODetails->Add(m_Date, wxGBPosition(4, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
474 sISODetails->Add(m_FSTText, wxGBPosition(5, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
475 sISODetails->Add(m_FST, wxGBPosition(5, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
476 sISODetails->AddGrowableCol(1);
477 sbISODetails = new wxStaticBoxSizer(wxVERTICAL, m_Information, _("ISO Details"));
478 sbISODetails->Add(sISODetails, 0, wxEXPAND, 5);
480 // Banner Details
481 sBannerDetails = new wxGridBagSizer(0, 0);
482 sBannerDetails->Add(m_LangText, wxGBPosition(0, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
483 sBannerDetails->Add(m_Lang, wxGBPosition(0, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
484 sBannerDetails->Add(m_ShortText, wxGBPosition(1, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
485 sBannerDetails->Add(m_ShortName, wxGBPosition(1, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
486 sBannerDetails->Add(m_MakerText, wxGBPosition(2, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
487 sBannerDetails->Add(m_Maker, wxGBPosition(2, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
488 sBannerDetails->Add(m_CommentText, wxGBPosition(3, 0), wxGBSpan(1, 1), wxALL, 5);
489 sBannerDetails->Add(m_Comment, wxGBPosition(3, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
490 sBannerDetails->Add(m_BannerText, wxGBPosition(4, 0), wxGBSpan(1, 1), wxALL, 5);
491 sBannerDetails->Add(m_Banner, wxGBPosition(4, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
492 sBannerDetails->AddGrowableCol(1);
493 sbBannerDetails = new wxStaticBoxSizer(wxVERTICAL, m_Information, _("Banner Details"));
494 sbBannerDetails->Add(sBannerDetails, 0, wxEXPAND, 5);
496 wxBoxSizer* sInfoPage;
497 sInfoPage = new wxBoxSizer(wxVERTICAL);
498 sInfoPage->Add(sbISODetails, 0, wxEXPAND|wxALL, 5);
499 sInfoPage->Add(sbBannerDetails, 0, wxEXPAND|wxALL, 5);
500 m_Information->SetSizer(sInfoPage);
501 sInfoPage->Layout();
503 // Filesystem icons
504 m_iconList = new wxImageList(16, 16);
505 m_iconList->Add(wxBitmap(disc_xpm), wxNullBitmap); // 0
506 m_iconList->Add(wxBitmap(folder_xpm), wxNullBitmap); // 1
507 m_iconList->Add(wxBitmap(file_xpm), wxNullBitmap); // 2
509 // Filesystem tree
510 m_Treectrl = new wxTreeCtrl(m_Filesystem, ID_TREECTRL, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE, wxDefaultValidator);
511 m_Treectrl->AssignImageList(m_iconList);
512 RootId = m_Treectrl->AddRoot(wxT("Disc"), 0, 0, 0);
514 wxBoxSizer* sTreePage;
515 sTreePage = new wxBoxSizer(wxVERTICAL);
516 sTreePage->Add(m_Treectrl, 1, wxEXPAND|wxALL, 5);
517 m_Filesystem->SetSizer(sTreePage);
518 sTreePage->Layout();
520 // It's a wad file, so we remove the FileSystem page
521 if (IsWad)
522 m_Notebook->RemovePage(4);
525 // Add notebook and buttons to the dialog
526 wxBoxSizer* sMain;
527 sMain = new wxBoxSizer(wxVERTICAL);
528 sMain->Add(m_Notebook, 1, wxEXPAND|wxALL, 5);
529 sMain->Add(sButtons, 0, wxEXPAND, 5);
530 sMain->SetMinSize(wxSize(550, 600));
532 m_Notebook->SetMaxSize(wxSize(550, 600));
533 SetSizerAndFit(sMain);
536 void CISOProperties::OnClose(wxCloseEvent& WXUNUSED (event))
538 if (!SaveGameConfig())
539 PanicAlert("Could not save %s", GameIniFile.c_str());
541 EndModal(bRefreshList ? wxID_OK : wxID_CANCEL);
544 void CISOProperties::OnCloseClick(wxCommandEvent& WXUNUSED (event))
546 Close();
549 void CISOProperties::RightClickOnBanner(wxMouseEvent& event)
551 wxMenu* popupMenu = new wxMenu;
552 popupMenu->Append(IDM_BNRSAVEAS, _("Save as..."));
553 PopupMenu(popupMenu);
555 event.Skip();
558 void CISOProperties::OnBannerImageSave(wxCommandEvent& WXUNUSED (event))
560 wxString dirHome;
562 wxFileDialog dialog(this, _("Save as..."), wxGetHomeDir(&dirHome), wxString::Format(_("%s.png"), m_GameID->GetLabel().c_str()),
563 _("*.*"), wxFD_SAVE|wxFD_OVERWRITE_PROMPT, wxDefaultPosition, wxDefaultSize);
564 if (dialog.ShowModal() == wxID_OK)
566 m_Banner->GetBitmap().ConvertToImage().SaveFile(dialog.GetPath());
570 void CISOProperties::OnRightClickOnTree(wxTreeEvent& event)
572 m_Treectrl->SelectItem(event.GetItem());
574 wxMenu* popupMenu = new wxMenu;
576 if (m_Treectrl->GetItemImage(m_Treectrl->GetSelection()) == 0
577 && m_Treectrl->GetFirstVisibleItem() != m_Treectrl->GetSelection())
578 popupMenu->Append(IDM_EXTRACTDIR, _("Extract Partition..."));
579 else if (m_Treectrl->GetItemImage(m_Treectrl->GetSelection()) == 1)
580 popupMenu->Append(IDM_EXTRACTDIR, _("Extract Directory..."));
581 else if (m_Treectrl->GetItemImage(m_Treectrl->GetSelection()) == 2)
582 popupMenu->Append(IDM_EXTRACTFILE, _("Extract File..."));
584 popupMenu->Append(IDM_EXTRACTALL, _("Extract All Files..."));
585 popupMenu->AppendSeparator();
586 popupMenu->Append(IDM_EXTRACTAPPLOADER, _("Extract Apploader..."));
587 popupMenu->Append(IDM_EXTRACTDOL, _("Extract DOL..."));
589 PopupMenu(popupMenu);
591 event.Skip();
594 void CISOProperties::OnExtractFile(wxCommandEvent& WXUNUSED (event))
596 wxString Path;
597 wxString File;
599 File = m_Treectrl->GetItemText(m_Treectrl->GetSelection());
601 Path = wxFileSelector(
602 wxT("Export File"),
603 wxEmptyString, File, wxEmptyString,
604 wxString::Format
606 wxT("All files (%s)|%s"),
607 wxFileSelectorDefaultWildcardStr,
608 wxFileSelectorDefaultWildcardStr
610 wxFD_SAVE,
611 this);
613 if (!Path || !File)
614 return;
616 while (m_Treectrl->GetItemParent(m_Treectrl->GetSelection()) != m_Treectrl->GetRootItem())
618 wxString temp;
619 temp = m_Treectrl->GetItemText(m_Treectrl->GetItemParent(m_Treectrl->GetSelection()));
620 File = temp + wxT(DIR_SEP_CHR) + File;
622 m_Treectrl->SelectItem(m_Treectrl->GetItemParent(m_Treectrl->GetSelection()));
625 if (DiscIO::IsVolumeWiiDisc(OpenISO))
627 int partitionNum = wxAtoi(File.SubString(10, 11));
628 File.Remove(0, 12); // Remove "Partition x/"
629 WiiDisc.at(partitionNum).FileSystem->ExportFile(File.mb_str(), Path.mb_str());
631 else
632 pFileSystem->ExportFile(File.mb_str(), Path.mb_str());
635 void CISOProperties::ExportDir(const char* _rFullPath, const char* _rExportFolder, const int partitionNum)
637 char exportName[512];
638 u32 index[2] = {0, 0}, offsetShift = 0;
639 std::vector<const DiscIO::SFileInfo *> fst;
640 DiscIO::IFileSystem *FS = 0;
642 if (DiscIO::IsVolumeWiiDisc(OpenISO))
644 FS = WiiDisc.at(partitionNum).FileSystem;
645 offsetShift = 2;
647 else
648 FS = pFileSystem;
650 FS->GetFileList(fst);
652 if (!_rFullPath) // Extract all
654 index[0] = 0;
655 index[1] = (u32)fst.size();
657 FS->ExportApploader(_rExportFolder);
658 if (!DiscIO::IsVolumeWiiDisc(OpenISO))
659 FS->ExportDOL(_rExportFolder);
661 else // Look for the dir we are going to extract
663 for(index[0] = 0; index[0] < fst.size(); index[0]++)
665 if (!strcmp(fst.at(index[0])->m_FullPath, _rFullPath))
667 DEBUG_LOG(DISCIO, "Found the Dir at %u", index[0]);
668 index[1] = (u32)fst.at(index[0])->m_FileSize;
669 break;
673 DEBUG_LOG(DISCIO,"Dir found from %u to %u\nextracting to:\n%s",index[0],index[1],_rExportFolder);
676 wxString dialogTitle = index[0] ? _T("Extracting Directory") : _T("Extracting All Files");
677 wxProgressDialog dialog(dialogTitle,
678 _T("Extracting..."),
679 index[1], // range
680 this, // parent
681 wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT |
682 wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME |
683 wxPD_SMOOTH // - makes indeterminate mode bar on WinXP very small
685 dialog.CenterOnParent();
687 // Extraction
688 for (u32 i = index[0]; i < index[1]; i++)
690 dialog.SetTitle(wxString::Format(_T("%s : %d%%"), dialogTitle.c_str(),
691 (u32)(((float)(i - index[0]) / (float)(index[1] - index[0])) * 100)));
692 if (!dialog.Update(i, wxString::Format(_T("Extracting %s"), wxString(fst[i]->m_FullPath, *wxConvCurrent).c_str())))
693 break;
695 if (fst[i]->IsDirectory())
697 snprintf(exportName, sizeof(exportName), "%s/%s/", _rExportFolder, fst[i]->m_FullPath);
698 DEBUG_LOG(DISCIO, "%s", exportName);
700 if (!File::Exists(exportName) && !File::CreateFullPath(exportName))
702 ERROR_LOG(DISCIO, "Could not create the path %s", exportName);
704 else
706 if (!File::IsDirectory(exportName))
707 ERROR_LOG(DISCIO, "%s already exists and is not a directory", exportName);
709 DEBUG_LOG(DISCIO, "folder %s already exists", exportName);
712 else
714 snprintf(exportName, sizeof(exportName), "%s/%s", _rExportFolder, fst[i]->m_FullPath);
715 DEBUG_LOG(DISCIO, "%s", exportName);
717 if (!File::Exists(exportName) && !FS->ExportFile(fst[i]->m_FullPath, exportName))
719 ERROR_LOG(DISCIO, "Could not export %s", exportName);
721 else
723 DEBUG_LOG(DISCIO, "%s already exists", exportName);
729 void CISOProperties::OnExtractDir(wxCommandEvent& event)
731 wxString Directory = m_Treectrl->GetItemText(m_Treectrl->GetSelection());
732 wxString Path = wxDirSelector(wxT("Choose the folder where to extract to"));
734 if (!Path || !Directory)
735 return;
737 if (event.GetId() == IDM_EXTRACTALL)
739 if (DiscIO::IsVolumeWiiDisc(OpenISO))
740 for (u32 i = 0; i < WiiDisc.size(); i++)
741 ExportDir(NULL, Path.mb_str(), i);
742 else
743 ExportDir(NULL, Path.mb_str());
745 return;
748 while (m_Treectrl->GetItemParent(m_Treectrl->GetSelection()) != m_Treectrl->GetRootItem())
750 wxString temp;
751 temp = m_Treectrl->GetItemText(m_Treectrl->GetItemParent(m_Treectrl->GetSelection()));
752 Directory = temp + wxT(DIR_SEP_CHR) + Directory;
754 m_Treectrl->SelectItem(m_Treectrl->GetItemParent(m_Treectrl->GetSelection()));
757 if (DiscIO::IsVolumeWiiDisc(OpenISO))
759 int partitionNum = wxAtoi(Directory.SubString(10, 11));
760 Directory.Remove(0, 12); // Remove "Partition x/"
761 ExportDir(Directory.mb_str(), Path.mb_str(), partitionNum);
763 else
764 ExportDir(Directory.mb_str(), Path.mb_str());
767 void CISOProperties::OnExtractDataFromHeader(wxCommandEvent& event)
769 std::vector<const DiscIO::SFileInfo *> fst;
770 DiscIO::IFileSystem *FS = 0;
771 wxString Path = wxDirSelector(wxT("Choose the folder to extract to"));
773 if (Path.empty())
774 return;
776 if (DiscIO::IsVolumeWiiDisc(OpenISO))
777 FS = WiiDisc.at(1).FileSystem;
778 else
779 FS = pFileSystem;
781 bool ret = false;
782 if (event.GetId() == IDM_EXTRACTAPPLOADER)
784 ret = FS->ExportApploader(Path.mb_str());
786 else if (event.GetId() == IDM_EXTRACTDOL)
788 ret = FS->ExportDOL(Path.mb_str());
791 if (!ret)
792 PanicAlert("Failed to extract to %s!", (const char *)Path.mb_str());
795 void CISOProperties::SetRefresh(wxCommandEvent& event)
797 bRefreshList = true;
799 if (event.GetId() == ID_EMUSTATE)
800 EmuIssues->Enable(event.GetSelection() != 0);
803 void CISOProperties::LoadGameConfig()
805 bool bTemp;
806 int iTemp;
807 std::string sTemp;
809 if (GameIni.Get("Core", "CPUThread", &bTemp))
810 CPUThread->Set3StateValue((wxCheckBoxState)bTemp);
811 else
812 CPUThread->Set3StateValue(wxCHK_UNDETERMINED);
814 if (GameIni.Get("Core", "SkipIdle", &bTemp))
815 SkipIdle->Set3StateValue((wxCheckBoxState)bTemp);
816 else
817 SkipIdle->Set3StateValue(wxCHK_UNDETERMINED);
819 if (GameIni.Get("Core", "MMU", &bTemp))
820 MMU->Set3StateValue((wxCheckBoxState)bTemp);
821 else
822 MMU->Set3StateValue(wxCHK_UNDETERMINED);
824 if (GameIni.Get("Core", "TLBHack", &bTemp))
825 TLBHack->Set3StateValue((wxCheckBoxState)bTemp);
826 else
827 TLBHack->Set3StateValue(wxCHK_UNDETERMINED);
829 if (GameIni.Get("Core", "SMC", &bTemp))
830 SMC->Set3StateValue((wxCheckBoxState)bTemp);
831 else
832 SMC->Set3StateValue(wxCHK_UNDETERMINED);
834 if (GameIni.Get("Wii", "ProgressiveScan", &bTemp))
835 EnableProgressiveScan->Set3StateValue((wxCheckBoxState)bTemp);
836 else
837 EnableProgressiveScan->Set3StateValue(wxCHK_UNDETERMINED);
839 if (GameIni.Get("Wii", "Widescreen", &bTemp))
840 EnableWideScreen->Set3StateValue((wxCheckBoxState)bTemp);
841 else
842 EnableWideScreen->Set3StateValue(wxCHK_UNDETERMINED);
844 if (GameIni.Get("Video", "ForceFiltering", &bTemp))
845 ForceFiltering->Set3StateValue((wxCheckBoxState)bTemp);
846 else
847 ForceFiltering->Set3StateValue(wxCHK_UNDETERMINED);
849 if (GameIni.Get("Video", "EFBCopyDisable", &bTemp))
850 EFBCopyDisable->Set3StateValue((wxCheckBoxState)bTemp);
851 else
852 EFBCopyDisable->Set3StateValue(wxCHK_UNDETERMINED);
854 if (GameIni.Get("Video", "EFBToTextureEnable", &bTemp))
855 EFBToTextureEnable->Set3StateValue((wxCheckBoxState)bTemp);
856 else
857 EFBToTextureEnable->Set3StateValue(wxCHK_UNDETERMINED);
859 if (GameIni.Get("Video", "SafeTextureCache", &bTemp))
860 SafeTextureCache->Set3StateValue((wxCheckBoxState)bTemp);
861 else
862 SafeTextureCache->Set3StateValue(wxCHK_UNDETERMINED);
864 if (GameIni.Get("Video", "DstAlphaPass", &bTemp))
865 DstAlphaPass->Set3StateValue((wxCheckBoxState)bTemp);
866 else
867 DstAlphaPass->Set3StateValue(wxCHK_UNDETERMINED);
869 if (GameIni.Get("Video", "UseXFB", &bTemp))
870 UseXFB->Set3StateValue((wxCheckBoxState)bTemp);
871 else
872 UseXFB->Set3StateValue(wxCHK_UNDETERMINED);
874 if (GameIni.Get("Video", "ZTPSpeedupHack", &bTemp))
875 UseZTPSpeedupHack->Set3StateValue((wxCheckBoxState)bTemp);
876 else
877 UseZTPSpeedupHack->Set3StateValue(wxCHK_UNDETERMINED);
879 if (GameIni.Get("Video", "FIFOWatermarkTightness", &sTemp))
880 WMTightness->SetValue(wxString(sTemp.c_str(), *wxConvCurrent));
881 else
882 WMTightness->SetValue(wxT("50"));
884 GameIni.Get("Video", "ProjectionHack", &iTemp, -1);
885 Hack->SetSelection(iTemp);
887 GameIni.Get("EmuState", "EmulationStateId", &iTemp, -1);
888 EmuState->SetSelection(iTemp);
890 GameIni.Get("EmuState", "EmulationIssues", &sTemp);
891 if (!sTemp.empty())
893 EmuIssues->SetValue(wxString(sTemp.c_str(), *wxConvCurrent));
894 bRefreshList = true;
896 EmuIssues->Enable(EmuState->GetSelection() != 0);
898 PatchList_Load();
899 ActionReplayList_Load();
900 m_geckocode_panel->LoadCodes(GameIni, OpenISO->GetUniqueID());
903 bool CISOProperties::SaveGameConfig()
905 if (CPUThread->Get3StateValue() == wxCHK_UNDETERMINED)
906 GameIni.DeleteKey("Core", "CPUThread");
907 else
908 GameIni.Set("Core", "CPUThread", CPUThread->Get3StateValue());
910 if (SkipIdle->Get3StateValue() == wxCHK_UNDETERMINED)
911 GameIni.DeleteKey("Core", "SkipIdle");
912 else
913 GameIni.Set("Core", "SkipIdle", SkipIdle->Get3StateValue());
915 if (MMU->Get3StateValue() == wxCHK_UNDETERMINED)
916 GameIni.DeleteKey("Core", "MMU");
917 else
918 GameIni.Set("Core", "MMU", MMU->Get3StateValue());
920 if (TLBHack->Get3StateValue() == wxCHK_UNDETERMINED)
921 GameIni.DeleteKey("Core", "TLBHack");
922 else
923 GameIni.Set("Core", "TLBHack", TLBHack->Get3StateValue());
925 if (SMC->Get3StateValue() == wxCHK_UNDETERMINED)
926 GameIni.DeleteKey("Core", "SMC");
927 else
928 GameIni.Set("Core", "SMC", SMC->Get3StateValue());
930 if (EnableProgressiveScan->Get3StateValue() == wxCHK_UNDETERMINED)
931 GameIni.DeleteKey("Wii", "ProgressiveScan");
932 else
933 GameIni.Set("Wii", "ProgressiveScan", EnableProgressiveScan->Get3StateValue());
935 if (EnableWideScreen->Get3StateValue() == wxCHK_UNDETERMINED)
936 GameIni.DeleteKey("Wii", "Widescreen");
937 else
938 GameIni.Set("Wii", "Widescreen", EnableWideScreen->Get3StateValue());
940 if (ForceFiltering->Get3StateValue() == wxCHK_UNDETERMINED)
941 GameIni.DeleteKey("Video", "ForceFiltering");
942 else
943 GameIni.Set("Video", "ForceFiltering", ForceFiltering->Get3StateValue());
945 if (EFBCopyDisable->Get3StateValue() == wxCHK_UNDETERMINED)
946 GameIni.DeleteKey("Video", "EFBCopyDisable");
947 else
948 GameIni.Set("Video", "EFBCopyDisable", EFBCopyDisable->Get3StateValue());
950 if (EFBToTextureEnable->Get3StateValue() == wxCHK_UNDETERMINED)
951 GameIni.DeleteKey("Video", "EFBToTextureEnable");
952 else
953 GameIni.Set("Video", "EFBToTextureEnable", EFBToTextureEnable->Get3StateValue());
955 if (SafeTextureCache->Get3StateValue() == wxCHK_UNDETERMINED)
956 GameIni.DeleteKey("Video", "SafeTextureCache");
957 else
958 GameIni.Set("Video", "SafeTextureCache", SafeTextureCache->Get3StateValue());
960 if (DstAlphaPass->Get3StateValue() == wxCHK_UNDETERMINED)
961 GameIni.DeleteKey("Video", "DstAlphaPass");
962 else
963 GameIni.Set("Video", "DstAlphaPass", DstAlphaPass->Get3StateValue());
965 if (UseXFB->Get3StateValue() == wxCHK_UNDETERMINED)
966 GameIni.DeleteKey("Video", "UseXFB");
967 else
968 GameIni.Set("Video", "UseXFB", UseXFB->Get3StateValue());
970 if (UseZTPSpeedupHack->Get3StateValue() == wxCHK_UNDETERMINED)
971 GameIni.DeleteKey("Video", "ZTPSpeedupHack");
972 else
973 GameIni.Set("Video", "ZTPSpeedupHack", UseZTPSpeedupHack->Get3StateValue());
975 if (Hack->GetSelection() == -1)
976 GameIni.DeleteKey("Video", "ProjectionHack");
977 else
978 GameIni.Set("Video", "ProjectionHack", Hack->GetSelection());
980 if (WMTightness->GetValue().size() == 0)
981 GameIni.DeleteKey("Video", "FIFOWatermarkTightness");
982 else
984 long val;
985 WMTightness->GetValue().ToLong(&val);
986 GameIni.Set("Video", "FIFOWatermarkTightness", (int)val);
989 if (EmuState->GetSelection() == -1)
990 GameIni.DeleteKey("EmuState", "EmulationStateId");
991 else
992 GameIni.Set("EmuState", "EmulationStateId", EmuState->GetSelection());
994 GameIni.Set("EmuState", "EmulationIssues", (const char*)EmuIssues->GetValue().mb_str(*wxConvCurrent));
996 PatchList_Save();
997 ActionReplayList_Save();
998 Gecko::SaveCodes(GameIni, m_geckocode_panel->GetCodes());
1000 return GameIni.Save(GameIniFile.c_str());
1003 void CISOProperties::OnEditConfig(wxCommandEvent& WXUNUSED (event))
1005 if (wxFileExists(wxString::From8BitData(GameIniFile.c_str())))
1007 SaveGameConfig();
1009 wxFileType* filetype = wxTheMimeTypesManager->GetFileTypeFromExtension(_("ini"));
1010 if(filetype == NULL) // From extension failed, trying with MIME type now
1012 filetype = wxTheMimeTypesManager->GetFileTypeFromMimeType(_("text/plain"));
1013 if(filetype == NULL) // MIME type failed, aborting mission
1015 PanicAlert("Filetype 'ini' is unknown! Will not open!");
1016 return;
1019 wxString OpenCommand;
1020 OpenCommand = filetype->GetOpenCommand(wxString::From8BitData(GameIniFile.c_str()));
1021 if(OpenCommand.IsEmpty())
1022 PanicAlert("Couldn't find open command for extension 'ini'!");
1023 else
1024 if(wxExecute(OpenCommand, wxEXEC_SYNC) == -1)
1025 PanicAlert("wxExecute returned -1 on application run!");
1027 GameIni.Load(GameIniFile.c_str());
1028 LoadGameConfig();
1030 bRefreshList = true; // Just in case
1033 // Once we're done with the ini edit, give the focus back to Dolphin
1034 SetFocus();
1037 void CISOProperties::ListSelectionChanged(wxCommandEvent& event)
1039 switch (event.GetId())
1041 case ID_PATCHES_LIST:
1042 if (Patches->GetSelection() != wxNOT_FOUND)
1044 EditPatch->Enable();
1045 RemovePatch->Enable();
1047 break;
1048 case ID_CHEATS_LIST:
1049 if (Cheats->GetSelection() != wxNOT_FOUND)
1051 EditCheat->Enable();
1052 RemoveCheat->Enable();
1054 break;
1058 void CISOProperties::PatchList_Load()
1060 onFrame.clear();
1061 Patches->Clear();
1062 PatchEngine::LoadPatchSection("OnFrame", onFrame, GameIni);
1064 u32 index = 0;
1065 for (std::vector<PatchEngine::Patch>::const_iterator it = onFrame.begin(); it != onFrame.end(); ++it)
1067 PatchEngine::Patch p = *it;
1068 Patches->Append(wxString(p.name.c_str(), *wxConvCurrent));
1069 Patches->Check(index, p.active);
1070 ++index;
1074 void CISOProperties::PatchList_Save()
1076 std::vector<std::string> lines;
1077 u32 index = 0;
1078 for (std::vector<PatchEngine::Patch>::const_iterator onFrame_it = onFrame.begin(); onFrame_it != onFrame.end(); ++onFrame_it)
1080 lines.push_back(Patches->IsChecked(index) ? "+$" + onFrame_it->name : "$" + onFrame_it->name);
1082 for (std::vector<PatchEngine::PatchEntry>::const_iterator iter2 = onFrame_it->entries.begin(); iter2 != onFrame_it->entries.end(); ++iter2)
1084 std::string temp;
1086 ToStringFromFormat(&temp, "0x%08X:%s:0x%08X", iter2->address, PatchEngine::PatchTypeStrings[iter2->type], iter2->value);
1087 lines.push_back(temp);
1089 ++index;
1091 GameIni.SetLines("OnFrame", lines);
1092 lines.clear();
1095 void CISOProperties::PatchButtonClicked(wxCommandEvent& event)
1097 int selection = Patches->GetSelection();
1099 switch (event.GetId())
1101 case ID_EDITPATCH:
1103 CPatchAddEdit dlg(selection, this);
1104 dlg.ShowModal();
1106 break;
1107 case ID_ADDPATCH:
1109 CPatchAddEdit dlg(-1, this, 1, _("Add Patch"));
1110 if (dlg.ShowModal() == wxID_OK)
1112 Patches->Append(wxString(onFrame.back().name.c_str(), *wxConvCurrent));
1113 Patches->Check((unsigned int)(onFrame.size() - 1), onFrame.back().active);
1116 break;
1117 case ID_REMOVEPATCH:
1118 onFrame.erase(onFrame.begin() + Patches->GetSelection());
1119 Patches->Delete(Cheats->GetSelection());
1120 break;
1123 PatchList_Save();
1124 Patches->Clear();
1125 PatchList_Load();
1127 EditPatch->Enable(false);
1128 RemovePatch->Enable(false);
1131 void CISOProperties::ActionReplayList_Load()
1133 arCodes.clear();
1134 Cheats->Clear();
1135 ActionReplay::LoadCodes(arCodes, GameIni);
1137 u32 index = 0;
1138 for (std::vector<ActionReplay::ARCode>::const_iterator it = arCodes.begin(); it != arCodes.end(); ++it)
1140 ActionReplay::ARCode arCode = *it;
1141 Cheats->Append(wxString(arCode.name.c_str(), *wxConvCurrent));
1142 Cheats->Check(index, arCode.active);
1143 ++index;
1147 void CISOProperties::ActionReplayList_Save()
1149 std::vector<std::string> lines;
1150 u32 index = 0;
1151 for (std::vector<ActionReplay::ARCode>::const_iterator iter = arCodes.begin(); iter != arCodes.end(); ++iter)
1153 ActionReplay::ARCode code = *iter;
1155 lines.push_back(Cheats->IsChecked(index) ? "+$" + code.name : "$" + code.name);
1157 for (std::vector<ActionReplay::AREntry>::const_iterator iter2 = code.ops.begin(); iter2 != code.ops.end(); ++iter2)
1159 lines.push_back(std::string(wxString::Format(wxT("%08X %08X"), iter2->cmd_addr, iter2->value).mb_str()));
1161 ++index;
1163 GameIni.SetLines("ActionReplay", lines);
1166 void CISOProperties::ActionReplayButtonClicked(wxCommandEvent& event)
1168 int selection = Cheats->GetSelection();
1170 switch (event.GetId())
1172 case ID_EDITCHEAT:
1174 CARCodeAddEdit dlg(selection, this);
1175 dlg.ShowModal();
1177 break;
1178 case ID_ADDCHEAT:
1180 CARCodeAddEdit dlg(-1, this, 1, _("Add ActionReplay Code"));
1181 if (dlg.ShowModal() == wxID_OK)
1183 Cheats->Append(wxString::From8BitData(arCodes.back().name.c_str()));
1184 Cheats->Check((unsigned int)(arCodes.size() - 1), arCodes.back().active);
1187 break;
1188 case ID_REMOVECHEAT:
1189 arCodes.erase(arCodes.begin() + Cheats->GetSelection());
1190 Cheats->Delete(Cheats->GetSelection());
1191 break;
1194 ActionReplayList_Save();
1195 Cheats->Clear();
1196 ActionReplayList_Load();
1198 EditCheat->Enable(false);
1199 RemoveCheat->Enable(false);
1202 void CISOProperties::OnChangeBannerLang(wxCommandEvent& event)
1204 ChangeBannerDetails(event.GetSelection());
1207 void CISOProperties::ChangeBannerDetails(int lang)
1209 if (OpenGameListItem->GetCountry() == DiscIO::IVolume::COUNTRY_JAPAN
1210 || OpenGameListItem->GetCountry() == DiscIO::IVolume::COUNTRY_TAIWAN
1211 || OpenGameListItem->GetPlatform() == GameListItem::WII_WAD)
1213 #ifdef __linux__
1214 wxCSConv SJISConv(wxFontMapper::GetEncodingName(wxFONTENCODING_EUC_JP));
1215 #else
1216 wxCSConv SJISConv(wxFontMapper::GetEncodingName(wxFONTENCODING_SHIFT_JIS));
1217 #endif
1218 wxString name = wxString(OpenGameListItem->GetName(0).c_str(), SJISConv);
1220 // Updates the informations shown in the window
1221 m_ShortName->SetValue(name);
1222 m_Comment->SetValue(wxString(OpenGameListItem->GetDescription(0).c_str(), SJISConv));
1223 m_Maker->SetValue(wxString(OpenGameListItem->GetCompany().c_str(), SJISConv));//dev too
1225 std::string filename, extension;
1226 SplitPath(OpenGameListItem->GetFileName(), 0, &filename, &extension);
1228 // Also sets the window's title
1229 SetTitle(wxString::Format(wxT("%s%s"),
1230 wxString(StringFromFormat("%s%s: %s - ", filename.c_str(), extension.c_str(), OpenGameListItem->GetUniqueID().c_str()).c_str(), *wxConvCurrent).c_str(),
1231 name.c_str()));
1233 else // Do the same for PAL/US Games (assuming ISO 8859-1)
1235 wxString name = wxString::From8BitData(OpenGameListItem->GetName(lang).c_str());
1237 m_ShortName->SetValue(name);
1238 m_Comment->SetValue(wxString::From8BitData(OpenGameListItem->GetDescription(lang).c_str()));
1239 m_Maker->SetValue(wxString::From8BitData(OpenGameListItem->GetCompany().c_str()));//dev too
1241 std::string filename, extension;
1242 SplitPath(OpenGameListItem->GetFileName(), 0, &filename, &extension);
1244 SetTitle(wxString::Format(wxT("%s%s"),
1245 wxString::From8BitData(StringFromFormat("%s%s: %s - ", filename.c_str(), extension.c_str(), OpenGameListItem->GetUniqueID().c_str()).c_str()).c_str(),
1246 name.c_str()));