800 lines
18 KiB
C++
800 lines
18 KiB
C++
// TexPostCookWii.cpp : Defines the entry point for the console application.
|
|
//
|
|
#define _CRT_SECURE_NO_WARNINGS
|
|
|
|
#include "stdafx.h"
|
|
#include <stdio.h>
|
|
#include <iostream>
|
|
#include <fstream>
|
|
#include "./Squish/Squish.h"
|
|
//#include <Dds.h>
|
|
#include <ddraw.h>
|
|
|
|
using namespace std;
|
|
|
|
const char *strSourceFileName = 0;
|
|
const char *strDstFileName = 0;
|
|
bool g_rgbaNoCompressed = false;
|
|
|
|
typedef unsigned char u8;
|
|
typedef unsigned short u16;
|
|
typedef unsigned long u32;
|
|
|
|
struct ITF_DDSCAPS2
|
|
{
|
|
DWORD dwCaps;
|
|
DWORD dwCaps2;
|
|
DWORD Reserved[2];
|
|
};
|
|
|
|
struct ITF_DDPIXELFORMAT
|
|
{
|
|
DWORD dwSize;
|
|
DWORD dwFlags;
|
|
DWORD dwFourCC;
|
|
DWORD dwRGBBitCount;
|
|
DWORD dwRBitMask;
|
|
DWORD dwGBitMaskDWORD;
|
|
DWORD dwBBitMask;
|
|
DWORD dwRGBAlphaBitMask;
|
|
};
|
|
|
|
struct ITF_DDS_USER
|
|
{
|
|
DWORD dwLodBias;
|
|
DWORD dwAlphaBias;
|
|
DWORD dwbHasOneColor;
|
|
DWORD dwAnisotropy;
|
|
DWORD dwIntensityAlpha;
|
|
DWORD dwReserved[6];
|
|
};
|
|
|
|
struct ITF_DDS_HEADER
|
|
{
|
|
DWORD dwMagic;
|
|
DWORD dwSize;
|
|
DWORD dwFlags;
|
|
DWORD dwHeight;
|
|
DWORD dwWidth;
|
|
DWORD dwPitchOrLinearSize;
|
|
DWORD dwDepth;
|
|
DWORD dwMipMapCount;
|
|
|
|
union
|
|
{
|
|
ITF_DDS_USER dwUser;
|
|
DWORD dwReserved1[11];
|
|
};
|
|
|
|
ITF_DDPIXELFORMAT format;
|
|
ITF_DDSCAPS2 ddsCaps;
|
|
DWORD dwReserved2;
|
|
};
|
|
|
|
bool gb_Endiannes = false;
|
|
|
|
inline void endianess32(void *dst, const void *src)
|
|
{
|
|
unsigned long *q = (unsigned long *)dst;
|
|
unsigned long i = *(unsigned long *)src;
|
|
*q = (i>>24) | (i&0x00ff0000)>>8 | (i&0x0000ff00)<<8 | (i&0x000000ff)<<24;
|
|
}
|
|
|
|
void endianess(void *dst, const void *src, unsigned int size)
|
|
{
|
|
char *p = (char*)dst;
|
|
char *q = (char*)src;
|
|
for(unsigned int i = 0; i < size; i+=4, p+=4, q+=4)
|
|
endianess32(p,q);
|
|
}
|
|
|
|
bool bRGBACheckTransp(const unsigned char *src, unsigned int _w, unsigned int _h)
|
|
{
|
|
if(!gb_Endiannes)
|
|
src+=3;
|
|
for(unsigned int i = 0; i < _w*_h; i++, src+=4)
|
|
{
|
|
if((*src != 0xff) && (*src != 0x0))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void copyfile(const char * Dst, const char *Src)
|
|
{
|
|
FILE* psrc = fopen(Src,"rb");
|
|
if(!psrc)
|
|
return;
|
|
fseek(psrc, 0, SEEK_END);
|
|
size_t len = ftell(psrc);
|
|
void *buff = malloc(len);
|
|
fseek(psrc, 0, SEEK_SET);
|
|
fread(buff, len, 1, psrc);
|
|
fclose(psrc);
|
|
|
|
endianess(buff, buff, len);
|
|
|
|
FILE* pdst = fopen(Dst,"wb");
|
|
if(pdst)
|
|
{
|
|
fwrite(buff, len, 1, pdst);
|
|
fclose(pdst);
|
|
}
|
|
free(buff);
|
|
}
|
|
|
|
extern void GDK_images_TileDXTForWii(void *_pv_DestImg, void *_pv_SrcImg, u32 _u32_Width, u32 _u32_Height);
|
|
extern void GDK_images_TileRawBufferForWiiI8(void * _pv_DestImg, void * _pv_SrcImg, u32 _u32_Width, u32 _u32_Height);
|
|
extern void GDK_images_TileRawBufferForWiiI8A8(void * _pv_DestImg, void * _pv_SrcImg, u32 _u32_Width, u32 _u32_Height);
|
|
extern void GDK_images_TileForWii(void *_pv_DestImg, const void *_pv_SrcImg, u32 _u32_Width, u32 _u32_Height, u32 _u32_BPP);
|
|
|
|
unsigned char *workingBuff1 = 0;
|
|
unsigned char *workingBuff2 = 0;
|
|
|
|
void copyRGBAfile(const char *Dst, FILE *_pf_SrcFile, ITF_DDS_HEADER *_header, unsigned int flen)
|
|
{
|
|
if(!_pf_SrcFile)
|
|
return;
|
|
|
|
FILE* pdst = fopen(Dst,"wb");
|
|
if(!pdst)
|
|
{
|
|
fclose(_pf_SrcFile);
|
|
return;
|
|
}
|
|
|
|
unsigned int bufsize = flen - sizeof(ITF_DDS_HEADER);
|
|
void *src_rgba = malloc(bufsize);
|
|
fread(src_rgba, bufsize, 1, _pf_SrcFile);
|
|
fclose(_pf_SrcFile);
|
|
|
|
ITF_DDS_HEADER headerfile;
|
|
endianess(&headerfile, _header, sizeof(ITF_DDS_HEADER));
|
|
if(fwrite(&headerfile, sizeof(ITF_DDS_HEADER), 1, pdst) != 1)
|
|
{
|
|
cerr << "Can't write output file '" << Dst << "'" << endl;
|
|
fclose(pdst);
|
|
return;
|
|
}
|
|
|
|
endianess(src_rgba, src_rgba, bufsize);
|
|
fwrite(src_rgba, bufsize, 1, pdst);
|
|
fclose(pdst);
|
|
|
|
free(src_rgba);
|
|
}
|
|
|
|
void processRGBAfile(const char *Dst, FILE *_pf_SrcFile, ITF_DDS_HEADER *_header, unsigned int flen)
|
|
{
|
|
if(!_pf_SrcFile)
|
|
return;
|
|
|
|
FILE* pdst = fopen(Dst,"wb");
|
|
if(!pdst)
|
|
{
|
|
fclose(_pf_SrcFile);
|
|
return;
|
|
}
|
|
|
|
unsigned int bufsize = flen - sizeof(ITF_DDS_HEADER);
|
|
void *src_rgba = malloc(bufsize);
|
|
fread(src_rgba, bufsize, 1, _pf_SrcFile);
|
|
fclose(_pf_SrcFile);
|
|
|
|
int mipmapcount = 0;
|
|
int w = _header->dwWidth;
|
|
int h = _header->dwHeight;
|
|
|
|
while(1)
|
|
{
|
|
if((w<=8) || (h<=8)) // minimum square size
|
|
break;
|
|
mipmapcount++;
|
|
if(mipmapcount==10) // Max LOD on Wii
|
|
break;
|
|
w = w>>1;
|
|
h = h>>1;
|
|
}
|
|
|
|
if((int)_header->dwMipMapCount > mipmapcount)
|
|
_header->dwMipMapCount = (DWORD) mipmapcount;
|
|
|
|
ITF_DDS_HEADER headerfile;
|
|
endianess(&headerfile, _header, sizeof(ITF_DDS_HEADER));
|
|
if(fwrite(&headerfile, sizeof(ITF_DDS_HEADER), 1, pdst) != 1)
|
|
{
|
|
cerr << "Can't write output file '" << Dst << "'" << endl;
|
|
fclose(pdst);
|
|
return;
|
|
}
|
|
|
|
w = _header->dwWidth;
|
|
h = _header->dwHeight;
|
|
mipmapcount = _header->dwMipMapCount;
|
|
|
|
workingBuff1 = (unsigned char *) src_rgba;
|
|
workingBuff2 = (unsigned char *) malloc(h*w*4);
|
|
|
|
if(gb_Endiannes)
|
|
endianess(workingBuff1, workingBuff1, bufsize);
|
|
|
|
do
|
|
{
|
|
GDK_images_TileForWii(workingBuff2, workingBuff1, w, h, 32);
|
|
fwrite(workingBuff2, h*w*4, 1, pdst);
|
|
workingBuff1 += (h*w*4);
|
|
w >>= 1;
|
|
h >>= 1;
|
|
}while(--mipmapcount >= 0);
|
|
|
|
fclose(pdst);
|
|
|
|
workingBuff1 = 0;
|
|
free(workingBuff2);
|
|
free(src_rgba);
|
|
}
|
|
|
|
void copyDXT1file(const char *Dst, FILE *_pf_SrcFile, ITF_DDS_HEADER *_header, unsigned int flen)
|
|
{
|
|
if(!_pf_SrcFile)
|
|
return;
|
|
|
|
FILE* pdst = fopen(Dst,"wb");
|
|
if(!pdst)
|
|
{
|
|
fclose(_pf_SrcFile);
|
|
return;
|
|
}
|
|
|
|
unsigned int bufsize = flen - sizeof(ITF_DDS_HEADER);
|
|
void *src_dxt1 = malloc(bufsize);
|
|
fread(src_dxt1, bufsize, 1, _pf_SrcFile);
|
|
fclose(_pf_SrcFile);
|
|
|
|
int mipmapcount = 0;
|
|
int w = _header->dwWidth;
|
|
int h = _header->dwHeight;
|
|
|
|
while(1)
|
|
{
|
|
if((w<=8) || (h<=8)) // minimum square size
|
|
break;
|
|
mipmapcount++;
|
|
if(mipmapcount==10) // Max LOD on Wii
|
|
break;
|
|
w = w>>1;
|
|
h = h>>1;
|
|
}
|
|
|
|
if((int)_header->dwMipMapCount > mipmapcount)
|
|
_header->dwMipMapCount = (DWORD) mipmapcount;
|
|
|
|
ITF_DDS_HEADER headerfile;
|
|
endianess(&headerfile, _header, sizeof(ITF_DDS_HEADER));
|
|
if(fwrite(&headerfile, sizeof(ITF_DDS_HEADER), 1, pdst) != 1)
|
|
{
|
|
cerr << "Can't write output file '" << Dst << "'" << endl;
|
|
fclose(pdst);
|
|
return;
|
|
}
|
|
|
|
w = _header->dwWidth;
|
|
h = _header->dwHeight;
|
|
mipmapcount = _header->dwMipMapCount;
|
|
|
|
workingBuff1 = (unsigned char *) src_dxt1;
|
|
workingBuff2 = (unsigned char *) malloc(h*w/2);
|
|
|
|
if(gb_Endiannes)
|
|
endianess(workingBuff1, workingBuff1, bufsize);
|
|
|
|
do
|
|
{
|
|
GDK_images_TileDXTForWii(workingBuff2, workingBuff1, w, h);
|
|
fwrite(workingBuff2, h*w/2, 1, pdst);
|
|
workingBuff1 += (h*w/2);
|
|
w >>= 1;
|
|
h >>= 1;
|
|
}while(--mipmapcount >= 0);
|
|
|
|
fclose(pdst);
|
|
|
|
workingBuff1 = 0;
|
|
free(workingBuff2);
|
|
free(src_dxt1);
|
|
}
|
|
|
|
void ProcessBufferRGB(unsigned char * _rgba, unsigned int _w, unsigned int _h, unsigned char* _aaa, FILE *_pf)
|
|
{
|
|
unsigned c;
|
|
for(unsigned int i = 0; i < _h*_w; ++i)
|
|
{
|
|
unsigned char *rgba = _rgba+i*4;
|
|
if(gb_Endiannes)
|
|
endianess32(rgba, rgba);
|
|
|
|
c = *rgba; *rgba = rgba[2]; rgba[2] = c; // invert RB
|
|
if(_aaa)
|
|
{// fill alpha buffer
|
|
unsigned char *p = rgba+3;
|
|
unsigned char *q = _aaa+i*4;
|
|
q[0] = *p;
|
|
q[1] = *p;
|
|
q[2] = *p;
|
|
q[3] = 0xff;
|
|
*p = 0xff;
|
|
}
|
|
}
|
|
|
|
squish::CompressImage(_rgba, _w, _h, workingBuff1, squish::kDxt1);
|
|
GDK_images_TileDXTForWii(workingBuff2, workingBuff1, _w, _h);
|
|
|
|
fwrite(workingBuff2, _h*_w/2, 1, _pf);
|
|
}
|
|
|
|
void ProcessBufferAlpha(unsigned char * _aaa, unsigned int _w, unsigned int _h, FILE *_pf)
|
|
{
|
|
squish::CompressImage(_aaa, _w, _h, workingBuff1, squish::kDxt1);
|
|
GDK_images_TileDXTForWii(workingBuff2, workingBuff1, _w, _h);
|
|
|
|
fwrite(workingBuff2, _h*_w/2, 1, _pf);
|
|
}
|
|
|
|
void ProcessBufferRGBAForLuminance(unsigned char * _rgba, unsigned int _w, unsigned int _h, FILE *_pf, u32 _ps)
|
|
{
|
|
for(unsigned int i = 0; i < _w*_h; ++i)
|
|
{
|
|
workingBuff2[i] = _rgba[i*_ps+2];
|
|
}
|
|
|
|
GDK_images_TileRawBufferForWiiI8(_rgba, workingBuff2, _w, _h);
|
|
//endianess(_rgba, _rgba, _h*_w);
|
|
fwrite(_rgba, _h*_w, 1, _pf);
|
|
}
|
|
|
|
void ProcessBufferRGBAForLuminanceAlpha(unsigned char * _rgba, unsigned int _w, unsigned int _h, FILE *_pf, u32 _ps)
|
|
{
|
|
for(unsigned int i = 0; i < _w*_h; ++i)
|
|
{
|
|
workingBuff2[i*2+1] = _rgba[i*_ps+0];
|
|
workingBuff2[i*2+0] = _rgba[i*_ps+(_ps-1)];
|
|
}
|
|
|
|
GDK_images_TileRawBufferForWiiI8A8(_rgba, workingBuff2, _w, _h);
|
|
//endianess(_rgba, _rgba, _h*_w*2);
|
|
fwrite(_rgba, _h*_w*2, 1, _pf);
|
|
}
|
|
|
|
void copyLuminancefile(const char *Dst, FILE *_pf_SrcFile, ITF_DDS_HEADER *_header, unsigned int flen)
|
|
{
|
|
if(!_pf_SrcFile)
|
|
return;
|
|
|
|
FILE* pdst = fopen(Dst,"wb");
|
|
if(!pdst)
|
|
{
|
|
fclose(_pf_SrcFile);
|
|
return;
|
|
}
|
|
|
|
unsigned int bufsize = flen - sizeof(ITF_DDS_HEADER);
|
|
void *src_rgba = malloc(bufsize);
|
|
fread(src_rgba, bufsize, 1, _pf_SrcFile);
|
|
fclose(_pf_SrcFile);
|
|
|
|
if((_header->format.dwFlags & DDPF_LUMINANCE) != DDPF_LUMINANCE)
|
|
{
|
|
cerr << "Invalid input file '" << endl;
|
|
fclose(pdst);
|
|
free(src_rgba);
|
|
return;
|
|
}
|
|
|
|
int src_ps = _header->format.dwRGBBitCount >> 3; //source pixel size
|
|
|
|
_header->format.dwFourCC = MAKEFOURCC('L', '8', '0', '0');
|
|
_header->format.dwFlags = DDPF_LUMINANCE;
|
|
_header->format.dwRGBBitCount = 8;
|
|
_header->format.dwRBitMask = 0x00ff;
|
|
_header->format.dwGBitMaskDWORD = 0x0000;
|
|
_header->format.dwBBitMask = 0x0000;
|
|
_header->format.dwRGBAlphaBitMask = 0x0000;
|
|
|
|
ITF_DDS_HEADER headerfile;
|
|
endianess(&headerfile, _header, sizeof(ITF_DDS_HEADER));
|
|
if(fwrite(&headerfile, sizeof(ITF_DDS_HEADER), 1, pdst) != 1)
|
|
{
|
|
cerr << "Can't write output file '" << Dst << "'" << endl;
|
|
fclose(pdst);
|
|
free(src_rgba);
|
|
return;
|
|
}
|
|
|
|
int mipmapcount = 0;
|
|
int w = _header->dwWidth;
|
|
int h = _header->dwHeight;
|
|
|
|
while(1)
|
|
{
|
|
if((w<=8) || (h<=8)) // minimum square size
|
|
break;
|
|
mipmapcount++;
|
|
if(mipmapcount==10) // Max LOD on Wii
|
|
break;
|
|
w = w>>1;
|
|
h = h>>1;
|
|
}
|
|
|
|
if((int)_header->dwMipMapCount > mipmapcount)
|
|
_header->dwMipMapCount = (DWORD) mipmapcount;
|
|
|
|
w = _header->dwWidth;
|
|
h = _header->dwHeight;
|
|
mipmapcount = _header->dwMipMapCount;
|
|
|
|
workingBuff1 = (unsigned char *) src_rgba;
|
|
workingBuff2 = (unsigned char *) malloc(h*w*2);
|
|
if(gb_Endiannes)
|
|
endianess(workingBuff1, workingBuff1, bufsize);
|
|
|
|
do
|
|
{
|
|
ProcessBufferRGBAForLuminance(workingBuff1, w, h, pdst, src_ps);
|
|
workingBuff1 += (h*w*src_ps);
|
|
w >>= 1;
|
|
h >>= 1;
|
|
}while(--mipmapcount >= 0);
|
|
|
|
fclose(pdst);
|
|
|
|
free(workingBuff2);
|
|
workingBuff2 = 0;
|
|
free(src_rgba);
|
|
workingBuff1 = 0;
|
|
}
|
|
|
|
void copyLuminanceAlphafile(const char *Dst, FILE *_pf_SrcFile, ITF_DDS_HEADER *_header, unsigned int flen)
|
|
{
|
|
if(!_pf_SrcFile)
|
|
return;
|
|
|
|
FILE* pdst = fopen(Dst,"wb");
|
|
if(!pdst)
|
|
{
|
|
fclose(_pf_SrcFile);
|
|
return;
|
|
}
|
|
|
|
unsigned int bufsize = flen - sizeof(ITF_DDS_HEADER);
|
|
void *src_rgba = malloc(bufsize);
|
|
fread(src_rgba, bufsize, 1, _pf_SrcFile);
|
|
fclose(_pf_SrcFile);
|
|
|
|
if((_header->format.dwFlags & (DDPF_LUMINANCE | DDPF_ALPHAPIXELS)) != (DDPF_LUMINANCE | DDPF_ALPHAPIXELS))
|
|
{
|
|
cerr << "Invalid input file '" << endl;
|
|
fclose(pdst);
|
|
free(src_rgba);
|
|
return;
|
|
}
|
|
|
|
int src_ps = _header->format.dwRGBBitCount >> 3; //source pixel size
|
|
|
|
_header->format.dwFourCC = MAKEFOURCC('L', '8', 'A', '8');
|
|
_header->format.dwFlags = DDPF_LUMINANCE | DDPF_ALPHAPIXELS;
|
|
_header->format.dwRGBBitCount = 16;
|
|
_header->format.dwRBitMask = 0x00ff;
|
|
_header->format.dwGBitMaskDWORD = 0x0000;
|
|
_header->format.dwBBitMask = 0x0000;
|
|
_header->format.dwRGBAlphaBitMask = 0xff00;
|
|
|
|
ITF_DDS_HEADER headerfile;
|
|
endianess(&headerfile, _header, sizeof(ITF_DDS_HEADER));
|
|
if(fwrite(&headerfile, sizeof(ITF_DDS_HEADER), 1, pdst) != 1)
|
|
{
|
|
cerr << "Can't write output file '" << Dst << "'" << endl;
|
|
fclose(pdst);
|
|
free(src_rgba);
|
|
return;
|
|
}
|
|
|
|
int mipmapcount = 0;
|
|
int w = _header->dwWidth;
|
|
int h = _header->dwHeight;
|
|
|
|
while(1)
|
|
{
|
|
if((w<=8) || (h<=8)) // minimum square size
|
|
break;
|
|
mipmapcount++;
|
|
if(mipmapcount==10) // Max LOD on Wii
|
|
break;
|
|
w = w>>1;
|
|
h = h>>1;
|
|
}
|
|
|
|
if((int)_header->dwMipMapCount > mipmapcount)
|
|
_header->dwMipMapCount = (DWORD) mipmapcount;
|
|
|
|
w = _header->dwWidth;
|
|
h = _header->dwHeight;
|
|
mipmapcount = _header->dwMipMapCount;
|
|
|
|
workingBuff1 = (unsigned char *) src_rgba;
|
|
workingBuff2 = (unsigned char *) malloc(h*w*2);
|
|
if(gb_Endiannes)
|
|
endianess(workingBuff1, workingBuff1, bufsize);
|
|
|
|
do
|
|
{
|
|
ProcessBufferRGBAForLuminanceAlpha(workingBuff1, w, h, pdst, src_ps);
|
|
workingBuff1 += (h*w*src_ps);
|
|
w >>= 1;
|
|
h >>= 1;
|
|
}while(--mipmapcount >= 0);
|
|
|
|
fclose(pdst);
|
|
|
|
free(workingBuff2);
|
|
workingBuff2 = 0;
|
|
free(src_rgba);
|
|
workingBuff1 = 0;
|
|
}
|
|
|
|
int ProcessFile()
|
|
{
|
|
FILE *pf = fopen(strSourceFileName, "rb");
|
|
if(!pf)
|
|
{
|
|
cerr << "Can't open input file '" << strSourceFileName << "'" << endl;
|
|
return -2;
|
|
}
|
|
|
|
fseek(pf, 0, SEEK_END);
|
|
unsigned int flen = ftell(pf);
|
|
fseek(pf, 0, SEEK_SET);
|
|
|
|
ITF_DDS_HEADER header, headerfile;
|
|
if(fread(&headerfile, sizeof(ITF_DDS_HEADER), 1, pf) != 1)
|
|
{
|
|
cerr << " Can't read input file '" << strSourceFileName << "'. " << endl;
|
|
fclose(pf);
|
|
return -3;
|
|
}
|
|
gb_Endiannes = memcmp(&headerfile, "DDS ", 4) != 0;
|
|
if(gb_Endiannes)
|
|
endianess(&header, &headerfile, sizeof(ITF_DDS_HEADER));
|
|
else
|
|
memcpy(&header, &headerfile, sizeof(ITF_DDS_HEADER));
|
|
|
|
if(memcmp(&header, "DDS ", 4) != 0)
|
|
{
|
|
cerr << " Unknown file format. " << endl;
|
|
fclose(pf);
|
|
return -4;
|
|
}
|
|
|
|
if((header.dwHeight < 8) || (header.dwWidth < 8)) // TODO
|
|
{
|
|
cerr << " Texture size must scale of 8x8 pixels squares. " << endl;
|
|
copyRGBAfile(strDstFileName, pf, &header, flen);
|
|
return 0;
|
|
}
|
|
|
|
if((header.dwHeight % 8) || (header.dwWidth % 8)) // TODO
|
|
{
|
|
cerr << " Texture size must scale of 8x8 pixels squares. " << endl;
|
|
copyRGBAfile(strDstFileName, pf, &header, flen);
|
|
return 0;
|
|
}
|
|
|
|
if((header.dwHeight * header.dwWidth) % 64) // TODO
|
|
{
|
|
cerr << " Texture size must fit 32B tiles. " << endl;
|
|
copyRGBAfile(strDstFileName, pf, &header, flen);
|
|
return 0;
|
|
}
|
|
|
|
if(header.dwUser.dwIntensityAlpha == 1)
|
|
{
|
|
copyLuminancefile(strDstFileName, pf, &header, flen);
|
|
return 0;
|
|
}
|
|
|
|
if(header.dwUser.dwIntensityAlpha == 2)
|
|
{
|
|
copyLuminanceAlphafile(strDstFileName, pf, &header, flen);
|
|
return 0;
|
|
}
|
|
|
|
if(header.format.dwFourCC == MAKEFOURCC('D','X','T','1'))
|
|
{
|
|
copyDXT1file(strDstFileName, pf, &header, flen);
|
|
return 0;
|
|
}
|
|
|
|
if(g_rgbaNoCompressed)
|
|
{
|
|
processRGBAfile(strDstFileName, pf, &header, flen);
|
|
return 0;
|
|
}
|
|
|
|
if(header.format.dwFourCC != 0) //MAKEFOURCC('R','G','B','A'))
|
|
{
|
|
char str[5];
|
|
memcpy(str, &header.format.dwFourCC, 4);
|
|
str[sizeof(str)-1] = 0;
|
|
cerr << " Unknown texture format '" << str << "'." << endl;
|
|
fclose(pf);
|
|
return -5;
|
|
}
|
|
|
|
workingBuff1 = (unsigned char *) malloc(header.dwWidth*header.dwHeight);
|
|
workingBuff2 = workingBuff1 + header.dwWidth*header.dwHeight/2;
|
|
|
|
unsigned int blen = flen - sizeof(ITF_DDS_HEADER);
|
|
unsigned char *rgba = (unsigned char *) malloc(blen);
|
|
unsigned char *aaa = 0;
|
|
fread(rgba, blen, 1, pf);
|
|
fclose(pf);
|
|
|
|
bool bUseAlpha = bRGBACheckTransp(rgba, header.dwWidth, header.dwHeight);
|
|
|
|
if(bUseAlpha)
|
|
{
|
|
aaa = (unsigned char *) malloc(blen);
|
|
header.format.dwFourCC = MAKEFOURCC('C','M','P','A');
|
|
}
|
|
else
|
|
header.format.dwFourCC = MAKEFOURCC('D','X','T','1');
|
|
|
|
int mipmapcount = 0;
|
|
int w,h;
|
|
w = header.dwWidth;
|
|
h = header.dwHeight;
|
|
|
|
while(1)
|
|
{
|
|
if((w<=8) || (h<=8)) // minimum square size
|
|
break;
|
|
mipmapcount++;
|
|
if(mipmapcount==10) // Max LOD on Wii
|
|
break;
|
|
w = w>>1;
|
|
h = h>>1;
|
|
}
|
|
|
|
if((int)header.dwMipMapCount > mipmapcount)
|
|
header.dwMipMapCount = (DWORD) mipmapcount;
|
|
|
|
endianess(&headerfile, &header, sizeof(ITF_DDS_HEADER));
|
|
|
|
pf = fopen(strDstFileName, "wb");
|
|
if(!pf)
|
|
{
|
|
cerr << "Can't open output file '" << strDstFileName << "'" << endl;
|
|
return -6;
|
|
}
|
|
|
|
if(fwrite(&headerfile, sizeof(ITF_DDS_HEADER), 1, pf) != 1)
|
|
{
|
|
cerr << "Can't write output file '" << strDstFileName << "'" << endl;
|
|
fclose(pf);
|
|
return -7;
|
|
}
|
|
|
|
unsigned char *pMipmap, *pMipmapA;
|
|
pMipmap = rgba;
|
|
pMipmapA = aaa;
|
|
w = header.dwWidth;
|
|
h = header.dwHeight;
|
|
mipmapcount = header.dwMipMapCount;
|
|
do
|
|
{
|
|
ProcessBufferRGB(pMipmap, w, h, pMipmapA, pf);
|
|
pMipmap += w*h*4;
|
|
if(pMipmapA)
|
|
pMipmapA += w*h*4;
|
|
w = w>>1; h = h>>1;
|
|
}while(--mipmapcount >= 0);
|
|
|
|
if(bUseAlpha)
|
|
{
|
|
pMipmapA = aaa;
|
|
w = header.dwWidth;
|
|
h = header.dwHeight;
|
|
mipmapcount = header.dwMipMapCount;
|
|
do
|
|
{
|
|
ProcessBufferAlpha(pMipmapA, w, h, pf);
|
|
pMipmapA += w*h*4; w = w>>1; h = h>>1;
|
|
}while(--mipmapcount >= 0);
|
|
}
|
|
|
|
fclose(pf);
|
|
|
|
free(workingBuff1);
|
|
if(aaa) free(aaa);
|
|
free(rgba);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void help()
|
|
{
|
|
printf("TexPostCookWii version 1.0\n");
|
|
printf("Args:\n"
|
|
" -i inputfilename\n"
|
|
" -o outputfilename\n"
|
|
" -h display this help text\n"
|
|
);
|
|
}
|
|
|
|
void ProcessCommandLigne(int argc, char* argv[])
|
|
{
|
|
if(argc < 3)
|
|
{
|
|
help();
|
|
exit(-1);
|
|
}
|
|
|
|
for(int i = 1; i < argc; ++i)
|
|
{
|
|
if( (argv[i][0] != '-') && (argv[i][0] != '/') )
|
|
{
|
|
cerr << "Error on parameter \""<<argv[i]<<"\""<<endl<<endl;
|
|
help();
|
|
exit(-1);
|
|
return;
|
|
}
|
|
|
|
if (_stricmp(&argv[i][1], "i")==0)
|
|
{
|
|
strSourceFileName = argv[++i];
|
|
continue;
|
|
}
|
|
else if(_stricmp(&argv[i][1], "o")==0)
|
|
{
|
|
strDstFileName = argv[++i];
|
|
continue;
|
|
}
|
|
else if(_stricmp(&argv[i][1], "h")==0)
|
|
{
|
|
help();
|
|
exit(0);
|
|
return;
|
|
}
|
|
else if(_stricmp(&argv[i][1], "?")==0)
|
|
{
|
|
help();
|
|
exit(0);
|
|
return;
|
|
}
|
|
else if(_stricmp(&argv[i][1], "n")==0)
|
|
{
|
|
g_rgbaNoCompressed = true;
|
|
continue;
|
|
}
|
|
else if(_stricmp(&argv[i][1], "?")==0)
|
|
{
|
|
cerr << "Error on parameter \""<<argv[i]<<"\""<<endl<<endl;
|
|
help();
|
|
exit(-1);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
ProcessCommandLigne(argc, argv);
|
|
|
|
int ret = ProcessFile();
|
|
_fcloseall();
|
|
|
|
if(ret < 0)
|
|
copyfile(strDstFileName, strSourceFileName);
|
|
|
|
return ret;
|
|
}
|
|
|