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.