mirror of https://github.com/PCSX2/pcsx2.git
wxgui: more of the slowly progressing.
* Implemented internationalization (i18n) framework. * Made a pretty configuration dialog box! * Many minor bugfixes. * Removed most of the old Win32 and Linux/GTK gui code because it was causing gettext cataloging to grab about 500 non-relevant strings (can always reference trunk for them anyway). git-svn-id: http://pcsx2.googlecode.com/svn/branches/wxgui@1484 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
commit
3c195e9f9a
|
@ -408,6 +408,10 @@
|
|||
RelativePath="..\..\include\Utilities\win_memzero.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\include\Utilities\WinVersion.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
|
|
|
@ -1,26 +1,43 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2008 Pcsx2 Team
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __MCDDLGS_H__
|
||||
#define __MCDDLGS_H__
|
||||
#pragma once
|
||||
|
||||
#include "Linux.h"
|
||||
#include "RedtapeWindows.h"
|
||||
#include <winnt.h>
|
||||
|
||||
GtkWidget *MemDlg;
|
||||
namespace Win32
|
||||
{
|
||||
class RealVersionInfo
|
||||
{
|
||||
protected:
|
||||
HMODULE m_kernel32;
|
||||
wxString m_VersionString;
|
||||
|
||||
#endif
|
||||
public:
|
||||
~RealVersionInfo();
|
||||
RealVersionInfo();
|
||||
|
||||
bool IsVista() const;
|
||||
bool IsXP() const;
|
||||
const wxString& GetVersionString() const;
|
||||
|
||||
protected:
|
||||
void InitVersionString();
|
||||
};
|
||||
}
|
|
@ -18,6 +18,10 @@
|
|||
|
||||
#include "../PrecompiledHeader.h"
|
||||
#include "RedtapeWindows.h"
|
||||
#include "WinVersion.h"
|
||||
|
||||
#include <shlwapi.h> // for IsOS()
|
||||
|
||||
|
||||
static LARGE_INTEGER lfreq;
|
||||
|
||||
|
@ -37,3 +41,149 @@ u64 GetCPUTicks()
|
|||
QueryPerformanceCounter( &count );
|
||||
return count.QuadPart;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
static const char* GetVersionName( DWORD minorVersion, DWORD majorVersion )
|
||||
{
|
||||
switch( majorVersion )
|
||||
{
|
||||
case 6:
|
||||
return "Vista";
|
||||
break;
|
||||
|
||||
case 5:
|
||||
switch( minorVersion )
|
||||
{
|
||||
case 0:
|
||||
return "2000";
|
||||
break;
|
||||
|
||||
case 1:
|
||||
return "XP";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
return "Server 2003";
|
||||
break;
|
||||
|
||||
default:
|
||||
return "2000/XP";
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
switch( minorVersion )
|
||||
{
|
||||
case 0:
|
||||
return "95";
|
||||
break;
|
||||
|
||||
case 10:
|
||||
return "98";
|
||||
break;
|
||||
|
||||
case 90:
|
||||
return "ME";
|
||||
break;
|
||||
|
||||
default:
|
||||
return "95/98/ME";
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
return "32S";
|
||||
break;
|
||||
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
void Win32::RealVersionInfo::InitVersionString()
|
||||
{
|
||||
DWORD version = GetVersion();
|
||||
|
||||
int majorVersion = (DWORD)(LOBYTE(LOWORD(version)));
|
||||
int minorVersion = (DWORD)(HIBYTE(LOWORD(version)));
|
||||
|
||||
RealVersionInfo really;
|
||||
wxString verName( wxString::FromAscii( GetVersionName( minorVersion, majorVersion ) ) );
|
||||
|
||||
bool IsCompatMode = false;
|
||||
|
||||
if( really.IsVista() )
|
||||
{
|
||||
m_VersionString = L"Windows Vista";
|
||||
|
||||
if( verName != L"Vista" )
|
||||
{
|
||||
if( verName == L"Unknown" )
|
||||
m_VersionString += L" or Newer";
|
||||
else
|
||||
IsCompatMode = true;
|
||||
}
|
||||
|
||||
m_VersionString += wxsFormat( L" v%d.%d", majorVersion, minorVersion );
|
||||
|
||||
if( IsOS( OS_WOW6432 ) )
|
||||
m_VersionString += L" (64-bit)";
|
||||
else
|
||||
m_VersionString += L" (32-bit)";
|
||||
}
|
||||
else if( really.IsXP() )
|
||||
{
|
||||
m_VersionString = wxsFormat( L"Windows XP v%d.%d", majorVersion, minorVersion );
|
||||
|
||||
if( IsOS( OS_WOW6432 ) )
|
||||
m_VersionString += L" (64-bit)";
|
||||
else
|
||||
m_VersionString += L" (32-bit)";
|
||||
|
||||
if( verName != L"XP" )
|
||||
IsCompatMode = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_VersionString = L"Windows " + verName;
|
||||
}
|
||||
|
||||
if( IsCompatMode )
|
||||
m_VersionString += wxsFormat( L" [compatibility mode, running as Windows %s]", verName );
|
||||
}
|
||||
|
||||
Win32::RealVersionInfo::~RealVersionInfo()
|
||||
{
|
||||
if( m_kernel32 != NULL )
|
||||
FreeLibrary( m_kernel32 );
|
||||
}
|
||||
|
||||
Win32::RealVersionInfo::RealVersionInfo() :
|
||||
m_kernel32( LoadLibrary( L"kernel32" ) )
|
||||
{
|
||||
InitVersionString();
|
||||
}
|
||||
|
||||
bool Win32::RealVersionInfo::IsVista() const
|
||||
{
|
||||
if( m_kernel32 == NULL ) return false;
|
||||
|
||||
// CreateThreadpoolWait is a good pick -- it's not likely to exist on older OS's
|
||||
// GetLocaleInfoEx is also good -- two picks are better than one, just in case
|
||||
// one of the APIs becomes available in a future XP service pack.
|
||||
|
||||
return
|
||||
( GetProcAddress( m_kernel32, "CreateThreadpoolWait" ) != NULL ) &&
|
||||
( GetProcAddress( m_kernel32, "GetLocaleInfoEx" ) != NULL );
|
||||
}
|
||||
|
||||
bool Win32::RealVersionInfo::IsXP() const
|
||||
{
|
||||
return ( GetProcAddress( m_kernel32, "GetNativeSystemInfo" ) != NULL );
|
||||
}
|
||||
|
||||
const wxString& Win32::RealVersionInfo::GetVersionString() const
|
||||
{
|
||||
return m_VersionString;
|
||||
}
|
||||
|
||||
|
|
|
@ -60,12 +60,12 @@ public:
|
|||
struct FolderOptions
|
||||
{
|
||||
wxDirName Plugins;
|
||||
wxDirName Settings;
|
||||
wxDirName Bios;
|
||||
wxDirName Snapshots;
|
||||
wxDirName Savestates;
|
||||
wxDirName MemoryCards;
|
||||
wxDirName Logs;
|
||||
wxDirName Dumps;
|
||||
|
||||
void LoadSave( IniInterface& conf );
|
||||
};
|
||||
|
@ -190,9 +190,13 @@ public:
|
|||
|
||||
FullpathHelpers Files;
|
||||
|
||||
bool UseAdminMode; // dictates if the program uses /home/user or /cwd for the program data
|
||||
wxPoint MainGuiPosition;
|
||||
bool CdvdVerboseReads; // enables cdvd read activity verbosely dumped to the console
|
||||
|
||||
// Current language in use (correlates to a wxWidgets wxLANGUAGE specifier)
|
||||
int LanguageId;
|
||||
|
||||
// String value describing the desktop theme to use for pcsk2 (icons and background images)
|
||||
// The theme name is used to look up files in the themes folder (relative to the executable).
|
||||
wxString DeskTheme;
|
||||
|
@ -220,6 +224,9 @@ public:
|
|||
public:
|
||||
void Load();
|
||||
void Save();
|
||||
void Apply();
|
||||
|
||||
void LoadSaveUserMode( IniInterface& ini );
|
||||
|
||||
protected:
|
||||
void LoadSave( IniInterface& ini );
|
||||
|
|
|
@ -211,9 +211,9 @@ void iDumpBlock( int startpc, u8 * ptr )
|
|||
|
||||
Console::Status( "dump1 %x:%x, %x", params startpc, pc, cpuRegs.cycle );
|
||||
|
||||
g_Conf.Folders.Dumps.Mkdir();
|
||||
g_Conf.Folders.Logs.Mkdir();
|
||||
AsciiFile eff(
|
||||
Path::Combine( g_Conf.Folders.Dumps, wxsFormat(L"R5900dump%.8X.txt", startpc) ),
|
||||
Path::Combine( g_Conf.Folders.Logs, wxsFormat(L"R5900dump%.8X.txt", startpc) ),
|
||||
wxFile::write
|
||||
);
|
||||
|
||||
|
|
|
@ -530,9 +530,10 @@ public:
|
|||
/// hash keys. The <see cref="HashMap" /> class isn't suited to the task since it requires the key type to
|
||||
/// include a set of unary methods. Obviously predicates cannot be added to fundamentals after the fact. :)
|
||||
/// Note:
|
||||
/// Do not use <c>char *</c> or <c>wchar_t *</c> as key types. Use <c>std::string</c> and <c>std::wstring</c> instead,
|
||||
/// as performance of those types will generally be superior. For that matter, don't use this class at all!
|
||||
/// Use the string-specialized classes <see cref="Dictionary" /> and <see cref="UnicodeDictionary" />.
|
||||
/// Do not use <c>char *</c> or <c>wchar_t *</c> as key types. Use <c>std::string</c> and <c>std::wstring</c>
|
||||
/// instead, as performance of those types will generally be superior due to string length caching. For that
|
||||
/// matter, don't use this class at all! Use the string-specialized classes <see cref="Dictionary" /> and
|
||||
/// <see cref="UnicodeDictionary" />.
|
||||
/// </remarks>
|
||||
template< class Key, class T >
|
||||
class HashMap : public google::dense_hash_map<Key, T, CommonHashClass>
|
||||
|
@ -547,7 +548,7 @@ public:
|
|||
/// Both the <c>emptyKey</c>a nd c>deletedKey</c> parameters must be unique values that
|
||||
/// are *not* used as actual values in the set.
|
||||
/// </remarks>
|
||||
HashMap( Key emptyKey, Key deletedKey, int initialCapacity=33 ) :
|
||||
HashMap( const Key& emptyKey, const Key& deletedKey, int initialCapacity=33 ) :
|
||||
google::dense_hash_map<Key, T, CommonHashClass>( initialCapacity )
|
||||
{
|
||||
set_empty_key( emptyKey );
|
||||
|
@ -589,7 +590,7 @@ class Dictionary : public HashMap<std::string, T>
|
|||
public:
|
||||
virtual ~Dictionary() {}
|
||||
|
||||
Dictionary( int initialCapacity=33, std::string emptyKey = "@@-EMPTY-@@", std::string deletedKey = "@@-DELETED-@@" ) :
|
||||
Dictionary( int initialCapacity=33, const std::string& emptyKey = "@@-EMPTY-@@", const std::string& deletedKey = "@@-DELETED-@@" ) :
|
||||
HashMap( emptyKey, deletedKey, initialCapacity)
|
||||
{
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,162 +0,0 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2008 Pcsx2 Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_H__
|
||||
#define __LINUX_H__
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "Paths.h"
|
||||
#include "Common.h"
|
||||
#include "HostGui.h"
|
||||
|
||||
//For CpuDlg
|
||||
#include "Counters.h"
|
||||
|
||||
// For AdvancedDialog
|
||||
#include "x86/ix86/ix86.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include <X11/keysym.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <glib/gthread.h>
|
||||
#include <glib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "support.h"
|
||||
#include "callbacks.h"
|
||||
#include "interface.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void SaveConfig();
|
||||
extern int LoadConfig();
|
||||
extern void SysRestorableReset();
|
||||
|
||||
extern int Pcsx2Configure();
|
||||
|
||||
extern GtkWidget *MainWindow;
|
||||
|
||||
char cfgfile[g_MaxPath];
|
||||
|
||||
#define is_checked(main_widget, widget_name) (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name))))
|
||||
#define set_checked(main_widget,widget_name, state) gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(lookup_widget(main_widget, widget_name)), state)
|
||||
|
||||
#define set_flag(v, flag, value) if (value == TRUE) v |= flag; else v &= flag;
|
||||
#define get_flag(v,flag) ((v & (1 << flag)) != 0)
|
||||
|
||||
char ee_log_names[17][32] =
|
||||
{
|
||||
"Cpu Log",
|
||||
"Mem Log",
|
||||
"HW Log",
|
||||
"Dma Log",
|
||||
"Bios Log",
|
||||
"Elf Log",
|
||||
"Fpu Log",
|
||||
"MMI Log",
|
||||
"VU0 Log",
|
||||
"Cop0 Log",
|
||||
"Vif Log",
|
||||
"SPR Log",
|
||||
"GIF Log",
|
||||
"Sif Log",
|
||||
"IPU Log",
|
||||
"VU Micro Log",
|
||||
"RPC Log"
|
||||
};
|
||||
|
||||
char iop_log_names[9][32] =
|
||||
{
|
||||
"IOP Log",
|
||||
"Mem Log",
|
||||
"HW Log",
|
||||
"Bios Log",
|
||||
"Dma Log",
|
||||
"Pad Log",
|
||||
"Gte Log",
|
||||
"Cdr Log",
|
||||
"GPU Log"
|
||||
};
|
||||
|
||||
char vu_stealing_labels[5][256] =
|
||||
{
|
||||
"0: No speedup.",
|
||||
"1: Slight speedup, should work with most games.",
|
||||
"2: Moderate speedup, should work with most games with minor problems.",
|
||||
"3: Large speedup, may break many games and make others skip frames.",
|
||||
"4: Very large speedup, will break games in interesting ways."
|
||||
};
|
||||
|
||||
char ee_cycle_labels[3][256] =
|
||||
{
|
||||
"Default Cycle Rate: Most compatible option - recommended for everyone with high-end machines.",
|
||||
"x1.5 Cycle Rate: Moderate speedup, and works well with most games.",
|
||||
"x2 Cycle Rate: Big speedup! Works well with many games."
|
||||
};
|
||||
//Tri-Ace - IDC_GAMEFIX2
|
||||
#define FLAG_VU_ADD_SUB 0x1
|
||||
// Persona3/4 - IDC_GAMEFIX4
|
||||
#define FLAG_VU_CLIP 0x2
|
||||
|
||||
// Digimon Rumble Arena - IDC_GAMEFIX3
|
||||
#define FLAG_FPU_Compare 0x4
|
||||
//Tales of Destiny - IDC_GAMEFIX5
|
||||
#define FLAG_FPU_MUL 0x8
|
||||
//Fatal Frame
|
||||
#define FLAG_DMAExec 0x10
|
||||
//Erementar Gerad
|
||||
#define FLAG_XGKick 0x20
|
||||
|
||||
#define FLAG_VU_NO_OVERFLOW 0x2
|
||||
#define FLAG_VU_EXTRA_OVERFLOW 0x40
|
||||
|
||||
#define FLAG_FPU_NO_OVERFLOW 0x800
|
||||
#define FLAG_FPU_EXTRA_OVERFLOW 0x1000
|
||||
|
||||
#define FLAG_EE_2_SYNC 0x1
|
||||
#define FLAG_IOP_2_SYNC 0x10
|
||||
#define FLAG_TRIPLE_SYNC 0x20
|
||||
#define FLAG_ESC 0x400
|
||||
|
||||
#define FLAG_ROUND_NEAR 0x0000
|
||||
#define FLAG_ROUND_NEGATIVE 0x2000
|
||||
#define FLAG_ROUND_POSITIVE 0x4000
|
||||
#define FLAG_ROUND_ZERO 0x6000
|
||||
|
||||
#define FLAG_FLUSH_ZERO 0x8000
|
||||
#define FLAG_DENORMAL_ZERO 0x0040
|
||||
|
||||
#define FLAG_VU_CLAMP_NONE 0x0
|
||||
#define FLAG_VU_CLAMP_NORMAL 0x1
|
||||
#define FLAG_VU_CLAMP_EXTRA 0x3
|
||||
#define FLAG_VU_CLAMP_EXTRA_PRESERVE 0x7
|
||||
|
||||
#define FLAG_EE_CLAMP_NONE 0x0
|
||||
#define FLAG_EE_CLAMP_NORMAL 0x1
|
||||
#define FLAG_EE_CLAMP_EXTRA_PRESERVE 0x3
|
||||
#define FLAG_EE_CLAMP_FULL 0x7
|
||||
|
||||
#endif /* __LINUX_H__ */
|
|
@ -1,147 +0,0 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "Linux.h"
|
||||
|
||||
#define COLOR_RESET "\033[0m"
|
||||
|
||||
|
||||
// Linux Note : The Linux Console is pretty simple. It just dumps to the stdio!
|
||||
// (no console open/close/title stuff tho, so those functions are dummies)
|
||||
|
||||
// Yeah, haven't really seen a need to add a console window, though I might
|
||||
// at some point. --arcum42
|
||||
namespace Console
|
||||
{
|
||||
static const char *tbl_color_codes[] =
|
||||
{
|
||||
"\033[30m" // black
|
||||
, "\033[31m" // red
|
||||
, "\033[32m" // green
|
||||
, "\033[33m" // yellow
|
||||
, "\033[34m" // blue
|
||||
, "\033[35m" // magenta
|
||||
, "\033[36m" // cyan
|
||||
, "\033[37m" // white!
|
||||
};
|
||||
|
||||
void SetTitle(const string& title)
|
||||
{
|
||||
}
|
||||
|
||||
void Open()
|
||||
{
|
||||
}
|
||||
|
||||
void Close()
|
||||
{
|
||||
}
|
||||
|
||||
__forceinline bool __fastcall Newline()
|
||||
{
|
||||
if (Config.PsxOut)
|
||||
printf("\n");
|
||||
|
||||
if (emuLog != NULL)
|
||||
{
|
||||
fprintf(emuLog,"\n");
|
||||
fflush(emuLog);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
__forceinline bool __fastcall Write(const char* fmt)
|
||||
{
|
||||
// By using fputs, append a newline automatically.
|
||||
if (Config.PsxOut) fputs(fmt, stdout);
|
||||
|
||||
// Color changing should not use this function, as we don't want the color codes logged, or new lines inserted.
|
||||
if (emuLog != NULL) fputs(fmt, emuLog);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void __fastcall SetColor(Colors color)
|
||||
{
|
||||
// Don't log the color change, and don't insert a new line afterwards.
|
||||
printf(tbl_color_codes[color]);
|
||||
}
|
||||
|
||||
void ClearColor()
|
||||
{
|
||||
// Don't log the color change, and don't insert a new line afterwards.
|
||||
printf(COLOR_RESET);
|
||||
}
|
||||
}
|
||||
|
||||
namespace Msgbox
|
||||
{
|
||||
bool Alert(const char* fmt)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
|
||||
if (g_Startup.NoGui)
|
||||
{
|
||||
Console::Error(fmt);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
dialog = gtk_message_dialog_new(GTK_WINDOW(MainWindow),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_OK, fmt);
|
||||
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Alert(const char* fmt, VARG_PARAM dummy, ...)
|
||||
{
|
||||
GtkWidget *dialog;
|
||||
string msg;
|
||||
va_list list;
|
||||
|
||||
va_start(list, dummy);
|
||||
vssprintf(msg, fmt, list);
|
||||
va_end(list);
|
||||
|
||||
// fixme: using NULL terminators on std::string might work, but are technically "incorrect."
|
||||
// This should use one of the std::string trimming functions instead.
|
||||
if (msg[msg.length()-1] == '\n')
|
||||
msg[msg.length()-1] = 0;
|
||||
|
||||
if (g_Startup.NoGui)
|
||||
{
|
||||
Console::Error(msg.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
dialog = gtk_message_dialog_new(GTK_WINDOW(MainWindow),
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_OK, msg.c_str());
|
||||
gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
gtk_widget_destroy(dialog);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,534 +0,0 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "LnxMain.h"
|
||||
|
||||
using namespace R5900;
|
||||
|
||||
DIR *dir;
|
||||
GtkWidget *FileSel;
|
||||
GtkWidget *MsgDlg;
|
||||
const char* g_pRunGSState = NULL;
|
||||
|
||||
int efile = 0;
|
||||
char elfname[g_MaxPath];
|
||||
char MAIN_DIR[g_MaxPath];
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *file = NULL;
|
||||
char elfname[g_MaxPath];
|
||||
|
||||
efile = 0;
|
||||
|
||||
getcwd(MAIN_DIR, ArraySize(MAIN_DIR)); /* store main dir */
|
||||
Console::Notice("MAIN_DIR is %s", params MAIN_DIR);
|
||||
#ifdef ENABLE_NLS
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, "Langs");
|
||||
textdomain(PACKAGE);
|
||||
#endif
|
||||
|
||||
// Note: Config.InisDir won't do anything till we set up windows and the plugins to use it.
|
||||
#ifndef LOCAL_PLUGIN_INIS
|
||||
mkdir(DEFAULT_INIS_DIR, 0755);
|
||||
sprintf(Config.InisDir, "%s/%s/", MAIN_DIR, DEFAULT_INIS_DIR);
|
||||
sprintf(cfgfile, "%s/pcsx2.cfg", Config.InisDir);
|
||||
#else
|
||||
mkdir("~/.pcsx2");
|
||||
chdir("~/.pcsx2");
|
||||
mkdir(DEFAULT_INIS_DIR, 0755);
|
||||
sprintf(Config.InisDir, "~/.pcsx2/%s/", DEFAULT_INIS_DIR);
|
||||
sprintf(cfgfile, "%s/pcsx2.cfg", Config.InisDir);
|
||||
chdir(MAIN_DIR);
|
||||
#endif
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
memset(&g_Startup, 0, sizeof(g_Startup));
|
||||
#endif
|
||||
|
||||
if (!ParseCommandLine(argc, argv, file)) return 0;
|
||||
|
||||
// make gtk thread safe if using MTGS
|
||||
if (CHECK_MULTIGS)
|
||||
{
|
||||
g_thread_init(NULL);
|
||||
gdk_threads_init();
|
||||
}
|
||||
|
||||
if (!g_Startup.NoGui)
|
||||
{
|
||||
gtk_init(NULL, NULL);
|
||||
}
|
||||
|
||||
if (LoadConfig() == -1)
|
||||
{
|
||||
|
||||
memset(&Config, 0, sizeof(Config));
|
||||
sprintf(Config.BiosDir, "%s/%s/", MAIN_DIR, DEFAULT_BIOS_DIR);
|
||||
sprintf(Config.PluginsDir, "%s/%s/", MAIN_DIR, DEFAULT_PLUGINS_DIR);
|
||||
sprintf(Config.Mcd[0].Filename, "%s/%s/%s", MAIN_DIR, MEMCARDS_DIR, DEFAULT_MEMCARD1);
|
||||
sprintf(Config.Mcd[1].Filename, "%s/%s/%s", MAIN_DIR, MEMCARDS_DIR, DEFAULT_MEMCARD2);
|
||||
Config.Mcd[0].Enabled = 1;
|
||||
Config.Mcd[1].Enabled = 1;
|
||||
Config.McdEnableEject = 1;
|
||||
Config.Patch = 0;
|
||||
Config.PsxOut = 1;
|
||||
Config.Options = PCSX2_EEREC | PCSX2_VU0REC | PCSX2_VU1REC | PCSX2_FRAMELIMIT_LIMIT;
|
||||
Config.sseMXCSR = DEFAULT_sseMXCSR;
|
||||
Config.sseVUMXCSR = DEFAULT_sseVUMXCSR;
|
||||
Config.eeOptions = DEFAULT_eeOptions;
|
||||
Config.vuOptions = DEFAULT_vuOptions;
|
||||
|
||||
Msgbox::Alert("Pcsx2 needs to be configured");
|
||||
Pcsx2Configure();
|
||||
|
||||
LoadConfig();
|
||||
}
|
||||
|
||||
InitLanguages();
|
||||
|
||||
if (Config.PsxOut)
|
||||
{
|
||||
// output the help commands
|
||||
Console::WriteLn("\tF1 - save state");
|
||||
Console::WriteLn("\t(Shift +) F2 - cycle states");
|
||||
Console::WriteLn("\tF3 - load state");
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
Console::WriteLn("\tF10 - dump performance counters");
|
||||
Console::WriteLn("\tF11 - save GS state");
|
||||
Console::WriteLn("\tF12 - dump hardware registers");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!SysInit()) return 1;
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
if (g_pRunGSState)
|
||||
{
|
||||
LoadGSState(g_pRunGSState);
|
||||
SysClose();
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!g_Startup.NoGui && (file == NULL))
|
||||
{
|
||||
StartGui();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (OpenPlugins(file) == -1) return -1;
|
||||
|
||||
SysReset();
|
||||
|
||||
cpuExecuteBios();
|
||||
if (file) strcpy(elfname, file);
|
||||
if (!efile) efile = GetPS2ElfName(elfname);
|
||||
loadElfFile(elfname);
|
||||
|
||||
//ExecuteCpu();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InitLanguages()
|
||||
{
|
||||
char *lang;
|
||||
int i = 1;
|
||||
|
||||
if (Config.Lang[0] == 0)
|
||||
{
|
||||
strcpy(Config.Lang, "en");
|
||||
}
|
||||
|
||||
langs = (_langs*)malloc(sizeof(_langs));
|
||||
strcpy(langs[0].lang, "en");
|
||||
dir = opendir(LANGS_DIR);
|
||||
|
||||
while ((lang = GetLanguageNext()) != NULL)
|
||||
{
|
||||
langs = (_langs*)realloc(langs, sizeof(_langs) * (i + 1));
|
||||
strcpy(langs[i].lang, lang);
|
||||
i++;
|
||||
}
|
||||
|
||||
CloseLanguages();
|
||||
langsMax = i;
|
||||
}
|
||||
|
||||
char *GetLanguageNext()
|
||||
{
|
||||
struct dirent *ent;
|
||||
|
||||
if (dir == NULL) return NULL;
|
||||
for (;;)
|
||||
{
|
||||
ent = readdir(dir);
|
||||
if (ent == NULL) return NULL;
|
||||
|
||||
if (!strcmp(ent->d_name, ".")) continue;
|
||||
if (!strcmp(ent->d_name, "..")) continue;
|
||||
break;
|
||||
}
|
||||
|
||||
return ent->d_name;
|
||||
}
|
||||
|
||||
void CloseLanguages()
|
||||
{
|
||||
if (dir) closedir(dir);
|
||||
}
|
||||
|
||||
void ChangeLanguage(char *lang)
|
||||
{
|
||||
strcpy(Config.Lang, lang);
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
void OnMsg_Ok()
|
||||
{
|
||||
gtk_widget_destroy(MsgDlg);
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
|
||||
void On_Dialog_Cancelled(GtkButton* button, gpointer user_data)
|
||||
{
|
||||
gtk_widget_destroy((GtkWidget*)gtk_widget_get_toplevel((GtkWidget*)button));
|
||||
gtk_widget_set_sensitive(MainWindow, TRUE);
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
void On_Dialog_Close(GtkDialog* dialog, gpointer user_data)
|
||||
{
|
||||
gtk_widget_set_sensitive(MainWindow, TRUE);
|
||||
}
|
||||
|
||||
void RefreshMenuSlots()
|
||||
{
|
||||
GtkWidget *Item;
|
||||
char str[g_MaxPath], str2[g_MaxPath];
|
||||
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
sprintf(str, "load_slot_%d", i);
|
||||
sprintf(str2, "save_slot_%d", i);
|
||||
Item = lookup_widget(MainWindow, str);
|
||||
|
||||
if GTK_IS_WIDGET(Item)
|
||||
gtk_widget_set_sensitive(Item, Slots[i]);
|
||||
else
|
||||
Console::Error("No such widget: %s", params str);
|
||||
|
||||
Item = lookup_widget(MainWindow, str2);
|
||||
gtk_widget_set_sensitive(Item, (ElfCRC != 0));
|
||||
}
|
||||
}
|
||||
void StartGui()
|
||||
{
|
||||
GtkWidget *Menu;
|
||||
GtkWidget *Item;
|
||||
|
||||
u32 i;
|
||||
|
||||
add_pixmap_directory(".pixmaps");
|
||||
MainWindow = create_MainWindow();
|
||||
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
gtk_window_set_title(GTK_WINDOW(MainWindow), "PCSX2 "PCSX2_VERSION" "SVN_REV);
|
||||
#else
|
||||
gtk_window_set_title(GTK_WINDOW(MainWindow), "PCSX2 "PCSX2_VERSION);
|
||||
#endif
|
||||
// status bar
|
||||
pStatusBar = gtk_statusbar_new();
|
||||
gtk_box_pack_start(GTK_BOX(lookup_widget(MainWindow, "status_box")), pStatusBar, TRUE, TRUE, 0);
|
||||
gtk_widget_show(pStatusBar);
|
||||
|
||||
HostGui::SetStatusMsg( "F1 - save, F2 - next state, Shift+F2 - prev state, F3 - load, F8 - snapshot");
|
||||
|
||||
// add all the languages
|
||||
Item = lookup_widget(MainWindow, "GtkMenuItem_Language");
|
||||
Menu = gtk_menu_new();
|
||||
gtk_menu_item_set_submenu(GTK_MENU_ITEM(Item), Menu);
|
||||
|
||||
for (i = 0; i < langsMax; i++)
|
||||
{
|
||||
Item = gtk_check_menu_item_new_with_label(ParseLang(langs[i].lang));
|
||||
gtk_widget_show(Item);
|
||||
gtk_container_add(GTK_CONTAINER(Menu), Item);
|
||||
gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(Item), TRUE);
|
||||
if (!strcmp(Config.Lang, langs[i].lang))
|
||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(Item), TRUE);
|
||||
|
||||
gtk_signal_connect(GTK_OBJECT(Item), "activate",
|
||||
GTK_SIGNAL_FUNC(OnLanguage),
|
||||
(gpointer)(uptr)i);
|
||||
}
|
||||
|
||||
// check the appropriate menu items
|
||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(lookup_widget(MainWindow, "enable_console1")), Config.PsxOut);
|
||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(lookup_widget(MainWindow, "enable_patches1")), Config.Patch);
|
||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(lookup_widget(MainWindow, "print_cdvd_info1")), Config.cdvdPrint);
|
||||
|
||||
// disable anything not implemented or not working properly.
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(lookup_widget(MainWindow, "patch_browser1")), FALSE);
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(lookup_widget(MainWindow, "patch_finder2")), FALSE);
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(lookup_widget(MainWindow, "GtkMenuItem_EnterDebugger")), FALSE);
|
||||
#ifndef PCSX2_DEVBUILD
|
||||
/*gtk_widget_set_sensitive(GTK_WIDGET(lookup_widget(MainWindow, "GtkMenuItem_Logging")), FALSE);
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(lookup_widget(MainWindow, "GtkMenuItem_Arguments")), FALSE);*/
|
||||
gtk_widget_destroy(lookup_widget(MainWindow, "GtkMenuItem_Debug"));
|
||||
#endif
|
||||
|
||||
RefreshMenuSlots();
|
||||
|
||||
gtk_widget_show_all(MainWindow);
|
||||
gtk_window_activate_focus(GTK_WINDOW(MainWindow));
|
||||
gtk_main();
|
||||
}
|
||||
|
||||
void OnDestroy(GtkObject *object, gpointer user_data) {}
|
||||
|
||||
gboolean OnDelete(GtkWidget *widget, GdkEvent *event, gpointer user_data)
|
||||
{
|
||||
pcsx2_exit();
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
int Pcsx2Configure()
|
||||
{
|
||||
if (g_Startup.NoGui) return 0;
|
||||
|
||||
MainWindow = NULL;
|
||||
OnConf_Conf(NULL, 0);
|
||||
|
||||
return applychanges;
|
||||
}
|
||||
|
||||
void OnLanguage(GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
ChangeLanguage(langs[(int)(uptr)user_data].lang);
|
||||
gtk_widget_destroy(MainWindow);
|
||||
gtk_main_quit();
|
||||
while (gtk_events_pending()) gtk_main_iteration();
|
||||
StartGui();
|
||||
}
|
||||
|
||||
void OnFile_RunCD(GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
SysReset();
|
||||
SysPrepareExecution(NULL);
|
||||
}
|
||||
|
||||
void OnRunElf_Ok(GtkButton* button, gpointer user_data)
|
||||
{
|
||||
gchar *File;
|
||||
|
||||
File = (gchar*)gtk_file_selection_get_filename(GTK_FILE_SELECTION(FileSel));
|
||||
strcpy(elfname, File);
|
||||
gtk_widget_destroy(FileSel);
|
||||
|
||||
SysPrepareExecution(elfname);
|
||||
}
|
||||
|
||||
void OnRunElf_Cancel(GtkButton* button, gpointer user_data)
|
||||
{
|
||||
gtk_widget_destroy(FileSel);
|
||||
}
|
||||
|
||||
void OnFile_LoadElf(GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
GtkWidget *Ok, *Cancel;
|
||||
|
||||
FileSel = gtk_file_selection_new("Select Psx Elf File");
|
||||
|
||||
Ok = GTK_FILE_SELECTION(FileSel)->ok_button;
|
||||
gtk_signal_connect(GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnRunElf_Ok), NULL);
|
||||
gtk_widget_show(Ok);
|
||||
|
||||
Cancel = GTK_FILE_SELECTION(FileSel)->cancel_button;
|
||||
gtk_signal_connect(GTK_OBJECT(Cancel), "clicked", GTK_SIGNAL_FUNC(OnRunElf_Cancel), NULL);
|
||||
gtk_widget_show(Cancel);
|
||||
|
||||
gtk_widget_show(FileSel);
|
||||
gdk_window_raise(FileSel->window);
|
||||
}
|
||||
|
||||
void pcsx2_exit()
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *ent;
|
||||
void *Handle;
|
||||
char plugin[g_MaxPath];
|
||||
|
||||
// with this the problem with plugins that are linked with the pthread
|
||||
// library is solved
|
||||
|
||||
dir = opendir(Config.PluginsDir);
|
||||
if (dir != NULL)
|
||||
{
|
||||
while ((ent = readdir(dir)) != NULL)
|
||||
{
|
||||
sprintf(plugin, "%s%s", Config.PluginsDir, ent->d_name);
|
||||
|
||||
if (strstr(plugin, ".so") == NULL) continue;
|
||||
Handle = SysLoadLibrary(plugin);
|
||||
if (Handle == NULL) continue;
|
||||
}
|
||||
}
|
||||
|
||||
printf("PCSX2 Quitting\n");
|
||||
|
||||
if (g_Startup.NoGui)
|
||||
{
|
||||
SysClose();
|
||||
exit(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_main_quit();
|
||||
SysClose();
|
||||
gtk_exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
void SignalExit(int sig)
|
||||
{
|
||||
ClosePlugins(true);
|
||||
pcsx2_exit();
|
||||
}
|
||||
|
||||
void OnFile_Exit(GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
pcsx2_exit();
|
||||
}
|
||||
|
||||
void OnEmu_Run(GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
SysPrepareExecution(NULL, true); // boots bios if no savestate is to be recovered
|
||||
}
|
||||
|
||||
void OnEmu_Reset(GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
SysReset();
|
||||
}
|
||||
|
||||
//2002-09-28 (Florin)
|
||||
void OnArguments_Ok(GtkButton *button, gpointer user_data)
|
||||
{
|
||||
char *str;
|
||||
|
||||
str = (char*)gtk_entry_get_text(GTK_ENTRY(widgetCmdLine));
|
||||
memcpy(args, str, g_MaxPath);
|
||||
|
||||
gtk_widget_destroy(CmdLine);
|
||||
gtk_widget_set_sensitive(MainWindow, TRUE);
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
void OnEmu_Arguments(GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
GtkWidget *widgetCmdLine;
|
||||
|
||||
CmdLine = create_CmdLine();
|
||||
gtk_window_set_title(GTK_WINDOW(CmdLine), _("Program arguments"));
|
||||
|
||||
widgetCmdLine = lookup_widget(CmdLine, "GtkEntry_dCMDLINE");
|
||||
|
||||
gtk_entry_set_text(GTK_ENTRY(widgetCmdLine), args);
|
||||
gtk_widget_show_all(CmdLine);
|
||||
gtk_widget_set_sensitive(MainWindow, FALSE);
|
||||
gtk_main();
|
||||
}
|
||||
|
||||
void OnLogging_Ok(GtkButton *button, gpointer user_data)
|
||||
{
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
GtkWidget *Btn;
|
||||
char str[32];
|
||||
int i, ret;
|
||||
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (((i > 16) && (i < 20)) || (i == 29))
|
||||
continue;
|
||||
|
||||
sprintf(str, "Log%d", i);
|
||||
Btn = lookup_widget(LogDlg, str);
|
||||
ret = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(Btn));
|
||||
if (ret) varLog |= 1 << i;
|
||||
else varLog &= ~(1 << i);
|
||||
}
|
||||
|
||||
SaveConfig();
|
||||
#endif
|
||||
|
||||
gtk_widget_destroy(LogDlg);
|
||||
gtk_widget_set_sensitive(MainWindow, TRUE);
|
||||
gtk_main_quit();
|
||||
}
|
||||
|
||||
void OnDebug_Logging(GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
GtkWidget *Btn;
|
||||
char str[32];
|
||||
int i;
|
||||
|
||||
LogDlg = create_Logging();
|
||||
|
||||
|
||||
for (i = 0; i < 32; i++)
|
||||
{
|
||||
if (((i > 16) && (i < 20)) || (i == 29))
|
||||
continue;
|
||||
|
||||
sprintf(str, "Log%d", i);
|
||||
Btn = lookup_widget(LogDlg, str);
|
||||
gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(Btn), varLog & (1 << i));
|
||||
}
|
||||
|
||||
gtk_widget_show_all(LogDlg);
|
||||
gtk_widget_set_sensitive(MainWindow, FALSE);
|
||||
gtk_main();
|
||||
}
|
||||
|
||||
void on_patch_browser1_activate(GtkMenuItem *menuitem, gpointer user_data) {}
|
||||
|
||||
void on_patch_finder2_activate(GtkMenuItem *menuitem, gpointer user_data) {}
|
||||
|
||||
void on_enable_console1_activate(GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
Config.PsxOut = (int)gtk_check_menu_item_get_active((GtkCheckMenuItem*)menuitem);
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
void on_enable_patches1_activate(GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
Config.Patch = (int)gtk_check_menu_item_get_active((GtkCheckMenuItem*)menuitem);
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
void OnPrintCdvdInfo(GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
Config.cdvdPrint = (int)gtk_check_menu_item_get_active((GtkCheckMenuItem*)menuitem);
|
||||
SaveConfig();
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __LNXMAIN_H__
|
||||
#define __LNXMAIN_H__
|
||||
|
||||
#include "Linux.h"
|
||||
#include "LnxMain.h"
|
||||
#include "HostGui.h"
|
||||
|
||||
extern bool applychanges;
|
||||
extern bool Slots[5];
|
||||
|
||||
extern bool ParseCommandLine(int argc, char *argv[], char *file);
|
||||
extern void MemoryCard_Init();
|
||||
|
||||
void OnLanguage(GtkMenuItem *menuitem, gpointer user_data);
|
||||
void InitLanguages();
|
||||
char *GetLanguageNext();
|
||||
void CloseLanguages();
|
||||
|
||||
void StartGui();
|
||||
void pcsx2_exit();
|
||||
extern bool SysInit();
|
||||
extern void SysClose();
|
||||
|
||||
GtkWidget *MainWindow, *Status_Box;
|
||||
GtkWidget *pStatusBar = NULL;
|
||||
GtkWidget *CmdLine, *widgetCmdLine;
|
||||
GtkWidget *LogDlg, *MemDlg;
|
||||
GtkAccelGroup *AccelGroup;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char lang[g_MaxPath];
|
||||
} _langs;
|
||||
|
||||
_langs *langs;
|
||||
unsigned int langsMax;
|
||||
|
||||
const char* phelpmsg =
|
||||
"\tpcsx2 [options] [file]\n\n"
|
||||
"-cfg [file] {configuration file}\n"
|
||||
"-efile [efile] {0 - reset, 1 - runcd (default), 2 - loadelf}\n"
|
||||
"-help {display this help file}\n"
|
||||
"-nogui {Don't use gui when launching}\n"
|
||||
"-loadgs [file} {Loads a gsstate}\n"
|
||||
"\n"
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
"Testing Options: \n"
|
||||
"\t-frame [frame] {game will run up to this frame before exiting}\n"
|
||||
"\t-image [name] {path and base name of image (do not include the .ext)}\n"
|
||||
"\t-jpg {save images to jpg format}\n"
|
||||
"\t-log [name] {log path to save log file in}\n"
|
||||
"\t-logopt [hex] {log options in hex (see debug.h) }\n"
|
||||
"\t-numimages [num] {after hitting frame, this many images will be captures every 20 frames}\n"
|
||||
"\t-test {Triggers testing mode (only for dev builds)}\n"
|
||||
"\n"
|
||||
#endif
|
||||
"Load Plugins:\n"
|
||||
"\t-cdvd [libpath] {specify the library load path of the CDVD plugin}\n"
|
||||
"\t-gs [libpath] {specify the library load path of the GS plugin}\n"
|
||||
"-pad [tsxcal] {specify to hold down on the triangle, square, circle, x, start, select buttons}\n"
|
||||
"\t-spu [libpath] {specify the library load path of the SPU2 plugin}\n"
|
||||
"\n";
|
||||
|
||||
#endif
|
|
@ -1,572 +0,0 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "Linux.h"
|
||||
#include "LnxSysExec.h"
|
||||
#include "HostGui.h"
|
||||
|
||||
static bool sinit = false;
|
||||
GtkWidget *FileSel;
|
||||
static uptr current_offset = 0;
|
||||
static uptr offset_counter = 0;
|
||||
bool Slots[5] = { false, false, false, false, false };
|
||||
|
||||
__noinline void InstallLinuxExceptionHandler()
|
||||
{
|
||||
struct sigaction sa;
|
||||
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
sa.sa_sigaction = &SysPageFaultExceptionFilter;
|
||||
sigaction(SIGSEGV, &sa, NULL);
|
||||
}
|
||||
|
||||
__noinline void ReleaseLinuxExceptionHandler()
|
||||
{
|
||||
// This may be called too early or something, since implementing it causes all games to segfault.
|
||||
// I'll look in to it. --arcum42
|
||||
}
|
||||
|
||||
__noinline void KillLinuxExceptionHandler()
|
||||
{
|
||||
struct sigaction sa;
|
||||
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = SA_RESETHAND;
|
||||
//sa.sa_sigaction = &SysPageFaultExceptionFilter;
|
||||
sigaction(SIGSEGV, &sa, NULL);
|
||||
}
|
||||
static const uptr m_pagemask = getpagesize()-1;
|
||||
|
||||
// Linux implementation of SIGSEGV handler. Bind it using sigaction().
|
||||
__noinline void SysPageFaultExceptionFilter( int signal, siginfo_t *info, void * )
|
||||
{
|
||||
// get bad virtual address
|
||||
uptr offset = (u8*)info->si_addr - psM;
|
||||
|
||||
if (offset != current_offset)
|
||||
{
|
||||
current_offset = offset;
|
||||
offset_counter = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
offset_counter++;
|
||||
if (offset_counter > 500)
|
||||
{
|
||||
DevCon::Status( "Offset 0x%x endlessly repeating. Aborting.", params offset );
|
||||
KillLinuxExceptionHandler();
|
||||
assert( false );
|
||||
}
|
||||
}
|
||||
|
||||
if (offset>=Ps2MemSize::Base)
|
||||
{
|
||||
// Bad mojo! Completely invalid address.
|
||||
// Instigate a crash or abort emulation or something.
|
||||
DevCon::Status( "Offset 0x%x invalid. Legit SIGSEGV. Aborting.", params offset );
|
||||
KillLinuxExceptionHandler();
|
||||
assert( false );
|
||||
}
|
||||
|
||||
mmap_ClearCpuBlock( offset & ~m_pagemask );
|
||||
}
|
||||
|
||||
bool ParseCommandLine(int argc, char *argv[], char *file)
|
||||
{
|
||||
int i = 1;
|
||||
g_Startup.BootMode = BootMode_Bios;
|
||||
|
||||
while (i < argc)
|
||||
{
|
||||
char* token = argv[i++];
|
||||
|
||||
if (stricmp(token, "-help") == 0 || stricmp(token, "--help") == 0 || stricmp(token, "-h") == 0)
|
||||
{
|
||||
//Msgbox::Alert( phelpmsg );
|
||||
return false;
|
||||
}
|
||||
else if (stricmp(token, "-nogui") == 0)
|
||||
{
|
||||
g_Startup.NoGui = FALSE;
|
||||
}
|
||||
else if (stricmp(token, "-loadgs") == 0)
|
||||
{
|
||||
g_pRunGSState = argv[i++];
|
||||
}
|
||||
else if( strcmp(token, "-bootmode" ) == 0)
|
||||
{
|
||||
token = argv[i++];
|
||||
g_Startup.BootMode = (StartupMode)atoi( token);
|
||||
g_Startup.Enabled = true;
|
||||
}
|
||||
else if (stricmp(token, "-gs") == 0)
|
||||
{
|
||||
token = argv[i++];
|
||||
g_Startup.gsdll = token;
|
||||
}
|
||||
else if (stricmp(token, "-cdvd") == 0)
|
||||
{
|
||||
token = argv[i++];
|
||||
g_Startup.cdvddll = token;
|
||||
}
|
||||
else if (stricmp(token, "-spu") == 0)
|
||||
{
|
||||
token = argv[i++];
|
||||
g_Startup.spudll = token;
|
||||
}
|
||||
else if (stricmp(token, "-pad") == 0)
|
||||
{
|
||||
token = argv[i++];
|
||||
g_Startup.pad1dll = token;
|
||||
g_Startup.pad2dll = token;
|
||||
}
|
||||
else if (stricmp(token, "-pad1") == 0)
|
||||
{
|
||||
token = argv[i++];
|
||||
g_Startup.pad1dll = token;
|
||||
}
|
||||
else if (stricmp(token, "-pad2") == 0)
|
||||
{
|
||||
token = argv[i++];
|
||||
g_Startup.pad2dll = token;
|
||||
}
|
||||
else if (stricmp(token, "-loadgs") == 0)
|
||||
{
|
||||
token = argv[i++];
|
||||
g_pRunGSState = token;
|
||||
}
|
||||
else
|
||||
{
|
||||
file = token;
|
||||
printf("opening file %s\n", file);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void SysPrintf(const char *fmt, ...)
|
||||
{
|
||||
va_list list;
|
||||
char msg[512];
|
||||
|
||||
va_start(list, fmt);
|
||||
vsnprintf(msg, 511, fmt, list);
|
||||
msg[511] = '\0';
|
||||
va_end(list);
|
||||
|
||||
Console::Write(msg);
|
||||
}
|
||||
|
||||
static std::string str_Default( "default" );
|
||||
|
||||
void RunGui()
|
||||
{
|
||||
PCSX2_MEM_PROTECT_BEGIN();
|
||||
|
||||
LoadPatch( str_Default );
|
||||
if( g_Startup.NoGui || g_Startup.Enabled )
|
||||
{
|
||||
// Initially bypass GUI and start PCSX2 directly.
|
||||
// Manually load plugins using the user's configured image (if non-elf).
|
||||
|
||||
if( g_Startup.Enabled && (g_Startup.BootMode != BootMode_Elf) )
|
||||
{
|
||||
if (OpenPlugins(g_Startup.ImageName) == -1)
|
||||
return;
|
||||
}
|
||||
|
||||
SysPrepareExecution(
|
||||
(g_Startup.BootMode == BootMode_Elf) ? g_Startup.ImageName : NULL,
|
||||
(g_Startup.BootMode == BootMode_Bios)
|
||||
);
|
||||
}
|
||||
|
||||
StartGui();
|
||||
|
||||
PCSX2_MEM_PROTECT_END();
|
||||
}
|
||||
|
||||
void OnStates_Load(GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
char *name;
|
||||
int i;
|
||||
|
||||
if (GTK_BIN (menuitem)->child)
|
||||
{
|
||||
GtkWidget *child = GTK_BIN (menuitem)->child;
|
||||
|
||||
if (GTK_IS_LABEL (child))
|
||||
gtk_label_get (GTK_LABEL (child), &name);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
sscanf(name, "Slot %d", &i);
|
||||
States_Load(i);
|
||||
RefreshMenuSlots();
|
||||
}
|
||||
|
||||
void OnLoadOther_Ok(GtkButton* button, gpointer user_data)
|
||||
{
|
||||
gchar *File;
|
||||
char str[g_MaxPath];
|
||||
|
||||
File = (gchar*)gtk_file_selection_get_filename(GTK_FILE_SELECTION(FileSel));
|
||||
strcpy(str, File);
|
||||
gtk_widget_destroy(FileSel);
|
||||
States_Load(str);
|
||||
RefreshMenuSlots();
|
||||
}
|
||||
|
||||
void OnLoadOther_Cancel(GtkButton* button, gpointer user_data)
|
||||
{
|
||||
gtk_widget_destroy(FileSel);
|
||||
}
|
||||
|
||||
void OnStates_LoadOther(GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
GtkWidget *Ok, *Cancel;
|
||||
|
||||
FileSel = gtk_file_selection_new(_("Select State File"));
|
||||
gtk_file_selection_set_filename(GTK_FILE_SELECTION(FileSel), SSTATES_DIR "/");
|
||||
|
||||
Ok = GTK_FILE_SELECTION(FileSel)->ok_button;
|
||||
gtk_signal_connect(GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnLoadOther_Ok), NULL);
|
||||
gtk_widget_show(Ok);
|
||||
|
||||
Cancel = GTK_FILE_SELECTION(FileSel)->cancel_button;
|
||||
gtk_signal_connect(GTK_OBJECT(Cancel), "clicked", GTK_SIGNAL_FUNC(OnLoadOther_Cancel), NULL);
|
||||
gtk_widget_show(Cancel);
|
||||
|
||||
gtk_widget_show(FileSel);
|
||||
gdk_window_raise(FileSel->window);
|
||||
}
|
||||
|
||||
void OnStates_Save(GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
char *name;
|
||||
int i;
|
||||
|
||||
if (GTK_BIN (menuitem)->child)
|
||||
{
|
||||
GtkWidget *child = GTK_BIN (menuitem)->child;
|
||||
|
||||
if (GTK_IS_LABEL (child))
|
||||
gtk_label_get (GTK_LABEL (child), &name);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
sscanf(name, "Slot %d", &i);
|
||||
States_Save(i);
|
||||
}
|
||||
|
||||
void OnSaveOther_Ok(GtkButton* button, gpointer user_data)
|
||||
{
|
||||
gchar *File;
|
||||
char str[g_MaxPath];
|
||||
|
||||
File = (gchar*)gtk_file_selection_get_filename(GTK_FILE_SELECTION(FileSel));
|
||||
strcpy(str, File);
|
||||
gtk_widget_destroy(FileSel);
|
||||
|
||||
States_Save(str);
|
||||
}
|
||||
|
||||
void OnSaveOther_Cancel(GtkButton* button, gpointer user_data)
|
||||
{
|
||||
gtk_widget_destroy(FileSel);
|
||||
}
|
||||
|
||||
void OnStates_SaveOther(GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
GtkWidget *Ok, *Cancel;
|
||||
|
||||
FileSel = gtk_file_selection_new(_("Select State File"));
|
||||
gtk_file_selection_set_filename(GTK_FILE_SELECTION(FileSel), SSTATES_DIR "/");
|
||||
|
||||
Ok = GTK_FILE_SELECTION(FileSel)->ok_button;
|
||||
gtk_signal_connect(GTK_OBJECT(Ok), "clicked", GTK_SIGNAL_FUNC(OnSaveOther_Ok), NULL);
|
||||
gtk_widget_show(Ok);
|
||||
|
||||
Cancel = GTK_FILE_SELECTION(FileSel)->cancel_button;
|
||||
gtk_signal_connect(GTK_OBJECT(Cancel), "clicked", GTK_SIGNAL_FUNC(OnSaveOther_Cancel), NULL);
|
||||
gtk_widget_show(Cancel);
|
||||
|
||||
gtk_widget_show(FileSel);
|
||||
gdk_window_raise(FileSel->window);
|
||||
}
|
||||
|
||||
bool SysInit()
|
||||
{
|
||||
if (sinit) return true;
|
||||
sinit = true;
|
||||
|
||||
mkdir(SSTATES_DIR, 0755);
|
||||
mkdir(MEMCARDS_DIR, 0755);
|
||||
|
||||
mkdir(LOGS_DIR, 0755);
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
if (emuLog == NULL)
|
||||
emuLog = fopen(LOGS_DIR "/emuLog.txt", "wb");
|
||||
#endif
|
||||
|
||||
if (emuLog != NULL)
|
||||
setvbuf(emuLog, NULL, _IONBF, 0);
|
||||
|
||||
PCSX2_MEM_PROTECT_BEGIN();
|
||||
SysDetect();
|
||||
if (!SysAllocateMem()) return false; // critical memory allocation failure;
|
||||
|
||||
SysAllocateDynarecs();
|
||||
PCSX2_MEM_PROTECT_END();
|
||||
|
||||
while (LoadPlugins() == -1)
|
||||
{
|
||||
if (Pcsx2Configure() == FALSE)
|
||||
{
|
||||
Msgbox::Alert("Configuration failed. Exiting.");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SysClose()
|
||||
{
|
||||
if (sinit == false) return;
|
||||
cpuShutdown();
|
||||
ClosePlugins( true );
|
||||
ReleasePlugins();
|
||||
|
||||
if (emuLog != NULL)
|
||||
{
|
||||
fclose(emuLog);
|
||||
emuLog = NULL;
|
||||
}
|
||||
sinit = false;
|
||||
|
||||
// Precautionary extra shutdown stuff.
|
||||
SysEndExecution();
|
||||
g_EmulationInProgress = false;
|
||||
}
|
||||
|
||||
namespace HostSys
|
||||
{
|
||||
void *LoadLibrary(const char *lib)
|
||||
{
|
||||
return dlopen(lib, RTLD_NOW);
|
||||
}
|
||||
|
||||
void *LoadSym(void *lib, const char *sym)
|
||||
{
|
||||
return dlsym(lib, sym);
|
||||
}
|
||||
|
||||
const char *LibError()
|
||||
{
|
||||
return dlerror();
|
||||
}
|
||||
|
||||
void CloseLibrary(void *lib)
|
||||
{
|
||||
dlclose(lib);
|
||||
}
|
||||
|
||||
void *Mmap(uptr base, u32 size)
|
||||
{
|
||||
u8 *Mem;
|
||||
Mem = (u8*)mmap((uptr*)base, size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
||||
if (Mem == MAP_FAILED) Console::Notice("Mmap Failed!");
|
||||
|
||||
return Mem;
|
||||
}
|
||||
|
||||
void Munmap(uptr base, u32 size)
|
||||
{
|
||||
munmap((uptr*)base, size);
|
||||
}
|
||||
|
||||
void MemProtect( void* baseaddr, size_t size, PageProtectionMode mode, bool allowExecution )
|
||||
{
|
||||
// Breakpoint this to trap potentially inappropriate use of page protection, which would
|
||||
// be caused by failed aligned directives on global vars.
|
||||
if( ((uptr)baseaddr & m_pagemask) != 0 )
|
||||
{
|
||||
Console::Error(
|
||||
"*PCSX2/Linux Warning* Inappropriate use of page protection detected.\n"
|
||||
"\tbaseaddr not page aligned: 0x%08X", params (uptr)baseaddr
|
||||
);
|
||||
}
|
||||
|
||||
int lnxmode = 0;
|
||||
|
||||
// make sure base and size are aligned to the system page size:
|
||||
size = (size + m_pagemask) & ~m_pagemask;
|
||||
baseaddr = (void*)( ((uptr)baseaddr) & ~m_pagemask );
|
||||
|
||||
switch( mode )
|
||||
{
|
||||
case Protect_NoAccess: break;
|
||||
case Protect_ReadOnly: lnxmode = PROT_READ; break;
|
||||
case Protect_ReadWrite: lnxmode = PROT_READ | PROT_WRITE; break;
|
||||
}
|
||||
|
||||
if( allowExecution ) lnxmode |= PROT_EXEC;
|
||||
mprotect( baseaddr, size, lnxmode );
|
||||
}
|
||||
}
|
||||
|
||||
namespace HostGui
|
||||
{
|
||||
// Sets the status bar message without mirroring the output to the console.
|
||||
void SetStatusMsg( const string& text )
|
||||
{
|
||||
// don't try this in Visual C++ folks!
|
||||
gtk_statusbar_push(GTK_STATUSBAR(pStatusBar), 0, text.c_str());
|
||||
}
|
||||
|
||||
void Notice( const string& text )
|
||||
{
|
||||
// mirror output to the console!
|
||||
Console::Status( text.c_str() );
|
||||
SetStatusMsg( text );
|
||||
}
|
||||
|
||||
void ResetMenuSlots()
|
||||
{
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
Slots[i] = States_isSlotUsed(i);
|
||||
}
|
||||
}
|
||||
|
||||
void BeginExecution()
|
||||
{
|
||||
// Destroy the window. Ugly thing.
|
||||
gtk_widget_destroy(MainWindow);
|
||||
gtk_main_quit();
|
||||
|
||||
while (gtk_events_pending()) gtk_main_iteration();
|
||||
|
||||
signal(SIGINT, SignalExit);
|
||||
signal(SIGPIPE, SignalExit);
|
||||
|
||||
// no try/catch needed since no cleanup needed.. ?
|
||||
SysExecute();
|
||||
}
|
||||
|
||||
/* Quick macros for checking shift, control, alt, and caps lock. */
|
||||
#define SHIFT_EVT(evt) ((evt == XK_Shift_L) || (evt == XK_Shift_R))
|
||||
#define CTRL_EVT(evt) ((evt == XK_Control_L) || (evt == XK_Control_R))
|
||||
#define ALT_EVT(evt) ((evt == XK_Alt_L) || (evt == XK_Alt_R))
|
||||
#define CAPS_LOCK_EVT(evt) (evt == XK_Caps_Lock)
|
||||
|
||||
void __fastcall KeyEvent(keyEvent* ev)
|
||||
{
|
||||
struct KeyModifiers *keymod = &keymodifiers;
|
||||
|
||||
if (ev == NULL) return;
|
||||
|
||||
if (GSkeyEvent != NULL) GSkeyEvent(ev);
|
||||
|
||||
if (ev->evt == KEYPRESS)
|
||||
{
|
||||
if (SHIFT_EVT(ev->key)) keymod->shift = TRUE;
|
||||
if (CTRL_EVT(ev->key)) keymod->control = TRUE;
|
||||
if (ALT_EVT(ev->key)) keymod->alt = TRUE;
|
||||
if (CAPS_LOCK_EVT(ev->key)) keymod->capslock = TRUE;
|
||||
|
||||
switch (ev->key)
|
||||
{
|
||||
case XK_F1:
|
||||
case XK_F2:
|
||||
case XK_F3:
|
||||
case XK_F4:
|
||||
case XK_F5:
|
||||
case XK_F6:
|
||||
case XK_F7:
|
||||
case XK_F8:
|
||||
case XK_F9:
|
||||
case XK_F10:
|
||||
case XK_F11:
|
||||
case XK_F12:
|
||||
try
|
||||
{
|
||||
ProcessFKeys(ev->key - XK_F1 + 1, keymod);
|
||||
}
|
||||
catch (Exception::CpuStateShutdown&)
|
||||
{
|
||||
// Woops! Something was unrecoverable. Bummer.
|
||||
// Let's give the user a RunGui!
|
||||
|
||||
g_EmulationInProgress = false;
|
||||
SysEndExecution();
|
||||
}
|
||||
break;
|
||||
|
||||
case XK_Tab:
|
||||
CycleFrameLimit(0);
|
||||
break;
|
||||
|
||||
case XK_Escape:
|
||||
signal(SIGINT, SIG_DFL);
|
||||
signal(SIGPIPE, SIG_DFL);
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
if (g_SaveGSStream >= 3)
|
||||
{
|
||||
g_SaveGSStream = 4;// gs state
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
SysEndExecution();
|
||||
|
||||
if (g_Startup.NoGui) exit(0);
|
||||
|
||||
// fixme: The GUI is now capable of receiving control back from the
|
||||
// emulator. Which means that when we call SysEscapeExecute() here, the
|
||||
// emulation loop in ExecuteCpu() will exit. You should be able to set it
|
||||
// up so that it returns control to the existing GTK event loop, instead of
|
||||
// always starting a new one via RunGui(). (but could take some trial and
|
||||
// error) -- (air)
|
||||
|
||||
// Easier said then done; running gtk in two threads at the same time can't be
|
||||
// done, and working around that is pretty fiddly.
|
||||
RunGui();
|
||||
break;
|
||||
|
||||
default:
|
||||
GSkeyEvent(ev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (ev->evt == KEYRELEASE)
|
||||
{
|
||||
if (SHIFT_EVT(ev->key)) keymod->shift = FALSE;
|
||||
if (CTRL_EVT(ev->key)) keymod->control = FALSE;
|
||||
if (ALT_EVT(ev->key)) keymod->alt = FALSE;
|
||||
if (CAPS_LOCK_EVT(ev->key)) keymod->capslock = FALSE;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __LNXSYSEXEC_H__
|
||||
#define __LNXSYSEXEC_H__
|
||||
|
||||
#include "Linux.h"
|
||||
#include "GS.h"
|
||||
#include <sys/mman.h>
|
||||
#include "x86/iR5900.h"
|
||||
|
||||
void SysPageFaultExceptionFilter( int signal, siginfo_t *info, void * );
|
||||
void __fastcall InstallLinuxExceptionHandler();
|
||||
void __fastcall ReleaseLinuxExceptionHandler();
|
||||
|
||||
#define PCSX2_MEM_PROTECT_BEGIN() InstallLinuxExceptionHandler()
|
||||
#define PCSX2_MEM_PROTECT_END() ReleaseLinuxExceptionHandler()
|
||||
|
||||
extern void StartGui();
|
||||
extern void RefreshMenuSlots();
|
||||
|
||||
extern void SignalExit(int sig);
|
||||
extern const char* g_pRunGSState;
|
||||
extern int efile;
|
||||
extern GtkWidget *pStatusBar;
|
||||
|
||||
#endif
|
|
@ -1,107 +0,0 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2008 Pcsx2 Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "McdDlgs.h"
|
||||
|
||||
void OnConf_Memcards(GtkMenuItem *menuitem, gpointer user_data)
|
||||
{
|
||||
char file[g_MaxPath], card[g_MaxPath];
|
||||
DIR *dir;
|
||||
struct dirent *entry;
|
||||
struct stat statinfo;
|
||||
GtkWidget *memcombo[2];
|
||||
int i = 0, j = 0;
|
||||
bool active[2] ={false, false};
|
||||
|
||||
MemDlg = create_MemDlg();
|
||||
|
||||
memcombo[0] = lookup_widget(MemDlg, "memcard1combo");
|
||||
memcombo[1] = lookup_widget(MemDlg, "memcard2combo");
|
||||
|
||||
set_checked(MemDlg, "check_enable_mcd1", Config.Mcd[0].Enabled);
|
||||
set_checked(MemDlg, "check_enable_mcd2", Config.Mcd[1].Enabled);
|
||||
set_checked(MemDlg, "check_eject_mcds", Config.McdEnableEject);
|
||||
|
||||
getcwd(file, ArraySize(file)); /* store current dir */
|
||||
sprintf(card, "%s/%s", file, MEMCARDS_DIR );
|
||||
chdir(card); /* change dirs so that plugins can find their config file*/
|
||||
|
||||
if ((dir = opendir(card)) == NULL)
|
||||
{
|
||||
Console::Error("ERROR: Could not open directory %s\n", params card);
|
||||
return;
|
||||
}
|
||||
|
||||
while ((entry = readdir(dir)) != NULL)
|
||||
{
|
||||
stat(entry->d_name, &statinfo);
|
||||
|
||||
if (S_ISREG(statinfo.st_mode))
|
||||
{
|
||||
char path[g_MaxPath];
|
||||
|
||||
sprintf(path, "%s/%s/%s", MAIN_DIR, MEMCARDS_DIR, entry->d_name);
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
{
|
||||
gtk_combo_box_append_text(GTK_COMBO_BOX(memcombo[j]), entry->d_name);
|
||||
|
||||
if (strcmp(Config.Mcd[j].Filename, path) == 0)
|
||||
{
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(memcombo[j]), i);
|
||||
active[j] = true;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
|
||||
chdir(file);
|
||||
gtk_widget_show_all(MemDlg);
|
||||
gtk_widget_set_sensitive(MainWindow, FALSE);
|
||||
gtk_main();
|
||||
|
||||
}
|
||||
|
||||
void OnMemcards_Ok(GtkButton *button, gpointer user_data)
|
||||
{
|
||||
if (gtk_combo_box_get_active(GTK_COMBO_BOX(lookup_widget(MemDlg, "memcard1combo"))) != -1)
|
||||
sprintf(Config.Mcd[0].Filename, "%s/%s/%s", MAIN_DIR, MEMCARDS_DIR,
|
||||
gtk_combo_box_get_active_text(GTK_COMBO_BOX(lookup_widget(MemDlg, "memcard1combo"))));
|
||||
else
|
||||
sprintf(Config.Mcd[0].Filename, "%s/%s/%s", MAIN_DIR, MEMCARDS_DIR, DEFAULT_MEMCARD1);
|
||||
|
||||
|
||||
if (gtk_combo_box_get_active(GTK_COMBO_BOX(lookup_widget(MemDlg, "memcard2combo"))) != -1)
|
||||
sprintf(Config.Mcd[1].Filename, "%s/%s/%s", MAIN_DIR, MEMCARDS_DIR,
|
||||
gtk_combo_box_get_active_text(GTK_COMBO_BOX(lookup_widget(MemDlg, "memcard2combo"))));
|
||||
else
|
||||
sprintf(Config.Mcd[1].Filename, "%s/%s/%s", MAIN_DIR, MEMCARDS_DIR, DEFAULT_MEMCARD2);
|
||||
|
||||
Config.Mcd[0].Enabled = is_checked(MemDlg, "check_enable_mcd1");
|
||||
Config.Mcd[1].Enabled = is_checked(MemDlg, "check_enable_mcd2");
|
||||
Config.McdEnableEject = is_checked(MemDlg, "check_eject_mcds");
|
||||
|
||||
SaveConfig();
|
||||
|
||||
gtk_widget_destroy(MemDlg);
|
||||
gtk_widget_set_sensitive(MainWindow, TRUE);
|
||||
gtk_main_quit();
|
||||
}
|
|
@ -1,208 +0,0 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "Linux.h"
|
||||
|
||||
FILE *pref_file;
|
||||
char *data;
|
||||
|
||||
static void SetValue(const char *name, char *var)
|
||||
{
|
||||
fprintf(pref_file, "%s = %s\n", name, var);
|
||||
}
|
||||
|
||||
static void SetValuel(const char *name, s32 var)
|
||||
{
|
||||
fprintf(pref_file, "%s = %x\n", name, var);
|
||||
}
|
||||
|
||||
#define GetValue(name, var) {\
|
||||
char * tmp; \
|
||||
tmp = strstr(data, name); \
|
||||
if (tmp != NULL) { \
|
||||
tmp+=strlen(name); \
|
||||
while ((*tmp == ' ') || (*tmp == '=')) tmp++; \
|
||||
if (*tmp != '\n') sscanf(tmp, "%s", var); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define GetValuel(name, var) {\
|
||||
char * tmp; \
|
||||
tmp = strstr(data, name); \
|
||||
if (tmp != NULL) { \
|
||||
tmp+=strlen(name); \
|
||||
while ((*tmp == ' ') || (*tmp == '=')) tmp++; \
|
||||
if (*tmp != '\n') sscanf(tmp, "%x", &var); \
|
||||
} \
|
||||
}
|
||||
|
||||
int LoadConfig()
|
||||
{
|
||||
struct stat buf;
|
||||
int size;
|
||||
|
||||
if (stat(cfgfile, &buf) == -1) return -1;
|
||||
size = buf.st_size;
|
||||
|
||||
pref_file = fopen(cfgfile, "r");
|
||||
if (pref_file == NULL) return -1;
|
||||
|
||||
data = (char*)malloc(size);
|
||||
if (data == NULL) return -1;
|
||||
|
||||
fread(data, 1, size, pref_file);
|
||||
fclose(pref_file);
|
||||
|
||||
GetValue("Bios", Config.Bios);
|
||||
Config.Lang[0] = 0;
|
||||
GetValue("Lang", Config.Lang);
|
||||
GetValuel("Ps2Out", Config.PsxOut);
|
||||
GetValuel("cdvdPrint", Config.cdvdPrint);
|
||||
GetValue("PluginsDir", Config.PluginsDir);
|
||||
GetValue("BiosDir", Config.BiosDir);
|
||||
|
||||
GetValuel("EnabledCard1", Config.Mcd[0].Enabled);
|
||||
GetValue("Mcd1", Config.Mcd[0].Filename);
|
||||
if (strcmp(Config.Mcd[0].Filename,"") == 0) strcpy(Config.Mcd[0].Filename, MEMCARDS_DIR "/" DEFAULT_MEMCARD1);
|
||||
|
||||
GetValuel("EnabledCard2", Config.Mcd[1].Enabled);
|
||||
GetValue("Mcd2", Config.Mcd[1].Filename);
|
||||
if (strcmp(Config.Mcd[1].Filename,"") == 0) strcpy(Config.Mcd[1].Filename, MEMCARDS_DIR "/" DEFAULT_MEMCARD2);
|
||||
|
||||
GetValuel("McdEnableEject", Config.McdEnableEject);
|
||||
|
||||
GetValue("GS", Config.GS);
|
||||
GetValue("SPU2", Config.SPU2);
|
||||
GetValue("CDVD", Config.CDVD);
|
||||
GetValue("PAD1", Config.PAD1);
|
||||
GetValue("PAD2", Config.PAD2);
|
||||
GetValue("DEV9", Config.DEV9);
|
||||
GetValue("USB", Config.USB);
|
||||
GetValue("FW", Config.FW);
|
||||
|
||||
GetValuel("Patch", Config.Patch);
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
GetValuel("varLog", varLog);
|
||||
#endif
|
||||
GetValuel("Options", Config.Options);
|
||||
|
||||
GetValuel("EECycleRate", Config.Hacks.EECycleRate);
|
||||
if (Config.Hacks.EECycleRate > 2)
|
||||
Config.Hacks.EECycleRate = 2;
|
||||
GetValuel("IOPCycleDouble", Config.Hacks.IOPCycleDouble);
|
||||
GetValuel("WaitCycleExt", Config.Hacks.WaitCycleExt);
|
||||
GetValuel("INTCSTATSlow", Config.Hacks.INTCSTATSlow);
|
||||
GetValuel("VUCycleSteal", Config.Hacks.VUCycleSteal);
|
||||
GetValuel("vuFlagHack", Config.Hacks.vuFlagHack);
|
||||
GetValuel("vuMinMax", Config.Hacks.vuMinMax);
|
||||
GetValuel("IdleLoopFF", Config.Hacks.IdleLoopFF);
|
||||
GetValuel("ESCExits", Config.Hacks.ESCExits);
|
||||
|
||||
if (Config.Hacks.VUCycleSteal < 0 || Config.Hacks.VUCycleSteal > 4)
|
||||
Config.Hacks.VUCycleSteal = 0;
|
||||
GetValuel("Fixes", Config.GameFixes);
|
||||
|
||||
GetValuel("CustomFps", Config.CustomFps);
|
||||
GetValuel("CustomFrameskip", Config.CustomFrameSkip);
|
||||
GetValuel("CustomConsecutiveFrames", Config.CustomConsecutiveFrames);
|
||||
GetValuel("CustomConsecutiveSkip", Config.CustomConsecutiveSkip);
|
||||
|
||||
// Note - order is currently important.
|
||||
GetValuel("sseMXCSR", Config.sseMXCSR);
|
||||
GetValuel("sseVUMXCSR", Config.sseVUMXCSR);
|
||||
GetValuel("eeOptions", Config.eeOptions);
|
||||
GetValuel("vuOptions", Config.vuOptions);
|
||||
|
||||
free(data);
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
if (Config.Lang[0])
|
||||
{
|
||||
extern int _nl_msg_cat_cntr;
|
||||
|
||||
setenv("LANGUAGE", Config.Lang, 1);
|
||||
++_nl_msg_cat_cntr;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
void SaveConfig()
|
||||
{
|
||||
|
||||
pref_file = fopen(cfgfile, "w");
|
||||
if (pref_file == NULL) return;
|
||||
|
||||
SetValue("Bios", Config.Bios);
|
||||
SetValue("Lang", Config.Lang);
|
||||
SetValue("PluginsDir", Config.PluginsDir);
|
||||
SetValue("BiosDir", Config.BiosDir);
|
||||
SetValuel("Ps2Out", Config.PsxOut);
|
||||
SetValuel("cdvdPrint", Config.cdvdPrint);
|
||||
|
||||
SetValuel("EnabledCard1", Config.Mcd[0].Enabled);
|
||||
SetValue("Mcd1", Config.Mcd[0].Filename);
|
||||
|
||||
SetValuel("EnabledCard2", Config.Mcd[1].Enabled);
|
||||
SetValue("Mcd2", Config.Mcd[1].Filename);
|
||||
SetValuel("McdEnableEject", Config.McdEnableEject);
|
||||
|
||||
SetValue("GS", Config.GS);
|
||||
SetValue("SPU2", Config.SPU2);
|
||||
SetValue("CDVD", Config.CDVD);
|
||||
SetValue("PAD1", Config.PAD1);
|
||||
SetValue("PAD2", Config.PAD2);
|
||||
SetValue("DEV9", Config.DEV9);
|
||||
SetValue("USB", Config.USB);
|
||||
SetValue("FW", Config.FW);
|
||||
|
||||
SetValuel("Options", Config.Options);
|
||||
|
||||
SetValuel("EECycleRate", Config.Hacks.EECycleRate);
|
||||
SetValuel("IOPCycleDouble", Config.Hacks.IOPCycleDouble);
|
||||
SetValuel("WaitCycleExt", Config.Hacks.WaitCycleExt);
|
||||
SetValuel("INTCSTATSlow", Config.Hacks.INTCSTATSlow);
|
||||
SetValuel("VUCycleSteal", Config.Hacks.VUCycleSteal);
|
||||
SetValuel("IdleLoopFF", Config.Hacks.IdleLoopFF);
|
||||
SetValuel("ESCExits", Config.Hacks.ESCExits);
|
||||
|
||||
SetValuel("Fixes", Config.GameFixes);
|
||||
|
||||
SetValuel("Patch", Config.Patch);
|
||||
|
||||
SetValuel("CustomFps", Config.CustomFps);
|
||||
SetValuel("CustomFrameskip", Config.CustomFrameSkip);
|
||||
SetValuel("CustomConsecutiveFrames", Config.CustomConsecutiveFrames);
|
||||
SetValuel("CustomConsecutiveSkip", Config.CustomConsecutiveSkip);
|
||||
|
||||
SetValuel("sseMXCSR", Config.sseMXCSR);
|
||||
SetValuel("sseVUMXCSR", Config.sseVUMXCSR);
|
||||
SetValuel("eeOptions", Config.eeOptions);
|
||||
SetValuel("vuOptions", Config.vuOptions);
|
||||
|
||||
#ifdef PCSX2_DEVBUILD
|
||||
SetValuel("varLog", varLog);
|
||||
#endif
|
||||
|
||||
fclose(pref_file);
|
||||
|
||||
return;
|
||||
}
|
|
@ -1,267 +0,0 @@
|
|||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
void
|
||||
On_Dialog_Close (GtkDialog *dialog,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_Advanced_Defaults (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_Advanced_OK (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
On_Dialog_Cancelled (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_ee_slider_changed (GtkRange *range,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_vu_slider_changed (GtkRange *range,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_Speed_Hack_OK (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_Game_Fix_OK (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnMemWrite32_Ok (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnArguments_Ok (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDumpR_Ok (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDumpC_Ok (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnSetBPC_Ok (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnSetBPA_Ok (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnSetBPA_Cancel (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnSetPC_Ok (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDebug_EEMode (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDebug_IOPMode (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDebug_Step (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDebug_Skip (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDebug_Go (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDebug_Log (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDebug_SetPC (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDebug_SetBPA (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDebug_SetBPC (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDebug_ClearBPs (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDebug_DumpCode (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDebug_RawDump (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDebug_Close (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDebug_memWrite32 (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnConfButton (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnConfConf_PluginsPath (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnConfConf_BiosPath (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnConfConf_Ok (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnHelpAbout_Ok (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDestroy (GtkObject *object,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean
|
||||
OnDelete (GtkWidget *widget,
|
||||
GdkEvent *event,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnFile_RunCD (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnFile_LoadElf (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnStates_Load (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnStates_LoadOther (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnStates_Save (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnStates_SaveOther (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnFile_Exit (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnEmu_Run (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnEmu_Reset (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnConf_Conf (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnConf_Menu (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnConf_Memcards (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnConf_Cpu (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_Game_Fixes (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_Speed_Hacks (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_Advanced (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_patch_browser1_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_patch_finder2_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_enable_console1_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
on_enable_patches1_activate (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnPrintCdvdInfo (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDebug_Debugger (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnDebug_Logging (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnEmu_Arguments (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnHelp_About (GtkMenuItem *menuitem,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnCpuCheckToggled (GtkToggleButton *togglebutton,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnCpu_Ok (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnLogging_Ok (GtkButton *button,
|
||||
gpointer user_data);
|
||||
|
||||
void
|
||||
OnMemcards_Ok (GtkButton *button,
|
||||
gpointer user_data);
|
File diff suppressed because it is too large
Load Diff
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* DO NOT EDIT THIS FILE - it is generated by Glade.
|
||||
*/
|
||||
|
||||
GtkWidget* create_AdvDlg (void);
|
||||
GtkWidget* create_SpeedHacksDlg (void);
|
||||
GtkWidget* create_GameFixDlg (void);
|
||||
GtkWidget* create_MemWrite32 (void);
|
||||
GtkWidget* create_CmdLine (void);
|
||||
GtkWidget* create_DumpRDlg (void);
|
||||
GtkWidget* create_DumpCDlg (void);
|
||||
GtkWidget* create_SetBPCDlg (void);
|
||||
GtkWidget* create_SetBPADlg (void);
|
||||
GtkWidget* create_SetPCDlg (void);
|
||||
GtkWidget* create_DebugWnd (void);
|
||||
GtkWidget* create_ConfDlg (void);
|
||||
GtkWidget* create_AboutDlg (void);
|
||||
GtkWidget* create_MainWindow (void);
|
||||
GtkWidget* create_PatchBrowserWindow (void);
|
||||
GtkWidget* create_PatchFinderWindow (void);
|
||||
GtkWidget* create_CpuDlg (void);
|
||||
GtkWidget* create_Logging (void);
|
||||
GtkWidget* create_MemDlg (void);
|
|
@ -1,144 +0,0 @@
|
|||
/*
|
||||
* DO NOT EDIT THIS FILE - it is generated by Glade.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "support.h"
|
||||
|
||||
GtkWidget*
|
||||
lookup_widget (GtkWidget *widget,
|
||||
const gchar *widget_name)
|
||||
{
|
||||
GtkWidget *parent, *found_widget;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (GTK_IS_MENU (widget))
|
||||
parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
|
||||
else
|
||||
parent = widget->parent;
|
||||
if (!parent)
|
||||
parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey");
|
||||
if (parent == NULL)
|
||||
break;
|
||||
widget = parent;
|
||||
}
|
||||
|
||||
found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget),
|
||||
widget_name);
|
||||
if (!found_widget)
|
||||
g_warning ("Widget not found: %s", widget_name);
|
||||
return found_widget;
|
||||
}
|
||||
|
||||
static GList *pixmaps_directories = NULL;
|
||||
|
||||
/* Use this function to set the directory containing installed pixmaps. */
|
||||
void
|
||||
add_pixmap_directory (const gchar *directory)
|
||||
{
|
||||
pixmaps_directories = g_list_prepend (pixmaps_directories,
|
||||
g_strdup (directory));
|
||||
}
|
||||
|
||||
/* This is an internally used function to find pixmap files. */
|
||||
static gchar*
|
||||
find_pixmap_file (const gchar *filename)
|
||||
{
|
||||
GList *elem;
|
||||
|
||||
/* We step through each of the pixmaps directory to find it. */
|
||||
elem = pixmaps_directories;
|
||||
while (elem)
|
||||
{
|
||||
gchar *pathname = g_strdup_printf ("%s%s%s", (gchar*)elem->data,
|
||||
G_DIR_SEPARATOR_S, filename);
|
||||
if (g_file_test (pathname, G_FILE_TEST_EXISTS))
|
||||
return pathname;
|
||||
g_free (pathname);
|
||||
elem = elem->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This is an internally used function to create pixmaps. */
|
||||
GtkWidget*
|
||||
create_pixmap (GtkWidget *widget,
|
||||
const gchar *filename)
|
||||
{
|
||||
gchar *pathname = NULL;
|
||||
GtkWidget *pixmap;
|
||||
|
||||
if (!filename || !filename[0])
|
||||
return gtk_image_new ();
|
||||
|
||||
pathname = find_pixmap_file (filename);
|
||||
|
||||
if (!pathname)
|
||||
{
|
||||
g_warning (_("Couldn't find pixmap file: %s"), filename);
|
||||
return gtk_image_new ();
|
||||
}
|
||||
|
||||
pixmap = gtk_image_new_from_file (pathname);
|
||||
g_free (pathname);
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
/* This is an internally used function to create pixmaps. */
|
||||
GdkPixbuf*
|
||||
create_pixbuf (const gchar *filename)
|
||||
{
|
||||
gchar *pathname = NULL;
|
||||
GdkPixbuf *pixbuf;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!filename || !filename[0])
|
||||
return NULL;
|
||||
|
||||
pathname = find_pixmap_file (filename);
|
||||
|
||||
if (!pathname)
|
||||
{
|
||||
g_warning (_("Couldn't find pixmap file: %s"), filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pixbuf = gdk_pixbuf_new_from_file (pathname, &error);
|
||||
if (!pixbuf)
|
||||
{
|
||||
fprintf (stderr, "Failed to load pixbuf file: %s: %s\n",
|
||||
pathname, error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
g_free (pathname);
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
/* This is used to set ATK action descriptions. */
|
||||
void
|
||||
glade_set_atk_action_description (AtkAction *action,
|
||||
const gchar *action_name,
|
||||
const gchar *description)
|
||||
{
|
||||
gint n_actions, i;
|
||||
|
||||
n_actions = atk_action_get_n_actions (action);
|
||||
for (i = 0; i < n_actions; i++)
|
||||
{
|
||||
if (!strcmp (atk_action_get_name (action, i), action_name))
|
||||
atk_action_set_description (action, i, description);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* DO NOT EDIT THIS FILE - it is generated by Glade.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
/*
|
||||
* Standard gettext macros.
|
||||
*/
|
||||
#ifdef ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# undef _
|
||||
# define _(String) dgettext (PACKAGE, String)
|
||||
# define Q_(String) g_strip_context ((String), gettext (String))
|
||||
# ifdef gettext_noop
|
||||
# define N_(String) gettext_noop (String)
|
||||
# else
|
||||
# define N_(String) (String)
|
||||
# endif
|
||||
#else
|
||||
# define textdomain(String) (String)
|
||||
# define gettext(String) (String)
|
||||
# define dgettext(Domain,Message) (Message)
|
||||
# define dcgettext(Domain,Message,Type) (Message)
|
||||
# define bindtextdomain(Domain,Directory) (Domain)
|
||||
# define _(String) (String)
|
||||
# define Q_(String) g_strip_context ((String), (String))
|
||||
# define N_(String) (String)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Public Functions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This function returns a widget in a component created by Glade.
|
||||
* Call it with the toplevel widget in the component (i.e. a window/dialog),
|
||||
* or alternatively any widget in the component, and the name of the widget
|
||||
* you want returned.
|
||||
*/
|
||||
GtkWidget* lookup_widget (GtkWidget *widget,
|
||||
const gchar *widget_name);
|
||||
|
||||
|
||||
/* Use this function to set the directory containing installed pixmaps. */
|
||||
void add_pixmap_directory (const gchar *directory);
|
||||
|
||||
|
||||
/*
|
||||
* Private Functions.
|
||||
*/
|
||||
|
||||
/* This is used to create the pixmaps used in the interface. */
|
||||
GtkWidget* create_pixmap (GtkWidget *widget,
|
||||
const gchar *filename);
|
||||
|
||||
/* This is used to create the pixbufs used in the interface. */
|
||||
GdkPixbuf* create_pixbuf (const gchar *filename);
|
||||
|
||||
/* This is used to set ATK action descriptions. */
|
||||
void glade_set_atk_action_description (AtkAction *action,
|
||||
const gchar *action_name,
|
||||
const gchar *description);
|
||||
|
|
@ -106,6 +106,7 @@ bool IsRooted( const wxString& path )
|
|||
// ------------------------------------------------------------------------
|
||||
// Concatenates two pathnames together, inserting delimiters (backslash on win32)
|
||||
// as needed! Assumes the 'dest' is allocated to at least g_MaxPath length.
|
||||
//
|
||||
wxString Combine( const wxString& srcPath, const wxString& srcFile )
|
||||
{
|
||||
#if 0
|
||||
|
|
|
@ -88,24 +88,9 @@ public:
|
|||
// removes the lastmost directory from the path
|
||||
void RemoveLast() { wxFileName::RemoveDir(GetCount() - 1); }
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool Normalize( int flags = wxPATH_NORM_ALL, const wxString& cwd = wxEmptyString )
|
||||
{
|
||||
wxASSERT_MSG( IsDir(), L"Warning: Malformed directory name detected during wDirName normalization." );
|
||||
return wxFileName::Normalize( flags, cwd );
|
||||
}
|
||||
|
||||
bool MakeRelativeTo( const wxString& pathBase = wxEmptyString )
|
||||
{
|
||||
wxASSERT_MSG( IsDir(), L"Warning: Malformed directory name detected during wDirName normalization." );
|
||||
return wxFileName::MakeRelativeTo( pathBase );
|
||||
}
|
||||
|
||||
bool MakeAbsolute( const wxString& cwd = wxEmptyString )
|
||||
{
|
||||
wxASSERT_MSG( IsDir(), L"Warning: Malformed directory name detected during wDirName normalization." );
|
||||
return wxFileName::MakeAbsolute( cwd );
|
||||
}
|
||||
wxDirName& Normalize( int flags = wxPATH_NORM_ALL, const wxString& cwd = wxEmptyString );
|
||||
wxDirName& MakeRelativeTo( const wxString& pathBase = wxEmptyString );
|
||||
wxDirName& MakeAbsolute( const wxString& cwd = wxEmptyString );
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
|
@ -181,7 +166,7 @@ namespace PathDefs
|
|||
extern const wxDirName Snapshots;
|
||||
extern const wxDirName Savestates;
|
||||
extern const wxDirName MemoryCards;
|
||||
extern const wxDirName Configs;
|
||||
extern const wxDirName Settings;
|
||||
extern const wxDirName Plugins;
|
||||
extern const wxDirName Themes;
|
||||
|
||||
|
@ -192,7 +177,7 @@ namespace PathDefs
|
|||
extern wxDirName GetPlugins();
|
||||
extern wxDirName GetSavestates();
|
||||
extern wxDirName GetMemoryCards();
|
||||
extern wxDirName GetConfigs();
|
||||
extern wxDirName GetSettings();
|
||||
}
|
||||
|
||||
namespace FilenameDefs
|
||||
|
|
|
@ -1,7 +1,20 @@
|
|||
#ifndef PCSX2_PRECOMPILED_HEADER
|
||||
#define PCSX2_PRECOMPILED_HEADER
|
||||
|
||||
//#pragma once
|
||||
//#pragma once // no dice, causes problems in GCC PCH (which doesn't really work very well
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Define PCSX2's own i18n helpers. These override the wxWidgets helpers and provide
|
||||
// additional functionality.
|
||||
//
|
||||
#define WXINTL_NO_GETTEXT_MACRO
|
||||
#undef _
|
||||
#define _(s) pxGetTranslation(_T(s))
|
||||
|
||||
// macro provided for tagging translation strings, without actually running them through the
|
||||
// translator (which the _() does automatically, and sometimes we don't want that). This is
|
||||
// a shorthand replacement for wxTRANSLATE.
|
||||
#define wxLt(a) (a)
|
||||
|
||||
#define NOMINMAX // Disables other libs inclusion of their own min/max macros (we use std instead)
|
||||
|
||||
|
@ -38,6 +51,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <pthread.h>
|
||||
|
||||
|
||||
using std::string; // we use it enough, so bring it into the global namespace.
|
||||
using std::min;
|
||||
using std::max;
|
||||
|
@ -49,10 +63,6 @@ typedef int BOOL;
|
|||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
// macro provided for tagging translation strings, without actually running them through the
|
||||
// translator (which the _() does automatically, and sometimes we don't want that)
|
||||
#define wxLt(a) a
|
||||
|
||||
#define wxASSERT_MSG_A( cond, msg ) wxASSERT_MSG( cond, wxString::FromAscii(msg).c_str() );
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -61,6 +71,7 @@ typedef int BOOL;
|
|||
// need a full recompile anyway, when modified (etc)
|
||||
|
||||
#include "zlib/zlib.h"
|
||||
#include "i18n.h"
|
||||
#include "Pcsx2Defs.h"
|
||||
#include "Paths.h"
|
||||
#include "Config.h"
|
||||
|
|
|
@ -2048,7 +2048,7 @@ void _vuXITOP(VURegs * VU) {
|
|||
|
||||
void _vuXGKICK(VURegs * VU)
|
||||
{
|
||||
u32* ptr = (u32*)GET_VU_MEM(VU, (VU->VI[_Is_].US[0]*16) & (VU == &VU1 ? 0x3fff : 0xfff));
|
||||
// u32* ptr = (u32*)GET_VU_MEM(VU, (VU->VI[_Is_].US[0]*16) & (VU == &VU1 ? 0x3fff : 0xfff));
|
||||
// int temp = 0x4000 - ((VU->VI[_Is_].US[0]*16) & 0x3fff);
|
||||
// u32 tempmem[0x8000];
|
||||
|
||||
|
|
|
@ -464,11 +464,6 @@ static int VIFalign(u32 *data, vifCode *v, unsigned int size, const unsigned int
|
|||
|
||||
if (vif->cl != 0 || (size & 0xf)) //Check alignment for SSE unpacks
|
||||
{
|
||||
|
||||
#ifdef PCSX2_DEBUG
|
||||
static int s_count = 0;
|
||||
#endif
|
||||
|
||||
int incdest;
|
||||
|
||||
if (vifRegs->cycle.cl >= vifRegs->cycle.wl) // skipping write
|
||||
|
@ -611,10 +606,6 @@ static void VIFunpack(u32 *data, vifCode *v, unsigned int size, const unsigned i
|
|||
|
||||
if (vifRegs->cycle.cl >= vifRegs->cycle.wl) // skipping write
|
||||
{
|
||||
|
||||
#ifdef PCSX2_DEBUG
|
||||
static int s_count = 0;
|
||||
#endif
|
||||
if (v->addr >= memlimit)
|
||||
{
|
||||
//DevCon::Notice("Overflown at the start");
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "PrecompiledHeader.h"
|
||||
#include "Misc.h"
|
||||
#include "App.h"
|
||||
#include "AboutBoxDialog.h"
|
||||
#include "Dialogs/ModalPopups.h"
|
||||
#include "wxHelpers.h"
|
||||
|
||||
#include "Resources/EmbeddedImage.h"
|
||||
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include <wx/mstream.h>
|
||||
#include <wx/hyperlink.h>
|
||||
|
||||
using namespace wxHelpers;
|
||||
|
||||
namespace Dialogs {
|
||||
|
@ -97,19 +98,19 @@ AboutBoxDialog::AboutBoxDialog( wxWindow* parent, int id ):
|
|||
label_auth->Wrap( m_bitmap_logo.GetSize().GetWidth() / 2 );
|
||||
label_greets->Wrap( (m_bitmap_logo.GetSize().GetWidth() * 4) / 3 );
|
||||
|
||||
aboutUs.Add( label_auth, stdSpacingFlags );
|
||||
contribs.Add( label_greets, stdSpacingFlags.Expand() );
|
||||
aboutUs.Add( label_auth, SizerFlags::StdSpace() );
|
||||
contribs.Add( label_greets, SizerFlags::StdExpand() );
|
||||
|
||||
AuthLogoSizer.Add( &aboutUs );
|
||||
AuthLogoSizer.AddSpacer( 7 );
|
||||
AuthLogoSizer.Add( &m_bitmap_logo, wxSizerFlags().Border( wxALL, 4 ) );
|
||||
|
||||
ContribSizer.AddStretchSpacer( 1 );
|
||||
ContribSizer.Add( &m_bitmap_ps2system, stdSpacingFlags );
|
||||
ContribSizer.Add( &m_bitmap_ps2system, SizerFlags::StdSpace() );
|
||||
ContribSizer.AddStretchSpacer( 1 );
|
||||
ContribSizer.Add( &contribs, wxSizerFlags(7).HorzBorder().Expand() );
|
||||
|
||||
mainSizer.Add( &AuthLogoSizer, stdSpacingFlags );
|
||||
mainSizer.Add( &AuthLogoSizer, SizerFlags::StdSpace() );
|
||||
|
||||
mainSizer.Add( new wxHyperlinkCtrl(
|
||||
this, wxID_ANY, L"Pcsx2 Official Website and Forums" , L"http://www.pcsx2.net" ),
|
||||
|
@ -118,9 +119,9 @@ AboutBoxDialog::AboutBoxDialog( wxWindow* parent, int id ):
|
|||
this, wxID_ANY, L"Pcsx2 Official Svn Repository at Googlecode" , L"http://code.google.com/p/pcsx2" ),
|
||||
wxSizerFlags(1).Center().Border( wxALL, 3 ) );
|
||||
|
||||
mainSizer.Add( &ContribSizer, stdSpacingFlags.Expand() );
|
||||
mainSizer.Add( &ContribSizer, SizerFlags::StdExpand() );
|
||||
|
||||
mainSizer.Add( new wxButton( this, wxID_OK, L"I've seen enough"), stdCenteredFlags );
|
||||
mainSizer.Add( new wxButton( this, wxID_OK, L"I've seen enough"), SizerFlags::StdCenter() );
|
||||
SetSizerAndFit( &mainSizer );
|
||||
}
|
||||
|
||||
|
|
|
@ -70,17 +70,22 @@ protected:
|
|||
void OnResize( wxSizeEvent& evt );
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
struct AppImageIds
|
||||
{
|
||||
struct ConfigIds
|
||||
{
|
||||
int Paths,
|
||||
Plugins,
|
||||
Speedhacks,
|
||||
Gamefixes,
|
||||
Video;
|
||||
|
||||
ConfigIds() :
|
||||
Paths( -1 )
|
||||
, Plugins( -1 )
|
||||
, Speedhacks( -1 )
|
||||
, Gamefixes( -1 )
|
||||
, Video( -1 )
|
||||
|
@ -148,6 +153,8 @@ public:
|
|||
ConsoleLogFrame* GetConsoleFrame() const { return m_ConsoleFrame; }
|
||||
void SetConsoleFrame( ConsoleLogFrame& frame ) { m_ConsoleFrame = &frame; }
|
||||
|
||||
protected:
|
||||
void ReadUserModeSettings();
|
||||
bool TryOpenConfigCwd();
|
||||
};
|
||||
|
||||
|
|
|
@ -31,14 +31,14 @@
|
|||
//
|
||||
namespace PathDefs
|
||||
{
|
||||
const wxDirName Snapshots( L"snaps" );
|
||||
const wxDirName Savestates( L"sstates" );
|
||||
const wxDirName MemoryCards( L"memcards" );
|
||||
const wxDirName Configs( L"inis" );
|
||||
const wxDirName Plugins( L"plugins" );
|
||||
const wxDirName Logs( L"logs" );
|
||||
const wxDirName Dumps( L"dumps" );
|
||||
const wxDirName Themes( L"themes" );
|
||||
const wxDirName Snapshots ( L"snaps" );
|
||||
const wxDirName Savestates ( L"sstates" );
|
||||
const wxDirName MemoryCards ( L"memcards" );
|
||||
const wxDirName Settings ( L"inis" );
|
||||
const wxDirName Plugins ( L"plugins" );
|
||||
const wxDirName Logs ( L"logs" );
|
||||
const wxDirName Dumps ( L"dumps" );
|
||||
const wxDirName Themes ( L"themes" );
|
||||
|
||||
// Specifies the root folder for the application install.
|
||||
// (currently it's the CWD, but in the future I intend to move all binaries to a "bin"
|
||||
|
@ -49,18 +49,20 @@ namespace PathDefs
|
|||
// share with other programs: screenshots, memory cards, and savestates.
|
||||
wxDirName GetDocuments()
|
||||
{
|
||||
wxString wtf( wxStandardPaths::Get().GetDocumentsDir() );
|
||||
return (wxDirName)wxStandardPaths::Get().GetDocumentsDir() + (wxDirName)wxGetApp().GetAppName();
|
||||
if( g_Conf.UseAdminMode )
|
||||
return (wxDirName)wxGetCwd();
|
||||
else
|
||||
return (wxDirName)wxStandardPaths::Get().GetDocumentsDir() + (wxDirName)wxGetApp().GetAppName();
|
||||
}
|
||||
|
||||
wxDirName GetSnapshots()
|
||||
{
|
||||
return (wxDirName)GetDocuments() + Snapshots;
|
||||
return GetDocuments() + Snapshots;
|
||||
}
|
||||
|
||||
wxDirName GetBios()
|
||||
{
|
||||
return AppRoot + wxDirName( L"bios" );
|
||||
return GetDocuments() + wxDirName( L"bios" );
|
||||
}
|
||||
|
||||
wxDirName GetSavestates()
|
||||
|
@ -73,15 +75,15 @@ namespace PathDefs
|
|||
return GetDocuments() + MemoryCards;
|
||||
}
|
||||
|
||||
wxDirName GetConfigs()
|
||||
{
|
||||
return GetDocuments() + Configs;
|
||||
}
|
||||
|
||||
wxDirName GetPlugins()
|
||||
{
|
||||
return AppRoot + Plugins;
|
||||
}
|
||||
|
||||
wxDirName GetSettings()
|
||||
{
|
||||
return GetDocuments() + Settings;
|
||||
}
|
||||
|
||||
wxDirName GetThemes()
|
||||
{
|
||||
|
@ -134,6 +136,7 @@ wxFileName wxDirName::Combine( const wxFileName& right ) const
|
|||
return result;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
wxDirName wxDirName::Combine( const wxDirName& right ) const
|
||||
{
|
||||
wxASSERT_MSG( IsDir() && right.IsDir(), L"Warning: Malformed directory name detected during wDirName concatenation." );
|
||||
|
@ -143,6 +146,34 @@ wxDirName wxDirName::Combine( const wxDirName& right ) const
|
|||
return result;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
wxDirName& wxDirName::Normalize( int flags, const wxString& cwd )
|
||||
{
|
||||
wxASSERT_MSG( IsDir(), L"Warning: Malformed directory name detected during wDirName normalization." );
|
||||
if( !wxFileName::Normalize( flags, cwd ) )
|
||||
throw Exception::RuntimeError( "wxDirName::Normalize operation failed." );
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
wxDirName& wxDirName::MakeRelativeTo( const wxString& pathBase )
|
||||
{
|
||||
wxASSERT_MSG( IsDir(), L"Warning: Malformed directory name detected during wDirName normalization." );
|
||||
if( !wxFileName::MakeRelativeTo( pathBase ) )
|
||||
throw Exception::RuntimeError( "wxDirName::MakeRelativeTo operation failed." );
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
wxDirName& wxDirName::MakeAbsolute( const wxString& cwd )
|
||||
{
|
||||
wxASSERT_MSG( IsDir(), L"Warning: Malformed directory name detected during wDirName normalization." );
|
||||
if( !wxFileName::MakeAbsolute( cwd ) )
|
||||
throw Exception::RuntimeError( "wxDirName::MakeAbsolute operation failed." );
|
||||
return *this;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void wxDirName::Rmdir()
|
||||
{
|
||||
if( !Exists() ) return;
|
||||
|
@ -171,6 +202,66 @@ wxString AppConfig::FullpathHelpers::Mcd( uint mcdidx ) const { return Path::Com
|
|||
//
|
||||
#define IniEntry( varname, defval ) ini.Entry( wxT(#varname), varname, defval )
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void AppConfig::LoadSaveUserMode( IniInterface& ini )
|
||||
{
|
||||
IniEntry( UseAdminMode, false );
|
||||
ini.Entry( L"SettingsPath", Folders.Settings, PathDefs::GetSettings() );
|
||||
|
||||
ini.Flush();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
//
|
||||
void i18n_DoPackageCheck( int wxLangId, wxArrayString& destEng, wxArrayString& destTrans )
|
||||
{
|
||||
// Note: wx auto-preserves the current locale for us
|
||||
|
||||
if( !wxLocale::IsAvailable( wxLangId ) ) return;
|
||||
wxLocale* locale = new wxLocale( wxLangId, wxLOCALE_CONV_ENCODING );
|
||||
|
||||
if( locale->IsOk() && locale->AddCatalog( L"pcsx2ident" ) )
|
||||
{
|
||||
// Should be a valid language, so add it to the list.
|
||||
|
||||
destEng.Add( wxLocale::GetLanguageName( wxLangId ) );
|
||||
destTrans.Add( wxGetTranslation( L"NativeName" ) );
|
||||
}
|
||||
delete locale;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Finds all valid PCSX2 language packs, and enumerates them for configuration selection.
|
||||
// Note: On linux there's no easy way to reliably enumerate language packs, since every distro
|
||||
// could use its own location for installing pcsx2.mo files (wtcrap?). Furthermore wxWidgets
|
||||
// doesn't give us a public API for checking what the language search paths are. So the only
|
||||
// safe way to enumerate the languages is by forcibly loading every possible locale in the wx
|
||||
// database. Anything which hasn't been installed will fail to load.
|
||||
//
|
||||
// Because loading and hashing the entire pcsx2 translation for every possible language would
|
||||
// assinine and slow, I've decided to use a two-file translation system. One file is very
|
||||
// small and simply contains the name of the language in the language native. The second file
|
||||
// is loaded only if the user picks it (or if it's the default language of the OS).
|
||||
//
|
||||
void i18n_EnumeratePackages( wxArrayString& englishNames, wxArrayString& xlatedNames)
|
||||
{
|
||||
for( int li=wxLANGUAGE_ABKHAZIAN; li<wxLANGUAGE_ZULU; ++li )
|
||||
{
|
||||
i18n_DoPackageCheck( li, englishNames, xlatedNames );
|
||||
}
|
||||
|
||||
// Brilliant. Because someone in the wx world didn't think to move wxLANGUAGE_USER_DEFINED
|
||||
// to a place where it wasn't butt right up against the main languages (like, say, start user
|
||||
// defined values at 4000 or something?), they had to add new languages in at some arbitrary
|
||||
// value instead. Let's handle them here:
|
||||
// fixme: these won't show up in alphabetical order if they're actually present (however
|
||||
// horribly unlikely that is)... do we care? Probably not.
|
||||
|
||||
i18n_DoPackageCheck( wxLANGUAGE_VALENCIAN, englishNames, xlatedNames );
|
||||
i18n_DoPackageCheck( wxLANGUAGE_SAMI, englishNames, xlatedNames );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void AppConfig::LoadSave( IniInterface& ini )
|
||||
{
|
||||
IniEntry( MainGuiPosition, wxDefaultPosition );
|
||||
|
@ -185,9 +276,31 @@ void AppConfig::LoadSave( IniInterface& ini )
|
|||
ini.Flush();
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
//
|
||||
void AppConfig::Apply()
|
||||
{
|
||||
// Language Application:
|
||||
// Three stages. First we try and configure the requested language. If that fails,
|
||||
// we fall back on the default language for the user's operating system. If that
|
||||
// fails we fall back on good old english.
|
||||
|
||||
//wxLocale* locale;
|
||||
|
||||
if( !i18n_SetLanguage( LanguageId ) )
|
||||
{
|
||||
if( !i18n_SetLanguage( wxLANGUAGE_DEFAULT ) )
|
||||
{
|
||||
//wxGetTranslation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
void AppConfig::Load()
|
||||
{
|
||||
// Note: Extra parenthisis resolves "I think this is a function" issues with C++.
|
||||
// Note: Extra parenthesis resolves "I think this is a function" issues with C++.
|
||||
IniLoader loader( (IniLoader()) );
|
||||
LoadSave( loader );
|
||||
}
|
||||
|
@ -227,12 +340,12 @@ void AppConfig::FolderOptions::LoadSave( IniInterface& ini )
|
|||
const wxDirName def( L"default" );
|
||||
|
||||
IniEntry( Plugins, PathDefs::GetPlugins() );
|
||||
IniEntry( Settings, PathDefs::GetSettings() );
|
||||
IniEntry( Bios, PathDefs::GetBios() );
|
||||
IniEntry( Snapshots, PathDefs::GetSnapshots() );
|
||||
IniEntry( Savestates, PathDefs::GetSavestates() );
|
||||
IniEntry( MemoryCards, PathDefs::GetMemoryCards() );
|
||||
IniEntry( Logs, PathDefs::GetLogs() );
|
||||
IniEntry( Dumps, PathDefs::GetDumps() );
|
||||
|
||||
ini.SetPath( L".." );
|
||||
}
|
||||
|
|
|
@ -253,7 +253,8 @@ namespace Console
|
|||
if( ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame() )
|
||||
FrameHandle->Newline();
|
||||
|
||||
fputs( "\n", emuLog );
|
||||
if( emuLog != NULL )
|
||||
fputs( "\n", emuLog );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -263,7 +264,8 @@ namespace Console
|
|||
if( ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame() )
|
||||
FrameHandle->Write( fmt );
|
||||
|
||||
fputs( fmt, emuLog );
|
||||
if( emuLog != NULL )
|
||||
fputs( fmt, emuLog );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -273,7 +275,8 @@ namespace Console
|
|||
if( ConsoleLogFrame* FrameHandle = wxGetApp().GetConsoleFrame() )
|
||||
FrameHandle->Write( fmt );
|
||||
|
||||
fputs( fmt.ToAscii().data(), emuLog );
|
||||
if( emuLog != NULL )
|
||||
fputs( fmt.ToAscii().data(), emuLog );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,22 +41,22 @@ Dialogs::ConfigurationDialog::ConfigurationDialog( wxWindow* parent, int id ) :
|
|||
#endif
|
||||
|
||||
wxBoxSizer& mainSizer = *new wxBoxSizer( wxVERTICAL );
|
||||
wxListbook& Notebook = *new wxListbook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, orient );
|
||||
wxListbook& listbook = *new wxListbook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, orient );
|
||||
|
||||
Notebook.SetImageList( &wxGetApp().GetImgList_Config() );
|
||||
listbook.SetImageList( &wxGetApp().GetImgList_Config() );
|
||||
|
||||
const AppImageIds::ConfigIds& cfgid( wxGetApp().GetImgId().Config );
|
||||
|
||||
Notebook.AddPage( new PathsPanel( Notebook ), L"Paths", false, cfgid.Paths );
|
||||
//Notebook->AddPage( new PluginSelectionPanel( Notebook ), L"Plugins" );
|
||||
Notebook.AddPage( new SpeedHacksPanel( Notebook ), L"Speedhacks", true, cfgid.Speedhacks );
|
||||
Notebook.AddPage( new GameFixesPanel( Notebook ), L"Game Fixes", false, cfgid.Gamefixes );
|
||||
listbook.AddPage( new PathsPanel( listbook ), L"Paths", false, cfgid.Paths );
|
||||
listbook.AddPage( new PluginSelectorPanel( listbook ), L"Plugins", false, cfgid.Plugins );
|
||||
listbook.AddPage( new SpeedHacksPanel( listbook ), L"Speedhacks", true, cfgid.Speedhacks );
|
||||
listbook.AddPage( new GameFixesPanel( listbook ), L"Game Fixes", false, cfgid.Gamefixes );
|
||||
|
||||
mainSizer.Add( &Notebook );
|
||||
AddOkCancel( mainSizer );
|
||||
mainSizer.Add( &listbook );
|
||||
AddOkCancel( mainSizer, true );
|
||||
|
||||
SetSizerAndFit( &mainSizer );
|
||||
|
||||
Center();
|
||||
Center( wxCENTER_ON_SCREEN );
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include <wx/wx.h>
|
||||
#include <wx/image.h>
|
||||
|
||||
#include "wxHelpers.h"
|
||||
|
||||
namespace Dialogs
|
||||
{
|
||||
class AboutBoxDialog: public wxDialog
|
||||
|
@ -33,5 +35,11 @@ namespace Dialogs
|
|||
wxStaticBitmap m_bitmap_ps2system;
|
||||
|
||||
};
|
||||
|
||||
class PickUserModeDialog : public wxDialogWithHelpers
|
||||
{
|
||||
public:
|
||||
PickUserModeDialog( wxWindow* parent, int id=wxID_ANY );
|
||||
};
|
||||
}
|
||||
|
|
@ -16,22 +16,21 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __MCDSDLG_H__
|
||||
#define __MCDSDLG_H__
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
// Old school memcard manager that never got finished/working :(
|
||||
//BOOL CALLBACK ConfigureMcdsDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
#include "ModalPopups.h"
|
||||
|
||||
class MemcardConfig
|
||||
using namespace wxHelpers;
|
||||
|
||||
Dialogs::PickUserModeDialog::PickUserModeDialog( wxWindow* parent, int id ) :
|
||||
wxDialogWithHelpers( parent, id, _("PCSX2 Select User Mode"), false )
|
||||
{
|
||||
protected:
|
||||
static void Open_Mcd_Proc(HWND hW, int mcd);
|
||||
static BOOL CALLBACK DialogProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
public:
|
||||
static void OpenDialog();
|
||||
static void LoadSettings();
|
||||
};
|
||||
AddStaticText( s_main, _("PCSX2 is starting from a new or unknown working directory and needs to be configured."), 400 );
|
||||
AddStaticText( s_main, _("Current Working Directory: ") + wxGetCwd(), 480 );
|
||||
|
||||
AddOkCancel( s_main );
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -46,13 +46,13 @@ LogOptionsDialog::eeLogOptionsPanel::eeLogOptionsPanel( wxWindow* parent ) :
|
|||
|
||||
AddCheckBoxTo( this, eeMisc, L"Memory", LogID_Memory );
|
||||
AddCheckBoxTo( this, eeMisc, L"Bios", LogID_Bios );
|
||||
AddCheckBoxTo( this, eeMisc, L"Elf", LogID_ELF );
|
||||
AddCheckBoxTo( this, eeMisc, L"Elf", LogID_ELF );
|
||||
|
||||
wxBoxSizer& eeStack = *new wxBoxSizer( wxVERTICAL );
|
||||
eeStack.Add( new DisasmPanel( this ), stdSpacingFlags );
|
||||
eeStack.Add( new DisasmPanel( this ), SizerFlags::StdSpace() );
|
||||
eeStack.Add( &eeMisc );
|
||||
|
||||
ThisSizer.Add( new HwPanel( this ), stdSpacingFlags );
|
||||
ThisSizer.Add( new HwPanel( this ), SizerFlags::StdSpace() );
|
||||
ThisSizer.Add( &eeStack );
|
||||
|
||||
SetValue( true );
|
||||
|
@ -62,11 +62,11 @@ LogOptionsDialog::eeLogOptionsPanel::eeLogOptionsPanel( wxWindow* parent ) :
|
|||
LogOptionsDialog::eeLogOptionsPanel::DisasmPanel::DisasmPanel( wxWindow* parent ) :
|
||||
CheckedStaticBox( parent, wxVERTICAL, L"Disasm" , LogID_Disasm )
|
||||
{
|
||||
AddCheckBox( L"Core", LogID_CPU );
|
||||
AddCheckBox( L"Core", LogID_CPU );
|
||||
AddCheckBox( L"Fpu", LogID_FPU );
|
||||
AddCheckBox( L"VU0", LogID_VU0 );
|
||||
AddCheckBox( L"Cop0", LogID_COP0 );
|
||||
AddCheckBox( L"VU Macro",LogID_VU_Macro );
|
||||
AddCheckBox( L"Cop0", LogID_COP0 );
|
||||
AddCheckBox( L"VU Macro", LogID_VU_Macro );
|
||||
|
||||
SetValue( false );
|
||||
Fit();
|
||||
|
@ -75,7 +75,7 @@ LogOptionsDialog::eeLogOptionsPanel::DisasmPanel::DisasmPanel( wxWindow* parent
|
|||
LogOptionsDialog::eeLogOptionsPanel::HwPanel::HwPanel( wxWindow* parent ) :
|
||||
CheckedStaticBox( parent, wxVERTICAL, L"Hardware", LogID_Hardware )
|
||||
{
|
||||
AddCheckBox( L"Registers", LogID_Registers );
|
||||
AddCheckBox( L"Registers", LogID_Registers );
|
||||
AddCheckBox( L"Dma", LogID_DMA );
|
||||
AddCheckBox( L"Vif", LogID_VIF );
|
||||
AddCheckBox( L"SPR", LogID_SPR );
|
||||
|
@ -132,11 +132,11 @@ LogOptionsDialog::LogOptionsDialog(wxWindow* parent, int id, const wxPoint& pos,
|
|||
// only wanted to work right for the miscSizer and I couldn't figure out why the CheckStaticBox
|
||||
// panel wouldn't also resize to fit the window.. :( -- air
|
||||
|
||||
topSizer.Add( &eeBox, stdSpacingFlags ); //.Expand() );
|
||||
topSizer.Add( &iopSizer, stdSpacingFlags ); //.Expand() );
|
||||
topSizer.Add( &eeBox, SizerFlags::StdSpace() ); //.Expand() );
|
||||
topSizer.Add( &iopSizer, SizerFlags::StdSpace() ); //.Expand() );
|
||||
|
||||
mainsizer.Add( &topSizer ); //, wxSizerFlags().Expand() ); // topsizer has it's own padding.
|
||||
mainsizer.Add( &miscSizer, stdSpacingFlags ); //.Expand() );
|
||||
mainsizer.Add( &miscSizer, SizerFlags::StdSpace() ); //.Expand() );
|
||||
|
||||
AddOkCancel( mainsizer );
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "PrecompiledHeader.h"
|
||||
#include "MainFrame.h"
|
||||
#include "LogOptionsDialog.h"
|
||||
#include "AboutBoxDialog.h"
|
||||
#include "Dialogs/ModalPopups.h"
|
||||
|
||||
#include "Resources/EmbeddedImage.h"
|
||||
#include "Resources/AppIcon.h"
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <wx/image.h>
|
||||
#include <wx/statline.h>
|
||||
|
||||
#include "wxHelpers.h"
|
||||
|
||||
|
@ -68,8 +69,38 @@ namespace Panels
|
|||
//
|
||||
class PathsPanel: public wxPanelWithHelpers
|
||||
{
|
||||
protected:
|
||||
class MyBasePanel : public wxPanelWithHelpers
|
||||
{
|
||||
public:
|
||||
MyBasePanel(wxWindow& parent, int id=wxID_ANY);
|
||||
|
||||
protected:
|
||||
wxDirPickerCtrl& AddDirPicker( wxBoxSizer& sizer, int id, const wxDirName& defaultPath, const wxString& label, const wxString& dialogLabel, bool pathMustExist=true );
|
||||
};
|
||||
|
||||
class StandardPanel : public MyBasePanel
|
||||
{
|
||||
public:
|
||||
StandardPanel(wxWindow& parent, int id=wxID_ANY);
|
||||
};
|
||||
|
||||
class AdvancedPanel : public MyBasePanel
|
||||
{
|
||||
public:
|
||||
AdvancedPanel(wxWindow& parent, int id=wxID_ANY);
|
||||
};
|
||||
|
||||
public:
|
||||
PathsPanel(wxWindow& parent, int id=wxID_ANY);
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
class PluginSelectorPanel: public wxPanelWithHelpers
|
||||
{
|
||||
public:
|
||||
PluginSelectorPanel(wxWindow& parent, int id=wxID_ANY);
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
@ -41,8 +41,8 @@ Panels::GameFixesPanel::GameFixesPanel( wxWindow& parent, int id ) :
|
|||
AddCheckBox( groupSizer, _T("VU Add / Sub Hack - Special fix for Tri-Ace games!") );
|
||||
AddCheckBox( groupSizer, _T("VU Clip Hack - Special fix for God of War") );
|
||||
|
||||
mainSizer.Add( label_Title, stdCenteredFlags );
|
||||
mainSizer.Add( &groupSizer, stdSpacingFlags );
|
||||
mainSizer.Add( label_Title, SizerFlags::StdCenter() );
|
||||
mainSizer.Add( &groupSizer, SizerFlags::StdSpace() );
|
||||
|
||||
SetSizerAndFit( &mainSizer );
|
||||
|
||||
|
|
|
@ -17,11 +17,118 @@
|
|||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "ConfigurationPanels.h"
|
||||
|
||||
#include <wx/notebook.h>
|
||||
#include <wx/stdpaths.h>
|
||||
|
||||
using namespace wxHelpers;
|
||||
static const int BetweenFolderSpace = 5;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
wxDirPickerCtrl& Panels::PathsPanel::MyBasePanel::AddDirPicker( wxBoxSizer& sizer, int id, const wxDirName& defaultPath, const wxString& label, const wxString& dialogLabel, bool pathMustExist )
|
||||
{
|
||||
// fixme: Should wxGTK (linux) force-enable the wxDIRP_USE_TEXTCTRL? It's not "standard" on that platform
|
||||
// but it might still be preferred. - air
|
||||
|
||||
wxDirName normalized( defaultPath );
|
||||
normalized.Normalize();
|
||||
|
||||
wxDirPickerCtrl* jobe = new wxDirPickerCtrl( this, id, normalized.ToString(), dialogLabel );
|
||||
wxStaticBoxSizer& s_box = *new wxStaticBoxSizer( wxVERTICAL, this, label );
|
||||
|
||||
s_box.Add( jobe, wxSizerFlags().Border(wxLEFT | wxRIGHT | wxTOP, 5).Expand() );
|
||||
AddCheckBox( s_box, _("Use operating system default settings") );
|
||||
sizer.Add( &s_box, SizerFlags::StdGroupie() );
|
||||
return *jobe;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
Panels::PathsPanel::MyBasePanel::MyBasePanel( wxWindow& parent, int id ) :
|
||||
wxPanelWithHelpers( &parent, id )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
Panels::PathsPanel::StandardPanel::StandardPanel( wxWindow& parent, int id ) :
|
||||
MyBasePanel( parent, id )
|
||||
{
|
||||
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
AddDirPicker( s_main, wxID_ANY, g_Conf.Folders.Bios, _("Bios:"), _("Select folder with PS2 Bios") )
|
||||
.SetToolTip( pxE(Msg_Tooltips_Bios) );
|
||||
|
||||
s_main.AddSpacer( BetweenFolderSpace );
|
||||
AddDirPicker( s_main, wxID_ANY, g_Conf.Folders.Savestates, _("Savestates:"), _("Select folder for Savestates") )
|
||||
.SetToolTip( pxE(Msg_Tooltips_Savestates) );
|
||||
|
||||
s_main.AddSpacer( BetweenFolderSpace );
|
||||
AddDirPicker( s_main, wxID_ANY, g_Conf.Folders.Snapshots, _("Snapshots:"), _("Select a folder for Snapshots") )
|
||||
.SetToolTip( pxE(Msg_Tooltips_Snapshots) );
|
||||
|
||||
s_main.AddSpacer( BetweenFolderSpace );
|
||||
AddDirPicker( s_main, wxID_ANY, g_Conf.Folders.Logs, _("Log/Dumps:" ), _("Select a folder for logs/dumps") )
|
||||
.SetToolTip( pxE(Msg_Tooltips_Logs) );
|
||||
|
||||
s_main.AddSpacer( BetweenFolderSpace );
|
||||
AddDirPicker( s_main, wxID_ANY, g_Conf.Folders.MemoryCards, _("Memorycards:"), _("Select a default Memorycards folder") )
|
||||
.SetToolTip( pxE(Msg_Tooltips_Memorycards) );
|
||||
|
||||
s_main.AddSpacer( 5 );
|
||||
|
||||
SetSizerAndFit( &s_main );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
Panels::PathsPanel::AdvancedPanel::AdvancedPanel( wxWindow& parent, int id ) :
|
||||
MyBasePanel( parent, id )
|
||||
{
|
||||
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
wxStaticBoxSizer& advanced = *new wxStaticBoxSizer( wxVERTICAL, this, _("Advanced") );
|
||||
AddStaticText( advanced, pxE(Msg_Dialog_AdvancedPaths), 420, wxALIGN_CENTRE );
|
||||
|
||||
AddDirPicker( advanced, wxID_ANY, g_Conf.Folders.Plugins, _("Plugins:"), _("Select folder for PCSX2 plugins") )
|
||||
.SetToolTip( pxE(Msg_Tooltips_PluginsPath) );
|
||||
|
||||
advanced.AddSpacer( BetweenFolderSpace );
|
||||
AddDirPicker( advanced, wxID_ANY, g_Conf.Folders.Settings, _("Settings:"), _("Select a folder for PCSX2 settings/inis") )
|
||||
.SetToolTip( pxE(Msg_Tooltips_SettingsPath) );
|
||||
|
||||
wxStaticBoxSizer& s_diag = *new wxStaticBoxSizer( wxVERTICAL, this, _("Default folder mode") );
|
||||
|
||||
AddStaticText( s_diag,
|
||||
L"This setting only affects folders which are set to use the default folder configurations for your "
|
||||
L"operating system. Any folders which are configured manually will override this option. ",
|
||||
400, wxALIGN_CENTRE );
|
||||
|
||||
AddRadioButton( s_diag, _("Use to your Documents folder"), _("Location: ") + wxStandardPaths::Get().GetDocumentsDir() );
|
||||
AddRadioButton( s_diag, _("Use the current working folder"), _("Location: ") + wxGetCwd() );
|
||||
|
||||
s_diag.AddSpacer( 4 );
|
||||
|
||||
advanced.AddSpacer( 4 );
|
||||
advanced.Add( &s_diag, SizerFlags::StdGroupie() );
|
||||
|
||||
s_main.Add( &advanced, SizerFlags::StdGroupie() );
|
||||
s_main.AddSpacer( 5 );
|
||||
|
||||
SetSizerAndFit( &s_main );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
Panels::PathsPanel::PathsPanel( wxWindow& parent, int id ) :
|
||||
wxPanelWithHelpers( &parent, id )
|
||||
{
|
||||
wxBoxSizer& s_main = *new wxBoxSizer( wxVERTICAL );
|
||||
wxNotebook& notebook = *new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM | wxNB_FIXEDWIDTH );
|
||||
|
||||
notebook.AddPage( new StandardPanel( notebook ), _("Standard") );
|
||||
notebook.AddPage( new AdvancedPanel( notebook ), _("Advanced") );
|
||||
|
||||
s_main.Add( ¬ebook, SizerFlags::StdSpace() );
|
||||
|
||||
SetSizerAndFit( &s_main );
|
||||
}
|
||||
|
||||
|
|
|
@ -16,4 +16,12 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "PrecompiledHeader.h"
|
||||
|
||||
#include "ConfigurationPanels.h"
|
||||
|
||||
Panels::PluginSelectorPanel::PluginSelectorPanel( wxWindow& parent, int id ) :
|
||||
wxPanelWithHelpers( &parent, id )
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ Panels::SpeedHacksPanel::SpeedHacksPanel( wxWindow& parent, int id ) :
|
|||
wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE
|
||||
);
|
||||
|
||||
mainSizer.Add( label_Title, stdCenteredFlags );
|
||||
mainSizer.Add( label_Title, SizerFlags::StdCenter() );
|
||||
|
||||
wxSlider* vuScale = new wxSlider(this, wxID_ANY, Config.Hacks.VUCycleSteal, 0, 4 );
|
||||
wxSlider* eeScale = new wxSlider(this, wxID_ANY, Config.Hacks.EECycleRate, 0, 2);
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "PrecompiledHeader.h"
|
||||
#include "i18n.h"
|
||||
#include "HashMap.h"
|
||||
|
||||
#include "Utilities/SafeArray.h"
|
||||
|
||||
|
||||
using namespace HashTools;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Notes to Translators:
|
||||
// * The first line of each entry consists of an enumerated index (used internally), and
|
||||
// the gettext lookup string (which you'll find in the PO data). The resulting translation
|
||||
// should match the text underneath.
|
||||
//
|
||||
// * Text marked as Tooltips are usually tertiary information that is not critical to PCSX2
|
||||
// use, and translations are not required.
|
||||
//
|
||||
const EnglishExpansionEntry m_tbl_English[] =
|
||||
{
|
||||
{ Msg_Dialog_AdvancedPaths, wxLt(L"Settings Dialog:Advanced Paths"),
|
||||
L"Warning!! These advanced options are provided for developers and advanced testers only. "
|
||||
L"Changing these settings can cause program errors, so please be weary."
|
||||
},
|
||||
|
||||
{ Msg_Tooltips_SettingsPath, wxLt(L"Setting Tooltip:Settings Path"),
|
||||
L"This is the folder where PCSX2 saves all settings, including settings generated "
|
||||
L"by most plugins.\n\nWarning: Some older versions of plugins may not respect this value."
|
||||
},
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Begin Tooltips Section
|
||||
// (All following texts are non-critical for a functional PCSX2 translation).
|
||||
|
||||
{ Msg_Tooltips_PluginsPath, wxLt(L"Setting Tooltip:Plugins Path"),
|
||||
L"This is the location where PCSX2 will expect to find its plugins. Plugins found in this folder "
|
||||
L"will be enumerated and are selectable from the Plugins panel."
|
||||
},
|
||||
|
||||
{ Msg_Tooltips_Savestates, wxLt(L"Setting Tooltip:Savestates Folder"),
|
||||
L"This folder is where PCSX2 records savestates; which are recorded either by using "
|
||||
L"menus/toolbars, or by pressing F1/F3 (load/save)."
|
||||
},
|
||||
|
||||
{ Msg_Tooltips_Snapshots, wxLt(L"Setting Tooltip:Snapshots Folder"),
|
||||
L"This folder is where PCSX2 saves screenshots. Actual screenshot image format and style "
|
||||
L"may vary depending on the GS plugin being used."
|
||||
},
|
||||
|
||||
{ Msg_Tooltips_Bios, wxLt(L"Setting Tooltip:Bios Folder"),
|
||||
L"This folder is where PCSX2 looks to find PS2 bios files. The actual bios used can be "
|
||||
L"selected from the CPU dialog."
|
||||
},
|
||||
|
||||
{ Msg_Tooltips_Logs, wxLt(L"Setting Tooltip:Logs Folder"),
|
||||
L"This folder is where PCSX2 saves its logfiles and diagnostic dumps. Most plugins will "
|
||||
L"also adhere to this folder, however some older plugins may ignore it."
|
||||
},
|
||||
|
||||
{ Msg_Tooltips_Memorycards, wxLt(L"Setting Tooltip:Memorycards Folder"),
|
||||
L"This is the default path where PCSX2 loads or creates its memory cards, and can be "
|
||||
L"overridden in the MemoryCard Configuration by using absolute filenames."
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
C_ASSERT( ArraySize( m_tbl_English ) == ExpandedMsg_Count );
|
||||
|
||||
static HashMap<int,HashedExpansionPair> m_EnglishExpansions( -1, 0xcdcdcd, ArraySize( m_tbl_English ) );
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Builds an internal hashtable for English iconized description lookups.
|
||||
//
|
||||
void i18n_InitPlainEnglish()
|
||||
{
|
||||
static bool IsInitialized = false;
|
||||
|
||||
IsInitialized = true;
|
||||
for( int i=0; i<ExpandedMsg_Count; ++i )
|
||||
{
|
||||
HashedExpansionPair silly = { m_tbl_English[i].gettextKey, m_tbl_English[i].Expanded };
|
||||
m_EnglishExpansions[m_tbl_English[i].Key] = silly;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// PCSX2's Iconized Text Translator.
|
||||
// This i18n version provides two layers of translated lookups. It puts the key through the
|
||||
// current language first and, if the key is not resolved (meaning the language pack doesn't
|
||||
// have a translation for it), it's put through our own built-in english translation. This
|
||||
// second step is needed to resolve some of our lengthy UI tooltips and descriptors, which
|
||||
// use iconized GetText identifiers.
|
||||
//
|
||||
// (without this second pass many tooltips would just show up as "Savestate Tooltip" instead
|
||||
// of something meaningful).
|
||||
//
|
||||
const wxChar* __fastcall pxExpandMsg( ExpandedMsgEnum key )
|
||||
{
|
||||
const HashedExpansionPair& data( m_EnglishExpansions[key] );
|
||||
|
||||
int curlangid = wxLocale::GetLanguageInfo( g_Conf.LanguageId )->Language;
|
||||
if( curlangid == wxLANGUAGE_ENGLISH || curlangid == wxLANGUAGE_ENGLISH_US )
|
||||
return data.Expanded;
|
||||
|
||||
const wxChar* retval = wxGetTranslation( data.gettextKey );
|
||||
|
||||
// Check if the translation failed, and fall back on an english lookup.
|
||||
return ( wxStrcmp( retval, data.gettextKey ) == 0 ) ? data.Expanded : retval;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Alternative implementation for wxGetTranslation.
|
||||
// This version performs a string length check in devel builds, which issues a warning
|
||||
// if the string seems too long for gettext lookups. Longer complicated strings should
|
||||
// usually be implemented used the pxMsgExpand system instead.
|
||||
//
|
||||
const wxChar* __fastcall pxGetTranslation( const wxChar* message )
|
||||
{
|
||||
if( IsDevBuild )
|
||||
{
|
||||
if( wxStrlen( message ) > 96 )
|
||||
{
|
||||
Console::Notice( "pxGetTranslation: Long message detected, maybe use pxExpandMsg instead?" );
|
||||
Console::Status( wxsFormat( L"\tMessage: %s", message ) );
|
||||
}
|
||||
}
|
||||
return wxGetTranslation( message );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
bool i18n_SetLanguage( int wxLangId )
|
||||
{
|
||||
if( !wxLocale::IsAvailable( wxLangId ) )
|
||||
{
|
||||
Console::Notice( "Invalid Language Identifier (wxID=%d).", params wxLangId );
|
||||
return false;
|
||||
}
|
||||
|
||||
wxLocale* locale = new wxLocale( wxLangId, wxLOCALE_CONV_ENCODING );
|
||||
|
||||
if( !locale->IsOk() )
|
||||
{
|
||||
Console::Notice( wxsFormat( L"SetLanguage: '%s' [%s] is not supported by the operating system",
|
||||
wxLocale::GetLanguageName( locale->GetLanguage() ), locale->GetCanonicalName() )
|
||||
);
|
||||
|
||||
safe_delete( locale );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !locale->AddCatalog( L"pcsx2main" ) ) //, wxLANGUAGE_UNKNOWN, NULL ) )
|
||||
{
|
||||
Console::Notice( wxsFormat( L"SetLanguage: Cannot find pcsx2main.mo file for language '%s' [%s]",
|
||||
wxLocale::GetLanguageName( locale->GetLanguage() ), locale->GetCanonicalName() )
|
||||
);
|
||||
safe_delete( locale );
|
||||
}
|
||||
//return locale;
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <wx/wx.h>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
enum ExpandedMsgEnum
|
||||
{
|
||||
Msg_Dialog_AdvancedPaths,
|
||||
|
||||
Msg_Tooltips_Savestates,
|
||||
Msg_Tooltips_Snapshots,
|
||||
Msg_Tooltips_Bios,
|
||||
Msg_Tooltips_Logs,
|
||||
Msg_Tooltips_Memorycards,
|
||||
Msg_Tooltips_SettingsPath,
|
||||
Msg_Tooltips_PluginsPath,
|
||||
|
||||
ExpandedMsg_Count
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// English Tables for "Translating" iconized UI descriptions.
|
||||
//
|
||||
struct HashedExpansionPair
|
||||
{
|
||||
const wxChar* gettextKey; // send this to wxGetTranslation()
|
||||
const wxChar* Expanded;
|
||||
};
|
||||
|
||||
struct EnglishExpansionEntry
|
||||
{
|
||||
ExpandedMsgEnum Key;
|
||||
const wxChar* gettextKey; // send this to wxGetTranslation()
|
||||
const wxChar* Expanded;
|
||||
};
|
||||
|
||||
extern void i18n_InitPlainEnglish();
|
||||
extern bool i18n_SetLanguage( int wxLangId );
|
||||
|
||||
extern const wxChar* __fastcall pxExpandMsg( ExpandedMsgEnum key );
|
||||
extern const wxChar* __fastcall pxGetTranslation( const wxChar* message );
|
||||
|
||||
#define pxE(n) pxExpandMsg( n )
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
#include "PrecompiledHeader.h"
|
||||
#include "IniInterface.h"
|
||||
#include "MainFrame.h"
|
||||
#include "Dialogs/ModalPopups.h"
|
||||
|
||||
#include "Resources/EmbeddedImage.h"
|
||||
#include "Resources/BackgroundLogo.h"
|
||||
|
@ -46,11 +47,33 @@ wxFileConfig* OpenConfig( const wxString& filename )
|
|||
return new wxFileConfig( wxEmptyString, wxEmptyString, filename, wxEmptyString, wxCONFIG_USE_RELATIVE_PATH );
|
||||
}
|
||||
|
||||
void Pcsx2App::ReadUserModeSettings()
|
||||
{
|
||||
wxString configfile( Path::Combine( wxGetCwd(), L"usermode.ini" ) );
|
||||
|
||||
if( !wxFile::Exists( configfile ) )
|
||||
{
|
||||
Dialogs::PickUserModeDialog( m_MainFrame ).ShowModal();
|
||||
}
|
||||
|
||||
wxFileConfig* conf_usermode = OpenConfig( Path::Combine( wxGetCwd(), L"usermode.ini" ) );
|
||||
|
||||
// Ensure proper scoping (IniLoader gets closed prior to delete)
|
||||
{
|
||||
IniLoader loader( *conf_usermode );
|
||||
g_Conf.LoadSaveUserMode( loader );
|
||||
}
|
||||
|
||||
delete conf_usermode;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// returns true if a configuration file is present in the current working dir (cwd).
|
||||
// returns false if not (in which case the calling code should fall back on using OpenConfigUserLocal())
|
||||
//
|
||||
bool Pcsx2App::TryOpenConfigCwd()
|
||||
{
|
||||
wxDirName inipath_cwd( (wxDirName)wxGetCwd() + PathDefs::Configs );
|
||||
wxDirName inipath_cwd( (wxDirName)wxGetCwd() + PathDefs::Settings );
|
||||
if( !inipath_cwd.IsReadable() ) return false;
|
||||
|
||||
wxString inifile_cwd( Path::Combine( inipath_cwd, FilenameDefs::GetConfig() ) );
|
||||
|
@ -107,23 +130,33 @@ bool Pcsx2App::OnInit()
|
|||
|
||||
wxApp::OnInit();
|
||||
|
||||
// Ini Startup: The ini file could be in one of two locations, depending on how Pcsx2 has
|
||||
// been installed or configured. The first place we look is in our program's working
|
||||
// directory. If the ini there exist, and is *not* empty, then we'll use it. Otherwise
|
||||
// we fall back on the ini file in the user's Documents folder.
|
||||
i18n_InitPlainEnglish();
|
||||
wxLocale::AddCatalogLookupPathPrefix( wxGetCwd() );
|
||||
|
||||
// User/Admin Mode Dual Setup:
|
||||
// Pcsx2 now supports two fundamental modes of operation. The default is Classic mode,
|
||||
// which uses the Current Working Directory (CWD) for all user data files, and requires
|
||||
// Admin access on Vista (and some Linux as well). The second mode is the Vista-
|
||||
// compatible \documents folder usage. The mode is determined by the presence and
|
||||
// contents of a usermode.ini file in the CWD. If the ini file is missing, we assume
|
||||
// the user is setting up a classic install. If the ini is present, we read the value of
|
||||
// the UserMode and SettingsPath vars.
|
||||
//
|
||||
// Conveniently this dual mode setup applies equally well to most modern Linux distros.
|
||||
|
||||
if( !TryOpenConfigCwd() )
|
||||
{
|
||||
PathDefs::GetDocuments().Mkdir();
|
||||
PathDefs::GetConfigs().Mkdir();
|
||||
PathDefs::GetSettings().Mkdir();
|
||||
|
||||
// Allow wx to use our config, and enforces auto-cleanup as well
|
||||
wxString confile( Path::Combine( PathDefs::GetConfigs(), FilenameDefs::GetConfig() ) );
|
||||
wxString confile( Path::Combine( PathDefs::GetSettings(), FilenameDefs::GetConfig() ) );
|
||||
wxConfigBase::Set( OpenConfig( confile ) );
|
||||
wxConfigBase::Get()->SetRecordDefaults();
|
||||
}
|
||||
|
||||
g_Conf.Load();
|
||||
g_Conf.Apply();
|
||||
|
||||
m_MainFrame = new MainEmuFrame( NULL, wxID_ANY, wxEmptyString );
|
||||
SetTopWindow( m_MainFrame );
|
||||
|
@ -230,6 +263,7 @@ const wxBitmap& Pcsx2App::GetLogoBitmap()
|
|||
#include "Resources/ConfigIcon_Speedhacks.h"
|
||||
#include "Resources/ConfigIcon_Gamefixes.h"
|
||||
#include "Resources/ConfigIcon_Paths.h"
|
||||
#include "Resources/ConfigIcon_Plugins.h"
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
wxImageList& Pcsx2App::GetImgList_Config()
|
||||
|
@ -260,6 +294,7 @@ wxImageList& Pcsx2App::GetImgList_Config()
|
|||
}
|
||||
|
||||
FancyLoadMacro( Paths );
|
||||
FancyLoadMacro( Plugins );
|
||||
FancyLoadMacro( Gamefixes );
|
||||
FancyLoadMacro( Speedhacks );
|
||||
FancyLoadMacro( Video );
|
||||
|
|
|
@ -27,23 +27,96 @@
|
|||
|
||||
namespace wxHelpers
|
||||
{
|
||||
wxSizerFlags stdCenteredFlags( wxSizerFlags().Align( wxALIGN_CENTER ).DoubleBorder() );
|
||||
wxSizerFlags stdSpacingFlags( wxSizerFlags().Border( wxALL, 6 ) );
|
||||
wxSizerFlags stdButtonSizerFlags( wxSizerFlags().Align( wxALIGN_RIGHT ).Border() );
|
||||
wxSizerFlags CheckboxFlags( wxSizerFlags().Border( wxALL, 6 ).Expand() );
|
||||
// ------------------------------------------------------------------------
|
||||
// FlagsAccessors - Provides read-write copies of standard sizer flags for our interface.
|
||||
// These standard definitions provide a consistent and pretty interface for our GUI.
|
||||
// Without them things look compacted, misaligned, and yucky!
|
||||
//
|
||||
// Implementation Note: Accessors are all provisioned as dynamic (realtime) sizer calculations.
|
||||
// I've preferred this over cstatic const variables on the premise that spacing logic could
|
||||
// in the future become a dynamic value (currently it is affixed to 6 for most items).
|
||||
//
|
||||
namespace SizerFlags
|
||||
{
|
||||
wxSizerFlags StdSpace()
|
||||
{
|
||||
return wxSizerFlags().Border( wxALL, 6 );
|
||||
}
|
||||
|
||||
wxSizerFlags StdCenter()
|
||||
{
|
||||
return wxSizerFlags().Align( wxALIGN_CENTER ).DoubleBorder();
|
||||
}
|
||||
|
||||
wxSizerFlags StdExpand()
|
||||
{
|
||||
return StdSpace().Expand();
|
||||
}
|
||||
|
||||
wxSizerFlags StdGroupie()
|
||||
{
|
||||
// Groups look better with a slightly smaller margin than standard.
|
||||
// (basically this accounts for the group's frame)
|
||||
return wxSizerFlags().Border( wxLEFT | wxBOTTOM | wxRIGHT, 4 ).Expand();
|
||||
}
|
||||
|
||||
// This force-aligns the std button sizer to the right, where (at least) us win32 platform
|
||||
// users always expect it to be. Most likely Mac platforms expect it on the left side
|
||||
// just because it's *not* where win32 sticks it. Too bad!
|
||||
wxSizerFlags StdButton()
|
||||
{
|
||||
return wxSizerFlags().Align( wxALIGN_RIGHT ).Border();
|
||||
}
|
||||
|
||||
wxSizerFlags Checkbox()
|
||||
{
|
||||
return StdExpand();
|
||||
}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Creates a new checkbox and adds it to the specified sizer/parent combo.
|
||||
// Uses the default spacer setting for adding checkboxes.
|
||||
//
|
||||
wxCheckBox& AddCheckBoxTo( wxWindow* parent, wxBoxSizer& sizer, const wxString& label, wxWindowID id )
|
||||
{
|
||||
wxCheckBox* retval = new wxCheckBox( parent, id, label );
|
||||
sizer.Add( retval, CheckboxFlags );
|
||||
sizer.Add( retval, SizerFlags::Checkbox() );
|
||||
return *retval;
|
||||
}
|
||||
|
||||
wxStaticText& AddStaticTextTo(wxWindow* parent, wxBoxSizer& sizer, const wxString& label, int size )
|
||||
// ------------------------------------------------------------------------
|
||||
// Creates a new Radio Button and adds it to the specified sizer/parent combo.
|
||||
// The first item in a group should pass True for the isFisrt parameter.
|
||||
// Uses the default spacer setting for checkboxes.
|
||||
//
|
||||
wxRadioButton& AddRadioButtonTo( wxWindow* parent, wxBoxSizer& sizer, const wxString& label, wxWindowID id, bool isFirst )
|
||||
{
|
||||
wxStaticText *temp = new wxStaticText(parent, wxID_ANY, label);
|
||||
wxRadioButton* retval = new wxRadioButton( parent, id, label, wxDefaultPosition, wxDefaultSize, isFirst ? wxRB_GROUP : 0 );
|
||||
sizer.Add( retval, SizerFlags::Checkbox() );
|
||||
return *retval;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Creates a static text box that generally "makes sense" in a free-flowing layout. Specifically, this
|
||||
// ensures that that auto resizing is disabled, and that the sizer flags match the alignment specified
|
||||
// for the textbox.
|
||||
//
|
||||
// Parameters:
|
||||
// Size - allows forcing the control to wrap text at a specific pre-defined pixel width;
|
||||
// or specify zero to let wxWidgets layout the text as it deems appropriate (recommended)
|
||||
//
|
||||
// alignFlags - Either wxALIGN_LEFT, RIGHT, or CENTRE. All other wxStaticText flags are ignored
|
||||
// or overridden. [default is left alignment]
|
||||
//
|
||||
wxStaticText& AddStaticTextTo(wxWindow* parent, wxBoxSizer& sizer, const wxString& label, int size, int alignFlags )
|
||||
{
|
||||
// No reason to ever have AutoResize enabled, quite frankly. It just causes layout and centering problems.
|
||||
alignFlags |= wxST_NO_AUTORESIZE;
|
||||
wxStaticText *temp = new wxStaticText(parent, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, alignFlags );
|
||||
if (size > 0) temp->Wrap(size);
|
||||
sizer.Add(temp);
|
||||
|
||||
sizer.Add(temp, SizerFlags::StdSpace().Align( alignFlags & wxALIGN_MASK ) );
|
||||
return *temp;
|
||||
}
|
||||
|
||||
|
@ -107,7 +180,7 @@ wxStaticText& wxDialogWithHelpers::AddStaticText(wxBoxSizer& sizer, const wxStri
|
|||
return wxHelpers::AddStaticTextTo( this, sizer, label, size );
|
||||
}
|
||||
|
||||
void wxDialogWithHelpers::AddOkCancel( wxBoxSizer &sizer )
|
||||
void wxDialogWithHelpers::AddOkCancel( wxBoxSizer &sizer, bool hasApply )
|
||||
{
|
||||
wxBoxSizer* buttonSizer = &sizer;
|
||||
if( m_hasContextHelp )
|
||||
|
@ -124,13 +197,26 @@ void wxDialogWithHelpers::AddOkCancel( wxBoxSizer &sizer )
|
|||
sizer.Add( buttonSizer, wxSizerFlags().Center() );
|
||||
#endif
|
||||
}
|
||||
buttonSizer->Add( CreateStdDialogButtonSizer( wxOK | wxCANCEL ), wxHelpers::stdButtonSizerFlags );
|
||||
|
||||
wxStdDialogButtonSizer& s_buttons = *new wxStdDialogButtonSizer();
|
||||
|
||||
s_buttons.AddButton( new wxButton( this, wxID_OK ) );
|
||||
s_buttons.AddButton( new wxButton( this, wxID_CANCEL ) );
|
||||
|
||||
if( hasApply )
|
||||
{
|
||||
s_buttons.AddButton( new wxButton( this, wxID_APPLY ) );
|
||||
}
|
||||
|
||||
s_buttons.Realize();
|
||||
buttonSizer->Add( &s_buttons, wxHelpers::SizerFlags::StdButton() );
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
wxPanelWithHelpers::wxPanelWithHelpers( wxWindow* parent, int id, const wxPoint& pos, const wxSize& size ) :
|
||||
wxPanel( parent, id, pos, size )
|
||||
, m_StartNewRadioGroup( true )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -139,7 +225,21 @@ wxCheckBox& wxPanelWithHelpers::AddCheckBox( wxBoxSizer& sizer, const wxString&
|
|||
return wxHelpers::AddCheckBoxTo( this, sizer, label, id );
|
||||
}
|
||||
|
||||
wxStaticText& wxPanelWithHelpers::AddStaticText(wxBoxSizer& sizer, const wxString& label, int size )
|
||||
wxStaticText& wxPanelWithHelpers::AddStaticText(wxBoxSizer& sizer, const wxString& label, int size, int alignFlags )
|
||||
{
|
||||
return wxHelpers::AddStaticTextTo( this, sizer, label, size );
|
||||
return wxHelpers::AddStaticTextTo( this, sizer, label, size, alignFlags );
|
||||
}
|
||||
|
||||
wxRadioButton& wxPanelWithHelpers::AddRadioButton( wxBoxSizer& sizer, const wxString& label, const wxString& subtext, wxWindowID id )
|
||||
{
|
||||
wxRadioButton& retval = wxHelpers::AddRadioButtonTo( this, sizer, label, id, m_StartNewRadioGroup );
|
||||
m_StartNewRadioGroup = false;
|
||||
|
||||
if( !subtext.IsEmpty() )
|
||||
{
|
||||
sizer.Add( new wxStaticText( this, wxID_ANY, subtext ), wxSizerFlags().Border( wxLEFT, 25 ) );
|
||||
sizer.AddSpacer( 4 );
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
#include <wx/wx.h>
|
||||
#include <wx/filepicker.h>
|
||||
|
||||
|
||||
namespace wxHelpers
|
||||
{
|
||||
// Creates a new checkbox and adds it to the specified sizer/parent combo.
|
||||
// Uses the default spacer setting for adding checkboxes.
|
||||
extern wxCheckBox& AddCheckBoxTo( wxWindow* parent, wxBoxSizer& sizer, const wxString& label, wxWindowID id=wxID_ANY );
|
||||
extern wxStaticText& AddWrappedStaticTextTo(wxWindow* parent, wxBoxSizer& sizer, const wxString& label, int size );
|
||||
extern wxRadioButton& AddRadioButtonTo( wxWindow* parent, wxBoxSizer& sizer, const wxString& label, wxWindowID id=wxID_ANY, bool isFirst = false );
|
||||
extern wxStaticText& AddStaticTextTo(wxWindow* parent, wxBoxSizer& sizer, const wxString& label, int size=0, int alignFlags=wxALIGN_LEFT );
|
||||
|
||||
extern wxSizerFlags stdCenteredFlags;
|
||||
extern wxSizerFlags stdSpacingFlags;
|
||||
|
||||
// This force-aligns the std button sizer to the right, where (at least) us win32 platform
|
||||
// users always expect it to be. Most likely Mac platforms expect it on the left side
|
||||
// just because it's *not* where win32 sticks it. Too bad!
|
||||
extern wxSizerFlags stdButtonSizerFlags;
|
||||
|
||||
extern wxSizerFlags CheckboxFlags;
|
||||
namespace SizerFlags
|
||||
{
|
||||
extern wxSizerFlags StdSpace();
|
||||
extern wxSizerFlags StdCenter();
|
||||
extern wxSizerFlags StdExpand();
|
||||
extern wxSizerFlags StdGroupie();
|
||||
extern wxSizerFlags StdButton();
|
||||
extern wxSizerFlags Checkbox();
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -33,17 +34,26 @@ public:
|
|||
protected:
|
||||
wxCheckBox& AddCheckBox( wxBoxSizer& sizer, const wxString& label, wxWindowID id=wxID_ANY );
|
||||
wxStaticText& AddStaticText(wxBoxSizer& sizer, const wxString& label, int size=0 );
|
||||
void AddOkCancel( wxBoxSizer& sizer );
|
||||
void AddOkCancel( wxBoxSizer& sizer, bool hasApply=false );
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
class wxPanelWithHelpers : public wxPanel
|
||||
{
|
||||
protected:
|
||||
bool m_StartNewRadioGroup;
|
||||
|
||||
public:
|
||||
wxPanelWithHelpers( wxWindow* parent, int id, const wxPoint& pos=wxDefaultPosition, const wxSize& size=wxDefaultSize );
|
||||
|
||||
protected:
|
||||
wxCheckBox& AddCheckBox( wxBoxSizer& sizer, const wxString& label, wxWindowID id=wxID_ANY );
|
||||
wxStaticText& AddStaticText(wxBoxSizer& sizer, const wxString& label, int size=0 );
|
||||
wxRadioButton& AddRadioButton( wxBoxSizer& sizer, const wxString& label, const wxString& subtext=wxEmptyString, wxWindowID id=wxID_ANY );
|
||||
wxStaticText& AddStaticText(wxBoxSizer& sizer, const wxString& label, int size=0, int alignFlags=wxALIGN_LEFT );
|
||||
|
||||
void StartRadioGroup()
|
||||
{
|
||||
m_StartNewRadioGroup = true;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,566 +0,0 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "Win32.h"
|
||||
|
||||
#include <shlobj.h>
|
||||
#include "common.h"
|
||||
#include "plugins.h"
|
||||
|
||||
struct ComboInitializer
|
||||
{
|
||||
HWND hwnd;
|
||||
|
||||
HANDLE Find;
|
||||
HANDLE Lib;
|
||||
|
||||
WIN32_FIND_DATA FindData;
|
||||
|
||||
_PS2EgetLibType PS2E_GetLibType;
|
||||
_PS2EgetLibName PS2E_GetLibName;
|
||||
_PS2EgetLibVersion2 PS2E_GetLibVersion2;
|
||||
|
||||
long version;
|
||||
u32 type;
|
||||
|
||||
ComboInitializer( HWND hwndDlg ) :
|
||||
hwnd( hwndDlg )
|
||||
, Find( INVALID_HANDLE_VALUE )
|
||||
, Lib( NULL )
|
||||
, PS2E_GetLibType( NULL )
|
||||
, PS2E_GetLibName( NULL )
|
||||
, PS2E_GetLibVersion2( NULL )
|
||||
{
|
||||
Find = FindFirstFile( Path::Combine( Config.PluginsDir, "*.dll" ).c_str(), &FindData);
|
||||
}
|
||||
|
||||
~ComboInitializer()
|
||||
{
|
||||
if (Find!=INVALID_HANDLE_VALUE)
|
||||
FindClose(Find);
|
||||
}
|
||||
|
||||
bool FindNext()
|
||||
{
|
||||
return !!FindNextFile( Find, &FindData );
|
||||
}
|
||||
|
||||
bool LoadNextLibrary()
|
||||
{
|
||||
string tmpStr( Path::Combine( Config.PluginsDir, FindData.cFileName ) );
|
||||
Lib = HostSys::LoadLibrary( tmpStr.c_str() );
|
||||
if (Lib == NULL)
|
||||
{
|
||||
Console::Error( "Plugin load failure: %hs\n\tSysLibError Message: %s", params &tmpStr, SysLibError() );
|
||||
return false;
|
||||
}
|
||||
|
||||
PS2E_GetLibType = (_PS2EgetLibType) GetProcAddress((HMODULE)Lib,"PS2EgetLibType");
|
||||
PS2E_GetLibName = (_PS2EgetLibName) GetProcAddress((HMODULE)Lib,"PS2EgetLibName");
|
||||
PS2E_GetLibVersion2 = (_PS2EgetLibVersion2) GetProcAddress((HMODULE)Lib,"PS2EgetLibVersion2");
|
||||
|
||||
if( PS2E_GetLibType == NULL || PS2E_GetLibName == NULL || PS2E_GetLibVersion2 == NULL )
|
||||
return false;
|
||||
|
||||
type = PS2E_GetLibType();
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddPlugin(HWND hwndCombo, const char* str)
|
||||
{
|
||||
string tmpStr;
|
||||
int i;
|
||||
|
||||
ssprintf(tmpStr, "%s %d.%d.%d", PS2E_GetLibName(), (version>>8)&0xff, version&0xff, (version>>24)&0xff);
|
||||
char* lp = (char *)malloc(strlen(FindData.cFileName)+8);
|
||||
sprintf(lp, "%s", FindData.cFileName);
|
||||
i = ComboBox_AddString(hwndCombo, tmpStr.c_str());
|
||||
ComboBox_SetItemData(hwndCombo, i, lp);
|
||||
if (_stricmp(str, lp)==0)
|
||||
ComboBox_SetCurSel(hwndCombo, i);
|
||||
}
|
||||
|
||||
bool CheckVersion( const char* typeStr, u32 pluginType, long checkver )
|
||||
{
|
||||
if( type & pluginType )
|
||||
{
|
||||
version = PS2E_GetLibVersion2( pluginType );
|
||||
if ( ((version >> 16)&0xff) == checkver )
|
||||
return true;
|
||||
|
||||
Console::Notice("%s Plugin %s: Version %x != %x", params typeStr, FindData.cFileName, 0xff&(version >> 16), checkver);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
BOOL OnConfigureDialog(HWND hW) {
|
||||
HWND const hWC_GS=GetDlgItem(hW,IDC_LISTGS);
|
||||
HWND const hWC_PAD1=GetDlgItem(hW,IDC_LISTPAD1);
|
||||
HWND const hWC_PAD2=GetDlgItem(hW,IDC_LISTPAD2);
|
||||
HWND const hWC_SPU2=GetDlgItem(hW,IDC_LISTSPU2);
|
||||
HWND const hWC_CDVD=GetDlgItem(hW,IDC_LISTCDVD);
|
||||
HWND const hWC_DEV9=GetDlgItem(hW,IDC_LISTDEV9);
|
||||
HWND const hWC_USB=GetDlgItem(hW,IDC_LISTUSB);
|
||||
HWND const hWC_FW=GetDlgItem(hW,IDC_LISTFW);
|
||||
HWND const hWC_BIOS=GetDlgItem(hW,IDC_LISTBIOS);
|
||||
|
||||
ComboInitializer tool(hW);
|
||||
if( tool.Find == INVALID_HANDLE_VALUE ) // epic fail?
|
||||
return FALSE;
|
||||
|
||||
do
|
||||
{
|
||||
if( !tool.LoadNextLibrary() ) continue;
|
||||
|
||||
if( tool.CheckVersion( "GS", PS2E_LT_GS, PS2E_GS_VERSION ) )
|
||||
tool.AddPlugin(hWC_GS, winConfig.GS);
|
||||
|
||||
if (tool.type & PS2E_LT_PAD)
|
||||
{
|
||||
_PADquery query;
|
||||
|
||||
query = (_PADquery)GetProcAddress((HMODULE)tool.Lib, "PADquery");
|
||||
if( query != NULL )
|
||||
{
|
||||
if( tool.CheckVersion( "PAD", PS2E_LT_PAD, PS2E_PAD_VERSION ) )
|
||||
{
|
||||
if (query() & 0x1)
|
||||
tool.AddPlugin(hWC_PAD1, winConfig.PAD1);
|
||||
if (query() & 0x2)
|
||||
tool.AddPlugin(hWC_PAD2, winConfig.PAD2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( tool.CheckVersion( "SPU2", PS2E_LT_SPU2, PS2E_SPU2_VERSION ) )
|
||||
tool.AddPlugin(hWC_SPU2, winConfig.SPU2);
|
||||
|
||||
if( tool.CheckVersion( "CDVD", PS2E_LT_CDVD, PS2E_CDVD_VERSION ) )
|
||||
tool.AddPlugin(hWC_CDVD, winConfig.CDVD);
|
||||
|
||||
if( tool.CheckVersion( "DEV9", PS2E_LT_DEV9, PS2E_DEV9_VERSION ) )
|
||||
tool.AddPlugin(hWC_DEV9, winConfig.DEV9);
|
||||
|
||||
if( tool.CheckVersion( "USB", PS2E_LT_USB, PS2E_USB_VERSION ) )
|
||||
tool.AddPlugin(hWC_USB, winConfig.USB);
|
||||
|
||||
if( tool.CheckVersion( "FW", PS2E_LT_FW, PS2E_FW_VERSION ) )
|
||||
tool.AddPlugin(hWC_FW, winConfig.FW);
|
||||
|
||||
} while( tool.FindNext() );
|
||||
|
||||
// BIOS
|
||||
|
||||
/*lp=(char *)malloc(strlen("HLE") + 1);
|
||||
sprintf(lp, "HLE");
|
||||
i=ComboBox_AddString(hWC_BIOS, "Internal HLE Bios");
|
||||
ComboBox_SetItemData(hWC_BIOS, i, lp);
|
||||
if (_stricmp(Config.Bios, lp)==0)
|
||||
ComboBox_SetCurSel(hWC_BIOS, i);*/
|
||||
|
||||
HANDLE Find;
|
||||
|
||||
WIN32_FIND_DATA FindData;
|
||||
Find = FindFirstFile( Path::Combine( Config.BiosDir, "*" ).c_str(), &FindData);
|
||||
|
||||
do
|
||||
{
|
||||
char* lp;
|
||||
int i;
|
||||
|
||||
char description[50]; //2002-09-22 (Florin)
|
||||
if (Find==INVALID_HANDLE_VALUE) break;
|
||||
if (!strcmp(FindData.cFileName, ".")) continue;
|
||||
if (!strcmp(FindData.cFileName, "..")) continue;
|
||||
if (FindData.nFileSizeLow > 1024 * 4096) continue; //2002-09-22 (Florin)
|
||||
if (!IsBIOS(FindData.cFileName, description)) continue;//2002-09-22 (Florin)
|
||||
lp = (char *)malloc(strlen(FindData.cFileName)+8);
|
||||
sprintf(lp, "%s", (char *)FindData.cFileName);
|
||||
i = ComboBox_AddString(hWC_BIOS, description); //2002-09-22 (Florin) modified
|
||||
ComboBox_SetItemData(hWC_BIOS, i, lp);
|
||||
if (_stricmp(Config.Bios, FindData.cFileName)==0)
|
||||
ComboBox_SetCurSel(hWC_BIOS, i);
|
||||
} while (FindNextFile(Find,&FindData));
|
||||
|
||||
if (Find!=INVALID_HANDLE_VALUE) FindClose(Find);
|
||||
|
||||
if (ComboBox_GetCurSel(hWC_GS) == -1)
|
||||
ComboBox_SetCurSel(hWC_GS, 0);
|
||||
if (ComboBox_GetCurSel(hWC_PAD1) == -1)
|
||||
ComboBox_SetCurSel(hWC_PAD1, 0);
|
||||
if (ComboBox_GetCurSel(hWC_PAD2) == -1)
|
||||
ComboBox_SetCurSel(hWC_PAD2, 0);
|
||||
if (ComboBox_GetCurSel(hWC_SPU2) == -1)
|
||||
ComboBox_SetCurSel(hWC_SPU2, 0);
|
||||
if (ComboBox_GetCurSel(hWC_CDVD) == -1)
|
||||
ComboBox_SetCurSel(hWC_CDVD, 0);
|
||||
if (ComboBox_GetCurSel(hWC_DEV9) == -1)
|
||||
ComboBox_SetCurSel(hWC_DEV9, 0);
|
||||
if (ComboBox_GetCurSel(hWC_USB) == -1)
|
||||
ComboBox_SetCurSel(hWC_USB, 0);
|
||||
if (ComboBox_GetCurSel(hWC_FW) == -1)
|
||||
ComboBox_SetCurSel(hWC_FW, 0);
|
||||
if (ComboBox_GetCurSel(hWC_BIOS) == -1)
|
||||
ComboBox_SetCurSel(hWC_BIOS, 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define CleanCombo(item) \
|
||||
hWC = GetDlgItem(hW, item); \
|
||||
iCnt = ComboBox_GetCount(hWC); \
|
||||
for (i=0; i<iCnt; i++) { \
|
||||
lp = (char *)ComboBox_GetItemData(hWC, i); \
|
||||
if (lp) free(lp); \
|
||||
} \
|
||||
ComboBox_ResetContent(hWC);
|
||||
|
||||
void CleanUpCombos(HWND hW) {
|
||||
int i,iCnt;HWND hWC;char * lp;
|
||||
|
||||
CleanCombo(IDC_LISTGS);
|
||||
CleanCombo(IDC_LISTPAD1);
|
||||
CleanCombo(IDC_LISTPAD2);
|
||||
CleanCombo(IDC_LISTSPU2);
|
||||
CleanCombo(IDC_LISTCDVD);
|
||||
CleanCombo(IDC_LISTDEV9);
|
||||
CleanCombo(IDC_LISTUSB);
|
||||
CleanCombo(IDC_LISTFW);
|
||||
CleanCombo(IDC_LISTBIOS);
|
||||
}
|
||||
|
||||
|
||||
void OnCancel(HWND hW) {
|
||||
CleanUpCombos(hW);
|
||||
EndDialog(hW,FALSE);
|
||||
}
|
||||
|
||||
|
||||
char *GetComboSel(HWND hW, int id) {
|
||||
HWND hWC = GetDlgItem(hW,id);
|
||||
int iSel;
|
||||
iSel = ComboBox_GetCurSel(hWC);
|
||||
if (iSel<0) return NULL;
|
||||
return (char *)ComboBox_GetItemData(hWC, iSel);
|
||||
}
|
||||
|
||||
#define CheckComboSel(cfg, idc) { \
|
||||
char *str = GetComboSel(hW, idc); \
|
||||
\
|
||||
if (str != NULL) strcpy(cfg, str); \
|
||||
}
|
||||
|
||||
void OnOK(HWND hW) {
|
||||
CheckComboSel(winConfig.Bios, IDC_LISTBIOS);
|
||||
CheckComboSel(winConfig.GS, IDC_LISTGS);
|
||||
CheckComboSel(winConfig.PAD1, IDC_LISTPAD1);
|
||||
CheckComboSel(winConfig.PAD2, IDC_LISTPAD2);
|
||||
CheckComboSel(winConfig.SPU2, IDC_LISTSPU2);
|
||||
CheckComboSel(winConfig.CDVD, IDC_LISTCDVD);
|
||||
CheckComboSel(winConfig.DEV9, IDC_LISTDEV9);
|
||||
CheckComboSel(winConfig.USB, IDC_LISTUSB);
|
||||
CheckComboSel(winConfig.FW, IDC_LISTFW);
|
||||
CleanUpCombos(hW);
|
||||
|
||||
EndDialog(hW, TRUE);
|
||||
|
||||
// Apply winConfig settings:
|
||||
#define ApplyPluginPath( name ) strcpy( Config.name, winConfig.name )
|
||||
ApplyPluginPath( Bios );
|
||||
ApplyPluginPath( GS );
|
||||
ApplyPluginPath( PAD1 );
|
||||
ApplyPluginPath( PAD2 );
|
||||
ApplyPluginPath( SPU2 );
|
||||
ApplyPluginPath( CDVD );
|
||||
ApplyPluginPath( DEV9 );
|
||||
ApplyPluginPath( USB );
|
||||
ApplyPluginPath( FW );
|
||||
|
||||
SaveConfig();
|
||||
SysRestorableReset();
|
||||
ReleasePlugins();
|
||||
}
|
||||
|
||||
|
||||
static void ConfPlugin( HWND hW, int confs, const char* name )
|
||||
{
|
||||
void *drv;
|
||||
void (*conf)();
|
||||
char * pDLL = GetComboSel(hW, confs);
|
||||
|
||||
if(pDLL==NULL) return;
|
||||
|
||||
drv = SysLoadLibrary( Path::Combine( Config.PluginsDir, pDLL ).c_str() );
|
||||
if (drv == NULL) return;
|
||||
|
||||
conf = (void (*)()) SysLoadSym(drv, name);
|
||||
if (SysLibError() == NULL) conf();
|
||||
SysCloseLibrary(drv);
|
||||
}
|
||||
|
||||
void ConfigureGS(HWND hW) {
|
||||
ConfPlugin(hW, IDC_LISTGS, "GSconfigure");
|
||||
}
|
||||
|
||||
void ConfigurePAD1(HWND hW) {
|
||||
ConfPlugin(hW, IDC_LISTPAD1, "PADconfigure");
|
||||
}
|
||||
|
||||
void ConfigurePAD2(HWND hW) {
|
||||
ConfPlugin(hW, IDC_LISTPAD2, "PADconfigure");
|
||||
}
|
||||
|
||||
void ConfigureSPU2(HWND hW) {
|
||||
ConfPlugin(hW, IDC_LISTSPU2, "SPU2configure");
|
||||
}
|
||||
|
||||
void ConfigureCDVD(HWND hW) {
|
||||
ConfPlugin(hW, IDC_LISTCDVD, "CDVDconfigure");
|
||||
}
|
||||
|
||||
void ConfigureDEV9(HWND hW) {
|
||||
ConfPlugin(hW, IDC_LISTDEV9, "DEV9configure");
|
||||
}
|
||||
|
||||
void ConfigureUSB(HWND hW) {
|
||||
ConfPlugin(hW, IDC_LISTUSB, "USBconfigure");
|
||||
}
|
||||
void ConfigureFW(HWND hW) {
|
||||
ConfPlugin(hW, IDC_LISTFW, "FWconfigure");
|
||||
}
|
||||
|
||||
void AboutGS(HWND hW) {
|
||||
ConfPlugin(hW, IDC_LISTGS, "GSabout");
|
||||
}
|
||||
|
||||
void AboutPAD1(HWND hW) {
|
||||
ConfPlugin(hW, IDC_LISTPAD1, "PADabout");
|
||||
}
|
||||
|
||||
void AboutPAD2(HWND hW) {
|
||||
ConfPlugin(hW, IDC_LISTPAD2, "PADabout");
|
||||
}
|
||||
|
||||
void AboutSPU2(HWND hW) {
|
||||
ConfPlugin(hW, IDC_LISTSPU2, "SPU2about");
|
||||
}
|
||||
|
||||
void AboutCDVD(HWND hW) {
|
||||
ConfPlugin(hW, IDC_LISTCDVD, "CDVDabout");
|
||||
}
|
||||
|
||||
void AboutDEV9(HWND hW) {
|
||||
ConfPlugin(hW, IDC_LISTDEV9, "DEV9about");
|
||||
}
|
||||
|
||||
void AboutUSB(HWND hW) {
|
||||
ConfPlugin(hW, IDC_LISTUSB, "USBabout");
|
||||
}
|
||||
void AboutFW(HWND hW) {
|
||||
ConfPlugin(hW, IDC_LISTFW, "FWabout");
|
||||
}
|
||||
|
||||
static void TestPlugin( HWND hW, int confs, const char* name )
|
||||
{
|
||||
void *drv;
|
||||
int (*conf)();
|
||||
int ret = 0;
|
||||
char * pDLL = GetComboSel(hW, confs);
|
||||
|
||||
if (pDLL== NULL) return;
|
||||
|
||||
drv = SysLoadLibrary( Path::Combine( Config.PluginsDir, pDLL ).c_str() );
|
||||
if (drv == NULL) return;
|
||||
|
||||
conf = (int (*)()) SysLoadSym(drv, name);
|
||||
if (SysLibError() == NULL) ret = conf();
|
||||
SysCloseLibrary(drv);
|
||||
|
||||
if (ret == 0)
|
||||
Msgbox::Alert("Success!\nThis plugin reports that should work correctly.");
|
||||
else
|
||||
Msgbox::Alert("Test Failed.\nThis plugin may not work correctly.");
|
||||
}
|
||||
|
||||
void TestGS(HWND hW) {
|
||||
TestPlugin(hW, IDC_LISTGS, "GStest");
|
||||
}
|
||||
|
||||
void TestPAD1(HWND hW) {
|
||||
TestPlugin(hW, IDC_LISTPAD1, "PADtest");
|
||||
}
|
||||
|
||||
void TestPAD2(HWND hW) {
|
||||
TestPlugin(hW, IDC_LISTPAD2, "PADtest");
|
||||
}
|
||||
|
||||
void TestSPU2(HWND hW) {
|
||||
TestPlugin(hW, IDC_LISTSPU2, "SPU2test");
|
||||
}
|
||||
|
||||
void TestCDVD(HWND hW) {
|
||||
TestPlugin(hW, IDC_LISTCDVD, "CDVDtest");
|
||||
}
|
||||
|
||||
void TestDEV9(HWND hW) {
|
||||
TestPlugin(hW, IDC_LISTDEV9, "DEV9test");
|
||||
}
|
||||
|
||||
void TestUSB(HWND hW) {
|
||||
TestPlugin(hW, IDC_LISTUSB, "USBtest");
|
||||
}
|
||||
void TestFW(HWND hW) {
|
||||
TestPlugin(hW, IDC_LISTFW, "FWtest");
|
||||
}
|
||||
|
||||
int SelectPath(HWND hW, char *Title, char *Path) {
|
||||
LPITEMIDLIST pidl;
|
||||
BROWSEINFO bi;
|
||||
char Buffer[g_MaxPath];
|
||||
|
||||
bi.hwndOwner = hW;
|
||||
bi.pidlRoot = NULL;
|
||||
bi.pszDisplayName = Buffer;
|
||||
bi.lpszTitle = Title;
|
||||
bi.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS;
|
||||
bi.lpfn = NULL;
|
||||
bi.lParam = 0;
|
||||
if ((pidl = SHBrowseForFolder(&bi)) != NULL) {
|
||||
if (SHGetPathFromIDList(pidl, Path)) {
|
||||
int len = strlen(Path);
|
||||
|
||||
if (Path[len - 1] != '\\') { strcat(Path,"\\"); }
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void SetPluginsDir(HWND hW) {
|
||||
char Path[g_MaxPath];
|
||||
|
||||
if (SelectPath(hW, "Select Plugins Directory", Path) == -1) return;
|
||||
strcpy(Config.PluginsDir, Path);
|
||||
CleanUpCombos(hW);
|
||||
OnConfigureDialog(hW);
|
||||
}
|
||||
|
||||
void SetBiosDir(HWND hW) {
|
||||
char Path[g_MaxPath];
|
||||
|
||||
if (SelectPath(hW, "Select Bios Directory", Path) == -1) return;
|
||||
strcpy(Config.BiosDir, Path);
|
||||
CleanUpCombos(hW);
|
||||
OnConfigureDialog(hW);
|
||||
}
|
||||
|
||||
BOOL CALLBACK ConfigureDlgProc(HWND hW, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
switch(uMsg) {
|
||||
case WM_INITDIALOG:
|
||||
SetWindowText(hW, "Configuration");
|
||||
|
||||
Button_SetText(GetDlgItem(hW, IDOK), "OK");
|
||||
Button_SetText(GetDlgItem(hW, IDCANCEL), "Cancel");
|
||||
Static_SetText(GetDlgItem(hW, IDC_GRAPHICS), "Graphics");
|
||||
Static_SetText(GetDlgItem(hW, IDC_FIRSTCONTROLLER), "First Controller");
|
||||
Static_SetText(GetDlgItem(hW, IDC_SECONDCONTROLLER), "Second Controller");
|
||||
Static_SetText(GetDlgItem(hW, IDC_SOUND), "Sound");
|
||||
Static_SetText(GetDlgItem(hW, IDC_CDVDROM), "Cdvdrom");
|
||||
Static_SetText(GetDlgItem(hW, IDC_BIOS), "Bios");
|
||||
Static_SetText(GetDlgItem(hW, IDC_USB), "Usb");
|
||||
Static_SetText(GetDlgItem(hW, IDC_FW), "FireWire");
|
||||
Static_SetText(GetDlgItem(hW, IDC_DEV9), "Dev9");
|
||||
Button_SetText(GetDlgItem(hW, IDC_BIOSDIR), "Set Bios Directory");
|
||||
Button_SetText(GetDlgItem(hW, IDC_PLUGINSDIR), "Set Plugins Directory");
|
||||
Button_SetText(GetDlgItem(hW, IDC_CONFIGGS), "Configure...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_TESTGS), "Test...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_ABOUTGS), "About...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_CONFIGSPU2), "Configure...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_TESTSPU2), "Test...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_ABOUTSPU2), "About...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_CONFIGCDVD), "Configure...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_TESTCDVD), "Test...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_ABOUTCDVD), "About...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_CONFIGPAD1), "Configure...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_TESTPAD1), "Test...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_ABOUTPAD1), "About...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_CONFIGPAD2), "Configure...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_TESTPAD2), "Test...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_ABOUTPAD2), "About...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_CONFIGDEV9), "Configure...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_TESTDEV9), "Test...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_ABOUTDEV9), "About...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_CONFIGUSB), "Configure...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_TESTUSB), "Test...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_ABOUTUSB), "About...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_CONFIGFW), "Configure...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_TESTFW), "Test...");
|
||||
Button_SetText(GetDlgItem(hW, IDC_ABOUTFW), "About...");
|
||||
return OnConfigureDialog(hW);
|
||||
|
||||
case WM_COMMAND:
|
||||
switch(LOWORD(wParam)) {
|
||||
case IDC_CONFIGGS: ConfigureGS(hW); return TRUE;
|
||||
case IDC_CONFIGPAD1: ConfigurePAD1(hW); return TRUE;
|
||||
case IDC_CONFIGPAD2: ConfigurePAD2(hW); return TRUE;
|
||||
case IDC_CONFIGSPU2: ConfigureSPU2(hW); return TRUE;
|
||||
case IDC_CONFIGCDVD: ConfigureCDVD(hW); return TRUE;
|
||||
case IDC_CONFIGDEV9: ConfigureDEV9(hW); return TRUE;
|
||||
case IDC_CONFIGUSB: ConfigureUSB(hW); return TRUE;
|
||||
case IDC_CONFIGFW: ConfigureFW(hW); return TRUE;
|
||||
|
||||
case IDC_TESTGS: TestGS(hW); return TRUE;
|
||||
case IDC_TESTPAD1: TestPAD1(hW); return TRUE;
|
||||
case IDC_TESTPAD2: TestPAD2(hW); return TRUE;
|
||||
case IDC_TESTSPU2: TestSPU2(hW); return TRUE;
|
||||
case IDC_TESTCDVD: TestCDVD(hW); return TRUE;
|
||||
case IDC_TESTDEV9: TestDEV9(hW); return TRUE;
|
||||
case IDC_TESTUSB: TestUSB(hW); return TRUE;
|
||||
case IDC_TESTFW: TestFW(hW); return TRUE;
|
||||
|
||||
case IDC_ABOUTGS: AboutGS(hW); return TRUE;
|
||||
case IDC_ABOUTPAD1: AboutPAD1(hW); return TRUE;
|
||||
case IDC_ABOUTPAD2: AboutPAD2(hW); return TRUE;
|
||||
case IDC_ABOUTSPU2: AboutSPU2(hW); return TRUE;
|
||||
case IDC_ABOUTCDVD: AboutCDVD(hW); return TRUE;
|
||||
case IDC_ABOUTDEV9: AboutDEV9(hW); return TRUE;
|
||||
case IDC_ABOUTUSB: AboutUSB(hW); return TRUE;
|
||||
case IDC_ABOUTFW: AboutFW(hW); return TRUE;
|
||||
|
||||
case IDC_PLUGINSDIR: SetPluginsDir(hW); return TRUE;
|
||||
case IDC_BIOSDIR: SetBiosDir(hW); return TRUE;
|
||||
|
||||
case IDCANCEL: OnCancel(hW); return TRUE;
|
||||
case IDOK: OnOK(hW); return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL Pcsx2Configure(HWND hWnd)
|
||||
{
|
||||
return DialogBox(
|
||||
gApp.hInstance,
|
||||
MAKEINTRESOURCE(IDD_CONFIG),
|
||||
hWnd,
|
||||
(DLGPROC)ConfigureDlgProc
|
||||
);
|
||||
}
|
||||
|
|
@ -1,268 +0,0 @@
|
|||
/* Pcsx2 - Pc Ps2 Emulator
|
||||
* Copyright (C) 2002-2009 Pcsx2 Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "Win32.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "System.h"
|
||||
#include "McdsDlg.h"
|
||||
|
||||
#include "Sio.h"
|
||||
|
||||
HWND mcdDlg;
|
||||
|
||||
#define SET_CHECK(idc,value) SendMessage(GetDlgItem(hWnd,idc),BM_SETCHECK,((value)==0)?BST_UNCHECKED:BST_CHECKED,0)
|
||||
#define ENABLE_CONTROL(idc,value) EnableWindow(GetDlgItem(hWnd,idc),value)
|
||||
|
||||
#define HANDLE_CHECK(idc,hvar) case idc: (hvar) = !(hvar); SendMessage(GetDlgItem(hWnd,idc),BM_SETCHECK,(hvar)?BST_CHECKED:BST_UNCHECKED,0); break
|
||||
#define HANDLE_CHECKNB(idc,hvar) case idc: (hvar) = !(hvar); SendMessage(GetDlgItem(hWnd,idc),BM_SETCHECK,(hvar)?BST_CHECKED:BST_UNCHECKED,0)
|
||||
|
||||
void DlgItem_GetText( HWND hwnd, int dlgId, wxString& dest )
|
||||
{
|
||||
HWND dlg = GetDlgItem( hwnd, dlgId );
|
||||
int length = GetWindowTextLength( dlg );
|
||||
|
||||
if( length <= 0 )
|
||||
{
|
||||
dest.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
char* outstr = new char[length+2];
|
||||
if( outstr != NULL )
|
||||
{
|
||||
GetWindowText( dlg, outstr, length+1 );
|
||||
dest = outstr;
|
||||
safe_delete_array( outstr );
|
||||
}
|
||||
}
|
||||
|
||||
// strips path information so that absolute paths are reduced to relative paths
|
||||
// where appropriate.
|
||||
static const char* _stripPathInfo( const char* src )
|
||||
{
|
||||
const char* retval = src;
|
||||
const char* workingfold = g_WorkingFolder;
|
||||
|
||||
while( (*retval != 0) && (*workingfold != 0) && (tolower(*retval) == tolower(*workingfold)) )
|
||||
{
|
||||
retval++;
|
||||
workingfold++;
|
||||
}
|
||||
|
||||
// If a difference is found before we reach the end of our pcsx2 working folder, it
|
||||
// means we need to use the fully absolute path form the user.
|
||||
if( *workingfold != 0 ) return src;
|
||||
|
||||
while( (*retval != 0) && (*retval == '\\') ) retval++;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
void MemcardConfig::Open_Mcd_Proc(HWND hW, int mcd)
|
||||
{
|
||||
OPENFILENAME ofn;
|
||||
char szFileName[256];
|
||||
char szFileTitle[256];
|
||||
char szFilter[1024];
|
||||
char *str;
|
||||
|
||||
memzero_obj( szFileName );
|
||||
memzero_obj( szFileTitle );
|
||||
memzero_obj( szFilter );
|
||||
|
||||
strcpy(szFilter, "Ps2 Memory Card (*.ps2)");
|
||||
str = szFilter + strlen(szFilter) + 1;
|
||||
strcpy(str, "*.ps2");
|
||||
|
||||
str += strlen(str) + 1;
|
||||
strcpy(str, "All Files");
|
||||
str += strlen(str) + 1;
|
||||
strcpy(str, "*.*");
|
||||
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
ofn.hwndOwner = hW;
|
||||
ofn.lpstrFilter = szFilter;
|
||||
ofn.lpstrCustomFilter = NULL;
|
||||
ofn.nMaxCustFilter = 0;
|
||||
ofn.nFilterIndex = 1;
|
||||
ofn.lpstrFile = szFileName;
|
||||
ofn.nMaxFile = 256;
|
||||
ofn.lpstrInitialDir = MEMCARDS_DIR;
|
||||
ofn.lpstrFileTitle = szFileTitle;
|
||||
ofn.nMaxFileTitle = 256;
|
||||
ofn.lpstrTitle = NULL;
|
||||
ofn.lpstrDefExt = "PS2";
|
||||
ofn.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER;
|
||||
|
||||
if (GetOpenFileName ((LPOPENFILENAME)&ofn))
|
||||
{
|
||||
Edit_SetText(GetDlgItem(hW,mcd == 1 ? IDC_MCD_FILE1 : IDC_MCD_FILE2),
|
||||
_stripPathInfo( Path::Combine( g_WorkingFolder, szFileName ).c_str() ) );
|
||||
}
|
||||
}
|
||||
|
||||
static wxString m_Default_MemcardsDir[2] =
|
||||
{
|
||||
Path::Combine( MEMCARDS_DIR, DEFAULT_MEMCARD1 ),
|
||||
Path::Combine( MEMCARDS_DIR, DEFAULT_MEMCARD2 )
|
||||
};
|
||||
|
||||
BOOL CALLBACK MemcardConfig::DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
mcdDlg = hWnd;
|
||||
SetWindowText(hWnd, "MemoryCard Config - Pcsx2");
|
||||
|
||||
Button_SetText(GetDlgItem(hWnd, IDOK), "OK");
|
||||
Button_SetText(GetDlgItem(hWnd, IDCANCEL), "Cancel");
|
||||
|
||||
Button_SetText(GetDlgItem(hWnd, IDC_MCDSEL1), "Browse...");
|
||||
Button_SetText(GetDlgItem(hWnd, IDC_MCDSEL2), "Browse...");
|
||||
|
||||
Static_SetText(GetDlgItem(hWnd, IDC_MCD_ENABLE1), "Memory Card Slot 1");
|
||||
Static_SetText(GetDlgItem(hWnd, IDC_MCD_ENABLE2), "Memory Card Slot 2");
|
||||
|
||||
if( Config.Mcd[0].Filename[0] == 0 )
|
||||
{
|
||||
strcpy_s( Config.Mcd[0].Filename,
|
||||
Path::Combine( g_WorkingFolder, m_Default_MemcardsDir[0] ).c_str() );
|
||||
}
|
||||
|
||||
if( Config.Mcd[1].Filename[1] == 0 )
|
||||
{
|
||||
strcpy_s( Config.Mcd[1].Filename,
|
||||
Path::Combine( g_WorkingFolder, m_Default_MemcardsDir[1] ).c_str() );
|
||||
}
|
||||
|
||||
Edit_SetText( GetDlgItem(hWnd,IDC_MCD_FILE1), _stripPathInfo( Config.Mcd[0].Filename ) );
|
||||
Edit_SetText( GetDlgItem(hWnd,IDC_MCD_FILE2), _stripPathInfo( Config.Mcd[1].Filename ) );
|
||||
|
||||
SET_CHECK( IDC_MCD_ENABLE1, Config.Mcd[0].Enabled );
|
||||
SET_CHECK( IDC_MCD_ENABLE2, Config.Mcd[1].Enabled );
|
||||
|
||||
SET_CHECK( IDC_NTFS_ENABLE, Config.McdEnableNTFS );
|
||||
SET_CHECK( IDC_MCD_EJECT_ENABLE, Config.McdEnableEject );
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
{
|
||||
int wmId = LOWORD(wParam);
|
||||
int wmEvent = HIWORD(wParam);
|
||||
|
||||
switch (LOWORD(wmId))
|
||||
{
|
||||
case IDC_MCD_BROWSE1:
|
||||
Open_Mcd_Proc(hWnd, 1);
|
||||
return TRUE;
|
||||
|
||||
case IDC_MCD_BROWSE2:
|
||||
Open_Mcd_Proc(hWnd, 2);
|
||||
return TRUE;
|
||||
|
||||
case IDCANCEL:
|
||||
EndDialog(hWnd,FALSE);
|
||||
return TRUE;
|
||||
|
||||
case IDOK:
|
||||
{
|
||||
//DlgItem_GetText( hWnd, IDC_MCD_FILE1, Config.Mcd[0].Filename );
|
||||
//DlgItem_GetText( hWnd, IDC_MCD_FILE2, Config.Mcd[1].Filename );
|
||||
|
||||
wxString oldone( Config.Mcd[0].Filename ), oldtwo( Config.Mcd[1].Filename );
|
||||
|
||||
GetWindowText( GetDlgItem( hWnd, IDC_MCD_FILE1 ), Config.Mcd[0].Filename, g_MaxPath );
|
||||
GetWindowText( GetDlgItem( hWnd, IDC_MCD_FILE2 ), Config.Mcd[1].Filename, g_MaxPath );
|
||||
|
||||
// reassign text with the extra unnecessary path info stripped out.
|
||||
|
||||
_tcscpy( Config.Mcd[0].Filename, _stripPathInfo( Path::Combine( g_WorkingFolder, Config.Mcd[0].Filename ).c_str() ) );
|
||||
_tcscpy( Config.Mcd[1].Filename, _stripPathInfo( Path::Combine( g_WorkingFolder, Config.Mcd[1].Filename ).c_str() ) );
|
||||
|
||||
if( g_EmulationInProgress )
|
||||
{
|
||||
if( !Config.Mcd[0].Enabled || oldone != Config.Mcd[0].Filename )
|
||||
sioEjectCard( 0 );
|
||||
|
||||
if( !Config.Mcd[1].Enabled || oldtwo != Config.Mcd[1].Filename )
|
||||
sioEjectCard( 1 );
|
||||
}
|
||||
|
||||
IniFileSaver().MemcardSettings( Config );
|
||||
EndDialog( hWnd, TRUE );
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
HANDLE_CHECKNB( IDC_MCD_ENABLE1, Config.Mcd[0].Enabled );
|
||||
ENABLE_CONTROL( IDC_MCD_BROWSE1, Config.Mcd[0].Enabled );
|
||||
ENABLE_CONTROL( IDC_MCD_FILE1, Config.Mcd[0].Enabled );
|
||||
ENABLE_CONTROL( IDC_MCD_LABEL1, Config.Mcd[0].Enabled );
|
||||
break;
|
||||
|
||||
HANDLE_CHECKNB( IDC_MCD_ENABLE2, Config.Mcd[1].Enabled );
|
||||
ENABLE_CONTROL( IDC_MCD_BROWSE2, Config.Mcd[1].Enabled );
|
||||
ENABLE_CONTROL( IDC_MCD_FILE2, Config.Mcd[1].Enabled );
|
||||
ENABLE_CONTROL( IDC_MCD_LABEL2, Config.Mcd[1].Enabled );
|
||||
break;
|
||||
|
||||
HANDLE_CHECK( IDC_NTFS_ENABLE, Config.McdEnableNTFS );
|
||||
HANDLE_CHECK( IDC_MCD_EJECT_ENABLE, Config.McdEnableEject );
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Both loads and saves as a single unified settings function! :D
|
||||
void IniFile::MemcardSettings( PcsxConfig& conf )
|
||||
{
|
||||
SetCurrentSection( "Memorycards" );
|
||||
|
||||
Entry( "Slot1_Path", conf.Mcd[0].Filename,
|
||||
Path::Combine( g_WorkingFolder, m_Default_MemcardsDir[0] ) );
|
||||
|
||||
Entry( "Slot2_Path", conf.Mcd[1].Filename,
|
||||
Path::Combine( g_WorkingFolder, m_Default_MemcardsDir[1] ) );
|
||||
|
||||
Entry( "Slot1_Enabled", conf.Mcd[0].Enabled, true );
|
||||
Entry( "Slot2_Enabled", conf.Mcd[1].Enabled, true );
|
||||
|
||||
Entry( "EnableNTFS", conf.McdEnableNTFS, true );
|
||||
Entry( "EnableEjection", conf.McdEnableEject, true );
|
||||
}
|
||||
|
||||
// Creates the MemoryCard configuration dialog box
|
||||
void MemcardConfig::OpenDialog()
|
||||
{
|
||||
DialogBox( gApp.hInstance, MAKEINTRESOURCE(IDD_CONF_MEMCARD), gApp.hWnd, (DLGPROC)DialogProc );
|
||||
|
||||
// Re-loads old config if the user canceled.
|
||||
IniFileLoader().MemcardSettings( Config );
|
||||
}
|
|
@ -1941,6 +1941,14 @@
|
|||
RelativePath="..\..\HostGui.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\gui\i18n.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\gui\i18n.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\gui\IniInterface.cpp"
|
||||
>
|
||||
|
@ -1976,10 +1984,6 @@
|
|||
RelativePath="..\..\gui\AboutBoxDialog.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\gui\AboutBoxDialog.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\gui\AdvancedDialog.cpp"
|
||||
>
|
||||
|
@ -2004,6 +2008,14 @@
|
|||
RelativePath="..\..\gui\LogOptionsDialog.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\gui\Dialogs\ModalPopups.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\gui\Dialogs\PickUserModeDialog.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resources"
|
||||
|
@ -2185,6 +2197,38 @@
|
|||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Linux"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\Linux\LnxHostSys.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Devel|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath="..\..\Common.h"
|
||||
|
@ -2194,10 +2238,6 @@
|
|||
RelativePath="..\..\Config.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\icon1.ico"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\IopCommon.h"
|
||||
>
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="./;../../;../../x86;"../../x86/ix86-32";../libs;../../IPU"
|
||||
PreprocessorDefinitions="__i386__;ENABLE_NLS;PACKAGE=\"pcsx2\";TIXML_USE_STL"
|
||||
PreprocessorDefinitions="__i386__;TIXML_USE_STL;_SCL_SECURE_NO_WARNINGS"
|
||||
RuntimeTypeInfo="false"
|
||||
PrecompiledHeaderFile="$(IntDir)/pcsx2.pch"
|
||||
CompileAs="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib ws2_32.lib winmm.lib"
|
||||
AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib ws2_32.lib shlwapi.lib winmm.lib"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="..\;..\libs"
|
||||
GenerateDebugInformation="true"
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "System.h"
|
||||
#include "HostGui.h"
|
||||
#include "resource.h"
|
||||
#include "WinDebugResource.h"
|
||||
|
||||
#define COMPILEDATE __DATE__
|
||||
|
||||
|
|
|
@ -153,9 +153,9 @@ static void iIopDumpBlock( int startpc, u8 * ptr )
|
|||
int numused, count;
|
||||
|
||||
Console::WriteLn( "dump1 %x:%x, %x", params startpc, psxpc, psxRegs.cycle );
|
||||
Path::CreateDirectory( L"dumps" );
|
||||
g_Conf.Folders.Logs.Mkdir();
|
||||
|
||||
wxString filename( Path::Combine( g_Conf.Folders.Dumps, wxsFormat( L"psxdump%.8X.txt", startpc ) ) );
|
||||
wxString filename( Path::Combine( g_Conf.Folders.Logs, wxsFormat( L"psxdump%.8X.txt", startpc ) ) );
|
||||
AsciiFile f( filename, wxFile::write );
|
||||
|
||||
/*for ( i = startpc; i < s_nEndBlock; i += 4 ) {
|
||||
|
@ -697,6 +697,7 @@ static __forceinline u32 psxRecClearMem(u32 pc)
|
|||
|
||||
jASSUME(blockidx != -1);
|
||||
|
||||
// Variable assignment in the middle of the while statements condition?
|
||||
while (pexblock = recBlocks[blockidx - 1]) {
|
||||
if (pexblock->startpc + pexblock->size * 4 <= lowerextent)
|
||||
break;
|
||||
|
@ -705,6 +706,7 @@ static __forceinline u32 psxRecClearMem(u32 pc)
|
|||
blockidx--;
|
||||
}
|
||||
|
||||
// Same here.
|
||||
while (pexblock = recBlocks[blockidx]) {
|
||||
if (pexblock->startpc >= upperextent)
|
||||
break;
|
||||
|
@ -813,6 +815,7 @@ static void iPsxBranchTest(u32 newpc, u32 cpuBranch)
|
|||
x86SetJ8( j8Ptr[0] );
|
||||
}
|
||||
|
||||
#if 0
|
||||
//static const int *s_pCode;
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
|
@ -828,6 +831,7 @@ static void checkcodefn()
|
|||
Console::WriteLn("iop code changed! %x", params pctemp);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void rpsxSYSCALL()
|
||||
{
|
||||
|
@ -873,7 +877,7 @@ void psxRecompileNextInstruction(int delayslot)
|
|||
static u8 s_bFlushReg = 1;
|
||||
|
||||
// pblock isn't used elsewhere in this function.
|
||||
BASEBLOCK* pblock = PSX_GETBLOCK(psxpc);
|
||||
//BASEBLOCK* pblock = PSX_GETBLOCK(psxpc);
|
||||
|
||||
if( IsDebugBuild )
|
||||
MOV32ItoR(EAX, psxpc);
|
||||
|
|
|
@ -783,7 +783,6 @@ void recDIVU1_constt(int info)
|
|||
|
||||
EERECOMPILE_CODE0(DIVU1, XMMINFO_READS|XMMINFO_READT);
|
||||
|
||||
|
||||
void recMADD()
|
||||
{
|
||||
EEINST_SETSIGNEXT(_Rs_);
|
||||
|
@ -816,7 +815,7 @@ void recMADD()
|
|||
MOV32RtoM( (int)&cpuRegs.HI.UL[1], EDX );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
_deleteEEreg(XMMGPR_LO, 1);
|
||||
_deleteEEreg(XMMGPR_HI, 1);
|
||||
_deleteGPRtoXMMreg(_Rs_, 1);
|
||||
|
@ -826,15 +825,15 @@ void recMADD()
|
|||
|
||||
if( GPR_IS_CONST1(_Rs_) ) {
|
||||
MOV32ItoR( EAX, g_cpuConstRegs[_Rs_].UL[0] );
|
||||
MUL32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
|
||||
IMUL32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
|
||||
}
|
||||
else if ( GPR_IS_CONST1(_Rt_) ) {
|
||||
MOV32ItoR( EAX, g_cpuConstRegs[_Rt_].UL[0] );
|
||||
MUL32M( (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
||||
IMUL32M( (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
||||
}
|
||||
else {
|
||||
MOV32MtoR( EAX, (int)&cpuRegs.GPR.r[ _Rs_ ].UL[ 0 ] );
|
||||
MUL32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
|
||||
IMUL32M( (int)&cpuRegs.GPR.r[ _Rt_ ].UL[ 0 ] );
|
||||
}
|
||||
|
||||
MOV32RtoR( ECX, EDX );
|
||||
|
|
|
@ -40,15 +40,16 @@ microVUt(void) mVUinit(VURegs* vuRegsPtr, int vuIndex) {
|
|||
microVU* mVU = mVUx;
|
||||
memset(&mVU->prog, 0, sizeof(mVU->prog));
|
||||
|
||||
mVU->regs = vuRegsPtr;
|
||||
mVU->index = vuIndex;
|
||||
mVU->vuMemSize = (vuIndex ? 0x4000 : 0x1000);
|
||||
mVU->microMemSize = (vuIndex ? 0x4000 : 0x1000);
|
||||
mVU->progSize = (vuIndex ? 0x4000 : 0x1000) / 4;
|
||||
mVU->cache = NULL;
|
||||
mVU->cacheSize = mVUcacheSize;
|
||||
mVU->prog.max = mMaxProg - 1;
|
||||
mVU->prog.prog = (microProgram*)_aligned_malloc(sizeof(microProgram)*(mVU->prog.max+1), 64);
|
||||
mVU->regs = vuRegsPtr;
|
||||
mVU->index = vuIndex;
|
||||
mVU->vuMemSize = (vuIndex ? 0x4000 : 0x1000);
|
||||
mVU->microMemSize = (vuIndex ? 0x4000 : 0x1000);
|
||||
mVU->progSize = (vuIndex ? 0x4000 : 0x1000) / 4;
|
||||
mVU->cache = NULL;
|
||||
mVU->cacheSize = mVUcacheSize;
|
||||
mVU->prog.max = mMaxProg - 1;
|
||||
mVU->prog.prog = (microProgram*)_aligned_malloc(sizeof(microProgram)*(mVU->prog.max+1), 64);
|
||||
mVU->prog.progList = new int[mMaxProg];
|
||||
mVUprint((vuIndex) ? "microVU1: init" : "microVU0: init");
|
||||
|
||||
mVU->cache = SysMmapEx((vuIndex ? 0x5f240000 : 0x5e240000), mVU->cacheSize + 0x1000, 0, (vuIndex ? "Micro VU1" : "Micro VU0"));
|
||||
|
@ -69,18 +70,18 @@ microVUt(void) mVUinit(VURegs* vuRegsPtr, int vuIndex) {
|
|||
microVUt(void) mVUreset(mV) {
|
||||
|
||||
mVUprint((mVU->index) ? "microVU1: reset" : "microVU0: reset");
|
||||
mVUclose(mVU, 1);
|
||||
|
||||
// Clear All Program Data
|
||||
//memset(&mVU->prog, 0, sizeof(mVU->prog));
|
||||
memset(&mVU->prog.lpState, 0, sizeof(mVU->prog.lpState));
|
||||
|
||||
// Program Variables
|
||||
mVU->prog.cleared = 1;
|
||||
mVU->prog.isSame = -1;
|
||||
mVU->prog.cur = -1;
|
||||
mVU->prog.total = -1;
|
||||
mVU->prog.max = mMaxProg - 1;
|
||||
mVU->prog.cleared = 1;
|
||||
mVU->prog.isSame = -1;
|
||||
mVU->prog.cur = -1;
|
||||
mVU->prog.total = -1;
|
||||
mVU->prog.curFrame = 0;
|
||||
mVU->prog.max = mMaxProg - 1;
|
||||
|
||||
// Setup Dynarec Cache Limits for Each Program
|
||||
u8* z = (mVU->cache + 0x1000); // Dispatcher Code is in first page of cache
|
||||
|
@ -89,20 +90,18 @@ microVUt(void) mVUreset(mV) {
|
|||
mVU->prog.x86end = (u8*)((uptr)z + (uptr)(mVU->cacheSize - (mVU->cacheSize*.05)));
|
||||
|
||||
for (int i = 0; i <= mVU->prog.max; i++) {
|
||||
for (int j = 0; j <= mVU->prog.prog[i].ranges.max; j++) {
|
||||
mVU->prog.prog[i].ranges.range[j][0] = -1; // Set range to
|
||||
mVU->prog.prog[i].ranges.range[j][1] = -1; // indeterminable status
|
||||
mVU->prog.prog[i].ranges.total = -1;
|
||||
}
|
||||
if (!mVU->index) mVUclearProg<0>(i);
|
||||
else mVUclearProg<1>(i);
|
||||
mVU->prog.progList[i] = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Free Allocated Resources
|
||||
microVUt(void) mVUclose(mV, bool isReset) {
|
||||
microVUt(void) mVUclose(mV) {
|
||||
|
||||
mVUprint((mVU->index) ? "microVU1: close" : "microVU0: close");
|
||||
|
||||
if (!isReset && mVU->cache) { HostSys::Munmap(mVU->cache, mVU->cacheSize); mVU->cache = NULL; }
|
||||
if (mVU->cache) { HostSys::Munmap(mVU->cache, mVU->cacheSize); mVU->cache = NULL; }
|
||||
|
||||
// Delete Programs and Block Managers
|
||||
if (mVU->prog.prog) {
|
||||
|
@ -111,8 +110,9 @@ microVUt(void) mVUclose(mV, bool isReset) {
|
|||
microBlockManager::Delete(mVU->prog.prog[i].block[j]);
|
||||
}
|
||||
}
|
||||
if (!isReset) safe_aligned_free(mVU->prog.prog);
|
||||
safe_aligned_free(mVU->prog.prog);
|
||||
}
|
||||
safe_delete_array(mVU->prog.progList);
|
||||
}
|
||||
|
||||
// Clears Block Data in specified range
|
||||
|
@ -127,18 +127,18 @@ microVUt(void) mVUclear(mV, u32 addr, u32 size) {
|
|||
// Micro VU - Private Functions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
// Clears program data (Sets used to 1 because calling this function implies the program will be used at least once)
|
||||
// Clears program data
|
||||
microVUf(void) mVUclearProg(int progIndex) {
|
||||
microVU* mVU = mVUx;
|
||||
mVUprogI.used = 1;
|
||||
mVUprogI.last_used = 3;
|
||||
mVUprogI.used = 0;
|
||||
mVUprogI.isDead = 1;
|
||||
mVUprogI.frame = mVU->prog.curFrame;
|
||||
for (int j = 0; j <= mVUprogI.ranges.max; j++) {
|
||||
mVUprogI.ranges.range[j][0] = -1; // Set range to
|
||||
mVUprogI.ranges.range[j][1] = -1; // indeterminable status
|
||||
mVUprogI.ranges.total = -1;
|
||||
}
|
||||
for (u32 i = 0; i < (mVU->progSize / 2); i++) {
|
||||
//if (mVUprogI.block[i]) { mVUprogI.block[i]->reset(); }
|
||||
microBlockManager::Delete(mVUprogI.block[i]);
|
||||
}
|
||||
}
|
||||
|
@ -150,85 +150,66 @@ microVUf(void) mVUcacheProg(int progIndex) {
|
|||
mVUdumpProg(progIndex);
|
||||
}
|
||||
|
||||
#define aWrap(x, nMax) ((x > nMax) ? 0 : x)
|
||||
// Sorts the program list (Moves progIndex to Beginning of ProgList)
|
||||
microVUt(void) mVUsortProg(mV, int progIndex) {
|
||||
int* temp = new int[mVU->prog.max+1];
|
||||
int offset = 0;
|
||||
for (int i = 0; i <= (mVU->prog.max-1); i++) {
|
||||
if (progIndex == mVU->prog.progList[i]) offset = 1;
|
||||
temp[i+1] = mVU->prog.progList[i+offset];
|
||||
}
|
||||
temp[0] = progIndex;
|
||||
delete[] mVU->prog.progList;
|
||||
mVU->prog.progList = temp;
|
||||
}
|
||||
|
||||
// Finds the least used program, (if program list full clears and returns an old program; if not-full, returns free program)
|
||||
microVUf(int) mVUfindLeastUsedProg() {
|
||||
microVU* mVU = mVUx;
|
||||
if (mVU->prog.total < mVU->prog.max) {
|
||||
mVU->prog.total++;
|
||||
mVUcacheProg<vuIndex>(mVU->prog.total); // Cache Micro Program
|
||||
mVU->prog.prog[mVU->prog.total].used = 1;
|
||||
mVU->prog.prog[mVU->prog.total].last_used = 3;
|
||||
Console::Notice("microVU%d: Cached MicroPrograms = %d", params vuIndex, mVU->prog.total+1);
|
||||
return mVU->prog.total;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
const int pMax = mVU->prog.max;
|
||||
int smallidx = aWrap((mVU->prog.cur+1), pMax);
|
||||
u64 smallval = mVU->prog.prog[smallidx].used;
|
||||
|
||||
for (int i = 1, j = aWrap((smallidx+1), pMax); i <= pMax; i++, aWrap((j+1), pMax)) {
|
||||
if (smallval > mVU->prog.prog[j].used) {
|
||||
smallval = mVU->prog.prog[j].used;
|
||||
smallidx = j;
|
||||
}
|
||||
}
|
||||
//smallidx = rand() % 200;
|
||||
mVUclearProg<vuIndex>(smallidx); // Clear old data if overwriting old program
|
||||
mVUcacheProg<vuIndex>(smallidx); // Cache Micro Program
|
||||
//Console::Notice("microVU%d: Overwriting existing program in slot %d [%d times used]", params vuIndex, smallidx, smallval);
|
||||
|
||||
return smallidx;
|
||||
*/
|
||||
|
||||
/*
|
||||
static int smallidx = 0;
|
||||
const int pMax = mVU->prog.max;
|
||||
smallidx = aWrap((smallidx+1), pMax);
|
||||
mVUclearProg<vuIndex>(smallidx); // Clear old data if overwriting old program
|
||||
mVUcacheProg<vuIndex>(smallidx); // Cache Micro Program
|
||||
//Console::Notice("microVU%d: Overwriting existing program in slot %d [%d times used]", params vuIndex, smallidx, smallval);
|
||||
return smallidx;
|
||||
*/
|
||||
|
||||
//mVUreset(mVU);
|
||||
mVU->prog.x86ptr = mVU->prog.x86start;
|
||||
for (int z = 0; z <= mVU->prog.max; z++) {
|
||||
mVUclearProg<vuIndex>(z);
|
||||
mVU->prog.prog[z].used = 0;
|
||||
mVU->prog.prog[z].last_used = 0;
|
||||
}
|
||||
mVU->prog.total = 0;
|
||||
mVUcacheProg<vuIndex>(mVU->prog.total); // Cache Micro Program
|
||||
mVU->prog.prog[mVU->prog.total].used = 1;
|
||||
mVU->prog.prog[mVU->prog.total].last_used = 3;
|
||||
Console::Notice("microVU%d: Cached MicroPrograms = %d", params vuIndex, mVU->prog.total+1);
|
||||
return mVU->prog.total;
|
||||
}
|
||||
}
|
||||
|
||||
// mVUvsyncUpdate -->
|
||||
// This should be run at 30fps intervals from Counters.cpp (or 60fps works too, but 30fps is
|
||||
// probably all we need for accurate results)
|
||||
//
|
||||
// To fix the program cache to more efficiently dispose of "obsolete" programs, we need to use a
|
||||
// frame-based decrementing system in combination with a program-execution-based incrementing
|
||||
// system. In English: if last_used >= 2 it means the program has been used for the current
|
||||
// or prev frame. if it's 0, the program hasn't been used for a while.
|
||||
microVUt(void) mVUvsyncUpdate(mV) {
|
||||
|
||||
if (mVU->prog.total < mVU->prog.max) return;
|
||||
|
||||
for (int i = 0; i <= mVU->prog.max; i++) {
|
||||
if (mVU->prog.prog[i].last_used != 0) {
|
||||
if (mVU->prog.prog[i].last_used >= 3) {
|
||||
mVU->prog.prog[i].used += 0x200; // give 'weighted' bonus
|
||||
}
|
||||
mVU->prog.prog[i].last_used--;
|
||||
if (mVU->prog.prog[i].isDead) {
|
||||
mVU->prog.total++;
|
||||
mVUcacheProg<vuIndex>(i); // Cache Micro Program
|
||||
mVU->prog.prog[i].isDead = 0;
|
||||
mVU->prog.prog[i].used = 1;
|
||||
mVUsortProg(mVU, i);
|
||||
Console::Notice("microVU%d: Cached MicroPrograms = [%03d] [%03d]", params vuIndex, i+1, mVU->prog.total+1);
|
||||
return i;
|
||||
}
|
||||
else mVU->prog.prog[i].used /= 2; // penalize unused programs.
|
||||
}
|
||||
|
||||
static int clearIdx = 0;
|
||||
int pIdx = clearIdx;
|
||||
for (int i = 0; i < ((mVU->prog.max+1)/4); i++) {
|
||||
mVUclearProg<vuIndex>(clearIdx);
|
||||
clearIdx = aWrap(clearIdx+1, mVU->prog.max);
|
||||
}
|
||||
mVU->prog.total -= ((mVU->prog.max+1)/4)-1;
|
||||
mVUcacheProg<vuIndex>(pIdx); // Cache Micro Program
|
||||
mVU->prog.prog[pIdx].isDead = 0;
|
||||
mVU->prog.prog[pIdx].used = 1;
|
||||
mVUsortProg(mVU, pIdx);
|
||||
Console::Notice("microVU%d: Cached MicroPrograms = [%03d] [%03d]", params vuIndex, pIdx+1, mVU->prog.total+1);
|
||||
return pIdx;
|
||||
}
|
||||
|
||||
// Finds and Kills Programs if they haven't been used in a while.
|
||||
microVUt(void) mVUvsyncUpdate(mV) {
|
||||
for (int i = 0; i <= mVU->prog.max; i++) {
|
||||
if (mVU->prog.prog[i].isDead) continue;
|
||||
if (mVU->prog.prog[i].used) {
|
||||
mVU->prog.prog[i].used = 0;
|
||||
mVU->prog.prog[i].frame = mVU->prog.curFrame;
|
||||
}
|
||||
if((mVU->prog.curFrame - mVU->prog.prog[i].frame) >= (60 * 7)) {
|
||||
mVU->prog.total--;
|
||||
if (!mVU->index) mVUclearProg<0>(i);
|
||||
else mVUclearProg<1>(i);
|
||||
DevCon::Status("microVU%d: Killing Dead Program [%03d]", params mVU->index, i+1);
|
||||
}
|
||||
}
|
||||
mVU->prog.curFrame++;
|
||||
}
|
||||
|
||||
microVUf(bool) mVUcmpPartial(int progIndex) {
|
||||
|
@ -244,16 +225,15 @@ microVUf(bool) mVUcmpPartial(int progIndex) {
|
|||
}
|
||||
|
||||
// Compare Cached microProgram to mVU->regs->Micro
|
||||
microVUf(bool) mVUcmpProg(int progIndex, bool progUsed, const bool cmpWholeProg) {
|
||||
microVUf(bool) mVUcmpProg(int progIndex, const bool cmpWholeProg) {
|
||||
microVU* mVU = mVUx;
|
||||
if (progUsed) {
|
||||
if (!mVUprogI.isDead) {
|
||||
if ((cmpWholeProg && !memcmp_mmx((u8*)mVUprogI.data, mVU->regs->Micro, mVU->microMemSize))
|
||||
|| (!cmpWholeProg && mVUcmpPartial<vuIndex>(progIndex))) {
|
||||
mVU->prog.cur = progIndex;
|
||||
mVU->prog.cleared = 0;
|
||||
mVU->prog.isSame = cmpWholeProg ? 1 : -1;
|
||||
mVU->prog.prog[progIndex].last_used = 3;
|
||||
mVU->prog.prog[progIndex].used++; // increment 'used'
|
||||
mVU->prog.prog[progIndex].used = 1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -263,23 +243,17 @@ microVUf(bool) mVUcmpProg(int progIndex, bool progUsed, const bool cmpWholeProg)
|
|||
// Searches for Cached Micro Program and sets prog.cur to it (returns 1 if program found, else returns 0)
|
||||
microVUf(int) mVUsearchProg() {
|
||||
microVU* mVU = mVUx;
|
||||
|
||||
if (mVU->prog.cleared) { // If cleared, we need to search for new program
|
||||
for (int i = 0; i <= mVU->prog.total; i++) {
|
||||
if (mVUcmpProg<vuIndex>(i, !!mVU->prog.prog[i].used, 0))
|
||||
return 1; // Check Recently Used Programs
|
||||
}
|
||||
for (int i = 0; i <= mVU->prog.total; i++) {
|
||||
if (mVUcmpProg<vuIndex>(i, !mVU->prog.prog[i].used, 0))
|
||||
return 1; // Check Older Programs
|
||||
for (int i = mVU->prog.max; i >= 0; i--) {
|
||||
if (mVUcmpProg<vuIndex>(mVU->prog.progList[i], 0))
|
||||
return 1;
|
||||
}
|
||||
mVU->prog.cur = mVUfindLeastUsedProg<vuIndex>(); // If cleared and program not found, make a new program instance
|
||||
mVU->prog.cleared = 0;
|
||||
mVU->prog.isSame = 1;
|
||||
return 0;
|
||||
}
|
||||
mVU->prog.prog[mVU->prog.cur].used++;
|
||||
mVU->prog.prog[mVU->prog.cur].last_used = 3;
|
||||
mVU->prog.prog[mVU->prog.cur].used = 1;
|
||||
return 1; // If !cleared, then we're still on the same program as last-time ;)
|
||||
}
|
||||
|
||||
|
@ -288,7 +262,7 @@ microVUf(int) mVUsearchProg() {
|
|||
//------------------------------------------------------------------
|
||||
|
||||
void initVUrec (VURegs* vuRegs, const int vuIndex) { mVUinit(vuRegs, vuIndex); }
|
||||
void closeVUrec(const int vuIndex) { mVUclose(mVUx, 0); }
|
||||
void closeVUrec(const int vuIndex) { mVUclose(mVUx); }
|
||||
void resetVUrec(const int vuIndex) { mVUreset(mVUx); }
|
||||
void vsyncVUrec(const int vuIndex) { mVUvsyncUpdate(mVUx); }
|
||||
|
||||
|
|
|
@ -114,23 +114,26 @@ struct microProgram {
|
|||
u32 data [mProgSize]; // Holds a copy of the VU microProgram
|
||||
microBlockManager* block[mProgSize/2]; // Array of Block Managers
|
||||
microRange ranges; // The ranges of the microProgram that have already been recompiled
|
||||
u64 used; // Number of times its been used
|
||||
u32 last_used; // Counters # of frames since last use (starts at 3 and counts backwards to 0 for each 30fps vSync)
|
||||
u32 frame; // Frame # the program was last used on
|
||||
u32 used; // Program was used this frame?
|
||||
bool isDead; // Program is dead?
|
||||
};
|
||||
|
||||
#define mMaxProg ((mVU->index)?400:8) // The amount of Micro Programs Recs will 'remember' (For n = 1, 2, 4, 8, 16, etc...)
|
||||
struct microProgManager {
|
||||
microIR<mProgSize> allocInfo; // IR information
|
||||
microProgram* prog; // Store MicroPrograms in memory
|
||||
int max; // Max Number of MicroPrograms minus 1
|
||||
int total; // Total Number of valid MicroPrograms minus 1
|
||||
int cur; // Index to Current MicroProgram thats running (-1 = uncached)
|
||||
int isSame; // Current cached microProgram is Exact Same program as mVU->regs->Micro (-1 = unknown, 0 = No, 1 = Yes)
|
||||
int cleared; // Micro Program is Indeterminate so must be searched for (and if no matches are found then recompile a new one)
|
||||
u8* x86ptr; // Pointer to program's recompilation code
|
||||
u8* x86start; // Start of program's rec-cache
|
||||
u8* x86end; // Limit of program's rec-cache
|
||||
microRegInfo lpState; // Pipeline state from where program left off (useful for continuing execution)
|
||||
microIR<mProgSize> allocInfo; // IR information
|
||||
microProgram* prog; // Store MicroPrograms in memory
|
||||
int* progList; // List of program indexes ordered by age (ordered from newest to oldest)
|
||||
int max; // Max Number of MicroPrograms minus 1
|
||||
int total; // Total Number of valid MicroPrograms minus 1
|
||||
int cur; // Index to Current MicroProgram thats running (-1 = uncached)
|
||||
int isSame; // Current cached microProgram is Exact Same program as mVU->regs->Micro (-1 = unknown, 0 = No, 1 = Yes)
|
||||
int cleared; // Micro Program is Indeterminate so must be searched for (and if no matches are found then recompile a new one)
|
||||
u32 curFrame; // Frame Counter
|
||||
u8* x86ptr; // Pointer to program's recompilation code
|
||||
u8* x86start; // Start of program's rec-cache
|
||||
u8* x86end; // Limit of program's rec-cache
|
||||
microRegInfo lpState; // Pipeline state from where program left off (useful for continuing execution)
|
||||
};
|
||||
|
||||
#define mVUcacheSize (mMaxProg * (0x100000 * 0.5)) // 0.5mb per program
|
||||
|
@ -175,7 +178,7 @@ extern int mVUdebugNow;
|
|||
// Main Functions
|
||||
microVUt(void) mVUinit(VURegs*, int);
|
||||
microVUt(void) mVUreset(mV);
|
||||
microVUt(void) mVUclose(mV, bool isReset);
|
||||
microVUt(void) mVUclose(mV);
|
||||
microVUt(void) mVUclear(mV, u32, u32);
|
||||
microVUt(void*) mVUblockFetch(microVU* mVU, u32 startPC, uptr pState);
|
||||
microVUx(void*) __fastcall mVUcompileJIT(u32 startPC, uptr pState);
|
||||
|
@ -187,6 +190,8 @@ mVUop(mVUopU);
|
|||
mVUop(mVUopL);
|
||||
|
||||
// Private Functions
|
||||
microVUt(void) mVUsortProg(mV, int progIndex);
|
||||
microVUf(void) mVUclearProg(int progIndex);
|
||||
microVUf(int) mVUfindLeastUsedProg(microVU* mVU);
|
||||
microVUf(int) mVUsearchProg();
|
||||
microVUf(void) mVUcacheProg(int progIndex);
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
#define doLowerOp() { incPC(-1); mVUopL(mVU, 1); incPC(1); }
|
||||
#define doSwapOp() { doBackupVF1(); mVUopL(mVU, 1); doBackupVF2(); incPC(1); doUpperOp(); doBackupVF3(); }
|
||||
#define doIbit() { if (mVUup.iBit) { incPC(-1); MOV32ItoM((uptr)&mVU->regs->VI[REG_I].UL, curI); incPC(1); } }
|
||||
#define blockCreate(addr) { if (!mVUblocks[addr]) mVUblocks[addr] = new microBlockManager();/*microBlockManager::AlignedNew();*/ }
|
||||
#define blockCreate(addr) { if (!mVUblocks[addr]) mVUblocks[addr] = new microBlockManager(); }
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Helper Functions
|
||||
|
|
|
@ -143,9 +143,9 @@ microVUt(int) mVUsetFlags(mV, int* xStatus, int* xMac, int* xClip) {
|
|||
mFLAG.lastWrite = (xM-1) & 3;
|
||||
cFLAG.lastWrite = (xC-1) & 3;
|
||||
|
||||
if (sFlagCond) { xStatus[xS] = cycles + 4; xS = (xS+1) & 3; }
|
||||
if (mFLAG.doFlag) { xMac [xM] = cycles + 4; xM = (xM+1) & 3; }
|
||||
if (cFLAG.doFlag) { xClip [xC] = cycles + 4; xC = (xC+1) & 3; }
|
||||
if (sFlagCond) { xStatus[xS] = cycles + 4; xS = (xS+1) & 3; }
|
||||
if (mFLAG.doFlag) { xMac [xM] = cycles + 4; xM = (xM+1) & 3; }
|
||||
if (cFLAG.doFlag) { xClip [xC] = cycles + 4; xC = (xC+1) & 3; }
|
||||
|
||||
cycles++;
|
||||
incPC2(2);
|
||||
|
@ -170,9 +170,6 @@ microVUt(void) mVUsetupFlags(mV, int* xStatus, int* xMac, int* xClip, int cycles
|
|||
int sortRegs = sortFlag(xStatus, bStatus, cycles);
|
||||
// DevCon::Status("sortRegs = %d", params sortRegs);
|
||||
// Note: Emitter will optimize out mov(reg1, reg1) cases...
|
||||
// There 'is' still room for small optimizations but the
|
||||
// sorting algorithm would be really complex and not really
|
||||
// a noticeable improvement... (Most common cases are 1 & 2)
|
||||
if (sortRegs == 1) {
|
||||
MOV32RtoR(gprF0, getFlagReg1(bStatus[0]));
|
||||
MOV32RtoR(gprF1, getFlagReg1(bStatus[1]));
|
||||
|
@ -224,12 +221,12 @@ microVUt(void) mVUsetupFlags(mV, int* xStatus, int* xMac, int* xClip, int cycles
|
|||
}
|
||||
}
|
||||
|
||||
#define shortBranch() { \
|
||||
if (branch == 3) { \
|
||||
#define shortBranch() \
|
||||
if ((branch == 3) || (branch == 4)) { \
|
||||
mVUflagPass(mVU, aBranchAddr, (xCount - (mVUcount+1))); \
|
||||
mVUcount = 4; \
|
||||
if (branch == 3) { mVUcount = 4; break; } \
|
||||
} \
|
||||
}
|
||||
else break
|
||||
|
||||
// Scan through instructions and check if flags are read (FSxxx, FMxxx, FCxxx opcodes)
|
||||
void mVUflagPass(mV, u32 startPC, u32 xCount) {
|
||||
|
@ -243,12 +240,12 @@ void mVUflagPass(mV, u32 startPC, u32 xCount) {
|
|||
mVUbranch = 0;
|
||||
for (int branch = 0; mVUcount < xCount; mVUcount++) {
|
||||
incPC(1);
|
||||
if ( curI & _Ebit_ ) { branch = 1; }
|
||||
if ( curI & _DTbit_ ) { branch = 4; }
|
||||
if (!(curI & _Ibit_) ) { incPC(-1); mVUopL(mVU, 3); incPC(1); }
|
||||
if (branch >= 2) { shortBranch(); break; }
|
||||
if ( curI & _Ebit_ ) { branch = 1; }
|
||||
if ( curI & _DTbit_ ) { branch = 6; }
|
||||
if (!(curI & _Ibit_) ) { incPC(-1); mVUopL(mVU, 3); incPC(1); }
|
||||
if (branch >= 2) { shortBranch(); }
|
||||
else if (branch == 1) { branch = 2; }
|
||||
if (mVUbranch) { branch = (mVUbranch >= 9) ? 5 : 3; aBranchAddr = branchAddr; mVUbranch = 0; }
|
||||
if (mVUbranch) { branch = ((mVUbranch>8)?(5):((mVUbranch<3)?3:4)); aBranchAddr = branchAddr; mVUbranch = 0; }
|
||||
incPC(1);
|
||||
}
|
||||
if (mVUcount < 4) { mVUflagInfo |= 0xfff; }
|
||||
|
@ -267,7 +264,7 @@ microVUt(void) mVUsetFlagInfo(mV) {
|
|||
branchType1 { incPC(-1); mVUflagPass(mVU, branchAddr, 4); incPC(1); }
|
||||
branchType2 {
|
||||
if (!mVUlow.constJump.isValid) { mVUflagInfo |= 0xfff; }
|
||||
else { mVUflagPass(mVU, mVUlow.constJump.regValue, 4); }
|
||||
else { mVUflagPass(mVU, (mVUlow.constJump.regValue*8)&(mVU->microMemSize-8), 4); }
|
||||
}
|
||||
branchType3 {
|
||||
incPC(-1);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
// writes text directly to the microVU.txt, no newlines appended.
|
||||
// writes text directly to mVU->logFile, no newlines appended.
|
||||
microVUx(void) __mVULog(const char* fmt, ...) {
|
||||
microVU* mVU = mVUx;
|
||||
char tmp[2024];
|
||||
|
|
|
@ -219,6 +219,7 @@ typedef u32 (__fastcall *mVUCall)(void*, void*);
|
|||
#define cmpOffset(x) ((u8*)&(((u8*)x)[mVUprogI.ranges.range[i][0]]))
|
||||
#define Rmem (uptr)&mVU->regs->VI[REG_R].UL
|
||||
#define Roffset (uptr)&mVU->regs->VI[9].UL
|
||||
#define aWrap(x, m) ((x > m) ? 0 : x)
|
||||
|
||||
// Flag Info
|
||||
#define __Status (mVUflagInfo & (0xf<<0))
|
||||
|
|
|
@ -568,9 +568,9 @@ void SuperVUDumpBlock(list<VuBaseBlock*>& blocks, int vuindex)
|
|||
u32 *mem;
|
||||
u32 i;
|
||||
|
||||
g_Conf.Folders.Dumps.Mkdir();
|
||||
g_Conf.Folders.Logs.Mkdir();
|
||||
AsciiFile eff(
|
||||
Path::Combine( g_Conf.Folders.Dumps, wxsFormat(L"svu%cdump%.4X.txt", s_vu?L'0':L'1', s_pFnHeader->startpc) ),
|
||||
Path::Combine( g_Conf.Folders.Logs, wxsFormat(L"svu%cdump%.4X.txt", s_vu?L'0':L'1', s_pFnHeader->startpc) ),
|
||||
wxFile::write
|
||||
);
|
||||
|
||||
|
|
|
@ -26,9 +26,8 @@
|
|||
#include "GPUScanlineEnvironment.h"
|
||||
#include "GPUSetupPrimCodeGenerator.h"
|
||||
#include "GPUDrawScanlineCodeGenerator.h"
|
||||
#include "GSAlignedClass.h"
|
||||
|
||||
class GPUDrawScanline : public GSAlignedClass<16>, public IDrawScanline
|
||||
class GPUDrawScanline : public IDrawScanline
|
||||
{
|
||||
GPUScanlineEnvironment m_env;
|
||||
|
||||
|
|
|
@ -113,7 +113,17 @@ void GPURenderer::VSync()
|
|||
|
||||
Flush();
|
||||
|
||||
if(!Merge()) return;
|
||||
if(!m_dev->IsLost(true))
|
||||
{
|
||||
if(!Merge())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ResetDevice();
|
||||
}
|
||||
|
||||
// osd
|
||||
|
||||
|
@ -148,11 +158,6 @@ void GPURenderer::VSync()
|
|||
SetWindowText(m_hWnd, s.c_str());
|
||||
}
|
||||
|
||||
if(m_dev->IsLost())
|
||||
{
|
||||
ResetDevice();
|
||||
}
|
||||
|
||||
GSVector4i r;
|
||||
|
||||
GetClientRect(m_hWnd, r);
|
||||
|
|
|
@ -32,6 +32,7 @@ GPURendererSW::GPURendererSW(GSDevice* dev)
|
|||
|
||||
GPURendererSW::~GPURendererSW()
|
||||
{
|
||||
delete m_texture;
|
||||
}
|
||||
|
||||
void GPURendererSW::ResetDevice()
|
||||
|
@ -50,36 +51,16 @@ GSTexture* GPURendererSW::GetOutput()
|
|||
r.right <<= m_scale.x;
|
||||
r.bottom <<= m_scale.y;
|
||||
|
||||
// TODO
|
||||
static uint32* buff = (uint32*)_aligned_malloc(m_mem.GetWidth() * m_mem.GetHeight() * sizeof(uint32), 16);
|
||||
|
||||
m_mem.ReadFrame32(r, buff, !!m_env.STATUS.ISRGB24);
|
||||
|
||||
int w = r.width();
|
||||
int h = r.height();
|
||||
|
||||
if(m_texture)
|
||||
if(m_dev->ResizeTexture(&m_texture, r.width(), r.height()))
|
||||
{
|
||||
if(m_texture->GetWidth() != w || m_texture->GetHeight() != h)
|
||||
{
|
||||
delete m_texture;
|
||||
// TODO
|
||||
static uint32* buff = (uint32*)_aligned_malloc(m_mem.GetWidth() * m_mem.GetHeight() * sizeof(uint32), 16);
|
||||
|
||||
m_texture = NULL;
|
||||
}
|
||||
m_mem.ReadFrame32(r, buff, !!m_env.STATUS.ISRGB24);
|
||||
|
||||
m_texture->Update(r.rsize(), buff, m_mem.GetWidth() * sizeof(uint32));
|
||||
}
|
||||
|
||||
if(!m_texture)
|
||||
{
|
||||
m_texture = m_dev->CreateTexture(w, h);
|
||||
|
||||
if(!m_texture)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
m_texture->Update(r.rsize(), buff, m_mem.GetWidth() * sizeof(uint32));
|
||||
|
||||
return m_texture;
|
||||
}
|
||||
|
||||
|
@ -164,8 +145,8 @@ void GPURendererSW::Draw()
|
|||
{
|
||||
GSVector4 p = m_vertices[i].p;
|
||||
|
||||
tl = tl.minv(p);
|
||||
br = br.maxv(p);
|
||||
tl = tl.min(p);
|
||||
br = br.max(p);
|
||||
}
|
||||
|
||||
GSVector4i r = GSVector4i(tl.xyxy(br)).rintersect(data.scissor);
|
||||
|
|
|
@ -801,7 +801,9 @@ union
|
|||
uint64 _PAD4:30;
|
||||
};
|
||||
};
|
||||
REG_END
|
||||
REG_END2
|
||||
__forceinline bool IsRepeating() {return ((uint32)1 << TW) > (TBW << 6);}
|
||||
REG_END2
|
||||
|
||||
REG64_(GIFReg, TEX1)
|
||||
uint32 LCM:1;
|
||||
|
|
|
@ -25,7 +25,8 @@ template<int i> class GSAlignedClass
|
|||
{
|
||||
public:
|
||||
GSAlignedClass() {}
|
||||
|
||||
virtual ~GSAlignedClass() {}
|
||||
|
||||
void* operator new (size_t size)
|
||||
{
|
||||
return _aligned_malloc(size, i);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include "GSClut.h"
|
||||
#include "GSLocalMemory.h"
|
||||
|
||||
GSClut::GSClut(const GSLocalMemory* mem)
|
||||
GSClut::GSClut(GSLocalMemory* mem)
|
||||
: m_mem(mem)
|
||||
{
|
||||
uint8* p = (uint8*)VirtualAlloc(NULL, 2 * 4096, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
|
@ -168,14 +168,16 @@ void GSClut::WriteCLUT16S_I4_CSM1(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& T
|
|||
|
||||
template<int n> void GSClut::WriteCLUT32_CSM2(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
|
||||
{
|
||||
uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4);
|
||||
GSLocalMemory::PixelOffset* po = m_mem->GetPixelOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT32);
|
||||
|
||||
uint32 base = m_mem->PixelAddress32(0, TEXCLUT.COV, TEX0.CBP, TEXCLUT.CBW);
|
||||
int* offset = &m_mem->rowOffset32[TEXCLUT.COU << 4];
|
||||
uint32* RESTRICT s = &m_mem->m_vm32[po->row[TEXCLUT.COV]];
|
||||
int* RESTRICT o = &po->col[0][TEXCLUT.COU << 4];
|
||||
|
||||
uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4);
|
||||
|
||||
for(int i = 0; i < n; i++)
|
||||
{
|
||||
uint32 c = m_mem->ReadPixel32(base + offset[i]);
|
||||
uint32 c = s[o[i]];
|
||||
|
||||
clut[i] = (uint16)(c & 0xffff);
|
||||
clut[i + 256] = (uint16)(c >> 16);
|
||||
|
@ -184,27 +186,31 @@ template<int n> void GSClut::WriteCLUT32_CSM2(const GIFRegTEX0& TEX0, const GIFR
|
|||
|
||||
template<int n> void GSClut::WriteCLUT16_CSM2(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
|
||||
{
|
||||
uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4);
|
||||
GSLocalMemory::PixelOffset* po = m_mem->GetPixelOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT16);
|
||||
|
||||
uint32 base = m_mem->PixelAddress16(0, TEXCLUT.COV, TEX0.CBP, TEXCLUT.CBW);
|
||||
int* offset = &m_mem->rowOffset16[TEXCLUT.COU << 4];
|
||||
uint16* RESTRICT s = &m_mem->m_vm16[po->row[TEXCLUT.COV]];
|
||||
int* RESTRICT o = &po->col[0][TEXCLUT.COU << 4];
|
||||
|
||||
uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4);
|
||||
|
||||
for(int i = 0; i < n; i++)
|
||||
{
|
||||
clut[i] = (uint16)m_mem->ReadPixel16(base + offset[i]);
|
||||
clut[i] = s[o[i]];
|
||||
}
|
||||
}
|
||||
|
||||
template<int n> void GSClut::WriteCLUT16S_CSM2(const GIFRegTEX0& TEX0, const GIFRegTEXCLUT& TEXCLUT)
|
||||
{
|
||||
uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4);
|
||||
GSLocalMemory::PixelOffset* po = m_mem->GetPixelOffset(TEX0.CBP, TEXCLUT.CBW, PSM_PSMCT16S);
|
||||
|
||||
uint32 base = m_mem->PixelAddress16S(0, TEXCLUT.COV, TEX0.CBP, TEXCLUT.CBW);
|
||||
int* offset = &m_mem->rowOffset16S[TEXCLUT.COU << 4];
|
||||
uint16* RESTRICT s = &m_mem->m_vm16[po->row[TEXCLUT.COV]];
|
||||
int* RESTRICT o = &po->col[0][TEXCLUT.COU << 4];
|
||||
|
||||
uint16* RESTRICT clut = m_clut + (TEX0.CSA << 4);
|
||||
|
||||
for(int i = 0; i < n; i++)
|
||||
{
|
||||
clut[i] = (uint16)m_mem->ReadPixel16(base + offset[i]);
|
||||
clut[i] = s[o[i]];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ class GSLocalMemory;
|
|||
|
||||
__declspec(align(16)) class GSClut : public GSAlignedClass<16>
|
||||
{
|
||||
const GSLocalMemory* m_mem;
|
||||
GSLocalMemory* m_mem;
|
||||
|
||||
uint32 m_CBP[2];
|
||||
uint16* m_clut;
|
||||
|
@ -93,7 +93,7 @@ __declspec(align(16)) class GSClut : public GSAlignedClass<16>
|
|||
static void Expand16(const uint16* RESTRICT src, uint32* RESTRICT dst, int w, const GIFRegTEXA& TEXA);
|
||||
|
||||
public:
|
||||
GSClut(const GSLocalMemory* mem);
|
||||
GSClut(GSLocalMemory* mem);
|
||||
virtual ~GSClut();
|
||||
|
||||
void Invalidate();
|
||||
|
|
|
@ -89,6 +89,7 @@ CRC::Game CRC::m_games[] =
|
|||
{0x7D8F539A, SoTC, EU, 0},
|
||||
{0x3122B508, OnePieceGrandAdventure, US, 0},
|
||||
{0x8DF14A24, OnePieceGrandAdventure, Unknown, 0},
|
||||
{0x5D02CC5B, OnePieceGrandBattle, Unknown, 0},
|
||||
{0x6F8545DB, ICO, US, 0},
|
||||
{0xB01A4C95, ICO, JP, 0},
|
||||
{0x5C991F4E, ICO, Unknown, 0},
|
||||
|
@ -143,7 +144,9 @@ CRC::Game CRC::m_games[] =
|
|||
{0x23A97857, StarOcean3, JPUNDUB, 0},
|
||||
{0xCC96CE93, ValkyrieProfile2, US, 0},
|
||||
{0x774DE8E2, ValkyrieProfile2, JP, 0},
|
||||
{0x47B9B2FD, RadiataStories, US, 0},
|
||||
{0x04CCB600, ValkyrieProfile2, EU, 0},
|
||||
{0x47B9B2FD, RadiataStories, US, 0},
|
||||
{0xE8FCF8EC, SMTNocturne, US, ZWriteMustNotClear}, // saves/reloads z buffer around shadow drawing
|
||||
};
|
||||
|
||||
hash_map<uint32, CRC::Game*> CRC::m_map;
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
BullyCC,
|
||||
SoTC,
|
||||
OnePieceGrandAdventure,
|
||||
OnePieceGrandBattle,
|
||||
ICO,
|
||||
GT4,
|
||||
WildArms5,
|
||||
|
@ -74,6 +75,7 @@ public:
|
|||
StarOcean3,
|
||||
ValkyrieProfile2,
|
||||
RadiataStories,
|
||||
SMTNocturne,
|
||||
TitleCount,
|
||||
};
|
||||
|
||||
|
@ -95,6 +97,7 @@ public:
|
|||
enum Flags
|
||||
{
|
||||
PointListPalette = 1,
|
||||
ZWriteMustNotClear = 2,
|
||||
};
|
||||
|
||||
struct Game
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
GSDevice::GSDevice()
|
||||
: m_wnd(NULL)
|
||||
, m_rbswapped(false)
|
||||
, m_backbuffer(NULL)
|
||||
, m_merge(NULL)
|
||||
, m_weavebob(NULL)
|
||||
|
@ -34,6 +35,13 @@ GSDevice::GSDevice()
|
|||
|
||||
GSDevice::~GSDevice()
|
||||
{
|
||||
for_each(m_pool.begin(), m_pool.end(), delete_object());
|
||||
|
||||
delete m_backbuffer;
|
||||
delete m_merge;
|
||||
delete m_weavebob;
|
||||
delete m_blend;
|
||||
delete m_1x1;
|
||||
}
|
||||
|
||||
bool GSDevice::Create(GSWnd* wnd, bool vsync)
|
||||
|
@ -44,12 +52,9 @@ bool GSDevice::Create(GSWnd* wnd, bool vsync)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GSDevice::Reset(int w, int h, bool fs)
|
||||
bool GSDevice::Reset(int w, int h, int mode)
|
||||
{
|
||||
for(list<GSTexture*>::iterator i = m_pool.begin(); i != m_pool.end(); i++)
|
||||
{
|
||||
delete *i;
|
||||
}
|
||||
for_each(m_pool.begin(), m_pool.end(), delete_object());
|
||||
|
||||
m_pool.clear();
|
||||
|
||||
|
@ -74,9 +79,15 @@ void GSDevice::Present(const GSVector4i& r, int shader)
|
|||
{
|
||||
GSVector4i cr = m_wnd->GetClientRect();
|
||||
|
||||
if(m_backbuffer->GetWidth() != cr.width() || m_backbuffer->GetHeight() != cr.height())
|
||||
int w = std::max(cr.width(), 1);
|
||||
int h = std::max(cr.height(), 1);
|
||||
|
||||
if(!m_backbuffer || m_backbuffer->GetWidth() != w || m_backbuffer->GetHeight() != h)
|
||||
{
|
||||
Reset(cr.width(), cr.height(), false);
|
||||
if(!Reset(w, h, DontCare))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ClearRenderTarget(m_backbuffer, 0);
|
||||
|
@ -221,4 +232,22 @@ void GSDevice::Interlace(const GSVector2i& ds, int field, int mode, float yoffse
|
|||
{
|
||||
m_current = m_merge;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GSDevice::ResizeTexture(GSTexture** t, int w, int h)
|
||||
{
|
||||
if(t == NULL) {ASSERT(0); return false;}
|
||||
|
||||
GSTexture* t2 = *t;
|
||||
|
||||
if(t2 == NULL || t2->GetWidth() != w || t2->GetHeight() != h)
|
||||
{
|
||||
delete t2;
|
||||
|
||||
t2 = CreateTexture(w, h);
|
||||
|
||||
*t = t2;
|
||||
}
|
||||
|
||||
return t2 != NULL;
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ class GSDevice : public GSAlignedClass<16>
|
|||
protected:
|
||||
GSWnd* m_wnd;
|
||||
bool m_vsync;
|
||||
bool m_rbswapped;
|
||||
GSTexture* m_backbuffer;
|
||||
GSTexture* m_merge;
|
||||
GSTexture* m_weavebob;
|
||||
|
@ -73,10 +74,11 @@ public:
|
|||
|
||||
void Recycle(GSTexture* t);
|
||||
|
||||
virtual bool Create(GSWnd* wnd, bool vsync);
|
||||
virtual bool Reset(int w, int h, bool fs);
|
||||
enum {Windowed, Fullscreen, DontCare};
|
||||
|
||||
virtual bool IsLost() {return false;}
|
||||
virtual bool Create(GSWnd* wnd, bool vsync);
|
||||
virtual bool Reset(int w, int h, int mode);
|
||||
virtual bool IsLost(bool update = false) {return false;}
|
||||
virtual void Present(const GSVector4i& r, int shader);
|
||||
virtual void Flip() {}
|
||||
|
||||
|
@ -96,15 +98,20 @@ public:
|
|||
|
||||
virtual GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0) {return NULL;}
|
||||
|
||||
virtual void CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r) {}
|
||||
|
||||
virtual void StretchRect(GSTexture* st, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true);
|
||||
virtual void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true) {}
|
||||
|
||||
GSTexture* GetCurrent();
|
||||
virtual bool IsCurrentRGBA() {return true;}
|
||||
|
||||
void Merge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, const GSVector2i& fs, bool slbg, bool mmod, const GSVector4& c);
|
||||
void Interlace(const GSVector2i& ds, int field, int mode, float yoffset);
|
||||
|
||||
bool ResizeTexture(GSTexture** t, int w, int h);
|
||||
|
||||
bool IsRBSwapped() {return m_rbswapped;}
|
||||
|
||||
template<class T> void PrepareShaderMacro(vector<T>& dst, const T* src, const char* model)
|
||||
{
|
||||
dst.clear();
|
||||
|
|
|
@ -207,16 +207,16 @@ bool GSDevice10::Create(GSWnd* wnd, bool vsync)
|
|||
|
||||
//
|
||||
|
||||
Reset(1, 1, false);
|
||||
Reset(1, 1, Windowed);
|
||||
|
||||
//
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSDevice10::Reset(int w, int h, bool fs)
|
||||
bool GSDevice10::Reset(int w, int h, int mode)
|
||||
{
|
||||
if(!__super::Reset(w, h, fs))
|
||||
if(!__super::Reset(w, h, mode))
|
||||
return false;
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC scd;
|
||||
|
@ -392,6 +392,13 @@ GSTexture* GSDevice10::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w,
|
|||
return dst;
|
||||
}
|
||||
|
||||
void GSDevice10::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
|
||||
{
|
||||
D3D10_BOX box = {r.left, r.top, 0, r.right, r.bottom, 1};
|
||||
|
||||
m_dev->CopySubresourceRegion(*(GSTexture10*)dt, 0, 0, 0, 0, *(GSTexture10*)st, 0, &box);
|
||||
}
|
||||
|
||||
void GSDevice10::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader, bool linear)
|
||||
{
|
||||
StretchRect(st, sr, dt, dr, m_convert.ps[shader], NULL, linear);
|
||||
|
@ -504,7 +511,7 @@ void GSDevice10::IASetVertexBuffer(const void* vertices, size_t stride, size_t c
|
|||
m_vertices.vb = NULL;
|
||||
m_vertices.start = 0;
|
||||
m_vertices.count = 0;
|
||||
m_vertices.limit = max(count * 3 / 2, 10000);
|
||||
m_vertices.limit = std::max<int>(count * 3 / 2, 10000);
|
||||
}
|
||||
|
||||
if(m_vertices.vb == NULL)
|
||||
|
|
|
@ -96,8 +96,7 @@ public:
|
|||
virtual ~GSDevice10();
|
||||
|
||||
bool Create(GSWnd* wnd, bool vsync);
|
||||
bool Reset(int w, int h, bool fs);
|
||||
|
||||
bool Reset(int w, int h, int mode);
|
||||
void Flip();
|
||||
|
||||
void BeginScene();
|
||||
|
@ -116,6 +115,8 @@ public:
|
|||
|
||||
GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0);
|
||||
|
||||
void CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r);
|
||||
|
||||
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true);
|
||||
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, ID3D10PixelShader* ps, ID3D10Buffer* ps_cb, bool linear = true);
|
||||
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, ID3D10PixelShader* ps, ID3D10Buffer* ps_cb, ID3D10BlendState* bs, bool linear = true);
|
||||
|
|
|
@ -92,8 +92,8 @@ bool GSDevice11::Create(GSWnd* wnd, bool vsync)
|
|||
flags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
#endif
|
||||
|
||||
hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &m_level, &m_ctx);
|
||||
// hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &m_level, &m_ctx);
|
||||
hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, NULL, 0, D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &m_level, &m_ctx);
|
||||
// hr = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, flags, NULL, 0, D3D11_SDK_VERSION, &scd, &m_swapchain, &m_dev, &m_level, &m_ctx);
|
||||
|
||||
if(FAILED(hr)) return false;
|
||||
|
||||
|
@ -244,16 +244,16 @@ bool GSDevice11::Create(GSWnd* wnd, bool vsync)
|
|||
|
||||
//
|
||||
|
||||
Reset(1, 1, false);
|
||||
Reset(1, 1, Windowed);
|
||||
|
||||
//
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSDevice11::Reset(int w, int h, bool fs)
|
||||
bool GSDevice11::Reset(int w, int h, int mode)
|
||||
{
|
||||
if(!__super::Reset(w, h, fs))
|
||||
if(!__super::Reset(w, h, mode))
|
||||
return false;
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC scd;
|
||||
|
@ -429,6 +429,13 @@ GSTexture* GSDevice11::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w,
|
|||
return dst;
|
||||
}
|
||||
|
||||
void GSDevice11::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
|
||||
{
|
||||
D3D11_BOX box = {r.left, r.top, 0, r.right, r.bottom, 1};
|
||||
|
||||
m_ctx->CopySubresourceRegion(*(GSTexture11*)dt, 0, 0, 0, 0, *(GSTexture11*)st, 0, &box);
|
||||
}
|
||||
|
||||
void GSDevice11::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader, bool linear)
|
||||
{
|
||||
StretchRect(st, sr, dt, dr, m_convert.ps[shader], NULL, linear);
|
||||
|
@ -541,7 +548,7 @@ void GSDevice11::IASetVertexBuffer(const void* vertices, size_t stride, size_t c
|
|||
m_vertices.vb = NULL;
|
||||
m_vertices.start = 0;
|
||||
m_vertices.count = 0;
|
||||
m_vertices.limit = max(count * 3 / 2, 10000);
|
||||
m_vertices.limit = std::max<int>(count * 3 / 2, 10000);
|
||||
}
|
||||
|
||||
if(m_vertices.vb == NULL)
|
||||
|
|
|
@ -99,8 +99,7 @@ public:
|
|||
virtual ~GSDevice11();
|
||||
|
||||
bool Create(GSWnd* wnd, bool vsync);
|
||||
bool Reset(int w, int h, bool fs);
|
||||
|
||||
bool Reset(int w, int h, int mode);
|
||||
void Flip();
|
||||
|
||||
void BeginScene();
|
||||
|
@ -119,6 +118,8 @@ public:
|
|||
|
||||
GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0);
|
||||
|
||||
void CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r);
|
||||
|
||||
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true);
|
||||
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, bool linear = true);
|
||||
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, ID3D11PixelShader* ps, ID3D11Buffer* ps_cb, ID3D11BlendState* bs, bool linear = true);
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "GSDevice7.h"
|
||||
|
||||
GSDevice7::GSDevice7()
|
||||
: m_lost(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -75,14 +76,14 @@ bool GSDevice7::Create(GSWnd* wnd, bool vsync)
|
|||
return false;
|
||||
}
|
||||
|
||||
Reset(1, 1, false);
|
||||
Reset(1, 1, Windowed);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSDevice7::Reset(int w, int h, bool fs)
|
||||
bool GSDevice7::Reset(int w, int h, int mode)
|
||||
{
|
||||
if(!__super::Reset(w, h, fs))
|
||||
if(!__super::Reset(w, h, mode))
|
||||
return false;
|
||||
|
||||
DDSURFACEDESC2 desc;
|
||||
|
@ -130,6 +131,8 @@ bool GSDevice7::Reset(int w, int h, bool fs)
|
|||
}
|
||||
}
|
||||
|
||||
m_lost = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -139,9 +142,15 @@ void GSDevice7::Present(const GSVector4i& r, int shader)
|
|||
|
||||
GSVector4i cr = m_wnd->GetClientRect();
|
||||
|
||||
if(m_backbuffer->GetWidth() != cr.width() || m_backbuffer->GetHeight() != cr.height())
|
||||
int w = std::max(cr.width(), 1);
|
||||
int h = std::max(cr.height(), 1);
|
||||
|
||||
if(!m_backbuffer || m_backbuffer->GetWidth() != w || m_backbuffer->GetHeight() != h)
|
||||
{
|
||||
Reset(cr.width(), cr.height(), false);
|
||||
if(!Reset(w, h, DontCare))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CComPtr<IDirectDrawSurface7> backbuffer = *(GSTexture7*)m_backbuffer;
|
||||
|
@ -157,7 +166,10 @@ void GSDevice7::Present(const GSVector4i& r, int shader)
|
|||
|
||||
GSVector4i r2 = r;
|
||||
|
||||
hr = backbuffer->Blt(r2, *(GSTexture7*)m_merge, NULL, DDBLT_WAIT, NULL);
|
||||
if(m_current)
|
||||
{
|
||||
hr = backbuffer->Blt(r2, *(GSTexture7*)m_current, NULL, DDBLT_WAIT, NULL);
|
||||
}
|
||||
|
||||
// if ClearRenderTarget was implemented the parent class could handle these tasks until this point
|
||||
|
||||
|
@ -174,6 +186,8 @@ void GSDevice7::Present(const GSVector4i& r, int shader)
|
|||
|
||||
if(hr == DDERR_SURFACELOST)
|
||||
{
|
||||
m_lost = true;
|
||||
|
||||
// TODO
|
||||
|
||||
HRESULT hr = m_dd->TestCooperativeLevel();
|
||||
|
|
|
@ -29,6 +29,7 @@ class GSDevice7 : public GSDevice
|
|||
private:
|
||||
CComPtr<IDirectDraw7> m_dd;
|
||||
CComPtr<IDirectDrawSurface7> m_primary;
|
||||
bool m_lost;
|
||||
|
||||
GSTexture* Create(int type, int w, int h, int format);
|
||||
|
||||
|
@ -40,7 +41,7 @@ public:
|
|||
virtual ~GSDevice7();
|
||||
|
||||
bool Create(GSWnd* wnd, bool vsync);
|
||||
bool Reset(int w, int h, bool fs);
|
||||
|
||||
bool Reset(int w, int h, int mode);
|
||||
bool IsLost(bool update) {return m_lost;}
|
||||
void Present(const GSVector4i& r, int shader);
|
||||
};
|
||||
|
|
|
@ -42,7 +42,10 @@ GSDevice9::GSDevice9()
|
|||
, m_bf(0xffffffff)
|
||||
, m_rtv(NULL)
|
||||
, m_dsv(NULL)
|
||||
, m_lost(false)
|
||||
{
|
||||
m_rbswapped = true;
|
||||
|
||||
memset(&m_pp, 0, sizeof(m_pp));
|
||||
memset(&m_ddcaps, 0, sizeof(m_ddcaps));
|
||||
memset(&m_d3dcaps, 0, sizeof(m_d3dcaps));
|
||||
|
@ -89,12 +92,12 @@ bool GSDevice9::Create(GSWnd* wnd, bool vsync)
|
|||
|
||||
// d3d
|
||||
|
||||
m_d3d = Direct3DCreate9(D3D_SDK_VERSION);
|
||||
m_d3d.Attach(Direct3DCreate9(D3D_SDK_VERSION));
|
||||
|
||||
if(!m_d3d) return false;
|
||||
|
||||
hr = m_d3d->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24S8);
|
||||
|
||||
|
||||
if(FAILED(hr)) return false;
|
||||
|
||||
hr = m_d3d->CheckDepthStencilMatch(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, D3DFMT_D24S8);
|
||||
|
@ -105,9 +108,7 @@ bool GSDevice9::Create(GSWnd* wnd, bool vsync)
|
|||
|
||||
m_d3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &m_d3dcaps);
|
||||
|
||||
bool fs = theApp.GetConfig("ModeWidth", 0) > 0;
|
||||
|
||||
if(!Reset(1, 1, fs)) return false;
|
||||
if(!Reset(1, 1, theApp.GetConfig("ModeWidth", 0) > 0 ? Fullscreen : Windowed)) return false;
|
||||
|
||||
m_dev->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0);
|
||||
|
||||
|
@ -188,35 +189,46 @@ bool GSDevice9::Create(GSWnd* wnd, bool vsync)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GSDevice9::Reset(int w, int h, bool fs)
|
||||
bool GSDevice9::Reset(int w, int h, int mode)
|
||||
{
|
||||
if(!__super::Reset(w, h, fs))
|
||||
if(!__super::Reset(w, h, mode))
|
||||
return false;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
if(!m_d3d) return false;
|
||||
|
||||
if(m_swapchain && !fs && m_pp.Windowed)
|
||||
if(mode == DontCare)
|
||||
{
|
||||
m_swapchain = NULL;
|
||||
mode = m_pp.Windowed ? Windowed : Fullscreen;
|
||||
}
|
||||
|
||||
m_pp.BackBufferWidth = w;
|
||||
m_pp.BackBufferHeight = h;
|
||||
if(!m_lost)
|
||||
{
|
||||
if(m_swapchain && mode != Fullscreen && m_pp.Windowed)
|
||||
{
|
||||
m_swapchain = NULL;
|
||||
|
||||
hr = m_dev->CreateAdditionalSwapChain(&m_pp, &m_swapchain);
|
||||
m_pp.BackBufferWidth = w;
|
||||
m_pp.BackBufferHeight = h;
|
||||
|
||||
if(FAILED(hr)) return false;
|
||||
hr = m_dev->CreateAdditionalSwapChain(&m_pp, &m_swapchain);
|
||||
|
||||
CComPtr<IDirect3DSurface9> backbuffer;
|
||||
hr = m_swapchain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
|
||||
m_backbuffer = new GSTexture9(backbuffer);
|
||||
if(FAILED(hr)) return false;
|
||||
|
||||
return true;
|
||||
CComPtr<IDirect3DSurface9> backbuffer;
|
||||
hr = m_swapchain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
|
||||
m_backbuffer = new GSTexture9(backbuffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
m_swapchain = NULL;
|
||||
|
||||
|
||||
m_vertices.vb = NULL;
|
||||
m_vertices.vb_old = NULL;
|
||||
m_vertices.start = 0;
|
||||
m_vertices.count = 0;
|
||||
|
||||
if(m_vs_cb) _aligned_free(m_vs_cb);
|
||||
if(m_ps_cb) _aligned_free(m_ps_cb);
|
||||
|
||||
|
@ -258,7 +270,7 @@ bool GSDevice9::Reset(int w, int h, bool fs)
|
|||
int mh = theApp.GetConfig("ModeHeight", 0);
|
||||
int mrr = theApp.GetConfig("ModeRefreshRate", 0);
|
||||
|
||||
if(fs && mw > 0 && mh > 0 && mrr >= 0)
|
||||
if(mode == Fullscreen && mw > 0 && mh > 0 && mrr >= 0)
|
||||
{
|
||||
m_pp.Windowed = FALSE;
|
||||
m_pp.BackBufferWidth = mw;
|
||||
|
@ -324,27 +336,39 @@ bool GSDevice9::Reset(int w, int h, bool fs)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GSDevice9::IsLost()
|
||||
bool GSDevice9::IsLost(bool update)
|
||||
{
|
||||
HRESULT hr = m_dev->TestCooperativeLevel();
|
||||
|
||||
return hr == D3DERR_DEVICELOST || hr == D3DERR_DEVICENOTRESET;
|
||||
if(!m_lost || update)
|
||||
{
|
||||
HRESULT hr = m_dev->TestCooperativeLevel();
|
||||
|
||||
m_lost = hr == D3DERR_DEVICELOST || hr == D3DERR_DEVICENOTRESET;
|
||||
}
|
||||
|
||||
return m_lost;
|
||||
}
|
||||
|
||||
void GSDevice9::Flip()
|
||||
{
|
||||
m_dev->EndScene();
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
if(m_swapchain)
|
||||
{
|
||||
m_swapchain->Present(NULL, NULL, NULL, NULL, 0);
|
||||
hr = m_swapchain->Present(NULL, NULL, NULL, NULL, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dev->Present(NULL, NULL, NULL, NULL);
|
||||
hr = m_dev->Present(NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
m_dev->BeginScene();
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
m_lost = true;
|
||||
}
|
||||
}
|
||||
|
||||
void GSDevice9::BeginScene()
|
||||
|
@ -549,6 +573,11 @@ GSTexture* GSDevice9::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w,
|
|||
return dst;
|
||||
}
|
||||
|
||||
void GSDevice9::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
|
||||
{
|
||||
m_dev->StretchRect(*(GSTexture9*)st, r, *(GSTexture9*)dt, r, D3DTEXF_POINT);
|
||||
}
|
||||
|
||||
void GSDevice9::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader, bool linear)
|
||||
{
|
||||
StretchRect(st, sr, dt, dr, m_convert.ps[shader], NULL, 0, linear);
|
||||
|
@ -663,7 +692,7 @@ void GSDevice9::IASetVertexBuffer(const void* vertices, size_t stride, size_t co
|
|||
m_vertices.vb = NULL;
|
||||
m_vertices.start = 0;
|
||||
m_vertices.count = 0;
|
||||
m_vertices.limit = max(count * 3 / 2, 10000);
|
||||
m_vertices.limit = std::max<int>(count * 3 / 2, 10000);
|
||||
}
|
||||
|
||||
if(m_vertices.vb == NULL)
|
||||
|
@ -817,16 +846,16 @@ void GSDevice9::PSSetSamplerState(Direct3DSamplerState9* ss)
|
|||
|
||||
m_dev->SetSamplerState(0, D3DSAMP_ADDRESSU, ss->AddressU);
|
||||
m_dev->SetSamplerState(0, D3DSAMP_ADDRESSV, ss->AddressV);
|
||||
m_dev->SetSamplerState(1, D3DSAMP_ADDRESSU, ss->AddressU);
|
||||
m_dev->SetSamplerState(1, D3DSAMP_ADDRESSV, ss->AddressV);
|
||||
m_dev->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
m_dev->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
m_dev->SetSamplerState(2, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
|
||||
m_dev->SetSamplerState(2, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
|
||||
m_dev->SetSamplerState(3, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
|
||||
m_dev->SetSamplerState(3, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
|
||||
m_dev->SetSamplerState(0, D3DSAMP_MINFILTER, ss->FilterMin[0]);
|
||||
m_dev->SetSamplerState(0, D3DSAMP_MAGFILTER, ss->FilterMag[0]);
|
||||
m_dev->SetSamplerState(1, D3DSAMP_MINFILTER, ss->FilterMin[1]);
|
||||
m_dev->SetSamplerState(1, D3DSAMP_MAGFILTER, ss->FilterMag[1]);
|
||||
m_dev->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_POINT);
|
||||
m_dev->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
|
||||
m_dev->SetSamplerState(2, D3DSAMP_MINFILTER, D3DTEXF_POINT);
|
||||
m_dev->SetSamplerState(2, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
|
||||
m_dev->SetSamplerState(3, D3DSAMP_MINFILTER, D3DTEXF_POINT);
|
||||
|
|
|
@ -92,9 +92,11 @@ private:
|
|||
|
||||
DDCAPS m_ddcaps;
|
||||
D3DCAPS9 m_d3dcaps;
|
||||
D3DPRESENT_PARAMETERS m_pp;
|
||||
CComPtr<IDirect3D9> m_d3d;
|
||||
CComPtr<IDirect3DDevice9> m_dev;
|
||||
CComPtr<IDirect3DSwapChain9> m_swapchain;
|
||||
bool m_lost;
|
||||
|
||||
struct
|
||||
{
|
||||
|
@ -103,7 +105,6 @@ private:
|
|||
} m_vertices;
|
||||
|
||||
public: // TODO
|
||||
D3DPRESENT_PARAMETERS m_pp;
|
||||
|
||||
struct
|
||||
{
|
||||
|
@ -132,9 +133,8 @@ public:
|
|||
virtual ~GSDevice9();
|
||||
|
||||
bool Create(GSWnd* wnd, bool vsync);
|
||||
bool Reset(int w, int h, bool fs);
|
||||
|
||||
bool IsLost();
|
||||
bool Reset(int w, int h, int mode);
|
||||
bool IsLost(bool update);
|
||||
void Flip();
|
||||
|
||||
void BeginScene();
|
||||
|
@ -153,7 +153,7 @@ public:
|
|||
|
||||
GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0);
|
||||
|
||||
virtual bool IsCurrentRGBA() {return false;}
|
||||
void CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r);
|
||||
|
||||
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true);
|
||||
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, IDirect3DPixelShader9* ps, const float* ps_cb, int ps_cb_len, bool linear = true);
|
||||
|
|
|
@ -29,14 +29,14 @@ bool GSDeviceNull::Create(GSWnd* wnd, bool vsync)
|
|||
return false;
|
||||
}
|
||||
|
||||
Reset(1, 1, false);
|
||||
Reset(1, 1, Windowed);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSDeviceNull::Reset(int w, int h, bool fs)
|
||||
bool GSDeviceNull::Reset(int w, int h, int mode)
|
||||
{
|
||||
if(!__super::Reset(w, h, fs))
|
||||
if(!__super::Reset(w, h, mode))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
|
|
@ -36,5 +36,5 @@ public:
|
|||
GSDeviceNull() {}
|
||||
|
||||
bool Create(GSWnd* wnd, bool vsync);
|
||||
bool Reset(int w, int h, bool fs);
|
||||
bool Reset(int w, int h, int mode);
|
||||
};
|
||||
|
|
|
@ -150,14 +150,14 @@ bool GSDeviceOGL::Create(GSWnd* wnd, bool vsync)
|
|||
*/
|
||||
GSVector4i r = wnd->GetClientRect();
|
||||
|
||||
Reset(r.width(), r.height(), false);
|
||||
Reset(r.width(), r.height(), Windowed);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSDeviceOGL::Reset(int w, int h, bool fs)
|
||||
bool GSDeviceOGL::Reset(int w, int h, int mode)
|
||||
{
|
||||
if(!__super::Reset(w, h, fs))
|
||||
if(!__super::Reset(w, h, mode))
|
||||
return false;
|
||||
|
||||
glCullFace(GL_FRONT_AND_BACK); CheckError();
|
||||
|
@ -333,6 +333,11 @@ GSTexture* GSDeviceOGL::CopyOffscreen(GSTexture* src, const GSVector4& sr, int w
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void GSDeviceOGL::CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
void GSDeviceOGL::StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader, bool linear)
|
||||
{
|
||||
// TODO
|
||||
|
@ -361,7 +366,7 @@ void GSDeviceOGL::IASetVertexBuffer(const void* vertices, size_t stride, size_t
|
|||
{
|
||||
m_vertices.start = 0;
|
||||
m_vertices.count = 0;
|
||||
m_vertices.limit = max(count * 3 / 2, 10000);
|
||||
m_vertices.limit = std::max<int>(count * 3 / 2, 10000);
|
||||
|
||||
growbuffer = true;
|
||||
}
|
||||
|
|
|
@ -110,8 +110,7 @@ public:
|
|||
virtual ~GSDeviceOGL();
|
||||
|
||||
bool Create(GSWnd* wnd, bool vsync);
|
||||
bool Reset(int w, int h, bool fs);
|
||||
|
||||
bool Reset(int w, int h, int mode);
|
||||
void Present(const GSVector4i& r, int shader);
|
||||
void Flip();
|
||||
|
||||
|
@ -131,6 +130,8 @@ public:
|
|||
|
||||
GSTexture* CopyOffscreen(GSTexture* src, const GSVector4& sr, int w, int h, int format = 0);
|
||||
|
||||
void CopyRect(GSTexture* st, GSTexture* dt, const GSVector4i& r);
|
||||
|
||||
void StretchRect(GSTexture* st, const GSVector4& sr, GSTexture* dt, const GSVector4& dr, int shader = 0, bool linear = true);
|
||||
|
||||
void IASetVertexBuffer(const void* vertices, size_t stride, size_t count);
|
||||
|
|
|
@ -48,8 +48,8 @@ void GSDrawScanline::BeginDraw(const GSRasterizerData* data, Functions* f)
|
|||
m_env.vm = p->vm;
|
||||
m_env.fbr = p->fbo->row;
|
||||
m_env.zbr = p->zbo->row;
|
||||
m_env.fbc = p->fbo->col;
|
||||
m_env.zbc = p->zbo->col;
|
||||
m_env.fbc = p->fbo->col[0];
|
||||
m_env.zbc = p->zbo->col[0];
|
||||
m_env.fzbr = p->fzbo->row;
|
||||
m_env.fzbc = p->fzbo->col;
|
||||
m_env.fm = GSVector4i(p->fm);
|
||||
|
@ -116,8 +116,8 @@ void GSDrawScanline::BeginDraw(const GSRasterizerData* data, Functions* f)
|
|||
m_env.t.mask.u32[0] = 0;
|
||||
break;
|
||||
case CLAMP_REGION_CLAMP:
|
||||
m_env.t.min.u16[0] = min(context->CLAMP.MINU, tw - 1);
|
||||
m_env.t.max.u16[0] = min(context->CLAMP.MAXU, tw - 1);
|
||||
m_env.t.min.u16[0] = std::min<int>(context->CLAMP.MINU, tw - 1);
|
||||
m_env.t.max.u16[0] = std::min<int>(context->CLAMP.MAXU, tw - 1);
|
||||
m_env.t.mask.u32[0] = 0;
|
||||
break;
|
||||
case CLAMP_REGION_REPEAT:
|
||||
|
@ -142,8 +142,8 @@ void GSDrawScanline::BeginDraw(const GSRasterizerData* data, Functions* f)
|
|||
m_env.t.mask.u32[2] = 0;
|
||||
break;
|
||||
case CLAMP_REGION_CLAMP:
|
||||
m_env.t.min.u16[4] = min(context->CLAMP.MINV, th - 1);
|
||||
m_env.t.max.u16[4] = min(context->CLAMP.MAXV, th - 1); // ffx anima summon scene, when the anchor appears (th = 256, maxv > 256)
|
||||
m_env.t.min.u16[4] = std::min<int>(context->CLAMP.MINV, th - 1);
|
||||
m_env.t.max.u16[4] = std::min<int>(context->CLAMP.MAXV, th - 1); // ffx anima summon scene, when the anchor appears (th = 256, maxv > 256)
|
||||
m_env.t.mask.u32[2] = 0;
|
||||
break;
|
||||
case CLAMP_REGION_REPEAT:
|
||||
|
@ -224,22 +224,22 @@ void GSDrawScanline::DrawSolidRect(const GSVector4i& r, const GSVertexSW& v)
|
|||
{
|
||||
if(m == 0)
|
||||
{
|
||||
DrawSolidRectT<uint32, false>(m_env.zbr, m_env.zbc[0], r, z, m);
|
||||
DrawSolidRectT<uint32, false>(m_env.zbr, m_env.zbc, r, z, m);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawSolidRectT<uint32, true>(m_env.zbr, m_env.zbc[0], r, z, m);
|
||||
DrawSolidRectT<uint32, true>(m_env.zbr, m_env.zbc, r, z, m);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m == 0)
|
||||
{
|
||||
DrawSolidRectT<uint16, false>(m_env.zbr, m_env.zbc[0], r, z, m);
|
||||
DrawSolidRectT<uint16, false>(m_env.zbr, m_env.zbc, r, z, m);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawSolidRectT<uint16, true>(m_env.zbr, m_env.zbc[0], r, z, m);
|
||||
DrawSolidRectT<uint16, true>(m_env.zbr, m_env.zbc, r, z, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -259,11 +259,11 @@ void GSDrawScanline::DrawSolidRect(const GSVector4i& r, const GSVertexSW& v)
|
|||
{
|
||||
if(m == 0)
|
||||
{
|
||||
DrawSolidRectT<uint32, false>(m_env.fbr, m_env.fbc[0], r, c, m);
|
||||
DrawSolidRectT<uint32, false>(m_env.fbr, m_env.fbc, r, c, m);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawSolidRectT<uint32, true>(m_env.fbr, m_env.fbc[0], r, c, m);
|
||||
DrawSolidRectT<uint32, true>(m_env.fbr, m_env.fbc, r, c, m);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -272,18 +272,18 @@ void GSDrawScanline::DrawSolidRect(const GSVector4i& r, const GSVertexSW& v)
|
|||
|
||||
if(m == 0)
|
||||
{
|
||||
DrawSolidRectT<uint16, false>(m_env.fbr, m_env.fbc[0], r, c, m);
|
||||
DrawSolidRectT<uint16, false>(m_env.fbr, m_env.fbc, r, c, m);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawSolidRectT<uint16, true>(m_env.fbr, m_env.fbc[0], r, c, m);
|
||||
DrawSolidRectT<uint16, true>(m_env.fbr, m_env.fbc, r, c, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, bool masked>
|
||||
void GSDrawScanline::DrawSolidRectT(const GSVector4i* row, int* col, const GSVector4i& r, uint32 c, uint32 m)
|
||||
void GSDrawScanline::DrawSolidRectT(const int* RESTRICT row, const int* RESTRICT col, const GSVector4i& r, uint32 c, uint32 m)
|
||||
{
|
||||
if(m == 0xffffffff) return;
|
||||
|
||||
|
@ -320,35 +320,33 @@ void GSDrawScanline::DrawSolidRectT(const GSVector4i* row, int* col, const GSVec
|
|||
}
|
||||
|
||||
template<class T, bool masked>
|
||||
void GSDrawScanline::FillRect(const GSVector4i* row, int* col, const GSVector4i& r, uint32 c, uint32 m)
|
||||
void GSDrawScanline::FillRect(const int* RESTRICT row, const int* RESTRICT col, const GSVector4i& r, uint32 c, uint32 m)
|
||||
{
|
||||
if(r.x >= r.z) return;
|
||||
|
||||
for(int y = r.y; y < r.w; y++)
|
||||
{
|
||||
uint32 base = row[y].x;
|
||||
T* RESTRICT d = &((T*)m_env.vm)[row[y]];
|
||||
|
||||
for(int x = r.x; x < r.z; x++)
|
||||
{
|
||||
T* p = &((T*)m_env.vm)[base + col[x]];
|
||||
|
||||
*p = (T)(!masked ? c : (c | (*p & m)));
|
||||
d[col[x]] = (T)(!masked ? c : (c | (d[col[x]] & m)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, bool masked>
|
||||
void GSDrawScanline::FillBlock(const GSVector4i* row, int* col, const GSVector4i& r, const GSVector4i& c, const GSVector4i& m)
|
||||
void GSDrawScanline::FillBlock(const int* RESTRICT row, const int* RESTRICT col, const GSVector4i& r, const GSVector4i& c, const GSVector4i& m)
|
||||
{
|
||||
if(r.x >= r.z) return;
|
||||
|
||||
for(int y = r.y; y < r.w; y += 8)
|
||||
{
|
||||
uint32 base = row[y].x;
|
||||
T* RESTRICT d = &((T*)m_env.vm)[row[y]];
|
||||
|
||||
for(int x = r.x; x < r.z; x += 8 * 4 / sizeof(T))
|
||||
{
|
||||
GSVector4i* p = (GSVector4i*)&((T*)m_env.vm)[base + col[x]];
|
||||
GSVector4i* RESTRICT p = (GSVector4i*)&d[col[x]];
|
||||
|
||||
for(int i = 0; i < 16; i += 4)
|
||||
{
|
||||
|
|
|
@ -26,9 +26,8 @@
|
|||
#include "GSScanlineEnvironment.h"
|
||||
#include "GSSetupPrimCodeGenerator.h"
|
||||
#include "GSDrawScanlineCodeGenerator.h"
|
||||
#include "GSAlignedClass.h"
|
||||
|
||||
class GSDrawScanline : public GSAlignedClass<16>, public IDrawScanline
|
||||
class GSDrawScanline : public IDrawScanline
|
||||
{
|
||||
GSScanlineEnvironment m_env;
|
||||
GSScanlineSelector m_sel;
|
||||
|
@ -60,13 +59,13 @@ class GSDrawScanline : public GSAlignedClass<16>, public IDrawScanline
|
|||
void DrawSolidRect(const GSVector4i& r, const GSVertexSW& v);
|
||||
|
||||
template<class T, bool masked>
|
||||
void DrawSolidRectT(const GSVector4i* row, int* col, const GSVector4i& r, uint32 c, uint32 m);
|
||||
void DrawSolidRectT(const int* RESTRICT row, const int* RESTRICT col, const GSVector4i& r, uint32 c, uint32 m);
|
||||
|
||||
template<class T, bool masked>
|
||||
__forceinline void FillRect(const GSVector4i* row, int* col, const GSVector4i& r, uint32 c, uint32 m);
|
||||
__forceinline void FillRect(const int* RESTRICT row, const int* RESTRICT col, const GSVector4i& r, uint32 c, uint32 m);
|
||||
|
||||
template<class T, bool masked>
|
||||
__forceinline void FillBlock(const GSVector4i* row, int* col, const GSVector4i& r, const GSVector4i& c, const GSVector4i& m);
|
||||
__forceinline void FillBlock(const int* RESTRICT row, const int* RESTRICT col, const GSVector4i& r, const GSVector4i& c, const GSVector4i& m);
|
||||
|
||||
protected:
|
||||
GSState* m_state;
|
||||
|
|
|
@ -66,10 +66,7 @@ public:
|
|||
|
||||
virtual ~GSFunctionMap()
|
||||
{
|
||||
for(hash_map<KEY, ActivePtr*>::iterator i = m_map_active.begin(); i != m_map_active.end(); i++)
|
||||
{
|
||||
delete i->second;
|
||||
}
|
||||
for_each(m_map_active.begin(), m_map_active.end(), delete_second());
|
||||
}
|
||||
|
||||
VALUE operator [] (KEY key)
|
||||
|
@ -177,10 +174,7 @@ public:
|
|||
|
||||
virtual ~GSCodeGeneratorFunctionMap()
|
||||
{
|
||||
for(hash_map<uint64, CG*>::iterator i = m_cgmap.begin(); i != m_cgmap.end(); i++)
|
||||
{
|
||||
delete i->second;
|
||||
}
|
||||
for_each(m_cgmap.begin(), m_cgmap.end(), delete_second());
|
||||
}
|
||||
|
||||
VALUE GetDefaultFunction(KEY key)
|
||||
|
|
|
@ -28,19 +28,21 @@
|
|||
#include "GSLocalMemory.h"
|
||||
|
||||
#define ASSERT_BLOCK(r, w, h) \
|
||||
ASSERT((r).width() >= w && (r).height() >= h && !((r).left&(w-1)) && !((r).top&(h-1)) && !((r).right&(w-1)) && !((r).bottom&(h-1))); \
|
||||
ASSERT((r).width() >= w && (r).height() >= h && !((r).left & (w - 1)) && !((r).top & (h - 1)) && !((r).right & (w - 1)) && !((r).bottom & (h - 1))); \
|
||||
|
||||
#define FOREACH_BLOCK_START(w, h, bpp, format) \
|
||||
const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[format]; \
|
||||
uint32 bp = TEX0.TBP0; \
|
||||
uint32 bw = TEX0.TBW; \
|
||||
int offset = dstpitch * h - r.width() * bpp / 8; \
|
||||
for(int y = r.top, ye = r.bottom; y < ye; y += h, dst += offset) \
|
||||
{ ASSERT_BLOCK(r, w, h); \
|
||||
uint32 base = psm.bn(0, y, bp, bw); \
|
||||
for(int x = r.left, xe = r.right; x < xe; x += w, dst += w * bpp / 8) \
|
||||
#define FOREACH_BLOCK_START(r, w, h, bpp, psm) \
|
||||
ASSERT_BLOCK(r, w, h); \
|
||||
const GSLocalMemory::BlockOffset* RESTRICT _bo = GetBlockOffset(TEX0.TBP0, TEX0.TBW, psm); \
|
||||
GSVector4i _r = r >> 3; \
|
||||
uint8* _dst = dst - _r.left * bpp; \
|
||||
int _offset = dstpitch * h; \
|
||||
for(int y = _r.top; y < _r.bottom; y += h >> 3, _dst += _offset) \
|
||||
{ \
|
||||
uint32 _base = _bo->row[y]; \
|
||||
for(int x = _r.left; x < _r.right; x += w >> 3) \
|
||||
{ \
|
||||
const uint8* src = BlockPtr(base + psm.blockOffset[x >> 3]); \
|
||||
const uint8* src = BlockPtr(_base + _bo->col[x]); \
|
||||
uint8* dst = &_dst[x * bpp]; \
|
||||
|
||||
#define FOREACH_BLOCK_END }}
|
||||
|
||||
|
@ -463,37 +465,52 @@ GSLocalMemory::~GSLocalMemory()
|
|||
{
|
||||
VirtualFree(m_vm8, 0, MEM_RELEASE);
|
||||
|
||||
for(hash_map<uint32, Offset*>::iterator i = m_omap.begin(); i != m_omap.end(); i++)
|
||||
{
|
||||
Offset* o = i->second;
|
||||
|
||||
_aligned_free(o->col[0]);
|
||||
|
||||
_aligned_free(o);
|
||||
}
|
||||
|
||||
for(hash_map<uint32, Offset4*>::iterator i = m_o4map.begin(); i != m_o4map.end(); i++)
|
||||
{
|
||||
_aligned_free(i->second);
|
||||
}
|
||||
for_each(m_bomap.begin(), m_bomap.end(), aligned_free_second());
|
||||
for_each(m_pomap.begin(), m_pomap.end(), aligned_free_second());
|
||||
for_each(m_po4map.begin(), m_po4map.end(), aligned_free_second());
|
||||
}
|
||||
|
||||
GSLocalMemory::Offset* GSLocalMemory::GetOffset(uint32 bp, uint32 bw, uint32 psm)
|
||||
GSLocalMemory::BlockOffset* GSLocalMemory::GetBlockOffset(uint32 bp, uint32 bw, uint32 psm)
|
||||
{
|
||||
if(bw == 0) {ASSERT(0); return NULL;}
|
||||
|
||||
ASSERT(m_psm[psm].bpp > 8); // only for 16/24/32/8h/4hh/4hl formats where all columns are the same
|
||||
|
||||
uint32 hash = bp | (bw << 14) | (psm << 20);
|
||||
|
||||
hash_map<uint32, Offset*>::iterator i = m_omap.find(hash);
|
||||
hash_map<uint32, BlockOffset*>::iterator i = m_bomap.find(hash);
|
||||
|
||||
if(i != m_omap.end())
|
||||
if(i != m_bomap.end())
|
||||
{
|
||||
return i->second;
|
||||
}
|
||||
|
||||
Offset* o = (Offset*)_aligned_malloc(sizeof(Offset), 16);
|
||||
BlockOffset* o = (BlockOffset*)_aligned_malloc(sizeof(BlockOffset), 16);
|
||||
|
||||
o->hash = hash;
|
||||
|
||||
pixelAddress bn = m_psm[psm].bn;
|
||||
|
||||
for(int i = 0; i < 256; i++)
|
||||
{
|
||||
o->row[i] = (int)bn(0, i << 3, bp, bw);
|
||||
}
|
||||
|
||||
o->col = m_psm[psm].blockOffset;
|
||||
|
||||
m_bomap[hash] = o;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
GSLocalMemory::PixelOffset* GSLocalMemory::GetPixelOffset(uint32 bp, uint32 bw, uint32 psm)
|
||||
{
|
||||
uint32 hash = bp | (bw << 14) | (psm << 20);
|
||||
|
||||
hash_map<uint32, PixelOffset*>::iterator i = m_pomap.find(hash);
|
||||
|
||||
if(i != m_pomap.end())
|
||||
{
|
||||
return i->second;
|
||||
}
|
||||
|
||||
PixelOffset* o = (PixelOffset*)_aligned_malloc(sizeof(PixelOffset), 16);
|
||||
|
||||
o->hash = hash;
|
||||
|
||||
|
@ -501,24 +518,20 @@ GSLocalMemory::Offset* GSLocalMemory::GetOffset(uint32 bp, uint32 bw, uint32 psm
|
|||
|
||||
for(int i = 0; i < 2048; i++)
|
||||
{
|
||||
o->row[i] = GSVector4i((int)pa(0, i, bp, bw));
|
||||
o->row[i] = (int)pa(0, i, bp, bw);
|
||||
}
|
||||
|
||||
int* p = (int*)_aligned_malloc(sizeof(int) * (2048 + 3) * 4, 16);
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
o->col[i] = &p[2048 * i + ((4 - (i & 3)) & 3)];
|
||||
|
||||
memcpy(o->col[i], m_psm[psm].rowOffset[0], sizeof(int) * 2048);
|
||||
o->col[i] = m_psm[psm].rowOffset[i];
|
||||
}
|
||||
|
||||
m_omap[hash] = o;
|
||||
m_pomap[hash] = o;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
GSLocalMemory::Offset4* GSLocalMemory::GetOffset4(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF)
|
||||
GSLocalMemory::PixelOffset4* GSLocalMemory::GetPixelOffset4(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF)
|
||||
{
|
||||
uint32 fbp = FRAME.Block();
|
||||
uint32 zbp = ZBUF.Block();
|
||||
|
@ -535,14 +548,14 @@ GSLocalMemory::Offset4* GSLocalMemory::GetOffset4(const GIFRegFRAME& FRAME, cons
|
|||
|
||||
uint32 hash = (FRAME.FBP << 0) | (ZBUF.ZBP << 9) | (bw << 18) | (fpsm_hash << 24) | (zpsm_hash << 28);
|
||||
|
||||
hash_map<uint32, Offset4*>::iterator i = m_o4map.find(hash);
|
||||
hash_map<uint32, PixelOffset4*>::iterator i = m_po4map.find(hash);
|
||||
|
||||
if(i != m_o4map.end())
|
||||
if(i != m_po4map.end())
|
||||
{
|
||||
return i->second;
|
||||
}
|
||||
|
||||
Offset4* o = (Offset4*)_aligned_malloc(sizeof(Offset4), 16);
|
||||
PixelOffset4* o = (PixelOffset4*)_aligned_malloc(sizeof(PixelOffset4), 16);
|
||||
|
||||
o->hash = hash;
|
||||
|
||||
|
@ -564,7 +577,7 @@ GSLocalMemory::Offset4* GSLocalMemory::GetOffset4(const GIFRegFRAME& FRAME, cons
|
|||
o->col[i].y = m_psm[zpsm].rowOffset[0][i * 4] << zs;
|
||||
}
|
||||
|
||||
m_o4map[hash] = o;
|
||||
m_po4map[hash] = o;
|
||||
|
||||
return o;
|
||||
}
|
||||
|
@ -1436,20 +1449,20 @@ void GSLocalMemory::ReadImageX(int& tx, int& ty, uint8* dst, int len, GIFRegBITB
|
|||
|
||||
///////////////////
|
||||
|
||||
void GSLocalMemory::ReadTexture32(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture32(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
FOREACH_BLOCK_START(8, 8, 32, PSM_PSMCT32)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMCT32)
|
||||
{
|
||||
ReadBlock32<true>(src, dst, dstpitch);
|
||||
}
|
||||
FOREACH_BLOCK_END
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture24(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture24(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
if(TEXA.AEM)
|
||||
{
|
||||
FOREACH_BLOCK_START(8, 8, 32, PSM_PSMCT24)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMCT24)
|
||||
{
|
||||
ReadAndExpandBlock24<true>(src, dst, dstpitch, TEXA);
|
||||
}
|
||||
|
@ -1457,7 +1470,7 @@ void GSLocalMemory::ReadTexture24(const GSVector4i& r, uint8* dst, int dstpitch,
|
|||
}
|
||||
else
|
||||
{
|
||||
FOREACH_BLOCK_START(8, 8, 32, PSM_PSMCT24)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMCT24)
|
||||
{
|
||||
ReadAndExpandBlock24<false>(src, dst, dstpitch, TEXA);
|
||||
}
|
||||
|
@ -1465,11 +1478,11 @@ void GSLocalMemory::ReadTexture24(const GSVector4i& r, uint8* dst, int dstpitch,
|
|||
}
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture16(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture16(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
__declspec(align(16)) uint16 block[16 * 8];
|
||||
|
||||
FOREACH_BLOCK_START(16, 8, 32, PSM_PSMCT16)
|
||||
FOREACH_BLOCK_START(r, 16, 8, 32, PSM_PSMCT16)
|
||||
{
|
||||
ReadBlock16<true>(src, (uint8*)block, sizeof(block) / 8);
|
||||
|
||||
|
@ -1478,11 +1491,11 @@ void GSLocalMemory::ReadTexture16(const GSVector4i& r, uint8* dst, int dstpitch,
|
|||
FOREACH_BLOCK_END
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture16S(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture16S(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
__declspec(align(16)) uint16 block[16 * 8];
|
||||
|
||||
FOREACH_BLOCK_START(16, 8, 32, PSM_PSMCT16S)
|
||||
FOREACH_BLOCK_START(r, 16, 8, 32, PSM_PSMCT16S)
|
||||
{
|
||||
ReadBlock16<true>(src, (uint8*)block, sizeof(block) / 8);
|
||||
|
||||
|
@ -1491,75 +1504,75 @@ void GSLocalMemory::ReadTexture16S(const GSVector4i& r, uint8* dst, int dstpitch
|
|||
FOREACH_BLOCK_END
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture8(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture8(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
const uint32* pal = m_clut;
|
||||
|
||||
FOREACH_BLOCK_START(16, 16, 32, PSM_PSMT8)
|
||||
FOREACH_BLOCK_START(r, 16, 16, 32, PSM_PSMT8)
|
||||
{
|
||||
ReadAndExpandBlock8_32(src, dst, dstpitch, pal);
|
||||
}
|
||||
FOREACH_BLOCK_END
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture4(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture4(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
const uint64* pal = m_clut;
|
||||
|
||||
FOREACH_BLOCK_START(32, 16, 32, PSM_PSMT4)
|
||||
FOREACH_BLOCK_START(r, 32, 16, 32, PSM_PSMT4)
|
||||
{
|
||||
ReadAndExpandBlock4_32(src, dst, dstpitch, pal);
|
||||
}
|
||||
FOREACH_BLOCK_END
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture8H(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture8H(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
const uint32* pal = m_clut;
|
||||
|
||||
FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT8H)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMT8H)
|
||||
{
|
||||
ReadAndExpandBlock8H_32(src, dst, dstpitch, pal);
|
||||
}
|
||||
FOREACH_BLOCK_END
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture4HL(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture4HL(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
const uint32* pal = m_clut;
|
||||
|
||||
FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT4HL)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMT4HL)
|
||||
{
|
||||
ReadAndExpandBlock4HL_32(src, dst, dstpitch, pal);
|
||||
}
|
||||
FOREACH_BLOCK_END
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture4HH(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture4HH(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
const uint32* pal = m_clut;
|
||||
|
||||
FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT4HH)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMT4HH)
|
||||
{
|
||||
ReadAndExpandBlock4HH_32(src, dst, dstpitch, pal);
|
||||
}
|
||||
FOREACH_BLOCK_END
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture32Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture32Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
FOREACH_BLOCK_START(8, 8, 32, PSM_PSMZ32)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMZ32)
|
||||
{
|
||||
ReadBlock32<true>(src, dst, dstpitch);
|
||||
}
|
||||
FOREACH_BLOCK_END
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture24Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture24Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
if(TEXA.AEM)
|
||||
{
|
||||
FOREACH_BLOCK_START(8, 8, 32, PSM_PSMZ24)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMZ24)
|
||||
{
|
||||
ReadAndExpandBlock24<true>(src, dst, dstpitch, TEXA);
|
||||
}
|
||||
|
@ -1567,7 +1580,7 @@ void GSLocalMemory::ReadTexture24Z(const GSVector4i& r, uint8* dst, int dstpitch
|
|||
}
|
||||
else
|
||||
{
|
||||
FOREACH_BLOCK_START(8, 8, 32, PSM_PSMZ24)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMZ24)
|
||||
{
|
||||
ReadAndExpandBlock24<false>(src, dst, dstpitch, TEXA);
|
||||
}
|
||||
|
@ -1575,11 +1588,11 @@ void GSLocalMemory::ReadTexture24Z(const GSVector4i& r, uint8* dst, int dstpitch
|
|||
}
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture16Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture16Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
__declspec(align(16)) uint16 block[16 * 8];
|
||||
|
||||
FOREACH_BLOCK_START(16, 8, 32, PSM_PSMZ16)
|
||||
FOREACH_BLOCK_START(r, 16, 8, 32, PSM_PSMZ16)
|
||||
{
|
||||
ReadBlock16<true>(src, (uint8*)block, sizeof(block) / 8);
|
||||
|
||||
|
@ -1588,11 +1601,11 @@ void GSLocalMemory::ReadTexture16Z(const GSVector4i& r, uint8* dst, int dstpitch
|
|||
FOREACH_BLOCK_END
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture16SZ(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture16SZ(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
__declspec(align(16)) uint16 block[16 * 8];
|
||||
|
||||
FOREACH_BLOCK_START(16, 8, 32, PSM_PSMZ16S)
|
||||
FOREACH_BLOCK_START(r, 16, 8, 32, PSM_PSMZ16S)
|
||||
{
|
||||
ReadBlock16<true>(src, (uint8*)block, sizeof(block) / 8);
|
||||
|
||||
|
@ -1737,31 +1750,31 @@ void GSLocalMemory::ReadTexture(const GSVector4i& r, uint8* dst, int dstpitch, c
|
|||
}
|
||||
///////////////////
|
||||
|
||||
void GSLocalMemory::ReadTexture16NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture16NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
FOREACH_BLOCK_START(16, 8, 16, PSM_PSMCT16)
|
||||
FOREACH_BLOCK_START(r, 16, 8, 16, PSM_PSMCT16)
|
||||
{
|
||||
ReadBlock16<true>(src, dst, dstpitch);
|
||||
}
|
||||
FOREACH_BLOCK_END
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture16SNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture16SNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
FOREACH_BLOCK_START(16, 8, 16, PSM_PSMCT16S)
|
||||
FOREACH_BLOCK_START(r, 16, 8, 16, PSM_PSMCT16S)
|
||||
{
|
||||
ReadBlock16<true>(src, dst, dstpitch);
|
||||
}
|
||||
FOREACH_BLOCK_END
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture8NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture8NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
const uint32* pal = m_clut;
|
||||
|
||||
if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24)
|
||||
{
|
||||
FOREACH_BLOCK_START(16, 16, 32, PSM_PSMT8)
|
||||
FOREACH_BLOCK_START(r, 16, 16, 32, PSM_PSMT8)
|
||||
{
|
||||
ReadAndExpandBlock8_32(src, dst, dstpitch, pal);
|
||||
}
|
||||
|
@ -1773,7 +1786,7 @@ void GSLocalMemory::ReadTexture8NP(const GSVector4i& r, uint8* dst, int dstpitch
|
|||
|
||||
__declspec(align(16)) uint8 block[16 * 16];
|
||||
|
||||
FOREACH_BLOCK_START(16, 16, 16, PSM_PSMT8)
|
||||
FOREACH_BLOCK_START(r, 16, 16, 16, PSM_PSMT8)
|
||||
{
|
||||
ReadBlock8<true>(src, (uint8*)block, sizeof(block) / 16);
|
||||
|
||||
|
@ -1783,13 +1796,13 @@ void GSLocalMemory::ReadTexture8NP(const GSVector4i& r, uint8* dst, int dstpitch
|
|||
}
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture4NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture4NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
const uint64* pal = m_clut;
|
||||
|
||||
if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24)
|
||||
{
|
||||
FOREACH_BLOCK_START(32, 16, 32, PSM_PSMT4)
|
||||
FOREACH_BLOCK_START(r, 32, 16, 32, PSM_PSMT4)
|
||||
{
|
||||
ReadAndExpandBlock4_32(src, dst, dstpitch, pal);
|
||||
}
|
||||
|
@ -1801,7 +1814,7 @@ void GSLocalMemory::ReadTexture4NP(const GSVector4i& r, uint8* dst, int dstpitch
|
|||
|
||||
__declspec(align(16)) uint8 block[(32 / 2) * 16];
|
||||
|
||||
FOREACH_BLOCK_START(32, 16, 16, PSM_PSMT4)
|
||||
FOREACH_BLOCK_START(r, 32, 16, 16, PSM_PSMT4)
|
||||
{
|
||||
ReadBlock4<true>(src, (uint8*)block, sizeof(block) / 16);
|
||||
|
||||
|
@ -1811,13 +1824,13 @@ void GSLocalMemory::ReadTexture4NP(const GSVector4i& r, uint8* dst, int dstpitch
|
|||
}
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture8HNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture8HNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
const uint32* pal = m_clut;
|
||||
|
||||
if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24)
|
||||
{
|
||||
FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT8H)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMT8H)
|
||||
{
|
||||
ReadAndExpandBlock8H_32(src, dst, dstpitch, pal);
|
||||
}
|
||||
|
@ -1829,7 +1842,7 @@ void GSLocalMemory::ReadTexture8HNP(const GSVector4i& r, uint8* dst, int dstpitc
|
|||
|
||||
__declspec(align(16)) uint32 block[8 * 8];
|
||||
|
||||
FOREACH_BLOCK_START(8, 8, 16, PSM_PSMT8H)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 16, PSM_PSMT8H)
|
||||
{
|
||||
ReadBlock32<true>(src, (uint8*)block, sizeof(block) / 8);
|
||||
|
||||
|
@ -1839,13 +1852,13 @@ void GSLocalMemory::ReadTexture8HNP(const GSVector4i& r, uint8* dst, int dstpitc
|
|||
}
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture4HLNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture4HLNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
const uint32* pal = m_clut;
|
||||
|
||||
if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24)
|
||||
{
|
||||
FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT4HL)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMT4HL)
|
||||
{
|
||||
ReadAndExpandBlock4HL_32(src, dst, dstpitch, pal);
|
||||
}
|
||||
|
@ -1857,7 +1870,7 @@ void GSLocalMemory::ReadTexture4HLNP(const GSVector4i& r, uint8* dst, int dstpit
|
|||
|
||||
__declspec(align(16)) uint32 block[8 * 8];
|
||||
|
||||
FOREACH_BLOCK_START(8, 8, 16, PSM_PSMT4HL)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 16, PSM_PSMT4HL)
|
||||
{
|
||||
ReadBlock32<true>(src, (uint8*)block, sizeof(block) / 8);
|
||||
|
||||
|
@ -1867,13 +1880,13 @@ void GSLocalMemory::ReadTexture4HLNP(const GSVector4i& r, uint8* dst, int dstpit
|
|||
}
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture4HHNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture4HHNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
const uint32* pal = m_clut;
|
||||
|
||||
if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24)
|
||||
{
|
||||
FOREACH_BLOCK_START(8, 8, 32, PSM_PSMT4HH)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 32, PSM_PSMT4HH)
|
||||
{
|
||||
ReadAndExpandBlock4HH_32(src, dst, dstpitch, pal);
|
||||
}
|
||||
|
@ -1885,7 +1898,7 @@ void GSLocalMemory::ReadTexture4HHNP(const GSVector4i& r, uint8* dst, int dstpit
|
|||
|
||||
__declspec(align(16)) uint32 block[8 * 8];
|
||||
|
||||
FOREACH_BLOCK_START(8, 8, 16, PSM_PSMT4HH)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 16, PSM_PSMT4HH)
|
||||
{
|
||||
ReadBlock32<true>(src, (uint8*)block, sizeof(block) / 8);
|
||||
|
||||
|
@ -1895,18 +1908,18 @@ void GSLocalMemory::ReadTexture4HHNP(const GSVector4i& r, uint8* dst, int dstpit
|
|||
}
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture16ZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture16ZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
FOREACH_BLOCK_START(16, 8, 16, PSM_PSMZ16)
|
||||
FOREACH_BLOCK_START(r, 16, 8, 16, PSM_PSMZ16)
|
||||
{
|
||||
ReadBlock16<true>(src, dst, dstpitch);
|
||||
}
|
||||
FOREACH_BLOCK_END
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture16SZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture16SZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
FOREACH_BLOCK_START(16, 8, 16, PSM_PSMZ16S)
|
||||
FOREACH_BLOCK_START(r, 16, 8, 16, PSM_PSMZ16S)
|
||||
{
|
||||
ReadBlock16<true>(src, dst, dstpitch);
|
||||
}
|
||||
|
@ -1959,45 +1972,45 @@ void GSLocalMemory::ReadTextureNP(const GSVector4i& r, uint8* dst, int dstpitch,
|
|||
|
||||
// 32/8
|
||||
|
||||
void GSLocalMemory::ReadTexture8P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture8P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
FOREACH_BLOCK_START(16, 16, 8, PSM_PSMT8)
|
||||
FOREACH_BLOCK_START(r, 16, 16, 8, PSM_PSMT8)
|
||||
{
|
||||
ReadBlock8<true>(src, dst, dstpitch);
|
||||
}
|
||||
FOREACH_BLOCK_END
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture4P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture4P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
FOREACH_BLOCK_START(32, 16, 8, PSM_PSMT4)
|
||||
FOREACH_BLOCK_START(r, 32, 16, 8, PSM_PSMT4)
|
||||
{
|
||||
ReadBlock4P(src, dst, dstpitch);
|
||||
}
|
||||
FOREACH_BLOCK_END
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture8HP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture8HP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
FOREACH_BLOCK_START(8, 8, 8, PSM_PSMT8H)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 8, PSM_PSMT8H)
|
||||
{
|
||||
ReadBlock8HP(src, dst, dstpitch);
|
||||
}
|
||||
FOREACH_BLOCK_END
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture4HLP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture4HLP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
FOREACH_BLOCK_START(8, 8, 8, PSM_PSMT4HL)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 8, PSM_PSMT4HL)
|
||||
{
|
||||
ReadBlock4HLP(src, dst, dstpitch);
|
||||
}
|
||||
FOREACH_BLOCK_END
|
||||
}
|
||||
|
||||
void GSLocalMemory::ReadTexture4HHP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const
|
||||
void GSLocalMemory::ReadTexture4HHP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA)
|
||||
{
|
||||
FOREACH_BLOCK_START(8, 8, 8, PSM_PSMT4HH)
|
||||
FOREACH_BLOCK_START(r, 8, 8, 8, PSM_PSMT4HH)
|
||||
{
|
||||
ReadBlock4HHP(src, dst, dstpitch);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
typedef uint32 (GSLocalMemory::*readTexelAddr)(uint32 addr, const GIFRegTEXA& TEXA) const;
|
||||
typedef void (GSLocalMemory::*writeImage)(int& tx, int& ty, uint8* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG);
|
||||
typedef void (GSLocalMemory::*readImage)(int& tx, int& ty, uint8* dst, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) const;
|
||||
typedef void (GSLocalMemory::*readTexture)(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
typedef void (GSLocalMemory::*readTexture)(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
typedef void (GSLocalMemory::*readTextureBlock)(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const;
|
||||
|
||||
typedef union
|
||||
|
@ -81,14 +81,21 @@ public:
|
|||
|
||||
GSClut m_clut;
|
||||
|
||||
struct Offset
|
||||
struct BlockOffset
|
||||
{
|
||||
GSVector4i row[2048]; // 0 | 0 | 0 | 0
|
||||
int* col[4]; // x | x+1 | x+2 | x+3
|
||||
int row[256]; // yn (n = 0 8 16 ...)
|
||||
int* col; // blockOffset*
|
||||
uint32 hash;
|
||||
};
|
||||
|
||||
struct Offset4
|
||||
struct PixelOffset
|
||||
{
|
||||
int row[2048]; // yn (n = 0 1 2 ...)
|
||||
int* col[8]; // rowOffset*
|
||||
uint32 hash;
|
||||
};
|
||||
|
||||
struct PixelOffset4
|
||||
{
|
||||
// 16 bit offsets (m_vm16[...])
|
||||
|
||||
|
@ -141,15 +148,17 @@ protected:
|
|||
|
||||
//
|
||||
|
||||
hash_map<uint32, Offset*> m_omap;
|
||||
hash_map<uint32, Offset4*> m_o4map;
|
||||
hash_map<uint32, BlockOffset*> m_bomap;
|
||||
hash_map<uint32, PixelOffset*> m_pomap;
|
||||
hash_map<uint32, PixelOffset4*> m_po4map;
|
||||
|
||||
public:
|
||||
GSLocalMemory();
|
||||
virtual ~GSLocalMemory();
|
||||
|
||||
Offset* GetOffset(uint32 bp, uint32 bw, uint32 psm);
|
||||
Offset4* GetOffset4(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF);
|
||||
BlockOffset* GetBlockOffset(uint32 bp, uint32 bw, uint32 psm);
|
||||
PixelOffset* GetPixelOffset(uint32 bp, uint32 bw, uint32 psm);
|
||||
PixelOffset4* GetPixelOffset4(const GIFRegFRAME& FRAME, const GIFRegZBUF& ZBUF);
|
||||
|
||||
// address
|
||||
|
||||
|
@ -626,6 +635,77 @@ public:
|
|||
WriteFrame16(PixelAddress16SZ(x, y, bp, bw), c);
|
||||
}
|
||||
|
||||
__forceinline void WritePixel32(uint8* RESTRICT src, uint32 pitch, PixelOffset* po, const GSVector4i& r)
|
||||
{
|
||||
src -= r.left * sizeof(uint32);
|
||||
|
||||
for(int y = r.top; y < r.bottom; y++, src += pitch)
|
||||
{
|
||||
uint32* RESTRICT s = (uint32*)src;
|
||||
uint32* RESTRICT d = &m_vm32[po->row[y]];
|
||||
int* RESTRICT o = po->col[0];
|
||||
|
||||
for(int x = r.left; x < r.right; x++)
|
||||
{
|
||||
d[o[x]] = s[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__forceinline void WritePixel24(uint8* RESTRICT src, uint32 pitch, PixelOffset* po, const GSVector4i& r)
|
||||
{
|
||||
src -= r.left * sizeof(uint32);
|
||||
|
||||
for(int y = r.top; y < r.bottom; y++, src += pitch)
|
||||
{
|
||||
uint32* RESTRICT s = (uint32*)src;
|
||||
uint32* RESTRICT d = &m_vm32[po->row[y]];
|
||||
int* RESTRICT o = po->col[0];
|
||||
|
||||
for(int x = r.left; x < r.right; x++)
|
||||
{
|
||||
d[o[x]] = (d[o[x]] & 0xff000000) | (s[x] & 0x00ffffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__forceinline void WritePixel16(uint8* RESTRICT src, uint32 pitch, PixelOffset* po, const GSVector4i& r)
|
||||
{
|
||||
src -= r.left * sizeof(uint16);
|
||||
|
||||
for(int y = r.top; y < r.bottom; y++, src += pitch)
|
||||
{
|
||||
uint16* RESTRICT s = (uint16*)src;
|
||||
uint16* RESTRICT d = &m_vm16[po->row[y]];
|
||||
int* RESTRICT o = po->col[0];
|
||||
|
||||
for(int x = r.left; x < r.right; x++)
|
||||
{
|
||||
d[o[x]] = s[x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__forceinline void WriteFrame16(uint8* RESTRICT src, uint32 pitch, PixelOffset* po, const GSVector4i& r)
|
||||
{
|
||||
src -= r.left * sizeof(uint32);
|
||||
|
||||
for(int y = r.top; y < r.bottom; y++, src += pitch)
|
||||
{
|
||||
uint32* RESTRICT s = (uint32*)src;
|
||||
uint16* RESTRICT d = &m_vm16[po->row[y]];
|
||||
int* RESTRICT o = po->col[0];
|
||||
|
||||
for(int x = r.left; x < r.right; x++)
|
||||
{
|
||||
uint32 rb = s[x] & 0x00f800f8;
|
||||
uint32 ga = s[x] & 0x8000f800;
|
||||
|
||||
d[o[x]] = (ga >> 16) | (rb >> 9) | (ga >> 6) | (rb >> 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__forceinline uint32 ReadTexel32(uint32 addr, const GIFRegTEXA& TEXA) const
|
||||
{
|
||||
return m_vm32[addr];
|
||||
|
@ -781,19 +861,19 @@ public:
|
|||
|
||||
// * => 32
|
||||
|
||||
void ReadTexture32(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture24(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture16(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture16S(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture8(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture4(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture8H(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture4HL(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture4HH(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture32Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture24Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture16Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture16SZ(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture32(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture24(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture16(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture16S(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture8(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture4(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture8H(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture4HL(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture4HH(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture32Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture24Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture16Z(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture16SZ(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
|
||||
void ReadTexture(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
|
||||
|
@ -813,25 +893,25 @@ public:
|
|||
|
||||
// * => 32/16
|
||||
|
||||
void ReadTexture16NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture16SNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture8NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture4NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture8HNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture4HLNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture4HHNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture16ZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture16SZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture16NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture16SNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture8NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture4NP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture8HNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture4HLNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture4HHNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture16ZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture16SZNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
|
||||
void ReadTextureNP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
|
||||
// pal ? 8 : 32
|
||||
|
||||
void ReadTexture8P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture4P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture8HP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture4HLP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture4HHP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTexture8P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture4P(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture8HP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture4HLP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
void ReadTexture4HHP(const GSVector4i& r, uint8* dst, int dstpitch, const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA);
|
||||
|
||||
void ReadTextureBlock8P(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const;
|
||||
void ReadTextureBlock4P(uint32 bp, uint8* dst, int dstpitch, const GIFRegTEXA& TEXA) const;
|
||||
|
|
|
@ -290,8 +290,8 @@ void GSRasterizer::DrawTriangleTop(GSVertexSW* v, const GSVector4i& scissor)
|
|||
|
||||
GSVector4 tb = l.p.upl(v[2].p).ceil();
|
||||
|
||||
GSVector4 tbmax = tb.maxv(fscissor.yyyy());
|
||||
GSVector4 tbmin = tb.minv(fscissor.wwww());
|
||||
GSVector4 tbmax = tb.max(fscissor.yyyy());
|
||||
GSVector4 tbmin = tb.min(fscissor.wwww());
|
||||
|
||||
GSVector4i tbi = GSVector4i(tbmax.zzww(tbmin));
|
||||
|
||||
|
@ -342,8 +342,8 @@ void GSRasterizer::DrawTriangleBottom(GSVertexSW* v, const GSVector4i& scissor)
|
|||
|
||||
GSVector4 tb = l.p.upl(v[2].p).ceil();
|
||||
|
||||
GSVector4 tbmax = tb.maxv(fscissor.yyyy());
|
||||
GSVector4 tbmin = tb.minv(fscissor.wwww());
|
||||
GSVector4 tbmax = tb.max(fscissor.yyyy());
|
||||
GSVector4 tbmin = tb.min(fscissor.wwww());
|
||||
|
||||
GSVector4i tbi = GSVector4i(tbmax.zzww(tbmin));
|
||||
|
||||
|
@ -398,8 +398,8 @@ void GSRasterizer::DrawTriangleTopBottom(GSVertexSW* v, const GSVector4i& scisso
|
|||
|
||||
GSVector4 tb = v[0].p.upl(v[1].p).zwzw(v[1].p.upl(v[2].p)).ceil();
|
||||
|
||||
GSVector4 tbmax = tb.maxv(fscissor.yyyy());
|
||||
GSVector4 tbmin = tb.minv(fscissor.wwww());
|
||||
GSVector4 tbmax = tb.max(fscissor.yyyy());
|
||||
GSVector4 tbmin = tb.min(fscissor.wwww());
|
||||
|
||||
GSVector4i tbi = GSVector4i(tbmax.xzyw(tbmin));
|
||||
|
||||
|
@ -462,8 +462,8 @@ void GSRasterizer::DrawTriangleSection(int top, int bottom, GSVertexSW& l, const
|
|||
{
|
||||
GSVector4 lr = l.p.xyxy(r).ceil();
|
||||
|
||||
GSVector4 lrmax = lr.maxv(fscissor.xxxx());
|
||||
GSVector4 lrmin = lr.minv(fscissor.zzzz());
|
||||
GSVector4 lrmax = lr.max(fscissor.xxxx());
|
||||
GSVector4 lrmin = lr.min(fscissor.zzzz());
|
||||
|
||||
GSVector4i lri = GSVector4i(lrmax.xxzz(lrmin));
|
||||
|
||||
|
@ -503,8 +503,8 @@ void GSRasterizer::DrawTriangleSection(int top, int bottom, GSVertexSW& l, const
|
|||
{
|
||||
GSVector4 lr = l.p.ceil();
|
||||
|
||||
GSVector4 lrmax = lr.maxv(fscissor.xxxx());
|
||||
GSVector4 lrmin = lr.minv(fscissor.zzzz());
|
||||
GSVector4 lrmax = lr.max(fscissor.xxxx());
|
||||
GSVector4 lrmin = lr.min(fscissor.zzzz());
|
||||
|
||||
GSVector4i lri = GSVector4i(lrmax.xxyy(lrmin));
|
||||
|
||||
|
@ -613,8 +613,8 @@ void GSRasterizer::DrawEdge(const GSVertexSW& v0, const GSVertexSW& v1, const GS
|
|||
|
||||
if(orientation)
|
||||
{
|
||||
GSVector4 tbmax = lrtb.maxv(fscissor.yyyy());
|
||||
GSVector4 tbmin = lrtb.minv(fscissor.wwww());
|
||||
GSVector4 tbmax = lrtb.max(fscissor.yyyy());
|
||||
GSVector4 tbmin = lrtb.min(fscissor.wwww());
|
||||
|
||||
GSVector4i tbi = GSVector4i(tbmax.zwzw(tbmin));
|
||||
|
||||
|
@ -711,8 +711,8 @@ void GSRasterizer::DrawEdge(const GSVertexSW& v0, const GSVertexSW& v1, const GS
|
|||
}
|
||||
else
|
||||
{
|
||||
GSVector4 lrmax = lrtb.maxv(fscissor.xxxx());
|
||||
GSVector4 lrmin = lrtb.minv(fscissor.zzzz());
|
||||
GSVector4 lrmax = lrtb.max(fscissor.xxxx());
|
||||
GSVector4 lrmin = lrtb.min(fscissor.zzzz());
|
||||
|
||||
GSVector4i lri = GSVector4i(lrmax.xyxy(lrmin));
|
||||
|
||||
|
@ -883,10 +883,7 @@ GSRasterizerList::~GSRasterizerList()
|
|||
|
||||
void GSRasterizerList::FreeRasterizers()
|
||||
{
|
||||
for(list<IRasterizer*>::iterator i = begin(); i != end(); i++)
|
||||
{
|
||||
delete *i;
|
||||
}
|
||||
for_each(begin(), end(), delete_object());
|
||||
|
||||
clear();
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "GSVertexSW.h"
|
||||
#include "GSFunctionMap.h"
|
||||
#include "GSThread.h"
|
||||
#include "GSAlignedClass.h"
|
||||
|
||||
__declspec(align(16)) class GSRasterizerData
|
||||
{
|
||||
|
@ -46,7 +47,7 @@ public:
|
|||
virtual void PrintStats() = 0;
|
||||
};
|
||||
|
||||
class IDrawScanline
|
||||
class IDrawScanline : public GSAlignedClass<16>
|
||||
{
|
||||
public:
|
||||
typedef void (__fastcall *DrawScanlineStaticPtr)(int right, int left, int top, const GSVertexSW& v);
|
||||
|
|
|
@ -41,10 +41,16 @@ GSRenderer::GSRenderer(uint8* base, bool mt, void (*irq)(), GSDevice* dev)
|
|||
s_dump = !!theApp.GetConfig("dump", 0);
|
||||
s_save = !!theApp.GetConfig("save", 0);
|
||||
s_savez = !!theApp.GetConfig("savez", 0);
|
||||
s_saven = theApp.GetConfig("saven", 0);
|
||||
}
|
||||
|
||||
GSRenderer::~GSRenderer()
|
||||
{
|
||||
if(m_dev)
|
||||
{
|
||||
m_dev->Reset(1, 1, GSDevice::Windowed);
|
||||
}
|
||||
|
||||
delete m_dev;
|
||||
}
|
||||
|
||||
|
@ -259,9 +265,17 @@ void GSRenderer::VSync(int field)
|
|||
|
||||
Flush();
|
||||
|
||||
field = field ? 1 : 0;
|
||||
|
||||
if(!Merge(field)) return;
|
||||
if(!m_dev->IsLost(true))
|
||||
{
|
||||
if(!Merge(field ? 1 : 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ResetDevice();
|
||||
}
|
||||
|
||||
// osd
|
||||
|
||||
|
@ -311,11 +325,6 @@ void GSRenderer::VSync(int field)
|
|||
|
||||
// present
|
||||
|
||||
if(m_dev->IsLost())
|
||||
{
|
||||
ResetDevice();
|
||||
}
|
||||
|
||||
m_dev->Present(m_wnd.GetClientRect().fit(m_aspectratio), m_shader);
|
||||
|
||||
// snapshot
|
||||
|
@ -365,7 +374,7 @@ void GSRenderer::VSync(int field)
|
|||
|
||||
if(offscreen->Map(m))
|
||||
{
|
||||
m_capture.DeliverFrame(m.bits, m.pitch, m_dev->IsCurrentRGBA());
|
||||
m_capture.DeliverFrame(m.bits, m.pitch, m_dev->IsRBSwapped());
|
||||
|
||||
offscreen->Unmap();
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ public:
|
|||
bool s_dump;
|
||||
bool s_save;
|
||||
bool s_savez;
|
||||
int s_saven;
|
||||
|
||||
public:
|
||||
GSRenderer(uint8* base, bool mt, void (*irq)(), GSDevice* dev);
|
||||
|
@ -127,7 +128,10 @@ protected:
|
|||
{
|
||||
// FIXME: berserk fpsm = 27 (8H)
|
||||
|
||||
Draw();
|
||||
if(!m_dev->IsLost())
|
||||
{
|
||||
Draw();
|
||||
}
|
||||
|
||||
m_perfmon.Put(GSPerfMon::Draw, 1);
|
||||
}
|
||||
|
|
|
@ -91,10 +91,30 @@ public:
|
|||
GSTextureFX::OMBlendSelector om_bsel;
|
||||
|
||||
om_bsel.abe = !IsOpaque();
|
||||
om_bsel.a = context->ALPHA.A;
|
||||
om_bsel.b = context->ALPHA.B;
|
||||
om_bsel.c = context->ALPHA.C;
|
||||
om_bsel.d = context->ALPHA.D;
|
||||
|
||||
if(om_bsel.abe)
|
||||
{
|
||||
om_bsel.a = context->ALPHA.A;
|
||||
om_bsel.b = context->ALPHA.B;
|
||||
om_bsel.c = context->ALPHA.C;
|
||||
om_bsel.d = context->ALPHA.D;
|
||||
|
||||
if(env.PABE.PABE)
|
||||
{
|
||||
if(om_bsel.a == 0 && om_bsel.b == 1 && om_bsel.c == 0 && om_bsel.d == 1)
|
||||
{
|
||||
// this works because with PABE alpha blending is on when alpha >= 0x80, but since the pixel shader
|
||||
// cannot output anything over 0x80 (== 1.0) blending with 0x80 or turning it off gives the same result
|
||||
|
||||
om_bsel.abe = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
om_bsel.wr = (context->FRAME.FBMSK & 0x000000ff) != 0x000000ff;
|
||||
om_bsel.wg = (context->FRAME.FBMSK & 0x0000ff00) != 0x0000ff00;
|
||||
om_bsel.wb = (context->FRAME.FBMSK & 0x00ff0000) != 0x00ff0000;
|
||||
|
@ -173,7 +193,6 @@ public:
|
|||
ps_sel.fst = PRIM->FST;
|
||||
ps_sel.wms = context->CLAMP.WMS;
|
||||
ps_sel.wmt = context->CLAMP.WMT;
|
||||
ps_sel.bpp = 0;
|
||||
ps_sel.aem = env.TEXA.AEM;
|
||||
ps_sel.tfx = context->TEX0.TFX;
|
||||
ps_sel.tcc = context->TEX0.TCC;
|
||||
|
@ -193,24 +212,30 @@ public:
|
|||
|
||||
GSTextureFX::PSConstantBuffer ps_cb;
|
||||
|
||||
ps_cb.FogColor_AREF = GSVector4((int)env.FOGCOL.FCR, (int)env.FOGCOL.FCG, (int)env.FOGCOL.FCB, 0) / 255;
|
||||
|
||||
switch(ps_sel.atst)
|
||||
if(ps_sel.fog)
|
||||
{
|
||||
case ATST_LESS:
|
||||
ps_cb.FogColor_AREF.a = (float)((int)context->TEST.AREF - 1);
|
||||
break;
|
||||
case ATST_GREATER:
|
||||
ps_cb.FogColor_AREF.a = (float)((int)context->TEST.AREF + 1);
|
||||
break;
|
||||
default:
|
||||
ps_cb.FogColor_AREF.a = (float)(int)context->TEST.AREF;
|
||||
break;
|
||||
ps_cb.FogColor_AREF = GSVector4((int)env.FOGCOL.FCR, (int)env.FOGCOL.FCG, (int)env.FOGCOL.FCB, 0) / 255;
|
||||
}
|
||||
|
||||
if(ps_sel.ate)
|
||||
{
|
||||
switch(ps_sel.atst)
|
||||
{
|
||||
case ATST_LESS:
|
||||
ps_cb.FogColor_AREF.a = (float)((int)context->TEST.AREF - 1);
|
||||
break;
|
||||
case ATST_GREATER:
|
||||
ps_cb.FogColor_AREF.a = (float)((int)context->TEST.AREF + 1);
|
||||
break;
|
||||
default:
|
||||
ps_cb.FogColor_AREF.a = (float)(int)context->TEST.AREF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(tex)
|
||||
{
|
||||
ps_sel.bpp = tex->m_bpp;
|
||||
ps_sel.fmt = tex->m_fmt;
|
||||
ps_sel.rt = tex->m_target;
|
||||
|
||||
int w = tex->m_texture->GetWidth();
|
||||
|
@ -223,19 +248,19 @@ public:
|
|||
|
||||
switch(context->CLAMP.WMS)
|
||||
{
|
||||
case 0:
|
||||
case CLAMP_REPEAT:
|
||||
ps_ssel.tau = 1;
|
||||
break;
|
||||
case 1:
|
||||
case CLAMP_CLAMP:
|
||||
ps_ssel.tau = 0;
|
||||
break;
|
||||
case 2:
|
||||
case CLAMP_REGION_CLAMP:
|
||||
ps_cb.MinMax.x = ((float)(int)context->CLAMP.MINU) / (1 << context->TEX0.TW);
|
||||
ps_cb.MinMax.z = ((float)(int)context->CLAMP.MAXU) / (1 << context->TEX0.TW);
|
||||
ps_cb.MinF_TA.x = ((float)(int)context->CLAMP.MINU + 0.5f) / (1 << context->TEX0.TW);
|
||||
ps_ssel.tau = 0;
|
||||
break;
|
||||
case 3:
|
||||
case CLAMP_REGION_REPEAT:
|
||||
ps_cb.MskFix.x = context->CLAMP.MINU;
|
||||
ps_cb.MskFix.z = context->CLAMP.MAXU;
|
||||
ps_ssel.tau = 1;
|
||||
|
@ -246,19 +271,19 @@ public:
|
|||
|
||||
switch(context->CLAMP.WMT)
|
||||
{
|
||||
case 0:
|
||||
case CLAMP_REPEAT:
|
||||
ps_ssel.tav = 1;
|
||||
break;
|
||||
case 1:
|
||||
case CLAMP_CLAMP:
|
||||
ps_ssel.tav = 0;
|
||||
break;
|
||||
case 2:
|
||||
case CLAMP_REGION_CLAMP:
|
||||
ps_cb.MinMax.y = ((float)(int)context->CLAMP.MINV) / (1 << context->TEX0.TH);
|
||||
ps_cb.MinMax.w = ((float)(int)context->CLAMP.MAXV) / (1 << context->TEX0.TH);
|
||||
ps_cb.MinF_TA.y = ((float)(int)context->CLAMP.MINV + 0.5f) / (1 << context->TEX0.TH);
|
||||
ps_ssel.tav = 0;
|
||||
break;
|
||||
case 3:
|
||||
case CLAMP_REGION_REPEAT:
|
||||
ps_cb.MskFix.y = context->CLAMP.MINV;
|
||||
ps_cb.MskFix.w = context->CLAMP.MAXV;
|
||||
ps_ssel.tav = 1;
|
||||
|
|
|
@ -122,14 +122,14 @@ void GSRendererDX9::VertexKick(bool skip)
|
|||
case GS_LINELIST:
|
||||
case GS_LINESTRIP:
|
||||
case GS_SPRITE:
|
||||
pmin = v[0].p.minv(v[1].p);
|
||||
pmax = v[0].p.maxv(v[1].p);
|
||||
pmin = v[0].p.min(v[1].p);
|
||||
pmax = v[0].p.max(v[1].p);
|
||||
break;
|
||||
case GS_TRIANGLELIST:
|
||||
case GS_TRIANGLESTRIP:
|
||||
case GS_TRIANGLEFAN:
|
||||
pmin = v[0].p.minv(v[1].p).minv(v[2].p);
|
||||
pmax = v[0].p.maxv(v[1].p).maxv(v[2].p);
|
||||
pmin = v[0].p.min(v[1].p).min(v[2].p);
|
||||
pmax = v[0].p.max(v[1].p).max(v[2].p);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ protected:
|
|||
|
||||
if(s_dump)
|
||||
{
|
||||
if(s_save)
|
||||
if(s_save && s_n >= s_saven)
|
||||
{
|
||||
t->Save(format("c:\\temp2\\_%05d_f%I64d_fr%d_%05x_%d.bmp", s_n, m_perfmon.GetFrame(), i, (int)TEX0.TBP0, (int)TEX0.PSM));
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ protected:
|
|||
|
||||
string s;
|
||||
|
||||
if(s_save && tex)
|
||||
if(s_save && s_n >= s_saven && tex)
|
||||
{
|
||||
s = format("c:\\temp2\\_%05d_f%I64d_tex_%05x_%d_%d%d_%02x_%02x_%02x_%02x.dds",
|
||||
s_n, frame, (int)context->TEX0.TBP0, (int)context->TEX0.PSM,
|
||||
|
@ -177,14 +177,14 @@ protected:
|
|||
|
||||
s_n++;
|
||||
|
||||
if(s_save)
|
||||
if(s_save && s_n >= s_saven)
|
||||
{
|
||||
s = format("c:\\temp2\\_%05d_f%I64d_rt0_%05x_%d.bmp", s_n, frame, context->FRAME.Block(), context->FRAME.PSM);
|
||||
|
||||
rt->m_texture->Save(s);
|
||||
}
|
||||
|
||||
if(s_savez)
|
||||
if(s_savez && s_n >= s_saven)
|
||||
{
|
||||
s = format("c:\\temp2\\_%05d_f%I64d_rz0_%05x_%d.bmp", s_n, frame, context->ZBUF.Block(), context->ZBUF.PSM);
|
||||
|
||||
|
@ -265,14 +265,14 @@ protected:
|
|||
|
||||
string s;
|
||||
|
||||
if(s_save)
|
||||
if(s_save && s_n >= s_saven)
|
||||
{
|
||||
s = format("c:\\temp2\\_%05d_f%I64d_rt1_%05x_%d.bmp", s_n, frame, context->FRAME.Block(), context->FRAME.PSM);
|
||||
|
||||
rt->m_texture->Save(s);
|
||||
}
|
||||
|
||||
if(s_savez)
|
||||
if(s_savez && s_n >= s_saven)
|
||||
{
|
||||
s = format("c:\\temp2\\_%05d_f%I64d_rz1_%05x_%d.bmp", s_n, frame, context->ZBUF.Block(), context->ZBUF.PSM);
|
||||
|
||||
|
|
|
@ -39,6 +39,11 @@ GSRendererSW::GSRendererSW(uint8* base, bool mt, void (*irq)(), GSDevice* dev)
|
|||
GSRendererSW::~GSRendererSW()
|
||||
{
|
||||
delete m_tc;
|
||||
|
||||
for(int i = 0; i < countof(m_texture); i++)
|
||||
{
|
||||
delete m_texture[i];
|
||||
}
|
||||
}
|
||||
|
||||
void GSRendererSW::Reset()
|
||||
|
@ -87,51 +92,34 @@ GSTexture* GSRendererSW::GetOutput(int i)
|
|||
TEX0.TBW = DISPFB.FBW;
|
||||
TEX0.PSM = DISPFB.PSM;
|
||||
|
||||
GSVector4i r(0, 0, TEX0.TBW * 64, GetFrameRect(i).bottom);
|
||||
int w = TEX0.TBW * 64;
|
||||
int h = GetFrameRect(i).bottom;
|
||||
|
||||
// TODO: round up bottom
|
||||
|
||||
int w = r.width();
|
||||
int h = r.height();
|
||||
|
||||
if(m_texture[i])
|
||||
if(m_dev->ResizeTexture(&m_texture[i], w, h))
|
||||
{
|
||||
if(m_texture[i]->GetWidth() != w || m_texture[i]->GetHeight() != h)
|
||||
// TODO
|
||||
static uint8* buff = (uint8*)_aligned_malloc(1024 * 1024 * 4, 16);
|
||||
static int pitch = 1024 * 4;
|
||||
|
||||
GSVector4i r(0, 0, w, h);
|
||||
|
||||
m_mem.ReadTexture(r, buff, pitch, TEX0, m_env.TEXA);
|
||||
|
||||
m_texture[i]->Update(r, buff, pitch);
|
||||
|
||||
if(s_dump)
|
||||
{
|
||||
delete m_texture[i];
|
||||
if(s_save && s_n >= s_saven)
|
||||
{
|
||||
m_texture[i]->Save(format("c:\\temp1\\_%05d_f%I64d_fr%d_%05x_%d.bmp", s_n, m_perfmon.GetFrame(), i, (int)TEX0.TBP0, (int)TEX0.PSM));
|
||||
}
|
||||
|
||||
m_texture[i] = NULL;
|
||||
s_n++;
|
||||
}
|
||||
}
|
||||
|
||||
if(!m_texture[i])
|
||||
{
|
||||
m_texture[i] = m_dev->CreateTexture(w, h);
|
||||
|
||||
if(!m_texture[i])
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
static uint8* buff = (uint8*)_aligned_malloc(1024 * 1024 * 4, 16);
|
||||
static int pitch = 1024 * 4;
|
||||
|
||||
m_mem.ReadTexture(r, buff, pitch, TEX0, m_env.TEXA);
|
||||
|
||||
m_texture[i]->Update(r, buff, pitch);
|
||||
|
||||
if(s_dump)
|
||||
{
|
||||
if(s_save)
|
||||
{
|
||||
m_texture[i]->Save(format("c:\\temp1\\_%05d_f%I64d_fr%d_%05x_%d.bmp", s_n, m_perfmon.GetFrame(), i, (int)TEX0.TBP0, (int)TEX0.PSM));
|
||||
}
|
||||
|
||||
s_n++;
|
||||
}
|
||||
|
||||
return m_texture[i];
|
||||
}
|
||||
|
||||
|
@ -161,7 +149,7 @@ void GSRendererSW::Draw()
|
|||
|
||||
string s;
|
||||
|
||||
if(s_save && PRIM->TME)
|
||||
if(s_save && s_n >= s_saven && PRIM->TME)
|
||||
{
|
||||
s = format("c:\\temp1\\_%05d_f%I64d_tex_%05x_%d.bmp", s_n, frame, (int)m_context->TEX0.TBP0, (int)m_context->TEX0.PSM);
|
||||
|
||||
|
@ -170,14 +158,14 @@ void GSRendererSW::Draw()
|
|||
|
||||
s_n++;
|
||||
|
||||
if(s_save)
|
||||
if(s_save && s_n >= s_saven)
|
||||
{
|
||||
s = format("c:\\temp1\\_%05d_f%I64d_rt0_%05x_%d.bmp", s_n, frame, m_context->FRAME.Block(), m_context->FRAME.PSM);
|
||||
|
||||
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameRect().width(), 512);//GetFrameSize(1).cy);
|
||||
}
|
||||
|
||||
if(s_savez)
|
||||
if(s_savez && s_n >= s_saven)
|
||||
{
|
||||
s = format("c:\\temp1\\_%05d_f%I64d_rz0_%05x_%d.bmp", s_n, frame, m_context->ZBUF.Block(), m_context->ZBUF.PSM);
|
||||
|
||||
|
@ -234,14 +222,14 @@ void GSRendererSW::Draw()
|
|||
|
||||
string s;
|
||||
|
||||
if(s_save)
|
||||
if(s_save && s_n >= s_saven)
|
||||
{
|
||||
s = format("c:\\temp1\\_%05d_f%I64d_rt1_%05x_%d.bmp", s_n, frame, m_context->FRAME.Block(), m_context->FRAME.PSM);
|
||||
|
||||
m_mem.SaveBMP(s, m_context->FRAME.Block(), m_context->FRAME.FBW, m_context->FRAME.PSM, GetFrameRect().width(), 512);//GetFrameSize(1).cy);
|
||||
}
|
||||
|
||||
if(s_savez)
|
||||
if(s_savez && s_n >= s_saven)
|
||||
{
|
||||
s = format("c:\\temp1\\_%05d_f%I64d_rz1_%05x_%d.bmp", s_n, frame, m_context->ZBUF.Block(), m_context->ZBUF.PSM);
|
||||
|
||||
|
@ -273,9 +261,9 @@ void GSRendererSW::GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass)
|
|||
|
||||
p.vm = m_mem.m_vm8;
|
||||
|
||||
p.fbo = m_mem.GetOffset(context->FRAME.Block(), context->FRAME.FBW, context->FRAME.PSM);
|
||||
p.zbo = m_mem.GetOffset(context->ZBUF.Block(), context->FRAME.FBW, context->ZBUF.PSM);
|
||||
p.fzbo = m_mem.GetOffset4(context->FRAME, context->ZBUF);
|
||||
p.fbo = m_mem.GetPixelOffset(context->FRAME.Block(), context->FRAME.FBW, context->FRAME.PSM);
|
||||
p.zbo = m_mem.GetPixelOffset(context->ZBUF.Block(), context->FRAME.FBW, context->ZBUF.PSM);
|
||||
p.fzbo = m_mem.GetPixelOffset4(context->FRAME, context->ZBUF);
|
||||
|
||||
p.sel.key = 0;
|
||||
|
||||
|
@ -517,14 +505,14 @@ if(!m_dump)
|
|||
case GS_LINELIST:
|
||||
case GS_LINESTRIP:
|
||||
case GS_SPRITE:
|
||||
pmin = v[0].p.minv(v[1].p);
|
||||
pmax = v[0].p.maxv(v[1].p);
|
||||
pmin = v[0].p.min(v[1].p);
|
||||
pmax = v[0].p.max(v[1].p);
|
||||
break;
|
||||
case GS_TRIANGLELIST:
|
||||
case GS_TRIANGLESTRIP:
|
||||
case GS_TRIANGLEFAN:
|
||||
pmin = v[0].p.minv(v[1].p).minv(v[2].p);
|
||||
pmax = v[0].p.maxv(v[1].p).maxv(v[2].p);
|
||||
pmin = v[0].p.min(v[1].p).min(v[2].p);
|
||||
pmax = v[0].p.max(v[1].p).max(v[2].p);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -108,9 +108,9 @@ __declspec(align(16)) struct GSScanlineParam
|
|||
const uint32* clut;
|
||||
uint32 tw;
|
||||
|
||||
GSLocalMemory::Offset* fbo;
|
||||
GSLocalMemory::Offset* zbo;
|
||||
GSLocalMemory::Offset4* fzbo;
|
||||
GSLocalMemory::PixelOffset* fbo;
|
||||
GSLocalMemory::PixelOffset* zbo;
|
||||
GSLocalMemory::PixelOffset4* fzbo;
|
||||
|
||||
uint32 fm, zm;
|
||||
};
|
||||
|
@ -122,10 +122,10 @@ __declspec(align(16)) struct GSScanlineEnvironment
|
|||
const uint32* clut;
|
||||
uint32 tw;
|
||||
|
||||
GSVector4i* fbr;
|
||||
GSVector4i* zbr;
|
||||
int** fbc;
|
||||
int** zbc;
|
||||
int* fbr;
|
||||
int* zbr;
|
||||
int* fbc;
|
||||
int* zbc;
|
||||
GSVector2i* fzbr;
|
||||
GSVector2i* fzbc;
|
||||
|
||||
|
|
|
@ -120,9 +120,10 @@ void GSSettingsDlg::OnInit()
|
|||
ComboBoxInit(IDC_INTERLACE, g_interlace, countof(g_interlace), theApp.GetConfig("Interlace", 0));
|
||||
ComboBoxInit(IDC_ASPECTRATIO, g_aspectratio, countof(g_aspectratio), theApp.GetConfig("AspectRatio", 1));
|
||||
|
||||
CheckDlgButton(m_hWnd, IDC_FILTER, theApp.GetConfig("filter", 1));
|
||||
CheckDlgButton(m_hWnd, IDC_FILTER, theApp.GetConfig("filter", 2));
|
||||
CheckDlgButton(m_hWnd, IDC_PALTEX, theApp.GetConfig("paltex", 1));
|
||||
CheckDlgButton(m_hWnd, IDC_VSYNC, theApp.GetConfig("vsync", 0));
|
||||
CheckDlgButton(m_hWnd, IDC_LOGZ, theApp.GetConfig("logz", 0));
|
||||
CheckDlgButton(m_hWnd, IDC_LOGZ, theApp.GetConfig("logz", 1));
|
||||
CheckDlgButton(m_hWnd, IDC_FBA, theApp.GetConfig("fba", 1));
|
||||
CheckDlgButton(m_hWnd, IDC_AA1, theApp.GetConfig("aa1", 0));
|
||||
CheckDlgButton(m_hWnd, IDC_BLUR, theApp.GetConfig("blur", 0));
|
||||
|
@ -179,6 +180,7 @@ bool GSSettingsDlg::OnCommand(HWND hWnd, UINT id, UINT code)
|
|||
}
|
||||
|
||||
theApp.SetConfig("filter", (int)IsDlgButtonChecked(m_hWnd, IDC_FILTER));
|
||||
theApp.SetConfig("paltex", (int)IsDlgButtonChecked(m_hWnd, IDC_PALTEX));
|
||||
theApp.SetConfig("vsync", (int)IsDlgButtonChecked(m_hWnd, IDC_VSYNC));
|
||||
theApp.SetConfig("logz", (int)IsDlgButtonChecked(m_hWnd, IDC_LOGZ));
|
||||
theApp.SetConfig("fba", (int)IsDlgButtonChecked(m_hWnd, IDC_FBA));
|
||||
|
@ -220,6 +222,7 @@ void GSSettingsDlg::UpdateControls()
|
|||
EnableWindow(GetDlgItem(m_hWnd, IDC_RESY_EDIT), hw && !native);
|
||||
EnableWindow(GetDlgItem(m_hWnd, IDC_NATIVERES), hw);
|
||||
EnableWindow(GetDlgItem(m_hWnd, IDC_FILTER), hw && !native);
|
||||
EnableWindow(GetDlgItem(m_hWnd, IDC_PALTEX), hw);
|
||||
EnableWindow(GetDlgItem(m_hWnd, IDC_LOGZ), dx9 && hw);
|
||||
EnableWindow(GetDlgItem(m_hWnd, IDC_FBA), dx9 && hw);
|
||||
EnableWindow(GetDlgItem(m_hWnd, IDC_AA1), sw);
|
||||
|
|
|
@ -87,8 +87,6 @@ GSState::GSState(uint8* base, bool mt, void (*irq)())
|
|||
|
||||
m_regs = (GSPrivRegSet*)(base + 0x12000000);
|
||||
|
||||
memset(m_regs, 0, sizeof(GSPrivRegSet));
|
||||
|
||||
PRIM = &m_env.PRIM;
|
||||
// CSR->rREV = 0x20;
|
||||
m_env.PRMODECONT.AC = 1;
|
||||
|
@ -948,7 +946,7 @@ void GSState::FlushWrite()
|
|||
r.left = m_env.TRXPOS.DSAX;
|
||||
r.top = y;
|
||||
r.right = r.left + m_env.TRXREG.RRW;
|
||||
r.bottom = min(r.top + m_env.TRXREG.RRH, m_tr.x == r.left ? m_tr.y : m_tr.y + 1);
|
||||
r.bottom = std::min<int>(r.top + m_env.TRXREG.RRH, m_tr.x == r.left ? m_tr.y : m_tr.y + 1);
|
||||
|
||||
InvalidateVideoMem(m_env.BITBLTBUF, r);
|
||||
/*
|
||||
|
@ -1085,96 +1083,168 @@ void GSState::Move()
|
|||
|
||||
// TODO: unroll inner loops (width has special size requirement, must be multiples of 1 << n, depending on the format)
|
||||
|
||||
GSLocalMemory::PixelOffset* RESTRICT spo = m_mem.GetPixelOffset(m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW, m_env.BITBLTBUF.SPSM);
|
||||
GSLocalMemory::PixelOffset* RESTRICT dpo = m_mem.GetPixelOffset(m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW, m_env.BITBLTBUF.DPSM);
|
||||
|
||||
if(spsm.trbpp == dpsm.trbpp && spsm.trbpp >= 16)
|
||||
{
|
||||
int* soffset = spsm.rowOffset[0];
|
||||
int* doffset = dpsm.rowOffset[0];
|
||||
int* RESTRICT scol = &spo->col[0][sx];
|
||||
int* RESTRICT dcol = &dpo->col[0][dx];
|
||||
|
||||
if(spsm.trbpp == 32)
|
||||
{
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc * w, dx -= xinc * w)
|
||||
if(xinc > 0)
|
||||
{
|
||||
uint32 sbase = spsm.pa(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW);
|
||||
uint32 dbase = dpsm.pa(0, dy, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW);
|
||||
|
||||
for(int x = 0; x < w; x++, sx += xinc, dx += xinc)
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
|
||||
{
|
||||
m_mem.WritePixel32(dbase + doffset[dx], m_mem.ReadPixel32(sbase + soffset[sx]));
|
||||
uint32* RESTRICT s = &m_mem.m_vm32[spo->row[sy]];
|
||||
uint32* RESTRICT d = &m_mem.m_vm32[dpo->row[dy]];
|
||||
|
||||
for(int x = 0; x < w; x++) d[dcol[x]] = s[scol[x]];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
|
||||
{
|
||||
uint32* RESTRICT s = &m_mem.m_vm32[spo->row[sy]];
|
||||
uint32* RESTRICT d = &m_mem.m_vm32[dpo->row[dy]];
|
||||
|
||||
for(int x = 0; x > -w; x--) d[dcol[x]] = s[scol[x]];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(spsm.trbpp == 24)
|
||||
{
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc * w, dx -= xinc * w)
|
||||
if(xinc > 0)
|
||||
{
|
||||
uint32 sbase = spsm.pa(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW);
|
||||
uint32 dbase = dpsm.pa(0, dy, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW);
|
||||
|
||||
for(int x = 0; x < w; x++, sx += xinc, dx += xinc)
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
|
||||
{
|
||||
m_mem.WritePixel24(dbase + doffset[dx], m_mem.ReadPixel24(sbase + soffset[sx]));
|
||||
uint32* RESTRICT s = &m_mem.m_vm32[spo->row[sy]];
|
||||
uint32* RESTRICT d = &m_mem.m_vm32[dpo->row[dy]];
|
||||
|
||||
for(int x = 0; x < w; x++) d[dcol[x]] = (d[dcol[x]] & 0xff000000) | (s[scol[x]] & 0x00ffffff);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
|
||||
{
|
||||
uint32* RESTRICT s = &m_mem.m_vm32[spo->row[sy]];
|
||||
uint32* RESTRICT d = &m_mem.m_vm32[dpo->row[dy]];
|
||||
|
||||
for(int x = 0; x > -w; x--) d[dcol[x]] = (d[dcol[x]] & 0xff000000) | (s[scol[x]] & 0x00ffffff);
|
||||
}
|
||||
}
|
||||
}
|
||||
else // if(spsm.trbpp == 16)
|
||||
{
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc * w, dx -= xinc * w)
|
||||
if(xinc > 0)
|
||||
{
|
||||
uint32 sbase = spsm.pa(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW);
|
||||
uint32 dbase = dpsm.pa(0, dy, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW);
|
||||
|
||||
for(int x = 0; x < w; x++, sx += xinc, dx += xinc)
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
|
||||
{
|
||||
m_mem.WritePixel16(dbase + doffset[dx], m_mem.ReadPixel16(sbase + soffset[sx]));
|
||||
uint16* RESTRICT s = &m_mem.m_vm16[spo->row[sy]];
|
||||
uint16* RESTRICT d = &m_mem.m_vm16[dpo->row[dy]];
|
||||
|
||||
for(int x = 0; x < w; x++) d[dcol[x]] = s[scol[x]];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
|
||||
{
|
||||
uint16* RESTRICT s = &m_mem.m_vm16[spo->row[sy]];
|
||||
uint16* RESTRICT d = &m_mem.m_vm16[dpo->row[dy]];
|
||||
|
||||
for(int x = 0; x > -w; x--) d[dcol[x]] = s[scol[x]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(m_env.BITBLTBUF.SPSM == PSM_PSMT8 && m_env.BITBLTBUF.DPSM == PSM_PSMT8)
|
||||
{
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc * w, dx -= xinc * w)
|
||||
if(xinc > 0)
|
||||
{
|
||||
uint32 sbase = GSLocalMemory::PixelAddress8(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW);
|
||||
int* soffset = spsm.rowOffset[sy & 7];
|
||||
|
||||
uint32 dbase = GSLocalMemory::PixelAddress8(0, dy, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW);
|
||||
int* doffset = dpsm.rowOffset[dy & 7];
|
||||
|
||||
for(int x = 0; x < w; x++, sx += xinc, dx += xinc)
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
|
||||
{
|
||||
m_mem.WritePixel8(dbase + doffset[dx], m_mem.ReadPixel8(sbase + soffset[sx]));
|
||||
uint8* RESTRICT s = &m_mem.m_vm8[spo->row[sy]];
|
||||
uint8* RESTRICT d = &m_mem.m_vm8[dpo->row[dy]];
|
||||
|
||||
int* RESTRICT scol = &spo->col[sy & 7][sx];
|
||||
int* RESTRICT dcol = &dpo->col[dy & 7][dx];
|
||||
|
||||
for(int x = 0; x < w; x++) d[dcol[x]] = s[scol[x]];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
|
||||
{
|
||||
uint8* RESTRICT s = &m_mem.m_vm8[spo->row[sy]];
|
||||
uint8* RESTRICT d = &m_mem.m_vm8[dpo->row[dy]];
|
||||
|
||||
int* RESTRICT scol = &spo->col[sy & 7][sx];
|
||||
int* RESTRICT dcol = &dpo->col[dy & 7][dx];
|
||||
|
||||
for(int x = 0; x > -w; x--) d[dcol[x]] = s[scol[x]];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(m_env.BITBLTBUF.SPSM == PSM_PSMT4 && m_env.BITBLTBUF.DPSM == PSM_PSMT4)
|
||||
{
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc * w, dx -= xinc * w)
|
||||
if(xinc > 0)
|
||||
{
|
||||
uint32 sbase = GSLocalMemory::PixelAddress4(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW);
|
||||
int* soffset = spsm.rowOffset[sy & 7];
|
||||
|
||||
uint32 dbase = GSLocalMemory::PixelAddress4(0, dy, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW);
|
||||
int* doffset = dpsm.rowOffset[dy & 7];
|
||||
|
||||
for(int x = 0; x < w; x++, sx += xinc, dx += xinc)
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
|
||||
{
|
||||
m_mem.WritePixel4(dbase + doffset[dx], m_mem.ReadPixel4(sbase + soffset[sx]));
|
||||
uint32 sbase = spo->row[sy];
|
||||
uint32 dbase = dpo->row[dy];
|
||||
|
||||
int* RESTRICT scol = &spo->col[sy & 7][sx];
|
||||
int* RESTRICT dcol = &dpo->col[dy & 7][dx];
|
||||
|
||||
for(int x = 0; x < w; x++) m_mem.WritePixel4(dbase + dcol[x], m_mem.ReadPixel4(sbase + scol[x]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
|
||||
{
|
||||
uint32 sbase = spo->row[sy];
|
||||
uint32 dbase = dpo->row[dy];
|
||||
|
||||
int* RESTRICT scol = &spo->col[sy & 7][sx];
|
||||
int* RESTRICT dcol = &dpo->col[dy & 7][dx];
|
||||
|
||||
for(int x = 0; x > -w; x--) m_mem.WritePixel4(dbase + dcol[x], m_mem.ReadPixel4(sbase + scol[x]));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc * w, dx -= xinc * w)
|
||||
if(xinc > 0)
|
||||
{
|
||||
uint32 sbase = spsm.pa(0, sy, m_env.BITBLTBUF.SBP, m_env.BITBLTBUF.SBW);
|
||||
int* soffset = spsm.rowOffset[sy & 7];
|
||||
|
||||
uint32 dbase = dpsm.pa(0, dy, m_env.BITBLTBUF.DBP, m_env.BITBLTBUF.DBW);
|
||||
int* doffset = dpsm.rowOffset[dy & 7];
|
||||
|
||||
for(int x = 0; x < w; x++, sx += xinc, dx += xinc)
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
|
||||
{
|
||||
(m_mem.*dpsm.wpa)(dbase + doffset[dx], (m_mem.*spsm.rpa)(sbase + soffset[sx]));
|
||||
uint32 sbase = spo->row[sy];
|
||||
uint32 dbase = dpo->row[dy];
|
||||
|
||||
int* RESTRICT scol = &spo->col[sy & 7][sx];
|
||||
int* RESTRICT dcol = &dpo->col[dy & 7][dx];
|
||||
|
||||
for(int x = 0; x < w; x++) (m_mem.*dpsm.wpa)(dbase + dcol[x], (m_mem.*spsm.rpa)(sbase + scol[x]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int y = 0; y < h; y++, sy += yinc, dy += yinc)
|
||||
{
|
||||
uint32 sbase = spo->row[sy];
|
||||
uint32 dbase = dpo->row[dy];
|
||||
|
||||
int* RESTRICT scol = &spo->col[sy & 7][sx];
|
||||
int* RESTRICT dcol = &dpo->col[dy & 7][dx];
|
||||
|
||||
for(int x = 0; x > -w; x--) (m_mem.*dpsm.wpa)(dbase + dcol[x], (m_mem.*spsm.rpa)(sbase + scol[x]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1880,6 +1950,19 @@ bool GSC_OnePieceGrandAdventure(const GSFrameInfo& fi, int& skip)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool GSC_OnePieceGrandBattle(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && fi.FBP == 0x02d00 && fi.FPSM == PSM_PSMCT16 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00f00) && fi.TPSM == PSM_PSMCT16)
|
||||
{
|
||||
skip = 4;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GSC_ICO(const GSFrameInfo& fi, int& skip)
|
||||
{
|
||||
if(skip == 0)
|
||||
|
@ -2300,6 +2383,7 @@ bool GSState::IsBadFrame(int& skip)
|
|||
map[CRC::BullyCC] = GSC_BullyCC;
|
||||
map[CRC::SoTC] = GSC_SoTC;
|
||||
map[CRC::OnePieceGrandAdventure] = GSC_OnePieceGrandAdventure;
|
||||
map[CRC::OnePieceGrandBattle] = GSC_OnePieceGrandBattle;
|
||||
map[CRC::ICO] = GSC_ICO;
|
||||
map[CRC::GT4] = GSC_GT4;
|
||||
map[CRC::WildArms5] = GSC_WildArms5;
|
||||
|
|
|
@ -82,7 +82,7 @@ bool GSTexture7::Update(const GSVector4i& r, const void* data, int pitch)
|
|||
uint8* src = (uint8*)data;
|
||||
uint8* dst = (uint8*)desc.lpSurface;
|
||||
|
||||
int bytes = min(pitch, desc.lPitch);
|
||||
int bytes = std::min<int>(pitch, desc.lPitch);
|
||||
|
||||
for(int i = 0, j = r.height(); i < j; i++, src += pitch, dst += desc.lPitch)
|
||||
{
|
||||
|
|
|
@ -87,7 +87,14 @@ bool GSTexture9::Update(const GSVector4i& r, const void* data, int pitch)
|
|||
uint8* src = (uint8*)data;
|
||||
uint8* dst = (uint8*)lr.pBits;
|
||||
|
||||
int bytes = r.width() << (m_desc.Format == D3DFMT_A1R5G5B5 ? 1 : 2);
|
||||
int bytes = r.width() * sizeof(uint32);
|
||||
|
||||
switch(m_desc.Format)
|
||||
{
|
||||
case D3DFMT_A8: bytes >>= 2; break;
|
||||
case D3DFMT_A1R5G5B5: bytes >>= 1; break;
|
||||
default: ASSERT(m_desc.Format == D3DFMT_A8R8G8B8); break;
|
||||
}
|
||||
|
||||
bytes = min(bytes, pitch);
|
||||
bytes = min(bytes, lr.Pitch);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue