Skip to content

Commit 98f2fa5

Browse files
vtfpp: ps3 orange box textures have reversed mips
1 parent 082c231 commit 98f2fa5

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

src/vtfpp/VTF.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,15 @@ VTF::VTF(std::vector<std::byte>&& vtfData, bool parseHeaderOnly)
680680
if (resource.type == Resource::TYPE_THUMBNAIL_DATA) {
681681
::swapImageDataEndianForConsole<true>(resource.data, this->thumbnailFormat, 1, 1, 1, this->thumbnailWidth, this->thumbnailHeight, 1, this->platform);
682682
} else if (resource.type == Resource::TYPE_IMAGE_DATA) {
683+
if (this->platform == PLATFORM_PS3_ORANGEBOX) {
684+
bool ok;
685+
const auto reorderedFallbackData = ::convertBetweenDDSAndVTFMipOrderForXBOX<true>(false, resource.data, this->format, this->mipCount, this->frameCount, this->getFaceCount(), this->width, this->height, this->depth, ok);
686+
if (!ok || reorderedFallbackData.size() != resource.data.size()) {
687+
this->opened = false;
688+
return;
689+
}
690+
std::memcpy(resource.data.data(), reorderedFallbackData.data(), resource.data.size());
691+
}
683692
::swapImageDataEndianForConsole<true>(resource.data, this->format, this->mipCount, this->frameCount, this->getFaceCount(), this->width, this->height, this->depth, this->platform);
684693
} else if (!(resource.flags & Resource::FLAG_LOCAL_DATA) && resource.data.size() >= sizeof(uint32_t)) {
685694
BufferStream::swap_endian(reinterpret_cast<uint32_t*>(resource.data.data()));
@@ -2384,7 +2393,15 @@ std::vector<std::byte> VTF::bake() const {
23842393
::swapImageDataEndianForConsole<false>(thumbnailResourceData, this->thumbnailFormat, 1, 1, 1, this->thumbnailWidth, this->thumbnailHeight, 1, this->platform);
23852394
resource.data = thumbnailResourceData;
23862395
} else if (resource.type == Resource::TYPE_IMAGE_DATA) {
2387-
imageResourceData = {resource.data.begin(), resource.data.end()};
2396+
if (this->platform == PLATFORM_PS3_ORANGEBOX) {
2397+
bool ok;
2398+
imageResourceData = ::convertBetweenDDSAndVTFMipOrderForXBOX<false>(false, resource.data, this->format, this->mipCount, this->frameCount, this->getFaceCount(), this->width, this->height, this->depth, ok);
2399+
if (!ok || imageResourceData.size() != resource.data.size()) {
2400+
return {};
2401+
}
2402+
} else {
2403+
imageResourceData = {resource.data.begin(), resource.data.end()};
2404+
}
23882405
::swapImageDataEndianForConsole<false>(imageResourceData, this->format, this->mipCount, this->frameCount, this->getFaceCount(), this->width, this->height, this->depth, this->platform);
23892406

23902407
// LZMA compression has not been observed on the PS3 copy of The Orange Box

test/vtfpp.cpp

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1257,7 +1257,40 @@ TEST(vtfpp, read_xbox_p8_animated) {
12571257
EXPECT_EQ(image->data.size(), ImageFormatDetails::getDataLengthXBOX(true, vtf.getFormat(), vtf.getMipCount(), vtf.getFrameCount(), vtf.getFaceCount(), vtf.getWidth(), vtf.getHeight(), vtf.getDepth()));
12581258
}
12591259

1260-
TEST(vtfpp, read_ps3_orangebox) {
1260+
TEST(vtfpp, read_ps3_orangebox_mips) {
1261+
VTF vtf{fs::readFileBuffer(ASSET_ROOT "vtfpp/ps3_orangebox/mips.ps3.vtf")};
1262+
ASSERT_TRUE(vtf);
1263+
1264+
// Header
1265+
EXPECT_EQ(vtf.getPlatform(), VTF::PLATFORM_PS3_ORANGEBOX);
1266+
EXPECT_EQ(vtf.getVersion(), 4);
1267+
EXPECT_EQ(vtf.getWidth(), 512);
1268+
EXPECT_EQ(vtf.getHeight(), 512);
1269+
EXPECT_EQ(vtf.getFlags(), VTF::FLAG_V0_VTEX_NO_COMPRESS);
1270+
EXPECT_EQ(vtf.getFormat(), ImageFormat::DXT1);
1271+
EXPECT_EQ(vtf.getMipCount(), 10);
1272+
EXPECT_EQ(vtf.getFrameCount(), 1);
1273+
EXPECT_EQ(vtf.getFaceCount(), 1);
1274+
EXPECT_EQ(vtf.getDepth(), 1);
1275+
EXPECT_EQ(vtf.getStartFrame(), 0);
1276+
EXPECT_FLOAT_EQ(vtf.getReflectivity()[0], 0.32249445f);
1277+
EXPECT_FLOAT_EQ(vtf.getReflectivity()[1], 0.29758567f);
1278+
EXPECT_FLOAT_EQ(vtf.getReflectivity()[2], 0.24868284f);
1279+
EXPECT_FLOAT_EQ(vtf.getBumpMapScale(), 1.f);
1280+
EXPECT_EQ(vtf.getThumbnailFormat(), ImageFormat::EMPTY);
1281+
EXPECT_EQ(vtf.getThumbnailWidth(), 0);
1282+
EXPECT_EQ(vtf.getThumbnailHeight(), 0);
1283+
1284+
// Resources
1285+
EXPECT_EQ(vtf.getResources().size(), 1);
1286+
1287+
const auto* image = vtf.getResource(Resource::TYPE_IMAGE_DATA);
1288+
ASSERT_TRUE(image);
1289+
EXPECT_EQ(image->flags, Resource::FLAG_NONE);
1290+
EXPECT_EQ(image->data.size(), ImageFormatDetails::getDataLength(vtf.getFormat(), vtf.getMipCount(), vtf.getFrameCount(), vtf.getFaceCount(), vtf.getWidth(), vtf.getHeight(), vtf.getDepth()));
1291+
}
1292+
1293+
TEST(vtfpp, read_ps3_orangebox_portal) {
12611294
VTF vtf{fs::readFileBuffer(ASSET_ROOT "vtfpp/ps3_orangebox/portal.ps3.vtf")};
12621295
ASSERT_TRUE(vtf);
12631296

0 commit comments

Comments
 (0)