Skip to content

Commit b711c0a

Browse files
author
Andrew Jones
authored
Merge pull request #31 from C7-Game/FLCPerformance
FLC Import Performance
2 parents 89f4db1 + fc51efa commit b711c0a

File tree

4 files changed

+76
-12
lines changed

4 files changed

+76
-12
lines changed

C7/C7.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<Project Sdk="Godot.NET.Sdk/3.3.0">
22
<PropertyGroup>
33
<TargetFramework>net472</TargetFramework>
4+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
45
</PropertyGroup>
56
<ItemGroup>
67
<ProjectReference Include="..\ConvertCiv3Media\ConvertCiv3Media.csproj" />

C7/Civ3Unit/Civ3Unit.cs

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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
109160
public class MovingSprite : AnimatedSprite {

C7/project.godot

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ window/size/height=768
3131

3232
theme/custom="res://C7Theme.tres"
3333

34+
[network]
35+
36+
limits/debugger_stdout/max_chars_per_second=16384
37+
3438
[rendering]
3539

3640
environment/default_environment="res://default_env.tres"

ConvertCiv3Media/ReadFlic.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,12 @@ public class Flic {
1515
public int Width = 0;
1616
public int Height = 0;
1717

18+
private string path;
19+
1820
// constructors
1921
public Flic(){}
2022
public Flic(string path) {
23+
this.path = path;
2124
this.Load(path);
2225
}
2326
public void Load(string path) {
@@ -189,5 +192,10 @@ public void Load(string path) {
189192
Offset += RingChunkLength;
190193
}
191194
}
195+
196+
public override string ToString()
197+
{
198+
return "FLIC " + this.path;
199+
}
192200
}
193201
}

0 commit comments

Comments
 (0)