aboutsummaryrefslogtreecommitdiff
path: root/docs/specs/texture.md
diff options
context:
space:
mode:
authorValentin Popov <valentin@popov.link>2026-02-19 03:46:23 +0300
committerValentin Popov <valentin@popov.link>2026-02-19 03:46:23 +0300
commit0e19660eb5122c8c52d5e909927884ad5c50b813 (patch)
tree6a53c24544ca828f08c2b6872d568b1edc1a4cef /docs/specs/texture.md
parent8a69872576eed41a918643be52a80fe74a054974 (diff)
downloadfparkan-0e19660eb5122c8c52d5e909927884ad5c50b813.tar.xz
fparkan-0e19660eb5122c8c52d5e909927884ad5c50b813.zip
Refactor documentation structure and add new specifications
- Updated MSH documentation to reflect changes in material, wear, and texture specifications. - Introduced new `render.md` file detailing the render pipeline process. - Removed outdated sections from `runtime-pipeline.md` and redirected to `render.md`. - Added detailed specifications for `Texm` texture format and `WEAR` wear table. - Updated navigation in `mkdocs.yml` to align with new documentation structure.
Diffstat (limited to 'docs/specs/texture.md')
-rw-r--r--docs/specs/texture.md125
1 files changed, 125 insertions, 0 deletions
diff --git a/docs/specs/texture.md b/docs/specs/texture.md
new file mode 100644
index 0000000..5fa1e9d
--- /dev/null
+++ b/docs/specs/texture.md
@@ -0,0 +1,125 @@
+# Texture (`Texm`)
+
+`Texm` — основной формат текстур движка.
+
+Связанные страницы:
+
+- [Material (`MAT0`)](material.md)
+- [Wear table (`WEAR`)](wear.md)
+- [Render pipeline](render.md)
+
+## 1. Контейнер
+
+- Тип ресурса: `0x6D786554` (`Texm`).
+- Используется в `Textures.lib`, `LightMap.lib` и других `NRes` архивах.
+
+## 2. Заголовок
+
+```c
+struct TexmHeader32 {
+ uint32_t magic; // 'Texm'
+ uint32_t width;
+ uint32_t height;
+ uint32_t mipCount;
+ uint32_t flags4;
+ uint32_t flags5;
+ uint32_t unk6;
+ uint32_t format;
+};
+```
+
+## 3. Поддерживаемые форматы
+
+Базовые форматы:
+
+- `0` (8-bit indexed + palette)
+- `565`
+- `4444`
+- `888`
+- `8888`
+
+Дополнительные ветки загрузки поддерживают также `556` и `88`.
+
+## 4. Layout payload
+
+1. `TexmHeader32` (32 байта)
+2. palette `1024` байта, если `format == 0`
+3. mip-chain пикселей
+4. optional `Page` chunk
+
+Расчёт ядра:
+
+```c
+bytesPerPixel =
+ (format == 0) ? 1 :
+ (format == 565 || format == 556 || format == 4444 || format == 88) ? 2 :
+ 4;
+
+pixelCount = sum(max(1, width>>i) * max(1, height>>i), i=0..mipCount-1);
+sizeCore = 32 + (format==0 ? 1024 : 0) + bytesPerPixel * pixelCount;
+```
+
+## 5. `Page` chunk
+
+```c
+struct PageChunk {
+ uint32_t magic; // 'Page'
+ uint32_t rectCount;
+ Rect16 rects[rectCount];
+};
+
+struct Rect16 {
+ int16_t x;
+ int16_t w;
+ int16_t y;
+ int16_t h;
+};
+```
+
+`Page` задаёт atlas-прямоугольники для выборки под-областей текстуры.
+
+## 6. Mip-skip политика
+
+Загрузчик может пропускать первые mip-уровни в зависимости от:
+
+- `flags5`,
+- размеров текстуры,
+- количества mip.
+
+После `mipSkip`:
+
+- уменьшаются `width/height/mipCount`;
+- сдвигается начало пиксельных данных;
+- `Page`-координаты пересчитываются в соответствии с новым базовым уровнем.
+
+## 7. Палитры
+
+Для части текстур движок связывает палитру по суффиксу имени.
+
+Практический формат:
+
+- буква `A..Z` + вариант `""` или `0..9`
+- всего `26 * 11 = 286` возможных слотов палитр.
+
+Невалидные суффиксы нужно считать ошибкой входных данных в инструментах.
+
+## 8. Кэширование
+
+Движок ведёт отдельные кэши:
+
+- общий texture cache;
+- lightmap cache.
+
+Для обычных текстур используется отложенный сбор неиспользуемых слотов (по времени нулевого refcount).
+
+## 9. Правила writer/editor
+
+1. Не нормализовать `flags4/flags5/unk6`.
+2. Сохранять payload без лишних хвостовых байт.
+3. Если есть `Page`, его размер должен быть ровно `8 + rectCount * 8`.
+4. Проверять `width > 0`, `height > 0`, `mipCount > 0`.
+
+## 10. Статус валидации
+
+- Инварианты `Texm` реализованы в `tools/msh_doc_validator.py`.
+- В текущем окружении нет полного игрового набора текстур в `testdata`, поэтому массовая перепроверка не запускалась.