Author Topic: [FF7] camdat files  (Read 11226 times)

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
[FF7] camdat files
« on: 2009-10-14 19:10:26 »
After performing a search for these files I've found that they've been largely ignored for about five years. I'd like to see if I can discover their purpose. I have a few notes I'd like to share, but I don't want to spout them all out if someone has actual info that contradicts mine.

Does anyone have any info regarding the structure of these files?

Akari

  • *
  • Posts: 766
    • View Profile
Re: [FF7] camdat files
« Reply #1 on: 2009-10-14 19:17:15 »
This is camera packs for battle. Most likely camera data itself is stored just like in movies.

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Re: [FF7] camdat files
« Reply #2 on: 2009-10-14 20:31:07 »
True, those are camera motions for various battle sequences (likely camera movements for attacks), but they doesn't seem to have much in common with the .cam files that control the movies.

It actually seems to be quite different.

<thinking_out_loud>
The movie .cam files come into play when a character needs to be overlaid with the video. It looks like there are 10 signed DWORDS for each frame of the video. The first six look most important (ie, actual coordinates for the camera), but I don't know what the next three do. The last seems to be some kind of scene indicator or flag of some sort. I'm sure plenty is know about these by now.
</thinking_out_loud>

Anyway, the battle cameras function very differently. If I'm reading the archive correctly, the segments vary in size but are multiples of 4 bytes. They appear to be in some sort of script form terminated with F4h FFh and 0s added to the next fourth block (run the script until you find FFF4h?). Very little else I've seen about them other than their indexing structure.

Covarr

  • Covarr-Let
  • Administrator
  • *
  • Posts: 3941
  • Just Covarr. No "n".
    • View Profile
Re: [FF7] camdat files
« Reply #3 on: 2009-10-15 00:39:57 »
Coordinates: I assume three for location, three for rotation? Anything relating to size/zoom?

Akari

  • *
  • Posts: 766
    • View Profile
Re: [FF7] camdat files
« Reply #4 on: 2009-10-15 04:56:08 »
I don't know how they stored it on PC, but on PSX each camera frame stored as transformation packet for GTE. This is used in field to set 3d transformations for models and in movies. It must be true for battle )

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Re: [FF7] camdat files
« Reply #5 on: 2009-10-15 14:03:57 »
I don't know how they stored it on PC, but on PSX each camera frame stored as transformation packet for GTE. This is used in field to set 3d transformations for models and in movies. It must be true for battle )

Are you talking about the movie cams or the battle cams? The PCs version of the battle cams might be different. It doesn't seem like anyone has UnLZSed them to compare them.

Battle related cameras can't just be origin and target coordinates, they'd have to include someway of playing sounds. The final Sephiroth battle is the best (only?) example of this. I believe it most likely that these files contain all the camera-related battle data (this is where all the indexes point to) and it's further likely that they contain a combination of relative and absolute pointers (point at caster for x seconds, then sweep to target(s), etc.).

Akari

  • *
  • Posts: 766
    • View Profile
Re: [FF7] camdat files
« Reply #6 on: 2009-11-18 14:21:45 »
I looked at those a little. There is bytecode sequence as well =)

offset 0x4 is pointer to list of offsets to camera data's (3 offsets for each camera id).
offset 0xc is pointer to 3 camera data for win camera.

At each offset start of camera sequence. Control bytes are 0xd8-0xff.

ps: still don't know why it use 3 offsets. It just call function 3 times for each of offsets.

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Re: [FF7] camdat files
« Reply #7 on: 2009-11-18 16:11:11 »
There are four DWORD pointers at the beginning at 0x0, 0x4, 0x8, and 0xC

for camdat0.bin:
0x0 points to 1182 addresses in this file. Most of these are unique, but plenty are not.
0x4 has same structure as 0x0, but point to different locations.
0x8 points to 3 locations
0xC points to 3 locations (one of these is likely win cam, but what are the others?)

for camdat1.bin:
same as camdat0, but 0x0 and 0x4 point to 1125 addresses each

for camdat2.bin:
same as camdat1, but 0x0 and 0x4 point to 1122 addresses each

At a glance, I can't tell if any of the camera segments are similar to segments in other files. Why are they separated into three files? Are they different for each disc?

Akari

  • *
  • Posts: 766
    • View Profile
Re: [FF7] camdat files
« Reply #8 on: 2009-11-18 17:23:44 »
There are four DWORD pointers at the beginning at 0x0, 0x4, 0x8, and 0xC

