Extract texture maps from mmp.

This commit is contained in:
lzwdgc 2015-08-08 01:08:36 +03:00
parent 7f214ed2ec
commit 1a237c283d
12 changed files with 1376 additions and 135 deletions

View file

@ -20,15 +20,15 @@
#include <common.h> #include <common.h>
string getSqlType(uint32_t ft) string getSqlType(FieldType type)
{ {
switch (ft) switch (type)
{ {
case T_STRING: case FieldType::String:
return "TEXT"; return "TEXT";
case T_INTEGER: case FieldType::Integer:
return "INTEGER"; return "INTEGER";
case T_FLOAT: case FieldType::Float:
return "REAL"; return "REAL";
default: default:
assert(false); assert(false);
@ -40,9 +40,6 @@ void table::load(buffer &b)
{ {
READ(b, id); READ(b, id);
READ(b, name); READ(b, name);
READ(b, unk1);
READ(b, unk2);
READ(b, unk3);
READ(b, unk4); READ(b, unk4);
} }
@ -51,9 +48,6 @@ void field::load(buffer &b)
READ(b, table_id); READ(b, table_id);
READ(b, id); READ(b, id);
READ(b, name); READ(b, name);
READ(b, unk1);
READ(b, unk2);
READ(b, unk3);
READ(b, type); READ(b, type);
} }
@ -83,20 +77,13 @@ void value::load_index(buffer &b)
{ {
READ(b, table_id); READ(b, table_id);
READ(b, name); READ(b, name);
READ(b, unk1);
READ(b, unk2);
READ(b, unk3);
READ(b, offset); READ(b, offset);
READ(b, data_size); READ(b, data_size);
} }
void value::load_data(buffer &b) void value::load_fields(const tab &tab, buffer &b)
{
data = buffer(b, data_size, offset);
}
void value::extract_fields(const tab &tab)
{ {
buffer data(b, data_size, offset);
while (!data.eof()) while (!data.eof())
{ {
field_value fv; field_value fv;
@ -108,16 +95,16 @@ void value::extract_fields(const tab &tab)
continue; continue;
switch (i->second.type) switch (i->second.type)
{ {
case T_STRING: case FieldType::String:
fv.s.resize(fv.size); fv.s.resize(fv.size);
READ_N(data, fv.s[0], fv.s.size()); READ_N(data, fv.s[0], fv.s.size());
break; break;
case T_INTEGER: case FieldType::Integer:
READ(data, fv.i); READ(data, fv.i);
if (fv.size > sizeof(fv.i)) if (fv.size > sizeof(fv.i))
data.skip(fv.size - sizeof(fv.i)); data.skip(fv.size - sizeof(fv.i));
break; break;
case T_FLOAT: case FieldType::Float:
READ(data, fv.f); READ(data, fv.f);
if (fv.size > sizeof(fv.i)) if (fv.size > sizeof(fv.i))
data.skip(fv.size - sizeof(fv.i)); data.skip(fv.size - sizeof(fv.i));

View file

@ -28,21 +28,18 @@
using namespace std; using namespace std;
enum FieldType enum class FieldType : uint32_t
{ {
T_STRING, String,
T_INTEGER, Integer,
T_FLOAT, Float,
}; };
string getSqlType(uint32_t ft); string getSqlType(FieldType type);
struct table struct table
{ {
uint32_t id; uint32_t id;
char name[0x14]; char name[0x20];
uint32_t unk1;
uint32_t unk2;
uint32_t unk3;
uint32_t unk4; uint32_t unk4;
void load(buffer &b); void load(buffer &b);
@ -52,11 +49,8 @@ struct field
{ {
uint32_t table_id; uint32_t table_id;
uint32_t id; uint32_t id;
char name[0x14]; char name[0x20];
uint32_t unk1; FieldType type;
uint32_t unk2;
uint32_t unk3;
uint32_t type;
void load(buffer &b); void load(buffer &b);
}; };
@ -85,20 +79,13 @@ struct field_value
struct value struct value
{ {
uint32_t table_id; uint32_t table_id;
char name[0x14]; char name[0x20];
uint32_t unk1;
uint32_t unk2;
uint32_t unk3;
uint32_t offset; uint32_t offset;
uint32_t data_size; uint32_t data_size;
buffer data;
uint32_t number_of_fields;
vector<field_value> fields; vector<field_value> fields;
void extract_fields(const tab &tab);
void load_index(buffer &b); void load_index(buffer &b);
void load_data(buffer &b); void load_fields(const tab &tab, buffer &b);
}; };
struct db struct db

View file

@ -30,9 +30,7 @@ void open_db(string path, db &db)
db.load(buffer(readFile(path + ".ind"))); db.load(buffer(readFile(path + ".ind")));
buffer b(readFile(path + ".dat")); buffer b(readFile(path + ".dat"));
for (auto &v : db.values) for (auto &v : db.values)
v.load_data(b); v.load_fields(db.t, b);
for (auto &v : db.values)
v.extract_fields(db.t);
} }
string str2utf8(string codepage_str) string str2utf8(string codepage_str)
@ -132,13 +130,13 @@ void create_sql(string path, const db &db)
auto fld = db.t.fields.find(f.field_id); auto fld = db.t.fields.find(f.field_id);
switch (fld->second.type) switch (fld->second.type)
{ {
case T_STRING: case FieldType::String:
s += str2utf8(f.s.c_str()); s += str2utf8(f.s.c_str());
break; break;
case T_INTEGER: case FieldType::Integer:
s += to_string(f.i); s += to_string(f.i);
break; break;
case T_FLOAT: case FieldType::Float:
s += to_string(f.f); s += to_string(f.f);
break; break;
default: default:

46
src/mmp_extractor/bmp.h Normal file
View file

@ -0,0 +1,46 @@
#pragma once
#include <stdint.h>
using BYTE = uint8_t;
using WORD = uint16_t;
using DWORD = uint32_t;
using LONG = uint32_t;
#pragma pack(push, 1)
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER {
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO;
#pragma pack(pop)

47
src/mmp_extractor/mat.h Normal file
View file

@ -0,0 +1,47 @@
#pragma once
#include <assert.h>
#include <deque>
#include <vector>
template <class T>
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<mat *>(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<T> &getData() const { return data; }
std::vector<T> &getData() { return data; }
private:
std::vector<T> data;
int width;
int height;
};

View file

@ -18,17 +18,76 @@
#include "mmp.h" #include "mmp.h"
void unk_segment1::load(buffer &b) #include <algorithm>
#include <fstream>
#include <iomanip>
#include "bmp.h"
template<class T>
void write_mat_bmp(const std::string &filename, const mat<T> &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<uint8_t> &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()) while (!b.eof())
{ {
unk_segment1_1 s; water w;
s.load(b); w.load(b);
segments.push_back(s); segments.push_back(w);
} }
} }
void unk_segment1_1::load(buffer &b) void water::load(buffer &b)
{ {
READ(b, unk0); READ(b, unk0);
READ(b, name1); READ(b, name1);
@ -40,7 +99,7 @@ void unk_segment1_1::load(buffer &b)
READ(b, unk5); READ(b, unk5);
} }
void unk_segment2::load(buffer &b) void weather_segment::load(buffer &b)
{ {
READ(b, n_segs); READ(b, n_segs);
segments.resize(n_segs); segments.resize(n_segs);
@ -49,22 +108,36 @@ void unk_segment2::load(buffer &b)
s.load(b); s.load(b);
} }
void unk_segment2_1::load(buffer &b) void weather::load(buffer &b)
{ {
READ(b, name1); READ(b, name);
READ(b, name2);
READ(b, name3);
READ(b, name4);
READ(b, name5);
READ(b, unk0); READ(b, unk0);
READ(b, unk1); READ(b, unk1);
READ(b, tex_name0); READ(b, smoke_1);
READ(b, smoke_3);
READ(b, smokeType);
READ(b, unk2); READ(b, unk2);
READ(b, unk_name0); READ(b, cloud_layer1);
READ(b, unk3); READ(b, cloud_layer2);
READ(b, tex_name1); READ(b, cloud_layer1_speed);
READ(b, tex_name2); READ(b, cloud_layer2_speed);
READ(b, unk4); READ(b, cloud_layer1_direction);
READ(b, cloud_layer2_direction);
READ(b, sun);
READ(b, general_color);
READ(b, sun_color);
READ(b, moon_color);
READ(b, moon);
READ(b, probability);
READ(b, day_night_gradient_name);
READ(b, dawn_dusk_gradient_name);
READ(b, dawn_dusk_color);
READ(b, effects);
READ(b, smoke_2);
READ(b, smoke_4);
READ(b, slider_3);
READ(b, slider_1);
READ(b, unk8);
} }
header_segment *header::create_segment(buffer &b) header_segment *header::create_segment(buffer &b)
@ -75,11 +148,11 @@ header_segment *header::create_segment(buffer &b)
header_segment *segment = 0; header_segment *segment = 0;
switch (type) switch (type)
{ {
case HeaderSegmentType::unk1: case HeaderSegmentType::water:
segment = new unk_segment1; segment = new water_segment;
break; break;
case HeaderSegmentType::unk2: case HeaderSegmentType::weather:
segment = new unk_segment2; segment = new weather_segment;
break; break;
default: default:
throw std::logic_error("unknown header segment type " + std::to_string((int)type)); throw std::logic_error("unknown header segment type " + std::to_string((int)type));
@ -101,8 +174,8 @@ void header::load(buffer &b)
READ(b, name2); READ(b, name2);
READ(b, width); READ(b, width);
READ(b, height); READ(b, height);
READ(b, n_segs); READ(b, n_header_segs);
segments.resize(n_segs); segments.resize(n_header_segs);
READ(b, name); READ(b, name);
for (auto &s : segments) for (auto &s : segments)
{ {
@ -124,8 +197,203 @@ void segment::load(buffer &b)
void mmp::load(buffer &b) void mmp::load(buffer &b)
{ {
h.load(b); h.load(b);
int n_segs = h.width / 64 * h.height / 64; xsegs = (h.width - 1) / 64;
if ((h.width - 1) % 64 != 0)
xsegs++;
ysegs = (h.height - 1) / 64;
if ((h.height - 1) % 64 != 0)
ysegs++;
int n_segs = xsegs * ysegs;
segments.resize(n_segs); segments.resize(n_segs);
for (auto &s : segments) for (auto &s : segments)
s.load(b); s.load(b);
// check whether all segments were read
if (segments.size())
{
auto len = segments[0].desc.offset + segments.size() * sizeof(segment::data);
if (len != b.size())
throw std::logic_error("Some segments were not read");
} }
}
void mmp::load(const std::string &fn)
{
filename = fn;
buffer b(readFile(filename));
load(b);
}
void mmp::loadTextureNames(const std::string &fn)
{
std::ifstream ifile(fn);
while (ifile)
{
int id;
std::string name;
ifile >> id >> name;
textures_names[id] = name;
}
}
void mmp::process()
{
int k = segment::len;
for (auto &s : segments)
{
for (auto &i : s.d.Infomap)
textures[i.getTexture()]++;
}
textures.erase(0);
auto textures_per_color = std::max(1U, textures.size() / 3);
auto color_step = 200 / textures.size();
for (int i = 0; i < textures.size(); i++)
{
int color_id = i / textures_per_color;
color c = { 0 };
if (color_id == 0)
c.r = 255 - 200 / textures_per_color * (i % textures_per_color);
else if (color_id == 1)
c.g = 255 - 200 / textures_per_color * (i % textures_per_color);
else if (color_id == 2)
c.b = 255 - 200 / textures_per_color * (i % textures_per_color);
auto iter = textures.begin();
std::advance(iter, i);
textures_map_colored[iter->first] = c;
color c2 = { 0 };
c2.g = 255 - i * color_step;
textures_map[iter->first] = c2;
}
alpha_maps[0] = mat<uint32_t>(h.width, h.height);
for (auto &t : textures_map)
alpha_maps[t.second.g] = mat<uint32_t>(h.width, h.height);
// merge
heightmap = decltype(heightmap)(h.width, h.height);
texmap = decltype(texmap)(h.width, h.height);
texmap_colored = decltype(texmap_colored)(h.width, h.height);
colormap = decltype(colormap)(h.width, h.height);
for (int y = 0; y < h.height; y++)
{
auto ys = y / k * xsegs;
auto yc = y % k * k;
for (int x = 0; x < h.width; x++)
{
auto xs = x / k;
auto xc = x % k;
auto y_rev = h.height - y - 1;
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 };
texmap_colored(y_rev, x) = textures_map_colored[t];
colormap(y_rev, x) = data.Colormap[yc + xc];
if (x == 0 && y == 0)
{
h_min = height;
h_max = height;
}
else
{
h_min = std::min(h_min, height);
h_max = std::max(h_max, height);
}
}
}
alpha_maps.erase(0);
scale16 = 0xffff / (h_max - h_min);
for (int y = 0; y < h.height; y++)
{
auto ys = y / k * xsegs;
auto yc = y % k * k;
for (int x = 0; x < h.width; x++)
{
auto xs = x / k;
auto xc = x % k;
auto height = segments[ys + xs].d.Heightmap[yc + xc];
auto val = (height - h_min) * scale16;
heightmap(y, x) = val;
}
}
}
void mmp::writeFileInfo()
{
std::ofstream ofile(filename + ".info.txt");
if (!ofile)
return;
ofile << "width: " << h.width << "\n";
ofile << "height: " << h.height << "\n";
ofile << "x segments: " << xsegs << "\n";
ofile << "y segments: " << ysegs << "\n";
ofile << "h_min: " << h_min << "\n";
ofile << "h_max: " << h_max << "\n";
ofile << "h_diff: " << h_max - h_min << "\n";
ofile << "scale16: " << scale16 << "\n";
}
void mmp::writeTexturesList()
{
std::ofstream ofile(filename + ".textures.txt");
if (!ofile)
return;
for (auto &t : textures)
{
ofile << t.first;
if (!textures_names.empty())
{
int c = textures_map[t.first].g;
ofile << "\tcount: " << t.second;
ofile << "\thex: 0x00" << std::hex << c << "0000" << std::dec;
ofile << "\tg: " << c;
ofile << "\tg: " << std::setprecision(3) << std::setw(3) << c / 256.f;
ofile << "\t" << textures_names[t.first];
}
ofile << "\n";
}
}
void mmp::writeHeightMap()
{
auto fn = filename + ".heightmap16.raw";
FILE *f = fopen(fn.c_str(), "wb");
if (f == nullptr)
return;
fwrite(&heightmap(0, 0), heightmap.size() * sizeof(decltype(heightmap)::type), 1, f);
fclose(f);
}
void mmp::writeTextureMap()
{
auto fn = filename + ".texmap.bmp";
write_mat_bmp(fn, texmap);
}
void mmp::writeTextureAlphaMaps()
{
for (auto &t : alpha_maps)
{
auto fn = filename + ".texmap." + std::to_string(t.first) + ".bmp";
write_mat_bmp(fn, t.second);
}
}
void mmp::writeTextureMapColored()
{
auto fn = filename + ".texmap.colored.bmp";
write_mat_bmp(fn, texmap_colored);
}
void mmp::writeColorMap()
{
auto fn = filename + ".colormap.bmp";
write_mat_bmp(fn, colormap);
}

View file

@ -16,16 +16,60 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <map>
#include <set>
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
#include <vector> #include <vector>
#include <common.h> #include <common.h>
#include "mat.h"
enum class WeatherType : uint32_t
{
rain = 0x1,
snow = 0x2,
storm = 0x4,
};
enum class SmokeType : uint32_t
{
none,
exp,
biexp,
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<uint32_t *>(const_cast<uint8_t *>(&b));
}
};
struct direction
{
float x;
float y;
float z;
};
enum class HeaderSegmentType : uint32_t enum class HeaderSegmentType : uint32_t
{ {
unk1 = 1, water = 1,
unk2 = 2, weather = 2,
}; };
struct header_segment struct header_segment
@ -37,7 +81,7 @@ struct header_segment
virtual void load(buffer &b) = 0; virtual void load(buffer &b) = 0;
}; };
struct unk_segment1_1 struct water
{ {
float unk0[6]; float unk0[6];
char name1[0x20]; char name1[0x20];
@ -51,38 +95,61 @@ struct unk_segment1_1
void load(buffer &b); void load(buffer &b);
}; };
struct unk_segment1 : public header_segment struct water_segment : public header_segment
{ {
std::vector<unk_segment1_1> segments; std::vector<water> segments;
virtual void load(buffer &b) override; virtual void load(buffer &b) override;
}; };
struct unk_segment2_1 struct weather
{ {
char name1[0x20]; struct atmospheric_effects
char name2[0x20]; {
char name3[0x20]; direction wind;
char name4[0x20]; WeatherType weatherType;
char name5[0x20]; float strength;
float unk0[2]; float duration;
uint32_t unk1[6]; float probability;
char tex_name0[0x20]; };
char name[0x20];
char unk0[0x20];
uint32_t unk1[2];
color smoke_1; //3?
color smoke_3; //1?
SmokeType smokeType;
uint32_t unk2[3]; uint32_t unk2[3];
char unk_name0[0x20]; char cloud_layer1[0x20];
float unk3; char cloud_layer2[0x20];
char tex_name1[0x20]; float cloud_layer1_speed;
char tex_name2[0x20]; float cloud_layer2_speed;
uint32_t unk4[23]; direction cloud_layer1_direction;
direction cloud_layer2_direction;
char sun[0x20];
color general_color;
color sun_color;
color moon_color;
char moon[0x20];
float probability;
char day_night_gradient_name[0x20];
char dawn_dusk_gradient_name[0x20];
color dawn_dusk_color;
atmospheric_effects effects;
color smoke_2;
color smoke_4;
uint32_t slider_3;
uint32_t slider_1;
float unk8[11];
void load(buffer &b); void load(buffer &b);
}; };
struct unk_segment2 : public header_segment struct weather_segment : public header_segment
{ {
uint32_t n_segs; uint32_t n_segs;
char name[0xA0]; char name[0xA0];
std::vector<unk_segment2_1> segments; std::vector<weather> segments;
virtual void load(buffer &b) override; virtual void load(buffer &b) override;
}; };
@ -94,7 +161,7 @@ struct header
wchar_t name2[0x20]; wchar_t name2[0x20];
uint32_t width; uint32_t width;
uint32_t height; uint32_t height;
uint32_t n_segs; uint32_t n_header_segs;
char name[0xA0]; char name[0xA0];
std::vector<header_segment*> segments; std::vector<header_segment*> segments;
@ -106,6 +173,9 @@ private:
struct segment struct segment
{ {
static const int len = 65;
static const int size = len * len;
struct description struct description
{ {
uint32_t offset; uint32_t offset;
@ -124,13 +194,8 @@ struct segment
{ {
uint16_t render_flags; uint16_t render_flags;
uint16_t texture_index; uint16_t texture_index;
};
struct color uint16_t getTexture() const { return texture_index & 0x0fff; } // first 4 bits are unk (flags?)
{
uint8_t b;
uint8_t g;
uint8_t r;
uint8_t a;
}; };
struct shadow struct shadow
{ {
@ -151,11 +216,11 @@ struct segment
uint32_t MagicNumber; uint32_t MagicNumber;
old_data old; old_data old;
float Heightmap[4225]; float Heightmap[size];
info Infomap[4225]; info Infomap[size];
color Colormap[4225]; color Colormap[size];
shadow Shadowmap[4225]; shadow Shadowmap[size];
normal Normalmap[4225]; normal Normalmap[size];
}; };
description desc; description desc;
@ -169,5 +234,34 @@ struct mmp
header h; header h;
std::vector<segment> segments; std::vector<segment> segments;
//
std::string filename;
int xsegs;
int ysegs;
std::map<int, int /* count */> textures;
std::map<int, color> textures_map;
std::map<int, mat<uint32_t>> alpha_maps;
std::map<int, color> textures_map_colored;
std::map<int, std::string> textures_names;
float h_min;
float h_max;
float scale16 = 0;
mat<uint16_t> heightmap;
mat<uint32_t> texmap;
mat<uint32_t> texmap_colored;
mat<uint32_t> colormap;
void load(buffer &b); void load(buffer &b);
void load(const std::string &filename);
void loadTextureNames(const std::string &filename);
void process();
void writeFileInfo();
void writeTexturesList();
void writeHeightMap();
void writeTextureMap();
void writeTextureAlphaMaps();
void writeTextureMapColored();
void writeColorMap();
}; };

View file

@ -1,2 +1,3 @@
python mmp_extractor.py --dir "h:\Games\AIM\data\maps.pak.dir" python mmp_extractor.py --dir "h:\Games\AIM\data\maps.pak.dir" --tex mmp_tex_aim1.txt
python mmp_extractor.py --dir "h:\Games\Steam\steamapps\common\AIM2\Data\mmp.pak\DATA\LOCS" python mmp_extractor.py --dir "h:\Games\Steam\steamapps\common\AIM2\Data\mmp.pak\DATA\LOCS" --tex mmp_tex_aim2.txt
python mmp_extractor.py --dir "h:\Games\Steam\steamapps\common\AIM2\Projects" --tex mmp_tex_aim2.txt

View file

@ -17,6 +17,7 @@
*/ */
#include <iostream> #include <iostream>
#include <set>
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
#include <sstream> #include <sstream>
@ -25,28 +26,26 @@
using namespace std; using namespace std;
mmp read_mmp(string fn)
{
buffer b(readFile(fn));
mmp m;
m.load(b);
return m;
}
void process_mmp(mmp &m, string fn)
{
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
try try
{ {
if (argc != 2) if (argc < 2 || argc > 3)
{ {
cout << "Usage:\n" << argv[0] << " file.mmp" << "\n"; cout << "Usage:\n" << argv[0] << " file.mmp [texture_ids.txt]" << "\n";
return 1; return 1;
} }
auto m = read_mmp(argv[1]); mmp m;
process_mmp(m, argv[1]); if (argc > 2)
m.loadTextureNames(argv[2]);
m.load(argv[1]);
m.process();
m.writeFileInfo();
m.writeTexturesList();
m.writeHeightMap();
m.writeTextureMap();
m.writeTextureAlphaMaps();
m.writeTextureMapColored();
m.writeColorMap();
return 0; return 0;
} }
catch (std::exception &e) catch (std::exception &e)

View file

@ -8,17 +8,18 @@ import subprocess
def main(): def main():
parser = argparse.ArgumentParser(description='Batch MMP extractor') parser = argparse.ArgumentParser(description='Batch MMP extractor')
parser.add_argument('--dir', dest='dir', help='path to directory with maps') parser.add_argument('--dir', dest='dir', help='path to directory with maps')
parser.add_argument('--tex', dest='tex', help='path to textures ids')
pargs = parser.parse_args() pargs = parser.parse_args()
if pargs.dir: if pargs.dir:
run(pargs.dir) run(pargs.dir, pargs.tex)
def run(dir): def run(dir, tex):
for file in sorted(os.listdir(dir)): for file in sorted(os.listdir(dir)):
if os.path.isdir(file) or os.path.splitext(file)[1].lower() != ".mmp": if os.path.isdir(file) or os.path.splitext(file)[1].lower() != ".mmp":
continue continue
print('processing: ' + file) print('processing: ' + file)
p = subprocess.Popen(['mmp_extractor.exe', dir + '/' + file]) p = subprocess.Popen(['mmp_extractor.exe', dir + '/' + file, tex])
p.communicate() p.communicate()
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -0,0 +1,328 @@
276 TEX_VERT_12
284 TEX_LAND108
285 TEX_PESOK_8
288 TEX_6_8-2
289 TEX_VERT5
291 TEX_VERT_1
292 TEX_TRAVA-8
293 TEX_16_8
299 TEX_PLITA8
314 TEX_SNOW2_8
321 TEX_SNOW3_8
321 TEX_SNOW3_8
325 TEX_SNOW4_8
345 TEX_SNOW_VERT_1
352 TEX_SNOW_VERT2
428 TEX_ROADS_8
437 TEX_ICE_8
455 TEX_MOH_BROUN_8
493 TEX_BEREG
502 TEX_BEREG_2
511 TEX_GLINA_8_2
520 TEX_LAVA_8_2
523 TEX_PESOK_V_8
532 TEX_BASALT_8
549 TEX_LAVA1_8
558 TEX_LAND_S_8
564 TEX_FUND8
567 TEX_VERT_LAVA_1
576 TEX_LAVA_2_8
585 TEX_VERT_LAVA_2
598 TEX_LAND_BLACK_8
607 TEX_TRAVA-8
616 TEX_SWAMP_8
625 TEX_SWAMP_2_8
634 TEX_LAND_3_8
643 TEX_CRYSTALL_8
652 TEX_ROAD_BROUNE_8
661 TEX_CRYST_8
670 TEX_16_8
690 TEX_6_8-2
699 TEX_LAND_V_8
708 TEX_LAND_V_8
736 TEX_PESOK_8
745 TEX_KORDILYER
785 TEX_PESOK_8
794 TEX_L3_ROAD_8
797 TEX_ROCKLAND_2
824 TEX_TRAVA-8
833 TEX_ROCK_LAND
841 TEX_SWAMP_8
844 TEX_IKRA-8
847 TEX_SNOW_VERT_3
850 TEX_VERT_SNOW_2
853 TEX_VERT_SNOW_3
856 TEX_L4_ROAD_8
859 TEX_TRAVA-8
862 TEX_TRAVA-8
864 TEX_16_8
868 TEX_PESOK_8
908 TEX_VERT_1
914 TEX_PESOK_8
927 TEX_BEREG
933 TEX_GLINA_8_2
943 TEX_L5_DUNA_81
953 TEX_PESOK_8
957 TEX_PESOK_8
960 TEX_PESOK_8
981 TEX_L5_DUNA_81
984 TEX_VERTIKAL
987 TEX_L5_DUNA_81
990 TEX_GLINA_8_2
999 TEX_LAND108
1002 TEX_L5_DUNA_8
1005 TEX_L5_DUNA_81
1014 TEX_L5_STONE_DUNA
1026 TEX_PESOK_8
1034 TEX_L5_DUNA_81
1037 TEX_L5_DUNA_81
1049 TEX_PESOK_8
1052 TEX_L5_ROAD_8
1056 TEX_PESOK_8
1067 TEX_PESOK_8
1070 TEX_PESOK_8
1079 TEX_LAND108
1082 TEX_LAND108
1089 TEX_PESOK_8
1092 TEX_PESOK_8
1095 TEX_BEREG_2
1104 TEX_GLINA_8_2
1110 TEX_LAVA_8_2
1123 TEX_L6_SAND_1
1129 TEX_LAND_V_8
1149 TEX_SWAMP_2_8
1153 TEX_SWAMP_2_8
1159 TEX_SWAMP_2_8
1166 TEX_SWAMP_2_8
1168 TEX_L3_ROAD_8
1171 TEX_SWAMP_2_8
1174 TEX_SWAMP_2_8
1180 TEX_BEREG
1183 TEX_SWAMP_2_8
1186 TEX_GLINA_8_2
1189 TEX_SWAMP_2_8
1198 TEX_SWAMP_2_8
1206 TEX_SWAMP_2_8
1213 TEX_LAND_3_8
1216 TEX_SWAMP_2_8
1225 TEX_L6_SAND_1
1229 TEX_VERTIKAL
1235 TEX_ROCKLAND_2
1245 TEX_BEREG_2
1248 TEX_VERTIKAL
1251 TEX_SWAMP_2_8
1254 TEX_SWAMP_2_8
1256 TEX_CRYST_8
1259 TEX_PLITA_8
1268 TEX_TRAVA
1279 TEX_L3_ROAD_8
1286 TEX_L3_ROAD_8
1292 TEX_SWAMP_2_8
1295 TEX_TRAVA
1299 TEX_L6_SAND_1
1308 TEX_L6_SAND_1
1311 TEX_L6_SAND_1
1316 TEX_L6_SAND_1
1319 TEX_TRAVA
1326 TEX_16_8
1337 TEX_PESOK_8
1340 TEX_PLITA_BLD_8
1343 TEX_L3_ROAD_8
1346 TEX_PLITA_BETON
1355 TEX_PLITA_8
1358 TEX_PESOK_8
1363 TEX_SWAMP_2_8
1371 TEX_SWAMP_2_8
1382 TEX_SWAMP_2_8
1385 TEX_SWAMP_2_8
1400 TEX_SWAMP_2_8
1410 TEX_SWAMP_2_8
1420 TEX_SWAMP_2_8
1423 TEX_SWAMP_2_8
1432 TEX_MOH_BROUN_8
1438 TEX_SWAMP_2_8
1440 TEX_SWAMP_2_8
1444 TEX_SWAMP_2_8
1447 TEX_GLINA_8_2
1458 TEX_SWAMP_2_8
1469 TEX_SWAMP_2_8
1472 TEX_SWAMP_2_8
1475 TEX_GLINA_8_2
1484 TEX_SWAMP_2_8
1488 TEX_SWAMP_2_8
1493 TEX_SWAMP_2_8
1504 TEX_GLINA_8_2
1510 TEX_SWAMP_2_8
1513 TEX_MOH_BROUN_8
1522 TEX_BASALT_8
1528 TEX_BASALT_8
1531 TEX_MAGMA_8
1543 TEX_LAVA_2_8
1552 TEX_LAVA1_8
1558 TEX_LAND_S_8
1569 TEX_PLITA_BETON
1575 TEX_CRYSTALL_8
1584 TEX_SWAMP_2_8
1589 TEX_SWAMP_2_8
1598 TEX_SWAMP_2_8
1601 TEX_LAVA_2_8
1604 TEX_SWAMP_2_8
1607 TEX_SWAMP_2_8
1610 TEX_L4_PROVAL_8
1613 TEX_L4_FLASH
1615 TEX_SWAMP_2_8
1618 TEX_GLINA_8_2
1621 TEX_SWAMP_2_8
1626 TEX_SWAMP_2_8
1632 TEX_SWAMP_2_8
1643 TEX_L7_MOUTH
1646 TEX_SNOW_VERT_3
1649 TEX_CRYSTALL_8
1661 TEX_L4_LAVA_STONE_8
1664 TEX_L8_KORNI_8
1669 TEX_SWAMP_2_8
1673 TEX_L8_PIMPLE_8
1676 TEX_L8_PIMPLE_VIOLET_8
1686 TEX_CRYSTALL_8
1689 TEX_L8_PIMPLE_ORANGE_8
1698 TEX_VERT_LAVA_1
1701 TEX_L8_ROCKS
1704 TEX_L8_KORNI_8
1713 TEX_L8_PIMPLE_8
1719 TEX_L8_PIMPLE_ORANGE_8
1721 TEX_L8_PIMPLE_ORANGE_8
1724 TEX_L8_PIMPLE_VIOLET_8
1727 TEX_L8_ROOTS_8
1730 TEX_SWAMP_2_8
1733 TEX_L8_FLESH_8
1736 TEX_L8_MOULD_ROCK
1739 TEX_PESOK_8
1742 TEX_L8_ROCKS_2
1745 TEX_L8_BOWELS
1748 TEX_16_8
1758 TEX_SWAMP_2_8
1768 TEX_L6_ROAD_90_8
1771 TEX_L6_ROAD_45_8
1775 TEX_L6_ROAD_FD_8
1782 TEX_L6_SAND_1
1793 TEX_PESOK_8
1801 TEX_PESOK_8
1803 TEX_L6_SAND_1
1806 TEX_SWAMP_2_8
1809 TEX_L8_BOWELS_2
1819 TEX_SWAMP_2_8
1829 TEX_SWAMP_2_8
1831 TEX_BEREG_2
1836 TEX_SWAMP_2_8
1839 TEX_TRAVA_8_ALT
1842 TEX_SWAMP_2_8
1845 TEX_LAND_3_8
1848 TEX_SWAMP_2_8
1859 TEX_L3_ROCKS_V
1870 TEX_L5_STONE_DUNE_G_8
1879 TEX_L6_SAND_1
1885 TEX_L6_SAND_1
1888 TEX_L6_SAND_CLIFF
1891 TEX_METAL_WALL
1894 TEX_METAL_WALL_2
1903 TEX_METAL_GORIZ_8
1906 TEX_METAL_RELS_8
1909 TEX_METAL_RELS_2_8
1920 TEX_L5_BIGWORM_V
1926 TEX_PLITA_8
1937 TEX_PESOK_8
1941 TEX_SWAMP_2_8
1952 TEX_TRAVA
1955 TEX_SWAMP_2_8
1959 TEX_SWAMP_2_8
1967 TEX_SWAMP_2_8
1974 TEX_SWAMP_2_8
1980 TEX_SWAMP_2_8
1987 TEX_SWAMP_2_8
1991 TEX_L6_SAND_1
1995 TEX_SWAMP_2_8
1999 TEX_L6_SAND_1
2010 TEX_L6_SAND_1
2014 TEX_PLITA8
2024 TEX_PESOK_8
2029 TEX_SNOW3_8
2034 TEX_ROADS_8
2040 TEX_SNOW4_8
2044 TEX_SNOW2_8
2050 TEX_L3_ROCKS_V
2055 TEX_SNOW4_8
2061 TEX_ICE_8
2065 TEX_ICE_8
2070 TEX_ICE_8
2074 TEX_LAND_3_8
2076 TEX_LAND_3_8
2082 TEX_LAND_3_8
2091 TEX_L3_ROCKS_V
2101 TEX_VERT_SNOW_3
2108 TEX_LAND_3_8
2113 TEX_L6_SAND_1
2123 TEX_SWAMP_2_8
2127 TEX_L6_SAND_1
2133 TEX_L6_STONES
2140 TEX_L6_STONES
2151 TEX_PESOK_8
2155 TEX_SNOW4_8
2158 TEX_SWAMP_2_8
2163 TEX_SNOW4_8
2173 TEX_LAVA1_8
2177 TEX_LAVA1_8
2180 TEX_PLITA_BLD_8
2189 TEX_METAL_WALL_2
2195 TEX_METAL_WALL
2197 TEX_METAL_GORIZ_8
2208 TEX_UG_LOW_WALL_GENERAL_8
2214 TEX_UG_PIPE_8
2224 TEX_UG_RAIL_8
2234 TEX_UG_FLOOR_CONVEYOR_8_V2
2238 TEX_METAL_GORIZ_8
2244 TEX_UG_FLOOR_PANEL_VENT_8
2251 TEX_UG_LOW_WALL_GENERAL_8
2257 TEX_METAL_WALL_2
2260 TEX_UG_FLOOR_CONVEYOR_8
2263 TEX_ROCK_LAND
2272 TEX_MOH_BROUN_8
2278 TEX_UG_LOW_WALL_GENERAL_8
2286 TEX_ROCKLAND_2
2288 TEX__TEST
2292 TEX_ROCKLAND_2
2300 TEX_L6_SAND_CLIFF
2305 TEX_SWAMP_2_8
2318 TEX_VERT_LAVA_2
2321 TEX_LDM_SAND
2336 TEX_LDM_SAND
2345 TEX_L6_SAND_CLIFF
2351 TEX_LDM_SAND
2353 TEX_MAGMA_8
2364 TEX_LDM_SAND
2370 TEX_LAND_3_8
2380 TEX_LAND_3_8
2383 TEX_L6_STONES
2386 TEX_SWAMP_2_8
2389 TEX_SWAMP_2_8
2393 TEX_L5_ROAD2_8
2400 TEX_VERT_LAVA_2
2407 TEX_L3_ROCKS_V
2412 TEX_L6_SAND_CLIFF
2414 TEX_SNOW2_8
2422 TEX_SWAMP_2_8
2422 TEX_SWAMP_2_8
2425 TEX_SNOW_VERT2
2428 TEX_L6_SAND_CLIFF
2428 TEX_L6_SAND_CLIFF
2434 TEX_CRYST_8
2437 TEX_MOH_BROUN_8
2437 TEX_MOH_BROUN_8
2443 TEX_LAND108
2443 TEX_LAND108
2453 TEX_LAND108
2456 TEX_L6_ROAD_90_8
2456 TEX_L6_ROAD_90_8
2464 TEX_MOH_BROUN_8
2464 TEX_MOH_BROUN_8
2467 TEX_METAL_GORIZ_8
2467 TEX_METAL_GORIZ_8

View file

@ -0,0 +1,485 @@
276 TEX_VERT_12
284 TEX_LAND108
285 TEX_PESOK_8
288 TEX_6_8-2
289 TEX_VERT5
291 TEX_L1_CLIFF_SLICK
292 TEX_TRAVA-8
293 TEX_16_8
299 TEX_PLITA8
314 TEX_SNOW2_8
321 TEX_SNOW3_8
321 TEX_SNOW3_8
325 TEX_SNOW4_8
345 TEX_SNOW_VERT_1
352 TEX_SNOW_VERT2
428 TEX_ROADS_8
437 TEX_ICE_8
455 TEX_MOH_BROUN_8
493 TEX_BEREG
502 TEX_BEREG_2
511 TEX_GLINA_8_2
520 TEX_LAVA_8_2
523 TEX_PESOK_V_8
532 TEX_BASALT_8
549 TEX_LAVA1_8
558 TEX_LAND_S_8
564 TEX_FUND8
567 TEX_VERT_LAVA_1
576 TEX_LAVA_2_8
585 TEX_VERT_LAVA_2
598 TEX_LAND_BLACK_8
607 TEX_TRAVA-8
616 TEX_SWAMP_8
625 TEX_SWAMP_2_8
634 TEX_LAND_3_8
643 TEX_CRYSTALL_8
652 TEX_ROAD_BROUNE_8
661 TEX_CRYST_8
670 TEX_16_8
690 TEX_6_8-2
699 TEX_LAND_V_8
708 TEX_LAND_V_8
736 TEX_PESOK_8
745 TEX_KORDILYER
785 TEX_PESOK_8
794 TEX_L3_ROAD_8
797 TEX_ROCKLAND_2
824 TEX_TRAVA-8
833 TEX_ROCK_LAND
841 TEX_SWAMP_8
844 TEX_IKRA-8
847 TEX_SNOW_VERT_3
850 TEX_VERT_SNOW_2
853 TEX_VERT_SNOW_3
856 TEX_L4_ROAD_8
859 TEX_TRAVA-8
862 TEX_TRAVA-8
864 TEX_16_8
868 TEX_PESOK_8
908 TEX_VERT_1
914 TEX_PESOK_8
927 TEX_L2_RIVERBANK
933 TEX_GLINA_8_2
943 TEX_L5_DUNA_81
953 TEX_PESOK_8
957 TEX_PESOK_8
960 TEX_PESOK_8
981 TEX_L5_DUNA_81
984 TEX_VERTIKAL
987 TEX_L5_DUNA_81
990 TEX_GLINA_8_2
999 TEX_LAND108
1002 TEX_L5_DUNA_8
1005 TEX_L5_DUNA_81
1014 TEX_L5_STONE_DUNA
1026 TEX_PESOK_8
1034 TEX_L5_DUNA_81
1037 TEX_L5_DUNA_81
1049 TEX_PESOK_8
1052 TEX_L5_ROAD_8
1056 TEX_PESOK_8
1067 TEX_PESOK_8
1070 TEX_PESOK_8
1079 TEX_LAND108
1082 TEX_LAND108
1089 TEX_PESOK_8
1092 TEX_PESOK_8
1095 TEX_L2_SAND_GULLY_02
1104 TEX_GLINA_8_2
1110 TEX_LAVA_8_2
1123 TEX_L6_SAND_1
1129 TEX_LAND_V_8
1149 TEX_SWAMP_2_8
1153 TEX_SWAMP_2_8
1159 TEX_SWAMP_2_8
1166 TEX_SWAMP_2_8
1168 TEX_L3_ROAD_8
1171 TEX_SWAMP_2_8
1174 TEX_SWAMP_2_8
1180 TEX_BEREG
1183 TEX_SWAMP_2_8
1186 TEX_GLINA_8_2
1189 TEX_SWAMP_2_8
1198 TEX_SWAMP_2_8
1206 TEX_SWAMP_2_8
1213 TEX_LAND_3_8
1216 TEX_SWAMP_2_8
1225 TEX_L6_SAND_1
1229 TEX_VERTIKAL
1235 TEX_ROCKLAND_2
1245 TEX_L2_SAND_GULLY_01_2
1248 TEX_VERTIKAL
1251 TEX_SWAMP_2_8
1254 TEX_SWAMP_2_8
1256 TEX_CRYST_8
1259 TEX_PLITA_8
1268 TEX_TRAVA
1279 TEX_L3_ROAD_8
1286 TEX_L3_ROAD_8
1292 TEX_SWAMP_2_8
1295 TEX_TRAVA
1299 TEX_L6_SAND_1
1308 TEX_L6_SAND_1
1311 TEX_L6_SAND_1
1316 TEX_L6_SAND_1
1319 TEX_TRAVA
1326 TEX_16_8
1337 TEX_PESOK_8
1340 TEX_PLITA_BLD_8
1343 TEX_L3_ROAD_8
1346 TEX_PLITA_BETON
1355 TEX_PLITA_8
1358 TEX_PESOK_8
1363 TEX_SWAMP_2_8
1371 TEX_SWAMP_2_8
1382 TEX_SWAMP_2_8
1385 TEX_SWAMP_2_8
1400 TEX_SWAMP_2_8
1410 TEX_SWAMP_2_8
1420 TEX_SWAMP_2_8
1423 TEX_SWAMP_2_8
1432 TEX_MOH_BROUN_8
1438 TEX_SWAMP_2_8
1440 TEX_SWAMP_2_8
1444 TEX_SWAMP_2_8
1447 TEX_GLINA_8_2
1458 TEX_SWAMP_2_8
1469 TEX_SWAMP_2_8
1472 TEX_SWAMP_2_8
1475 TEX_GLINA_8_2
1484 TEX_SWAMP_2_8
1488 TEX_SWAMP_2_8
1493 TEX_SWAMP_2_8
1504 TEX_GLINA_8_2
1510 TEX_SWAMP_2_8
1513 TEX_MOH_BROUN_8
1522 TEX_BASALT_8
1528 TEX_BASALT_8
1531 TEX_MAGMA_8
1543 TEX_LAVA_2_8
1552 TEX_LAVA1_8
1558 TEX_LAND_S_8
1569 TEX_PLITA_BETON
1575 TEX_CRYSTALL_8
1584 TEX_SWAMP_2_8
1589 TEX_SWAMP_2_8
1598 TEX_SWAMP_2_8
1601 TEX_LAVA_2_8
1604 TEX_SWAMP_2_8
1607 TEX_SWAMP_2_8
1610 TEX_L4_PROVAL_8
1613 TEX_L4_FLASH
1615 TEX_SWAMP_2_8
1618 TEX_GLINA_8_2
1621 TEX_SWAMP_2_8
1626 TEX_SWAMP_2_8
1632 TEX_SWAMP_2_8
1643 TEX_L7_MOUTH
1646 TEX_SNOW_VERT_3
1649 TEX_CRYSTALL_8
1661 TEX_L4_LAVA_STONE_8
1664 TEX_L8_KORNI_8
1669 TEX_SWAMP_2_8
1673 TEX_L8_PIMPLE_8
1676 TEX_L8_PIMPLE_VIOLET_8
1686 TEX_CRYSTALL_8
1689 TEX_L8_PIMPLE_ORANGE_8
1698 TEX_VERT_LAVA_1
1701 TEX_L8_ROCKS
1704 TEX_L8_KORNI_8
1713 TEX_L8_PIMPLE_8
1719 TEX_L8_PIMPLE_ORANGE_8
1721 TEX_L8_PIMPLE_ORANGE_8
1724 TEX_L8_PIMPLE_VIOLET_8
1727 TEX_L8_ROOTS_8
1730 TEX_SWAMP_2_8
1733 TEX_L8_FLESH_8
1736 TEX_L8_MOULD_ROCK
1739 TEX_PESOK_8
1742 TEX_L8_ROCKS_2
1745 TEX_L8_BOWELS
1748 TEX_16_8
1758 TEX_SWAMP_2_8
1768 TEX_L6_ROAD_90_8
1771 TEX_L6_ROAD_45_8
1775 TEX_L6_ROAD_FD_8
1782 TEX_L6_SAND_1
1793 TEX_PESOK_8
1801 TEX_PESOK_8
1803 TEX_L6_SAND_1
1806 TEX_SWAMP_2_8
1809 TEX_L8_BOWELS_2
1819 TEX_SWAMP_2_8
1829 TEX_SWAMP_2_8
1831 TEX_BEREG_2
1836 TEX_SWAMP_2_8
1839 TEX_TRAVA_8_ALT
1842 TEX_SWAMP_2_8
1845 TEX_LAND_3_8
1848 TEX_SWAMP_2_8
1859 TEX_L3_ROCKS_V
1870 TEX_L5_STONE_DUNE_G_8
1879 TEX_L6_SAND_1
1885 TEX_L6_SAND_1
1888 TEX_L6_SAND_CLIFF
1891 TEX_METAL_WALL
1894 TEX_METAL_WALL_2
1903 TEX_METAL_GORIZ_8
1906 TEX_METAL_RELS_8
1909 TEX_METAL_RELS_2_8
1920 TEX_L5_BIGWORM_V
1926 TEX_PLITA_8
1937 TEX_PESOK_8
1941 TEX_SWAMP_2_8
1952 TEX_TRAVA
1955 TEX_SWAMP_2_8
1959 TEX_SWAMP_2_8
1967 TEX_SWAMP_2_8
1974 TEX_SWAMP_2_8
1980 TEX_SWAMP_2_8
1987 TEX_SWAMP_2_8
1991 TEX_L6_SAND_1
1995 TEX_SWAMP_2_8
1999 TEX_L6_SAND_1
2010 TEX_L6_SAND_1
2014 TEX_PLITA8
2024 TEX_PESOK_8
2029 TEX_SNOW3_8
2034 TEX_ROADS_8
2040 TEX_SNOW4_8
2044 TEX_SNOW2_8
2050 TEX_L3_ROCKS_V
2055 TEX_SNOW4_8
2061 TEX_ICE_8
2065 TEX_ICE_8
2070 TEX_ICE_8
2074 TEX_LAND_3_8
2076 TEX_LAND_3_8
2082 TEX_LAND_3_8
2091 TEX_L3_ROCKS_V
2101 TEX_VERT_SNOW_3
2108 TEX_LAND_3_8
2113 TEX_L6_SAND_1
2123 TEX_SWAMP_2_8
2127 TEX_L6_SAND_1
2133 TEX_L6_STONES
2140 TEX_L6_STONES
2151 TEX_PESOK_8
2155 TEX_SNOW4_8
2158 TEX_SWAMP_2_8
2163 TEX_SNOW4_8
2173 TEX_LAVA1_8
2177 TEX_LAVA1_8
2180 TEX_PLITA_BLD
2189 TEX_METAL_WALL_2
2195 TEX_METAL_WALL
2197 TEX_METAL_GORIZ_8
2208 TEX_UG_LOW_WALL_GENERAL
2214 TEX_UG_PIPE_8
2224 TEX_UG_RAIL_8
2234 TEX_UG_FLOOR_CONVEYOR_8_V2
2238 TEX_METAL_GORIZ
2244 TEX_UG_FLOOR_PANEL_VENT_8
2251 TEX_UG_LOW_WALL_GENERAL_8
2257 TEX_METAL_WALL_2
2260 TEX_UG_FLOOR_CONVEYOR_8
2263 TEX_ROCK_LAND
2272 TEX_MOH_BROUN_8
2278 TEX_UG_LOW_WALL_GENERAL_8
2286 TEX_ROCKLAND_2
2288 TEX__TEST
2292 TEX_ROCKLAND_2
2300 TEX_L6_SAND_CLIFF
2305 TEX_SWAMP_2_8
2318 TEX_VERT_LAVA_2
2321 TEX_LDM_SAND
2336 TEX_LDM_SAND
2345 TEX_L6_SAND_CLIFF
2351 TEX_LDM_SAND
2353 TEX_MAGMA_8
2364 TEX_LDM_SAND
2370 TEX_LAND_3_8
2380 TEX_LAND_3_8
2383 TEX_L6_STONES
2386 TEX_SWAMP_2_8
2389 TEX_SWAMP_2_8
2393 TEX_L5_ROAD2_8
2400 TEX_VERT_LAVA_2
2407 TEX_L3_ROCKS_V
2412 TEX_L6_SAND_CLIFF
2414 TEX_SNOW2_8
2422 TEX_SWAMP_2_8
2425 TEX_SNOW_VERT2
2428 TEX_L6_SAND_CLIFF
2437 TEX_MOH_BROUN_8
2443 TEX_LAND108
2453 TEX_LAND108
2456 TEX_L6_ROAD_90_8
2464 TEX_MOH_BROUN_8
2467 TEX_METAL_GORIZ_8
2470 TEX_L9_GROUND_BROWN_8
2473 TEX_L9_GROUND_STONES_2_8
2482 TEX_L9_GROUND_8
2488 TEX_L9_GROUND_STONES_8
2490 TEX_L9_GROUND_STONES_2_8
2501 TEX_L9_SAND_8
2507 TEX_L9_SAND_2_8
2517 TEX_L9_CLIFF_LAYERED
2520 TEX_L9_CLIFF_CRACKS
2529 TEX_L9_CLIFF_CRACKS_2
2535 TEX_L9_CLIFF
2538 TEX_L10_GROUND_8
2547 TEX_L10_ROCKS_8
2553 TEX_L10_CLIFF_STRIPES
2555 TEX_L10_CLIFF
2558 TEX_L9_CLIFF
2567 TEX_L10_CLIFF_CANYON
2573 TEX_L10_LAVA_1
2575 TEX_L9_SAND_8
2586 TEX_L10_GRASS_8
2592 TEX_L10_CLIFF_CANYON_2
2598 TEX_L10_ROAD_1_S8
2604 TEX_L9_GROUND_BROWN_8
2609 TEX_L9_SAND_8
2617 TEX_L9_SAND_2_8
2620 TEX_L9_GROUND_8
2627 TEX_L9_GROUND_8
2632 TEX_L9_SAND_8
2640 TEX_L9_SAND_8
2651 TEX_L9_SAND_8
2656 TEX_L9_SAND_8
2658 TEX_L10_GROUND_8
2662 TEX_L10_GROUND_8
2673 TEX_L10_GRASS_8
2678 TEX_L10_ROCKS_8
2680 TEX_PLITA_BLD_8
2683 TEX_U_FLOOR_BROWN_S1
2692 TEX_U_FLOOR_CONCRETE_S4
2698 TEX_U_FLOOR_CROSSING_S8
2700 TEX_U_FLOOR_DARK_S8
2711 TEX_U_FLOOR_GRATE_SIMPLE_S1
2717 TEX_U_FLOOR_LIGHT_S8
2720 TEX_U_FLOOR_METAL_SQUARED_S8
2735 TEX_U_FLOOR_WARNING_S1
2737 TEX_U_WALL_BLOCKS
2748 TEX_U_WALL_BLOCKS_STRIPE
2754 TEX_U_WALL_BLOCKS_WARN
2764 TEX_U_WALL_FRAMES
2774 TEX_U_WALL_FRAMES_CROSS
2778 TEX_U_WALL_HOLES
2784 TEX_U_WALL_METAL_EDGES
2791 TEX_U_WALL_METAL_EDGES_CORR
2798 TEX_U_WALL_METAL_PLATES
2801 TEX_U_WALL_PATCHY_1
2810 TEX_U_WALL_PATCHY_2
2813 TEX_U_WALL_PATCHY_3
2816 TEX_U_WALL_PLATED_2
2823 TEX_U_WALL_PLATED_SIMPLE
2827 TEX_U_WALL_SCALES
2836 TEX_U_WALL_STRIPS_PLASTIC
2844 TEX_U_WALL_STRIPS_PLASTIC_2
2847 TEX_U_WALL_VENTS
2853 TEX_U_WALL_METAL_HOLES
2855 TEX_U_FLOOR_PATCHY_RAIL
2858 TEX_U_FLOOR_PANEL_VENT_RUST_S4
2867 TEX_U_FLOOR_PATCHY_FRAME_S4
2870 TEX_U_FLOOR_PATCHY_S8
2873 TEX_U_FLOOR_METAL
2882 TEX_L11_LICHEN_S1
2885 TEX_L11_LICHEN_2
2894 TEX_L11_MOULD_S4
2900 TEX_L11_PLATEU_2_S4
2902 TEX_L11_PLATEU_3_S1
2913 TEX_L11_PLATEU_4_S1
2919 TEX_L11_PLATEU_GRASS_S4
2929 TEX_L11_PLATEU_PL_S4
2939 TEX_L11_ROCK
2943 TEX_L11_ROCK2
2949 TEX_L11_ROCK3
2956 TEX_L11_ROCK4
2963 TEX_L11_MUSHROOM_BASE
2966 TEX_U_WALL_CONCRETE
2969 TEX_L12_CAVE_SLICK
2978 TEX_L12_CAVE_HARD
2984 TEX_L11_ROCK3
2987 TEX_L10_GROUND_8
2996 TEX_MOH_BROUN_8
2998 TEX_U_WALL_CONCRETE
3001 TEX_U_LIGHT_WHITE
3010 TEX_U_BORDER_PIPES
3028 TEX_L9_GROUND_BROWN_8
3034 TEX_L9_CLIFF
3042 TEX_L9_SAND_8
3047 TEX_L9_SAND_8
3057 TEX_L9_HIGHWAY_WALL
3060 TEX_L9_METAL_PLATES
3069 TEX_L9_WALL_RUSTY
3072 TEX_CANYON01
3076 TEX_L10_CLIFF
3083 TEX_L10_LAVA_1
3094 TEX_SWAMP_2_8
3099 TEX_PESOK_8
3110 TEX_GLINA_8_2
3113 TEX_VERT5
3122 TEX__TEST
3131 TEX_L10_GROUND_8
3134 TEX_L10_CRATER
3140 TEX_U_FLOOR_CLIMB_90
3143 TEX_VERT_LAVA_1
3152 TEX_L4_PROVAL_8
3160 TEX_L9_SAND_2_8
3173 TEX_L10_CLIFF_MIX
3181 TEX_L1_CLIFF_CANYON
3189 TEX_L1_CLIFF_HARD
3197 TEX_L1_CLIFF_HARD_2
3200 TEX_L10_ROAD_M2
3208 TEX_L10_ROAD_M2
3212 TEX_SNOW4_8
3217 TEX_LD_ROAD
3221 TEX_PLITA_8
3226 TEX_L9_SAND_8
3233 TEX_SWAMP_2_8
3238 TEX_L4_PROVAL_8
3246 TEX_GLINA_8_2
3252 TEX_L10_ROCKS_8
3260 TEX_L10_ROCKS_8
3262 TEX_L10_CLIFF_STRIPES
3270 TEX_L9_SAND_2_8
3278 TEX_L9_SAND_8
3281 TEX_L10_GROUND_8
3292 TEX_L11_LICHEN_2
3297 TEX_L11_PLATEU_4_S1
3307 TEX_L10_LAVA_1
3317 TEX_L10_CLIFF
3323 TEX_SWAMP_2_8
3330 TEX_L11_VEINS_S4
3341 TEX_L11_VEINS_S4
3350 TEX_L11_VEINS_S4
3361 TEX_L11_GROUND_SKIN_4
3367 TEX_L4_LAVA_STONE_8
3369 TEX_U_WALL_PLATED_SIMPLE
3379 TEX_U_WALL_PLATED_SIMPLE
3390 TEX_U_FLOOR_WARNING_S1
3398 TEX_U_FLOOR_CLIMB_90
3402 TEX_U_FLOOR_LIGHT_S8
3412 TEX_L2_RIVERBANK_2
3419 TEX_GLINA_8_2
3424 TEX_SWAMP_2_8
3434 TEX_SWAMP_2_8
3437 TEX_SWAMP_2_8
3445 TEX_L10_GRASS_8
3454 TEX_L11_GROUND_MEAT_4
3466 TEX_L11_GROUND_SPONGE_8
3474 TEX_L11_VEINS_S4
3489 TEX_L11_SOUP_4
3500 TEX_L11_CLIFF_SKIN
3510 TEX_L11_TONGUE_S4
3519 TEX_L11_PLATEU_3_S1
3523 TEX_L11_ROCK4
3532 TEX_L11_GROUND_SPONGE_8
3543 TEX_U_FLOOR_PATCHY_RG
3552 TEX_SWAMP_2_8
3562 TEX_U_WALL_PLATED_SNOW
3570 TEX_U_FLOOR_LIGHT_S8_SNOW
3576 TEX_L11_GROUND_SPONGE_8