From 50db190a25e76e24ee25ff1e83ccd71d7d358243 Mon Sep 17 00:00:00 2001 From: lzwdgc Date: Thu, 23 Jun 2016 00:21:01 +0300 Subject: [PATCH] Initial save loader for AIM2. --- src/common/buffer.cpp | 4 +- src/common/buffer.h | 47 +- src/common/dxt5.h | 6 +- src/common/mat.h | 5 +- src/common/objects.cpp | 5 +- src/common/objects.h | 23 +- src/common/types.cpp | 8 +- src/common/types.h | 56 +- src/db_extractor/db.cpp | 10 +- src/db_extractor/db.h | 10 +- src/mmm_extractor/mmm_extractor.cpp | 2 +- src/mmo_extractor/mmo_extractor.cpp | 2 +- src/mmo_extractor/other.h | 92 +--- src/mmp_extractor/mmp.cpp | 12 +- src/mmp_extractor/mmp.h | 14 +- src/mod_converter/model.cpp | 14 +- src/mod_converter/model.h | 14 +- src/mpj_loader/mpj.cpp | 28 +- src/mpj_loader/mpj.h | 36 +- src/save_loader/save.h | 799 ++++++++++++++++++++++++++++ src/save_loader/save_loader.bat | 1 + src/save_loader/save_loader.cpp | 12 + src/save_loader/save_loader.py | 23 + src/script2txt/script.h | 2 +- 24 files changed, 1030 insertions(+), 195 deletions(-) create mode 100644 src/save_loader/save.h create mode 100644 src/save_loader/save_loader.bat create mode 100644 src/save_loader/save_loader.py diff --git a/src/common/buffer.cpp b/src/common/buffer.cpp index 9361872..c2a6e19 100644 --- a/src/common/buffer.cpp +++ b/src/common/buffer.cpp @@ -81,7 +81,7 @@ buffer::buffer(const std::vector &buf, uint32_t data_offset) end_ = index_ + size_; } -buffer::buffer(buffer &rhs, uint32_t size) +buffer::buffer(const buffer &rhs, uint32_t size) : buf_(rhs.buf_) { index_ = rhs.index_; @@ -92,7 +92,7 @@ buffer::buffer(buffer &rhs, uint32_t size) rhs.skip(size); } -buffer::buffer(buffer &rhs, uint32_t size, uint32_t offset) +buffer::buffer(const buffer &rhs, uint32_t size, uint32_t offset) : buf_(rhs.buf_) { index_ = offset; diff --git a/src/common/buffer.h b/src/common/buffer.h index d42554b..0e9f601 100644 --- a/src/common/buffer.h +++ b/src/common/buffer.h @@ -32,6 +32,8 @@ #define READ_WSTRING(b, var) var = b.read_wstring() #define READ_WSTRING_N(b, var, sz) var = b.read_wstring(sz) +#define READ_PASCAL_STRING(b, var) var = b.read_pascal_string() + #define WRITE(b, var) b.write(&var) std::string version(); @@ -44,18 +46,13 @@ public: buffer(); buffer(size_t size); buffer(const std::vector &buf, uint32_t data_offset = 0); - buffer(buffer &rhs, uint32_t size); - buffer(buffer &rhs, uint32_t size, uint32_t offset); + buffer(const buffer &rhs, uint32_t size); + buffer(const buffer &rhs, uint32_t size, uint32_t offset); template - uint32_t read(T *dst) const + uint32_t read(T *dst, uint32_t size = 1) const { - return _read(dst, sizeof(T), 0); - } - template - uint32_t read(T *dst, uint32_t size) const - { - return _read(dst, size * sizeof(T), 0); + return _read((void *)dst, size * sizeof(T), 0); } std::string read_string(uint32_t blocksize = 0x20) const; std::wstring read_wstring(uint32_t blocksize = 0x20) const; @@ -81,7 +78,37 @@ public: return _write(src, sizeof(T)); } - void seek(uint32_t size) const; + template + void read_vector(std::vector &v, int n) const + { + v.clear(); + v.reserve(n); + for (int i = 0; i < n; i++) + { + T t; + t.load(*this); + v.push_back(t); + } + } + + template + void read_vector(std::vector &v) const + { + SizeType n = 0; + read(&n); + read_vector(v, n); + } + + std::string read_pascal_string() const + { + uint32_t n = 0; + read(&n); + std::string s(n, 0); + read(s.data(), n); + return s; + } + + void seek(uint32_t size) const; // setpos void skip(int n) const; bool eof() const; bool check(int index) const; diff --git a/src/common/dxt5.h b/src/common/dxt5.h index 12cd581..a8d307b 100644 --- a/src/common/dxt5.h +++ b/src/common/dxt5.h @@ -47,7 +47,7 @@ struct dxt5_block }; dxt5_block() {} - void load(buffer &b) + void load(const buffer &b) { READ(b, alpha_part); READ(b, color_part); @@ -114,13 +114,13 @@ struct dxt5 uint32_t height; std::vector blocks; - void load(buffer &b) + void load(const buffer &b) { READ(b, width); READ(b, height); load_blocks(b); } - void load_blocks(buffer &b) + void load_blocks(const buffer &b) { blocks.resize(width * height / 16); for (auto &d : blocks) diff --git a/src/common/mat.h b/src/common/mat.h index 4cca0d8..b6e9aab 100644 --- a/src/common/mat.h +++ b/src/common/mat.h @@ -57,6 +57,7 @@ public: int getWidth() const { return width; } int getHeight() const { return height; } int size() const { return width * height; } + int getBytesLength() const { return size() * sizeof(T); } int getPos(const T *const elem) const { return elem - &data[0]; } const std::vector &getData() const { return data; } std::vector &getData() { return data; } @@ -101,7 +102,7 @@ void write_mat_tga(const std::string &filename, const mat &m) FILE *f = fopen(filename.c_str(), "wb"); if (f == nullptr) return; - + tga t; t.width = m.getWidth(); t.height = m.getHeight(); @@ -109,7 +110,7 @@ void write_mat_tga(const std::string &filename, const mat &m) // header fwrite(&t, sizeof(tga), 1, f); fwrite(t.label(), t.idlength, 1, f); - + // data fwrite(&m(0, 0), m.size() * sizeof(T), 1, f); fclose(f); diff --git a/src/common/objects.cpp b/src/common/objects.cpp index c6d2df7..48b6022 100644 --- a/src/common/objects.cpp +++ b/src/common/objects.cpp @@ -18,7 +18,7 @@ #include "objects.h" -Segment *Segment::create_segment(buffer &b) +Segment *Segment::create_segment(const buffer &b) { ObjectType segment_type; READ(b, segment_type); @@ -81,8 +81,9 @@ Segment *Segment::create_segment(buffer &b) return segment; } -void Objects::load(buffer &b) +void Objects::load(const buffer &b) { + uint32_t n_segments = 0; READ(b, n_segments); for (int s = 0; s < n_segments; s++) diff --git a/src/common/objects.h b/src/common/objects.h index fa20a2c..e4e6910 100644 --- a/src/common/objects.h +++ b/src/common/objects.h @@ -69,8 +69,8 @@ struct Segment uint32_t n_objects = 0; virtual ~Segment(){} - static Segment *create_segment(buffer &b); - virtual void load(buffer &b) = 0; + static Segment *create_segment(const buffer &b); + virtual void load(const buffer &b) = 0; }; template @@ -78,7 +78,7 @@ struct SegmentObjects : public Segment { std::vector objects; - virtual void load(buffer &b) + virtual void load(const buffer &b) { for (int i = 0; i < n_objects; i++) { @@ -91,10 +91,10 @@ struct SegmentObjects : public Segment struct Common { - Vector4 m_rotate_z[3]; - Vector4 position; + vector4 m_rotate_z[3]; + vector4 position; - void load(buffer &b) + void load(const buffer &b) { READ(b, m_rotate_z); READ(b, position); @@ -106,7 +106,7 @@ struct MapObject : public Common std::string name1; std::string name2; - void load(buffer &b) + void load(const buffer &b) { Common::load(b); @@ -120,7 +120,7 @@ struct MapObjectWithArray : public MapObject uint32_t len = 0; std::vector unk0; - void load(buffer &b) + void load(const buffer &b) { MapObject::load(b); @@ -136,7 +136,7 @@ struct Sound : public Common uint32_t unk1[11]; char name1[0x14]; - void load(buffer &b) + void load(const buffer &b) { Common::load(b); @@ -162,15 +162,14 @@ KNOWN_OBJECT(Tower); KNOWN_OBJECT(SoundZone); #define UNKNOWN_OBJECT(name) \ - struct name : public MapObject { void load(buffer &b){ int pos = b.index(); assert(false); } } + struct name : public MapObject { void load(const buffer &b){ int pos = b.index(); assert(false); } } UNKNOWN_OBJECT(unk0); UNKNOWN_OBJECT(unk1); struct Objects { - uint32_t n_segments = 0; std::vector segments; - void load(buffer &b); + void load(const buffer &b); }; diff --git a/src/common/types.cpp b/src/common/types.cpp index a3fc261..58bcf90 100644 --- a/src/common/types.cpp +++ b/src/common/types.cpp @@ -20,7 +20,7 @@ GameType gameType = GameType::Aim2; -void weather::load(buffer &b) +void weather::load(const buffer &b) { READ_STRING(b, name); READ_STRING(b, unk0); @@ -52,7 +52,7 @@ void weather::load(buffer &b) READ(b, unk8); } -void weather_group::load(buffer &b) +void weather_group::load(const buffer &b) { READ(b, n_segs); segments.resize(n_segs); @@ -61,7 +61,7 @@ void weather_group::load(buffer &b) s.load(b); } -void water::load(buffer &b) +void water::load(const buffer &b) { READ(b, unk0); READ_STRING(b, name1); @@ -73,7 +73,7 @@ void water::load(buffer &b) READ(b, unk5); } -void water_group::load(buffer &b) +void water_group::load(const buffer &b) { while (!b.eof()) { diff --git a/src/common/types.h b/src/common/types.h index c307ca4..3dce160 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -37,7 +37,7 @@ struct vector3 float z = 0; }; -struct Vector4 +struct vector4 { float x = 0; float y = 0; @@ -100,7 +100,7 @@ struct weather uint32_t slider_1; float unk8[11]; - void load(buffer &b); + void load(const buffer &b); }; struct weather_group @@ -109,7 +109,7 @@ struct weather_group char name[0xA0]; std::vector segments; - void load(buffer &b); + void load(const buffer &b); }; struct water @@ -123,14 +123,14 @@ struct water std::string name2; uint32_t unk5[16]; - void load(buffer &b); + void load(const buffer &b); }; struct water_group { std::vector segments; - void load(buffer &b); + void load(const buffer &b); }; struct Good @@ -143,7 +143,7 @@ struct Good float unk2_1[2]; uint32_t unk2_2[2]; - void load(buffer &b) + void load(const buffer &b) { READ_STRING(b, name); if (gameType == GameType::Aim1) @@ -168,7 +168,7 @@ struct BuildingGoods std::vector goods; - void load(buffer &b) + void load(const buffer &b) { READ_STRING(b, name); READ(b, n); @@ -187,13 +187,10 @@ struct MapMusic std::string name1; std::string name2; - uint32_t n1 = 0; std::vector names1; - - uint32_t n2 = 0; std::vector names2; - void load(buffer &b) + void load(const buffer &b) { READ_STRING(b, name1); READ_STRING(b, name2); @@ -204,9 +201,11 @@ struct MapMusic v.push_back(b.read_string()); }; + uint32_t n1 = 0; READ(b, n1); read_values(names1, n1); + uint32_t n2 = 0; READ(b, n2); read_values(names2, n2); } @@ -217,7 +216,7 @@ struct OrganizationConfig uint32_t n_configs = 0; std::vector configs; - void load(buffer &b) + void load(const buffer &b) { READ(b, n_configs); configs.resize(n_configs, std::string(0x20, 0)); @@ -233,7 +232,7 @@ struct Organization char unk1[0xE0]; OrganizationConfig configs[3]; - void load(buffer &b) + void load(const buffer &b) { READ(b, unk0); READ_STRING(b, name); @@ -245,13 +244,13 @@ struct Organization struct Organizations { - uint32_t len = 0; - uint32_t n = 0; std::vector organizations; - void load(buffer &b) + void load(const buffer &b) { + uint32_t len = 0; READ(b, len); + uint32_t n = 0; READ(b, n); for (int i = 0; i < n; i++) { @@ -268,7 +267,7 @@ struct OrganizationBase std::string org_name; uint32_t unk0 = 0; - void load(buffer &b) + void load(const buffer &b) { READ_STRING(b, base_name); READ_STRING(b, org_name); @@ -278,11 +277,11 @@ struct OrganizationBase struct OrganizationBases { - uint32_t n = 0; std::vector organizationBases; - void load(buffer &b) + void load(const buffer &b) { + uint32_t n = 0; READ(b, n); for (int i = 0; i < n; i++) { @@ -292,3 +291,22 @@ struct OrganizationBases } } }; + +struct ModificatorMask +{ + enum class ItemType : uint8_t + { + Glider = 1, + Weapon, + Reactor, + Engine, + EnergyShield + }; + + uint8_t fight : 4; + uint8_t trade : 4; + uint8_t courier : 4; + ItemType type : 4; + + uint16_t : 16; +}; diff --git a/src/db_extractor/db.cpp b/src/db_extractor/db.cpp index b45fb61..e3c6da0 100644 --- a/src/db_extractor/db.cpp +++ b/src/db_extractor/db.cpp @@ -36,14 +36,14 @@ string getSqlType(FieldType type) return ""; } -void table::load(buffer &b) +void table::load(const buffer &b) { READ(b, id); READ_STRING(b, name); READ(b, unk4); } -void field::load(buffer &b) +void field::load(const buffer &b) { READ(b, table_id); READ(b, id); @@ -51,7 +51,7 @@ void field::load(buffer &b) READ(b, type); } -void tab::load(buffer &b) +void tab::load(const buffer &b) { READ(b, number_of_tables); READ(b, number_of_fields); @@ -73,7 +73,7 @@ void tab::load(buffer &b) } } -void value::load_index(buffer &b) +void value::load_index(const buffer &b) { READ(b, table_id); READ_STRING(b, name); @@ -122,7 +122,7 @@ void value::load_fields(const tab &tab, buffer &b) } } -void db::load(buffer &b) +void db::load(const buffer &b) { READ(b, number_of_values); diff --git a/src/db_extractor/db.h b/src/db_extractor/db.h index 4e6c32d..6d927cd 100644 --- a/src/db_extractor/db.h +++ b/src/db_extractor/db.h @@ -42,7 +42,7 @@ struct table std::string name; uint32_t unk4; - void load(buffer &b); + void load(const buffer &b); }; struct field @@ -52,7 +52,7 @@ struct field std::string name; FieldType type; - void load(buffer &b); + void load(const buffer &b); }; struct tab @@ -63,7 +63,7 @@ struct tab map tables; map fields; - void load(buffer &b); + void load(const buffer &b); }; struct field_value @@ -84,7 +84,7 @@ struct value uint32_t data_size; vector fields; - void load_index(buffer &b); + void load_index(const buffer &b); void load_fields(const tab &tab, buffer &b); }; @@ -95,5 +95,5 @@ struct db tab t; vector values; - void load(buffer &b); + void load(const buffer &b); }; \ No newline at end of file diff --git a/src/mmm_extractor/mmm_extractor.cpp b/src/mmm_extractor/mmm_extractor.cpp index fa51c86..87ec2d7 100644 --- a/src/mmm_extractor/mmm_extractor.cpp +++ b/src/mmm_extractor/mmm_extractor.cpp @@ -32,7 +32,7 @@ struct mmm uint32_t unk2; dxt5 data; - void load(buffer &b) + void load(const buffer &b) { READ(b, unk1); READ(b, unk2); diff --git a/src/mmo_extractor/mmo_extractor.cpp b/src/mmo_extractor/mmo_extractor.cpp index 3bb9e41..07b2e4c 100644 --- a/src/mmo_extractor/mmo_extractor.cpp +++ b/src/mmo_extractor/mmo_extractor.cpp @@ -54,7 +54,7 @@ struct storage OrganizationBases orgsBases; Prices prices; - void load(buffer &b) + void load(const buffer &b) { objects.load(b); mechGroups.load(b); diff --git a/src/mmo_extractor/other.h b/src/mmo_extractor/other.h index ec0788d..b00da4f 100644 --- a/src/mmo_extractor/other.h +++ b/src/mmo_extractor/other.h @@ -48,7 +48,7 @@ struct MechGroup std::vector configs; char unk100; - void load(buffer &b) + void load(const buffer &b) { READ_STRING(b, name); READ_STRING(b, org); @@ -82,16 +82,17 @@ struct MechGroup struct MechGroups { - uint32_t length = 0; - uint32_t n = 0; char prefix[0x30]; + std::vector mechGroups; - std::vector mgs; - - void load(buffer &b) + void load(const buffer &b) { if (gameType == GameType::Aim2) + { + uint32_t length = 0; READ(b, length); + } + uint32_t n = 0; READ(b, n); READ(b, prefix); @@ -99,28 +100,28 @@ struct MechGroups { MechGroup mg; mg.load(b); - mgs.push_back(mg); + mechGroups.push_back(mg); } } }; struct MapGoods { - uint32_t length = 0; uint32_t unk2 = 0; uint32_t unk3 = 0; - uint32_t n = 0; std::vector bgs; - void load(buffer &b) + void load(const buffer &b) { + uint32_t length = 0; READ(b, length); READ(b, unk2); if (gameType != GameType::Aim2) READ(b, unk3); - READ(b, n); + uint32_t n = 0; + READ(b, n); for (int i = 0; i < n; i++) { BuildingGoods bg; @@ -139,7 +140,7 @@ struct MapSound uint32_t unk2 = 0; float unk3[4]; - void load(buffer &b) + void load(const buffer &b) { READ_STRING(b, name); READ(b, unk1); @@ -150,40 +151,14 @@ struct MapSound struct MapSounds { - uint32_t n = 0; std::vector sounds; - void load(buffer &b) + void load(const buffer &b) { - READ(b, n); - for (int i = 0; i < n; i++) - { - MapSound s; - s.load(b); - sounds.push_back(s); - } + b.read_vector(sounds); } }; -struct ModificatorMask -{ - enum class ItemType : uint8_t - { - Glider = 1, - Weapon, - Reactor, - Engine, - EnergyShield - }; - - uint8_t fight:4; - uint8_t trade:4; - uint8_t courier:4; - ItemType type:4; - - uint16_t:16; -}; - struct Price { enum class ItemType : uint32_t @@ -201,7 +176,7 @@ struct Price float unk2 = 0.0f; // count ? float probability; // of appearence - void load(buffer &b) + void load(const buffer &b) { READ_STRING(b, tov_name); READ(b, type); @@ -217,17 +192,10 @@ struct BuildingPrice std::string name; std::vector prices; - void load(buffer &b) + void load(const buffer &b) { READ_STRING(b, name); - uint32_t n_tov = 0; - READ(b, n_tov); - for (int i = 0; i < n_tov; i++) - { - Price s; - s.load(b); - prices.push_back(s); - } + b.read_vector(prices); } }; @@ -236,35 +204,21 @@ struct BuildingPrices std::vector prices; std::vector buildingPrices; - void load(buffer &b) + void load(const buffer &b) { - uint32_t n_tov = 0; - READ(b, n_tov); - for (int i = 0; i < n_tov; i++) - { - Price s; - s.load(b); - prices.push_back(s); - } - uint32_t n_bases = 0; - READ(b, n_bases); - for (int i = 0; i < n_bases; i++) - { - BuildingPrice s; - s.load(b); - buildingPrices.push_back(s); - } + b.read_vector(prices); + b.read_vector(buildingPrices); } }; struct Prices { - uint32_t len = 0; uint32_t unk0 = 0; BuildingPrices buildingPrices; - void load(buffer &b) + void load(const buffer &b) { + uint32_t len = 0; READ(b, len); READ(b, unk0); buildingPrices.load(b); diff --git a/src/mmp_extractor/mmp.cpp b/src/mmp_extractor/mmp.cpp index c9dc84f..6b10868 100644 --- a/src/mmp_extractor/mmp.cpp +++ b/src/mmp_extractor/mmp.cpp @@ -22,17 +22,17 @@ #include #include -void water_segment::load(buffer &b) +void water_segment::load(const buffer &b) { wg.load(b); } -void weather_segment::load(buffer &b) +void weather_segment::load(const buffer &b) { wg.load(b); } -header_segment *header::create_segment(buffer &b) +header_segment *header::create_segment(const buffer &b) { HeaderSegmentType type; READ(b, type); @@ -59,7 +59,7 @@ header_segment *header::create_segment(buffer &b) return segment; } -void header::load(buffer &b) +void header::load(const buffer &b) { READ(b, unk0); READ_WSTRING(b, name1); @@ -78,7 +78,7 @@ void header::load(buffer &b) } } -void segment::load(buffer &b) +void segment::load(const buffer &b) { READ(b, desc); buffer b2(b); @@ -86,7 +86,7 @@ void segment::load(buffer &b) READ(b2, d); } -void mmp::load(buffer &b) +void mmp::load(const buffer &b) { h.load(b); xsegs = (h.width - 1) / 64; diff --git a/src/mmp_extractor/mmp.h b/src/mmp_extractor/mmp.h index 825da22..44c142d 100644 --- a/src/mmp_extractor/mmp.h +++ b/src/mmp_extractor/mmp.h @@ -41,21 +41,21 @@ struct header_segment uint32_t unk0; uint32_t len; - virtual void load(buffer &b) = 0; + virtual void load(const buffer &b) = 0; }; struct water_segment : public header_segment { water_group wg; - virtual void load(buffer &b) override; + virtual void load(const buffer &b) override; }; struct weather_segment : public header_segment { weather_group wg; - virtual void load(buffer &b) override; + virtual void load(const buffer &b) override; }; struct header @@ -69,10 +69,10 @@ struct header std::string name; std::vector segments; - void load(buffer &b); + void load(const buffer &b); private: - header_segment *create_segment(buffer &b); + header_segment *create_segment(const buffer &b); }; struct segment @@ -139,7 +139,7 @@ struct segment description desc; data d; - void load(buffer &b); + void load(const buffer &b); }; struct mmp @@ -164,7 +164,7 @@ struct mmp mat texmap_colored; mat colormap; - void load(buffer &b); + void load(const buffer &b); void load(const std::string &filename); void loadTextureNames(const std::string &filename); diff --git a/src/mod_converter/model.cpp b/src/mod_converter/model.cpp index 46ce804..6398398 100644 --- a/src/mod_converter/model.cpp +++ b/src/mod_converter/model.cpp @@ -36,7 +36,7 @@ std::string Vector4::print() const return s; } -void vertex::load(buffer &b, uint32_t flags) +void vertex::load(const buffer &b, uint32_t flags) { READ(b, vX); READ(b, vZ); @@ -74,7 +74,7 @@ std::string vertex::printTex() const return s; } -void damage_model::load(buffer &b) +void damage_model::load(const buffer &b) { READ(b, n_polygons); polygons.resize(n_polygons); @@ -94,7 +94,7 @@ void damage_model::load(buffer &b) READ(b, t); } -void animation::load(buffer &b) +void animation::load(const buffer &b) { READ(b, type); READ(b, name); @@ -105,14 +105,14 @@ void animation::load(buffer &b) s.loadData(b); } -void animation::segment::loadHeader(buffer &b) +void animation::segment::loadHeader(const buffer &b) { READ(b, n); READ(b, unk0); READ(b, unk1); } -void animation::segment::loadData(buffer &b) +void animation::segment::loadData(const buffer &b) { if (n == 0) return; @@ -190,7 +190,7 @@ std::string block::printObj(const std::string &mtl_name) const return s; } -void block::load(buffer &b) +void block::load(const buffer &b) { // header READ(b, type); @@ -267,7 +267,7 @@ void block::load(buffer &b) throw std::logic_error("extraction error: block #" + std::string(name)); } -void model::load(buffer &b) +void model::load(const buffer &b) { READ(b, n_blocks); if (n_blocks > 1000) // probably bad file diff --git a/src/mod_converter/model.h b/src/mod_converter/model.h index 587710a..c6b5753 100644 --- a/src/mod_converter/model.h +++ b/src/mod_converter/model.h @@ -77,7 +77,7 @@ struct vertex float t1; float t2; - void load(buffer &b, uint32_t flags); + void load(const buffer &b, uint32_t flags); std::string printVertex() const; std::string printNormal() const; @@ -103,15 +103,15 @@ struct animation std::vector triangles; std::vector unk2; - void loadHeader(buffer &b); - void loadData(buffer &b); + void loadHeader(const buffer &b); + void loadData(const buffer &b); }; uint32_t type; char name[0xC]; segment segments[4]; - virtual void load(buffer &b); + virtual void load(const buffer &b); }; struct damage_model @@ -127,7 +127,7 @@ struct damage_model std::vector vertices; std::vector triangles; - virtual void load(buffer &b); + virtual void load(const buffer &b); }; struct material @@ -212,7 +212,7 @@ struct block std::vector animations; std::vector damage_models; - void load(buffer &b); + void load(const buffer &b); std::string printMtl(const std::string &mtl_name) const; std::string printObj(const std::string &mtl_name) const; }; @@ -223,5 +223,5 @@ struct model char header[0x40]; std::vector blocks; - void load(buffer &b); + void load(const buffer &b); }; diff --git a/src/mpj_loader/mpj.cpp b/src/mpj_loader/mpj.cpp index 1feadb3..a77fc5a 100644 --- a/src/mpj_loader/mpj.cpp +++ b/src/mpj_loader/mpj.cpp @@ -23,7 +23,7 @@ #include #include -segment *segment::create_segment(buffer &b) +segment *segment::create_segment(const buffer &b) { SegmentType type; READ(b, type); @@ -79,7 +79,7 @@ segment *segment::create_segment(buffer &b) return segment; } -void map_data::load(buffer &b) +void map_data::load(const buffer &b) { auto sz = b.size(); assert(sz % 3 == 0); @@ -94,7 +94,7 @@ void map_data::load(buffer &b) #undef READ_SEG } -void surface::load(buffer &b) +void surface::load(const buffer &b) { while (!b.eof()) { @@ -105,36 +105,36 @@ void surface::load(buffer &b) } } -void weather_data::load(buffer &b) +void weather_data::load(const buffer &b) { wg.load(b); } -void objects_data::load(buffer &b) +void objects_data::load(const buffer &b) { objects.load(b); } -void segment7::load(buffer &b) +void segment7::load(const buffer &b) { auto n = b.size() / sizeof(decltype(data)::value_type); data.resize(n); READ_N(b, data[0], n); } -void water_data::load(buffer &b) +void water_data::load(const buffer &b) { wg.load(b); } -void segment9::load(buffer &b) +void segment9::load(const buffer &b) { auto n = b.size() / sizeof(decltype(data)::value_type); data.resize(n); READ_N(b, data[0], n); } -void building_goods::load(buffer &b) +void building_goods::load(const buffer &b) { READ(b, unk1); READ(b, n); @@ -143,7 +143,7 @@ void building_goods::load(buffer &b) bg.load(b); } -void map_music::load(buffer &b) +void map_music::load(const buffer &b) { while (!b.eof()) { @@ -154,7 +154,7 @@ void map_music::load(buffer &b) } } -void organizations::load(buffer &b) +void organizations::load(const buffer &b) { READ(b, n); orgs.resize(n); @@ -163,7 +163,7 @@ void organizations::load(buffer &b) bases.load(b); } -void gliders_n_goods::load(buffer &b) +void gliders_n_goods::load(const buffer &b) { READ(b, n_good_groups); READ(b, n_gliders); @@ -176,7 +176,7 @@ void gliders_n_goods::load(buffer &b) g.load(b); } -void header::load(buffer &b) +void header::load(const buffer &b) { READ(b, magic); if (memcmp(magic, "MPRJ", 4) != 0) @@ -212,7 +212,7 @@ void header::load(buffer &b) } } -void mpj::load(buffer &b) +void mpj::load(const buffer &b) { h.load(b); } diff --git a/src/mpj_loader/mpj.h b/src/mpj_loader/mpj.h index 22ec4c7..7256876 100644 --- a/src/mpj_loader/mpj.h +++ b/src/mpj_loader/mpj.h @@ -50,8 +50,8 @@ struct segment virtual ~segment() {} - static segment *create_segment(buffer &b); - virtual void load(buffer &b) = 0; + static segment *create_segment(const buffer &b); + virtual void load(const buffer &b) = 0; }; struct map_data : public segment @@ -60,7 +60,7 @@ struct map_data : public segment std::vector unk2; std::vector unk3; - virtual void load(buffer &b) override; + virtual void load(const buffer &b) override; }; struct surface : public segment @@ -72,42 +72,42 @@ struct surface : public segment }; std::vector unk1; - virtual void load(buffer &b) override; + virtual void load(const buffer &b) override; }; struct weather_data : public segment { weather_group wg; - virtual void load(buffer &b) override; + virtual void load(const buffer &b) override; }; struct objects_data : public segment { Objects objects; - virtual void load(buffer &b) override; + virtual void load(const buffer &b) override; }; struct segment7 : public segment { std::vector data; - virtual void load(buffer &b) override; + virtual void load(const buffer &b) override; }; struct water_data : public segment { water_group wg; - virtual void load(buffer &b) override; + virtual void load(const buffer &b) override; }; struct segment9 : public segment { std::vector data; - virtual void load(buffer &b) override; + virtual void load(const buffer &b) override; }; struct building_goods : public segment @@ -117,7 +117,7 @@ struct building_goods : public segment BuildingGoods bg; uint32_t unk0; - void load(buffer &b) + void load(const buffer &b) { bg.load(b); READ(b, unk0); @@ -127,7 +127,7 @@ struct building_goods : public segment uint32_t n; std::vector bgs; - virtual void load(buffer &b) override; + virtual void load(const buffer &b) override; }; struct map_music : public segment @@ -135,7 +135,7 @@ struct map_music : public segment std::vector mms; uint32_t unk1; - virtual void load(buffer &b) override; + virtual void load(const buffer &b) override; }; struct organizations : public segment @@ -144,7 +144,7 @@ struct organizations : public segment std::vector orgs; OrganizationBases bases; - virtual void load(buffer &b) override; + virtual void load(const buffer &b) override; }; struct gliders_n_goods : public segment @@ -154,7 +154,7 @@ struct gliders_n_goods : public segment std::string name; int unk0[3]; - void load(buffer &b) + void load(const buffer &b) { READ_STRING(b, name); READ(b, unk0); @@ -166,7 +166,7 @@ struct gliders_n_goods : public segment uint32_t n_goods; std::vector goods; - void load(buffer &b) + void load(const buffer &b) { READ(b, n_goods); goods.resize(n_goods); @@ -181,7 +181,7 @@ struct gliders_n_goods : public segment uint32_t unk1; std::vector goods; - virtual void load(buffer &b) override; + virtual void load(const buffer &b) override; }; struct header @@ -196,7 +196,7 @@ struct header char unk4[0x3F4]; std::vector segments; - void load(buffer &b); + void load(const buffer &b); }; struct mpj @@ -206,6 +206,6 @@ struct mpj // std::string filename; - void load(buffer &b); + void load(const buffer &b); void load(const std::string &filename); }; diff --git a/src/save_loader/save.h b/src/save_loader/save.h new file mode 100644 index 0000000..ee6d3f5 --- /dev/null +++ b/src/save_loader/save.h @@ -0,0 +1,799 @@ +/* + * 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 . + */ + +#pragma once + +#include +#include +#include +#include + +// common structs + +struct int_variable +{ + std::string name; + uint32_t value; + + void load(const buffer &b) + { + READ_STRING(b, name); + READ(b, value); + } +}; + +struct single_string +{ + std::string name; + + void load(const buffer &b) + { + READ_STRING(b, name); + } +}; + +struct string_variable +{ + std::string name; + std::string value; + + void load(const buffer &b) + { + READ_STRING(b, name); + READ_STRING(b, value); + } +}; + +// segments + +struct segment +{ + virtual void load(const buffer &) = 0; +}; + +struct header_segment : public segment +{ + uint32_t unk1[3]; + std::string save_name; + vector3 position; + std::string mmp_file; + std::string location_name; + 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); + } +}; + +struct string_segment : public segment +{ + std::string s; + + void load(const buffer &b) + { + READ_PASCAL_STRING(b, s); + } +}; + +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. + } +}; + +struct scripts_segment : public segment +{ + struct script_entry + { + std::string name; + std::string path; + + void load(const buffer &b) + { + READ_STRING(b, name); + READ_STRING_N(b, path, 0x80); + } + }; + + 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); + } + }; + + std::vector bases; + std::vector events; + std::vector unk0; + 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); + } +}; + +// todo +struct radar_segment : public segment +{ + struct radar + { + char unk0[0x1C4]; + + void load(const buffer &b) + { + READ(b, unk0); + } + }; + + struct mechanoid5 + { + std::string name; + float unk0[6]; + + void load(const buffer &b) + { + READ_STRING(b, name); + READ(b, unk0); + } + }; + + std::vector radars; + uint16_t unk0; + std::vector mechanoid5s; + std::vector orgs; + + void load(const buffer &b) + { + b.read_vector(radars); + READ(b, unk0); + b.read_vector(mechanoid5s); + b.read_vector(orgs); + } +}; + +// todo +struct gamedata_segment : public segment +{ + void load(const buffer &b) + { + } +}; + +struct questlog_segment : public segment +{ + struct record + { + std::string name; + std::string name_journal; + 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); + } + }; + + uint32_t unk0; + + std::vector int_variables; + 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); + } +}; + +struct trade_segment : public segment +{ + struct Price + { + std::string tov_name; + float unk2[6]; + + void load(const buffer &b) + { + READ_STRING(b, tov_name); + READ(b, unk2); + } + }; + + struct BuildingPrice + { + std::string name; + std::vector prices; + uint32_t unk0; + + void load(const buffer &b) + { + READ_STRING(b, name); + b.read_vector(prices); + READ(b, unk0); + } + }; + + uint32_t unk0 = 0; + std::vector buildingPrices; + + void load(const buffer &b) + { + READ(b, unk0); + b.read_vector(buildingPrices); + } +}; + +// todo +struct env_segment : public segment +{ + void load(const buffer &b) + { + } +}; + +// todo +struct orgrel_segment : public segment +{ + struct org_rep + { + char unk1[0xE0]; + + void load(const buffer &b) + { + READ(b, unk1); + } + }; + + std::vector org_reps; + + void load(const buffer &b) + { + b.read_vector(org_reps); + } +}; + +struct others_segment : public segment +{ + uint32_t unk0; + uint32_t unk1; + + void load(const buffer &b) + { + READ(b, unk0); + READ(b, unk1); + } +}; + +// todo +struct mech_segment : public segment +{ + struct equipment + { + uint8_t id; + std::string name; + uint32_t unk0; + uint32_t unk1; + + void load(const buffer &b) + { + READ(b, id); + READ_STRING(b, name); + READ(b, unk0); + READ(b, unk1); + } + }; + + struct moddable_equipment + { + std::string name; + ModificatorMask mask; + + void load(const buffer &b) + { + READ_STRING(b, name); + READ(b, mask); + } + }; + + struct unk_equ + { + uint8_t id; + std::string name; + uint32_t unk0; + uint32_t unk1; + + void load(const buffer &b) + { + READ(b, id); + READ_STRING(b, name); + READ(b, unk0); + READ(b, unk1); + } + }; + + struct hold_item + { + enum class Type : uint32_t + { + Good = 0, + Mechanoid = 2, + }; + + Type type; + std::string name; + uint32_t count; + 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); + } + }; + + struct glider + { + moddable_equipment glider_; + moddable_equipment weapon1; + moddable_equipment weapon2; + moddable_equipment reactor1; + moddable_equipment reactor2; + moddable_equipment engine1; + moddable_equipment engine2; + moddable_equipment energy_shield; + moddable_equipment armor; + + uint32_t unk0; + uint32_t unk1; + std::string unk2; // fast bomb + uint32_t unk3; + + unk_equ ureactor1; + unk_equ ureactor2; + unk_equ uengine1; + unk_equ uengine2; + unk_equ uenergy_shield; + unk_equ uarmor; + + std::string unk4; + uint32_t unk5[3]; + + float money; + + std::vector items; + + void load(const buffer &b) + { + glider_.load(b); + weapon1.load(b); + weapon2.load(b); + reactor1.load(b); + reactor2.load(b); + engine1.load(b); + engine2.load(b); + energy_shield.load(b); + armor.load(b); + + // ? + READ(b, unk0); + READ(b, unk1); + if (unk0) + READ_STRING(b, unk2); + READ(b, unk3); + + ureactor1.load(b); + ureactor2.load(b); + uengine1.load(b); + uengine2.load(b); + uenergy_shield.load(b); + uarmor.load(b); + + READ_STRING(b, unk4); + READ(b, unk5); + + READ(b, money); + + b.read_vector(items); + + if (unk0) + b.skip(0x15D); + else + b.skip(0x150); + } + }; + + struct mech + { + uint8_t id; + std::string name; + std::string name2; + std::string org; + std::string building; + + //Common pos; + uint8_t unk2; + uint32_t unk3; + std::vector equipments; + uint32_t unk4[8]; + glider g; + + uint32_t unk5[8]; + uint8_t unk6; + + void load(const buffer &b) + { + READ(b, id); + READ_STRING(b, name); + READ_STRING(b, name2); + READ_STRING(b, org); + READ_STRING(b, building); + + //READ(b, pos); + READ(b, unk2); + READ(b, unk3); + b.read_vector(equipments); + READ(b, unk4); + g.load(b); + } + }; + + std::vector mechs; + + void load(const buffer &b) + { + b.read_vector(mechs); + } +}; + +// todo +struct groups_segment : public segment +{ + struct group + { + vector3 pos; + std::string org; + float unk0[12]; + + void load(const buffer &b) + { + READ(b, pos); + READ_STRING(b, org); + READ(b, unk0); + } + }; + + std::vector groups; + + void load(const buffer &b) + { + b.read_vector(groups); + } +}; + +struct orgdata_segment : public segment +{ + struct org_config + { + std::vector names; + + void load(const buffer &b) + { + b.read_vector(names); + } + }; + + struct orgdata + { + uint32_t unk0; + std::string org; + float unk1[4]; + uint32_t unk2[2]; + 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); + } + }; + + std::vector orgdatas; + + void load(const buffer &b) + { + b.read_vector(orgdatas); + } +}; + +struct builds_segment : public segment +{ + struct build + { + std::string bld; + std::string org; + float unk1; + + void load(const buffer &b) + { + READ_STRING(b, bld); + READ_STRING(b, org); + READ(b, unk1); + } + }; + + std::vector builds; + + void load(const buffer &b) + { + b.read_vector(builds); + } +}; + +// todo +struct orgs_segment : public segment +{ + struct org + { + void load(const buffer &b) + { + } + }; + + std::vector orgs; + + void load(const buffer &b) + { + b.read_vector(orgs); + } +}; + +struct tradeeqp_segment : public segment +{ + struct Good + { + std::string tov_name; + uint32_t unk0; + uint32_t mask; + float price; + 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); + } + }; + + struct bld + { + std::string name; + std::vector prices; + + void load(const buffer &b) + { + READ_STRING(b, name); + b.read_vector(prices); + } + }; + + 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); + } +}; + +// todo +struct objects_segment : public segment +{ + struct object + { + void load(const buffer &b) + { + } + }; + + std::vector objects; + + void load(const buffer &b) + { + b.read_vector(objects); + } +}; + +struct mms_state_segment : public segment +{ + std::string name; + + void load(const buffer &b) + { + READ_STRING(b, name); + } +}; + +// todo +struct mms_c_config_segment : public segment +{ + struct object + { + void load(const buffer &b) + { + } + }; + + std::vector objects; + + void load(const buffer &b) + { + b.read_vector(objects); + } +}; + +struct mms_world_data_segment : public segment +{ + float unk0; + + void load(const buffer &b) + { + READ(b, unk0); + } +}; + +struct mainmech_segment : public segment +{ + uint32_t unk0[9]; + + void load(const buffer &b) + { + READ(b, unk0); + } +}; + +struct segment_desc +{ + std::string name; + uint32_t len2; + 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); + 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); + 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 + } +}; + +struct save +{ + uint32_t magick; + uint32_t unk0; + std::vector segments; + + void load(const buffer &b) + { + READ(b, magick); + READ(b, unk0); + + while (!b.eof()) + { + segment_desc sd; + sd.load(b); + segments.push_back(sd); + } + } +}; diff --git a/src/save_loader/save_loader.bat b/src/save_loader/save_loader.bat new file mode 100644 index 0000000..c01215b --- /dev/null +++ b/src/save_loader/save_loader.bat @@ -0,0 +1 @@ +python save_loader.py --dir "h:\\Games\\Steam\\steamapps\\common\\AIM2\\SAVES\\" \ No newline at end of file diff --git a/src/save_loader/save_loader.cpp b/src/save_loader/save_loader.cpp index 151dc82..a01821f 100644 --- a/src/save_loader/save_loader.cpp +++ b/src/save_loader/save_loader.cpp @@ -17,6 +17,17 @@ */ #include +#include + +#include "save.h" + +save read_save(const std::string &fn) +{ + buffer f(readFile(fn)); + save s; + s.load(f); + return s; +} int main(int argc, char *argv[]) try @@ -26,6 +37,7 @@ try printf("Usage: %s file.sav\n", argv[0]); return 1; } + auto s = read_save(argv[1]); return 0; } catch (std::exception &e) diff --git a/src/save_loader/save_loader.py b/src/save_loader/save_loader.py new file mode 100644 index 0000000..ad25095 --- /dev/null +++ b/src/save_loader/save_loader.py @@ -0,0 +1,23 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- + +import argparse +import os +import subprocess + +def main(): + parser = argparse.ArgumentParser(description='Batch models converter') + parser.add_argument('--dir', dest='dir', help='path to directory with models') + pargs = parser.parse_args() + + if pargs.dir: + run(pargs.dir) + +def run(dir): + for root, subdirs, files in os.walk(dir): + for file in files: + p = subprocess.Popen(['save_loader.exe', os.path.join(root, file)]) + p.communicate() + +if __name__ == '__main__': + main() diff --git a/src/script2txt/script.h b/src/script2txt/script.h index b4110af..bd74745 100644 --- a/src/script2txt/script.h +++ b/src/script2txt/script.h @@ -36,7 +36,7 @@ struct script // std::vector lines; - void load(buffer &b) + void load(const buffer &b) { READ(b, file_size); READ(b, unk0);