// TexPostCook360.cpp : Defines the entry point for the console application. // #define _CRT_SECURE_NO_WARNINGS #include "stdafx.h" #include #include #include #include //#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 \""<