Fix storing pointers in map global variables

This commit is contained in:
Alexander Batalov 2022-11-09 14:35:07 +03:00
parent 3f25c9265b
commit 6c03e4e293
3 changed files with 37 additions and 10 deletions

View File

@ -1220,16 +1220,20 @@ static void opGetMapVar(Program* program)
{ {
int data = programStackPopInteger(program); int data = programStackPopInteger(program);
int value = mapGetGlobalVar(data); ProgramValue value;
if (mapGetGlobalVar(data, value) == -1) {
value.opcode = VALUE_TYPE_INT;
value.integerValue = -1;
}
programStackPushInteger(program, value); programStackPushValue(program, value);
} }
// set_map_var // set_map_var
// 0x4558C8 // 0x4558C8
static void opSetMapVar(Program* program) static void opSetMapVar(Program* program)
{ {
int value = programStackPopInteger(program); ProgramValue value = programStackPopValue(program);
int variable = programStackPopInteger(program); int variable = programStackPopInteger(program);
mapSetGlobalVar(variable, value); mapSetGlobalVar(variable, value);

View File

@ -164,6 +164,11 @@ static char _scratchStr[40];
// 0x631E78 // 0x631E78
static char _map_path[COMPAT_MAX_PATH]; static char _map_path[COMPAT_MAX_PATH];
// CE: Basically the same problem described in |gMapLocalPointers|, but this
// time Olympus folks use global map variables to store objects (looks like
// only `self_obj`).
static std::vector<void*> gMapGlobalPointers;
// CE: There is a bug in the user-space scripting where they want to store // CE: There is a bug in the user-space scripting where they want to store
// pointers to |Object| instances in local vars. This is obviously wrong as it's // pointers to |Object| instances in local vars. This is obviously wrong as it's
// meaningless to save these pointers in file. As a workaround use second array // meaningless to save these pointers in file. As a workaround use second array
@ -390,27 +395,41 @@ int mapSetElevation(int elevation)
} }
// 0x482220 // 0x482220
int mapSetGlobalVar(int var, int value) int mapSetGlobalVar(int var, ProgramValue& value)
{ {
if (var < 0 || var >= gMapGlobalVarsLength) { if (var < 0 || var >= gMapGlobalVarsLength) {
debugPrint("ERROR: attempt to reference map var out of range: %d", var); debugPrint("ERROR: attempt to reference map var out of range: %d", var);
return -1; return -1;
} }
gMapGlobalVars[var] = value; if (value.opcode == VALUE_TYPE_PTR) {
gMapGlobalVars[var] = 0;
gMapGlobalPointers[var] = value.pointerValue;
} else {
gMapGlobalVars[var] = value.integerValue;
gMapGlobalPointers[var] = nullptr;
}
return 0; return 0;
} }
// 0x482250 // 0x482250
int mapGetGlobalVar(int var) int mapGetGlobalVar(int var, ProgramValue& value)
{ {
if (var < 0 || var >= gMapGlobalVarsLength) { if (var < 0 || var >= gMapGlobalVarsLength) {
debugPrint("ERROR: attempt to reference map var out of range: %d", var); debugPrint("ERROR: attempt to reference map var out of range: %d", var);
return 0; return -1;
} }
return gMapGlobalVars[var]; if (gMapGlobalPointers[var] != nullptr) {
value.opcode = VALUE_TYPE_PTR;
value.pointerValue = gMapGlobalPointers[var];
} else {
value.opcode = VALUE_TYPE_INT;
value.integerValue = gMapGlobalVars[var];
}
return 0;
} }
// 0x482280 // 0x482280
@ -1521,6 +1540,8 @@ static int mapGlobalVariablesInit(int count)
if (gMapGlobalVars == NULL) { if (gMapGlobalVars == NULL) {
return -1; return -1;
} }
gMapGlobalPointers.resize(count);
} }
gMapGlobalVarsLength = count; gMapGlobalVarsLength = count;
@ -1536,6 +1557,8 @@ static void mapGlobalVariablesFree()
gMapGlobalVars = NULL; gMapGlobalVars = NULL;
gMapGlobalVarsLength = 0; gMapGlobalVarsLength = 0;
} }
gMapGlobalPointers.clear();
} }
// NOTE: Inlined. // NOTE: Inlined.

View File

@ -86,8 +86,8 @@ void isoEnable();
bool isoDisable(); bool isoDisable();
bool isoIsDisabled(); bool isoIsDisabled();
int mapSetElevation(int elevation); int mapSetElevation(int elevation);
int mapSetGlobalVar(int var, int value); int mapSetGlobalVar(int var, ProgramValue& value);
int mapGetGlobalVar(int var); int mapGetGlobalVar(int var, ProgramValue& value);
int mapSetLocalVar(int var, ProgramValue& value); int mapSetLocalVar(int var, ProgramValue& value);
int mapGetLocalVar(int var, ProgramValue& value); int mapGetLocalVar(int var, ProgramValue& value);
int _map_malloc_local_var(int a1); int _map_malloc_local_var(int a1);