diff --git a/src/mmp_extractor/bmp.h b/src/common/bmp.h
similarity index 100%
rename from src/mmp_extractor/bmp.h
rename to src/common/bmp.h
diff --git a/src/common/common.cpp b/src/common/buffer.cpp
similarity index 99%
rename from src/common/common.cpp
rename to src/common/buffer.cpp
index 62987f1..05aeefc 100644
--- a/src/common/common.cpp
+++ b/src/common/buffer.cpp
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-#include "common.h"
+#include "buffer.h"
#include
diff --git a/src/common/common.h b/src/common/buffer.h
similarity index 100%
rename from src/common/common.h
rename to src/common/buffer.h
diff --git a/src/common/color.h b/src/common/color.h
new file mode 100644
index 0000000..d73d2e7
--- /dev/null
+++ b/src/common/color.h
@@ -0,0 +1,62 @@
+/*
+ * 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
+
+typedef uint16_t color_rgb565;
+
+struct color
+{
+ union
+ {
+ struct
+ {
+ uint8_t b;
+ uint8_t g;
+ uint8_t r;
+ uint8_t a;
+ };
+ uint8_t byte[4];
+ uint32_t data;
+ };
+
+ color() {}
+ color(uint8_t b, uint8_t g, uint8_t r, uint8_t a)
+ : b(b), g(g), r(r), a(a)
+ {}
+ color(const color_rgb565 &c)
+ {
+ static uint8_t Table5[] = {
+ 0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99, 107, 115, 123, 132,
+ 140, 148, 156, 165, 173, 181, 189, 197, 206, 214, 222, 230, 239, 247, 255 };
+ static uint8_t Table6[] = {
+ 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69,
+ 73, 77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138,
+ 142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 194, 198,
+ 202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255 };
+
+ b = Table5[c & 0x1F];
+ g = Table6[(c >> 5) & 0x3F];
+ r = Table5[(c >> 11) & 0x1F];
+ }
+
+ operator uint32_t() const
+ {
+ return data;
+ }
+};
diff --git a/src/common/dxt5.h b/src/common/dxt5.h
new file mode 100644
index 0000000..12cd581
--- /dev/null
+++ b/src/common/dxt5.h
@@ -0,0 +1,164 @@
+/*
+ * 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
+#include
+#include
+
+#include "buffer.h"
+#include "color.h"
+#include "mat.h"
+
+struct dxt5_block
+{
+ union
+ {
+ uint64_t alpha_part;
+ uint8_t a[8];
+ };
+ union
+ {
+ uint64_t color_part;
+ uint16_t c[4];
+ };
+
+ //
+ uint8_t alpha_table[8];
+ color color_table[4];
+ union
+ {
+ color pixels[16];
+ color pixel_mat[4][4];
+ };
+
+ dxt5_block() {}
+ void load(buffer &b)
+ {
+ READ(b, alpha_part);
+ READ(b, color_part);
+ }
+ void unpack()
+ {
+ // alpha
+ auto &a = alpha_table;
+ a[0] = this->a[0];
+ a[1] = this->a[1];
+ if (a[0] > a[1])
+ {
+ a[2] = double(6 * a[0] + 1 * a[1]) / 7.0;
+ a[3] = double(5 * a[0] + 2 * a[1]) / 7.0;
+ a[4] = double(4 * a[0] + 3 * a[1]) / 7.0;
+ a[5] = double(3 * a[0] + 4 * a[1]) / 7.0;
+ a[6] = double(2 * a[0] + 5 * a[1]) / 7.0;
+ a[7] = double(1 * a[0] + 6 * a[1]) / 7.0;
+ }
+ else
+ {
+ a[2] = double(4 * a[0] + 1 * a[1]) / 5.0;
+ a[3] = double(3 * a[0] + 2 * a[1]) / 5.0;
+ a[4] = double(2 * a[0] + 3 * a[1]) / 5.0;
+ a[5] = double(1 * a[0] + 4 * a[1]) / 5.0;
+ a[6] = 0;
+ a[7] = 255;
+ }
+
+ // color
+ auto &c = color_table;
+ c[0] = color(this->c[0]);
+ c[1] = color(this->c[1]);
+ if (this->c[0] > this->c[1])
+ {
+ c[2] = interpolate(c[0], c[1], 2.f / 3.f);
+ c[3] = interpolate(c[0], c[1], 1.f / 3.f);
+ }
+ else
+ {
+ c[2] = interpolate(c[0], c[1], 1.f / 2.f);
+ c[3].data = 0;
+ }
+
+ // result
+ for (int p = 0; p < 16; p++)
+ {
+ pixels[p] = c[(color_part >> (32 + p * 2)) & 0b11];
+ pixels[p].a = a[(alpha_part >> (16 + p * 3)) & 0b111];
+ }
+ }
+ color interpolate(color c0, color c1, float m)
+ {
+ color r;
+ for (int i = 0; i < 4; i++)
+ r.byte[i] = c0.byte[i] * m + c1.byte[i] * (1 - m);
+ return r;
+ }
+};
+
+struct dxt5
+{
+ uint32_t width;
+ uint32_t height;
+ std::vector blocks;
+
+ void load(buffer &b)
+ {
+ READ(b, width);
+ READ(b, height);
+ load_blocks(b);
+ }
+ void load_blocks(buffer &b)
+ {
+ blocks.resize(width * height / 16);
+ for (auto &d : blocks)
+ {
+ d.load(b);
+ d.unpack();
+ }
+ }
+ mat unpack_mmm()
+ {
+ mat m(width, height);
+ auto big_xsegs = width / 64;
+ auto big_ysegs = height / 64;
+ for (int seg = 0; seg < blocks.size(); seg++)
+ {
+ auto &d = blocks[seg];
+ int big_seg = seg / 256;
+ auto big_xseg = big_seg % big_xsegs;
+ auto big_yseg = big_seg / big_xsegs;
+ auto xseg = seg % 16 + big_xseg * 16;
+ auto yseg = seg % 256 / 16 + big_yseg * 16;
+ for (int i = 0; i < 4; i++)
+ memcpy(&m(height - 1 - (yseg * 4 + i), xseg * 4), d.pixel_mat[i], 16);
+ }
+ return m;
+ }
+ mat unpack_tm()
+ {
+ mat m(width, height);
+ auto xsegs = width / 4;
+ for (int seg = 0; seg < blocks.size(); seg++)
+ {
+ auto &d = blocks[seg];
+ auto xseg = seg % xsegs;
+ auto yseg = seg / xsegs;
+ for (int i = 0; i < 4; i++)
+ memcpy(&m(height - 1 - (yseg * 4 + i), xseg * 4), d.pixel_mat[i], 16);
+ }
+ return m;
+ }
+};
diff --git a/src/common/mat.h b/src/common/mat.h
new file mode 100644
index 0000000..a555056
--- /dev/null
+++ b/src/common/mat.h
@@ -0,0 +1,95 @@
+/*
+* 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
+
+template
+class mat
+{
+public:
+ using type = T;
+
+public:
+ mat(int w = 0, int h = 0)
+ {
+ width = w < 0 ? 0 : w;
+ height = h < 0 ? 0 : h;
+ data.resize(width * height, T());
+ }
+
+ T &operator()(int row, int col)
+ {
+ assert(!(row >= height || col >= width || row < 0 || col < 0));
+ return data[row * width + col];
+ }
+ const T &operator()(int row, int col) const
+ {
+ return (*const_cast(this))(row, col);
+ }
+
+ void clean()
+ {
+ std::fill(data.begin(), data.end(), T());
+ }
+
+ int getWidth() const { return width; }
+ int getHeight() const { return height; }
+ int size() const { return width * height; }
+ int getPos(const T *const elem) const { return elem - &data[0]; }
+ const std::vector &getData() const { return data; }
+ std::vector &getData() { return data; }
+
+private:
+ std::vector data;
+ int width;
+ int height;
+};
+
+template
+void write_mat_bmp(const std::string &filename, const mat &m)
+{
+ FILE *f = fopen(filename.c_str(), "wb");
+ if (f == nullptr)
+ return;
+ BITMAPFILEHEADER h = { 0 };
+ h.bfType = 0x4D42;
+ h.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO) + m.size() * sizeof(T);
+ h.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO);
+ BITMAPINFO i = { 0 };
+ i.bmiHeader.biSize = sizeof(i.bmiHeader);
+ i.bmiHeader.biWidth = m.getWidth();
+ i.bmiHeader.biHeight = m.getHeight();
+ i.bmiHeader.biPlanes = 1;
+ i.bmiHeader.biBitCount = sizeof(T) * 8;
+ i.bmiHeader.biCompression = 0;
+ i.bmiHeader.biSizeImage = 0;
+ i.bmiHeader.biXPelsPerMeter = 0;
+ i.bmiHeader.biYPelsPerMeter = 0;
+ i.bmiHeader.biClrUsed = 0;
+ i.bmiHeader.biClrImportant = 0;
+ fwrite(&h, sizeof(BITMAPFILEHEADER), 1, f);
+ fwrite(&i, sizeof(BITMAPINFO), 1, f);
+ fwrite(&m(0, 0), m.size() * sizeof(T), 1, f);
+ fclose(f);
+}
diff --git a/src/db_extractor/db.cpp b/src/db_extractor/db.cpp
index 2f957cd..640d4ba 100644
--- a/src/db_extractor/db.cpp
+++ b/src/db_extractor/db.cpp
@@ -18,7 +18,7 @@
#include "db.h"
-#include
+#include
string getSqlType(FieldType type)
{
diff --git a/src/db_extractor/db.h b/src/db_extractor/db.h
index c1389e4..eb8584d 100644
--- a/src/db_extractor/db.h
+++ b/src/db_extractor/db.h
@@ -24,7 +24,7 @@
#include
#include
-#include
+#include
using namespace std;
diff --git a/src/db_extractor/db_extractor.cpp b/src/db_extractor/db_extractor.cpp
index 89cb881..0d4ef63 100644
--- a/src/db_extractor/db_extractor.cpp
+++ b/src/db_extractor/db_extractor.cpp
@@ -22,7 +22,7 @@
#include
-#include
+#include
void open_db(string path, db &db)
{
diff --git a/src/mmm_extractor/mmm.cpp b/src/mmm_extractor/mmm.cpp
deleted file mode 100644
index 2222cc1..0000000
--- a/src/mmm_extractor/mmm.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * AIM mmm_extractor
- * 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 "mmm.h"
-
-void mmm::load(buffer &b)
-{
- READ(b, unk1);
- READ(b, unk2);
- READ(b, width);
- READ(b, height);
- data.resize(width * height / 16);
- READ_N(b, data[0], data.size() * 16);
-}
\ No newline at end of file
diff --git a/src/mmm_extractor/mmm.h b/src/mmm_extractor/mmm.h
deleted file mode 100644
index 61a5914..0000000
--- a/src/mmm_extractor/mmm.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * AIM mmm_extractor
- * 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
-#include
-#include
-
-#include
-
-struct dxt5_record
-{
- char unk[0x10];
-};
-
-struct mmm
-{
- uint32_t unk1;
- uint32_t unk2;
- uint32_t width;
- uint32_t height;
- std::vector data;
-
- void load(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 7f91f1f..fa51c86 100644
--- a/src/mmm_extractor/mmm_extractor.cpp
+++ b/src/mmm_extractor/mmm_extractor.cpp
@@ -21,10 +21,25 @@
#include
#include
-#include "mmm.h"
+#include
+#include
using namespace std;
+struct mmm
+{
+ uint32_t unk1;
+ uint32_t unk2;
+ dxt5 data;
+
+ void load(buffer &b)
+ {
+ READ(b, unk1);
+ READ(b, unk2);
+ data.load(b);
+ }
+};
+
mmm read_mmm(string fn)
{
buffer b(readFile(fn));
@@ -33,8 +48,8 @@ mmm read_mmm(string fn)
if (!b.eof())
{
- stringstream ss;
- ss << hex << b.index() << " != " << hex << b.size();
+ std::stringstream ss;
+ ss << std::hex << b.index() << " != " << hex << b.size();
throw std::logic_error(ss.str());
}
return m;
@@ -43,16 +58,13 @@ mmm read_mmm(string fn)
int main(int argc, char *argv[])
try
{
-#ifdef NDEBUG
if (argc != 2)
{
cout << "Usage:\n" << argv[0] << " file.mmp" << "\n";
return 1;
}
- read_mmm(argv[1]);
-#else
- auto loc1 = read_mmm("h:\\Games\\AIM\\data\\minimaps.pak.dir\\location1.mmm");
-#endif
+ auto m = read_mmm(argv[1]);
+ write_mat_bmp(std::string(argv[1]) + ".bmp", m.data.unpack_mmm());
return 0;
}
catch (std::exception &e)
diff --git a/src/mmo_extractor/mmo_extractor.cpp b/src/mmo_extractor/mmo_extractor.cpp
index e5fe84b..c720adb 100644
--- a/src/mmo_extractor/mmo_extractor.cpp
+++ b/src/mmo_extractor/mmo_extractor.cpp
@@ -32,7 +32,7 @@
#include
-#include
+#include
#define RAD2GRAD(x) (x) = (x) / M_PI * 180.0
@@ -132,14 +132,14 @@ void write_mmo(string db, const storage &s)
if (seg->segment_type == SegmentType::SHELL ||
seg->segment_type == SegmentType::TOWER)
{
- SegmentObjects *segment = (SegmentObjects *)seg;
+ SegmentObjects<::MapObject> *segment = (SegmentObjects<::MapObject> *)seg;
set objs;
std::map bld_ids;
for (auto &object : segment->objects)
- objs.insert(object.name1);
+ objs.insert(object->name1);
for (auto &o : objs)
{
- auto iter = find_if(storage->buildings.begin(), storage->buildings.end(), [&](const decltype(Storage::buildings)::value_type &p)
+ auto iter = find_if(storage->buildings.begin(), storage->buildings.end(), [&](const auto &p)
{
return p.second->text_id == o;
});
@@ -155,18 +155,18 @@ void write_mmo(string db, const storage &s)
for (auto &object : segment->objects)
{
MapBuilding mb;
- mb.text_id = object.name2;
- mb.building = storage->buildings[bld_ids[object.name1]];
+ mb.text_id = object->name2;
+ mb.building = storage->buildings[bld_ids[object->name1]];
mb.map = this_map;
- mb.x = object.position.x;
- mb.y = object.position.y;
- mb.z = object.position.z;
+ mb.x = object->position.x;
+ mb.y = object->position.y;
+ mb.z = object->position.z;
mb.roll = 0;
mb.pitch = 0;
- mb.yaw = acos(object.m_rotate_z[0].x);
+ mb.yaw = acos(object->m_rotate_z[0].x);
RAD2GRAD(mb.yaw);
- mb.scale = object.m_rotate_z[2].z;
- auto i = find_if(storage->mapBuildings.begin(), storage->mapBuildings.end(), [&](const decltype(Storage::mapBuildings)::value_type &p)
+ mb.scale = object->m_rotate_z[2].z;
+ auto i = find_if(storage->mapBuildings.begin(), storage->mapBuildings.end(), [&](const auto &p)
{
return *p.second.get() == mb;
});
@@ -180,16 +180,17 @@ void write_mmo(string db, const storage &s)
}
if (seg->segment_type == SegmentType::SURFACE ||
seg->segment_type == SegmentType::STONE ||
- seg->segment_type == SegmentType::EXPLOSION)
+ seg->segment_type == SegmentType::EXPLOSION ||
+ seg->segment_type == SegmentType::BOUNDARY)
{
- SegmentObjects *segment = (SegmentObjects *)seg;
+ SegmentObjects<::MapObject> *segment = (SegmentObjects<::MapObject> *)seg;
set objs;
std::map bld_ids;
for (auto &object : segment->objects)
- objs.insert(object.name1);
+ objs.insert(object->name1);
for (auto &o : objs)
{
- auto iter = find_if(storage->objects.begin(), storage->objects.end(), [&](const decltype(Storage::objects)::value_type &p)
+ auto iter = find_if(storage->objects.begin(), storage->objects.end(), [&](const auto &p)
{
return p.second->text_id == o;
});
@@ -205,18 +206,18 @@ void write_mmo(string db, const storage &s)
for (auto &object : segment->objects)
{
detail::MapObject mb;
- mb.text_id = object.name2;
+ mb.text_id = object->name2;
mb.map = this_map;
- mb.object = storage->objects[bld_ids[object.name1]];
- mb.x = object.position.x;
- mb.y = object.position.y;
- mb.z = object.position.z;
+ mb.object = storage->objects[bld_ids[object->name1]];
+ mb.x = object->position.x;
+ mb.y = object->position.y;
+ mb.z = object->position.z;
mb.roll = 0;
mb.pitch = 0;
- mb.yaw = acos(object.m_rotate_z[0].x);
+ mb.yaw = acos(object->m_rotate_z[0].x);
RAD2GRAD(mb.yaw);
- mb.scale = object.m_rotate_z[2].z;
- auto i = find_if(storage->mapObjects.begin(), storage->mapObjects.end(), [&](const decltype(Storage::mapObjects)::value_type &p)
+ mb.scale = object->m_rotate_z[2].z;
+ auto i = find_if(storage->mapObjects.begin(), storage->mapObjects.end(), [&](const auto &p)
{
return *p.second.get() == mb;
});
diff --git a/src/mmo_extractor/objects.h b/src/mmo_extractor/objects.h
index ee9684e..91b00e6 100644
--- a/src/mmo_extractor/objects.h
+++ b/src/mmo_extractor/objects.h
@@ -24,7 +24,7 @@
#include
#include
-#include
+#include
using namespace std;
@@ -76,15 +76,15 @@ struct Segment
template
struct SegmentObjects : public Segment
{
- vector objects;
+ vector objects;
virtual void load(buffer &b)
{
for (int i = 0; i < n_objects; i++)
{
- T r;
- r.load(b);
- objects.push_back(r);
+ T* o = new T;
+ o->load(b);
+ objects.push_back(o);
}
}
};
@@ -126,16 +126,16 @@ struct MapObject : public Common
struct MapObjectWithArray : public MapObject
{
uint32_t len = 0;
- vector unk7;
+ vector unk0;
void load(buffer &b)
{
MapObject::load(b);
READ(b, len);
- unk7.resize(len);
+ unk0.resize(len);
for (int i = 0; i < len; i++)
- READ(b, unk7[i]);
+ READ(b, unk0[i]);
}
};
diff --git a/src/mmo_extractor/other.h b/src/mmo_extractor/other.h
index f464cf8..8ecd85f 100644
--- a/src/mmo_extractor/other.h
+++ b/src/mmo_extractor/other.h
@@ -24,7 +24,7 @@
#include
#include
-#include
+#include
using namespace std;
diff --git a/src/mmp_extractor/mat.h b/src/mmp_extractor/mat.h
deleted file mode 100644
index 9550be2..0000000
--- a/src/mmp_extractor/mat.h
+++ /dev/null
@@ -1,47 +0,0 @@
-#pragma once
-
-#include
-#include
-#include
-
-template
-class mat
-{
-public:
- using type = T;
-
-public:
- mat(int w = 0, int h = 0)
- {
- width = w < 0 ? 0 : w;
- height = h < 0 ? 0 : h;
- data.resize(width * height, T());
- }
-
- T &operator()(int row, int col)
- {
- assert(!(row >= height || col >= width || row < 0 || col < 0));
- return data[row * width + col];
- }
- const T &operator()(int row, int col) const
- {
- return (*const_cast(this))(row, col);
- }
-
- void clean()
- {
- std::fill(data.begin(), data.end(), T());
- }
-
- int getWidth() const { return width; }
- int getHeight() const { return height; }
- int size() const { return width * height; }
- int getPos(const T *const elem) const { return elem - &data[0]; }
- const std::vector &getData() const { return data; }
- std::vector &getData() { return data; }
-
-private:
- std::vector data;
- int width;
- int height;
-};
diff --git a/src/mmp_extractor/mmp.cpp b/src/mmp_extractor/mmp.cpp
index c21b47f..696b6ca 100644
--- a/src/mmp_extractor/mmp.cpp
+++ b/src/mmp_extractor/mmp.cpp
@@ -22,61 +22,6 @@
#include
#include
-#include "bmp.h"
-
-template
-void write_mat_bmp(const std::string &filename, const mat &m)
-{
- FILE *f = fopen(filename.c_str(), "wb");
- if (f == nullptr)
- return;
- BITMAPFILEHEADER h = { 0 };
- h.bfType = 0x4D42;
- h.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO) + m.size() * sizeof(T);
- h.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO);
- BITMAPINFO i = { 0 };
- i.bmiHeader.biSize = sizeof(i.bmiHeader);
- i.bmiHeader.biWidth = m.getWidth();
- i.bmiHeader.biHeight = m.getHeight();
- i.bmiHeader.biPlanes = 1;
- i.bmiHeader.biBitCount = 32;
- i.bmiHeader.biCompression = 0;
- i.bmiHeader.biSizeImage = 0;
- i.bmiHeader.biXPelsPerMeter = 0;
- i.bmiHeader.biYPelsPerMeter = 0;
- i.bmiHeader.biClrUsed = 0;
- i.bmiHeader.biClrImportant = 0;
- fwrite(&h, sizeof(BITMAPFILEHEADER), 1, f);
- fwrite(&i, sizeof(BITMAPINFO), 1, f);
- fwrite(&m(0, 0), m.size() * sizeof(T), 1, f);
- fclose(f);
-}
-
-void write_mat_tga(const std::string &filename, const mat &m)
-{
- // http://paulbourke.net/dataformats/tga/
- buffer dst;
- dst.write(uint8_t(0xE)); // idlength (comment length)
- dst.write(uint8_t(0)); // colourmaptype
- dst.write(uint8_t(3)); // datatypecode
- dst.write(uint16_t(0)); // colourmaporigin
- dst.write(uint16_t(0)); // colourmaplength
- dst.write(uint8_t(0)); // colourmapdepth
- dst.write(uint16_t(0)); // x_origin
- dst.write(uint16_t(0)); // y_origin
- dst.write(uint16_t(m.getWidth())); // width
- dst.write(uint16_t(m.getHeight())); // height
- dst.write(uint8_t(8)); // bitsperpixel
- dst.write(uint8_t(0x28)); // imagedescriptor
-
- const char *label = "AIMMPExtractor";
- dst.write(label, strlen(label));
-
- dst.write(m.getData().data(), m.getWidth() * m.getHeight());
-
- writeFile(filename, dst.buf());
-}
-
void water_segment::load(buffer &b)
{
while (!b.eof())
@@ -247,7 +192,7 @@ void mmp::process()
}
textures.erase(0);
auto textures_per_color = std::max(1U, textures.size() / 3);
- auto color_step = 200 / textures.size();
+ auto color_step = 200 / std::max(1U, textures.size());
for (int i = 0; i < textures.size(); i++)
{
int color_id = i / textures_per_color;
@@ -286,10 +231,14 @@ void mmp::process()
const auto &data = segments[ys + xs].d;
auto height = data.Heightmap[yc + xc];
auto t = data.Infomap[yc + xc].getTexture();
- auto t_norm = textures_map[t];
- texmap(y_rev, x) = t_norm;
- alpha_maps[t_norm.g](y_rev, x) = color{ 0,255,0,0 };
+ auto t_norm = textures_map.find(t);
+ if (t_norm != textures_map.end())
+ {
+ texmap(y_rev, x) = t_norm->second;
+ alpha_maps[t_norm->second.g](y_rev, x) = color{ 0,255,0,0 };
+ }
+
texmap_colored(y_rev, x) = textures_map_colored[t];
colormap(y_rev, x) = data.Colormap[yc + xc];
diff --git a/src/mmp_extractor/mmp.h b/src/mmp_extractor/mmp.h
index 6a7de19..8ea1ac6 100644
--- a/src/mmp_extractor/mmp.h
+++ b/src/mmp_extractor/mmp.h
@@ -22,9 +22,9 @@
#include
#include
-#include
-
-#include "mat.h"
+#include
+#include
+#include
enum class WeatherType : uint32_t
{
@@ -41,24 +41,6 @@ enum class SmokeType : uint32_t
linear,
};
-struct color
-{
- uint8_t b;
- uint8_t g;
- uint8_t r;
- uint8_t a;
-
- operator uint32_t() const
- {
- uint32_t color = 0;
- color |= r << 16;
- color |= g << 8;
- color |= b;
- return color;
- //return *reinterpret_cast(const_cast(&b));
- }
-};
-
struct direction
{
float x;
diff --git a/src/mod_converter/mod_converter.cpp b/src/mod_converter/mod_converter.cpp
index d69f96a..4659601 100644
--- a/src/mod_converter/mod_converter.cpp
+++ b/src/mod_converter/mod_converter.cpp
@@ -23,7 +23,7 @@
#include
#include
-#include
+#include
#include "model.h"
using namespace std;
diff --git a/src/mod_converter/model.cpp b/src/mod_converter/model.cpp
index 3b7dc6f..e80b2a8 100644
--- a/src/mod_converter/model.cpp
+++ b/src/mod_converter/model.cpp
@@ -23,7 +23,7 @@
#include
#include
-#include
+#include
using namespace std;
diff --git a/src/tm_converter/tm_converter.bat b/src/tm_converter/tm_converter.bat
index be0c4ee..2c04b2c 100644
--- a/src/tm_converter/tm_converter.bat
+++ b/src/tm_converter/tm_converter.bat
@@ -1 +1,2 @@
-python tm_converter.py --dir "h:\\Games\\Epic Games\\Projects\\AIM\\models\\aim1\\"
\ No newline at end of file
+python tm_converter.py --dir "h:\\Games\\AIM\\data\\res1.pak.dir\\Data\\TM\\"
+python tm_converter.py --dir "h:\\Games\\Steam\\steamapps\\common\\AIM2\\Data\\tex.pak\\DATA\\TM\\"
diff --git a/src/tm_converter/tm_converter.cpp b/src/tm_converter/tm_converter.cpp
index db8d2d2..bf7cbc9 100644
--- a/src/tm_converter/tm_converter.cpp
+++ b/src/tm_converter/tm_converter.cpp
@@ -23,7 +23,9 @@
#include
#include
-#include
+#include
+#include
+#include
using namespace std;
@@ -44,44 +46,48 @@ void convert_simple(buffer &dst, buffer &src, int width, int height)
void tm2tga(string fn)
{
int width, height;
- int dxt5 = 0;
+ int dxt5_flag = 0;
buffer src(readFile(fn));
READ(src, width);
READ(src, height);
src.seek(0x10);
- src.read(&dxt5, 1);
+ src.read(&dxt5_flag, 1);
src.seek(0x4C);
- // http://paulbourke.net/dataformats/tga/
- buffer dst;
- dst.write(uint8_t(0xE)); // idlength (comment length)
- dst.write(uint8_t(0)); // colourmaptype
- dst.write(uint8_t(2)); // datatypecode
- dst.write(uint16_t(0)); // colourmaporigin
- dst.write(uint16_t(0)); // colourmaplength
- dst.write(uint8_t(0)); // colourmapdepth
- dst.write(uint16_t(0)); // x_origin
- dst.write(uint16_t(0)); // y_origin
- dst.write(uint16_t(width)); // width
- dst.write(uint16_t(height)); // height
- dst.write(uint8_t(32)); // bitsperpixel
- dst.write(uint8_t(0x28)); // imagedescriptor
-
- const char *label = "AIMTMConverter";
- dst.write(label, strlen(label));
-
- if (dxt5)
+ if (dxt5_flag)
{
- //convert_dxt5(dst, src, width, height);
- throw std::logic_error("dxt5 converter is not implemented!");
+ dxt5 d;
+ d.width = width;
+ d.height = height;
+ d.load_blocks(src);
+ write_mat_bmp(fn + ".bmp", d.unpack_tm());
}
else
- convert_simple(dst, src, width, height);
+ {
+ // http://paulbourke.net/dataformats/tga/
+ buffer dst;
+ dst.write(uint8_t(0xE)); // idlength (comment length)
+ dst.write(uint8_t(0)); // colourmaptype
+ dst.write(uint8_t(2)); // datatypecode
+ dst.write(uint16_t(0)); // colourmaporigin
+ dst.write(uint16_t(0)); // colourmaplength
+ dst.write(uint8_t(0)); // colourmapdepth
+ dst.write(uint16_t(0)); // x_origin
+ dst.write(uint16_t(0)); // y_origin
+ dst.write(uint16_t(width)); // width
+ dst.write(uint16_t(height)); // height
+ dst.write(uint8_t(32)); // bitsperpixel
+ dst.write(uint8_t(0x28)); // imagedescriptor
- transform(fn.begin(), fn.end(), fn.begin(), ::tolower);
- fn = fn.substr(0, fn.rfind(".tm")) + ".tga";
- writeFile(fn, dst.buf());
+ const char *label = "AIMTMConverter";
+ dst.write(label, strlen(label));
+
+ convert_simple(dst, src, width, height);
+ transform(fn.begin(), fn.end(), fn.begin(), ::tolower);
+ fn = fn.substr(0, fn.rfind(".tm")) + ".tga";
+ writeFile(fn, dst.buf());
+ }
}
int main(int argc, char *argv[])
diff --git a/src/tm_converter/tm_converter.py b/src/tm_converter/tm_converter.py
index 97921d4..d1590fd 100644
--- a/src/tm_converter/tm_converter.py
+++ b/src/tm_converter/tm_converter.py
@@ -17,6 +17,7 @@ def run(dir):
for file in sorted(os.listdir(dir)):
if os.path.isdir(file) or os.path.splitext(file)[1].lower() != ".tm":
continue
+ print('processing: ' + file)
p = subprocess.Popen(['tm_converter.exe', dir + '/' + file])
p.communicate()
diff --git a/src/unpaker/decode.h b/src/unpaker/decode.h
index c4e3d6f..0074e72 100644
--- a/src/unpaker/decode.h
+++ b/src/unpaker/decode.h
@@ -3,7 +3,6 @@
#define _BYTE uint8_t
#define _WORD uint16_t
#define _DWORD uint32_t
-#define _QWORD uint64_t
#define LOBYTE(x) (*((_BYTE*)&(x)))
#define LOWORD(x) (*((_WORD*)&(x)))