From c59d9702a6c053727328e0f95f4e10dccf994de9 Mon Sep 17 00:00:00 2001 From: lzwdgc Date: Tue, 19 Mar 2019 22:18:46 +0300 Subject: [PATCH] Split save implementation. Improve save loader. --- src/common/types.cpp | 22 +- src/model/model.cpp | 8 +- src/save_loader/save.cpp | 644 +++++++++++++++++++++++++++++++ src/save_loader/save.h | 655 +++++++------------------------- src/save_loader/save_loader.cpp | 2 + 5 files changed, 810 insertions(+), 521 deletions(-) create mode 100644 src/save_loader/save.cpp diff --git a/src/common/types.cpp b/src/common/types.cpp index c41ee61..d1b142c 100644 --- a/src/common/types.cpp +++ b/src/common/types.cpp @@ -26,7 +26,16 @@ void weather::load(const buffer &b) READ(b, smoke_1); READ(b, smoke_3); READ(b, smokeType); - READ(b, unk2); + switch (smokeType) + { + case SmokeType::biexp: + READ(b, unk2); + b.skip(4); + break; + default: + READ(b, unk2); + break; + } READ_STRING(b, cloud_layer1); READ_STRING(b, cloud_layer2); READ(b, cloud_layer1_speed); @@ -47,7 +56,16 @@ void weather::load(const buffer &b) READ(b, smoke_4); READ(b, slider_3); READ(b, slider_1); - READ(b, unk8); + switch (smokeType) + { + case SmokeType::biexp: + READ(b, unk8); + b.skip(-4); + break; + default: + READ(b, unk8); + break; + } } void weather_group::load(const buffer &b) diff --git a/src/model/model.cpp b/src/model/model.cpp index a05c621..aab00de 100644 --- a/src/model/model.cpp +++ b/src/model/model.cpp @@ -122,10 +122,10 @@ static void load_translated(aim_vector3 &v, const buffer &b) /* Our coord system: - ^ z - | - ---> y - / + ^ z + | + ---> y + / v x AIM Coordinates: diff --git a/src/save_loader/save.cpp b/src/save_loader/save.cpp new file mode 100644 index 0000000..38d2342 --- /dev/null +++ b/src/save_loader/save.cpp @@ -0,0 +1,644 @@ +/* + * AIM save_loader + * Copyright (C) 2016 lzwdgc + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "save.h" + +#include + +changes save_changes; + +void changes::rewrite_mech_org(const buffer &b, std::string &org) +{ + if (mech_org.empty()) + return; + + // setpos + out.seek(b.index()); + out.skip(-0x20); + out.write(mech_org); + + org = mech_org; +} + +void changes::rewrite_money(const buffer &b) +{ + if (money == 0) + return; + out.seek(b.index()); + out.skip(-4); + out.write(money); +} + +void changes::rewrite_upgrade_equ_for_player(const buffer &b, uint32_t value) +{ + if (!upgrade_equ_for_player) + return; + out.seek(b.index()); + out.skip(-4); + out.write(value); +} + +void int_variable::load(const buffer &b) +{ + READ_STRING(b, name); + READ(b, value); +} + +void single_string::load(const buffer &b) +{ + READ_STRING(b, name); +} + +void string_variable::load(const buffer &b) +{ + READ_STRING(b, name); + READ_STRING(b, value); +} + +void header_segment::load(const buffer &b) +{ + READ(b, unk1); + READ_STRING_N(b, save_name, 0x60); + READ(b, position); + READ_STRING_N(b, mmp_file, 0x110); + READ_STRING(b, location_name); + READ(b, camera); + READ(b, unk2); +} + +void string_segment::load(const buffer &b) +{ + READ_PASCAL_STRING(b, s); +} + +void screen_segment::load(const buffer &b) +{ + b._read((uint8_t *)screenshot.getData().data(), screenshot.getBytesLength()); + // rows should be swapped now: bottom is the first row etc. +} + +void scripts_segment::script_entry::load(const buffer &b) +{ + READ_STRING(b, name); + READ_STRING_N(b, path, 0x80); +} + +void scripts_segment::script_entry_ext::load(const buffer &b) +{ + READ_STRING(b, name); + READ(b, unk0); + READ_STRING_N(b, path, 0x80); +} + +void scripts_segment::load(const buffer &b) +{ + b.read_vector(bases); + b.read_vector(events); + b.read_vector(unk0); + b.read_vector(int_variables); + b.read_vector(str_variables); +} + +void radar_segment::radar::load(const buffer &b) +{ + READ(b, unk0); +} + +void radar_segment::mechanoid5::load(const buffer &b) +{ + READ_STRING(b, name); + READ(b, unk0); +} + +void radar_segment::load(const buffer &b) +{ + b.read_vector(radars); + READ(b, unk0); + b.read_vector(mechanoid5s); + b.read_vector(orgs); +} + +void gamedata_segment::load(const buffer &b) +{ + READ(b, unk00); + READ_N_OBJECTS_WITH_LOAD(b, locs); + READ_N_OBJECTS_WITH_LOAD(b, orgs); + READ(b, unk0); + READ_N_OBJECTS_WITH_LOAD(b, unk1); + READ_STRING(b, base_name); + READ(b, unk2); + READ_PASCAL_STRING(b, user_name); + READ_N_OBJECTS_WITH_LOAD(b, unk3); + READ_STRING(b, icon); + READ(b, unk4); +} + +void questlog_segment::record::load(const buffer &b) +{ + READ_STRING(b, name); + READ_STRING(b, name_journal); + READ(b, unk0); + READ_STRING(b, endtime); +} + +void questlog_segment::load(const buffer &b) +{ + READ(b, unk0); + b.read_vector(int_variables); + b.read_vector(events); + b.read_vector(story_quests); +} + +void trade_segment::Price::load(const buffer &b) +{ + READ_STRING(b, tov_name); + READ(b, unk0); + READ(b, mass); + READ(b, price); + READ(b, notrade); + READ(b, type); + READ(b, unk1); +} + +void trade_segment::BuildingPrice::load(const buffer &b) +{ + READ_STRING(b, name); + b.read_vector(prices); + READ(b, unk0); +} + +void trade_segment::load(const buffer &b) +{ + READ(b, unk0); + b.read_vector(buildingPrices); +} + +void env_segment::load(const buffer &b) +{ + READ(b, unk0); + w.load(b); +} + +void orgrel_segment::org_rep::load(const buffer &b) +{ + READ(b, unk0); + READ(b, unk1); +} + +void orgrel_segment::load(const buffer &b) +{ + b.read_vector(org_reps); + uint32_t unk0[2]; + READ(b, unk0); +} + +void others_segment::load(const buffer &b) +{ + READ(b, unk0); + READ(b, unk1); +} + +void mech_segment::equipment::load(const buffer &b) +{ + READ(b, id); + READ_STRING(b, name); + READ(b, unk0); + READ(b, unk1); +} + +void mech_segment::moddable_equipment::load(const buffer &b) +{ + READ_STRING(b, name); + READ(b, mask); +} + +void mech_segment::moddable_equipment2::load(const buffer &b) +{ + READ(b, id); + READ_STRING(b, name); + READ(b, unk0); + READ(b, mask); +} + +void mech_segment::hold_item::load(const buffer &b) +{ + READ(b, type); + READ_STRING(b, name); + READ(b, count); + READ(b, unk0); + READ(b, unk1); +} + +void mech_segment::ammo::load(const buffer &b) +{ + READ_STRING(b, name); +} + +void mech_segment::ammo_count::load(const buffer &b) +{ + READ_STRING(b, name); + READ(b, count); +} + +void mech_segment::mech::load(const buffer &b) +{ + READ(b, id); + READ_STRING(b, name); + READ_STRING(b, name2); + READ_STRING(b, org); + save_changes.rewrite_mech_org(b, org); + READ_STRING(b, building); + + READ(b, flags); + READ(b, unk11); + READ(b, unk12); + READ(b, unk13); + READ(b, unk14); + + auto f = (uint32_t)flags; + if (!(f == 0x01000101 || f == 0x00000001 || f == 0x00000101 || f == 0x01000001)) + { + READ(b, unk16); + return; + } + + READ(b, unk15); + + if (unk14 == 0) + return; + + READ(b, unk15_1); // size? + + b.read_vector(equipments); + + READ(b, unk40); + READ(b, unk4); + + // + glider.load(b); + if (isPlayer()) + save_changes.rewrite_upgrade_equ_for_player(b, 0x1666); + weapon1.load(b); + if (isPlayer()) + save_changes.rewrite_upgrade_equ_for_player(b, 0x2666); + weapon2.load(b); + if (isPlayer()) + save_changes.rewrite_upgrade_equ_for_player(b, 0x2666); + reactor1.load(b); + reactor2.load(b); + engine1.load(b); + engine2.load(b); + energy_shield.load(b); + armor.load(b); + + // ? + READ(b, g_unk0); + if (g_unk0 == 0) + READ(b, g_unk1); + READ(b, g_unk2); + + if (g_unk0 == 0) + b.read_vector(ammos, g_unk1); + + b.read_vector(ammos1, g_unk0); + + if (g_unk0 != 0 || g_unk1 != 0) + { + READ(b, g_unk3); + if (g_unk0 > 0) + { + uint32_t n; + b.skip(-8); + READ(b, n); + b.skip(4); + b.read_vector(ammos2, n); + std::vector> v; + b.read_vector(v, n); + } + if (g_unk1 > 0) + { + g_unk1--; + while (g_unk1--) + READ(b, g_unk3); + } + } + + ureactor1.load(b); + if (isPlayer()) + save_changes.rewrite_upgrade_equ_for_player(b, 0x3666); + ureactor2.load(b); + if (isPlayer()) + save_changes.rewrite_upgrade_equ_for_player(b, 0x3666); + uengine1.load(b); + if (isPlayer()) + save_changes.rewrite_upgrade_equ_for_player(b, 0x4666); + uengine2.load(b); + if (isPlayer()) + save_changes.rewrite_upgrade_equ_for_player(b, 0x4666); + uenergy_shield.load(b); + if (isPlayer()) + save_changes.rewrite_upgrade_equ_for_player(b, 0x5666); + uarmor.load(b); + + g_unk4.load(b); + + READ(b, glider_mask); + if (isPlayer()) + save_changes.rewrite_upgrade_equ_for_player(b, 0x1666); + + b.read_vector(ammos3); + + READ(b, money); + if (name == "PLAYER") + save_changes.rewrite_money(b); + + b.read_vector(items); + + READ(b, g_unk6); + + // TODO + + // if (g_unk0 == 1) + // if ((uint32_t)g_unk2 == 15) + // if ((uint32_t)g_unk3 == 0) + // if (unk13[0] == 5) + if (g_unk6[26][0] != 0 && strcmp((const char *)b.getPtr(), "GROUPS") != 0) + { + + READ(b, g_unk7); + /*if (g_unk7 != 0) + { + b.skip(-4); + return; + }*/ + READ(b, g_unk8); + READ(b, g_unk9); + READ(b, g_unk10); + } +} + +bool mech_segment::mech::isPlayer() const +{ + return name == "PLAYER"; +} + +void mech_segment::load(const buffer &b) +{ + b.read_vector(mechs); +} + +void groups_segment::mech::load(const buffer &b) +{ + READ_STRING(b, name); + READ(b, unk0); + READ(b, unk1); + READ(b, unk2); + READ(b, unk3); +} + +void groups_segment::group::load(const buffer &b) +{ + READ(b, pos); + READ_STRING(b, org); + READ_STRING(b, base); + uint32_t unk0; + uint16_t unk1; + float unk2[3]; + READ(b, unk0); + READ(b, unk1); + READ(b, unk2); + b.read_vector(mechs); +} + +void groups_segment::load(const buffer &b) +{ + b.read_vector(groups); +} + +void orgdata_segment::org_config::load(const buffer &b) +{ + b.read_vector(names); +} + +void orgdata_segment::orgdata::load(const buffer &b) +{ + READ(b, unk0); + READ_STRING(b, org); + READ(b, unk1); + READ(b, unk2); + READ(b, rep); + b.read_vector(configs, 3); +} + +void orgdata_segment::load(const buffer &b) +{ + b.read_vector(orgdatas); +} + +void builds_segment::build::load(const buffer &b) +{ + READ_STRING(b, bld); + READ_STRING(b, org); + READ(b, unk1); +} + +void builds_segment::load(const buffer &b) +{ + b.read_vector(builds); +} + +void orgs_segment::org::load(const buffer &b) +{ + struct base + { + struct mech + { + std::string name; + + void load(const buffer &b) + { + READ_STRING(b, name); + } + }; + + std::string name; + float unk2; + bool unk3; + uint32_t unk4[2]; + std::vector mechs; + std::string mname; // mech + + void load(const buffer &b) + { + READ_STRING(b, name); + READ(b, unk2); + READ(b, unk3); + READ(b, unk4); + b.read_vector(mechs); + } + }; + + uint32_t unk0[8]; + std::vector bases; + std::string unk1; + + READ(b, unk0); + b.read_vector(bases); + READ_STRING(b, unk1); +} + +void orgs_segment::load(const buffer &b) +{ + b.read_vector(orgs); +} + +void tradeeqp_segment::Good::load(const buffer &b) +{ + READ_STRING(b, tov_name); + READ(b, unk0); + READ(b, mask); + READ(b, price); + READ(b, count); + READ(b, probability); +} + +void tradeeqp_segment::bld::load(const buffer &b) +{ + READ_STRING(b, name); + b.read_vector(prices); +} + +void tradeeqp_segment::load(const buffer &b) +{ + READ(b, unk0); + b.read_vector(prices); + b.read_vector(blds); +} + +void objects_segment::base::load(const buffer &b) +{ + READ_STRING(b, name); + READ(b, unk0); + READ(b, unk1); +} + +void objects_segment::load(const buffer &b) +{ + b.read_vector(bases); +} + +void mms_state_segment::load(const buffer &b) +{ + READ_STRING(b, name); +} + +void mms_c_config_segment::load(const buffer &b) +{ + // todo: insert config read from mech + b.read_vector(objects); +} + +void mms_world_data_segment::load(const buffer &b) +{ + READ(b, unk0); +} + +void mainmech_segment::load(const buffer &b) +{ + READ(b, unk0); +} + +void segment_desc::load(const buffer &b) +{ + READ_STRING(b, name); + uint32_t magic; + READ(b, magic); + if (magic != (uint32_t)-2) + throw SW_RUNTIME_ERROR("bad magic for segment: " + name); + uint32_t len; + READ(b, len); // length of segment + 4 (sizeof(int) - internal segment length) + uint32_t offset; + READ(b, offset); + uint32_t unk1; + READ(b, unk1); + uint32_t len2; + READ(b, len2); + if (len != len2 + sizeof(len2)) + throw SW_RUNTIME_ERROR("bad length for segment: " + name); + + uint32_t start = b.index(); + uint32_t end = start + len2; + +#define SWITCH(s, t) \ + if (name == s) \ + seg = new t +#define CASE(s, t) else SWITCH(s, t) +#define DEFAULT else + + SWITCH("HEADER", header_segment); + CASE("CAPTION", string_segment); + CASE("PLAYER", string_segment); + CASE("SCREEN", screen_segment); + CASE("SCRIPTS", scripts_segment); + // CASE("RADAR", radar_segment); + CASE("GAMEDATA", gamedata_segment); + CASE("QUESTLOG", questlog_segment); + CASE("TRADE", trade_segment); + CASE("ENV", env_segment); + CASE("ORGREL", orgrel_segment); + CASE("OTHERS", others_segment); + CASE("MECH", mech_segment); + // CASE("GROUPS", groups_segment); + CASE("ORGDATA", orgdata_segment); + CASE("BUILDS", builds_segment); + //CASE("ORGS", orgs_segment); + CASE("TRADEEQP", tradeeqp_segment); + // CASE("OBJECTS", objects_segment); + CASE("MMS_STATE", mms_state_segment); + // CASE("MMS_C_CONFIG", mms_c_config_segment); // (my) clan config + CASE("MMS_WORLD_DATA", mms_world_data_segment); + CASE("MAINMECH", mainmech_segment); + DEFAULT + { + std::cout << "skipped " << name << " size = " << len2 << "\n"; + b.skip(len2); + return; + } + + seg->load(b); + if (b.index() != end) + throw SW_RUNTIME_ERROR("bad segment read: " + name); + +#undef SWITCH +#undef CASE +#undef DEFAULT +} + +void save::load(const buffer &b) +{ + READ(b, magic); + READ(b, version); + + while (!b.eof()) + { + segment_desc sd; + sd.load(b); + if (sd.seg) + segments.push_back(sd); + } +} diff --git a/src/save_loader/save.h b/src/save_loader/save.h index 0d108a8..23e50ff 100644 --- a/src/save_loader/save.h +++ b/src/save_loader/save.h @@ -35,38 +35,13 @@ struct changes float money = 0; bool upgrade_equ_for_player = false; - void rewrite_mech_org(const buffer &b, std::string &org) - { - if (mech_org.empty()) - return; + void rewrite_mech_org(const buffer &b, std::string &org); + void rewrite_money(const buffer &b); + void rewrite_upgrade_equ_for_player(const buffer &b, uint32_t value); - // setpos - out.seek(b.index()); - out.skip(-0x20); - out.write(mech_org); +}; - org = mech_org; - } - - void rewrite_money(const buffer &b) - { - if (money == 0) - return; - out.seek(b.index()); - out.skip(-4); - out.write(money); - } - - void rewrite_upgrade_equ_for_player(const buffer &b, uint32_t value) - { - if (!upgrade_equ_for_player) - return; - out.seek(b.index()); - out.skip(-4); - out.write(value); - } - -} save_changes; +extern changes save_changes; // common structs @@ -75,11 +50,7 @@ struct int_variable std::string name; uint32_t value; - void load(const buffer &b) - { - READ_STRING(b, name); - READ(b, value); - } + void load(const buffer &b); }; template @@ -97,10 +68,7 @@ struct single_string { std::string name; - void load(const buffer &b) - { - READ_STRING(b, name); - } + void load(const buffer &b); }; struct string_variable @@ -108,11 +76,7 @@ struct string_variable std::string name; std::string value; - void load(const buffer &b) - { - READ_STRING(b, name); - READ_STRING(b, value); - } + void load(const buffer &b); }; // segments @@ -132,37 +96,21 @@ struct header_segment : public segment Common camera; uint32_t unk2[7]; - void load(const buffer &b) - { - READ(b, unk1); - READ_STRING_N(b, save_name, 0x60); - READ(b, position); - READ_STRING_N(b, mmp_file, 0x110); - READ_STRING(b, location_name); - READ(b, camera); - READ(b, unk2); - } + void load(const buffer &b); }; struct string_segment : public segment { std::string s; - void load(const buffer &b) - { - READ_PASCAL_STRING(b, s); - } + void load(const buffer &b); }; struct screen_segment : public segment { mat screenshot{ 128, 128 }; - void load(const buffer &b) - { - b._read((uint8_t*)screenshot.getData().data(), screenshot.getBytesLength()); - // rows should be swapped now: bottom is the first row etc. - } + void load(const buffer &b); }; struct scripts_segment : public segment @@ -172,23 +120,14 @@ struct scripts_segment : public segment std::string name; std::string path; - void load(const buffer &b) - { - READ_STRING(b, name); - READ_STRING_N(b, path, 0x80); - } + void load(const buffer &b); }; struct script_entry_ext : public script_entry { uint32_t unk0[10]; - void load(const buffer &b) - { - READ_STRING(b, name); - READ(b, unk0); - READ_STRING_N(b, path, 0x80); - } + void load(const buffer &b); }; std::vector bases; @@ -197,14 +136,7 @@ struct scripts_segment : public segment std::vector int_variables; std::vector str_variables; - void load(const buffer &b) - { - b.read_vector(bases); - b.read_vector(events); - b.read_vector(unk0); - b.read_vector(int_variables); - b.read_vector(str_variables); - } + void load(const buffer &b); }; // todo @@ -214,10 +146,7 @@ struct radar_segment : public segment { char unk0[0x1C4]; - void load(const buffer &b) - { - READ(b, unk0); - } + void load(const buffer &b); }; struct mechanoid5 @@ -225,6 +154,38 @@ struct radar_segment : public segment std::string name; float unk0[6]; + void load(const buffer &b); + }; + + std::vector radars; + uint16_t unk0; + std::vector mechanoid5s; + std::vector orgs; + + void load(const buffer &b); +}; + +struct gamedata_segment : public segment +{ + struct loc + { + float unk0; + uint32_t unk1[2]; + std::string name; + + void load(const buffer &b) + { + READ(b, unk0); + READ(b, unk1); + READ_STRING(b, name); + } + }; + + struct org + { + std::string name; + uint32_t unk0; // flags? + void load(const buffer &b) { READ_STRING(b, name); @@ -232,26 +193,49 @@ struct radar_segment : public segment } }; - std::vector radars; - uint16_t unk0; - std::vector mechanoid5s; - std::vector orgs; - - void load(const buffer &b) + struct unk0s { - b.read_vector(radars); - READ(b, unk0); - b.read_vector(mechanoid5s); - b.read_vector(orgs); - } -}; + float unk0[2]; + uint32_t unk1; -// todo -struct gamedata_segment : public segment -{ - void load(const buffer &b) + void load(const buffer &b) + { + READ(b, unk0); + READ(b, unk1); + } + }; + + struct unk1s { - } + std::string name; // loc part? + char unk0[0xE0]; + uint32_t unk1; + uint32_t unk2; + std::string location; // loc + + void load(const buffer &b) + { + READ_STRING(b, name); + READ(b, unk0); + READ(b, unk1); + READ(b, unk2); + READ_STRING(b, location); + } + }; + + char unk00[0x5C]; + std::vector locs; + std::vector orgs; + uint32_t unk0; + std::vector unk1; + std::string base_name; + uint32_t unk2; + std::string user_name; // mech name? + std::vector unk3; + std::string icon; // clan icon? + uint32_t unk4; + + void load(const buffer &b); }; struct questlog_segment : public segment @@ -263,13 +247,7 @@ struct questlog_segment : public segment uint32_t unk0[2]; std::string endtime; - void load(const buffer &b) - { - READ_STRING(b, name); - READ_STRING(b, name_journal); - READ(b, unk0); - READ_STRING(b, endtime); - } + void load(const buffer &b); }; uint32_t unk0; @@ -278,13 +256,7 @@ struct questlog_segment : public segment std::vector events; std::vector story_quests; - void load(const buffer &b) - { - READ(b, unk0); - b.read_vector(int_variables); - b.read_vector(events); - b.read_vector(story_quests); - } + void load(const buffer &b); }; struct trade_segment : public segment @@ -292,13 +264,14 @@ struct trade_segment : public segment struct Price { std::string tov_name; - float unk2[6]; + uint32_t unk0; + float mass; + float price; + uint32_t notrade; + uint32_t type; + float unk1; - void load(const buffer &b) - { - READ_STRING(b, tov_name); - READ(b, unk2); - } + void load(const buffer &b); }; struct BuildingPrice @@ -307,51 +280,36 @@ struct trade_segment : public segment std::vector prices; uint32_t unk0; - void load(const buffer &b) - { - READ_STRING(b, name); - b.read_vector(prices); - READ(b, unk0); - } + void load(const buffer &b); }; uint32_t unk0 = 0; std::vector buildingPrices; - void load(const buffer &b) - { - READ(b, unk0); - b.read_vector(buildingPrices); - } + void load(const buffer &b); }; -// todo struct env_segment : public segment { - void load(const buffer &b) - { - } + char unk0[0x151]; + weather w; + + void load(const buffer &b); }; -// todo struct orgrel_segment : public segment { struct org_rep { - char unk1[0xE0]; + char unk0[0x8]; + bool unk1; - void load(const buffer &b) - { - READ(b, unk1); - } + void load(const buffer &b); }; std::vector org_reps; - void load(const buffer &b) - { - b.read_vector(org_reps); - } + void load(const buffer &b); }; struct others_segment : public segment @@ -359,11 +317,7 @@ struct others_segment : public segment uint32_t unk0; uint32_t unk1; - void load(const buffer &b) - { - READ(b, unk0); - READ(b, unk1); - } + void load(const buffer &b); }; struct mech_segment : public segment @@ -375,13 +329,7 @@ struct mech_segment : public segment uint32_t unk0; uint32_t unk1; - void load(const buffer &b) - { - READ(b, id); - READ_STRING(b, name); - READ(b, unk0); - READ(b, unk1); - } + void load(const buffer &b); }; struct moddable_equipment @@ -389,11 +337,7 @@ struct mech_segment : public segment std::string name; ModificatorMask mask; - void load(const buffer &b) - { - READ_STRING(b, name); - READ(b, mask); - } + void load(const buffer &b); }; struct moddable_equipment2 @@ -403,13 +347,7 @@ struct mech_segment : public segment uint32_t unk0; // health? ModificatorMask mask; - void load(const buffer &b) - { - READ(b, id); - READ_STRING(b, name); - READ(b, unk0); - READ(b, mask); - } + void load(const buffer &b); }; struct hold_item @@ -426,24 +364,14 @@ struct mech_segment : public segment uint32_t unk0; uint32_t unk1; - void load(const buffer &b) - { - READ(b, type); - READ_STRING(b, name); - READ(b, count); - READ(b, unk0); - READ(b, unk1); - } + void load(const buffer &b); }; struct ammo { std::string name; - void load(const buffer &b) - { - READ_STRING(b, name); - } + void load(const buffer &b); }; struct ammo_count @@ -451,11 +379,7 @@ struct mech_segment : public segment std::string name; uint32_t count; - void load(const buffer &b) - { - READ_STRING(b, name); - READ(b, count); - } + void load(const buffer &b); }; enum class MechFlags : uint32_t @@ -534,159 +458,14 @@ struct mech_segment : public segment uint32_t g_unk9 = 0; uint8_t g_unk10 = 0; - void load(const buffer &b) - { - READ(b, id); - READ_STRING(b, name); - READ_STRING(b, name2); - READ_STRING(b, org); - save_changes.rewrite_mech_org(b, org); - READ_STRING(b, building); + void load(const buffer &b); - READ(b, flags); - READ(b, unk11); - READ(b, unk12); - READ(b, unk13); - READ(b, unk14); - - auto f = (uint32_t)flags; - if (!(f == 0x01000101 || - f == 0x00000001 || - f == 0x00000101 || - f == 0x01000001)) - { - READ(b, unk16); - return; - } - - READ(b, unk15); - - if (unk14 == 0) - return; - - READ(b, unk15_1); // size? - - b.read_vector(equipments); - - READ(b, unk40); - READ(b, unk4); - - // - glider.load(b); - if (isPlayer()) - save_changes.rewrite_upgrade_equ_for_player(b, 0x1666); - weapon1.load(b); - if (isPlayer()) - save_changes.rewrite_upgrade_equ_for_player(b, 0x2666); - weapon2.load(b); - if (isPlayer()) - save_changes.rewrite_upgrade_equ_for_player(b, 0x2666); - reactor1.load(b); - reactor2.load(b); - engine1.load(b); - engine2.load(b); - energy_shield.load(b); - armor.load(b); - - // ? - READ(b, g_unk0); - if (g_unk0 == 0) - READ(b, g_unk1); - READ(b, g_unk2); - - if (g_unk0 == 0) - b.read_vector(ammos, g_unk1); - - b.read_vector(ammos1, g_unk0); - - if (g_unk0 != 0 || g_unk1 != 0) - { - READ(b, g_unk3); - if (g_unk0 > 0) - { - uint32_t n; - b.skip(-8); - READ(b, n); - b.skip(4); - b.read_vector(ammos2, n); - std::vector> v; - b.read_vector(v, n); - } - if (g_unk1 > 0) - { - g_unk1--; - while (g_unk1--) - READ(b, g_unk3); - } - } - - ureactor1.load(b); - if (isPlayer()) - save_changes.rewrite_upgrade_equ_for_player(b, 0x3666); - ureactor2.load(b); - if (isPlayer()) - save_changes.rewrite_upgrade_equ_for_player(b, 0x3666); - uengine1.load(b); - if (isPlayer()) - save_changes.rewrite_upgrade_equ_for_player(b, 0x4666); - uengine2.load(b); - if (isPlayer()) - save_changes.rewrite_upgrade_equ_for_player(b, 0x4666); - uenergy_shield.load(b); - if (isPlayer()) - save_changes.rewrite_upgrade_equ_for_player(b, 0x5666); - uarmor.load(b); - - g_unk4.load(b); - - READ(b, glider_mask); - if (isPlayer()) - save_changes.rewrite_upgrade_equ_for_player(b, 0x1666); - - b.read_vector(ammos3); - - READ(b, money); - if (name == "PLAYER") - save_changes.rewrite_money(b); - - b.read_vector(items); - - READ(b, g_unk6); - - // TODO - - //if (g_unk0 == 1) - //if ((uint32_t)g_unk2 == 15) - //if ((uint32_t)g_unk3 == 0) - //if (unk13[0] == 5) - if (g_unk6[26][0] != 0 && - strcmp((const char *)b.getPtr(), "GROUPS") != 0) - { - - READ(b, g_unk7); - /*if (g_unk7 != 0) - { - b.skip(-4); - return; - }*/ - READ(b, g_unk8); - READ(b, g_unk9); - READ(b, g_unk10); - } - } - - bool isPlayer() const - { - return name == "PLAYER"; - } + bool isPlayer() const; }; std::vector mechs; - void load(const buffer &b) - { - b.read_vector(mechs); - } + void load(const buffer &b); }; // todo @@ -700,14 +479,7 @@ struct groups_segment : public segment uint32_t unk2[2]; float unk3; - void load(const buffer &b) - { - READ_STRING(b, name); - READ(b, unk0); - READ(b, unk1); - READ(b, unk2); - READ(b, unk3); - } + void load(const buffer &b); }; struct group @@ -715,28 +487,15 @@ struct groups_segment : public segment vector3f pos; std::string org; std::string base; - float unk0[4]; - uint16_t unk1; std::vector mechs; - void load(const buffer &b) - { - READ(b, pos); - READ_STRING(b, org); - READ_STRING(b, base); - READ(b, unk0); - READ(b, unk1); - b.read_vector(mechs); - } + void load(const buffer &b); }; std::vector groups; - void load(const buffer &b) - { - b.read_vector(groups); - } + void load(const buffer &b); }; struct orgdata_segment : public segment @@ -745,10 +504,7 @@ struct orgdata_segment : public segment { std::vector names; - void load(const buffer &b) - { - b.read_vector(names); - } + void load(const buffer &b); }; struct orgdata @@ -760,23 +516,12 @@ struct orgdata_segment : public segment float rep[50]; std::vector configs; - void load(const buffer &b) - { - READ(b, unk0); - READ_STRING(b, org); - READ(b, unk1); - READ(b, unk2); - READ(b, rep); - b.read_vector(configs, 3); - } + void load(const buffer &b); }; std::vector orgdatas; - void load(const buffer &b) - { - b.read_vector(orgdatas); - } + void load(const buffer &b); }; struct builds_segment : public segment @@ -787,20 +532,12 @@ struct builds_segment : public segment std::string org; float unk1; - void load(const buffer &b) - { - READ_STRING(b, bld); - READ_STRING(b, org); - READ(b, unk1); - } + void load(const buffer &b); }; std::vector builds; - void load(const buffer &b) - { - b.read_vector(builds); - } + void load(const buffer &b); }; // todo @@ -808,17 +545,12 @@ struct orgs_segment : public segment { struct org { - void load(const buffer &b) - { - } + void load(const buffer &b); }; std::vector orgs; - void load(const buffer &b) - { - b.read_vector(orgs); - } + void load(const buffer &b); }; struct tradeeqp_segment : public segment @@ -832,15 +564,7 @@ struct tradeeqp_segment : public segment int32_t count; float probability; - void load(const buffer &b) - { - READ_STRING(b, tov_name); - READ(b, unk0); - READ(b, mask); - READ(b, price); - READ(b, count); - READ(b, probability); - } + void load(const buffer &b); }; struct bld @@ -848,23 +572,14 @@ struct tradeeqp_segment : public segment std::string name; std::vector prices; - void load(const buffer &b) - { - READ_STRING(b, name); - b.read_vector(prices); - } + void load(const buffer &b); }; uint32_t unk0 = 0; std::vector prices; std::vector blds; - void load(const buffer &b) - { - READ(b, unk0); - b.read_vector(prices); - b.read_vector(blds); - } + void load(const buffer &b); }; // todo @@ -876,30 +591,20 @@ struct objects_segment : public segment uint32_t unk0[26]; uint16_t unk1; - void load(const buffer &b) - { - READ_STRING(b, name); - READ(b, unk0); - READ(b, unk1); - } + void load(const buffer &b); }; std::vector bases; - void load(const buffer &b) - { - b.read_vector(bases); - } + void load(const buffer &b); }; +// what is mms? struct mms_state_segment : public segment { std::string name; - void load(const buffer &b) - { - READ_STRING(b, name); - } + void load(const buffer &b); }; // todo @@ -907,38 +612,26 @@ struct mms_c_config_segment : public segment { struct object { - void load(const buffer &b) - { - } + void load(const buffer &b) {} }; std::vector objects; - void load(const buffer &b) - { - // todo: insert config read from mech - b.read_vector(objects); - } + void load(const buffer &b); }; struct mms_world_data_segment : public segment { float unk0; - void load(const buffer &b) - { - READ(b, unk0); - } + void load(const buffer &b); }; struct mainmech_segment : public segment { uint32_t unk0[9]; - void load(const buffer &b) - { - READ(b, unk0); - } + void load(const buffer &b); }; struct segment_desc @@ -946,82 +639,14 @@ struct segment_desc std::string name; segment *seg = nullptr; - void load(const buffer &b) - { - READ_STRING(b, name); - uint32_t unk0; - READ(b, unk0); - uint32_t len; - READ(b, len); - uint32_t offset; - READ(b, offset); - uint32_t unk1; - READ(b, unk1); - uint32_t len2; - READ(b, len2); - - uint32_t start = b.index(); - uint32_t end = start + len2; - -#define SWITCH(s, t) if (name == s) seg = new t -#define CASE(s, t) else SWITCH(s, t) -#define DEFAULT else - - SWITCH("HEADER", header_segment); - CASE("CAPTION", string_segment); - CASE("PLAYER", string_segment); - CASE("SCREEN", screen_segment); - CASE("SCRIPTS", scripts_segment); - //CASE("RADAR", radar_segment); - //CASE("GAMEDATA", gamedata_segment); - CASE("QUESTLOG", questlog_segment); - CASE("TRADE", trade_segment); - //CASE("ENV", env_segment); - //CASE("ORGREL", orgrel_segment); - CASE("OTHERS", others_segment); - CASE("MECH", mech_segment); - //CASE("GROUPS", groups_segment); - CASE("ORGDATA", orgdata_segment); - CASE("BUILDS", builds_segment); - //CASE("ORGS", orgs_segment); - CASE("TRADEEQP", tradeeqp_segment); - //CASE("OBJECTS", objects_segment); - CASE("MMS_STATE", mms_state_segment); - //CASE("MMS_C_CONFIG", mms_c_config_segment); // (my) clan config - CASE("MMS_WORLD_DATA", mms_world_data_segment); - CASE("MAINMECH", mainmech_segment); - DEFAULT - { - std::cout << "skipped " << name << " size = " << len2 << "\n"; - b.skip(len2); - return; - } - - seg->load(b); - -#undef SWITCH -#undef CASE -#undef DEFAULT - } + void load(const buffer &b); }; struct save { - uint32_t magick; + uint32_t magic; uint32_t version; std::vector segments; - void load(const buffer &b) - { - READ(b, magick); - READ(b, version); - - while (!b.eof()) - { - segment_desc sd; - sd.load(b); - if (sd.seg) - segments.push_back(sd); - } - } + void load(const buffer &b); }; diff --git a/src/save_loader/save_loader.cpp b/src/save_loader/save_loader.cpp index 4f04b75..5b8253d 100644 --- a/src/save_loader/save_loader.cpp +++ b/src/save_loader/save_loader.cpp @@ -26,6 +26,8 @@ #include #include +// for aim2 1.4.30 + int main(int argc, char *argv[]) { cl::opt p(cl::Positional, cl::desc(""), cl::Required);