bug fixes

This commit is contained in:
haven1433
2025-11-27 17:44:39 -06:00
parent 4b4d5fce2b
commit 8d97075a46
6 changed files with 41 additions and 23 deletions

View File

@@ -7,7 +7,6 @@ using Microsoft.Scripting.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;
@@ -670,7 +669,7 @@ namespace HavenSoft.HexManiac.Core.Models.Code {
// done with script lines, now write deferred data
foreach (var deferred in deferredContent) {
deferred.WriteData(result, start);
deferred.WriteData(result, start);
}
if (updateBody != null) updateBody.StreamTypes = streamTypes;
@@ -767,7 +766,7 @@ namespace HavenSoft.HexManiac.Core.Models.Code {
// match linecode (if there is one)
if (tokens.Length > 1 && candidates.Any(candidate => candidate.LineCode.Count > 1) && tokens[1].TryParseInt(out var num)) candidates = candidates.Where(line => line.LineCode.Count < 2 || line.LineCode[1] == num).ToList();
var isAfterToken = context.Index > 0 &&
var isAfterToken = context.Index > 0 && context.Index < context.Line.Length &&
(context.Line.Length == context.Index || context.Line[context.Index] == ' ') &&
(char.IsLetterOrDigit(context.Line[context.Index - 1]) || context.Line[context.Index - 1].IsAny("_~'\"-.".ToCharArray()));
if (isAfterToken) {
@@ -971,7 +970,7 @@ namespace HavenSoft.HexManiac.Core.Models.Code {
}
public static class ScriptExtensions {
public static MacroScriptLine GetMatchingMacro(this IReadOnlyList<IScriptLine> self, int gameHash, IReadOnlyList<byte>data, int start) {
public static MacroScriptLine GetMatchingMacro(this IReadOnlyList<IScriptLine> self, int gameHash, IReadOnlyList<byte> data, int start) {
return (MacroScriptLine)self.FirstOrDefault(option => option is MacroScriptLine && option.Matches(gameHash, data, start));
}
@@ -1105,7 +1104,7 @@ namespace HavenSoft.HexManiac.Core.Models.Code {
}
}
private (int, int) ReadSpriteTemplateField(string format,string content) {
private (int, int) ReadSpriteTemplateField(string format, string content) {
content = content.Trim();
if (format.EndsWith(":") && content.TryParseInt(out var result)) return (result, 2);
if (format.EndsWith("<>") && content.Trim('<', '>').TryParseHex(out result)) return (result, 4);

View File

@@ -10,7 +10,7 @@ using System.Text;
namespace HavenSoft.HexManiac.Core.Models {
public interface ITextConverter {
List<byte> Convert(string text, out bool containsBadCharacters);
string Convert(IReadOnlyList<byte> data, int startIndex, int length);
string Convert(IReadOnlyList<byte> data, int startIndex, int length, bool includeNewlineCharacters = false);
bool AnyMacroStartsWith(string input);
/// <summary>
@@ -36,8 +36,8 @@ namespace HavenSoft.HexManiac.Core.Models {
return PCSString.Convert(text, gameCode, out containsBadCharacters);
}
public string Convert(IReadOnlyList<byte> data, int startIndex, int length) {
return PCSString.Convert(gameCode, data, startIndex, length);
public string Convert(IReadOnlyList<byte> data, int startIndex, int length, bool includeNewlineCharacters = false) {
return PCSString.Convert(gameCode, data, startIndex, length, includeNewlineCharacters);
}
public bool AnyMacroStartsWith(string input) {
@@ -138,7 +138,7 @@ namespace HavenSoft.HexManiac.Core.Models {
private static IReadOnlyDictionary<string, IReadOnlyDictionary<string, byte[]>> GetTextMacrosFromReference(string[] reference) {
var macros = new Dictionary<string, IReadOnlyDictionary<string, byte[]>>();
foreach(var game in new[] { "AXVE", "AXPE", "BPRE", "BPGE", "BPEE" }) {
foreach (var game in new[] { "AXVE", "AXPE", "BPRE", "BPGE", "BPEE" }) {
macros.Add(game, GetTextMacrosFromReference(reference, game));
}
return macros;
@@ -148,7 +148,7 @@ namespace HavenSoft.HexManiac.Core.Models {
var allIndex = new Dictionary<string, IReadOnlyList<IReadOnlyDictionary<string, byte[]>>>();
foreach (var macroKvp in allMacros) {
var index = new IReadOnlyDictionary<string, byte[]>[256];
foreach(var macro in macroKvp.Value) {
foreach (var macro in macroKvp.Value) {
var (text, bytes) = macro;
if (bytes.Length < 1) continue;
var lead = bytes[0];
@@ -240,7 +240,7 @@ namespace HavenSoft.HexManiac.Core.Models {
public static string Convert(IReadOnlyList<byte> data, int startIndex, int length) => Convert(string.Empty, data, startIndex, length);
public static string Convert(string macroSet, IReadOnlyList<byte> data, int startIndex, int length) {
public static string Convert(string macroSet, IReadOnlyList<byte> data, int startIndex, int length, bool includeNewlineCharacters = false) {
var result = new StringBuilder("\"", length * 2);
if (!TextMacrosIndex.TryGetValue(macroSet, out var textMacros)) textMacros = null;
@@ -261,13 +261,16 @@ namespace HavenSoft.HexManiac.Core.Models {
// this line optimized for maximum speed. Otherwise would like to use the Newlines array.
if (length > 1 && (currentByte == 0xFA || currentByte == 0xFB || currentByte == 0xFE)) {
if (currentByte == 0xFB) {
if (currentByte == 0xFB) { // paragraph
if (includeNewlineCharacters) result.Append("\\pn");
result.AppendLine(Environment.NewLine);
nextExpectedNewline = NewlineMode.Wrap;
} else if (currentByte == 0xFE && nextExpectedNewline == NewlineMode.Wrap) {
if (includeNewlineCharacters) result.Append("\\n");
result.AppendLine();
nextExpectedNewline = NewlineMode.Feed;
} else if (currentByte == 0xFA && nextExpectedNewline == NewlineMode.Feed) {
if (includeNewlineCharacters) result.Append("\\l");
result.AppendLine();
nextExpectedNewline = NewlineMode.Feed;
} else {
@@ -324,7 +327,7 @@ namespace HavenSoft.HexManiac.Core.Models {
bool foundMatch = false;
// check macros
if (input[index] == '[' && textMacros!=null) {
if (input[index] == '[' && textMacros != null) {
var closeMacro = input.Substring(index).IndexOf(']') + index;
if (closeMacro > index) {
var candidate = input.Substring(index, closeMacro + 1 - index);

View File

@@ -83,7 +83,7 @@ namespace HavenSoft.HexManiac.Core.Models.Runs {
protected override BaseRun Clone(SortedSpan<int> newPointerSources) => new PCSRun(model, Start, Length, newPointerSources);
public void AppendTo(IDataModel model, StringBuilder builder, int start, int length, int depth) => builder.Append(model.TextConverter.Convert(model, Start, Length));
public void AppendTo(IDataModel model, StringBuilder builder, int start, int length, int depth) => builder.Append(model.TextConverter.Convert(model, Start, Length, includeNewlineCharacters: true));
public void Clear(IDataModel model, ModelDelta changeToken, int start, int length) {
for (int i = 0; i < length; i++) {

View File

@@ -562,6 +562,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map {
}
public void GetSelectionFromTile(IPixelViewModel tileImage) {
if (tileImage is null) return;
ShowTiles = true;
var index = indexForTileImage[tileImage];
var (pal, hFlip, vFlip, tileIndex) = LzTilemapRun.ReadTileData(blocks[blockIndex], index, 2);

View File

@@ -101,7 +101,8 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map {
if (events[i].Equals(selectedEvent)) {
selectionIndex = categories[currentCategory].Count - 1;
selectedCategory = currentCategory;
};
}
;
}
// remove unused categories
@@ -225,10 +226,12 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map {
public double WidthRatio => 80.0 / PixelWidth / Math.Min(1, SpriteScale);
public double HeightRatio => 80.0 / PixelHeight / Math.Min(1, SpriteScale);
private bool showBeneath;
public bool ShowBeneath { get => showBeneath; set => Set(ref showBeneath, value, old => {
NotifyPropertiesChanged(nameof(WidthRatio), nameof(HeightRatio));
tutorials.Complete(Tutorial.SpaceBar_ShowBeneath);
} ); }
public bool ShowBeneath {
get => showBeneath; set => Set(ref showBeneath, value, old => {
NotifyPropertiesChanged(nameof(WidthRatio), nameof(HeightRatio));
tutorials.Complete(Tutorial.SpaceBar_ShowBeneath);
});
}
private MapDisplayOptions showEvents;
public MapDisplayOptions ShowEvents { get => showEvents; set => SetEnum(ref showEvents, value, old => ClearPixelCache()); }
@@ -1044,8 +1047,8 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map {
var defaultBlock = grid[1, 1] & 0x3FF;
var key = corner7.MostCommonKey(); corners[0, 0] = key != 0 ? key : defaultBlock;
key = corner9.MostCommonKey(); corners[1, 0] = key != 0 ? key : defaultBlock;
key = corner1.MostCommonKey(); corners[0, 1] = key != 0 ? key : defaultBlock;
key = corner3.MostCommonKey(); corners[1, 1] = key != 0 ? key : defaultBlock;
key = corner1.MostCommonKey(); corners[0, 1] = key != 0 ? key : defaultBlock;
key = corner3.MostCommonKey(); corners[1, 1] = key != 0 ? key : defaultBlock;
innerCornersFor9Grid = corners;
}
@@ -2242,7 +2245,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map {
var (borderWidth, borderHeight) = (borderBlockCopy.PixelWidth / 16, borderBlockCopy.PixelHeight / 16);
for (int y = 0; y < height + border.North + border.South; y++) {
for (int x = 0; x < width + border.West + border.East; x++) {
if (y < border.North || x < border.West || y >= border.North + height || x >= border.West + width) {
if ((y < border.North || x < border.West || y >= border.North + height || x >= border.West + width) && borderWidth > 0 && borderHeight > 0) {
var (xEdge, yEdge) = (x - border.West - width, y - border.North - height);
var (rightEdge, bottomEdge) = (xEdge >= 0, yEdge >= 0);
// top/left
@@ -2637,7 +2640,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map {
return MapIDToText(model, group, map);
}
public static string MapIDToText(IDataModel model, int group, int map){
public static string MapIDToText(IDataModel model, int group, int map) {
var offset = model.IsFRLG() ? 0x58 : 0;
var mapBanks = new ModelTable(model, model.GetTable(HardcodeTablesModel.MapBankTable).Start);

View File

@@ -786,6 +786,18 @@ namespace HavenSoft.HexManiac.Tests {
Assert.Equal(1, value); // matches "cde" over "abc" because it starts with "c"
}
[Fact]
public void TextContainsNewline_Copy_IncludeNewlines() {
SetFullModel(0xFF);
ViewPort.Edit("^text\"\" Line1\\nLine2");
ViewPort.SelectionStart = new(0, 0);
ViewPort.ExpandSelection(0, 0);
ViewPort.Copy.Execute(FileSystem);
Assert.Contains("\\n", FileSystem.CopyText.value);
}
private void HackTextConverter(string game) {
var converter = New.PCSConverter(game);
var property = Model.GetType().GetProperty(nameof(Model.TextConverter));