Skip to content

Commit 9782a85

Browse files
committed
add palette generator csproj
1 parent 8cec59e commit 9782a85

File tree

4 files changed

+180
-18
lines changed

4 files changed

+180
-18
lines changed

DataSanitiser/Program.cs

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,39 @@
66
using OpenLoco.Dat.Objects;
77
using OpenLoco.Dat.Types;
88
using OpenLoco.Definitions.SourceData;
9-
using SixLabors.ImageSharp;
10-
using SixLabors.ImageSharp.PixelFormats;
9+
using System.Data;
1110
using System.Text.Json;
1211
using System.Text.Json.Serialization;
1312

14-
// load 32bpp palette
15-
var paletteFile = "Q:\\Games\\Locomotion\\Palettes\\palette.png";
16-
var img = Image.Load<Rgba32>(paletteFile);
17-
var palStrings = new List<string>()
13+
// directory maker
14+
var path = "Q:\\Games\\Locomotion\\OriginalObjects\\GoG\\objectIndex.json";
15+
var idx = ObjectIndex.LoadIndex(path);
16+
var sourcePath = "C:\\Users\\bigba\\source\\repos\\OpenLoco\\OpenGraphics\\objects";
17+
var keepfile = Path.Combine(sourcePath, ".gitkeep");
18+
foreach (var objType in idx.Objects.GroupBy(x => x.ObjectType))
1819
{
19-
"JASC-PAL", // header
20-
"0100", // version
21-
"256", // colours in palette file
22-
};
23-
24-
for (var y = 0; y < img.Height; y++)
25-
{
26-
for (var x = 0; x < img.Width; x++)
20+
var d = Directory.CreateDirectory(Path.Combine(sourcePath, objType.Key.ToString()));
21+
if (objType.Key == ObjectType.Vehicle)
22+
{
23+
foreach (var subtype in objType.GroupBy(x => x.VehicleType))
24+
{
25+
var dd = Directory.CreateDirectory(Path.Combine(d.FullName, subtype.Key.ToString()!));
26+
foreach (var obj in subtype)
27+
{
28+
var ddd = Directory.CreateDirectory(Path.Combine(dd.FullName, obj.DatName));
29+
_ = File.Create(Path.Combine(ddd.FullName, ".gitkeep"), 0);
30+
}
31+
}
32+
}
33+
else
2734
{
28-
var col = img[x, y];
29-
palStrings.Add($"{col.R} {col.G} {col.B}");
35+
foreach (var obj in objType)
36+
{
37+
var ddd = Directory.CreateDirectory(Path.Combine(d.FullName, obj.DatName));
38+
_ = File.Create(Path.Combine(ddd.FullName, ".gitkeep"), 0);
39+
}
3040
}
3141
}
32-
File.WriteAllLines("Q:\\Games\\Locomotion\\Palettes\\jascpal.pal", palStrings);
33-
// spit out .pal file
3442
Environment.Exit(0);
3543

3644
var jsonOptions = new JsonSerializerOptions() { WriteIndented = true, Converters = { new JsonStringEnumConverter() }, };

