Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/RePak.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<ClCompile Include="assets\texture_list.cpp" />
<ClCompile Include="assets\texture.cpp" />
<ClCompile Include="assets\ui_image_atlas.cpp" />
<ClCompile Include="assets\rui.cpp" />
<ClCompile Include="logic\buildsettings.cpp" />
<ClCompile Include="logic\pakpage.cpp" />
<ClCompile Include="logic\pakfile.cpp" />
Expand Down
3 changes: 3 additions & 0 deletions src/RePak.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@
<ClCompile Include="assets\texture_list.cpp">
<Filter>assets</Filter>
</ClCompile>
<ClCompile Include="assets\rui.cpp">
<Filter>assets</Filter>
</ClCompile>
<ClCompile Include="application\console.cpp" />
<ClCompile Include="assets\ui_image_atlas.cpp">
<Filter>assets</Filter>
Expand Down
2 changes: 2 additions & 0 deletions src/assets/assets.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,6 @@ namespace Assets
void AddShaderSetAsset_v11(CPakFileBuilder* const pak, const PakGuid_t assetGuid, const char* const assetPath, const rapidjson::Value& mapEntry);
void AddShaderAsset_v8(CPakFileBuilder* const pak, const PakGuid_t assetGuid, const char* const assetPath, const rapidjson::Value& mapEntry);
void AddShaderAsset_v12(CPakFileBuilder* const pak, const PakGuid_t assetGuid, const char* const assetPath, const rapidjson::Value& mapEntry);

void AddRuiAsset_v30(CPakFileBuilder* const pak, const PakGuid_t assetGuid, const char* const assetPath, const rapidjson::Value& mapEntry);
};
141 changes: 141 additions & 0 deletions src/assets/rui.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#include "pch.h"
#include "assets.h"
#include "public/rui.h"

void Rui_loadFromPackage(CPakFileBuilder* const pak, const PakGuid_t assetGuid, const char* const assetPath) {

UNUSED(assetGuid);
const fs::path inputFilePath = pak->GetAssetPath() / fs::path(assetPath).replace_extension("ruip");
RuiPackage rui{inputFilePath};

PakAsset_t& asset = pak->BeginAsset(assetGuid,assetPath);
PakPageLump_s hdrChunk = pak->CreatePageLump(sizeof(RuiHeader_v30_s),SF_HEAD|SF_CLIENT,8);
RuiHeader_v30_s* ruiHdr = reinterpret_cast<RuiHeader_v30_s*>(hdrChunk.data);
*ruiHdr = rui.CreateRuiHeader_v30();

PakPageLump_s nameChunk = pak->CreatePageLump(rui.name.size(),SF_CPU|SF_CLIENT,8);
memcpy(nameChunk.data,rui.name.data(),rui.name.size());
pak->AddPointer(hdrChunk,offsetof(RuiHeader_v30_s,name),nameChunk,0);

PakPageLump_s defaultValuesChunk = pak->CreatePageLump(rui.defaultData.size()+rui.defaultStrings.size(),SF_CPU|SF_CLIENT,8);
memcpy(defaultValuesChunk.data,rui.defaultData.data(),rui.defaultData.size());
memcpy(&defaultValuesChunk.data[rui.defaultData.size()],rui.defaultStrings.data(),rui.defaultStrings.size());
for (uint16_t offset : rui.defaultStringOffsets) {
uint64_t stringOffset = *reinterpret_cast<uint64_t*>(&rui.defaultData[offset])+rui.defaultData.size();
pak->AddPointer(defaultValuesChunk,offset,defaultValuesChunk,stringOffset);
}
pak->AddPointer(hdrChunk,offsetof(RuiHeader_v30_s,dataStructInitData),defaultValuesChunk,0);

PakPageLump_s transformDataChunk = pak->CreatePageLump(rui.transformData.size(),SF_CPU|SF_CLIENT,8);
memcpy(transformDataChunk.data,rui.transformData.data(),rui.transformData.size());
pak->AddPointer(hdrChunk,offsetof(RuiHeader_v30_s,transformData),transformDataChunk,0);

PakPageLump_s argClustersChunk = pak->CreatePageLump(rui.argCluster.size()*sizeof(ArgCluster_s),SF_CPU|SF_CLIENT,8);
memcpy(argClustersChunk.data,rui.argCluster.data(),rui.argCluster.size()*sizeof(ArgCluster_s));
pak->AddPointer(hdrChunk,offsetof(RuiHeader_v30_s,argClusters),argClustersChunk,0);

PakPageLump_s argumentsChunk = pak->CreatePageLump(rui.arguments.size()*sizeof(Argument_s),SF_CPU|SF_CLIENT,8);
memcpy(argumentsChunk.data,rui.arguments.data(),rui.arguments.size()*sizeof(Argument_s));
pak->AddPointer(hdrChunk,offsetof(RuiHeader_v30_s,arguments),argumentsChunk,0);

ruiHdr->argNames = 0;

PakPageLump_s styleDescriptorChunk = pak->CreatePageLump(rui.styleDescriptors.size(),SF_CPU|SF_CLIENT,8);
memcpy(styleDescriptorChunk.data,rui.styleDescriptors.data(),rui.styleDescriptors.size());
pak->AddPointer(hdrChunk,offsetof(RuiHeader_v30_s,styleDescriptors),styleDescriptorChunk,0);

PakPageLump_s renderJobChunk = pak->CreatePageLump(rui.renderJobs.size(),SF_CPU|SF_CLIENT,8);
memcpy(renderJobChunk.data,rui.renderJobs.data(),rui.renderJobs.size());
pak->AddPointer(hdrChunk,offsetof(RuiHeader_v30_s,renderJobData),renderJobChunk,0);

asset.InitAsset(hdrChunk.GetPointer(),sizeof(RuiHeader_v30_s),
PagePtr_t::NullPtr(),30,AssetType::UI);
asset.SetHeaderPointer(hdrChunk.data);

pak->FinishAsset();

}

RuiHeader_v30_s RuiPackage::CreateRuiHeader_v30() {
RuiHeader_v30_s ruiHdr;

ruiHdr.elementWidth = hdr.elementWidth;
ruiHdr.elementHeight = hdr.elementHeight;
ruiHdr.elementWidthRcp = hdr.elementWidthRcp;
ruiHdr.elementHeightRcp = hdr.elementHeightRcp;

ruiHdr.argumentCount = hdr.argCount;
ruiHdr.mappingCount = hdr.mappingCount;
ruiHdr.dataStructSize = hdr.dataStructSize;
ruiHdr.dataStructInitSize = hdr.defaultValuesSize;
ruiHdr.styleDescriptorCount = hdr.styleDescriptorCount;
ruiHdr.maxTransformIndex = 0;
ruiHdr.renderJobCount = hdr.renderJobCount;
ruiHdr.argClusterCount = hdr.argClusterCount;

return ruiHdr;
}

RuiPackage::RuiPackage(const fs::path& inputPath) {
FILE* f = NULL;
errno_t errorCode = fopen_s(&f, inputPath.string().c_str(), "rb");
if (errorCode == 0) {
fread(&hdr,sizeof(hdr),1,f);
if(hdr.magic != RUI_PACKAGE_MAGIC)
Error("Attempted to load an invalid RUIP file (expected magic %x, got %x).\n", RUI_PACKAGE_MAGIC, hdr.magic);
if(hdr.packageVersion != RUI_PACKAGE_VERSION)
Error("Attempted to load an unsupported RUIP file (expected version %u, got %u).\n", RUI_PACKAGE_VERSION, hdr.packageVersion);

fseek(f,(long)hdr.nameOffset,0);
name.resize(hdr.nameSize);
fread(name.data(), 1, hdr.nameSize, f);

fseek(f,(long)hdr.defaultValuesOffset,0);
defaultData.resize(hdr.defaultValuesSize);
fread(defaultData.data(),1,hdr.defaultValuesSize,f);

fseek(f,(long)hdr.defaultStringDataOffset,0);
defaultStrings.resize(hdr.defaultStringsDataSize);
fread(defaultStrings.data(),1,hdr.defaultStringsDataSize,f);

fseek(f,(long)hdr.rpakPointersInDefaultDataOffset,0);
defaultStringOffsets.resize(hdr.rpakPointersInDefaltDataCount);
fread(defaultStringOffsets.data(),sizeof(uint16_t),hdr.rpakPointersInDefaltDataCount,f);

fseek(f,(long)hdr.styleDescriptorOffset,0);
styleDescriptors.resize(hdr.styleDescriptorCount*sizeof(StyleDescriptor_v30_s));
fread(styleDescriptors.data(),sizeof(StyleDescriptor_v30_s),hdr.styleDescriptorCount,f);

fseek(f,(long)hdr.renderJobOffset,0);
renderJobs.resize(hdr.renderJobSize);
fread(renderJobs.data(),1,hdr.renderJobSize,f);

fseek(f,(long)hdr.transformDataOffset,0);
transformData.resize(hdr.transformDataSize);
fread(transformData.data(),1,hdr.transformDataSize,f);

fseek(f,(long)hdr.argumentsOffset,0);
arguments.resize(hdr.argCount);
fread(arguments.data(),sizeof(Argument_s),hdr.argCount,f);

fseek(f,(long)hdr.argClusterOffset,0);
argCluster.resize(hdr.argClusterCount);
fread(argCluster.data(),sizeof(ArgCluster_s),hdr.argClusterCount,f);

fclose(f);
}
else {
Error("Could not open ruip file %s with error %x",inputPath.string().c_str(),errorCode);
}
}






