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
|
RateTransposer.cpp
|
||||||
SoundTouch.cpp
|
SoundTouch.cpp
|
||||||
TDStretch.cpp
|
TDStretch.cpp
|
||||||
WavFile.cpp
|
# WavFile.cpp # directly include in spu2x
|
||||||
cpu_detect_x86_gcc.cpp
|
cpu_detect_x86_gcc.cpp
|
||||||
mmx_optimized.cpp
|
mmx_optimized.cpp
|
||||||
sse_optimized.cpp)
|
sse_optimized.cpp)
|
||||||
|
@ -55,7 +55,7 @@ set(SoundTouchHeaders
|
||||||
STTypes.h
|
STTypes.h
|
||||||
SoundTouch.h
|
SoundTouch.h
|
||||||
TDStretch.h
|
TDStretch.h
|
||||||
WavFile.h
|
# WavFile.h # directly include in spu2x
|
||||||
cpu_detect.h)
|
cpu_detect.h)
|
||||||
|
|
||||||
# add library
|
# add library
|
||||||
|
|
|
@ -23,9 +23,6 @@ if(Linux)
|
||||||
endif(GTK2_FOUND)
|
endif(GTK2_FOUND)
|
||||||
|
|
||||||
find_package(X11)
|
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)
|
endif(Linux)
|
||||||
|
|
||||||
## Use cmake package to find module
|
## Use cmake package to find module
|
||||||
|
|
|
@ -445,6 +445,10 @@
|
||||||
RelativePath="..\..\include\Utilities\pxEvents.h"
|
RelativePath="..\..\include\Utilities\pxEvents.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\include\Utilities\pxForwardDefs.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\include\Utilities\pxRadioPanel.h"
|
RelativePath="..\..\include\Utilities\pxRadioPanel.h"
|
||||||
>
|
>
|
||||||
|
|
|
@ -278,7 +278,9 @@ void CALLBACK GSsetFrameSkip(int frameskip);
|
||||||
int CALLBACK GSsetupRecording(int start, void* pData);
|
int CALLBACK GSsetupRecording(int start, void* pData);
|
||||||
|
|
||||||
void CALLBACK GSreset();
|
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);
|
void CALLBACK GSwriteCSR(u32 value);
|
||||||
s32 CALLBACK GSfreeze(int mode, freezeData *data);
|
s32 CALLBACK GSfreeze(int mode, freezeData *data);
|
||||||
void CALLBACK GSconfigure();
|
void CALLBACK GSconfigure();
|
||||||
|
@ -575,7 +577,7 @@ typedef void (CALLBACK* _GSreadFIFO)(u64 *pMem);
|
||||||
typedef void (CALLBACK* _GSreadFIFO2)(u64 *pMem, int qwc);
|
typedef void (CALLBACK* _GSreadFIFO2)(u64 *pMem, int qwc);
|
||||||
|
|
||||||
typedef void (CALLBACK* _GSchangeSaveState)(int, const char* filename);
|
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* _GSirqCallback)(void (*callback)());
|
||||||
typedef void (CALLBACK* _GSprintf)(int timeout, char *fmt, ...);
|
typedef void (CALLBACK* _GSprintf)(int timeout, char *fmt, ...);
|
||||||
typedef void (CALLBACK* _GSsetBaseMem)(void*);
|
typedef void (CALLBACK* _GSsetBaseMem)(void*);
|
||||||
|
@ -729,7 +731,7 @@ extern _GSreadFIFO GSreadFIFO;
|
||||||
extern _GSreadFIFO2 GSreadFIFO2;
|
extern _GSreadFIFO2 GSreadFIFO2;
|
||||||
|
|
||||||
extern _GSchangeSaveState GSchangeSaveState;
|
extern _GSchangeSaveState GSchangeSaveState;
|
||||||
extern _GSgetTitleInfo GSgetTitleInfo;
|
extern _GSgetTitleInfo2 GSgetTitleInfo2;
|
||||||
extern _GSmakeSnapshot GSmakeSnapshot;
|
extern _GSmakeSnapshot GSmakeSnapshot;
|
||||||
extern _GSmakeSnapshot2 GSmakeSnapshot2;
|
extern _GSmakeSnapshot2 GSmakeSnapshot2;
|
||||||
extern _GSirqCallback GSirqCallback;
|
extern _GSirqCallback GSirqCallback;
|
||||||
|
|
|
@ -18,37 +18,7 @@
|
||||||
// Dependencies.h : Contains classes required by all Utilities headers.
|
// Dependencies.h : Contains classes required by all Utilities headers.
|
||||||
// This file is included by most .h files provided by the Utilities class.
|
// This file is included by most .h files provided by the Utilities class.
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
#include "pxForwardDefs.h"
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This should prove useful....
|
// This should prove useful....
|
||||||
#define wxsFormat wxString::Format
|
#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/string.h>
|
||||||
#include <wx/intl.h>
|
#include <wx/intl.h>
|
||||||
#include <wx/log.h>
|
#include <wx/log.h>
|
||||||
|
@ -178,6 +192,9 @@ public:
|
||||||
|
|
||||||
#include "Pcsx2Defs.h"
|
#include "Pcsx2Defs.h"
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// Handy Human-readable constants for common immediate values (_16kb -> _4gb)
|
||||||
|
|
||||||
static const sptr _64kb = 0x10000;
|
static const sptr _64kb = 0x10000;
|
||||||
static const sptr _16kb = _64kb / 4;
|
static const sptr _16kb = _64kb / 4;
|
||||||
static const sptr _128kb = _64kb * 2;
|
static const sptr _128kb = _64kb * 2;
|
||||||
|
@ -193,30 +210,8 @@ static const s64 _1gb = _256mb * 4;
|
||||||
static const s64 _4gb = _1gb * 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]
|
// pxE(key, msg) and pxEt(key, msg) [macros]
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// 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]
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// Translation Feature: pxE is used as a method of dereferencing very long english text
|
// 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
|
// descriptions via a "key" identifier. In this way, the english text can be revised without
|
||||||
|
@ -226,28 +221,42 @@ extern wxString fromAscii( const char* src );
|
||||||
//
|
//
|
||||||
// Valid prefix types:
|
// 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.
|
// checkbox description, by may also include some controls with long labels.
|
||||||
// These have the highest translation priority.
|
// 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 error. These typically have very high translation priority (roughly equal
|
||||||
// or slightly less than pxE_Panel).
|
// or slightly less than pxE_Panel).
|
||||||
//
|
//
|
||||||
// .Error Key-based translation of error messages, typically used when throwing exceptions
|
// !Tooltip: Key-based translation of a tooltip for a button on a tool bar. Since buttons are
|
||||||
// that have end-user errors. These are normally (but not always) displayed as popups
|
// rarely self-explanatory, these translations are considered medium to high priority.
|
||||||
// to the user. Translation priority is medium.
|
|
||||||
//
|
//
|
||||||
// .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
|
// 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
|
// 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 )
|
#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/Assertions.h"
|
||||||
#include "Utilities/Exceptions.h"
|
#include "Utilities/Exceptions.h"
|
||||||
|
|
|
@ -184,7 +184,7 @@ public: \
|
||||||
// an App message loop we'll still want it to be handled in a reasonably graceful manner.
|
// an App message loop we'll still want it to be handled in a reasonably graceful manner.
|
||||||
class CancelEvent : public RuntimeError
|
class CancelEvent : public RuntimeError
|
||||||
{
|
{
|
||||||
DEFINE_RUNTIME_EXCEPTION( CancelEvent, RuntimeError, wxLt("No reason given.") )
|
DEFINE_RUNTIME_EXCEPTION( CancelEvent, RuntimeError, pxLt("No reason given.") )
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CancelEvent( const wxString& logmsg )
|
explicit CancelEvent( const wxString& logmsg )
|
||||||
|
@ -223,7 +223,7 @@ public: \
|
||||||
|
|
||||||
class ParseError : public RuntimeError
|
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
|
class HardwareDeficiency : public RuntimeError
|
||||||
{
|
{
|
||||||
public:
|
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 void InitCPUTicks();
|
||||||
extern u64 GetTickFrequency();
|
extern u64 GetTickFrequency();
|
||||||
extern u64 GetCPUTicks();
|
extern u64 GetCPUTicks();
|
||||||
|
extern u64 GetPhysicalMemory();
|
||||||
|
|
||||||
extern wxString GetOSVersionString();
|
extern wxString GetOSVersionString();
|
||||||
|
|
|
@ -195,16 +195,16 @@ public:
|
||||||
|
|
||||||
this->m_buffer = (T*)malloc( this->m_size * sizeof(T) );
|
this->m_buffer = (T*)malloc( this->m_size * sizeof(T) );
|
||||||
if (!this->m_buffer)
|
if (!this->m_buffer)
|
||||||
throw Exception::OutOfMemory("ScopedAlloc");
|
throw Exception::OutOfMemory(L"ScopedAlloc");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void Resize( size_t newsize )
|
virtual void Resize( size_t newsize )
|
||||||
{
|
{
|
||||||
this->m_size = 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)
|
if (!this->m_buffer)
|
||||||
throw Exception::OutOfMemory("ScopedAlloc::Resize");
|
throw Exception::OutOfMemory(L"ScopedAlloc::Resize");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -233,7 +233,8 @@ protected:
|
||||||
m_Close :1;
|
m_Close :1;
|
||||||
BITFIELD_END
|
BITFIELD_END
|
||||||
|
|
||||||
wxString m_CustomLabel;
|
wxString m_CustomLabel;
|
||||||
|
wxString m_CustomLabelId;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MsgButtons() { bitset = 0; }
|
MsgButtons() { bitset = 0; }
|
||||||
|
@ -251,9 +252,12 @@ public:
|
||||||
MsgButtons& Reset() { m_Reset = true; return *this; }
|
MsgButtons& Reset() { m_Reset = true; return *this; }
|
||||||
MsgButtons& Close() { m_Close = 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_CustomLabel = label;
|
||||||
|
m_CustomLabelId = fromUTF8(id);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +278,8 @@ public:
|
||||||
bool HasClose() const { return m_Close; }
|
bool HasClose() const { return m_Close; }
|
||||||
|
|
||||||
bool HasCustom() const { return !m_CustomLabel.IsEmpty(); }
|
bool HasCustom() const { return !m_CustomLabel.IsEmpty(); }
|
||||||
const wxString& GetCustomLabel() const { return m_CustomLabel; }
|
const wxString& GetCustomLabel() const { return m_CustomLabel; }
|
||||||
|
const wxString& GetCustomLabelId() const { return m_CustomLabelId; }
|
||||||
|
|
||||||
bool Allows( wxWindowID id ) const;
|
bool Allows( wxWindowID id ) const;
|
||||||
void SetBestFocus( wxWindow* dialog ) const;
|
void SetBestFocus( wxWindow* dialog ) const;
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "wx/filefn.h"
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// pxStreamBase
|
// pxStreamBase
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
@ -36,7 +38,10 @@ public:
|
||||||
// or wxOputStream derivative).
|
// or wxOputStream derivative).
|
||||||
virtual wxStreamBase* GetWxStreamBase() const=0;
|
virtual wxStreamBase* GetWxStreamBase() const=0;
|
||||||
virtual void Close()=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;
|
bool IsOk() const;
|
||||||
wxString GetStreamName() const { return m_filename; }
|
wxString GetStreamName() const { return m_filename; }
|
||||||
};
|
};
|
||||||
|
@ -71,6 +76,9 @@ public:
|
||||||
{
|
{
|
||||||
Write( &data, sizeof(data) );
|
Write( &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxFileOffset Tell() const;
|
||||||
|
wxFileOffset Seek( wxFileOffset ofs, wxSeekMode mode = wxFromStart );
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
@ -102,4 +110,7 @@ public:
|
||||||
{
|
{
|
||||||
Read( &dest, sizeof(dest) );
|
Read( &dest, sizeof(dest) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxFileOffset Tell() const;
|
||||||
|
wxFileOffset Seek( wxFileOffset ofs, wxSeekMode mode = wxFromStart );
|
||||||
};
|
};
|
||||||
|
|
|
@ -522,6 +522,7 @@ public:
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
class wxDialogWithHelpers : public wxDialog
|
class wxDialogWithHelpers : public wxDialog
|
||||||
{
|
{
|
||||||
|
typedef wxDialog _parent;
|
||||||
DECLARE_DYNAMIC_CLASS_NO_COPY(wxDialogWithHelpers)
|
DECLARE_DYNAMIC_CLASS_NO_COPY(wxDialogWithHelpers)
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -541,6 +542,7 @@ public:
|
||||||
virtual void SmartCenterFit();
|
virtual void SmartCenterFit();
|
||||||
virtual int ShowModal();
|
virtual int ShowModal();
|
||||||
virtual bool Show( bool show=true );
|
virtual bool Show( bool show=true );
|
||||||
|
virtual bool Destroy();
|
||||||
|
|
||||||
// Must return the same thing as GetNameStatic; a name ideal for use in uniquely
|
// 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
|
// identifying dialogs. (this version is the 'instance' version, which is called
|
||||||
|
|
|
@ -31,8 +31,6 @@ class x86capabilities
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool isIdentified;
|
bool isIdentified;
|
||||||
u32 LogicalCoresPerPhysicalCPU;
|
|
||||||
u32 PhysicalCoresPerPhysicalCPU;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
x86VendorType VendorID;
|
x86VendorType VendorID;
|
||||||
|
@ -106,8 +104,6 @@ public:
|
||||||
{
|
{
|
||||||
isIdentified = false;
|
isIdentified = false;
|
||||||
VendorID = x86Vendor_Unknown;
|
VendorID = x86Vendor_Unknown;
|
||||||
LogicalCoresPerPhysicalCPU = 1;
|
|
||||||
PhysicalCoresPerPhysicalCPU = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Identify();
|
void Identify();
|
||||||
|
|
|
@ -251,7 +251,7 @@ wxString Exception::VirtualMemoryMapConflict::FormatDisplayMessage() const
|
||||||
{
|
{
|
||||||
FastFormatUnicode retmsg;
|
FastFormatUnicode retmsg;
|
||||||
retmsg.Write( L"%s",
|
retmsg.Write( L"%s",
|
||||||
pxE( ".Error:VirtualMemoryMap",
|
pxE( "!Notice:VirtualMemoryMap",
|
||||||
L"There is not enough virtual memory available, or necessary virtual memory "
|
L"There is not enough virtual memory available, or necessary virtual memory "
|
||||||
L"mappings have already been reserved by other processes, services, or DLLs."
|
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).
|
// pretty well stops all PCSX2 threads anyway).
|
||||||
|
|
||||||
Munmap(base, size);
|
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. "
|
"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
|
"This is likely caused by multi-thread memory contention.", base, (uptr)base+size
|
||||||
));
|
));
|
||||||
|
|
|
@ -20,11 +20,18 @@
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <wx/utils.h>
|
#include <wx/utils.h>
|
||||||
|
|
||||||
extern "C" __aligned16 u8 _xmm_backup[16*2];
|
// Returns 0 on failure (not supported by the operating system).
|
||||||
extern "C" __aligned16 u8 _mmx_backup[8*4];
|
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()
|
void InitCPUTicks()
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,7 +38,7 @@ ConsoleLogSource_Threading::ConsoleLogSource_Threading()
|
||||||
static const TraceLogDescriptor myDesc =
|
static const TraceLogDescriptor myDesc =
|
||||||
{
|
{
|
||||||
L"pxThread", L"pxThread",
|
L"pxThread", L"pxThread",
|
||||||
wxLt("Threading activity: start, detach, sync, deletion, etc.")
|
pxLt("Threading activity: start, detach, sync, deletion, etc.")
|
||||||
};
|
};
|
||||||
|
|
||||||
m_Descriptor = &myDesc;
|
m_Descriptor = &myDesc;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include <winnt.h>
|
#include <winnt.h>
|
||||||
|
|
||||||
|
|
||||||
int SysPageFaultExceptionFilter( EXCEPTION_POINTERS* eps )
|
int SysPageFaultExceptionFilter( EXCEPTION_POINTERS* eps )
|
||||||
{
|
{
|
||||||
if( eps->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION )
|
if( eps->ExceptionRecord->ExceptionCode != EXCEPTION_ACCESS_VIOLATION )
|
||||||
|
|
|
@ -39,6 +39,14 @@ u64 GetCPUTicks()
|
||||||
return count.QuadPart;
|
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:
|
// Windows SDK 7 provides this but previous ones do not, so roll our own in those cases:
|
||||||
#ifndef VER_SUITE_WH_SERVER
|
#ifndef VER_SUITE_WH_SERVER
|
||||||
# define VER_SUITE_WH_SERVER 0x00008000
|
# define VER_SUITE_WH_SERVER 0x00008000
|
||||||
|
|
|
@ -35,6 +35,12 @@ bool pxStreamBase::IsOk() const
|
||||||
return woot && woot->IsOk();
|
return woot && woot->IsOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxFileOffset pxStreamBase::Length() const
|
||||||
|
{
|
||||||
|
if (!GetWxStreamBase()) return 0;
|
||||||
|
return GetWxStreamBase()->GetLength();
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// pxInputStream (implementations)
|
// pxInputStream (implementations)
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
@ -55,6 +61,16 @@ pxInputStream::pxInputStream(const wxString& filename, wxInputStream* input)
|
||||||
|
|
||||||
wxStreamBase* pxInputStream::GetWxStreamBase() const { return m_stream_in.GetPtr(); }
|
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 )
|
void pxInputStream::SetStream( const wxString& filename, ScopedPtr<wxInputStream>& stream )
|
||||||
{
|
{
|
||||||
m_filename = filename;
|
m_filename = filename;
|
||||||
|
@ -107,6 +123,15 @@ pxOutputStream::pxOutputStream(const wxString& filename, wxOutputStream* output)
|
||||||
|
|
||||||
wxStreamBase* pxOutputStream::GetWxStreamBase() const { return m_stream_out.GetPtr(); }
|
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 )
|
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
|
// (without this second pass many tooltips would just show up as "Savestate Tooltip" instead
|
||||||
// of something meaningful).
|
// 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).
|
// 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
|
// 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 )
|
const wxChar* __fastcall pxExpandMsg( const wxChar* key, const wxChar* englishContent )
|
||||||
{
|
{
|
||||||
#ifdef PCSX2_DEVBUILD
|
#ifdef PCSX2_DEVBUILD
|
||||||
static const wxChar* tbl_pxE_Prefixes[] =
|
static const wxChar* tbl_pxE_Prefixes[] =
|
||||||
{
|
{
|
||||||
L".Panel:",
|
L"!Panel:",
|
||||||
L".Popup:",
|
L"!Notice:",
|
||||||
L".Error:",
|
L"!Wizard:",
|
||||||
L".Wizard:",
|
L"!Tooltip:",
|
||||||
L".Tooltip:",
|
L"!ContextTip:",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,7 +62,7 @@ const wxChar* __fastcall pxExpandMsg( const wxChar* key, const wxChar* englishCo
|
||||||
++prefix;
|
++prefix;
|
||||||
}
|
}
|
||||||
pxAssertDev( *prefix != NULL,
|
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
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ ConsoleLogSource_App::ConsoleLogSource_App()
|
||||||
static const TraceLogDescriptor myDesc =
|
static const TraceLogDescriptor myDesc =
|
||||||
{
|
{
|
||||||
L"AppEvents", L"App Events",
|
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;
|
m_Descriptor = &myDesc;
|
||||||
|
|
|
@ -274,13 +274,13 @@ pxStaticText& wxDialogWithHelpers::Heading( const wxString& label )
|
||||||
return *new pxStaticHeading( this, label );
|
return *new pxStaticHeading( this, label );
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxDialogWithHelpers::OnCloseWindow( wxCloseEvent& evt )
|
bool wxDialogWithHelpers::Destroy()
|
||||||
{
|
{
|
||||||
// Save the dialog position if the dialog is named...
|
// 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.
|
// FIXME : This doesn't get called if the app is exited by alt-f4'ing the main app window.
|
||||||
// ... not sure how to fix that yet. I could register a list of open windows into wxAppWithHelpers
|
// ... not sure how to fix that yet. I could register a list of open windows into wxAppWithHelpers
|
||||||
// that systematically get closed. Seems like work, maybe later. --air
|
// that systematically get closed. Seems like work, maybe later. --air
|
||||||
|
|
||||||
if( wxConfigBase* cfg = IsIconized() ? NULL : wxConfigBase::Get( false ) )
|
if( wxConfigBase* cfg = IsIconized() ? NULL : wxConfigBase::Get( false ) )
|
||||||
{
|
{
|
||||||
const wxString dlgName( GetDialogName() );
|
const wxString dlgName( GetDialogName() );
|
||||||
|
@ -300,6 +300,11 @@ void wxDialogWithHelpers::OnCloseWindow( wxCloseEvent& evt )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return _parent::Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxDialogWithHelpers::OnCloseWindow( wxCloseEvent& evt )
|
||||||
|
{
|
||||||
if( !IsModal() ) Destroy();
|
if( !IsModal() ) Destroy();
|
||||||
evt.Skip();
|
evt.Skip();
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,11 +183,11 @@ __fi void memcpy_vibes(void * dest, const void * src, int size) {
|
||||||
__asm__ __volatile__
|
__asm__ __volatile__
|
||||||
(
|
(
|
||||||
".intel_syntax noprefix\n"
|
".intel_syntax noprefix\n"
|
||||||
"mov eax, %[qwc]\n" // keep a copy of count for looping
|
"sub %[qwc], 1\n" // dec the counter to ease the count of 16bytes block later (optimization)
|
||||||
"shr eax, 1\n"
|
// Note after this line, real value of the counter is %[qwc] + 1
|
||||||
"jz memcpy_qwc_1_%=\n" // only one 16 byte block to copy?
|
"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)
|
"jb memcpy_qwc_loop1_%=\n" // small copies should be cached (definite speedup --air)
|
||||||
|
|
||||||
"memcpy_qwc_loop2_%=:\n" // 32-byte blocks, uncached copy
|
"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 %[src],32\n" // update source pointer
|
||||||
"add %[dest],32\n" // update destination pointer
|
"add %[dest],32\n" // update destination pointer
|
||||||
"sub eax,1\n"
|
"sub %[qwc],2\n"
|
||||||
"jnz memcpy_qwc_loop2_%=\n" // last 64-byte block?
|
"jg memcpy_qwc_loop2_%=\n" // last 64-byte block?
|
||||||
"sfence\n" // flush the write buffer
|
"sfence\n" // flush the write buffer
|
||||||
"jmp memcpy_qwc_1_%=\n"
|
"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 %[src],32\n" // update source pointer
|
||||||
"add %[dest],32\n" // update destination pointer
|
"add %[dest],32\n" // update destination pointer
|
||||||
"sub eax,1\n"
|
"sub %[qwc],2\n"
|
||||||
"jnz memcpy_qwc_loop1_%=\n" // last 64-byte block?
|
"jg memcpy_qwc_loop2_%=\n" // last 64-byte block?
|
||||||
|
|
||||||
"memcpy_qwc_1_%=:\n"
|
"memcpy_qwc_1_%=:\n"
|
||||||
"test %[qwc],1\n"
|
"cmp %[qwc],0\n"
|
||||||
"jz memcpy_qwc_final_%=\n"
|
"jne memcpy_qwc_final_%=\n"
|
||||||
"movq mm0,[%[src]]\n"
|
"movq mm0,[%[src]]\n"
|
||||||
"movq mm1,[%[src]+8]\n"
|
"movq mm1,[%[src]+8]\n"
|
||||||
"movq [%[dest]], mm0\n"
|
"movq [%[dest]], mm0\n"
|
||||||
|
@ -243,7 +243,7 @@ __fi void memcpy_vibes(void * dest, const void * src, int size) {
|
||||||
".att_syntax\n"
|
".att_syntax\n"
|
||||||
: "=&r"(dest), "=&r"(src), "=&r"(qwc)
|
: "=&r"(dest), "=&r"(src), "=&r"(qwc)
|
||||||
: [dest]"0"(dest), [src]"1"(src), [qwc]"2"(qwc)
|
: [dest]"0"(dest), [src]"1"(src), [qwc]"2"(qwc)
|
||||||
: "memory", "eax", "mm0", "mm1", "mm2", "mm3"
|
: "memory", "mm0", "mm1", "mm2", "mm3"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,24 +16,16 @@
|
||||||
|
|
||||||
#include "PrecompiledHeader.h"
|
#include "PrecompiledHeader.h"
|
||||||
#include "cpudetect_internal.h"
|
#include "cpudetect_internal.h"
|
||||||
|
#include <wx/thread.h>
|
||||||
|
|
||||||
// Note: Apparently this solution is Linux/Solaris only.
|
// Note: Apparently this solution is Linux/Solaris only.
|
||||||
// FreeBSD/OsX need something far more complicated (apparently)
|
// FreeBSD/OsX need something far more complicated (apparently)
|
||||||
void x86capabilities::CountLogicalCores()
|
void x86capabilities::CountLogicalCores()
|
||||||
{
|
{
|
||||||
const uint numCPU = sysconf( _SC_NPROCESSORS_ONLN );
|
// Note : GetCPUCount uses sysconf( _SC_NPROCESSORS_ONLN ) internally, which can return 1
|
||||||
if( numCPU > 0 )
|
// if sysconf info isn't available (a long standing linux bug). There are no fallbacks or
|
||||||
{
|
// alternatives, apparently.
|
||||||
//isMultiCore = numCPU > 1;
|
LogicalCores = wxThread::GetCPUCount();
|
||||||
LogicalCores = numCPU;
|
|
||||||
PhysicalCores = ( numCPU / LogicalCoresPerPhysicalCPU ) * PhysicalCoresPerPhysicalCPU;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Indeterminate?
|
|
||||||
LogicalCores = 1;
|
|
||||||
PhysicalCores = 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanEmitShit()
|
bool CanEmitShit()
|
||||||
|
|
|
@ -37,10 +37,6 @@ void x86capabilities::CountLogicalCores()
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicalCores = CPUs;
|
LogicalCores = CPUs;
|
||||||
if( LogicalCoresPerPhysicalCPU > CPUs) // for 1-socket HTT-disabled machines
|
|
||||||
LogicalCoresPerPhysicalCPU = CPUs;
|
|
||||||
|
|
||||||
PhysicalCores = ( CPUs / LogicalCoresPerPhysicalCPU ) * PhysicalCoresPerPhysicalCPU;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _test_instruction( void* pfnCall )
|
bool _test_instruction( void* pfnCall )
|
||||||
|
|
|
@ -133,23 +133,6 @@ void x86capabilities::CountCores()
|
||||||
s32 regs[ 4 ];
|
s32 regs[ 4 ];
|
||||||
u32 cmds;
|
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 );
|
__cpuid( regs, 0x80000000 );
|
||||||
cmds = regs[ 0 ];
|
cmds = regs[ 0 ];
|
||||||
|
|
||||||
|
@ -157,9 +140,6 @@ void x86capabilities::CountCores()
|
||||||
|
|
||||||
if ((cmds >= 0x80000008) && (VendorID == x86Vendor_AMD) )
|
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
|
// 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.
|
// 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
|
// (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;
|
hasMultiThreading = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !hasMultiThreading || LogicalCoresPerPhysicalCPU == 0 )
|
|
||||||
LogicalCoresPerPhysicalCPU = 1;
|
|
||||||
|
|
||||||
// This will assign values into LogicalCores and PhysicalCores
|
// This will assign values into LogicalCores and PhysicalCores
|
||||||
CountLogicalCores();
|
CountLogicalCores();
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,9 +122,6 @@ find $NEW_DIR -name "configure.ac" -exec rm -f {} \;
|
||||||
find $NEW_DIR -name "Makefile.am" -exec rm -f {} \;
|
find $NEW_DIR -name "Makefile.am" -exec rm -f {} \;
|
||||||
echo "Remove 3rd party directories"
|
echo "Remove 3rd party directories"
|
||||||
find $NEW_DIR -name "3rdparty" -exec rm -fr {} \; 2> /dev/null
|
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)"
|
echo "Remove windows file (useless & copyright issue)"
|
||||||
find $NEW_DIR -iname "windows" -type d -exec rm -fr {} \; 2> /dev/null
|
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
|
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)"
|
echo "Remove useless files (copyright issues)"
|
||||||
rm -fr "${NEW_DIR}/plugins/zzogl-pg/opengl/ZeroGSShaders"
|
rm -fr "${NEW_DIR}/plugins/zzogl-pg/opengl/ZeroGSShaders"
|
||||||
rm -fr "${NEW_DIR}/common/src/Utilities/x86/MemcpyFast.cpp"
|
rm -fr "${NEW_DIR}/common/src/Utilities/x86/MemcpyFast.cpp"
|
||||||
rm -fr "${NEW_DIR}/plugins/zzogl-pg/opengl/memcpy_amd.cpp"
|
|
||||||
|
|
||||||
## BUILD
|
## BUILD
|
||||||
echo "Build the tar.gz file"
|
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
|
01_rename_binary_generated.patch
|
||||||
02_update_default_path.patch
|
02_update_default_path.patch
|
||||||
05_move_data_to_config.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)
|
if (!ENABLE_LOADING_PS1_GAMES)
|
||||||
Cpu->ThrowException( Exception::RuntimeError()
|
Cpu->ThrowException( Exception::RuntimeError()
|
||||||
.SetDiagMsg(L"PSX game discs are not supported by PCSX2.")
|
.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"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.")
|
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)
|
// (and if numparts is incremented, elsn will get assigned accordingly)
|
||||||
|
|
||||||
if (!Detect())
|
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))
|
if (!(m_flags & ISOFLAGS_BLOCKDUMP_V2))
|
||||||
{
|
{
|
||||||
|
|
|
@ -274,7 +274,6 @@ set(pcsx2DebugToolsHeaders
|
||||||
|
|
||||||
# gui sources
|
# gui sources
|
||||||
set(pcsx2GuiSources
|
set(pcsx2GuiSources
|
||||||
gui/AdvancedDialog.cpp
|
|
||||||
gui/AppAssert.cpp
|
gui/AppAssert.cpp
|
||||||
gui/AppConfig.cpp
|
gui/AppConfig.cpp
|
||||||
gui/AppCorePlugins.cpp
|
gui/AppCorePlugins.cpp
|
||||||
|
@ -338,7 +337,6 @@ set(pcsx2GuiSources
|
||||||
|
|
||||||
# gui headers
|
# gui headers
|
||||||
set(pcsx2GuiHeaders
|
set(pcsx2GuiHeaders
|
||||||
gui/AdvancedDialog.h
|
|
||||||
gui/App.h
|
gui/App.h
|
||||||
gui/ApplyState.h
|
gui/ApplyState.h
|
||||||
gui/AppAccelerators.h
|
gui/AppAccelerators.h
|
||||||
|
|
|
@ -400,7 +400,7 @@ struct Pcsx2Config
|
||||||
|
|
||||||
// when enabled uses BOOT2 injection, skipping sony bios splashes
|
// when enabled uses BOOT2 injection, skipping sony bios splashes
|
||||||
UseBOOT2Injection :1,
|
UseBOOT2Injection :1,
|
||||||
|
BackupSavestate :1,
|
||||||
// enables simulated ejection of memory cards when loading savestates
|
// enables simulated ejection of memory cards when loading savestates
|
||||||
McdEnableEjection :1,
|
McdEnableEjection :1,
|
||||||
|
|
||||||
|
|
|
@ -556,7 +556,9 @@ extern tDMA_TAG *dmaGetAddr(u32 addr, bool write);
|
||||||
extern void hwIntcIrq(int n);
|
extern void hwIntcIrq(int n);
|
||||||
extern void hwDmacIrq(int n);
|
extern void hwDmacIrq(int n);
|
||||||
|
|
||||||
|
extern void FireMFIFOEmpty();
|
||||||
extern bool hwMFIFOWrite(u32 addr, const u128* data, uint size_qwc);
|
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 hwDmacSrcChainWithStack(DMACh& dma, int id);
|
||||||
extern bool hwDmacSrcChain(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);
|
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)
|
void ElfObject::checkElfSize(s64 elfsize)
|
||||||
{
|
{
|
||||||
if (elfsize > 0xfffffff)
|
const wxChar* diagMsg = NULL;
|
||||||
throw Exception::BadStream(filename).SetBothMsgs(wxLt("Illegal ELF file size over 2GB!"));
|
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)
|
if (diagMsg)
|
||||||
throw Exception::BadStream(filename).SetBothMsgs(wxLt("ELF file does not exist!"));
|
throw Exception::BadStream(filename)
|
||||||
|
.SetDiagMsg(diagMsg)
|
||||||
if (elfsize == 0)
|
.SetUserMsg(GetMsg_InvalidELF());
|
||||||
throw Exception::BadStream(filename).SetBothMsgs(wxLt("Unexpected end of ELF file."));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 ElfObject::getCRC()
|
u32 ElfObject::getCRC()
|
||||||
|
|
184
pcsx2/Gif.cpp
184
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).
|
// 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.
|
// 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 int gifstate = GIF_STATE_READY;
|
||||||
static bool gifempty = false;
|
|
||||||
|
|
||||||
static bool gspath3done = false;
|
static bool gspath3done = false;
|
||||||
|
|
||||||
|
@ -47,14 +46,14 @@ static __fi void clearFIFOstuff(bool full)
|
||||||
else
|
else
|
||||||
CSRreg.FIFO = CSR_FIFO_EMPTY;
|
CSRreg.FIFO = CSR_FIFO_EMPTY;
|
||||||
}
|
}
|
||||||
|
extern bool SIGNAL_IMR_Pending;
|
||||||
void gsPath1Interrupt()
|
void gsPath1Interrupt()
|
||||||
{
|
{
|
||||||
//DevCon.Warning("Path1 flush W %x, R %x", Path1WritePos, Path1ReadPos);
|
//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;
|
gifRegs.stat.P1Q = false;
|
||||||
|
|
||||||
|
@ -62,7 +61,7 @@ void gsPath1Interrupt()
|
||||||
{
|
{
|
||||||
GetMTGS().PrepDataPacket(GIF_PATH_1, size);
|
GetMTGS().PrepDataPacket(GIF_PATH_1, size);
|
||||||
//DevCon.Warning("Flush Size = %x", 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);
|
uint count = GIFPath_CopyTag(GIF_PATH_1, ((u128*)Path1Buffer) + Path1ReadPos, size);
|
||||||
Path1ReadPos += count;
|
Path1ReadPos += count;
|
||||||
|
@ -79,13 +78,18 @@ void gsPath1Interrupt()
|
||||||
if(Path1ReadPos == Path1WritePos)
|
if(Path1ReadPos == Path1WritePos)
|
||||||
{
|
{
|
||||||
Path1WritePos = Path1ReadPos = 0;
|
Path1WritePos = Path1ReadPos = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//DevCon.Warning("Queue quitting early due to signal or EOP %x", size);
|
||||||
|
gifRegs.stat.P1Q = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(gifRegs.stat.PSE) DevCon.Warning("Path1 paused by GIF_CTRL");
|
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);
|
//if(!(cpuRegs.interrupt & (1<<28)) && Path1WritePos > 0)CPU_INT(28, 128);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,6 +101,13 @@ __fi void gsInterrupt()
|
||||||
{
|
{
|
||||||
GIF_LOG("gsInterrupt caught!");
|
GIF_LOG("gsInterrupt caught!");
|
||||||
|
|
||||||
|
if (dmacRegs.ctrl.MFD == MFD_GIF) // GIF MFIFO
|
||||||
|
{
|
||||||
|
//Console.WriteLn("GIF MFIFO");
|
||||||
|
gifMFIFOInterrupt();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(SIGNAL_IMR_Pending == true)
|
if(SIGNAL_IMR_Pending == true)
|
||||||
{
|
{
|
||||||
//DevCon.Warning("Path 3 Paused");
|
//DevCon.Warning("Path 3 Paused");
|
||||||
|
@ -234,6 +245,7 @@ bool CheckPaths(int Channel)
|
||||||
{
|
{
|
||||||
if((vif1.cmd & 0x7f) != 0x51 || gifRegs.stat.P1Q == true)
|
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;
|
gifRegs.stat.IP3 = true;
|
||||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||||
CPU_INT(DMAC_GIF, 16);
|
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).
|
//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))
|
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;
|
gifRegs.stat.IP3 = true;
|
||||||
CPU_INT(DMAC_GIF, 16);
|
CPU_INT(DMAC_GIF, 16);
|
||||||
return false;
|
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:
|
// called from only one location, so forceinline it:
|
||||||
static __fi bool mfifoGIFrbTransfer()
|
static __fi bool mfifoGIFrbTransfer()
|
||||||
{
|
{
|
||||||
u32 mfifoqwc = min(gifqwc, (u32)gifch.qwc);
|
u16 mfifoqwc = min(QWCinGIFMFIFO(gifch.madr), gifch.qwc);
|
||||||
u32 *src;
|
u32 *src;
|
||||||
|
|
||||||
|
if(mfifoqwc == 0) return true; //Lets skip all this, we don't have the data
|
||||||
|
|
||||||
GetMTGS().PrepDataPacket(GIF_PATH_3, mfifoqwc);
|
GetMTGS().PrepDataPacket(GIF_PATH_3, mfifoqwc);
|
||||||
|
|
||||||
// TODO (minor optimization): The new GIFpath parser can do rather efficient wrapping of
|
// 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
|
// 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.
|
// 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 */
|
/* 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 s1 = ((dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16) - gifch.madr) >> 4;
|
||||||
uint s2 = (mfifoqwc - s1);
|
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' */
|
/* it does (wrap around), so first copy 's1' bytes from 'addr' to 'data' */
|
||||||
/* and second copy 's2' bytes from 'maddr' to '&data[s1]' */
|
/* 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);
|
src = (u32*)PSM(gifch.madr);
|
||||||
if (src == NULL) return false;
|
if (src == NULL) return false;
|
||||||
uint copied = GIFPath_CopyTag(GIF_PATH_3, (u128*)src, s1);
|
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.
|
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);
|
src = (u32*)PSM(dmacRegs.rbor.ADDR);
|
||||||
|
gifch.madr = dmacRegs.rbor.ADDR;
|
||||||
if (src == NULL) return false;
|
if (src == NULL) return false;
|
||||||
copied += GIFPath_CopyTag(GIF_PATH_3, (u128*)src, s2);
|
copied += GIFPath_CopyTag(GIF_PATH_3, (u128*)src, s2);
|
||||||
}
|
}
|
||||||
|
|
||||||
mfifoqwc = copied;
|
mfifoqwc = copied;
|
||||||
|
GIF_LOG("Copied %x QWC, %x QWC Left", mfifoqwc, gifch.qwc);
|
||||||
}
|
}
|
||||||
else
|
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 */
|
/* 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);
|
src = (u32*)PSM(gifch.madr);
|
||||||
if (src == NULL) return false;
|
if (src == NULL) return false;
|
||||||
mfifoqwc = GIFPath_CopyTag(GIF_PATH_3, (u128*)src, mfifoqwc);
|
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();
|
GetMTGS().SendDataPacket();
|
||||||
gifqwc -= mfifoqwc;
|
//gifqwc -= mfifoqwc;
|
||||||
|
mfifocycles += (mfifoqwc) * 2; /* guessing */
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -496,14 +538,19 @@ static __fi bool mfifoGIFchain()
|
||||||
if (gifch.qwc == 0) return true;
|
if (gifch.qwc == 0) return true;
|
||||||
|
|
||||||
if (gifch.madr >= dmacRegs.rbor.ADDR &&
|
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
|
else
|
||||||
{
|
{
|
||||||
int mfifoqwc;
|
int mfifoqwc;
|
||||||
|
GIF_LOG("Non-MFIFO Location transfer doing %x Total QWC", gifch.qwc);
|
||||||
tDMA_TAG *pMem = dmaGetAddr(gifch.madr, false);
|
tDMA_TAG *pMem = dmaGetAddr(gifch.madr, false);
|
||||||
if (pMem == NULL) return false;
|
if (pMem == NULL) return false;
|
||||||
|
|
||||||
|
@ -528,12 +575,13 @@ void mfifoGIFtransfer(int qwc)
|
||||||
|
|
||||||
if(qwc > 0 )
|
if(qwc > 0 )
|
||||||
{
|
{
|
||||||
gifqwc += qwc;
|
if ((gifstate & GIF_STATE_EMPTY) && !(cpuRegs.interrupt & (1<<DMAC_MFIFO_GIF)))
|
||||||
|
{
|
||||||
if (!(gifstate & GIF_STATE_EMPTY)) return;
|
if(gifch.chcr.STR == true)CPU_INT(DMAC_MFIFO_GIF, 4);
|
||||||
// if (gifempty == false) return;
|
gifstate &= ~GIF_STATE_EMPTY;
|
||||||
gifstate &= ~GIF_STATE_EMPTY;
|
}
|
||||||
gifempty = false;
|
gifRegs.stat.FQC = 16;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gifRegs.ctrl.PSE) // temporarily stop
|
if (gifRegs.ctrl.PSE) // temporarily stop
|
||||||
|
@ -545,15 +593,6 @@ void mfifoGIFtransfer(int qwc)
|
||||||
|
|
||||||
if (gifch.qwc == 0)
|
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);
|
gifch.tadr = qwctag(gifch.tadr);
|
||||||
|
|
||||||
ptag = dmaGetAddr(gifch.tadr, false);
|
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",
|
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);
|
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)
|
if(gspath3done == true) gifstate = GIF_STATE_DONE;
|
||||||
{
|
else gifstate = GIF_STATE_READY;
|
||||||
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 ((gifch.chcr.TIE) && (ptag->IRQ))
|
if ((gifch.chcr.TIE) && (ptag->IRQ))
|
||||||
{
|
{
|
||||||
|
@ -608,7 +615,8 @@ void mfifoGIFtransfer(int qwc)
|
||||||
gifstate = GIF_STATE_DONE;
|
gifstate = GIF_STATE_DONE;
|
||||||
gifmfifoirq = true;
|
gifmfifoirq = true;
|
||||||
}
|
}
|
||||||
}
|
if (QWCinGIFMFIFO(gifch.tadr) == 0) gifstate |= GIF_STATE_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
if (!mfifoGIFchain())
|
if (!mfifoGIFchain())
|
||||||
{
|
{
|
||||||
|
@ -616,7 +624,7 @@ void mfifoGIFtransfer(int qwc)
|
||||||
gifstate = GIF_STATE_STALL;
|
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);
|
CPU_INT(DMAC_MFIFO_GIF,mfifocycles);
|
||||||
|
|
||||||
SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gifch.chcr._u32, gifch.madr, gifch.tadr);
|
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()
|
void gifMFIFOInterrupt()
|
||||||
{
|
{
|
||||||
//Console.WriteLn("gifMFIFOInterrupt");
|
GIF_LOG("gifMFIFOInterrupt");
|
||||||
mfifocycles = 0;
|
mfifocycles = 0;
|
||||||
|
|
||||||
|
if (dmacRegs.ctrl.MFD != MFD_GIF)
|
||||||
|
{
|
||||||
|
DevCon.Warning("Not in GIF MFIFO mode! Stopping GIF MFIFO");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(SIGNAL_IMR_Pending == true)
|
if(SIGNAL_IMR_Pending == true)
|
||||||
{
|
{
|
||||||
//DevCon.Warning("Path 3 Paused");
|
//DevCon.Warning("Path 3 Paused");
|
||||||
|
@ -634,13 +648,20 @@ void gifMFIFOInterrupt()
|
||||||
return;
|
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;
|
gifRegs.stat.OPH = false;
|
||||||
|
GSTransferStatus.PTH3 = STOPPED_MODE;
|
||||||
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
gifRegs.stat.APATH = GIF_APATH_IDLE;
|
||||||
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
if(gifRegs.stat.P1Q) gsPath1Interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if((gifstate & GIF_STATE_EMPTY))
|
||||||
|
{
|
||||||
|
FireMFIFOEmpty();
|
||||||
|
if(!(gifstate & GIF_STATE_STALL)) return;
|
||||||
|
}
|
||||||
|
|
||||||
if(CheckPaths(11) == false) return;
|
if(CheckPaths(11) == false) return;
|
||||||
|
|
||||||
if (!(gifch.chcr.STR))
|
if (!(gifch.chcr.STR))
|
||||||
|
@ -652,16 +673,13 @@ void gifMFIFOInterrupt()
|
||||||
|
|
||||||
if (!(gifstate & GIF_STATE_STALL))
|
if (!(gifstate & GIF_STATE_STALL))
|
||||||
{
|
{
|
||||||
if (gifqwc <= 0)
|
if (QWCinGIFMFIFO(gifch.tadr) == 0)
|
||||||
{
|
{
|
||||||
//Console.WriteLn("Empty");
|
|
||||||
hwDmacIrq(DMAC_MFIFO_EMPTY);
|
|
||||||
gifstate |= GIF_STATE_EMPTY;
|
gifstate |= GIF_STATE_EMPTY;
|
||||||
gifempty = true;
|
CPU_INT(DMAC_MFIFO_GIF, 4);
|
||||||
|
|
||||||
gifRegs.stat.IMT = false;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mfifoGIFtransfer(0);
|
mfifoGIFtransfer(0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -685,6 +703,7 @@ void gifMFIFOInterrupt()
|
||||||
gifch.chcr.STR = false;
|
gifch.chcr.STR = false;
|
||||||
gifstate = GIF_STATE_READY;
|
gifstate = GIF_STATE_READY;
|
||||||
hwDmacIrq(DMAC_GIF);
|
hwDmacIrq(DMAC_GIF);
|
||||||
|
GIF_LOG("gifMFIFO End");
|
||||||
clearFIFOstuff(false);
|
clearFIFOstuff(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,7 +715,6 @@ void SaveStateBase::gifFreeze()
|
||||||
Freeze( gifqwc );
|
Freeze( gifqwc );
|
||||||
Freeze( gspath3done );
|
Freeze( gspath3done );
|
||||||
Freeze( gscycles );
|
Freeze( gscycles );
|
||||||
//Freeze(gifempty);
|
|
||||||
// Note: mfifocycles is not a persistent var, so no need to save it here.
|
// Note: mfifocycles is not a persistent var, so no need to save it here.
|
||||||
|
|
||||||
int bufsize = Path1WritePos - Path1ReadPos;
|
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
|
enum GSTransferModes //0 = Image Mode (DirectHL), 1 = transferring, 2 = Stopped at End of Packet
|
||||||
{
|
{
|
||||||
PENDINGIMAGE_MODE = 0,
|
WAITING_MODE = 0,
|
||||||
IMAGE_MODE = 1,
|
IMAGE_MODE = 1,
|
||||||
TRANSFER_MODE = 2,
|
TRANSFER_MODE = 2,
|
||||||
PENDINGSTOP_MODE = 3,
|
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();
|
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'.
|
// Write 'size' bytes to memory address 'addr' from 'data'.
|
||||||
__ri bool hwMFIFOWrite(u32 addr, const u128* data, uint qwc)
|
__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((dmacRegs.rbor.ADDR & 15) == 0);
|
||||||
pxAssume((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
|
// 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
|
// 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
|
// 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) {
|
__ri bool hwDmacSrcChainWithStack(DMACh& dma, int id) {
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
|
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
|
||||||
|
dma.tadr += 16;
|
||||||
//End Transfer
|
//End Transfer
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
||||||
// Set MADR to QW afer tag, and set TADR to QW following the data.
|
// Set MADR to QW afer tag, and set TADR to QW following the data.
|
||||||
dma.madr = dma.tadr + 16;
|
dma.tadr += 16;
|
||||||
dma.tadr = dma.madr + (dma.qwc << 4);
|
dma.madr = dma.tadr;
|
||||||
|
//dma.tadr = dma.madr + (dma.qwc << 4);
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
|
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
|
||||||
|
@ -267,6 +278,33 @@ __ri bool hwDmacSrcChainWithStack(DMACh& dma, int id) {
|
||||||
return false;
|
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)
|
bool hwDmacSrcChain(DMACh& dma, int id)
|
||||||
{
|
{
|
||||||
u32 temp;
|
u32 temp;
|
||||||
|
@ -274,13 +312,14 @@ bool hwDmacSrcChain(DMACh& dma, int id)
|
||||||
switch (id)
|
switch (id)
|
||||||
{
|
{
|
||||||
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
|
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
|
||||||
|
dma.tadr += 16;
|
||||||
// End the transfer.
|
// End the transfer.
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
||||||
// Set MADR to QW after the tag, and TADR to QW following the data.
|
// Set MADR to QW after the tag, and TADR to QW following the data.
|
||||||
dma.madr = dma.tadr + 16;
|
dma.madr = dma.tadr + 16;
|
||||||
dma.tadr = dma.madr + (dma.qwc << 4);
|
dma.tadr = dma.madr;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
|
case TAG_NEXT: // Next - Transfer QWC following tag. TADR = ADDR
|
||||||
|
@ -305,3 +344,4 @@ bool hwDmacSrcChain(DMACh& dma, int id)
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -308,6 +308,7 @@ enum EERegisterAddresses
|
||||||
DMAC_RBSR = 0x1000E040,
|
DMAC_RBSR = 0x1000E040,
|
||||||
DMAC_RBOR = 0x1000E050,
|
DMAC_RBOR = 0x1000E050,
|
||||||
DMAC_STADR = 0x1000E060,
|
DMAC_STADR = 0x1000E060,
|
||||||
|
DMAC_FAKESTAT = 0x1000E100, //Midway, you're idiots (checked this in the MK Deception ELF!) (Refraction)
|
||||||
|
|
||||||
INTC_STAT = 0x1000F000,
|
INTC_STAT = 0x1000F000,
|
||||||
INTC_MASK = 0x1000F010,
|
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,
|
// 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
|
// someone with knowledge on the subject please feel free to explain this one. :) --air
|
||||||
|
|
||||||
ipuRegs.cmd.DATA &= 0xFFFF;
|
// The upper bits are the "length" of the decoded command, where the lower is the address.
|
||||||
ipuRegs.cmd.DATA |= 0x10000;
|
// 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);
|
ipuRegs.ctrl.ECD = (ipuRegs.cmd.DATA == 0);
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -909,7 +908,7 @@ __noinline void IPUWorker()
|
||||||
// CHECK!: IPU0dma remains when IDEC is done, so we need to clear it
|
// 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.
|
// Check Mana Khemia 1 "off campus" to trigger a GUST IDEC messup.
|
||||||
// This hackfixes it :/
|
// This hackfixes it :/
|
||||||
if (ipu0dma.qwc > 0 && ipu0dma.chcr.STR) ipu0Interrupt();
|
//if (ipu0dma.qwc > 0 && ipu0dma.chcr.STR) ipu0Interrupt();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCE_IPU_BDEC:
|
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");
|
pxAssumeMsg(size>0, "Invalid size==0 when calling IPU_Fifo_Output::write");
|
||||||
|
|
||||||
uint origsize = size;
|
uint origsize = size;
|
||||||
do {
|
/*do {*/
|
||||||
IPU0dma();
|
//IPU0dma();
|
||||||
|
|
||||||
uint transsize = min(size, 8 - (uint)ipuRegs.ctrl.OFC);
|
uint transsize = min(size, 8 - (uint)ipuRegs.ctrl.OFC);
|
||||||
if(!transsize) break;
|
if(!transsize) return 0;
|
||||||
|
|
||||||
ipuRegs.ctrl.OFC = transsize;
|
ipuRegs.ctrl.OFC = transsize;
|
||||||
size -= transsize;
|
size -= transsize;
|
||||||
|
@ -124,7 +124,7 @@ int IPU_Fifo_Output::write(const u32 *value, uint size)
|
||||||
value += 4;
|
value += 4;
|
||||||
--transsize;
|
--transsize;
|
||||||
}
|
}
|
||||||
} while(true);
|
/*} while(true);*/
|
||||||
|
|
||||||
return origsize - size;
|
return origsize - size;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,21 +42,6 @@ void SaveStateBase::ipuDmaFreeze()
|
||||||
Freeze(IPU1Status);
|
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()
|
static __fi void ipuDmacSrcChain()
|
||||||
{
|
{
|
||||||
switch (IPU1Status.ChainMode)
|
switch (IPU1Status.ChainMode)
|
||||||
|
@ -82,7 +67,7 @@ static __fi void ipuDmacSrcChain()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_END: // end
|
case TAG_END: // end
|
||||||
ipu1dma.tadr = ipu1dma.madr;
|
//ipu1dma.tadr = ipu1dma.madr;
|
||||||
IPU1Status.DMAFinished = true;
|
IPU1Status.DMAFinished = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -136,15 +121,12 @@ static __fi int IPU1chain() {
|
||||||
ipu1dma.qwc -= qwc;
|
ipu1dma.qwc -= qwc;
|
||||||
totalqwc += qwc;
|
totalqwc += qwc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Update TADR etc
|
||||||
|
if(IPU1Status.DMAMode == DMA_MODE_CHAIN) ipuDmacSrcChain();
|
||||||
|
|
||||||
if( ipu1dma.qwc == 0)
|
if( ipu1dma.qwc == 0)
|
||||||
{
|
|
||||||
//Update TADR etc
|
|
||||||
if(IPU1Status.DMAMode == DMA_MODE_CHAIN) ipuDmacSrcChain();
|
|
||||||
//If the transfer has finished or we have room in the FIFO, schedule to the interrupt code.
|
|
||||||
|
|
||||||
//No data left
|
|
||||||
IPU1Status.InProgress = false;
|
IPU1Status.InProgress = false;
|
||||||
} //If we still have data the commands should pull this across when need be.
|
|
||||||
|
|
||||||
return totalqwc;
|
return totalqwc;
|
||||||
}
|
}
|
||||||
|
@ -238,7 +220,8 @@ int IPU1dma()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_CNT: // cnt
|
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);
|
IPU_LOG("Tag should end on %x", ipu1dma.madr + ipu1dma.qwc * 16);
|
||||||
//ipu1dma.tadr = ipu1dma.madr + (ipu1dma.qwc * 16);
|
//ipu1dma.tadr = ipu1dma.madr + (ipu1dma.qwc * 16);
|
||||||
// Set the taddr to the next tag
|
// Set the taddr to the next tag
|
||||||
|
@ -262,7 +245,7 @@ int IPU1dma()
|
||||||
case TAG_END: // end
|
case TAG_END: // end
|
||||||
// do not change tadr
|
// do not change tadr
|
||||||
ipu1dma.madr = ipu1dma.tadr + 16;
|
ipu1dma.madr = ipu1dma.tadr + 16;
|
||||||
ipu1dma.tadr += 16;
|
//ipu1dma.tadr += 16;
|
||||||
IPU_LOG("Tag should end on %x", ipu1dma.madr + ipu1dma.qwc * 16);
|
IPU_LOG("Tag should end on %x", ipu1dma.madr + ipu1dma.qwc * 16);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -310,15 +293,23 @@ int IPU1dma()
|
||||||
return totalqwc;
|
return totalqwc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int IPU0dma()
|
void IPU0dma()
|
||||||
{
|
{
|
||||||
if(!ipuRegs.ctrl.OFC) return 0;
|
if(!ipuRegs.ctrl.OFC)
|
||||||
|
{
|
||||||
|
IPU_INT_FROM( 64 );
|
||||||
|
IPUProcessInterrupt();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int readsize;
|
int readsize;
|
||||||
tDMA_TAG* pMem;
|
tDMA_TAG* pMem;
|
||||||
|
|
||||||
if ((!(ipu0dma.chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_FROM_IPU))) || (ipu0dma.qwc == 0))
|
if ((!(ipu0dma.chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_FROM_IPU))) || (ipu0dma.qwc == 0))
|
||||||
return 0;
|
{
|
||||||
|
DevCon.Warning("How??");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
pxAssert(!(ipu0dma.chcr.TTE));
|
pxAssert(!(ipu0dma.chcr.TTE));
|
||||||
|
|
||||||
|
@ -362,10 +353,11 @@ int IPU0dma()
|
||||||
//This was IPU_INT_FROM(readsize*BIAS );
|
//This was IPU_INT_FROM(readsize*BIAS );
|
||||||
//This broke vids in Digital Devil Saga
|
//This broke vids in Digital Devil Saga
|
||||||
//Note that interrupting based on totalsize is just guessing..
|
//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
|
__fi void dmaIPU0() // fromIPU
|
||||||
|
@ -381,7 +373,10 @@ __fi void dmaIPU0() // fromIPU
|
||||||
hwDmacIrq(DMAC_FROM_IPU);
|
hwDmacIrq(DMAC_FROM_IPU);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPUProcessInterrupt();
|
IPU_INT_FROM( 64 );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__fi void dmaIPU1() // toIPU
|
__fi void dmaIPU1() // toIPU
|
||||||
|
@ -450,6 +445,11 @@ void ipu0Interrupt()
|
||||||
{
|
{
|
||||||
IPU_LOG("ipu0Interrupt: %x", cpuRegs.cycle);
|
IPU_LOG("ipu0Interrupt: %x", cpuRegs.cycle);
|
||||||
|
|
||||||
|
if(ipu0dma.qwc > 0)
|
||||||
|
{
|
||||||
|
IPU0dma();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (g_nDMATransfer.FIREINT0)
|
if (g_nDMATransfer.FIREINT0)
|
||||||
{
|
{
|
||||||
g_nDMATransfer.FIREINT0 = false;
|
g_nDMATransfer.FIREINT0 = false;
|
||||||
|
|
|
@ -87,7 +87,7 @@ extern void ipu1Interrupt();
|
||||||
|
|
||||||
extern void dmaIPU0();
|
extern void dmaIPU0();
|
||||||
extern void dmaIPU1();
|
extern void dmaIPU1();
|
||||||
extern int IPU0dma();
|
extern void IPU0dma();
|
||||||
extern int IPU1dma();
|
extern int IPU1dma();
|
||||||
|
|
||||||
extern void ipuDmaReset();
|
extern void ipuDmaReset();
|
||||||
|
|
|
@ -135,14 +135,13 @@ int get_macroblock_modes()
|
||||||
{
|
{
|
||||||
macroblock_modes |= GETBITS(2) * MOTION_TYPE_BASE;
|
macroblock_modes |= GETBITS(2) * MOTION_TYPE_BASE;
|
||||||
}
|
}
|
||||||
|
return (macroblock_modes | (tab->len << 16));
|
||||||
return macroblock_modes;
|
|
||||||
}
|
}
|
||||||
else if (decoder.frame_pred_frame_dct)
|
else if (decoder.frame_pred_frame_dct)
|
||||||
{
|
{
|
||||||
/* if (! (macroblock_modes & MACROBLOCK_INTRA)) */
|
/* if (! (macroblock_modes & MACROBLOCK_INTRA)) */
|
||||||
macroblock_modes |= MC_FRAME;
|
macroblock_modes |= MC_FRAME;
|
||||||
return macroblock_modes;
|
return (macroblock_modes | (tab->len << 16));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -155,15 +154,15 @@ int get_macroblock_modes()
|
||||||
intra:
|
intra:
|
||||||
macroblock_modes |= GETBITS(1) * DCT_TYPE_INTERLACED;
|
macroblock_modes |= GETBITS(1) * DCT_TYPE_INTERLACED;
|
||||||
}
|
}
|
||||||
|
return (macroblock_modes | (tab->len << 16));
|
||||||
return macroblock_modes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case D_TYPE:
|
case D_TYPE:
|
||||||
macroblock_modes = GETBITS(1);
|
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
|
if (macroblock_modes == 0) return 0; // error
|
||||||
return MACROBLOCK_INTRA;
|
return (MACROBLOCK_INTRA | (1 << 16));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -222,14 +221,15 @@ int __fi get_motion_delta(const int f_code)
|
||||||
|
|
||||||
sign = SBITS(1);
|
sign = SBITS(1);
|
||||||
DUMPBITS(1);
|
DUMPBITS(1);
|
||||||
return (delta ^ sign) - sign;
|
|
||||||
|
return (((delta ^ sign) - sign) | (tab->len << 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
int __fi get_dmv()
|
int __fi get_dmv()
|
||||||
{
|
{
|
||||||
const DMVtab* tab = DMV_2 + UBITS(2);
|
const DMVtab* tab = DMV_2 + UBITS(2);
|
||||||
DUMPBITS(tab->len);
|
DUMPBITS(tab->len);
|
||||||
return tab->dmv;
|
return (tab->dmv | (tab->len << 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_macroblock_address_increment()
|
int get_macroblock_address_increment()
|
||||||
|
@ -246,13 +246,13 @@ int get_macroblock_address_increment()
|
||||||
{
|
{
|
||||||
case 8: /* macroblock_escape */
|
case 8: /* macroblock_escape */
|
||||||
DUMPBITS(11);
|
DUMPBITS(11);
|
||||||
return 0x23;
|
return 0xb0023;
|
||||||
|
|
||||||
case 15: /* macroblock_stuffing (MPEG1 only) */
|
case 15: /* macroblock_stuffing (MPEG1 only) */
|
||||||
if (decoder.mpeg1)
|
if (decoder.mpeg1)
|
||||||
{
|
{
|
||||||
DUMPBITS(11);
|
DUMPBITS(11);
|
||||||
return 0x22;
|
return 0xb0022;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -261,7 +261,7 @@ int get_macroblock_address_increment()
|
||||||
|
|
||||||
DUMPBITS(mba->len);
|
DUMPBITS(mba->len);
|
||||||
|
|
||||||
return mba->mba + 1;
|
return ((mba->mba + 1) | (mba->len << 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
static __fi int get_luma_dc_dct_diff()
|
static __fi int get_luma_dc_dct_diff()
|
||||||
|
|
|
@ -395,8 +395,6 @@
|
||||||
<Unit filename="../ZipTools/ThreadedZipTools.h" />
|
<Unit filename="../ZipTools/ThreadedZipTools.h" />
|
||||||
<Unit filename="../ZipTools/thread_gzip.cpp" />
|
<Unit filename="../ZipTools/thread_gzip.cpp" />
|
||||||
<Unit filename="../ZipTools/thread_lzma.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/App.h" />
|
||||||
<Unit filename="../gui/AppAccelerators.h" />
|
<Unit filename="../gui/AppAccelerators.h" />
|
||||||
<Unit filename="../gui/AppAssert.cpp" />
|
<Unit filename="../gui/AppAssert.cpp" />
|
||||||
|
|
|
@ -806,7 +806,7 @@ void SysMtgsThread::WaitForOpen()
|
||||||
// emulator forcefully, or to continue waiting on the GS.
|
// emulator forcefully, or to continue waiting on the GS.
|
||||||
|
|
||||||
throw Exception::PluginOpenError( PluginId_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( ConsoleToStdio );
|
||||||
IniBitBool( HostFs );
|
IniBitBool( HostFs );
|
||||||
|
|
||||||
|
IniBitBool( BackupSavestate );
|
||||||
IniBitBool( McdEnableEjection );
|
IniBitBool( McdEnableEjection );
|
||||||
IniBitBool( MultitapPort0_Enabled );
|
IniBitBool( MultitapPort0_Enabled );
|
||||||
IniBitBool( MultitapPort1_Enabled );
|
IniBitBool( MultitapPort1_Enabled );
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "CDVD/CDVDisoReader.h"
|
#include "CDVD/CDVDisoReader.h"
|
||||||
|
|
||||||
#include "Utilities/ScopedPtr.h"
|
#include "Utilities/ScopedPtr.h"
|
||||||
|
#include "Utilities/pxStreams.h"
|
||||||
|
|
||||||
#if _MSC_VER
|
#if _MSC_VER
|
||||||
# include "svnrev.h"
|
# include "svnrev.h"
|
||||||
|
@ -152,7 +153,7 @@ _GSgifSoftReset GSgifSoftReset;
|
||||||
_GSreadFIFO GSreadFIFO;
|
_GSreadFIFO GSreadFIFO;
|
||||||
_GSreadFIFO2 GSreadFIFO2;
|
_GSreadFIFO2 GSreadFIFO2;
|
||||||
_GSchangeSaveState GSchangeSaveState;
|
_GSchangeSaveState GSchangeSaveState;
|
||||||
_GSgetTitleInfo GSgetTitleInfo;
|
_GSgetTitleInfo2 GSgetTitleInfo2;
|
||||||
_GSmakeSnapshot GSmakeSnapshot;
|
_GSmakeSnapshot GSmakeSnapshot;
|
||||||
_GSmakeSnapshot2 GSmakeSnapshot2;
|
_GSmakeSnapshot2 GSmakeSnapshot2;
|
||||||
_GSirqCallback GSirqCallback;
|
_GSirqCallback GSirqCallback;
|
||||||
|
@ -185,8 +186,11 @@ static void CALLBACK GS_printf(int timeout, char *fmt, ...)
|
||||||
Console.WriteLn(msg);
|
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[0] = 'G';
|
||||||
dest[1] = 'S';
|
dest[1] = 'S';
|
||||||
dest[2] = 0;
|
dest[2] = 0;
|
||||||
|
@ -372,7 +376,7 @@ static const LegacyApi_ReqMethod s_MethMessReq_GS[] =
|
||||||
{ "GSsetVsync", (vMeth**)&GSsetVsync, (vMeth*)GS_setVsync },
|
{ "GSsetVsync", (vMeth**)&GSsetVsync, (vMeth*)GS_setVsync },
|
||||||
{ "GSsetExclusive", (vMeth**)&GSsetExclusive, (vMeth*)GS_setExclusive },
|
{ "GSsetExclusive", (vMeth**)&GSsetExclusive, (vMeth*)GS_setExclusive },
|
||||||
{ "GSchangeSaveState",(vMeth**)&GSchangeSaveState,(vMeth*)GS_changeSaveState },
|
{ "GSchangeSaveState",(vMeth**)&GSchangeSaveState,(vMeth*)GS_changeSaveState },
|
||||||
{ "GSgetTitleInfo", (vMeth**)&GSgetTitleInfo, (vMeth*)GS_getTitleInfo },
|
{ "GSgetTitleInfo2", (vMeth**)&GSgetTitleInfo2, (vMeth*)GS_getTitleInfo2 },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -807,11 +811,11 @@ SysCorePlugins::PluginStatus_t::PluginStatus_t( PluginsEnum_t _pid, const wxStri
|
||||||
|
|
||||||
if( !wxFile::Exists( Filename ) )
|
if( !wxFile::Exists( Filename ) )
|
||||||
throw Exception::PluginLoadError( pid ).SetStreamName(srcfile)
|
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 ) )
|
if( !Lib.Load( Filename ) )
|
||||||
throw Exception::PluginLoadError( pid ).SetStreamName(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.
|
// 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!)
|
// fixme: use plugin's GetLastError (not implemented yet!)
|
||||||
throw Exception::PluginInitError( PluginId_Mcd )
|
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.
|
// No locking leeded -- DoFreeze locks as needed, and this avoids MTGS deadlock.
|
||||||
//ScopedLock lock( m_mtx_PluginStatus );
|
//ScopedLock lock( m_mtx_PluginStatus );
|
||||||
|
|
||||||
Console.Indent().WriteLn( "%s %s", state.IsSaving() ? "Saving" : "Loading",
|
|
||||||
tbl_PluginInfo[pid].shortname );
|
|
||||||
|
|
||||||
freezeData fP = { 0, NULL };
|
freezeData fP = { 0, NULL };
|
||||||
if( !DoFreeze( pid, FREEZE_SIZE, &fP ) )
|
if( !DoFreeze( pid, FREEZE_SIZE, &fP ) )
|
||||||
fP.size = 0;
|
fP.size = 0;
|
||||||
|
@ -1409,6 +1410,9 @@ void SysCorePlugins::Freeze( PluginsEnum_t pid, SaveStateBase& state )
|
||||||
int fsize = fP.size;
|
int fsize = fP.size;
|
||||||
state.Freeze( fsize );
|
state.Freeze( fsize );
|
||||||
|
|
||||||
|
Console.Indent().WriteLn( "%s %s", state.IsSaving() ? "Saving" : "Loading",
|
||||||
|
tbl_PluginInfo[pid].shortname );
|
||||||
|
|
||||||
if( state.IsLoading() && (fsize == 0) )
|
if( state.IsLoading() && (fsize == 0) )
|
||||||
{
|
{
|
||||||
// no state data to read, but the plugin expects some state data.
|
// 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 );
|
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 )
|
bool SysCorePlugins::KeyEvent( const keyEvent& evt )
|
||||||
{
|
{
|
||||||
ScopedLock lock( m_mtx_PluginStatus );
|
ScopedLock lock( m_mtx_PluginStatus );
|
||||||
|
|
|
@ -326,6 +326,10 @@ public:
|
||||||
virtual bool IsInitialized( PluginsEnum_t pid ) const;
|
virtual bool IsInitialized( PluginsEnum_t pid ) const;
|
||||||
virtual bool IsLoaded( 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 void Freeze( PluginsEnum_t pid, SaveStateBase& state );
|
||||||
virtual bool DoFreeze( PluginsEnum_t pid, int mode, freezeData* data );
|
virtual bool DoFreeze( PluginsEnum_t pid, int mode, freezeData* data );
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#ifndef PCSX2_PRECOMPILED_HEADER
|
#ifndef PCSX2_PRECOMPILED_HEADER
|
||||||
#define 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...
|
// Disable some pointless warnings...
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -24,20 +24,7 @@
|
||||||
# pragma warning(disable:4996) //ignore the stricmp deprecated warning
|
# pragma warning(disable:4996) //ignore the stricmp deprecated warning
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
#include "Utilities/Dependencies.h"
|
||||||
// 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
|
|
||||||
|
|
||||||
#define NOMINMAX // Disables other libs inclusion of their own min/max macros (we use std instead)
|
#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()
|
__fi void SPR0chain()
|
||||||
{
|
{
|
||||||
CPU_INT(DMAC_FROM_SPR, _SPR0chain() / BIAS);
|
CPU_INT(DMAC_FROM_SPR, _SPR0chain() * BIAS);
|
||||||
spr0ch.qwc = 0;
|
spr0ch.qwc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ void _SPR0interleave()
|
||||||
SPR_LOG("SPR0 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx",
|
SPR_LOG("SPR0 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx",
|
||||||
spr0ch.qwc, tqwc, sqwc, spr0ch.madr, spr0ch.sadr);
|
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)
|
while (qwc > 0)
|
||||||
{
|
{
|
||||||
|
@ -290,13 +290,14 @@ int _SPR1chain()
|
||||||
|
|
||||||
SPR1transfer(pMem, spr1ch.qwc);
|
SPR1transfer(pMem, spr1ch.qwc);
|
||||||
spr1ch.madr += spr1ch.qwc * 16;
|
spr1ch.madr += spr1ch.qwc * 16;
|
||||||
|
hwDmacSrcTadrInc(spr1ch);
|
||||||
|
|
||||||
return (spr1ch.qwc);
|
return (spr1ch.qwc);
|
||||||
}
|
}
|
||||||
|
|
||||||
__fi void SPR1chain()
|
__fi void SPR1chain()
|
||||||
{
|
{
|
||||||
CPU_INT(DMAC_TO_SPR, _SPR1chain() / BIAS);
|
CPU_INT(DMAC_TO_SPR, _SPR1chain() * BIAS);
|
||||||
spr1ch.qwc = 0;
|
spr1ch.qwc = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,7 +311,7 @@ void _SPR1interleave()
|
||||||
if (tqwc == 0) tqwc = qwc;
|
if (tqwc == 0) tqwc = qwc;
|
||||||
SPR_LOG("SPR1 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx",
|
SPR_LOG("SPR1 interleave size=%d, tqwc=%d, sqwc=%d, addr=%lx sadr=%lx",
|
||||||
spr1ch.qwc, tqwc, sqwc, spr1ch.madr, spr1ch.sadr);
|
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)
|
while (qwc > 0)
|
||||||
{
|
{
|
||||||
spr1ch.qwc = std::min(tqwc, qwc);
|
spr1ch.qwc = std::min(tqwc, qwc);
|
||||||
|
|
|
@ -70,8 +70,6 @@ void SaveStateBase::Init( SafeArray<u8>* memblock )
|
||||||
m_memory = memblock;
|
m_memory = memblock;
|
||||||
m_version = g_SaveVersion;
|
m_version = g_SaveVersion;
|
||||||
m_idx = 0;
|
m_idx = 0;
|
||||||
m_sectid = FreezeId_Unknown;
|
|
||||||
m_pid = PluginId_GS;
|
|
||||||
m_DidBios = false;
|
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
|
// 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
|
// doesn't match the bios currently being used (chances are it'll still
|
||||||
// work fine, but some games are very picky).
|
// work fine, but some games are very picky).
|
||||||
|
|
||||||
|
u32 bioscheck = BiosChecksum;
|
||||||
|
char biosdesc[256];
|
||||||
|
|
||||||
char descin[128], desccmp[128];
|
pxToUTF8 utf8(BiosDescription);
|
||||||
wxString descout;
|
|
||||||
IsBIOS( g_Conf->FullpathToBios(), descout );
|
|
||||||
memzero( descin );
|
|
||||||
memzero( desccmp );
|
|
||||||
|
|
||||||
pxToUTF8 utf8(descout);
|
memzero( biosdesc );
|
||||||
memcpy_fast( descin, utf8, utf8.Length() );
|
memcpy_fast( biosdesc, utf8, std::min( sizeof(biosdesc), utf8.Length() ) );
|
||||||
memcpy_fast( desccmp, utf8, utf8.Length() );
|
|
||||||
|
Freeze( bioscheck );
|
||||||
|
Freeze( biosdesc );
|
||||||
|
|
||||||
// ... and only freeze bios info once per state, since the user msg could
|
if (bioscheck != BiosChecksum)
|
||||||
// become really annoying on a corrupted state or something. (have to always
|
|
||||||
// load though, so that we advance past the duplicated info, if present)
|
|
||||||
|
|
||||||
if( IsLoading() || !m_DidBios )
|
|
||||||
Freeze( descin );
|
|
||||||
|
|
||||||
if( !m_DidBios )
|
|
||||||
{
|
{
|
||||||
if( memcmp( descin, desccmp, 128 ) != 0 )
|
Console.Newline();
|
||||||
{
|
Console.Indent(1).Error( "Warning: BIOS Version Mismatch, savestate may be unstable!" );
|
||||||
Console.Newline();
|
Console.Indent(2).Error(
|
||||||
Console.Indent(1).Error( "Warning: BIOS Version Mismatch, savestate may be unstable!" );
|
"Current BIOS: %ls (crc=0x%08x)\n"
|
||||||
Console.Indent(2).Error(
|
"Savestate BIOS: %s (crc=0x%08x)\n",
|
||||||
"Current Version: %s\n"
|
BiosDescription.c_str(), BiosChecksum,
|
||||||
"Savestate Version: %s\n",
|
biosdesc, bioscheck
|
||||||
utf8.data(), descin
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
m_DidBios = true;
|
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint MainMemorySizeInBytes =
|
static const uint MainMemorySizeInBytes =
|
||||||
Ps2MemSize::MainRam + Ps2MemSize::Scratch + Ps2MemSize::Hardware +
|
Ps2MemSize::MainRam + Ps2MemSize::Scratch + Ps2MemSize::Hardware +
|
||||||
Ps2MemSize::IopRam + Ps2MemSize::IopHardware;
|
Ps2MemSize::IopRam + Ps2MemSize::IopHardware;
|
||||||
|
|
||||||
void SaveStateBase::FreezeMainMemory()
|
SaveStateBase& SaveStateBase::FreezeMainMemory()
|
||||||
{
|
{
|
||||||
if (IsLoading())
|
if (IsLoading())
|
||||||
PreLoadPrep();
|
PreLoadPrep();
|
||||||
|
@ -170,9 +163,11 @@ void SaveStateBase::FreezeMainMemory()
|
||||||
|
|
||||||
FreezeMem(vuRegs[1].Micro, VU1_PROGSIZE);
|
FreezeMem(vuRegs[1].Micro, VU1_PROGSIZE);
|
||||||
FreezeMem(vuRegs[1].Mem, VU1_MEMSIZE);
|
FreezeMem(vuRegs[1].Mem, VU1_MEMSIZE);
|
||||||
|
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveStateBase::FreezeRegisters()
|
SaveStateBase& SaveStateBase::FreezeInternals()
|
||||||
{
|
{
|
||||||
if( IsLoading() )
|
if( IsLoading() )
|
||||||
PreLoadPrep();
|
PreLoadPrep();
|
||||||
|
@ -229,138 +224,31 @@ void SaveStateBase::FreezeRegisters()
|
||||||
|
|
||||||
if( IsLoading() )
|
if( IsLoading() )
|
||||||
PostLoadPrep();
|
PostLoadPrep();
|
||||||
|
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveStateBase::WritebackSectionLength( int seekpos, int sectlen, const wxChar* sectname )
|
SaveStateBase& SaveStateBase::FreezePlugins()
|
||||||
{
|
{
|
||||||
int realsectsize = m_idx - seekpos;
|
for (uint i=0; i<PluginId_Count; ++i)
|
||||||
if( IsSaving() )
|
|
||||||
{
|
{
|
||||||
// write back the section length...
|
FreezeTag( FastFormatAscii().Write("Plugin:%s", tbl_PluginInfo[i].shortname) );
|
||||||
*((u32*)m_memory->GetPtr(seekpos-4)) = realsectsize;
|
GetCorePlugins().Freeze( (PluginsEnum_t)i, *this );
|
||||||
}
|
|
||||||
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."));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SaveStateBase::FreezeSection( int seek_section )
|
SaveStateBase& SaveStateBase::FreezeAll()
|
||||||
{
|
{
|
||||||
const bool isSeeking = (seek_section != FreezeId_NotSeeking );
|
FreezeMainMemory();
|
||||||
if( IsSaving() ) pxAssertDev( !isSeeking, "Cannot seek on a saving-mode savestate stream." );
|
FreezeBios();
|
||||||
|
FreezeInternals();
|
||||||
Freeze( m_sectid );
|
FreezePlugins();
|
||||||
if( seek_section == m_sectid ) return false;
|
|
||||||
|
return *this;
|
||||||
switch( m_sectid )
|
|
||||||
{
|
|
||||||
case FreezeId_End:
|
|
||||||
return false;
|
|
||||||
|
|
||||||
case FreezeId_Bios:
|
|
||||||
{
|
|
||||||
int sectlen = 128;
|
|
||||||
FreezeTag( "BiosVersion" );
|
|
||||||
Freeze( sectlen );
|
|
||||||
|
|
||||||
if( sectlen != 128 )
|
|
||||||
{
|
|
||||||
throw Exception::SaveStateLoadError()
|
|
||||||
.SetDiagMsg(L"Invalid size encountered on BiosVersion section.")
|
|
||||||
.SetUserMsg(_("The savestate data is invalid or corrupted."));
|
|
||||||
}
|
|
||||||
|
|
||||||
if( isSeeking )
|
|
||||||
m_idx += sectlen;
|
|
||||||
else
|
|
||||||
FreezeBios();
|
|
||||||
m_sectid++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FreezeId_Registers:
|
|
||||||
{
|
|
||||||
FreezeTag( "HardwareRegisters" );
|
|
||||||
int seekpos = m_idx+4;
|
|
||||||
int sectlen = 0xdead; // gets written back over with "real" data in IsSaving() mode
|
|
||||||
|
|
||||||
Freeze( sectlen );
|
|
||||||
FreezeRegisters();
|
|
||||||
|
|
||||||
WritebackSectionLength( seekpos, sectlen, L"HardwareRegisters" );
|
|
||||||
m_sectid++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FreezeId_Plugin:
|
|
||||||
{
|
|
||||||
FreezeTag( "Plugin" );
|
|
||||||
int seekpos = m_idx+4;
|
|
||||||
int sectlen = 0xdead; // gets written back over with "real" data in IsSaving() mode
|
|
||||||
|
|
||||||
Freeze( sectlen );
|
|
||||||
Freeze( m_pid );
|
|
||||||
|
|
||||||
if( isSeeking )
|
|
||||||
m_idx += sectlen;
|
|
||||||
else
|
|
||||||
GetCorePlugins().Freeze( (PluginsEnum_t)m_pid, *this );
|
|
||||||
|
|
||||||
WritebackSectionLength( seekpos, sectlen, L"Plugins" );
|
|
||||||
|
|
||||||
// following increments only affect Saving mode, which needs to be sure to save all
|
|
||||||
// plugins (order doesn't matter but sequential is easy enough. (ignored by Loading mode)
|
|
||||||
m_pid++;
|
|
||||||
if( m_pid >= PluginId_Count )
|
|
||||||
m_sectid = FreezeId_End;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FreezeId_Unknown:
|
|
||||||
default:
|
|
||||||
pxAssert( IsSaving() );
|
|
||||||
|
|
||||||
// Skip unknown sections with a warning log.
|
|
||||||
// Maybe it'll work! (haha?)
|
|
||||||
|
|
||||||
int size;
|
|
||||||
Freeze( m_tagspace );
|
|
||||||
Freeze( size );
|
|
||||||
m_tagspace[sizeof(m_tagspace)-1] = 0;
|
|
||||||
|
|
||||||
Console.Warning(
|
|
||||||
"Warning: Unknown tag encountered while loading savestate; going to ignore it!\n"
|
|
||||||
"\tTagname: %s, Size: %d", m_tagspace, size
|
|
||||||
);
|
|
||||||
m_idx += size;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( wxThread::IsMain() )
|
|
||||||
wxSafeYield( NULL, true );
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
// memSavingState (implementations)
|
||||||
|
@ -380,7 +268,9 @@ memSavingState::memSavingState( SafeArray<u8>* save_to )
|
||||||
// Saving of state data
|
// Saving of state data
|
||||||
void memSavingState::FreezeMem( void* data, int size )
|
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 );
|
memcpy_fast( m_memory->GetPtr(m_idx), data, size );
|
||||||
m_idx += size;
|
m_idx += size;
|
||||||
}
|
}
|
||||||
|
@ -394,10 +284,11 @@ void memSavingState::MakeRoomForData()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Saving of state data to a memory buffer
|
// Saving of state data to a memory buffer
|
||||||
void memSavingState::FreezeAll()
|
memSavingState& memSavingState::FreezeAll()
|
||||||
{
|
{
|
||||||
MakeRoomForData();
|
MakeRoomForData();
|
||||||
_parent::FreezeAll();
|
_parent::FreezeAll();
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
@ -423,25 +314,6 @@ void memLoadingState::FreezeMem( void* data, int size )
|
||||||
memcpy_fast( data, src, 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
|
// SaveState Exception Messages
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -31,21 +31,6 @@ static const u32 g_SaveVersion = (0x9A01 << 16) | 0x0000;
|
||||||
extern s32 CALLBACK gsSafeFreeze( int mode, freezeData *data );
|
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
|
namespace Exception
|
||||||
{
|
{
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
|
@ -119,8 +104,6 @@ protected:
|
||||||
u32 m_version; // version of the savestate being loaded.
|
u32 m_version; // version of the savestate being loaded.
|
||||||
|
|
||||||
int m_idx; // current read/write index of the allocation
|
int m_idx; // current read/write index of the allocation
|
||||||
int m_sectid;
|
|
||||||
int m_pid;
|
|
||||||
|
|
||||||
bool m_DidBios;
|
bool m_DidBios;
|
||||||
|
|
||||||
|
@ -141,9 +124,12 @@ public:
|
||||||
// Loads or saves the entire emulation state.
|
// Loads or saves the entire emulation state.
|
||||||
// Note: The Cpu state must be reset, and plugins *open*, prior to Defrosting
|
// Note: The Cpu state must be reset, and plugins *open*, prior to Defrosting
|
||||||
// (loading) a state!
|
// (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.
|
// Loads or saves an arbitrary data type. Usable on atomic types, structs, and arrays.
|
||||||
// For dynamically allocated pointers use FreezeMem instead.
|
// For dynamically allocated pointers use FreezeMem instead.
|
||||||
|
@ -183,9 +169,6 @@ public:
|
||||||
m_idx += size;
|
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.
|
// Freezes an identifier value into the savestate for troubleshooting purposes.
|
||||||
// Identifiers can be used to determine where in a savestate that data has become
|
// 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
|
// 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!
|
// Load/Save functions for the various components of our glorious emulator!
|
||||||
|
|
||||||
void FreezeBios();
|
|
||||||
void FreezeRegisters();
|
|
||||||
|
|
||||||
void rcntFreeze();
|
void rcntFreeze();
|
||||||
void vuMicroFreeze();
|
void vuMicroFreeze();
|
||||||
void vif0Freeze();
|
void vif0Freeze();
|
||||||
|
@ -257,7 +237,7 @@ public:
|
||||||
void MakeRoomForData();
|
void MakeRoomForData();
|
||||||
|
|
||||||
void FreezeMem( void* data, int size );
|
void FreezeMem( void* data, int size );
|
||||||
void FreezeAll();
|
memSavingState& FreezeAll();
|
||||||
|
|
||||||
bool IsSaving() const { return true; }
|
bool IsSaving() const { return true; }
|
||||||
};
|
};
|
||||||
|
@ -271,7 +251,6 @@ public:
|
||||||
memLoadingState( const VmStateBuffer* load_from );
|
memLoadingState( const VmStateBuffer* load_from );
|
||||||
|
|
||||||
void FreezeMem( void* data, int size );
|
void FreezeMem( void* data, int size );
|
||||||
bool SeekToSection( PluginsEnum_t pid );
|
|
||||||
|
|
||||||
bool IsSaving() const { return false; }
|
bool IsSaving() const { return false; }
|
||||||
bool IsFinished() const { return m_idx >= m_memory->GetSizeInBytes(); }
|
bool IsFinished() const { return m_idx >= m_memory->GetSizeInBytes(); }
|
||||||
|
|
|
@ -52,6 +52,7 @@ static __fi bool WriteEEtoFifo()
|
||||||
sif1.fifo.write((u32*)ptag, writeSize << 2);
|
sif1.fifo.write((u32*)ptag, writeSize << 2);
|
||||||
|
|
||||||
sif1dma.madr += writeSize << 4;
|
sif1dma.madr += writeSize << 4;
|
||||||
|
hwDmacSrcTadrInc(sif1dma);
|
||||||
sif1.ee.cycles += writeSize; // fixme : BIAS is factored in above
|
sif1.ee.cycles += writeSize; // fixme : BIAS is factored in above
|
||||||
sif1dma.qwc -= writeSize;
|
sif1dma.qwc -= writeSize;
|
||||||
|
|
||||||
|
@ -114,8 +115,8 @@ static __fi bool ProcessEETag()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_CNT:
|
case TAG_CNT:
|
||||||
sif1dma.madr = sif1dma.tadr + 16;
|
sif1dma.tadr += 16;
|
||||||
sif1dma.tadr = sif1dma.madr + (sif1dma.qwc << 4);
|
sif1dma.madr = sif1dma.tadr;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TAG_NEXT:
|
case TAG_NEXT:
|
||||||
|
@ -132,7 +133,7 @@ static __fi bool ProcessEETag()
|
||||||
case TAG_END:
|
case TAG_END:
|
||||||
sif1.ee.end = true;
|
sif1.ee.end = true;
|
||||||
sif1dma.madr = sif1dma.tadr + 16;
|
sif1dma.madr = sif1dma.tadr + 16;
|
||||||
sif1dma.tadr = sif1dma.madr + (sif1dma.qwc << 4);
|
//sif1dma.tadr = sif1dma.madr + (sif1dma.qwc << 4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -93,27 +93,27 @@ static const TraceLogDescriptor
|
||||||
|
|
||||||
TLD_ELF = {
|
TLD_ELF = {
|
||||||
L"ELF", L"ELF",
|
L"ELF", L"ELF",
|
||||||
wxLt("Dumps detailed information for PS2 executables (ELFs).")
|
pxDt("Dumps detailed information for PS2 executables (ELFs).")
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_eeRecPerf = {
|
TLD_eeRecPerf = {
|
||||||
L"EErecPerf", L"EErec Performance",
|
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 = {
|
TLD_eeConsole = {
|
||||||
L"EEout", L"EE Console",
|
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 = {
|
TLD_iopConsole = {
|
||||||
L"IOPout", L"IOP Console",
|
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 = {
|
TLD_deci2 = {
|
||||||
L"DECI2", L"DECI2 Console",
|
L"DECI2", L"DECI2 Console",
|
||||||
wxLt("Shows DECI2 debugging logs (EE processor)")
|
pxDt("Shows DECI2 debugging logs (EE processor)")
|
||||||
};
|
};
|
||||||
|
|
||||||
SysConsoleLogPack::SysConsoleLogPack()
|
SysConsoleLogPack::SysConsoleLogPack()
|
||||||
|
@ -131,7 +131,7 @@ SysConsoleLogPack::SysConsoleLogPack()
|
||||||
static const SysTraceLogDescriptor
|
static const SysTraceLogDescriptor
|
||||||
TLD_SIF = {
|
TLD_SIF = {
|
||||||
L"SIF", L"SIF (EE <-> IOP)",
|
L"SIF", L"SIF (EE <-> IOP)",
|
||||||
wxLt(""),
|
pxDt(""),
|
||||||
"SIF"
|
"SIF"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -142,109 +142,109 @@ TLD_SIF = {
|
||||||
static const SysTraceLogDescriptor
|
static const SysTraceLogDescriptor
|
||||||
TLD_EE_Bios = {
|
TLD_EE_Bios = {
|
||||||
L"Bios", L"Bios",
|
L"Bios", L"Bios",
|
||||||
wxLt("SYSCALL and DECI2 activity."),
|
pxDt("SYSCALL and DECI2 activity."),
|
||||||
"EE"
|
"EE"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_EE_Memory = {
|
TLD_EE_Memory = {
|
||||||
L"Memory", L"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"
|
"eMem"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_EE_R5900 = {
|
TLD_EE_R5900 = {
|
||||||
L"R5900", L"R5900 Core",
|
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"
|
"eDis"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_EE_COP0 = {
|
TLD_EE_COP0 = {
|
||||||
L"COP0", L"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"
|
"eDis"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_EE_COP1 = {
|
TLD_EE_COP1 = {
|
||||||
L"FPU", L"COP1/FPU",
|
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"
|
"eDis"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_EE_COP2 = {
|
TLD_EE_COP2 = {
|
||||||
L"VUmacro", L"COP2/VUmacro",
|
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"
|
"eDis"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_EE_Cache = {
|
TLD_EE_Cache = {
|
||||||
L"Cache", L"Cache",
|
L"Cache", L"Cache",
|
||||||
wxLt("Execution of EE cache instructions."),
|
pxDt("Execution of EE cache instructions."),
|
||||||
"eDis"
|
"eDis"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_EE_KnownHw = {
|
TLD_EE_KnownHw = {
|
||||||
L"HwRegs", L"Hardware Regs",
|
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"
|
"eReg"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_EE_UnknownHw = {
|
TLD_EE_UnknownHw = {
|
||||||
L"UnknownRegs", L"Unknown Regs",
|
L"UnknownRegs", L"Unknown Regs",
|
||||||
wxLt("Logs only unknown, unmapped, or unimplemented register accesses."),
|
pxDt("Logs only unknown, unmapped, or unimplemented register accesses."),
|
||||||
"eReg"
|
"eReg"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_EE_DMAhw = {
|
TLD_EE_DMAhw = {
|
||||||
L"DmaRegs", L"DMA Regs",
|
L"DmaRegs", L"DMA Regs",
|
||||||
wxLt("Logs only DMA-related registers."),
|
pxDt("Logs only DMA-related registers."),
|
||||||
"eReg"
|
"eReg"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_EE_IPU = {
|
TLD_EE_IPU = {
|
||||||
L"IPU", L"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"
|
"IPU"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_EE_GIFtag = {
|
TLD_EE_GIFtag = {
|
||||||
L"GIFtags", L"GIFtags",
|
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"
|
"GIF"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_EE_VIFcode = {
|
TLD_EE_VIFcode = {
|
||||||
L"VIFcodes", L"VIFcodes",
|
L"VIFcodes", L"VIFcodes",
|
||||||
wxLt("All VIFcode processing; command, tag style, interrupts."),
|
pxDt("All VIFcode processing; command, tag style, interrupts."),
|
||||||
"VIF"
|
"VIF"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_EE_SPR = {
|
TLD_EE_SPR = {
|
||||||
L"MFIFO", L"Scratchpad MFIFO",
|
L"MFIFO", L"Scratchpad MFIFO",
|
||||||
wxLt("Scratchpad's MFIFO activity."),
|
pxDt("Scratchpad's MFIFO activity."),
|
||||||
"SPR"
|
"SPR"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_EE_DMAC = {
|
TLD_EE_DMAC = {
|
||||||
L"DmaCtrl", L"DMA Controller",
|
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"
|
"eDmaC"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_EE_Counters = {
|
TLD_EE_Counters = {
|
||||||
L"Counters", L"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"
|
"eCnt"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_EE_VIF = {
|
TLD_EE_VIF = {
|
||||||
L"VIF", L"VIF",
|
L"VIF", L"VIF",
|
||||||
wxLt("Dumps various VIF and VIFcode processing data."),
|
pxDt("Dumps various VIF and VIFcode processing data."),
|
||||||
"VIF"
|
"VIF"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_EE_GIF = {
|
TLD_EE_GIF = {
|
||||||
L"GIF", L"GIF",
|
L"GIF", L"GIF",
|
||||||
wxLt("Dumps various GIF and GIFtag parsing data."),
|
pxDt("Dumps various GIF and GIFtag parsing data."),
|
||||||
"GIF"
|
"GIF"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -255,73 +255,73 @@ TLD_EE_GIF = {
|
||||||
static const SysTraceLogDescriptor
|
static const SysTraceLogDescriptor
|
||||||
TLD_IOP_Bios = {
|
TLD_IOP_Bios = {
|
||||||
L"Bios", L"Bios",
|
L"Bios", L"Bios",
|
||||||
wxLt("SYSCALL and IRX activity."),
|
pxDt("SYSCALL and IRX activity."),
|
||||||
"IOP"
|
"IOP"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_IOP_Memory = {
|
TLD_IOP_Memory = {
|
||||||
L"Memory", L"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"
|
"iMem"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_IOP_R3000A = {
|
TLD_IOP_R3000A = {
|
||||||
L"R3000A", L"R3000A Core",
|
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"
|
"iDis"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_IOP_COP2 = {
|
TLD_IOP_COP2 = {
|
||||||
L"COP2/GPU", L"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"
|
"iDis"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_IOP_KnownHw = {
|
TLD_IOP_KnownHw = {
|
||||||
L"HwRegs", L"Hardware Regs",
|
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"
|
"iReg"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_IOP_UnknownHw = {
|
TLD_IOP_UnknownHw = {
|
||||||
L"UnknownRegs", L"Unknown Regs",
|
L"UnknownRegs", L"Unknown Regs",
|
||||||
wxLt("Logs only unknown, unmapped, or unimplemented register accesses."),
|
pxDt("Logs only unknown, unmapped, or unimplemented register accesses."),
|
||||||
"iReg"
|
"iReg"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_IOP_DMAhw = {
|
TLD_IOP_DMAhw = {
|
||||||
L"DmaRegs", L"DMA Regs",
|
L"DmaRegs", L"DMA Regs",
|
||||||
wxLt("Logs only DMA-related registers."),
|
pxDt("Logs only DMA-related registers."),
|
||||||
"iReg"
|
"iReg"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_IOP_Memcards = {
|
TLD_IOP_Memcards = {
|
||||||
L"Memorycards", L"Memorycards",
|
L"Memorycards", L"Memorycards",
|
||||||
wxLt("Memorycard reads, writes, erases, terminators, and other processing."),
|
pxDt("Memorycard reads, writes, erases, terminators, and other processing."),
|
||||||
"Mcd"
|
"Mcd"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_IOP_PAD = {
|
TLD_IOP_PAD = {
|
||||||
L"Pad", L"Pad",
|
L"Pad", L"Pad",
|
||||||
wxLt("Gamepad activity on the SIO."),
|
pxDt("Gamepad activity on the SIO."),
|
||||||
"Pad"
|
"Pad"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_IOP_DMAC = {
|
TLD_IOP_DMAC = {
|
||||||
L"DmaCrl", L"DMA Controller",
|
L"DmaCrl", L"DMA Controller",
|
||||||
wxLt("Actual DMA event processing and data transfer logs."),
|
pxDt("Actual DMA event processing and data transfer logs."),
|
||||||
"iDmaC"
|
"iDmaC"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_IOP_Counters = {
|
TLD_IOP_Counters = {
|
||||||
L"Counters", L"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"
|
"iCnt"
|
||||||
},
|
},
|
||||||
|
|
||||||
TLD_IOP_CDVD = {
|
TLD_IOP_CDVD = {
|
||||||
L"CDVD", L"CDVD",
|
L"CDVD", L"CDVD",
|
||||||
wxLt("Detailed logging of CDVD hardware."),
|
pxDt("Detailed logging of CDVD hardware."),
|
||||||
"CDVD"
|
"CDVD"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -21,9 +21,6 @@
|
||||||
|
|
||||||
#include "SamplProf.h"
|
#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 "Elfheader.h"
|
||||||
|
|
||||||
#include "System/RecTypes.h"
|
#include "System/RecTypes.h"
|
||||||
|
@ -114,7 +111,7 @@ void RecompiledCodeReserve::ThrowIfNotOk() const
|
||||||
|
|
||||||
throw Exception::OutOfMemory(m_name)
|
throw Exception::OutOfMemory(m_name)
|
||||||
.SetDiagMsg(pxsFmt( L"Recompiled code cache could not be mapped." ))
|
.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 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"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 "
|
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)
|
if (Cpu)
|
||||||
{
|
{
|
||||||
Cpu->SetCacheReserve( (Cpu->GetCacheReserve() * 3) / 2 );
|
Cpu->SetCacheReserve( (Cpu->GetCacheReserve() * 2) / 3 );
|
||||||
Cpu->Reset();
|
Cpu->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CpuVU0)
|
if (CpuVU0)
|
||||||
{
|
{
|
||||||
CpuVU0->SetCacheReserve( (CpuVU0->GetCacheReserve() * 3) / 2 );
|
CpuVU0->SetCacheReserve( (CpuVU0->GetCacheReserve() * 2) / 3 );
|
||||||
CpuVU0->Reset();
|
CpuVU0->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CpuVU1)
|
if (CpuVU1)
|
||||||
{
|
{
|
||||||
CpuVU1->SetCacheReserve( (CpuVU1->GetCacheReserve() * 3) / 2 );
|
CpuVU1->SetCacheReserve( (CpuVU1->GetCacheReserve() * 2) / 3 );
|
||||||
CpuVU1->Reset();
|
CpuVU1->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (psxCpu)
|
if (psxCpu)
|
||||||
{
|
{
|
||||||
psxCpu->SetCacheReserve( (psxCpu->GetCacheReserve() * 3) / 2 );
|
psxCpu->SetCacheReserve( (psxCpu->GetCacheReserve() * 2) / 3 );
|
||||||
psxCpu->Reset();
|
psxCpu->Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,30 +198,37 @@ TraceLogFilters& SetTraceConfig()
|
||||||
// This function should be called once during program execution.
|
// This function should be called once during program execution.
|
||||||
void SysLogMachineCaps()
|
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)" : ""
|
SVN_REV, SVN_MODS ? "(modded)" : ""
|
||||||
);
|
);
|
||||||
|
|
||||||
Console.WriteLn( "Savestate version: 0x%x", g_SaveVersion);
|
Console.WriteLn( "Savestate version: 0x%x", g_SaveVersion);
|
||||||
Console.Newline();
|
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();
|
u32 speed = x86caps.CalculateMHz();
|
||||||
|
|
||||||
Console.Indent().WriteLn(
|
Console.Indent().WriteLn(
|
||||||
L"CPU vendor name = %s\n"
|
L"CPU name = %s\n"
|
||||||
L"FamilyID = %x\n"
|
L"Vendor/Model = %s (stepping %02X)\n"
|
||||||
L"x86Family = %s\n"
|
L"CPU speed = %u.%03u ghz (%u logical thread%s)\n"
|
||||||
L"CPU speed = %d.%03d ghz\n"
|
|
||||||
L"Cores = %d physical [%d logical]\n"
|
|
||||||
L"x86PType = %s\n"
|
L"x86PType = %s\n"
|
||||||
L"x86Flags = %8.8x %8.8x\n"
|
L"x86Flags = %08x %08x\n"
|
||||||
L"x86EFlags = %8.8x",
|
L"x86EFlags = %08x",
|
||||||
fromUTF8( x86caps.VendorName ).c_str(), x86caps.StepID,
|
|
||||||
fromUTF8( x86caps.FamilyName ).Trim().Trim(false).c_str(),
|
fromUTF8( x86caps.FamilyName ).Trim().Trim(false).c_str(),
|
||||||
|
fromUTF8( x86caps.VendorName ).c_str(), x86caps.StepID,
|
||||||
speed / 1000, speed % 1000,
|
speed / 1000, speed % 1000,
|
||||||
x86caps.PhysicalCores, x86caps.LogicalCores,
|
x86caps.LogicalCores, (x86caps.LogicalCores==1) ? L"" : L"s",
|
||||||
x86caps.GetTypeName().c_str(),
|
x86caps.GetTypeName().c_str(),
|
||||||
x86caps.Flags, x86caps.Flags2,
|
x86caps.Flags, x86caps.Flags2,
|
||||||
x86caps.EFlags
|
x86caps.EFlags
|
||||||
|
@ -339,7 +343,7 @@ public:
|
||||||
// returns the translated error message for the Virtual Machine failing to allocate!
|
// returns the translated error message for the Virtual Machine failing to allocate!
|
||||||
static wxString GetMemoryErrorVM()
|
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"PCSX2 is unable to allocate memory needed for the PS2 virtual machine. "
|
||||||
L"Close out some memory hogging background tasks and try again."
|
L"Close out some memory hogging background tasks and try again."
|
||||||
);
|
);
|
||||||
|
@ -598,7 +602,7 @@ wxString SysGetDiscID()
|
||||||
|
|
||||||
if( !ElfCRC )
|
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
|
// the BIOS being run (either a checksum of the BIOS roms, and/or a string based on BIOS
|
||||||
// region and revision).
|
// 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;
|
if( !pxAssertDev( IsPaused(), "CoreThread is not paused; new VM state cannot be uploaded." ) ) return;
|
||||||
|
|
||||||
memLoadingState loadme( copy );
|
memLoadingState loadme( copy );
|
||||||
loadme.FreezeMainMemory();
|
|
||||||
loadme.FreezeAll();
|
loadme.FreezeAll();
|
||||||
m_resetVirtualMachine = false;
|
m_resetVirtualMachine = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,12 +77,16 @@ __fi void vif0FBRST(u32 value) {
|
||||||
|
|
||||||
memzero(vif0);
|
memzero(vif0);
|
||||||
vif0ch.qwc = 0; //?
|
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) = 0;
|
||||||
psHu64(VIF0_FIFO + 8) = 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.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
|
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
|
/* 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);
|
memzero(vif1);
|
||||||
|
|
||||||
//cpuRegs.interrupt &= ~((1 << 1) | (1 << 10)); //Stop all vif1 DMA's
|
//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) = 0;
|
||||||
psHu64(VIF1_FIFO + 8) = 0;
|
psHu64(VIF1_FIFO + 8) = 0;
|
||||||
//vif1.done = false;
|
//vif1.done = false;
|
||||||
|
@ -160,6 +165,7 @@ __fi void vif1FBRST(u32 value) {
|
||||||
vif1.vifstalled = false;
|
vif1.vifstalled = false;
|
||||||
vif1Regs.stat.FQC = 0;
|
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);
|
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
|
/* 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);
|
vif1ch.qwc, vif1ch.madr, vif1ch.tadr);
|
||||||
|
|
||||||
if (vif1.vifstalled)
|
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
|
else
|
||||||
return VIF1transfer(pMem, vif1ch.qwc * 4);
|
return VIF1transfer(pMem, vif1ch.qwc * 4, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
__fi void vif1SetupTransfer()
|
__fi void vif1SetupTransfer()
|
||||||
|
@ -490,7 +490,7 @@ void dmaVIF1()
|
||||||
if(vif1ch.chcr.MOD == CHAIN_MODE && vif1.dmamode != VIF_NORMAL_TO_MEM_MODE)
|
if(vif1ch.chcr.MOD == CHAIN_MODE && vif1.dmamode != VIF_NORMAL_TO_MEM_MODE)
|
||||||
{
|
{
|
||||||
vif1.dmamode = VIF_CHAIN_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))
|
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.dmamode = VIF_CHAIN_MODE;
|
||||||
vif1.done = false;
|
vif1.done = false;
|
||||||
|
vif1.inprogress = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vif1ch.chcr.DIR) vif1Regs.stat.FQC = min((u16)0x10, vif1ch.qwc);
|
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));
|
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()
|
static __fi bool mfifoVIF1rbTransfer()
|
||||||
{
|
{
|
||||||
u32 maddr = dmacRegs.rbor.ADDR;
|
u32 maddr = dmacRegs.rbor.ADDR;
|
||||||
u32 msize = dmacRegs.rbor.ADDR + dmacRegs.rbsr.RMSK + 16;
|
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;
|
u32 *src;
|
||||||
bool ret;
|
bool ret;
|
||||||
|
|
||||||
|
if(mfifoqwc == 0) return true; //Cant do anything, lets forget it
|
||||||
|
|
||||||
/* Check if the transfer should wrap around the ring buffer */
|
/* Check if the transfer should wrap around the ring buffer */
|
||||||
if ((vif1ch.madr + (mfifoqwc << 4)) > (msize))
|
if ((vif1ch.madr + (mfifoqwc << 4)) > (msize))
|
||||||
{
|
{
|
||||||
|
@ -48,6 +73,8 @@ static __fi bool mfifoVIF1rbTransfer()
|
||||||
SPR_LOG("Split MFIFO");
|
SPR_LOG("Split MFIFO");
|
||||||
|
|
||||||
/* it does, so first copy 's1' bytes from 'addr' to 'data' */
|
/* it does, so first copy 's1' bytes from 'addr' to 'data' */
|
||||||
|
vif1ch.madr = qwctag(vif1ch.madr);
|
||||||
|
|
||||||
src = (u32*)PSM(vif1ch.madr);
|
src = (u32*)PSM(vif1ch.madr);
|
||||||
if (src == NULL) return false;
|
if (src == NULL) return false;
|
||||||
|
|
||||||
|
@ -56,10 +83,9 @@ static __fi bool mfifoVIF1rbTransfer()
|
||||||
else
|
else
|
||||||
ret = VIF1transfer(src, s1);
|
ret = VIF1transfer(src, s1);
|
||||||
|
|
||||||
vif1ch.madr = qwctag(vif1ch.madr);
|
|
||||||
|
|
||||||
if (ret)
|
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]' */
|
/* and second copy 's2' bytes from 'maddr' to '&data[s1]' */
|
||||||
vif1ch.madr = maddr;
|
vif1ch.madr = maddr;
|
||||||
|
|
||||||
|
@ -67,13 +93,12 @@ static __fi bool mfifoVIF1rbTransfer()
|
||||||
if (src == NULL) return false;
|
if (src == NULL) return false;
|
||||||
VIF1transfer(src, ((mfifoqwc << 2) - s1));
|
VIF1transfer(src, ((mfifoqwc << 2) - s1));
|
||||||
}
|
}
|
||||||
vif1ch.madr = qwctag(vif1ch.madr);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SPR_LOG("Direct MFIFO");
|
SPR_LOG("Direct MFIFO");
|
||||||
|
|
||||||
/* it doesn't, so just transfer 'qwc*4' words */
|
/* it doesn't, so just transfer 'qwc*4' words */
|
||||||
src = (u32*)PSM(vif1ch.madr);
|
src = (u32*)PSM(vif1ch.madr);
|
||||||
if (src == NULL) return false;
|
if (src == NULL) return false;
|
||||||
|
@ -83,8 +108,6 @@ static __fi bool mfifoVIF1rbTransfer()
|
||||||
else
|
else
|
||||||
ret = VIF1transfer(src, mfifoqwc << 2);
|
ret = VIF1transfer(src, mfifoqwc << 2);
|
||||||
|
|
||||||
vif1ch.madr = qwctag(vif1ch.madr);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -99,13 +122,17 @@ static __fi void mfifo_VIF1chain()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vif1ch.madr >= dmacRegs.rbor.ADDR &&
|
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();
|
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
|
else
|
||||||
|
@ -124,8 +151,6 @@ static __fi void mfifo_VIF1chain()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int NextTADR = 0; //Bodge for Clock Tower 3 (see below)
|
|
||||||
|
|
||||||
void mfifoVIF1transfer(int qwc)
|
void mfifoVIF1transfer(int qwc)
|
||||||
{
|
{
|
||||||
tDMA_TAG *ptag;
|
tDMA_TAG *ptag;
|
||||||
|
@ -134,11 +159,15 @@ void mfifoVIF1transfer(int qwc)
|
||||||
|
|
||||||
if (qwc > 0)
|
if (qwc > 0)
|
||||||
{
|
{
|
||||||
vifqwc += qwc;
|
//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);
|
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 (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
|
vif1Regs.stat.FQC = 0x10; // FQC=16
|
||||||
}
|
}
|
||||||
|
@ -147,8 +176,9 @@ void mfifoVIF1transfer(int qwc)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vif1ch.qwc == 0 && vifqwc > 0)
|
if (vif1ch.qwc == 0)
|
||||||
{
|
{
|
||||||
|
vif1ch.tadr = qwctag(vif1ch.tadr);
|
||||||
ptag = dmaGetAddr(vif1ch.tadr, false);
|
ptag = dmaGetAddr(vif1ch.tadr, false);
|
||||||
|
|
||||||
if (vif1ch.chcr.TTE)
|
if (vif1ch.chcr.TTE)
|
||||||
|
@ -169,63 +199,32 @@ void mfifoVIF1transfer(int qwc)
|
||||||
}
|
}
|
||||||
else
|
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
|
//ret = VIF1transfer((u32*)ptag + 2, 2); //Transfer Tag
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ret && vif1.irqoffset)
|
if (!ret && vif1.irqoffset)
|
||||||
{
|
{
|
||||||
|
vif1.inprogress &= ~1;
|
||||||
return; //IRQ set by VIFTransfer
|
return; //IRQ set by VIFTransfer
|
||||||
|
|
||||||
} //else vif1.vifstalled = false;
|
} //else vif1.vifstalled = false;
|
||||||
g_vifCycles += 2;
|
g_vifCycles += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
vif1.irqoffset = 0;
|
vif1.irqoffset = 0;
|
||||||
|
|
||||||
vif1ch.unsafeTransfer(ptag);
|
vif1ch.unsafeTransfer(ptag);
|
||||||
|
|
||||||
vif1ch.madr = ptag[1]._u32;
|
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",
|
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);
|
ptag[1]._u32, ptag[0]._u32, vif1ch.qwc, ptag->ID, vif1ch.madr, vif1ch.tadr, vifqwc, spr0ch.madr);
|
||||||
|
|
||||||
switch (ptag->ID)
|
vif1.done |= hwDmacSrcChainWithStack(vif1ch, 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vif1ch.chcr.TIE && ptag->IRQ)
|
if (vif1ch.chcr.TIE && ptag->IRQ)
|
||||||
{
|
{
|
||||||
|
@ -233,8 +232,16 @@ void mfifoVIF1transfer(int qwc)
|
||||||
vif1.done = true;
|
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");
|
VIF_LOG("vif mfifo interrupt");
|
||||||
|
|
||||||
|
|
||||||
if(NextTADR != 0 && vif1ch.qwc == 0)
|
if (dmacRegs.ctrl.MFD != MFD_VIF1)
|
||||||
{
|
{
|
||||||
// Clock Tower 3 Note!
|
DevCon.Warning("Not in VIF MFIFO mode! Stopping VIF MFIFO");
|
||||||
/* If the DMA starts the transfer then hammers the TADR to see when the transfer has finished(as clock tower does)
|
return;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH2)
|
if(GSTransferStatus.PTH2 == STOPPED_MODE && gifRegs.stat.APATH == GIF_APATH2)
|
||||||
|
@ -269,7 +272,11 @@ void vifMFIFOInterrupt()
|
||||||
|
|
||||||
if (schedulepath3msk & 0x10) Vif1MskPath3();
|
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)
|
//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
|
//Simulated GS transfer time done, clear the flags
|
||||||
|
@ -283,8 +290,10 @@ void vifMFIFOInterrupt()
|
||||||
vif1Regs.stat.VPS = VPS_IDLE;
|
vif1Regs.stat.VPS = VPS_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (vif1.irq && vif1.tag.size == 0)
|
if (vif1.irq && vif1.tag.size == 0)
|
||||||
{
|
{
|
||||||
|
SPR_LOG("VIF MFIFO Code Interrupt detected");
|
||||||
vif1Regs.stat.INT = true;
|
vif1Regs.stat.INT = true;
|
||||||
hwIntcIrq(INTC_VIF1);
|
hwIntcIrq(INTC_VIF1);
|
||||||
--vif1.irq;
|
--vif1.irq;
|
||||||
|
@ -293,55 +302,40 @@ void vifMFIFOInterrupt()
|
||||||
{
|
{
|
||||||
/*vif1Regs.stat.FQC = 0; // FQC=0
|
/*vif1Regs.stat.FQC = 0; // FQC=0
|
||||||
vif1ch.chcr.STR = false;*/
|
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)
|
if (vif1.done == false || vif1ch.qwc)
|
||||||
{
|
{
|
||||||
|
|
||||||
switch(vif1.inprogress & 1)
|
switch(vif1.inprogress & 1)
|
||||||
{
|
{
|
||||||
case 0: //Set up transfer
|
case 0: //Set up transfer
|
||||||
if (vif1ch.tadr == spr0ch.madr)
|
if (QWCinVIFMFIFO(vif1ch.tadr) == 0)
|
||||||
{
|
{
|
||||||
// Console.WriteLn("Empty 1");
|
vif1.inprogress |= 0x10;
|
||||||
vifqwc = 0;
|
CPU_INT(DMAC_MFIFO_VIF, 4 );
|
||||||
if((vif1.inprogress & 0x10) == 0)
|
|
||||||
{
|
|
||||||
hwDmacIrq(DMAC_MFIFO_EMPTY);
|
|
||||||
vif1.inprogress |= 0x10;
|
|
||||||
}
|
|
||||||
vif1Regs.stat.FQC = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mfifoVIF1transfer(0);
|
mfifoVIF1transfer(0);
|
||||||
|
|
||||||
|
|
||||||
CPU_INT(DMAC_MFIFO_VIF, 4);
|
|
||||||
return;
|
|
||||||
|
|
||||||
case 1: //Transfer data
|
case 1: //Transfer data
|
||||||
mfifo_VIF1chain();
|
mfifo_VIF1chain();
|
||||||
//Sanity check! making sure we always have non-zero values
|
//Sanity check! making sure we always have non-zero values
|
||||||
CPU_INT(DMAC_MFIFO_VIF, (g_vifCycles == 0 ? 4 : g_vifCycles) );
|
CPU_INT(DMAC_MFIFO_VIF, (g_vifCycles == 0 ? 4 : g_vifCycles) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//FF7 Dirge of Cerberus seems to like the mfifo to tell it when it's empty, even if it's ending.
|
|
||||||
//Doesn't seem to care about the vif1 dma interrupting (possibly disabled the interrupt?)
|
|
||||||
if (vif1ch.tadr == spr0ch.madr)
|
|
||||||
{
|
|
||||||
vifqwc = 0;
|
|
||||||
if((vif1.inprogress & 0x10) == 0)
|
|
||||||
{
|
|
||||||
hwDmacIrq(DMAC_MFIFO_EMPTY);
|
|
||||||
vif1.inprogress |= 0x10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
vif1.vifstalled = false;
|
vif1.vifstalled = false;
|
||||||
vif1.done = 1;
|
vif1.done = 1;
|
||||||
g_vifCycles = 0;
|
g_vifCycles = 0;
|
||||||
|
|
|
@ -115,6 +115,8 @@ vifOp(vifCode_Base) {
|
||||||
}
|
}
|
||||||
|
|
||||||
extern bool SIGNAL_IMR_Pending;
|
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) {
|
template<int idx> __fi int _vifCode_Direct(int pass, const u8* data, bool isDirectHL) {
|
||||||
pass1 {
|
pass1 {
|
||||||
|
@ -154,7 +156,7 @@ template<int idx> __fi int _vifCode_Direct(int pass, const u8* data, bool isDire
|
||||||
}
|
}
|
||||||
if(SIGNAL_IMR_Pending == true)
|
if(SIGNAL_IMR_Pending == true)
|
||||||
{
|
{
|
||||||
DevCon.Warning("Path 2 Paused (At start)");
|
//DevCon.Warning("Path 2 Paused (At start)");
|
||||||
vif1.vifstalled = true;
|
vif1.vifstalled = true;
|
||||||
return 0;
|
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 minSize = aMin(vif1.vifpacketsize, vif1.tag.size);
|
||||||
uint ret;
|
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
|
// 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
|
// 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,
|
// 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)
|
for( uint i=0; i<(minSize & 3); ++i)
|
||||||
|
{
|
||||||
partial_write[partial_count++] = ((u32*)data)[i];
|
partial_write[partial_count++] = ((u32*)data)[i];
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
|
||||||
pxAssume( partial_count <= 4 );
|
pxAssume( partial_count <= 4 );
|
||||||
ret = 0;
|
|
||||||
if (partial_count == 4)
|
if (partial_count == 4)
|
||||||
{
|
{
|
||||||
GetMTGS().PrepDataPacket(GIF_PATH_2, 1);
|
GetMTGS().PrepDataPacket(GIF_PATH_2, 1);
|
||||||
GIFPath_CopyTag(GIF_PATH_2, (u128*)partial_write, 1);
|
GIFPath_CopyTag(GIF_PATH_2, (u128*)partial_write, 1);
|
||||||
GetMTGS().SendDataPacket();
|
GetMTGS().SendDataPacket();
|
||||||
partial_count = 0;
|
partial_count = 0;
|
||||||
ret = 4;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -372,14 +377,16 @@ vifOp(vifCode_MSCNT) {
|
||||||
vifOp(vifCode_MskPath3) {
|
vifOp(vifCode_MskPath3) {
|
||||||
vif1Only();
|
vif1Only();
|
||||||
pass1 {
|
pass1 {
|
||||||
|
//I Hate the timing sensitivity of this stuff
|
||||||
if (vif1ch.chcr.STR && vif1.lastcmd != 0x13) {
|
if (vif1ch.chcr.STR && vif1.lastcmd != 0x13) {
|
||||||
schedulepath3msk = 0x10 | ((vif1Regs.code >> 15) & 0x1);
|
schedulepath3msk = 0x10 | ((vif1Regs.code >> 15) & 0x1);
|
||||||
vif1.vifstalled = true;
|
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
schedulepath3msk = (vif1Regs.code >> 15) & 0x1;
|
schedulepath3msk = (vif1Regs.code >> 15) & 0x1;
|
||||||
Vif1MskPath3();
|
Vif1MskPath3();
|
||||||
}
|
}
|
||||||
|
if(vif1ch.chcr.STR)vif1.vifstalled = true;
|
||||||
vif1.cmd = 0;
|
vif1.cmd = 0;
|
||||||
}
|
}
|
||||||
pass3 { VifCodeLog("MskPath3"); }
|
pass3 { VifCodeLog("MskPath3"); }
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
// Doesn't stall if the next vifCode is the Mark command
|
// Doesn't stall if the next vifCode is the Mark command
|
||||||
_vifT bool runMark(u32* &data) {
|
_vifT bool runMark(u32* &data) {
|
||||||
if (((vifXRegs.code >> 24) & 0x7f) == 0x7) {
|
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; // No Stall?
|
||||||
}
|
}
|
||||||
return 1; // Stall
|
return 1; // Stall
|
||||||
|
@ -145,12 +145,21 @@ _vifT static __fi bool vifTransfer(u32 *data, int size, bool TTE) {
|
||||||
|
|
||||||
vifXch.madr +=(transferred << 4);
|
vifXch.madr +=(transferred << 4);
|
||||||
vifXch.qwc -= transferred;
|
vifXch.qwc -= transferred;
|
||||||
}
|
if(vifXch.chcr.STR)hwDmacSrcTadrInc(vifXch);
|
||||||
|
|
||||||
if (!vifXch.qwc && !vifX.irqoffset)
|
if (!vifXch.qwc)
|
||||||
|
{
|
||||||
|
vifX.inprogress &= ~0x1;
|
||||||
|
vifX.vifstalled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
vifX.inprogress &= ~0x1;
|
|
||||||
vifX.vifstalled = false;
|
if(!vifX.irqoffset)
|
||||||
|
{
|
||||||
|
vifX.vifstalled = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vifX.irq && vifX.cmd == 0) {
|
if (vifX.irq && vifX.cmd == 0) {
|
||||||
|
|
|
@ -21,22 +21,6 @@
|
||||||
|
|
||||||
using namespace Threading;
|
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
|
// 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.
|
// single for-loop to create them.
|
||||||
static const int PluginMenuId_Interval = 0x10;
|
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
|
// 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
|
// 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.
|
// along with the GS, since the GS viewport window handle will have changed.
|
||||||
|
@ -109,6 +117,7 @@ enum MenuIdentifiers
|
||||||
MenuId_Config_AppSettings,
|
MenuId_Config_AppSettings,
|
||||||
MenuId_Config_GameDatabase,
|
MenuId_Config_GameDatabase,
|
||||||
MenuId_Config_BIOS,
|
MenuId_Config_BIOS,
|
||||||
|
MenuId_Config_Language,
|
||||||
|
|
||||||
// Plugin ID order is important. Must match the order in tbl_PluginInfo.
|
// Plugin ID order is important. Must match the order in tbl_PluginInfo.
|
||||||
MenuId_Config_GS,
|
MenuId_Config_GS,
|
||||||
|
@ -359,6 +368,10 @@ class Pcsx2AppTraits : public wxGUIAppTraits
|
||||||
public:
|
public:
|
||||||
virtual ~Pcsx2AppTraits() {}
|
virtual ~Pcsx2AppTraits() {}
|
||||||
wxMessageOutput* CreateMessageOutput();
|
wxMessageOutput* CreateMessageOutput();
|
||||||
|
|
||||||
|
#ifdef wxUSE_STDPATHS
|
||||||
|
wxStandardPathsBase& GetStandardPaths();
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// =====================================================================================================
|
// =====================================================================================================
|
||||||
|
|
|
@ -97,26 +97,7 @@ namespace PathDefs
|
||||||
// Specifies the main configuration folder.
|
// Specifies the main configuration folder.
|
||||||
wxDirName GetUserLocalDataDir()
|
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());
|
return wxDirName(wxStandardPaths::Get().GetUserLocalDataDir());
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetches the path location for user-consumable documents -- stuff users are likely to want to
|
// Fetches the path location for user-consumable documents -- stuff users are likely to want to
|
||||||
|
@ -384,6 +365,7 @@ AppConfig::AppConfig()
|
||||||
, DeskTheme( L"default" )
|
, DeskTheme( L"default" )
|
||||||
{
|
{
|
||||||
LanguageId = wxLANGUAGE_DEFAULT;
|
LanguageId = wxLANGUAGE_DEFAULT;
|
||||||
|
LanguageCode = L"default";
|
||||||
RecentIsoCount = 12;
|
RecentIsoCount = 12;
|
||||||
Listbook_ImageSize = 32;
|
Listbook_ImageSize = 32;
|
||||||
Toolbar_ImageSize = 24;
|
Toolbar_ImageSize = 24;
|
||||||
|
@ -487,6 +469,7 @@ void AppConfig::LoadSaveRootItems( IniInterface& ini )
|
||||||
IniEntry( AppSettingsTabName );
|
IniEntry( AppSettingsTabName );
|
||||||
IniEntry( GameDatabaseTabName );
|
IniEntry( GameDatabaseTabName );
|
||||||
ini.EnumEntry( L"LanguageId", LanguageId, NULL, defaults.LanguageId );
|
ini.EnumEntry( L"LanguageId", LanguageId, NULL, defaults.LanguageId );
|
||||||
|
IniEntry( LanguageCode );
|
||||||
IniEntry( RecentIsoCount );
|
IniEntry( RecentIsoCount );
|
||||||
IniEntry( DeskTheme );
|
IniEntry( DeskTheme );
|
||||||
IniEntry( Listbook_ImageSize );
|
IniEntry( Listbook_ImageSize );
|
||||||
|
@ -780,7 +763,8 @@ void AppConfig_OnChangedSettingsFolder( bool overwrite )
|
||||||
if( overwrite )
|
if( overwrite )
|
||||||
{
|
{
|
||||||
if( wxFileExists( iniFilename ) && !wxRemoveFile( iniFilename ) )
|
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
|
// Bind into wxConfigBase to allow wx to use our config internally, and delete whatever
|
||||||
|
|
|
@ -195,9 +195,14 @@ public:
|
||||||
wxString AppSettingsTabName;
|
wxString AppSettingsTabName;
|
||||||
wxString GameDatabaseTabName;
|
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;
|
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.
|
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)
|
// 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") );
|
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"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." )
|
L"Your options will be limited and emulation will be *very* slow." )
|
||||||
);
|
);
|
||||||
|
@ -70,12 +70,30 @@ void Pcsx2App::WipeUserModeSettings()
|
||||||
usermodefile.SetPath( usrlocaldir.ToString() );
|
usermodefile.SetPath( usrlocaldir.ToString() );
|
||||||
ScopedPtr<wxFileConfig> conf_usermode( OpenFileConfig( usermodefile.GetFullPath() ) );
|
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.WriteLn( "(UserModeSettings) Removing entry:" );
|
||||||
Console.Indent().WriteLn( L"Path: %s\nHash:%s", cwd.c_str(), groupname.c_str() );
|
Console.Indent().WriteLn( L"Path: %s\nHash:%s", cwd.c_str(), groupname.c_str() );
|
||||||
conf_usermode->DeleteGroup( groupname );
|
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:
|
// 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)
|
// (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
|
// (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() );
|
usermodefile.SetPath( usrlocaldir.ToString() );
|
||||||
ScopedPtr<wxFileConfig> conf_usermode( OpenFileConfig( usermodefile.GetFullPath() ) );
|
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 hasGroup = conf_usermode->HasGroup( groupname );
|
||||||
bool forceWiz = Startup.ForceWizard || !hasGroup;
|
bool forceWiz = Startup.ForceWizard || !hasGroup;
|
||||||
|
@ -135,10 +154,7 @@ void Pcsx2App::ReadUserModeSettings()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// first time startup, so give the user the choice of user mode:
|
DoFirstTimeWizard();
|
||||||
FirstTimeWizard wiz( NULL );
|
|
||||||
if( !wiz.RunWizard( wiz.GetUsermodePage() ) )
|
|
||||||
throw Exception::StartupAborted( L"User canceled FirstTime Wizard." );
|
|
||||||
|
|
||||||
// Save user's new settings
|
// Save user's new settings
|
||||||
IniSaver saver( *conf_usermode );
|
IniSaver saver( *conf_usermode );
|
||||||
|
@ -159,14 +175,8 @@ void Pcsx2App::ReadUserModeSettings()
|
||||||
if( !wxFile::Exists( GetSettingsFilename() ) )
|
if( !wxFile::Exists( GetSettingsFilename() ) )
|
||||||
{
|
{
|
||||||
// user wiped their pcsx2.ini -- needs a reconfiguration via wizard!
|
// user wiped their pcsx2.ini -- needs a reconfiguration via wizard!
|
||||||
// (we skip the first page since it's a usermode.ini thing)
|
|
||||||
|
DoFirstTimeWizard();
|
||||||
// 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." );
|
|
||||||
|
|
||||||
// Save user's new settings
|
// Save user's new settings
|
||||||
IniSaver saver( *conf_usermode );
|
IniSaver saver( *conf_usermode );
|
||||||
|
@ -236,6 +246,19 @@ void Pcsx2App::OpenProgramLog()
|
||||||
EnableAllLogging();
|
EnableAllLogging();
|
||||||
|
|
||||||
if( m_current_focus ) m_current_focus->SetFocus();
|
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()
|
void Pcsx2App::AllocateCoreStuffs()
|
||||||
|
@ -264,7 +287,7 @@ void Pcsx2App::AllocateCoreStuffs()
|
||||||
wxDialogWithHelpers exconf( NULL, _("PCSX2 Recompiler Error(s)") );
|
wxDialogWithHelpers exconf( NULL, _("PCSX2 Recompiler Error(s)") );
|
||||||
|
|
||||||
exconf += 12;
|
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:" )
|
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;
|
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"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." )
|
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 {
|
const PluginInfo* pi = tbl_PluginInfo; do {
|
||||||
parser.AddOption( wxEmptyString, pi->GetShortname().Lower(),
|
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 );
|
} while( ++pi, pi->shortname != NULL );
|
||||||
|
|
||||||
|
@ -524,6 +547,9 @@ bool Pcsx2App::OnInit()
|
||||||
g_Conf = new AppConfig();
|
g_Conf = new AppConfig();
|
||||||
wxInitAllImageHandlers();
|
wxInitAllImageHandlers();
|
||||||
|
|
||||||
|
Console.WriteLn("Applying operating system default language...");
|
||||||
|
i18n_SetLanguage( wxLANGUAGE_DEFAULT );
|
||||||
|
|
||||||
Console.WriteLn("Command line parsing...");
|
Console.WriteLn("Command line parsing...");
|
||||||
if( !_parent::OnInit() ) return false;
|
if( !_parent::OnInit() ) return false;
|
||||||
Console.WriteLn("Command line parsed!");
|
Console.WriteLn("Command line parsed!");
|
||||||
|
@ -552,8 +578,6 @@ bool Pcsx2App::OnInit()
|
||||||
InitDefaultGlobalAccelerators();
|
InitDefaultGlobalAccelerators();
|
||||||
delete wxLog::SetActiveTarget( new pxLogConsole() );
|
delete wxLog::SetActiveTarget( new pxLogConsole() );
|
||||||
|
|
||||||
m_RecentIsoList = new RecentIsoList();
|
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
pxDwm_Load();
|
pxDwm_Load();
|
||||||
#endif
|
#endif
|
||||||
|
@ -775,6 +799,28 @@ protected:
|
||||||
Pcsx2App::Pcsx2App()
|
Pcsx2App::Pcsx2App()
|
||||||
: SysExecutorThread( new SysEvtHandler() )
|
: 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_PendingSaves = 0;
|
||||||
m_ScheduledTermination = false;
|
m_ScheduledTermination = false;
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
|
|
||||||
#include "Utilities/IniInterface.h"
|
#include "Utilities/IniInterface.h"
|
||||||
|
|
||||||
|
#include <wx/stdpaths.h>
|
||||||
|
|
||||||
#ifdef __WXMSW__
|
#ifdef __WXMSW__
|
||||||
# include <wx/msw/wrapwin.h> // needed to implement the app!
|
# include <wx/msw/wrapwin.h> // needed to implement the app!
|
||||||
#endif
|
#endif
|
||||||
|
@ -275,6 +277,12 @@ public:
|
||||||
virtual void Printf(const wxChar* format, ...);
|
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, ...)
|
void pxMessageOutputMessageBox::Printf(const wxChar* format, ...)
|
||||||
{
|
{
|
||||||
using namespace pxSizerFlags;
|
using namespace pxSizerFlags;
|
||||||
|
@ -285,14 +293,16 @@ void pxMessageOutputMessageBox::Printf(const wxChar* format, ...)
|
||||||
out.PrintfV(format, args);
|
out.PrintfV(format, args);
|
||||||
va_end(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)
|
if(pos == wxNOT_FOUND)
|
||||||
{
|
{
|
||||||
Msgbox::Alert( out ); return;
|
Msgbox::Alert( out ); return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pos += 9; // strlen of [IsoFile]
|
pos += isoFormatted.Length();
|
||||||
|
|
||||||
wxDialogWithHelpers popup( NULL, AddAppName(_("%s Commandline Options")) );
|
wxDialogWithHelpers popup( NULL, AddAppName(_("%s Commandline Options")) );
|
||||||
popup.SetMinWidth( 640 );
|
popup.SetMinWidth( 640 );
|
||||||
|
@ -305,8 +315,8 @@ void pxMessageOutputMessageBox::Printf(const wxChar* format, ...)
|
||||||
wxTE_READONLY | wxTE_MULTILINE | wxTE_RICH2 | wxHSCROLL
|
wxTE_READONLY | wxTE_MULTILINE | wxTE_RICH2 | wxHSCROLL
|
||||||
);
|
);
|
||||||
|
|
||||||
traceArea->SetDefaultStyle( wxTextAttr( wxNullColour, wxNullColour, pxGetFixedFont() ) );
|
traceArea->SetDefaultStyle( wxTextAttr( wxNullColour, wxNullColour, pxGetFixedFont(9) ) );
|
||||||
traceArea->SetFont( pxGetFixedFont() );
|
traceArea->SetFont( pxGetFixedFont(9) );
|
||||||
|
|
||||||
int fonty = traceArea->GetCharHeight();
|
int fonty = traceArea->GetCharHeight();
|
||||||
|
|
||||||
|
@ -328,7 +338,54 @@ wxMessageOutput* Pcsx2AppTraits::CreateMessageOutput()
|
||||||
return new pxMessageOutputMessageBox;
|
return new pxMessageOutputMessageBox;
|
||||||
#endif
|
#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)
|
// FramerateManager (implementations)
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
@ -423,7 +480,7 @@ void Pcsx2App::OnEmuKeyDown( wxKeyEvent& evt )
|
||||||
// are multiple variations on the BIOS and BIOS folder checks).
|
// are multiple variations on the BIOS and BIOS folder checks).
|
||||||
wxString BIOS_GetMsg_Required()
|
wxString BIOS_GetMsg_Required()
|
||||||
{
|
{
|
||||||
return pxE( ".Popup:BiosDumpRequired",
|
return pxE( "!Notice:BiosDumpRequired",
|
||||||
L"\n\n"
|
L"\n\n"
|
||||||
L"PCSX2 requires a PS2 BIOS in order to run. For legal reasons, you *must* obtain \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"
|
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 );
|
wxDialogWithHelpers dialog( NULL, _("PCSX2 Unresponsive Thread"), wxVERTICAL );
|
||||||
|
|
||||||
dialog += dialog.Heading( ex.FormatDisplayMessage() + L"\n\n" +
|
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"'Ignore' to continue waiting for the thread to respond.\n"
|
||||||
L"'Cancel' to attempt to cancel the thread.\n"
|
L"'Cancel' to attempt to cancel the thread.\n"
|
||||||
L"'Terminate' to quit PCSX2 immediately.\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
|
// 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
|
// 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
|
// closed). In most cases you'll want to use HasMainFrame() to test for thread
|
||||||
|
@ -622,16 +674,10 @@ void AppApplySettings( const AppConfig* oldconf )
|
||||||
|
|
||||||
RelocateLogfile();
|
RelocateLogfile();
|
||||||
|
|
||||||
if( (oldconf == NULL) || (oldconf->LanguageId != g_Conf->LanguageId) )
|
if( (oldconf == NULL) || (oldconf->LanguageCode.CmpNoCase(g_Conf->LanguageCode)) )
|
||||||
{
|
{
|
||||||
wxDoNotLogInThisScope please;
|
wxDoNotLogInThisScope please;
|
||||||
if( !i18n_SetLanguage( g_Conf->LanguageId ) )
|
i18n_SetLanguage( g_Conf->LanguageId, g_Conf->LanguageCode );
|
||||||
{
|
|
||||||
if( !i18n_SetLanguage( wxLANGUAGE_DEFAULT ) )
|
|
||||||
{
|
|
||||||
i18n_SetLanguage( wxLANGUAGE_ENGLISH );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CorePlugins.SetSettingsFolder( GetSettingsFolder().ToString() );
|
CorePlugins.SetSettingsFolder( GetSettingsFolder().ToString() );
|
||||||
|
|
|
@ -80,13 +80,13 @@ pxAppResources::~pxAppResources() throw() {}
|
||||||
|
|
||||||
wxMenu& Pcsx2App::GetRecentIsoMenu()
|
wxMenu& Pcsx2App::GetRecentIsoMenu()
|
||||||
{
|
{
|
||||||
pxAssert( !!m_RecentIsoList->Menu );
|
if (!m_RecentIsoList) m_RecentIsoList = new RecentIsoList();
|
||||||
return *m_RecentIsoList->Menu;
|
return *m_RecentIsoList->Menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
RecentIsoManager& Pcsx2App::GetRecentIsoManager()
|
RecentIsoManager& Pcsx2App::GetRecentIsoManager()
|
||||||
{
|
{
|
||||||
pxAssert( !!m_RecentIsoList->Manager );
|
if (!m_RecentIsoList) m_RecentIsoList = new RecentIsoList();
|
||||||
return *m_RecentIsoList->Manager;
|
return *m_RecentIsoList->Manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ namespace Exception
|
||||||
public:
|
public:
|
||||||
explicit CannotApplySettings( BaseApplicableConfigPanel* thispanel )
|
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;
|
m_Panel = thispanel;
|
||||||
IsVerbose = true;
|
IsVerbose = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -409,22 +409,22 @@ ConsoleLogFrame::ConsoleLogFrame( MainEmuFrame *parent, const wxString& title, A
|
||||||
|
|
||||||
// create Appearance menu and submenus
|
// 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 );
|
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 );
|
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 );
|
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 );
|
wxITEM_RADIO )->Check( options.FontSize == 12 );
|
||||||
|
|
||||||
menuFontSizes.AppendSeparator();
|
menuFontSizes.AppendSeparator();
|
||||||
menuFontSizes.Append( MenuId_ColorScheme_Light, _("Light theme"), _("Default soft-tone color scheme."), wxITEM_RADIO );
|
menuFontSizes.Append( MenuId_ColorScheme_Light, _("Light theme"), _t("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_Dark, _("Dark theme"), _t("Classic black color scheme for people who enjoy having text seared into their optic nerves."), wxITEM_RADIO );
|
||||||
|
|
||||||
menuAppear.AppendSeparator();
|
menuAppear.AppendSeparator();
|
||||||
menuAppear.Append( wxID_ANY, _("Always on Top"),
|
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_SAVE, _("&Save..."), _("Save log contents to file"));
|
||||||
menuLog.Append(wxID_CLEAR, _("C&lear"), _("Clear the log window contents"));
|
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; }
|
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
|
// McdConfigDialog
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -65,7 +65,7 @@ static wxString ResultToString( int result, const MsgButtons& buttons )
|
||||||
case wxID_ABORT: return L"abort";
|
case wxID_ABORT: return L"abort";
|
||||||
case wxID_RETRY: return L"retry";
|
case wxID_RETRY: return L"retry";
|
||||||
|
|
||||||
// [TODO] : maybe add in an Ignore All?
|
// [TODO] : maybe add in an Ignore All?
|
||||||
case wxID_IGNORE: return L"ignore";
|
case wxID_IGNORE: return L"ignore";
|
||||||
|
|
||||||
case wxID_RESET: return L"reset";
|
case wxID_RESET: return L"reset";
|
||||||
|
@ -73,7 +73,7 @@ static wxString ResultToString( int result, const MsgButtons& buttons )
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result <= wxID_LOWEST)
|
if (result <= wxID_LOWEST)
|
||||||
return buttons.GetCustomLabel();
|
return buttons.GetCustomLabelId();
|
||||||
|
|
||||||
return wxEmptyString;
|
return wxEmptyString;
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,7 +148,7 @@ void Dialogs::CreateMemoryCardDialog::CreateControls()
|
||||||
GetMsg_McdNtfsCompress()
|
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."
|
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[] =
|
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."))
|
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),
|
. SetInt(8),
|
||||||
|
|
||||||
RadioPanelItem(_("16 MB"), _("A typical size for 3rd-party memory cards which should work with most games."))
|
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),
|
. SetInt(16),
|
||||||
|
|
||||||
RadioPanelItem(_("32 MB"), _("A typical size for 3rd-party memory cards which should work with most games."))
|
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),
|
. SetInt(32),
|
||||||
|
|
||||||
RadioPanelItem(_("64 MB"), _("Low compatibility warning: Yes it's very big, but may not work with many games."))
|
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)
|
. SetInt(64)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -45,12 +45,12 @@ bool ApplicableWizardPage::PrepForApply()
|
||||||
Panels::SettingsDirPickerPanel::SettingsDirPickerPanel( wxWindow* parent )
|
Panels::SettingsDirPickerPanel::SettingsDirPickerPanel( wxWindow* parent )
|
||||||
: DirPickerPanel( parent, FolderId_Settings, _("Settings"), AddAppName(_("Select a folder for %s settings")) )
|
: 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"This is the folder where PCSX2 saves your settings, including settings generated "
|
||||||
L"by most plugins (some older plugins may not respect this value)."
|
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"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."
|
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.
|
// FIXME: There's already a file by the same name.. not sure what we should do here.
|
||||||
throw Exception::BadStream( path.ToString() )
|
throw Exception::BadStream( path.ToString() )
|
||||||
.SetDiagMsg(L"Targeted documents folder is already occupied by a file.")
|
.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"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"The path name matches an existing file. Delete the file or change the documents location, "
|
||||||
L"and then try again."
|
L"and then try again."
|
||||||
|
@ -120,7 +120,7 @@ bool FirstTimeWizard::UsermodePage::PrepForApply()
|
||||||
dialog += 12;
|
dialog += 12;
|
||||||
dialog += dialog.Heading( path.ToString() );
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
path.Mkdir();
|
path.Mkdir();
|
||||||
|
@ -149,7 +149,7 @@ FirstTimeWizard::FirstTimeWizard( wxWindow* parent )
|
||||||
// Temporary tutorial message for the BIOS, needs proof-reading!!
|
// Temporary tutorial message for the BIOS, needs proof-reading!!
|
||||||
m_page_bios += 12;
|
m_page_bios += 12;
|
||||||
m_page_bios += new pxStaticHeading( &m_page_bios,
|
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"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 cannot use a copy obtained from a friend or the Internet.\n"
|
||||||
L"You must dump the BIOS from your *own* Playstation 2 console."
|
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_CHANGED, wxWizardEventHandler (FirstTimeWizard::OnPageChanged) );
|
||||||
Connect( wxEVT_WIZARD_PAGE_CHANGING, wxWizardEventHandler (FirstTimeWizard::OnPageChanging) );
|
Connect( wxEVT_WIZARD_PAGE_CHANGING, wxWizardEventHandler (FirstTimeWizard::OnPageChanging) );
|
||||||
Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler (FirstTimeWizard::OnDoubleClicked) );
|
Connect( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEventHandler (FirstTimeWizard::OnDoubleClicked) );
|
||||||
|
|
||||||
|
Connect( pxID_RestartWizard, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( FirstTimeWizard::OnRestartWizard ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
FirstTimeWizard::~FirstTimeWizard() throw()
|
FirstTimeWizard::~FirstTimeWizard() throw()
|
||||||
|
@ -182,6 +184,12 @@ FirstTimeWizard::~FirstTimeWizard() throw()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FirstTimeWizard::OnRestartWizard( wxCommandEvent& evt )
|
||||||
|
{
|
||||||
|
EndModal( pxID_RestartWizard );
|
||||||
|
evt.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
static void _OpenConsole()
|
static void _OpenConsole()
|
||||||
{
|
{
|
||||||
g_Conf->ProgLogBox.Visible = true;
|
g_Conf->ProgLogBox.Visible = true;
|
||||||
|
|
|
@ -17,10 +17,13 @@
|
||||||
#include "ConfigurationDialog.h"
|
#include "ConfigurationDialog.h"
|
||||||
#include "Panels/ConfigurationPanels.h"
|
#include "Panels/ConfigurationPanels.h"
|
||||||
|
|
||||||
|
using namespace Panels;
|
||||||
|
using namespace pxSizerFlags;
|
||||||
|
|
||||||
Dialogs::GameDatabaseDialog::GameDatabaseDialog(wxWindow* parent)
|
Dialogs::GameDatabaseDialog::GameDatabaseDialog(wxWindow* parent)
|
||||||
: BaseConfigurationDialog( parent, AddAppName(_("Game Database - %s")), 580 )
|
: BaseConfigurationDialog( parent, AddAppName(_("Game database - %s")), 580 )
|
||||||
{
|
{
|
||||||
ScopedBusyCursor busy( Cursor_ReallyBusy );
|
ScopedBusyCursor busy( Cursor_ReallyBusy );
|
||||||
*this += new Panels::GameDatabasePanel(this);
|
*this += new GameDatabasePanel(this) | StdExpand();
|
||||||
AddOkCancel();
|
AddOkCancel();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,8 +25,10 @@ Dialogs::ImportSettingsDialog::ImportSettingsDialog( wxWindow* parent )
|
||||||
{
|
{
|
||||||
SetMinWidth( 440 );
|
SetMinWidth( 440 );
|
||||||
|
|
||||||
pxStaticText& heading( Text( wxsFormat(
|
pxStaticText& heading( Text( pxsFmt(
|
||||||
pxE( ".Popup:ImportExistingSettings",
|
|
||||||
|
/// (%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"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"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)"
|
L"\n\n(or press Cancel to select a different settings folder)"
|
||||||
|
|
|
@ -27,7 +27,7 @@ using namespace pxSizerFlags;
|
||||||
|
|
||||||
wxString GetMsg_McdNtfsCompress()
|
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"NTFS compression is built-in, fast, and completely reliable; and typically compresses memory cards "
|
||||||
L"very well (this option is highly recommended)."
|
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,
|
m_check_Ejection = new pxCheckBox( this,
|
||||||
_("Auto-eject memory cards when loading savestates"),
|
_("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"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)."
|
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 )
|
for( uint i=0; i<2; ++i )
|
||||||
{
|
{
|
||||||
m_check_Multitap[i] = new pxCheckBox( this, pxsFmt(_("Enable Multitap on Port %u"), i+1) );
|
m_check_Multitap[i] = new pxCheckBox( this, pxsFmt(_("Enable Multitap on Port %u"), i+1) );
|
||||||
|
@ -60,23 +62,29 @@ Panels::McdConfigPanel_Toggles::McdConfigPanel_Toggles(wxWindow *parent)
|
||||||
|
|
||||||
*this += 4;
|
*this += 4;
|
||||||
|
|
||||||
|
*this += m_check_SavestateBackup;
|
||||||
|
|
||||||
|
*this += 4;
|
||||||
|
|
||||||
*this += m_check_Ejection;
|
*this += m_check_Ejection;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panels::McdConfigPanel_Toggles::Apply()
|
void Panels::McdConfigPanel_Toggles::Apply()
|
||||||
{
|
{
|
||||||
g_Conf->EmuOptions.MultitapPort0_Enabled = m_check_Multitap[0]->GetValue();
|
g_Conf->EmuOptions.MultitapPort0_Enabled = m_check_Multitap[0]->GetValue();
|
||||||
g_Conf->EmuOptions.MultitapPort1_Enabled = m_check_Multitap[1]->GetValue();
|
g_Conf->EmuOptions.MultitapPort1_Enabled = m_check_Multitap[1]->GetValue();
|
||||||
|
|
||||||
g_Conf->EmuOptions.McdEnableEjection = m_check_Ejection->GetValue();
|
g_Conf->EmuOptions.BackupSavestate = m_check_SavestateBackup->GetValue();
|
||||||
|
g_Conf->EmuOptions.McdEnableEjection = m_check_Ejection->GetValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panels::McdConfigPanel_Toggles::AppStatusEvent_OnSettingsApplied()
|
void Panels::McdConfigPanel_Toggles::AppStatusEvent_OnSettingsApplied()
|
||||||
{
|
{
|
||||||
m_check_Multitap[0] ->SetValue( g_Conf->EmuOptions.MultitapPort0_Enabled );
|
m_check_Multitap[0] ->SetValue( g_Conf->EmuOptions.MultitapPort0_Enabled );
|
||||||
m_check_Multitap[1] ->SetValue( g_Conf->EmuOptions.MultitapPort1_Enabled );
|
m_check_Multitap[1] ->SetValue( g_Conf->EmuOptions.MultitapPort1_Enabled );
|
||||||
|
|
||||||
m_check_Ejection ->SetValue( g_Conf->EmuOptions.McdEnableEjection );
|
m_check_SavestateBackup ->SetValue( g_Conf->EmuOptions.BackupSavestate );
|
||||||
|
m_check_Ejection ->SetValue( g_Conf->EmuOptions.McdEnableEjection );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,9 +99,6 @@ Dialogs::McdConfigDialog::McdConfigDialog( wxWindow* parent )
|
||||||
// [TODO] : Plan here is to add an advanced tab which gives the user the ability
|
// [TODO] : Plan here is to add an advanced tab which gives the user the ability
|
||||||
// to configure the names of each memory card slot.
|
// 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 += Heading(_("Drag items over other items in the list to swap or copy memory cards.")) | StdExpand();
|
||||||
*this += StdPadding;
|
*this += StdPadding;
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,6 @@
|
||||||
|
|
||||||
#include <wx/wizard.h>
|
#include <wx/wizard.h>
|
||||||
|
|
||||||
static const wxWindowID pxID_CUSTOM = wxID_LOWEST - 1;
|
|
||||||
|
|
||||||
class FirstTimeWizard : public wxWizard
|
class FirstTimeWizard : public wxWizard
|
||||||
{
|
{
|
||||||
typedef wxWizard _parent;
|
typedef wxWizard _parent;
|
||||||
|
@ -71,6 +69,8 @@ protected:
|
||||||
virtual void OnPageChanging( wxWizardEvent& evt );
|
virtual void OnPageChanging( wxWizardEvent& evt );
|
||||||
virtual void OnPageChanged( wxWizardEvent& evt );
|
virtual void OnPageChanged( wxWizardEvent& evt );
|
||||||
virtual void OnDoubleClicked( wxCommandEvent& evt );
|
virtual void OnDoubleClicked( wxCommandEvent& evt );
|
||||||
|
|
||||||
|
void OnRestartWizard( wxCommandEvent& evt );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ Dialogs::StuckThreadDialog::StuckThreadDialog( wxWindow* parent, StuckThreadActi
|
||||||
stuck_thread.AddListener( this );
|
stuck_thread.AddListener( this );
|
||||||
|
|
||||||
*this += Heading( wxsFormat(
|
*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"The thread '%s' is not responding. It could be deadlocked, or it might "
|
||||||
L"just be running *really* slowly."
|
L"just be running *really* slowly."
|
||||||
),
|
),
|
||||||
|
@ -43,7 +43,7 @@ Dialogs::StuckThreadDialog::StuckThreadDialog( wxWindow* parent, StuckThreadActi
|
||||||
L"\nOr press [Ignore] to suppress further assertions."
|
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 ) )
|
if( wxWindow* idyes = FindWindowById( wxID_YES ) )
|
||||||
idyes->SetFocus();
|
idyes->SetFocus();
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "Panels/ConfigurationPanels.h"
|
#include "Panels/ConfigurationPanels.h"
|
||||||
|
|
||||||
using namespace Panels;
|
using namespace Panels;
|
||||||
|
using namespace pxSizerFlags;
|
||||||
|
|
||||||
static void CheckHacksOverrides()
|
static void CheckHacksOverrides()
|
||||||
{
|
{
|
||||||
|
@ -33,7 +34,7 @@ static void CheckHacksOverrides()
|
||||||
|
|
||||||
wxDialogWithHelpers dialog( wxFindWindowByName( L"Dialog:" + Dialogs::SysConfigDialog::GetNameStatic() ), _("Config Overrides Warning") );
|
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"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"These command line options will not be reflected in the Settings dialog, and will be disabled "
|
||||||
L"if you apply any changes here."
|
L"if you apply any changes here."
|
||||||
|
@ -53,7 +54,7 @@ static void CheckPluginsOverrides()
|
||||||
|
|
||||||
wxDialogWithHelpers dialog( NULL, _("Components Overrides Warning") );
|
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"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"These command line options will not be reflected in the settings dialog, and will be disabled "
|
||||||
L"when you apply settings changes here."
|
L"when you apply settings changes here."
|
||||||
|
@ -72,13 +73,12 @@ Dialogs::SysConfigDialog::SysConfigDialog(wxWindow* parent)
|
||||||
CreateListbook( wxGetApp().GetImgList_Config() );
|
CreateListbook( wxGetApp().GetImgList_Config() );
|
||||||
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
|
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
|
||||||
|
|
||||||
AddPage<CpuPanelEE> ( wxLt("EE/IOP"), cfgid.Cpu );
|
AddPage<CpuPanelEE> ( pxL("EE/IOP"), cfgid.Cpu );
|
||||||
AddPage<CpuPanelVU> ( wxLt("VUs"), cfgid.Cpu );
|
AddPage<CpuPanelVU> ( pxL("VUs"), cfgid.Cpu );
|
||||||
AddPage<VideoPanel> ( wxLt("GS"), cfgid.Cpu );
|
AddPage<VideoPanel> ( pxL("GS"), cfgid.Cpu );
|
||||||
AddPage<GSWindowSettingsPanel> ( wxLt("GS Window"), cfgid.Video );
|
AddPage<GSWindowSettingsPanel> ( pxL("GS Window"), cfgid.Video );
|
||||||
AddPage<SpeedHacksPanel> ( wxLt("Speedhacks"), cfgid.Speedhacks );
|
AddPage<SpeedHacksPanel> ( pxL("Speedhacks"), cfgid.Speedhacks );
|
||||||
AddPage<GameFixesPanel> ( wxLt("Game Fixes"), cfgid.Gamefixes );
|
AddPage<GameFixesPanel> ( pxL("Game Fixes"), cfgid.Gamefixes );
|
||||||
//AddPage<GameDatabasePanel> ( wxLt("Game Database"),cfgid.Plugins );
|
|
||||||
|
|
||||||
AddListbook();
|
AddListbook();
|
||||||
AddOkCancel();
|
AddOkCancel();
|
||||||
|
@ -95,9 +95,9 @@ Dialogs::ComponentsConfigDialog::ComponentsConfigDialog(wxWindow* parent)
|
||||||
CreateListbook( wxGetApp().GetImgList_Config() );
|
CreateListbook( wxGetApp().GetImgList_Config() );
|
||||||
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
|
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
|
||||||
|
|
||||||
AddPage<PluginSelectorPanel> ( wxLt("Plugins"), cfgid.Plugins );
|
AddPage<PluginSelectorPanel> ( pxL("Plugins"), cfgid.Plugins );
|
||||||
AddPage<BiosSelectorPanel> ( wxLt("BIOS"), cfgid.Cpu );
|
AddPage<BiosSelectorPanel> ( pxL("BIOS"), cfgid.Cpu );
|
||||||
AddPage<StandardPathsPanel> ( wxLt("Folders"), cfgid.Paths );
|
AddPage<StandardPathsPanel> ( pxL("Folders"), cfgid.Paths );
|
||||||
|
|
||||||
AddListbook();
|
AddListbook();
|
||||||
AddOkCancel();
|
AddOkCancel();
|
||||||
|
@ -105,3 +105,13 @@ Dialogs::ComponentsConfigDialog::ComponentsConfigDialog(wxWindow* parent)
|
||||||
if( wxGetApp().Overrides.HasPluginsOverride() )
|
if( wxGetApp().Overrides.HasPluginsOverride() )
|
||||||
wxGetApp().PostMethod( CheckPluginsOverrides );
|
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 ) {
|
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 ) {
|
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 ) {
|
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()
|
ConsoleLogSource_Event::ConsoleLogSource_Event()
|
||||||
|
@ -37,7 +37,7 @@ ConsoleLogSource_Event::ConsoleLogSource_Event()
|
||||||
static const TraceLogDescriptor myDesc =
|
static const TraceLogDescriptor myDesc =
|
||||||
{
|
{
|
||||||
L"SysEvents", L"SysVM Control Events",
|
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;
|
m_Descriptor = &myDesc;
|
||||||
|
|
|
@ -386,8 +386,7 @@ void GSFrame::OnUpdateTitle( wxTimerEvent& evt )
|
||||||
double fps = wxGetApp().FpsManager.GetFramerate();
|
double fps = wxGetApp().FpsManager.GetFramerate();
|
||||||
|
|
||||||
char gsDest[128];
|
char gsDest[128];
|
||||||
GSgetTitleInfo( gsDest );
|
GSgetTitleInfo2( gsDest, sizeof(gsDest) );
|
||||||
|
|
||||||
|
|
||||||
const wxChar* limiterStr = L"None";
|
const wxChar* limiterStr = L"None";
|
||||||
|
|
||||||
|
@ -401,16 +400,16 @@ void GSFrame::OnUpdateTitle( wxTimerEvent& evt )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString cpuUsage;
|
FastFormatUnicode cpuUsage;
|
||||||
if( m_CpuUsage.IsImplemented() )
|
if( m_CpuUsage.IsImplemented() )
|
||||||
{
|
{
|
||||||
m_CpuUsage.UpdateStats();
|
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);
|
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(),
|
fromUTF8(gsDest).c_str(),
|
||||||
(smode2 & 1) ? L"Interlaced" : L"Progressive",
|
(smode2 & 1) ? L"Interlaced" : L"Progressive",
|
||||||
(smode2 & 2) ? L"frame" : L"field",
|
(smode2 & 2) ? L"frame" : L"field",
|
||||||
|
|
|
@ -240,26 +240,26 @@ static const GlobalCommandDescriptor CommandDeclarations[] =
|
||||||
{
|
{
|
||||||
{ "States_FreezeCurrentSlot",
|
{ "States_FreezeCurrentSlot",
|
||||||
States_FreezeCurrentSlot,
|
States_FreezeCurrentSlot,
|
||||||
wxLt( "Save state" ),
|
pxL( "Save state" ),
|
||||||
wxLt( "Saves the virtual machine state to the current slot." ),
|
pxL( "Saves the virtual machine state to the current slot." ),
|
||||||
},
|
},
|
||||||
|
|
||||||
{ "States_DefrostCurrentSlot",
|
{ "States_DefrostCurrentSlot",
|
||||||
States_DefrostCurrentSlot,
|
States_DefrostCurrentSlot,
|
||||||
wxLt( "Load state" ),
|
pxL( "Load state" ),
|
||||||
wxLt( "Loads a virtual machine state from the current slot." ),
|
pxL( "Loads a virtual machine state from the current slot." ),
|
||||||
},
|
},
|
||||||
|
|
||||||
{ "States_CycleSlotForward",
|
{ "States_CycleSlotForward",
|
||||||
States_CycleSlotForward,
|
States_CycleSlotForward,
|
||||||
wxLt( "Cycle to next slot" ),
|
pxL( "Cycle to next slot" ),
|
||||||
wxLt( "Cycles the current save slot in +1 fashion!" ),
|
pxL( "Cycles the current save slot in +1 fashion!" ),
|
||||||
},
|
},
|
||||||
|
|
||||||
{ "States_CycleSlotBackward",
|
{ "States_CycleSlotBackward",
|
||||||
States_CycleSlotBackward,
|
States_CycleSlotBackward,
|
||||||
wxLt( "Cycle to prev slot" ),
|
pxL( "Cycle to prev slot" ),
|
||||||
wxLt( "Cycles the current save slot in -1 fashion!" ),
|
pxL( "Cycles the current save slot in -1 fashion!" ),
|
||||||
},
|
},
|
||||||
|
|
||||||
{ "Frameskip_Toggle",
|
{ "Frameskip_Toggle",
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
wxString GetMsg_ConfirmSysReset()
|
wxString GetMsg_ConfirmSysReset()
|
||||||
{
|
{
|
||||||
return pxE( ".Popup:ConfirmSysReset",
|
return pxE( "!Notice:ConfirmSysReset",
|
||||||
L"This action will reset the existing PS2 virtual machine state; "
|
L"This action will reset the existing PS2 virtual machine state; "
|
||||||
L"all current progress will be lost. Are you sure?"
|
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") ) );
|
// 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
|
// MainFrame OnEvent Handlers
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
@ -157,6 +180,7 @@ void MainEmuFrame::ConnectMenus()
|
||||||
ConnectMenu( MenuId_Config_AppSettings, Menu_WindowSettings_Click );
|
ConnectMenu( MenuId_Config_AppSettings, Menu_WindowSettings_Click );
|
||||||
ConnectMenu( MenuId_Config_GameDatabase,Menu_GameDatabase_Click );
|
ConnectMenu( MenuId_Config_GameDatabase,Menu_GameDatabase_Click );
|
||||||
ConnectMenu( MenuId_Config_BIOS, Menu_SelectPluginsBios_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_ResetAll, Menu_ResetAllSettings_Click );
|
||||||
|
|
||||||
ConnectMenu( MenuId_Config_Multitap0Toggle, Menu_MultitapToggle_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_LoadStatesSubmenu( *MakeStatesSubMenu( MenuId_State_Load01 ) )
|
||||||
, m_SaveStatesSubmenu( *MakeStatesSubMenu( MenuId_State_Save01 ) )
|
, m_SaveStatesSubmenu( *MakeStatesSubMenu( MenuId_State_Save01 ) )
|
||||||
|
|
||||||
, m_MenuItem_Console( *new wxMenuItem( &m_menuMisc, MenuId_Console, L"Show Console", 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, L"Console to Stdio", wxEmptyString, wxITEM_CHECK ) )
|
, m_MenuItem_Console_Stdio( *new wxMenuItem( &m_menuMisc, MenuId_Console_Stdio, _("Console to Stdio"), wxEmptyString, wxITEM_CHECK ) )
|
||||||
|
|
||||||
{
|
{
|
||||||
m_RestartEmuOnDelete = false;
|
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_SysSettings, _("Emulation &Settings") );
|
||||||
m_menuConfig.Append(MenuId_Config_McdSettings, _("&Memory cards") );
|
m_menuConfig.Append(MenuId_Config_McdSettings, _("&Memory cards") );
|
||||||
m_menuConfig.Append(MenuId_Config_BIOS, _("&Plugin/BIOS Selector") );
|
m_menuConfig.Append(MenuId_Config_BIOS, _("&Plugin/BIOS Selector") );
|
||||||
m_menuConfig.Append(MenuId_Config_GameDatabase, _("Game Database Editor") );
|
if (IsDebugBuild)
|
||||||
|
{
|
||||||
|
m_menuConfig.Append(MenuId_Config_GameDatabase, _("Game Database Editor") );
|
||||||
|
m_menuConfig.Append(MenuId_Config_Language, _("Language...") );
|
||||||
|
}
|
||||||
|
|
||||||
m_menuConfig.AppendSeparator();
|
m_menuConfig.AppendSeparator();
|
||||||
|
|
||||||
m_menuConfig.Append(MenuId_Config_GS, _("&Video (GS)"), m_PluginMenuPacks[PluginId_GS]);
|
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_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_DEV9, _("Dev9"), m_PluginMenuPacks[PluginId_DEV9]);
|
||||||
m_menuConfig.Append(MenuId_Config_USB, _("USB"), m_PluginMenuPacks[PluginId_USB]);
|
m_menuConfig.Append(MenuId_Config_USB, _("USB"), m_PluginMenuPacks[PluginId_USB]);
|
||||||
m_menuConfig.Append(MenuId_Config_FireWire, _("Firewire"), m_PluginMenuPacks[PluginId_FW]);
|
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(41, "Patch Browser...", wxEmptyString, wxITEM_NORMAL);
|
||||||
//m_menuMisc.Append(42, "Patch Finder...", 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();
|
m_menuMisc.AppendSeparator();
|
||||||
|
|
||||||
//Todo:
|
//Todo:
|
||||||
|
|
|
@ -145,6 +145,8 @@ public:
|
||||||
void UpdateIsoSrcSelection();
|
void UpdateIsoSrcSelection();
|
||||||
void RemoveCdvdMenu();
|
void RemoveCdvdMenu();
|
||||||
void EnableMenuItem( int id, bool enable );
|
void EnableMenuItem( int id, bool enable );
|
||||||
|
|
||||||
|
bool Destroy();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void DoGiveHelp(const wxString& text, bool show);
|
void DoGiveHelp(const wxString& text, bool show);
|
||||||
|
@ -166,6 +168,7 @@ protected:
|
||||||
void Menu_WindowSettings_Click(wxCommandEvent &event);
|
void Menu_WindowSettings_Click(wxCommandEvent &event);
|
||||||
void Menu_GSSettings_Click(wxCommandEvent &event);
|
void Menu_GSSettings_Click(wxCommandEvent &event);
|
||||||
void Menu_SelectPluginsBios_Click(wxCommandEvent &event);
|
void Menu_SelectPluginsBios_Click(wxCommandEvent &event);
|
||||||
|
void Menu_Language_Click(wxCommandEvent &event);
|
||||||
void Menu_ResetAllSettings_Click(wxCommandEvent &event);
|
void Menu_ResetAllSettings_Click(wxCommandEvent &event);
|
||||||
|
|
||||||
void Menu_IsoBrowse_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)
|
void MainEmuFrame::Menu_GameDatabase_Click(wxCommandEvent &event)
|
||||||
{
|
{
|
||||||
AppOpenDialog<McdConfigDialog>( this );
|
AppOpenDialog<GameDatabaseDialog>( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainEmuFrame::Menu_WindowSettings_Click(wxCommandEvent &event)
|
void MainEmuFrame::Menu_WindowSettings_Click(wxCommandEvent &event)
|
||||||
|
@ -72,6 +72,11 @@ void MainEmuFrame::Menu_SelectPluginsBios_Click(wxCommandEvent &event)
|
||||||
AppOpenDialog<ComponentsConfigDialog>( this );
|
AppOpenDialog<ComponentsConfigDialog>( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MainEmuFrame::Menu_Language_Click(wxCommandEvent &event)
|
||||||
|
{
|
||||||
|
//AppOpenDialog<LanguageSelectionDialog>( this );
|
||||||
|
LanguageSelectionDialog(this).ShowModal();
|
||||||
|
}
|
||||||
|
|
||||||
static void WipeSettings()
|
static void WipeSettings()
|
||||||
{
|
{
|
||||||
|
@ -104,7 +109,7 @@ void MainEmuFrame::Menu_ResetAllSettings_Click(wxCommandEvent &event)
|
||||||
{
|
{
|
||||||
ScopedCoreThreadPopup suspender;
|
ScopedCoreThreadPopup suspender;
|
||||||
if( !Msgbox::OkCancel( pxsFmt(
|
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"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"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?"
|
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.GetCharHeight();
|
||||||
dialog += dialog.Heading(_("Do you want to swap discs or boot the new image (via system reset)?"));
|
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 )
|
if( result == wxID_CANCEL )
|
||||||
{
|
{
|
||||||
core_control.AllowResume();
|
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)?")
|
_("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 )
|
if( result == wxID_CANCEL )
|
||||||
{
|
{
|
||||||
|
|
|
@ -74,7 +74,7 @@ protected:
|
||||||
|
|
||||||
wxString GetDisabledMessage( uint slot ) const
|
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"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.",
|
L"and re-enable the memory card at any time using Config:Memory cards from the main menu.",
|
||||||
slot
|
slot
|
||||||
|
|
|
@ -123,7 +123,7 @@ void Panels::BiosSelectorPanel::Apply()
|
||||||
{
|
{
|
||||||
throw Exception::CannotApplySettings(this)
|
throw Exception::CannotApplySettings(this)
|
||||||
.SetDiagMsg(L"User did not specify a valid BIOS selection.")
|
.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"Please select a valid BIOS. If you are unable to make a valid selection "
|
||||||
L"then press cancel to close the Configuration panel."
|
L"then press cancel to close the Configuration panel."
|
||||||
) );
|
) );
|
||||||
|
|
|
@ -109,6 +109,9 @@ namespace Panels
|
||||||
|
|
||||||
void Apply();
|
void Apply();
|
||||||
void AppStatusEvent_OnSettingsApplied();
|
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.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?" )
|
L"The specified path/directory does not exist. Would you like to create it?" )
|
||||||
);
|
);
|
||||||
|
|
||||||
wxWindowID result = pxIssueConfirmation( createPathDlg,
|
wxWindowID result = pxIssueConfirmation( createPathDlg,
|
||||||
MsgButtons().Custom(_("Create")).Cancel(),
|
MsgButtons().Custom(_("Create"), "create").Cancel(),
|
||||||
L"DirPicker:CreateOnExplore"
|
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") );
|
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. " )
|
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 += 12;
|
||||||
dialog += dialog.Heading( path );
|
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 );
|
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_VsyncEnable = new pxCheckBox( this, _("Wait for vsync on refresh") );
|
||||||
m_check_ExclusiveFS = new pxCheckBox( this, _("Use exclusive fullscreen mode (if available)") );
|
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"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."
|
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"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"the mouse as a primary control device for gaming. By default the mouse auto-hides after "
|
||||||
L"2 seconds of inactivity."
|
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"Enables automatic mode switch to fullscreen when starting or resuming emulation. "
|
||||||
L"You can still toggle fullscreen display at any time using alt-enter."
|
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"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."
|
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"Completely closes the often large and bulky GS window when pressing "
|
||||||
L"ESC or suspending the emulator."
|
L"ESC or suspending the emulator."
|
||||||
) );
|
) );
|
||||||
|
|
|
@ -18,11 +18,301 @@
|
||||||
#include "AppGameDatabase.h"
|
#include "AppGameDatabase.h"
|
||||||
#include "ConfigurationPanels.h"
|
#include "ConfigurationPanels.h"
|
||||||
|
|
||||||
|
#include <wx/listctrl.h>
|
||||||
|
|
||||||
extern wxString DiscSerial;
|
extern wxString DiscSerial;
|
||||||
|
|
||||||
using namespace pxSizerFlags;
|
using namespace pxSizerFlags;
|
||||||
|
|
||||||
#define blankLine() { \
|
|
||||||
sizer1+=5; sizer1+=5; sizer1+=Text(L""); sizer1+=5; sizer1+=5; \
|
enum GameDataColumnId
|
||||||
|
{
|
||||||
|
GdbCol_Serial = 0,
|
||||||
|
GdbCol_Title,
|
||||||
|
GdbCol_Region,
|
||||||
|
GdbCol_Compat,
|
||||||
|
GdbCol_Patches,
|
||||||
|
|
||||||
|
GdbCol_Count
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ListViewColumnInfo
|
||||||
|
{
|
||||||
|
const wxChar* name;
|
||||||
|
int width;
|
||||||
|
wxListColumnFormat align;
|
||||||
|
};
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// GameDatabaseListView
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
class GameDatabaseListView : public wxListView
|
||||||
|
{
|
||||||
|
typedef wxListView _parent;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
wxArrayString m_GamesInView;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~GameDatabaseListView() throw() { }
|
||||||
|
GameDatabaseListView( wxWindow* parent );
|
||||||
|
|
||||||
|
void CreateColumns();
|
||||||
|
GameDatabaseListView& AddGame( const wxString& serial );
|
||||||
|
GameDatabaseListView& RemoveGame( const wxString& serial );
|
||||||
|
GameDatabaseListView& ClearAllGames();
|
||||||
|
GameDatabaseListView& SortBy( GameDataColumnId column );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Overrides for wxLC_VIRTUAL
|
||||||
|
virtual wxString OnGetItemText(long item, long column) const;
|
||||||
|
virtual int OnGetItemImage(long item) const;
|
||||||
|
virtual int OnGetItemColumnImage(long item, long column) const;
|
||||||
|
virtual wxListItemAttr* OnGetItemAttr(long item) const;
|
||||||
|
|
||||||
|
const ListViewColumnInfo& GetDefaultColumnInfo( uint idx ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// GameDatabaseListView (implementations)
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
GameDatabaseListView::GameDatabaseListView( wxWindow* parent )
|
||||||
|
: _parent( parent )
|
||||||
|
{
|
||||||
|
CreateColumns();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ListViewColumnInfo& GameDatabaseListView::GetDefaultColumnInfo( uint idx ) const
|
||||||
|
{
|
||||||
|
static const ListViewColumnInfo columns[] =
|
||||||
|
{
|
||||||
|
{ L"Serial", 96, wxLIST_FORMAT_LEFT },
|
||||||
|
{ L"Title", 132, wxLIST_FORMAT_LEFT },
|
||||||
|
{ L"Region", 72, wxLIST_FORMAT_CENTER },
|
||||||
|
{ L"Compat", 48, wxLIST_FORMAT_CENTER },
|
||||||
|
{ L"Patches", 48, wxLIST_FORMAT_CENTER },
|
||||||
|
};
|
||||||
|
|
||||||
|
pxAssumeDev( idx < ArraySize(columns), "ListView column index is out of bounds." );
|
||||||
|
return columns[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameDatabaseListView::CreateColumns()
|
||||||
|
{
|
||||||
|
for( int i=0; i<GdbCol_Count; ++i )
|
||||||
|
{
|
||||||
|
const ListViewColumnInfo& info = GetDefaultColumnInfo(i);
|
||||||
|
InsertColumn( i, pxGetTranslation(info.name), info.align, info.width );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GameDatabaseListView& GameDatabaseListView::AddGame( const wxString& serial )
|
||||||
|
{
|
||||||
|
if (m_GamesInView.Index( serial, false ) != wxNOT_FOUND) return *this;
|
||||||
|
m_GamesInView.Add( serial );
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameDatabaseListView& GameDatabaseListView::RemoveGame( const wxString& serial )
|
||||||
|
{
|
||||||
|
m_GamesInView.Remove( serial );
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
GameDatabaseListView& GameDatabaseListView::ClearAllGames()
|
||||||
|
{
|
||||||
|
m_GamesInView.Clear();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class BaseGameListSort
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
IGameDatabase* m_GameDB;
|
||||||
|
bool m_descending;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BaseGameListSort( bool descend )
|
||||||
|
{
|
||||||
|
m_GameDB = AppHost_GetGameDatabase();
|
||||||
|
m_descending = descend;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~BaseGameListSort() throw() {}
|
||||||
|
|
||||||
|
// Note: Return TRUE if the first value is less than the second value.
|
||||||
|
bool operator()(const wxString& i1, const wxString& i2)
|
||||||
|
{
|
||||||
|
if (!m_GameDB || (i1 == i2)) return false;
|
||||||
|
|
||||||
|
// note: Anything not in the database gets sorted to the bottom of the list ...
|
||||||
|
Game_Data first, second;
|
||||||
|
if (!m_GameDB->findGame(first, i1)) return false;
|
||||||
|
if (!m_GameDB->findGame(second, i2)) return true;
|
||||||
|
|
||||||
|
if (int retval = _doCompare(first, second))
|
||||||
|
return m_descending ? (retval>0) : (retval<0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual int _doCompare( const Game_Data& first, const Game_Data& second )=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GLSort_bySerial : public BaseGameListSort
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GLSort_bySerial( bool descend ) : BaseGameListSort( descend ) { }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int _doCompare( const Game_Data& g1, const Game_Data& g2 )
|
||||||
|
{
|
||||||
|
return g1.getString("Serial").CmpNoCase( g2.getString("Serial") );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class GLSort_byTitle : public BaseGameListSort
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GLSort_byTitle( bool descend ) : BaseGameListSort( descend ) { }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int _doCompare( const Game_Data& g1, const Game_Data& g2 )
|
||||||
|
{
|
||||||
|
return g1.getString("Name").Cmp( g2.getString("Name") );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class GLSort_byRegion : public BaseGameListSort
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GLSort_byRegion( bool descend ) : BaseGameListSort( descend ) { }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int _doCompare( const Game_Data& g1, const Game_Data& g2 )
|
||||||
|
{
|
||||||
|
return g1.getString("Region").CmpNoCase( g2.getString("Region") );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class GLSort_byCompat : public BaseGameListSort
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GLSort_byCompat( bool descend ) : BaseGameListSort( descend ) { }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int _doCompare( const Game_Data& g1, const Game_Data& g2 )
|
||||||
|
{
|
||||||
|
return g1.getInt("Compat") - g2.getInt("Compat");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class GLSort_byPatches : public BaseGameListSort
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GLSort_byPatches( bool descend ) : BaseGameListSort( descend ) { }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int _doCompare( const Game_Data& g1, const Game_Data& g2 )
|
||||||
|
{
|
||||||
|
bool hasPatches1 = !g1.getString("[patches]").IsEmpty();
|
||||||
|
bool hasPatches2 = !g2.getString("[patches]").IsEmpty();
|
||||||
|
|
||||||
|
if (hasPatches1 == hasPatches2) return 0;
|
||||||
|
|
||||||
|
return hasPatches1 ? -1 : 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GameDatabaseListView& GameDatabaseListView::SortBy( GameDataColumnId column )
|
||||||
|
{
|
||||||
|
wxArrayString::CompareFunction cmpfunc = NULL;
|
||||||
|
|
||||||
|
const bool isDescending = false;
|
||||||
|
|
||||||
|
wxArrayString::iterator begin = m_GamesInView.begin();
|
||||||
|
wxArrayString::iterator end = m_GamesInView.end();
|
||||||
|
|
||||||
|
// Note: std::sort does not pass predicate instances by reference, which means we can't use
|
||||||
|
// object polymorphism to simplify the code below. --air
|
||||||
|
|
||||||
|
switch( column )
|
||||||
|
{
|
||||||
|
case GdbCol_Serial: std::sort(begin, end, GLSort_bySerial(isDescending)); break;
|
||||||
|
case GdbCol_Title: std::sort(begin, end, GLSort_byTitle(isDescending)); break;
|
||||||
|
case GdbCol_Region: std::sort(begin, end, GLSort_byRegion(isDescending)); break;
|
||||||
|
case GdbCol_Compat: std::sort(begin, end, GLSort_byCompat(isDescending)); break;
|
||||||
|
case GdbCol_Patches: std::sort(begin, end, GLSort_byPatches(isDescending)); break;
|
||||||
|
|
||||||
|
// do not use jNO_DEFAULT here -- keeps release builds from crashing (it'll just
|
||||||
|
// ignore the sort request!)
|
||||||
|
}
|
||||||
|
//m_GamesInView.( );
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the text for the given column of the given item
|
||||||
|
wxString GameDatabaseListView::OnGetItemText(long item, long column) const
|
||||||
|
{
|
||||||
|
IGameDatabase* GameDB = AppHost_GetGameDatabase();
|
||||||
|
|
||||||
|
if (!GameDB || (item < 0) || ((uint)item >= m_GamesInView.GetCount()))
|
||||||
|
return _parent::OnGetItemText(item, column);
|
||||||
|
|
||||||
|
Game_Data game;
|
||||||
|
if (!GameDB->findGame(game, m_GamesInView[item]))
|
||||||
|
{
|
||||||
|
pxFail( "Unknown row index in GameDatabaseListView -- returning default value." );
|
||||||
|
return _parent::OnGetItemText(item, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( column )
|
||||||
|
{
|
||||||
|
case GdbCol_Serial: return m_GamesInView[item];
|
||||||
|
case GdbCol_Title: return game.getString("Name");
|
||||||
|
case GdbCol_Region: return game.getString("Region");
|
||||||
|
case GdbCol_Compat: return game.getString("Compat");
|
||||||
|
case GdbCol_Patches: return game.getString("[patches]").IsEmpty() ? L"No" : L"Yes";
|
||||||
|
}
|
||||||
|
|
||||||
|
pxFail( "Unknown column index in GameDatabaseListView -- returning an empty string." );
|
||||||
|
return wxEmptyString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the icon for the given item. In report view, OnGetItemImage will
|
||||||
|
// only be called for the first column. See OnGetItemColumnImage for
|
||||||
|
// details.
|
||||||
|
int GameDatabaseListView::OnGetItemImage(long item) const
|
||||||
|
{
|
||||||
|
return _parent::OnGetItemImage( item );
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the icon for the given item and column.
|
||||||
|
int GameDatabaseListView::OnGetItemColumnImage(long item, long column) const
|
||||||
|
{
|
||||||
|
return _parent::OnGetItemColumnImage( item, column );
|
||||||
|
}
|
||||||
|
|
||||||
|
static wxListItemAttr m_ItemAttr;
|
||||||
|
|
||||||
|
// return the attribute for the item (may return NULL if none)
|
||||||
|
wxListItemAttr* GameDatabaseListView::OnGetItemAttr(long item) const
|
||||||
|
{
|
||||||
|
m_ItemAttr = wxListItemAttr(); // Wipe it clean!
|
||||||
|
|
||||||
|
// For eventual drag&drop ?
|
||||||
|
//if( m_TargetedItem == item )
|
||||||
|
// m_ItemAttr.SetBackgroundColour( wxColour(L"Wheat") );
|
||||||
|
|
||||||
|
return &m_ItemAttr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define blankLine() { \
|
||||||
|
sizer1+=5; sizer1+=5; sizer1+=Text(wxEmptyString); sizer1+=5; sizer1+=5; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define placeTextBox(wxBox, txt) { \
|
#define placeTextBox(wxBox, txt) { \
|
||||||
|
@ -43,9 +333,6 @@ wxTextCtrl* CreateMultiLineTextCtrl( wxWindow* parent, int digits, long flags =
|
||||||
Panels::GameDatabasePanel::GameDatabasePanel( wxWindow* parent )
|
Panels::GameDatabasePanel::GameDatabasePanel( wxWindow* parent )
|
||||||
: BaseApplicableConfigPanel( parent )
|
: BaseApplicableConfigPanel( parent )
|
||||||
{
|
{
|
||||||
IGameDatabase* GameDB = AppHost_GetGameDatabase();
|
|
||||||
pxAssume( GameDB != NULL );
|
|
||||||
|
|
||||||
searchBtn = new wxButton (this, wxID_ANY, _("Search"));
|
searchBtn = new wxButton (this, wxID_ANY, _("Search"));
|
||||||
|
|
||||||
serialBox = CreateNumericalTextCtrl(this, 40, wxTE_LEFT);
|
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 );
|
gameFixes[i] = new pxCheckBox(this, EnumToString(i), wxCHK_3STATE | wxCHK_ALLOW_3RD_STATE_FOR_USER );
|
||||||
|
|
||||||
*this += Heading(_("Game Database Editor")).Bold() | StdExpand();
|
*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));
|
wxFlexGridSizer& sizer1(*new wxFlexGridSizer(5, StdPadding));
|
||||||
sizer1.AddGrowableCol(0);
|
sizer1.AddGrowableCol(0);
|
||||||
|
|
|
@ -64,7 +64,7 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow* parent )
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
_("EE timing hack - Multi purpose hack. Try if all else fails."),
|
_("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"Known to affect following games:\n"
|
||||||
L" * Digital Devil Saga (Fixes FMV and crashes)\n"
|
L" * Digital Devil Saga (Fixes FMV and crashes)\n"
|
||||||
L" * SSX (Fixes bad graphics 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."),
|
_("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"Known to affect following games:\n"
|
||||||
L" * Bleach Blade Battler\n"
|
L" * Bleach Blade Battler\n"
|
||||||
L" * Growlanser II and III\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"),
|
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"Gamefixes can fix wrong emulation in some games. However "
|
||||||
L"it can cause compatibility or performance issues in other games. You "
|
L"it can cause compatibility or performance issues in other games. You "
|
||||||
L"will need to turn off fixes manually when changing games."
|
L"will need to turn off fixes manually when changing games."
|
||||||
|
|
|
@ -362,7 +362,7 @@ public:
|
||||||
|
|
||||||
if( dest.IsPresent && dest.IsFormatted )
|
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"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?" ),
|
L"All data on the target slot will be lost. Are you sure?" ),
|
||||||
src.Slot, dest.Slot
|
src.Slot, dest.Slot
|
||||||
|
@ -376,7 +376,7 @@ public:
|
||||||
if( !wxCopyFile( srcfile.GetFullPath(), destfile.GetFullPath(), true ) )
|
if( !wxCopyFile( srcfile.GetFullPath(), destfile.GetFullPath(), true ) )
|
||||||
{
|
{
|
||||||
wxString heading;
|
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." ),
|
L"Error! Could not copy the memory card into slot %u. The destination file is in use." ),
|
||||||
dest.Slot
|
dest.Slot
|
||||||
);
|
);
|
||||||
|
@ -582,7 +582,7 @@ void Panels::MemoryCardListPanel_Simple::OnCreateCard(wxCommandEvent& evt)
|
||||||
{
|
{
|
||||||
wxString content;
|
wxString content;
|
||||||
content.Printf(
|
content.Printf(
|
||||||
pxE( ".Popup:Mcd:Delete",
|
pxE( "!Notice:Mcd:Delete",
|
||||||
L"You are about to delete the formatted memory card in slot %u. "
|
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?"
|
L"All data on this card will be lost! Are you absolutely and quite positively sure?"
|
||||||
), slot
|
), slot
|
||||||
|
|
|
@ -20,6 +20,13 @@
|
||||||
#include <wx/dnd.h>
|
#include <wx/dnd.h>
|
||||||
#include <wx/listctrl.h>
|
#include <wx/listctrl.h>
|
||||||
|
|
||||||
|
struct ListViewColumnInfo
|
||||||
|
{
|
||||||
|
const wxChar* name;
|
||||||
|
int width;
|
||||||
|
wxListColumnFormat align;
|
||||||
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// McdListItem / IMcdList
|
// McdListItem / IMcdList
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
@ -67,13 +74,6 @@ public:
|
||||||
virtual wxDirName GetMcdPath() const=0;
|
virtual wxDirName GetMcdPath() const=0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ListViewColumnInfo
|
|
||||||
{
|
|
||||||
const wxChar* name;
|
|
||||||
int width;
|
|
||||||
wxListColumnFormat align;
|
|
||||||
};
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// BaseMcdListView
|
// BaseMcdListView
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
@ -231,6 +231,7 @@ namespace Panels
|
||||||
protected:
|
protected:
|
||||||
pxCheckBox* m_check_Multitap[2];
|
pxCheckBox* m_check_Multitap[2];
|
||||||
pxCheckBox* m_check_Ejection;
|
pxCheckBox* m_check_Ejection;
|
||||||
|
pxCheckBox* m_check_SavestateBackup;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
McdConfigPanel_Toggles( wxWindow* parent );
|
McdConfigPanel_Toggles( wxWindow* parent );
|
||||||
|
|
|
@ -32,13 +32,13 @@ using namespace pxSizerFlags;
|
||||||
Panels::DocsFolderPickerPanel::DocsFolderPickerPanel( wxWindow* parent, bool isFirstTime )
|
Panels::DocsFolderPickerPanel::DocsFolderPickerPanel( wxWindow* parent, bool isFirstTime )
|
||||||
: BaseApplicableConfigPanel( parent, wxVERTICAL, _("Usermode Selection") )
|
: 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"Please select your preferred default location for PCSX2 user-level documents below "
|
||||||
L"(includes memory cards, screenshots, settings, and savestates). "
|
L"(includes memory cards, screenshots, settings, and savestates). "
|
||||||
L"These folder locations can be overridden at any time using the Core Settings panel."
|
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"You can change the preferred default location for PCSX2 user-level documents here "
|
||||||
L"(includes memory cards, screenshots, settings, and savestates). "
|
L"(includes memory cards, screenshots, settings, and savestates). "
|
||||||
L"This option only affects Standard Paths which are set to use the installation default value."
|
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 );
|
i18n_EnumeratePackages( m_langs );
|
||||||
|
|
||||||
int size = m_langs.size();
|
int size = m_langs.size();
|
||||||
int cursel = 0;
|
ScopedArray<wxString> compiled( size );
|
||||||
ScopedArray<wxString> compiled( size ); //, L"Compiled Language Names" );
|
|
||||||
wxString configLangName( wxLocale::GetLanguageName( wxLANGUAGE_DEFAULT ) );
|
|
||||||
|
|
||||||
for( int i=0; i<size; ++i )
|
for( int i=0; i<size; ++i )
|
||||||
{
|
compiled[i].Printf( L"%s", m_langs[i].englishName.c_str() );
|
||||||
compiled[i].Printf( L"%s", m_langs[i].englishName.c_str() ); //, xltNames[i].c_str() );
|
|
||||||
if( m_langs[i].englishName == configLangName )
|
|
||||||
cursel = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_picker = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
|
m_picker = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
|
||||||
size, compiled.GetPtr(), wxCB_READONLY | wxCB_SORT );
|
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 += 5;
|
||||||
*this += m_picker | pxSizerFlags::StdSpace();
|
*this += m_picker | pxSizerFlags::StdSpace();
|
||||||
|
*this += 5;
|
||||||
|
*this += applyButton | pxSizerFlags::StdSpace();
|
||||||
|
|
||||||
m_picker->SetSelection( cursel );
|
Connect( pxID_RestartWizard, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( LanguageSelectionPanel::OnApplyLanguage_Clicked ) );
|
||||||
//AppStatusEvent_OnSettingsApplied();
|
|
||||||
|
m_picker->SetSelection( 0 ); // always default to System Default
|
||||||
|
}
|
||||||
|
|
||||||
|
void Panels::LanguageSelectionPanel::OnApplyLanguage_Clicked( wxCommandEvent& evt )
|
||||||
|
{
|
||||||
|
evt.Skip();
|
||||||
|
Apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panels::LanguageSelectionPanel::Apply()
|
void Panels::LanguageSelectionPanel::Apply()
|
||||||
|
@ -144,19 +150,39 @@ void Panels::LanguageSelectionPanel::Apply()
|
||||||
|
|
||||||
wxString sel( m_picker->GetString( m_picker->GetSelection() ) );
|
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();
|
int size = m_langs.size();
|
||||||
for( int i=0; i<size; ++i )
|
for( int i=0; i<size; ++i )
|
||||||
{
|
{
|
||||||
if( m_langs[i].englishName == sel )
|
if( m_langs[i].englishName == sel )
|
||||||
{
|
{
|
||||||
g_Conf->LanguageId = m_langs[i].wxLangId;
|
if( i18n_SetLanguage( m_langs[i].wxLangId, m_langs[i].canonicalName ) )
|
||||||
|
{
|
||||||
|
g_Conf->LanguageCode = m_langs[i].canonicalName;
|
||||||
|
g_Conf->LanguageId = m_langs[i].wxLangId;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Panels::LanguageSelectionPanel::AppStatusEvent_OnSettingsApplied()
|
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