mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-14 17:33:25 +00:00
Add tga writer.
This commit is contained in:
parent
79bf2cc606
commit
0fdf743260
5 changed files with 137 additions and 55 deletions
|
|
@ -23,6 +23,7 @@
|
|||
#include <vector>
|
||||
|
||||
#include <bmp.h>
|
||||
#include <tga.h>
|
||||
|
||||
template <class T>
|
||||
class mat
|
||||
|
|
@ -93,3 +94,23 @@ void write_mat_bmp(const std::string &filename, const mat<T> &m)
|
|||
fwrite(&m(0, 0), m.size() * sizeof(T), 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void write_mat_tga(const std::string &filename, const mat<T> &m)
|
||||
{
|
||||
FILE *f = fopen(filename.c_str(), "wb");
|
||||
if (f == nullptr)
|
||||
return;
|
||||
|
||||
tga t;
|
||||
t.width = m.getWidth();
|
||||
t.height = m.getHeight();
|
||||
|
||||
// header
|
||||
fwrite(&t, sizeof(tga), 1, f);
|
||||
fwrite(t.label(), t.idlength, 1, f);
|
||||
|
||||
// data
|
||||
fwrite(&m(0, 0), m.size() * sizeof(T), 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
|
|
|||
52
src/common/tga.h
Normal file
52
src/common/tga.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "buffer.h"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
// http://paulbourke.net/dataformats/tga/
|
||||
struct tga
|
||||
{
|
||||
uint8_t idlength; // label length
|
||||
uint8_t colourmaptype = 0;
|
||||
uint8_t datatypecode = 2;
|
||||
uint16_t colourmaporigin = 0;
|
||||
uint16_t colourmaplength = 0;
|
||||
uint8_t colourmapdepth = 0;
|
||||
uint16_t x_origin = 0;
|
||||
uint16_t y_origin = 0;
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
uint8_t bitsperpixel = 32;
|
||||
uint8_t imagedescriptor = 0x28;
|
||||
|
||||
tga()
|
||||
{
|
||||
idlength = strlen(label());
|
||||
}
|
||||
constexpr const char *label() const
|
||||
{
|
||||
return "AIMTMConverter";
|
||||
}
|
||||
|
||||
void write(buffer &b)
|
||||
{
|
||||
b.write(idlength);
|
||||
b.write(colourmaptype);
|
||||
b.write(datatypecode);
|
||||
b.write(colourmaporigin);
|
||||
b.write(colourmaplength);
|
||||
b.write(colourmapdepth);
|
||||
b.write(x_origin);
|
||||
b.write(y_origin);
|
||||
b.write(width);
|
||||
b.write(height);
|
||||
b.write(bitsperpixel);
|
||||
b.write(imagedescriptor);
|
||||
b.write(label(), idlength);
|
||||
}
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
|
@ -36,14 +36,13 @@
|
|||
#include <types.h>
|
||||
|
||||
#define RAD2GRAD(x) (x) = (x) / M_PI * 180.0
|
||||
|
||||
using namespace std;
|
||||
#define ASSIGN(x, d) isnan(x) ? d : x
|
||||
|
||||
std::string prefix;
|
||||
|
||||
struct storage
|
||||
{
|
||||
string name;
|
||||
std::string name;
|
||||
Objects objects;
|
||||
MechGroups mechGroups;
|
||||
MapGoods mapGoods;
|
||||
|
|
@ -74,14 +73,14 @@ struct storage
|
|||
|
||||
if (!b.eof())
|
||||
{
|
||||
stringstream ss;
|
||||
ss << hex << b.index() << " != " << hex << b.size();
|
||||
std::stringstream ss;
|
||||
ss << std::hex << b.index() << " != " << std::hex << b.size();
|
||||
throw std::logic_error(ss.str());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
storage read_mmo(string fn)
|
||||
storage read_mmo(std::string fn)
|
||||
{
|
||||
buffer f(readFile(fn));
|
||||
storage s;
|
||||
|
|
@ -90,7 +89,7 @@ storage read_mmo(string fn)
|
|||
return s;
|
||||
}
|
||||
|
||||
void write_mmo(string db, const storage &s)
|
||||
void write_mmo(std::string db, const storage &s)
|
||||
{
|
||||
using namespace polygon4;
|
||||
using namespace polygon4::detail;
|
||||
|
|
@ -104,12 +103,12 @@ void write_mmo(string db, const storage &s)
|
|||
auto p2 = s.name.rfind('/');
|
||||
if (p2 == -1)
|
||||
p2 = 0;
|
||||
int p = max(p1, p2);
|
||||
string map_name = s.name.substr(p + 1);
|
||||
int p = std::max(p1, p2);
|
||||
std::string map_name = s.name.substr(p + 1);
|
||||
map_name = map_name.substr(0, map_name.find('.'));
|
||||
if (!prefix.empty())
|
||||
map_name = prefix + "." + map_name;
|
||||
transform(map_name.begin(), map_name.end(), map_name.begin(), ::tolower);
|
||||
std::transform(map_name.begin(), map_name.end(), map_name.begin(), ::tolower);
|
||||
|
||||
int map_id = 0;
|
||||
for (auto &m : storage->maps)
|
||||
|
|
@ -129,19 +128,21 @@ void write_mmo(string db, const storage &s)
|
|||
|
||||
auto this_map = storage->maps[map_id];
|
||||
|
||||
int inserted = 0;
|
||||
int exist = 0;
|
||||
for (auto &seg : s.objects.segments)
|
||||
{
|
||||
if (seg->segment_type == ObjectType::BUILDING ||
|
||||
seg->segment_type == ObjectType::TOWER)
|
||||
{
|
||||
SegmentObjects<::MapObject> *segment = (SegmentObjects<::MapObject> *)seg;
|
||||
set<string> objs;
|
||||
std::map<string, int> bld_ids;
|
||||
std::set<std::string> objs;
|
||||
std::map<std::string, int> bld_ids;
|
||||
for (auto &object : segment->objects)
|
||||
objs.insert(object->name1);
|
||||
for (auto &o : objs)
|
||||
{
|
||||
auto iter = find_if(storage->buildings.begin(), storage->buildings.end(), [&](const auto &p)
|
||||
auto iter = std::find_if(storage->buildings.begin(), storage->buildings.end(), [&](const auto &p)
|
||||
{
|
||||
return p.second->text_id == o;
|
||||
});
|
||||
|
|
@ -152,7 +153,9 @@ void write_mmo(string db, const storage &s)
|
|||
bld_ids[o] = bld->getId();
|
||||
}
|
||||
else
|
||||
{
|
||||
bld_ids[o] = iter->getId();
|
||||
}
|
||||
}
|
||||
for (auto &object : segment->objects)
|
||||
{
|
||||
|
|
@ -160,14 +163,19 @@ void write_mmo(string db, const storage &s)
|
|||
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 = ASSIGN(object->position.x, 0);
|
||||
mb.y = ASSIGN(object->position.y, 0);
|
||||
mb.z = ASSIGN(object->position.z, 0);
|
||||
mb.roll = 0;
|
||||
mb.pitch = 0;
|
||||
mb.yaw = acos(object->m_rotate_z[0].x);
|
||||
auto yaw = ASSIGN(object->m_rotate_z[0].x, 0);
|
||||
if (yaw > 1)
|
||||
yaw = yaw - floor(yaw);
|
||||
if (yaw < -1)
|
||||
yaw = yaw - ceil(yaw);
|
||||
mb.yaw = acos(yaw);
|
||||
RAD2GRAD(mb.yaw);
|
||||
mb.scale = object->m_rotate_z[2].z;
|
||||
mb.scale = ASSIGN(object->m_rotate_z[2].z, 1);
|
||||
auto i = find_if(storage->mapBuildings.begin(), storage->mapBuildings.end(), [&](const auto &p)
|
||||
{
|
||||
return *p.second.get() == mb;
|
||||
|
|
@ -176,7 +184,12 @@ void write_mmo(string db, const storage &s)
|
|||
{
|
||||
auto mb2 = storage->addMapBuilding(storage->maps[map_id].get());
|
||||
mb.setId(mb2->getId());
|
||||
*mb2.ptr = mb;
|
||||
*mb2 = mb;
|
||||
inserted++;
|
||||
}
|
||||
else
|
||||
{
|
||||
exist++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -186,8 +199,8 @@ void write_mmo(string db, const storage &s)
|
|||
seg->segment_type == ObjectType::BOUNDARY)
|
||||
{
|
||||
SegmentObjects<::MapObject> *segment = (SegmentObjects<::MapObject> *)seg;
|
||||
set<string> objs;
|
||||
std::map<string, int> bld_ids;
|
||||
std::set<std::string> objs;
|
||||
std::map<std::string, int> bld_ids;
|
||||
for (auto &object : segment->objects)
|
||||
objs.insert(object->name1);
|
||||
for (auto &o : objs)
|
||||
|
|
@ -211,14 +224,19 @@ void write_mmo(string db, const storage &s)
|
|||
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.x = ASSIGN(object->position.x, 0);
|
||||
mb.y = ASSIGN(object->position.y, 0);
|
||||
mb.z = ASSIGN(object->position.z, 0);
|
||||
mb.roll = 0;
|
||||
mb.pitch = 0;
|
||||
mb.yaw = acos(object->m_rotate_z[0].x);
|
||||
auto yaw = ASSIGN(object->m_rotate_z[0].x, 0);
|
||||
if (yaw > 1)
|
||||
yaw = yaw - floor(yaw);
|
||||
if (yaw < -1)
|
||||
yaw = yaw - ceil(yaw);
|
||||
mb.yaw = acos(yaw);
|
||||
RAD2GRAD(mb.yaw);
|
||||
mb.scale = object->m_rotate_z[2].z;
|
||||
mb.scale = ASSIGN(object->m_rotate_z[2].z, 1);
|
||||
auto i = find_if(storage->mapObjects.begin(), storage->mapObjects.end(), [&](const auto &p)
|
||||
{
|
||||
return *p.second.get() == mb;
|
||||
|
|
@ -227,12 +245,19 @@ void write_mmo(string db, const storage &s)
|
|||
{
|
||||
auto mb2 = storage->addMapObject(storage->maps[map_id].get());
|
||||
mb.setId(mb2->getId());
|
||||
*mb2.ptr = mb;
|
||||
*mb2 = mb;
|
||||
inserted++;
|
||||
}
|
||||
else
|
||||
{
|
||||
exist++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
storage->save();
|
||||
if (inserted)
|
||||
storage->save();
|
||||
std::cout << "inserted: " << inserted << ", exist: " << exist << "\n";
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
|
@ -240,7 +265,7 @@ try
|
|||
{
|
||||
if (argc != 4)
|
||||
{
|
||||
cout << "Usage:\n" << argv[0] << " db.sqlite file.mmo prefix" << "\n";
|
||||
std::cout << "Usage:\n" << argv[0] << " db.sqlite file.mmo prefix" << "\n";
|
||||
return 1;
|
||||
}
|
||||
prefix = argv[3];
|
||||
|
|
|
|||
|
|
@ -121,24 +121,20 @@ catch (std::runtime_error &e)
|
|||
if (silent)
|
||||
return 1;
|
||||
string error;
|
||||
if (argv[1])
|
||||
error += argv[1];
|
||||
error += filename;
|
||||
error += "\n";
|
||||
error += "fatal error: ";
|
||||
error += e.what();
|
||||
error += "\n";
|
||||
if (argv[1])
|
||||
{
|
||||
ofstream ofile(string(argv[1]) + ".error.txt");
|
||||
ofile << error;
|
||||
}
|
||||
ofstream ofile(filename + ".error.txt");
|
||||
ofile << error;
|
||||
return 1;
|
||||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
if (silent)
|
||||
return 1;
|
||||
printf("%s\n", argv[1]);
|
||||
printf("%s\n", filename.c_str());
|
||||
printf("error: %s\n", e.what());
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -146,7 +142,7 @@ catch (...)
|
|||
{
|
||||
if (silent)
|
||||
return 1;
|
||||
printf("%s\n", argv[1]);
|
||||
printf("%s\n", filename.c_str());
|
||||
printf("error: unknown exception\n");
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,27 +61,15 @@ void tm2tga(string fn)
|
|||
d.width = width;
|
||||
d.height = height;
|
||||
d.load_blocks(src);
|
||||
write_mat_bmp(fn + ".bmp", d.unpack_tm());
|
||||
write_mat_tga(fn + ".tga", d.unpack_tm());
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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));
|
||||
tga t;
|
||||
t.width = width;
|
||||
t.height = height;
|
||||
t.write(dst);
|
||||
|
||||
convert_simple(dst, src, width, height);
|
||||
transform(fn.begin(), fn.end(), fn.begin(), ::tolower);
|
||||
|
|
|
|||
Loading…
Reference in a new issue