for camdat0.bin:
0x0 points to 1182 addresses in this file. Most of these are unique, but plenty are not.
0x4 has same structure as 0x0, but point to different locations.
0x8 points to 3 locations
0xC points to 3 locations (one of these is likely win cam, but what are the others?)

for camdat1.bin:
same as camdat0, but 0x0 and 0x4 point to 1125 addresses each

for camdat2.bin:
same as camdat1, but 0x0 and 0x4 point to 1122 addresses each

At a glance, I can't tell if any of the camera segments are similar to segments in other files. Why are they separated into three files? Are they different for each disc?

All this locations are camera scripts. Some of them are not in camdat though. For example idle camera script or start battle camera script.

Camdats are different for different battle layout. It's set in battle setup +0x12 byte. 0,1,8 - CAMDAT0.LZS, 2 - CAMDAT1.LZS, 3,4,5,6,7 - CAMDAT2.LZS.

Akari

  • *
  • Posts: 766
    • View Profile
Re: [FF7] camdat files
« Reply #9 on: 2009-11-24 14:24:42 »
There are four DWORD pointers at the beginning at 0x0, 0x4, 0x8, and 0xC

for camdat0.bin:
0x0 points to 1182 addresses in this file. Most of these are unique, but plenty are not.
0x4 has same structure as 0x0, but point to different locations.
0x8 points to 3 locations
0xC points to 3 locations (one of these is likely win cam, but what are the others?)

New info.
Offset 0x0 points to scripts for camera position vector scripts.
Offset 0x4 points to scripts for camera direction vector scripts.

There are 3 scripts for each camera id. Each of them called every time and result stored to 3 different structures. Which one to use are completly random.

 if ((game_timer & 3) != 3)
 {
  struct_id = game_timer & 3;
 }

3 is special cases, if developer want camera to work not random way.

Win camera not the exeption. there are 3 pointers to this camera.
0x8 points to position scripts for win camera.
0xc points to direction scripts for win camera.

Simple script example from start battle camera direction vector:
FA(30F8,9CFF,1027) - set start position of camera
E2(3C) - set callback function for transition from start position to idle position from battle setup with given number of steps.
F5(3C) - set wait timer
F4 - wait
FF - finish

0xE2 opcode is most important. There are few callback functions, but they fixed for opcode. calling opcode 0xE2 and 0xE8 will produce different transition effect.

Problem mostly solved =)
« Last Edit: 2009-11-24 14:48:55 by Akari »

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Re: [FF7] camdat files
« Reply #10 on: 2009-11-24 21:55:05 »
So section 0 entries have pairs in section 1 and each camera index is a triplet (cam_ind x 3, cam_ind x 3 + 1, and cam_ind x 3 + 2)?

The highest value of camera index I've seen is Adamantaimai's Light Shell. That's 0155h.
For the different battle types, these are ranges of start-cam and the camdat file they're associated with:

0,0 : 0h - 66h
1,0 : Ch
2,1 : 0h - 43h
3,2 : 0h - 2Dh
4,2 : 0h - 66h
5,2 : 0h - 2Dh
6,2 : 0
7,2 : 4C
8,0 : 56h, 58h

I'm unsure how these references translate into actual indexes. The start-cams aren't using three different cams. They're absolute. So if I'm calculating these correctly, then there are 168h "triplets" of cam indexes in camdat0.bin, 160h in camdat1.bin, and 153h in camdat2.bin.

Akari

  • *
  • Posts: 766
    • View Profile
Re: [FF7] camdat files
« Reply #11 on: 2009-11-25 04:20:00 »
So section 0 entries have pairs in section 1 and each camera index is a triplet (cam_ind x 3, cam_ind x 3 + 1, and cam_ind x 3 + 2)?

Yes, and win camera work the same way (exept there is only one camera).

The highest value of camera index I've seen is Adamantaimai's Light Shell. That's 0155h.
For the different battle types, these are ranges of start-cam and the camdat file they're associated with:

0,0 : 0h - 66h
1,0 : Ch
2,1 : 0h - 43h
3,2 : 0h - 2Dh
4,2 : 0h - 66h
5,2 : 0h - 2Dh
6,2 : 0
7,2 : 4C
8,0 : 56h, 58h

I'm unsure how these references translate into actual indexes. The start-cams aren't using three different cams. They're absolute. So if I'm calculating these correctly, then there are 168h "triplets" of cam indexes in camdat0.bin, 160h in camdat1.bin, and 153h in camdat2.bin.

Init camera scripts are not in camdat. They loaded with all load data earlier (they are right after init positions for players).
Init camera scripts called 3 times with the same address. So random doesn't affect it, there are same info in all slots.
Idle camera works the same way (but there is only one script for direction and one for position).

