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
3,279 changes: 3,279 additions & 0 deletions RASM/Data/RDRNativesPC.csv

Large diffs are not rendered by default.

154 changes: 104 additions & 50 deletions RASM/Include/Compiler/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1111,6 +1111,30 @@ void CompileBase::ParseOpcode(Opcode op)
case Opcode::SetGlobalSR:
case Opcode::GetGlobalPs:
case Opcode::GetHash:
case Opcode::PushStringNull:
case Opcode::PatchRet:
case Opcode::PatchTrap0:
case Opcode::PatchTrap1:
case Opcode::PatchTrap2:
case Opcode::PatchTrap3:
case Opcode::PatchTrap4:
case Opcode::PatchTrap5:
case Opcode::PatchTrap6:
case Opcode::PatchTrap7:
case Opcode::PatchTrap8:
case Opcode::PatchTrap9:
case Opcode::PatchTrapA:
case Opcode::PatchTrapB:
case Opcode::PatchTrapC:
case Opcode::PatchTrapD:
case Opcode::PatchTrapE:
case Opcode::PatchTrapF:
case Opcode::CallPatch:
case Opcode::CallOutOfPatch:
case Opcode::LoadRef:
case Opcode::StoreRef:
case Opcode::StoreVector:
case Opcode::MakeVector:
AddSingleOp(op);
break;

Expand Down Expand Up @@ -1721,10 +1745,10 @@ void CompileRDR::AddPushString()
str.resize(0xFF - 1);
}

FixCodePage(2 + str.size() + 1);
AddSingleOp(Opcode::PushString);
CodeBuilder->WriteUInt8(str.size() + 1);
CodeBuilder->WriteString(str);

}

void CompileRDR::AddPushArray()
Expand All @@ -1737,11 +1761,14 @@ void CompileRDR::AddPushArray()
hexData.resize(0xFFFFFFFF);
}

auto vec = Utils::DataConversion::HexToData(hexData);

FixCodePage(1 + 4 + vec.size());

AddSingleOp(Opcode::PushArray);
CodeBuilder->WriteUInt32(hexData.size());
CodeBuilder->WriteUInt32(vec.size());

auto vec = Utils::DataConversion::HexToData(hexData);
CodeBuilder->WriteData(vec.data(), hexData.size());
CodeBuilder->WriteData(vec.data(), vec.size());
}

void CompileRDR::AddCall()
Expand Down Expand Up @@ -1815,76 +1842,91 @@ void CompileRDR::AddReturn()

