mirror of
https://github.com/aimrebirth/tools.git
synced 2026-04-14 17:33:25 +00:00
Add common library with some helpers.
This commit is contained in:
parent
ef6cd29915
commit
fb6aa75845
17 changed files with 483 additions and 384 deletions
2
.gitmodules
vendored
2
.gitmodules
vendored
|
|
@ -1,3 +1,3 @@
|
||||||
[submodule "dep/dbmgr"]
|
[submodule "dep/dbmgr"]
|
||||||
path = dep/dbmgr
|
path = dep/dbmgr
|
||||||
url = https://github.com/aimrebirth/DatabaseManager.git
|
url = git@github.com:aimrebirth/DatabaseManager.git
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ endif(MSVC)
|
||||||
|
|
||||||
include_directories(dep/dbmgr/include)
|
include_directories(dep/dbmgr/include)
|
||||||
add_subdirectory(dep/dbmgr)
|
add_subdirectory(dep/dbmgr)
|
||||||
|
set_target_properties(sqlite3 PROPERTIES FOLDER Extern)
|
||||||
|
set_target_properties(DatabaseManager PROPERTIES FOLDER Extern)
|
||||||
|
|
||||||
add_custom_target(version ALL
|
add_custom_target(version ALL
|
||||||
COMMAND git rev-list HEAD --count > ${CMAKE_CURRENT_BINARY_DIR}/version.h_
|
COMMAND git rev-list HEAD --count > ${CMAKE_CURRENT_BINARY_DIR}/version.h_
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 8fbdd4aba7438c7d3eace1308476597460d0aeed
|
Subproject commit f6aae55f91ac07cbdd286e96fb9cc5e278a4a6c5
|
||||||
|
|
@ -1,12 +1,15 @@
|
||||||
|
include_directories(common)
|
||||||
|
|
||||||
file(GLOB unpaker_src "unpaker/*")
|
file(GLOB unpaker_src "unpaker/*")
|
||||||
add_executable(unpaker ${unpaker_src})
|
add_executable(unpaker ${unpaker_src})
|
||||||
|
|
||||||
file(GLOB db_extractor_src "db_extractor/*")
|
file(GLOB db_extractor_src "db_extractor/*")
|
||||||
add_executable(db_extractor ${db_extractor_src})
|
add_executable(db_extractor ${db_extractor_src})
|
||||||
|
target_link_libraries(db_extractor common)
|
||||||
|
|
||||||
file(GLOB obj_extractor_src "obj_extractor/*")
|
file(GLOB obj_extractor_src "obj_extractor/*")
|
||||||
add_executable(obj_extractor ${obj_extractor_src})
|
add_executable(obj_extractor ${obj_extractor_src})
|
||||||
target_link_libraries(obj_extractor DatabaseManager)
|
target_link_libraries(obj_extractor DatabaseManager common)
|
||||||
|
|
||||||
file(GLOB script2txt_src "script2txt/*")
|
file(GLOB script2txt_src "script2txt/*")
|
||||||
add_executable(script2txt ${script2txt_src})
|
add_executable(script2txt ${script2txt_src})
|
||||||
|
|
@ -16,3 +19,6 @@ add_executable(mmp_extractor ${mmp_extractor_src})
|
||||||
|
|
||||||
file(GLOB mod_converter_src "mod_converter/*")
|
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)
|
||||||
|
|
||||||
|
add_subdirectory(common)
|
||||||
2
src/common/CMakeLists.txt
Normal file
2
src/common/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
file(GLOB common_src "*.h" "*.cpp")
|
||||||
|
add_library(common ${common_src})
|
||||||
127
src/common/common.cpp
Normal file
127
src/common/common.cpp
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* AIM tools
|
||||||
|
* Copyright (C) 2015 lzwdgc
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
const int build_version =
|
||||||
|
#include <version.h.in>
|
||||||
|
;
|
||||||
|
|
||||||
|
std::string version()
|
||||||
|
{
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
string s;
|
||||||
|
s = to_string(0) + "." +
|
||||||
|
to_string(1) + "." +
|
||||||
|
to_string(0) + "." +
|
||||||
|
to_string(build_version);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> readFile(const std::string &fn)
|
||||||
|
{
|
||||||
|
FILE *f = fopen(fn.c_str(), "rb");
|
||||||
|
if (!f)
|
||||||
|
throw std::runtime_error("Cannot open file " + fn);
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
auto sz = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
std::vector<uint8_t> buf(sz);
|
||||||
|
fread(buf.data(), 1, sz, f);
|
||||||
|
fclose(f);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer::buffer()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer::buffer(const std::vector<uint8_t> &buf, uint32_t data_offset)
|
||||||
|
: buf(new std::vector<uint8_t>(buf)), data_offset(data_offset)
|
||||||
|
{
|
||||||
|
skip(0);
|
||||||
|
size = buf.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer::buffer(buffer &rhs, uint32_t size)
|
||||||
|
: buf(rhs.buf)
|
||||||
|
{
|
||||||
|
index = rhs.index;
|
||||||
|
data_offset = rhs.data_offset;
|
||||||
|
ptr = rhs.ptr;
|
||||||
|
this->size = index + size;
|
||||||
|
rhs.skip(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer::buffer(buffer &rhs, uint32_t size, uint32_t offset)
|
||||||
|
: buf(rhs.buf)
|
||||||
|
{
|
||||||
|
index = offset;
|
||||||
|
data_offset = offset;
|
||||||
|
ptr = (uint8_t *)buf->data() + index;
|
||||||
|
this->size = index + size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t buffer::read(void *dst, uint32_t size, bool nothrow)
|
||||||
|
{
|
||||||
|
if (!buf)
|
||||||
|
throw std::logic_error("buffer: not initialized");
|
||||||
|
if (index >= this->size)
|
||||||
|
{
|
||||||
|
if (nothrow)
|
||||||
|
return 0;
|
||||||
|
throw std::logic_error("buffer: out of range");
|
||||||
|
}
|
||||||
|
if (index + size > this->size)
|
||||||
|
size = this->size - index;
|
||||||
|
memcpy(dst, buf->data() + index, size);
|
||||||
|
skip(size);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void buffer::skip(int n)
|
||||||
|
{
|
||||||
|
if (!buf)
|
||||||
|
throw std::logic_error("buffer: not initialized");
|
||||||
|
index += n;
|
||||||
|
data_offset += n;
|
||||||
|
ptr = (uint8_t *)buf->data() + index;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool buffer::check(int index) const
|
||||||
|
{
|
||||||
|
return this->index == index;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool buffer::eof() const
|
||||||
|
{
|
||||||
|
return check(this->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t buffer::getIndex() const
|
||||||
|
{
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t buffer::getSize() const
|
||||||
|
{
|
||||||
|
return this->size;
|
||||||
|
}
|
||||||
55
src/common/common.h
Normal file
55
src/common/common.h
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* AIM tools
|
||||||
|
* Copyright (C) 2015 lzwdgc
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define READ(b, var) b.read(&var, sizeof(var))
|
||||||
|
#define READ_NOTHROW(b, var) b.read(&var, sizeof(var), true)
|
||||||
|
#define READ_N(b, var, sz) b.read(&var, sz)
|
||||||
|
|
||||||
|
std::string version();
|
||||||
|
std::vector<uint8_t> readFile(const std::string &fn);
|
||||||
|
|
||||||
|
class buffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
buffer();
|
||||||
|
buffer(const std::vector<uint8_t> &buf, uint32_t data_offset = 0);
|
||||||
|
buffer(buffer &rhs, uint32_t size);
|
||||||
|
buffer(buffer &rhs, uint32_t size, uint32_t offset);
|
||||||
|
|
||||||
|
uint32_t read(void *dst, uint32_t size, bool nothrow = false);
|
||||||
|
void skip(int n);
|
||||||
|
bool eof() const;
|
||||||
|
bool check(int index) const;
|
||||||
|
|
||||||
|
uint32_t getIndex() const;
|
||||||
|
uint32_t getSize() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<const std::vector<uint8_t>> buf;
|
||||||
|
uint32_t index = 0;
|
||||||
|
uint8_t *ptr = 0;
|
||||||
|
uint32_t data_offset = 0;
|
||||||
|
uint32_t size = 0;
|
||||||
|
};
|
||||||
|
|
@ -18,9 +18,7 @@
|
||||||
|
|
||||||
#include "db.h"
|
#include "db.h"
|
||||||
|
|
||||||
#define FREAD(var) fread(&var, 1, sizeof(var), f)
|
#include <common.h>
|
||||||
#define SREAD(var) s.read(&var, sizeof(var))
|
|
||||||
#define SREAD_N(var, sz) s.read(&var, sz)
|
|
||||||
|
|
||||||
string getSqlType(uint32_t ft)
|
string getSqlType(uint32_t ft)
|
||||||
{
|
{
|
||||||
|
|
@ -38,37 +36,37 @@ string getSqlType(uint32_t ft)
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void table::load(FILE *f)
|
void table::load(buffer &b)
|
||||||
{
|
{
|
||||||
FREAD(id);
|
READ(b, id);
|
||||||
FREAD(name);
|
READ(b, name);
|
||||||
FREAD(unk1);
|
READ(b, unk1);
|
||||||
FREAD(unk2);
|
READ(b, unk2);
|
||||||
FREAD(unk3);
|
READ(b, unk3);
|
||||||
FREAD(unk4);
|
READ(b, unk4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void field::load(FILE *f)
|
void field::load(buffer &b)
|
||||||
{
|
{
|
||||||
FREAD(table_id);
|
READ(b, table_id);
|
||||||
FREAD(id);
|
READ(b, id);
|
||||||
FREAD(name);
|
READ(b, name);
|
||||||
FREAD(unk1);
|
READ(b, unk1);
|
||||||
FREAD(unk2);
|
READ(b, unk2);
|
||||||
FREAD(unk3);
|
READ(b, unk3);
|
||||||
FREAD(type);
|
READ(b, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tab::load(FILE *f)
|
void tab::load(buffer &b)
|
||||||
{
|
{
|
||||||
FREAD(number_of_tables);
|
READ(b, number_of_tables);
|
||||||
FREAD(number_of_fields);
|
READ(b, number_of_fields);
|
||||||
|
|
||||||
auto n = number_of_tables;
|
auto n = number_of_tables;
|
||||||
while (n--)
|
while (n--)
|
||||||
{
|
{
|
||||||
table t;
|
table t;
|
||||||
t.load(f);
|
t.load(b);
|
||||||
tables[t.id] = t;
|
tables[t.id] = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,39 +74,35 @@ void tab::load(FILE *f)
|
||||||
while (n--)
|
while (n--)
|
||||||
{
|
{
|
||||||
field t;
|
field t;
|
||||||
t.load(f);
|
t.load(b);
|
||||||
fields[t.id] = t;
|
fields[t.id] = t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void value::load_index(FILE *f)
|
void value::load_index(buffer &b)
|
||||||
{
|
{
|
||||||
FREAD(table_id);
|
READ(b, table_id);
|
||||||
FREAD(name);
|
READ(b, name);
|
||||||
FREAD(unk1);
|
READ(b, unk1);
|
||||||
FREAD(unk2);
|
READ(b, unk2);
|
||||||
FREAD(unk3);
|
READ(b, unk3);
|
||||||
FREAD(offset);
|
READ(b, offset);
|
||||||
FREAD(data_size);
|
READ(b, data_size);
|
||||||
buf.resize(data_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void value::load_data(FILE *f)
|
void value::load_data(buffer &b)
|
||||||
{
|
{
|
||||||
fseek(f, offset, SEEK_SET);
|
data = buffer(b, data_size, offset);
|
||||||
fread(buf.data(), buf.size(), 1, f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void value::extract_fields(const tab &tab)
|
void value::extract_fields(const tab &tab)
|
||||||
{
|
{
|
||||||
s_file s(buf);
|
while (!data.eof())
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
{
|
||||||
field_value fv;
|
field_value fv;
|
||||||
if (SREAD(fv.field_id) == 0)
|
if (READ_NOTHROW(data, fv.field_id) == 0)
|
||||||
break;
|
break;
|
||||||
SREAD(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())
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -116,17 +110,17 @@ void value::extract_fields(const tab &tab)
|
||||||
{
|
{
|
||||||
case T_STRING:
|
case T_STRING:
|
||||||
fv.s.resize(fv.size);
|
fv.s.resize(fv.size);
|
||||||
SREAD_N(fv.s[0], fv.s.size());
|
READ_N(data, fv.s[0], fv.s.size());
|
||||||
break;
|
break;
|
||||||
case T_INTEGER:
|
case T_INTEGER:
|
||||||
SREAD(fv.i);
|
READ(data, fv.i);
|
||||||
if (fv.size > sizeof(fv.i))
|
if (fv.size > sizeof(fv.i))
|
||||||
s.skip(fv.size - sizeof(fv.i));
|
data.skip(fv.size - sizeof(fv.i));
|
||||||
break;
|
break;
|
||||||
case T_FLOAT:
|
case T_FLOAT:
|
||||||
SREAD(fv.f);
|
READ(data, fv.f);
|
||||||
if (fv.size > sizeof(fv.i))
|
if (fv.size > sizeof(fv.i))
|
||||||
s.skip(fv.size - sizeof(fv.i));
|
data.skip(fv.size - sizeof(fv.i));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
|
|
@ -135,15 +129,15 @@ void value::extract_fields(const tab &tab)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void db::load(FILE *f)
|
void db::load(buffer &b)
|
||||||
{
|
{
|
||||||
FREAD(number_of_values);
|
READ(b, number_of_values);
|
||||||
|
|
||||||
auto n = number_of_values;
|
auto n = number_of_values;
|
||||||
while (n--)
|
while (n--)
|
||||||
{
|
{
|
||||||
value t;
|
value t;
|
||||||
t.load_index(f);
|
t.load_index(b);
|
||||||
values.push_back(t);
|
values.push_back(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -24,6 +24,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
enum FieldType
|
enum FieldType
|
||||||
|
|
@ -43,7 +45,7 @@ struct table
|
||||||
uint32_t unk3;
|
uint32_t unk3;
|
||||||
uint32_t unk4;
|
uint32_t unk4;
|
||||||
|
|
||||||
void load(FILE *f);
|
void load(buffer &b);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct field
|
struct field
|
||||||
|
|
@ -56,7 +58,7 @@ struct field
|
||||||
uint32_t unk3;
|
uint32_t unk3;
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
|
|
||||||
void load(FILE *f);
|
void load(buffer &b);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tab
|
struct tab
|
||||||
|
|
@ -67,7 +69,7 @@ struct tab
|
||||||
map<uint32_t, table> tables;
|
map<uint32_t, table> tables;
|
||||||
map<uint32_t, field> fields;
|
map<uint32_t, field> fields;
|
||||||
|
|
||||||
void load(FILE *f);
|
void load(buffer &b);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct field_value
|
struct field_value
|
||||||
|
|
@ -82,30 +84,6 @@ struct field_value
|
||||||
|
|
||||||
struct value
|
struct value
|
||||||
{
|
{
|
||||||
struct s_file
|
|
||||||
{
|
|
||||||
uint32_t index = 0;
|
|
||||||
const vector<char> buf;
|
|
||||||
|
|
||||||
s_file(const vector<char> &buf)
|
|
||||||
: buf(buf)
|
|
||||||
{}
|
|
||||||
uint32_t read(void *dst, uint32_t size)
|
|
||||||
{
|
|
||||||
if (index >= buf.size())
|
|
||||||
return 0;
|
|
||||||
if (index + size > buf.size())
|
|
||||||
size = buf.size() - index;
|
|
||||||
memcpy(dst, buf.data() + index, size);
|
|
||||||
index += size;
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
void skip(int n)
|
|
||||||
{
|
|
||||||
index += n;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t table_id;
|
uint32_t table_id;
|
||||||
char name[0x14];
|
char name[0x14];
|
||||||
uint32_t unk1;
|
uint32_t unk1;
|
||||||
|
|
@ -113,17 +91,14 @@ struct value
|
||||||
uint32_t unk3;
|
uint32_t unk3;
|
||||||
uint32_t offset;
|
uint32_t offset;
|
||||||
uint32_t data_size;
|
uint32_t data_size;
|
||||||
|
buffer data;
|
||||||
//
|
|
||||||
vector<char> buf;
|
|
||||||
//
|
|
||||||
uint32_t number_of_fields;
|
uint32_t number_of_fields;
|
||||||
vector<field_value> fields;
|
vector<field_value> fields;
|
||||||
|
|
||||||
void extract_fields(const tab &tab);
|
void extract_fields(const tab &tab);
|
||||||
|
|
||||||
void load_index(FILE *f);
|
void load_index(buffer &b);
|
||||||
void load_data(FILE *f);
|
void load_data(buffer &b);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct db
|
struct db
|
||||||
|
|
@ -133,5 +108,5 @@ struct db
|
||||||
tab t;
|
tab t;
|
||||||
vector<value> values;
|
vector<value> values;
|
||||||
|
|
||||||
void load(FILE *f);
|
void load(buffer &b);
|
||||||
};
|
};
|
||||||
|
|
@ -22,42 +22,15 @@
|
||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
||||||
void open_tab(string path, tab &tab)
|
#include <common.h>
|
||||||
{
|
|
||||||
path += ".tab";
|
|
||||||
FILE *f = fopen(path.c_str(), "rb");
|
|
||||||
if (!f)
|
|
||||||
return;
|
|
||||||
tab.load(f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void open_index(string path, db &index)
|
|
||||||
{
|
|
||||||
path += ".ind";
|
|
||||||
FILE *f = fopen(path.c_str(), "rb");
|
|
||||||
if (!f)
|
|
||||||
return;
|
|
||||||
index.load(f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void open_data(string path, db &index)
|
|
||||||
{
|
|
||||||
path += ".dat";
|
|
||||||
FILE *f = fopen(path.c_str(), "rb");
|
|
||||||
if (!f)
|
|
||||||
return;
|
|
||||||
for (auto &v : index.values)
|
|
||||||
v.load_data(f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void open_db(string path, db &db)
|
void open_db(string path, db &db)
|
||||||
{
|
{
|
||||||
open_tab(path, db.t);
|
db.t.load(buffer(readFile(path + ".tab")));
|
||||||
open_index(path, db);
|
db.load(buffer(readFile(path + ".ind")));
|
||||||
open_data(path, db);
|
buffer b(readFile(path + ".dat"));
|
||||||
|
for (auto &v : db.values)
|
||||||
|
v.load_data(b);
|
||||||
for (auto &v : db.values)
|
for (auto &v : db.values)
|
||||||
v.extract_fields(db.t);
|
v.extract_fields(db.t);
|
||||||
}
|
}
|
||||||
|
|
@ -179,6 +152,7 @@ void create_sql(string path, const db &db)
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
{
|
{
|
||||||
|
|
@ -190,4 +164,14 @@ int main(int argc, char *argv[])
|
||||||
open_db(path, db);
|
open_db(path, db);
|
||||||
create_sql(path, db);
|
create_sql(path, db);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
catch (std::exception &e)
|
||||||
|
{
|
||||||
|
printf("error: %s\n", e.what());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
printf("error: unknown exception\n");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -21,58 +21,31 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
using namespace std;
|
#include <common.h>
|
||||||
|
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
|
|
||||||
const int build_version =
|
using namespace std;
|
||||||
#include <version.h.in>
|
|
||||||
;
|
|
||||||
|
|
||||||
std::string version()
|
|
||||||
{
|
|
||||||
string s;
|
|
||||||
s = to_string(0) + "." +
|
|
||||||
to_string(1) + "." +
|
|
||||||
to_string(0) + "." +
|
|
||||||
to_string(build_version);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void convert_model(string fn)
|
void convert_model(string fn)
|
||||||
{
|
{
|
||||||
|
printf("%s\n", fn.c_str());
|
||||||
|
|
||||||
|
buffer b(readFile(fn));
|
||||||
model m;
|
model m;
|
||||||
FILE *f = fopen(fn.c_str(), "rb");
|
m.load(b);
|
||||||
if (!f)
|
|
||||||
return;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
m.load(f);
|
|
||||||
|
|
||||||
auto p = ftell(f);
|
if (!b.eof())
|
||||||
fseek(f, 0, SEEK_END);
|
|
||||||
auto end = ftell(f);
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
if (p != end)
|
|
||||||
{
|
|
||||||
stringstream ss;
|
|
||||||
ss << hex << p << " != " << hex << end;
|
|
||||||
throw std::logic_error(ss.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (std::exception &e)
|
|
||||||
{
|
{
|
||||||
printf("error: %s\n", fn.c_str());
|
stringstream ss;
|
||||||
printf("%s\n", e.what());
|
ss << hex << b.getIndex() << " != " << hex << b.getSize();
|
||||||
fclose(f);
|
throw std::logic_error(ss.str());
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m.writeObj(fn + ".obj");
|
m.writeObj(fn + ".obj");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
try
|
||||||
{
|
{
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
if (argc != 2)
|
if (argc != 2)
|
||||||
|
|
@ -98,4 +71,14 @@ int main(int argc, char *argv[])
|
||||||
convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_GL_M1_A_ATTACKER_DAMAGED");
|
convert_model("h:\\Games\\AIM\\data\\res0.pak.dir\\Data\\Models\\MOD_GL_M1_A_ATTACKER_DAMAGED");
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
catch (std::exception &e)
|
||||||
|
{
|
||||||
|
printf("error: %s\n", e.what());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
printf("error: unknown exception\n");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -20,31 +20,28 @@
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <time.h>
|
|
||||||
|
#include <common.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
std::string version();
|
std::string version();
|
||||||
|
|
||||||
#define FREAD(var) fread(&var, 1, sizeof(var), f)
|
void vertex::load(buffer &b, uint32_t flags)
|
||||||
#define SREAD(var) s.read(&var, sizeof(var))
|
|
||||||
#define SREAD_N(var, sz) s.read(&var, sz)
|
|
||||||
|
|
||||||
void vertex::load(s_file &s, uint32_t flags)
|
|
||||||
{
|
{
|
||||||
SREAD(vX);
|
READ(b, vX);
|
||||||
SREAD(vZ);
|
READ(b, vZ);
|
||||||
SREAD(vY);
|
READ(b, vY);
|
||||||
|
|
||||||
if (flags & F_WIND)
|
if (flags & F_WIND)
|
||||||
SREAD(wind);
|
READ(b, wind);
|
||||||
|
|
||||||
SREAD(nX);
|
READ(b, nX);
|
||||||
SREAD(nZ);
|
READ(b, nZ);
|
||||||
SREAD(nY);
|
READ(b, nY);
|
||||||
|
|
||||||
SREAD(t1);
|
READ(b, t1);
|
||||||
SREAD(t2);
|
READ(b, t2);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string vertex::printVertex() const
|
std::string vertex::printVertex() const
|
||||||
|
|
@ -68,50 +65,46 @@ std::string vertex::printTex() const
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fragment::load(FILE *f)
|
void fragment::load(buffer &b)
|
||||||
{
|
{
|
||||||
FREAD(type);
|
// header
|
||||||
FREAD(name0);
|
READ(b, type);
|
||||||
FREAD(name1);
|
READ(b, name0);
|
||||||
FREAD(name2);
|
READ(b, name1);
|
||||||
FREAD(name3);
|
READ(b, name2);
|
||||||
FREAD(name4);
|
READ(b, name3);
|
||||||
FREAD(unk0);
|
READ(b, name4);
|
||||||
FREAD(unk1);
|
READ(b, unk0);
|
||||||
FREAD(unk2);
|
READ(b, unk1);
|
||||||
FREAD(unk3);
|
READ(b, unk2);
|
||||||
FREAD(size);
|
READ(b, unk3);
|
||||||
FREAD(unk4);
|
READ(b, size);
|
||||||
data.resize(size);
|
READ(b, unk4);
|
||||||
data_offset = ftell(f);
|
|
||||||
fread(data.data(), 1, size, f);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool fragment::extract()
|
// data
|
||||||
{
|
buffer data(b, size);
|
||||||
s_file s(data, data_offset);
|
READ(data, n_segments);
|
||||||
|
|
||||||
SREAD(n_segments);
|
|
||||||
segments.resize(n_segments);
|
segments.resize(n_segments);
|
||||||
SREAD(header);
|
READ(data, header);
|
||||||
SREAD(triangles_mult_7);
|
READ(data, triangles_mult_7);
|
||||||
SREAD(unk10);
|
READ(data, unk10);
|
||||||
SREAD(flags);
|
READ(data, flags);
|
||||||
SREAD(n_vertex);
|
READ(data, n_vertex);
|
||||||
vertices.resize(n_vertex);
|
vertices.resize(n_vertex);
|
||||||
SREAD(n_triangles);
|
READ(data, n_triangles);
|
||||||
if (triangles_mult_7)
|
if (triangles_mult_7)
|
||||||
n_triangles *= 7;
|
n_triangles *= 7;
|
||||||
triangles.resize(n_triangles);
|
triangles.resize(n_triangles);
|
||||||
for (auto &v : vertices)
|
for (auto &v : vertices)
|
||||||
v.load(s, flags);
|
v.load(data, flags);
|
||||||
for (auto &t : triangles)
|
for (auto &t : triangles)
|
||||||
SREAD(t);
|
READ(data, t);
|
||||||
|
|
||||||
|
// segments
|
||||||
for (auto &seg : segments)
|
for (auto &seg : segments)
|
||||||
{
|
{
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
SREAD(type);
|
READ(data, type);
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
|
|
@ -127,94 +120,91 @@ bool fragment::extract()
|
||||||
throw std::logic_error("unknown segment type " + std::to_string(type));
|
throw std::logic_error("unknown segment type " + std::to_string(type));
|
||||||
}
|
}
|
||||||
seg->type = type;
|
seg->type = type;
|
||||||
seg->extract(s);
|
seg->load(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.eof();
|
if (!data.eof())
|
||||||
|
throw std::logic_error("extraction error: fragment #" + std::string(name0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void segment1::extract(s_file &s)
|
void segment1::load(buffer &b)
|
||||||
{
|
{
|
||||||
SREAD(name);
|
READ(b, name);
|
||||||
SREAD(unk0);
|
READ(b, unk0);
|
||||||
triangles.resize(unk0[0][0]);
|
triangles.resize(unk0[0][0]);
|
||||||
unk1.resize(unk0[0][0]);
|
unk1.resize(unk0[0][0]);
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
for (auto &t : triangles)
|
for (auto &t : triangles)
|
||||||
SREAD(t);
|
READ(b, t);
|
||||||
for (auto &unk: unk1)
|
for (auto &unk: unk1)
|
||||||
SREAD(unk);
|
READ(b, unk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void segment2::extract(s_file &s)
|
void segment2::load(buffer &b)
|
||||||
{
|
{
|
||||||
SREAD(name);
|
READ(b, name);
|
||||||
SREAD(unk0);
|
READ(b, unk0);
|
||||||
triangles.resize(unk0[0][0]);
|
triangles.resize(unk0[0][0]);
|
||||||
unk1.resize(unk0[0][0]);
|
unk1.resize(unk0[0][0]);
|
||||||
unk1_1.resize(unk0[0][0]);
|
unk1_1.resize(unk0[0][0]);
|
||||||
for (auto &t : triangles)
|
for (auto &t : triangles)
|
||||||
SREAD(t);
|
READ(b, t);
|
||||||
for (auto &unk : unk1)
|
for (auto &unk : unk1)
|
||||||
SREAD(unk);
|
READ(b, unk);
|
||||||
for (auto &unk : unk1_1)
|
for (auto &unk : unk1_1)
|
||||||
SREAD(unk);
|
READ(b, unk);
|
||||||
while (!s.eof())
|
while (!b.eof())
|
||||||
{
|
{
|
||||||
repeater r;
|
repeater r;
|
||||||
r.extract(s);
|
r.load(b);
|
||||||
unk2.push_back(r);
|
unk2.push_back(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void segment2::repeater::extract(s_file &s)
|
void segment2::repeater::load(buffer &b)
|
||||||
{
|
{
|
||||||
SREAD(unk2);
|
READ(b, unk2);
|
||||||
triangles2.resize(unk2);
|
triangles2.resize(unk2);
|
||||||
SREAD(unk8);
|
READ(b, unk8);
|
||||||
SREAD(unk3);
|
READ(b, unk3);
|
||||||
for (auto &t : triangles2)
|
for (auto &t : triangles2)
|
||||||
SREAD(t);
|
READ(b, t);
|
||||||
SREAD(unk6);
|
READ(b, unk6);
|
||||||
SREAD(flags);
|
READ(b, flags);
|
||||||
SREAD(n_vertex);
|
READ(b, n_vertex);
|
||||||
vertices.resize(n_vertex);
|
vertices.resize(n_vertex);
|
||||||
SREAD(n_triangles);
|
READ(b, n_triangles);
|
||||||
triangles.resize(n_triangles);
|
triangles.resize(n_triangles);
|
||||||
for (auto &v : vertices)
|
for (auto &v : vertices)
|
||||||
v.load(s, flags);
|
v.load(b, flags);
|
||||||
for (auto &t : triangles)
|
for (auto &t : triangles)
|
||||||
SREAD(t);
|
READ(b, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
void segment6::extract(s_file &s)
|
void segment6::load(buffer &b)
|
||||||
{
|
{
|
||||||
SREAD(name);
|
READ(b, name);
|
||||||
SREAD(unk0);
|
READ(b, unk0);
|
||||||
triangles.resize(unk0[0][0]);
|
triangles.resize(unk0[0][0]);
|
||||||
for (int i = 0; i < 1; i++)
|
for (int i = 0; i < 1; i++)
|
||||||
{
|
{
|
||||||
for (auto &t : triangles)
|
for (auto &t : triangles)
|
||||||
SREAD(t);
|
READ(b, t);
|
||||||
char unk1[0x30]; // some 6 floats
|
char unk1[0x30]; // some 6 floats
|
||||||
for (int i = 0; i < unk0[0][0]; i++)
|
for (int i = 0; i < unk0[0][0]; i++)
|
||||||
SREAD(unk1);
|
READ(b, unk1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void model::load(FILE *f)
|
void model::load(buffer &b)
|
||||||
{
|
{
|
||||||
FREAD(n_fragments);
|
READ(b, n_fragments);
|
||||||
FREAD(header);
|
READ(b, header);
|
||||||
fragments.resize(n_fragments);
|
fragments.resize(n_fragments);
|
||||||
for (int i = 0; i < fragments.size(); i++)
|
for (auto &f : fragments)
|
||||||
{
|
f.load(b);
|
||||||
fragments[i].load(f);
|
|
||||||
if (!fragments[i].extract())
|
|
||||||
throw std::logic_error("extraction error: fragment #" + std::to_string(i));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void model::writeObj(std::string fn)
|
void model::writeObj(std::string fn)
|
||||||
|
|
|
||||||
|
|
@ -22,37 +22,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct s_file
|
class buffer;
|
||||||
{
|
|
||||||
uint32_t index = 0;
|
|
||||||
const std::vector<uint8_t> &buf;
|
|
||||||
uint8_t *ptr;
|
|
||||||
uint32_t data_offset;
|
|
||||||
|
|
||||||
s_file(const std::vector<uint8_t> &buf, uint32_t data_offset)
|
|
||||||
: buf(buf), data_offset(data_offset)
|
|
||||||
{}
|
|
||||||
uint32_t read(void *dst, uint32_t size)
|
|
||||||
{
|
|
||||||
if (index >= buf.size())
|
|
||||||
throw std::logic_error("s_file: out of range");
|
|
||||||
if (index + size > buf.size())
|
|
||||||
size = buf.size() - index;
|
|
||||||
memcpy(dst, buf.data() + index, size);
|
|
||||||
skip(size);
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
void skip(int n)
|
|
||||||
{
|
|
||||||
index += n;
|
|
||||||
data_offset += n;
|
|
||||||
ptr = (uint8_t *)buf.data() + index;
|
|
||||||
}
|
|
||||||
bool eof() const
|
|
||||||
{
|
|
||||||
return index == buf.size();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
|
@ -74,7 +44,7 @@ struct vertex
|
||||||
float t1;
|
float t1;
|
||||||
float t2;
|
float t2;
|
||||||
|
|
||||||
void load(s_file &s, uint32_t flags);
|
void load(buffer &b, uint32_t flags);
|
||||||
|
|
||||||
std::string printVertex() const;
|
std::string printVertex() const;
|
||||||
std::string printNormal() const;
|
std::string printNormal() const;
|
||||||
|
|
@ -97,7 +67,7 @@ struct segment
|
||||||
{
|
{
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
|
|
||||||
virtual void extract(s_file &s) = 0;
|
virtual void load(buffer &b) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct segment1 : public segment
|
struct segment1 : public segment
|
||||||
|
|
@ -107,7 +77,7 @@ struct segment1 : public segment
|
||||||
std::vector<triangle> triangles;
|
std::vector<triangle> triangles;
|
||||||
std::vector<unk_float3x4> unk1;
|
std::vector<unk_float3x4> unk1;
|
||||||
|
|
||||||
virtual void extract(s_file &s);
|
virtual void load(buffer &b);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct segment2 : public segment
|
struct segment2 : public segment
|
||||||
|
|
@ -125,7 +95,7 @@ struct segment2 : public segment
|
||||||
std::vector<vertex> vertices;
|
std::vector<vertex> vertices;
|
||||||
std::vector<uint16_t> triangles;
|
std::vector<uint16_t> triangles;
|
||||||
|
|
||||||
virtual void extract(s_file &s);
|
virtual void load(buffer &b);
|
||||||
};
|
};
|
||||||
|
|
||||||
char name[0xC];
|
char name[0xC];
|
||||||
|
|
@ -135,17 +105,17 @@ struct segment2 : public segment
|
||||||
std::vector<unk_float6> unk1_1;
|
std::vector<unk_float6> unk1_1;
|
||||||
std::vector<repeater> unk2;
|
std::vector<repeater> unk2;
|
||||||
|
|
||||||
virtual void extract(s_file &s);
|
virtual void load(buffer &b);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct segment6 : public segment1
|
struct segment6 : public segment1
|
||||||
{
|
{
|
||||||
virtual void extract(s_file &s);
|
virtual void load(buffer &b);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fragment
|
struct fragment
|
||||||
{
|
{
|
||||||
// main header
|
// header
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
char name0[0x20];
|
char name0[0x20];
|
||||||
char name1[0x20];
|
char name1[0x20];
|
||||||
|
|
@ -159,10 +129,7 @@ struct fragment
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
uint32_t unk4[10];
|
uint32_t unk4[10];
|
||||||
|
|
||||||
// data buffer
|
// data
|
||||||
std::vector<uint8_t> data;
|
|
||||||
|
|
||||||
// main data
|
|
||||||
uint32_t n_segments;
|
uint32_t n_segments;
|
||||||
char header[0x68];
|
char header[0x68];
|
||||||
uint32_t triangles_mult_7;
|
uint32_t triangles_mult_7;
|
||||||
|
|
@ -176,11 +143,7 @@ struct fragment
|
||||||
// segments
|
// segments
|
||||||
std::vector<segment *> segments;
|
std::vector<segment *> segments;
|
||||||
|
|
||||||
// internal vars
|
void load(buffer &b);
|
||||||
uint32_t data_offset;
|
|
||||||
|
|
||||||
void load(FILE *f);
|
|
||||||
bool extract();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct model
|
struct model
|
||||||
|
|
@ -189,6 +152,6 @@ struct model
|
||||||
char header[0x40];
|
char header[0x40];
|
||||||
std::vector<fragment> fragments;
|
std::vector<fragment> fragments;
|
||||||
|
|
||||||
void load(FILE *f);
|
void load(buffer &b);
|
||||||
void writeObj(std::string fn);
|
void writeObj(std::string fn);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@
|
||||||
|
|
||||||
#include <Polygon4/Storage.h>
|
#include <Polygon4/Storage.h>
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
struct storage
|
struct storage
|
||||||
|
|
@ -39,27 +41,31 @@ struct storage
|
||||||
MapGoods mg;
|
MapGoods mg;
|
||||||
MapMusic mm;
|
MapMusic mm;
|
||||||
MapSounds ms;
|
MapSounds ms;
|
||||||
|
|
||||||
|
void load(buffer &b)
|
||||||
|
{
|
||||||
|
objects.load(b);
|
||||||
|
mgs.load(b);
|
||||||
|
if (b.eof()) // custom maps
|
||||||
|
return;
|
||||||
|
mg.load(b);
|
||||||
|
mm.load(b);
|
||||||
|
ms.load(b);
|
||||||
|
|
||||||
|
if (!b.eof())
|
||||||
|
{
|
||||||
|
stringstream ss;
|
||||||
|
ss << hex << b.getIndex() << " != " << hex << b.getSize();
|
||||||
|
throw std::logic_error(ss.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
storage read_mmo(string fn)
|
storage read_mmo(string fn)
|
||||||
{
|
{
|
||||||
storage s;
|
storage s;
|
||||||
s.name = fn;
|
s.name = fn;
|
||||||
FILE *f = fopen(fn.c_str(), "rb");
|
s.load(buffer(readFile(fn)));
|
||||||
if (!f)
|
|
||||||
return s;
|
|
||||||
s.objects.load(f);
|
|
||||||
s.mgs.load(f);
|
|
||||||
if (feof(f))
|
|
||||||
{
|
|
||||||
// custom maps?
|
|
||||||
fclose(f);
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
s.mg.load(f);
|
|
||||||
s.mm.load(f);
|
|
||||||
s.ms.load(f);
|
|
||||||
fclose(f);
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -197,6 +203,7 @@ void write_mmo(string db, const storage &s)
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (argc != 3)
|
if (argc != 3)
|
||||||
{
|
{
|
||||||
|
|
@ -206,4 +213,14 @@ int main(int argc, char *argv[])
|
||||||
storage s = read_mmo(argv[2]);
|
storage s = read_mmo(argv[2]);
|
||||||
write_mmo(argv[1], s);
|
write_mmo(argv[1], s);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
catch (std::exception &e)
|
||||||
|
{
|
||||||
|
printf("error: %s\n", e.what());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
printf("error: unknown exception\n");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -18,10 +18,10 @@
|
||||||
|
|
||||||
#include "objects.h"
|
#include "objects.h"
|
||||||
|
|
||||||
Segment *Segment::create_segment(FILE *f)
|
Segment *Segment::create_segment(buffer &b)
|
||||||
{
|
{
|
||||||
SegmentType segment_type;
|
SegmentType segment_type;
|
||||||
FREAD(segment_type);
|
READ(b, segment_type);
|
||||||
|
|
||||||
Segment *segment = 0;
|
Segment *segment = 0;
|
||||||
switch (segment_type)
|
switch (segment_type)
|
||||||
|
|
@ -78,22 +78,22 @@ Segment *Segment::create_segment(FILE *f)
|
||||||
if (segment)
|
if (segment)
|
||||||
{
|
{
|
||||||
segment->segment_type = segment_type;
|
segment->segment_type = segment_type;
|
||||||
FREAD(segment->segment_len);
|
READ(b, segment->segment_len);
|
||||||
FREAD(segment->n_objects);
|
READ(b, segment->n_objects);
|
||||||
}
|
}
|
||||||
return segment;
|
return segment;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Objects::load(FILE *f)
|
void Objects::load(buffer &b)
|
||||||
{
|
{
|
||||||
FREAD(n_segments);
|
READ(b, n_segments);
|
||||||
|
|
||||||
for (int s = 0; s < n_segments; s++)
|
for (int s = 0; s < n_segments; s++)
|
||||||
{
|
{
|
||||||
auto seg = Segment::create_segment(f);
|
auto seg = Segment::create_segment(b);
|
||||||
if (!seg)
|
if (!seg)
|
||||||
break;
|
break;
|
||||||
seg->load(f);
|
seg->load(b);
|
||||||
segments.push_back(seg);
|
segments.push_back(seg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#define FREAD(var) fread(&var, 1, sizeof(var), f)
|
#include <common.h>
|
||||||
#define FREAD_N(var, n) fread(&var, 1, n, f)
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
@ -71,8 +70,8 @@ struct Segment
|
||||||
uint32_t n_objects;
|
uint32_t n_objects;
|
||||||
|
|
||||||
virtual ~Segment(){}
|
virtual ~Segment(){}
|
||||||
static Segment *create_segment(FILE *f);
|
static Segment *create_segment(buffer &b);
|
||||||
virtual void load(FILE *f) = 0;
|
virtual void load(buffer &b) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|
@ -80,12 +79,12 @@ struct SegmentObjects : public Segment
|
||||||
{
|
{
|
||||||
vector<T> objects;
|
vector<T> objects;
|
||||||
|
|
||||||
virtual void load(FILE *f)
|
virtual void load(buffer &b)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < n_objects; i++)
|
for (int i = 0; i < n_objects; i++)
|
||||||
{
|
{
|
||||||
T r;
|
T r;
|
||||||
r.load(f);
|
r.load(b);
|
||||||
objects.push_back(r);
|
objects.push_back(r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -104,10 +103,10 @@ struct Common
|
||||||
Vector4 m_rotate_z[3];
|
Vector4 m_rotate_z[3];
|
||||||
Vector4 position;
|
Vector4 position;
|
||||||
|
|
||||||
void load(FILE *f)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
FREAD(m_rotate_z);
|
READ(b, m_rotate_z);
|
||||||
FREAD(position);
|
READ(b, position);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -116,12 +115,12 @@ struct MapObject : public Common
|
||||||
char name1[0x20];
|
char name1[0x20];
|
||||||
char name2[0x20];
|
char name2[0x20];
|
||||||
|
|
||||||
void load(FILE *f)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
Common::load(f);
|
Common::load(b);
|
||||||
|
|
||||||
FREAD(name1);
|
READ(b, name1);
|
||||||
FREAD(name2);
|
READ(b, name2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -130,14 +129,14 @@ struct MapObjectWithArray : public MapObject
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
vector<uint32_t> unk7;
|
vector<uint32_t> unk7;
|
||||||
|
|
||||||
void load(FILE *f)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
MapObject::load(f);
|
MapObject::load(b);
|
||||||
|
|
||||||
FREAD(len);
|
READ(b, len);
|
||||||
unk7.resize(len);
|
unk7.resize(len);
|
||||||
for (int i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
FREAD(unk7[i]);
|
READ(b, unk7[i]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -146,12 +145,12 @@ struct Sound : public Common
|
||||||
uint32_t unk1[11];
|
uint32_t unk1[11];
|
||||||
char name1[0x14];
|
char name1[0x14];
|
||||||
|
|
||||||
void load(FILE *f)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
Common::load(f);
|
Common::load(b);
|
||||||
|
|
||||||
FREAD(unk1);
|
READ(b, unk1);
|
||||||
FREAD(name1);
|
READ(b, name1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -172,7 +171,7 @@ KNOWN_OBJECT(Anomaly);
|
||||||
KNOWN_OBJECT(Boundary);
|
KNOWN_OBJECT(Boundary);
|
||||||
|
|
||||||
#define UNKNOWN_OBJECT(name) \
|
#define UNKNOWN_OBJECT(name) \
|
||||||
struct name : public MapObject { void load(FILE *f){ int pos = ftell(f); assert(false); } }
|
struct name : public MapObject { void load(buffer &b){ int pos = b.getIndex(); assert(false); } }
|
||||||
|
|
||||||
UNKNOWN_OBJECT(Building);
|
UNKNOWN_OBJECT(Building);
|
||||||
UNKNOWN_OBJECT(Goods);
|
UNKNOWN_OBJECT(Goods);
|
||||||
|
|
@ -183,5 +182,5 @@ struct Objects
|
||||||
uint32_t n_segments;
|
uint32_t n_segments;
|
||||||
vector<Segment *> segments;
|
vector<Segment *> segments;
|
||||||
|
|
||||||
void load(FILE *f);
|
void load(buffer &b);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
struct MechGroup
|
struct MechGroup
|
||||||
|
|
@ -47,35 +49,35 @@ struct MechGroup
|
||||||
vector<string> configs;
|
vector<string> configs;
|
||||||
char unk100;
|
char unk100;
|
||||||
|
|
||||||
void load(FILE *f)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
FREAD(unk1);
|
READ(b, unk1);
|
||||||
FREAD(unk2);
|
READ(b, unk2);
|
||||||
FREAD(type1);
|
READ(b, type1);
|
||||||
FREAD(len1);
|
READ(b, len1);
|
||||||
FREAD(name1);
|
READ(b, name1);
|
||||||
if (type1 == 3 || type1 == 4)
|
if (type1 == 3 || type1 == 4)
|
||||||
{
|
{
|
||||||
FREAD(unk30);
|
READ(b, unk30);
|
||||||
}
|
}
|
||||||
else if (type1 == 2)
|
else if (type1 == 2)
|
||||||
{
|
{
|
||||||
FREAD(len);
|
READ(b, len);
|
||||||
unk11.resize(len);
|
unk11.resize(len);
|
||||||
for (int i = 0; i < len; i++)
|
for (int i = 0; i < len; i++)
|
||||||
FREAD(unk11[i]);
|
READ(b, unk11[i]);
|
||||||
}
|
}
|
||||||
else if (type1 == 1 || type1 == 0)
|
else if (type1 == 1 || type1 == 0)
|
||||||
{
|
{
|
||||||
FREAD(unk20);
|
READ(b, unk20);
|
||||||
FREAD(unk21);
|
READ(b, unk21);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
assert(false);
|
assert(false);
|
||||||
configs.resize(len1, string(0x20, 0));
|
configs.resize(len1, string(0x20, 0));
|
||||||
for (int i = 0; i < len1; i++)
|
for (int i = 0; i < len1; i++)
|
||||||
FREAD_N(configs[i][0], 0x20);
|
READ_N(b, configs[i][0], 0x20);
|
||||||
FREAD(unk100);
|
READ(b, unk100);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -86,15 +88,15 @@ struct MechGroups
|
||||||
|
|
||||||
vector<MechGroup> mgs;
|
vector<MechGroup> mgs;
|
||||||
|
|
||||||
void load(FILE *f)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
FREAD(n);
|
READ(b, n);
|
||||||
FREAD(prefix);
|
READ(b, prefix);
|
||||||
|
|
||||||
for (int s = 0; s < n; s++)
|
for (int s = 0; s < n; s++)
|
||||||
{
|
{
|
||||||
MechGroup mg;
|
MechGroup mg;
|
||||||
mg.load(f);
|
mg.load(b);
|
||||||
mgs.push_back(mg);
|
mgs.push_back(mg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -107,12 +109,12 @@ struct Good
|
||||||
float price;
|
float price;
|
||||||
float unk2[10];
|
float unk2[10];
|
||||||
|
|
||||||
void load(FILE *f)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
FREAD(name);
|
READ(b, name);
|
||||||
FREAD(unk1);
|
READ(b, unk1);
|
||||||
FREAD(price);
|
READ(b, price);
|
||||||
FREAD(unk2);
|
READ(b, unk2);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -123,15 +125,15 @@ struct BuildingGoods
|
||||||
|
|
||||||
vector<Good> goods;
|
vector<Good> goods;
|
||||||
|
|
||||||
void load(FILE *f)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
FREAD(name);
|
READ(b, name);
|
||||||
FREAD(n);
|
READ(b, n);
|
||||||
|
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
Good g;
|
Good g;
|
||||||
g.load(f);
|
g.load(b);
|
||||||
goods.push_back(g);
|
goods.push_back(g);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -146,17 +148,17 @@ struct MapGoods
|
||||||
|
|
||||||
vector<BuildingGoods> bgs;
|
vector<BuildingGoods> bgs;
|
||||||
|
|
||||||
void load(FILE *f)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
FREAD(unk1);
|
READ(b, unk1);
|
||||||
FREAD(unk2);
|
READ(b, unk2);
|
||||||
FREAD(unk3);
|
READ(b, unk3);
|
||||||
FREAD(n);
|
READ(b, n);
|
||||||
|
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
BuildingGoods bg;
|
BuildingGoods bg;
|
||||||
bg.load(f);
|
bg.load(b);
|
||||||
bgs.push_back(bg);
|
bgs.push_back(bg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -174,25 +176,25 @@ struct MapMusic
|
||||||
uint32_t n2;
|
uint32_t n2;
|
||||||
vector<string> names2;
|
vector<string> names2;
|
||||||
|
|
||||||
void load(FILE *f)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
FREAD(unk1);
|
READ(b, unk1);
|
||||||
FREAD(name1);
|
READ(b, name1);
|
||||||
FREAD(name2);
|
READ(b, name2);
|
||||||
|
|
||||||
FREAD(n1);
|
READ(b, n1);
|
||||||
for (int i = 0; i < n1; i++)
|
for (int i = 0; i < n1; i++)
|
||||||
{
|
{
|
||||||
char name[0x20];
|
char name[0x20];
|
||||||
FREAD(name);
|
READ(b, name);
|
||||||
names1.push_back(name);
|
names1.push_back(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
FREAD(n2);
|
READ(b, n2);
|
||||||
for (int i = 0; i < n2; i++)
|
for (int i = 0; i < n2; i++)
|
||||||
{
|
{
|
||||||
char name[0x20];
|
char name[0x20];
|
||||||
FREAD(name);
|
READ(b, name);
|
||||||
names2.push_back(name);
|
names2.push_back(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -205,12 +207,12 @@ struct MapSound
|
||||||
uint32_t unk2;
|
uint32_t unk2;
|
||||||
float unk3[4];
|
float unk3[4];
|
||||||
|
|
||||||
void load(FILE *f)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
FREAD(name);
|
READ(b, name);
|
||||||
FREAD(unk1);
|
READ(b, unk1);
|
||||||
FREAD(unk2);
|
READ(b, unk2);
|
||||||
FREAD(unk3);
|
READ(b, unk3);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -219,13 +221,13 @@ struct MapSounds
|
||||||
uint32_t n;
|
uint32_t n;
|
||||||
vector<MapSound> sounds;
|
vector<MapSound> sounds;
|
||||||
|
|
||||||
void load(FILE *f)
|
void load(buffer &b)
|
||||||
{
|
{
|
||||||
FREAD(n);
|
READ(b, n);
|
||||||
for (int i = 0; i < n; i++)
|
for (int i = 0; i < n; i++)
|
||||||
{
|
{
|
||||||
MapSound s;
|
MapSound s;
|
||||||
s.load(f);
|
s.load(b);
|
||||||
sounds.push_back(s);
|
sounds.push_back(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue