Skip to content

Commit

Permalink
Added some todo notes, update GFX parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
kk49 committed Jan 12, 2020
1 parent 4430766 commit 9a3c8c7
Show file tree
Hide file tree
Showing 9 changed files with 264 additions and 25 deletions.
43 changes: 43 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
* Handle lFSB5 extract FSB5 files?
* Handle rival images, how are the name generated

* track audio files to events, determine how translatable audio files are used
* Example file hash == 00FFFE21 file number 15604
* Mission pm_03_southcoast, 218561533 (flicka translated to english)
* ```
# Structure(0xC4AB11E3), Data Offset: 95832(0x00017658)
{
Id:
462990682 # sint32(0x192FE633), Data Offset: 95832(0x00017658)
Name:
b'mission_wb_pm_03_missionitem_04_header' (0x2c250f28) # String Hash(0xC03F64BF), Data Offset: 95836(0x0001765c)
NameShort:
b'attach_paper' (0x6907c7bc) # String Hash(0xC03F64BF), Data Offset: 95840(0x00017660)
Type:
3 # sint32(0x192FE633), Data Offset: 95844(0x00017664)
Event:
OBJID 6 0x0000ca9556052e33 (0xca9556052e33) # String Hash(0x7421FAD9), Data Offset: 95848(0x00017668)
Text:
b'mission_wb_pm_03_missionitem_04_content' (0xa6094cd9) # String Hash(0xC03F64BF), Data Offset: 95856(0x00017670)
PlayAudioEvent:
OBJID 6 0x0000189e8146ac44 (0x189e8146ac44) # String Hash(0x7421FAD9), Data Offset: 95860(0x00017674)
StopAudioEvent:
OBJID 6 0x00006f0f9f8d3f83 (0x6f0f9f8d3f83) # String Hash(0x7421FAD9), Data Offset: 95866(0x0001767a)
Enabled:
1 # uint08(0x0CA2821D), Data Offset: 95872(0x00017680)
Image:
b'' # string(0x8955583E), Data Offset: 29584(0x00007390), Info Offset: 95880(0x00017688)
Entity:
b'pm03_audio_item_01' # string(0x8955583E), Data Offset: 95992(0x000176f8), Info Offset: 95888(0x00017690)
DependenciesRequired:
# Array of sint32s(0xFB9FD4CC), Data Offset: 96(0x00000060), Info Offset: 95896(0x00017698)
[
]
DependenciesOptional:
# Array of sint32s(0xFB9FD4CC), Data Offset: 96(0x00000060), Info Offset: 95912(0x000176a8)
[
]
Persist:
1 # uint08(0x0CA2821D), Data Offset: 95928(0x000176b8)
}
```
44 changes: 30 additions & 14 deletions deca/kaitai/gfx.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,24 +141,23 @@ def __init__(self, _io, _parent=None, _root=None):
self._read()

def _read(self):
self.b1 = self._io.read_u1()
self.skip = self._io.read_bytes(self.num_bytes)
self.num_bits = self._io.read_bits_int(5)
self.x_min_raw = [None] * (self.num_bits)
for i in range(self.num_bits):
self.x_min_raw[i] = self._io.read_bits_int(1) != 0

@property
def num_bits(self):
if hasattr(self, '_m_num_bits'):
return self._m_num_bits if hasattr(self, '_m_num_bits') else None
self.x_max_raw = [None] * (self.num_bits)
for i in range(self.num_bits):
self.x_max_raw[i] = self._io.read_bits_int(1) != 0

self._m_num_bits = (self.b1 >> 3)
return self._m_num_bits if hasattr(self, '_m_num_bits') else None
self.y_min_raw = [None] * (self.num_bits)
for i in range(self.num_bits):
self.y_min_raw[i] = self._io.read_bits_int(1) != 0

@property
def num_bytes(self):
if hasattr(self, '_m_num_bytes'):
return self._m_num_bytes if hasattr(self, '_m_num_bytes') else None
self.y_max_raw = [None] * (self.num_bits)
for i in range(self.num_bits):
self.y_max_raw[i] = self._io.read_bits_int(1) != 0