void Assets::AddRuiAsset_v30(CPakFileBuilder* const pak, const PakGuid_t assetGuid, const char* const assetPath, const rapidjson::Value& mapEntry)
{
UNUSED(mapEntry);
Rui_loadFromPackage(pak,assetGuid,assetPath);
}
6 changes: 4 additions & 2 deletions src/logic/pakfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ static std::unordered_set<PakAssetHandler_s, PakAssetHasher_s> s_pakAssetHandler
{"aseq", PakAssetScope_e::kAll, nullptr, Assets::AddAnimSeqAsset_v7},
{"arig", PakAssetScope_e::kAll, nullptr, Assets::AddAnimRigAsset_v4},
{"txls", PakAssetScope_e::kAll, nullptr, Assets::AddTextureListAsset_v1},
{"Ptch", PakAssetScope_e::kAll, Assets::AddPatchAsset, Assets::AddPatchAsset}
{"Ptch", PakAssetScope_e::kAll, Assets::AddPatchAsset, Assets::AddPatchAsset},
{"ui", PakAssetScope_e::kClientOnly, Assets::AddRuiAsset_v30, nullptr}

};

void CPakFileBuilder::AddJSONAsset(const PakAssetHandler_s& assetHandler, const char* const assetPath, const rapidjson::Value& file)
Expand Down Expand Up @@ -439,7 +441,7 @@ PakAsset_t* CPakFileBuilder::GetAssetByGuid(const PakGuid_t guid, size_t* const
}
i++;
}
if(!silent)
if (!silent)
Debug("Failed to find asset with guid %llX.\n", guid);
return nullptr;
}
Expand Down
2 changes: 2 additions & 0 deletions src/public/rpak.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#define TYPE_ARIG MAKE_FOURCC('a', 'r', 'i', 'g') // arig
#define TYPE_SHDS MAKE_FOURCC('s', 'h', 'd', 's') // shds
#define TYPE_SHDR MAKE_FOURCC('s', 'h', 'd', 'r') // shdr
#define TYPE_UI MAKE_FOURCC('u', 'i', 0, 0) // ui

enum class AssetType : uint32_t
{
Expand All @@ -63,6 +64,7 @@ enum class AssetType : uint32_t
ARIG = TYPE_ARIG, // animation rig
SHDS = TYPE_SHDS, // shaderset
SHDR = TYPE_SHDR, // shader
UI = TYPE_UI
};

#pragma pack(push, 1)
Expand Down
159 changes: 159 additions & 0 deletions src/public/rui.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#pragma once


#define RUI_PACKAGE_MAGIC ('R' | ('U' << 8) | ('I' << 16) | ('P' << 24))
#define RUI_PACKAGE_VERSION 1

