2020namespace vtfpp {
2121
2222constexpr uint32_t VTF_SIGNATURE = sourcepp::parser::binary::makeFourCC(" VTF\0 " );
23+ constexpr uint32_t XTF_SIGNATURE = sourcepp::parser::binary::makeFourCC(" XTF\0 " );
2324constexpr uint32_t VTFX_SIGNATURE = sourcepp::parser::binary::makeFourCC(" VTFX" );
2425constexpr uint32_t VTF3_SIGNATURE = sourcepp::parser::binary::makeFourCC(" VTF3" );
2526
@@ -34,8 +35,10 @@ enum class CompressionMethod : int16_t {
3435
3536struct Resource {
3637 enum Type : uint32_t {
37- TYPE_UNKNOWN = 0 , // Unknown
38+ TYPE_UNKNOWN = 0 , // Unknown
3839 TYPE_THUMBNAIL_DATA = 1 ,
40+ TYPE_PALETTE_DATA = 2 , // Hack for XBOX platform
41+ TYPE_FALLBACK_DATA = 3 , // Hack for XBOX platform
3942 TYPE_PARTICLE_SHEET_DATA = 16 ,
4043 TYPE_HOTSPOT_DATA = 43 ,
4144 TYPE_IMAGE_DATA = 48 ,
@@ -45,13 +48,16 @@ struct Resource {
4548 TYPE_LOD_CONTROL_INFO = sourcepp::parser::binary::makeFourCC (" LOD\0 " ),
4649 TYPE_KEYVALUES_DATA = sourcepp::parser::binary::makeFourCC (" KVD\0 " ),
4750 };
48- static consteval std::array<Type, 9 > getOrder () {
51+ static consteval std::array<Type, 11 > getOrder () {
4952 return {
5053 TYPE_THUMBNAIL_DATA,
54+ TYPE_PALETTE_DATA,
55+ TYPE_FALLBACK_DATA,
5156 TYPE_PARTICLE_SHEET_DATA,
5257 TYPE_HOTSPOT_DATA,
5358 // regular Source can't handle out of order resources, but Strata can,
54- // and it's the only branch that can read this and 7.6
59+ // and it's the only branch that can read this and 7.6.
60+ // Put this before the image data to fix resources being cut off when skipping mips
5561 TYPE_AUX_COMPRESSION,
5662 TYPE_IMAGE_DATA,
5763 TYPE_EXTENDED_FLAGS,
@@ -168,6 +174,12 @@ class VTF {
168174 };
169175 static constexpr uint32_t FLAGS_MASK_V2 = FLAG_V2_NO_DEPTH_BUFFER | FLAG_V2_CLAMP_U;
170176
177+ enum FlagsXBOX : uint32_t {
178+ FLAG_XBOX_CACHEABLE = 1 << 27 ,
179+ FLAG_XBOX_UNFILTERABLE_OK = 1 << 28 ,
180+ };
181+ static constexpr uint32_t FLAGS_MASK_XBOX = FLAG_XBOX_CACHEABLE | FLAG_XBOX_UNFILTERABLE_OK;
182+
171183 enum FlagsV3 : uint32_t {
172184 FLAG_V3_LOAD_ALL_MIPS = 1 << 10 ,
173185 FLAG_V3_VERTEX_TEXTURE = 1 << 26 ,
@@ -212,6 +224,7 @@ class VTF {
212224 enum Platform : uint32_t {
213225 PLATFORM_UNKNOWN = 0x000 ,
214226 PLATFORM_PC = 0x007 ,
227+ PLATFORM_XBOX = 0x005 ,
215228 PLATFORM_X360 = 0x360 ,
216229 PLATFORM_PS3_ORANGEBOX = 0x333 ,
217230 PLATFORM_PS3_PORTAL2 = 0x334 ,
@@ -239,6 +252,7 @@ class VTF {
239252 float bumpMapScale = 1 .f;
240253 float gammaCorrection = 1 .f;
241254 bool invertGreenChannel = false ;
255+ uint8_t xboxMipScale = 0 ;
242256 };
243257
244258 // / This value is only valid when passed to VTF::create through CreationOptions
@@ -363,6 +377,12 @@ class VTF {
363377
364378 [[nodiscard]] uint8_t getThumbnailHeight () const ;
365379
380+ [[nodiscard]] uint8_t getFallbackWidth () const ;
381+
382+ [[nodiscard]] uint8_t getFallbackHeight () const ;
383+
384+ [[nodiscard]] uint8_t getFallbackMipCount () const ;
385+
366386 [[nodiscard]] const std::vector<Resource>& getResources () const ;
367387
368388 [[nodiscard]] const Resource* getResource (Resource::Type type) const ;
@@ -434,6 +454,8 @@ class VTF {
434454
435455 void setThumbnail (std::span<const std::byte> imageData_, ImageFormat format_, uint16_t width_, uint16_t height_, float quality = ImageConversion::DEFAULT_COMPRESSED_QUALITY);
436456
457+ bool setThumbnail (const std::string& imagePath, float quality = ImageConversion::DEFAULT_COMPRESSED_QUALITY); // NOLINT(*-use-nodiscard)
458+
437459 void computeThumbnail (ImageConversion::ResizeFilter filter = ImageConversion::ResizeFilter::DEFAULT, float quality = ImageConversion::DEFAULT_COMPRESSED_QUALITY);
438460
439461 void removeThumbnail ();
@@ -442,6 +464,26 @@ class VTF {
442464
443465 bool saveThumbnailToFile (const std::string& imagePath, ImageConversion::FileFormat fileFormat = ImageConversion::FileFormat::DEFAULT) const ; // NOLINT(*-use-nodiscard)
444466
467+ [[nodiscard]] bool hasFallbackData () const ;
468+
469+ [[nodiscard]] std::span<const std::byte> getFallbackDataRaw (uint8_t mip = 0 , uint16_t frame = 0 , uint8_t face = 0 ) const ;
470+
471+ [[nodiscard]] std::vector<std::byte> getFallbackDataAs (ImageFormat newFormat, uint8_t mip = 0 , uint16_t frame = 0 , uint8_t face = 0 ) const ;
472+
473+ [[nodiscard]] std::vector<std::byte> getFallbackDataAsRGBA8888 (uint8_t mip = 0 , uint16_t frame = 0 , uint8_t face = 0 ) const ;
474+
475+ void computeFallback (ImageConversion::ResizeFilter filter = ImageConversion::ResizeFilter::DEFAULT);
476+
477+ void removeFallback ();
478+
479+ [[nodiscard]] std::vector<std::byte> saveFallbackToFile (uint8_t mip = 0 , uint16_t frame = 0 , uint8_t face = 0 , ImageConversion::FileFormat fileFormat = ImageConversion::FileFormat::DEFAULT) const ;
480+
481+ bool saveFallbackToFile (const std::string& imagePath, uint8_t mip = 0 , uint16_t frame = 0 , uint8_t face = 0 , ImageConversion::FileFormat fileFormat = ImageConversion::FileFormat::DEFAULT) const ; // NOLINT(*-use-nodiscard)
482+
483+ [[nodiscard]] uint8_t getXBOXMipScale () const ;
484+
485+ void setXBOXMipScale (uint8_t xboxMipScale_);
486+
445487 [[nodiscard]] std::vector<std::byte> bake () const ;
446488
447489 bool bake (const std::string& vtfPath) const ; // NOLINT(*-use-nodiscard)
@@ -461,37 +503,37 @@ class VTF {
461503
462504 std::vector<std::byte> data;
463505
464- // uint32_t signature;
465- uint32_t version{};
466- // uint32_t headerSize;
506+ uint32_t version = 4 ;
467507
468- uint16_t width{} ;
469- uint16_t height{} ;
470- uint32_t flags{} ;
508+ uint16_t width = 0 ;
509+ uint16_t height = 0 ;
510+ uint32_t flags = VTF::FLAG_NO_MIP | VTF::FLAG_NO_LOD ;
471511
472512 uint16_t frameCount = 1 ;
473- uint16_t startFrame{} ;
513+ uint16_t startFrame = 0 ;
474514
475- // uint8_t _padding0[4];
476- sourcepp::math::Vec3f reflectivity{};
477- // uint8_t _padding1[4];
515+ sourcepp::math::Vec3f reflectivity{0 .2f , 0 .2f , 0 .2f };
478516
479- float bumpMapScale{} ;
517+ float bumpMapScale = 0 . f ;
480518 ImageFormat format = ImageFormat::EMPTY;
481519 uint8_t mipCount = 1 ;
482520
483521 ImageFormat thumbnailFormat = ImageFormat::EMPTY;
484- uint8_t thumbnailWidth{};
485- uint8_t thumbnailHeight{};
522+ uint8_t thumbnailWidth = 0 ;
523+ uint8_t thumbnailHeight = 0 ;
524+
525+ uint8_t fallbackWidth = 0 ;
526+ uint8_t fallbackHeight = 0 ;
527+ uint8_t fallbackMipCount = 0 ;
528+
529+ // Number of times to multiply the scale of each mip by 2 when rendering on XBOX
530+ uint8_t xboxMipScale = 0 ;
486531
487532 // 1 for v7.1 and lower
488533 uint16_t sliceCount = 1 ;
489- // uint8_t _padding2[3];
490534
491535 // Technically added in v7.3, but we use it to store image and thumbnail data in v7.2 and lower anyway
492- // uint32_t resourceCount;
493536 std::vector<Resource> resources;
494- // uint8_t _padding3[4];
495537
496538 // These aren't in the header
497539 Platform platform = PLATFORM_PC;
0 commit comments