Skip to content

Commit

Permalink
emit vm8b crc at compilation and ignore vtable for vm8b
Browse files Browse the repository at this point in the history
  • Loading branch information
ate47 committed May 31, 2024
1 parent 0ac0a8d commit 49d2a2a
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 21 deletions.
33 changes: 31 additions & 2 deletions src/acts/compiler/gsc_compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1265,8 +1265,8 @@ namespace acts::compiler {
}

bool Compile(std::vector<byte>& data) {
// add the notify crc function for T9 vm
if (gscHandler->HasFlag(tool::gsc::GOHF_NOTIFY_CRC)) {
// add the notify crc function for T9 38 vm
constexpr const char* name = "$notif_checkum";
uint64_t nameHashed = vmInfo->HashField(name);
AddHash(name);
Expand Down Expand Up @@ -1305,6 +1305,35 @@ namespace acts::compiler {
f.m_nodes.push_back(new AscmNodeOpCode(OPCODE_Notify));
f.m_nodes.push_back(new AscmNodeOpCode(OPCODE_End));
}
else if (gscHandler->HasFlag(tool::gsc::GOHF_NOTIFY_CRC_STRING)) {
// add the notify crc function for JUP B vm

constexpr const char* name = "$notif_checkum";
uint64_t nameHashed = vmInfo->HashField(name);
AddHash(name);
auto [res, err] = exports.try_emplace(nameHashed, *this, nameHashed, currentNamespace, fileNameSpace, vmInfo);

if (!err) {
LOG_ERROR("Can't register notif checksum export: {}", name);
return false;
}

FunctionObject& f = res->second;
f.autoexecOrder = INT64_MIN; // first
f.m_flags = tool::gsc::CLASS_VTABLE;
f.m_nodes.push_back(new AscmNodeOpCode(OPCODE_CheckClearParams));
f.m_nodes.push_back(new AscmNodeOpCode(OPCODE_PreScriptCall));

const char* crcStr = utils::va("%d", crc);

RefObject& strdef = strings[crcStr];
auto* getstr = new AscmNodeData<uint32_t>(0xFFFFFFFF, OPCODE_GetString);
strdef.nodes.push_back(getstr);
f.m_nodes.push_back(getstr);
f.m_nodes.push_back(new AscmNodeOpCode(OPCODE_IW_GetLevel));
f.m_nodes.push_back(new AscmNodeOpCode(OPCODE_IW_Notify));
f.m_nodes.push_back(new AscmNodeOpCode(OPCODE_End));
}

// set builtin call types for jup VM
if (!gscHandler->HasFlag(tool::gsc::GOHF_SUPPORT_GET_API_SCRIPT)) {
Expand Down Expand Up @@ -4323,7 +4352,7 @@ namespace acts::compiler {
const char* outFile{ utils::va("%s.%s", opt.m_outFileName, client ? "cscc" : "gscc")};
utils::WriteFile(outFile, (const void*)data.data(), data.size());

LOG_INFO("Done into {}", outFile);
LOG_INFO("Done into {} ({}/{})", outFile, obj.vmInfo->codeName, PlatformName(obj.plt));
return tool::OK;
};

Expand Down
46 changes: 31 additions & 15 deletions src/acts/tools/gsc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1990,9 +1990,29 @@ int tool::gsc::DumpAsm(GSCExportReader& exp, std::ostream& out, GSCOBJHandler& g

int tool::gsc::DumpVTable(GSCExportReader& exp, std::ostream& out, GSCOBJHandler& gscFile, T8GSCOBJContext& objctx, ASMContext& ctx, DecompContext& dctxt) {
using namespace tool::gsc::opcode;
uint16_t code = *(uint16_t*)ctx.Aligned<uint16_t>();
auto FetchCode = [&ctx, &dctxt, &out]() -> const opcode::OPCodeInfo* {
uint16_t code;
if (ctx.m_objctx.m_vmInfo->HasFlag(VmFlags::VMF_OPCODE_U16)) {
if (ctx.m_objctx.m_vmInfo->HasFlag(VmFlags::VMF_ALIGN)) {
ctx.Aligned<uint16_t>();
}
code = *(uint16_t*)ctx.m_bcl;
ctx.m_bcl += 2;
} else {
code = (uint16_t)*ctx.m_bcl;
ctx.m_bcl += 1;
}
const opcode::OPCodeInfo* ret{ ctx.LookupOpCode(code) };

if (!ret || ret->m_id == OPCODE_Undefined) {
dctxt.WritePadding(out) << "Bad vtable opcode: " << std::hex << code << "\n";
}

return ret;
};

// main reading loop
const auto* ccp = ctx.LookupOpCode(code);
const auto* ccp = FetchCode();

/*
* Start
Expand All @@ -2007,39 +2027,35 @@ int tool::gsc::DumpVTable(GSCExportReader& exp, std::ostream& out, GSCOBJHandler
*/

if (!ccp || ccp->m_id != OPCODE_CheckClearParams) {
//dctxt.WritePadding(out) << "Bad vtable opcode: " << std::hex << code << ", expected CheckClearParams\n";
// dctxt.WritePadding(out) << "Bad vtable opcode: expected CheckClearParams\n";
return DVA_NOT;
}

ctx.m_bcl += 2;

const auto* preScriptCall = ctx.LookupOpCode(code = *(uint16_t*)ctx.Aligned<uint16_t>());
const auto* preScriptCall = FetchCode();


if (!preScriptCall || preScriptCall->m_id != OPCODE_PreScriptCall) {
//dctxt.WritePadding(out) << "Bad vtable opcode: " << std::hex << code << ", expected PreScriptCall\n";
// dctxt.WritePadding(out) << "Bad vtable opcode: expected PreScriptCall\n";
return DVA_NOT;
}

ctx.m_bcl += 2;

const auto* spawnStruct = ctx.LookupOpCode(code = *(uint16_t*)ctx.Aligned<uint16_t>());
const auto* spawnStruct = FetchCode();


if (!spawnStruct) {
//dctxt.WritePadding(out) << "Bad vtable opcode: " << std::hex << code << "\n";
// dctxt.WritePadding(out) << "Bad vtable opcode\n";
return DVA_NOT;
}

if (spawnStruct->m_id != OPCODE_ScriptFunctionCall && spawnStruct->m_id != OPCODE_CallBuiltinFunction) {
if (gscFile.GetVM() == VM_T9) {
if (ctx.m_vm == VM_T9 || ctx.m_vm == VM_MW23B) {
return DVA_OK; // crc dump
}
//dctxt.WritePadding(out) << "Bad vtable opcode: " << std::hex << code << ", expected ScriptFunctionCall\n";
// dctxt.WritePadding(out) << "Bad vtable opcode, expected ScriptFunctionCall vm" << std::hex << (int)ctx.m_vm << "\n";
return DVA_NOT;
}

ctx.m_bcl += 2 + 1; // call
ctx.m_bcl += 1; // call
ctx.Aligned<uint64_t>() += 8; // assume that we have a spawnstruct

ctx.Aligned<uint16_t>() += 2; // GetZero
Expand Down
1 change: 1 addition & 0 deletions src/acts/tools/gsc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ namespace tool::gsc {
GOHF_FOREACH_TYPE_MASK = GOHF_FOREACH_TYPE_V1 | GOHF_FOREACH_TYPE_V2 | GOHF_FOREACH_TYPE_V3,
GOHF_SUPPORT_GET_API_SCRIPT = 0x1000,
GOHF_STRING_NAMES = 0x2000,
GOHF_NOTIFY_CRC_STRING = 0x4000,
};
static_assert(
((GOHF_FOREACH_TYPE_T8 | GOHF_FOREACH_TYPE_T9 | GOHF_FOREACH_TYPE_JUP | GOHF_FOREACH_TYPE_T7
Expand Down
13 changes: 9 additions & 4 deletions src/acts/tools/gsc_vm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1107,7 +1107,7 @@ class MW23GSCOBJHandler : public GSCOBJHandler {

class MW23BGSCOBJHandler : public GSCOBJHandler {
public:
MW23BGSCOBJHandler(byte* file, size_t fileSize) : GSCOBJHandler(file, fileSize, GOHF_ANIMTREE | GOHF_ANIMTREE_DOUBLE | GOHF_FOREACH_TYPE_JUP) {}
MW23BGSCOBJHandler(byte* file, size_t fileSize) : GSCOBJHandler(file, fileSize, GOHF_ANIMTREE | GOHF_ANIMTREE_DOUBLE | GOHF_FOREACH_TYPE_JUP | GOHF_NOTIFY_CRC_STRING) {}

void DumpHeader(std::ostream& asmout, const GscInfoOption& opt) override {
auto* data = Ptr<GscObj23>();
Expand Down Expand Up @@ -1238,7 +1238,10 @@ class MW23BGSCOBJHandler : public GSCOBJHandler {
return sizeof(GscObj23);
}
char* DecryptString(char* str) override {
return str + 3; // iw
if ((*str & 0xC0) != 0x80) {
return str; // not encrypted
}
return str + 3; // should be decrypted before
}
bool IsValidHeader(size_t size) override {
return size >= sizeof(GscObj23) && *reinterpret_cast<uint64_t*>(file) == 0xa0d4353478b;
Expand Down Expand Up @@ -1307,6 +1310,7 @@ class MW23BGSCOBJHandler : public GSCOBJHandler {

byte RemapFlagsExport(byte flags) override {
byte nflags{};
if (flags == 0x15) return tool::gsc::CLASS_VTABLE;
if (flags & 1) {
nflags |= T8GSCExportFlags::AUTOEXEC;
}
Expand All @@ -1325,6 +1329,7 @@ class MW23BGSCOBJHandler : public GSCOBJHandler {

byte MapFlagsExportToInt(byte flags) override {
byte nflags = 0;
if (flags == tool::gsc::CLASS_VTABLE) return 0x15;

if (flags & AUTOEXEC) nflags |= 1;
if (flags & LINKED) nflags |= 2;
Expand All @@ -1350,7 +1355,7 @@ class MW23BGSCOBJHandler : public GSCOBJHandler {
Ptr<GscObj23>()->name = name;
}
void SetHeader() override {
Ref<uint64_t>() = 0xa0d4353478a;
Ref<uint64_t>() = 0xa0d4353478b;
}
void SetExportsCount(uint16_t val) override {
Ptr<GscObj23>()->export_count = val;
Expand Down Expand Up @@ -1449,7 +1454,7 @@ class MW23BGSCOBJHandler : public GSCOBJHandler {
return ""; // idc
}
bool IsVTableImportFlags(byte flags) override {
return false;
return flags == 0x15;
}
};

Expand Down

0 comments on commit 49d2a2a

Please sign in to comment.