self._m_num_bytes = (((self.num_bits * 4) - 3) + 7) // 8
return self._m_num_bytes if hasattr(self, '_m_num_bytes') else None


class Tag(KaitaiStruct):
Expand Down Expand Up @@ -199,6 +198,10 @@ def _read(self):
self._raw_tag_body = self._io.read_bytes(self.record_header.len)
io = KaitaiStream(BytesIO(self._raw_tag_body))
self.tag_body = self._root.ImportAssets2Body(io, self, self._root)
elif _on == self._root.TagType.define_shape3:
self._raw_tag_body = self._io.read_bytes(self.record_header.len)
io = KaitaiStream(BytesIO(self._raw_tag_body))
self.tag_body = self._root.DefineShape3Body(io, self, self._root)
elif _on == self._root.TagType.do_abc:
self._raw_tag_body = self._io.read_bytes(self.record_header.len)
io = KaitaiStream(BytesIO(self._raw_tag_body))
Expand Down Expand Up @@ -412,4 +415,17 @@ def _read(self):
self.script_timeout_seconds = self._io.read_u2le()


class DefineShape3Body(KaitaiStruct):
def __init__(self, _io, _parent=None, _root=None):
self._io = _io
self._parent = _parent
self._root = _root if _root else self
self._read()

def _read(self):
self.shape_id = self._io.read_u2le()
self.bounds = self._root.Rect(self._io, self, self._root)
self.shapes = self._io.read_bytes_full()



39 changes: 39 additions & 0 deletions deca/kaitai/var_int.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild

from pkg_resources import parse_version
from kaitaistruct import __version__ as ks_version, KaitaiStruct, KaitaiStream, BytesIO


if parse_version(ks_version) < parse_version('0.7'):
raise Exception("Incompatible Kaitai Struct Python API: 0.7 or later is required, but you have %s" % (ks_version))

class VarInt(KaitaiStruct):
"""LIMITATIONS:
Max number of bits is 32
SWF has can have integers of variable bit lengths determined at runtime. This provides support for that
"""
def __init__(self, raw, num_bits, is_signed, is_le, _io, _parent=None, _root=None):
self._io = _io
self._parent = _parent
self._root = _root if _root else self
self.raw = raw
self.num_bits = num_bits
self.is_signed = is_signed
self.is_le = is_le
self._read()

def _read(self):
self.raw = [None] * (self.num_bits)
for i in range(self.num_bits):
self.raw[i] = self._io.read_bits_int(1) != 0


@property
def value(self):
if hasattr(self, '_m_value'):
return self._m_value if hasattr(self, '_m_value') else None