Quote
The highest value of camera index I've seen is Adamantaimai's Light Shell. That's 0155h.

0x15e - Smoke Shot for Sweeper.
« Last Edit: 2009-11-27 19:50:06 by Akari »

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Re: [FF7] camdat files
« Reply #12 on: 2010-07-06 19:57:35 »
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.
Code: [Select]
            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:

Code: [Select]
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.
« Last Edit: 2011-03-11 21:24:46 by NFITC1 »

Bosola

  • Fire hazard!
  • *
  • Posts: 1752
    • View Profile
    • My YouTube Channel
Re: [FF7] camdat files
« Reply #13 on: 2010-07-06 21:16:26 »
Slightly off-topic, but what do we know about the camera data for attacks in battle? Do the camera angle indeces refer to camdat files, or are they just parameters for camera movement (the former seems far more likely)?

nfitc1

  • *
  • Posts: 3011
  • I just don't know what went wrong.
    • View Profile
    • WM/PrC Blog
Re: [FF7] camdat files
« Reply #14 on: 2010-07-06 22:18:21 »
Slightly off-topic, but what do we know about the camera data for attacks in battle? Do the camera angle indeces refer to camdat files, or are they just parameters for camera movement (the former seems far more likely)?

I think all that's definite is that battle type determines which camdat to use. After that it's the camera index that determines which camera set (position and focus) to use.

There's over 1000 scripts in each camdat file, but like Akari mentioned I believe the game will sometimes pick one at random. Imagine that each camera index is multiplied by three. Then the game chooses between that result and the next two. So if the camera index is 100, then the game will select either 300, 301, or 302. In some cases, this is sort of unrandomized by listing those three indexes the same. Camera set 300, 301, and 302 will use position script 517 and focus script 518 (for example). I'm not sure how the camera value translates into actual camera set data. Camera data gets bounced around a lot before it gets used.

Akari

  • *
  • Posts: 766
    • View Profile
Re: [FF7] camdat files
« Reply #15 on: 2010-07-07 09:14:38 »
Slightly off-topic, but what do we know about the camera data for attacks in battle? Do the camera angle indeces refer to camdat files, or are they just parameters for camera movement (the former seems far more likely)?

I think all that's definite is that battle type determines which camdat to use. After that it's the camera index that determines which camera set (position and focus) to use.

There's over 1000 scripts in each camdat file, but like Akari mentioned I believe the game will sometimes pick one at random. Imagine that each camera index is multiplied by three. Then the game chooses between that result and the next two. So if the camera index is 100, then the game will select either 300, 301, or 302. In some cases, this is sort of unrandomized by listing those three indexes the same. Camera set 300, 301, and 302 will use position script 517 and focus script 518 (for example). I'm not sure how the camera value translates into actual camera set data. Camera data gets bounced around a lot before it gets used.

Try look at some scripts I reversed. For example here http://q-gears.svn.sourceforge.net/viewvc/q-gears/trunk/reversing/ffvii/ffvii_battle/camera/camera_script_export_attack_normal.lua?revision=413&view=markup

Every reverse related to thing related are here - http://q-gears.svn.sourceforge.net/viewvc/q-gears/trunk/reversing/ffvii/ffvii_battle/camera/

How it works:
1) Camera id selected acording to actions (idle or some action camera ot victory camera).
2) 2 actual camera sequences randomly selected one for camera position and one for camera directions.

Note: camera seted based on this two points. They stored in two structures and camera updates every frame based on this structures. So script just need to update this points positions. Script rarely set camera position directly. more often it call transition functions that update position or direction of camera each frame.

3) Scripts actually runned. For example one of script:
set static view of attacker for 0xf frames
set_transition("static_attacker_view", "attacker_joint0", 0x0000, 0xff88, 0x0000, 0xf); --E8 00 0000 88FF 0000 0F

set script to wait 0xf frames before continue.
set_wait(0x0f); --F5 0F

actual wait
wait(); --F4

next set linear transition to next point related to attacker joint 6
set_transition("direct_transition", "attacker_joint6", 0x0000, 0x0000, 0x0000, 0x8); --E4 06 0000 0000 0000 08

wait again
set_wait(0x08); --F5 08
wait(); --F4

next move to target joint 0
set_transition("direct_transition", "target_joint0", 0x0000, 0x0000, 0x0000, 0x8); --E5 00 0000 0000 0000 08

and wait
set_wait(0x08); --F5 08
wait(); --F4

remain here until next camera id is set
loop();