diff --git a/Unreal/GameDatabase.cpp b/Unreal/GameDatabase.cpp index b0b45bb3..ea6981a3 100644 --- a/Unreal/GameDatabase.cpp +++ b/Unreal/GameDatabase.cpp @@ -386,6 +386,9 @@ const GameInfo GListOfGames[] = { # if LIS2 G("Life is Strange 2", lis2, GAME_LIS2), # endif +# if PUBG + G("PUBG PC v6.0.1+", pubg, GAME_PUBG), +# endif #endif // UNREAL4 // end marker diff --git a/Unreal/GameDefines.h b/Unreal/GameDefines.h index 8c2afd85..bc9be175 100644 --- a/Unreal/GameDefines.h +++ b/Unreal/GameDefines.h @@ -159,6 +159,7 @@ #define HIT 1 // Heroes of Incredible Tales #define NGB 1 // New Gundam Breaker #define LIS2 1 // Life is Strange 2 +#define PUBG 1 // PUBG PC #define SPECIAL_TAGS 1 // games with different PACKAGE_FILE_TAG diff --git a/Unreal/UnCore.h b/Unreal/UnCore.h index 6d250764..5b935713 100644 --- a/Unreal/UnCore.h +++ b/Unreal/UnCore.h @@ -427,6 +427,7 @@ enum EGame // 4.16 GAME_NGB = GAME_UE4(16)+1, GAME_UT4 = GAME_UE4(16)+2, + GAME_PUBG = GAME_UE4(16)+3, // 4.17 GAME_LIS2 = GAME_UE4(17)+1, // 4.19 diff --git a/Unreal/UnMesh4.cpp b/Unreal/UnMesh4.cpp index 6fc3e90a..9bc1e60d 100644 --- a/Unreal/UnMesh4.cpp +++ b/Unreal/UnMesh4.cpp @@ -1616,6 +1616,16 @@ struct FStaticMeshSection4 Ar << S.bEnableCollision << S.bCastShadow; #if DAUNTLESS if (Ar.Game == GAME_Dauntless) Ar.Seek(Ar.Tell()+8); // 8 zero-filled bytes here +#endif +#if PUBG + if (Ar.Game == GAME_PUBG) { + byte b; + int i; + Ar << b << i; +# if DEBUG_STATICMESH + appPrintf(" unk s8=%u, s32=%d\n", b, i); +# endif + } #endif //?? Has editor-only data? return Ar; @@ -1721,6 +1731,9 @@ struct FStaticMeshLODModel4 // UE4.20+ CDSF_MinLodData = 2, // used to drop some LODs CDSF_ReversedIndexBuffer = 4, + + // PUBG all 3 bits set, no idea what indicates what, they're just always set. + CDSF_StripIndexBuffers = 128 | 64 | 32, }; static void Serialize(FArchive& Ar, FStaticMeshLODModel4& Lod) @@ -1777,6 +1790,17 @@ struct FStaticMeshLODModel4 unguard; } + // I guess it's highly compressible or something? + template + static inline void UnpackIndex(TArray& arr) + { + T currentIndex = 0; + for (auto i = 0; i < arr.Num(); i++) { + currentIndex += arr[i]; + arr[i] = currentIndex; + } + } + // Pre-UE4.23 code static void SerializeBuffersLegacy(FArchive& Ar, FStaticMeshLODModel4& Lod, const FStripDataFlags& StripFlags) { @@ -1787,8 +1811,18 @@ struct FStaticMeshLODModel4 Ar << Lod.ColorVertexBuffer; Ar << Lod.IndexBuffer; +#if PUBG + if (Ar.Game == GAME_PUBG && StripFlags.IsClassDataStripped(CDSF_StripIndexBuffers)) { + UnpackIndex(Lod.IndexBuffer.Indices16); + UnpackIndex(Lod.IndexBuffer.Indices32); + } +#endif + /// reference for VER_UE4_SOUND_CONCURRENCY_PACKAGE (UE4.9+): /// 25.09.2015 - 948c1698 +#if PUBG + if (Ar.Game != GAME_PUBG || !StripFlags.IsClassDataStripped(CDSF_StripIndexBuffers)) { +#endif if (Ar.ArVer >= VER_UE4_SOUND_CONCURRENCY_PACKAGE && !StripFlags.IsClassDataStripped(CDSF_ReversedIndexBuffer)) { Ar << Lod.ReversedIndexBuffer; @@ -1819,6 +1853,9 @@ struct FStaticMeshLODModel4 #if UT4 if (Ar.Game == GAME_UT4) return; #endif +#if PUBG + } +#endif if (Ar.Game >= GAME_UE4(16)) { diff --git a/umodel.exe b/umodel.exe index b02e4d57..fd40ecd1 100644 Binary files a/umodel.exe and b/umodel.exe differ