1+ using Europa1400 . Tools . Decoder . Gfx ;
2+ using Europa1400 . Tools . Interfaces ;
3+ using System . Drawing ;
4+ using System . Drawing . Imaging ;
5+ using System . Runtime . CompilerServices ;
6+
7+ [ assembly: InternalsVisibleTo ( "Europa1400.Tools.Tests" ) ]
8+
9+ namespace Europa1400 . Tools . Converter ;
10+
11+ #pragma warning disable CA1416 // Validate platform compatibility
12+ internal class GraphicsConverter : IConverter
13+ {
14+ public void Convert ( string pathToGameFiles , string targetDirectory )
15+ {
16+ var sourceDirectory = new DirectoryInfo ( pathToGameFiles ) ;
17+
18+ var outputPath = Path . Combine ( targetDirectory , "Graphics" ) ;
19+ var graphicsDirectory = new DirectoryInfo ( outputPath ) ;
20+ graphicsDirectory . Create ( ) ;
21+
22+ var graphicsFiles = sourceDirectory . GetFiles ( "*.gfx" , SearchOption . AllDirectories ) ;
23+
24+ foreach ( var graphicsFile in graphicsFiles )
25+ {
26+ using var br = new BinaryReader ( File . OpenRead ( graphicsFile . FullName ) ) ;
27+ var gfxStruct = GfxStruct . FromBytes ( br ) ;
28+
29+ Dictionary < string , Dictionary < string , Image > > shapebankImages = [ ] ;
30+
31+ foreach ( var shapebankDefinition in gfxStruct . ShapebankDefinitions )
32+ {
33+ if ( shapebankDefinition . Shapebank == null )
34+ continue ;
35+
36+ var convertedShapebank = ConvertShapebank ( shapebankDefinition . Name , shapebankDefinition . Shapebank ) ;
37+
38+ shapebankImages . Add ( shapebankDefinition . Name , convertedShapebank ) ;
39+ }
40+
41+ foreach ( var shapebank in shapebankImages )
42+ {
43+ var shapebankDirectory = Path . Combine ( outputPath , shapebank . Key ) ;
44+ var shapebankDirectoryInfo = new DirectoryInfo ( shapebankDirectory ) ;
45+ shapebankDirectoryInfo . Create ( ) ;
46+
47+ foreach ( var image in shapebank . Value )
48+ {
49+ image . Value . Save ( Path . Combine ( shapebankDirectory , $ "{ image . Key } .png") , ImageFormat . Png ) ;
50+ }
51+ }
52+ }
53+ }
54+
55+ private Dictionary < string , Image > ConvertShapebank ( string baseName , ShapebankStruct shapebank )
56+ {
57+ var result = new Dictionary < string , Image > ( ) ;
58+
59+ for ( var i = 0 ; i < shapebank . Graphics . Length ; i ++ )
60+ {
61+ var graphic = shapebank . Graphics [ i ] ;
62+ var convertedGraphic = ConvertGraphic ( graphic ) ;
63+
64+ result . Add ( $ "{ baseName } _{ i } ", convertedGraphic ) ;
65+ }
66+
67+ return result ;
68+ }
69+
70+ private Image ConvertGraphic ( GraphicStruct graphic )
71+ {
72+ var result = new Bitmap ( graphic . Width , graphic . Height ) ;
73+
74+ if ( graphic . PixelData != null )
75+ {
76+ var row = 0 ;
77+ var col = 0 ;
78+
79+ for ( var i = 0 ; i < graphic . Width * graphic . Height ; i += 3 )
80+ {
81+ var pixel = Color . FromArgb ( 255 , graphic . PixelData [ i ] , graphic . PixelData [ i + 1 ] ,
82+ graphic . PixelData [ i + 2 ] ) ;
83+
84+ result . SetPixel ( row , col , pixel ) ;
85+
86+ if ( row == graphic . Width - 1 )
87+ {
88+ row = 0 ;
89+ col ++ ;
90+ }
91+ else
92+ row ++ ;
93+ }
94+ }
95+ else if ( graphic . GraphicRows != null )
96+ {
97+ var transparent = Color . FromArgb ( 0 , 255 , 255 , 255 ) ;
98+ var imageData = new List < Color > ( ) ;
99+
100+ foreach ( var graphicRow in graphic . GraphicRows )
101+ {
102+ foreach ( var transparencyBlock in graphicRow . TransparencyBlocks )
103+ {
104+ for ( var k = 0 ; k < transparencyBlock . Size ; k += 3 )
105+ {
106+ imageData . Add ( transparent ) ;
107+ }
108+
109+ for ( var k = 0 ; k < transparencyBlock . Data . Length ; k += 3 )
110+ {
111+ imageData . Add ( Color . FromArgb ( 255 , transparencyBlock . Data [ k ] , transparencyBlock . Data [ k + 1 ] ,
112+ transparencyBlock . Data [ k + 2 ] ) ) ;
113+ }
114+ }
115+ }
116+
117+ if ( imageData . Count != graphic . Height * graphic . Width )
118+ throw new Exception (
119+ $ "Image data does not match graphic dimensions. Expected { graphic . Height * graphic . Width } , got { imageData . Count } ") ;
120+
121+ var row = 0 ;
122+ var col = 0 ;
123+
124+ foreach ( var pixel in imageData )
125+ {
126+ result . SetPixel ( row , col , pixel ) ;
127+
128+ if ( row == graphic . Width - 1 )
129+ {
130+ row = 0 ;
131+ col ++ ;
132+ }
133+ else
134+ row ++ ;
135+ }
136+ }
137+ else
138+ throw new ArgumentException ( "Graphic has no pixel data or graphic rows" ) ;
139+
140+ return result ;
141+ }
142+ }
0 commit comments