Merge pull request #259 from kichikuou/global-dtors

Dungeons & Dolls: Call global variable destructors on exit
This commit is contained in:
Nunuhara Cabbage
2025-07-21 21:39:38 -07:00
committed by GitHub
3 changed files with 24 additions and 0 deletions
+1
View File
@@ -91,5 +91,6 @@ extern bool game_rance02_mg;
extern bool game_rance6_mg;
extern bool game_rance7_mg;
extern bool game_rance8;
extern bool game_dungeons_and_dolls;
#endif /* XSYSTEM4_H */
+3
View File
@@ -37,6 +37,7 @@ bool game_rance02_mg = false;
bool game_rance6_mg = false;
bool game_rance7_mg = false;
bool game_rance8 = false;
bool game_dungeons_and_dolls = false;
static void write_instruction0(struct buffer *out, enum opcode op)
{
@@ -205,6 +206,8 @@ void apply_game_specific_hacks(struct ain *ain)
apply_rance7_hacks(ain);
} else if (!strcmp(game_name, "ランス・クエスト") || !strcmp(game_name, "Rance Quest")) {
game_rance8 = true;
} else if (!strcmp(game_name, "DUNGEONS&DOLLS")) {
game_dungeons_and_dolls = true;
}
free(game_name);
}
+20
View File
@@ -2319,8 +2319,28 @@ static void vm_execute(void)
}
}
static void call_global_destructors(void)
{
if (heap_size <= 0 || heap[0].ref <= 0)
return;
struct page *global_page = heap_get_page(0);
// Call global variable destructors, but do not unref them because the
// destructors may reference other global variables.
for (int i = global_page->nr_vars - 1; i >= 0; i--) {
if (variable_type(global_page, i, NULL, NULL) != AIN_STRUCT)
continue;
int slot = global_page->values[i].i;
delete_struct(heap_get_page(slot)->index, slot);
}
}
static void vm_free(void)
{
if (game_dungeons_and_dolls) {
// Dungeons & Dolls saves the game state in destructors of global variables
call_global_destructors();
}
// call library exit routines
exit_libraries();
// flush call stack