Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - ergonomy_joe

Pages: [1]
1
As a bonus, here is an old post where I give some insight of the .wat format:

https://magnetiktank.blogspot.com/2016/01/ff7s-chocobowat-having-fun-with-3d.html

2
I put the reversed code to the chocobo race mini-game online:

https://github.com/ergonomy-joe/ff7-chocobo/

The algorithm are there, it's up to you to make a sense out of it ^_^

Have retro-fun !

(please avoid pull requests)

3
Hi,

I'm not sure if that will help but here is the reversed code (in C) to the World module of the windows version of FF7: https://github.com/ergonomy-joe/ff7-worldmap

4
Here is a first draft of the format of the "amp" files:
Code: [Select]
u32 animationCount;and then, for each animation:
Code: [Select]
u32 boneCount;
u32 frameCount;
u32 dataSize;
Then follows the data (which size is dataSize, you use this size to skip to the next animation):
The data starts with a 5 bytes header:
Code: [Select]
u16 frameCount_bis;//save as frameCount
u16 size;//= dataSize +7
u8 rotValueShift;//can also be understood as "number of 0s"
What follows is the actual data, but the unit is not byte, it is bit. It's a little hard to explain so here it is:
Code: [Select]
//format for the first frame:
s16 posX,posY,posZ;//since data is a bitstream, there are to be read as BigEndian
sMax12 bone0_rotX,bone0_rotY,bone0_rotZ;
sMax12 bone1_rotX,bone1_rotY,bone1_rotZ;
//...
and the format for the remaining frames:
Code: [Select]
s7_16 transX,transY,transZ;
special bone0_rotX,bone0_rotY,bone0_rotZ;
special bone1_rotX,bone1_rotY,bone1_rotZ;
//...

"sMax12" means that the data is "up to 12 bits long". The actual size (in bits) is "12 - rotValueShift". And the read data must be shifted left by rotValueShift bits.
"s7_16" is a little trickier. You read one bit. If its value is 0, you read the next 7 bits. If it is 1, you read the next 16 bits.
"special" is beyond any possible explanation for me so here is the code that parses it (note that the next 3 bits are read and used to determine the type of data that follows):
Code: [Select]
//read "special" value from buffer?
short C_005E7CE4(unsigned char *bp08, int *pBitIndex/*bp0c*/, int dwRotShift/*bp10*/) {
struct {
int bp_08;
int dwValue;//bp_04
}lolo;

if(C_005E7C40(bp08, pBitIndex, 1) == 0)//read value from buffer?
return 0;
lolo.bp_08 = C_005E7C40(bp08, pBitIndex, 3) & 7;//read value from buffer?
switch(lolo.bp_08) {
case 0:
return 0xffffffff << dwRotShift;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
lolo.dwValue = C_005E7C40(bp08, pBitIndex, lolo.bp_08);//read value from buffer?
if(lolo.dwValue >= 0)
lolo.dwValue += BIT(lolo.bp_08 - 1);
else
lolo.dwValue -= BIT(lolo.bp_08 - 1);
return lolo.dwValue << dwRotShift;
case 7:
lolo.dwValue = C_005E7C40(bp08, pBitIndex, 12 - dwRotShift);//read value from buffer?
return lolo.dwValue << dwRotShift;
}//end switch

return 0;
}
"bp08" is a pointer to the data just after the "5 byte long" header.
"pBitIndex" is a pointer to the current index (in bit) in the data.

5
Hi there, I'm trying to undersand the **DA and **BA naming.

concerning the former, it seems that the file name is obfuscated from ".Axx" (xx being a number) filenames.
For example, "CLOUD.A00" is obfuscated into "RTDA".
The A stands for "amp" I guess (I got that from the source code debug info: amptoanm.cpp).
I found the code that parses those files but it is hard to read. I may post some info on the format later.

As for the **BA files I'm not sure because I could not find a runtime example.
They look very close to Polygon files, and there is an obfuscation for ".Pxx" files, but they do not end as **BA.
example: "CLOUD.P01" becomes "RTAN"

Here is my decompiled version of the obfuscation function at 0x005E2460:
Code: [Select]
//obfuscate name?
void C_005E2460(int dwCount/*bp08*/, struct t_battle_obfuscateInfo *bp0c, const char *pFName/*bp10*/, char *pObfuscated/*bp14*/) {
struct {
int dwDotIndex;//bp_ec
int dwLen;//bp_e8
int bp_e4;
int bp_e0;
int dwIndex;//bp_dc
int bp_d8;
int dwBase;//bp_d4
int i;//bp_d0
int dwFoundInfo;//bp_cc
char bp_c8[200];
}lolo;

//-- init --
if(bp0c[1].dwStartIndex == 0)
C_005E23F6(dwCount, bp0c);//compute dwStartIndex?
//-- --
lolo.dwFoundInfo = 0;
for(lolo.i = 0; lolo.i < dwCount; lolo.i ++) {
if(*(int *)bp0c->pPrefix == *(int *)pFName) {//compare 4 first characters
if(bp0c->dwFullName) {//else 005E258C
C_00682C91(pFName, lolo.bp_c8);//file:remove file extension
if(strcmp(bp0c->pPrefix, lolo.bp_c8) == 0) {
lolo.dwFoundInfo = 1;
break;
}
} else {
lolo.dwFoundInfo = 1;
break;
}
}
bp0c ++;
}//end for
//-- --
if(lolo.dwFoundInfo) {//else 005E28D0
//-- --
lolo.dwIndex = bp0c->dwStartIndex;
if(bp0c->dwCodeLength > 0) {//else 005E2688
lolo.bp_d8 = 0;
for(lolo.i = 0; lolo.i < bp0c->dwCodeLength; lolo.i ++) {
lolo.bp_e4 = pFName[bp0c->dwFirstChar + bp0c->dwCodeLength - (lolo.i + 1)] - '0';
if(lolo.i == 0) {
lolo.bp_d8 = lolo.bp_e4;
lolo.bp_e0 = 10;
} else {
lolo.bp_d8 += lolo.bp_e4 * lolo.bp_e0;
lolo.bp_e0 *= 10;
}
}//end for
lolo.dwIndex += lolo.bp_d8;
}
//-- --
lolo.dwBase = 0;
lolo.dwDotIndex = 0;
lolo.dwLen = strlen(pFName);
if(lolo.dwLen > 0) {//else 005E26F8
for(lolo.dwDotIndex = lolo.dwLen - 1; lolo.dwDotIndex >= 0; lolo.dwDotIndex --) {
if(pFName[lolo.dwDotIndex] == '.')
break;
}//end for
}
switch(pFName[lolo.dwDotIndex + 1]) {
case 'D':
lolo.dwBase = 0;
break;
case 'B':
lolo.dwBase = 1;
break;
case 'T':
lolo.dwBase = 2;
lolo.dwBase += (pFName[lolo.dwDotIndex + 2] - '0') * 10;
lolo.dwBase += pFName[lolo.dwDotIndex + 3] - '0';
break;
case 'P':
lolo.dwBase = 12;
lolo.dwBase += (pFName[lolo.dwDotIndex + 2] - '0') * 10;
lolo.dwBase += pFName[lolo.dwDotIndex + 3] - '0';
break;
case 'W':
lolo.dwBase = 62;
lolo.dwBase += (pFName[lolo.dwDotIndex + 2] - '0') * 10;
lolo.dwBase += pFName[lolo.dwDotIndex + 3] - '0';
break;
case 'A':
lolo.dwBase = 78;
break;
default:
sprintf(lolo.bp_c8, /*008FF9D4*/"ERROR: EXTENSION NOT SUPPORTED %s \n", pFName);
C_00664E30(lolo.bp_c8);//dx_dbg:kind of puts?
}//end switch
//-- --
pObfuscated[0] = (lolo.dwIndex / 26) + 'A';
pObfuscated[1] = (lolo.dwIndex % 26) + 'A';
pObfuscated[2] = (lolo.dwBase / 26) + 'A';
pObfuscated[3] = (lolo.dwBase % 26) + 'A';
pObfuscated[4] = 0;
}
}

the argument passed as "bp0c" is the array at 0x008FF2F0:
Code: [Select]
struct t_battle_obfuscateInfo {//size 0x18
/*00*/const char *pPrefix;
/*04*/int dwStartIndex;
/*08*/int dwCodeLength;
/*0c*/int dwFirstChar;
/*10*/int dwElementCount;
/*14*/int dwFullName;
};

struct t_battle_obfuscateInfo D_008FF2F0[0x17] = {
{/*008FF900*/"ENEMY",   0,3,5,0x172,0},
{/*008FF908*/"STAGE",   0,2,5,0x5a,0},
{/*008FF910*/"FROG",    0,0,0,1,0},
{/*008FF918*/"CLOUD",   0,0,0,1,0},
{/*008FF920*/"TIFA",    0,0,0,1,0},
{/*008FF928*/"EARITH",  0,0,0,1,0},
{/*008FF930*/"RED13",   0,0,0,1,0},
{/*008FF938*/"YUFI",    0,0,0,1,0},
{/*008FF940*/"KETCY",   0,0,0,1,0},
{/*008FF948*/"CID1",    0,0,0,1,0},
{/*008FF950*/"SEFIROS", 0,0,0,1,0},
{/*008FF958*/"BARRETT", 0,0,0,1,1},
{/*008FF960*/"BARRETT2",0,0,0,1,1},
{/*008FF96C*/"BARRETT3",0,0,0,1,1},
{/*008FF978*/"BARRETT4",0,0,0,1,0},
{/*008FF984*/"VINSENT", 0,0,0,1,1},
{/*008FF98C*/"VINSENT2",0,0,0,1,1},
{/*008FF998*/"VINSENT3",0,0,0,1,0},
{/*008FF9A4*/"HICLOUD", 0,0,0,1,0},
{/*008FF9AC*/"GALL",    0,0,0,1,0},
{/*008FF9B4*/"DEATHGIG",0,0,0,1,0},
{/*008FF9C0*/"HELLMASK",0,0,0,1,0},
{/*008FF9CC*/"CHAOS",   0,0,0,1,0}
};

6
You seem to be doing a great job quantumpencil.
Honestly this battle code is either a clever engineering job or a total mess, I cannot tell yet.
Either way, it is really hard to understand.
Just a thing, the array at 0x009ACB98 has a maximum size of 0x80.

7
Hi, it's me again.

