wxSavestates branch: (partially sync'd with trunk**)

* Finished up zipfile-style savestate implementation
 * Simplified BaseSaveState class, and removed lots of now-unneeded code.
 * Prepared the i18n stuff for a pcsx2_Dev.pot file (WIP), and sorted more stuff to pcsx2_Tertiary.pot.

git-svn-id: http://pcsx2.googlecode.com/svn/branches/wxSavestates@4091 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2010-12-14 07:28:05 +00:00
commit daf47b50a0
201 changed files with 9252 additions and 7551 deletions

View File

@ -39,7 +39,7 @@ set(SoundTouchSources
RateTransposer.cpp
SoundTouch.cpp
TDStretch.cpp
WavFile.cpp
# WavFile.cpp # directly include in spu2x
cpu_detect_x86_gcc.cpp
mmx_optimized.cpp
sse_optimized.cpp)
@ -55,7 +55,7 @@ set(SoundTouchHeaders
STTypes.h
SoundTouch.h
TDStretch.h
WavFile.h
# WavFile.h # directly include in spu2x
cpu_detect.h)
# add library

View File

@ -23,9 +23,6 @@ if(Linux)
endif(GTK2_FOUND)
find_package(X11)
# Manually find Xxf86vm because it is not done in the module...
FIND_LIBRARY(X11_Xxf86vm_LIB Xxf86vm ${X11_LIB_SEARCH_PATH})
MARK_AS_ADVANCED(X11_Xxf86vm_LIB)
endif(Linux)
## Use cmake package to find module

View File

@ -445,6 +445,10 @@
RelativePath="..\..\include\Utilities\pxEvents.h"
>
</File>
<File
RelativePath="..\..\include\Utilities\pxForwardDefs.h"
>
</File>
<File
RelativePath="..\..\include\Utilities\pxRadioPanel.h"
>

View File

@ -278,7 +278,9 @@ void CALLBACK GSsetFrameSkip(int frameskip);
int CALLBACK GSsetupRecording(int start, void* pData);
void CALLBACK GSreset();
void CALLBACK GSgetTitleInfo( char dest[128] );
//deprecated: GSgetTitleInfo was used in PCSX2 but no plugin supported it prior to r4070:
//void CALLBACK GSgetTitleInfo( char dest[128] );
void CALLBACK GSgetTitleInfo2( char* dest, size_t length );
void CALLBACK GSwriteCSR(u32 value);
s32 CALLBACK GSfreeze(int mode, freezeData *data);
void CALLBACK GSconfigure();
@ -575,7 +577,7 @@ typedef void (CALLBACK* _GSreadFIFO)(u64 *pMem);
typedef void (CALLBACK* _GSreadFIFO2)(u64 *pMem, int qwc);
typedef void (CALLBACK* _GSchangeSaveState)(int, const char* filename);
typedef void (CALLBACK* _GSgetTitleInfo)(char dest[128]);
typedef void (CALLBACK* _GSgetTitleInfo2)(char* dest, size_t length);
typedef void (CALLBACK* _GSirqCallback)(void (*callback)());
typedef void (CALLBACK* _GSprintf)(int timeout, char *fmt, ...);
typedef void (CALLBACK* _GSsetBaseMem)(void*);
@ -729,7 +731,7 @@ extern _GSreadFIFO GSreadFIFO;
extern _GSreadFIFO2 GSreadFIFO2;
extern _GSchangeSaveState GSchangeSaveState;
extern _GSgetTitleInfo GSgetTitleInfo;
extern _GSgetTitleInfo2 GSgetTitleInfo2;
extern _GSmakeSnapshot GSmakeSnapshot;
extern _GSmakeSnapshot2 GSmakeSnapshot2;
extern _GSirqCallback GSirqCallback;

View File

@ -18,37 +18,7 @@
// Dependencies.h : Contains classes required by all Utilities headers.
// This file is included by most .h files provided by the Utilities class.
// --------------------------------------------------------------------------------------
// Forward Declarations Section
// --------------------------------------------------------------------------------------
class wxOutputStream;
class wxFileOutputStream;
class wxFFileOutputStream;
class wxStreamBase;
class wxInputStream;
class wxFileInputStream;
class wxFFileInputStream;
class wxPoint;
class wxRect;
class wxSize;
extern const wxSize wxDefaultSize;
extern const wxPoint wxDefaultPosition;
namespace Threading
{
class Mutex;
class Semaphore;
class pxThread;
}
namespace Exception
{
class BaseException;
}
#include "pxForwardDefs.h"
// This should prove useful....
#define wxsFormat wxString::Format
@ -165,6 +135,50 @@ public:
}
};
// --------------------------------------------------------------------------------------
// _(x) / _t(x) / _d(x) / pxL(x) / pxLt(x) [macros]
// --------------------------------------------------------------------------------------
// Define pxWex's own i18n helpers. These override the wxWidgets helpers and provide
// additional functionality. Define them FIRST THING, to make sure that wx's own gettext
// macros aren't in place.
//
// _ is for standard translations
// _t is for tertiary low priority translations
// _d is for debug/devel build translations
#define WXINTL_NO_GETTEXT_MACRO
#ifndef _
# define _(s) pxGetTranslation(_T(s))
#endif
#ifndef _t
# define _t(s) pxGetTranslation(_T(s))
#endif
#ifndef _d
# define _d(s) pxGetTranslation(_T(s))
#endif
// pxL / pxLt / pxDt -- macros provided for tagging translation strings, without actually running
// them through the translator (which the _() does automatically, and sometimes we don't
// want that). This is a shorthand replacement for wxTRANSLATE. pxL is a standard translation
// moniker. pxLt is for tertiary strings that have a very low translation priority. pxDt is for
// debug/devel specific translations.
//
#ifndef pxL
# define pxL(a) wxT(a)
#endif
#ifndef pxLt
# define pxLt(a) wxT(a)
#endif
#ifndef pxDt
# define pxDt(a) wxT(a)
#endif
#include <wx/string.h>
#include <wx/intl.h>
#include <wx/log.h>
@ -178,6 +192,9 @@ public:
#include "Pcsx2Defs.h"
// --------------------------------------------------------------------------------------
// Handy Human-readable constants for common immediate values (_16kb -> _4gb)
static const sptr _64kb = 0x10000;
static const sptr _16kb = _64kb / 4;
static const sptr _128kb = _64kb * 2;
@ -193,30 +210,8 @@ static const s64 _1gb = _256mb * 4;
static const s64 _4gb = _1gb * 4;
// ===========================================================================================
// i18n/Translation Feature Set!
// ===========================================================================================
extern const wxChar* __fastcall pxExpandMsg( const wxChar* key, const wxChar* englishContent );
extern const wxChar* __fastcall pxGetTranslation( const wxChar* message );
extern bool pxIsEnglish( int id );
extern wxString fromUTF8( const char* src );
extern wxString fromAscii( const char* src );
// --------------------------------------------------------------------------------------
// wxLt(x) [macro]
// --------------------------------------------------------------------------------------
// macro provided for tagging translation strings, without actually running them through the
// translator (which the _() does automatically, and sometimes we don't want that). This is
// a shorthand replacement for wxTRANSLATE.
//
#ifndef wxLt
# define wxLt(a) wxT(a)
#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
@ -226,28 +221,42 @@ 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 )
// For use with Dev/debug build translations (low priority).
#define pxE_dev(key, english) pxExpandMsg( wxT(key), english )
extern const wxChar* __fastcall pxExpandMsg( const wxChar* key, const wxChar* englishContent );
extern const wxChar* __fastcall pxGetTranslation( const wxChar* message );
extern bool pxIsEnglish( int id );
extern wxString fromUTF8( const char* src );
extern wxString fromAscii( const char* src );
#include "Utilities/Assertions.h"
#include "Utilities/Exceptions.h"

View File

@ -184,7 +184,7 @@ public: \
// an App message loop we'll still want it to be handled in a reasonably graceful manner.
class CancelEvent : public RuntimeError
{
DEFINE_RUNTIME_EXCEPTION( CancelEvent, RuntimeError, wxLt("No reason given.") )
DEFINE_RUNTIME_EXCEPTION( CancelEvent, RuntimeError, pxLt("No reason given.") )
public:
explicit CancelEvent( const wxString& logmsg )
@ -223,7 +223,7 @@ public: \
class ParseError : public RuntimeError
{
DEFINE_RUNTIME_EXCEPTION( ParseError, RuntimeError, wxLt("Parse error") );
DEFINE_RUNTIME_EXCEPTION( ParseError, RuntimeError, pxL("Parse error") );
};
// ---------------------------------------------------------------------------------------
@ -247,7 +247,7 @@ public: \
class HardwareDeficiency : public RuntimeError
{
public:
DEFINE_RUNTIME_EXCEPTION( HardwareDeficiency, RuntimeError, wxLt("Your machine's hardware is incapable of running PCSX2. Sorry dood.") );
DEFINE_RUNTIME_EXCEPTION( HardwareDeficiency, RuntimeError, pxL("Your machine's hardware is incapable of running PCSX2. Sorry dood.") );
};
// ---------------------------------------------------------------------------------------

View File

@ -251,5 +251,6 @@ namespace HostSys
extern void InitCPUTicks();
extern u64 GetTickFrequency();
extern u64 GetCPUTicks();
extern u64 GetPhysicalMemory();
extern wxString GetOSVersionString();

View File

@ -195,16 +195,16 @@ public:
this->m_buffer = (T*)malloc( this->m_size * sizeof(T) );
if (!this->m_buffer)
throw Exception::OutOfMemory("ScopedAlloc");
throw Exception::OutOfMemory(L"ScopedAlloc");
}
virtual void Resize( size_t newsize )
{
this->m_size = newsize;
this->m_buffer = (T*)realloc(this->m_buffer * sizeof(T), newsize);
this->m_buffer = (T*)realloc(this->m_buffer, this->m_size * sizeof(T));
if (!this->m_buffer)
throw Exception::OutOfMemory("ScopedAlloc::Resize");
throw Exception::OutOfMemory(L"ScopedAlloc::Resize");
}
};

View File

@ -233,7 +233,8 @@ protected:
m_Close :1;
BITFIELD_END
wxString m_CustomLabel;
wxString m_CustomLabel;
wxString m_CustomLabelId;
public:
MsgButtons() { bitset = 0; }
@ -251,9 +252,12 @@ public:
MsgButtons& Reset() { m_Reset = true; return *this; }
MsgButtons& Close() { m_Close = true; return *this; }
MsgButtons& Custom( const wxString& label)
// label - native language label displayed to user
// id - raw ASCII identifier used in the config file (do not translate, hence char*)
MsgButtons& Custom( const wxString& label, const char* id )
{
m_CustomLabel = label;
m_CustomLabelId = fromUTF8(id);
return *this;
}
@ -274,7 +278,8 @@ public:
bool HasClose() const { return m_Close; }
bool HasCustom() const { return !m_CustomLabel.IsEmpty(); }
const wxString& GetCustomLabel() const { return m_CustomLabel; }
const wxString& GetCustomLabel() const { return m_CustomLabel; }
const wxString& GetCustomLabelId() const { return m_CustomLabelId; }
bool Allows( wxWindowID id ) const;
void SetBestFocus( wxWindow* dialog ) const;

View File

@ -15,6 +15,8 @@
#pragma once
#include "wx/filefn.h"
// --------------------------------------------------------------------------------------
// pxStreamBase
// --------------------------------------------------------------------------------------
@ -36,7 +38,10 @@ public:
// or wxOputStream derivative).
virtual wxStreamBase* GetWxStreamBase() const=0;
virtual void Close()=0;
virtual wxFileOffset Tell() const=0;
virtual wxFileOffset Seek( wxFileOffset ofs, wxSeekMode mode = wxFromStart )=0;
virtual wxFileOffset Length() const;
bool IsOk() const;
wxString GetStreamName() const { return m_filename; }
};
@ -71,6 +76,9 @@ public:
{
Write( &data, sizeof(data) );
}
wxFileOffset Tell() const;
wxFileOffset Seek( wxFileOffset ofs, wxSeekMode mode = wxFromStart );
};
// --------------------------------------------------------------------------------------
@ -102,4 +110,7 @@ public:
{
Read( &dest, sizeof(dest) );
}
wxFileOffset Tell() const;
wxFileOffset Seek( wxFileOffset ofs, wxSeekMode mode = wxFromStart );
};

View File