OpenLocoObjectEditor.sln

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DatabaseExporter", "Databas
3838
EndProject
3939
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataSanitiser", "DataSanitiser\DataSanitiser.csproj", "{ED77CF9B-CA65-4798-A269-0748D14CFC9F}"
4040
EndProject
41+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PaletteGenerator", "PaletteGenerator\PaletteGenerator.csproj", "{010B8AB4-9867-4BE0-A663-6261DA4056F9}"
42+
EndProject
4143
Global
4244
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4345
Debug|Any CPU = Debug|Any CPU
@@ -156,6 +158,18 @@ Global
156158
{ED77CF9B-CA65-4798-A269-0748D14CFC9F}.Release|x64.Build.0 = Release|Any CPU
157159
{ED77CF9B-CA65-4798-A269-0748D14CFC9F}.Release|x86.ActiveCfg = Release|Any CPU
158160
{ED77CF9B-CA65-4798-A269-0748D14CFC9F}.Release|x86.Build.0 = Release|Any CPU
161+
{010B8AB4-9867-4BE0-A663-6261DA4056F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
162+
{010B8AB4-9867-4BE0-A663-6261DA4056F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
163+
{010B8AB4-9867-4BE0-A663-6261DA4056F9}.Debug|x64.ActiveCfg = Debug|Any CPU
164+
{010B8AB4-9867-4BE0-A663-6261DA4056F9}.Debug|x64.Build.0 = Debug|Any CPU
165+
{010B8AB4-9867-4BE0-A663-6261DA4056F9}.Debug|x86.ActiveCfg = Debug|Any CPU
166+
{010B8AB4-9867-4BE0-A663-6261DA4056F9}.Debug|x86.Build.0 = Debug|Any CPU
167+
{010B8AB4-9867-4BE0-A663-6261DA4056F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
168+
{010B8AB4-9867-4BE0-A663-6261DA4056F9}.Release|Any CPU.Build.0 = Release|Any CPU
169+
{010B8AB4-9867-4BE0-A663-6261DA4056F9}.Release|x64.ActiveCfg = Release|Any CPU
170+
{010B8AB4-9867-4BE0-A663-6261DA4056F9}.Release|x64.Build.0 = Release|Any CPU
171+
{010B8AB4-9867-4BE0-A663-6261DA4056F9}.Release|x86.ActiveCfg = Release|Any CPU
172+
{010B8AB4-9867-4BE0-A663-6261DA4056F9}.Release|x86.Build.0 = Release|Any CPU
159173
EndGlobalSection
160174
GlobalSection(SolutionProperties) = preSolution
161175
HideSolutionNode = FALSE
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.5" />
12+
</ItemGroup>
13+
14+
</Project>

PaletteGenerator/Program.cs

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
using SixLabors.ImageSharp;
2+
using SixLabors.ImageSharp.PixelFormats;
3+
using System.Text;
4+
5+
// this should really be in OpenLoco/OpenGraphics
6+
7+
var baseDir = "Q:\\Games\\Locomotion\\Palettes";
8+
var paletteFile = Path.Combine(baseDir, "palette.png");
9+
var img = Image.Load<Rgba32>(paletteFile);
10+
11+
MakeJascPal(baseDir, img);
12+
MakeMicrosoftPal(baseDir, img);
13+
MakePhotoshopAco(baseDir, img);
14+
MakePhotoshopAct(baseDir, img);
15+
16+
static void MakeJascPal(string baseDir, Image<Rgba32> img)
17+
{
18+
// header
19+
var lines = new List<string>()
20+
{
21+
"JASC-PAL", // header
22+
"0100", // version
23+
"256", // colours in palette file
24+
};
25+
26+
// colours
27+
for (var y = 0; y < img.Height; y++)
28+
{
29+
for (var x = 0; x < img.Width; x++)
30+
{
31+
var col = img[x, y];
32+
lines.Add($"{col.R} {col.G} {col.B}");
33+
}
34+
}
35+
36+
File.WriteAllLines(Path.Combine(baseDir, "locopal.jasc.pal"), lines);
37+
}
38+
39+
static void MakeMicrosoftPal(string baseDir, Image<Rgba32> img)
40+
{
41+
// from https://www.aelius.com/njh/wavemetatools/doc/riffmci.pdf
42+
43+
var count = (uint)img.Width * (uint)img.Height;
44+
45+
using var fs = new FileStream(Path.Combine(baseDir, "locopal.ms.pal"), FileMode.Create, FileAccess.Write, FileShare.None);
46+
using var bw = new BinaryWriter(fs);
47+
48+
// RIFF header
49+
bw.Write(Encoding.ASCII.GetBytes("RIFF"));
50+
bw.Write(16 + (count * 4)); // exclude RIFF and filesize from the file size calc
51+
bw.Write(Encoding.ASCII.GetBytes("PAL "));
52+
53+
// data chunk
54+
bw.Write(Encoding.ASCII.GetBytes("data"));
55+
bw.Write(4 + (count * 4)); // chunk size
56+
bw.Write((ushort)0x0300); // palVersion
57+
bw.Write((ushort)count); // palNumEntries
58+
59+
// colours
60+
for (var y = 0; y < img.Height; y++)
61+
{
62+
for (var x = 0; x < img.Width; x++)
63+
{
64+
var col = img[x, y];
65+
bw.Write(col.R); // peRed
66+
bw.Write(col.G); // peGreen
67+
bw.Write(col.B); // peBlue
68+
bw.Write((byte)0x0); // peFlags (usually 0)
69+
}
70+
}
71+
}
72+
73+
static void MakePhotoshopAco(string baseDir, Image<Rgba32> img)
74+
{
75+
var count = (uint)img.Width * (uint)img.Height;
76+
using var fs = new FileStream(Path.Combine(baseDir, "locopal.aco"), FileMode.Create, FileAccess.Write, FileShare.None);
77+
78+
// Write the ACO file header
79+
WriteInt16(fs, 1); // Version 1
80+
WriteInt16(fs, (short)count);
81+
82+
// Write each colour
83+
for (var y = 0; y < img.Height; y++)
84+
{
85+
for (var x = 0; x < img.Width; x++)
86+
{
87+
var col = img[x, y];
88+
WriteInt16(fs, 0); // Colour space: RGB
89+
WriteInt16(fs, (short)(col.R * 256)); // Red channel
90+
WriteInt16(fs, (short)(col.G * 256)); // Green channel
91+
WriteInt16(fs, (short)(col.B * 256)); // Blue channel
92+
WriteInt16(fs, 0); // Padding
93+
}
94+
}
95+
96+
static void WriteInt16(Stream stream, short value)
97+
{
98+
stream.WriteByte((byte)(value >> 8));
99+
stream.WriteByte((byte)value);
100+
}
101+
}
102+
103+
static void MakePhotoshopAct(string baseDir, Image<Rgba32> img)
104+
{
105+
var count = (uint)img.Width * (uint)img.Height;
106+
107+
// ACT files expect 256 colors
108+
if (count != 256)
109+
{
110+
throw new ArgumentException("ACT files require exactly 256 colours.");
111+
}
112+
113+
using var fs = new FileStream(Path.Combine(baseDir, "locopal.act"), FileMode.Create, FileAccess.Write, FileShare.None);
114+
115+
// Write each colour
116+
for (var y = 0; y < img.Height; y++)
117+
{
118+
for (var x = 0; x < img.Width; x++)
119+
{
120+
var col = img[x, y];
121+
fs.WriteByte(col.R);
122+
fs.WriteByte(col.G);
123+
fs.WriteByte(col.B);
124+
}
125+
}
126+
}

0 commit comments

Comments
 (0)