Added lua exporting
This commit is contained in:
15
Editor/LuaFileAssetEditor.cs
Normal file
15
Editor/LuaFileAssetEditor.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using Splashedit.RuntimeCode;
|
||||||
|
using UnityEditor;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
[CustomEditor(typeof(LuaFile))]
|
||||||
|
public class LuaScriptAssetEditor : Editor
|
||||||
|
{
|
||||||
|
public override void OnInspectorGUI()
|
||||||
|
{
|
||||||
|
LuaFile luaScriptAsset = (LuaFile)target;
|
||||||
|
|
||||||
|
// Allow user to drag-and-drop the Lua file
|
||||||
|
luaScriptAsset.luaScript = (TextAsset)EditorGUILayout.ObjectField("Lua Script", luaScriptAsset.luaScript, typeof(TextAsset), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Editor/LuaFileAssetEditor.cs.meta
Normal file
2
Editor/LuaFileAssetEditor.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 32c0501d523345500be12e6e4214ec9d
|
||||||
17
Editor/LuaImporter.cs
Normal file
17
Editor/LuaImporter.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
using System.IO;
|
||||||
|
using UnityEditor.AssetImporters;
|
||||||
|
|
||||||
|
namespace SplashEdit.EditorCode
|
||||||
|
{
|
||||||
|
[ScriptedImporter(1, "lua")]
|
||||||
|
class LuaImporter : ScriptedImporter
|
||||||
|
{
|
||||||
|
public override void OnImportAsset(AssetImportContext ctx)
|
||||||
|
{
|
||||||
|
var asset = new TextAsset(File.ReadAllText(ctx.assetPath));
|
||||||
|
ctx.AddObjectToAsset("Text", asset);
|
||||||
|
ctx.SetMainObject(asset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Editor/LuaImporter.cs.meta
Normal file
2
Editor/LuaImporter.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d364a1392e3bccd77aca824ac471f89c
|
||||||
11
Runtime/LuaFile.cs
Normal file
11
Runtime/LuaFile.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Splashedit.RuntimeCode
|
||||||
|
{
|
||||||
|
|
||||||
|
[CreateAssetMenu(fileName = "NewLuaScript", menuName = "Lua Script", order = 1)]
|
||||||
|
public class LuaFile : ScriptableObject
|
||||||
|
{
|
||||||
|
public TextAsset luaScript;
|
||||||
|
}
|
||||||
|
}
|
||||||
2
Runtime/LuaFile.cs.meta
Normal file
2
Runtime/LuaFile.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e3b07239f3beb7a87ad987c3fedae9c1
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Splashedit.RuntimeCode;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace SplashEdit.RuntimeCode
|
namespace SplashEdit.RuntimeCode
|
||||||
@@ -7,6 +8,7 @@ namespace SplashEdit.RuntimeCode
|
|||||||
public class PSXObjectExporter : MonoBehaviour
|
public class PSXObjectExporter : MonoBehaviour
|
||||||
{
|
{
|
||||||
public PSXBPP BitDepth = PSXBPP.TEX_8BIT; // Defines the bit depth of the texture (e.g., 4BPP, 8BPP)
|
public PSXBPP BitDepth = PSXBPP.TEX_8BIT; // Defines the bit depth of the texture (e.g., 4BPP, 8BPP)
|
||||||
|
public LuaFile luaFile;
|
||||||
|
|
||||||
public List<PSXTexture2D> Textures { get; set; } = new List<PSXTexture2D>(); // Stores the converted PlayStation-style texture
|
public List<PSXTexture2D> Textures { get; set; } = new List<PSXTexture2D>(); // Stores the converted PlayStation-style texture
|
||||||
public PSXMesh Mesh { get; set; } // Stores the converted PlayStation-style mesh
|
public PSXMesh Mesh { get; set; } // Stores the converted PlayStation-style mesh
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Splashedit.RuntimeCode;
|
||||||
using UnityEditor;
|
using UnityEditor;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
@@ -83,6 +84,10 @@ namespace SplashEdit.RuntimeCode
|
|||||||
string path = EditorUtility.SaveFilePanel("Select Output File", "", "output", "bin");
|
string path = EditorUtility.SaveFilePanel("Select Output File", "", "output", "bin");
|
||||||
int totalFaces = 0;
|
int totalFaces = 0;
|
||||||
|
|
||||||
|
// Lists for lua data offsets.
|
||||||
|
List<long> luaOffsetPlaceholderPositions = new List<long>();
|
||||||
|
List<long> luaDataOffsets = new List<long>();
|
||||||
|
|
||||||
// Lists for mesh data offsets.
|
// Lists for mesh data offsets.
|
||||||
List<long> meshOffsetPlaceholderPositions = new List<long>();
|
List<long> meshOffsetPlaceholderPositions = new List<long>();
|
||||||
List<long> meshDataOffsets = new List<long>();
|
List<long> meshDataOffsets = new List<long>();
|
||||||
@@ -100,6 +105,7 @@ namespace SplashEdit.RuntimeCode
|
|||||||
List<long> navmeshDataOffsets = new List<long>();
|
List<long> navmeshDataOffsets = new List<long>();
|
||||||
|
|
||||||
int clutCount = 0;
|
int clutCount = 0;
|
||||||
|
List<LuaFile> luaFiles = new List<LuaFile>();
|
||||||
|
|
||||||
// Cluts
|
// Cluts
|
||||||
foreach (TextureAtlas atlas in _atlases)
|
foreach (TextureAtlas atlas in _atlases)
|
||||||
@@ -113,12 +119,26 @@ namespace SplashEdit.RuntimeCode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lua files
|
||||||
|
foreach (PSXObjectExporter exporter in _exporters)
|
||||||
|
{
|
||||||
|
if (exporter.luaFile != null)
|
||||||
|
{
|
||||||
|
//if not contains
|
||||||
|
if (!luaFiles.Contains(exporter.luaFile))
|
||||||
|
{
|
||||||
|
luaFiles.Add(exporter.luaFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
using (BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.Create)))
|
using (BinaryWriter writer = new BinaryWriter(File.Open(path, FileMode.Create)))
|
||||||
{
|
{
|
||||||
// Header
|
// Header
|
||||||
writer.Write('S'); // 1 byte // 1
|
writer.Write('S'); // 1 byte // 1
|
||||||
writer.Write('P'); // 1 byte // 2
|
writer.Write('P'); // 1 byte // 2
|
||||||
writer.Write((ushort)1); // 2 bytes - version // 4
|
writer.Write((ushort)1); // 2 bytes - version // 4
|
||||||
|
writer.Write((ushort)luaFiles.Count); // 2 bytes - padding // 6
|
||||||
writer.Write((ushort)_exporters.Length); // 2 bytes // 6
|
writer.Write((ushort)_exporters.Length); // 2 bytes // 6
|
||||||
writer.Write((ushort)_navmeshes.Length); // 8
|
writer.Write((ushort)_navmeshes.Length); // 8
|
||||||
writer.Write((ushort)_atlases.Length); // 2 bytes // 10
|
writer.Write((ushort)_atlases.Length); // 2 bytes // 10
|
||||||
@@ -134,6 +154,16 @@ namespace SplashEdit.RuntimeCode
|
|||||||
writer.Write((ushort)PSXTrig.ConvertCoordinateToPSX(_playerHeight, GTEScaling)); // 26
|
writer.Write((ushort)PSXTrig.ConvertCoordinateToPSX(_playerHeight, GTEScaling)); // 26
|
||||||
|
|
||||||
writer.Write((ushort)0);
|
writer.Write((ushort)0);
|
||||||
|
writer.Write((ushort)0);
|
||||||
|
|
||||||
|
// Lua file section
|
||||||
|
foreach (LuaFile luaFile in luaFiles)
|
||||||
|
{
|
||||||
|
// Write placeholder for lua file data offset and record its position.
|
||||||
|
luaOffsetPlaceholderPositions.Add(writer.BaseStream.Position);
|
||||||
|
writer.Write((int)0); // 4-byte placeholder for mesh data offset.
|
||||||
|
writer.Write((uint)luaFile.luaScript.text.Length);
|
||||||
|
}
|
||||||
|
|
||||||
// GameObject section (exporters)
|
// GameObject section (exporters)
|
||||||
foreach (PSXObjectExporter exporter in _exporters)
|
foreach (PSXObjectExporter exporter in _exporters)
|
||||||
@@ -159,7 +189,15 @@ namespace SplashEdit.RuntimeCode
|
|||||||
writer.Write((int)rotationMatrix[2, 2]);
|
writer.Write((int)rotationMatrix[2, 2]);
|
||||||
|
|
||||||
writer.Write((ushort)exporter.Mesh.Triangles.Count);
|
writer.Write((ushort)exporter.Mesh.Triangles.Count);
|
||||||
writer.Write((ushort)0);
|
if (exporter.luaFile != null)
|
||||||
|
{
|
||||||
|
int index = luaFiles.IndexOf(exporter.luaFile);
|
||||||
|
writer.Write((short)index);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
writer.Write((short)-1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Navmesh metadata section
|
// Navmesh metadata section
|
||||||
@@ -205,6 +243,17 @@ namespace SplashEdit.RuntimeCode
|
|||||||
|
|
||||||
// Start of data section
|
// Start of data section
|
||||||
|
|
||||||
|
// Lua data section: Write lua file data for each exporter.
|
||||||
|
foreach (LuaFile luaFile in luaFiles)
|
||||||
|
{
|
||||||
|
AlignToFourBytes(writer);
|
||||||
|
// Record the current offset for this lua file's data.
|
||||||
|
long luaDataOffset = writer.BaseStream.Position;
|
||||||
|
luaDataOffsets.Add(luaDataOffset);
|
||||||
|
|
||||||
|
writer.Write(luaFile.luaScript.bytes);
|
||||||
|
}
|
||||||
|
|
||||||
// Mesh data section: Write mesh data for each exporter.
|
// Mesh data section: Write mesh data for each exporter.
|
||||||
foreach (PSXObjectExporter exporter in _exporters)
|
foreach (PSXObjectExporter exporter in _exporters)
|
||||||
{
|
{
|
||||||
@@ -337,6 +386,20 @@ namespace SplashEdit.RuntimeCode
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bacfill the lua data offsets into the metadata section.
|
||||||
|
if (luaOffsetPlaceholderPositions.Count == luaDataOffsets.Count)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < luaOffsetPlaceholderPositions.Count; i++)
|
||||||
|
{
|
||||||
|
writer.Seek((int)luaOffsetPlaceholderPositions[i], SeekOrigin.Begin);
|
||||||
|
writer.Write((int)luaDataOffsets[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.LogError("Mismatch between metadata lua offset placeholders and lua data blocks!");
|
||||||
|
}
|
||||||
|
|
||||||
// Backfill the mesh data offsets into the metadata section.
|
// Backfill the mesh data offsets into the metadata section.
|
||||||
if (meshOffsetPlaceholderPositions.Count == meshDataOffsets.Count)
|
if (meshOffsetPlaceholderPositions.Count == meshDataOffsets.Count)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,24 +10,32 @@ All numeric values are stored in little‐endian format. All offsets are counted
|
|||||||
| ------ | ---- | ------ | ----------------------------------- |
|
| ------ | ---- | ------ | ----------------------------------- |
|
||||||
| 0x00 | 2 | char | `'SP'` – File magic |
|
| 0x00 | 2 | char | `'SP'` – File magic |
|
||||||
| 0x02 | 2 | uint16 | Version number |
|
| 0x02 | 2 | uint16 | Version number |
|
||||||
| 0x04 | 2 | uint16 | Number of GameObjects |
|
| 0x04 | 2 | uint16 | Number of Lua Files |
|
||||||
| 0x06 | 2 | uint16 | Number of Navmeshes |
|
| 0x06 | 2 | uint16 | Number of GameObjects |
|
||||||
| 0x08 | 2 | uint16 | Number of Texture Atlases |
|
| 0x08 | 2 | uint16 | Number of Navmeshes |
|
||||||
| 0x0A | 2 | uint16 | Number of CLUTs |
|
| 0x0A | 2 | uint16 | Number of Texture Atlases |
|
||||||
| 0x0C | 2 | uint16 | Player Start X |
|
| 0x0C | 2 | uint16 | Number of CLUTs |
|
||||||
| 0x0E | 2 | uint16 | Player Start Y |
|
| 0x0E | 2 | uint16 | Player Start X (Fixed-point) |
|
||||||
| 0x10 | 2 | uint16 | Player Start Z |
|
| 0x10 | 2 | uint16 | Player Start Y (Fixed-point) |
|
||||||
| 0x12 | 2 | uint16 | Player Rotation X |
|
| 0x12 | 2 | uint16 | Player Start Z (Fixed-point) |
|
||||||
| 0x14 | 2 | uint16 | Player Rotation Y |
|
| 0x14 | 2 | uint16 | Player Rotation X (Fixed-point) |
|
||||||
| 0x16 | 2 | uint16 | Player Rotation Z |
|
| 0x16 | 2 | uint16 | Player Rotation Y (Fixed-point) |
|
||||||
| 0x18 | 2 | uint16 | Player Height |
|
| 0x18 | 2 | uint16 | Player Rotation Z (Fixed-point) |
|
||||||
| 0x1A | 2 | uint16 | Reserved (always 0) |
|
| 0x1A | 2 | uint16 | Player Height (Fixed-point) |
|
||||||
|
| 0x1C | 4 | uint32 | Reserved (always 0) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. Metadata Section
|
## 2. Metadata Section
|
||||||
|
|
||||||
### 2.1 GameObject Descriptors (56 bytes each)
|
### 2.1 Lua File Descriptors (8 bytes each)
|
||||||
|
|
||||||
|
| Offset (per entry) | Size | Type | Description |
|
||||||
|
| ------------------ | ---- | ------ | --------------------------------- |
|
||||||
|
| 0x00 | 4 | uint32 | Lua File Data Offset |
|
||||||
|
| 0x04 | 4 | uint32 | Lua File Size |
|
||||||
|
|
||||||
|
### 2.2 GameObject Descriptors (56 bytes each)
|
||||||
|
|
||||||
| Offset (per entry) | Size | Type | Description |
|
| Offset (per entry) | Size | Type | Description |
|
||||||
| ------------------ | ---- | -------- | --------------------------------- |
|
| ------------------ | ---- | -------- | --------------------------------- |
|
||||||
@@ -37,21 +45,17 @@ All numeric values are stored in little‐endian format. All offsets are counted
|
|||||||
| 0x0C | 4 | int32 | Z position (Fixed-point) |
|
| 0x0C | 4 | int32 | Z position (Fixed-point) |
|
||||||
| 0x10 | 36 | int32[9] | 3×3 Rotation Matrix (Fixed-point) |
|
| 0x10 | 36 | int32[9] | 3×3 Rotation Matrix (Fixed-point) |
|
||||||
| 0x34 | 2 | uint16 | Triangle count |
|
| 0x34 | 2 | uint16 | Triangle count |
|
||||||
| 0x36 | 2 | int16 | Padding |
|
| 0x36 | 2 | int16 | Lua File Index (-1 if none) |
|
||||||
|
|
||||||
> Mesh data for each GameObject is located at `meshDataOffset`.
|
### 2.3 Navmesh Descriptors (8 bytes each)
|
||||||
|
|
||||||
### 2.2 Navmesh Descriptors (8 bytes each)
|
|
||||||
|
|
||||||
| Offset (per entry) | Size | Type | Description |
|
| Offset (per entry) | Size | Type | Description |
|
||||||
| ------------------ | ---- | ------ | --------------------------------- |
|
| ------------------ | ---- | ------ | --------------------------------- |
|
||||||
| 0x00 | 4 | uint32 | Navmesh Data Offset |
|
| 0x00 | 4 | uint32 | Navmesh Data Offset |
|
||||||
| 0x04 | 2 | int16 | Triangle count |
|
| 0x04 | 2 | uint16 | Triangle count |
|
||||||
| 0x06 | 2 | int16 | Padding |
|
| 0x06 | 2 | uint16 | Padding |
|
||||||
|
|
||||||
> Each triangle in a navmesh is defined by 3 `int16` vertices (6 bytes per vertex).
|
### 2.4 Texture Atlas Descriptors (12 bytes each)
|
||||||
|
|
||||||
### 2.3 Texture Atlas Descriptors (12 bytes each)
|
|
||||||
|
|
||||||
| Offset (per entry) | Size | Type | Description |
|
| Offset (per entry) | Size | Type | Description |
|
||||||
| ------------------ | ---- | ------ | -------------------------------- |
|
| ------------------ | ---- | ------ | -------------------------------- |
|
||||||
@@ -61,9 +65,7 @@ All numeric values are stored in little‐endian format. All offsets are counted
|
|||||||
| 0x08 | 2 | uint16 | Atlas Position X (VRAM origin) |
|
| 0x08 | 2 | uint16 | Atlas Position X (VRAM origin) |
|
||||||
| 0x0A | 2 | uint16 | Atlas Position Y (VRAM origin) |
|
| 0x0A | 2 | uint16 | Atlas Position Y (VRAM origin) |
|
||||||
|
|
||||||
> Pixel data is stored as `uint16[width * height]`.
|
### 2.5 CLUT Descriptors (12 bytes each)
|
||||||
|
|
||||||
### 2.4 CLUT Descriptors (12 bytes each)
|
|
||||||
|
|
||||||
| Offset (per entry) | Size | Type | Description |
|
| Offset (per entry) | Size | Type | Description |
|
||||||
| ------------------ | ---- | ------ | ----------------------------------------------------- |
|
| ------------------ | ---- | ------ | ----------------------------------------------------- |
|
||||||
@@ -73,20 +75,24 @@ All numeric values are stored in little‐endian format. All offsets are counted
|
|||||||
| 0x08 | 2 | uint16 | Palette entry count |
|
| 0x08 | 2 | uint16 | Palette entry count |
|
||||||
| 0x0A | 2 | uint16 | Padding |
|
| 0x0A | 2 | uint16 | Padding |
|
||||||
|
|
||||||
> CLUT pixel data is stored as `uint16[length]`.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3. Data Section
|
## 3. Data Section
|
||||||
|
|
||||||
### 3.1 Mesh Data Block (per GameObject)
|
### 3.1 Lua Data Block
|
||||||
|
|
||||||
|
Each Lua file is stored as raw bytes. The size of each Lua file is specified in the Lua File Descriptor.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3.2 Mesh Data Block (per GameObject)
|
||||||
|
|
||||||
Each mesh is made of triangles:
|
Each mesh is made of triangles:
|
||||||
|
|
||||||
**Triangle Layout (52 bytes):**
|
**Triangle Layout (52 bytes):**
|
||||||
|
|
||||||
| Field | Size | Description |
|
| Field | Size | Description |
|
||||||
| -------------------|------|-----------------------------------------------------|
|
| ------------------- |------|-----------------------------------------------------|
|
||||||
| Vertex v0 | 6 | x, y, z (int16) |
|
| Vertex v0 | 6 | x, y, z (int16) |
|
||||||
| Vertex v1 | 6 | x, y, z (int16) |
|
| Vertex v1 | 6 | x, y, z (int16) |
|
||||||
| Vertex v2 | 6 | x, y, z (int16) |
|
| Vertex v2 | 6 | x, y, z (int16) |
|
||||||
@@ -105,20 +111,27 @@ Each mesh is made of triangles:
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 3.2 Navmesh Data Block
|
### 3.3 Navmesh Data Block
|
||||||
|
|
||||||
Each triangle is 3 vertices (`int16` x/y/z), total 18 bytes per triangle.
|
Each triangle is 3 vertices (`int16` x/y/z), total 18 bytes per triangle.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 3.3 Texture Atlas Data Block
|
### 3.4 Texture Atlas Data Block
|
||||||
|
|
||||||
Pixel data stored as `uint16[width * height]`.
|
Pixel data stored as `uint16[width * height]`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### 3.4 CLUT Data Block
|
### 3.5 CLUT Data Block
|
||||||
|
|
||||||
Pixel data stored as `uint16[length]`.
|
Pixel data stored as `uint16[length]`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- All offsets are aligned to 4-byte boundaries.
|
||||||
|
- Fixed-point values are scaled by the `GTEScaling` factor.
|
||||||
|
- Lua file indices in GameObject descriptors are `-1` if no Lua file is associated with the object.
|
||||||
|
- Navmesh triangles are stored as raw vertex data without additional attributes.
|
||||||
Binary file not shown.
Reference in New Issue
Block a user