@ -522,6 +522,7 @@ public:
// --------------------------------------------------------------------------------------
class wxDialogWithHelpers : public wxDialog
{
typedef wxDialog _parent;
DECLARE_DYNAMIC_CLASS_NO_COPY(wxDialogWithHelpers)
protected:
@ -541,6 +542,7 @@ public:
virtual void SmartCenterFit();
virtual int ShowModal();
virtual bool Show( bool show=true );
virtual bool Destroy();
// Must return the same thing as GetNameStatic; a name ideal for use in uniquely
// identifying dialogs. (this version is the 'instance' version, which is called

View File

@ -31,8 +31,6 @@ class x86capabilities
{
public:
bool isIdentified;
u32 LogicalCoresPerPhysicalCPU;
u32 PhysicalCoresPerPhysicalCPU;
public:
x86VendorType VendorID;
@ -106,8 +104,6 @@ public:
{
isIdentified = false;
VendorID = x86Vendor_Unknown;
LogicalCoresPerPhysicalCPU = 1;
PhysicalCoresPerPhysicalCPU = 1;
}
void Identify();

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

@ -167,9 +167,9 @@ void HostSys::MmapResetPtr(void* base, size_t size)
// pretty well stops all PCSX2 threads anyway).
Munmap(base, size);
void* result = Mmap((uptr)base, size);
void* result = MmapReservePtr(base, size);
pxAssertRel ((uptr)result != (uptr)base, pxsFmt(
pxAssertRel ((uptr)result == (uptr)base, pxsFmt(
"Virtual memory decommit failed: memory at 0x%08X -> 0x%08X could not be remapped. "
"This is likely caused by multi-thread memory contention.", base, (uptr)base+size
));

View File

@ -20,11 +20,18 @@
#include <sys/time.h>
#include <wx/utils.h>
extern "C" __aligned16 u8 _xmm_backup[16*2];
extern "C" __aligned16 u8 _mmx_backup[8*4];
// Returns 0 on failure (not supported by the operating system).
u64 GetPhysicalMemory()
{
u64 pages = 0;
#ifdef _SC_PHYS_PAGES
pages = sysconf(_SC_PHYS_PAGES);
#endif
return pages * getpagesize();
}
u8 _xmm_backup[16*2];
u8 _mmx_backup[8*4];
void InitCPUTicks()
{

View File

@ -38,7 +38,7 @@ ConsoleLogSource_Threading::ConsoleLogSource_Threading()
static const TraceLogDescriptor myDesc =
{
L"pxThread", L"pxThread",
wxLt("Threading activity: start, detach, sync, deletion, etc.")
pxLt("Threading activity: start, detach, sync, deletion, etc.")
};
m_Descriptor = &myDesc;

View File

@ -19,6 +19,7 @@
#include <winnt.h>
int SysPageFaultExceptionFilter( EXCEPTION_POINTERS* eps )
{
if( eps->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION )

View File

@ -39,6 +39,14 @@ u64 GetCPUTicks()
return count.QuadPart;
}
u64 GetPhysicalMemory()
{
MEMORYSTATUSEX status;
status.dwLength = sizeof(status);
GlobalMemoryStatusEx(&status);
return status.ullTotalPhys;
}
// Windows SDK 7 provides this but previous ones do not, so roll our own in those cases:
#ifndef VER_SUITE_WH_SERVER
# define VER_SUITE_WH_SERVER 0x00008000

View File

@ -35,6 +35,12 @@ bool pxStreamBase::IsOk() const
return woot && woot->IsOk();
}
wxFileOffset pxStreamBase::Length() const
{
if (!GetWxStreamBase()) return 0;
return GetWxStreamBase()->GetLength();
}
// --------------------------------------------------------------------------------------
// pxInputStream (implementations)
// --------------------------------------------------------------------------------------
@ -55,6 +61,16 @@ pxInputStream::pxInputStream(const wxString& filename, wxInputStream* input)
wxStreamBase* pxInputStream::GetWxStreamBase() const { return m_stream_in.GetPtr(); }
wxFileOffset pxInputStream::Tell() const
{
return m_stream_in->TellI();
}
wxFileOffset pxInputStream::Seek( wxFileOffset ofs, wxSeekMode mode )
{
return m_stream_in->SeekI(ofs, mode);
}
void pxInputStream::SetStream( const wxString& filename, ScopedPtr<wxInputStream>& stream )
{
m_filename = filename;
@ -107,6 +123,15 @@ pxOutputStream::pxOutputStream(const wxString& filename, wxOutputStream* output)
wxStreamBase* pxOutputStream::GetWxStreamBase() const { return m_stream_out.GetPtr(); }
wxFileOffset pxOutputStream::Tell() const
{
return m_stream_out->TellO();
}
wxFileOffset pxOutputStream::Seek( wxFileOffset ofs, wxSeekMode mode )
{
return m_stream_out->SeekO( ofs, mode );
}
void pxOutputStream::SetStream( const wxString& filename, ScopedPtr<wxOutputStream>& stream )
{

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

@ -33,7 +33,7 @@ ConsoleLogSource_App::ConsoleLogSource_App()
static const TraceLogDescriptor myDesc =
{
L"AppEvents", L"App Events",
wxLt("Includes idle event processing and some other uncommon event usages.")
pxLt("Includes idle event processing and some other uncommon event usages.")
};
m_Descriptor = &myDesc;

View File

@ -274,13 +274,13 @@ pxStaticText& wxDialogWithHelpers::Heading( const wxString& label )
return *new pxStaticHeading( this, label );
}
void wxDialogWithHelpers::OnCloseWindow( wxCloseEvent& evt )
bool wxDialogWithHelpers::Destroy()
{
// Save the dialog position if the dialog is named...
// FIXME : This doesn't get called if the app is exited by alt-f4'ing the main app window.
// ... not sure how to fix that yet. I could register a list of open windows into wxAppWithHelpers
// that systematically get closed. Seems like work, maybe later. --air
if( wxConfigBase* cfg = IsIconized() ? NULL : wxConfigBase::Get( false ) )
{
const wxString dlgName( GetDialogName() );
@ -300,6 +300,11 @@ void wxDialogWithHelpers::OnCloseWindow( wxCloseEvent& evt )
}
}
return _parent::Destroy();
}
void wxDialogWithHelpers::OnCloseWindow( wxCloseEvent& evt )
{
if( !IsModal() ) Destroy();
evt.Skip();
}

View File

@ -183,11 +183,11 @@ __fi void memcpy_vibes(void * dest, const void * src, int size) {
__asm__ __volatile__
(
".intel_syntax noprefix\n"
"mov eax, %[qwc]\n" // keep a copy of count for looping
"shr eax, 1\n"
"jz memcpy_qwc_1_%=\n" // only one 16 byte block to copy?
"sub %[qwc], 1\n" // dec the counter to ease the count of 16bytes block later (optimization)
// Note after this line, real value of the counter is %[qwc] + 1
"jle memcpy_qwc_1_%=\n" // only one 16 byte block to copy? Or nothing.
"cmp eax, 64\n" // "IN_CACHE_COPY/32"
"cmp %[qwc], 127\n" // "IN_CACHE_COPY/16"
"jb memcpy_qwc_loop1_%=\n" // small copies should be cached (definite speedup --air)
"memcpy_qwc_loop2_%=:\n" // 32-byte blocks, uncached copy
@ -204,8 +204,8 @@ __fi void memcpy_vibes(void * dest, const void * src, int size) {
"add %[src],32\n" // update source pointer
"add %[dest],32\n" // update destination pointer
"sub eax,1\n"
"jnz memcpy_qwc_loop2_%=\n" // last 64-byte block?
"sub %[qwc],2\n"
"jg memcpy_qwc_loop2_%=\n" // last 64-byte block?
"sfence\n" // flush the write buffer
"jmp memcpy_qwc_1_%=\n"
@ -227,12 +227,12 @@ __fi void memcpy_vibes(void * dest, const void * src, int size) {
"add %[src],32\n" // update source pointer
"add %[dest],32\n" // update destination pointer
"sub eax,1\n"
"jnz memcpy_qwc_loop1_%=\n" // last 64-byte block?
"sub %[qwc],2\n"
"jg memcpy_qwc_loop2_%=\n" // last 64-byte block?
"memcpy_qwc_1_%=:\n"
"test %[qwc],1\n"
"jz memcpy_qwc_final_%=\n"
"cmp %[qwc],0\n"
"jne memcpy_qwc_final_%=\n"
"movq mm0,[%[src]]\n"
"movq mm1,[%[src]+8]\n"
"movq [%[dest]], mm0\n"
@ -243,7 +243,7 @@ __fi void memcpy_vibes(void * dest, const void * src, int size) {
".att_syntax\n"
: "=&r"(dest), "=&r"(src), "=&r"(qwc)
: [dest]"0"(dest), [src]"1"(src), [qwc]"2"(qwc)
: "memory", "eax", "mm0", "mm1", "mm2", "mm3"
: "memory", "mm0", "mm1", "mm2", "mm3"
);
}
#endif

View File

@ -16,24 +16,16 @@
#include "PrecompiledHeader.h"
#include "cpudetect_internal.h"
#include <wx/thread.h>
// Note: Apparently this solution is Linux/Solaris only.
// FreeBSD/OsX need something far more complicated (apparently)
void x86capabilities::CountLogicalCores()
{
const uint numCPU = sysconf( _SC_NPROCESSORS_ONLN );
if( numCPU > 0 )
{
//isMultiCore = numCPU > 1;
LogicalCores = numCPU;
PhysicalCores = ( numCPU / LogicalCoresPerPhysicalCPU ) * PhysicalCoresPerPhysicalCPU;
}
else
{
// Indeterminate?
LogicalCores = 1;
PhysicalCores = 1;
}
// Note : GetCPUCount uses sysconf( _SC_NPROCESSORS_ONLN ) internally, which can return 1
// if sysconf info isn't available (a long standing linux bug). There are no fallbacks or
// alternatives, apparently.
LogicalCores = wxThread::GetCPUCount();
}
bool CanEmitShit()

View File

@ -37,10 +37,6 @@ void x86capabilities::CountLogicalCores()
}
LogicalCores = CPUs;
if( LogicalCoresPerPhysicalCPU > CPUs) // for 1-socket HTT-disabled machines
LogicalCoresPerPhysicalCPU = CPUs;
PhysicalCores = ( CPUs / LogicalCoresPerPhysicalCPU ) * PhysicalCoresPerPhysicalCPU;
}
bool _test_instruction( void* pfnCall )

View File

@ -133,23 +133,6 @@ void x86capabilities::CountCores()
s32 regs[ 4 ];
u32 cmds;
LogicalCoresPerPhysicalCPU = 0;
PhysicalCoresPerPhysicalCPU = 1;
// detect multicore for Intel cpu
__cpuid( regs, 0 );
cmds = regs[ 0 ];
if( cmds >= 0x00000001 )
LogicalCoresPerPhysicalCPU = ( regs[1] >> 16 ) & 0xff;
if ((cmds >= 0x00000004) && (VendorID == x86Vendor_Intel))
{
__cpuid( regs, 0x00000004 );
PhysicalCoresPerPhysicalCPU += ( regs[0] >> 26) & 0x3f;
}
__cpuid( regs, 0x80000000 );
cmds = regs[ 0 ];
@ -157,9 +140,6 @@ void x86capabilities::CountCores()
if ((cmds >= 0x80000008) && (VendorID == x86Vendor_AMD) )
{
__cpuid( regs, 0x80000008 );
PhysicalCoresPerPhysicalCPU += ( regs[2] ) & 0xff;
// AMD note: they don't support hyperthreading, but they like to flag this true
// anyway. Let's force-unflag it until we come up with a better solution.
// (note: seems to affect some Phenom II's only? -- Athlon X2's and PhenomI's do
@ -167,9 +147,6 @@ void x86capabilities::CountCores()
hasMultiThreading = 0;
}
if( !hasMultiThreading || LogicalCoresPerPhysicalCPU == 0 )
LogicalCoresPerPhysicalCPU = 1;
// This will assign values into LogicalCores and PhysicalCores
CountLogicalCores();
}

View File

@ -122,9 +122,6 @@ find $NEW_DIR -name "configure.ac" -exec rm -f {} \;
find $NEW_DIR -name "Makefile.am" -exec rm -f {} \;
echo "Remove 3rd party directories"
find $NEW_DIR -name "3rdparty" -exec rm -fr {} \; 2> /dev/null
# I really need to clean this mess one day
# echo "Remove plugins/zzogl-pg/opengl/ZeroGSShaders (some zlib source in the middle)"
# rm -fr $NEW_DIR/plugins/zzogl-pg/opengl/ZeroGSShaders
echo "Remove windows file (useless & copyright issue)"
find $NEW_DIR -iname "windows" -type d -exec rm -fr {} \; 2> /dev/null
find $NEW_DIR -name "Win32" -type d -exec rm -fr {} \; 2> /dev/null
@ -134,7 +131,6 @@ rm -fr "${NEW_DIR}/common/vsprops"
echo "Remove useless files (copyright issues)"
rm -fr "${NEW_DIR}/plugins/zzogl-pg/opengl/ZeroGSShaders"
rm -fr "${NEW_DIR}/common/src/Utilities/x86/MemcpyFast.cpp"
rm -fr "${NEW_DIR}/plugins/zzogl-pg/opengl/memcpy_amd.cpp"
## BUILD
echo "Build the tar.gz file"

View File

@ -1,176 +0,0 @@
This patch removes recording feature beacause it needs libsoundtouch > 1.4.
Howerever only the version 1.3 is in debian. Unfortunately the package seems
to be not actively maintained.
Note it also correct the inlude path.
Index: pcsx2.snapshot-3369/plugins/spu2-x/src/Wavedump_wav.cpp
===================================================================
--- pcsx2.snapshot-3369.orig/plugins/spu2-x/src/Wavedump_wav.cpp
+++ pcsx2.snapshot-3369/plugins/spu2-x/src/Wavedump_wav.cpp
@@ -16,16 +16,22 @@
*/
#include "Global.h"
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
#include "soundtouch/WavFile.h"
+#endif
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
static WavOutFile* _new_WavOutFile( const char* destfile )
{
return new WavOutFile( destfile, 48000, 16, 2 );
}
+#endif
namespace WaveDump
{
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
static WavOutFile* m_CoreWav[2][CoreSrc_Count] = { NULL };
+#endif
static const char* m_tbl_CoreOutputTypeNames[CoreSrc_Count] =
{
@@ -42,6 +48,7 @@
if( !IsDevBuild ) return;
if( !WaveLog() ) return;
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
char wavfilename[256];
for( uint cidx=0; cidx<2; cidx++ )
@@ -68,11 +75,13 @@
}
}
}
+#endif
}
void Close()
{
if( !IsDevBuild ) return;
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
for( uint cidx=0; cidx<2; cidx++ )
{
for( int srcidx=0; srcidx<CoreSrc_Count; srcidx++ )
@@ -80,13 +89,16 @@
safe_delete( m_CoreWav[cidx][srcidx] );
}
}
+#endif
}
void WriteCore( uint coreidx, CoreSourceType src, const StereoOut16& sample )
{
if( !IsDevBuild ) return;
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
if( m_CoreWav[coreidx][src] != NULL )
m_CoreWav[coreidx][src]->write( (s16*)&sample, 2 );
+#endif
}
void WriteCore( uint coreidx, CoreSourceType src, s16 left, s16 right )
@@ -101,11 +113,14 @@
bool WavRecordEnabled = false;
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
static WavOutFile* m_wavrecord = NULL;
+#endif
static Mutex WavRecordMutex;
void RecordStart()
{
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
WavRecordEnabled = false;
try
@@ -120,18 +135,23 @@
m_wavrecord = NULL; // not needed, but what the heck. :)
SysMessage("SPU2-X couldn't open file for recording: %s.\nRecording to wavfile disabled.", "recording.wav");
}
+#endif
}
void RecordStop()
{
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
WavRecordEnabled = false;
ScopedLock lock( WavRecordMutex );
safe_delete( m_wavrecord );
+#endif
}
void RecordWrite( const StereoOut16& sample )
{
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
ScopedLock lock( WavRecordMutex );
if( m_wavrecord == NULL ) return;
m_wavrecord->write( (s16*)&sample, 2 );
+#endif
}
Index: pcsx2.snapshot-3369/plugins/zerospu2/zerospu2.cpp
===================================================================
--- pcsx2.snapshot-3369.orig/plugins/zerospu2/zerospu2.cpp
+++ pcsx2.snapshot-3369/plugins/zerospu2/zerospu2.cpp
@@ -28,7 +28,9 @@
#include <stdlib.h>
#include "soundtouch/SoundTouch.h"
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
#include "soundtouch/WavFile.h"
+#endif
char libraryName[256];
@@ -74,7 +76,9 @@
// time stretch variables
soundtouch::SoundTouch* pSoundTouch=NULL;
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
extern WavOutFile* g_pWavRecord; // used for recording
+#endif
u64 s_GlobalTimeStamp = 0;
s32 s_nDurations[64]={0};
@@ -361,7 +365,9 @@
RemoveSound();
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
delete g_pWavRecord; g_pWavRecord = NULL;
+#endif
delete pSoundTouch; pSoundTouch = NULL;
for (u32 i = 0; i < ArraySize(s_pAudioBuffers); ++i)
Index: pcsx2.snapshot-3369/plugins/zerospu2/zeroworker.cpp
===================================================================
--- pcsx2.snapshot-3369.orig/plugins/zerospu2/zeroworker.cpp
+++ pcsx2.snapshot-3369/plugins/zerospu2/zeroworker.cpp
@@ -19,10 +19,14 @@
#include "zerospu2.h"
#include "zeroworker.h"
#include "soundtouch/SoundTouch.h"
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
#include "soundtouch/WavFile.h"
+#endif
s32 g_logsound = 0;
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
WavOutFile* g_pWavRecord=NULL; // used for recording
+#endif
const s32 f[5][2] = {
{ 0, 0 },
@@ -302,6 +306,7 @@
void LogRawSound(void* pleft, s32 leftstride, void* pright, s32 rightstride, s32 numsamples)
{
+#if defined(SOUNDTOUCH_VERSION_ID) & (SOUNDTOUCH_VERSION_ID >= 10400)
if (g_pWavRecord == NULL )
g_pWavRecord = new WavOutFile(RECORD_FILENAME, SAMPLE_RATE, 16, 2);
@@ -320,4 +325,5 @@
}
g_pWavRecord->write(&tempbuf[0], numsamples*2);
+#endif
}

View File

@ -1,4 +1,3 @@
01_rename_binary_generated.patch
02_update_default_path.patch
05_move_data_to_config.patch
21_use_legacy_soundtouch_13.patch

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

