Structs

TODO: Describe kaitai structs

Load the definitions into the Kaitai WebIDE to interactively explore binaries and generate parsers.

fastfile.ksy

Download

fastfile.ksy
meta:
  id: fastfile
  file-extension: fastfile
  endian: le
seq:
  - id: num_offsets
    type: u4
  - id: first_offset
    type: u4
  - id: files
    type: file_entry(_index) # <= pass `_index` into file_entry
    repeat: expr
    repeat-expr: num_offsets - 1
types:
  file_entry:
    params:
      - id: i                # => receive `_index` as `i` here
        type: u4
    seq:
      - id: filename
        type: strz
        size: 13
        encoding: ASCII
      - id: ofs_end
        type: u4
    instances:
      ofs_start:
        # Normally we access previous file's end offset and use it as
        # our current start offset, but for the very first file we'll
        # use special field, as "previous file" does not exist for it.
        value: 'i > 0 ? _parent.files[i - 1].ofs_end : _parent.first_offset'
      filesize:
        value: ofs_end - ofs_start
      body:
        pos: ofs_start
        size: filesize

t3d_fast_file.ksy

Download

t3d_fast_file.ksy
meta:
  id: t3d_fast_file
  file-extension:
    - t3d
    - ff
  endian: le

seq:
  - id: header
    type: header

  - id: files
    type: file(_index)
    repeat: expr
    repeat-expr: header.num_offsets - 1

  - id: total_filesize
    type: u8

  - id: filenames
    type: strz
    encoding: ASCII
    repeat: expr
    repeat-expr: header.num_offsets - 1

types:
  header:
    seq:
      - id: magic
        contents: [0x02, 0x3D, 0xFF, 0xFF]
      - id: version
        contents: [0x00, 0x57, 0x01, 0x00]
      - id: num_offsets
        type: u4
      - id: filenames_length
        type: u4
  file:
    params:
      - id: i
        type: u4
    seq:
      - id: file_offset
        type: u4
      - id: filename_offset
        type: u4
    instances:
      next_file_offset:
        value: '(i == _root.header.num_offsets - 2) ? _root.total_filesize : _parent.files[i + 1].file_offset'
      filename:
        io: _root._io
        type: strz
        encoding: ASCII
        pos: sizeof<header> + (sizeof<file> * i) + filename_offset
      filesize:
        value: next_file_offset - file_offset
      body:
        io: _root._io
        pos: file_offset
        size: filesize


sony_wld.ksy

Incomplete.

Download

sony_wld.ksy
meta:
  id: sony_wld
  title: Binary Sony WLD
  file-extension: wld
  endian: le

# rethink flags
#  (flags & 0b10) >> 1 == 1 could be (flags & 0b10) != 0
#  look into kaitai's bitfield docs

doc: |
  Sony WLD Doc.
seq:
  - id: header
    type: header
    doc: WLD file header
  - id: string_hash
    type: xor_string(header.string_hash_bytes, header.string_count)
  - id: objects
    type: wld_object
    repeat: expr
    repeat-expr: header.object_count
  - id: footer
    contents: [0xff, 0xff, 0xff, 0xff]