self._m_value = (((((((((((((((((((((((((((((((((((1 if ((self.num_bits > 0) and (self.raw[0])) else 0) << 0) | ((1 if ((self.num_bits > 1) and (self.raw[1])) else 0) << 1)) | ((1 if ((self.num_bits > 2) and (self.raw[2])) else 0) << 2)) | ((1 if ((self.num_bits > 3) and (self.raw[3])) else 0) << 3)) | ((1 if ((self.num_bits > 4) and (self.raw[4])) else 0) << 4)) | ((1 if ((self.num_bits > 5) and (self.raw[5])) else 0) << 5)) | ((1 if ((self.num_bits > 6) and (self.raw[6])) else 0) << 6)) | ((1 if ((self.num_bits > 7) and (self.raw[7])) else 0) << 7)) | ((1 if ((self.num_bits > 8) and (self.raw[8])) else 0) << 8)) | ((1 if ((self.num_bits > 9) and (self.raw[9])) else 0) << 9)) | ((1 if ((self.num_bits > 10) and (self.raw[10])) else 0) << 10)) | ((1 if ((self.num_bits > 11) and (self.raw[11])) else 0) << 11)) | ((1 if ((self.num_bits > 12) and (self.raw[12])) else 0) << 12)) | ((1 if ((self.num_bits > 13) and (self.raw[13])) else 0) << 13)) | ((1 if ((self.num_bits > 14) and (self.raw[14])) else 0) << 14)) | ((1 if ((self.num_bits > 15) and (self.raw[15])) else 0) << 15)) | ((1 if ((self.num_bits > 16) and (self.raw[16])) else 0) << 16)) | ((1 if ((self.num_bits > 17) and (self.raw[17])) else 0) << 17)) | ((1 if ((self.num_bits > 18) and (self.raw[18])) else 0) << 18)) | ((1 if ((self.num_bits > 19) and (self.raw[19])) else 0) << 19)) | ((1 if ((self.num_bits > 20) and (self.raw[20])) else 0) << 20)) | ((1 if ((self.num_bits > 21) and (self.raw[21])) else 0) << 21)) | ((1 if ((self.num_bits > 22) and (self.raw[22])) else 0) << 22)) | ((1 if ((self.num_bits > 23) and (self.raw[23])) else 0) << 23)) | ((1 if ((self.num_bits > 24) and (self.raw[24])) else 0) << 24)) | ((1 if ((self.num_bits > 25) and (self.raw[25])) else 0) << 25)) | ((1 if ((self.num_bits > 26) and (self.raw[26])) else 0) << 26)) | ((1 if ((self.num_bits > 27) and (self.raw[27])) else 0) << 27)) | ((1 if ((self.num_bits > 28) and (self.raw[28])) else 0) << 28)) | ((1 if ((self.num_bits > 29) and (self.raw[29])) else 0) << 29)) | ((1 if ((self.num_bits > 30) and (self.raw[30])) else 0) << 30)) | ((1 if ((self.num_bits > 31) and (self.raw[31])) else 0) << 31)) | ((-1 << self.num_bits) if ((self.is_signed) and (self.raw[((self.num_bits - 1) if self.is_le else 0)])) else 0)) if self.is_le else ((((((((((((((((((((((((((((((((((1 if ((self.num_bits > 0) and (self.raw[0])) else 0) << ((self.num_bits - 1) - 0)) | ((1 if ((self.num_bits > 1) and (self.raw[1])) else 0) << ((self.num_bits - 1) - 1))) | ((1 if ((self.num_bits > 2) and (self.raw[2])) else 0) << ((self.num_bits - 1) - 2))) | ((1 if ((self.num_bits > 3) and (self.raw[3])) else 0) << ((self.num_bits - 1) - 3))) | ((1 if ((self.num_bits > 4) and (self.raw[4])) else 0) << ((self.num_bits - 1) - 4))) | ((1 if ((self.num_bits > 5) and (self.raw[5])) else 0) << ((self.num_bits - 1) - 5))) | ((1 if ((self.num_bits > 6) and (self.raw[6])) else 0) << ((self.num_bits - 1) - 6))) | ((1 if ((self.num_bits > 7) and (self.raw[7])) else 0) << ((self.num_bits - 1) - 7))) | ((1 if ((self.num_bits > 8) and (self.raw[8])) else 0) << ((self.num_bits - 1) - 8))) | ((1 if ((self.num_bits > 9) and (self.raw[9])) else 0) << ((self.num_bits - 1) - 9))) | ((1 if ((self.num_bits > 10) and (self.raw[10])) else 0) << ((self.num_bits - 1) - 10))) | ((1 if ((self.num_bits > 11) and (self.raw[11])) else 0) << ((self.num_bits - 1) - 11))) | ((1 if ((self.num_bits > 12) and (self.raw[12])) else 0) << ((self.num_bits - 1) - 12))) | ((1 if ((self.num_bits > 13) and (self.raw[13])) else 0) << ((self.num_bits - 1) - 13))) | ((1 if ((self.num_bits > 14) and (self.raw[14])) else 0) << ((self.num_bits - 1) - 14))) | ((1 if ((self.num_bits > 15) and (self.raw[15])) else 0) << ((self.num_bits - 1) - 15))) | ((1 if ((self.num_bits > 16) and (self.raw[16])) else 0) << ((self.num_bits - 1) - 16))) | ((1 if ((self.num_bits > 17) and (self.raw[17])) else 0) << ((self.num_bits - 1) - 17))) | ((1 if ((self.num_bits > 18) and (self.raw[18])) else 0) << ((self.num_bits - 1) - 18))) | ((1 if ((self.num_bits > 19) and (self.raw[19])) else 0) << ((self.num_bits - 1) - 19))) | ((1 if ((self.num_bits > 20) and (self.raw[20])) else 0) << ((self.num_bits - 1) - 20))) | ((1 if ((self.num_bits > 21) and (self.raw[21])) else 0) << ((self.num_bits - 1) - 21))) | ((1 if ((self.num_bits > 22) and (self.raw[22])) else 0) << ((self.num_bits - 1) - 22))) | ((1 if ((self.num_bits > 23) and (self.raw[23])) else 0) << ((self.num_bits - 1) - 23))) | ((1 if ((self.num_bits > 24) and (self.raw[24])) else 0) << ((self.num_bits - 1) - 24))) | ((1 if ((self.num_bits > 25) and (self.raw[25])) else 0) << ((self.num_bits - 1) - 25))) | ((1 if ((self.num_bits > 26) and (self.raw[26])) else 0) << ((self.num_bits - 1) - 26))) | ((1 if ((self.num_bits > 27) and (self.raw[27])) else 0) << ((self.num_bits - 1) - 27))) | ((1 if ((self.num_bits > 28) and (self.raw[28])) else 0) << ((self.num_bits - 1) - 28))) | ((1 if ((self.num_bits > 29) and (self.raw[29])) else 0) << ((self.num_bits - 1) - 29))) | ((1 if ((self.num_bits > 30) and (self.raw[30])) else 0) << ((self.num_bits - 1) - 30))) | ((1 if ((self.num_bits > 31) and (self.raw[31])) else 0) << ((self.num_bits - 1) - 31))) | ((-1 << self.num_bits) if ((self.is_signed) and (self.raw[((self.num_bits - 1) if self.is_le else 0)])) else 0)))
return self._m_value if hasattr(self, '_m_value') else None


