diff --git a/src/interpreter.cc b/src/interpreter.cc index 23793ac..c431c53 100644 --- a/src/interpreter.cc +++ b/src/interpreter.cc @@ -2,10 +2,14 @@ #include #include +#include +#include #include +#include #include #include #include +#include #include "db.h" #include "debug.h" @@ -2506,6 +2510,84 @@ static void opLookupStringProc(Program* program) programFatalError(err); } +void checkScriptsOpcodes() +{ + printf("Checking scripts opcodes\n"); + + std::map> unknown_opcodes; + + // char path[COMPAT_MAX_PATH] = { 0 }; + // strcpy(path, _cd_path_base); + // strcat(path, gScriptsBasePath); + // strcat(path, filename); + // strcat(path, ".int"); + + auto check_file = [&unknown_opcodes](std::string fName) { + File* stream = fileOpen(fName.c_str(), "rb"); + if (stream == NULL) { + printf("Error opening %s\n", fName.c_str()); + exit(1); + } + + int fileSize = fileGetSize(stream); + // TODO: Use smart ptr + auto data = (unsigned char*)malloc(fileSize); + + fileRead(data, 1, fileSize, stream); + fileClose(stream); + + { + auto check_data = [&fName, &unknown_opcodes](unsigned char* data, size_t len) { + size_t i = 0; + while (i < len) { + opcode_t opcode = stackReadInt16(data, i); + if (!((opcode >> 8) & 0x80)) { + printf("ERROR\n"); + return; + }; + unsigned int opcodeIndex = opcode & 0x3FF; + OpcodeHandler* handler = gInterpreterOpcodeHandlers[opcodeIndex]; + if (handler == NULL) { + auto& set = unknown_opcodes[opcode]; + set.insert(fName); + }; + + i += 2; + + if (opcodeIndex == (OPCODE_PUSH & 0x3FF)) { + i += 4; + } + } + }; + + check_data(data, 0); + + auto identifiers = data + 24 * stackReadInt32(data, 42) + 42 + 4; + auto static_strings = identifiers + stackReadInt32(identifiers, 0) + 4 + 4; + auto code_pos = static_strings + stackReadInt32(static_strings, 0) + 4 + 4; + + check_data(code_pos, fileSize - (code_pos - data)); + } + + free(data); + }; + + check_file(std::string("master.dat/scripts/OBJ_DUDE.int")); + + if (unknown_opcodes.size() == 0) { + printf("Everything is ok, all opcodes are known\n"); + } else { + printf("Unknown opcodes:\n"); + for (auto iter : unknown_opcodes) { + printf("%x:\n", iter.first); + for (auto fName : iter.second) { + printf(" - %s\n", fName.c_str()); + } + } + } + printf("Done\n"); +} + // 0x46C7DC void interpreterRegisterOpcodeHandlers() { @@ -2591,6 +2673,8 @@ void interpreterRegisterOpcodeHandlers() intLibInit(); _initExport(); + + checkScriptsOpcodes(); } // 0x46CC68