aboutsummaryrefslogtreecommitdiff
path: root/docs/specs/fxid.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/specs/fxid.md')
-rw-r--r--docs/specs/fxid.md64
1 files changed, 32 insertions, 32 deletions
diff --git a/docs/specs/fxid.md b/docs/specs/fxid.md
index 957f95b..7dd1d4b 100644
--- a/docs/specs/fxid.md
+++ b/docs/specs/fxid.md
@@ -35,7 +35,7 @@
## 2. Контейнер и runtime API
-## 2.1. NRes entry
+### 2.1. NRes entry
FXID хранится как NRes-entry:
@@ -45,7 +45,7 @@ FXID хранится как NRes-entry:
- `attr1 = 0`, `attr2 = 0`, `attr3 = 1`.
-## 2.2. Export API `Effect.dll`
+### 2.2. Export API `Effect.dll`
Экспортируются:
@@ -54,7 +54,7 @@ FXID хранится как NRes-entry:
`CreateFxManager` создаёт manager-объект (`0xB8` байт), инициализирует через `sub_10003AE0`, возвращает интерфейсный указатель (`base + 4`).
-## 2.3. Интерфейс менеджера
+### 2.3. Интерфейс менеджера
Рабочая vtable (`off_1001E478`):
@@ -83,7 +83,7 @@ FXID хранится как NRes-entry:
Все значения little-endian.
-## 3.1. Header (60 байт, `0x3C`)
+### 3.1. Header (60 байт, `0x3C`)
```c
struct FxHeader60 {
@@ -107,7 +107,7 @@ struct FxHeader60 {
Командный поток начинается строго с `offset = 0x3C`.
-## 3.2. Header-поля (подтвержденная семантика)
+### 3.2. Header-поля (подтвержденная семантика)
- `cmd_count`: число команд (engine итерирует ровно столько шагов).
- `time_mode`: базовый режим вычисления alpha/time (`sub_10005C60`).
@@ -119,7 +119,7 @@ struct FxHeader60 {
- `pivot_*`: используется в ветках `sub_10007D10`.
- `scale_*`: копируется в runtime scale и влияет на матрицы.
-## 3.3. `flags` (битовая карта)
+### 3.3. `flags` (битовая карта)
| Бит | Маска | Наблюдаемое поведение |
|---|---:|---|
@@ -137,7 +137,7 @@ struct FxHeader60 {
Нерасшифрованные биты должны сохраняться 1:1.
-## 3.4. `time_mode` (`0..17`)
+### 3.4. `time_mode` (`0..17`)
Обозначения (`sub_10005C60`):
@@ -175,7 +175,7 @@ Post-обработка после mode:
## 4. Командный поток
-## 4.1. Общий формат команды
+### 4.1. Общий формат команды
Каждая команда:
@@ -190,7 +190,7 @@ Post-обработка после mode:
Выравнивания между командами нет.
-## 4.2. Размеры
+### 4.2. Размеры
| Opcode | Размер записи |
|---:|---:|
@@ -205,7 +205,7 @@ Post-обработка после mode:
| 9 | 208 |
| 10 | 208 |
-## 4.3. Opcode -> runtime-класс (vtable)
+### 4.3. Opcode -> runtime-класс (vtable)
| Opcode | `new(size)` | vtable |
|---:|---:|---|
@@ -220,7 +220,7 @@ Post-обработка после mode:
| 9 | `0x100` | `off_1001E700` |
| 10 | `0x48` | `off_1001E24C` |
-## 4.4. Общий вызовной контракт команды
+### 4.4. Общий вызовной контракт команды
После создания команды (`sub_10007650`):
@@ -332,7 +332,7 @@ struct ResourceRef64 {
Смещения указаны от начала команды (включая `cmd_word`).
-## 8.1. Opcode 1 (`off_1001E78C`, size=224)
+### 8.1. Opcode 1 (`off_1001E78C`, size=224)
Основные методы:
@@ -387,7 +387,7 @@ struct FxCmd01 {
- `6 -> create_kind=1, flags=0xA0000000`;
- `7 -> create_kind=1, flags=0x20000000`.
-## 8.2. Opcode 2 (`off_1001F048`, size=148)
+### 8.2. Opcode 2 (`off_1001F048`, size=148)
Основные методы:
@@ -424,7 +424,7 @@ struct FxCmd02 {
- `0 -> 0`, `1 -> 512`, `2 -> 2`, `3 -> 514`.
-## 8.3. Opcode 3 (`off_1001E770`, size=200)
+### 8.3. Opcode 3 (`off_1001E770`, size=200)
Методы:
@@ -465,7 +465,7 @@ struct FxCmd03 {
};
```
-## 8.4. Opcode 4 (`off_1001E754`, size=204)
+### 8.4. Opcode 4 (`off_1001E754`, size=204)
Layout как opcode 3 + последний коэффициент:
@@ -478,7 +478,7 @@ struct FxCmd04 {
`sub_100108C0`: `obj->inv = 1.0 / raw[200]`.
-## 8.5. Opcode 5 (`off_1001E360`, size=112)
+### 8.5. Opcode 5 (`off_1001E360`, size=112)
Методы:
@@ -508,7 +508,7 @@ struct FxCmd05 {
};
```
-## 8.6. Opcode 6 (`off_1001E738`, size=4)
+### 8.6. Opcode 6 (`off_1001E738`, size=4)
Только `cmd_word`:
@@ -520,7 +520,7 @@ struct FxCmd06 {
`init/update/emit` фактически no-op (`sub_100030B0` возвращает `0`).
-## 8.7. Opcode 7 (`off_1001E228`, size=208)
+### 8.7. Opcode 7 (`off_1001E228`, size=208)
Методы:
@@ -563,7 +563,7 @@ struct FxCmd07 {
};
```
-## 8.8. Opcode 8 (`off_1001E71C`, size=248)
+### 8.8. Opcode 8 (`off_1001E71C`, size=248)
Методы:
@@ -609,7 +609,7 @@ struct FxCmd08 {
};
```
-## 8.9. Opcode 9 (`off_1001E700`, size=208)
+### 8.9. Opcode 9 (`off_1001E700`, size=208)
Layout как opcode 3 с двумя final-полями:
@@ -626,7 +626,7 @@ struct FxCmd09 {
- init/update как у opcode 3 (`sub_100103B0`, `sub_100105F0`);
- emit: `sub_100138C0` -> формирует код рендера и вызывает `sub_100106C0`.
-## 8.10. Opcode 10 (`off_1001E24C`, size=208)
+### 8.10. Opcode 10 (`off_1001E24C`, size=208)
Body-layout совпадает с opcode 7 (`FxCmd07`), но другой runtime класс.
@@ -643,7 +643,7 @@ Body-layout совпадает с opcode 7 (`FxCmd07`), но другой runtim
## 9. Runtime-специфика по opcode (важные отличия)
-## 9.1. Opcode 1
+### 9.1. Opcode 1
- создаёт handle через manager (`vfunc +48`);
- задаёт флаги handle (`vfunc +52`);
@@ -653,30 +653,30 @@ Body-layout совпадает с opcode 7 (`FxCmd07`), но другой runtim
- 4-компонентный параметр (`vfunc +12`),
- scalar+rgb (`vfunc +16`).
-## 9.2. Opcode 2
+### 9.2. Opcode 2
- `ResourceRef64` резолвится через `sub_100065A0` (режим-зависимая загрузка, в данных обычно `sounds.lib`/`wav`);
- использует manager-команду id `910`.
-## 9.3. Opcode 3/4/9
+### 9.3. Opcode 3/4/9
- общий core-emitter в `sub_100106C0`;
- opcode 4 добавляет нормализацию по `raw+200`;
- opcode 9 добавляет переключение render-кода (`raw+200/+204`).
-## 9.4. Opcode 5
+### 9.4. Opcode 5
- держит массив внутренних сегментов (`332` байта/элемент, ctor `sub_100099F0`);
- context-matrix приходит через `vfunc +24` (`sub_10003070`).
-## 9.5. Opcode 7/10
+### 9.5. Opcode 7/10
- общий update/render (`sub_10001230`, `sub_10001300`);
- разные внутренние element-форматы:
- opcode 7: `204` байта/элемент (`sub_100092D0`),
- opcode 10: `492` байта/элемент (`sub_1000BB40`).
-## 9.6. Opcode 8
+### 9.6. Opcode 8
- самый тяжёлый спавнер, хранит ring/slot-структуры;
- emit фаза (`sub_10012030`) использует `mode`, `render_pow`, per-slot transforms.
@@ -685,7 +685,7 @@ Body-layout совпадает с opcode 7 (`FxCmd07`), но другой runtim
## 10. Спецификация инструментов
-## 10.1. Reader (strict)
+### 10.1. Reader (strict)
Алгоритм:
@@ -699,14 +699,14 @@ Body-layout совпадает с opcode 7 (`FxCmd07`), но другой runtim
- `ptr += size(opcode)`;
5. strict-tail: `ptr == len(payload)`.
-## 10.2. Reader (engine-compatible)
+### 10.2. Reader (engine-compatible)
Legacy-режим (опасный, только при необходимости byte-совместимости):
- без bounds-check;
- tolerant к unknown opcode как в оригинале.
-## 10.3. Writer (canonical)
+### 10.3. Writer (canonical)
1. записать `FxHeader60`;
2. `cmd_count = commands.len()`;
@@ -714,7 +714,7 @@ Legacy-режим (опасный, только при необходимост
4. размер payload: `0x3C + sum(size(op_i))`;
5. без хвостовых байт.
-## 10.4. Editor (lossless)
+### 10.4. Editor (lossless)
Правила:
@@ -724,7 +724,7 @@ Legacy-режим (опасный, только при необходимост
- сохранять неизвестные биты (`cmd_word`, `header.flags`) copy-through;
- для частично-известных полей поддерживать режим `opaque`.
-## 10.5. IR/JSON (рекомендуемая форма)
+### 10.5. IR/JSON (рекомендуемая форма)
```json
{