1 /*---------------------------------------------------------------------------*
2
3 Copyright (C) Nintendo. All rights reserved.
4
5 These coded instructions, statements, and computer programs contain
6 proprietary information of Nintendo of America Inc. and/or Nintendo
7 Company Ltd., and are protected by Federal copyright law. They may
8 not be disclosed to third parties or copied or duplicated in any form,
9 in whole or in part, without the prior written consent of Nintendo.
10
11 *---------------------------------------------------------------------------*/
12 // ------------------------------------------------------------------
13 // TexConvert.cpp
14 // ------------------------------------------------------------------
15 #include <stdio.h>
16 #include <string.h>
17 #include "ddsReader.h"
18 #include "tgaReader.h"
19 #include "TexConvert.h"
20
PrintSupportedDstFormats(void)21 void PrintSupportedDstFormats(void)
22 {
23 printf("Supported destination converted formats:\n");
24 printf(" GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM\n");
25 printf(" GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_SRGB\n");
26 printf(" GX2_SURFACE_FORMAT_T_BC1_UNORM\n");
27 printf(" GX2_SURFACE_FORMAT_T_BC1_SRGB\n");
28 printf(" GX2_SURFACE_FORMAT_T_BC2_UNORM\n");
29 printf(" GX2_SURFACE_FORMAT_T_BC2_SRGB\n");
30 printf(" GX2_SURFACE_FORMAT_T_BC3_UNORM\n");
31 printf(" GX2_SURFACE_FORMAT_T_BC3_SRGB\n");
32 printf(" GX2_SURFACE_FORMAT_T_BC4_UNORM\n");
33 printf(" GX2_SURFACE_FORMAT_T_BC4_SNORM\n");
34 printf(" GX2_SURFACE_FORMAT_T_BC5_UNORM\n");
35 printf(" GX2_SURFACE_FORMAT_T_BC5_SNORM\n");
36 printf(" GX2_SURFACE_FORMAT_TC_R8_UNORM\n");
37 printf(" GX2_SURFACE_FORMAT_TC_R8_G8_UNORM\n");
38
39 printf("\n");
40 printf("Supported source DDS formats for conversion:\n");
41 printf(" ARGB 8888\n");
42 printf(" ABGR 8888\n");
43 printf(" ABGR 32Float\n");
44
45 printf("\n");
46 printf("Supported source DDS formats for passthrough:\n");
47 printf(" ARGB 1555 -> GX2_SURFACE_FORMAT_TC_R5_G5_B5_A1_UNORM\n");
48 printf(" ABGR 2101010 -> GX2_SURFACE_FORMAT_TCS_R10_G10_B10_A2_UNORM\n");
49 printf(" ARGB 2101010 -> GX2_SURFACE_FORMAT_TCS_R10_G10_B10_A2_UNORM\n");
50 printf(" ARGB 4444 -> GX2_SURFACE_FORMAT_TC_R4_G4_B4_A4_UNORM\n");
51 printf(" ABGR 8888 -> GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM\n");
52 printf(" ARGB 8888 -> GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM\n");
53 printf(" ABGR 16161616 -> GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_UNORM\n");
54 printf(" ABGR 16Float -> GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_FLOAT\n");
55 printf(" ABGR 32Float -> GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_FLOAT\n");
56 printf(" RGB 565 -> GX2_SURFACE_FORMAT_TCS_R5_G6_B5_UNORM\n");
57 printf(" RGB 888 -> GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM\n");
58 printf(" XRGB 1555 -> GX2_SURFACE_FORMAT_TC_R5_G5_B5_A1_UNORM\n");
59 printf(" XRGB 4444 -> GX2_SURFACE_FORMAT_TC_R4_G4_B4_A4_UNORM\n");
60 printf(" XBGR 4444 -> GX2_SURFACE_FORMAT_TC_R4_G4_B4_A4_UNORM\n");
61 printf(" XBGR 8888 -> GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM\n");
62 printf(" XRGB 8888 -> GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM\n");
63 printf(" BC1 -> GX2_SURFACE_FORMAT_T_BC1_UNORM\n");
64 printf(" BC2 -> GX2_SURFACE_FORMAT_T_BC2_UNORM\n");
65 printf(" BC3 -> GX2_SURFACE_FORMAT_T_BC3_UNORM\n");
66 printf(" BC4 -> GX2_SURFACE_FORMAT_T_BC4_UNORM\n");
67 printf(" BC5 -> GX2_SURFACE_FORMAT_T_BC5_UNORM\n");
68 printf("\n");
69 printf("(Any necessary component reordering is done during input)\n");
70
71 printf("\n");
72 printf("Supported source GTX format file inputs for converting to DDS:\n");
73 printf(" GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_FLOAT -> ABGR 32F\n");
74 printf(" GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_UNORM -> ABGR 16161616\n");
75 printf(" GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_FLOAT -> ABGR 16F\n");
76 printf(" GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM -> ABGR 8888\n");
77 printf(" GX2_SURFACE_FORMAT_TCS_R10_G10_B10_A2_UNORM -> ABGR 2101010\n");
78 printf(" GX2_SURFACE_FORMAT_TCS_R5_G6_B5_UNORM -> RGB 565\n");
79 printf(" GX2_SURFACE_FORMAT_TC_R5_G5_B5_A1_UNORM -> XRGB 1555\n");
80 printf(" GX2_SURFACE_FORMAT_TC_R4_G4_B4_A4_UNORM -> XRGB 4444\n");
81 printf(" GX2_SURFACE_FORMAT_TC_R8_UNORM -> L8\n");
82 printf(" GX2_SURFACE_FORMAT_T_BC1_UNORM -> BC1\n");
83 printf(" GX2_SURFACE_FORMAT_T_BC2_UNORM -> BC2\n");
84 printf(" GX2_SURFACE_FORMAT_T_BC3_UNORM -> BC3\n");
85 printf(" GX2_SURFACE_FORMAT_T_BC4_UNORM -> BC4\n");
86 printf(" GX2_SURFACE_FORMAT_T_BC5_UNORM -> BC5\n");
87 printf("\n");
88 printf("(Any necessary component reordering is done during input.It does not guarantee data consistency between input file and output file.)\n");
89 }
90
PrintUsageMessage(void)91 void PrintUsageMessage(void)
92 {
93 // 1 2 3 4 5 6 7
94 //345678901234567890123456789012345678901234567890123456789012345678901234567890
95 printf("\
96 Example command line params (to .gtx):\n\
97 -i texture1.dds(.tga) -i texture2.dds(.tga) -o out.gtx -texturearray\n\
98 -mipFilter box -minmip 1 -f GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM\n\
99 -tileMode GX2_TILE_MODE_DEFAULT -swizzle 1\n\
100 \n\
101 Example command line params (to .dds):\n\
102 -i texturebin.gtx -o out.dds -printinfo\n\
103 \n\
104 -i <SrcFile> : Source image file. This can appear more than once on the\n\
105 command line for texture arrays or when creating multiple\n\
106 textures in one gtx file. Maximum source file count is %d.\n\
107 When source file is gtx file, only the first gtx file is converted to dds.\n\
108 -o <DstFile> : Destination texture binary file (default: out.gtx)\n\
109 -oa <DstFile> : Destination existing texture binary file to append textures.\n\
110 -f <DstFmt> : Destination texture format (default: if not specified,\n\
111 a destination format is chosen based on the source format)\n\
112 -mipFilter <mode> : Mip filter for generating mips (only \"box\" supported now)\n\
113 -minmip <N> : Minimum mipmap size (ie, generate until dimensions <= NxN)\n\
114 -swizzle <N> : Swizzle value (refer to GX2 Texture documentation)\n\
115 -tileMode <mode> : Tile mode (default: GX2_TILE_MODE_DEFAULT)\n\
116 -texarray_from_src : Creates a texture array from the source textures.\n\
117 Source textures should have the same dimensions.\n\
118 -mips_from_src : Creates mips from the source textures. The order of the\n\
119 source textures on the command line should be the desired\n\
120 order of the mip levels: src_1 = lvl_0, src_2 = lvl_1, etc.\n\
121 Note: This option cannot be used with texarray_from_src.\n\
122 -align : Adds alignment padding blocks between the header & image.\n\
123 The amount of padding depends upon hardware requirements.\n\
124 -weightingRed <N> : The weighting of the Red or X Channel in BC1/2/3 compression.\n\
125 The default value is 1.0.\n\
126 -weightingGreen <N> : The weighting of the Green or Y Channel in BC1/2/3 compression.\n\
127 The default value is 1.0.\n\
128 -weightingBlue <N> : The weighting of the Blue or Z Channel in BC1/2/3 compression.\n\
129 The default value is 1.0.\n\
130 -bc1alpha <N> : Sets alpha threshold to use when converting to BC1 format.\n\
131 Texels with alpha < N will be considered transparent.\n\
132 The default value is 127. Use N=0 to disable alpha.\n\
133 -valuetype <type> : Treats input texture's value as specified type.\n\
134 (type = unorm or snorm)(default: unorm)\n\
135 -gbtilingconfig <N> : Value to use in tiling config register (HW debugging only)\n\
136 -printinfo : Print out useful information about the resulting textures.\n\
137 -endianbugfix : Performs 8-in-32 byte swap on the output texture data.\n\
138 This is a bug workaround for the prototype hardware.\n\
139 Also need to set this option to convert from endianbugfixed gtx file to dds.\n\
140 -supported : List supported output texture formats.\n\
141 -? : Show this usage message.\n", MAX_INPUTFILE_COUNT);
142 return;
143 }
144
PrintCommandLine(s32 argc,char ** argv)145 void PrintCommandLine(s32 argc, char** argv)
146 {
147 for (s32 count = 0; count < argc; count++)
148 {
149 printf("%s ", argv[count]);
150 }
151 }
152
LoadDLLs(HMODULE * hTexUtilDLL,TC2Func * fpTC2,HMODULE * hGfdDLL,GFDFunc * fpGFD)153 void LoadDLLs(HMODULE *hTexUtilDLL, TC2Func *fpTC2, HMODULE *hGfdDLL, GFDFunc *fpGFD)
154 {
155 // Load DLL
156 *hTexUtilDLL = LoadLibrary(LIB_DLL_TEXUTILS);
157 if ( !*hTexUtilDLL )
158 {
159 printf("Failed to load DLL %ws. Exiting.", LIB_DLL_TEXUTILS);
160 FreeLibrary(*hTexUtilDLL);
161 exit(1);
162 }
163
164 *hGfdDLL = LoadLibrary(LIB_DLL_GFD);
165 if ( !*hGfdDLL )
166 {
167 printf("Failed to load DLL %ws. Exiting.", LIB_DLL_GFD);
168 FreeLibrary(*hGfdDLL);
169 exit(1);
170 }
171
172 // Get functions
173 fpTC2->Initialize = reinterpret_cast<PTC2Initialize>(GetProcAddress(*hTexUtilDLL, "TC2Initialize"));
174 fpTC2->Destroy = reinterpret_cast<PTC2Destroy>(GetProcAddress(*hTexUtilDLL, "TC2Destroy"));
175 fpTC2->GX2SurfaceFormatFromStr = reinterpret_cast<PTC2GX2SurfaceFormatFromStr>(GetProcAddress(*hTexUtilDLL, "TC2GX2SurfaceFormatFromStr"));
176 fpTC2->GenerateMipLevels = reinterpret_cast<PTC2GenerateMipLevels>(GetProcAddress(*hTexUtilDLL, "TC2GenerateMipLevels"));
177 fpTC2->ConvertSurfaceFormat = reinterpret_cast<PTC2ConvertSurfaceFormat>(GetProcAddress(*hTexUtilDLL, "TC2ConvertSurfaceFormat"));
178 fpTC2->ConvertTiling = reinterpret_cast<PTC2ConvertTiling>(GetProcAddress(*hTexUtilDLL, "TC2ConvertTiling"));
179 fpTC2->DestroyGX2Surface = reinterpret_cast<PTC2DestroyGX2Surface>(GetProcAddress(*hTexUtilDLL, "TC2DestroyGX2Surface"));
180 fpTC2->GenerateTexture = reinterpret_cast<PTC2GenerateTexture>(GetProcAddress(*hTexUtilDLL, "TC2GenerateTexture"));
181 fpTC2->DestroyGX2Texture = reinterpret_cast<PTC2DestroyGX2Texture>(GetProcAddress(*hTexUtilDLL, "TC2DestroyGX2Texture"));
182 fpTC2->ConvertStringToTileMode = reinterpret_cast<PTC2ConvertStringToTileMode>(GetProcAddress(*hTexUtilDLL, "TC2ConvertStringToTileMode"));
183 fpTC2->GetSourceSurfaceSize = reinterpret_cast<PTC2GetSourceSurfaceSize>(GetProcAddress(*hTexUtilDLL, "TC2GetSourceSurfaceSize"));
184 fpTC2->CombineAsTextureArray = reinterpret_cast<PTC2CombineAsTextureArray>(GetProcAddress(*hTexUtilDLL, "TC2CombineAsTextureArray"));
185 fpTC2->CombineAsMips = reinterpret_cast<PTC2CombineAsMips>(GetProcAddress(*hTexUtilDLL, "TC2CombineAsMips"));
186
187 fpGFD->WriteFileTexture = reinterpret_cast<PGFDWriteFileTexture>(GetProcAddress(*hGfdDLL, "GFDWriteFileTexture"));
188 fpGFD->AppendWriteFileTexture = reinterpret_cast<PGFDAppendWriteFileTexture>(GetProcAddress(*hGfdDLL, "GFDAppendWriteFileTexture"));
189 fpGFD->ReadFileTexture = reinterpret_cast<PGFDReadFileTexture>(GetProcAddress(*hGfdDLL, "GFDReadFileTexture"));
190 fpGFD->FreeFileTexture = reinterpret_cast<PGFDFreeFileTexture>(GetProcAddress(*hGfdDLL, "GFDFreeFileTexture"));
191 }
192
FreeDLLs(HMODULE * hTexUtilDLL,HMODULE * hGfdDLL)193 void FreeDLLs(HMODULE *hTexUtilDLL, HMODULE *hGfdDLL)
194 {
195 FreeLibrary(*hTexUtilDLL);
196 FreeLibrary(*hGfdDLL);
197 }
198
199 // Convert GX2SurfaceFormat strings to text
FormatTypeToString(GX2SurfaceFormat eSurfaceFormat)200 char * FormatTypeToString(GX2SurfaceFormat eSurfaceFormat)
201 {
202 // Magic macro - Creates: 'case x: "x"'
203 #define A(x) case x: return #x
204
205 switch(eSurfaceFormat)
206 {
207 default:
208 A(GX2_SURFACE_FORMAT_INVALID);
209 A(GX2_SURFACE_FORMAT_TC_R8_UNORM);
210 A(GX2_SURFACE_FORMAT_TC_R8_UINT);
211 A(GX2_SURFACE_FORMAT_TC_R8_SNORM);
212 A(GX2_SURFACE_FORMAT_TC_R8_SINT);
213 A(GX2_SURFACE_FORMAT_T_R4_G4_UNORM);
214 A(GX2_SURFACE_FORMAT_TCD_R16_UNORM);
215 A(GX2_SURFACE_FORMAT_TC_R16_UINT );
216 A(GX2_SURFACE_FORMAT_TC_R16_SNORM);
217 A(GX2_SURFACE_FORMAT_TC_R16_SINT);
218 A(GX2_SURFACE_FORMAT_TC_R16_FLOAT);
219 A(GX2_SURFACE_FORMAT_TC_R8_G8_UNORM);
220 A(GX2_SURFACE_FORMAT_TC_R8_G8_UINT);
221 A(GX2_SURFACE_FORMAT_TC_R8_G8_SNORM);
222 A(GX2_SURFACE_FORMAT_TC_R8_G8_SINT );
223 A(GX2_SURFACE_FORMAT_TCS_R5_G6_B5_UNORM );
224 A(GX2_SURFACE_FORMAT_TC_A1_B5_G5_R5_UNORM);
225 A(GX2_SURFACE_FORMAT_TC_R4_G4_B4_A4_UNORM);
226 A(GX2_SURFACE_FORMAT_TC_R5_G5_B5_A1_UNORM );
227 A(GX2_SURFACE_FORMAT_TC_R32_UINT);
228 A(GX2_SURFACE_FORMAT_TC_R32_SINT);
229 A(GX2_SURFACE_FORMAT_TCD_R32_FLOAT);
230 A(GX2_SURFACE_FORMAT_TC_R16_G16_UNORM);
231 A(GX2_SURFACE_FORMAT_TC_R16_G16_UINT );
232 A(GX2_SURFACE_FORMAT_TC_R16_G16_SNORM);
233 A(GX2_SURFACE_FORMAT_TC_R16_G16_SINT);
234 A(GX2_SURFACE_FORMAT_TC_R16_G16_FLOAT);
235 A(GX2_SURFACE_FORMAT_D_D24_S8_UNORM);
236 // A(GX2_SURFACE_FORMAT_TC_24_8_UNORM); // dup of above
237 A(GX2_SURFACE_FORMAT_TC_R11_G11_B10_FLOAT);
238 A(GX2_SURFACE_FORMAT_TCS_A2_B10_G10_R10_UNORM);
239 A(GX2_SURFACE_FORMAT_TC_A2_B10_G10_R10_UINT);
240 A(GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM);
241 A(GX2_SURFACE_FORMAT_TC_R8_G8_B8_A8_UINT);
242 A(GX2_SURFACE_FORMAT_TC_R8_G8_B8_A8_SNORM);
243 A(GX2_SURFACE_FORMAT_TC_R8_G8_B8_A8_SINT);
244 A(GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_SRGB);
245 A(GX2_SURFACE_FORMAT_TCS_R10_G10_B10_A2_UNORM);
246 A(GX2_SURFACE_FORMAT_TC_R10_G10_B10_A2_UINT);
247 A(GX2_SURFACE_FORMAT_D_D32_FLOAT_S8_UINT_X24);
248 // A(GX2_SURFACE_FORMAT_T_R32_FLOAT_X8_X24); // dup of above
249 A(GX2_SURFACE_FORMAT_T_X32_G8_UINT_X24);
250 A(GX2_SURFACE_FORMAT_TC_R32_G32_UINT);
251 A(GX2_SURFACE_FORMAT_TC_R32_G32_SINT);
252 A(GX2_SURFACE_FORMAT_TC_R32_G32_FLOAT);
253 A(GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_UNORM );
254 A(GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_UINT );
255 A(GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_SNORM );
256 A(GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_SINT );
257 A(GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_FLOAT );
258 A(GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_UINT );
259 A(GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_SINT );
260 A(GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_FLOAT );
261 A(GX2_SURFACE_FORMAT_T_BC1_UNORM);
262 A(GX2_SURFACE_FORMAT_T_BC1_SRGB);
263 A(GX2_SURFACE_FORMAT_T_BC2_UNORM);
264 A(GX2_SURFACE_FORMAT_T_BC2_SRGB);
265 A(GX2_SURFACE_FORMAT_T_BC3_UNORM);
266 A(GX2_SURFACE_FORMAT_T_BC3_SRGB );
267 A(GX2_SURFACE_FORMAT_T_BC4_UNORM );
268 A(GX2_SURFACE_FORMAT_T_BC4_SNORM );
269 A(GX2_SURFACE_FORMAT_T_BC5_UNORM );
270 A(GX2_SURFACE_FORMAT_T_BC5_SNORM );
271 }
272 }
273
FormatsMatch(const char * pFormatStr,GX2SurfaceFormat otherFormat)274 bool FormatsMatch(const char* pFormatStr, GX2SurfaceFormat otherFormat )
275 {
276 const char* pOtherStr = FormatTypeToString( otherFormat );
277 if(0 == strcmp(pOtherStr, pFormatStr))
278 {
279 return( true );
280 }
281
282 // Some formats may be interchangeable
283 for( int i = GX2_SURFACE_FORMAT_FIRST; i <= GX2_SURFACE_FORMAT_LAST; ++i )
284 {
285 if(0 == strcmp(pFormatStr, FormatTypeToString((GX2SurfaceFormat)i)))
286 {
287 switch((GX2SurfaceFormat)i)
288 {
289 case GX2_SURFACE_FORMAT_TC_A1_B5_G5_R5_UNORM: return( otherFormat == GX2_SURFACE_FORMAT_TC_R5_G5_B5_A1_UNORM );
290 case GX2_SURFACE_FORMAT_TC_R5_G5_B5_A1_UNORM: return( otherFormat == GX2_SURFACE_FORMAT_TC_A1_B5_G5_R5_UNORM );
291 // case GX2_SURFACE_FORMAT_TC_R5_G5_B5_UNORM: return( otherFormat == GX2_SURFACE_FORMAT_TC_A1_B5_G5_R5_UNORM );
292 }
293 break;
294 }
295 }
296
297 return( false );
298 }
299
300 // Convert path to file
PathToFileName(char * pPath)301 char *PathToFileName(char *pPath)
302 {
303 for(char *p = strchr(pPath, '\0' ); p >= pPath; p--)
304 {
305 if (('\\'==*p) || ('/'==*p))
306 return p + 1;
307 }
308 return (char *)pPath;
309 }
310
PrintTextureFileInfo(AppConfig * pConfig)311 void PrintTextureFileInfo(AppConfig *pConfig)
312 {
313 // print information
314 if(pConfig->printinfo)
315 {
316 printf("// ----- File Format Info ----- \n");
317 printf(" fileName = %s\n", PathToFileName(pConfig->outFileName));
318 printf(" indexCount = %d\n", pConfig->inFileCount);
319 printf(" alignMode = %d\n", pConfig->alignMode);
320 printf(" endianMode = %d\n", pConfig->endianbugfix);
321 printf(" BC1Alpha = %d\n", pConfig->bc1alphathreshold);
322 printf(" GBTilingCfg = 0x%X\n", pConfig->gbtilingconfig);
323 }
324 }
325
PrintTextureSurfaceInfo(bool printinfo,u32 id,GX2Texture * pGx2Textures)326 void PrintTextureSurfaceInfo(bool printinfo, u32 id, GX2Texture *pGx2Textures)
327 {
328 // print information
329 if(printinfo)
330 {
331 printf("// ----- GX2Surface Info ----- \n");
332 printf(" index = %d \n", id);
333 printf(" dim = %d\n", pGx2Textures->surface.dim);
334 printf(" width = %d\n", pGx2Textures->surface.width);
335 printf(" height = %d\n", pGx2Textures->surface.height);
336 printf(" depth = %d\n", pGx2Textures->surface.depth);
337 printf(" numMips = %d\n", pGx2Textures->surface.numMips);
338 printf(" format = %s\n", FormatTypeToString(pGx2Textures->surface.format));
339 printf(" aa = %d\n", pGx2Textures->surface.aa);
340 printf(" use = %d\n", pGx2Textures->surface.use);
341 printf(" imageSize = %d\n", pGx2Textures->surface.imageSize);
342 printf(" mipSize = %d\n", pGx2Textures->surface.mipSize);
343 printf(" tileMode = %d\n", pGx2Textures->surface.tileMode);
344 printf(" swizzle = %d, 0x%X\n", pGx2Textures->surface.swizzle, pGx2Textures->surface.swizzle);
345 printf(" alignment = %d\n", pGx2Textures->surface.alignment);
346 printf(" pitch = %d\n", pGx2Textures->surface.pitch);
347 printf(" mipOffset = %d\n", pGx2Textures->surface.mipOffset);
348 }
349 }
350
InitializeConfig(s32 argc,char ** argv,AppConfig * pConfig)351 bool InitializeConfig(s32 argc, char** argv, AppConfig* pConfig)
352 {
353 s32 count = 0;
354
355 memset(pConfig, 0, sizeof(*pConfig));
356
357 //setup default values
358 strcpy_s(pConfig->dstFormat, DSTFORMAT_DEFAULT);
359 strcpy_s(pConfig->tileMode, TILEMODE_DEFAULT);
360
361 pConfig->gpu = GPU_DEFAULT;
362 pConfig->minMipSize = MINMIPSIZE_DEFAULT;
363 pConfig->mipFilter = MIPFILTER_DEFAULT;
364 pConfig->outFileName = NULL;
365 pConfig->inFileCount = INFILECOUNT_DEFAULT;
366 pConfig->textureArray = TEXTUREARRAY_DEFAULT;
367 pConfig->mipsFromSrc = MIPFROMSOURCE_DEFAULT;
368 pConfig->alignMode = ALIGNMODE_DEFAULT;
369 pConfig->appendMode = APPENDMODE_DEFAULT;
370 pConfig->endianbugfix = ENDIANBUGFIX_DEFAULT;
371 pConfig->initialSwizzle = INITIALSWIZZLE_DEFAULT;
372 pConfig->gbtilingconfig = GBTILINGCONFIG_DEFAULT;
373 pConfig->valuetype = VALUETYPE_DEFAULT;
374 pConfig->useWeighting = USEWEIGHTING_DEFAULT;
375 pConfig->weightingRed = WEIGHTINGRED_DEFAULT;
376 pConfig->weightingGreen = WEIGHTINGGREEN_DEFAULT;
377 pConfig->weightingBlue = WEIGHTINGBLUE_DEFAULT;
378 pConfig->useAdaptiveWeighting = USEADAPTIVEWEIGHTING_DEFAULT;
379
380 pConfig->bc1usealpha = BC1USEALPHA_DEFAULT;
381 pConfig->bc1alphathreshold = BC1ALPHATHRESHOLD_DEFAULT;
382 pConfig->printinfo = PRINTINFO_DEFAULT;
383
384 pConfig->fix2197 = false;
385
386 for (count = 0; count < argc; count++)
387 {
388 if (!strcmp(argv[count], "-tileMode"))
389 {
390 if ((count + 1) < argc)
391 {
392 strcpy_s(pConfig->tileMode, argv[count + 1]);
393 count++;
394 }
395 }
396 else if (!strcmp(argv[count], "-gpu"))
397 {
398 if ((count + 1) < argc)
399 {
400 switch(atoi(argv[count + 1]))
401 {
402 case 0:
403 pConfig->gpu = GPU_V1;
404 break;
405 case 1:
406 pConfig->gpu = GPU_V2;
407 break;
408 case 2:
409 pConfig->gpu = GPU_Cafe;
410 break;
411 default:
412 printf("Error: Unsupported GPU version\n");
413 exit(1);
414 break;
415 }
416 count++;
417 }
418 }
419 // -i source filename
420 else if (!strcmp(argv[count], "-i"))
421 {
422 if ((count + 1) < argc)
423 {
424 pConfig->inFileName[pConfig->inFileCount++] = argv[count + 1];
425
426 if (pConfig->inFileCount > MAX_INPUTFILE_COUNT)
427 {
428 printf("Exceeded maximum input file count of %d. Exiting.\n", MAX_INPUTFILE_COUNT);
429 exit(1);
430 }
431
432 count++;
433 }
434 }
435 // -o destination filename
436 else if (!strcmp(argv[count], "-o"))
437 {
438 if ((count + 1) < argc)
439 {
440 pConfig->outFileName = argv[count + 1];
441 count++;
442 }
443 }
444 else if (!strcmp(argv[count], "-oa"))
445 {
446 if ((count + 1) < argc)
447 {
448 pConfig->outFileName = argv[count + 1];
449 pConfig->appendMode = true;
450 count++;
451 }
452 }
453 else if (!strcmp(argv[count], "-mipFilter"))
454 {
455 if ((count + 1) < argc)
456 {
457 if (!strcmp(argv[count + 1], "box"))
458 {
459 pConfig->mipFilter = MF_BOX;
460 }
461 else
462 {
463 printf("Error: Unsupported mip filter mode\n");
464 exit(1);
465 }
466 count++;
467 }
468 }
469 // -minmip minimum mip size
470 else if (!strcmp(argv[count], "-minmip"))
471 {
472 if ((count + 1) < argc)
473 {
474 pConfig->minMipSize = atoi(argv[count + 1]);
475 count++;
476 }
477 }
478 else if (!strcmp(argv[count], "-swizzle"))
479 {
480 if ((count + 1) < argc)
481 {
482 if((argv[count + 1][0] == '0') &&
483 (argv[count + 1][1] == 'x'))
484 {
485 sscanf_s(argv[count + 1],"0x%X", &pConfig->initialSwizzle);
486 }
487 else
488 {
489 pConfig->initialSwizzle = atoi(argv[count + 1]);
490 }
491 count++;
492 }
493 }
494 // -f destination format
495 else if (!strcmp(argv[count], "-f"))
496 {
497 if ((count + 1) < argc)
498 {
499 strcpy_s(pConfig->dstFormat, argv[count + 1]);
500 count++;
501 }
502 }
503 else if (!strcmp(argv[count], "-gbtilingconfig"))
504 {
505 if ((count + 1) < argc)
506 {
507 if((argv[count + 1][0] == '0') &&
508 (argv[count + 1][1] == 'x'))
509 {
510 sscanf_s(argv[count + 1],"0x%X", &pConfig->gbtilingconfig);
511 }
512 else
513 {
514 pConfig->gbtilingconfig = atoi(argv[count + 1]);
515 }
516 count++;
517 }
518 }
519 else if (!strcmp(argv[count], "-valuetype"))
520 {
521 if ((count + 1) < argc)
522 {
523 if (!strcmp(argv[count + 1], "snorm"))
524 {
525 pConfig->valuetype = VT_SNORM;
526 }
527 else
528 {
529 pConfig->valuetype = VT_UNORM;
530 }
531 count++;
532 }
533 }
534 else if (!strcmp(argv[count], "-bc1alpha"))
535 {
536 if ((count + 1) < argc)
537 {
538 pConfig->bc1alphathreshold = atoi(argv[count + 1]);
539 pConfig->bc1usealpha = (pConfig->bc1alphathreshold > 0);
540 count++;
541 }
542 }
543 else if (!strcmp(argv[count], "-weightingRed"))
544 {
545 if ((count + 1) < argc)
546 {
547 pConfig->weightingRed = atof(argv[count + 1]);
548 pConfig->useWeighting = (pConfig->weightingRed != 1.0);
549 count++;
550 }
551 }
552 else if (!strcmp(argv[count], "-weightingGreen"))
553 {
554 if ((count + 1) < argc)
555 {
556 pConfig->weightingGreen = atof(argv[count + 1]);
557 pConfig->useWeighting = (pConfig->weightingGreen != 1.0);
558 count++;
559 }
560 }
561 else if (!strcmp(argv[count], "-weightingBlue"))
562 {
563 if ((count + 1) < argc)
564 {
565 pConfig->weightingBlue = atof(argv[count + 1]);
566 pConfig->useWeighting = (pConfig->weightingBlue != 1.0);
567 count++;
568 }
569 }
570 else if (!strcmp(argv[count], "-texarray_from_src"))
571 {
572 if (pConfig->mipsFromSrc)
573 {
574 printf("Error: Cannot use -texarray_from_src with -mips_from_src.\n");
575 exit(1);
576 }
577 pConfig->textureArray = true;
578 }
579 else if (!strcmp(argv[count], "-mips_from_src"))
580 {
581 if (pConfig->textureArray)
582 {
583 printf("Error: Cannot use -mips_from_src with -texarray_from_src.\n");
584 exit(1);
585 }
586 pConfig->mipsFromSrc = true;
587 pConfig->minMipSize = 0;
588 pConfig->mipFilter = MF_NONE;
589 }
590 else if (!strcmp(argv[count], "-align"))
591 {
592 pConfig->alignMode = true;
593 }
594 else if (!strcmp(argv[count], "-endianbugfix"))
595 {
596 pConfig->endianbugfix = true;
597 }
598 // -? or -help print help
599 else if (!strcmp(argv[count], "-?") || !strcmp(argv[count], "-help"))
600 {
601 PrintUsageMessage();
602 exit(0);
603 }
604 // -supported
605 else if (!strcmp(argv[count], "-supported"))
606 {
607 PrintSupportedDstFormats();
608 exit(0);
609 }
610 else if (!strcmp(argv[count], "-printinfo"))
611 {
612 pConfig->printinfo = true;
613 }
614 // -fix2197
615 else if(!strcmp(argv[count], "-fix2197"))
616 {
617 pConfig->fix2197 = true;
618 }
619 else if (count != 0)
620 {
621 printf("Unrecognized command line parameter \"%s\". Exiting.", argv[count]);
622 exit(1);
623 }
624 }
625 assert(pConfig->minMipSize >= 0);
626
627 if ((pConfig->minMipSize > 0) && (pConfig->mipFilter == MF_NONE))
628 { // use the default in the case where user specifies a minMipSize but no filter mode
629 pConfig->mipFilter = MF_BOX;
630 }
631
632 // default to 1 when no minmip specified
633 if (pConfig->mipFilter != MF_NONE && pConfig->minMipSize < 1)
634 {
635 printf("Minimum mip size of one or more not specified. Setting minimum size to 1.\n");
636 pConfig->minMipSize = 1;
637 }
638
639 if (!pConfig->inFileCount)
640 {
641 return false;
642 }
643
644 if (pConfig->mipsFromSrc)
645 {
646 pConfig->minMipSize = 0;
647 pConfig->mipFilter = MF_NONE;
648 }
649
650 return true;
651 }
652
StrToLower(char * str)653 char* StrToLower (char *str)
654 {
655 char *p;
656
657 for (p = str; *p; p++)
658 {
659 *p = tolower(*p);
660 }
661 return (str);
662 }
663
SNORMToUNORM(GX2Surface * pInSurface)664 bool SNORMToUNORM(GX2Surface *pInSurface)
665 {
666 u32 i;
667 u32 count = 0;
668 u32 value = 0;
669 u32* pSurface = (u32*)pInSurface->imagePtr;
670
671 if (pInSurface->format == GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM)
672 {
673 // assuming dword aligned size so double check
674 u8* pSurface = (u8*)pInSurface->imagePtr;
675
676 for (count = 0; count < pInSurface->imageSize; count += 4)
677 {
678 for(i = 0; i < 4; i++)
679 {
680 s8 sv = (s8)*(pSurface + count + i) ;
681 u8 uv = (u8)((s32)sv + 128);
682 *(pSurface + count + i) = uv;
683 }
684 }
685 }
686 else
687 {
688 assert(0);
689 return false;
690 }
691
692 return true;
693 }
694
_tmain(s32 argc,char * argv[])695 s32 _tmain(s32 argc, char* argv[])
696 {
697 HMODULE hTexUtilDLL;
698 HMODULE hGfdDLL;
699 TC2Func fpTC2;
700 GFDFunc fpGFD;
701 TC2Config texConfig;
702 GX2TileMode tileMode;
703 AppConfig config;
704 u32 count = 0;
705 ExtensionType extType = ET_DDS;
706 GFDEndianSwapMode swapMode = GFD_ENDIAN_SWAP_MODE_DEFAULT;
707 GFDAlignMode alignMode = GFD_ALIGN_MODE_DISABLE;
708
709 TC2ConvertOptions convertOptions;
710 GX2Texture *pGx2Textures = NULL;
711 GX2Surface *pSrcTextures = NULL;
712 GX2Surface *pTiledTextures = NULL;
713 GX2Surface *pMipmapTextures = NULL;
714 GX2Surface **ppTexturesToConvert = NULL;
715 GX2Surface *pConvertedTextures = NULL;
716
717 // Loade DLLs
718 LoadDLLs(&hTexUtilDLL, &fpTC2, &hGfdDLL, &fpGFD);
719
720 if (!InitializeConfig(argc, argv, &config))
721 {
722 PrintUsageMessage();
723 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
724 return 1;
725 }
726
727 memset(&texConfig, 0, sizeof(texConfig));
728 texConfig.gbTilingConfig = config.gbtilingconfig;
729 texConfig.gpu = config.gpu;
730 texConfig.bugFix2197 = config.fix2197;
731
732 memset(&convertOptions, 0, sizeof(convertOptions));
733 convertOptions.useWeighting = config.useWeighting;
734 convertOptions.weightingRed = config.weightingRed;
735 convertOptions.weightingGreen = config.weightingGreen;
736 convertOptions.weightingBlue = config.weightingBlue;
737 convertOptions.useAdaptiveWeighting = config.useAdaptiveWeighting;
738
739 convertOptions.bc1usealpha = config.bc1usealpha;
740 convertOptions.bc1alphathreshold = config.bc1alphathreshold;
741 convertOptions.bc1alphathreshold = config.bc1alphathreshold;
742
743 pSrcTextures = (GX2Surface*)malloc(sizeof(*pSrcTextures) * config.inFileCount);
744 memset(pSrcTextures, 0, sizeof(*pSrcTextures) * config.inFileCount);
745
746 ppTexturesToConvert = (GX2Surface**)malloc(sizeof(*ppTexturesToConvert) * config.inFileCount);
747 memset(ppTexturesToConvert, 0, (sizeof(ppTexturesToConvert) * config.inFileCount));
748
749 if (config.mipFilter != MF_NONE && pSrcTextures[0].numMips < 2)
750 {
751 pMipmapTextures = (GX2Surface*)malloc(sizeof(*pMipmapTextures) * config.inFileCount);
752 memset(pMipmapTextures, 0, sizeof(*pMipmapTextures) * config.inFileCount);
753 }
754
755 pConvertedTextures = (GX2Surface*)malloc(sizeof(*pConvertedTextures) * config.inFileCount);
756 memset(pConvertedTextures, 0, sizeof(*pConvertedTextures) * config.inFileCount);
757
758 pTiledTextures = (GX2Surface*)malloc(sizeof(*pTiledTextures) * config.inFileCount);
759 memset(pTiledTextures, 0, sizeof(*pTiledTextures) * config.inFileCount);
760
761 // set align mode
762 if(config.alignMode)
763 {
764 alignMode = GFD_ALIGN_MODE_ENABLE;
765 }
766
767 // Reset endian swap mode for endian bug fix mode
768 if(config.endianbugfix)
769 {
770 swapMode = GFD_ENDIAN_SWAP_MODE_8_IN_32;
771 }
772
773 if (!fpTC2.Initialize(&texConfig))
774 {
775 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
776 return 1;
777 }
778
779 if (!fpTC2.ConvertStringToTileMode(config.tileMode, &tileMode))
780 {
781 printf("Error: Unsupported tileMode.");
782 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
783 return 1;
784 }
785
786 for (count = 0; count < config.inFileCount; count++)
787 {
788 GX2SurfaceFormat dstFormat;
789
790 // read in TGA texture
791 if (strstr(StrToLower(config.inFileName[count]), ".tga"))
792 {
793 extType = ET_TGA;
794 if (config.outFileName == NULL)
795 {
796 config.outFileName = DEFAULT_GTX_FILENAME;
797 }
798 if (!TGAReader::TGALoadFile(config.inFileName[count], &pSrcTextures[count]))
799 {
800 printf("Error loading TGA file. Exiting.\n");
801 fpTC2.Destroy();
802 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
803 return 2;
804 }
805 }
806 // read in DDS texture
807 else if (strstr(StrToLower(config.inFileName[count]), ".dds"))
808 {
809 extType = ET_DDS;
810 if (config.outFileName == NULL)
811 {
812 config.outFileName = DEFAULT_GTX_FILENAME;
813 }
814 if (!DDSReader::DDSLoadFile(config.inFileName[count], &pSrcTextures[count]))
815 {
816 printf("Error loading DDS file. Exiting.\n");
817 fpTC2.Destroy();
818 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
819 return 3;
820 }
821 }
822 // read in GTX texture
823 else if (strstr(StrToLower(config.inFileName[count]), ".gtx"))
824 {
825 FILE* pFile = NULL;
826 GX2Texture gx2Texture;
827 GX2Surface retiledSurface;
828 GFDEndianSwapMode endianSwapMode = GFD_ENDIAN_SWAP_MODE_DEFAULT;
829
830 int id = 0;
831 extType = ET_GTX;
832
833 if(config.endianbugfix)
834 endianSwapMode = GFD_ENDIAN_SWAP_MODE_8_IN_32;
835
836 if (config.outFileName == NULL)
837 {
838 config.outFileName = DEFAULT_DDS_FILENAME;
839 }
840
841 if(!fpGFD.ReadFileTexture(&gx2Texture, (GFDGPUVersion)config.gpu, endianSwapMode, config.inFileName[count]))
842 {
843 printf("Error loading GTX file. Exiting.\n");
844 fpTC2.Destroy();
845 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
846 return 3;
847 }
848
849 // Print input config
850 //PrintTextureFileInfo(&config);
851
852 // Print Information (ID == 0)
853 PrintTextureSurfaceInfo(config.printinfo, 0, &gx2Texture);
854
855 // retile and store in texture object
856 if (!fpTC2.ConvertTiling(&gx2Texture.surface, GX2_TILE_MODE_LINEAR_SPECIAL, 0, &retiledSurface))
857 {
858 printf("Error converting tiling. Exiting.\n");
859 fpGFD.FreeFileTexture(&gx2Texture);
860 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
861 return 18;
862 }
863
864 if (strstr(StrToLower(config.outFileName), ".dds"))
865 {
866 // Save Texture as DDS file
867 if (!DDSReader::DDSSaveFile(config.outFileName, &retiledSurface))
868 {
869 printf("Error input format %s doesn't supported in DDS file format. Exiting.\n", FormatTypeToString(retiledSurface.format));
870 fpGFD.FreeFileTexture(&gx2Texture);
871 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
872 return 19;
873 }
874
875 fpGFD.FreeFileTexture(&gx2Texture);
876 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
877 return 0;
878 }
879 else
880 {
881 memcpy(&pSrcTextures[count], &retiledSurface, sizeof(GX2Surface));
882 }
883 }
884 else
885 {
886 printf("Unrecognized texture file type.\n");
887 fpTC2.Destroy();
888 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
889 return 3;
890 }
891
892 // convert snorm to unorm
893 if (config.valuetype == VT_SNORM)
894 {
895 if (!SNORMToUNORM(&pSrcTextures[count]))
896 {
897 printf("Error converting snorm to unorm. Exiting.\n");
898 fpTC2.Destroy();
899 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
900 return 4;
901 }
902 }
903
904 // generate mipmaps if necessary
905 if (config.mipFilter != MF_NONE && pSrcTextures[count].numMips < 2)
906 {
907 if (!fpTC2.GenerateMipLevels(&pSrcTextures[count], config.minMipSize, MF_BOX, &pMipmapTextures[count]))
908 {
909 printf("Error generating mips. Exiting.\n");
910 fpTC2.Destroy();
911 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
912 return 4;
913 }
914
915 ppTexturesToConvert[count] = &pMipmapTextures[count];
916 }
917 else
918 {
919 ppTexturesToConvert[count] = &pSrcTextures[count];
920 }
921
922 // make the destination format to match the source format if it was not specified on the command line (passthrough mode)
923 // likewise if the format was specified, but matches the texture format, no conversion is necessary
924 if (!strcmp(config.dstFormat, DSTFORMAT_DEFAULT) || FormatsMatch(config.dstFormat, ppTexturesToConvert[count]->format ) )
925 {
926 dstFormat = ppTexturesToConvert[count]->format;
927 }
928 else if (!fpTC2.GX2SurfaceFormatFromStr(config.dstFormat, &dstFormat))
929 {
930 printf("Error: Unsupported destination format. (%s)\n", argv[count + 1]);
931 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
932 return 1;
933 }
934
935 // convert surface to destination format
936 if (!fpTC2.ConvertSurfaceFormat(ppTexturesToConvert[count], dstFormat, &pConvertedTextures[count], &convertOptions))
937 {
938 printf("Error converting to destination format. Exiting.\n");
939 fpTC2.Destroy();
940 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
941 return 5;
942 }
943 }
944
945 if (config.textureArray)
946 {
947 GX2Surface texArray;
948 memset(&texArray, 0, sizeof(texArray));
949
950 fpTC2.CombineAsTextureArray(pConvertedTextures, config.inFileCount, &texArray);
951
952 pGx2Textures = (GX2Texture*)malloc(sizeof(*pGx2Textures));
953 memset(pGx2Textures, 0, sizeof(*pGx2Textures));
954
955 // tile and store in texture object
956 if (!fpTC2.ConvertTiling(&texArray, tileMode, config.initialSwizzle, pTiledTextures))
957 {
958 printf("Error converting tiling. Exiting.\n");
959 fpTC2.Destroy();
960 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
961 return 6;
962 }
963
964 // generate a texture
965 if (!fpTC2.GenerateTexture(pTiledTextures, pGx2Textures))
966 {
967 printf("Error generating texture. Exiting.\n");
968 fpTC2.Destroy();
969 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
970 return 7;
971 }
972
973 if(config.appendMode)
974 {
975 // append textures to gtx file
976 if(!fpGFD.AppendWriteFileTexture(config.outFileName, (GFDGPUVersion)config.gpu, swapMode, alignMode, 1, pGx2Textures))
977 {
978 printf("Error writing texture to file. Exiting.\n");
979 fpTC2.Destroy();
980 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
981 return 8;
982 }
983 }
984 else
985 {
986 // write gtx file
987 if(!fpGFD.WriteFileTexture(config.outFileName, (GFDGPUVersion)config.gpu, swapMode, alignMode, 1, pGx2Textures))
988 {
989 printf("Error writing texture to file. Exiting.\n");
990 fpTC2.Destroy();
991 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
992 return 8;
993 }
994 }
995
996 // print information
997 PrintTextureFileInfo(&config);
998 PrintTextureSurfaceInfo(config.printinfo, 0, pGx2Textures);
999
1000 fpTC2.DestroyGX2Texture(pGx2Textures);
1001 free(pGx2Textures);
1002 }
1003 else if (config.mipsFromSrc)
1004 {
1005 GX2Surface mipSurface;
1006 memset(&mipSurface, 0, sizeof(mipSurface));
1007
1008 fpTC2.CombineAsMips(pConvertedTextures, config.inFileCount, &mipSurface);
1009
1010 pGx2Textures = (GX2Texture*)malloc(sizeof(*pGx2Textures));
1011 memset(pGx2Textures, 0, sizeof(*pGx2Textures));
1012
1013 // tile and store in texture object
1014 if (!fpTC2.ConvertTiling(&mipSurface, tileMode, config.initialSwizzle, pTiledTextures))
1015 {
1016 printf("Error converting tiling. Exiting.\n");
1017 fpTC2.Destroy();
1018 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
1019 return 6;
1020 }
1021
1022 // generate a texture
1023 if (!fpTC2.GenerateTexture(pTiledTextures, pGx2Textures))
1024 {
1025 printf("Error generating texture. Exiting.\n");
1026 fpTC2.Destroy();
1027 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
1028 return 7;
1029 }
1030
1031 if(config.appendMode)
1032 {
1033 // append textures to gtx file
1034 if(!fpGFD.AppendWriteFileTexture(config.outFileName, (GFDGPUVersion)config.gpu, swapMode, alignMode, 1, pGx2Textures))
1035 {
1036 printf("Error writing texture to file. Exiting.\n");
1037 fpTC2.Destroy();
1038 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
1039 return 8;
1040 }
1041 }
1042 else
1043 {
1044 // write gtx file
1045 if(!fpGFD.WriteFileTexture(config.outFileName, (GFDGPUVersion)config.gpu, swapMode, alignMode, 1, pGx2Textures))
1046 {
1047 printf("Error writing texture to file. Exiting.\n");
1048 fpTC2.Destroy();
1049 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
1050 return 8;
1051 }
1052 }
1053 // print information
1054 PrintTextureFileInfo(&config);
1055 PrintTextureSurfaceInfo(config.printinfo, 0, pGx2Textures);
1056
1057 fpTC2.DestroyGX2Texture(pGx2Textures);
1058 free(pGx2Textures);
1059 }
1060 else
1061 {
1062 pGx2Textures = (GX2Texture*)malloc(sizeof(*pGx2Textures) * config.inFileCount);
1063 memset(pGx2Textures, 0, sizeof(*pGx2Textures) * config.inFileCount);
1064
1065 for (count = 0; count < config.inFileCount; count++)
1066 {
1067 // tile and store in texture object
1068 if (!fpTC2.ConvertTiling(&pConvertedTextures[count], tileMode, config.initialSwizzle, &pTiledTextures[count]))
1069 {
1070 printf("Error converting tiling. Exiting.\n");
1071 fpTC2.Destroy();
1072 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
1073 return 9;
1074 }
1075
1076 // generate a texture
1077 if (!fpTC2.GenerateTexture(&pTiledTextures[count], &pGx2Textures[count]))
1078 {
1079 printf("Error generating texture. Exiting.\n");
1080 fpTC2.Destroy();
1081 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
1082 return 10;
1083 }
1084 }
1085
1086 if(config.appendMode)
1087 {
1088 // append textures to gtx file
1089 if(!fpGFD.AppendWriteFileTexture(config.outFileName, (GFDGPUVersion)config.gpu, swapMode, alignMode, config.inFileCount, pGx2Textures))
1090 {
1091 printf("Error writing texture to file. Exiting.\n");
1092 fpTC2.Destroy();
1093 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
1094 return 11;
1095 }
1096 }
1097 else
1098 {
1099 // write gtx file
1100 if(!fpGFD.WriteFileTexture(config.outFileName, (GFDGPUVersion)config.gpu, swapMode, alignMode, config.inFileCount, pGx2Textures))
1101 {
1102 printf("Error writing texture to file. Exiting.\n");
1103 fpTC2.Destroy();
1104 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
1105 return 11;
1106 }
1107 }
1108
1109 // print information
1110 PrintTextureFileInfo(&config);
1111
1112 for (count = 0; count < config.inFileCount; count++)
1113 {
1114 // print information
1115 PrintTextureSurfaceInfo(config.printinfo, count, pGx2Textures);
1116 fpTC2.DestroyGX2Texture(&pGx2Textures[count]);
1117 }
1118 free(pGx2Textures);
1119 }
1120
1121 for (count = 0; count < config.inFileCount; count++)
1122 {
1123 if (config.mipFilter != MF_NONE && pSrcTextures[count].numMips < 2)
1124 {
1125 fpTC2.DestroyGX2Surface(&pMipmapTextures[count]);
1126 }
1127 if(extType == ET_DDS)
1128 {
1129 DDSReader::DDSFree(&pSrcTextures[count]);
1130 fpTC2.DestroyGX2Surface(&pSrcTextures[count]);
1131 fpTC2.DestroyGX2Surface(&pConvertedTextures[count]);
1132 }
1133 else if(extType == ET_TGA)
1134 {
1135 TGAReader::TGAFree(&pSrcTextures[count]);
1136 fpTC2.DestroyGX2Surface(&pSrcTextures[count]);
1137 fpTC2.DestroyGX2Surface(&pConvertedTextures[count]);
1138 }
1139
1140 if ((count == 0) || (!config.textureArray && !config.mipsFromSrc))
1141 {
1142 fpTC2.DestroyGX2Surface(&pTiledTextures[count]);
1143 }
1144 }
1145
1146 free(pSrcTextures);
1147 free(pConvertedTextures);
1148 free(pTiledTextures);
1149
1150 fpTC2.Destroy();
1151
1152 FreeDLLs(&hTexUtilDLL, &hGfdDLL);
1153
1154 return 0;
1155 }
1156