JD2022-TU1/main/extern/TexPostCook360/TexPostCook360.cpp

387 lines
8.6 KiB
C++

// TexPostCook360.cpp : Defines the entry point for the console application.
//
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
//#include "d3d9.h"
#include "d3dx9.h"
#include "xgraphics.h"
using namespace std;
//char strSourceFileName[256];
const char *strSourceFileName = 0;
const char *strDstFileName = 0;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
struct DDSCAPS2
{
DWORD dwCaps;
DWORD dwCaps2;
DWORD Reserved[2];
};
struct DDPIXELFORMAT
{
DWORD dwSize;
DWORD dwFlags;
DWORD dwFourCC;
DWORD dwRGBBitCount;
DWORD dwRBitMask;
DWORD dwGBitMaskDWORD;
DWORD dwBBitMask;
DWORD dwRGBAlphaBitMask;
};
struct DDS_HEADER
{
DWORD dwMagic;
DWORD dwSize;
DWORD dwFlags;
DWORD dwHeight;
DWORD dwWidth;
DWORD dwPitchOrLinearSize;
DWORD dwDepth;
DWORD dwMipMapCount;
DWORD dwReserved1[11];
DDPIXELFORMAT format;
DDSCAPS2 ddsCaps;
DWORD dwReserved2;
};
/*
enum PixFormat
{
//! Each pixel is 3 bytes. RGB in that order.
PF_RGB,
//! Each pixel is 4 bytes. RGBA in that order.
PF_RGBA,
PF_DXT1,
PF_DXT2,
PF_DXT3,
PF_DXT4,
PF_DXT5,
PF_RGB_NATIVE_CTR,
PF_RGBA_NATIVE_CTR,
PF_ETC1_CTR,
PF_ETC1_A4_CTR,
PF_CMPA, // WII : DXT1 for RGB + DXT1 for Alpha
PF_L8,
PF_LA8,
PF_A8
};
*/
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);
}
int ProcessFile()
{
FILE *pf = fopen(strSourceFileName, "rb");
//FILE *pf = fopen("cooking.dds", "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);
u8* rawBuf = (unsigned char *) malloc(flen);
if(fread(rawBuf, flen, 1, pf) != 1)
{
cerr << " Can't read input file '" << strSourceFileName << "'. " << endl;
fclose(pf);
return -3;
}
fclose(pf);
DDS_HEADER header;
u32 gb_Endiannes = memcmp(&rawBuf, "DDS ", 4) != 0;
memcpy(&header, rawBuf, sizeof(DDS_HEADER));
/*
//PixFormat pixFormat;
D3DFORMAT pixFormat;
switch (header.format.dwFourCC)
{
case MAKEFOURCC('D', 'X', 'T', '1'):
pixFormat = D3DFMT_DXT1;//PixFormat::PF_DXT1;
break;
case MAKEFOURCC('D', 'X', 'T', '2'):
pixFormat = D3DFMT_DXT2;//PixFormat::PF_DXT2;
break;
case MAKEFOURCC('D', 'X', 'T', '3'):
pixFormat = D3DFMT_DXT3;//PixFormat::PF_DXT3;
break;
case MAKEFOURCC('D', 'X', 'T', '4'):
pixFormat = D3DFMT_DXT4;//PixFormat::PF_DXT4;
break;
case MAKEFOURCC('D', 'X', 'T', '5'):
pixFormat = D3DFMT_DXT5;//PixFormat::PF_DXT5;
break;
default:
pixFormat = D3DFMT_A8B8G8R8;//PixFormat::PF_RGBA;
break;
}
*/
u8 *mipData = rawBuf + /*sizeof(u32) +*/ sizeof(DDS_HEADER);
D3DXIMAGE_INFO imageInfo;
D3DXGetImageInfoFromFileInMemory(rawBuf, flen, &imageInfo);
D3DFORMAT targetFormat = (D3DFORMAT)( imageInfo.Format | D3DFORMAT_TILED_MASK );
u32 swapStride = 0;
XGENDIANTYPE swapType = XGENDIAN_NONE;
if( imageInfo.Format == D3DFMT_LIN_DXT1 || imageInfo.Format == D3DFMT_LIN_DXT2 || imageInfo.Format == D3DFMT_LIN_DXT3 || imageInfo.Format == D3DFMT_LIN_DXT4 || imageInfo.Format == D3DFMT_LIN_DXT5 )
{
swapStride = 2;
swapType = XGENDIAN_8IN16;
}
else if( imageInfo.Format == D3DFMT_LIN_A8R8G8B8 || imageInfo.Format == D3DFMT_LIN_X8R8G8B8 || imageInfo.Format == D3DFMT_LIN_G16R16 )
{
swapStride = 4;
swapType = XGENDIAN_8IN32;
}
else
{
return -12;
}
// Create texture
D3DBaseTexture textureHeader;
u32 baseSize;
u32 mipSize;
XGSetTextureHeaderEx
(
imageInfo.Width,
imageInfo.Height,
imageInfo.MipLevels,
0,
targetFormat,
0,
0,
0,
XGHEADER_CONTIGUOUS_MIP_OFFSET,
0,
( D3DTexture* )&textureHeader,
(UINT*)&baseSize,
(UINT*)&mipSize
);
// Create a buffer to hold the texture data.
u8* buffer = (u8*)malloc( ( baseSize + mipSize) * sizeof(u8) );
memset(buffer, 0, baseSize + mipSize);
XGTEXTURE_DESC baseDesc;
XGGetTextureDesc( &textureHeader, 0, &baseDesc );
bool tiled = XGIsTiledFormat( (D3DFORMAT)baseDesc.Format );
if(!tiled)
{
free(buffer);
return -11;
}
// Convert every mip level
for( u32 levelIndex = 0; levelIndex < imageInfo.MipLevels; levelIndex++ )
{
// Get the description of the current mip level.
XGTEXTURE_DESC MipDesc;
XGGetTextureDesc( &textureHeader, levelIndex, &MipDesc );
u32 mipMapDataSize = MipDesc.WidthInBlocks * MipDesc.BytesPerBlock * MipDesc.HeightInBlocks;
u32 rowStride = MipDesc.WidthInBlocks * MipDesc.BytesPerBlock;
// Perform the endian-swap in-place on the image data...
XGEndianSwapMemory
(
mipData,
mipData,
swapType,
swapStride,
mipMapDataSize / swapStride
);
// Get the mip level offset within our buffer.
DWORD mipLevelOffset = XGGetMipLevelOffset( &textureHeader, 0, levelIndex );
if( ( levelIndex > 0 ) && ( mipSize > 0 ) )
{
mipLevelOffset += baseSize;
}
// Tile.
XGTileTextureLevel
(
baseDesc.Width,
baseDesc.Height,
levelIndex,
XGGetGpuFormat(targetFormat),
0,
buffer + mipLevelOffset,
NULL,
mipData,
rowStride,
NULL
);
// Skip to the next mipmap
mipData += mipMapDataSize;
}
free(rawBuf);
// Endian swap the texture header
XGEndianSwapMemory
(
&textureHeader,
&textureHeader,
XGENDIAN_8IN32,
sizeof(DWORD),
sizeof(textureHeader) / sizeof(DWORD)
);
pf = fopen(strDstFileName, "wb");
if(!pf)
{
cerr << "Can't open output file '" << strDstFileName << "'" << endl;
free(buffer);
return -6;
}
if(fwrite(&textureHeader, sizeof(textureHeader), 1, pf) != 1)
{
cerr << "Can't write output file '" << strDstFileName << "'" << endl;
fclose(pf);
free(buffer);
return -7;
}
if(fwrite(buffer, baseSize + mipSize, 1, pf) != 1)
{
cerr << "Can't write output file '" << strDstFileName << "'" << endl;
fclose(pf);
free(buffer);
return -8;
}
fclose(pf);
free(buffer);
return 0;
}
void help()
{
printf("TexConvertForXbox 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], "?")==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;
}