22using Avalonia . Media . Imaging ;
33using Avalonia . Threading ;
44using DynamicData ;
5+ using OpenLoco . Common ;
56using OpenLoco . Common . Logging ;
67using OpenLoco . Dat ;
78using OpenLoco . Dat . Types ;
1920using System . Reactive . Linq ;
2021using System . Text . Json ;
2122using System . Text . Json . Serialization ;
22- using System . Text . RegularExpressions ;
2323using System . Threading . Tasks ;
2424using System . Windows . Input ;
2525using Image = SixLabors . ImageSharp . Image ;
@@ -55,7 +55,10 @@ public enum ColourSwatches
5555 public record SpriteOffset (
5656 [ property: JsonPropertyName ( "path" ) ] string Path ,
5757 [ property: JsonPropertyName ( "x" ) ] int16_t X ,
58- [ property: JsonPropertyName ( "y" ) ] int16_t Y ) ;
58+ [ property: JsonPropertyName ( "y" ) ] int16_t Y )
59+ {
60+ public static SpriteOffset Zero => new SpriteOffset ( string . Empty , 0 , 0 ) ;
61+ }
5962
6063 public class ImageTableViewModel : ReactiveObject , IExtraContentViewModel
6164 {
@@ -249,42 +252,55 @@ public async Task ImportImages()
249252
250253 try
251254 {
255+ Logger . Debug ( $ "{ G1Provider . G1Elements . Count } images in current object") ;
256+
257+ // count files in dir and check naming
258+ var files = Directory . GetFiles ( dirPath , "*.png" , SearchOption . AllDirectories ) ;
259+
260+ Logger . Debug ( $ "{ files . Length } files in current directory") ;
261+
262+ IEnumerable < SpriteOffset > offsets ;
263+
264+ // check for offsets file
252265 var offsetsFile = Path . Combine ( dirPath , "sprites.json" ) ;
253266 if ( File . Exists ( offsetsFile ) )
254267 {
255- // found blender folder
256- var offsets = JsonSerializer . Deserialize < ICollection < SpriteOffset > > ( File . ReadAllText ( offsetsFile ) ) ; // sprites.json is an unnamed array so we need ICollection here, not IEnumerable
268+ offsets = JsonSerializer . Deserialize < ICollection < SpriteOffset > > ( File . ReadAllText ( offsetsFile ) ) ; // sprites.json is an unnamed array so we need ICollection here, not IEnumerable
257269 ArgumentNullException . ThrowIfNull ( offsets ) ;
258- Logger . Debug ( "Found sprites.json file, using that" ) ;
259-
260- if ( offsets . Count != G1Provider . G1Elements . Count )
261- {
262- Logger . Warning ( $ "Expected { G1Provider . G1Elements . Count } offsets, got { offsets . Count } offsets. Continue at your peril.") ;
263- }
264-
265- foreach ( var offset in offsets )
266- {
267- var filename = Path . Combine ( dirPath , offset . Path ) ;
268- LoadSprite ( filename , offset ) ;
269- }
270+ Logger . Debug ( "Found sprites.json file; using that" ) ;
270271 }
271272 else
272273 {
273- Logger . Debug ( "No sprites.json file found" ) ;
274- var files = Directory . GetFiles ( dirPath , "*" , SearchOption . AllDirectories ) ;
274+ offsets = G1Provider . G1Elements . Select ( ( x , i ) => new SpriteOffset ( $ "{ i } .png", x . XOffset , x . YOffset ) ) ;
275+ Logger . Debug ( "Didn't find sprites.json; using existing G1Element32 offsets" ) ;
276+ }
277+
278+ offsets = offsets . Fill ( files . Length , SpriteOffset . Zero ) ;
279+
280+ // clear existing images
281+ Logger . Info ( "Clearing current G1Element32s and existing object images" ) ;
282+ G1Provider . G1Elements . Clear ( ) ;
283+ Images . Clear ( ) ;
284+ Bitmaps . Clear ( ) ;
285+
286+ // load files
287+ var offsetList = offsets . ToList ( ) ;
288+ for ( var i = 0 ; i < files . Length ; ++ i )
289+ {
290+ var filename = Path . Combine ( dirPath , $ "{ i } .png") ;
275291
276- if ( files . Length != G1Provider . G1Elements . Count )
292+ if ( i < G1Provider . G1Elements . Count )
277293 {
278- Logger . Warning ( $ "Expected { G1Provider . G1Elements . Count } images, got { files . Length } images. Continue at your peril.") ;
294+ var g1 = G1Provider . G1Elements [ i ] ;
295+ LoadSprite ( filename , 0 , offsetList [ i ] . X , offsetList [ i ] . Y , g1 . Flags , g1 . ZoomOffset ) ;
279296 }
280-
281- foreach ( var filename in files )
297+ else
282298 {
283- LoadSprite ( filename ) ;
299+ LoadSprite ( filename , 0 , offsetList [ i ] . X , offsetList [ i ] . Y , G1ElementFlags . None , 0 ) ;
284300 }
285301 }
286302
287- Logger . Debug ( "Import successful ") ;
303+ Logger . Debug ( $ "Imported { G1Provider . G1Elements . Count } images successfully ") ;
288304 this . RaisePropertyChanged ( nameof ( Bitmaps ) ) ;
289305 }
290306 catch ( Exception ex )
@@ -294,38 +310,25 @@ public async Task ImportImages()
294310 }
295311
296312 animationTimer . Start ( ) ;
297- }
298-
299- void LoadSprite ( string filename , SpriteOffset ? offset = null )
300- {
301- if ( ! Path . Exists ( filename ) )
302- {
303- Logger . Error ( $ "File doesn't exist: \" { filename } \" ") ;
304- return ;
305- }
306313
307- var match = Regex . Match ( Path . GetFileNameWithoutExtension ( filename ) , @".*?(\d+).*?" ) ;
308- if ( ! match . Success )
314+ void LoadSprite ( string filename , uint imageOffset , short xOffset , short yOffset , G1ElementFlags flags , short zoomOffset )
309315 {
310- Logger . Error ( $ "Couldn't parse sprite index from filename: \" { filename } \" ") ;
311- return ;
312- }
316+ if ( ! Path . Exists ( filename ) )
317+ {
318+ Logger . Error ( $ "File doesn't exist: \" { filename } \" ") ;
319+ return ;
320+ }
313321
314- var index = int . Parse ( match . Groups [ 1 ] . Value ) ;
315- var img = Image . Load < Rgba32 > ( filename ) ;
322+ var img = Image . Load < Rgba32 > ( filename ) ;
316323
317- if ( index >= G1Provider . G1Elements . Count )
318- {
319- var newElement = new G1Element32 ( 0 , ( int16_t ) img . Width , ( int16_t ) img . Height , 0 , 0 , G1ElementFlags . None , 0 )
324+ var newElement = new G1Element32 ( imageOffset , ( int16_t ) img . Width , ( int16_t ) img . Height , xOffset , yOffset , flags , zoomOffset )
320325 {
321- ImageData = PaletteMap . ConvertRgba32ImageToG1Data ( img , G1ElementFlags . None )
326+ ImageData = PaletteMap . ConvertRgba32ImageToG1Data ( img , flags )
322327 } ;
323- G1Provider . G1Elements . Insert ( index , newElement ) ;
324- Images . Insert ( index , img ) ; // update the UI
325- }
326- else
327- {
328- UpdateImage ( img , index , offset ) ;
328+
329+ G1Provider . G1Elements . Add ( newElement ) ;
330+ Images . Add ( img ) ;
331+ Bitmaps . Add ( G1ImageConversion . CreateAvaloniaImage ( img ) ) ;
329332 }
330333 }
331334
0 commit comments