mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-15 01:43:25 +00:00
Fix mmp extractor. Add mpj loader. Some fixes in buffer class.
This commit is contained in:
parent
78812b5236
commit
e1e46a3b75
17 changed files with 1106 additions and 505 deletions
|
|
@ -12,6 +12,7 @@ endif()
|
||||||
file(GLOB script2txt_src "script2txt/*")
|
file(GLOB script2txt_src "script2txt/*")
|
||||||
add_executable(script2txt ${script2txt_src})
|
add_executable(script2txt ${script2txt_src})
|
||||||
|
|
||||||
|
|
||||||
if (DATABASE_MANAGER_DIR)
|
if (DATABASE_MANAGER_DIR)
|
||||||
file(GLOB mmm_extractor_src "mmm_extractor/*")
|
file(GLOB mmm_extractor_src "mmm_extractor/*")
|
||||||
add_executable(mmm_extractor ${mmm_extractor_src})
|
add_executable(mmm_extractor ${mmm_extractor_src})
|
||||||
|
|
@ -22,6 +23,7 @@ add_executable(mmo_extractor ${mmo_extractor_src})
|
||||||
target_link_libraries(mmo_extractor DatabaseManager common)
|
target_link_libraries(mmo_extractor DatabaseManager common)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
file(GLOB mmp_extractor_src "mmp_extractor/*")
|
file(GLOB mmp_extractor_src "mmp_extractor/*")
|
||||||
add_executable(mmp_extractor ${mmp_extractor_src})
|
add_executable(mmp_extractor ${mmp_extractor_src})
|
||||||
target_link_libraries(mmp_extractor common)
|
target_link_libraries(mmp_extractor common)
|
||||||
|
|
@ -30,6 +32,10 @@ file(GLOB mod_converter_src "mod_converter/*")
|
||||||
add_executable(mod_converter ${mod_converter_src})
|
add_executable(mod_converter ${mod_converter_src})
|
||||||
target_link_libraries(mod_converter common)
|
target_link_libraries(mod_converter common)
|
||||||
|
|
||||||
|
file(GLOB mpj_loader_src "mpj_loader/*")
|
||||||
|
add_executable(mpj_loader ${mpj_loader_src})
|
||||||
|
target_link_libraries(mpj_loader common)
|
||||||
|
|
||||||
file(GLOB tm_converter_src "tm_converter/*")
|
file(GLOB tm_converter_src "tm_converter/*")
|
||||||
add_executable(tm_converter ${tm_converter_src})
|
add_executable(tm_converter ${tm_converter_src})
|
||||||
target_link_libraries(tm_converter common)
|
target_link_libraries(tm_converter common)
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ buffer::buffer(const std::vector<uint8_t> &buf, uint32_t data_offset)
|
||||||
{
|
{
|
||||||
skip(0);
|
skip(0);
|
||||||
size_ = buf_->size();
|
size_ = buf_->size();
|
||||||
|
end_ = index_ + size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer::buffer(buffer &rhs, uint32_t size)
|
buffer::buffer(buffer &rhs, uint32_t size)
|
||||||
|
|
@ -86,7 +87,8 @@ buffer::buffer(buffer &rhs, uint32_t size)
|
||||||
index_ = rhs.index_;
|
index_ = rhs.index_;
|
||||||
data_offset = rhs.data_offset;
|
data_offset = rhs.data_offset;
|
||||||
ptr = rhs.ptr;
|
ptr = rhs.ptr;
|
||||||
size_ = index_ + size;
|
size_ = size;
|
||||||
|
end_ = index_ + size_;
|
||||||
rhs.skip(size);
|
rhs.skip(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,62 +97,39 @@ buffer::buffer(buffer &rhs, uint32_t size, uint32_t offset)
|
||||||
{
|
{
|
||||||
index_ = offset;
|
index_ = offset;
|
||||||
data_offset = offset;
|
data_offset = offset;
|
||||||
|
size_ = size;
|
||||||
ptr = (uint8_t *)buf_->data() + index_;
|
ptr = (uint8_t *)buf_->data() + index_;
|
||||||
size_ = index_ + size;
|
end_ = index_ + size_;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t buffer::read(void *dst, uint32_t size, bool nothrow) const
|
uint32_t buffer::_read(void *dst, uint32_t size, uint32_t offset) const
|
||||||
{
|
{
|
||||||
if (!buf_)
|
if (!buf_)
|
||||||
throw std::logic_error("buffer: not initialized");
|
throw std::logic_error("buffer: not initialized");
|
||||||
if (index_ >= size_)
|
if (index_ >= end_)
|
||||||
{
|
|
||||||
if (nothrow)
|
|
||||||
return 0;
|
|
||||||
throw std::logic_error("buffer: out of range");
|
throw std::logic_error("buffer: out of range");
|
||||||
}
|
if (index_ + offset + size > end_)
|
||||||
if (index_ + size > size_)
|
throw std::logic_error("buffer: too much data");
|
||||||
{
|
memcpy(dst, buf_->data() + index_ + offset, size);
|
||||||
if (!nothrow)
|
skip(size + offset);
|
||||||
throw std::logic_error("buffer: too much data");
|
|
||||||
size = size_ - index_;
|
|
||||||
}
|
|
||||||
memcpy(dst, buf_->data() + index_, size);
|
|
||||||
skip(size);
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t buffer::readfrom(void *dst, uint32_t size, uint32_t offset, bool nothrow) const
|
uint32_t buffer::_write(const void *src, uint32_t size)
|
||||||
{
|
|
||||||
if (!buf_)
|
|
||||||
throw std::logic_error("buffer: not initialized");
|
|
||||||
if (offset + size > size_)
|
|
||||||
{
|
|
||||||
if (!nothrow)
|
|
||||||
throw std::logic_error("buffer: too much data");
|
|
||||||
size = size_ - offset;
|
|
||||||
}
|
|
||||||
memcpy(dst, buf_->data() + offset, size);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t buffer::write(const void *src, uint32_t size, bool nothrow)
|
|
||||||
{
|
{
|
||||||
if (!buf_)
|
if (!buf_)
|
||||||
{
|
{
|
||||||
buf_ = std::make_shared<std::vector<uint8_t>>(size);
|
buf_ = std::make_shared<std::vector<uint8_t>>(size);
|
||||||
size_ = buf_->size();
|
size_ = buf_->size();
|
||||||
|
end_ = index_ + size_;
|
||||||
}
|
}
|
||||||
if (index_ > size_)
|
if (index_ > end_)
|
||||||
{
|
|
||||||
if (nothrow)
|
|
||||||
return 0;
|
|
||||||
throw std::logic_error("buffer: out of range");
|
throw std::logic_error("buffer: out of range");
|
||||||
}
|
if (index_ + size > end_)
|
||||||
if (index_ + size > size_)
|
|
||||||
{
|
{
|
||||||
buf_->resize(index_ + size);
|
buf_->resize(index_ + size);
|
||||||
size_ = buf_->size();
|
size_ = buf_->size();
|
||||||
|
end_ = index_ + size_;
|
||||||
}
|
}
|
||||||
memcpy((uint8_t *)buf_->data() + index_, src, size);
|
memcpy((uint8_t *)buf_->data() + index_, src, size);
|
||||||
skip(size);
|
skip(size);
|
||||||
|
|
@ -186,7 +165,7 @@ bool buffer::check(int index) const
|
||||||
|
|
||||||
bool buffer::eof() const
|
bool buffer::eof() const
|
||||||
{
|
{
|
||||||
return check(size_);
|
return index_ == end_;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t buffer::index() const
|
uint32_t buffer::index() const
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,9 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#define READ(b, var) b.read(&var, sizeof(var))
|
#define READ(b, var) b.read(&var)
|
||||||
#define READ_NOTHROW(b, var) b.read(&var, sizeof(var), true)
|
|
||||||
#define READ_N(b, var, sz) b.read(&var, sz)
|
#define READ_N(b, var, sz) b.read(&var, sz)
|
||||||
#define WRITE(b, var) b.write(&var, sizeof(var))
|
#define WRITE(b, var) b.write(&var)
|
||||||
|
|
||||||
std::string version();
|
std::string version();
|
||||||
std::vector<uint8_t> readFile(const std::string &fn);
|
std::vector<uint8_t> readFile(const std::string &fn);
|
||||||
|
|
@ -41,13 +40,36 @@ public:
|
||||||
buffer(buffer &rhs, uint32_t size);
|
buffer(buffer &rhs, uint32_t size);
|
||||||
buffer(buffer &rhs, uint32_t size, uint32_t offset);
|
buffer(buffer &rhs, uint32_t size, uint32_t offset);
|
||||||
|
|
||||||
uint32_t read(void *dst, uint32_t size, bool nothrow = false) const;
|
template <typename T>
|
||||||
uint32_t readfrom(void *dst, uint32_t size, uint32_t offset, bool nothrow = false) const;
|
uint32_t read(T *dst) const
|
||||||
uint32_t write(const void *src, uint32_t size, bool nothrow = false);
|
{
|
||||||
|
return _read(dst, sizeof(T), 0);
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
uint32_t read(T *dst, uint32_t size) const
|
||||||
|
{
|
||||||
|
return _read(dst, size * sizeof(T), 0);
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
uint32_t readfrom(T *dst, uint32_t size, uint32_t offset) const
|
||||||
|
{
|
||||||
|
return _read(dst, size * sizeof(T), offset);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
uint32_t write(const T &src)
|
uint32_t write(const T &src)
|
||||||
{
|
{
|
||||||
return write(&src, sizeof(src));
|
return _write(&src, sizeof(T));
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
uint32_t write(const T *src, uint32_t size)
|
||||||
|
{
|
||||||
|
return _write(src, size * sizeof(T));
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
uint32_t write(const T *src)
|
||||||
|
{
|
||||||
|
return _write(src, sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
void seek(uint32_t size) const;
|
void seek(uint32_t size) const;
|
||||||
|
|
@ -66,4 +88,8 @@ private:
|
||||||
mutable uint8_t *ptr = 0;
|
mutable uint8_t *ptr = 0;
|
||||||
mutable uint32_t data_offset = 0;
|
mutable uint32_t data_offset = 0;
|
||||||
mutable uint32_t size_ = 0;
|
mutable uint32_t size_ = 0;
|
||||||
|
uint32_t end_;
|
||||||
|
|
||||||
|
uint32_t _read(void *dst, uint32_t size, uint32_t offset = 0) const;
|
||||||
|
uint32_t _write(const void *src, uint32_t size);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef uint16_t color_rgb565;
|
typedef uint16_t color_rgb565;
|
||||||
|
|
|
||||||
|
|
@ -74,22 +74,22 @@ void write_mat_bmp(const std::string &filename, const mat<T> &m)
|
||||||
return;
|
return;
|
||||||
BITMAPFILEHEADER h = { 0 };
|
BITMAPFILEHEADER h = { 0 };
|
||||||
h.bfType = 0x4D42;
|
h.bfType = 0x4D42;
|
||||||
h.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO) + m.size() * sizeof(T);
|
h.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + m.size() * sizeof(T);
|
||||||
h.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO);
|
h.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
|
||||||
BITMAPINFO i = { 0 };
|
BITMAPINFOHEADER i = { 0 };
|
||||||
i.bmiHeader.biSize = sizeof(i.bmiHeader);
|
i.biSize = sizeof(i);
|
||||||
i.bmiHeader.biWidth = m.getWidth();
|
i.biWidth = m.getWidth();
|
||||||
i.bmiHeader.biHeight = m.getHeight();
|
i.biHeight = m.getHeight();
|
||||||
i.bmiHeader.biPlanes = 1;
|
i.biPlanes = 1;
|
||||||
i.bmiHeader.biBitCount = sizeof(T) * 8;
|
i.biBitCount = sizeof(T) * 8;
|
||||||
i.bmiHeader.biCompression = 0;
|
i.biCompression = 0;
|
||||||
i.bmiHeader.biSizeImage = 0;
|
i.biSizeImage = 0;
|
||||||
i.bmiHeader.biXPelsPerMeter = 0;
|
i.biXPelsPerMeter = 0;
|
||||||
i.bmiHeader.biYPelsPerMeter = 0;
|
i.biYPelsPerMeter = 0;
|
||||||
i.bmiHeader.biClrUsed = 0;
|
i.biClrUsed = 0;
|
||||||
i.bmiHeader.biClrImportant = 0;
|
i.biClrImportant = 0;
|
||||||
fwrite(&h, sizeof(BITMAPFILEHEADER), 1, f);
|
fwrite(&h, sizeof(BITMAPFILEHEADER), 1, f);
|
||||||
fwrite(&i, sizeof(BITMAPINFO), 1, f);
|
fwrite(&i, sizeof(BITMAPINFOHEADER), 1, f);
|
||||||
fwrite(&m(0, 0), m.size() * sizeof(T), 1, f);
|
fwrite(&m(0, 0), m.size() * sizeof(T), 1, f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,55 +20,52 @@
|
||||||
|
|
||||||
Segment *Segment::create_segment(buffer &b)
|
Segment *Segment::create_segment(buffer &b)
|
||||||
{
|
{
|
||||||
SegmentType segment_type;
|
ObjectType segment_type;
|
||||||
READ(b, segment_type);
|
READ(b, segment_type);
|
||||||
|
|
||||||
Segment *segment = 0;
|
Segment *segment = 0;
|
||||||
switch (segment_type)
|
switch (segment_type)
|
||||||
{
|
{
|
||||||
case SegmentType::ROAD:
|
case ObjectType::ROAD:
|
||||||
segment = new SegmentObjects<Road>;
|
segment = new SegmentObjects<Road>;
|
||||||
break;
|
break;
|
||||||
case SegmentType::BUILDING:
|
case ObjectType::BUILDING:
|
||||||
segment = new SegmentObjects<Building>;
|
segment = new SegmentObjects<Building>;
|
||||||
break;
|
break;
|
||||||
case SegmentType::SURFACE:
|
case ObjectType::TREE:
|
||||||
segment = new SegmentObjects<Surface>;
|
segment = new SegmentObjects<Tree>;
|
||||||
break;
|
break;
|
||||||
case SegmentType::STONE:
|
case ObjectType::STONE:
|
||||||
segment = new SegmentObjects<Stone>;
|
segment = new SegmentObjects<Stone>;
|
||||||
break;
|
break;
|
||||||
case SegmentType::HELPER:
|
case ObjectType::HELPER:
|
||||||
segment = new SegmentObjects<Helper>;
|
segment = new SegmentObjects<Helper>;
|
||||||
break;
|
break;
|
||||||
case SegmentType::SHELL:
|
case ObjectType::IMAGE:
|
||||||
segment = new SegmentObjects<Shell>;
|
|
||||||
break;
|
|
||||||
case SegmentType::IMAGE:
|
|
||||||
segment = new SegmentObjects<Image>;
|
segment = new SegmentObjects<Image>;
|
||||||
break;
|
break;
|
||||||
case SegmentType::EXPLOSION:
|
case ObjectType::LAMP:
|
||||||
segment = new SegmentObjects<Explosion>;
|
segment = new SegmentObjects<Lamp>;
|
||||||
break;
|
break;
|
||||||
case SegmentType::SOUND:
|
case ObjectType::SOUND:
|
||||||
segment = new SegmentObjects<Sound>;
|
segment = new SegmentObjects<Sound>;
|
||||||
break;
|
break;
|
||||||
case SegmentType::ANOMALY:
|
case ObjectType::ANOMALY:
|
||||||
segment = new SegmentObjects<Anomaly>;
|
segment = new SegmentObjects<Anomaly>;
|
||||||
break;
|
break;
|
||||||
case SegmentType::TOWER:
|
case ObjectType::TOWER:
|
||||||
segment = new SegmentObjects<Tower>;
|
segment = new SegmentObjects<Tower>;
|
||||||
break;
|
break;
|
||||||
case SegmentType::BOUNDARY:
|
case ObjectType::BOUNDARY:
|
||||||
segment = new SegmentObjects<Boundary>;
|
segment = new SegmentObjects<Boundary>;
|
||||||
break;
|
break;
|
||||||
case SegmentType::GOODS:
|
case ObjectType::SOUND_ZONE:
|
||||||
segment = new SegmentObjects<Goods>;
|
|
||||||
break;
|
|
||||||
case SegmentType::SOUND_ZONE:
|
|
||||||
segment = new SegmentObjects<SoundZone>;
|
segment = new SegmentObjects<SoundZone>;
|
||||||
break;
|
break;
|
||||||
case SegmentType::unk1:
|
case ObjectType::unk0:
|
||||||
|
segment = new SegmentObjects<unk0>;
|
||||||
|
break;
|
||||||
|
case ObjectType::unk1:
|
||||||
segment = new SegmentObjects<unk1>;
|
segment = new SegmentObjects<unk1>;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
@ -24,49 +24,49 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <buffer.h>
|
#include "buffer.h"
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
using namespace std;
|
enum class ObjectType : uint32_t
|
||||||
|
|
||||||
enum class SegmentType : uint32_t
|
|
||||||
{
|
{
|
||||||
TEXTURE = 0x1,
|
TEXTURE = 1,
|
||||||
MODEL,
|
//MODEL,
|
||||||
SURFACE, // stones
|
//SURFACE,
|
||||||
STONE, // trees
|
STONE = 3,
|
||||||
TREE,
|
TREE = 4,
|
||||||
|
|
||||||
GLIDER,
|
//GLIDER,
|
||||||
HELPER,
|
HELPER = 7,
|
||||||
ROAD,
|
ROAD = 8,
|
||||||
WEAPON,
|
//WEAPON,
|
||||||
CONFIG,
|
//CONFIG,
|
||||||
|
|
||||||
SHELL, // buildings
|
//SHELL, // buildings
|
||||||
|
BUILDING = 11,
|
||||||
IMAGE,
|
IMAGE,
|
||||||
EXPLOSION, // road lights
|
LAMP = 13,
|
||||||
EQUIPMENT,
|
//EXPLOSION, // road lights
|
||||||
ORGANIZATION,
|
//EQUIPMENT,
|
||||||
|
//ORGANIZATION,
|
||||||
|
|
||||||
BUILDING,
|
//COVERING = 18,
|
||||||
LAMP,
|
SOUND = 19,
|
||||||
COVERING,
|
//GOODS, // anomaly?
|
||||||
SOUND,
|
ANOMALY = 20, // radiation?
|
||||||
GOODS,
|
|
||||||
|
|
||||||
ANOMALY,
|
unk0 = 21, // anomaly?
|
||||||
TOWER,
|
TOWER = 22,
|
||||||
BOUNDARY,
|
BOUNDARY = 23,
|
||||||
SOUND_ZONE,
|
SOUND_ZONE = 24,
|
||||||
|
|
||||||
unk1 = 0x1b,
|
unk1 = 27,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Segment
|
struct Segment
|
||||||
{
|
{
|
||||||
SegmentType segment_type;
|
ObjectType segment_type;
|
||||||
uint32_t segment_len = 0;
|
uint32_t segment_len = 0;
|
||||||
uint32_t n_objects = 0;
|
uint32_t n_objects = 0;
|
||||||
|
|
||||||
virtual ~Segment(){}
|
virtual ~Segment(){}
|
||||||
static Segment *create_segment(buffer &b);
|
static Segment *create_segment(buffer &b);
|
||||||
|
|
@ -76,7 +76,7 @@ struct Segment
|
||||||
template <class T>
|
template <class T>
|
||||||
struct SegmentObjects : public Segment
|
struct SegmentObjects : public Segment
|
||||||
{
|
{
|
||||||
vector<T*> objects;
|
std::vector<T*> objects;
|
||||||
|
|
||||||
virtual void load(buffer &b)
|
virtual void load(buffer &b)
|
||||||
{
|
{
|
||||||
|
|
@ -89,18 +89,10 @@ struct SegmentObjects : public Segment
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Vector4
|
|
||||||
{
|
|
||||||
float x = 0;
|
|
||||||
float y = 0;
|
|
||||||
float z = 0;
|
|
||||||
float w = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Common
|
struct Common
|
||||||
{
|
{
|
||||||
Vector4 m_rotate_z[3];
|
Vector4 m_rotate_z[3];
|
||||||
Vector4 position;
|
Vector4 position;
|
||||||
|
|
||||||
void load(buffer &b)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
|
|
@ -126,7 +118,7 @@ struct MapObject : public Common
|
||||||
struct MapObjectWithArray : public MapObject
|
struct MapObjectWithArray : public MapObject
|
||||||
{
|
{
|
||||||
uint32_t len = 0;
|
uint32_t len = 0;
|
||||||
vector<uint32_t> unk0;
|
std::vector<uint32_t> unk0;
|
||||||
|
|
||||||
void load(buffer &b)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
|
|
@ -159,13 +151,12 @@ struct Boundary : public MapObjectWithArray {};
|
||||||
#define KNOWN_OBJECT(name) \
|
#define KNOWN_OBJECT(name) \
|
||||||
struct name : public MapObject {}
|
struct name : public MapObject {}
|
||||||
|
|
||||||
KNOWN_OBJECT(Surface);
|
|
||||||
KNOWN_OBJECT(Helper);
|
|
||||||
KNOWN_OBJECT(Shell);
|
|
||||||
KNOWN_OBJECT(Stone);
|
KNOWN_OBJECT(Stone);
|
||||||
KNOWN_OBJECT(Explosion);
|
KNOWN_OBJECT(Helper);
|
||||||
|
KNOWN_OBJECT(Building);
|
||||||
|
KNOWN_OBJECT(Tree);
|
||||||
|
KNOWN_OBJECT(Lamp);
|
||||||
KNOWN_OBJECT(Image);
|
KNOWN_OBJECT(Image);
|
||||||
KNOWN_OBJECT(Goods);
|
|
||||||
KNOWN_OBJECT(Anomaly);
|
KNOWN_OBJECT(Anomaly);
|
||||||
KNOWN_OBJECT(Tower);
|
KNOWN_OBJECT(Tower);
|
||||||
KNOWN_OBJECT(SoundZone);
|
KNOWN_OBJECT(SoundZone);
|
||||||
|
|
@ -173,13 +164,13 @@ KNOWN_OBJECT(SoundZone);
|
||||||
#define UNKNOWN_OBJECT(name) \
|
#define UNKNOWN_OBJECT(name) \
|
||||||
struct name : public MapObject { void load(buffer &b){ int pos = b.index(); assert(false); } }
|
struct name : public MapObject { void load(buffer &b){ int pos = b.index(); assert(false); } }
|
||||||
|
|
||||||
UNKNOWN_OBJECT(Building);
|
UNKNOWN_OBJECT(unk0);
|
||||||
UNKNOWN_OBJECT(unk1);
|
UNKNOWN_OBJECT(unk1);
|
||||||
|
|
||||||
struct Objects
|
struct Objects
|
||||||
{
|
{
|
||||||
uint32_t n_segments = 0;
|
uint32_t n_segments = 0;
|
||||||
vector<Segment *> segments;
|
std::vector<Segment *> segments;
|
||||||
|
|
||||||
void load(buffer &b);
|
void load(buffer &b);
|
||||||
};
|
};
|
||||||
84
src/common/types.cpp
Normal file
84
src/common/types.cpp
Normal file
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
* 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 "types.h"
|
||||||
|
|
||||||
|
GameType gameType = GameType::Aim2;
|
||||||
|
|
||||||
|
void weather::load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, name);
|
||||||
|
READ(b, unk0);
|
||||||
|
READ(b, unk1);
|
||||||
|
READ(b, smoke_1);
|
||||||
|
READ(b, smoke_3);
|
||||||
|
READ(b, smokeType);
|
||||||
|
READ(b, unk2);
|
||||||
|
READ(b, cloud_layer1);
|
||||||
|
READ(b, cloud_layer2);
|
||||||
|
READ(b, cloud_layer1_speed);
|
||||||
|
READ(b, cloud_layer2_speed);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void weather_group::load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, n_segs);
|
||||||
|
segments.resize(n_segs);
|
||||||
|
READ(b, name);
|
||||||
|
for (auto &s : segments)
|
||||||
|
s.load(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void water::load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, unk0);
|
||||||
|
READ(b, name1);
|
||||||
|
READ(b, unk1);
|
||||||
|
READ(b, unk2);
|
||||||
|
READ(b, unk3);
|
||||||
|
READ(b, unk4);
|
||||||
|
READ(b, name2);
|
||||||
|
READ(b, unk5);
|
||||||
|
}
|
||||||
|
|
||||||
|
void water_group::load(buffer &b)
|
||||||
|
{
|
||||||
|
while (!b.eof())
|
||||||
|
{
|
||||||
|
water w;
|
||||||
|
w.load(b);
|
||||||
|
segments.push_back(w);
|
||||||
|
}
|
||||||
|
}
|
||||||
298
src/common/types.h
Normal file
298
src/common/types.h
Normal file
|
|
@ -0,0 +1,298 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "buffer.h"
|
||||||
|
#include "color.h"
|
||||||
|
|
||||||
|
enum class GameType
|
||||||
|
{
|
||||||
|
Aim1,
|
||||||
|
Aim2
|
||||||
|
};
|
||||||
|
extern GameType gameType;
|
||||||
|
|
||||||
|
struct vector3
|
||||||
|
{
|
||||||
|
float x = 0;
|
||||||
|
float y = 0;
|
||||||
|
float z = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Vector4
|
||||||
|
{
|
||||||
|
float x = 0;
|
||||||
|
float y = 0;
|
||||||
|
float z = 0;
|
||||||
|
float w = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class WeatherType : uint32_t
|
||||||
|
{
|
||||||
|
rain = 0x1,
|
||||||
|
snow = 0x2,
|
||||||
|
storm = 0x4,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SmokeType : uint32_t
|
||||||
|
{
|
||||||
|
none,
|
||||||
|
exp,
|
||||||
|
biexp,
|
||||||
|
linear,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct weather
|
||||||
|
{
|
||||||
|
struct atmospheric_effects
|
||||||
|
{
|
||||||
|
vector3 wind;
|
||||||
|
WeatherType weatherType;
|
||||||
|
float strength;
|
||||||
|
float duration;
|
||||||
|
float probability;
|
||||||
|
};
|
||||||
|
|
||||||
|
char name[0x20];
|
||||||
|
char unk0[0x20];
|
||||||
|
uint32_t unk1[2];
|
||||||
|
color smoke_1; //3?
|
||||||
|
color smoke_3; //1?
|
||||||
|
SmokeType smokeType;
|
||||||
|
uint32_t unk2[3];
|
||||||
|
char cloud_layer1[0x20];
|
||||||
|
char cloud_layer2[0x20];
|
||||||
|
float cloud_layer1_speed;
|
||||||
|
float cloud_layer2_speed;
|
||||||
|
vector3 cloud_layer1_direction;
|
||||||
|
vector3 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);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct weather_group
|
||||||
|
{
|
||||||
|
uint32_t n_segs;
|
||||||
|
char name[0xA0];
|
||||||
|
std::vector<weather> segments;
|
||||||
|
|
||||||
|
void load(buffer &b);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct water
|
||||||
|
{
|
||||||
|
float unk0[6];
|
||||||
|
char name1[0x20];
|
||||||
|
uint32_t unk1;
|
||||||
|
float unk2;
|
||||||
|
uint32_t unk3[16];
|
||||||
|
float unk4;
|
||||||
|
char name2[0x20];
|
||||||
|
uint32_t unk5[16];
|
||||||
|
|
||||||
|
void load(buffer &b);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct water_group
|
||||||
|
{
|
||||||
|
std::vector<water> segments;
|
||||||
|
|
||||||
|
void load(buffer &b);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Good
|
||||||
|
{
|
||||||
|
char name[0x20];
|
||||||
|
char unk1[0x40];
|
||||||
|
float unk1_2 = 0;
|
||||||
|
float price = 0;
|
||||||
|
float unk2[10];
|
||||||
|
float unk2_1[2];
|
||||||
|
uint32_t unk2_2[2];
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, name);
|
||||||
|
if (gameType == GameType::Aim1)
|
||||||
|
READ(b, unk1);
|
||||||
|
else
|
||||||
|
READ(b, unk1_2);
|
||||||
|
READ(b, price);
|
||||||
|
if (gameType == GameType::Aim1)
|
||||||
|
READ(b, unk2);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
READ(b, unk2_1);
|
||||||
|
READ(b, unk2_2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BuildingGoods
|
||||||
|
{
|
||||||
|
char name[0x20];
|
||||||
|
uint32_t n = 0;
|
||||||
|
|
||||||
|
std::vector<Good> goods;
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, name);
|
||||||
|
READ(b, n);
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
Good g;
|
||||||
|
g.load(b);
|
||||||
|
goods.push_back(g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MapMusic
|
||||||
|
{
|
||||||
|
char name1[0x20];
|
||||||
|
char name2[0x20];
|
||||||
|
|
||||||
|
uint32_t n1 = 0;
|
||||||
|
std::vector<std::string> names1;
|
||||||
|
|
||||||
|
uint32_t n2 = 0;
|
||||||
|
std::vector<std::string> names2;
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, name1);
|
||||||
|
READ(b, name2);
|
||||||
|
|
||||||
|
READ(b, n1);
|
||||||
|
for (int i = 0; i < n1; i++)
|
||||||
|
{
|
||||||
|
char name[0x20];
|
||||||
|
READ(b, name);
|
||||||
|
names1.push_back(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
READ(b, n2);
|
||||||
|
for (int i = 0; i < n2; i++)
|
||||||
|
{
|
||||||
|
char name[0x20];
|
||||||
|
READ(b, name);
|
||||||
|
names2.push_back(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OrganizationConfig
|
||||||
|
{
|
||||||
|
uint32_t n_configs = 0;
|
||||||
|
std::vector<std::string> configs;
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, n_configs);
|
||||||
|
configs.resize(n_configs, std::string(0x20, 0));
|
||||||
|
for (int i = 0; i < n_configs; i++)
|
||||||
|
READ_N(b, configs[i][0], 0x20);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Organization
|
||||||
|
{
|
||||||
|
uint32_t unk0 = 0;
|
||||||
|
char name[0x20];
|
||||||
|
char unk1[0xE0];
|
||||||
|
OrganizationConfig configs[3];
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, unk0);
|
||||||
|
READ(b, name);
|
||||||
|
READ(b, unk1);
|
||||||
|
for (auto &c : configs)
|
||||||
|
c.load(b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Organizations
|
||||||
|
{
|
||||||
|
uint32_t len = 0;
|
||||||
|
uint32_t n = 0;
|
||||||
|
std::vector<Organization> organizations;
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, len);
|
||||||
|
READ(b, n);
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
Organization s;
|
||||||
|
s.load(b);
|
||||||
|
organizations.push_back(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OrganizationBase
|
||||||
|
{
|
||||||
|
char base_name[0x20];
|
||||||
|
char org_name[0x20];
|
||||||
|
uint32_t unk0 = 0;
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, base_name);
|
||||||
|
READ(b, org_name);
|
||||||
|
READ(b, unk0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OrganizationBases
|
||||||
|
{
|
||||||
|
uint32_t n = 0;
|
||||||
|
std::vector<OrganizationBase> organizationBases;
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, n);
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
OrganizationBase s;
|
||||||
|
s.load(b);
|
||||||
|
organizationBases.push_back(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -87,8 +87,14 @@ void value::load_fields(const tab &tab, buffer &b)
|
||||||
while (!data.eof())
|
while (!data.eof())
|
||||||
{
|
{
|
||||||
field_value fv;
|
field_value fv;
|
||||||
if (READ_NOTHROW(data, fv.field_id) == 0)
|
try
|
||||||
|
{
|
||||||
|
READ(data, fv.field_id);
|
||||||
|
}
|
||||||
|
catch (std::exception &)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
READ(data, fv.size);
|
READ(data, fv.size);
|
||||||
auto i = tab.fields.find(fv.field_id);
|
auto i = tab.fields.find(fv.field_id);
|
||||||
if (i == tab.fields.end())
|
if (i == tab.fields.end())
|
||||||
|
|
|
||||||
|
|
@ -27,19 +27,19 @@
|
||||||
#define _USE_MATH_DEFINES
|
#define _USE_MATH_DEFINES
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "objects.h"
|
#include <objects.h>
|
||||||
#include "other.h"
|
#include "other.h"
|
||||||
|
|
||||||
#include <Polygon4/Storage.h>
|
#include <Polygon4/Storage.h>
|
||||||
|
|
||||||
#include <buffer.h>
|
#include <buffer.h>
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
#define RAD2GRAD(x) (x) = (x) / M_PI * 180.0
|
#define RAD2GRAD(x) (x) = (x) / M_PI * 180.0
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
std::string prefix;
|
std::string prefix;
|
||||||
GameType gameType;
|
|
||||||
|
|
||||||
struct storage
|
struct storage
|
||||||
{
|
{
|
||||||
|
|
@ -47,6 +47,7 @@ struct storage
|
||||||
Objects objects;
|
Objects objects;
|
||||||
MechGroups mechGroups;
|
MechGroups mechGroups;
|
||||||
MapGoods mapGoods;
|
MapGoods mapGoods;
|
||||||
|
uint32_t unk0 = 0;
|
||||||
MapMusic mapMusic;
|
MapMusic mapMusic;
|
||||||
MapSounds mapSounds;
|
MapSounds mapSounds;
|
||||||
// aim2
|
// aim2
|
||||||
|
|
@ -61,6 +62,7 @@ struct storage
|
||||||
if (b.eof()) // custom maps
|
if (b.eof()) // custom maps
|
||||||
return;
|
return;
|
||||||
mapGoods.load(b);
|
mapGoods.load(b);
|
||||||
|
READ(b, unk0);
|
||||||
mapMusic.load(b);
|
mapMusic.load(b);
|
||||||
mapSounds.load(b);
|
mapSounds.load(b);
|
||||||
if (gameType == GameType::Aim2)
|
if (gameType == GameType::Aim2)
|
||||||
|
|
@ -129,8 +131,8 @@ void write_mmo(string db, const storage &s)
|
||||||
|
|
||||||
for (auto &seg : s.objects.segments)
|
for (auto &seg : s.objects.segments)
|
||||||
{
|
{
|
||||||
if (seg->segment_type == SegmentType::SHELL ||
|
if (seg->segment_type == ObjectType::BUILDING ||
|
||||||
seg->segment_type == SegmentType::TOWER)
|
seg->segment_type == ObjectType::TOWER)
|
||||||
{
|
{
|
||||||
SegmentObjects<::MapObject> *segment = (SegmentObjects<::MapObject> *)seg;
|
SegmentObjects<::MapObject> *segment = (SegmentObjects<::MapObject> *)seg;
|
||||||
set<string> objs;
|
set<string> objs;
|
||||||
|
|
@ -178,10 +180,10 @@ void write_mmo(string db, const storage &s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (seg->segment_type == SegmentType::SURFACE ||
|
if (seg->segment_type == ObjectType::TREE ||
|
||||||
seg->segment_type == SegmentType::STONE ||
|
seg->segment_type == ObjectType::STONE ||
|
||||||
seg->segment_type == SegmentType::EXPLOSION ||
|
seg->segment_type == ObjectType::LAMP ||
|
||||||
seg->segment_type == SegmentType::BOUNDARY)
|
seg->segment_type == ObjectType::BOUNDARY)
|
||||||
{
|
{
|
||||||
SegmentObjects<::MapObject> *segment = (SegmentObjects<::MapObject> *)seg;
|
SegmentObjects<::MapObject> *segment = (SegmentObjects<::MapObject> *)seg;
|
||||||
set<string> objs;
|
set<string> objs;
|
||||||
|
|
|
||||||
|
|
@ -25,16 +25,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <buffer.h>
|
#include <buffer.h>
|
||||||
|
#include <types.h>
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
enum class GameType
|
|
||||||
{
|
|
||||||
Aim1,
|
|
||||||
Aim2
|
|
||||||
};
|
|
||||||
|
|
||||||
extern GameType gameType;
|
|
||||||
|
|
||||||
struct MechGroup
|
struct MechGroup
|
||||||
{
|
{
|
||||||
|
|
@ -48,13 +39,13 @@ struct MechGroup
|
||||||
//}
|
//}
|
||||||
//{2
|
//{2
|
||||||
uint32_t len = 0;
|
uint32_t len = 0;
|
||||||
vector<uint32_t> unk11;
|
std::vector<uint32_t> unk11;
|
||||||
//}
|
//}
|
||||||
//{1,0
|
//{1,0
|
||||||
uint32_t unk20 = 0;
|
uint32_t unk20 = 0;
|
||||||
uint32_t unk21 = 0;
|
uint32_t unk21 = 0;
|
||||||
//}
|
//}
|
||||||
vector<string> configs;
|
std::vector<std::string> configs;
|
||||||
char unk100;
|
char unk100;
|
||||||
|
|
||||||
void load(buffer &b)
|
void load(buffer &b)
|
||||||
|
|
@ -82,7 +73,7 @@ struct MechGroup
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
assert(false);
|
assert(false);
|
||||||
configs.resize(len1, string(0x20, 0));
|
configs.resize(len1, std::string(0x20, 0));
|
||||||
for (int i = 0; i < len1; i++)
|
for (int i = 0; i < len1; i++)
|
||||||
READ_N(b, configs[i][0], 0x20);
|
READ_N(b, configs[i][0], 0x20);
|
||||||
READ(b, unk100);
|
READ(b, unk100);
|
||||||
|
|
@ -95,7 +86,7 @@ struct MechGroups
|
||||||
uint32_t n = 0;
|
uint32_t n = 0;
|
||||||
char prefix[0x30];
|
char prefix[0x30];
|
||||||
|
|
||||||
vector<MechGroup> mgs;
|
std::vector<MechGroup> mgs;
|
||||||
|
|
||||||
void load(buffer &b)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
|
|
@ -113,51 +104,6 @@ struct MechGroups
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Good
|
|
||||||
{
|
|
||||||
char name[0x20];
|
|
||||||
char unk1[0x40];
|
|
||||||
uint32_t unk1_2 = 0;
|
|
||||||
float price = 0;
|
|
||||||
float unk2[10];
|
|
||||||
float unk2_2[4];
|
|
||||||
|
|
||||||
void load(buffer &b)
|
|
||||||
{
|
|
||||||
READ(b, name);
|
|
||||||
if (gameType == GameType::Aim1)
|
|
||||||
READ(b, unk1);
|
|
||||||
else
|
|
||||||
READ(b, unk1_2);
|
|
||||||
READ(b, price);
|
|
||||||
if (gameType == GameType::Aim1)
|
|
||||||
READ(b, unk2);
|
|
||||||
else
|
|
||||||
READ(b, unk2_2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BuildingGoods
|
|
||||||
{
|
|
||||||
char name[0x20];
|
|
||||||
uint32_t n = 0;
|
|
||||||
|
|
||||||
vector<Good> goods;
|
|
||||||
|
|
||||||
void load(buffer &b)
|
|
||||||
{
|
|
||||||
READ(b, name);
|
|
||||||
READ(b, n);
|
|
||||||
|
|
||||||
for (int i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
Good g;
|
|
||||||
g.load(b);
|
|
||||||
goods.push_back(g);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MapGoods
|
struct MapGoods
|
||||||
{
|
{
|
||||||
uint32_t length = 0;
|
uint32_t length = 0;
|
||||||
|
|
@ -165,7 +111,7 @@ struct MapGoods
|
||||||
uint32_t unk3 = 0;
|
uint32_t unk3 = 0;
|
||||||
uint32_t n = 0;
|
uint32_t n = 0;
|
||||||
|
|
||||||
vector<BuildingGoods> bgs;
|
std::vector<BuildingGoods> bgs;
|
||||||
|
|
||||||
void load(buffer &b)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
|
|
@ -186,42 +132,6 @@ struct MapGoods
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MapMusic
|
|
||||||
{
|
|
||||||
uint32_t unk1 = 0;
|
|
||||||
char name1[0x20];
|
|
||||||
char name2[0x20];
|
|
||||||
|
|
||||||
uint32_t n1 = 0;
|
|
||||||
vector<string> names1;
|
|
||||||
|
|
||||||
uint32_t n2 = 0;
|
|
||||||
vector<string> names2;
|
|
||||||
|
|
||||||
void load(buffer &b)
|
|
||||||
{
|
|
||||||
READ(b, unk1);
|
|
||||||
READ(b, name1);
|
|
||||||
READ(b, name2);
|
|
||||||
|
|
||||||
READ(b, n1);
|
|
||||||
for (int i = 0; i < n1; i++)
|
|
||||||
{
|
|
||||||
char name[0x20];
|
|
||||||
READ(b, name);
|
|
||||||
names1.push_back(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
READ(b, n2);
|
|
||||||
for (int i = 0; i < n2; i++)
|
|
||||||
{
|
|
||||||
char name[0x20];
|
|
||||||
READ(b, name);
|
|
||||||
names2.push_back(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MapSound
|
struct MapSound
|
||||||
{
|
{
|
||||||
char name[0x20];
|
char name[0x20];
|
||||||
|
|
@ -241,7 +151,7 @@ struct MapSound
|
||||||
struct MapSounds
|
struct MapSounds
|
||||||
{
|
{
|
||||||
uint32_t n = 0;
|
uint32_t n = 0;
|
||||||
vector<MapSound> sounds;
|
std::vector<MapSound> sounds;
|
||||||
|
|
||||||
void load(buffer &b)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
|
|
@ -255,87 +165,6 @@ struct MapSounds
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OrganizationConfig
|
|
||||||
{
|
|
||||||
uint32_t n_configs = 0;
|
|
||||||
vector<string> configs;
|
|
||||||
|
|
||||||
void load(buffer &b)
|
|
||||||
{
|
|
||||||
READ(b, n_configs);
|
|
||||||
configs.resize(n_configs, string(0x20, 0));
|
|
||||||
for (int i = 0; i < n_configs; i++)
|
|
||||||
READ_N(b, configs[i][0], 0x20);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Organization
|
|
||||||
{
|
|
||||||
uint32_t unk0 = 0;
|
|
||||||
char name[0x20];
|
|
||||||
char unk1[0xE0];
|
|
||||||
OrganizationConfig configs[3];
|
|
||||||
|
|
||||||
void load(buffer &b)
|
|
||||||
{
|
|
||||||
READ(b, unk0);
|
|
||||||
READ(b, name);
|
|
||||||
READ(b, unk1);
|
|
||||||
for (auto &c : configs)
|
|
||||||
c.load(b);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Organizations
|
|
||||||
{
|
|
||||||
uint32_t len = 0;
|
|
||||||
uint32_t n = 0;
|
|
||||||
vector<Organization> organizations;
|
|
||||||
|
|
||||||
void load(buffer &b)
|
|
||||||
{
|
|
||||||
READ(b, len);
|
|
||||||
READ(b, n);
|
|
||||||
for (int i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
Organization s;
|
|
||||||
s.load(b);
|
|
||||||
organizations.push_back(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OrganizationBase
|
|
||||||
{
|
|
||||||
char base_name[0x20];
|
|
||||||
char org_name[0x20];
|
|
||||||
uint32_t unk0 = 0;
|
|
||||||
|
|
||||||
void load(buffer &b)
|
|
||||||
{
|
|
||||||
READ(b, base_name);
|
|
||||||
READ(b, org_name);
|
|
||||||
READ(b, unk0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct OrganizationBases
|
|
||||||
{
|
|
||||||
uint32_t n = 0;
|
|
||||||
vector<OrganizationBase> organizationBases;
|
|
||||||
|
|
||||||
void load(buffer &b)
|
|
||||||
{
|
|
||||||
READ(b, n);
|
|
||||||
for (int i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
OrganizationBase s;
|
|
||||||
s.load(b);
|
|
||||||
organizationBases.push_back(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Price
|
struct Price
|
||||||
{
|
{
|
||||||
char tov_name[0x20];
|
char tov_name[0x20];
|
||||||
|
|
@ -356,7 +185,7 @@ struct BuildingPrice
|
||||||
{
|
{
|
||||||
char name[0x20];
|
char name[0x20];
|
||||||
uint32_t n_tov = 0;
|
uint32_t n_tov = 0;
|
||||||
vector<Price> prices;
|
std::vector<Price> prices;
|
||||||
|
|
||||||
void load(buffer &b)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
|
|
@ -374,9 +203,9 @@ struct BuildingPrice
|
||||||
struct BuildingPrices
|
struct BuildingPrices
|
||||||
{
|
{
|
||||||
uint32_t n_tov = 0;
|
uint32_t n_tov = 0;
|
||||||
vector<Price> prices;
|
std::vector<Price> prices;
|
||||||
uint32_t n_bases = 0;
|
uint32_t n_bases = 0;
|
||||||
vector<BuildingPrice> buildingPrices;
|
std::vector<BuildingPrice> buildingPrices;
|
||||||
|
|
||||||
void load(buffer &b)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -24,65 +24,12 @@
|
||||||
|
|
||||||
void water_segment::load(buffer &b)
|
void water_segment::load(buffer &b)
|
||||||
{
|
{
|
||||||
while (!b.eof())
|
wg.load(b);
|
||||||
{
|
|
||||||
water w;
|
|
||||||
w.load(b);
|
|
||||||
segments.push_back(w);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void water::load(buffer &b)
|
|
||||||
{
|
|
||||||
READ(b, unk0);
|
|
||||||
READ(b, name1);
|
|
||||||
READ(b, unk1);
|
|
||||||
READ(b, unk2);
|
|
||||||
READ(b, unk3);
|
|
||||||
READ(b, unk4);
|
|
||||||
READ(b, name2);
|
|
||||||
READ(b, unk5);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void weather_segment::load(buffer &b)
|
void weather_segment::load(buffer &b)
|
||||||
{
|
{
|
||||||
READ(b, n_segs);
|
wg.load(b);
|
||||||
segments.resize(n_segs);
|
|
||||||
READ(b, name);
|
|
||||||
for (auto &s : segments)
|
|
||||||
s.load(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
void weather::load(buffer &b)
|
|
||||||
{
|
|
||||||
READ(b, name);
|
|
||||||
READ(b, unk0);
|
|
||||||
READ(b, unk1);
|
|
||||||
READ(b, smoke_1);
|
|
||||||
READ(b, smoke_3);
|
|
||||||
READ(b, smokeType);
|
|
||||||
READ(b, unk2);
|
|
||||||
READ(b, cloud_layer1);
|
|
||||||
READ(b, cloud_layer2);
|
|
||||||
READ(b, cloud_layer1_speed);
|
|
||||||
READ(b, cloud_layer2_speed);
|
|
||||||
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)
|
||||||
|
|
@ -183,8 +130,6 @@ void mmp::loadTextureNames(const std::string &fn)
|
||||||
|
|
||||||
void mmp::process()
|
void mmp::process()
|
||||||
{
|
{
|
||||||
int k = segment::len;
|
|
||||||
|
|
||||||
for (auto &s : segments)
|
for (auto &s : segments)
|
||||||
{
|
{
|
||||||
for (auto &i : s.d.Infomap)
|
for (auto &i : s.d.Infomap)
|
||||||
|
|
@ -212,43 +157,50 @@ void mmp::process()
|
||||||
}
|
}
|
||||||
alpha_maps[0] = mat<uint32_t>(h.width, h.height);
|
alpha_maps[0] = mat<uint32_t>(h.width, h.height);
|
||||||
for (auto &t : textures_map)
|
for (auto &t : textures_map)
|
||||||
|
{
|
||||||
alpha_maps[t.second.g] = mat<uint32_t>(h.width, h.height);
|
alpha_maps[t.second.g] = mat<uint32_t>(h.width, h.height);
|
||||||
|
}
|
||||||
|
|
||||||
// merge
|
// merge
|
||||||
heightmap = decltype(heightmap)(h.width, h.height);
|
heightmap = decltype(heightmap)(h.width, h.height);
|
||||||
texmap = decltype(texmap)(h.width, h.height);
|
texmap = decltype(texmap)(h.width, h.height);
|
||||||
texmap_colored = decltype(texmap_colored)(h.width, h.height);
|
texmap_colored = decltype(texmap_colored)(h.width, h.height);
|
||||||
colormap = decltype(colormap)(h.width, h.height);
|
colormap = decltype(colormap)(h.width, h.height);
|
||||||
for (int y = 0; y < h.height; y++)
|
|
||||||
|
h_min = std::numeric_limits<Height>::max();
|
||||||
|
h_max = std::numeric_limits<Height>::min();
|
||||||
|
for (auto &s : segments)
|
||||||
{
|
{
|
||||||
auto ys = y / k * xsegs;
|
const auto &data = s.d;
|
||||||
auto yc = y % k * k;
|
int y1 = s.desc.Ymin / 10;
|
||||||
for (int x = 0; x < h.width; x++)
|
int y2 = s.desc.Ymax / 10;
|
||||||
|
if (y2 > h.height)
|
||||||
|
y2 = h.height;
|
||||||
|
for (int y = 0; y1 < y2; y1++, y++)
|
||||||
{
|
{
|
||||||
auto xs = x / k;
|
int x1 = s.desc.Xmin / 10;
|
||||||
auto xc = x % k;
|
int x2 = s.desc.Xmax / 10;
|
||||||
auto y_rev = h.height - y - 1;
|
auto dx = x2 - x1;
|
||||||
const auto &data = segments[ys + xs].d;
|
if (x2 > h.width)
|
||||||
auto height = data.Heightmap[yc + xc];
|
x2 = h.width;
|
||||||
auto t = data.Infomap[yc + xc].getTexture();
|
for (int x = 0; x1 < x2; x1++, x++)
|
||||||
|
|
||||||
auto t_norm = textures_map.find(t);
|
|
||||||
if (t_norm != textures_map.end())
|
|
||||||
{
|
{
|
||||||
texmap(y_rev, x) = t_norm->second;
|
auto p = y * dx + x;
|
||||||
alpha_maps[t_norm->second.g](y_rev, x) = color{ 0,255,0,0 };
|
auto y_rev = h.height - y1 - 1; // for bmp reversion
|
||||||
}
|
//auto y_rev = y1;
|
||||||
|
|
||||||
texmap_colored(y_rev, x) = textures_map_colored[t];
|
auto t = data.Infomap[p].getTexture();
|
||||||
colormap(y_rev, x) = data.Colormap[yc + xc];
|
auto t_norm = textures_map.find(t);
|
||||||
|
if (t_norm != textures_map.end())
|
||||||
|
{
|
||||||
|
texmap(y_rev, x1) = t_norm->second;
|
||||||
|
alpha_maps[t_norm->second.g](y_rev, x1) = color{ 0,255,0,0 };
|
||||||
|
}
|
||||||
|
|
||||||
if (x == 0 && y == 0)
|
texmap_colored(y_rev, x1) = textures_map_colored[t];
|
||||||
{
|
colormap(y_rev, x1) = data.Colormap[p];
|
||||||
h_min = height;
|
|
||||||
h_max = height;
|
auto height = data.Heightmap[p];
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
h_min = std::min(h_min, height);
|
h_min = std::min(h_min, height);
|
||||||
h_max = std::max(h_max, height);
|
h_max = std::max(h_max, height);
|
||||||
}
|
}
|
||||||
|
|
@ -257,18 +209,31 @@ void mmp::process()
|
||||||
|
|
||||||
alpha_maps.erase(0);
|
alpha_maps.erase(0);
|
||||||
scale16 = 0xffff / (h_max - h_min);
|
scale16 = 0xffff / (h_max - h_min);
|
||||||
|
const int unreal_koef = 51200;
|
||||||
|
const int aim_koef = 10;
|
||||||
|
const double diff = h_max - h_min;
|
||||||
|
const double scale = aim_koef / (unreal_koef / diff);
|
||||||
|
|
||||||
for (int y = 0; y < h.height; y++)
|
for (auto &s : segments)
|
||||||
{
|
{
|
||||||
auto ys = y / k * xsegs;
|
int y1 = s.desc.Ymin / 10;
|
||||||
auto yc = y % k * k;
|
int y2 = s.desc.Ymax / 10;
|
||||||
for (int x = 0; x < h.width; x++)
|
if (y2 > h.height)
|
||||||
|
y2 = h.height;
|
||||||
|
for (int y = 0; y1 < y2; y1++, y++)
|
||||||
{
|
{
|
||||||
auto xs = x / k;
|
int x1 = s.desc.Xmin / 10;
|
||||||
auto xc = x % k;
|
int x2 = s.desc.Xmax / 10;
|
||||||
auto height = segments[ys + xs].d.Heightmap[yc + xc];
|
auto dx = x2 - x1;
|
||||||
auto val = (height - h_min) * scale16;
|
if (x2 > h.width)
|
||||||
heightmap(y, x) = val;
|
x2 = h.width;
|
||||||
|
for (int x = 0; x1 < x2; x1++, x++)
|
||||||
|
{
|
||||||
|
auto height = s.d.Heightmap[y * dx + x];
|
||||||
|
auto val = (height - h_min) * scale16 * scale;
|
||||||
|
auto &old_height = heightmap(y1, x1);
|
||||||
|
old_height = val;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,28 +25,9 @@
|
||||||
#include <buffer.h>
|
#include <buffer.h>
|
||||||
#include <color.h>
|
#include <color.h>
|
||||||
#include <mat.h>
|
#include <mat.h>
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
enum class WeatherType : uint32_t
|
using Height = float;
|
||||||
{
|
|
||||||
rain = 0x1,
|
|
||||||
snow = 0x2,
|
|
||||||
storm = 0x4,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class SmokeType : uint32_t
|
|
||||||
{
|
|
||||||
none,
|
|
||||||
exp,
|
|
||||||
biexp,
|
|
||||||
linear,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct direction
|
|
||||||
{
|
|
||||||
float x;
|
|
||||||
float y;
|
|
||||||
float z;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class HeaderSegmentType : uint32_t
|
enum class HeaderSegmentType : uint32_t
|
||||||
{
|
{
|
||||||
|
|
@ -63,75 +44,16 @@ struct header_segment
|
||||||
virtual void load(buffer &b) = 0;
|
virtual void load(buffer &b) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct water
|
|
||||||
{
|
|
||||||
float unk0[6];
|
|
||||||
char name1[0x20];
|
|
||||||
uint32_t unk1;
|
|
||||||
float unk2;
|
|
||||||
uint32_t unk3[16];
|
|
||||||
float unk4;
|
|
||||||
char name2[0x20];
|
|
||||||
uint32_t unk5[16];
|
|
||||||
|
|
||||||
void load(buffer &b);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct water_segment : public header_segment
|
struct water_segment : public header_segment
|
||||||
{
|
{
|
||||||
std::vector<water> segments;
|
water_group wg;
|
||||||
|
|
||||||
virtual void load(buffer &b) override;
|
virtual void load(buffer &b) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct weather
|
|
||||||
{
|
|
||||||
struct atmospheric_effects
|
|
||||||
{
|
|
||||||
direction wind;
|
|
||||||
WeatherType weatherType;
|
|
||||||
float strength;
|
|
||||||
float duration;
|
|
||||||
float probability;
|
|
||||||
};
|
|
||||||
|
|
||||||
char name[0x20];
|
|
||||||
char unk0[0x20];
|
|
||||||
uint32_t unk1[2];
|
|
||||||
color smoke_1; //3?
|
|
||||||
color smoke_3; //1?
|
|
||||||
SmokeType smokeType;
|
|
||||||
uint32_t unk2[3];
|
|
||||||
char cloud_layer1[0x20];
|
|
||||||
char cloud_layer2[0x20];
|
|
||||||
float cloud_layer1_speed;
|
|
||||||
float cloud_layer2_speed;
|
|
||||||
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);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct weather_segment : public header_segment
|
struct weather_segment : public header_segment
|
||||||
{
|
{
|
||||||
uint32_t n_segs;
|
weather_group wg;
|
||||||
char name[0xA0];
|
|
||||||
std::vector<weather> segments;
|
|
||||||
|
|
||||||
virtual void load(buffer &b) override;
|
virtual void load(buffer &b) override;
|
||||||
};
|
};
|
||||||
|
|
@ -188,17 +110,26 @@ struct segment
|
||||||
int16_t x;
|
int16_t x;
|
||||||
int16_t y;
|
int16_t y;
|
||||||
};
|
};
|
||||||
struct old_data
|
struct mini_lod
|
||||||
{
|
{
|
||||||
uint16_t Heightmap[1089 * 2];
|
static const int len = 33;
|
||||||
color Colormap[1089];
|
static const int size = len * len;
|
||||||
uint32_t unk0[1089];
|
|
||||||
normal unk1[1089]; // normals?
|
struct flagged_heightmap
|
||||||
|
{
|
||||||
|
uint16_t height;
|
||||||
|
uint16_t flag;
|
||||||
|
};
|
||||||
|
|
||||||
|
flagged_heightmap Heightmap[size];
|
||||||
|
color Colormap[size];
|
||||||
|
uint32_t unk0[size]; // shadowmap?
|
||||||
|
normal unk1[size]; // normals?
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t MagicNumber;
|
uint32_t MagicNumber;
|
||||||
old_data old;
|
mini_lod mlod;
|
||||||
float Heightmap[size];
|
Height Heightmap[size];
|
||||||
info Infomap[size];
|
info Infomap[size];
|
||||||
color Colormap[size];
|
color Colormap[size];
|
||||||
shadow Shadowmap[size];
|
shadow Shadowmap[size];
|
||||||
|
|
@ -225,9 +156,9 @@ struct mmp
|
||||||
std::map<int, mat<uint32_t>> alpha_maps;
|
std::map<int, mat<uint32_t>> alpha_maps;
|
||||||
std::map<int, color> textures_map_colored;
|
std::map<int, color> textures_map_colored;
|
||||||
std::map<int, std::string> textures_names;
|
std::map<int, std::string> textures_names;
|
||||||
float h_min;
|
Height h_min;
|
||||||
float h_max;
|
Height h_max;
|
||||||
float scale16 = 0;
|
double scale16 = 0;
|
||||||
mat<uint16_t> heightmap;
|
mat<uint16_t> heightmap;
|
||||||
mat<uint32_t> texmap;
|
mat<uint32_t> texmap;
|
||||||
mat<uint32_t> texmap_colored;
|
mat<uint32_t> texmap_colored;
|
||||||
|
|
|
||||||
224
src/mpj_loader/mpj.cpp
Normal file
224
src/mpj_loader/mpj.cpp
Normal file
|
|
@ -0,0 +1,224 @@
|
||||||
|
/*
|
||||||
|
* AIM mpj_loader
|
||||||
|
* 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 "mpj.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
|
segment *segment::create_segment(buffer &b)
|
||||||
|
{
|
||||||
|
SegmentType type;
|
||||||
|
READ(b, type);
|
||||||
|
if (type == SegmentType::none)
|
||||||
|
READ(b, type);
|
||||||
|
|
||||||
|
segment *segment = nullptr;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case SegmentType::MapData:
|
||||||
|
segment = new map_data;
|
||||||
|
break;
|
||||||
|
case SegmentType::Surface:
|
||||||
|
segment = new surface;
|
||||||
|
break;
|
||||||
|
case SegmentType::Weather:
|
||||||
|
segment = new weather_data;
|
||||||
|
break;
|
||||||
|
case SegmentType::Objects:
|
||||||
|
segment = new objects_data;
|
||||||
|
break;
|
||||||
|
case SegmentType::Water:
|
||||||
|
segment = new water_data;
|
||||||
|
break;
|
||||||
|
case SegmentType::unk7:
|
||||||
|
segment = new segment7;
|
||||||
|
break;
|
||||||
|
case SegmentType::unk9:
|
||||||
|
segment = new segment9;
|
||||||
|
break;
|
||||||
|
case SegmentType::BuildingGoods:
|
||||||
|
segment = new building_goods;
|
||||||
|
break;
|
||||||
|
case SegmentType::MapMusic:
|
||||||
|
segment = new map_music;
|
||||||
|
break;
|
||||||
|
case SegmentType::Organizations:
|
||||||
|
segment = new organizations;
|
||||||
|
break;
|
||||||
|
case SegmentType::Goods:
|
||||||
|
segment = new gliders_n_goods;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (segment)
|
||||||
|
{
|
||||||
|
segment->type = type;
|
||||||
|
READ(b, segment->unk0);
|
||||||
|
READ(b, segment->size);
|
||||||
|
}
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void map_data::load(buffer &b)
|
||||||
|
{
|
||||||
|
auto sz = b.size();
|
||||||
|
assert(sz % 3 == 0);
|
||||||
|
sz /= 3;
|
||||||
|
#define READ_SEG(v) \
|
||||||
|
v.resize(sz / sizeof(decltype(v)::value_type)); \
|
||||||
|
READ_N(b, v[0], v.size())
|
||||||
|
|
||||||
|
READ_SEG(unk1);
|
||||||
|
READ_SEG(unk2);
|
||||||
|
READ_SEG(unk3);
|
||||||
|
#undef READ_SEG
|
||||||
|
}
|
||||||
|
|
||||||
|
void surface::load(buffer &b)
|
||||||
|
{
|
||||||
|
while (!b.eof())
|
||||||
|
{
|
||||||
|
value v;
|
||||||
|
READ(b, v);
|
||||||
|
unk1.push_back(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void weather_data::load(buffer &b)
|
||||||
|
{
|
||||||
|
wg.load(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void objects_data::load(buffer &b)
|
||||||
|
{
|
||||||
|
objects.load(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void segment7::load(buffer &b)
|
||||||
|
{
|
||||||
|
auto n = b.size() / sizeof(decltype(data)::value_type);
|
||||||
|
data.resize(n);
|
||||||
|
READ_N(b, data[0], n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void water_data::load(buffer &b)
|
||||||
|
{
|
||||||
|
wg.load(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void segment9::load(buffer &b)
|
||||||
|
{
|
||||||
|
auto n = b.size() / sizeof(decltype(data)::value_type);
|
||||||
|
data.resize(n);
|
||||||
|
READ_N(b, data[0], n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void building_goods::load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, unk1);
|
||||||
|
READ(b, n);
|
||||||
|
bgs.resize(n);
|
||||||
|
for (auto &bg : bgs)
|
||||||
|
bg.load(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void map_music::load(buffer &b)
|
||||||
|
{
|
||||||
|
while (!b.eof())
|
||||||
|
{
|
||||||
|
MapMusic mm;
|
||||||
|
mm.load(b);
|
||||||
|
mms.push_back(mm);
|
||||||
|
READ(b, unk1); // or read after cycle?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void organizations::load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, n);
|
||||||
|
orgs.resize(n);
|
||||||
|
for (auto &org : orgs)
|
||||||
|
org.load(b);
|
||||||
|
bases.load(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gliders_n_goods::load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, n_good_groups);
|
||||||
|
READ(b, n_gliders);
|
||||||
|
gliders.resize(n_gliders);
|
||||||
|
for (auto &g : gliders)
|
||||||
|
g.load(b);
|
||||||
|
READ(b, unk1);
|
||||||
|
goods.resize(n_good_groups);
|
||||||
|
for (auto &g : goods)
|
||||||
|
g.load(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void header::load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, magic);
|
||||||
|
if (memcmp(magic, "MPRJ", 4) != 0)
|
||||||
|
throw std::runtime_error("This file is not a mechanoid project");
|
||||||
|
READ(b, unk0);
|
||||||
|
READ(b, unk1);
|
||||||
|
READ(b, unk2);
|
||||||
|
READ(b, unk3);
|
||||||
|
READ(b, width);
|
||||||
|
READ(b, height);
|
||||||
|
READ(b, unk4);
|
||||||
|
|
||||||
|
auto seg_size = 64;
|
||||||
|
auto xsegs = width / seg_size;
|
||||||
|
if ((width - 1) % 64 != 0)
|
||||||
|
xsegs++;
|
||||||
|
auto ysegs = height / seg_size;
|
||||||
|
if ((width - 1) % 64 != 0)
|
||||||
|
ysegs++;
|
||||||
|
|
||||||
|
while (!b.eof())
|
||||||
|
{
|
||||||
|
auto seg = segment::create_segment(b);
|
||||||
|
if (!seg)
|
||||||
|
break;
|
||||||
|
seg->load(buffer(b, seg->size));
|
||||||
|
segments.push_back(seg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!b.eof())
|
||||||
|
{
|
||||||
|
throw std::logic_error("End of file was not reached");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mpj::load(buffer &b)
|
||||||
|
{
|
||||||
|
h.load(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mpj::load(const std::string &fn)
|
||||||
|
{
|
||||||
|
filename = fn;
|
||||||
|
buffer b(readFile(filename));
|
||||||
|
load(b);
|
||||||
|
}
|
||||||
211
src/mpj_loader/mpj.h
Normal file
211
src/mpj_loader/mpj.h
Normal file
|
|
@ -0,0 +1,211 @@
|
||||||
|
/*
|
||||||
|
* AIM mpj_loader
|
||||||
|
* 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 <map>
|
||||||
|
#include <set>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <buffer.h>
|
||||||
|
#include <objects.h>
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
enum class SegmentType : uint32_t
|
||||||
|
{
|
||||||
|
none = 0,
|
||||||
|
MapData = 1,
|
||||||
|
Surface = 2,
|
||||||
|
Weather = 4,
|
||||||
|
Objects = 6,
|
||||||
|
unk7 = 7,
|
||||||
|
Water = 8,
|
||||||
|
unk9 = 9,
|
||||||
|
BuildingGoods = 10,
|
||||||
|
MapMusic = 11,
|
||||||
|
Organizations = 12,
|
||||||
|
Goods = 13,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct segment
|
||||||
|
{
|
||||||
|
SegmentType type;
|
||||||
|
uint32_t unk0;
|
||||||
|
uint32_t size;
|
||||||
|
|
||||||
|
virtual ~segment() {}
|
||||||
|
|
||||||
|
static segment *create_segment(buffer &b);
|
||||||
|
virtual void load(buffer &b) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct map_data : public segment
|
||||||
|
{
|
||||||
|
std::vector<float> unk1;
|
||||||
|
std::vector<uint32_t> unk2;
|
||||||
|
std::vector<uint32_t> unk3;
|
||||||
|
|
||||||
|
virtual void load(buffer &b) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct surface : public segment
|
||||||
|
{
|
||||||
|
struct value
|
||||||
|
{
|
||||||
|
char name[0x20];
|
||||||
|
uint32_t unk0;
|
||||||
|
};
|
||||||
|
std::vector<value> unk1;
|
||||||
|
|
||||||
|
virtual void load(buffer &b) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct weather_data : public segment
|
||||||
|
{
|
||||||
|
weather_group wg;
|
||||||
|
|
||||||
|
virtual void load(buffer &b) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct objects_data : public segment
|
||||||
|
{
|
||||||
|
Objects objects;
|
||||||
|
|
||||||
|
virtual void load(buffer &b) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct segment7 : public segment
|
||||||
|
{
|
||||||
|
std::vector<uint32_t> data;
|
||||||
|
|
||||||
|
virtual void load(buffer &b) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct water_data : public segment
|
||||||
|
{
|
||||||
|
water_group wg;
|
||||||
|
|
||||||
|
virtual void load(buffer &b) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct segment9 : public segment
|
||||||
|
{
|
||||||
|
std::vector<uint32_t> data;
|
||||||
|
|
||||||
|
virtual void load(buffer &b) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct building_goods : public segment
|
||||||
|
{
|
||||||
|
struct bg_internal
|
||||||
|
{
|
||||||
|
BuildingGoods bg;
|
||||||
|
uint32_t unk0;
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
bg.load(b);
|
||||||
|
READ(b, unk0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
uint32_t unk1; // record format? aim2 ?
|
||||||
|
uint32_t n;
|
||||||
|
std::vector<bg_internal> bgs;
|
||||||
|
|
||||||
|
virtual void load(buffer &b) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct map_music : public segment
|
||||||
|
{
|
||||||
|
std::vector<MapMusic> mms;
|
||||||
|
uint32_t unk1;
|
||||||
|
|
||||||
|
virtual void load(buffer &b) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct organizations : public segment
|
||||||
|
{
|
||||||
|
uint32_t n;
|
||||||
|
std::vector<Organization> orgs;
|
||||||
|
OrganizationBases bases;
|
||||||
|
|
||||||
|
virtual void load(buffer &b) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct gliders_n_goods : public segment
|
||||||
|
{
|
||||||
|
struct Good
|
||||||
|
{
|
||||||
|
char name[0x20];
|
||||||
|
int unk0[3];
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, name);
|
||||||
|
READ(b, unk0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Goods
|
||||||
|
{
|
||||||
|
uint32_t n_goods;
|
||||||
|
std::vector<Good> goods;
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
READ(b, n_goods);
|
||||||
|
goods.resize(n_goods);
|
||||||
|
for (auto &g : goods)
|
||||||
|
g.load(b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t n_good_groups;
|
||||||
|
uint32_t n_gliders;
|
||||||
|
std::vector<Good> gliders;
|
||||||
|
uint32_t unk1;
|
||||||
|
std::vector<Goods> goods;
|
||||||
|
|
||||||
|
virtual void load(buffer &b) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct header
|
||||||
|
{
|
||||||
|
char magic[4];
|
||||||
|
uint32_t unk0;
|
||||||
|
uint32_t unk1;
|
||||||
|
uint32_t unk2;
|
||||||
|
uint32_t unk3;
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
char unk4[0x3F4];
|
||||||
|
std::vector<segment*> segments;
|
||||||
|
|
||||||
|
void load(buffer &b);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mpj
|
||||||
|
{
|
||||||
|
header h;
|
||||||
|
|
||||||
|
//
|
||||||
|
std::string filename;
|
||||||
|
|
||||||
|
void load(buffer &b);
|
||||||
|
void load(const std::string &filename);
|
||||||
|
};
|
||||||
50
src/mpj_loader/mpj_loader.cpp
Normal file
50
src/mpj_loader/mpj_loader.cpp
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* AIM mpj_loader
|
||||||
|
* 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 <iostream>
|
||||||
|
#include <set>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "mpj.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
cout << "Usage:\n" << argv[0] << " file.mpj" << "\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
mpj m;
|
||||||
|
m.load(argv[1]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
catch (std::exception &e)
|
||||||
|
{
|
||||||
|
printf("error: %s\n", e.what());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
printf("error: unknown exception\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue