Skip to content

Commit

Permalink
Fix storing pointers in map global variables
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbatalov committed Nov 9, 2022
1 parent 3f25c92 commit 6c03e4e
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 10 deletions.
10 changes: 7 additions & 3 deletions src/interpreter_extra.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1220,16 +1220,20 @@ static void opGetMapVar(Program* 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
// 0x4558C8
static void opSetMapVar(Program* program)
{
int value = programStackPopInteger(program);
ProgramValue value = programStackPopValue(program);
int variable = programStackPopInteger(program);

mapSetGlobalVar(variable, value);
Expand Down
33 changes: 28 additions & 5 deletions src/map.cc
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,11 @@ static char _scratchStr[40];
// 0x631E78
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
// 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
Expand Down Expand Up @@ -390,27 +395,41 @@ int mapSetElevation(int elevation)
}

// 0x482220
int mapSetGlobalVar(int var, int value)
int mapSetGlobalVar(int var, ProgramValue& value)
{
if (var < 0 || var >= gMapGlobalVarsLength) {
debugPrint("ERROR: attempt to reference map var out of range: %d", var);
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;
}

// 0x482250
int mapGetGlobalVar(int var)
int mapGetGlobalVar(int var, ProgramValue& value)
{
if (var < 0 || var >= gMapGlobalVarsLength) {
debugPrint("ERROR: attempt to reference map var out of range: %d", var);
return 0;
return -1;
}

if (gMapGlobalPointers[var] != nullptr) {
value.opcode = VALUE_TYPE_PTR;
value.pointerValue = gMapGlobalPointers[var];
} else {
value.opcode = VALUE_TYPE_INT;
value.integerValue = gMapGlobalVars[var];
}

return gMapGlobalVars[var];
return 0;
}

// 0x482280
Expand Down Expand Up @@ -1521,6 +1540,8 @@ static int mapGlobalVariablesInit(int count)
if (gMapGlobalVars == NULL) {
return -1;
}

gMapGlobalPointers.resize(count);
}

gMapGlobalVarsLength = count;
Expand All @@ -1536,6 +1557,8 @@ static void mapGlobalVariablesFree()
gMapGlobalVars = NULL;
gMapGlobalVarsLength = 0;
}

gMapGlobalPointers.clear();
}

// NOTE: Inlined.
Expand Down
4 changes: 2 additions & 2 deletions src/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ void isoEnable();
bool isoDisable();
bool isoIsDisabled();
int mapSetElevation(int elevation);
int mapSetGlobalVar(int var, int value);
int mapGetGlobalVar(int var);
int mapSetGlobalVar(int var, ProgramValue& value);
int mapGetGlobalVar(int var, ProgramValue& value);
int mapSetLocalVar(int var, ProgramValue& value);
int mapGetLocalVar(int var, ProgramValue& value);
int _map_malloc_local_var(int a1);
Expand Down

0 comments on commit 6c03e4e

Please sign in to comment.