Files
korenkonder_ReDIVA/src/KKdLib/pvsr.cpp
T

510 lines
15 KiB
C++

/*
by korenkonder
GitHub/GitLab: korenkonder
*/
#include "pvsr.hpp"
#include "f2/struct.hpp"
#include "io/file_stream.hpp"
#include "io/memory_stream.hpp"
#include "io/path.hpp"
#include "str_utils.hpp"
static void pvsr_auth_3d_read(pvsr_auth_3d* a3d, stream& s);
static void pvsr_auth_2d_read(pvsr_auth_2d* a2d, stream& s);
static void pvsr_effect_read(pvsr_effect* eff, stream& s);
static void pvsr_glitter_read(pvsr_glitter* glt, stream& s);
static void pvsr_read_inner(pvsr* sr, stream& s);
static void pvsr_stage_change_effect_read(pvsr_stage_change_effect* stg_chg_eff, stream& s);
static void pvsr_stage_effect_read(pvsr_stage_effect* stg_eff, stream& s);
static void pvsr_stage_effect_env_read(pvsr_stage_effect_env* env, stream& s, int32_t x00);
static bool pvsr_stage_effect_env_light_read(pvsr_stage_effect_env_light* env_light, stream& s, int64_t offset);
static bool pvsr_stage_effect_env_post_process_read(
pvsr_stage_effect_env_post_process* env_post_process, stream& s, int64_t offset);
pvsr_auth_2d::pvsr_auth_2d() {
bright_scale = 1.0f;
}
pvsr_auth_2d::~pvsr_auth_2d() {
}
pvsr_auth_3d::pvsr_auth_3d() : flags() {
}
pvsr_auth_3d::~pvsr_auth_3d() {
}
pvsr_effect::pvsr_effect() {
emission = 1.0f;
}
pvsr_effect::~pvsr_effect() {
}
pvsr_glitter::pvsr_glitter() : fade_time(), flags() {
}
pvsr_glitter::~pvsr_glitter() {
}
pvsr_stage_change_effect::pvsr_stage_change_effect() : enable(), bar_count() {
}
pvsr_stage_change_effect::~pvsr_stage_change_effect() {
}
pvsr_stage_effect::pvsr_stage_effect() {
}
pvsr_stage_effect::~pvsr_stage_effect() {
}
pvsr_stage_effect_env_light::pvsr_stage_effect_env_light() {
stage_light = -1;
}
pvsr_stage_effect_env_light::~pvsr_stage_effect_env_light() {
}
pvsr_stage_effect_env_post_process::pvsr_stage_effect_env_post_process() {
index0 = -1;
start0 = -1;
trans0 = -1;
index1 = -1;
start1 = -1;
trans1 = -1;
index2 = -1;
}
pvsr_stage_effect_env::pvsr_stage_effect_env() : light(), light_init(), fog(),
fog_init(), bloom(), bloom_init(), cct(), cct_init(), shimmer(), shimmer_init() {
chara_light = -1;
chara_shadow_light = -1;
shadow_light = -1;
item_light = -1;
common_light = -1;
u52 = -1;
ibl_color_light = -1;
u56 = -1;
cat = -1;
u5a = -1;
u5c = -1;
reflection = -1;
effect_light = -1;
}
pvsr_stage_effect_env::~pvsr_stage_effect_env() {
}
pvsr::pvsr() : ready(), big_endian() {
}
pvsr::~pvsr() {
}
void pvsr::read(const char* path) {
if (!path)
return;
char* path_pvsr = str_utils_add(path, ".pvsr");
if (!path_pvsr)
return;
if (path_check_file_exists(path_pvsr)) {
file_stream s;
s.open(path_pvsr, "rb");
if (s.check_not_null())
pvsr_read_inner(this, s);
}
free_def(path_pvsr);
}
void pvsr::read(const wchar_t* path) {
if (!path)
return;
wchar_t* path_pvsr = str_utils_add(path, L".pvsr");
if (!path_pvsr)
return;
if (path_check_file_exists(path_pvsr)) {
file_stream s;
s.open(path_pvsr, L"rb");
if (s.check_not_null())
pvsr_read_inner(this, s);
}
free_def(path_pvsr);
}
void pvsr::read(const void* data, size_t size) {
if (!data || !size)
return;
memory_stream s;
s.open(data, size);
pvsr_read_inner(this, s);
}
bool pvsr::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);
pvsr* sr = (pvsr*)data;
sr->read(path.c_str());
return sr->ready;
}
static void pvsr_auth_2d_read(pvsr_auth_2d* a2d, stream& s) {
a2d->name = s.read_string_null_terminated_offset(s.read_offset_x());
s.read_uint32_t_reverse_endianness();
a2d->bright_scale = s.read_float_t_reverse_endianness();
}
static void pvsr_auth_3d_read(pvsr_auth_3d* a3d, stream& s) {
a3d->name = s.read_string_null_terminated_offset(s.read_offset_x());
s.read_uint32_t_reverse_endianness();
a3d->flags = (pvsr_auth_3d_flags)s.read_uint8_t();
s.align_read(0x08);
}
static void pvsr_effect_read(pvsr_effect* eff, stream& s) {
eff->name = s.read_string_null_terminated_offset(s.read_offset_x());
eff->emission = s.read_float_t_reverse_endianness();
s.align_read(0x08);
}
static void pvsr_glitter_read(pvsr_glitter* glt, stream& s) {
glt->name = s.read_string_null_terminated_offset(s.read_offset_x());
glt->fade_time = s.read_int8_t();
glt->flags = (pvsr_glitter_flags)s.read_uint8_t();
s.align_read(0x08);
}
static void pvsr_read_inner(pvsr* sr, stream& s) {
f2_struct st;
st.read(s);
if (st.header.signature != reverse_endianness_uint32_t('PVSR') || !st.data.data()) {
sr->ready = false;
sr->big_endian = false;
return;
}
bool big_endian = st.header.attrib.get_big_endian();
memory_stream s_pvsr;
s_pvsr.open(st.data);
s_pvsr.big_endian = big_endian;
int32_t x00 = s_pvsr.read_int32_t_reverse_endianness();
uint8_t x04 = s_pvsr.read_uint8_t();
uint8_t x05 = s_pvsr.read_uint8_t();
uint8_t x06 = s_pvsr.read_uint8_t();
uint8_t x07 = s_pvsr.read_uint8_t();
int8_t stage_effect_count = s_pvsr.read_int8_t();
int8_t stage_effect_envs_count = s_pvsr.read_int8_t();
uint8_t x0a = s_pvsr.read_uint8_t();
uint8_t x0b = s_pvsr.read_uint8_t();
uint8_t x0c = s_pvsr.read_uint8_t();
uint8_t x0d = s_pvsr.read_uint8_t();
uint8_t x0e = s_pvsr.read_uint8_t();
uint8_t x0f = s_pvsr.read_uint8_t();
int64_t x10 = s_pvsr.read_offset_x();
int64_t stage_effect_offset = s_pvsr.read_offset_x();
int64_t stage_change_effect_offset = s_pvsr.read_offset_x();
int64_t stage_effect_env_offset = s_pvsr.read_offset_x();
int8_t unknown_count = 0;
int8_t effect_count = 0;
int8_t emcs_count = 0;
int64_t unknown_offset = 0;
int64_t effect_offset = 0;
int64_t emcs_offset = 0;
if (x10) {
s_pvsr.position_push(x10, SEEK_SET);
unknown_count = s_pvsr.read_int8_t();
effect_count = s_pvsr.read_int8_t();
emcs_count = s_pvsr.read_int8_t();
unknown_offset = s_pvsr.read_offset_x();
effect_offset = s_pvsr.read_offset_x();
emcs_offset = s_pvsr.read_offset_x();
s_pvsr.position_pop();
}
if (effect_offset > 0) {
sr->effect.resize(effect_count);
s_pvsr.position_push(effect_offset, SEEK_SET);
for (pvsr_effect& i : sr->effect)
pvsr_effect_read(&i, s_pvsr);
s_pvsr.position_pop();
}
if (emcs_offset > 0) {
sr->emcs.resize(emcs_count);
s_pvsr.position_push(emcs_offset, SEEK_SET);
for (std::string& i : sr->emcs)
i = s_pvsr.read_string_null_terminated_offset(s_pvsr.read_offset_x());
s_pvsr.position_pop();
}
if (stage_effect_offset > 0) {
sr->stage_effect.resize(stage_effect_count);
s_pvsr.position_push(stage_effect_offset, SEEK_SET);
for (pvsr_stage_effect& i : sr->stage_effect)
pvsr_stage_effect_read(&i, s_pvsr);
s_pvsr.position_pop();
}
for (int32_t i = 0; i < PVSR_STAGE_EFFECT_COUNT; i++)
for (int32_t j = 0; j < PVSR_STAGE_EFFECT_COUNT; j++)
sr->stage_change_effect[i][j].enable = false;
if (stage_change_effect_offset > 0) {
s_pvsr.position_push(stage_change_effect_offset, SEEK_SET);
for (int32_t i = 0; i < PVSR_STAGE_EFFECT_COUNT; i++)
for (int32_t j = 0; j < PVSR_STAGE_EFFECT_COUNT; j++) {
int64_t offset = s_pvsr.read_offset_x();
if (offset <= 0)
continue;
s_pvsr.position_push(offset, SEEK_SET);
pvsr_stage_change_effect_read(&sr->stage_change_effect[i][j], s_pvsr);
s_pvsr.position_pop();
}
s_pvsr.position_pop();
}
if (stage_effect_env_offset > 0) {
sr->stage_effect_env.resize(stage_effect_envs_count);
s_pvsr.position_push(stage_effect_env_offset, SEEK_SET);
for (pvsr_stage_effect_env& i : sr->stage_effect_env)
pvsr_stage_effect_env_read(&i, s_pvsr, x00);
s_pvsr.position_pop();
}
sr->ready = true;
sr->big_endian = big_endian;
}
static void pvsr_stage_change_effect_read(pvsr_stage_change_effect* stg_chg_eff, stream& s) {
int8_t enable = s.read_int8_t();
int8_t auth_3d_count = s.read_int8_t();
int8_t glitter_count = s.read_int8_t();
int8_t u03 = s.read_int8_t();
int8_t bar_count = s.read_int8_t();
int64_t auth_3d_offset = s.read_offset_x();
int64_t glitter_offset = s.read_offset_x();
s.read_offset_x();
if (!enable) {
stg_chg_eff->enable = false;
return;
}
stg_chg_eff->enable = true;
if (bar_count > 0)
stg_chg_eff->bar_count = bar_count;
else
stg_chg_eff->bar_count = 0;
if (auth_3d_offset > 0) {
stg_chg_eff->auth_3d.resize(auth_3d_count);
s.position_push(auth_3d_offset, SEEK_SET);
for (pvsr_auth_3d& i : stg_chg_eff->auth_3d)
pvsr_auth_3d_read(&i, s);
s.position_pop();
}
if (glitter_offset > 0) {
stg_chg_eff->glitter.resize(glitter_count);
s.position_push(glitter_offset, SEEK_SET);
for (pvsr_glitter& i : stg_chg_eff->glitter)
pvsr_glitter_read(&i, s);
s.position_pop();
}
}
static void pvsr_stage_effect_read(pvsr_stage_effect* stg_eff, stream& s) {
int8_t auth_3d_count = s.read_int8_t();
int8_t glitter_count = s.read_int8_t();
int8_t u02 = s.read_int8_t();
int8_t u03 = s.read_int8_t();
int8_t u04 = s.read_int8_t();
int64_t auth_3d_offset = s.read_offset_x();
int64_t glitter_offset = s.read_offset_x();
s.read_offset_x();
if (auth_3d_offset > 0) {
stg_eff->auth_3d.resize(auth_3d_count);
s.position_push(auth_3d_offset, SEEK_SET);
for (pvsr_auth_3d& i : stg_eff->auth_3d)
pvsr_auth_3d_read(&i, s);
s.position_pop();
}
if (glitter_offset > 0) {
stg_eff->glitter.resize(glitter_count);
s.position_push(glitter_offset, SEEK_SET);
for (pvsr_glitter& i : stg_eff->glitter)
pvsr_glitter_read(&i, s);
s.position_pop();
}
}
static void pvsr_stage_effect_env_read(pvsr_stage_effect_env* env, stream& s, int32_t x00) {
int64_t set_name_offset = s.read_offset_x();
int64_t aet_front_offset = s.read_offset_x();
int64_t aet_front_low_offset = s.read_offset_x();
int64_t aet_back_offset = s.read_offset_x();
int64_t light_offset = s.read_offset_x();
int64_t fog_offset = s.read_offset_x();
int64_t bloom_offset = s.read_offset_x();
int64_t cct_offset = s.read_offset_x();
int64_t shimmer_offset = s.read_offset_x();
env->chara_light = s.read_int16_t_reverse_endianness();
env->chara_shadow_light = s.read_int16_t_reverse_endianness();
env->shadow_light = s.read_int16_t_reverse_endianness();
env->item_light = s.read_int16_t_reverse_endianness();
env->common_light = s.read_int16_t_reverse_endianness();
env->u52 = s.read_int16_t_reverse_endianness();
env->ibl_color_light = s.read_int16_t_reverse_endianness();
env->u56 = s.read_int16_t_reverse_endianness();
env->cat = s.read_int16_t_reverse_endianness();
env->u5a = s.read_int16_t_reverse_endianness();
env->u5c = s.read_int16_t_reverse_endianness();
env->reflection = s.read_int16_t_reverse_endianness();
env->effect_light = s.read_int16_t_reverse_endianness();
int8_t aet_front_count = s.read_int8_t();
int8_t aet_front_low_count = s.read_int8_t();
int8_t aet_back_count = s.read_int8_t();
s.align_read(0x08);
int64_t o68 = 0;
int64_t o70 = 0;
int8_t u78 = 0;
int8_t u79 = 0;
if (x00 & 0x100) {
o68 = s.read_offset_x();
o70 = s.read_offset_x();
u78 = s.read_int8_t();
u79 = s.read_int8_t();
s.align_read(0x08);
}
env->set_name = s.read_string_null_terminated_offset(set_name_offset);
if (aet_front_offset > 0) {
env->aet_front.resize(aet_front_count);
s.position_push(aet_front_offset, SEEK_SET);
for (pvsr_auth_2d& i : env->aet_front)
pvsr_auth_2d_read(&i, s);
s.position_pop();
}
if (aet_front_low_offset > 0) {
env->aet_front_low.resize(aet_front_low_count);
s.position_push(aet_front_low_offset, SEEK_SET);
for (pvsr_auth_2d& i : env->aet_front_low)
pvsr_auth_2d_read(&i, s);
s.position_pop();
}
if (aet_back_offset > 0) {
env->aet_back.resize(aet_back_count);
s.position_push(aet_back_offset, SEEK_SET);
for (pvsr_auth_2d& i : env->aet_back)
pvsr_auth_2d_read(&i, s);
s.position_pop();
}
env->light_init = pvsr_stage_effect_env_light_read(&env->light, s, light_offset);
env->fog_init = pvsr_stage_effect_env_post_process_read(&env->fog, s, fog_offset);
env->bloom_init = pvsr_stage_effect_env_post_process_read(&env->bloom, s, bloom_offset);
env->cct_init = pvsr_stage_effect_env_post_process_read(&env->cct, s, cct_offset);
env->shimmer_init = pvsr_stage_effect_env_post_process_read(&env->shimmer, s, shimmer_offset);
if (x00 & 0x100) {
if (o68 > 0) {
env->unk03.resize(u78);
s.position_push(o68, SEEK_SET);
for (pvsr_auth_2d& i : env->unk03)
pvsr_auth_2d_read(&i, s);
s.position_pop();
}
if (o70 > 0) {
env->unk04.resize(u79);
s.position_push(o70, SEEK_SET);
for (pvsr_auth_2d& i : env->unk04)
pvsr_auth_2d_read(&i, s);
s.position_pop();
}
}
}
static bool pvsr_stage_effect_env_light_read(
pvsr_stage_effect_env_light* env_light, stream& s, int64_t offset) {
if (offset <= 0)
return false;
s.position_push(offset, SEEK_SET);
env_light->auth_3d_name = s.read_string_null_terminated_offset(s.read_offset_x());
s.read_uint32_t_reverse_endianness();
env_light->stage_light = s.read_int16_t_reverse_endianness();
s.align_read(0x08);
s.position_pop();
return true;
}
static bool pvsr_stage_effect_env_post_process_read(
pvsr_stage_effect_env_post_process* env_post_process, stream& s, int64_t offset) {
if (offset <= 0)
return false;
s.position_push(offset, SEEK_SET);
env_post_process->index0 = s.read_int16_t_reverse_endianness();
env_post_process->start0 = s.read_int16_t_reverse_endianness();
env_post_process->trans0 = s.read_int16_t_reverse_endianness();
env_post_process->index1 = s.read_int16_t_reverse_endianness();
env_post_process->start1 = s.read_int16_t_reverse_endianness();
env_post_process->trans1 = s.read_int16_t_reverse_endianness();
env_post_process->index2 = s.read_int16_t_reverse_endianness();
s.align_read(0x08);
s.position_pop();
return true;
}