mirror of https://github.com/PCSX2/pcsx2.git
GSdx: Dynamic CRC hack: now supports CRC
. Allows to have a single dynaCRC DLL for several games, differentiated by their CRCs by using the new utility IsCRC(0x12345678, 0x87654321, ...). Note: With old GSdx (and updated new DynaCrcHack.c), IsCRC always returns false. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5215 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
13df336966
commit
253c0078d3
|
@ -5120,25 +5120,33 @@ public:
|
|||
// result contains the result of the hack call.
|
||||
|
||||
typedef uint32 (__cdecl* DynaHackType)(uint32, uint32, uint32, uint32, uint32, uint32, uint32, int32*, uint32, int32);
|
||||
typedef uint32 (__cdecl* DynaHackType2)(uint32, uint32, uint32, uint32, uint32, uint32, uint32, int32*, uint32, int32, uint32); // Also accept CRC
|
||||
|
||||
bool IsInvokedDynamicCrcHack( GSFrameInfo &fi, int& skip, int region, bool &result )
|
||||
bool IsInvokedDynamicCrcHack( GSFrameInfo &fi, int& skip, int region, bool &result, uint32 crc )
|
||||
{
|
||||
static AutoReloadLibrary dll( DYNA_DLL_PATH );
|
||||
static DynaHackType dllFunc = NULL;
|
||||
static DynaHackType2 dllFunc2 = NULL;
|
||||
|
||||
if( dll.isChanged() )
|
||||
{
|
||||
dllFunc = (DynaHackType)dll.GetSymbolAddress( "DynamicCrcHack" );
|
||||
printf( "GSdx: Dynamic CRC-hacks: %s\n", dllFunc?
|
||||
"Loaded OK (-> overriding internal hacks)" : "Not available (-> using internal hacks)");
|
||||
dllFunc = (DynaHackType)dll.GetSymbolAddress( "DynamicCrcHack" );
|
||||
dllFunc2 = (DynaHackType2)dll.GetSymbolAddress( "DynamicCrcHack2" );
|
||||
printf( "GSdx: Dynamic CRC-hacks%s: %s\n",
|
||||
((dllFunc && !dllFunc2)?" [Old dynaDLL - No CRC support]":""),
|
||||
dllFunc? "Loaded OK (-> overriding internal hacks)" :
|
||||
"Not available (-> using internal hacks)");
|
||||
}
|
||||
|
||||
if( !dllFunc )
|
||||
if( !dllFunc2 && !dllFunc )
|
||||
return false;
|
||||
|
||||
int32 skip32 = skip;
|
||||
bool hasSharedBits = GSUtil::HasSharedBits(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM);
|
||||
result = dllFunc( fi.FBP, fi.FPSM, fi.FBMSK, fi.TBP0, fi.TPSM, fi.TZTST, (uint32)fi.TME, &skip32, (uint32)region, (uint32)(hasSharedBits?1:0) )?true:false;
|
||||
if(dllFunc2)
|
||||
result = dllFunc2( fi.FBP, fi.FPSM, fi.FBMSK, fi.TBP0, fi.TPSM, fi.TZTST, (uint32)fi.TME, &skip32, (uint32)region, (uint32)(hasSharedBits?1:0), crc )?true:false;
|
||||
else
|
||||
result = dllFunc( fi.FBP, fi.FPSM, fi.FBMSK, fi.TBP0, fi.TPSM, fi.TZTST, (uint32)fi.TME, &skip32, (uint32)region, (uint32)(hasSharedBits?1:0) )?true:false;
|
||||
skip = skip32;
|
||||
|
||||
return true;
|
||||
|
@ -5289,7 +5297,7 @@ bool GSState::IsBadFrame(int& skip, int UserHacks_SkipDraw)
|
|||
g_crc_region = m_game.region;
|
||||
|
||||
#ifdef ENABLE_DYNAMIC_CRC_HACK
|
||||
bool res=false; if(IsInvokedDynamicCrcHack(fi, skip, g_crc_region, res)){ if( !res ) return false; } else
|
||||
bool res=false; if(IsInvokedDynamicCrcHack(fi, skip, g_crc_region, res, m_crc)){ if( !res ) return false; } else
|
||||
#endif
|
||||
if(gsc && !gsc(fi, skip))
|
||||
{
|
||||
|
|
|
@ -1,26 +1,37 @@
|
|||
@echo off
|
||||
set source=DynaCrcHack.c
|
||||
set tcc=tcc\tcc
|
||||
|
||||
@cd /D "%~d1%~p1" > nul
|
||||
pushd "%~dp0"
|
||||
|
||||
if not exist tcc\tcc.exe (
|
||||
echo.
|
||||
echo Missing ^<this-folder^>\tcc\tcc.exe
|
||||
echo.
|
||||
echo Please download TCC 0.9.25 for windows from http://bellard.org/tcc/
|
||||
echo and extract the package to ^<this-folder^>\tcc
|
||||
echo.
|
||||
pause
|
||||
goto end
|
||||
if exist %tcc%.exe goto pre
|
||||
|
||||
rem local tcc not found, try to invoke a global tcc
|
||||
set tcc=tcc
|
||||
%tcc% utils\ding.c -luser32 -o utils\ding.exe >nul 2>nul
|
||||
if %errorlevel% == 0 (
|
||||
echo.
|
||||
echo Using globally installed tcc ...
|
||||
echo.
|
||||
) else (
|
||||
echo.
|
||||
echo Missing ^<this-folder^>\tcc\tcc.exe
|
||||
echo.
|
||||
echo Please download TCC 0.9.25 for windows from http://bellard.org/tcc/
|
||||
echo and extract the package to ^<this-folder^>\tcc
|
||||
echo.
|
||||
pause
|
||||
goto end
|
||||
)
|
||||
|
||||
if not exist utils\waitForChange.exe tcc\tcc utils\waitForChange.c -o utils\waitForChange.exe
|
||||
if not exist utils\ding.exe tcc\tcc utils\ding.c -luser32 -o utils\ding.exe
|
||||
:pre
|
||||
if not exist utils\waitForChange.exe %tcc% utils\waitForChange.c -o utils\waitForChange.exe
|
||||
if not exist utils\ding.exe %tcc% utils\ding.c -luser32 -o utils\ding.exe
|
||||
|
||||
:start
|
||||
echo Compiling ...
|
||||
echo.
|
||||
tcc\tcc -shared -Wall %source%
|
||||
%tcc% -shared -Wall %source%
|
||||
if %errorlevel% == 0 (
|
||||
echo -^> OK
|
||||
utils\ding 2
|
||||
|
@ -38,4 +49,5 @@ echo.
|
|||
|
||||
goto start
|
||||
|
||||
:end
|
||||
:end
|
||||
popd
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
//some common tokens not available in C
|
||||
|
@ -53,7 +54,7 @@ enum GS_PSM{PSM_PSMCT32=0,PSM_PSMCT24=1,PSM_PSMCT16=2,PSM_PSMCT16S=10,PSM_PSMT8=
|
|||
#define skip (*pSkip)
|
||||
#define GSUtil_HasSharedBits(a,b,c,d) sharedBits
|
||||
#define GSC_AnyGame(a,b) _GSC_AnyGame()
|
||||
GSFrameInfo fi; int* pSkip; uint32 g_crc_region; uint32 sharedBits;
|
||||
GSFrameInfo fi; int* pSkip; uint32 g_crc_region; uint32 sharedBits; uint32 g_crc;
|
||||
|
||||
//utils
|
||||
const int MODE_3_DELAY = 750; // ms
|
||||
|
@ -61,7 +62,11 @@ void dprintf(const char* format, ...);
|
|||
void dings(const int n);
|
||||
bool isCornerTriggered();
|
||||
bool IsIn(const DWORD val, ...);
|
||||
#define END 0x72951413
|
||||
// END is a magic number, if we have such CRC - meh
|
||||
#define END (0x72951413)
|
||||
#define IsCRC(...) (g_crc!=END && IsIn(g_crc, __VA_ARGS__, END))
|
||||
// C99 syntax for variadic macro: #define FOO(fmt, ...) printf(fmt, __VA_ARGS__) // empty list not supported
|
||||
// empty list is possible by suppressing prior comma by using ##__VA_ARGS__
|
||||
|
||||
|
||||
// ---------- Configuration ---------------------------------
|
||||
|
@ -85,7 +90,7 @@ bool GSC_AnyGame( const GSFrameInfo& fi, int& skip )
|
|||
{
|
||||
|
||||
//Example: MGS3 CRC hack copied directly from GSState.cpp (see the Notes section exceptions):
|
||||
|
||||
if( IsCRC(0x086273D2, 0x26A6E286, 0x9F185CE1) ){ // 3 first MGS3 CRCs from GSCrc.c
|
||||
if(skip == 0)
|
||||
{
|
||||
if(fi.TME && fi.FBP == 0x02000 && fi.FPSM == PSM_PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01000) && fi.TPSM == PSM_PSMCT24)
|
||||
|
@ -120,17 +125,19 @@ bool GSC_AnyGame( const GSFrameInfo& fi, int& skip )
|
|||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*********** Dynamic CRC hack code ends here *****************/
|
||||
|
||||
|
||||
// Prints to the Debugger's output window or to DebugView ( http://technet.microsoft.com/en-us/sysinternals/bb896647 )
|
||||
void dprintf( const char* format, ...)
|
||||
{
|
||||
#define BUFSIZ 2048
|
||||
char buffer[BUFSIZ];
|
||||
#define _BUFSIZ 2048
|
||||
char buffer[_BUFSIZ];
|
||||
va_list args;
|
||||
va_start( args, format );
|
||||
if( 0 > vsnprintf( buffer, BUFSIZ, format, args ) )
|
||||
if( 0 > vsnprintf( buffer, _BUFSIZ, format, args ) )
|
||||
sprintf( buffer, "%s","<too-long-to-print>\n" );
|
||||
OutputDebugString( buffer );
|
||||
va_end( args );
|
||||
|
@ -200,24 +207,70 @@ bool preProcess_isAbort()
|
|||
}
|
||||
|
||||
|
||||
DWORD WINAPI thread_PrintStats( LPVOID lpParam );
|
||||
typedef struct _stats { uint32 overall, changed, skipped, nextPrint;} Stats;
|
||||
|
||||
#define DLL_EXPORT __declspec(dllexport)
|
||||
|
||||
#define CRC_HACK DynamicCrcHack
|
||||
#define CRC_HACK DynamicCrcHack2
|
||||
#define CRC_HACK_OLD DynamicCrcHack
|
||||
#if INITIAL_MODE == 0
|
||||
#define CRC_HACK Voldemort
|
||||
#define CRC_HACK_OLD Voldemort
|
||||
#endif
|
||||
DLL_EXPORT bool CRC_HACK (uint32 FBP, uint32 FPSM, uint32 FBMSK, uint32 TBP0, uint32 TPSM, uint32 TZTST,
|
||||
uint32 TME, int* _pSkip, uint32 _g_crc_region, uint32 _sharedBits)
|
||||
uint32 TME, int* _pSkip, uint32 _g_crc_region, uint32 _sharedBits, uint32 _crc)
|
||||
{
|
||||
|
||||
static Stats stat={overall:0, changed:0, skipped:0, nextPrint:0};
|
||||
|
||||
DWORD now=GetTickCount();
|
||||
if(stat.nextPrint <= now){
|
||||
dprintf("DH: Overall: %5d, skipped: %5d, actions:%5d\n", stat.overall, stat.skipped, stat.changed);
|
||||
stat.overall=stat.changed=stat.skipped=0;
|
||||
stat.nextPrint=now+1000;
|
||||
}
|
||||
|
||||
stat.overall++;
|
||||
|
||||
if(preProcess_isAbort()) // Process dings if required
|
||||
return true; // Abort hack depending on mode
|
||||
|
||||
fi.FBP=FBP; fi.FPSM=FPSM; fi.FBMSK=FBMSK; fi.TBP0=TBP0; fi.TPSM=TPSM; fi.TZTST=TZTST; fi.TME=TME;
|
||||
pSkip=_pSkip; g_crc_region=_g_crc_region; sharedBits=_sharedBits;
|
||||
pSkip=_pSkip; g_crc_region=_g_crc_region; sharedBits=_sharedBits; g_crc = _crc;
|
||||
|
||||
return _GSC_AnyGame();
|
||||
int pre=skip;
|
||||
bool res=_GSC_AnyGame();
|
||||
int post=skip;
|
||||
|
||||
if(skip) stat.skipped++;
|
||||
|
||||
if(post!=pre) stat.changed++;
|
||||
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
DLL_EXPORT bool CRC_HACK_OLD (uint32 FBP, uint32 FPSM, uint32 FBMSK, uint32 TBP0, uint32 TPSM, uint32 TZTST,
|
||||
uint32 TME, int* _pSkip, uint32 _g_crc_region, uint32 _sharedBits)
|
||||
{
|
||||
return CRC_HACK(FBP, FPSM, FBMSK, TBP0, TPSM, TZTST, TME,_pSkip, _g_crc_region,_sharedBits, END);
|
||||
}
|
||||
|
||||
char* v[]={
|
||||
"DLL_PROCESS_DETACH",
|
||||
"DLL_PROCESS_ATTACH",
|
||||
"DLL_THREAD_ATTACH",
|
||||
"DLL_THREAD_DETACH"
|
||||
};
|
||||
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
|
||||
{
|
||||
if (dwReason<4)
|
||||
dprintf("DllMain: %s\n", v[dwReason]);
|
||||
else
|
||||
dprintf("DllMain: %d\n", dwReason);
|
||||
return TRUE;
|
||||
}
|
||||
/*-------------------- Notes- -------------------------------*\
|
||||
|
||||
1. If required, Use CRC_<region> instead of CRC::<region> (e.g. CRC_US instead of CRC::US)
|
||||
|
@ -230,6 +283,10 @@ DLL_EXPORT bool CRC_HACK (uint32 FBP, uint32 FPSM, uint32 FBMSK, uint32 TBP0, ui
|
|||
|
||||
3. When copying the code back to GSState.cpp, remember to restore CRC::.. and GSUtil::...
|
||||
|
||||
4. GSdx v5215 onwards also sends the CRC of the game (even if it's not defined at GSdx).
|
||||
You can test the CRC using IsCRC(0x12345678) or, for few CRCs: IsCRC(0x12345678, 0x87654321, ...)
|
||||
NOTE: with GSdx v5214 and before: IsCRC(...) always returns false.
|
||||
|
||||
\*----------------------------------------------------------*/
|
||||
|
||||
/* --------------- Usage instructions --------------------------------------------*\
|
||||
|
|
Loading…
Reference in New Issue