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
|
// 0x58E940
|
||||||
MessageList gMiscMessageList;
|
MessageList gMiscMessageList;
|
||||||
|
|
||||||
|
// CE: Sonora folks like to store objects in global variables.
|
||||||
|
static void** gGameGlobalPointers = nullptr;
|
||||||
|
|
||||||
// 0x442580
|
// 0x442580
|
||||||
int gameInitWithOptions(const char* windowTitle, bool isMapper, int font, int a4, int argc, char** argv)
|
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
|
// 0x443CC8
|
||||||
static int gameLoadGlobalVars()
|
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
|
// 0x443CE8
|
||||||
|
@ -1134,6 +1148,11 @@ static void gameFreeGlobalVars()
|
||||||
internal_free(gGameGlobalVars);
|
internal_free(gGameGlobalVars);
|
||||||
gGameGlobalVars = NULL;
|
gGameGlobalVars = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gGameGlobalPointers != nullptr) {
|
||||||
|
internal_free(gGameGlobalPointers);
|
||||||
|
gGameGlobalPointers = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0x443F74
|
// 0x443F74
|
||||||
|
@ -1492,6 +1511,28 @@ int gameShowDeathDialog(const char* message)
|
||||||
return rc;
|
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;
|
int GameMode::currentGameMode = 0;
|
||||||
|
|
||||||
void GameMode::enterGameMode(int gameMode)
|
void GameMode::enterGameMode(int gameMode)
|
||||||
|
|
|
@ -38,6 +38,8 @@ void gameUpdateState();
|
||||||
int showQuitConfirmationDialog();
|
int showQuitConfirmationDialog();
|
||||||
|
|
||||||
int gameShowDeathDialog(const char* message);
|
int gameShowDeathDialog(const char* message);
|
||||||
|
void* gameGetGlobalPointer(int var);
|
||||||
|
int gameSetGlobalPointer(int var, void* value);
|
||||||
|
|
||||||
class GameMode {
|
class GameMode {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -1207,16 +1207,19 @@ static void opSetMapVar(Program* program)
|
||||||
// 0x455950
|
// 0x455950
|
||||||
static void opGetGlobalVar(Program* program)
|
static void opGetGlobalVar(Program* program)
|
||||||
{
|
{
|
||||||
int data = programStackPopInteger(program);
|
int variable = programStackPopInteger(program);
|
||||||
|
|
||||||
int value = -1;
|
|
||||||
if (gGameGlobalVarsLength != 0) {
|
if (gGameGlobalVarsLength != 0) {
|
||||||
value = gameGetGlobalVar(data);
|
void* ptr = gameGetGlobalPointer(variable);
|
||||||
|
if (ptr != nullptr) {
|
||||||
|
programStackPushPointer(program, ptr);
|
||||||
|
} else {
|
||||||
|
programStackPushInteger(program, gameGetGlobalVar(variable));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
scriptError("\nScript Error: %s: op_global_var: no global vars found!", program->name);
|
scriptError("\nScript Error: %s: op_global_var: no global vars found!", program->name);
|
||||||
|
programStackPushInteger(program, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
programStackPushInteger(program, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set_global_var
|
// set_global_var
|
||||||
|
@ -1224,11 +1227,17 @@ static void opGetGlobalVar(Program* program)
|
||||||
// 0x80C6
|
// 0x80C6
|
||||||
static void opSetGlobalVar(Program* program)
|
static void opSetGlobalVar(Program* program)
|
||||||
{
|
{
|
||||||
int value = programStackPopInteger(program);
|
ProgramValue value = programStackPopValue(program);
|
||||||
int variable = programStackPopInteger(program);
|
int variable = programStackPopInteger(program);
|
||||||
|
|
||||||
if (gGameGlobalVarsLength != 0) {
|
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 {
|
} else {
|
||||||
scriptError("\nScript Error: %s: op_set_global_var: no global vars found!", program->name);
|
scriptError("\nScript Error: %s: op_set_global_var: no global vars found!", program->name);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue