88#include " util/util.h"
99
1010#include < string.h>
11+ #include " math/Vector.h"
1112
1213struct RECT16
1314{
@@ -42,10 +43,55 @@ void ExportSkyImage(const char* skyFileName, ubyte* data, int x_idx, int y_idx,
4243 CopyTpageImage ((ushort*)data, (ushort*)imageClut, clut_x, clut_y, 16 , 1 );
4344
4445 SaveTIM_4bit (varargs (" %s_%d_%d.TIM" , skyFileName, sky_id, n),
45- imageCopy, SKY_SIZE_W * SKY_SIZE_H, 0 , 0 , SKY_SIZE_W*2 , SKY_SIZE_H, (ubyte*)imageClut, 1 );
46+ imageCopy, 64 * SKY_SIZE_H, 0 , 0 , SKY_SIZE_W*2 , SKY_SIZE_H, (ubyte*)imageClut, 1 );
4647}
4748
48- void ConvertSky (const char * skyFileName)
49+ void ConvertIndexedSkyImage (uint* color_data, ubyte* src_indexed, int x_idx, int y_idx, bool outputBGR, bool originalTransparencyKey)
50+ {
51+ ushort imageClut[16 ];
52+
53+ int clut_x = x_idx * 16 ;
54+ int clut_y = SKY_CLUT_START_Y + y_idx;
55+
56+ CopyTpageImage ((ushort*)src_indexed, (ushort*)imageClut, clut_x, clut_y, 16 , 1 );
57+
58+ int ox = x_idx * SKY_SIZE_W * 2 ;
59+ int oy = y_idx * SKY_SIZE_H;
60+ int w = SKY_SIZE_W * 2 ;
61+ int h = SKY_SIZE_H;
62+
63+ int tp_wx = ox + w;
64+ int tp_hy = oy + h;
65+
66+ for (int y = oy; y < tp_hy; y++)
67+ {
68+ for (int x = ox; x < tp_wx; x++)
69+ {
70+ ubyte clindex = src_indexed[y * 256 + x / 2 ];
71+
72+ if (0 != (x & 1 ))
73+ clindex >>= 4 ;
74+
75+ clindex &= 0xF ;
76+
77+ // flip texture by Y
78+ int ypos = (256 - y - 1 ) * 512 ;
79+
80+ if (outputBGR)
81+ {
82+ TVec4D<ubyte> color = rgb5a1_ToBGRA8 (imageClut[clindex], originalTransparencyKey);
83+ color_data[ypos + x] = *(uint*)(&color);
84+ }
85+ else
86+ {
87+ TVec4D<ubyte> color = rgb5a1_ToRGBA8 (imageClut[clindex], originalTransparencyKey);
88+ color_data[ypos + x] = *(uint*)(&color);
89+ }
90+ }
91+ }
92+ }
93+
94+ void ConvertSky (const char * skyFileName, bool saveTGA)
4995{
5096 FILE* fp = fopen (skyFileName, " rb" );
5197 if (!fp)
@@ -54,8 +100,6 @@ void ConvertSky(const char* skyFileName)
54100 return ;
55101 }
56102
57- MsgInfo (" Converting '%s' to separate TIM files..." , skyFileName);
58-
59103 fseek (fp, 0 , SEEK_END);
60104 int size = ftell (fp);
61105 fseek (fp, 0 , SEEK_SET);
@@ -67,18 +111,139 @@ void ConvertSky(const char* skyFileName)
67111
68112 const int OFFSET_STEP = 0x10000 ;
69113
114+ #define SKY_TEX_CHANNELS 4
115+ #define SKY_TEXPAGE_SIZE (512 *256 )
116+
117+ uint* color_data;
118+ int imgSize = SKY_TEXPAGE_SIZE * SKY_TEX_CHANNELS;
119+
120+ if (saveTGA)
121+ {
122+ color_data = (uint*)malloc (imgSize);
123+
124+ MsgInfo (" Converting '%s' to separata TGAs...\n " , skyFileName);
125+ }
126+ else
127+ {
128+ MsgInfo (" Converting '%s' to separate TIM files...\n " , skyFileName);
129+ }
130+
131+ // 5 skies in total
70132 for (int i = 0 ; i < 5 ; i++)
71133 {
72134 int n = 0 ;
73135 ubyte* skyImage = data + i * OFFSET_STEP;
74136
137+ if (saveTGA)
138+ {
139+ memset (color_data, 0 , imgSize);
140+ }
141+
142+ // 3x4 images (128x84 makes 256x252 tpage)
75143 for (int y = 0 ; y < 3 ; y++)
76144 {
77145 for (int x = 0 ; x < 4 ; x++, n++)
78- ExportSkyImage (skyFileName, skyImage, x, y, i, n);
146+ {
147+ if (saveTGA)
148+ {
149+ ConvertIndexedSkyImage (color_data, skyImage, x, y, true , true );
150+ }
151+ else
152+ {
153+ ExportSkyImage (skyFileName, skyImage, x, y, i, n);
154+ }
155+ }
156+ }
157+
158+ if (saveTGA)
159+ {
160+ SaveTGA (varargs (" %s_%d.TGA" , skyFileName, i), (ubyte*)color_data, 512 , 256 , SKY_TEX_CHANNELS);
79161 }
80162 }
81163
164+ if (saveTGA)
165+ {
166+ free (color_data);
167+ }
168+
169+ MsgInfo (" Done!" );
170+ }
171+
172+ // -----------------------------------------------------
173+
174+ void ExportExtraImage (const char * filename, ubyte* data, ubyte* clut_data, int n)
175+ {
176+ ubyte imageCopy[64 * 219 ];
177+ ushort imageClut[16 ];
178+
179+ // size is 64x219. palette goes after it
180+
181+ // CopyTpageImage((ushort*)data, (ushort*)imageCopy, 0, 0, 64, 219);
182+ // CopyTpageImage((ushort*)data, (ushort*)imageClut, clut_x, clut_y, 16, 1);
183+
184+ SaveTIM_4bit (varargs (" %s_%d.TIM" , filename, n),
185+ data, 64 * 2 * 219 , 0 , 0 , 64 * 4 , 219 , clut_data, 1 );
186+ }
187+
188+ // In frontend, extra poly has a preview image drawn
189+ void ConvertBackgroundRaw (const char * filename, const char * extraFilename)
190+ {
191+ FILE* bgFp = fopen (filename, " rb" );
192+
193+ if (!bgFp)
194+ {
195+ MsgError (" Unable to open '%s'\n " , filename);
196+ return ;
197+ }
198+
199+ MsgInfo (" Converting background '%s' to separate TIM files..." , filename);
200+
201+ // read background file
202+ fseek (bgFp, 0 , SEEK_END);
203+ int bgSize = ftell (bgFp);
204+ fseek (bgFp, 0 , SEEK_SET);
205+
206+ ubyte* bgData = (ubyte*)malloc (bgSize);
207+ fread (bgData, bgSize, 1 , bgFp);
208+
209+ fclose (bgFp);
210+
211+ // load extra file if specified
212+ if (extraFilename)
213+ {
214+ FILE* fp = fopen (extraFilename, " rb" );
215+ if (!fp)
216+ {
217+ free (bgData);
218+ MsgError (" Unable to open '%s'\n " , extraFilename);
219+ return ;
220+ }
221+
222+ MsgInfo (" Converting '%s' to separate TIM files..." , extraFilename);
223+
224+ fseek (fp, 0 , SEEK_END);
225+ int size = ftell (fp);
226+ fseek (fp, 0 , SEEK_SET);
227+
228+ ubyte* data = (ubyte*)malloc (size);
229+
230+ fread (data, size, 1 , fp);
231+ fclose (fp);
232+
233+ const int OFFSET_STEP = 0x8000 ;
234+
235+ for (int i = 0 ; i < 10 ; i++)
236+ {
237+ ubyte* imageAddr = data + i * OFFSET_STEP;
238+
239+ ExportExtraImage (extraFilename, imageAddr, bgData + 11 *0x8000 , i);
240+ }
241+
242+ free (data);
243+ }
244+
245+ free (bgData);
246+
82247 MsgInfo (" Done!" );
83248}
84249
@@ -88,6 +253,8 @@ void PrintCommandLineArguments()
88253{
89254 MsgInfo (" Example usage:\n " );
90255 MsgInfo (" \t DriverImageTool -sky2tim SKY0.RAW\n " );
256+ MsgInfo (" \t DriverImageTool -sky2tga SKY1.RAW\n " );
257+ MsgInfo (" \t DriverImageTool -bg2tim CARBACK.RAW <CCARS.RAW>\n " );
91258}
92259
93260int main (int argc, char ** argv)
@@ -109,10 +276,29 @@ int main(int argc, char** argv)
109276 if (!stricmp (argv[i], " -sky2tim" ))
110277 {
111278 if (i + 1 <= argc)
112- ConvertSky (argv[i + 1 ]);
279+ ConvertSky (argv[i + 1 ], false );
113280 else
114281 MsgWarning (" -sky2tim must have an argument!" );
115282 }
283+ else if (!stricmp (argv[i], " -sky2tga" ))
284+ {
285+ if (i + 1 <= argc)
286+ ConvertSky (argv[i + 1 ], true );
287+ else
288+ MsgWarning (" -sky2tga must have an argument!" );
289+ }
290+ else if (!stricmp (argv[i], " -bg2tim" ))
291+ {
292+ if (i + 1 <= argc)
293+ {
294+ if (i + 2 <= argc)
295+ ConvertBackgroundRaw (argv[i + 1 ], argv[i + 2 ]);
296+ else
297+ ConvertBackgroundRaw (argv[i + 1 ], nullptr );
298+ }
299+ else
300+ MsgWarning (" -bg2tim must have an argument!" );
301+ }
116302 }
117303
118304 return 0 ;
0 commit comments