I'm not sure I understand all you say, but here is my C version of the function at 0x0041FBA4:
Code: [Select]
//execute combat script?
void C_0041FBA4(short bp08, unsigned char **ppScriptData/*bp0c*/, int bp10, int bp14) {
struct {
struct tTextureObj *bp_38;
int bp_34;
tRGBA bp_30;
struct t_f0 *bp_2c;
short bp_28; char ___26[2];
tRGBA *bp_24;
void *bp_20;
int bp_1c;
int bp_18;
struct t_battle_ScriptContext *pScriptContext;//bp_14
int i;//bp_10
struct t_menu_temp_440 *bp_0c;
struct t_battle_B_Header *bp_08;
struct t_battle_B_Header *bp_04;
}lolo;

if(D_00DC0E6C)
return;
lolo.pScriptContext = (struct t_battle_ScriptContext *)D_008FE2AC;
D_009ADEF8 = 0;
lolo.pScriptContext->bScriptActive = 1;
//-- set script data --
lolo.pScriptContext->pScriptData = ppScriptData[D_00BE1178[bp08].wCurScriptId];
switch(D_00BE1178[bp08].wCurScriptId) {
case 0x2e: lolo.pScriptContext->pScriptData = D_007C10E0; break;
case 0x2f: lolo.pScriptContext->pScriptData = D_007C10F0; break;
case 0x30: lolo.pScriptContext->pScriptData = D_007C10F8; break;
case 0x31: lolo.pScriptContext->pScriptData = D_007C1120; break;
case 0x32: lolo.pScriptContext->pScriptData = D_007C1130; break;
case 0x34: lolo.pScriptContext->pScriptData = D_007C1118; break;
case 0x35: lolo.pScriptContext->pScriptData = D_007C1170; break;
case 0x36: lolo.pScriptContext->pScriptData = D_007C1160; break;
case 0x37: lolo.pScriptContext->pScriptData = D_007C1150; break;
case 0x38: lolo.pScriptContext->pScriptData = D_007C1140; break;
case 0x39:
D_00BE1178[bp08].f_0025 = D_00BE1178[bp08].f_0025 | 0x80;
lolo.pScriptContext->pScriptData = D_007C1110;
break;
case 0x3a: lolo.pScriptContext->pScriptData = D_007C1108; break;
case 0x3b: lolo.pScriptContext->pScriptData = D_007C110C; break;
}//end switch
//-- --
if(D_00BE1178[bp08].f_003e & 1) {
C_004254B0(bp08);
D_00BE1178[bp08].f_003e = D_00BE1178[bp08].f_003e & ~1;
}
if(D_00BE1178[bp08].f_003b) {//else 00424745
D_00BE1178[bp08].f_0b9c = 0;
while(lolo.pScriptContext->bScriptActive) {//else 00424745
lolo.pScriptContext->bOpcode = CURSCRIPT_GETBYTE;
switch(lolo.pScriptContext->bOpcode) {
case 0xfe:
if(D_00BE1178[bp08].f_003d == 0) {
lolo.pScriptContext->bOpcode = lolo.pScriptContext->pScriptData[D_00BE1178[bp08].f_003c];
if(lolo.pScriptContext->bOpcode == 0xc0) {
D_00BE1178[bp08].f_003c = 0;
D_00BE0E28[bp08].f_00 = 0;
D_00BF23C0[bp08].f_36 = 0;
D_00BE1178[bp08].f_0074 = 0;
D_00BE1178[bp08].f_003d = 0;
D_00BE1178[bp08].f_000e = lolo.pScriptContext->pScriptData[0];
D_00BE1178[bp08].wCurScriptId = D_00BF2DF8[bp08];
lolo.pScriptContext->pScriptData = ppScriptData[D_00BE1178[bp08].wCurScriptId];
C_004254B0(bp08);
}
}
break;
case 0x91:
*D_00C05FE8 = CURSCRIPT_GETBYTE;
lolo.pScriptContext->f_14 = C_005BED92(C_004255B7);
D_00BFC3A0[lolo.pScriptContext->f_14].f_04 = *D_00C05FE8;
break;
case 0x9c:
C_00430C9F();
break;
case 0xf8:
*D_00C05FE8 = CURSCRIPT_GETBYTE;
lolo.pScriptContext->f_0a = C_005BED92(C_00425AAD);
if(bp08 < 4) {
*D_00C05FF0 = bp08;
lolo.bp_04 = D_00BFB2B8[*D_00C05FF0]->f_00;
} else {
*D_00C05FF0 = D_00BF2054[bp08 - 4].f_00;
lolo.bp_04 = D_00BFB2B8[*D_00C05FF0]->f_00;
}
D_00BFC3A0[lolo.pScriptContext->f_0a].f_10 = lolo.bp_04->f_24[*D_00C05FE8];
D_00BFC3A0[lolo.pScriptContext->f_0a].f_06 = bp08;
D_00BFC3A0[lolo.pScriptContext->f_0a].f_18 = 0;
D_00BFC3A0[lolo.pScriptContext->f_0a].f_04 = 0;
D_00BF23C0[bp08].f_34 ++;
D_00BFC3A0[lolo.pScriptContext->f_0a].f_02 = D_00BF23C0[bp08].f_34;
break;
case 0xa9:
D_00BE1178[bp08].f_003c ++;
D_00BE1178[bp08].f_000e = CURSCRIPT_GETBYTE;
D_00BE1178[bp08].f_0074 = 0;
D_00BF23C0[bp08].f_36 = 0;
D_00BE0E28[bp08].f_00 = 0;
D_00C05F80 += 3;
*D_00C05FE8 = D_00C05F80 & 0xf;
for(lolo.i = 0; lolo.i < *D_00C05FE8; lolo.i ++) {
D_00BF23C0[bp08].f_36 ++;
C_00424B4B(bp08, bp10, bp14);
}//end for
lolo.pScriptContext->bScriptActive = 0;
break;
case 0x8f:
D_00BF2150 = 0;
break;
case 0x8e:
if(D_00BFB710 == 0) {
D_00BF2150 = 1;
D_00BFB710 = 1;
}
break;
case 0x92:
D_00BFB2EC = 1;
break;
case 0x93://some fade to white?
C_005BED92(C_005BCD42);
break;
case 0xb9:
D_00BF211C = CURSCRIPT_GETBYTE;
D_009AAD70[D_00BF2A38].f_08 = -2;
C_00430AA7();
break;
case 0xbc:
D_00BFCB28 = CURSCRIPT_GETBYTE;
break;
case 0xfd:
D_00BE1178[bp08].f_0140.f_26.f_00 = CURSCRIPT_GETWORD;
D_00BE1178[bp08].f_0140.f_26.f_02 = CURSCRIPT_GETWORD;
D_00BE1178[bp08].f_0140.f_26.f_04 = CURSCRIPT_GETWORD;
break;
case 0x94:
*D_00C05FE8 = CURSCRIPT_GETWORD;
*D_00C05FEC = CURSCRIPT_GETWORD;
*D_00C05FF0 = CURSCRIPT_GETBYTE;
lolo.pScriptContext->f_14 = C_005BECF1(C_00426899);
D_00BF2E70[lolo.pScriptContext->f_14].f_08 = bp08;
D_00BF2E70[lolo.pScriptContext->f_14].f_0a = *D_00C05FE8;
D_00BF2E70[lolo.pScriptContext->f_14].f_0c = *D_00C05FEC;
D_00BF2E70[lolo.pScriptContext->f_14].f_0e = (*D_00C05FEC - *D_00C05FE8) / *D_00C05FF0;
D_00BF2E70[lolo.pScriptContext->f_14].f_04 = *D_00C05FF0;
break;
case 0xba:
D_00BE1178[bp08].f_0140.f_1e.f_02 = D_00BE1178[bp08].f_0018;
D_00BE1178[bp08].f_0140.f_1e.f_02 += CURSCRIPT_GETWORD;
//break;
case 0xb4:
switch(D_00BFD0E0) {
case 2: D_00BE1178[bp08].f_0018 = 0x800; break;
case 4: D_00BE1178[bp08].f_0018 = 0; break;
}//end switch
D_00BE1178[bp08].f_0140.f_1e.f_02 = D_00BE1178[bp08].f_0018;
break;
case 0x95:
switch(D_00BFD0E0) {
case 1: break;
case 2: if(bp08 < 4) D_00BE1178[bp08].f_0018 = 0x800; break;
}//end switch
D_00BE1178[bp08].f_0140.f_1e.f_02 = D_00BE1178[bp08].f_0018;
break;
case 0xe5:
switch(D_00BFD0E0) {
case 4:
if(bp08 < 4 && (bp08 != D_00BFCDE0 || bp08 != D_00BE1170) && D_00BF2E1C == 0) {
if(bp08 == D_00BE1170) {//else 0042063A
if(D_00BE1178[D_00BFCDE0].f_0018 == 0)
D_00BE1178[bp08].f_0018 = 0x800;
else
D_00BE1178[bp08].f_0018 = 0;
} else {
if(D_00BE1178[D_00BE1170].f_0018 == 0)
D_00BE1178[bp08].f_0018 = 0x800;
else
D_00BE1178[bp08].f_0018 = 0;
}
}
break;
case 3: case 5: case 6:
if(bp08 >= 4) {
if(bp08 == D_00BE1170) {
if(D_00BE1178[D_00BFCDE0].f_0018 == 0)
D_00BE1178[bp08].f_0018 = 0x800;
else
D_00BE1178[bp08].f_0018 = 0;
} else {
if(D_00BE1178[D_00BE1170].f_0018 == 0)
D_00BE1178[bp08].f_0018 = 0x800;
else
D_00BE1178[bp08].f_0018 = 0;
}
}
break;
case 1:
if(bp08 >= 4)
D_00BE1178[bp08].f_0018 = 0x800;
break;
case 2:
if(bp08 < 4)
D_00BE1178[bp08].f_0018 = 0x800;
break;
}//end switch
D_00BE1178[bp08].f_0140.f_1e.f_02 = D_00BE1178[bp08].f_0018;
break;
case 0xc7:
lolo.pScriptContext->f_0e = bp08 + CURSCRIPT_GETWORD;
lolo.pScriptContext->f_10 = CURSCRIPT_GETBYTE;
if(lolo.pScriptContext->f_0e < 0xa && lolo.pScriptContext->f_0e >= 4) {//else 00420AA3
if((D_00BF23C0[bp08].f_0c & 4) == 0) {//else 0042091B
if(D_00BE1178[lolo.pScriptContext->f_0e].f_0025 & 0x80) {//else 00420916
D_00BE1178[lolo.pScriptContext->f_0e].f_0018 = D_00BE1178[bp08].f_0018;
D_00BE1178[lolo.pScriptContext->f_0e].f_0140.f_1e.f_02 = D_00BE1178[lolo.pScriptContext->f_0e].f_0018;
D_00BE1178[lolo.pScriptContext->f_0e].wCurScriptId = lolo.pScriptContext->f_10;
D_00BE1178[lolo.pScriptContext->f_0e].f_003e = D_00BE1178[lolo.pScriptContext->f_0e].f_003e | 1;
D_00BE1178[lolo.pScriptContext->f_0e].f_0026 = 0;
D_00BF23C0[lolo.pScriptContext->f_0e].f_0c = D_00BF23C0[lolo.pScriptContext->f_0e].f_0c | 4;
}
//goto 00420AA3
} else if(D_00BF23C0[bp08].f_0c & 8) {//else 00420AA3
if(D_00BF2E1C) {//else 00420A00
if(D_00BFD0DC == bp08 && (D_00BE1178[lolo.pScriptContext->f_0e].f_0025 & 0x80)) {//else 004209FB
D_00BE1178[lolo.pScriptContext->f_0e].wCurScriptId = lolo.pScriptContext->f_10;
D_00BE1178[lolo.pScriptContext->f_0e].f_003e = D_00BE1178[lolo.pScriptContext->f_0e].f_003e | 1;
D_00BE1178[lolo.pScriptContext->f_0e].f_0026 = 0;
D_00BF23C0[lolo.pScriptContext->f_0e].f_0c = D_00BF23C0[lolo.pScriptContext->f_0e].f_0c | 4;
}
//goto 00420AA3
} else if(D_00BE1178[lolo.pScriptContext->f_0e].f_0025 & 0x80) {//else 00420AA3
D_00BE1178[lolo.pScriptContext->f_0e].wCurScriptId = lolo.pScriptContext->f_10;
D_00BE1178[lolo.pScriptContext->f_0e].f_003e = D_00BE1178[lolo.pScriptContext->f_0e].f_003e | 1;
D_00BE1178[lolo.pScriptContext->f_0e].f_0026 = 0;
D_00BF23C0[lolo.pScriptContext->f_0e].f_0c = D_00BF23C0[lolo.pScriptContext->f_0e].f_0c | 4;
}
}
}
break;
case 0xf9:
D_00BE1178[bp08].f_0140.f_1e.f_02 = D_00BE1178[bp08].f_0018;
break;
case 0xe3:
D_00BFD0A0[D_00BE1170].wX = D_00BE1178[D_00BE1170].f_0140.f_26.f_00;
D_00BFD0A0[D_00BE1170].wZ = D_00BE1178[D_00BE1170].f_0140.f_26.f_04;
break;
case 0xd4:
lolo.pScriptContext->f_12 = CURSCRIPT_GETWORD;
lolo.pScriptContext->f_10 = CURSCRIPT_GETBYTE;
*D_00C05FE8 = lolo.pScriptContext->f_12 / lolo.pScriptContext->f_10;
lolo.pScriptContext->f_14 = C_005BECF1(C_004267F1);
D_00BF2E70[lolo.pScriptContext->f_14].f_08 = bp08;
D_00BF2E70[lolo.pScriptContext->f_14].f_0a = *D_00C05FE8;
D_00BF2E70[lolo.pScriptContext->f_14].f_04 = lolo.pScriptContext->f_10;
break;
case 0xdf:
C_005BFEC9(D_00BFD0F8, &(lolo.pScriptContext->f_16));
D_00BE1178[bp08].f_0140.f_1e.f_02 = C_00662573(lolo.pScriptContext->f_16.f_00 - D_00BE1178[bp08].f_0140.f_26.f_00, lolo.pScriptContext->f_16.f_04 - D_00BE1178[bp08].f_0140.f_26.f_04) + 0x800;
break;
case 0xfc:
if(D_00BF2E1C) {//else 00420D4B
switch(D_00BFD0E0) {
case 3: case 5: case 6: case 7:
for(lolo.i = 4; lolo.i < 0xa; lolo.i ++) {
if(D_00BE1178[bp08].f_0018 == 0)
D_00BE1178[lolo.i].f_0018 = 0x800;
else
D_00BE1178[lolo.i].f_0018 = 0;
}//end for
break;
case 4:
if(D_009A8748.f_162[0] & D_00BFD0F8)
D_00BE1178[bp08].f_0140.f_1e.f_02 = 0;
if(D_009A8748.f_162[2] & D_00BFD0F8)
D_00BE1178[bp08].f_0140.f_1e.f_02 = 0x800;
break;
}//end switch
//goto 00420E6A
} else if((D_00BE1178[bp08].cLimitBreakId != 0x15 || D_00BE1178[bp08].f_0023 != 0xd) && D_00BE1170 != D_00BFB198) {//else 00420E6A
D_00BE1178[bp08].f_0140.f_1e.f_02 = C_00662573(D_00BE1178[D_00BFB198].f_0140.f_26.f_00 - D_00BE1178[bp08].f_0140.f_26.f_00, D_00BE1178[D_00BFB198].f_0140.f_26.f_04 - D_00BE1178[bp08].f_0140.f_26.f_04) + 0x800;
D_00BF23C0[D_00BFB198].f_2c = C_00662573(D_00BE1178[D_00BFB198].f_0140.f_26.f_00 - D_00BE1178[bp08].f_0140.f_26.f_00, D_00BE1178[D_00BFB198].f_0140.f_26.f_04 - D_00BE1178[bp08].f_0140.f_26.f_04);
}
break;
case 0x9a: case 0xfb:
lolo.pScriptContext->f_12 = CURSCRIPT_GETWORD;
lolo.pScriptContext->f_0c = CURSCRIPT_GETWORD;
lolo.pScriptContext->f_08 = 0x1000 - (D_00BF23C0[D_00BFB198].f_2c + 0x800);
lolo.pScriptContext->f_0a =
FIX_MUL(lolo.pScriptContext->f_12, D_00BE1178[bp08].f_0006) +
FIX_MUL(D_00BE1178[D_00BFB198].f_0012, D_00BE1178[D_00BFB198].f_0006)
;
D_00BE1178[bp08].f_0140.f_26.f_00 = D_00BE1178[D_00BFB198].f_0140.f_26.f_00 - FIX_MUL(C_00662538(lolo.pScriptContext->f_08), lolo.pScriptContext->f_0a);
D_00BE1178[bp08].f_0140.f_26.f_04 = D_00BE1178[D_00BFB198].f_0140.f_26.f_04 + FIX_MUL(C_006624FD(lolo.pScriptContext->f_08), lolo.pScriptContext->f_0a);
D_00BE1178[bp08].f_0140.f_26.f_02 = lolo.pScriptContext->f_0c;
break;
case 0xa8:
*D_00C05FE8 = CURSCRIPT_GETBYTE;
*D_00C05FEC = CURSCRIPT_GETBYTE;
C_00426C9B(bp08, *D_00C05FEC, *D_00C05FE8);
break;
case 0xe9:
lolo.pScriptContext->f_12 = CURSCRIPT_GETWORD;
lolo.pScriptContext->f_10 = CURSCRIPT_GETBYTE;
*D_00C05FE8 = D_00BF23C0[bp08].f_28;
C_0042519A(bp08, lolo.pScriptContext->pScriptData, lolo.pScriptContext->f_12, C_00426A26, lolo.pScriptContext->f_10, &(D_00BE1178[D_00BFB198].f_0140.f_26));
break;
case 0x99:
D_00BE10B4 = CURSCRIPT_GETBYTE;
lolo.pScriptContext->f_12 = CURSCRIPT_GETWORD;
*D_00C05FE8 = CURSCRIPT_GETWORD;
lolo.pScriptContext->f_10 = CURSCRIPT_GETBYTE;
if(D_00BF2E1C == 0) {
C_0042519A(bp08, lolo.pScriptContext->pScriptData, lolo.pScriptContext->f_12, C_00426A26, lolo.pScriptContext->f_10, &(D_00BE1178[D_00BFB198].f_0140.f_26));
} else {
C_005BFEC9(D_00BFD0F8, &(lolo.pScriptContext->f_16));
C_0042519A(bp08, lolo.pScriptContext->pScriptData, lolo.pScriptContext->f_12, C_00426A26, lolo.pScriptContext->f_10, &(lolo.pScriptContext->f_16));
}
break;
case 0xd1:
lolo.pScriptContext->f_12 = CURSCRIPT_GETWORD;
*D_00C05FE8 = CURSCRIPT_GETWORD;
lolo.pScriptContext->f_10 = CURSCRIPT_GETBYTE;
if(D_00BF2E1C == 0) {
C_0042519A(bp08, lolo.pScriptContext->pScriptData, lolo.pScriptContext->f_12, C_00426A26, lolo.pScriptContext->f_10, &(D_00BE1178[D_00BFB198].f_0140.f_26));
} else {
C_005BFEC9(D_00BFD0F8, &(lolo.pScriptContext->f_16));
C_0042519A(bp08, lolo.pScriptContext->pScriptData, lolo.pScriptContext->f_12, C_00426A26, lolo.pScriptContext->f_10, &(lolo.pScriptContext->f_16));
}
break;
case 0xc8:
*D_00C05FE8 = CURSCRIPT_GETWORD;
*D_00C05FEC = CURSCRIPT_GETWORD;
*D_00C05FF0 = CURSCRIPT_GETBYTE;
*D_00C05FF4 = C_005BECF1(C_00426941);
D_00BF2E70[*D_00C05FF4].f_08 = bp08;
D_00BF2E70[*D_00C05FF4].f_0a = *D_00C05FE8;
D_00BF2E70[*D_00C05FF4].f_0c = *D_00C05FEC;
D_00BF2E70[*D_00C05FF4].f_04 = *D_00C05FF0;
break;
case 0xc3:
D_00BE1178[bp08].f_0026 = 1;
C_00425628(bp08);
lolo.pScriptContext->f_14 = C_005BECF1(C_005BBF31);
D_00BF2E70[lolo.pScriptContext->f_14].f_08 = bp08;
D_00BF2E70[lolo.pScriptContext->f_14].f_0a = 0;
D_00BF2E70[lolo.pScriptContext->f_14].f_06 = 1;
break;
case 0xb8:
D_00BE1178[bp08].f_0025 = D_00BE1178[bp08].f_0025 & ~0x80;
D_00BE1178[bp08].f_0025 = D_00BE1178[bp08].f_0025 | 4;
break;
case 0xb7:
C_00425890(bp08, 1);
break;
case 0xc4:
if(D_009ADF08 == 0) {
C_00430D32(0x185, -1, 0x40);
D_009ADF08 = 1;
}
*D_00C05FEC = CURSCRIPT_GETWORD;
*D_00C05FF0 = CURSCRIPT_GETBYTE;
*D_00C05FF4 = C_005BECF1(C_00426941);
D_00BF2E70[*D_00C05FF4].f_08 = bp08;
D_00BF2E70[*D_00C05FF4].f_0a = 0;
D_00BF2E70[*D_00C05FF4].f_04 = *D_00C05FF0;
switch(D_00BFD0E0) {
case 0: case 1: case 8:
*D_00C05FF8 = *D_00C05FEC;
break;
case 2:
*D_00C05FF8 = -*D_00C05FEC;
break;
case 3: case 5: case 6: case 7:
if(D_00BE1178[bp08].f_0018 == 0)
*D_00C05FF8 = *D_00C05FEC;
else
*D_00C05FF8 = -*D_00C05FEC;
break;
case 4:
if(D_009A8748.f_174) {
D_00BE1178[bp08].f_0140.f_1e.f_02 = 0;
*D_00C05FF8 = *D_00C05FEC;
} else {
D_00BE1178[bp08].f_0140.f_1e.f_02 = 0x800;
*D_00C05FF8 = -*D_00C05FEC;
}
break;
}//end switch
D_00BF2E70[*D_00C05FF4].f_0c = *D_00C05FF8;
break;
case 0xbd:
D_00BF2370 = 1;
lolo.pScriptContext->f_12 = CURSCRIPT_GETWORD;
lolo.pScriptContext->f_0c = CURSCRIPT_GETWORD;
C_00424FF1(bp08, D_00BFB198, lolo.pScriptContext->f_12, lolo.pScriptContext->f_0c);
break;
case 0xa6:
D_00BE1178[D_00BFCB68].f_0140.f_26.f_00 = D_00BFD0A0[D_00BFCB68].wX;
D_00BE1178[D_00BFCB68].f_0140.f_26.f_02 = D_00BFD0A0[D_00BFCB68].wY;
D_00BE1178[D_00BFCB68].f_0140.f_26.f_04 = D_00BFD0A0[D_00BFCB68].wZ;
break;
case 0xab:
*D_00C05FE8 = CURSCRIPT_GETWORD;
lolo.pScriptContext->f_12 = 0;
lolo.pScriptContext->f_0c = CURSCRIPT_GETWORD;
D_00BE1178[bp08].f_0140.f_26.f_00 = D_00BFD0A0[D_00BFCB68].wX;
D_00BE1178[bp08].f_0140.f_26.f_02 = D_00BFD0A0[D_00BFCB68].wY;
D_00BE1178[bp08].f_0140.f_26.f_04 = D_00BFD0A0[D_00BFCB68].wZ;
D_00BE1178[bp08].f_0140.f_1e.f_02 = D_00BE1178[D_00BFCB68].f_0018;
lolo.pScriptContext->f_12 = *D_00C05FE8;
lolo.pScriptContext->f_0c = 0;
lolo.pScriptContext->f_08 = 0x1000 - (D_00BE1178[D_00BE1170].f_0140.f_1e.f_02 + 0x800);
lolo.pScriptContext->f_0a = FIX_MUL(lolo.pScriptContext->f_12, D_00BE1178[D_00BFCB68].f_0006) + FIX_MUL(D_00BE1178[bp08].f_0012, D_00BE1178[bp08].f_0006);
D_00BE1178[D_00BFCB68].f_0140.f_26.f_00 = D_00BE1178[bp08].f_0140.f_26.f_00 - FIX_MUL(C_00662538(lolo.pScriptContext->f_08), lolo.pScriptContext->f_0a);
D_00BE1178[D_00BFCB68].f_0140.f_26.f_04 = D_00BE1178[bp08].f_0140.f_26.f_04 + FIX_MUL(C_006624FD(lolo.pScriptContext->f_08), lolo.pScriptContext->f_0a);
D_00BE1178[D_00BFCB68].f_0140.f_26.f_02 = lolo.pScriptContext->f_0c;
break;
case 0xcc:
lolo.pScriptContext->f_12 = 0;
*D_00C05FE8 = 0;
lolo.pScriptContext->f_10 = CURSCRIPT_GETBYTE;
C_005BFEC9(D_00BFD0F8, &(lolo.pScriptContext->f_16));
lolo.pScriptContext->f_16.f_00 = lolo.pScriptContext->f_16.f_00 << 1;
lolo.pScriptContext->f_16.f_04 = lolo.pScriptContext->f_16.f_04 << 1;
C_0042519A(bp08, lolo.pScriptContext->pScriptData, lolo.pScriptContext->f_12, C_00426A26, lolo.pScriptContext->f_10, &(lolo.pScriptContext->f_16));
break;

case 0xa3:
C_00740D80(0xa4, CURSCRIPT_GETBYTE, 0, 0, 0, 0, 0, 0, 0);
break;
case 0xcb:
*D_00C05FE8 = CURSCRIPT_GETBYTE;
*D_00C05FEC = CURSCRIPT_GETWORD;
*D_00C05FF0 = CURSCRIPT_GETBYTE;
*D_00C06000 = CURSCRIPT_GETBYTE;
*D_00C06004 = CURSCRIPT_GETBYTE;
*D_00C05FF4 = CURSCRIPT_GETBYTE;
*D_00C05FF8 = CURSCRIPT_GETBYTE;
*D_00C05FFC = ((*D_00C05FF0 & 0xff) << 10) | ((*D_00C06000 & 0xff) << 5) | (*D_00C06004 & 0xff);
if(*D_00C05FE8 == 0xff)
C_005BF388(bp08, 0, *D_00C05FEC, *D_00C05FFC, *D_00C05FF4, *D_00C05FF8);
else
C_005BF388(bp08, *D_00C05FE8, *D_00C05FEC, *D_00C05FFC, *D_00C05FF4, *D_00C05FF8);
break;
case 0xd5:
lolo.pScriptContext->f_12 = CURSCRIPT_GETWORD;
*D_00C05FEC = CURSCRIPT_GETWORD;
*D_00C05FE8 = CURSCRIPT_GETWORD;
*D_00C05FF0 = CURSCRIPT_GETBYTE;
*D_00C05FF4 = CURSCRIPT_GETBYTE;
lolo.pScriptContext->f_10 = *D_00C05FF4;
C_0042519A(bp08, lolo.pScriptContext->pScriptData, lolo.pScriptContext->f_12, C_004270DE, lolo.pScriptContext->f_10, &(D_00BE1178[D_00BFB198].f_0140.f_26));
break;
case 0xcf:
lolo.pScriptContext->f_12 = CURSCRIPT_GETWORD;
*D_00C05FEC = CURSCRIPT_GETWORD;
*D_00C05FE8 = CURSCRIPT_GETWORD;
*D_00C05FF0 = CURSCRIPT_GETBYTE;
*D_00C05FF4 = CURSCRIPT_GETBYTE;
lolo.pScriptContext->f_10 = *D_00C05FF4;
C_0042519A(bp08, lolo.pScriptContext->pScriptData, lolo.pScriptContext->f_12, C_0042739D, lolo.pScriptContext->f_10, &(D_00BE1178[D_00BFB198].f_0140.f_26));
break;
case 0xe7:
*D_00C05FF0 = CURSCRIPT_GETBYTE;
if(*D_00C05FF0 == 0)
D_00BE1178[bp08].f_0025 = D_00BE1178[bp08].f_0025 | 4;
else
D_00BE1178[bp08].f_0025 = D_00BE1178[bp08].f_0025 & ~4;
break;
case 0xf5:
*D_00C05FF4 = CURSCRIPT_GETBYTE;
D_00BF2054[bp08 - 4].f_00 = *D_00C05FF4 + 3;
C_0042BC15(bp08);
D_00BE1178[bp08].f_003e = D_00BE1178[bp08].f_003e | 1;
break;
case 0xd0:
lolo.pScriptContext->f_12 = CURSCRIPT_GETWORD;
*D_00C05FE8 = CURSCRIPT_GETBYTE;
switch(*D_00C05FE8) {
case 0: case 1: case 2: case 3: lolo.pScriptContext->f_10 = 5; break;
case 4: case 5: case 6: case 7: lolo.pScriptContext->f_10 = 8; break;
}//end switch
if(D_00BF2E1C == 0) {
C_0042519A(bp08, lolo.pScriptContext->pScriptData, lolo.pScriptContext->f_12, C_00426F58, lolo.pScriptContext->f_10, &(D_00BE1178[D_00BFB198].f_0140.f_26));
} else {
C_005BFEC9(D_00BFD0F8, &(lolo.pScriptContext->f_16));
C_0042519A(bp08, lolo.pScriptContext->pScriptData, lolo.pScriptContext->f_12, C_00426F58, lolo.pScriptContext->f_10, &(lolo.pScriptContext->f_16));
}
break;
case 0xf3:
if(D_00BE1178[bp08].f_003d) {
D_00BE1178[bp08].f_003d --;
D_00BE1178[bp08].f_003c --;
lolo.pScriptContext->bScriptActive = 0;
return;
}
break;
case 0xf4:
D_00BE1178[bp08].f_003d = CURSCRIPT_GETBYTE;
break;
case 0xc5:
D_00BE1178[bp08].f_003d = D_00BFD0F0;
break;
case 0xfa:
C_00425119(bp08);
break;
case 0xc2:
*D_00C05FE8 = CURSCRIPT_GETBYTE;
*D_00C05FEC = C_005BEC50(C_00425D29);
D_00BFB718[*D_00C05FEC].f_08 = D_00BFCDE0;
lolo.i = C_0042DE25(D_00BFCDE0);
D_00BFB718[*D_00C05FEC].f_0a = D_00BF2A40[lolo.i].f_00;
D_00BFB718[*D_00C05FEC].f_0e = D_00BF2A40[lolo.i].f_02;
D_00BFB718[*D_00C05FEC].f_06 = D_00BF2A40[lolo.i].f_08;
D_00BFB718[*D_00C05FEC].f_19 = D_00BF2A40[lolo.i].f_0a;
D_00BFB718[*D_00C05FEC].f_04 = *D_00C05FE8;
break;
case 0xf7:
D_00BF23BC = 0;
*D_00C05FE8 = CURSCRIPT_GETBYTE;
C_005BE9F0(D_00BFD0F8, *D_00C05FE8, 1);
break;
case 0xa1:
D_00BF23BC = 0;
*D_00C05FE8 = CURSCRIPT_GETBYTE;
*D_00C05FEC = CURSCRIPT_GETBYTE;
C_005BEB27(*D_00C05FE8, *D_00C05FEC);
break;
case 0xbe:
D_00BF23BC = 1;
*D_00C05FE8 = CURSCRIPT_GETBYTE;
if(
D_009A8748.f_0ac[D_00BE1170].f_00 != 2 ||
*D_00C05FE8 != 8 ||
!(D_009A8748.f_0ac[D_00BFCDE0].f_08 & 0x00000800)
) {
C_005BE9F0(D_00BFD0F8, *D_00C05FE8, 1);
}
break;
case 0xf6:
if(D_00BFC398 == 0) {
if(D_00BFCB20 & BIT(bp08))
C_00425890(bp08, 1);
} else {
if(D_00BF23C0[bp08].f_0c & 0x10)
C_00425890(bp08, 1);
}
break;
case 0xce:
if(bp08 >= 4) {
while(CURSCRIPT_GETBYTE != 0xcd)
;
}
break;
case 0xb3:
if(D_00BF23C0[bp08].f_00 & 0x1000) {
while(CURSCRIPT_GETBYTE != 0xb2)
;
}
break;
case 0xbf:
*D_00C05FE8 = CURSCRIPT_GETBYTE;
*D_00C05FEC = CURSCRIPT_GETBYTE;
D_00BFCDF0[*D_00C05FE8] = *D_00C05FEC;
C_004254E8();
break;
case 0xc1:
D_00BE1178[bp08].f_003c = 0;
while(CURSCRIPT_GETBYTE != 0xc9)
;
break;
case 0xca:
if(D_00BF2A30) {
D_00BE1178[bp08].f_003c = 0;
while(CURSCRIPT_GETBYTE != 0xc9)
;
}
break;
case 0xed:
*D_00C05FE8 = D_00BE1178[bp08].f_0140.f_1e.f_02;
D_00BE1178[bp08].f_0140.f_26.f_00 -= FIX_MUL(C_00662538(*D_00C05FE8), 0x204);
D_00BE1178[bp08].f_0140.f_26.f_04 -= FIX_MUL(C_006624FD(*D_00C05FE8), 0x204);
break;
case 0xe4:
*D_00C05FE8 = D_00BE1178[bp08].f_0140.f_1e.f_02 + 0x800;
D_00BE1178[bp08].f_0140.f_26.f_00 -= FIX_MUL(C_00662538(*D_00C05FE8), 0x204);
D_00BE1178[bp08].f_0140.f_26.f_04 -= FIX_MUL(C_006624FD(*D_00C05FE8), 0x204);
break;
case 0xb1:
*D_00C05FE8 = D_00BE1178[bp08].f_0140.f_1e.f_02;
D_00BE1178[bp08].f_0140.f_26.f_00 -= FIX_MUL(C_00662538(*D_00C05FE8), 0x102);
D_00BE1178[bp08].f_0140.f_26.f_04 -= FIX_MUL(C_006624FD(*D_00C05FE8), 0x102);
break;
case 0xb0:
*D_00C05FE8 = D_00BE1178[bp08].f_0140.f_1e.f_02 + 0x800;
D_00BE1178[bp08].f_0140.f_26.f_00 -= FIX_MUL(C_00662538(*D_00C05FE8), 0x102);
D_00BE1178[bp08].f_0140.f_26.f_04 -= FIX_MUL(C_006624FD(*D_00C05FE8), 0x102);
break;
case 0xd7:
*D_00C05FE8 = CURSCRIPT_GETBYTE;
*D_00C05FEC = CURSCRIPT_GETBYTE;
lolo.pScriptContext->f_0a = C_005BED92(C_004276B6);
D_00BFC3A0[lolo.pScriptContext->f_0a].f_04 = *D_00C05FE8;
D_00BFC3A0[lolo.pScriptContext->f_0a].f_06 = *D_00C05FEC;
D_00BFC3A0[lolo.pScriptContext->f_0a].f_08 = bp08;
break;
case 0xd8:
*D_00C05FE8 = CURSCRIPT_GETBYTE;
*D_00C05FEC = CURSCRIPT_GETWORD;
lolo.pScriptContext->f_0a = C_005BED92(C_00427737);
D_00BFC3A0[lolo.pScriptContext->f_0a].f_04 = *D_00C05FE8;
D_00BFC3A0[lolo.pScriptContext->f_0a].f_06 = *D_00C05FEC;
break;
case 0xf2:
break;
case 0x9e:
if(bp08 == D_00BFCDE0) {//else 00422DA4
if(D_00C05EBC == 0) {
D_00BE1178[bp08].f_0026 = 1;
return;
}
D_00BE1178[bp08].f_003c --;
return;
}
if(D_00BE1178[D_00BFCDE0].f_0026 == 1 && D_00C05EBC == 0) {
D_00BE1178[bp08].f_0026 = 1;
return;
}
D_00BE1178[bp08].f_003c --;
return;
//break;
case 0xee:
case 0xff:
D_00BF23C0[bp08].f_0c = D_00BF23C0[bp08].f_0c & ~4;
D_00BE1178[bp08].f_0026 = 1;
D_00BF23C0[bp08].f_0c = D_00BF23C0[bp08].f_0c & ~8;
D_00BF2DF8[bp08] = D_009A8748.f_0ac[bp08].f_01;
D_00BE1178[bp08].wCurScriptId = D_00BF2DF8[bp08];
lolo.pScriptContext->pScriptData = ppScriptData[D_00BE1178[bp08].wCurScriptId];
C_004254B0(bp08);
break;
case 0xf1:
D_00BF23C0[bp08].f_0c = D_00BF23C0[bp08].f_0c & ~4;
D_00BE1178[bp08].f_0026 = 1;
D_00BF23C0[bp08].f_0c = D_00BF23C0[bp08].f_0c & ~8;
D_00BE1178[bp08].f_003c --;
return;
//break;
case 0xa0:
D_00BF23C0[D_00BFB198].f_0c = D_00BF23C0[D_00BFB198].f_0c | 1;
*D_00C05FE8 = CURSCRIPT_GETBYTE;
C_00430A99(&(D_00BE1178[bp08].f_0174[*D_00C05FE8]), &(D_00BE1178[D_00BFB198].f_0140));
D_00BE1178[D_00BFB198].f_0140.f_1e.f_02 = 0;
D_00BE1178[D_00BFB198].f_0140.f_1e.f_00 = 0;
D_00BE1178[D_00BFB198].f_0140.f_26.f_00 = D_00BE1178[D_00BFB198].f_0140.f_26.f_02 = D_00BE1178[D_00BFB198].f_0140.f_26.f_04 = 0;
D_00BE1178[D_00BFB198].f_0140.f_1e.f_04 = 0x800;
D_00BE1178[D_00BFB198].f_0025 = D_00BE1178[D_00BFB198].f_0025 | 0x10;
D_00BE1178[D_00BFB198].f_1ae4 = bp08;
D_00BE1178[D_00BFB198].f_1ae8 = *D_00C05FE8;
break;
case 0xaf:
D_00BF23C0[D_00BFB198].f_0c = D_00BF23C0[D_00BFB198].f_0c | 1;
*D_00C05FE8 = CURSCRIPT_GETBYTE;
C_00430A99(&(D_00BE1178[bp08].f_0174[*D_00C05FE8]), &(D_00BE1178[D_00BFB198].f_0140));
D_00BE1178[D_00BFB198].f_0140.f_1e.f_00 = D_00BE1178[D_00BFB198].f_0140.f_1e.f_02 = D_00BE1178[D_00BFB198].f_0140.f_1e.f_04 = 0;
D_00BE1178[D_00BFB198].f_0140.f_26.f_00 = D_00BE1178[D_00BFB198].f_0140.f_26.f_02 = D_00BE1178[D_00BFB198].f_0140.f_26.f_04 = 0;
D_00BE1178[D_00BFB198].f_0025 = D_00BE1178[D_00BFB198].f_0025 | 0x10;
D_00BE1178[D_00BFB198].f_1ae4 = bp08;
D_00BE1178[D_00BFB198].f_1ae8 = *D_00C05FE8;
break;
case 0xae:
D_00BF23C0[D_00BFB198].f_0c = D_00BF23C0[D_00BFB198].f_0c & ~1;
C_00430A99(D_00BF2168, &(D_00BE1178[D_00BFB198].f_0140));
D_00BE1178[D_00BFB198].f_0140.f_26.f_00 = D_00BFD0A0[D_00BFB198].wX;
D_00BE1178[D_00BFB198].f_0140.f_26.f_02 = D_00BFD0A0[D_00BFB198].wY;
D_00BE1178[D_00BFB198].f_0140.f_26.f_04 = D_00BFD0A0[D_00BFB198].wZ;
D_00BE1178[D_00BFB198].f_0140.f_1e.f_00 = D_00BE1178[D_00BFB198].f_0140.f_1e.f_02 = D_00BE1178[D_00BFB198].f_0140.f_1e.f_04 = 0;
D_00BE1178[D_00BFB198].f_0025 = D_00BE1178[D_00BFB198].f_0025 & ~0x10;
break;
case 0x9d://limit2/tifa1 related?
*D_00C05FE8 = CURSCRIPT_GETBYTE;
switch(*D_00C05FE8) {
case 0: C_004E1627(D_00BFD0F8, D_00BE1170); break;
case 1: C_004E163E(D_00BFD0F8, D_00BE1170); break;
case 2: C_004E1655(D_00BFD0F8, D_00BE1170); break;
case 3: C_004E166C(D_00BFD0F8, D_00BE1170); break;
case 4: C_004E1683(D_00BFD0F8, D_00BE1170); break;
case 5: C_004E169A(D_00BFD0F8, D_00BE1170); break;
case 6: C_004E16B1(D_00BFD0F8, D_00BE1170); break;
}//end switch
break;
case 0xda:
D_00BE1178[bp08].cLimitBreakId = CURSCRIPT_GETBYTE;
D_00BE1178[bp08].f_0023 = 2;
break;
case 0x96:
lolo.pScriptContext->f_0a = CURSCRIPT_GETBYTE;
lolo.pScriptContext->f_0c = CURSCRIPT_GETBYTE;
lolo.bp_0c = C_006CB98E(bp08);//get character's info object?
if(lolo.bp_0c) {
lolo.pScriptContext->f_0e = D_007C10B8[lolo.bp_0c->f_408.f_09 & 0xf];
C_0043930D(D_00BFCDE0, bp08, -1, lolo.pScriptContext->f_0e, lolo.pScriptContext->f_0a, lolo.pScriptContext->f_0c);//MAGIC/MGUN
}
break;
case 0xdc:
lolo.pScriptContext->f_0a = CURSCRIPT_GETBYTE;
D_00BE1178[bp08].f_001a[lolo.pScriptContext->f_0a] = FIX_MUL(CURSCRIPT_GETWORD, D_00BE1178[bp08].f_0006);
break;
case 0xde:
lolo.pScriptContext->f_0a = CURSCRIPT_GETBYTE;
lolo.pScriptContext->f_0c = CURSCRIPT_GETBYTE;
C_00439907(D_00BFCDE0, bp08, lolo.pScriptContext->f_0a, lolo.pScriptContext->f_0c);//MAGIC/MGUN
break;
case 0xdd:
lolo.pScriptContext->f_0a = CURSCRIPT_GETBYTE;
lolo.pScriptContext->f_0c = CURSCRIPT_GETBYTE;
C_00439946(D_00BFCDE0, bp08, lolo.pScriptContext->f_0a, lolo.pScriptContext->f_0c);//MAGIC/MGUN
break;
case 0xad:
lolo.pScriptContext->f_10 = CURSCRIPT_GETBYTE;
lolo.pScriptContext->f_0e = CURSCRIPT_GETWORD;
lolo.pScriptContext->f_0a = CURSCRIPT_GETBYTE;
lolo.pScriptContext->f_0c = CURSCRIPT_GETBYTE;
C_0043930D(D_00BFCDE0, bp08, D_00BE1178[bp08].f_002b[lolo.pScriptContext->f_10], lolo.pScriptContext->f_0e, lolo.pScriptContext->f_0a, lolo.pScriptContext->f_0c);//MAGIC/MGUN
break;
case 0xdb:
lolo.pScriptContext->f_0e = CURSCRIPT_GETWORD;
lolo.pScriptContext->f_0a = CURSCRIPT_GETBYTE;
lolo.pScriptContext->f_0c = CURSCRIPT_GETBYTE;
C_0043930D(D_00BFCDE0, bp08, -1, lolo.pScriptContext->f_0e, lolo.pScriptContext->f_0a, lolo.pScriptContext->f_0c);//MAGIC/MGUN
break;
case 0xf0:
C_005BE490(bp08);//make smoke trail?
break;
case 0xb5:
lolo.pScriptContext->f_16.f_00 = CURSCRIPT_GETWORD;
lolo.pScriptContext->f_16.f_02 = CURSCRIPT_GETWORD;
lolo.pScriptContext->f_16.f_04 = CURSCRIPT_GETWORD;
lolo.pScriptContext->f_0a = CURSCRIPT_GETBYTE;
lolo.pScriptContext->f_0c = CURSCRIPT_GETWORD;
lolo.pScriptContext->f_0e = CURSCRIPT_GETWORD;
C_005BE844(bp08, &(lolo.pScriptContext->f_16), lolo.pScriptContext->f_0a, lolo.pScriptContext->f_0c, lolo.pScriptContext->f_0e);
break;
case 0xa4:
lolo.i = C_005BED92(C_00425520);
D_00BFC3A0[lolo.i].f_02 = 2;
D_00BFC3A0[lolo.i].f_04 = 0x1f0;
break;
case 0xa5:
lolo.i = C_005BED92(C_00425520);
D_00BFC3A0[lolo.i].f_02 = 3;
D_00BFC3A0[lolo.i].f_04 = 0x1e9;
break;
case 0xe6:
lolo.i = C_005BED92(C_00425520);
D_00BFC3A0[lolo.i].f_02 = 0;
D_00BFC3A0[lolo.i].f_04 = 0xd;
break;
case 0xe0:
lolo.i = C_005BED92(C_00425520);
D_00BFC3A0[lolo.i].f_02 = 1;
D_00BFC3A0[lolo.i].f_04 = 0x24;
break;
case 0x90:
lolo.pScriptContext->f_15 = CURSCRIPT_GETBYTE;
switch(bp08) {
case 6:
*D_00C05FE8 = 0;
*D_00C05FEC = lolo.pScriptContext->f_15;
break;
case 7:
*D_00C05FE8 = 0;
*D_00C05FEC = lolo.pScriptContext->f_15 + 8;
break;
case 8:
*D_00C05FE8 = 1;
*D_00C05FEC = lolo.pScriptContext->f_15;
break;
case 9:
*D_00C05FE8 = 1;
*D_00C05FEC = lolo.pScriptContext->f_15 + 8;
break;
}//end switch
lolo.bp_2c = C_00666BBE(C_00676578());//get field_934[gfx_driver]?
lolo.bp_34 = 4;
lolo.bp_28 = CURSCRIPT_GETWORD;
lolo.bp_24 = &lolo.bp_30;
lolo.bp_24->c.b = (lolo.bp_28 & 0x001f) << 3;
lolo.bp_24->c.g = (lolo.bp_28 & 0x03e0) >> 2;
lolo.bp_24->c.r = (lolo.bp_28 & 0x7c00) >> 7;
lolo.bp_24->c.a = 0xff;
lolo.bp_18 = *D_00C05FEC;
lolo.bp_20 = 0;

D_009ADEE8 = 0;
D_009ADEE0[0] = 0;
D_009ADEE0[1] = 0;
D_009ADEF0[0] = 0;
D_009ADEF0[1] = 0;
C_00685028(lolo.bp_20, C_0041FB1C, D_00BE1178[lolo.bp_34].f_0ba8->f_04);//anm:apply function to skeleton?
if(bp08 < 8)
lolo.bp_38 = D_009ADEE0[0];
else
lolo.bp_38 = D_009ADEE0[1];
if(lolo.bp_38) {
C_0068924B(0, 1, lolo.bp_24, lolo.bp_18, lolo.bp_38);//dx_graph:SetPaletteData
lolo.bp_2c->f_54(lolo.bp_18, 1, lolo.bp_18, lolo.bp_38->f_8c, lolo.bp_38);
}
break;
case 0x9b:
D_00BF2370 = 1;
break;
case 0x9f:
D_00BF2370 = 0;
break;
case 0xc6:
D_00BFD0F0 = CURSCRIPT_GETBYTE;
break;
case 0xe2:
D_00BE1178[bp08].f_003e = D_00BE1178[bp08].f_003e | 2;
break;
case 0xe1:
D_00BE1178[bp08].f_003e = D_00BE1178[bp08].f_003e | 4;
break;
case 0xe8:
C_004281B1(bp08);//launch magic attack?
break;
case 0xac:
D_00BE1178[bp08].f_003e = D_00BE1178[bp08].f_003e | 0x20;
D_00BF23C0[bp08].f_00 = D_009A8748.f_0ac[bp08].f_08;
D_00BE1178[bp08].f_0140.f_1e.f_02 = D_00BE1178[bp08].f_0018;
lolo.pScriptContext->f_0a = CURSCRIPT_GETBYTE;
if(lolo.pScriptContext->f_0a == 0xa) {//else 00424012
lolo.bp_0c = C_006CB98E(bp08);//get character's info object?
if(lolo.bp_0c) {//else 00423FFD
lolo.pScriptContext->f_0c = lolo.bp_0c->f_408.f_09 & 0xf0;
switch(lolo.pScriptContext->f_0c) {
case 0x00: lolo.pScriptContext->f_0e = 4; break;
case 0x10: lolo.pScriptContext->f_0e = 5; break;
case 0x20: lolo.pScriptContext->f_0e = 6; break;
default:
lolo.pScriptContext->f_0e = 4;
}//end switch
} else {
lolo.pScriptContext->f_0e = 4;
}
lolo.bp_1c = lolo.pScriptContext->f_0e;
} else {
lolo.bp_1c = lolo.pScriptContext->f_0a;
}
D_009ADED8 = lolo.bp_1c;
break;
case 0xa2:
lolo.pScriptContext->f_0e = CURSCRIPT_GETBYTE;
if(D_009ADED8 >= 4)
C_0042A330(0, 0, bp08, D_007C1098[D_009ADED8]);
else
C_0042A330(0, 1, bp08, D_007C1098[D_009ADED8]);
if(D_00BFB2B8[bp08])
D_00BE1178[bp08].f_0ba8 = D_00BFB2B8[bp08];
D_00BE1178[bp08].f_000e = 0;
D_00BE1178[bp08].f_0b9c = 0;
D_00BE1178[bp08].f_0ba0 = 0;
D_00BE1178[bp08].f_0ba4 = 0;
D_00BE1178[bp08].f_1ac4 = 0;
C_0042C21B(bp08);
C_0042C1B4(bp08);
//-- update scripts pointers --
lolo.bp_08 = D_00BFB2B8[bp08]->f_00;
for(lolo.i = 0; lolo.i < 0x4a; lolo.i ++)
lolo.bp_08->f_68[lolo.i] += (int)(D_00BFB2B8[bp08]->f_00);
//-- --
C_0042B66A(bp08);
D_00BE1178[bp08].wCurScriptId = lolo.pScriptContext->f_0e;
D_009A8748.f_0ac[bp08].f_01 = D_00BE1178[bp08].wCurScriptId;
D_00BF2DF8[bp08] = D_009A8748.f_0ac[bp08].f_01;
D_00BE1178[bp08].f_003e = D_00BE1178[bp08].f_003e | 1;
D_00BE1178[bp08].f_003e = D_00BE1178[bp08].f_003e | 4;
D_00BE1178[bp08].f_0025 = D_00BE1178[bp08].f_0025 & ~2;
C_00430D32(0x2d9, bp08, 0);
return;
//break;
case 0xd6:
lolo.pScriptContext->f_0a = CURSCRIPT_GETBYTE;
lolo.pScriptContext->f_0c = C_005BED92(C_004277B1);
D_00BFC3A0[lolo.pScriptContext->f_0c].f_06 = bp08;
D_00BFC3A0[lolo.pScriptContext->f_0c].f_04 = lolo.pScriptContext->f_0a;
break;
case 0xec:
if(D_00BF2A30 == 0) {
C_00427C22(bp08);
D_009ADF04 = 0;
} else {
D_00BE1178[bp08].f_003c --;
lolo.pScriptContext->bScriptActive = 0;
D_009ADF04 = 1;
}
break;
case 0x97:
*D_00C05FE8 = CURSCRIPT_GETBYTE;
*D_00C05FEC = CURSCRIPT_GETBYTE;
C_0042567E(bp08, *D_00C05FE8, *D_00C05FEC);
break;
case 0x98:
*D_00C05FE8 = CURSCRIPT_GETBYTE;
lolo.pScriptContext->f_14 = C_005BEC50(C_0042782A);
D_00BFB718[lolo.pScriptContext->f_14].f_04 = C_005BE475();//battle message speed?
D_00BFB718[lolo.pScriptContext->f_14].f_06 = *D_00C05FE8;
break;
case 0xea:
lolo.pScriptContext->f_14 = C_005BEC50(C_0042782A);
D_00BFB718[lolo.pScriptContext->f_14].f_04 = C_005BE475();//battle message speed?
D_00BFB718[lolo.pScriptContext->f_14].f_06 = 0;
break;
case 0xeb:
if(D_00BF2A30 == 0) {
C_00427B4B(bp08);
} else {
D_00BE1178[bp08].f_003c --;
lolo.pScriptContext->bScriptActive = 0;
}
break;
case 0xb2:
case 0xc9:
break;
case 0xaa:
D_00BF2A2C = 0;
break;
case 0xa7:
D_00BE1178[bp08].f_000e = CURSCRIPT_GETBYTE;
D_00BE1178[bp08].f_0074 = 0;
D_00BE0E28[bp08].f_00 = 0;
if(D_00BF23C0[bp08].f_36) {
for(lolo.i = 0; lolo.i < D_00BF23C0[bp08].f_36; lolo.i ++)
C_00424B4B(bp08, bp10, bp14);
}
lolo.pScriptContext->bScriptActive = 0;
break;
case 0xb6:
C_005BED92(C_0042517B);
D_00BE1178[bp08].f_000e = CURSCRIPT_GETBYTE;
D_00BE1178[bp08].f_0074 = 0;
D_00BE0E28[bp08].f_00 = 0;
if(D_00BF23C0[bp08].f_36) {
for(lolo.i = 0; lolo.i < D_00BF23C0[bp08].f_36; lolo.i ++)
C_00424B4B(bp08, bp10, bp14);
}
lolo.pScriptContext->bScriptActive = 0;
break;
default:
D_00BE1178[bp08].f_000e = lolo.pScriptContext->bOpcode;
D_00BE1178[bp08].f_0074 = 0;
D_00BF23C0[bp08].f_36 = 0;
D_00BE0E28[bp08].f_00 = 0;
lolo.pScriptContext->bScriptActive = 0;
}//end switch(lolo.pScriptContext->f_01)
}//end while(lolo.pScriptContext->bScriptActive)
}
//00424745
if(D_00BF23C0[bp08].f_0c & 2)
return;
D_00BF23C0[bp08].f_36 ++;
if(D_00BE1178[bp08].wCurScriptId != D_00BF2DF8[bp08]) {
C_00424B4B(bp08, bp10, bp14);
return;
}
switch(D_00BF23C0[bp08].f_33) {
default:
C_00424B4B(bp08, bp10, bp14);
break;
case 1:
C_00424B4B(bp08, bp10, bp14);
C_00424B4B(bp08, bp10, bp14);
break;
case 2:
if(D_00BFD0E4 & 1)
C_00424B4B(bp08, bp10, bp14);
break;
case 3:
D_00BE1178[bp08].f_0074 = 0;
D_00BE0E28[bp08].f_00 = 0;
D_009ADEF8 = 1;
C_00424B4B(bp08, bp10, bp14);
break;
}//end switch
}

