Fix storing pointers in game global variables
This commit is contained in:
parent
c14f671a0d
commit
81210f46af
43
src/game.cc
43
src/game.cc
|
@ -117,6 +117,9 @@ int _game_user_wants_to_quit = 0;
|
|||
// 0x58E940
|
||||
MessageList gMiscMessageList;
|
||||
|
||||
// CE: Sonora folks like to store objects in global variables.
|
||||
static void** gGameGlobalPointers = nullptr;
|
||||
|
||||
// 0x442580
|
||||
int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int a4, int argc, char** argv)
|
||||
{
|
||||
|
@ -993,7 +996,18 @@ int gameSetGlobalVar(int var, int value)
|
|||
// 0x443CC8
|
||||
static int gameLoadGlobalVars()
|
||||
{
|
||||
return globalVarsRead("data\\vault13.gam", "GAME_GLOBAL_VARS:", &gGameGlobalVarsLength, &gGameGlobalVars);
|
||||
if (globalVarsRead("data\\vault13.gam", "GAME_GLOBAL_VARS:", &gGameGlobalVarsLength, &gGameGlobalVars) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
gGameGlobalPointers = reinterpret_cast<void**>(internal_malloc(sizeof(*gGameGlobalPointers) * gGameGlobalVarsLength));
|
||||
if (gGameGlobalPointers == nullptr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(gGameGlobalPointers, 0, sizeof(*gGameGlobalPointers) * gGameGlobalVarsLength);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 0x443CE8
|
||||
|
@ -1134,6 +1148,11 @@ static void gameFreeGlobalVars()
|
|||
internal_free(gGameGlobalVars);
|
||||
gGameGlobalVars = NULL;
|
||||
}
|
||||
|
||||
if (gGameGlobalPointers != nullptr) {
|
||||
internal_free(gGameGlobalPointers);
|
||||
gGameGlobalPointers = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// 0x443F74
|
||||
|
@ -1492,6 +1511,28 @@ int gameShowDeathDialog(const char* message)
|
|||
return rc;
|
||||
}
|
||||
|
||||
void* gameGetGlobalPointer(int var)
|
||||
{
|
||||
if (var < 0 || var >= gGameGlobalVarsLength) {
|
||||
debugPrint("ERROR: attempt to reference global pointer out of range: %d", var);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return gGameGlobalPointers[var];
|
||||
}
|
||||
|
||||
int gameSetGlobalPointer(int var, void* value)
|
||||
{
|
||||
if (var < 0 || var >= gGameGlobalVarsLength) {
|
||||
debugPrint("ERROR: attempt to reference global var out of range: %d", var);
|
||||
return -1;
|
||||
}
|
||||
|
||||
gGameGlobalPointers[var] = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GameMode::currentGameMode = 0;
|
||||
|
||||
void GameMode::enterGameMode(int gameMode)
|
||||
|
|
|
@ -38,6 +38,8 @@ void gameUpdateState();
|
|||
int showQuitConfirmationDialog();
|
||||
|
||||
int gameShowDeathDialog(const char* message);
|
||||
void* gameGetGlobalPointer(int var);
|
||||
int gameSetGlobalPointer(int var, void* value);
|
||||
|
||||
class GameMode {
|
||||
public:
|
||||
|
|
|
@ -1207,16 +1207,19 @@ static void opSetMapVar(Program* program)
|
|||
// 0x455950
|
||||
static void opGetGlobalVar(Program* program)
|
||||
{
|
||||
int data = programStackPopInteger(program);
|
||||
int variable = programStackPopInteger(program);
|
||||
|
||||
int value = -1;
|
||||
if (gGameGlobalVarsLength != 0) {
|
||||
value = gameGetGlobalVar(data);
|
||||
void* ptr = gameGetGlobalPointer(variable);
|
||||
if (ptr != nullptr) {
|
||||
programStackPushPointer(program, ptr);
|
||||
} else {
|
||||
programStackPushInteger(program, gameGetGlobalVar(variable));
|
||||
}
|
||||
} else {
|
||||
scriptError("\nScript Error: %s: op_global_var: no global vars found!", program->name);
|
||||
programStackPushInteger(program, -1);
|
||||
}
|
||||
|
||||
programStackPushInteger(program, value);
|
||||
}
|
||||
|
||||
// set_global_var
|
||||
|
@ -1224,11 +1227,17 @@ static void opGetGlobalVar(Program* program)
|
|||
// 0x80C6
|
||||
static void opSetGlobalVar(Program* program)
|
||||
{
|
||||
int value = programStackPopInteger(program);
|
||||
ProgramValue value = programStackPopValue(program);
|
||||
int variable = programStackPopInteger(program);
|
||||
|
||||
if (gGameGlobalVarsLength != 0) {
|
||||
gameSetGlobalVar(variable, value);
|
||||
if (value.opcode == VALUE_TYPE_PTR) {
|
||||
gameSetGlobalPointer(variable, value.pointerValue);
|
||||
gameSetGlobalVar(variable, 0);
|
||||
} else {
|
||||
gameSetGlobalPointer(variable, nullptr);
|
||||
gameSetGlobalVar(variable, value.integerValue);
|
||||
}
|
||||
} else {
|
||||
scriptError("\nScript Error: %s: op_set_global_var: no global vars found!", program->name);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue