Files
korenkonder_ReDIVA/src/KKdLib/database/item_table.cpp
T

893 lines
25 KiB
C++

/*
by korenkonder
GitHub/GitLab: korenkonder
*/
#include "item_table.hpp"
#include "../io/file_stream.hpp"
#include "../io/memory_stream.hpp"
#include "../io/path.hpp"
#include "../key_val.hpp"
#include "../sort.hpp"
#include "../str_utils.hpp"
const char* chara_auth_3d_names[] = {
"MIK",
"RIN",
"LEN",
"LUK",
"NER",
"HAK",
"KAI",
"MEI",
"SAK",
"TET",
"EXT",
};
const char* chara_face_mot_names[] = {
"MIK",
"RIN",
"LEN",
"LUK",
"NER",
"HAK",
"KAI",
"MEI",
"SAK",
"TET",
"EXT",
};
const char* chara_full_names[] = {
"MIKU",
"RIN",
"LEN",
"LUKA",
"NERU",
"HAKU",
"KAITO",
"MEIKO",
"SAKINE",
"TETO",
"EXTRA",
};
const char* chara_names[] = {
"MIK",
"RIN",
"LEN",
"LUK",
"NER",
"HAK",
"KAI",
"MEI",
"SAK",
"TET",
"EXT",
};
const char* item_id_names[] = {
"BODY",
"ATAMA",
"KATA_R",
"MUNE",
"KATA_L",
"UDE_R",
"SENAKA",
"UDE_L",
"HARA",
"KOSI",
"TE_R",
"TE_L",
"MOMO",
"SUNE",
"ASI",
"KAMI",
"OUTER",
"PANTS",
"ZUJO",
"MEGANE",
"KUBI",
"JOHA_USHIRO",
"KUCHI",
"ITEM09",
"ITEM10",
"ITEM11",
"ITEM12",
"ITEM13",
"ITEM14",
"ITEM15",
"ITEM16",
};
const char* item_sub_id_names[] = {
"ZUJO",
"KAMI",
"HITAI",
"ME",
"MEGANE",
"MIMI",
"KUCHI",
"MAKI",
"KUBI",
"INNER",
"OUTER",
"KATA",
"U_UDE",
"L_UDE",
"TE",
"JOHA_MAE",
"JOHA_USHIRO",
"BELT",
"KOSI",
"PANTS",
"ASI",
"SUNE",
"KUTSU",
"HADA",
"HEAD",
};
static void itm_table_read_inner(itm_table* itm_tbl, stream& s);
static void itm_table_write_inner(itm_table* itm_tbl, stream& s);
static void itm_table_read_text(itm_table* itm_tbl, void* data, size_t size);
static void itm_table_write_text(itm_table* itm_tbl, void** data, size_t* size);
itm_table_item_data_obj::itm_table_item_data_obj() : rpk() {
}
itm_table_item_data_obj::~itm_table_item_data_obj() {
}
itm_table_item_data_ofs::itm_table_item_data_ofs() : sub_id(), no() {
}
itm_table_item_data_tex::itm_table_item_data_tex() {
}
itm_table_item_data_tex::~itm_table_item_data_tex() {
}
itm_table_item_data_col::itm_table_item_data_col() : flag(), col_tone() {
}
itm_table_item_data_col::~itm_table_item_data_col() {
}
itm_table_item_data::itm_table_item_data() {
}
itm_table_item_data::~itm_table_item_data() {
}
itm_table_item::itm_table_item() : no(), flag(), type(), attr(), des_id(),
sub_id(), exclusion(), point(), org_itm(), npr_flag(), face_depth() {
}
itm_table_item::~itm_table_item() {
}
itm_table_cos::itm_table_cos() : id() {
}
itm_table_cos::~itm_table_cos() {
}
itm_table_dbgset::itm_table_dbgset() {
}
itm_table_dbgset::~itm_table_dbgset() {
}
itm_table::itm_table() : ready() {
}
itm_table::~itm_table() {
}
void itm_table::read(const char* path) {
if (!path)
return;
char* path_txt = str_utils_add(path, ".txt");
if (!path_txt)
return;
if (path_check_file_exists(path_txt)) {
file_stream s;
s.open(path_txt, "rb");
if (s.check_not_null())
itm_table_read_inner(this, s);
}
free_def(path_txt);
}
void itm_table::read(const wchar_t* path) {
if (!path)
return;
wchar_t* path_txt = str_utils_add(path, L".txt");
if (!path_txt)
return;
if (path_check_file_exists(path_txt)) {
file_stream s;
s.open(path_txt, L"rb");
if (s.check_not_null())
itm_table_read_inner(this, s);
}
free_def(path_txt);
}
void itm_table::read(const void* data, size_t size) {
if (!data || !size)
return;
memory_stream s;
s.open(data, size);
itm_table_read_inner(this, s);
}
void itm_table::write(const char* path) {
if (!path || !ready)
return;
char* path_txt = str_utils_add(path, ".txt");
if (!path_txt)
return;
file_stream s;
s.open(path_txt, "wb");
if (s.check_not_null())
itm_table_write_inner(this, s);
free_def(path_txt);
}
void itm_table::write(const wchar_t* path) {
if (!path || !ready)
return;
wchar_t* path_txt = str_utils_add(path, L".txt");
if (!path_txt)
return;
file_stream s;
s.open(path_txt, L"wb");
if (s.check_not_null())
itm_table_write_inner(this, s);
free_def(path_txt);
}
void itm_table::write(void** data, size_t* size) {
if (!data || !size || !ready)
return;
memory_stream s;
s.open();
itm_table_write_inner(this, s);
s.copy(data, size);
}
bool itm_table::load_file(void* data, const char* dir, const char* file, uint32_t hash) {
size_t file_len = utf8_length(file);
const char* t = strrchr(file, '.');
if (t)
file_len = t - file;
std::string path(dir);
path.append(file, file_len);
itm_table* itm_tbl = (itm_table*)data;
itm_tbl->read(path.c_str());
return itm_tbl->ready;
}
const char* chara_index_get_auth_3d_name(chara_index chara_index) {
if (chara_index >= 0 && chara_index < CHARA_MAX)
return chara_auth_3d_names[chara_index];
return 0;
}
const char* chara_index_get_chara_name(chara_index chara_index) {
if (chara_index >= 0 && chara_index < CHARA_MAX)
return chara_names[chara_index];
return 0;
}
const char* chara_index_get_face_mot_name(chara_index chara_index) {
if (chara_index >= 0 && chara_index < CHARA_MAX)
return chara_face_mot_names[chara_index];
return 0;
}
chara_index chara_index_get_from_chara_name(const char* str) {
if (!str)
return CHARA_MAX;
for (int32_t i = 0; i < CHARA_MAX; i++) {
const char* chr_s = chara_names[i];
const char* s = str;
char chr_c;
char diff;
do {
chr_c = *chr_s;
diff = *s - chr_c;
if (diff)
break;
s++;
chr_s++;
} while (chr_c);
if (!diff)
return (chara_index)i;
}
return CHARA_MAX;
}
const char* chara_index_get_name(chara_index chara_index) {
if (chara_index >= 0 && chara_index < CHARA_MAX)
return chara_full_names[chara_index];
return 0;
}
const char* item_id_get_name(item_id id) {
if (id >= 0 && id < ITEM_MAX)
return item_id_names[id];
return 0;
}
const char* item_sub_id_get_name(item_sub_id sub_id) {
if (sub_id >= 0 && sub_id < ITEM_SUB_MAX)
return item_sub_id_names[sub_id];
return 0;
}
static void itm_table_read_inner(itm_table* itm_tbl, stream& s) {
void* itm_tbl_data = force_malloc(s.length);
s.read(itm_tbl_data, s.length);
itm_table_read_text(itm_tbl, itm_tbl_data, s.length);
free_def(itm_tbl_data);
itm_tbl->ready = true;
}
static void itm_table_write_inner(itm_table* itm_tbl, stream& s) {
void* itm_tbl_data = 0;
size_t itm_tbl_data_length = 0;
itm_table_write_text(itm_tbl, &itm_tbl_data, &itm_tbl_data_length);
s.write(itm_tbl_data, itm_tbl_data_length);
free_def(itm_tbl_data);
}
static void itm_table_read_text(itm_table* itm_tbl, void* data, size_t size) {
key_val kv;
kv.parse(data, size);
itm_tbl->item.clear();
int32_t count;
if (kv.read("cos", "length", count)) {
std::vector<itm_table_cos>& vc = itm_tbl->cos;
vc.reserve(count);
for (int32_t i = 0; i < count; i++) {
if (!kv.open_scope_fmt(i))
continue;
itm_table_cos c;
kv.read("id", c.id);
int32_t count;
if (kv.read("item", "length", count)) {
std::vector<int32_t>& vci = c.item;
vci.resize(count);
for (int32_t j = 0; j < count; j++) {
if (!kv.open_scope_fmt(j))
continue;
kv.read(vci[j]);
kv.close_scope();
}
kv.close_scope();
}
vc.push_back(c);
kv.close_scope();
}
kv.close_scope();
}
itm_tbl->dbgset.clear();
if (kv.read("dbgset", "length", count)) {
std::vector<itm_table_dbgset>& vd = itm_tbl->dbgset;
vd.reserve(count);
for (int32_t i = 0; i < count; i++) {
if (!kv.open_scope_fmt(i))
continue;
itm_table_dbgset d;
int32_t count;
if (kv.read("item", "length", count)) {
std::vector<int32_t>& vdi = d.item;
vdi.resize(count);
for (int32_t j = 0; j < count; j++) {
if (!kv.open_scope_fmt(j))
continue;
kv.read(vdi[j]);
kv.close_scope();
}
kv.close_scope();
}
kv.read("name", d.name);
vd.push_back(d);
kv.close_scope();
}
kv.close_scope();
}
itm_tbl->item.clear();
if (kv.read("item", "length", count)) {
std::vector<itm_table_item>& vi = itm_tbl->item;
vi.reserve(count);
for (int32_t i = 0; i < count; i++) {
if (!kv.open_scope_fmt(i))
continue;
itm_table_item itm;
if (!kv.read("no", itm.no)) {
kv.close_scope();
continue;
}
if (!kv.read("flag", itm.flag)
|| !kv.read("name", itm.name)) {
kv.close_scope();
continue;
}
int32_t count;
if (kv.read("objset", "length", count)) {
std::vector<std::string>& vio = itm.objset;
vio.resize(count);
for (int32_t j = 0; j < count; j++) {
if (!kv.open_scope_fmt(j))
continue;
kv.read(vio[j]);
kv.close_scope();
}
kv.close_scope();
}
int32_t sub_id = 0;
if (!kv.read("type", itm.type)
|| !kv.read("attr", itm.attr)
|| !kv.read("des_id", itm.des_id)
|| !kv.read("sub_id", sub_id)) {
kv.close_scope();
continue;
}
itm.sub_id = (item_sub_id)sub_id;
if (kv.open_scope("data")) {
int32_t count;
if (kv.read("obj", "length", count)) {
std::vector<itm_table_item_data_obj>& vido = itm.data.obj;
vido.reserve(count);
for (int32_t j = 0; j < count; j++) {
if (!kv.open_scope_fmt(j))
continue;
itm_table_item_data_obj obj;
int32_t rpk = 0;
if (kv.read("rpk", rpk))
obj.rpk = (item_id)rpk;
kv.read("uid", obj.uid);
vido.push_back(obj);
kv.close_scope();
}
kv.close_scope();
}
if (kv.read("ofs", "length", count)) {
std::vector<itm_table_item_data_ofs>& vido = itm.data.ofs;
vido.reserve(count);
for (int32_t j = 0; j < count; j++) {
if (!kv.open_scope_fmt(j))
continue;
itm_table_item_data_ofs ofs;
int32_t sub_id = 0;
if (kv.read("no", ofs.no)
&& kv.read("sub_id", sub_id)
&& kv.read("tx", ofs.position.x)
&& kv.read("ty", ofs.position.y)
&& kv.read("tz", ofs.position.z)
&& kv.read("rx", ofs.rotation.x)
&& kv.read("ry", ofs.rotation.y)
&& kv.read("rz", ofs.rotation.z)
&& kv.read("sx", ofs.scale.x)
&& kv.read("sy", ofs.scale.y)
&& kv.read("sz", ofs.scale.z)) {
ofs.sub_id = (item_sub_id)sub_id;
vido.push_back(ofs);
}
kv.close_scope();
}
kv.close_scope();
}
if (kv.read("tex", "length", count)) {
std::vector<itm_table_item_data_tex>& vidt = itm.data.tex;
vidt.reserve(count);
for (int32_t j = 0; j < count; j++) {
if (!kv.open_scope_fmt(j))
continue;
itm_table_item_data_tex tex;
kv.read("org", tex.org);
kv.read("chg", tex.chg);
vidt.push_back(tex);
kv.close_scope();
}
kv.close_scope();
}
if (kv.read("col", "length", count)) {
std::vector<itm_table_item_data_col>& vidc = itm.data.col;
vidc.reserve(count);
for (int32_t j = 0; j < count; j++) {
if (!kv.open_scope_fmt(j))
continue;
itm_table_item_data_col col;
kv.read("tex", col.tex);
kv.read("flag", col.flag);
if (!(col.flag & 0x01)) {
vidc.push_back(col);
kv.close_scope();
continue;
}
kv.read("blend.0", col.col_tone.blend.x);
kv.read("blend.1", col.col_tone.blend.y);
kv.read("blend.2", col.col_tone.blend.z);
kv.read("offset.0", col.col_tone.offset.x);
kv.read("offset.1", col.col_tone.offset.y);
kv.read("offset.2", col.col_tone.offset.z);
kv.read("hue", col.col_tone.hue);
kv.read("saturation", col.col_tone.saturation);
kv.read("value", col.col_tone.value);
kv.read("contrast", col.col_tone.contrast);
kv.read("inverse", col.col_tone.inverse);
vidc.push_back(col);
kv.close_scope();
}
kv.close_scope();
}
kv.close_scope();
}
if (!kv.read("exclusion", itm.exclusion)
|| !kv.read("point", itm.point)
|| !kv.read("org_itm", itm.org_itm)) {
kv.close_scope();
continue;
}
kv.read("npr_flag", itm.npr_flag);
kv.read("face_depth", itm.face_depth);
vi.push_back(itm);
kv.close_scope();
}
kv.close_scope();
}
}
static void itm_table_write_text(itm_table* itm_tbl, void** data, size_t* size) {
memory_stream s;
s.open();
key_val_out kv;
if (itm_tbl->cos.size() > 0) {
kv.open_scope("cos");
int32_t count = (int32_t)itm_tbl->cos.size();
itm_table_cos* vc = itm_tbl->cos.data();
std::vector<int32_t> sort_index;
key_val_out::get_lexicographic_order(sort_index, count);
int32_t* sort_index_data = sort_index.data();
for (int32_t i = 0; i < count; i++) {
kv.open_scope_fmt(sort_index_data[i]);
itm_table_cos* c = &vc[sort_index_data[i]];
kv.write(s, "id", c->id);
kv.open_scope("item");
int32_t count = (int32_t)c->item.size();
int32_t* vci = c->item.data();
std::vector<int32_t> sort_index;
key_val_out::get_lexicographic_order(sort_index, count);
int32_t* sort_index_data = sort_index.data();
for (int32_t j = 0; j < count; j++) {
kv.open_scope_fmt(sort_index_data[j]);
kv.write(s, vci[sort_index_data[j]]);
kv.close_scope();
}
kv.write(s, "length", count);
kv.close_scope();
kv.close_scope();
}
kv.write(s, "length", count);
kv.close_scope();
}
if (itm_tbl->dbgset.size() > 0) {
kv.open_scope("dbgset");
int32_t count = (int32_t)itm_tbl->dbgset.size();
itm_table_dbgset* vd = itm_tbl->dbgset.data();
std::vector<int32_t> sort_index;
key_val_out::get_lexicographic_order(sort_index, count);
int32_t* sort_index_data = sort_index.data();
for (int32_t i = 0; i < count; i++) {
kv.open_scope_fmt(sort_index_data[i]);
itm_table_dbgset* d = &vd[sort_index_data[i]];
kv.open_scope("item");
int32_t count = (int32_t)d->item.size();
int32_t* vdi = d->item.data();
std::vector<int32_t> sort_index;
key_val_out::get_lexicographic_order(sort_index, count);
int32_t* sort_index_data = sort_index.data();
for (int32_t j = 0; j < count; j++) {
kv.open_scope_fmt(sort_index_data[j]);
kv.write(s, vdi[sort_index_data[j]]);
kv.close_scope();
}
kv.write(s, "length", count);
kv.write(s, "name", d->name);
kv.close_scope();
kv.close_scope();
}
kv.write(s, "length", count);
kv.close_scope();
}
if (itm_tbl->item.size() > 0) {
kv.open_scope("item");
int32_t count = (int32_t)itm_tbl->item.size();
itm_table_item* vi = itm_tbl->item.data();
std::vector<int32_t> sort_index;
key_val_out::get_lexicographic_order(sort_index, count);
int32_t* sort_index_data = sort_index.data();
for (int32_t i = 0; i < count; i++) {
kv.open_scope_fmt(sort_index_data[i]);
itm_table_item* itm = &vi[sort_index_data[i]];
kv.write(s, "attr", itm->attr);
if (itm->data.col.size() || itm->data.obj.size()
|| itm->data.ofs.size() || itm->data.tex.size()) {
kv.open_scope("data");
if (itm->data.col.size()) {
kv.open_scope("col");
int32_t count = (int32_t)itm->data.col.size();
itm_table_item_data_col* vidc = itm-> data.col.data();
std::vector<int32_t> sort_index;
key_val_out::get_lexicographic_order(sort_index, count);
int32_t* sort_index_data = sort_index.data();
for (int32_t j = 0; j < count; j++) {
kv.open_scope_fmt(sort_index_data[j]);
itm_table_item_data_col* col = &vidc[sort_index_data[j]];
if (col->flag & 0x01) {
kv.write(s, "blend.0", col->col_tone.blend.x);
kv.write(s, "blend.1", col->col_tone.blend.y);
kv.write(s, "blend.2", col->col_tone.blend.z);
kv.write(s, "contrast", col->col_tone.contrast);
}
kv.write(s, "flag", col->flag);
if (col->flag & 0x01) {
kv.write(s, "hue", col->col_tone.hue);
kv.write(s, "inverse", col->col_tone.inverse ? 1 : 0);
kv.write(s, "offset.0", col->col_tone.offset.x);
kv.write(s, "offset.1", col->col_tone.offset.y);
kv.write(s, "offset.2", col->col_tone.offset.z);
kv.write(s, "saturation", col->col_tone.saturation);
}
kv.write(s, "tex", col->tex);
if (col->flag & 0x01)
kv.write(s, "value", col->col_tone.value);
kv.close_scope();
}
kv.write(s, "length", count);
kv.close_scope();
}
if (itm->data.obj.size()) {
kv.open_scope("obj");
int32_t count = (int32_t)itm->data.obj.size();
itm_table_item_data_obj* vido = itm->data.obj.data();
std::vector<int32_t> sort_index;
key_val_out::get_lexicographic_order(sort_index, count);
int32_t* sort_index_data = sort_index.data();
for (int32_t j = 0; j < count; j++) {
kv.open_scope_fmt(sort_index_data[j]);
itm_table_item_data_obj* obj = &vido[sort_index_data[j]];
kv.write(s, "rpk", obj->rpk);
kv.write(s, "uid", obj->uid);
kv.close_scope();
}
kv.write(s, "length", count);
kv.close_scope();
}
if (itm->data.ofs.size()) {
kv.open_scope("ofs");
int32_t count = (int32_t)itm->data.ofs.size();
itm_table_item_data_ofs* vido = itm->data.ofs.data();
std::vector<int32_t> sort_index;
key_val_out::get_lexicographic_order(sort_index, count);
int32_t* sort_index_data = sort_index.data();
for (int32_t j = 0; j < count; j++) {
kv.open_scope_fmt(sort_index_data[j]);
itm_table_item_data_ofs* ofs = &vido[sort_index_data[j]];
kv.write(s, "no", ofs->no);
kv.write(s, "rx", ofs->rotation.x);
kv.write(s, "ry", ofs->rotation.y);
kv.write(s, "rz", ofs->rotation.z);
kv.write(s, "sub_id", ofs->sub_id);
kv.write(s, "sx", ofs->scale.x);
kv.write(s, "sy", ofs->scale.y);
kv.write(s, "sz", ofs->scale.z);
kv.write(s, "tx", ofs->position.x);
kv.write(s, "ty", ofs->position.y);
kv.write(s, "tz", ofs->position.z);
kv.close_scope();
}
kv.write(s, "length", count);
kv.close_scope();
}
if (itm->data.tex.size()) {
kv.open_scope("tex");
int32_t count = (int32_t)itm->data.tex.size();
itm_table_item_data_tex* vidt = itm->data.tex.data();
std::vector<int32_t> sort_index;
key_val_out::get_lexicographic_order(sort_index, count);
int32_t* sort_index_data = sort_index.data();
for (int32_t j = 0; j < count; j++) {
kv.open_scope_fmt(sort_index_data[j]);
itm_table_item_data_tex* tex = &vidt[sort_index_data[j]];
kv.write(s, "chg", tex->chg);
kv.write(s, "org", tex->org);
kv.close_scope();
}
kv.write(s, "length", count);
kv.close_scope();
}
kv.close_scope();
}
kv.write(s, "des_id", itm->des_id);
kv.write(s, "exclusion", itm->exclusion);
kv.write(s, "face_depth", itm->face_depth);
kv.write(s, "flag", itm->flag);
kv.write(s, "name", itm->name);
kv.write(s, "no", itm->no);
kv.write(s, "npr_flag", itm->npr_flag);
if (itm->objset.size()) {
kv.open_scope("objset");
int32_t count = (int32_t)itm->objset.size();
std::string* vio = itm->objset.data();
std::vector<int32_t> sort_index;
key_val_out::get_lexicographic_order(sort_index, count);
int32_t* sort_index_data = sort_index.data();
for (int32_t j = 0; j < count; j++) {
kv.open_scope_fmt(sort_index_data[j]);
kv.write(s, vio[sort_index_data[j]]);
kv.close_scope();
}
kv.write(s, "length", count);
kv.close_scope();
}
kv.write(s, "org_itm", itm->org_itm);
kv.write(s, "point", itm->point);
kv.write(s, "sub_id", itm->sub_id);
kv.write(s, "type", itm->type);
kv.close_scope();
}
kv.write(s, "length", count);
kv.close_scope();
}
s.copy(data, size);
}