Fix IA8 texture decoding

This commit is contained in:
Phillip Stephens 2019-02-16 09:16:34 -08:00
parent 95890088a5
commit fb1f65434d
4 changed files with 61 additions and 5 deletions

View File

@ -3,6 +3,7 @@
#include "TXTR.hpp" #include "TXTR.hpp"
#include "PAK.hpp" #include "PAK.hpp"
#include "athena/FileWriter.hpp" #include "athena/FileWriter.hpp"
#include "hecl/hecl.hpp"
namespace DataSpec { namespace DataSpec {
@ -268,7 +269,7 @@ static void DecodeIA8(png_structp png, png_infop info, const uint8_t* texels, in
std::unique_ptr<uint16_t[]> buf(new uint16_t[width]); std::unique_ptr<uint16_t[]> buf(new uint16_t[width]);
for (int y = height - 1; y >= 0; --y) { for (int y = height - 1; y >= 0; --y) {
for (int x = 0; x < width; ++x) for (int x = 0; x < width; ++x)
buf[x] = Lookup16BPP(texels, width, x, y); buf[x] = hecl::SBig(Lookup16BPP(texels, width, x, y));
png_write_row(png, (png_bytep)buf.get()); png_write_row(png, (png_bytep)buf.get());
} }
} }
@ -276,7 +277,7 @@ static void DecodeIA8(png_structp png, png_infop info, const uint8_t* texels, in
static void EncodeIA8(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) { static void EncodeIA8(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) {
for (int y = height - 1; y >= 0; --y) { for (int y = height - 1; y >= 0; --y) {
for (int x = 0; x < width; ++x) for (int x = 0; x < width; ++x)
Set16BPP(texels, width, x, y, ((uint16_t*)rgbaIn)[x]); Set16BPP(texels, width, x, y, hecl::SBig(((uint16_t*)rgbaIn)[x]));
rgbaIn += width * 2; rgbaIn += width * 2;
} }
} }
@ -1590,4 +1591,60 @@ bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outP
return true; return true;
} }
static const atInt32 RetroToDol[11] {
0, 1, 2, 3, 8, 9, -1, 4, 5, 6, 14
};
std::string TXTR::CalculateDolphinName(DataSpec::PAKEntryReadStream& rs) {
atUint32 format = RetroToDol[rs.readUint32Big()];
if (format == -1)
return {};
atUint16 width = rs.readUint16Big();
atUint16 height = rs.readUint16Big();
atUint32 mips = rs.readUint32Big();
std::string res = hecl::Format("tex1_%dx%d%s", width, height, mips > 1 ? "_m" : "");
atUint64 palHash = 0;
bool hasPalette = false;
atUint32 textureSize = width * height;
if (format == 8 || format == 9) {
hasPalette = true;
atUint32 paletteFormat = rs.readUint32Big();
atUint16 palWidth = rs.readUint16Big();
atUint16 palHeight = rs.readUint16Big();
atUint32 palSize = atUint32(palWidth * palHeight * 2);
if (format == 4)
textureSize /= 2;
std::unique_ptr<u8[]> palData(new u8[palSize]);
rs.readUBytesToBuf(palData.get(), palSize);
palHash = XXH64(palData.get(), palSize, 0);
} else {
switch(format) {
case 0: // I4
case 14: // DXT1
textureSize /= 2;
break;
case 3:
case 4:
case 5:
textureSize *= 2;
break;
case 6:
textureSize *= 4;
break;
default:
break;
}
}
std::unique_ptr<u8[]> textureData(new u8[textureSize]);
rs.readUBytesToBuf(textureData.get(), textureSize);
atUint64 texHash = XXH64(textureData.get(), textureSize, 0);
res += hecl::Format("_%016" PRIx64, texHash);
if (hasPalette)
res += hecl::Format("_%016" PRIx64, palHash);
res += hecl::Format("_%d", format);
return res;
}
} // namespace DataSpec } // namespace DataSpec

View File

@ -9,6 +9,7 @@ struct TXTR {
static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath);
static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath); static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath);
static bool CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath); static bool CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath);
static std::string CalculateDolphinName(PAKEntryReadStream& rs);
}; };
} // namespace DataSpec } // namespace DataSpec

View File

@ -326,8 +326,6 @@ ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const nod::Node& pakNode, con
return {SCAN::Extract, {_SYS_STR(".yaml")}, 0, SCAN::Name}; return {SCAN::Extract, {_SYS_STR(".yaml")}, 0, SCAN::Name};
case SBIG('HINT'): case SBIG('HINT'):
return {HINT::Extract, {_SYS_STR(".yaml")}}; return {HINT::Extract, {_SYS_STR(".yaml")}};
case SBIG('SAVW'):
return {SAVWCommon::ExtractSAVW<SAVW>, {_SYS_STR(".yaml")}};
case SBIG('TXTR'): case SBIG('TXTR'):
return {TXTR::Extract, {_SYS_STR(".png")}}; return {TXTR::Extract, {_SYS_STR(".png")}};
case SBIG('AFSM'): case SBIG('AFSM'):

View File

@ -56,7 +56,7 @@ std::shared_ptr<CGuiWidget> CGuiCamera::Create(CGuiFrame* frame, CInputStream& i
float zfar = in.readFloatBig(); float zfar = in.readFloatBig();
ret = std::make_shared<CGuiCamera>(parms, left, right, top, bottom, znear, zfar); ret = std::make_shared<CGuiCamera>(parms, left, right, top, bottom, znear, zfar);
break; break;
} break; }
} }
frame->SetFrameCamera(ret->shared_from_this()); frame->SetFrameCamera(ret->shared_from_this());
ret->ParseBaseInfo(frame, in, parms); ret->ParseBaseInfo(frame, in, parms);