2
2
using Avalonia . Media . Imaging ;
3
3
using Avalonia . Threading ;
4
4
using DynamicData ;
5
+ using OpenLoco . Common ;
5
6
using OpenLoco . Common . Logging ;
6
7
using OpenLoco . Dat ;
7
8
using OpenLoco . Dat . Types ;
19
20
using System . Reactive . Linq ;
20
21
using System . Text . Json ;
21
22
using System . Text . Json . Serialization ;
22
- using System . Text . RegularExpressions ;
23
23
using System . Threading . Tasks ;
24
24
using System . Windows . Input ;
25
25
using Image = SixLabors . ImageSharp . Image ;
@@ -55,7 +55,10 @@ public enum ColourSwatches
55
55
public record SpriteOffset (
56
56
[ property: JsonPropertyName ( "path" ) ] string Path ,
57
57
[ 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
+ }
59
62
60
63
public class ImageTableViewModel : ReactiveObject , IExtraContentViewModel
61
64
{
@@ -249,42 +252,55 @@ public async Task ImportImages()
249
252
250
253
try
251
254
{
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
252
265
var offsetsFile = Path . Combine ( dirPath , "sprites.json" ) ;
253
266
if ( File . Exists ( offsetsFile ) )
254
267
{
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
257
269
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" ) ;
270
271
}
271
272
else
272
273
{
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") ;
275
291
276
- if ( files . Length != G1Provider . G1Elements . Count )
292
+ if ( i < G1Provider . G1Elements . Count )
277
293
{
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 ) ;
279
296
}
280
-
281
- foreach ( var filename in files )
297
+ else
282
298
{
283
- LoadSprite ( filename ) ;
299
+ LoadSprite ( filename , 0 , offsetList [ i ] . X , offsetList [ i ] . Y , G1ElementFlags . None , 0 ) ;
284
300
}
285
301
}
286
302
287
- Logger . Debug ( "Import successful ") ;
303
+ Logger . Debug ( $ "Imported { G1Provider . G1Elements . Count } images successfully ") ;
288
304
this . RaisePropertyChanged ( nameof ( Bitmaps ) ) ;
289
305
}
290
306
catch ( Exception ex )
@@ -294,38 +310,25 @@ public async Task ImportImages()
294
310
}
295
311
296
312
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
- }
306
313
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 )
309
315
{
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
+ }
313
321
314
- var index = int . Parse ( match . Groups [ 1 ] . Value ) ;
315
- var img = Image . Load < Rgba32 > ( filename ) ;
322
+ var img = Image . Load < Rgba32 > ( filename ) ;
316
323
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 )
320
325
{
321
- ImageData = PaletteMap . ConvertRgba32ImageToG1Data ( img , G1ElementFlags . None )
326
+ ImageData = PaletteMap . ConvertRgba32ImageToG1Data ( img , flags )
322
327
} ;
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 ) ) ;
329
332
}
330
333
}
331
334
0 commit comments