@ -411,7 +411,9 @@ void isoFile::Open( const wxString& srcfile )
// (and if numparts is incremented, elsn will get assigned accordingly)
if (!Detect())
throw Exception::BadStream().SetUserMsg(wxLt("Unrecognized ISO file format."));
throw Exception::BadStream()
.SetUserMsg(L"Unrecognized ISO image file format")
.SetDiagMsg(_("ISO mounting failed: PCSX2 is unable to identify the ISO image type."));
if (!(m_flags & ISOFLAGS_BLOCKDUMP_V2))
{

View File

@ -274,7 +274,6 @@ set(pcsx2DebugToolsHeaders
# gui sources
set(pcsx2GuiSources
gui/AdvancedDialog.cpp
gui/AppAssert.cpp
gui/AppConfig.cpp
gui/AppCorePlugins.cpp
@ -338,7 +337,6 @@ set(pcsx2GuiSources
# gui headers
set(pcsx2GuiHeaders
gui/AdvancedDialog.h
gui/App.h
gui/ApplyState.h
gui/AppAccelerators.h

View File

@ -400,7 +400,7 @@ struct Pcsx2Config
// when enabled uses BOOT2 injection, skipping sony bios splashes
UseBOOT2Injection :1,
BackupSavestate :1,
// enables simulated ejection of memory cards when loading savestates
McdEnableEjection :1,

View File

@ -556,7 +556,9 @@ extern tDMA_TAG *dmaGetAddr(u32 addr, bool write);
extern void hwIntcIrq(int n);
extern void hwDmacIrq(int n);
extern void FireMFIFOEmpty();
extern bool hwMFIFOWrite(u32 addr, const u128* data, uint size_qwc);
extern void hwDmacSrcTadrInc(DMACh& dma);
extern bool hwDmacSrcChainWithStack(DMACh& dma, int id);
extern bool hwDmacSrcChain(DMACh& dma, int id);

View File

@ -260,16 +260,26 @@ void ElfObject::readFile()
if (rsize < data.GetSizeInBytes()) throw Exception::EndOfStream(filename);
}
static wxString GetMsg_InvalidELF()
{
return
_("Cannot load ELF binary image. The file may be corrupt or incomplete.") +
wxString(L"\n\n") +
_("If loading from an ISO image, this error may be caused by an unsupported ISO image type or bug in PCSX2 ISO image support.");
}
void ElfObject::checkElfSize(s64 elfsize)
{
if (elfsize > 0xfffffff)
throw Exception::BadStream(filename).SetBothMsgs(wxLt("Illegal ELF file size over 2GB!"));
const wxChar* diagMsg = NULL;
if (elfsize > 0xfffffff) diagMsg = L"Illegal ELF file size over 2GB!";
else if (elfsize == -1) diagMsg = L"ELF file does not exist!";
else if (elfsize == 0) diagMsg = L"Unexpected end of ELF file.";
if (elfsize == -1)
throw Exception::BadStream(filename).SetBothMsgs(wxLt("ELF file does not exist!"));
if (elfsize == 0)
throw Exception::BadStream(filename).SetBothMsgs(wxLt("Unexpected end of ELF file."));
if (diagMsg)
throw Exception::BadStream(filename)
.SetDiagMsg(diagMsg)
.SetUserMsg(GetMsg_InvalidELF());
}
u32 ElfObject::getCRC()

View File

@ -27,7 +27,6 @@ using std::min;
// A three-way toggle used to determine if the GIF is stalling (transferring) or done (finished).
// Should be a gifstate_t rather then int, but I don't feel like possibly interfering with savestates right now.
static int gifstate = GIF_STATE_READY;
static bool gifempty = false;
static bool gspath3done = false;
@ -47,14 +46,14 @@ static __fi void clearFIFOstuff(bool full)
else
CSRreg.FIFO = CSR_FIFO_EMPTY;
}
extern bool SIGNAL_IMR_Pending;
void gsPath1Interrupt()
{
//DevCon.Warning("Path1 flush W %x, R %x", Path1WritePos, Path1ReadPos);
if((gifRegs.stat.APATH <= GIF_APATH1 || (gifRegs.stat.IP3 == true && gifRegs.stat.APATH == GIF_APATH3)) && Path1WritePos > 0 && !gifRegs.stat.PSE)
if((gifRegs.stat.APATH <= GIF_APATH1 || (gifRegs.stat.IP3 == true && gifRegs.stat.APATH == GIF_APATH3)) && Path1WritePos > 0 && !gifRegs.stat.PSE && SIGNAL_IMR_Pending == false)
{
gifRegs.stat.P1Q = false;
@ -62,7 +61,7 @@ void gsPath1Interrupt()
{
GetMTGS().PrepDataPacket(GIF_PATH_1, size);
//DevCon.Warning("Flush Size = %x", size);
while(size > 0)
while(size > 0 && SIGNAL_IMR_Pending == false)
{
uint count = GIFPath_CopyTag(GIF_PATH_1, ((u128*)Path1Buffer) + Path1ReadPos, size);
Path1ReadPos += count;
@ -79,13 +78,18 @@ void gsPath1Interrupt()
if(Path1ReadPos == Path1WritePos)
{
Path1WritePos = Path1ReadPos = 0;
}
else
{
//DevCon.Warning("Queue quitting early due to signal or EOP %x", size);
gifRegs.stat.P1Q = true;
}
}
}
else
{
if(gifRegs.stat.PSE) DevCon.Warning("Path1 paused by GIF_CTRL");
DevCon.Warning("Looping??? IP3 %x APATH %x OPH %x", gifRegs.stat.IP3, gifRegs.stat.APATH, gifRegs.stat.OPH);
//DevCon.Warning("Looping??? IP3 %x APATH %x OPH %x", gifRegs.stat.IP3, gifRegs.stat.APATH, gifRegs.stat.OPH);
//if(!(cpuRegs.interrupt & (1<<28)) && Path1WritePos > 0)CPU_INT(28, 128);
}
@ -97,6 +101,13 @@ __fi void gsInterrupt()
{
GIF_LOG("gsInterrupt caught!");
if (dmacRegs.ctrl.MFD == MFD_GIF) // GIF MFIFO
{
//Console.WriteLn("GIF MFIFO");
gifMFIFOInterrupt();
return;
}
if(SIGNAL_IMR_Pending == true)
{
//DevCon.Warning("Path 3 Paused");
@ -234,6 +245,7 @@ bool CheckPaths(int Channel)
{
if((vif1.cmd & 0x7f) != 0x51 || gifRegs.stat.P1Q == true)
{
//DevCon.Warning("GIF Stall 1 P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.APATH, GSTransferStatus.PTH3, vif1.cmd);
gifRegs.stat.IP3 = true;
if(gifRegs.stat.P1Q) gsPath1Interrupt();
CPU_INT(DMAC_GIF, 16);
@ -246,6 +258,7 @@ bool CheckPaths(int Channel)
//This should cover both scenarios, as DIRECTHL doesn't gain priority when image mode is running (PENDINGIMAGE_MODE == fininshed).
if((gifRegs.stat.P1Q == true || gifRegs.stat.P2Q == true) || (gifRegs.stat.APATH > GIF_APATH_IDLE && gifRegs.stat.APATH < GIF_APATH3))
{
//DevCon.Warning("GIF Stall 2 P1Q %x P2Q %x APATH %x PTH3 %x vif1cmd %x", gifRegs.stat.P1Q, gifRegs.stat.P2Q, gifRegs.stat.APATH, GSTransferStatus.PTH3, vif1.cmd);
gifRegs.stat.IP3 = true;
CPU_INT(DMAC_GIF, 16);
return false;
@ -430,61 +443,90 @@ void dmaGIF()
}
}
if (dmacRegs.ctrl.MFD == MFD_GIF) // GIF MFIFO
{
//Console.WriteLn("GIF MFIFO");
gifMFIFOInterrupt();
return;
}
GIFdma();
gsInterrupt();
}
static u16 QWCinGIFMFIFO(u32 DrainADDR)
{
u32 ret;
GIF_LOG("GIF MFIFO Requesting %x QWC from the MFIFO Base %x, SPR MADR %x Drain %x", gifch.qwc, dmacRegs.rbor.ADDR, spr0ch.madr, DrainADDR);
//Calculate what we have in the fifo.
if(DrainADDR <= spr0ch.madr)
{
//Drain is below the tadr, calculate the difference between them
ret = (spr0ch.madr - DrainADDR) >> 4;
}
else
{
u32 limit = dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16;
//Drain is higher than SPR so it has looped round,
//calculate from base to the SPR tag addr and what is left in the top of the ring
ret = ((spr0ch.madr - dmacRegs.rbor.ADDR) + (limit - DrainADDR)) >> 4;
}
GIF_LOG("%x Available of the %x requested", ret, gifch.qwc);
if((s32)ret < 0) DevCon.Warning("GIF Returning %x!", ret);
return ret;
}
// called from only one location, so forceinline it:
static __fi bool mfifoGIFrbTransfer()
{
u32 mfifoqwc = min(gifqwc, (u32)gifch.qwc);
u16 mfifoqwc = min(QWCinGIFMFIFO(gifch.madr), gifch.qwc);
u32 *src;
if(mfifoqwc == 0) return true; //Lets skip all this, we don't have the data
GetMTGS().PrepDataPacket(GIF_PATH_3, mfifoqwc);
// TODO (minor optimization): The new GIFpath parser can do rather efficient wrapping of
// its own internally now. We just need to groom a version of it that can wrap around MFIFO
// memory similarly to how it wraps VU1 memory on PATH1.
GIF_LOG("MFIFO QWC to Transfer %x", mfifoqwc);
/* Check if the transfer should wrap around the ring buffer */
if ((gifch.madr + mfifoqwc * 16) > (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16))
if ( (gifch.madr + (mfifoqwc * 16)) > (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16))
{
uint s1 = ((dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16) - gifch.madr) >> 4;
uint s2 = (mfifoqwc - s1);
GIF_LOG("Split transfer doing %x QWC of %x Total QWC", s1, mfifoqwc);
/* it does (wrap around), so first copy 's1' bytes from 'addr' to 'data' */
/* and second copy 's2' bytes from 'maddr' to '&data[s1]' */
gifch.madr = dmacRegs.rbor.ADDR + (gifch.madr & dmacRegs.rbsr.RMSK);
src = (u32*)PSM(gifch.madr);
if (src == NULL) return false;
uint copied = GIFPath_CopyTag(GIF_PATH_3, (u128*)src, s1);
if (copied == s1) // but only copy second if first didn't abort prematurely for some reason.
{
GIF_LOG("Transferring last %x QWC", s2);
src = (u32*)PSM(dmacRegs.rbor.ADDR);
gifch.madr = dmacRegs.rbor.ADDR;
if (src == NULL) return false;
copied += GIFPath_CopyTag(GIF_PATH_3, (u128*)src, s2);
}
mfifoqwc = copied;
GIF_LOG("Copied %x QWC, %x QWC Left", mfifoqwc, gifch.qwc);
}
else
{
GIF_LOG("Direct MFIFO transfer doing %x Total QWC", mfifoqwc);
/* it doesn't, so just transfer 'qwc*16' words from 'gifch.madr' to GS */
gifch.madr = dmacRegs.rbor.ADDR + (gifch.madr & dmacRegs.rbsr.RMSK);
src = (u32*)PSM(gifch.madr);
if (src == NULL) return false;
mfifoqwc = GIFPath_CopyTag(GIF_PATH_3, (u128*)src, mfifoqwc);
gifch.madr = dmacRegs.rbor.ADDR + (gifch.madr & dmacRegs.rbsr.RMSK);
GIF_LOG("%X QWC Copied direct %x QWC Left", mfifoqwc, gifch.qwc);
}
GetMTGS().SendDataPacket();
gifqwc -= mfifoqwc;
//gifqwc -= mfifoqwc;
mfifocycles += (mfifoqwc) * 2; /* guessing */
return true;
}
@ -496,14 +538,19 @@ static __fi bool mfifoGIFchain()
if (gifch.qwc == 0) return true;
if (gifch.madr >= dmacRegs.rbor.ADDR &&
gifch.madr <= (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK))
gifch.madr <= (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16))
{
if (!mfifoGIFrbTransfer()) return false;
bool ret = true;
// if(gifch.madr == (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16)) DevCon.Warning("Edge GIF");
if (!mfifoGIFrbTransfer()) ret = false;
if(QWCinGIFMFIFO(gifch.madr) == 0) gifstate |= GIF_STATE_EMPTY;
return ret;
}
else
{
int mfifoqwc;
GIF_LOG("Non-MFIFO Location transfer doing %x Total QWC", gifch.qwc);
tDMA_TAG *pMem = dmaGetAddr(gifch.madr, false);
if (pMem == NULL) return false;
@ -528,12 +575,13 @@ void mfifoGIFtransfer(int qwc)
if(qwc > 0 )
{
gifqwc += qwc;
if (!(gifstate & GIF_STATE_EMPTY)) return;
// if (gifempty == false) return;
gifstate &= ~GIF_STATE_EMPTY;
gifempty = false;
if ((gifstate & GIF_STATE_EMPTY) && !(cpuRegs.interrupt & (1<<DMAC_MFIFO_GIF)))
{
if(gifch.chcr.STR == true)CPU_INT(DMAC_MFIFO_GIF, 4);
gifstate &= ~GIF_STATE_EMPTY;
}
gifRegs.stat.FQC = 16;
return;
}
if (gifRegs.ctrl.PSE) // temporarily stop
@ -545,15 +593,6 @@ void mfifoGIFtransfer(int qwc)
if (gifch.qwc == 0)
{
if (gifch.tadr == spr0ch.madr)
{
//if( gifqwc > 1 ) DevCon.WriteLn("gif mfifo tadr==madr but qwc = %d", gifqwc);
hwDmacIrq(DMAC_MFIFO_EMPTY);
gifstate |= GIF_STATE_EMPTY;
gifempty = true;
return;
}
gifch.tadr = qwctag(gifch.tadr);
ptag = dmaGetAddr(gifch.tadr, false);
@ -565,42 +604,10 @@ void mfifoGIFtransfer(int qwc)
GIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x",
ptag[1]._u32, ptag[0]._u32, gifch.qwc, ptag->ID, gifch.madr, gifch.tadr, gifqwc, spr0ch.madr);
gifqwc--;
gspath3done = hwDmacSrcChainWithStack(gifch, ptag->ID);
switch (ptag->ID)
{
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
gifch.tadr = qwctag(gifch.tadr + 16);
gifstate = GIF_STATE_DONE; //End Transfer
break;
case TAG_CNT: // CNT - Transfer QWC following the tag.
gifch.madr = qwctag(gifch.tadr + 16); //Set MADR to QW after Tag
gifch.tadr = qwctag(gifch.madr + (gifch.qwc << 4)); //Set TADR to QW following the data
gifstate = GIF_STATE_READY;
break;
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
{
u32 temp = gifch.madr; //Temporarily Store ADDR
gifch.madr = qwctag(gifch.tadr + 16); //Set MADR to QW following the tag
gifch.tadr = temp; //Copy temporarily stored ADDR to Tag
gifstate = GIF_STATE_READY;
break;
}
case TAG_REF: // Ref - Transfer QWC from ADDR field
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
gifch.tadr = qwctag(gifch.tadr + 16); //Set TADR to next tag
gifstate = GIF_STATE_READY;
break;
case TAG_END: // End - Transfer QWC following the tag
gifch.madr = qwctag(gifch.tadr + 16); //Set MADR to data following the tag
gifch.tadr = qwctag(gifch.madr + (gifch.qwc << 4)); //Set TADR to QW following the data
gifstate = GIF_STATE_DONE; //End Transfer
break;
}
if(gspath3done == true) gifstate = GIF_STATE_DONE;
else gifstate = GIF_STATE_READY;
if ((gifch.chcr.TIE) && (ptag->IRQ))
{
@ -608,7 +615,8 @@ void mfifoGIFtransfer(int qwc)
gifstate = GIF_STATE_DONE;
gifmfifoirq = true;
}
}
if (QWCinGIFMFIFO(gifch.tadr) == 0) gifstate |= GIF_STATE_EMPTY;
}
if (!mfifoGIFchain())
{
@ -616,7 +624,7 @@ void mfifoGIFtransfer(int qwc)
gifstate = GIF_STATE_STALL;
}
if ((gifch.qwc == 0) && (gifstate & GIF_STATE_DONE)) gifstate = GIF_STATE_STALL;
if ((gifch.qwc == 0) && (gifstate & GIF_STATE_DONE)) gifstate |= GIF_STATE_STALL;
CPU_INT(DMAC_MFIFO_GIF,mfifocycles);
SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gifch.chcr._u32, gifch.madr, gifch.tadr);
@ -624,9 +632,15 @@ void mfifoGIFtransfer(int qwc)
void gifMFIFOInterrupt()
{
//Console.WriteLn("gifMFIFOInterrupt");
GIF_LOG("gifMFIFOInterrupt");
mfifocycles = 0;
if (dmacRegs.ctrl.MFD != MFD_GIF)
{
DevCon.Warning("Not in GIF MFIFO mode! Stopping GIF MFIFO");
return;
}
if(SIGNAL_IMR_Pending == true)
{
//DevCon.Warning("Path 3 Paused");
@ -634,13 +648,20 @@ void gifMFIFOInterrupt()
return;
}
if(GSTransferStatus.PTH3 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH3 )
if(GSTransferStatus.PTH3 >= PENDINGSTOP_MODE && gifRegs.stat.APATH == GIF_APATH3 )
{
gifRegs.stat.OPH = false;
GSTransferStatus.PTH3 = STOPPED_MODE;
gifRegs.stat.APATH = GIF_APATH_IDLE;
if(gifRegs.stat.P1Q) gsPath1Interrupt();
}
if((gifstate & GIF_STATE_EMPTY))
{
FireMFIFOEmpty();
if(!(gifstate & GIF_STATE_STALL)) return;
}
if(CheckPaths(11) == false) return;
if (!(gifch.chcr.STR))
@ -652,16 +673,13 @@ void gifMFIFOInterrupt()
if (!(gifstate & GIF_STATE_STALL))
{
if (gifqwc <= 0)
if (QWCinGIFMFIFO(gifch.tadr) == 0)
{
//Console.WriteLn("Empty");
hwDmacIrq(DMAC_MFIFO_EMPTY);
gifstate |= GIF_STATE_EMPTY;
gifempty = true;
gifRegs.stat.IMT = false;
CPU_INT(DMAC_MFIFO_GIF, 4);
return;
}
mfifoGIFtransfer(0);
return;
}
@ -685,6 +703,7 @@ void gifMFIFOInterrupt()
gifch.chcr.STR = false;
gifstate = GIF_STATE_READY;
hwDmacIrq(DMAC_GIF);
GIF_LOG("gifMFIFO End");
clearFIFOstuff(false);
}
@ -696,7 +715,6 @@ void SaveStateBase::gifFreeze()
Freeze( gifqwc );
Freeze( gspath3done );
Freeze( gscycles );
//Freeze(gifempty);
// Note: mfifocycles is not a persistent var, so no need to save it here.
int bufsize = Path1WritePos - Path1ReadPos;

View File

@ -26,7 +26,7 @@ enum gifstate_t
enum GSTransferModes //0 = Image Mode (DirectHL), 1 = transferring, 2 = Stopped at End of Packet
{
PENDINGIMAGE_MODE = 0,
WAITING_MODE = 0,
IMAGE_MODE = 1,
TRANSFER_MODE = 2,
PENDINGSTOP_MODE = 3,

View File

@ -130,6 +130,14 @@ void hwDmacIrq(int n)
if(psHu16(DMAC_STAT+2) & (1<<n))cpuTestDMACInts();
}
void FireMFIFOEmpty()
{
SPR_LOG("VIF MFIFO Data Empty");
hwDmacIrq(DMAC_MFIFO_EMPTY);
if (dmacRegs.ctrl.MFD == MFD_VIF1) vif1Regs.stat.FQC = 0;
else if (dmacRegs.ctrl.MFD == MFD_GIF) gifRegs.stat.FQC = 0;
}
// Write 'size' bytes to memory address 'addr' from 'data'.
__ri bool hwMFIFOWrite(u32 addr, const u128* data, uint qwc)
{
@ -137,6 +145,7 @@ __ri bool hwMFIFOWrite(u32 addr, const u128* data, uint qwc)
pxAssume((dmacRegs.rbor.ADDR & 15) == 0);
pxAssume((addr & 15) == 0);
if(qwc > ((dmacRegs.rbsr.RMSK + 16) >> 4)) DevCon.Warning("MFIFO Write bigger than MFIFO! QWC=%x FifoSize=%x", qwc, ((dmacRegs.rbsr.RMSK + 16) >> 4));
// DMAC Address resolution: FIFO can be placed anywhere in the *physical* memory map
// for the PS2. Its probably a serious error for a PS2 app to have the buffer cross
// valid/invalid page areas of ram, so realistically we only need to test the base address
@ -162,13 +171,15 @@ __ri bool hwMFIFOWrite(u32 addr, const u128* data, uint qwc)
__ri bool hwDmacSrcChainWithStack(DMACh& dma, int id) {
switch (id) {
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
dma.tadr += 16;
//End Transfer
return true;
case TAG_CNT: // CNT - Transfer QWC following the tag.
// Set MADR to QW afer tag, and set TADR to QW following the data.
dma.madr = dma.tadr + 16;
dma.tadr = dma.madr + (dma.qwc << 4);
dma.tadr += 16;
dma.madr = dma.tadr;
//dma.tadr = dma.madr + (dma.qwc << 4);
return false;
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
@ -267,6 +278,33 @@ __ri bool hwDmacSrcChainWithStack(DMACh& dma, int id) {
return false;
}
/********TADR NOTES***********
From what i've gathered from testing tadr increment stuff (with CNT) is that we might not be 100% accurate in what
increments it and what doesnt. Previously we presumed REFE and END didn't increment the tag, but SIF and IPU never
liked this.
From what i've deduced, REFE does in fact increment, but END doesn't, after much testing, i've concluded this is how
we can standardize DMA chains, so i've modified the code to work like this. The below function controls the increment
of the TADR along with the MADR on VIF, GIF and SPR1 when using the CNT tag, the others don't use it yet, but they
can probably be modified to do so now.
Reason for this:- Many games (such as clock tower 3 and FFX Videos) watched the TADR to see when a transfer has finished,
so we need to simulate this wherever we can! Even the FFX video gets corruption and tries to fire multiple DMA Kicks
if this doesnt happen, which was the reasoning for the hacked up SPR timing we had, that is no longer required.
-Refraction
******************************/
void hwDmacSrcTadrInc(DMACh& dma)
{
u16 tagid = (dma.chcr.TAG >> 12) & 0x7;
if(tagid == TAG_CNT)
{
dma.tadr = dma.madr;
}
}
bool hwDmacSrcChain(DMACh& dma, int id)
{
u32 temp;
@ -274,13 +312,14 @@ bool hwDmacSrcChain(DMACh& dma, int id)
switch (id)
{
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
dma.tadr += 16;
// End the transfer.
return true;
case TAG_CNT: // CNT - Transfer QWC following the tag.
// Set MADR to QW after the tag, and TADR to QW following the data.
dma.madr = dma.tadr + 16;
dma.tadr = dma.madr + (dma.qwc << 4);
dma.tadr = dma.madr;
return false;
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
@ -305,3 +344,4 @@ bool hwDmacSrcChain(DMACh& dma, int id)
return false;
}

View File

@ -308,6 +308,7 @@ enum EERegisterAddresses
DMAC_RBSR = 0x1000E040,
DMAC_RBOR = 0x1000E050,
DMAC_STADR = 0x1000E060,
DMAC_FAKESTAT = 0x1000E100, //Midway, you're idiots (checked this in the MK Deception ELF!) (Refraction)
INTC_STAT = 0x1000F000,
INTC_MASK = 0x1000F010,

View File

@ -440,10 +440,9 @@ static __fi bool ipuVDEC(u32 val)
// very choppy (basically only decoding/updating every 30th frame or so). So yeah,
// someone with knowledge on the subject please feel free to explain this one. :) --air
ipuRegs.cmd.DATA &= 0xFFFF;
ipuRegs.cmd.DATA |= 0x10000;
// The upper bits are the "length" of the decoded command, where the lower is the address.
// This is due to differences with IPU and the MPEG standard. See get_macroblock_address_increment().
//ipuRegs.cmd.DATA = (ipuRegs.cmd.DATA & 0xFFFF) | ((decoder.bitstream_bits + 16) << 16);
ipuRegs.ctrl.ECD = (ipuRegs.cmd.DATA == 0);
case 1:
@ -909,7 +908,7 @@ __noinline void IPUWorker()
// CHECK!: IPU0dma remains when IDEC is done, so we need to clear it
// Check Mana Khemia 1 "off campus" to trigger a GUST IDEC messup.
// This hackfixes it :/
if (ipu0dma.qwc > 0 && ipu0dma.chcr.STR) ipu0Interrupt();
//if (ipu0dma.qwc > 0 && ipu0dma.chcr.STR) ipu0Interrupt();
break;
case SCE_IPU_BDEC:

View File

@ -109,11 +109,11 @@ int IPU_Fifo_Output::write(const u32 *value, uint size)
pxAssumeMsg(size>0, "Invalid size==0 when calling IPU_Fifo_Output::write");
uint origsize = size;
do {
IPU0dma();
/*do {*/
//IPU0dma();
uint transsize = min(size, 8 - (uint)ipuRegs.ctrl.OFC);
if(!transsize) break;
if(!transsize) return 0;
ipuRegs.ctrl.OFC = transsize;
size -= transsize;
@ -124,7 +124,7 @@ int IPU_Fifo_Output::write(const u32 *value, uint size)
value += 4;
--transsize;
}
} while(true);
/*} while(true);*/
return origsize - size;
}

View File

@ -42,21 +42,6 @@ void SaveStateBase::ipuDmaFreeze()
Freeze(IPU1Status);
}
static __fi bool ipuDmacPartialChain(tDMA_TAG tag)
{
switch (tag.ID)
{
case TAG_REFE: // refe
ipu1dma.tadr += 16;
return true;
case TAG_END: // end
ipu1dma.tadr = ipu1dma.madr;
return true;
}
return false;
}
static __fi void ipuDmacSrcChain()
{
switch (IPU1Status.ChainMode)
@ -82,7 +67,7 @@ static __fi void ipuDmacSrcChain()
break;
case TAG_END: // end
ipu1dma.tadr = ipu1dma.madr;
//ipu1dma.tadr = ipu1dma.madr;
IPU1Status.DMAFinished = true;
break;
}
@ -136,15 +121,12 @@ static __fi int IPU1chain() {
ipu1dma.qwc -= qwc;
totalqwc += qwc;
}
//Update TADR etc
if(IPU1Status.DMAMode == DMA_MODE_CHAIN) ipuDmacSrcChain();
if( ipu1dma.qwc == 0)
{
//Update TADR etc
if(IPU1Status.DMAMode == DMA_MODE_CHAIN) ipuDmacSrcChain();
//If the transfer has finished or we have room in the FIFO, schedule to the interrupt code.
//No data left
IPU1Status.InProgress = false;
} //If we still have data the commands should pull this across when need be.
return totalqwc;
}
@ -238,7 +220,8 @@ int IPU1dma()
break;
case TAG_CNT: // cnt
ipu1dma.madr = ipu1dma.tadr + 16;
ipu1dma.tadr += 16;
ipu1dma.madr = ipu1dma.tadr;
IPU_LOG("Tag should end on %x", ipu1dma.madr + ipu1dma.qwc * 16);
//ipu1dma.tadr = ipu1dma.madr + (ipu1dma.qwc * 16);
// Set the taddr to the next tag
@ -262,7 +245,7 @@ int IPU1dma()
case TAG_END: // end
// do not change tadr
ipu1dma.madr = ipu1dma.tadr + 16;
ipu1dma.tadr += 16;
//ipu1dma.tadr += 16;
IPU_LOG("Tag should end on %x", ipu1dma.madr + ipu1dma.qwc * 16);
break;
@ -310,15 +293,23 @@ int IPU1dma()
return totalqwc;
}
int IPU0dma()
void IPU0dma()
{
if(!ipuRegs.ctrl.OFC) return 0;
if(!ipuRegs.ctrl.OFC)
{
IPU_INT_FROM( 64 );
IPUProcessInterrupt();
return;
}
int readsize;
tDMA_TAG* pMem;
if ((!(ipu0dma.chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_FROM_IPU))) || (ipu0dma.qwc == 0))
return 0;
{
DevCon.Warning("How??");
return;
}
pxAssert(!(ipu0dma.chcr.TTE));
@ -362,10 +353,11 @@ int IPU0dma()
//This was IPU_INT_FROM(readsize*BIAS );
//This broke vids in Digital Devil Saga
//Note that interrupting based on totalsize is just guessing..
IPU_INT_FROM( readsize * BIAS );
}
IPU_INT_FROM( readsize * BIAS );
if(ipuRegs.ctrl.IFC > 0) IPUProcessInterrupt();
return readsize;
//return readsize;
}
__fi void dmaIPU0() // fromIPU
@ -381,7 +373,10 @@ __fi void dmaIPU0() // fromIPU
hwDmacIrq(DMAC_FROM_IPU);
}
IPUProcessInterrupt();
IPU_INT_FROM( 64 );
}
__fi void dmaIPU1() // toIPU
@ -450,6 +445,11 @@ void ipu0Interrupt()
{
IPU_LOG("ipu0Interrupt: %x", cpuRegs.cycle);
if(ipu0dma.qwc > 0)
{
IPU0dma();
return;
}
if (g_nDMATransfer.FIREINT0)
{
g_nDMATransfer.FIREINT0 = false;

View File

@ -87,7 +87,7 @@ extern void ipu1Interrupt();
extern void dmaIPU0();
extern void dmaIPU1();
extern int IPU0dma();
extern void IPU0dma();
extern int IPU1dma();
extern void ipuDmaReset();

View File

@ -135,14 +135,13 @@ int get_macroblock_modes()
{
macroblock_modes |= GETBITS(2) * MOTION_TYPE_BASE;
}
return macroblock_modes;
return (macroblock_modes | (tab->len << 16));
}
else if (decoder.frame_pred_frame_dct)
{
/* if (! (macroblock_modes & MACROBLOCK_INTRA)) */
macroblock_modes |= MC_FRAME;
return macroblock_modes;
return (macroblock_modes | (tab->len << 16));
}
else
{
@ -155,15 +154,15 @@ int get_macroblock_modes()
intra:
macroblock_modes |= GETBITS(1) * DCT_TYPE_INTERLACED;
}
return macroblock_modes;
return (macroblock_modes | (tab->len << 16));
}
case D_TYPE:
macroblock_modes = GETBITS(1);
//I suspect (as this is actually a 2 bit command) that this should be getbits(2)
//additionally, we arent dumping any bits here when i think we should be, need a game to test. (Refraction)
if (macroblock_modes == 0) return 0; // error
return MACROBLOCK_INTRA;
return (MACROBLOCK_INTRA | (1 << 16));
default:
return 0;
@ -222,14 +221,15 @@ int __fi get_motion_delta(const int f_code)
sign = SBITS(1);
DUMPBITS(1);
return (delta ^ sign) - sign;
return (((delta ^ sign) - sign) | (tab->len << 16));
}
int __fi get_dmv()
{
const DMVtab* tab = DMV_2 + UBITS(2);
DUMPBITS(tab->len);
return tab->dmv;
return (tab->dmv | (tab->len << 16));
}
int get_macroblock_address_increment()
@ -246,13 +246,13 @@ int get_macroblock_address_increment()
{
case 8: /* macroblock_escape */
DUMPBITS(11);
return 0x23;
return 0xb0023;
case 15: /* macroblock_stuffing (MPEG1 only) */
if (decoder.mpeg1)
{
DUMPBITS(11);
return 0x22;
return 0xb0022;
}
default:
@ -261,7 +261,7 @@ int get_macroblock_address_increment()
DUMPBITS(mba->len);
return mba->mba + 1;
return ((mba->mba + 1) | (mba->len << 16));
}
static __fi int get_luma_dc_dct_diff()

