Add simple script scanner
This commit is contained in:
parent
a06097aef5
commit
ead87c78e7
|
@ -2,10 +2,14 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
@ -2506,6 +2510,84 @@ static void opLookupStringProc(Program* program)
|
||||||
programFatalError(err);
|
programFatalError(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void checkScriptsOpcodes()
|
||||||
|
{
|
||||||
|
printf("Checking scripts opcodes\n");
|
||||||
|
|
||||||
|
std::map<opcode_t, std::set<std::string>> 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
|
// 0x46C7DC
|
||||||
void interpreterRegisterOpcodeHandlers()
|
void interpreterRegisterOpcodeHandlers()
|
||||||
{
|
{
|
||||||
|
@ -2591,6 +2673,8 @@ void interpreterRegisterOpcodeHandlers()
|
||||||
|
|
||||||
intLibInit();
|
intLibInit();
|
||||||
_initExport();
|
_initExport();
|
||||||
|
|
||||||
|
checkScriptsOpcodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x46CC68
|
// 0x46CC68
|
||||||
|
|
Loading…
Reference in New Issue