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
This commit is contained in:
Jake.Stine 2010-12-02 08:15:11 +00:00
parent 8d974015d5
commit 9bcff9f3d5
42 changed files with 583 additions and 229 deletions

View File

@ -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"

View File

@ -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."
)

View File

@ -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

View File

@ -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.")
)

View File

@ -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."
);

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include "PrecompiledHeader.h"

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#ifndef ADVANCEDDIALOG_H_INCLUDED
#define ADVANCEDDIALOG_H_INCLUDED
#endif // ADVANCEDDIALOG_H_INCLUDED

View File

@ -359,6 +359,10 @@ class Pcsx2AppTraits : public wxGUIAppTraits
public:
virtual ~Pcsx2AppTraits() {}
wxMessageOutput* CreateMessageOutput();
#ifdef wxUSE_STDPATHS
wxStandardPathsBase& GetStandardPaths();
#endif
};
// =====================================================================================================

View File

@ -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 );

View File

@ -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.

View File

@ -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." )
);

View File

@ -29,6 +29,8 @@
#include "Utilities/IniInterface.h"
#include <wx/stdpaths.h>
#ifdef __WXMSW__
# include <wx/msw/wrapwin.h> // 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 ) )
{

View File

@ -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."
)
);

View File

@ -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."

View File

@ -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();
}

View File

@ -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)"

View File

@ -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)."
)

View File

@ -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."
),

View File

@ -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."

View File

@ -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()

View File

@ -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",

View File

@ -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?"
);

View File

@ -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]);

View File

@ -50,7 +50,7 @@ void MainEmuFrame::Menu_McdSettings_Click(wxCommandEvent &event)
void MainEmuFrame::Menu_GameDatabase_Click(wxCommandEvent &event)
{
AppOpenDialog<McdConfigDialog>( this );
AppOpenDialog<GameDatabaseDialog>( 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?"

View File

@ -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

View File

@ -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."
) );

View File

@ -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. " )
);

View File

@ -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."
) );

View File

@ -18,11 +18,301 @@
#include "AppGameDatabase.h"
#include "ConfigurationPanels.h"
#include <wx/listctrl.h>
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; i<GdbCol_Count; ++i )
{
const ListViewColumnInfo& info = GetDefaultColumnInfo(i);
InsertColumn( i, pxGetTranslation(info.name), info.align, info.width );
}
}
GameDatabaseListView& GameDatabaseListView::AddGame( const wxString& serial )
{
if (m_GamesInView.Index( serial, false ) != wxNOT_FOUND) return *this;
m_GamesInView.Add( serial );
return *this;
}
GameDatabaseListView& GameDatabaseListView::RemoveGame( const wxString& serial )
{
m_GamesInView.Remove( serial );
return *this;
}
GameDatabaseListView& GameDatabaseListView::ClearAllGames()
{
m_GamesInView.Clear();
return *this;
}
class BaseGameListSort
{
protected:
IGameDatabase* m_GameDB;
bool m_descending;
public:
BaseGameListSort( bool descend )
{
m_GameDB = AppHost_GetGameDatabase();
m_descending = descend;
}
virtual ~BaseGameListSort() throw() {}
// Note: Return TRUE if the first value is less than the second value.
bool operator()(const wxString& i1, const wxString& i2)
{
if (!m_GameDB || (i1 == i2)) return false;
// note: Anything not in the database gets sorted to the bottom of the list ...
Game_Data first, second;
if (!m_GameDB->findGame(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);

View File

@ -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."

View File

@ -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

View File

@ -20,6 +20,13 @@
#include <wx/dnd.h>
#include <wx/listctrl.h>
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
// --------------------------------------------------------------------------------------

View File

@ -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; i<size; ++i )
{
if( m_langs[i].englishName == sel )
{
g_Conf->LanguageId = 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; i<m_langs.size(); ++i)
{
if (0==m_langs[i].canonicalName.CmpNoCase(g_Conf->LanguageCode))
{
m_picker->SetSelection( i );
}
}
}
}

View File

@ -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."
)

View File

@ -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."

View File

@ -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'"
) );

View File

@ -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)."

View File

@ -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; i<ArraySize(dictFiles); ++i)
{
if (!dictFiles[i]) continue;
if (!locale->AddCatalog(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;
}

View File

@ -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<LangPackEnumeration> LangPackList;
extern bool i18n_SetLanguage( const wxString& langCode );
extern bool i18n_SetLanguage( int wxLangId );
extern void i18n_EnumeratePackages( LangPackList& langs );

View File

@ -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."

View File

@ -1996,14 +1996,6 @@
RelativePath="..\..\gui\Dialogs\AboutBoxDialog.cpp"
>
</File>
<File
RelativePath="..\..\gui\AdvancedDialog.cpp"
>
</File>
<File
RelativePath="..\..\gui\AdvancedDialog.h"
>
</File>
<File
RelativePath="..\..\gui\Dialogs\AssertionDialog.cpp"
>

View File

@ -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. :)"