View File

@ -395,8 +395,6 @@
<Unit filename="../ZipTools/ThreadedZipTools.h" />
<Unit filename="../ZipTools/thread_gzip.cpp" />
<Unit filename="../ZipTools/thread_lzma.cpp" />
<Unit filename="../gui/AdvancedDialog.cpp" />
<Unit filename="../gui/AdvancedDialog.h" />
<Unit filename="../gui/App.h" />
<Unit filename="../gui/AppAccelerators.h" />
<Unit filename="../gui/AppAssert.cpp" />

View File

@ -806,7 +806,7 @@ void SysMtgsThread::WaitForOpen()
// emulator forcefully, or to continue waiting on the GS.
throw Exception::PluginOpenError( PluginId_GS )
.SetBothMsgs(wxLt("The MTGS thread has become unresponsive while waiting for the GS plugin to open."));
.SetBothMsgs(pxLt("The MTGS thread has become unresponsive while waiting for the GS plugin to open."));
}
}

View File

@ -374,6 +374,7 @@ void Pcsx2Config::LoadSave( IniInterface& ini )
IniBitBool( ConsoleToStdio );
IniBitBool( HostFs );
IniBitBool( BackupSavestate );
IniBitBool( McdEnableEjection );
IniBitBool( MultitapPort0_Enabled );
IniBitBool( MultitapPort1_Enabled );

View File

@ -23,6 +23,7 @@
#include "CDVD/CDVDisoReader.h"
#include "Utilities/ScopedPtr.h"
#include "Utilities/pxStreams.h"
#if _MSC_VER
# include "svnrev.h"
@ -152,7 +153,7 @@ _GSgifSoftReset GSgifSoftReset;
_GSreadFIFO GSreadFIFO;
_GSreadFIFO2 GSreadFIFO2;
_GSchangeSaveState GSchangeSaveState;
_GSgetTitleInfo GSgetTitleInfo;
_GSgetTitleInfo2 GSgetTitleInfo2;
_GSmakeSnapshot GSmakeSnapshot;
_GSmakeSnapshot2 GSmakeSnapshot2;
_GSirqCallback GSirqCallback;
@ -185,8 +186,11 @@ static void CALLBACK GS_printf(int timeout, char *fmt, ...)
Console.WriteLn(msg);
}
void CALLBACK GS_getTitleInfo( char dest[128] )
void CALLBACK GS_getTitleInfo2( char* dest, size_t length )
{
// Just return a generic "GS" title -- a plugin actually implementing this feature
// should return a title such as "GSdx" or "ZZogl" instead. --air
dest[0] = 'G';
dest[1] = 'S';
dest[2] = 0;
@ -372,7 +376,7 @@ static const LegacyApi_ReqMethod s_MethMessReq_GS[] =
{ "GSsetVsync", (vMeth**)&GSsetVsync, (vMeth*)GS_setVsync },
{ "GSsetExclusive", (vMeth**)&GSsetExclusive, (vMeth*)GS_setExclusive },
{ "GSchangeSaveState",(vMeth**)&GSchangeSaveState,(vMeth*)GS_changeSaveState },
{ "GSgetTitleInfo", (vMeth**)&GSgetTitleInfo, (vMeth*)GS_getTitleInfo },
{ "GSgetTitleInfo2", (vMeth**)&GSgetTitleInfo2, (vMeth*)GS_getTitleInfo2 },
{ NULL }
};
@ -807,11 +811,11 @@ SysCorePlugins::PluginStatus_t::PluginStatus_t( PluginsEnum_t _pid, const wxStri
if( !wxFile::Exists( Filename ) )
throw Exception::PluginLoadError( pid ).SetStreamName(srcfile)
.SetBothMsgs(wxLt("The configured %s plugin file was not found"));
.SetBothMsgs(pxL("The configured %s plugin file was not found"));
if( !Lib.Load( Filename ) )
throw Exception::PluginLoadError( pid ).SetStreamName(Filename)
.SetBothMsgs(wxLt("The configured %s plugin file is not a valid dynamic library"));
.SetBothMsgs(pxL("The configured %s plugin file is not a valid dynamic library"));
// Try to enumerate the new v2.0 plugin interface first.
@ -1321,7 +1325,7 @@ bool SysCorePlugins::Init()
{
// fixme: use plugin's GetLastError (not implemented yet!)
throw Exception::PluginInitError( PluginId_Mcd )
.SetBothMsgs(wxLt("Internal Memorycard Plugin failed to initialize."));
.SetBothMsgs(pxLt("Internal Memorycard Plugin failed to initialize."));
}
}
@ -1399,9 +1403,6 @@ void SysCorePlugins::Freeze( PluginsEnum_t pid, SaveStateBase& state )
// No locking leeded -- DoFreeze locks as needed, and this avoids MTGS deadlock.
//ScopedLock lock( m_mtx_PluginStatus );
Console.Indent().WriteLn( "%s %s", state.IsSaving() ? "Saving" : "Loading",
tbl_PluginInfo[pid].shortname );
freezeData fP = { 0, NULL };
if( !DoFreeze( pid, FREEZE_SIZE, &fP ) )
fP.size = 0;
@ -1409,6 +1410,9 @@ void SysCorePlugins::Freeze( PluginsEnum_t pid, SaveStateBase& state )
int fsize = fP.size;
state.Freeze( fsize );
Console.Indent().WriteLn( "%s %s", state.IsSaving() ? "Saving" : "Loading",
tbl_PluginInfo[pid].shortname );
if( state.IsLoading() && (fsize == 0) )
{
// no state data to read, but the plugin expects some state data.
@ -1443,6 +1447,82 @@ void SysCorePlugins::Freeze( PluginsEnum_t pid, SaveStateBase& state )
state.CommitBlock( fP.size );
}
size_t SysCorePlugins::GetFreezeSize( PluginsEnum_t pid )
{
freezeData fP = { 0, NULL };
if (!DoFreeze( pid, FREEZE_SIZE, &fP)) return 0;
return fP.size;
}
void SysCorePlugins::FreezeOut( PluginsEnum_t pid, void* dest )
{
// No locking needed -- DoFreeze locks as needed, and this avoids MTGS deadlock.
//ScopedLock lock( m_mtx_PluginStatus );
freezeData fP = { 0, (s8*)dest };
if (!DoFreeze( pid, FREEZE_SIZE, &fP)) return;
if (!fP.size) return;
Console.Indent().WriteLn( "Saving %s", tbl_PluginInfo[pid].shortname );
if (!DoFreeze(pid, FREEZE_SAVE, &fP))
throw Exception::FreezePluginFailure( pid );
}
void SysCorePlugins::FreezeOut( PluginsEnum_t pid, pxOutputStream& outfp )
{
// No locking needed -- DoFreeze locks as needed, and this avoids MTGS deadlock.
//ScopedLock lock( m_mtx_PluginStatus );
freezeData fP = { 0, NULL };
if (!DoFreeze( pid, FREEZE_SIZE, &fP)) return;
if (!fP.size) return;
Console.Indent().WriteLn( "Saving %s", tbl_PluginInfo[pid].shortname );
ScopedAlloc<s8> data( fP.size );
fP.data = data.GetPtr();
if (!DoFreeze(pid, FREEZE_SAVE, &fP))
throw Exception::FreezePluginFailure( pid );
outfp.Write( fP.data, fP.size );
}
void SysCorePlugins::FreezeIn( PluginsEnum_t pid, pxInputStream& infp )
{
// No locking needed -- DoFreeze locks as needed, and this avoids MTGS deadlock.
//ScopedLock lock( m_mtx_PluginStatus );
freezeData fP = { 0, NULL };
if (!DoFreeze( pid, FREEZE_SIZE, &fP ))
fP.size = 0;
Console.Indent().WriteLn( "Loading %s", tbl_PluginInfo[pid].shortname );
if (!infp.IsOk() || !infp.Length())
{
// no state data to read, but the plugin expects some state data?
// Issue a warning to console...
if( fP.size != 0 )
Console.Indent().Warning( "Warning: No data for this plugin was found. Plugin status may be unpredictable." );
return;
// Note: Size mismatch check could also be done here on loading, but
// some plugins may have built-in version support for non-native formats or
// older versions of a different size... or could give different sizes depending
// on the status of the plugin when loading, so let's ignore it.
}
ScopedAlloc<s8> data( fP.size );
fP.data = data.GetPtr();
infp.Read( fP.data, fP.size );
if (!DoFreeze(pid, FREEZE_LOAD, &fP))
throw Exception::ThawPluginFailure( pid );
}
bool SysCorePlugins::KeyEvent( const keyEvent& evt )
{
ScopedLock lock( m_mtx_PluginStatus );

View File

@ -326,6 +326,10 @@ public:
virtual bool IsInitialized( PluginsEnum_t pid ) const;
virtual bool IsLoaded( PluginsEnum_t pid ) const;
virtual size_t GetFreezeSize( PluginsEnum_t pid );
virtual void FreezeOut( PluginsEnum_t pid, void* dest );
virtual void FreezeOut( PluginsEnum_t pid, pxOutputStream& outfp );
virtual void FreezeIn( PluginsEnum_t pid, pxInputStream& infp );
virtual void Freeze( PluginsEnum_t pid, SaveStateBase& state );
virtual bool DoFreeze( PluginsEnum_t pid, int mode, freezeData* data );

View File

@ -16,7 +16,7 @@
#ifndef PCSX2_PRECOMPILED_HEADER
#define PCSX2_PRECOMPILED_HEADER
//#pragma once // no dice, causes problems in GCC PCH (which doesn't really work very well
//#pragma once // no dice, causes problems in GCC PCH (which doesn't really work very well anyway)
// Disable some pointless warnings...
#ifdef _MSC_VER
@ -24,20 +24,7 @@
# pragma warning(disable:4996) //ignore the stricmp deprecated warning
#endif
//////////////////////////////////////////////////////////////////////////////////////////
// Define PCSX2's own i18n helpers. These override the wxWidgets helpers and provide
// additional functionality.
//
#define WXINTL_NO_GETTEXT_MACRO
#undef _
#define _(s) pxGetTranslation(_T(s))
// macro provided for tagging translation strings, without actually running them through the
// translator (which the _() does automatically, and sometimes we don't want that). This is
// a shorthand replacement for wxTRANSLATE.
#ifndef wxLt
# define wxLt(a) wxT(a)
#endif
#include "Utilities/Dependencies.h"
#define NOMINMAX // Disables other libs inclusion of their own min/max macros (we use std instead)

View File

@ -86,7 +86,7 @@ int _SPR0chain()
__fi void SPR0chain()
{
CPU_INT(DMAC_FROM_SPR, _SPR0chain() / BIAS);
CPU_INT(DMAC_FROM_SPR, _SPR0chain() * BIAS);
spr0ch.qwc = 0;
}
@ -102,7 +102,7 @@ void _SPR0interleave()
SPR_LOG("SPR0 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx",
spr0ch.qwc, tqwc, sqwc, spr0ch.madr, spr0ch.sadr);
CPU_INT(DMAC_FROM_SPR, qwc / BIAS);
CPU_INT(DMAC_FROM_SPR, qwc * BIAS);
while (qwc > 0)
{
@ -290,13 +290,14 @@ int _SPR1chain()
SPR1transfer(pMem, spr1ch.qwc);
spr1ch.madr += spr1ch.qwc * 16;
hwDmacSrcTadrInc(spr1ch);
return (spr1ch.qwc);
}
__fi void SPR1chain()
{
CPU_INT(DMAC_TO_SPR, _SPR1chain() / BIAS);
CPU_INT(DMAC_TO_SPR, _SPR1chain() * BIAS);
spr1ch.qwc = 0;
}
@ -310,7 +311,7 @@ void _SPR1interleave()
if (tqwc == 0) tqwc = qwc;
SPR_LOG("SPR1 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx",
spr1ch.qwc, tqwc, sqwc, spr1ch.madr, spr1ch.sadr);
CPU_INT(DMAC_TO_SPR, qwc / BIAS);
CPU_INT(DMAC_TO_SPR, qwc * BIAS);
while (qwc > 0)
{
spr1ch.qwc = std::min(tqwc, qwc);

View File

@ -70,8 +70,6 @@ void SaveStateBase::Init( SafeArray<u8>* memblock )
m_memory = memblock;
m_version = g_SaveVersion;
m_idx = 0;
m_sectid = FreezeId_Unknown;
m_pid = PluginId_GS;
m_DidBios = false;
}
@ -106,50 +104,45 @@ void SaveStateBase::FreezeTag( const char* src )
}
}
void SaveStateBase::FreezeBios()
SaveStateBase& SaveStateBase::FreezeBios()
{
FreezeTag( "BIOS" );
// Check the BIOS, and issue a warning if the bios for this state
// doesn't match the bios currently being used (chances are it'll still
// work fine, but some games are very picky).
u32 bioscheck = BiosChecksum;
char biosdesc[256];
char descin[128], desccmp[128];
wxString descout;
IsBIOS( g_Conf->FullpathToBios(), descout );
memzero( descin );
memzero( desccmp );
pxToUTF8 utf8(BiosDescription);
pxToUTF8 utf8(descout);
memcpy_fast( descin, utf8, utf8.Length() );
memcpy_fast( desccmp, utf8, utf8.Length() );
memzero( biosdesc );
memcpy_fast( biosdesc, utf8, std::min( sizeof(biosdesc), utf8.Length() ) );
Freeze( bioscheck );
Freeze( biosdesc );
// ... and only freeze bios info once per state, since the user msg could
// become really annoying on a corrupted state or something. (have to always
// load though, so that we advance past the duplicated info, if present)
if( IsLoading() || !m_DidBios )
Freeze( descin );
if( !m_DidBios )
if (bioscheck != BiosChecksum)
{
if( memcmp( descin, desccmp, 128 ) != 0 )
{
Console.Newline();
Console.Indent(1).Error( "Warning: BIOS Version Mismatch, savestate may be unstable!" );
Console.Indent(2).Error(
"Current Version: %s\n"
"Savestate Version: %s\n",
utf8.data(), descin
);
}
Console.Newline();
Console.Indent(1).Error( "Warning: BIOS Version Mismatch, savestate may be unstable!" );
Console.Indent(2).Error(
"Current BIOS: %ls (crc=0x%08x)\n"
"Savestate BIOS: %s (crc=0x%08x)\n",
BiosDescription.c_str(), BiosChecksum,
biosdesc, bioscheck
);
}
m_DidBios = true;
return *this;
}
static const uint MainMemorySizeInBytes =
Ps2MemSize::MainRam + Ps2MemSize::Scratch + Ps2MemSize::Hardware +
Ps2MemSize::IopRam + Ps2MemSize::IopHardware;
void SaveStateBase::FreezeMainMemory()
SaveStateBase& SaveStateBase::FreezeMainMemory()
{
if (IsLoading())
PreLoadPrep();
@ -170,9 +163,11 @@ void SaveStateBase::FreezeMainMemory()
FreezeMem(vuRegs[1].Micro, VU1_PROGSIZE);
FreezeMem(vuRegs[1].Mem, VU1_MEMSIZE);
return *this;
}
void SaveStateBase::FreezeRegisters()
SaveStateBase& SaveStateBase::FreezeInternals()
{
if( IsLoading() )
PreLoadPrep();
@ -229,138 +224,31 @@ void SaveStateBase::FreezeRegisters()
if( IsLoading() )
PostLoadPrep();
return *this;
}
void SaveStateBase::WritebackSectionLength( int seekpos, int sectlen, const wxChar* sectname )
SaveStateBase& SaveStateBase::FreezePlugins()
{
int realsectsize = m_idx - seekpos;
if( IsSaving() )
for (uint i=0; i<PluginId_Count; ++i)
{
// write back the section length...
*((u32*)m_memory->GetPtr(seekpos-4)) = realsectsize;
}
else // IsLoading!!
{
if( sectlen != realsectsize ) // if they don't match then we have a problem, jim.
{
throw Exception::SaveStateLoadError()
.SetDiagMsg(pxsFmt(L"Invalid size encountered on section '%s'.", sectname ))
.SetUserMsg(_("The savestate data is invalid or corrupted."));
}
FreezeTag( FastFormatAscii().Write("Plugin:%s", tbl_PluginInfo[i].shortname) );
GetCorePlugins().Freeze( (PluginsEnum_t)i, *this );
}
return *this;
}
bool SaveStateBase::FreezeSection( int seek_section )
SaveStateBase& SaveStateBase::FreezeAll()
{
const bool isSeeking = (seek_section != FreezeId_NotSeeking );
if( IsSaving() ) pxAssertDev( !isSeeking, "Cannot seek on a saving-mode savestate stream." );
Freeze( m_sectid );
if( seek_section == m_sectid ) return false;
switch( m_sectid )
{
case FreezeId_End:
return false;
case FreezeId_Bios:
{
int sectlen = 128;
FreezeTag( "BiosVersion" );
Freeze( sectlen );
if( sectlen != 128 )
{
throw Exception::SaveStateLoadError()
.SetDiagMsg(L"Invalid size encountered on BiosVersion section.")
.SetUserMsg(_("The savestate data is invalid or corrupted."));
}
if( isSeeking )
m_idx += sectlen;
else
FreezeBios();
m_sectid++;
}
break;
case FreezeId_Registers:
{
FreezeTag( "HardwareRegisters" );
int seekpos = m_idx+4;
int sectlen = 0xdead; // gets written back over with "real" data in IsSaving() mode
Freeze( sectlen );
FreezeRegisters();
WritebackSectionLength( seekpos, sectlen, L"HardwareRegisters" );
m_sectid++;
}
break;
case FreezeId_Plugin:
{
FreezeTag( "Plugin" );
int seekpos = m_idx+4;
int sectlen = 0xdead; // gets written back over with "real" data in IsSaving() mode
Freeze( sectlen );
Freeze( m_pid );
if( isSeeking )
m_idx += sectlen;
else
GetCorePlugins().Freeze( (PluginsEnum_t)m_pid, *this );
WritebackSectionLength( seekpos, sectlen, L"Plugins" );
// following increments only affect Saving mode, which needs to be sure to save all
// plugins (order doesn't matter but sequential is easy enough. (ignored by Loading mode)
m_pid++;
if( m_pid >= PluginId_Count )
m_sectid = FreezeId_End;
}
break;
case FreezeId_Unknown:
default:
pxAssert( IsSaving() );
// Skip unknown sections with a warning log.
// Maybe it'll work! (haha?)
int size;
Freeze( m_tagspace );
Freeze( size );
m_tagspace[sizeof(m_tagspace)-1] = 0;
Console.Warning(
"Warning: Unknown tag encountered while loading savestate; going to ignore it!\n"
"\tTagname: %s, Size: %d", m_tagspace, size
);
m_idx += size;
break;
}
if( wxThread::IsMain() )
wxSafeYield( NULL, true );
return true;
FreezeMainMemory();
FreezeBios();
FreezeInternals();
FreezePlugins();
return *this;
}
void SaveStateBase::FreezeAll()
{
if( IsSaving() )
{
// Loading mode streams will assign these, but saving mode reads them so better
// do some setup first.
m_sectid = (int)FreezeId_End+1;
m_pid = PluginId_GS;
}
while( FreezeSection() );
}
// --------------------------------------------------------------------------------------
// memSavingState (implementations)
@ -380,7 +268,9 @@ memSavingState::memSavingState( SafeArray<u8>* save_to )
// Saving of state data
void memSavingState::FreezeMem( void* data, int size )
{
m_memory->MakeRoomFor( m_idx+size );
if (!size) return;
m_memory->MakeRoomFor( m_idx + size );
memcpy_fast( m_memory->GetPtr(m_idx), data, size );
m_idx += size;
}
@ -394,10 +284,11 @@ void memSavingState::MakeRoomForData()
}
// Saving of state data to a memory buffer
void memSavingState::FreezeAll()
memSavingState& memSavingState::FreezeAll()
{
MakeRoomForData();
_parent::FreezeAll();
return *this;
}
// --------------------------------------------------------------------------------------
@ -423,25 +314,6 @@ void memLoadingState::FreezeMem( void* data, int size )
memcpy_fast( data, src, size );
}
bool memLoadingState::SeekToSection( PluginsEnum_t pid )
{
m_idx = 0; // start from the beginning
do
{
while( FreezeSection( FreezeId_Plugin ) );
if( m_sectid == FreezeId_End ) return false;
FreezeTag( "Plugin" );
int sectlen = 0xdead;
Freeze( sectlen );
Freeze( m_pid );
} while( m_pid != pid );
return true;
}
// --------------------------------------------------------------------------------------
// SaveState Exception Messages
// --------------------------------------------------------------------------------------