#pragma pack(push)
struct RuiPackageHeader_v1_t {
uint32_t magic;
uint16_t packageVersion;
uint16_t ruiVersion;
uint64_t nameOffset;
float elementWidth;
float elementHeight;
float elementWidthRcp;
float elementHeightRcp;
uint16_t defaultValuesSize;
uint16_t dataStructSize;
uint16_t styleDescriptorCount;
uint16_t unk_A4;//unused in r2
uint16_t renderJobCount;
uint16_t argClusterCount;
uint16_t argCount;
uint16_t mappingCount;
uint16_t transformDataSize;
uint16_t nameSize;
uint16_t rpakPointersInDefaltDataCount;
uint8_t pad[2];
uint32_t argNamesSize;
uint32_t renderJobSize;
uint32_t mappingSize;
uint32_t defaultStringsSize;
uint64_t argNamesOffset;//debug only
uint64_t argClusterOffset;
uint64_t argumentsOffset;
uint64_t styleDescriptorOffset;
uint64_t renderJobOffset;
uint64_t mappingOffset;
uint64_t transformDataOffset;
uint64_t defaultValuesOffset;
uint64_t defaultStringDataOffset;
uint64_t rpakPointersInDefaultDataOffset;
uint64_t defaultStringsDataSize;
};
#pragma pack(pop)

enum class VariableType : uint8_t {
NONE = 0x0,
STRING = 0x1,
ASSET = 0x2,
BOOL = 0x3,
INT = 0x4,
FLOAT = 0x5,
FLOAT2 = 0x6,
FLOAT3 = 0x7,
COLOR_ALPHA = 0x8,
GAMETIME = 0x9,
FLOAT_UNK = 0xA,
IMAGE = 0xB

};

struct Argument_s
{
VariableType type;

uint8_t unk_1;

uint16_t dataOffset;
uint16_t nameOffset;

uint16_t shortHash;
};

struct ArgCluster_s
{
uint16_t argIndex;
uint16_t argCount;

uint8_t byte_4;
uint8_t byte_5;

uint16_t short_6;
uint16_t valueSize;
uint16_t dataStructSize;
uint16_t short_C;
uint16_t short_E;
uint16_t renderJobCount;
};

struct IndexedColor_s {
uint16_t red;
uint16_t green;
uint16_t blue;
uint16_t alpha;
};

struct StyleDescriptor_v30_s {
uint16_t type;
IndexedColor_s color0;
IndexedColor_s color1;
IndexedColor_s color2;
uint16_t blend;
uint16_t premul;
uint16_t val_1E;
uint16_t val_20;
uint16_t val_22;
uint16_t val_24;
uint16_t val_26;
uint16_t val_28;
uint16_t val_2A;
uint16_t val_2C;
uint16_t val_2E;
uint16_t val_30;
uint16_t val_32;
};


struct RuiHeader_v30_s
{
const char* name;
uint8_t* dataStructInitData;
uint8_t* transformData;
float elementWidth;
float elementHeight;
float elementWidthRcp;
float elementHeightRcp;
char* argNames;
ArgCluster_s* argClusters;
Argument_s* arguments;
short argumentCount; // number of slots for arguments. not all are used. has to be power of 2
short mappingCount;
uint16_t dataStructSize;
uint16_t dataStructInitSize;
uint16_t styleDescriptorCount;
uint16_t maxTransformIndex;
uint16_t renderJobCount;
uint16_t argClusterCount;
StyleDescriptor_v30_s* styleDescriptors;
uint8_t* renderJobData;
void* valueMappings; // maps values to others through linar/qubicSpline regression
};

struct RuiPackage {
RuiPackageHeader_v1_t hdr{};

RuiPackage(const fs::path& inputPath);
RuiHeader_v30_s CreateRuiHeader_v30();
std::vector<char> name;
std::vector<char> defaultData;
std::vector<char> defaultStrings;
std::vector<uint16_t> defaultStringOffsets;
std::vector<char> transformData;
std::vector<char> renderJobs;
std::vector<Argument_s> arguments;
std::vector<ArgCluster_s> argCluster;
std::vector<char> styleDescriptors;

};