diff --git a/Runtime/PSXSceneExporter.cs b/Runtime/PSXSceneExporter.cs index e5b04a9..3fcab20 100644 --- a/Runtime/PSXSceneExporter.cs +++ b/Runtime/PSXSceneExporter.cs @@ -72,6 +72,7 @@ namespace SplashEdit.RuntimeCode List atlasOffsetPlaceholderPositions = new List(); List atlasDataOffsets = new List(); + using (BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.Create))) { // Header @@ -101,6 +102,8 @@ namespace SplashEdit.RuntimeCode writer.Write((int)rotationMatrix[2, 1]); writer.Write((int)rotationMatrix[2, 2]); + writer.Write((ushort)exporter.Mesh.Triangles.Count); + // Set up texture page attributes TPageAttr tpage = new TPageAttr(); tpage.SetPageX(exporter.Texture.TexpageX); @@ -119,7 +122,27 @@ namespace SplashEdit.RuntimeCode } tpage.SetDithering(true); writer.Write((ushort)tpage.info); - writer.Write((ushort)exporter.Mesh.Triangles.Count); + writer.Write((ushort)exporter.Texture.ClutPackingX); + writer.Write((ushort)exporter.Texture.ClutPackingY); + if (exporter.Texture.BitDepth != PSXBPP.TEX_16BIT) + { + foreach (VRAMPixel color in exporter.Texture.ColorPalette) + { + writer.Write((ushort)color.Pack()); + } + for (int i = exporter.Texture.ColorPalette.Count; i < 256; i++) + { + writer.Write((ushort)0); + } + } + else + { + for (int i = 0; i < 256; i++) + { + writer.Write((ushort)0); + } + } + // Write placeholder for mesh data offset and record its position. offsetPlaceholderPositions.Add(writer.BaseStream.Position); @@ -279,7 +302,7 @@ namespace SplashEdit.RuntimeCode void OnDrawGizmos() { Gizmos.DrawIcon(transform.position, "Packages/net.psxsplash.splashedit/Icons/PSXSceneExporter.png", true); - Vector3 sceneOrigin = new Vector3(0,0,0); + Vector3 sceneOrigin = new Vector3(0, 0, 0); Vector3 cubeSize = new Vector3(8.0f * GTEScaling, 8.0f * GTEScaling, 8.0f * GTEScaling); Gizmos.color = Color.red; Gizmos.DrawWireCube(sceneOrigin, cubeSize); diff --git a/Runtime/TexturePacker.cs b/Runtime/TexturePacker.cs index 86ed3cc..25be041 100644 --- a/Runtime/TexturePacker.cs +++ b/Runtime/TexturePacker.cs @@ -227,7 +227,7 @@ namespace SplashEdit.RuntimeCode if (IsPlacementValid(candidate)) { _allocatedCLUTs.Add(candidate); - texture.ClutPackingX = x; + texture.ClutPackingX = (ushort)(x/16); texture.ClutPackingY = y; placed = true; break; diff --git a/doc/splashbundle.md b/doc/splashbundle.md index 3c32438..d7bacf5 100644 --- a/doc/splashbundle.md +++ b/doc/splashbundle.md @@ -22,17 +22,18 @@ The metadata section is split into two parts: **Object Descriptors** and **Atlas ### 2.1 Object (Exporter) Descriptors -For each exporter, the following fields are stored sequentially: - | Offset (per entry) | Size | Type | Description | | ------------------ | -------- | ------- | -------------------------------------------------------------------- | | 0x00 | 4 | int | X coordinate (GTE-converted) | | 0x04 | 4 | int | Y coordinate (GTE-converted) | | 0x08 | 4 | int | Z coordinate (GTE-converted) | | 0x0C | 36 | int[9] | Rotation matrix (3×3, row-major order) | -| 0x30 | 2 | uint16 | Texture page attributes (encoded from page X/Y, bit depth, dithering) | -| 0x32 | 2 | uint16 | Number of triangles in the mesh | -| 0x34 | 4 | int | Mesh data offset placeholder | +| 0x30 | 2 | uint16 | Number of triangles in the mesh | +| 0x32 | 2 | uint16 | Texture page attributes (encoded from page X/Y, bit depth, dithering) | +| 0x34 | 2 | uint16 | CLUT packing X coordinate | +| 0x36 | 2 | uint16 | CLUT packing Y coordinate | +| 0x38 | 512 | uint16[256] | Color palette (filled with zeros if 16-bit textures) | +| 0x438 | 4 | int | Mesh data offset placeholder | *Each object descriptor occupies **0x38** bytes.* @@ -82,4 +83,5 @@ For each texture atlas, the raw texture data is stored as a 2D array. Before wri | ------------- | --------------------------------------------------------------------------------------------------- | | **Raw Texture Data** | The atlas data is written pixel by pixel. ---- \ No newline at end of file +--- +