View File

@ -31,21 +31,6 @@ static const u32 g_SaveVersion = (0x9A01 << 16) | 0x0000;
extern s32 CALLBACK gsSafeFreeze( int mode, freezeData *data );
enum FreezeSectionId
{
FreezeId_NotSeeking = -2,
FreezeId_End,
// A BIOS tag should always be saved in conjunction with Memory or Registers tags,
// but can be skipped if the savestate has only plugins.
FreezeId_Bios,
FreezeId_Registers,
FreezeId_Plugin,
// anything here and beyond we can skip, with a warning
FreezeId_Unknown,
};
namespace Exception
{
// ---------------------------------------------------------------------------------------
@ -119,8 +104,6 @@ protected:
u32 m_version; // version of the savestate being loaded.
int m_idx; // current read/write index of the allocation
int m_sectid;
int m_pid;
bool m_DidBios;
@ -141,9 +124,12 @@ public:
// Loads or saves the entire emulation state.
// Note: The Cpu state must be reset, and plugins *open*, prior to Defrosting
// (loading) a state!
virtual void FreezeAll();
virtual SaveStateBase& FreezeAll();
void FreezeMainMemory();
virtual SaveStateBase& FreezeMainMemory();
virtual SaveStateBase& FreezeBios();
virtual SaveStateBase& FreezeInternals();
virtual SaveStateBase& FreezePlugins();
// Loads or saves an arbitrary data type. Usable on atomic types, structs, and arrays.
// For dynamically allocated pointers use FreezeMem instead.
@ -183,9 +169,6 @@ public:
m_idx += size;
}
void WritebackSectionLength( int seekpos, int sectlen, const wxChar* sectname );
bool FreezeSection( int seek_section = FreezeId_NotSeeking );
// Freezes an identifier value into the savestate for troubleshooting purposes.
// Identifiers can be used to determine where in a savestate that data has become
// skewed (if the value does not match then the error occurs somewhere prior to that
@ -210,9 +193,6 @@ protected:
// Load/Save functions for the various components of our glorious emulator!
void FreezeBios();
void FreezeRegisters();
void rcntFreeze();
void vuMicroFreeze();
void vif0Freeze();
@ -257,7 +237,7 @@ public:
void MakeRoomForData();
void FreezeMem( void* data, int size );
void FreezeAll();
memSavingState& FreezeAll();
bool IsSaving() const { return true; }
};
@ -271,7 +251,6 @@ public:
memLoadingState( const VmStateBuffer* load_from );
void FreezeMem( void* data, int size );
bool SeekToSection( PluginsEnum_t pid );
bool IsSaving() const { return false; }
bool IsFinished() const { return m_idx >= m_memory->GetSizeInBytes(); }

View File

@ -52,6 +52,7 @@ static __fi bool WriteEEtoFifo()
sif1.fifo.write((u32*)ptag, writeSize << 2);
sif1dma.madr += writeSize << 4;
hwDmacSrcTadrInc(sif1dma);
sif1.ee.cycles += writeSize; // fixme : BIAS is factored in above
sif1dma.qwc -= writeSize;
@ -114,8 +115,8 @@ static __fi bool ProcessEETag()
break;
case TAG_CNT:
sif1dma.madr = sif1dma.tadr + 16;
sif1dma.tadr = sif1dma.madr + (sif1dma.qwc << 4);
sif1dma.tadr += 16;
sif1dma.madr = sif1dma.tadr;
break;
case TAG_NEXT:
@ -132,7 +133,7 @@ static __fi bool ProcessEETag()
case TAG_END:
sif1.ee.end = true;
sif1dma.madr = sif1dma.tadr + 16;
sif1dma.tadr = sif1dma.madr + (sif1dma.qwc << 4);
//sif1dma.tadr = sif1dma.madr + (sif1dma.qwc << 4);
break;
default:

View File

