So, yes, I'm Necroing this post. It's mine I'm allowed to hijack it if I need to.
I did find something useful that isn't here or on the wiki and I want it logged.
Re-Write:
This looked sloppy before. Let me re-write it.
There are two sets of commands associated with each camera movement. There's a command set for the position of the camera, and a command set for the focal point of the camera (not the vector that the camera is pointing in, the point in the scene that is in the center of the camera). Each script modifies a group of 14 bytes. The structure of them is this:
0x0: X (Word)
0x2: Y (Word)
0x4: Z (Word)
0x6: Align 0x2
0x8: Progress (Word; like the program counter for the script)
0xA: Wait (Word; number of loops to wait)
0xC: Unknown1 (Byte)
0xD: Unknown2 (Byte) [Focus script does not use this]
The commands for each instruction are located in two different places in the exe.
Function addresses Function address pointers (annoying, isn't it?)
Position 0x5C3C61 N/A (other values point to "end")
Focus 0x5C5268 0x5C52D0
Valid opcodes and their argument counts for position scripts are:
D5 - (One Word Parameter)
D6 - (No Parameters)
D7 - (Two Byte Parameters)
D8 - (Two Byte, Three Word, One Byte Parameters) *
D9 - (No Parameters) Loads Point from memory at 0xBF2158
DA - (No Parameters) Sets Unknown2 to 0
DB - (No Parameters) Sets Unknown2 to 1
DC - (No Parameters) Sets Unknown1 to 1
DD - (One Byte Parameter) Sets active "Idle" camera index (based on formation data) to parameter
DE - (One Byte Parameter) If non-0 parameter, set 0xBF2A34 to 3
DF - (No Parameter) Sets 0xBF2A34 to Fh; No questions asked
E0 - (Two Byte Parameters)
E1 - (No Parameters) Loads current idle camera position point
E2 - (One Byte Parameter)
E3 - (Two Byte, Three Word, One Byte Parameters) *
E4 - (One Byte, Three Word, One Byte Parameters) *
E5 - (One Byte, Three Word, One Byte Parameters) *
E6 - (Three Word, One Byte Parameters)
E7 - (One Byte, Three Word, One Byte Parameters)
E9 - (One Byte, Three Word, One Byte Parameters)
EB - (Two Byte, Three Word, One Byte Parameters)
EF - (Two Byte, Three Word Parameters)
F0 - (One Byte, Three Word Parameters)
F1 - (No Parameters) Sets Unknown1 to 0
F2 - (One Byte, Two Word Parameters)
F3 - (One Byte, Two Word Parameters)
F4 - (No Parameters) Wait
F5 - (One Byte Parameter) Set Wait
F7 - (Six Word Parameters) Store These values in six words starting at 0xBFCE0C (not in order)
F8 - (One Byte, Three Word Parameters)
F9 - (Three Word Parameters) Load Point specified by parameters (X, Y, Z as Words)
FE - (One Optional Parameter) If waiting and next byte is C0h, then restart script and stop waiting. Else do nothing?
FF - (No Parameters) ScriptEnd
Focal point scripts use a different set:
D8 - (Two Byte, Three Word, One Byte Parameters) *
D9 - (No Parameters) Loads point from memory at 0xBFB1A0
DB - (No Parameters) Sets Unknown to 0
DC - (No Parameters) Sets Unknown to 1
DD - (One Byte Parameter) Sets Current active "Idle" Camera (indexed in formation data) to parameter
DE - (One Byte Parameter) If non-0 parameter, set 0xBF2A34 to 3
DF - (No Parameter) Sets 0xBF2A34 to Fh; No questions asked
E0 - (Two byte parameters)
E1 - (No Parameters) Loads point of current active "Idle" camera
E2 - (One Byte parameter) Does something with active "Idle" Camera index and loading a new point based on it.
E3 - (Two Byte, Three Word, One Byte Parameters) *
E4 - (One Byte, Three Word, One Byte Parameters) *
E5 - (One Byte, Three Word, One Byte Parameters) *
E6 - (Three Word, One Byte Parameters)
E8 - (One Byte, Three Word, One Byte Parameters)
EA - (One Byte, Three Word, One Byte Parameters)
EC - (Two Byte, Three Word, One Byte Parameters)
F0 - (Two Byte, Three Word Parameters)
F4 - No Parameters; "Pause" processing while decrementing "Wait" by 1 each iteration. (Seems sketchy since loops would be different based on processing power)
F5 - One Parameter; Set "Wait"
F8 - (One Byte, Three Word Parameters)
F9 - (One Byte, Three Word Parameters)
FA - (Three Word Parameters) Load Point specified by parameters (X, Y, Z as Words)
FE - (One Optional Parameter) If waiting and next byte is C0h, then restart script and stop waiting. Else do nothing?
FF - (No Parameters) ScriptEnd
* May use stepping method to calculate position per frame.
Camera scripts:
Initial Battle cam (intro movement as you start a battle) scripts are located at 0x9001A0 (pointers start at 0x9010D0 for position scripts and 0x901270 for focus scripts) and are generally paired Position0, Focus0, Position1, Focus1, etc.
Camdat files are similar. Each one has a main header of four unsigned longs beginning with 801Ah*:
Position script pointers location
Focus script pointers location
Victory cam Position script pointers location
Victory cam Focus script pointers location
Then the actual scripts start. Within camdat0.dat there are 1019 pos cam scripts and 1022 foc cam scripts in this block. They're usually Position, Focus, Position, Focus, but sometimes not (as seen shortly). The scripts are traditionally aligned to the nearest fourth byte (filled in with 00h).
After this block come the actual pointers. First the Position pointers then the Focus pointers. They point to the beginning of the script to be used. There are an equal number of position pointers and focus pointers. Within camdat0.dat there are 1182 pairs in this section. Some of them use the same scripts so there are duplicate pointers. This is why there are more pointers than scripts. These pointers will have the same 801Ah header as well*.
Finally, the win camera comes in the same way. Scripts first, then pointers*. There are always three pos/foc pairs.
The game chooses which camdat file to use based on the battle type (0-8). This is decided at 0x7C2528:
Battle type: Camdat file:
0 0
1 0
2 1
3 2
4 2
5 2
6 2
7 2
8 0
Other discovery is pending.
*Upper Word is discarded when loading the camdat files, but it is necessary to have because of lazy coding on the PCs part. The loaded value is subtracted by 801A0000h instead of being BIT-wise anded by FFFFh. All camdat indexes are like that.