diff --git a/src/HexManiac.Core/Models/IDataModel.cs b/src/HexManiac.Core/Models/IDataModel.cs
index 699b0ff7..0225bfa5 100644
--- a/src/HexManiac.Core/Models/IDataModel.cs
+++ b/src/HexManiac.Core/Models/IDataModel.cs
@@ -13,6 +13,11 @@ namespace HavenSoft.HexManiac.Core.Models {
bool HasChanged(int index);
void ResetChanges();
+ ///
+ /// Used during repointing
+ ///
+ int FreeSpaceStart { get; set; }
+
new byte this[int index] { get; set; }
IReadOnlyList Arrays { get; }
IReadOnlyList Streams { get; }
@@ -76,6 +81,8 @@ namespace HavenSoft.HexManiac.Core.Models {
public BaseModel(byte[] data) => RawData = data;
+ public int FreeSpaceStart { get; set; }
+
public virtual IReadOnlyList Arrays { get; } = new List();
public virtual IReadOnlyList Streams { get; } = new List();
public virtual IReadOnlyList Anchors { get; } = new List();
diff --git a/src/HexManiac.Core/Models/PokemonModel.cs b/src/HexManiac.Core/Models/PokemonModel.cs
index 123e86ab..7006f212 100644
--- a/src/HexManiac.Core/Models/PokemonModel.cs
+++ b/src/HexManiac.Core/Models/PokemonModel.cs
@@ -58,6 +58,7 @@ namespace HavenSoft.HexManiac.Core.Models {
WriteSpriteRuns(pointersForDestination);
WriteStringRuns(pointersForDestination);
ResolveConflicts();
+ FreeSpaceStart = EarliestAllowedAnchor;
if (metadata == null) return;
@@ -88,6 +89,8 @@ namespace HavenSoft.HexManiac.Core.Models {
}
}
+ if (metadata.FreeSpaceSearch >= 0) FreeSpaceStart = metadata.FreeSpaceSearch;
+
ResolveConflicts();
}
@@ -914,6 +917,8 @@ namespace HavenSoft.HexManiac.Core.Models {
}
public override int FindFreeSpace(int start, int minimumLength) {
+ start = FreeSpaceStart;
+ if (start < EarliestAllowedAnchor) start = EarliestAllowedAnchor;
const int SpacerLength = 0x100;
minimumLength += 0x140; // make sure there's plenty of room after, so that we're not in the middle of some other data set
var runIndex = 0;
@@ -940,6 +945,7 @@ namespace HavenSoft.HexManiac.Core.Models {
// found a good spot!
// move the run
+ FreeSpaceStart = start;
return start;
}
@@ -1367,7 +1373,7 @@ namespace HavenSoft.HexManiac.Core.Models {
lists.Add(new StoredList(name, members.ToList()));
}
- return new StoredMetadata(anchors, unmappedPointers, matchedWords, lists, metadataInfo);
+ return new StoredMetadata(anchors, unmappedPointers, matchedWords, lists, metadataInfo, FreeSpaceStart);
}
///
diff --git a/src/HexManiac.Core/Models/StoredMetadata.cs b/src/HexManiac.Core/Models/StoredMetadata.cs
index 5c955479..753fb2fa 100644
--- a/src/HexManiac.Core/Models/StoredMetadata.cs
+++ b/src/HexManiac.Core/Models/StoredMetadata.cs
@@ -3,6 +3,7 @@ using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
+using System.Runtime.ExceptionServices;
namespace HavenSoft.HexManiac.Core.Models {
public class StoredMetadata {
@@ -11,15 +12,17 @@ namespace HavenSoft.HexManiac.Core.Models {
public IReadOnlyList MatchedWords { get; }
public IReadOnlyList Lists { get; }
public string Version { get; }
+ public int FreeSpaceSearch { get; } = -1;
public bool IsEmpty => NamedAnchors.Count == 0 && UnmappedPointers.Count == 0;
- public StoredMetadata(IReadOnlyList anchors, IReadOnlyList unmappedPointers, IReadOnlyList matchedWords, IReadOnlyList lists, IMetadataInfo generalInfo) {
+ public StoredMetadata(IReadOnlyList anchors, IReadOnlyList unmappedPointers, IReadOnlyList matchedWords, IReadOnlyList lists, IMetadataInfo generalInfo, int freeSpaceSearch) {
NamedAnchors = anchors ?? new List();
UnmappedPointers = unmappedPointers ?? new List();
MatchedWords = matchedWords ?? new List();
Lists = lists ?? new List();
Version = generalInfo.VersionNumber;
+ FreeSpaceSearch = freeSpaceSearch;
}
public StoredMetadata(string[] lines) {
@@ -65,6 +68,10 @@ namespace HavenSoft.HexManiac.Core.Models {
Version = cleanLine.Split("'''")[1];
}
+ if (cleanLine.StartsWith("FreeSpaceSearch = '''")) {
+ if (int.TryParse(cleanLine.Split("'''")[1], out var fss)) FreeSpaceSearch = fss;
+ }
+
if (cleanLine.Contains('=') && int.TryParse(cleanLine.Split('=')[0].Trim(), out int currentItemIndex)) {
if (currentItemChildren == null) currentItemChildren = new List();
while (currentItemChildren.Count < currentItemIndex) currentItemChildren.Add(null);
@@ -98,6 +105,7 @@ namespace HavenSoft.HexManiac.Core.Models {
"[General]"
};
if (Version != null) lines.Add($"ApplicationVersion = '''{Version}'''");
+ lines.Add($"FreeSpaceSearch = '''{FreeSpaceSearch}'''");
lines.Add(string.Empty);
lines.Add("#################################");
diff --git a/src/HexManiac.Core/ViewModels/ViewPort.cs b/src/HexManiac.Core/ViewModels/ViewPort.cs
index 6f98afd8..a92f2872 100644
--- a/src/HexManiac.Core/ViewModels/ViewPort.cs
+++ b/src/HexManiac.Core/ViewModels/ViewPort.cs
@@ -424,6 +424,14 @@ namespace HavenSoft.HexManiac.Core.ViewModels {
#endregion
+ public int FreeSpaceStart { get => Model.FreeSpaceStart; set {
+ if (Model.FreeSpaceStart != value) {
+ Model.FreeSpaceStart = value;
+ NotifyPropertyChanged();
+ }
+ }
+ }
+
private readonly ToolTray tools;
public bool HasTools => true;
public IToolTrayViewModel Tools => tools;
@@ -896,10 +904,9 @@ namespace HavenSoft.HexManiac.Core.ViewModels {
return false;
}
- var startSearch = (Model as PokemonModel)?.EarliestAllowedAnchor ?? 0;
var length = FormatRunFactory.GetStrategy(pointerSegment.InnerFormat).LengthForNewRun(Model, pointer);
- var insert = Model.FindFreeSpace(startSearch, length);
+ var insert = Model.FindFreeSpace(0, length);
if (insert < 0) {
insert = Model.Count;
Model.ExpandData(CurrentChange, Model.Count + length);
@@ -1970,6 +1977,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels {
currentView = new HexElement[Width, Height];
RequestMenuClose?.Invoke(this, EventArgs.Empty);
NotifyCollectionChanged(ResetArgs);
+ NotifyPropertyChanged(nameof(FreeSpaceStart));
}
private void RefreshBackingDataFull() {
diff --git a/src/HexManiac.WPF/Controls/TabView.xaml b/src/HexManiac.WPF/Controls/TabView.xaml
index bc53ee1e..8871ccf9 100644
--- a/src/HexManiac.WPF/Controls/TabView.xaml
+++ b/src/HexManiac.WPF/Controls/TabView.xaml
@@ -14,10 +14,14 @@
-
-
+
+
+
+
+
+