mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-14 17:33:25 +00:00
Add mmp extractor.
This commit is contained in:
parent
c13dede2e8
commit
0a67413c4b
6 changed files with 218 additions and 40 deletions
|
|
@ -1 +1 @@
|
|||
Subproject commit 8a5126cd1a2769780bd4e05c18d553f2bcb60f56
|
||||
Subproject commit 8fbdd4aba7438c7d3eace1308476597460d0aeed
|
||||
|
|
@ -10,3 +10,6 @@ target_link_libraries(obj_extractor DatabaseManager)
|
|||
|
||||
file(GLOB script2txt_src "script2txt/*")
|
||||
add_executable(script2txt ${script2txt_src})
|
||||
|
||||
file(GLOB mmp_extractor_src "mmp_extractor/*")
|
||||
add_executable(mmp_extractor ${mmp_extractor_src})
|
||||
|
|
|
|||
57
src/mmp_extractor/mmp.cpp
Normal file
57
src/mmp_extractor/mmp.cpp
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* AIM mmp_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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "mmp.h"
|
||||
|
||||
#define FREAD(var) fread(&var, 1, sizeof(var), f)
|
||||
#define FREAD_N(var, n) fread(&var, 1, n, f)
|
||||
|
||||
size_t file_size(FILE *f)
|
||||
{
|
||||
auto old = ftell(f);
|
||||
fseek(f, 0, SEEK_END);
|
||||
auto sz = ftell(f);
|
||||
fseek(f, old, SEEK_SET);
|
||||
return sz;
|
||||
}
|
||||
|
||||
void mmp::load(FILE *f)
|
||||
{
|
||||
FREAD(unk1);
|
||||
FREAD(unk2);
|
||||
FREAD(width);
|
||||
FREAD(height);
|
||||
FREAD(unk3);
|
||||
FREAD(unk4);
|
||||
FREAD(unk5);
|
||||
FREAD(unk6);
|
||||
FREAD(unk7);
|
||||
FREAD(unk8);
|
||||
|
||||
int n_seg = width / 64 * height / 64;
|
||||
int sz = n_seg * sizeof(segment);
|
||||
int fsz = file_size(f);
|
||||
int off = fsz - sz;
|
||||
fseek(f, off, SEEK_SET);
|
||||
|
||||
segments = vector<segment>(n_seg);
|
||||
for (int i = 0; i < n_seg; i++)
|
||||
FREAD(segments[i]);
|
||||
|
||||
assert(ftell(f) == fsz);
|
||||
}
|
||||
60
src/mmp_extractor/mmp.h
Normal file
60
src/mmp_extractor/mmp.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* AIM mmp_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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
struct mmp
|
||||
{
|
||||
struct segment
|
||||
{
|
||||
uint32_t MagicNumber;
|
||||
uint32_t MiniLayer1[1089];
|
||||
uint32_t MiniLayer2[1089];
|
||||
uint32_t MiniLayer3[1089];
|
||||
uint32_t MiniLayer4[1089];
|
||||
float Heightmap[4225];
|
||||
uint32_t Infomap[4225];
|
||||
uint32_t Colormap[4225];
|
||||
uint32_t Shadowmap[4225];
|
||||
uint32_t Normalmap[4225];
|
||||
};
|
||||
|
||||
uint32_t unk1;
|
||||
char unk2[0x80];
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t unk3;
|
||||
char unk4[0xA0];
|
||||
uint32_t unk5[7];
|
||||
char unk6[0xA0];
|
||||
char unk7[0x1AC];
|
||||
char unk8[0x1AC];
|
||||
uint32_t offset; // the beginning of segments
|
||||
|
||||
vector<segment> segments;
|
||||
|
||||
void load(FILE *f);
|
||||
};
|
||||
57
src/mmp_extractor/mmp_extractor.cpp
Normal file
57
src/mmp_extractor/mmp_extractor.cpp
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* AIM mmp_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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#include "mmp.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
mmp read_mmp(string fn)
|
||||
{
|
||||
mmp m;
|
||||
FILE *f = fopen(fn.c_str(), "rb");
|
||||
if (!f)
|
||||
return m;
|
||||
m.load(f);
|
||||
fclose(f);
|
||||
return m;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifdef NDEBUG
|
||||
if (argc != 2)
|
||||
{
|
||||
cout << "Usage:\n" << argv[0] << " file.mmp" << "\n";
|
||||
return 1;
|
||||
}
|
||||
read_mmp(argv[1]);
|
||||
#else
|
||||
auto arena = read_mmp("h:\\Games\\Ìåõàíîèäû\\data\\maps.pak.dir\\arena.mmp");
|
||||
auto loc1 = read_mmp("h:\\Games\\Ìåõàíîèäû\\data\\maps.pak.dir\\location1.mmp");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -33,6 +33,7 @@ using namespace std;
|
|||
|
||||
struct storage
|
||||
{
|
||||
string name;
|
||||
Objects objects;
|
||||
MechGroups mgs;
|
||||
MapGoods mg;
|
||||
|
|
@ -43,6 +44,7 @@ struct storage
|
|||
storage read_mmo(string fn)
|
||||
{
|
||||
storage s;
|
||||
s.name = fn;
|
||||
FILE *f = fopen(fn.c_str(), "rb");
|
||||
if (!f)
|
||||
return s;
|
||||
|
|
@ -69,7 +71,30 @@ void write_mmo(string db, const storage &s)
|
|||
auto storage = initStorage(db);
|
||||
storage->load();
|
||||
|
||||
int map_id = 1;
|
||||
auto p1 = s.name.rfind('\\');
|
||||
if (p1 == -1)
|
||||
p1 = 0;
|
||||
auto p2 = s.name.rfind('/');
|
||||
if (p2 == -1)
|
||||
p2 = 0;
|
||||
int p = max(p1, p2);
|
||||
string map_name = s.name.substr(p + 1);
|
||||
map_name = map_name.substr(0, map_name.find('.'));
|
||||
|
||||
int map_id = 0;
|
||||
for (auto &m : storage->maps)
|
||||
{
|
||||
if (m.second->text_id == map_name)
|
||||
{
|
||||
map_id = m.first;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (map_id == 0)
|
||||
return;
|
||||
|
||||
auto this_map = storage->maps[map_id];
|
||||
|
||||
for (auto &seg : s.objects.segments)
|
||||
{
|
||||
|
|
@ -78,7 +103,6 @@ void write_mmo(string db, const storage &s)
|
|||
SegmentObjects<Shell> *segment = (SegmentObjects<Shell> *)seg;
|
||||
set<string> objs;
|
||||
std::map<string, int> bld_ids;
|
||||
std::map<string, int> coord_ids;
|
||||
for (auto &object : segment->objects)
|
||||
objs.insert(object.name1);
|
||||
for (auto &o : objs)
|
||||
|
|
@ -101,24 +125,13 @@ void write_mmo(string db, const storage &s)
|
|||
MapBuilding mb;
|
||||
mb.text_id = object.name2;
|
||||
mb.building = storage->buildings[bld_ids[object.name1]];
|
||||
auto iter = find_if(storage->coordinates.begin(), storage->coordinates.end(), [&](const decltype(Storage::coordinates)::value_type &p)
|
||||
{
|
||||
Coordinate c;
|
||||
c.x = object.position.x;
|
||||
c.y = object.position.y;
|
||||
c.z = object.position.z;
|
||||
return *p.second.get() == c;
|
||||
});
|
||||
if (iter == storage->coordinates.end())
|
||||
{
|
||||
auto c = storage->addCoordinate();
|
||||
c->x = object.position.x;
|
||||
c->y = object.position.y;
|
||||
c->z = object.position.z;
|
||||
mb.coordinate = c;
|
||||
}
|
||||
else
|
||||
mb.coordinate = iter->second;
|
||||
mb.map = this_map;
|
||||
mb.x = object.position.x * 100.0;
|
||||
mb.y = object.position.y * 100.0;
|
||||
mb.z = object.position.z * 100.0;
|
||||
mb.yaw = atan2(object.m_rotate_z[1].x, object.m_rotate_z[0].x);
|
||||
mb.pitch = atan2(-object.m_rotate_z[2].x, sqrt(object.m_rotate_z[2].y * object.m_rotate_z[2].y + object.m_rotate_z[2].z * object.m_rotate_z[2].z));
|
||||
mb.roll = atan2(object.m_rotate_z[2].y, object.m_rotate_z[2].z);
|
||||
auto i = find_if(storage->mapBuildings.begin(), storage->mapBuildings.end(), [&](const decltype(Storage::mapBuildings)::value_type &p)
|
||||
{
|
||||
return *p.second.get() == mb;
|
||||
|
|
@ -138,7 +151,6 @@ void write_mmo(string db, const storage &s)
|
|||
SegmentObjects<Surface> *segment = (SegmentObjects<Surface> *)seg;
|
||||
set<string> objs;
|
||||
std::map<string, int> bld_ids;
|
||||
std::map<string, int> coord_ids;
|
||||
for (auto &object : segment->objects)
|
||||
objs.insert(object.name1);
|
||||
for (auto &o : objs)
|
||||
|
|
@ -160,25 +172,14 @@ void write_mmo(string db, const storage &s)
|
|||
{
|
||||
detail::MapObject mb;
|
||||
//mb.text_id = object.name2;
|
||||
mb.map = this_map;
|
||||
mb.object = storage->objects[bld_ids[object.name1]];
|
||||
auto iter = find_if(storage->coordinates.begin(), storage->coordinates.end(), [&](const decltype(Storage::coordinates)::value_type &p)
|
||||
{
|
||||
Coordinate c;
|
||||
c.x = object.position.x;
|
||||
c.y = object.position.y;
|
||||
c.z = object.position.z;
|
||||
return *p.second.get() == c;
|
||||
});
|
||||
if (iter == storage->coordinates.end())
|
||||
{
|
||||
auto c = storage->addCoordinate();
|
||||
c->x = object.position.x;
|
||||
c->y = object.position.y;
|
||||
c->z = object.position.z;
|
||||
mb.coordinate = c;
|
||||
}
|
||||
else
|
||||
mb.coordinate = iter->second;
|
||||
mb.x = object.position.x * 100.0;
|
||||
mb.y = object.position.y * 100.0;
|
||||
mb.z = object.position.z * 100.0;
|
||||
mb.yaw = atan2(object.m_rotate_z[1].x, object.m_rotate_z[0].x);
|
||||
mb.pitch = atan2(-object.m_rotate_z[2].x, sqrt(object.m_rotate_z[2].y * object.m_rotate_z[2].y + object.m_rotate_z[2].z * object.m_rotate_z[2].z));
|
||||
mb.roll = atan2(object.m_rotate_z[2].y, object.m_rotate_z[2].z);
|
||||
auto i = find_if(storage->mapObjects.begin(), storage->mapObjects.end(), [&](const decltype(Storage::mapObjects)::value_type &p)
|
||||
{
|
||||
return *p.second.get() == mb;
|
||||
|
|
|
|||
Loading…
Reference in a new issue