Skip to content

Commit 9a20a8f

Browse files
authored
Merge pull request #1114 from UE4SS-RE/usmapupdate
feat: update usmap gen for longer fname; over 255 enum values
2 parents d0479fd + 32b76b7 commit 9a20a8f

File tree

1 file changed

+25
-38
lines changed

1 file changed

+25
-38
lines changed

UE4SS/src/USMapGenerator/Generator.cpp

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,18 @@ namespace RC::OutTheShade
2323
{
2424
using namespace ::RC::Unreal;
2525

26+
enum class EUsmapVersion : uint8_t
27+
{
28+
Initial = 0,
29+
PackageVersioning = 1,
30+
LongFName = 2,
31+
LargeEnums = 3,
32+
ExplicitEnumValues = 4,
33+
34+
Latest = ExplicitEnumValues,
35+
LatestPlusOne
36+
};
37+
2638
enum class EPropertyType : uint8_t
2739
{
2840
ByteProperty,
@@ -349,8 +361,8 @@ namespace RC::OutTheShade
349361
NameView = NameView.substr(Find + 2);
350362
}
351363

352-
// Warning: Converting size_t (uint64) to uint8_t.
353-
Buffer.Write<uint8_t>(static_cast<uint8_t>(NameView.length()));
364+
// LongFName support (version >= 2): use uint16 for name lengths
365+
Buffer.Write<uint16_t>(static_cast<uint16_t>(NameView.length()));
354366
Buffer.WriteString(NameView);
355367

356368
CurrentNameIndex++;
@@ -363,20 +375,19 @@ namespace RC::OutTheShade
363375
{
364376
Buffer.Write(NameMap[Enum->GetNamePrivate()]);
365377

366-
// limit to 255 entries; why is this a byte in the first place?
367-
uint8_t EnumNameCount{};
378+
// LargeEnums support (version >= 3): use uint16 for enum member counts
379+
uint16_t EnumNameCount{};
368380
for (auto _ : Enum->ForEachName())
369381
{
370382
++EnumNameCount;
371-
if (EnumNameCount >= std::numeric_limits<uint8_t>::max()) break;
372383
}
373-
Buffer.Write<uint8_t>(EnumNameCount);
384+
Buffer.Write<uint16_t>(EnumNameCount);
374385

375-
int numSoFar = 0;
376-
for (auto& [Key, _] : Enum->ForEachName())
386+
// ExplicitEnumValues (version >= 4): write value then name index
387+
for (auto& [Key, Value] : Enum->ForEachName())
377388
{
378-
Buffer.Write<uint32_t>(NameMap[Key]);
379-
if (++numSoFar >= EnumNameCount) break;
389+
Buffer.Write<int64_t>(Value); // explicit enum value
390+
Buffer.Write<int32_t>(NameMap[Key]); // name index
380391
}
381392
}
382393

@@ -421,7 +432,7 @@ namespace RC::OutTheShade
421432
Buffer.Write<uint32_t>(0x54584543); // "CEXT"; magic
422433
Buffer.Write<uint8_t>(0); // extensions layout version; 0 (Initial)
423434

424-
Buffer.Write<uint32_t>(3); // number of extensions, 3 right now
435+
Buffer.Write<uint32_t>(2); // number of extensions (ENVP removed - now redundant with ExplicitEnumValues)
425436

426437
// extension 1: PPTH (object paths)
427438
Buffer.Write<uint32_t>(0x48545050); // ext id
@@ -490,32 +501,7 @@ namespace RC::OutTheShade
490501
Buffer.Write<uint32_t>(extEndPos - extStartPos);
491502
Buffer.GetBuffer().seekp(extEndPos);
492503

493-
// extension 3: ENVP (enum name/value pairs)
494-
Buffer.Write<uint32_t>(0x50564E45); // ext id
495-
Buffer.Write<uint32_t>(0); // size; unknown for now
496-
497-
extStartPos = Buffer.GetBuffer().tellp();
498-
Buffer.Write<uint8_t>(0); // ENVP version; 0
499-
Buffer.Write<uint32_t>(static_cast<uint32_t>(Enums.size()));
500-
for (auto Enum : Enums)
501-
{
502-
uint32_t EnumNameCount = 0;
503-
for (auto _ : Enum->ForEachName())
504-
++EnumNameCount;
505-
Buffer.Write<uint32_t>(EnumNameCount);
506-
507-
for (auto& [Key, val] : Enum->ForEachName())
508-
{
509-
Buffer.Write<uint32_t>(NameMap[Key]);
510-
Buffer.Write<int64_t>(val);
511-
}
512-
}
513-
extEndPos = Buffer.GetBuffer().tellp();
514-
515-
Buffer.GetBuffer().seekp(extStartPos);
516-
Buffer.GetBuffer().seekp(-(int32)sizeof(uint32), std::ios_base::cur);
517-
Buffer.Write<uint32_t>(extEndPos - extStartPos);
518-
Buffer.GetBuffer().seekp(extEndPos);
504+
// ENVP extension removed - enum values are now written explicitly in the main format (version 4)
519505

520506
// end of extensions //
521507

@@ -528,7 +514,8 @@ namespace RC::OutTheShade
528514
auto FileOutput = FileWriter(filename.c_str());
529515

530516
FileOutput.Write<uint16_t>(0x30C4); // magic
531-
FileOutput.Write<uint8_t>(0); // version
517+
FileOutput.Write<uint8_t>(static_cast<uint8_t>(EUsmapVersion::Latest)); // version
518+
FileOutput.Write<int32_t>(0); // bHasVersionInfo (false, no UE4/UE5 version info)
532519
FileOutput.Write<uint8_t>(0); // compression
533520
// Warning: Converting size_t (uint64) to int.
534521
FileOutput.Write<uint32_t>(static_cast<uint32_t>(UsmapData.size())); // compressed size

0 commit comments

Comments
 (0)