From 39d6cf0a5a4eb46b81d5e6b450150f2a3bfe9866 Mon Sep 17 00:00:00 2001 From: colinator27 <17358554+colinator27@users.noreply.github.com> Date: Mon, 21 Nov 2022 18:49:11 -0500 Subject: [PATCH] Fix 2022.9 issues, add load failure warning --- .../Models/UndertaleEmbeddedTexture.cs | 84 ++++++++++--------- UndertaleModLib/UndertaleChunks.cs | 2 +- .../UndertaleEmbeddedTextureEditor.xaml | 10 ++- 3 files changed, 54 insertions(+), 42 deletions(-) diff --git a/UndertaleModLib/Models/UndertaleEmbeddedTexture.cs b/UndertaleModLib/Models/UndertaleEmbeddedTexture.cs index b13767294..0dcb9c73a 100644 --- a/UndertaleModLib/Models/UndertaleEmbeddedTexture.cs +++ b/UndertaleModLib/Models/UndertaleEmbeddedTexture.cs @@ -54,9 +54,9 @@ public class UndertaleEmbeddedTexture : UndertaleNamedResource, IDisposable /// - /// Helper variable for whether or not an external texture was loaded yet. + /// Helper variable for whether or not a texture was loaded yet. /// - public bool TextureExternallyLoaded { get; set; } = false; + public bool TextureLoaded { get; set; } = false; /// /// Width of the texture. 2022.9+ only. @@ -156,6 +156,7 @@ public void UnserializeBlob(UndertaleReader reader) throw new IOException("Padding error!"); reader.ReadUndertaleObject(_textureData); + TextureLoaded = true; } /// @@ -173,21 +174,20 @@ public static void FindAllTextureInfo(UndertaleData data) } } - private static TexData _placeholderTexture = null; - private static TexData CreatePlaceholderTexture() + // 1x1 black pixel in PNG format + private static TexData _placeholderTexture = new() { - _placeholderTexture = new(); - - // Construct new PNG file that has placeholder image - // TODO: display a helpful message instead? - Bitmap image = new Bitmap(64, 64); - Graphics g = Graphics.FromImage(image); - g.Clear(Color.Black); - g.Dispose(); - - _placeholderTexture.TextureBlob = TextureWorker.GetImageBytes(image); - return _placeholderTexture; - } + TextureBlob = new byte[] + { + 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x77, 0x53, 0xDE, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, + 0x42, 0x00, 0xAE, 0xCE, 0x1C, 0xE9, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4D, 0x41, 0x00, 0x00, 0xB1, 0x8F, 0x0B, 0xFC, + 0x61, 0x05, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0E, 0xC3, 0x00, 0x00, 0x0E, 0xC3, 0x01, 0xC7, + 0x6F, 0xA8, 0x64, 0x00, 0x00, 0x00, 0x0C, 0x49, 0x44, 0x41, 0x54, 0x18, 0x57, 0x63, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x01, 0x5C, 0xCD, 0xFF, 0x69, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82 + } + }; + private static object _textureLoadLock = new(); /// /// Attempts to load the corresponding external texture. Should only happen in 2022.9 and above. @@ -195,32 +195,38 @@ private static TexData CreatePlaceholderTexture() /// public TexData LoadExternalTexture() { - TexData texData; + lock (_textureLoadLock) + { + if (TextureLoaded) + return _textureData; - if (_2022_9_GameDirectory == null) - return _placeholderTexture ?? CreatePlaceholderTexture(); + TexData texData; - // Try to find file on disk - string path = Path.Combine(_2022_9_GameDirectory, TextureInfo.Directory.Content, - TextureInfo.Name.Content + "_" + IndexInGroup.ToString() + TextureInfo.Extension.Content); - if (!File.Exists(path)) - return _placeholderTexture ?? CreatePlaceholderTexture(); + if (_2022_9_GameDirectory == null) + return _placeholderTexture; - // Load file! - try - { - using FileStream fs = new(path, FileMode.Open); - using FileBinaryReader fbr = new(fs); - texData = new TexData(); - texData.Unserialize(fbr, true); - TextureExternallyLoaded = true; - } - catch (IOException) - { - return _placeholderTexture ?? CreatePlaceholderTexture(); - } + // Try to find file on disk + string path = Path.Combine(_2022_9_GameDirectory, TextureInfo.Directory.Content, + TextureInfo.Name.Content + "_" + IndexInGroup.ToString() + TextureInfo.Extension.Content); + if (!File.Exists(path)) + return _placeholderTexture; + + // Load file! + try + { + using FileStream fs = new(path, FileMode.Open); + using FileBinaryReader fbr = new(fs); + texData = new TexData(); + texData.Unserialize(fbr, true); + TextureLoaded = true; + } + catch (IOException) + { + return _placeholderTexture; + } - return texData; + return texData; + } } /// @@ -238,7 +244,7 @@ public void Dispose() { GC.SuppressFinalize(this); - _textureData.Dispose(); + _textureData?.Dispose(); _textureData = null; Name = null; TextureInfo = null; diff --git a/UndertaleModLib/UndertaleChunks.cs b/UndertaleModLib/UndertaleChunks.cs index 5fec9573d..1463d3406 100644 --- a/UndertaleModLib/UndertaleChunks.cs +++ b/UndertaleModLib/UndertaleChunks.cs @@ -750,7 +750,7 @@ internal override void SerializeChunk(UndertaleWriter writer) bool anythingUsesQoi = false; foreach (var tex in List) { - if (tex.TextureExternal && !tex.TextureExternallyLoaded) + if (tex.TextureExternal && !tex.TextureLoaded) continue; // don't accidentally load everything... if (tex.TextureData.FormatQOI) { diff --git a/UndertaleModTool/Editors/UndertaleEmbeddedTextureEditor.xaml b/UndertaleModTool/Editors/UndertaleEmbeddedTextureEditor.xaml index 6d6e740a9..d600cb554 100644 --- a/UndertaleModTool/Editors/UndertaleEmbeddedTextureEditor.xaml +++ b/UndertaleModTool/Editors/UndertaleEmbeddedTextureEditor.xaml @@ -6,7 +6,10 @@ xmlns:local="clr-namespace:UndertaleModTool" xmlns:undertale="clr-namespace:UndertaleModLib.Models;assembly=UndertaleModLib" mc:Ignorable="d" - d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance undertale:UndertaleEmbeddedTexture}"> + d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance undertale:UndertaleEmbeddedTexture}"> + + + @@ -17,6 +20,7 @@ + Scaled @@ -34,8 +38,10 @@ + + Warning: Texture failed to load! - +