5 changes: 5 additions & 0 deletions extern_tools/fsb_aud_extr/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fmodL.dll
fmod_extr.exe
fmodex.dll
fsb_aud_extr.exe
*.wav
3 changes: 3 additions & 0 deletions extern_tools/fsb_aud_extr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FSB5 and RIFF audio extraction info

https://zenhax.com/viewtopic.php?t=1901
2 changes: 1 addition & 1 deletion kaitai_struct/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
```
cd deca/deca/kaitai/
kaitai-struct-compiler -t python ../../kaitai_struct/gfx.ksy
kaitai-struct-compiler -t python --python-package deca.kaitai ../../kaitai_struct/gfx.ksy
```
55 changes: 45 additions & 10 deletions kaitai_struct/gfx.ksy
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,16 @@ meta:
wikidata: Q594447
license: CC0-1.0
endian: le
# imports:
imports:
- var_int
# - abc_bytecode

doc: |
First pass at a parser for ScaleForm GFX files.
https://help.autodesk.com/view/SCLFRM/ENU/?guid=__scaleform_help_flash_support_controltags_html
doc-ref: https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf

seq:
- id: compression
-orig-id: Signature
Expand Down Expand Up @@ -51,17 +55,36 @@ types:
type: tag
repeat: until
repeat-until: _.record_header.tag_type == tag_type::end_of_file

rect:
seq:
- id: b1
type: u1
- id: skip
size: num_bytes
instances:
num_bits:
value: b1 >> 3
num_bytes:
value: ((num_bits * 4 - 3) + 7) / 8
- id: num_bits
type: b5
- id: x_min_raw
# type: var_int(num_bits, true, false)
type: b1
repeat: expr
repeat-expr: num_bits
- id: x_max_raw
# type: var_int(num_bits, true, false)
type: b1
repeat: expr
repeat-expr: num_bits
- id: y_min_raw
# type: var_int(num_bits, true, false)
type: b1
repeat: expr
repeat-expr: num_bits
- id: y_max_raw
# type: var_int(num_bits, true, false)
type: b1
repeat: expr
repeat-expr: num_bits
# instances:
# x_min:
# value: 'x_min_raw.as<bin32>'
# value: 'var_int(x_min_raw, num_bits, true, false)'

