diff --git a/DRM/DRM.h b/DRM/DRM.h index 923cb38..66c2a16 100644 --- a/DRM/DRM.h +++ b/DRM/DRM.h @@ -7,7 +7,7 @@ //Constants const unsigned int DRM_MAX_SECTIONS = 16777215; -#define REPACK_MODE (0) +#define REPACK_MODE (1)//Must be on for PCD->DDS tool #if (TR7 || TRAE) #define DRM_VERSION (14) diff --git a/PCD2DDS/File.cpp b/PCD2DDS/File.cpp index 2d1653d..f2f3008 100644 --- a/PCD2DDS/File.cpp +++ b/PCD2DDS/File.cpp @@ -2,9 +2,11 @@ #include #include - #include "File.h" +#include "PCD.h" +#define ENDIAN_BIG PS3 + unsigned int getFileMagic(const char* filePath) { std::ifstream ifs(filePath, std::ios::binary); @@ -58,7 +60,7 @@ short ReadShort(std::ifstream& ifs) short val; ifs.read((char*)&val, sizeof(short)); #if ENDIAN_BIG - ReverseShort(val); + val = ReverseShort(val); #endif return val; } @@ -68,7 +70,7 @@ unsigned short ReadUShort(std::ifstream& ifs) unsigned short val; ifs.read((char*)&val, sizeof(unsigned short)); #if ENDIAN_BIG - ReverseUShort(val); + val = ReverseUShort(val); #endif return val; } @@ -78,7 +80,7 @@ int ReadInt(std::ifstream& ifs) int val; ifs.read((char*)&val, sizeof(int)); #if ENDIAN_BIG - ReverseInt(val); + val = ReverseInt(val); #endif return val; } @@ -88,7 +90,7 @@ unsigned int ReadUInt(std::ifstream& ifs) unsigned int val; ifs.read((char*)&val, sizeof(unsigned int)); #if ENDIAN_BIG - ReverseUInt(val); + val = ReverseUInt(val); #endif return val; } diff --git a/PCD2DDS/Main.cpp b/PCD2DDS/Main.cpp index af96473..37d84dd 100644 --- a/PCD2DDS/Main.cpp +++ b/PCD2DDS/Main.cpp @@ -18,6 +18,9 @@ int main(int argc, char* argv[]) { unsigned int fileMagic = getFileMagic(argv[1]); +#if PS3 + fileMagic = ReverseUInt(fileMagic); +#endif switch (fileMagic) { case SECTION_MAGIC: @@ -26,6 +29,9 @@ int main(int argc, char* argv[]) case DDS_MAGIC: ConvertDDSToPCD(argv[1]); break; + default: + std::cout << "Failed to detect file type!" << std::endl; + break; } } else diff --git a/PCD2DDS/PCD.cpp b/PCD2DDS/PCD.cpp index fceb4f2..65d7dc6 100644 --- a/PCD2DDS/PCD.cpp +++ b/PCD2DDS/PCD.cpp @@ -6,6 +6,7 @@ void ConvertPCDToDDS(const char* filePath) { +#ifndef PS3 std::ifstream ifs(filePath, std::ios::binary); //If there was a failure to open the file we must exit @@ -45,18 +46,18 @@ void ConvertPCDToDDS(const char* filePath) ifs.seekg(24, SEEK_SET); //Load texture data header - char* fileBuffer = new char[sizeof(PCTextureDataHeader)]; - ifs.read(fileBuffer, sizeof(PCTextureDataHeader)); - - PCTextureDataHeader* pcdHeader = nullptr; - pcdHeader = (PCTextureDataHeader*)fileBuffer; + char* fileBuffer = new char[sizeof(cdc::PC::Texture::Header)]; + ifs.read(fileBuffer, sizeof(cdc::PC::Texture::Header)); + + cdc::PC::Texture::Header* pcdHeader = reinterpret_cast(fileBuffer); + if (pcdHeader->m_magic != PCD_MAGIC) { std::cout << "Error PCD magic mis-match!" << std::endl; ifs.close(); return; } - + char* textureData = new char[pcdHeader->m_textureDataSize]; ifs.read(textureData, pcdHeader->m_textureDataSize); ifs.close(); @@ -104,4 +105,129 @@ void ConvertPCDToDDS(const char* filePath) ofs.close(); delete[] fileBuffer; delete[] textureData; -} \ No newline at end of file +#else + std::ifstream ifs(filePath, std::ios::binary); + + //If there was a failure to open the file we must exit + if (!ifs.good()) + { + std::cout << "Error: failed to open the file!" << std::endl; + ifs.close(); + return; + } + + //Check to see if file has valid section header + unsigned int sectionMagic = ReadUInt(ifs); + + if (sectionMagic != SECTION_MAGIC) + { + std::cout << "Error: section magic mis-match!" << std::endl; + ifs.close(); + return; + } + + unsigned int sectionSize = ReadUInt(ifs); + if (sectionSize <= 0) + { + std::cout << "Error: section corrupt, size is <= 0!" << std::endl; + ifs.close(); + return; + } + + unsigned char sectionType = ReadUByte(ifs); + if (sectionType != TEXTURE_SECTION_TYPE) + { + std::cout << "Error: invalid section type!" << std::endl; + ifs.close(); + return; + } + + //Skip past section header + ifs.seekg(24, SEEK_SET); + + //Load texture data header + char* fileBuffer = new char[sizeof(cdc::ps3::Texture::Header)]; + ifs.read(fileBuffer, sizeof(cdc::ps3::Texture::Header)); + + cdc::ps3::Texture::Header* ps3tHeader = reinterpret_cast(fileBuffer); + + //Endian swap + *&ps3tHeader->m_magic = ReverseUInt(*&ps3tHeader->m_magic); + *&ps3tHeader->m_textureDataSize = ReverseUInt(*&ps3tHeader->m_textureDataSize); + *&ps3tHeader->m_width = ReverseUShort(*&ps3tHeader->m_width); + *&ps3tHeader->m_height = ReverseUShort(*&ps3tHeader->m_height); + + //Swap + if (ps3tHeader->m_magic != PS3T_MAGIC) + { + std::cout << "Error PS3T magic mis-match!" << std::endl; + ifs.close(); + return; + } + + char* textureData = new char[ps3tHeader->m_textureDataSize]; + ifs.read(textureData, ps3tHeader->m_textureDataSize); + ifs.close(); + + char nameBuff[128]; + memset(nameBuff, 0, 128); + sprintf_s(nameBuff, "%s%s", filePath, ".dds"); + + std::ofstream ofs(nameBuff, std::ios::binary); + + unsigned int ddsSize = 0x7C; + unsigned int ddsFlags = 0x000A1007; + unsigned int ddsPitchOrLinearSize = 0x00010000; + unsigned int ddsDummy = 0; + unsigned int ddsHeight = ps3tHeader->m_height; + unsigned int ddsWidth = ps3tHeader->m_width; + unsigned int ddsDepth = 0;//;ps3tHeader->m_depth; + unsigned int ddsMipCount = 0;// ps3tHeader->m_numMipMaps; + unsigned int ddsFormat = cdc::ps3::Texture::getFormat(ps3tHeader->m_format); + unsigned int ddsUnk00 = 0x00401008; + + WriteUInt(ofs, DDS_MAGIC); + WriteUInt(ofs, ddsSize); + WriteUInt(ofs, ddsFlags); + WriteUInt(ofs, ddsHeight); + + WriteUInt(ofs, ddsWidth); + WriteUInt(ofs, ddsPitchOrLinearSize); + WriteUInt(ofs, ddsDummy); + WriteUInt(ofs, ddsDepth); + + WriteUInt(ofs, ddsMipCount); + + //Reserved + ofs.seekp(12 * sizeof(unsigned int), SEEK_CUR); + + WriteUInt(ofs, ddsFormat); + ofs.seekp(0x14, SEEK_CUR); + WriteUInt(ofs, ddsUnk00); + ofs.seekp(0x10, SEEK_CUR); + + ofs.write(textureData, ps3tHeader->m_textureDataSize); + + ofs.flush(); + ofs.close(); + delete[] fileBuffer; + delete[] textureData; +#endif +} + +unsigned int cdc::ps3::Texture::getFormat(unsigned int format) +{ + switch (format) + { + case cdc::ps3::Texture::kFormat::DXT1: + return 0x31545844; + break; + case cdc::ps3::Texture::kFormat::DXT5: + return 0x35545844; + default: + assert(false); + break; + } + + return -1; +} diff --git a/PCD2DDS/PCD.h b/PCD2DDS/PCD.h index 2e489de..1a2ab0d 100644 --- a/PCD2DDS/PCD.h +++ b/PCD2DDS/PCD.h @@ -6,44 +6,93 @@ #define DDS_MAGIC (0x20534444) #define TEXTURE_SECTION_TYPE (5) -enum PCDFormat -{ - DXT1 = 0x31545844, - DXT3 = 0x33545844, - DTX5 = 0x35545844 -}; +#define PS3 1 + +#define PS3T_MAGIC (0x50533354) + +#include -enum PCDFlags +namespace cdc { - FILTER_POINT = 0x0, - FILTER_BILINEAR = 0x1, - FILTER_TRILINEAR = 0x2, - FILTER_ANISOTROPIC_1X = 0x3, - FILTER_ANISOTROPIC_2X = 0x4, - FILTER_ANISOTROPIC_4X = 0x6, - FILTER_ANISOTROPIC_8X = 0xa, - FILTER_ANISOTROPIC_16X = 0x12, - FILTER_BEST = 0x100, - FILTER_DEFAULT = 0x12, - FILTER_INVALID = 0x200, -}; + namespace PC + { + namespace Texture + { + enum kFormat + { + DXT1 = 0x31545844, + DXT3 = 0x33545844, + DTX5 = 0x35545844 + }; + + enum kFlags//Taken from TR7.pdb + { + FILTER_POINT = 0x0, + FILTER_BILINEAR = 0x1, + FILTER_TRILINEAR = 0x2, + FILTER_ANISOTROPIC_1X = 0x3, + FILTER_ANISOTROPIC_2X = 0x4, + FILTER_ANISOTROPIC_4X = 0x6, + FILTER_ANISOTROPIC_8X = 0xa, + FILTER_ANISOTROPIC_16X = 0x12, + FILTER_BEST = 0x100, + FILTER_DEFAULT = 0x12, + FILTER_INVALID = 0x200, + }; #pragma pack(push, 1) -struct PCTextureDataHeader -{ - unsigned int m_magic; - enum PCDFMT m_format; - unsigned int m_textureDataSize; - unsigned int m_paletteDataSize; - unsigned short m_width; - unsigned short m_height; - unsigned char m_depth; - unsigned char m_numMipMaps; - unsigned short m_flags; -}; + struct Header + { + unsigned int m_magic; + enum PCDFMT m_format; + unsigned int m_textureDataSize; + unsigned int m_paletteDataSize; + unsigned short m_width; + unsigned short m_height; + unsigned char m_depth; + unsigned char m_numMipMaps; + unsigned short m_flags; + }; +#pragma pack(pop) + } + } + + namespace ps3 + { + namespace Texture + { + enum kFormat + { + DXT1 = 0x86, + //DXT3 = 0x33545844, + DXT5 = 0x88 + }; +#pragma pack(push, 1) + struct Header + { + unsigned int m_magic; + unsigned int m_textureDataSize; + unsigned short m_unk00; + unsigned short m_unk01; + unsigned char m_format; + unsigned char m_unk02; + unsigned short m_unk03; + + unsigned int m_unk04; + unsigned short m_width; + unsigned short m_height; + unsigned int m_unk05; + unsigned int m_unk06; + unsigned int m_unk07; + }; #pragma pack(pop) + unsigned int getFormat(unsigned int format); + } + } +} + void ConvertPCDToDDS(const char* filePath); #endif \ No newline at end of file