Merge pull request #1659 from PCSX2/greg/clang-format-common

reformat main common directory
This commit is contained in:
Gregory Hainaut 2016-11-14 11:37:53 +01:00 committed by GitHub
commit 259521ec3e
137 changed files with 15017 additions and 14373 deletions

File diff suppressed because it is too large Load Diff

View File

@ -55,8 +55,7 @@ static void __forceinline PluginNullConfigure(std::wstring desc, s32 &log);
static void __forceinline PluginNullAbout(const wchar_t *aboutText); static void __forceinline PluginNullAbout(const wchar_t *aboutText);
#endif #endif
enum FileMode enum FileMode {
{
READ_FILE = 0, READ_FILE = 0,
WRITE_FILE WRITE_FILE
}; };
@ -70,9 +69,8 @@ struct PluginLog
{ {
LogFile = fopen(logname.c_str(), "w"); LogFile = fopen(logname.c_str(), "w");
if (LogFile) if (LogFile) {
{ setvbuf(LogFile, NULL, _IONBF, 0);
setvbuf(LogFile, NULL, _IONBF, 0);
return true; return true;
} }
return false; return false;
@ -90,11 +88,14 @@ struct PluginLog
{ {
va_list list; va_list list;
if (LogFile == NULL) return; if (LogFile == NULL)
return;
va_start(list, fmt); va_start(list, fmt);
if (WriteToFile) vfprintf(LogFile, fmt, list); if (WriteToFile)
if (WriteToConsole) vfprintf(stdout, fmt, list); vfprintf(LogFile, fmt, list);
if (WriteToConsole)
vfprintf(stdout, fmt, list);
va_end(list); va_end(list);
} }
@ -102,15 +103,20 @@ struct PluginLog
{ {
va_list list; va_list list;
if (LogFile == NULL) return; if (LogFile == NULL)
return;
va_start(list, fmt); va_start(list, fmt);
if (WriteToFile) vfprintf(LogFile, fmt, list); if (WriteToFile)
if (WriteToConsole) vfprintf(stdout, fmt, list); vfprintf(LogFile, fmt, list);
if (WriteToConsole)
vfprintf(stdout, fmt, list);
va_end(list); va_end(list);
if (WriteToFile) fprintf(LogFile, "\n"); if (WriteToFile)
if (WriteToConsole) fprintf(stdout, "\n"); fprintf(LogFile, "\n");
if (WriteToConsole)
fprintf(stdout, "\n");
} }
#if !defined(_MSC_VER) || !defined(UNICODE) #if !defined(_MSC_VER) || !defined(UNICODE)
@ -119,7 +125,8 @@ struct PluginLog
va_list list; va_list list;
char buf[256]; char buf[256];
if (LogFile == NULL) return; if (LogFile == NULL)
return;
va_start(list, fmt); va_start(list, fmt);
vsprintf(buf, fmt, list); vsprintf(buf, fmt, list);
@ -128,19 +135,20 @@ struct PluginLog
SysMessage(buf); SysMessage(buf);
} }
#else #else
void Message(const wchar_t *fmt, ...) void Message(const wchar_t *fmt, ...)
{ {
va_list list; va_list list;
wchar_t buf[256]; wchar_t buf[256];
if (LogFile == NULL) return; if (LogFile == NULL)
return;
va_start(list, fmt); va_start(list, fmt);
vswprintf(buf, 256, fmt, list); vswprintf(buf, 256, fmt, list);
va_end(list); va_end(list);
SysMessage(buf); SysMessage(buf);
} }
#endif #endif
}; };
@ -151,16 +159,14 @@ struct PluginConf
bool Open(std::string name, FileMode mode = READ_FILE) bool Open(std::string name, FileMode mode = READ_FILE)
{ {
if (mode == READ_FILE) if (mode == READ_FILE) {
{
ConfFile = fopen(name.c_str(), "r"); ConfFile = fopen(name.c_str(), "r");
} } else {
else
{
ConfFile = fopen(name.c_str(), "w"); ConfFile = fopen(name.c_str(), "w");
} }
if (ConfFile == NULL) return false; if (ConfFile == NULL)
return false;
return true; return true;
} }
@ -173,14 +179,14 @@ struct PluginConf
} }
} }
int ReadInt(const std::string& item, int defval) int ReadInt(const std::string &item, int defval)
{ {
int value = defval; int value = defval;
std::string buf = item + " = %d\n"; std::string buf = item + " = %d\n";
if (ConfFile) if (ConfFile)
if (fscanf(ConfFile, buf.c_str(), &value) < 0) if (fscanf(ConfFile, buf.c_str(), &value) < 0)
fprintf(stderr, "Error reading %s\n", item.c_str()); fprintf(stderr, "Error reading %s\n", item.c_str());
return value; return value;
} }
@ -189,7 +195,8 @@ struct PluginConf
{ {
std::string buf = item + " = %d\n"; std::string buf = item + " = %d\n";
if (ConfFile) fprintf(ConfFile, buf.c_str(), value); if (ConfFile)
fprintf(ConfFile, buf.c_str(), value);
} }
}; };
@ -204,19 +211,20 @@ static void SysMessage(const char *fmt, ...)
vsprintf(msg, fmt, list); vsprintf(msg, fmt, list);
va_end(list); va_end(list);
if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0; if (msg[strlen(msg) - 1] == '\n')
msg[strlen(msg) - 1] = 0;
GtkWidget *dialog; GtkWidget *dialog;
dialog = gtk_message_dialog_new (NULL, dialog = gtk_message_dialog_new(NULL,
GTK_DIALOG_DESTROY_WITH_PARENT, GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO, GTK_MESSAGE_INFO,
GTK_BUTTONS_OK, GTK_BUTTONS_OK,
"%s", msg); "%s", msg);
gtk_dialog_run (GTK_DIALOG (dialog)); gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy (dialog); gtk_widget_destroy(dialog);
} }
static void __forceinline set_logging(GtkToggleButton *check, int& log) static void __forceinline set_logging(GtkToggleButton *check, int &log)
{ {
log = gtk_toggle_button_get_active(check); log = gtk_toggle_button_get_active(check);
} }
@ -227,7 +235,7 @@ static void __forceinline PluginNullConfigure(std::string desc, int &log)
/* Create the widgets */ /* Create the widgets */
dialog = gtk_dialog_new(); dialog = gtk_dialog_new();
label = gtk_label_new (desc.c_str()); label = gtk_label_new(desc.c_str());
check_box = gtk_check_button_new_with_label("Logging"); check_box = gtk_check_button_new_with_label("Logging");
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_box), (log != 0)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_box), (log != 0));
@ -236,14 +244,14 @@ static void __forceinline PluginNullConfigure(std::string desc, int &log)
g_signal_connect(check_box, "toggled", G_CALLBACK(set_logging), &log); g_signal_connect(check_box, "toggled", G_CALLBACK(set_logging), &log);
/* Add all our widgets, and show everything we've added to the dialog. */ /* Add all our widgets, and show everything we've added to the dialog. */
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area(GTK_DIALOG(dialog))), label); gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), label);
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area(GTK_DIALOG(dialog))), check_box); gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), check_box);
gtk_dialog_add_button(GTK_DIALOG(dialog), "Ok", 0); gtk_dialog_add_button(GTK_DIALOG(dialog), "Ok", 0);
gtk_widget_show_all (dialog); gtk_widget_show_all(dialog);
gtk_dialog_run (GTK_DIALOG (dialog)); gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy (dialog); gtk_widget_destroy(dialog);
} }
static void __forceinline PluginNullAbout(const char *aboutText) static void __forceinline PluginNullAbout(const char *aboutText)
@ -265,7 +273,8 @@ static void SysMessage(const char *fmt, ...)
vsprintf(msg, fmt, list); vsprintf(msg, fmt, list);
va_end(list); va_end(list);
if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0; if (msg[strlen(msg) - 1] == '\n')
msg[strlen(msg) - 1] = 0;
// TODO OSX can we use WX MessageBox here or should Cocoa MessageBox used? // TODO OSX can we use WX MessageBox here or should Cocoa MessageBox used?
} }
@ -297,7 +306,7 @@ static void __forceinline PluginNullAbout(const char *aboutText)
#else #else
#define usleep(x) Sleep(x / 1000) #define usleep(x) Sleep(x / 1000)
#ifndef UNICODE #ifndef UNICODE
@ -305,15 +314,15 @@ static void __forceinline SysMessage(const char *fmt, ...)
{ {
va_list list; va_list list;
char tmp[512]; char tmp[512];
va_start(list,fmt); va_start(list, fmt);
vsprintf(tmp,fmt,list); vsprintf(tmp, fmt, list);
va_end(list); va_end(list);
MessageBox( GetActiveWindow(), tmp, "Message", MB_SETFOREGROUND | MB_OK ); MessageBox(GetActiveWindow(), tmp, "Message", MB_SETFOREGROUND | MB_OK);
} }
static void __forceinline PluginNullConfigure(std::string desc, s32 &log) static void __forceinline PluginNullConfigure(std::string desc, s32 &log)
{ {
/* To do: Write a dialog box that displays a dialog box with the text in desc, /* To do: Write a dialog box that displays a dialog box with the text in desc,
and a check box that says "Logging", checked if log !=0, and set log to and a check box that says "Logging", checked if log !=0, and set log to
1 if it is checked on return, and 0 if it isn't. */ 1 if it is checked on return, and 0 if it isn't. */
SysMessage("This space is intentionally left blank."); SysMessage("This space is intentionally left blank.");
@ -327,39 +336,39 @@ static void __forceinline PluginNullAbout(const char *aboutText)
static void __forceinline SysMessage(const wchar_t *fmt, ...) static void __forceinline SysMessage(const wchar_t *fmt, ...)
{ {
va_list list; va_list list;
wchar_t tmp[512]; wchar_t tmp[512];
va_start(list, fmt); va_start(list, fmt);
vswprintf(tmp, 512, fmt, list); vswprintf(tmp, 512, fmt, list);
va_end(list); va_end(list);
MessageBox(GetActiveWindow(), tmp, L"Message", MB_SETFOREGROUND | MB_OK); MessageBox(GetActiveWindow(), tmp, L"Message", MB_SETFOREGROUND | MB_OK);
} }
static void __forceinline PluginNullConfigure(std::string desc, s32 &log) static void __forceinline PluginNullConfigure(std::string desc, s32 &log)
{ {
/* To do: Write a dialog box that displays a dialog box with the text in desc, /* To do: Write a dialog box that displays a dialog box with the text in desc,
and a check box that says "Logging", checked if log !=0, and set log to and a check box that says "Logging", checked if log !=0, and set log to
1 if it is checked on return, and 0 if it isn't. */ 1 if it is checked on return, and 0 if it isn't. */
SysMessage(L"This space is intentionally left blank."); SysMessage(L"This space is intentionally left blank.");
} }
static void __forceinline PluginNullAbout(const wchar_t *aboutText) static void __forceinline PluginNullAbout(const wchar_t *aboutText)
{ {
SysMessage(aboutText); SysMessage(aboutText);
} }
#endif #endif
#define ENTRY_POINT \ #define ENTRY_POINT \
HINSTANCE hInst; \ HINSTANCE hInst; \
\ \
BOOL APIENTRY DllMain(HANDLE hModule, /* DLL INIT*/ \ BOOL APIENTRY DllMain(HANDLE hModule, /* DLL INIT*/ \
DWORD dwReason, \ DWORD dwReason, \
LPVOID lpReserved) \ LPVOID lpReserved) \
{ \ { \
hInst = (HINSTANCE)hModule; \ hInst = (HINSTANCE)hModule; \
return TRUE; /* very quick :)*/ \ return TRUE; /* very quick :)*/ \
} }
#endif #endif
#endif // PS2EEXT_H_INCLUDED #endif // PS2EEXT_H_INCLUDED

View File

@ -13,7 +13,7 @@
* If not, see <http://www.gnu.org/licenses/>. * If not, see <http://www.gnu.org/licenses/>.
*/ */
// This file is just for backwards compatibility. // This file is just for backwards compatibility.
#ifndef __PS2ETYPES_H__ #ifndef __PS2ETYPES_H__
#define __PS2ETYPES_H__ #define __PS2ETYPES_H__

View File

@ -35,64 +35,71 @@
#ifdef _MSC_VER #ifdef _MSC_VER
#define EXPORT_C(type) extern "C" type CALLBACK #define EXPORT_C(type) extern "C" type CALLBACK
#else #else
#define EXPORT_C(type) extern "C" __attribute__((externally_visible,visibility("default"))) type #define EXPORT_C(type) extern "C" __attribute__((externally_visible, visibility("default"))) type
#endif #endif
EXPORT_C(u32) PS2EgetLibType(void); EXPORT_C(u32)
EXPORT_C(u32) PS2EgetLibVersion2(u32 type); PS2EgetLibType(void);
EXPORT_C(char*) PS2EgetLibName(void); EXPORT_C(u32)
PS2EgetLibVersion2(u32 type);
EXPORT_C(char *)
PS2EgetLibName(void);
// Extended functions. // Extended functions.
// allows the plugin to see the whole configuration when started up. // allows the plugin to see the whole configuration when started up.
// Intended for them to get the ini and plugin paths, but could allow for other things as well. // Intended for them to get the ini and plugin paths, but could allow for other things as well.
EXPORT_C_(void) PS2EpassConfig(PcsxConfig Config); EXPORT_C_(void)
PS2EpassConfig(PcsxConfig Config);
// Alternately, this function serves the same purpose, but would work for emulators outside // Alternately, this function serves the same purpose, but would work for emulators outside
// of pcsx2. // of pcsx2.
EXPORT_C_(void) PS2EpassIniPath(const char *path); EXPORT_C_(void)
PS2EpassIniPath(const char *path);
// PS2EgetLibType returns (may be OR'd) // PS2EgetLibType returns (may be OR'd)
enum { enum {
PS2E_LT_GS = 0x01, PS2E_LT_GS = 0x01,
PS2E_LT_PAD = 0x02, // -=[ OBSOLETE ]=- PS2E_LT_PAD = 0x02, // -=[ OBSOLETE ]=-
PS2E_LT_SPU2 = 0x04, PS2E_LT_SPU2 = 0x04,
PS2E_LT_CDVD = 0x08, PS2E_LT_CDVD = 0x08,
PS2E_LT_DEV9 = 0x10, PS2E_LT_DEV9 = 0x10,
PS2E_LT_USB = 0x20, PS2E_LT_USB = 0x20,
PS2E_LT_FW = 0x40, PS2E_LT_FW = 0x40,
PS2E_LT_SIO = 0x80 PS2E_LT_SIO = 0x80
} PluginLibType; } PluginLibType;
// PS2EgetLibVersion2 (high 16 bits) // PS2EgetLibVersion2 (high 16 bits)
enum { enum {
PS2E_GS_VERSION = 0x0006, PS2E_GS_VERSION = 0x0006,
PS2E_PAD_VERSION = 0x0002, // -=[ OBSOLETE ]=- PS2E_PAD_VERSION = 0x0002, // -=[ OBSOLETE ]=-
PS2E_SPU2_VERSION = 0x0005, PS2E_SPU2_VERSION = 0x0005,
PS2E_CDVD_VERSION = 0x0005, PS2E_CDVD_VERSION = 0x0005,
PS2E_DEV9_VERSION = 0x0003, PS2E_DEV9_VERSION = 0x0003,
PS2E_USB_VERSION = 0x0003, PS2E_USB_VERSION = 0x0003,
PS2E_FW_VERSION = 0x0002, PS2E_FW_VERSION = 0x0002,
PS2E_SIO_VERSION = 0x0001 PS2E_SIO_VERSION = 0x0001
} PluginLibVersion; } PluginLibVersion;
// freeze modes: // freeze modes:
enum { enum {
FREEZE_LOAD = 0, FREEZE_LOAD = 0,
FREEZE_SAVE = 1, FREEZE_SAVE = 1,
FREEZE_SIZE = 2 FREEZE_SIZE = 2
} FreezeModes; } FreezeModes;
typedef struct _GSdriverInfo { typedef struct _GSdriverInfo
char name[8]; {
void *common; char name[8];
void *common;
} GSdriverInfo; } GSdriverInfo;
#ifdef _MSC_VER #ifdef _MSC_VER
typedef struct _winInfo { // unsupported values must be set to zero typedef struct _winInfo
HWND hWnd; { // unsupported values must be set to zero
HMENU hMenu; HWND hWnd;
HWND hStatusWnd; HMENU hMenu;
HWND hStatusWnd;
} winInfo; } winInfo;
#endif #endif

View File

@ -26,9 +26,9 @@
// make sure __POSIX__ is defined for all systems where we assume POSIX // make sure __POSIX__ is defined for all systems where we assume POSIX
// compliance // compliance
#if defined(__linux__) || defined(__APPLE__) || defined(__unix__) || defined(__CYGWIN__) || defined(__LINUX__) #if defined(__linux__) || defined(__APPLE__) || defined(__unix__) || defined(__CYGWIN__) || defined(__LINUX__)
# if !defined(__POSIX__) #if !defined(__POSIX__)
# define __POSIX__ 1 #define __POSIX__ 1
# endif #endif
#endif #endif
#include "Pcsx2Types.h" #include "Pcsx2Types.h"
@ -39,7 +39,7 @@
// Notes: I'd have used ARRAY_SIZE instead but ran into cross-platform lib conflicts with // Notes: I'd have used ARRAY_SIZE instead but ran into cross-platform lib conflicts with
// that as well. >_< // that as well. >_<
#ifndef ArraySize #ifndef ArraySize
# define ArraySize(x) (sizeof(x)/sizeof((x)[0])) #define ArraySize(x) (sizeof(x) / sizeof((x)[0]))
#endif #endif
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -51,51 +51,51 @@
// some tight loops it will likely make debug builds unusably slow. // some tight loops it will likely make debug builds unusably slow.
// //
#ifdef __cplusplus #ifdef __cplusplus
# ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
static const bool IsDevBuild = true; static const bool IsDevBuild = true;
# else
static const bool IsDevBuild = false;
# endif
# ifdef PCSX2_DEBUG
static const bool IsDebugBuild = true;
# else
static const bool IsDebugBuild = false;
# endif
#else #else
static const bool IsDevBuild = false;
# ifdef PCSX2_DEVBUILD
static const u8 IsDevBuild = 1;
# else
static const u8 IsDevBuild = 0;
# endif
# ifdef PCSX2_DEBUG
static const u8 IsDebugBuild = 1;
# else
static const u8 IsDebugBuild = 0;
# endif
#endif #endif
#ifdef PCSX2_DEBUG #ifdef PCSX2_DEBUG
# define pxDebugCode(code) code static const bool IsDebugBuild = true;
#else #else
# define pxDebugCode(code) static const bool IsDebugBuild = false;
#endif
#else
#ifdef PCSX2_DEVBUILD
static const u8 IsDevBuild = 1;
#else
static const u8 IsDevBuild = 0;
#endif
#ifdef PCSX2_DEBUG
static const u8 IsDebugBuild = 1;
#else
static const u8 IsDebugBuild = 0;
#endif
#endif
#ifdef PCSX2_DEBUG
#define pxDebugCode(code) code
#else
#define pxDebugCode(code)
#endif #endif
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
# define pxDevelCode(code) code #define pxDevelCode(code) code
#else #else
# define pxDevelCode(code) #define pxDevelCode(code)
#endif #endif
#if defined(PCSX2_DEBUG) || defined(PCSX2_DEVBUILD) #if defined(PCSX2_DEBUG) || defined(PCSX2_DEVBUILD)
# define pxReleaseCode(code) #define pxReleaseCode(code)
# define pxNonReleaseCode(code) code #define pxNonReleaseCode(code) code
#else #else
# define pxReleaseCode(code) code #define pxReleaseCode(code) code
# define pxNonReleaseCode(code) #define pxNonReleaseCode(code)
#endif #endif
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -116,8 +116,8 @@
// Defines the memory page size for the target platform at compilation. All supported platforms // Defines the memory page size for the target platform at compilation. All supported platforms
// (which means Intel only right now) have a 4k granularity. // (which means Intel only right now) have a 4k granularity.
#define PCSX2_PAGESIZE 0x1000 #define PCSX2_PAGESIZE 0x1000
static const int __pagesize = PCSX2_PAGESIZE; static const int __pagesize = PCSX2_PAGESIZE;
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Structure Packing (__packed) // Structure Packing (__packed)
@ -154,27 +154,27 @@ static const int __pagesize = PCSX2_PAGESIZE;
// This is the 2005/earlier compatible packing define, which must be used in conjunction // This is the 2005/earlier compatible packing define, which must be used in conjunction
// with #ifdef _MSC_VER/#pragma pack() directives (ugly). // with #ifdef _MSC_VER/#pragma pack() directives (ugly).
# define __packed #define __packed
# define __aligned(alig) __declspec(align(alig)) #define __aligned(alig) __declspec(align(alig))
# define __aligned16 __declspec(align(16)) #define __aligned16 __declspec(align(16))
# define __aligned32 __declspec(align(32)) #define __aligned32 __declspec(align(32))
# define __pagealigned __declspec(align(PCSX2_PAGESIZE)) #define __pagealigned __declspec(align(PCSX2_PAGESIZE))
// Deprecated; use __align instead. // Deprecated; use __align instead.
# define PCSX2_ALIGNED(alig,x) __declspec(align(alig)) x #define PCSX2_ALIGNED(alig, x) __declspec(align(alig)) x
# define PCSX2_ALIGNED_EXTERN(alig,x) extern __declspec(align(alig)) x #define PCSX2_ALIGNED_EXTERN(alig, x) extern __declspec(align(alig)) x
# define PCSX2_ALIGNED16(x) __declspec(align(16)) x #define PCSX2_ALIGNED16(x) __declspec(align(16)) x
# define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x #define PCSX2_ALIGNED16_EXTERN(x) extern __declspec(align(16)) x
# define __noinline __declspec(noinline) #define __noinline __declspec(noinline)
# define __threadlocal __declspec(thread) #define __threadlocal __declspec(thread)
// Don't know if there are Visual C++ equivalents of these. // Don't know if there are Visual C++ equivalents of these.
# define likely(x) (!!(x)) #define likely(x) (!!(x))
# define unlikely(x) (!!(x)) #define unlikely(x) (!!(x))
# define CALLBACK __stdcall #define CALLBACK __stdcall
#else #else
@ -183,42 +183,42 @@ static const int __pagesize = PCSX2_PAGESIZE;
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
#ifndef __packed #ifndef __packed
# define __packed __attribute__((packed)) #define __packed __attribute__((packed))
#endif #endif
#ifndef __aligned #ifndef __aligned
# define __aligned(alig) __attribute__((aligned(alig))) #define __aligned(alig) __attribute__((aligned(alig)))
#endif #endif
# define __aligned16 __attribute__((aligned(16))) #define __aligned16 __attribute__((aligned(16)))
# define __aligned32 __attribute__((aligned(32))) #define __aligned32 __attribute__((aligned(32)))
# define __pagealigned __attribute__((aligned(PCSX2_PAGESIZE))) #define __pagealigned __attribute__((aligned(PCSX2_PAGESIZE)))
// Deprecated; use __align instead. // Deprecated; use __align instead.
# define PCSX2_ALIGNED(alig,x) x __attribute((aligned(alig))) #define PCSX2_ALIGNED(alig, x) x __attribute((aligned(alig)))
# define PCSX2_ALIGNED16(x) x __attribute((aligned(16))) #define PCSX2_ALIGNED16(x) x __attribute((aligned(16)))
# define PCSX2_ALIGNED_EXTERN(alig,x) extern x __attribute((aligned(alig))) #define PCSX2_ALIGNED_EXTERN(alig, x) extern x __attribute((aligned(alig)))
# define PCSX2_ALIGNED16_EXTERN(x) extern x __attribute((aligned(16))) #define PCSX2_ALIGNED16_EXTERN(x) extern x __attribute((aligned(16)))
# define __assume(cond) ((void)0) // GCC has no equivalent for __assume #define __assume(cond) ((void)0) // GCC has no equivalent for __assume
# define CALLBACK __attribute__((stdcall)) #define CALLBACK __attribute__((stdcall))
// Inlining note: GCC needs ((unused)) attributes defined on inlined functions to suppress // Inlining note: GCC needs ((unused)) attributes defined on inlined functions to suppress
// warnings when a static inlined function isn't used in the scope of a single file (which // warnings when a static inlined function isn't used in the scope of a single file (which
// happens *by design* like all the friggen time >_<) // happens *by design* like all the friggen time >_<)
#ifndef __fastcall #ifndef __fastcall
# define __fastcall __attribute__((fastcall)) #define __fastcall __attribute__((fastcall))
#endif
#define _inline __inline__ __attribute__((unused))
#ifdef NDEBUG
#define __forceinline __attribute__((always_inline, unused))
#else
#define __forceinline __attribute__((unused))
#endif #endif
# define _inline __inline__ __attribute__((unused))
# ifdef NDEBUG
# define __forceinline __attribute__((always_inline,unused))
# else
# define __forceinline __attribute__((unused))
# endif
#ifndef __noinline #ifndef __noinline
# define __noinline __attribute__((noinline)) #define __noinline __attribute__((noinline))
#endif #endif
# define __threadlocal __thread #define __threadlocal __thread
# define likely(x) __builtin_expect(!!(x), 1) #define likely(x) __builtin_expect(!!(x), 1)
# define unlikely(x) __builtin_expect(!!(x), 0) #define unlikely(x) __builtin_expect(!!(x), 0)
#endif #endif
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -233,13 +233,13 @@ static const int __pagesize = PCSX2_PAGESIZE;
// environment. // environment.
// //
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
# define __releaseinline #define __releaseinline
#else #else
# define __releaseinline __forceinline #define __releaseinline __forceinline
#endif #endif
#define __ri __releaseinline #define __ri __releaseinline
#define __fi __forceinline #define __fi __forceinline
#define __fc __fastcall #define __fc __fastcall
#endif #endif

View File

@ -24,9 +24,9 @@
// depend on these types will not be usable (they will yield linker errors). // depend on these types will not be usable (they will yield linker errors).
#ifdef __cplusplus #ifdef __cplusplus
class wxString; class wxString;
class FastFormatAscii; class FastFormatAscii;
class FastFormatUnicode; class FastFormatUnicode;
#endif #endif
@ -65,116 +65,116 @@ typedef unsigned int uint;
#ifdef __cplusplus #ifdef __cplusplus
union u128 union u128
{ {
struct struct
{ {
u64 lo; u64 lo;
u64 hi; u64 hi;
}; };
u64 _u64[2]; u64 _u64[2];
u32 _u32[4]; u32 _u32[4];
u16 _u16[8]; u16 _u16[8];
u8 _u8[16]; u8 _u8[16];
// Explicit conversion from u64. Zero-extends the source through 128 bits. // Explicit conversion from u64. Zero-extends the source through 128 bits.
static u128 From64( u64 src ) static u128 From64(u64 src)
{ {
u128 retval; u128 retval;
retval.lo = src; retval.lo = src;
retval.hi = 0; retval.hi = 0;
return retval; return retval;
} }
// Explicit conversion from u32. Zero-extends the source through 128 bits. // Explicit conversion from u32. Zero-extends the source through 128 bits.
static u128 From32( u32 src ) static u128 From32(u32 src)
{ {
u128 retval; u128 retval;
retval._u32[0] = src; retval._u32[0] = src;
retval._u32[1] = 0; retval._u32[1] = 0;
retval.hi = 0; retval.hi = 0;
return retval; return retval;
} }
operator u32() const { return _u32[0]; } operator u32() const { return _u32[0]; }
operator u16() const { return _u16[0]; } operator u16() const { return _u16[0]; }
operator u8() const { return _u8[0]; } operator u8() const { return _u8[0]; }
bool operator==( const u128& right ) const
{
return (lo == right.lo) && (hi == right.hi);
}
bool operator!=( const u128& right ) const bool operator==(const u128 &right) const
{ {
return (lo != right.lo) || (hi != right.hi); return (lo == right.lo) && (hi == right.hi);
} }
// In order for the following ToString() and WriteTo methods to be available, you must bool operator!=(const u128 &right) const
// be linking to both wxWidgets and the pxWidgets extension library. If you are not {
// using them, then you will need to provide your own implementations of these methods. return (lo != right.lo) || (hi != right.hi);
wxString ToString() const; }
wxString ToString64() const;
wxString ToString8() const; // In order for the following ToString() and WriteTo methods to be available, you must
// be linking to both wxWidgets and the pxWidgets extension library. If you are not
void WriteTo( FastFormatAscii& dest ) const; // using them, then you will need to provide your own implementations of these methods.
void WriteTo8( FastFormatAscii& dest ) const; wxString ToString() const;
void WriteTo64( FastFormatAscii& dest ) const; wxString ToString64() const;
wxString ToString8() const;
void WriteTo(FastFormatAscii &dest) const;
void WriteTo8(FastFormatAscii &dest) const;
void WriteTo64(FastFormatAscii &dest) const;
}; };
struct s128 struct s128
{ {
s64 lo; s64 lo;
s64 hi; s64 hi;
// explicit conversion from s64, with sign extension. // explicit conversion from s64, with sign extension.
static s128 From64( s64 src ) static s128 From64(s64 src)
{ {
s128 retval = { src, (src < 0) ? -1 : 0 }; s128 retval = {src, (src < 0) ? -1 : 0};
return retval; return retval;
} }
// explicit conversion from s32, with sign extension. // explicit conversion from s32, with sign extension.
static s128 From64( s32 src ) static s128 From64(s32 src)
{ {
s128 retval = { src, (src < 0) ? -1 : 0 }; s128 retval = {src, (src < 0) ? -1 : 0};
return retval; return retval;
} }
operator u32() const { return (s32)lo; } operator u32() const { return (s32)lo; }
operator u16() const { return (s16)lo; } operator u16() const { return (s16)lo; }
operator u8() const { return (s8)lo; } operator u8() const { return (s8)lo; }
bool operator==( const s128& right ) const bool operator==(const s128 &right) const
{ {
return (lo == right.lo) && (hi == right.hi); return (lo == right.lo) && (hi == right.hi);
} }
bool operator!=( const s128& right ) const bool operator!=(const s128 &right) const
{ {
return (lo != right.lo) || (hi != right.hi); return (lo != right.lo) || (hi != right.hi);
} }
}; };
#else #else
typedef union _u128_t typedef union _u128_t
{ {
struct struct
{ {
u64 lo; u64 lo;
u64 hi; u64 hi;
}; };
u64 _u64[2]; u64 _u64[2];
u32 _u32[4]; u32 _u32[4];
u16 _u16[8]; u16 _u16[8];
u8 _u8[16]; u8 _u8[16];
} u128; } u128;
typedef union _s128_t typedef union _s128_t
{ {
u64 lo; u64 lo;
s64 hi; s64 hi;
} s128; } s128;
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -27,14 +27,13 @@
// //
class Pcsx2AppTraits : public wxGUIAppTraits class Pcsx2AppTraits : public wxGUIAppTraits
{ {
typedef wxGUIAppTraits _parent; typedef wxGUIAppTraits _parent;
public: public:
virtual ~Pcsx2AppTraits() {} virtual ~Pcsx2AppTraits() {}
wxMessageOutput* CreateMessageOutput(); wxMessageOutput *CreateMessageOutput();
#ifdef wxUSE_STDPATHS #ifdef wxUSE_STDPATHS
wxStandardPaths& GetStandardPaths(); wxStandardPaths &GetStandardPaths();
#endif #endif
}; };

View File

@ -17,14 +17,14 @@
#ifndef __pxFUNCTION__ #ifndef __pxFUNCTION__
#if defined(__GNUG__) #if defined(__GNUG__)
# define __pxFUNCTION__ __PRETTY_FUNCTION__ #define __pxFUNCTION__ __PRETTY_FUNCTION__
#else #else
# define __pxFUNCTION__ __FUNCTION__ #define __pxFUNCTION__ __FUNCTION__
#endif #endif
#endif #endif
#ifndef wxNullChar #ifndef wxNullChar
# define wxNullChar ((wxChar*)NULL) #define wxNullChar ((wxChar *)NULL)
#endif #endif
// FnChar_t - function name char type; typedef'd in case it ever changes between compilers // FnChar_t - function name char type; typedef'd in case it ever changes between compilers
@ -36,29 +36,29 @@ typedef char FnChar_t;
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct DiagnosticOrigin struct DiagnosticOrigin
{ {
const wxChar* srcfile; const wxChar *srcfile;
const FnChar_t* function; const FnChar_t *function;
const wxChar* condition; const wxChar *condition;
int line; int line;
DiagnosticOrigin( const wxChar *_file, int _line, const FnChar_t *_func, const wxChar* _cond = NULL ) DiagnosticOrigin(const wxChar *_file, int _line, const FnChar_t *_func, const wxChar *_cond = NULL)
: srcfile( _file ) : srcfile(_file)
, function( _func ) , function(_func)
, condition( _cond ) , condition(_cond)
, line( _line ) , line(_line)
{ {
} }
wxString ToString( const wxChar* msg=NULL ) const; wxString ToString(const wxChar *msg = NULL) const;
}; };
// Returns ture if the assertion is to trap into the debugger, or false if execution // Returns ture if the assertion is to trap into the debugger, or false if execution
// of the program should continue unimpeded. // of the program should continue unimpeded.
typedef bool pxDoAssertFnType(const DiagnosticOrigin& origin, const wxChar *msg); typedef bool pxDoAssertFnType(const DiagnosticOrigin &origin, const wxChar *msg);
extern pxDoAssertFnType pxAssertImpl_LogIt; extern pxDoAssertFnType pxAssertImpl_LogIt;
extern pxDoAssertFnType* pxDoAssert; extern pxDoAssertFnType *pxDoAssert;
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// pxAssert / pxAssertDev // pxAssert / pxAssertDev
@ -97,95 +97,99 @@ extern pxDoAssertFnType* pxDoAssert;
// it can lead to the compiler optimizing out code and leading to crashes in dev/release // it can lead to the compiler optimizing out code and leading to crashes in dev/release
// builds. To have code optimized, explicitly use pxAssume(false) or pxAssumeDev(false,msg); // builds. To have code optimized, explicitly use pxAssume(false) or pxAssumeDev(false,msg);
#define pxDiagSpot DiagnosticOrigin( __TFILE__, __LINE__, __pxFUNCTION__ ) #define pxDiagSpot DiagnosticOrigin(__TFILE__, __LINE__, __pxFUNCTION__)
#define pxAssertSpot(cond) DiagnosticOrigin( __TFILE__, __LINE__, __pxFUNCTION__, _T(#cond) ) #define pxAssertSpot(cond) DiagnosticOrigin(__TFILE__, __LINE__, __pxFUNCTION__, _T(#cond))
// pxAssertRel -> // pxAssertRel ->
// Special release-mode assertion. Limited use since stack traces in release mode builds // Special release-mode assertion. Limited use since stack traces in release mode builds
// (especially with LTCG) are highly suspect. But when troubleshooting crashes that only // (especially with LTCG) are highly suspect. But when troubleshooting crashes that only
// rear ugly heads in optimized builds, this is one of the few tools we have. // rear ugly heads in optimized builds, this is one of the few tools we have.
#define pxAssertRel(cond, msg) ( (likely(cond)) || (pxOnAssert(pxAssertSpot(cond), msg), false) ) #define pxAssertRel(cond, msg) ((likely(cond)) || (pxOnAssert(pxAssertSpot(cond), msg), false))
#define pxAssumeRel(cond, msg) ((void) ( (!likely(cond)) && (pxOnAssert(pxAssertSpot(cond), msg), false) )) #define pxAssumeRel(cond, msg) ((void)((!likely(cond)) && (pxOnAssert(pxAssertSpot(cond), msg), false)))
#define pxFailRel(msg) pxAssertRel(false, msg) #define pxFailRel(msg) pxAssertRel(false, msg)
#if defined(PCSX2_DEBUG) #if defined(PCSX2_DEBUG)
# define pxAssertMsg(cond, msg) pxAssertRel(cond, msg) #define pxAssertMsg(cond, msg) pxAssertRel(cond, msg)
# define pxAssertDev(cond, msg) pxAssertMsg(cond, msg) #define pxAssertDev(cond, msg) pxAssertMsg(cond, msg)
# define pxAssumeMsg(cond, msg) pxAssumeRel(cond, msg) #define pxAssumeMsg(cond, msg) pxAssumeRel(cond, msg)
# define pxAssumeDev(cond, msg) pxAssumeRel(cond, msg) #define pxAssumeDev(cond, msg) pxAssumeRel(cond, msg)
# define pxFail(msg) pxAssertMsg(false, msg) #define pxFail(msg) pxAssertMsg(false, msg)
# define pxFailDev(msg) pxAssertDev(false, msg) #define pxFailDev(msg) pxAssertDev(false, msg)
#elif defined(PCSX2_DEVBUILD) #elif defined(PCSX2_DEVBUILD)
// Devel builds now will give you a release-mode assertion dialog window if any of the // Devel builds now will give you a release-mode assertion dialog window if any of the
// following macro's 'cond' field is false. // following macro's 'cond' field is false.
// Note: Only use pxAssume/Msg/Dev if you know what you're doing, __assume is supposed // Note: Only use pxAssume/Msg/Dev if you know what you're doing, __assume is supposed
// to be used as an optimization hint, yet many devs have been using psAssume // to be used as an optimization hint, yet many devs have been using psAssume
// thinking its the same as an assertion. // thinking its the same as an assertion.
// __assume(0) is also very dangerous because it is a special case of __assume() which // __assume(0) is also very dangerous because it is a special case of __assume() which
// tells the compiler that the code path is not reachable, and it can cause unpredictable // tells the compiler that the code path is not reachable, and it can cause unpredictable
// results if the code path can be reached. // results if the code path can be reached.
// i.e. if (1) { __assume(0); something(); } // i.e. if (1) { __assume(0); something(); }
// In the above example, something() may never be called. // In the above example, something() may never be called.
// __assume(0)'s real use is in optimizing stuff such as "default:" cases on a switch // __assume(0)'s real use is in optimizing stuff such as "default:" cases on a switch
// statement. See jNO_DEFAULT // statement. See jNO_DEFAULT
# define pxAssertMsg(cond, msg) pxAssertRel(cond, msg) #define pxAssertMsg(cond, msg) pxAssertRel(cond, msg)
# define pxAssertDev(cond, msg) pxAssertRel(cond, msg) #define pxAssertDev(cond, msg) pxAssertRel(cond, msg)
# define pxAssumeMsg(cond, msg) pxAssumeRel(cond, msg) //(__assume(cond)) #define pxAssumeMsg(cond, msg) pxAssumeRel(cond, msg) //(__assume(cond))
# define pxAssumeDev(cond, msg) pxAssumeRel(cond, msg) #define pxAssumeDev(cond, msg) pxAssumeRel(cond, msg)
# define pxFail(msg) pxAssertDev(false, msg) #define pxFail(msg) pxAssertDev(false, msg)
# define pxFailDev(msg) pxAssertDev(false, msg) #define pxFailDev(msg) pxAssertDev(false, msg)
#else #else
// Release Builds just use __assume as an optimization, and return the conditional // Release Builds just use __assume as an optimization, and return the conditional
// as a result (which is optimized to nil if unused). // as a result (which is optimized to nil if unused).
# define pxAssertMsg(cond, msg) (likely(cond)) #define pxAssertMsg(cond, msg) (likely(cond))
# define pxAssertDev(cond, msg) (likely(cond)) #define pxAssertDev(cond, msg) (likely(cond))
# define pxAssumeMsg(cond, msg) (__assume(cond)) #define pxAssumeMsg(cond, msg) (__assume(cond))
# define pxAssumeDev(cond, msg) (__assume(cond)) #define pxAssumeDev(cond, msg) (__assume(cond))
# define pxFail(msg) do{} while(0) #define pxFail(msg) \
# define pxFailDev(msg) do{} while(0) do { \
} while (0)
#define pxFailDev(msg) \
do { \
} while (0)
#endif #endif
#define pxAssert(cond) pxAssertMsg(cond, wxNullChar) #define pxAssert(cond) pxAssertMsg(cond, wxNullChar)
#define pxAssume(cond) pxAssumeMsg(cond, wxNullChar) #define pxAssume(cond) pxAssumeMsg(cond, wxNullChar)
#define pxAssertRelease( cond, msg ) #define pxAssertRelease(cond, msg)
// Performs an unsigned index bounds check, and generates a debug assertion if the check fails. // Performs an unsigned index bounds check, and generates a debug assertion if the check fails.
// For stricter checking in Devel builds as well as debug builds (but possibly slower), use // For stricter checking in Devel builds as well as debug builds (but possibly slower), use
// IndexBoundsCheckDev. // IndexBoundsCheckDev.
#define IndexBoundsCheck( objname, idx, sze ) pxAssertMsg( (uint)(idx) < (uint)(sze), \ #define IndexBoundsCheck(objname, idx, sze) pxAssertMsg((uint)(idx) < (uint)(sze), \
pxsFmt( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) ) pxsFmt(L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze)))
#define IndexBoundsCheckDev( objname, idx, sze ) pxAssertDev( (uint)(idx) < (uint)(sze), \ #define IndexBoundsCheckDev(objname, idx, sze) pxAssertDev((uint)(idx) < (uint)(sze), \
pxsFmt( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) ) pxsFmt(L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze)))
#define IndexBoundsAssume( objname, idx, sze ) pxAssumeMsg( (uint)(idx) < (uint)(sze), \ #define IndexBoundsAssume(objname, idx, sze) pxAssumeMsg((uint)(idx) < (uint)(sze), \
pxsFmt( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) ) pxsFmt(L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze)))
#define IndexBoundsAssumeDev( objname, idx, sze ) pxAssumeDev( (uint)(idx) < (uint)(sze), \ #define IndexBoundsAssumeDev(objname, idx, sze) pxAssumeDev((uint)(idx) < (uint)(sze), \
pxsFmt( L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze) ) ) pxsFmt(L"Array index out of bounds accessing object '%s' (index=%d, size=%d)", objname, (idx), (sze)))
extern void pxOnAssert( const DiagnosticOrigin& origin, const wxChar* msg=NULL ); extern void pxOnAssert(const DiagnosticOrigin &origin, const wxChar *msg = NULL);
extern void pxOnAssert( const DiagnosticOrigin& origin, const char* msg ); extern void pxOnAssert(const DiagnosticOrigin &origin, const char *msg);
extern void pxOnAssert( const DiagnosticOrigin& origin, const wxString& msg); extern void pxOnAssert(const DiagnosticOrigin &origin, const wxString &msg);
extern void pxOnAssert( const DiagnosticOrigin& origin, const FastFormatUnicode& msg); extern void pxOnAssert(const DiagnosticOrigin &origin, const FastFormatUnicode &msg);
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// jNO_DEFAULT -- disables the default case in a switch, which improves switch optimization // jNO_DEFAULT -- disables the default case in a switch, which improves switch optimization
@ -198,10 +202,9 @@ extern void pxOnAssert( const DiagnosticOrigin& origin, const FastFormatUnicode&
// * In debug/devel builds the default case will cause an assertion. // * In debug/devel builds the default case will cause an assertion.
// //
#ifndef jNO_DEFAULT #ifndef jNO_DEFAULT
# define jNO_DEFAULT \ #define jNO_DEFAULT \
default: \ default: { \
{ \ pxAssumeDev(0, "Incorrect usage of jNO_DEFAULT detected (default case is not unreachable!)"); \
pxAssumeDev( 0, "Incorrect usage of jNO_DEFAULT detected (default case is not unreachable!)" ); \ break; \
break; \ }
}
#endif #endif

View File

@ -19,19 +19,19 @@
class CheckedStaticBox : public wxPanelWithHelpers class CheckedStaticBox : public wxPanelWithHelpers
{ {
typedef wxPanelWithHelpers _parent; typedef wxPanelWithHelpers _parent;
public: public:
wxBoxSizer& ThisSizer; // Boxsizer which holds all child items. wxBoxSizer &ThisSizer; // Boxsizer which holds all child items.
wxCheckBox& ThisToggle; // toggle which can enable/disable all child controls wxCheckBox &ThisToggle; // toggle which can enable/disable all child controls
public: public:
CheckedStaticBox( wxWindow* parent, int orientation, const wxString& title=wxEmptyString ); CheckedStaticBox(wxWindow *parent, int orientation, const wxString &title = wxEmptyString);
void SetValue(bool val);
bool GetValue() const;
bool Enable(bool enable = true);
void SetValue( bool val );
bool GetValue() const;
bool Enable( bool enable = true );
public: public:
virtual void MainToggle_Click( wxCommandEvent& evt ); virtual void MainToggle_Click(wxCommandEvent &evt);
}; };

View File

@ -17,46 +17,45 @@
#include "StringHelpers.h" #include "StringHelpers.h"
enum ConsoleColors enum ConsoleColors {
{ Color_Current = -1,
Color_Current = -1,
Color_Default = 0, Color_Default = 0,
Color_Black, Color_Black,
Color_Green, Color_Green,
Color_Red, Color_Red,
Color_Blue, Color_Blue,
Color_Magenta, Color_Magenta,
Color_Orange, Color_Orange,
Color_Gray, Color_Gray,
Color_Cyan, // faint visibility, intended for logging PS2/IOP output Color_Cyan, // faint visibility, intended for logging PS2/IOP output
Color_Yellow, // faint visibility, intended for logging PS2/IOP output Color_Yellow, // faint visibility, intended for logging PS2/IOP output
Color_White, // faint visibility, intended for logging PS2/IOP output Color_White, // faint visibility, intended for logging PS2/IOP output
// Strong text *may* result in mis-aligned text in the console, depending on the // Strong text *may* result in mis-aligned text in the console, depending on the
// font and the platform, so use these with caution. // font and the platform, so use these with caution.
Color_StrongBlack, Color_StrongBlack,
Color_StrongRed, // intended for errors Color_StrongRed, // intended for errors
Color_StrongGreen, // intended for infrequent state information Color_StrongGreen, // intended for infrequent state information
Color_StrongBlue, // intended for block headings Color_StrongBlue, // intended for block headings
Color_StrongMagenta, Color_StrongMagenta,
Color_StrongOrange, // intended for warnings Color_StrongOrange, // intended for warnings
Color_StrongGray, Color_StrongGray,
Color_StrongCyan, Color_StrongCyan,
Color_StrongYellow, Color_StrongYellow,
Color_StrongWhite, Color_StrongWhite,
ConsoleColors_Count ConsoleColors_Count
}; };
static const ConsoleColors DefaultConsoleColor = Color_Default; static const ConsoleColors DefaultConsoleColor = Color_Default;
// Use fastcall for the console; should be helpful in most cases // Use fastcall for the console; should be helpful in most cases
#define __concall __fastcall #define __concall __fastcall
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
// IConsoleWriter -- For printing messages to the console. // IConsoleWriter -- For printing messages to the console.
@ -71,60 +70,60 @@ static const ConsoleColors DefaultConsoleColor = Color_Default;
// //
struct IConsoleWriter struct IConsoleWriter
{ {
// A direct console write, without tabbing or newlines. Useful to devs who want to do quick // A direct console write, without tabbing or newlines. Useful to devs who want to do quick
// logging of various junk; but should *not* be used in production code due. // logging of various junk; but should *not* be used in production code due.
void (__concall *WriteRaw)( const wxString& fmt ); void(__concall *WriteRaw)(const wxString &fmt);
// WriteLn implementation for internal use only. Bypasses tabbing, prefixing, and other // WriteLn implementation for internal use only. Bypasses tabbing, prefixing, and other
// formatting. // formatting.
void (__concall *DoWriteLn)( const wxString& fmt ); void(__concall *DoWriteLn)(const wxString &fmt);
// SetColor implementation for internal use only. // SetColor implementation for internal use only.
void (__concall *DoSetColor)( ConsoleColors color ); void(__concall *DoSetColor)(ConsoleColors color);
// Special implementation of DoWrite that's pretty much for MSVC use only. // Special implementation of DoWrite that's pretty much for MSVC use only.
// All implementations should map to DoWrite, except Stdio which should map to Null. // All implementations should map to DoWrite, except Stdio which should map to Null.
// (This avoids circular/recursive stdio output) // (This avoids circular/recursive stdio output)
void (__concall *DoWriteFromStdout)( const wxString& fmt ); void(__concall *DoWriteFromStdout)(const wxString &fmt);
void (__concall *Newline)(); void(__concall *Newline)();
void (__concall *SetTitle)( const wxString& title ); void(__concall *SetTitle)(const wxString &title);
// internal value for indentation of individual lines. Use the Indent() member to invoke. // internal value for indentation of individual lines. Use the Indent() member to invoke.
int _imm_indentation; int _imm_indentation;
// For internal use only. // For internal use only.
wxString _addIndentation( const wxString& src, int glob_indent ) const; wxString _addIndentation(const wxString &src, int glob_indent) const;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Public members; call these to print stuff to console! // Public members; call these to print stuff to console!
// //
// All functions always return false. Return value is provided only so that we can easily // All functions always return false. Return value is provided only so that we can easily
// disable logs at compile time using the "0&&action" macro trick. // disable logs at compile time using the "0&&action" macro trick.
ConsoleColors GetColor() const; ConsoleColors GetColor() const;
const IConsoleWriter& SetColor( ConsoleColors color ) const; const IConsoleWriter &SetColor(ConsoleColors color) const;
const IConsoleWriter& ClearColor() const; const IConsoleWriter &ClearColor() const;
const IConsoleWriter& SetIndent( int tabcount=1 ) const; const IConsoleWriter &SetIndent(int tabcount = 1) const;
IConsoleWriter Indent( int tabcount=1 ) const; IConsoleWriter Indent(int tabcount = 1) const;
bool FormatV( const char* fmt, va_list args ) const; bool FormatV(const char *fmt, va_list args) const;
bool WriteLn( ConsoleColors color, const char* fmt, ... ) const; bool WriteLn(ConsoleColors color, const char *fmt, ...) const;
bool WriteLn( const char* fmt, ... ) const; bool WriteLn(const char *fmt, ...) const;
bool Error( const char* fmt, ... ) const; bool Error(const char *fmt, ...) const;
bool Warning( const char* fmt, ... ) const; bool Warning(const char *fmt, ...) const;
bool FormatV( const wxChar* fmt, va_list args ) const; bool FormatV(const wxChar *fmt, va_list args) const;
bool WriteLn( ConsoleColors color, const wxChar* fmt, ... ) const; bool WriteLn(ConsoleColors color, const wxChar *fmt, ...) const;
bool WriteLn( const wxChar* fmt, ... ) const; bool WriteLn(const wxChar *fmt, ...) const;
bool Error( const wxChar* fmt, ... ) const; bool Error(const wxChar *fmt, ...) const;
bool Warning( const wxChar* fmt, ... ) const; bool Warning(const wxChar *fmt, ...) const;
bool WriteLn( ConsoleColors color, const wxString fmt, ... ) const; bool WriteLn(ConsoleColors color, const wxString fmt, ...) const;
bool WriteLn( const wxString fmt, ... ) const; bool WriteLn(const wxString fmt, ...) const;
bool Error( const wxString fmt, ... ) const; bool Error(const wxString fmt, ...) const;
bool Warning( const wxString fmt, ... ) const; bool Warning(const wxString fmt, ...) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -134,37 +133,37 @@ struct IConsoleWriter
// //
struct NullConsoleWriter struct NullConsoleWriter
{ {
void WriteRaw( const wxString& fmt ) {} void WriteRaw(const wxString &fmt) {}
void DoWriteLn( const wxString& fmt ) {} void DoWriteLn(const wxString &fmt) {}
void DoSetColor( ConsoleColors color ) {} void DoSetColor(ConsoleColors color) {}
void DoWriteFromStdout( const wxString& fmt ) {} void DoWriteFromStdout(const wxString &fmt) {}
void Newline() {} void Newline() {}
void SetTitle( const wxString& title ) {} void SetTitle(const wxString &title) {}
ConsoleColors GetColor() const { return Color_Current; } ConsoleColors GetColor() const { return Color_Current; }
const NullConsoleWriter& SetColor( ConsoleColors color ) const { return *this; } const NullConsoleWriter &SetColor(ConsoleColors color) const { return *this; }
const NullConsoleWriter& ClearColor() const { return *this; } const NullConsoleWriter &ClearColor() const { return *this; }
const NullConsoleWriter& SetIndent( int tabcount=1 ) const { return *this; } const NullConsoleWriter &SetIndent(int tabcount = 1) const { return *this; }
NullConsoleWriter Indent( int tabcount=1 ) const { return NullConsoleWriter(); } NullConsoleWriter Indent(int tabcount = 1) const { return NullConsoleWriter(); }
bool FormatV( const char* fmt, va_list args ) const { return false; } bool FormatV(const char *fmt, va_list args) const { return false; }
bool WriteLn( ConsoleColors color, const char* fmt, ... ) const { return false; } bool WriteLn(ConsoleColors color, const char *fmt, ...) const { return false; }
bool WriteLn( const char* fmt, ... ) const { return false; } bool WriteLn(const char *fmt, ...) const { return false; }
bool Error( const char* fmt, ... ) const { return false; } bool Error(const char *fmt, ...) const { return false; }
bool Warning( const char* fmt, ... ) const { return false; } bool Warning(const char *fmt, ...) const { return false; }
bool FormatV( const wxChar* fmt, va_list args ) const { return false; } bool FormatV(const wxChar *fmt, va_list args) const { return false; }
bool WriteLn( ConsoleColors color, const wxChar* fmt, ... ) const { return false; } bool WriteLn(ConsoleColors color, const wxChar *fmt, ...) const { return false; }
bool WriteLn( const wxChar* fmt, ... ) const { return false; } bool WriteLn(const wxChar *fmt, ...) const { return false; }
bool Error( const wxChar* fmt, ... ) const { return false; } bool Error(const wxChar *fmt, ...) const { return false; }
bool Warning( const wxChar* fmt, ... ) const { return false; } bool Warning(const wxChar *fmt, ...) const { return false; }
bool WriteLn( ConsoleColors color, const wxString fmt, ... ) const { return false; } bool WriteLn(ConsoleColors color, const wxString fmt, ...) const { return false; }
bool WriteLn( const wxString fmt, ... ) const { return false; } bool WriteLn(const wxString fmt, ...) const { return false; }
bool Error( const wxString fmt, ... ) const { return false; } bool Error(const wxString fmt, ...) const { return false; }
bool Warning( const wxString fmt, ... ) const { return false; } bool Warning(const wxString fmt, ...) const { return false; }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -180,19 +179,19 @@ struct NullConsoleWriter
// //
class ConsoleIndentScope class ConsoleIndentScope
{ {
DeclareNoncopyableObject( ConsoleIndentScope ); DeclareNoncopyableObject(ConsoleIndentScope);
protected: protected:
int m_amount; int m_amount;
bool m_IsScoped; bool m_IsScoped;
public: public:
// Constructor: The specified number of tabs will be appended to the current indentation // Constructor: The specified number of tabs will be appended to the current indentation
// setting. The tabs will be unrolled when the object leaves scope or is destroyed. // setting. The tabs will be unrolled when the object leaves scope or is destroyed.
ConsoleIndentScope( int tabs=1 ); ConsoleIndentScope(int tabs = 1);
virtual ~ConsoleIndentScope() throw(); virtual ~ConsoleIndentScope() throw();
void EnterScope(); void EnterScope();
void LeaveScope(); void LeaveScope();
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -200,18 +199,18 @@ public:
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class ConsoleColorScope class ConsoleColorScope
{ {
DeclareNoncopyableObject( ConsoleColorScope ); DeclareNoncopyableObject(ConsoleColorScope);
protected: protected:
ConsoleColors m_newcolor; ConsoleColors m_newcolor;
ConsoleColors m_old_color; ConsoleColors m_old_color;
bool m_IsScoped; bool m_IsScoped;
public: public:
ConsoleColorScope( ConsoleColors newcolor ); ConsoleColorScope(ConsoleColors newcolor);
virtual ~ConsoleColorScope() throw(); virtual ~ConsoleColorScope() throw();
void EnterScope(); void EnterScope();
void LeaveScope(); void LeaveScope();
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -221,42 +220,42 @@ public:
// //
class ConsoleAttrScope class ConsoleAttrScope
{ {
DeclareNoncopyableObject( ConsoleAttrScope ); DeclareNoncopyableObject(ConsoleAttrScope);
protected: protected:
ConsoleColors m_old_color; ConsoleColors m_old_color;
int m_tabsize; int m_tabsize;
public: public:
ConsoleAttrScope( ConsoleColors newcolor, int indent=0 ); ConsoleAttrScope(ConsoleColors newcolor, int indent = 0);
virtual ~ConsoleAttrScope() throw(); virtual ~ConsoleAttrScope() throw();
}; };
extern IConsoleWriter Console; extern IConsoleWriter Console;
#if defined(__unix__) #if defined(__unix__)
extern void Console_SetStdout(FILE *fp); extern void Console_SetStdout(FILE *fp);
#endif #endif
extern void Console_SetActiveHandler( const IConsoleWriter& writer, FILE* flushfp=NULL ); extern void Console_SetActiveHandler(const IConsoleWriter &writer, FILE *flushfp = NULL);
extern const IConsoleWriter ConsoleWriter_Null; extern const IConsoleWriter ConsoleWriter_Null;
extern const IConsoleWriter ConsoleWriter_Stdout; extern const IConsoleWriter ConsoleWriter_Stdout;
extern const IConsoleWriter ConsoleWriter_Assert; extern const IConsoleWriter ConsoleWriter_Assert;
extern NullConsoleWriter NullCon; extern NullConsoleWriter NullCon;
extern IConsoleWriter DevConWriter; extern IConsoleWriter DevConWriter;
extern bool DevConWriterEnabled; extern bool DevConWriterEnabled;
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
# define DevCon DevConWriter #define DevCon DevConWriter
#else #else
# define DevCon DevConWriterEnabled && DevConWriter #define DevCon DevConWriterEnabled &&DevConWriter
#endif #endif
#ifdef PCSX2_DEBUG #ifdef PCSX2_DEBUG
extern IConsoleWriter DbgConWriter; extern IConsoleWriter DbgConWriter;
# define DbgCon DbgConWriter #define DbgCon DbgConWriter
#else #else
# define DbgCon 0&&NullCon #define DbgCon 0 && NullCon
#endif #endif

View File

@ -24,19 +24,19 @@
#define wxsFormat wxString::Format #define wxsFormat wxString::Format
#ifdef PCSX2_DEBUG #ifdef PCSX2_DEBUG
# define tryDEBUG try #define tryDEBUG try
# define catchDEBUG(clause) catch(clause) #define catchDEBUG(clause) catch (clause)
#else #else
# define tryDEBUG if(true) #define tryDEBUG if (true)
# define catchDEBUG(clause) if(false) #define catchDEBUG(clause) if (false)
#endif #endif
#if defined(PCSX2_DEVBUILD) || defined(PCSX2_DEBUG) #if defined(PCSX2_DEVBUILD) || defined(PCSX2_DEBUG)
# define tryDEVEL try #define tryDEVEL try
# define catchDEVEL catch(clause) #define catchDEVEL catch (clause)
#else #else
# define tryDEBUG if(true) #define tryDEBUG if (true)
# define catchDEBUG(clause) if(false) #define catchDEBUG(clause) if (false)
#endif #endif
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -61,24 +61,48 @@
// method is not implemented! You must implement it yourself if you want to use it: // method is not implemented! You must implement it yourself if you want to use it:
// EnumToString(value); // EnumToString(value);
// //
#define ImplementEnumOperators( enumName ) \ #define ImplementEnumOperators(enumName) \
static __fi enumName& operator++ ( enumName& src ) { src = (enumName)((int)src+1); return src; } \ static __fi enumName &operator++(enumName &src) \
static __fi enumName& operator-- ( enumName& src ) { src = (enumName)((int)src-1); return src; } \ { \
static __fi enumName operator++ ( enumName& src, int ) { enumName orig = src; src = (enumName)((int)src+1); return orig; } \ src = (enumName)((int)src + 1); \
static __fi enumName operator-- ( enumName& src, int ) { enumName orig = src; src = (enumName)((int)src-1); return orig; } \ return src; \
\ } \
static __fi bool operator< ( const enumName& left, const pxEnumEnd_t& ) { return (int)left < enumName##_COUNT; } \ static __fi enumName &operator--(enumName &src) \
static __fi bool operator!=( const enumName& left, const pxEnumEnd_t& ) { return (int)left != enumName##_COUNT; } \ { \
static __fi bool operator==( const enumName& left, const pxEnumEnd_t& ) { return (int)left == enumName##_COUNT; } \ src = (enumName)((int)src - 1); \
\ return src; \
static __fi bool EnumIsValid( enumName id ) { \ } \
return ((int)id >= enumName##_FIRST) && ((int)id < enumName##_COUNT); } \ static __fi enumName operator++(enumName &src, int) \
static __fi void EnumAssert( enumName id ) { \ { \
pxAssert( EnumIsValid(id) ); } \ enumName orig = src; \
\ src = (enumName)((int)src + 1); \
extern const wxChar* EnumToString( enumName id ) return orig; \
} \
static __fi enumName operator--(enumName &src, int) \
{ \
enumName orig = src; \
src = (enumName)((int)src - 1); \
return orig; \
} \
\
static __fi bool operator<(const enumName &left, const pxEnumEnd_t &) { return (int)left < enumName##_COUNT; } \
static __fi bool operator!=(const enumName &left, const pxEnumEnd_t &) { return (int)left != enumName##_COUNT; } \
static __fi bool operator==(const enumName &left, const pxEnumEnd_t &) { return (int)left == enumName##_COUNT; } \
\
static __fi bool EnumIsValid(enumName id) \
{ \
return ((int)id >= enumName##_FIRST) && ((int)id < enumName##_COUNT); \
} \
static __fi void EnumAssert(enumName id) \
{ \
pxAssert(EnumIsValid(id)); \
} \
\
extern const wxChar *EnumToString(enumName id)
class pxEnumEnd_t { }; class pxEnumEnd_t
{
};
static const pxEnumEnd_t pxEnumEnd = {}; static const pxEnumEnd_t pxEnumEnd = {};
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -105,10 +129,10 @@ static const pxEnumEnd_t pxEnumEnd = {};
// of wx dependencies though, and has a nicer typeset. :) // of wx dependencies though, and has a nicer typeset. :)
// //
#ifndef DeclareNoncopyableObject #ifndef DeclareNoncopyableObject
# define DeclareNoncopyableObject(classname) \ #define DeclareNoncopyableObject(classname) \
private: \ private: \
explicit classname(const classname&); \ explicit classname(const classname &); \
classname& operator=(const classname&) classname &operator=(const classname &)
#endif #endif
@ -120,19 +144,19 @@ static const pxEnumEnd_t pxEnumEnd = {};
class ScopedBool class ScopedBool
{ {
protected: protected:
bool* m_boolme; bool *m_boolme;
public: public:
ScopedBool(bool& boolme) ScopedBool(bool &boolme)
{ {
boolme = true; boolme = true;
m_boolme = &boolme; m_boolme = &boolme;
} }
~ScopedBool() throw() ~ScopedBool() throw()
{ {
*m_boolme = false; *m_boolme = false;
} }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -149,15 +173,15 @@ public:
#define WXINTL_NO_GETTEXT_MACRO #define WXINTL_NO_GETTEXT_MACRO
#ifndef _ #ifndef _
# define _(s) pxGetTranslation(_T(s)) #define _(s) pxGetTranslation(_T(s))
#endif #endif
#ifndef _t #ifndef _t
# define _t(s) pxGetTranslation(_T(s)) #define _t(s) pxGetTranslation(_T(s))
#endif #endif
#ifndef _d #ifndef _d
# define _d(s) pxGetTranslation(_T(s)) #define _d(s) pxGetTranslation(_T(s))
#endif #endif
// pxL / pxLt / pxDt -- macros provided for tagging translation strings, without actually running // pxL / pxLt / pxDt -- macros provided for tagging translation strings, without actually running
@ -167,15 +191,15 @@ public:
// debug/devel specific translations. // debug/devel specific translations.
// //
#ifndef pxL #ifndef pxL
# define pxL(a) wxT(a) #define pxL(a) wxT(a)
#endif #endif
#ifndef pxLt #ifndef pxLt
# define pxLt(a) wxT(a) #define pxLt(a) wxT(a)
#endif #endif
#ifndef pxDt #ifndef pxDt
# define pxDt(a) wxT(a) #define pxDt(a) wxT(a)
#endif #endif
@ -193,8 +217,8 @@ public:
#endif #endif
#include <stdexcept> #include <stdexcept>
#include <cstring> // string.h under c++ #include <cstring> // string.h under c++
#include <cstdio> // stdio.h under c++ #include <cstdio> // stdio.h under c++
#include <cstdlib> #include <cstdlib>
#include <vector> #include <vector>
#include <list> #include <list>
@ -207,42 +231,42 @@ public:
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Handy Human-readable constants for common immediate values (_16kb -> _4gb) // Handy Human-readable constants for common immediate values (_16kb -> _4gb)
static const sptr _1kb = 1024 * 1; static const sptr _1kb = 1024 * 1;
static const sptr _4kb = _1kb * 4; static const sptr _4kb = _1kb * 4;
static const sptr _16kb = _1kb * 16; static const sptr _16kb = _1kb * 16;
static const sptr _32kb = _1kb * 32; static const sptr _32kb = _1kb * 32;
static const sptr _64kb = _1kb * 64; static const sptr _64kb = _1kb * 64;
static const sptr _128kb = _1kb * 128; static const sptr _128kb = _1kb * 128;
static const sptr _256kb = _1kb * 256; static const sptr _256kb = _1kb * 256;
static const s64 _1mb = 1024 * 1024; static const s64 _1mb = 1024 * 1024;
static const s64 _8mb = _1mb * 8; static const s64 _8mb = _1mb * 8;
static const s64 _16mb = _1mb * 16; static const s64 _16mb = _1mb * 16;
static const s64 _32mb = _1mb * 32; static const s64 _32mb = _1mb * 32;
static const s64 _64mb = _1mb * 64; static const s64 _64mb = _1mb * 64;
static const s64 _256mb = _1mb * 256; static const s64 _256mb = _1mb * 256;
static const s64 _1gb = _1mb * 1024; static const s64 _1gb = _1mb * 1024;
static const s64 _4gb = _1gb * 4; static const s64 _4gb = _1gb * 4;
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// pxE(msg) and pxEt(msg) [macros] => now same as _/_t/_d // pxE(msg) and pxEt(msg) [macros] => now same as _/_t/_d
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
#define pxE(english) pxExpandMsg( (english) ) #define pxE(english) pxExpandMsg((english))
// For use with tertiary translations (low priority). // For use with tertiary translations (low priority).
#define pxEt(english) pxExpandMsg( (english) ) #define pxEt(english) pxExpandMsg((english))
// For use with Dev/debug build translations (low priority). // For use with Dev/debug build translations (low priority).
#define pxE_dev(english) pxExpandMsg( (english) ) #define pxE_dev(english) pxExpandMsg((english))
extern const wxChar* __fastcall pxExpandMsg( const wxChar* englishContent ); extern const wxChar *__fastcall pxExpandMsg(const wxChar *englishContent);
extern const wxChar* __fastcall pxGetTranslation( const wxChar* message ); extern const wxChar *__fastcall pxGetTranslation(const wxChar *message);
extern bool pxIsEnglish( int id ); extern bool pxIsEnglish(int id);
extern wxString fromUTF8( const char* src ); extern wxString fromUTF8(const char *src);
extern wxString fromAscii( const char* src ); extern wxString fromAscii(const char *src);
#include "Utilities/Assertions.h" #include "Utilities/Assertions.h"

View File

@ -25,8 +25,8 @@
class IEmbeddedImage class IEmbeddedImage
{ {
public: public:
virtual const wxImage& Get()=0; virtual const wxImage &Get() = 0;
virtual wxImage Scale( int width, int height )=0; virtual wxImage Scale(int width, int height) = 0;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -38,85 +38,83 @@ public:
// Note: Get() only loads the image once. All subsequent calls to Get will use the // Note: Get() only loads the image once. All subsequent calls to Get will use the
// previously loaded image data. // previously loaded image data.
// //
template< typename ImageType > template <typename ImageType>
class EmbeddedImage : public IEmbeddedImage class EmbeddedImage : public IEmbeddedImage
{ {
protected: protected:
wxImage m_Image; wxImage m_Image;
const wxSize m_ResampleTo; const wxSize m_ResampleTo;
protected: protected:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Internal function used to ensure the image is loaded before returning the image // Internal function used to ensure the image is loaded before returning the image
// handle (called from all methods that return an image handle). // handle (called from all methods that return an image handle).
// //
void _loadImage() void _loadImage()
{ {
if( !m_Image.Ok() ) if (!m_Image.Ok()) {
{ wxMemoryInputStream joe(ImageType::Data, ImageType::Length);
wxMemoryInputStream joe( ImageType::Data, ImageType::Length ); m_Image.LoadFile(joe, ImageType::GetFormat());
m_Image.LoadFile( joe, ImageType::GetFormat() );
if( m_ResampleTo.IsFullySpecified() && ( m_ResampleTo.GetWidth() != m_Image.GetWidth() || m_ResampleTo.GetHeight() != m_Image.GetHeight() ) ) if (m_ResampleTo.IsFullySpecified() && (m_ResampleTo.GetWidth() != m_Image.GetWidth() || m_ResampleTo.GetHeight() != m_Image.GetHeight()))
m_Image.Rescale( m_ResampleTo.GetWidth(), m_ResampleTo.GetHeight(), wxIMAGE_QUALITY_HIGH ); m_Image.Rescale(m_ResampleTo.GetWidth(), m_ResampleTo.GetHeight(), wxIMAGE_QUALITY_HIGH);
} }
} }
public: public:
EmbeddedImage() : EmbeddedImage()
m_Image() : m_Image()
, m_ResampleTo( wxDefaultSize ) , m_ResampleTo(wxDefaultSize)
{ {
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Constructor for creating an embedded image that gets resampled to the specified size when // Constructor for creating an embedded image that gets resampled to the specified size when
// loaded. // loaded.
// //
// Implementation Note: This function uses wxWidgets ResamplBox method to resize the image. // Implementation Note: This function uses wxWidgets ResamplBox method to resize the image.
// wxWidgets ResampleBicubic appears to be buggy and produces fairly poor results when down- // wxWidgets ResampleBicubic appears to be buggy and produces fairly poor results when down-
// sampling images (basically resembles a pixel resize). ResampleBox produces much cleaner // sampling images (basically resembles a pixel resize). ResampleBox produces much cleaner
// results. // results.
// //
EmbeddedImage( int newWidth, int newHeight ) : EmbeddedImage(int newWidth, int newHeight)
m_Image() : m_Image()
, m_ResampleTo( newWidth, newHeight ) , m_ResampleTo(newWidth, newHeight)
{ {
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Loads and retrieves the embedded image. The embedded image is only loaded from its em- // Loads and retrieves the embedded image. The embedded image is only loaded from its em-
// bedded format once. Any subsequent calls to Get(), Rescale(), or Resample() will use // bedded format once. Any subsequent calls to Get(), Rescale(), or Resample() will use
// the pre-loaded copy. Translation: the png/jpeg decoding overhead happens only once, // the pre-loaded copy. Translation: the png/jpeg decoding overhead happens only once,
// and only happens when the image is actually fetched. Simply creating an instance // and only happens when the image is actually fetched. Simply creating an instance
// of an EmbeddedImage object uses no excess memory nor cpu overhead. :) // of an EmbeddedImage object uses no excess memory nor cpu overhead. :)
// //
const wxImage& Get() const wxImage &Get()
{ {
_loadImage(); _loadImage();
return m_Image; return m_Image;
} }
wxIcon GetIcon() wxIcon GetIcon()
{ {
wxIcon retval; wxIcon retval;
retval.CopyFromBitmap( Get() ); retval.CopyFromBitmap(Get());
return retval; return retval;
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Performs a pixel resize of the loaded image and returns a new image handle (EmbeddedImage // Performs a pixel resize of the loaded image and returns a new image handle (EmbeddedImage
// is left unmodified). // is left unmodified).
// //
wxImage Scale( int width, int height ) wxImage Scale(int width, int height)
{ {
_loadImage(); _loadImage();
// Not strictly necessary - wxWidgets does the dimensions check anyway. // Not strictly necessary - wxWidgets does the dimensions check anyway.
if( width != m_Image.GetWidth() || height != m_Image.GetHeight() ) if (width != m_Image.GetWidth() || height != m_Image.GetHeight())
return m_Image.Scale( width, height, wxIMAGE_QUALITY_HIGH ); return m_Image.Scale(width, height, wxIMAGE_QUALITY_HIGH);
else else
return m_Image; return m_Image;
} }
}; };

View File

@ -22,56 +22,58 @@
// EventSource< template EvtType > // EventSource< template EvtType >
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
template< typename ListenerType > template <typename ListenerType>
class EventSource class EventSource
{ {
public: public:
typedef typename ListenerType::EvtParams EvtParams; typedef typename ListenerType::EvtParams EvtParams;
typedef typename std::list< ListenerType* > ListenerList; typedef typename std::list<ListenerType *> ListenerList;
typedef typename ListenerList::iterator ListenerIterator; typedef typename ListenerList::iterator ListenerIterator;
protected: protected:
typedef typename ListenerList::const_iterator ConstIterator; typedef typename ListenerList::const_iterator ConstIterator;
ListenerList m_listeners; ListenerList m_listeners;
// This is a cached copy of the listener list used to handle standard dispatching, which // This is a cached copy of the listener list used to handle standard dispatching, which
// allows for self-modification of the EventSource's listener list by the listeners. // allows for self-modification of the EventSource's listener list by the listeners.
// Translation: The dispatcher uses this copy instead, to avoid iterator invalidation. // Translation: The dispatcher uses this copy instead, to avoid iterator invalidation.
ListenerList m_cache_copy; ListenerList m_cache_copy;
bool m_cache_valid; bool m_cache_valid;
Threading::Mutex m_listeners_lock; Threading::Mutex m_listeners_lock;
public: public:
EventSource() EventSource()
{ {
m_cache_valid = false; m_cache_valid = false;
} }
virtual ~EventSource() throw() {} virtual ~EventSource() throw() {}
virtual ListenerIterator Add( ListenerType& listener ); virtual ListenerIterator Add(ListenerType &listener);
virtual void Remove( ListenerType& listener ); virtual void Remove(ListenerType &listener);
virtual void Remove( const ListenerIterator& listenerHandle ); virtual void Remove(const ListenerIterator &listenerHandle);
void Add( ListenerType* listener ) void Add(ListenerType *listener)
{ {
if( listener == NULL ) return; if (listener == NULL)
Add( *listener ); return;
} Add(*listener);
}
void Remove( ListenerType* listener ) void Remove(ListenerType *listener)
{ {
if( listener == NULL ) return; if (listener == NULL)
Remove( *listener ); return;
} Remove(*listener);
}
void Dispatch( const EvtParams& params ); void Dispatch(const EvtParams &params);
protected: protected:
virtual ListenerIterator _AddFast_without_lock( ListenerType& listener ); virtual ListenerIterator _AddFast_without_lock(ListenerType &listener);
virtual void _DispatchRaw( ListenerIterator iter, const ListenerIterator& iend, const EvtParams& params ); virtual void _DispatchRaw(ListenerIterator iter, const ListenerIterator &iend, const EvtParams &params);
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -80,13 +82,13 @@ protected:
// This class is used as a base interface for EventListeners. It allows the listeners to do // This class is used as a base interface for EventListeners. It allows the listeners to do
// customized dispatching of several event types into "user friendly" function overrides. // customized dispatching of several event types into "user friendly" function overrides.
// //
template< typename EvtParams > template <typename EvtParams>
class IEventDispatcher class IEventDispatcher
{ {
protected: protected:
IEventDispatcher() {} IEventDispatcher() {}
public: public:
virtual ~IEventDispatcher() throw() {} virtual ~IEventDispatcher() throw() {}
virtual void DispatchEvent( const EvtParams& params )=0; virtual void DispatchEvent(const EvtParams &params) = 0;
}; };

View File

@ -19,88 +19,80 @@
using Threading::ScopedLock; using Threading::ScopedLock;
template< typename ListenerType > template <typename ListenerType>
typename EventSource<ListenerType>::ListenerIterator EventSource<ListenerType>::Add( ListenerType& listener ) typename EventSource<ListenerType>::ListenerIterator EventSource<ListenerType>::Add(ListenerType &listener)
{ {
ScopedLock locker( m_listeners_lock ); ScopedLock locker(m_listeners_lock);
// Check for duplicates before adding the event. // Check for duplicates before adding the event.
if( IsDebugBuild ) if (IsDebugBuild) {
{ ListenerIterator iter = m_listeners.begin();
ListenerIterator iter = m_listeners.begin(); while (iter != m_listeners.end()) {
while( iter != m_listeners.end() ) if ((*iter) == &listener)
{ return iter;
if( (*iter) == &listener ) return iter; ++iter;
++iter; }
} }
} return _AddFast_without_lock(listener);
return _AddFast_without_lock( listener );
} }
template< typename ListenerType > template <typename ListenerType>
void EventSource<ListenerType>::Remove( ListenerType& listener ) void EventSource<ListenerType>::Remove(ListenerType &listener)
{ {
ScopedLock locker( m_listeners_lock ); ScopedLock locker(m_listeners_lock);
m_cache_valid = false; m_cache_valid = false;
m_listeners.remove( &listener ); m_listeners.remove(&listener);
} }
template< typename ListenerType > template <typename ListenerType>
void EventSource<ListenerType>::Remove( const ListenerIterator& listenerHandle ) void EventSource<ListenerType>::Remove(const ListenerIterator &listenerHandle)
{ {
ScopedLock locker( m_listeners_lock ); ScopedLock locker(m_listeners_lock);
m_cache_valid = false; m_cache_valid = false;
m_listeners.erase( listenerHandle ); m_listeners.erase(listenerHandle);
} }
template< typename ListenerType > template <typename ListenerType>
typename EventSource<ListenerType>::ListenerIterator EventSource<ListenerType>::_AddFast_without_lock( ListenerType& listener ) typename EventSource<ListenerType>::ListenerIterator EventSource<ListenerType>::_AddFast_without_lock(ListenerType &listener)
{ {
m_cache_valid = false; m_cache_valid = false;
m_listeners.push_front( &listener ); m_listeners.push_front(&listener);
return m_listeners.begin(); return m_listeners.begin();
} }
template< typename ListenerType > template <typename ListenerType>
__fi void EventSource<ListenerType>::_DispatchRaw( ListenerIterator iter, const ListenerIterator& iend, const EvtParams& evtparams ) __fi void EventSource<ListenerType>::_DispatchRaw(ListenerIterator iter, const ListenerIterator &iend, const EvtParams &evtparams)
{ {
while( iter != iend ) while (iter != iend) {
{ try {
try { (*iter)->DispatchEvent(evtparams);
(*iter)->DispatchEvent( evtparams ); } catch (Exception::RuntimeError &ex) {
} if (IsDevBuild) {
catch( Exception::RuntimeError& ex ) pxFailDev(L"Ignoring runtime error thrown from event listener (event listeners should not throw exceptions!): " + ex.FormatDiagnosticMessage());
{ } else {
if( IsDevBuild ) { Console.Error(L"Ignoring runtime error thrown from event listener: " + ex.FormatDiagnosticMessage());
pxFailDev( L"Ignoring runtime error thrown from event listener (event listeners should not throw exceptions!): " + ex.FormatDiagnosticMessage() ); }
} } catch (BaseException &ex) {
else { if (IsDevBuild) {
Console.Error( L"Ignoring runtime error thrown from event listener: " + ex.FormatDiagnosticMessage() ); ex.DiagMsg() = L"Non-runtime BaseException thrown from event listener .. " + ex.DiagMsg();
} throw;
} }
catch( BaseException& ex ) Console.Error(L"Ignoring non-runtime BaseException thrown from event listener: " + ex.FormatDiagnosticMessage());
{ }
if( IsDevBuild ) ++iter;
{ }
ex.DiagMsg() = L"Non-runtime BaseException thrown from event listener .. " + ex.DiagMsg();
throw;
}
Console.Error( L"Ignoring non-runtime BaseException thrown from event listener: " + ex.FormatDiagnosticMessage() );
}
++iter;
}
} }
template< typename ListenerType > template <typename ListenerType>
void EventSource<ListenerType>::Dispatch( const EvtParams& evtparams ) void EventSource<ListenerType>::Dispatch(const EvtParams &evtparams)
{ {
if( !m_cache_valid ) if (!m_cache_valid) {
{ m_cache_copy = m_listeners;
m_cache_copy = m_listeners; m_cache_valid = true;
m_cache_valid = true; }
}
if( m_cache_copy.empty() ) return; if (m_cache_copy.empty())
_DispatchRaw( m_cache_copy.begin(), m_cache_copy.end(), evtparams ); return;
_DispatchRaw(m_cache_copy.begin(), m_cache_copy.end(), evtparams);
} }

View File

@ -30,112 +30,113 @@ void pxTrap();
// friendly error log in their wake. // friendly error log in their wake.
// //
// Note: Console can also fire an Exception::OutOfMemory // Note: Console can also fire an Exception::OutOfMemory
#define __DESTRUCTOR_CATCHALL( funcname ) \ #define __DESTRUCTOR_CATCHALL(funcname) \
catch( BaseException& ex ) \ catch (BaseException & ex) \
{ \ { \
try { \ try { \
Console.Error( "Unhandled BaseException in %s (ignored!):", funcname ); \ Console.Error("Unhandled BaseException in %s (ignored!):", funcname); \
Console.Error( ex.FormatDiagnosticMessage() ); \ Console.Error(ex.FormatDiagnosticMessage()); \
} catch (...) { \ } catch (...) { \
fprintf(stderr, "ERROR: (out of memory?)\n"); \ fprintf(stderr, "ERROR: (out of memory?)\n"); \
} \ } \
} \ } \
catch( std::exception& ex ) \ catch (std::exception & ex) \
{ \ { \
try { \ try { \
Console.Error( "Unhandled std::exception in %s (ignored!):", funcname ); \ Console.Error("Unhandled std::exception in %s (ignored!):", funcname); \
Console.Error( ex.what() ); \ Console.Error(ex.what()); \
} catch (...) { \ } catch (...) { \
fprintf(stderr, "ERROR: (out of memory?)\n"); \ fprintf(stderr, "ERROR: (out of memory?)\n"); \
} \ } \
} \ } \
catch(...) { \ catch (...) \
/* Unreachable code */ \ { \
} /* Unreachable code */ \
}
#define DESTRUCTOR_CATCHALL __DESTRUCTOR_CATCHALL( __pxFUNCTION__ ) #define DESTRUCTOR_CATCHALL __DESTRUCTOR_CATCHALL(__pxFUNCTION__)
namespace Exception namespace Exception
{ {
int MakeNewType(); int MakeNewType();
BaseException* FromErrno( const wxString& streamname, int errcode ); BaseException *FromErrno(const wxString &streamname, int errcode);
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// BaseException // BaseException
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// std::exception sucks, and isn't entirely cross-platform reliable in its implementation, // std::exception sucks, and isn't entirely cross-platform reliable in its implementation,
// so I made a replacement. The internal messages are non-const, which means that a // so I made a replacement. The internal messages are non-const, which means that a
// catch clause can optionally modify them and then re-throw to a top-level handler. // catch clause can optionally modify them and then re-throw to a top-level handler.
// //
// Note, this class is "abstract" which means you shouldn't use it directly like, ever. // Note, this class is "abstract" which means you shouldn't use it directly like, ever.
// Use Exception::RuntimeError instead for generic exceptions. // Use Exception::RuntimeError instead for generic exceptions.
// //
// Because exceptions are the (only!) really useful example of multiple inheritance, // Because exceptions are the (only!) really useful example of multiple inheritance,
// this class has only a trivial constructor, and must be manually initialized using // this class has only a trivial constructor, and must be manually initialized using
// InitBaseEx() or by individual member assignments. This is because C++ multiple inheritence // InitBaseEx() or by individual member assignments. This is because C++ multiple inheritence
// is, by design, a lot of fail, especially when class initializers are mixed in. // is, by design, a lot of fail, especially when class initializers are mixed in.
// //
// [TODO] : Add an InnerException component, and Clone() facility. // [TODO] : Add an InnerException component, and Clone() facility.
// //
class BaseException class BaseException
{ {
protected: protected:
wxString m_message_diag; // (untranslated) a "detailed" message of what disastrous thing has occurred! wxString m_message_diag; // (untranslated) a "detailed" message of what disastrous thing has occurred!
wxString m_message_user; // (translated) a "detailed" message of what disastrous thing has occurred! wxString m_message_user; // (translated) a "detailed" message of what disastrous thing has occurred!
public: public:
virtual ~BaseException() throw()=0; // the =0; syntax forces this class into "abstract" mode. virtual ~BaseException() throw() = 0; // the =0; syntax forces this class into "abstract" mode.
const wxString& DiagMsg() const { return m_message_diag; } const wxString &DiagMsg() const { return m_message_diag; }
const wxString& UserMsg() const { return m_message_user; } const wxString &UserMsg() const { return m_message_user; }
wxString& DiagMsg() { return m_message_diag; } wxString &DiagMsg() { return m_message_diag; }
wxString& UserMsg() { return m_message_user; } wxString &UserMsg() { return m_message_user; }
BaseException& SetBothMsgs( const wxChar* msg_diag ); BaseException &SetBothMsgs(const wxChar *msg_diag);
BaseException& SetDiagMsg( const wxString& msg_diag ); BaseException &SetDiagMsg(const wxString &msg_diag);
BaseException& SetUserMsg( const wxString& msg_user ); BaseException &SetUserMsg(const wxString &msg_user);
// Returns a message suitable for diagnostic / logging purposes. // Returns a message suitable for diagnostic / logging purposes.
// This message is always in English, and includes a full stack trace. // This message is always in English, and includes a full stack trace.
virtual wxString FormatDiagnosticMessage() const; virtual wxString FormatDiagnosticMessage() const;
// Returns a message suitable for end-user display. // Returns a message suitable for end-user display.
// This message is usually meant for display in a user popup or such. // This message is usually meant for display in a user popup or such.
virtual wxString FormatDisplayMessage() const; virtual wxString FormatDisplayMessage() const;
virtual void Rethrow() const=0; virtual void Rethrow() const = 0;
virtual BaseException* Clone() const=0; virtual BaseException *Clone() const = 0;
}; };
typedef std::unique_ptr<BaseException> ScopedExcept; typedef std::unique_ptr<BaseException> ScopedExcept;
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Ps2Generic Exception // Ps2Generic Exception
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// This class is used as a base exception for things tossed by PS2 cpus (EE, IOP, etc). // This class is used as a base exception for things tossed by PS2 cpus (EE, IOP, etc).
// //
// Implementation note: does not derive from BaseException, so that we can use different // Implementation note: does not derive from BaseException, so that we can use different
// catch block hierarchies to handle them (if needed). // catch block hierarchies to handle them (if needed).
// //
// Translation Note: Currently these exceptions are never translated. English/diagnostic // Translation Note: Currently these exceptions are never translated. English/diagnostic
// format only. :) // format only. :)
// //
class Ps2Generic class Ps2Generic
{ {
protected: protected:
wxString m_message; // a "detailed" message of what disastrous thing has occurred! wxString m_message; // a "detailed" message of what disastrous thing has occurred!
public: public:
virtual ~Ps2Generic() throw() {} virtual ~Ps2Generic() throw() {}
virtual u32 GetPc() const=0; virtual u32 GetPc() const = 0;
virtual bool IsDelaySlot() const=0; virtual bool IsDelaySlot() const = 0;
virtual wxString& Message() { return m_message; } virtual wxString &Message() { return m_message; }
virtual void Rethrow() const=0; virtual void Rethrow() const = 0;
virtual Ps2Generic* Clone() const=0; virtual Ps2Generic *Clone() const = 0;
}; };
// Some helper macros for defining the standard constructors of internationalized constructors // Some helper macros for defining the standard constructors of internationalized constructors
// Parameters: // Parameters:
@ -151,217 +152,239 @@ namespace Exception
// //
// (update: web searches indicate it's MSVC specific -- happens in 2008, not sure about 2010). // (update: web searches indicate it's MSVC specific -- happens in 2008, not sure about 2010).
// //
#define DEFINE_EXCEPTION_COPYTORS( classname, parent ) \ #define DEFINE_EXCEPTION_COPYTORS(classname, parent) \
private: \ private: \
typedef parent _parent; \ typedef parent _parent; \
public: \ \
virtual ~classname() throw() {} \ public: \
virtual void Rethrow() const { throw *this; } \ virtual ~classname() throw() {} \
virtual classname* Clone() const { return new classname( *this ); } virtual void Rethrow() const { throw * this; } \
virtual classname *Clone() const { return new classname(*this); }
#define DEFINE_EXCEPTION_MESSAGES( classname ) \ #define DEFINE_EXCEPTION_MESSAGES(classname) \
public: \ public: \
classname& SetBothMsgs( const wxChar* msg_diag ) { BaseException::SetBothMsgs(msg_diag); return *this; } \ classname &SetBothMsgs(const wxChar *msg_diag) \
classname& SetDiagMsg( const wxString& msg_diag ) { m_message_diag = msg_diag; return *this; } \ { \
classname& SetUserMsg( const wxString& msg_user ) { m_message_user = msg_user; return *this; } BaseException::SetBothMsgs(msg_diag); \
return *this; \
} \
classname &SetDiagMsg(const wxString &msg_diag) \
{ \
m_message_diag = msg_diag; \
return *this; \
} \
classname &SetUserMsg(const wxString &msg_user) \
{ \
m_message_user = msg_user; \
return *this; \
}
#define DEFINE_RUNTIME_EXCEPTION( classname, parent, message ) \ #define DEFINE_RUNTIME_EXCEPTION(classname, parent, message) \
DEFINE_EXCEPTION_COPYTORS( classname, parent ) \ DEFINE_EXCEPTION_COPYTORS(classname, parent) \
classname() { SetDiagMsg(message); } \ classname() { SetDiagMsg(message); } \
DEFINE_EXCEPTION_MESSAGES( classname ) DEFINE_EXCEPTION_MESSAGES(classname)
// ---------------------------------------------------------------------------------------
// RuntimeError - Generalized Exceptions with Recoverable Traits!
// ---------------------------------------------------------------------------------------
class RuntimeError : public BaseException
{
DEFINE_EXCEPTION_COPYTORS( RuntimeError, BaseException )
DEFINE_EXCEPTION_MESSAGES( RuntimeError )
public: // ---------------------------------------------------------------------------------------
bool IsSilent; // RuntimeError - Generalized Exceptions with Recoverable Traits!
// ---------------------------------------------------------------------------------------
RuntimeError() { IsSilent = false; } class RuntimeError : public BaseException
RuntimeError( const std::runtime_error& ex, const wxString& prefix=wxEmptyString ); {
RuntimeError( const std::exception& ex, const wxString& prefix=wxEmptyString ); DEFINE_EXCEPTION_COPYTORS(RuntimeError, BaseException)
}; DEFINE_EXCEPTION_MESSAGES(RuntimeError)
// -------------------------------------------------------------------------------------- public:
// CancelAppEvent - Exception for canceling an event in a non-verbose fashion bool IsSilent;
// --------------------------------------------------------------------------------------
// Typically the PCSX2 interface issues popup dialogs for runtime errors. This exception
// instead issues a "silent" cancelation that is handled by the app gracefully (generates
// log, and resumes messages queue processing).
//
// I chose to have this exception derive from RuntimeError, since if one is thrown from outside
// an App message loop we'll still want it to be handled in a reasonably graceful manner.
class CancelEvent : public RuntimeError
{
DEFINE_RUNTIME_EXCEPTION( CancelEvent, RuntimeError, pxLt("No reason given.") )
public: RuntimeError() { IsSilent = false; }
explicit CancelEvent( const wxString& logmsg ) RuntimeError(const std::runtime_error &ex, const wxString &prefix = wxEmptyString);
{ RuntimeError(const std::exception &ex, const wxString &prefix = wxEmptyString);
m_message_diag = logmsg; };
// overridden message formatters only use the diagnostic version...
}
virtual wxString FormatDisplayMessage() const; // --------------------------------------------------------------------------------------
virtual wxString FormatDiagnosticMessage() const; // CancelAppEvent - Exception for canceling an event in a non-verbose fashion
}; // --------------------------------------------------------------------------------------
// Typically the PCSX2 interface issues popup dialogs for runtime errors. This exception
// instead issues a "silent" cancelation that is handled by the app gracefully (generates
// log, and resumes messages queue processing).
//
// I chose to have this exception derive from RuntimeError, since if one is thrown from outside
// an App message loop we'll still want it to be handled in a reasonably graceful manner.
class CancelEvent : public RuntimeError
{
DEFINE_RUNTIME_EXCEPTION(CancelEvent, RuntimeError, pxLt("No reason given."))
// --------------------------------------------------------------------------------------- public:
// OutOfMemory explicit CancelEvent(const wxString &logmsg)
// --------------------------------------------------------------------------------------- {
// This exception has a custom-formatted Diagnostic string. The parameter give when constructing m_message_diag = logmsg;
// the exception is a block/alloc name, which is used as a formatting parameter in the diagnostic // overridden message formatters only use the diagnostic version...
// output. The default diagnostic message is "Out of memory exception, while allocating the %s." }
// where %s is filled in with the block name.
//
// The user string is not custom-formatted, and should contain *NO* %s tags.
//
class OutOfMemory : public RuntimeError
{
DEFINE_RUNTIME_EXCEPTION( OutOfMemory, RuntimeError, wxEmptyString )
public: virtual wxString FormatDisplayMessage() const;
wxString AllocDescription; virtual wxString FormatDiagnosticMessage() const;
};
public: // ---------------------------------------------------------------------------------------
OutOfMemory( const wxString& allocdesc ); // OutOfMemory
// ---------------------------------------------------------------------------------------
// This exception has a custom-formatted Diagnostic string. The parameter give when constructing
// the exception is a block/alloc name, which is used as a formatting parameter in the diagnostic
// output. The default diagnostic message is "Out of memory exception, while allocating the %s."
// where %s is filled in with the block name.
//
// The user string is not custom-formatted, and should contain *NO* %s tags.
//
class OutOfMemory : public RuntimeError
{
DEFINE_RUNTIME_EXCEPTION(OutOfMemory, RuntimeError, wxEmptyString)
virtual wxString FormatDisplayMessage() const; public:
virtual wxString FormatDiagnosticMessage() const; wxString AllocDescription;
};
class ParseError : public RuntimeError public:
{ OutOfMemory(const wxString &allocdesc);
DEFINE_RUNTIME_EXCEPTION( ParseError, RuntimeError, pxL("Parse error") );
};
// --------------------------------------------------------------------------------------- virtual wxString FormatDisplayMessage() const;
// Hardware/OS Exceptions: virtual wxString FormatDiagnosticMessage() const;
// HardwareDeficiency / VirtualMemoryMapConflict };
// ---------------------------------------------------------------------------------------
// This exception is a specific type of OutOfMemory error that isn't "really" an out of class ParseError : public RuntimeError
// memory error. More likely it's caused by a plugin or driver reserving a range of memory {
// we'd really like to have access to. DEFINE_RUNTIME_EXCEPTION(ParseError, RuntimeError, pxL("Parse error"));
class VirtualMemoryMapConflict : public OutOfMemory };
{
DEFINE_RUNTIME_EXCEPTION( VirtualMemoryMapConflict, OutOfMemory, wxEmptyString )
VirtualMemoryMapConflict( const wxString& allocdesc ); // ---------------------------------------------------------------------------------------
// Hardware/OS Exceptions:
// HardwareDeficiency / VirtualMemoryMapConflict
// ---------------------------------------------------------------------------------------
virtual wxString FormatDisplayMessage() const; // This exception is a specific type of OutOfMemory error that isn't "really" an out of
virtual wxString FormatDiagnosticMessage() const; // memory error. More likely it's caused by a plugin or driver reserving a range of memory
}; // we'd really like to have access to.
class VirtualMemoryMapConflict : public OutOfMemory
{
DEFINE_RUNTIME_EXCEPTION(VirtualMemoryMapConflict, OutOfMemory, wxEmptyString)
class HardwareDeficiency : public RuntimeError VirtualMemoryMapConflict(const wxString &allocdesc);
{
public:
DEFINE_RUNTIME_EXCEPTION( HardwareDeficiency, RuntimeError, pxL("Your machine's hardware is incapable of running PCSX2. Sorry dood.") );
};
// --------------------------------------------------------------------------------------- virtual wxString FormatDisplayMessage() const;
// Streaming (file) Exceptions: virtual wxString FormatDiagnosticMessage() const;
// Stream / BadStream / CannotCreateStream / FileNotFound / AccessDenied / EndOfStream };
// ---------------------------------------------------------------------------------------
#define DEFINE_STREAM_EXCEPTION_ACCESSORS( classname ) \ class HardwareDeficiency : public RuntimeError
virtual classname& SetStreamName( const wxString& name ) { StreamName = name; return *this; } \ {
virtual classname& SetStreamName( const char* name ) { StreamName = fromUTF8(name); return *this; } public:
DEFINE_RUNTIME_EXCEPTION(HardwareDeficiency, RuntimeError, pxL("Your machine's hardware is incapable of running PCSX2. Sorry dood."));
};
#define DEFINE_STREAM_EXCEPTION( classname, parent ) \ // ---------------------------------------------------------------------------------------
DEFINE_RUNTIME_EXCEPTION( classname, parent, wxEmptyString ) \ // Streaming (file) Exceptions:
classname( const wxString& filename ) { \ // Stream / BadStream / CannotCreateStream / FileNotFound / AccessDenied / EndOfStream
StreamName = filename; \ // ---------------------------------------------------------------------------------------
} \
DEFINE_STREAM_EXCEPTION_ACCESSORS( classname )
// A generic base error class for bad streams -- corrupted data, sudden closures, loss of
// connection, or anything else that would indicate a failure to open a stream or read the
// data after the stream was successfully opened.
//
class BadStream : public RuntimeError
{
DEFINE_STREAM_EXCEPTION( BadStream, RuntimeError )
public: #define DEFINE_STREAM_EXCEPTION_ACCESSORS(classname) \
wxString StreamName; // name of the stream (if applicable) virtual classname &SetStreamName(const wxString &name) \
{ \
StreamName = name; \
return *this; \
} \
virtual classname &SetStreamName(const char *name) \
{ \
StreamName = fromUTF8(name); \
return *this; \
}
virtual wxString FormatDiagnosticMessage() const; #define DEFINE_STREAM_EXCEPTION(classname, parent) \
virtual wxString FormatDisplayMessage() const; DEFINE_RUNTIME_EXCEPTION(classname, parent, wxEmptyString) \
classname(const wxString &filename) \
{ \
StreamName = filename; \
} \
DEFINE_STREAM_EXCEPTION_ACCESSORS(classname)
protected: // A generic base error class for bad streams -- corrupted data, sudden closures, loss of
void _formatDiagMsg( FastFormatUnicode& dest ) const; // connection, or anything else that would indicate a failure to open a stream or read the
void _formatUserMsg( FastFormatUnicode& dest ) const; // data after the stream was successfully opened.
}; //
class BadStream : public RuntimeError
{
DEFINE_STREAM_EXCEPTION(BadStream, RuntimeError)
// A generic exception for odd-ball stream creation errors. public:
// wxString StreamName; // name of the stream (if applicable)
class CannotCreateStream : public BadStream
{
DEFINE_STREAM_EXCEPTION( CannotCreateStream, BadStream )
virtual wxString FormatDiagnosticMessage() const; virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const; virtual wxString FormatDisplayMessage() const;
};
// Exception thrown when an attempt to open a non-existent file is made. protected:
// (this exception can also mean file permissions are invalid) void _formatDiagMsg(FastFormatUnicode &dest) const;
// void _formatUserMsg(FastFormatUnicode &dest) const;
class FileNotFound : public CannotCreateStream };
{
public:
DEFINE_STREAM_EXCEPTION( FileNotFound, CannotCreateStream )
virtual wxString FormatDiagnosticMessage() const; // A generic exception for odd-ball stream creation errors.
virtual wxString FormatDisplayMessage() const; //
}; class CannotCreateStream : public BadStream
{
DEFINE_STREAM_EXCEPTION(CannotCreateStream, BadStream)
class AccessDenied : public CannotCreateStream virtual wxString FormatDiagnosticMessage() const;
{ virtual wxString FormatDisplayMessage() const;
public: };
DEFINE_STREAM_EXCEPTION( AccessDenied, CannotCreateStream )
virtual wxString FormatDiagnosticMessage() const; // Exception thrown when an attempt to open a non-existent file is made.
virtual wxString FormatDisplayMessage() const; // (this exception can also mean file permissions are invalid)
}; //
class FileNotFound : public CannotCreateStream
{
public:
DEFINE_STREAM_EXCEPTION(FileNotFound, CannotCreateStream)
// EndOfStream can be used either as an error, or used just as a shortcut for manual virtual wxString FormatDiagnosticMessage() const;
// feof checks. virtual wxString FormatDisplayMessage() const;
// };
class EndOfStream : public BadStream
{
public:
DEFINE_STREAM_EXCEPTION( EndOfStream, BadStream )
virtual wxString FormatDiagnosticMessage() const; class AccessDenied : public CannotCreateStream
virtual wxString FormatDisplayMessage() const; {
}; public:
DEFINE_STREAM_EXCEPTION(AccessDenied, CannotCreateStream)
virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const;
};
// EndOfStream can be used either as an error, or used just as a shortcut for manual
// feof checks.
//
class EndOfStream : public BadStream
{
public:
DEFINE_STREAM_EXCEPTION(EndOfStream, BadStream)
virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const;
};
#ifdef __WXMSW__ #ifdef __WXMSW__
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Exception::WinApiError // Exception::WinApiError
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class WinApiError : public RuntimeError class WinApiError : public RuntimeError
{ {
DEFINE_EXCEPTION_COPYTORS( WinApiError, RuntimeError ) DEFINE_EXCEPTION_COPYTORS(WinApiError, RuntimeError)
DEFINE_EXCEPTION_MESSAGES( WinApiError ) DEFINE_EXCEPTION_MESSAGES(WinApiError)
public: public:
int ErrorId; int ErrorId;
public: public:
WinApiError(); WinApiError();
wxString GetMsgFromWindows() const; wxString GetMsgFromWindows() const;
virtual wxString FormatDisplayMessage() const; virtual wxString FormatDisplayMessage() const;
virtual wxString FormatDiagnosticMessage() const; virtual wxString FormatDiagnosticMessage() const;
}; };
#endif #endif
} }

View File

@ -17,59 +17,59 @@
#include "Dependencies.h" #include "Dependencies.h"
template< int Precision > template <int Precision>
struct FixedInt struct FixedInt
{ {
s32 Raw; s32 Raw;
FixedInt(); FixedInt();
FixedInt( int signedval ); FixedInt(int signedval);
FixedInt( double doubval ); FixedInt(double doubval);
FixedInt( float floval ); FixedInt(float floval);
bool operator ==( const FixedInt<Precision>& right ) const { return Raw == right.Raw; } bool operator==(const FixedInt<Precision> &right) const { return Raw == right.Raw; }
bool operator !=( const FixedInt<Precision>& right ) const { return Raw != right.Raw; } bool operator!=(const FixedInt<Precision> &right) const { return Raw != right.Raw; }
bool operator>( const FixedInt<Precision>& right ) const { return Raw > right.Raw; }; bool operator>(const FixedInt<Precision> &right) const { return Raw > right.Raw; };
bool operator>=( const FixedInt<Precision>& right ) const { return Raw >= right.Raw; }; bool operator>=(const FixedInt<Precision> &right) const { return Raw >= right.Raw; };
bool operator<( const FixedInt<Precision>& right ) const { return Raw < right.Raw; }; bool operator<(const FixedInt<Precision> &right) const { return Raw < right.Raw; };
bool operator<=( const FixedInt<Precision>& right ) const { return Raw <= right.Raw; }; bool operator<=(const FixedInt<Precision> &right) const { return Raw <= right.Raw; };
FixedInt<Precision> operator+( const FixedInt<Precision>& right ) const; FixedInt<Precision> operator+(const FixedInt<Precision> &right) const;
FixedInt<Precision> operator-( const FixedInt<Precision>& right ) const; FixedInt<Precision> operator-(const FixedInt<Precision> &right) const;
FixedInt<Precision>& operator+=( const FixedInt<Precision>& right ); FixedInt<Precision> &operator+=(const FixedInt<Precision> &right);
FixedInt<Precision>& operator-=( const FixedInt<Precision>& right ); FixedInt<Precision> &operator-=(const FixedInt<Precision> &right);
FixedInt<Precision>& ConfineTo( const FixedInt<Precision>& low, const FixedInt<Precision>& high ); FixedInt<Precision> &ConfineTo(const FixedInt<Precision> &low, const FixedInt<Precision> &high);
FixedInt<Precision> operator*( const FixedInt<Precision>& right ) const; FixedInt<Precision> operator*(const FixedInt<Precision> &right) const;
FixedInt<Precision> operator/( const FixedInt<Precision>& right ) const; FixedInt<Precision> operator/(const FixedInt<Precision> &right) const;
FixedInt<Precision>& operator*=( const FixedInt<Precision>& right ); FixedInt<Precision> &operator*=(const FixedInt<Precision> &right);
FixedInt<Precision>& operator/=( const FixedInt<Precision>& right ); FixedInt<Precision> &operator/=(const FixedInt<Precision> &right);
static bool OverflowCheck( int signedval ); static bool OverflowCheck(int signedval);
static bool OverflowCheck( double signedval ); static bool OverflowCheck(double signedval);
int GetWhole() const; int GetWhole() const;
int GetFraction() const; int GetFraction() const;
FixedInt<Precision>& SetRaw( s32 rawsrc ); FixedInt<Precision> &SetRaw(s32 rawsrc);
FixedInt<Precision>& Round(); FixedInt<Precision> &Round();
FixedInt<Precision>& SetWhole( s32 wholepart ); FixedInt<Precision> &SetWhole(s32 wholepart);
FixedInt<Precision>& SetFraction( u32 fracpart ); FixedInt<Precision> &SetFraction(u32 fracpart);
wxString ToString() const; wxString ToString() const;
wxString ToString( int fracDigits ) const; wxString ToString(int fracDigits) const;
double ToDouble() const; double ToDouble() const;
float ToFloat() const; float ToFloat() const;
int ToIntTruncated() const; int ToIntTruncated() const;
int ToIntRounded() const; int ToIntRounded() const;
static bool TryFromString( FixedInt<Precision>& dest, const wxString& parseFrom ); static bool TryFromString(FixedInt<Precision> &dest, const wxString &parseFrom);
static FixedInt<Precision> FromString( const wxString& parseFrom, const FixedInt<Precision>& defval ); static FixedInt<Precision> FromString(const wxString &parseFrom, const FixedInt<Precision> &defval);
static FixedInt<Precision> FromString( const wxString parseFrom ); static FixedInt<Precision> FromString(const wxString parseFrom);
}; };
typedef FixedInt<256> Fixed256; typedef FixedInt<256> Fixed256;
typedef FixedInt<100> Fixed100; typedef FixedInt<100> Fixed100;

View File

@ -16,226 +16,237 @@
#pragma once #pragma once
#include "FixedPointTypes.h" #include "FixedPointTypes.h"
#include <cmath> // for pow! #include <cmath> // for pow!
template< int Precision > template <int Precision>
FixedInt<Precision>::FixedInt() FixedInt<Precision>::FixedInt()
{ {
Raw = 0; Raw = 0;
} }
template< int Precision > template <int Precision>
FixedInt<Precision>::FixedInt( int signedval ) FixedInt<Precision>::FixedInt(int signedval)
{ {
Raw = signedval * Precision; Raw = signedval * Precision;
} }
template< int Precision > template <int Precision>
FixedInt<Precision>::FixedInt( double doubval ) FixedInt<Precision>::FixedInt(double doubval)
{ {
Raw = lround(doubval * (double)Precision); Raw = lround(doubval * (double)Precision);
} }
template< int Precision > template <int Precision>
FixedInt<Precision>::FixedInt( float floval ) FixedInt<Precision>::FixedInt(float floval)
{ {
Raw = lroundf(floval * (float)Precision); Raw = lroundf(floval * (float)Precision);
} }
template< int Precision > template <int Precision>
FixedInt<Precision> FixedInt<Precision>::operator+( const FixedInt<Precision>& right ) const FixedInt<Precision> FixedInt<Precision>::operator+(const FixedInt<Precision> &right) const
{ {
return FixedInt<Precision>().SetRaw( Raw + right.Raw ); return FixedInt<Precision>().SetRaw(Raw + right.Raw);
} }
template< int Precision > template <int Precision>
FixedInt<Precision> FixedInt<Precision>::operator-( const FixedInt<Precision>& right ) const FixedInt<Precision> FixedInt<Precision>::operator-(const FixedInt<Precision> &right) const
{ {
return FixedInt<Precision>().SetRaw( Raw + right.Raw ); return FixedInt<Precision>().SetRaw(Raw + right.Raw);
} }
template< int Precision > template <int Precision>
FixedInt<Precision>& FixedInt<Precision>::operator+=( const FixedInt<Precision>& right ) FixedInt<Precision> &FixedInt<Precision>::operator+=(const FixedInt<Precision> &right)
{ {
return SetRaw( Raw + right.Raw ); return SetRaw(Raw + right.Raw);
} }
template< int Precision > template <int Precision>
FixedInt<Precision>& FixedInt<Precision>::operator-=( const FixedInt<Precision>& right ) FixedInt<Precision> &FixedInt<Precision>::operator-=(const FixedInt<Precision> &right)
{ {
return SetRaw( Raw + right.Raw ); return SetRaw(Raw + right.Raw);
} }
template< int Precision > template <int Precision>
FixedInt<Precision>& FixedInt<Precision>::ConfineTo( const FixedInt<Precision>& low, const FixedInt<Precision>& high ) FixedInt<Precision> &FixedInt<Precision>::ConfineTo(const FixedInt<Precision> &low, const FixedInt<Precision> &high)
{ {
return SetRaw( std::min( std::max( Raw, low.Raw ), high.Raw ) ); return SetRaw(std::min(std::max(Raw, low.Raw), high.Raw));
} }
// Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math // Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
// you'll need to use the Raw values directly. // you'll need to use the Raw values directly.
template< int Precision > template <int Precision>
FixedInt<Precision> FixedInt<Precision>::operator*( const FixedInt<Precision>& right ) const FixedInt<Precision> FixedInt<Precision>::operator*(const FixedInt<Precision> &right) const
{ {
s64 mulres = (s64)Raw * right.Raw; s64 mulres = (s64)Raw * right.Raw;
return FixedInt<Precision>().SetRaw( (s32)(mulres / Precision) ); return FixedInt<Precision>().SetRaw((s32)(mulres / Precision));
} }
// Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math // Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
// you'll need to use the Raw values directly. // you'll need to use the Raw values directly.
template< int Precision > template <int Precision>
FixedInt<Precision> FixedInt<Precision>::operator/( const FixedInt<Precision>& right ) const FixedInt<Precision> FixedInt<Precision>::operator/(const FixedInt<Precision> &right) const
{ {
s64 divres = Raw * Precision; s64 divres = Raw * Precision;
return FixedInt<Precision>().SetRaw( (s32)(divres / right.Raw) ); return FixedInt<Precision>().SetRaw((s32)(divres / right.Raw));
} }
// Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math // Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
// you'll need to use the Raw values directly. // you'll need to use the Raw values directly.
template< int Precision > template <int Precision>
FixedInt<Precision>& FixedInt<Precision>::operator*=( const FixedInt<Precision>& right ) FixedInt<Precision> &FixedInt<Precision>::operator*=(const FixedInt<Precision> &right)
{ {
s64 mulres = (s64)Raw * right.Raw; s64 mulres = (s64)Raw * right.Raw;
return SetRaw( (s32)(mulres / Precision) ); return SetRaw((s32)(mulres / Precision));
} }
// Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math // Uses 64 bit internally to avoid overflows. For more precise/optimized 32 bit math
// you'll need to use the Raw values directly. // you'll need to use the Raw values directly.
template< int Precision > template <int Precision>
FixedInt<Precision>& FixedInt<Precision>::operator/=( const FixedInt<Precision>& right ) FixedInt<Precision> &FixedInt<Precision>::operator/=(const FixedInt<Precision> &right)
{ {
s64 divres = Raw * Precision; s64 divres = Raw * Precision;
return SetRaw( (s32)(divres / right.Raw) ); return SetRaw((s32)(divres / right.Raw));
} }
// returns TRUE if the value overflows the legal integer range of this container. // returns TRUE if the value overflows the legal integer range of this container.
template< int Precision > template <int Precision>
bool FixedInt<Precision>::OverflowCheck( int signedval ) bool FixedInt<Precision>::OverflowCheck(int signedval)
{ {
return ( signedval >= (INT_MAX / Precision) ); return (signedval >= (INT_MAX / Precision));
} }
// returns TRUE if the value overflows the legal integer range of this container. // returns TRUE if the value overflows the legal integer range of this container.
template< int Precision > template <int Precision>
bool FixedInt<Precision>::OverflowCheck( double signedval ) bool FixedInt<Precision>::OverflowCheck(double signedval)
{ {
return ( signedval >= (INT_MAX / Precision) ); return (signedval >= (INT_MAX / Precision));
} }
template< int Precision > int FixedInt<Precision>::GetWhole() const { return Raw / Precision; } template <int Precision>
template< int Precision > int FixedInt<Precision>::GetFraction() const { return Raw % Precision; } int FixedInt<Precision>::GetWhole() const
template< int Precision >
FixedInt<Precision>& FixedInt<Precision>::SetRaw( s32 rawsrc )
{ {
Raw = rawsrc; return Raw / Precision;
return *this; }
template <int Precision>
int FixedInt<Precision>::GetFraction() const
{
return Raw % Precision;
} }
template< int Precision > template <int Precision>
FixedInt<Precision>& FixedInt<Precision>::Round() FixedInt<Precision> &FixedInt<Precision>::SetRaw(s32 rawsrc)
{ {
Raw = ToIntRounded(); Raw = rawsrc;
return *this; return *this;
} }
template< int Precision > template <int Precision>
FixedInt<Precision>& FixedInt<Precision>::SetWhole( s32 wholepart ) FixedInt<Precision> &FixedInt<Precision>::Round()
{ {
pxAssert( wholepart < (INT_MAX / Precision) ); Raw = ToIntRounded();
Raw = GetFraction() + (wholepart * Precision); return *this;
return *this;
} }
template< int Precision > template <int Precision>
FixedInt<Precision>& FixedInt<Precision>::SetFraction( u32 fracpart ) FixedInt<Precision> &FixedInt<Precision>::SetWhole(s32 wholepart)
{ {
Raw = (GetWhole() * Precision) + fracpart; pxAssert(wholepart < (INT_MAX / Precision));
return *this; Raw = GetFraction() + (wholepart * Precision);
return *this;
} }
template< int Precision > template <int Precision>
FixedInt<Precision> &FixedInt<Precision>::SetFraction(u32 fracpart)
{
Raw = (GetWhole() * Precision) + fracpart;
return *this;
}
template <int Precision>
wxString FixedInt<Precision>::ToString() const wxString FixedInt<Precision>::ToString() const
{ {
return wxsFormat( L"%d.%02d", GetWhole(), (GetFraction() * 100) / Precision ); return wxsFormat(L"%d.%02d", GetWhole(), (GetFraction() * 100) / Precision);
} }
template< int Precision > template <int Precision>
wxString FixedInt<Precision>::ToString( int fracDigits ) const wxString FixedInt<Precision>::ToString(int fracDigits) const
{ {
if( fracDigits == 0 ) return wxsFormat( L"%d", GetWhole() ); if (fracDigits == 0)
return wxsFormat(L"%d", GetWhole());
pxAssert( fracDigits <= 7 ); // higher numbers would just cause overflows and bad mojo. pxAssert(fracDigits <= 7); // higher numbers would just cause overflows and bad mojo.
int mulby = (int)pow( 10.0, fracDigits ); int mulby = (int)pow(10.0, fracDigits);
wxString fmt=wxsFormat(L"%%d.%%0%dd", fracDigits); wxString fmt = wxsFormat(L"%%d.%%0%dd", fracDigits);
return wxsFormat( fmt, GetWhole(), (GetFraction() * mulby) / Precision ); return wxsFormat(fmt, GetWhole(), (GetFraction() * mulby) / Precision);
} }
template< int Precision > template <int Precision>
double FixedInt<Precision>::ToDouble() const double FixedInt<Precision>::ToDouble() const
{ {
return ((double)Raw / (double)Precision); return ((double)Raw / (double)Precision);
} }
template< int Precision > template <int Precision>
float FixedInt<Precision>::ToFloat() const float FixedInt<Precision>::ToFloat() const
{ {
return ((float)Raw / (float)Precision); return ((float)Raw / (float)Precision);
} }
template< int Precision > template <int Precision>
int FixedInt<Precision>::ToIntTruncated() const int FixedInt<Precision>::ToIntTruncated() const
{ {
return Raw / Precision; return Raw / Precision;
} }
template< int Precision > template <int Precision>
int FixedInt<Precision>::ToIntRounded() const int FixedInt<Precision>::ToIntRounded() const
{ {
return (Raw + (Precision/2)) / Precision; return (Raw + (Precision / 2)) / Precision;
} }
template< int Precision > template <int Precision>
bool FixedInt<Precision>::TryFromString( FixedInt<Precision>& dest, const wxString& parseFrom ) bool FixedInt<Precision>::TryFromString(FixedInt<Precision> &dest, const wxString &parseFrom)
{ {
long whole=0, frac=0; long whole = 0, frac = 0;
const wxString beforeFirst( parseFrom.BeforeFirst( L'.' ) ); const wxString beforeFirst(parseFrom.BeforeFirst(L'.'));
const wxString afterFirst( parseFrom.AfterFirst( L'.' ).Mid(0, 5) ); const wxString afterFirst(parseFrom.AfterFirst(L'.').Mid(0, 5));
bool success = true; bool success = true;
if( !beforeFirst.IsEmpty() ) if (!beforeFirst.IsEmpty())
success = success && beforeFirst.ToLong( &whole ); success = success && beforeFirst.ToLong(&whole);
if( !afterFirst.IsEmpty() ) if (!afterFirst.IsEmpty())
success = success && afterFirst.ToLong( &frac ); success = success && afterFirst.ToLong(&frac);
if( !success ) return false; if (!success)
return false;
dest.SetWhole( whole ); dest.SetWhole(whole);
if( afterFirst.Length() != 0 && frac != 0 ) if (afterFirst.Length() != 0 && frac != 0) {
{ int fracPower = (int)pow(10.0, (int)afterFirst.Length());
int fracPower = (int)pow( 10.0, (int)afterFirst.Length() ); dest.SetFraction((frac * Precision) / fracPower);
dest.SetFraction( (frac * Precision) / fracPower ); }
} return true;
return true;
} }
template< int Precision > template <int Precision>
FixedInt<Precision> FixedInt<Precision>::FromString( const wxString& parseFrom, const FixedInt<Precision>& defval ) FixedInt<Precision> FixedInt<Precision>::FromString(const wxString &parseFrom, const FixedInt<Precision> &defval)
{ {
FixedInt<Precision> dest; FixedInt<Precision> dest;
if( !TryFromString( dest, parseFrom ) ) return defval; if (!TryFromString(dest, parseFrom))
return dest; return defval;
return dest;
} }
// This version of FromString throws a ParseError exception if the conversion fails. // This version of FromString throws a ParseError exception if the conversion fails.
template< int Precision > template <int Precision>
FixedInt<Precision> FixedInt<Precision>::FromString( const wxString parseFrom ) FixedInt<Precision> FixedInt<Precision>::FromString(const wxString parseFrom)
{ {
FixedInt<Precision> dest; FixedInt<Precision> dest;
if( !TryFromString( dest, parseFrom ) ) throw Exception::ParseError() if (!TryFromString(dest, parseFrom))
.SetDiagMsg(wxsFormat(L"Parse error on FixedInt<%d>::FromString", Precision)); throw Exception::ParseError()
.SetDiagMsg(wxsFormat(L"Parse error on FixedInt<%d>::FromString", Precision));
return dest; return dest;
} }

View File

@ -17,16 +17,22 @@
// This macro is actually useful for about any and every possible application of C++ // This macro is actually useful for about any and every possible application of C++
// equality operators. // equality operators.
#define OpEqu( field ) (field == right.field) #define OpEqu(field) (field == right.field)
// Macro used for removing some of the redtape involved in defining bitfield/union helpers. // Macro used for removing some of the redtape involved in defining bitfield/union helpers.
// //
#define BITFIELD32() \ #define BITFIELD32() \
union { \ union \
u32 bitset; \ { \
struct { u32 bitset; \
struct \
{
#define BITFIELD_END }; }; #define BITFIELD_END \
} \
; \
} \
;
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
@ -42,15 +48,20 @@
class RecursionGuard class RecursionGuard
{ {
public: public:
int& Counter; int &Counter;
RecursionGuard( int& counter ) : Counter( counter ) RecursionGuard(int &counter)
{ ++Counter; } : Counter(counter)
{
++Counter;
}
virtual ~RecursionGuard() throw() virtual ~RecursionGuard() throw()
{ --Counter; } {
--Counter;
}
bool IsReentrant() const { return Counter > 1; } bool IsReentrant() const { return Counter > 1; }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -59,30 +70,30 @@ public:
class IActionInvocation class IActionInvocation
{ {
public: public:
virtual ~IActionInvocation() throw() {} virtual ~IActionInvocation() throw() {}
virtual void InvokeAction()=0; virtual void InvokeAction() = 0;
}; };
class ICloneable class ICloneable
{ {
public: public:
virtual ICloneable* Clone() const=0; virtual ICloneable *Clone() const = 0;
}; };
class IDeletableObject class IDeletableObject
{ {
public: public:
virtual ~IDeletableObject() throw() {} virtual ~IDeletableObject() throw() {}
virtual void DeleteSelf()=0; virtual void DeleteSelf() = 0;
virtual bool IsBeingDeleted()=0; virtual bool IsBeingDeleted() = 0;
protected: protected:
// This function is GUI implementation dependent! It's implemented by PCSX2's AppHost, // This function is GUI implementation dependent! It's implemented by PCSX2's AppHost,
// but if the SysCore is being linked to another front end, you'll need to implement this // but if the SysCore is being linked to another front end, you'll need to implement this
// yourself. Most GUIs have built in message pumps. If a platform lacks one then you'll // yourself. Most GUIs have built in message pumps. If a platform lacks one then you'll
// need to implement one yourself (yay?). // need to implement one yourself (yay?).
virtual void DoDeletion()=0; virtual void DoDeletion() = 0;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -111,26 +122,26 @@ protected:
class BaseDeletableObject : public virtual IDeletableObject class BaseDeletableObject : public virtual IDeletableObject
{ {
protected: protected:
std::atomic<bool> m_IsBeingDeleted; std::atomic<bool> m_IsBeingDeleted;
public: public:
BaseDeletableObject(); BaseDeletableObject();
virtual ~BaseDeletableObject() throw(); virtual ~BaseDeletableObject() throw();
void DeleteSelf(); void DeleteSelf();
bool IsBeingDeleted() { return !!m_IsBeingDeleted; } bool IsBeingDeleted() { return !!m_IsBeingDeleted; }
// Returns FALSE if the object is already marked for deletion, or TRUE if the app // Returns FALSE if the object is already marked for deletion, or TRUE if the app
// should schedule the object for deletion. Only schedule if TRUE is returned, otherwise // should schedule the object for deletion. Only schedule if TRUE is returned, otherwise
// the object could get deleted twice if two threads try to schedule it at the same time. // the object could get deleted twice if two threads try to schedule it at the same time.
bool MarkForDeletion(); bool MarkForDeletion();
protected: protected:
// This function is GUI implementation dependent! It's implemented by PCSX2's AppHost, // This function is GUI implementation dependent! It's implemented by PCSX2's AppHost,
// but if the SysCore is being linked to another front end, you'll need to implement this // but if the SysCore is being linked to another front end, you'll need to implement this
// yourself. Most GUIs have built in message pumps. If a platform lacks one then you'll // yourself. Most GUIs have built in message pumps. If a platform lacks one then you'll
// need to implement one yourself (yay?). // need to implement one yourself (yay?).
virtual void DoDeletion(); virtual void DoDeletion();
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -139,76 +150,76 @@ protected:
class PageProtectionMode class PageProtectionMode
{ {
protected: protected:
bool m_read; bool m_read;
bool m_write; bool m_write;
bool m_exec; bool m_exec;
public: public:
PageProtectionMode() PageProtectionMode()
{ {
All( false ); All(false);
} }
PageProtectionMode& Read( bool allow=true ) PageProtectionMode &Read(bool allow = true)
{ {
m_read = allow; m_read = allow;
return *this; return *this;
} }
PageProtectionMode& Write( bool allow=true ) PageProtectionMode &Write(bool allow = true)
{ {
m_write = allow; m_write = allow;
return *this; return *this;
} }
PageProtectionMode& Execute( bool allow=true ) PageProtectionMode &Execute(bool allow = true)
{ {
m_exec = allow; m_exec = allow;
return *this; return *this;
} }
PageProtectionMode& All( bool allow=true )
{
m_read = m_write = m_exec = allow;
return *this;
}
bool CanRead() const { return m_read; } PageProtectionMode &All(bool allow = true)
bool CanWrite() const { return m_write; } {
bool CanExecute() const { return m_exec && m_read; } m_read = m_write = m_exec = allow;
bool IsNone() const { return !m_read && !m_write; } return *this;
}
wxString ToString() const;
bool CanRead() const { return m_read; }
bool CanWrite() const { return m_write; }
bool CanExecute() const { return m_exec && m_read; }
bool IsNone() const { return !m_read && !m_write; }
wxString ToString() const;
}; };
static __fi PageProtectionMode PageAccess_None() static __fi PageProtectionMode PageAccess_None()
{ {
return PageProtectionMode(); return PageProtectionMode();
} }
static __fi PageProtectionMode PageAccess_ReadOnly() static __fi PageProtectionMode PageAccess_ReadOnly()
{ {
return PageProtectionMode().Read(); return PageProtectionMode().Read();
} }
static __fi PageProtectionMode PageAccess_WriteOnly() static __fi PageProtectionMode PageAccess_WriteOnly()
{ {
return PageProtectionMode().Write(); return PageProtectionMode().Write();
} }
static __fi PageProtectionMode PageAccess_ReadWrite() static __fi PageProtectionMode PageAccess_ReadWrite()
{ {
return PageAccess_ReadOnly().Write(); return PageAccess_ReadOnly().Write();
} }
static __fi PageProtectionMode PageAccess_ExecOnly() static __fi PageProtectionMode PageAccess_ExecOnly()
{ {
return PageAccess_ReadOnly().Execute(); return PageAccess_ReadOnly().Execute();
} }
static __fi PageProtectionMode PageAccess_Any() static __fi PageProtectionMode PageAccess_Any()
{ {
return PageProtectionMode().All(); return PageProtectionMode().All();
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -218,39 +229,39 @@ static __fi PageProtectionMode PageAccess_Any()
// platform prior to wxWidgets .. it should prolly be removed -- air) // platform prior to wxWidgets .. it should prolly be removed -- air)
namespace HostSys namespace HostSys
{ {
void* MmapReserve(uptr base, size_t size); void *MmapReserve(uptr base, size_t size);
bool MmapCommit(uptr base, size_t size, const PageProtectionMode& mode); bool MmapCommit(uptr base, size_t size, const PageProtectionMode &mode);
void MmapReset(uptr base, size_t size); void MmapReset(uptr base, size_t size);
void* MmapReservePtr(void* base, size_t size); void *MmapReservePtr(void *base, size_t size);
bool MmapCommitPtr(void* base, size_t size, const PageProtectionMode& mode); bool MmapCommitPtr(void *base, size_t size, const PageProtectionMode &mode);
void MmapResetPtr(void* base, size_t size); void MmapResetPtr(void *base, size_t size);
// Maps a block of memory for use as a recompiled code buffer. // Maps a block of memory for use as a recompiled code buffer.
// Returns NULL on allocation failure. // Returns NULL on allocation failure.
extern void* Mmap(uptr base, size_t size); extern void *Mmap(uptr base, size_t size);
// Unmaps a block allocated by SysMmap // Unmaps a block allocated by SysMmap
extern void Munmap(uptr base, size_t size); extern void Munmap(uptr base, size_t size);
extern void MemProtect( void* baseaddr, size_t size, const PageProtectionMode& mode ); extern void MemProtect(void *baseaddr, size_t size, const PageProtectionMode &mode);
extern void Munmap( void* base, size_t size ); extern void Munmap(void *base, size_t size);
template< uint size > template <uint size>
void MemProtectStatic( u8 (&arr)[size], const PageProtectionMode& mode ) void MemProtectStatic(u8 (&arr)[size], const PageProtectionMode &mode)
{ {
MemProtect( arr, size, mode ); MemProtect(arr, size, mode);
} }
} }
// Safe version of Munmap -- NULLs the pointer variable immediately after free'ing it. // Safe version of Munmap -- NULLs the pointer variable immediately after free'ing it.
#define SafeSysMunmap( ptr, size ) \ #define SafeSysMunmap(ptr, size) \
((void) ( HostSys::Munmap( (uptr)(ptr), size ), (ptr) = NULL )) ((void)(HostSys::Munmap((uptr)(ptr), size), (ptr) = NULL))
extern void InitCPUTicks(); extern void InitCPUTicks();
extern u64 GetTickFrequency(); extern u64 GetTickFrequency();
extern u64 GetCPUTicks(); extern u64 GetCPUTicks();
extern u64 GetPhysicalMemory(); extern u64 GetPhysicalMemory();
extern wxString GetOSVersionString(); extern wxString GetOSVersionString();

View File

@ -15,7 +15,8 @@
#pragma once #pragma once
namespace HashTools { namespace HashTools
{
/// <summary> /// <summary>
/// Type that represents a hashcode; returned by all hash functions. /// Type that represents a hashcode; returned by all hash functions.
@ -26,7 +27,5 @@ namespace HashTools {
/// </remarks> /// </remarks>
typedef u32 hash_key_t; typedef u32 hash_key_t;
hash_key_t Hash(const char* data, int len); hash_key_t Hash(const char *data, int len);
} }

View File

@ -21,7 +21,7 @@
#include <wx/gdicmn.h> #include <wx/gdicmn.h>
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// IniInterface (abstract base class) // IniInterface (abstract base class)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// This is used as an interchangable interface for both loading and saving options from an // This is used as an interchangable interface for both loading and saving options from an
// ini/configuration file. The LoadSave code takes an IniInterface, and the interface // ini/configuration file. The LoadSave code takes an IniInterface, and the interface
@ -32,53 +32,57 @@
class IniInterface class IniInterface
{ {
protected: protected:
wxConfigBase* m_Config; wxConfigBase *m_Config;
public: public:
virtual ~IniInterface(); virtual ~IniInterface();
explicit IniInterface(); explicit IniInterface();
explicit IniInterface( wxConfigBase& config ); explicit IniInterface(wxConfigBase &config);
explicit IniInterface( wxConfigBase* config ); explicit IniInterface(wxConfigBase *config);
void SetPath( const wxString& path ); void SetPath(const wxString &path);
void Flush(); void Flush();
wxConfigBase& GetConfig() { pxAssert( m_Config ); return *m_Config; } wxConfigBase &GetConfig()
bool IsOk() const { return m_Config != NULL; } {
pxAssert(m_Config);
return *m_Config;
}
bool IsOk() const { return m_Config != NULL; }
virtual bool IsLoading() const=0; virtual bool IsLoading() const = 0;
bool IsSaving() const { return !IsLoading(); } bool IsSaving() const { return !IsLoading(); }
virtual void Entry( const wxString& var, wxString& value, const wxString defvalue=wxString() )=0; virtual void Entry(const wxString &var, wxString &value, const wxString defvalue = wxString()) = 0;
virtual void Entry( const wxString& var, wxDirName& value, const wxDirName defvalue=wxDirName(), bool isAllowRelative=false )=0; virtual void Entry(const wxString &var, wxDirName &value, const wxDirName defvalue = wxDirName(), bool isAllowRelative = false) = 0;
virtual void Entry( const wxString& var, wxFileName& value, const wxFileName defvalue=wxFileName(), bool isAllowRelative=false )=0; virtual void Entry(const wxString &var, wxFileName &value, const wxFileName defvalue = wxFileName(), bool isAllowRelative = false) = 0;
virtual void Entry( const wxString& var, int& value, const int defvalue=0 )=0; virtual void Entry(const wxString &var, int &value, const int defvalue = 0) = 0;
virtual void Entry( const wxString& var, uint& value, const uint defvalue=0 )=0; virtual void Entry(const wxString &var, uint &value, const uint defvalue = 0) = 0;
virtual void Entry( const wxString& var, bool& value, const bool defvalue=false )=0; virtual void Entry(const wxString &var, bool &value, const bool defvalue = false) = 0;
// This special form of Entry is provided for bitfields, which cannot be passed by reference. // This special form of Entry is provided for bitfields, which cannot be passed by reference.
virtual bool EntryBitBool( const wxString& var, bool value, const bool defvalue=false )=0; virtual bool EntryBitBool(const wxString &var, bool value, const bool defvalue = false) = 0;
virtual int EntryBitfield( const wxString& var, int value, const int defvalue=0 )=0; virtual int EntryBitfield(const wxString &var, int value, const int defvalue = 0) = 0;
virtual void Entry( const wxString& var, Fixed100& value, const Fixed100 defvalue=Fixed100() )=0; virtual void Entry(const wxString &var, Fixed100 &value, const Fixed100 defvalue = Fixed100()) = 0;
virtual void Entry( const wxString& var, wxPoint& value, const wxPoint defvalue=wxDefaultPosition )=0; virtual void Entry(const wxString &var, wxPoint &value, const wxPoint defvalue = wxDefaultPosition) = 0;
virtual void Entry( const wxString& var, wxSize& value, const wxSize defvalue=wxDefaultSize )=0; virtual void Entry(const wxString &var, wxSize &value, const wxSize defvalue = wxDefaultSize) = 0;
virtual void Entry( const wxString& var, wxRect& value, const wxRect defvalue=wxDefaultRect )=0; virtual void Entry(const wxString &var, wxRect &value, const wxRect defvalue = wxDefaultRect) = 0;
template< typename T > template <typename T>
void EnumEntry( const wxString& var, T& value, const wxChar* const* enumArray=NULL, const T defvalue=(T)0 ) void EnumEntry(const wxString &var, T &value, const wxChar *const *enumArray = NULL, const T defvalue = (T)0)
{ {
int tstore = (int)value; int tstore = (int)value;
if( enumArray == NULL ) if (enumArray == NULL)
Entry( var, tstore, defvalue ); Entry(var, tstore, defvalue);
else else
_EnumEntry( var, tstore, enumArray, defvalue ); _EnumEntry(var, tstore, enumArray, defvalue);
value = (T)tstore; value = (T)tstore;
} }
protected: protected:
virtual void _EnumEntry( const wxString& var, int& value, const wxChar* const* enumArray, int defvalue )=0; virtual void _EnumEntry(const wxString &var, int &value, const wxChar *const *enumArray, int defvalue) = 0;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -87,11 +91,11 @@ protected:
class ScopedIniGroup class ScopedIniGroup
{ {
protected: protected:
IniInterface& m_mom; IniInterface &m_mom;
public: public:
ScopedIniGroup( IniInterface& mommy, const wxString& group ); ScopedIniGroup(IniInterface &mommy, const wxString &group);
virtual ~ScopedIniGroup(); virtual ~ScopedIniGroup();
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -105,31 +109,31 @@ public:
class IniLoader : public IniInterface class IniLoader : public IniInterface
{ {
public: public:
virtual ~IniLoader() throw(); virtual ~IniLoader() throw();
explicit IniLoader(); explicit IniLoader();
explicit IniLoader( wxConfigBase& config ); explicit IniLoader(wxConfigBase &config);
explicit IniLoader( wxConfigBase* config ); explicit IniLoader(wxConfigBase *config);
bool IsLoading() const { return true; } bool IsLoading() const { return true; }
void Entry( const wxString& var, wxString& value, const wxString defvalue=wxEmptyString ); void Entry(const wxString &var, wxString &value, const wxString defvalue = wxEmptyString);
void Entry( const wxString& var, wxDirName& value, const wxDirName defvalue=wxDirName(), bool isAllowRelative=false ); void Entry(const wxString &var, wxDirName &value, const wxDirName defvalue = wxDirName(), bool isAllowRelative = false);
void Entry( const wxString& var, wxFileName& value, const wxFileName defvalue=wxFileName(), bool isAllowRelative=false ); void Entry(const wxString &var, wxFileName &value, const wxFileName defvalue = wxFileName(), bool isAllowRelative = false);
void Entry( const wxString& var, int& value, const int defvalue=0 ); void Entry(const wxString &var, int &value, const int defvalue = 0);
void Entry( const wxString& var, uint& value, const uint defvalue=0 ); void Entry(const wxString &var, uint &value, const uint defvalue = 0);
void Entry( const wxString& var, bool& value, const bool defvalue=false ); void Entry(const wxString &var, bool &value, const bool defvalue = false);
bool EntryBitBool( const wxString& var, bool value, const bool defvalue=false ); bool EntryBitBool(const wxString &var, bool value, const bool defvalue = false);
int EntryBitfield( const wxString& var, int value, const int defvalue=0 ); int EntryBitfield(const wxString &var, int value, const int defvalue = 0);
void Entry( const wxString& var, Fixed100& value, const Fixed100 defvalue=Fixed100() ); void Entry(const wxString &var, Fixed100 &value, const Fixed100 defvalue = Fixed100());
void Entry( const wxString& var, wxPoint& value, const wxPoint defvalue=wxDefaultPosition ); void Entry(const wxString &var, wxPoint &value, const wxPoint defvalue = wxDefaultPosition);
void Entry( const wxString& var, wxSize& value, const wxSize defvalue=wxDefaultSize ); void Entry(const wxString &var, wxSize &value, const wxSize defvalue = wxDefaultSize);
void Entry( const wxString& var, wxRect& value, const wxRect defvalue=wxDefaultRect ); void Entry(const wxString &var, wxRect &value, const wxRect defvalue = wxDefaultRect);
protected: protected:
void _EnumEntry( const wxString& var, int& value, const wxChar* const* enumArray, int defvalue ); void _EnumEntry(const wxString &var, int &value, const wxChar *const *enumArray, int defvalue);
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -143,45 +147,45 @@ protected:
class IniSaver : public IniInterface class IniSaver : public IniInterface
{ {
public: public:
virtual ~IniSaver(); virtual ~IniSaver();
explicit IniSaver(); explicit IniSaver();
explicit IniSaver( wxConfigBase& config ); explicit IniSaver(wxConfigBase &config);
explicit IniSaver( wxConfigBase* config ); explicit IniSaver(wxConfigBase *config);
bool IsLoading() const { return false; } bool IsLoading() const { return false; }
void Entry( const wxString& var, wxString& value, const wxString defvalue=wxString() ); void Entry(const wxString &var, wxString &value, const wxString defvalue = wxString());
void Entry( const wxString& var, wxDirName& value, const wxDirName defvalue=wxDirName(), bool isAllowRelative=false ); void Entry(const wxString &var, wxDirName &value, const wxDirName defvalue = wxDirName(), bool isAllowRelative = false);
void Entry( const wxString& var, wxFileName& value, const wxFileName defvalue=wxFileName(), bool isAllowRelative=false ); void Entry(const wxString &var, wxFileName &value, const wxFileName defvalue = wxFileName(), bool isAllowRelative = false);
void Entry( const wxString& var, int& value, const int defvalue=0 ); void Entry(const wxString &var, int &value, const int defvalue = 0);
void Entry( const wxString& var, uint& value, const uint defvalue=0 ); void Entry(const wxString &var, uint &value, const uint defvalue = 0);
void Entry( const wxString& var, bool& value, const bool defvalue=false ); void Entry(const wxString &var, bool &value, const bool defvalue = false);
bool EntryBitBool( const wxString& var, bool value, const bool defvalue=false ); bool EntryBitBool(const wxString &var, bool value, const bool defvalue = false);
int EntryBitfield( const wxString& var, int value, const int defvalue=0 ); int EntryBitfield(const wxString &var, int value, const int defvalue = 0);
void Entry( const wxString& var, Fixed100& value, const Fixed100 defvalue=Fixed100() ); void Entry(const wxString &var, Fixed100 &value, const Fixed100 defvalue = Fixed100());
void Entry( const wxString& var, wxPoint& value, const wxPoint defvalue=wxDefaultPosition ); void Entry(const wxString &var, wxPoint &value, const wxPoint defvalue = wxDefaultPosition);
void Entry( const wxString& var, wxSize& value, const wxSize defvalue=wxDefaultSize ); void Entry(const wxString &var, wxSize &value, const wxSize defvalue = wxDefaultSize);
void Entry( const wxString& var, wxRect& value, const wxRect defvalue=wxDefaultRect ); void Entry(const wxString &var, wxRect &value, const wxRect defvalue = wxDefaultRect);
protected: protected:
void _EnumEntry( const wxString& var, int& value, const wxChar* const* enumArray, int defvalue ); void _EnumEntry(const wxString &var, int &value, const wxChar *const *enumArray, int defvalue);
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// GCC Note: wxT() macro is required when using string token pasting. For some reason L generates // GCC Note: wxT() macro is required when using string token pasting. For some reason L generates
// syntax errors. >_< // syntax errors. >_<
// //
#define IniEntry( varname ) ini.Entry( wxT(#varname), varname, varname ) #define IniEntry(varname) ini.Entry(wxT(#varname), varname, varname)
#define IniEntryDirFile( varname, isAllowRelative ) ini.Entry( wxT(#varname), varname, varname, isAllowRelative ) #define IniEntryDirFile(varname, isAllowRelative) ini.Entry(wxT(#varname), varname, varname, isAllowRelative)
#define IniBitfield( varname ) varname = ini.EntryBitfield( wxT(#varname), varname, varname ) #define IniBitfield(varname) varname = ini.EntryBitfield(wxT(#varname), varname, varname)
#define IniBitBool( varname ) varname = ini.EntryBitBool( wxT(#varname), !!varname, varname ) #define IniBitBool(varname) varname = ini.EntryBitBool(wxT(#varname), !!varname, varname)
#define IniBitfieldEx( varname, textname ) varname = ini.EntryBitfield( wxT(textname), varname, varname ) #define IniBitfieldEx(varname, textname) varname = ini.EntryBitfield(wxT(textname), varname, varname)
#define IniBitBoolEx( varname, textname ) varname = ini.EntryBitBool( wxT(textname), !!varname, varname ) #define IniBitBoolEx(varname, textname) varname = ini.EntryBitBool(wxT(textname), !!varname, varname)
//used for filenames and folder names as ini values. //used for filenames and folder names as ini values.
//Set to app root folder, so all files and folders which are inside appRoot will be written as relative. //Set to app root folder, so all files and folders which are inside appRoot will be written as relative.
void SetFullBaseDir( wxDirName appRoot ); void SetFullBaseDir(wxDirName appRoot);

View File

@ -20,22 +20,22 @@
#include "Pcsx2Defs.h" #include "Pcsx2Defs.h"
// On GCC >= 4.7, this is equivalent to __builtin_clrsb(n); // On GCC >= 4.7, this is equivalent to __builtin_clrsb(n);
inline u32 count_leading_sign_bits(s32 n) { inline u32 count_leading_sign_bits(s32 n)
// If the sign bit is 1, we invert the bits to 0 for count-leading-zero. {
if (n < 0) // If the sign bit is 1, we invert the bits to 0 for count-leading-zero.
n = ~n; if (n < 0)
n = ~n;
// If BSR is used directly, it would have an undefined value for 0. // If BSR is used directly, it would have an undefined value for 0.
if (n == 0) if (n == 0)
return 32; return 32;
// Perform our count leading zero. // Perform our count leading zero.
#ifdef _MSC_VER #ifdef _MSC_VER
unsigned long ret; unsigned long ret;
_BitScanReverse(&ret, n); _BitScanReverse(&ret, n);
return 31 - (u32)ret; return 31 - (u32)ret;
#else #else
return __builtin_clz(n); return __builtin_clz(n);
#endif #endif
} }

View File

@ -16,15 +16,15 @@
#pragma once #pragma once
#if defined(__POSIX__) #if defined(__POSIX__)
# include "lnx_memzero.h" #include "lnx_memzero.h"
#else #else
# include "win_memzero.h" #include "win_memzero.h"
#endif #endif
// For 32-bit MSVC compiles, memcmp performs much worse than memcmp_mmx and // For 32-bit MSVC compiles, memcmp performs much worse than memcmp_mmx and
// other implementations. So for this combination only, prefer memcmp_mmx // other implementations. So for this combination only, prefer memcmp_mmx
#if defined(_MSC_VER) && !defined(_M_X86_64) #if defined(_MSC_VER) && !defined(_M_X86_64)
extern u8 memcmp_mmx(const void* src1, const void* src2, int cmpsize); extern u8 memcmp_mmx(const void *src1, const void *src2, int cmpsize);
#else #else
#define memcmp_mmx memcmp #define memcmp_mmx memcmp
#endif #endif

View File

@ -17,69 +17,67 @@
#include <xmmintrin.h> #include <xmmintrin.h>
#define StoreDestIdx(idx) case idx: _mm_store_ps(&destxmm[idx-1][0], srcreg) #define StoreDestIdx(idx) \
case idx: \
template< u8 data > _mm_store_ps(&destxmm[idx - 1][0], srcreg)
__noinline void memset_sse_a( void* dest, const size_t size )
template <u8 data>
__noinline void memset_sse_a(void *dest, const size_t size)
{ {
const uint MZFqwc = size / 16; const uint MZFqwc = size / 16;
pxAssert( (size & 0xf) == 0 ); pxAssert((size & 0xf) == 0);
__m128 srcreg; __m128 srcreg;
if (data != 0) if (data != 0) {
{ static __aligned16 const u8 loadval[8] = {data, data, data, data, data, data, data, data};
static __aligned16 const u8 loadval[8] = { data,data,data,data,data,data,data,data }; srcreg = _mm_loadh_pi(_mm_load_ps((float *)loadval), (__m64 *)loadval);
srcreg = _mm_loadh_pi( _mm_load_ps( (float*)loadval ), (__m64*)loadval ); } else
} srcreg = _mm_setzero_ps();
else
srcreg = _mm_setzero_ps();
float (*destxmm)[4] = (float(*)[4])dest; float(*destxmm)[4] = (float(*)[4])dest;
switch( MZFqwc & 0x07 ) switch (MZFqwc & 0x07) {
{ StoreDestIdx(0x07);
StoreDestIdx(0x07); StoreDestIdx(0x06);
StoreDestIdx(0x06); StoreDestIdx(0x05);
StoreDestIdx(0x05); StoreDestIdx(0x04);
StoreDestIdx(0x04); StoreDestIdx(0x03);
StoreDestIdx(0x03); StoreDestIdx(0x02);
StoreDestIdx(0x02); StoreDestIdx(0x01);
StoreDestIdx(0x01); }
}
destxmm += (MZFqwc & 0x07); destxmm += (MZFqwc & 0x07);
for( uint i=0; i<MZFqwc / 8; ++i, destxmm+=8 ) for (uint i = 0; i < MZFqwc / 8; ++i, destxmm += 8) {
{ _mm_store_ps(&destxmm[0][0], srcreg);
_mm_store_ps(&destxmm[0][0], srcreg); _mm_store_ps(&destxmm[1][0], srcreg);
_mm_store_ps(&destxmm[1][0], srcreg); _mm_store_ps(&destxmm[2][0], srcreg);
_mm_store_ps(&destxmm[2][0], srcreg); _mm_store_ps(&destxmm[3][0], srcreg);
_mm_store_ps(&destxmm[3][0], srcreg); _mm_store_ps(&destxmm[4][0], srcreg);
_mm_store_ps(&destxmm[4][0], srcreg); _mm_store_ps(&destxmm[5][0], srcreg);
_mm_store_ps(&destxmm[5][0], srcreg); _mm_store_ps(&destxmm[6][0], srcreg);
_mm_store_ps(&destxmm[6][0], srcreg); _mm_store_ps(&destxmm[7][0], srcreg);
_mm_store_ps(&destxmm[7][0], srcreg); }
}
}; };
static __fi void memzero_sse_a( void* dest, const size_t size ) static __fi void memzero_sse_a(void *dest, const size_t size)
{ {
memset_sse_a<0>( dest, size ); memset_sse_a<0>(dest, size);
} }
#undef StoreDestIdx #undef StoreDestIdx
template< u8 data, typename T > template <u8 data, typename T>
__noinline void memset_sse_a( T& dest ) __noinline void memset_sse_a(T &dest)
{ {
static_assert( (sizeof(dest) & 0xf) == 0, "Bad size for SSE memset" ); static_assert((sizeof(dest) & 0xf) == 0, "Bad size for SSE memset");
memset_sse_a<data>( &dest, sizeof(dest) ); memset_sse_a<data>(&dest, sizeof(dest));
} }
template< typename T > template <typename T>
void memzero_sse_a( T& dest ) void memzero_sse_a(T &dest)
{ {
static_assert( (sizeof(dest) & 0xf) == 0, "Bad size for SSE memset" ); static_assert((sizeof(dest) & 0xf) == 0, "Bad size for SSE memset");
memset_sse_a<0>( &dest, sizeof(dest) ); memset_sse_a<0>(&dest, sizeof(dest));
} }

View File

@ -28,12 +28,12 @@
struct PageFaultInfo struct PageFaultInfo
{ {
uptr addr; uptr addr;
PageFaultInfo( uptr address ) PageFaultInfo(uptr address)
{ {
addr = address; addr = address;
} }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -42,22 +42,22 @@ struct PageFaultInfo
class IEventListener_PageFault : public IEventDispatcher<PageFaultInfo> class IEventListener_PageFault : public IEventDispatcher<PageFaultInfo>
{ {
public: public:
typedef PageFaultInfo EvtParams; typedef PageFaultInfo EvtParams;
public: public:
virtual ~IEventListener_PageFault() throw() {} virtual ~IEventListener_PageFault() throw() {}
virtual void DispatchEvent( const PageFaultInfo& evtinfo, bool& handled ) virtual void DispatchEvent(const PageFaultInfo &evtinfo, bool &handled)
{ {
OnPageFaultEvent( evtinfo, handled ); OnPageFaultEvent(evtinfo, handled);
} }
virtual void DispatchEvent( const PageFaultInfo& evtinfo ) virtual void DispatchEvent(const PageFaultInfo &evtinfo)
{ {
pxFailRel( "Don't call me, damnit. Use DispatchException instead." ); pxFailRel("Don't call me, damnit. Use DispatchException instead.");
} }
virtual void OnPageFaultEvent( const PageFaultInfo& evtinfo, bool& handled ) {} virtual void OnPageFaultEvent(const PageFaultInfo &evtinfo, bool &handled) {}
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -66,35 +66,34 @@ public:
class EventListener_PageFault : public IEventListener_PageFault class EventListener_PageFault : public IEventListener_PageFault
{ {
public: public:
EventListener_PageFault(); EventListener_PageFault();
virtual ~EventListener_PageFault() throw(); virtual ~EventListener_PageFault() throw();
}; };
template< typename TypeToDispatchTo > template <typename TypeToDispatchTo>
class EventListenerHelper_PageFault : public EventListener_PageFault class EventListenerHelper_PageFault : public EventListener_PageFault
{ {
public: public:
TypeToDispatchTo* Owner; TypeToDispatchTo *Owner;
public: public:
EventListenerHelper_PageFault( TypeToDispatchTo& dispatchTo ) EventListenerHelper_PageFault(TypeToDispatchTo &dispatchTo)
{ {
Owner = &dispatchTo; Owner = &dispatchTo;
} }
EventListenerHelper_PageFault( TypeToDispatchTo* dispatchTo ) EventListenerHelper_PageFault(TypeToDispatchTo *dispatchTo)
{ {
Owner = dispatchTo; Owner = dispatchTo;
} }
virtual ~EventListenerHelper_PageFault() throw() {} virtual ~EventListenerHelper_PageFault() throw() {}
protected: protected:
virtual void OnPageFaultEvent( const PageFaultInfo& info, bool& handled ) virtual void OnPageFaultEvent(const PageFaultInfo &info, bool &handled)
{ {
Owner->OnPageFaultEvent( info, handled ); Owner->OnPageFaultEvent(info, handled);
} }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -103,20 +102,23 @@ protected:
class SrcType_PageFault : public EventSource<IEventListener_PageFault> class SrcType_PageFault : public EventSource<IEventListener_PageFault>
{ {
protected: protected:
typedef EventSource<IEventListener_PageFault> _parent; typedef EventSource<IEventListener_PageFault> _parent;
protected: protected:
bool m_handled; bool m_handled;
public: public:
SrcType_PageFault() : m_handled(false) {} SrcType_PageFault()
virtual ~SrcType_PageFault() throw() { } : m_handled(false)
{
}
virtual ~SrcType_PageFault() throw() {}
bool WasHandled() const { return m_handled; } bool WasHandled() const { return m_handled; }
virtual void Dispatch( const PageFaultInfo& params ); virtual void Dispatch(const PageFaultInfo &params);
protected: protected:
virtual void _DispatchRaw( ListenerIterator iter, const ListenerIterator& iend, const PageFaultInfo& evt ); virtual void _DispatchRaw(ListenerIterator iter, const ListenerIterator &iend, const PageFaultInfo &evt);
}; };
@ -125,92 +127,92 @@ protected:
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class VirtualMemoryReserve class VirtualMemoryReserve
{ {
DeclareNoncopyableObject( VirtualMemoryReserve ); DeclareNoncopyableObject(VirtualMemoryReserve);
protected: protected:
wxString m_name; wxString m_name;
// Default size of the reserve, in bytes. Can be specified when the object is constructed. // Default size of the reserve, in bytes. Can be specified when the object is constructed.
// Is used as the reserve size when Reserve() is called, unless an override is specified // Is used as the reserve size when Reserve() is called, unless an override is specified
// in the Reserve parameters. // in the Reserve parameters.
size_t m_defsize; size_t m_defsize;
void* m_baseptr; void *m_baseptr;
// reserved memory (in pages). // reserved memory (in pages).
uptr m_pages_reserved; uptr m_pages_reserved;
// Records the number of pages committed to memory. // Records the number of pages committed to memory.
// (metric for analysis of buffer usage) // (metric for analysis of buffer usage)
uptr m_pages_commited; uptr m_pages_commited;
// Protection mode to be applied to committed blocks. // Protection mode to be applied to committed blocks.
PageProtectionMode m_prot_mode; PageProtectionMode m_prot_mode;
// Controls write access to the entire reserve. When true (the default), the reserve // Controls write access to the entire reserve. When true (the default), the reserve
// operates normally. When set to false, all committed blocks are re-protected with // operates normally. When set to false, all committed blocks are re-protected with
// write disabled, and accesses to uncommitted blocks (read or write) will cause a GPF // write disabled, and accesses to uncommitted blocks (read or write) will cause a GPF
// as well. // as well.
bool m_allow_writes; bool m_allow_writes;
public: public:
VirtualMemoryReserve( const wxString& name=wxEmptyString, size_t size = 0 ); VirtualMemoryReserve(const wxString &name = wxEmptyString, size_t size = 0);
virtual ~VirtualMemoryReserve() throw() virtual ~VirtualMemoryReserve() throw()
{ {
Release(); Release();
} }
virtual void* Reserve( size_t size = 0, uptr base = 0, uptr upper_bounds = 0 ); virtual void *Reserve(size_t size = 0, uptr base = 0, uptr upper_bounds = 0);
virtual void* ReserveAt( uptr base = 0, uptr upper_bounds = 0 ) virtual void *ReserveAt(uptr base = 0, uptr upper_bounds = 0)
{ {
return Reserve(m_defsize, base, upper_bounds); return Reserve(m_defsize, base, upper_bounds);
} }
virtual void Reset(); virtual void Reset();
virtual void Release(); virtual void Release();
virtual bool TryResize( uint newsize ); virtual bool TryResize(uint newsize);
virtual bool Commit(); virtual bool Commit();
virtual void ForbidModification();
virtual void AllowModification();
bool IsOk() const { return m_baseptr != NULL; } virtual void ForbidModification();
wxString GetName() const { return m_name; } virtual void AllowModification();
uptr GetReserveSizeInBytes() const { return m_pages_reserved * __pagesize; } bool IsOk() const { return m_baseptr != NULL; }
uptr GetReserveSizeInPages() const { return m_pages_reserved; } wxString GetName() const { return m_name; }
uint GetCommittedPageCount() const { return m_pages_commited; }
uint GetCommittedBytes() const { return m_pages_commited * __pagesize; }
u8* GetPtr() { return (u8*)m_baseptr; } uptr GetReserveSizeInBytes() const { return m_pages_reserved * __pagesize; }
const u8* GetPtr() const { return (u8*)m_baseptr; } uptr GetReserveSizeInPages() const { return m_pages_reserved; }
u8* GetPtrEnd() { return (u8*)m_baseptr + (m_pages_reserved * __pagesize); } uint GetCommittedPageCount() const { return m_pages_commited; }
const u8* GetPtrEnd() const { return (u8*)m_baseptr + (m_pages_reserved * __pagesize); } uint GetCommittedBytes() const { return m_pages_commited * __pagesize; }
VirtualMemoryReserve& SetName( const wxString& newname ); u8 *GetPtr() { return (u8 *)m_baseptr; }
VirtualMemoryReserve& SetBaseAddr( uptr newaddr ); const u8 *GetPtr() const { return (u8 *)m_baseptr; }
VirtualMemoryReserve& SetPageAccessOnCommit( const PageProtectionMode& mode ); u8 *GetPtrEnd() { return (u8 *)m_baseptr + (m_pages_reserved * __pagesize); }
const u8 *GetPtrEnd() const { return (u8 *)m_baseptr + (m_pages_reserved * __pagesize); }
operator void*() { return m_baseptr; } VirtualMemoryReserve &SetName(const wxString &newname);
operator const void*() const { return m_baseptr; } VirtualMemoryReserve &SetBaseAddr(uptr newaddr);
VirtualMemoryReserve &SetPageAccessOnCommit(const PageProtectionMode &mode);
operator u8*() { return (u8*)m_baseptr; } operator void *() { return m_baseptr; }
operator const u8*() const { return (u8*)m_baseptr; } operator const void *() const { return m_baseptr; }
u8& operator[](uint idx) operator u8 *() { return (u8 *)m_baseptr; }
{ operator const u8 *() const { return (u8 *)m_baseptr; }
pxAssert(idx < (m_pages_reserved * __pagesize));
return *((u8*)m_baseptr + idx);
}
const u8& operator[](uint idx) const u8 &operator[](uint idx)
{ {
pxAssert(idx < (m_pages_reserved * __pagesize)); pxAssert(idx < (m_pages_reserved * __pagesize));
return *((u8*)m_baseptr + idx); return *((u8 *)m_baseptr + idx);
} }
const u8 &operator[](uint idx) const
{
pxAssert(idx < (m_pages_reserved * __pagesize));
return *((u8 *)m_baseptr + idx);
}
protected: protected:
virtual void ReprotectCommittedBlocks( const PageProtectionMode& newmode ); virtual void ReprotectCommittedBlocks(const PageProtectionMode &newmode);
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -218,80 +220,79 @@ protected:
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class BaseVmReserveListener : public VirtualMemoryReserve class BaseVmReserveListener : public VirtualMemoryReserve
{ {
DeclareNoncopyableObject( BaseVmReserveListener ); DeclareNoncopyableObject(BaseVmReserveListener);
typedef VirtualMemoryReserve _parent; typedef VirtualMemoryReserve _parent;
protected: protected:
EventListenerHelper_PageFault<BaseVmReserveListener> m_pagefault_listener; EventListenerHelper_PageFault<BaseVmReserveListener> m_pagefault_listener;
// Incremental size by which the buffer grows (in pages) // Incremental size by which the buffer grows (in pages)
uptr m_blocksize; uptr m_blocksize;
public: public:
BaseVmReserveListener( const wxString& name, size_t size = 0 ); BaseVmReserveListener(const wxString &name, size_t size = 0);
virtual ~BaseVmReserveListener() throw() { } virtual ~BaseVmReserveListener() throw() {}
operator void*() { return m_baseptr; } operator void *() { return m_baseptr; }
operator const void*() const { return m_baseptr; } operator const void *() const { return m_baseptr; }
operator u8*() { return (u8*)m_baseptr; } operator u8 *() { return (u8 *)m_baseptr; }
operator const u8*() const { return (u8*)m_baseptr; } operator const u8 *() const { return (u8 *)m_baseptr; }
using _parent::operator[]; using _parent::operator[];
void OnPageFaultEvent( const PageFaultInfo& info, bool& handled ); void OnPageFaultEvent(const PageFaultInfo &info, bool &handled);
virtual uptr SetBlockSize( uptr bytes ) virtual uptr SetBlockSize(uptr bytes)
{ {
m_blocksize = (bytes + __pagesize - 1) / __pagesize; m_blocksize = (bytes + __pagesize - 1) / __pagesize;
return m_blocksize * __pagesize; return m_blocksize * __pagesize;
} }
virtual void Reset()
{
_parent::Reset();
}
virtual void Reset()
{
_parent::Reset();
}
protected: protected:
// This function is called from OnPageFaultEvent after the address has been translated
// and confirmed to apply to this reserved area in question. OnPageFaultEvent contains
// a try/catch exception handler, which ensures "reasonable" error response behavior if
// this function throws exceptions.
//
// Important: This method is called from the context of an exception/signal handler. On
// Windows this isn't a big deal (most operations are ok). On Linux, however, logging
// and other facilities are probably not a good idea.
virtual void DoCommitAndProtect(uptr offset) = 0;
// This function is called from OnPageFaultEvent after the address has been translated // This function is called for every committed block.
// and confirmed to apply to this reserved area in question. OnPageFaultEvent contains virtual void OnCommittedBlock(void *block) = 0;
// a try/catch exception handler, which ensures "reasonable" error response behavior if
// this function throws exceptions.
//
// Important: This method is called from the context of an exception/signal handler. On
// Windows this isn't a big deal (most operations are ok). On Linux, however, logging
// and other facilities are probably not a good idea.
virtual void DoCommitAndProtect( uptr offset )=0;
// This function is called for every committed block. virtual void CommitBlocks(uptr page, uint blocks);
virtual void OnCommittedBlock( void* block )=0;
virtual void CommitBlocks( uptr page, uint blocks );
}; };
#ifdef __POSIX__ #ifdef __POSIX__
# define PCSX2_PAGEFAULT_PROTECT #define PCSX2_PAGEFAULT_PROTECT
# define PCSX2_PAGEFAULT_EXCEPT #define PCSX2_PAGEFAULT_EXCEPT
#elif defined( _WIN32 ) #elif defined(_WIN32)
struct _EXCEPTION_POINTERS; struct _EXCEPTION_POINTERS;
extern int SysPageFaultExceptionFilter(struct _EXCEPTION_POINTERS* eps); extern int SysPageFaultExceptionFilter(struct _EXCEPTION_POINTERS *eps);
# define PCSX2_PAGEFAULT_PROTECT __try #define PCSX2_PAGEFAULT_PROTECT __try
# define PCSX2_PAGEFAULT_EXCEPT __except(SysPageFaultExceptionFilter(GetExceptionInformation())) {} #define PCSX2_PAGEFAULT_EXCEPT \
__except (SysPageFaultExceptionFilter(GetExceptionInformation())) {}
#else #else
# error PCSX2 - Unsupported operating system platform. #error PCSX2 - Unsupported operating system platform.
#endif #endif
extern void pxInstallSignalHandler(); extern void pxInstallSignalHandler();
extern void _platform_InstallSignalHandler(); extern void _platform_InstallSignalHandler();
#include "Threading.h" #include "Threading.h"
extern SrcType_PageFault* Source_PageFault; extern SrcType_PageFault *Source_PageFault;
extern Threading::Mutex PageFault_Mutex; extern Threading::Mutex PageFault_Mutex;

View File

@ -18,7 +18,7 @@
#include <wx/filename.h> #include <wx/filename.h>
#include "StringHelpers.h" #include "StringHelpers.h"
#define g_MaxPath 255 // 255 is safer with antiquated Win32 ASCII APIs. #define g_MaxPath 255 // 255 is safer with antiquated Win32 ASCII APIs.
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// wxDirName // wxDirName
@ -26,164 +26,180 @@
class wxDirName : protected wxFileName class wxDirName : protected wxFileName
{ {
public: public:
explicit wxDirName( const wxFileName& src ) explicit wxDirName(const wxFileName &src)
{ {
Assign( src.GetPath(), wxEmptyString ); Assign(src.GetPath(), wxEmptyString);
} }
wxDirName() : wxFileName() {} wxDirName()
wxDirName( const wxDirName& src ) : wxFileName( src ) { } : wxFileName()
explicit wxDirName( const char* src ) { Assign( fromUTF8(src) ); } {
explicit wxDirName( const wxString& src ) { Assign( src ); } }
wxDirName(const wxDirName &src)
: wxFileName(src)
{
}
explicit wxDirName(const char *src) { Assign(fromUTF8(src)); }
explicit wxDirName(const wxString &src) { Assign(src); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void Assign( const wxString& volume, const wxString& path ) void Assign(const wxString &volume, const wxString &path)
{ {
wxFileName::Assign( volume, path, wxEmptyString ); wxFileName::Assign(volume, path, wxEmptyString);
} }
void Assign( const wxString& path ) void Assign(const wxString &path)
{ {
wxFileName::Assign( path, wxEmptyString ); wxFileName::Assign(path, wxEmptyString);
} }
void Assign( const wxDirName& path ) void Assign(const wxDirName &path)
{ {
wxFileName::Assign( path ); wxFileName::Assign(path);
} }
void Clear() { wxFileName::Clear(); } void Clear() { wxFileName::Clear(); }
wxCharBuffer ToUTF8() const { return GetPath().ToUTF8(); } wxCharBuffer ToUTF8() const { return GetPath().ToUTF8(); }
wxCharBuffer ToAscii() const { return GetPath().ToAscii(); } wxCharBuffer ToAscii() const { return GetPath().ToAscii(); }
wxString ToString() const { return GetPath(); } wxString ToString() const { return GetPath(); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
bool IsWritable() const { return IsDirWritable(); } bool IsWritable() const { return IsDirWritable(); }
bool IsReadable() const { return IsDirReadable(); } bool IsReadable() const { return IsDirReadable(); }
bool Exists() const { return DirExists(); } bool Exists() const { return DirExists(); }
bool FileExists() const { return wxFileName::FileExists(); } bool FileExists() const { return wxFileName::FileExists(); }
bool IsOk() const { return wxFileName::IsOk(); } bool IsOk() const { return wxFileName::IsOk(); }
bool IsRelative() const { return wxFileName::IsRelative(); } bool IsRelative() const { return wxFileName::IsRelative(); }
bool IsAbsolute() const { return wxFileName::IsAbsolute(); } bool IsAbsolute() const { return wxFileName::IsAbsolute(); }
bool SameAs( const wxDirName& filepath ) const bool SameAs(const wxDirName &filepath) const
{ {
return wxFileName::SameAs( filepath ); return wxFileName::SameAs(filepath);
} }
//Returns true if the file is somewhere inside this directory (and both file and directory are not relative). //Returns true if the file is somewhere inside this directory (and both file and directory are not relative).
bool IsContains( const wxFileName& file ) const bool IsContains(const wxFileName &file) const
{ {
if( this->IsRelative() || file.IsRelative() ) if (this->IsRelative() || file.IsRelative())
return false; return false;
wxFileName f( file ); wxFileName f(file);
while( 1 ) while (1) {
{ if (this->SameAs(wxDirName(f.GetPath())))
if( this->SameAs( wxDirName(f.GetPath()) ) ) return true;
return true;
if( f.GetDirCount() == 0 ) if (f.GetDirCount() == 0)
return false; return false;
f.RemoveLastDir(); f.RemoveLastDir();
} }
return false; return false;
} }
bool IsContains( const wxDirName& dir ) const bool IsContains(const wxDirName &dir) const
{ {
return IsContains( (wxFileName)dir ); return IsContains((wxFileName)dir);
} }
//Auto relative works as follows: //Auto relative works as follows:
// 1. if either base or subject are relative, return subject (should never be used with relative paths). // 1. if either base or subject are relative, return subject (should never be used with relative paths).
// 2. else if subject is somewhere inside base folder, then result is subject relative to base. // 2. else if subject is somewhere inside base folder, then result is subject relative to base.
// 3. (windows only, implicitly) else if subject is on the same driveletter as base, result is absolute path of subject without the driveletter. // 3. (windows only, implicitly) else if subject is on the same driveletter as base, result is absolute path of subject without the driveletter.
// 4. else, result is absolute path of subject. // 4. else, result is absolute path of subject.
// //
// returns ok if both this and base are absolute paths. // returns ok if both this and base are absolute paths.
static wxString MakeAutoRelativeTo(const wxFileName _subject, const wxString& pathbase) static wxString MakeAutoRelativeTo(const wxFileName _subject, const wxString &pathbase)
{ {
wxFileName subject( _subject ); wxFileName subject(_subject);
wxDirName base ( pathbase ); wxDirName base(pathbase);
if( base.IsRelative() || subject.IsRelative() ) if (base.IsRelative() || subject.IsRelative())
return subject.GetFullPath(); return subject.GetFullPath();
wxString bv( base.GetVolume() ); bv.MakeUpper(); wxString bv(base.GetVolume());
wxString sv( subject.GetVolume() ); sv.MakeUpper(); bv.MakeUpper();
wxString sv(subject.GetVolume());
sv.MakeUpper();
if( base.IsContains( subject ) ) if (base.IsContains(subject)) {
{ subject.MakeRelativeTo(base.GetFullPath());
subject.MakeRelativeTo( base.GetFullPath() ); } else if (base.HasVolume() && subject.HasVolume() && bv == sv) {
} wxString unusedVolume;
else if( base.HasVolume() && subject.HasVolume() && bv == sv ) wxString pathSansVolume;
{ subject.SplitVolume(subject.GetFullPath(), &unusedVolume, &pathSansVolume);
wxString unusedVolume; subject = pathSansVolume;
wxString pathSansVolume; }
subject.SplitVolume(subject.GetFullPath(), &unusedVolume, &pathSansVolume); //implicit else: this stays fully absolute
subject = pathSansVolume;
}
//implicit else: this stays fully absolute
return subject.GetFullPath(); return subject.GetFullPath();
} }
static wxString MakeAutoRelativeTo(const wxDirName subject, const wxString& pathbase) static wxString MakeAutoRelativeTo(const wxDirName subject, const wxString &pathbase)
{ {
return MakeAutoRelativeTo( wxFileName( subject ), pathbase ); return MakeAutoRelativeTo(wxFileName(subject), pathbase);
} }
// Returns the number of sub folders in this directory path // Returns the number of sub folders in this directory path
size_t GetCount() const { return GetDirCount(); } size_t GetCount() const { return GetDirCount(); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
wxFileName Combine( const wxFileName& right ) const; wxFileName Combine(const wxFileName &right) const;
wxDirName Combine( const wxDirName& right ) const; wxDirName Combine(const wxDirName &right) const;
// removes the lastmost directory from the path // removes the lastmost directory from the path
void RemoveLast() { wxFileName::RemoveDir(GetCount() - 1); } void RemoveLast() { wxFileName::RemoveDir(GetCount() - 1); }
wxDirName& Normalize( int flags = wxPATH_NORM_ALL, const wxString& cwd = wxEmptyString ); wxDirName &Normalize(int flags = wxPATH_NORM_ALL, const wxString &cwd = wxEmptyString);
wxDirName& MakeRelativeTo( const wxString& pathBase = wxEmptyString ); wxDirName &MakeRelativeTo(const wxString &pathBase = wxEmptyString);
wxDirName& MakeAbsolute( const wxString& cwd = wxEmptyString ); wxDirName &MakeAbsolute(const wxString &cwd = wxEmptyString);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void AssignCwd( const wxString& volume = wxEmptyString ) { wxFileName::AssignCwd( volume ); } void AssignCwd(const wxString &volume = wxEmptyString) { wxFileName::AssignCwd(volume); }
bool SetCwd() { return wxFileName::SetCwd(); } bool SetCwd() { return wxFileName::SetCwd(); }
// wxWidgets is missing the const qualifier for this one! Shame! // wxWidgets is missing the const qualifier for this one! Shame!
void Rmdir(); void Rmdir();
bool Mkdir(); bool Mkdir();
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
wxDirName& operator=(const wxDirName& dirname) { Assign( dirname ); return *this; } wxDirName &operator=(const wxDirName &dirname)
wxDirName& operator=(const wxString& dirname) { Assign( dirname ); return *this; } {
wxDirName& operator=(const char* dirname) { Assign( fromUTF8(dirname) ); return *this; } Assign(dirname);
return *this;
}
wxDirName &operator=(const wxString &dirname)
{
Assign(dirname);
return *this;
}
wxDirName &operator=(const char *dirname)
{
Assign(fromUTF8(dirname));
return *this;
}
wxFileName operator+( const wxFileName& right ) const { return Combine( right ); } wxFileName operator+(const wxFileName &right) const { return Combine(right); }
wxDirName operator+( const wxDirName& right ) const { return Combine( right ); } wxDirName operator+(const wxDirName &right) const { return Combine(right); }
wxFileName operator+( const wxString& right ) const { return Combine( wxFileName(right) ); } wxFileName operator+(const wxString &right) const { return Combine(wxFileName(right)); }
wxFileName operator+( const char* right ) const { return Combine( wxFileName(fromUTF8(right)) ); } wxFileName operator+(const char *right) const { return Combine(wxFileName(fromUTF8(right))); }
bool operator==(const wxDirName& filename) const { return SameAs(filename); } bool operator==(const wxDirName &filename) const { return SameAs(filename); }
bool operator!=(const wxDirName& filename) const { return !SameAs(filename); } bool operator!=(const wxDirName &filename) const { return !SameAs(filename); }
bool operator==(const wxFileName& filename) const { return SameAs(wxDirName(filename)); } bool operator==(const wxFileName &filename) const { return SameAs(wxDirName(filename)); }
bool operator!=(const wxFileName& filename) const { return !SameAs(wxDirName(filename)); } bool operator!=(const wxFileName &filename) const { return !SameAs(wxDirName(filename)); }
// compare with a filename string interpreted as a native file name // compare with a filename string interpreted as a native file name
bool operator==(const wxString& filename) const { return SameAs(wxDirName(filename)); } bool operator==(const wxString &filename) const { return SameAs(wxDirName(filename)); }
bool operator!=(const wxString& filename) const { return !SameAs(wxDirName(filename)); } bool operator!=(const wxString &filename) const { return !SameAs(wxDirName(filename)); }
const wxFileName& GetFilename() const { return *this; } const wxFileName &GetFilename() const { return *this; }
wxFileName& GetFilename() { return *this; } wxFileName &GetFilename() { return *this; }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -195,20 +211,20 @@ public:
// //
namespace Path namespace Path
{ {
extern bool IsRelative( const wxString& path ); extern bool IsRelative(const wxString &path);
extern s64 GetFileSize( const wxString& path ); extern s64 GetFileSize(const wxString &path);
extern wxString Normalize( const wxString& srcpath ); extern wxString Normalize(const wxString &srcpath);
extern wxString Normalize( const wxDirName& srcpath ); extern wxString Normalize(const wxDirName &srcpath);
extern wxString MakeAbsolute( const wxString& srcpath ); extern wxString MakeAbsolute(const wxString &srcpath);
extern wxString Combine( const wxString& srcPath, const wxString& srcFile ); extern wxString Combine(const wxString &srcPath, const wxString &srcFile);
extern wxString Combine( const wxDirName& srcPath, const wxFileName& srcFile ); extern wxString Combine(const wxDirName &srcPath, const wxFileName &srcFile);
extern wxString Combine( const wxString& srcPath, const wxDirName& srcFile ); extern wxString Combine(const wxString &srcPath, const wxDirName &srcFile);
extern wxString ReplaceExtension( const wxString& src, const wxString& ext ); extern wxString ReplaceExtension(const wxString &src, const wxString &ext);
extern wxString ReplaceFilename( const wxString& src, const wxString& newfilename ); extern wxString ReplaceFilename(const wxString &src, const wxString &newfilename);
extern wxString GetFilename( const wxString& src ); extern wxString GetFilename(const wxString &src);
extern wxString GetDirectory( const wxString& src ); extern wxString GetDirectory(const wxString &src);
extern wxString GetFilenameWithoutExt( const wxString& src ); extern wxString GetFilenameWithoutExt(const wxString &src);
extern wxString GetRootDirectory( const wxString& src ); extern wxString GetRootDirectory(const wxString &src);
} }

View File

@ -15,43 +15,42 @@
#pragma once #pragma once
namespace Perf { namespace Perf
{
struct Info struct Info
{ {
uptr m_x86; uptr m_x86;
u32 m_size; u32 m_size;
char m_symbol[20]; char m_symbol[20];
// The idea is to keep static zones that are set only // The idea is to keep static zones that are set only
// once. // once.
bool m_dynamic; bool m_dynamic;
Info(uptr x86, u32 size, const char* symbol); Info(uptr x86, u32 size, const char *symbol);
Info(uptr x86, u32 size, const char* symbol, u32 pc); Info(uptr x86, u32 size, const char *symbol, u32 pc);
void Print(FILE* fp); void Print(FILE *fp);
}; };
class InfoVector class InfoVector
{ {
std::vector<Info> m_v; std::vector<Info> m_v;
char m_prefix[20]; char m_prefix[20];
public: public:
InfoVector(const char *prefix);
InfoVector(const char* prefix); void print(FILE *fp);
void map(uptr x86, u32 size, const char *symbol);
void map(uptr x86, u32 size, u32 pc);
void reset();
};
void print(FILE* fp); void dump();
void map(uptr x86, u32 size, const char* symbol); void dump_and_reset();
void map(uptr x86, u32 size, u32 pc);
void reset();
}; extern InfoVector any;
extern InfoVector ee;
void dump(); extern InfoVector iop;
void dump_and_reset(); extern InfoVector vu;
extern InfoVector any;
extern InfoVector ee;
extern InfoVector iop;
extern InfoVector vu;
} }

View File

@ -25,38 +25,38 @@ namespace Threading
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ThreadDeleteEvent // ThreadDeleteEvent
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class EventListener_Thread : public IEventDispatcher<int> class EventListener_Thread : public IEventDispatcher<int>
{ {
public: public:
typedef int EvtParams; typedef int EvtParams;
protected: protected:
pxThread* m_thread; pxThread *m_thread;
public: public:
EventListener_Thread() EventListener_Thread()
{ {
m_thread = NULL; m_thread = NULL;
} }
virtual ~EventListener_Thread() throw() {} virtual ~EventListener_Thread() throw() {}
void SetThread( pxThread& thr ) { m_thread = &thr; } void SetThread(pxThread &thr) { m_thread = &thr; }
void SetThread( pxThread* thr ) { m_thread = thr; } void SetThread(pxThread *thr) { m_thread = thr; }
void DispatchEvent( const int& params ) void DispatchEvent(const int &params)
{ {
OnThreadCleanup(); OnThreadCleanup();
} }
protected: protected:
// Invoked by the pxThread when the thread execution is ending. This is // Invoked by the pxThread when the thread execution is ending. This is
// typically more useful than a delete listener since the extended thread information // typically more useful than a delete listener since the extended thread information
// provided by virtualized functions/methods will be available. // provided by virtualized functions/methods will be available.
// Important! This event is executed *by the thread*, so care must be taken to ensure // Important! This event is executed *by the thread*, so care must be taken to ensure
// thread sync when necessary (posting messages to the main thread, etc). // thread sync when necessary (posting messages to the main thread, etc).
virtual void OnThreadCleanup()=0; virtual void OnThreadCleanup() = 0;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// pxThread - Helper class for the basics of starting/managing persistent threads. // pxThread - Helper class for the basics of starting/managing persistent threads.
@ -85,122 +85,123 @@ namespace Threading
// no dependency options for ensuring correct static var initializations). Use heap // no dependency options for ensuring correct static var initializations). Use heap
// allocation to create thread objects instead. // allocation to create thread objects instead.
// //
class pxThread class pxThread
{ {
DeclareNoncopyableObject(pxThread); DeclareNoncopyableObject(pxThread);
friend void pxYield( int ms ); friend void pxYield(int ms);
protected: protected:
wxString m_name; // diagnostic name for our thread. wxString m_name; // diagnostic name for our thread.
pthread_t m_thread; pthread_t m_thread;
uptr m_native_id; // typically an id, but implementing platforms can do whatever. uptr m_native_id; // typically an id, but implementing platforms can do whatever.
uptr m_native_handle; // typically a pointer/handle, but implementing platforms can do whatever. uptr m_native_handle; // typically a pointer/handle, but implementing platforms can do whatever.
Semaphore m_sem_event; // general wait event that's needed by most threads Semaphore m_sem_event; // general wait event that's needed by most threads
Semaphore m_sem_startup; // startup sync tool Semaphore m_sem_startup; // startup sync tool
Mutex m_mtx_InThread; // used for canceling and closing threads in a deadlock-safe manner Mutex m_mtx_InThread; // used for canceling and closing threads in a deadlock-safe manner
MutexRecursive m_mtx_start; // used to lock the Start() code from starting simultaneous threads accidentally. MutexRecursive m_mtx_start; // used to lock the Start() code from starting simultaneous threads accidentally.
Mutex m_mtx_ThreadName; Mutex m_mtx_ThreadName;
std::atomic<bool> m_detached; // a boolean value which indicates if the m_thread handle is valid std::atomic<bool> m_detached; // a boolean value which indicates if the m_thread handle is valid
std::atomic<bool> m_running; // set true by Start(), and set false by Cancel(), Block(), etc. std::atomic<bool> m_running; // set true by Start(), and set false by Cancel(), Block(), etc.
// exception handle, set non-NULL if the thread terminated with an exception // exception handle, set non-NULL if the thread terminated with an exception
// Use RethrowException() to re-throw the exception using its original exception type. // Use RethrowException() to re-throw the exception using its original exception type.
ScopedPtrMT<BaseException> m_except; ScopedPtrMT<BaseException> m_except;
EventSource<EventListener_Thread> m_evtsrc_OnDelete; EventSource<EventListener_Thread> m_evtsrc_OnDelete;
public: public:
virtual ~pxThread() throw(); virtual ~pxThread() throw();
pxThread( const wxString& name=L"pxThread" ); pxThread(const wxString &name = L"pxThread");
pthread_t GetId() const { return m_thread; } pthread_t GetId() const { return m_thread; }
u64 GetCpuTime() const; u64 GetCpuTime() const;
virtual void Start(); virtual void Start();
virtual void Cancel( bool isBlocking = true ); virtual void Cancel(bool isBlocking = true);
virtual bool Cancel( const wxTimeSpan& timeout ); virtual bool Cancel(const wxTimeSpan &timeout);
virtual bool Detach(); virtual bool Detach();
virtual void Block(); virtual void Block();
virtual bool Block( const wxTimeSpan& timeout ); virtual bool Block(const wxTimeSpan &timeout);
virtual void RethrowException() const; virtual void RethrowException() const;
void AddListener( EventListener_Thread& evt ); void AddListener(EventListener_Thread &evt);
void AddListener( EventListener_Thread* evt ) void AddListener(EventListener_Thread *evt)
{ {
if( evt == NULL ) return; if (evt == NULL)
AddListener( *evt ); return;
} AddListener(*evt);
}
void WaitOnSelf( Semaphore& mutex ) const; void WaitOnSelf(Semaphore &mutex) const;
void WaitOnSelf( Mutex& mutex ) const; void WaitOnSelf(Mutex &mutex) const;
bool WaitOnSelf( Semaphore& mutex, const wxTimeSpan& timeout ) const; bool WaitOnSelf(Semaphore &mutex, const wxTimeSpan &timeout) const;
bool WaitOnSelf( Mutex& mutex, const wxTimeSpan& timeout ) const; bool WaitOnSelf(Mutex &mutex, const wxTimeSpan &timeout) const;
bool IsRunning() const; bool IsRunning() const;
bool IsSelf() const; bool IsSelf() const;
bool HasPendingException() const { return !!m_except; } bool HasPendingException() const { return !!m_except; }
wxString GetName() const; wxString GetName() const;
void SetName( const wxString& newname ); void SetName(const wxString &newname);
protected: protected:
// Extending classes should always implement your own OnStart(), which is called by // Extending classes should always implement your own OnStart(), which is called by
// Start() once necessary locks have been obtained. Do not override Start() directly // Start() once necessary locks have been obtained. Do not override Start() directly
// unless you're really sure that's what you need to do. ;) // unless you're really sure that's what you need to do. ;)
virtual void OnStart(); virtual void OnStart();
virtual void OnStartInThread(); virtual void OnStartInThread();
// This is called when the thread has been canceled or exits normally. The pxThread // This is called when the thread has been canceled or exits normally. The pxThread
// automatically binds it to the pthread cleanup routines as soon as the thread starts. // automatically binds it to the pthread cleanup routines as soon as the thread starts.
virtual void OnCleanupInThread(); virtual void OnCleanupInThread();
// Implemented by derived class to perform actual threaded task! // Implemented by derived class to perform actual threaded task!
virtual void ExecuteTaskInThread()=0; virtual void ExecuteTaskInThread() = 0;
void TestCancel() const; void TestCancel() const;
// Yields this thread to other threads and checks for cancellation. A sleeping thread should // Yields this thread to other threads and checks for cancellation. A sleeping thread should
// always test for cancellation, however if you really don't want to, you can use Threading::Sleep() // always test for cancellation, however if you really don't want to, you can use Threading::Sleep()
// or better yet, disable cancellation of the thread completely with DisableCancellation(). // or better yet, disable cancellation of the thread completely with DisableCancellation().
// //
// Parameters: // Parameters:
// ms - 'minimum' yield time in milliseconds (rough -- typically yields are longer by 1-5ms // ms - 'minimum' yield time in milliseconds (rough -- typically yields are longer by 1-5ms
// depending on operating system/platform). If ms is 0 or unspecified, then a single // depending on operating system/platform). If ms is 0 or unspecified, then a single
// timeslice is yielded to other contending threads. If no threads are contending for // timeslice is yielded to other contending threads. If no threads are contending for
// time when ms==0, then no yield is done, but cancellation is still tested. // time when ms==0, then no yield is done, but cancellation is still tested.
void Yield( int ms = 0 ) void Yield(int ms = 0)
{ {
pxAssert( IsSelf() ); pxAssert(IsSelf());
Threading::Sleep( ms ); Threading::Sleep(ms);
TestCancel(); TestCancel();
} }
void FrankenMutex( Mutex& mutex ); void FrankenMutex(Mutex &mutex);
bool AffinityAssert_AllowFromSelf( const DiagnosticOrigin& origin ) const; bool AffinityAssert_AllowFromSelf(const DiagnosticOrigin &origin) const;
bool AffinityAssert_DisallowFromSelf( const DiagnosticOrigin& origin ) const; bool AffinityAssert_DisallowFromSelf(const DiagnosticOrigin &origin) const;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Section of methods for internal use only. // Section of methods for internal use only.
void _platform_specific_OnStartInThread(); void _platform_specific_OnStartInThread();
void _platform_specific_OnCleanupInThread(); void _platform_specific_OnCleanupInThread();
bool _basecancel(); bool _basecancel();
void _selfRunningTest( const wxChar* name ) const; void _selfRunningTest(const wxChar *name) const;
void _DoSetThreadName( const wxString& name ); void _DoSetThreadName(const wxString &name);
void _DoSetThreadName( const char* name ); void _DoSetThreadName(const char *name);
void _internal_execute(); void _internal_execute();
void _try_virtual_invoke( void (pxThread::*method)() ); void _try_virtual_invoke(void (pxThread::*method)());
void _ThreadCleanup(); void _ThreadCleanup();
static void* _internal_callback( void* func ); static void *_internal_callback(void *func);
static void _pt_callback_cleanup( void* handle ); static void _pt_callback_cleanup(void *handle);
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -240,32 +241,32 @@ namespace Threading
// into smaller sections. For example, if you have 20,000 items to process, the task // into smaller sections. For example, if you have 20,000 items to process, the task
// can be divided into two threads of 10,000 items each. // can be divided into two threads of 10,000 items each.
// //
class BaseTaskThread : public pxThread class BaseTaskThread : public pxThread
{ {
protected: protected:
std::atomic<bool> m_Done; std::atomic<bool> m_Done;
std::atomic<bool> m_TaskPending; std::atomic<bool> m_TaskPending;
Semaphore m_post_TaskComplete; Semaphore m_post_TaskComplete;
Mutex m_lock_TaskComplete; Mutex m_lock_TaskComplete;
public: public:
virtual ~BaseTaskThread() throw() {} virtual ~BaseTaskThread() throw() {}
BaseTaskThread() : BaseTaskThread()
m_Done( false ) : m_Done(false)
, m_TaskPending( false ) , m_TaskPending(false)
, m_post_TaskComplete() , m_post_TaskComplete()
{ {
} }
void Block(); void Block();
void PostTask(); void PostTask();
void WaitForResult(); void WaitForResult();
protected: protected:
// Abstract method run when a task has been posted. Implementing classes should do // Abstract method run when a task has been posted. Implementing classes should do
// all your necessary processing work here. // all your necessary processing work here.
virtual void Task()=0; virtual void Task() = 0;
virtual void ExecuteTaskInThread(); virtual void ExecuteTaskInThread();
}; };
} }

View File

@ -16,7 +16,7 @@
#pragma once #pragma once
#ifdef __WXMSW__ #ifdef __WXMSW__
# include <wx/msw/wrapwin.h> #include <wx/msw/wrapwin.h>
#else #else
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -27,7 +27,7 @@
// check, so that we don't have to do it explicitly in every instance where it might // check, so that we don't have to do it explicitly in every instance where it might
// be needed from non-Win32-specific files // be needed from non-Win32-specific files
#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)
#ifdef _WIN32 #ifdef _WIN32

View File

@ -22,69 +22,69 @@ namespace Threading
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// RwMutex // RwMutex
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class RwMutex class RwMutex
{ {
DeclareNoncopyableObject(RwMutex); DeclareNoncopyableObject(RwMutex);
protected: protected:
pthread_rwlock_t m_rwlock; pthread_rwlock_t m_rwlock;
public: public:
RwMutex(); RwMutex();
virtual ~RwMutex() throw(); virtual ~RwMutex() throw();
virtual void AcquireRead();
virtual void AcquireWrite();
virtual bool TryAcquireRead();
virtual bool TryAcquireWrite();
virtual void Release(); virtual void AcquireRead();
}; virtual void AcquireWrite();
virtual bool TryAcquireRead();
virtual bool TryAcquireWrite();
virtual void Release();
};
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// BaseScopedReadWriteLock // BaseScopedReadWriteLock
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class BaseScopedReadWriteLock class BaseScopedReadWriteLock
{ {
DeclareNoncopyableObject(BaseScopedReadWriteLock); DeclareNoncopyableObject(BaseScopedReadWriteLock);
protected: protected:
RwMutex& m_lock; RwMutex &m_lock;
bool m_IsLocked; bool m_IsLocked;
public: public:
BaseScopedReadWriteLock( RwMutex& locker ) BaseScopedReadWriteLock(RwMutex &locker)
: m_lock( locker ) : m_lock(locker)
{ {
} }
virtual ~BaseScopedReadWriteLock() throw(); virtual ~BaseScopedReadWriteLock() throw();
void Release(); void Release();
bool IsLocked() const { return m_IsLocked; } bool IsLocked() const { return m_IsLocked; }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ScopedReadLock / ScopedWriteLock // ScopedReadLock / ScopedWriteLock
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class ScopedReadLock : public BaseScopedReadWriteLock class ScopedReadLock : public BaseScopedReadWriteLock
{ {
public: public:
ScopedReadLock( RwMutex& locker ); ScopedReadLock(RwMutex &locker);
virtual ~ScopedReadLock() throw() {} virtual ~ScopedReadLock() throw() {}
void Acquire(); void Acquire();
}; };
class ScopedWriteLock : public BaseScopedReadWriteLock class ScopedWriteLock : public BaseScopedReadWriteLock
{ {
public: public:
ScopedWriteLock( RwMutex& locker ); ScopedWriteLock(RwMutex &locker);
virtual ~ScopedWriteLock() throw() {} virtual ~ScopedWriteLock() throw() {}
void Acquire(); void Acquire();
protected: protected:
ScopedWriteLock( RwMutex& locker, bool isTryLock ); ScopedWriteLock(RwMutex &locker, bool isTryLock);
}; };
} }

View File

@ -23,8 +23,8 @@
// Microsoft Windows only macro, useful for freeing out COM objects: // Microsoft Windows only macro, useful for freeing out COM objects:
#define safe_release( ptr ) \ #define safe_release(ptr) \
((void) (( ( (ptr) != NULL ) && ((ptr)->Release(), !!0) ), (ptr) = NULL)) ((void)((((ptr) != NULL) && ((ptr)->Release(), !!0)), (ptr) = NULL))
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// SafeArray // SafeArray
@ -32,75 +32,75 @@
// Handy little class for allocating a resizable memory block, complete with exception // Handy little class for allocating a resizable memory block, complete with exception
// error handling and automatic cleanup. A lightweight alternative to std::vector. // error handling and automatic cleanup. A lightweight alternative to std::vector.
// //
template< typename T > template <typename T>
class SafeArray class SafeArray
{ {
DeclareNoncopyableObject(SafeArray); DeclareNoncopyableObject(SafeArray);
public: public:
static const int DefaultChunkSize = 0x1000 * sizeof(T); static const int DefaultChunkSize = 0x1000 * sizeof(T);
public: public:
wxString Name; // user-assigned block name wxString Name; // user-assigned block name
int ChunkSize; int ChunkSize;
protected: protected:
T* m_ptr; T *m_ptr;
int m_size; // size of the allocation of memory int m_size; // size of the allocation of memory
protected: protected:
SafeArray( const wxChar* name, T* allocated_mem, int initSize ); SafeArray(const wxChar *name, T *allocated_mem, int initSize);
virtual T* _virtual_realloc( int newsize ); virtual T *_virtual_realloc(int newsize);
// A safe array index fetcher. Asserts if the index is out of bounds (dev and debug // A safe array index fetcher. Asserts if the index is out of bounds (dev and debug
// builds only -- no bounds checking is done in release builds). // builds only -- no bounds checking is done in release builds).
T* _getPtr( uint i ) const; T *_getPtr(uint i) const;
public: public:
virtual ~SafeArray() throw(); virtual ~SafeArray() throw();
explicit SafeArray( const wxChar* name=L"Unnamed" ); explicit SafeArray(const wxChar *name = L"Unnamed");
explicit SafeArray( int initialSize, const wxChar* name=L"Unnamed" ); explicit SafeArray(int initialSize, const wxChar *name = L"Unnamed");
void Dispose();
void ExactAlloc( int newsize );
void MakeRoomFor( int newsize )
{
if( newsize > m_size )
ExactAlloc( newsize );
}
bool IsDisposed() const { return (m_ptr==NULL); } void Dispose();
void ExactAlloc(int newsize);
void MakeRoomFor(int newsize)
{
if (newsize > m_size)
ExactAlloc(newsize);
}
// Returns the size of the memory allocation, as according to the array type. bool IsDisposed() const { return (m_ptr == NULL); }
int GetLength() const { return m_size; }
// Returns the size of the memory allocation in bytes.
int GetSizeInBytes() const { return m_size * sizeof(T); }
// Extends the containment area of the array. Extensions are performed // Returns the size of the memory allocation, as according to the array type.
// in chunks. int GetLength() const { return m_size; }
void GrowBy( int items ) // Returns the size of the memory allocation in bytes.
{ int GetSizeInBytes() const { return m_size * sizeof(T); }
MakeRoomFor( m_size + ChunkSize + items + 1 );
}
// Gets a pointer to the requested allocation index. // Extends the containment area of the array. Extensions are performed
// DevBuilds : Generates assertion if the index is invalid. // in chunks.
T* GetPtr( uint idx=0 ) { return _getPtr( idx ); } void GrowBy(int items)
const T* GetPtr( uint idx=0 ) const { return _getPtr( idx ); } {
MakeRoomFor(m_size + ChunkSize + items + 1);
}
// Gets a pointer to the element directly after the last element in the array. // Gets a pointer to the requested allocation index.
// This is equivalent to doing GetPtr(GetLength()), except that this call *avoids* // DevBuilds : Generates assertion if the index is invalid.
// the out-of-bounds assertion check that typically occurs when you do that. :) T *GetPtr(uint idx = 0) { return _getPtr(idx); }
T* GetPtrEnd() { return &m_ptr[m_size]; } const T *GetPtr(uint idx = 0) const { return _getPtr(idx); }
const T* GetPtrEnd() const { return &m_ptr[m_size]; }
// Gets an element of this memory allocation much as if it were an array. // Gets a pointer to the element directly after the last element in the array.
// DevBuilds : Generates assertion if the index is invalid. // This is equivalent to doing GetPtr(GetLength()), except that this call *avoids*
T& operator[]( int idx ) { return *_getPtr( (uint)idx ); } // the out-of-bounds assertion check that typically occurs when you do that. :)
const T& operator[]( int idx ) const { return *_getPtr( (uint)idx ); } T *GetPtrEnd() { return &m_ptr[m_size]; }
const T *GetPtrEnd() const { return &m_ptr[m_size]; }
virtual SafeArray<T>* Clone() const; // Gets an element of this memory allocation much as if it were an array.
// DevBuilds : Generates assertion if the index is invalid.
T &operator[](int idx) { return *_getPtr((uint)idx); }
const T &operator[](int idx) const { return *_getPtr((uint)idx); }
virtual SafeArray<T> *Clone() const;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -113,76 +113,76 @@ public:
// * Classes with copy constructors (copying is done using performance memcpy) // * Classes with copy constructors (copying is done using performance memcpy)
// * Classes with destructors (they're not called, sorry!) // * Classes with destructors (they're not called, sorry!)
// //
template< typename T > template <typename T>
class SafeList class SafeList
{ {
DeclareNoncopyableObject(SafeList); DeclareNoncopyableObject(SafeList);
public: public:
static const int DefaultChunkSize = 0x80 * sizeof(T); static const int DefaultChunkSize = 0x80 * sizeof(T);
public: public:
wxString Name; // user-assigned block name wxString Name; // user-assigned block name
int ChunkSize; // assigned DefaultChunkSize on init, reconfigurable at any time. int ChunkSize; // assigned DefaultChunkSize on init, reconfigurable at any time.
protected: protected:
T* m_ptr; T *m_ptr;
int m_allocsize; // size of the allocation of memory int m_allocsize; // size of the allocation of memory
uint m_length; // length of the array (active items, not buffer allocation) uint m_length; // length of the array (active items, not buffer allocation)
protected: protected:
virtual T* _virtual_realloc( int newsize ); virtual T *_virtual_realloc(int newsize);
void _MakeRoomFor_threshold( int newsize ); void _MakeRoomFor_threshold(int newsize);
T* _getPtr( uint i ) const; T *_getPtr(uint i) const;
public: public:
virtual ~SafeList() throw(); virtual ~SafeList() throw();
explicit SafeList( const wxChar* name=L"Unnamed" ); explicit SafeList(const wxChar *name = L"Unnamed");
explicit SafeList( int initialSize, const wxChar* name=L"Unnamed" ); explicit SafeList(int initialSize, const wxChar *name = L"Unnamed");
virtual SafeList<T>* Clone() const; virtual SafeList<T> *Clone() const;
void Remove( int index ); void Remove(int index);
void MakeRoomFor( int blockSize ); void MakeRoomFor(int blockSize);
T& New(); T &New();
int Add( const T& src ); int Add(const T &src);
T& AddNew( const T& src ); T &AddNew(const T &src);
// Returns the size of the list, as according to the array type. This includes // Returns the size of the list, as according to the array type. This includes
// mapped items only. The actual size of the allocation may differ. // mapped items only. The actual size of the allocation may differ.
int GetLength() const { return m_length; } int GetLength() const { return m_length; }
// Returns the size of the list, in bytes. This includes mapped items only. // Returns the size of the list, in bytes. This includes mapped items only.
// The actual size of the allocation may differ. // The actual size of the allocation may differ.
int GetSizeInBytes() const { return m_length * sizeof(T); } int GetSizeInBytes() const { return m_length * sizeof(T); }
void MatchLengthToAllocatedSize() void MatchLengthToAllocatedSize()
{ {
m_length = m_allocsize; m_length = m_allocsize;
} }
void GrowBy( int items ) void GrowBy(int items)
{ {
MakeRoomFor( m_length + ChunkSize + items + 1 ); MakeRoomFor(m_length + ChunkSize + items + 1);
} }
// Sets the item length to zero. Does not free memory allocations. // Sets the item length to zero. Does not free memory allocations.
void Clear() void Clear()
{ {
m_length = 0; m_length = 0;
} }
// Gets an element of this memory allocation much as if it were an array. // Gets an element of this memory allocation much as if it were an array.
// DevBuilds : Generates assertion if the index is invalid. // DevBuilds : Generates assertion if the index is invalid.
T& operator[]( int idx ) { return *_getPtr( (uint)idx ); } T &operator[](int idx) { return *_getPtr((uint)idx); }
const T& operator[]( int idx ) const { return *_getPtr( (uint)idx ); } const T &operator[](int idx) const { return *_getPtr((uint)idx); }
T* GetPtr() { return m_ptr; } T *GetPtr() { return m_ptr; }
const T* GetPtr() const { return m_ptr; } const T *GetPtr() const { return m_ptr; }
T& GetLast() { return m_ptr[m_length-1]; } T &GetLast() { return m_ptr[m_length - 1]; }
const T& GetLast() const{ return m_ptr[m_length-1]; } const T &GetLast() const { return m_ptr[m_length - 1]; }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -192,25 +192,24 @@ public:
// exception-based error handling and automatic cleanup. // exception-based error handling and automatic cleanup.
// This one supports aligned data allocations too! // This one supports aligned data allocations too!
template< typename T, uint Alignment > template <typename T, uint Alignment>
class SafeAlignedArray : public SafeArray<T> class SafeAlignedArray : public SafeArray<T>
{ {
typedef SafeArray<T> _parent; typedef SafeArray<T> _parent;
protected: protected:
T* _virtual_realloc( int newsize ); T *_virtual_realloc(int newsize);
public: public:
using _parent::operator[]; using _parent::operator[];
virtual ~SafeAlignedArray() throw(); virtual ~SafeAlignedArray() throw();
explicit SafeAlignedArray( const wxChar* name=L"Unnamed" ) : explicit SafeAlignedArray(const wxChar *name = L"Unnamed")
SafeArray<T>::SafeArray( name ) : SafeArray<T>::SafeArray(name)
{ {
} }
explicit SafeAlignedArray( int initialSize, const wxChar* name=L"Unnamed" ); explicit SafeAlignedArray(int initialSize, const wxChar *name = L"Unnamed");
virtual SafeAlignedArray<T,Alignment>* Clone() const; virtual SafeAlignedArray<T, Alignment> *Clone() const;
}; };

View File

@ -21,104 +21,104 @@
// use its own memory allocation (with an aligned memory, for example). // use its own memory allocation (with an aligned memory, for example).
// Throws: // Throws:
// Exception::OutOfMemory if the allocated_mem pointer is NULL. // Exception::OutOfMemory if the allocated_mem pointer is NULL.
template< typename T > template <typename T>
SafeArray<T>::SafeArray( const wxChar* name, T* allocated_mem, int initSize ) SafeArray<T>::SafeArray(const wxChar *name, T *allocated_mem, int initSize)
: Name( name ) : Name(name)
{ {
ChunkSize = DefaultChunkSize; ChunkSize = DefaultChunkSize;
m_ptr = allocated_mem; m_ptr = allocated_mem;
m_size = initSize; m_size = initSize;
if( m_ptr == NULL ) if (m_ptr == NULL)
throw Exception::OutOfMemory(name) throw Exception::OutOfMemory(name)
.SetDiagMsg(wxsFormat(L"Called from 'SafeArray::ctor' [size=%d]", initSize)); .SetDiagMsg(wxsFormat(L"Called from 'SafeArray::ctor' [size=%d]", initSize));
} }
template< typename T > template <typename T>
T* SafeArray<T>::_virtual_realloc( int newsize ) T *SafeArray<T>::_virtual_realloc(int newsize)
{ {
T* retval = (T*)((m_ptr == NULL) ? T *retval = (T *)((m_ptr == NULL) ?
malloc( newsize * sizeof(T) ) : malloc(newsize * sizeof(T)) :
realloc( m_ptr, newsize * sizeof(T) ) realloc(m_ptr, newsize * sizeof(T)));
);
if( IsDebugBuild && (retval != NULL))
{
// Zero everything out to 0xbaadf00d, so that its obviously uncleared
// to a debuggee
u32* fill = (u32*)&retval[m_size]; if (IsDebugBuild && (retval != NULL)) {
const u32* end = (u32*)((((uptr)&retval[newsize-1])-3) & ~0x3); // Zero everything out to 0xbaadf00d, so that its obviously uncleared
for( ; fill<end; ++fill ) *fill = 0xbaadf00d; // to a debuggee
}
u32 *fill = (u32 *)&retval[m_size];
return retval; const u32 *end = (u32 *)((((uptr)&retval[newsize - 1]) - 3) & ~0x3);
for (; fill < end; ++fill)
*fill = 0xbaadf00d;
}
return retval;
} }
template< typename T > template <typename T>
SafeArray<T>::~SafeArray() throw() SafeArray<T>::~SafeArray() throw()
{ {
safe_free( m_ptr ); safe_free(m_ptr);
} }
template< typename T > template <typename T>
SafeArray<T>::SafeArray( const wxChar* name ) SafeArray<T>::SafeArray(const wxChar *name)
: Name( name ) : Name(name)
{ {
ChunkSize = DefaultChunkSize; ChunkSize = DefaultChunkSize;
m_ptr = NULL; m_ptr = NULL;
m_size = 0; m_size = 0;
} }
template< typename T > template <typename T>
SafeArray<T>::SafeArray( int initialSize, const wxChar* name ) SafeArray<T>::SafeArray(int initialSize, const wxChar *name)
: Name( name ) : Name(name)
{ {
ChunkSize = DefaultChunkSize; ChunkSize = DefaultChunkSize;
m_ptr = (initialSize==0) ? NULL : (T*)malloc( initialSize * sizeof(T) ); m_ptr = (initialSize == 0) ? NULL : (T *)malloc(initialSize * sizeof(T));
m_size = initialSize; m_size = initialSize;
if( (initialSize != 0) && (m_ptr == NULL) ) if ((initialSize != 0) && (m_ptr == NULL))
throw Exception::OutOfMemory(name) throw Exception::OutOfMemory(name)
.SetDiagMsg(wxsFormat(L"Called from 'SafeArray::ctor' [size=%d]", initialSize)); .SetDiagMsg(wxsFormat(L"Called from 'SafeArray::ctor' [size=%d]", initialSize));
} }
// Clears the contents of the array to zero, and frees all memory allocations. // Clears the contents of the array to zero, and frees all memory allocations.
template< typename T > template <typename T>
void SafeArray<T>::Dispose() void SafeArray<T>::Dispose()
{ {
m_size = 0; m_size = 0;
safe_free( m_ptr ); safe_free(m_ptr);
} }
template< typename T > template <typename T>
T* SafeArray<T>::_getPtr( uint i ) const T *SafeArray<T>::_getPtr(uint i) const
{ {
IndexBoundsAssumeDev( WX_STR(Name), i, m_size ); IndexBoundsAssumeDev(WX_STR(Name), i, m_size);
return &m_ptr[i]; return &m_ptr[i];
} }
// reallocates the array to the explicit size. Can be used to shrink or grow an // reallocates the array to the explicit size. Can be used to shrink or grow an
// array, and bypasses the internal threshold growth indicators. // array, and bypasses the internal threshold growth indicators.
template< typename T > template <typename T>
void SafeArray<T>::ExactAlloc( int newsize ) void SafeArray<T>::ExactAlloc(int newsize)
{ {
if( newsize == m_size ) return; if (newsize == m_size)
return;
m_ptr = _virtual_realloc( newsize ); m_ptr = _virtual_realloc(newsize);
if( m_ptr == NULL ) if (m_ptr == NULL)
throw Exception::OutOfMemory(Name) throw Exception::OutOfMemory(Name)
.SetDiagMsg(wxsFormat(L"Called from 'SafeArray::ExactAlloc' [oldsize=%d] [newsize=%d]", m_size, newsize)); .SetDiagMsg(wxsFormat(L"Called from 'SafeArray::ExactAlloc' [oldsize=%d] [newsize=%d]", m_size, newsize));
m_size = newsize; m_size = newsize;
} }
template< typename T > template <typename T>
SafeArray<T>* SafeArray<T>::Clone() const SafeArray<T> *SafeArray<T>::Clone() const
{ {
SafeArray<T>* retval = new SafeArray<T>( m_size ); SafeArray<T> *retval = new SafeArray<T>(m_size);
memcpy( retval->GetPtr(), m_ptr, sizeof(T) * m_size ); memcpy(retval->GetPtr(), m_ptr, sizeof(T) * m_size);
return retval; return retval;
} }
@ -126,164 +126,158 @@ SafeArray<T>* SafeArray<T>::Clone() const
// SafeAlignedArray<T> (implementations) // SafeAlignedArray<T> (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
template< typename T, uint Alignment > template <typename T, uint Alignment>
T* SafeAlignedArray<T,Alignment>::_virtual_realloc( int newsize ) T *SafeAlignedArray<T, Alignment>::_virtual_realloc(int newsize)
{ {
return (T*)( ( this->m_ptr == NULL ) ? return (T *)((this->m_ptr == NULL) ?
_aligned_malloc( newsize * sizeof(T), Alignment ) : _aligned_malloc(newsize * sizeof(T), Alignment) :
pcsx2_aligned_realloc( this->m_ptr, newsize * sizeof(T), Alignment, this->m_size * sizeof(T) ) pcsx2_aligned_realloc(this->m_ptr, newsize * sizeof(T), Alignment, this->m_size * sizeof(T)));
);
} }
// Appends "(align: xx)" to the name of the allocation in devel builds. // Appends "(align: xx)" to the name of the allocation in devel builds.
// Maybe useful,maybe not... no harm in attaching it. :D // Maybe useful,maybe not... no harm in attaching it. :D
template< typename T, uint Alignment > template <typename T, uint Alignment>
SafeAlignedArray<T,Alignment>::~SafeAlignedArray() throw() SafeAlignedArray<T, Alignment>::~SafeAlignedArray() throw()
{ {
safe_aligned_free( this->m_ptr ); safe_aligned_free(this->m_ptr);
// mptr is set to null, so the parent class's destructor won't re-free it. // mptr is set to null, so the parent class's destructor won't re-free it.
} }
template< typename T, uint Alignment > template <typename T, uint Alignment>
SafeAlignedArray<T,Alignment>::SafeAlignedArray( int initialSize, const wxChar* name ) : SafeAlignedArray<T, Alignment>::SafeAlignedArray(int initialSize, const wxChar *name)
SafeArray<T>::SafeArray( : SafeArray<T>::SafeArray(
name, name,
(T*)_aligned_malloc( initialSize * sizeof(T), Alignment ), (T *)_aligned_malloc(initialSize * sizeof(T), Alignment),
initialSize initialSize)
)
{ {
} }
template< typename T, uint Alignment > template <typename T, uint Alignment>
SafeAlignedArray<T,Alignment>* SafeAlignedArray<T,Alignment>::Clone() const SafeAlignedArray<T, Alignment> *SafeAlignedArray<T, Alignment>::Clone() const
{ {
SafeAlignedArray<T,Alignment>* retval = new SafeAlignedArray<T,Alignment>( this->m_size ); SafeAlignedArray<T, Alignment> *retval = new SafeAlignedArray<T, Alignment>(this->m_size);
memcpy( retval->GetPtr(), this->m_ptr, sizeof(T) * this->m_size ); memcpy(retval->GetPtr(), this->m_ptr, sizeof(T) * this->m_size);
return retval; return retval;
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// SafeList<T> (implementations) // SafeList<T> (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
template< typename T > template <typename T>
T* SafeList<T>::_virtual_realloc( int newsize ) T *SafeList<T>::_virtual_realloc(int newsize)
{ {
return (T*)realloc( m_ptr, newsize * sizeof(T) ); return (T *)realloc(m_ptr, newsize * sizeof(T));
} }
template< typename T > template <typename T>
SafeList<T>::~SafeList() throw() SafeList<T>::~SafeList() throw()
{ {
safe_free( m_ptr ); safe_free(m_ptr);
} }
template< typename T > template <typename T>
SafeList<T>::SafeList( const wxChar* name ) SafeList<T>::SafeList(const wxChar *name)
: Name( name ) : Name(name)
{ {
ChunkSize = DefaultChunkSize; ChunkSize = DefaultChunkSize;
m_ptr = NULL; m_ptr = NULL;
m_allocsize = 0; m_allocsize = 0;
m_length = 0; m_length = 0;
} }
template< typename T > template <typename T>
SafeList<T>::SafeList( int initialSize, const wxChar* name ) SafeList<T>::SafeList(int initialSize, const wxChar *name)
: Name( name ) : Name(name)
{ {
ChunkSize = DefaultChunkSize; ChunkSize = DefaultChunkSize;
m_allocsize = initialSize; m_allocsize = initialSize;
m_length = 0; m_length = 0;
m_ptr = (T*)malloc( initialSize * sizeof(T) ); m_ptr = (T *)malloc(initialSize * sizeof(T));
if( m_ptr == NULL ) if (m_ptr == NULL)
throw Exception::OutOfMemory(Name) throw Exception::OutOfMemory(Name)
.SetDiagMsg(wxsFormat(L"called from 'SafeList::ctor' [length=%d]", m_length)); .SetDiagMsg(wxsFormat(L"called from 'SafeList::ctor' [length=%d]", m_length));
for( int i=0; i<m_allocsize; ++i )
{
new (&m_ptr[i]) T();
}
for (int i = 0; i < m_allocsize; ++i) {
new (&m_ptr[i]) T();
}
} }
template< typename T > template <typename T>
T* SafeList<T>::_getPtr( uint i ) const T *SafeList<T>::_getPtr(uint i) const
{ {
IndexBoundsAssumeDev( WX_STR(Name), i, m_length ); IndexBoundsAssumeDev(WX_STR(Name), i, m_length);
return &m_ptr[i]; return &m_ptr[i];
} }
// Ensures that the allocation is large enough to fit data of the // Ensures that the allocation is large enough to fit data of the
// amount requested. The memory allocation is not resized smaller. // amount requested. The memory allocation is not resized smaller.
template< typename T > template <typename T>
void SafeList<T>::MakeRoomFor( int blockSize ) void SafeList<T>::MakeRoomFor(int blockSize)
{ {
if( blockSize > m_allocsize ) if (blockSize > m_allocsize) {
{ const int newalloc = blockSize + ChunkSize;
const int newalloc = blockSize + ChunkSize; m_ptr = _virtual_realloc(newalloc);
m_ptr = _virtual_realloc( newalloc ); if (m_ptr == NULL)
if( m_ptr == NULL ) throw Exception::OutOfMemory(Name)
throw Exception::OutOfMemory(Name) .SetDiagMsg(wxsFormat(L"Called from 'SafeList::MakeRoomFor' [oldlen=%d] [newlen=%d]", m_length, blockSize));
.SetDiagMsg(wxsFormat(L"Called from 'SafeList::MakeRoomFor' [oldlen=%d] [newlen=%d]", m_length, blockSize));
for( ; m_allocsize<newalloc; ++m_allocsize ) for (; m_allocsize < newalloc; ++m_allocsize) {
{ new (&m_ptr[m_allocsize]) T();
new (&m_ptr[m_allocsize]) T(); }
} }
}
} }
// Appends an item to the end of the list and returns a handle to it. // Appends an item to the end of the list and returns a handle to it.
template< typename T > template <typename T>
T& SafeList<T>::New() T &SafeList<T>::New()
{ {
_MakeRoomFor_threshold( m_length + 1 ); _MakeRoomFor_threshold(m_length + 1);
return m_ptr[m_length++]; return m_ptr[m_length++];
} }
template< typename T > template <typename T>
int SafeList<T>::Add( const T& src ) int SafeList<T>::Add(const T &src)
{ {
_MakeRoomFor_threshold( m_length + 1 ); _MakeRoomFor_threshold(m_length + 1);
m_ptr[m_length] = src; m_ptr[m_length] = src;
return m_length++; return m_length++;
} }
// Same as Add, but returns the handle of the new object instead of it's array index. // Same as Add, but returns the handle of the new object instead of it's array index.
template< typename T > template <typename T>
T& SafeList<T>::AddNew( const T& src ) T &SafeList<T>::AddNew(const T &src)
{ {
_MakeRoomFor_threshold( m_length + 1 ); _MakeRoomFor_threshold(m_length + 1);
m_ptr[m_length] = src; m_ptr[m_length] = src;
return m_ptr[m_length]; return m_ptr[m_length];
} }
// Performs a standard array-copy removal of the given item. All items past the // Performs a standard array-copy removal of the given item. All items past the
// given item are copied over. // given item are copied over.
// DevBuilds : Generates assertion if the index is invalid. // DevBuilds : Generates assertion if the index is invalid.
template< typename T > template <typename T>
void SafeList<T>::Remove( int index ) void SafeList<T>::Remove(int index)
{ {
IndexBoundsAssumeDev( Name.c_str(), index, m_length ); IndexBoundsAssumeDev(Name.c_str(), index, m_length);
int copylen = m_length - index; int copylen = m_length - index;
if( copylen > 0 ) if (copylen > 0)
memcpy( &m_ptr[index], &m_ptr[index+1], copylen ); memcpy(&m_ptr[index], &m_ptr[index + 1], copylen);
} }
template< typename T > template <typename T>
SafeList<T>* SafeList<T>::Clone() const SafeList<T> *SafeList<T>::Clone() const
{ {
SafeList<T>* retval = new SafeList<T>( m_length ); SafeList<T> *retval = new SafeList<T>(m_length);
memcpy( retval->m_ptr, m_ptr, sizeof(T) * m_length ); memcpy(retval->m_ptr, m_ptr, sizeof(T) * m_length);
return retval; return retval;
} }
template< typename T > template <typename T>
void SafeList<T>::_MakeRoomFor_threshold( int newsize ) void SafeList<T>::_MakeRoomFor_threshold(int newsize)
{ {
MakeRoomFor( newsize + ChunkSize ); MakeRoomFor(newsize + ChunkSize);
} }

View File

@ -27,43 +27,43 @@
// Safe deallocation macros -- checks pointer validity (non-null) when needed, and sets // Safe deallocation macros -- checks pointer validity (non-null) when needed, and sets
// pointer to null after deallocation. // pointer to null after deallocation.
#define safe_delete( ptr ) \ #define safe_delete(ptr) \
((void) (delete (ptr)), (ptr) = NULL) ((void)(delete (ptr)), (ptr) = NULL)
#define safe_delete_array( ptr ) \ #define safe_delete_array(ptr) \
((void) (delete[] (ptr)), (ptr) = NULL) ((void)(delete[](ptr)), (ptr) = NULL)
// No checks for NULL -- wxWidgets says it's safe to skip NULL checks and it runs on // No checks for NULL -- wxWidgets says it's safe to skip NULL checks and it runs on
// just about every compiler and libc implementation of any recentness. // just about every compiler and libc implementation of any recentness.
#define safe_free( ptr ) \ #define safe_free(ptr) \
( (void) (free( ptr ), !!0), (ptr) = NULL ) ((void)(free(ptr), !!0), (ptr) = NULL)
//((void) (( ( (ptr) != NULL ) && (free( ptr ), !!0) ), (ptr) = NULL)) //((void) (( ( (ptr) != NULL ) && (free( ptr ), !!0) ), (ptr) = NULL))
#define safe_fclose( ptr ) \ #define safe_fclose(ptr) \
((void) (( ( (ptr) != NULL ) && (fclose( ptr ), !!0) ), (ptr) = NULL)) ((void)((((ptr) != NULL) && (fclose(ptr), !!0)), (ptr) = NULL))
// Implementation note: all known implementations of _aligned_free check the pointer for // Implementation note: all known implementations of _aligned_free check the pointer for
// NULL status (our implementation under GCC, and microsoft's under MSVC), so no need to // NULL status (our implementation under GCC, and microsoft's under MSVC), so no need to
// do it here. // do it here.
#define safe_aligned_free( ptr ) \ #define safe_aligned_free(ptr) \
((void) ( _aligned_free( ptr ), (ptr) = NULL )) ((void)(_aligned_free(ptr), (ptr) = NULL))
// aligned_malloc: Implement/declare linux equivalents here! // aligned_malloc: Implement/declare linux equivalents here!
#if !defined(_MSC_VER) #if !defined(_MSC_VER)
extern void* __fastcall _aligned_malloc(size_t size, size_t align); extern void *__fastcall _aligned_malloc(size_t size, size_t align);
extern void* __fastcall pcsx2_aligned_realloc(void* handle, size_t new_size, size_t align, size_t old_size); extern void *__fastcall pcsx2_aligned_realloc(void *handle, size_t new_size, size_t align, size_t old_size);
extern void _aligned_free(void* pmem); extern void _aligned_free(void *pmem);
#else #else
#define pcsx2_aligned_realloc(handle, new_size, align, old_size) \ #define pcsx2_aligned_realloc(handle, new_size, align, old_size) \
_aligned_realloc(handle, new_size, align) _aligned_realloc(handle, new_size, align)
#endif #endif
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// pxDoOutOfMemory // pxDoOutOfMemory
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
typedef void FnType_OutOfMemory( uptr blocksize ); typedef void FnType_OutOfMemory(uptr blocksize);
typedef FnType_OutOfMemory* Fnptr_OutOfMemory; typedef FnType_OutOfMemory *Fnptr_OutOfMemory;
// This method is meant to be assigned by applications that link against pxWex. It is called // This method is meant to be assigned by applications that link against pxWex. It is called
// (invoked) prior to most pxWex built-in memory/array classes throwing exceptions, and can be // (invoked) prior to most pxWex built-in memory/array classes throwing exceptions, and can be
@ -89,77 +89,78 @@ extern Fnptr_OutOfMemory pxDoOutOfMemory;
// destructing container for malloc. The entire class is almost completely dependency free, // destructing container for malloc. The entire class is almost completely dependency free,
// and thus can be included everywhere and anywhere without dependency hassles. // and thus can be included everywhere and anywhere without dependency hassles.
// //
template< typename T > template <typename T>
class BaseScopedAlloc class BaseScopedAlloc
{ {
protected: protected:
T* m_buffer; T *m_buffer;
uint m_size; uint m_size;
public: public:
BaseScopedAlloc() BaseScopedAlloc()
{ {
m_buffer = NULL; m_buffer = NULL;
m_size = 0; m_size = 0;
} }
virtual ~BaseScopedAlloc() throw() virtual ~BaseScopedAlloc() throw()
{ {
//pxAssert(m_buffer==NULL); //pxAssert(m_buffer==NULL);
} }
public: public:
size_t GetSize() const { return m_size; } size_t GetSize() const { return m_size; }
size_t GetLength() const { return m_size; } size_t GetLength() const { return m_size; }
// Allocates the object to the specified size. If an existing allocation is in
// place, it is freed and replaced with the new allocation, and all data is lost.
// Parameter:
// newSize - size of the new allocation, in elements (not bytes!). If the specified
// size is 0, the the allocation is freed, same as calling Free().
virtual void Alloc( size_t newsize )=0;
// Re-sizes the allocation to the requested size, without any data loss. // Allocates the object to the specified size. If an existing allocation is in
// Parameter: // place, it is freed and replaced with the new allocation, and all data is lost.
// newSize - size of the new allocation, in elements (not bytes!). If the specified // Parameter:
// size is 0, the the allocation is freed, same as calling Free(). // newSize - size of the new allocation, in elements (not bytes!). If the specified
virtual void Resize( size_t newsize )=0; // size is 0, the the allocation is freed, same as calling Free().
virtual void Alloc(size_t newsize) = 0;
void Free() // Re-sizes the allocation to the requested size, without any data loss.
{ // Parameter:
Alloc( 0 ); // newSize - size of the new allocation, in elements (not bytes!). If the specified
} // size is 0, the the allocation is freed, same as calling Free().
virtual void Resize(size_t newsize) = 0;
// Makes enough room for the requested size. Existing data in the array is retained.
void MakeRoomFor( uint size )
{
if (size <= m_size) return;
Resize( size );
}
T* GetPtr( uint idx=0 ) const void Free()
{ {
#if pxUSE_SECURE_MALLOC Alloc(0);
IndexBoundsAssumeDev( "ScopedAlloc", idx, m_size ); }
#endif
return &m_buffer[idx];
}
T& operator[]( uint idx ) // Makes enough room for the requested size. Existing data in the array is retained.
{ void MakeRoomFor(uint size)
#if pxUSE_SECURE_MALLOC {
IndexBoundsAssumeDev( "ScopedAlloc", idx, m_size ); if (size <= m_size)
#endif return;
return m_buffer[idx]; Resize(size);
} }
const T& operator[]( uint idx ) const T *GetPtr(uint idx = 0) const
{ {
#if pxUSE_SECURE_MALLOC #if pxUSE_SECURE_MALLOC
IndexBoundsAssumeDev( "ScopedAlloc", idx, m_size ); IndexBoundsAssumeDev("ScopedAlloc", idx, m_size);
#endif #endif
return m_buffer[idx]; return &m_buffer[idx];
} }
T &operator[](uint idx)
{
#if pxUSE_SECURE_MALLOC
IndexBoundsAssumeDev("ScopedAlloc", idx, m_size);
#endif
return m_buffer[idx];
}
const T &operator[](uint idx) const
{
#if pxUSE_SECURE_MALLOC
IndexBoundsAssumeDev("ScopedAlloc", idx, m_size);
#endif
return m_buffer[idx];
}
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -171,43 +172,45 @@ public:
// //
// See docs for BaseScopedAlloc for details and rationale. // See docs for BaseScopedAlloc for details and rationale.
// //
template< typename T > template <typename T>
class ScopedAlloc : public BaseScopedAlloc<T> class ScopedAlloc : public BaseScopedAlloc<T>
{ {
typedef BaseScopedAlloc<T> _parent; typedef BaseScopedAlloc<T> _parent;
public: public:
ScopedAlloc( size_t size=0 ) : _parent() ScopedAlloc(size_t size = 0)
{ : _parent()
Alloc(size); {
} Alloc(size);
}
virtual ~ScopedAlloc() throw() virtual ~ScopedAlloc() throw()
{ {
safe_free(this->m_buffer); safe_free(this->m_buffer);
} }
virtual void Alloc( size_t newsize ) virtual void Alloc(size_t newsize)
{ {
safe_free(this->m_buffer); safe_free(this->m_buffer);
this->m_size = newsize; this->m_size = newsize;
if (!this->m_size) return; if (!this->m_size)
return;
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(L"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, this->m_size * sizeof(T)); this->m_buffer = (T *)realloc(this->m_buffer, this->m_size * sizeof(T));
if (!this->m_buffer) if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlloc::Resize"); throw Exception::OutOfMemory(L"ScopedAlloc::Resize");
} }
using _parent::operator[]; using _parent::operator[];
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -219,41 +222,43 @@ public:
// //
// See docs for BaseScopedAlloc for details and rationale. // See docs for BaseScopedAlloc for details and rationale.
// //
template< typename T, uint align > template <typename T, uint align>
class ScopedAlignedAlloc : public BaseScopedAlloc<T> class ScopedAlignedAlloc : public BaseScopedAlloc<T>
{ {
typedef BaseScopedAlloc<T> _parent; typedef BaseScopedAlloc<T> _parent;
public: public:
ScopedAlignedAlloc( size_t size=0 ) : _parent() ScopedAlignedAlloc(size_t size = 0)
{ : _parent()
Alloc(size); {
} Alloc(size);
}
virtual ~ScopedAlignedAlloc() throw()
{
safe_aligned_free(this->m_buffer);
}
virtual void Alloc( size_t newsize ) virtual ~ScopedAlignedAlloc() throw()
{ {
safe_aligned_free(this->m_buffer); safe_aligned_free(this->m_buffer);
this->m_size = newsize; }
if (!this->m_size) return;
this->m_buffer = (T*)_aligned_malloc( this->m_size * sizeof(T), align ); virtual void Alloc(size_t newsize)
if (!this->m_buffer) {
throw Exception::OutOfMemory(L"ScopedAlignedAlloc"); safe_aligned_free(this->m_buffer);
} this->m_size = newsize;
if (!this->m_size)
return;
virtual void Resize( size_t newsize ) this->m_buffer = (T *)_aligned_malloc(this->m_size * sizeof(T), align);
{ if (!this->m_buffer)
this->m_buffer = (T*)pcsx2_aligned_realloc(this->m_buffer, newsize * sizeof(T), align, this->m_size * sizeof(T)); throw Exception::OutOfMemory(L"ScopedAlignedAlloc");
this->m_size = newsize; }
if (!this->m_buffer) virtual void Resize(size_t newsize)
throw Exception::OutOfMemory(L"ScopedAlignedAlloc::Resize"); {
} this->m_buffer = (T *)pcsx2_aligned_realloc(this->m_buffer, newsize * sizeof(T), align, this->m_size * sizeof(T));
this->m_size = newsize;
using _parent::operator[];
if (!this->m_buffer)
throw Exception::OutOfMemory(L"ScopedAlignedAlloc::Resize");
}
using _parent::operator[];
}; };

View File

@ -22,95 +22,96 @@ using Threading::ScopedLock;
// ScopedPtrMT // ScopedPtrMT
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
template< typename T > template <typename T>
class ScopedPtrMT class ScopedPtrMT
{ {
DeclareNoncopyableObject(ScopedPtrMT); DeclareNoncopyableObject(ScopedPtrMT);
protected: protected:
std::atomic<T*> m_ptr; std::atomic<T *> m_ptr;
Threading::Mutex m_mtx; Threading::Mutex m_mtx;
public: public:
typedef T element_type; typedef T element_type;
wxEXPLICIT ScopedPtrMT(T * ptr = nullptr) wxEXPLICIT ScopedPtrMT(T *ptr = nullptr)
{ {
m_ptr = ptr; m_ptr = ptr;
} }
~ScopedPtrMT() throw() { _Delete_unlocked(); } ~ScopedPtrMT() throw() { _Delete_unlocked(); }
ScopedPtrMT& Reassign(T * ptr = nullptr) ScopedPtrMT &Reassign(T *ptr = nullptr)
{ {
T* doh = m_ptr.exchange(ptr); T *doh = m_ptr.exchange(ptr);
if ( ptr != doh ) delete doh; if (ptr != doh)
return *this; delete doh;
} return *this;
}
ScopedPtrMT& Delete() throw() ScopedPtrMT &Delete() throw()
{ {
ScopedLock lock( m_mtx ); ScopedLock lock(m_mtx);
_Delete_unlocked(); _Delete_unlocked();
} }
// Removes the pointer from scoped management, but does not delete! // Removes the pointer from scoped management, but does not delete!
// (ScopedPtr will be nullptr after this method) // (ScopedPtr will be nullptr after this method)
T *DetachPtr() T *DetachPtr()
{ {
ScopedLock lock( m_mtx ); ScopedLock lock(m_mtx);
return m_ptr.exchange(nullptr); return m_ptr.exchange(nullptr);
} }
// Returns the managed pointer. Can return nullptr as a valid result if the ScopedPtrMT // Returns the managed pointer. Can return nullptr as a valid result if the ScopedPtrMT
// has no object in management. // has no object in management.
T* GetPtr() const T *GetPtr() const
{ {
return m_ptr; return m_ptr;
} }
void SwapPtr(ScopedPtrMT& other) void SwapPtr(ScopedPtrMT &other)
{ {
ScopedLock lock( m_mtx ); ScopedLock lock(m_mtx);
m_ptr.exchange(other.m_ptr.exchange(m_ptr.load())); m_ptr.exchange(other.m_ptr.exchange(m_ptr.load()));
T * const tmp = other.m_ptr; T *const tmp = other.m_ptr;
other.m_ptr = m_ptr; other.m_ptr = m_ptr;
m_ptr = tmp; m_ptr = tmp;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ScopedPtrMT Operators // ScopedPtrMT Operators
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// I've decided to use the ATL's approach to pointer validity tests, opposed to // I've decided to use the ATL's approach to pointer validity tests, opposed to
// the wx/boost approach (which uses some bizarre member method pointer crap, and can't // the wx/boost approach (which uses some bizarre member method pointer crap, and can't
// allow the T* implicit casting. // allow the T* implicit casting.
bool operator!() const throw() bool operator!() const throw()
{ {
return m_ptr.load() == nullptr; return m_ptr.load() == nullptr;
} }
// Equality // Equality
bool operator==(T* pT) const throw() bool operator==(T *pT) const throw()
{ {
return m_ptr == pT; return m_ptr == pT;
} }
// Inequality // Inequality
bool operator!=(T* pT) const throw() bool operator!=(T *pT) const throw()
{ {
return !operator==(pT); return !operator==(pT);
} }
// Convenient assignment operator. ScopedPtrMT = nullptr will issue an automatic deletion // Convenient assignment operator. ScopedPtrMT = nullptr will issue an automatic deletion
// of the managed pointer. // of the managed pointer.
ScopedPtrMT& operator=( T* src ) ScopedPtrMT &operator=(T *src)
{ {
return Reassign( src ); return Reassign(src);
} }
#if 0 #if 0
operator T*() const operator T*() const
{ {
return m_ptr; return m_ptr;
@ -129,11 +130,11 @@ public:
pxAssert(m_ptr != nullptr); pxAssert(m_ptr != nullptr);
return m_ptr; return m_ptr;
} }
#endif #endif
protected: protected:
void _Delete_unlocked() throw() void _Delete_unlocked() throw()
{ {
delete m_ptr.exchange(nullptr); delete m_ptr.exchange(nullptr);
} }
}; };

View File

@ -22,10 +22,10 @@
#include <wx/tokenzr.h> #include <wx/tokenzr.h>
#if _WIN32 #if _WIN32
#define WX_STR(str) (str.wc_str()) #define WX_STR(str) (str.wc_str())
#else #else
// Stupid wx3.0 doesn't support c_str for vararg function // Stupid wx3.0 doesn't support c_str for vararg function
#define WX_STR(str) (static_cast<const char*>(str.c_str())) #define WX_STR(str) (static_cast<const char *>(str.c_str()))
#endif #endif
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -34,59 +34,59 @@
// Converts a string to UTF8 and provides an interface for getting its length. // Converts a string to UTF8 and provides an interface for getting its length.
class pxToUTF8 class pxToUTF8
{ {
DeclareNoncopyableObject( pxToUTF8 ); DeclareNoncopyableObject(pxToUTF8);
protected: protected:
wxCharBuffer m_result; wxCharBuffer m_result;
int m_length; int m_length;
public: public:
explicit pxToUTF8(const wxString& src) explicit pxToUTF8(const wxString &src)
: m_result( src.ToUTF8() ) : m_result(src.ToUTF8())
{ {
m_length = -1; m_length = -1;
} }
size_t Length() size_t Length()
{ {
if( -1 == m_length ) if (-1 == m_length)
m_length = strlen( m_result ); m_length = strlen(m_result);
return m_length; return m_length;
} }
void Convert( const wxString& src ) void Convert(const wxString &src)
{ {
m_result = src.ToUTF8(); m_result = src.ToUTF8();
m_length = -1; m_length = -1;
} }
const char* data() const { return m_result; } const char *data() const { return m_result; }
operator const char*() const operator const char *() const
{ {
return m_result.data(); return m_result.data();
} }
}; };
extern void px_fputs( FILE* fp, const char* src ); extern void px_fputs(FILE *fp, const char *src);
// wxWidgets lacks one of its own... // wxWidgets lacks one of its own...
extern const wxRect wxDefaultRect; extern const wxRect wxDefaultRect;
extern void SplitString( wxArrayString& dest, const wxString& src, const wxString& delims, wxStringTokenizerMode mode = wxTOKEN_RET_EMPTY_ALL ); extern void SplitString(wxArrayString &dest, const wxString &src, const wxString &delims, wxStringTokenizerMode mode = wxTOKEN_RET_EMPTY_ALL);
extern wxString JoinString( const wxArrayString& src, const wxString& separator ); extern wxString JoinString(const wxArrayString &src, const wxString &separator);
extern wxString JoinString( const wxChar** src, const wxString& separator ); extern wxString JoinString(const wxChar **src, const wxString &separator);
extern wxString ToString( const wxPoint& src, const wxString& separator=L"," ); extern wxString ToString(const wxPoint &src, const wxString &separator = L",");
extern wxString ToString( const wxSize& src, const wxString& separator=L"," ); extern wxString ToString(const wxSize &src, const wxString &separator = L",");
extern wxString ToString( const wxRect& src, const wxString& separator=L"," ); extern wxString ToString(const wxRect &src, const wxString &separator = L",");
extern bool TryParse( wxPoint& dest, const wxStringTokenizer& parts ); extern bool TryParse(wxPoint &dest, const wxStringTokenizer &parts);
extern bool TryParse( wxSize& dest, const wxStringTokenizer& parts ); extern bool TryParse(wxSize &dest, const wxStringTokenizer &parts);
extern bool TryParse( wxPoint& dest, const wxString& src, const wxPoint& defval=wxDefaultPosition, const wxString& separators=L","); extern bool TryParse(wxPoint &dest, const wxString &src, const wxPoint &defval = wxDefaultPosition, const wxString &separators = L",");
extern bool TryParse( wxSize& dest, const wxString& src, const wxSize& defval=wxDefaultSize, const wxString& separators=L","); extern bool TryParse(wxSize &dest, const wxString &src, const wxSize &defval = wxDefaultSize, const wxString &separators = L",");
extern bool TryParse( wxRect& dest, const wxString& src, const wxRect& defval=wxDefaultRect, const wxString& separators=L","); extern bool TryParse(wxRect &dest, const wxString &src, const wxRect &defval = wxDefaultRect, const wxString &separators = L",");
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ParsedAssignmentString // ParsedAssignmentString
@ -104,11 +104,11 @@ extern bool TryParse( wxRect& dest, const wxString& src, const wxRect& defval=wx
// //
struct ParsedAssignmentString struct ParsedAssignmentString
{ {
wxString lvalue; wxString lvalue;
wxString rvalue; wxString rvalue;
bool IsComment; bool IsComment;
ParsedAssignmentString( const wxString& src ); ParsedAssignmentString(const wxString &src);
}; };
// ====================================================================================== // ======================================================================================
@ -134,46 +134,46 @@ struct ParsedAssignmentString
typedef ScopedAlignedAlloc<char, 16> CharBufferType; typedef ScopedAlignedAlloc<char, 16> CharBufferType;
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// FastFormatAscii // FastFormatAscii
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class FastFormatAscii class FastFormatAscii
{ {
protected: protected:
CharBufferType m_dest; CharBufferType m_dest;
public: public:
FastFormatAscii(); FastFormatAscii();
~FastFormatAscii() throw(); ~FastFormatAscii() throw();
FastFormatAscii& Write( const char* fmt, ... ); FastFormatAscii &Write(const char *fmt, ...);
FastFormatAscii& WriteV( const char* fmt, va_list argptr ); FastFormatAscii &WriteV(const char *fmt, va_list argptr);
void Clear(); void Clear();
bool IsEmpty() const; bool IsEmpty() const;
const char* c_str() const { return m_dest.GetPtr(); } const char *c_str() const { return m_dest.GetPtr(); }
operator const char*() const { return m_dest.GetPtr(); } operator const char *() const { return m_dest.GetPtr(); }
const wxString GetString() const; const wxString GetString() const;
//operator wxString() const; //operator wxString() const;
FastFormatAscii& operator+=(const wxString& s) FastFormatAscii &operator+=(const wxString &s)
{ {
Write( "%s", WX_STR(s) ); Write("%s", WX_STR(s));
return *this; return *this;
} }
FastFormatAscii& operator+=(const wxChar* psz ) FastFormatAscii &operator+=(const wxChar *psz)
{ {
Write( "%ls", psz ); Write("%ls", psz);
return *this; return *this;
} }
FastFormatAscii& operator+=(const char* psz ) FastFormatAscii &operator+=(const char *psz)
{ {
Write( "%s", psz ); Write("%s", psz);
return *this; return *this;
} }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -182,57 +182,57 @@ public:
class FastFormatUnicode class FastFormatUnicode
{ {
protected: protected:
CharBufferType m_dest; CharBufferType m_dest;
uint m_Length; uint m_Length;
public: public:
FastFormatUnicode(); FastFormatUnicode();
~FastFormatUnicode() throw(); ~FastFormatUnicode() throw();
FastFormatUnicode& Write( const char* fmt, ... ); FastFormatUnicode &Write(const char *fmt, ...);
FastFormatUnicode& Write( const wxChar* fmt, ... ); FastFormatUnicode &Write(const wxChar *fmt, ...);
FastFormatUnicode& Write( const wxString fmt, ... ); FastFormatUnicode &Write(const wxString fmt, ...);
FastFormatUnicode& WriteV( const char* fmt, va_list argptr ); FastFormatUnicode &WriteV(const char *fmt, va_list argptr);
FastFormatUnicode& WriteV( const wxChar* fmt, va_list argptr ); FastFormatUnicode &WriteV(const wxChar *fmt, va_list argptr);
void Clear(); void Clear();
bool IsEmpty() const; bool IsEmpty() const;
uint Length() const { return m_Length; } uint Length() const { return m_Length; }
FastFormatUnicode& ToUpper(); FastFormatUnicode &ToUpper();
FastFormatUnicode& ToLower(); FastFormatUnicode &ToLower();
const wxChar* c_str() const { return (const wxChar*)m_dest.GetPtr(); } const wxChar *c_str() const { return (const wxChar *)m_dest.GetPtr(); }
operator const wxChar*() const { return (const wxChar*)m_dest.GetPtr(); } operator const wxChar *() const { return (const wxChar *)m_dest.GetPtr(); }
operator wxString() const { return (const wxChar*)m_dest.GetPtr(); } operator wxString() const { return (const wxChar *)m_dest.GetPtr(); }
FastFormatUnicode& operator+=(const wxString& s) FastFormatUnicode &operator+=(const wxString &s)
{ {
Write( L"%s", WX_STR(s) ); Write(L"%s", WX_STR(s));
return *this; return *this;
} }
FastFormatUnicode& operator+=(const wxChar* psz ) FastFormatUnicode &operator+=(const wxChar *psz)
{ {
Write( L"%s", psz ); Write(L"%s", psz);
return *this; return *this;
} }
FastFormatUnicode& operator+=(const char* psz ); FastFormatUnicode &operator+=(const char *psz);
}; };
extern bool pxParseAssignmentString( const wxString& src, wxString& ldest, wxString& rdest ); extern bool pxParseAssignmentString(const wxString &src, wxString &ldest, wxString &rdest);
#define pxsFmt FastFormatUnicode().Write #define pxsFmt FastFormatUnicode().Write
#define pxsFmtV FastFormatUnicode().WriteV #define pxsFmtV FastFormatUnicode().WriteV
#define pxsPtr(ptr) pxsFmt("0x%08X", (ptr)).c_str() #define pxsPtr(ptr) pxsFmt("0x%08X", (ptr)).c_str()
extern wxString& operator+=(wxString& str1, const FastFormatUnicode& str2); extern wxString &operator+=(wxString &str1, const FastFormatUnicode &str2);
extern wxString operator+(const wxString& str1, const FastFormatUnicode& str2); extern wxString operator+(const wxString &str1, const FastFormatUnicode &str2);
extern wxString operator+(const wxChar* str1, const FastFormatUnicode& str2); extern wxString operator+(const wxChar *str1, const FastFormatUnicode &str2);
extern wxString operator+(const FastFormatUnicode& str1, const wxString& str2); extern wxString operator+(const FastFormatUnicode &str1, const wxString &str2);
extern wxString operator+(const FastFormatUnicode& str1, const wxChar* str2); extern wxString operator+(const FastFormatUnicode &str1, const wxChar *str2);
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -241,4 +241,4 @@ extern wxString operator+(const FastFormatUnicode& str1, const wxChar* str2);
// These functions are useful since they are ASCII always, even under Unicode. Typically // These functions are useful since they are ASCII always, even under Unicode. Typically
// even in a unicode app. // even in a unicode app.
extern void ssappendf(std::string& dest, const char* format, ...); extern void ssappendf(std::string &dest, const char *format, ...);

View File

@ -26,10 +26,10 @@
#include "Pcsx2Defs.h" #include "Pcsx2Defs.h"
#include "TraceLog.h" #include "TraceLog.h"
#undef Yield // release the burden of windows.h global namespace spam. #undef Yield // release the burden of windows.h global namespace spam.
#define AffinityAssert_AllowFrom_MainUI() \ #define AffinityAssert_AllowFrom_MainUI() \
pxAssertMsg( wxThread::IsMain(), "Thread affinity violation: Call allowed from main thread only." ) pxAssertMsg(wxThread::IsMain(), "Thread affinity violation: Call allowed from main thread only.")
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// pxThreadLog / ConsoleLogSource_Threading // pxThreadLog / ConsoleLogSource_Threading
@ -37,22 +37,25 @@
class ConsoleLogSource_Threading : ConsoleLogSource class ConsoleLogSource_Threading : ConsoleLogSource
{ {
typedef ConsoleLogSource _parent; typedef ConsoleLogSource _parent;
public: public:
using _parent::IsActive; using _parent::IsActive;
ConsoleLogSource_Threading(); ConsoleLogSource_Threading();
bool Write( const wxString& thrname, const wxChar* msg ) { bool Write(const wxString &thrname, const wxChar *msg)
return _parent::Write( wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg ); {
} return _parent::Write(wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg);
bool Warn( const wxString& thrname, const wxChar* msg ) { }
return _parent::Warn( wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg ); bool Warn(const wxString &thrname, const wxChar *msg)
} {
bool Error( const wxString& thrname, const wxChar* msg ) { return _parent::Warn(wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg);
return _parent::Error( wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg ); }
} bool Error(const wxString &thrname, const wxChar *msg)
{
return _parent::Error(wxsFormat(L"(thread:%s) ", WX_STR(thrname)) + msg);
}
}; };
extern ConsoleLogSource_Threading pxConLog_Thread; extern ConsoleLogSource_Threading pxConLog_Thread;
@ -69,79 +72,80 @@ extern ConsoleLogSource_Threading pxConLog_Thread;
//#define PCSX2_THREAD_LOCAL 0 // uncomment this line to force-disable native TLS (useful for testing TlsVariable on windows/linux) //#define PCSX2_THREAD_LOCAL 0 // uncomment this line to force-disable native TLS (useful for testing TlsVariable on windows/linux)
#ifndef PCSX2_THREAD_LOCAL #ifndef PCSX2_THREAD_LOCAL
# define PCSX2_THREAD_LOCAL 1 #define PCSX2_THREAD_LOCAL 1
#endif #endif
class wxTimeSpan; class wxTimeSpan;
namespace Threading namespace Threading
{ {
class pxThread; class pxThread;
class RwMutex; class RwMutex;
extern void pxTestCancel(); extern void pxTestCancel();
extern pxThread* pxGetCurrentThread(); extern pxThread *pxGetCurrentThread();
extern wxString pxGetCurrentThreadName(); extern wxString pxGetCurrentThreadName();
extern u64 GetThreadCpuTime(); extern u64 GetThreadCpuTime();
extern u64 GetThreadTicksPerSecond(); extern u64 GetThreadTicksPerSecond();
// Yields the current thread and provides cancellation points if the thread is managed by // Yields the current thread and provides cancellation points if the thread is managed by
// pxThread. Unmanaged threads use standard Sleep. // pxThread. Unmanaged threads use standard Sleep.
extern void pxYield( int ms ); extern void pxYield(int ms);
} }
namespace Exception namespace Exception
{ {
class BaseThreadError : public RuntimeError class BaseThreadError : public RuntimeError
{ {
DEFINE_EXCEPTION_COPYTORS( BaseThreadError, RuntimeError ) DEFINE_EXCEPTION_COPYTORS(BaseThreadError, RuntimeError)
DEFINE_EXCEPTION_MESSAGES( BaseThreadError ) DEFINE_EXCEPTION_MESSAGES(BaseThreadError)
public: public:
Threading::pxThread* m_thread; Threading::pxThread *m_thread;
protected: protected:
BaseThreadError() { BaseThreadError()
m_thread = NULL; {
} m_thread = NULL;
}
public: public:
explicit BaseThreadError( Threading::pxThread* _thread ) explicit BaseThreadError(Threading::pxThread *_thread)
{ {
m_thread = _thread; m_thread = _thread;
m_message_diag = L"An unspecified thread-related error occurred (thread=%s)"; m_message_diag = L"An unspecified thread-related error occurred (thread=%s)";
} }
explicit BaseThreadError( Threading::pxThread& _thread ) explicit BaseThreadError(Threading::pxThread &_thread)
{ {
m_thread = &_thread; m_thread = &_thread;
m_message_diag = L"An unspecified thread-related error occurred (thread=%s)"; m_message_diag = L"An unspecified thread-related error occurred (thread=%s)";
} }
virtual wxString FormatDiagnosticMessage() const; virtual wxString FormatDiagnosticMessage() const;
virtual wxString FormatDisplayMessage() const; virtual wxString FormatDisplayMessage() const;
Threading::pxThread& Thread(); Threading::pxThread &Thread();
const Threading::pxThread& Thread() const; const Threading::pxThread &Thread() const;
}; };
class ThreadCreationError : public BaseThreadError class ThreadCreationError : public BaseThreadError
{ {
DEFINE_EXCEPTION_COPYTORS( ThreadCreationError, BaseThreadError ) DEFINE_EXCEPTION_COPYTORS(ThreadCreationError, BaseThreadError)
public: public:
explicit ThreadCreationError( Threading::pxThread* _thread ) explicit ThreadCreationError(Threading::pxThread *_thread)
{ {
m_thread = _thread; m_thread = _thread;
SetBothMsgs( L"Thread creation failure. An unspecified error occurred while trying to create the %s thread." ); SetBothMsgs(L"Thread creation failure. An unspecified error occurred while trying to create the %s thread.");
} }
explicit ThreadCreationError( Threading::pxThread& _thread ) explicit ThreadCreationError(Threading::pxThread &_thread)
{ {
m_thread = &_thread; m_thread = &_thread;
SetBothMsgs( L"Thread creation failure. An unspecified error occurred while trying to create the %s thread." ); SetBothMsgs(L"Thread creation failure. An unspecified error occurred while trying to create the %s thread.");
} }
}; };
} }
@ -153,22 +157,22 @@ namespace Threading
// The following set of documented functions have Linux/Win32 specific implementations, // The following set of documented functions have Linux/Win32 specific implementations,
// which are found in WinThreads.cpp and LnxThreads.cpp // which are found in WinThreads.cpp and LnxThreads.cpp
// Releases a timeslice to other threads. // Releases a timeslice to other threads.
extern void Timeslice(); extern void Timeslice();
// For use in spin/wait loops. // For use in spin/wait loops.
extern void SpinWait(); extern void SpinWait();
// Optional implementation to enable hires thread/process scheduler for the operating system. // Optional implementation to enable hires thread/process scheduler for the operating system.
// Needed by Windows, but might not be relevant to other platforms. // Needed by Windows, but might not be relevant to other platforms.
extern void EnableHiresScheduler(); extern void EnableHiresScheduler();
extern void DisableHiresScheduler(); extern void DisableHiresScheduler();
// sleeps the current thread for the given number of milliseconds. // sleeps the current thread for the given number of milliseconds.
extern void Sleep( int ms ); extern void Sleep(int ms);
// pthread Cond is an evil api that is not suited for Pcsx2 needs. // pthread Cond is an evil api that is not suited for Pcsx2 needs.
// Let's not use it. Use mutexes and semaphores instead to create waits. (Air) // Let's not use it. Use mutexes and semaphores instead to create waits. (Air)
#if 0 #if 0
struct WaitEvent struct WaitEvent
{ {
@ -194,181 +198,187 @@ namespace Threading
// If TryAcquire() returns true, you've locked the object and are *responsible* for unlocking // If TryAcquire() returns true, you've locked the object and are *responsible* for unlocking
// it later. // it later.
// //
class NonblockingMutex class NonblockingMutex
{ {
protected: protected:
std::atomic_flag val; std::atomic_flag val;
public: public:
NonblockingMutex() { val.clear(); } NonblockingMutex() { val.clear(); }
virtual ~NonblockingMutex() throw() {} virtual ~NonblockingMutex() throw() {}
bool TryAcquire() throw() bool TryAcquire() throw()
{ {
return !val.test_and_set(); return !val.test_and_set();
} }
// Can be done with a TryAcquire/Release but it is likely better to do it outside of the object // Can be done with a TryAcquire/Release but it is likely better to do it outside of the object
bool IsLocked() bool IsLocked()
{ pxAssertMsg(0, "IsLocked isn't supported for NonblockingMutex"); return false; } {
pxAssertMsg(0, "IsLocked isn't supported for NonblockingMutex");
return false;
}
void Release() void Release()
{ {
val.clear(); val.clear();
} }
}; };
class Semaphore class Semaphore
{ {
protected: protected:
#ifdef __APPLE__ #ifdef __APPLE__
semaphore_t m_sema; semaphore_t m_sema;
int m_counter; int m_counter;
#else #else
sem_t m_sema; sem_t m_sema;
#endif #endif
public: public:
Semaphore(); Semaphore();
virtual ~Semaphore() throw(); virtual ~Semaphore() throw();
void Reset(); void Reset();
void Post(); void Post();
void Post( int multiple ); void Post(int multiple);
void WaitWithoutYield(); void WaitWithoutYield();
bool WaitWithoutYield( const wxTimeSpan& timeout ); bool WaitWithoutYield(const wxTimeSpan &timeout);
void WaitNoCancel(); void WaitNoCancel();
void WaitNoCancel( const wxTimeSpan& timeout ); void WaitNoCancel(const wxTimeSpan &timeout);
int Count(); int Count();
void Wait(); void Wait();
bool Wait( const wxTimeSpan& timeout ); bool Wait(const wxTimeSpan &timeout);
}; };
class Mutex class Mutex
{ {
protected: protected:
pthread_mutex_t m_mutex; pthread_mutex_t m_mutex;
public: public:
Mutex(); Mutex();
virtual ~Mutex() throw(); virtual ~Mutex() throw();
virtual bool IsRecursive() const { return false; } virtual bool IsRecursive() const { return false; }
void Recreate(); void Recreate();
bool RecreateIfLocked(); bool RecreateIfLocked();
void Detach(); void Detach();
void Acquire(); void Acquire();
bool Acquire( const wxTimeSpan& timeout ); bool Acquire(const wxTimeSpan &timeout);
bool TryAcquire(); bool TryAcquire();
void Release(); void Release();
void AcquireWithoutYield(); void AcquireWithoutYield();
bool AcquireWithoutYield( const wxTimeSpan& timeout ); bool AcquireWithoutYield(const wxTimeSpan &timeout);
void Wait(); void Wait();
bool Wait( const wxTimeSpan& timeout ); bool Wait(const wxTimeSpan &timeout);
void WaitWithoutYield(); void WaitWithoutYield();
bool WaitWithoutYield( const wxTimeSpan& timeout ); bool WaitWithoutYield(const wxTimeSpan &timeout);
protected: protected:
// empty constructor used by MutexLockRecursive // empty constructor used by MutexLockRecursive
Mutex( bool ) {} Mutex(bool) {}
}; };
class MutexRecursive : public Mutex class MutexRecursive : public Mutex
{ {
public: public:
MutexRecursive(); MutexRecursive();
virtual ~MutexRecursive() throw(); virtual ~MutexRecursive() throw();
virtual bool IsRecursive() const { return true; } virtual bool IsRecursive() const { return true; }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ScopedLock // ScopedLock
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Helper class for using Mutexes. Using this class provides an exception-safe (and // Helper class for using Mutexes. Using this class provides an exception-safe (and
// generally clean) method of locking code inside a function or conditional block. The lock // generally clean) method of locking code inside a function or conditional block. The lock
// will be automatically released on any return or exit from the function. // will be automatically released on any return or exit from the function.
// //
// Const qualification note: // Const qualification note:
// ScopedLock takes const instances of the mutex, even though the mutex is modified // ScopedLock takes const instances of the mutex, even though the mutex is modified
// by locking and unlocking. Two rationales: // by locking and unlocking. Two rationales:
// //
// 1) when designing classes with accessors (GetString, GetValue, etc) that need mutexes, // 1) when designing classes with accessors (GetString, GetValue, etc) that need mutexes,
// this class needs a const hack to allow those accessors to be const (which is typically // this class needs a const hack to allow those accessors to be const (which is typically
// *very* important). // *very* important).
// //
// 2) The state of the Mutex is guaranteed to be unchanged when the calling function or // 2) The state of the Mutex is guaranteed to be unchanged when the calling function or
// scope exits, by any means. Only via manual calls to Release or Acquire does that // scope exits, by any means. Only via manual calls to Release or Acquire does that
// change, and typically those are only used in very special circumstances of their own. // change, and typically those are only used in very special circumstances of their own.
// //
class ScopedLock class ScopedLock
{ {
DeclareNoncopyableObject(ScopedLock); DeclareNoncopyableObject(ScopedLock);
protected: protected:
Mutex* m_lock; Mutex *m_lock;
bool m_IsLocked; bool m_IsLocked;
public: public:
virtual ~ScopedLock() throw(); virtual ~ScopedLock() throw();
explicit ScopedLock( const Mutex* locker=NULL ); explicit ScopedLock(const Mutex *locker = NULL);
explicit ScopedLock( const Mutex& locker ); explicit ScopedLock(const Mutex &locker);
void AssignAndLock( const Mutex& locker ); void AssignAndLock(const Mutex &locker);
void AssignAndLock( const Mutex* locker ); void AssignAndLock(const Mutex *locker);
void Assign( const Mutex& locker ); void Assign(const Mutex &locker);
void Assign( const Mutex* locker ); void Assign(const Mutex *locker);
void Release(); void Release();
void Acquire(); void Acquire();
bool IsLocked() const { return m_IsLocked; } bool IsLocked() const { return m_IsLocked; }
protected: protected:
// Special constructor used by ScopedTryLock // Special constructor used by ScopedTryLock
ScopedLock( const Mutex& locker, bool isTryLock ); ScopedLock(const Mutex &locker, bool isTryLock);
}; };
class ScopedTryLock : public ScopedLock class ScopedTryLock : public ScopedLock
{ {
public: public:
ScopedTryLock( const Mutex& locker ) : ScopedLock( locker, true ) { } ScopedTryLock(const Mutex &locker)
virtual ~ScopedTryLock() throw() {} : ScopedLock(locker, true)
bool Failed() const { return !m_IsLocked; } {
}; }
virtual ~ScopedTryLock() throw() {}
bool Failed() const { return !m_IsLocked; }
};
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ScopedNonblockingLock // ScopedNonblockingLock
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// A ScopedTryLock branded for use with Nonblocking mutexes. See ScopedTryLock for details. // A ScopedTryLock branded for use with Nonblocking mutexes. See ScopedTryLock for details.
// //
class ScopedNonblockingLock class ScopedNonblockingLock
{ {
DeclareNoncopyableObject(ScopedNonblockingLock); DeclareNoncopyableObject(ScopedNonblockingLock);
protected: protected:
NonblockingMutex& m_lock; NonblockingMutex &m_lock;
bool m_IsLocked; bool m_IsLocked;
public: public:
ScopedNonblockingLock( NonblockingMutex& locker ) : ScopedNonblockingLock(NonblockingMutex &locker)
m_lock( locker ) : m_lock(locker)
, m_IsLocked( m_lock.TryAcquire() ) , m_IsLocked(m_lock.TryAcquire())
{ {
} }
virtual ~ScopedNonblockingLock() throw() virtual ~ScopedNonblockingLock() throw()
{ {
if( m_IsLocked ) if (m_IsLocked)
m_lock.Release(); m_lock.Release();
} }
bool Failed() const { return !m_IsLocked; } bool Failed() const { return !m_IsLocked; }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ScopedLockBool // ScopedLockBool
@ -377,26 +387,30 @@ namespace Threading
// Note that the isLockedBool should only be used as an indicator for the locked status, // Note that the isLockedBool should only be used as an indicator for the locked status,
// and not actually depended on for thread synchronization... // and not actually depended on for thread synchronization...
struct ScopedLockBool { struct ScopedLockBool
ScopedLock m_lock; {
std::atomic<bool>& m_bool; ScopedLock m_lock;
std::atomic<bool> &m_bool;
ScopedLockBool(Mutex& mutexToLock, std::atomic<bool>& isLockedBool) ScopedLockBool(Mutex &mutexToLock, std::atomic<bool> &isLockedBool)
: m_lock(mutexToLock), : m_lock(mutexToLock)
m_bool(isLockedBool) { , m_bool(isLockedBool)
m_bool.store(m_lock.IsLocked(), std::memory_order_relaxed); {
} m_bool.store(m_lock.IsLocked(), std::memory_order_relaxed);
virtual ~ScopedLockBool() throw() { }
m_bool.store(false, std::memory_order_relaxed); virtual ~ScopedLockBool() throw()
} {
void Acquire() { m_bool.store(false, std::memory_order_relaxed);
m_lock.Acquire(); }
m_bool.store(m_lock.IsLocked(), std::memory_order_relaxed); void Acquire()
} {
void Release() { m_lock.Acquire();
m_bool.store(false, std::memory_order_relaxed); m_bool.store(m_lock.IsLocked(), std::memory_order_relaxed);
m_lock.Release(); }
} void Release()
}; {
m_bool.store(false, std::memory_order_relaxed);
m_lock.Release();
}
};
} }

View File

@ -22,32 +22,31 @@ wxDECLARE_EVENT(pxEvt_ThreadedTaskComplete, wxCommandEvent);
namespace Threading namespace Threading
{ {
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// WaitForTaskDialog // WaitForTaskDialog
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// This dialog is displayed whenever the main thread is recursively waiting on multiple // This dialog is displayed whenever the main thread is recursively waiting on multiple
// mutexes or semaphores. wxwidgets does not support recursive yielding to pending events // mutexes or semaphores. wxwidgets does not support recursive yielding to pending events
// but it *does* support opening a modal dialog, which disables the interface (preventing // but it *does* support opening a modal dialog, which disables the interface (preventing
// the user from starting additional actions), and processes messages (allowing the system // the user from starting additional actions), and processes messages (allowing the system
// to continue to manage threads and process logging). // to continue to manage threads and process logging).
// //
class WaitForTaskDialog : public wxDialogWithHelpers class WaitForTaskDialog : public wxDialogWithHelpers
{ {
DECLARE_DYNAMIC_CLASS_NO_COPY(WaitForTaskDialog) DECLARE_DYNAMIC_CLASS_NO_COPY(WaitForTaskDialog)
typedef wxDialogWithHelpers _parent; typedef wxDialogWithHelpers _parent;
protected: protected:
SynchronousActionState m_sync; SynchronousActionState m_sync;
public: public:
WaitForTaskDialog( const wxString& title=wxEmptyString, const wxString& heading=wxEmptyString ); WaitForTaskDialog(const wxString &title = wxEmptyString, const wxString &heading = wxEmptyString);
virtual ~WaitForTaskDialog() throw() {} virtual ~WaitForTaskDialog() throw() {}
virtual int ShowModal(); virtual int ShowModal();
protected:
void OnTaskComplete( wxCommandEvent& evt );
//void OnTimer( wxTimerEvent& evt );
};
protected:
void OnTaskComplete(wxCommandEvent &evt);
//void OnTimer( wxTimerEvent& evt );
};
} }

View File

@ -18,9 +18,9 @@
#include "Threading.h" #include "Threading.h"
#if PCSX2_THREAD_LOCAL #if PCSX2_THREAD_LOCAL
# define DeclareTls(x) __threadlocal x #define DeclareTls(x) __threadlocal x
#else #else
# define DeclareTls(x) Threading::TlsVariable<x> #define DeclareTls(x) Threading::TlsVariable<x>
#endif #endif
namespace Threading namespace Threading
@ -38,152 +38,153 @@ namespace Threading
// result in repeated calls to pthread_getspecific. (if the function inlines then it // result in repeated calls to pthread_getspecific. (if the function inlines then it
// should actually optimize well enough, but I doubt it does). // should actually optimize well enough, but I doubt it does).
// //
template< typename T > template <typename T>
class BaseTlsVariable class BaseTlsVariable
{ {
DeclareNoncopyableObject(BaseTlsVariable<T>); DeclareNoncopyableObject(BaseTlsVariable<T>);
protected: protected:
pthread_key_t m_thread_key; pthread_key_t m_thread_key;
bool m_IsDisposed; bool m_IsDisposed;
public: public:
BaseTlsVariable(); BaseTlsVariable();
virtual ~BaseTlsVariable() throw() virtual ~BaseTlsVariable() throw()
{ {
Dispose(); Dispose();
} }
T* GetPtr() const; T *GetPtr() const;
T& GetRef() const { return *GetPtr(); } T &GetRef() const { return *GetPtr(); }
operator T&() const { return GetRef(); } operator T &() const { return GetRef(); }
T* operator->() const { return GetPtr(); } T *operator->() const { return GetPtr(); }
void Dispose() void Dispose()
{ {
if (!m_IsDisposed) if (!m_IsDisposed) {
{ m_IsDisposed = true;
m_IsDisposed = true; KillKey();
KillKey(); }
} }
}
protected: protected:
void CreateKey(); void CreateKey();
void KillKey(); void KillKey();
virtual void CreateInstance( T* result ) const virtual void CreateInstance(T *result) const
{ {
new (result) T(); new (result) T();
} }
static void _aligned_delete_and_free( void* ptr ) static void _aligned_delete_and_free(void *ptr)
{ {
if (!ptr) return; if (!ptr)
((T*)ptr)->~T(); return;
_aligned_free(ptr); ((T *)ptr)->~T();
} _aligned_free(ptr);
}
}; };
template< typename T > template <typename T>
class TlsVariable : public BaseTlsVariable<T> class TlsVariable : public BaseTlsVariable<T>
{ {
DeclareNoncopyableObject(TlsVariable<T>); DeclareNoncopyableObject(TlsVariable<T>);
protected: protected:
T m_initval; T m_initval;
public: public:
TlsVariable() {} TlsVariable() {}
TlsVariable( const T& initval ) TlsVariable(const T &initval)
: m_initval(initval) { } : m_initval(initval)
{
}
// This is needed; The C++ standard likes making life suck for programmers. // This is needed; The C++ standard likes making life suck for programmers.
using BaseTlsVariable<T>::GetRef; using BaseTlsVariable<T>::GetRef;
virtual ~TlsVariable() throw() virtual ~TlsVariable() throw()
{ {
// disable the parent cleanup. This leaks memory blocks, but its necessary because // disable the parent cleanup. This leaks memory blocks, but its necessary because
// TLS is expected to be persistent until the very end of execution on the main thread. // TLS is expected to be persistent until the very end of execution on the main thread.
// Killing the pthread_key at all will lead to the console logger death, etc. // Killing the pthread_key at all will lead to the console logger death, etc.
// DON'T REMOVE this->, the "official"[ly stupid] C++ standard requires it because of its
// insistence that variables be looked up during initial template parsing and not during
// instantiation.
this->m_IsDisposed = true;
}
TlsVariable<T>& operator=( const T& src ) // DON'T REMOVE this->, the "official"[ly stupid] C++ standard requires it because of its
{ // insistence that variables be looked up during initial template parsing and not during
GetRef() = src; // instantiation.
return *this; this->m_IsDisposed = true;
} }
bool operator==( const T& src ) const { return GetRef() == src; } TlsVariable<T> &operator=(const T &src)
bool operator!=( const T& src ) const { return GetRef() != src; } {
bool operator>( const T& src ) const { return GetRef() > src; } GetRef() = src;
bool operator<( const T& src ) const { return GetRef() < src; } return *this;
bool operator>=( const T& src ) const { return GetRef() >= src; } }
bool operator<=( const T& src ) const { return GetRef() <= src; }
T operator+( const T& src ) const { return GetRef() + src; } bool operator==(const T &src) const { return GetRef() == src; }
T operator-( const T& src ) const { return GetRef() - src; } bool operator!=(const T &src) const { return GetRef() != src; }
bool operator>(const T &src) const { return GetRef() > src; }
bool operator<(const T &src) const { return GetRef() < src; }
bool operator>=(const T &src) const { return GetRef() >= src; }
bool operator<=(const T &src) const { return GetRef() <= src; }
T operator+(const T &src) const { return GetRef() + src; }
T operator-(const T &src) const { return GetRef() - src; }
void operator+=(const T &src) { GetRef() += src; }
void operator-=(const T &src) { GetRef() -= src; }
void operator+=( const T& src ) { GetRef() += src; }
void operator-=( const T& src ) { GetRef() -= src; }
protected: protected:
virtual void CreateInstance( T* result ) const virtual void CreateInstance(T *result) const
{ {
new (result) T(m_initval); new (result) T(m_initval);
} }
}; };
}; };
template< typename T > template <typename T>
Threading::BaseTlsVariable<T>::BaseTlsVariable() Threading::BaseTlsVariable<T>::BaseTlsVariable()
{ {
m_IsDisposed = false; m_IsDisposed = false;
CreateKey(); CreateKey();
} }
template< typename T > template <typename T>
void Threading::BaseTlsVariable<T>::KillKey() void Threading::BaseTlsVariable<T>::KillKey()
{ {
if (!m_thread_key) return; if (!m_thread_key)
return;
// Delete the handle for the current thread (which should always be the main/UI thread!) // Delete the handle for the current thread (which should always be the main/UI thread!)
// This is needed because pthreads does *not* clean up the dangling objects when you delete // This is needed because pthreads does *not* clean up the dangling objects when you delete
// the key. The TLS for the process main thread will only be deleted when the process // the key. The TLS for the process main thread will only be deleted when the process
// ends; which is too damn late (it shows up int he leaked memory blocks). // ends; which is too damn late (it shows up int he leaked memory blocks).
BaseTlsVariable<T>::_aligned_delete_and_free( pthread_getspecific(m_thread_key) ); BaseTlsVariable<T>::_aligned_delete_and_free(pthread_getspecific(m_thread_key));
pthread_key_delete( m_thread_key ); pthread_key_delete(m_thread_key);
m_thread_key = 0; m_thread_key = 0;
} }
template< typename T > template <typename T>
T* Threading::BaseTlsVariable<T>::GetPtr() const T *Threading::BaseTlsVariable<T>::GetPtr() const
{ {
T* result = (T*)pthread_getspecific( m_thread_key ); T *result = (T *)pthread_getspecific(m_thread_key);
if( result == NULL ) if (result == NULL) {
{ pthread_setspecific(m_thread_key, result = (T *)_aligned_malloc(sizeof(T), 16));
pthread_setspecific( m_thread_key, result = (T*)_aligned_malloc(sizeof(T), 16) ); CreateInstance(result);
CreateInstance(result); if (result == NULL)
if( result == NULL ) throw Exception::OutOfMemory(L"thread local storage variable instance");
throw Exception::OutOfMemory( L"thread local storage variable instance" ); }
} return result;
return result;
} }
template< typename T > template <typename T>
void Threading::BaseTlsVariable<T>::CreateKey() void Threading::BaseTlsVariable<T>::CreateKey()
{ {
if( 0 != pthread_key_create(&m_thread_key, BaseTlsVariable<T>::_aligned_delete_and_free) ) if (0 != pthread_key_create(&m_thread_key, BaseTlsVariable<T>::_aligned_delete_and_free)) {
{ pxFailRel("Thread Local Storage Error: key creation failed. This will most likely lead to a rapid application crash.");
pxFailRel( "Thread Local Storage Error: key creation failed. This will most likely lead to a rapid application crash." ); }
}
} }

View File

@ -29,20 +29,20 @@
// //
struct TraceLogDescriptor struct TraceLogDescriptor
{ {
// short name, alphanumerics only: used for saving/loading options. // short name, alphanumerics only: used for saving/loading options.
const wxChar* ShortName; const wxChar *ShortName;
// Standard UI name for this log source. Used in menus, options dialogs. // Standard UI name for this log source. Used in menus, options dialogs.
const wxChar* Name; const wxChar *Name;
// Length description for use as a tooltip or menu item description. // Length description for use as a tooltip or menu item description.
const wxChar* Description; const wxChar *Description;
wxString GetShortName() const wxString GetShortName() const
{ {
pxAssumeDev(Name, "Tracelog descriptors require a valid name!"); pxAssumeDev(Name, "Tracelog descriptors require a valid name!");
return ShortName ? ShortName : Name; return ShortName ? ShortName : Name;
} }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -62,52 +62,55 @@ struct TraceLogDescriptor
// check is done top-level, the parameters' calculations can be skipped. If the IsActive() // check is done top-level, the parameters' calculations can be skipped. If the IsActive()
// check is done internally as part of the Write/Format calls, all parameters have to be // check is done internally as part of the Write/Format calls, all parameters have to be
// resolved regardless of if the log is actually active. // resolved regardless of if the log is actually active.
// //
class BaseTraceLogSource class BaseTraceLogSource
{ {
protected: protected:
const TraceLogDescriptor* m_Descriptor; const TraceLogDescriptor *m_Descriptor;
public: public:
// Indicates if the user has enabled this specific log. This boolean only represents // Indicates if the user has enabled this specific log. This boolean only represents
// the configured status of this log, and does *NOT* actually mean the log is active // the configured status of this log, and does *NOT* actually mean the log is active
// even when TRUE. Because many tracelogs have master enablers that act on a group // even when TRUE. Because many tracelogs have master enablers that act on a group
// of logs, logging checks should always use IsActive() instead to determine if a log // of logs, logging checks should always use IsActive() instead to determine if a log
// should be processed or not. // should be processed or not.
bool Enabled; bool Enabled;
protected: protected:
BaseTraceLogSource() : m_Descriptor(NULL), Enabled(false) {} BaseTraceLogSource()
: m_Descriptor(NULL)
, Enabled(false)
{
}
public: public:
TraceLog_ImplementBaseAPI(BaseTraceLogSource) TraceLog_ImplementBaseAPI(BaseTraceLogSource)
BaseTraceLogSource( const TraceLogDescriptor* desc ) BaseTraceLogSource(const TraceLogDescriptor *desc)
{ {
pxAssumeDev( desc, "Trace logs must have a valid (non-NULL) descriptor." ); pxAssumeDev(desc, "Trace logs must have a valid (non-NULL) descriptor.");
Enabled = false; Enabled = false;
m_Descriptor = desc; m_Descriptor = desc;
} }
// Provides a categorical identifier, typically in "group.subgroup.subgroup" form. // Provides a categorical identifier, typically in "group.subgroup.subgroup" form.
// (use periods in favor of colons, since they do not require escape characters when // (use periods in favor of colons, since they do not require escape characters when
// written to ini/config files). // written to ini/config files).
virtual wxString GetCategory() const { return wxEmptyString; } virtual wxString GetCategory() const { return wxEmptyString; }
// This method should be used to determine if a log should be generated or not. // This method should be used to determine if a log should be generated or not.
// See the class overview comments for details on how and why this method should // See the class overview comments for details on how and why this method should
// be used. // be used.
virtual bool IsActive() const { return Enabled; } virtual bool IsActive() const { return Enabled; }
virtual wxString GetShortName() const { return m_Descriptor->GetShortName(); } virtual wxString GetShortName() const { return m_Descriptor->GetShortName(); }
virtual const wxChar* GetName() const { return m_Descriptor->Name; } virtual const wxChar *GetName() const { return m_Descriptor->Name; }
virtual const wxChar* GetDescription() const virtual const wxChar *GetDescription() const
{ {
return (m_Descriptor->Description!=NULL) ? pxGetTranslation(m_Descriptor->Description) : wxEmptyString; return (m_Descriptor->Description != NULL) ? pxGetTranslation(m_Descriptor->Description) : wxEmptyString;
} }
virtual bool HasDescription() const { return m_Descriptor->Description != NULL;}
virtual bool HasDescription() const { return m_Descriptor->Description != NULL; }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -119,32 +122,32 @@ public:
class TextFileTraceLog : public BaseTraceLogSource class TextFileTraceLog : public BaseTraceLogSource
{ {
public: public:
TextFileTraceLog( const TraceLogDescriptor* desc ) TextFileTraceLog(const TraceLogDescriptor *desc)
: BaseTraceLogSource( desc ) : BaseTraceLogSource(desc)
{ {
} }
bool Write( const char* fmt, ... ) const bool Write(const char *fmt, ...) const
{ {
va_list list; va_list list;
va_start( list, fmt ); va_start(list, fmt);
WriteV( fmt, list ); WriteV(fmt, list);
va_end( list ); va_end(list);
return false; return false;
} }
bool WriteV( const char *fmt, va_list list ) const bool WriteV(const char *fmt, va_list list) const
{ {
FastFormatAscii ascii; FastFormatAscii ascii;
ApplyPrefix(ascii); ApplyPrefix(ascii);
ascii.WriteV( fmt, list ); ascii.WriteV(fmt, list);
DoWrite( ascii ); DoWrite(ascii);
return false; return false;
} }
virtual void ApplyPrefix( FastFormatAscii& ascii ) const {} virtual void ApplyPrefix(FastFormatAscii &ascii) const {}
virtual void DoWrite( const char* fmt ) const=0; virtual void DoWrite(const char *fmt) const = 0;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -156,128 +159,130 @@ public:
class ConsoleLogSource : public BaseTraceLogSource class ConsoleLogSource : public BaseTraceLogSource
{ {
public: public:
ConsoleColors DefaultColor; ConsoleColors DefaultColor;
protected: protected:
ConsoleLogSource() : DefaultColor(Color_Gray) {} ConsoleLogSource()
: DefaultColor(Color_Gray)
{
}
public: public:
ConsoleLog_ImplementBaseAPI(ConsoleLogSource) ConsoleLog_ImplementBaseAPI(ConsoleLogSource)
ConsoleLogSource( const TraceLogDescriptor* desc, ConsoleColors defaultColor = Color_Gray ) ConsoleLogSource(const TraceLogDescriptor *desc, ConsoleColors defaultColor = Color_Gray)
: BaseTraceLogSource(desc) : BaseTraceLogSource(desc)
{ {
DefaultColor = defaultColor; DefaultColor = defaultColor;
} }
// Writes to the console using the source's default color. Note that the source's default // Writes to the console using the source's default color. Note that the source's default
// color will always be used, thus ConsoleColorScope() will not be effectual unless the // color will always be used, thus ConsoleColorScope() will not be effectual unless the
// console's default color is Color_Default. // console's default color is Color_Default.
bool Write( const char* fmt, ... ) const bool Write(const char *fmt, ...) const
{ {
va_list list; va_list list;
va_start( list, fmt ); va_start(list, fmt);
WriteV( fmt, list ); WriteV(fmt, list);
va_end( list ); va_end(list);
return false; return false;
} }
bool Write( const wxChar* fmt, ... ) const bool Write(const wxChar *fmt, ...) const
{ {
va_list list; va_list list;
va_start( list, fmt ); va_start(list, fmt);
WriteV( fmt, list ); WriteV(fmt, list);
va_end( list ); va_end(list);
return false; return false;
} }
bool Write( const wxString fmt, ... ) const bool Write(const wxString fmt, ...) const
{ {
va_list list; va_list list;
va_start( list, fmt ); va_start(list, fmt);
WriteV( fmt.wx_str(), list ); WriteV(fmt.wx_str(), list);
va_end( list ); va_end(list);
return false; return false;
} }
// Writes to the console using the specified color. This overrides the default color setting // Writes to the console using the specified color. This overrides the default color setting
// for this log. // for this log.
bool Write( ConsoleColors color, const char* fmt, ... ) const bool Write(ConsoleColors color, const char *fmt, ...) const
{ {
va_list list; va_list list;
va_start( list, fmt ); va_start(list, fmt);
WriteV( color, fmt, list ); WriteV(color, fmt, list);
va_end( list ); va_end(list);
return false; return false;
} }
bool Write( ConsoleColors color, const wxChar* fmt, ... ) const bool Write(ConsoleColors color, const wxChar *fmt, ...) const
{ {
va_list list; va_list list;
va_start( list, fmt ); va_start(list, fmt);
WriteV( color, fmt, list ); WriteV(color, fmt, list);
va_end( list ); va_end(list);
return false; return false;
} }
// Writes to the console using bold yellow text -- overrides the log source's default // Writes to the console using bold yellow text -- overrides the log source's default
// color settings. // color settings.
bool Warn( const wxChar* fmt, ... ) const bool Warn(const wxChar *fmt, ...) const
{ {
va_list list; va_list list;
va_start( list, fmt ); va_start(list, fmt);
WriteV( Color_StrongYellow, fmt, list ); WriteV(Color_StrongYellow, fmt, list);
va_end( list ); va_end(list);
return false; return false;
} }
bool Warn( const wxString fmt, ... ) const bool Warn(const wxString fmt, ...) const
{ {
va_list list; va_list list;
va_start( list, fmt ); va_start(list, fmt);
WriteV( Color_StrongYellow, fmt.wx_str(), list ); WriteV(Color_StrongYellow, fmt.wx_str(), list);
va_end( list ); va_end(list);
return false; return false;
} }
// Writes to the console using bold red text -- overrides the log source's default // Writes to the console using bold red text -- overrides the log source's default
// color settings. // color settings.
bool Error( const wxChar* fmt, ... ) const bool Error(const wxChar *fmt, ...) const
{ {
va_list list; va_list list;
va_start( list, fmt ); va_start(list, fmt);
WriteV( Color_StrongRed, fmt, list ); WriteV(Color_StrongRed, fmt, list);
va_end( list ); va_end(list);
return false; return false;
} }
bool Error( const wxString fmt, ... ) const bool Error(const wxString fmt, ...) const
{ {
va_list list; va_list list;
va_start( list, fmt ); va_start(list, fmt);
WriteV( Color_StrongRed, fmt.wx_str(), list ); WriteV(Color_StrongRed, fmt.wx_str(), list);
va_end( list ); va_end(list);
return false; return false;
} }
bool WriteV( const char *fmt, va_list list ) const; bool WriteV(const char *fmt, va_list list) const;
bool WriteV( const wxChar *fmt, va_list list ) const; bool WriteV(const wxChar *fmt, va_list list) const;
bool WriteV( ConsoleColors color, const char *fmt, va_list list ) const; bool WriteV(ConsoleColors color, const char *fmt, va_list list) const;
bool WriteV( ConsoleColors color, const wxChar *fmt, va_list list ) const; bool WriteV(ConsoleColors color, const wxChar *fmt, va_list list) const;
virtual void DoWrite( const wxChar* msg ) const virtual void DoWrite(const wxChar *msg) const
{ {
Console.DoWriteLn( msg ); Console.DoWriteLn(msg);
} }
}; };

View File

@ -18,43 +18,43 @@
// This header contains non-optimized implementation of memzero_ptr and memset8, etc // This header contains non-optimized implementation of memzero_ptr and memset8, etc
template< u32 data, typename T > template <u32 data, typename T>
static __fi void memset32( T& obj ) static __fi void memset32(T &obj)
{ {
// this function works on 32-bit aligned lengths of data only. // this function works on 32-bit aligned lengths of data only.
// If the data length is not a factor of 32 bits, the C++ optimizing compiler will // If the data length is not a factor of 32 bits, the C++ optimizing compiler will
// probably just generate mysteriously broken code in Release builds. ;) // probably just generate mysteriously broken code in Release builds. ;)
pxAssume((sizeof(T) & 0x3) == 0); pxAssume((sizeof(T) & 0x3) == 0);
u32* dest = (u32*)&obj; u32 *dest = (u32 *)&obj;
for( int i=sizeof(T)>>2; i; --i, ++dest ) for (int i = sizeof(T) >> 2; i; --i, ++dest)
*dest = data; *dest = data;
} }
template< typename T > template <typename T>
static __fi void memzero( T& obj ) static __fi void memzero(T &obj)
{ {
memset( &obj, 0, sizeof( T ) ); memset(&obj, 0, sizeof(T));
} }
template< u8 data, typename T > template <u8 data, typename T>
static __fi void memset8( T& obj ) static __fi void memset8(T &obj)
{ {
// Aligned sizes use the optimized 32 bit inline memset. Unaligned sizes use memset. // Aligned sizes use the optimized 32 bit inline memset. Unaligned sizes use memset.
if( (sizeof(T) & 0x3) != 0 ) if ((sizeof(T) & 0x3) != 0)
memset( &obj, data, sizeof( T ) ); memset(&obj, data, sizeof(T));
else { else {
const u32 data32 = data + (data<<8) + (data<<16) + (data<<24); const u32 data32 = data + (data << 8) + (data << 16) + (data << 24);
memset32<data32>( obj ); memset32<data32>(obj);
} }
} }
// Code is only called in the init so no need to bother with ASM // Code is only called in the init so no need to bother with ASM
template< u8 data, size_t bytes > template <u8 data, size_t bytes>
static __fi void memset_8( void *dest ) static __fi void memset_8(void *dest)
{ {
memset(dest, data, bytes); memset(dest, data, bytes);
} }
#endif #endif

View File

@ -29,50 +29,74 @@
class pxCheckBox : public wxPanelWithHelpers class pxCheckBox : public wxPanelWithHelpers
{ {
protected: protected:
wxCheckBox* m_checkbox; wxCheckBox *m_checkbox;
pxStaticText* m_subtext; pxStaticText *m_subtext;
// padding below the subtext (if there's subtext). If there's no subtext, this value is unused. // padding below the subtext (if there's subtext). If there's no subtext, this value is unused.
int m_subPadding; int m_subPadding;
wxSizerItem *m_sizerItem_subtext;
wxSizerItem* m_sizerItem_subtext;
public: public:
pxCheckBox( wxWindow* parent, const wxString& label, const wxString& subtext=wxEmptyString, int flags = wxCHK_2STATE ); pxCheckBox(wxWindow *parent, const wxString &label, const wxString &subtext = wxEmptyString, int flags = wxCHK_2STATE);
pxCheckBox( wxWindow* parent, const wxString& label, int flags ); pxCheckBox(wxWindow *parent, const wxString &label, int flags);
virtual ~pxCheckBox() throw() {} virtual ~pxCheckBox() throw() {}
bool HasSubText() const { return m_subtext != NULL; } bool HasSubText() const { return m_subtext != NULL; }
const pxStaticText* GetSubText() const { return m_subtext; } const pxStaticText *GetSubText() const { return m_subtext; }
pxCheckBox& SetSubPadding( int pad ); pxCheckBox &SetSubPadding(int pad);
pxCheckBox& SetToolTip( const wxString& tip ); pxCheckBox &SetToolTip(const wxString &tip);
pxCheckBox& SetValue( bool val ); pxCheckBox &SetValue(bool val);
pxCheckBox& SetIndeterminate(); pxCheckBox &SetIndeterminate();
pxCheckBox& SetState( wxCheckBoxState state ); pxCheckBox &SetState(wxCheckBoxState state);
wxCheckBoxState GetState() const { pxAssert( m_checkbox != NULL ); return m_checkbox->Get3StateValue(); } wxCheckBoxState GetState() const
bool GetValue() const { pxAssert( m_checkbox != NULL ); return m_checkbox->GetValue(); } {
bool IsChecked() const { pxAssert( m_checkbox != NULL ); return m_checkbox->IsChecked(); } pxAssert(m_checkbox != NULL);
bool IsIndeterminate() const { pxAssert( m_checkbox != NULL ); return m_checkbox->Get3StateValue() == wxCHK_UNDETERMINED; } return m_checkbox->Get3StateValue();
operator wxCheckBox&() { pxAssert( m_checkbox != NULL ); return *m_checkbox; } }
operator const wxCheckBox&() const { pxAssert( m_checkbox != NULL ); return *m_checkbox; } bool GetValue() const
{
pxAssert(m_checkbox != NULL);
return m_checkbox->GetValue();
}
bool IsChecked() const
{
pxAssert(m_checkbox != NULL);
return m_checkbox->IsChecked();
}
bool IsIndeterminate() const
{
pxAssert(m_checkbox != NULL);
return m_checkbox->Get3StateValue() == wxCHK_UNDETERMINED;
}
operator wxCheckBox &()
{
pxAssert(m_checkbox != NULL);
return *m_checkbox;
}
operator const wxCheckBox &() const
{
pxAssert(m_checkbox != NULL);
return *m_checkbox;
}
wxCheckBox* GetWxPtr() { return m_checkbox; } wxCheckBox *GetWxPtr() { return m_checkbox; }
const wxCheckBox* GetWxPtr() const { return m_checkbox; } const wxCheckBox *GetWxPtr() const { return m_checkbox; }
//wxWindowID GetId() const { pxAssert( m_checkbox != NULL ); return m_checkbox->GetId(); } //wxWindowID GetId() const { pxAssert( m_checkbox != NULL ); return m_checkbox->GetId(); }
protected: protected:
void Init( const wxString& label, const wxString& subtext, int flags ); void Init(const wxString &label, const wxString &subtext, int flags);
void OnCheckpartCommand( wxCommandEvent& evt ); void OnCheckpartCommand(wxCommandEvent &evt);
void OnSubtextClicked( wxCommandEvent& evt ); void OnSubtextClicked(wxCommandEvent &evt);
}; };
extern void operator+=( wxSizer& target, pxCheckBox& src ); extern void operator+=(wxSizer &target, pxCheckBox &src);
template<> template <>
inline void operator+=( wxSizer& target, const pxWindowAndFlags<pxCheckBox>& src ) inline void operator+=(wxSizer &target, const pxWindowAndFlags<pxCheckBox> &src)
{ {
target.Add( src.window, src.flags ); target.Add(src.window, src.flags);
} }

View File

@ -26,36 +26,36 @@ typedef void FnType_Void();
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class SynchronousActionState class SynchronousActionState
{ {
DeclareNoncopyableObject( SynchronousActionState ); DeclareNoncopyableObject(SynchronousActionState);
protected: protected:
bool m_posted; bool m_posted;
Threading::Semaphore m_sema; Threading::Semaphore m_sema;
ScopedExcept m_exception; ScopedExcept m_exception;
public: public:
sptr return_value; sptr return_value;
SynchronousActionState() SynchronousActionState()
{ {
m_posted = false; m_posted = false;
return_value = 0; return_value = 0;
} }
virtual ~SynchronousActionState() throw() {} virtual ~SynchronousActionState() throw() {}
void SetException( const BaseException& ex ); void SetException(const BaseException &ex);
void SetException( BaseException* ex ); void SetException(BaseException *ex);
Threading::Semaphore& GetSemaphore() { return m_sema; } Threading::Semaphore &GetSemaphore() { return m_sema; }
const Threading::Semaphore& GetSemaphore() const { return m_sema; } const Threading::Semaphore &GetSemaphore() const { return m_sema; }
void RethrowException() const; void RethrowException() const;
int WaitForResult(); int WaitForResult();
int WaitForResult_NoExceptions(); int WaitForResult_NoExceptions();
void PostResult( int res ); void PostResult(int res);
void ClearResult(); void ClearResult();
void PostResult(); void PostResult();
}; };
@ -68,18 +68,20 @@ public:
// //
class pxSimpleEvent : public wxEvent class pxSimpleEvent : public wxEvent
{ {
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSimpleEvent) DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSimpleEvent)
public: public:
explicit pxSimpleEvent( int evtid=0 ) explicit pxSimpleEvent(int evtid = 0)
: wxEvent(0, evtid) : wxEvent(0, evtid)
{ } {
}
pxSimpleEvent( wxWindowID winId, int evtid ) pxSimpleEvent(wxWindowID winId, int evtid)
: wxEvent(winId, evtid) : wxEvent(winId, evtid)
{ } {
}
virtual wxEvent *Clone() const { return new pxSimpleEvent(*this); } virtual wxEvent *Clone() const { return new pxSimpleEvent(*this); }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -91,41 +93,41 @@ wxDECLARE_EVENT(pxEvt_InvokeAction, pxActionEvent);
class pxActionEvent : public wxEvent class pxActionEvent : public wxEvent
{ {
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxActionEvent) DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxActionEvent)
protected: protected:
SynchronousActionState* m_state; SynchronousActionState *m_state;
public: public:
virtual ~pxActionEvent() throw() { } virtual ~pxActionEvent() throw() {}
virtual pxActionEvent *Clone() const { return new pxActionEvent(*this); } virtual pxActionEvent *Clone() const { return new pxActionEvent(*this); }
explicit pxActionEvent( SynchronousActionState* sema=NULL, int msgtype=pxEvt_InvokeAction ); explicit pxActionEvent(SynchronousActionState *sema = NULL, int msgtype = pxEvt_InvokeAction);
explicit pxActionEvent( SynchronousActionState& sema, int msgtype=pxEvt_InvokeAction ); explicit pxActionEvent(SynchronousActionState &sema, int msgtype = pxEvt_InvokeAction);
pxActionEvent( const pxActionEvent& src ); pxActionEvent(const pxActionEvent &src);
Threading::Semaphore* GetSemaphore() const { return m_state ? &m_state->GetSemaphore() : NULL; } Threading::Semaphore *GetSemaphore() const { return m_state ? &m_state->GetSemaphore() : NULL; }
const SynchronousActionState* GetSyncState() const { return m_state; } const SynchronousActionState *GetSyncState() const { return m_state; }
SynchronousActionState* GetSyncState() { return m_state; } SynchronousActionState *GetSyncState() { return m_state; }
void SetSyncState( SynchronousActionState* obj ) { m_state = obj; } void SetSyncState(SynchronousActionState *obj) { m_state = obj; }
void SetSyncState( SynchronousActionState& obj ) { m_state = &obj; } void SetSyncState(SynchronousActionState &obj) { m_state = &obj; }
virtual void SetException( BaseException* ex ); virtual void SetException(BaseException *ex);
void SetException( const BaseException& ex ); void SetException(const BaseException &ex);
virtual void _DoInvokeEvent();
virtual void _DoInvokeEvent();
protected: protected:
// Extending classes should implement this method to perfoem whatever action it is // Extending classes should implement this method to perfoem whatever action it is
// the event is supposed to do. :) Thread affinity is garaunteed to be the Main/UI // the event is supposed to do. :) Thread affinity is garaunteed to be the Main/UI
// thread, and exceptions will be handled automatically. // thread, and exceptions will be handled automatically.
// //
// Exception note: exceptions are passed back to the thread that posted the event // Exception note: exceptions are passed back to the thread that posted the event
// to the queue, when possible. If the calling thread is not blocking for a result // to the queue, when possible. If the calling thread is not blocking for a result
// from this event, then the exception will be posted to the Main/UI thread instead. // from this event, then the exception will be posted to the Main/UI thread instead.
virtual void InvokeEvent() {} virtual void InvokeEvent() {}
}; };
@ -134,27 +136,27 @@ protected:
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class pxExceptionEvent : public pxActionEvent class pxExceptionEvent : public pxActionEvent
{ {
typedef pxActionEvent _parent; typedef pxActionEvent _parent;
protected: protected:
BaseException* m_except; BaseException *m_except;
public: public:
pxExceptionEvent( BaseException* ex=NULL ) pxExceptionEvent(BaseException *ex = NULL)
{ {
m_except = ex; m_except = ex;
} }
pxExceptionEvent( const BaseException& ex ); pxExceptionEvent(const BaseException &ex);
virtual ~pxExceptionEvent() throw() virtual ~pxExceptionEvent() throw()
{ {
} }
virtual pxExceptionEvent *Clone() const { return new pxExceptionEvent(*this); } virtual pxExceptionEvent *Clone() const { return new pxExceptionEvent(*this); }
protected: protected:
void InvokeEvent(); void InvokeEvent();
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -163,29 +165,29 @@ protected:
class pxSynchronousCommandEvent : public wxCommandEvent class pxSynchronousCommandEvent : public wxCommandEvent
{ {
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSynchronousCommandEvent) DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxSynchronousCommandEvent)
protected: protected:
SynchronousActionState* m_sync; SynchronousActionState *m_sync;
wxEventType m_realEvent; wxEventType m_realEvent;
public: public:
virtual ~pxSynchronousCommandEvent() throw() { } virtual ~pxSynchronousCommandEvent() throw() {}
virtual pxSynchronousCommandEvent *Clone() const { return new pxSynchronousCommandEvent(*this); } virtual pxSynchronousCommandEvent *Clone() const { return new pxSynchronousCommandEvent(*this); }
pxSynchronousCommandEvent(SynchronousActionState* sema=NULL, wxEventType commandType = wxEVT_NULL, int winid = 0); pxSynchronousCommandEvent(SynchronousActionState *sema = NULL, wxEventType commandType = wxEVT_NULL, int winid = 0);
pxSynchronousCommandEvent(SynchronousActionState& sema, wxEventType commandType = wxEVT_NULL, int winid = 0); pxSynchronousCommandEvent(SynchronousActionState &sema, wxEventType commandType = wxEVT_NULL, int winid = 0);
pxSynchronousCommandEvent(SynchronousActionState* sema, const wxCommandEvent& evt); pxSynchronousCommandEvent(SynchronousActionState *sema, const wxCommandEvent &evt);
pxSynchronousCommandEvent(SynchronousActionState& sema, const wxCommandEvent& evt); pxSynchronousCommandEvent(SynchronousActionState &sema, const wxCommandEvent &evt);
pxSynchronousCommandEvent(const pxSynchronousCommandEvent& src); pxSynchronousCommandEvent(const pxSynchronousCommandEvent &src);
Threading::Semaphore* GetSemaphore() { return m_sync ? &m_sync->GetSemaphore() : NULL; } Threading::Semaphore *GetSemaphore() { return m_sync ? &m_sync->GetSemaphore() : NULL; }
wxEventType GetRealEventType() const { return m_realEvent; } wxEventType GetRealEventType() const { return m_realEvent; }
void SetException( BaseException* ex ); void SetException(BaseException *ex);
void SetException( const BaseException& ex ); void SetException(const BaseException &ex);
}; };
wxDECLARE_EVENT(pxEvt_SynchronousCommand, pxSynchronousCommandEvent); wxDECLARE_EVENT(pxEvt_SynchronousCommand, pxSynchronousCommandEvent);
@ -195,23 +197,23 @@ wxDECLARE_EVENT(pxEvt_SynchronousCommand, pxSynchronousCommandEvent);
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class BaseMessageBoxEvent : public pxActionEvent class BaseMessageBoxEvent : public pxActionEvent
{ {
typedef pxActionEvent _parent; typedef pxActionEvent _parent;
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(BaseMessageBoxEvent) DECLARE_DYNAMIC_CLASS_NO_ASSIGN(BaseMessageBoxEvent)
protected: protected:
wxString m_Content; wxString m_Content;
public: public:
virtual ~BaseMessageBoxEvent() throw() { } virtual ~BaseMessageBoxEvent() throw() {}
virtual BaseMessageBoxEvent *Clone() const { return new BaseMessageBoxEvent(*this); } virtual BaseMessageBoxEvent *Clone() const { return new BaseMessageBoxEvent(*this); }
explicit BaseMessageBoxEvent( const wxString& content=wxEmptyString, SynchronousActionState* instdata=NULL ); explicit BaseMessageBoxEvent(const wxString &content = wxEmptyString, SynchronousActionState *instdata = NULL);
BaseMessageBoxEvent( const wxString& content, SynchronousActionState& instdata ); BaseMessageBoxEvent(const wxString &content, SynchronousActionState &instdata);
BaseMessageBoxEvent( const BaseMessageBoxEvent& event ); BaseMessageBoxEvent(const BaseMessageBoxEvent &event);
protected: protected:
virtual void InvokeEvent(); virtual void InvokeEvent();
virtual int _DoDialog() const; virtual int _DoDialog() const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -220,82 +222,134 @@ protected:
class MsgButtons class MsgButtons
{ {
protected: protected:
BITFIELD32() BITFIELD32()
bool bool
m_OK :1, m_OK : 1,
m_Cancel :1, m_Cancel : 1,
m_Yes :1, m_Yes : 1,
m_No :1, m_No : 1,
m_AllowToAll:1, m_AllowToAll : 1,
m_Apply :1, m_Apply : 1,
m_Abort :1, m_Abort : 1,
m_Retry :1, m_Retry : 1,
m_Ignore :1, m_Ignore : 1,
m_Reset :1, m_Reset : 1,
m_Close :1; m_Close : 1;
BITFIELD_END BITFIELD_END
wxString m_CustomLabel; wxString m_CustomLabel;
wxString m_CustomLabelId; wxString m_CustomLabelId;
public: public:
MsgButtons() { bitset = 0; } MsgButtons() { bitset = 0; }
MsgButtons& OK() { m_OK = true; return *this; } MsgButtons &OK()
MsgButtons& Cancel() { m_Cancel = true; return *this; } {
MsgButtons& Apply() { m_Apply = true; return *this; } m_OK = true;
MsgButtons& Yes() { m_Yes = true; return *this; } return *this;
MsgButtons& No() { m_No = true; return *this; } }
MsgButtons& ToAll() { m_AllowToAll = true; return *this; } MsgButtons &Cancel()
{
m_Cancel = true;
return *this;
}
MsgButtons &Apply()
{
m_Apply = true;
return *this;
}
MsgButtons &Yes()
{
m_Yes = true;
return *this;
}
MsgButtons &No()
{
m_No = true;
return *this;
}
MsgButtons &ToAll()
{
m_AllowToAll = true;
return *this;
}
MsgButtons& Abort() { m_Abort = true; return *this; } MsgButtons &Abort()
MsgButtons& Retry() { m_Retry = true; return *this; } {
MsgButtons& Ignore() { m_Ignore = true; return *this; } m_Abort = true;
MsgButtons& Reset() { m_Reset = true; return *this; } return *this;
MsgButtons& Close() { m_Close = true; return *this; } }
MsgButtons &Retry()
{
m_Retry = true;
return *this;
}
MsgButtons &Ignore()
{
m_Ignore = true;
return *this;
}
MsgButtons &Reset()
{
m_Reset = true;
return *this;
}
MsgButtons &Close()
{
m_Close = true;
return *this;
}
// label - native language label displayed to user // label - native language label displayed to user
// id - raw ASCII identifier used in the config file (do not translate, hence char*) // id - raw ASCII identifier used in the config file (do not translate, hence char*)
MsgButtons& Custom( const wxString& label, const char* id ) MsgButtons &Custom(const wxString &label, const char *id)
{ {
m_CustomLabel = label; m_CustomLabel = label;
m_CustomLabelId = fromUTF8(id); m_CustomLabelId = fromUTF8(id);
return *this; return *this;
} }
MsgButtons& OKCancel() { m_OK = m_Cancel = true; return *this; } MsgButtons &OKCancel()
MsgButtons& YesNo() { m_Yes = m_No = true; return *this; } {
m_OK = m_Cancel = true;
return *this;
}
MsgButtons &YesNo()
{
m_Yes = m_No = true;
return *this;
}
bool HasOK() const { return m_OK; } bool HasOK() const { return m_OK; }
bool HasCancel() const { return m_Cancel; } bool HasCancel() const { return m_Cancel; }
bool HasApply() const { return m_Apply; } bool HasApply() const { return m_Apply; }
bool HasYes() const { return m_Yes; } bool HasYes() const { return m_Yes; }
bool HasNo() const { return m_No; } bool HasNo() const { return m_No; }
bool AllowsToAll() const{ return m_AllowToAll; } bool AllowsToAll() const { return m_AllowToAll; }
bool HasAbort() const { return m_Abort; } bool HasAbort() const { return m_Abort; }
bool HasRetry() const { return m_Retry; } bool HasRetry() const { return m_Retry; }
bool HasIgnore() const { return m_Ignore; } bool HasIgnore() const { return m_Ignore; }
bool HasReset() const { return m_Reset; } bool HasReset() const { return m_Reset; }
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; } 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;
void SetBestFocus( wxWindow& dialog ) const; void SetBestFocus(wxWindow &dialog) const;
bool operator ==( const MsgButtons& right ) const bool operator==(const MsgButtons &right) const
{ {
return OpEqu( bitset ); return OpEqu(bitset);
} }
bool operator !=( const MsgButtons& right ) const bool operator!=(const MsgButtons &right) const
{ {
return !OpEqu( bitset ); return !OpEqu(bitset);
} }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -318,24 +372,24 @@ public:
// //
class pxMessageBoxEvent : public BaseMessageBoxEvent class pxMessageBoxEvent : public BaseMessageBoxEvent
{ {
typedef BaseMessageBoxEvent _parent; typedef BaseMessageBoxEvent _parent;
DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxMessageBoxEvent) DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxMessageBoxEvent)
protected: protected:
wxString m_Title; wxString m_Title;
MsgButtons m_Buttons; MsgButtons m_Buttons;
public: public:
virtual ~pxMessageBoxEvent() throw() { } virtual ~pxMessageBoxEvent() throw() {}
virtual pxMessageBoxEvent *Clone() const { return new pxMessageBoxEvent(*this); } virtual pxMessageBoxEvent *Clone() const { return new pxMessageBoxEvent(*this); }
pxMessageBoxEvent() {} pxMessageBoxEvent() {}
pxMessageBoxEvent( const wxString& title, const wxString& content, const MsgButtons& buttons, SynchronousActionState& instdata ); pxMessageBoxEvent(const wxString &title, const wxString &content, const MsgButtons &buttons, SynchronousActionState &instdata);
pxMessageBoxEvent( const wxString& title, const wxString& content, const MsgButtons& buttons, SynchronousActionState* instdata=NULL ); pxMessageBoxEvent(const wxString &title, const wxString &content, const MsgButtons &buttons, SynchronousActionState *instdata = NULL);
pxMessageBoxEvent( const pxMessageBoxEvent& event ); pxMessageBoxEvent(const pxMessageBoxEvent &event);
protected: protected:
int _DoDialog() const; int _DoDialog() const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -343,22 +397,22 @@ protected:
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class pxAssertionEvent : public BaseMessageBoxEvent class pxAssertionEvent : public BaseMessageBoxEvent
{ {
typedef BaseMessageBoxEvent _parent; typedef BaseMessageBoxEvent _parent;
DECLARE_DYNAMIC_CLASS_NO_ASSIGN( pxAssertionEvent ) DECLARE_DYNAMIC_CLASS_NO_ASSIGN(pxAssertionEvent)
protected: protected:
wxString m_Stacktrace; wxString m_Stacktrace;
public: public:
virtual ~pxAssertionEvent() throw() { } virtual ~pxAssertionEvent() throw() {}
virtual pxAssertionEvent *Clone() const { return new pxAssertionEvent(*this); } virtual pxAssertionEvent *Clone() const { return new pxAssertionEvent(*this); }
pxAssertionEvent( const wxString& content=wxEmptyString, const wxString& trace=wxEmptyString, SynchronousActionState* instdata=NULL ); pxAssertionEvent(const wxString &content = wxEmptyString, const wxString &trace = wxEmptyString, SynchronousActionState *instdata = NULL);
pxAssertionEvent( const wxString& content, const wxString& trace, SynchronousActionState& instdata ); pxAssertionEvent(const wxString &content, const wxString &trace, SynchronousActionState &instdata);
pxAssertionEvent( const pxAssertionEvent& event ); pxAssertionEvent(const pxAssertionEvent &event);
pxAssertionEvent& SetStacktrace( const wxString& trace ); pxAssertionEvent &SetStacktrace(const wxString &trace);
protected: protected:
int _DoDialog() const; int _DoDialog() const;
}; };

View File

@ -40,12 +40,12 @@ extern const wxPoint wxDefaultPosition;
namespace Threading namespace Threading
{ {
class Mutex; class Mutex;
class Semaphore; class Semaphore;
class pxThread; class pxThread;
} }
namespace Exception namespace Exception
{ {
class BaseException; class BaseException;
} }

View File

@ -25,45 +25,45 @@
struct RadioPanelItem struct RadioPanelItem
{ {
wxString Label; wxString Label;
wxString SubText; wxString SubText;
wxString ToolTip; wxString ToolTip;
int SomeInt; int SomeInt;
void* SomePtr; void *SomePtr;
RadioPanelItem( const wxString& label, const wxString& subtext=wxEmptyString, const wxString& tooltip=wxEmptyString ) RadioPanelItem(const wxString &label, const wxString &subtext = wxEmptyString, const wxString &tooltip = wxEmptyString)
: Label( label ) : Label(label)
, SubText( subtext ) , SubText(subtext)
, ToolTip( tooltip ) , ToolTip(tooltip)
{ {
SomeInt = 0; SomeInt = 0;
SomePtr = NULL; SomePtr = NULL;
} }
RadioPanelItem& SetToolTip( const wxString& tip ) RadioPanelItem &SetToolTip(const wxString &tip)
{ {
ToolTip = tip; ToolTip = tip;
return *this; return *this;
} }
RadioPanelItem& SetSubText( const wxString& text ) RadioPanelItem &SetSubText(const wxString &text)
{ {
SubText = text; SubText = text;
return *this; return *this;
} }
RadioPanelItem& SetInt( int intval )
{
SomeInt = intval;
return *this;
}
RadioPanelItem& SetPtr( void* ptrval ) RadioPanelItem &SetInt(int intval)
{ {
SomePtr = ptrval; SomeInt = intval;
return *this; return *this;
} }
RadioPanelItem &SetPtr(void *ptrval)
{
SomePtr = ptrval;
return *this;
}
}; };
@ -71,8 +71,8 @@ struct RadioPanelItem
// wrapped and re-wrapped with multiple calls to OnResize(). // wrapped and re-wrapped with multiple calls to OnResize().
struct RadioPanelObjects struct RadioPanelObjects
{ {
wxRadioButton* LabelObj; wxRadioButton *LabelObj;
pxStaticText* SubTextObj; pxStaticText *SubTextObj;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -91,86 +91,86 @@ struct RadioPanelObjects
class pxRadioPanel : public wxPanelWithHelpers class pxRadioPanel : public wxPanelWithHelpers
{ {
protected: protected:
typedef std::vector<RadioPanelItem> ButtonArray; typedef std::vector<RadioPanelItem> ButtonArray;
typedef SafeArray<RadioPanelObjects> ButtonObjArray; typedef SafeArray<RadioPanelObjects> ButtonObjArray;
ButtonArray m_buttonStrings; ButtonArray m_buttonStrings;
ButtonObjArray m_objects; ButtonObjArray m_objects;
bool m_IsRealized; bool m_IsRealized;
wxSize m_padding; wxSize m_padding;
int m_Indentation; int m_Indentation;
int m_DefaultIdx; // index of the default option (gets specific color/font treatment) int m_DefaultIdx; // index of the default option (gets specific color/font treatment)
public: public:
template< int size > template <int size>
pxRadioPanel( wxWindow* parent, const RadioPanelItem (&src)[size] ) pxRadioPanel(wxWindow *parent, const RadioPanelItem (&src)[size])
: wxPanelWithHelpers( parent, wxVERTICAL ) : wxPanelWithHelpers(parent, wxVERTICAL)
{ {
Init( src, size ); Init(src, size);
} }
pxRadioPanel( wxWindow* parent ) pxRadioPanel(wxWindow *parent)
: wxPanelWithHelpers( parent, wxVERTICAL ) : wxPanelWithHelpers(parent, wxVERTICAL)
{ {
Init(); Init();
} }
virtual ~pxRadioPanel() throw() {} virtual ~pxRadioPanel() throw() {}
void Reset(); void Reset();
void Realize(); void Realize();
pxStaticText* GetSubText( int idx ); pxStaticText *GetSubText(int idx);
const pxStaticText* GetSubText( int idx ) const; const pxStaticText *GetSubText(int idx) const;
pxRadioPanel& Append( const RadioPanelItem& entry ); pxRadioPanel &Append(const RadioPanelItem &entry);
pxRadioPanel& SetToolTip( int idx, const wxString& tip ); pxRadioPanel &SetToolTip(int idx, const wxString &tip);
pxRadioPanel& SetSelection( int idx ); pxRadioPanel &SetSelection(int idx);
pxRadioPanel& SetDefaultItem( int idx ); pxRadioPanel &SetDefaultItem(int idx);
pxRadioPanel& EnableItem( int idx, bool enable=true ); pxRadioPanel &EnableItem(int idx, bool enable = true);
const RadioPanelItem& Item(int idx) const; const RadioPanelItem &Item(int idx) const;
RadioPanelItem& Item(int idx); RadioPanelItem &Item(int idx);
int GetSelection() const; int GetSelection() const;
wxWindowID GetSelectionId() const; wxWindowID GetSelectionId() const;
bool IsSelected( int idx ) const; bool IsSelected(int idx) const;
const RadioPanelItem& SelectedItem() const { return Item(GetSelection()); } const RadioPanelItem &SelectedItem() const { return Item(GetSelection()); }
RadioPanelItem& SelectedItem() { return Item(GetSelection()); } RadioPanelItem &SelectedItem() { return Item(GetSelection()); }
wxRadioButton* GetButton( int idx ); wxRadioButton *GetButton(int idx);
const wxRadioButton* GetButton( int idx ) const; const wxRadioButton *GetButton(int idx) const;
int GetPaddingVert() const { return m_padding.GetHeight(); } int GetPaddingVert() const { return m_padding.GetHeight(); }
int GetIndentation() const { return m_Indentation; } int GetIndentation() const { return m_Indentation; }
pxRadioPanel& SetPaddingHoriz( int newpad ) pxRadioPanel &SetPaddingHoriz(int newpad)
{ {
m_padding.SetHeight( newpad ); m_padding.SetHeight(newpad);
return *this; return *this;
} }
pxRadioPanel& SetIndentation( int newdent ) pxRadioPanel &SetIndentation(int newdent)
{ {
m_Indentation = newdent; m_Indentation = newdent;
return *this; return *this;
} }
bool HasSubText( int idx ) const bool HasSubText(int idx) const
{ {
return !m_buttonStrings[idx].SubText.IsEmpty(); return !m_buttonStrings[idx].SubText.IsEmpty();
} }
pxRadioPanel& Append( const wxString& label, const wxString& subtext=wxEmptyString, const wxString& tooltip=wxEmptyString ) pxRadioPanel &Append(const wxString &label, const wxString &subtext = wxEmptyString, const wxString &tooltip = wxEmptyString)
{ {
return Append( RadioPanelItem(label, subtext, tooltip) ); return Append(RadioPanelItem(label, subtext, tooltip));
} }
protected: protected:
void Init( const RadioPanelItem* srcArray=NULL, int arrsize=0 ); void Init(const RadioPanelItem *srcArray = NULL, int arrsize = 0);
void _setToolTipImmediate( int idx, const wxString &tip ); void _setToolTipImmediate(int idx, const wxString &tip);
void _RealizeDefaultOption(); void _RealizeDefaultOption();
}; };

View File

@ -33,93 +33,92 @@
// //
class pxStaticText : public wxControl class pxStaticText : public wxControl
{ {
typedef wxControl _parent; typedef wxControl _parent;
protected: protected:
wxString m_label; wxString m_label;
wxString m_wrappedLabel; wxString m_wrappedLabel;
wxAlignment m_align; wxAlignment m_align;
bool m_autowrap; bool m_autowrap;
int m_wrappedWidth; int m_wrappedWidth;
int m_heightInLines; int m_heightInLines;
int m_paddingPix_horiz; int m_paddingPix_horiz;
int m_paddingPix_vert; int m_paddingPix_vert;
float m_paddingPct_horiz; float m_paddingPct_horiz;
float m_paddingPct_vert; float m_paddingPct_vert;
protected: protected:
explicit pxStaticText( wxWindow* parent=NULL ); explicit pxStaticText(wxWindow *parent = NULL);
// wxWindow overloads! // wxWindow overloads!
bool AcceptsFocus() const { return false; } bool AcceptsFocus() const { return false; }
bool HasTransparentBackground() { return true; } bool HasTransparentBackground() { return true; }
void DoSetSize(int x, int y, int w, int h, int sizeFlags = wxSIZE_AUTO); void DoSetSize(int x, int y, int w, int h, int sizeFlags = wxSIZE_AUTO);
public: public:
pxStaticText( wxWindow* parent, const wxString& label, wxAlignment align=wxALIGN_CENTRE_HORIZONTAL ); pxStaticText(wxWindow *parent, const wxString &label, wxAlignment align = wxALIGN_CENTRE_HORIZONTAL);
pxStaticText( wxWindow* parent, int heightInLines, const wxString& label, wxAlignment align=wxALIGN_CENTRE_HORIZONTAL ); pxStaticText(wxWindow *parent, int heightInLines, const wxString &label, wxAlignment align = wxALIGN_CENTRE_HORIZONTAL);
virtual ~pxStaticText() throw() {} virtual ~pxStaticText() throw() {}
wxFont GetFontOk() const; wxFont GetFontOk() const;
bool Enable( bool enabled=true ); bool Enable(bool enabled = true);
virtual void SetLabel(const wxString& label); virtual void SetLabel(const wxString &label);
virtual wxString GetLabel() const { return m_label; } virtual wxString GetLabel() const { return m_label; }
pxStaticText& SetMinWidth( int width ); pxStaticText &SetMinWidth(int width);
pxStaticText& SetMinHeight( int height ); pxStaticText &SetMinHeight(int height);
pxStaticText& SetHeight( int lines ); pxStaticText &SetHeight(int lines);
pxStaticText& Align( wxAlignment align ); pxStaticText &Align(wxAlignment align);
pxStaticText& Bold(); pxStaticText &Bold();
pxStaticText& WrapAt( int width ); pxStaticText &WrapAt(int width);
pxStaticText& Unwrapped(); pxStaticText &Unwrapped();
pxStaticText& PaddingPixH( int pixels ); pxStaticText &PaddingPixH(int pixels);
pxStaticText& PaddingPixV( int pixels ); pxStaticText &PaddingPixV(int pixels);
pxStaticText& PaddingPctH( float pct ); pxStaticText &PaddingPctH(float pct);
pxStaticText& PaddingPctV( float pct ); pxStaticText &PaddingPctV(float pct);
//pxStaticText& DoBestGuessHeight(); //pxStaticText& DoBestGuessHeight();
protected: protected:
void SetPaddingDefaults(); void SetPaddingDefaults();
void Init( const wxString& label ); void Init(const wxString &label);
wxSize GetBestWrappedSize( const wxClientDC& dc ) const; wxSize GetBestWrappedSize(const wxClientDC &dc) const;
wxSize DoGetBestSize() const; wxSize DoGetBestSize() const;
int calcPaddingWidth( int newWidth ) const; int calcPaddingWidth(int newWidth) const;
int calcPaddingHeight( int newHeight ) const; int calcPaddingHeight(int newHeight) const;
void paintEvent(wxPaintEvent& evt); void paintEvent(wxPaintEvent &evt);
void UpdateWrapping( bool textChanged ); void UpdateWrapping(bool textChanged);
bool _updateWrapping( bool textChanged ); bool _updateWrapping(bool textChanged);
}; };
class pxStaticHeading : public pxStaticText class pxStaticHeading : public pxStaticText
{ {
typedef pxStaticText _parent; typedef pxStaticText _parent;
public: public:
pxStaticHeading( wxWindow* parent=NULL, const wxString& label=wxEmptyString ); pxStaticHeading(wxWindow *parent = NULL, const wxString &label = wxEmptyString);
pxStaticHeading( wxWindow* parent, int heightInLines, const wxString& label=wxEmptyString ); pxStaticHeading(wxWindow *parent, int heightInLines, const wxString &label = wxEmptyString);
virtual ~pxStaticHeading() throw() {} virtual ~pxStaticHeading() throw() {}
protected: protected:
void SetPaddingDefaults(); void SetPaddingDefaults();
}; };
extern void operator+=( wxSizer& target, pxStaticText& src ); extern void operator+=(wxSizer &target, pxStaticText &src);
template<> template <>
inline void operator+=( wxSizer& target, const pxWindowAndFlags<pxStaticText>& src ) inline void operator+=(wxSizer &target, const pxWindowAndFlags<pxStaticText> &src)
{ {
target.Add( src.window, src.flags ); target.Add(src.window, src.flags);
} }

View File

@ -23,28 +23,28 @@
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class pxStreamBase class pxStreamBase
{ {
DeclareNoncopyableObject(pxStreamBase); DeclareNoncopyableObject(pxStreamBase);
protected: protected:
// Filename of the stream, provided by the creator/caller. This is typically used *only* // Filename of the stream, provided by the creator/caller. This is typically used *only*
// for generating comprehensive error messages when an error occurs (the stream name is // for generating comprehensive error messages when an error occurs (the stream name is
// passed to the exception handlers). // passed to the exception handlers).
wxString m_filename; wxString m_filename;
public: public:
pxStreamBase(const wxString& filename); pxStreamBase(const wxString &filename);
virtual ~pxStreamBase() throw() {} virtual ~pxStreamBase() throw() {}
// Implementing classes should return the base wxStream object (usually either a wxInputStream // Implementing classes should return the base wxStream object (usually either a wxInputStream
// 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 Tell() const = 0;
virtual wxFileOffset Seek( wxFileOffset ofs, wxSeekMode mode = wxFromStart )=0; virtual wxFileOffset Seek(wxFileOffset ofs, wxSeekMode mode = wxFromStart) = 0;
virtual wxFileOffset Length() const; virtual wxFileOffset Length() const;
bool IsOk() const; bool IsOk() const;
wxString GetStreamName() const { return m_filename; } wxString GetStreamName() const { return m_filename; }
}; };
@ -53,33 +53,33 @@ public:
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class pxOutputStream : public pxStreamBase class pxOutputStream : public pxStreamBase
{ {
DeclareNoncopyableObject(pxOutputStream); DeclareNoncopyableObject(pxOutputStream);
protected: protected:
std::unique_ptr<wxOutputStream> m_stream_out; std::unique_ptr<wxOutputStream> m_stream_out;
public: public:
pxOutputStream(const wxString& filename, std::unique_ptr<wxOutputStream>& output); pxOutputStream(const wxString &filename, std::unique_ptr<wxOutputStream> &output);
pxOutputStream(const wxString& filename, wxOutputStream* output); pxOutputStream(const wxString &filename, wxOutputStream *output);
virtual ~pxOutputStream() throw() {} virtual ~pxOutputStream() throw() {}
virtual void Write( const void* data, size_t size ); virtual void Write(const void *data, size_t size);
void SetStream( const wxString& filename, std::unique_ptr<wxOutputStream>& stream );
void SetStream( const wxString& filename, wxOutputStream* stream );
void Close() { m_stream_out = nullptr; } void SetStream(const wxString &filename, std::unique_ptr<wxOutputStream> &stream);
void SetStream(const wxString &filename, wxOutputStream *stream);
virtual wxStreamBase* GetWxStreamBase() const; void Close() { m_stream_out = nullptr; }
template< typename T > virtual wxStreamBase *GetWxStreamBase() const;
void Write( const T& data )
{
Write( &data, sizeof(data) );
}
wxFileOffset Tell() const; template <typename T>
wxFileOffset Seek( wxFileOffset ofs, wxSeekMode mode = wxFromStart ); void Write(const T &data)
{
Write(&data, sizeof(data));
}
wxFileOffset Tell() const;
wxFileOffset Seek(wxFileOffset ofs, wxSeekMode mode = wxFromStart);
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -87,31 +87,31 @@ public:
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class pxInputStream : public pxStreamBase class pxInputStream : public pxStreamBase
{ {
DeclareNoncopyableObject(pxInputStream); DeclareNoncopyableObject(pxInputStream);
protected: protected:
std::unique_ptr<wxInputStream> m_stream_in; std::unique_ptr<wxInputStream> m_stream_in;
public: public:
pxInputStream(const wxString& filename, std::unique_ptr<wxInputStream>& input); pxInputStream(const wxString &filename, std::unique_ptr<wxInputStream> &input);
pxInputStream(const wxString& filename, wxInputStream* input); pxInputStream(const wxString &filename, wxInputStream *input);
virtual ~pxInputStream() throw() {} virtual ~pxInputStream() throw() {}
virtual void Read( void* dest, size_t size ); virtual void Read(void *dest, size_t size);
void SetStream( const wxString& filename, std::unique_ptr<wxInputStream>& stream );
void SetStream( const wxString& filename, wxInputStream* stream );
void Close() { m_stream_in = nullptr; } void SetStream(const wxString &filename, std::unique_ptr<wxInputStream> &stream);
void SetStream(const wxString &filename, wxInputStream *stream);
virtual wxStreamBase* GetWxStreamBase() const; void Close() { m_stream_in = nullptr; }
template< typename T > virtual wxStreamBase *GetWxStreamBase() const;
void Read( T& dest )
{
Read( &dest, sizeof(dest) );
}
wxFileOffset Tell() const; template <typename T>
wxFileOffset Seek( wxFileOffset ofs, wxSeekMode mode = wxFromStart ); void Read(T &dest)
{
Read(&dest, sizeof(dest));
}
wxFileOffset Tell() const;
wxFileOffset Seek(wxFileOffset ofs, wxSeekMode mode = wxFromStart);
}; };

View File

@ -16,30 +16,30 @@
#pragma once #pragma once
#ifdef _MSC_VER #ifdef _MSC_VER
# pragma warning(disable:4063) // case '1' is not a valid value for switch() #pragma warning(disable : 4063) // case '1' is not a valid value for switch()
#endif #endif
// These functions are meant for memset operations of constant length only. // These functions are meant for memset operations of constant length only.
// For dynamic length clears, use the C-compiler provided memset instead. // For dynamic length clears, use the C-compiler provided memset instead.
template< u8 data, size_t bytes > template <u8 data, size_t bytes>
static __fi void memset_8( void *dest ) static __fi void memset_8(void *dest)
{ {
memset(dest, data, bytes); memset(dest, data, bytes);
} }
// This method can clear any object-like entity -- which is anything that is not a pointer. // This method can clear any object-like entity -- which is anything that is not a pointer.
// Structures, static arrays, etc. No need to include sizeof() crap, this does it automatically // Structures, static arrays, etc. No need to include sizeof() crap, this does it automatically
// for you! // for you!
template< typename T > template <typename T>
static __fi void memzero( T& object ) static __fi void memzero(T &object)
{ {
memset(&object, 0, sizeof(T)); memset(&object, 0, sizeof(T));
} }
// This method clears an object with the given 8 bit value. // This method clears an object with the given 8 bit value.
template< u8 data, typename T > template <u8 data, typename T>
static __fi void memset8( T& object ) static __fi void memset8(T &object)
{ {
memset_8<data, sizeof(T)>( &object ); memset_8<data, sizeof(T)>(&object);
} }

View File

@ -32,10 +32,10 @@ class pxSynchronousCommandEvent;
class ConsoleLogSource_App : public ConsoleLogSource class ConsoleLogSource_App : public ConsoleLogSource
{ {
typedef ConsoleLogSource _parent; typedef ConsoleLogSource _parent;
public: public:
ConsoleLogSource_App(); ConsoleLogSource_App();
}; };
extern ConsoleLogSource_App pxConLog_App; extern ConsoleLogSource_App pxConLog_App;
@ -49,96 +49,97 @@ extern ConsoleLogSource_App pxConLog_App;
class ModalButtonPanel : public wxPanelWithHelpers class ModalButtonPanel : public wxPanelWithHelpers
{ {
public: public:
ModalButtonPanel( wxWindow* window, const MsgButtons& buttons ); ModalButtonPanel(wxWindow *window, const MsgButtons &buttons);
virtual ~ModalButtonPanel() throw() { } virtual ~ModalButtonPanel() throw() {}
virtual void AddActionButton( wxWindowID id ); virtual void AddActionButton(wxWindowID id);
virtual void AddCustomButton( wxWindowID id, const wxString& label ); virtual void AddCustomButton(wxWindowID id, const wxString &label);
virtual void OnActionButtonClicked( wxCommandEvent& evt ); virtual void OnActionButtonClicked(wxCommandEvent &evt);
}; };
typedef std::list< wxEvent* > wxEventList; typedef std::list<wxEvent *> wxEventList;
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// wxAppWithHelpers // wxAppWithHelpers
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class wxAppWithHelpers : public wxApp class wxAppWithHelpers : public wxApp
{ {
typedef wxApp _parent; typedef wxApp _parent;
DECLARE_DYNAMIC_CLASS(wxAppWithHelpers) DECLARE_DYNAMIC_CLASS(wxAppWithHelpers)
protected: protected:
wxEventList m_IdleEventQueue; wxEventList m_IdleEventQueue;
Threading::MutexRecursive m_IdleEventMutex; Threading::MutexRecursive m_IdleEventMutex;
wxTimer m_IdleEventTimer; wxTimer m_IdleEventTimer;
public: public:
wxAppWithHelpers(); wxAppWithHelpers();
virtual ~wxAppWithHelpers() {} virtual ~wxAppWithHelpers() {}
wxAppTraits* CreateTraits(); wxAppTraits *CreateTraits();
void CleanUp(); void CleanUp();
void DeleteObject( BaseDeletableObject& obj );
void DeleteObject( BaseDeletableObject* obj )
{
if( obj == NULL ) return;
DeleteObject( *obj );
}
void DeleteThread( Threading::pxThread& obj ); void DeleteObject(BaseDeletableObject &obj);
void DeleteThread( Threading::pxThread* obj ) void DeleteObject(BaseDeletableObject *obj)
{ {
if( obj == NULL ) return; if (obj == NULL)
DeleteThread( *obj ); return;
} DeleteObject(*obj);
}
void PostCommand( void* clientData, int evtType, int intParam=0, long longParam=0, const wxString& stringParam=wxEmptyString ); void DeleteThread(Threading::pxThread &obj);
void PostCommand( int evtType, int intParam=0, long longParam=0, const wxString& stringParam=wxEmptyString ); void DeleteThread(Threading::pxThread *obj)
void PostMethod( FnType_Void* method ); {
void PostIdleMethod( FnType_Void* method ); if (obj == NULL)
void ProcessMethod( FnType_Void* method ); return;
DeleteThread(*obj);
}
bool Rpc_TryInvoke( FnType_Void* method ); void PostCommand(void *clientData, int evtType, int intParam = 0, long longParam = 0, const wxString &stringParam = wxEmptyString);
bool Rpc_TryInvokeAsync( FnType_Void* method ); void PostCommand(int evtType, int intParam = 0, long longParam = 0, const wxString &stringParam = wxEmptyString);
void PostMethod(FnType_Void *method);
void PostIdleMethod(FnType_Void *method);
void ProcessMethod(FnType_Void *method);
sptr ProcessCommand( void* clientData, int evtType, int intParam=0, long longParam=0, const wxString& stringParam=wxEmptyString ); bool Rpc_TryInvoke(FnType_Void *method);
sptr ProcessCommand( int evtType, int intParam=0, long longParam=0, const wxString& stringParam=wxEmptyString ); bool Rpc_TryInvokeAsync(FnType_Void *method);
void ProcessAction( pxActionEvent& evt ); sptr ProcessCommand(void *clientData, int evtType, int intParam = 0, long longParam = 0, const wxString &stringParam = wxEmptyString);
void PostAction( const pxActionEvent& evt ); sptr ProcessCommand(int evtType, int intParam = 0, long longParam = 0, const wxString &stringParam = wxEmptyString);
void Ping(); void ProcessAction(pxActionEvent &evt);
bool OnInit(); void PostAction(const pxActionEvent &evt);
//int OnExit();
void AddIdleEvent( const wxEvent& evt ); void Ping();
bool OnInit();
//int OnExit();
void PostEvent( const wxEvent& evt ); void AddIdleEvent(const wxEvent &evt);
bool ProcessEvent( wxEvent& evt );
bool ProcessEvent( wxEvent* evt ); void PostEvent(const wxEvent &evt);
bool ProcessEvent(wxEvent &evt);
bool ProcessEvent( pxActionEvent& evt ); bool ProcessEvent(wxEvent *evt);
bool ProcessEvent( pxActionEvent* evt );
bool ProcessEvent(pxActionEvent &evt);
bool ProcessEvent(pxActionEvent *evt);
protected: protected:
void IdleEventDispatcher( const wxChar* action=wxEmptyString ); void IdleEventDispatcher(const wxChar *action = wxEmptyString);
void OnIdleEvent( wxIdleEvent& evt );
void OnStartIdleEventTimer( wxCommandEvent& evt );
void OnIdleEventTimeout( wxTimerEvent& evt );
void OnDeleteObject( wxCommandEvent& evt );
void OnDeleteThread( wxCommandEvent& evt );
void OnSynchronousCommand( pxSynchronousCommandEvent& evt );
void OnInvokeAction( pxActionEvent& evt );
void OnIdleEvent(wxIdleEvent &evt);
void OnStartIdleEventTimer(wxCommandEvent &evt);
void OnIdleEventTimeout(wxTimerEvent &evt);
void OnDeleteObject(wxCommandEvent &evt);
void OnDeleteThread(wxCommandEvent &evt);
void OnSynchronousCommand(pxSynchronousCommandEvent &evt);
void OnInvokeAction(pxActionEvent &evt);
}; };
namespace Msgbox namespace Msgbox
{ {
extern int ShowModal( BaseMessageBoxEvent& evt ); extern int ShowModal(BaseMessageBoxEvent &evt);
extern int ShowModal( const wxString& title, const wxString& content, const MsgButtons& buttons ); extern int ShowModal(const wxString &title, const wxString &content, const MsgButtons &buttons);
} }

View File

@ -26,11 +26,11 @@
// which require wxCore, see wxGuiTools.h // which require wxCore, see wxGuiTools.h
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
extern void pxExplore( const wxString& path ); extern void pxExplore(const wxString &path);
extern void pxExplore( const char *path ); extern void pxExplore(const char *path);
extern void pxLaunch( const wxString& path ); extern void pxLaunch(const wxString &path);
extern void pxLaunch( const char *path ); extern void pxLaunch(const char *path);
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// wxDoNotLogInThisScope // wxDoNotLogInThisScope
@ -44,29 +44,28 @@ extern void pxLaunch( const char *path );
// //
class wxDoNotLogInThisScope class wxDoNotLogInThisScope
{ {
DeclareNoncopyableObject(wxDoNotLogInThisScope); DeclareNoncopyableObject(wxDoNotLogInThisScope);
protected: protected:
bool m_prev; bool m_prev;
public: public:
wxDoNotLogInThisScope() wxDoNotLogInThisScope()
{ {
m_prev = wxLog::EnableLogging( false ); m_prev = wxLog::EnableLogging(false);
} }
virtual ~wxDoNotLogInThisScope() throw() virtual ~wxDoNotLogInThisScope() throw()
{ {
wxLog::EnableLogging( m_prev ); wxLog::EnableLogging(m_prev);
} }
}; };
extern wxString pxReadLine( wxInputStream& input ); extern wxString pxReadLine(wxInputStream &input);
extern void pxReadLine( wxInputStream& input, wxString& dest ); extern void pxReadLine(wxInputStream &input, wxString &dest);
extern void pxReadLine( wxInputStream& input, wxString& dest, std::string& intermed ); extern void pxReadLine(wxInputStream &input, wxString &dest, std::string &intermed);
extern bool pxReadLine( wxInputStream& input, std::string& dest ); extern bool pxReadLine(wxInputStream &input, std::string &dest);
extern void pxWriteLine( wxOutputStream& output ); extern void pxWriteLine(wxOutputStream &output);
extern void pxWriteLine( wxOutputStream& output, const wxString& text ); extern void pxWriteLine(wxOutputStream &output, const wxString &text);
extern void pxWriteMultiline( wxOutputStream& output, const wxString& src ); extern void pxWriteMultiline(wxOutputStream &output, const wxString &src);

File diff suppressed because it is too large Load Diff

View File

@ -35,101 +35,124 @@
// Basic functions. // Basic functions.
EXPORT_C_(s32) CDVDinit(); EXPORT_C_(s32)
EXPORT_C_(s32) CDVDopen(void *pDisplay, const char* pTitleFilename); CDVDinit();
EXPORT_C_(void) CDVDclose(); EXPORT_C_(s32)
EXPORT_C_(void) CDVDshutdown(); CDVDopen(void *pDisplay, const char *pTitleFilename);
EXPORT_C_(s32) CDVDreadTrack(u32 lsn, int mode); EXPORT_C_(void)
CDVDclose();
EXPORT_C_(void)
CDVDshutdown();
EXPORT_C_(s32)
CDVDreadTrack(u32 lsn, int mode);
// return can be NULL (for async modes) // return can be NULL (for async modes)
EXPORT_C_(u8*) CDVDgetBuffer(); EXPORT_C_(u8 *)
CDVDgetBuffer();
EXPORT_C_(s32) CDVDreadSubQ(u32 lsn, cdvdSubQ* subq);//read subq from disc (only cds have subq data) EXPORT_C_(s32)
EXPORT_C_(s32) CDVDgetTN(cdvdTN *Buffer); //disk information CDVDreadSubQ(u32 lsn, cdvdSubQ *subq); //read subq from disc (only cds have subq data)
EXPORT_C_(s32) CDVDgetTD(u8 Track, cdvdTD *Buffer); //track info: min,sec,frame,type EXPORT_C_(s32)
EXPORT_C_(s32) CDVDgetTOC(void* toc); //gets ps2 style toc from disc CDVDgetTN(cdvdTN *Buffer); //disk information
EXPORT_C_(s32) CDVDgetDiskType(); //CDVD_TYPE_xxxx EXPORT_C_(s32)
EXPORT_C_(s32) CDVDgetTrayStatus(); //CDVD_TRAY_xxxx CDVDgetTD(u8 Track, cdvdTD *Buffer); //track info: min,sec,frame,type
EXPORT_C_(s32) CDVDctrlTrayOpen(); //open disc tray EXPORT_C_(s32)
EXPORT_C_(s32) CDVDctrlTrayClose(); //close disc tray CDVDgetTOC(void *toc); //gets ps2 style toc from disc
EXPORT_C_(s32)
CDVDgetDiskType(); //CDVD_TYPE_xxxx
EXPORT_C_(s32)
CDVDgetTrayStatus(); //CDVD_TRAY_xxxx
EXPORT_C_(s32)
CDVDctrlTrayOpen(); //open disc tray
EXPORT_C_(s32)
CDVDctrlTrayClose(); //close disc tray
// Extended functions // Extended functions
EXPORT_C_(void) CDVDkeyEvent(keyEvent *ev); EXPORT_C_(void)
EXPORT_C_(void) CDVDconfigure(); CDVDkeyEvent(keyEvent *ev);
EXPORT_C_(s32) CDVDfreeze(u8 mode, freezeData *data); EXPORT_C_(void)
EXPORT_C_(void) CDVDabout(); CDVDconfigure();
EXPORT_C_(s32) CDVDtest(); EXPORT_C_(s32)
EXPORT_C_(void) CDVDnewDiskCB(void (*callback)()); CDVDfreeze(u8 mode, freezeData *data);
EXPORT_C_(void)
CDVDabout();
EXPORT_C_(s32)
CDVDtest();
EXPORT_C_(void)
CDVDnewDiskCB(void (*callback)());
typedef struct _cdvdSubQ { typedef struct _cdvdSubQ
u8 ctrl:4; // control and mode bits {
u8 mode:4; // control and mode bits u8 ctrl : 4; // control and mode bits
u8 trackNum; // current track number (1 to 99) u8 mode : 4; // control and mode bits
u8 trackIndex; // current index within track (0 to 99) u8 trackNum; // current track number (1 to 99)
u8 trackM; // current minute location on the disc (BCD encoded) u8 trackIndex; // current index within track (0 to 99)
u8 trackS; // current sector location on the disc (BCD encoded) u8 trackM; // current minute location on the disc (BCD encoded)
u8 trackF; // current frame location on the disc (BCD encoded) u8 trackS; // current sector location on the disc (BCD encoded)
u8 pad; // unused u8 trackF; // current frame location on the disc (BCD encoded)
u8 discM; // current minute offset from first track (BCD encoded) u8 pad; // unused
u8 discS; // current sector offset from first track (BCD encoded) u8 discM; // current minute offset from first track (BCD encoded)
u8 discF; // current frame offset from first track (BCD encoded) u8 discS; // current sector offset from first track (BCD encoded)
u8 discF; // current frame offset from first track (BCD encoded)
} cdvdSubQ; } cdvdSubQ;
typedef struct _cdvdTD { // NOT bcd coded typedef struct _cdvdTD
u32 lsn; { // NOT bcd coded
u8 type; u32 lsn;
u8 type;
} cdvdTD; } cdvdTD;
typedef struct _cdvdTN { typedef struct _cdvdTN
u8 strack; //number of the first track (usually 1) {
u8 etrack; //number of the last track u8 strack; //number of the first track (usually 1)
u8 etrack; //number of the last track
} cdvdTN; } cdvdTN;
// CDVDreadTrack mode values: // CDVDreadTrack mode values:
enum { enum {
CDVD_MODE_2352 0, // full 2352 bytes CDVD_MODE_2352 0, // full 2352 bytes
CDVD_MODE_2340 1, // skip sync (12) bytes CDVD_MODE_2340 1, // skip sync (12) bytes
CDVD_MODE_2328 2, // skip sync+head+sub (24) bytes CDVD_MODE_2328 2, // skip sync+head+sub (24) bytes
CDVD_MODE_2048 3, // skip sync+head+sub (24) bytes CDVD_MODE_2048 3, // skip sync+head+sub (24) bytes
CDVD_MODE_2368 4 // full 2352 bytes + 16 subq CDVD_MODE_2368 4 // full 2352 bytes + 16 subq
} TrackModes } TrackModes
// CDVDgetDiskType returns: // CDVDgetDiskType returns:
enum { enum {
CDVD_TYPE_ILLEGAL = 0xff, // Illegal Disc CDVD_TYPE_ILLEGAL = 0xff, // Illegal Disc
CDVD_TYPE_DVDV = 0xfe, // DVD Video CDVD_TYPE_DVDV = 0xfe, // DVD Video
CDVD_TYPE_CDDA = 0xfd, // Audio CD CDVD_TYPE_CDDA = 0xfd, // Audio CD
CDVD_TYPE_PS2DVD = 0x14, // PS2 DVD CDVD_TYPE_PS2DVD = 0x14, // PS2 DVD
CDVD_TYPE_PS2CDDA = 0x13, // PS2 CD (with audio) CDVD_TYPE_PS2CDDA = 0x13, // PS2 CD (with audio)
CDVD_TYPE_PS2CD = 0x12, // PS2 CD CDVD_TYPE_PS2CD = 0x12, // PS2 CD
CDVD_TYPE_PSCDDA = 0x11, // PS CD (with audio) CDVD_TYPE_PSCDDA = 0x11, // PS CD (with audio)
CDVD_TYPE_PSCD = 0x10, // PS CD CDVD_TYPE_PSCD = 0x10, // PS CD
CDVD_TYPE_UNKNOWN = 0x05, // Unknown CDVD_TYPE_UNKNOWN = 0x05, // Unknown
CDVD_TYPE_DETCTDVDD = 0x04, // Detecting Dvd Dual Sided CDVD_TYPE_DETCTDVDD = 0x04, // Detecting Dvd Dual Sided
CDVD_TYPE_DETCTDVDS = 0x03, // Detecting Dvd Single Sided CDVD_TYPE_DETCTDVDS = 0x03, // Detecting Dvd Single Sided
CDVD_TYPE_DETCTCD = 0x02, // Detecting Cd CDVD_TYPE_DETCTCD = 0x02, // Detecting Cd
CDVD_TYPE_DETCT = 0x01, // Detecting CDVD_TYPE_DETCT = 0x01, // Detecting
CDVD_TYPE_NODISC = 0x00 // No Disc CDVD_TYPE_NODISC = 0x00 // No Disc
} DiskType; } DiskType;
// CDVDgetTrayStatus returns: // CDVDgetTrayStatus returns:
enum { enum {
CDVD_TRAY_CLOSE = 0x00, CDVD_TRAY_CLOSE = 0x00,
CDVD_TRAY_OPEN = 0x01 CDVD_TRAY_OPEN = 0x01
} TrayStatus; } TrayStatus;
// cdvdTD.type (track types for cds) // cdvdTD.type (track types for cds)
enum { enum {
CDVD_AUDIO_TRACK = 0x01, CDVD_AUDIO_TRACK = 0x01,
CDVD_MODE1_TRACK = 0x41, CDVD_MODE1_TRACK = 0x41,
CDVD_MODE2_TRACK = 0x61 CDVD_MODE2_TRACK = 0x61
} CDVDTDType; } CDVDTDType;
enum { enum {
CDVD_AUDIO_MASK = 0x00, CDVD_AUDIO_MASK = 0x00,
CDVD_DATA_MASK = 0x40 CDVD_DATA_MASK = 0x40
// CDROM_DATA_TRACK 0x04 //do not enable this! (from linux kernel) // CDROM_DATA_TRACK 0x04 //do not enable this! (from linux kernel)
} CDVD_Masks; } CDVD_Masks;
#endif // __CDVDAPI_H__ #endif // __CDVDAPI_H__

View File

@ -32,37 +32,56 @@
#include "Pcsx2Api.h" #include "Pcsx2Api.h"
typedef void (*DEV9callback)(int cycles); typedef void (*DEV9callback)(int cycles);
typedef int (*DEV9handler)(void); typedef int (*DEV9handler)(void);
// Basic functions. // Basic functions.
// NOTE: The read/write functions CANNOT use XMM/MMX regs // NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones // If you want to use them, need to save and restore current ones
EXPORT_C_(s32) DEV9init(); EXPORT_C_(s32)
DEV9init();
// pDisplay normally is passed a handle to the GS plugins window. // pDisplay normally is passed a handle to the GS plugins window.
EXPORT_C_(s32) DEV9open(void *pDisplay); EXPORT_C_(s32)
EXPORT_C_(void) DEV9close(); DEV9open(void *pDisplay);
EXPORT_C_(void) DEV9shutdown(); EXPORT_C_(void)
EXPORT_C_(u8) DEV9read8(u32 addr); DEV9close();
EXPORT_C_(u16) DEV9read16(u32 addr); EXPORT_C_(void)
EXPORT_C_(u32) DEV9read32(u32 addr); DEV9shutdown();
EXPORT_C_(void) DEV9write8(u32 addr, u8 value); EXPORT_C_(u8)
EXPORT_C_(void) DEV9write16(u32 addr, u16 value); DEV9read8(u32 addr);
EXPORT_C_(void) DEV9write32(u32 addr, u32 value); EXPORT_C_(u16)
EXPORT_C_(void) DEV9readDMA8Mem(u32 *pMem, int size); DEV9read16(u32 addr);
EXPORT_C_(void) DEV9writeDMA8Mem(u32 *pMem, int size); EXPORT_C_(u32)
DEV9read32(u32 addr);
EXPORT_C_(void)
DEV9write8(u32 addr, u8 value);
EXPORT_C_(void)
DEV9write16(u32 addr, u16 value);
EXPORT_C_(void)
DEV9write32(u32 addr, u32 value);
EXPORT_C_(void)
DEV9readDMA8Mem(u32 *pMem, int size);
EXPORT_C_(void)
DEV9writeDMA8Mem(u32 *pMem, int size);
// cycles = IOP cycles before calling callback, // cycles = IOP cycles before calling callback,
// if callback returns 1 the irq is triggered, else not // if callback returns 1 the irq is triggered, else not
EXPORT_C_(void) DEV9irqCallback(DEV9callback callback); EXPORT_C_(void)
EXPORT_C_(DEV9handler) DEV9irqHandler(void); DEV9irqCallback(DEV9callback callback);
EXPORT_C_(DEV9handler)
DEV9irqHandler(void);
// Extended functions // Extended functions
EXPORT_C_(void) DEV9keyEvent(keyEvent *ev); EXPORT_C_(void)
EXPORT_C_(s32) DEV9freeze(u8 mode, freezeData *data); DEV9keyEvent(keyEvent *ev);
EXPORT_C_(void) DEV9configure(); EXPORT_C_(s32)
EXPORT_C_(void) DEV9about(); DEV9freeze(u8 mode, freezeData *data);
EXPORT_C_(s32) DEV9test(); EXPORT_C_(void)
DEV9configure();
EXPORT_C_(void)
DEV9about();
EXPORT_C_(s32)
DEV9test();
#endif // __DEV9API_H__ #endif // __DEV9API_H__

View File

@ -37,22 +37,34 @@
// NOTE: The read/write functions CANNOT use XMM/MMX regs // NOTE: The read/write functions CANNOT use XMM/MMX regs
// If you want to use them, need to save and restore current ones // If you want to use them, need to save and restore current ones
EXPORT_C_(s32) FWinit(); EXPORT_C_(s32)
FWinit();
// pDisplay normally is passed a handle to the GS plugins window. // pDisplay normally is passed a handle to the GS plugins window.
EXPORT_C_(s32) FWopen(void *pDisplay); EXPORT_C_(s32)
EXPORT_C_(void) FWclose(); FWopen(void *pDisplay);
EXPORT_C_(void) FWshutdown(); EXPORT_C_(void)
EXPORT_C_(u32) FWread32(u32 addr); FWclose();
EXPORT_C_(void) FWwrite32(u32 addr, u32 value); EXPORT_C_(void)
EXPORT_C_(void) FWirqCallback(void (*callback)()); FWshutdown();
EXPORT_C_(u32)
FWread32(u32 addr);
EXPORT_C_(void)
FWwrite32(u32 addr, u32 value);
EXPORT_C_(void)
FWirqCallback(void (*callback)());
// Extended functions // Extended functions
EXPORT_C_(void) FWkeyEvent(keyEvent *ev); EXPORT_C_(void)
EXPORT_C_(s32) FWfreeze(u8 mode, freezeData *data); FWkeyEvent(keyEvent *ev);
EXPORT_C_(void) FWconfigure(); EXPORT_C_(s32)
EXPORT_C_(void) FWabout(); FWfreeze(u8 mode, freezeData *data);
EXPORT_C_(s32) FWtest(); EXPORT_C_(void)
FWconfigure();
EXPORT_C_(void)
FWabout();
EXPORT_C_(s32)
FWtest();
#endif #endif
#endif // __USBAPI_H__ #endif // __USBAPI_H__

View File

@ -31,55 +31,86 @@
#include "Pcsx2Api.h" #include "Pcsx2Api.h"
typedef struct _GSdriverInfo { typedef struct _GSdriverInfo
char name[8]; {
void *common; char name[8];
void *common;
} GSdriverInfo; } GSdriverInfo;
// Basic functions. // Basic functions.
EXPORT_C_(s32) GSinit(); EXPORT_C_(s32)
GSinit();
// pDisplay normally is passed a handle to the GS plugins window. // pDisplay normally is passed a handle to the GS plugins window.
EXPORT_C_(s32) GSopen(void *pDisplay, char *Title, bool multithread); EXPORT_C_(s32)
EXPORT_C_(void) GSclose(); GSopen(void *pDisplay, char *Title, bool multithread);
EXPORT_C_(void) GSshutdown(); EXPORT_C_(void)
EXPORT_C_(void) GSvsync(int field); GSclose();
EXPORT_C_(void) GSgifTransfer1(u32 *pMem, u32 addr); EXPORT_C_(void)
EXPORT_C_(void) GSgifTransfer2(u32 *pMem, u32 size); GSshutdown();
EXPORT_C_(void) GSgifTransfer3(u32 *pMem, u32 size); EXPORT_C_(void)
EXPORT_C_(void) GSgetLastTag(u64* ptag); // returns the last tag processed (64 bits) GSvsync(int field);
EXPORT_C_(void) GSgifSoftReset(u32 mask); EXPORT_C_(void)
EXPORT_C_(void) GSreadFIFO(u64 *mem); GSgifTransfer1(u32 *pMem, u32 addr);
EXPORT_C_(void) GSreadFIFO2(u64 *mem, int qwc); EXPORT_C_(void)
GSgifTransfer2(u32 *pMem, u32 size);
EXPORT_C_(void)
GSgifTransfer3(u32 *pMem, u32 size);
EXPORT_C_(void)
GSgetLastTag(u64 *ptag); // returns the last tag processed (64 bits)
EXPORT_C_(void)
GSgifSoftReset(u32 mask);
EXPORT_C_(void)
GSreadFIFO(u64 *mem);
EXPORT_C_(void)
GSreadFIFO2(u64 *mem, int qwc);
// Extended functions // Extended functions
// GSkeyEvent gets called when there is a keyEvent from the PAD plugin // GSkeyEvent gets called when there is a keyEvent from the PAD plugin
EXPORT_C_(void) GSkeyEvent(keyEvent *ev); EXPORT_C_(void)
EXPORT_C_(void) GSchangeSaveState(s32 state, const char* filename); GSkeyEvent(keyEvent *ev);
EXPORT_C_(void) GSmakeSnapshot(char *path); EXPORT_C_(void)
EXPORT_C_(void) GSmakeSnapshot2(char *pathname, int* snapdone, int savejpg); GSchangeSaveState(s32 state, const char *filename);
EXPORT_C_(void) GSirqCallback(void (*callback)()); EXPORT_C_(void)
EXPORT_C_(void) CALLBACK GSprintf(s32 timeout, char *fmt, ...); GSmakeSnapshot(char *path);
EXPORT_C_(void) GSsetBaseMem(void*); EXPORT_C_(void)
EXPORT_C_(void) GSsetGameCRC(s32 crc, s32 gameoptions); GSmakeSnapshot2(char *pathname, int *snapdone, int savejpg);
EXPORT_C_(void)
GSirqCallback(void (*callback)());
EXPORT_C_(void)
CALLBACK GSprintf(s32 timeout, char *fmt, ...);
EXPORT_C_(void)
GSsetBaseMem(void *);
EXPORT_C_(void)
GSsetGameCRC(s32 crc, s32 gameoptions);
// controls frame skipping in the GS, if this routine isn't present, frame skipping won't be done // controls frame skipping in the GS, if this routine isn't present, frame skipping won't be done
EXPORT_C_(void) GSsetFrameSkip(int frameskip); EXPORT_C_(void)
GSsetFrameSkip(int frameskip);
// if start is true, starts recording spu2 data, else stops // if start is true, starts recording spu2 data, else stops
// returns true if successful // returns true if successful
// for now, pData is not used // for now, pData is not used
EXPORT_C_(bool) GSsetupRecording(bool start); EXPORT_C_(bool)
GSsetupRecording(bool start);
EXPORT_C_(void) GSreset(); EXPORT_C_(void)
EXPORT_C_(void) GSwriteCSR(u32 value); GSreset();
EXPORT_C_(void ) GSgetDriverInfo(GSdriverInfo *info); EXPORT_C_(void)
GSwriteCSR(u32 value);
EXPORT_C_(void)
GSgetDriverInfo(GSdriverInfo *info);
#ifdef _WIN32 #ifdef _WIN32
EXPORT_C_(s32) CALLBACK GSsetWindowInfo(winInfo *info); EXPORT_C_(s32)
CALLBACK GSsetWindowInfo(winInfo *info);
#endif #endif
EXPORT_C_(s32) GSfreeze(u8 mode, freezeData *data); EXPORT_C_(s32)
EXPORT_C_(void) GSconfigure(); GSfreeze(u8 mode, freezeData *data);
EXPORT_C_(void) GSabout(); EXPORT_C_(void)
EXPORT_C_(s32) GStest(); GSconfigure();
EXPORT_C_(void)
GSabout();
EXPORT_C_(s32)
GStest();
#endif // __GSAPI_H__ #endif // __GSAPI_H__

View File

@ -35,19 +35,27 @@
/* So obsolete that everyone uses it. */ /* So obsolete that everyone uses it. */
// Basic functions. // Basic functions.
EXPORT_C_(s32) PADinit(u32 flags); EXPORT_C_(s32)
PADinit(u32 flags);
// pDisplay normally is passed a handle to the GS plugins window. // pDisplay normally is passed a handle to the GS plugins window.
EXPORT_C_(s32) PADopen(void *pDisplay); EXPORT_C_(s32)
EXPORT_C_(void) PADclose(); PADopen(void *pDisplay);
EXPORT_C_(void) PADshutdown(); EXPORT_C_(void)
PADclose();
EXPORT_C_(void)
PADshutdown();
// PADkeyEvent is called every vsync (return NULL if no event) // PADkeyEvent is called every vsync (return NULL if no event)
EXPORT_C_(keyEvent*) PADkeyEvent(); EXPORT_C_(keyEvent *)
EXPORT_C_(u8) PADstartPoll(u8 pad); PADkeyEvent();
EXPORT_C_(u8) PADpoll(u8 value); EXPORT_C_(u8)
PADstartPoll(u8 pad);
EXPORT_C_(u8)
PADpoll(u8 value);
// returns: 1 if supported pad1 // returns: 1 if supported pad1
// 2 if supported pad2 // 2 if supported pad2
// 3 if both are supported // 3 if both are supported
EXPORT_C_(u8) PADquery(); EXPORT_C_(u8)
PADquery();
// call to give a hint to the PAD plugin to query for the keyboard state. A // call to give a hint to the PAD plugin to query for the keyboard state. A
// good plugin will query the OS for keyboard state ONLY in this function. // good plugin will query the OS for keyboard state ONLY in this function.
@ -56,25 +64,33 @@ EXPORT_C_(u8) PADquery();
// the window (and input). Note that PADupdate can be called from a different // the window (and input). Note that PADupdate can be called from a different
// thread than the other functions, so mutex or other multithreading primitives // thread than the other functions, so mutex or other multithreading primitives
// have to be added to maintain data integrity. // have to be added to maintain data integrity.
EXPORT_C_(void) PADupdate(u8 pad); EXPORT_C_(void)
PADupdate(u8 pad);
// Extended functions // Extended functions
EXPORT_C_(void) PADgsDriverInfo(GSdriverInfo *info); EXPORT_C_(void)
EXPORT_C_(s32) PADfreeze(u8 mode, freezeData *data); PADgsDriverInfo(GSdriverInfo *info);
EXPORT_C_(s32)
PADfreeze(u8 mode, freezeData *data);
// Returns 1 if the pad plugin wants a multitap on the specified port. // Returns 1 if the pad plugin wants a multitap on the specified port.
// 0 otherwise. // 0 otherwise.
EXPORT_C_(s32) PADqueryMtap(u8 port); EXPORT_C_(s32)
PADqueryMtap(u8 port);
// Sets the active pad slot for the specified port. // Sets the active pad slot for the specified port.
// Both numbers are 1-based indices. Should return 0 if there's no // Both numbers are 1-based indices. Should return 0 if there's no
// pad on the specified slot. Even if PADqueryMtap(port) returns 0, // pad on the specified slot. Even if PADqueryMtap(port) returns 0,
// should handle this properly for slot != 1, so emulator can allow // should handle this properly for slot != 1, so emulator can allow
// Multitap to be enabled/disabled elsewhere. // Multitap to be enabled/disabled elsewhere.
EXPORT_C_(s32) PADsetSlot(u8 port, u8 slot); EXPORT_C_(s32)
PADsetSlot(u8 port, u8 slot);
EXPORT_C_(void) PADconfigure(); EXPORT_C_(void)
EXPORT_C_(void) PADabout(); PADconfigure();
EXPORT_C_(s32) PADtest(); EXPORT_C_(void)
PADabout();
EXPORT_C_(s32)
PADtest();
#endif // __PADAPI_H__ #endif // __PADAPI_H__

View File

@ -38,49 +38,61 @@
// MTAP SIO plugins should ignore slot values on startPoll, as should RMs (probably). // MTAP SIO plugins should ignore slot values on startPoll, as should RMs (probably).
// Port isn't strictly necessary, but doesn't hurt. // Port isn't strictly necessary, but doesn't hurt.
typedef int (CALLBACK * SIOchangeSlotCB)(int port, int slot); typedef int(CALLBACK *SIOchangeSlotCB)(int port, int slot);
// Basic functions. // Basic functions.
// Types is an or-ed combination of SioTypes to initialize. It'd probably be simplest // Types is an or-ed combination of SioTypes to initialize. It'd probably be simplest
// just to make each SIO plugin support only one type, for simplicity. // just to make each SIO plugin support only one type, for simplicity.
// SIOchangeSlotCB should *only* be called by MTAP plugins. // SIOchangeSlotCB should *only* be called by MTAP plugins.
EXPORT_C_(s32) SIOinit(int types, SIOchangeSlotCB f); EXPORT_C_(s32)
SIOinit(int types, SIOchangeSlotCB f);
// Single plugin can only be PAD, MTAP, RM, or MC. Only load one plugin of each type, // Single plugin can only be PAD, MTAP, RM, or MC. Only load one plugin of each type,
// but not both a PAD and MTAP. Simplifies plugin selection and interface, as well // but not both a PAD and MTAP. Simplifies plugin selection and interface, as well
// as API. // as API.
// pDisplay normally is passed a handle to the GS plugins window. // pDisplay normally is passed a handle to the GS plugins window.
EXPORT_C_(s32) SIOopen(void *pDisplay); EXPORT_C_(s32)
EXPORT_C_(void) SIOclose(); SIOopen(void *pDisplay);
EXPORT_C_(void) SIOshutdown(); EXPORT_C_(void)
SIOclose();
EXPORT_C_(void)
SIOshutdown();
// Returns 0 if device doesn't exist. Means old pad plugins can just say nothing // Returns 0 if device doesn't exist. Means old pad plugins can just say nothing
// connected to other slots, and SIOpoll won't be called on those slots, ideally. // connected to other slots, and SIOpoll won't be called on those slots, ideally.
EXPORT_C_(s32) SIOstartPoll(u8 deviceType, u32 port, u32 slot, u8 *returnValue); EXPORT_C_(s32)
SIOstartPoll(u8 deviceType, u32 port, u32 slot, u8 *returnValue);
// Returns 0 on the last output byte. // Returns 0 on the last output byte.
EXPORT_C_(s32) SIOpoll(u8 value, u8 *returnValue); EXPORT_C_(s32)
SIOpoll(u8 value, u8 *returnValue);
// returns: SIO_TYPE_{PAD,MTAP,RM,MC} // returns: SIO_TYPE_{PAD,MTAP,RM,MC}
EXPORT_C_(u32) SIOquery(); EXPORT_C_(u32)
SIOquery();
// extended funcs // extended funcs
EXPORT_C_(void) SIOconfigure(); EXPORT_C_(void)
EXPORT_C_(keyEvent*) CALLBACK SIOkeyEvent(); SIOconfigure();
EXPORT_C_(keyEvent *)
CALLBACK SIOkeyEvent();
// Save one type at a time. If a plugin supports all 4 types, // Save one type at a time. If a plugin supports all 4 types,
// should expect 4 calls. Increases savestate compatibility. // should expect 4 calls. Increases savestate compatibility.
EXPORT_C_(s32) SIOfreeze(u8 mode, freezeData *data, int type); EXPORT_C_(s32)
EXPORT_C_(void) SIOabout(); SIOfreeze(u8 mode, freezeData *data, int type);
EXPORT_C_(s32) SIOtest(); EXPORT_C_(void)
SIOabout();
EXPORT_C_(s32)
SIOtest();
enum { enum {
SIO_TYPE_PAD = 0x00000001, SIO_TYPE_PAD = 0x00000001,
SIO_TYPE_MTAP = 0x00000004, SIO_TYPE_MTAP = 0x00000004,
SIO_TYPE_RM = 0x00000040, SIO_TYPE_RM = 0x00000040,
SIO_TYPE_MC = 0x00000100 SIO_TYPE_MC = 0x00000100
} SioTypes; } SioTypes;
#endif // __SIOAPI_H__ #endif // __SIOAPI_H__

View File

@ -31,47 +31,74 @@
#include "Pcsx2Api.h" #include "Pcsx2Api.h"
EXPORT_C_(s32) SPU2init(); EXPORT_C_(s32)
SPU2init();
// pDisplay normally is passed a handle to the GS plugins window. // pDisplay normally is passed a handle to the GS plugins window.
EXPORT_C_(s32) SPU2open(void *pDisplay); EXPORT_C_(s32)
EXPORT_C_(void) SPU2close(); SPU2open(void *pDisplay);
EXPORT_C_(void) SPU2shutdown(); EXPORT_C_(void)
EXPORT_C_(void) SPU2write(u32 mem, u16 value); SPU2close();
EXPORT_C_(u16) SPU2read(u32 mem); EXPORT_C_(void)
SPU2shutdown();
EXPORT_C_(void)
SPU2write(u32 mem, u16 value);
EXPORT_C_(u16)
SPU2read(u32 mem);
// The following calls are depreciated. // The following calls are depreciated.
EXPORT_C_(void) SPU2readDMA4Mem(u16 *pMem, u32 size); EXPORT_C_(void)
EXPORT_C_(void) SPU2readDMA7Mem(u16 *pMem, u32 size); SPU2readDMA4Mem(u16 *pMem, u32 size);
EXPORT_C_(void) SPU2writeDMA4Mem(u16 *pMem, u32 size); EXPORT_C_(void)
EXPORT_C_(void) SPU2writeDMA7Mem(u16 *pMem, u32 size); SPU2readDMA7Mem(u16 *pMem, u32 size);
EXPORT_C_(void) SPU2interruptDMA4(); EXPORT_C_(void)
EXPORT_C_(void) SPU2interruptDMA7(); SPU2writeDMA4Mem(u16 *pMem, u32 size);
EXPORT_C_(void)
SPU2writeDMA7Mem(u16 *pMem, u32 size);
EXPORT_C_(void)
SPU2interruptDMA4();
EXPORT_C_(void)
SPU2interruptDMA7();
// These calls replace the calls above. // These calls replace the calls above.
EXPORT_C_(void) SPU2readDMAMem(u16 *pMem, u32 size, u8 core); EXPORT_C_(void)
EXPORT_C_(void) SPU2writeDMAMem(u16 *pMem, u32 size, u8 core); SPU2readDMAMem(u16 *pMem, u32 size, u8 core);
EXPORT_C_(void) SPU2interruptDMA(u8 core); EXPORT_C_(void)
SPU2writeDMAMem(u16 *pMem, u32 size, u8 core);
EXPORT_C_(void)
SPU2interruptDMA(u8 core);
// all addresses passed by dma will be pointers to the array starting at baseaddr // all addresses passed by dma will be pointers to the array starting at baseaddr
// This function is necessary to successfully save and reload the spu2 state // This function is necessary to successfully save and reload the spu2 state
EXPORT_C_(void) SPU2setDMABaseAddr(uptr baseaddr); EXPORT_C_(void)
SPU2setDMABaseAddr(uptr baseaddr);
EXPORT_C_(u32) SPU2ReadMemAddr(u8 core); EXPORT_C_(u32)
EXPORT_C_(void) SPU2WriteMemAddr(u8 core,u32 value); SPU2ReadMemAddr(u8 core);
EXPORT_C_(void) SPU2irqCallback(void (*SPU2callback)(),void (*DMA4callback)(),void (*DMA7callback)()); EXPORT_C_(void)
SPU2WriteMemAddr(u8 core, u32 value);
EXPORT_C_(void)
SPU2irqCallback(void (*SPU2callback)(), void (*DMA4callback)(), void (*DMA7callback)());
// extended funcs // extended funcs
// if start is true, starts recording spu2 data, else stops // if start is true, starts recording spu2 data, else stops
// returns true if successful // returns true if successful
EXPORT_C_(bool) SPU2setupRecording(bool start); EXPORT_C_(bool)
SPU2setupRecording(bool start);
EXPORT_C_(void) SPU2keyEvent(keyEvent *ev); EXPORT_C_(void)
EXPORT_C_(void) SPU2setClockPtr(u32* ptr); SPU2keyEvent(keyEvent *ev);
EXPORT_C_(void) SPU2async(u32 cycles); EXPORT_C_(void)
EXPORT_C_(s32) SPU2freeze(u8 mode, freezeData *data); SPU2setClockPtr(u32 *ptr);
EXPORT_C_(void) SPU2configure(); EXPORT_C_(void)
EXPORT_C_(void) SPU2about(); SPU2async(u32 cycles);
EXPORT_C_(s32) SPU2test(); EXPORT_C_(s32)
SPU2freeze(u8 mode, freezeData *data);
EXPORT_C_(void)
SPU2configure();
EXPORT_C_(void)
SPU2about();
EXPORT_C_(s32)
SPU2test();
#endif #endif

View File

@ -32,34 +32,53 @@
#include "Pcsx2Api.h" #include "Pcsx2Api.h"
typedef void (*USBcallback)(int cycles); typedef void (*USBcallback)(int cycles);
typedef int (*USBhandler)(void); typedef int (*USBhandler)(void);
// Basic functions. // Basic functions.
EXPORT_C_(s32) USBinit(); EXPORT_C_(s32)
USBinit();
// pDisplay normally is passed a handle to the GS plugins window. // pDisplay normally is passed a handle to the GS plugins window.
EXPORT_C_(s32) USBopen(void *pDisplay); EXPORT_C_(s32)
EXPORT_C_(void) USBclose(); USBopen(void *pDisplay);
EXPORT_C_(void) USBshutdown(); EXPORT_C_(void)
EXPORT_C_(u8) USBread8(u32 addr); USBclose();
EXPORT_C_(u16) USBread16(u32 addr); EXPORT_C_(void)
EXPORT_C_(u32) USBread32(u32 addr); USBshutdown();
EXPORT_C_(void) USBwrite8(u32 addr, u8 value); EXPORT_C_(u8)
EXPORT_C_(void) USBwrite16(u32 addr, u16 value); USBread8(u32 addr);
EXPORT_C_(void) USBwrite32(u32 addr, u32 value); EXPORT_C_(u16)
EXPORT_C_(void) USBasync(u32 cycles); USBread16(u32 addr);
EXPORT_C_(u32)
USBread32(u32 addr);
EXPORT_C_(void)
USBwrite8(u32 addr, u8 value);
EXPORT_C_(void)
USBwrite16(u32 addr, u16 value);
EXPORT_C_(void)
USBwrite32(u32 addr, u32 value);
EXPORT_C_(void)
USBasync(u32 cycles);
// cycles = IOP cycles before calling callback, // cycles = IOP cycles before calling callback,
// if callback returns 1 the irq is triggered, else not // if callback returns 1 the irq is triggered, else not
EXPORT_C_(void) USBirqCallback(USBcallback callback); EXPORT_C_(void)
EXPORT_C_(USBhandler) USBirqHandler(void); USBirqCallback(USBcallback callback);
EXPORT_C_(void) USBsetRAM(void *mem); EXPORT_C_(USBhandler)
USBirqHandler(void);
EXPORT_C_(void)
USBsetRAM(void *mem);
// Extended functions // Extended functions
EXPORT_C_(void) USBkeyEvent(keyEvent *ev); EXPORT_C_(void)
EXPORT_C_(s32) USBfreeze(u8 mode, freezeData *data); USBkeyEvent(keyEvent *ev);
EXPORT_C_(void) USBconfigure(); EXPORT_C_(s32)
EXPORT_C_(void) USBabout(); USBfreeze(u8 mode, freezeData *data);
EXPORT_C_(s32) USBtest(); EXPORT_C_(void)
USBconfigure();
EXPORT_C_(void)
USBabout();
EXPORT_C_(s32)
USBtest();
#endif // __USBAPI_H__ #endif // __USBAPI_H__

View File

@ -17,21 +17,22 @@
// Implement BMI1/BMI2 instruction set // Implement BMI1/BMI2 instruction set
namespace x86Emitter { namespace x86Emitter
{
struct xImplBMI_RVM struct xImplBMI_RVM
{ {
u8 Prefix; u8 Prefix;
u8 MbPrefix; u8 MbPrefix;
u8 Opcode; u8 Opcode;
// RVM // RVM
// MULX Unsigned multiply without affecting flags, and arbitrary destination registers // MULX Unsigned multiply without affecting flags, and arbitrary destination registers
// PDEP Parallel bits deposit // PDEP Parallel bits deposit
// PEXT Parallel bits extract // PEXT Parallel bits extract
// ANDN Logical and not ~x & y // ANDN Logical and not ~x & y
void operator()( const xRegisterInt& to, const xRegisterInt& from1, const xRegisterInt& from2) const; void operator()(const xRegisterInt &to, const xRegisterInt &from1, const xRegisterInt &from2) const;
void operator()( const xRegisterInt& to, const xRegisterInt& from1, const xIndirectVoid& from2) const; void operator()(const xRegisterInt &to, const xRegisterInt &from1, const xIndirectVoid &from2) const;
#if 0 #if 0
// RMV // RMV
@ -56,6 +57,5 @@ namespace x86Emitter {
void operator()( const xRegisterInt& to, const xRegisterInt& from, u8 imm) const; void operator()( const xRegisterInt& to, const xRegisterInt& from, u8 imm) const;
void operator()( const xRegisterInt& to, const xIndirectVoid& from, u8 imm) const; void operator()( const xRegisterInt& to, const xIndirectVoid& from, u8 imm) const;
#endif #endif
}; };
} }

View File

@ -15,7 +15,8 @@
#pragma once #pragma once
namespace x86Emitter { namespace x86Emitter
{
// Implementations here cover SHLD and SHRD. // Implementations here cover SHLD and SHRD.
@ -30,14 +31,14 @@ namespace x86Emitter {
// //
struct xImpl_DwordShift struct xImpl_DwordShift
{ {
u16 OpcodeBase; u16 OpcodeBase;
void operator()( const xRegister16or32or64& to, const xRegister16or32or64& from, const xRegisterCL& clreg ) const; void operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from, const xRegisterCL &clreg) const;
void operator()( const xRegister16or32or64& to, const xRegister16or32or64& from, u8 shiftcnt ) const; void operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from, u8 shiftcnt) const;
void operator()( const xIndirectVoid& dest,const xRegister16or32or64& from, const xRegisterCL& clreg ) const; void operator()(const xIndirectVoid &dest, const xRegister16or32or64 &from, const xRegisterCL &clreg) const;
void operator()( const xIndirectVoid& dest,const xRegister16or32or64& from, u8 shiftcnt ) const; void operator()(const xIndirectVoid &dest, const xRegister16or32or64 &from, u8 shiftcnt) const;
}; };
} // End namespace x86Emitter } // End namespace x86Emitter

View File

@ -15,35 +15,35 @@
#pragma once #pragma once
namespace x86Emitter { namespace x86Emitter
enum G1Type
{ {
G1Type_ADD=0,
G1Type_OR, enum G1Type {
G1Type_ADC, G1Type_ADD = 0,
G1Type_SBB, G1Type_OR,
G1Type_AND, G1Type_ADC,
G1Type_SUB, G1Type_SBB,
G1Type_XOR, G1Type_AND,
G1Type_CMP G1Type_SUB,
G1Type_XOR,
G1Type_CMP
}; };
extern void _g1_EmitOp( G1Type InstType, const xRegisterInt& to, const xRegisterInt& from ); extern void _g1_EmitOp(G1Type InstType, const xRegisterInt &to, const xRegisterInt &from);
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImpl_Group1 // xImpl_Group1
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct xImpl_Group1 struct xImpl_Group1
{ {
G1Type InstType; G1Type InstType;
void operator()( const xRegisterInt& to, const xRegisterInt& from ) const; void operator()(const xRegisterInt &to, const xRegisterInt &from) const;
void operator()( const xIndirectVoid& to, const xRegisterInt& from ) const; void operator()(const xIndirectVoid &to, const xRegisterInt &from) const;
void operator()( const xRegisterInt& to, const xIndirectVoid& from ) const; void operator()(const xRegisterInt &to, const xIndirectVoid &from) const;
void operator()( const xRegisterInt& to, int imm ) const; void operator()(const xRegisterInt &to, int imm) const;
void operator()( const xIndirect64orLess& to, int imm ) const; void operator()(const xIndirect64orLess &to, int imm) const;
#if 0 #if 0
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -87,18 +87,18 @@ struct xImpl_Group1
// //
struct xImpl_G1Logic struct xImpl_G1Logic
{ {
G1Type InstType; G1Type InstType;
void operator()( const xRegisterInt& to, const xRegisterInt& from ) const; void operator()(const xRegisterInt &to, const xRegisterInt &from) const;
void operator()( const xIndirectVoid& to, const xRegisterInt& from ) const; void operator()(const xIndirectVoid &to, const xRegisterInt &from) const;
void operator()( const xRegisterInt& to, const xIndirectVoid& from ) const; void operator()(const xRegisterInt &to, const xIndirectVoid &from) const;
void operator()( const xRegisterInt& to, int imm ) const; void operator()(const xRegisterInt &to, int imm) const;
void operator()( const xIndirect64orLess& to, int imm ) const; void operator()(const xIndirect64orLess &to, int imm) const;
xImplSimd_DestRegSSE PS; // packed single precision xImplSimd_DestRegSSE PS; // packed single precision
xImplSimd_DestRegSSE PD; // packed double precision xImplSimd_DestRegSSE PD; // packed double precision
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -106,38 +106,37 @@ struct xImpl_G1Logic
// //
struct xImpl_G1Arith struct xImpl_G1Arith
{ {
G1Type InstType; G1Type InstType;
void operator()( const xRegisterInt& to, const xRegisterInt& from ) const; void operator()(const xRegisterInt &to, const xRegisterInt &from) const;
void operator()( const xIndirectVoid& to, const xRegisterInt& from ) const; void operator()(const xIndirectVoid &to, const xRegisterInt &from) const;
void operator()( const xRegisterInt& to, const xIndirectVoid& from ) const; void operator()(const xRegisterInt &to, const xIndirectVoid &from) const;
void operator()( const xRegisterInt& to, int imm ) const; void operator()(const xRegisterInt &to, int imm) const;
void operator()( const xIndirect64orLess& to, int imm ) const; void operator()(const xIndirect64orLess &to, int imm) const;
xImplSimd_DestRegSSE PS; // packed single precision xImplSimd_DestRegSSE PS; // packed single precision
xImplSimd_DestRegSSE PD; // packed double precision xImplSimd_DestRegSSE PD; // packed double precision
xImplSimd_DestRegSSE SS; // scalar single precision xImplSimd_DestRegSSE SS; // scalar single precision
xImplSimd_DestRegSSE SD; // scalar double precision xImplSimd_DestRegSSE SD; // scalar double precision
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
struct xImpl_G1Compare struct xImpl_G1Compare
{ {
void operator()( const xRegisterInt& to, const xRegisterInt& from ) const; void operator()(const xRegisterInt &to, const xRegisterInt &from) const;
void operator()( const xIndirectVoid& to, const xRegisterInt& from ) const; void operator()(const xIndirectVoid &to, const xRegisterInt &from) const;
void operator()( const xRegisterInt& to, const xIndirectVoid& from ) const; void operator()(const xRegisterInt &to, const xIndirectVoid &from) const;
void operator()( const xRegisterInt& to, int imm ) const; void operator()(const xRegisterInt &to, int imm) const;
void operator()( const xIndirect64orLess& to, int imm ) const; void operator()(const xIndirect64orLess &to, int imm) const;
xImplSimd_DestSSE_CmpImm PS; xImplSimd_DestSSE_CmpImm PS;
xImplSimd_DestSSE_CmpImm PD; xImplSimd_DestSSE_CmpImm PD;
xImplSimd_DestSSE_CmpImm SS; xImplSimd_DestSSE_CmpImm SS;
xImplSimd_DestSSE_CmpImm SD; xImplSimd_DestSSE_CmpImm SD;
}; };
} // End namespace x86Emitter } // End namespace x86Emitter

View File

@ -15,18 +15,18 @@
#pragma once #pragma once
namespace x86Emitter { namespace x86Emitter
enum G2Type
{ {
G2Type_ROL=0,
G2Type_ROR, enum G2Type {
G2Type_RCL, G2Type_ROL = 0,
G2Type_RCR, G2Type_ROR,
G2Type_SHL, G2Type_RCL,
G2Type_SHR, G2Type_RCR,
G2Type_Unused, G2Type_SHL,
G2Type_SAR G2Type_SHR,
G2Type_Unused,
G2Type_SAR
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -38,12 +38,12 @@ enum G2Type
// //
struct xImpl_Group2 struct xImpl_Group2
{ {
G2Type InstType; G2Type InstType;
void operator()( const xRegisterInt& to, const xRegisterCL& from ) const; void operator()(const xRegisterInt &to, const xRegisterCL &from) const;
void operator()( const xIndirect64orLess& to, const xRegisterCL& from ) const; void operator()(const xIndirect64orLess &to, const xRegisterCL &from) const;
void operator()( const xRegisterInt& to, u8 imm ) const; void operator()(const xRegisterInt &to, u8 imm) const;
void operator()( const xIndirect64orLess& to, u8 imm ) const; void operator()(const xIndirect64orLess &to, u8 imm) const;
#if 0 #if 0
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -15,16 +15,16 @@
#pragma once #pragma once
namespace x86Emitter { namespace x86Emitter
enum G3Type
{ {
G3Type_NOT = 2,
G3Type_NEG = 3, enum G3Type {
G3Type_MUL = 4, G3Type_NOT = 2,
G3Type_iMUL = 5, // partial implementation, iMul has additional forms in ix86.cpp G3Type_NEG = 3,
G3Type_DIV = 6, G3Type_MUL = 4,
G3Type_iDIV = 7 G3Type_iMUL = 5, // partial implementation, iMul has additional forms in ix86.cpp
G3Type_DIV = 6,
G3Type_iDIV = 7
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -32,10 +32,10 @@ enum G3Type
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct xImpl_Group3 struct xImpl_Group3
{ {
G3Type InstType; G3Type InstType;
void operator()( const xRegisterInt& from ) const; void operator()(const xRegisterInt &from) const;
void operator()( const xIndirect64orLess& from ) const; void operator()(const xIndirect64orLess &from) const;
#if 0 #if 0
template< typename T > template< typename T >
@ -53,16 +53,16 @@ struct xImpl_Group3
// //
struct xImpl_MulDivBase struct xImpl_MulDivBase
{ {
G3Type InstType; G3Type InstType;
u16 OpcodeSSE; u16 OpcodeSSE;
void operator()( const xRegisterInt& from ) const; void operator()(const xRegisterInt &from) const;
void operator()( const xIndirect64orLess& from ) const; void operator()(const xIndirect64orLess &from) const;
const xImplSimd_DestRegSSE PS; const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE PD; const xImplSimd_DestRegSSE PD;
const xImplSimd_DestRegSSE SS; const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD; const xImplSimd_DestRegSSE SD;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -70,13 +70,13 @@ struct xImpl_MulDivBase
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct xImpl_iDiv struct xImpl_iDiv
{ {
void operator()( const xRegisterInt& from ) const; void operator()(const xRegisterInt &from) const;
void operator()( const xIndirect64orLess& from ) const; void operator()(const xIndirect64orLess &from) const;
const xImplSimd_DestRegSSE PS; const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE PD; const xImplSimd_DestRegSSE PD;
const xImplSimd_DestRegSSE SS; const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD; const xImplSimd_DestRegSSE SD;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -85,25 +85,24 @@ struct xImpl_iDiv
// //
struct xImpl_iMul struct xImpl_iMul
{ {
void operator()( const xRegisterInt& from ) const; void operator()(const xRegisterInt &from) const;
void operator()( const xIndirect64orLess& from ) const; void operator()(const xIndirect64orLess &from) const;
// The following iMul-specific forms are valid for 16 and 32 bit register operands only! // The following iMul-specific forms are valid for 16 and 32 bit register operands only!
void operator()( const xRegister32& to, const xRegister32& from ) const; void operator()(const xRegister32 &to, const xRegister32 &from) const;
void operator()( const xRegister32& to, const xIndirectVoid& src ) const; void operator()(const xRegister32 &to, const xIndirectVoid &src) const;
void operator()( const xRegister16& to, const xRegister16& from ) const; void operator()(const xRegister16 &to, const xRegister16 &from) const;
void operator()( const xRegister16& to, const xIndirectVoid& src ) const; void operator()(const xRegister16 &to, const xIndirectVoid &src) const;
void operator()( const xRegister32& to, const xRegister32& from, s32 imm ) const; void operator()(const xRegister32 &to, const xRegister32 &from, s32 imm) const;
void operator()( const xRegister32& to, const xIndirectVoid& from, s32 imm ) const; void operator()(const xRegister32 &to, const xIndirectVoid &from, s32 imm) const;
void operator()( const xRegister16& to, const xRegister16& from, s16 imm ) const; void operator()(const xRegister16 &to, const xRegister16 &from, s16 imm) const;
void operator()( const xRegister16& to, const xIndirectVoid& from, s16 imm ) const; void operator()(const xRegister16 &to, const xIndirectVoid &from, s16 imm) const;
const xImplSimd_DestRegSSE PS; const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE PD; const xImplSimd_DestRegSSE PD;
const xImplSimd_DestRegSSE SS; const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD; const xImplSimd_DestRegSSE SD;
}; };
} }

View File

@ -15,7 +15,8 @@
#pragma once #pragma once
namespace x86Emitter { namespace x86Emitter
{
// helpermess is currently broken >_< // helpermess is currently broken >_<
@ -88,4 +89,4 @@ void _DoI_helpermess( const xImpl& helpme, const xDirectOrIndirect<T>& to, const
} }
#endif #endif
} // End namespace x86Emitter } // End namespace x86Emitter

View File

@ -18,17 +18,18 @@
// Implementations found here: Increment and Decrement Instructions! // Implementations found here: Increment and Decrement Instructions!
// (They're soooo lonely... but I dunno where else to stick this class!) // (They're soooo lonely... but I dunno where else to stick this class!)
namespace x86Emitter { namespace x86Emitter
{
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImpl_IncDec // xImpl_IncDec
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct xImpl_IncDec struct xImpl_IncDec
{ {
bool isDec; bool isDec;
void operator()( const xRegisterInt& to ) const; void operator()(const xRegisterInt &to) const;
void operator()( const xIndirect64orLess& to ) const; void operator()(const xIndirect64orLess &to) const;
}; };
} // End namespace x86Emitter } // End namespace x86Emitter

View File

@ -17,171 +17,170 @@
// Implementations found here: CALL and JMP! (unconditional only) // Implementations found here: CALL and JMP! (unconditional only)
namespace x86Emitter { namespace x86Emitter
{
extern void xJccKnownTarget( JccComparisonType comparison, const void* target, bool slideForward ); extern void xJccKnownTarget(JccComparisonType comparison, const void *target, bool slideForward);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
struct xImpl_JmpCall struct xImpl_JmpCall
{ {
bool isJmp; bool isJmp;
void operator()( const xRegisterInt& absreg ) const; void operator()(const xRegisterInt &absreg) const;
void operator()( const xIndirect64orLess& src ) const; void operator()(const xIndirect64orLess &src) const;
// Special form for calling functions. This form automatically resolves the // Special form for calling functions. This form automatically resolves the
// correct displacement based on the size of the instruction being generated. // correct displacement based on the size of the instruction being generated.
void operator()( void* func ) const void operator()(void *func) const
{ {
if( isJmp ) if (isJmp)
xJccKnownTarget( Jcc_Unconditional, (void*)(uptr)func, false ); // double cast to/from (uptr) needed to appease GCC xJccKnownTarget(Jcc_Unconditional, (void *)(uptr)func, false); // double cast to/from (uptr) needed to appease GCC
else else {
{ // calls are relative to the instruction after this one, and length is
// calls are relative to the instruction after this one, and length is // always 5 bytes (16 bit calls are bad mojo, so no bother to do special logic).
// always 5 bytes (16 bit calls are bad mojo, so no bother to do special logic).
sptr dest = (sptr)func - ((sptr)xGetPtr() + 5); sptr dest = (sptr)func - ((sptr)xGetPtr() + 5);
xWrite8( 0xe8 ); xWrite8(0xe8);
xWrite32( dest ); xWrite32(dest);
} }
} }
}; };
// yes it is awful. Due to template code is in a header with a nice circular dep. // yes it is awful. Due to template code is in a header with a nice circular dep.
extern const xImpl_Mov xMOV; extern const xImpl_Mov xMOV;
extern const xImpl_JmpCall xCALL; extern const xImpl_JmpCall xCALL;
struct xImpl_FastCall struct xImpl_FastCall
{ {
// FIXME: current 64 bits is mostly a copy/past potentially it would require to push/pop // FIXME: current 64 bits is mostly a copy/past potentially it would require to push/pop
// some registers. But I think it is enough to handle the first call. // some registers. But I think it is enough to handle the first call.
// Type unsafety is nice // Type unsafety is nice
#ifdef __x86_64__ #ifdef __x86_64__
#define XFASTCALL \ #define XFASTCALL \
xCALL(f); xCALL(f);
#define XFASTCALL1 \ #define XFASTCALL1 \
xMOV(rdi, a1); \ xMOV(rdi, a1); \
xCALL(f); xCALL(f);
#define XFASTCALL2 \ #define XFASTCALL2 \
xMOV(rdi, a1); \ xMOV(rdi, a1); \
xMOV(rsi, a2); \ xMOV(rsi, a2); \
xCALL(f); xCALL(f);
#else #else
#define XFASTCALL \ #define XFASTCALL \
xCALL(f); xCALL(f);
#define XFASTCALL1 \ #define XFASTCALL1 \
xMOV(ecx, a1); \ xMOV(ecx, a1); \
xCALL(f); xCALL(f);
#define XFASTCALL2 \ #define XFASTCALL2 \
xMOV(ecx, a1); \ xMOV(ecx, a1); \
xMOV(edx, a2); \ xMOV(edx, a2); \
xCALL(f); xCALL(f);
#endif #endif
void operator()( void* f, const xRegisterLong& a1 = xEmptyReg, const xRegisterLong& a2 = xEmptyReg) const void operator()(void *f, const xRegisterLong &a1 = xEmptyReg, const xRegisterLong &a2 = xEmptyReg) const
{ {
#ifdef __x86_64__ #ifdef __x86_64__
if (a1.IsEmpty()) { if (a1.IsEmpty()) {
XFASTCALL; XFASTCALL;
} else if (a2.IsEmpty()) { } else if (a2.IsEmpty()) {
XFASTCALL1; XFASTCALL1;
} else { } else {
XFASTCALL2; XFASTCALL2;
} }
#else #else
if (a1.IsEmpty()) { if (a1.IsEmpty()) {
XFASTCALL; XFASTCALL;
} else if (a2.IsEmpty()) { } else if (a2.IsEmpty()) {
XFASTCALL1; XFASTCALL1;
} else { } else {
XFASTCALL2; XFASTCALL2;
} }
#endif #endif
} }
template< typename T > __fi template <typename T>
void operator()( T* func, u32 a1, const xRegisterLong& a2) const __fi void operator()(T *func, u32 a1, const xRegisterLong &a2) const
{ {
void* f = (void*)func; void *f = (void *)func;
#ifdef __x86_64__ #ifdef __x86_64__
XFASTCALL2; XFASTCALL2;
#else #else
XFASTCALL2; XFASTCALL2;
#endif #endif
} }
template< typename T > __fi template <typename T>
void operator()( T* func, const xIndirectVoid& a1) const __fi void operator()(T *func, const xIndirectVoid &a1) const
{ {
void* f = (void*)func; void *f = (void *)func;
#ifdef __x86_64__ #ifdef __x86_64__
XFASTCALL1; XFASTCALL1;
#else #else
XFASTCALL1; XFASTCALL1;
#endif #endif
} }
template< typename T > __fi template <typename T>
void operator()( T* func, u32 a1, u32 a2) const __fi void operator()(T *func, u32 a1, u32 a2) const
{ {
void* f = (void*)func; void *f = (void *)func;
#ifdef __x86_64__ #ifdef __x86_64__
XFASTCALL2; XFASTCALL2;
#else #else
XFASTCALL2; XFASTCALL2;
#endif #endif
} }
template< typename T > __fi template <typename T>
void operator()( T* func, u32 a1) const __fi void operator()(T *func, u32 a1) const
{ {
void* f = (void*)func; void *f = (void *)func;
#ifdef __x86_64__ #ifdef __x86_64__
XFASTCALL1; XFASTCALL1;
#else #else
XFASTCALL1; XFASTCALL1;
#endif #endif
} }
void operator()(const xIndirect32& f, const xRegisterLong& a1 = xEmptyReg, const xRegisterLong& a2 = xEmptyReg) const void operator()(const xIndirect32 &f, const xRegisterLong &a1 = xEmptyReg, const xRegisterLong &a2 = xEmptyReg) const
{ {
#ifdef __x86_64__ #ifdef __x86_64__
if (a1.IsEmpty()) { if (a1.IsEmpty()) {
XFASTCALL; XFASTCALL;
} else if (a2.IsEmpty()) { } else if (a2.IsEmpty()) {
XFASTCALL1; XFASTCALL1;
} else { } else {
XFASTCALL2; XFASTCALL2;
} }
#else #else
if (a1.IsEmpty()) { if (a1.IsEmpty()) {
XFASTCALL; XFASTCALL;
} else if (a2.IsEmpty()) { } else if (a2.IsEmpty()) {
XFASTCALL1; XFASTCALL1;
} else { } else {
XFASTCALL2; XFASTCALL2;
} }
#endif #endif
} }
#undef XFASTCALL #undef XFASTCALL
#undef XFASTCALL1 #undef XFASTCALL1
#undef XFASTCALL2 #undef XFASTCALL2
}; };
} // End namespace x86Emitter } // End namespace x86Emitter

View File

@ -18,7 +18,8 @@
// Header: ix86_impl_movs.h -- covers mov, cmov, movsx/movzx, and SETcc (which shares // Header: ix86_impl_movs.h -- covers mov, cmov, movsx/movzx, and SETcc (which shares
// with cmov many similarities). // with cmov many similarities).
namespace x86Emitter { namespace x86Emitter
{
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// MovImplAll // MovImplAll
@ -27,13 +28,13 @@ namespace x86Emitter {
// //
struct xImpl_Mov struct xImpl_Mov
{ {
xImpl_Mov() {} // Satisfy GCC's whims. xImpl_Mov() {} // Satisfy GCC's whims.
void operator()( const xRegisterInt& to, const xRegisterInt& from ) const; void operator()(const xRegisterInt &to, const xRegisterInt &from) const;
void operator()( const xIndirectVoid& dest, const xRegisterInt& from ) const; void operator()(const xIndirectVoid &dest, const xRegisterInt &from) const;
void operator()( const xRegisterInt& to, const xIndirectVoid& src ) const; void operator()(const xRegisterInt &to, const xIndirectVoid &src) const;
void operator()( const xIndirect64orLess& dest, int imm ) const; void operator()(const xIndirect64orLess &dest, int imm) const;
void operator()( const xRegisterInt& to, int imm, bool preserve_flags=false ) const; void operator()(const xRegisterInt &to, int imm, bool preserve_flags = false) const;
#if 0 #if 0
template< typename T > __noinline void operator()( const ModSibBase& to, const xImmReg<T>& immOrReg ) const template< typename T > __noinline void operator()( const ModSibBase& to, const xImmReg<T>& immOrReg ) const
@ -84,22 +85,22 @@ struct xImpl_Mov
struct xImpl_CMov struct xImpl_CMov
{ {
JccComparisonType ccType; JccComparisonType ccType;
void operator()( const xRegister16or32or64& to, const xRegister16or32or64& from ) const; void operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from) const;
void operator()( const xRegister16or32or64& to, const xIndirectVoid& sibsrc ) const; void operator()(const xRegister16or32or64 &to, const xIndirectVoid &sibsrc) const;
//void operator()( const xDirectOrIndirect32& to, const xDirectOrIndirect32& from ); //void operator()( const xDirectOrIndirect32& to, const xDirectOrIndirect32& from );
//void operator()( const xDirectOrIndirect16& to, const xDirectOrIndirect16& from ) const; //void operator()( const xDirectOrIndirect16& to, const xDirectOrIndirect16& from ) const;
}; };
struct xImpl_Set struct xImpl_Set
{ {
JccComparisonType ccType; JccComparisonType ccType;
void operator()( const xRegister8& to ) const; void operator()(const xRegister8 &to) const;
void operator()( const xIndirect8& dest ) const; void operator()(const xIndirect8 &dest) const;
//void operator()( const xDirectOrIndirect8& dest ) const; //void operator()( const xDirectOrIndirect8& dest ) const;
}; };
@ -110,16 +111,16 @@ struct xImpl_Set
// //
struct xImpl_MovExtend struct xImpl_MovExtend
{ {
bool SignExtend; bool SignExtend;
void operator()( const xRegister16or32or64& to, const xRegister8& from ) const; void operator()(const xRegister16or32or64 &to, const xRegister8 &from) const;
void operator()( const xRegister16or32or64& to, const xIndirect8& sibsrc ) const; void operator()(const xRegister16or32or64 &to, const xIndirect8 &sibsrc) const;
void operator()( const xRegister32or64& to, const xRegister16& from ) const; void operator()(const xRegister32or64 &to, const xRegister16 &from) const;
void operator()( const xRegister32or64& to, const xIndirect16& sibsrc ) const; void operator()(const xRegister32or64 &to, const xIndirect16 &sibsrc) const;
//void operator()( const xRegister32& to, const xDirectOrIndirect16& src ) const; //void operator()( const xRegister32& to, const xDirectOrIndirect16& src ) const;
//void operator()( const xRegister16or32& to, const xDirectOrIndirect8& src ) const; //void operator()( const xRegister16or32& to, const xDirectOrIndirect8& src ) const;
//void operator()( const xRegister16& to, const xDirectOrIndirect8& src ) const; //void operator()( const xRegister16& to, const xDirectOrIndirect8& src ) const;
}; };
} // End namespace x86Emitter } // End namespace x86Emitter

View File

@ -15,22 +15,23 @@
#pragma once #pragma once
namespace x86Emitter { namespace x86Emitter
{
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// _SimdShiftHelper // _SimdShiftHelper
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct _SimdShiftHelper struct _SimdShiftHelper
{ {
u8 Prefix; u8 Prefix;
u16 Opcode; u16 Opcode;
u16 OpcodeImm; u16 OpcodeImm;
u8 Modcode; u8 Modcode;
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const; void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const;
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const; void operator()(const xRegisterSSE &to, const xIndirectVoid &from) const;
void operator()( const xRegisterSSE& to, u8 imm8 ) const; void operator()(const xRegisterSSE &to, u8 imm8) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -41,70 +42,70 @@ struct _SimdShiftHelper
// //
struct xImplSimd_ShiftWithoutQ struct xImplSimd_ShiftWithoutQ
{ {
const _SimdShiftHelper W; const _SimdShiftHelper W;
const _SimdShiftHelper D; const _SimdShiftHelper D;
}; };
// Implements PSRL and PSLL // Implements PSRL and PSLL
// //
struct xImplSimd_Shift struct xImplSimd_Shift
{ {
const _SimdShiftHelper W; const _SimdShiftHelper W;
const _SimdShiftHelper D; const _SimdShiftHelper D;
const _SimdShiftHelper Q; const _SimdShiftHelper Q;
void DQ( const xRegisterSSE& to, u8 imm8 ) const; void DQ(const xRegisterSSE &to, u8 imm8) const;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
struct xImplSimd_AddSub struct xImplSimd_AddSub
{ {
const xImplSimd_DestRegEither B; const xImplSimd_DestRegEither B;
const xImplSimd_DestRegEither W; const xImplSimd_DestRegEither W;
const xImplSimd_DestRegEither D; const xImplSimd_DestRegEither D;
const xImplSimd_DestRegEither Q; const xImplSimd_DestRegEither Q;
// Add/Sub packed signed byte [8bit] integers from src into dest, and saturate the results. // Add/Sub packed signed byte [8bit] integers from src into dest, and saturate the results.
const xImplSimd_DestRegEither SB; const xImplSimd_DestRegEither SB;
// Add/Sub packed signed word [16bit] integers from src into dest, and saturate the results. // Add/Sub packed signed word [16bit] integers from src into dest, and saturate the results.
const xImplSimd_DestRegEither SW; const xImplSimd_DestRegEither SW;
// Add/Sub packed unsigned byte [8bit] integers from src into dest, and saturate the results. // Add/Sub packed unsigned byte [8bit] integers from src into dest, and saturate the results.
const xImplSimd_DestRegEither USB; const xImplSimd_DestRegEither USB;
// Add/Sub packed unsigned word [16bit] integers from src into dest, and saturate the results. // Add/Sub packed unsigned word [16bit] integers from src into dest, and saturate the results.
const xImplSimd_DestRegEither USW; const xImplSimd_DestRegEither USW;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
struct xImplSimd_PMul struct xImplSimd_PMul
{ {
const xImplSimd_DestRegEither LW; const xImplSimd_DestRegEither LW;
const xImplSimd_DestRegEither HW; const xImplSimd_DestRegEither HW;
const xImplSimd_DestRegEither HUW; const xImplSimd_DestRegEither HUW;
const xImplSimd_DestRegEither UDQ; const xImplSimd_DestRegEither UDQ;
// [SSE-3] PMULHRSW multiplies vertically each signed 16-bit integer from dest with the // [SSE-3] PMULHRSW multiplies vertically each signed 16-bit integer from dest with the
// corresponding signed 16-bit integer of source, producing intermediate signed 32-bit // corresponding signed 16-bit integer of source, producing intermediate signed 32-bit
// integers. Each intermediate 32-bit integer is truncated to the 18 most significant // integers. Each intermediate 32-bit integer is truncated to the 18 most significant
// bits. Rounding is always performed by adding 1 to the least significant bit of the // bits. Rounding is always performed by adding 1 to the least significant bit of the
// 18-bit intermediate result. The final result is obtained by selecting the 16 bits // 18-bit intermediate result. The final result is obtained by selecting the 16 bits
// immediately to the right of the most significant bit of each 18-bit intermediate // immediately to the right of the most significant bit of each 18-bit intermediate
// result and packed to the destination operand. // result and packed to the destination operand.
// //
// Both operands can be MMX or XMM registers. Source can be register or memory. // Both operands can be MMX or XMM registers. Source can be register or memory.
// //
const xImplSimd_DestRegEither HRSW; const xImplSimd_DestRegEither HRSW;
// [SSE-4.1] Multiply the packed dword signed integers in dest with src, and store // [SSE-4.1] Multiply the packed dword signed integers in dest with src, and store
// the low 32 bits of each product in xmm1. // the low 32 bits of each product in xmm1.
const xImplSimd_DestRegSSE LD; const xImplSimd_DestRegSSE LD;
// [SSE-4.1] Multiply the packed signed dword integers in dest with src. // [SSE-4.1] Multiply the packed signed dword integers in dest with src.
const xImplSimd_DestRegSSE DQ; const xImplSimd_DestRegSSE DQ;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -112,8 +113,8 @@ struct xImplSimd_PMul
// //
struct xImplSimd_rSqrt struct xImplSimd_rSqrt
{ {
const xImplSimd_DestRegSSE PS; const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE SS; const xImplSimd_DestRegSSE SS;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -121,17 +122,17 @@ struct xImplSimd_rSqrt
// //
struct xImplSimd_Sqrt struct xImplSimd_Sqrt
{ {
const xImplSimd_DestRegSSE PS; const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE SS; const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD; const xImplSimd_DestRegSSE SD;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
struct xImplSimd_AndNot struct xImplSimd_AndNot
{ {
const xImplSimd_DestRegSSE PS; const xImplSimd_DestRegSSE PS;
const xImplSimd_DestRegSSE PD; const xImplSimd_DestRegSSE PD;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -139,17 +140,17 @@ struct xImplSimd_AndNot
// //
struct xImplSimd_PAbsolute struct xImplSimd_PAbsolute
{ {
// [sSSE-3] Computes the absolute value of bytes in the src, and stores the result // [sSSE-3] Computes the absolute value of bytes in the src, and stores the result
// in dest, as UNSIGNED. // in dest, as UNSIGNED.
const xImplSimd_DestRegEither B; const xImplSimd_DestRegEither B;
// [sSSE-3] Computes the absolute value of word in the src, and stores the result // [sSSE-3] Computes the absolute value of word in the src, and stores the result
// in dest, as UNSIGNED. // in dest, as UNSIGNED.
const xImplSimd_DestRegEither W; const xImplSimd_DestRegEither W;
// [sSSE-3] Computes the absolute value of doublewords in the src, and stores the // [sSSE-3] Computes the absolute value of doublewords in the src, and stores the
// result in dest, as UNSIGNED. // result in dest, as UNSIGNED.
const xImplSimd_DestRegEither D; const xImplSimd_DestRegEither D;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -158,27 +159,26 @@ struct xImplSimd_PAbsolute
// //
struct xImplSimd_PSign struct xImplSimd_PSign
{ {
// [sSSE-3] negates each byte element of dest if the signed integer value of the // [sSSE-3] negates each byte element of dest if the signed integer value of the
// corresponding data element in src is less than zero. If the signed integer value // corresponding data element in src is less than zero. If the signed integer value
// of a data element in src is positive, the corresponding data element in dest is // of a data element in src is positive, the corresponding data element in dest is
// unchanged. If a data element in src is zero, the corresponding data element in // unchanged. If a data element in src is zero, the corresponding data element in
// dest is set to zero. // dest is set to zero.
const xImplSimd_DestRegEither B; const xImplSimd_DestRegEither B;
// [sSSE-3] negates each word element of dest if the signed integer value of the // [sSSE-3] negates each word element of dest if the signed integer value of the
// corresponding data element in src is less than zero. If the signed integer value // corresponding data element in src is less than zero. If the signed integer value
// of a data element in src is positive, the corresponding data element in dest is // of a data element in src is positive, the corresponding data element in dest is
// unchanged. If a data element in src is zero, the corresponding data element in // unchanged. If a data element in src is zero, the corresponding data element in
// dest is set to zero. // dest is set to zero.
const xImplSimd_DestRegEither W; const xImplSimd_DestRegEither W;
// [sSSE-3] negates each doubleword element of dest if the signed integer value
// of the corresponding data element in src is less than zero. If the signed integer
// value of a data element in src is positive, the corresponding data element in dest
// is unchanged. If a data element in src is zero, the corresponding data element in
// dest is set to zero.
const xImplSimd_DestRegEither D;
// [sSSE-3] negates each doubleword element of dest if the signed integer value
// of the corresponding data element in src is less than zero. If the signed integer
// value of a data element in src is positive, the corresponding data element in dest
// is unchanged. If a data element in src is zero, the corresponding data element in
// dest is set to zero.
const xImplSimd_DestRegEither D;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -186,31 +186,31 @@ struct xImplSimd_PSign
// //
struct xImplSimd_PMultAdd struct xImplSimd_PMultAdd
{ {
// Multiplies the individual signed words of dest by the corresponding signed words // Multiplies the individual signed words of dest by the corresponding signed words
// of src, producing temporary signed, doubleword results. The adjacent doubleword // of src, producing temporary signed, doubleword results. The adjacent doubleword
// results are then summed and stored in the destination operand. // results are then summed and stored in the destination operand.
// //
// DEST[31:0] = ( DEST[15:0] * SRC[15:0]) + (DEST[31:16] * SRC[31:16] ); // DEST[31:0] = ( DEST[15:0] * SRC[15:0]) + (DEST[31:16] * SRC[31:16] );
// DEST[63:32] = ( DEST[47:32] * SRC[47:32]) + (DEST[63:48] * SRC[63:48] ); // DEST[63:32] = ( DEST[47:32] * SRC[47:32]) + (DEST[63:48] * SRC[63:48] );
// [.. repeat in the case of XMM src/dest operands ..] // [.. repeat in the case of XMM src/dest operands ..]
// //
const xImplSimd_DestRegEither WD; const xImplSimd_DestRegEither WD;
// [sSSE-3] multiplies vertically each unsigned byte of dest with the corresponding // [sSSE-3] multiplies vertically each unsigned byte of dest with the corresponding
// signed byte of src, producing intermediate signed 16-bit integers. Each adjacent // signed byte of src, producing intermediate signed 16-bit integers. Each adjacent
// pair of signed words is added and the saturated result is packed to dest. // pair of signed words is added and the saturated result is packed to dest.
// For example, the lowest-order bytes (bits 7-0) in src and dest are multiplied // For example, the lowest-order bytes (bits 7-0) in src and dest are multiplied
// and the intermediate signed word result is added with the corresponding // and the intermediate signed word result is added with the corresponding
// intermediate result from the 2nd lowest-order bytes (bits 15-8) of the operands; // intermediate result from the 2nd lowest-order bytes (bits 15-8) of the operands;
// the sign-saturated result is stored in the lowest word of dest (bits 15-0). // the sign-saturated result is stored in the lowest word of dest (bits 15-0).
// The same operation is performed on the other pairs of adjacent bytes. // The same operation is performed on the other pairs of adjacent bytes.
// //
// In Coder Speak: // In Coder Speak:
// DEST[15-0] = SaturateToSignedWord( SRC[15-8] * DEST[15-8] + SRC[7-0] * DEST[7-0] ); // DEST[15-0] = SaturateToSignedWord( SRC[15-8] * DEST[15-8] + SRC[7-0] * DEST[7-0] );
// DEST[31-16] = SaturateToSignedWord( SRC[31-24] * DEST[31-24] + SRC[23-16] * DEST[23-16] ); // DEST[31-16] = SaturateToSignedWord( SRC[31-24] * DEST[31-24] + SRC[23-16] * DEST[23-16] );
// [.. repeat for each 16 bits up to 64 (mmx) or 128 (xmm) ..] // [.. repeat for each 16 bits up to 64 (mmx) or 128 (xmm) ..]
// //
const xImplSimd_DestRegEither UBSW; const xImplSimd_DestRegEither UBSW;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -218,21 +218,21 @@ struct xImplSimd_PMultAdd
// //
struct xImplSimd_HorizAdd struct xImplSimd_HorizAdd
{ {
// [SSE-3] Horizontal Add of Packed Data. A three step process: // [SSE-3] Horizontal Add of Packed Data. A three step process:
// * Adds the single-precision floating-point values in the first and second dwords of // * Adds the single-precision floating-point values in the first and second dwords of
// dest and stores the result in the first dword of dest. // dest and stores the result in the first dword of dest.
// * Adds single-precision floating-point values in the third and fourth dword of dest // * Adds single-precision floating-point values in the third and fourth dword of dest
// stores the result in the second dword of dest. // stores the result in the second dword of dest.
// * Adds single-precision floating-point values in the first and second dword of *src* // * Adds single-precision floating-point values in the first and second dword of *src*
// and stores the result in the third dword of dest. // and stores the result in the third dword of dest.
const xImplSimd_DestRegSSE PS; const xImplSimd_DestRegSSE PS;
// [SSE-3] Horizontal Add of Packed Data. A two step process: // [SSE-3] Horizontal Add of Packed Data. A two step process:
// * Adds the double-precision floating-point values in the high and low quadwords of // * Adds the double-precision floating-point values in the high and low quadwords of
// dest and stores the result in the low quadword of dest. // dest and stores the result in the low quadword of dest.
// * Adds the double-precision floating-point values in the high and low quadwords of // * Adds the double-precision floating-point values in the high and low quadwords of
// *src* stores the result in the high quadword of dest. // *src* stores the result in the high quadword of dest.
const xImplSimd_DestRegSSE PD; const xImplSimd_DestRegSSE PD;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -240,23 +240,23 @@ struct xImplSimd_HorizAdd
// //
struct xImplSimd_DotProduct struct xImplSimd_DotProduct
{ {
// [SSE-4.1] Conditionally multiplies the packed single precision floating-point // [SSE-4.1] Conditionally multiplies the packed single precision floating-point
// values in dest with the packed single-precision floats in src depending on a // values in dest with the packed single-precision floats in src depending on a
// mask extracted from the high 4 bits of the immediate byte. If a condition mask // mask extracted from the high 4 bits of the immediate byte. If a condition mask
// bit in Imm8[7:4] is zero, the corresponding multiplication is replaced by a value // bit in Imm8[7:4] is zero, the corresponding multiplication is replaced by a value
// of 0.0. The four resulting single-precision values are summed into an inter- // of 0.0. The four resulting single-precision values are summed into an inter-
// mediate result. // mediate result.
// //
// The intermediate result is conditionally broadcasted to the destination using a // The intermediate result is conditionally broadcasted to the destination using a
// broadcast mask specified by bits [3:0] of the immediate byte. If a broadcast // broadcast mask specified by bits [3:0] of the immediate byte. If a broadcast
// mask bit is 1, the intermediate result is copied to the corresponding dword // mask bit is 1, the intermediate result is copied to the corresponding dword
// element in dest. If a broadcast mask bit is zero, the corresponding element in // element in dest. If a broadcast mask bit is zero, the corresponding element in
// the destination is set to zero. // the destination is set to zero.
// //
xImplSimd_DestRegImmSSE PS; xImplSimd_DestRegImmSSE PS;
// [SSE-4.1] // [SSE-4.1]
xImplSimd_DestRegImmSSE PD; xImplSimd_DestRegImmSSE PD;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -264,54 +264,53 @@ struct xImplSimd_DotProduct
// (SSE4.1 only!) // (SSE4.1 only!)
struct xImplSimd_Round struct xImplSimd_Round
{ {
// [SSE-4.1] Rounds the 4 packed single-precision src values and stores them in dest. // [SSE-4.1] Rounds the 4 packed single-precision src values and stores them in dest.
// //
// Imm8 specifies control fields for the rounding operation: // Imm8 specifies control fields for the rounding operation:
// Bit 3 - processor behavior for a precision exception (0: normal, 1: inexact) // Bit 3 - processor behavior for a precision exception (0: normal, 1: inexact)
// Bit 2 - If enabled, use MXCSR.RC, else use RC specified in bits 1:0 of this Imm8. // Bit 2 - If enabled, use MXCSR.RC, else use RC specified in bits 1:0 of this Imm8.
// Bits 1:0 - Specifies a rounding mode for this instruction only. // Bits 1:0 - Specifies a rounding mode for this instruction only.
// //
// Rounding Mode Reference: // Rounding Mode Reference:
// 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate. // 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate.
// //
const xImplSimd_DestRegImmSSE PS; const xImplSimd_DestRegImmSSE PS;
// [SSE-4.1] Rounds the 2 packed double-precision src values and stores them in dest. // [SSE-4.1] Rounds the 2 packed double-precision src values and stores them in dest.
// //
// Imm8 specifies control fields for the rounding operation: // Imm8 specifies control fields for the rounding operation:
// Bit 3 - processor behavior for a precision exception (0: normal, 1: inexact) // Bit 3 - processor behavior for a precision exception (0: normal, 1: inexact)
// Bit 2 - If enabled, use MXCSR.RC, else use RC specified in bits 1:0 of this Imm8. // Bit 2 - If enabled, use MXCSR.RC, else use RC specified in bits 1:0 of this Imm8.
// Bits 1:0 - Specifies a rounding mode for this instruction only. // Bits 1:0 - Specifies a rounding mode for this instruction only.
// //
// Rounding Mode Reference: // Rounding Mode Reference:
// 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate. // 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate.
// //
const xImplSimd_DestRegImmSSE PD; const xImplSimd_DestRegImmSSE PD;
// [SSE-4.1] Rounds the single-precision src value and stores in dest. // [SSE-4.1] Rounds the single-precision src value and stores in dest.
// //
// Imm8 specifies control fields for the rounding operation: // Imm8 specifies control fields for the rounding operation:
// Bit 3 - processor behavior for a precision exception (0: normal, 1: inexact) // Bit 3 - processor behavior for a precision exception (0: normal, 1: inexact)
// Bit 2 - If enabled, use MXCSR.RC, else use RC specified in bits 1:0 of this Imm8. // Bit 2 - If enabled, use MXCSR.RC, else use RC specified in bits 1:0 of this Imm8.
// Bits 1:0 - Specifies a rounding mode for this instruction only. // Bits 1:0 - Specifies a rounding mode for this instruction only.
// //
// Rounding Mode Reference: // Rounding Mode Reference:
// 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate. // 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate.
// //
const xImplSimd_DestRegImmSSE SS; const xImplSimd_DestRegImmSSE SS;
// [SSE-4.1] Rounds the double-precision src value and stores in dest. // [SSE-4.1] Rounds the double-precision src value and stores in dest.
// //
// Imm8 specifies control fields for the rounding operation: // Imm8 specifies control fields for the rounding operation:
// Bit 3 - processor behavior for a precision exception (0: normal, 1: inexact) // Bit 3 - processor behavior for a precision exception (0: normal, 1: inexact)
// Bit 2 - If enabled, use MXCSR.RC, else use RC specified in bits 1:0 of this Imm8. // Bit 2 - If enabled, use MXCSR.RC, else use RC specified in bits 1:0 of this Imm8.
// Bits 1:0 - Specifies a rounding mode for this instruction only. // Bits 1:0 - Specifies a rounding mode for this instruction only.
// //
// Rounding Mode Reference: // Rounding Mode Reference:
// 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate. // 0 - Nearest, 1 - Negative Infinity, 2 - Positive infinity, 3 - Truncate.
// //
const xImplSimd_DestRegImmSSE SD; const xImplSimd_DestRegImmSSE SD;
}; };
} // End namespace x86Emitter } // End namespace x86Emitter

View File

@ -15,33 +15,34 @@
#pragma once #pragma once
namespace x86Emitter { namespace x86Emitter
{
struct xImplSimd_MinMax struct xImplSimd_MinMax
{ {
const xImplSimd_DestRegSSE PS; // packed single precision const xImplSimd_DestRegSSE PS; // packed single precision
const xImplSimd_DestRegSSE PD; // packed double precision const xImplSimd_DestRegSSE PD; // packed double precision
const xImplSimd_DestRegSSE SS; // scalar single precision const xImplSimd_DestRegSSE SS; // scalar single precision
const xImplSimd_DestRegSSE SD; // scalar double precision const xImplSimd_DestRegSSE SD; // scalar double precision
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
struct xImplSimd_Compare struct xImplSimd_Compare
{ {
SSE2_ComparisonType CType; SSE2_ComparisonType CType;
void PS( const xRegisterSSE& to, const xRegisterSSE& from ) const; void PS(const xRegisterSSE &to, const xRegisterSSE &from) const;
void PS( const xRegisterSSE& to, const xIndirectVoid& from ) const; void PS(const xRegisterSSE &to, const xIndirectVoid &from) const;
void PD( const xRegisterSSE& to, const xRegisterSSE& from ) const; void PD(const xRegisterSSE &to, const xRegisterSSE &from) const;
void PD( const xRegisterSSE& to, const xIndirectVoid& from ) const; void PD(const xRegisterSSE &to, const xIndirectVoid &from) const;
void SS( const xRegisterSSE& to, const xRegisterSSE& from ) const; void SS(const xRegisterSSE &to, const xRegisterSSE &from) const;
void SS( const xRegisterSSE& to, const xIndirectVoid& from ) const; void SS(const xRegisterSSE &to, const xIndirectVoid &from) const;
void SD( const xRegisterSSE& to, const xRegisterSSE& from ) const; void SD(const xRegisterSSE &to, const xRegisterSSE &from) const;
void SD( const xRegisterSSE& to, const xIndirectVoid& from ) const; void SD(const xRegisterSSE &to, const xIndirectVoid &from) const;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
@ -49,8 +50,8 @@ struct xImplSimd_Compare
// //
struct xImplSimd_COMI struct xImplSimd_COMI
{ {
const xImplSimd_DestRegSSE SS; const xImplSimd_DestRegSSE SS;
const xImplSimd_DestRegSSE SD; const xImplSimd_DestRegSSE SD;
}; };
@ -59,65 +60,64 @@ struct xImplSimd_COMI
struct xImplSimd_PCompare struct xImplSimd_PCompare
{ {
public: public:
// Compare packed bytes for equality. // Compare packed bytes for equality.
// If a data element in dest is equal to the corresponding date element src, the // If a data element in dest is equal to the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s. // corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither EQB; const xImplSimd_DestRegEither EQB;
// Compare packed words for equality. // Compare packed words for equality.
// If a data element in dest is equal to the corresponding date element src, the // If a data element in dest is equal to the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s. // corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither EQW; const xImplSimd_DestRegEither EQW;
// Compare packed doublewords [32-bits] for equality. // Compare packed doublewords [32-bits] for equality.
// If a data element in dest is equal to the corresponding date element src, the // If a data element in dest is equal to the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s. // corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither EQD; const xImplSimd_DestRegEither EQD;
// Compare packed signed bytes for greater than. // Compare packed signed bytes for greater than.
// If a data element in dest is greater than the corresponding date element src, the // If a data element in dest is greater than the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s. // corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither GTB; const xImplSimd_DestRegEither GTB;
// Compare packed signed words for greater than. // Compare packed signed words for greater than.
// If a data element in dest is greater than the corresponding date element src, the // If a data element in dest is greater than the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s. // corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither GTW; const xImplSimd_DestRegEither GTW;
// Compare packed signed doublewords [32-bits] for greater than. // Compare packed signed doublewords [32-bits] for greater than.
// If a data element in dest is greater than the corresponding date element src, the // If a data element in dest is greater than the corresponding date element src, the
// corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s. // corresponding data element in dest is set to all 1s; otherwise, it is set to all 0s.
const xImplSimd_DestRegEither GTD; const xImplSimd_DestRegEither GTD;
}; };
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// //
struct xImplSimd_PMinMax struct xImplSimd_PMinMax
{ {
// Compare packed unsigned byte integers in dest to src and store packed min/max // Compare packed unsigned byte integers in dest to src and store packed min/max
// values in dest. // values in dest.
const xImplSimd_DestRegEither UB; const xImplSimd_DestRegEither UB;
// Compare packed signed word integers in dest to src and store packed min/max // Compare packed signed word integers in dest to src and store packed min/max
// values in dest. // values in dest.
const xImplSimd_DestRegEither SW; const xImplSimd_DestRegEither SW;
// [SSE-4.1] Compare packed signed byte integers in dest to src and store // [SSE-4.1] Compare packed signed byte integers in dest to src and store
// packed min/max values in dest. (SSE operands only) // packed min/max values in dest. (SSE operands only)
const xImplSimd_DestRegSSE SB; const xImplSimd_DestRegSSE SB;
// [SSE-4.1] Compare packed signed doubleword integers in dest to src and store // [SSE-4.1] Compare packed signed doubleword integers in dest to src and store
// packed min/max values in dest. (SSE operands only) // packed min/max values in dest. (SSE operands only)
const xImplSimd_DestRegSSE SD; const xImplSimd_DestRegSSE SD;
// [SSE-4.1] Compare packed unsigned word integers in dest to src and store // [SSE-4.1] Compare packed unsigned word integers in dest to src and store
// packed min/max values in dest. (SSE operands only) // packed min/max values in dest. (SSE operands only)
const xImplSimd_DestRegSSE UW; const xImplSimd_DestRegSSE UW;
// [SSE-4.1] Compare packed unsigned doubleword integers in dest to src and store // [SSE-4.1] Compare packed unsigned doubleword integers in dest to src and store
// packed min/max values in dest. (SSE operands only) // packed min/max values in dest. (SSE operands only)
const xImplSimd_DestRegSSE UD; const xImplSimd_DestRegSSE UD;
}; };
} // end namespace x86Emitter } // end namespace x86Emitter

View File

@ -15,7 +15,8 @@
#pragma once #pragma once
namespace x86Emitter { namespace x86Emitter
{
// ===================================================================================================== // =====================================================================================================
// xImpl_SIMD Types (template free!) // xImpl_SIMD Types (template free!)
@ -27,11 +28,11 @@ namespace x86Emitter {
// //
struct xImplSimd_DestRegSSE struct xImplSimd_DestRegSSE
{ {
u8 Prefix; u8 Prefix;
u16 Opcode; u16 Opcode;
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const; void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const;
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const; void operator()(const xRegisterSSE &to, const xIndirectVoid &from) const;
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -40,20 +41,20 @@ struct xImplSimd_DestRegSSE
// //
struct xImplSimd_DestRegImmSSE struct xImplSimd_DestRegImmSSE
{ {
u8 Prefix; u8 Prefix;
u16 Opcode; u16 Opcode;
void operator()( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm ) const; void operator()(const xRegisterSSE &to, const xRegisterSSE &from, u8 imm) const;
void operator()( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm ) const; void operator()(const xRegisterSSE &to, const xIndirectVoid &from, u8 imm) const;
}; };
struct xImplSimd_DestSSE_CmpImm struct xImplSimd_DestSSE_CmpImm
{ {
u8 Prefix; u8 Prefix;
u16 Opcode; u16 Opcode;
void operator()( const xRegisterSSE& to, const xRegisterSSE& from, SSE2_ComparisonType imm ) const; void operator()(const xRegisterSSE &to, const xRegisterSSE &from, SSE2_ComparisonType imm) const;
void operator()( const xRegisterSSE& to, const xIndirectVoid& from, SSE2_ComparisonType imm ) const; void operator()(const xRegisterSSE &to, const xIndirectVoid &from, SSE2_ComparisonType imm) const;
}; };
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -62,12 +63,11 @@ struct xImplSimd_DestSSE_CmpImm
// //
struct xImplSimd_DestRegEither struct xImplSimd_DestRegEither
{ {
u8 Prefix; u8 Prefix;
u16 Opcode; u16 Opcode;
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const; void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const;
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const; void operator()(const xRegisterSSE &to, const xIndirectVoid &from) const;
}; };
} // end namespace x86Emitter } // end namespace x86Emitter

View File

@ -15,7 +15,8 @@
#pragma once #pragma once
namespace x86Emitter { namespace x86Emitter
{
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImplSimd_MovHL // xImplSimd_MovHL
@ -25,13 +26,13 @@ namespace x86Emitter {
// //
struct xImplSimd_MovHL struct xImplSimd_MovHL
{ {
u16 Opcode; u16 Opcode;
void PS( const xRegisterSSE& to, const xIndirectVoid& from ) const; void PS(const xRegisterSSE &to, const xIndirectVoid &from) const;
void PS( const xIndirectVoid& to, const xRegisterSSE& from ) const; void PS(const xIndirectVoid &to, const xRegisterSSE &from) const;
void PD( const xRegisterSSE& to, const xIndirectVoid& from ) const; void PD(const xRegisterSSE &to, const xIndirectVoid &from) const;
void PD( const xIndirectVoid& to, const xRegisterSSE& from ) const; void PD(const xIndirectVoid &to, const xRegisterSSE &from) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -42,10 +43,10 @@ struct xImplSimd_MovHL
// //
struct xImplSimd_MovHL_RtoR struct xImplSimd_MovHL_RtoR
{ {
u16 Opcode; u16 Opcode;
void PS( const xRegisterSSE& to, const xRegisterSSE& from ) const; void PS(const xRegisterSSE &to, const xRegisterSSE &from) const;
void PD( const xRegisterSSE& to, const xRegisterSSE& from ) const; void PD(const xRegisterSSE &to, const xRegisterSSE &from) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -59,12 +60,12 @@ struct xImplSimd_MovHL_RtoR
// //
struct xImplSimd_MoveSSE struct xImplSimd_MoveSSE
{ {
u8 Prefix; u8 Prefix;
bool isAligned; bool isAligned;
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const; void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const;
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const; void operator()(const xRegisterSSE &to, const xIndirectVoid &from) const;
void operator()( const xIndirectVoid& to, const xRegisterSSE& from ) const; void operator()(const xIndirectVoid &to, const xRegisterSSE &from) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -78,12 +79,12 @@ struct xImplSimd_MoveSSE
struct xImplSimd_MoveDQ struct xImplSimd_MoveDQ
{ {
u8 Prefix; u8 Prefix;
bool isAligned; bool isAligned;
void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const; void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const;
void operator()( const xRegisterSSE& to, const xIndirectVoid& from ) const; void operator()(const xRegisterSSE &to, const xIndirectVoid &from) const;
void operator()( const xIndirectVoid& to, const xRegisterSSE& from ) const; void operator()(const xIndirectVoid &to, const xRegisterSSE &from) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -93,41 +94,41 @@ struct xImplSimd_MoveDQ
// //
struct xImplSimd_Blend struct xImplSimd_Blend
{ {
// [SSE-4.1] Conditionally copies dword values from src to dest, depending on the // [SSE-4.1] Conditionally copies dword values from src to dest, depending on the
// mask bits in the immediate operand (bits [3:0]). Each mask bit corresponds to a // mask bits in the immediate operand (bits [3:0]). Each mask bit corresponds to a
// dword element in a 128-bit operand. // dword element in a 128-bit operand.
// //
// If a mask bit is 1, then the corresponding dword in the source operand is copied // If a mask bit is 1, then the corresponding dword in the source operand is copied
// to dest, else the dword element in dest is left unchanged. // to dest, else the dword element in dest is left unchanged.
// //
xImplSimd_DestRegImmSSE PS; xImplSimd_DestRegImmSSE PS;
// [SSE-4.1] Conditionally copies quadword values from src to dest, depending on the // [SSE-4.1] Conditionally copies quadword values from src to dest, depending on the
// mask bits in the immediate operand (bits [1:0]). Each mask bit corresponds to a // mask bits in the immediate operand (bits [1:0]). Each mask bit corresponds to a
// quadword element in a 128-bit operand. // quadword element in a 128-bit operand.
// //
// If a mask bit is 1, then the corresponding dword in the source operand is copied // If a mask bit is 1, then the corresponding dword in the source operand is copied
// to dest, else the dword element in dest is left unchanged. // to dest, else the dword element in dest is left unchanged.
// //
xImplSimd_DestRegImmSSE PD; xImplSimd_DestRegImmSSE PD;
// [SSE-4.1] Conditionally copies dword values from src to dest, depending on the // [SSE-4.1] Conditionally copies dword values from src to dest, depending on the
// mask (bits [3:0]) in XMM0 (yes, the fixed register). Each mask bit corresponds // mask (bits [3:0]) in XMM0 (yes, the fixed register). Each mask bit corresponds
// to a dword element in the 128-bit operand. // to a dword element in the 128-bit operand.
// //
// If a mask bit is 1, then the corresponding dword in the source operand is copied // If a mask bit is 1, then the corresponding dword in the source operand is copied
// to dest, else the dword element in dest is left unchanged. // to dest, else the dword element in dest is left unchanged.
// //
xImplSimd_DestRegSSE VPS; xImplSimd_DestRegSSE VPS;
// [SSE-4.1] Conditionally copies quadword values from src to dest, depending on the // [SSE-4.1] Conditionally copies quadword values from src to dest, depending on the
// mask (bits [1:0]) in XMM0 (yes, the fixed register). Each mask bit corresponds // mask (bits [1:0]) in XMM0 (yes, the fixed register). Each mask bit corresponds
// to a quadword element in the 128-bit operand. // to a quadword element in the 128-bit operand.
// //
// If a mask bit is 1, then the corresponding dword in the source operand is copied // If a mask bit is 1, then the corresponding dword in the source operand is copied
// to dest, else the dword element in dest is left unchanged. // to dest, else the dword element in dest is left unchanged.
// //
xImplSimd_DestRegSSE VPD; xImplSimd_DestRegSSE VPD;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -137,38 +138,36 @@ struct xImplSimd_Blend
// //
struct xImplSimd_PMove struct xImplSimd_PMove
{ {
u16 OpcodeBase; u16 OpcodeBase;
// [SSE-4.1] Zero/Sign-extend the low byte values in src into word integers // [SSE-4.1] Zero/Sign-extend the low byte values in src into word integers
// and store them in dest. // and store them in dest.
void BW( const xRegisterSSE& to, const xRegisterSSE& from ) const; void BW(const xRegisterSSE &to, const xRegisterSSE &from) const;
void BW( const xRegisterSSE& to, const xIndirect64& from ) const; void BW(const xRegisterSSE &to, const xIndirect64 &from) const;
// [SSE-4.1] Zero/Sign-extend the low byte values in src into dword integers // [SSE-4.1] Zero/Sign-extend the low byte values in src into dword integers
// and store them in dest. // and store them in dest.
void BD( const xRegisterSSE& to, const xRegisterSSE& from ) const; void BD(const xRegisterSSE &to, const xRegisterSSE &from) const;
void BD( const xRegisterSSE& to, const xIndirect32& from ) const; void BD(const xRegisterSSE &to, const xIndirect32 &from) const;
// [SSE-4.1] Zero/Sign-extend the low byte values in src into qword integers // [SSE-4.1] Zero/Sign-extend the low byte values in src into qword integers
// and store them in dest. // and store them in dest.
void BQ( const xRegisterSSE& to, const xRegisterSSE& from ) const; void BQ(const xRegisterSSE &to, const xRegisterSSE &from) const;
void BQ( const xRegisterSSE& to, const xIndirect16& from ) const; void BQ(const xRegisterSSE &to, const xIndirect16 &from) const;
// [SSE-4.1] Zero/Sign-extend the low word values in src into dword integers // [SSE-4.1] Zero/Sign-extend the low word values in src into dword integers
// and store them in dest. // and store them in dest.
void WD( const xRegisterSSE& to, const xRegisterSSE& from ) const; void WD(const xRegisterSSE &to, const xRegisterSSE &from) const;
void WD( const xRegisterSSE& to, const xIndirect64& from ) const; void WD(const xRegisterSSE &to, const xIndirect64 &from) const;
// [SSE-4.1] Zero/Sign-extend the low word values in src into qword integers // [SSE-4.1] Zero/Sign-extend the low word values in src into qword integers
// and store them in dest. // and store them in dest.
void WQ( const xRegisterSSE& to, const xRegisterSSE& from ) const; void WQ(const xRegisterSSE &to, const xRegisterSSE &from) const;
void WQ( const xRegisterSSE& to, const xIndirect32& from ) const; void WQ(const xRegisterSSE &to, const xIndirect32 &from) const;
// [SSE-4.1] Zero/Sign-extend the low dword values in src into qword integers // [SSE-4.1] Zero/Sign-extend the low dword values in src into qword integers
// and store them in dest. // and store them in dest.
void DQ( const xRegisterSSE& to, const xRegisterSSE& from ) const; void DQ(const xRegisterSSE &to, const xRegisterSSE &from) const;
void DQ( const xRegisterSSE& to, const xIndirect64& from ) const; void DQ(const xRegisterSSE &to, const xIndirect64 &from) const;
}; };
} }

View File

@ -15,20 +15,21 @@
#pragma once #pragma once
namespace x86Emitter { namespace x86Emitter
{
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImplSimd_Shuffle // xImplSimd_Shuffle
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct xImplSimd_Shuffle struct xImplSimd_Shuffle
{ {
inline void _selector_assertion_check( u8 selector ) const; inline void _selector_assertion_check(u8 selector) const;
void PS( const xRegisterSSE& to, const xRegisterSSE& from, u8 selector ) const; void PS(const xRegisterSSE &to, const xRegisterSSE &from, u8 selector) const;
void PS( const xRegisterSSE& to, const xIndirectVoid& from, u8 selector ) const; void PS(const xRegisterSSE &to, const xIndirectVoid &from, u8 selector) const;
void PD( const xRegisterSSE& to, const xRegisterSSE& from, u8 selector ) const; void PD(const xRegisterSSE &to, const xRegisterSSE &from, u8 selector) const;
void PD( const xRegisterSSE& to, const xIndirectVoid& from, u8 selector ) const; void PD(const xRegisterSSE &to, const xIndirectVoid &from, u8 selector) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -36,33 +37,33 @@ struct xImplSimd_Shuffle
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct xImplSimd_PShuffle struct xImplSimd_PShuffle
{ {
// Copies doublewords from src and inserts them into dest at dword locations selected // Copies doublewords from src and inserts them into dest at dword locations selected
// with the order operand (8 bit immediate). // with the order operand (8 bit immediate).
const xImplSimd_DestRegImmSSE D; const xImplSimd_DestRegImmSSE D;
// Copies words from the low quadword of src and inserts them into the low quadword // Copies words from the low quadword of src and inserts them into the low quadword
// of dest at word locations selected with the order operand (8 bit immediate). // of dest at word locations selected with the order operand (8 bit immediate).
// The high quadword of src is copied to the high quadword of dest. // The high quadword of src is copied to the high quadword of dest.
const xImplSimd_DestRegImmSSE LW; const xImplSimd_DestRegImmSSE LW;
// Copies words from the high quadword of src and inserts them into the high quadword // Copies words from the high quadword of src and inserts them into the high quadword
// of dest at word locations selected with the order operand (8 bit immediate). // of dest at word locations selected with the order operand (8 bit immediate).
// The low quadword of src is copied to the low quadword of dest. // The low quadword of src is copied to the low quadword of dest.
const xImplSimd_DestRegImmSSE HW; const xImplSimd_DestRegImmSSE HW;
// [sSSE-3] Performs in-place shuffles of bytes in dest according to the shuffle // [sSSE-3] Performs in-place shuffles of bytes in dest according to the shuffle
// control mask in src. If the most significant bit (bit[7]) of each byte of the // control mask in src. If the most significant bit (bit[7]) of each byte of the
// shuffle control mask is set, then constant zero is written in the result byte. // shuffle control mask is set, then constant zero is written in the result byte.
// Each byte in the shuffle control mask forms an index to permute the corresponding // Each byte in the shuffle control mask forms an index to permute the corresponding
// byte in dest. The value of each index is the least significant 4 bits (128-bit // byte in dest. The value of each index is the least significant 4 bits (128-bit
// operation) or 3 bits (64-bit operation) of the shuffle control byte. // operation) or 3 bits (64-bit operation) of the shuffle control byte.
// //
const xImplSimd_DestRegEither B; const xImplSimd_DestRegEither B;
// below is my test bed for a new system, free of subclasses. Was supposed to improve intellisense // below is my test bed for a new system, free of subclasses. Was supposed to improve intellisense
// but it doesn't (makes it worse). Will try again in MSVC 2010. --air // but it doesn't (makes it worse). Will try again in MSVC 2010. --air
#if 0 #if 0
// Copies words from src and inserts them into dest at word locations selected with // Copies words from src and inserts them into dest at word locations selected with
// the order operand (8 bit immediate). // the order operand (8 bit immediate).
@ -92,7 +93,7 @@ struct xImplSimd_PShuffle
// //
void B( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( 0x66, 0x0038 ); } void B( const xRegisterSSE& to, const xRegisterSSE& from ) const { OpWriteSSE( 0x66, 0x0038 ); }
void B( const xRegisterSSE& to, const xIndirectVoid& from ) const { OpWriteSSE( 0x66, 0x0038 ); } void B( const xRegisterSSE& to, const xIndirectVoid& from ) const { OpWriteSSE( 0x66, 0x0038 ); }
#endif #endif
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -100,23 +101,23 @@ struct xImplSimd_PShuffle
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct SimdImpl_PUnpack struct SimdImpl_PUnpack
{ {
// Unpack and interleave low-order bytes from src and dest into dest. // Unpack and interleave low-order bytes from src and dest into dest.
const xImplSimd_DestRegEither LBW; const xImplSimd_DestRegEither LBW;
// Unpack and interleave low-order words from src and dest into dest. // Unpack and interleave low-order words from src and dest into dest.
const xImplSimd_DestRegEither LWD; const xImplSimd_DestRegEither LWD;
// Unpack and interleave low-order doublewords from src and dest into dest. // Unpack and interleave low-order doublewords from src and dest into dest.
const xImplSimd_DestRegEither LDQ; const xImplSimd_DestRegEither LDQ;
// Unpack and interleave low-order quadwords from src and dest into dest. // Unpack and interleave low-order quadwords from src and dest into dest.
const xImplSimd_DestRegSSE LQDQ; const xImplSimd_DestRegSSE LQDQ;
// Unpack and interleave high-order bytes from src and dest into dest. // Unpack and interleave high-order bytes from src and dest into dest.
const xImplSimd_DestRegEither HBW; const xImplSimd_DestRegEither HBW;
// Unpack and interleave high-order words from src and dest into dest. // Unpack and interleave high-order words from src and dest into dest.
const xImplSimd_DestRegEither HWD; const xImplSimd_DestRegEither HWD;
// Unpack and interleave high-order doublewords from src and dest into dest. // Unpack and interleave high-order doublewords from src and dest into dest.
const xImplSimd_DestRegEither HDQ; const xImplSimd_DestRegEither HDQ;
// Unpack and interleave high-order quadwords from src and dest into dest. // Unpack and interleave high-order quadwords from src and dest into dest.
const xImplSimd_DestRegSSE HQDQ; const xImplSimd_DestRegSSE HQDQ;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -126,21 +127,21 @@ struct SimdImpl_PUnpack
// //
struct SimdImpl_Pack struct SimdImpl_Pack
{ {
// Converts packed signed word integers from src and dest into packed signed // Converts packed signed word integers from src and dest into packed signed
// byte integers in dest, using signed saturation. // byte integers in dest, using signed saturation.
const xImplSimd_DestRegEither SSWB; const xImplSimd_DestRegEither SSWB;
// Converts packed signed dword integers from src and dest into packed signed // Converts packed signed dword integers from src and dest into packed signed
// word integers in dest, using signed saturation. // word integers in dest, using signed saturation.
const xImplSimd_DestRegEither SSDW; const xImplSimd_DestRegEither SSDW;
// Converts packed unsigned word integers from src and dest into packed unsigned // Converts packed unsigned word integers from src and dest into packed unsigned
// byte integers in dest, using unsigned saturation. // byte integers in dest, using unsigned saturation.
const xImplSimd_DestRegEither USWB; const xImplSimd_DestRegEither USWB;
// [SSE-4.1] Converts packed unsigned dword integers from src and dest into packed // [SSE-4.1] Converts packed unsigned dword integers from src and dest into packed
// unsigned word integers in dest, using signed saturation. // unsigned word integers in dest, using signed saturation.
const xImplSimd_DestRegSSE USDW; const xImplSimd_DestRegSSE USDW;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -148,50 +149,50 @@ struct SimdImpl_Pack
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
struct xImplSimd_Unpack struct xImplSimd_Unpack
{ {
// Unpacks the high doubleword [single-precision] values from src and dest into // Unpacks the high doubleword [single-precision] values from src and dest into
// dest, such that the result of dest looks like this: // dest, such that the result of dest looks like this:
// dest[0] <- dest[2] // dest[0] <- dest[2]
// dest[1] <- src[2] // dest[1] <- src[2]
// dest[2] <- dest[3] // dest[2] <- dest[3]
// dest[3] <- src[3] // dest[3] <- src[3]
// //
const xImplSimd_DestRegSSE HPS; const xImplSimd_DestRegSSE HPS;
// Unpacks the high quadword [double-precision] values from src and dest into // Unpacks the high quadword [double-precision] values from src and dest into
// dest, such that the result of dest looks like this: // dest, such that the result of dest looks like this:
// dest.lo <- dest.hi // dest.lo <- dest.hi
// dest.hi <- src.hi // dest.hi <- src.hi
// //
const xImplSimd_DestRegSSE HPD; const xImplSimd_DestRegSSE HPD;
// Unpacks the low doubleword [single-precision] values from src and dest into // Unpacks the low doubleword [single-precision] values from src and dest into
// dest, such that the result of dest looks like this: // dest, such that the result of dest looks like this:
// dest[3] <- src[1] // dest[3] <- src[1]
// dest[2] <- dest[1] // dest[2] <- dest[1]
// dest[1] <- src[0] // dest[1] <- src[0]
// dest[0] <- dest[0] // dest[0] <- dest[0]
// //
const xImplSimd_DestRegSSE LPS; const xImplSimd_DestRegSSE LPS;
// Unpacks the low quadword [double-precision] values from src and dest into // Unpacks the low quadword [double-precision] values from src and dest into
// dest, effectively moving the low portion of src into the upper portion of dest. // dest, effectively moving the low portion of src into the upper portion of dest.
// The result of dest is loaded as such: // The result of dest is loaded as such:
// dest.hi <- src.lo // dest.hi <- src.lo
// dest.lo <- dest.lo [remains unchanged!] // dest.lo <- dest.lo [remains unchanged!]
// //
const xImplSimd_DestRegSSE LPD; const xImplSimd_DestRegSSE LPD;
}; };
struct xImplSimd_InsertExtractHelper struct xImplSimd_InsertExtractHelper
{ {
u16 Opcode; u16 Opcode;
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid) // [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
void operator()( const xRegisterSSE& to, const xRegister32& from, u8 imm8 ) const; void operator()(const xRegisterSSE &to, const xRegister32 &from, u8 imm8) const;
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid) // [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
void operator()( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm8 ) const; void operator()(const xRegisterSSE &to, const xIndirectVoid &from, u8 imm8) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -201,14 +202,14 @@ struct xImplSimd_InsertExtractHelper
// //
struct xImplSimd_PInsert struct xImplSimd_PInsert
{ {
void W( const xRegisterSSE& to, const xRegister32& from, u8 imm8 ) const; void W(const xRegisterSSE &to, const xRegister32 &from, u8 imm8) const;
void W( const xRegisterSSE& to, const xIndirectVoid& from, u8 imm8 ) const; void W(const xRegisterSSE &to, const xIndirectVoid &from, u8 imm8) const;
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid) // [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
xImplSimd_InsertExtractHelper B; xImplSimd_InsertExtractHelper B;
// [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid) // [SSE-4.1] Allowed with SSE registers only (MMX regs are invalid)
xImplSimd_InsertExtractHelper D; xImplSimd_InsertExtractHelper D;
}; };
@ -219,23 +220,22 @@ struct xImplSimd_PInsert
// //
struct SimdImpl_PExtract struct SimdImpl_PExtract
{ {
// Copies the word element specified by imm8 from src to dest. The upper bits // Copies the word element specified by imm8 from src to dest. The upper bits
// of dest are zero-extended (cleared). This can be used to extract any single packed // of dest are zero-extended (cleared). This can be used to extract any single packed
// word value from src into an x86 32 bit register. // word value from src into an x86 32 bit register.
// //
// [SSE-4.1] Note: Indirect memory forms of this instruction are an SSE-4.1 extension! // [SSE-4.1] Note: Indirect memory forms of this instruction are an SSE-4.1 extension!
// //
void W( const xRegister32& to, const xRegisterSSE& from, u8 imm8 ) const; void W(const xRegister32 &to, const xRegisterSSE &from, u8 imm8) const;
void W( const xIndirectVoid& dest, const xRegisterSSE& from, u8 imm8 ) const; void W(const xIndirectVoid &dest, const xRegisterSSE &from, u8 imm8) const;
// [SSE-4.1] Copies the byte element specified by imm8 from src to dest. The upper bits // [SSE-4.1] Copies the byte element specified by imm8 from src to dest. The upper bits
// of dest are zero-extended (cleared). This can be used to extract any single packed // of dest are zero-extended (cleared). This can be used to extract any single packed
// byte value from src into an x86 32 bit register. // byte value from src into an x86 32 bit register.
const xImplSimd_InsertExtractHelper B; const xImplSimd_InsertExtractHelper B;
// [SSE-4.1] Copies the dword element specified by imm8 from src to dest. This can be // [SSE-4.1] Copies the dword element specified by imm8 from src to dest. This can be
// used to extract any single packed dword value from src into an x86 32 bit register. // used to extract any single packed dword value from src into an x86 32 bit register.
const xImplSimd_InsertExtractHelper D; const xImplSimd_InsertExtractHelper D;
}; };
} }

View File

@ -22,17 +22,17 @@
// For implementing SSE-only logic operations that have xmmreg,xmmreg/rm forms only, // For implementing SSE-only logic operations that have xmmreg,xmmreg/rm forms only,
// like ANDPS/ANDPD // like ANDPS/ANDPD
// //
template< u8 Prefix, u16 Opcode > template <u8 Prefix, u16 Opcode>
class SimdImpl_DestRegSSE class SimdImpl_DestRegSSE
{ {
public: public:
__forceinline void operator()( const xRegisterSSE& to, const xRegisterSSE& from ) const { xOpWrite0F( Prefix, Opcode, to, from ); } __forceinline void operator()(const xRegisterSSE &to, const xRegisterSSE &from) const { xOpWrite0F(Prefix, Opcode, to, from); }
__forceinline void operator()( const xRegisterSSE& to, const ModSibBase& from ) const __forceinline void operator()(const xRegisterSSE &to, const ModSibBase &from) const
{ {
bool isReallyAligned = ((from.Displacement & 0x0f) == 0) && from.Index.IsEmpty() && from.Base.IsEmpty(); bool isReallyAligned = ((from.Displacement & 0x0f) == 0) && from.Index.IsEmpty() && from.Base.IsEmpty();
pxAssertDev( isReallyAligned, "Alignment check failed on SSE indirect load." ); pxAssertDev(isReallyAligned, "Alignment check failed on SSE indirect load.");
xOpWrite0F( Prefix, Opcode, to, from ); xOpWrite0F(Prefix, Opcode, to, from);
} }
SimdImpl_DestRegSSE() {} //GCWho? SimdImpl_DestRegSSE() {} //GCWho?
}; };

View File

@ -17,7 +17,8 @@
// Implementations found here: TEST + BTS/BT/BTC/BTR + BSF/BSR! (for lack of better location) // Implementations found here: TEST + BTS/BT/BTC/BTR + BSF/BSR! (for lack of better location)
namespace x86Emitter { namespace x86Emitter
{
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// xImpl_Test // xImpl_Test
@ -25,17 +26,16 @@ namespace x86Emitter {
// //
struct xImpl_Test struct xImpl_Test
{ {
void operator()( const xRegisterInt& to, const xRegisterInt& from ) const; void operator()(const xRegisterInt &to, const xRegisterInt &from) const;
void operator()( const xIndirect64orLess& dest, int imm ) const; void operator()(const xIndirect64orLess &dest, int imm) const;
void operator()( const xRegisterInt& to, int imm ) const; void operator()(const xRegisterInt &to, int imm) const;
}; };
enum G8Type enum G8Type {
{ G8Type_BT = 4,
G8Type_BT = 4, G8Type_BTS,
G8Type_BTS, G8Type_BTR,
G8Type_BTR, G8Type_BTC,
G8Type_BTC,
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -45,11 +45,11 @@ enum G8Type
// //
struct xImpl_BitScan struct xImpl_BitScan
{ {
// 0xbc [fwd] / 0xbd [rev] // 0xbc [fwd] / 0xbd [rev]
u16 Opcode; u16 Opcode;
void operator()( const xRegister16or32or64& to, const xRegister16or32or64& from ) const; void operator()(const xRegister16or32or64 &to, const xRegister16or32or64 &from) const;
void operator()( const xRegister16or32or64& to, const xIndirectVoid& sibsrc ) const; void operator()(const xRegister16or32or64 &to, const xIndirectVoid &sibsrc) const;
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -59,17 +59,16 @@ struct xImpl_BitScan
// //
struct xImpl_Group8 struct xImpl_Group8
{ {
G8Type InstType; G8Type InstType;
void operator()( const xRegister16or32or64& bitbase, const xRegister16or32or64& bitoffset ) const; void operator()(const xRegister16or32or64 &bitbase, const xRegister16or32or64 &bitoffset) const;
void operator()( const xRegister16or32or64& bitbase, u8 bitoffset ) const; void operator()(const xRegister16or32or64 &bitbase, u8 bitoffset) const;
void operator()( const xIndirectVoid& bitbase, const xRegister16or32or64& bitoffset ) const; void operator()(const xIndirectVoid &bitbase, const xRegister16or32or64 &bitoffset) const;
void operator()( const xIndirect64& bitbase, u8 bitoffset ) const; void operator()(const xIndirect64 &bitbase, u8 bitoffset) const;
void operator()( const xIndirect32& bitbase, u8 bitoffset ) const; void operator()(const xIndirect32 &bitbase, u8 bitoffset) const;
void operator()( const xIndirect16& bitbase, u8 bitoffset ) const; void operator()(const xIndirect16 &bitbase, u8 bitoffset) const;
}; };
} // End namespace x86Emitter } // End namespace x86Emitter

View File

@ -18,7 +18,8 @@
// This header file is intended to be the future home of xchg, cmpxchg, xadd, and // This header file is intended to be the future home of xchg, cmpxchg, xadd, and
// other threading-related exchange instructions. // other threading-related exchange instructions.
namespace x86Emitter { namespace x86Emitter
{
} // End namespace x86Emitter } // End namespace x86Emitter

View File

@ -32,472 +32,551 @@
namespace x86Emitter namespace x86Emitter
{ {
extern void xStoreReg( const xRegisterSSE& src ); extern void xStoreReg(const xRegisterSSE &src);
extern void xRestoreReg( const xRegisterSSE& dest ); extern void xRestoreReg(const xRegisterSSE &dest);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Group 1 Instruction Class // Group 1 Instruction Class
extern const xImpl_Group1 xADC; extern const xImpl_Group1 xADC;
extern const xImpl_Group1 xSBB; extern const xImpl_Group1 xSBB;
extern const xImpl_G1Logic xAND; extern const xImpl_G1Logic xAND;
extern const xImpl_G1Logic xOR; extern const xImpl_G1Logic xOR;
extern const xImpl_G1Logic xXOR; extern const xImpl_G1Logic xXOR;
extern const xImpl_G1Arith xADD; extern const xImpl_G1Arith xADD;
extern const xImpl_G1Arith xSUB; extern const xImpl_G1Arith xSUB;
extern const xImpl_G1Compare xCMP; extern const xImpl_G1Compare xCMP;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Group 2 Instruction Class // Group 2 Instruction Class
// //
// Optimization Note: For Imm forms, we ignore the instruction if the shift count is // Optimization Note: For Imm forms, we ignore the instruction if the shift count is
// zero. This is a safe optimization since any zero-value shift does not affect any // zero. This is a safe optimization since any zero-value shift does not affect any
// flags. // flags.
extern const xImpl_Mov xMOV; extern const xImpl_Mov xMOV;
extern const xImpl_Test xTEST; extern const xImpl_Test xTEST;
extern const xImpl_Group2 xROL, xROR, extern const xImpl_Group2 xROL, xROR,
xRCL, xRCR, xRCL, xRCR,
xSHL, xSHR, xSHL, xSHR,
xSAR; xSAR;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Group 3 Instruction Class // Group 3 Instruction Class
extern const xImpl_Group3 xNOT, xNEG; extern const xImpl_Group3 xNOT, xNEG;
extern const xImpl_Group3 xUMUL, xUDIV; extern const xImpl_Group3 xUMUL, xUDIV;
extern const xImpl_iDiv xDIV; extern const xImpl_iDiv xDIV;
extern const xImpl_iMul xMUL; extern const xImpl_iMul xMUL;
extern const xImpl_IncDec xINC, xDEC; extern const xImpl_IncDec xINC, xDEC;
extern const xImpl_MovExtend xMOVZX, xMOVSX; extern const xImpl_MovExtend xMOVZX, xMOVSX;
extern const xImpl_DwordShift xSHLD, xSHRD; extern const xImpl_DwordShift xSHLD, xSHRD;
extern const xImpl_Group8 xBT; extern const xImpl_Group8 xBT;
extern const xImpl_Group8 xBTR; extern const xImpl_Group8 xBTR;
extern const xImpl_Group8 xBTS; extern const xImpl_Group8 xBTS;
extern const xImpl_Group8 xBTC; extern const xImpl_Group8 xBTC;
extern const xImpl_BitScan xBSF, xBSR; extern const xImpl_BitScan xBSF, xBSR;
extern const xImpl_JmpCall xJMP; extern const xImpl_JmpCall xJMP;
#ifdef __x86_64__ #ifdef __x86_64__
// 32 bits Call won't be compatible in 64 bits (different ABI) // 32 bits Call won't be compatible in 64 bits (different ABI)
// Just a reminder to port the code // Just a reminder to port the code
[[deprecated]] extern const xImpl_JmpCall xCALL; [[deprecated]] extern const xImpl_JmpCall xCALL;
#else #else
extern const xImpl_JmpCall xCALL; extern const xImpl_JmpCall xCALL;
#endif #endif
extern const xImpl_FastCall xFastCall; extern const xImpl_FastCall xFastCall;
// ------------------------------------------------------------------------
extern const xImpl_CMov
xCMOVA, xCMOVAE,
xCMOVB, xCMOVBE,
xCMOVG, xCMOVGE,
xCMOVL, xCMOVLE,
xCMOVZ, xCMOVE,
xCMOVNZ, xCMOVNE,
xCMOVO, xCMOVNO,
xCMOVC, xCMOVNC,
xCMOVS, xCMOVNS,
xCMOVPE, xCMOVPO;
// ------------------------------------------------------------------------
extern const xImpl_Set
xSETA, xSETAE,
xSETB, xSETBE,
xSETG, xSETGE,
xSETL, xSETLE,
xSETZ, xSETE,
xSETNZ, xSETNE,
xSETO, xSETNO,
xSETC, xSETNC,
xSETS, xSETNS,
xSETPE, xSETPO;
// ------------------------------------------------------------------------
// BMI extra instruction requires BMI1/BMI2
extern const xImplBMI_RVM xMULX, xPDEP, xPEXT, xANDN_S; // Warning xANDN is already used by SSE
//////////////////////////////////////////////////////////////////////////////////////////
// Miscellaneous Instructions
// These are all defined inline or in ix86.cpp.
//
extern void xBSWAP( const xRegister32or64& to );
// ----- Lea Instructions (Load Effective Address) -----
// Note: alternate (void*) forms of these instructions are not provided since those
// forms are functionally equivalent to Mov reg,imm, and thus better written as MOVs
// instead.
extern void xLEA( xRegister64 to, const xIndirectVoid& src, bool preserve_flags=false );
extern void xLEA( xRegister32 to, const xIndirectVoid& src, bool preserve_flags=false );
extern void xLEA( xRegister16 to, const xIndirectVoid& src, bool preserve_flags=false );
// ----- Push / Pop Instructions -----
// Note: pushad/popad implementations are intentionally left out. The instructions are
// invalid in x64, and are super slow on x32. Use multiple Push/Pop instructions instead.
extern void xPOP( const xIndirectVoid& from );
extern void xPUSH( const xIndirectVoid& from );
extern void xPOP( xRegister32or64 from );
extern void xPUSH( u32 imm );
extern void xPUSH( xRegister32or64 from );
// pushes the EFLAGS register onto the stack
extern void xPUSHFD();
// pops the EFLAGS register from the stack
extern void xPOPFD();
// ----- Miscellaneous Instructions -----
// Various Instructions with no parameter and no special encoding logic.
extern void xLEAVE();
extern void xRET();
extern void xCBW();
extern void xCWD();
extern void xCDQ();
extern void xCWDE();
extern void xLAHF();
extern void xSAHF();
extern void xSTC();
extern void xCLC();
// NOP 1-byte
extern void xNOP();
extern void xINT( u8 imm );
extern void xINTO();
//////////////////////////////////////////////////////////////////////////////////////////
// Helper object to handle the various functions ABI
class xScopedStackFrame
{
bool m_base_frame;
bool m_save_base_pointer;
int m_offset;
public:
xScopedStackFrame(bool base_frame, bool save_base_pointer = false, int offset = 0);
~xScopedStackFrame();
};
//////////////////////////////////////////////////////////////////////////////////////////
// JMP / Jcc Instructions!
extern void xJcc( JccComparisonType comparison, const void* target );
extern s8* xJcc8( JccComparisonType comparison=Jcc_Unconditional, s8 displacement=0 );
extern s32* xJcc32( JccComparisonType comparison=Jcc_Unconditional, s32 displacement=0 );
// ------------------------------------------------------------------------
// Conditional jumps to fixed targets.
// Jumps accept any pointer as a valid target (function or data), and will generate either
// 8 or 32 bit displacement versions of the jump, depending on relative displacement of
// the target (efficient!)
//
template< typename T > __fi void xJE( T* func ) { xJcc( Jcc_Equal, (void*)(uptr)func ); }
template< typename T > __fi void xJZ( T* func ) { xJcc( Jcc_Zero, (void*)(uptr)func ); }
template< typename T > __fi void xJNE( T* func ) { xJcc( Jcc_NotEqual, (void*)(uptr)func ); }
template< typename T > __fi void xJNZ( T* func ) { xJcc( Jcc_NotZero, (void*)(uptr)func ); }
template< typename T > __fi void xJO( T* func ) { xJcc( Jcc_Overflow, (void*)(uptr)func ); }
template< typename T > __fi void xJNO( T* func ) { xJcc( Jcc_NotOverflow, (void*)(uptr)func ); }
template< typename T > __fi void xJC( T* func ) { xJcc( Jcc_Carry, (void*)(uptr)func ); }
template< typename T > __fi void xJNC( T* func ) { xJcc( Jcc_NotCarry, (void*)(uptr)func ); }
template< typename T > __fi void xJS( T* func ) { xJcc( Jcc_Signed, (void*)(uptr)func ); }
template< typename T > __fi void xJNS( T* func ) { xJcc( Jcc_Unsigned, (void*)(uptr)func ); }
template< typename T > __fi void xJPE( T* func ) { xJcc( Jcc_ParityEven, (void*)(uptr)func ); }
template< typename T > __fi void xJPO( T* func ) { xJcc( Jcc_ParityOdd, (void*)(uptr)func ); }
template< typename T > __fi void xJL( T* func ) { xJcc( Jcc_Less, (void*)(uptr)func ); }
template< typename T > __fi void xJLE( T* func ) { xJcc( Jcc_LessOrEqual, (void*)(uptr)func ); }
template< typename T > __fi void xJG( T* func ) { xJcc( Jcc_Greater, (void*)(uptr)func ); }
template< typename T > __fi void xJGE( T* func ) { xJcc( Jcc_GreaterOrEqual, (void*)(uptr)func ); }
template< typename T > __fi void xJB( T* func ) { xJcc( Jcc_Below, (void*)(uptr)func ); }
template< typename T > __fi void xJBE( T* func ) { xJcc( Jcc_BelowOrEqual, (void*)(uptr)func ); }
template< typename T > __fi void xJA( T* func ) { xJcc( Jcc_Above, (void*)(uptr)func ); }
template< typename T > __fi void xJAE( T* func ) { xJcc( Jcc_AboveOrEqual, (void*)(uptr)func ); }
// ------------------------------------------------------------------------
// Forward Jump Helpers (act as labels!)
#define DEFINE_FORWARD_JUMP( label, cond ) \
template< typename OperandType > \
class xForward##label : public xForwardJump<OperandType> \
{ \
public: \
xForward##label() : xForwardJump<OperandType>( cond ) {} \
};
// ------------------------------------------------------------------------
// Note: typedefs below are defined individually in order to appease Intellisense
// resolution. Including them into the class definition macro above breaks it.
typedef xForwardJump<s8> xForwardJump8;
typedef xForwardJump<s32> xForwardJump32;
DEFINE_FORWARD_JUMP( JA, Jcc_Above );
DEFINE_FORWARD_JUMP( JB, Jcc_Below );
DEFINE_FORWARD_JUMP( JAE, Jcc_AboveOrEqual );
DEFINE_FORWARD_JUMP( JBE, Jcc_BelowOrEqual );
typedef xForwardJA<s8> xForwardJA8;
typedef xForwardJA<s32> xForwardJA32;
typedef xForwardJB<s8> xForwardJB8;
typedef xForwardJB<s32> xForwardJB32;
typedef xForwardJAE<s8> xForwardJAE8;
typedef xForwardJAE<s32> xForwardJAE32;
typedef xForwardJBE<s8> xForwardJBE8;
typedef xForwardJBE<s32> xForwardJBE32;
DEFINE_FORWARD_JUMP( JG, Jcc_Greater );
DEFINE_FORWARD_JUMP( JL, Jcc_Less );
DEFINE_FORWARD_JUMP( JGE, Jcc_GreaterOrEqual );
DEFINE_FORWARD_JUMP( JLE, Jcc_LessOrEqual );
typedef xForwardJG<s8> xForwardJG8;
typedef xForwardJG<s32> xForwardJG32;
typedef xForwardJL<s8> xForwardJL8;
typedef xForwardJL<s32> xForwardJL32;
typedef xForwardJGE<s8> xForwardJGE8;
typedef xForwardJGE<s32> xForwardJGE32;
typedef xForwardJLE<s8> xForwardJLE8;
typedef xForwardJLE<s32> xForwardJLE32;
DEFINE_FORWARD_JUMP( JZ, Jcc_Zero );
DEFINE_FORWARD_JUMP( JE, Jcc_Equal );
DEFINE_FORWARD_JUMP( JNZ, Jcc_NotZero );
DEFINE_FORWARD_JUMP( JNE, Jcc_NotEqual );
typedef xForwardJZ<s8> xForwardJZ8;
typedef xForwardJZ<s32> xForwardJZ32;
typedef xForwardJE<s8> xForwardJE8;
typedef xForwardJE<s32> xForwardJE32;
typedef xForwardJNZ<s8> xForwardJNZ8;
typedef xForwardJNZ<s32> xForwardJNZ32;
typedef xForwardJNE<s8> xForwardJNE8;
typedef xForwardJNE<s32> xForwardJNE32;
DEFINE_FORWARD_JUMP( JS, Jcc_Signed );
DEFINE_FORWARD_JUMP( JNS, Jcc_Unsigned );
typedef xForwardJS<s8> xForwardJS8;
typedef xForwardJS<s32> xForwardJS32;
typedef xForwardJNS<s8> xForwardJNS8;
typedef xForwardJNS<s32> xForwardJNS32;
DEFINE_FORWARD_JUMP( JO, Jcc_Overflow );
DEFINE_FORWARD_JUMP( JNO, Jcc_NotOverflow );
typedef xForwardJO<s8> xForwardJO8;
typedef xForwardJO<s32> xForwardJO32;
typedef xForwardJNO<s8> xForwardJNO8;
typedef xForwardJNO<s32> xForwardJNO32;
DEFINE_FORWARD_JUMP( JC, Jcc_Carry );
DEFINE_FORWARD_JUMP( JNC, Jcc_NotCarry );
typedef xForwardJC<s8> xForwardJC8;
typedef xForwardJC<s32> xForwardJC32;
typedef xForwardJNC<s8> xForwardJNC8;
typedef xForwardJNC<s32> xForwardJNC32;
DEFINE_FORWARD_JUMP( JPE, Jcc_ParityEven );
DEFINE_FORWARD_JUMP( JPO, Jcc_ParityOdd );
typedef xForwardJPE<s8> xForwardJPE8;
typedef xForwardJPE<s32> xForwardJPE32;
typedef xForwardJPO<s8> xForwardJPO8;
typedef xForwardJPO<s32> xForwardJPO32;
// ------------------------------------------------------------------------
extern void xEMMS();
extern void xSTMXCSR( const xIndirect32& dest );
extern void xLDMXCSR( const xIndirect32& src );
extern void xFXSAVE( const xIndirectVoid& dest );
extern void xFXRSTOR( const xIndirectVoid& src );
extern void xMOVDZX( const xRegisterSSE& to, const xRegister32or64& from );
extern void xMOVDZX( const xRegisterSSE& to, const xIndirectVoid& src );
extern void xMOVD( const xRegister32or64& to, const xRegisterSSE& from );
extern void xMOVD( const xIndirectVoid& dest, const xRegisterSSE& from );
extern void xMOVQ( const xIndirectVoid& dest, const xRegisterSSE& from );
extern void xMOVQZX( const xRegisterSSE& to, const xIndirectVoid& src );
extern void xMOVQZX( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xMOVSS( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xMOVSS( const xIndirectVoid& to, const xRegisterSSE& from );
extern void xMOVSD( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xMOVSD( const xIndirectVoid& to, const xRegisterSSE& from );
extern void xMOVSSZX( const xRegisterSSE& to, const xIndirectVoid& from );
extern void xMOVSDZX( const xRegisterSSE& to, const xIndirectVoid& from );
extern void xMOVNTDQA( const xRegisterSSE& to, const xIndirectVoid& from );
extern void xMOVNTDQA( const xIndirectVoid& to, const xRegisterSSE& from );
extern void xMOVNTPD( const xIndirectVoid& to, const xRegisterSSE& from );
extern void xMOVNTPS( const xIndirectVoid& to, const xRegisterSSE& from );
extern void xMOVMSKPS( const xRegister32or64& to, const xRegisterSSE& from );
extern void xMOVMSKPD( const xRegister32or64& to, const xRegisterSSE& from );
extern void xMASKMOV( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xPMOVMSKB( const xRegister32or64& to, const xRegisterSSE& from );
extern void xPALIGNR( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8 );
// ------------------------------------------------------------------------
extern const xImplSimd_MoveSSE xMOVAPS;
extern const xImplSimd_MoveSSE xMOVUPS;
extern const xImplSimd_MoveSSE xMOVAPD;
extern const xImplSimd_MoveSSE xMOVUPD;
#ifdef ALWAYS_USE_MOVAPS
extern const xImplSimd_MoveSSE xMOVDQA;
extern const xImplSimd_MoveSSE xMOVDQU;
#else
extern const xImplSimd_MoveDQ xMOVDQA;
extern const xImplSimd_MoveDQ xMOVDQU;
#endif
extern const xImplSimd_MovHL xMOVH;
extern const xImplSimd_MovHL xMOVL;
extern const xImplSimd_MovHL_RtoR xMOVLH;
extern const xImplSimd_MovHL_RtoR xMOVHL;
extern const xImplSimd_Blend xBLEND;
extern const xImplSimd_PMove xPMOVSX;
extern const xImplSimd_PMove xPMOVZX;
extern const xImplSimd_DestRegSSE xMOVSLDUP;
extern const xImplSimd_DestRegSSE xMOVSHDUP;
extern void xINSERTPS( const xRegisterSSE& to, const xRegisterSSE& from, u8 imm8 );
extern void xINSERTPS( const xRegisterSSE& to, const xIndirect32& from, u8 imm8 );
extern void xEXTRACTPS( const xRegister32or64& to, const xRegisterSSE& from, u8 imm8 );
extern void xEXTRACTPS( const xIndirect32& dest, const xRegisterSSE& from, u8 imm8 );
// ------------------------------------------------------------------------
extern const xImplSimd_DestRegEither xPAND;
extern const xImplSimd_DestRegEither xPANDN;
extern const xImplSimd_DestRegEither xPOR;
extern const xImplSimd_DestRegEither xPXOR;
extern const xImplSimd_Shuffle xSHUF;
// ------------------------------------------------------------------------
extern const xImplSimd_DestRegSSE xPTEST;
extern const xImplSimd_MinMax xMIN;
extern const xImplSimd_MinMax xMAX;
extern const xImplSimd_Compare xCMPEQ, xCMPLT,
xCMPLE, xCMPUNORD,
xCMPNE, xCMPNLT,
xCMPNLE,xCMPORD;
extern const xImplSimd_COMI xCOMI;
extern const xImplSimd_COMI xUCOMI;
extern const xImplSimd_PCompare xPCMP;
extern const xImplSimd_PMinMax xPMIN;
extern const xImplSimd_PMinMax xPMAX;
// ------------------------------------------------------------------------
//
//
extern void xCVTDQ2PD( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTDQ2PD( const xRegisterSSE& to, const xIndirect64& from );
extern void xCVTDQ2PS( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTDQ2PS( const xRegisterSSE& to, const xIndirect128& from );
extern void xCVTPD2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTPD2DQ( const xRegisterSSE& to, const xIndirect128& from );
extern void xCVTPD2PS( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTPD2PS( const xRegisterSSE& to, const xIndirect128& from );
extern void xCVTPI2PD( const xRegisterSSE& to, const xIndirect64& from );
extern void xCVTPI2PS( const xRegisterSSE& to, const xIndirect64& from );
extern void xCVTPS2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTPS2DQ( const xRegisterSSE& to, const xIndirect128& from );
extern void xCVTPS2PD( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTPS2PD( const xRegisterSSE& to, const xIndirect64& from );
extern void xCVTSD2SI( const xRegister32or64& to, const xRegisterSSE& from );
extern void xCVTSD2SI( const xRegister32or64& to, const xIndirect64& from );
extern void xCVTSD2SS( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTSD2SS( const xRegisterSSE& to, const xIndirect64& from );
extern void xCVTSI2SS( const xRegisterSSE& to, const xRegister32or64& from );
extern void xCVTSI2SS( const xRegisterSSE& to, const xIndirect32& from );
extern void xCVTSS2SD( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTSS2SD( const xRegisterSSE& to, const xIndirect32& from );
extern void xCVTSS2SI( const xRegister32or64& to, const xRegisterSSE& from );
extern void xCVTSS2SI( const xRegister32or64& to, const xIndirect32& from );
extern void xCVTTPD2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTTPD2DQ( const xRegisterSSE& to, const xIndirect128& from );
extern void xCVTTPS2DQ( const xRegisterSSE& to, const xRegisterSSE& from );
extern void xCVTTPS2DQ( const xRegisterSSE& to, const xIndirect128& from );
extern void xCVTTSD2SI( const xRegister32or64& to, const xRegisterSSE& from );
extern void xCVTTSD2SI( const xRegister32or64& to, const xIndirect64& from );
extern void xCVTTSS2SI( const xRegister32or64& to, const xRegisterSSE& from );
extern void xCVTTSS2SI( const xRegister32or64& to, const xIndirect32& from );
// ------------------------------------------------------------------------
extern const xImplSimd_AndNot xANDN;
extern const xImplSimd_rSqrt xRCP;
extern const xImplSimd_rSqrt xRSQRT;
extern const xImplSimd_Sqrt xSQRT;
extern const xImplSimd_Shift xPSLL;
extern const xImplSimd_Shift xPSRL;
extern const xImplSimd_ShiftWithoutQ xPSRA;
extern const xImplSimd_AddSub xPADD;
extern const xImplSimd_AddSub xPSUB;
extern const xImplSimd_PMul xPMUL;
extern const xImplSimd_PAbsolute xPABS;
extern const xImplSimd_PSign xPSIGN;
extern const xImplSimd_PMultAdd xPMADD;
extern const xImplSimd_HorizAdd xHADD;
extern const xImplSimd_DotProduct xDP;
extern const xImplSimd_Round xROUND;
extern const xImplSimd_PShuffle xPSHUF;
extern const SimdImpl_PUnpack xPUNPCK;
extern const xImplSimd_Unpack xUNPCK;
extern const SimdImpl_Pack xPACK;
extern const xImplSimd_PInsert xPINSR;
extern const SimdImpl_PExtract xPEXTR;
// ------------------------------------------------------------------------
extern const xImpl_CMov xCMOVA, xCMOVAE,
xCMOVB, xCMOVBE,
xCMOVG, xCMOVGE,
xCMOVL, xCMOVLE,
xCMOVZ, xCMOVE,
xCMOVNZ, xCMOVNE,
xCMOVO, xCMOVNO,
xCMOVC, xCMOVNC,
xCMOVS, xCMOVNS,
xCMOVPE, xCMOVPO;
// ------------------------------------------------------------------------
extern const xImpl_Set xSETA, xSETAE,
xSETB, xSETBE,
xSETG, xSETGE,
xSETL, xSETLE,
xSETZ, xSETE,
xSETNZ, xSETNE,
xSETO, xSETNO,
xSETC, xSETNC,
xSETS, xSETNS,
xSETPE, xSETPO;
// ------------------------------------------------------------------------
// BMI extra instruction requires BMI1/BMI2
extern const xImplBMI_RVM xMULX, xPDEP, xPEXT, xANDN_S; // Warning xANDN is already used by SSE
//////////////////////////////////////////////////////////////////////////////////////////
// Miscellaneous Instructions
// These are all defined inline or in ix86.cpp.
//
extern void xBSWAP(const xRegister32or64 &to);
// ----- Lea Instructions (Load Effective Address) -----
// Note: alternate (void*) forms of these instructions are not provided since those
// forms are functionally equivalent to Mov reg,imm, and thus better written as MOVs
// instead.
extern void xLEA(xRegister64 to, const xIndirectVoid &src, bool preserve_flags = false);
extern void xLEA(xRegister32 to, const xIndirectVoid &src, bool preserve_flags = false);
extern void xLEA(xRegister16 to, const xIndirectVoid &src, bool preserve_flags = false);
// ----- Push / Pop Instructions -----
// Note: pushad/popad implementations are intentionally left out. The instructions are
// invalid in x64, and are super slow on x32. Use multiple Push/Pop instructions instead.
extern void xPOP(const xIndirectVoid &from);
extern void xPUSH(const xIndirectVoid &from);
extern void xPOP(xRegister32or64 from);
extern void xPUSH(u32 imm);
extern void xPUSH(xRegister32or64 from);
// pushes the EFLAGS register onto the stack
extern void xPUSHFD();
// pops the EFLAGS register from the stack
extern void xPOPFD();
// ----- Miscellaneous Instructions -----
// Various Instructions with no parameter and no special encoding logic.
extern void xLEAVE();
extern void xRET();
extern void xCBW();
extern void xCWD();
extern void xCDQ();
extern void xCWDE();
extern void xLAHF();
extern void xSAHF();
extern void xSTC();
extern void xCLC();
// NOP 1-byte
extern void xNOP();
extern void xINT(u8 imm);
extern void xINTO();
//////////////////////////////////////////////////////////////////////////////////////////
// Helper object to handle the various functions ABI
class xScopedStackFrame
{
bool m_base_frame;
bool m_save_base_pointer;
int m_offset;
public:
xScopedStackFrame(bool base_frame, bool save_base_pointer = false, int offset = 0);
~xScopedStackFrame();
};
//////////////////////////////////////////////////////////////////////////////////////////
// JMP / Jcc Instructions!
extern void xJcc(JccComparisonType comparison, const void *target);
extern s8 *xJcc8(JccComparisonType comparison = Jcc_Unconditional, s8 displacement = 0);
extern s32 *xJcc32(JccComparisonType comparison = Jcc_Unconditional, s32 displacement = 0);
// ------------------------------------------------------------------------
// Conditional jumps to fixed targets.
// Jumps accept any pointer as a valid target (function or data), and will generate either
// 8 or 32 bit displacement versions of the jump, depending on relative displacement of
// the target (efficient!)
//
template <typename T>
__fi void xJE(T *func)
{
xJcc(Jcc_Equal, (void *)(uptr)func);
}
template <typename T>
__fi void xJZ(T *func)
{
xJcc(Jcc_Zero, (void *)(uptr)func);
}
template <typename T>
__fi void xJNE(T *func)
{
xJcc(Jcc_NotEqual, (void *)(uptr)func);
}
template <typename T>
__fi void xJNZ(T *func)
{
xJcc(Jcc_NotZero, (void *)(uptr)func);
} }
template <typename T>
__fi void xJO(T *func)
{
xJcc(Jcc_Overflow, (void *)(uptr)func);
}
template <typename T>
__fi void xJNO(T *func)
{
xJcc(Jcc_NotOverflow, (void *)(uptr)func);
}
template <typename T>
__fi void xJC(T *func)
{
xJcc(Jcc_Carry, (void *)(uptr)func);
}
template <typename T>
__fi void xJNC(T *func)
{
xJcc(Jcc_NotCarry, (void *)(uptr)func);
}
template <typename T>
__fi void xJS(T *func)
{
xJcc(Jcc_Signed, (void *)(uptr)func);
}
template <typename T>
__fi void xJNS(T *func)
{
xJcc(Jcc_Unsigned, (void *)(uptr)func);
}
template <typename T>
__fi void xJPE(T *func)
{
xJcc(Jcc_ParityEven, (void *)(uptr)func);
}
template <typename T>
__fi void xJPO(T *func)
{
xJcc(Jcc_ParityOdd, (void *)(uptr)func);
}
template <typename T>
__fi void xJL(T *func)
{
xJcc(Jcc_Less, (void *)(uptr)func);
}
template <typename T>
__fi void xJLE(T *func)
{
xJcc(Jcc_LessOrEqual, (void *)(uptr)func);
}
template <typename T>
__fi void xJG(T *func)
{
xJcc(Jcc_Greater, (void *)(uptr)func);
}
template <typename T>
__fi void xJGE(T *func)
{
xJcc(Jcc_GreaterOrEqual, (void *)(uptr)func);
}
template <typename T>
__fi void xJB(T *func)
{
xJcc(Jcc_Below, (void *)(uptr)func);
}
template <typename T>
__fi void xJBE(T *func)
{
xJcc(Jcc_BelowOrEqual, (void *)(uptr)func);
}
template <typename T>
__fi void xJA(T *func)
{
xJcc(Jcc_Above, (void *)(uptr)func);
}
template <typename T>
__fi void xJAE(T *func)
{
xJcc(Jcc_AboveOrEqual, (void *)(uptr)func);
}
// ------------------------------------------------------------------------
// Forward Jump Helpers (act as labels!)
#define DEFINE_FORWARD_JUMP(label, cond) \
template <typename OperandType> \
class xForward##label : public xForwardJump<OperandType> \
{ \
public: \
xForward##label() \
: xForwardJump<OperandType>(cond) \
{ \
} \
};
// ------------------------------------------------------------------------
// Note: typedefs below are defined individually in order to appease Intellisense
// resolution. Including them into the class definition macro above breaks it.
typedef xForwardJump<s8> xForwardJump8;
typedef xForwardJump<s32> xForwardJump32;
DEFINE_FORWARD_JUMP(JA, Jcc_Above);
DEFINE_FORWARD_JUMP(JB, Jcc_Below);
DEFINE_FORWARD_JUMP(JAE, Jcc_AboveOrEqual);
DEFINE_FORWARD_JUMP(JBE, Jcc_BelowOrEqual);
typedef xForwardJA<s8> xForwardJA8;
typedef xForwardJA<s32> xForwardJA32;
typedef xForwardJB<s8> xForwardJB8;
typedef xForwardJB<s32> xForwardJB32;
typedef xForwardJAE<s8> xForwardJAE8;
typedef xForwardJAE<s32> xForwardJAE32;
typedef xForwardJBE<s8> xForwardJBE8;
typedef xForwardJBE<s32> xForwardJBE32;
DEFINE_FORWARD_JUMP(JG, Jcc_Greater);
DEFINE_FORWARD_JUMP(JL, Jcc_Less);
DEFINE_FORWARD_JUMP(JGE, Jcc_GreaterOrEqual);
DEFINE_FORWARD_JUMP(JLE, Jcc_LessOrEqual);
typedef xForwardJG<s8> xForwardJG8;
typedef xForwardJG<s32> xForwardJG32;
typedef xForwardJL<s8> xForwardJL8;
typedef xForwardJL<s32> xForwardJL32;
typedef xForwardJGE<s8> xForwardJGE8;
typedef xForwardJGE<s32> xForwardJGE32;
typedef xForwardJLE<s8> xForwardJLE8;
typedef xForwardJLE<s32> xForwardJLE32;
DEFINE_FORWARD_JUMP(JZ, Jcc_Zero);
DEFINE_FORWARD_JUMP(JE, Jcc_Equal);
DEFINE_FORWARD_JUMP(JNZ, Jcc_NotZero);
DEFINE_FORWARD_JUMP(JNE, Jcc_NotEqual);
typedef xForwardJZ<s8> xForwardJZ8;
typedef xForwardJZ<s32> xForwardJZ32;
typedef xForwardJE<s8> xForwardJE8;
typedef xForwardJE<s32> xForwardJE32;
typedef xForwardJNZ<s8> xForwardJNZ8;
typedef xForwardJNZ<s32> xForwardJNZ32;
typedef xForwardJNE<s8> xForwardJNE8;
typedef xForwardJNE<s32> xForwardJNE32;
DEFINE_FORWARD_JUMP(JS, Jcc_Signed);
DEFINE_FORWARD_JUMP(JNS, Jcc_Unsigned);
typedef xForwardJS<s8> xForwardJS8;
typedef xForwardJS<s32> xForwardJS32;
typedef xForwardJNS<s8> xForwardJNS8;
typedef xForwardJNS<s32> xForwardJNS32;
DEFINE_FORWARD_JUMP(JO, Jcc_Overflow);
DEFINE_FORWARD_JUMP(JNO, Jcc_NotOverflow);
typedef xForwardJO<s8> xForwardJO8;
typedef xForwardJO<s32> xForwardJO32;
typedef xForwardJNO<s8> xForwardJNO8;
typedef xForwardJNO<s32> xForwardJNO32;
DEFINE_FORWARD_JUMP(JC, Jcc_Carry);
DEFINE_FORWARD_JUMP(JNC, Jcc_NotCarry);
typedef xForwardJC<s8> xForwardJC8;
typedef xForwardJC<s32> xForwardJC32;
typedef xForwardJNC<s8> xForwardJNC8;
typedef xForwardJNC<s32> xForwardJNC32;
DEFINE_FORWARD_JUMP(JPE, Jcc_ParityEven);
DEFINE_FORWARD_JUMP(JPO, Jcc_ParityOdd);
typedef xForwardJPE<s8> xForwardJPE8;
typedef xForwardJPE<s32> xForwardJPE32;
typedef xForwardJPO<s8> xForwardJPO8;
typedef xForwardJPO<s32> xForwardJPO32;
// ------------------------------------------------------------------------
extern void xEMMS();
extern void xSTMXCSR(const xIndirect32 &dest);
extern void xLDMXCSR(const xIndirect32 &src);
extern void xFXSAVE(const xIndirectVoid &dest);
extern void xFXRSTOR(const xIndirectVoid &src);
extern void xMOVDZX(const xRegisterSSE &to, const xRegister32or64 &from);
extern void xMOVDZX(const xRegisterSSE &to, const xIndirectVoid &src);
extern void xMOVD(const xRegister32or64 &to, const xRegisterSSE &from);
extern void xMOVD(const xIndirectVoid &dest, const xRegisterSSE &from);
extern void xMOVQ(const xIndirectVoid &dest, const xRegisterSSE &from);
extern void xMOVQZX(const xRegisterSSE &to, const xIndirectVoid &src);
extern void xMOVQZX(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xMOVSS(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xMOVSS(const xIndirectVoid &to, const xRegisterSSE &from);
extern void xMOVSD(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xMOVSD(const xIndirectVoid &to, const xRegisterSSE &from);
extern void xMOVSSZX(const xRegisterSSE &to, const xIndirectVoid &from);
extern void xMOVSDZX(const xRegisterSSE &to, const xIndirectVoid &from);
extern void xMOVNTDQA(const xRegisterSSE &to, const xIndirectVoid &from);
extern void xMOVNTDQA(const xIndirectVoid &to, const xRegisterSSE &from);
extern void xMOVNTPD(const xIndirectVoid &to, const xRegisterSSE &from);
extern void xMOVNTPS(const xIndirectVoid &to, const xRegisterSSE &from);
extern void xMOVMSKPS(const xRegister32or64 &to, const xRegisterSSE &from);
extern void xMOVMSKPD(const xRegister32or64 &to, const xRegisterSSE &from);
extern void xMASKMOV(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xPMOVMSKB(const xRegister32or64 &to, const xRegisterSSE &from);
extern void xPALIGNR(const xRegisterSSE &to, const xRegisterSSE &from, u8 imm8);
// ------------------------------------------------------------------------
extern const xImplSimd_MoveSSE xMOVAPS;
extern const xImplSimd_MoveSSE xMOVUPS;
extern const xImplSimd_MoveSSE xMOVAPD;
extern const xImplSimd_MoveSSE xMOVUPD;
#ifdef ALWAYS_USE_MOVAPS
extern const xImplSimd_MoveSSE xMOVDQA;
extern const xImplSimd_MoveSSE xMOVDQU;
#else
extern const xImplSimd_MoveDQ xMOVDQA;
extern const xImplSimd_MoveDQ xMOVDQU;
#endif
extern const xImplSimd_MovHL xMOVH;
extern const xImplSimd_MovHL xMOVL;
extern const xImplSimd_MovHL_RtoR xMOVLH;
extern const xImplSimd_MovHL_RtoR xMOVHL;
extern const xImplSimd_Blend xBLEND;
extern const xImplSimd_PMove xPMOVSX;
extern const xImplSimd_PMove xPMOVZX;
extern const xImplSimd_DestRegSSE xMOVSLDUP;
extern const xImplSimd_DestRegSSE xMOVSHDUP;
extern void xINSERTPS(const xRegisterSSE &to, const xRegisterSSE &from, u8 imm8);
extern void xINSERTPS(const xRegisterSSE &to, const xIndirect32 &from, u8 imm8);
extern void xEXTRACTPS(const xRegister32or64 &to, const xRegisterSSE &from, u8 imm8);
extern void xEXTRACTPS(const xIndirect32 &dest, const xRegisterSSE &from, u8 imm8);
// ------------------------------------------------------------------------
extern const xImplSimd_DestRegEither xPAND;
extern const xImplSimd_DestRegEither xPANDN;
extern const xImplSimd_DestRegEither xPOR;
extern const xImplSimd_DestRegEither xPXOR;
extern const xImplSimd_Shuffle xSHUF;
// ------------------------------------------------------------------------
extern const xImplSimd_DestRegSSE xPTEST;
extern const xImplSimd_MinMax xMIN;
extern const xImplSimd_MinMax xMAX;
extern const xImplSimd_Compare xCMPEQ, xCMPLT,
xCMPLE, xCMPUNORD,
xCMPNE, xCMPNLT,
xCMPNLE, xCMPORD;
extern const xImplSimd_COMI xCOMI;
extern const xImplSimd_COMI xUCOMI;
extern const xImplSimd_PCompare xPCMP;
extern const xImplSimd_PMinMax xPMIN;
extern const xImplSimd_PMinMax xPMAX;
// ------------------------------------------------------------------------
//
//
extern void xCVTDQ2PD(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTDQ2PD(const xRegisterSSE &to, const xIndirect64 &from);
extern void xCVTDQ2PS(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTDQ2PS(const xRegisterSSE &to, const xIndirect128 &from);
extern void xCVTPD2DQ(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTPD2DQ(const xRegisterSSE &to, const xIndirect128 &from);
extern void xCVTPD2PS(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTPD2PS(const xRegisterSSE &to, const xIndirect128 &from);
extern void xCVTPI2PD(const xRegisterSSE &to, const xIndirect64 &from);
extern void xCVTPI2PS(const xRegisterSSE &to, const xIndirect64 &from);
extern void xCVTPS2DQ(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTPS2DQ(const xRegisterSSE &to, const xIndirect128 &from);
extern void xCVTPS2PD(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTPS2PD(const xRegisterSSE &to, const xIndirect64 &from);
extern void xCVTSD2SI(const xRegister32or64 &to, const xRegisterSSE &from);
extern void xCVTSD2SI(const xRegister32or64 &to, const xIndirect64 &from);
extern void xCVTSD2SS(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTSD2SS(const xRegisterSSE &to, const xIndirect64 &from);
extern void xCVTSI2SS(const xRegisterSSE &to, const xRegister32or64 &from);
extern void xCVTSI2SS(const xRegisterSSE &to, const xIndirect32 &from);
extern void xCVTSS2SD(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTSS2SD(const xRegisterSSE &to, const xIndirect32 &from);
extern void xCVTSS2SI(const xRegister32or64 &to, const xRegisterSSE &from);
extern void xCVTSS2SI(const xRegister32or64 &to, const xIndirect32 &from);
extern void xCVTTPD2DQ(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTTPD2DQ(const xRegisterSSE &to, const xIndirect128 &from);
extern void xCVTTPS2DQ(const xRegisterSSE &to, const xRegisterSSE &from);
extern void xCVTTPS2DQ(const xRegisterSSE &to, const xIndirect128 &from);
extern void xCVTTSD2SI(const xRegister32or64 &to, const xRegisterSSE &from);
extern void xCVTTSD2SI(const xRegister32or64 &to, const xIndirect64 &from);
extern void xCVTTSS2SI(const xRegister32or64 &to, const xRegisterSSE &from);
extern void xCVTTSS2SI(const xRegister32or64 &to, const xIndirect32 &from);
// ------------------------------------------------------------------------
extern const xImplSimd_AndNot xANDN;
extern const xImplSimd_rSqrt xRCP;
extern const xImplSimd_rSqrt xRSQRT;
extern const xImplSimd_Sqrt xSQRT;
extern const xImplSimd_Shift xPSLL;
extern const xImplSimd_Shift xPSRL;
extern const xImplSimd_ShiftWithoutQ xPSRA;
extern const xImplSimd_AddSub xPADD;
extern const xImplSimd_AddSub xPSUB;
extern const xImplSimd_PMul xPMUL;
extern const xImplSimd_PAbsolute xPABS;
extern const xImplSimd_PSign xPSIGN;
extern const xImplSimd_PMultAdd xPMADD;
extern const xImplSimd_HorizAdd xHADD;
extern const xImplSimd_DotProduct xDP;
extern const xImplSimd_Round xROUND;
extern const xImplSimd_PShuffle xPSHUF;
extern const SimdImpl_PUnpack xPUNPCK;
extern const xImplSimd_Unpack xUNPCK;
extern const SimdImpl_Pack xPACK;
extern const xImplSimd_PInsert xPINSR;
extern const SimdImpl_PExtract xPEXTR;
}

View File

@ -19,156 +19,164 @@
#include "instructions.h" #include "instructions.h"
namespace x86Emitter { namespace x86Emitter
{
#define OpWriteSSE( pre, op ) xOpWrite0F( pre, op, to, from ) #define OpWriteSSE(pre, op) xOpWrite0F(pre, op, to, from)
extern void SimdPrefix( u8 prefix, u16 opcode ); extern void SimdPrefix(u8 prefix, u16 opcode);
extern void EmitSibMagic( uint regfield, const void* address ); extern void EmitSibMagic(uint regfield, const void *address);
extern void EmitSibMagic( uint regfield, const xIndirectVoid& info ); extern void EmitSibMagic(uint regfield, const xIndirectVoid &info);
extern void EmitSibMagic( uint reg1, const xRegisterBase& reg2 ); extern void EmitSibMagic(uint reg1, const xRegisterBase &reg2);
extern void EmitSibMagic( const xRegisterBase& reg1, const xRegisterBase& reg2 ); extern void EmitSibMagic(const xRegisterBase &reg1, const xRegisterBase &reg2);
extern void EmitSibMagic( const xRegisterBase& reg1, const void* src ); extern void EmitSibMagic(const xRegisterBase &reg1, const void *src);
extern void EmitSibMagic( const xRegisterBase& reg1, const xIndirectVoid& sib ); extern void EmitSibMagic(const xRegisterBase &reg1, const xIndirectVoid &sib);
extern void EmitRex( uint regfield, const void* address ); extern void EmitRex(uint regfield, const void *address);
extern void EmitRex( uint regfield, const xIndirectVoid& info ); extern void EmitRex(uint regfield, const xIndirectVoid &info);
extern void EmitRex( uint reg1, const xRegisterBase& reg2 ); extern void EmitRex(uint reg1, const xRegisterBase &reg2);
extern void EmitRex( const xRegisterBase& reg1, const xRegisterBase& reg2 ); extern void EmitRex(const xRegisterBase &reg1, const xRegisterBase &reg2);
extern void EmitRex( const xRegisterBase& reg1, const void* src ); extern void EmitRex(const xRegisterBase &reg1, const void *src);
extern void EmitRex( const xRegisterBase& reg1, const xIndirectVoid& sib ); extern void EmitRex(const xRegisterBase &reg1, const xIndirectVoid &sib);
extern void _xMovRtoR( const xRegisterInt& to, const xRegisterInt& from ); extern void _xMovRtoR(const xRegisterInt &to, const xRegisterInt &from);
template< typename T > inline
void xWrite( T val )
{
*(T*)x86Ptr = val;
x86Ptr += sizeof(T);
}
template< typename T1, typename T2 > __emitinline
void xOpWrite( u8 prefix, u8 opcode, const T1& param1, const T2& param2 )
{
if( prefix != 0 ) xWrite8( prefix );
EmitRex( param1, param2 );
xWrite8( opcode );
EmitSibMagic( param1, param2 );
}
template< typename T1, typename T2 > __emitinline
void xOpAccWrite( u8 prefix, u8 opcode, const T1& param1, const T2& param2 )
{
if( prefix != 0 ) xWrite8( prefix );
EmitRex( param1, param2 );
xWrite8( opcode );
}
//////////////////////////////////////////////////////////////////////////////////////////
// emitter helpers for xmm instruction with prefixes, most of which are using
// the basic opcode format (items inside braces denote optional or conditional
// emission):
//
// [Prefix] / 0x0f / [OpcodePrefix] / Opcode / ModRM+[SibSB]
//
// Prefixes are typically 0x66, 0xf2, or 0xf3. OpcodePrefixes are either 0x38 or
// 0x3a [and other value will result in assertion failue].
//
template< typename T1, typename T2 > __emitinline
void xOpWrite0F( u8 prefix, u16 opcode, const T1& param1, const T2& param2 )
{
if( prefix != 0 ) xWrite8( prefix );
EmitRex( param1, param2 );
SimdPrefix( 0, opcode );
EmitSibMagic( param1, param2 );
}
template< typename T1, typename T2 > __emitinline
void xOpWrite0F( u8 prefix, u16 opcode, const T1& param1, const T2& param2, u8 imm8 )
{
xOpWrite0F( prefix, opcode, param1, param2 );
xWrite8( imm8 );
}
template< typename T1, typename T2 > __emitinline
void xOpWrite0F( u16 opcode, const T1& param1, const T2& param2 ) { xOpWrite0F( 0, opcode, param1, param2 ); }
template< typename T1, typename T2 > __emitinline
void xOpWrite0F( u16 opcode, const T1& param1, const T2& param2, u8 imm8 ) { xOpWrite0F( 0, opcode, param1, param2, imm8 ); }
// VEX 2 Bytes Prefix
template< typename T1, typename T2, typename T3 > __emitinline
void xOpWriteC5( u8 prefix, u8 opcode, const T1& param1, const T2& param2, const T3& param3 )
{
pxAssert( prefix == 0 || prefix == 0x66 || prefix == 0xF3 || prefix == 0xF2 );
const xRegisterInt& reg = param1.IsReg() ? param1 : param2;
#ifdef __x86_64__
u8 nR = reg.IsExtended() ? 0x00 : 0x80;
#else
u8 nR = 0x80;
#endif
u8 L = reg.IsWideSIMD() ? 4 : 0;
u8 nv = (~param2.GetId() & 0xF) << 3;
u8 p =
prefix == 0xF2 ? 3 :
prefix == 0xF3 ? 2 :
prefix == 0x66 ? 1 : 0;
xWrite8( 0xC5 );
xWrite8( nR | nv | L | p );
xWrite8( opcode );
EmitSibMagic( param1, param3 );
}
// VEX 3 Bytes Prefix
template< typename T1, typename T2, typename T3 > __emitinline
void xOpWriteC4( u8 prefix, u8 mb_prefix, u8 opcode, const T1& param1, const T2& param2, const T3& param3, int w = -1 )
{
pxAssert( prefix == 0 || prefix == 0x66 || prefix == 0xF3 || prefix == 0xF2 );
pxAssert( mb_prefix == 0x0F || mb_prefix == 0x38 || mb_prefix == 0x3A );
const xRegisterInt& reg = param1.IsReg() ? param1 : param2;
#ifdef __x86_64__
u8 nR = reg.IsExtended() ? 0x00 : 0x80;
u8 nB = param3.IsExtended() ? 0x00 : 0x20;
u8 nX = 0x40; // likely unused so hardwired to disabled
#else
u8 nR = 0x80;
u8 nB = 0x20;
u8 nX = 0x40;
#endif
u8 L = reg.IsWideSIMD() ? 4 : 0;
u8 W = (w == -1) ? (reg.GetOperandSize() == 8 ? 0x80 : 0) : // autodetect the size
0x80 * w; // take directly the W value
u8 nv = (~param2.GetId() & 0xF) << 3;
u8 p =
prefix == 0xF2 ? 3 :
prefix == 0xF3 ? 2 :
prefix == 0x66 ? 1 : 0;
u8 m =
mb_prefix == 0x3A ? 3 :
mb_prefix == 0x38 ? 2 : 1;
xWrite8( 0xC4 );
xWrite8( nR | nX | nB | m );
xWrite8( W | nv | L | p );
xWrite8( opcode );
EmitSibMagic( param1, param3 );
}
template <typename T>
inline void xWrite(T val)
{
*(T *)x86Ptr = val;
x86Ptr += sizeof(T);
} }
template <typename T1, typename T2>
__emitinline void xOpWrite(u8 prefix, u8 opcode, const T1 &param1, const T2 &param2)
{
if (prefix != 0)
xWrite8(prefix);
EmitRex(param1, param2);
xWrite8(opcode);
EmitSibMagic(param1, param2);
}
template <typename T1, typename T2>
__emitinline void xOpAccWrite(u8 prefix, u8 opcode, const T1 &param1, const T2 &param2)
{
if (prefix != 0)
xWrite8(prefix);
EmitRex(param1, param2);
xWrite8(opcode);
}
//////////////////////////////////////////////////////////////////////////////////////////
// emitter helpers for xmm instruction with prefixes, most of which are using
// the basic opcode format (items inside braces denote optional or conditional
// emission):
//
// [Prefix] / 0x0f / [OpcodePrefix] / Opcode / ModRM+[SibSB]
//
// Prefixes are typically 0x66, 0xf2, or 0xf3. OpcodePrefixes are either 0x38 or
// 0x3a [and other value will result in assertion failue].
//
template <typename T1, typename T2>
__emitinline void xOpWrite0F(u8 prefix, u16 opcode, const T1 &param1, const T2 &param2)
{
if (prefix != 0)
xWrite8(prefix);
EmitRex(param1, param2);
SimdPrefix(0, opcode);
EmitSibMagic(param1, param2);
}
template <typename T1, typename T2>
__emitinline void xOpWrite0F(u8 prefix, u16 opcode, const T1 &param1, const T2 &param2, u8 imm8)
{
xOpWrite0F(prefix, opcode, param1, param2);
xWrite8(imm8);
}
template <typename T1, typename T2>
__emitinline void xOpWrite0F(u16 opcode, const T1 &param1, const T2 &param2)
{
xOpWrite0F(0, opcode, param1, param2);
}
template <typename T1, typename T2>
__emitinline void xOpWrite0F(u16 opcode, const T1 &param1, const T2 &param2, u8 imm8)
{
xOpWrite0F(0, opcode, param1, param2, imm8);
}
// VEX 2 Bytes Prefix
template <typename T1, typename T2, typename T3>
__emitinline void xOpWriteC5(u8 prefix, u8 opcode, const T1 &param1, const T2 &param2, const T3 &param3)
{
pxAssert(prefix == 0 || prefix == 0x66 || prefix == 0xF3 || prefix == 0xF2);
const xRegisterInt &reg = param1.IsReg() ? param1 : param2;
#ifdef __x86_64__
u8 nR = reg.IsExtended() ? 0x00 : 0x80;
#else
u8 nR = 0x80;
#endif
u8 L = reg.IsWideSIMD() ? 4 : 0;
u8 nv = (~param2.GetId() & 0xF) << 3;
u8 p =
prefix == 0xF2 ? 3 :
prefix == 0xF3 ? 2 :
prefix == 0x66 ? 1 : 0;
xWrite8(0xC5);
xWrite8(nR | nv | L | p);
xWrite8(opcode);
EmitSibMagic(param1, param3);
}
// VEX 3 Bytes Prefix
template <typename T1, typename T2, typename T3>
__emitinline void xOpWriteC4(u8 prefix, u8 mb_prefix, u8 opcode, const T1 &param1, const T2 &param2, const T3 &param3, int w = -1)
{
pxAssert(prefix == 0 || prefix == 0x66 || prefix == 0xF3 || prefix == 0xF2);
pxAssert(mb_prefix == 0x0F || mb_prefix == 0x38 || mb_prefix == 0x3A);
const xRegisterInt &reg = param1.IsReg() ? param1 : param2;
#ifdef __x86_64__
u8 nR = reg.IsExtended() ? 0x00 : 0x80;
u8 nB = param3.IsExtended() ? 0x00 : 0x20;
u8 nX = 0x40; // likely unused so hardwired to disabled
#else
u8 nR = 0x80;
u8 nB = 0x20;
u8 nX = 0x40;
#endif
u8 L = reg.IsWideSIMD() ? 4 : 0;
u8 W = (w == -1) ? (reg.GetOperandSize() == 8 ? 0x80 : 0) : // autodetect the size
0x80 * w; // take directly the W value
u8 nv = (~param2.GetId() & 0xF) << 3;
u8 p =
prefix == 0xF2 ? 3 :
prefix == 0xF3 ? 2 :
prefix == 0x66 ? 1 : 0;
u8 m =
mb_prefix == 0x3A ? 3 :
mb_prefix == 0x38 ? 2 : 1;
xWrite8(0xC4);
xWrite8(nR | nX | nB | m);
xWrite8(W | nv | L | p);
xWrite8(opcode);
EmitSibMagic(param1, param3);
}
}

View File

@ -25,15 +25,15 @@
//------------------------------------------------------------------ //------------------------------------------------------------------
// legacy jump/align functions // legacy jump/align functions
//------------------------------------------------------------------ //------------------------------------------------------------------
ATTR_DEP extern void x86SetPtr( u8 *ptr ); ATTR_DEP extern void x86SetPtr(u8 *ptr);
ATTR_DEP extern void x86SetJ8( u8 *j8 ); ATTR_DEP extern void x86SetJ8(u8 *j8);
ATTR_DEP extern void x86SetJ8A( u8 *j8 ); ATTR_DEP extern void x86SetJ8A(u8 *j8);
ATTR_DEP extern void x86SetJ16( u16 *j16 ); ATTR_DEP extern void x86SetJ16(u16 *j16);
ATTR_DEP extern void x86SetJ16A( u16 *j16 ); ATTR_DEP extern void x86SetJ16A(u16 *j16);
ATTR_DEP extern void x86SetJ32( u32 *j32 ); ATTR_DEP extern void x86SetJ32(u32 *j32);
ATTR_DEP extern void x86SetJ32A( u32 *j32 ); ATTR_DEP extern void x86SetJ32A(u32 *j32);
ATTR_DEP extern void x86Align( int bytes ); ATTR_DEP extern void x86Align(int bytes);
ATTR_DEP extern void x86AlignExecutable( int align ); ATTR_DEP extern void x86AlignExecutable(int align);
//------------------------------------------------------------------ //------------------------------------------------------------------
//////////////////////////////////// ////////////////////////////////////
@ -41,55 +41,55 @@ ATTR_DEP extern void x86AlignExecutable( int align );
//////////////////////////////////// ////////////////////////////////////
// jmp rel8 // jmp rel8
ATTR_DEP extern u8* JMP8( u8 to ); ATTR_DEP extern u8 *JMP8(u8 to);
// jmp rel32 // jmp rel32
ATTR_DEP extern u32* JMP32( uptr to ); ATTR_DEP extern u32 *JMP32(uptr to);
// jp rel8 // jp rel8
ATTR_DEP extern u8* JP8( u8 to ); ATTR_DEP extern u8 *JP8(u8 to);
// jnp rel8 // jnp rel8
ATTR_DEP extern u8* JNP8( u8 to ); ATTR_DEP extern u8 *JNP8(u8 to);
// je rel8 // je rel8
ATTR_DEP extern u8* JE8( u8 to ); ATTR_DEP extern u8 *JE8(u8 to);
// jz rel8 // jz rel8
ATTR_DEP extern u8* JZ8( u8 to ); ATTR_DEP extern u8 *JZ8(u8 to);
// jg rel8 // jg rel8
ATTR_DEP extern u8* JG8( u8 to ); ATTR_DEP extern u8 *JG8(u8 to);
// jge rel8 // jge rel8
ATTR_DEP extern u8* JGE8( u8 to ); ATTR_DEP extern u8 *JGE8(u8 to);
// js rel8 // js rel8
ATTR_DEP extern u8* JS8( u8 to ); ATTR_DEP extern u8 *JS8(u8 to);
// jns rel8 // jns rel8
ATTR_DEP extern u8* JNS8( u8 to ); ATTR_DEP extern u8 *JNS8(u8 to);
// jl rel8 // jl rel8
ATTR_DEP extern u8* JL8( u8 to ); ATTR_DEP extern u8 *JL8(u8 to);
// ja rel8 // ja rel8
ATTR_DEP extern u8* JA8( u8 to ); ATTR_DEP extern u8 *JA8(u8 to);
// jae rel8 // jae rel8
ATTR_DEP extern u8* JAE8( u8 to ); ATTR_DEP extern u8 *JAE8(u8 to);
// jb rel8 // jb rel8
ATTR_DEP extern u8* JB8( u8 to ); ATTR_DEP extern u8 *JB8(u8 to);
// jbe rel8 // jbe rel8
ATTR_DEP extern u8* JBE8( u8 to ); ATTR_DEP extern u8 *JBE8(u8 to);
// jle rel8 // jle rel8
ATTR_DEP extern u8* JLE8( u8 to ); ATTR_DEP extern u8 *JLE8(u8 to);
// jne rel8 // jne rel8
ATTR_DEP extern u8* JNE8( u8 to ); ATTR_DEP extern u8 *JNE8(u8 to);
// jnz rel8 // jnz rel8
ATTR_DEP extern u8* JNZ8( u8 to ); ATTR_DEP extern u8 *JNZ8(u8 to);
// jng rel8 // jng rel8
ATTR_DEP extern u8* JNG8( u8 to ); ATTR_DEP extern u8 *JNG8(u8 to);
// jnge rel8 // jnge rel8
ATTR_DEP extern u8* JNGE8( u8 to ); ATTR_DEP extern u8 *JNGE8(u8 to);
// jnl rel8 // jnl rel8
ATTR_DEP extern u8* JNL8( u8 to ); ATTR_DEP extern u8 *JNL8(u8 to);
// jnle rel8 // jnle rel8
ATTR_DEP extern u8* JNLE8( u8 to ); ATTR_DEP extern u8 *JNLE8(u8 to);
// jo rel8 // jo rel8
ATTR_DEP extern u8* JO8( u8 to ); ATTR_DEP extern u8 *JO8(u8 to);
// jno rel8 // jno rel8
ATTR_DEP extern u8* JNO8( u8 to ); ATTR_DEP extern u8 *JNO8(u8 to);
/* /*
// jb rel16 // jb rel16
@ -103,51 +103,51 @@ ATTR_DEP extern u16* JZ16( u16 to );
*/ */
// jns rel32 // jns rel32
ATTR_DEP extern u32* JNS32( u32 to ); ATTR_DEP extern u32 *JNS32(u32 to);
// js rel32 // js rel32
ATTR_DEP extern u32* JS32( u32 to ); ATTR_DEP extern u32 *JS32(u32 to);
// jb rel32 // jb rel32
ATTR_DEP extern u32* JB32( u32 to ); ATTR_DEP extern u32 *JB32(u32 to);
// je rel32 // je rel32
ATTR_DEP extern u32* JE32( u32 to ); ATTR_DEP extern u32 *JE32(u32 to);
// jz rel32 // jz rel32
ATTR_DEP extern u32* JZ32( u32 to ); ATTR_DEP extern u32 *JZ32(u32 to);
// jg rel32 // jg rel32
ATTR_DEP extern u32* JG32( u32 to ); ATTR_DEP extern u32 *JG32(u32 to);
// jge rel32 // jge rel32
ATTR_DEP extern u32* JGE32( u32 to ); ATTR_DEP extern u32 *JGE32(u32 to);
// jl rel32 // jl rel32
ATTR_DEP extern u32* JL32( u32 to ); ATTR_DEP extern u32 *JL32(u32 to);
// jle rel32 // jle rel32
ATTR_DEP extern u32* JLE32( u32 to ); ATTR_DEP extern u32 *JLE32(u32 to);
// jae rel32 // jae rel32
ATTR_DEP extern u32* JAE32( u32 to ); ATTR_DEP extern u32 *JAE32(u32 to);
// jne rel32 // jne rel32
ATTR_DEP extern u32* JNE32( u32 to ); ATTR_DEP extern u32 *JNE32(u32 to);
// jnz rel32 // jnz rel32
ATTR_DEP extern u32* JNZ32( u32 to ); ATTR_DEP extern u32 *JNZ32(u32 to);
// jng rel32 // jng rel32
ATTR_DEP extern u32* JNG32( u32 to ); ATTR_DEP extern u32 *JNG32(u32 to);
// jnge rel32 // jnge rel32
ATTR_DEP extern u32* JNGE32( u32 to ); ATTR_DEP extern u32 *JNGE32(u32 to);
// jnl rel32 // jnl rel32
ATTR_DEP extern u32* JNL32( u32 to ); ATTR_DEP extern u32 *JNL32(u32 to);
// jnle rel32 // jnle rel32
ATTR_DEP extern u32* JNLE32( u32 to ); ATTR_DEP extern u32 *JNLE32(u32 to);
// jo rel32 // jo rel32
ATTR_DEP extern u32* JO32( u32 to ); ATTR_DEP extern u32 *JO32(u32 to);
// jno rel32 // jno rel32
ATTR_DEP extern u32* JNO32( u32 to ); ATTR_DEP extern u32 *JNO32(u32 to);
// js rel32 // js rel32
ATTR_DEP extern u32* JS32( u32 to ); ATTR_DEP extern u32 *JS32(u32 to);
//****************** //******************
// FPU instructions // FPU instructions
//****************** //******************
// fld m32 to fpu reg stack // fld m32 to fpu reg stack
ATTR_DEP extern void FLD32( u32 from ); ATTR_DEP extern void FLD32(u32 from);
// fld st(i) // fld st(i)
ATTR_DEP extern void FLD(int st); ATTR_DEP extern void FLD(int st);
// fld1 (push +1.0f on the stack) // fld1 (push +1.0f on the stack)
@ -155,7 +155,7 @@ ATTR_DEP extern void FLD1();
// fld1 (push log_2 e on the stack) // fld1 (push log_2 e on the stack)
ATTR_DEP extern void FLDL2E(); ATTR_DEP extern void FLDL2E();
// fstp m32 from fpu reg stack // fstp m32 from fpu reg stack
ATTR_DEP extern void FSTP32( u32 to ); ATTR_DEP extern void FSTP32(u32 to);
// fstp st(i) // fstp st(i)
ATTR_DEP extern void FSTP(int st); ATTR_DEP extern void FSTP(int st);
@ -166,32 +166,32 @@ ATTR_DEP extern void F2XM1();
ATTR_DEP extern void FSCALE(); ATTR_DEP extern void FSCALE();
// fadd ST(0) to fpu reg stack ST(src) // fadd ST(0) to fpu reg stack ST(src)
ATTR_DEP extern void FADD320toR( x86IntRegType src ); ATTR_DEP extern void FADD320toR(x86IntRegType src);
// fsub ST(src) to fpu reg stack ST(0) // fsub ST(src) to fpu reg stack ST(0)
ATTR_DEP extern void FSUB32Rto0( x86IntRegType src ); ATTR_DEP extern void FSUB32Rto0(x86IntRegType src);
// fmul m32 to fpu reg stack // fmul m32 to fpu reg stack
ATTR_DEP extern void FMUL32( u32 from ); ATTR_DEP extern void FMUL32(u32 from);
// fdiv m32 to fpu reg stack // fdiv m32 to fpu reg stack
ATTR_DEP extern void FDIV32( u32 from ); ATTR_DEP extern void FDIV32(u32 from);
// ftan fpu reg stack // ftan fpu reg stack
ATTR_DEP extern void FPATAN( void ); ATTR_DEP extern void FPATAN(void);
// fsin fpu reg stack // fsin fpu reg stack
ATTR_DEP extern void FSIN( void ); ATTR_DEP extern void FSIN(void);
//********************* //*********************
// SSE instructions * // SSE instructions *
//********************* //*********************
ATTR_DEP extern void SSE_MAXSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); ATTR_DEP extern void SSE_MAXSS_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
ATTR_DEP extern void SSE_MINSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); ATTR_DEP extern void SSE_MINSS_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
ATTR_DEP extern void SSE_ADDSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); ATTR_DEP extern void SSE_ADDSS_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
ATTR_DEP extern void SSE_SUBSS_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); ATTR_DEP extern void SSE_SUBSS_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
//********************* //*********************
// SSE 2 Instructions* // SSE 2 Instructions*
//********************* //*********************
ATTR_DEP extern void SSE2_MAXSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); ATTR_DEP extern void SSE2_MAXSD_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
ATTR_DEP extern void SSE2_MINSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); ATTR_DEP extern void SSE2_MINSD_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
ATTR_DEP extern void SSE2_ADDSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); ATTR_DEP extern void SSE2_ADDSD_XMM_to_XMM(x86SSERegType to, x86SSERegType from);
ATTR_DEP extern void SSE2_SUBSD_XMM_to_XMM( x86SSERegType to, x86SSERegType from ); ATTR_DEP extern void SSE2_SUBSD_XMM_to_XMM(x86SSERegType to, x86SSERegType from);

View File

@ -31,11 +31,10 @@ using x86Emitter::xWrite64;
#include "legacy_types.h" #include "legacy_types.h"
#include "legacy_instructions.h" #include "legacy_instructions.h"
#define MEMADDR(addr, oplen) (addr) #define MEMADDR(addr, oplen) (addr)
extern void ModRM( uint mod, uint reg, uint rm );
extern void SibSB( uint ss, uint index, uint base );
extern void SET8R( int cc, int to );
extern u8* J8Rel( int cc, int to );
extern u32* J32Rel( int cc, u32 to );
extern void ModRM(uint mod, uint reg, uint rm);
extern void SibSB(uint ss, uint index, uint base);
extern void SET8R(int cc, int to);
extern u8 *J8Rel(int cc, int to);
extern u32 *J32Rel(int cc, u32 to);

View File

@ -17,7 +17,7 @@
//#define SIB 4 // maps to ESP //#define SIB 4 // maps to ESP
//#define SIBDISP 5 // maps to EBP //#define SIBDISP 5 // maps to EBP
#define DISP32 5 // maps to EBP #define DISP32 5 // maps to EBP
// general types // general types
typedef int x86IntRegType; typedef int x86IntRegType;

View File

@ -17,11 +17,10 @@
#include "x86emitter.h" #include "x86emitter.h"
enum x86VendorType enum x86VendorType {
{ x86Vendor_Intel = 0,
x86Vendor_Intel = 0, x86Vendor_AMD = 1,
x86Vendor_AMD = 1, x86Vendor_Unknown = 2
x86Vendor_Unknown = 2
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -30,110 +29,111 @@ enum x86VendorType
class x86capabilities class x86capabilities
{ {
public: public:
bool isIdentified; bool isIdentified;
public: public:
x86VendorType VendorID; x86VendorType VendorID;
uint FamilyID; // Processor Family uint FamilyID; // Processor Family
uint Model; // Processor Model uint Model; // Processor Model
uint TypeID; // Processor Type uint TypeID; // Processor Type
uint StepID; // Stepping ID uint StepID; // Stepping ID
u32 Flags; // Feature Flags u32 Flags; // Feature Flags
u32 Flags2; // More Feature Flags u32 Flags2; // More Feature Flags
u32 EFlags; // Extended Feature Flags u32 EFlags; // Extended Feature Flags
u32 EFlags2; // Extended Feature Flags pg2 u32 EFlags2; // Extended Feature Flags pg2
u32 SEFlag; // Structured Extended Feature Flags Enumeration u32 SEFlag; // Structured Extended Feature Flags Enumeration
char VendorName[16]; // Vendor/Creator ID char VendorName[16]; // Vendor/Creator ID
char FamilyName[50]; // the original cpu name char FamilyName[50]; // the original cpu name
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// x86 CPU Capabilities Section (all boolean flags!) // x86 CPU Capabilities Section (all boolean flags!)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
union { union
struct { {
u32 hasFloatingPointUnit :1; struct
u32 hasVirtual8086ModeEnhancements :1; {
u32 hasDebuggingExtensions :1; u32 hasFloatingPointUnit : 1;
u32 hasPageSizeExtensions :1; u32 hasVirtual8086ModeEnhancements : 1;
u32 hasTimeStampCounter :1; u32 hasDebuggingExtensions : 1;
u32 hasModelSpecificRegisters :1; u32 hasPageSizeExtensions : 1;
u32 hasPhysicalAddressExtension :1; u32 hasTimeStampCounter : 1;
u32 hasCOMPXCHG8BInstruction :1; u32 hasModelSpecificRegisters : 1;
u32 hasAdvancedProgrammableInterruptController :1; u32 hasPhysicalAddressExtension : 1;
u32 hasSEPFastSystemCall :1; u32 hasCOMPXCHG8BInstruction : 1;
u32 hasMemoryTypeRangeRegisters :1; u32 hasAdvancedProgrammableInterruptController : 1;
u32 hasPTEGlobalFlag :1; u32 hasSEPFastSystemCall : 1;
u32 hasMachineCheckArchitecture :1; u32 hasMemoryTypeRangeRegisters : 1;
u32 hasConditionalMoveAndCompareInstructions :1; u32 hasPTEGlobalFlag : 1;
u32 hasFGPageAttributeTable :1; u32 hasMachineCheckArchitecture : 1;
u32 has36bitPageSizeExtension :1; u32 hasConditionalMoveAndCompareInstructions : 1;
u32 hasProcessorSerialNumber :1; u32 hasFGPageAttributeTable : 1;
u32 hasCFLUSHInstruction :1; u32 has36bitPageSizeExtension : 1;
u32 hasDebugStore :1; u32 hasProcessorSerialNumber : 1;
u32 hasACPIThermalMonitorAndClockControl :1; u32 hasCFLUSHInstruction : 1;
u32 hasFastStreamingSIMDExtensionsSaveRestore :1; u32 hasDebugStore : 1;
u32 hasStreamingSIMDExtensions :1; u32 hasACPIThermalMonitorAndClockControl : 1;
u32 hasStreamingSIMD2Extensions :1; u32 hasFastStreamingSIMDExtensionsSaveRestore : 1;
u32 hasSelfSnoop :1; u32 hasStreamingSIMDExtensions : 1;
u32 hasStreamingSIMD2Extensions : 1;
u32 hasSelfSnoop : 1;
// is TRUE for both multi-core and Hyperthreaded CPUs. // is TRUE for both multi-core and Hyperthreaded CPUs.
u32 hasMultiThreading :1; u32 hasMultiThreading : 1;
u32 hasThermalMonitor :1; u32 hasThermalMonitor : 1;
u32 hasIntel64BitArchitecture :1; u32 hasIntel64BitArchitecture : 1;
u32 hasStreamingSIMD3Extensions :1; u32 hasStreamingSIMD3Extensions : 1;
u32 hasSupplementalStreamingSIMD3Extensions :1; u32 hasSupplementalStreamingSIMD3Extensions : 1;
u32 hasStreamingSIMD4Extensions :1; u32 hasStreamingSIMD4Extensions : 1;
u32 hasStreamingSIMD4Extensions2 :1; u32 hasStreamingSIMD4Extensions2 : 1;
u32 hasAVX :1; u32 hasAVX : 1;
u32 hasAVX2 :1; u32 hasAVX2 : 1;
u32 hasBMI1 :1; u32 hasBMI1 : 1;
u32 hasBMI2 :1; u32 hasBMI2 : 1;
u32 hasFMA :1; u32 hasFMA : 1;
// AMD-specific CPU Features // AMD-specific CPU Features
u32 hasAMD64BitArchitecture :1; u32 hasAMD64BitArchitecture : 1;
u32 hasStreamingSIMD4ExtensionsA :1; u32 hasStreamingSIMD4ExtensionsA : 1;
}; };
u64 AllCapabilities; u64 AllCapabilities;
}; };
// Core Counts! // Core Counts!
u32 PhysicalCores; u32 PhysicalCores;
u32 LogicalCores; u32 LogicalCores;
public: public:
x86capabilities(); x86capabilities();
void Identify(); void Identify();
void CountCores(); void CountCores();
wxString GetTypeName() const; wxString GetTypeName() const;
u32 CalculateMHz() const; u32 CalculateMHz() const;
void SIMD_EstablishMXCSRmask(); void SIMD_EstablishMXCSRmask();
protected: protected:
s64 _CPUSpeedHz( u64 time ) const; s64 _CPUSpeedHz(u64 time) const;
void CountLogicalCores(); void CountLogicalCores();
}; };
enum SSE_RoundMode enum SSE_RoundMode {
{ SSE_RoundMode_FIRST = 0,
SSE_RoundMode_FIRST = 0, SSEround_Nearest = 0,
SSEround_Nearest = 0, SSEround_NegInf,
SSEround_NegInf, SSEround_PosInf,
SSEround_PosInf, SSEround_Chop,
SSEround_Chop, SSE_RoundMode_COUNT
SSE_RoundMode_COUNT
}; };
ImplementEnumOperators( SSE_RoundMode ); ImplementEnumOperators(SSE_RoundMode);
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// SSE_MXCSR - Control/Status Register (bitfield) // SSE_MXCSR - Control/Status Register (bitfield)
@ -147,56 +147,55 @@ ImplementEnumOperators( SSE_RoundMode );
// //
union SSE_MXCSR union SSE_MXCSR
{ {
u32 bitmask; u32 bitmask;
struct struct
{ {
u32 u32
InvalidOpFlag :1, InvalidOpFlag : 1,
DenormalFlag :1, DenormalFlag : 1,
DivideByZeroFlag :1, DivideByZeroFlag : 1,
OverflowFlag :1, OverflowFlag : 1,
UnderflowFlag :1, UnderflowFlag : 1,
PrecisionFlag :1, PrecisionFlag : 1,
// This bit is supported only on SSE2 or better CPUs. Setting it to 1 on // This bit is supported only on SSE2 or better CPUs. Setting it to 1 on
// SSE1 cpus will result in an invalid instruction exception when executing // SSE1 cpus will result in an invalid instruction exception when executing
// LDMXSCR. // LDMXSCR.
DenormalsAreZero :1, DenormalsAreZero : 1,
InvalidOpMask :1, InvalidOpMask : 1,
DenormalMask :1, DenormalMask : 1,
DivideByZeroMask :1, DivideByZeroMask : 1,
OverflowMask :1, OverflowMask : 1,
UnderflowMask :1, UnderflowMask : 1,
PrecisionMask :1, PrecisionMask : 1,
RoundingControl :2, RoundingControl : 2,
FlushToZero :1; FlushToZero : 1;
}; };
SSE_RoundMode GetRoundMode() const; SSE_RoundMode GetRoundMode() const;
SSE_MXCSR& SetRoundMode( SSE_RoundMode mode ); SSE_MXCSR &SetRoundMode(SSE_RoundMode mode);
SSE_MXCSR& ClearExceptionFlags(); SSE_MXCSR &ClearExceptionFlags();
SSE_MXCSR& EnableExceptions(); SSE_MXCSR &EnableExceptions();
SSE_MXCSR& DisableExceptions(); SSE_MXCSR &DisableExceptions();
SSE_MXCSR& ApplyReserveMask(); SSE_MXCSR &ApplyReserveMask();
bool operator ==( const SSE_MXCSR& right ) const bool operator==(const SSE_MXCSR &right) const
{ {
return bitmask == right.bitmask; return bitmask == right.bitmask;
} }
bool operator !=( const SSE_MXCSR& right ) const bool operator!=(const SSE_MXCSR &right) const
{ {
return bitmask != right.bitmask; return bitmask != right.bitmask;
} }
operator x86Emitter::xIndirect32() const; operator x86Emitter::xIndirect32() const;
}; };
extern SSE_MXCSR MXCSR_Mask; extern SSE_MXCSR MXCSR_Mask;
extern __aligned16 x86capabilities x86caps; extern __aligned16 x86capabilities x86caps;

View File

@ -32,26 +32,30 @@
// CPU information support // CPU information support
#if defined(_WIN32) #if defined(_WIN32)
#define cpuid __cpuid #define cpuid __cpuid
#define cpuidex __cpuidex #define cpuidex __cpuidex
#else #else
#include <cpuid.h> #include <cpuid.h>
static __inline__ __attribute__((always_inline)) void cpuidex(int CPUInfo[], const int InfoType, const int count) { static __inline__ __attribute__((always_inline)) void cpuidex(int CPUInfo[], const int InfoType, const int count)
__cpuid_count(InfoType, count, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]); {
__cpuid_count(InfoType, count, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);
} }
static __inline__ __attribute__((always_inline)) void cpuid(int CPUInfo[], const int InfoType) { static __inline__ __attribute__((always_inline)) void cpuid(int CPUInfo[], const int InfoType)
__cpuid(InfoType, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]); {
__cpuid(InfoType, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);
} }
static __inline__ __attribute__((always_inline)) unsigned long long _xgetbv(unsigned int index) static __inline__ __attribute__((always_inline)) unsigned long long _xgetbv(unsigned int index)
{ {
unsigned int eax, edx; unsigned int eax, edx;
__asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index)); __asm__ __volatile__("xgetbv"
return ((unsigned long long)edx << 32) | eax; : "=a"(eax), "=d"(edx)
: "c"(index));
return ((unsigned long long)edx << 32) | eax;
} }
#endif #endif
@ -61,16 +65,16 @@ static __inline__ __attribute__((always_inline)) unsigned long long _xgetbv(unsi
// Seriously what is so complicated to provided this bunch of intrinsics in clangs. // Seriously what is so complicated to provided this bunch of intrinsics in clangs.
static unsigned int _rotr(unsigned int x, int s) static unsigned int _rotr(unsigned int x, int s)
{ {
return (x >> s) | (x << (32 - s)); return (x >> s) | (x << (32 - s));
} }
static unsigned int _rotl(unsigned int x, int s) static unsigned int _rotl(unsigned int x, int s)
{ {
return (x << s) | (x >> (32 - s)); return (x << s) | (x >> (32 - s));
} }
#endif #endif
// Not correctly defined in GCC4.8 and below ! (dunno for VS) // Not correctly defined in GCC4.8 and below ! (dunno for VS)
#ifndef _MM_MK_INSERTPS_NDX #ifndef _MM_MK_INSERTPS_NDX
#define _MM_MK_INSERTPS_NDX(srcField, dstField, zeroMask) (((srcField)<<6) | ((dstField)<<4) | (zeroMask)) #define _MM_MK_INSERTPS_NDX(srcField, dstField, zeroMask) (((srcField) << 6) | ((dstField) << 4) | (zeroMask))
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -18,32 +18,32 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
void* __fastcall _aligned_malloc(size_t size, size_t align) void *__fastcall _aligned_malloc(size_t size, size_t align)
{ {
pxAssert( align < 0x10000 ); pxAssert(align < 0x10000);
#if defined(__USE_ISOC11) && !defined(ASAN_WORKAROUND) // not supported yet on gcc 4.9 #if defined(__USE_ISOC11) && !defined(ASAN_WORKAROUND) // not supported yet on gcc 4.9
return aligned_alloc(align, size); return aligned_alloc(align, size);
#else #else
void *result = 0; void *result = 0;
posix_memalign(&result, align, size); posix_memalign(&result, align, size);
return result; return result;
#endif #endif
} }
void* __fastcall pcsx2_aligned_realloc(void* handle, size_t new_size, size_t align, size_t old_size) void *__fastcall pcsx2_aligned_realloc(void *handle, size_t new_size, size_t align, size_t old_size)
{ {
pxAssert( align < 0x10000 ); pxAssert(align < 0x10000);
void* newbuf = _aligned_malloc(new_size, align); void *newbuf = _aligned_malloc(new_size, align);
if (newbuf != NULL && handle != NULL) { if (newbuf != NULL && handle != NULL) {
memcpy(newbuf, handle, std::min(old_size, new_size)); memcpy(newbuf, handle, std::min(old_size, new_size));
_aligned_free(handle); _aligned_free(handle);
} }
return newbuf; return newbuf;
} }
__fi void _aligned_free(void* pmem) __fi void _aligned_free(void *pmem)
{ {
free(pmem); free(pmem);
} }

View File

@ -16,62 +16,61 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "CheckedStaticBox.h" #include "CheckedStaticBox.h"
CheckedStaticBox::CheckedStaticBox( wxWindow* parent, int orientation, const wxString& title ) CheckedStaticBox::CheckedStaticBox(wxWindow *parent, int orientation, const wxString &title)
: wxPanelWithHelpers( parent, wxVERTICAL ) : wxPanelWithHelpers(parent, wxVERTICAL)
, ThisSizer( *new wxStaticBoxSizer( orientation, this ) ) , ThisSizer(*new wxStaticBoxSizer(orientation, this))
, ThisToggle( *new wxCheckBox( this, wxID_ANY, title, wxPoint( 8, 0 ) ) ) , ThisToggle(*new wxCheckBox(this, wxID_ANY, title, wxPoint(8, 0)))
{ {
*this += ThisToggle; *this += ThisToggle;
*this += ThisSizer | pxExpand; *this += ThisSizer | pxExpand;
// Ensure that the right-side of the static group box isn't too cozy: // Ensure that the right-side of the static group box isn't too cozy:
SetMinWidth( ThisToggle.GetSize().GetWidth() + 32 ); SetMinWidth(ThisToggle.GetSize().GetWidth() + 32);
Bind(wxEVT_CHECKBOX, &CheckedStaticBox::MainToggle_Click, this, ThisToggle.GetId()); Bind(wxEVT_CHECKBOX, &CheckedStaticBox::MainToggle_Click, this, ThisToggle.GetId());
} }
// Event handler for click events for the main checkbox (default behavior: enables/disables all child controls) // Event handler for click events for the main checkbox (default behavior: enables/disables all child controls)
// This function can be overridden to implement custom handling of check enable/disable behavior. // This function can be overridden to implement custom handling of check enable/disable behavior.
void CheckedStaticBox::MainToggle_Click( wxCommandEvent& evt ) void CheckedStaticBox::MainToggle_Click(wxCommandEvent &evt)
{ {
SetValue( evt.IsChecked() ); SetValue(evt.IsChecked());
} }
// Sets the main checkbox status, and enables/disables all child controls // Sets the main checkbox status, and enables/disables all child controls
// bound to the StaticBox accordingly. // bound to the StaticBox accordingly.
void CheckedStaticBox::SetValue( bool val ) void CheckedStaticBox::SetValue(bool val)
{ {
wxWindowList& list = GetChildren(); wxWindowList &list = GetChildren();
for( wxWindowList::iterator iter = list.begin(); iter != list.end(); ++iter) for (wxWindowList::iterator iter = list.begin(); iter != list.end(); ++iter) {
{ wxWindow *current = *iter;
wxWindow *current = *iter; if (current != &ThisToggle)
if( current != &ThisToggle ) current->Enable(val);
current->Enable( val ); }
} ThisToggle.SetValue(val);
ThisToggle.SetValue( val );
} }
bool CheckedStaticBox::GetValue() const bool CheckedStaticBox::GetValue() const
{ {
return ThisToggle.GetValue(); return ThisToggle.GetValue();
} }
// This override is here so to only enable the children if both the main toggle and // This override is here so to only enable the children if both the main toggle and
// the enable request are true. If not, disable them! // the enable request are true. If not, disable them!
bool CheckedStaticBox::Enable( bool enable ) bool CheckedStaticBox::Enable(bool enable)
{ {
if (!_parent::Enable(enable)) return false; if (!_parent::Enable(enable))
return false;
bool val = enable && ThisToggle.GetValue(); bool val = enable && ThisToggle.GetValue();
wxWindowList& list = GetChildren(); wxWindowList &list = GetChildren();
for( wxWindowList::iterator iter = list.begin(); iter != list.end(); ++iter) for (wxWindowList::iterator iter = list.begin(); iter != list.end(); ++iter) {
{ wxWindow *current = *iter;
wxWindow *current = *iter; if (current != &ThisToggle)
if( current != &ThisToggle ) current->Enable(val);
current->Enable( val ); }
}
return true; return true;
} }

View File

@ -18,22 +18,22 @@
#include "TraceLog.h" #include "TraceLog.h"
#include "TlsVariable.inl" #include "TlsVariable.inl"
#include "RedtapeWindows.h" // nneded for OutputDebugString #include "RedtapeWindows.h" // nneded for OutputDebugString
using namespace Threading; using namespace Threading;
// thread-local console indentation setting. // thread-local console indentation setting.
static DeclareTls(int) conlog_Indent( 0 ); static DeclareTls(int) conlog_Indent(0);
// thread-local console color storage. // thread-local console color storage.
static DeclareTls(ConsoleColors) conlog_Color( DefaultConsoleColor ); static DeclareTls(ConsoleColors) conlog_Color(DefaultConsoleColor);
#ifdef __POSIX__ #ifdef __POSIX__
static FILE *stdout_fp = stdout; static FILE *stdout_fp = stdout;
void Console_SetStdout(FILE *fp) void Console_SetStdout(FILE *fp)
{ {
stdout_fp = fp; stdout_fp = fp;
} }
#endif #endif
@ -44,33 +44,33 @@ void Console_SetStdout(FILE *fp)
// Important! Only Assert and Null console loggers are allowed during C++ startup init (when // Important! Only Assert and Null console loggers are allowed during C++ startup init (when
// the program or DLL first loads). Other log targets rely on the static buffer and a // the program or DLL first loads). Other log targets rely on the static buffer and a
// threaded mutex lock, which are only valid after C++ initialization has finished. // threaded mutex lock, which are only valid after C++ initialization has finished.
void Console_SetActiveHandler( const IConsoleWriter& writer, FILE* flushfp ) void Console_SetActiveHandler(const IConsoleWriter &writer, FILE *flushfp)
{ {
pxAssertDev( pxAssertDev(
(writer.WriteRaw != NULL) && (writer.DoWriteLn != NULL) && (writer.WriteRaw != NULL) && (writer.DoWriteLn != NULL) &&
(writer.Newline != NULL) && (writer.SetTitle != NULL) && (writer.Newline != NULL) && (writer.SetTitle != NULL) &&
(writer.DoSetColor != NULL), (writer.DoSetColor != NULL),
"Invalid IConsoleWriter object! All function pointer interfaces must be implemented." "Invalid IConsoleWriter object! All function pointer interfaces must be implemented.");
);
Console = writer; Console = writer;
DevConWriter = writer; DevConWriter = writer;
#ifdef PCSX2_DEBUG #ifdef PCSX2_DEBUG
DbgCon = writer; DbgCon = writer;
#endif #endif
} }
// Writes text to the Visual Studio Output window (Microsoft Windows only). // Writes text to the Visual Studio Output window (Microsoft Windows only).
// On all other platforms this pipes to Stdout instead. // On all other platforms this pipes to Stdout instead.
void MSW_OutputDebugString( const wxString& text ) void MSW_OutputDebugString(const wxString &text)
{ {
#if defined(__WXMSW__) && !defined(__WXMICROWIN__) #if defined(__WXMSW__) && !defined(__WXMICROWIN__)
static bool hasDebugger = wxIsDebuggerRunning(); static bool hasDebugger = wxIsDebuggerRunning();
if( hasDebugger ) OutputDebugString( text ); if (hasDebugger)
OutputDebugString(text);
#else #else
fputs(text.utf8_str(), stdout_fp); fputs(text.utf8_str(), stdout_fp);
fflush(stdout_fp); fflush(stdout_fp);
#endif #endif
} }
@ -79,23 +79,23 @@ void MSW_OutputDebugString( const wxString& text )
// ConsoleNull // ConsoleNull
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
static void __concall ConsoleNull_SetTitle( const wxString& title ) {} static void __concall ConsoleNull_SetTitle(const wxString &title) {}
static void __concall ConsoleNull_DoSetColor( ConsoleColors color ) {} static void __concall ConsoleNull_DoSetColor(ConsoleColors color) {}
static void __concall ConsoleNull_Newline() {} static void __concall ConsoleNull_Newline() {}
static void __concall ConsoleNull_DoWrite( const wxString& fmt ) {} static void __concall ConsoleNull_DoWrite(const wxString &fmt) {}
static void __concall ConsoleNull_DoWriteLn( const wxString& fmt ) {} static void __concall ConsoleNull_DoWriteLn(const wxString &fmt) {}
const IConsoleWriter ConsoleWriter_Null = const IConsoleWriter ConsoleWriter_Null =
{ {
ConsoleNull_DoWrite, ConsoleNull_DoWrite,
ConsoleNull_DoWriteLn, ConsoleNull_DoWriteLn,
ConsoleNull_DoSetColor, ConsoleNull_DoSetColor,
ConsoleNull_DoWrite, ConsoleNull_DoWrite,
ConsoleNull_Newline, ConsoleNull_Newline,
ConsoleNull_SetTitle, ConsoleNull_SetTitle,
0, // instance-level indentation (should always be 0) 0, // instance-level indentation (should always be 0)
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -103,118 +103,133 @@ const IConsoleWriter ConsoleWriter_Null =
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
#if defined(__unix__) #if defined(__unix__)
static __fi const char* GetLinuxConsoleColor(ConsoleColors color) static __fi const char *GetLinuxConsoleColor(ConsoleColors color)
{ {
switch(color) switch (color) {
{
case Color_Black: case Color_Black:
case Color_StrongBlack: return "\033[30m\033[1m"; case Color_StrongBlack:
return "\033[30m\033[1m";
case Color_Red: return "\033[31m"; case Color_Red:
case Color_StrongRed: return "\033[31m\033[1m"; return "\033[31m";
case Color_StrongRed:
return "\033[31m\033[1m";
case Color_Green: return "\033[32m"; case Color_Green:
case Color_StrongGreen: return "\033[32m\033[1m"; return "\033[32m";
case Color_StrongGreen:
return "\033[32m\033[1m";
case Color_Yellow: return "\033[33m"; case Color_Yellow:
case Color_StrongYellow: return "\033[33m\033[1m"; return "\033[33m";
case Color_StrongYellow:
return "\033[33m\033[1m";
case Color_Blue: return "\033[34m"; case Color_Blue:
case Color_StrongBlue: return "\033[34m\033[1m"; return "\033[34m";
case Color_StrongBlue:
return "\033[34m\033[1m";
// No orange, so use magenta. // No orange, so use magenta.
case Color_Orange: case Color_Orange:
case Color_Magenta: return "\033[35m"; case Color_Magenta:
return "\033[35m";
case Color_StrongOrange: case Color_StrongOrange:
case Color_StrongMagenta: return "\033[35m\033[1m"; case Color_StrongMagenta:
return "\033[35m\033[1m";
case Color_Cyan: return "\033[36m"; case Color_Cyan:
case Color_StrongCyan: return "\033[36m\033[1m"; return "\033[36m";
case Color_StrongCyan:
return "\033[36m\033[1m";
// Use 'white' instead of grey. // Use 'white' instead of grey.
case Color_Gray: case Color_Gray:
case Color_White: return "\033[37m"; case Color_White:
return "\033[37m";
case Color_StrongGray: case Color_StrongGray:
case Color_StrongWhite: return "\033[37m\033[1m"; case Color_StrongWhite:
return "\033[37m\033[1m";
// On some other value being passed, clear any formatting. // On some other value being passed, clear any formatting.
case Color_Default: case Color_Default:
default: return "\033[0m"; default:
return "\033[0m";
} }
} }
#endif #endif
// One possible default write action at startup and shutdown is to use the stdout. // One possible default write action at startup and shutdown is to use the stdout.
static void __concall ConsoleStdout_DoWrite( const wxString& fmt ) static void __concall ConsoleStdout_DoWrite(const wxString &fmt)
{ {
MSW_OutputDebugString( fmt ); MSW_OutputDebugString(fmt);
} }
// Default write action at startup and shutdown is to use the stdout. // Default write action at startup and shutdown is to use the stdout.
static void __concall ConsoleStdout_DoWriteLn( const wxString& fmt ) static void __concall ConsoleStdout_DoWriteLn(const wxString &fmt)
{ {
MSW_OutputDebugString( fmt + L"\n" ); MSW_OutputDebugString(fmt + L"\n");
} }
static void __concall ConsoleStdout_Newline() static void __concall ConsoleStdout_Newline()
{ {
MSW_OutputDebugString( L"\n" ); MSW_OutputDebugString(L"\n");
} }
static void __concall ConsoleStdout_DoSetColor( ConsoleColors color ) static void __concall ConsoleStdout_DoSetColor(ConsoleColors color)
{ {
#if defined(__unix__) #if defined(__unix__)
fprintf(stdout_fp, "\033[0m%s", GetLinuxConsoleColor(color)); fprintf(stdout_fp, "\033[0m%s", GetLinuxConsoleColor(color));
fflush(stdout_fp); fflush(stdout_fp);
#endif #endif
} }
static void __concall ConsoleStdout_SetTitle( const wxString& title ) static void __concall ConsoleStdout_SetTitle(const wxString &title)
{ {
#if defined(__unix__) #if defined(__unix__)
fputs("\033]0;", stdout_fp); fputs("\033]0;", stdout_fp);
fputs(title.utf8_str(), stdout_fp); fputs(title.utf8_str(), stdout_fp);
fputs("\007", stdout_fp); fputs("\007", stdout_fp);
#endif #endif
} }
const IConsoleWriter ConsoleWriter_Stdout = const IConsoleWriter ConsoleWriter_Stdout =
{ {
ConsoleStdout_DoWrite, // Writes without newlines go to buffer to avoid error log spam. ConsoleStdout_DoWrite, // Writes without newlines go to buffer to avoid error log spam.
ConsoleStdout_DoWriteLn, ConsoleStdout_DoWriteLn,
ConsoleStdout_DoSetColor, ConsoleStdout_DoSetColor,
ConsoleNull_DoWrite, // writes from re-piped stdout are ignored here, lest we create infinite loop hell >_< ConsoleNull_DoWrite, // writes from re-piped stdout are ignored here, lest we create infinite loop hell >_<
ConsoleStdout_Newline, ConsoleStdout_Newline,
ConsoleStdout_SetTitle, ConsoleStdout_SetTitle,
0, // instance-level indentation (should always be 0) 0, // instance-level indentation (should always be 0)
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ConsoleAssert // ConsoleAssert
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
static void __concall ConsoleAssert_DoWrite( const wxString& fmt ) static void __concall ConsoleAssert_DoWrite(const wxString &fmt)
{ {
pxFail( L"Console class has not been initialized; Message written:\n\t" + fmt ); pxFail(L"Console class has not been initialized; Message written:\n\t" + fmt);
} }
static void __concall ConsoleAssert_DoWriteLn( const wxString& fmt ) static void __concall ConsoleAssert_DoWriteLn(const wxString &fmt)
{ {
pxFail( L"Console class has not been initialized; Message written:\n\t" + fmt ); pxFail(L"Console class has not been initialized; Message written:\n\t" + fmt);
} }
const IConsoleWriter ConsoleWriter_Assert = const IConsoleWriter ConsoleWriter_Assert =
{ {
ConsoleAssert_DoWrite, ConsoleAssert_DoWrite,
ConsoleAssert_DoWriteLn, ConsoleAssert_DoWriteLn,
ConsoleNull_DoSetColor, ConsoleNull_DoSetColor,
ConsoleNull_DoWrite, ConsoleNull_DoWrite,
ConsoleNull_Newline, ConsoleNull_Newline,
ConsoleNull_SetTitle, ConsoleNull_SetTitle,
0, // instance-level indentation (should always be 0) 0, // instance-level indentation (should always be 0)
}; };
// ===================================================================================================== // =====================================================================================================
@ -227,214 +242,216 @@ const IConsoleWriter ConsoleWriter_Assert =
// glob_indent - this parameter is used to specify a global indentation setting. It is used by // glob_indent - this parameter is used to specify a global indentation setting. It is used by
// WriteLn function, but defaults to 0 for Warning and Error calls. Local indentation always // WriteLn function, but defaults to 0 for Warning and Error calls. Local indentation always
// applies to all writes. // applies to all writes.
wxString IConsoleWriter::_addIndentation( const wxString& src, int glob_indent=0 ) const wxString IConsoleWriter::_addIndentation(const wxString &src, int glob_indent = 0) const
{ {
const int indent = glob_indent + _imm_indentation; const int indent = glob_indent + _imm_indentation;
if( indent == 0 ) return src; if (indent == 0)
return src;
wxString result( src ); wxString result(src);
const wxString indentStr( L'\t', indent ); const wxString indentStr(L'\t', indent);
result.Replace( L"\n", L"\n" + indentStr ); result.Replace(L"\n", L"\n" + indentStr);
return indentStr + result; return indentStr + result;
} }
// Sets the indentation to be applied to all WriteLn's. The indentation is added to the // Sets the indentation to be applied to all WriteLn's. The indentation is added to the
// primary write, and to any newlines specified within the write. Note that this applies // primary write, and to any newlines specified within the write. Note that this applies
// to calls to WriteLn *only* -- calls to Write bypass the indentation parser. // to calls to WriteLn *only* -- calls to Write bypass the indentation parser.
const IConsoleWriter& IConsoleWriter::SetIndent( int tabcount ) const const IConsoleWriter &IConsoleWriter::SetIndent(int tabcount) const
{ {
conlog_Indent += tabcount; conlog_Indent += tabcount;
pxAssert( conlog_Indent >= 0 ); pxAssert(conlog_Indent >= 0);
return *this; return *this;
} }
IConsoleWriter IConsoleWriter::Indent( int tabcount ) const IConsoleWriter IConsoleWriter::Indent(int tabcount) const
{ {
IConsoleWriter retval = *this; IConsoleWriter retval = *this;
retval._imm_indentation = tabcount; retval._imm_indentation = tabcount;
return retval; return retval;
} }
// Changes the active console color. // Changes the active console color.
// This color will be unset by calls to colored text methods // This color will be unset by calls to colored text methods
// such as ErrorMsg and Notice. // such as ErrorMsg and Notice.
const IConsoleWriter& IConsoleWriter::SetColor( ConsoleColors color ) const const IConsoleWriter &IConsoleWriter::SetColor(ConsoleColors color) const
{ {
// Ignore current color requests since, well, the current color is already set. ;) // Ignore current color requests since, well, the current color is already set. ;)
if( color == Color_Current ) return *this; if (color == Color_Current)
return *this;
pxAssertMsg( (color > Color_Current) && (color < ConsoleColors_Count), "Invalid ConsoleColor specified." ); pxAssertMsg((color > Color_Current) && (color < ConsoleColors_Count), "Invalid ConsoleColor specified.");
if( conlog_Color != color ) if (conlog_Color != color)
DoSetColor( conlog_Color = color ); DoSetColor(conlog_Color = color);
return *this; return *this;
} }
ConsoleColors IConsoleWriter::GetColor() const ConsoleColors IConsoleWriter::GetColor() const
{ {
return conlog_Color; return conlog_Color;
} }
// Restores the console color to default (usually black, or low-intensity white if the console uses a black background) // Restores the console color to default (usually black, or low-intensity white if the console uses a black background)
const IConsoleWriter& IConsoleWriter::ClearColor() const const IConsoleWriter &IConsoleWriter::ClearColor() const
{ {
if( conlog_Color != DefaultConsoleColor ) if (conlog_Color != DefaultConsoleColor)
DoSetColor( conlog_Color = DefaultConsoleColor ); DoSetColor(conlog_Color = DefaultConsoleColor);
return *this; return *this;
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ASCII/UTF8 (char*) // ASCII/UTF8 (char*)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
bool IConsoleWriter::FormatV( const char* fmt, va_list args ) const bool IConsoleWriter::FormatV(const char *fmt, va_list args) const
{ {
DoWriteLn( _addIndentation( pxsFmtV(fmt,args), conlog_Indent ) ); DoWriteLn(_addIndentation(pxsFmtV(fmt, args), conlog_Indent));
return false; return false;
} }
bool IConsoleWriter::WriteLn( const char* fmt, ... ) const bool IConsoleWriter::WriteLn(const char *fmt, ...) const
{ {
va_list args; va_list args;
va_start(args,fmt); va_start(args, fmt);
FormatV(fmt, args); FormatV(fmt, args);
va_end(args); va_end(args);
return false; return false;
} }
bool IConsoleWriter::WriteLn( ConsoleColors color, const char* fmt, ... ) const bool IConsoleWriter::WriteLn(ConsoleColors color, const char *fmt, ...) const
{ {
va_list args; va_list args;
va_start(args,fmt); va_start(args, fmt);
ConsoleColorScope cs( color ); ConsoleColorScope cs(color);
FormatV(fmt, args); FormatV(fmt, args);
va_end(args); va_end(args);
return false; return false;
} }
bool IConsoleWriter::Error( const char* fmt, ... ) const bool IConsoleWriter::Error(const char *fmt, ...) const
{ {
va_list args; va_list args;
va_start(args,fmt); va_start(args, fmt);
ConsoleColorScope cs( Color_StrongRed ); ConsoleColorScope cs(Color_StrongRed);
FormatV(fmt, args); FormatV(fmt, args);
va_end(args); va_end(args);
return false; return false;
} }
bool IConsoleWriter::Warning( const char* fmt, ... ) const bool IConsoleWriter::Warning(const char *fmt, ...) const
{ {
va_list args; va_list args;
va_start(args,fmt); va_start(args, fmt);
ConsoleColorScope cs( Color_StrongOrange ); ConsoleColorScope cs(Color_StrongOrange);
FormatV(fmt, args); FormatV(fmt, args);
va_end(args); va_end(args);
return false; return false;
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Write Variants - Unicode/UTF16 style // Write Variants - Unicode/UTF16 style
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
bool IConsoleWriter::FormatV( const wxChar* fmt, va_list args ) const bool IConsoleWriter::FormatV(const wxChar *fmt, va_list args) const
{ {
DoWriteLn( _addIndentation( pxsFmtV( fmt, args ), conlog_Indent ) ); DoWriteLn(_addIndentation(pxsFmtV(fmt, args), conlog_Indent));
return false; return false;
} }
bool IConsoleWriter::WriteLn( const wxChar* fmt, ... ) const bool IConsoleWriter::WriteLn(const wxChar *fmt, ...) const
{ {
va_list args; va_list args;
va_start(args,fmt); va_start(args, fmt);
FormatV(fmt,args); FormatV(fmt, args);
va_end(args); va_end(args);
return false; return false;
} }
bool IConsoleWriter::WriteLn( ConsoleColors color, const wxChar* fmt, ... ) const bool IConsoleWriter::WriteLn(ConsoleColors color, const wxChar *fmt, ...) const
{ {
va_list args; va_list args;
va_start(args,fmt); va_start(args, fmt);
ConsoleColorScope cs( color ); ConsoleColorScope cs(color);
FormatV(fmt,args); FormatV(fmt, args);
va_end(args); va_end(args);
return false; return false;
} }
bool IConsoleWriter::Error( const wxChar* fmt, ... ) const bool IConsoleWriter::Error(const wxChar *fmt, ...) const
{ {
va_list args; va_list args;
va_start(args,fmt); va_start(args, fmt);
ConsoleColorScope cs( Color_StrongRed ); ConsoleColorScope cs(Color_StrongRed);
FormatV(fmt,args); FormatV(fmt, args);
va_end(args); va_end(args);
return false; return false;
} }
bool IConsoleWriter::Warning( const wxChar* fmt, ... ) const bool IConsoleWriter::Warning(const wxChar *fmt, ...) const
{ {
va_list args; va_list args;
va_start(args,fmt); va_start(args, fmt);
ConsoleColorScope cs( Color_StrongOrange ); ConsoleColorScope cs(Color_StrongOrange);
FormatV(fmt,args); FormatV(fmt, args);
va_end(args); va_end(args);
return false; return false;
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Write Variants - Unknown style // Write Variants - Unknown style
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
bool IConsoleWriter::WriteLn( const wxString fmt, ... ) const bool IConsoleWriter::WriteLn(const wxString fmt, ...) const
{ {
va_list args; va_list args;
va_start(args,fmt); va_start(args, fmt);
FormatV(fmt.wx_str(),args); FormatV(fmt.wx_str(), args);
va_end(args); va_end(args);
return false; return false;
} }
bool IConsoleWriter::WriteLn( ConsoleColors color, const wxString fmt, ... ) const bool IConsoleWriter::WriteLn(ConsoleColors color, const wxString fmt, ...) const
{ {
va_list args; va_list args;
va_start(args,fmt); va_start(args, fmt);
ConsoleColorScope cs( color ); ConsoleColorScope cs(color);
FormatV(fmt.wx_str(),args); FormatV(fmt.wx_str(), args);
va_end(args); va_end(args);
return false; return false;
} }
bool IConsoleWriter::Error( const wxString fmt, ... ) const bool IConsoleWriter::Error(const wxString fmt, ...) const
{ {
va_list args; va_list args;
va_start(args,fmt); va_start(args, fmt);
ConsoleColorScope cs( Color_StrongRed ); ConsoleColorScope cs(Color_StrongRed);
FormatV(fmt.wx_str(),args); FormatV(fmt.wx_str(), args);
va_end(args); va_end(args);
return false; return false;
} }
bool IConsoleWriter::Warning( const wxString fmt, ... ) const bool IConsoleWriter::Warning(const wxString fmt, ...) const
{ {
va_list args; va_list args;
va_start(args,fmt); va_start(args, fmt);
ConsoleColorScope cs( Color_StrongOrange ); ConsoleColorScope cs(Color_StrongOrange);
FormatV(fmt.wx_str(),args); FormatV(fmt.wx_str(), args);
va_end(args); va_end(args);
return false; return false;
} }
@ -442,73 +459,72 @@ bool IConsoleWriter::Warning( const wxString fmt, ... ) const
// ConsoleColorScope / ConsoleIndentScope // ConsoleColorScope / ConsoleIndentScope
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
ConsoleColorScope::ConsoleColorScope( ConsoleColors newcolor ) ConsoleColorScope::ConsoleColorScope(ConsoleColors newcolor)
{ {
m_IsScoped = false; m_IsScoped = false;
m_newcolor = newcolor; m_newcolor = newcolor;
EnterScope(); EnterScope();
} }
ConsoleColorScope::~ConsoleColorScope() throw() ConsoleColorScope::~ConsoleColorScope() throw()
{ {
LeaveScope(); LeaveScope();
} }
void ConsoleColorScope::EnterScope() void ConsoleColorScope::EnterScope()
{ {
if (!m_IsScoped) if (!m_IsScoped) {
{ m_old_color = Console.GetColor();
m_old_color = Console.GetColor(); Console.SetColor(m_newcolor);
Console.SetColor( m_newcolor ); m_IsScoped = true;
m_IsScoped = true; }
}
} }
void ConsoleColorScope::LeaveScope() void ConsoleColorScope::LeaveScope()
{ {
m_IsScoped = m_IsScoped && (Console.SetColor( m_old_color ), false); m_IsScoped = m_IsScoped && (Console.SetColor(m_old_color), false);
} }
ConsoleIndentScope::ConsoleIndentScope( int tabs ) ConsoleIndentScope::ConsoleIndentScope(int tabs)
{ {
m_IsScoped = false; m_IsScoped = false;
m_amount = tabs; m_amount = tabs;
EnterScope(); EnterScope();
} }
ConsoleIndentScope::~ConsoleIndentScope() throw() ConsoleIndentScope::~ConsoleIndentScope() throw()
{ {
try { try {
LeaveScope(); LeaveScope();
} }
DESTRUCTOR_CATCHALL DESTRUCTOR_CATCHALL
} }
void ConsoleIndentScope::EnterScope() void ConsoleIndentScope::EnterScope()
{ {
m_IsScoped = m_IsScoped || (Console.SetIndent( m_amount ),true); m_IsScoped = m_IsScoped || (Console.SetIndent(m_amount), true);
} }
void ConsoleIndentScope::LeaveScope() void ConsoleIndentScope::LeaveScope()
{ {
m_IsScoped = m_IsScoped && (Console.SetIndent( -m_amount ),false); m_IsScoped = m_IsScoped && (Console.SetIndent(-m_amount), false);
} }
ConsoleAttrScope::ConsoleAttrScope( ConsoleColors newcolor, int indent ) ConsoleAttrScope::ConsoleAttrScope(ConsoleColors newcolor, int indent)
{ {
m_old_color = Console.GetColor(); m_old_color = Console.GetColor();
Console.SetIndent( m_tabsize = indent ); Console.SetIndent(m_tabsize = indent);
Console.SetColor( newcolor ); Console.SetColor(newcolor);
} }
ConsoleAttrScope::~ConsoleAttrScope() throw() ConsoleAttrScope::~ConsoleAttrScope() throw()
{ {
try { try {
Console.SetColor( m_old_color ); Console.SetColor(m_old_color);
Console.SetIndent( -m_tabsize ); Console.SetIndent(-m_tabsize);
} }
DESTRUCTOR_CATCHALL DESTRUCTOR_CATCHALL
} }
@ -520,18 +536,18 @@ ConsoleAttrScope::~ConsoleAttrScope() throw()
// platform specific code). Under windows Stdout will attempt to write to the IDE Debug // platform specific code). Under windows Stdout will attempt to write to the IDE Debug
// console, if one is available (such as running pcsx2 via MSVC). If not available, then // console, if one is available (such as running pcsx2 via MSVC). If not available, then
// the log message will pretty much be lost into the ether. // the log message will pretty much be lost into the ether.
// //
#define _DefaultWriter_ ConsoleWriter_Stdout #define _DefaultWriter_ ConsoleWriter_Stdout
IConsoleWriter Console = _DefaultWriter_; IConsoleWriter Console = _DefaultWriter_;
IConsoleWriter DevConWriter = _DefaultWriter_; IConsoleWriter DevConWriter = _DefaultWriter_;
bool DevConWriterEnabled = false; bool DevConWriterEnabled = false;
#ifdef PCSX2_DEBUG #ifdef PCSX2_DEBUG
IConsoleWriter DbgConWriter = _DefaultWriter_; IConsoleWriter DbgConWriter = _DefaultWriter_;
#endif #endif
NullConsoleWriter NullCon = {}; NullConsoleWriter NullCon = {};
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ConsoleLogSource (implementations) // ConsoleLogSource (implementations)
@ -539,31 +555,31 @@ NullConsoleWriter NullCon = {};
// Writes to the console using the specified color. This overrides the default color setting // Writes to the console using the specified color. This overrides the default color setting
// for this log. // for this log.
bool ConsoleLogSource::WriteV( ConsoleColors color, const char *fmt, va_list list ) const bool ConsoleLogSource::WriteV(ConsoleColors color, const char *fmt, va_list list) const
{ {
ConsoleColorScope cs(color); ConsoleColorScope cs(color);
DoWrite( pxsFmtV(fmt,list).c_str() ); DoWrite(pxsFmtV(fmt, list).c_str());
return false; return false;
} }
bool ConsoleLogSource::WriteV( ConsoleColors color, const wxChar *fmt, va_list list ) const bool ConsoleLogSource::WriteV(ConsoleColors color, const wxChar *fmt, va_list list) const
{ {
ConsoleColorScope cs(color); ConsoleColorScope cs(color);
DoWrite( pxsFmtV(fmt,list).c_str() ); DoWrite(pxsFmtV(fmt, list).c_str());
return false; return false;
} }
// Writes to the console using the source's default color. Note that the source's default // Writes to the console using the source's default color. Note that the source's default
// color will always be used, thus ConsoleColorScope() will not be effectual unless the // color will always be used, thus ConsoleColorScope() will not be effectual unless the
// console's default color is Color_Default. // console's default color is Color_Default.
bool ConsoleLogSource::WriteV( const char *fmt, va_list list ) const bool ConsoleLogSource::WriteV(const char *fmt, va_list list) const
{ {
WriteV( DefaultColor, fmt, list ); WriteV(DefaultColor, fmt, list);
return false; return false;
} }
bool ConsoleLogSource::WriteV( const wxChar *fmt, va_list list ) const bool ConsoleLogSource::WriteV(const wxChar *fmt, va_list list) const
{ {
WriteV( DefaultColor, fmt, list ); WriteV(DefaultColor, fmt, list);
return false; return false;
} }

View File

@ -24,7 +24,7 @@
#include <mach/mach_time.h> #include <mach/mach_time.h>
#define NELEM(x) \ #define NELEM(x) \
((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) ((sizeof(x) / sizeof(0 [x])) / ((size_t)(!(sizeof(x) % sizeof(0 [x])))))
// Darwin (OSX) is a bit different from Linux when requesting properties of // Darwin (OSX) is a bit different from Linux when requesting properties of
// the OS because of its BSD/Mach heritage. Helpfully, most of this code // the OS because of its BSD/Mach heritage. Helpfully, most of this code
@ -38,23 +38,23 @@
// failure (not supported by the operating system). // failure (not supported by the operating system).
u64 GetPhysicalMemory() u64 GetPhysicalMemory()
{ {
static u64 mem = 0; static u64 mem = 0;
// fetch the total memory only once, as its an expensive system call and // fetch the total memory only once, as its an expensive system call and
// doesn't change during the course of the program. Thread-safety is // doesn't change during the course of the program. Thread-safety is
// ensured by atomic operations with full-barriers (usually compiled // ensured by atomic operations with full-barriers (usually compiled
// down to XCHG on x86). // down to XCHG on x86).
if (__atomic_load_n(&mem, __ATOMIC_SEQ_CST) == 0) { if (__atomic_load_n(&mem, __ATOMIC_SEQ_CST) == 0) {
u64 getmem = 0; u64 getmem = 0;
size_t len = sizeof(getmem); size_t len = sizeof(getmem);
int mib[] = { CTL_HW, HW_MEMSIZE }; int mib[] = {CTL_HW, HW_MEMSIZE};
if (sysctl(mib, NELEM(mib), &getmem, &len, NULL, 0) < 0) { if (sysctl(mib, NELEM(mib), &getmem, &len, NULL, 0) < 0) {
perror("sysctl:"); perror("sysctl:");
} }
__atomic_store_n(&mem, getmem, __ATOMIC_SEQ_CST); __atomic_store_n(&mem, getmem, __ATOMIC_SEQ_CST);
} }
return mem; return mem;
} }
void InitCPUTicks() void InitCPUTicks()
@ -71,26 +71,26 @@ void InitCPUTicks()
// GetTickFrequency() to maintain good precision. // GetTickFrequency() to maintain good precision.
u64 GetTickFrequency() u64 GetTickFrequency()
{ {
static u64 freq = 0; static u64 freq = 0;
// by the time denom is not 0, the structure will have been fully // by the time denom is not 0, the structure will have been fully
// updated and no more atomic accesses are necessary. // updated and no more atomic accesses are necessary.
if (__atomic_load_n(&freq, __ATOMIC_SEQ_CST) == 0) { if (__atomic_load_n(&freq, __ATOMIC_SEQ_CST) == 0) {
mach_timebase_info_data_t info; mach_timebase_info_data_t info;
// mach_timebase_info() is a syscall, very slow, that's why we take // mach_timebase_info() is a syscall, very slow, that's why we take
// pains to only do it once. On x86(-64), the result is guaranteed // pains to only do it once. On x86(-64), the result is guaranteed
// to be info.denom == info.numer == 1 (i.e.: the frequency is 1e9, // to be info.denom == info.numer == 1 (i.e.: the frequency is 1e9,
// which means GetCPUTicks is just nanoseconds). // which means GetCPUTicks is just nanoseconds).
if (mach_timebase_info(&info) != KERN_SUCCESS) { if (mach_timebase_info(&info) != KERN_SUCCESS) {
abort(); abort();
} }
// store the calculated value atomically // store the calculated value atomically
__atomic_store_n(&freq, (u64) 1e9 * (u64) info.denom / (u64) info.numer, __ATOMIC_SEQ_CST); __atomic_store_n(&freq, (u64)1e9 * (u64)info.denom / (u64)info.numer, __ATOMIC_SEQ_CST);
} }
return freq; return freq;
} }
// return the number of "ticks" since some arbitrary, fixed time in the // return the number of "ticks" since some arbitrary, fixed time in the
@ -99,52 +99,52 @@ u64 GetTickFrequency()
// nanoseconds. // nanoseconds.
u64 GetCPUTicks() u64 GetCPUTicks()
{ {
return mach_absolute_time(); return mach_absolute_time();
} }
wxString GetOSVersionString() wxString GetOSVersionString()
{ {
wxString version; wxString version;
static int initialized = 0; static int initialized = 0;
// fetch the OS description only once (thread-safely) // fetch the OS description only once (thread-safely)
if (__atomic_load_n(&initialized, __ATOMIC_SEQ_CST) == 0) { if (__atomic_load_n(&initialized, __ATOMIC_SEQ_CST) == 0) {
char type[32] = {0}; char type[32] = {0};
char release[32] = {0}; char release[32] = {0};
char arch[32] = {0}; char arch[32] = {0};
#define SYSCTL_GET(var, base, name) \ #define SYSCTL_GET(var, base, name) \
do { \ do { \
int mib[] = { base, name }; \ int mib[] = {base, name}; \
size_t len = sizeof(var); \ size_t len = sizeof(var); \
sysctl(mib, NELEM(mib), NULL, &len, NULL, 0); \ sysctl(mib, NELEM(mib), NULL, &len, NULL, 0); \
sysctl(mib, NELEM(mib), var, &len, NULL, 0); \ sysctl(mib, NELEM(mib), var, &len, NULL, 0); \
} while (0) } while (0)
SYSCTL_GET(release, CTL_KERN, KERN_OSRELEASE); SYSCTL_GET(release, CTL_KERN, KERN_OSRELEASE);
SYSCTL_GET(type, CTL_KERN, KERN_OSTYPE); SYSCTL_GET(type, CTL_KERN, KERN_OSTYPE);
SYSCTL_GET(arch, CTL_HW, HW_MACHINE); SYSCTL_GET(arch, CTL_HW, HW_MACHINE);
#undef SYSCTL_KERN #undef SYSCTL_KERN
// I know strcat is not good, but stpcpy is not universally // I know strcat is not good, but stpcpy is not universally
// available yet. // available yet.
char buf[128] = {0}; char buf[128] = {0};
strcat(buf, type); strcat(buf, type);
strcat(buf, " "); strcat(buf, " ");
strcat(buf, release); strcat(buf, release);
strcat(buf, " "); strcat(buf, " ");
strcat(buf, arch); strcat(buf, arch);
version = buf; version = buf;
__atomic_store_n(&initialized, 1, __ATOMIC_SEQ_CST); __atomic_store_n(&initialized, 1, __ATOMIC_SEQ_CST);
} }
return version; return version;
} }
void ScreensaverAllow(bool allow) void ScreensaverAllow(bool allow)
{ {
// no-op // no-op
} }

View File

@ -14,17 +14,17 @@
*/ */
#include <cstdio> #include <cstdio>
#include <cassert> // assert #include <cassert> // assert
#include <pthread.h> // pthread_setcancelstate() #include <pthread.h> // pthread_setcancelstate()
#include <sys/time.h> // gettimeofday() #include <sys/time.h> // gettimeofday()
#include <mach/mach.h> #include <mach/mach.h>
#include <mach/task.h> // semaphore_create() and semaphore_destroy() #include <mach/task.h> // semaphore_create() and semaphore_destroy()
#include <mach/semaphore.h> // semaphore_*() #include <mach/semaphore.h> // semaphore_*()
#include <mach/mach_error.h> // mach_error_string() #include <mach/mach_error.h> // mach_error_string()
#include <mach/mach_time.h> // mach_absolute_time() #include <mach/mach_time.h> // mach_absolute_time()
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
@ -47,105 +47,105 @@
// //
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
#define MACH_CHECK(mach_retval) \ #define MACH_CHECK(mach_retval) \
do { \ do { \
kern_return_t _kr = (mach_retval); \ kern_return_t _kr = (mach_retval); \
if (_kr != KERN_SUCCESS) { \ if (_kr != KERN_SUCCESS) { \
fprintf(stderr, "mach error: %s", mach_error_string(_kr)); \ fprintf(stderr, "mach error: %s", mach_error_string(_kr)); \
assert(_kr == KERN_SUCCESS); \ assert(_kr == KERN_SUCCESS); \
} \ } \
} while (0) } while (0)
Threading::Semaphore::Semaphore() Threading::Semaphore::Semaphore()
{ {
// other platforms explicitly make a thread-private (unshared) semaphore // other platforms explicitly make a thread-private (unshared) semaphore
// here. But it seems Mach doesn't support that. // here. But it seems Mach doesn't support that.
MACH_CHECK(semaphore_create(mach_task_self(), (semaphore_t *)&m_sema, SYNC_POLICY_FIFO, 0)); MACH_CHECK(semaphore_create(mach_task_self(), (semaphore_t *)&m_sema, SYNC_POLICY_FIFO, 0));
__atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST); __atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST);
} }
Threading::Semaphore::~Semaphore() throw() Threading::Semaphore::~Semaphore() throw()
{ {
MACH_CHECK(semaphore_destroy(mach_task_self(), (semaphore_t) m_sema)); MACH_CHECK(semaphore_destroy(mach_task_self(), (semaphore_t)m_sema));
__atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST); __atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST);
} }
void Threading::Semaphore::Reset() void Threading::Semaphore::Reset()
{ {
MACH_CHECK(semaphore_destroy(mach_task_self(), (semaphore_t) m_sema)); MACH_CHECK(semaphore_destroy(mach_task_self(), (semaphore_t)m_sema));
MACH_CHECK(semaphore_create(mach_task_self(), (semaphore_t *) &m_sema, SYNC_POLICY_FIFO, 0)); MACH_CHECK(semaphore_create(mach_task_self(), (semaphore_t *)&m_sema, SYNC_POLICY_FIFO, 0));
__atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST); __atomic_store_n(&m_counter, 0, __ATOMIC_SEQ_CST);
} }
void Threading::Semaphore::Post() void Threading::Semaphore::Post()
{ {
MACH_CHECK(semaphore_signal(m_sema)); MACH_CHECK(semaphore_signal(m_sema));
__atomic_add_fetch(&m_counter, 1, __ATOMIC_SEQ_CST); __atomic_add_fetch(&m_counter, 1, __ATOMIC_SEQ_CST);
} }
void Threading::Semaphore::Post(int multiple) void Threading::Semaphore::Post(int multiple)
{ {
for (int i = 0; i < multiple; ++i) { for (int i = 0; i < multiple; ++i) {
MACH_CHECK(semaphore_signal(m_sema)); MACH_CHECK(semaphore_signal(m_sema));
} }
__atomic_add_fetch(&m_counter, multiple, __ATOMIC_SEQ_CST); __atomic_add_fetch(&m_counter, multiple, __ATOMIC_SEQ_CST);
} }
void Threading::Semaphore::WaitWithoutYield() void Threading::Semaphore::WaitWithoutYield()
{ {
pxAssertMsg(!wxThread::IsMain(), "Unyielding semaphore wait issued from the main/gui thread. Please use Wait() instead."); pxAssertMsg(!wxThread::IsMain(), "Unyielding semaphore wait issued from the main/gui thread. Please use Wait() instead.");
MACH_CHECK(semaphore_wait(m_sema)); MACH_CHECK(semaphore_wait(m_sema));
__atomic_sub_fetch(&m_counter, 1, __ATOMIC_SEQ_CST); __atomic_sub_fetch(&m_counter, 1, __ATOMIC_SEQ_CST);
} }
bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan& timeout) bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan &timeout)
{ {
// This method is the reason why there has to be a special Darwin // This method is the reason why there has to be a special Darwin
// implementation of Semaphore. Note that semaphore_timedwait() is prone // implementation of Semaphore. Note that semaphore_timedwait() is prone
// to returning with KERN_ABORTED, which basically signifies that some // to returning with KERN_ABORTED, which basically signifies that some
// signal has worken it up. The best official "documentation" for // signal has worken it up. The best official "documentation" for
// semaphore_timedwait() is the way it's used in Grand Central Dispatch, // semaphore_timedwait() is the way it's used in Grand Central Dispatch,
// which is open-source. // which is open-source.
// on x86 platforms, mach_absolute_time() returns nanoseconds // on x86 platforms, mach_absolute_time() returns nanoseconds
// TODO(aktau): on iOS a scale value from mach_timebase_info will be necessary // TODO(aktau): on iOS a scale value from mach_timebase_info will be necessary
u64 const kOneThousand = 1000; u64 const kOneThousand = 1000;
u64 const kOneBillion = kOneThousand * kOneThousand * kOneThousand; u64 const kOneBillion = kOneThousand * kOneThousand * kOneThousand;
u64 const delta = timeout.GetMilliseconds().GetValue() * (kOneThousand * kOneThousand); u64 const delta = timeout.GetMilliseconds().GetValue() * (kOneThousand * kOneThousand);
mach_timespec_t ts; mach_timespec_t ts;
kern_return_t kr = KERN_ABORTED; kern_return_t kr = KERN_ABORTED;
for (u64 now = mach_absolute_time(), deadline = now + delta; for (u64 now = mach_absolute_time(), deadline = now + delta;
kr == KERN_ABORTED; now = mach_absolute_time()) { kr == KERN_ABORTED; now = mach_absolute_time()) {
if (now > deadline) { if (now > deadline) {
// timed out by definition // timed out by definition
return false; return false;
} }
u64 timeleft = deadline - now; u64 timeleft = deadline - now;
ts.tv_sec = timeleft / kOneBillion; ts.tv_sec = timeleft / kOneBillion;
ts.tv_nsec = timeleft % kOneBillion; ts.tv_nsec = timeleft % kOneBillion;
// possible return values of semaphore_timedwait() (from XNU sources): // possible return values of semaphore_timedwait() (from XNU sources):
// internal kernel val -> return value // internal kernel val -> return value
// THREAD_INTERRUPTED -> KERN_ABORTED // THREAD_INTERRUPTED -> KERN_ABORTED
// THREAD_TIMED_OUT -> KERN_OPERATION_TIMED_OUT // THREAD_TIMED_OUT -> KERN_OPERATION_TIMED_OUT
// THREAD_AWAKENED -> KERN_SUCCESS // THREAD_AWAKENED -> KERN_SUCCESS
// THREAD_RESTART -> KERN_TERMINATED // THREAD_RESTART -> KERN_TERMINATED
// default -> KERN_FAILURE // default -> KERN_FAILURE
kr = semaphore_timedwait(m_sema, ts); kr = semaphore_timedwait(m_sema, ts);
} }
if (kr == KERN_OPERATION_TIMED_OUT) { if (kr == KERN_OPERATION_TIMED_OUT) {
return false; return false;
} }
// while it's entirely possible to have KERN_FAILURE here, we should // while it's entirely possible to have KERN_FAILURE here, we should
// probably assert so we can study and correct the actual error here // probably assert so we can study and correct the actual error here
// (the thread dying while someone is wainting for it). // (the thread dying while someone is wainting for it).
MACH_CHECK(kr); MACH_CHECK(kr);
__atomic_sub_fetch(&m_counter, 1, __ATOMIC_SEQ_CST); __atomic_sub_fetch(&m_counter, 1, __ATOMIC_SEQ_CST);
return true; return true;
} }
// This is a wxApp-safe implementation of Wait, which makes sure and executes the App's // This is a wxApp-safe implementation of Wait, which makes sure and executes the App's
@ -155,20 +155,18 @@ bool Threading::Semaphore::WaitWithoutYield(const wxTimeSpan& timeout)
void Threading::Semaphore::Wait() void Threading::Semaphore::Wait()
{ {
#if wxUSE_GUI #if wxUSE_GUI
if(!wxThread::IsMain() || (wxTheApp == NULL)) { if (!wxThread::IsMain() || (wxTheApp == NULL)) {
WaitWithoutYield(); WaitWithoutYield();
} } else if (_WaitGui_RecursionGuard(L"Semaphore::Wait")) {
else if(_WaitGui_RecursionGuard( L"Semaphore::Wait" )) { ScopedBusyCursor hourglass(Cursor_ReallyBusy);
ScopedBusyCursor hourglass( Cursor_ReallyBusy ); WaitWithoutYield();
WaitWithoutYield(); } else {
} while (!WaitWithoutYield(def_yieldgui_interval)) {
else { YieldToMain();
while (!WaitWithoutYield(def_yieldgui_interval)) { }
YieldToMain(); }
}
}
#else #else
WaitWithoutYield(); WaitWithoutYield();
#endif #endif
} }
@ -181,30 +179,29 @@ void Threading::Semaphore::Wait()
// false if the wait timed out before the semaphore was signaled, or true if the signal was // false if the wait timed out before the semaphore was signaled, or true if the signal was
// reached prior to timeout. // reached prior to timeout.
// //
bool Threading::Semaphore::Wait(const wxTimeSpan& timeout) bool Threading::Semaphore::Wait(const wxTimeSpan &timeout)
{ {
#if wxUSE_GUI #if wxUSE_GUI
if(!wxThread::IsMain() || (wxTheApp == NULL)) { if (!wxThread::IsMain() || (wxTheApp == NULL)) {
return WaitWithoutYield(timeout); return WaitWithoutYield(timeout);
} } else if (_WaitGui_RecursionGuard(L"Semaphore::TimedWait")) {
else if (_WaitGui_RecursionGuard( L"Semaphore::TimedWait")) { ScopedBusyCursor hourglass(Cursor_ReallyBusy);
ScopedBusyCursor hourglass(Cursor_ReallyBusy); return WaitWithoutYield(timeout);
return WaitWithoutYield(timeout); } else {
} //ScopedBusyCursor hourglass( Cursor_KindaBusy );
else { wxTimeSpan countdown((timeout));
//ScopedBusyCursor hourglass( Cursor_KindaBusy );
wxTimeSpan countdown((timeout));
do { do {
if (WaitWithoutYield(def_yieldgui_interval)) break; if (WaitWithoutYield(def_yieldgui_interval))
YieldToMain(); break;
countdown -= def_yieldgui_interval; YieldToMain();
} while (countdown.GetMilliseconds() > 0); countdown -= def_yieldgui_interval;
} while (countdown.GetMilliseconds() > 0);
return countdown.GetMilliseconds() > 0; return countdown.GetMilliseconds() > 0;
} }
#else #else
return WaitWithoutYield(timeout); return WaitWithoutYield(timeout);
#endif #endif
} }
@ -223,21 +220,21 @@ bool Threading::Semaphore::Wait(const wxTimeSpan& timeout)
// POSIX threads), this should work. -- aktau // POSIX threads), this should work. -- aktau
void Threading::Semaphore::WaitNoCancel() void Threading::Semaphore::WaitNoCancel()
{ {
int oldstate; int oldstate;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
Wait(); Wait();
pthread_setcancelstate(oldstate, NULL); pthread_setcancelstate(oldstate, NULL);
} }
void Threading::Semaphore::WaitNoCancel(const wxTimeSpan& timeout) void Threading::Semaphore::WaitNoCancel(const wxTimeSpan &timeout)
{ {
int oldstate; int oldstate;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
Wait(timeout); Wait(timeout);
pthread_setcancelstate(oldstate, NULL); pthread_setcancelstate(oldstate, NULL);
} }
int Threading::Semaphore::Count() int Threading::Semaphore::Count()
{ {
return __atomic_load_n(&m_counter, __ATOMIC_SEQ_CST); return __atomic_load_n(&m_counter, __ATOMIC_SEQ_CST);
} }

View File

@ -19,7 +19,7 @@
#include <unistd.h> #include <unistd.h>
#if !defined(__APPLE__) #if !defined(__APPLE__)
# error "DarwinThreads.cpp should only be compiled by projects or makefiles targeted at OSX." #error "DarwinThreads.cpp should only be compiled by projects or makefiles targeted at OSX."
#else #else
#include <mach/mach_init.h> #include <mach/mach_init.h>
@ -30,7 +30,7 @@
// the LOCK prefix. The prefix works on single core CPUs fine (but is slow), but not // the LOCK prefix. The prefix works on single core CPUs fine (but is slow), but not
// having the LOCK prefix is very bad indeed. // having the LOCK prefix is very bad indeed.
__forceinline void Threading::Sleep( int ms ) __forceinline void Threading::Sleep(int ms)
{ {
usleep(1000 * ms); usleep(1000 * ms);
} }
@ -41,7 +41,7 @@ __forceinline void Threading::SpinWait()
{ {
// If this doesn't compile you can just comment it out (it only serves as a // If this doesn't compile you can just comment it out (it only serves as a
// performance hint and isn't required). // performance hint and isn't required).
__asm__ ( "pause" ); __asm__("pause");
} }
__forceinline void Threading::EnableHiresScheduler() __forceinline void Threading::EnableHiresScheduler()
@ -66,21 +66,22 @@ u64 Threading::GetThreadTicksPerSecond()
// gets the CPU time used by the current thread (both system and user), in // gets the CPU time used by the current thread (both system and user), in
// microseconds, returns 0 on failure // microseconds, returns 0 on failure
static u64 getthreadtime(thread_port_t thread) { static u64 getthreadtime(thread_port_t thread)
{
mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT; mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
thread_basic_info_data_t info; thread_basic_info_data_t info;
kern_return_t kr = thread_info(thread, THREAD_BASIC_INFO, kern_return_t kr = thread_info(thread, THREAD_BASIC_INFO,
(thread_info_t) &info, &count); (thread_info_t)&info, &count);
if (kr != KERN_SUCCESS) { if (kr != KERN_SUCCESS) {
return 0; return 0;
} }
// add system and user time // add system and user time
return (u64) info.user_time.seconds * (u64) 1e6 + return (u64)info.user_time.seconds * (u64)1e6 +
(u64) info.user_time.microseconds + (u64)info.user_time.microseconds +
(u64) info.system_time.seconds * (u64) 1e6 + (u64)info.system_time.seconds * (u64)1e6 +
(u64) info.system_time.microseconds; (u64)info.system_time.microseconds;
} }
// Returns the current timestamp (not relative to a real world clock) in // Returns the current timestamp (not relative to a real world clock) in
@ -109,19 +110,19 @@ u64 Threading::pxThread::GetCpuTime() const
return 0; return 0;
} }
return getthreadtime((thread_port_t) m_native_id) * 10ULL; return getthreadtime((thread_port_t)m_native_id) * 10ULL;
} }
void Threading::pxThread::_platform_specific_OnStartInThread() void Threading::pxThread::_platform_specific_OnStartInThread()
{ {
m_native_id = (uptr) mach_thread_self(); m_native_id = (uptr)mach_thread_self();
} }
void Threading::pxThread::_platform_specific_OnCleanupInThread() void Threading::pxThread::_platform_specific_OnCleanupInThread()
{ {
// cleanup of handles that were upened in // cleanup of handles that were upened in
// _platform_specific_OnStartInThread // _platform_specific_OnStartInThread
mach_port_deallocate(mach_task_self(), (thread_port_t) m_native_id); mach_port_deallocate(mach_task_self(), (thread_port_t)m_native_id);
} }
// name can be up to 16 bytes // name can be up to 16 bytes

View File

@ -43,37 +43,37 @@ Fnptr_OutOfMemory pxDoOutOfMemory = NULL;
// const false). // const false).
// //
#ifdef PCSX2_DEVBUILD #ifdef PCSX2_DEVBUILD
# define DEVASSERT_INLINE __noinline #define DEVASSERT_INLINE __noinline
#else #else
# define DEVASSERT_INLINE __fi #define DEVASSERT_INLINE __fi
#endif #endif
// Using a threadlocal assertion guard. Separate threads can assert at the same time. // Using a threadlocal assertion guard. Separate threads can assert at the same time.
// That's ok. What we don't want is the *same* thread recurse-asserting. // That's ok. What we don't want is the *same* thread recurse-asserting.
static DeclareTls(int) s_assert_guard( 0 ); static DeclareTls(int) s_assert_guard(0);
pxDoAssertFnType* pxDoAssert = pxAssertImpl_LogIt; pxDoAssertFnType *pxDoAssert = pxAssertImpl_LogIt;
// make life easier for people using VC++ IDE by using this format, which allows double-click // make life easier for people using VC++ IDE by using this format, which allows double-click
// response times from the Output window... // response times from the Output window...
wxString DiagnosticOrigin::ToString( const wxChar* msg ) const wxString DiagnosticOrigin::ToString(const wxChar *msg) const
{ {
FastFormatUnicode message; FastFormatUnicode message;
message.Write( L"%ls(%d) : assertion failed:\n", srcfile, line ); message.Write(L"%ls(%d) : assertion failed:\n", srcfile, line);
if( function != NULL ) if (function != NULL)
message.Write( " Function: %s\n", function ); message.Write(" Function: %s\n", function);
message.Write(L" Thread: %s\n", WX_STR(Threading::pxGetCurrentThreadName()) ); message.Write(L" Thread: %s\n", WX_STR(Threading::pxGetCurrentThreadName()));
if( condition != NULL ) if (condition != NULL)
message.Write(L" Condition: %ls\n", condition); message.Write(L" Condition: %ls\n", condition);
if( msg != NULL ) if (msg != NULL)
message.Write(L" Message: %ls\n", msg); message.Write(L" Message: %ls\n", msg);
return message; return message;
} }
@ -83,71 +83,72 @@ void pxTrap()
#if defined(__WXMSW__) && !defined(__WXMICROWIN__) #if defined(__WXMSW__) && !defined(__WXMICROWIN__)
__debugbreak(); __debugbreak();
#elif defined(__WXMAC__) && !defined(__DARWIN__) #elif defined(__WXMAC__) && !defined(__DARWIN__)
#if __powerc #if __powerc
Debugger(); Debugger();
#else #else
SysBreak(); SysBreak();
#endif #endif
#elif defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS #elif defined(_MSL_USING_MW_C_HEADERS) && _MSL_USING_MW_C_HEADERS
Debugger(); Debugger();
#elif defined(__UNIX__) #elif defined(__UNIX__)
raise(SIGTRAP); raise(SIGTRAP);
#else #else
// TODO // TODO
#endif // Win/Unix #endif // Win/Unix
} }
bool pxAssertImpl_LogIt( const DiagnosticOrigin& origin, const wxChar *msg ) bool pxAssertImpl_LogIt(const DiagnosticOrigin &origin, const wxChar *msg)
{ {
//wxLogError( L"%s", origin.ToString( msg ).c_str() ); //wxLogError( L"%s", origin.ToString( msg ).c_str() );
wxMessageOutputDebug().Printf( L"%s", origin.ToString( msg ).c_str() ); wxMessageOutputDebug().Printf(L"%s", origin.ToString(msg).c_str());
pxTrap(); pxTrap();
return false; return false;
} }
DEVASSERT_INLINE void pxOnAssert( const DiagnosticOrigin& origin, const wxChar* msg ) DEVASSERT_INLINE void pxOnAssert(const DiagnosticOrigin &origin, const wxChar *msg)
{ {
// Recursion guard: Allow at least one recursive call. This is useful because sometimes // Recursion guard: Allow at least one recursive call. This is useful because sometimes
// we get meaningless assertions while unwinding stack traces after exceptions have occurred. // we get meaningless assertions while unwinding stack traces after exceptions have occurred.
RecursionGuard guard( s_assert_guard ); RecursionGuard guard(s_assert_guard);
if (guard.Counter > 2) { return pxTrap(); } if (guard.Counter > 2) {
return pxTrap();
}
// wxWidgets doesn't come with debug builds on some Linux distros, and other distros make // wxWidgets doesn't come with debug builds on some Linux distros, and other distros make
// it difficult to use the debug build (compilation failures). To handle these I've had to // it difficult to use the debug build (compilation failures). To handle these I've had to
// bypass the internal wxWidgets assertion handler entirely, since it may not exist even if // bypass the internal wxWidgets assertion handler entirely, since it may not exist even if
// PCSX2 itself is compiled in debug mode (assertions enabled). // PCSX2 itself is compiled in debug mode (assertions enabled).
bool trapit; bool trapit;
if( pxDoAssert == NULL ) if (pxDoAssert == NULL) {
{ // Note: Format uses MSVC's syntax for output window hotlinking.
// Note: Format uses MSVC's syntax for output window hotlinking. trapit = pxAssertImpl_LogIt(origin, msg);
trapit = pxAssertImpl_LogIt( origin, msg ); } else {
} trapit = pxDoAssert(origin, msg);
else }
{
trapit = pxDoAssert( origin, msg );
}
if( trapit ) { pxTrap(); } if (trapit) {
pxTrap();
}
} }
__fi void pxOnAssert( const DiagnosticOrigin& origin, const char* msg) __fi void pxOnAssert(const DiagnosticOrigin &origin, const char *msg)
{ {
pxOnAssert( origin, fromUTF8(msg) ); pxOnAssert(origin, fromUTF8(msg));
} }
__fi void pxOnAssert( const DiagnosticOrigin& origin, const wxString& msg) __fi void pxOnAssert(const DiagnosticOrigin &origin, const wxString &msg)
{ {
pxOnAssert( origin, msg.wc_str() ); pxOnAssert(origin, msg.wc_str());
} }
__fi void pxOnAssert( const DiagnosticOrigin& origin, const FastFormatUnicode& msg) __fi void pxOnAssert(const DiagnosticOrigin &origin, const FastFormatUnicode &msg)
{ {
pxOnAssert( origin, msg.c_str()); pxOnAssert(origin, msg.c_str());
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -156,136 +157,132 @@ __fi void pxOnAssert( const DiagnosticOrigin& origin, const FastFormatUnicode& m
BaseException::~BaseException() throw() {} BaseException::~BaseException() throw() {}
BaseException& BaseException::SetBothMsgs( const wxChar* msg_diag ) BaseException &BaseException::SetBothMsgs(const wxChar *msg_diag)
{ {
m_message_user = msg_diag ? wxString(wxGetTranslation( msg_diag )) : wxString(""); m_message_user = msg_diag ? wxString(wxGetTranslation(msg_diag)) : wxString("");
return SetDiagMsg( msg_diag ); return SetDiagMsg(msg_diag);
} }
BaseException& BaseException::SetDiagMsg( const wxString& msg_diag ) BaseException &BaseException::SetDiagMsg(const wxString &msg_diag)
{ {
m_message_diag = msg_diag; m_message_diag = msg_diag;
return *this; return *this;
} }
BaseException& BaseException::SetUserMsg( const wxString& msg_user ) BaseException &BaseException::SetUserMsg(const wxString &msg_user)
{ {
m_message_user = msg_user; m_message_user = msg_user;
return *this; return *this;
} }
wxString BaseException::FormatDiagnosticMessage() const wxString BaseException::FormatDiagnosticMessage() const
{ {
return m_message_diag; return m_message_diag;
} }
wxString BaseException::FormatDisplayMessage() const wxString BaseException::FormatDisplayMessage() const
{ {
return m_message_user.IsEmpty() ? m_message_diag : m_message_user; return m_message_user.IsEmpty() ? m_message_diag : m_message_user;
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Exception::RuntimeError (implementations) // Exception::RuntimeError (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
Exception::RuntimeError::RuntimeError( const std::runtime_error& ex, const wxString& prefix ) Exception::RuntimeError::RuntimeError(const std::runtime_error &ex, const wxString &prefix)
{ {
IsSilent = false; IsSilent = false;
SetDiagMsg( pxsFmt( L"STL Runtime Error%s: %s", SetDiagMsg(pxsFmt(L"STL Runtime Error%s: %s",
(prefix.IsEmpty() ? L"" : pxsFmt(L" (%s)", WX_STR(prefix)).c_str()), (prefix.IsEmpty() ? L"" : pxsFmt(L" (%s)", WX_STR(prefix)).c_str()),
WX_STR(fromUTF8( ex.what() )) WX_STR(fromUTF8(ex.what()))));
) );
} }
Exception::RuntimeError::RuntimeError( const std::exception& ex, const wxString& prefix ) Exception::RuntimeError::RuntimeError(const std::exception &ex, const wxString &prefix)
{ {
IsSilent = false; IsSilent = false;
SetDiagMsg( pxsFmt( L"STL Exception%s: %s", SetDiagMsg(pxsFmt(L"STL Exception%s: %s",
(prefix.IsEmpty() ? L"" : pxsFmt(L" (%s)", WX_STR(prefix)).c_str()), (prefix.IsEmpty() ? L"" : pxsFmt(L" (%s)", WX_STR(prefix)).c_str()),
WX_STR(fromUTF8( ex.what() )) WX_STR(fromUTF8(ex.what()))));
) );
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Exception::OutOfMemory (implementations) // Exception::OutOfMemory (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
Exception::OutOfMemory::OutOfMemory( const wxString& allocdesc ) Exception::OutOfMemory::OutOfMemory(const wxString &allocdesc)
{ {
AllocDescription = allocdesc; AllocDescription = allocdesc;
} }
wxString Exception::OutOfMemory::FormatDiagnosticMessage() const wxString Exception::OutOfMemory::FormatDiagnosticMessage() const
{ {
FastFormatUnicode retmsg; FastFormatUnicode retmsg;
retmsg.Write(L"Out of memory"); retmsg.Write(L"Out of memory");
if (!AllocDescription.IsEmpty()) if (!AllocDescription.IsEmpty())
retmsg.Write(L" while allocating '%s'", WX_STR(AllocDescription)); retmsg.Write(L" while allocating '%s'", WX_STR(AllocDescription));
if (!m_message_diag.IsEmpty()) if (!m_message_diag.IsEmpty())
retmsg.Write(L":\n%s", WX_STR(m_message_diag)); retmsg.Write(L":\n%s", WX_STR(m_message_diag));
return retmsg; return retmsg;
} }
wxString Exception::OutOfMemory::FormatDisplayMessage() const wxString Exception::OutOfMemory::FormatDisplayMessage() const
{ {
FastFormatUnicode retmsg; FastFormatUnicode retmsg;
retmsg.Write( L"%s", _("Oh noes! Out of memory!") ); retmsg.Write(L"%s", _("Oh noes! Out of memory!"));
if (!m_message_user.IsEmpty()) if (!m_message_user.IsEmpty())
retmsg.Write(L"\n\n%s", WX_STR(m_message_user)); retmsg.Write(L"\n\n%s", WX_STR(m_message_user));
return retmsg; return retmsg;
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// Exception::VirtualMemoryMapConflict (implementations) // Exception::VirtualMemoryMapConflict (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
Exception::VirtualMemoryMapConflict::VirtualMemoryMapConflict( const wxString& allocdesc ) Exception::VirtualMemoryMapConflict::VirtualMemoryMapConflict(const wxString &allocdesc)
{ {
AllocDescription = allocdesc; AllocDescription = allocdesc;
m_message_user = _("Virtual memory mapping failure! Your system may have conflicting device drivers, services, or may simply have insufficient memory or resources to meet PCSX2's lofty needs."); m_message_user = _("Virtual memory mapping failure! Your system may have conflicting device drivers, services, or may simply have insufficient memory or resources to meet PCSX2's lofty needs.");
} }
wxString Exception::VirtualMemoryMapConflict::FormatDiagnosticMessage() const wxString Exception::VirtualMemoryMapConflict::FormatDiagnosticMessage() const
{ {
FastFormatUnicode retmsg; FastFormatUnicode retmsg;
retmsg.Write(L"Virtual memory map failed"); retmsg.Write(L"Virtual memory map failed");
if (!AllocDescription.IsEmpty()) if (!AllocDescription.IsEmpty())
retmsg.Write(L" while reserving '%s'", WX_STR(AllocDescription)); retmsg.Write(L" while reserving '%s'", WX_STR(AllocDescription));
if (!m_message_diag.IsEmpty()) if (!m_message_diag.IsEmpty())
retmsg.Write(L":\n%s", WX_STR(m_message_diag)); retmsg.Write(L":\n%s", WX_STR(m_message_diag));
return retmsg; return retmsg;
} }
wxString Exception::VirtualMemoryMapConflict::FormatDisplayMessage() const wxString Exception::VirtualMemoryMapConflict::FormatDisplayMessage() const
{ {
FastFormatUnicode retmsg; FastFormatUnicode retmsg;
retmsg.Write( L"%s", retmsg.Write(L"%s",
pxE( L"There is not enough virtual memory available, or necessary virtual memory mappings have already been reserved by other processes, services, or DLLs." pxE(L"There is not enough virtual memory available, or necessary virtual memory mappings have already been reserved by other processes, services, or DLLs."));
)
);
if (!m_message_diag.IsEmpty()) if (!m_message_diag.IsEmpty())
retmsg.Write(L"\n\n%s", WX_STR(m_message_diag)); retmsg.Write(L"\n\n%s", WX_STR(m_message_diag));
return retmsg; return retmsg;
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
wxString Exception::CancelEvent::FormatDiagnosticMessage() const wxString Exception::CancelEvent::FormatDiagnosticMessage() const
{ {
return L"Action canceled: " + m_message_diag; return L"Action canceled: " + m_message_diag;
} }
wxString Exception::CancelEvent::FormatDisplayMessage() const wxString Exception::CancelEvent::FormatDisplayMessage() const
{ {
return L"Action canceled: " + m_message_diag; return L"Action canceled: " + m_message_diag;
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -293,40 +290,40 @@ wxString Exception::CancelEvent::FormatDisplayMessage() const
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
wxString Exception::BadStream::FormatDiagnosticMessage() const wxString Exception::BadStream::FormatDiagnosticMessage() const
{ {
FastFormatUnicode retval; FastFormatUnicode retval;
_formatDiagMsg(retval); _formatDiagMsg(retval);
return retval; return retval;
} }
wxString Exception::BadStream::FormatDisplayMessage() const wxString Exception::BadStream::FormatDisplayMessage() const
{ {
FastFormatUnicode retval; FastFormatUnicode retval;
_formatUserMsg(retval); _formatUserMsg(retval);
return retval; return retval;
} }
void Exception::BadStream::_formatDiagMsg( FastFormatUnicode& dest ) const void Exception::BadStream::_formatDiagMsg(FastFormatUnicode &dest) const
{ {
dest.Write( L"Path: " ); dest.Write(L"Path: ");
if (!StreamName.IsEmpty()) if (!StreamName.IsEmpty())
dest.Write( L"%s", WX_STR(StreamName) ); dest.Write(L"%s", WX_STR(StreamName));
else else
dest.Write( L"[Unnamed or unknown]" ); dest.Write(L"[Unnamed or unknown]");
if (!m_message_diag.IsEmpty()) if (!m_message_diag.IsEmpty())
dest.Write(L"\n%s", WX_STR(m_message_diag)); dest.Write(L"\n%s", WX_STR(m_message_diag));
} }
void Exception::BadStream::_formatUserMsg( FastFormatUnicode& dest ) const void Exception::BadStream::_formatUserMsg(FastFormatUnicode &dest) const
{ {
dest.Write( _("Path: ") ); dest.Write(_("Path: "));
if (!StreamName.IsEmpty()) if (!StreamName.IsEmpty())
dest.Write( L"%s", WX_STR(StreamName) ); dest.Write(L"%s", WX_STR(StreamName));
else else
dest.Write( _("[Unnamed or unknown]") ); dest.Write(_("[Unnamed or unknown]"));
if (!m_message_user.IsEmpty()) if (!m_message_user.IsEmpty())
dest.Write(L"\n%s", WX_STR(m_message_user)); dest.Write(L"\n%s", WX_STR(m_message_user));
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -334,19 +331,19 @@ void Exception::BadStream::_formatUserMsg( FastFormatUnicode& dest ) const
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
wxString Exception::CannotCreateStream::FormatDiagnosticMessage() const wxString Exception::CannotCreateStream::FormatDiagnosticMessage() const
{ {
FastFormatUnicode retval; FastFormatUnicode retval;
retval.Write("File could not be created."); retval.Write("File could not be created.");
_formatDiagMsg(retval); _formatDiagMsg(retval);
return retval; return retval;
} }
wxString Exception::CannotCreateStream::FormatDisplayMessage() const wxString Exception::CannotCreateStream::FormatDisplayMessage() const
{ {
FastFormatUnicode retval; FastFormatUnicode retval;
retval.Write(_("A file could not be created.")); retval.Write(_("A file could not be created."));
retval.Write("\n"); retval.Write("\n");
_formatUserMsg(retval); _formatUserMsg(retval);
return retval; return retval;
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -354,19 +351,19 @@ wxString Exception::CannotCreateStream::FormatDisplayMessage() const
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
wxString Exception::FileNotFound::FormatDiagnosticMessage() const wxString Exception::FileNotFound::FormatDiagnosticMessage() const
{ {
FastFormatUnicode retval; FastFormatUnicode retval;
retval.Write("File not found.\n"); retval.Write("File not found.\n");
_formatDiagMsg(retval); _formatDiagMsg(retval);
return retval; return retval;
} }
wxString Exception::FileNotFound::FormatDisplayMessage() const wxString Exception::FileNotFound::FormatDisplayMessage() const
{ {
FastFormatUnicode retval; FastFormatUnicode retval;
retval.Write(_("File not found.")); retval.Write(_("File not found."));
retval.Write("\n"); retval.Write("\n");
_formatUserMsg(retval); _formatUserMsg(retval);
return retval; return retval;
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -374,19 +371,19 @@ wxString Exception::FileNotFound::FormatDisplayMessage() const
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
wxString Exception::AccessDenied::FormatDiagnosticMessage() const wxString Exception::AccessDenied::FormatDiagnosticMessage() const
{ {
FastFormatUnicode retval; FastFormatUnicode retval;
retval.Write("Permission denied to file.\n"); retval.Write("Permission denied to file.\n");
_formatDiagMsg(retval); _formatDiagMsg(retval);
return retval; return retval;
} }
wxString Exception::AccessDenied::FormatDisplayMessage() const wxString Exception::AccessDenied::FormatDisplayMessage() const
{ {
FastFormatUnicode retval; FastFormatUnicode retval;
retval.Write(_("Permission denied while trying to open file, likely due to insufficient user account rights.")); retval.Write(_("Permission denied while trying to open file, likely due to insufficient user account rights."));
retval.Write("\n"); retval.Write("\n");
_formatUserMsg(retval); _formatUserMsg(retval);
return retval; return retval;
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -394,19 +391,19 @@ wxString Exception::AccessDenied::FormatDisplayMessage() const
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
wxString Exception::EndOfStream::FormatDiagnosticMessage() const wxString Exception::EndOfStream::FormatDiagnosticMessage() const
{ {
FastFormatUnicode retval; FastFormatUnicode retval;
retval.Write("Unexpected end of file or stream.\n"); retval.Write("Unexpected end of file or stream.\n");
_formatDiagMsg(retval); _formatDiagMsg(retval);
return retval; return retval;
} }
wxString Exception::EndOfStream::FormatDisplayMessage() const wxString Exception::EndOfStream::FormatDisplayMessage() const
{ {
FastFormatUnicode retval; FastFormatUnicode retval;
retval.Write(_("Unexpected end of file or stream encountered. File is probably truncated or corrupted.")); retval.Write(_("Unexpected end of file or stream encountered. File is probably truncated or corrupted."));
retval.Write("\n"); retval.Write("\n");
_formatUserMsg(retval); _formatUserMsg(retval);
return retval; return retval;
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -415,35 +412,34 @@ wxString Exception::EndOfStream::FormatDisplayMessage() const
// Translates an Errno code into an exception. // Translates an Errno code into an exception.
// Throws an exception based on the given error code (usually taken from ANSI C's errno) // Throws an exception based on the given error code (usually taken from ANSI C's errno)
BaseException* Exception::FromErrno( const wxString& streamname, int errcode ) BaseException *Exception::FromErrno(const wxString &streamname, int errcode)
{ {
pxAssumeDev( errcode != 0, "Invalid NULL error code? (errno)" ); pxAssumeDev(errcode != 0, "Invalid NULL error code? (errno)");
switch( errcode ) switch (errcode) {
{ case EINVAL:
case EINVAL: pxFailDev(L"Invalid argument");
pxFailDev( L"Invalid argument" ); return &(new Exception::BadStream(streamname))->SetDiagMsg(L"Invalid argument? (likely caused by an unforgivable programmer error!)");
return &(new Exception::BadStream( streamname ))->SetDiagMsg(L"Invalid argument? (likely caused by an unforgivable programmer error!)" );
case EACCES: // Access denied! case EACCES: // Access denied!
return new Exception::AccessDenied( streamname ); return new Exception::AccessDenied(streamname);
case EMFILE: // Too many open files! case EMFILE: // Too many open files!
return &(new Exception::CannotCreateStream( streamname ))->SetDiagMsg(L"Too many open files"); // File handle allocation failure return &(new Exception::CannotCreateStream(streamname))->SetDiagMsg(L"Too many open files"); // File handle allocation failure
case EEXIST: case EEXIST:
return &(new Exception::CannotCreateStream( streamname ))->SetDiagMsg(L"File already exists"); return &(new Exception::CannotCreateStream(streamname))->SetDiagMsg(L"File already exists");
case ENOENT: // File not found! case ENOENT: // File not found!
return new Exception::FileNotFound( streamname ); return new Exception::FileNotFound(streamname);
case EPIPE: case EPIPE:
return &(new Exception::BadStream( streamname ))->SetDiagMsg(L"Broken pipe"); return &(new Exception::BadStream(streamname))->SetDiagMsg(L"Broken pipe");
case EBADF: case EBADF:
return &(new Exception::BadStream( streamname ))->SetDiagMsg(L"Bad file number"); return &(new Exception::BadStream(streamname))->SetDiagMsg(L"Bad file number");
default: default:
return &(new Exception::BadStream( streamname ))->SetDiagMsg(pxsFmt( L"General file/stream error [errno: %d]", errcode )); return &(new Exception::BadStream(streamname))->SetDiagMsg(pxsFmt(L"General file/stream error [errno: %d]", errcode));
} }
} }

View File

@ -24,9 +24,9 @@ template class SafeArray<char>;
template class SafeArray<wchar_t>; template class SafeArray<wchar_t>;
template class SafeArray<u8>; template class SafeArray<u8>;
template class SafeAlignedArray<char,16>; template class SafeAlignedArray<char, 16>;
template class SafeAlignedArray<wchar_t,16>; template class SafeAlignedArray<wchar_t, 16>;
template class SafeAlignedArray<u8,16>; template class SafeAlignedArray<u8, 16>;
// Sanity check: truncate strings if they exceed 512k in length. Anything like that // Sanity check: truncate strings if they exceed 512k in length. Anything like that
// is either a bug or really horrible code that needs to be stopped before it causes // is either a bug or really horrible code that needs to be stopped before it causes
@ -35,82 +35,86 @@ static const int MaxFormattedStringLength = 0x80000;
static static
#ifndef __linux__ #ifndef __linux__
__ri __ri
#endif #endif
void format_that_ascii_mess( CharBufferType& buffer, uint writepos, const char* fmt, va_list argptr ) void
format_that_ascii_mess(CharBufferType &buffer, uint writepos, const char *fmt, va_list argptr)
{ {
va_list args; va_list args;
while( true ) while (true) {
{ int size = buffer.GetLength();
int size = buffer.GetLength();
va_copy(args, argptr); va_copy(args, argptr);
int len = vsnprintf(buffer.GetPtr(writepos), size-writepos, fmt, args); int len = vsnprintf(buffer.GetPtr(writepos), size - writepos, fmt, args);
va_end(args); va_end(args);
// some implementations of vsnprintf() don't NUL terminate // some implementations of vsnprintf() don't NUL terminate
// the string if there is not enough space for it so // the string if there is not enough space for it so
// always do it manually // always do it manually
buffer[size-1] = '\0'; buffer[size - 1] = '\0';
if (size >= MaxFormattedStringLength) break; if (size >= MaxFormattedStringLength)
break;
// vsnprintf() may return either -1 (traditional Unix behavior) or the // vsnprintf() may return either -1 (traditional Unix behavior) or the
// total number of characters which would have been written if the // total number of characters which would have been written if the
// buffer were large enough (newer standards such as Unix98) // buffer were large enough (newer standards such as Unix98)
if (len < 0) if (len < 0)
len = size + (size/4); len = size + (size / 4);
len += writepos; len += writepos;
if (len < size) break; if (len < size)
buffer.Resize( len + 128 ); break;
}; buffer.Resize(len + 128);
};
// performing an assertion or log of a truncated string is unsafe, so let's not; even // performing an assertion or log of a truncated string is unsafe, so let's not; even
// though it'd be kinda nice if we did. // though it'd be kinda nice if we did.
} }
// returns the length of the formatted string, in characters (wxChars). // returns the length of the formatted string, in characters (wxChars).
static static
#ifndef __linux__ #ifndef __linux__
__ri __ri
#endif #endif
uint format_that_unicode_mess( CharBufferType& buffer, uint writepos, const wxChar* fmt, va_list argptr) uint
format_that_unicode_mess(CharBufferType &buffer, uint writepos, const wxChar *fmt, va_list argptr)
{ {
va_list args; va_list args;
while( true ) while (true) {
{ int size = buffer.GetLength() / sizeof(wxChar);
int size = buffer.GetLength() / sizeof(wxChar);
va_copy(args, argptr); va_copy(args, argptr);
int len = wxVsnprintf((wxChar*)buffer.GetPtr(writepos*sizeof(wxChar)), size-writepos, fmt, args); int len = wxVsnprintf((wxChar *)buffer.GetPtr(writepos * sizeof(wxChar)), size - writepos, fmt, args);
va_end(args); va_end(args);
// some implementations of vsnprintf() don't NUL terminate // some implementations of vsnprintf() don't NUL terminate
// the string if there is not enough space for it so // the string if there is not enough space for it so
// always do it manually // always do it manually
((wxChar*)buffer.GetPtr())[size-1] = L'\0'; ((wxChar *)buffer.GetPtr())[size - 1] = L'\0';
if( size >= MaxFormattedStringLength ) return size-1; if (size >= MaxFormattedStringLength)
return size - 1;
// vsnprintf() may return either -1 (traditional Unix behavior) or the // vsnprintf() may return either -1 (traditional Unix behavior) or the
// total number of characters which would have been written if the // total number of characters which would have been written if the
// buffer were large enough (newer standards such as Unix98) // buffer were large enough (newer standards such as Unix98)
if (len < 0) if (len < 0)
len = size + (size/4); len = size + (size / 4);
len += writepos; len += writepos;
if (len < size) return len; if (len < size)
buffer.Resize( (len + 128) * sizeof(wxChar) ); return len;
}; buffer.Resize((len + 128) * sizeof(wxChar));
};
// performing an assertion or log of a truncated string is unsafe, so let's not; even // performing an assertion or log of a truncated string is unsafe, so let's not; even
// though it'd be kinda nice if we did. // though it'd be kinda nice if we did.
pxAssume( false ); pxAssume(false);
return 0; // unreachable. return 0; // unreachable.
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -123,9 +127,9 @@ uint format_that_unicode_mess( CharBufferType& buffer, uint writepos, const wxCh
// this class nicely in its current state. --air // this class nicely in its current state. --air
FastFormatUnicode::FastFormatUnicode() FastFormatUnicode::FastFormatUnicode()
: m_dest(2048) : m_dest(2048)
{ {
Clear(); Clear();
} }
FastFormatUnicode::~FastFormatUnicode() throw() FastFormatUnicode::~FastFormatUnicode() throw()
@ -134,117 +138,117 @@ FastFormatUnicode::~FastFormatUnicode() throw()
void FastFormatUnicode::Clear() void FastFormatUnicode::Clear()
{ {
m_Length = 0; m_Length = 0;
((wxChar*)m_dest.GetPtr())[0] = 0; ((wxChar *)m_dest.GetPtr())[0] = 0;
} }
FastFormatUnicode& FastFormatUnicode::WriteV( const char* fmt, va_list argptr ) FastFormatUnicode &FastFormatUnicode::WriteV(const char *fmt, va_list argptr)
{ {
wxString converted( fromUTF8(FastFormatAscii().WriteV( fmt, argptr )) ); wxString converted(fromUTF8(FastFormatAscii().WriteV(fmt, argptr)));
const uint inspos = m_Length; const uint inspos = m_Length;
const uint convLen = converted.Length(); const uint convLen = converted.Length();
m_dest.MakeRoomFor((inspos + convLen + 64) * sizeof(wxChar)); m_dest.MakeRoomFor((inspos + convLen + 64) * sizeof(wxChar));
memcpy( &((wxChar*)m_dest.GetPtr())[inspos], converted.wc_str(), (convLen+1)*sizeof(wxChar) ); memcpy(&((wxChar *)m_dest.GetPtr())[inspos], converted.wc_str(), (convLen + 1) * sizeof(wxChar));
m_Length += convLen; m_Length += convLen;
return *this; return *this;
} }
FastFormatUnicode& FastFormatUnicode::WriteV( const wxChar* fmt, va_list argptr ) FastFormatUnicode &FastFormatUnicode::WriteV(const wxChar *fmt, va_list argptr)
{ {
m_Length = format_that_unicode_mess( m_dest, m_Length, fmt, argptr ); m_Length = format_that_unicode_mess(m_dest, m_Length, fmt, argptr);
return *this; return *this;
} }
FastFormatUnicode& FastFormatUnicode::Write( const char* fmt, ... ) FastFormatUnicode &FastFormatUnicode::Write(const char *fmt, ...)
{ {
va_list list; va_list list;
va_start(list, fmt); va_start(list, fmt);
WriteV(fmt,list); WriteV(fmt, list);
va_end(list); va_end(list);
return *this; return *this;
} }
FastFormatUnicode& FastFormatUnicode::Write( const wxChar* fmt, ... ) FastFormatUnicode &FastFormatUnicode::Write(const wxChar *fmt, ...)
{ {
va_list list; va_list list;
va_start(list, fmt); va_start(list, fmt);
WriteV(fmt,list); WriteV(fmt, list);
va_end(list); va_end(list);
return *this; return *this;
} }
FastFormatUnicode& FastFormatUnicode::Write( const wxString fmt, ... ) FastFormatUnicode &FastFormatUnicode::Write(const wxString fmt, ...)
{ {
va_list list; va_list list;
va_start(list, fmt); va_start(list, fmt);
WriteV(fmt.wx_str(),list); WriteV(fmt.wx_str(), list);
va_end(list); va_end(list);
return *this; return *this;
} }
bool FastFormatUnicode::IsEmpty() const bool FastFormatUnicode::IsEmpty() const
{ {
return ((wxChar&)m_dest[0]) == 0; return ((wxChar &)m_dest[0]) == 0;
} }
FastFormatUnicode& FastFormatUnicode::ToUpper() FastFormatUnicode &FastFormatUnicode::ToUpper()
{ {
wxChar* ch = (wxChar*)m_dest.GetPtr(); wxChar *ch = (wxChar *)m_dest.GetPtr();
for ( uint i=0; i<m_Length; ++i, ++ch ) for (uint i = 0; i < m_Length; ++i, ++ch)
*ch = (wxChar)wxToupper(*ch); *ch = (wxChar)wxToupper(*ch);
return *this; return *this;
} }
FastFormatUnicode& FastFormatUnicode::ToLower() FastFormatUnicode &FastFormatUnicode::ToLower()
{ {
wxChar* ch = (wxChar*)m_dest.GetPtr(); wxChar *ch = (wxChar *)m_dest.GetPtr();
for ( uint i=0; i<m_Length; ++i, ++ch ) for (uint i = 0; i < m_Length; ++i, ++ch)
*ch = (wxChar)wxTolower(*ch); *ch = (wxChar)wxTolower(*ch);
return *this; return *this;
} }
FastFormatUnicode& FastFormatUnicode::operator+=(const char* psz ) FastFormatUnicode &FastFormatUnicode::operator+=(const char *psz)
{ {
Write( L"%s", WX_STR(fromUTF8(psz)) ); Write(L"%s", WX_STR(fromUTF8(psz)));
return *this; return *this;
} }
wxString& operator+=(wxString& str1, const FastFormatUnicode& str2) wxString &operator+=(wxString &str1, const FastFormatUnicode &str2)
{ {
str1.Append(str2.c_str(), str2.Length()); str1.Append(str2.c_str(), str2.Length());
return str1; return str1;
} }
wxString operator+(const wxString& str1, const FastFormatUnicode& str2) wxString operator+(const wxString &str1, const FastFormatUnicode &str2)
{ {
wxString s = str1; wxString s = str1;
s += str2; s += str2;
return s; return s;
} }
wxString operator+(const wxChar* str1, const FastFormatUnicode& str2) wxString operator+(const wxChar *str1, const FastFormatUnicode &str2)
{ {
wxString s = str1; wxString s = str1;
s += str2; s += str2;
return s; return s;
} }
wxString operator+(const FastFormatUnicode& str1, const wxString& str2) wxString operator+(const FastFormatUnicode &str1, const wxString &str2)
{ {
wxString s = str1; wxString s = str1;
s += str2; s += str2;
return s; return s;
} }
wxString operator+(const FastFormatUnicode& str1, const wxChar* str2) wxString operator+(const FastFormatUnicode &str1, const wxChar *str2)
{ {
wxString s = str1; wxString s = str1;
s += str2; s += str2;
return s; return s;
} }
@ -252,9 +256,9 @@ wxString operator+(const FastFormatUnicode& str1, const wxChar* str2)
// FastFormatAscii (implementations) // FastFormatAscii (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
FastFormatAscii::FastFormatAscii() FastFormatAscii::FastFormatAscii()
: m_dest(2048) : m_dest(2048)
{ {
Clear(); Clear();
} }
FastFormatAscii::~FastFormatAscii() throw() FastFormatAscii::~FastFormatAscii() throw()
@ -263,31 +267,31 @@ FastFormatAscii::~FastFormatAscii() throw()
void FastFormatAscii::Clear() void FastFormatAscii::Clear()
{ {
m_dest.GetPtr()[0] = 0; m_dest.GetPtr()[0] = 0;
} }
const wxString FastFormatAscii::GetString() const const wxString FastFormatAscii::GetString() const
{ {
return fromAscii(m_dest.GetPtr()); return fromAscii(m_dest.GetPtr());
} }
FastFormatAscii& FastFormatAscii::WriteV( const char* fmt, va_list argptr ) FastFormatAscii &FastFormatAscii::WriteV(const char *fmt, va_list argptr)
{ {
format_that_ascii_mess( m_dest, strlen(m_dest.GetPtr()), fmt, argptr ); format_that_ascii_mess(m_dest, strlen(m_dest.GetPtr()), fmt, argptr);
return *this; return *this;
} }
FastFormatAscii& FastFormatAscii::Write( const char* fmt, ... ) FastFormatAscii &FastFormatAscii::Write(const char *fmt, ...)
{ {
va_list list; va_list list;
va_start(list, fmt); va_start(list, fmt);
WriteV(fmt,list); WriteV(fmt, list);
va_end(list); va_end(list);
return *this; return *this;
} }
bool FastFormatAscii::IsEmpty() const bool FastFormatAscii::IsEmpty() const
{ {
return m_dest[0] == 0; return m_dest[0] == 0;
} }

View File

@ -16,9 +16,10 @@
#include "PrecompiledHeader.h" #include "PrecompiledHeader.h"
#include "HashMap.h" #include "HashMap.h"
namespace HashTools { namespace HashTools
{
#define get16bits(d) (*((const u16 *) (d))) #define get16bits(d) (*((const u16 *)(d)))
/// <summary> /// <summary>
/// Calculates a hash value for an arbitrary set of binary data. /// Calculates a hash value for an arbitrary set of binary data.
@ -52,51 +53,53 @@ namespace HashTools {
/// uint32 hashval = Hash( (const char*)&data, sizeof( data ) ); /// uint32 hashval = Hash( (const char*)&data, sizeof( data ) );
/// </code> /// </code>
/// </example> /// </example>
u32 Hash(const s8 * data, int len) u32 Hash(const s8 *data, int len)
{ {
u32 hash = len; u32 hash = len;
int rem; int rem;
if (len <= 0 || data == NULL) return 0; if (len <= 0 || data == NULL)
return 0;
rem = len & 3; rem = len & 3;
len >>= 2; len >>= 2;
/* Main loop */ /* Main loop */
for (;len > 0; --len) for (; len > 0; --len) {
{ hash += get16bits(data);
hash += get16bits (data); u32 tmp = (get16bits(data + 2) << 11) ^ hash;
u32 tmp = (get16bits (data+2) << 11) ^ hash; hash = (hash << 16) ^ tmp;
hash = (hash << 16) ^ tmp; data += 2 * sizeof(u16);
data += 2*sizeof (u16); hash += hash >> 11;
hash += hash >> 11; }
}
/* Handle end cases */ /* Handle end cases */
switch (rem) switch (rem) {
{ case 3:
case 3: hash += get16bits (data); hash += get16bits(data);
hash ^= hash << 16; hash ^= hash << 16;
hash ^= data[sizeof (u16)] << 18; hash ^= data[sizeof(u16)] << 18;
hash += hash >> 11; hash += hash >> 11;
break; break;
case 2: hash += get16bits (data); case 2:
hash ^= hash << 11; hash += get16bits(data);
hash += hash >> 17; hash ^= hash << 11;
break; hash += hash >> 17;
case 1: hash += *data; break;
hash ^= hash << 10; case 1:
hash += hash >> 1; hash += *data;
} hash ^= hash << 10;
hash += hash >> 1;
}
/* Force "avalanching" of final 127 bits */ /* Force "avalanching" of final 127 bits */
hash ^= hash << 3; hash ^= hash << 3;
hash += hash >> 5; hash += hash >> 5;
hash ^= hash << 4; hash ^= hash << 4;
hash += hash >> 17; hash += hash >> 17;
hash ^= hash << 25; hash ^= hash << 25;
hash += hash >> 6; hash += hash >> 6;
return hash; return hash;
} }
} }

View File

@ -18,7 +18,7 @@
#include <wx/gdicmn.h> #include <wx/gdicmn.h>
const wxRect wxDefaultRect( wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, wxDefaultCoord ); const wxRect wxDefaultRect(wxDefaultCoord, wxDefaultCoord, wxDefaultCoord, wxDefaultCoord);
// Implement FixedPointTypes (for lack of a better location, for now) // Implement FixedPointTypes (for lack of a better location, for now)
@ -27,369 +27,396 @@ template struct FixedInt<100>;
template struct FixedInt<256>; template struct FixedInt<256>;
wxDirName g_fullBaseDirName = wxDirName(L""); wxDirName g_fullBaseDirName = wxDirName(L"");
void SetFullBaseDir( wxDirName appRoot ) void SetFullBaseDir(wxDirName appRoot)
{ {
g_fullBaseDirName = appRoot; g_fullBaseDirName = appRoot;
} }
static int _calcEnumLength( const wxChar* const* enumArray ) static int _calcEnumLength(const wxChar *const *enumArray)
{ {
int cnt = 0; int cnt = 0;
while( *enumArray != NULL ) while (*enumArray != NULL) {
{ enumArray++;
enumArray++; cnt++;
cnt++; }
}
return cnt; return cnt;
} }
ScopedIniGroup::ScopedIniGroup( IniInterface& mommy, const wxString& group ) ScopedIniGroup::ScopedIniGroup(IniInterface &mommy, const wxString &group)
: m_mom( mommy ) : m_mom(mommy)
{ {
pxAssertDev( wxStringTokenize( group, L"/" ).Count() <= 1, L"Cannot nest more than one group deep per instance of ScopedIniGroup." ); pxAssertDev(wxStringTokenize(group, L"/").Count() <= 1, L"Cannot nest more than one group deep per instance of ScopedIniGroup.");
m_mom.SetPath( group ); m_mom.SetPath(group);
} }
ScopedIniGroup::~ScopedIniGroup() ScopedIniGroup::~ScopedIniGroup()
{ {
m_mom.SetPath( L".." ); m_mom.SetPath(L"..");
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// IniInterface (implementations) // IniInterface (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
IniInterface::IniInterface( wxConfigBase& config ) IniInterface::IniInterface(wxConfigBase &config)
{ {
m_Config = &config; m_Config = &config;
} }
IniInterface::IniInterface( wxConfigBase* config ) IniInterface::IniInterface(wxConfigBase *config)
{ {
m_Config = config; m_Config = config;
} }
IniInterface::IniInterface() IniInterface::IniInterface()
{ {
m_Config = wxConfigBase::Get( false ); m_Config = wxConfigBase::Get(false);
} }
IniInterface::~IniInterface() IniInterface::~IniInterface()
{ {
Flush(); Flush();
} }
void IniInterface::SetPath( const wxString& path ) void IniInterface::SetPath(const wxString &path)
{ {
if( m_Config ) m_Config->SetPath( path ); if (m_Config)
m_Config->SetPath(path);
} }
void IniInterface::Flush() void IniInterface::Flush()
{ {
if( m_Config ) m_Config->Flush(); if (m_Config)
m_Config->Flush();
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// IniLoader (implementations) // IniLoader (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
IniLoader::IniLoader( wxConfigBase& config ) : IniInterface( config ) { } IniLoader::IniLoader(wxConfigBase &config)
IniLoader::IniLoader( wxConfigBase* config ) : IniInterface( config ) { } : IniInterface(config)
{
}
IniLoader::IniLoader(wxConfigBase *config)
: IniInterface(config)
{
}
IniLoader::IniLoader() : IniInterface() {} IniLoader::IniLoader()
: IniInterface()
{
}
IniLoader::~IniLoader() throw() {} IniLoader::~IniLoader() throw() {}
void IniLoader::Entry( const wxString& var, wxString& value, const wxString defvalue ) void IniLoader::Entry(const wxString &var, wxString &value, const wxString defvalue)
{ {
if( m_Config ) if (m_Config)
m_Config->Read( var, &value, defvalue ); m_Config->Read(var, &value, defvalue);
else else
value = defvalue; value = defvalue;
} }
void IniLoader::Entry( const wxString& var, wxDirName& value, const wxDirName defvalue, bool isAllowRelative ) void IniLoader::Entry(const wxString &var, wxDirName &value, const wxDirName defvalue, bool isAllowRelative)
{ {
wxString dest; wxString dest;
if( m_Config ) m_Config->Read( var, &dest, wxEmptyString ); if (m_Config)
m_Config->Read(var, &dest, wxEmptyString);
if( dest.IsEmpty() ) if (dest.IsEmpty())
value = defvalue; value = defvalue;
else else {
{ value = dest;
value = dest; if (isAllowRelative)
if( isAllowRelative ) value = g_fullBaseDirName + value;
value = g_fullBaseDirName + value;
if( value.IsAbsolute() ) if (value.IsAbsolute())
value.Normalize(); value.Normalize();
} }
} }
void IniLoader::Entry( const wxString& var, wxFileName& value, const wxFileName defvalue, bool isAllowRelative ) void IniLoader::Entry(const wxString &var, wxFileName &value, const wxFileName defvalue, bool isAllowRelative)
{ {
wxString dest( defvalue.GetFullPath() ); wxString dest(defvalue.GetFullPath());
if( m_Config ) m_Config->Read( var, &dest, defvalue.GetFullPath() ); if (m_Config)
value = dest; m_Config->Read(var, &dest, defvalue.GetFullPath());
if( isAllowRelative ) value = dest;
value = g_fullBaseDirName + value; if (isAllowRelative)
value = g_fullBaseDirName + value;
if( value.IsAbsolute() ) if (value.IsAbsolute())
value.Normalize(); value.Normalize();
if (value.HasVolume()) if (value.HasVolume())
value.SetVolume(value.GetVolume().Upper()); value.SetVolume(value.GetVolume().Upper());
} }
void IniLoader::Entry( const wxString& var, int& value, const int defvalue ) void IniLoader::Entry(const wxString &var, int &value, const int defvalue)
{ {
if( m_Config ) if (m_Config)
m_Config->Read( var, &value, defvalue ); m_Config->Read(var, &value, defvalue);
else else
value = defvalue; value = defvalue;
} }
void IniLoader::Entry( const wxString& var, uint& value, const uint defvalue ) void IniLoader::Entry(const wxString &var, uint &value, const uint defvalue)
{ {
if( m_Config ) if (m_Config)
m_Config->Read( var, (int*)&value, (int)defvalue ); m_Config->Read(var, (int *)&value, (int)defvalue);
else else
value = defvalue; value = defvalue;
} }
void IniLoader::Entry( const wxString& var, bool& value, const bool defvalue ) void IniLoader::Entry(const wxString &var, bool &value, const bool defvalue)
{ {
// TODO : Stricter value checking on enabled/disabled? // TODO : Stricter value checking on enabled/disabled?
wxString dest(defvalue ? L"enabled" : L"disabled"); wxString dest(defvalue ? L"enabled" : L"disabled");
if( m_Config ) m_Config->Read( var, &dest, dest ); if (m_Config)
value = (dest == L"enabled") || (dest == L"1"); m_Config->Read(var, &dest, dest);
value = (dest == L"enabled") || (dest == L"1");
} }
bool IniLoader::EntryBitBool( const wxString& var, bool value, const bool defvalue ) bool IniLoader::EntryBitBool(const wxString &var, bool value, const bool defvalue)
{ {
// Note: 'value' param is used by inisaver only. // Note: 'value' param is used by inisaver only.
bool result; bool result;
Entry( var, result, defvalue ); Entry(var, result, defvalue);
return result; return result;
} }
int IniLoader::EntryBitfield( const wxString& var, int value, const int defvalue ) int IniLoader::EntryBitfield(const wxString &var, int value, const int defvalue)
{ {
int result; int result;
Entry( var, result, defvalue ); Entry(var, result, defvalue);
return result; return result;
} }
void IniLoader::Entry( const wxString& var, Fixed100& value, const Fixed100 defvalue ) void IniLoader::Entry(const wxString &var, Fixed100 &value, const Fixed100 defvalue)
{ {
// Note: the "easy" way would be to convert to double and load/save that, but floating point // Note: the "easy" way would be to convert to double and load/save that, but floating point
// has way too much rounding error so we really need to do things out manually.. >_< // has way too much rounding error so we really need to do things out manually.. >_<
wxString readval( value.ToString() ); wxString readval(value.ToString());
if( m_Config ) m_Config->Read( var, &readval ); if (m_Config)
value = Fixed100::FromString( readval, value ); m_Config->Read(var, &readval);
value = Fixed100::FromString(readval, value);
} }
void IniLoader::Entry( const wxString& var, wxPoint& value, const wxPoint defvalue ) void IniLoader::Entry(const wxString &var, wxPoint &value, const wxPoint defvalue)
{ {
if( !m_Config ) if (!m_Config) {
{ value = defvalue;
value = defvalue; return; return;
} }
TryParse( value, m_Config->Read( var, ToString( defvalue ) ), defvalue ); TryParse(value, m_Config->Read(var, ToString(defvalue)), defvalue);
} }
void IniLoader::Entry( const wxString& var, wxSize& value, const wxSize defvalue ) void IniLoader::Entry(const wxString &var, wxSize &value, const wxSize defvalue)
{ {
if( !m_Config ) if (!m_Config) {
{ value = defvalue;
value = defvalue; return; return;
} }
TryParse( value, m_Config->Read( var, ToString( defvalue ) ), defvalue ); TryParse(value, m_Config->Read(var, ToString(defvalue)), defvalue);
} }
void IniLoader::Entry( const wxString& var, wxRect& value, const wxRect defvalue ) void IniLoader::Entry(const wxString &var, wxRect &value, const wxRect defvalue)
{ {
if( !m_Config ) if (!m_Config) {
{ value = defvalue;
value = defvalue; return; return;
} }
TryParse( value, m_Config->Read( var, ToString( defvalue ) ), defvalue ); TryParse(value, m_Config->Read(var, ToString(defvalue)), defvalue);
} }
void IniLoader::_EnumEntry( const wxString& var, int& value, const wxChar* const* enumArray, int defvalue ) void IniLoader::_EnumEntry(const wxString &var, int &value, const wxChar *const *enumArray, int defvalue)
{ {
// Confirm default value sanity... // Confirm default value sanity...
const int cnt = _calcEnumLength( enumArray ); const int cnt = _calcEnumLength(enumArray);
if( !IndexBoundsCheck( L"IniLoader EnumDefaultValue", defvalue, cnt ) ) if (!IndexBoundsCheck(L"IniLoader EnumDefaultValue", defvalue, cnt)) {
{ Console.Error("(LoadSettings) Default enumeration index is out of bounds. Truncating.");
Console.Error( "(LoadSettings) Default enumeration index is out of bounds. Truncating." ); defvalue = cnt - 1;
defvalue = cnt-1; }
}
// Sanity confirmed, proceed with craziness! // Sanity confirmed, proceed with craziness!
if( !m_Config ) if (!m_Config) {
{ value = defvalue;
value = defvalue; return;
return; }
}
wxString retval; wxString retval;
m_Config->Read( var, &retval, enumArray[defvalue] ); m_Config->Read(var, &retval, enumArray[defvalue]);
int i=0; int i = 0;
while( enumArray[i] != NULL && ( retval != enumArray[i] ) ) i++; while (enumArray[i] != NULL && (retval != enumArray[i]))
i++;
if( enumArray[i] == NULL ) if (enumArray[i] == NULL) {
{ Console.Warning(L"(LoadSettings) Warning: Unrecognized value '%s' on key '%s'\n\tUsing the default setting of '%s'.",
Console.Warning( L"(LoadSettings) Warning: Unrecognized value '%s' on key '%s'\n\tUsing the default setting of '%s'.", WX_STR(retval), WX_STR(var), enumArray[defvalue]);
WX_STR(retval), WX_STR(var), enumArray[defvalue] value = defvalue;
); } else
value = defvalue; value = i;
}
else
value = i;
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// IniSaver (implementations) // IniSaver (implementations)
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
IniSaver::IniSaver( wxConfigBase& config ) : IniInterface( config ) { } IniSaver::IniSaver(wxConfigBase &config)
IniSaver::IniSaver( wxConfigBase* config ) : IniInterface( config ) { } : IniInterface(config)
{
}
IniSaver::IniSaver(wxConfigBase *config)
: IniInterface(config)
{
}
IniSaver::IniSaver() : IniInterface() {} IniSaver::IniSaver()
: IniInterface()
{
}
IniSaver::~IniSaver() {} IniSaver::~IniSaver() {}
void IniSaver::Entry( const wxString& var, wxString& value, const wxString defvalue ) void IniSaver::Entry(const wxString &var, wxString &value, const wxString defvalue)
{ {
if( !m_Config ) return; if (!m_Config)
m_Config->Write( var, value ); return;
m_Config->Write(var, value);
} }
void IniSaver::Entry( const wxString& var, wxDirName& value, const wxDirName defvalue, bool isAllowRelative ) void IniSaver::Entry(const wxString &var, wxDirName &value, const wxDirName defvalue, bool isAllowRelative)
{ {
if( !m_Config ) return; if (!m_Config)
wxDirName res(value); return;
wxDirName res(value);
if ( res.IsAbsolute() ) if (res.IsAbsolute())
res.Normalize(); res.Normalize();
if (isAllowRelative) if (isAllowRelative)
res = wxDirName::MakeAutoRelativeTo( res, g_fullBaseDirName.ToString() ); res = wxDirName::MakeAutoRelativeTo(res, g_fullBaseDirName.ToString());
/*if( value == defvalue ) /*if( value == defvalue )
m_Config->Write( var, wxString() ); m_Config->Write( var, wxString() );
else*/ else*/
m_Config->Write( var, res.ToString() ); m_Config->Write(var, res.ToString());
} }
void IniSaver::Entry( const wxString& var, wxFileName& value, const wxFileName defvalue, bool isAllowRelative ) void IniSaver::Entry(const wxString &var, wxFileName &value, const wxFileName defvalue, bool isAllowRelative)
{ {
if( !m_Config ) return; if (!m_Config)
wxFileName res(value); return;
wxFileName res(value);
if ( res.IsAbsolute() ) if (res.IsAbsolute())
res.Normalize(); res.Normalize();
if (isAllowRelative) if (isAllowRelative)
res = wxDirName::MakeAutoRelativeTo( res, g_fullBaseDirName.ToString() ); res = wxDirName::MakeAutoRelativeTo(res, g_fullBaseDirName.ToString());
m_Config->Write( var, res.GetFullPath() ); m_Config->Write(var, res.GetFullPath());
} }
void IniSaver::Entry( const wxString& var, int& value, const int defvalue ) void IniSaver::Entry(const wxString &var, int &value, const int defvalue)
{ {
if( !m_Config ) return; if (!m_Config)
m_Config->Write( var, value ); return;
m_Config->Write(var, value);
} }
void IniSaver::Entry( const wxString& var, uint& value, const uint defvalue ) void IniSaver::Entry(const wxString &var, uint &value, const uint defvalue)
{ {
if( !m_Config ) return; if (!m_Config)
m_Config->Write( var, (int)value ); return;
m_Config->Write(var, (int)value);
} }
void IniSaver::Entry( const wxString& var, bool& value, const bool defvalue ) void IniSaver::Entry(const wxString &var, bool &value, const bool defvalue)
{ {
if( !m_Config ) return; if (!m_Config)
m_Config->Write( var, value ? L"enabled" : L"disabled" ); return;
m_Config->Write(var, value ? L"enabled" : L"disabled");
} }
bool IniSaver::EntryBitBool( const wxString& var, bool value, const bool defvalue ) bool IniSaver::EntryBitBool(const wxString &var, bool value, const bool defvalue)
{ {
if( m_Config ) m_Config->Write( var, value ? L"enabled" : L"disabled" ); if (m_Config)
return value; m_Config->Write(var, value ? L"enabled" : L"disabled");
return value;
} }
int IniSaver::EntryBitfield( const wxString& var, int value, const int defvalue ) int IniSaver::EntryBitfield(const wxString &var, int value, const int defvalue)
{ {
if( m_Config ) m_Config->Write( var, value ); if (m_Config)
return value; m_Config->Write(var, value);
return value;
} }
void IniSaver::Entry( const wxString& var, Fixed100& value, const Fixed100 defvalue ) void IniSaver::Entry(const wxString &var, Fixed100 &value, const Fixed100 defvalue)
{ {
if( !m_Config ) return; if (!m_Config)
return;
// Note: the "easy" way would be to convert to double and load/save that, but floating point // Note: the "easy" way would be to convert to double and load/save that, but floating point
// has way too much rounding error so we really need to do things out manually, using strings. // has way too much rounding error so we really need to do things out manually, using strings.
m_Config->Write( var, value.ToString() ); m_Config->Write(var, value.ToString());
} }
void IniSaver::Entry( const wxString& var, wxPoint& value, const wxPoint defvalue ) void IniSaver::Entry(const wxString &var, wxPoint &value, const wxPoint defvalue)
{ {
if( !m_Config ) return; if (!m_Config)
m_Config->Write( var, ToString( value ) ); return;
m_Config->Write(var, ToString(value));
} }
void IniSaver::Entry( const wxString& var, wxSize& value, const wxSize defvalue ) void IniSaver::Entry(const wxString &var, wxSize &value, const wxSize defvalue)
{ {
if( !m_Config ) return; if (!m_Config)
m_Config->Write( var, ToString( value ) ); return;
m_Config->Write(var, ToString(value));
} }
void IniSaver::Entry( const wxString& var, wxRect& value, const wxRect defvalue ) void IniSaver::Entry(const wxString &var, wxRect &value, const wxRect defvalue)
{ {
if( !m_Config ) return; if (!m_Config)
m_Config->Write( var, ToString( value ) ); return;
m_Config->Write(var, ToString(value));
} }
void IniSaver::_EnumEntry( const wxString& var, int& value, const wxChar* const* enumArray, int defvalue ) void IniSaver::_EnumEntry(const wxString &var, int &value, const wxChar *const *enumArray, int defvalue)
{ {
const int cnt = _calcEnumLength( enumArray ); const int cnt = _calcEnumLength(enumArray);
// Confirm default value sanity... // Confirm default value sanity...
if( !IndexBoundsCheck( L"IniSaver EnumDefaultValue", defvalue, cnt ) ) if (!IndexBoundsCheck(L"IniSaver EnumDefaultValue", defvalue, cnt)) {
{ Console.Error("(SaveSettings) Default enumeration index is out of bounds. Truncating.");
Console.Error( "(SaveSettings) Default enumeration index is out of bounds. Truncating." ); defvalue = cnt - 1;
defvalue = cnt-1; }
}
if( !m_Config ) return; if (!m_Config)
return;
if( value >= cnt ) if (value >= cnt) {
{ Console.Warning(L"(SaveSettings) An illegal enumerated index was detected when saving '%s'", WX_STR(var));
Console.Warning( L"(SaveSettings) An illegal enumerated index was detected when saving '%s'", WX_STR(var) ); Console.Indent().Warning(
Console.Indent().Warning( L"Illegal Value: %d\n"
L"Illegal Value: %d\n" L"Using Default: %d (%s)\n",
L"Using Default: %d (%s)\n", value, defvalue, enumArray[defvalue]);
value, defvalue, enumArray[defvalue]
);
// Cause a debug assertion, since this is a fully recoverable error. // Cause a debug assertion, since this is a fully recoverable error.
pxAssert( value < cnt ); pxAssert(value < cnt);
value = defvalue; value = defvalue;
} }
m_Config->Write( var, enumArray[value] ); m_Config->Write(var, enumArray[value]);
} }

View File

@ -27,205 +27,206 @@
// Apple uses the MAP_ANON define instead of MAP_ANONYMOUS, but they mean // Apple uses the MAP_ANON define instead of MAP_ANONYMOUS, but they mean
// the same thing. // the same thing.
#if defined(__APPLE__) && !defined(MAP_ANONYMOUS) #if defined(__APPLE__) && !defined(MAP_ANONYMOUS)
# define MAP_ANONYMOUS MAP_ANON #define MAP_ANONYMOUS MAP_ANON
#endif #endif
extern void SignalExit(int sig); extern void SignalExit(int sig);
static const uptr m_pagemask = getpagesize()-1; static const uptr m_pagemask = getpagesize() - 1;
// Linux implementation of SIGSEGV handler. Bind it using sigaction(). // Linux implementation of SIGSEGV handler. Bind it using sigaction().
static void SysPageFaultSignalFilter( int signal, siginfo_t *siginfo, void * ) static void SysPageFaultSignalFilter(int signal, siginfo_t *siginfo, void *)
{ {
// [TODO] : Add a thread ID filter to the Linux Signal handler here. // [TODO] : Add a thread ID filter to the Linux Signal handler here.
// Rationale: On windows, the __try/__except model allows per-thread specific behavior // Rationale: On windows, the __try/__except model allows per-thread specific behavior
// for page fault handling. On linux, there is a single signal handler for the whole // for page fault handling. On linux, there is a single signal handler for the whole
// process, but the handler is executed by the thread that caused the exception. // process, but the handler is executed by the thread that caused the exception.
// Stdio Usage note: SIGSEGV handling is a synchronous in-thread signal. It is done // Stdio Usage note: SIGSEGV handling is a synchronous in-thread signal. It is done
// from the context of the current thread and stackframe. So long as the thread is not // from the context of the current thread and stackframe. So long as the thread is not
// the main/ui thread, use of the px assertion system should be safe. Use of stdio should // the main/ui thread, use of the px assertion system should be safe. Use of stdio should
// be safe even on the main thread. // be safe even on the main thread.
// (in other words, stdio limitations only really apply to process-level asynchronous // (in other words, stdio limitations only really apply to process-level asynchronous
// signals) // signals)
// Note: Use of stdio functions isn't safe here. Avoid console logs, // Note: Use of stdio functions isn't safe here. Avoid console logs,
// assertions, file logs, or just about anything else useful. // assertions, file logs, or just about anything else useful.
// Note: This signal can be accessed by the EE or MTVU thread // Note: This signal can be accessed by the EE or MTVU thread
// Source_PageFault is a global variable with its own state information // Source_PageFault is a global variable with its own state information
// so for now we lock this exception code unless someone can fix this better... // so for now we lock this exception code unless someone can fix this better...
Threading::ScopedLock lock(PageFault_Mutex); Threading::ScopedLock lock(PageFault_Mutex);
Source_PageFault->Dispatch( PageFaultInfo( (uptr)siginfo->si_addr & ~m_pagemask ) ); Source_PageFault->Dispatch(PageFaultInfo((uptr)siginfo->si_addr & ~m_pagemask));
// resumes execution right where we left off (re-executes instruction that // resumes execution right where we left off (re-executes instruction that
// caused the SIGSEGV). // caused the SIGSEGV).
if (Source_PageFault->WasHandled()) return; if (Source_PageFault->WasHandled())
return;
if (!wxThread::IsMain()) if (!wxThread::IsMain()) {
{ pxFailRel(pxsFmt("Unhandled page fault @ 0x%08x", siginfo->si_addr));
pxFailRel(pxsFmt("Unhandled page fault @ 0x%08x", siginfo->si_addr)); }
}
// Bad mojo! Completely invalid address. // Bad mojo! Completely invalid address.
// Instigate a trap if we're in a debugger, and if not then do a SIGKILL. // Instigate a trap if we're in a debugger, and if not then do a SIGKILL.
pxTrap(); pxTrap();
if (!IsDebugBuild) raise( SIGKILL ); if (!IsDebugBuild)
raise(SIGKILL);
} }
void _platform_InstallSignalHandler() void _platform_InstallSignalHandler()
{ {
Console.WriteLn("Installing POSIX SIGSEGV handler..."); Console.WriteLn("Installing POSIX SIGSEGV handler...");
struct sigaction sa; struct sigaction sa;
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO; sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = SysPageFaultSignalFilter; sa.sa_sigaction = SysPageFaultSignalFilter;
sigaction(SIGSEGV, &sa, NULL); sigaction(SIGSEGV, &sa, NULL);
} }
static __ri void PageSizeAssertionTest( size_t size ) static __ri void PageSizeAssertionTest(size_t size)
{ {
pxAssertMsg( (__pagesize == getpagesize()), pxsFmt( pxAssertMsg((__pagesize == getpagesize()), pxsFmt(
"Internal system error: Operating system pagesize does not match compiled pagesize.\n\t" "Internal system error: Operating system pagesize does not match compiled pagesize.\n\t"
L"\tOS Page Size: 0x%x (%d), Compiled Page Size: 0x%x (%u)", L"\tOS Page Size: 0x%x (%d), Compiled Page Size: 0x%x (%u)",
getpagesize(), getpagesize(), __pagesize, __pagesize ) getpagesize(), getpagesize(), __pagesize, __pagesize));
);
pxAssertDev( (size & (__pagesize-1)) == 0, pxsFmt( pxAssertDev((size & (__pagesize - 1)) == 0, pxsFmt(
L"Memory block size must be a multiple of the target platform's page size.\n" L"Memory block size must be a multiple of the target platform's page size.\n"
L"\tPage Size: 0x%x (%u), Block Size: 0x%x (%u)", L"\tPage Size: 0x%x (%u), Block Size: 0x%x (%u)",
__pagesize, __pagesize, size, size ) __pagesize, __pagesize, size, size));
);
} }
// returns FALSE if the mprotect call fails with an ENOMEM. // returns FALSE if the mprotect call fails with an ENOMEM.
// Raises assertions on other types of POSIX errors (since those typically reflect invalid object // Raises assertions on other types of POSIX errors (since those typically reflect invalid object
// or memory states). // or memory states).
static bool _memprotect( void* baseaddr, size_t size, const PageProtectionMode& mode ) static bool _memprotect(void *baseaddr, size_t size, const PageProtectionMode &mode)
{ {
PageSizeAssertionTest(size); PageSizeAssertionTest(size);
uint lnxmode = 0; uint lnxmode = 0;
if (mode.CanWrite()) lnxmode |= PROT_WRITE; if (mode.CanWrite())
if (mode.CanRead()) lnxmode |= PROT_READ; lnxmode |= PROT_WRITE;
if (mode.CanExecute()) lnxmode |= PROT_EXEC | PROT_READ; if (mode.CanRead())
lnxmode |= PROT_READ;
if (mode.CanExecute())
lnxmode |= PROT_EXEC | PROT_READ;
const int result = mprotect( baseaddr, size, lnxmode ); const int result = mprotect(baseaddr, size, lnxmode);
if (result == 0) return true; if (result == 0)
return true;
switch(errno) switch (errno) {
{ case EINVAL:
case EINVAL: pxFailDev(pxsFmt(L"mprotect returned EINVAL @ 0x%08X -> 0x%08X (mode=%s)",
pxFailDev(pxsFmt(L"mprotect returned EINVAL @ 0x%08X -> 0x%08X (mode=%s)", baseaddr, (uptr)baseaddr + size, WX_STR(mode.ToString())));
baseaddr, (uptr)baseaddr+size, WX_STR(mode.ToString())) break;
);
break;
case EACCES: case EACCES:
pxFailDev(pxsFmt(L"mprotect returned EACCES @ 0x%08X -> 0x%08X (mode=%s)", pxFailDev(pxsFmt(L"mprotect returned EACCES @ 0x%08X -> 0x%08X (mode=%s)",
baseaddr, (uptr)baseaddr+size, WX_STR(mode.ToString())) baseaddr, (uptr)baseaddr + size, WX_STR(mode.ToString())));
); break;
break;
case ENOMEM: case ENOMEM:
// caller handles assertion or exception, or whatever. // caller handles assertion or exception, or whatever.
break; break;
} }
return false; return false;
} }
void* HostSys::MmapReservePtr(void* base, size_t size) void *HostSys::MmapReservePtr(void *base, size_t size)
{ {
PageSizeAssertionTest(size); PageSizeAssertionTest(size);
// On linux a reserve-without-commit is performed by using mmap on a read-only // On linux a reserve-without-commit is performed by using mmap on a read-only
// or anonymous source, with PROT_NONE (no-access) permission. Since the mapping // or anonymous source, with PROT_NONE (no-access) permission. Since the mapping
// is completely inaccessible, the OS will simply reserve it and will not put it // is completely inaccessible, the OS will simply reserve it and will not put it
// against the commit table. // against the commit table.
return mmap(base, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); return mmap(base, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
} }
bool HostSys::MmapCommitPtr(void* base, size_t size, const PageProtectionMode& mode) bool HostSys::MmapCommitPtr(void *base, size_t size, const PageProtectionMode &mode)
{ {
// In linux, reserved memory is automatically committed when its permissions are // In linux, reserved memory is automatically committed when its permissions are
// changed to something other than PROT_NONE. If the user is committing memory // changed to something other than PROT_NONE. If the user is committing memory
// as PROT_NONE, then just ignore this call (memory will be committed automatically // as PROT_NONE, then just ignore this call (memory will be committed automatically
// later when the user changes permissions to something useful via calls to MemProtect). // later when the user changes permissions to something useful via calls to MemProtect).
if (mode.IsNone()) return false; if (mode.IsNone())
return false;
if (_memprotect( base, size, mode )) return true; if (_memprotect(base, size, mode))
return true;
if (!pxDoOutOfMemory) return false; if (!pxDoOutOfMemory)
pxDoOutOfMemory(size); return false;
return _memprotect( base, size, mode ); pxDoOutOfMemory(size);
return _memprotect(base, size, mode);
} }
void HostSys::MmapResetPtr(void* base, size_t size) void HostSys::MmapResetPtr(void *base, size_t size)
{ {
// On linux the only way to reset the memory is to unmap and remap it as PROT_NONE. // On linux the only way to reset the memory is to unmap and remap it as PROT_NONE.
// That forces linux to unload all committed pages and start from scratch. // That forces linux to unload all committed pages and start from scratch.
// FIXME: Ideally this code would have some threading lock on it to prevent any other // FIXME: Ideally this code would have some threading lock on it to prevent any other
// malloc/free code in the current process from interfering with the operation, but I // malloc/free code in the current process from interfering with the operation, but I
// can't think of any good way to do that. (generally it shouldn't be a problem in // can't think of any good way to do that. (generally it shouldn't be a problem in
// PCSX2 anyway, since MmapReset is only called when the ps2vm is suspended; so that // PCSX2 anyway, since MmapReset is only called when the ps2vm is suspended; so that
// pretty well stops all PCSX2 threads anyway). // pretty well stops all PCSX2 threads anyway).
Munmap(base, size); Munmap(base, size);
void* result = MmapReservePtr(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));
} }
void* HostSys::MmapReserve(uptr base, size_t size) void *HostSys::MmapReserve(uptr base, size_t size)
{ {
return MmapReservePtr((void*)base, size); return MmapReservePtr((void *)base, size);
} }
bool HostSys::MmapCommit(uptr base, size_t size, const PageProtectionMode& mode) bool HostSys::MmapCommit(uptr base, size_t size, const PageProtectionMode &mode)
{ {
return MmapCommitPtr( (void*)base, size, mode ); return MmapCommitPtr((void *)base, size, mode);
} }
void HostSys::MmapReset(uptr base, size_t size) void HostSys::MmapReset(uptr base, size_t size)
{ {
MmapResetPtr((void*)base, size); MmapResetPtr((void *)base, size);
} }
void* HostSys::Mmap(uptr base, size_t size) void *HostSys::Mmap(uptr base, size_t size)
{ {
PageSizeAssertionTest(size); PageSizeAssertionTest(size);
// MAP_ANONYMOUS - means we have no associated file handle (or device). // MAP_ANONYMOUS - means we have no associated file handle (or device).
return mmap((void*)base, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); return mmap((void *)base, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
} }
void HostSys::Munmap(uptr base, size_t size) void HostSys::Munmap(uptr base, size_t size)
{ {
if (!base) return; if (!base)
munmap((void*)base, size); return;
munmap((void *)base, size);
} }
void HostSys::MemProtect( void* baseaddr, size_t size, const PageProtectionMode& mode ) void HostSys::MemProtect(void *baseaddr, size_t size, const PageProtectionMode &mode)
{ {
if (!_memprotect(baseaddr, size, mode)) if (!_memprotect(baseaddr, size, mode)) {
{ throw Exception::OutOfMemory(L"MemProtect")
throw Exception::OutOfMemory( L"MemProtect" ) .SetDiagMsg(pxsFmt(L"mprotect failed @ 0x%08X -> 0x%08X (mode=%s)",
.SetDiagMsg(pxsFmt( L"mprotect failed @ 0x%08X -> 0x%08X (mode=%s)", baseaddr, (uptr)baseaddr + size, WX_STR(mode.ToString())));
baseaddr, (uptr)baseaddr+size, WX_STR(mode.ToString()) }
)
);
}
} }

View File

@ -24,13 +24,13 @@
// Returns 0 on failure (not supported by the operating system). // Returns 0 on failure (not supported by the operating system).
u64 GetPhysicalMemory() u64 GetPhysicalMemory()
{ {
u64 pages = 0; u64 pages = 0;
#ifdef _SC_PHYS_PAGES #ifdef _SC_PHYS_PAGES
pages = sysconf(_SC_PHYS_PAGES); pages = sysconf(_SC_PHYS_PAGES);
#endif #endif
return pages * getpagesize(); return pages * getpagesize();
} }
@ -40,22 +40,22 @@ void InitCPUTicks()
u64 GetTickFrequency() u64 GetTickFrequency()
{ {
return 1000000; // unix measures in microseconds return 1000000; // unix measures in microseconds
} }
u64 GetCPUTicks() u64 GetCPUTicks()
{ {
struct timeval t; struct timeval t;
gettimeofday(&t, NULL); gettimeofday(&t, NULL);
return ((u64)t.tv_sec*GetTickFrequency())+t.tv_usec; return ((u64)t.tv_sec * GetTickFrequency()) + t.tv_usec;
} }
wxString GetOSVersionString() wxString GetOSVersionString()
{ {
return wxGetOsDescription(); return wxGetOsDescription();
} }
void ScreensaverAllow(bool allow) void ScreensaverAllow(bool allow)
{ {
// no-op // no-op
} }

View File

@ -29,7 +29,7 @@
#if !defined(__unix__) #if !defined(__unix__)
# pragma message( "LnxThreads.cpp should only be compiled by projects or makefiles targeted at Linux/BSD distros.") #pragma message("LnxThreads.cpp should only be compiled by projects or makefiles targeted at Linux/BSD distros.")
#else #else
@ -37,23 +37,23 @@
// the LOCK prefix. The prefix works on single core CPUs fine (but is slow), but not // the LOCK prefix. The prefix works on single core CPUs fine (but is slow), but not
// having the LOCK prefix is very bad indeed. // having the LOCK prefix is very bad indeed.
__forceinline void Threading::Sleep( int ms ) __forceinline void Threading::Sleep(int ms)
{ {
usleep( 1000*ms ); usleep(1000 * ms);
} }
// For use in spin/wait loops, Acts as a hint to Intel CPUs and should, in theory // For use in spin/wait loops, Acts as a hint to Intel CPUs and should, in theory
// improve performance and reduce cpu power consumption. // improve performance and reduce cpu power consumption.
__forceinline void Threading::SpinWait() __forceinline void Threading::SpinWait()
{ {
// If this doesn't compile you can just comment it out (it only serves as a // If this doesn't compile you can just comment it out (it only serves as a
// performance hint and isn't required). // performance hint and isn't required).
__asm__ ( "pause" ); __asm__("pause");
} }
__forceinline void Threading::EnableHiresScheduler() __forceinline void Threading::EnableHiresScheduler()
{ {
// Don't know if linux has a customizable scheduler resolution like Windows (doubtful) // Don't know if linux has a customizable scheduler resolution like Windows (doubtful)
} }
__forceinline void Threading::DisableHiresScheduler() __forceinline void Threading::DisableHiresScheduler()
@ -63,66 +63,69 @@ __forceinline void Threading::DisableHiresScheduler()
// Unit of time of GetThreadCpuTime/GetCpuTime // Unit of time of GetThreadCpuTime/GetCpuTime
u64 Threading::GetThreadTicksPerSecond() u64 Threading::GetThreadTicksPerSecond()
{ {
return 1000000; return 1000000;
} }
// Helper function to get either either the current cpu usage // Helper function to get either either the current cpu usage
// in called thread or in id thread // in called thread or in id thread
static u64 get_thread_time(uptr id = 0) static u64 get_thread_time(uptr id = 0)
{ {
clockid_t cid; clockid_t cid;
if (id) { if (id) {
int err = pthread_getcpuclockid((pthread_t)id, &cid); int err = pthread_getcpuclockid((pthread_t)id, &cid);
if (err) return 0; if (err)
} else { return 0;
cid = CLOCK_THREAD_CPUTIME_ID; } else {
} cid = CLOCK_THREAD_CPUTIME_ID;
}
struct timespec ts; struct timespec ts;
int err = clock_gettime(cid, &ts); int err = clock_gettime(cid, &ts);
if (err) return 0; if (err)
return 0;
return (u64) ts.tv_sec * (u64) 1e6 + (u64) ts.tv_nsec / (u64) 1e3; return (u64)ts.tv_sec * (u64)1e6 + (u64)ts.tv_nsec / (u64)1e3;
} }
// Returns the current timestamp (not relative to a real world clock) // Returns the current timestamp (not relative to a real world clock)
u64 Threading::GetThreadCpuTime() u64 Threading::GetThreadCpuTime()
{ {
return get_thread_time(); return get_thread_time();
} }
u64 Threading::pxThread::GetCpuTime() const u64 Threading::pxThread::GetCpuTime() const
{ {
// Get the cpu time for the thread belonging to this object. Use m_native_id and/or // Get the cpu time for the thread belonging to this object. Use m_native_id and/or
// m_native_handle to implement it. Return value should be a measure of total time the // m_native_handle to implement it. Return value should be a measure of total time the
// thread has used on the CPU (scaled by the value returned by GetThreadTicksPerSecond(), // thread has used on the CPU (scaled by the value returned by GetThreadTicksPerSecond(),
// which typically would be an OS-provided scalar or some sort). // which typically would be an OS-provided scalar or some sort).
if (!m_native_id) return 0; if (!m_native_id)
return 0;
return get_thread_time(m_native_id); return get_thread_time(m_native_id);
} }
void Threading::pxThread::_platform_specific_OnStartInThread() void Threading::pxThread::_platform_specific_OnStartInThread()
{ {
// Obtain linux-specific thread IDs or Handles here, which can be used to query // Obtain linux-specific thread IDs or Handles here, which can be used to query
// kernel scheduler performance information. // kernel scheduler performance information.
m_native_id = (uptr) pthread_self(); m_native_id = (uptr)pthread_self();
} }
void Threading::pxThread::_platform_specific_OnCleanupInThread() void Threading::pxThread::_platform_specific_OnCleanupInThread()
{ {
// Cleanup handles here, which were opened above. // Cleanup handles here, which were opened above.
} }
void Threading::pxThread::_DoSetThreadName( const char* name ) void Threading::pxThread::_DoSetThreadName(const char *name)
{ {
#if defined(__linux__) #if defined(__linux__)
// Extract of manpage: "The name can be up to 16 bytes long, and should be // Extract of manpage: "The name can be up to 16 bytes long, and should be
// null-terminated if it contains fewer bytes." // null-terminated if it contains fewer bytes."
prctl(PR_SET_NAME, name, 0, 0, 0); prctl(PR_SET_NAME, name, 0, 0, 0);
#elif defined(__unix__) #elif defined(__unix__)
pthread_set_name_np(pthread_self(), name); pthread_set_name_np(pthread_self(), name);
#endif #endif
} }

View File

@ -23,8 +23,8 @@
namespace Threading namespace Threading
{ {
static std::atomic<int> _attr_refcount(0); static std::atomic<int> _attr_refcount(0);
static pthread_mutexattr_t _attr_recursive; static pthread_mutexattr_t _attr_recursive;
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -38,7 +38,7 @@ namespace Threading
// We have to emulate pthread_mutex_timedlock(). This could be a serious // We have to emulate pthread_mutex_timedlock(). This could be a serious
// performance drain if its used a lot. // performance drain if its used a lot.
#include <sys/time.h> // gettimeofday() #include <sys/time.h> // gettimeofday()
// sleep for 10ms at a time // sleep for 10ms at a time
#define TIMEDLOCK_EMU_SLEEP_NS 10000000ULL #define TIMEDLOCK_EMU_SLEEP_NS 10000000ULL
@ -55,87 +55,91 @@ namespace Threading
// This is an implementation that emulates pthread_mutex_timedlock() via // This is an implementation that emulates pthread_mutex_timedlock() via
// pthread_mutex_trylock(). // pthread_mutex_trylock().
static int xpthread_mutex_timedlock( static int xpthread_mutex_timedlock(
pthread_mutex_t *mutex, pthread_mutex_t *mutex,
const struct timespec *abs_timeout) const struct timespec *abs_timeout)
{ {
int err = 0; int err = 0;
while ((err = pthread_mutex_trylock(mutex)) == EBUSY) { while ((err = pthread_mutex_trylock(mutex)) == EBUSY) {
// acquiring lock failed, sleep some // acquiring lock failed, sleep some
struct timespec ts; struct timespec ts;
ts.tv_sec = 0; ts.tv_sec = 0;
ts.tv_nsec = TIMEDLOCK_EMU_SLEEP_NS; ts.tv_nsec = TIMEDLOCK_EMU_SLEEP_NS;
int status; int status;
while ((status = nanosleep(&ts, &ts)) == -1); while ((status = nanosleep(&ts, &ts)) == -1)
;
// check if the timeout has expired, gettimeofday() is implemented // check if the timeout has expired, gettimeofday() is implemented
// efficiently (in userspace) on OSX // efficiently (in userspace) on OSX
struct timeval now; struct timeval now;
int res = gettimeofday(&now, NULL); int res = gettimeofday(&now, NULL);
if (abs_timeout->tv_sec == 0 || now.tv_sec > abs_timeout->tv_sec || if (abs_timeout->tv_sec == 0 || now.tv_sec > abs_timeout->tv_sec ||
(u64) now.tv_usec * 1000ULL > (u64) abs_timeout->tv_nsec) { (u64)now.tv_usec * 1000ULL > (u64)abs_timeout->tv_nsec) {
return ETIMEDOUT; return ETIMEDOUT;
} }
} }
return err; return err;
} }
#endif #endif
Threading::Mutex::Mutex() Threading::Mutex::Mutex()
{ {
pthread_mutex_init( &m_mutex, NULL ); pthread_mutex_init(&m_mutex, NULL);
} }
static wxTimeSpan def_detach_timeout( 0, 0, 6, 0 ); static wxTimeSpan def_detach_timeout(0, 0, 6, 0);
void Threading::Mutex::Detach() void Threading::Mutex::Detach()
{ {
if( EBUSY != pthread_mutex_destroy(&m_mutex) ) return; if (EBUSY != pthread_mutex_destroy(&m_mutex))
return;
if( IsRecursive() ) if (IsRecursive()) {
{ // Sanity check: Recursive locks could be held by our own thread, which would
// Sanity check: Recursive locks could be held by our own thread, which would // be considered an assertion failure, but can also be handled gracefully.
// be considered an assertion failure, but can also be handled gracefully. // (note: if the mutex is locked recursively more than twice then this assert won't
// (note: if the mutex is locked recursively more than twice then this assert won't // detect it)
// detect it)
Release(); Release(); // in case of double recursion. Release();
int result = pthread_mutex_destroy( &m_mutex ); Release(); // in case of double recursion.
if( pxAssertDev( result != EBUSY, "Detachment of a recursively-locked mutex (self-locked!)." ) ) return; int result = pthread_mutex_destroy(&m_mutex);
} if (pxAssertDev(result != EBUSY, "Detachment of a recursively-locked mutex (self-locked!)."))
return;
}
if( Wait(def_detach_timeout) ) if (Wait(def_detach_timeout))
pthread_mutex_destroy( &m_mutex ); pthread_mutex_destroy(&m_mutex);
else else
Console.Error( "(Thread Log) Mutex cleanup failed due to possible deadlock."); Console.Error("(Thread Log) Mutex cleanup failed due to possible deadlock.");
} }
Threading::Mutex::~Mutex() throw() Threading::Mutex::~Mutex() throw()
{ {
try { try {
Mutex::Detach(); Mutex::Detach();
} DESTRUCTOR_CATCHALL; }
DESTRUCTOR_CATCHALL;
} }
Threading::MutexRecursive::MutexRecursive() : Mutex( false ) Threading::MutexRecursive::MutexRecursive()
: Mutex(false)
{ {
if( ++_attr_refcount == 1 ) if (++_attr_refcount == 1) {
{ if (0 != pthread_mutexattr_init(&_attr_recursive))
if( 0 != pthread_mutexattr_init( &_attr_recursive ) ) throw Exception::OutOfMemory(L"Recursive mutexing attributes");
throw Exception::OutOfMemory(L"Recursive mutexing attributes");
pthread_mutexattr_settype( &_attr_recursive, PTHREAD_MUTEX_RECURSIVE ); pthread_mutexattr_settype(&_attr_recursive, PTHREAD_MUTEX_RECURSIVE);
} }
if (pthread_mutex_init( &m_mutex, &_attr_recursive )) if (pthread_mutex_init(&m_mutex, &_attr_recursive))
Console.Error( "(Thread Log) Failed to initialize mutex."); Console.Error("(Thread Log) Failed to initialize mutex.");
} }
Threading::MutexRecursive::~MutexRecursive() throw() Threading::MutexRecursive::~MutexRecursive() throw()
{ {
if( --_attr_refcount == 0 ) if (--_attr_refcount == 0)
pthread_mutexattr_destroy( &_attr_recursive ); pthread_mutexattr_destroy(&_attr_recursive);
} }
// This is a bit of a hackish function, which is technically unsafe, but can be useful for allowing // This is a bit of a hackish function, which is technically unsafe, but can be useful for allowing
@ -144,8 +148,8 @@ Threading::MutexRecursive::~MutexRecursive() throw()
// the deeper meanings of the universe for eternity. // the deeper meanings of the universe for eternity.
void Threading::Mutex::Recreate() void Threading::Mutex::Recreate()
{ {
Detach(); Detach();
pthread_mutex_init( &m_mutex, NULL ); pthread_mutex_init(&m_mutex, NULL);
} }
// Returns: // Returns:
@ -153,12 +157,11 @@ void Threading::Mutex::Recreate()
// unlocked. // unlocked.
bool Threading::Mutex::RecreateIfLocked() bool Threading::Mutex::RecreateIfLocked()
{ {
if( !Wait(def_detach_timeout) ) if (!Wait(def_detach_timeout)) {
{ Recreate();
Recreate(); return true;
return true; }
} return false;
return false;
} }
@ -168,25 +171,25 @@ bool Threading::Mutex::RecreateIfLocked()
// other than the main thread. // other than the main thread.
void Threading::Mutex::AcquireWithoutYield() void Threading::Mutex::AcquireWithoutYield()
{ {
pxAssertMsg( !wxThread::IsMain(), "Unyielding mutex acquire issued from the main/gui thread. Please use Acquire() instead." ); pxAssertMsg(!wxThread::IsMain(), "Unyielding mutex acquire issued from the main/gui thread. Please use Acquire() instead.");
pthread_mutex_lock( &m_mutex ); pthread_mutex_lock(&m_mutex);
} }
bool Threading::Mutex::AcquireWithoutYield( const wxTimeSpan& timeout ) bool Threading::Mutex::AcquireWithoutYield(const wxTimeSpan &timeout)
{ {
wxDateTime megafail( wxDateTime::UNow() + timeout ); wxDateTime megafail(wxDateTime::UNow() + timeout);
const timespec fail = { megafail.GetTicks(), megafail.GetMillisecond() * 1000000 }; const timespec fail = {megafail.GetTicks(), megafail.GetMillisecond() * 1000000};
return xpthread_mutex_timedlock( &m_mutex, &fail ) == 0; return xpthread_mutex_timedlock(&m_mutex, &fail) == 0;
} }
void Threading::Mutex::Release() void Threading::Mutex::Release()
{ {
pthread_mutex_unlock( &m_mutex ); pthread_mutex_unlock(&m_mutex);
} }
bool Threading::Mutex::TryAcquire() bool Threading::Mutex::TryAcquire()
{ {
return EBUSY != pthread_mutex_trylock( &m_mutex ); return EBUSY != pthread_mutex_trylock(&m_mutex);
} }
// This is a wxApp-safe rendition of AcquireWithoutYield, which makes sure to execute pending app events // This is a wxApp-safe rendition of AcquireWithoutYield, which makes sure to execute pending app events
@ -195,54 +198,45 @@ bool Threading::Mutex::TryAcquire()
void Threading::Mutex::Acquire() void Threading::Mutex::Acquire()
{ {
#if wxUSE_GUI #if wxUSE_GUI
if( !wxThread::IsMain() || (wxTheApp == NULL) ) if (!wxThread::IsMain() || (wxTheApp == NULL)) {
{ pthread_mutex_lock(&m_mutex);
pthread_mutex_lock( &m_mutex ); } else if (_WaitGui_RecursionGuard(L"Mutex::Acquire")) {
} ScopedBusyCursor hourglass(Cursor_ReallyBusy);
else if( _WaitGui_RecursionGuard( L"Mutex::Acquire" ) ) pthread_mutex_lock(&m_mutex);
{ } else {
ScopedBusyCursor hourglass( Cursor_ReallyBusy ); //ScopedBusyCursor hourglass( Cursor_KindaBusy );
pthread_mutex_lock( &m_mutex ); while (!AcquireWithoutYield(def_yieldgui_interval))
} YieldToMain();
else }
{
//ScopedBusyCursor hourglass( Cursor_KindaBusy );
while( !AcquireWithoutYield(def_yieldgui_interval) )
YieldToMain();
}
#else #else
pthread_mutex_lock( &m_mutex ); pthread_mutex_lock(&m_mutex);
#endif #endif
} }
bool Threading::Mutex::Acquire( const wxTimeSpan& timeout ) bool Threading::Mutex::Acquire(const wxTimeSpan &timeout)
{ {
#if wxUSE_GUI #if wxUSE_GUI
if( !wxThread::IsMain() || (wxTheApp == NULL) ) if (!wxThread::IsMain() || (wxTheApp == NULL)) {
{ return AcquireWithoutYield(timeout);
return AcquireWithoutYield(timeout); } else if (_WaitGui_RecursionGuard(L"Mutex::TimedAcquire")) {
} ScopedBusyCursor hourglass(Cursor_ReallyBusy);
else if( _WaitGui_RecursionGuard( L"Mutex::TimedAcquire" ) ) return AcquireWithoutYield(timeout);
{ } else {
ScopedBusyCursor hourglass( Cursor_ReallyBusy ); //ScopedBusyCursor hourglass( Cursor_KindaBusy );
return AcquireWithoutYield( timeout ); wxTimeSpan countdown((timeout));
}
else
{
//ScopedBusyCursor hourglass( Cursor_KindaBusy );
wxTimeSpan countdown( (timeout) );
do { do {
if( AcquireWithoutYield( def_yieldgui_interval ) ) break; if (AcquireWithoutYield(def_yieldgui_interval))
YieldToMain(); break;
countdown -= def_yieldgui_interval; YieldToMain();
} while( countdown.GetMilliseconds() > 0 ); countdown -= def_yieldgui_interval;
} while (countdown.GetMilliseconds() > 0);
return countdown.GetMilliseconds() > 0; return countdown.GetMilliseconds() > 0;
} }
#else #else
return AcquireWithoutYield(); return AcquireWithoutYield();
#endif #endif
} }
@ -255,14 +249,14 @@ bool Threading::Mutex::Acquire( const wxTimeSpan& timeout )
// //
void Threading::Mutex::Wait() void Threading::Mutex::Wait()
{ {
Acquire(); Acquire();
Release(); Release();
} }
void Threading::Mutex::WaitWithoutYield() void Threading::Mutex::WaitWithoutYield()
{ {
AcquireWithoutYield(); AcquireWithoutYield();
Release(); Release();
} }
// Performs a wait on a locked mutex, or returns instantly if the mutex is unlocked. // Performs a wait on a locked mutex, or returns instantly if the mutex is unlocked.
@ -272,24 +266,22 @@ void Threading::Mutex::WaitWithoutYield()
// true if the mutex was freed and is in an unlocked state; or false if the wait timed out // true if the mutex was freed and is in an unlocked state; or false if the wait timed out
// and the mutex is still locked by another thread. // and the mutex is still locked by another thread.
// //
bool Threading::Mutex::Wait( const wxTimeSpan& timeout ) bool Threading::Mutex::Wait(const wxTimeSpan &timeout)
{ {
if( Acquire(timeout) ) if (Acquire(timeout)) {
{ Release();
Release(); return true;
return true; }
} return false;
return false;
} }
bool Threading::Mutex::WaitWithoutYield( const wxTimeSpan& timeout ) bool Threading::Mutex::WaitWithoutYield(const wxTimeSpan &timeout)
{ {
if( AcquireWithoutYield(timeout) ) if (AcquireWithoutYield(timeout)) {
{ Release();
Release(); return true;
return true; }
} return false;
return false;
} }
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
@ -298,67 +290,72 @@ bool Threading::Mutex::WaitWithoutYield( const wxTimeSpan& timeout )
Threading::ScopedLock::~ScopedLock() throw() Threading::ScopedLock::~ScopedLock() throw()
{ {
if( m_IsLocked && m_lock ) if (m_IsLocked && m_lock)
m_lock->Release(); m_lock->Release();
} }
Threading::ScopedLock::ScopedLock( const Mutex* locker ) Threading::ScopedLock::ScopedLock(const Mutex *locker)
{ {
m_IsLocked = false; m_IsLocked = false;
AssignAndLock( locker ); AssignAndLock(locker);
} }
Threading::ScopedLock::ScopedLock( const Mutex& locker ) Threading::ScopedLock::ScopedLock(const Mutex &locker)
{ {
m_IsLocked = false; m_IsLocked = false;
AssignAndLock( locker ); AssignAndLock(locker);
} }
void Threading::ScopedLock::AssignAndLock( const Mutex& locker ) void Threading::ScopedLock::AssignAndLock(const Mutex &locker)
{ {
AssignAndLock( &locker ); AssignAndLock(&locker);
} }
void Threading::ScopedLock::AssignAndLock( const Mutex* locker ) void Threading::ScopedLock::AssignAndLock(const Mutex *locker)
{ {
pxAssert(!m_IsLocked); // if we're already locked, changing the lock is bad mojo. pxAssert(!m_IsLocked); // if we're already locked, changing the lock is bad mojo.
m_lock = const_cast<Mutex*>(locker); m_lock = const_cast<Mutex *>(locker);
if( !m_lock ) return; if (!m_lock)
return;
m_IsLocked = true; m_IsLocked = true;
m_lock->Acquire(); m_lock->Acquire();
} }
void Threading::ScopedLock::Assign( const Mutex& locker ) void Threading::ScopedLock::Assign(const Mutex &locker)
{ {
m_lock = const_cast<Mutex*>(&locker); m_lock = const_cast<Mutex *>(&locker);
} }
void Threading::ScopedLock::Assign( const Mutex* locker ) void Threading::ScopedLock::Assign(const Mutex *locker)
{ {
m_lock = const_cast<Mutex*>(locker); m_lock = const_cast<Mutex *>(locker);
} }
// Provides manual unlocking of a scoped lock prior to object destruction. // Provides manual unlocking of a scoped lock prior to object destruction.
void Threading::ScopedLock::Release() void Threading::ScopedLock::Release()
{ {
if( !m_IsLocked ) return; if (!m_IsLocked)
m_IsLocked = false; return;
if( m_lock ) m_lock->Release(); m_IsLocked = false;
if (m_lock)
m_lock->Release();
} }
// provides manual locking of a scoped lock, to re-lock after a manual unlocking. // provides manual locking of a scoped lock, to re-lock after a manual unlocking.
void Threading::ScopedLock::Acquire() void Threading::ScopedLock::Acquire()
{ {
if( m_IsLocked || !m_lock ) return; if (m_IsLocked || !m_lock)
m_lock->Acquire(); return;
m_IsLocked = true; m_lock->Acquire();
m_IsLocked = true;
} }
Threading::ScopedLock::ScopedLock( const Mutex& locker, bool isTryLock ) Threading::ScopedLock::ScopedLock(const Mutex &locker, bool isTryLock)
{ {
m_lock = const_cast<Mutex*>(&locker); m_lock = const_cast<Mutex *>(&locker);
if( !m_lock ) return; if (!m_lock)
m_IsLocked = isTryLock ? m_lock->TryAcquire() : false; return;
m_IsLocked = isTryLock ? m_lock->TryAcquire() : false;
} }

View File

@ -23,72 +23,74 @@
// wxDirName (implementations) // wxDirName (implementations)
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
wxFileName wxDirName::Combine( const wxFileName& right ) const wxFileName wxDirName::Combine(const wxFileName &right) const
{ {
pxAssertMsg( IsDir(), L"Warning: Malformed directory name detected during wxDirName concatenation." ); pxAssertMsg(IsDir(), L"Warning: Malformed directory name detected during wxDirName concatenation.");
if( right.IsAbsolute() ) if (right.IsAbsolute())
return right; return right;
// Append any directory parts from right, and then set the filename. // Append any directory parts from right, and then set the filename.
// Except we can't do that because our m_members are private (argh!) and there is no API // Except we can't do that because our m_members are private (argh!) and there is no API
// for getting each component of the path. So instead let's use Normalize: // for getting each component of the path. So instead let's use Normalize:
wxFileName result( right ); wxFileName result(right);
result.Normalize( wxPATH_NORM_ENV_VARS | wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE, GetPath() ); result.Normalize(wxPATH_NORM_ENV_VARS | wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE, GetPath());
return result; return result;
} }
wxDirName wxDirName::Combine( const wxDirName& right ) const wxDirName wxDirName::Combine(const wxDirName &right) const
{ {
pxAssertMsg( IsDir() && right.IsDir(), L"Warning: Malformed directory name detected during wDirName concatenation." ); pxAssertMsg(IsDir() && right.IsDir(), L"Warning: Malformed directory name detected during wDirName concatenation.");
wxDirName result( right ); wxDirName result(right);
result.Normalize( wxPATH_NORM_ENV_VARS | wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE, GetPath() ); result.Normalize(wxPATH_NORM_ENV_VARS | wxPATH_NORM_DOTS | wxPATH_NORM_ABSOLUTE, GetPath());
return result; return result;
} }
wxDirName& wxDirName::Normalize( int flags, const wxString& cwd ) wxDirName &wxDirName::Normalize(int flags, const wxString &cwd)
{ {
pxAssertMsg( IsDir(), L"Warning: Malformed directory name detected during wDirName normalization." ); pxAssertMsg(IsDir(), L"Warning: Malformed directory name detected during wDirName normalization.");
if( !wxFileName::Normalize( flags, cwd ) ) if (!wxFileName::Normalize(flags, cwd))
throw Exception::ParseError().SetDiagMsg( L"wxDirName::Normalize operation failed." ); throw Exception::ParseError().SetDiagMsg(L"wxDirName::Normalize operation failed.");
return *this; return *this;
} }
wxDirName& wxDirName::MakeRelativeTo( const wxString& pathBase ) wxDirName &wxDirName::MakeRelativeTo(const wxString &pathBase)
{ {
pxAssertMsg( IsDir(), L"Warning: Malformed directory name detected during wDirName normalization." ); pxAssertMsg(IsDir(), L"Warning: Malformed directory name detected during wDirName normalization.");
if( !wxFileName::MakeRelativeTo( pathBase ) ) if (!wxFileName::MakeRelativeTo(pathBase))
throw Exception::ParseError().SetDiagMsg( L"wxDirName::MakeRelativeTo operation failed." ); throw Exception::ParseError().SetDiagMsg(L"wxDirName::MakeRelativeTo operation failed.");
return *this; return *this;
} }
wxDirName& wxDirName::MakeAbsolute( const wxString& cwd ) wxDirName &wxDirName::MakeAbsolute(const wxString &cwd)
{ {
pxAssertMsg( IsDir(), L"Warning: Malformed directory name detected during wDirName normalization." ); pxAssertMsg(IsDir(), L"Warning: Malformed directory name detected during wDirName normalization.");
if( !wxFileName::MakeAbsolute( cwd ) ) if (!wxFileName::MakeAbsolute(cwd))
throw Exception::ParseError().SetDiagMsg( L"wxDirName::MakeAbsolute operation failed." ); throw Exception::ParseError().SetDiagMsg(L"wxDirName::MakeAbsolute operation failed.");
return *this; return *this;
} }
void wxDirName::Rmdir() void wxDirName::Rmdir()
{ {
if( !Exists() ) return; if (!Exists())
wxFileName::Rmdir(); return;
// TODO : Throw exception if operation failed? Do we care? wxFileName::Rmdir();
// TODO : Throw exception if operation failed? Do we care?
} }
bool wxDirName::Mkdir() bool wxDirName::Mkdir()
{ {
// wxWidgets recurses directory creation for us. // wxWidgets recurses directory creation for us.
// only exist in wx2.9 and above // only exist in wx2.9 and above
#ifndef wxS_DIR_DEFAULT #ifndef wxS_DIR_DEFAULT
#define wxS_DIR_DEFAULT 0777 #define wxS_DIR_DEFAULT 0777
#endif #endif
if( Exists() ) return true; if (Exists())
return wxFileName::Mkdir(wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL); return true;
return wxFileName::Mkdir(wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL);
} }
@ -97,110 +99,111 @@ bool wxDirName::Mkdir()
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
bool Path::IsRelative( const wxString& path ) bool Path::IsRelative(const wxString &path)
{ {
return wxDirName( path ).IsRelative(); return wxDirName(path).IsRelative();
} }
// Returns -1 if the file does not exist. // Returns -1 if the file does not exist.
s64 Path::GetFileSize( const wxString& path ) s64 Path::GetFileSize(const wxString &path)
{ {
if( !wxFile::Exists( path.c_str() ) ) return -1; if (!wxFile::Exists(path.c_str()))
return (s64)wxFileName::GetSize( path ).GetValue(); return -1;
return (s64)wxFileName::GetSize(path).GetValue();
} }
wxString Path::Normalize( const wxString& src ) wxString Path::Normalize(const wxString &src)
{ {
wxFileName normalize( src ); wxFileName normalize(src);
normalize.Normalize(); normalize.Normalize();
return normalize.GetFullPath(); return normalize.GetFullPath();
} }
wxString Path::Normalize( const wxDirName& src ) wxString Path::Normalize(const wxDirName &src)
{ {
return wxDirName(src).Normalize().ToString(); return wxDirName(src).Normalize().ToString();
} }
wxString Path::MakeAbsolute( const wxString& src ) wxString Path::MakeAbsolute(const wxString &src)
{ {
wxFileName absolute( src ); wxFileName absolute(src);
absolute.MakeAbsolute(); absolute.MakeAbsolute();
return absolute.GetFullPath(); return absolute.GetFullPath();
} }
// Concatenates two pathnames together, inserting delimiters (backslash on win32) // Concatenates two pathnames together, inserting delimiters (backslash on win32)
// as needed! Assumes the 'dest' is allocated to at least g_MaxPath length. // as needed! Assumes the 'dest' is allocated to at least g_MaxPath length.
// //
wxString Path::Combine( const wxString& srcPath, const wxString& srcFile ) wxString Path::Combine(const wxString &srcPath, const wxString &srcFile)
{ {
return (wxDirName( srcPath ) + srcFile).GetFullPath(); return (wxDirName(srcPath) + srcFile).GetFullPath();
} }
wxString Path::Combine( const wxDirName& srcPath, const wxFileName& srcFile ) wxString Path::Combine(const wxDirName &srcPath, const wxFileName &srcFile)
{ {
return (srcPath + srcFile).GetFullPath(); return (srcPath + srcFile).GetFullPath();
} }
wxString Path::Combine( const wxString& srcPath, const wxDirName& srcFile ) wxString Path::Combine(const wxString &srcPath, const wxDirName &srcFile)
{ {
return (wxDirName( srcPath ) + srcFile).ToString(); return (wxDirName(srcPath) + srcFile).ToString();
} }
// Replaces the extension of the file with the one given. // Replaces the extension of the file with the one given.
// This function works for path names as well as file names. // This function works for path names as well as file names.
wxString Path::ReplaceExtension( const wxString& src, const wxString& ext ) wxString Path::ReplaceExtension(const wxString &src, const wxString &ext)
{ {
wxFileName jojo( src ); wxFileName jojo(src);
jojo.SetExt( ext ); jojo.SetExt(ext);
return jojo.GetFullPath(); return jojo.GetFullPath();
} }
wxString Path::ReplaceFilename( const wxString& src, const wxString& newfilename ) wxString Path::ReplaceFilename(const wxString &src, const wxString &newfilename)
{ {
wxFileName jojo( src ); wxFileName jojo(src);
jojo.SetFullName( newfilename ); jojo.SetFullName(newfilename);
return jojo.GetFullPath(); return jojo.GetFullPath();
} }
wxString Path::GetFilename( const wxString& src ) wxString Path::GetFilename(const wxString &src)
{ {
return wxFileName(src).GetFullName(); return wxFileName(src).GetFullName();
} }
wxString Path::GetFilenameWithoutExt( const wxString& src ) wxString Path::GetFilenameWithoutExt(const wxString &src)
{ {
return wxFileName(src).GetName(); return wxFileName(src).GetName();
} }
wxString Path::GetDirectory( const wxString& src ) wxString Path::GetDirectory(const wxString &src)
{ {
return wxFileName(src).GetPath(); return wxFileName(src).GetPath();
} }
// returns the base/root directory of the given path. // returns the base/root directory of the given path.
// Example /this/that/something.txt -> dest == "/" // Example /this/that/something.txt -> dest == "/"
wxString Path::GetRootDirectory( const wxString& src ) wxString Path::GetRootDirectory(const wxString &src)
{ {
size_t pos = src.find_first_of( wxFileName::GetPathSeparators() ); size_t pos = src.find_first_of(wxFileName::GetPathSeparators());
if( pos == wxString::npos ) if (pos == wxString::npos)
return wxString(); return wxString();
else else
return wxString( src.begin(), src.begin()+pos ); return wxString(src.begin(), src.begin() + pos);
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// Launches the specified file according to its mime type // Launches the specified file according to its mime type
// //
void pxLaunch( const wxString& filename ) void pxLaunch(const wxString &filename)
{ {
wxLaunchDefaultBrowser( filename ); wxLaunchDefaultBrowser(filename);
} }
void pxLaunch(const char *filename) void pxLaunch(const char *filename)
{ {
pxLaunch( fromUTF8(filename) ); pxLaunch(fromUTF8(filename));
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -209,12 +212,12 @@ void pxLaunch(const char *filename)
// bypasses wxWidgets internal filename checking, which can end up launching things // bypasses wxWidgets internal filename checking, which can end up launching things
// through browser more often than desired. // through browser more often than desired.
// //
void pxExplore( const wxString& path ) void pxExplore(const wxString &path)
{ {
wxLaunchDefaultBrowser( !path.Contains( L"://") ? L"file://" + path : path ); wxLaunchDefaultBrowser(!path.Contains(L"://") ? L"file://" + path : path);
} }
void pxExplore(const char *path) void pxExplore(const char *path)
{ {
pxExplore( fromUTF8(path) ); pxExplore(fromUTF8(path));
} }

View File

@ -23,118 +23,125 @@
namespace Perf namespace Perf
{ {
// Warning object aren't thread safe // Warning object aren't thread safe
InfoVector any(""); InfoVector any("");
InfoVector ee("EE"); InfoVector ee("EE");
InfoVector iop("IOP"); InfoVector iop("IOP");
InfoVector vu("VU"); InfoVector vu("VU");
// Perf is only supported on linux // Perf is only supported on linux
#if defined(__linux__) && defined(ProfileWithPerf) #if defined(__linux__) && defined(ProfileWithPerf)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Implementation of the Info object // Implementation of the Info object
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Info::Info(uptr x86, u32 size, const char* symbol) : m_x86(x86), m_size(size), m_dynamic(false) Info::Info(uptr x86, u32 size, const char *symbol)
{ : m_x86(x86)
strncpy(m_symbol, symbol, sizeof(m_symbol)); , m_size(size)
} , m_dynamic(false)
{
strncpy(m_symbol, symbol, sizeof(m_symbol));
}
Info::Info(uptr x86, u32 size, const char* symbol, u32 pc) : m_x86(x86), m_size(size), m_dynamic(true) Info::Info(uptr x86, u32 size, const char *symbol, u32 pc)
{ : m_x86(x86)
snprintf(m_symbol, sizeof(m_symbol), "%s_0x%08x", symbol, pc); , m_size(size)
} , m_dynamic(true)
{
snprintf(m_symbol, sizeof(m_symbol), "%s_0x%08x", symbol, pc);
}
void Info::Print(FILE* fp) void Info::Print(FILE *fp)
{ {
fprintf(fp, "%x %x %s\n", m_x86, m_size, m_symbol); fprintf(fp, "%x %x %s\n", m_x86, m_size, m_symbol);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Implementation of the InfoVector object // Implementation of the InfoVector object
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
InfoVector::InfoVector(const char* prefix) InfoVector::InfoVector(const char *prefix)
{ {
strncpy(m_prefix, prefix, sizeof(m_prefix)); strncpy(m_prefix, prefix, sizeof(m_prefix));
} }
void InfoVector::print(FILE* fp) void InfoVector::print(FILE *fp)
{ {
for(auto&& it : m_v) it.Print(fp); for (auto &&it : m_v)
} it.Print(fp);
}
void InfoVector::map(uptr x86, u32 size, const char* symbol) void InfoVector::map(uptr x86, u32 size, const char *symbol)
{ {
// This function is typically used for dispatcher and recompiler. // This function is typically used for dispatcher and recompiler.
// Dispatchers are on a page and must always be kept. // Dispatchers are on a page and must always be kept.
// Recompilers are much bigger (TODO check VIF) and are only // Recompilers are much bigger (TODO check VIF) and are only
// useful when MERGE_BLOCK_RESULT is defined // useful when MERGE_BLOCK_RESULT is defined
#ifdef MERGE_BLOCK_RESULT #ifdef MERGE_BLOCK_RESULT
m_v.emplace_back(x86, size, symbol); m_v.emplace_back(x86, size, symbol);
#else #else
if (size < 8 * _1kb) m_v.emplace_back(x86, size, symbol); if (size < 8 * _1kb)
m_v.emplace_back(x86, size, symbol);
#endif
}
void InfoVector::map(uptr x86, u32 size, u32 pc)
{
#ifndef MERGE_BLOCK_RESULT
m_v.emplace_back(x86, size, m_prefix, pc);
#endif
}
void InfoVector::reset()
{
auto dynamic = std::remove_if(m_v.begin(), m_v.end(), [](Info i) { return i.m_dynamic; });
m_v.erase(dynamic, m_v.end());
}
////////////////////////////////////////////////////////////////////////////////
// Global function
////////////////////////////////////////////////////////////////////////////////
void dump()
{
char file[256];
snprintf(file, 250, "/tmp/perf-%d.map", getpid());
FILE *fp = fopen(file, "w");
any.print(fp);
ee.print(fp);
iop.print(fp);
vu.print(fp);
if (fp)
fclose(fp);
}
void dump_and_reset()
{
dump();
any.reset();
ee.reset();
iop.reset();
vu.reset();
}
#else
////////////////////////////////////////////////////////////////////////////////
// Dummy implementation
////////////////////////////////////////////////////////////////////////////////
InfoVector::InfoVector(const char *prefix) {}
void InfoVector::map(uptr x86, u32 size, const char *symbol) {}
void InfoVector::map(uptr x86, u32 size, u32 pc) {}
void InfoVector::reset() {}
void dump() {}
void dump_and_reset() {}
#endif #endif
}
void InfoVector::map(uptr x86, u32 size, u32 pc)
{
#ifndef MERGE_BLOCK_RESULT
m_v.emplace_back(x86, size, m_prefix, pc);
#endif
}
void InfoVector::reset()
{
auto dynamic = std::remove_if(m_v.begin(), m_v.end(), [](Info i) { return i.m_dynamic; });
m_v.erase(dynamic, m_v.end());
}
////////////////////////////////////////////////////////////////////////////////
// Global function
////////////////////////////////////////////////////////////////////////////////
void dump()
{
char file[256];
snprintf(file, 250, "/tmp/perf-%d.map", getpid());
FILE* fp = fopen(file, "w");
any.print(fp);
ee.print(fp);
iop.print(fp);
vu.print(fp);
if (fp)
fclose(fp);
}
void dump_and_reset()
{
dump();
any.reset();
ee.reset();
iop.reset();
vu.reset();
}
#else
////////////////////////////////////////////////////////////////////////////////
// Dummy implementation
////////////////////////////////////////////////////////////////////////////////
InfoVector::InfoVector(const char* prefix) {}
void InfoVector::map(uptr x86, u32 size, const char* symbol) {}
void InfoVector::map(uptr x86, u32 size, u32 pc) {}
void InfoVector::reset() {}
void dump() {}
void dump_and_reset() {}
#endif
} }

View File

@ -28,4 +28,3 @@
#include "General.h" #include "General.h"
#endif #endif

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