void CompileRDR::WriteScript(const std::string& scriptOutPath)
{
DataBuilderBig script;
script.BlockSize = 16384;
std::unique_ptr<DataBuilder> script;
if (Options::Platform == Platform::PC)
script = std::make_unique<DataBuilderLit>();
else
script = std::make_unique<DataBuilderBig>();

script.Data.reserve(sizeof(RDRHeader) + CodeBuilder->Data.size() + Statics.size() * sizeof(uint32_t) + NativeIndexes.size() * sizeof(uint32_t) + script.BlockSize);
script->BlockSize = 16384;

uint32_t codeOffset = script.Data.size();
script.WriteData(CodeBuilder->Data.data(), CodeBuilder->Data.size());
script.Pad(16, 0xCD);
script->Data.reserve(sizeof(RDRHeader) + CodeBuilder->Data.size() + Statics.size() * sizeof(uint32_t) + NativeIndexes.size() * sizeof(uint32_t) + script->BlockSize);

uint32_t nativesOffset = script.Data.size();
script.PadDirect(NativeIndexes.size() * sizeof(uint32_t));
uint32_t codeOffset = script->Data.size();
script->WriteData(CodeBuilder->Data.data(), CodeBuilder->Data.size());
script->Pad(16, 0xCD);

uint32_t nativesLength = NativeIndexes.size() * sizeof(uint32_t);
if (script->IsWriteOverPage(nativesLength))
script->PadPage(0xCD);

uint32_t nativesOffset = script->Data.size();
script->PadDirect(nativesLength);
for (auto i : NativeIndexes)
{
script.SetUInt32((uint32_t)i.first, nativesOffset + i.second * sizeof(uint32_t));
script->SetUInt32((uint32_t)i.first, nativesOffset + i.second * sizeof(uint32_t));
}
script.Pad(16, 0xCD);
script->Pad(16, 0xCD);

uint32_t staticsOffset = script.Data.size();
uint32_t staticsLength = Statics.size() * sizeof(uint32_t);
if (script->IsWriteOverPage(staticsLength))
script->PadPage(0xCD);

uint32_t staticsOffset = script->Data.size();
for (auto i : Statics)
{
script.WriteInt32(i);
auto value = i;
if (Options::Platform == Platform::PC) // PC must have statics in big-endian
value = Utils::Bitwise::SwapEndian(value);
script->WriteInt32(value);
}
script.Pad(16, 0xCD);
script->Pad(16, 0xCD);

uint32_t codeBlocksOffset = script.Data.size();
uint32_t codeBlocksOffset = script->Data.size();

for (int i = 0; i < CodeBuilder->Data.size(); i += CodeBuilder->BlockSize)
script.WriteUInt32(RelPtr(codeOffset + i).Value);
script->WriteUInt32(RelPtr(codeOffset + i).Value);

script.Pad(16, 0xCD);
script->Pad(16, 0xCD);

uint32_t pageMap[8] = { 0, 0, 1, 0, 0, 0, 0, 0 };
uint32_t pageMapOffset = script.Data.size();
script.WriteData(pageMap, sizeof(uint32_t) * 8);
uint32_t pageMapOffset = script->Data.size();
script->WriteData(pageMap, sizeof(uint32_t) * 8);



uint32_t totalSize = script.Data.size() + sizeof(RDRHeader);
script.Data.resize(totalSize, 0xCD);
uint32_t totalSize = script->Data.size() + sizeof(RDRHeader);
script->Data.resize(totalSize, 0xCD);

vector<uint32_t> DataSizePages = GetPageSizes(totalSize);
uint32_t HeaderStartIndex = GetHeaderPagePos(DataSizePages);
if (totalSize != script.Data.size())
script.Data.resize(totalSize, 0xCD);
if (totalSize != script->Data.size())
script->Data.resize(totalSize, 0xCD);

//poor mans header pos
//should be shrunk
while (HeaderStartIndex < pageMapOffset)
{
totalSize = script.Data.size() + 16384;
script.Data.resize(totalSize, 0xCD);
totalSize = script->Data.size() + 16384;
script->Data.resize(totalSize, 0xCD);

DataSizePages = GetPageSizes(totalSize);
HeaderStartIndex = GetHeaderPagePos(DataSizePages);
if (totalSize != script.Data.size())
script.Data.resize(totalSize, 0xCD);
if (totalSize != script->Data.size())
script->Data.resize(totalSize, 0xCD);
}


script.SetUInt32(0xA8D74300, HeaderStartIndex + offsetof(RDRHeader, PgBase));
script.SetUInt32((uint32_t)SignatureType, HeaderStartIndex + offsetof(RDRHeader, Signature));
script.SetUInt32((uint32_t)CodeBuilder->Data.size(), HeaderStartIndex + offsetof(RDRHeader, CodeLength));
script.SetUInt32(ParameterCount, HeaderStartIndex + offsetof(RDRHeader, ParameterCount));
script.SetUInt32(Statics.size(), HeaderStartIndex + offsetof(RDRHeader, StaticsCount));
script.SetUInt32(NativeIndexes.size(), HeaderStartIndex + offsetof(RDRHeader, NativesCount));
script.SetUInt32(RelPtr(nativesOffset).Value, HeaderStartIndex + offsetof(RDRHeader, NativesOffset));
script.SetUInt32(RelPtr(staticsOffset).Value, HeaderStartIndex + offsetof(RDRHeader, StaticsOffset));
script.SetUInt32(RelPtr(codeBlocksOffset).Value, HeaderStartIndex + offsetof(RDRHeader, CodeBlocksOffset));
script.SetUInt32(RelPtr(pageMapOffset).Value, HeaderStartIndex + offsetof(RDRHeader, PageMapOffset));
script->SetUInt32(Options::Platform == Platform::PC ? 0x0016E444 : 0xA8D74300, HeaderStartIndex + offsetof(RDRHeader, PgBase));
script->SetUInt32((uint32_t)SignatureType, HeaderStartIndex + offsetof(RDRHeader, Signature));
script->SetUInt32((uint32_t)CodeBuilder->Data.size(), HeaderStartIndex + offsetof(RDRHeader, CodeLength));
script->SetUInt32(ParameterCount, HeaderStartIndex + offsetof(RDRHeader, ParameterCount));
script->SetUInt32(Statics.size(), HeaderStartIndex + offsetof(RDRHeader, StaticsCount));
script->SetUInt32(NativeIndexes.size(), HeaderStartIndex + offsetof(RDRHeader, NativesCount));
script->SetUInt32(RelPtr(nativesOffset).Value, HeaderStartIndex + offsetof(RDRHeader, NativesOffset));
script->SetUInt32(RelPtr(staticsOffset).Value, HeaderStartIndex + offsetof(RDRHeader, StaticsOffset));
script->SetUInt32(RelPtr(codeBlocksOffset).Value, HeaderStartIndex + offsetof(RDRHeader, CodeBlocksOffset));
script->SetUInt32(RelPtr(pageMapOffset).Value, HeaderStartIndex + offsetof(RDRHeader, PageMapOffset));


switch (Options::Platform)
Expand All @@ -1899,36 +1941,45 @@ void CompileRDR::WriteScript(const std::string& scriptOutPath)
compressedData.SetUInt32(0x0FF512F1, 0);//LZX Signature?


Utils::Compression::XCompress_Compress(script.Data.data(), totalSize, compressedData.Data.data() + 8, &compressedSize);
Utils::Compression::XCompress_Compress(script->Data.data(), totalSize, compressedData.Data.data() + 8, &compressedSize);

compressedData.Data.resize(compressedSize + 8);

compressedData.SetUInt32(compressedSize, 4);

script.Data = compressedData.Data;
script->Data = compressedData.Data;

}
break;
case Platform::PSX:
{
vector<uint8_t> compressedData(totalSize);

Utils::Compression::ZLIB_CompressNew(script.Data, compressedData);
Utils::Compression::ZLIB_CompressNew(script->Data, compressedData);

script->Data = compressedData;
}
break;
case Platform::PC:
{
vector<uint8_t> compressedData(totalSize);

Utils::Compression::ZSTD_CompressNew(script->Data, compressedData);

script.Data = compressedData;
script->Data = compressedData;
}
break;
}


