mirror of https://github.com/PCSX2/pcsx2.git
FPU fixes:
tweaked the fpu compare clamping so now gt4 works again. made the digimon rumble arena 2 fix into a gamefix. tekken 5 doesn't need a gamefix anymore. VU fixes: fixed 2 opcodes thanks to nneeve. optimized FCOR a bit. changed the way ICO gamefix works so its less hacky (just always sets VI to 1 instead of setting VI to the opposite of the 'correct' result) General fix: there was some odd bug with the autogenerated TEXTINCLUDE stuff. if you edited a resource, it would generate #include "afxresmw.h instead of #include "afxresmw.h" (a quotation mark was missing so you'd get compile errors) so i fixed that ;p git-svn-id: http://pcsx2.googlecode.com/svn/trunk@563 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
4a8ba5cd40
commit
de2e939fcc
28
pcsx2/Misc.h
28
pcsx2/Misc.h
|
@ -82,23 +82,23 @@ extern SessionOverrideFlags g_Session;
|
|||
#define CHECK_MULTIGS (Config.Options&PCSX2_GSMULTITHREAD)
|
||||
#define CHECK_EEREC (!g_Session.ForceDisableEErec && Config.Options&PCSX2_EEREC)
|
||||
//------------ SPEED/MISC HACKS!!! ---------------
|
||||
#define CHECK_EE_CYCLERATE (Config.Hacks & 0x03)
|
||||
#define CHECK_IOP_CYCLERATE (Config.Hacks & (1<<3))
|
||||
#define CHECK_WAITCYCLE_HACK (Config.Hacks & (1<<4))
|
||||
#define CHECK_INTC_STAT_HACK (Config.Hacks & (1<<5))
|
||||
#define CHECK_ESCAPE_HACK (Config.Hacks & 0x400)
|
||||
#define CHECK_EE_CYCLERATE (Config.Hacks & 0x03)
|
||||
#define CHECK_IOP_CYCLERATE (Config.Hacks & 0x08)
|
||||
#define CHECK_WAITCYCLE_HACK (Config.Hacks & 0x10)
|
||||
#define CHECK_INTC_STAT_HACK (Config.Hacks & 0x20)
|
||||
#define CHECK_ESCAPE_HACK (Config.Hacks & 0x400)
|
||||
//------------ SPECIAL GAME FIXES!!! ---------------
|
||||
#define CHECK_VUADDSUBHACK (Config.GameFixes & 0x1) // Special Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate.
|
||||
#define CHECK_FPUCLAMPHACK (Config.GameFixes & 0x4) // Special Fix for Tekken 5, different clamping for FPU (sets NaN to zero; doesn't clamp infinities)
|
||||
#define CHECK_FCORHACK (Config.GameFixes & 0x8) // Special Fix for ICO, cures SPS due to some misscalculation of the clip flag.
|
||||
#define CHECK_VUADDSUBHACK (Config.GameFixes & 0x1) // Special Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate.
|
||||
#define CHECK_FPUCOMPAREHACK (Config.GameFixes & 0x4) // Special Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu.
|
||||
#define CHECK_FCORHACK (Config.GameFixes & 0x8) // Special Fix for ICO, cures SPS due to some misscalculation of the clip flag.
|
||||
//------------ Advanced Options!!! ---------------
|
||||
#define CHECK_VU_OVERFLOW (Config.vuOptions & 0x1)
|
||||
#define CHECK_VU_EXTRA_OVERFLOW (Config.vuOptions & 0x2) // If enabled, Operands are clamped before being used in the VU recs
|
||||
#define CHECK_VU_SIGN_OVERFLOW (Config.vuOptions & 0x4)
|
||||
#define CHECK_VU_UNDERFLOW (Config.vuOptions & 0x8)
|
||||
#define CHECK_VU_OVERFLOW (Config.vuOptions & 0x1)
|
||||
#define CHECK_VU_EXTRA_OVERFLOW (Config.vuOptions & 0x2) // If enabled, Operands are clamped before being used in the VU recs
|
||||
#define CHECK_VU_SIGN_OVERFLOW (Config.vuOptions & 0x4)
|
||||
#define CHECK_VU_UNDERFLOW (Config.vuOptions & 0x8)
|
||||
#define CHECK_VU_EXTRA_FLAGS 0 // Always disabled now // Sets correct flags in the VU recs
|
||||
#define CHECK_FPU_OVERFLOW (Config.eeOptions & 0x1)
|
||||
#define CHECK_FPU_EXTRA_OVERFLOW (Config.eeOptions & 0x2) // If enabled, Operands are checked for infinities before being used in the FPU recs
|
||||
#define CHECK_FPU_OVERFLOW (Config.eeOptions & 0x1)
|
||||
#define CHECK_FPU_EXTRA_OVERFLOW (Config.eeOptions & 0x2) // If enabled, Operands are checked for infinities before being used in the FPU recs
|
||||
#define CHECK_FPU_EXTRA_FLAGS 1 // Always enabled now // Sets D/I flags on FPU instructions
|
||||
#define DEFAULT_eeOptions 0x01
|
||||
#define DEFAULT_vuOptions 0x01
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxresmw.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
|
@ -84,11 +83,12 @@ BEGIN
|
|||
PUSHBUTTON "Cancel",IDCANCEL,139,99,50,14
|
||||
CTEXT "Some games need special settings.\nConfigure them here.",IDC_STATIC,7,7,264,17
|
||||
GROUPBOX "PCSX2 Gamefixes",IDC_STATIC,7,31,264,89
|
||||
CONTROL "FPU Clamp Hack - Special fix for Tekken 5.",IDC_GAMEFIX3,
|
||||
CONTROL "FPU Compare Hack - Special fix for Digimon Rumble Arena 2.",IDC_GAMEFIX3,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,51,249,10
|
||||
CONTROL "VU Add / Sub Hack - Special fix for Tri-Ace games!",IDC_GAMEFIX2,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,65,252,10
|
||||
CONTROL "VU FCOR Hack - Fixes ICO SPS",IDC_GAMEFIX7,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,79,252,10
|
||||
CONTROL "VU FCOR Hack - Special Fix for ICO SPS.",IDC_GAMEFIX7,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,79,252,10
|
||||
END
|
||||
|
||||
|
||||
|
@ -1388,7 +1388,7 @@ END
|
|||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""afxresmw.h\0"
|
||||
"#include ""afxresmw.h""\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
|
|
|
@ -371,70 +371,61 @@ REC_FPUFUNC(RSQRT_S);
|
|||
//------------------------------------------------------------------
|
||||
// Clamp Functions (Converts NaN's and Infinities to Normal Numbers)
|
||||
//------------------------------------------------------------------
|
||||
void fpuFloat(int regd) { // +/-NaN -> +fMax, +Inf -> +fMax, -Inf -> -fMax
|
||||
if (CHECK_FPU_OVERFLOW && !CHECK_FPUCLAMPHACK) { // Tekken 5 doesn't like clamping infinities.
|
||||
|
||||
PCSX2_ALIGNED16(u64 FPU_FLOAT_TEMP[2]);
|
||||
__forceinline void fpuFloat4(int regd) { // +NaN -> +fMax, -NaN -> -fMax, +Inf -> +fMax, -Inf -> -fMax
|
||||
int t1reg = _allocTempXMMreg(XMMT_FPS, -1);
|
||||
if (t1reg >= 0) {
|
||||
SSE_MOVSS_XMM_to_XMM(t1reg, regd);
|
||||
SSE_ANDPS_M128_to_XMM(t1reg, (uptr)&s_neg[0]);
|
||||
SSE_MINSS_M32_to_XMM(regd, (uptr)&g_maxvals[0]);
|
||||
SSE_MAXSS_M32_to_XMM(regd, (uptr)&g_minvals[0]);
|
||||
SSE_ORPS_XMM_to_XMM(regd, t1reg);
|
||||
_freeXMMreg(t1reg);
|
||||
}
|
||||
else {
|
||||
Console::Error("fpuFloat2() allocation error");
|
||||
t1reg = (regd == 0) ? 1 : 0; // get a temp reg thats not regd
|
||||
SSE_MOVAPS_XMM_to_M128( (uptr)&FPU_FLOAT_TEMP[0], t1reg ); // backup data in t1reg to a temp address
|
||||
SSE_MOVSS_XMM_to_XMM(t1reg, regd);
|
||||
SSE_ANDPS_M128_to_XMM(t1reg, (uptr)&s_neg[0]);
|
||||
SSE_MINSS_M32_to_XMM(regd, (uptr)&g_maxvals[0]);
|
||||
SSE_MAXSS_M32_to_XMM(regd, (uptr)&g_minvals[0]);
|
||||
SSE_ORPS_XMM_to_XMM(regd, t1reg);
|
||||
SSE_MOVAPS_M128_to_XMM( t1reg, (uptr)&FPU_FLOAT_TEMP[0] ); // restore t1reg data
|
||||
}
|
||||
}
|
||||
|
||||
__forceinline void fpuFloat(int regd) { // +/-NaN -> +fMax, +Inf -> +fMax, -Inf -> -fMax
|
||||
if (CHECK_FPU_OVERFLOW) {
|
||||
SSE_MINSS_M32_to_XMM(regd, (uptr)&g_maxvals[0]); // MIN() must be before MAX()! So that NaN's become +Maximum
|
||||
SSE_MAXSS_M32_to_XMM(regd, (uptr)&g_minvals[0]);
|
||||
}
|
||||
}
|
||||
|
||||
PCSX2_ALIGNED16(u64 FPU_FLOAT_TEMP[2]);
|
||||
void fpuFloat2(int regd) { // +NaN -> +fMax, -NaN -> -fMax, +Inf -> +fMax, -Inf -> -fMax
|
||||
if (CHECK_FPU_OVERFLOW && !CHECK_FPUCLAMPHACK) { // Tekken 5 doesn't like clamping infinities.
|
||||
int t1reg = _allocTempXMMreg(XMMT_FPS, -1);
|
||||
if (t1reg >= 0) {
|
||||
SSE_MOVSS_XMM_to_XMM(t1reg, regd);
|
||||
SSE_ANDPS_M128_to_XMM(t1reg, (uptr)&s_neg[0]);
|
||||
SSE_MINSS_M32_to_XMM(regd, (uptr)&g_maxvals[0]);
|
||||
SSE_MAXSS_M32_to_XMM(regd, (uptr)&g_minvals[0]);
|
||||
SSE_ORPS_XMM_to_XMM(regd, t1reg);
|
||||
_freeXMMreg(t1reg);
|
||||
}
|
||||
else {
|
||||
Console::Error("fpuFloat2() allocation error");
|
||||
t1reg = (regd == 0) ? 1 : 0; // get a temp reg thats not regd
|
||||
SSE_MOVAPS_XMM_to_M128( (uptr)&FPU_FLOAT_TEMP[0], t1reg ); // backup data in t1reg to a temp address
|
||||
SSE_MOVSS_XMM_to_XMM(t1reg, regd);
|
||||
SSE_ANDPS_M128_to_XMM(t1reg, (uptr)&s_neg[0]);
|
||||
SSE_MINSS_M32_to_XMM(regd, (uptr)&g_maxvals[0]);
|
||||
SSE_MAXSS_M32_to_XMM(regd, (uptr)&g_minvals[0]);
|
||||
SSE_ORPS_XMM_to_XMM(regd, t1reg);
|
||||
SSE_MOVAPS_M128_to_XMM( t1reg, (uptr)&FPU_FLOAT_TEMP[0] ); // restore t1reg data
|
||||
}
|
||||
__forceinline void fpuFloat2(int regd) { // +NaN -> +fMax, -NaN -> -fMax, +Inf -> +fMax, -Inf -> -fMax
|
||||
if (CHECK_FPU_OVERFLOW) {
|
||||
fpuFloat4(regd);
|
||||
}
|
||||
}
|
||||
|
||||
__forceinline void fpuFloat3(int regd) {
|
||||
// This clamp function used in the recC_xx opcodes
|
||||
// This clamp function is used in the recC_xx opcodes
|
||||
// Rule of Rose needs clamping or else it crashes (minss or maxss both fix the crash)
|
||||
// Tekken 5 has disappearing characters unless preserving NaN sign (fpuFloat4() preserves NaN sign).
|
||||
// Digimon Rumble Arena 2 needs MAXSS clamping (if you only use minss, it spins on the intro-menus;
|
||||
// it also doesn't like preserving NaN sign with fpuFloat2, so the only way to make Digimon work
|
||||
// it also doesn't like preserving NaN sign with fpuFloat4, so the only way to make Digimon work
|
||||
// is by calling MAXSS first)
|
||||
SSE_MAXSS_M32_to_XMM(regd, (uptr)&g_minvals[0]);
|
||||
//SSE_MINSS_M32_to_XMM(regd, (uptr)&g_maxvals[0]);
|
||||
if (CHECK_FPUCOMPAREHACK) {
|
||||
//SSE_MINSS_M32_to_XMM(regd, (uptr)&g_maxvals[0]);
|
||||
SSE_MAXSS_M32_to_XMM(regd, (uptr)&g_minvals[0]);
|
||||
}
|
||||
else fpuFloat4(regd);
|
||||
}
|
||||
|
||||
void ClampValues(int regd) {
|
||||
fpuFloat(regd);
|
||||
}
|
||||
|
||||
void ClampValues2(int regd) {
|
||||
if (CHECK_FPUCLAMPHACK) { // Fixes Tekken 5 ( Makes NaN equal 0, infinities stay the same )
|
||||
int t5reg = _allocTempXMMreg(XMMT_FPS, -1);
|
||||
|
||||
SSE_XORPS_XMM_to_XMM(t5reg, t5reg);
|
||||
SSE_CMPORDSS_XMM_to_XMM(t5reg, regd);
|
||||
|
||||
SSE_ANDPS_XMM_to_XMM(regd, t5reg);
|
||||
|
||||
/* --- Its odd but tekken dosn't like Infinities to be clamped. --- */
|
||||
//SSE_MINSS_M32_to_XMM(regd, (uptr)&g_maxvals[0]);
|
||||
//SSE_MAXSS_M32_to_XMM(regd, (uptr)&g_minvals[0]);
|
||||
|
||||
_freeXMMreg(t5reg);
|
||||
}
|
||||
else fpuFloat(regd);
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
|
||||
|
||||
|
@ -639,7 +630,7 @@ int recCommutativeOp(int info, int regd, int op)
|
|||
void recADD_S_xmm(int info)
|
||||
{
|
||||
//AND32ItoM((uptr)&fpuRegs.fprc[31], ~(FPUflagO|FPUflagU)); // Clear O and U flags
|
||||
ClampValues2(recCommutativeOp(info, EEREC_D, 0));
|
||||
ClampValues(recCommutativeOp(info, EEREC_D, 0));
|
||||
//REC_FPUOP(ADD_S);
|
||||
}
|
||||
|
||||
|
@ -1561,7 +1552,7 @@ void recSUBop(int info, int regd)
|
|||
break;
|
||||
}
|
||||
|
||||
ClampValues2(regd);
|
||||
ClampValues(regd);
|
||||
_freeXMMreg(t0reg);
|
||||
}
|
||||
|
||||
|
|
|
@ -1364,7 +1364,7 @@ void recVUMI_FMEQ( VURegs *VU, int info )
|
|||
if ( _Ft_ == 0 ) return;
|
||||
//SysPrintf("recVUMI_FMEQ \n");
|
||||
if( _Ft_ == _Fs_ ) {
|
||||
ftreg = ALLOCVI(_Ft_, MODE_WRITE|MODE_READ);//|MODE_8BITREG);
|
||||
ftreg = ALLOCVI(_Ft_, MODE_WRITE|MODE_READ|MODE_8BITREG);
|
||||
|
||||
CMP16MtoR(ftreg, VU_VI_ADDR(REG_MAC_FLAG, 1));
|
||||
SETE8R(EAX);
|
||||
|
@ -1397,7 +1397,7 @@ void recVUMI_FMOR( VURegs *VU, int info )
|
|||
MOVZX32M16toR( ftreg, VU_VI_ADDR(REG_MAC_FLAG, 1) );
|
||||
}
|
||||
else if( _Ft_ == _Fs_ ) {
|
||||
ftreg = ALLOCVI(_Ft_, MODE_WRITE);//|MODE_READ|MODE_8BITREG);
|
||||
ftreg = ALLOCVI(_Ft_, MODE_WRITE|MODE_READ);//|MODE_8BITREG);
|
||||
OR16MtoR( ftreg, VU_VI_ADDR(REG_MAC_FLAG, 1) );
|
||||
}
|
||||
else {
|
||||
|
@ -1453,18 +1453,20 @@ void recVUMI_FCEQ( VURegs *VU, int info )
|
|||
//------------------------------------------------------------------
|
||||
void recVUMI_FCOR( VURegs *VU, int info )
|
||||
{
|
||||
int ftreg = ALLOCVI(1, MODE_WRITE|MODE_8BITREG);
|
||||
//SysPrintf("recVUMI_FCOR \n");
|
||||
MOV32MtoR( EAX, VU_VI_ADDR(REG_CLIP_FLAG, 1) );
|
||||
XOR32RtoR( ftreg, ftreg );
|
||||
OR32ItoR( EAX, VU->code );
|
||||
AND32ItoR( EAX, 0xffffff );
|
||||
CMP32ItoR( EAX, 0xffffff );
|
||||
|
||||
if(CHECK_FCORHACK) //ICO Misscalculated CLIP flag (bits missing id guess)
|
||||
SETNZ8R(ftreg);
|
||||
else
|
||||
SETZ8R(ftreg);
|
||||
int ftreg;
|
||||
//SysPrintf("recVUMI_FCOR\n");
|
||||
if(CHECK_FCORHACK) {//ICO Miss-calculated CLIP flag so always set to true (probably a zerorec pipeline problem)
|
||||
ftreg = ALLOCVI(1, MODE_WRITE|MODE_8BITREG);
|
||||
MOV32ItoR( ftreg, 1 );
|
||||
}
|
||||
else {
|
||||
ftreg = ALLOCVI(1, MODE_WRITE);
|
||||
MOV32MtoR( ftreg, VU_VI_ADDR(REG_CLIP_FLAG, 1) );
|
||||
OR32ItoR ( ftreg, VU->code );
|
||||
AND32ItoR( ftreg, 0xffffff );
|
||||
ADD32ItoR( ftreg, 1 ); // If 24 1's will make 25th bit 1, else 0
|
||||
SHR32ItoR( ftreg, 24 ); // Get the 25th bit (also clears the rest of the garbage in the reg)
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue