mirror of https://github.com/PCSX2/pcsx2.git
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:
commit
daf47b50a0
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -445,6 +445,10 @@
|
|||
RelativePath="..\..\include\Utilities\pxEvents.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\Utilities\pxForwardDefs.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\Utilities\pxRadioPanel.h"
|
||||
>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,29 +221,43 @@ extern wxString fromAscii( const char* src );
|
|||
//
|
||||
// Valid prefix types:
|
||||
//
|
||||
// .Panel: Key-based translation of a panel or dialog text; usually either a header or
|
||||
// !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,
|
||||
// !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
|
||||
// !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.
|
||||
// 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
|
||||
// !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
|
||||
// the most tertiary of info to the user.
|
||||
// only tertiary (extra) info to the user.
|
||||
//
|
||||
|
||||
#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"
|
||||
#include "Utilities/ScopedPtr.h"
|
||||
|
|
|
@ -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.") );
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
|
|
@ -251,5 +251,6 @@ namespace HostSys
|
|||
extern void InitCPUTicks();
|
||||
extern u64 GetTickFrequency();
|
||||
extern u64 GetCPUTicks();
|
||||
extern u64 GetPhysicalMemory();
|
||||
|
||||
extern wxString GetOSVersionString();
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -234,6 +234,7 @@ protected:
|
|||
BITFIELD_END
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -275,6 +279,7 @@ public:
|
|||
|
||||
bool HasCustom() const { return !m_CustomLabel.IsEmpty(); }
|
||||
const wxString& GetCustomLabel() const { return m_CustomLabel; }
|
||||
const wxString& GetCustomLabelId() const { return m_CustomLabelId; }
|
||||
|
||||
bool Allows( wxWindowID id ) const;
|
||||
void SetBestFocus( wxWindow* dialog ) const;
|
||||
|
|
|
@ -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 );
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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."
|
||||
)
|
||||
|
|
|
@ -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
|
||||
));
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <winnt.h>
|
||||
|
||||
|
||||
int SysPageFaultExceptionFilter( EXCEPTION_POINTERS* eps )
|
||||
{
|
||||
if( eps->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION )
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -274,7 +274,7 @@ 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.
|
||||
|
@ -300,6 +300,11 @@ void wxDialogWithHelpers::OnCloseWindow( wxCloseEvent& evt )
|
|||
}
|
||||
}
|
||||
|
||||
return _parent::Destroy();
|
||||
}
|
||||
|
||||
void wxDialogWithHelpers::OnCloseWindow( wxCloseEvent& evt )
|
||||
{
|
||||
if( !IsModal() ) Destroy();
|
||||
evt.Skip();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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.")
|
||||
)
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
178
pcsx2/Gif.cpp
178
pcsx2/Gif.cpp
|
@ -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;
|
||||
|
@ -80,12 +79,17 @@ void gsPath1Interrupt()
|
|||
{
|
||||
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;
|
||||
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;
|
||||
gifempty = false;
|
||||
}
|
||||
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,6 +615,7 @@ 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;
|
||||
|
|
|
@ -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,
|
||||
|
|
46
pcsx2/Hw.cpp
46
pcsx2/Hw.cpp
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
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
|
||||
if( ipu1dma.qwc == 0)
|
||||
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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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."));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -374,6 +374,7 @@ void Pcsx2Config::LoadSave( IniInterface& ini )
|
|||
IniBitBool( ConsoleToStdio );
|
||||
IniBitBool( HostFs );
|
||||
|
||||
IniBitBool( BackupSavestate );
|
||||
IniBitBool( McdEnableEjection );
|
||||
IniBitBool( MultitapPort0_Enabled );
|
||||
IniBitBool( MultitapPort1_Enabled );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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).
|
||||
|
||||
char descin[128], desccmp[128];
|
||||
wxString descout;
|
||||
IsBIOS( g_Conf->FullpathToBios(), descout );
|
||||
memzero( descin );
|
||||
memzero( desccmp );
|
||||
u32 bioscheck = BiosChecksum;
|
||||
char biosdesc[256];
|
||||
|
||||
pxToUTF8 utf8(descout);
|
||||
memcpy_fast( descin, utf8, utf8.Length() );
|
||||
memcpy_fast( desccmp, utf8, utf8.Length() );
|
||||
pxToUTF8 utf8(BiosDescription);
|
||||
|
||||
// ... 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)
|
||||
memzero( biosdesc );
|
||||
memcpy_fast( biosdesc, utf8, std::min( sizeof(biosdesc), utf8.Length() ) );
|
||||
|
||||
if( IsLoading() || !m_DidBios )
|
||||
Freeze( descin );
|
||||
Freeze( bioscheck );
|
||||
Freeze( biosdesc );
|
||||
|
||||
if( !m_DidBios )
|
||||
{
|
||||
if( memcmp( descin, desccmp, 128 ) != 0 )
|
||||
if (bioscheck != BiosChecksum)
|
||||
{
|
||||
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
|
||||
"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
|
||||
FreezeMainMemory();
|
||||
FreezeBios();
|
||||
m_sectid++;
|
||||
}
|
||||
break;
|
||||
FreezeInternals();
|
||||
FreezePlugins();
|
||||
|
||||
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;
|
||||
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
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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"
|
||||
};
|
||||
|
||||
|
|
|
@ -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).
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,7 +93,6 @@ static __fi bool mfifoVIF1rbTransfer()
|
|||
if (src == NULL) return false;
|
||||
VIF1transfer(src, ((mfifoqwc << 2) - s1));
|
||||
}
|
||||
vif1ch.madr = qwctag(vif1ch.madr);
|
||||
|
||||
}
|
||||
else
|
||||
|
@ -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))
|
||||
vif1ch.madr <= (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16))
|
||||
{
|
||||
//Need to exit on mfifo locations, if the madr is matching the madr of spr, we dont have any data left :(
|
||||
if(vif1ch.madr == (dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16)) DevCon.Warning("Edge VIF1");
|
||||
|
||||
u16 startqwc = vif1ch.qwc;
|
||||
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,12 +199,14 @@ 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;
|
||||
|
@ -186,46 +218,13 @@ void mfifoVIF1transfer(int qwc)
|
|||
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,34 +302,31 @@ 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;
|
||||
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
|
||||
|
@ -330,18 +336,6 @@ void vifMFIFOInterrupt()
|
|||
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
schedulepath3msk = (vif1Regs.code >> 15) & 0x1;
|
||||
Vif1MskPath3();
|
||||
}
|
||||
if(vif1ch.chcr.STR)vif1.vifstalled = true;
|
||||
vif1.cmd = 0;
|
||||
}
|
||||
pass3 { VifCodeLog("MskPath3"); }
|
||||
|
|
|
@ -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,13 +145,22 @@ _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
|
||||
{
|
||||
|
||||
if(!vifX.irqoffset)
|
||||
{
|
||||
vifX.vifstalled = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (vifX.irq && vifX.cmd == 0) {
|
||||
//DevCon.WriteLn("Vif IRQ!");
|
||||
|
|
|
@ -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
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
|
|
@ -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"
|
|
@ -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
|
|
@ -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
|
||||
};
|
||||
|
||||
// =====================================================================================================
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
@ -329,6 +339,53 @@ wxMessageOutput* Pcsx2AppTraits::CreateMessageOutput()
|
|||
#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() );
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"));
|
||||
|
|
|
@ -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
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
|
|
@ -73,7 +73,7 @@ static wxString ResultToString( int result, const MsgButtons& buttons )
|
|||
}
|
||||
|
||||
if (result <= wxID_LOWEST)
|
||||
return buttons.GetCustomLabel();
|
||||
return buttons.GetCustomLabelId();
|
||||
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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)"
|
||||
|
|
|
@ -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,6 +62,10 @@ Panels::McdConfigPanel_Toggles::McdConfigPanel_Toggles(wxWindow *parent)
|
|||
|
||||
*this += 4;
|
||||
|
||||
*this += m_check_SavestateBackup;
|
||||
|
||||
*this += 4;
|
||||
|
||||
*this += m_check_Ejection;
|
||||
}
|
||||
|
||||
|
@ -68,6 +74,7 @@ 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.BackupSavestate = m_check_SavestateBackup->GetValue();
|
||||
g_Conf->EmuOptions.McdEnableEjection = m_check_Ejection->GetValue();
|
||||
}
|
||||
|
||||
|
@ -76,6 +83,7 @@ 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_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;
|
||||
|
||||
|
|
|
@ -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 );
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 );
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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?"
|
||||
);
|
||||
|
|
|
@ -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") );
|
||||
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:
|
||||
|
|
|
@ -146,6 +146,8 @@ public:
|
|||
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);
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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."
|
||||
) );
|
||||
|
|
|
@ -109,6 +109,9 @@ namespace Panels
|
|||
|
||||
void Apply();
|
||||
void AppStatusEvent_OnSettingsApplied();
|
||||
|
||||
protected:
|
||||
void OnApplyLanguage_Clicked( wxCommandEvent& evt );
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
@ -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."
|
||||
) );
|
||||
|
|
|
@ -18,11 +18,301 @@
|
|||
#include "AppGameDatabase.h"
|
||||
#include "ConfigurationPanels.h"
|
||||
|
||||
#include <wx/listctrl.h>
|
||||
|
||||
extern wxString DiscSerial;
|
||||
|
||||
using namespace pxSizerFlags;
|
||||
|
||||
|
||||
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(L""); sizer1+=5; sizer1+=5; \
|
||||
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);
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
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
Loading…
Reference in New Issue