Again another donation another feature. Thanks for donating!
-updated to version 2.5- *Fixed a bug in DM that could cause a fatal read error when using devices with under 8GB size *Added a PADHOOK pattern for Batman:Vengeance *Added a screenshot feature This feature can be enabled/disabled via the DM(L) config Press R+Z on the fourth controller to take a screenshot any time! Screenshots will be saved to device:/screenshots in the YPbPr format, you can use my tool to convert them. git-svn-id: svn://localhost/Users/andi/Downloads/code/DML@33 be6c1b03-d731-4111-a574-e37d80d43941
This commit is contained in:
parent
a2190e4497
commit
c879f0d115
1
Config.h
1
Config.h
@ -65,6 +65,7 @@ enum dmlconfig
|
|||||||
DML_CFG_BOOT_DISC = (1<<10),
|
DML_CFG_BOOT_DISC = (1<<10),
|
||||||
DML_CFG_BOOT_DISC2 = (1<<11),
|
DML_CFG_BOOT_DISC2 = (1<<11),
|
||||||
DML_CFG_NODISC = (1<<12),
|
DML_CFG_NODISC = (1<<12),
|
||||||
|
DML_CFG_SCREENSHOT = (1<<13),
|
||||||
};
|
};
|
||||||
|
|
||||||
enum dmlvideomode
|
enum dmlvideomode
|
||||||
|
158
Patches.c
158
Patches.c
@ -6,6 +6,18 @@
|
|||||||
#include "CheatCode.c"
|
#include "CheatCode.c"
|
||||||
|
|
||||||
extern u32 DOLSize;
|
extern u32 DOLSize;
|
||||||
|
u32 FrameBuffer = 0;
|
||||||
|
u32 FBOffset = 0;
|
||||||
|
u32 FBEnable = 0;
|
||||||
|
u32 FBSize = 0;
|
||||||
|
|
||||||
|
unsigned char VISetFB[] =
|
||||||
|
{
|
||||||
|
0x38, 0x7F, 0x00, 0xF0, // mr %r3, %r7
|
||||||
|
0x38, 0x9F, 0x01, 0x24,
|
||||||
|
0x38, 0xBF, 0x01, 0x28,
|
||||||
|
0x38, 0xDF, 0x01, 0x3C,
|
||||||
|
};
|
||||||
|
|
||||||
unsigned char OSReportDM[] =
|
unsigned char OSReportDM[] =
|
||||||
{
|
{
|
||||||
@ -147,7 +159,7 @@ FuncPattern FPatterns[] =
|
|||||||
{ 0x2FC, 73, 8, 23, 16, 15, (u8*)NULL, 0xdead000B, "PADRead B", 2, 0 },
|
{ 0x2FC, 73, 8, 23, 16, 15, (u8*)NULL, 0xdead000B, "PADRead B", 2, 0 },
|
||||||
{ 0x3B0, 87, 13, 27, 17, 25, (u8*)NULL, 0xdead000B, "PADRead C", 2, 0 },
|
{ 0x3B0, 87, 13, 27, 17, 25, (u8*)NULL, 0xdead000B, "PADRead C", 2, 0 },
|
||||||
{ 0x334, 78, 7, 20, 17, 19, (u8*)NULL, 0xdead000B, "PADRead D", 2, 0 },
|
{ 0x334, 78, 7, 20, 17, 19, (u8*)NULL, 0xdead000B, "PADRead D", 2, 0 },
|
||||||
|
{ 0x2A8, 66, 4, 20, 17, 14, (u8*)NULL, 0xdead000B, "PADRead E", 2, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
FuncPattern CPatterns[] =
|
FuncPattern CPatterns[] =
|
||||||
@ -197,7 +209,97 @@ FuncPattern CPatterns[] =
|
|||||||
|
|
||||||
u32 CardLowestOff = 0;
|
u32 CardLowestOff = 0;
|
||||||
|
|
||||||
|
u32 FB[MAX_FB];
|
||||||
|
|
||||||
|
void SMenuAddFramebuffer( void )
|
||||||
|
{
|
||||||
|
u32 i,j,f;
|
||||||
|
|
||||||
|
if( *(vu32*)FBEnable != 1 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
FrameBuffer = (*(vu32*)FBOffset) & 0x7FFFFFFF;
|
||||||
|
|
||||||
|
for( i=0; i < MAX_FB; i++)
|
||||||
|
{
|
||||||
|
if( FB[i] ) //add a new entry
|
||||||
|
continue;
|
||||||
|
|
||||||
|
//check if we already know this address
|
||||||
|
f=0;
|
||||||
|
for( j=0; j<i; ++j )
|
||||||
|
{
|
||||||
|
if( FrameBuffer == FB[j] ) // already known!
|
||||||
|
{
|
||||||
|
f=1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( !f && FrameBuffer && FrameBuffer < 0x14000000 ) // add new entry
|
||||||
|
{
|
||||||
|
dbgprintf("ES:Added new FB[%d]:%08X\n", i, FrameBuffer );
|
||||||
|
FB[i] = FrameBuffer;
|
||||||
|
|
||||||
|
switch( *(vu32*)(FBEnable+0x20) )
|
||||||
|
{
|
||||||
|
case VI_NTSC:
|
||||||
|
FBSize = 304*480*4;
|
||||||
|
break;
|
||||||
|
case VI_PAL:
|
||||||
|
FBSize = 320*480*4;
|
||||||
|
break;
|
||||||
|
case VI_EUR60:
|
||||||
|
FBSize = 320*480*4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dbgprintf("ES:SMenuFindOffsets():Invalid Video mode:%d\n", *(vu32*)(FBEnable+0x20) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ScreenShot( void )
|
||||||
|
{
|
||||||
|
if( *(vu32*)FBEnable != 1 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
set32( HW_GPIO_OUT, 1<<5 );
|
||||||
|
|
||||||
|
char *str = (char*)malloc( 64 );
|
||||||
|
|
||||||
|
u32 i=0,r,wrote;
|
||||||
|
FIL SCRFile;
|
||||||
|
|
||||||
|
sprintf( str, "/screenshots" );
|
||||||
|
f_mkdir( str );
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
sprintf( str, "/screenshots/scrn_%02X.raw", i++ );
|
||||||
|
r = f_open( &SCRFile, str, FA_CREATE_NEW|FA_WRITE );
|
||||||
|
if( r == FR_OK )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if( r != FR_EXIST )
|
||||||
|
{
|
||||||
|
dbgprintf("Failed to create file:%u\n", r );
|
||||||
|
clear32( HW_GPIO_OUT, 1<<5 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while(1);
|
||||||
|
|
||||||
|
free(str);
|
||||||
|
|
||||||
|
if( r == FR_OK )
|
||||||
|
{
|
||||||
|
f_write( &SCRFile, (void*)(FB[0]), FBSize, &wrote );
|
||||||
|
f_close( &SCRFile );
|
||||||
|
}
|
||||||
|
|
||||||
|
clear32( HW_GPIO_OUT, 1<<5 );
|
||||||
|
}
|
||||||
void PatchB( u32 dst, u32 src )
|
void PatchB( u32 dst, u32 src )
|
||||||
{
|
{
|
||||||
u32 newval = (dst - src);
|
u32 newval = (dst - src);
|
||||||
@ -500,6 +602,10 @@ void DoPatches( char *ptr, u32 size, u32 SectionOffset )
|
|||||||
{
|
{
|
||||||
u32 i=0,j=0,k=0,value;
|
u32 i=0,j=0,k=0,value;
|
||||||
u32 PatchCount = 0;
|
u32 PatchCount = 0;
|
||||||
|
u32 r13 = 0;
|
||||||
|
|
||||||
|
FBOffset = 0;
|
||||||
|
FBEnable = 0;
|
||||||
|
|
||||||
dbgprintf("DoPatches( 0x%p, %d, 0x%X)\n", ptr, size, SectionOffset );
|
dbgprintf("DoPatches( 0x%p, %d, 0x%X)\n", ptr, size, SectionOffset );
|
||||||
|
|
||||||
@ -761,12 +867,54 @@ void DoPatches( char *ptr, u32 size, u32 SectionOffset )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( (PatchCount & 128) == 0 )
|
||||||
|
{
|
||||||
|
if( ConfigGetConfig(DML_CFG_SCREENSHOT) )
|
||||||
|
{
|
||||||
|
if( *(u32*)(ptr+i) >> 16 == 0x3DA0 && r13 == 0 )
|
||||||
|
{
|
||||||
|
r13 = ((*(u32*)(ptr+i)) & 0xFFFF) << 16;
|
||||||
|
r13|= (*(u32*)(ptr+i+4)) & 0xFFFF;
|
||||||
|
|
||||||
|
dbgprintf("Patch:r13:%08X\n", r13 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( memcmp( ptr+i, VISetFB, sizeof(VISetFB) ) == 0 && FBEnable == 0 )
|
||||||
|
{
|
||||||
|
dbgprintf("Patch:[VISetFB]%08X\n", (u32)ptr+i );
|
||||||
|
|
||||||
|
FBEnable = ( *(u32*)(ptr+i-4) );
|
||||||
|
|
||||||
|
if( FBEnable & 0x8000 )
|
||||||
|
{
|
||||||
|
FBEnable = ((~FBEnable) & 0xFFFF) + 1;
|
||||||
|
FBEnable = (r13 - FBEnable) & 0x7FFFFFF;
|
||||||
|
} else {
|
||||||
|
FBEnable = FBEnable & 0xFFFF;
|
||||||
|
FBEnable = (r13 + FBEnable) & 0x7FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
FBOffset = FBEnable - 0x08;
|
||||||
|
// dbgprintf("FBOffset:%08X\n", FBOffset );
|
||||||
|
// dbgprintf("FBEnable:%08X\n", FBEnable );
|
||||||
|
|
||||||
|
for( j=0; j < MAX_FB; ++j )
|
||||||
|
FB[j] = 0;
|
||||||
|
|
||||||
|
PatchCount |= 128;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PatchCount |= 128;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( ConfigGetConfig(DML_CFG_CHEATS) || ConfigGetConfig( DML_CFG_DEBUGGER ) )
|
if( ConfigGetConfig(DML_CFG_CHEATS) || ConfigGetConfig( DML_CFG_DEBUGGER ) )
|
||||||
{
|
{
|
||||||
if( PatchCount == 127 )
|
if( PatchCount == 255 )
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if( PatchCount == 111 )
|
if( PatchCount == 239 )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -881,8 +1029,8 @@ void DoPatches( char *ptr, u32 size, u32 SectionOffset )
|
|||||||
|
|
||||||
dbgprintf("Patch:[PADRead hook] %08X\n", FOffset + j );
|
dbgprintf("Patch:[PADRead hook] %08X\n", FOffset + j );
|
||||||
|
|
||||||
memcpy( (void*)0x2EE0, padipc, sizeof(padipc) );
|
memcpy( (void*)0x2ECC, padipc, sizeof(padipc) );
|
||||||
PatchB( 0x2EE0, FOffset + j );
|
PatchB( 0x2ECC, FOffset + j );
|
||||||
write32( 0x12FC, 0 );
|
write32( 0x12FC, 0 );
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
11
Patches.h
11
Patches.h
@ -10,6 +10,7 @@
|
|||||||
#include "dol.h"
|
#include "dol.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
|
|
||||||
|
#define MAX_FB 3
|
||||||
|
|
||||||
typedef struct PatchInfo
|
typedef struct PatchInfo
|
||||||
{
|
{
|
||||||
@ -60,12 +61,22 @@ typedef struct _gx_rmodeobj {
|
|||||||
u8 vfilter[7];
|
u8 vfilter[7];
|
||||||
} GXRModeObj;
|
} GXRModeObj;
|
||||||
|
|
||||||
|
|
||||||
|
#define VI_NTSC 0
|
||||||
|
#define VI_PAL 1
|
||||||
|
#define VI_MPAL 2
|
||||||
|
#define VI_DEBUG 3
|
||||||
|
#define VI_DEBUG_PAL 4
|
||||||
|
#define VI_EUR60 5
|
||||||
|
|
||||||
#define GXPal528IntDf 0
|
#define GXPal528IntDf 0
|
||||||
#define GXEurgb60Hz480IntDf 1
|
#define GXEurgb60Hz480IntDf 1
|
||||||
#define GXMpal480IntDf 2
|
#define GXMpal480IntDf 2
|
||||||
#define GXNtsc480IntDf 3
|
#define GXNtsc480IntDf 3
|
||||||
#define GXNtsc480Int 4
|
#define GXNtsc480Int 4
|
||||||
|
|
||||||
|
void SMenuAddFramebuffer( void );
|
||||||
|
void ScreenShot( void );
|
||||||
void DoPatches( char *ptr, u32 size, u32 SectionOffset );
|
void DoPatches( char *ptr, u32 size, u32 SectionOffset );
|
||||||
void DoCardPatches( char *ptr, u32 size, u32 SectionOffset );
|
void DoCardPatches( char *ptr, u32 size, u32 SectionOffset );
|
||||||
void DoPatchesLoader( char *ptr, u32 size );
|
void DoPatchesLoader( char *ptr, u32 size );
|
||||||
|
@ -4,8 +4,15 @@
|
|||||||
PADRead:
|
PADRead:
|
||||||
|
|
||||||
lis %r4, 0xCC00
|
lis %r4, 0xCC00
|
||||||
|
|
||||||
|
lwz %r5, 0x6428(%r4)
|
||||||
|
lwz %r0, 0x642C(%r4)
|
||||||
|
|
||||||
lwz %r0, 0x6404(%r4)
|
lwz %r0, 0x6404(%r4)
|
||||||
lwz %r4, 0x6408(%r4)
|
lwz %r4, 0x6408(%r4)
|
||||||
|
|
||||||
lis %r4, 0xC000
|
lis %r4, 0xC000
|
||||||
stw %r0, 0x12FC(%r4)
|
stw %r0, 0x12FC(%r4)
|
||||||
|
stw %r5, 0x12F8(%r4)
|
||||||
|
|
||||||
blr
|
blr
|
||||||
|
2
global.h
2
global.h
@ -15,7 +15,7 @@
|
|||||||
#define PADHOOK 1
|
#define PADHOOK 1
|
||||||
|
|
||||||
#define CONFIG_VERSION 0x00000002
|
#define CONFIG_VERSION 0x00000002
|
||||||
#define DML_VERSION 0x00020004
|
#define DML_VERSION 0x00020005
|
||||||
|
|
||||||
#define DI_SUCCESS 1
|
#define DI_SUCCESS 1
|
||||||
#define DI_ERROR 2
|
#define DI_ERROR 2
|
||||||
|
17
main.c
17
main.c
@ -20,7 +20,7 @@ Copyright (C) 2010-2012 crediar
|
|||||||
#include "DVD.h"
|
#include "DVD.h"
|
||||||
#include "Drive.h"
|
#include "Drive.h"
|
||||||
#include "dip.h"
|
#include "dip.h"
|
||||||
|
#include "Patches.h"
|
||||||
|
|
||||||
char __aeabi_unwind_cpp_pr0[0];
|
char __aeabi_unwind_cpp_pr0[0];
|
||||||
|
|
||||||
@ -221,15 +221,29 @@ int main( int argc, char *argv[] )
|
|||||||
write32( 0x30F8, 0 ); // Tell PPC side to start
|
write32( 0x30F8, 0 ); // Tell PPC side to start
|
||||||
|
|
||||||
ahb_flush_to( AHB_PPC );
|
ahb_flush_to( AHB_PPC );
|
||||||
|
|
||||||
|
u32 PADLock = 0;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
ahb_flush_from( AHB_STARLET ); //flush to arm
|
ahb_flush_from( AHB_STARLET ); //flush to arm
|
||||||
|
|
||||||
|
if( (((read32(0x12F8) >> 16) & 0x30) == 0x30 ) )
|
||||||
|
{
|
||||||
|
if( !PADLock )
|
||||||
|
{
|
||||||
|
ScreenShot();
|
||||||
|
PADLock = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PADLock = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if( (((read32(0x12FC) >> 16) & 0x1030) == 0x1030 ) )
|
if( (((read32(0x12FC) >> 16) & 0x1030) == 0x1030 ) )
|
||||||
{
|
{
|
||||||
SysReset();
|
SysReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (((read32(0x12FC) >> 16) & 0x234) == 0x234 ) )
|
if( (((read32(0x12FC) >> 16) & 0x234) == 0x234 ) )
|
||||||
{
|
{
|
||||||
SysShutdown();
|
SysShutdown();
|
||||||
@ -259,6 +273,7 @@ int main( int argc, char *argv[] )
|
|||||||
|
|
||||||
// write32(0x1860, 0xdeadbeef);
|
// write32(0x1860, 0xdeadbeef);
|
||||||
//}
|
//}
|
||||||
|
SMenuAddFramebuffer();
|
||||||
|
|
||||||
DIUpdateRegisters();
|
DIUpdateRegisters();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user