types:
  header:
    seq:
      - id: magic
        contents: [0x02, 0x3d, 0x50, 0x54]
      - id: version
        type: u4
      - id: object_count
        type: u4
      - id: region_count
        type: u4
      - id: max_object_bytes
        type: u4
      - id: string_hash_bytes
        type: u4
      - id: string_count
        type: u4

  xor_string:
    params:
      - id: length
        type: u2
      - id: count
        type: u2
    seq:
      - id: decoded
        size: length
        # wasn't able to get the key stored as a value instance
        process: xor([0x95, 0x3A, 0xC5, 0x2A, 0x95, 0x7A, 0x95, 0x6A])
        type: decoded_string_raw(count)
    types:
      decoded_string_raw:
        params:
          - id: repeats
            type: u2
        seq:
          - id: strings
            type: strz
            encoding: ASCII
            repeat: expr
            repeat-expr: repeats + 1
        instances:
          raw:
            pos: 0
            type: str
            encoding: ASCII
            size-eos: true

  string_hash_reference:
    doc: Decode and return the string at `position` in the `string_hash`
    params:
      - id: position
        type: u2
    instances:
      string:
        io: _root.string_hash.decoded._io
        pos: position * -1
        type: strz
        encoding: ASCII


  wld_object:
    seq:
      - id: length
        type: u4
      - id: object_type
        type: u4
      - id: body
        size: length
        type:
          switch-on: object_type
          cases:
            0x3: object_type_03 # FRAME and BMINFO
            0x4: object_type_04 # SIMPLESPRITEDEF
            # 0x5: object_type_05 # merchant 25 I think
            0x6: object_type_06
            0x8: object_type_08
            0x12: object_type_12 # TRACKDEFINITION
            0x13: object_type_13 # TRACKINSTANCE
            0x16: object_type_16 # SPHERE
            0x18: object_type_18 # POLYHEDRON
            0x1a: object_type_1a # SPHERELIST
            0x1b: object_type_1b
            0x1c: object_type_1c # part of pointlight
            0x21: object_type_21 # WORLDTREE
            0x28: object_type_28 # POINTLIGHT
            # 0x19 # SPHERELISTDEFINITION
            # _: object_type_unknown

  # FRAME and BMINFO
  # FRAME "filename" "name"
  object_type_03:
    seq:
      - id: name_reference
        type: s4
      - id: filename_count
        type: u4
      - id: filenames
        type: filename
        repeat: expr
        repeat-expr: filename_count
    instances:
      name:
        type: string_hash_reference(name_reference)
    types:
      filename:
        seq:
          - id: length
            type: u2
          - id: name
            size: length
            type: xor_string(length, 0)

  # SIMPLESPRITEDEF
  object_type_04:
    doc: |
      ```
      SIMPLESPRITEDEF
        SIMPLESPRITETAG %s
        NUMFRAMES %d
        // repeated NUMFRAMES times
        FRAME "%s" "%s"
        CURRENTFRAME %d
        SLEEP %d
        SKIPFRAMES ON
      ENDSIMPLESPRITEDEF
      ```
    seq:
      - id: name_reference
        type: s4

      # bit 2 => CURRENTFRAME %d
      # bit 3 => SLEEP %d
      # bit 3 and 5 => SKIPFRAMES ON
      - id: flags
        type: s4
        # type: b16le

      # NUMFRAMES %d
      - id: frame_count
        type: u4

      # SLEEP %d
      - id: sleep
        type: u4
        if: animated == 1

      # points to 0x03 objects
      - id: frame_references
        type: u4
        repeat: expr
        repeat-expr: frame_count

    instances:
      # SIMPLESPRITETAG "%s"
      name:
        type: string_hash_reference(name_reference)
        # TODO: should it check if name_reference is 0
      animated:
        value: (flags & 0b1000) >> 3
      skip_frames:
        value: (flags & 0b101000) != 0


  # I think this is the ascii that is it generated from: im pretty confident
  # SIMPLESPRITEINST
  #   TAG "PIZZA_SPRITE"
  # ENDSIMPLESPRITEINST
  # object_type_05:

  # 2DSPRITEDEF
  object_type_06:
    doc: |
      #### Example
      ```
      2DSPRITEDEF
        2DSPRITETAG I_SWORDSPRITE
        CENTEROFFSET 0.0 1.0 0.0
        NUMFRAMES 2
        SLEEP 100
        SPRITESIZE 1.0 1.0
        NUMPITCHES 2
        PITCH 1
          PITCHCAP 512
          NUMHEADINGS 2
          HEADING 1
            HEADINGCAP 64
            FRAME "isword.bmp"  sword11
            FRAME "isword.bmp"  sword11
          ENDHEADING 1
          HEADING 2
            HEADINGCAP 128
            FRAME "isword.bmp" sword21
            FRAME "isword.bmp"  sword11
          ENDHEADING 2
        ENDPITCH 1
        PITCH 2
          PITCHCAP 256
          NUMHEADINGS 1
          HEADING 1
            HEADINGCAP 64
            FRAME "isword.bmp"  sword11
            FRAME "isword.bmp"  sword11
          ENDHEADING 1
        ENDPITCH 2
        // Default instance: render info
        RENDERMETHOD TEXTURE3
        // RENDERINFO block is optional
        RENDERINFO
          //TWOSIDED
          PEN 52
          BRIGHTNESS 1.000
          SCALEDAMBIENT 1.000
          UVORIGIN 0.5 0.4 0.3
          UAXIS 1.0 0.22 0.33 0.44
          VAXIS 1.0 0.25 0.35 0.45
        ENDRENDERINFO
      END2DSPRITEDEF
      ```
    meta:
      bit-endian: le
    seq:
      - id: name_reference
        type: s4
        doc: |
          The name of this sprite
      - id: flags
        type: sprite_flags
      - id: num_frames
        doc: |
          The number of frames present in each heading
        type: u4
      - id: num_pitches
        type: s4
        doc: |
          The number of pitches
      - id: sprite_size_x
        type: f4
        doc: |
          Scale the sprite by this amount in the x direction?
      - id: sprite_size_y
        type: f4
        doc: |
          Scale the sprite by this amount in the y direction?
      - id: sphere_fragment
        type: s4
        doc: |
          When SPHERE or SPHERELIST is defined this references a 0x16 fragment.
          When POLYHEDRON is defined this references a 0x16 fragment.
      - id: depth_scale
        type: f4
        if: flags.has_depth_scale
      - id: center_offset_x
        type: f4
        if: flags.has_center_offset
      - id: center_offset_y
        type: f4
        if: flags.has_center_offset
      - id: bounding_radius
        type: f4
        if: flags.has_bounding_radius
      - id: current_frame
        type: u4
        if: flags.has_current_frame
      - id: sleep
        type: s4
        if: flags.has_sleep
      - id: pitches
        type: sprite_pitch(num_frames)
        repeat: expr
        repeat-expr: num_pitches
      - id: render_method
        type: render_method_attrs
      - id: renderinfo_flags
        type: render_flags
      - id: pen
        type: s4
        if: renderinfo_flags.has_pen
      - id: brightness
        type: f4
        if: renderinfo_flags.has_brightness
      - id: scaled_ambient
        type: f4
        if: renderinfo_flags.has_scaled_ambient
      - id: uv_info
        type: uv_info
        if: renderinfo_flags.has_uv_info
    types:
      render_method_attrs:
        seq:
          - id: draw_style
            type: b2
            enum: draw_style
          - id: lighting
            type: b3
            enum: lighting
          - id: shading
            type: b2
            enum: shading
          - id: texture_style
            type: b4
            enum: texture_style
          - id: unused1
            doc: These bits cause WLDCOM.EXE to crash when decompiling if set
            type: b5
          - id: unused2
            type: b15
          - id: user_defined
            type: b1
        enums:
          draw_style:
            0b00: transparent
            0b01: unknown
            0b10: wireframe
            0b11: solid
          lighting:
            0b000: zero_intensity
            0b001: unknown1
            0b010: constant
            0b011: xxxxx
            0b100: ambient
            0b101: scaled_ambient
            0b111: invalid
          shading:
            0b00: none1
            0b01: none2
            0b10: gouraud1
            0b11: gouraud2
          texture_style:
            0b0001: xxxxxxxx
            0b0010: texture1
            0b0011: transtexture1
            0b0100: texture2
            0b0101: transtexture2
            0b0110: texture3
            0b0111: xxxxxxxx
            0b1000: texture4
            0b1001: transtexture4
            0b1010: texture5
            0b1011: transtexture5
            0b1100: unknown1
            0b1101: unknown2
            0b1110: unknown3
            0b1111: xxxxx
      sprite_flags:
        seq:
          - id: has_center_offset
            type: b1
          - id: has_bounding_radius
            type: b1
          - id: has_current_frame
            type: b1
          - id: has_sleep
            type: b1
          - id: flag04
            type: b1
          - id: flag05
            type: b1
          - id: skip_frames
            type: b1
          - id: has_depth_scale
            type: b1
          - id: flag08
            type: b1
          - id: flag09
            type: b1
          - id: flag10
            type: b1
          - id: flag11
            type: b1
          - id: flag12
            type: b1
          - id: flag13
            type: b1
          - id: flag14
            type: b1
          - id: flag15
            type: b1
          - id: flag16
            type: b1
          - id: flag17
            type: b1
          - id: flag18
            type: b1
          - id: flag19
            type: b1
          - id: flag20
            type: b1
          - id: flag21
            type: b1
          - id: flag22
            type: b1
          - id: flag23
            type: b1
          - id: flag24
            type: b1
          - id: flag25
            type: b1
          - id: flag26
            type: b1
          - id: flag27
            type: b1
          - id: flag28
            type: b1
          - id: flag29
            type: b1
          - id: flag30
            type: b1
          - id: flag31
            type: b1
      sprite_pitch:
        params:
          - id: num_frames
            type: u4
        seq:
          - id: pitch_cap
            type: s4
          - id: num_headings
            type: b31
          - id: top_or_bottom_view
            type: b1
          - id: headings
            type: sprite_heading(num_frames)
            repeat: expr
            repeat-expr: num_headings
      sprite_heading:
        params:
          - id: num_frames
            type: u4
        seq:
          - id: heading_cap
            type: s4
          - id: frames
            type: u4
            repeat: expr
            repeat-expr: num_frames
      render_flags:
        seq:
          - id: has_pen
            type: b1
          - id: has_brightness
            type: b1
          - id: has_scaled_ambient
            type: b1
          - id: flag03
            type: b1
          - id: has_uv_info
            type: b1
          - id: flag05
            type: b1
          - id: flag06
            type: b1
          - id: flag07
            type: b1
          - id: flag08
            type: b1
          - id: flag09
            type: b1
          - id: flag10
            type: b1
          - id: flag11
            type: b1
          - id: flag12
            type: b1
          - id: flag13
            type: b1
          - id: flag14
            type: b1
          - id: flag15
            type: b1
          - id: flag16
            type: b1
          - id: flag17
            type: b1
          - id: flag18
            type: b1
          - id: flag19
            type: b1
          - id: flag20
            type: b1
          - id: flag21
            type: b1
          - id: flag22
            type: b1
          - id: flag23
            type: b1
          - id: flag24
            type: b1
          - id: flag25
            type: b1
          - id: flag26
            type: b1
          - id: flag27
            type: b1
          - id: flag28
            type: b1
          - id: flag29
            type: b1
          - id: flag30
            type: b1
          - id: flag31
            type: b1
      uv_info:
        seq:
          - id: uv_origin_x
            type: f4
          - id: uv_origin_y
            type: f4
          - id: uv_origin_z
            type: f4
          - id: u_axis_x
            type: f4
          - id: u_axis_y
            type: f4
          - id: u_axis_z
            type: f4
          - id: v_axis_x
            type: f4
          - id: v_axis_y
            type: f4
          - id: v_axis_z
            type: f4
    instances:
      name:
        type: string_hash_reference(name_reference)

  # Added by 3DSPRITEDEF
  # massive - the whole bsp nodes and everything.
  object_type_08:
    seq:
      - id: unk
        type: u1

  # TRACKDEFINITION
  object_type_12:
    seq:
      # TAG
      - id: name_reference
        type: s4
      # unk
      - id: flags
        type: u4
      # NUMFRAMES %d
      - id: frame_count
        type: u4
      - id: frames
        type: frame_transform
        repeat: expr
        repeat-expr: frame_count
        # TODO: handle fields added by flags
    types:
      frame_transform:
        seq:
          - id: rotate_denominator
            type: f4
          - id: rotate_x_numerator
            type: f4
          - id: rotate_y_numerator
            type: f4
          - id: rotate_z_numerator
            type: f4
          - id: shift_x_numerator
            type: f4
          - id: shift_y_numerator
            type: f4
          - id: shift_z_numerator
            type: f4
          - id: shift_denominator
            type: f4

    instances:
      name:
        type: string_hash_reference(name_reference)

  # TRACKINSTANCE
  object_type_13:
    seq:
      # TAG
      - id: name_reference
        type: s4

      - id: track_reference
        type: u4

      # bit 0 => sleep
      # bit 1 => reverse
      # bit 2 => interpolate
      - id: flags
        type: u4

      - id: sleep
        type: u4
        if: (flags & 0b1) == 1

    instances:
      name:
        type: string_hash_reference(name_reference)
      interpolate:
        value: (flags & 0b100) >> 2 == 1
      reverse:
        value: (flags & 0b10) >> 1 == 1

  # SPHERE
  object_type_16:
    seq:
      - id: name_reference
        type: s4
      - id: radius
        type: f4

  # POLYHEDRON
  object_type_18:
    seq:
      - id: tag_reference
        type: s4
      - id: definition_reference
        type: s4
      - id: polyhedron_flags
        type: polyhedron_flags
      - id: scale_factor
        type: f4
        if: polyhedron_flags.has_scale_factor
    meta:
      bit-endian: le
    types:
      polyhedron_flags:
        seq:
          - id: has_scale_factor
            type: b1
          - id: ukn
            type: b31
    instances:
      tag:
        type: string_hash_reference(tag_reference)
      definition:
        type: string_hash_reference(definition_reference)

  # SPHERELIST
  # No idea what this one is trying to do, will need to see if changing the file changes this object.
  # maybe this is the spherelist def?
  # could check mapedit for an example spherelist with more data
  object_type_1a:
    seq:
      - id: tag_reference
        type: s4
      - id: definition_reference
        type: s4
      - id: sphere_list_flags
        type: sphere_list_flags
      - id: scale_factor
        type: f4
        if: sphere_list_flags.has_scale_factor
    meta:
      bit-endian: le
    types:
      sphere_list_flags:
        seq:
          - id: has_scale_factor
            type: b1
          - id: ukn
            type: b31
    instances:
      tag:
        type: string_hash_reference(tag_reference)
      definition:
        type: string_hash_reference(definition_reference)

  # LIGHTDEFINITION
  # unable to test CURRENTFRAME or multiple frames/colors.
  object_type_1b:
    seq:
      - id: name_reference
        type: s4

      # bit 0 => CURRENTFRAME %d
      # bit 1 => SLEEP %d
      # bit 2 => LIGHTLEVELS %f
      # bit 3 => SKIPFRAMES ON
      # bit 4 and 1 => COLOR
      - id: flags
        type: s4
        # type: b16le

      # NUMFRAMES
      - id: frame_count
        type: u4
      # SLEEP %d
      - id: sleep
        type: u4
        if: (flags & 0b10) >> 1 == 1
      # LIGHTLEVELS %f
      - id: light_levels
        type: f4
        if: (flags & 0b100) >> 2 == 1
      # COLOR  %f %f %f
      - id: colors
        type: color_rgb
        repeat: expr
        repeat-expr: frame_count
        if: (flags & 0b1010) != 0 and frame_count != 0

    types:
      color_rgb:
        seq:
          - id: red
            type: f4
          - id: green
            type: f4
          - id: blue
            type: f4

    instances:
      name:
        type: string_hash_reference(name_reference)
      # SKIPFRAMES ON
      skip_frames:
        value: (flags & 0b1000) >> 3 == 1

  # LIGHT "%s"
  # unk fields were both 0 even with all the added instructions
  object_type_1c:
    seq:
      # always 0?
      - id: unk1
        type: u4
      - id: name_reference
        type: s4
      # always 0?
      - id: unk2
        type: u4
    instances:
      name:
        type: string_hash_reference(name_reference)

  # WORLDTREE
  object_type_21:
    seq:
      - id: unk
        type: u4

      # NUMWORLDNODES %d
      - id: world_node_count
        type: u4

      # WORLDNODE
      - id: world_nodes
        type: world_node
        repeat: expr
        repeat-expr: world_node_count
    types:
      world_node:
        seq:
          # NORMALABCD %f %f %f %f
          - id: normal_a
            type: f4
          - id: normal_b
            type: f4
          - id: normal_c
            type: f4
          - id: normal_d
            type: f4

          # WORLDREGIONTAG %d
          - id: region_tag
            type: u4
          # TODO: revisit with more examples and add conditions when region isn't zero

          # FRONTTREE %d
          - id: front_tree
            type: u4
            if: region_tag == 0

          # BACKTREE %d
          - id: back_tree
            type: u4
            if: region_tag == 0

  # POINTLIGHT
  object_type_28:
    seq:
      # TAG
      - id: name_reference
        type: s4
      - id: light_reference
        type: s4

      # bit 5 => STATIC
      # bit 6 => STATICINFLUENCE
      # bit 7 => NUMREGIONS and REGIONS
      - id: flags
        type: u4

      # XYZ %f, %f, %f
      - id: x
        type: f4
      - id: y
        type: f4
      - id: z
        type: f4

      # RADIUSOFINFLUENCE
      - id: radius
        type: f4

      # NUMREGIONS %d
      - id: region_count
        type: u4
        if: (flags & 0b10000000) != 0

      # REGIONS %d
      # values are offset by 1
      # REGIONS 0, 3, 5
      # becomes -1, 2, 4
      - id: regions
        type: s4
        repeat: expr
        repeat-expr: region_count
        if: (flags & 0b10000000) != 0

    instances:
      name:
        type: string_hash_reference(name_reference)
        if: name_reference != 0
      static:
        value: (flags & 0b100000) != 0
      static_influence:
        value: (flags & 0b1000000) != 0

  # # object_type_unknown:

Edit this page on GitHub Updated at Tue, Aug 1, 2023