From fb6aa75845ff3019e32fbc736c98495f5bda4b0b Mon Sep 17 00:00:00 2001 From: lzwdgc Date: Mon, 29 Jun 2015 18:50:30 +0300 Subject: [PATCH] Add common library with some helpers. --- .gitmodules | 2 +- CMakeLists.txt | 2 + dep/dbmgr | 2 +- src/CMakeLists.txt | 8 +- src/common/CMakeLists.txt | 2 + src/common/common.cpp | 127 ++++++++++++++++++++++ src/common/common.h | 55 ++++++++++ src/db_extractor/db.cpp | 90 ++++++++-------- src/db_extractor/db.h | 43 ++------ src/db_extractor/db_extractor.cpp | 50 +++------ src/mod_converter/mod_converter.cpp | 59 ++++------ src/mod_converter/model.cpp | 162 +++++++++++++--------------- src/mod_converter/model.h | 59 ++-------- src/obj_extractor/obj_extractor.cpp | 47 +++++--- src/obj_extractor/objects.cpp | 16 +-- src/obj_extractor/objects.h | 45 ++++---- src/obj_extractor/other.h | 98 ++++++++--------- 17 files changed, 483 insertions(+), 384 deletions(-) create mode 100644 src/common/CMakeLists.txt create mode 100644 src/common/common.cpp create mode 100644 src/common/common.h diff --git a/.gitmodules b/.gitmodules index 8c64a62..fde7751 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "dep/dbmgr"] path = dep/dbmgr - url = https://github.com/aimrebirth/DatabaseManager.git + url = git@github.com:aimrebirth/DatabaseManager.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 7609fff..e1da9f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,8 @@ endif(MSVC) include_directories(dep/dbmgr/include) add_subdirectory(dep/dbmgr) +set_target_properties(sqlite3 PROPERTIES FOLDER Extern) +set_target_properties(DatabaseManager PROPERTIES FOLDER Extern) add_custom_target(version ALL COMMAND git rev-list HEAD --count > ${CMAKE_CURRENT_BINARY_DIR}/version.h_ diff --git a/dep/dbmgr b/dep/dbmgr index 8fbdd4a..f6aae55 160000 --- a/dep/dbmgr +++ b/dep/dbmgr @@ -1 +1 @@ -Subproject commit 8fbdd4aba7438c7d3eace1308476597460d0aeed +Subproject commit f6aae55f91ac07cbdd286e96fb9cc5e278a4a6c5 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7a9cabd..7dbf224 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,12 +1,15 @@ +include_directories(common) + file(GLOB unpaker_src "unpaker/*") add_executable(unpaker ${unpaker_src}) file(GLOB db_extractor_src "db_extractor/*") add_executable(db_extractor ${db_extractor_src}) +target_link_libraries(db_extractor common) file(GLOB obj_extractor_src "obj_extractor/*") add_executable(obj_extractor ${obj_extractor_src}) -target_link_libraries(obj_extractor DatabaseManager) +target_link_libraries(obj_extractor DatabaseManager common) file(GLOB script2txt_src "script2txt/*") add_executable(script2txt ${script2txt_src}) @@ -16,3 +19,6 @@ add_executable(mmp_extractor ${mmp_extractor_src}) file(GLOB mod_converter_src "mod_converter/*") add_executable(mod_converter ${mod_converter_src}) +target_link_libraries(mod_converter common) + +add_subdirectory(common) \ No newline at end of file diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt new file mode 100644 index 0000000..4fb3e61 --- /dev/null +++ b/src/common/CMakeLists.txt @@ -0,0 +1,2 @@ +file(GLOB common_src "*.h" "*.cpp") +add_library(common ${common_src}) \ No newline at end of file diff --git a/src/common/common.cpp b/src/common/common.cpp new file mode 100644 index 0000000..9cbeb9a --- /dev/null +++ b/src/common/common.cpp @@ -0,0 +1,127 @@ +/* + * AIM tools + * Copyright (C) 2015 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 "common.h" + +#include + +const int build_version = +#include +; + +std::string version() +{ + using namespace std; + + string s; + s = to_string(0) + "." + + to_string(1) + "." + + to_string(0) + "." + + to_string(build_version); + return s; +} + +std::vector readFile(const std::string &fn) +{ + FILE *f = fopen(fn.c_str(), "rb"); + if (!f) + throw std::runtime_error("Cannot open file " + fn); + fseek(f, 0, SEEK_END); + auto sz = ftell(f); + fseek(f, 0, SEEK_SET); + std::vector buf(sz); + fread(buf.data(), 1, sz, f); + fclose(f); + return buf; +} + +buffer::buffer() +{ +} + +buffer::buffer(const std::vector &buf, uint32_t data_offset) + : buf(new std::vector(buf)), data_offset(data_offset) +{ + skip(0); + size = buf.size(); +} + +buffer::buffer(buffer &rhs, uint32_t size) + : buf(rhs.buf) +{ + index = rhs.index; + data_offset = rhs.data_offset; + ptr = rhs.ptr; + this->size = index + size; + rhs.skip(size); +} + +buffer::buffer(buffer &rhs, uint32_t size, uint32_t offset) + : buf(rhs.buf) +{ + index = offset; + data_offset = offset; + ptr = (uint8_t *)buf->data() + index; + this->size = index + size; +} + +uint32_t buffer::read(void *dst, uint32_t size, bool nothrow) +{ + if (!buf) + throw std::logic_error("buffer: not initialized"); + if (index >= this->size) + { + if (nothrow) + return 0; + throw std::logic_error("buffer: out of range"); + } + if (index + size > this->size) + size = this->size - index; + memcpy(dst, buf->data() + index, size); + skip(size); + return size; +} + +void buffer::skip(int n) +{ + if (!buf) + throw std::logic_error("buffer: not initialized"); + index += n; + data_offset += n; + ptr = (uint8_t *)buf->data() + index; +} + +bool buffer::check(int index) const +{ + return this->index == index; +} + +bool buffer::eof() const +{ + return check(this->size); +} + +uint32_t buffer::getIndex() const +{ + return index; +} + +uint32_t buffer::getSize() const +{ + return this->size; +} diff --git a/src/common/common.h b/src/common/common.h new file mode 100644 index 0000000..4545639 --- /dev/null +++ b/src/common/common.h @@ -0,0 +1,55 @@ +/* + * AIM tools + * Copyright (C) 2015 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 + +#define READ(b, var) b.read(&var, sizeof(var)) +#define READ_NOTHROW(b, var) b.read(&var, sizeof(var), true) +#define READ_N(b, var, sz) b.read(&var, sz) + +std::string version(); +std::vector readFile(const std::string &fn); + +class buffer +{ +public: + buffer(); + 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); + + uint32_t read(void *dst, uint32_t size, bool nothrow = false); + void skip(int n); + bool eof() const; + bool check(int index) const; + + uint32_t getIndex() const; + uint32_t getSize() const; + +private: + std::shared_ptr> buf; + uint32_t index = 0; + uint8_t *ptr = 0; + uint32_t data_offset = 0; + uint32_t size = 0; +}; diff --git a/src/db_extractor/db.cpp b/src/db_extractor/db.cpp index 820520f..c3f0444 100644 --- a/src/db_extractor/db.cpp +++ b/src/db_extractor/db.cpp @@ -18,9 +18,7 @@ #include "db.h" -#define FREAD(var) fread(&var, 1, sizeof(var), f) -#define SREAD(var) s.read(&var, sizeof(var)) -#define SREAD_N(var, sz) s.read(&var, sz) +#include string getSqlType(uint32_t ft) { @@ -38,37 +36,37 @@ string getSqlType(uint32_t ft) return ""; } -void table::load(FILE *f) +void table::load(buffer &b) { - FREAD(id); - FREAD(name); - FREAD(unk1); - FREAD(unk2); - FREAD(unk3); - FREAD(unk4); + READ(b, id); + READ(b, name); + READ(b, unk1); + READ(b, unk2); + READ(b, unk3); + READ(b, unk4); } -void field::load(FILE *f) +void field::load(buffer &b) { - FREAD(table_id); - FREAD(id); - FREAD(name); - FREAD(unk1); - FREAD(unk2); - FREAD(unk3); - FREAD(type); + READ(b, table_id); + READ(b, id); + READ(b, name); + READ(b, unk1); + READ(b, unk2); + READ(b, unk3); + READ(b, type); } -void tab::load(FILE *f) +void tab::load(buffer &b) { - FREAD(number_of_tables); - FREAD(number_of_fields); + READ(b, number_of_tables); + READ(b, number_of_fields); auto n = number_of_tables; while (n--) { table t; - t.load(f); + t.load(b); tables[t.id] = t; } @@ -76,39 +74,35 @@ void tab::load(FILE *f) while (n--) { field t; - t.load(f); + t.load(b); fields[t.id] = t; } } -void value::load_index(FILE *f) +void value::load_index(buffer &b) { - FREAD(table_id); - FREAD(name); - FREAD(unk1); - FREAD(unk2); - FREAD(unk3); - FREAD(offset); - FREAD(data_size); - buf.resize(data_size); + READ(b, table_id); + READ(b, name); + READ(b, unk1); + READ(b, unk2); + READ(b, unk3); + READ(b, offset); + READ(b, data_size); } -void value::load_data(FILE *f) +void value::load_data(buffer &b) { - fseek(f, offset, SEEK_SET); - fread(buf.data(), buf.size(), 1, f); + data = buffer(b, data_size, offset); } void value::extract_fields(const tab &tab) { - s_file s(buf); - - while (1) + while (!data.eof()) { field_value fv; - if (SREAD(fv.field_id) == 0) + if (READ_NOTHROW(data, fv.field_id) == 0) break; - SREAD(fv.size); + READ(data, fv.size); auto i = tab.fields.find(fv.field_id); if (i == tab.fields.end()) continue; @@ -116,17 +110,17 @@ void value::extract_fields(const tab &tab) { case T_STRING: fv.s.resize(fv.size); - SREAD_N(fv.s[0], fv.s.size()); + READ_N(data, fv.s[0], fv.s.size()); break; case T_INTEGER: - SREAD(fv.i); + READ(data, fv.i); if (fv.size > sizeof(fv.i)) - s.skip(fv.size - sizeof(fv.i)); + data.skip(fv.size - sizeof(fv.i)); break; case T_FLOAT: - SREAD(fv.f); + READ(data, fv.f); if (fv.size > sizeof(fv.i)) - s.skip(fv.size - sizeof(fv.i)); + data.skip(fv.size - sizeof(fv.i)); break; default: assert(false); @@ -135,15 +129,15 @@ void value::extract_fields(const tab &tab) } } -void db::load(FILE *f) +void db::load(buffer &b) { - FREAD(number_of_values); + READ(b, number_of_values); auto n = number_of_values; while (n--) { value t; - t.load_index(f); + t.load_index(b); values.push_back(t); } } \ No newline at end of file diff --git a/src/db_extractor/db.h b/src/db_extractor/db.h index 7e4e70d..7005532 100644 --- a/src/db_extractor/db.h +++ b/src/db_extractor/db.h @@ -24,6 +24,8 @@ #include #include +#include + using namespace std; enum FieldType @@ -43,7 +45,7 @@ struct table uint32_t unk3; uint32_t unk4; - void load(FILE *f); + void load(buffer &b); }; struct field @@ -56,7 +58,7 @@ struct field uint32_t unk3; uint32_t type; - void load(FILE *f); + void load(buffer &b); }; struct tab @@ -67,7 +69,7 @@ struct tab map tables; map fields; - void load(FILE *f); + void load(buffer &b); }; struct field_value @@ -82,30 +84,6 @@ struct field_value struct value { - struct s_file - { - uint32_t index = 0; - const vector buf; - - s_file(const vector &buf) - : buf(buf) - {} - uint32_t read(void *dst, uint32_t size) - { - if (index >= buf.size()) - return 0; - if (index + size > buf.size()) - size = buf.size() - index; - memcpy(dst, buf.data() + index, size); - index += size; - return size; - } - void skip(int n) - { - index += n; - } - }; - uint32_t table_id; char name[0x14]; uint32_t unk1; @@ -113,17 +91,14 @@ struct value uint32_t unk3; uint32_t offset; uint32_t data_size; - - // - vector buf; - // + buffer data; uint32_t number_of_fields; vector fields; void extract_fields(const tab &tab); - void load_index(FILE *f); - void load_data(FILE *f); + void load_index(buffer &b); + void load_data(buffer &b); }; struct db @@ -133,5 +108,5 @@ struct db tab t; vector values; - void load(FILE *f); + void load(buffer &b); }; \ No newline at end of file diff --git a/src/db_extractor/db_extractor.cpp b/src/db_extractor/db_extractor.cpp index 454a375..89ad9f2 100644 --- a/src/db_extractor/db_extractor.cpp +++ b/src/db_extractor/db_extractor.cpp @@ -22,42 +22,15 @@ #include -void open_tab(string path, tab &tab) -{ - path += ".tab"; - FILE *f = fopen(path.c_str(), "rb"); - if (!f) - return; - tab.load(f); - fclose(f); -} - -void open_index(string path, db &index) -{ - path += ".ind"; - FILE *f = fopen(path.c_str(), "rb"); - if (!f) - return; - index.load(f); - fclose(f); -} - -void open_data(string path, db &index) -{ - path += ".dat"; - FILE *f = fopen(path.c_str(), "rb"); - if (!f) - return; - for (auto &v : index.values) - v.load_data(f); - fclose(f); -} +#include void open_db(string path, db &db) { - open_tab(path, db.t); - open_index(path, db); - open_data(path, db); + db.t.load(buffer(readFile(path + ".tab"))); + db.load(buffer(readFile(path + ".ind"))); + buffer b(readFile(path + ".dat")); + for (auto &v : db.values) + v.load_data(b); for (auto &v : db.values) v.extract_fields(db.t); } @@ -179,6 +152,7 @@ void create_sql(string path, const db &db) } int main(int argc, char *argv[]) +try { if (argc != 2) { @@ -190,4 +164,14 @@ int main(int argc, char *argv[]) open_db(path, db); create_sql(path, db); return 0; +} +catch (std::exception &e) +{ + printf("error: %s\n", e.what()); + return 1; +} +catch (...) +{ + printf("error: unknown exception\n"); + return 1; } \ No newline at end of file diff --git a/src/mod_converter/mod_converter.cpp b/src/mod_converter/mod_converter.cpp index d8ead6c..a48ff1b 100644 --- a/src/mod_converter/mod_converter.cpp +++ b/src/mod_converter/mod_converter.cpp @@ -21,58 +21,31 @@ #include #include -using namespace std; - +#include #include "model.h" -const int build_version = -#include -; - -std::string version() -{ - string s; - s = to_string(0) + "." + - to_string(1) + "." + - to_string(0) + "." + - to_string(build_version); - return s; -} +using namespace std; void convert_model(string fn) { + printf("%s\n", fn.c_str()); + + buffer b(readFile(fn)); model m; - FILE *f = fopen(fn.c_str(), "rb"); - if (!f) - return; - try - { - m.load(f); + m.load(b); - auto p = ftell(f); - fseek(f, 0, SEEK_END); - auto end = ftell(f); - fclose(f); - - if (p != end) - { - stringstream ss; - ss << hex << p << " != " << hex << end; - throw std::logic_error(ss.str()); - } - } - catch (std::exception &e) + if (!b.eof()) { - printf("error: %s\n", fn.c_str()); - printf("%s\n", e.what()); - fclose(f); - return; + stringstream ss; + ss << hex << b.getIndex() << " != " << hex << b.getSize(); + throw std::logic_error(ss.str()); } m.writeObj(fn + ".obj"); } int main(int argc, char *argv[]) +try { #ifdef NDEBUG if (argc != 2) @@ -98,4 +71,14 @@ int main(int argc, char *argv[]) convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_GL_M1_A_ATTACKER_DAMAGED"); #endif return 0; +} +catch (std::exception &e) +{ + printf("error: %s\n", e.what()); + return 1; +} +catch (...) +{ + printf("error: unknown exception\n"); + return 1; } \ No newline at end of file diff --git a/src/mod_converter/model.cpp b/src/mod_converter/model.cpp index 6c38bd6..2624100 100644 --- a/src/mod_converter/model.cpp +++ b/src/mod_converter/model.cpp @@ -20,31 +20,28 @@ #include #include -#include + +#include using namespace std; std::string version(); -#define FREAD(var) fread(&var, 1, sizeof(var), f) -#define SREAD(var) s.read(&var, sizeof(var)) -#define SREAD_N(var, sz) s.read(&var, sz) - -void vertex::load(s_file &s, uint32_t flags) +void vertex::load(buffer &b, uint32_t flags) { - SREAD(vX); - SREAD(vZ); - SREAD(vY); + READ(b, vX); + READ(b, vZ); + READ(b, vY); if (flags & F_WIND) - SREAD(wind); + READ(b, wind); - SREAD(nX); - SREAD(nZ); - SREAD(nY); + READ(b, nX); + READ(b, nZ); + READ(b, nY); - SREAD(t1); - SREAD(t2); + READ(b, t1); + READ(b, t2); } std::string vertex::printVertex() const @@ -68,50 +65,46 @@ std::string vertex::printTex() const return s; } -void fragment::load(FILE *f) +void fragment::load(buffer &b) { - FREAD(type); - FREAD(name0); - FREAD(name1); - FREAD(name2); - FREAD(name3); - FREAD(name4); - FREAD(unk0); - FREAD(unk1); - FREAD(unk2); - FREAD(unk3); - FREAD(size); - FREAD(unk4); - data.resize(size); - data_offset = ftell(f); - fread(data.data(), 1, size, f); -} + // header + READ(b, type); + READ(b, name0); + READ(b, name1); + READ(b, name2); + READ(b, name3); + READ(b, name4); + READ(b, unk0); + READ(b, unk1); + READ(b, unk2); + READ(b, unk3); + READ(b, size); + READ(b, unk4); -bool fragment::extract() -{ - s_file s(data, data_offset); - - SREAD(n_segments); + // data + buffer data(b, size); + READ(data, n_segments); segments.resize(n_segments); - SREAD(header); - SREAD(triangles_mult_7); - SREAD(unk10); - SREAD(flags); - SREAD(n_vertex); + READ(data, header); + READ(data, triangles_mult_7); + READ(data, unk10); + READ(data, flags); + READ(data, n_vertex); vertices.resize(n_vertex); - SREAD(n_triangles); + READ(data, n_triangles); if (triangles_mult_7) n_triangles *= 7; triangles.resize(n_triangles); for (auto &v : vertices) - v.load(s, flags); + v.load(data, flags); for (auto &t : triangles) - SREAD(t); + READ(data, t); + // segments for (auto &seg : segments) { uint32_t type; - SREAD(type); + READ(data, type); switch (type) { case 1: @@ -127,94 +120,91 @@ bool fragment::extract() throw std::logic_error("unknown segment type " + std::to_string(type)); } seg->type = type; - seg->extract(s); + seg->load(data); } - return s.eof(); + if (!data.eof()) + throw std::logic_error("extraction error: fragment #" + std::string(name0)); } -void segment1::extract(s_file &s) +void segment1::load(buffer &b) { - SREAD(name); - SREAD(unk0); + READ(b, name); + READ(b, unk0); triangles.resize(unk0[0][0]); unk1.resize(unk0[0][0]); for (int i = 0; i < 2; i++) { for (auto &t : triangles) - SREAD(t); + READ(b, t); for (auto &unk: unk1) - SREAD(unk); + READ(b, unk); } } -void segment2::extract(s_file &s) +void segment2::load(buffer &b) { - SREAD(name); - SREAD(unk0); + READ(b, name); + READ(b, unk0); triangles.resize(unk0[0][0]); unk1.resize(unk0[0][0]); unk1_1.resize(unk0[0][0]); for (auto &t : triangles) - SREAD(t); + READ(b, t); for (auto &unk : unk1) - SREAD(unk); + READ(b, unk); for (auto &unk : unk1_1) - SREAD(unk); - while (!s.eof()) + READ(b, unk); + while (!b.eof()) { repeater r; - r.extract(s); + r.load(b); unk2.push_back(r); } } -void segment2::repeater::extract(s_file &s) +void segment2::repeater::load(buffer &b) { - SREAD(unk2); + READ(b, unk2); triangles2.resize(unk2); - SREAD(unk8); - SREAD(unk3); + READ(b, unk8); + READ(b, unk3); for (auto &t : triangles2) - SREAD(t); - SREAD(unk6); - SREAD(flags); - SREAD(n_vertex); + READ(b, t); + READ(b, unk6); + READ(b, flags); + READ(b, n_vertex); vertices.resize(n_vertex); - SREAD(n_triangles); + READ(b, n_triangles); triangles.resize(n_triangles); for (auto &v : vertices) - v.load(s, flags); + v.load(b, flags); for (auto &t : triangles) - SREAD(t); + READ(b, t); } -void segment6::extract(s_file &s) +void segment6::load(buffer &b) { - SREAD(name); - SREAD(unk0); + READ(b, name); + READ(b, unk0); triangles.resize(unk0[0][0]); for (int i = 0; i < 1; i++) { for (auto &t : triangles) - SREAD(t); + READ(b, t); char unk1[0x30]; // some 6 floats for (int i = 0; i < unk0[0][0]; i++) - SREAD(unk1); + READ(b, unk1); } } -void model::load(FILE *f) +void model::load(buffer &b) { - FREAD(n_fragments); - FREAD(header); + READ(b, n_fragments); + READ(b, header); fragments.resize(n_fragments); - for (int i = 0; i < fragments.size(); i++) - { - fragments[i].load(f); - if (!fragments[i].extract()) - throw std::logic_error("extraction error: fragment #" + std::to_string(i)); - } + for (auto &f : fragments) + f.load(b); } void model::writeObj(std::string fn) diff --git a/src/mod_converter/model.h b/src/mod_converter/model.h index f920794..3937f2f 100644 --- a/src/mod_converter/model.h +++ b/src/mod_converter/model.h @@ -22,37 +22,7 @@ #include #include -struct s_file -{ - uint32_t index = 0; - const std::vector &buf; - uint8_t *ptr; - uint32_t data_offset; - - s_file(const std::vector &buf, uint32_t data_offset) - : buf(buf), data_offset(data_offset) - {} - uint32_t read(void *dst, uint32_t size) - { - if (index >= buf.size()) - throw std::logic_error("s_file: out of range"); - if (index + size > buf.size()) - size = buf.size() - index; - memcpy(dst, buf.data() + index, size); - skip(size); - return size; - } - void skip(int n) - { - index += n; - data_offset += n; - ptr = (uint8_t *)buf.data() + index; - } - bool eof() const - { - return index == buf.size(); - } -}; +class buffer; enum { @@ -74,7 +44,7 @@ struct vertex float t1; float t2; - void load(s_file &s, uint32_t flags); + void load(buffer &b, uint32_t flags); std::string printVertex() const; std::string printNormal() const; @@ -97,7 +67,7 @@ struct segment { uint32_t type; - virtual void extract(s_file &s) = 0; + virtual void load(buffer &b) = 0; }; struct segment1 : public segment @@ -107,7 +77,7 @@ struct segment1 : public segment std::vector triangles; std::vector unk1; - virtual void extract(s_file &s); + virtual void load(buffer &b); }; struct segment2 : public segment @@ -125,7 +95,7 @@ struct segment2 : public segment std::vector vertices; std::vector triangles; - virtual void extract(s_file &s); + virtual void load(buffer &b); }; char name[0xC]; @@ -135,17 +105,17 @@ struct segment2 : public segment std::vector unk1_1; std::vector unk2; - virtual void extract(s_file &s); + virtual void load(buffer &b); }; struct segment6 : public segment1 { - virtual void extract(s_file &s); + virtual void load(buffer &b); }; struct fragment { - // main header + // header uint32_t type; char name0[0x20]; char name1[0x20]; @@ -159,10 +129,7 @@ struct fragment uint32_t size; uint32_t unk4[10]; - // data buffer - std::vector data; - - // main data + // data uint32_t n_segments; char header[0x68]; uint32_t triangles_mult_7; @@ -176,11 +143,7 @@ struct fragment // segments std::vector segments; - // internal vars - uint32_t data_offset; - - void load(FILE *f); - bool extract(); + void load(buffer &b); }; struct model @@ -189,6 +152,6 @@ struct model char header[0x40]; std::vector fragments; - void load(FILE *f); + void load(buffer &b); void writeObj(std::string fn); }; diff --git a/src/obj_extractor/obj_extractor.cpp b/src/obj_extractor/obj_extractor.cpp index 0300427..6e1e7af 100644 --- a/src/obj_extractor/obj_extractor.cpp +++ b/src/obj_extractor/obj_extractor.cpp @@ -29,6 +29,8 @@ #include +#include + using namespace std; struct storage @@ -39,27 +41,31 @@ struct storage MapGoods mg; MapMusic mm; MapSounds ms; + + void load(buffer &b) + { + objects.load(b); + mgs.load(b); + if (b.eof()) // custom maps + return; + mg.load(b); + mm.load(b); + ms.load(b); + + if (!b.eof()) + { + stringstream ss; + ss << hex << b.getIndex() << " != " << hex << b.getSize(); + throw std::logic_error(ss.str()); + } + } }; storage read_mmo(string fn) { storage s; s.name = fn; - FILE *f = fopen(fn.c_str(), "rb"); - if (!f) - return s; - s.objects.load(f); - s.mgs.load(f); - if (feof(f)) - { - // custom maps? - fclose(f); - return s; - } - s.mg.load(f); - s.mm.load(f); - s.ms.load(f); - fclose(f); + s.load(buffer(readFile(fn))); return s; } @@ -197,6 +203,7 @@ void write_mmo(string db, const storage &s) } int main(int argc, char *argv[]) +try { if (argc != 3) { @@ -206,4 +213,14 @@ int main(int argc, char *argv[]) storage s = read_mmo(argv[2]); write_mmo(argv[1], s); return 0; +} +catch (std::exception &e) +{ + printf("error: %s\n", e.what()); + return 1; +} +catch (...) +{ + printf("error: unknown exception\n"); + return 1; } \ No newline at end of file diff --git a/src/obj_extractor/objects.cpp b/src/obj_extractor/objects.cpp index 64af13f..b49d853 100644 --- a/src/obj_extractor/objects.cpp +++ b/src/obj_extractor/objects.cpp @@ -18,10 +18,10 @@ #include "objects.h" -Segment *Segment::create_segment(FILE *f) +Segment *Segment::create_segment(buffer &b) { SegmentType segment_type; - FREAD(segment_type); + READ(b, segment_type); Segment *segment = 0; switch (segment_type) @@ -78,22 +78,22 @@ Segment *Segment::create_segment(FILE *f) if (segment) { segment->segment_type = segment_type; - FREAD(segment->segment_len); - FREAD(segment->n_objects); + READ(b, segment->segment_len); + READ(b, segment->n_objects); } return segment; } -void Objects::load(FILE *f) +void Objects::load(buffer &b) { - FREAD(n_segments); + READ(b, n_segments); for (int s = 0; s < n_segments; s++) { - auto seg = Segment::create_segment(f); + auto seg = Segment::create_segment(b); if (!seg) break; - seg->load(f); + seg->load(b); segments.push_back(seg); } } diff --git a/src/obj_extractor/objects.h b/src/obj_extractor/objects.h index d9c88b9..8ace369 100644 --- a/src/obj_extractor/objects.h +++ b/src/obj_extractor/objects.h @@ -24,8 +24,7 @@ #include #include -#define FREAD(var) fread(&var, 1, sizeof(var), f) -#define FREAD_N(var, n) fread(&var, 1, n, f) +#include using namespace std; @@ -71,8 +70,8 @@ struct Segment uint32_t n_objects; virtual ~Segment(){} - static Segment *create_segment(FILE *f); - virtual void load(FILE *f) = 0; + static Segment *create_segment(buffer &b); + virtual void load(buffer &b) = 0; }; template @@ -80,12 +79,12 @@ struct SegmentObjects : public Segment { vector objects; - virtual void load(FILE *f) + virtual void load(buffer &b) { for (int i = 0; i < n_objects; i++) { T r; - r.load(f); + r.load(b); objects.push_back(r); } } @@ -104,10 +103,10 @@ struct Common Vector4 m_rotate_z[3]; Vector4 position; - void load(FILE *f) + void load(buffer &b) { - FREAD(m_rotate_z); - FREAD(position); + READ(b, m_rotate_z); + READ(b, position); } }; @@ -116,12 +115,12 @@ struct MapObject : public Common char name1[0x20]; char name2[0x20]; - void load(FILE *f) + void load(buffer &b) { - Common::load(f); + Common::load(b); - FREAD(name1); - FREAD(name2); + READ(b, name1); + READ(b, name2); } }; @@ -130,14 +129,14 @@ struct MapObjectWithArray : public MapObject uint32_t len; vector unk7; - void load(FILE *f) + void load(buffer &b) { - MapObject::load(f); + MapObject::load(b); - FREAD(len); + READ(b, len); unk7.resize(len); for (int i = 0; i < len; i++) - FREAD(unk7[i]); + READ(b, unk7[i]); } }; @@ -146,12 +145,12 @@ struct Sound : public Common uint32_t unk1[11]; char name1[0x14]; - void load(FILE *f) + void load(buffer &b) { - Common::load(f); + Common::load(b); - FREAD(unk1); - FREAD(name1); + READ(b, unk1); + READ(b, name1); } }; @@ -172,7 +171,7 @@ KNOWN_OBJECT(Anomaly); KNOWN_OBJECT(Boundary); #define UNKNOWN_OBJECT(name) \ - struct name : public MapObject { void load(FILE *f){ int pos = ftell(f); assert(false); } } + struct name : public MapObject { void load(buffer &b){ int pos = b.getIndex(); assert(false); } } UNKNOWN_OBJECT(Building); UNKNOWN_OBJECT(Goods); @@ -183,5 +182,5 @@ struct Objects uint32_t n_segments; vector segments; - void load(FILE *f); + void load(buffer &b); }; diff --git a/src/obj_extractor/other.h b/src/obj_extractor/other.h index 200f55f..a21aae5 100644 --- a/src/obj_extractor/other.h +++ b/src/obj_extractor/other.h @@ -24,6 +24,8 @@ #include #include +#include + using namespace std; struct MechGroup @@ -47,35 +49,35 @@ struct MechGroup vector configs; char unk100; - void load(FILE *f) + void load(buffer &b) { - FREAD(unk1); - FREAD(unk2); - FREAD(type1); - FREAD(len1); - FREAD(name1); + READ(b, unk1); + READ(b, unk2); + READ(b, type1); + READ(b, len1); + READ(b, name1); if (type1 == 3 || type1 == 4) { - FREAD(unk30); + READ(b, unk30); } else if (type1 == 2) { - FREAD(len); + READ(b, len); unk11.resize(len); for (int i = 0; i < len; i++) - FREAD(unk11[i]); + READ(b, unk11[i]); } else if (type1 == 1 || type1 == 0) { - FREAD(unk20); - FREAD(unk21); + READ(b, unk20); + READ(b, unk21); } else assert(false); configs.resize(len1, string(0x20, 0)); for (int i = 0; i < len1; i++) - FREAD_N(configs[i][0], 0x20); - FREAD(unk100); + READ_N(b, configs[i][0], 0x20); + READ(b, unk100); } }; @@ -86,15 +88,15 @@ struct MechGroups vector mgs; - void load(FILE *f) + void load(buffer &b) { - FREAD(n); - FREAD(prefix); + READ(b, n); + READ(b, prefix); for (int s = 0; s < n; s++) { MechGroup mg; - mg.load(f); + mg.load(b); mgs.push_back(mg); } } @@ -107,12 +109,12 @@ struct Good float price; float unk2[10]; - void load(FILE *f) + void load(buffer &b) { - FREAD(name); - FREAD(unk1); - FREAD(price); - FREAD(unk2); + READ(b, name); + READ(b, unk1); + READ(b, price); + READ(b, unk2); } }; @@ -123,15 +125,15 @@ struct BuildingGoods vector goods; - void load(FILE *f) + void load(buffer &b) { - FREAD(name); - FREAD(n); + READ(b, name); + READ(b, n); for (int i = 0; i < n; i++) { Good g; - g.load(f); + g.load(b); goods.push_back(g); } } @@ -146,17 +148,17 @@ struct MapGoods vector bgs; - void load(FILE *f) + void load(buffer &b) { - FREAD(unk1); - FREAD(unk2); - FREAD(unk3); - FREAD(n); + READ(b, unk1); + READ(b, unk2); + READ(b, unk3); + READ(b, n); for (int i = 0; i < n; i++) { BuildingGoods bg; - bg.load(f); + bg.load(b); bgs.push_back(bg); } } @@ -174,25 +176,25 @@ struct MapMusic uint32_t n2; vector names2; - void load(FILE *f) + void load(buffer &b) { - FREAD(unk1); - FREAD(name1); - FREAD(name2); + READ(b, unk1); + READ(b, name1); + READ(b, name2); - FREAD(n1); + READ(b, n1); for (int i = 0; i < n1; i++) { char name[0x20]; - FREAD(name); + READ(b, name); names1.push_back(name); } - FREAD(n2); + READ(b, n2); for (int i = 0; i < n2; i++) { char name[0x20]; - FREAD(name); + READ(b, name); names2.push_back(name); } } @@ -205,12 +207,12 @@ struct MapSound uint32_t unk2; float unk3[4]; - void load(FILE *f) + void load(buffer &b) { - FREAD(name); - FREAD(unk1); - FREAD(unk2); - FREAD(unk3); + READ(b, name); + READ(b, unk1); + READ(b, unk2); + READ(b, unk3); } }; @@ -219,13 +221,13 @@ struct MapSounds uint32_t n; vector sounds; - void load(FILE *f) + void load(buffer &b) { - FREAD(n); + READ(b, n); for (int i = 0; i < n; i++) { MapSound s; - s.load(f); + s.load(b); sounds.push_back(s); } }