I know, it's pretty ugly. Concerning CURSCRIPT_GETBYTE, it's a macro I made to make the code more "readable". For info:
Code: [Select]
#define CURSCRIPT_GETBYTE lolo.pScriptContext->pScriptData[D_00BE1178[bp08].f_003c ++]
#define CURSCRIPT_GETWORD C_00424F5F(bp08, lolo.pScriptContext->pScriptData)

Also, here is what I call the script context structure:
Code: [Select]
struct t_battle_ScriptContext {//size 0x1e?
/*00*/char bScriptActive;
/*01*/unsigned char bOpcode;
/*02*/char __02[2];//pad
/*04*/unsigned char *pScriptData;
/*08*/short f_08;
/*0a*/short f_0a;
//-- --
/*0c*/short f_0c;
/*0e*/short f_0e;
/*10*/short f_10;
/*12*/short f_12;
/*14*/char f_14;
/*15*/char f_15;
/*16*/struct SVECTOR f_16;
//-- --
/*1e*/
};

Enjoy :D

8
here is the detail of the function at 0x00432687:
Code: [Select]
//add battle command?
void C_00432687(int bp08, int bp0c, int bp10, int bp14, int bp18) {
struct t_battle_local_08_HHHH local_2;

local_2.f_00 = bp0c;
local_2.f_02 = bp08;
local_2.f_03 = bp10;
local_2.f_04 = bp14;
local_2.f_06 = bp18;
C_0043258A(&local_2);//queue battle command?
}

