20
« on: 2019-02-18 13:49:56 »
The structure that the camera animation is loaded into looks like:
struct CameraStruct {
BYTE unkbyte000; //000
BYTE unkbyte001; //001 keyframe count?
WORD control_word; //002
WORD unkword004; //004
WORD unkword006; //006
WORD unkword008; //008
WORD unkword00A; //00A
WORD unkword00C; //00C
WORD unkword00E; //00E total frame count/time?
BYTE unk[20] //010
short unkword024[32]; //024 - start frames for each key frame?
short unkword064[32]; //064
short unkword0A4[32]; //0A4
short unkword0E4[32]; //0E4
BYTE unkbyte124[32]; //124
short unkword144[32]; //144
short unkword184[32]; //184
short unkword1C4[32]; //1C4
BYTE unkbyte204[32]; //204
BYTE unkbyte224[128]; //224
BYTE unkbyte2A4[128]; //2A4
BYTE unkbyte324[128]; //324
BYTE unkbyte3A4[128]; //3A4
BYTE unkbyte424[128]; //424
BYTE unkbyte4A4[128]; //4A4
};
and the function that parses the animation into it looks something like:
short* parse_camera(short* camera_data, CameraStruct* cam) {
short* local2C;
BYTE keyframecount;
WORD totalframecount;
short* local1C;
short* local18;
short* local14;
short* local10;
short* current_position = camera_data;
if (*current_position == 0xFFFF) {
return NULL;
}
cam->control_word = *current_position;
current_position++;
totalframecount = 0;
keyframecount = 0;
switch ((cam->control_word >> 6) & 3) {
case 1:
cam->unkword004 = 0x200;
cam->unkword006 = 0x200;
break;
case 2:
cam->unkword004 = *current_position;
cam->unkword006 = *current_position;
current_position++;
break;
case 3:
cam->unkword004 = *current_position++;
cam->unkword006 = *current_position++;
break;
}
switch ((cam->control_word >> 8) & 3) {
case 0:
cam->unkword008 = ff8vars.unkword1D977A2;
cam->unkword00A = ff8vars.unkword1D977A2;
break;
case 1:
cam->unkword008 = 0;
cam->unkword00A = 0;
break;
case 2:
cam->unkword008 = *current_position;
cam->unkword00A = *current_position;
current_position++;
break;
case 3:
cam->unkword008 = *current_position++;
cam->unkword00A = *current_position++;
break;
}
switch (cam->control_word & 1) {
case 0:
if (*current_position >= 0) {
do {
cam->unkword024[keyframecount] = totalframecount;
totalframecount += *current_position++ * 16;
cam->unkbyte124[keyframecount] = *current_position++;
cam->unkword064[keyframecount] = *current_position++;
cam->unkword0A4[keyframecount] = *current_position++;
cam->unkword0E4[keyframecount] = *current_position++;
cam->unkbyte204[keyframecount] = *current_position++;
cam->unkword144[keyframecount] = *current_position++;
cam->unkword184[keyframecount] = *current_position++;
cam->unkword1C4[keyframecount] = *current_position++;
keyframecount++;
} while (*current_position >= 0);
if (keyframecount > 2) {
ff8funcs.Sub50D010(cam->unkword024, cam->unkword064, cam->unkword0A4, cam->unkword0E4, keyframecount, cam->unkbyte224, cam->unkbyte2A4, cam->unkbyte324);
ff8funcs.Sub50D010(cam->unkword024, cam->unkword144, cam->unkword184, cam->unkword1C4, keyframecount, cam->unkbyte3A4, cam->unkbyte424, cam->unkbyte4A4);
}
}
break;
case 1:
if (*current_position >= 0) {
local14 = current_position + 5;
local10 = current_position + 6;
local2C = current_position + 7;
local18 = current_position + 1;
local1C = current_position + 2;
short* ebx = current_position + 3;
do {
cam->unkword024[keyframecount] = totalframecount;
totalframecount += *current_position++ * 16;
ff8funcs.Sub503AE0(++local18, ++local1C, ++ebx, *(BYTE*)current_position, &cam->unkword064[keyframecount], &cam->unkword0A4[keyframecount], &cam->unkword0E4[keyframecount]);
ff8funcs.Sub503AE0(++local14, ++local10, ++local2C, *(BYTE*)(current_position + 4), &cam->unkword144[keyframecount], &cam->unkword184[keyframecount], &cam->unkword1C4[keyframecount]);
cam->unkbyte204[keyframecount] = 0xFB;
cam->unkbyte124[keyframecount] = 0xFB;
local1C += 8;
local18 += 8;
current_position += 8;
local2C += 8;
ebx += 8;
local10 += 8;
local14 += 8;
keyframecount++;
} while (*current_position >= 0);
if (keyframecount > 2) {
ff8funcs.Sub50D010(cam->unkword024, cam->unkword064, cam->unkword0A4, cam->unkword0E4, keyframecount, cam->unkbyte224, cam->unkbyte2A4, cam->unkbyte324);
ff8funcs.Sub50D010(cam->unkword024, cam->unkword144, cam->unkword184, cam->unkword1C4, keyframecount, cam->unkbyte3A4, cam->unkbyte424, cam->unkbyte4A4);
}
}
break;
}
if ((cam->control_word & 0x3E) == 0x1E) {
ff8funcs.Sub503300();
}
cam->unkbyte001 = keyframecount;
cam->unkword00E = totalframecount;
cam->unkword00C = 0;
return current_position + 1;
}
note: adding to a word pointer adds 2 to the value.
The size of the animation depends a lot on the control word and the amount of keyframes.
I haven't verified the code completely but it should be roughly correct with some possible minor errors.