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);
}
}