the details about "struct t_battle_local_08_HHHH" (sorry about the name) is already given in the wiki, at "Queued Actions"(although there seems to be a confusion with offsets 0,1 and 2). According to it, the last two parameters are respectively "target mask" and "action index". Not sure that helps though  :-\

9
ok, so there is this function at 0x0043526A:
Code: [Select]
//counters:refresh(1)?
void C_0043526A() {
struct {
int dwDecr;//bp_40
int dwCurCounter;//bp_3c
int dwNewHP;//bp_38
int dwHPMax;//bp_34
int bp_30;
int dwHPIncr;//bp_2c
int dwCountIncr_1;//bp_28
int dwDecr_2_3;//bp_24
int dwCountIncr_0;//bp_20
int dwDecr_def;//bp_1c
int j;//bp_18
int i;//bp_14//local_5
int bp_10;//local_4
int *bp_0c;//local_3
int *bp_08;//local_2
int dwDecr_0;//bp_04//local_1
}lolo;

//-- --
lolo.bp_10 = D_009AE8A0;
D_009AE8A0 ^= 1;
lolo.bp_0c = D_009AE928[lolo.bp_10];
lolo.bp_08 = D_009AE978[lolo.bp_10];
//-- --
lolo.dwDecr_0 = D_009AE8D0[lolo.bp_10] >> 13;
D_009AE8D0[lolo.bp_10] &= 0x1fff;
//-- --
for(lolo.i = 0; lolo.i < 0xa; lolo.i ++) {
lolo.bp_30 = D_009A8B10.f_0000[lolo.i].f_06;
lolo.dwCountIncr_1 = lolo.bp_0c[lolo.i];
lolo.dwCountIncr_0 = lolo.bp_08[lolo.i];
//-- some counter --
D_009AE900[lolo.i] += lolo.dwCountIncr_1;
lolo.dwDecr_def = D_009AE900[lolo.i] >> 13;
D_009AE900[lolo.i] &= 0x1fff;
//-- some counter --
D_009AE8D8[lolo.i] += lolo.dwCountIncr_0;
lolo.dwDecr_2_3 = D_009AE8D8[lolo.i] >> 12;
D_009AE8D8[lolo.i] &= 0xfff;
//-- counter for HP recovery? --
D_009AE8A8[lolo.i] += lolo.dwCountIncr_1 * lolo.bp_30;
lolo.dwHPIncr = D_009AE8A8[lolo.i] >> 15;
D_009AE8A8[lolo.i] &= 0x7fff;
//-- --
lolo.bp_0c[lolo.i] = 0;
lolo.bp_08[lolo.i] = 0;
//-- --
if((D_009AB0A0.f_03c[lolo.i].f_00 & 1) == 0) {//else 00435485
lolo.dwNewHP = D_009AB0A0.f_03c[lolo.i].dwHP + lolo.dwHPIncr;
lolo.dwHPMax = D_009AB0A0.f_03c[lolo.i].dwHPMax;
if(lolo.dwNewHP < 0) {//else 00435468
D_009AB0A0.f_03c[lolo.i].f_00 |= 1;
C_005C89E2(lolo.i, lolo.i, 1);
C_005C8931();//execute "other" scripts
lolo.dwNewHP = 0;
//goto 00435476
} else if(lolo.dwNewHP > lolo.dwHPMax) {
lolo.dwNewHP = lolo.dwHPMax;
}
D_009AB0A0.f_03c[lolo.i].dwHP = lolo.dwNewHP;
}
//-- some other states(poison, ...) --
for(lolo.j = 0; lolo.j < 0x10; lolo.j ++) {
lolo.dwCurCounter = D_009A8B10.f_0000[lolo.i].f_10[lolo.j];
if(lolo.dwCurCounter) {//else 00435531
switch(lolo.j) {
case 0:
lolo.dwDecr = lolo.dwDecr_0;
break;
case 2:
case 3:
lolo.dwDecr = lolo.dwDecr_2_3;
break;
default:
lolo.dwDecr = lolo.dwDecr_def;
}//end switch
lolo.dwCurCounter -= lolo.dwDecr;
if(lolo.dwCurCounter < 0)
lolo.dwCurCounter = 0;
if(lolo.dwCurCounter == 0)
C_00435139(2, lolo.i, lolo.j, lolo.j);//...:add event?
D_009A8B10.f_0000[lolo.i].f_10[lolo.j] = lolo.dwCurCounter;
}
}//end for
//-- --
}//end for
}

