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:
cottonvibes 2009-02-21 17:33:10 +00:00
parent 4a8ba5cd40
commit de2e939fcc
4 changed files with 74 additions and 81 deletions

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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)
}
}
//------------------------------------------------------------------