Skip to content

Commit

Permalink
PS3 Texture support.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gh0stBlade committed Apr 5, 2017
1 parent 4fb1766 commit 03e52ed
Show file tree
Hide file tree
Showing 5 changed files with 227 additions and 44 deletions.
2 changes: 1 addition & 1 deletion DRM/DRM.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
12 changes: 7 additions & 5 deletions PCD2DDS/File.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
#include <iostream>
#include <Shlwapi.h>


#include "File.h"

#include "PCD.h"
#define ENDIAN_BIG PS3

unsigned int getFileMagic(const char* filePath)
{
std::ifstream ifs(filePath, std::ios::binary);
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down
6 changes: 6 additions & 0 deletions PCD2DDS/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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
Expand Down
140 changes: 133 additions & 7 deletions PCD2DDS/PCD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<cdc::PC::Texture::Header*>(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();
Expand Down Expand Up @@ -104,4 +105,129 @@ void ConvertPCDToDDS(const char* filePath)
ofs.close();
delete[] fileBuffer;
delete[] textureData;
}
#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<cdc::ps3::Texture::Header*>(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;
}
111 changes: 80 additions & 31 deletions PCD2DDS/PCD.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <cassert>

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

0 comments on commit 03e52ed

Please sign in to comment.