aboutsummaryrefslogtreecommitdiff
path: root/docs/reference/rsli.md
blob: a28aa1dccb1c7379cbdc8879e1b3234de8903dbc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# RsLi

`RsLi` -- библиотечный архив Iron3D с каталогом в начале файла и payloads после
него.

```text
[Header: 32 bytes]
[Entry table: entry_count * 32 bytes]
[Payloads]
[optional trailer]
```

## Header fields

```text
+0x00  char[2]  "NL"
+0x02  u8       reserved
+0x03  u8       version = 1
+0x04  i16      entry_count
+0x0E  u16      presorted_flag = 0xABBA
+0x14  u32      xor_seed
```

Остальные bytes сохраняются без нормализации.

## Entry

```c
struct RsLiEntry32 {
    char     name[12];
    uint8_t  service[4];
    int16_t  flags;
    int16_t  sort_to_original;
    uint32_t unpacked_size;
    uint32_t data_offset_raw;
    uint32_t packed_size;
};
```

Имя обычно хранится в uppercase ASCII. `sort_to_original` связывает sorted
position с исходной записью.

## Table transform

Entry table проходит обратимое потоковое XOR-преобразование. Начальное
состояние берётся из младших 16 bits `xor_seed` и продолжается через всю
таблицу, не сбрасываясь на границе записи.

## Storage methods

```text
0x000  raw block
0x020  byte transform only
0x040  LZSS
0x060  transform + LZSS
0x080  adaptive Huffman + LZSS
0x0A0  transform + adaptive Huffman + LZSS
0x100  raw Deflate
```

После любого пути должно получиться ровно `unpacked_size` bytes. Методы
`0x080` и `0x0A0` подтверждены decoder-кодом, но не живыми payload демоверсии
или обеих частей.

## Compatibility quirk

`sprites.lib::INTERF8.TEX` объявляет Deflate range на один byte дальше EOF.
Совместимый reader допускает `packed_size - 1` только для этого именованного
случая. Строгий режим сообщает `deflate_eof_plus_one`.