StringUtil cleanup. Nothing seems broken.
[dolphin.git] / Source / Core / DolphinWX / Src / ISOProperties.cpp
blob7ecda54a78863a47d86199912c167d9981a3d1b9
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_RUSSIA:
150 m_Country->SetValue(wxT("RUSSIA"));
151 break;
152 case DiscIO::IVolume::COUNTRY_USA:
153 m_Country->SetValue(wxT("USA"));
154 m_Lang->SetSelection(0);
155 m_Lang->Disable(); // For NTSC Games, there's no multi lang
156 break;
157 case DiscIO::IVolume::COUNTRY_JAPAN:
158 m_Country->SetValue(wxT("JAPAN"));
159 m_Lang->SetSelection(-1);
160 m_Lang->Disable(); // For NTSC Games, there's no multi lang
161 break;
162 case DiscIO::IVolume::COUNTRY_KOREA:
163 m_Country->SetValue(wxT("KOREA"));
164 break;
165 case DiscIO::IVolume::COUNTRY_TAIWAN:
166 m_Country->SetValue(wxT("TAIWAN"));
167 m_Lang->SetSelection(-1);
168 m_Lang->Disable(); // For NTSC Games, there's no multi lang
169 break;
170 case DiscIO::IVolume::COUNTRY_SDK:
171 m_Country->SetValue(wxT("No Country (SDK)"));
172 break;
173 default:
174 m_Country->SetValue(wxT("UNKNOWN"));
175 break;
177 wxString temp = _T("0x") + wxString::From8BitData(OpenISO->GetMakerID().c_str());
178 m_MakerID->SetValue(temp);
179 m_Date->SetValue(wxString::From8BitData(OpenISO->GetApploaderDate().c_str()));
180 m_FST->SetValue(wxString::Format(_T("%u"), OpenISO->GetFSTSize()));
182 // Here we set all the info to be shown (be it SJIS or Ascii) + we set the window title
183 ChangeBannerDetails((int)SConfig::GetInstance().m_InterfaceLanguage);
184 m_Banner->SetBitmap(OpenGameListItem->GetImage());
185 m_Banner->Connect(wxID_ANY, wxEVT_RIGHT_DOWN,
186 wxMouseEventHandler(CISOProperties::RightClickOnBanner), (wxObject*)NULL, this);
188 // Filesystem browser/dumper
189 if (DiscIO::IsVolumeWiiDisc(OpenISO))
191 for (u32 i = 0; i < WiiDisc.size(); i++)
193 WiiPartition partition = WiiDisc.at(i);
194 wxTreeItemId PartitionRoot = m_Treectrl->AppendItem(RootId, wxString::Format(wxT("Partition %i"), i), 0, 0, 0);
195 CreateDirectoryTree(PartitionRoot, partition.Files, 1, partition.Files.at(0)->m_FileSize);
196 if (i == 1)
197 m_Treectrl->Expand(PartitionRoot);
200 else
202 // TODO : Should we add a way to browse the wad file ?
203 if (!DiscIO::IsVolumeWadFile(OpenISO))
205 if (!GCFiles.empty())
206 CreateDirectoryTree(RootId, GCFiles, 1, GCFiles.at(0)->m_FileSize);
209 m_Treectrl->Expand(RootId);
212 CISOProperties::~CISOProperties()
214 if (!IsVolumeWiiDisc(OpenISO))
215 if (!IsVolumeWadFile(OpenISO))
216 if (pFileSystem)
217 delete pFileSystem;
218 // two vector's items are no longer valid after deleting filesystem
219 WiiDisc.clear();
220 GCFiles.clear();
221 delete OpenGameListItem;
222 delete OpenISO;
225 size_t CISOProperties::CreateDirectoryTree(wxTreeItemId& parent,
226 std::vector<const DiscIO::SFileInfo*> fileInfos,
227 const size_t _FirstIndex,
228 const size_t _LastIndex)
230 size_t CurrentIndex = _FirstIndex;
232 while (CurrentIndex < _LastIndex)
234 const DiscIO::SFileInfo *rFileInfo = fileInfos[CurrentIndex];
235 char *name = (char*)rFileInfo->m_FullPath;
237 if (rFileInfo->IsDirectory()) name[strlen(name) - 1] = '\0';
238 char *itemName = strrchr(name, DIR_SEP_CHR);
240 if(!itemName)
241 itemName = name;
242 else
243 itemName++;
245 // check next index
246 if (rFileInfo->IsDirectory())
248 wxTreeItemId item = m_Treectrl->AppendItem(parent, wxString::From8BitData(itemName), 1, 1);
249 CurrentIndex = CreateDirectoryTree(item, fileInfos, CurrentIndex + 1, (size_t)rFileInfo->m_FileSize);
251 else
253 m_Treectrl->AppendItem(parent, wxString::From8BitData(itemName), 2, 2);
254 CurrentIndex++;
258 return CurrentIndex;
261 void CISOProperties::CreateGUIControls(bool IsWad)
263 m_Close = new wxButton(this, ID_CLOSE, _("Close"), wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
264 EditConfig = new wxButton(this, ID_EDITCONFIG, _("Edit Config"), wxDefaultPosition, wxDefaultSize);
265 EditConfig->SetToolTip(_("This will let you Manually Edit the INI config file"));
267 // Notebook
268 m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize);
269 m_GameConfig = new wxPanel(m_Notebook, ID_GAMECONFIG, wxDefaultPosition, wxDefaultSize);
270 m_Notebook->AddPage(m_GameConfig, _("GameConfig"));
271 m_PatchPage = new wxPanel(m_Notebook, ID_PATCH_PAGE, wxDefaultPosition, wxDefaultSize);
272 m_Notebook->AddPage(m_PatchPage, _("Patches"));
273 m_CheatPage = new wxPanel(m_Notebook, ID_ARCODE_PAGE, wxDefaultPosition, wxDefaultSize);
274 m_Notebook->AddPage(m_CheatPage, _("AR Codes"));
275 m_geckocode_panel = new Gecko::CodeConfigPanel(m_Notebook);
276 m_Notebook->AddPage(m_geckocode_panel, wxT("Gecko Codes"));
277 m_Information = new wxPanel(m_Notebook, ID_INFORMATION, wxDefaultPosition, wxDefaultSize);
278 m_Notebook->AddPage(m_Information, _("Info"));
279 m_Filesystem = new wxPanel(m_Notebook, ID_FILESYSTEM, wxDefaultPosition, wxDefaultSize);
280 m_Notebook->AddPage(m_Filesystem, _("Filesystem"));
282 wxBoxSizer* sButtons;
283 sButtons = new wxBoxSizer(wxHORIZONTAL);
284 sButtons->Add(EditConfig, 0, wxALL, 5);
285 sButtons->Add(0, 0, 1, wxEXPAND, 5);
286 sButtons->Add(m_Close, 0, wxALL, 5);
289 // GameConfig editing - Overrides and emulation state
290 sbGameConfig = new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("Game-Specific Settings"));
291 OverrideText = new wxStaticText(m_GameConfig, ID_OVERRIDE_TEXT, _("These settings override core Dolphin settings.\nUndetermined means the game uses Dolphin's setting."), wxDefaultPosition, wxDefaultSize);
292 // Core
293 sbCoreOverrides = new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("Core"));
294 CPUThread = new wxCheckBox(m_GameConfig, ID_USEDUALCORE, _("Enable Dual Core"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
295 SkipIdle = new wxCheckBox(m_GameConfig, ID_IDLESKIP, _("Enable Idle Skipping"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
296 MMU = new wxCheckBox(m_GameConfig, ID_MMU, _("Enable MMU"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
297 MMU->SetToolTip(wxT("Enables the Memory Management Unit, needed for some games. (ON = Compatible, OFF = Fast)"));
298 MMUBAT = new wxCheckBox(m_GameConfig, ID_MMUBAT, _("Enable BAT"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
299 MMUBAT->SetToolTip(wxT("Enables Block Address Translation (BAT); a function of the Memory Management Unit. Accurate to the hardware, but slow to emulate. (ON = Compatible, OFF = Fast)"));
300 TLBHack = new wxCheckBox(m_GameConfig, ID_TLBHACK, _("MMU Speed Hack"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
301 TLBHack->SetToolTip(wxT("Fast version of the MMU. Does not work for every game."));
302 AlternateRFI = new wxCheckBox(m_GameConfig, ID_RFI, _("Alternate RFI"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
303 AlternateRFI->SetToolTip(wxT("If a game hangs, works only in the Interpreter or Dolphin crashes, this option may fix the game."));
304 FastDiscSpeed = new wxCheckBox(m_GameConfig, ID_DISCSPEED, _("Speed up Disc Transfer Rate"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
305 FastDiscSpeed->SetToolTip(wxT("Enable fast disc access. Needed for a few games. (ON = Fast, OFF = Compatible)"));
306 BlockMerging = new wxCheckBox(m_GameConfig, ID_MERGEBLOCKS, _("Enable Block Merging"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
308 // Wii Console
309 sbWiiOverrides = new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("Wii Console"));
310 EnableProgressiveScan = new wxCheckBox(m_GameConfig, ID_ENABLEPROGRESSIVESCAN, _("Enable Progressive Scan"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
311 EnableWideScreen = new wxCheckBox(m_GameConfig, ID_ENABLEWIDESCREEN, _("Enable WideScreen"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
312 if (!DiscIO::IsVolumeWiiDisc(OpenISO) && !DiscIO::IsVolumeWadFile(OpenISO))
314 sbWiiOverrides->ShowItems(false);
315 EnableProgressiveScan->Hide();
316 EnableWideScreen->Hide();
318 else
320 //Progressive Scan is not used by Dolphin itself,
321 //and changing it on a per-game basis would have the side-effect of changing the SysConf,
322 //making this setting rather useless.
323 EnableProgressiveScan->Disable();
325 // Video
326 sbVideoOverrides = new wxStaticBoxSizer(wxVERTICAL, m_GameConfig, _("Video"));
327 ForceFiltering = new wxCheckBox(m_GameConfig, ID_FORCEFILTERING, _("Force Filtering"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
328 EFBCopyDisable = new wxCheckBox(m_GameConfig, ID_EFBCOPYDISABLE, _("Disable Copy to EFB"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
329 EFBToTextureEnable = new wxCheckBox(m_GameConfig, ID_EFBTOTEXTUREENABLE, _("Enable EFB To Texture"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
330 SafeTextureCache = new wxCheckBox(m_GameConfig, ID_SAFETEXTURECACHE, _("Safe Texture Cache"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
331 DstAlphaPass = new wxCheckBox(m_GameConfig, ID_DSTALPHAPASS, _("Distance Alpha Pass"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
332 UseXFB = new wxCheckBox(m_GameConfig, ID_USEXFB, _("Use XFB"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
333 UseZTPSpeedupHack = new wxCheckBox(m_GameConfig, ID_ZTP_SPEEDUP, _("ZTP hack"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
334 UseZTPSpeedupHack->SetToolTip(wxT("Enable this to speed up The Legend of Zelda: Twilight Princess. Disable for ANY other game."));
335 DListCache = new wxCheckBox(m_GameConfig, ID_DLISTCACHE, _("DList Cache"), wxDefaultPosition, wxDefaultSize, wxCHK_3STATE|wxCHK_ALLOW_3RD_STATE_FOR_USER, wxDefaultValidator);
336 // Hack
337 Hacktext = new wxStaticText(m_GameConfig, ID_HACK_TEXT, _("Projection Hack for: "), wxDefaultPosition, wxDefaultSize);
338 arrayStringFor_Hack.Add(_("None"));
339 arrayStringFor_Hack.Add(_("Zelda Twilight Princess Bloom hack"));
340 arrayStringFor_Hack.Add(_("Sonic and the Black Knight"));
341 arrayStringFor_Hack.Add(_("Bleach Versus Crusade"));
342 arrayStringFor_Hack.Add(_("Skies of Arcadia"));
343 Hack = new wxChoice(m_GameConfig, ID_HACK, wxDefaultPosition, wxDefaultSize, arrayStringFor_Hack, 0, wxDefaultValidator);
345 WMTightnessText = new wxStaticText(m_GameConfig, ID_WMTIGHTNESS_TEXT, wxT("Watermark tightness: "), wxDefaultPosition, wxDefaultSize);
346 WMTightness = new wxTextCtrl(m_GameConfig, ID_WMTIGHTNESS, wxT(""), wxDefaultPosition, wxDefaultSize, 0, wxTextValidator(wxFILTER_NUMERIC));
347 WMTightness->SetToolTip(wxT("Change this if you get lots of FIFO overflow errors. Reasonable values range from 0 to 1000."));
349 // Emulation State
350 sEmuState = new wxBoxSizer(wxHORIZONTAL);
351 EmuStateText = new wxStaticText(m_GameConfig, ID_EMUSTATE_TEXT, _("Emulation State: "), wxDefaultPosition, wxDefaultSize);
352 arrayStringFor_EmuState.Add(_("Not Set"));
353 arrayStringFor_EmuState.Add(_("Broken"));
354 arrayStringFor_EmuState.Add(_("Intro"));
355 arrayStringFor_EmuState.Add(_("In Game"));
356 arrayStringFor_EmuState.Add(_("Playable"));
357 arrayStringFor_EmuState.Add(_("Perfect"));
358 EmuState = new wxChoice(m_GameConfig, ID_EMUSTATE, wxDefaultPosition, wxDefaultSize, arrayStringFor_EmuState, 0, wxDefaultValidator);
359 EmuIssues = new wxTextCtrl(m_GameConfig, ID_EMU_ISSUES, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator);
361 wxBoxSizer* sConfigPage;
362 sConfigPage = new wxBoxSizer(wxVERTICAL);
363 sbGameConfig->Add(OverrideText, 0, wxEXPAND|wxALL, 5);
364 sbCoreOverrides->Add(CPUThread, 0, wxEXPAND|wxLEFT, 5);
365 sbCoreOverrides->Add(SkipIdle, 0, wxEXPAND|wxLEFT, 5);
366 sbCoreOverrides->Add(MMU, 0, wxEXPAND|wxLEFT, 5);
367 sbCoreOverrides->Add(MMUBAT, 0, wxEXPAND|wxLEFT, 5);
368 sbCoreOverrides->Add(TLBHack, 0, wxEXPAND|wxLEFT, 5);
369 sbCoreOverrides->Add(AlternateRFI, 0, wxEXPAND|wxLEFT, 5);
370 sbCoreOverrides->Add(FastDiscSpeed, 0, wxEXPAND|wxLEFT, 5);
371 sbCoreOverrides->Add(BlockMerging, 0, wxEXPAND|wxLEFT, 5);
372 sbWiiOverrides->Add(EnableProgressiveScan, 0, wxEXPAND|wxLEFT, 5);
373 sbWiiOverrides->Add(EnableWideScreen, 0, wxEXPAND|wxLEFT, 5);
374 sbVideoOverrides->Add(ForceFiltering, 0, wxEXPAND|wxLEFT, 5);
375 sbVideoOverrides->Add(EFBCopyDisable, 0, wxEXPAND|wxLEFT, 5);
376 sbVideoOverrides->Add(EFBToTextureEnable, 0, wxEXPAND|wxLEFT, 5);
377 sbVideoOverrides->Add(SafeTextureCache, 0, wxEXPAND|wxLEFT, 5);
378 sbVideoOverrides->Add(DstAlphaPass, 0, wxEXPAND|wxLEFT, 5);
379 sbVideoOverrides->Add(UseXFB, 0, wxEXPAND|wxLEFT, 5);
380 sbVideoOverrides->Add(UseZTPSpeedupHack, 0, wxEXPAND|wxLEFT, 5);
381 sbVideoOverrides->Add(DListCache, 0, wxEXPAND|wxLEFT, 5);
383 wxFlexGridSizer* fifosizer = new wxFlexGridSizer(2, 2, 0, 0);
384 fifosizer->Add(Hacktext, 0, wxLEFT, 5);
385 fifosizer->Add(Hack, 0, wxEXPAND|wxLEFT, 5);
386 fifosizer->Add(WMTightnessText, 0, wxLEFT, 5);
387 fifosizer->Add(WMTightness, 0, wxEXPAND|wxLEFT, 5);
388 sbVideoOverrides->Add(fifosizer);
390 sbGameConfig->Add(sbCoreOverrides, 0, wxEXPAND);
391 sbGameConfig->Add(sbWiiOverrides, 0, wxEXPAND);
392 sbGameConfig->Add(sbVideoOverrides, 0, wxEXPAND);
393 sConfigPage->Add(sbGameConfig, 0, wxEXPAND|wxALL, 5);
394 sEmuState->Add(EmuStateText, 0, wxALIGN_CENTER_VERTICAL);
395 sEmuState->Add(EmuState, 0, wxEXPAND);
396 sEmuState->Add(EmuIssues,1,wxEXPAND);
397 sConfigPage->Add(sEmuState, 0, wxEXPAND|wxALL, 5);
398 m_GameConfig->SetSizer(sConfigPage);
399 sConfigPage->Layout();
402 // Patches
403 sPatches = new wxBoxSizer(wxVERTICAL);
404 Patches = new wxCheckListBox(m_PatchPage, ID_PATCHES_LIST, wxDefaultPosition, wxDefaultSize, arrayStringFor_Patches, wxLB_HSCROLL, wxDefaultValidator);
405 sPatchButtons = new wxBoxSizer(wxHORIZONTAL);
406 EditPatch = new wxButton(m_PatchPage, ID_EDITPATCH, _("Edit..."), wxDefaultPosition, wxDefaultSize, 0);
407 AddPatch = new wxButton(m_PatchPage, ID_ADDPATCH, _("Add..."), wxDefaultPosition, wxDefaultSize, 0);
408 RemovePatch = new wxButton(m_PatchPage, ID_REMOVEPATCH, _("Remove"), wxDefaultPosition, wxDefaultSize, 0);
409 EditPatch->Enable(false);
410 RemovePatch->Enable(false);
412 wxBoxSizer* sPatchPage;
413 sPatchPage = new wxBoxSizer(wxVERTICAL);
414 sPatches->Add(Patches, 1, wxEXPAND|wxALL, 0);
415 sPatchButtons->Add(EditPatch, 0, wxEXPAND|wxALL, 0);
416 sPatchButtons->AddStretchSpacer();
417 sPatchButtons->Add(AddPatch, 0, wxEXPAND|wxALL, 0);
418 sPatchButtons->Add(RemovePatch, 0, wxEXPAND|wxALL, 0);
419 sPatches->Add(sPatchButtons, 0, wxEXPAND|wxALL, 0);
420 sPatchPage->Add(sPatches, 1, wxEXPAND|wxALL, 5);
421 m_PatchPage->SetSizer(sPatchPage);
422 sPatchPage->Layout();
425 // Action Replay Cheats
426 sCheats = new wxBoxSizer(wxVERTICAL);
427 Cheats = new wxCheckListBox(m_CheatPage, ID_CHEATS_LIST, wxDefaultPosition, wxDefaultSize, arrayStringFor_Cheats, wxLB_HSCROLL, wxDefaultValidator);
428 sCheatButtons = new wxBoxSizer(wxHORIZONTAL);
429 EditCheat = new wxButton(m_CheatPage, ID_EDITCHEAT, _("Edit..."), wxDefaultPosition, wxDefaultSize, 0);
430 AddCheat = new wxButton(m_CheatPage, ID_ADDCHEAT, _("Add..."), wxDefaultPosition, wxDefaultSize, 0);
431 RemoveCheat = new wxButton(m_CheatPage, ID_REMOVECHEAT, _("Remove"), wxDefaultPosition, wxDefaultSize, 0);
432 EditCheat->Enable(false);
433 RemoveCheat->Enable(false);
435 wxBoxSizer* sCheatPage;
436 sCheatPage = new wxBoxSizer(wxVERTICAL);
437 sCheats->Add(Cheats, 1, wxEXPAND|wxALL, 0);
438 sCheatButtons->Add(EditCheat, 0, wxEXPAND|wxALL, 0);
439 sCheatButtons->AddStretchSpacer();
440 sCheatButtons->Add(AddCheat, 0, wxEXPAND|wxALL, 0);
441 sCheatButtons->Add(RemoveCheat, 0, wxEXPAND|wxALL, 0);
442 sCheats->Add(sCheatButtons, 0, wxEXPAND|wxALL, 0);
443 sCheatPage->Add(sCheats, 1, wxEXPAND|wxALL, 5);
444 m_CheatPage->SetSizer(sCheatPage);
445 sCheatPage->Layout();
448 m_NameText = new wxStaticText(m_Information, ID_NAME_TEXT, _("Name:"), wxDefaultPosition, wxDefaultSize);
449 m_Name = new wxTextCtrl(m_Information, ID_NAME, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
450 m_GameIDText = new wxStaticText(m_Information, ID_GAMEID_TEXT, _("Game ID:"), wxDefaultPosition, wxDefaultSize);
451 m_GameID = new wxTextCtrl(m_Information, ID_GAMEID, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
452 m_CountryText = new wxStaticText(m_Information, ID_COUNTRY_TEXT, _("Country:"), wxDefaultPosition, wxDefaultSize);
453 m_Country = new wxTextCtrl(m_Information, ID_COUNTRY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
454 m_MakerIDText = new wxStaticText(m_Information, ID_MAKERID_TEXT, _("Maker ID:"), wxDefaultPosition, wxDefaultSize);
455 m_MakerID = new wxTextCtrl(m_Information, ID_MAKERID, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
456 m_DateText = new wxStaticText(m_Information, ID_DATE_TEXT, _("Date:"), wxDefaultPosition, wxDefaultSize);
457 m_Date = new wxTextCtrl(m_Information, ID_DATE, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
458 m_FSTText = new wxStaticText(m_Information, ID_FST_TEXT, _("FST Size:"), wxDefaultPosition, wxDefaultSize);
459 m_FST = new wxTextCtrl(m_Information, ID_FST, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
461 m_LangText = new wxStaticText(m_Information, ID_LANG_TEXT, _("Show Language:"), wxDefaultPosition, wxDefaultSize);
462 arrayStringFor_Lang.Add(_("English"));
463 arrayStringFor_Lang.Add(_("German"));
464 arrayStringFor_Lang.Add(_("French"));
465 arrayStringFor_Lang.Add(_("Spanish"));
466 arrayStringFor_Lang.Add(_("Italian"));
467 arrayStringFor_Lang.Add(_("Dutch"));
468 m_Lang = new wxChoice(m_Information, ID_LANG, wxDefaultPosition, wxDefaultSize, arrayStringFor_Lang, 0, wxDefaultValidator);
469 m_Lang->SetSelection((int)SConfig::GetInstance().m_InterfaceLanguage);
470 m_ShortText = new wxStaticText(m_Information, ID_SHORTNAME_TEXT, _("Short Name:"), wxDefaultPosition, wxDefaultSize);
471 m_ShortName = new wxTextCtrl(m_Information, ID_SHORTNAME, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
472 m_MakerText = new wxStaticText(m_Information, ID_MAKER_TEXT, _("Maker:"), wxDefaultPosition, wxDefaultSize);
473 m_Maker = new wxTextCtrl(m_Information, ID_MAKER, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
474 m_CommentText = new wxStaticText(m_Information, ID_COMMENT_TEXT, _("Comment:"), wxDefaultPosition, wxDefaultSize);
475 m_Comment = new wxTextCtrl(m_Information, ID_COMMENT, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY);
476 m_BannerText = new wxStaticText(m_Information, ID_BANNER_TEXT, _("Banner:"), wxDefaultPosition, wxDefaultSize);
477 m_Banner = new wxStaticBitmap(m_Information, ID_BANNER, wxNullBitmap, wxDefaultPosition, wxSize(96, 32), 0);
479 // ISO Details
480 sISODetails = new wxGridBagSizer(0, 0);
481 sISODetails->Add(m_NameText, wxGBPosition(0, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
482 sISODetails->Add(m_Name, wxGBPosition(0, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
483 sISODetails->Add(m_GameIDText, wxGBPosition(1, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
484 sISODetails->Add(m_GameID, wxGBPosition(1, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
485 sISODetails->Add(m_CountryText, wxGBPosition(2, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
486 sISODetails->Add(m_Country, wxGBPosition(2, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
487 sISODetails->Add(m_MakerIDText, wxGBPosition(3, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
488 sISODetails->Add(m_MakerID, wxGBPosition(3, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
489 sISODetails->Add(m_DateText, wxGBPosition(4, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
490 sISODetails->Add(m_Date, wxGBPosition(4, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
491 sISODetails->Add(m_FSTText, wxGBPosition(5, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
492 sISODetails->Add(m_FST, wxGBPosition(5, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
493 sISODetails->AddGrowableCol(1);
494 sbISODetails = new wxStaticBoxSizer(wxVERTICAL, m_Information, _("ISO Details"));
495 sbISODetails->Add(sISODetails, 0, wxEXPAND, 5);
497 // Banner Details
498 sBannerDetails = new wxGridBagSizer(0, 0);
499 sBannerDetails->Add(m_LangText, wxGBPosition(0, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
500 sBannerDetails->Add(m_Lang, wxGBPosition(0, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
501 sBannerDetails->Add(m_ShortText, wxGBPosition(1, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
502 sBannerDetails->Add(m_ShortName, wxGBPosition(1, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
503 sBannerDetails->Add(m_MakerText, wxGBPosition(2, 0), wxGBSpan(1, 1), wxALIGN_CENTER_VERTICAL|wxALL, 5);
504 sBannerDetails->Add(m_Maker, wxGBPosition(2, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
505 sBannerDetails->Add(m_CommentText, wxGBPosition(3, 0), wxGBSpan(1, 1), wxALL, 5);
506 sBannerDetails->Add(m_Comment, wxGBPosition(3, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
507 sBannerDetails->Add(m_BannerText, wxGBPosition(4, 0), wxGBSpan(1, 1), wxALL, 5);
508 sBannerDetails->Add(m_Banner, wxGBPosition(4, 1), wxGBSpan(1, 1), wxEXPAND|wxALL, 5);
509 sBannerDetails->AddGrowableCol(1);
510 sbBannerDetails = new wxStaticBoxSizer(wxVERTICAL, m_Information, _("Banner Details"));
511 sbBannerDetails->Add(sBannerDetails, 0, wxEXPAND, 5);
513 wxBoxSizer* sInfoPage;
514 sInfoPage = new wxBoxSizer(wxVERTICAL);
515 sInfoPage->Add(sbISODetails, 0, wxEXPAND|wxALL, 5);
516 sInfoPage->Add(sbBannerDetails, 0, wxEXPAND|wxALL, 5);
517 m_Information->SetSizer(sInfoPage);
518 sInfoPage->Layout();
520 // Filesystem icons
521 m_iconList = new wxImageList(16, 16);
522 m_iconList->Add(wxBitmap(disc_xpm), wxNullBitmap); // 0
523 m_iconList->Add(wxBitmap(folder_xpm), wxNullBitmap); // 1
524 m_iconList->Add(wxBitmap(file_xpm), wxNullBitmap); // 2
526 // Filesystem tree
527 m_Treectrl = new wxTreeCtrl(m_Filesystem, ID_TREECTRL, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE, wxDefaultValidator);
528 m_Treectrl->AssignImageList(m_iconList);
529 RootId = m_Treectrl->AddRoot(wxT("Disc"), 0, 0, 0);
531 wxBoxSizer* sTreePage;
532 sTreePage = new wxBoxSizer(wxVERTICAL);
533 sTreePage->Add(m_Treectrl, 1, wxEXPAND|wxALL, 5);
534 m_Filesystem->SetSizer(sTreePage);
535 sTreePage->Layout();
537 // It's a wad file, so we remove the FileSystem page
538 if (IsWad)
539 m_Notebook->RemovePage(4);
542 // Add notebook and buttons to the dialog
543 wxBoxSizer* sMain;
544 sMain = new wxBoxSizer(wxVERTICAL);
545 sMain->Add(m_Notebook, 1, wxEXPAND|wxALL, 5);
546 sMain->Add(sButtons, 0, wxEXPAND, 5);
547 sMain->SetMinSize(wxSize(550, 600));
549 m_Notebook->SetMaxSize(wxSize(550, 600));
550 SetSizerAndFit(sMain);
553 void CISOProperties::OnClose(wxCloseEvent& WXUNUSED (event))
555 if (!SaveGameConfig())
556 PanicAlert("Could not save %s", GameIniFile.c_str());
558 EndModal(bRefreshList ? wxID_OK : wxID_CANCEL);
561 void CISOProperties::OnCloseClick(wxCommandEvent& WXUNUSED (event))
563 Close();
566 void CISOProperties::RightClickOnBanner(wxMouseEvent& event)
568 wxMenu* popupMenu = new wxMenu;
569 popupMenu->Append(IDM_BNRSAVEAS, _("Save as..."));
570 PopupMenu(popupMenu);
572 event.Skip();
575 void CISOProperties::OnBannerImageSave(wxCommandEvent& WXUNUSED (event))
577 wxString dirHome;
579 wxFileDialog dialog(this, _("Save as..."), wxGetHomeDir(&dirHome), wxString::Format(_("%s.png"), m_GameID->GetLabel().c_str()),
580 _("*.*"), wxFD_SAVE|wxFD_OVERWRITE_PROMPT, wxDefaultPosition, wxDefaultSize);
581 if (dialog.ShowModal() == wxID_OK)
583 m_Banner->GetBitmap().ConvertToImage().SaveFile(dialog.GetPath());
587 void CISOProperties::OnRightClickOnTree(wxTreeEvent& event)
589 m_Treectrl->SelectItem(event.GetItem());
591 wxMenu* popupMenu = new wxMenu;
593 if (m_Treectrl->GetItemImage(m_Treectrl->GetSelection()) == 0
594 && m_Treectrl->GetFirstVisibleItem() != m_Treectrl->GetSelection())
595 popupMenu->Append(IDM_EXTRACTDIR, _("Extract Partition..."));
596 else if (m_Treectrl->GetItemImage(m_Treectrl->GetSelection()) == 1)
597 popupMenu->Append(IDM_EXTRACTDIR, _("Extract Directory..."));
598 else if (m_Treectrl->GetItemImage(m_Treectrl->GetSelection()) == 2)
599 popupMenu->Append(IDM_EXTRACTFILE, _("Extract File..."));
601 popupMenu->Append(IDM_EXTRACTALL, _("Extract All Files..."));
602 popupMenu->AppendSeparator();
603 popupMenu->Append(IDM_EXTRACTAPPLOADER, _("Extract Apploader..."));
604 popupMenu->Append(IDM_EXTRACTDOL, _("Extract DOL..."));
606 PopupMenu(popupMenu);
608 event.Skip();
611 void CISOProperties::OnExtractFile(wxCommandEvent& WXUNUSED (event))
613 wxString Path;
614 wxString File;
616 File = m_Treectrl->GetItemText(m_Treectrl->GetSelection());
618 Path = wxFileSelector(
619 wxT("Export File"),
620 wxEmptyString, File, wxEmptyString,
621 wxString::Format
623 wxT("All files (%s)|%s"),
624 wxFileSelectorDefaultWildcardStr,
625 wxFileSelectorDefaultWildcardStr
627 wxFD_SAVE,
628 this);
630 if (!Path || !File)
631 return;
633 while (m_Treectrl->GetItemParent(m_Treectrl->GetSelection()) != m_Treectrl->GetRootItem())
635 wxString temp;
636 temp = m_Treectrl->GetItemText(m_Treectrl->GetItemParent(m_Treectrl->GetSelection()));
637 File = temp + wxT(DIR_SEP_CHR) + File;
639 m_Treectrl->SelectItem(m_Treectrl->GetItemParent(m_Treectrl->GetSelection()));
642 if (DiscIO::IsVolumeWiiDisc(OpenISO))
644 int partitionNum = wxAtoi(File.SubString(10, 11));
645 File.Remove(0, 12); // Remove "Partition x/"
646 WiiDisc.at(partitionNum).FileSystem->ExportFile(File.mb_str(), Path.mb_str());
648 else
649 pFileSystem->ExportFile(File.mb_str(), Path.mb_str());
652 void CISOProperties::ExportDir(const char* _rFullPath, const char* _rExportFolder, const int partitionNum)
654 char exportName[512];
655 u32 index[2] = {0, 0}, offsetShift = 0;
656 std::vector<const DiscIO::SFileInfo *> fst;
657 DiscIO::IFileSystem *FS = 0;
659 if (DiscIO::IsVolumeWiiDisc(OpenISO))
661 FS = WiiDisc.at(partitionNum).FileSystem;
662 offsetShift = 2;
664 else
665 FS = pFileSystem;
667 FS->GetFileList(fst);
669 if (!_rFullPath) // Extract all
671 index[0] = 0;
672 index[1] = (u32)fst.size();
674 FS->ExportApploader(_rExportFolder);
675 if (!DiscIO::IsVolumeWiiDisc(OpenISO))
676 FS->ExportDOL(_rExportFolder);
678 else // Look for the dir we are going to extract
680 for(index[0] = 0; index[0] < fst.size(); index[0]++)
682 if (!strcmp(fst.at(index[0])->m_FullPath, _rFullPath))
684 DEBUG_LOG(DISCIO, "Found the Dir at %u", index[0]);
685 index[1] = (u32)fst.at(index[0])->m_FileSize;
686 break;
690 DEBUG_LOG(DISCIO,"Dir found from %u to %u\nextracting to:\n%s",index[0],index[1],_rExportFolder);
693 wxString dialogTitle = index[0] ? _T("Extracting Directory") : _T("Extracting All Files");
694 wxProgressDialog dialog(dialogTitle,
695 _T("Extracting..."),
696 index[1], // range
697 this, // parent
698 wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT |
699 wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME |
700 wxPD_SMOOTH // - makes indeterminate mode bar on WinXP very small
702 dialog.CenterOnParent();
704 // Extraction
705 for (u32 i = index[0]; i < index[1]; i++)
707 dialog.SetTitle(wxString::Format(_T("%s : %d%%"), dialogTitle.c_str(),
708 (u32)(((float)(i - index[0]) / (float)(index[1] - index[0])) * 100)));
709 if (!dialog.Update(i, wxString::Format(_T("Extracting %s"), wxString(fst[i]->m_FullPath, *wxConvCurrent).c_str())))
710 break;
712 if (fst[i]->IsDirectory())
714 snprintf(exportName, sizeof(exportName), "%s/%s/", _rExportFolder, fst[i]->m_FullPath);
715 DEBUG_LOG(DISCIO, "%s", exportName);
717 if (!File::Exists(exportName) && !File::CreateFullPath(exportName))
719 ERROR_LOG(DISCIO, "Could not create the path %s", exportName);
721 else
723 if (!File::IsDirectory(exportName))
724 ERROR_LOG(DISCIO, "%s already exists and is not a directory", exportName);
726 DEBUG_LOG(DISCIO, "folder %s already exists", exportName);
729 else
731 snprintf(exportName, sizeof(exportName), "%s/%s", _rExportFolder, fst[i]->m_FullPath);
732 DEBUG_LOG(DISCIO, "%s", exportName);
734 if (!File::Exists(exportName) && !FS->ExportFile(fst[i]->m_FullPath, exportName))
736 ERROR_LOG(DISCIO, "Could not export %s", exportName);
738 else
740 DEBUG_LOG(DISCIO, "%s already exists", exportName);
746 void CISOProperties::OnExtractDir(wxCommandEvent& event)
748 wxString Directory = m_Treectrl->GetItemText(m_Treectrl->GetSelection());
749 wxString Path = wxDirSelector(wxT("Choose the folder where to extract to"));
751 if (!Path || !Directory)
752 return;
754 if (event.GetId() == IDM_EXTRACTALL)
756 if (DiscIO::IsVolumeWiiDisc(OpenISO))
757 for (u32 i = 0; i < WiiDisc.size(); i++)
758 ExportDir(NULL, Path.mb_str(), i);
759 else
760 ExportDir(NULL, Path.mb_str());
762 return;
765 while (m_Treectrl->GetItemParent(m_Treectrl->GetSelection()) != m_Treectrl->GetRootItem())
767 wxString temp;
768 temp = m_Treectrl->GetItemText(m_Treectrl->GetItemParent(m_Treectrl->GetSelection()));
769 Directory = temp + wxT(DIR_SEP_CHR) + Directory;
771 m_Treectrl->SelectItem(m_Treectrl->GetItemParent(m_Treectrl->GetSelection()));
774 if (DiscIO::IsVolumeWiiDisc(OpenISO))
776 int partitionNum = wxAtoi(Directory.SubString(10, 11));
777 Directory.Remove(0, 12); // Remove "Partition x/"
778 ExportDir(Directory.mb_str(), Path.mb_str(), partitionNum);
780 else
781 ExportDir(Directory.mb_str(), Path.mb_str());
784 void CISOProperties::OnExtractDataFromHeader(wxCommandEvent& event)
786 std::vector<const DiscIO::SFileInfo *> fst;
787 DiscIO::IFileSystem *FS = 0;
788 wxString Path = wxDirSelector(wxT("Choose the folder to extract to"));
790 if (Path.empty())
791 return;
793 if (DiscIO::IsVolumeWiiDisc(OpenISO))
794 FS = WiiDisc.at(1).FileSystem;
795 else
796 FS = pFileSystem;
798 bool ret = false;
799 if (event.GetId() == IDM_EXTRACTAPPLOADER)
801 ret = FS->ExportApploader(Path.mb_str());
803 else if (event.GetId() == IDM_EXTRACTDOL)
805 ret = FS->ExportDOL(Path.mb_str());
808 if (!ret)
809 PanicAlert("Failed to extract to %s!", (const char *)Path.mb_str());
812 void CISOProperties::SetRefresh(wxCommandEvent& event)
814 bRefreshList = true;
816 if (event.GetId() == ID_EMUSTATE)
817 EmuIssues->Enable(event.GetSelection() != 0);
820 void CISOProperties::LoadGameConfig()
822 bool bTemp;
823 int iTemp;
824 std::string sTemp;
826 if (GameIni.Get("Core", "CPUThread", &bTemp))
827 CPUThread->Set3StateValue((wxCheckBoxState)bTemp);
828 else
829 CPUThread->Set3StateValue(wxCHK_UNDETERMINED);
831 if (GameIni.Get("Core", "SkipIdle", &bTemp))
832 SkipIdle->Set3StateValue((wxCheckBoxState)bTemp);
833 else
834 SkipIdle->Set3StateValue(wxCHK_UNDETERMINED);
836 if (GameIni.Get("Core", "MMU", &bTemp))
837 MMU->Set3StateValue((wxCheckBoxState)bTemp);
838 else
839 MMU->Set3StateValue(wxCHK_UNDETERMINED);
841 if (GameIni.Get("Core", "BAT", &bTemp))
842 MMUBAT->Set3StateValue((wxCheckBoxState)bTemp);
843 else
844 MMUBAT->Set3StateValue(wxCHK_UNDETERMINED);
846 if (GameIni.Get("Core", "TLBHack", &bTemp))
847 TLBHack->Set3StateValue((wxCheckBoxState)bTemp);
848 else
849 TLBHack->Set3StateValue(wxCHK_UNDETERMINED);
851 if (GameIni.Get("Core", "AlternateRFI", &bTemp))
852 AlternateRFI->Set3StateValue((wxCheckBoxState)bTemp);
853 else
854 AlternateRFI->Set3StateValue(wxCHK_UNDETERMINED);
856 if (GameIni.Get("Core", "FastDiscSpeed", &bTemp))
857 FastDiscSpeed->Set3StateValue((wxCheckBoxState)bTemp);
858 else
859 FastDiscSpeed->Set3StateValue(wxCHK_UNDETERMINED);
861 if (GameIni.Get("Core", "BlockMerging", &bTemp))
862 BlockMerging->Set3StateValue((wxCheckBoxState)bTemp);
863 else
864 BlockMerging->Set3StateValue(wxCHK_UNDETERMINED);
866 if (GameIni.Get("Display", "ProgressiveScan", &bTemp))
867 EnableProgressiveScan->Set3StateValue((wxCheckBoxState)bTemp);
868 else
869 EnableProgressiveScan->Set3StateValue(wxCHK_UNDETERMINED);
871 if (GameIni.Get("Wii", "Widescreen", &bTemp))
872 EnableWideScreen->Set3StateValue((wxCheckBoxState)bTemp);
873 else
874 EnableWideScreen->Set3StateValue(wxCHK_UNDETERMINED);
876 if (GameIni.Get("Video", "ForceFiltering", &bTemp))
877 ForceFiltering->Set3StateValue((wxCheckBoxState)bTemp);
878 else
879 ForceFiltering->Set3StateValue(wxCHK_UNDETERMINED);
881 if (GameIni.Get("Video", "EFBCopyDisable", &bTemp))
882 EFBCopyDisable->Set3StateValue((wxCheckBoxState)bTemp);
883 else
884 EFBCopyDisable->Set3StateValue(wxCHK_UNDETERMINED);
886 if (GameIni.Get("Video", "EFBToTextureEnable", &bTemp))
887 EFBToTextureEnable->Set3StateValue((wxCheckBoxState)bTemp);
888 else
889 EFBToTextureEnable->Set3StateValue(wxCHK_UNDETERMINED);
891 if (GameIni.Get("Video", "SafeTextureCache", &bTemp))
892 SafeTextureCache->Set3StateValue((wxCheckBoxState)bTemp);
893 else
894 SafeTextureCache->Set3StateValue(wxCHK_UNDETERMINED);
896 if (GameIni.Get("Video", "DstAlphaPass", &bTemp))
897 DstAlphaPass->Set3StateValue((wxCheckBoxState)bTemp);
898 else
899 DstAlphaPass->Set3StateValue(wxCHK_UNDETERMINED);
901 if (GameIni.Get("Video", "UseXFB", &bTemp))
902 UseXFB->Set3StateValue((wxCheckBoxState)bTemp);
903 else
904 UseXFB->Set3StateValue(wxCHK_UNDETERMINED);
906 if (GameIni.Get("Video", "ZTPSpeedupHack", &bTemp))
907 UseZTPSpeedupHack->Set3StateValue((wxCheckBoxState)bTemp);
908 else
909 UseZTPSpeedupHack->Set3StateValue(wxCHK_UNDETERMINED);
911 if (GameIni.Get("Video", "DlistCachingEnable", &bTemp))
912 DListCache->Set3StateValue((wxCheckBoxState)bTemp);
913 else
914 DListCache->Set3StateValue(wxCHK_UNDETERMINED);
916 if (GameIni.Get("Video", "FIFOWatermarkTightness", &sTemp))
917 WMTightness->SetValue(wxString(sTemp.c_str(), *wxConvCurrent));
918 else
919 WMTightness->SetValue(wxT("50"));
921 GameIni.Get("Video", "ProjectionHack", &iTemp, -1);
922 Hack->SetSelection(iTemp);
924 GameIni.Get("EmuState", "EmulationStateId", &iTemp, -1);
925 EmuState->SetSelection(iTemp);
927 GameIni.Get("EmuState", "EmulationIssues", &sTemp);
928 if (!sTemp.empty())
930 EmuIssues->SetValue(wxString(sTemp.c_str(), *wxConvCurrent));
931 bRefreshList = true;
933 EmuIssues->Enable(EmuState->GetSelection() != 0);
935 PatchList_Load();
936 ActionReplayList_Load();
937 m_geckocode_panel->LoadCodes(GameIni, OpenISO->GetUniqueID());
940 bool CISOProperties::SaveGameConfig()
942 if (CPUThread->Get3StateValue() == wxCHK_UNDETERMINED)
943 GameIni.DeleteKey("Core", "CPUThread");
944 else
945 GameIni.Set("Core", "CPUThread", CPUThread->Get3StateValue());
947 if (SkipIdle->Get3StateValue() == wxCHK_UNDETERMINED)
948 GameIni.DeleteKey("Core", "SkipIdle");
949 else
950 GameIni.Set("Core", "SkipIdle", SkipIdle->Get3StateValue());
952 if (MMU->Get3StateValue() == wxCHK_UNDETERMINED)
953 GameIni.DeleteKey("Core", "MMU");
954 else
955 GameIni.Set("Core", "MMU", MMU->Get3StateValue());
957 if (MMUBAT->Get3StateValue() == wxCHK_UNDETERMINED)
958 GameIni.DeleteKey("Core", "BAT");
959 else
960 GameIni.Set("Core", "BAT", MMUBAT->Get3StateValue());
962 if (TLBHack->Get3StateValue() == wxCHK_UNDETERMINED)
963 GameIni.DeleteKey("Core", "TLBHack");
964 else
965 GameIni.Set("Core", "TLBHack", TLBHack->Get3StateValue());
967 if (AlternateRFI->Get3StateValue() == wxCHK_UNDETERMINED)
968 GameIni.DeleteKey("Core", "AlternateRFI");
969 else
970 GameIni.Set("Core", "AlternateRFI", AlternateRFI->Get3StateValue());
972 if (FastDiscSpeed->Get3StateValue() == wxCHK_UNDETERMINED)
973 GameIni.DeleteKey("Core", "FastDiscSpeed");
974 else
975 GameIni.Set("Core", "FastDiscSpeed", FastDiscSpeed->Get3StateValue());
977 if (BlockMerging->Get3StateValue() == wxCHK_UNDETERMINED)
978 GameIni.DeleteKey("Core", "BlockMerging");
979 else
980 GameIni.Set("Core", "BlockMerging", BlockMerging->Get3StateValue());
982 if (EnableProgressiveScan->Get3StateValue() == wxCHK_UNDETERMINED)
983 GameIni.DeleteKey("Display", "ProgressiveScan");
984 else
985 GameIni.Set("Display", "ProgressiveScan", EnableProgressiveScan->Get3StateValue());
987 if (EnableWideScreen->Get3StateValue() == wxCHK_UNDETERMINED)
988 GameIni.DeleteKey("Wii", "Widescreen");
989 else
990 GameIni.Set("Wii", "Widescreen", EnableWideScreen->Get3StateValue());
992 if (ForceFiltering->Get3StateValue() == wxCHK_UNDETERMINED)
993 GameIni.DeleteKey("Video", "ForceFiltering");
994 else
995 GameIni.Set("Video", "ForceFiltering", ForceFiltering->Get3StateValue());
997 if (EFBCopyDisable->Get3StateValue() == wxCHK_UNDETERMINED)
998 GameIni.DeleteKey("Video", "EFBCopyDisable");
999 else
1000 GameIni.Set("Video", "EFBCopyDisable", EFBCopyDisable->Get3StateValue());
1002 if (EFBToTextureEnable->Get3StateValue() == wxCHK_UNDETERMINED)
1003 GameIni.DeleteKey("Video", "EFBToTextureEnable");
1004 else
1005 GameIni.Set("Video", "EFBToTextureEnable", EFBToTextureEnable->Get3StateValue());
1007 if (SafeTextureCache->Get3StateValue() == wxCHK_UNDETERMINED)
1008 GameIni.DeleteKey("Video", "SafeTextureCache");
1009 else
1010 GameIni.Set("Video", "SafeTextureCache", SafeTextureCache->Get3StateValue());
1012 if (DstAlphaPass->Get3StateValue() == wxCHK_UNDETERMINED)
1013 GameIni.DeleteKey("Video", "DstAlphaPass");
1014 else
1015 GameIni.Set("Video", "DstAlphaPass", DstAlphaPass->Get3StateValue());
1017 if (UseXFB->Get3StateValue() == wxCHK_UNDETERMINED)
1018 GameIni.DeleteKey("Video", "UseXFB");
1019 else
1020 GameIni.Set("Video", "UseXFB", UseXFB->Get3StateValue());
1022 if (UseZTPSpeedupHack->Get3StateValue() == wxCHK_UNDETERMINED)
1023 GameIni.DeleteKey("Video", "ZTPSpeedupHack");
1024 else
1025 GameIni.Set("Video", "ZTPSpeedupHack", UseZTPSpeedupHack->Get3StateValue());
1027 if (DListCache->Get3StateValue() == wxCHK_UNDETERMINED)
1028 GameIni.DeleteKey("Video", "DlistCachingEnable");
1029 else
1030 GameIni.Set("Video", "DlistCachingEnable", DListCache->Get3StateValue());
1032 if (Hack->GetSelection() == -1)
1033 GameIni.DeleteKey("Video", "ProjectionHack");
1034 else
1035 GameIni.Set("Video", "ProjectionHack", Hack->GetSelection());
1037 if (WMTightness->GetValue().size() == 0)
1038 GameIni.DeleteKey("Video", "FIFOWatermarkTightness");
1039 else
1041 long val;
1042 WMTightness->GetValue().ToLong(&val);
1043 GameIni.Set("Video", "FIFOWatermarkTightness", (int)val);
1046 if (EmuState->GetSelection() == -1)
1047 GameIni.DeleteKey("EmuState", "EmulationStateId");
1048 else
1049 GameIni.Set("EmuState", "EmulationStateId", EmuState->GetSelection());
1051 GameIni.Set("EmuState", "EmulationIssues", (const char*)EmuIssues->GetValue().mb_str(*wxConvCurrent));
1053 PatchList_Save();
1054 ActionReplayList_Save();
1055 Gecko::SaveCodes(GameIni, m_geckocode_panel->GetCodes());
1057 return GameIni.Save(GameIniFile.c_str());
1060 void CISOProperties::OnEditConfig(wxCommandEvent& WXUNUSED (event))
1062 if (wxFileExists(wxString::From8BitData(GameIniFile.c_str())))
1064 SaveGameConfig();
1066 wxFileType* filetype = wxTheMimeTypesManager->GetFileTypeFromExtension(_("ini"));
1067 if(filetype == NULL) // From extension failed, trying with MIME type now
1069 filetype = wxTheMimeTypesManager->GetFileTypeFromMimeType(_("text/plain"));
1070 if(filetype == NULL) // MIME type failed, aborting mission
1072 PanicAlert("Filetype 'ini' is unknown! Will not open!");
1073 return;
1076 wxString OpenCommand;
1077 OpenCommand = filetype->GetOpenCommand(wxString::From8BitData(GameIniFile.c_str()));
1078 if(OpenCommand.IsEmpty())
1079 PanicAlert("Couldn't find open command for extension 'ini'!");
1080 else
1081 if(wxExecute(OpenCommand, wxEXEC_SYNC) == -1)
1082 PanicAlert("wxExecute returned -1 on application run!");
1084 GameIni.Load(GameIniFile.c_str());
1085 LoadGameConfig();
1087 bRefreshList = true; // Just in case
1090 // Once we're done with the ini edit, give the focus back to Dolphin
1091 SetFocus();
1094 void CISOProperties::ListSelectionChanged(wxCommandEvent& event)
1096 switch (event.GetId())
1098 case ID_PATCHES_LIST:
1099 if (Patches->GetSelection() != wxNOT_FOUND)
1101 EditPatch->Enable();
1102 RemovePatch->Enable();
1104 break;
1105 case ID_CHEATS_LIST:
1106 if (Cheats->GetSelection() != wxNOT_FOUND)
1108 EditCheat->Enable();
1109 RemoveCheat->Enable();
1111 break;
1115 void CISOProperties::PatchList_Load()
1117 onFrame.clear();
1118 Patches->Clear();
1119 PatchEngine::LoadPatchSection("OnFrame", onFrame, GameIni);
1121 u32 index = 0;
1122 for (std::vector<PatchEngine::Patch>::const_iterator it = onFrame.begin(); it != onFrame.end(); ++it)
1124 PatchEngine::Patch p = *it;
1125 Patches->Append(wxString(p.name.c_str(), *wxConvCurrent));
1126 Patches->Check(index, p.active);
1127 ++index;
1131 void CISOProperties::PatchList_Save()
1133 std::vector<std::string> lines;
1134 u32 index = 0;
1135 for (std::vector<PatchEngine::Patch>::const_iterator onFrame_it = onFrame.begin(); onFrame_it != onFrame.end(); ++onFrame_it)
1137 lines.push_back(Patches->IsChecked(index) ? "+$" + onFrame_it->name : "$" + onFrame_it->name);
1139 for (std::vector<PatchEngine::PatchEntry>::const_iterator iter2 = onFrame_it->entries.begin(); iter2 != onFrame_it->entries.end(); ++iter2)
1141 std::string temp = StringFromFormat("0x%08X:%s:0x%08X", iter2->address, PatchEngine::PatchTypeStrings[iter2->type], iter2->value);
1142 lines.push_back(temp);
1144 ++index;
1146 GameIni.SetLines("OnFrame", lines);
1147 lines.clear();
1150 void CISOProperties::PatchButtonClicked(wxCommandEvent& event)
1152 int selection = Patches->GetSelection();
1154 switch (event.GetId())
1156 case ID_EDITPATCH:
1158 CPatchAddEdit dlg(selection, this);
1159 dlg.ShowModal();
1161 break;
1162 case ID_ADDPATCH:
1164 CPatchAddEdit dlg(-1, this, 1, _("Add Patch"));
1165 if (dlg.ShowModal() == wxID_OK)
1167 Patches->Append(wxString(onFrame.back().name.c_str(), *wxConvCurrent));
1168 Patches->Check((unsigned int)(onFrame.size() - 1), onFrame.back().active);
1171 break;
1172 case ID_REMOVEPATCH:
1173 onFrame.erase(onFrame.begin() + Patches->GetSelection());
1174 Patches->Delete(Cheats->GetSelection());
1175 break;
1178 PatchList_Save();
1179 Patches->Clear();
1180 PatchList_Load();
1182 EditPatch->Enable(false);
1183 RemovePatch->Enable(false);
1186 void CISOProperties::ActionReplayList_Load()
1188 arCodes.clear();
1189 Cheats->Clear();
1190 ActionReplay::LoadCodes(arCodes, GameIni);
1192 u32 index = 0;
1193 for (std::vector<ActionReplay::ARCode>::const_iterator it = arCodes.begin(); it != arCodes.end(); ++it)
1195 ActionReplay::ARCode arCode = *it;
1196 Cheats->Append(wxString(arCode.name.c_str(), *wxConvCurrent));
1197 Cheats->Check(index, arCode.active);
1198 ++index;
1202 void CISOProperties::ActionReplayList_Save()
1204 std::vector<std::string> lines;
1205 u32 index = 0;
1206 for (std::vector<ActionReplay::ARCode>::const_iterator iter = arCodes.begin(); iter != arCodes.end(); ++iter)
1208 ActionReplay::ARCode code = *iter;
1210 lines.push_back(Cheats->IsChecked(index) ? "+$" + code.name : "$" + code.name);
1212 for (std::vector<ActionReplay::AREntry>::const_iterator iter2 = code.ops.begin(); iter2 != code.ops.end(); ++iter2)
1214 lines.push_back(std::string(wxString::Format(wxT("%08X %08X"), iter2->cmd_addr, iter2->value).mb_str()));
1216 ++index;
1218 GameIni.SetLines("ActionReplay", lines);
1221 void CISOProperties::ActionReplayButtonClicked(wxCommandEvent& event)
1223 int selection = Cheats->GetSelection();
1225 switch (event.GetId())
1227 case ID_EDITCHEAT:
1229 CARCodeAddEdit dlg(selection, this);
1230 dlg.ShowModal();
1232 break;
1233 case ID_ADDCHEAT:
1235 CARCodeAddEdit dlg(-1, this, 1, _("Add ActionReplay Code"));
1236 if (dlg.ShowModal() == wxID_OK)
1238 Cheats->Append(wxString::From8BitData(arCodes.back().name.c_str()));
1239 Cheats->Check((unsigned int)(arCodes.size() - 1), arCodes.back().active);
1242 break;
1243 case ID_REMOVECHEAT:
1244 arCodes.erase(arCodes.begin() + Cheats->GetSelection());
1245 Cheats->Delete(Cheats->GetSelection());
1246 break;
1249 ActionReplayList_Save();
1250 Cheats->Clear();
1251 ActionReplayList_Load();
1253 EditCheat->Enable(false);
1254 RemoveCheat->Enable(false);
1257 void CISOProperties::OnChangeBannerLang(wxCommandEvent& event)
1259 ChangeBannerDetails(event.GetSelection());
1262 void CISOProperties::ChangeBannerDetails(int lang)
1264 if (OpenGameListItem->GetCountry() == DiscIO::IVolume::COUNTRY_JAPAN
1265 || OpenGameListItem->GetCountry() == DiscIO::IVolume::COUNTRY_TAIWAN
1266 || OpenGameListItem->GetPlatform() == GameListItem::WII_WAD)
1268 #ifdef __linux__
1269 wxCSConv SJISConv(wxFontMapper::GetEncodingName(wxFONTENCODING_EUC_JP));
1270 #else
1271 wxCSConv SJISConv(wxFontMapper::GetEncodingName(wxFONTENCODING_SHIFT_JIS));
1272 #endif
1273 wxString name = wxString(OpenGameListItem->GetName(0).c_str(), SJISConv);
1275 // Updates the informations shown in the window
1276 m_ShortName->SetValue(name);
1277 m_Comment->SetValue(wxString(OpenGameListItem->GetDescription(0).c_str(), SJISConv));
1278 m_Maker->SetValue(wxString(OpenGameListItem->GetCompany().c_str(), SJISConv));//dev too
1280 std::string filename, extension;
1281 SplitPath(OpenGameListItem->GetFileName(), 0, &filename, &extension);
1283 // Also sets the window's title
1284 SetTitle(wxString::Format(wxT("%s%s"),
1285 wxString(StringFromFormat("%s%s: %s - ", filename.c_str(), extension.c_str(), OpenGameListItem->GetUniqueID().c_str()).c_str(), *wxConvCurrent).c_str(),
1286 name.c_str()));
1288 else // Do the same for PAL/US Games (assuming ISO 8859-1)
1290 wxString name = wxString::From8BitData(OpenGameListItem->GetName(lang).c_str());
1292 m_ShortName->SetValue(name);
1293 m_Comment->SetValue(wxString::From8BitData(OpenGameListItem->GetDescription(lang).c_str()));
1294 m_Maker->SetValue(wxString::From8BitData(OpenGameListItem->GetCompany().c_str()));//dev too
1296 std::string filename, extension;
1297 SplitPath(OpenGameListItem->GetFileName(), 0, &filename, &extension);
1299 SetTitle(wxString::Format(wxT("%s%s"),
1300 wxString::From8BitData(StringFromFormat("%s%s: %s - ", filename.c_str(), extension.c_str(), OpenGameListItem->GetUniqueID().c_str()).c_str()).c_str(),
1301 name.c_str()));