mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-09-27 17:38:08 +03:00
Merge pull request #184 from kichikuou/gsave7
Add support for group save format v7
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
struct config {
|
||||
char *game_name;
|
||||
char *ain_filename;
|
||||
char *vm_name;
|
||||
char *game_dir;
|
||||
char *save_dir;
|
||||
char *home_dir;
|
||||
|
||||
+26
-8
@@ -88,10 +88,11 @@ static struct gsave_flat_array *collect_flat_arrays(struct page *page, struct gs
|
||||
fa = collect_flat_arrays(heap_get_page(page->values[i].i), fa, save);
|
||||
return fa;
|
||||
}
|
||||
enum ain_data_type type = variable_type(page, 0, NULL, NULL);
|
||||
fa->nr_values = page->nr_vars;
|
||||
fa->type = type;
|
||||
fa->values = xcalloc(fa->nr_values, sizeof(struct gsave_array_value));
|
||||
for (int i = 0; i < page->nr_vars; i++) {
|
||||
enum ain_data_type type = variable_type(page, i, NULL, NULL);
|
||||
fa->values[i].type = type;
|
||||
fa->values[i].value = add_value_to_gsave(type, page->values[i], save);
|
||||
}
|
||||
@@ -123,6 +124,11 @@ static int32_t add_value_to_gsave(enum ain_data_type type, union vm_value val, s
|
||||
.nr_indices = st->nr_members,
|
||||
.indices = xcalloc(st->nr_members, sizeof(int32_t)),
|
||||
};
|
||||
if (save->version >= 7) {
|
||||
rec.struct_index = gsave_get_struct_def(save, st->name);
|
||||
if (rec.struct_index < 0)
|
||||
rec.struct_index = gsave_add_struct_def(save, st);
|
||||
}
|
||||
for (int i = 0; i < page->nr_vars; i++) {
|
||||
enum ain_data_type type = st->members[i].type.data;
|
||||
int32_t value = add_value_to_gsave(type, page->values[i], save);
|
||||
@@ -166,6 +172,14 @@ static int32_t add_value_to_gsave(enum ain_data_type type, union vm_value val, s
|
||||
}
|
||||
}
|
||||
|
||||
static int get_gsave_version(void)
|
||||
{
|
||||
if (AIN_VERSION_GTE(ain, 6, 0)) {
|
||||
return config.vm_name ? 5 : 7;
|
||||
}
|
||||
return AIN_VERSION_GTE(ain, 5, 0) ? 5 : 4;
|
||||
}
|
||||
|
||||
int save_globals(const char *keyname, const char *filename, const char *group_name, int *n_out)
|
||||
{
|
||||
int group = -1;
|
||||
@@ -184,8 +198,7 @@ int save_globals(const char *keyname, const char *filename, const char *group_na
|
||||
nr_vars = ain->nr_globals;
|
||||
}
|
||||
|
||||
int gsave_version = AIN_VERSION_GTE(ain, 5, 0) ? 5 : 4;
|
||||
struct gsave *save = gsave_create(gsave_version, keyname, ain->nr_globals, group_name);
|
||||
struct gsave *save = gsave_create(get_gsave_version(), keyname, ain->nr_globals, group_name);
|
||||
gsave_add_globals_record(save, nr_vars);
|
||||
|
||||
struct gsave_global *global = save->globals;
|
||||
@@ -450,27 +463,32 @@ static union vm_value gsave_to_vm_value(struct gsave *save, enum ain_data_type t
|
||||
case AIN_STRING:
|
||||
{
|
||||
int slot = heap_alloc_slot(VM_STRING);
|
||||
heap[slot].s = string_ref(save->strings[value]);
|
||||
heap[slot].s = string_ref(value == GSAVE7_EMPTY_STRING ? &EMPTY_STRING : save->strings[value]);
|
||||
return vm_int(slot);
|
||||
}
|
||||
case AIN_STRUCT:
|
||||
{
|
||||
struct gsave_record *rec = &save->records[value];
|
||||
struct ain_struct *st = &ain->structures[struct_type];
|
||||
if (strcmp(rec->struct_name, st->name))
|
||||
struct gsave_struct_def *sd =
|
||||
save->version >= 7 ? &save->struct_defs[rec->struct_index] : NULL;
|
||||
const char *struct_name = sd ? sd->name : rec->struct_name;
|
||||
if (strcmp(struct_name, st->name))
|
||||
VM_ERROR("Bad save file: structure name mismatch");
|
||||
int slot = alloc_struct(struct_type);
|
||||
struct page *page = heap[slot].page;
|
||||
for (int i = 0; i < rec->nr_indices; i++) {
|
||||
struct gsave_keyval *kv = &save->keyvals[rec->indices[i]];
|
||||
int index = struct_member_index(st, kv->name);
|
||||
const char *field_name = sd ? sd->fields[i].name : kv->name;
|
||||
enum ain_data_type field_type = sd ? sd->fields[i].type : kv->type;
|
||||
int index = struct_member_index(st, field_name);
|
||||
if (index < 0) {
|
||||
WARNING("structure %s has no member named %s", display_sjis0(rec->struct_name), display_sjis1(kv->name));
|
||||
WARNING("structure %s has no member named %s", display_sjis0(struct_name), display_sjis1(field_name));
|
||||
continue;
|
||||
}
|
||||
int struct_type, array_rank;
|
||||
enum ain_data_type data_type = variable_type(page, index, &struct_type, &array_rank);
|
||||
if (data_type != kv->type)
|
||||
if (data_type != field_type)
|
||||
VM_ERROR("Bad save file: structure member type mismatch");
|
||||
union vm_value val = gsave_to_vm_value(save, data_type, struct_type, array_rank, kv->value);
|
||||
page->values[index] = val;
|
||||
|
||||
@@ -49,6 +49,7 @@ void apply_game_specific_hacks(struct ain *ain);
|
||||
struct config config = {
|
||||
.game_name = NULL,
|
||||
.ain_filename = NULL,
|
||||
.vm_name = NULL,
|
||||
.game_dir = NULL,
|
||||
.save_dir = NULL,
|
||||
.home_dir = NULL,
|
||||
@@ -133,6 +134,8 @@ static bool read_config(const char *path)
|
||||
config.game_name = strdup(ini_string(&ini[i])->text);
|
||||
} else if (!strcmp(ini[i].name->text, "CodeName")) {
|
||||
config.ain_filename = strdup(ini_string(&ini[i])->text);
|
||||
} else if (!strcmp(ini[i].name->text, "MainVM")) {
|
||||
config.vm_name = strdup(ini_string(&ini[i])->text);
|
||||
} else if (!strcmp(ini[i].name->text, "SaveFolder")) {
|
||||
config.save_dir = strdup(ini_string(&ini[i])->text);
|
||||
} else if (!strcmp(ini[i].name->text, "ViewWidth")) {
|
||||
|
||||
+1
-1
Submodule subprojects/libsys4 updated: 81c1319770...9f5feaa240
Reference in New Issue
Block a user