aboutsummaryrefslogtreecommitdiff
path: root/docs/reference/nres.md
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2026-06-22 00:58:51 +0300
committerValentin Popov <valentin@popov.link>2026-06-22 00:58:51 +0300
commit78fc5f1debf1395d5df0bab7cc0dde54351205cb (patch)
treeef8f7c72a183723fcbea0b2d1fefd7c28ca7bc18 /docs/reference/nres.md
parent50c2cf4686b53ebd2b76318223096660e92305a4 (diff)
downloadfparkan-78fc5f1debf1395d5df0bab7cc0dde54351205cb.tar.xz
fparkan-78fc5f1debf1395d5df0bab7cc0dde54351205cb.zip
docs: rewrite MkDocs documentation
Diffstat (limited to 'docs/reference/nres.md')
-rw-r--r--docs/reference/nres.md61
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.