Sims 3:0x6B20C4F3
Sims 3:Main Page -> Sims 3:PackedFileTypes
S3Clip (NOT complete in any sense of the word - Karybdis)
These resources do not always hash from the animation name to the resource key. Any age specifiers (a2p, t2o, etc) are converted to only reference adult or objects (a or o) respectively to generate the hash, and the high bit is stripped off. This becomes the "default" animation if no age specific override is provided. Age overrides are found by XORing an age mask with the high byte (Or the second high byte for the second actor in an animation).
Contents |
Main Header
Offsets in the main header are all based off the location of the offset value. So an offset at byte 4 would point to 4 + offset.
DWORD - TID DWORD offset // Offset of a linked clip - purpose unknown, always 0 DWORD size of _S3Clip_ Section DWORD clipoffset // offset to _S3Clip_ section DWORD slotoffset // Offset to actor/slot pair table DWORD actoroffset // Offset to clip actor name (Null terminated string) DWORD eventoffset // Offset to clip event section DWORD // 0 or 2 DWORD // all have been 1 DWORD endoffset // Offset to 16 bytes of unknown data 16 BYTES // blank
Clip Header
The source file name is important in that jazz scripts reference it for assigning the jazz actors to the clip actors. Frame data is format dependent. If the time code override is used, it is at the start of the frame data chunk, with the first joint movement rule starting right after it.
QWORD _S3Clip_ // Integer value, not a string, so swapped for byte order on little endian DWORD version // 2 DWORD // blank FLOAT frameduration // Always seen as 1/30 WORD framecount // Not necessarily the number of frames in this clip WORD // unknown - might be uncleared memory DWORD count1 // Joint movement rules DWORD count2 // Indexed float count - floats listed at start of frame data DWORD offset1 // Offset from start of clip header to joint movement rules DWORD offset2 // Offset from start of clip header to frame data DWORD anim name offset // Offset to null terminated animation name DWORD source file offset // Offset to null terminated source file
Joint Movement Rules
DWORD frame data offset // Offset into frame data for this movement data DWORD hash // joint name FLOAT offset // Offset to apply to the values in the frame data FLOAT scale // Scale to apply to the values in the frame data WORD frames // Number of defined frames in the frame data WORD frame data type
Frame Data
WORD Frame Index // Can skip some or most frames WORD Sign bits + ? // Has some data beyond sign bits in there // Type dependant data (Bit 0 = sign of first value, bit 1 = sign of second value, etc)
The type dependant data can be one of the following. The sign bits are applied to all values, even those that are floats (Indexed float values). For integer values, the value is converted to a float by dividing by the maximum possible value, for example 4095 or 1023.
Data type | Data format | Count | Usage notes |
---|---|---|---|
0x103 | WORD | 3 | Indexed float reference |
0x10b | ? | ? | Always with a 0 count |
0x112 | DWORD
Contains 3 10-bit values packed into 30 bits |
1 | Used as translation values |
0x20c | ? | ? | Always with a 0 count |
0x211 | ? | ? | Always with a 0 count |
0x214 | WORD
Only 12 bits used (0...4095) |
2 | Quaternion rotational values
Order is XYZW. Framework requires +90 degree rotation |
Actor/Slot Table
Table always starts on a DWORD boundary, padded with 0x7e if needed. All offsets are based on the start of the corresponding offset table. It is unclear what the significance of primary entries vs secondary entries is. The named actor may or may not be the actor for the animation.
DWORD count // Primary entry count REP count DWORD offset REP count DWORD pad // 0x7e7e7e7e DWORD count2 // Secondary entry count REP count2 DWORD offset REP count2 DWORD index // Secondary entry index 512 BYTE Actor // Name, null terminated and padded with 0x23 (#) 512 BYTE Slot // Name, null terminated and padded with 0x23 (#)
Clip Events
Offsets in this table are based on the address of the start offset.
4 BYTES "=CE=" DWORD version // 0x103 DWORD count // Event count DWORD endoffset DWORD startoffset // 4 if count > 0, otherwise 0 REP count WORD event type WORD 0xc1e4 DWORD id // Type dependent meaning FLOAT timecode // When to trigger the event FLOAT // -1.0 FLOAT // -1.0 DWORD DWORD length // Can be 0, in which case the name still includes the null terminator and DWORD padding STRING event name // Size is length, with added null terminated followed by 0-padding to next DWORD // Type dependent data
Event type | Description | Notes |
---|---|---|
1 | Attach object | Attach a prop object to a specific slot |
2 | Un-parent | Mostly used for the bath ducky |
3 | Play sound | |
4 | SACS script event | ID is the event ID to send to the game scripts |
6 | ||
9 | Destroy prop | Destroys an object created with "Create prop" in jazz scripts |
10 |
Event 1
DWORD hash // Prop actor name DWORD hash // Object actor name DWORD hash // Slot to attach to on object DWORD // Blank
Event 2
DWORD hash // Object actor name to unparent
Event 3
On event type 3, after the string there is various data. It can take the form of a series of floats, a series of incrementing dwords, or data that looks compressed or encrypted. Given that the same data appears in multiple instances with varying amounts of it overwritten by the string, it seems likely that it is just random data from memory that was not cleared.
128 BYTES // Sound name null terminated
Event 4
// No additional data
Event 5
DWORD DWORD DWORD hash // Effect name DWORD hash // actor name DWORD hash // to attach effect to
Event 6
FLOAT
Event 9
DWORD hash // Actor name of prop to destroy
Event 10
DWORD hash DWORD // blank?
End Data
12 BYTES // Empty FLOAT // 1.0