From adb5d515100fe5dfc905f13922cd4f2bf9829f8a Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Wed, 15 May 2024 22:06:11 -0700 Subject: [PATCH] update save file structs and encode/decode pathways --- src/ItemData.cc | 8 ++++---- src/PlayerInventory.hh | 1 - src/SaveFileFormats.cc | 2 ++ src/SaveFileFormats.hh | 22 +++++++++++----------- 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/ItemData.cc b/src/ItemData.cc index 28ea27a9..bd35b5b8 100644 --- a/src/ItemData.cc +++ b/src/ItemData.cc @@ -431,14 +431,14 @@ void ItemData::decode_for_version(Version from_version) { } void ItemData::encode_for_version(Version to_version, shared_ptr item_parameter_table) { - bool should_encode_v2_data = (is_v1(to_version) || is_v2(to_version)) && (to_version != Version::GC_NTE) && !this->has_encoded_v2_data(); + bool should_encode_v2_data = item_parameter_table && + (is_v1(to_version) || is_v2(to_version)) && + (to_version != Version::GC_NTE) && + !this->has_encoded_v2_data(); switch (this->data1[0]) { case 0x00: if (should_encode_v2_data && (this->data1[1] > 0x26)) { - if (!item_parameter_table) { - throw logic_error("item parameter table is required to encode v2 data"); - } if (this->data1[1] < 0x89) { this->data1[5] = this->data1[1]; this->data1[1] = item_parameter_table->get_weapon_v1_replacement(this->data1[1]); diff --git a/src/PlayerInventory.hh b/src/PlayerInventory.hh index 5fa77cae..7e0339ab 100644 --- a/src/PlayerInventory.hh +++ b/src/PlayerInventory.hh @@ -288,7 +288,6 @@ struct PlayerInventoryT { } operator PlayerInventoryT() const { - PlayerInventoryT ret; ret.num_items = this->num_items; ret.hp_from_materials = this->hp_from_materials; diff --git a/src/SaveFileFormats.cc b/src/SaveFileFormats.cc index 95bd94f5..96370c2f 100644 --- a/src/SaveFileFormats.cc +++ b/src/SaveFileFormats.cc @@ -608,6 +608,8 @@ PSODCV2CharacterFile PSOBBCharacterFile::to_dc_v2() const { PSODCV2CharacterFile ret; ret.inventory = this->inventory; + // We don't need to do the v1-compatible encoding (hence it is OK to pass + // nullptr here) but we do need to encode mag stats in the v2 format ret.inventory.encode_for_client(Version::DC_V2, nullptr); ret.disp = this->disp.to_dcpcv3(language, language); ret.disp.visual.enforce_lobby_join_limits_for_version(Version::DC_V2); diff --git a/src/SaveFileFormats.hh b/src/SaveFileFormats.hh index e4e71890..b591bfd3 100644 --- a/src/SaveFileFormats.hh +++ b/src/SaveFileFormats.hh @@ -494,8 +494,8 @@ struct PSOGCEp3CharacterFile { // This structure is internally split into two by the game. The offsets here // are relative to the start of this structure (first column), and relative // to the start of the second internal structure (second column). - /* 0000:---- */ PlayerInventory inventory; - /* 034C:---- */ PlayerDispDataDCPCV3 disp; + /* 0000:---- */ PlayerInventoryBE inventory; + /* 034C:---- */ PlayerDispDataDCPCV3BE disp; /* 041C:0000 */ be_uint32_t flags = 0; /* 0420:0004 */ be_uint32_t creation_timestamp = 0; /* 0424:0008 */ be_uint32_t signature = 0xA204B064; @@ -540,15 +540,15 @@ struct PSOGCEp3CharacterFile { // by the B7 command sent by the server instead. /* 19420 */ be_uint64_t bgm_test_songs_unlocked = 0; /* 19428 */ be_uint32_t save_count = 1; - // This is an array of 999 bits, represented here as 128 bytes (the last bit - // is never used). Each bit corresponds to a card ID with the bit's index; if - // the bit is set, then during offline play, the card's rank is replaced with - // D2 if its original rank is S, SS, E, or D2, or with D1 if the original rank - // is any other value. Upon receiving a B8 command (server card definitions), - // the game clears this array, and sets all bits whose corresponding cards - // from the server have the D1 or D2 ranks. This could have been used by Sega - // to prevent broken cards from being used offline, but there's no indication - // that they ever used this functionality. + // This is an array of 999 bits, represented here as 128 bytes (the last 25 + // bits are not used). Each bit corresponds to a card ID with the bit's index; + // if the bit is set, then during offline play, the card's rank is replaced + // with D2 if its original rank is S, SS, E, or D2, or with D1 if the original + // rank is any other value. Upon receiving a B8 command (server card + // definitions), the game clears this array, and sets all bits whose + // corresponding cards from the server have the D1 or D2 ranks. This could + // have been used by Sega to prevent broken cards from being used offline, but + // there's no indication that they ever used this functionality. /* 1942C */ parray card_rank_override_flags; /* 194AC */ be_uint32_t round2_seed = 0; /* 194B0 */