if (!Utils::Crypt::AES_Encrypt(script.Data.data(), script.Data.size(), RDRKey))
if (!Utils::Crypt::AES_Encrypt(script->Data.data(), script->Data.size(), RDRKey))
Utils::System::Throw("Encryption Failed");


CSRHeader csr =
{
Utils::Bitwise::SwapEndian(Options::Platform == Platform::XBOX ? 0x85435352u : 0x86435352u),
Utils::Bitwise::SwapEndian(0x00000002u)
Options::Platform == Platform::PC ? 0x85435352u : Utils::Bitwise::SwapEndian(Options::Platform == Platform::XBOX ? 0x85435352u : 0x86435352u),
Options::Platform == Platform::PC ? 0x00000002u : Utils::Bitwise::SwapEndian(0x00000002u)
};


Expand All @@ -1937,14 +1988,17 @@ void CompileRDR::WriteScript(const std::string& scriptOutPath)
csr.Flags.TotalVSize = totalSize >> 12;//platform dependent? (currently xbox)
csr.Flags.ObjectStartPage = ObjectStartPageSizeToFlag(DataSizePages[DataSizePages.size() - 1]);

csr.Flags.Flag[0] = Utils::Bitwise::SwapEndian(csr.Flags.Flag[0]);
csr.Flags.Flag[1] = Utils::Bitwise::SwapEndian(csr.Flags.Flag[1]);
if (Options::Platform != Platform::PC)
{
csr.Flags.Flag[0] = Utils::Bitwise::SwapEndian(csr.Flags.Flag[0]);
csr.Flags.Flag[1] = Utils::Bitwise::SwapEndian(csr.Flags.Flag[1]);
}

FILE* file = nullptr;
if (Utils::IO::CreateFileWithDir(scriptOutPath.c_str(), file))
{
fwrite(&csr, 1, sizeof(csr), file);
fwrite(script.Data.data(), 1, script.Data.size(), file);
fwrite(script->Data.data(), 1, script->Data.size(), file);
fclose(file);
}

Expand Down
26 changes: 25 additions & 1 deletion RASM/Include/Compiler/Compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ class CompileBase
}

//RDR2 requires sorted cases
std::sort(casesAndLabels.begin(), casesAndLabels.end());
if (Options::GameTarget == GameTarget::RDR2)
std::sort(casesAndLabels.begin(), casesAndLabels.end());

writeSwitch(casesAndLabels);

Expand Down Expand Up @@ -570,6 +571,29 @@ class CompileRDR : public CompileBase
{Opcode::PushF_5, 153},
{Opcode::PushF_6, 154},
{Opcode::PushF_7, 155},
{Opcode::PatchRet, 156},
{Opcode::PatchTrap0, 157},
{Opcode::PatchTrap1, 158},
{Opcode::PatchTrap2, 159},
{Opcode::PatchTrap3, 160},
{Opcode::PatchTrap4, 161},
{Opcode::PatchTrap5, 162},
{Opcode::PatchTrap6, 163},
{Opcode::PatchTrap7, 164},
{Opcode::PatchTrap8, 165},
{Opcode::PatchTrap9, 166},
{Opcode::PatchTrapA, 167},
{Opcode::PatchTrapB, 168},
{Opcode::PatchTrapC, 169},
{Opcode::PatchTrapD, 170},
{Opcode::PatchTrapE, 171},
{Opcode::PatchTrapF, 172},
{Opcode::CallPatch, 173},
{Opcode::CallOutOfPatch, 174},
{Opcode::LoadRef, 175},
{Opcode::StoreRef, 176},
{Opcode::StoreVector, 177},
{Opcode::MakeVector, 178},
};
#pragma endregion

Expand Down
Loading