From 2dfc4b72ab3ac7a5795115d57f2a6f50643797bc Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 7 Feb 2026 08:31:49 -0800 Subject: [PATCH] Add Kaitai Struct definition for texture data files (.tex) (#1741) --- docs/README.md | 8 ++++ docs/samples/Dbfrfn.tex | Bin 0 -> 16524 bytes docs/tex.ksy | 91 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100755 docs/samples/Dbfrfn.tex create mode 100644 docs/tex.ksy diff --git a/docs/README.md b/docs/README.md index df933a8a..de0f2ffe 100644 --- a/docs/README.md +++ b/docs/README.md @@ -21,6 +21,7 @@ Kaitai Struct allows you to define binary formats in a YAML-based `.ksy` file, w | [`animation.ksy`](/docs/animation.ksy) | `.ani` | Animation data (keyframes, actor references, camera animation) | | [`wdb.ksy`](/docs/wdb.ksy) | `.wdb` | World database (textures, parts, models, ROI hierarchies, LODs) | | [`dta.ksy`](/docs/dta.ksy) | `.dta` | Animation data (world animation info, model placement) | +| [`tex.ksy`](/docs/tex.ksy) | `.tex` | Texture data (named textures with palette and pixel data) | ## Using the Tools @@ -50,6 +51,9 @@ ksv /path/to/lego/data/world.wdb wdb.ksy # View an animation data file ksv samples/BLDRINF.DTA dta.ksy + +# View a texture data file +ksv samples/Dbfrfn.tex tex.ksy ``` ### Kaitai Struct Dump (ksdump) @@ -74,6 +78,9 @@ ksdump --format yaml /path/to/lego/data/world.wdb wdb.ksy # Dump an animation data file to JSON ksdump --format json samples/BLDRINF.DTA dta.ksy + +# Dump a texture data file to JSON +ksdump --format json samples/Dbfrfn.tex tex.ksy ``` ## Sample Files @@ -84,5 +91,6 @@ The [`samples/`](/docs/samples/) directory contains example files for testing: - `History.gsi` - Sample score history data - `pns065rd.ani` - Sample animation file - `BLDRINF.DTA` - Sample animation data file +- `Dbfrfn.tex` - Sample texture data file (dune buggy front fender) Note: The world database (`world.wdb`) can be found in your LEGO Island installation at `lego/data/world.wdb`. diff --git a/docs/samples/Dbfrfn.tex b/docs/samples/Dbfrfn.tex new file mode 100755 index 0000000000000000000000000000000000000000..dcda861dd192ce07dc4c263f5ca7051168a0c81b GIT binary patch literal 16524 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 XI%a{rwErpc5ta8R-Yf8btH6H&qud2_ literal 0 HcmV?d00001 diff --git a/docs/tex.ksy b/docs/tex.ksy new file mode 100644 index 00000000..0622c30f --- /dev/null +++ b/docs/tex.ksy @@ -0,0 +1,91 @@ +meta: + id: tex + title: Texture Data File + application: LEGO Island + file-extension: tex + license: CC0-1.0 + endian: le + +doc: | + Texture data format for LEGO Island (1997). Contains one or more named + textures with 8-bit indexed color image data. + + Texture data is embedded in SI (Interleaf) container files and parsed by + LegoTexturePresenter::Read(). Each texture consists of a length-prefixed + name followed by image data with a color palette and pixel indices. + + The image format is shared with the world database (world.wdb) texture + data, using the same LegoImage and LegoPaletteEntry serialization. + + File structure: + 1. Texture count + 2. Named texture entries - name + palette + pixel data + +seq: + - id: num_textures + type: u4 + doc: Number of textures in this file. + - id: textures + type: named_texture + repeat: expr + repeat-expr: num_textures + doc: Array of named textures. + +types: + named_texture: + doc: | + A named texture with 8-bit indexed color image data. + seq: + - id: name_length + type: u4 + doc: Length of the texture name buffer in bytes. + - id: name + type: str + size: name_length + encoding: ASCII + terminator: 0 + doc: | + Texture name (e.g., "dbfrfn.gif"). The name is a null-terminated + C string within the allocated buffer. Bytes after the null + terminator are unused padding and consumed but not included + in the string value. + - id: image + type: image + doc: The texture image data. + + image: + doc: | + An 8-bit indexed color image with palette. Parsed by LegoImage::Read(). + seq: + - id: width + type: u4 + doc: Image width in pixels. + - id: height + type: u4 + doc: Image height in pixels. + - id: palette_size + type: u4 + doc: Number of entries in the color palette (max 256). + - id: palette + type: palette_entry + repeat: expr + repeat-expr: palette_size + doc: Color palette entries. + - id: pixels + size: width * height + doc: | + Pixel data as palette indices. Each byte is an index into + the palette array. + + palette_entry: + doc: RGB color palette entry. Parsed by LegoPaletteEntry::Read(). + seq: + - id: red + type: u1 + doc: Red component (0-255). + - id: green + type: u1 + doc: Green component (0-255). + - id: blue + type: u1 + doc: Blue component (0-255).