rgb:
seq:
- id: r
Expand Down Expand Up @@ -95,6 +118,7 @@ types:
switch-on: record_header.tag_type
cases:
'tag_type::define_sound': define_sound_body
'tag_type::define_shape3': define_shape3_body
'tag_type::do_abc': do_abc_body
'tag_type::script_limits': script_limits_body
'tag_type::symbol_class': symbol_class_body
Expand All @@ -104,6 +128,7 @@ types:
'tag_type::gfx_exporter_info': gfx_exporter_info_body
'tag_type::gfx_define_external_image': gfx_define_external_image_body
'tag_type::gfx_define_external_image2': gfx_define_external_image2_body

define_sound_body:
seq:
- id: id
Expand Down Expand Up @@ -139,6 +164,16 @@ types:
channels:
0: mono
1: stereo

define_shape3_body:
seq:
- id: shape_id
type: u2
- id: bounds
type: rect
- id: shapes
size-eos: true

do_abc_body:
seq:
- id: flags
Expand Down
File renamed without changes.
98 changes: 98 additions & 0 deletions kaitai_struct/var_int.ksy
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
meta:
id: var_int
title: Variable length integer helper
license: CC0-1.0
ks-version: 0.8
doc: |
LIMITATIONS:
Max number of bits is 32
SWF has can have integers of variable bit lengths determined at runtime. This provides support for that
params:
- id: raw
- id: num_bits
type: u1
doc: Number of bits per digit. Only values of 4 and 8 are supported.
- id: is_signed
type: bool
doc: Endianness of bit array. True means signed integer, false means unsigned integer
- id: is_le
type: bool
doc: Endianness of bit array. True means little-endian, false is for big-endian.
seq:
- id: raw
type: b1
repeat: expr
repeat-expr: num_bits