@ -93,27 +93,27 @@ static const TraceLogDescriptor
TLD_ELF = {
L"ELF", L"ELF",
wxLt("Dumps detailed information for PS2 executables (ELFs).")
pxDt("Dumps detailed information for PS2 executables (ELFs).")
},
TLD_eeRecPerf = {
L"EErecPerf", L"EErec Performance",
wxLt("Logs manual protection, split blocks, and other things that might impact performance.")
pxDt("Logs manual protection, split blocks, and other things that might impact performance.")
},
TLD_eeConsole = {
L"EEout", L"EE Console",
wxLt("Shows the game developer's logging text (EE processor)")
pxDt("Shows the game developer's logging text (EE processor)")
},
TLD_iopConsole = {
L"IOPout", L"IOP Console",
wxLt("Shows the game developer's logging text (IOP processor)")
pxDt("Shows the game developer's logging text (IOP processor)")
},
TLD_deci2 = {
L"DECI2", L"DECI2 Console",
wxLt("Shows DECI2 debugging logs (EE processor)")
pxDt("Shows DECI2 debugging logs (EE processor)")
};
SysConsoleLogPack::SysConsoleLogPack()
@ -131,7 +131,7 @@ SysConsoleLogPack::SysConsoleLogPack()
static const SysTraceLogDescriptor
TLD_SIF = {
L"SIF", L"SIF (EE <-> IOP)",
wxLt(""),
pxDt(""),
"SIF"
};
@ -142,109 +142,109 @@ TLD_SIF = {
static const SysTraceLogDescriptor
TLD_EE_Bios = {
L"Bios", L"Bios",
wxLt("SYSCALL and DECI2 activity."),
pxDt("SYSCALL and DECI2 activity."),
"EE"
},
TLD_EE_Memory = {
L"Memory", L"Memory",
wxLt("Direct memory accesses to unknown or unmapped EE memory space."),
pxDt("Direct memory accesses to unknown or unmapped EE memory space."),
"eMem"
},
TLD_EE_R5900 = {
L"R5900", L"R5900 Core",
wxLt("Disasm of executing core instructions (excluding COPs and CACHE)."),
pxDt("Disasm of executing core instructions (excluding COPs and CACHE)."),
"eDis"
},
TLD_EE_COP0 = {
L"COP0", L"COP0",
wxLt("Disasm of COP0 instructions (MMU, cpu and dma status, etc)."),
pxDt("Disasm of COP0 instructions (MMU, cpu and dma status, etc)."),
"eDis"
},
TLD_EE_COP1 = {
L"FPU", L"COP1/FPU",
wxLt("Disasm of the EE's floating point unit (FPU) only."),
pxDt("Disasm of the EE's floating point unit (FPU) only."),
"eDis"
},
TLD_EE_COP2 = {
L"VUmacro", L"COP2/VUmacro",
wxLt("Disasm of the EE's VU0macro co-processor instructions."),
pxDt("Disasm of the EE's VU0macro co-processor instructions."),
"eDis"
},
TLD_EE_Cache = {
L"Cache", L"Cache",
wxLt("Execution of EE cache instructions."),
pxDt("Execution of EE cache instructions."),
"eDis"
},
TLD_EE_KnownHw = {
L"HwRegs", L"Hardware Regs",
wxLt("All known hardware register accesses (very slow!); not including sub filter options below."),
pxDt("All known hardware register accesses (very slow!); not including sub filter options below."),
"eReg"
},
TLD_EE_UnknownHw = {
L"UnknownRegs", L"Unknown Regs",
wxLt("Logs only unknown, unmapped, or unimplemented register accesses."),
pxDt("Logs only unknown, unmapped, or unimplemented register accesses."),
"eReg"
},
TLD_EE_DMAhw = {
L"DmaRegs", L"DMA Regs",
wxLt("Logs only DMA-related registers."),
pxDt("Logs only DMA-related registers."),
"eReg"
},
TLD_EE_IPU = {
L"IPU", L"IPU",
wxLt("IPU activity: hardware registers, decoding operations, DMA status, etc."),
pxDt("IPU activity: hardware registers, decoding operations, DMA status, etc."),
"IPU"
},
TLD_EE_GIFtag = {
L"GIFtags", L"GIFtags",
wxLt("All GIFtag parse activity; path index, tag type, etc."),
pxDt("All GIFtag parse activity; path index, tag type, etc."),
"GIF"
},
TLD_EE_VIFcode = {
L"VIFcodes", L"VIFcodes",
wxLt("All VIFcode processing; command, tag style, interrupts."),
pxDt("All VIFcode processing; command, tag style, interrupts."),
"VIF"
},
TLD_EE_SPR = {
L"MFIFO", L"Scratchpad MFIFO",
wxLt("Scratchpad's MFIFO activity."),
pxDt("Scratchpad's MFIFO activity."),
"SPR"
},
TLD_EE_DMAC = {
L"DmaCtrl", L"DMA Controller",
wxLt("Actual data transfer logs, bus right arbitration, stalls, etc."),
pxDt("Actual data transfer logs, bus right arbitration, stalls, etc."),
"eDmaC"
},
TLD_EE_Counters = {
L"Counters", L"Counters",
wxLt("Tracks all EE counters events and some counter register activity."),
pxDt("Tracks all EE counters events and some counter register activity."),
"eCnt"
},
TLD_EE_VIF = {
L"VIF", L"VIF",
wxLt("Dumps various VIF and VIFcode processing data."),
pxDt("Dumps various VIF and VIFcode processing data."),
"VIF"
},
TLD_EE_GIF = {
L"GIF", L"GIF",
wxLt("Dumps various GIF and GIFtag parsing data."),
pxDt("Dumps various GIF and GIFtag parsing data."),
"GIF"
};
@ -255,73 +255,73 @@ TLD_EE_GIF = {
static const SysTraceLogDescriptor
TLD_IOP_Bios = {
L"Bios", L"Bios",
wxLt("SYSCALL and IRX activity."),
pxDt("SYSCALL and IRX activity."),
"IOP"
},
TLD_IOP_Memory = {
L"Memory", L"Memory",
wxLt("Direct memory accesses to unknown or unmapped IOP memory space."),
pxDt("Direct memory accesses to unknown or unmapped IOP memory space."),
"iMem"
},
TLD_IOP_R3000A = {
L"R3000A", L"R3000A Core",
wxLt("Disasm of executing core instructions (excluding COPs and CACHE)."),
pxDt("Disasm of executing core instructions (excluding COPs and CACHE)."),
"iDis"
},
TLD_IOP_COP2 = {
L"COP2/GPU", L"COP2",
wxLt("Disasm of the IOP's GPU co-processor instructions."),
pxDt("Disasm of the IOP's GPU co-processor instructions."),
"iDis"
},
TLD_IOP_KnownHw = {
L"HwRegs", L"Hardware Regs",
wxLt("All known hardware register accesses, not including the sub-filters below."),
pxDt("All known hardware register accesses, not including the sub-filters below."),
"iReg"
},
TLD_IOP_UnknownHw = {
L"UnknownRegs", L"Unknown Regs",
wxLt("Logs only unknown, unmapped, or unimplemented register accesses."),
pxDt("Logs only unknown, unmapped, or unimplemented register accesses."),
"iReg"
},
TLD_IOP_DMAhw = {
L"DmaRegs", L"DMA Regs",
wxLt("Logs only DMA-related registers."),
pxDt("Logs only DMA-related registers."),
"iReg"
},
TLD_IOP_Memcards = {
L"Memorycards", L"Memorycards",
wxLt("Memorycard reads, writes, erases, terminators, and other processing."),
pxDt("Memorycard reads, writes, erases, terminators, and other processing."),
"Mcd"
},
TLD_IOP_PAD = {
L"Pad", L"Pad",
wxLt("Gamepad activity on the SIO."),
pxDt("Gamepad activity on the SIO."),
"Pad"
},
TLD_IOP_DMAC = {
L"DmaCrl", L"DMA Controller",
wxLt("Actual DMA event processing and data transfer logs."),
pxDt("Actual DMA event processing and data transfer logs."),
"iDmaC"
},
TLD_IOP_Counters = {
L"Counters", L"Counters",
wxLt("Tracks all IOP counters events and some counter register activity."),
pxDt("Tracks all IOP counters events and some counter register activity."),
"iCnt"
},
TLD_IOP_CDVD = {
L"CDVD", L"CDVD",
wxLt("Detailed logging of CDVD hardware."),
pxDt("Detailed logging of CDVD hardware."),
"CDVD"
};

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 "
@ -133,25 +130,25 @@ void SysOutOfMemory_EmergencyResponse(uptr blocksize)
if (Cpu)
{
Cpu->SetCacheReserve( (Cpu->GetCacheReserve() * 3) / 2 );
Cpu->SetCacheReserve( (Cpu->GetCacheReserve() * 2) / 3 );
Cpu->Reset();
}
if (CpuVU0)
{
CpuVU0->SetCacheReserve( (CpuVU0->GetCacheReserve() * 3) / 2 );
CpuVU0->SetCacheReserve( (CpuVU0->GetCacheReserve() * 2) / 3 );
CpuVU0->Reset();
}
if (CpuVU1)
{
CpuVU1->SetCacheReserve( (CpuVU1->GetCacheReserve() * 3) / 2 );
CpuVU1->SetCacheReserve( (CpuVU1->GetCacheReserve() * 2) / 3 );
CpuVU1->Reset();
}
if (psxCpu)
{
psxCpu->SetCacheReserve( (psxCpu->GetCacheReserve() * 3) / 2 );
psxCpu->SetCacheReserve( (psxCpu->GetCacheReserve() * 2) / 3 );
psxCpu->Reset();
}
}
@ -201,30 +198,37 @@ TraceLogFilters& SetTraceConfig()
// This function should be called once during program execution.
void SysLogMachineCaps()
{
Console.WriteLn( Color_StrongGreen, "PCSX2 %u.%u.%u.r%d %s - compiled on " __DATE__, PCSX2_VersionHi, PCSX2_VersionMid, PCSX2_VersionLo,
Console.WriteLn( Color_StrongGreen, "PCSX2 %u.%u.%u.r%d %s - compiled on " __DATE__,
PCSX2_VersionHi, PCSX2_VersionMid, PCSX2_VersionLo,
SVN_REV, SVN_MODS ? "(modded)" : ""
);
Console.WriteLn( "Savestate version: 0x%x", g_SaveVersion);
Console.Newline();
Console.WriteLn( Color_StrongBlack, "x86-32 Init:" );
Console.WriteLn( Color_StrongBlack, "Host Machine Init:" );
Console.Indent().WriteLn(
L"Operating System = %s\n"
L"Physical RAM = %u MB",
GetOSVersionString().c_str(),
(u32)(GetPhysicalMemory() / _1mb)
);
u32 speed = x86caps.CalculateMHz();
Console.Indent().WriteLn(
L"CPU vendor name = %s\n"
L"FamilyID = %x\n"
L"x86Family = %s\n"
L"CPU speed = %d.%03d ghz\n"
L"Cores = %d physical [%d logical]\n"
L"CPU name = %s\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 = %8.8x %8.8x\n"
L"x86EFlags = %8.8x",
fromUTF8( x86caps.VendorName ).c_str(), x86caps.StepID,
L"x86Flags = %08x %08x\n"
L"x86EFlags = %08x",
fromUTF8( x86caps.FamilyName ).Trim().Trim(false).c_str(),
fromUTF8( x86caps.VendorName ).c_str(), x86caps.StepID,
speed / 1000, speed % 1000,
x86caps.PhysicalCores, x86caps.LogicalCores,
x86caps.LogicalCores, (x86caps.LogicalCores==1) ? L"" : L"s",
x86caps.GetTypeName().c_str(),
x86caps.Flags, x86caps.Flags2,
x86caps.EFlags
@ -339,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."
);
@ -598,7 +602,7 @@ wxString SysGetDiscID()
if( !ElfCRC )
{
// FIXME: If the system is currently running the BIOS, it should return a serial based on
// FIXME: system is currently running the BIOS, so it should return a serial based on
// the BIOS being run (either a checksum of the BIOS roms, and/or a string based on BIOS
// region and revision).
}

View File

@ -151,7 +151,6 @@ void SysCoreThread::UploadStateCopy( const VmStateBuffer& copy )
if( !pxAssertDev( IsPaused(), "CoreThread is not paused; new VM state cannot be uploaded." ) ) return;
memLoadingState loadme( copy );
loadme.FreezeMainMemory();
loadme.FreezeAll();
m_resetVirtualMachine = false;
}

View File

@ -77,12 +77,16 @@ __fi void vif0FBRST(u32 value) {
memzero(vif0);
vif0ch.qwc = 0; //?
cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
//cpuRegs.interrupt &= ~1; //Stop all vif0 DMA's
psHu64(VIF0_FIFO) = 0;
psHu64(VIF0_FIFO + 8) = 0;
vif0.done = false;
vif0.vifstalled = false;
vif0.inprogress = 0;
vif0.cmd = 0;
//vif0.done = false;
vif0Regs.err.reset();
vif0Regs.stat.clear_flags(VIF0_STAT_FQC | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0
if(vif0ch.chcr.STR == true) CPU_INT(DMAC_VIF0, 4);
}
/* Fixme: Forcebreaks are pretty unknown for operation, presumption is it just stops it what its doing
@ -137,7 +141,8 @@ __fi void vif1FBRST(u32 value) {
memzero(vif1);
//cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
vif1ch.qwc -= min((int)vif1ch.qwc, 16); //?
//vif1ch.qwc -= min((int)vif1ch.qwc, 16); //not sure if the dma should stop, FFWDing could be tricky
vif1ch.qwc = 0;
psHu64(VIF1_FIFO) = 0;
psHu64(VIF1_FIFO + 8) = 0;
//vif1.done = false;
@ -160,6 +165,7 @@ __fi void vif1FBRST(u32 value) {
vif1.vifstalled = false;
vif1Regs.stat.FQC = 0;
vif1Regs.stat.clear_flags(VIF1_STAT_FDR | VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS | VIF1_STAT_VPS);
if(vif1ch.chcr.STR == true) CPU_INT(DMAC_VIF1, 4);
}
/* Fixme: Forcebreaks are pretty unknown for operation, presumption is it just stops it what its doing

View File

@ -155,9 +155,9 @@ bool _VIF1chain()
vif1ch.qwc, vif1ch.madr, vif1ch.tadr);
if (vif1.vifstalled)
return VIF1transfer(pMem + vif1.irqoffset, vif1ch.qwc * 4 - vif1.irqoffset);
return VIF1transfer(pMem + vif1.irqoffset, vif1ch.qwc * 4 - vif1.irqoffset, false);
else
return VIF1transfer(pMem, vif1ch.qwc * 4);
return VIF1transfer(pMem, vif1ch.qwc * 4, false);
}
__fi void vif1SetupTransfer()
@ -490,7 +490,7 @@ void dmaVIF1()
if(vif1ch.chcr.MOD == CHAIN_MODE && vif1.dmamode != VIF_NORMAL_TO_MEM_MODE)
{
vif1.dmamode = VIF_CHAIN_MODE;
DevCon.Warning(L"VIF1 QWC on Chain CHCR " + vif1ch.chcr.desc());
//DevCon.Warning(L"VIF1 QWC on Chain CHCR " + vif1ch.chcr.desc());
if ((vif1ch.chcr.tag().ID == TAG_REFE) || (vif1ch.chcr.tag().ID == TAG_END))
{
@ -502,6 +502,7 @@ void dmaVIF1()
{
vif1.dmamode = VIF_CHAIN_MODE;
vif1.done = false;
vif1.inprogress = 0;
}
if (vif1ch.chcr.DIR) vif1Regs.stat.FQC = min((u16)0x10, vif1ch.qwc);

View File

@ -32,14 +32,39 @@ static u32 qwctag(u32 mask)
return (dmacRegs.rbor.ADDR + (mask & dmacRegs.rbsr.RMSK));
}
static u16 QWCinVIFMFIFO(u32 DrainADDR)
{
u32 ret;
SPR_LOG("VIF MFIFO Requesting %x QWC from the MFIFO Base %x, SPR MADR %x Drain %x", vif1ch.qwc, dmacRegs.rbor.ADDR, spr0ch.madr, DrainADDR);
//Calculate what we have in the fifo.
if(DrainADDR <= spr0ch.madr)
{
//Drain is below the tadr, calculate the difference between them
ret = (spr0ch.madr - DrainADDR) >> 4;
}
else
{
u32 limit = dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16;
//Drain is higher than SPR so it has looped round,
//calculate from base to the SPR tag addr and what is left in the top of the ring
ret = ((spr0ch.madr - dmacRegs.rbor.ADDR) + (limit - DrainADDR)) >> 4;
}
SPR_LOG("%x Available of the %x requested", ret, vif1ch.qwc);
return ret;
}
static __fi bool mfifoVIF1rbTransfer()
{
u32 maddr = dmacRegs.rbor.ADDR;
u32 msize = dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16;
u16 mfifoqwc = std::min(vif1ch.qwc, vifqwc);
u16 mfifoqwc = min(QWCinVIFMFIFO(vif1ch.madr), vif1ch.qwc);
u32 *src;
bool ret;
if(mfifoqwc == 0) return true; //Cant do anything, lets forget it
/* Check if the transfer should wrap around the ring buffer */
if ((vif1ch.madr + (mfifoqwc << 4)) > (msize))
{
@ -48,6 +73,8 @@ static __fi bool mfifoVIF1rbTransfer()
SPR_LOG("Split MFIFO");
/* it does, so first copy 's1' bytes from 'addr' to 'data' */
vif1ch.madr = qwctag(vif1ch.madr);
src = (u32*)PSM(vif1ch.madr);
if (src == NULL) return false;
@ -56,10 +83,9 @@ static __fi bool mfifoVIF1rbTransfer()
else
ret = VIF1transfer(src, s1);
vif1ch.madr = qwctag(vif1ch.madr);
if (ret)
{
if(vif1.irqoffset != 0) DevCon.Warning("VIF1 MFIFO Offest != 0! vifoffset=%x", vif1.irqoffset);
/* and second copy 's2' bytes from 'maddr' to '&data[s1]' */
vif1ch.madr = maddr;
@ -67,13 +93,12 @@ static __fi bool mfifoVIF1rbTransfer()
if (src == NULL) return false;
VIF1transfer(src, ((mfifoqwc << 2) - s1));
}
vif1ch.madr = qwctag(vif1ch.madr);
}
else
{
SPR_LOG("Direct MFIFO");
/* it doesn't, so just transfer 'qwc*4' words */
src = (u32*)PSM(vif1ch.madr);
if (src == NULL) return false;
@ -83,8 +108,6 @@ static __fi bool mfifoVIF1rbTransfer()
else
ret = VIF1transfer(src, mfifoqwc << 2);
vif1ch.madr = qwctag(vif1ch.madr);
}
return ret;
}
@ -99,13 +122,17 @@ static __fi void mfifo_VIF1chain()
}
if (vif1ch.madr >= dmacRegs.rbor.ADDR &&
vif1ch.madr <= (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK))
{
//Need to exit on mfifo locations, if the madr is matching the madr of spr, we dont have any data left :(
u16 startqwc = vif1ch.qwc;
vif1ch.madr <= (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16))
{
if(vif1ch.madr == (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16)) DevCon.Warning("Edge VIF1");
vif1ch.madr = qwctag(vif1ch.madr);
mfifoVIF1rbTransfer();
vifqwc -= startqwc - vif1ch.qwc;
vif1ch.tadr = qwctag(vif1ch.tadr);
vif1ch.madr = qwctag(vif1ch.madr);
if(QWCinVIFMFIFO(vif1ch.madr) == 0) vif1.inprogress |= 0x10;
//vifqwc -= startqwc - vif1ch.qwc;
}
else
@ -124,8 +151,6 @@ static __fi void mfifo_VIF1chain()
}
}
int NextTADR = 0; //Bodge for Clock Tower 3 (see below)
void mfifoVIF1transfer(int qwc)
{
tDMA_TAG *ptag;
@ -134,11 +159,15 @@ void mfifoVIF1transfer(int qwc)
if (qwc > 0)
{
vifqwc += qwc;
SPR_LOG("Added %x qw to mfifo, total now %x - Vif CHCR %x Stalled %x done %x", qwc, vifqwc, vif1ch.chcr._u32, vif1.vifstalled, vif1.done);
//vifqwc += qwc;
SPR_LOG("Added %x qw to mfifo, total now %x - Vif CHCR %x Stalled %x done %x", qwc, vif1ch.chcr._u32, vif1.vifstalled, vif1.done);
if (vif1.inprogress & 0x10)
{
if(vif1ch.chcr.STR == true)CPU_INT(DMAC_MFIFO_VIF, 4);
if(vif1ch.chcr.STR == true && !(cpuRegs.interrupt & (1<<DMAC_MFIFO_VIF)))
{
SPR_LOG("Data Added, Resuming");
CPU_INT(DMAC_MFIFO_VIF, 4);
}
vif1Regs.stat.FQC = 0x10; // FQC=16
}
@ -147,8 +176,9 @@ void mfifoVIF1transfer(int qwc)
return;
}
if (vif1ch.qwc == 0 && vifqwc > 0)
if (vif1ch.qwc == 0)
{
vif1ch.tadr = qwctag(vif1ch.tadr);
ptag = dmaGetAddr(vif1ch.tadr, false);
if (vif1ch.chcr.TTE)
@ -169,63 +199,32 @@ void mfifoVIF1transfer(int qwc)
}
else
{
ret = VIF1transfer((u32*)&masked_tag, 4, true); //Transfer Tag
vif1.irqoffset = 2;
ret = VIF1transfer((u32*)&masked_tag + 2, 2, true); //Transfer Tag
//ret = VIF1transfer((u32*)ptag + 2, 2); //Transfer Tag
}
if (!ret && vif1.irqoffset)
{
vif1.inprogress &= ~1;
return; //IRQ set by VIFTransfer
} //else vif1.vifstalled = false;
g_vifCycles += 2;
}
vif1.irqoffset = 0;
vif1ch.unsafeTransfer(ptag);
vif1ch.madr = ptag[1]._u32;
vifqwc--;
//vifqwc--;
SPR_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x",
ptag[1]._u32, ptag[0]._u32, vif1ch.qwc, ptag->ID, vif1ch.madr, vif1ch.tadr, vifqwc, spr0ch.madr);
switch (ptag->ID)
{
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
NextTADR = qwctag(vif1ch.tadr + 16);
vif1.done = true; //End Transfer
break;
case TAG_CNT: // CNT - Transfer QWC following the tag.
vif1ch.madr = qwctag(vif1ch.tadr + 16); //Set MADR to QW after Tag
NextTADR = qwctag(vif1ch.madr + (vif1ch.qwc << 4)); //Set TADR to QW following the data
vif1.done = false;
break;
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
{
int temp = vif1ch.madr; //Temporarily Store ADDR
vif1ch.madr = qwctag(vif1ch.tadr + 16); //Set MADR to QW following the tag
NextTADR = temp; //Copy temporarily stored ADDR to Tag
if ((temp & dmacRegs.rbsr.RMSK) != dmacRegs.rbor.ADDR) Console.WriteLn("Next tag = %x outside ring %x size %x", temp, psHu32(DMAC_RBOR), psHu32(DMAC_RBSR));
vif1.done = false;
break;
}
case TAG_REF: // Ref - Transfer QWC from ADDR field
case TAG_REFS: // Refs - Transfer QWC from ADDR field (Stall Control)
NextTADR = qwctag(vif1ch.tadr + 16); //Set TADR to next tag
vif1.done = false;
break;
case TAG_END: // End - Transfer QWC following the tag
vif1ch.madr = qwctag(vif1ch.tadr + 16); //Set MADR to data following the tag
NextTADR = qwctag(vif1ch.madr + (vif1ch.qwc << 4)); //Set TADR to QW following the data
vif1.done = true; //End Transfer
break;
}
vif1.done |= hwDmacSrcChainWithStack(vif1ch, ptag->ID);
if (vif1ch.chcr.TIE && ptag->IRQ)
{
@ -233,8 +232,16 @@ void mfifoVIF1transfer(int qwc)
vif1.done = true;
}
vif1Regs.stat.FQC = min(vif1ch.qwc, (u16)16);
vif1.inprogress |= 1;
if(vif1ch.qwc > 0) vif1.inprogress |= 1;
vif1ch.tadr = qwctag(vif1ch.tadr);
if(QWCinVIFMFIFO(vif1ch.tadr) == 0) vif1.inprogress |= 0x10;
}
else
{
DevCon.Warning("Vif MFIFO QWC not 0 on tag");
}
@ -247,14 +254,10 @@ void vifMFIFOInterrupt()
VIF_LOG("vif mfifo interrupt");
if(NextTADR != 0 && vif1ch.qwc == 0)
if (dmacRegs.ctrl.MFD != MFD_VIF1)
{
// Clock Tower 3 Note!
/* If the DMA starts the transfer then hammers the TADR to see when the transfer has finished(as clock tower does)
and we have preincremented before all data has arrived, it breaks. Idealy we increment this as we transfer the data.
"NextTADR" bodge in for the moment! - Refraction */
vif1ch.tadr = NextTADR;
NextTADR = 0;
DevCon.Warning("Not in VIF MFIFO mode! Stopping VIF MFIFO");
return;
}
if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH2)
@ -269,7 +272,11 @@ void vifMFIFOInterrupt()
if (schedulepath3msk & 0x10) Vif1MskPath3();
if(vif1ch.chcr.DIR && CheckPath2GIF(DMAC_MFIFO_VIF) == false) return;
if(vif1ch.chcr.DIR && CheckPath2GIF(DMAC_MFIFO_VIF) == false)
{
SPR_LOG("Waiting for PATH to be ready");
return;
}
//We need to check the direction, if it is downloading from the GS, we handle that seperately (KH2 for testing)
//Simulated GS transfer time done, clear the flags
@ -283,8 +290,10 @@ void vifMFIFOInterrupt()
vif1Regs.stat.VPS = VPS_IDLE;
}
if (vif1.irq && vif1.tag.size == 0)
{
SPR_LOG("VIF MFIFO Code Interrupt detected");
vif1Regs.stat.INT = true;
hwIntcIrq(INTC_VIF1);
--vif1.irq;
@ -293,55 +302,40 @@ void vifMFIFOInterrupt()
{
/*vif1Regs.stat.FQC = 0; // FQC=0
vif1ch.chcr.STR = false;*/
if(vif1ch.qwc > 0 || !vif1.done) return;
if((vif1ch.qwc > 0 || !vif1.done) && !(vif1.inprogress & 0x10)) return;
}
}
if(vif1.inprogress & 0x10)
{
FireMFIFOEmpty();
if(!(vif1.done && vif1ch.qwc == 0))return;
}
if (vif1.done == false || vif1ch.qwc)
{
switch(vif1.inprogress & 1)
{
case 0: //Set up transfer
if (vif1ch.tadr == spr0ch.madr)
if (QWCinVIFMFIFO(vif1ch.tadr) == 0)
{
// Console.WriteLn("Empty 1");
vifqwc = 0;
if((vif1.inprogress & 0x10) == 0)
{
hwDmacIrq(DMAC_MFIFO_EMPTY);
vif1.inprogress |= 0x10;
}
vif1Regs.stat.FQC = 0;
vif1.inprogress |= 0x10;
CPU_INT(DMAC_MFIFO_VIF, 4 );
return;
}
mfifoVIF1transfer(0);
CPU_INT(DMAC_MFIFO_VIF, 4);
return;
case 1: //Transfer data
mfifo_VIF1chain();
//Sanity check! making sure we always have non-zero values
CPU_INT(DMAC_MFIFO_VIF, (g_vifCycles == 0 ? 4 : g_vifCycles) );
CPU_INT(DMAC_MFIFO_VIF, (g_vifCycles == 0 ? 4 : g_vifCycles) );
return;
}
return;
}
}
//FF7 Dirge of Cerberus seems to like the mfifo to tell it when it's empty, even if it's ending.
//Doesn't seem to care about the vif1 dma interrupting (possibly disabled the interrupt?)
if (vif1ch.tadr == spr0ch.madr)
{
vifqwc = 0;
if((vif1.inprogress & 0x10) == 0)
{
hwDmacIrq(DMAC_MFIFO_EMPTY);
vif1.inprogress |= 0x10;
}
}
vif1.vifstalled = false;
vif1.done = 1;
g_vifCycles = 0;

View File

