Skip to content

Commit 3757d4e

Browse files
authored
Read sprite offsets (#102)
* read sprites.json file output from blender * clean up logging * handle unnamed array, read actual file as json * refactor image import to use common methods/code
1 parent 0e941f6 commit 3757d4e

File tree

1 file changed

+60
-29
lines changed

1 file changed

+60
-29
lines changed

AvaGui/ViewModels/SubObjectTypes/ImageTableViewModel.cs

Lines changed: 60 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,23 @@
1111
using SixLabors.ImageSharp.PixelFormats;
1212
using System;
1313
using System.Collections.Generic;
14-
using System.Collections.Immutable;
1514
using System.IO;
1615
using System.Linq;
1716
using System.Reactive.Linq;
17+
using System.Text.Json;
18+
using System.Text.Json.Serialization;
1819
using System.Text.RegularExpressions;
1920
using System.Threading.Tasks;
2021
using System.Windows.Input;
2122
using Image = SixLabors.ImageSharp.Image;
2223

2324
namespace AvaGui.ViewModels
2425
{
26+
public record SpriteOffset(
27+
[property: JsonPropertyName("path")] string Path,
28+
[property: JsonPropertyName("x")] int16_t X,
29+
[property: JsonPropertyName("y")] int16_t Y);
30+
2531
public class ImageTableViewModel : ReactiveObject, IExtraContentViewModel, ILocoFileViewModel
2632
{
2733
readonly IHasG1Elements G1Provider;
@@ -186,6 +192,8 @@ public UIG1Element32? SelectedG1Element
186192
//todo: second half should be model
187193
public async Task ImportImages()
188194
{
195+
animationTimer.Stop();
196+
189197
var folders = await PlatformSpecific.OpenFolderPicker();
190198
var dir = folders.FirstOrDefault();
191199
if (dir == null)
@@ -199,48 +207,71 @@ public async Task ImportImages()
199207
return;
200208
}
201209

202-
var files = Directory.GetFiles(dirPath);
203-
if (files.Length == 0)
204-
{
205-
return;
206-
}
207-
208210
try
209211
{
210-
var sorted = files.OrderBy(static f =>
212+
var offsetsFile = Path.Combine(dirPath, "sprites.json");
213+
if (File.Exists(offsetsFile))
211214
{
212-
var match = Regex.Match(Path.GetFileNameWithoutExtension(f), @".*?(\d+).*?");
213-
return match.Success
214-
? int.Parse(match.Groups[1].Value)
215-
: throw new InvalidDataException($"Directory contains file that doesn't contain a number={f}");
216-
});
217-
218-
var sortedH = sorted.ToImmutableHashSet();
215+
// found blender folder
216+
var offsets = JsonSerializer.Deserialize<ICollection<SpriteOffset>>(File.ReadAllText(offsetsFile)); // sprites.json is an unnamed array so we need ICollection here, not IEnumerable
217+
Logger.Debug("Found sprites.json file, using that");
219218

220-
var g1Elements = new List<G1Element32>();
221-
var i = 0;
222-
foreach (var file in sorted)
219+
foreach (var offset in offsets)
220+
{
221+
var filename = Path.Combine(dirPath, offset.Path);
222+
LoadSprite(filename, offset);
223+
}
224+
}
225+
else
223226
{
224-
var img = Image.Load<Rgba32>(file);
225-
Images[i] = img;
226-
var currG1 = G1Provider.G1Elements[i];
227-
currG1 = currG1 with
227+
Logger.Debug("No sprites.json file found");
228+
foreach (var filename in Directory.GetFiles(dirPath, "*", SearchOption.AllDirectories))
228229
{
229-
Width = (int16_t)img.Width,
230-
Height = (int16_t)img.Height,
231-
Flags = currG1.Flags & ~G1ElementFlags.IsRLECompressed, // SawyerStreamWriter::SaveImageTable does this anyways
232-
ImageData = PaletteMap.ConvertRgba32ImageToG1Data(img, currG1.Flags)
233-
};
234-
G1Provider.G1Elements[i] = currG1;
235-
i++;
230+
LoadSprite(filename);
231+
}
236232
}
237233

234+
Logger.Debug("Import successful");
238235
this.RaisePropertyChanged(nameof(Bitmaps));
239236
}
240237
catch (Exception ex)
241238
{
242239
Logger.Error(ex);
243240
}
241+
242+
animationTimer.Start();
243+
}
244+
245+
void LoadSprite(string filename, SpriteOffset? offset = null)
246+
{
247+
if (!Path.Exists(filename))
248+
{
249+
Logger.Error($"File doesn't exist: \"{filename}\"");
250+
return;
251+
}
252+
253+
var match = Regex.Match(Path.GetFileNameWithoutExtension(filename), @".*?(\d+).*?");
254+
if (!match.Success)
255+
{
256+
Logger.Warning($"Couldn't parse sprite index from filename: \"{filename}\"");
257+
return;
258+
}
259+
260+
var index = int.Parse(match.Groups[1].Value);
261+
var img = Image.Load<Rgba32>(filename);
262+
Images[index] = img;
263+
264+
var currG1 = G1Provider.G1Elements[index];
265+
currG1 = currG1 with
266+
{
267+
Width = (int16_t)img.Width,
268+
Height = (int16_t)img.Height,
269+
Flags = currG1.Flags & ~G1ElementFlags.IsRLECompressed, // SawyerStreamWriter::SaveImageTable does this anyways
270+
ImageData = PaletteMap.ConvertRgba32ImageToG1Data(img, currG1.Flags),
271+
XOffset = offset?.X ?? currG1.XOffset,
272+
YOffset = offset?.Y ?? currG1.YOffset
273+
};
274+
G1Provider.G1Elements[index] = currG1;
244275
}
245276

246277
// todo: second half should be in model

0 commit comments

Comments
 (0)