From d3d2422ec027b078d6b576a9d2005ea8f1570583 Mon Sep 17 00:00:00 2001 From: haven1433 Date: Tue, 1 Nov 2022 23:36:40 -0500 Subject: [PATCH] fix decap algorithm Now works right for capital letters that come after escape bytes also fix random crash in ModelTable string recognition also fi random assert from adding an anchor to a pointer --- src/HexManiac.Core/Models/ModelTable.cs | 1 + src/HexManiac.Core/Models/PokemonModel.cs | 6 ++++ .../ViewModels/QuickEditItems/DecapNames.cs | 28 +++++++++++-------- .../Before_Baseclass/PointerModelTests.cs | 10 +++++++ 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/HexManiac.Core/Models/ModelTable.cs b/src/HexManiac.Core/Models/ModelTable.cs index 4357282a..45981c9f 100644 --- a/src/HexManiac.Core/Models/ModelTable.cs +++ b/src/HexManiac.Core/Models/ModelTable.cs @@ -87,6 +87,7 @@ namespace HavenSoft.HexManiac.Core.Models { valueAddress = model.ReadPointer(valueAddress); if (valueAddress < 0 || valueAddress >= model.Count) return string.Empty; var length = PCSString.ReadString(model, valueAddress, true); + if (length < 1) return string.Empty; return model.TextConverter.Convert(model, valueAddress, length).Trim('"'); } else { throw new NotImplementedException(); diff --git a/src/HexManiac.Core/Models/PokemonModel.cs b/src/HexManiac.Core/Models/PokemonModel.cs index 07591eac..66d74b8e 100644 --- a/src/HexManiac.Core/Models/PokemonModel.cs +++ b/src/HexManiac.Core/Models/PokemonModel.cs @@ -1071,6 +1071,12 @@ namespace HavenSoft.HexManiac.Core.Models { changeToken.RemoveRun(runs[index]); RemoveIndex(index); } + if (run is PointerRun && run.PointerSources != null && run.PointerSources.Count == 0 && !anchorForAddress.ContainsKey(run.Start)) { + // this run contains useful information, but no useful anchors. Remove the pointer sources. + run = run.Duplicate(run.Start, null); + changeToken.AddRun(run); + SetIndex(index, run); + } if (existingRun is ArrayRun arrayRun2 && arrayRun2.SupportsInnerPointers && arrayRun2.Length > run.Length) { for (int i = 0; i < arrayRun2.ElementCount; i++) { diff --git a/src/HexManiac.Core/ViewModels/QuickEditItems/DecapNames.cs b/src/HexManiac.Core/ViewModels/QuickEditItems/DecapNames.cs index a07c131d..bd5c3f59 100644 --- a/src/HexManiac.Core/ViewModels/QuickEditItems/DecapNames.cs +++ b/src/HexManiac.Core/ViewModels/QuickEditItems/DecapNames.cs @@ -125,21 +125,27 @@ namespace HavenSoft.HexManiac.Core.ViewModels.QuickEditItems { if (address < 0 || address >= model.Count) return; var textLength = PCSString.ReadString(model, address, true); if (textLength < 3) return; - var text = model.TextConverter.Convert(model, address, textLength).ToCharArray(); - for (int i = 1; i < text.Length; i++) { - if (IsLetter(text[i - 1]) && IsCap(text[i])) { - text[i] += (char)('a' - 'A'); + var (_A, _a) = (0xBB, 0xD5); + var run = new PCSRun(model, address, textLength); + if (address == 0x245F01) ; + bool previousIsCap = run.CreateDataFormat(model, address) is PCS pcs0 && IsCap(pcs0.ThisCharacter); + for (int i = 1; i < textLength; i++) { + if (run.CreateDataFormat(model, address + i) is not PCS pcs) { + previousIsCap = false; + continue; } + var isCap = IsCap(pcs.ThisCharacter); + if (previousIsCap && isCap) { + token.ChangeData(model, address + i, (byte)(model[address + i] - _A + _a)); + } + previousIsCap = isCap; } - token.ChangeData(model, address, model.TextConverter.Convert(new string(text), out var _)); } - private bool IsLetter(char c) { - return char.IsLetter(c); - } - - private bool IsCap(char c) { - return 'A' <= c && c <= 'Z'; + private bool IsCap(string c) { + if (c.StartsWith("\"")) c = c.Substring(1); + if (c.Length != 1) return false; + return 'A' <= c[0] && c[0] <= 'Z'; } } } diff --git a/src/HexManiac.Tests/Before_Baseclass/PointerModelTests.cs b/src/HexManiac.Tests/Before_Baseclass/PointerModelTests.cs index 07909b2f..b2894e31 100644 --- a/src/HexManiac.Tests/Before_Baseclass/PointerModelTests.cs +++ b/src/HexManiac.Tests/Before_Baseclass/PointerModelTests.cs @@ -970,6 +970,16 @@ namespace HavenSoft.HexManiac.Tests { Assert.IsType(p2); } + [Fact] + public void PointerToLocation_AddAnchorToPointer_NoError() { + ViewPort.Edit("<100> "); + + ViewPort.Edit("@000 ^ "); + + Assert.Null(Model.GetNextRun(0).PointerSources); + Assert.Empty(Errors); + } + private void StandardSetup(out byte[] data, out PokemonModel model, out ViewPort viewPort) { data = new byte[0x200]; model = new PokemonModel(data);