@ -115,6 +115,8 @@ vifOp(vifCode_Base) {
}
extern bool SIGNAL_IMR_Pending;
static __aligned16 u32 partial_write[4];
static uint partial_count = 0;
template<int idx> __fi int _vifCode_Direct(int pass, const u8* data, bool isDirectHL) {
pass1 {
@ -154,7 +156,7 @@ template<int idx> __fi int _vifCode_Direct(int pass, const u8* data, bool isDire
}
if(SIGNAL_IMR_Pending == true)
{
DevCon.Warning("Path 2 Paused (At start)");
//DevCon.Warning("Path 2 Paused (At start)");
vif1.vifstalled = true;
return 0;
}
@ -175,7 +177,7 @@ template<int idx> __fi int _vifCode_Direct(int pass, const u8* data, bool isDire
uint minSize = aMin(vif1.vifpacketsize, vif1.tag.size);
uint ret;
if(minSize < 4)
if(minSize < 4 || partial_count > 0)
{
// When TTE==1, the VIF might end up sending us 8-byte packets instead of the usual 16-byte
// variety, if DIRECT tags cross chain dma boundaries. The actual behavior of real hardware
@ -189,21 +191,24 @@ template<int idx> __fi int _vifCode_Direct(int pass, const u8* data, bool isDire
// be any need to worry about queuing more than 16 bytes of data,
//
static __aligned16 u32 partial_write[4];
static uint partial_count = 0;
ret = 0;
minSize = aMin(minSize, 4-partial_count);
for( uint i=0; i<(minSize & 3); ++i)
{
partial_write[partial_count++] = ((u32*)data)[i];
ret++;
}
pxAssume( partial_count <= 4 );
ret = 0;
if (partial_count == 4)
{
GetMTGS().PrepDataPacket(GIF_PATH_2, 1);
GIFPath_CopyTag(GIF_PATH_2, (u128*)partial_write, 1);
GetMTGS().SendDataPacket();
partial_count = 0;
ret = 4;
}
}
else
@ -372,14 +377,16 @@ vifOp(vifCode_MSCNT) {
vifOp(vifCode_MskPath3) {
vif1Only();
pass1 {
//I Hate the timing sensitivity of this stuff
if (vif1ch.chcr.STR && vif1.lastcmd != 0x13) {
schedulepath3msk = 0x10 | ((vif1Regs.code >> 15) & 0x1);
vif1.vifstalled = true;
schedulepath3msk = 0x10 | ((vif1Regs.code >> 15) & 0x1);
}
else {
else
{
schedulepath3msk = (vif1Regs.code >> 15) & 0x1;
Vif1MskPath3();
}
if(vif1ch.chcr.STR)vif1.vifstalled = true;
vif1.cmd = 0;
}
pass3 { VifCodeLog("MskPath3"); }

View File

@ -25,7 +25,7 @@
// Doesn't stall if the next vifCode is the Mark command
_vifT bool runMark(u32* &data) {
if (((vifXRegs.code >> 24) & 0x7f) == 0x7) {
DevCon.WriteLn("Vif%d: Running Mark with I-bit", idx);
//DevCon.WriteLn("Vif%d: Running Mark with I-bit", idx);
return 1; // No Stall?
}
return 1; // Stall
@ -145,12 +145,21 @@ _vifT static __fi bool vifTransfer(u32 *data, int size, bool TTE) {
vifXch.madr +=(transferred << 4);
vifXch.qwc -= transferred;
}
if(vifXch.chcr.STR)hwDmacSrcTadrInc(vifXch);
if (!vifXch.qwc && !vifX.irqoffset)
if (!vifXch.qwc)
{
vifX.inprogress &= ~0x1;
vifX.vifstalled = false;
}
}
else
{
vifX.inprogress &= ~0x1;
vifX.vifstalled = false;
if(!vifX.irqoffset)
{
vifX.vifstalled = false;
}
}
if (vifX.irq && vifX.cmd == 0) {

View File

@ -21,22 +21,6 @@
using namespace Threading;
// --------------------------------------------------------------------------------------
// BaseArchiveEntry
// --------------------------------------------------------------------------------------
class BaseArchiveEntry
{
protected:
BaseArchiveEntry() {}
virtual ~BaseArchiveEntry() throw() {}
public:
virtual wxString GetFilename() const=0;
virtual u8* GetDataPtr() const=0;
virtual uint GetDataSize() const=0;
};
// --------------------------------------------------------------------------------------
// ArchiveEntry
// --------------------------------------------------------------------------------------

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

@ -47,6 +47,14 @@ static const int pxID_PadHandler_Keydown = 8030;
// single for-loop to create them.
static const int PluginMenuId_Interval = 0x10;
// ID and return code used for modal popups that have a custom button.
static const wxWindowID pxID_CUSTOM = wxID_LOWEST - 1;
// Return code used by first time wizard if the dialog needs to be automatically recreated
// (assigned an arbitrary value)
static const wxWindowID pxID_RestartWizard = wxID_LOWEST - 100;
// Forces the Interface to destroy the GS viewport window when the GS plugin is
// destroyed. This has the side effect of forcing all plugins to close and re-open
// along with the GS, since the GS viewport window handle will have changed.
@ -109,6 +117,7 @@ enum MenuIdentifiers
MenuId_Config_AppSettings,
MenuId_Config_GameDatabase,
MenuId_Config_BIOS,
MenuId_Config_Language,
// Plugin ID order is important. Must match the order in tbl_PluginInfo.
MenuId_Config_GS,
@ -359,6 +368,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
@ -384,6 +365,7 @@ AppConfig::AppConfig()
, DeskTheme( L"default" )
{
LanguageId = wxLANGUAGE_DEFAULT;
LanguageCode = L"default";
RecentIsoCount = 12;
Listbook_ImageSize = 32;
Toolbar_ImageSize = 24;
@ -487,6 +469,7 @@ void AppConfig::LoadSaveRootItems( IniInterface& ini )
IniEntry( AppSettingsTabName );
IniEntry( GameDatabaseTabName );
ini.EnumEntry( L"LanguageId", LanguageId, NULL, defaults.LanguageId );
IniEntry( LanguageCode );
IniEntry( RecentIsoCount );
IniEntry( DeskTheme );
IniEntry( Listbook_ImageSize );
@ -780,7 +763,8 @@ void AppConfig_OnChangedSettingsFolder( bool overwrite )
if( overwrite )
{
if( wxFileExists( iniFilename ) && !wxRemoveFile( iniFilename ) )
throw Exception::AccessDenied(iniFilename).SetBothMsgs(wxLt("Failed to overwrite existing settings file; permission was denied."));
throw Exception::AccessDenied(iniFilename)
.SetBothMsgs(pxL("Failed to overwrite existing settings file; permission was denied."));
}
// Bind into wxConfigBase to allow wx to use our config internally, and delete whatever

View File

@ -195,9 +195,14 @@ public:
wxString AppSettingsTabName;
wxString GameDatabaseTabName;
// Current language in use (correlates to a wxWidgets wxLANGUAGE specifier)
// Currently selected language ID -- wxWidgets version-specific identifier. This is one side of
// a two-part configuration that also includes LanguageCode.
wxLanguage LanguageId;
// Current language in use (correlates to the universal language codes, such as "en_US", "de_DE", etc).
// This code is not always unique, which is why we use the language ID also.
wxString LanguageCode;
int RecentIsoCount; // number of files displayed in the Recent Isos list.
// String value describing the desktop theme to use for pcsk2 (icons and background images)

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." )
);
@ -70,12 +70,30 @@ void Pcsx2App::WipeUserModeSettings()
usermodefile.SetPath( usrlocaldir.ToString() );
ScopedPtr<wxFileConfig> conf_usermode( OpenFileConfig( usermodefile.GetFullPath() ) );
wxString groupname( wxsFormat( L"CWD.%08x", hashres ) );
FastFormatUnicode groupname;
groupname.Write( L"CWD.%08x", hashres );
Console.WriteLn( "(UserModeSettings) Removing entry:" );
Console.Indent().WriteLn( L"Path: %s\nHash:%s", cwd.c_str(), groupname.c_str() );
conf_usermode->DeleteGroup( groupname );
}
static void DoFirstTimeWizard()
{
// first time startup, so give the user the choice of user mode:
while(true)
{
// PCSX2's FTWizard allows improptu restarting of the wizard without cancellation. This is
// typically used to change the user's language selection.
FirstTimeWizard wiz( NULL );
if( wiz.RunWizard( wiz.GetUsermodePage() ) ) break;
if (wiz.GetReturnCode() != pxID_RestartWizard)
throw Exception::StartupAborted( L"User canceled FirstTime Wizard." );
Console.WriteLn( Color_StrongBlack, "Restarting First Time Wizard!" );
}
}
// User mode settings can't be stored in the CWD for two reasons:
// (a) the user may not have permission to do so (most obvious)
// (b) it would result in sloppy usermode.ini found all over a hard drive if people runs the
@ -104,7 +122,8 @@ void Pcsx2App::ReadUserModeSettings()
usermodefile.SetPath( usrlocaldir.ToString() );
ScopedPtr<wxFileConfig> conf_usermode( OpenFileConfig( usermodefile.GetFullPath() ) );
wxString groupname( wxsFormat( L"CWD.%08x", hashres ) );
FastFormatUnicode groupname;
groupname.Write( L"CWD.%08x", hashres );
bool hasGroup = conf_usermode->HasGroup( groupname );
bool forceWiz = Startup.ForceWizard || !hasGroup;
@ -135,10 +154,7 @@ void Pcsx2App::ReadUserModeSettings()
}
#endif
// first time startup, so give the user the choice of user mode:
FirstTimeWizard wiz( NULL );
if( !wiz.RunWizard( wiz.GetUsermodePage() ) )
throw Exception::StartupAborted( L"User canceled FirstTime Wizard." );
DoFirstTimeWizard();
// Save user's new settings
IniSaver saver( *conf_usermode );
@ -159,14 +175,8 @@ void Pcsx2App::ReadUserModeSettings()
if( !wxFile::Exists( GetSettingsFilename() ) )
{
// user wiped their pcsx2.ini -- needs a reconfiguration via wizard!
// (we skip the first page since it's a usermode.ini thing)
// Fixme : Skipping the first page is a bad idea, as it does a lot of file / directory checks on hitting Apply.
// If anything is missing, the first page prompts to fix it.
// If we skip this check, it's very likely that actions like creating Memory Cards will fail.
FirstTimeWizard wiz( NULL );
if( !wiz.RunWizard( /*wiz.GetPostUsermodePage()*/ wiz.GetUsermodePage() ) )
throw Exception::StartupAborted( L"User canceled Configuration Wizard." );
DoFirstTimeWizard();
// Save user's new settings
IniSaver saver( *conf_usermode );
@ -236,6 +246,19 @@ void Pcsx2App::OpenProgramLog()
EnableAllLogging();
if( m_current_focus ) m_current_focus->SetFocus();
// This is test code for printing out all supported languages and their canonical names in wiki-fied
// format. I might use it again soon, so I'm leaving it in for now... --air
/*
for( int li=wxLANGUAGE_UNKNOWN+1; li<wxLANGUAGE_USER_DEFINED; ++li )
{
if (const wxLanguageInfo* info = wxLocale::GetLanguageInfo( li ))
{
if (i18n_IsLegacyLanguageId((wxLanguage)info->Language)) continue;
Console.WriteLn( L"|| %-30s || %-8s ||", info->Description.c_str(), info->CanonicalName.c_str() );
}
}
*/
}
void Pcsx2App::AllocateCoreStuffs()
@ -264,7 +287,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 +341,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." )
);
@ -365,7 +388,7 @@ void Pcsx2App::OnInitCmdLine( wxCmdLineParser& parser )
const PluginInfo* pi = tbl_PluginInfo; do {
parser.AddOption( wxEmptyString, pi->GetShortname().Lower(),
wxsFormat( _("specify the file to use as the %s plugin"), pi->GetShortname().c_str() )
pxsFmt( _("specify the file to use as the %s plugin"), pi->GetShortname().c_str() )
);
} while( ++pi, pi->shortname != NULL );
@ -524,6 +547,9 @@ bool Pcsx2App::OnInit()
g_Conf = new AppConfig();
wxInitAllImageHandlers();
Console.WriteLn("Applying operating system default language...");
i18n_SetLanguage( wxLANGUAGE_DEFAULT );
Console.WriteLn("Command line parsing...");
if( !_parent::OnInit() ) return false;
Console.WriteLn("Command line parsed!");
@ -552,8 +578,6 @@ bool Pcsx2App::OnInit()
InitDefaultGlobalAccelerators();
delete wxLog::SetActiveTarget( new pxLogConsole() );
m_RecentIsoList = new RecentIsoList();
#ifdef __WXMSW__
pxDwm_Load();
#endif
@ -775,6 +799,28 @@ protected:
Pcsx2App::Pcsx2App()
: SysExecutorThread( new SysEvtHandler() )
{
#if 0
{
// Some common labels provided by wxWidgets. wxWidgets translation files are chucked full
// of worthless crap, and tally more than 200k each. We only need these couple.
_("OK");
_("&OK");
_("Cancel");
_("&Cancel");
_("&Apply");
_("&Next >");
_("&Back >");
_("&Back");
_("&Finish");
_("&Save");
_("Save &As...");
_("&Help");
_("&Home");
}
#endif
m_PendingSaves = 0;
m_ScheduledTermination = false;

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
@ -275,6 +277,12 @@ public:
virtual void Printf(const wxChar* format, ...);
};
// EXTRAORDINARY HACK! wxWidgets does not provide a clean way of overriding the commandline options
// display dialog. The default one uses operating system built-in message/notice windows, which are
// appaling, ugly, and not at all suited to a large number of command line options. Fortunately,
// wxMessageOutputMessageBox::PrintF is only used in like two places, so we can just check for the
// commandline window using an identifier we know is contained in it, and then format our own window
// display. :D --air
void pxMessageOutputMessageBox::Printf(const wxChar* format, ...)
{
using namespace pxSizerFlags;
@ -285,14 +293,16 @@ void pxMessageOutputMessageBox::Printf(const wxChar* format, ...)
out.PrintfV(format, args);
va_end(args);
int pos = out.Find( L"[IsoFile]" );
FastFormatUnicode isoFormatted;
isoFormatted.Write( L"[%s]", _("IsoFile") );
int pos = out.Find( isoFormatted );
if(pos == wxNOT_FOUND)
{
Msgbox::Alert( out ); return;
}
pos += 9; // strlen of [IsoFile]
pos += isoFormatted.Length();
wxDialogWithHelpers popup( NULL, AddAppName(_("%s Commandline Options")) );
popup.SetMinWidth( 640 );
@ -305,8 +315,8 @@ void pxMessageOutputMessageBox::Printf(const wxChar* format, ...)
wxTE_READONLY | wxTE_MULTILINE | wxTE_RICH2 | wxHSCROLL
);
traceArea->SetDefaultStyle( wxTextAttr( wxNullColour, wxNullColour, pxGetFixedFont() ) );
traceArea->SetFont( pxGetFixedFont() );
traceArea->SetDefaultStyle( wxTextAttr( wxNullColour, wxNullColour, pxGetFixedFont(9) ) );
traceArea->SetFont( pxGetFixedFont(9) );
int fonty = traceArea->GetCharHeight();
@ -328,7 +338,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.ToString();
}
#endif
};
wxStandardPathsBase& Pcsx2AppTraits::GetStandardPaths()
{
static Pcsx2StandardPaths stdPaths;
return stdPaths;
}
#endif
wxAppTraits* Pcsx2App::CreateTraits()
{
return new Pcsx2AppTraits;
}
// --------------------------------------------------------------------------------------
// FramerateManager (implementations)
// --------------------------------------------------------------------------------------
@ -423,7 +480,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 +564,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 +631,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,16 +674,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( wxLANGUAGE_DEFAULT ) )
{
i18n_SetLanguage( wxLANGUAGE_ENGLISH );
}
}
i18n_SetLanguage( g_Conf->LanguageId, g_Conf->LanguageCode );
}
CorePlugins.SetSettingsFolder( GetSettingsFolder().ToString() );

View File

@ -80,13 +80,13 @@ pxAppResources::~pxAppResources() throw() {}
wxMenu& Pcsx2App::GetRecentIsoMenu()
{
pxAssert( !!m_RecentIsoList->Menu );
if (!m_RecentIsoList) m_RecentIsoList = new RecentIsoList();
return *m_RecentIsoList->Menu;
}
RecentIsoManager& Pcsx2App::GetRecentIsoManager()
{
pxAssert( !!m_RecentIsoList->Manager );
if (!m_RecentIsoList) m_RecentIsoList = new RecentIsoList();
return *m_RecentIsoList->Manager;
}

View File

@ -52,7 +52,7 @@ namespace Exception
public:
explicit CannotApplySettings( BaseApplicableConfigPanel* thispanel )
{
SetBothMsgs(wxLt("Cannot apply new settings, one of the settings is invalid."));
SetBothMsgs(pxL("Cannot apply new settings, one of the settings is invalid."));
m_Panel = thispanel;
IsVerbose = true;
}

View File

@ -409,22 +409,22 @@ ConsoleLogFrame::ConsoleLogFrame( MainEmuFrame *parent, const wxString& title, A
// create Appearance menu and submenus
menuFontSizes.Append( MenuId_FontSize_Small, _("Small"), _("Fits a lot of log in a microcosmically small area."),
menuFontSizes.Append( MenuId_FontSize_Small, _("Small"), _t("Fits a lot of log in a microcosmically small area."),
wxITEM_RADIO )->Check( options.FontSize == 7 );
menuFontSizes.Append( MenuId_FontSize_Normal, _("Normal"),_("It's what I use (the programmer guy)."),
menuFontSizes.Append( MenuId_FontSize_Normal, _("Normal"),_t("It's what I use (the programmer guy)."),
wxITEM_RADIO )->Check( options.FontSize == 8 );
menuFontSizes.Append( MenuId_FontSize_Large, _("Large"), _("Its nice and readable."),
menuFontSizes.Append( MenuId_FontSize_Large, _("Large"), _t("Its nice and readable."),
wxITEM_RADIO )->Check( options.FontSize == 10 );
menuFontSizes.Append( MenuId_FontSize_Huge, _("Huge"), _("In case you have a really high res display."),
menuFontSizes.Append( MenuId_FontSize_Huge, _("Huge"), _t("In case you have a really high res display."),
wxITEM_RADIO )->Check( options.FontSize == 12 );
menuFontSizes.AppendSeparator();
menuFontSizes.Append( MenuId_ColorScheme_Light, _("Light theme"), _("Default soft-tone color scheme."), wxITEM_RADIO );
menuFontSizes.Append( MenuId_ColorScheme_Dark, _("Dark theme"), _("Classic black color scheme for people who enjoy having text seared into their optic nerves."), wxITEM_RADIO );
menuFontSizes.Append( MenuId_ColorScheme_Light, _("Light theme"), _t("Default soft-tone color scheme."), wxITEM_RADIO );
menuFontSizes.Append( MenuId_ColorScheme_Dark, _("Dark theme"), _t("Classic black color scheme for people who enjoy having text seared into their optic nerves."), wxITEM_RADIO );
menuAppear.AppendSeparator();
menuAppear.Append( wxID_ANY, _("Always on Top"),
_("When checked the log window will be visible over other foreground windows."), wxITEM_CHECK );
_t("When checked the log window will be visible over other foreground windows."), wxITEM_CHECK );
menuLog.Append(wxID_SAVE, _("&Save..."), _("Save log contents to file"));
menuLog.Append(wxID_CLEAR, _("C&lear"), _("Clear the log window contents"));

View File

@ -89,6 +89,26 @@ namespace Dialogs
virtual wxString& GetConfSettingsTabName() const { return g_Conf->SysSettingsTabName; }
};
// --------------------------------------------------------------------------------------
// LanguageSelectionDialog
// --------------------------------------------------------------------------------------
class LanguageSelectionDialog : public BaseConfigurationDialog
{
public:
virtual ~LanguageSelectionDialog() throw() {}
LanguageSelectionDialog(wxWindow* parent=NULL);
static wxString GetNameStatic() { return L"LanguageSelector"; }
wxString GetDialogName() const { return GetNameStatic(); }
protected:
virtual wxString& GetConfSettingsTabName() const
{
pxFailDev("Language selector does not have a listbook or settings tab.");
static wxString fail;
return fail;
}
};
// --------------------------------------------------------------------------------------
// McdConfigDialog
// --------------------------------------------------------------------------------------

View File

@ -65,7 +65,7 @@ static wxString ResultToString( int result, const MsgButtons& buttons )
case wxID_ABORT: return L"abort";
case wxID_RETRY: return L"retry";
// [TODO] : maybe add in an Ignore All?
// [TODO] : maybe add in an Ignore All?
case wxID_IGNORE: return L"ignore";
case wxID_RESET: return L"reset";
@ -73,7 +73,7 @@ static wxString ResultToString( int result, const MsgButtons& buttons )
}
if (result <= wxID_LOWEST)
return buttons.GetCustomLabel();
return buttons.GetCustomLabelId();
return wxEmptyString;
}

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."
)
);
@ -161,19 +161,19 @@ void Dialogs::CreateMemoryCardDialog::CreateControls()
const RadioPanelItem tbl_CardSizes[] =
{
RadioPanelItem(_("8 MB [most compatible]"), _("This is the standard Sony-provisioned size, and is supported by all games and BIOS versions."))
. SetToolTip(_("Always use this option if you want the safest and surest memory card behavior."))
. SetToolTip(_t("Always use this option if you want the safest and surest memory card behavior."))
. SetInt(8),
RadioPanelItem(_("16 MB"), _("A typical size for 3rd-party memory cards which should work with most games."))
. SetToolTip(_("16 and 32 MB cards have roughly the same compatibility factor."))
. SetToolTip(_t("16 and 32 MB cards have roughly the same compatibility factor."))
. SetInt(16),
RadioPanelItem(_("32 MB"), _("A typical size for 3rd-party memory cards which should work with most games."))
. SetToolTip(_("16 and 32 MB cards have roughly the same compatibility factor."))
. SetToolTip(_t("16 and 32 MB cards have roughly the same compatibility factor."))
. SetInt(32),
RadioPanelItem(_("64 MB"), _("Low compatibility warning: Yes it's very big, but may not work with many games."))
. SetToolTip(_("Use at your own risk. Erratic memory card behavior is possible (though unlikely)."))
. SetToolTip(_t("Use at your own risk. Erratic memory card behavior is possible (though unlikely)."))
. SetInt(64)
};

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."
@ -120,7 +120,7 @@ bool FirstTimeWizard::UsermodePage::PrepForApply()
dialog += 12;
dialog += dialog.Heading( path.ToString() );
if( wxID_CANCEL == pxIssueConfirmation( dialog, MsgButtons().Custom(_("Create")).Cancel(), L"CreateNewFolder" ) )
if( wxID_CANCEL == pxIssueConfirmation( dialog, MsgButtons().Custom(_("Create"), "create").Cancel(), L"CreateNewFolder" ) )
return false;
}
path.Mkdir();
@ -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."
@ -175,6 +175,8 @@ FirstTimeWizard::FirstTimeWizard( wxWindow* parent )
Connect( wxEVT_WIZARD_PAGE_CHANGED, wxWizardEventHandler (FirstTimeWizard::OnPageChanged) );
Connect( wxEVT_WIZARD_PAGE_CHANGING, wxWizardEventHandler (FirstTimeWizard::OnPageChanging) );
Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler (FirstTimeWizard::OnDoubleClicked) );
Connect( pxID_RestartWizard, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FirstTimeWizard::OnRestartWizard ) );
}
FirstTimeWizard::~FirstTimeWizard() throw()
@ -182,6 +184,12 @@ FirstTimeWizard::~FirstTimeWizard() throw()
}
void FirstTimeWizard::OnRestartWizard( wxCommandEvent& evt )
{
EndModal( pxID_RestartWizard );
evt.Skip();
}
static void _OpenConsole()
{
g_Conf->ProgLogBox.Visible = true;

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,12 +38,14 @@ 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)."
)
);
m_check_SavestateBackup = new pxCheckBox( this, pxsFmt(_("Backup existing Savestate when creating a new one")) );
for( uint i=0; i<2; ++i )
{
m_check_Multitap[i] = new pxCheckBox( this, pxsFmt(_("Enable Multitap on Port %u"), i+1) );
@ -60,23 +62,29 @@ Panels::McdConfigPanel_Toggles::McdConfigPanel_Toggles(wxWindow *parent)
*this += 4;
*this += m_check_SavestateBackup;
*this += 4;
*this += m_check_Ejection;
}
void Panels::McdConfigPanel_Toggles::Apply()
{
g_Conf->EmuOptions.MultitapPort0_Enabled = m_check_Multitap[0]->GetValue();
g_Conf->EmuOptions.MultitapPort1_Enabled = m_check_Multitap[1]->GetValue();
g_Conf->EmuOptions.MultitapPort0_Enabled = m_check_Multitap[0]->GetValue();
g_Conf->EmuOptions.MultitapPort1_Enabled = m_check_Multitap[1]->GetValue();
g_Conf->EmuOptions.McdEnableEjection = m_check_Ejection->GetValue();
g_Conf->EmuOptions.BackupSavestate = m_check_SavestateBackup->GetValue();
g_Conf->EmuOptions.McdEnableEjection = m_check_Ejection->GetValue();
}
void Panels::McdConfigPanel_Toggles::AppStatusEvent_OnSettingsApplied()
{
m_check_Multitap[0] ->SetValue( g_Conf->EmuOptions.MultitapPort0_Enabled );
m_check_Multitap[1] ->SetValue( g_Conf->EmuOptions.MultitapPort1_Enabled );
m_check_Multitap[0] ->SetValue( g_Conf->EmuOptions.MultitapPort0_Enabled );
m_check_Multitap[1] ->SetValue( g_Conf->EmuOptions.MultitapPort1_Enabled );
m_check_Ejection ->SetValue( g_Conf->EmuOptions.McdEnableEjection );
m_check_SavestateBackup ->SetValue( g_Conf->EmuOptions.BackupSavestate );
m_check_Ejection ->SetValue( g_Conf->EmuOptions.McdEnableEjection );
}
@ -91,9 +99,6 @@ Dialogs::McdConfigDialog::McdConfigDialog( wxWindow* parent )
// [TODO] : Plan here is to add an advanced tab which gives the user the ability
// to configure the names of each memory card slot.
//AddPage<McdConfigPanel_Toggles> ( wxLt("Settings"), cfgid.MemoryCard );
//AddPage<McdConfigPanel_Standard> ( wxLt("Slots 1/2"), cfgid.MemoryCard );
*this += Heading(_("Drag items over other items in the list to swap or copy memory cards.")) | StdExpand();
*this += StdPadding;

