2015-05-24 06:55:12 +02:00
// Copyright 2008 Dolphin Emulator Project
2015-05-18 01:08:10 +02:00
// Licensed under GPLv2+
2013-04-17 23:43:35 -04:00
// Refer to the license.txt file included.
2008-12-08 05:30:24 +00:00
2011-01-30 14:20:20 +00:00
#ifdef __APPLE__
#import <Cocoa/Cocoa.h>
#endif
2013-10-26 11:55:41 +02:00
#include <cinttypes>
2014-02-22 23:36:30 +01:00
#include <cstddef>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <set>
#include <string>
2014-02-17 05:18:15 -05:00
#include <type_traits>
2014-02-22 23:36:30 +01:00
#include <vector>
2015-09-24 00:39:34 +02:00
#include <mbedtls/md5.h>
2014-02-22 23:36:30 +01:00
#include <wx/bitmap.h>
#include <wx/button.h>
#include <wx/checkbox.h>
#include <wx/checklst.h>
#include <wx/choice.h>
#include <wx/dialog.h>
#include <wx/dirdlg.h>
#include <wx/filedlg.h>
#include <wx/gbsizer.h>
#include <wx/image.h>
#include <wx/imaglist.h>
#include <wx/itemid.h>
#include <wx/menu.h>
#include <wx/mimetype.h>
#include <wx/msgdlg.h>
#include <wx/notebook.h>
#include <wx/panel.h>
#include <wx/progdlg.h>
#include <wx/sizer.h>
2015-01-02 18:49:10 +01:00
#include <wx/slider.h>
#include <wx/spinctrl.h>
2014-02-22 23:36:30 +01:00
#include <wx/statbmp.h>
#include <wx/stattext.h>
#include <wx/textctrl.h>
#include <wx/thread.h>
#include <wx/treebase.h>
#include <wx/treectrl.h>
#include <wx/utils.h>
#include <wx/validate.h>
2013-09-07 23:02:49 +02:00
2014-02-17 05:18:15 -05:00
#include "Common/CommonPaths.h"
2014-09-07 20:06:58 -05:00
#include "Common/CommonTypes.h"
2014-02-22 23:36:30 +01:00
#include "Common/FileUtil.h"
#include "Common/IniFile.h"
2014-02-17 05:18:15 -05:00
#include "Common/StringUtil.h"
2014-02-22 23:36:30 +01:00
#include "Common/SysConf.h"
#include "Core/ActionReplay.h"
2014-02-17 05:18:15 -05:00
#include "Core/ConfigManager.h"
2014-02-22 23:36:30 +01:00
#include "Core/GeckoCodeConfig.h"
#include "Core/PatchEngine.h"
#include "Core/Boot/Boot.h"
2015-09-16 21:06:54 +02:00
#include "DiscIO/Blob.h"
2014-02-17 05:18:15 -05:00
#include "DiscIO/Filesystem.h"
2014-02-22 23:36:30 +01:00
#include "DiscIO/Volume.h"
2014-02-17 05:18:15 -05:00
#include "DiscIO/VolumeCreator.h"
#include "DolphinWX/ARCodeAddEdit.h"
2015-02-24 18:32:17 -05:00
#include "DolphinWX/GameListCtrl.h"
//#include "DolphinWX/Frame.h"
2014-02-22 23:36:30 +01:00
#include "DolphinWX/ISOFile.h"
2014-02-17 05:18:15 -05:00
#include "DolphinWX/ISOProperties.h"
#include "DolphinWX/PatchAddEdit.h"
#include "DolphinWX/WxUtils.h"
2014-10-18 17:32:50 -04:00
#include "DolphinWX/Cheats/GeckoCodeDiag.h"
2009-09-13 22:03:18 +00:00
2008-12-08 05:30:24 +00:00
BEGIN_EVENT_TABLE ( CISOProperties , wxDialog )
EVT_CLOSE ( CISOProperties :: OnClose )
2011-03-15 21:57:00 +00:00
EVT_BUTTON ( wxID_OK , CISOProperties :: OnCloseClick )
2008-12-08 05:30:24 +00:00
EVT_BUTTON ( ID_EDITCONFIG , CISOProperties :: OnEditConfig )
2014-04-12 05:50:12 -05:00
EVT_BUTTON ( ID_MD5SUMCOMPUTE , CISOProperties :: OnComputeMD5Sum )
2013-09-07 23:02:49 +02:00
EVT_BUTTON ( ID_SHOWDEFAULTCONFIG , CISOProperties :: OnShowDefaultConfig )
2008-12-08 05:30:24 +00:00
EVT_CHOICE ( ID_EMUSTATE , CISOProperties :: SetRefresh )
2009-02-21 14:40:34 +00:00
EVT_CHOICE ( ID_EMU_ISSUES , CISOProperties :: SetRefresh )
2008-12-08 05:30:24 +00:00
EVT_LISTBOX ( ID_PATCHES_LIST , CISOProperties :: ListSelectionChanged )
EVT_BUTTON ( ID_EDITPATCH , CISOProperties :: PatchButtonClicked )
EVT_BUTTON ( ID_ADDPATCH , CISOProperties :: PatchButtonClicked )
EVT_BUTTON ( ID_REMOVEPATCH , CISOProperties :: PatchButtonClicked )
EVT_LISTBOX ( ID_CHEATS_LIST , CISOProperties :: ListSelectionChanged )
EVT_BUTTON ( ID_EDITCHEAT , CISOProperties :: ActionReplayButtonClicked )
EVT_BUTTON ( ID_ADDCHEAT , CISOProperties :: ActionReplayButtonClicked )
EVT_BUTTON ( ID_REMOVECHEAT , CISOProperties :: ActionReplayButtonClicked )
EVT_MENU ( IDM_BNRSAVEAS , CISOProperties :: OnBannerImageSave )
EVT_TREE_ITEM_RIGHT_CLICK ( ID_TREECTRL , CISOProperties :: OnRightClickOnTree )
EVT_MENU ( IDM_EXTRACTFILE , CISOProperties :: OnExtractFile )
EVT_MENU ( IDM_EXTRACTDIR , CISOProperties :: OnExtractDir )
2009-09-13 22:03:18 +00:00
EVT_MENU ( IDM_EXTRACTALL , CISOProperties :: OnExtractDir )
2009-12-29 13:59:38 +00:00
EVT_MENU ( IDM_EXTRACTAPPLOADER , CISOProperties :: OnExtractDataFromHeader )
EVT_MENU ( IDM_EXTRACTDOL , CISOProperties :: OnExtractDataFromHeader )
2012-05-04 12:49:10 +02:00
EVT_MENU ( IDM_CHECKINTEGRITY , CISOProperties :: CheckPartitionIntegrity )
2009-02-14 17:32:03 +00:00
EVT_CHOICE ( ID_LANG , CISOProperties :: OnChangeBannerLang )
2008-12-08 05:30:24 +00:00
END_EVENT_TABLE ()
2015-09-13 14:17:58 +02:00
CISOProperties :: CISOProperties ( const GameListItem & game_list_item , wxWindow * parent , wxWindowID id , const wxString & title , const wxPoint & position , const wxSize & size , long style )
2008-12-08 05:30:24 +00:00
: wxDialog ( parent , id , title , position , size , style )
2015-09-13 14:17:58 +02:00
, OpenGameListItem ( game_list_item )
2008-12-08 05:30:24 +00:00
{
2013-09-07 23:02:49 +02:00
// Load ISO data
2015-12-06 23:15:51 -05:00
m_open_iso = DiscIO :: CreateVolumeFromFilename ( OpenGameListItem . GetFileName ());
2008-12-08 05:30:24 +00:00
2015-12-06 23:15:51 -05:00
game_id = m_open_iso -> GetUniqueID ();
2013-04-08 01:16:50 -04:00
2015-02-07 21:27:26 +01:00
// Load game INIs
2015-02-24 20:04:19 +01:00
GameIniFileLocal = File :: GetUserPath ( D_GAMESETTINGS_IDX ) + game_id + ".ini" ;
2015-12-06 23:15:51 -05:00
GameIniDefault = SConfig :: LoadDefaultGameIni ( game_id , m_open_iso -> GetRevision ());
GameIniLocal = SConfig :: LoadLocalGameIni ( game_id , m_open_iso -> GetRevision ());
2013-04-08 01:16:50 -04:00
2013-09-07 23:02:49 +02:00
// Setup GUI
bRefreshList = false ;
2015-04-09 17:44:53 +02:00
CreateGUIControls ();
2013-09-07 23:02:49 +02:00
LoadGameConfig ();
2008-12-08 05:30:24 +00:00
// Disk header and apploader
2011-12-18 22:01:46 -08:00
2015-12-06 23:15:51 -05:00
m_InternalName -> SetValue ( StrToWxStr ( m_open_iso -> GetInternalName ()));
m_GameID -> SetValue ( StrToWxStr ( m_open_iso -> GetUniqueID ()));
switch ( m_open_iso -> GetCountry ())
2008-12-08 05:30:24 +00:00
{
2014-10-30 10:35:46 -04:00
case DiscIO :: IVolume :: COUNTRY_AUSTRALIA :
2015-01-14 23:44:03 -05:00
m_Country -> SetValue ( _ ( "Australia" ));
2014-10-30 10:35:46 -04:00
break ;
2008-12-08 05:30:24 +00:00
case DiscIO :: IVolume :: COUNTRY_EUROPE :
2015-01-14 23:44:03 -05:00
m_Country -> SetValue ( _ ( "Europe" ));
2009-07-03 22:34:51 +00:00
break ;
2008-12-08 05:30:24 +00:00
case DiscIO :: IVolume :: COUNTRY_FRANCE :
2015-01-14 23:44:03 -05:00
m_Country -> SetValue ( _ ( "France" ));
2009-07-03 22:34:51 +00:00
break ;
2009-03-07 18:03:53 +00:00
case DiscIO :: IVolume :: COUNTRY_ITALY :
2015-01-14 23:44:03 -05:00
m_Country -> SetValue ( _ ( "Italy" ));
2008-12-08 05:30:24 +00:00
break ;
2014-10-30 10:35:46 -04:00
case DiscIO :: IVolume :: COUNTRY_GERMANY :
2015-01-14 23:44:03 -05:00
m_Country -> SetValue ( _ ( "Germany" ));
2014-10-30 10:35:46 -04:00
break ;
case DiscIO :: IVolume :: COUNTRY_NETHERLANDS :
2015-01-14 23:44:03 -05:00
m_Country -> SetValue ( _ ( "Netherlands" ));
2014-10-30 10:35:46 -04:00
break ;
2010-10-03 06:10:14 +00:00
case DiscIO :: IVolume :: COUNTRY_RUSSIA :
2015-01-14 23:44:03 -05:00
m_Country -> SetValue ( _ ( "Russia" ));
2010-10-03 06:10:14 +00:00
break ;
2014-10-30 10:35:46 -04:00
case DiscIO :: IVolume :: COUNTRY_SPAIN :
2015-01-14 23:44:03 -05:00
m_Country -> SetValue ( _ ( "Spain" ));
2014-10-30 10:35:46 -04:00
break ;
2008-12-08 05:30:24 +00:00
case DiscIO :: IVolume :: COUNTRY_USA :
2015-02-17 18:17:34 -06:00
m_Country -> SetValue ( _ ( "USA" ));
2008-12-08 05:30:24 +00:00
break ;
2009-07-03 22:34:51 +00:00
case DiscIO :: IVolume :: COUNTRY_JAPAN :
2015-01-14 23:44:03 -05:00
m_Country -> SetValue ( _ ( "Japan" ));
2009-07-03 22:34:51 +00:00
break ;
case DiscIO :: IVolume :: COUNTRY_KOREA :
2015-01-14 23:44:03 -05:00
m_Country -> SetValue ( _ ( "Korea" ));
2009-07-03 22:34:51 +00:00
break ;
case DiscIO :: IVolume :: COUNTRY_TAIWAN :
2015-01-14 23:44:03 -05:00
m_Country -> SetValue ( _ ( "Taiwan" ));
2009-07-03 22:34:51 +00:00
break ;
2015-04-08 18:55:16 -04:00
case DiscIO :: IVolume :: COUNTRY_WORLD :
m_Country -> SetValue ( _ ( "World" ));
break ;
2014-10-30 10:35:46 -04:00
case DiscIO :: IVolume :: COUNTRY_UNKNOWN :
2008-12-08 05:30:24 +00:00
default :
2015-01-14 23:44:03 -05:00
m_Country -> SetValue ( _ ( "Unknown" ));
2008-12-08 05:30:24 +00:00
break ;
}
2013-10-29 01:23:17 -04:00
2015-12-06 23:15:51 -05:00
wxString temp = "0x" + StrToWxStr ( m_open_iso -> GetMakerID ());
2008-12-08 05:30:24 +00:00
m_MakerID -> SetValue ( temp );
2015-12-06 23:15:51 -05:00
m_Revision -> SetValue ( StrToWxStr ( std :: to_string ( m_open_iso -> GetRevision ())));
m_Date -> SetValue ( StrToWxStr ( m_open_iso -> GetApploaderDate ()));
m_FST -> SetValue ( StrToWxStr ( std :: to_string ( m_open_iso -> GetFSTSize ())));
2008-12-08 05:30:24 +00:00
2015-04-09 17:44:53 +02:00
// Here we set all the info to be shown + we set the window title
2015-12-06 23:15:51 -05:00
bool wii = m_open_iso -> GetVolumeType () != DiscIO :: IVolume :: GAMECUBE_DISC ;
2015-06-12 13:56:53 +02:00
ChangeBannerDetails ( SConfig :: GetInstance (). GetCurrentLanguage ( wii ));
2013-10-29 01:23:17 -04:00
2015-09-13 14:17:58 +02:00
m_Banner -> SetBitmap ( OpenGameListItem . GetBitmap ());
2013-01-13 12:07:45 -06:00
m_Banner -> Bind ( wxEVT_RIGHT_DOWN , & CISOProperties :: RightClickOnBanner , this );
2008-12-08 05:30:24 +00:00
// Filesystem browser/dumper
2011-03-16 22:22:21 +00:00
// TODO : Should we add a way to browse the wad file ?
2015-12-06 23:15:51 -05:00
if ( m_open_iso -> GetVolumeType () != DiscIO :: IVolume :: WII_WAD )
2009-03-10 17:19:30 +00:00
{
2015-12-06 23:15:51 -05:00
if ( m_open_iso -> GetVolumeType () == DiscIO :: IVolume :: WII_DISC )
2009-03-10 17:19:30 +00:00
{
2015-04-15 09:29:24 +02:00
int partition_count = 0 ;
for ( int group = 0 ; group < 4 ; group ++ )
2011-03-16 22:22:21 +00:00
{
2015-04-15 09:29:24 +02:00
for ( u32 i = 0 ; i < 0xFFFFFFFF ; i ++ ) // yes, technically there can be OVER NINE THOUSAND partitions...
{
2015-09-13 14:17:58 +02:00
std :: unique_ptr < DiscIO :: IVolume > volume ( DiscIO :: CreateVolumeFromFilename ( OpenGameListItem . GetFileName (), group , i ));
2015-08-15 18:04:30 -04:00
if ( volume != nullptr )
2015-04-15 09:29:24 +02:00
{
2015-08-15 18:04:30 -04:00
std :: unique_ptr < DiscIO :: IFileSystem > file_system ( DiscIO :: CreateFileSystem ( volume . get ()));
if ( file_system != nullptr )
2015-04-15 09:29:24 +02:00
{
2015-08-15 18:04:30 -04:00
WiiPartition * const partition = new WiiPartition ( std :: move ( volume ), std :: move ( file_system ));
2015-04-15 09:29:24 +02:00
wxTreeItemId PartitionRoot =
m_Treectrl -> AppendItem ( RootId , wxString :: Format ( _ ( "Partition %i" ), partition_count ), 0 , 0 );
2015-08-15 18:04:30 -04:00
m_Treectrl -> SetItemData ( PartitionRoot , partition );
CreateDirectoryTree ( PartitionRoot , partition -> FileSystem -> GetFileList ());
2015-04-15 09:29:24 +02:00
if ( partition_count == 1 )
m_Treectrl -> Expand ( PartitionRoot );
2015-08-15 18:04:30 -04:00
2015-04-15 09:29:24 +02:00
partition_count ++ ;
}
}
else
{
break ;
}
}
2011-03-16 22:22:21 +00:00
}
2009-03-10 17:19:30 +00:00
}
2015-04-15 09:29:24 +02:00
else
2013-04-08 01:16:50 -04:00
{
2015-12-06 23:15:51 -05:00
m_filesystem = DiscIO :: CreateFileSystem ( m_open_iso . get ());
if ( m_filesystem )
CreateDirectoryTree ( RootId , m_filesystem -> GetFileList ());
2013-04-08 01:16:50 -04:00
}
2011-03-16 22:22:21 +00:00
m_Treectrl -> Expand ( RootId );
2009-03-10 17:19:30 +00:00
}
2008-12-08 05:30:24 +00:00
}
CISOProperties ::~ CISOProperties ()
{
}
2015-04-28 12:48:05 +02:00
size_t CISOProperties :: CreateDirectoryTree ( wxTreeItemId & parent , const std :: vector < DiscIO :: SFileInfo >& fileInfos )
2015-04-25 15:33:20 +02:00
{
if ( fileInfos . empty ())
return 0 ;
else
2015-04-28 12:48:05 +02:00
return CreateDirectoryTree ( parent , fileInfos , 1 , fileInfos . at ( 0 ). m_FileSize );
2015-04-25 15:33:20 +02:00
}
2009-09-13 22:03:18 +00:00
size_t CISOProperties :: CreateDirectoryTree ( wxTreeItemId & parent ,
2015-04-28 12:48:05 +02:00
const std :: vector < DiscIO :: SFileInfo >& fileInfos ,
2013-10-29 01:23:17 -04:00
const size_t _FirstIndex ,
2011-03-16 22:22:21 +00:00
const size_t _LastIndex )
2008-12-08 05:30:24 +00:00
{
2009-09-13 22:03:18 +00:00
size_t CurrentIndex = _FirstIndex ;
2008-12-08 05:30:24 +00:00
2009-09-13 22:03:18 +00:00
while ( CurrentIndex < _LastIndex )
2008-12-08 05:30:24 +00:00
{
2015-04-28 12:48:05 +02:00
const DiscIO :: SFileInfo rFileInfo = fileInfos [ CurrentIndex ];
std :: string filePath = rFileInfo . m_FullPath ;
2008-12-08 05:30:24 +00:00
2014-03-14 23:38:14 -04:00
// Trim the trailing '/' if it exists.
if ( filePath [ filePath . length () - 1 ] == DIR_SEP_CHR )
2013-04-08 01:16:50 -04:00
{
2014-03-14 23:38:14 -04:00
filePath . pop_back ();
2013-04-08 01:16:50 -04:00
}
2014-03-14 23:38:14 -04:00
// Cut off the path up to the actual filename or folder.
// Say we have "/music/stream/stream1.strm", the result will be "stream1.strm".
size_t dirSepIndex = filePath . find_last_of ( DIR_SEP_CHR );
if ( dirSepIndex != std :: string :: npos )
{
filePath = filePath . substr ( dirSepIndex + 1 );
}
2009-09-13 22:03:18 +00:00
// check next index
2015-04-28 12:48:05 +02:00
if ( rFileInfo . IsDirectory ())
2009-09-13 22:03:18 +00:00
{
2014-03-14 23:38:14 -04:00
wxTreeItemId item = m_Treectrl -> AppendItem ( parent , StrToWxStr ( filePath ), 1 , 1 );
2015-04-28 12:48:05 +02:00
CurrentIndex = CreateDirectoryTree ( item , fileInfos , CurrentIndex + 1 , ( size_t ) rFileInfo . m_FileSize );
2008-12-08 05:30:24 +00:00
}
2009-09-13 22:03:18 +00:00
else
{
2014-03-14 23:38:14 -04:00
m_Treectrl -> AppendItem ( parent , StrToWxStr ( filePath ), 2 , 2 );
2009-09-13 22:03:18 +00:00
CurrentIndex ++ ;
}
}
2008-12-08 05:30:24 +00:00
2009-09-13 22:03:18 +00:00
return CurrentIndex ;
2008-12-08 05:30:24 +00:00
}
2013-09-07 23:02:49 +02:00
long CISOProperties :: GetElementStyle ( const char * section , const char * key )
{
// Disable 3rd state if default gameini overrides the setting
if ( GameIniDefault . Exists ( section , key ))
return 0 ;
return wxCHK_3STATE | wxCHK_ALLOW_3RD_STATE_FOR_USER ;
}
2015-04-09 17:44:53 +02:00
void CISOProperties :: CreateGUIControls ()
2008-12-08 05:30:24 +00:00
{
2014-03-05 23:02:34 -05:00
wxButton * const EditConfig = new wxButton ( this , ID_EDITCONFIG , _ ( "Edit Config" ));
2014-09-22 13:45:28 -04:00
EditConfig -> SetToolTip ( _ ( "This will let you manually edit the INI config file." ));
2008-12-08 05:30:24 +00:00
2014-03-05 23:02:34 -05:00
wxButton * const EditConfigDefault = new wxButton ( this , ID_SHOWDEFAULTCONFIG , _ ( "Show Defaults" ));
2013-09-08 21:03:24 +02:00
EditConfigDefault -> SetToolTip ( _ ( "Opens the default (read-only) configuration for this game in an external text editor." ));
2008-12-08 05:30:24 +00:00
// Notebook
2014-03-05 23:02:34 -05:00
wxNotebook * const m_Notebook = new wxNotebook ( this , ID_NOTEBOOK );
wxPanel * const m_GameConfig = new wxPanel ( m_Notebook , ID_GAMECONFIG );
2008-12-08 05:30:24 +00:00
m_Notebook -> AddPage ( m_GameConfig , _ ( "GameConfig" ));
2014-03-05 23:02:34 -05:00
wxPanel * const m_PatchPage = new wxPanel ( m_Notebook , ID_PATCH_PAGE );
2009-03-24 23:10:43 +00:00
m_Notebook -> AddPage ( m_PatchPage , _ ( "Patches" ));
2014-03-05 23:02:34 -05:00
wxPanel * const m_CheatPage = new wxPanel ( m_Notebook , ID_ARCODE_PAGE );
2009-03-24 23:10:43 +00:00
m_Notebook -> AddPage ( m_CheatPage , _ ( "AR Codes" ));
2010-07-22 01:48:48 +00:00
m_geckocode_panel = new Gecko :: CodeConfigPanel ( m_Notebook );
2011-01-05 04:35:46 +00:00
m_Notebook -> AddPage ( m_geckocode_panel , _ ( "Gecko Codes" ));
2014-03-05 23:02:34 -05:00
wxPanel * const m_Information = new wxPanel ( m_Notebook , ID_INFORMATION );
2008-12-08 05:30:24 +00:00
m_Notebook -> AddPage ( m_Information , _ ( "Info" ));
2009-03-24 23:10:43 +00:00
// GameConfig editing - Overrides and emulation state
2014-03-05 23:02:34 -05:00
wxStaticText * const OverrideText = new wxStaticText ( m_GameConfig , wxID_ANY , _ ( "These settings override core Dolphin settings. \n Undetermined means the game uses Dolphin's setting." ));
2013-09-07 23:02:49 +02:00
2009-03-24 23:10:43 +00:00
// Core
2014-03-05 23:02:34 -05:00
CPUThread = new wxCheckBox ( m_GameConfig , ID_USEDUALCORE , _ ( "Enable Dual Core" ), wxDefaultPosition , wxDefaultSize , GetElementStyle ( "Core" , "CPUThread" ));
SkipIdle = new wxCheckBox ( m_GameConfig , ID_IDLESKIP , _ ( "Enable Idle Skipping" ), wxDefaultPosition , wxDefaultSize , GetElementStyle ( "Core" , "SkipIdle" ));
MMU = new wxCheckBox ( m_GameConfig , ID_MMU , _ ( "Enable MMU" ), wxDefaultPosition , wxDefaultSize , GetElementStyle ( "Core" , "MMU" ));
2011-01-05 04:35:46 +00:00
MMU -> SetToolTip ( _ ( "Enables the Memory Management Unit, needed for some games. (ON = Compatible, OFF = Fast)" ));
2014-03-05 23:02:34 -05:00
DCBZOFF = new wxCheckBox ( m_GameConfig , ID_DCBZOFF , _ ( "Skip DCBZ clearing" ), wxDefaultPosition , wxDefaultSize , GetElementStyle ( "Core" , "DCBZ" ));
2013-01-20 13:09:38 +11:00
DCBZOFF -> SetToolTip ( _ ( "Bypass the clearing of the data cache by the DCBZ instruction. Usually leave this option disabled." ));
2015-02-11 19:16:23 -08:00
FPRF = new wxCheckBox ( m_GameConfig , ID_FPRF , _ ( "Enable FPRF" ), wxDefaultPosition , wxDefaultSize , GetElementStyle ( "Core" , "FPRF" ));
2014-10-15 08:22:17 -07:00
FPRF -> SetToolTip ( _ ( "Enables Floating Point Result Flag calculation, needed for a few games. (ON = Compatible, OFF = Fast)" ));
2014-03-05 23:02:34 -05:00
SyncGPU = new wxCheckBox ( m_GameConfig , ID_SYNCGPU , _ ( "Synchronize GPU thread" ), wxDefaultPosition , wxDefaultSize , GetElementStyle ( "Core" , "SyncGPU" ));
2013-03-29 11:05:22 -05:00
SyncGPU -> SetToolTip ( _ ( "Synchronizes the GPU and CPU threads to help prevent random freezes in Dual Core mode. (ON = Compatible, OFF = Fast)" ));
2014-03-05 23:02:34 -05:00
FastDiscSpeed = new wxCheckBox ( m_GameConfig , ID_DISCSPEED , _ ( "Speed up Disc Transfer Rate" ), wxDefaultPosition , wxDefaultSize , GetElementStyle ( "Core" , "FastDiscSpeed" ));
2015-02-24 20:06:38 +01:00
FastDiscSpeed -> SetToolTip ( _ ( "Enable fast disc access. This can cause crashes and other problems in some games. (ON = Fast, OFF = Compatible)" ));
2014-03-05 23:02:34 -05:00
DSPHLE = new wxCheckBox ( m_GameConfig , ID_AUDIO_DSP_HLE , _ ( "DSP HLE emulation (fast)" ), wxDefaultPosition , wxDefaultSize , GetElementStyle ( "Core" , "DSPHLE" ));
2010-09-14 13:50:25 +00:00
2014-11-07 21:29:41 -05:00
wxBoxSizer * const sGPUDeterminism = new wxBoxSizer ( wxHORIZONTAL );
wxStaticText * const GPUDeterminismText = new wxStaticText ( m_GameConfig , wxID_ANY , _ ( "Deterministic dual core: " ));
arrayStringFor_GPUDeterminism . Add ( _ ( "Not Set" ));
arrayStringFor_GPUDeterminism . Add ( _ ( "auto" ));
arrayStringFor_GPUDeterminism . Add ( _ ( "none" ));
arrayStringFor_GPUDeterminism . Add ( _ ( "fake-completion" ));
2014-12-14 14:38:35 +11:00
GPUDeterminism = new wxChoice ( m_GameConfig , ID_GPUDETERMINISM , wxDefaultPosition , wxDefaultSize , arrayStringFor_GPUDeterminism );
2014-11-07 21:29:41 -05:00
sGPUDeterminism -> Add ( GPUDeterminismText );
sGPUDeterminism -> Add ( GPUDeterminism );
2009-03-24 23:10:43 +00:00
// Wii Console
2014-03-05 23:02:34 -05:00
EnableWideScreen = new wxCheckBox ( m_GameConfig , ID_ENABLEWIDESCREEN , _ ( "Enable WideScreen" ), wxDefaultPosition , wxDefaultSize , GetElementStyle ( "Wii" , "Widescreen" ));
2011-05-25 15:01:49 +00:00
2015-01-02 18:49:10 +01:00
// Stereoscopy
wxBoxSizer * const sDepthPercentage = new wxBoxSizer ( wxHORIZONTAL );
wxStaticText * const DepthPercentageText = new wxStaticText ( m_GameConfig , wxID_ANY , _ ( "Depth Percentage: " ));
DepthPercentage = new wxSlider ( m_GameConfig , ID_DEPTHPERCENTAGE , 100 , 0 , 200 );
DepthPercentage -> SetToolTip ( _ ( "This value is multiplied with the depth set in the graphics configuration." ));
sDepthPercentage -> Add ( DepthPercentageText );
sDepthPercentage -> Add ( DepthPercentage );
2015-12-17 23:37:35 +01:00
wxBoxSizer * const sConvergence = new wxBoxSizer ( wxHORIZONTAL );
wxStaticText * const ConvergenceText = new wxStaticText ( m_GameConfig , wxID_ANY , _ ( "Convergence: " ));
Convergence = new wxSpinCtrl ( m_GameConfig , ID_CONVERGENCE );
Convergence -> SetRange ( 0 , INT32_MAX );
Convergence -> SetToolTip ( _ ( "This value is added to the convergence value set in the graphics configuration." ));
sConvergence -> Add ( ConvergenceText );
sConvergence -> Add ( Convergence );
2015-01-02 18:49:10 +01:00
MonoDepth = new wxCheckBox ( m_GameConfig , ID_MONODEPTH , _ ( "Monoscopic Shadows" ), wxDefaultPosition , wxDefaultSize , GetElementStyle ( "Video_Stereoscopy" , "StereoEFBMonoDepth" ));
MonoDepth -> SetToolTip ( _ ( "Use a single depth buffer for both eyes. Needed for a few games." ));
2014-03-05 23:02:34 -05:00
wxBoxSizer * const sEmuState = new wxBoxSizer ( wxHORIZONTAL );
wxStaticText * const EmuStateText = new wxStaticText ( m_GameConfig , wxID_ANY , _ ( "Emulation State: " ));
2008-12-08 05:30:24 +00:00
arrayStringFor_EmuState . Add ( _ ( "Not Set" ));
arrayStringFor_EmuState . Add ( _ ( "Broken" ));
arrayStringFor_EmuState . Add ( _ ( "Intro" ));
arrayStringFor_EmuState . Add ( _ ( "In Game" ));
2009-09-25 16:29:00 +00:00
arrayStringFor_EmuState . Add ( _ ( "Playable" ));
2008-12-08 05:30:24 +00:00
arrayStringFor_EmuState . Add ( _ ( "Perfect" ));
2014-03-05 23:02:34 -05:00
EmuState = new wxChoice ( m_GameConfig , ID_EMUSTATE , wxDefaultPosition , wxDefaultSize , arrayStringFor_EmuState );
2011-03-16 22:22:21 +00:00
EmuIssues = new wxTextCtrl ( m_GameConfig , ID_EMU_ISSUES , wxEmptyString );
2008-12-08 05:30:24 +00:00
2014-03-05 23:02:34 -05:00
wxBoxSizer * const sConfigPage = new wxBoxSizer ( wxVERTICAL );
wxStaticBoxSizer * const sbCoreOverrides =
2011-03-16 22:22:21 +00:00
new wxStaticBoxSizer ( wxVERTICAL , m_GameConfig , _ ( "Core" ));
2011-02-04 23:44:11 +00:00
sbCoreOverrides -> Add ( CPUThread , 0 , wxLEFT , 5 );
sbCoreOverrides -> Add ( SkipIdle , 0 , wxLEFT , 5 );
sbCoreOverrides -> Add ( MMU , 0 , wxLEFT , 5 );
2013-02-16 12:51:09 +11:00
sbCoreOverrides -> Add ( DCBZOFF , 0 , wxLEFT , 5 );
2014-10-15 08:22:17 -07:00
sbCoreOverrides -> Add ( FPRF , 0 , wxLEFT , 5 );
2013-02-16 12:51:09 +11:00
sbCoreOverrides -> Add ( SyncGPU , 0 , wxLEFT , 5 );
2013-10-29 01:23:17 -04:00
sbCoreOverrides -> Add ( FastDiscSpeed , 0 , wxLEFT , 5 );
2011-02-04 23:44:11 +00:00
sbCoreOverrides -> Add ( DSPHLE , 0 , wxLEFT , 5 );
2014-11-07 21:29:41 -05:00
sbCoreOverrides -> Add ( sGPUDeterminism , 0 , wxEXPAND | wxALL , 5 );
2011-01-31 22:19:30 +00:00
2014-03-05 23:02:34 -05:00
wxStaticBoxSizer * const sbWiiOverrides = new wxStaticBoxSizer ( wxVERTICAL , m_GameConfig , _ ( "Wii Console" ));
2015-12-06 23:15:51 -05:00
if ( m_open_iso -> GetVolumeType () == DiscIO :: IVolume :: GAMECUBE_DISC )
2011-01-31 22:19:30 +00:00
{
sbWiiOverrides -> ShowItems ( false );
EnableWideScreen -> Hide ();
}
2011-02-04 23:44:11 +00:00
sbWiiOverrides -> Add ( EnableWideScreen , 0 , wxLEFT , 5 );
2011-01-31 22:19:30 +00:00
2015-01-02 18:49:10 +01:00
wxStaticBoxSizer * const sbStereoOverrides =
new wxStaticBoxSizer ( wxVERTICAL , m_GameConfig , _ ( "Stereoscopy" ));
sbStereoOverrides -> Add ( sDepthPercentage );
2015-12-17 23:37:35 +01:00
sbStereoOverrides -> Add ( sConvergence );
2015-01-02 18:49:10 +01:00
sbStereoOverrides -> Add ( MonoDepth );
2014-03-05 23:02:34 -05:00
wxStaticBoxSizer * const sbGameConfig = new wxStaticBoxSizer ( wxVERTICAL , m_GameConfig , _ ( "Game-Specific Settings" ));
2011-01-31 22:19:30 +00:00
sbGameConfig -> Add ( OverrideText , 0 , wxEXPAND | wxALL , 5 );
2009-03-24 23:10:43 +00:00
sbGameConfig -> Add ( sbCoreOverrides , 0 , wxEXPAND );
sbGameConfig -> Add ( sbWiiOverrides , 0 , wxEXPAND );
2015-01-02 18:49:10 +01:00
sbGameConfig -> Add ( sbStereoOverrides , 0 , wxEXPAND );
2009-03-24 23:10:43 +00:00
sConfigPage -> Add ( sbGameConfig , 0 , wxEXPAND | wxALL , 5 );
sEmuState -> Add ( EmuStateText , 0 , wxALIGN_CENTER_VERTICAL );
sEmuState -> Add ( EmuState , 0 , wxEXPAND );
2011-01-29 21:13:56 +00:00
sEmuState -> Add ( EmuIssues , 1 , wxEXPAND );
2009-03-24 23:10:43 +00:00
sConfigPage -> Add ( sEmuState , 0 , wxEXPAND | wxALL , 5 );
m_GameConfig -> SetSizer ( sConfigPage );
2013-10-29 01:23:17 -04:00
2008-12-08 05:30:24 +00:00
// Patches
2014-03-05 23:02:34 -05:00
wxBoxSizer * const sPatches = new wxBoxSizer ( wxVERTICAL );
2015-04-10 19:49:09 -04:00
Patches = new wxCheckListBox ( m_PatchPage , ID_PATCHES_LIST , wxDefaultPosition , wxDefaultSize , 0 , nullptr , wxLB_HSCROLL );
2014-03-05 23:02:34 -05:00
wxBoxSizer * const sPatchButtons = new wxBoxSizer ( wxHORIZONTAL );
2011-03-16 22:22:21 +00:00
EditPatch = new wxButton ( m_PatchPage , ID_EDITPATCH , _ ( "Edit..." ));
2014-03-05 23:02:34 -05:00
wxButton * const AddPatch = new wxButton ( m_PatchPage , ID_ADDPATCH , _ ( "Add..." ));
2011-03-16 22:22:21 +00:00
RemovePatch = new wxButton ( m_PatchPage , ID_REMOVEPATCH , _ ( "Remove" ));
2015-02-14 16:00:15 -05:00
EditPatch -> Disable ();
RemovePatch -> Disable ();
2008-12-08 05:30:24 +00:00
2011-03-16 22:22:21 +00:00
wxBoxSizer * sPatchPage = new wxBoxSizer ( wxVERTICAL );
2009-03-24 23:10:43 +00:00
sPatches -> Add ( Patches , 1 , wxEXPAND | wxALL , 0 );
sPatchButtons -> Add ( EditPatch , 0 , wxEXPAND | wxALL , 0 );
sPatchButtons -> AddStretchSpacer ();
sPatchButtons -> Add ( AddPatch , 0 , wxEXPAND | wxALL , 0 );
sPatchButtons -> Add ( RemovePatch , 0 , wxEXPAND | wxALL , 0 );
sPatches -> Add ( sPatchButtons , 0 , wxEXPAND | wxALL , 0 );
sPatchPage -> Add ( sPatches , 1 , wxEXPAND | wxALL , 5 );
m_PatchPage -> SetSizer ( sPatchPage );
2009-02-21 14:40:34 +00:00
2013-10-29 01:23:17 -04:00
2008-12-08 05:30:24 +00:00
// Action Replay Cheats
2011-03-16 22:22:21 +00:00
wxBoxSizer * const sCheats = new wxBoxSizer ( wxVERTICAL );
2015-04-10 19:49:09 -04:00
Cheats = new wxCheckListBox ( m_CheatPage , ID_CHEATS_LIST , wxDefaultPosition , wxDefaultSize , 0 , nullptr , wxLB_HSCROLL );
2011-03-16 22:22:21 +00:00
wxBoxSizer * const sCheatButtons = new wxBoxSizer ( wxHORIZONTAL );
EditCheat = new wxButton ( m_CheatPage , ID_EDITCHEAT , _ ( "Edit..." ));
wxButton * const AddCheat = new wxButton ( m_CheatPage , ID_ADDCHEAT , _ ( "Add..." ));
2014-03-05 23:02:34 -05:00
RemoveCheat = new wxButton ( m_CheatPage , ID_REMOVECHEAT , _ ( "Remove" ));
2015-02-14 16:00:15 -05:00
EditCheat -> Disable ();
RemoveCheat -> Disable ();
2008-12-08 05:30:24 +00:00
2011-03-16 22:22:21 +00:00
wxBoxSizer * sCheatPage = new wxBoxSizer ( wxVERTICAL );
2008-12-08 05:30:24 +00:00
sCheats -> Add ( Cheats , 1 , wxEXPAND | wxALL , 0 );
sCheatButtons -> Add ( EditCheat , 0 , wxEXPAND | wxALL , 0 );
sCheatButtons -> AddStretchSpacer ();
sCheatButtons -> Add ( AddCheat , 0 , wxEXPAND | wxALL , 0 );
sCheatButtons -> Add ( RemoveCheat , 0 , wxEXPAND | wxALL , 0 );
sCheats -> Add ( sCheatButtons , 0 , wxEXPAND | wxALL , 0 );
2009-03-24 23:10:43 +00:00
sCheatPage -> Add ( sCheats , 1 , wxEXPAND | wxALL , 5 );
2008-12-08 05:30:24 +00:00
m_CheatPage -> SetSizer ( sCheatPage );
2013-10-29 01:23:17 -04:00
2015-05-11 11:19:30 +02:00
wxStaticText * const m_InternalNameText = new wxStaticText ( m_Information , wxID_ANY , _ ( "Internal Name:" ));
m_InternalName = new wxTextCtrl ( m_Information , ID_NAME , wxEmptyString , wxDefaultPosition , wxDefaultSize , wxTE_READONLY );
2014-03-05 23:02:34 -05:00
wxStaticText * const m_GameIDText = new wxStaticText ( m_Information , wxID_ANY , _ ( "Game ID:" ));
m_GameID = new wxTextCtrl ( m_Information , ID_GAMEID , wxEmptyString , wxDefaultPosition , wxDefaultSize , wxTE_READONLY );
wxStaticText * const m_CountryText = new wxStaticText ( m_Information , wxID_ANY , _ ( "Country:" ));
m_Country = new wxTextCtrl ( m_Information , ID_COUNTRY , wxEmptyString , wxDefaultPosition , wxDefaultSize , wxTE_READONLY );
wxStaticText * const m_MakerIDText = new wxStaticText ( m_Information , wxID_ANY , _ ( "Maker ID:" ));
m_MakerID = new wxTextCtrl ( m_Information , ID_MAKERID , wxEmptyString , wxDefaultPosition , wxDefaultSize , wxTE_READONLY );
wxStaticText * const m_RevisionText = new wxStaticText ( m_Information , wxID_ANY , _ ( "Revision:" ));
m_Revision = new wxTextCtrl ( m_Information , ID_REVISION , wxEmptyString , wxDefaultPosition , wxDefaultSize , wxTE_READONLY );
2015-01-03 17:05:35 -05:00
wxStaticText * const m_DateText = new wxStaticText ( m_Information , wxID_ANY , _ ( "Apploader Date:" ));
2014-03-05 23:02:34 -05:00
m_Date = new wxTextCtrl ( m_Information , ID_DATE , wxEmptyString , wxDefaultPosition , wxDefaultSize , wxTE_READONLY );
wxStaticText * const m_FSTText = new wxStaticText ( m_Information , wxID_ANY , _ ( "FST Size:" ));
m_FST = new wxTextCtrl ( m_Information , ID_FST , wxEmptyString , wxDefaultPosition , wxDefaultSize , wxTE_READONLY );
2014-04-12 05:50:12 -05:00
wxStaticText * const m_MD5SumText = new wxStaticText ( m_Information , wxID_ANY , _ ( "MD5 Checksum:" ));
m_MD5Sum = new wxTextCtrl ( m_Information , ID_MD5SUM , wxEmptyString , wxDefaultPosition , wxDefaultSize , wxTE_READONLY );
m_MD5SumCompute = new wxButton ( m_Information , ID_MD5SUMCOMPUTE , _ ( "Compute" ));
2008-12-08 05:30:24 +00:00
2014-03-05 23:02:34 -05:00
wxStaticText * const m_LangText = new wxStaticText ( m_Information , wxID_ANY , _ ( "Show Language:" ));
2013-10-29 01:23:17 -04:00
2015-12-06 23:15:51 -05:00
bool wii = m_open_iso -> GetVolumeType () != DiscIO :: IVolume :: GAMECUBE_DISC ;
2015-06-12 13:56:53 +02:00
DiscIO :: IVolume :: ELanguage preferred_language = SConfig :: GetInstance (). GetCurrentLanguage ( wii );
2015-04-09 17:44:53 +02:00
2015-09-13 14:17:58 +02:00
std :: vector < DiscIO :: IVolume :: ELanguage > languages = OpenGameListItem . GetLanguages ();
2015-04-09 17:44:53 +02:00
int preferred_language_index = 0 ;
for ( size_t i = 0 ; i < languages . size (); ++ i )
{
if ( languages [ i ] == preferred_language )
preferred_language_index = i ;
switch ( languages [ i ])
{
2015-05-08 17:28:03 -04:00
case DiscIO :: IVolume :: LANGUAGE_JAPANESE :
2015-04-09 17:44:53 +02:00
arrayStringFor_Lang . Add ( _ ( "Japanese" ));
break ;
2015-05-08 17:28:03 -04:00
case DiscIO :: IVolume :: LANGUAGE_ENGLISH :
2015-04-09 17:44:53 +02:00
arrayStringFor_Lang . Add ( _ ( "English" ));
break ;
2015-05-08 17:28:03 -04:00
case DiscIO :: IVolume :: LANGUAGE_GERMAN :
2015-04-09 17:44:53 +02:00
arrayStringFor_Lang . Add ( _ ( "German" ));
break ;
2015-05-08 17:28:03 -04:00
case DiscIO :: IVolume :: LANGUAGE_FRENCH :
2015-04-09 17:44:53 +02:00
arrayStringFor_Lang . Add ( _ ( "French" ));
break ;
2015-05-08 17:28:03 -04:00
case DiscIO :: IVolume :: LANGUAGE_SPANISH :
2015-04-09 17:44:53 +02:00
arrayStringFor_Lang . Add ( _ ( "Spanish" ));
break ;
2015-05-08 17:28:03 -04:00
case DiscIO :: IVolume :: LANGUAGE_ITALIAN :
2015-04-09 17:44:53 +02:00
arrayStringFor_Lang . Add ( _ ( "Italian" ));
break ;
2015-05-08 17:28:03 -04:00
case DiscIO :: IVolume :: LANGUAGE_DUTCH :
2015-04-09 17:44:53 +02:00
arrayStringFor_Lang . Add ( _ ( "Dutch" ));
break ;
2015-05-08 17:28:03 -04:00
case DiscIO :: IVolume :: LANGUAGE_SIMPLIFIED_CHINESE :
2015-04-09 17:44:53 +02:00
arrayStringFor_Lang . Add ( _ ( "Simplified Chinese" ));
break ;
2015-05-08 17:28:03 -04:00
case DiscIO :: IVolume :: LANGUAGE_TRADITIONAL_CHINESE :
2015-04-09 17:44:53 +02:00
arrayStringFor_Lang . Add ( _ ( "Traditional Chinese" ));
break ;
2015-05-08 17:28:03 -04:00
case DiscIO :: IVolume :: LANGUAGE_KOREAN :
2015-04-09 17:44:53 +02:00
arrayStringFor_Lang . Add ( _ ( "Korean" ));
break ;
2015-05-08 17:28:03 -04:00
case DiscIO :: IVolume :: LANGUAGE_UNKNOWN :
2015-04-09 17:44:53 +02:00
default :
arrayStringFor_Lang . Add ( _ ( "Unknown" ));
break ;
}
2013-09-14 15:07:53 -07:00
}
2011-03-16 22:22:21 +00:00
m_Lang = new wxChoice ( m_Information , ID_LANG , wxDefaultPosition , wxDefaultSize , arrayStringFor_Lang );
2015-04-09 17:44:53 +02:00
m_Lang -> SetSelection ( preferred_language_index );
if ( arrayStringFor_Lang . size () <= 1 )
m_Lang -> Disable ();
2013-10-29 01:23:17 -04:00
2015-05-11 11:19:30 +02:00
wxStaticText * const m_NameText = new wxStaticText ( m_Information , wxID_ANY , _ ( "Name:" ));
m_Name = new wxTextCtrl ( m_Information , ID_SHORTNAME , wxEmptyString , wxDefaultPosition , wxDefaultSize , wxTE_READONLY );
2014-03-05 23:02:34 -05:00
wxStaticText * const m_MakerText = new wxStaticText ( m_Information , wxID_ANY , _ ( "Maker:" ));
2008-12-08 05:30:24 +00:00
m_Maker = new wxTextCtrl ( m_Information , ID_MAKER , wxEmptyString , wxDefaultPosition , wxDefaultSize , wxTE_READONLY );
2015-05-11 11:19:30 +02:00
wxStaticText * const m_CommentText = new wxStaticText ( m_Information , wxID_ANY , _ ( "Description:" ));
2008-12-08 05:30:24 +00:00
m_Comment = new wxTextCtrl ( m_Information , ID_COMMENT , wxEmptyString , wxDefaultPosition , wxDefaultSize , wxTE_MULTILINE | wxTE_READONLY );
2014-03-05 23:02:34 -05:00
wxStaticText * const m_BannerText = new wxStaticText ( m_Information , wxID_ANY , _ ( "Banner:" ));
m_Banner = new wxStaticBitmap ( m_Information , ID_BANNER , wxNullBitmap , wxDefaultPosition , wxSize ( 96 , 32 ));
2008-12-08 05:30:24 +00:00
2010-06-11 08:39:03 +00:00
// ISO Details
2014-03-05 23:02:34 -05:00
wxGridBagSizer * const sISODetails = new wxGridBagSizer ( 0 , 0 );
2015-05-11 11:19:30 +02:00
sISODetails -> Add ( m_InternalNameText , wxGBPosition ( 0 , 0 ), wxGBSpan ( 1 , 1 ), wxALIGN_CENTER_VERTICAL | wxALL , 5 );
sISODetails -> Add ( m_InternalName , wxGBPosition ( 0 , 1 ), wxGBSpan ( 1 , 2 ), wxEXPAND | wxALL , 5 );
2008-12-08 05:30:24 +00:00
sISODetails -> Add ( m_GameIDText , wxGBPosition ( 1 , 0 ), wxGBSpan ( 1 , 1 ), wxALIGN_CENTER_VERTICAL | wxALL , 5 );
2014-04-12 05:50:12 -05:00
sISODetails -> Add ( m_GameID , wxGBPosition ( 1 , 1 ), wxGBSpan ( 1 , 2 ), wxEXPAND | wxALL , 5 );
2008-12-08 05:30:24 +00:00
sISODetails -> Add ( m_CountryText , wxGBPosition ( 2 , 0 ), wxGBSpan ( 1 , 1 ), wxALIGN_CENTER_VERTICAL | wxALL , 5 );
2014-04-12 05:50:12 -05:00
sISODetails -> Add ( m_Country , wxGBPosition ( 2 , 1 ), wxGBSpan ( 1 , 2 ), wxEXPAND | wxALL , 5 );
2008-12-08 05:30:24 +00:00
sISODetails -> Add ( m_MakerIDText , wxGBPosition ( 3 , 0 ), wxGBSpan ( 1 , 1 ), wxALIGN_CENTER_VERTICAL | wxALL , 5 );
2014-04-12 05:50:12 -05:00
sISODetails -> Add ( m_MakerID , wxGBPosition ( 3 , 1 ), wxGBSpan ( 1 , 2 ), wxEXPAND | wxALL , 5 );
2013-04-16 22:29:01 -05:00
sISODetails -> Add ( m_RevisionText , wxGBPosition ( 4 , 0 ), wxGBSpan ( 1 , 1 ), wxALIGN_CENTER_VERTICAL | wxALL , 5 );
2014-04-12 05:50:12 -05:00
sISODetails -> Add ( m_Revision , wxGBPosition ( 4 , 1 ), wxGBSpan ( 1 , 2 ), wxEXPAND | wxALL , 5 );
2013-04-16 22:29:01 -05:00
sISODetails -> Add ( m_DateText , wxGBPosition ( 5 , 0 ), wxGBSpan ( 1 , 1 ), wxALIGN_CENTER_VERTICAL | wxALL , 5 );
2014-04-12 05:50:12 -05:00
sISODetails -> Add ( m_Date , wxGBPosition ( 5 , 1 ), wxGBSpan ( 1 , 2 ), wxEXPAND | wxALL , 5 );
2013-04-16 22:29:01 -05:00
sISODetails -> Add ( m_FSTText , wxGBPosition ( 6 , 0 ), wxGBSpan ( 1 , 1 ), wxALIGN_CENTER_VERTICAL | wxALL , 5 );
2014-04-12 05:50:12 -05:00
sISODetails -> Add ( m_FST , wxGBPosition ( 6 , 1 ), wxGBSpan ( 1 , 2 ), wxEXPAND | wxALL , 5 );
sISODetails -> Add ( m_MD5SumText , wxGBPosition ( 7 , 0 ), wxGBSpan ( 1 , 1 ), wxALIGN_CENTER_VERTICAL | wxALL , 5 );
sISODetails -> Add ( m_MD5Sum , wxGBPosition ( 7 , 1 ), wxGBSpan ( 1 , 1 ), wxEXPAND | wxALL , 5 );
wxSizer * sMD5SumButtonSizer = CreateButtonSizer ( wxNO_DEFAULT );
sMD5SumButtonSizer -> Add ( m_MD5SumCompute );
sISODetails -> Add ( sMD5SumButtonSizer , wxGBPosition ( 7 , 2 ), wxGBSpan ( 1 , 1 ), wxEXPAND | wxALL , 5 );
2010-06-14 22:01:10 +00:00
sISODetails -> AddGrowableCol ( 1 );
2014-03-05 23:02:34 -05:00
wxStaticBoxSizer * const sbISODetails =
2011-03-16 22:22:21 +00:00
new wxStaticBoxSizer ( wxVERTICAL , m_Information , _ ( "ISO Details" ));
2008-12-08 05:30:24 +00:00
sbISODetails -> Add ( sISODetails , 0 , wxEXPAND , 5 );
2009-02-14 17:32:03 +00:00
2010-06-11 08:39:03 +00:00
// Banner Details
2014-03-05 23:02:34 -05:00
wxGridBagSizer * const sBannerDetails = new wxGridBagSizer ( 0 , 0 );
2009-02-14 17:32:03 +00:00
sBannerDetails -> Add ( m_LangText , wxGBPosition ( 0 , 0 ), wxGBSpan ( 1 , 1 ), wxALIGN_CENTER_VERTICAL | wxALL , 5 );
sBannerDetails -> Add ( m_Lang , wxGBPosition ( 0 , 1 ), wxGBSpan ( 1 , 1 ), wxEXPAND | wxALL , 5 );
2015-05-11 11:19:30 +02:00
sBannerDetails -> Add ( m_NameText , wxGBPosition ( 1 , 0 ), wxGBSpan ( 1 , 1 ), wxALIGN_CENTER_VERTICAL | wxALL , 5 );
sBannerDetails -> Add ( m_Name , wxGBPosition ( 1 , 1 ), wxGBSpan ( 1 , 1 ), wxEXPAND | wxALL , 5 );
2009-02-14 17:32:03 +00:00
sBannerDetails -> Add ( m_MakerText , wxGBPosition ( 2 , 0 ), wxGBSpan ( 1 , 1 ), wxALIGN_CENTER_VERTICAL | wxALL , 5 );
sBannerDetails -> Add ( m_Maker , wxGBPosition ( 2 , 1 ), wxGBSpan ( 1 , 1 ), wxEXPAND | wxALL , 5 );
sBannerDetails -> Add ( m_CommentText , wxGBPosition ( 3 , 0 ), wxGBSpan ( 1 , 1 ), wxALL , 5 );
sBannerDetails -> Add ( m_Comment , wxGBPosition ( 3 , 1 ), wxGBSpan ( 1 , 1 ), wxEXPAND | wxALL , 5 );
sBannerDetails -> Add ( m_BannerText , wxGBPosition ( 4 , 0 ), wxGBSpan ( 1 , 1 ), wxALL , 5 );
sBannerDetails -> Add ( m_Banner , wxGBPosition ( 4 , 1 ), wxGBSpan ( 1 , 1 ), wxEXPAND | wxALL , 5 );
2010-06-11 08:39:03 +00:00
sBannerDetails -> AddGrowableCol ( 1 );
2014-03-05 23:02:34 -05:00
wxStaticBoxSizer * const sbBannerDetails =
2011-03-16 22:22:21 +00:00
new wxStaticBoxSizer ( wxVERTICAL , m_Information , _ ( "Banner Details" ));
2010-06-11 08:39:03 +00:00
sbBannerDetails -> Add ( sBannerDetails , 0 , wxEXPAND , 5 );
2014-03-05 23:02:34 -05:00
wxBoxSizer * const sInfoPage = new wxBoxSizer ( wxVERTICAL );
2008-12-08 05:30:24 +00:00
sInfoPage -> Add ( sbISODetails , 0 , wxEXPAND | wxALL , 5 );
sInfoPage -> Add ( sbBannerDetails , 0 , wxEXPAND | wxALL , 5 );
m_Information -> SetSizer ( sInfoPage );
2009-03-24 23:10:43 +00:00
2015-12-06 23:15:51 -05:00
if ( m_open_iso -> GetVolumeType () != DiscIO :: IVolume :: WII_WAD )
2011-03-16 22:22:21 +00:00
{
2015-12-06 23:15:51 -05:00
wxPanel * const filesystem_panel = new wxPanel ( m_Notebook , ID_FILESYSTEM );
m_Notebook -> AddPage ( filesystem_panel , _ ( "Filesystem" ));
2009-09-13 22:03:18 +00:00
2011-03-16 22:22:21 +00:00
// Filesystem icons
2014-03-05 23:02:34 -05:00
wxImageList * const m_iconList = new wxImageList ( 16 , 16 );
2015-12-19 11:34:01 +01:00
m_iconList -> Add ( WxUtils :: LoadResourceBitmap ( "isoproperties_disc" )); // 0
m_iconList -> Add ( WxUtils :: LoadResourceBitmap ( "isoproperties_folder" )); // 1
m_iconList -> Add ( WxUtils :: LoadResourceBitmap ( "isoproperties_file" )); // 2
2008-12-08 05:30:24 +00:00
2011-03-16 22:22:21 +00:00
// Filesystem tree
2015-12-06 23:15:51 -05:00
m_Treectrl = new wxTreeCtrl ( filesystem_panel , ID_TREECTRL );
2011-03-16 22:22:21 +00:00
m_Treectrl -> AssignImageList ( m_iconList );
2014-03-09 21:14:26 +01:00
RootId = m_Treectrl -> AddRoot ( _ ( "Disc" ), 0 , 0 , nullptr );
2008-12-08 05:30:24 +00:00
2011-03-16 22:22:21 +00:00
wxBoxSizer * sTreePage = new wxBoxSizer ( wxVERTICAL );
sTreePage -> Add ( m_Treectrl , 1 , wxEXPAND | wxALL , 5 );
2015-12-06 23:15:51 -05:00
filesystem_panel -> SetSizer ( sTreePage );
2011-03-16 22:22:21 +00:00
}
wxSizer * sButtons = CreateButtonSizer ( wxNO_DEFAULT );
2013-09-08 21:03:24 +02:00
sButtons -> Prepend ( EditConfigDefault );
2011-06-03 12:26:32 +00:00
sButtons -> Prepend ( EditConfig );
sButtons -> Add ( new wxButton ( this , wxID_OK , _ ( "Close" )));
2009-06-07 02:54:07 +00:00
2013-09-07 23:02:49 +02:00
// If there is no default gameini, disable the button.
2015-02-24 20:04:19 +01:00
bool game_ini_exists = false ;
2015-12-06 23:15:51 -05:00
for ( const std :: string & ini_filename : SConfig :: GetGameIniFilenames ( game_id , m_open_iso -> GetRevision ()))
2015-02-24 20:04:19 +01:00
{
if ( File :: Exists ( File :: GetSysDirectory () + GAMESETTINGS_DIR DIR_SEP + ini_filename ))
{
game_ini_exists = true ;
break ;
}
}
if ( ! game_ini_exists )
2013-09-07 23:02:49 +02:00
EditConfigDefault -> Disable ();
2009-03-24 23:10:43 +00:00
// Add notebook and buttons to the dialog
2014-03-05 23:02:34 -05:00
wxBoxSizer * sMain = new wxBoxSizer ( wxVERTICAL );
2009-02-14 17:32:03 +00:00
sMain -> Add ( m_Notebook , 1 , wxEXPAND | wxALL , 5 );
2011-06-03 12:26:32 +00:00
sMain -> Add ( sButtons , 0 , wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM , 5 );
2011-03-16 22:22:21 +00:00
sMain -> SetMinSize ( wxSize ( 500 , - 1 ));
2010-06-14 22:01:10 +00:00
2009-02-14 17:32:03 +00:00
SetSizerAndFit ( sMain );
2011-03-15 21:57:00 +00:00
Center ();
2011-03-16 22:22:21 +00:00
SetFocus ();
2008-12-08 05:30:24 +00:00
}
void CISOProperties :: OnClose ( wxCloseEvent & WXUNUSED ( event ))
{
if ( ! SaveGameConfig ())
2014-07-24 21:46:46 -04:00
WxUtils :: ShowErrorDialog ( wxString :: Format ( _ ( "Could not save %s." ), GameIniFileLocal . c_str ()));
2015-02-24 18:32:17 -05:00
if ( bRefreshList )
(( CGameListCtrl * ) GetParent ()) -> Update ();
Destroy ();
2008-12-08 05:30:24 +00:00
}
void CISOProperties :: OnCloseClick ( wxCommandEvent & WXUNUSED ( event ))
{
Close ();
}
void CISOProperties :: RightClickOnBanner ( wxMouseEvent & event )
{
2014-11-11 09:50:11 -05:00
wxMenu popupMenu ;
popupMenu . Append ( IDM_BNRSAVEAS , _ ( "Save as..." ));
PopupMenu ( & popupMenu );
2008-12-08 05:30:24 +00:00
event . Skip ();
}
void CISOProperties :: OnBannerImageSave ( wxCommandEvent & WXUNUSED ( event ))
{
wxString dirHome ;
2014-10-06 17:42:24 -04:00
wxFileDialog dialog ( this , _ ( "Save as..." ), wxGetHomeDir ( & dirHome ), wxString :: Format ( "%s.png" , m_GameID -> GetValue (). c_str ()),
2014-03-05 23:02:34 -05:00
wxALL_FILES_PATTERN , wxFD_SAVE | wxFD_OVERWRITE_PROMPT );
2008-12-08 05:30:24 +00:00
if ( dialog . ShowModal () == wxID_OK )
{
m_Banner -> GetBitmap (). ConvertToImage (). SaveFile ( dialog . GetPath ());
}
2015-06-02 19:53:51 -04:00
Raise ();
2008-12-08 05:30:24 +00:00
}
void CISOProperties :: OnRightClickOnTree ( wxTreeEvent & event )
{
m_Treectrl -> SelectItem ( event . GetItem ());
2014-11-11 09:50:11 -05:00
wxMenu popupMenu ;
2009-09-13 22:03:18 +00:00
2014-03-11 00:30:55 +13:00
if ( m_Treectrl -> GetItemImage ( m_Treectrl -> GetSelection ()) == 0 &&
m_Treectrl -> GetFirstVisibleItem () != m_Treectrl -> GetSelection ())
2013-06-17 22:51:15 +12:00
{
2014-11-11 09:50:11 -05:00
popupMenu . Append ( IDM_EXTRACTDIR , _ ( "Extract Partition..." ));
2013-06-17 22:51:15 +12:00
}
2009-09-13 22:03:18 +00:00
else if ( m_Treectrl -> GetItemImage ( m_Treectrl -> GetSelection ()) == 1 )
2014-03-05 23:02:34 -05:00
{
2014-11-11 09:50:11 -05:00
popupMenu . Append ( IDM_EXTRACTDIR , _ ( "Extract Directory..." ));
2014-03-05 23:02:34 -05:00
}
2009-09-13 22:03:18 +00:00
else if ( m_Treectrl -> GetItemImage ( m_Treectrl -> GetSelection ()) == 2 )
2014-03-05 23:02:34 -05:00
{
2014-11-11 09:50:11 -05:00
popupMenu . Append ( IDM_EXTRACTFILE , _ ( "Extract File..." ));
2014-03-05 23:02:34 -05:00
}
2013-10-29 01:23:17 -04:00
2014-11-11 09:50:11 -05:00
popupMenu . Append ( IDM_EXTRACTALL , _ ( "Extract All Files..." ));
2013-10-29 01:23:17 -04:00
2015-12-06 23:15:51 -05:00
if ( m_open_iso -> GetVolumeType () != DiscIO :: IVolume :: WII_DISC ||
2014-03-17 03:04:22 -04:00
( m_Treectrl -> GetItemImage ( m_Treectrl -> GetSelection ()) == 0 &&
m_Treectrl -> GetFirstVisibleItem () != m_Treectrl -> GetSelection ()))
2012-05-04 12:49:10 +02:00
{
2014-11-11 09:50:11 -05:00
popupMenu . AppendSeparator ();
popupMenu . Append ( IDM_EXTRACTAPPLOADER , _ ( "Extract Apploader..." ));
popupMenu . Append ( IDM_EXTRACTDOL , _ ( "Extract DOL..." ));
2014-03-17 03:04:22 -04:00
}
if ( m_Treectrl -> GetItemImage ( m_Treectrl -> GetSelection ()) == 0 &&
m_Treectrl -> GetFirstVisibleItem () != m_Treectrl -> GetSelection ())
{
2014-11-11 09:50:11 -05:00
popupMenu . AppendSeparator ();
popupMenu . Append ( IDM_CHECKINTEGRITY , _ ( "Check Partition Integrity" ));
2012-05-04 12:49:10 +02:00
}
2013-10-29 01:23:17 -04:00
2014-11-11 09:50:11 -05:00
PopupMenu ( & popupMenu );
2008-12-08 05:30:24 +00:00
event . Skip ();
}
void CISOProperties :: OnExtractFile ( wxCommandEvent & WXUNUSED ( event ))
{
2014-03-05 23:02:34 -05:00
wxString File = m_Treectrl -> GetItemText ( m_Treectrl -> GetSelection ());
2008-12-08 05:30:24 +00:00
2014-03-05 23:02:34 -05:00
wxString Path = wxFileSelector (
2011-01-05 04:35:46 +00:00
_ ( "Export File" ),
2008-12-08 05:30:24 +00:00
wxEmptyString , File , wxEmptyString ,
2011-01-06 13:57:46 +00:00
wxGetTranslation ( wxALL_FILES ),
2008-12-08 05:30:24 +00:00
wxFD_SAVE ,
this );
if ( ! Path || ! File )
return ;
while ( m_Treectrl -> GetItemParent ( m_Treectrl -> GetSelection ()) != m_Treectrl -> GetRootItem ())
{
2014-03-05 23:02:34 -05:00
wxString temp = m_Treectrl -> GetItemText ( m_Treectrl -> GetItemParent ( m_Treectrl -> GetSelection ()));
2014-05-17 13:17:28 -04:00
File = temp + DIR_SEP_CHR + File ;
2008-12-08 05:30:24 +00:00
m_Treectrl -> SelectItem ( m_Treectrl -> GetItemParent ( m_Treectrl -> GetSelection ()));
}
2015-12-06 23:15:51 -05:00
if ( m_open_iso -> GetVolumeType () == DiscIO :: IVolume :: WII_DISC )
2009-03-10 17:19:30 +00:00
{
2015-04-24 22:08:15 +02:00
const wxTreeItemId tree_selection = m_Treectrl -> GetSelection ();
WiiPartition * partition = reinterpret_cast < WiiPartition *> ( m_Treectrl -> GetItemData ( tree_selection ));
File . erase ( 0 , m_Treectrl -> GetItemText ( tree_selection ). length () + 1 ); // Remove "Partition x/"
2015-04-15 09:29:24 +02:00
partition -> FileSystem -> ExportFile ( WxStrToStr ( File ), WxStrToStr ( Path ));
2009-03-10 17:19:30 +00:00
}
else
2013-04-08 01:16:50 -04:00
{
2015-12-06 23:15:51 -05:00
m_filesystem -> ExportFile ( WxStrToStr ( File ), WxStrToStr ( Path ));
2013-04-08 01:16:50 -04:00
}
2008-12-08 05:30:24 +00:00
}
2015-04-15 09:29:24 +02:00
void CISOProperties :: ExportDir ( const std :: string & _rFullPath , const std :: string & _rExportFolder , const WiiPartition * partition )
2008-12-08 05:30:24 +00:00
{
2015-12-06 23:15:51 -05:00
DiscIO :: IFileSystem * const fs = m_open_iso -> GetVolumeType () == DiscIO :: IVolume :: WII_DISC ? partition -> FileSystem . get () : m_filesystem . get ();
2009-09-13 09:03:38 +00:00
2015-04-28 12:48:05 +02:00
const std :: vector < DiscIO :: SFileInfo >& fst = fs -> GetFileList ();
2014-06-29 14:22:06 -05:00
u32 index = 0 ;
u32 size = 0 ;
// Extract all
if ( _rFullPath . empty ())
2009-09-13 22:03:18 +00:00
{
2014-06-29 14:22:06 -05:00
index = 0 ;
size = ( u32 ) fst . size ();
fs -> ExportApploader ( _rExportFolder );
2015-12-06 23:15:51 -05:00
if ( m_open_iso -> GetVolumeType () != DiscIO :: IVolume :: WII_DISC )
2014-06-29 14:22:06 -05:00
fs -> ExportDOL ( _rExportFolder );
2009-09-13 22:03:18 +00:00
}
else
2013-04-08 01:16:50 -04:00
{
2014-06-29 14:22:06 -05:00
// Look for the dir we are going to extract
for ( index = 0 ; index != fst . size (); ++ index )
2009-09-13 22:03:18 +00:00
{
2015-04-28 12:48:05 +02:00
if ( fst [ index ]. m_FullPath == _rFullPath )
2009-09-13 22:03:18 +00:00
{
2014-06-29 14:22:06 -05:00
DEBUG_LOG ( DISCIO , "Found the directory at %u" , index );
2015-04-28 12:48:05 +02:00
size = ( u32 ) fst [ index ]. m_FileSize ;
2009-09-13 22:03:18 +00:00
break ;
}
}
2014-06-29 14:22:06 -05:00
DEBUG_LOG ( DISCIO , "Directory found from %u to %u \n extracting to: \n %s" , index , size , _rExportFolder . c_str ());
2009-09-13 22:03:18 +00:00
}
2014-06-29 14:22:06 -05:00
wxString dialogTitle = ( index != 0 ) ? _ ( "Extracting Directory" ) : _ ( "Extracting All Files" );
2012-03-24 20:59:20 -07:00
wxProgressDialog dialog (
dialogTitle ,
_ ( "Extracting..." ),
2014-06-29 14:22:06 -05:00
size - 1 ,
2012-03-24 20:59:20 -07:00
this ,
wxPD_APP_MODAL | wxPD_AUTO_HIDE | wxPD_CAN_ABORT |
wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME |
wxPD_SMOOTH
);
2009-09-13 22:03:18 +00:00
// Extraction
2014-06-29 14:22:06 -05:00
for ( u32 i = index ; i < size ; i ++ )
2009-09-13 22:03:18 +00:00
{
2014-05-17 13:17:28 -04:00
dialog . SetTitle ( wxString :: Format ( "%s : %d%%" , dialogTitle . c_str (),
2014-06-29 14:22:06 -05:00
( u32 )((( float )( i - index ) / ( float )( size - index )) * 100 )));
2013-10-29 01:23:17 -04:00
2015-04-28 12:48:05 +02:00
dialog . Update ( i , wxString :: Format ( _ ( "Extracting %s" ), StrToWxStr ( fst [ i ]. m_FullPath )));
2012-03-24 20:59:20 -07:00
if ( dialog . WasCancelled ())
2009-09-13 22:03:18 +00:00
break ;
2015-04-28 12:48:05 +02:00
if ( fst [ i ]. IsDirectory ())
2009-09-13 22:03:18 +00:00
{
2015-04-28 12:48:05 +02:00
const std :: string exportName = StringFromFormat ( "%s/%s/" , _rExportFolder . c_str (), fst [ i ]. m_FullPath . c_str ());
2014-03-14 23:38:14 -04:00
DEBUG_LOG ( DISCIO , "%s" , exportName . c_str ());
2009-09-13 22:03:18 +00:00
if ( ! File :: Exists ( exportName ) && ! File :: CreateFullPath ( exportName ))
{
2014-03-14 23:38:14 -04:00
ERROR_LOG ( DISCIO , "Could not create the path %s" , exportName . c_str ());
2009-09-13 22:03:18 +00:00
}
else
{
if ( ! File :: IsDirectory ( exportName ))
2014-03-14 23:38:14 -04:00
ERROR_LOG ( DISCIO , "%s already exists and is not a directory" , exportName . c_str ());
2009-09-13 22:03:18 +00:00
2014-03-14 23:38:14 -04:00
DEBUG_LOG ( DISCIO , "Folder %s already exists" , exportName . c_str ());
2009-09-13 22:03:18 +00:00
}
}
else
{
2015-04-28 12:48:05 +02:00
const std :: string exportName = StringFromFormat ( "%s/%s" , _rExportFolder . c_str (), fst [ i ]. m_FullPath . c_str ());
2014-03-14 23:38:14 -04:00
DEBUG_LOG ( DISCIO , "%s" , exportName . c_str ());
2009-09-13 22:03:18 +00:00
2015-04-28 12:48:05 +02:00
if ( ! File :: Exists ( exportName ) && ! fs -> ExportFile ( fst [ i ]. m_FullPath , exportName ))
2009-09-13 22:03:18 +00:00
{
2014-03-14 23:38:14 -04:00
ERROR_LOG ( DISCIO , "Could not export %s" , exportName . c_str ());
2009-09-13 22:03:18 +00:00
}
else
{
2014-03-14 23:38:14 -04:00
DEBUG_LOG ( DISCIO , "%s already exists" , exportName . c_str ());
2009-09-13 22:03:18 +00:00
}
}
}
}
void CISOProperties :: OnExtractDir ( wxCommandEvent & event )
{
wxString Directory = m_Treectrl -> GetItemText ( m_Treectrl -> GetSelection ());
2011-01-06 13:57:46 +00:00
wxString Path = wxDirSelector ( _ ( "Choose the folder to extract to" ));
2009-09-13 09:03:38 +00:00
if ( ! Path || ! Directory )
return ;
2009-09-13 22:03:18 +00:00
if ( event . GetId () == IDM_EXTRACTALL )
{
2015-12-06 23:15:51 -05:00
if ( m_open_iso -> GetVolumeType () == DiscIO :: IVolume :: WII_DISC )
2015-04-15 09:29:24 +02:00
{
wxTreeItemIdValue cookie ;
wxTreeItemId root = m_Treectrl -> GetRootItem ();
wxTreeItemId item = m_Treectrl -> GetFirstChild ( root , cookie );
while ( item . IsOk ())
{
ExportDir ( "" , WxStrToStr ( Path ), reinterpret_cast < WiiPartition *> ( m_Treectrl -> GetItemData ( item )));
item = m_Treectrl -> GetNextChild ( root , cookie );
}
}
2009-09-13 22:03:18 +00:00
else
2015-04-15 09:29:24 +02:00
{
2014-07-13 23:43:41 -04:00
ExportDir ( "" , WxStrToStr ( Path ));
2015-04-15 09:29:24 +02:00
}
2009-09-13 22:03:18 +00:00
return ;
}
2009-09-13 09:03:38 +00:00
while ( m_Treectrl -> GetItemParent ( m_Treectrl -> GetSelection ()) != m_Treectrl -> GetRootItem ())
{
2014-03-14 23:38:14 -04:00
wxString temp = m_Treectrl -> GetItemText ( m_Treectrl -> GetItemParent ( m_Treectrl -> GetSelection ()));
2014-05-17 13:17:28 -04:00
Directory = temp + DIR_SEP_CHR + Directory ;
2009-09-13 09:03:38 +00:00
m_Treectrl -> SelectItem ( m_Treectrl -> GetItemParent ( m_Treectrl -> GetSelection ()));
}
2014-06-29 14:22:06 -05:00
Directory += DIR_SEP_CHR ;
2015-12-06 23:15:51 -05:00
if ( m_open_iso -> GetVolumeType () == DiscIO :: IVolume :: WII_DISC )
2009-09-13 09:03:38 +00:00
{
2015-04-24 22:08:15 +02:00
const wxTreeItemId tree_selection = m_Treectrl -> GetSelection ();
WiiPartition * partition = reinterpret_cast < WiiPartition *> ( m_Treectrl -> GetItemData ( tree_selection ));
Directory . erase ( 0 , m_Treectrl -> GetItemText ( tree_selection ). length () + 1 ); // Remove "Partition x/"
2015-04-15 09:29:24 +02:00
ExportDir ( WxStrToStr ( Directory ), WxStrToStr ( Path ), partition );
2009-09-13 09:03:38 +00:00
}
else
2013-04-08 01:16:50 -04:00
{
2014-06-29 14:22:06 -05:00
ExportDir ( WxStrToStr ( Directory ), WxStrToStr ( Path ));
2013-04-08 01:16:50 -04:00
}
2009-09-12 09:09:47 +00:00
}
2009-12-29 13:59:38 +00:00
void CISOProperties :: OnExtractDataFromHeader ( wxCommandEvent & event )
{
2014-03-09 21:14:26 +01:00
DiscIO :: IFileSystem * FS = nullptr ;
2011-01-05 04:35:46 +00:00
wxString Path = wxDirSelector ( _ ( "Choose the folder to extract to" ));
2009-12-29 13:59:38 +00:00
if ( Path . empty ())
return ;
2015-12-06 23:15:51 -05:00
if ( m_open_iso -> GetVolumeType () == DiscIO :: IVolume :: WII_DISC )
2013-06-17 22:51:15 +12:00
{
2015-04-15 09:29:24 +02:00
WiiPartition * partition = reinterpret_cast < WiiPartition *> ( m_Treectrl -> GetItemData ( m_Treectrl -> GetSelection ()));
2015-08-15 18:04:30 -04:00
FS = partition -> FileSystem . get ();
2013-06-17 22:51:15 +12:00
}
2009-12-29 13:59:38 +00:00
else
2013-06-17 22:51:15 +12:00
{
2015-12-06 23:15:51 -05:00
FS = m_filesystem . get ();
2013-06-17 22:51:15 +12:00
}
2013-10-29 01:23:17 -04:00
2009-12-29 13:59:38 +00:00
bool ret = false ;
if ( event . GetId () == IDM_EXTRACTAPPLOADER )
{
2014-03-12 15:33:41 -04:00
ret = FS -> ExportApploader ( WxStrToStr ( Path ));
2009-12-29 13:59:38 +00:00
}
else if ( event . GetId () == IDM_EXTRACTDOL )
{
2014-03-12 15:33:41 -04:00
ret = FS -> ExportDOL ( WxStrToStr ( Path ));
2009-12-29 13:59:38 +00:00
}
if ( ! ret )
2014-07-24 21:46:46 -04:00
WxUtils :: ShowErrorDialog ( wxString :: Format ( _ ( "Failed to extract to %s!" ), WxStrToStr ( Path ). c_str ()));
2009-12-29 13:59:38 +00:00
}
2012-05-04 12:49:10 +02:00
class IntegrityCheckThread : public wxThread
{
public :
IntegrityCheckThread ( const WiiPartition & Partition )
: wxThread ( wxTHREAD_JOINABLE ), m_Partition ( Partition )
{
Create ();
}
2015-07-30 06:47:02 -04:00
ExitCode Entry () override
2012-05-04 12:49:10 +02:00
{
return ( ExitCode ) m_Partition . Partition -> CheckIntegrity ();
}
private :
const WiiPartition & m_Partition ;
};
void CISOProperties :: CheckPartitionIntegrity ( wxCommandEvent & event )
{
// Normally we can't enter this function if we aren't analyzing a Wii disc
// anyway, but let's still check to be sure.
2015-12-06 23:15:51 -05:00
if ( m_open_iso -> GetVolumeType () != DiscIO :: IVolume :: WII_DISC )
2012-05-04 12:49:10 +02:00
return ;
2014-07-13 15:04:25 -04:00
wxProgressDialog dialog ( _ ( "Checking integrity..." ), _ ( "Working..." ), 1000 , this ,
2012-05-04 12:49:10 +02:00
wxPD_APP_MODAL | wxPD_ELAPSED_TIME | wxPD_SMOOTH
);
2015-04-15 09:29:24 +02:00
WiiPartition * partition = reinterpret_cast < WiiPartition *> ( m_Treectrl -> GetItemData ( m_Treectrl -> GetSelection ()));
IntegrityCheckThread thread ( * partition );
2012-05-04 12:49:10 +02:00
thread . Run ();
while ( thread . IsAlive ())
{
2014-07-13 15:04:25 -04:00
dialog . Pulse ();
2012-05-04 12:49:10 +02:00
wxThread :: Sleep ( 50 );
}
2014-07-13 15:04:25 -04:00
dialog . Destroy ();
2012-05-04 12:49:10 +02:00
if ( ! thread . Wait ())
{
wxMessageBox (
2015-04-15 09:29:24 +02:00
wxString :: Format ( _ ( "Integrity check for %s failed. The disc image is most "
"likely corrupted or has been patched incorrectly." ),
m_Treectrl -> GetItemText ( m_Treectrl -> GetSelection ())),
2012-05-04 12:49:10 +02:00
_ ( "Integrity Check Error" ), wxOK | wxICON_ERROR , this
);
}
else
{
wxMessageBox ( _ ( "Integrity check completed. No errors have been found." ),
_ ( "Integrity check completed" ), wxOK | wxICON_INFORMATION , this );
}
}
2009-03-24 23:10:43 +00:00
void CISOProperties :: SetRefresh ( wxCommandEvent & event )
2008-12-08 05:30:24 +00:00
{
2009-03-24 23:10:43 +00:00
bRefreshList = true ;
if ( event . GetId () == ID_EMUSTATE )
2009-09-25 16:29:00 +00:00
EmuIssues -> Enable ( event . GetSelection () != 0 );
2008-12-08 05:30:24 +00:00
}
2013-09-07 23:02:49 +02:00
void CISOProperties :: SetCheckboxValueFromGameini ( const char * section , const char * key , wxCheckBox * checkbox )
{
// Prefer local gameini value over default gameini value.
bool value ;
2014-06-16 01:12:43 -04:00
if ( GameIniLocal . GetOrCreateSection ( section ) -> Get ( key , & value ))
2013-09-07 23:02:49 +02:00
checkbox -> Set3StateValue (( wxCheckBoxState ) value );
2014-06-16 01:12:43 -04:00
else if ( GameIniDefault . GetOrCreateSection ( section ) -> Get ( key , & value ))
2013-09-07 23:02:49 +02:00
checkbox -> Set3StateValue (( wxCheckBoxState ) value );
else
checkbox -> Set3StateValue ( wxCHK_UNDETERMINED );
}
2008-12-08 05:30:24 +00:00
void CISOProperties :: LoadGameConfig ()
{
2013-09-07 23:02:49 +02:00
SetCheckboxValueFromGameini ( "Core" , "CPUThread" , CPUThread );
SetCheckboxValueFromGameini ( "Core" , "SkipIdle" , SkipIdle );
SetCheckboxValueFromGameini ( "Core" , "MMU" , MMU );
SetCheckboxValueFromGameini ( "Core" , "DCBZ" , DCBZOFF );
2014-10-15 08:22:17 -07:00
SetCheckboxValueFromGameini ( "Core" , "FPRF" , FPRF );
2013-09-07 23:02:49 +02:00
SetCheckboxValueFromGameini ( "Core" , "SyncGPU" , SyncGPU );
SetCheckboxValueFromGameini ( "Core" , "FastDiscSpeed" , FastDiscSpeed );
SetCheckboxValueFromGameini ( "Core" , "DSPHLE" , DSPHLE );
SetCheckboxValueFromGameini ( "Wii" , "Widescreen" , EnableWideScreen );
2015-01-02 18:49:10 +01:00
SetCheckboxValueFromGameini ( "Video_Stereoscopy" , "StereoEFBMonoDepth" , MonoDepth );
2013-09-07 23:02:49 +02:00
2014-06-16 01:12:43 -04:00
IniFile :: Section * default_video = GameIniDefault . GetOrCreateSection ( "Video" );
2013-09-18 12:27:50 +02:00
int iTemp ;
2014-06-16 01:12:43 -04:00
default_video -> Get ( "ProjectionHack" , & iTemp );
2015-02-24 18:32:17 -05:00
default_video -> Get ( "PH_SZNear" , & m_PHack_Data . PHackSZNear );
2013-09-18 12:27:50 +02:00
if ( GameIniLocal . GetIfExists ( "Video" , "PH_SZNear" , & iTemp ))
2015-02-24 18:32:17 -05:00
m_PHack_Data . PHackSZNear = !! iTemp ;
default_video -> Get ( "PH_SZFar" , & m_PHack_Data . PHackSZFar );
2013-09-18 12:27:50 +02:00
if ( GameIniLocal . GetIfExists ( "Video" , "PH_SZFar" , & iTemp ))
2015-02-24 18:32:17 -05:00
m_PHack_Data . PHackSZFar = !! iTemp ;
2013-09-07 23:02:49 +02:00
2013-09-17 10:44:47 -04:00
std :: string sTemp ;
2015-02-24 18:32:17 -05:00
default_video -> Get ( "PH_ZNear" , & m_PHack_Data . PHZNear );
2013-09-18 12:27:50 +02:00
if ( GameIniLocal . GetIfExists ( "Video" , "PH_ZNear" , & sTemp ))
2015-02-24 18:32:17 -05:00
m_PHack_Data . PHZNear = sTemp ;
default_video -> Get ( "PH_ZFar" , & m_PHack_Data . PHZFar );
2013-09-18 12:27:50 +02:00
if ( GameIniLocal . GetIfExists ( "Video" , "PH_ZFar" , & sTemp ))
2015-02-24 18:32:17 -05:00
m_PHack_Data . PHZFar = sTemp ;
2013-09-07 23:02:49 +02:00
2014-06-16 01:12:43 -04:00
IniFile :: Section * default_emustate = GameIniDefault . GetOrCreateSection ( "EmuState" );
default_emustate -> Get ( "EmulationStateId" , & iTemp , 0 /*Not Set*/ );
2008-12-08 05:30:24 +00:00
EmuState -> SetSelection ( iTemp );
2013-09-18 12:27:50 +02:00
if ( GameIniLocal . GetIfExists ( "EmuState" , "EmulationStateId" , & iTemp ))
2013-09-07 23:02:49 +02:00
EmuState -> SetSelection ( iTemp );
2008-12-08 05:30:24 +00:00
2014-06-16 01:12:43 -04:00
default_emustate -> Get ( "EmulationIssues" , & sTemp );
2009-02-21 14:40:34 +00:00
if ( ! sTemp . empty ())
2013-02-28 02:39:06 -06:00
EmuIssues -> SetValue ( StrToWxStr ( sTemp ));
2013-09-18 12:27:50 +02:00
if ( GameIniLocal . GetIfExists ( "EmuState" , "EmulationIssues" , & sTemp ))
2013-09-07 23:02:49 +02:00
EmuIssues -> SetValue ( StrToWxStr ( sTemp ));
2009-09-25 16:29:00 +00:00
EmuIssues -> Enable ( EmuState -> GetSelection () != 0 );
2009-02-21 14:40:34 +00:00
2014-11-07 21:29:41 -05:00
sTemp = "" ;
if ( ! GameIniLocal . GetIfExists ( "Core" , "GPUDeterminismMode" , & sTemp ))
GameIniDefault . GetIfExists ( "Core" , "GPUDeterminismMode" , & sTemp );
if ( sTemp == "" )
GPUDeterminism -> SetSelection ( 0 );
else if ( sTemp == "auto" )
GPUDeterminism -> SetSelection ( 1 );
else if ( sTemp == "none" )
GPUDeterminism -> SetSelection ( 2 );
else if ( sTemp == "fake-completion" )
GPUDeterminism -> SetSelection ( 3 );
2015-01-02 18:49:10 +01:00
IniFile :: Section * default_stereoscopy = GameIniDefault . GetOrCreateSection ( "Video_Stereoscopy" );
default_stereoscopy -> Get ( "StereoDepthPercentage" , & iTemp , 100 );
GameIniLocal . GetIfExists ( "Video_Stereoscopy" , "StereoDepthPercentage" , & iTemp );
DepthPercentage -> SetValue ( iTemp );
2015-12-17 23:37:35 +01:00
default_stereoscopy -> Get ( "StereoConvergence" , & iTemp , 0 );
GameIniLocal . GetIfExists ( "Video_Stereoscopy" , "StereoConvergence" , & iTemp );
Convergence -> SetValue ( iTemp );
2015-01-02 18:49:10 +01:00
2008-12-08 05:30:24 +00:00
PatchList_Load ();
ActionReplayList_Load ();
2015-12-06 23:15:51 -05:00
m_geckocode_panel -> LoadCodes ( GameIniDefault , GameIniLocal , m_open_iso -> GetUniqueID ());
2013-09-07 23:02:49 +02:00
}
void CISOProperties :: SaveGameIniValueFrom3StateCheckbox ( const char * section , const char * key , wxCheckBox * checkbox )
{
// Delete any existing entries from the local gameini if checkbox is undetermined.
// Otherwise, write the current value to the local gameini if the value differs from the default gameini values.
// Delete any existing entry from the local gameini if the value does not differ from the default gameini value.
bool checkbox_val = ( checkbox -> Get3StateValue () == wxCHK_CHECKED );
if ( checkbox -> Get3StateValue () == wxCHK_UNDETERMINED )
GameIniLocal . DeleteKey ( section , key );
else if ( ! GameIniDefault . Exists ( section , key ))
2014-06-16 01:12:43 -04:00
GameIniLocal . GetOrCreateSection ( section ) -> Set ( key , checkbox_val );
2013-09-07 23:02:49 +02:00
else
{
bool default_value ;
2014-06-16 01:12:43 -04:00
GameIniDefault . GetOrCreateSection ( section ) -> Get ( key , & default_value );
2013-09-07 23:02:49 +02:00
if ( default_value != checkbox_val )
2014-06-16 01:12:43 -04:00
GameIniLocal . GetOrCreateSection ( section ) -> Set ( key , checkbox_val );
2013-09-07 23:02:49 +02:00
else
GameIniLocal . DeleteKey ( section , key );
}
2008-12-08 05:30:24 +00:00
}
bool CISOProperties :: SaveGameConfig ()
{
2013-09-07 23:02:49 +02:00
SaveGameIniValueFrom3StateCheckbox ( "Core" , "CPUThread" , CPUThread );
SaveGameIniValueFrom3StateCheckbox ( "Core" , "SkipIdle" , SkipIdle );
SaveGameIniValueFrom3StateCheckbox ( "Core" , "MMU" , MMU );
SaveGameIniValueFrom3StateCheckbox ( "Core" , "DCBZ" , DCBZOFF );
2014-10-15 08:22:17 -07:00
SaveGameIniValueFrom3StateCheckbox ( "Core" , "FPRF" , FPRF );
2013-09-07 23:02:49 +02:00
SaveGameIniValueFrom3StateCheckbox ( "Core" , "SyncGPU" , SyncGPU );
SaveGameIniValueFrom3StateCheckbox ( "Core" , "FastDiscSpeed" , FastDiscSpeed );
SaveGameIniValueFrom3StateCheckbox ( "Core" , "DSPHLE" , DSPHLE );
SaveGameIniValueFrom3StateCheckbox ( "Wii" , "Widescreen" , EnableWideScreen );
2015-01-02 18:49:10 +01:00
SaveGameIniValueFrom3StateCheckbox ( "Video_Stereoscopy" , "StereoEFBMonoDepth" , MonoDepth );
2008-12-08 05:30:24 +00:00
2013-09-07 23:02:49 +02:00
#define SAVE_IF_NOT_DEFAULT(section, key, val, def) do { \
if (GameIniDefault.Exists((section), (key))) { \
std::remove_reference<decltype((val))>::type tmp__; \
2014-06-16 01:12:43 -04:00
GameIniDefault.GetOrCreateSection((section))->Get((key), &tmp__); \
2013-09-07 23:02:49 +02:00
if ((val) != tmp__) \
2014-06-16 01:12:43 -04:00
GameIniLocal.GetOrCreateSection((section))->Set((key), (val)); \
2013-09-07 23:02:49 +02:00
else \
GameIniLocal.DeleteKey((section), (key)); \
} else if ((val) != (def)) \
2014-06-16 01:12:43 -04:00
GameIniLocal.GetOrCreateSection((section))->Set((key), (val)); \
2013-09-07 23:02:49 +02:00
else \
GameIniLocal.DeleteKey((section), (key)); \
} while (0)
2008-12-08 05:30:24 +00:00
2015-02-24 18:32:17 -05:00
SAVE_IF_NOT_DEFAULT ( "Video" , "PH_SZNear" , ( m_PHack_Data . PHackSZNear ? 1 : 0 ), 0 );
SAVE_IF_NOT_DEFAULT ( "Video" , "PH_SZFar" , ( m_PHack_Data . PHackSZFar ? 1 : 0 ), 0 );
SAVE_IF_NOT_DEFAULT ( "Video" , "PH_ZNear" , m_PHack_Data . PHZNear , "" );
SAVE_IF_NOT_DEFAULT ( "Video" , "PH_ZFar" , m_PHack_Data . PHZFar , "" );
2013-09-07 23:02:49 +02:00
SAVE_IF_NOT_DEFAULT ( "EmuState" , "EmulationStateId" , EmuState -> GetSelection (), 0 );
2010-07-29 12:17:47 +00:00
2013-09-07 23:02:49 +02:00
std :: string emu_issues = EmuIssues -> GetValue (). ToStdString ();
SAVE_IF_NOT_DEFAULT ( "EmuState" , "EmulationIssues" , emu_issues , "" );
2008-12-08 05:30:24 +00:00
2014-11-07 21:29:41 -05:00
std :: string tmp ;
if ( GPUDeterminism -> GetSelection () == 0 )
tmp = "Not Set" ;
else if ( GPUDeterminism -> GetSelection () == 1 )
tmp = "auto" ;
else if ( GPUDeterminism -> GetSelection () == 2 )
tmp = "none" ;
else if ( GPUDeterminism -> GetSelection () == 3 )
tmp = "fake-completion" ;
SAVE_IF_NOT_DEFAULT ( "Core" , "GPUDeterminismMode" , tmp , "Not Set" );
2015-01-02 18:49:10 +01:00
int depth = DepthPercentage -> GetValue () > 0 ? DepthPercentage -> GetValue () : 100 ;
SAVE_IF_NOT_DEFAULT ( "Video_Stereoscopy" , "StereoDepthPercentage" , depth , 100 );
2015-12-17 23:37:35 +01:00
SAVE_IF_NOT_DEFAULT ( "Video_Stereoscopy" , "StereoConvergence" , Convergence -> GetValue (), 0 );
2015-01-02 18:49:10 +01:00
2008-12-08 05:30:24 +00:00
PatchList_Save ();
ActionReplayList_Save ();
2013-09-07 23:02:49 +02:00
Gecko :: SaveCodes ( GameIniLocal , m_geckocode_panel -> GetCodes ());
2008-12-08 05:30:24 +00:00
2014-03-12 15:33:41 -04:00
bool success = GameIniLocal . Save ( GameIniFileLocal );
2013-09-07 23:02:49 +02:00
// If the resulting file is empty, delete it. Kind of a hack, but meh.
2013-09-14 22:58:32 -04:00
if ( success && File :: GetSize ( GameIniFileLocal ) == 0 )
File :: Delete ( GameIniFileLocal );
2013-09-07 23:02:49 +02:00
return success ;
}
2015-04-25 22:15:48 +02:00
void CISOProperties :: LaunchExternalEditor ( const std :: string & filename , bool wait_until_closed )
2013-09-07 23:02:49 +02:00
{
#ifdef __APPLE__
// wxTheMimeTypesManager is not yet implemented for wxCocoa
[[ NSWorkspace sharedWorkspace ] openFile :
[ NSString stringWithUTF8String : filename . c_str ()]
withApplication : @ "TextEdit" ];
#else
2014-05-17 13:17:28 -04:00
wxFileType * filetype = wxTheMimeTypesManager -> GetFileTypeFromExtension ( "ini" );
2014-03-11 00:30:55 +13:00
if ( filetype == nullptr ) // From extension failed, trying with MIME type now
2013-09-07 23:02:49 +02:00
{
2014-05-17 13:17:28 -04:00
filetype = wxTheMimeTypesManager -> GetFileTypeFromMimeType ( "text/plain" );
2014-03-11 00:30:55 +13:00
if ( filetype == nullptr ) // MIME type failed, aborting mission
2013-09-07 23:02:49 +02:00
{
2014-07-24 21:46:46 -04:00
WxUtils :: ShowErrorDialog ( _ ( "Filetype 'ini' is unknown! Will not open!" ));
2013-09-07 23:02:49 +02:00
return ;
}
}
2014-07-24 21:46:46 -04:00
wxString OpenCommand = filetype -> GetOpenCommand ( StrToWxStr ( filename ));
2014-03-11 00:30:55 +13:00
if ( OpenCommand . IsEmpty ())
2014-07-24 21:46:46 -04:00
{
WxUtils :: ShowErrorDialog ( _ ( "Couldn't find open command for extension 'ini'!" ));
2015-04-25 22:15:48 +02:00
return ;
2014-07-24 21:46:46 -04:00
}
2015-04-25 22:15:48 +02:00
long result ;
if ( wait_until_closed )
result = wxExecute ( OpenCommand , wxEXEC_SYNC );
2013-09-07 23:02:49 +02:00
else
2015-04-25 22:15:48 +02:00
result = wxExecute ( OpenCommand );
if ( result == - 1 )
2014-07-24 21:46:46 -04:00
{
2015-04-25 22:15:48 +02:00
WxUtils :: ShowErrorDialog ( _ ( "wxExecute returned -1 on application run!" ));
return ;
2014-07-24 21:46:46 -04:00
}
2015-04-25 22:15:48 +02:00
if ( wait_until_closed )
bRefreshList = true ; // Just in case
2013-09-07 23:02:49 +02:00
#endif
2008-12-08 05:30:24 +00:00
}
void CISOProperties :: OnEditConfig ( wxCommandEvent & WXUNUSED ( event ))
{
2013-09-07 23:02:49 +02:00
SaveGameConfig ();
2013-09-14 20:27:54 -04:00
// Create blank file to prevent editor from prompting to create it.
if ( ! File :: Exists ( GameIniFileLocal ))
{
2013-09-14 22:58:32 -04:00
std :: fstream blankFile ( GameIniFileLocal , std :: ios :: out );
2013-09-14 20:27:54 -04:00
blankFile . close ();
}
2015-04-25 22:15:48 +02:00
LaunchExternalEditor ( GameIniFileLocal , true );
2013-09-07 23:02:49 +02:00
GameIniLocal . Load ( GameIniFileLocal );
LoadGameConfig ();
}
2008-12-08 05:30:24 +00:00
2014-04-12 05:50:12 -05:00
void CISOProperties :: OnComputeMD5Sum ( wxCommandEvent & WXUNUSED ( event ))
{
u8 output [ 16 ];
std :: string output_string ;
std :: vector < u8 > data ( 8 * 1024 * 1024 );
2014-04-14 20:35:40 -05:00
u64 read_offset = 0 ;
2015-09-24 00:39:34 +02:00
mbedtls_md5_context ctx ;
2014-04-12 05:50:12 -05:00
2015-09-16 21:06:54 +02:00
std :: unique_ptr < DiscIO :: IBlobReader > file ( DiscIO :: CreateBlobReader ( OpenGameListItem . GetFileName ()));
u64 game_size = file -> GetDataSize ();
2014-04-12 05:50:12 -05:00
wxProgressDialog progressDialog (
_ ( "Computing MD5 checksum" ),
_ ( "Working..." ),
2014-04-14 20:35:40 -05:00
1000 ,
2014-04-12 05:50:12 -05:00
this ,
wxPD_APP_MODAL | wxPD_CAN_ABORT |
wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME |
wxPD_SMOOTH
);
2015-09-24 00:39:34 +02:00
mbedtls_md5_starts ( & ctx );
2014-04-12 05:50:12 -05:00
while ( read_offset < game_size )
{
2015-09-16 21:06:54 +02:00
if ( ! progressDialog . Update (( int )(( double ) read_offset / ( double ) game_size * 1000 )))
2014-04-12 05:50:12 -05:00
return ;
2015-09-16 21:06:54 +02:00
size_t read_size = std :: min (( u64 ) data . size (), game_size - read_offset );
if ( ! file -> Read ( read_offset , read_size , data . data ()))
return ;
2014-04-12 05:50:12 -05:00
2015-09-16 21:06:54 +02:00
mbedtls_md5_update ( & ctx , data . data (), read_size );
2014-04-12 05:50:12 -05:00
read_offset += read_size ;
}
2015-09-24 00:39:34 +02:00
mbedtls_md5_finish ( & ctx , output );
2014-04-12 05:50:12 -05:00
// Convert to hex
for ( int a = 0 ; a < 16 ; ++ a )
output_string += StringFromFormat ( "%02x" , output [ a ]);
m_MD5Sum -> SetValue ( output_string );
}
2015-02-24 20:04:19 +01:00
// Opens all pre-defined INIs for the game. If there are multiple ones,
// they will all be opened, but there is usually only one
2013-09-07 23:02:49 +02:00
void CISOProperties :: OnShowDefaultConfig ( wxCommandEvent & WXUNUSED ( event ))
{
2015-12-06 23:15:51 -05:00
for ( const std :: string & filename : SConfig :: GetGameIniFilenames ( game_id , m_open_iso -> GetRevision ()))
2015-02-24 20:04:19 +01:00
{
std :: string path = File :: GetSysDirectory () + GAMESETTINGS_DIR DIR_SEP + filename ;
if ( File :: Exists ( path ))
2015-04-25 22:15:48 +02:00
LaunchExternalEditor ( path , false );
2015-02-24 20:04:19 +01:00
}
2008-12-08 05:30:24 +00:00
}
void CISOProperties :: ListSelectionChanged ( wxCommandEvent & event )
{
switch ( event . GetId ())
{
case ID_PATCHES_LIST :
2014-03-11 00:30:55 +13:00
if ( Patches -> GetSelection () == wxNOT_FOUND ||
DefaultPatches . find ( Patches -> GetString ( Patches -> GetSelection ()). ToStdString ()) != DefaultPatches . end ())
2013-09-07 23:02:49 +02:00
{
EditPatch -> Disable ();
RemovePatch -> Disable ();
}
else
2008-12-08 05:30:24 +00:00
{
EditPatch -> Enable ();
RemovePatch -> Enable ();
}
break ;
case ID_CHEATS_LIST :
2014-03-11 00:30:55 +13:00
if ( Cheats -> GetSelection () == wxNOT_FOUND ||
DefaultCheats . find ( Cheats -> GetString ( Cheats -> GetSelection ()). ToStdString ()) != DefaultCheats . end ())
2013-09-07 23:02:49 +02:00
{
EditCheat -> Disable ();
RemoveCheat -> Disable ();
}
else
2008-12-08 05:30:24 +00:00
{
EditCheat -> Enable ();
RemoveCheat -> Enable ();
}
break ;
}
}
void CISOProperties :: PatchList_Load ()
{
onFrame . clear ();
Patches -> Clear ();
2013-09-07 23:02:49 +02:00
PatchEngine :: LoadPatchSection ( "OnFrame" , onFrame , GameIniDefault , GameIniLocal );
2008-12-08 05:30:24 +00:00
u32 index = 0 ;
2013-10-29 01:09:01 -04:00
for ( PatchEngine :: Patch & p : onFrame )
2008-12-08 05:30:24 +00:00
{
2013-02-28 02:39:06 -06:00
Patches -> Append ( StrToWxStr ( p . name ));
2008-12-08 05:30:24 +00:00
Patches -> Check ( index , p . active );
2013-09-07 23:02:49 +02:00
if ( ! p . user_defined )
DefaultPatches . insert ( p . name );
2008-12-08 05:30:24 +00:00
++ index ;
}
}
void CISOProperties :: PatchList_Save ()
{
std :: vector < std :: string > lines ;
2013-09-07 23:02:49 +02:00
std :: vector < std :: string > enabledLines ;
2009-01-03 23:02:13 +00:00
u32 index = 0 ;
2013-10-29 01:09:01 -04:00
for ( PatchEngine :: Patch & p : onFrame )
2008-12-08 05:30:24 +00:00
{
2013-09-07 23:02:49 +02:00
if ( Patches -> IsChecked ( index ))
2013-10-29 01:09:01 -04:00
enabledLines . push_back ( "$" + p . name );
2008-12-08 05:30:24 +00:00
2013-09-07 23:02:49 +02:00
// Do not save default patches.
2013-10-29 01:09:01 -04:00
if ( DefaultPatches . find ( p . name ) == DefaultPatches . end ())
2008-12-08 05:30:24 +00:00
{
2013-10-29 01:09:01 -04:00
lines . push_back ( "$" + p . name );
2014-02-12 16:00:34 +01:00
for ( const PatchEngine :: PatchEntry & entry : p . entries )
2013-09-07 23:02:49 +02:00
{
2014-02-12 16:00:34 +01:00
std :: string temp = StringFromFormat ( "0x%08X:%s:0x%08X" , entry . address , PatchEngine :: PatchTypeStrings [ entry . type ], entry . value );
2013-09-07 23:02:49 +02:00
lines . push_back ( temp );
}
2008-12-08 05:30:24 +00:00
}
2009-01-03 23:02:13 +00:00
++ index ;
2008-12-08 05:30:24 +00:00
}
2013-09-07 23:02:49 +02:00
GameIniLocal . SetLines ( "OnFrame_Enabled" , enabledLines );
GameIniLocal . SetLines ( "OnFrame" , lines );
2008-12-08 05:30:24 +00:00
}
void CISOProperties :: PatchButtonClicked ( wxCommandEvent & event )
{
int selection = Patches -> GetSelection ();
2013-10-29 01:23:17 -04:00
2008-12-08 05:30:24 +00:00
switch ( event . GetId ())
{
case ID_EDITPATCH :
{
2015-03-06 12:26:40 +01:00
CPatchAddEdit dlg ( selection , & onFrame , this );
2008-12-08 05:30:24 +00:00
dlg . ShowModal ();
2015-06-02 19:53:51 -04:00
Raise ();
2008-12-08 05:30:24 +00:00
}
break ;
case ID_ADDPATCH :
{
2015-03-06 12:26:40 +01:00
CPatchAddEdit dlg ( - 1 , & onFrame , this , 1 , _ ( "Add Patch" ));
2015-06-02 19:53:51 -04:00
int res = dlg . ShowModal ();
Raise ();
if ( res == wxID_OK )
2009-01-03 23:02:13 +00:00
{
2013-02-27 22:37:38 -06:00
Patches -> Append ( StrToWxStr ( onFrame . back (). name ));
2009-01-24 00:45:46 +00:00
Patches -> Check (( unsigned int )( onFrame . size () - 1 ), onFrame . back (). active );
2009-01-03 23:02:13 +00:00
}
2008-12-08 05:30:24 +00:00
}
break ;
case ID_REMOVEPATCH :
onFrame . erase ( onFrame . begin () + Patches -> GetSelection ());
2014-11-22 17:25:14 -05:00
Patches -> Delete ( Patches -> GetSelection ());
2008-12-08 05:30:24 +00:00
break ;
}
PatchList_Save ();
Patches -> Clear ();
PatchList_Load ();
2015-02-14 16:00:15 -05:00
EditPatch -> Disable ();
RemovePatch -> Disable ();
2008-12-08 05:30:24 +00:00
}
void CISOProperties :: ActionReplayList_Load ()
{
2008-12-17 04:14:24 +00:00
arCodes . clear ();
2008-12-08 05:30:24 +00:00
Cheats -> Clear ();
2013-09-07 23:02:49 +02:00
ActionReplay :: LoadCodes ( arCodes , GameIniDefault , GameIniLocal );
2008-12-08 05:30:24 +00:00
2008-12-17 04:14:24 +00:00
u32 index = 0 ;
2014-02-12 16:00:34 +01:00
for ( const ActionReplay :: ARCode & arCode : arCodes )
2008-12-08 05:30:24 +00:00
{
2013-02-27 22:37:38 -06:00
Cheats -> Append ( StrToWxStr ( arCode . name ));
2008-12-17 04:14:24 +00:00
Cheats -> Check ( index , arCode . active );
2013-09-07 23:02:49 +02:00
if ( ! arCode . user_defined )
DefaultCheats . insert ( arCode . name );
2008-12-17 04:14:24 +00:00
++ index ;
2008-12-08 05:30:24 +00:00
}
}
void CISOProperties :: ActionReplayList_Save ()
{
std :: vector < std :: string > lines ;
2013-09-07 23:02:49 +02:00
std :: vector < std :: string > enabledLines ;
2008-12-17 04:14:24 +00:00
u32 index = 0 ;
2014-08-05 20:07:23 -07:00
u32 cheats_chkbox_count = Cheats -> GetCount ();
2014-02-12 16:00:34 +01:00
for ( const ActionReplay :: ARCode & code : arCodes )
2008-12-08 05:30:24 +00:00
{
2014-08-05 20:45:18 -07:00
// Check the index against the count because of the hacky way codes are added from the "Cheat Search" dialog
2014-08-05 20:07:23 -07:00
if (( index < cheats_chkbox_count ) && Cheats -> IsChecked ( index ))
2013-09-07 23:02:49 +02:00
enabledLines . push_back ( "$" + code . name );
2008-12-08 05:30:24 +00:00
2013-09-07 23:02:49 +02:00
// Do not save default cheats.
if ( DefaultCheats . find ( code . name ) == DefaultCheats . end ())
2008-12-08 05:30:24 +00:00
{
2013-09-07 23:02:49 +02:00
lines . push_back ( "$" + code . name );
2014-02-12 16:00:34 +01:00
for ( const ActionReplay :: AREntry & op : code . ops )
2013-09-07 23:02:49 +02:00
{
2014-05-17 13:17:28 -04:00
lines . push_back ( WxStrToStr ( wxString :: Format ( "%08X %08X" , op . cmd_addr , op . value )));
2013-09-07 23:02:49 +02:00
}
2008-12-08 05:30:24 +00:00
}
2008-12-17 04:14:24 +00:00
++ index ;
2008-12-08 05:30:24 +00:00
}
2013-09-07 23:02:49 +02:00
GameIniLocal . SetLines ( "ActionReplay_Enabled" , enabledLines );
GameIniLocal . SetLines ( "ActionReplay" , lines );
2008-12-08 05:30:24 +00:00
}
void CISOProperties :: ActionReplayButtonClicked ( wxCommandEvent & event )
{
2008-12-17 04:14:24 +00:00
int selection = Cheats -> GetSelection ();
2013-10-29 01:23:17 -04:00
2008-12-08 05:30:24 +00:00
switch ( event . GetId ())
{
case ID_EDITCHEAT :
2008-12-17 04:14:24 +00:00
{
2015-03-06 12:26:40 +01:00
CARCodeAddEdit dlg ( selection , & arCodes , this );
2008-12-17 04:14:24 +00:00
dlg . ShowModal ();
2015-06-02 19:53:51 -04:00
Raise ();
2008-12-17 04:14:24 +00:00
}
2008-12-08 05:30:24 +00:00
break ;
case ID_ADDCHEAT :
2008-12-17 04:14:24 +00:00
{
2015-03-06 12:26:40 +01:00
CARCodeAddEdit dlg ( - 1 , & arCodes , this , 1 , _ ( "Add ActionReplay Code" ));
2015-06-02 19:53:51 -04:00
int res = dlg . ShowModal ();
Raise ();
if ( res == wxID_OK )
2009-02-20 00:07:35 +00:00
{
2013-03-02 20:34:53 -06:00
Cheats -> Append ( StrToWxStr ( arCodes . back (). name ));
2009-02-20 00:07:35 +00:00
Cheats -> Check (( unsigned int )( arCodes . size () - 1 ), arCodes . back (). active );
}
2008-12-17 04:14:24 +00:00
}
2008-12-08 05:30:24 +00:00
break ;
case ID_REMOVECHEAT :
2008-12-17 04:14:24 +00:00
arCodes . erase ( arCodes . begin () + Cheats -> GetSelection ());
2009-11-08 23:12:35 +00:00
Cheats -> Delete ( Cheats -> GetSelection ());
2008-12-08 05:30:24 +00:00
break ;
}
ActionReplayList_Save ();
Cheats -> Clear ();
ActionReplayList_Load ();
2015-02-14 16:00:15 -05:00
EditCheat -> Disable ();
RemoveCheat -> Disable ();
2008-12-08 05:30:24 +00:00
}
2009-02-14 17:32:03 +00:00
2015-09-19 17:20:16 +02:00
void CISOProperties :: AddARCode ( const ActionReplay :: ARCode & code )
{
arCodes . emplace_back ( code );
}
2009-02-14 17:32:03 +00:00
void CISOProperties :: OnChangeBannerLang ( wxCommandEvent & event )
{
2015-09-13 14:17:58 +02:00
ChangeBannerDetails ( OpenGameListItem . GetLanguages ()[ event . GetSelection ()]);
2009-02-14 17:32:03 +00:00
}
2015-05-08 17:28:03 -04:00
void CISOProperties :: ChangeBannerDetails ( DiscIO :: IVolume :: ELanguage language )
2009-02-14 17:32:03 +00:00
{
2015-09-13 14:17:58 +02:00
wxString const name = StrToWxStr ( OpenGameListItem . GetName ( language ));
wxString const comment = StrToWxStr ( OpenGameListItem . GetDescription ( language ));
wxString const maker = StrToWxStr ( OpenGameListItem . GetCompany ());
2013-03-02 19:46:55 -06:00
2013-04-19 09:21:45 -04:00
// Updates the information shown in the window
2015-05-11 11:19:30 +02:00
m_Name -> SetValue ( name );
2011-12-18 22:01:46 -08:00
m_Comment -> SetValue ( comment );
m_Maker -> SetValue ( maker ); //dev too
std :: string filename , extension ;
2015-09-13 14:17:58 +02:00
SplitPath ( OpenGameListItem . GetFileName (), nullptr , & filename , & extension );
2011-12-18 22:01:46 -08:00
// Also sets the window's title
2013-02-27 22:37:38 -06:00
SetTitle ( StrToWxStr ( StringFromFormat ( "%s%s: %s - " , filename . c_str (),
2015-09-13 14:17:58 +02:00
extension . c_str (), OpenGameListItem . GetUniqueID (). c_str ())) + name );
2009-02-14 17:32:03 +00:00
}