diff --git a/Editor/Core/SplashControlPanel.cs b/Editor/Core/SplashControlPanel.cs index 2825e8f..677ce82 100644 --- a/Editor/Core/SplashControlPanel.cs +++ b/Editor/Core/SplashControlPanel.cs @@ -547,7 +547,7 @@ private void DrawToolchainSection() GUILayout.FlexibleSpace(); if (_hasPsxavenc) { - PSXEditorStyles.DrawStatusBadge("Installed", PSXEditorStyles.Success); + PSXEditorStyles.DrawStatusBadge("Ready", PSXEditorStyles.Success); } else if (!_hasPsxavencDeps && Application.platform == RuntimePlatform.OSXEditor) { @@ -581,7 +581,7 @@ private void DrawToolchainSection() } else { - PSXEditorStyles.DrawStatusBadge("Installed", PSXEditorStyles.Success); + PSXEditorStyles.DrawStatusBadge("Ready", PSXEditorStyles.Success); } EditorGUILayout.EndHorizontal(); @@ -2656,7 +2656,7 @@ private void RefreshToolchainStatus() string reduxBin = SplashSettings.PCSXReduxPath; _hasRedux = !string.IsNullOrEmpty(reduxBin) && File.Exists(reduxBin); - _reduxVersion = _hasRedux ? "Installed" : ""; + _reduxVersion = _hasRedux ? "Ready" : ""; _hasPsxavenc = PSXAudioConverter.IsInstalled(); diff --git a/Editor/PSXTilemapPreview.cs b/Editor/PSXTilemapPreview.cs index 440d008..4bf9200 100644 --- a/Editor/PSXTilemapPreview.cs +++ b/Editor/PSXTilemapPreview.cs @@ -50,9 +50,18 @@ private class Entry public Mesh Mesh; public int Hash; public Texture2D Texture; + +#if UNITY_6000_4_OR_NEWER + public EntityId TilesetEntityId; +#endif + } +#if UNITY_6000_4_OR_NEWER + private static readonly Dictionary s_cache = new Dictionary(); +#else private static readonly Dictionary s_cache = new Dictionary(); +#endif private static Material s_material; /// Throw away every cached mesh (the painter calls this). @@ -80,7 +89,40 @@ private static Material PreviewMaterial() s_material = new Material(shader) { hideFlags = HideFlags.HideAndDontSave }; return s_material; } +#if UNITY_6000_4_OR_NEWER + private static int ContentHash(PSXTilemap map) + { + unchecked + { + int h = 17; + h = h * 31 + map.Width; + h = h * 31 + map.Height; + h = h * 31 + (map.Tileset != null ? map.Tileset.CellWidth * 397 + map.Tileset.CellHeight : 0); + foreach (var b in map.Brushes) h = h * 31 + b.tilesetCell * 7 + (b.walkable ? 1 : 0); + for (int y = 0; y < map.Height; y++) + for (int x = 0; x < map.Width; x++) + h = h * 31 + map.GetCell(x, y); + return h; + } + } + + /// The cached world-space mesh for a map, rebuilt when it changes. + public static Mesh MeshFor(PSXTilemap map) + { + if (map == null || map.Tileset == null || map.Tileset.SourceTexture == null) return null; + EntityId key = map.GetEntityId(); + EntityId tilesetEntityId = map.Tileset.GetEntityId(); + int hash = ContentHash(map); + if (s_cache.TryGetValue(key, out Entry e) && e.Mesh != null && e.Hash == hash && e.TilesetEntityId == tilesetEntityId) + return e.Mesh; + + if (e != null && e.Mesh != null) Object.DestroyImmediate(e.Mesh); + e = new Entry { Hash = hash, Texture = map.Tileset.SourceTexture, Mesh = BuildMesh(map), TilesetEntityId = tilesetEntityId }; + s_cache[key] = e; + return e.Mesh; + } +#else private static int ContentHash(PSXTilemap map) { unchecked @@ -113,7 +155,7 @@ public static Mesh MeshFor(PSXTilemap map) s_cache[key] = e; return e.Mesh; } - +#endif private static Mesh BuildMesh(PSXTilemap map) { PSXSpriteSheet set = map.Tileset; diff --git a/Editor/Timeline/PSXTimelineWindow.cs b/Editor/Timeline/PSXTimelineWindow.cs index b52dadf..b254ae1 100644 --- a/Editor/Timeline/PSXTimelineWindow.cs +++ b/Editor/Timeline/PSXTimelineWindow.cs @@ -41,6 +41,19 @@ public static void Open(ScriptableObject clip) window.Focus(); } +#if UNITY_6000_4_OR_NEWER + [OnOpenAsset] + public static bool OnOpenAsset(EntityId instanceID, int line) + { + var obj = EditorUtility.EntityIdToObject(instanceID); + if (obj is PSXAnimationClip || obj is PSXCutsceneClip) + { + Open((ScriptableObject)obj); + return true; + } + return false; + } +#else [OnOpenAsset] public static bool OnOpenAsset(int instanceID, int line) { @@ -52,6 +65,7 @@ public static bool OnOpenAsset(int instanceID, int line) } return false; } +#endif private void OnEnable() { diff --git a/README.md b/README.md index 8482093..95ac1a0 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ See the [installation guide](https://psxsplash.github.io/docs/getting-started/in ## Contributing -This has been a one-person project and it has grown over my head. Pull requests are very welcome. See the [contributing guide](https://psxsplash.github.io/docs/reference/contributing/) for areas where help is needed. +This has been a one-person project and it has grown over my head. Pull requests are very welcome. See the [contributing guide](https://psxsplash.github.io/docs/latest/reference/contributing/) for areas where help is needed. If you build something with SplashEdit, please share it on [PSX.Dev](https://psx.dev) or the Bandwidth Discord server! diff --git a/RFC.md.meta b/RFC.md.meta deleted file mode 100644 index 978adf4..0000000 --- a/RFC.md.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: d4e353987b434e8ab73e3aa6f0c737ab -TextScriptImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Runtime/PSXObjectExporter.cs b/Runtime/PSXObjectExporter.cs index 0708201..f29e21d 100644 --- a/Runtime/PSXObjectExporter.cs +++ b/Runtime/PSXObjectExporter.cs @@ -27,7 +27,7 @@ public class PSXObjectExporter : MonoBehaviour, IPSXExportable public LuaFile LuaFile => luaFile; [FormerlySerializedAs("IsActive")] - [SerializeField] private bool isActive = true; + [SerializeField] private bool isActive = true; public bool IsActive => isActive; public List Textures { get; set; } = new List(); @@ -58,7 +58,11 @@ public class PSXObjectExporter : MonoBehaviour, IPSXExportable public bool IsPlatform => isPlatform; public int UVOffsetMaterial => uvOffsetMaterial; +#if UNITY_6000_4_OR_NEWER + private readonly Dictionary<(EntityId, PSXBPP), PSXTexture2D> cache = new(); +#else private readonly Dictionary<(int, PSXBPP), PSXTexture2D> cache = new(); +#endif public void CreatePSXTextures2D() { @@ -78,7 +82,11 @@ public void CreatePSXTextures2D() if (tex2D == null) continue; +#if UNITY_6000_4_OR_NEWER + if (cache.TryGetValue((tex2D.GetEntityId(), bitDepth), out var cached)) +#else if (cache.TryGetValue((tex2D.GetInstanceID(), bitDepth), out var cached)) +#endif { Textures.Add(cached); } @@ -86,7 +94,11 @@ public void CreatePSXTextures2D() { var tex = PSXTexture2D.CreateFromTexture2D(tex2D, bitDepth); tex.OriginalTexture = tex2D; +#if UNITY_6000_4_OR_NEWER + cache.Add((tex2D.GetEntityId(), bitDepth), tex); +#else cache.Add((tex2D.GetInstanceID(), bitDepth), tex); +#endif Textures.Add(tex); } } diff --git a/Runtime/TexturePacker.cs b/Runtime/TexturePacker.cs index 6079a4a..ac690ae 100644 --- a/Runtime/TexturePacker.cs +++ b/Runtime/TexturePacker.cs @@ -87,7 +87,11 @@ public VRAMPacker(List framebuffers, List reservedAreas) List uniqueTextures = new List(); // Cutout is part of the key: the same source quantized with and without it // gives different pixels, so the two must not be merged. +#if UNITY_6000_4_OR_NEWER + Dictionary<(EntityId, PSXBPP, bool), int> textureToIndexMap = new Dictionary<(EntityId, PSXBPP, bool), int>(); +#else Dictionary<(int, PSXBPP, bool), int> textureToIndexMap = new Dictionary<(int, PSXBPP, bool), int>(); +#endif // Track duplicates so we can propagate packing data after placement List<(PSXTexture2D duplicate, int uniqueIndex)> duplicates = new List<(PSXTexture2D, int)>(); @@ -115,8 +119,11 @@ public VRAMPacker(List framebuffers, List reservedAreas) // Process each texture in descending order of area. foreach (var texture in group.OrderByDescending(tex => tex.QuantizedWidth * tex.Height)) { +#if UNITY_6000_4_OR_NEWER + var textureKey = (texture.OriginalTexture.GetEntityId(), texture.BitDepth, texture.Cutout); +#else var textureKey = (texture.OriginalTexture.GetInstanceID(), texture.BitDepth, texture.Cutout); - +#endif // Check if we've already processed this texture if (textureToIndexMap.TryGetValue(textureKey, out int existingIndex)) { @@ -154,7 +161,11 @@ public VRAMPacker(List framebuffers, List reservedAreas) for (int i = 0; i < obj.Textures.Count; i++) { +#if UNITY_6000_4_OR_NEWER + var textureKey = (obj.Textures[i].OriginalTexture.GetEntityId(), obj.Textures[i].BitDepth, obj.Textures[i].Cutout); +#else var textureKey = (obj.Textures[i].OriginalTexture.GetInstanceID(), obj.Textures[i].BitDepth, obj.Textures[i].Cutout); +#endif if (textureToIndexMap.TryGetValue(textureKey, out int newIndex)) { oldToNewIndexMap[i] = newIndex;