View File

@ -21,8 +21,6 @@
#include <wx/wizard.h>
static const wxWindowID pxID_CUSTOM = wxID_LOWEST - 1;
class FirstTimeWizard : public wxWizard
{
typedef wxWizard _parent;
@ -71,6 +69,8 @@ protected:
virtual void OnPageChanging( wxWizardEvent& evt );
virtual void OnPageChanged( wxWizardEvent& evt );
virtual void OnDoubleClicked( wxCommandEvent& evt );
void OnRestartWizard( wxCommandEvent& evt );
};

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."
),
@ -43,7 +43,7 @@ Dialogs::StuckThreadDialog::StuckThreadDialog( wxWindow* parent, StuckThreadActi
L"\nOr press [Ignore] to suppress further assertions."
);
*this += new ModalButtonPanel( this, MsgButtons().Cancel().Custom(L"Wait") ) | StdCenter();
*this += new ModalButtonPanel( this, MsgButtons().Cancel().Custom(L"Wait", "wait") ) | StdCenter();
if( wxWindow* idyes = FindWindowById( wxID_YES ) )
idyes->SetFocus();

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."
@ -72,13 +73,12 @@ Dialogs::SysConfigDialog::SysConfigDialog(wxWindow* parent)
CreateListbook( wxGetApp().GetImgList_Config() );
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
AddPage<CpuPanelEE> ( wxLt("EE/IOP"), cfgid.Cpu );
AddPage<CpuPanelVU> ( wxLt("VUs"), cfgid.Cpu );
AddPage<VideoPanel> ( wxLt("GS"), cfgid.Cpu );
AddPage<GSWindowSettingsPanel> ( wxLt("GS Window"), cfgid.Video );
AddPage<SpeedHacksPanel> ( wxLt("Speedhacks"), cfgid.Speedhacks );
AddPage<GameFixesPanel> ( wxLt("Game Fixes"), cfgid.Gamefixes );
//AddPage<GameDatabasePanel> ( wxLt("Game Database"),cfgid.Plugins );
AddPage<CpuPanelEE> ( pxL("EE/IOP"), cfgid.Cpu );
AddPage<CpuPanelVU> ( pxL("VUs"), cfgid.Cpu );
AddPage<VideoPanel> ( pxL("GS"), cfgid.Cpu );
AddPage<GSWindowSettingsPanel> ( pxL("GS Window"), cfgid.Video );
AddPage<SpeedHacksPanel> ( pxL("Speedhacks"), cfgid.Speedhacks );
AddPage<GameFixesPanel> ( pxL("Game Fixes"), cfgid.Gamefixes );
AddListbook();
AddOkCancel();
@ -95,9 +95,9 @@ Dialogs::ComponentsConfigDialog::ComponentsConfigDialog(wxWindow* parent)
CreateListbook( wxGetApp().GetImgList_Config() );
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
AddPage<PluginSelectorPanel> ( wxLt("Plugins"), cfgid.Plugins );
AddPage<BiosSelectorPanel> ( wxLt("BIOS"), cfgid.Cpu );
AddPage<StandardPathsPanel> ( wxLt("Folders"), cfgid.Paths );
AddPage<PluginSelectorPanel> ( pxL("Plugins"), cfgid.Plugins );
AddPage<BiosSelectorPanel> ( pxL("BIOS"), cfgid.Cpu );
AddPage<StandardPathsPanel> ( pxL("Folders"), cfgid.Paths );
AddListbook();
AddOkCancel();
@ -105,3 +105,13 @@ Dialogs::ComponentsConfigDialog::ComponentsConfigDialog(wxWindow* parent)
if( wxGetApp().Overrides.HasPluginsOverride() )
wxGetApp().PostMethod( CheckPluginsOverrides );
}
Dialogs::LanguageSelectionDialog::LanguageSelectionDialog(wxWindow *parent)
: BaseConfigurationDialog( parent, AddAppName(_("Language Selector - %s")), 400 )
{
ScopedBusyCursor busy( Cursor_ReallyBusy );
*this += new Panels::LanguageSelectionPanel( this ) | pxCenter;
wxDialogWithHelpers::AddOkCancel( NULL, false );
}

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()
@ -37,7 +37,7 @@ ConsoleLogSource_Event::ConsoleLogSource_Event()
static const TraceLogDescriptor myDesc =
{
L"SysEvents", L"SysVM Control Events",
wxLt("Logs events as they are passed to the PS2 virtual machine."),
pxLt("Logs events as they are passed to the PS2 virtual machine."),
};
m_Descriptor = &myDesc;

View File

@ -386,8 +386,7 @@ void GSFrame::OnUpdateTitle( wxTimerEvent& evt )
double fps = wxGetApp().FpsManager.GetFramerate();
char gsDest[128];
GSgetTitleInfo( gsDest );
GSgetTitleInfo2( gsDest, sizeof(gsDest) );
const wxChar* limiterStr = L"None";
@ -401,16 +400,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

@ -240,26 +240,26 @@ static const GlobalCommandDescriptor CommandDeclarations[] =
{
{ "States_FreezeCurrentSlot",
States_FreezeCurrentSlot,
wxLt( "Save state" ),
wxLt( "Saves the virtual machine state to the current slot." ),
pxL( "Save state" ),
pxL( "Saves the virtual machine state to the current slot." ),
},
{ "States_DefrostCurrentSlot",
States_DefrostCurrentSlot,
wxLt( "Load state" ),
wxLt( "Loads a virtual machine state from the current slot." ),
pxL( "Load state" ),
pxL( "Loads a virtual machine state from the current slot." ),
},
{ "States_CycleSlotForward",
States_CycleSlotForward,
wxLt( "Cycle to next slot" ),
wxLt( "Cycles the current save slot in +1 fashion!" ),
pxL( "Cycle to next slot" ),
pxL( "Cycles the current save slot in +1 fashion!" ),
},
{ "States_CycleSlotBackward",
States_CycleSlotBackward,
wxLt( "Cycle to prev slot" ),
wxLt( "Cycles the current save slot in -1 fashion!" ),
pxL( "Cycle to prev slot" ),
pxL( "Cycles the current save slot in -1 fashion!" ),
},
{ "Frameskip_Toggle",

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

@ -61,6 +61,29 @@ void MainEmuFrame::UpdateIsoSrcSelection()
// exists ? Path::GetFilename(g_Conf->CurrentIso).c_str() : _("Empty") ) );
}
bool MainEmuFrame::Destroy()
{
// Sigh: wxWidgets doesn't issue Destroy() calls for children windows when the parent
// is destroyed (it just deletes them, quite suddenly). So let's do it for them, since
// our children have configuration stuff they like to do when they're closing.
for (
wxWindowList::const_iterator
i = wxTopLevelWindows.begin(),
end = wxTopLevelWindows.end();
i != end; ++i
)
{
wxTopLevelWindow * const win = wx_static_cast(wxTopLevelWindow *, *i);
if (win == this) continue;
if (win->GetParent() != this) continue;
win->Destroy();
}
return _parent::Destroy();
}
// ------------------------------------------------------------------------
// MainFrame OnEvent Handlers
// ------------------------------------------------------------------------
@ -157,6 +180,7 @@ void MainEmuFrame::ConnectMenus()
ConnectMenu( MenuId_Config_AppSettings, Menu_WindowSettings_Click );
ConnectMenu( MenuId_Config_GameDatabase,Menu_GameDatabase_Click );
ConnectMenu( MenuId_Config_BIOS, Menu_SelectPluginsBios_Click );
ConnectMenu( MenuId_Config_Language, Menu_Language_Click );
ConnectMenu( MenuId_Config_ResetAll, Menu_ResetAllSettings_Click );
ConnectMenu( MenuId_Config_Multitap0Toggle, Menu_MultitapToggle_Click );
@ -290,8 +314,8 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title)
, m_LoadStatesSubmenu( *MakeStatesSubMenu( MenuId_State_Load01 ) )
, m_SaveStatesSubmenu( *MakeStatesSubMenu( MenuId_State_Save01 ) )
, m_MenuItem_Console( *new wxMenuItem( &m_menuMisc, MenuId_Console, L"Show Console", wxEmptyString, wxITEM_CHECK ) )
, m_MenuItem_Console_Stdio( *new wxMenuItem( &m_menuMisc, MenuId_Console_Stdio, L"Console to Stdio", wxEmptyString, wxITEM_CHECK ) )
, m_MenuItem_Console( *new wxMenuItem( &m_menuMisc, MenuId_Console, _("Show Console"), wxEmptyString, wxITEM_CHECK ) )
, m_MenuItem_Console_Stdio( *new wxMenuItem( &m_menuMisc, MenuId_Console_Stdio, _("Console to Stdio"), wxEmptyString, wxITEM_CHECK ) )
{
m_RestartEmuOnDelete = false;
@ -423,12 +447,17 @@ 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.Append(MenuId_Config_Language, _("Language...") );
}
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]);
@ -458,7 +487,7 @@ MainEmuFrame::MainEmuFrame(wxWindow* parent, const wxString& title)
//m_menuMisc.Append(41, "Patch Browser...", wxEmptyString, wxITEM_NORMAL);
//m_menuMisc.Append(42, "Patch Finder...", wxEmptyString, wxITEM_NORMAL);
m_menuMisc.Append(MenuId_CDVD_Info, _T("Print CDVD Info"), wxEmptyString, wxITEM_CHECK);
m_menuMisc.Append(MenuId_CDVD_Info, _("Print CDVD Info"), wxEmptyString, wxITEM_CHECK);
m_menuMisc.AppendSeparator();
//Todo:

View File

@ -145,6 +145,8 @@ public:
void UpdateIsoSrcSelection();
void RemoveCdvdMenu();
void EnableMenuItem( int id, bool enable );
bool Destroy();
protected:
void DoGiveHelp(const wxString& text, bool show);
@ -166,6 +168,7 @@ protected:
void Menu_WindowSettings_Click(wxCommandEvent &event);
void Menu_GSSettings_Click(wxCommandEvent &event);
void Menu_SelectPluginsBios_Click(wxCommandEvent &event);
void Menu_Language_Click(wxCommandEvent &event);
void Menu_ResetAllSettings_Click(wxCommandEvent &event);
void Menu_IsoBrowse_Click(wxCommandEvent &event);

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)
@ -72,6 +72,11 @@ void MainEmuFrame::Menu_SelectPluginsBios_Click(wxCommandEvent &event)
AppOpenDialog<ComponentsConfigDialog>( this );
}
void MainEmuFrame::Menu_Language_Click(wxCommandEvent &event)
{
//AppOpenDialog<LanguageSelectionDialog>( this );
LanguageSelectionDialog(this).ShowModal();
}
static void WipeSettings()
{
@ -104,7 +109,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?"
@ -146,7 +151,7 @@ wxWindowID SwapOrReset_Iso( wxWindow* owner, IScopedCoreThread& core_control, co
dialog += dialog.GetCharHeight();
dialog += dialog.Heading(_("Do you want to swap discs or boot the new image (via system reset)?"));
result = pxIssueConfirmation( dialog, MsgButtons().Reset().Cancel().Custom(_("Swap Disc")), L"DragDrop.BootSwapIso" );
result = pxIssueConfirmation( dialog, MsgButtons().Reset().Cancel().Custom(_("Swap Disc"), "swap"), L"DragDrop.BootSwapIso" );
if( result == wxID_CANCEL )
{
core_control.AllowResume();
@ -189,7 +194,7 @@ wxWindowID SwapOrReset_CdvdSrc( wxWindow* owner, CDVD_SourceType newsrc )
_("Do you want to swap discs or boot the new image (system reset)?")
);
result = pxIssueConfirmation( dialog, MsgButtons().Reset().Cancel().Custom(_("Swap Disc")), L"DragDrop.BootSwapIso" );
result = pxIssueConfirmation( dialog, MsgButtons().Reset().Cancel().Custom(_("Swap Disc"), "swap"), L"DragDrop.BootSwapIso" );
if( result == wxID_CANCEL )
{

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

@ -109,6 +109,9 @@ namespace Panels
void Apply();
void AppStatusEvent_OnSettingsApplied();
protected:
void OnApplyLanguage_Clicked( wxCommandEvent& evt );
};
// --------------------------------------------------------------------------------------

View File

@ -60,12 +60,12 @@ 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?" )
);
wxWindowID result = pxIssueConfirmation( createPathDlg,
MsgButtons().Custom(_("Create")).Cancel(),
MsgButtons().Custom(_("Create"), "create").Cancel(),
L"DirPicker:CreateOnExplore"
);
@ -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. " )
);
@ -225,7 +225,7 @@ void Panels::DirPickerPanel::Apply()
dialog += 12;
dialog += dialog.Heading( path );
if( wxID_CANCEL == pxIssueConfirmation( dialog, MsgButtons().Custom(_("Create")).Cancel(), L"CreateNewFolder" ) )
if( wxID_CANCEL == pxIssueConfirmation( dialog, MsgButtons().Custom(_("Create"), "create").Cancel(), L"CreateNewFolder" ) )
throw Exception::CannotApplySettings( this );
}

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
// --------------------------------------------------------------------------------------
@ -231,6 +231,7 @@ namespace Panels
protected:
pxCheckBox* m_check_Multitap[2];
pxCheckBox* m_check_Ejection;
pxCheckBox* m_check_SavestateBackup;
public:
McdConfigPanel_Toggles( wxWindow* parent );

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."
@ -113,26 +113,32 @@ Panels::LanguageSelectionPanel::LanguageSelectionPanel( wxWindow* parent )
i18n_EnumeratePackages( m_langs );
int size = m_langs.size();
int cursel = 0;
ScopedArray<wxString> compiled( size ); //, L"Compiled Language Names" );
wxString configLangName( wxLocale::GetLanguageName( wxLANGUAGE_DEFAULT ) );
ScopedArray<wxString> compiled( size );
for( int i=0; i<size; ++i )
{
compiled[i].Printf( L"%s", m_langs[i].englishName.c_str() ); //, xltNames[i].c_str() );
if( m_langs[i].englishName == configLangName )
cursel = i;
}
compiled[i].Printf( L"%s", m_langs[i].englishName.c_str() );
m_picker = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
size, compiled.GetPtr(), wxCB_READONLY | wxCB_SORT );
*this += Label(_("Select a language: (unimplemented)")) | pxMiddle;
wxButton* applyButton = new wxButton( this, pxID_RestartWizard, _("Apply") );
applyButton->SetToolTip(_("Make this language my default right now!"));
*this += Label(_("Select a language:")) | pxMiddle;
*this += 5;
*this += m_picker | pxSizerFlags::StdSpace();
*this += 5;
*this += applyButton | pxSizerFlags::StdSpace();
m_picker->SetSelection( cursel );
//AppStatusEvent_OnSettingsApplied();
Connect( pxID_RestartWizard, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( LanguageSelectionPanel::OnApplyLanguage_Clicked ) );
m_picker->SetSelection( 0 ); // always default to System Default
}
void Panels::LanguageSelectionPanel::OnApplyLanguage_Clicked( wxCommandEvent& evt )
{
evt.Skip();
Apply();
}
void Panels::LanguageSelectionPanel::Apply()
@ -144,19 +150,39 @@ 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
g_Conf->LanguageId = wxLANGUAGE_DEFAULT;
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;
if( i18n_SetLanguage( m_langs[i].wxLangId, m_langs[i].canonicalName ) )
{
g_Conf->LanguageCode = m_langs[i].canonicalName;
g_Conf->LanguageId = m_langs[i].wxLangId;
}
break;
}
}
}
void Panels::LanguageSelectionPanel::AppStatusEvent_OnSettingsApplied()
{
if( m_picker ) m_picker->SetSelection( g_Conf->LanguageId );
if (m_picker)
{
m_picker->SetSelection( 0 ); // always default to System Default
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 );
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More