@@ -85,25 +85,76 @@ public override void Move(Direction direction, float speed = (float)0.6) {
8585
8686 // TODO: This is mostly duplicated in/from PCXToGodot.cs, but special indexes
8787 // handled differently. Probably needs combining and refactoring
88- public static Image ByteArrayToImage ( byte [ ] ba , byte [ , ] palette , int width , int height , int [ ] transparent = null , bool shadows = false ) {
88+ public static Image ByteArrayToImage ( byte [ ] colorIndices , byte [ , ] palette , int width , int height , int [ ] transparent = null , bool shadows = false ) {
8989 Image OutImage = new Image ( ) ;
9090 OutImage . Create ( width , height , false , Image . Format . Rgba8 ) ;
9191 OutImage . Lock ( ) ;
92- for ( int i = 0 ; i < width * height ; i ++ )
93- {
94- if ( shadows && ba [ i ] > 239 ) {
95- // using black and transparency
96- OutImage . SetPixel ( i % width , i / width , Color . Color8 ( 0 , 0 , 0 , ( byte ) ( ( 255 - ba [ i ] ) * 16 ) ) ) ;
97- // using the palette color but adding transparency
98- // OutImage.SetPixel(i % width, i / width, Color.Color8(palette[ba[i],0], palette[ba[i],1], palette[ba[i],2], (byte)((255 -ba[i]) * 16)));
99- } else {
100- OutImage . SetPixel ( i % width , i / width , Color . Color8 ( palette [ ba [ i ] , 0 ] , palette [ ba [ i ] , 1 ] , palette [ ba [ i ] , 2 ] , ba [ i ] == 255 ? ( byte ) 0 : ( byte ) 255 ) ) ;
101- }
102- }
92+ byte [ ] bmpBuffer = getBmpBuffer ( colorIndices , palette , width , height , transparent , shadows ) ;
93+ OutImage . LoadBmpFromBuffer ( bmpBuffer ) ;
10394 OutImage . Unlock ( ) ;
10495
10596 return OutImage ;
10697 }
98+
99+ public static unsafe byte [ ] getBmpBuffer ( byte [ ] colorIndices , byte [ , ] palette , int width , int height , int [ ] transparent = null , bool shadows = false ) {
100+
101+ int bmpSize = width * height * 4 + 54 ; //54 = Windows 3 BMP header size.
102+ byte [ ] bmpBuffer = new byte [ bmpSize ] ;
103+ fixed ( byte * fPtr = bmpBuffer ) {
104+ //BMP header. This is a mix of byte, short, and int. Probably a cleaner way to do this, but my C is rusty.
105+ byte * bPtr = fPtr ;
106+ int * iPtr ;
107+ short * sPtr ;
108+ bPtr [ 0 ] = 66 ; //B
109+ bPtr [ 1 ] = 77 ; //M
110+ bPtr += 2 ;
111+ iPtr = ( int * ) bPtr ;
112+ iPtr [ 0 ] = bmpSize ; //size of BMP file in bytes
113+ iPtr [ 1 ] = 0 ; //reserved, two shorts
114+ iPtr [ 2 ] = 54 ; //offset of image data from start of file
115+ iPtr [ 3 ] = 40 ; //size of Windows 3 BMP header
116+ iPtr [ 4 ] = width ;
117+ iPtr [ 5 ] = height ;
118+ bPtr += 24 ; //6 * 4
119+ sPtr = ( short * ) bPtr ;
120+ sPtr [ 0 ] = 1 ; //num color planes
121+ sPtr [ 1 ] = 32 ; //bit depth. we want 32-bit with alpha
122+ bPtr += 4 ;
123+ iPtr = ( int * ) bPtr ;
124+ iPtr [ 0 ] = 0 ; //compression - none. Godot doesn't support compression
125+ iPtr [ 1 ] = bmpSize - 54 ; //size, without headers
126+ iPtr [ 2 ] = 0 ; //horizontal resolution. ignored.
127+ iPtr [ 3 ] = 0 ; //vertical resolution. ignored.
128+ iPtr [ 4 ] = 0 ; //num colors in palette. not relevant for 32-bit
129+ iPtr [ 5 ] = 0 ; //num important colors in palette. not relevant.
130+ bPtr += 24 ; //6 * 4
131+ iPtr = ( int * ) bPtr ;
132+ //Ready for image data
133+
134+ int c = 0 ;
135+ //The BMP data is stored bottom-to-top, whereas our data is top-to-bottom
136+ //Thus we'll use c to calculate the index for each row
137+ for ( int y = height - 1 ; y > - 1 ; y -- )
138+ {
139+ c = width * y ;
140+ for ( int x = 0 ; x < width ; x ++ )
141+ {
142+ if ( shadows && colorIndices [ c ] > 239 ) {
143+ // using black and transparency
144+ iPtr [ 0 ] = ( ( 255 - colorIndices [ c ] ) << 4 ) << 24 ;
145+ // using the palette color but adding transparency
146+ // OutImage.SetPixel(i % width, i / width, Color.Color8(palette[ba[i],0], palette[ba[i],1], palette[ba[i],2], (byte)((255 -ba[i]) * 16)));
147+ } else {
148+ // A, R, G, B
149+ iPtr [ 0 ] = ( ( byte ) 255 ) << 24 | palette [ colorIndices [ c ] , 0 ] << 16 | palette [ colorIndices [ c ] , 1 ] << 8 | palette [ colorIndices [ c ] , 2 ] << 0 ;
150+ }
151+ c ++ ;
152+ iPtr ++ ;
153+ }
154+ }
155+ }
156+ return bmpBuffer ;
157+ }
107158}
108159// This is just to add some movement to an AnimatedSprite
109160public class MovingSprite : AnimatedSprite {
0 commit comments