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:
crediar@rypp.net 2012-11-09 20:30:55 +00:00
parent a2190e4497
commit c879f0d115
6 changed files with 189 additions and 7 deletions

View File

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

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

View File

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

View File

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

View File

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

@ -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];
@ -222,14 +222,28 @@ int main( int argc, char *argv[] )
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();