From what I understand, it refreshes some counters and take their upper bits to refresh some more counters. But near the end of the function, we have "dwCurCounter", and if it reaches 0, a function at 0x00435139 is called with such parameters as: the actor id, and the event type, respectively "i" and "j" in our case (a value of 6 means poison). Function at 0x00435139 manages a list of events which are called by the function at 0x004351BD:
Code: [Select]
//...:add event?
void C_00435139(int bp08, int bp0c, int bp10, int bp14) {
int local_2;
struct t_battle_inner_4 *local_1;

local_2 = D_009AE890[bp08];
local_1 = &(D_009AE280[bp08][local_2]);
if(local_1->f_00 == (unsigned char)0xff) {
local_1->f_02 = bp14;
local_1->f_01 = bp10;
local_1->f_00 = bp0c;
D_009AE890[bp08] = C_004351A3(local_2);//make next id?
}
}

//make next id?
int C_004351A3(int bp08) {
bp08 ++;
bp08 &= 0x7f;

return bp08;
}

//...:flush events?
void C_004351BD(int bp08) {
struct {
void (**local_3)(int, int);
int local_2;
struct t_battle_inner_4 *local_1;
}lolo;

C_004351C3:
lolo.local_2 = D_009AE880[bp08];
lolo.local_1 = &(D_009AE280[bp08][lolo.local_2]);
if(lolo.local_1->f_00 != (unsigned char)0xff) {
lolo.local_3 = D_007C2AC0[bp08];
lolo.local_3[lolo.local_1->f_01](lolo.local_1->f_00, lolo.local_1->f_02);
lolo.local_1->f_00 = 0xff;
D_009AE880[bp08] = C_004351A3(lolo.local_2);//make next id?
goto C_004351C3;
}
}

