From 7ae90ec14d66603bbc8cb84c05ca4d77ef581ffc Mon Sep 17 00:00:00 2001 From: Benjamin Popp Date: Thu, 18 Feb 2021 22:54:20 -0600 Subject: [PATCH] Allow '+' on LZSpriteRun length to increase by 1 row For certain images, increasing the height is allowed. It doesn't need to be easy, just possible. * For an uncompressed image, changing the format will work to increase the size of the run. * For compressed images, allow the user to type '+' on the length to make it grow by one row. --- .../Models/Runs/Sprites/LzSpriteRun.cs | 16 ++++++++++++++++ .../ViewModels/Visitors/CompleteCellEdit.cs | 10 ++++++++++ .../ViewModels/Visitors/StartCellEdit.cs | 6 ++++++ 3 files changed, 32 insertions(+) diff --git a/src/HexManiac.Core/Models/Runs/Sprites/LzSpriteRun.cs b/src/HexManiac.Core/Models/Runs/Sprites/LzSpriteRun.cs index 97009b30..aac00321 100644 --- a/src/HexManiac.Core/Models/Runs/Sprites/LzSpriteRun.cs +++ b/src/HexManiac.Core/Models/Runs/Sprites/LzSpriteRun.cs @@ -1,5 +1,6 @@ using HavenSoft.HexManiac.Core.ViewModels.DataFormats; using HavenSoft.HexManiac.Core.ViewModels.Tools; +using System.Linq; namespace HavenSoft.HexManiac.Core.Models.Runs.Sprites { public class LzSpriteRun : PagedLZRun, ISpriteRun { @@ -88,5 +89,20 @@ namespace HavenSoft.HexManiac.Core.Models.Runs.Sprites { model.ObserveRunWritten(token, newRun); return newRun; } + + public LzSpriteRun IncreaseHeight(int tiles, ModelDelta token) { + var data = Decompress(Model, Start); + var longerData = data.Concat(new byte[SpriteFormat.ExpectedByteLength / SpriteFormat.TileHeight * tiles]).ToArray(); + var newModelData = Compress(longerData, 0, longerData.Length); + + var newRun = Model.RelocateForExpansion(token, this, newModelData.Count); + for (int i = 0; i < newModelData.Count; i++) token.ChangeData(Model, newRun.Start + i, newModelData[i]); + for (int i = newModelData.Count; i < Length; i++) token.ChangeData(Model, newRun.Start + i, 0xFF); + + var newFormat = new SpriteFormat(SpriteFormat.BitsPerPixel, SpriteFormat.TileWidth, SpriteFormat.TileHeight + tiles, SpriteFormat.PaletteHint, SpriteFormat.AllowLengthErrors); + newRun = new LzSpriteRun(newFormat, Model, newRun.Start, newRun.PointerSources); + Model.ObserveRunWritten(token, newRun); + return newRun; + } } } diff --git a/src/HexManiac.Core/ViewModels/Visitors/CompleteCellEdit.cs b/src/HexManiac.Core/ViewModels/Visitors/CompleteCellEdit.cs index 5e83e8b5..95b0382a 100644 --- a/src/HexManiac.Core/ViewModels/Visitors/CompleteCellEdit.cs +++ b/src/HexManiac.Core/ViewModels/Visitors/CompleteCellEdit.cs @@ -110,6 +110,16 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Visitors { } public void Visit(Integer integer, byte data) { + if (CurrentText == "+" && Model.GetNextRun(memoryLocation) is LzSpriteRun spriteRun) { + var newRun = spriteRun.IncreaseHeight(1, CurrentChange); + if (newRun.Start != spriteRun.Start) { + MessageText = $"Sprite was automatically moved to {newRun.Start:X6}. Pointers were updated."; + DataMoved = true; + NewDataIndex = newRun.Start + 1; + } + Result = true; + } + if (char.IsWhiteSpace(CurrentText.Last())) { CompleteIntegerEdit(integer); Result = true; diff --git a/src/HexManiac.Core/ViewModels/Visitors/StartCellEdit.cs b/src/HexManiac.Core/ViewModels/Visitors/StartCellEdit.cs index 003614bd..f2bd26da 100644 --- a/src/HexManiac.Core/ViewModels/Visitors/StartCellEdit.cs +++ b/src/HexManiac.Core/ViewModels/Visitors/StartCellEdit.cs @@ -1,5 +1,6 @@ using HavenSoft.HexManiac.Core.Models; using HavenSoft.HexManiac.Core.Models.Runs; +using HavenSoft.HexManiac.Core.Models.Runs.Sprites; using HavenSoft.HexManiac.Core.ViewModels.DataFormats; using System.Linq; using static HavenSoft.HexManiac.Core.Models.Runs.ArrayRun; @@ -140,6 +141,11 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Visitors { public void Visit(Ascii ascii, byte data) => Result = true; public void Visit(Integer intFormat, byte data) { + if (Input == '+' && Model.GetNextRun(MemoryLocation) is LzSpriteRun spriteRun && spriteRun.Start == MemoryLocation - 1 && spriteRun.Pages == 1) { + Result = true; + return; + } + if (!intFormat.CanStartWithCharacter(Input)) return; NewFormat = new UnderEdit(intFormat, Input.ToString(), intFormat.Length, null);