The engine patch
The testing portrait I made:
There are 2 extra 16x16p tiles in the rightbottom corner. They can be displayed at any position. I added these parameters to the entry in the pointer table for controlling them.
the 17th byte : x-coordinate of the left tile
the 18th byte : y-coordinate of the left tile
the 19th byte : x-coordinate of the right tile
the 20th byte : y-coordinate of the right tile
the 27th byte : the flag which indicates whether the hackbox needs exceeding (1-yes 0-no)
the src
attribute((section(".displayPortrait")))
int displayPortrait(int a1)
{
int v1,v3,v4,v5,v6;
__int16 v2;
v1 = a1;
v2 = sub(0x8006D9C)(a1);
sub(0x8006A34)(
*(_BYTE *)(v1 + 65),
*(_WORD )(v1 + 52) & 0x1FF,
((-(v2 & 0x400) >> 31) & 0x400) + ((_WORD *)(v1 + 54) & 0xFF),
*(_DWORD *)(v1 + 56),
*(_WORD )(v1 + 60));
if((_BYTE )((_DWORD *)(v1 + 44) + 26) == 1)
{
v3 = 4 - *(_BYTE )((_DWORD *)(v1 + 44) + 16);
if ( !(sub(0x8006D9C)(v1) & 1) )
v3 = -v3;
v5 = (8 * v3 + *(_WORD *)(v1 + 52) - 16) & 0x1FF;
if ( sub(0x8006D9C)(v1) & 1 )
// LOWORD(v5) = v5 + 0x1000;
LOWORD(v5) = v5 + 0x1000 + 16;
v6 = sub(0x8006D9C)(v1);
sub(0x8006A34)(
*(_BYTE *)(v1 + 65),
v5,
((-(v6 & 0x400) >> 31) & 0x400)
- ((*(_WORD *)(v1 + 54) + 8 * *(_BYTE )((_DWORD *)(v1 + 44) + 17)) & 0xFF),
0x8B905B8,
*(_WORD *)(v1 + 60)+0x5C);
v3 = 4 - *(_BYTE )((_DWORD *)(v1 + 44) + 18);
if ( !(sub(0x8006D9C)(v1) & 1) )
v3 = -v3;
v5 = (8 * v3 + *(_WORD *)(v1 + 52) - 16) & 0x1FF;
if ( sub(0x8006D9C)(v1) & 1 )
// LOWORD(v5) = v5 + 0x1000;
LOWORD(v5) = v5 + 0x1000 + 16;
sub(0x8006A34)(
*(_BYTE *)(v1 + 65),
v5,
((-(v6 & 0x400) >> 31) & 0x400) - ((*(_WORD *)(v1 + 54) + 8 * *(_BYTE )((_DWORD *)(v1 + 44) + 19)) & 0xFF),
0x8B905B8,
*(_WORD *)(v1 + 60)+0x5E);
}
return v4;
}
attribute((section(".displayPortraitInBox")))
int displayPortraitInBox(int a1, unsigned __int16 a2, int a3)
{
int v3;
unsigned __int16 v4;
int v5;
int v6;
int v7;
int v9;
v3 = a1;
v4 = a2;
v5 = *(_BYTE *)(a3 + 20) - 1;
v6 = *(_BYTE *)(a3 + 21);
sub(0x80C57B4)(a1, 0x8195680, a2);
v7 = 2 * (32 * v6 + v5) + v3;
*(_WORD *)v7 = v4 + 28;
*(_WORD *)(v7 + 2) = v4 + 29;
*(_WORD *)(v7 + 4) = v4 + 30;
*(_WORD *)(v7 + 6) = v4 + 31;
*(_WORD *)(v7 + 64) = v4 + 60;
*(_WORD *)(v7 + 66) = v4 + 61;
*(_WORD *)(v7 + 68) = v4 + 62;
*(_WORD )(v7 + 70) = v4 + 63;
if((_BYTE *)(a3 + 26) == 1)
{
v5 = *(_BYTE *)(a3 + 16) - 1;
v6 = *(_BYTE *)(a3 + 17);
v7 = 2 * (32 * v6 + v5) + v3;
if(v5 > -1 && v5 < 10 && v6 >= 0 && v6 < 9)
*(_WORD *)v7 = v4 + 92;
if(v5 > -2 && v5 < 9 && v6 >= 0 && v6 < 9)
*(_WORD *)(v7 + 2) = v4 + 93;
if(v5 > -1 && v5 < 10 && v6 >= -1 && v6 < 8)
*(_WORD *)(v7 + 64) = v4 + 124;
if(v5 > -2 && v5 < 9 && v6 >= -1 && v6 < 8)
*(_WORD *)(v7 + 66) = v4 + 125;
v5 = *(_BYTE *)(a3 + 18) - 1;
v6 = *(_BYTE *)(a3 + 19);
v7 = 2 * (32 * v6 + v5) + v3;
if(v5 > -1 && v5 < 10 && v6 >= 0 && v6 < 9)
*(_WORD *)v7 = v4 + 94;
if(v5 > -2 && v5 < 9 && v6 >= 0 && v6 < 9)
*(_WORD *)(v7 + 2) = v4 + 95;
if(v5 > -1 && v5 < 10 && v6 >= -1 && v6 < 8)
*(_WORD *)(v7 + 64) = v4 + 126;
if(v5 > -2 && v5 < 9 && v6 >= -1 && v6 < 8)
*(_WORD *)(v7 + 66) = v4 + 127;
}
return v9;
}
attribute((section(".displayPortraitInBox2")))
int displayPortraitInBox2(int a1, unsigned __int16 a2, int a3)
{
int v3;
unsigned __int16 v4;
int v5;
int v6;
int v7;
int v9;
v3 = a1;
v4 = a2;
v5 = *(_BYTE *)(a3 + 20) - 1;
v6 = *(_BYTE *)(a3 + 21) - 1;
sub(0x80C57B4)(a1, 0x8195738, a2);
v7 = 2 * (32 * v6 + v5) + v3;
*(_WORD *)v7 = v4 + 28;
*(_WORD *)(v7 + 2) = v4 + 29;
*(_WORD *)(v7 + 4) = v4 + 30;
*(_WORD *)(v7 + 6) = v4 + 31;
*(_WORD *)(v7 + 64) = v4 + 60;
*(_WORD *)(v7 + 66) = v4 + 61;
*(_WORD *)(v7 + 68) = v4 + 62;
*(_WORD )(v7 + 70) = v4 + 63;
if((_BYTE *)(a3 + 26) == 1)
{
v5 = *(_BYTE *)(a3 + 16) - 1;
v6 = *(_BYTE *)(a3 + 17) - 1;
v7 = 2 * (32 * v6 + v5) + v3;
if(v5 > -1 && v5 < 10 && v6 >= 0 && v6 < 9)
*(_WORD *)v7 = v4 + 92;
if(v5 > -2 && v5 < 9 && v6 >= 0 && v6 < 9)
*(_WORD *)(v7 + 2) = v4 + 93;
if(v5 > -1 && v5 < 10 && v6 >= -1 && v6 < 8)
*(_WORD *)(v7 + 64) = v4 + 124;
if(v5 > -2 && v5 < 9 && v6 >= -1 && v6 < 8)
*(_WORD *)(v7 + 66) = v4 + 125;
v5 = *(_BYTE *)(a3 + 18) - 1;
v6 = *(_BYTE *)(a3 + 19) - 1;
v7 = 2 * (32 * v6 + v5) + v3;
if(v5 > -1 && v5 < 10 && v6 >= 0 && v6 < 9)
*(_WORD *)v7 = v4 + 94;
if(v5 > -2 && v5 < 9 && v6 >= 0 && v6 < 9)
*(_WORD *)(v7 + 2) = v4 + 95;
if(v5 > -1 && v5 < 10 && v6 >= -1 && v6 < 8)
*(_WORD *)(v7 + 64) = v4 + 126;
if(v5 > -2 && v5 < 9 && v6 >= -1 && v6 < 8)
*(_WORD *)(v7 + 66) = v4 + 127;
}
return v9;
}
attribute((section(".cutPortraitInBox")))
int cutPortraitInBox(int a1, int a2, int a3, int a4)
{
int v4; // r9@1
int v5; // r5@1
int v6; // r6@1
int v7; // r7@1
int *v8; // r4@2
int v9; // r0@6
signed int v10; // r1@6
// int v12; // [sp+18h] [bp-4h]@0
v4 = a1;
v5 = a2;
v6 = a3;
v7 = a4;
if ( a2 )
{
v8 = sub(0x8006B20)(a2);
sub(0x8001084)(v8[2], 32 * v7, 32);
if ( *v8 )
{
sub(0x8013168)((_BYTE *)v8, 32 * v6 + 100663296);
sub(0x8001084)(v8[2], 32 * v7, 32);
if ( sub(0x800721C)(v5) << 24 )
sub(0x80071C4)(v4, ((_WORD)v7 << 12) + (v6 & 0x3FF), (int)v8);
else
sub(0x8007170)(v4, ((_WORD)v7 << 12) + (v6 & 0x3FF), (int)v8);
v9 = v4;
v10 = 5;
do
{
if((_WORD *)v9 == 0xD0E7)
*(_WORD )v9 = 0;
if((_WORD *)(v9 + 18) == 0xD0E7)
*(_WORD *)(v9 + 18) = 0;
v9 += 64;
–v10;
}
while ( v10 >= 0 );
}
else
{
sub(0x8013168)((_BYTE *)v8[4], 32 * v6 + 100663296);
sub(0x801331C)(v4, (v7 << 12) + (v6 & 0x3FF), 10, 9);
}
}
// return v12;
return 1;
}