mirror of
https://github.com/haven1433/HexManiacAdvance.git
synced 2026-05-27 18:42:45 -05:00
Add Free Space selector
Reasonable use case: user has multiple tools, some that can work with an expanded rom and some that cannot. They want to save what freespace they have below 1000000 for the weaker tools. So HMA needs to be able to put new data into a user-specified freespace (still being safe, of course).
This commit is contained in:
parent
0b3900bba5
commit
7b0c9f06e8
|
|
@ -13,6 +13,11 @@ namespace HavenSoft.HexManiac.Core.Models {
|
|||
bool HasChanged(int index);
|
||||
void ResetChanges();
|
||||
|
||||
/// <summary>
|
||||
/// Used during repointing
|
||||
/// </summary>
|
||||
int FreeSpaceStart { get; set; }
|
||||
|
||||
new byte this[int index] { get; set; }
|
||||
IReadOnlyList<ArrayRun> Arrays { get; }
|
||||
IReadOnlyList<IStreamRun> 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<ArrayRun> Arrays { get; } = new List<ArrayRun>();
|
||||
public virtual IReadOnlyList<IStreamRun> Streams { get; } = new List<IStreamRun>();
|
||||
public virtual IReadOnlyList<string> Anchors { get; } = new List<string>();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -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<StoredMatchedWord> MatchedWords { get; }
|
||||
public IReadOnlyList<StoredList> Lists { get; }
|
||||
public string Version { get; }
|
||||
public int FreeSpaceSearch { get; } = -1;
|
||||
|
||||
public bool IsEmpty => NamedAnchors.Count == 0 && UnmappedPointers.Count == 0;
|
||||
|
||||
public StoredMetadata(IReadOnlyList<StoredAnchor> anchors, IReadOnlyList<StoredUnmappedPointer> unmappedPointers, IReadOnlyList<StoredMatchedWord> matchedWords, IReadOnlyList<StoredList> lists, IMetadataInfo generalInfo) {
|
||||
public StoredMetadata(IReadOnlyList<StoredAnchor> anchors, IReadOnlyList<StoredUnmappedPointer> unmappedPointers, IReadOnlyList<StoredMatchedWord> matchedWords, IReadOnlyList<StoredList> lists, IMetadataInfo generalInfo, int freeSpaceSearch) {
|
||||
NamedAnchors = anchors ?? new List<StoredAnchor>();
|
||||
UnmappedPointers = unmappedPointers ?? new List<StoredUnmappedPointer>();
|
||||
MatchedWords = matchedWords ?? new List<StoredMatchedWord>();
|
||||
Lists = lists ?? new List<StoredList>();
|
||||
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<string>();
|
||||
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("#################################");
|
||||
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -14,10 +14,14 @@
|
|||
<DockPanel>
|
||||
<!-- Bottom Bar -->
|
||||
<DockPanel DockPanel.Dock="Bottom">
|
||||
<TextBlock DockPanel.Dock="Left" Text="{Binding SelectedAddress}" MouseRightButtonUp="AddressShowMenu"/>
|
||||
<Grid HorizontalAlignment="Right">
|
||||
<TextBlock DockPanel.Dock="Left" Width="200" Text="{Binding SelectedAddress}" MouseRightButtonUp="AddressShowMenu"/>
|
||||
<Grid HorizontalAlignment="Right" DockPanel.Dock="Right">
|
||||
<TextBlock Margin="10,0,0,0" Text="{Binding SelectedBytes}" MouseRightButtonUp="BytesShowMenu"/>
|
||||
</Grid>
|
||||
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
|
||||
<TextBlock Text="Free Space:"/>
|
||||
<TextBox Text="{Binding FreeSpaceStart, Converter={StaticResource Hex}}" Width="70"/>
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
<!-- Tool Headers -->
|
||||
<StackPanel DockPanel.Dock="Left" Visibility="{Binding HasTools, Converter={StaticResource BoolToVisibility}}">
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user