instances:
value:
value: >
is_le ? (
(((num_bits > 0) and raw[ 0]) ? 1 : 0) << 0 |
(((num_bits > 1) and raw[ 1]) ? 1 : 0) << 1 |
(((num_bits > 2) and raw[ 2]) ? 1 : 0) << 2 |
(((num_bits > 3) and raw[ 3]) ? 1 : 0) << 3 |
(((num_bits > 4) and raw[ 4]) ? 1 : 0) << 4 |
(((num_bits > 5) and raw[ 5]) ? 1 : 0) << 5 |
(((num_bits > 6) and raw[ 6]) ? 1 : 0) << 6 |
(((num_bits > 7) and raw[ 7]) ? 1 : 0) << 7 |
(((num_bits > 8) and raw[ 8]) ? 1 : 0) << 8 |
(((num_bits > 9) and raw[ 9]) ? 1 : 0) << 9 |
(((num_bits > 10) and raw[10]) ? 1 : 0) << 10 |
(((num_bits > 11) and raw[11]) ? 1 : 0) << 11 |
(((num_bits > 12) and raw[12]) ? 1 : 0) << 12 |
(((num_bits > 13) and raw[13]) ? 1 : 0) << 13 |
(((num_bits > 14) and raw[14]) ? 1 : 0) << 14 |
(((num_bits > 15) and raw[15]) ? 1 : 0) << 15 |
(((num_bits > 16) and raw[16]) ? 1 : 0) << 16 |
(((num_bits > 17) and raw[17]) ? 1 : 0) << 17 |
(((num_bits > 18) and raw[18]) ? 1 : 0) << 18 |
(((num_bits > 19) and raw[19]) ? 1 : 0) << 19 |
(((num_bits > 20) and raw[20]) ? 1 : 0) << 20 |
(((num_bits > 21) and raw[21]) ? 1 : 0) << 21 |
(((num_bits > 22) and raw[22]) ? 1 : 0) << 22 |
(((num_bits > 23) and raw[23]) ? 1 : 0) << 23 |
(((num_bits > 24) and raw[24]) ? 1 : 0) << 24 |
(((num_bits > 25) and raw[25]) ? 1 : 0) << 25 |
(((num_bits > 26) and raw[26]) ? 1 : 0) << 26 |
(((num_bits > 27) and raw[27]) ? 1 : 0) << 27 |
(((num_bits > 28) and raw[28]) ? 1 : 0) << 28 |
(((num_bits > 29) and raw[29]) ? 1 : 0) << 29 |
(((num_bits > 30) and raw[30]) ? 1 : 0) << 30 |
(((num_bits > 31) and raw[31]) ? 1 : 0) << 31 |
((is_signed and raw[is_le ? (num_bits - 1) : 0]) ? (-1 << num_bits): 0)
) : (
(((num_bits > 0) and raw[ 0]) ? 1 : 0) << ((num_bits - 1) - 0) |
(((num_bits > 1) and raw[ 1]) ? 1 : 0) << ((num_bits - 1) - 1) |
(((num_bits > 2) and raw[ 2]) ? 1 : 0) << ((num_bits - 1) - 2) |
(((num_bits > 3) and raw[ 3]) ? 1 : 0) << ((num_bits - 1) - 3) |
(((num_bits > 4) and raw[ 4]) ? 1 : 0) << ((num_bits - 1) - 4) |
(((num_bits > 5) and raw[ 5]) ? 1 : 0) << ((num_bits - 1) - 5) |
(((num_bits > 6) and raw[ 6]) ? 1 : 0) << ((num_bits - 1) - 6) |
(((num_bits > 7) and raw[ 7]) ? 1 : 0) << ((num_bits - 1) - 7) |
(((num_bits > 8) and raw[ 8]) ? 1 : 0) << ((num_bits - 1) - 8) |
(((num_bits > 9) and raw[ 9]) ? 1 : 0) << ((num_bits - 1) - 9) |
(((num_bits > 10) and raw[10]) ? 1 : 0) << ((num_bits - 1) - 10) |
(((num_bits > 11) and raw[11]) ? 1 : 0) << ((num_bits - 1) - 11) |
(((num_bits > 12) and raw[12]) ? 1 : 0) << ((num_bits - 1) - 12) |
(((num_bits > 13) and raw[13]) ? 1 : 0) << ((num_bits - 1) - 13) |
(((num_bits > 14) and raw[14]) ? 1 : 0) << ((num_bits - 1) - 14) |
(((num_bits > 15) and raw[15]) ? 1 : 0) << ((num_bits - 1) - 15) |
(((num_bits > 16) and raw[16]) ? 1 : 0) << ((num_bits - 1) - 16) |
(((num_bits > 17) and raw[17]) ? 1 : 0) << ((num_bits - 1) - 17) |
(((num_bits > 18) and raw[18]) ? 1 : 0) << ((num_bits - 1) - 18) |
(((num_bits > 19) and raw[19]) ? 1 : 0) << ((num_bits - 1) - 19) |
(((num_bits > 20) and raw[20]) ? 1 : 0) << ((num_bits - 1) - 20) |
(((num_bits > 21) and raw[21]) ? 1 : 0) << ((num_bits - 1) - 21) |
(((num_bits > 22) and raw[22]) ? 1 : 0) << ((num_bits - 1) - 22) |
(((num_bits > 23) and raw[23]) ? 1 : 0) << ((num_bits - 1) - 23) |
(((num_bits > 24) and raw[24]) ? 1 : 0) << ((num_bits - 1) - 24) |
(((num_bits > 25) and raw[25]) ? 1 : 0) << ((num_bits - 1) - 25) |
(((num_bits > 26) and raw[26]) ? 1 : 0) << ((num_bits - 1) - 26) |
(((num_bits > 27) and raw[27]) ? 1 : 0) << ((num_bits - 1) - 27) |
(((num_bits > 28) and raw[28]) ? 1 : 0) << ((num_bits - 1) - 28) |
(((num_bits > 29) and raw[29]) ? 1 : 0) << ((num_bits - 1) - 29) |
(((num_bits > 30) and raw[30]) ? 1 : 0) << ((num_bits - 1) - 30) |
(((num_bits > 31) and raw[31]) ? 1 : 0) << ((num_bits - 1) - 31) |
((is_signed and raw[is_le ? (num_bits - 1) : 0]) ? (-1 << num_bits): 0)
)

0 comments on commit 9a3c8c7

Please sign in to comment.