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/
19 #include "CommonPaths.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"
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
)
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...
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
);
97 // TODO : Should we add a way to browse the wad file ?
98 if (!DiscIO::IsVolumeWadFile(OpenISO
))
101 pFileSystem
= DiscIO::CreateFileSystem(OpenISO
);
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()))
118 // Will fail out if GameConfig folder doesn't exist
119 FILE *f
= fopen(GameIniFile
.c_str(), "w");
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");
129 if (GameIni
.Load(GameIniFile
.c_str()))
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"));
143 case DiscIO::IVolume::COUNTRY_FRANCE
:
144 m_Country
->SetValue(wxT("FRANCE"));
146 case DiscIO::IVolume::COUNTRY_ITALY
:
147 m_Country
->SetValue(wxT("ITALY"));
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
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
159 case DiscIO::IVolume::COUNTRY_KOREA
:
160 m_Country
->SetValue(wxT("KOREA"));
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
167 case DiscIO::IVolume::COUNTRY_SDK
:
168 m_Country
->SetValue(wxT("No Country (SDK)"));
171 m_Country
->SetValue(wxT("UNKNOWN"));
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
);
194 m_Treectrl
->Expand(PartitionRoot
);
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
))
215 // two vector's items are no longer valid after deleting filesystem
218 delete OpenGameListItem
;
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
);
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
);
250 m_Treectrl
->AppendItem(parent
, wxString::From8BitData(itemName
), 2, 2);
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"));
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
);
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
);
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();
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();
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."));
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."));
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();
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);
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);
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
);
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
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
);
520 // It's a wad file, so we remove the FileSystem page
522 m_Notebook
->RemovePage(4);
525 // Add notebook and buttons to the dialog
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
))
549 void CISOProperties::RightClickOnBanner(wxMouseEvent
& event
)
551 wxMenu
* popupMenu
= new wxMenu
;
552 popupMenu
->Append(IDM_BNRSAVEAS
, _("Save as..."));
553 PopupMenu(popupMenu
);
558 void CISOProperties::OnBannerImageSave(wxCommandEvent
& WXUNUSED (event
))
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
);
594 void CISOProperties::OnExtractFile(wxCommandEvent
& WXUNUSED (event
))
599 File
= m_Treectrl
->GetItemText(m_Treectrl
->GetSelection());
601 Path
= wxFileSelector(
603 wxEmptyString
, File
, wxEmptyString
,
606 wxT("All files (%s)|%s"),
607 wxFileSelectorDefaultWildcardStr
,
608 wxFileSelectorDefaultWildcardStr
616 while (m_Treectrl
->GetItemParent(m_Treectrl
->GetSelection()) != m_Treectrl
->GetRootItem())
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());
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
;
650 FS
->GetFileList(fst
);
652 if (!_rFullPath
) // Extract all
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
;
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
,
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();
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())))
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
);
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
);
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
);
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
)
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
);
743 ExportDir(NULL
, Path
.mb_str());
748 while (m_Treectrl
->GetItemParent(m_Treectrl
->GetSelection()) != m_Treectrl
->GetRootItem())
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
);
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"));
776 if (DiscIO::IsVolumeWiiDisc(OpenISO
))
777 FS
= WiiDisc
.at(1).FileSystem
;
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());
792 PanicAlert("Failed to extract to %s!", (const char *)Path
.mb_str());
795 void CISOProperties::SetRefresh(wxCommandEvent
& event
)
799 if (event
.GetId() == ID_EMUSTATE
)
800 EmuIssues
->Enable(event
.GetSelection() != 0);
803 void CISOProperties::LoadGameConfig()
809 if (GameIni
.Get("Core", "CPUThread", &bTemp
))
810 CPUThread
->Set3StateValue((wxCheckBoxState
)bTemp
);
812 CPUThread
->Set3StateValue(wxCHK_UNDETERMINED
);
814 if (GameIni
.Get("Core", "SkipIdle", &bTemp
))
815 SkipIdle
->Set3StateValue((wxCheckBoxState
)bTemp
);
817 SkipIdle
->Set3StateValue(wxCHK_UNDETERMINED
);
819 if (GameIni
.Get("Core", "MMU", &bTemp
))
820 MMU
->Set3StateValue((wxCheckBoxState
)bTemp
);
822 MMU
->Set3StateValue(wxCHK_UNDETERMINED
);
824 if (GameIni
.Get("Core", "TLBHack", &bTemp
))
825 TLBHack
->Set3StateValue((wxCheckBoxState
)bTemp
);
827 TLBHack
->Set3StateValue(wxCHK_UNDETERMINED
);
829 if (GameIni
.Get("Core", "SMC", &bTemp
))
830 SMC
->Set3StateValue((wxCheckBoxState
)bTemp
);
832 SMC
->Set3StateValue(wxCHK_UNDETERMINED
);
834 if (GameIni
.Get("Wii", "ProgressiveScan", &bTemp
))
835 EnableProgressiveScan
->Set3StateValue((wxCheckBoxState
)bTemp
);
837 EnableProgressiveScan
->Set3StateValue(wxCHK_UNDETERMINED
);
839 if (GameIni
.Get("Wii", "Widescreen", &bTemp
))
840 EnableWideScreen
->Set3StateValue((wxCheckBoxState
)bTemp
);
842 EnableWideScreen
->Set3StateValue(wxCHK_UNDETERMINED
);
844 if (GameIni
.Get("Video", "ForceFiltering", &bTemp
))
845 ForceFiltering
->Set3StateValue((wxCheckBoxState
)bTemp
);
847 ForceFiltering
->Set3StateValue(wxCHK_UNDETERMINED
);
849 if (GameIni
.Get("Video", "EFBCopyDisable", &bTemp
))
850 EFBCopyDisable
->Set3StateValue((wxCheckBoxState
)bTemp
);
852 EFBCopyDisable
->Set3StateValue(wxCHK_UNDETERMINED
);
854 if (GameIni
.Get("Video", "EFBToTextureEnable", &bTemp
))
855 EFBToTextureEnable
->Set3StateValue((wxCheckBoxState
)bTemp
);
857 EFBToTextureEnable
->Set3StateValue(wxCHK_UNDETERMINED
);
859 if (GameIni
.Get("Video", "SafeTextureCache", &bTemp
))
860 SafeTextureCache
->Set3StateValue((wxCheckBoxState
)bTemp
);
862 SafeTextureCache
->Set3StateValue(wxCHK_UNDETERMINED
);
864 if (GameIni
.Get("Video", "DstAlphaPass", &bTemp
))
865 DstAlphaPass
->Set3StateValue((wxCheckBoxState
)bTemp
);
867 DstAlphaPass
->Set3StateValue(wxCHK_UNDETERMINED
);
869 if (GameIni
.Get("Video", "UseXFB", &bTemp
))
870 UseXFB
->Set3StateValue((wxCheckBoxState
)bTemp
);
872 UseXFB
->Set3StateValue(wxCHK_UNDETERMINED
);
874 if (GameIni
.Get("Video", "ZTPSpeedupHack", &bTemp
))
875 UseZTPSpeedupHack
->Set3StateValue((wxCheckBoxState
)bTemp
);
877 UseZTPSpeedupHack
->Set3StateValue(wxCHK_UNDETERMINED
);
879 if (GameIni
.Get("Video", "FIFOWatermarkTightness", &sTemp
))
880 WMTightness
->SetValue(wxString(sTemp
.c_str(), *wxConvCurrent
));
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
);
893 EmuIssues
->SetValue(wxString(sTemp
.c_str(), *wxConvCurrent
));
896 EmuIssues
->Enable(EmuState
->GetSelection() != 0);
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");
908 GameIni
.Set("Core", "CPUThread", CPUThread
->Get3StateValue());
910 if (SkipIdle
->Get3StateValue() == wxCHK_UNDETERMINED
)
911 GameIni
.DeleteKey("Core", "SkipIdle");
913 GameIni
.Set("Core", "SkipIdle", SkipIdle
->Get3StateValue());
915 if (MMU
->Get3StateValue() == wxCHK_UNDETERMINED
)
916 GameIni
.DeleteKey("Core", "MMU");
918 GameIni
.Set("Core", "MMU", MMU
->Get3StateValue());
920 if (TLBHack
->Get3StateValue() == wxCHK_UNDETERMINED
)
921 GameIni
.DeleteKey("Core", "TLBHack");
923 GameIni
.Set("Core", "TLBHack", TLBHack
->Get3StateValue());
925 if (SMC
->Get3StateValue() == wxCHK_UNDETERMINED
)
926 GameIni
.DeleteKey("Core", "SMC");
928 GameIni
.Set("Core", "SMC", SMC
->Get3StateValue());
930 if (EnableProgressiveScan
->Get3StateValue() == wxCHK_UNDETERMINED
)
931 GameIni
.DeleteKey("Wii", "ProgressiveScan");
933 GameIni
.Set("Wii", "ProgressiveScan", EnableProgressiveScan
->Get3StateValue());
935 if (EnableWideScreen
->Get3StateValue() == wxCHK_UNDETERMINED
)
936 GameIni
.DeleteKey("Wii", "Widescreen");
938 GameIni
.Set("Wii", "Widescreen", EnableWideScreen
->Get3StateValue());
940 if (ForceFiltering
->Get3StateValue() == wxCHK_UNDETERMINED
)
941 GameIni
.DeleteKey("Video", "ForceFiltering");
943 GameIni
.Set("Video", "ForceFiltering", ForceFiltering
->Get3StateValue());
945 if (EFBCopyDisable
->Get3StateValue() == wxCHK_UNDETERMINED
)
946 GameIni
.DeleteKey("Video", "EFBCopyDisable");
948 GameIni
.Set("Video", "EFBCopyDisable", EFBCopyDisable
->Get3StateValue());
950 if (EFBToTextureEnable
->Get3StateValue() == wxCHK_UNDETERMINED
)
951 GameIni
.DeleteKey("Video", "EFBToTextureEnable");
953 GameIni
.Set("Video", "EFBToTextureEnable", EFBToTextureEnable
->Get3StateValue());
955 if (SafeTextureCache
->Get3StateValue() == wxCHK_UNDETERMINED
)
956 GameIni
.DeleteKey("Video", "SafeTextureCache");
958 GameIni
.Set("Video", "SafeTextureCache", SafeTextureCache
->Get3StateValue());
960 if (DstAlphaPass
->Get3StateValue() == wxCHK_UNDETERMINED
)
961 GameIni
.DeleteKey("Video", "DstAlphaPass");
963 GameIni
.Set("Video", "DstAlphaPass", DstAlphaPass
->Get3StateValue());
965 if (UseXFB
->Get3StateValue() == wxCHK_UNDETERMINED
)
966 GameIni
.DeleteKey("Video", "UseXFB");
968 GameIni
.Set("Video", "UseXFB", UseXFB
->Get3StateValue());
970 if (UseZTPSpeedupHack
->Get3StateValue() == wxCHK_UNDETERMINED
)
971 GameIni
.DeleteKey("Video", "ZTPSpeedupHack");
973 GameIni
.Set("Video", "ZTPSpeedupHack", UseZTPSpeedupHack
->Get3StateValue());
975 if (Hack
->GetSelection() == -1)
976 GameIni
.DeleteKey("Video", "ProjectionHack");
978 GameIni
.Set("Video", "ProjectionHack", Hack
->GetSelection());
980 if (WMTightness
->GetValue().size() == 0)
981 GameIni
.DeleteKey("Video", "FIFOWatermarkTightness");
985 WMTightness
->GetValue().ToLong(&val
);
986 GameIni
.Set("Video", "FIFOWatermarkTightness", (int)val
);
989 if (EmuState
->GetSelection() == -1)
990 GameIni
.DeleteKey("EmuState", "EmulationStateId");
992 GameIni
.Set("EmuState", "EmulationStateId", EmuState
->GetSelection());
994 GameIni
.Set("EmuState", "EmulationIssues", (const char*)EmuIssues
->GetValue().mb_str(*wxConvCurrent
));
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())))
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!");
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'!");
1024 if(wxExecute(OpenCommand
, wxEXEC_SYNC
) == -1)
1025 PanicAlert("wxExecute returned -1 on application run!");
1027 GameIni
.Load(GameIniFile
.c_str());
1030 bRefreshList
= true; // Just in case
1033 // Once we're done with the ini edit, give the focus back to Dolphin
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();
1048 case ID_CHEATS_LIST
:
1049 if (Cheats
->GetSelection() != wxNOT_FOUND
)
1051 EditCheat
->Enable();
1052 RemoveCheat
->Enable();
1058 void CISOProperties::PatchList_Load()
1062 PatchEngine::LoadPatchSection("OnFrame", onFrame
, GameIni
);
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
);
1074 void CISOProperties::PatchList_Save()
1076 std::vector
<std::string
> lines
;
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
)
1086 ToStringFromFormat(&temp
, "0x%08X:%s:0x%08X", iter2
->address
, PatchEngine::PatchTypeStrings
[iter2
->type
], iter2
->value
);
1087 lines
.push_back(temp
);
1091 GameIni
.SetLines("OnFrame", lines
);
1095 void CISOProperties::PatchButtonClicked(wxCommandEvent
& event
)
1097 int selection
= Patches
->GetSelection();
1099 switch (event
.GetId())
1103 CPatchAddEdit
dlg(selection
, this);
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
);
1117 case ID_REMOVEPATCH
:
1118 onFrame
.erase(onFrame
.begin() + Patches
->GetSelection());
1119 Patches
->Delete(Cheats
->GetSelection());
1127 EditPatch
->Enable(false);
1128 RemovePatch
->Enable(false);
1131 void CISOProperties::ActionReplayList_Load()
1135 ActionReplay::LoadCodes(arCodes
, GameIni
);
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
);
1147 void CISOProperties::ActionReplayList_Save()
1149 std::vector
<std::string
> lines
;
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()));
1163 GameIni
.SetLines("ActionReplay", lines
);
1166 void CISOProperties::ActionReplayButtonClicked(wxCommandEvent
& event
)
1168 int selection
= Cheats
->GetSelection();
1170 switch (event
.GetId())
1174 CARCodeAddEdit
dlg(selection
, this);
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
);
1188 case ID_REMOVECHEAT
:
1189 arCodes
.erase(arCodes
.begin() + Cheats
->GetSelection());
1190 Cheats
->Delete(Cheats
->GetSelection());
1194 ActionReplayList_Save();
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
)
1214 wxCSConv
SJISConv(wxFontMapper::GetEncodingName(wxFONTENCODING_EUC_JP
));
1216 wxCSConv
SJISConv(wxFontMapper::GetEncodingName(wxFONTENCODING_SHIFT_JIS
));
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(),
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(),