3.3 KiB
3.3 KiB
FXID
Документ описывает контейнер ресурса эффекта и формат команд эффекта.
3.2. Контейнер ресурса эффекта
Эффекты в игровых архивах хранятся как NRes‑entries типа:
0x44495846("FXID").
Парсер эффекта находится в Effect.dll!sub_10007650.
3.3. Формат payload эффекта
3.3.1. Header (первые 60 байт)
struct FxHeader60 {
uint32_t cmdCount; // +0x00
uint32_t globalFlags; // +0x04
float durationSec; // +0x08 (дальше умножается на 1000.0)
uint32_t unk0C; // +0x0C
uint32_t flags10; // +0x10 (используются биты 0x40 и 0x400)
uint8_t reserved[0x2C];// +0x14..+0x3B
};
Поток команд начинается строго с offset 0x3C.
3.3.2. Командный поток
Каждая команда начинается с uint32 cmdWord, где:
opcode = cmdWord & 0xFF;enabled = (cmdWord >> 8) & 1(копируется вobj+4).
Размер команды зависит от opcode и прибавляется в байтах (add edi, ... в ASM):
| Opcode | Размер записи |
|---|---|
| 1 | 224 |
| 2 | 148 |
| 3 | 200 |
| 4 | 204 |
| 5 | 112 |
| 6 | 4 |
| 7 | 208 |
| 8 | 248 |
| 9 | 208 |
| 10 | 208 |
Никакого межкомандного выравнивания нет: следующая команда сразу после size(opcode).
3.4. Runtime-классы команд (vtable mapping)
В sub_10007650 для каждого opcode создаётся объект конкретного типа:
op1→off_1001E78Cop2→off_1001F048op3→off_1001E770op4→off_1001E754op5→off_1001E360op6→off_1001E738op7→off_1001E228op8→off_1001E71Cop9→off_1001E700op10→off_1001E24C
flags10 & 0x400 включает глобальный runtime-флаг менеджера эффекта (manager+0xA0).
3.5. Алгоритм загрузки эффекта (1:1)
read header60
ptr = data + 0x3C
for i in 0..cmdCount-1:
op = ptr[0] & 0xFF
obj = new CommandClass(op)
obj->enabled = (ptr[0] >> 8) & 1
obj->raw = ptr
manager.attach(obj)
ptr += sizeByOpcode(op)
Ошибка формата:
- неизвестный opcode;
- выход за пределы буфера до обработки
cmdCount; - непустой «хвост» после
cmdCountкоманд (для строгого валидатора).
3.6. Проверка на реальных данных
Для testdata/nres/effects.rlb (923 entries):
opcodeвсегда в диапазоне1..10;- stream полностью покрывает payload без хвоста;
- частоты opcode:
1: 6182: 5173: 15454: 2025: 317: 11618: 2379: 26610: 1606в этом наборе не встретился, но поддерживается парсером.