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