In the case of poison, the callback is at 0x00434DB0:
Code: [Select]
//(callback)2_06 "poison hit"
void C_00434DB0(int bp08, int _p0c) {
if(D_009AB0A0.f_03c[bp08].f_00 & 8) {
D_009A8B10.f_0000[bp08].f_10[6] = 0xa;
C_00432687(bp08, 3, 0x23, 0, 0);//add battle command?
}
}

What does it do ?
It reloads a poison-specific counter D_009A8B10.f_0000[bp08].f_10[6], and creates an attack command that will take HP from the character actually poisonned.

A little complex I would say  :-/

10
That is in fact a contiguous array of structs of size 68h right?

I think you're refering to an array of structs starting at 0x009AB0DC;
here is how I reverse-engineered it:
Code: [Select]
struct t_battle_local_68 {//size 0x68
int f_00;//[0x4000]//009AB0DC
int f_04;//[0x4020]//009AB0E0
char f_08;//[0x4040]//009AB0E4
unsigned char f_09;//[0x4048]//009AB0E5
char __0a[1];//009AB0E6
unsigned char f_0b;//[0x4058]//009AB0E7
unsigned char f_0c;//[0x4060]//009AB0E8
unsigned char f_0d;//[0x4068]//009AB0E9
unsigned char f_0e;//[0x4070]//009AB0EA
unsigned char f_0f;//[0x4078]//009AB0EB
char f_10;//[0x4080]//009AB0EC
unsigned char f_11;//[0x4088]//009AB0ED
unsigned char f_12;//[0x4090]//009AB0EE
unsigned char f_13;//[0x4098]//009AB0EF
unsigned char f_14;//[0x40a0]//009AB0F0
unsigned char f_15;//[0x40a8]//009AB0F1
unsigned char f_16;//[0x40b0]//009AB0F2
unsigned char f_17;//[0x40b8]//009AB0F3
unsigned short f_18;//[0x40c0]//009AB0F4
unsigned short f_1a;//[0x40d0]//009AB0F6
unsigned short f_1c;//[0x40e0]//009AB0F8
unsigned short f_1e;//[0x40f0]//009AB0FA
unsigned short f_20;//[0x4100]//009AB0FC
unsigned short f_22;//[0x4110]//009AB0FE
unsigned short f_24;//[0x4120]//009AB100
unsigned short f_26;//[0x4130]//009AB102
unsigned short f_28,f_2a;//MP//[0x4140][0x4150]//009AB104,009AB106
unsigned f_2c,f_30;//HP//[0x4160][0x4180]009AB108,009AB10C
char __34[0x10];//009AB110
int f_44;//[0x4220]//009AB120
char __48[4];//009AB124
unsigned char f_4c;//[0x4260]//009AB128
unsigned char f_4d;//[0x4268]//009AB129
unsigned char f_4e;//[0x4270]//009AB12A
unsigned char f_4f;//[0x4278]//009AB12B
unsigned short f_50;//[0x4280]//009AB12C
unsigned short f_52;//[0x4290]//009AB12E
unsigned short f_54;//[0x42a0]//009AB130
unsigned char f_56;//[0x42b0]//009AB132
char __57[1];//009AB133
int f_58;//[0x42c0]//009AB134
int f_5c;//[0x42e0]//009AB138
char __60[8];//009AB13C
};

