diff options
| author | Valentin Popov <valentin@popov.link> | 2026-06-22 00:58:51 +0300 |
|---|---|---|
| committer | Valentin Popov <valentin@popov.link> | 2026-06-22 00:58:51 +0300 |
| commit | 78fc5f1debf1395d5df0bab7cc0dde54351205cb (patch) | |
| tree | ef8f7c72a183723fcbea0b2d1fefd7c28ca7bc18 /docs/reference/nres.md | |
| parent | 50c2cf4686b53ebd2b76318223096660e92305a4 (diff) | |
| download | fparkan-78fc5f1debf1395d5df0bab7cc0dde54351205cb.tar.xz fparkan-78fc5f1debf1395d5df0bab7cc0dde54351205cb.zip | |
docs: rewrite MkDocs documentation
Diffstat (limited to 'docs/reference/nres.md')
| -rw-r--r-- | docs/reference/nres.md | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/docs/reference/nres.md b/docs/reference/nres.md new file mode 100644 index 0000000..3b8384f --- /dev/null +++ b/docs/reference/nres.md @@ -0,0 +1,61 @@ +# NRes + +`NRes` -- основной контейнер ресурсов Iron3D. Он используется как внешний +архив и как внутренний контейнер модели `*.msh`. + +```text +[Header: 16 bytes] +[Data region: payload with alignment] +[Directory: entry_count * 64 bytes] +``` + +## Header + +```c +struct NResHeader16 { + char magic[4]; // "NRes" + uint32_t version; // 0x00000100 + int32_t entry_count; // >= 0 + uint32_t total_size; // equals file size +}; +``` + +`directory_offset = total_size - entry_count * 64`. Reader проверяет отсутствие +переполнений, `directory_offset >= 16` и точное окончание каталога на +`total_size`. + +## Entry + +```c +#pragma pack(push, 1) +struct NResEntry64 { + uint32_t type_id; + uint32_t attr1; + uint32_t attr2; + uint32_t size; + uint32_t attr3; + char name[36]; + uint32_t data_offset; + uint32_t sort_index; +}; +#pragma pack(pop) +``` + +Имя содержит bounded C-string до 35 полезных bytes. `sort_index` задаёт +отображение из sorted position в original entry index. В строгом режиме все +`sort_index` образуют перестановку `0..N-1`. + +## Data region + +Payload каждой записи лежит после header и до начала каталога. Игровые архивы +выравнивают следующий payload до 8 bytes нулями, но reader не должен требовать +плотного покрытия data region. + +Различаются: + +- active payload -- диапазон, на который указывает entry; +- gap/padding -- bytes между активными диапазонами; +- unindexed preserved region -- произвольные bytes, не принадлежащие entry. + +Lossless editor сохраняет все три категории. Compact writer может исключить +unindexed regions только при явной операции repack. |
