From 9bcff9f3d575c5d6a963aa2103d4c7239845695f Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Thu, 2 Dec 2010 08:15:11 +0000 Subject: [PATCH] Internationalization fix-ups. PCSX2 0.9.7 should *finally* be ready for translations. Whew. * Also did some work on re-introducing the game database dialog. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@4063 96395faa-99c1-11dd-bbfe-3dabce05a288 --- common/include/Utilities/Dependencies.h | 37 +-- common/src/Utilities/Exceptions.cpp | 2 +- common/src/Utilities/pxTranslate.cpp | 21 +- pcsx2/CDVD/CDVD.cpp | 2 +- pcsx2/System.cpp | 13 +- pcsx2/gui/AdvancedDialog.cpp | 16 - pcsx2/gui/AdvancedDialog.h | 21 -- pcsx2/gui/App.h | 4 + pcsx2/gui/AppConfig.cpp | 23 +- pcsx2/gui/AppConfig.h | 4 +- pcsx2/gui/AppInit.cpp | 6 +- pcsx2/gui/AppMain.cpp | 64 +++- pcsx2/gui/Dialogs/CreateMemoryCardDialog.cpp | 2 +- pcsx2/gui/Dialogs/FirstTimeWizard.cpp | 8 +- pcsx2/gui/Dialogs/GameDatabaseDialog.cpp | 7 +- pcsx2/gui/Dialogs/ImportSettingsDialog.cpp | 6 +- pcsx2/gui/Dialogs/McdConfigDialog.cpp | 4 +- pcsx2/gui/Dialogs/StuckThreadDialog.cpp | 2 +- pcsx2/gui/Dialogs/SysConfigDialog.cpp | 5 +- pcsx2/gui/ExecutorThread.cpp | 6 +- pcsx2/gui/FrameForGS.cpp | 6 +- pcsx2/gui/IsoDropTarget.cpp | 2 +- pcsx2/gui/MainFrame.cpp | 6 +- pcsx2/gui/MainMenuClicks.cpp | 4 +- pcsx2/gui/MemoryCardFile.cpp | 2 +- pcsx2/gui/Panels/BiosSelectorPanel.cpp | 2 +- pcsx2/gui/Panels/DirPickerPanel.cpp | 4 +- pcsx2/gui/Panels/GSWindowPanel.cpp | 10 +- pcsx2/gui/Panels/GameDatabasePanel.cpp | 300 ++++++++++++++++++- pcsx2/gui/Panels/GameFixesPanel.cpp | 6 +- pcsx2/gui/Panels/MemoryCardListPanel.cpp | 6 +- pcsx2/gui/Panels/MemoryCardPanels.h | 14 +- pcsx2/gui/Panels/MiscPanelStuff.cpp | 24 +- pcsx2/gui/Panels/PathsPanel.cpp | 8 +- pcsx2/gui/Panels/PluginSelectorPanel.cpp | 4 +- pcsx2/gui/Panels/SpeedhacksPanel.cpp | 32 +- pcsx2/gui/Panels/VideoPanel.cpp | 16 +- pcsx2/gui/i18n.cpp | 95 ++++-- pcsx2/gui/i18n.h | 6 +- pcsx2/vtlb.cpp | 2 +- pcsx2/windows/VCprojects/pcsx2_2008.vcproj | 8 - pcsx2/x86/sVU_zerorec.cpp | 2 +- 42 files changed, 583 insertions(+), 229 deletions(-) delete mode 100644 pcsx2/gui/AdvancedDialog.cpp delete mode 100644 pcsx2/gui/AdvancedDialog.h diff --git a/common/include/Utilities/Dependencies.h b/common/include/Utilities/Dependencies.h index f36cac9d1d..3e7593b869 100644 --- a/common/include/Utilities/Dependencies.h +++ b/common/include/Utilities/Dependencies.h @@ -191,7 +191,6 @@ static const s64 _256mb = _1mb * 256; static const s64 _1gb = _256mb * 4; static const s64 _4gb = _1gb * 4; - // =========================================================================================== // i18n/Translation Feature Set! // =========================================================================================== @@ -215,7 +214,7 @@ extern wxString fromAscii( const char* src ); #endif // -------------------------------------------------------------------------------------- -// pxE(x) [macro] +// pxE(key, msg) and pxEt(key, msg) [macros] // -------------------------------------------------------------------------------------- // Translation Feature: pxE is used as a method of dereferencing very long english text // descriptions via a "key" identifier. In this way, the english text can be revised without @@ -225,28 +224,30 @@ extern wxString fromAscii( const char* src ); // // Valid prefix types: // -// .Panel: Key-based translation of a panel or dialog text; usually either a header or -// checkbox description, by may also include some controls with long labels. -// These have the highest translation priority. +// !Panel: Key-based translation of a panel or dialog text; usually either a header or +// checkbox description, by may also include some controls with long labels. +// These have the highest translation priority. // -// .Popup: Key-based translation of a popup dialog box; either a notice, confirmation, -// or error. These typically have very high translation priority (roughly equal -// or slightly less than pxE_Panel). +// !Notice: Key-based translation of a popup dialog box; either a notice, confirmation, +// or error. These typically have very high translation priority (roughly equal +// or slightly less than pxE_Panel). // -// .Error Key-based translation of error messages, typically used when throwing exceptions -// that have end-user errors. These are normally (but not always) displayed as popups -// to the user. Translation priority is medium. +// !Tooltip: Key-based translation of a tooltip for a button on a tool bar. Since buttons are +// rarely self-explanatory, these translations are considered medium to high priority. // -// .Wizard Key-based translation of a heading, checkbox item, description, or other text -// associated with the First-time wizard. Translation of these items is considered -// lower-priority to most other messages; but equal or higher priority to tooltips. +// !Wizard Key-based translation of a heading, checkbox item, description, or other text +// associated with the First-time wizard. Translation of these items is considered +// lower-priority to most other messages; but equal or higher priority to ContextTips. // -// .Tooltip: Key-based translation of a tooltip for a control on a dialog/panel. Translation -// of these items is typically considered "lowest priority" as they usually provide -// the most tertiary of info to the user. +// !ContextTip: Key-based translation of a tooltip for a control on a dialog/panel. Translation +// of these items is typically considered "lowest priority" as they usually provide +// only tertiary (extra) info to the user. // -#define pxE(key, english) pxExpandMsg( wxT(key), english ) +#define pxE(key, english) pxExpandMsg( wxT(key), english ) + +// For use with tertiary translations (low priority). +#define pxEt(key, english) pxExpandMsg( wxT(key), english ) #include "Utilities/Assertions.h" #include "Utilities/Exceptions.h" diff --git a/common/src/Utilities/Exceptions.cpp b/common/src/Utilities/Exceptions.cpp index 64037aa4d1..9515618a7a 100644 --- a/common/src/Utilities/Exceptions.cpp +++ b/common/src/Utilities/Exceptions.cpp @@ -251,7 +251,7 @@ wxString Exception::VirtualMemoryMapConflict::FormatDisplayMessage() const { FastFormatUnicode retmsg; retmsg.Write( L"%s", - pxE( ".Error:VirtualMemoryMap", + pxE( "!Notice:VirtualMemoryMap", L"There is not enough virtual memory available, or necessary virtual memory " L"mappings have already been reserved by other processes, services, or DLLs." ) diff --git a/common/src/Utilities/pxTranslate.cpp b/common/src/Utilities/pxTranslate.cpp index 80e53950af..17e192b13e 100644 --- a/common/src/Utilities/pxTranslate.cpp +++ b/common/src/Utilities/pxTranslate.cpp @@ -32,20 +32,25 @@ bool pxIsEnglish( int id ) // (without this second pass many tooltips would just show up as "Savestate Tooltip" instead // of something meaningful). // -// Rationale: Traditional gnu-style gnu_gettext stuff tends to stop translating strings when +// Rationale: Traditional gnu-style gettext stuff tends to stop translating strings when // the slightest change to a string is made (including punctuation and possibly even case). // On long strings especially, this can be unwanted since future revisions of the app may have -// simple tyop fixes that *should not* break existing translations. Furthermore +// simple typo or newline fixes that *should not* break existing translations. Furthermore, +// icons can be used in places where otherwise identical english verbage for two separate +// terms can be differentiated. GNU gettext has some new tools for using fuzzy logic heuristics +// matching, but it is also imperfect and complicated, so we have opted to continue using this +// system instead. +// const wxChar* __fastcall pxExpandMsg( const wxChar* key, const wxChar* englishContent ) { #ifdef PCSX2_DEVBUILD static const wxChar* tbl_pxE_Prefixes[] = { - L".Panel:", - L".Popup:", - L".Error:", - L".Wizard:", - L".Tooltip:", + L"!Panel:", + L"!Notice:", + L"!Wizard:", + L"!Tooltip:", + L"!ContextTip:", NULL }; @@ -57,7 +62,7 @@ const wxChar* __fastcall pxExpandMsg( const wxChar* key, const wxChar* englishCo ++prefix; } pxAssertDev( *prefix != NULL, - wxsFormat( L"Invalid pxE key prefix in key '%s'. Prefix must be one of the valid prefixes listed in pxExpandMsg.", key ) + pxsFmt( L"Invalid pxE key prefix in key '%s'. Prefix must be one of the valid prefixes listed in pxExpandMsg.", key ) ); #endif diff --git a/pcsx2/CDVD/CDVD.cpp b/pcsx2/CDVD/CDVD.cpp index 36ab6672c8..cd13aed5bc 100644 --- a/pcsx2/CDVD/CDVD.cpp +++ b/pcsx2/CDVD/CDVD.cpp @@ -382,7 +382,7 @@ void cdvdReloadElfInfo(wxString elfoverride) if (!ENABLE_LOADING_PS1_GAMES) Cpu->ThrowException( Exception::RuntimeError() .SetDiagMsg(L"PSX game discs are not supported by PCSX2.") - .SetUserMsg(pxE( "Error:PsxDisc", + .SetUserMsg(pxE( "!Notice:PsxDisc", L"Playstation game discs are not supported by PCSX2. If you want to emulate PSX games " L"then you'll have to download a PSX-specific emulator, such as ePSXe or PCSX.") ) diff --git a/pcsx2/System.cpp b/pcsx2/System.cpp index 17f7341277..22479871e0 100644 --- a/pcsx2/System.cpp +++ b/pcsx2/System.cpp @@ -21,9 +21,6 @@ #include "SamplProf.h" -// Includes needed for cleanup, since we don't have a good system (yet) for -// cleaning up these things. -#include "GameDatabase.h" #include "Elfheader.h" #include "System/RecTypes.h" @@ -114,7 +111,7 @@ void RecompiledCodeReserve::ThrowIfNotOk() const throw Exception::OutOfMemory(m_name) .SetDiagMsg(pxsFmt( L"Recompiled code cache could not be mapped." )) - .SetUserMsg( pxE( ".Error:Recompiler:VirtualMemoryAlloc", + .SetUserMsg( pxE( "!Notice:Recompiler:VirtualMemoryAlloc", L"This recompiler was unable to reserve contiguous memory required for internal caches. " L"This error can be caused by low virtual memory resources, such as a small or disabled swapfile, " L"or by another program that is hogging a lot of memory. You can also try reducing the default " @@ -212,8 +209,8 @@ void SysLogMachineCaps() Console.WriteLn( Color_StrongBlack, "Host Machine Init:" ); Console.Indent().WriteLn( - L"Operating System = %s\n" - L"Physical RAM = %u MB", + L"Operating System = %s\n" + L"Physical RAM = %u MB", GetOSVersionString().c_str(), (u32)(GetPhysicalMemory() / _1mb) @@ -223,7 +220,7 @@ void SysLogMachineCaps() Console.Indent().WriteLn( L"CPU name = %s\n" - L"Vendor/Model = %s - stepping=%02X\n" + L"Vendor/Model = %s (stepping %02X)\n" L"CPU speed = %u.%03u ghz (%u logical thread%s)\n" L"x86PType = %s\n" L"x86Flags = %08x %08x\n" @@ -346,7 +343,7 @@ public: // returns the translated error message for the Virtual Machine failing to allocate! static wxString GetMemoryErrorVM() { - return pxE( ".Error:EmuCore::MemoryForVM", + return pxE( "!Notice:EmuCore::MemoryForVM", L"PCSX2 is unable to allocate memory needed for the PS2 virtual machine. " L"Close out some memory hogging background tasks and try again." ); diff --git a/pcsx2/gui/AdvancedDialog.cpp b/pcsx2/gui/AdvancedDialog.cpp deleted file mode 100644 index 91bee6fb09..0000000000 --- a/pcsx2/gui/AdvancedDialog.cpp +++ /dev/null @@ -1,16 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2002-2010 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#include "PrecompiledHeader.h" diff --git a/pcsx2/gui/AdvancedDialog.h b/pcsx2/gui/AdvancedDialog.h deleted file mode 100644 index 3c71fcab80..0000000000 --- a/pcsx2/gui/AdvancedDialog.h +++ /dev/null @@ -1,21 +0,0 @@ -/* PCSX2 - PS2 Emulator for PCs - * Copyright (C) 2002-2010 PCSX2 Dev Team - * - * PCSX2 is free software: you can redistribute it and/or modify it under the terms - * of the GNU Lesser General Public License as published by the Free Software Found- - * ation, either version 3 of the License, or (at your option) any later version. - * - * PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with PCSX2. - * If not, see . - */ - -#ifndef ADVANCEDDIALOG_H_INCLUDED -#define ADVANCEDDIALOG_H_INCLUDED - - - -#endif // ADVANCEDDIALOG_H_INCLUDED diff --git a/pcsx2/gui/App.h b/pcsx2/gui/App.h index 89538f7810..57e669d90a 100644 --- a/pcsx2/gui/App.h +++ b/pcsx2/gui/App.h @@ -359,6 +359,10 @@ class Pcsx2AppTraits : public wxGUIAppTraits public: virtual ~Pcsx2AppTraits() {} wxMessageOutput* CreateMessageOutput(); + +#ifdef wxUSE_STDPATHS + wxStandardPathsBase& GetStandardPaths(); +#endif }; // ===================================================================================================== diff --git a/pcsx2/gui/AppConfig.cpp b/pcsx2/gui/AppConfig.cpp index 8a0b525c6f..90f6e99682 100644 --- a/pcsx2/gui/AppConfig.cpp +++ b/pcsx2/gui/AppConfig.cpp @@ -97,26 +97,7 @@ namespace PathDefs // Specifies the main configuration folder. wxDirName GetUserLocalDataDir() { -#ifdef __LINUX__ - // Note: GetUserLocalDataDir() on linux return $HOME/.pcsx2 unfortunately it does not follow the XDG standard - // So we re-implement it, to follow the standard. - wxDirName user_local_dir; - wxString xdg_home_value; - if( wxGetEnv(L"XDG_CONFIG_HOME", &xdg_home_value) ) { - if ( xdg_home_value.IsEmpty() ) { - // variable exist but it is empty. So use the default value - user_local_dir = (wxDirName)Path::Combine( wxStandardPaths::Get().GetUserConfigDir() , wxDirName( L".config/pcsx2" )); - } else { - user_local_dir = (wxDirName)Path::Combine( xdg_home_value, pxGetAppName()); - } - } else { - // variable do not exist - user_local_dir = (wxDirName)Path::Combine( wxStandardPaths::Get().GetUserConfigDir() , wxDirName( L".config/pcsx2" )); - } - return user_local_dir; -#else return wxDirName(wxStandardPaths::Get().GetUserLocalDataDir()); -#endif } // Fetches the path location for user-consumable documents -- stuff users are likely to want to @@ -383,7 +364,7 @@ AppConfig::AppConfig() , GameDatabaseTabName( L"none" ) , DeskTheme( L"default" ) { - LanguageId = wxLANGUAGE_DEFAULT; + LanguageCode = L"default"; RecentIsoCount = 12; Listbook_ImageSize = 32; Toolbar_ImageSize = 24; @@ -486,7 +467,7 @@ void AppConfig::LoadSaveRootItems( IniInterface& ini ) IniEntry( McdSettingsTabName ); IniEntry( AppSettingsTabName ); IniEntry( GameDatabaseTabName ); - ini.EnumEntry( L"LanguageId", LanguageId, NULL, defaults.LanguageId ); + IniEntry( LanguageCode ); IniEntry( RecentIsoCount ); IniEntry( DeskTheme ); IniEntry( Listbook_ImageSize ); diff --git a/pcsx2/gui/AppConfig.h b/pcsx2/gui/AppConfig.h index ab5a345893..c5f5ac5dee 100644 --- a/pcsx2/gui/AppConfig.h +++ b/pcsx2/gui/AppConfig.h @@ -195,8 +195,8 @@ public: wxString AppSettingsTabName; wxString GameDatabaseTabName; - // Current language in use (correlates to a wxWidgets wxLANGUAGE specifier) - wxLanguage LanguageId; + // Current language in use (correlates to the universal language codes, such as "en_US", "de_DE", etc). + wxString LanguageCode; int RecentIsoCount; // number of files displayed in the Recent Isos list. diff --git a/pcsx2/gui/AppInit.cpp b/pcsx2/gui/AppInit.cpp index d9f539b5eb..143096d8ba 100644 --- a/pcsx2/gui/AppInit.cpp +++ b/pcsx2/gui/AppInit.cpp @@ -41,7 +41,7 @@ static void CpuCheckSSE2() wxDialogWithHelpers exconf( NULL, _("PCSX2 - SSE2 Recommended") ); - exconf += exconf.Heading( pxE( ".Popup:Startup:NoSSE2", + exconf += exconf.Heading( pxE( "!Notice:Startup:NoSSE2", L"Warning: Your computer does not support SSE2, which is required by many PCSX2 recompilers and plugins. " L"Your options will be limited and emulation will be *very* slow." ) ); @@ -264,7 +264,7 @@ void Pcsx2App::AllocateCoreStuffs() wxDialogWithHelpers exconf( NULL, _("PCSX2 Recompiler Error(s)") ); exconf += 12; - exconf += exconf.Heading( pxE( ".Popup:RecompilerInit:Header", + exconf += exconf.Heading( pxE( "!Notice:RecompilerInit:Header", L"Warning: Some of the configured PS2 recompilers failed to initialize and have been disabled:" ) ); @@ -318,7 +318,7 @@ void Pcsx2App::AllocateCoreStuffs() recOps.EnableVU1 = recOps.EnableVU1 && recOps.UseMicroVU1; } - exconf += exconf.Heading( pxE(".Popup:RecompilerInit:Footer", + exconf += exconf.Heading( pxE("!Notice:RecompilerInit:Footer", L"Note: Recompilers are not necessary for PCSX2 to run, however they typically improve emulation speed substantially. " L"You may have to manually re-enable the recompilers listed above, if you resolve the errors." ) ); diff --git a/pcsx2/gui/AppMain.cpp b/pcsx2/gui/AppMain.cpp index fa64938bd9..0de560370f 100644 --- a/pcsx2/gui/AppMain.cpp +++ b/pcsx2/gui/AppMain.cpp @@ -29,6 +29,8 @@ #include "Utilities/IniInterface.h" +#include + #ifdef __WXMSW__ # include // needed to implement the app! #endif @@ -328,7 +330,54 @@ wxMessageOutput* Pcsx2AppTraits::CreateMessageOutput() return new pxMessageOutputMessageBox; #endif } - + +// -------------------------------------------------------------------------------------- +// Pcsx2StandardPaths +// -------------------------------------------------------------------------------------- +#ifdef wxUSE_STDPATHS +class Pcsx2StandardPaths : public wxStandardPaths +{ +public: + wxString GetResourcesDir() const + { + return Path::Combine( GetDataDir(), L"Langs" ); + } + +#ifdef __LINUX__ + wxString GetUserLocalDataDir() const + { + // Note: GetUserLocalDataDir() on linux return $HOME/.pcsx2 unfortunately it does not follow the XDG standard + // So we re-implement it, to follow the standard. + wxDirName user_local_dir; + wxString xdg_home_value; + if( wxGetEnv(L"XDG_CONFIG_HOME", &xdg_home_value) ) { + if ( xdg_home_value.IsEmpty() ) { + // variable exist but it is empty. So use the default value + user_local_dir = (wxDirName)Path::Combine( GetUserConfigDir() , wxDirName( L".config/pcsx2" )); + } else { + user_local_dir = (wxDirName)Path::Combine( xdg_home_value, pxGetAppName()); + } + } else { + // variable do not exist + user_local_dir = (wxDirName)Path::Combine( GetUserConfigDir() , wxDirName( L".config/pcsx2" )); + } + return user_local_dir; + } +#endif +}; + +wxStandardPathsBase& Pcsx2AppTraits::GetStandardPaths() +{ + static Pcsx2StandardPaths stdPaths; + return stdPaths; +} +#endif + +wxAppTraits* Pcsx2App::CreateTraits() +{ + return new Pcsx2AppTraits; +} + // -------------------------------------------------------------------------------------- // FramerateManager (implementations) // -------------------------------------------------------------------------------------- @@ -423,7 +472,7 @@ void Pcsx2App::OnEmuKeyDown( wxKeyEvent& evt ) // are multiple variations on the BIOS and BIOS folder checks). wxString BIOS_GetMsg_Required() { - return pxE( ".Popup:BiosDumpRequired", + return pxE( "!Notice:BiosDumpRequired", L"\n\n" L"PCSX2 requires a PS2 BIOS in order to run. For legal reasons, you *must* obtain \n" L"a BIOS from an actual PS2 unit that you own (borrowing doesn't count).\n" @@ -507,7 +556,7 @@ void Pcsx2App::HandleEvent(wxEvtHandler* handler, wxEventFunction func, wxEvent& wxDialogWithHelpers dialog( NULL, _("PCSX2 Unresponsive Thread"), wxVERTICAL ); dialog += dialog.Heading( ex.FormatDisplayMessage() + L"\n\n" + - pxE( ".Popup Error:Thread Deadlock Actions", + pxE( "!Notice Error:Thread Deadlock Actions", L"'Ignore' to continue waiting for the thread to respond.\n" L"'Cancel' to attempt to cancel the thread.\n" L"'Terminate' to quit PCSX2 immediately.\n" @@ -574,11 +623,6 @@ void Pcsx2App::ClearPendingSave() } } -wxAppTraits* Pcsx2App::CreateTraits() -{ - return new Pcsx2AppTraits; -} - // This method generates debug assertions if the MainFrame handle is NULL (typically // indicating that PCSX2 is running in NoGUI mode, or that the main frame has been // closed). In most cases you'll want to use HasMainFrame() to test for thread @@ -622,10 +666,10 @@ void AppApplySettings( const AppConfig* oldconf ) RelocateLogfile(); - if( (oldconf == NULL) || (oldconf->LanguageId != g_Conf->LanguageId) ) + if( (oldconf == NULL) || (oldconf->LanguageCode.CmpNoCase(g_Conf->LanguageCode)) ) { wxDoNotLogInThisScope please; - if( !i18n_SetLanguage( g_Conf->LanguageId ) ) + if( !i18n_SetLanguage( g_Conf->LanguageCode ) ) { if( !i18n_SetLanguage( wxLANGUAGE_DEFAULT ) ) { diff --git a/pcsx2/gui/Dialogs/CreateMemoryCardDialog.cpp b/pcsx2/gui/Dialogs/CreateMemoryCardDialog.cpp index 2654ff16cf..921fda522c 100644 --- a/pcsx2/gui/Dialogs/CreateMemoryCardDialog.cpp +++ b/pcsx2/gui/Dialogs/CreateMemoryCardDialog.cpp @@ -148,7 +148,7 @@ void Dialogs::CreateMemoryCardDialog::CreateControls() GetMsg_McdNtfsCompress() ); - m_check_CompressNTFS->SetToolTip( pxE( ".Tooltip:ChangingNTFS", + m_check_CompressNTFS->SetToolTip( pxEt( "!ContextTip:ChangingNTFS", L"NTFS compression can be changed manually at any time by using file properties from Windows Explorer." ) ); diff --git a/pcsx2/gui/Dialogs/FirstTimeWizard.cpp b/pcsx2/gui/Dialogs/FirstTimeWizard.cpp index 36af9a4743..5e353a8148 100644 --- a/pcsx2/gui/Dialogs/FirstTimeWizard.cpp +++ b/pcsx2/gui/Dialogs/FirstTimeWizard.cpp @@ -45,12 +45,12 @@ bool ApplicableWizardPage::PrepForApply() Panels::SettingsDirPickerPanel::SettingsDirPickerPanel( wxWindow* parent ) : DirPickerPanel( parent, FolderId_Settings, _("Settings"), AddAppName(_("Select a folder for %s settings")) ) { - pxSetToolTip( this, pxE( ".Tooltip:Folders:Settings", + pxSetToolTip( this, pxEt( "!ContextTip:Folders:Settings", L"This is the folder where PCSX2 saves your settings, including settings generated " L"by most plugins (some older plugins may not respect this value)." ) ); - SetStaticDesc( pxE( ".Panel:Folders:Settings", + SetStaticDesc( pxE( "!Panel:Folders:Settings", L"You may optionally specify a location for your PCSX2 settings here. If the location " L"contains existing PCSX2 settings, you will be given the option to import or overwrite them." ) ); @@ -106,7 +106,7 @@ bool FirstTimeWizard::UsermodePage::PrepForApply() // FIXME: There's already a file by the same name.. not sure what we should do here. throw Exception::BadStream( path.ToString() ) .SetDiagMsg(L"Targeted documents folder is already occupied by a file.") - .SetUserMsg(pxE( ".Error:DocsFolderFileConflict", + .SetUserMsg(pxE( "!Notice:DocsFolderFileConflict", L"PCSX2 cannot create a documents folder in the requested location. " L"The path name matches an existing file. Delete the file or change the documents location, " L"and then try again." @@ -149,7 +149,7 @@ FirstTimeWizard::FirstTimeWizard( wxWindow* parent ) // Temporary tutorial message for the BIOS, needs proof-reading!! m_page_bios += 12; m_page_bios += new pxStaticHeading( &m_page_bios, - pxE( ".Wizard:Bios:Tutorial", + pxE( "!Wizard:Bios:Tutorial", L"PCSX2 requires a *legal* copy of the PS2 BIOS in order to run games.\n" L"You cannot use a copy obtained from a friend or the Internet.\n" L"You must dump the BIOS from your *own* Playstation 2 console." diff --git a/pcsx2/gui/Dialogs/GameDatabaseDialog.cpp b/pcsx2/gui/Dialogs/GameDatabaseDialog.cpp index 261c750630..1b8740c2a0 100644 --- a/pcsx2/gui/Dialogs/GameDatabaseDialog.cpp +++ b/pcsx2/gui/Dialogs/GameDatabaseDialog.cpp @@ -17,10 +17,13 @@ #include "ConfigurationDialog.h" #include "Panels/ConfigurationPanels.h" +using namespace Panels; +using namespace pxSizerFlags; + Dialogs::GameDatabaseDialog::GameDatabaseDialog(wxWindow* parent) - : BaseConfigurationDialog( parent, AddAppName(_("Game Database - %s")), 580 ) + : BaseConfigurationDialog( parent, AddAppName(_("Game database - %s")), 580 ) { ScopedBusyCursor busy( Cursor_ReallyBusy ); - *this += new Panels::GameDatabasePanel(this); + *this += new GameDatabasePanel(this) | StdExpand(); AddOkCancel(); } diff --git a/pcsx2/gui/Dialogs/ImportSettingsDialog.cpp b/pcsx2/gui/Dialogs/ImportSettingsDialog.cpp index bda14a45ad..4f5c5ff0a2 100644 --- a/pcsx2/gui/Dialogs/ImportSettingsDialog.cpp +++ b/pcsx2/gui/Dialogs/ImportSettingsDialog.cpp @@ -25,8 +25,10 @@ Dialogs::ImportSettingsDialog::ImportSettingsDialog( wxWindow* parent ) { SetMinWidth( 440 ); - pxStaticText& heading( Text( wxsFormat( - pxE( ".Popup:ImportExistingSettings", + pxStaticText& heading( Text( pxsFmt( + + /// (%s is the app name, normally PCSX2 -- omitting one or both %s is allowed) + pxE( "!Notice:ImportExistingSettings", L"Existing %s settings have been found in the configured settings folder. " L"Would you like to import these settings or overwrite them with %s default values?" L"\n\n(or press Cancel to select a different settings folder)" diff --git a/pcsx2/gui/Dialogs/McdConfigDialog.cpp b/pcsx2/gui/Dialogs/McdConfigDialog.cpp index 4603dc1e44..b9aff77549 100644 --- a/pcsx2/gui/Dialogs/McdConfigDialog.cpp +++ b/pcsx2/gui/Dialogs/McdConfigDialog.cpp @@ -27,7 +27,7 @@ using namespace pxSizerFlags; wxString GetMsg_McdNtfsCompress() { - return pxE( ".Panel:Mcd:NtfsCompress", + return pxE( "!Panel:Mcd:NtfsCompress", L"NTFS compression is built-in, fast, and completely reliable; and typically compresses memory cards " L"very well (this option is highly recommended)." ); @@ -38,7 +38,7 @@ Panels::McdConfigPanel_Toggles::McdConfigPanel_Toggles(wxWindow *parent) { m_check_Ejection = new pxCheckBox( this, _("Auto-eject memory cards when loading savestates"), - pxE( ".Panel:Mcd:EnableEjection", + pxE( "!Panel:Mcd:EnableEjection", L"Avoids memory card corruption by forcing games to re-index card contents after " L"loading from savestates. May not be compatible with all games (Guitar Hero)." ) diff --git a/pcsx2/gui/Dialogs/StuckThreadDialog.cpp b/pcsx2/gui/Dialogs/StuckThreadDialog.cpp index 8244d5b359..78d279c9db 100644 --- a/pcsx2/gui/Dialogs/StuckThreadDialog.cpp +++ b/pcsx2/gui/Dialogs/StuckThreadDialog.cpp @@ -30,7 +30,7 @@ Dialogs::StuckThreadDialog::StuckThreadDialog( wxWindow* parent, StuckThreadActi stuck_thread.AddListener( this ); *this += Heading( wxsFormat( - pxE( ".Panel:StuckThread:Heading", + pxE( "!Panel:StuckThread:Heading", L"The thread '%s' is not responding. It could be deadlocked, or it might " L"just be running *really* slowly." ), diff --git a/pcsx2/gui/Dialogs/SysConfigDialog.cpp b/pcsx2/gui/Dialogs/SysConfigDialog.cpp index 287fb89b5d..283a766ee8 100644 --- a/pcsx2/gui/Dialogs/SysConfigDialog.cpp +++ b/pcsx2/gui/Dialogs/SysConfigDialog.cpp @@ -23,6 +23,7 @@ #include "Panels/ConfigurationPanels.h" using namespace Panels; +using namespace pxSizerFlags; static void CheckHacksOverrides() { @@ -33,7 +34,7 @@ static void CheckHacksOverrides() wxDialogWithHelpers dialog( wxFindWindowByName( L"Dialog:" + Dialogs::SysConfigDialog::GetNameStatic() ), _("Config Overrides Warning") ); - dialog += dialog.Text( pxE(".Panel:HasHacksOverrides", + dialog += dialog.Text( pxE("!Panel:HasHacksOverrides", L"Warning! You are running PCSX2 with command line options that override your configured settings. " L"These command line options will not be reflected in the Settings dialog, and will be disabled " L"if you apply any changes here." @@ -53,7 +54,7 @@ static void CheckPluginsOverrides() wxDialogWithHelpers dialog( NULL, _("Components Overrides Warning") ); - dialog += dialog.Text( pxE(".Panel:HasPluginsOverrides", + dialog += dialog.Text( pxE("!Panel:HasPluginsOverrides", L"Warning! You are running PCSX2 with command line options that override your configured plugin and/or folder settings. " L"These command line options will not be reflected in the settings dialog, and will be disabled " L"when you apply settings changes here." diff --git a/pcsx2/gui/ExecutorThread.cpp b/pcsx2/gui/ExecutorThread.cpp index e822cb7c7c..77519dd9fa 100644 --- a/pcsx2/gui/ExecutorThread.cpp +++ b/pcsx2/gui/ExecutorThread.cpp @@ -23,13 +23,13 @@ using namespace pxSizerFlags; // -------------------------------------------------------------------------------------- bool ConsoleLogSource_Event::Write( const pxEvtHandler* evtHandler, const SysExecEvent* evt, const wxChar* msg ) { - return _parent::Write( wxsFormat(L"(%s%s) ", evtHandler->GetEventHandlerName().c_str(), evt->GetEventName().c_str()) + msg ); + return _parent::Write( pxsFmt(L"(%s:%s) ", evtHandler->GetEventHandlerName().c_str(), evt->GetEventName().c_str()) + msg ); } bool ConsoleLogSource_Event::Warn( const pxEvtHandler* evtHandler, const SysExecEvent* evt, const wxChar* msg ) { - return _parent::Write( wxsFormat(L"(%s%s) ", evtHandler->GetEventHandlerName().c_str(), evt->GetEventName().c_str()) + msg ); + return _parent::Write( pxsFmt(L"(%s:%s) ", evtHandler->GetEventHandlerName().c_str(), evt->GetEventName().c_str()) + msg ); } bool ConsoleLogSource_Event::Error( const pxEvtHandler* evtHandler, const SysExecEvent* evt, const wxChar* msg ) { - return _parent::Write( wxsFormat(L"(%s%s) ", evtHandler->GetEventHandlerName().c_str(), evt->GetEventName().c_str()) + msg ); + return _parent::Write( pxsFmt(L"(%s:%s) ", evtHandler->GetEventHandlerName().c_str(), evt->GetEventName().c_str()) + msg ); } ConsoleLogSource_Event::ConsoleLogSource_Event() diff --git a/pcsx2/gui/FrameForGS.cpp b/pcsx2/gui/FrameForGS.cpp index 084c593c4d..5801fc7f4b 100644 --- a/pcsx2/gui/FrameForGS.cpp +++ b/pcsx2/gui/FrameForGS.cpp @@ -401,16 +401,16 @@ void GSFrame::OnUpdateTitle( wxTimerEvent& evt ) } } - wxString cpuUsage; + FastFormatUnicode cpuUsage; if( m_CpuUsage.IsImplemented() ) { m_CpuUsage.UpdateStats(); - cpuUsage = wxsFormat( L" | EE: %3d%% | GS: %3d%% | UI: %3d%%", m_CpuUsage.GetEEcorePct(), m_CpuUsage.GetGsPct(), m_CpuUsage.GetGuiPct() ); + cpuUsage.Write( L" | EE: %3d%% | GS: %3d%% | UI: %3d%%", m_CpuUsage.GetEEcorePct(), m_CpuUsage.GetGsPct(), m_CpuUsage.GetGuiPct() ); } const u64& smode2 = *(u64*)PS2GS_BASE(GS_SMODE2); - SetTitle( wxsFormat( L"%s | %s (%s) | Limiter: %s | fps: %6.02f%s", + SetTitle( pxsFmt( L"%s | %s (%s) | Limiter: %s | fps: %6.02f%s", fromUTF8(gsDest).c_str(), (smode2 & 1) ? L"Interlaced" : L"Progressive", (smode2 & 2) ? L"frame" : L"field", diff --git a/pcsx2/gui/IsoDropTarget.cpp b/pcsx2/gui/IsoDropTarget.cpp index dcc740cdc3..9828c5ab46 100644 --- a/pcsx2/gui/IsoDropTarget.cpp +++ b/pcsx2/gui/IsoDropTarget.cpp @@ -25,7 +25,7 @@ wxString GetMsg_ConfirmSysReset() { - return pxE( ".Popup:ConfirmSysReset", + return pxE( "!Notice:ConfirmSysReset", L"This action will reset the existing PS2 virtual machine state; " L"all current progress will be lost. Are you sure?" ); diff --git a/pcsx2/gui/MainFrame.cpp b/pcsx2/gui/MainFrame.cpp index 7d47e48038..0f927744e3 100644 --- a/pcsx2/gui/MainFrame.cpp +++ b/pcsx2/gui/MainFrame.cpp @@ -423,12 +423,14 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title) m_menuConfig.Append(MenuId_Config_SysSettings, _("Emulation &Settings") ); m_menuConfig.Append(MenuId_Config_McdSettings, _("&Memory cards") ); m_menuConfig.Append(MenuId_Config_BIOS, _("&Plugin/BIOS Selector") ); - //m_menuConfig.Append(MenuId_Config_GameDatabase, _("Game Database Editor") ); + if (IsDebugBuild) + m_menuConfig.Append(MenuId_Config_GameDatabase, _("Game Database Editor") ); + m_menuConfig.AppendSeparator(); m_menuConfig.Append(MenuId_Config_GS, _("&Video (GS)"), m_PluginMenuPacks[PluginId_GS]); m_menuConfig.Append(MenuId_Config_SPU2, _("&Audio (SPU2)"), m_PluginMenuPacks[PluginId_SPU2]); - m_menuConfig.Append(MenuId_Config_PAD, _("&Controllers (PAD)"), m_PluginMenuPacks[PluginId_PAD]); + m_menuConfig.Append(MenuId_Config_PAD, _("&Controllers (PAD)"),m_PluginMenuPacks[PluginId_PAD]); m_menuConfig.Append(MenuId_Config_DEV9, _("Dev9"), m_PluginMenuPacks[PluginId_DEV9]); m_menuConfig.Append(MenuId_Config_USB, _("USB"), m_PluginMenuPacks[PluginId_USB]); m_menuConfig.Append(MenuId_Config_FireWire, _("Firewire"), m_PluginMenuPacks[PluginId_FW]); diff --git a/pcsx2/gui/MainMenuClicks.cpp b/pcsx2/gui/MainMenuClicks.cpp index b4dfbb3ced..2ba3980eca 100644 --- a/pcsx2/gui/MainMenuClicks.cpp +++ b/pcsx2/gui/MainMenuClicks.cpp @@ -50,7 +50,7 @@ void MainEmuFrame::Menu_McdSettings_Click(wxCommandEvent &event) void MainEmuFrame::Menu_GameDatabase_Click(wxCommandEvent &event) { - AppOpenDialog( this ); + AppOpenDialog( this ); } void MainEmuFrame::Menu_WindowSettings_Click(wxCommandEvent &event) @@ -104,7 +104,7 @@ void MainEmuFrame::Menu_ResetAllSettings_Click(wxCommandEvent &event) { ScopedCoreThreadPopup suspender; if( !Msgbox::OkCancel( pxsFmt( - pxE( ".Popup:DeleteSettings", + pxE( "!Notice:DeleteSettings", L"This command clears %s settings and allows you to re-run the First-Time Wizard. You will need to " L"manually restart %s after this operation.\n\n" L"WARNING!! Click OK to delete *ALL* settings for %s and force-close the app, losing any current emulation progress. Are you absolutely sure?" diff --git a/pcsx2/gui/MemoryCardFile.cpp b/pcsx2/gui/MemoryCardFile.cpp index e82734de6b..bad33ef61a 100644 --- a/pcsx2/gui/MemoryCardFile.cpp +++ b/pcsx2/gui/MemoryCardFile.cpp @@ -74,7 +74,7 @@ protected: wxString GetDisabledMessage( uint slot ) const { - return pxE( ".Popup:Mcd:HasBeenDisabled", wxsFormat( + return pxE( "!Notice:Mcd:HasBeenDisabled", wxsFormat( L"The memory card in slot %d has been automatically disabled. You can correct the problem\n" L"and re-enable the memory card at any time using Config:Memory cards from the main menu.", slot diff --git a/pcsx2/gui/Panels/BiosSelectorPanel.cpp b/pcsx2/gui/Panels/BiosSelectorPanel.cpp index ff41ed6d75..fb11e4b4da 100644 --- a/pcsx2/gui/Panels/BiosSelectorPanel.cpp +++ b/pcsx2/gui/Panels/BiosSelectorPanel.cpp @@ -123,7 +123,7 @@ void Panels::BiosSelectorPanel::Apply() { throw Exception::CannotApplySettings(this) .SetDiagMsg(L"User did not specify a valid BIOS selection.") - .SetUserMsg( pxE( ".Error:BIOS:InvalidSelection", + .SetUserMsg( pxE( "!Notice:BIOS:InvalidSelection", L"Please select a valid BIOS. If you are unable to make a valid selection " L"then press cancel to close the Configuration panel." ) ); diff --git a/pcsx2/gui/Panels/DirPickerPanel.cpp b/pcsx2/gui/Panels/DirPickerPanel.cpp index 62e53af084..d6b9b70247 100644 --- a/pcsx2/gui/Panels/DirPickerPanel.cpp +++ b/pcsx2/gui/Panels/DirPickerPanel.cpp @@ -60,7 +60,7 @@ void Panels::DirPickerPanel::Explore_Click( wxCommandEvent &evt ) createPathDlg += createPathDlg.Text( path ) | StdCenter(); - createPathDlg += createPathDlg.Heading( pxE( ".Error:DirPicker:CreatePath", + createPathDlg += createPathDlg.Heading( pxE( "!Notice:DirPicker:CreatePath", L"The specified path/directory does not exist. Would you like to create it?" ) ); @@ -115,7 +115,7 @@ void Panels::DirPickerPanel::Init( FoldersEnum_t folderid, const wxString& dialo { m_checkCtrl = new pxCheckBox( this, _("Use default setting") ); - pxSetToolTip( m_checkCtrl, pxE( ".Tooltip:DirPicker:UseDefault", + pxSetToolTip( m_checkCtrl, pxEt( "!ContextTip:DirPicker:UseDefault", L"When checked this folder will automatically reflect the default associated with PCSX2's current usermode setting. " ) ); diff --git a/pcsx2/gui/Panels/GSWindowPanel.cpp b/pcsx2/gui/Panels/GSWindowPanel.cpp index 48205ef04b..4f0080b7b5 100644 --- a/pcsx2/gui/Panels/GSWindowPanel.cpp +++ b/pcsx2/gui/Panels/GSWindowPanel.cpp @@ -48,28 +48,28 @@ Panels::GSWindowSettingsPanel::GSWindowSettingsPanel( wxWindow* parent ) m_check_VsyncEnable = new pxCheckBox( this, _("Wait for vsync on refresh") ); m_check_ExclusiveFS = new pxCheckBox( this, _("Use exclusive fullscreen mode (if available)") ); - m_check_VsyncEnable->SetToolTip( pxE( ".Tooltip:Window:Vsync", + m_check_VsyncEnable->SetToolTip( pxEt( "!ContextTip:Window:Vsync", L"Vsync eliminates screen tearing but typically has a big performance hit. " L"It usually only applies to fullscreen mode, and may not work with all GS plugins." ) ); - m_check_HideMouse->SetToolTip( pxE( ".Tooltip:Window:HideMouse", + m_check_HideMouse->SetToolTip( pxEt( "!ContextTip:Window:HideMouse", L"Check this to force the mouse cursor invisible inside the GS window; useful if using " L"the mouse as a primary control device for gaming. By default the mouse auto-hides after " L"2 seconds of inactivity." ) ); - m_check_Fullscreen->SetToolTip( pxE( ".Tooltip:Window:Fullscreen", + m_check_Fullscreen->SetToolTip( pxEt( "!ContextTip:Window:Fullscreen", L"Enables automatic mode switch to fullscreen when starting or resuming emulation. " L"You can still toggle fullscreen display at any time using alt-enter." ) ); - m_check_ExclusiveFS->SetToolTip( pxE( ".Tooltip:Window:FullscreenExclusive", + m_check_ExclusiveFS->SetToolTip( pxEt( "!ContextTip:Window:FullscreenExclusive", L"Fullscreen Exclusive Mode may look better on older CRTs and might be a little faster on older video cards, " L"but typically can lead to memory leaks or random crashes when entering/leaving fullscreen mode." ) ); - m_check_CloseGS->SetToolTip( pxE( ".Tooltip:Window:HideGS", + m_check_CloseGS->SetToolTip( pxEt( "!ContextTip:Window:HideGS", L"Completely closes the often large and bulky GS window when pressing " L"ESC or suspending the emulator." ) ); diff --git a/pcsx2/gui/Panels/GameDatabasePanel.cpp b/pcsx2/gui/Panels/GameDatabasePanel.cpp index 52db0630b5..652b761b56 100644 --- a/pcsx2/gui/Panels/GameDatabasePanel.cpp +++ b/pcsx2/gui/Panels/GameDatabasePanel.cpp @@ -18,11 +18,301 @@ #include "AppGameDatabase.h" #include "ConfigurationPanels.h" +#include + extern wxString DiscSerial; + using namespace pxSizerFlags; -#define blankLine() { \ - sizer1+=5; sizer1+=5; sizer1+=Text(L""); sizer1+=5; sizer1+=5; \ + +enum GameDataColumnId +{ + GdbCol_Serial = 0, + GdbCol_Title, + GdbCol_Region, + GdbCol_Compat, + GdbCol_Patches, + + GdbCol_Count +}; + +struct ListViewColumnInfo +{ + const wxChar* name; + int width; + wxListColumnFormat align; +}; + +// -------------------------------------------------------------------------------------- +// GameDatabaseListView +// -------------------------------------------------------------------------------------- +class GameDatabaseListView : public wxListView +{ + typedef wxListView _parent; + +protected: + wxArrayString m_GamesInView; + +public: + virtual ~GameDatabaseListView() throw() { } + GameDatabaseListView( wxWindow* parent ); + + void CreateColumns(); + GameDatabaseListView& AddGame( const wxString& serial ); + GameDatabaseListView& RemoveGame( const wxString& serial ); + GameDatabaseListView& ClearAllGames(); + GameDatabaseListView& SortBy( GameDataColumnId column ); + +protected: + // Overrides for wxLC_VIRTUAL + virtual wxString OnGetItemText(long item, long column) const; + virtual int OnGetItemImage(long item) const; + virtual int OnGetItemColumnImage(long item, long column) const; + virtual wxListItemAttr* OnGetItemAttr(long item) const; + + const ListViewColumnInfo& GetDefaultColumnInfo( uint idx ) const; +}; + +// -------------------------------------------------------------------------------------- +// GameDatabaseListView (implementations) +// -------------------------------------------------------------------------------------- +GameDatabaseListView::GameDatabaseListView( wxWindow* parent ) + : _parent( parent ) +{ + CreateColumns(); +} + +const ListViewColumnInfo& GameDatabaseListView::GetDefaultColumnInfo( uint idx ) const +{ + static const ListViewColumnInfo columns[] = + { + { L"Serial", 96, wxLIST_FORMAT_LEFT }, + { L"Title", 132, wxLIST_FORMAT_LEFT }, + { L"Region", 72, wxLIST_FORMAT_CENTER }, + { L"Compat", 48, wxLIST_FORMAT_CENTER }, + { L"Patches", 48, wxLIST_FORMAT_CENTER }, + }; + + pxAssumeDev( idx < ArraySize(columns), "ListView column index is out of bounds." ); + return columns[idx]; +} + +void GameDatabaseListView::CreateColumns() +{ + for( int i=0; ifindGame(first, i1)) return false; + if (!m_GameDB->findGame(second, i2)) return true; + + if (int retval = _doCompare(first, second)) + return m_descending ? (retval>0) : (retval<0); + + return 0; + } + + virtual int _doCompare( const Game_Data& first, const Game_Data& second )=0; +}; + +class GLSort_bySerial : public BaseGameListSort +{ +public: + GLSort_bySerial( bool descend ) : BaseGameListSort( descend ) { } + +protected: + int _doCompare( const Game_Data& g1, const Game_Data& g2 ) + { + return g1.getString("Serial").CmpNoCase( g2.getString("Serial") ); + } +}; + +class GLSort_byTitle : public BaseGameListSort +{ +public: + GLSort_byTitle( bool descend ) : BaseGameListSort( descend ) { } + +protected: + int _doCompare( const Game_Data& g1, const Game_Data& g2 ) + { + return g1.getString("Name").Cmp( g2.getString("Name") ); + } +}; + +class GLSort_byRegion : public BaseGameListSort +{ +public: + GLSort_byRegion( bool descend ) : BaseGameListSort( descend ) { } + +protected: + int _doCompare( const Game_Data& g1, const Game_Data& g2 ) + { + return g1.getString("Region").CmpNoCase( g2.getString("Region") ); + } +}; + +class GLSort_byCompat : public BaseGameListSort +{ +public: + GLSort_byCompat( bool descend ) : BaseGameListSort( descend ) { } + +protected: + int _doCompare( const Game_Data& g1, const Game_Data& g2 ) + { + return g1.getInt("Compat") - g2.getInt("Compat"); + } +}; + +class GLSort_byPatches : public BaseGameListSort +{ +public: + GLSort_byPatches( bool descend ) : BaseGameListSort( descend ) { } + +protected: + int _doCompare( const Game_Data& g1, const Game_Data& g2 ) + { + bool hasPatches1 = !g1.getString("[patches]").IsEmpty(); + bool hasPatches2 = !g2.getString("[patches]").IsEmpty(); + + if (hasPatches1 == hasPatches2) return 0; + + return hasPatches1 ? -1 : 1; + } +}; + +GameDatabaseListView& GameDatabaseListView::SortBy( GameDataColumnId column ) +{ + wxArrayString::CompareFunction cmpfunc = NULL; + + const bool isDescending = false; + + wxArrayString::iterator begin = m_GamesInView.begin(); + wxArrayString::iterator end = m_GamesInView.end(); + + // Note: std::sort does not pass predicate instances by reference, which means we can't use + // object polymorphism to simplify the code below. --air + + switch( column ) + { + case GdbCol_Serial: std::sort(begin, end, GLSort_bySerial(isDescending)); break; + case GdbCol_Title: std::sort(begin, end, GLSort_byTitle(isDescending)); break; + case GdbCol_Region: std::sort(begin, end, GLSort_byRegion(isDescending)); break; + case GdbCol_Compat: std::sort(begin, end, GLSort_byCompat(isDescending)); break; + case GdbCol_Patches: std::sort(begin, end, GLSort_byPatches(isDescending)); break; + + // do not use jNO_DEFAULT here -- keeps release builds from crashing (it'll just + // ignore the sort request!) + } + //m_GamesInView.( ); + + return *this; +} + +// return the text for the given column of the given item +wxString GameDatabaseListView::OnGetItemText(long item, long column) const +{ + IGameDatabase* GameDB = AppHost_GetGameDatabase(); + + if (!GameDB || (item < 0) || ((uint)item >= m_GamesInView.GetCount())) + return _parent::OnGetItemText(item, column); + + Game_Data game; + if (!GameDB->findGame(game, m_GamesInView[item])) + { + pxFail( "Unknown row index in GameDatabaseListView -- returning default value." ); + return _parent::OnGetItemText(item, column); + } + + switch( column ) + { + case GdbCol_Serial: return m_GamesInView[item]; + case GdbCol_Title: return game.getString("Name"); + case GdbCol_Region: return game.getString("Region"); + case GdbCol_Compat: return game.getString("Compat"); + case GdbCol_Patches: return game.getString("[patches]").IsEmpty() ? L"No" : L"Yes"; + } + + pxFail( "Unknown column index in GameDatabaseListView -- returning an empty string." ); + return wxEmptyString; +} + +// return the icon for the given item. In report view, OnGetItemImage will +// only be called for the first column. See OnGetItemColumnImage for +// details. +int GameDatabaseListView::OnGetItemImage(long item) const +{ + return _parent::OnGetItemImage( item ); +} + +// return the icon for the given item and column. +int GameDatabaseListView::OnGetItemColumnImage(long item, long column) const +{ + return _parent::OnGetItemColumnImage( item, column ); +} + +static wxListItemAttr m_ItemAttr; + +// return the attribute for the item (may return NULL if none) +wxListItemAttr* GameDatabaseListView::OnGetItemAttr(long item) const +{ + m_ItemAttr = wxListItemAttr(); // Wipe it clean! + + // For eventual drag&drop ? + //if( m_TargetedItem == item ) + // m_ItemAttr.SetBackgroundColour( wxColour(L"Wheat") ); + + return &m_ItemAttr; +} + + +#define blankLine() { \ + sizer1+=5; sizer1+=5; sizer1+=Text(wxEmptyString); sizer1+=5; sizer1+=5; \ } #define placeTextBox(wxBox, txt) { \ @@ -43,9 +333,6 @@ wxTextCtrl* CreateMultiLineTextCtrl( wxWindow* parent, int digits, long flags = Panels::GameDatabasePanel::GameDatabasePanel( wxWindow* parent ) : BaseApplicableConfigPanel( parent ) { - IGameDatabase* GameDB = AppHost_GetGameDatabase(); - pxAssume( GameDB != NULL ); - searchBtn = new wxButton (this, wxID_ANY, _("Search")); serialBox = CreateNumericalTextCtrl(this, 40, wxTE_LEFT); @@ -59,7 +346,8 @@ Panels::GameDatabasePanel::GameDatabasePanel( wxWindow* parent ) gameFixes[i] = new pxCheckBox(this, EnumToString(i), wxCHK_3STATE | wxCHK_ALLOW_3RD_STATE_FOR_USER ); *this += Heading(_("Game Database Editor")).Bold() | StdExpand(); - //*this += Heading(_("This panel lets you add and edit game titles, game fixes, and game patches.")) | StdExpand(); + + *this += new GameDatabaseListView( this ) | StdExpand(); wxFlexGridSizer& sizer1(*new wxFlexGridSizer(5, StdPadding)); sizer1.AddGrowableCol(0); diff --git a/pcsx2/gui/Panels/GameFixesPanel.cpp b/pcsx2/gui/Panels/GameFixesPanel.cpp index 8b6d10005c..ac14e3014b 100644 --- a/pcsx2/gui/Panels/GameFixesPanel.cpp +++ b/pcsx2/gui/Panels/GameFixesPanel.cpp @@ -64,7 +64,7 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent ) }, { _("EE timing hack - Multi purpose hack. Try if all else fails."), - pxE( ".Tooltip:Gamefixes:EE Timing Hack", + pxEt( "!ContextTip:Gamefixes:EE Timing Hack", L"Known to affect following games:\n" L" * Digital Devil Saga (Fixes FMV and crashes)\n" L" * SSX (Fixes bad graphics and crashes)\n" @@ -77,7 +77,7 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent ) }, { _("OPH Flag hack - Try if your game freezes showing the same frame."), - pxE( ".Tooltip:Gamefixes:OPH Flag hack", + pxEt( "!ContextTip:Gamefixes:OPH Flag hack", L"Known to affect following games:\n" L" * Bleach Blade Battler\n" L" * Growlanser II and III\n" @@ -93,7 +93,7 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent ) } m_check_Enable = new pxCheckBox( this, _("Enable game fixes"), - pxE( ".Panel:Gamefixes:Compat Warning", + pxE( "!Panel:Gamefixes:Compat Warning", L"Gamefixes can fix wrong emulation in some games. However " L"it can cause compatibility or performance issues in other games. You " L"will need to turn off fixes manually when changing games." diff --git a/pcsx2/gui/Panels/MemoryCardListPanel.cpp b/pcsx2/gui/Panels/MemoryCardListPanel.cpp index c00197699b..02cbd9c316 100644 --- a/pcsx2/gui/Panels/MemoryCardListPanel.cpp +++ b/pcsx2/gui/Panels/MemoryCardListPanel.cpp @@ -362,7 +362,7 @@ public: if( dest.IsPresent && dest.IsFormatted ) { - pxsFmt( pxE( ".Popup:Mcd:Overwrite", + pxsFmt( pxE( "!Notice:Mcd:Overwrite", L"This will copy the contents of the memory card in slot %u over the memory card in slot %u. " L"All data on the target slot will be lost. Are you sure?" ), src.Slot, dest.Slot @@ -376,7 +376,7 @@ public: if( !wxCopyFile( srcfile.GetFullPath(), destfile.GetFullPath(), true ) ) { wxString heading; - heading.Printf( pxE( ".Error:Mcd:Copy Failed", + heading.Printf( pxE( "!Notice:Mcd:Copy Failed", L"Error! Could not copy the memory card into slot %u. The destination file is in use." ), dest.Slot ); @@ -582,7 +582,7 @@ void Panels::MemoryCardListPanel_Simple::OnCreateCard(wxCommandEvent& evt) { wxString content; content.Printf( - pxE( ".Popup:Mcd:Delete", + pxE( "!Notice:Mcd:Delete", L"You are about to delete the formatted memory card in slot %u. " L"All data on this card will be lost! Are you absolutely and quite positively sure?" ), slot diff --git a/pcsx2/gui/Panels/MemoryCardPanels.h b/pcsx2/gui/Panels/MemoryCardPanels.h index 9bed7079a0..4eba605210 100644 --- a/pcsx2/gui/Panels/MemoryCardPanels.h +++ b/pcsx2/gui/Panels/MemoryCardPanels.h @@ -20,6 +20,13 @@ #include #include +struct ListViewColumnInfo +{ + const wxChar* name; + int width; + wxListColumnFormat align; +}; + // -------------------------------------------------------------------------------------- // McdListItem / IMcdList // -------------------------------------------------------------------------------------- @@ -67,13 +74,6 @@ public: virtual wxDirName GetMcdPath() const=0; }; -struct ListViewColumnInfo -{ - const wxChar* name; - int width; - wxListColumnFormat align; -}; - // -------------------------------------------------------------------------------------- // BaseMcdListView // -------------------------------------------------------------------------------------- diff --git a/pcsx2/gui/Panels/MiscPanelStuff.cpp b/pcsx2/gui/Panels/MiscPanelStuff.cpp index ad910c9e05..31a81cf309 100644 --- a/pcsx2/gui/Panels/MiscPanelStuff.cpp +++ b/pcsx2/gui/Panels/MiscPanelStuff.cpp @@ -32,13 +32,13 @@ using namespace pxSizerFlags; Panels::DocsFolderPickerPanel::DocsFolderPickerPanel( wxWindow* parent, bool isFirstTime ) : BaseApplicableConfigPanel( parent, wxVERTICAL, _("Usermode Selection") ) { - const wxString usermodeExplained( pxE( ".Panel:Usermode:Explained", + const wxString usermodeExplained( pxE( "!Panel:Usermode:Explained", L"Please select your preferred default location for PCSX2 user-level documents below " L"(includes memory cards, screenshots, settings, and savestates). " L"These folder locations can be overridden at any time using the Core Settings panel." ) ); - const wxString usermodeWarning( pxE( ".Panel:Usermode:Warning", + const wxString usermodeWarning( pxE( "!Panel:Usermode:Warning", L"You can change the preferred default location for PCSX2 user-level documents here " L"(includes memory cards, screenshots, settings, and savestates). " L"This option only affects Standard Paths which are set to use the installation default value." @@ -127,7 +127,7 @@ Panels::LanguageSelectionPanel::LanguageSelectionPanel( wxWindow* parent ) m_picker = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, size, compiled.GetPtr(), wxCB_READONLY | wxCB_SORT ); - *this += Label(_("Select a language: (unimplemented)")) | pxMiddle; + *this += Label(_("Select a language:")) | pxMiddle; *this += 5; *this += m_picker | pxSizerFlags::StdSpace(); @@ -144,13 +144,13 @@ void Panels::LanguageSelectionPanel::Apply() wxString sel( m_picker->GetString( m_picker->GetSelection() ) ); - g_Conf->LanguageId = wxLANGUAGE_DEFAULT; // use this if no matches found + g_Conf->LanguageCode = L"default"; // use this if no matches found int size = m_langs.size(); for( int i=0; iLanguageId = m_langs[i].wxLangId; + g_Conf->LanguageCode = m_langs[i].canonicalName; break; } } @@ -158,5 +158,17 @@ void Panels::LanguageSelectionPanel::Apply() void Panels::LanguageSelectionPanel::AppStatusEvent_OnSettingsApplied() { - if( m_picker ) m_picker->SetSelection( g_Conf->LanguageId ); + if (m_picker) + { + if (g_Conf->LanguageCode.IsEmpty()) + g_Conf->LanguageCode = L"default"; + + for (uint i=0; iLanguageCode)) + { + m_picker->SetSelection( i ); + } + } + } } diff --git a/pcsx2/gui/Panels/PathsPanel.cpp b/pcsx2/gui/Panels/PathsPanel.cpp index aa66abb1b5..f7500f1d3d 100644 --- a/pcsx2/gui/Panels/PathsPanel.cpp +++ b/pcsx2/gui/Panels/PathsPanel.cpp @@ -36,7 +36,7 @@ Panels::StandardPathsPanel::StandardPathsPanel( wxWindow* parent ) : *this += (new DirPickerPanel( this, FolderId_Savestates, _("Savestates:"), _("Select folder for Savestates") ))-> - SetToolTip( pxE( ".Tooltip:Folders:Savestates", + SetToolTip( pxEt( "!ContextTip:Folders:Savestates", L"This folder is where PCSX2 records savestates; which are recorded either by using " L"menus/toolbars, or by pressing F1/F3 (load/save)." ) @@ -46,7 +46,7 @@ Panels::StandardPathsPanel::StandardPathsPanel( wxWindow* parent ) : *this += (new DirPickerPanel( this, FolderId_Snapshots, _("Snapshots:"), _("Select a folder for Snapshots") ))-> - SetToolTip( pxE( ".Tooltip:Folders:Snapshots", + SetToolTip( pxEt( "!ContextTip:Folders:Snapshots", L"This folder is where PCSX2 saves screenshots. Actual screenshot image format and style " L"may vary depending on the GS plugin being used." ) @@ -56,7 +56,7 @@ Panels::StandardPathsPanel::StandardPathsPanel( wxWindow* parent ) : *this += (new DirPickerPanel( this, FolderId_Logs, _("Logs/Dumps:" ), _("Select a folder for logs/dumps") ))-> - SetToolTip( pxE( ".Tooltip:Folders:Logs", + SetToolTip( pxEt( "!ContextTip:Folders:Logs", L"This folder is where PCSX2 saves its logfiles and diagnostic dumps. Most plugins will " L"also adhere to this folder, however some older plugins may ignore it." ) @@ -67,7 +67,7 @@ Panels::StandardPathsPanel::StandardPathsPanel( wxWindow* parent ) : *this += (new DirPickerPanel( this, FolderId_MemoryCards, _("Memorycards:"), _("Select a default Memorycards folder") ))-> - SetToolTip( pxE( ".Tooltips:Folders:Memorycards", + SetToolTip( pxE( "!Tooltip:Folders:Memorycards", L"This is the default path where PCSX2 loads or creates its memory cards, and can be " L"overridden in the MemoryCard Configuration by using absolute filenames." ) diff --git a/pcsx2/gui/Panels/PluginSelectorPanel.cpp b/pcsx2/gui/Panels/PluginSelectorPanel.cpp index a4006a874e..87c35fb08b 100644 --- a/pcsx2/gui/Panels/PluginSelectorPanel.cpp +++ b/pcsx2/gui/Panels/PluginSelectorPanel.cpp @@ -239,7 +239,7 @@ void ApplyOverValidStateEvent::InvokeEvent() { wxDialogWithHelpers dialog( m_owner, _("Shutdown PS2 virtual machine?") ); - dialog += dialog.Heading( pxE( ".Popup:PluginSelector:ConfirmShutdown", + dialog += dialog.Heading( pxE( "!Notice:PluginSelector:ConfirmShutdown", L"Warning! Changing plugins requires a complete shutdown and reset of the PS2 virtual machine. " L"PCSX2 will attempt to save and restore the state, but if the newly selected plugins are " L"incompatible the recovery may fail, and current progress will be lost." @@ -453,7 +453,7 @@ void Panels::PluginSelectorPanel::AppStatusEvent_OnSettingsApplied() static wxString GetApplyFailedMsg() { - return wxsFormat( pxE( ".Error:PluginSelector:ApplyFailed", + return wxsFormat( pxE( "!Notice:PluginSelector:ApplyFailed", L"All plugins must have valid selections for %s to run. If you are unable to make " L"a valid selection due to missing plugins or an incomplete install of %s, then " L"press cancel to close the Configuration panel." diff --git a/pcsx2/gui/Panels/SpeedhacksPanel.cpp b/pcsx2/gui/Panels/SpeedhacksPanel.cpp index 648f1ddaaf..58ab05f015 100644 --- a/pcsx2/gui/Panels/SpeedhacksPanel.cpp +++ b/pcsx2/gui/Panels/SpeedhacksPanel.cpp @@ -24,17 +24,17 @@ const wxChar* Panels::SpeedHacksPanel::GetEEcycleSliderMsg( int val ) switch( val ) { case 1: - return pxE( ".Panel:Speedhacks:EECycleX1", + return pxEt( "!Panel:Speedhacks:EECycleX1", L"1 - Default cyclerate. This closely matches the actual speed of a real PS2 EmotionEngine." ); case 2: - return pxE( ".Panel:Speedhacks:EECycleX2", + return pxEt( "!Panel:Speedhacks:EECycleX2", L"2 - Reduces the EE's cyclerate by about 33%. Mild speedup for most games with high compatibility." ); case 3: - return pxE( ".Panel:Speedhacks:EECycleX3", + return pxEt( "!Panel:Speedhacks:EECycleX3", L"3 - Reduces the EE's cyclerate by about 50%. Moderate speedup, but *will* cause stuttering " L"audio on many FMVs." ); @@ -51,23 +51,23 @@ const wxChar* Panels::SpeedHacksPanel::GetVUcycleSliderMsg( int val ) switch( val ) { case 0: - return pxE( ".Panel:Speedhacks:VUCycleStealOff", + return pxEt( "!Panel:Speedhacks:VUCycleStealOff", L"0 - Disables VU Cycle Stealing. Most compatible setting!" ); case 1: - return pxE( ".Panel:Speedhacks:VUCycleSteal1", + return pxEt( "!Panel:Speedhacks:VUCycleSteal1", L"1 - Mild VU Cycle Stealing. Lower compatibility, but some speedup for most games." ); case 2: - return pxE( ".Panel:Speedhacks:VUCycleSteal2", + return pxEt( "!Panel:Speedhacks:VUCycleSteal2", L"2 - Moderate VU Cycle Stealing. Even lower compatibility, but significant speedups in some games." ); case 3: // TODO: Mention specific games that benefit from this setting here. - return pxE( ".Panel:Speedhacks:VUCycleSteal3", + return pxEt( "!Panel:Speedhacks:VUCycleSteal3", L"3 - Maximum VU Cycle Stealing. Usefulness is limited, as this will cause flickering " L"visuals or slowdown in most games." ); @@ -94,7 +94,7 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow* parent ) const wxSizerFlags sliderFlags( wxSizerFlags().Border( wxLEFT | wxRIGHT, 8 ).Expand() ); m_check_Enable = new pxCheckBox( this, _("Enable speedhacks"), - pxE( ".Panel:Speedhacks:Overview", + pxE( "!Panel:Speedhacks:Overview", L"Speedhacks usually improve emulation speed, but can cause glitches, broken audio, and " L"false FPS readings. When having emulation problems, disable this panel first." ) @@ -126,7 +126,7 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow* parent ) m_msg_eecycle->SetForegroundColour( wxColour( L"Red" ) ); m_msg_eecycle->SetHeight(3); - const wxChar* ee_tooltip = pxE( ".Tooltip:Speedhacks:EECycleRate Slider", + const wxChar* ee_tooltip = pxEt( "!ContextTip:Speedhacks:EECycleRate Slider", L"Setting higher values on this slider effectively reduces the clock speed of the EmotionEngine's " L"R5900 core cpu, and typically brings big speedups to games that fail to utilize " L"the full potential of the real PS2 hardware." @@ -147,7 +147,7 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow* parent ) m_msg_vustealer->SetForegroundColour( wxColour( L"Red" ) ); m_msg_vustealer->SetHeight(3); - const wxChar* vu_tooltip = pxE( ".Tooltip:Speedhacks:VUCycleStealing Slider", + const wxChar* vu_tooltip = pxEt( "!ContextTip:Speedhacks:VUCycleStealing Slider", L"This slider controls the amount of cycles the VU unit steals from the EmotionEngine. Higher values increase the number of " L"cycles stolen from the EE for each VU microprogram the game runs." ); @@ -169,17 +169,17 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow* parent ) m_check_vuMinMax = new pxCheckBox( vuHacksPanel, _("mVU Min/Max Hack"), _("Small Speedup; may cause black screens, garbage graphics, SPS, etc... [Not Recommended]") ); - m_check_vuFlagHack->SetToolTip( pxE( ".Tooltip:Speedhacks:vuFlagHack", + m_check_vuFlagHack->SetToolTip( pxEt( "!ContextTip:Speedhacks:vuFlagHack", L"Updates Status Flags only on blocks which will read them, instead of all the time. " L"This is safe most of the time, and Super VU does something similar by default." ) ); - m_check_vuBlockHack->SetToolTip( pxE( ".Tooltip:Speedhacks:vuBlockHack", + m_check_vuBlockHack->SetToolTip( pxEt( "!ContextTip:Speedhacks:vuBlockHack", L"Assumes that very far into future blocks will not need old flag instance data. " L"This should be pretty safe. It is unknown if this breaks any game..." ) ); - m_check_vuMinMax->SetToolTip( pxE( ".Tooltip:Speedhacks:vuMinMax", + m_check_vuMinMax->SetToolTip( pxEt( "!ContextTip:Speedhacks:vuMinMax", L"Uses SSE's Min/Max Floating Point Operations instead of custom logical Min/Max routines. " L"Known to break Gran Turismo 4, Tekken 5." ) ); @@ -199,19 +199,19 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow* parent ) _("Fast disc access, less loading times. [Not Recommended]") ); - m_check_intc->SetToolTip( pxE( ".Tooltip:Speedhacks:INTC", + m_check_intc->SetToolTip( pxEt( "!ContextTip:Speedhacks:INTC", L"This hack works best for games that use the INTC Status register to wait for vsyncs, which includes primarily non-3D " L"RPG titles. Games that do not use this method of vsync will see little or no speedup from this hack." ) ); - m_check_waitloop->SetToolTip( pxE( ".Tooltip:Speedhacks:BIFC0", + m_check_waitloop->SetToolTip( pxEt( "!ContextTip:Speedhacks:BIFC0", L"Primarily targetting the EE idle loop at address 0x81FC0 in the kernel, this hack attempts to " L"detect loops whose bodies are guaranteed to result in the same machine state for every iteration " L"until a scheduled event triggers emulation of another unit. After a single iteration of such loops, " L"we advance to the time of the next event or the end of the processor's timeslice, whichever comes first." ) ); - m_check_fastCDVD->SetToolTip( pxE( ".Tooltip:Speedhacks:fastCDVD", + m_check_fastCDVD->SetToolTip( pxEt( "!ContextTip:Speedhacks:fastCDVD", L"Check HDLoader compatibility lists for known games that have issues with this. (Often marked as needing 'mode 1' or 'slow DVD'" ) ); diff --git a/pcsx2/gui/Panels/VideoPanel.cpp b/pcsx2/gui/Panels/VideoPanel.cpp index 1389a6f136..fc88a634c7 100644 --- a/pcsx2/gui/Panels/VideoPanel.cpp +++ b/pcsx2/gui/Panels/VideoPanel.cpp @@ -34,7 +34,7 @@ Panels::FramelimiterPanel::FramelimiterPanel( wxWindow* parent ) m_check_LimiterDisable = new pxCheckBox( this, _("Disable Framelimiting"), _("Useful for running benchmarks. Toggle this option in-game by pressing F4.") ); - m_check_LimiterDisable->SetToolTip( pxE( ".Tooltip:Framelimiter:Disable", + m_check_LimiterDisable->SetToolTip( pxEt( "!ContextTip:Framelimiter:Disable", L"Note that when Framelimiting is disabled, Turbo and SlowMotion modes will not " L"be available either." ) ); @@ -102,8 +102,8 @@ Panels::FramelimiterPanel::FramelimiterPanel( wxWindow* parent ) *this += 5; - //*this += Heading( pxE( ".Panel:Framelimiter:Heading", - *this += new pxStaticText( this, pxE( ".Panel:Framelimiter:Heading", + //*this += Heading( pxE( "!Panel:Framelimiter:Heading", + *this += new pxStaticText( this, pxE( "!Panel:Framelimiter:Heading", L"The internal framelimiter regulates the speed of the virtual machine. Adjustment values below are in " L"percentages of the default region-based framerate, which can also be configured below." ) ); @@ -168,12 +168,12 @@ Panels::FrameSkipPanel::FrameSkipPanel( wxWindow* parent ) m_check_EnableSkip = new pxCheckBox( this, _("Use Frameskip"), _(".") ); - m_check_EnableSkip->SetToolTip( pxE( ".Tooltip:Frameskip:Disable", + m_check_EnableSkip->SetToolTip( pxEt( "!ContextTip:Frameskip:Disable", L"" L"" ) ); - m_check_EnableSkipOnTurbo->SetToolTip( pxE( ".Tooltip:Frameskip:UseForTurbo", + m_check_EnableSkipOnTurbo->SetToolTip( pxEt( "!ContextTip:Frameskip:UseForTurbo", L"Recommended option! Since frameskipping glitches typically aren't as annoying when you're " L" just trying to speed through stuff." ) );*/ @@ -227,7 +227,7 @@ Panels::FrameSkipPanel::FrameSkipPanel( wxWindow* parent ) *this += s_spins | StdExpand(); - *this += Text( pxE( ".Panel:Frameskip:Heading", + *this += Text( pxE( "!Panel:Frameskip:Heading", L"Notice: Due to PS2 hardware design, precise frame skipping is impossible. " L"Enabling it will cause severe graphical errors in some games." ) ) | StdExpand(); @@ -296,11 +296,11 @@ Panels::VideoPanel::VideoPanel( wxWindow* parent ) : _("Completely disables all GS plugin activity; ideal for benchmarking EEcore components.") ); - m_check_SynchronousGS->SetToolTip( pxE( ".Tooltip:GS:SyncMTGS", + m_check_SynchronousGS->SetToolTip( pxEt( "!ContextTip:GS:SyncMTGS", L"Enable this if you think MTGS thread sync is causing crashes or graphical errors.") ) ; - m_check_DisableOutput->SetToolTip( pxE( ".Tooltip:GS:DisableOutput", + m_check_DisableOutput->SetToolTip( pxEt( "!ContextTip:GS:DisableOutput", L"Removes any benchmark noise caused by the MTGS thread or GPU overhead. This option is best used in conjunction with savestates: " L"save a state at an ideal scene, enable this option, and re-load the savestate.\n\n" L"Warning: This option can be enabled on-the-fly but typically cannot be disabled on-the-fly (video will typically be garbage)." diff --git a/pcsx2/gui/i18n.cpp b/pcsx2/gui/i18n.cpp index dd56f1b8a4..3d2f85e3ac 100644 --- a/pcsx2/gui/i18n.cpp +++ b/pcsx2/gui/i18n.cpp @@ -20,20 +20,29 @@ #include "Utilities/SafeArray.h" LangPackEnumeration::LangPackEnumeration( wxLanguage langId ) - : wxLangId( langId ) - , englishName( wxLocale::GetLanguageName( wxLangId ) ) - , xlatedName( pxIsEnglish( wxLangId ) ? wxEmptyString : wxGetTranslation( L"NativeName" ) ) { + wxLangId = langId; + + if (const wxLanguageInfo* info = wxLocale::GetLanguageInfo( wxLangId )) + { + canonicalName = info->CanonicalName; + englishName = info->Description; + } } LangPackEnumeration::LangPackEnumeration() - : wxLangId( wxLANGUAGE_DEFAULT ) - , englishName( L" System Default" ) // left-side space forces it to sort to the front of the lists - , xlatedName() { - int sysLang( wxLocale::GetSystemLanguage() ); - if( sysLang != wxLANGUAGE_UNKNOWN ) - englishName += L" [" + wxLocale::GetLanguageName( sysLang ) + L"]"; + wxLangId = wxLANGUAGE_DEFAULT; + englishName = L" System Default"; // left-side space forces it to sort to the front of the lists + canonicalName = L"default"; + + int sysLang = wxLocale::GetSystemLanguage(); + + if (sysLang == wxLANGUAGE_UNKNOWN) + sysLang = wxLANGUAGE_ENGLISH; + + if (const wxLanguageInfo* info = wxLocale::GetLanguageInfo( sysLang )) + englishName += L" [" + info->Description + L"]"; } @@ -54,7 +63,7 @@ static void i18n_DoPackageCheck( wxLanguage wxLangId, LangPackList& langs ) // matching logic, which will bypass the catalog loader for all english-based dialects, and // (wrongly) enumerate a bunch of locales that don't actually exist. - if( locale->IsOk() && locale->AddCatalog( L"pcsx2ident", wxLANGUAGE_UNKNOWN, NULL ) ) + if( locale->IsOk() && locale->AddCatalog( L"pcsx2_Main", wxLANGUAGE_UNKNOWN, NULL ) ) langs.push_back( LangPackEnumeration( wxLangId ) ); delete locale; @@ -67,11 +76,11 @@ static void i18n_DoPackageCheck( wxLanguage wxLangId, LangPackList& langs ) // safe way to enumerate the languages is by forcibly loading every possible locale in the wx // database. Anything which hasn't been installed will fail to load. // -// Because loading and hashing the entire pcsx2 translation for every possible language would -// asinine and slow, I've decided to use a two-file translation system. One file (pcsx2ident.mo) -// is very small and simply contains the name of the language in the language native. The -// second file (pcsx2.mo) is loaded only if the user picks the language (or if it's the default -// language of the user's OS installation). +// Because loading and hashing the entire pcsx2 translation for every possible language would be +// asinine and slow, I've decided to use a file dedicated to being a translation detection anchor. +// This file is named pcsx2ident.mo, and contains only the name of the language in the language +// native form. Additional translation files are only loaded if the user picks the language (or +// if it's the default language of the user's OS installation). // void i18n_EnumeratePackages( LangPackList& langs ) { @@ -96,6 +105,21 @@ void i18n_EnumeratePackages( LangPackList& langs ) //i18n_DoPackageCheck( wxLANGUAGE_SAMI, englishNames, xlatedNames ); } +bool i18n_SetLanguage( const wxString& langCode ) +{ + if (langCode.IsEmpty() || langCode.CmpNoCase(L"default")) + { + wxLanguage sysLang = (wxLanguage)wxLocale::GetSystemLanguage(); + + if (sysLang == wxLANGUAGE_UNKNOWN) + sysLang = wxLANGUAGE_ENGLISH; + } + + const wxLanguageInfo* woot = wxLocale::FindLanguageInfo( langCode ); + if (!woot) return false; + return i18n_SetLanguage( woot->Language ); +} + bool i18n_SetLanguage( int wxLangId ) { if( !wxLocale::IsAvailable( wxLangId ) ) @@ -114,12 +138,43 @@ bool i18n_SetLanguage( int wxLangId ) return false; } - if( !pxIsEnglish(wxLangId) && !locale->AddCatalog( L"pcsx2main" ) ) + wxLangId = locale->GetLanguage(); + + if (wxLangId == wxLANGUAGE_UNKNOWN) { - /*Console.Warning( L"SetLanguage: Cannot find pcsx2main.mo file for language '%s' [%s]", - wxLocale::GetLanguageName( locale->GetLanguage() ).c_str(), locale->GetCanonicalName().c_str() - );*/ - Console.Warning("SetLanguage is not implemented yet, using English."); + Console.WriteLn("System-default language is unknown? Defaulting back to English/US."); + wxLangId = wxLANGUAGE_ENGLISH; + return true; + } + + // English/US is built in, so no need to load MO/PO files. + if( pxIsEnglish(wxLangId) ) return true; + + Console.WriteLn( Color_StrongBlack, L"Loading language translation databases for '%s' [%s]", + wxLocale::GetLanguageName( locale->GetLanguage() ).c_str(), locale->GetCanonicalName().c_str() + ); + + static const wxChar* dictFiles[] = + { + L"pcsx2_Main", + L"pcsx2_Notices", + L"pcsx2_ContextTips" + }; + + bool foundone = false; + for (uint i=0; iAddCatalog(dictFiles[i])) + Console.Indent().WriteLn(Color_StrongYellow, "%s not found -- translation dictionary may be incomplete.", dictFiles[i]); + else + foundone = true; + } + + if (!foundone) + { + Console.Warning("SetLanguage: Requested translation is not implemented yet, using English."); return false; } diff --git a/pcsx2/gui/i18n.h b/pcsx2/gui/i18n.h index d60ef53454..1f293a288a 100644 --- a/pcsx2/gui/i18n.h +++ b/pcsx2/gui/i18n.h @@ -22,8 +22,11 @@ class LangPackEnumeration { public: wxLanguage wxLangId; + wxString canonicalName; wxString englishName; - wxString xlatedName; + + // [TODO] : Might be nice, but have no idea how to implement it... + //wxString xlatedName; public: LangPackEnumeration( wxLanguage langId ); @@ -32,6 +35,7 @@ public: typedef std::vector LangPackList; +extern bool i18n_SetLanguage( const wxString& langCode ); extern bool i18n_SetLanguage( int wxLangId ); extern void i18n_EnumeratePackages( LangPackList& langs ); diff --git a/pcsx2/vtlb.cpp b/pcsx2/vtlb.cpp index a7d9c35b85..5130ab1b8e 100644 --- a/pcsx2/vtlb.cpp +++ b/pcsx2/vtlb.cpp @@ -585,7 +585,7 @@ void vtlb_Core_Free() static wxString GetHostVmErrorMsg() { - return pxE(".Error:HostVmReserve", + return pxE("!Notice:HostVmReserve", L"Your system is too low on virtual resources for PCSX2 to run. This can be " L"caused by having a small or disabled swapfile, or by other programs that are " L"hogging resources." diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj index c2011ce0c3..f2d5a73314 100644 --- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj +++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj @@ -1996,14 +1996,6 @@ RelativePath="..\..\gui\Dialogs\AboutBoxDialog.cpp" > - - - - diff --git a/pcsx2/x86/sVU_zerorec.cpp b/pcsx2/x86/sVU_zerorec.cpp index ff0b03f4ff..576f6890f4 100644 --- a/pcsx2/x86/sVU_zerorec.cpp +++ b/pcsx2/x86/sVU_zerorec.cpp @@ -359,7 +359,7 @@ static void SuperVUAlloc(int vuindex) safe_delete(s_recVUMem[vuindex]); throw Exception::VirtualMemoryMapConflict( s_recVUMem[vuindex]->GetName() ) .SetDiagMsg(pxsFmt( L"SuperVU failed to allocate virtual memory below 256MB." )) - .SetUserMsg(pxE( ".Error:superVU:VirtualMemoryAlloc", + .SetUserMsg(pxE( "!Notice:superVU:VirtualMemoryAlloc", L"Out of Memory (sorta): The SuperVU recompiler was unable to reserve the specific memory " L"ranges required, and will not be available for use. This is not a critical error, since " L"the sVU rec is obsolete, and you should use microVU instead anyway. :)"