The array is part of another structure: it starts at offset 0x3c of an object starting at 0x009AB0A0.
As you can see, there are a lot of field that I didn't make sense of yet.
But you can see HP at f_28/f_2a and MP at f_2c,f_30 for instance.

As for the function at 0x005DC880 here what it looks like transposed back to C:
Code: [Select]
const unsigned short D_007B7748[] = {
/*007B7748*/0x04,0x3C,0x04,0x20,
/*007B7750*/0x01,0x24,0x10,0x10,
/*007B7758*/0x04,0x02,0x02,0x02,
/*007B7760*/0x02,0x01,0x20,0x04,
/*007B7768*/0x24,0x10,0x10,0x04,
/*007B7770*/0x20,0x10,0x10,0x10,
/*007B7778*/0x30,0x10,0x20,0x10,
/*007B7780*/0x10,0x14,0x01,0x01,
/*007B7788*/0x01,0x01,0x01,0x18
};

int C_005DC880(int bp08) {
struct {
int bp_5c;
int bp_58;
int bp_54;
int bp_50;
int bp_4c;
int bp_48;
int bp_44;
int bp_40;
int bp_3c;
int bp_38;
int bp_34;
int bp_30;
int bp_2c;
int bp_28;
int bp_24;
int bp_20;
unsigned short bp_1c; char _p_1c[2];
int bp_18;
int bp_14;
struct t_temp_034 *bp_10;
int bp_0c;
int bp_08;
int bp_04;
}lolo;

lolo.bp_04 = 0;
if(D_0099CE0C->f_0bc == -1)
return lolo.bp_04;
if(D_007B7748[D_0099CE0C->f_0bc] & BIT(bp08)) {//else 005DD653
lolo.bp_14 = D_0099CE0C->f_000;
lolo.bp_10 = &(D_009A8B10.f_02a8[lolo.bp_14]);
switch(D_0099CE0C->f_0bc) {
case 0:
D_0099CE0C->f_0b0 = D_0099CE0C->f_0c0;
break;
case 1:
switch(bp08) {
case 2:
D_0099CE0C->f_090 |= 0x40000;
break;
case 3:
if(D_0099CE0C->f_230 & 0x80)
D_0099CE0C->f_218 |= 1;
break;
case 4:
if(D_0099CE0C->f_208 >= 4)
D_009A8B10.f_2228 |= BIT(D_0099CE0C->f_208);
break;
case 5:
if(D_0099CE0C->f_0e0 == 0) {
D_0099CE0C->f_0b4 ++;
D_0099CE0C->f_098 = 0x61;
C_00436C4B();//restore indexes D_009AEA9C & D_009AEAA0
C_005CAC07(D_0099CE0C->f_098);
}
break;
}//end switch
break;
case 2:
if(C_005C8BA1() < D_0099CE0C->f_0c0) {//Battle.random:get unsigned char?
D_0099CE0C->f_02c = 0x60;
D_0099CE0C->f_098 = D_0099CE0C->f_02c;
C_005CA807();//calls "CMD script_0C"
}
break;
case 3:
C_005DF95A();
break;
case 4:
lolo.bp_18 = (D_009AB0A0.f_03c[D_0099CE0C->f_208].f_04 & 0x80)?1:0;
lolo.bp_18 ^= D_0099CE0C->f_0c0;
D_0099CE0C->f_234 &= ~1;
D_0099CE0C->f_220 &= ~2;
if(lolo.bp_18 == 0)
D_0099CE0C->f_234 |= 1;
break;
case 5:
switch(bp08) {
case 2:
if((D_009A8748.f_008.f_10 & 4) == 0)
D_0099CE0C->f_0dc = 0x36;
break;
case 5:
D_009AB0A0.f_022 |= 8;
break;
}//end switch
break;
case 6:
if(D_0099CE0C->f_208 < 3) {//else 005DCC01
lolo.bp_1c = D_0099CE0C->f_004 * 0x14;
if(lolo.bp_1c > D_00DBFD38.dwGIL)
lolo.bp_1c = D_00DBFD38.dwGIL;
if(lolo.bp_1c && lolo.bp_1c + D_009AB0A0.f_03c[lolo.bp_14].f_50 < 0xffff) {//else 005DCC01
D_009AB0A0.f_03c[lolo.bp_14].f_50 += lolo.bp_1c;
D_00DBFD38.dwGIL -= lolo.bp_1c;
C_005C7D59(lolo.bp_14, 0x55, 1, &lolo.bp_1c);
}
}
if(D_0099CE0C->f_048 == 0) {
D_0099CE0C->f_218 |= 2;
D_0099CE0C->f_224 = D_009AB0A0.f_03c[D_0099CE0C->f_208].f_11;
}
break;
case 7:
if(D_009AB0A0.f_03c[lolo.bp_14].f_52 == (unsigned short)0xffff && D_0099CE0C->f_208 < 3)
C_00435139(0, lolo.bp_14, 0xb, 0);
if(D_0099CE0C->f_048 == 0) {
D_0099CE0C->f_218 |= 2;
D_0099CE0C->f_224 = D_009AB0A0.f_03c[D_0099CE0C->f_208].f_11;
}
break;
case 8:
D_0099CE0C->f_048 = C_005C8BDC(7);//Battle.random:get unsigned char(with max)?
D_0099CE0C->f_024 += D_0099CE0C->f_048;
D_0099CE0C->f_048 += 4;
D_0099CE0C->f_048 *= 8;
break;
case 9:
if(D_0099CE0C->f_004 == D_0099CE0C->f_254)
D_0099CE0C->f_214 *= 8;
break;
case 0xa:
C_005DFB5C();
break;
case 0xb:
C_005DFBEE();
break;
case 0xc:
C_005DFD5B();
break;
case 0xd:
if(1) {
lolo.bp_20 = 0;
lolo.bp_24 = 0;
for(lolo.bp_28 = 4; lolo.bp_28 < 0xa; lolo.bp_28 ++) {
if(D_0099CE0C->f_018 & BIT(lolo.bp_28)) {
lolo.bp_20 += D_009AB0A0.f_03c[lolo.bp_28].f_09;
lolo.bp_24 ++;
}
}
if(lolo.bp_24)
lolo.bp_20 /= lolo.bp_24;
D_0099CE0C->f_048 = lolo.bp_20;
}
break;
case 0xe:
for(lolo.bp_08 = 0; lolo.bp_08 < 3; lolo.bp_08 ++) {
if(D_009AB0A0.f_03c[lolo.bp_08].f_00 & 1) {
D_009AB0A0.f_03c[lolo.bp_08].f_00 &= ~1;
D_009AB0A0.f_03c[lolo.bp_08].f_2c = D_009AB0A0.f_03c[lolo.bp_08].f_30;
}
}
break;
case 0xf:
C_005DF460();
break;
case 0x10:
switch(bp08) {
case 2:
if(1) {
lolo.bp_2c = 0;
for(lolo.bp_08 = 0; lolo.bp_08 < 3; lolo.bp_08 ++) {
if(D_009AB0A0.f_03c[lolo.bp_08].f_08 != -1)
lolo.bp_2c ++;
}
if(lolo.bp_2c < 2)
D_0099CE0C->f_0dc = 0x50;
}
break;
case 5:
C_005DF5D7();
break;
}//end switch
break;
case 0x11:
if(D_0099CE0C->f_208 < 3) {
lolo.bp_30 = BIT(D_0099CE0C->f_208);
C_00435139(2, D_0099CE0C->f_208, 0x13, lolo.bp_30);
}
D_0099CE0C->f_224 = C_005CABBA();
break;
case 0x12:
if(1) {
lolo.bp_34 = BIT(D_0099CE0C->f_208);
if(D_0099CE0C->f_208 < 3)
C_00435139(2, D_0099CE0C->f_208, 0x13, lolo.bp_34);
D_009A8B10.f_2214 |= lolo.bp_34;
D_0099CE0C->f_224 = C_005CABBA();
}
break;
case 0x13:
if(1) {
D_0099CE0C->f_018 = 0;
D_0099CE0C->f_0b4 = 0;
lolo.bp_40 = D_009A8748.f_0ac[lolo.bp_14].f_00;
lolo.bp_38 = D_009A8B10.f_02a8[lolo.bp_14].f_00->f_22;
lolo.bp_3c = C_005C8684(lolo.bp_40, 0);
for(lolo.bp_08 = 0; lolo.bp_08 < 7; lolo.bp_08 ++) {
lolo.bp_44 = D_009A8748.f_16c[lolo.bp_08];
lolo.bp_48 = 0x7f;
for(lolo.bp_0c = 0; lolo.bp_0c < 0xc; lolo.bp_0c ++) {
if(lolo.bp_38 & BIT(lolo.bp_0c)) {
lolo.bp_48 = C_005C8684(lolo.bp_40, lolo.bp_0c);
lolo.bp_38 &= ~BIT(lolo.bp_0c);
break;
}
}
if(lolo.bp_44 && lolo.bp_48 - lolo.bp_3c < 7) {//else 005DD0FB
lolo.bp_48 -= lolo.bp_3c;
lolo.bp_48 += 0x62;
if(lolo.bp_44 > 1)
lolo.bp_48 |= 0x80;
C_005CAC07(lolo.bp_48);
D_0099CE0C->f_0b4 ++;
}
}
D_0099CE0C->f_090 |= 0x10000;
}
break;
case 0x14:
for(lolo.bp_08 = 0; lolo.bp_08 < 3; lolo.bp_08 ++) {
if(lolo.bp_14 != lolo.bp_08)
D_009A8B10.f_02a8[lolo.bp_08].f_08 = 0xff;
}//end for
break;
case 0x15:
C_005C7EE5(D_0099CE0C->f_208, D_0099CE0C->f_0c0 - 0x64, 0xf);
break;
case 0x16:
C_005C7EE5(lolo.bp_14, D_0099CE0C->f_0c0 - 0x64, 0x10);
break;
case 0x17:
C_005C7EE5(lolo.bp_14, D_0099CE0C->f_0c0 - 0x64, 1);
break;
case 0x18:
switch(bp08) {
case 4:
if(D_0099CE0C->f_208 >= 4)
D_009A8B10.f_2228 |= BIT(D_0099CE0C->f_208);
break;
case 5:
D_0099CE0C->f_0b4 ++;
D_0099CE0C->f_098 = D_0099CE0C->f_0c0;
D_0099CE0C->f_0ec = D_0099CE0C->f_018;
C_005CAC07(D_0099CE0C->f_098);
D_0099CE0C->f_090 |= 0x81000;
break;
}//end switch
break;
case 0x19:
if(C_005C7F60() && D_0099CE0C->f_208 < 3) {
D_0099CE0C->f_224 = (D_009AB0A0.f_03c[D_0099CE0C->f_208].f_04 & 0x40)?0x32:0x31;
D_009AB0A0.f_03c[D_0099CE0C->f_208].f_04 ^= 0x40;
}
break;
case 0x1a:
if(1) {
lolo.bp_4c = D_0099CE0C->f_018;
lolo.bp_50 = (lolo.bp_4c & 0xf)?0xf:0x3f0;
lolo.bp_54 = D_009A8748.f_14c & ~D_009A8748.f_15a;
lolo.bp_54 &= lolo.bp_50;
lolo.bp_54 &= ~lolo.bp_4c;
D_0099CE0C->f_0ec = lolo.bp_54;
D_0099CE0C->f_0b4 ++;
D_0099CE0C->f_098 = D_0099CE0C->f_0c0;
C_005CAC07(D_0099CE0C->f_098);
D_0099CE0C->f_090 |= 0x281000;
}
break;
case 0x1b:
if(D_0099CE0C->f_208 >= 4) {
lolo.bp_58 = BIT(D_0099CE0C->f_208);
D_009A8B10.f_2214 |= lolo.bp_58;
}
break;
case 0x1c:
C_005C7EE5(D_0099CE0C->f_208, D_0099CE0C->f_0c0 - 0x64, 0xc);
break;
case 0x1d:
switch(bp08) {
case 2:
D_0099CE0C->f_090 |= 0x1000000;
break;
case 4:
D_0099CE0C->f_224 = 0x33;
break;
}//end switch
break;
case 0x1e:
D_0099CE0C->f_048 = (D_0099CE0C->f_0c4 * 3 * D_009A8B10.f_0000[lolo.bp_14].f_3c) / D_009AB0A0.f_03c[lolo.bp_14].f_30 + 1;
break;
case 0x1f:
D_0099CE0C->f_048 = (D_0099CE0C->f_0c4 * 3 * D_009A8B10.f_0000[lolo.bp_14].f_3e) / D_009AB0A0.f_03c[lolo.bp_14].f_2a + 1;
break;
case 0x20:
C_005DFC52();
break;
case 0x21:
D_0099CE0C->f_048 = (lolo.bp_10->f_00->f_24 / 0x80) * D_0099CE0C->f_0c4 / 0x10 + 0xa;
break;
case 0x22:
D_0099CE0C->f_048 = ((lolo.bp_10->f_0a * (lolo.bp_10->f_05 + 1)) >> 4) * D_0099CE0C->f_0c4 / 0x10 + 1;
break;
case 0x23:
switch(bp08) {
case 3:
if(D_0099CE0C->f_230 & 0x80)
D_0099CE0C->f_218 |= 1;
break;
case 4:
if(D_0099CE0C->f_208 >= 4) {
lolo.bp_5c = BIT(D_0099CE0C->f_208);
D_009A8B10.f_2228 |= lolo.bp_5c;
D_009A8B10.f_0000[D_0099CE0C->f_208].f_29 |= 1;
D_009AB0A0.f_03c[D_0099CE0C->f_208].f_58 = 0;
}
break;
}//end switch
break;
}//end switch
}

return lolo.bp_04;
}

well... it needs a lot of work before making sense of it   :-p

11
I uploaded two parts from my decompilation work:
- the coaster minigame: https://github.com/ergonomy-joe/ff7-coaster
- the world map engine: https://github.com/ergonomy-joe/ff7-worldmap

The code once compiled with visual studio 97 is almost the same as the original code.
But this time I made some arrangement:
.this project build with Visual Studio 2008 (although it may be easy to build it with more recent versions)
.part of the original code is included as LIB files: the main library FF7LIB, the sound library FF7SND and the menu library FF7MENU (I may release as source code later but for now you have to use the libraries).
.I patched a little the original code so that it runs in a window (with a glitch though)
.both projects work as standalone. I included an original .cpp file in both case to launch both engines. Respectively CoasterMain.cpp and FF7WorldMap.cpp.
.you need to build/link with DirectX SDK version 5.0. I didn't try with newer versions. It may work too, I don't know.

Enjoy !

12
The conversation concerning the reversed source code has moved to private for now.
But to answer the questions:
.I would like to post my work somewhere
.I am aware of the legal issues

In the meantime I will try to update my blog with bits of code.
Especially, some of you maybe aware of the fact that the ORIGINAL EXE includes 3 different graphic drivers (Direct3D hardware accelerated, software, [broken]OpenGL) plus the option to load the driver as an external DLL. The sofware part is really interesting: it is a complete STATE OF THE ART (for 1997) sofware rendering library. I find it hard to beleive that EIDOS developped it only for the FF7 port, but I couldn't find traces of it in other games of that era. Anyway, this part of the code is really fun (mostly inlined ASM) and I'd like to make some post about it.

BTY, I might not be able to post anything during weekdays so don't blame me for not answering please

13
If you mean things like extracted/converted models, etc., we don't allow that to be posted here either.

I understand. That will be hard to discuss reverse-engineering if I can't post some source code though. Maybe one function at a time is acceptable ?

So you can compile your source and get a binary that runs the game - except for battles? Seems quite extreme to go to the level of completely binary compatibility!

It builds fine, and it runs (I have to change two or three things in the source to make it run on Win 8 though). Funny when you think I'm using a build environment from 1997. As for the extremity, that's because it's the only way to be sure my code has the closest shape to the original source code.
It took a couple of years so far.

I need the submarine game, I'd find that very very interesting. See, from what i could tell, there is a TON of unused/dupe data in there.  And very strange goings on.  I think originally they were planning yo have 5 distinct difficulties with different time limits... but ran out of time.

This one is interesting: all the game's data (except the textures) is embedded in the source code.
What kind of "strange goings" are you referring to ?

14
I'll try to clarify a little how I do:
.I translate from disassembled code to C code by hand, function after function (they are easy to spot in the ASM code)
.I then use --what I believe is-- the compiler originaly used, Visual C++ 5.0, to create an object file
.I then use an original tool to compare this object file to FF7.EXE to spot any translation error

Here is sample, the UPDATE callback to the Coast shooting mini-game:
Code: [Select]
//coaster[UPDATE][callback]
void C_005E8E7E(struct t_aa0 *bp08) {
C_005E8D03(0, 0, 0, 1.0f);//coaster:clear buffers
//%%% check ending condition? %%%
if(D_00C3F75C * 4  > D_00C3F894 - 0x10 || D_00C3F774 == 1) {//else 005E8ECB
C_005E988B();//sound related(6)
C_005E8E0B(bp08);//to mainDispatcher for coaster
return;
}
//%%% %%%
C_005E8F9B(bp08);//coaster:next frame
C_0041A21E(bp08);//Refresh input driver?
if(C_00660EC0(0, bp08)) {//G_DRV_88:BeginScene
C_00666DA3(bp08);//calls "instance:reset"
C_00666DC0(bp08);//calls "dx_sfx:reset heaps(1)"
C_00666DDD(bp08);//reset "deferred heap"
//-- refresh without display --
while(D_00C3F6EC + 1.0f < D_00C3F6E8) {
D_009014A8 = 0;
C_005E9051(bp08);//coaster.refresh
D_00C3F6EC += 1.0f;
}
//-- refresh with display --
D_009014A8 = 1;
C_005E9051(bp08);//coaster.refresh
D_00C3F6EC += 1.0f;
//-- --
C_00660EEB(bp08);//G_DRV_8C:EndScene
}
C_005E8E06();//<empty>
}

You can find others amples on my (not very good) blog concerning decompilation: http://magnetiktank.blogspot.jp/

15
Funny, decompiling Final Fantasy VII is what I have been doing for some times now.
The PC version I mean, and the patch version 1.02.
I succeeded in reversing most of the minigames (except condor) and most of the main systems (except battle) so far.
It's not easily readable (I use their addresses to name the functions and the global so far, and do not plan to rename them until all is done), but you can get a lot of information from it.
Since it's the most comprehensible of the lot I wanted to post the code to the roller-coaster mini game, but I guess I won't be allowed to do it here right ?
(though I don't understand why posting reversed data is less infringing than posting reversed code)

Pages: [1]